summaryrefslogtreecommitdiffstats
path: root/gfx/angle/checkout/src
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/checkout/src')
-rw-r--r--gfx/angle/checkout/src/common/CircularBuffer.h175
-rw-r--r--gfx/angle/checkout/src/common/Color.h104
-rw-r--r--gfx/angle/checkout/src/common/Color.inc69
-rw-r--r--gfx/angle/checkout/src/common/FastVector.h891
-rw-r--r--gfx/angle/checkout/src/common/FixedVector.h353
-rw-r--r--gfx/angle/checkout/src/common/Float16ToFloat32.cpp300
-rw-r--r--gfx/angle/checkout/src/common/MemoryBuffer.cpp179
-rw-r--r--gfx/angle/checkout/src/common/MemoryBuffer.h93
-rw-r--r--gfx/angle/checkout/src/common/Optional.h74
-rw-r--r--gfx/angle/checkout/src/common/PackedEGLEnums_autogen.cpp452
-rw-r--r--gfx/angle/checkout/src/common/PackedEGLEnums_autogen.h144
-rw-r--r--gfx/angle/checkout/src/common/PackedEnums.cpp673
-rw-r--r--gfx/angle/checkout/src/common/PackedEnums.h859
-rw-r--r--gfx/angle/checkout/src/common/PackedGLEnums_autogen.cpp2449
-rw-r--r--gfx/angle/checkout/src/common/PackedGLEnums_autogen.h610
-rw-r--r--gfx/angle/checkout/src/common/PoolAlloc.cpp487
-rw-r--r--gfx/angle/checkout/src/common/PoolAlloc.h181
-rw-r--r--gfx/angle/checkout/src/common/Spinlock.h71
-rw-r--r--gfx/angle/checkout/src/common/SynchronizedValue.h540
-rw-r--r--gfx/angle/checkout/src/common/aligned_memory.cpp64
-rw-r--r--gfx/angle/checkout/src/common/aligned_memory.h23
-rw-r--r--gfx/angle/checkout/src/common/android_util.cpp424
-rw-r--r--gfx/angle/checkout/src/common/android_util.h59
-rw-r--r--gfx/angle/checkout/src/common/angle_version.h28
-rw-r--r--gfx/angle/checkout/src/common/angle_version_info.cpp40
-rw-r--r--gfx/angle/checkout/src/common/angle_version_info.h20
-rw-r--r--gfx/angle/checkout/src/common/angleutils.cpp156
-rw-r--r--gfx/angle/checkout/src/common/angleutils.h601
-rw-r--r--gfx/angle/checkout/src/common/apple_platform_utils.h90
-rw-r--r--gfx/angle/checkout/src/common/bitset_utils.h1106
-rw-r--r--gfx/angle/checkout/src/common/debug.cpp349
-rw-r--r--gfx/angle/checkout/src/common/debug.h468
-rw-r--r--gfx/angle/checkout/src/common/entry_points_enum_autogen.cpp3454
-rw-r--r--gfx/angle/checkout/src/common/entry_points_enum_autogen.h1736
-rw-r--r--gfx/angle/checkout/src/common/event_tracer.cpp53
-rw-r--r--gfx/angle/checkout/src/common/event_tracer.h26
-rw-r--r--gfx/angle/checkout/src/common/hash_utils.h39
-rw-r--r--gfx/angle/checkout/src/common/mathutil.cpp83
-rw-r--r--gfx/angle/checkout/src/common/mathutil.h1482
-rw-r--r--gfx/angle/checkout/src/common/matrix_utils.cpp285
-rw-r--r--gfx/angle/checkout/src/common/matrix_utils.h424
-rw-r--r--gfx/angle/checkout/src/common/platform.h209
-rw-r--r--gfx/angle/checkout/src/common/spirv/spirv_types.h133
-rw-r--r--gfx/angle/checkout/src/common/string_utils.cpp357
-rw-r--r--gfx/angle/checkout/src/common/string_utils.h125
-rw-r--r--gfx/angle/checkout/src/common/system_utils.cpp267
-rw-r--r--gfx/angle/checkout/src/common/system_utils.h224
-rw-r--r--gfx/angle/checkout/src/common/system_utils_apple.cpp59
-rw-r--r--gfx/angle/checkout/src/common/system_utils_linux.cpp55
-rw-r--r--gfx/angle/checkout/src/common/system_utils_mac.cpp28
-rw-r--r--gfx/angle/checkout/src/common/system_utils_posix.cpp470
-rw-r--r--gfx/angle/checkout/src/common/system_utils_win.cpp264
-rw-r--r--gfx/angle/checkout/src/common/system_utils_win32.cpp235
-rw-r--r--gfx/angle/checkout/src/common/third_party/base/anglebase/base_export.h13
-rw-r--r--gfx/angle/checkout/src/common/third_party/base/anglebase/containers/mru_cache.h275
-rw-r--r--gfx/angle/checkout/src/common/third_party/base/anglebase/logging.h26
-rw-r--r--gfx/angle/checkout/src/common/third_party/base/anglebase/macros.h17
-rw-r--r--gfx/angle/checkout/src/common/third_party/base/anglebase/no_destructor.h106
-rw-r--r--gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/checked_math.h384
-rw-r--r--gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/checked_math_impl.h641
-rw-r--r--gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/clamped_math.h270
-rw-r--r--gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/clamped_math_impl.h368
-rw-r--r--gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/math_constants.h20
-rw-r--r--gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/ranges.h39
-rw-r--r--gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/safe_conversions.h403
-rw-r--r--gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/safe_conversions_arm_impl.h60
-rw-r--r--gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/safe_conversions_impl.h893
-rw-r--r--gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/safe_math.h12
-rw-r--r--gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/safe_math_arm_impl.h131
-rw-r--r--gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/safe_math_clang_gcc_impl.h182
-rw-r--r--gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/safe_math_shared_impl.h227
-rw-r--r--gfx/angle/checkout/src/common/third_party/base/anglebase/sha1.cc245
-rw-r--r--gfx/angle/checkout/src/common/third_party/base/anglebase/sha1.h36
-rw-r--r--gfx/angle/checkout/src/common/third_party/base/anglebase/sys_byteorder.h49
-rw-r--r--gfx/angle/checkout/src/common/third_party/smhasher/src/PMurHash.cpp339
-rw-r--r--gfx/angle/checkout/src/common/third_party/smhasher/src/PMurHash.h57
-rw-r--r--gfx/angle/checkout/src/common/third_party/xxhash/xxhash.c1030
-rw-r--r--gfx/angle/checkout/src/common/third_party/xxhash/xxhash.h341
-rw-r--r--gfx/angle/checkout/src/common/tls.cpp156
-rw-r--r--gfx/angle/checkout/src/common/tls.h54
-rw-r--r--gfx/angle/checkout/src/common/uniform_type_info_autogen.cpp378
-rw-r--r--gfx/angle/checkout/src/common/utilities.cpp1509
-rw-r--r--gfx/angle/checkout/src/common/utilities.h336
-rw-r--r--gfx/angle/checkout/src/common/vector_utils.h523
-rw-r--r--gfx/angle/checkout/src/common/vulkan/libvulkan_loader.cpp57
-rw-r--r--gfx/angle/checkout/src/common/vulkan/libvulkan_loader.h23
-rw-r--r--gfx/angle/checkout/src/common/vulkan/vk_google_filtering_precision.h57
-rw-r--r--gfx/angle/checkout/src/common/vulkan/vk_headers.h163
-rw-r--r--gfx/angle/checkout/src/common/vulkan/vulkan_icd.cpp349
-rw-r--r--gfx/angle/checkout/src/common/vulkan/vulkan_icd.h72
-rw-r--r--gfx/angle/checkout/src/compiler/preprocessor/DiagnosticsBase.cpp148
-rw-r--r--gfx/angle/checkout/src/compiler/preprocessor/DiagnosticsBase.h102
-rw-r--r--gfx/angle/checkout/src/compiler/preprocessor/DirectiveHandlerBase.cpp19
-rw-r--r--gfx/angle/checkout/src/compiler/preprocessor/DirectiveHandlerBase.h49
-rw-r--r--gfx/angle/checkout/src/compiler/preprocessor/DirectiveParser.cpp981
-rw-r--r--gfx/angle/checkout/src/compiler/preprocessor/DirectiveParser.h88
-rw-r--r--gfx/angle/checkout/src/compiler/preprocessor/ExpressionParser.h48
-rw-r--r--gfx/angle/checkout/src/compiler/preprocessor/Input.cpp130
-rw-r--r--gfx/angle/checkout/src/compiler/preprocessor/Input.h59
-rw-r--r--gfx/angle/checkout/src/compiler/preprocessor/Lexer.cpp19
-rw-r--r--gfx/angle/checkout/src/compiler/preprocessor/Lexer.h32
-rw-r--r--gfx/angle/checkout/src/compiler/preprocessor/Macro.cpp45
-rw-r--r--gfx/angle/checkout/src/compiler/preprocessor/Macro.h55
-rw-r--r--gfx/angle/checkout/src/compiler/preprocessor/MacroExpander.cpp531
-rw-r--r--gfx/angle/checkout/src/compiler/preprocessor/MacroExpander.h91
-rw-r--r--gfx/angle/checkout/src/compiler/preprocessor/Preprocessor.cpp107
-rw-r--r--gfx/angle/checkout/src/compiler/preprocessor/Preprocessor.h72
-rw-r--r--gfx/angle/checkout/src/compiler/preprocessor/SourceLocation.h44
-rw-r--r--gfx/angle/checkout/src/compiler/preprocessor/Token.cpp79
-rw-r--r--gfx/angle/checkout/src/compiler/preprocessor/Token.h115
-rw-r--r--gfx/angle/checkout/src/compiler/preprocessor/Tokenizer.h63
-rw-r--r--gfx/angle/checkout/src/compiler/preprocessor/numeric_lex.h54
-rw-r--r--gfx/angle/checkout/src/compiler/preprocessor/preprocessor_lex_autogen.cpp2626
-rw-r--r--gfx/angle/checkout/src/compiler/preprocessor/preprocessor_tab_autogen.cpp1773
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ASTMetadataHLSL.cpp445
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ASTMetadataHLSL.h62
-rw-r--r--gfx/angle/checkout/src/compiler/translator/AtomicCounterFunctionHLSL.cpp112
-rw-r--r--gfx/angle/checkout/src/compiler/translator/AtomicCounterFunctionHLSL.h50
-rw-r--r--gfx/angle/checkout/src/compiler/translator/BaseTypes.cpp64
-rw-r--r--gfx/angle/checkout/src/compiler/translator/BaseTypes.h1782
-rw-r--r--gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulator.cpp161
-rw-r--r--gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulator.h80
-rw-r--r--gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp284
-rw-r--r--gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorGLSL.h40
-rw-r--r--gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp173
-rw-r--r--gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorHLSL.h27
-rw-r--r--gfx/angle/checkout/src/compiler/translator/BuiltinsWorkaroundGLSL.cpp109
-rw-r--r--gfx/angle/checkout/src/compiler/translator/BuiltinsWorkaroundGLSL.h24
-rw-r--r--gfx/angle/checkout/src/compiler/translator/CallDAG.cpp316
-rw-r--r--gfx/angle/checkout/src/compiler/translator/CallDAG.h77
-rw-r--r--gfx/angle/checkout/src/compiler/translator/CodeGen.cpp96
-rw-r--r--gfx/angle/checkout/src/compiler/translator/CollectVariables.cpp1288
-rw-r--r--gfx/angle/checkout/src/compiler/translator/CollectVariables.h38
-rw-r--r--gfx/angle/checkout/src/compiler/translator/Common.h256
-rw-r--r--gfx/angle/checkout/src/compiler/translator/Compiler.cpp1746
-rw-r--r--gfx/angle/checkout/src/compiler/translator/Compiler.h397
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ConstantUnion.cpp803
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ConstantUnion.h122
-rw-r--r--gfx/angle/checkout/src/compiler/translator/Declarator.cpp33
-rw-r--r--gfx/angle/checkout/src/compiler/translator/Declarator.h49
-rw-r--r--gfx/angle/checkout/src/compiler/translator/Diagnostics.cpp106
-rw-r--r--gfx/angle/checkout/src/compiler/translator/Diagnostics.h67
-rw-r--r--gfx/angle/checkout/src/compiler/translator/DirectiveHandler.cpp304
-rw-r--r--gfx/angle/checkout/src/compiler/translator/DirectiveHandler.h57
-rw-r--r--gfx/angle/checkout/src/compiler/translator/DriverUniformMetal.h33
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ExtensionBehavior.cpp125
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ExtensionBehavior.h93
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ExtensionGLSL.cpp118
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ExtensionGLSL.h44
-rw-r--r--gfx/angle/checkout/src/compiler/translator/FlagStd140Structs.cpp76
-rw-r--r--gfx/angle/checkout/src/compiler/translator/FlagStd140Structs.h30
-rw-r--r--gfx/angle/checkout/src/compiler/translator/FunctionLookup.cpp179
-rw-r--r--gfx/angle/checkout/src/compiler/translator/FunctionLookup.h60
-rw-r--r--gfx/angle/checkout/src/compiler/translator/HashNames.cpp99
-rw-r--r--gfx/angle/checkout/src/compiler/translator/HashNames.h33
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ImageFunctionHLSL.cpp401
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ImageFunctionHLSL.h96
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ImmutableString.h143
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ImmutableStringBuilder.cpp63
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ImmutableStringBuilder.h80
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ImmutableString_ESSL_autogen.cpp345
-rw-r--r--gfx/angle/checkout/src/compiler/translator/InfoSink.cpp124
-rw-r--r--gfx/angle/checkout/src/compiler/translator/InfoSink.h152
-rw-r--r--gfx/angle/checkout/src/compiler/translator/Initialize.cpp223
-rw-r--r--gfx/angle/checkout/src/compiler/translator/Initialize.h30
-rw-r--r--gfx/angle/checkout/src/compiler/translator/InitializeDll.cpp33
-rw-r--r--gfx/angle/checkout/src/compiler/translator/InitializeDll.h15
-rw-r--r--gfx/angle/checkout/src/compiler/translator/InitializeGlobals.h13
-rw-r--r--gfx/angle/checkout/src/compiler/translator/IntermNode.cpp4226
-rw-r--r--gfx/angle/checkout/src/compiler/translator/IntermNode.h1046
-rw-r--r--gfx/angle/checkout/src/compiler/translator/IsASTDepthBelowLimit.cpp37
-rw-r--r--gfx/angle/checkout/src/compiler/translator/IsASTDepthBelowLimit.h20
-rw-r--r--gfx/angle/checkout/src/compiler/translator/Operator.cpp171
-rw-r--r--gfx/angle/checkout/src/compiler/translator/Operator_autogen.h578
-rw-r--r--gfx/angle/checkout/src/compiler/translator/OutputESSL.cpp55
-rw-r--r--gfx/angle/checkout/src/compiler/translator/OutputESSL.h30
-rw-r--r--gfx/angle/checkout/src/compiler/translator/OutputGLSL.cpp122
-rw-r--r--gfx/angle/checkout/src/compiler/translator/OutputGLSL.h31
-rw-r--r--gfx/angle/checkout/src/compiler/translator/OutputGLSLBase.cpp1513
-rw-r--r--gfx/angle/checkout/src/compiler/translator/OutputGLSLBase.h154
-rw-r--r--gfx/angle/checkout/src/compiler/translator/OutputHLSL.cpp3700
-rw-r--r--gfx/angle/checkout/src/compiler/translator/OutputHLSL.h289
-rw-r--r--gfx/angle/checkout/src/compiler/translator/OutputTree.cpp723
-rw-r--r--gfx/angle/checkout/src/compiler/translator/OutputTree.h22
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ParseContext.cpp7538
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ParseContext.h818
-rw-r--r--gfx/angle/checkout/src/compiler/translator/PoolAlloc.cpp40
-rw-r--r--gfx/angle/checkout/src/compiler/translator/PoolAlloc.h102
-rw-r--r--gfx/angle/checkout/src/compiler/translator/Pragma.h28
-rw-r--r--gfx/angle/checkout/src/compiler/translator/QualifierTypes.cpp1007
-rw-r--r--gfx/angle/checkout/src/compiler/translator/QualifierTypes.h214
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ResourcesHLSL.cpp989
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ResourcesHLSL.h155
-rw-r--r--gfx/angle/checkout/src/compiler/translator/Severity.h22
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ShaderLang.cpp1091
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ShaderStorageBlockFunctionHLSL.cpp439
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ShaderStorageBlockFunctionHLSL.h94
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ShaderStorageBlockOutputHLSL.cpp667
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ShaderStorageBlockOutputHLSL.h86
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ShaderVars.cpp625
-rw-r--r--gfx/angle/checkout/src/compiler/translator/StaticType.h296
-rw-r--r--gfx/angle/checkout/src/compiler/translator/StructureHLSL.cpp668
-rw-r--r--gfx/angle/checkout/src/compiler/translator/StructureHLSL.h102
-rw-r--r--gfx/angle/checkout/src/compiler/translator/Symbol.cpp254
-rw-r--r--gfx/angle/checkout/src/compiler/translator/Symbol.h402
-rw-r--r--gfx/angle/checkout/src/compiler/translator/SymbolTable.cpp559
-rw-r--r--gfx/angle/checkout/src/compiler/translator/SymbolTable.h363
-rw-r--r--gfx/angle/checkout/src/compiler/translator/SymbolTable_ESSL_autogen.cpp30071
-rw-r--r--gfx/angle/checkout/src/compiler/translator/SymbolTable_autogen.h169
-rw-r--r--gfx/angle/checkout/src/compiler/translator/SymbolUniqueId.cpp27
-rw-r--r--gfx/angle/checkout/src/compiler/translator/SymbolUniqueId.h58
-rw-r--r--gfx/angle/checkout/src/compiler/translator/TextureFunctionHLSL.cpp1614
-rw-r--r--gfx/angle/checkout/src/compiler/translator/TextureFunctionHLSL.h77
-rw-r--r--gfx/angle/checkout/src/compiler/translator/TranslatorESSL.cpp219
-rw-r--r--gfx/angle/checkout/src/compiler/translator/TranslatorESSL.h35
-rw-r--r--gfx/angle/checkout/src/compiler/translator/TranslatorGLSL.cpp388
-rw-r--r--gfx/angle/checkout/src/compiler/translator/TranslatorGLSL.h38
-rw-r--r--gfx/angle/checkout/src/compiler/translator/TranslatorHLSL.cpp311
-rw-r--r--gfx/angle/checkout/src/compiler/translator/TranslatorHLSL.h56
-rw-r--r--gfx/angle/checkout/src/compiler/translator/TranslatorMetal.h62
-rw-r--r--gfx/angle/checkout/src/compiler/translator/TranslatorMetalDirect.h195
-rw-r--r--gfx/angle/checkout/src/compiler/translator/TranslatorVulkan.h60
-rw-r--r--gfx/angle/checkout/src/compiler/translator/Types.cpp984
-rw-r--r--gfx/angle/checkout/src/compiler/translator/Types.h508
-rw-r--r--gfx/angle/checkout/src/compiler/translator/UtilsHLSL.cpp1223
-rw-r--r--gfx/angle/checkout/src/compiler/translator/UtilsHLSL.h148
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ValidateAST.cpp1133
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ValidateAST.h108
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ValidateBarrierFunctionCall.cpp100
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ValidateBarrierFunctionCall.h22
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ValidateClipCullDistance.cpp200
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ValidateClipCullDistance.h27
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ValidateGlobalInitializer.cpp157
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ValidateGlobalInitializer.h24
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ValidateLimitations.cpp452
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ValidateLimitations.h26
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ValidateMaxParameters.cpp30
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ValidateMaxParameters.h21
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ValidateOutputs.cpp184
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ValidateOutputs.h30
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ValidateSwitch.cpp315
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ValidateSwitch.h27
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ValidateTypeSizeLimitations.cpp229
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ValidateTypeSizeLimitations.h25
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ValidateVaryingLocations.cpp368
-rw-r--r--gfx/angle/checkout/src/compiler/translator/ValidateVaryingLocations.h28
-rw-r--r--gfx/angle/checkout/src/compiler/translator/VariablePacker.cpp409
-rw-r--r--gfx/angle/checkout/src/compiler/translator/VariablePacker.h32
-rw-r--r--gfx/angle/checkout/src/compiler/translator/VersionGLSL.cpp156
-rw-r--r--gfx/angle/checkout/src/compiler/translator/VersionGLSL.h76
-rw-r--r--gfx/angle/checkout/src/compiler/translator/blocklayout.cpp666
-rw-r--r--gfx/angle/checkout/src/compiler/translator/blocklayout.h322
-rw-r--r--gfx/angle/checkout/src/compiler/translator/blocklayoutHLSL.cpp167
-rw-r--r--gfx/angle/checkout/src/compiler/translator/blocklayoutHLSL.h68
-rw-r--r--gfx/angle/checkout/src/compiler/translator/emulated_builtin_functions_hlsl_autogen.cpp881
-rw-r--r--gfx/angle/checkout/src/compiler/translator/glslang.h24
-rw-r--r--gfx/angle/checkout/src/compiler/translator/glslang_lex_autogen.cpp4326
-rw-r--r--gfx/angle/checkout/src/compiler/translator/glslang_tab_autogen.cpp4909
-rw-r--r--gfx/angle/checkout/src/compiler/translator/glslang_tab_autogen.h320
-rw-r--r--gfx/angle/checkout/src/compiler/translator/glslang_wrapper.h46
-rw-r--r--gfx/angle/checkout/src/compiler/translator/length_limits.h26
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/ClampIndirectIndices.cpp136
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/ClampIndirectIndices.h27
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/ClampPointSize.cpp52
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/ClampPointSize.h28
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/ConvertUnsupportedConstructorsToFunctionCalls.cpp335
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/ConvertUnsupportedConstructorsToFunctionCalls.h25
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/DeclareAndInitBuiltinsForInstancedMultiview.cpp196
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/DeclareAndInitBuiltinsForInstancedMultiview.h52
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/DeferGlobalInitializers.cpp180
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/DeferGlobalInitializers.h38
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateGLFragColorBroadcast.cpp142
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateGLFragColorBroadcast.h35
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateMultiDrawShaderBuiltins.cpp274
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateMultiDrawShaderBuiltins.h47
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/FoldExpressions.cpp120
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/FoldExpressions.h29
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/ForcePrecisionQualifier.cpp101
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/ForcePrecisionQualifier.h17
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/InitializeVariables.cpp359
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/InitializeVariables.h60
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/MonomorphizeUnsupportedFunctions.cpp613
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/MonomorphizeUnsupportedFunctions.h54
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/NameNamelessUniformBuffers.cpp127
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/NameNamelessUniformBuffers.h32
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/PruneEmptyCases.cpp127
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/PruneEmptyCases.h22
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/PruneNoOps.cpp215
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/PruneNoOps.h29
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RecordConstantPrecision.cpp119
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RecordConstantPrecision.h33
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveArrayLengthMethod.cpp109
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveArrayLengthMethod.h37
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveAtomicCounterBuiltins.cpp74
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveAtomicCounterBuiltins.h24
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveDynamicIndexing.cpp597
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveDynamicIndexing.h41
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveInactiveInterfaceVariables.cpp209
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveInactiveInterfaceVariables.h42
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveInvariantDeclaration.cpp47
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveInvariantDeclaration.h21
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveUnreferencedVariables.cpp371
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveUnreferencedVariables.h29
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteArrayOfArrayOfOpaqueUniforms.cpp348
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteArrayOfArrayOfOpaqueUniforms.h25
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteAtomicCounters.cpp328
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteAtomicCounters.h28
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteCubeMapSamplersAs2DArray.cpp984
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteCubeMapSamplersAs2DArray.h29
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteDfdy.cpp141
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteDfdy.h32
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RewritePixelLocalStorage.cpp861
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RewritePixelLocalStorage.h29
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteStructSamplers.cpp673
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteStructSamplers.h38
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteTexelFetchOffset.cpp168
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteTexelFetchOffset.h34
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/ScalarizeVecAndMatConstructorArgs.cpp223
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/ScalarizeVecAndMatConstructorArgs.h28
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateDeclarations.cpp199
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateDeclarations.h32
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateStructFromUniformDeclarations.cpp115
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateStructFromUniformDeclarations.h39
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/SimplifyLoopConditions.cpp499
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/SimplifyLoopConditions.h32
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/SplitSequenceOperator.cpp173
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/SplitSequenceOperator.h30
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/apple/AddAndTrueToLoopCondition.cpp60
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/apple/AddAndTrueToLoopCondition.h31
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteDoWhile.cpp147
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteDoWhile.h38
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteRowMajorMatrices.cpp1595
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteRowMajorMatrices.h37
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteUnaryMinusOperatorFloat.cpp97
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteUnaryMinusOperatorFloat.h31
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/apple/UnfoldShortCircuitAST.cpp74
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/apple/UnfoldShortCircuitAST.h33
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AddDefaultReturnStatements.cpp61
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AddDefaultReturnStatements.h24
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AggregateAssignArraysInSSBOs.cpp82
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AggregateAssignArraysInSSBOs.h23
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AggregateAssignStructsInSSBOs.cpp76
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AggregateAssignStructsInSSBOs.h23
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/ArrayReturnValueToOutParameter.cpp233
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/ArrayReturnValueToOutParameter.h27
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/BreakVariableAliasingInInnerLoops.cpp110
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/BreakVariableAliasingInInnerLoops.h25
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/ExpandIntegerPowExpressions.cpp152
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/ExpandIntegerPowExpressions.h34
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RecordUniformBlocksWithLargeArrayMember.cpp385
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RecordUniformBlocksWithLargeArrayMember.h28
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RemoveSwitchFallThrough.cpp270
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RemoveSwitchFallThrough.h27
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteAtomicFunctionExpressions.cpp183
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteAtomicFunctionExpressions.h42
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteElseBlocks.cpp123
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteElseBlocks.h27
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteExpressionsWithShaderStorageBlock.cpp420
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteExpressionsWithShaderStorageBlock.h37
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteUnaryMinusOperatorInt.cpp117
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteUnaryMinusOperatorInt.h23
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateArrayConstructorStatements.cpp83
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateArrayConstructorStatements.h25
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateArrayInitialization.cpp89
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateArrayInitialization.h32
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateExpressionsReturningArrays.cpp138
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateExpressionsReturningArrays.h28
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/UnfoldShortCircuitToIf.cpp200
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/UnfoldShortCircuitToIf.h30
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/WrapSwitchStatementsInBlocks.cpp126
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/WrapSwitchStatementsInBlocks.h25
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/gl/ClampFragDepth.cpp54
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/gl/ClampFragDepth.h39
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/gl/RegenerateStructNames.cpp119
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/gl/RegenerateStructNames.h34
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/gl/RewriteRepeatedAssignToSwizzled.cpp97
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/gl/RewriteRepeatedAssignToSwizzled.h40
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/gl/UseInterfaceBlockFields.cpp108
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_ops/gl/UseInterfaceBlockFields.h44
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/AsNode.h212
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/BuiltIn.h18
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/BuiltIn_ESSL_autogen.h4177
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/BuiltIn_complete_autogen.h5008
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/DriverUniform.cpp435
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/DriverUniform.h110
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/FindFunction.cpp32
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/FindFunction.h21
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/FindMain.cpp54
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/FindMain.h24
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/FindPreciseNodes.cpp703
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/FindPreciseNodes.h25
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/FindSymbolNode.cpp53
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/FindSymbolNode.h23
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/IntermNodePatternMatcher.cpp213
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/IntermNodePatternMatcher.h81
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/IntermNode_util.cpp436
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/IntermNode_util.h128
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/IntermRebuild.cpp1046
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/IntermRebuild.h328
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/IntermTraverse.cpp708
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/IntermTraverse.h379
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/NodeSearch.h56
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/NodeType.h155
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceArrayOfMatrixVarying.cpp175
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceArrayOfMatrixVarying.h33
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceClipCullDistanceVariable.cpp591
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceClipCullDistanceVariable.h43
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceShadowingVariables.cpp142
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceShadowingVariables.h26
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceVariable.cpp145
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceVariable.h48
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/RewriteSampleMaskVariable.cpp198
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/RewriteSampleMaskVariable.h38
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/RunAtTheBeginningOfShader.cpp35
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/RunAtTheBeginningOfShader.h27
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/RunAtTheEndOfShader.cpp129
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/RunAtTheEndOfShader.h29
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/SpecializationConstant.cpp122
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/SpecializationConstant.h55
-rw-r--r--gfx/angle/checkout/src/compiler/translator/tree_util/Visit.h22
-rw-r--r--gfx/angle/checkout/src/compiler/translator/util.cpp1023
-rw-r--r--gfx/angle/checkout/src/compiler/translator/util.h108
-rw-r--r--gfx/angle/checkout/src/gpu_info_util/SystemInfo.cpp418
-rw-r--r--gfx/angle/checkout/src/gpu_info_util/SystemInfo.h179
-rw-r--r--gfx/angle/checkout/src/gpu_info_util/SystemInfo_internal.h42
-rw-r--r--gfx/angle/checkout/src/gpu_info_util/SystemInfo_vulkan.cpp284
-rw-r--r--gfx/angle/checkout/src/gpu_info_util/SystemInfo_vulkan.h23
-rw-r--r--gfx/angle/checkout/src/gpu_info_util/SystemInfo_win.cpp117
-rw-r--r--gfx/angle/checkout/src/image_util/copyimage.cpp74
-rw-r--r--gfx/angle/checkout/src/image_util/copyimage.h46
-rw-r--r--gfx/angle/checkout/src/image_util/copyimage.inc38
-rw-r--r--gfx/angle/checkout/src/image_util/generatemip.h34
-rw-r--r--gfx/angle/checkout/src/image_util/generatemip.inc268
-rw-r--r--gfx/angle/checkout/src/image_util/imageformats.cpp1954
-rw-r--r--gfx/angle/checkout/src/image_util/imageformats.h816
-rw-r--r--gfx/angle/checkout/src/image_util/loadimage.cpp1796
-rw-r--r--gfx/angle/checkout/src/image_util/loadimage.h976
-rw-r--r--gfx/angle/checkout/src/image_util/loadimage.inc201
-rw-r--r--gfx/angle/checkout/src/image_util/loadimage_astc.cpp84
-rw-r--r--gfx/angle/checkout/src/image_util/loadimage_etc.cpp1994
-rw-r--r--gfx/angle/checkout/src/image_util/loadimage_paletted.cpp158
-rw-r--r--gfx/angle/checkout/src/libANGLE/AttributeMap.cpp147
-rw-r--r--gfx/angle/checkout/src/libANGLE/AttributeMap.h100
-rw-r--r--gfx/angle/checkout/src/libANGLE/BinaryStream.h286
-rw-r--r--gfx/angle/checkout/src/libANGLE/BlobCache.cpp277
-rw-r--r--gfx/angle/checkout/src/libANGLE/BlobCache.h182
-rw-r--r--gfx/angle/checkout/src/libANGLE/Buffer.cpp449
-rw-r--r--gfx/angle/checkout/src/libANGLE/Buffer.h218
-rw-r--r--gfx/angle/checkout/src/libANGLE/Caps.cpp1371
-rw-r--r--gfx/angle/checkout/src/libANGLE/Caps.h786
-rw-r--r--gfx/angle/checkout/src/libANGLE/Compiler.cpp422
-rw-r--r--gfx/angle/checkout/src/libANGLE/Compiler.h78
-rw-r--r--gfx/angle/checkout/src/libANGLE/Config.cpp416
-rw-r--r--gfx/angle/checkout/src/libANGLE/Config.h115
-rw-r--r--gfx/angle/checkout/src/libANGLE/Constants.h125
-rw-r--r--gfx/angle/checkout/src/libANGLE/Context.cpp10472
-rw-r--r--gfx/angle/checkout/src/libANGLE/Context.h901
-rw-r--r--gfx/angle/checkout/src/libANGLE/Context.inl.h176
-rw-r--r--gfx/angle/checkout/src/libANGLE/Context_gl.cpp3706
-rw-r--r--gfx/angle/checkout/src/libANGLE/Context_gl_1_autogen.h349
-rw-r--r--gfx/angle/checkout/src/libANGLE/Context_gl_2_autogen.h44
-rw-r--r--gfx/angle/checkout/src/libANGLE/Context_gl_3_autogen.h82
-rw-r--r--gfx/angle/checkout/src/libANGLE/Context_gl_4_autogen.h358
-rw-r--r--gfx/angle/checkout/src/libANGLE/Context_gles_1_0.cpp746
-rw-r--r--gfx/angle/checkout/src/libANGLE/Context_gles_1_0_autogen.h109
-rw-r--r--gfx/angle/checkout/src/libANGLE/Context_gles_2_0_autogen.h190
-rw-r--r--gfx/angle/checkout/src/libANGLE/Context_gles_3_0_autogen.h164
-rw-r--r--gfx/angle/checkout/src/libANGLE/Context_gles_3_1_autogen.h133
-rw-r--r--gfx/angle/checkout/src/libANGLE/Context_gles_3_2_autogen.h83
-rw-r--r--gfx/angle/checkout/src/libANGLE/Context_gles_ext_autogen.h616
-rw-r--r--gfx/angle/checkout/src/libANGLE/Debug.cpp507
-rw-r--r--gfx/angle/checkout/src/libANGLE/Debug.h180
-rw-r--r--gfx/angle/checkout/src/libANGLE/Device.cpp133
-rw-r--r--gfx/angle/checkout/src/libANGLE/Device.h60
-rw-r--r--gfx/angle/checkout/src/libANGLE/Display.cpp2506
-rw-r--r--gfx/angle/checkout/src/libANGLE/Display.h427
-rw-r--r--gfx/angle/checkout/src/libANGLE/EGLSync.cpp114
-rw-r--r--gfx/angle/checkout/src/libANGLE/EGLSync.h72
-rw-r--r--gfx/angle/checkout/src/libANGLE/Error.cpp67
-rw-r--r--gfx/angle/checkout/src/libANGLE/Error.h206
-rw-r--r--gfx/angle/checkout/src/libANGLE/Error.inc91
-rw-r--r--gfx/angle/checkout/src/libANGLE/ErrorStrings.h627
-rw-r--r--gfx/angle/checkout/src/libANGLE/Fence.cpp124
-rw-r--r--gfx/angle/checkout/src/libANGLE/Fence.h88
-rw-r--r--gfx/angle/checkout/src/libANGLE/Framebuffer.cpp2727
-rw-r--r--gfx/angle/checkout/src/libANGLE/Framebuffer.h538
-rw-r--r--gfx/angle/checkout/src/libANGLE/FramebufferAttachment.cpp350
-rw-r--r--gfx/angle/checkout/src/libANGLE/FramebufferAttachment.h307
-rw-r--r--gfx/angle/checkout/src/libANGLE/GLES1Renderer.cpp1197
-rw-r--r--gfx/angle/checkout/src/libANGLE/GLES1Renderer.h340
-rw-r--r--gfx/angle/checkout/src/libANGLE/GLES1Shaders.inc1218
-rw-r--r--gfx/angle/checkout/src/libANGLE/GLES1State.cpp609
-rw-r--r--gfx/angle/checkout/src/libANGLE/GLES1State.h351
-rw-r--r--gfx/angle/checkout/src/libANGLE/HandleAllocator.cpp184
-rw-r--r--gfx/angle/checkout/src/libANGLE/HandleAllocator.h65
-rw-r--r--gfx/angle/checkout/src/libANGLE/Image.cpp581
-rw-r--r--gfx/angle/checkout/src/libANGLE/Image.h216
-rw-r--r--gfx/angle/checkout/src/libANGLE/ImageIndex.cpp388
-rw-r--r--gfx/angle/checkout/src/libANGLE/ImageIndex.h133
-rw-r--r--gfx/angle/checkout/src/libANGLE/IndexRangeCache.cpp116
-rw-r--r--gfx/angle/checkout/src/libANGLE/IndexRangeCache.h63
-rw-r--r--gfx/angle/checkout/src/libANGLE/InfoLog.h90
-rw-r--r--gfx/angle/checkout/src/libANGLE/LoggingAnnotator.cpp63
-rw-r--r--gfx/angle/checkout/src/libANGLE/LoggingAnnotator.h39
-rw-r--r--gfx/angle/checkout/src/libANGLE/MemoryObject.cpp66
-rw-r--r--gfx/angle/checkout/src/libANGLE/MemoryObject.h60
-rw-r--r--gfx/angle/checkout/src/libANGLE/MemoryProgramCache.cpp283
-rw-r--r--gfx/angle/checkout/src/libANGLE/MemoryProgramCache.h87
-rw-r--r--gfx/angle/checkout/src/libANGLE/MemoryShaderCache.cpp155
-rw-r--r--gfx/angle/checkout/src/libANGLE/MemoryShaderCache.h60
-rw-r--r--gfx/angle/checkout/src/libANGLE/Observer.cpp113
-rw-r--r--gfx/angle/checkout/src/libANGLE/Observer.h167
-rw-r--r--gfx/angle/checkout/src/libANGLE/Overlay.cpp103
-rw-r--r--gfx/angle/checkout/src/libANGLE/Overlay.h154
-rw-r--r--gfx/angle/checkout/src/libANGLE/OverlayWidgets.cpp737
-rw-r--r--gfx/angle/checkout/src/libANGLE/OverlayWidgets.h201
-rw-r--r--gfx/angle/checkout/src/libANGLE/Overlay_autogen.cpp824
-rw-r--r--gfx/angle/checkout/src/libANGLE/Overlay_autogen.h83
-rw-r--r--gfx/angle/checkout/src/libANGLE/Overlay_font_autogen.cpp5078
-rw-r--r--gfx/angle/checkout/src/libANGLE/Overlay_font_autogen.h27
-rw-r--r--gfx/angle/checkout/src/libANGLE/PixelLocalStorage.cpp826
-rw-r--r--gfx/angle/checkout/src/libANGLE/PixelLocalStorage.h177
-rw-r--r--gfx/angle/checkout/src/libANGLE/Platform.cpp76
-rw-r--r--gfx/angle/checkout/src/libANGLE/Program.cpp3810
-rw-r--r--gfx/angle/checkout/src/libANGLE/Program.h897
-rw-r--r--gfx/angle/checkout/src/libANGLE/ProgramExecutable.cpp1785
-rw-r--r--gfx/angle/checkout/src/libANGLE/ProgramExecutable.h517
-rw-r--r--gfx/angle/checkout/src/libANGLE/ProgramLinkedResources.cpp2377
-rw-r--r--gfx/angle/checkout/src/libANGLE/ProgramLinkedResources.h333
-rw-r--r--gfx/angle/checkout/src/libANGLE/ProgramPipeline.cpp721
-rw-r--r--gfx/angle/checkout/src/libANGLE/ProgramPipeline.h176
-rw-r--r--gfx/angle/checkout/src/libANGLE/Query.cpp96
-rw-r--r--gfx/angle/checkout/src/libANGLE/Query.h60
-rw-r--r--gfx/angle/checkout/src/libANGLE/RefCountObject.h327
-rw-r--r--gfx/angle/checkout/src/libANGLE/Renderbuffer.cpp423
-rw-r--r--gfx/angle/checkout/src/libANGLE/Renderbuffer.h181
-rw-r--r--gfx/angle/checkout/src/libANGLE/ResourceManager.cpp522
-rw-r--r--gfx/angle/checkout/src/libANGLE/ResourceManager.h353
-rw-r--r--gfx/angle/checkout/src/libANGLE/ResourceMap.h346
-rw-r--r--gfx/angle/checkout/src/libANGLE/Sampler.cpp211
-rw-r--r--gfx/angle/checkout/src/libANGLE/Sampler.h92
-rw-r--r--gfx/angle/checkout/src/libANGLE/Semaphore.cpp52
-rw-r--r--gfx/angle/checkout/src/libANGLE/Semaphore.h57
-rw-r--r--gfx/angle/checkout/src/libANGLE/Shader.cpp1331
-rw-r--r--gfx/angle/checkout/src/libANGLE/Shader.h305
-rw-r--r--gfx/angle/checkout/src/libANGLE/SizedMRUCache.h156
-rw-r--r--gfx/angle/checkout/src/libANGLE/State.cpp3866
-rw-r--r--gfx/angle/checkout/src/libANGLE/State.h1258
-rw-r--r--gfx/angle/checkout/src/libANGLE/Stream.cpp282
-rw-r--r--gfx/angle/checkout/src/libANGLE/Stream.h149
-rw-r--r--gfx/angle/checkout/src/libANGLE/Surface.cpp941
-rw-r--r--gfx/angle/checkout/src/libANGLE/Surface.h388
-rw-r--r--gfx/angle/checkout/src/libANGLE/Texture.cpp2494
-rw-r--r--gfx/angle/checkout/src/libANGLE/Texture.h738
-rw-r--r--gfx/angle/checkout/src/libANGLE/Thread.cpp168
-rw-r--r--gfx/angle/checkout/src/libANGLE/Thread.h80
-rw-r--r--gfx/angle/checkout/src/libANGLE/TransformFeedback.cpp347
-rw-r--r--gfx/angle/checkout/src/libANGLE/TransformFeedback.h120
-rw-r--r--gfx/angle/checkout/src/libANGLE/Uniform.cpp179
-rw-r--r--gfx/angle/checkout/src/libANGLE/Uniform.h138
-rw-r--r--gfx/angle/checkout/src/libANGLE/VaryingPacking.cpp1152
-rw-r--r--gfx/angle/checkout/src/libANGLE/VaryingPacking.h329
-rw-r--r--gfx/angle/checkout/src/libANGLE/Version.h34
-rw-r--r--gfx/angle/checkout/src/libANGLE/Version.inc59
-rw-r--r--gfx/angle/checkout/src/libANGLE/VertexArray.cpp906
-rw-r--r--gfx/angle/checkout/src/libANGLE/VertexArray.h436
-rw-r--r--gfx/angle/checkout/src/libANGLE/VertexAttribute.cpp170
-rw-r--r--gfx/angle/checkout/src/libANGLE/VertexAttribute.h139
-rw-r--r--gfx/angle/checkout/src/libANGLE/VertexAttribute.inc58
-rw-r--r--gfx/angle/checkout/src/libANGLE/WorkerThread.cpp356
-rw-r--r--gfx/angle/checkout/src/libANGLE/WorkerThread.h94
-rw-r--r--gfx/angle/checkout/src/libANGLE/angletypes.cpp1039
-rw-r--r--gfx/angle/checkout/src/libANGLE/angletypes.h1203
-rw-r--r--gfx/angle/checkout/src/libANGLE/angletypes.inc35
-rw-r--r--gfx/angle/checkout/src/libANGLE/capture/FrameCapture.h1208
-rw-r--r--gfx/angle/checkout/src/libANGLE/capture/FrameCapture_mock.cpp55
-rw-r--r--gfx/angle/checkout/src/libANGLE/capture/capture_egl.h69
-rw-r--r--gfx/angle/checkout/src/libANGLE/capture/capture_gl_1_autogen.h2072
-rw-r--r--gfx/angle/checkout/src/libANGLE/capture/capture_gl_2_autogen.h266
-rw-r--r--gfx/angle/checkout/src/libANGLE/capture/capture_gl_3_autogen.h609
-rw-r--r--gfx/angle/checkout/src/libANGLE/capture/capture_gl_4_autogen.h2524
-rw-r--r--gfx/angle/checkout/src/libANGLE/capture/capture_gles_1_0_autogen.h582
-rw-r--r--gfx/angle/checkout/src/libANGLE/capture/capture_gles_2_0_autogen.h1195
-rw-r--r--gfx/angle/checkout/src/libANGLE/capture/capture_gles_3_0_autogen.h1079
-rw-r--r--gfx/angle/checkout/src/libANGLE/capture/capture_gles_3_1_autogen.h728
-rw-r--r--gfx/angle/checkout/src/libANGLE/capture/capture_gles_3_2_autogen.h553
-rw-r--r--gfx/angle/checkout/src/libANGLE/capture/capture_gles_ext_autogen.h5231
-rw-r--r--gfx/angle/checkout/src/libANGLE/capture/frame_capture_utils.h23
-rw-r--r--gfx/angle/checkout/src/libANGLE/capture/frame_capture_utils_autogen.h3257
-rw-r--r--gfx/angle/checkout/src/libANGLE/capture/frame_capture_utils_mock.cpp19
-rw-r--r--gfx/angle/checkout/src/libANGLE/capture/gl_enum_utils.h32
-rw-r--r--gfx/angle/checkout/src/libANGLE/capture/gl_enum_utils_autogen.h419
-rw-r--r--gfx/angle/checkout/src/libANGLE/entry_points_utils.h127
-rw-r--r--gfx/angle/checkout/src/libANGLE/es3_copy_conversion_table_autogen.cpp171
-rw-r--r--gfx/angle/checkout/src/libANGLE/features.h56
-rw-r--r--gfx/angle/checkout/src/libANGLE/format_map_autogen.cpp1781
-rw-r--r--gfx/angle/checkout/src/libANGLE/format_map_desktop.cpp128
-rw-r--r--gfx/angle/checkout/src/libANGLE/formatutils.cpp3220
-rw-r--r--gfx/angle/checkout/src/libANGLE/formatutils.h577
-rw-r--r--gfx/angle/checkout/src/libANGLE/gles_extensions_autogen.cpp278
-rw-r--r--gfx/angle/checkout/src/libANGLE/gles_extensions_autogen.h727
-rw-r--r--gfx/angle/checkout/src/libANGLE/histogram_macros.h110
-rw-r--r--gfx/angle/checkout/src/libANGLE/queryconversions.cpp315
-rw-r--r--gfx/angle/checkout/src/libANGLE/queryconversions.h138
-rw-r--r--gfx/angle/checkout/src/libANGLE/queryutils.cpp4525
-rw-r--r--gfx/angle/checkout/src/libANGLE/queryutils.h293
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/BufferImpl.cpp39
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/BufferImpl.h98
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/CompilerImpl.h32
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/ContextImpl.cpp88
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/ContextImpl.h274
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/DeviceImpl.cpp18
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/DeviceImpl.h42
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/DisplayImpl.cpp168
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/DisplayImpl.h169
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/EGLImplFactory.h104
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/EGLReusableSync.cpp116
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/EGLReusableSync.h54
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/EGLSyncImpl.cpp37
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/EGLSyncImpl.h57
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/FenceNVImpl.h38
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/Format.h238
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/FormatID_autogen.h264
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/Format_table_autogen.cpp762
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/FramebufferAttachmentObjectImpl.h65
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/FramebufferImpl.cpp18
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/FramebufferImpl.h123
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/GLImplFactory.h116
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/ImageImpl.cpp30
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/ImageImpl.h68
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/MemoryObjectImpl.h47
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/OverlayImpl.h42
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/ProgramImpl.cpp18
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/ProgramImpl.h176
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/ProgramPipelineImpl.cpp26
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/ProgramPipelineImpl.h42
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/QueryImpl.cpp21
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/QueryImpl.h49
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/RenderTargetCache.h186
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/RenderbufferImpl.cpp19
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/RenderbufferImpl.h164
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/SamplerImpl.h44
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/SemaphoreImpl.h50
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/ShaderImpl.cpp105
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/ShaderImpl.h77
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/StreamProducerImpl.h40
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/SurfaceImpl.cpp158
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/SurfaceImpl.h136
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/SyncImpl.h45
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/TextureImpl.cpp200
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/TextureImpl.h254
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/TransformFeedbackImpl.cpp19
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/TransformFeedbackImpl.h42
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/VertexArrayImpl.cpp18
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/VertexArrayImpl.h70
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/copyvertex.h80
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/copyvertex.inc.h635
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/BufferD3D.cpp191
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/BufferD3D.h89
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/CompilerD3D.cpp24
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/CompilerD3D.h32
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/ContextD3D.h24
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/DeviceD3D.cpp84
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/DeviceD3D.h39
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/DisplayD3D.cpp462
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/DisplayD3D.h179
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/DynamicHLSL.cpp1537
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/DynamicHLSL.h212
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/DynamicImage2DHLSL.cpp919
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/DynamicImage2DHLSL.h28
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/EGLImageD3D.cpp93
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/EGLImageD3D.h55
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/FramebufferD3D.cpp402
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/FramebufferD3D.h143
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/HLSLCompiler.cpp387
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/HLSLCompiler.h74
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/ImageD3D.cpp56
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/ImageD3D.h105
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/IndexBuffer.cpp183
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/IndexBuffer.h125
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/IndexDataManager.cpp318
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/IndexDataManager.h112
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/NativeWindowD3D.cpp19
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/NativeWindowD3D.h38
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/ProgramD3D.cpp3412
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/ProgramD3D.h613
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/RenderTargetD3D.cpp31
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/RenderTargetD3D.h44
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/RenderbufferD3D.cpp126
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/RenderbufferD3D.h63
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/RendererD3D.cpp247
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/RendererD3D.h489
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/SamplerD3D.h33
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/ShaderD3D.cpp391
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/ShaderD3D.h126
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/ShaderExecutableD3D.cpp67
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/ShaderExecutableD3D.h57
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/SurfaceD3D.cpp517
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/SurfaceD3D.h145
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/SwapChainD3D.cpp34
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/SwapChainD3D.h83
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/TextureD3D.cpp4640
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/TextureD3D.h1050
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/TextureStorage.h135
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexBuffer.cpp308
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexBuffer.h189
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexDataManager.cpp683
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexDataManager.h163
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp1943
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Blit11.h300
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Blit11Helper_autogen.inc1575
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp1888
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Buffer11.h234
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp813
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Clear11.h102
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Context11.cpp1048
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Context11.h282
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp148
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h60
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ExternalImageSiblingImpl11.cpp209
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ExternalImageSiblingImpl11.h70
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Fence11.cpp234
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Fence11.h76
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp452
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h100
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Image11.cpp676
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Image11.h128
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.cpp160
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.h58
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp313
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h123
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/MappedSubresourceVerifier11.cpp119
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/MappedSubresourceVerifier11.h63
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/NativeWindow11.h38
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp271
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.h96
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Program11.cpp34
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Program11.h28
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ProgramPipeline11.cpp21
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ProgramPipeline11.h27
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Query11.cpp357
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Query11.h71
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.cpp323
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.h124
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp403
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.h133
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp4454
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Renderer11.h632
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ResourceManager11.cpp560
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ResourceManager11.h411
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.cpp116
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h69
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp4004
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/StateManager11.h692
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/StreamProducerD3DTexture.cpp166
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/StreamProducerD3DTexture.h44
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp1119
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h134
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp4352
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h1003
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/TransformFeedback11.cpp131
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/TransformFeedback11.h61
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Trim11.cpp103
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Trim11.h43
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexArray11.cpp375
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexArray11.h112
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp167
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.h65
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/converged/CompositorNativeWindow11.cpp457
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/converged/CompositorNativeWindow11.h116
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/formatutils11.cpp1029
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/formatutils11.h64
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp2751
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h478
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_gs.h80
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4f.h65
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4i.h65
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4ui.h65
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_vs.h145
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11_fl9vs.h71
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11multiviewgs.h83
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11multiviewvs.h80
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11vs.h69
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/cleardepth11ps.h74
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11_fl9ps.h128
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps1.h85
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps2.h91
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps3.h97
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps4.h104
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps5.h110
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps6.h116
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps7.h122
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps8.h128
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps1.h85
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps2.h91
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps3.h97
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps4.h104
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps5.h110
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps6.h116
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps7.h122
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps8.h128
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps1.h85
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps2.h91
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps3.h97
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps4.h104
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps5.h110
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps6.h116
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps7.h122
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps8.h128
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_luma_2d_ps.h76
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_luma_2darray_ps.h86
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_luma_3d_ps.h80
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_lumaalpha_2d_ps.h76
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_lumaalpha_2darray_ps.h86
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_lumaalpha_3d_ps.h80
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_2d_ps.h76
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_2darray_ps.h86
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_3d_ps.h80
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_565_2d_ps.h84
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_565_2darray_ps.h94
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_565_3d_ps.h88
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_2d_ps.h76
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_2darray_ps.h86
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_3d_ps.h80
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_4444_2d_ps.h82
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_4444_2darray_ps.h92
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_4444_3d_ps.h86
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_5551_2d_ps.h82
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_5551_2darray_ps.h92
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_5551_3d_ps.h86
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_luma_2d_ps.h82
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_luma_2darray_ps.h91
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_luma_3d_ps.h85
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_lumaalpha_2d_ps.h82
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_lumaalpha_2darray_ps.h91
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_lumaalpha_3d_ps.h85
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_2d_ps.h82
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_2darray_ps.h91
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_3d_ps.h85
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_565_2d_ps.h90
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_565_2darray_ps.h100
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_565_3d_ps.h93
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_2d_ps.h82
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_2darray_ps.h91
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_3d_ps.h85
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_4444_2d_ps.h88
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_4444_2darray_ps.h98
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_4444_3d_ps.h91
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_5551_2d_ps.h88
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_5551_2darray_ps.h98
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_5551_3d_ps.h91
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pm_rgb_2darray_ps.h96
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pm_rgb_3d_ps.h90
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pm_rgba_2darray_ps.h94
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pm_rgba_3d_ps.h88
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pt_rgb_2darray_ps.h94
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pt_rgb_3d_ps.h88
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pt_rgba_2darray_ps.h92
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pt_rgba_3d_ps.h85
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_um_rgb_2darray_ps.h102
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_um_rgb_3d_ps.h95
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_um_rgba_2darray_ps.h100
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_um_rgba_3d_ps.h93
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgb_2d_ps.h81
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgb_2darray_ps.h91
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgb_3d_ps.h85
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgba_2d_ps.h79
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgba_2darray_ps.h89
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgba_3d_ps.h83
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgb_2d_ps.h79
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgb_2darray_ps.h89
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgb_3d_ps.h80
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgba_2d_ps.h77
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgba_2darray_ps.h87
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgba_3d_ps.h80
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgb_2d_ps.h87
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgb_2darray_ps.h97
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgb_3d_ps.h90
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgba_2d_ps.h85
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgba_2darray_ps.h95
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgba_3d_ps.h88
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough2d11vs.h91
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11gs.h93
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11vs.h75
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrougha2d11ps.h103
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughdepth2d11ps.h73
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum2d11ps.h103
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum2darray11ps.h85
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum3d11ps.h79
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha2d11ps.h98
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha2darray11ps.h83
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha3d11ps.h77
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2d11ps.h104
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2darray11ps.h86
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2darrayi11ps.h90
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2darrayui11ps.h90
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2di11ps.h83
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2dui11ps.h83
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3d11ps.h80
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3di11ps.h86
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3dui11ps.h86
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2d11ps.h104
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2darray11ps.h86
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2darrayi11ps.h90
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2darrayui11ps.h90
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2di11ps.h83
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2dui11ps.h83
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3d11ps.h80
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3di11ps.h86
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3dui11ps.h86
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2d11ps.h103
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2d_565_11ps.h118
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2darray11ps.h85
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2darray_565_11ps.h91
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2darrayi11ps.h89
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2darrayui11ps.h89
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2di11ps.h82
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2dui11ps.h82
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3d11ps.h79
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3d_565_11ps.h85
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3di11ps.h85
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3dui11ps.h85
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d11ps.h93
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d_4444_11ps.h112
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d_5551_11ps.h112
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darray11ps.h81
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darray_4444_11ps.h89
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darray_5551_11ps.h89
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darrayi11ps.h85
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darrayui11ps.h85
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2di11ps.h78
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dms11ps.h80
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dui11ps.h78
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d11ps.h74
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d_4444_11ps.h83
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d_5551_11ps.h83
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3di11ps.h81
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3dui11ps.h81
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvecolor2dps.h103
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepth11_ps.h81
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepthstencil11_ps.h92
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepthstencil11_vs.h83
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvestencil11_ps.h84
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2darrayps.h135
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2dps.h126
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef3dps.h129
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2darrayps.h139
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2dps.h132
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei3dps.h135
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2darrayps.h139
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2dps.h132
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui3dps.h135
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/texture_format_table.cpp35
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/texture_format_table.h118
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp3269
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/texture_format_table_utils.h90
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow11Win32.cpp218
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow11Win32.h53
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Blit9.cpp760
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Blit9.h166
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp141
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Buffer9.h63
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Context9.cpp529
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Context9.h265
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.cpp48
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h38
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Fence9.cpp73
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Fence9.h39
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp416
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h89
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Image9.cpp907
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Image9.h112
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.cpp161
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.h57
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/NativeWindow9.cpp37
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/NativeWindow9.h35
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Query9.cpp176
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Query9.h50
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.cpp160
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.h98
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp3338
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Renderer9.h586
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/ShaderCache.h110
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.cpp51
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.h35
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp888
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/StateManager9.h211
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp472
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/SwapChain9.h80
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp575
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.h186
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexArray9.h57
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.cpp153
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.h56
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.cpp262
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h68
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp695
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/formatutils9.h59
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp845
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h105
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskpremultps.h50
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskps.h48
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskunmultps.h54
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/luminancepremultps.h50
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/luminanceps.h53
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/luminanceunmultps.h54
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/passthroughps.h37
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/standardvs.h46
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/vertexconversion.h197
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/driver_utils_d3d.cpp26
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/driver_utils_d3d.h21
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d/formatutilsD3D.h24
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d_format.cpp206
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/d3d_format.h58
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/driver_utils.cpp438
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/driver_utils.h278
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/dxgi_format_map.h27
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/dxgi_format_map_autogen.cpp516
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/dxgi_support_table.h43
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/dxgi_support_table_autogen.cpp3042
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/gl/functionsgl_enums.h1376
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/load_functions_table.h20
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/load_functions_table_autogen.cpp5465
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/renderer_utils.cpp1583
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/renderer_utils.h499
-rw-r--r--gfx/angle/checkout/src/libANGLE/renderer/serial_utils.h126
-rw-r--r--gfx/angle/checkout/src/libANGLE/trace.h26
-rw-r--r--gfx/angle/checkout/src/libANGLE/validationEGL.cpp6782
-rw-r--r--gfx/angle/checkout/src/libANGLE/validationEGL.h201
-rw-r--r--gfx/angle/checkout/src/libANGLE/validationEGL_autogen.h510
-rw-r--r--gfx/angle/checkout/src/libANGLE/validationES.cpp8666
-rw-r--r--gfx/angle/checkout/src/libANGLE/validationES.h1272
-rw-r--r--gfx/angle/checkout/src/libANGLE/validationES1.cpp2129
-rw-r--r--gfx/angle/checkout/src/libANGLE/validationES1.h20
-rw-r--r--gfx/angle/checkout/src/libANGLE/validationES1_autogen.h395
-rw-r--r--gfx/angle/checkout/src/libANGLE/validationES2.cpp6544
-rw-r--r--gfx/angle/checkout/src/libANGLE/validationES2.h207
-rw-r--r--gfx/angle/checkout/src/libANGLE/validationES2_autogen.h666
-rw-r--r--gfx/angle/checkout/src/libANGLE/validationES3.cpp5311
-rw-r--r--gfx/angle/checkout/src/libANGLE/validationES3.h72
-rw-r--r--gfx/angle/checkout/src/libANGLE/validationES31.cpp3157
-rw-r--r--gfx/angle/checkout/src/libANGLE/validationES31.h300
-rw-r--r--gfx/angle/checkout/src/libANGLE/validationES31_autogen.h415
-rw-r--r--gfx/angle/checkout/src/libANGLE/validationES32.cpp628
-rw-r--r--gfx/angle/checkout/src/libANGLE/validationES32.h20
-rw-r--r--gfx/angle/checkout/src/libANGLE/validationES32_autogen.h281
-rw-r--r--gfx/angle/checkout/src/libANGLE/validationES3_autogen.h578
-rw-r--r--gfx/angle/checkout/src/libANGLE/validationESEXT.cpp3599
-rw-r--r--gfx/angle/checkout/src/libANGLE/validationESEXT.h20
-rw-r--r--gfx/angle/checkout/src/libANGLE/validationESEXT_autogen.h2646
-rw-r--r--gfx/angle/checkout/src/libANGLE/validationGL1.cpp2421
-rw-r--r--gfx/angle/checkout/src/libANGLE/validationGL1_autogen.h1192
-rw-r--r--gfx/angle/checkout/src/libANGLE/validationGL2.cpp262
-rw-r--r--gfx/angle/checkout/src/libANGLE/validationGL2_autogen.h158
-rw-r--r--gfx/angle/checkout/src/libANGLE/validationGL3.cpp634
-rw-r--r--gfx/angle/checkout/src/libANGLE/validationGL3_autogen.h367
-rw-r--r--gfx/angle/checkout/src/libANGLE/validationGL4.cpp2223
-rw-r--r--gfx/angle/checkout/src/libANGLE/validationGL4_autogen.h1375
-rw-r--r--gfx/angle/checkout/src/libEGL/egl_loader_autogen.cpp320
-rw-r--r--gfx/angle/checkout/src/libEGL/egl_loader_autogen.h250
-rw-r--r--gfx/angle/checkout/src/libEGL/libEGL.rc103
-rw-r--r--gfx/angle/checkout/src/libEGL/libEGL_autogen.cpp917
-rw-r--r--gfx/angle/checkout/src/libEGL/libEGL_autogen.def193
-rw-r--r--gfx/angle/checkout/src/libEGL/resource.h14
-rw-r--r--gfx/angle/checkout/src/libGLESv2/egl_ext_stubs.cpp974
-rw-r--r--gfx/angle/checkout/src/libGLESv2/egl_ext_stubs_autogen.h264
-rw-r--r--gfx/angle/checkout/src/libGLESv2/egl_stubs.cpp777
-rw-r--r--gfx/angle/checkout/src/libGLESv2/egl_stubs_autogen.h165
-rw-r--r--gfx/angle/checkout/src/libGLESv2/entry_points_egl_autogen.cpp865
-rw-r--r--gfx/angle/checkout/src/libGLESv2/entry_points_egl_autogen.h138
-rw-r--r--gfx/angle/checkout/src/libGLESv2/entry_points_egl_ext_autogen.cpp1403
-rw-r--r--gfx/angle/checkout/src/libGLESv2/entry_points_egl_ext_autogen.h284
-rw-r--r--gfx/angle/checkout/src/libGLESv2/entry_points_gles_1_0_autogen.cpp2116
-rw-r--r--gfx/angle/checkout/src/libGLESv2/entry_points_gles_1_0_autogen.h123
-rw-r--r--gfx/angle/checkout/src/libGLESv2/entry_points_gles_2_0_autogen.cpp3864
-rw-r--r--gfx/angle/checkout/src/libGLESv2/entry_points_gles_2_0_autogen.h309
-rw-r--r--gfx/angle/checkout/src/libGLESv2/entry_points_gles_3_0_autogen.cpp3057
-rw-r--r--gfx/angle/checkout/src/libGLESv2/entry_points_gles_3_0_autogen.h299
-rw-r--r--gfx/angle/checkout/src/libGLESv2/entry_points_gles_3_1_autogen.cpp2098
-rw-r--r--gfx/angle/checkout/src/libGLESv2/entry_points_gles_3_1_autogen.h235
-rw-r--r--gfx/angle/checkout/src/libGLESv2/entry_points_gles_3_2_autogen.cpp1327
-rw-r--r--gfx/angle/checkout/src/libGLESv2/entry_points_gles_3_2_autogen.h172
-rw-r--r--gfx/angle/checkout/src/libGLESv2/entry_points_gles_ext_autogen.cpp11984
-rw-r--r--gfx/angle/checkout/src/libGLESv2/entry_points_gles_ext_autogen.h1788
-rw-r--r--gfx/angle/checkout/src/libGLESv2/global_state.cpp373
-rw-r--r--gfx/angle/checkout/src/libGLESv2/global_state.h215
-rw-r--r--gfx/angle/checkout/src/libGLESv2/libGLESv2.rc137
-rw-r--r--gfx/angle/checkout/src/libGLESv2/libGLESv2_autogen.cpp9704
-rw-r--r--gfx/angle/checkout/src/libGLESv2/libGLESv2_autogen.def1362
-rw-r--r--gfx/angle/checkout/src/libGLESv2/proc_table_egl.h25
-rw-r--r--gfx/angle/checkout/src/libGLESv2/proc_table_egl_autogen.cpp1623
-rw-r--r--gfx/angle/checkout/src/libGLESv2/resource.h17
-rw-r--r--gfx/angle/checkout/src/third_party/systeminfo/SystemInfo.cpp67
-rw-r--r--gfx/angle/checkout/src/third_party/systeminfo/SystemInfo.h36
-rw-r--r--gfx/angle/checkout/src/third_party/trace_event/trace_event.h777
-rw-r--r--gfx/angle/checkout/src/third_party/volk/volk.c2396
-rw-r--r--gfx/angle/checkout/src/third_party/volk/volk.h1578
1097 files changed, 502950 insertions, 0 deletions
diff --git a/gfx/angle/checkout/src/common/CircularBuffer.h b/gfx/angle/checkout/src/common/CircularBuffer.h
new file mode 100644
index 0000000000..3ff5f14d1b
--- /dev/null
+++ b/gfx/angle/checkout/src/common/CircularBuffer.h
@@ -0,0 +1,175 @@
+//
+// Copyright 2021 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.
+//
+// CircularBuffer.h:
+// An array class with an index that loops through the elements.
+//
+
+#ifndef COMMON_CIRCULARBUFFER_H_
+#define COMMON_CIRCULARBUFFER_H_
+
+#include "common/debug.h"
+
+#include <algorithm>
+#include <array>
+
+namespace angle
+{
+template <class T, size_t N, class Storage = std::array<T, N>>
+class CircularBuffer final
+{
+ public:
+ using value_type = typename Storage::value_type;
+ using size_type = typename Storage::size_type;
+ using reference = typename Storage::reference;
+ using const_reference = typename Storage::const_reference;
+ using pointer = typename Storage::pointer;
+ using const_pointer = typename Storage::const_pointer;
+ using iterator = typename Storage::iterator;
+ using const_iterator = typename Storage::const_iterator;
+
+ CircularBuffer();
+ CircularBuffer(const value_type &value);
+
+ CircularBuffer(const CircularBuffer<T, N, Storage> &other);
+ CircularBuffer(CircularBuffer<T, N, Storage> &&other);
+
+ CircularBuffer<T, N, Storage> &operator=(const CircularBuffer<T, N, Storage> &other);
+ CircularBuffer<T, N, Storage> &operator=(CircularBuffer<T, N, Storage> &&other);
+
+ ~CircularBuffer();
+
+ // begin() and end() are used to iterate over all elements regardless of the current position of
+ // the front of the buffer. Useful for initialization and clean up, as otherwise only the front
+ // element is expected to be accessed.
+ iterator begin();
+ const_iterator begin() const;
+
+ iterator end();
+ const_iterator end() const;
+
+ size_type size() const;
+
+ reference front();
+ const_reference front() const;
+
+ void swap(CircularBuffer<T, N, Storage> &other);
+
+ // Move the front forward to the next index, looping back to the beginning if the end of the
+ // array is reached.
+ void next();
+
+ private:
+ Storage mData;
+ size_type mFrontIndex;
+};
+
+template <class T, size_t N, class Storage>
+CircularBuffer<T, N, Storage>::CircularBuffer() : mFrontIndex(0)
+{}
+
+template <class T, size_t N, class Storage>
+CircularBuffer<T, N, Storage>::CircularBuffer(const value_type &value) : CircularBuffer()
+{
+ std::fill(begin(), end(), value);
+}
+
+template <class T, size_t N, class Storage>
+CircularBuffer<T, N, Storage>::CircularBuffer(const CircularBuffer<T, N, Storage> &other)
+{
+ *this = other;
+}
+
+template <class T, size_t N, class Storage>
+CircularBuffer<T, N, Storage>::CircularBuffer(CircularBuffer<T, N, Storage> &&other)
+ : CircularBuffer()
+{
+ swap(other);
+}
+
+template <class T, size_t N, class Storage>
+CircularBuffer<T, N, Storage> &CircularBuffer<T, N, Storage>::operator=(
+ const CircularBuffer<T, N, Storage> &other)
+{
+ std::copy(other.begin(), other.end(), begin());
+ mFrontIndex = other.mFrontIndex;
+ return *this;
+}
+
+template <class T, size_t N, class Storage>
+CircularBuffer<T, N, Storage> &CircularBuffer<T, N, Storage>::operator=(
+ CircularBuffer<T, N, Storage> &&other)
+{
+ swap(other);
+ return *this;
+}
+
+template <class T, size_t N, class Storage>
+CircularBuffer<T, N, Storage>::~CircularBuffer() = default;
+
+template <class T, size_t N, class Storage>
+ANGLE_INLINE typename CircularBuffer<T, N, Storage>::iterator CircularBuffer<T, N, Storage>::begin()
+{
+ return mData.begin();
+}
+
+template <class T, size_t N, class Storage>
+ANGLE_INLINE typename CircularBuffer<T, N, Storage>::const_iterator
+CircularBuffer<T, N, Storage>::begin() const
+{
+ return mData.begin();
+}
+
+template <class T, size_t N, class Storage>
+ANGLE_INLINE typename CircularBuffer<T, N, Storage>::iterator CircularBuffer<T, N, Storage>::end()
+{
+ return mData.end();
+}
+
+template <class T, size_t N, class Storage>
+ANGLE_INLINE typename CircularBuffer<T, N, Storage>::const_iterator
+CircularBuffer<T, N, Storage>::end() const
+{
+ return mData.end();
+}
+
+template <class T, size_t N, class Storage>
+ANGLE_INLINE typename CircularBuffer<T, N, Storage>::size_type CircularBuffer<T, N, Storage>::size()
+ const
+{
+ return N;
+}
+
+template <class T, size_t N, class Storage>
+ANGLE_INLINE typename CircularBuffer<T, N, Storage>::reference
+CircularBuffer<T, N, Storage>::front()
+{
+ ASSERT(mFrontIndex < size());
+ return mData[mFrontIndex];
+}
+
+template <class T, size_t N, class Storage>
+ANGLE_INLINE typename CircularBuffer<T, N, Storage>::const_reference
+CircularBuffer<T, N, Storage>::front() const
+{
+ ASSERT(mFrontIndex < size());
+ return mData[mFrontIndex];
+}
+
+template <class T, size_t N, class Storage>
+void CircularBuffer<T, N, Storage>::swap(CircularBuffer<T, N, Storage> &other)
+{
+ std::swap(mData, other.mData);
+ std::swap(mFrontIndex, other.mFrontIndex);
+}
+
+template <class T, size_t N, class Storage>
+void CircularBuffer<T, N, Storage>::next()
+{
+ mFrontIndex = (mFrontIndex + 1) % size();
+}
+} // namespace angle
+
+#endif // COMMON_CIRCULARBUFFER_H_
diff --git a/gfx/angle/checkout/src/common/Color.h b/gfx/angle/checkout/src/common/Color.h
new file mode 100644
index 0000000000..b228d8e8c5
--- /dev/null
+++ b/gfx/angle/checkout/src/common/Color.h
@@ -0,0 +1,104 @@
+//
+// 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.
+//
+
+// Color.h : Defines the Color type used throughout the ANGLE libraries
+
+#ifndef COMMON_COLOR_H_
+#define COMMON_COLOR_H_
+
+#include <cstdint>
+
+namespace angle
+{
+
+template <typename T>
+struct Color
+{
+ Color();
+ constexpr Color(T r, T g, T b, T a);
+
+ const T *data() const { return &red; }
+ T *ptr() { return &red; }
+
+ static Color fromData(const T *data) { return Color(data[0], data[1], data[2], data[3]); }
+ void writeData(T *data) const
+ {
+ data[0] = red;
+ data[1] = green;
+ data[2] = blue;
+ data[3] = alpha;
+ }
+
+ T red;
+ T green;
+ T blue;
+ T alpha;
+};
+
+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 ColorGeneric
+{
+ inline ColorGeneric();
+ inline ColorGeneric(const ColorF &color);
+ inline ColorGeneric(const ColorI &color);
+ inline ColorGeneric(const ColorUI &color);
+
+ enum class Type : uint8_t
+ {
+ Float = 0,
+ Int = 1,
+ UInt = 2
+ };
+
+ union
+ {
+ ColorF colorF;
+ ColorI colorI;
+ ColorUI colorUI;
+ };
+
+ Type type;
+};
+
+inline bool operator==(const ColorGeneric &a, const ColorGeneric &b);
+
+inline bool operator!=(const ColorGeneric &a, const ColorGeneric &b);
+
+struct DepthStencil
+{
+ DepthStencil() : depth(0), stencil(0) {}
+
+ // Double is needed to represent the 32-bit integer range of GL_DEPTH_COMPONENT32.
+ double depth;
+ uint32_t stencil;
+};
+} // 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;
+using ColorGeneric = angle::ColorGeneric;
+
+} // namespace gl
+
+#include "Color.inc"
+
+#endif // COMMON_COLOR_H_
diff --git a/gfx/angle/checkout/src/common/Color.inc b/gfx/angle/checkout/src/common/Color.inc
new file mode 100644
index 0000000000..0e1445111b
--- /dev/null
+++ b/gfx/angle/checkout/src/common/Color.inc
@@ -0,0 +1,69 @@
+//
+// 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.
+//
+
+// Color.inc : Inline definitions of some functions from Color.h
+
+namespace angle
+{
+
+template <typename T>
+Color<T>::Color() : Color(0, 0, 0, 0)
+{
+}
+
+template <typename T>
+constexpr 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);
+}
+
+
+ColorGeneric::ColorGeneric() : colorF(), type(Type::Float) {}
+
+ColorGeneric::ColorGeneric(const ColorF &color) : colorF(color), type(Type::Float) {}
+
+ColorGeneric::ColorGeneric(const ColorI &color) : colorI(color), type(Type::Int) {}
+
+ColorGeneric::ColorGeneric(const ColorUI &color) : colorUI(color), type(Type::UInt) {}
+
+bool operator==(const ColorGeneric &a, const ColorGeneric &b)
+{
+ if (a.type != b.type)
+ {
+ return false;
+ }
+ switch (a.type)
+ {
+ default:
+ case ColorGeneric::Type::Float:
+ return a.colorF == b.colorF;
+ case ColorGeneric::Type::Int:
+ return a.colorI == b.colorI;
+ case ColorGeneric::Type::UInt:
+ return a.colorUI == b.colorUI;
+ }
+}
+
+bool operator!=(const ColorGeneric &a, const ColorGeneric &b)
+{
+ return !(a == b);
+}
+
+} // namespace angle
diff --git a/gfx/angle/checkout/src/common/FastVector.h b/gfx/angle/checkout/src/common/FastVector.h
new file mode 100644
index 0000000000..6991adf715
--- /dev/null
+++ b/gfx/angle/checkout/src/common/FastVector.h
@@ -0,0 +1,891 @@
+//
+// Copyright 2018 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.
+//
+// FastVector.h:
+// A vector class with a initial fixed size and variable growth.
+// Based on FixedVector.
+//
+
+#ifndef COMMON_FASTVECTOR_H_
+#define COMMON_FASTVECTOR_H_
+
+#include "bitset_utils.h"
+#include "common/debug.h"
+
+#include <algorithm>
+#include <array>
+#include <initializer_list>
+#include <iterator>
+
+namespace angle
+{
+
+template <class Iter>
+class WrapIter
+{
+ public:
+ typedef Iter iterator_type;
+ typedef typename std::iterator_traits<iterator_type>::value_type value_type;
+ typedef typename std::iterator_traits<iterator_type>::difference_type difference_type;
+ typedef typename std::iterator_traits<iterator_type>::pointer pointer;
+ typedef typename std::iterator_traits<iterator_type>::reference reference;
+ typedef typename std::iterator_traits<iterator_type>::iterator_category iterator_category;
+
+ WrapIter() : mIter() {}
+ WrapIter(const Iter &iter) : mIter(iter) {}
+ ~WrapIter() = default;
+
+ WrapIter &operator=(const WrapIter &x)
+ {
+ mIter = x.mIter;
+ return *this;
+ }
+
+ bool operator==(const WrapIter &x) const { return mIter == x.mIter; }
+ bool operator!=(const WrapIter &x) const { return mIter != x.mIter; }
+ bool operator<(const WrapIter &x) const { return mIter < x.mIter; }
+ bool operator<=(const WrapIter &x) const { return mIter <= x.mIter; }
+ bool operator>(const WrapIter &x) const { return mIter > x.mIter; }
+ bool operator>=(const WrapIter &x) const { return mIter >= x.mIter; }
+
+ WrapIter &operator++()
+ {
+ mIter++;
+ return *this;
+ }
+
+ WrapIter operator++(int)
+ {
+ WrapIter tmp(mIter);
+ mIter++;
+ return tmp;
+ }
+
+ WrapIter operator+(difference_type n)
+ {
+ WrapIter tmp(mIter);
+ tmp.mIter += n;
+ return tmp;
+ }
+
+ WrapIter operator-(difference_type n)
+ {
+ WrapIter tmp(mIter);
+ tmp.mIter -= n;
+ return tmp;
+ }
+
+ difference_type operator-(const WrapIter &x) const { return mIter - x.mIter; }
+
+ iterator_type operator->() const { return mIter; }
+
+ reference operator*() const { return *mIter; }
+
+ private:
+ iterator_type mIter;
+};
+
+template <class T, size_t N, class Storage = std::array<T, N>>
+class FastVector final
+{
+ public:
+ using value_type = typename Storage::value_type;
+ using size_type = typename Storage::size_type;
+ using reference = typename Storage::reference;
+ using const_reference = typename Storage::const_reference;
+ using pointer = typename Storage::pointer;
+ using const_pointer = typename Storage::const_pointer;
+ using iterator = WrapIter<T *>;
+ using const_iterator = WrapIter<const T *>;
+
+ FastVector();
+ FastVector(size_type count, const value_type &value);
+ FastVector(size_type count);
+
+ FastVector(const FastVector<T, N, Storage> &other);
+ FastVector(FastVector<T, N, Storage> &&other);
+ FastVector(std::initializer_list<value_type> init);
+
+ template <class InputIt, std::enable_if_t<!std::is_integral<InputIt>::value, bool> = true>
+ FastVector(InputIt first, InputIt last);
+
+ FastVector<T, N, Storage> &operator=(const FastVector<T, N, Storage> &other);
+ FastVector<T, N, Storage> &operator=(FastVector<T, N, Storage> &&other);
+ FastVector<T, N, Storage> &operator=(std::initializer_list<value_type> init);
+
+ ~FastVector();
+
+ reference at(size_type pos);
+ const_reference at(size_type pos) const;
+
+ reference operator[](size_type pos);
+ const_reference operator[](size_type pos) const;
+
+ pointer data();
+ const_pointer data() const;
+
+ iterator begin();
+ const_iterator begin() const;
+
+ iterator end();
+ const_iterator end() const;
+
+ bool empty() const;
+ size_type size() const;
+
+ void clear();
+
+ void push_back(const value_type &value);
+ void push_back(value_type &&value);
+
+ template <typename... Args>
+ void emplace_back(Args &&...args);
+
+ void pop_back();
+
+ reference front();
+ const_reference front() const;
+
+ reference back();
+ const_reference back() const;
+
+ void swap(FastVector<T, N, Storage> &other);
+
+ void resize(size_type count);
+ void resize(size_type count, const value_type &value);
+
+ void reserve(size_type count);
+
+ // Specialty function that removes a known element and might shuffle the list.
+ void remove_and_permute(const value_type &element);
+ void remove_and_permute(iterator pos);
+
+ private:
+ void assign_from_initializer_list(std::initializer_list<value_type> init);
+ void ensure_capacity(size_t capacity);
+ bool uses_fixed_storage() const;
+
+ Storage mFixedStorage;
+ pointer mData = mFixedStorage.data();
+ size_type mSize = 0;
+ size_type mReservedSize = N;
+};
+
+template <class T, size_t N, class StorageN, size_t M, class StorageM>
+bool operator==(const FastVector<T, N, StorageN> &a, const FastVector<T, M, StorageM> &b)
+{
+ return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin());
+}
+
+template <class T, size_t N, class StorageN, size_t M, class StorageM>
+bool operator!=(const FastVector<T, N, StorageN> &a, const FastVector<T, M, StorageM> &b)
+{
+ return !(a == b);
+}
+
+template <class T, size_t N, class Storage>
+ANGLE_INLINE bool FastVector<T, N, Storage>::uses_fixed_storage() const
+{
+ return mData == mFixedStorage.data();
+}
+
+template <class T, size_t N, class Storage>
+FastVector<T, N, Storage>::FastVector()
+{}
+
+template <class T, size_t N, class Storage>
+FastVector<T, N, Storage>::FastVector(size_type count, const value_type &value)
+{
+ ensure_capacity(count);
+ mSize = count;
+ std::fill(begin(), end(), value);
+}
+
+template <class T, size_t N, class Storage>
+FastVector<T, N, Storage>::FastVector(size_type count)
+{
+ ensure_capacity(count);
+ mSize = count;
+}
+
+template <class T, size_t N, class Storage>
+FastVector<T, N, Storage>::FastVector(const FastVector<T, N, Storage> &other)
+ : FastVector(other.begin(), other.end())
+{}
+
+template <class T, size_t N, class Storage>
+FastVector<T, N, Storage>::FastVector(FastVector<T, N, Storage> &&other) : FastVector()
+{
+ swap(other);
+}
+
+template <class T, size_t N, class Storage>
+FastVector<T, N, Storage>::FastVector(std::initializer_list<value_type> init)
+{
+ assign_from_initializer_list(init);
+}
+
+template <class T, size_t N, class Storage>
+template <class InputIt, std::enable_if_t<!std::is_integral<InputIt>::value, bool>>
+FastVector<T, N, Storage>::FastVector(InputIt first, InputIt last)
+{
+ size_t newSize = last - first;
+ ensure_capacity(newSize);
+ mSize = newSize;
+ std::copy(first, last, begin());
+}
+
+template <class T, size_t N, class Storage>
+FastVector<T, N, Storage> &FastVector<T, N, Storage>::operator=(
+ const FastVector<T, N, Storage> &other)
+{
+ ensure_capacity(other.mSize);
+ mSize = other.mSize;
+ std::copy(other.begin(), other.end(), begin());
+ return *this;
+}
+
+template <class T, size_t N, class Storage>
+FastVector<T, N, Storage> &FastVector<T, N, Storage>::operator=(FastVector<T, N, Storage> &&other)
+{
+ swap(other);
+ return *this;
+}
+
+template <class T, size_t N, class Storage>
+FastVector<T, N, Storage> &FastVector<T, N, Storage>::operator=(
+ std::initializer_list<value_type> init)
+{
+ assign_from_initializer_list(init);
+ return *this;
+}
+
+template <class T, size_t N, class Storage>
+FastVector<T, N, Storage>::~FastVector()
+{
+ clear();
+ if (!uses_fixed_storage())
+ {
+ delete[] mData;
+ }
+}
+
+template <class T, size_t N, class Storage>
+typename FastVector<T, N, Storage>::reference FastVector<T, N, Storage>::at(size_type pos)
+{
+ ASSERT(pos < mSize);
+ return mData[pos];
+}
+
+template <class T, size_t N, class Storage>
+typename FastVector<T, N, Storage>::const_reference FastVector<T, N, Storage>::at(
+ size_type pos) const
+{
+ ASSERT(pos < mSize);
+ return mData[pos];
+}
+
+template <class T, size_t N, class Storage>
+ANGLE_INLINE typename FastVector<T, N, Storage>::reference FastVector<T, N, Storage>::operator[](
+ size_type pos)
+{
+ ASSERT(pos < mSize);
+ return mData[pos];
+}
+
+template <class T, size_t N, class Storage>
+ANGLE_INLINE typename FastVector<T, N, Storage>::const_reference
+FastVector<T, N, Storage>::operator[](size_type pos) const
+{
+ ASSERT(pos < mSize);
+ return mData[pos];
+}
+
+template <class T, size_t N, class Storage>
+ANGLE_INLINE typename FastVector<T, N, Storage>::const_pointer
+angle::FastVector<T, N, Storage>::data() const
+{
+ return mData;
+}
+
+template <class T, size_t N, class Storage>
+ANGLE_INLINE typename FastVector<T, N, Storage>::pointer angle::FastVector<T, N, Storage>::data()
+{
+ return mData;
+}
+
+template <class T, size_t N, class Storage>
+ANGLE_INLINE typename FastVector<T, N, Storage>::iterator FastVector<T, N, Storage>::begin()
+{
+ return mData;
+}
+
+template <class T, size_t N, class Storage>
+ANGLE_INLINE typename FastVector<T, N, Storage>::const_iterator FastVector<T, N, Storage>::begin()
+ const
+{
+ return mData;
+}
+
+template <class T, size_t N, class Storage>
+ANGLE_INLINE typename FastVector<T, N, Storage>::iterator FastVector<T, N, Storage>::end()
+{
+ return mData + mSize;
+}
+
+template <class T, size_t N, class Storage>
+ANGLE_INLINE typename FastVector<T, N, Storage>::const_iterator FastVector<T, N, Storage>::end()
+ const
+{
+ return mData + mSize;
+}
+
+template <class T, size_t N, class Storage>
+ANGLE_INLINE bool FastVector<T, N, Storage>::empty() const
+{
+ return mSize == 0;
+}
+
+template <class T, size_t N, class Storage>
+ANGLE_INLINE typename FastVector<T, N, Storage>::size_type FastVector<T, N, Storage>::size() const
+{
+ return mSize;
+}
+
+template <class T, size_t N, class Storage>
+void FastVector<T, N, Storage>::clear()
+{
+ resize(0);
+}
+
+template <class T, size_t N, class Storage>
+ANGLE_INLINE void FastVector<T, N, Storage>::push_back(const value_type &value)
+{
+ if (mSize == mReservedSize)
+ ensure_capacity(mSize + 1);
+ mData[mSize++] = value;
+}
+
+template <class T, size_t N, class Storage>
+ANGLE_INLINE void FastVector<T, N, Storage>::push_back(value_type &&value)
+{
+ emplace_back(std::move(value));
+}
+
+template <class T, size_t N, class Storage>
+template <typename... Args>
+ANGLE_INLINE void FastVector<T, N, Storage>::emplace_back(Args &&...args)
+{
+ if (mSize == mReservedSize)
+ ensure_capacity(mSize + 1);
+ mData[mSize++] = std::move(T(std::forward<Args>(args)...));
+}
+
+template <class T, size_t N, class Storage>
+ANGLE_INLINE void FastVector<T, N, Storage>::pop_back()
+{
+ ASSERT(mSize > 0);
+ mSize--;
+}
+
+template <class T, size_t N, class Storage>
+ANGLE_INLINE typename FastVector<T, N, Storage>::reference FastVector<T, N, Storage>::front()
+{
+ ASSERT(mSize > 0);
+ return mData[0];
+}
+
+template <class T, size_t N, class Storage>
+ANGLE_INLINE typename FastVector<T, N, Storage>::const_reference FastVector<T, N, Storage>::front()
+ const
+{
+ ASSERT(mSize > 0);
+ return mData[0];
+}
+
+template <class T, size_t N, class Storage>
+ANGLE_INLINE typename FastVector<T, N, Storage>::reference FastVector<T, N, Storage>::back()
+{
+ ASSERT(mSize > 0);
+ return mData[mSize - 1];
+}
+
+template <class T, size_t N, class Storage>
+ANGLE_INLINE typename FastVector<T, N, Storage>::const_reference FastVector<T, N, Storage>::back()
+ const
+{
+ ASSERT(mSize > 0);
+ return mData[mSize - 1];
+}
+
+template <class T, size_t N, class Storage>
+void FastVector<T, N, Storage>::swap(FastVector<T, N, Storage> &other)
+{
+ std::swap(mSize, other.mSize);
+
+ pointer tempData = other.mData;
+ if (uses_fixed_storage())
+ other.mData = other.mFixedStorage.data();
+ else
+ other.mData = mData;
+ if (tempData == other.mFixedStorage.data())
+ mData = mFixedStorage.data();
+ else
+ mData = tempData;
+ std::swap(mReservedSize, other.mReservedSize);
+
+ if (uses_fixed_storage() || other.uses_fixed_storage())
+ std::swap(mFixedStorage, other.mFixedStorage);
+}
+
+template <class T, size_t N, class Storage>
+void FastVector<T, N, Storage>::resize(size_type count)
+{
+ if (count > mSize)
+ {
+ ensure_capacity(count);
+ }
+ mSize = count;
+}
+
+template <class T, size_t N, class Storage>
+void FastVector<T, N, Storage>::resize(size_type count, const value_type &value)
+{
+ if (count > mSize)
+ {
+ ensure_capacity(count);
+ std::fill(mData + mSize, mData + count, value);
+ }
+ mSize = count;
+}
+
+template <class T, size_t N, class Storage>
+void FastVector<T, N, Storage>::reserve(size_type count)
+{
+ ensure_capacity(count);
+}
+
+template <class T, size_t N, class Storage>
+void FastVector<T, N, Storage>::assign_from_initializer_list(std::initializer_list<value_type> init)
+{
+ ensure_capacity(init.size());
+ mSize = init.size();
+ size_t index = 0;
+ for (auto &value : init)
+ {
+ mData[index++] = value;
+ }
+}
+
+template <class T, size_t N, class Storage>
+ANGLE_INLINE void FastVector<T, N, Storage>::remove_and_permute(const value_type &element)
+{
+ size_t len = mSize - 1;
+ for (size_t index = 0; index < len; ++index)
+ {
+ if (mData[index] == element)
+ {
+ mData[index] = std::move(mData[len]);
+ break;
+ }
+ }
+ pop_back();
+}
+
+template <class T, size_t N, class Storage>
+ANGLE_INLINE void FastVector<T, N, Storage>::remove_and_permute(iterator pos)
+{
+ ASSERT(pos >= begin());
+ ASSERT(pos < end());
+ size_t len = mSize - 1;
+ *pos = std::move(mData[len]);
+ pop_back();
+}
+
+template <class T, size_t N, class Storage>
+void FastVector<T, N, Storage>::ensure_capacity(size_t capacity)
+{
+ // We have a minimum capacity of N.
+ if (mReservedSize < capacity)
+ {
+ ASSERT(capacity > N);
+ size_type newSize = std::max(mReservedSize, N);
+ while (newSize < capacity)
+ {
+ newSize *= 2;
+ }
+
+ pointer newData = new value_type[newSize];
+
+ if (mSize > 0)
+ {
+ std::move(begin(), end(), newData);
+ }
+
+ if (!uses_fixed_storage())
+ {
+ delete[] mData;
+ }
+
+ mData = newData;
+ mReservedSize = newSize;
+ }
+}
+
+template <class Value, size_t N>
+class FastMap final
+{
+ public:
+ FastMap() {}
+ ~FastMap() {}
+
+ Value &operator[](uint32_t key)
+ {
+ if (mData.size() <= key)
+ {
+ mData.resize(key + 1, {});
+ }
+ return mData[key];
+ }
+
+ const Value &operator[](uint32_t key) const
+ {
+ ASSERT(key < mData.size());
+ return mData[key];
+ }
+
+ void clear() { mData.clear(); }
+
+ bool empty() const { return mData.empty(); }
+ size_t size() const { return mData.size(); }
+
+ const Value *data() const { return mData.data(); }
+
+ bool operator==(const FastMap<Value, N> &other) const
+ {
+ return (size() == other.size()) &&
+ (memcmp(data(), other.data(), size() * sizeof(Value)) == 0);
+ }
+
+ private:
+ FastVector<Value, N> mData;
+};
+
+template <class Key, class Value, size_t N>
+class FlatUnorderedMap final
+{
+ public:
+ using Pair = std::pair<Key, Value>;
+ using Storage = FastVector<Pair, N>;
+ using iterator = typename Storage::iterator;
+ using const_iterator = typename Storage::const_iterator;
+
+ FlatUnorderedMap() = default;
+ ~FlatUnorderedMap() = default;
+
+ iterator begin() { return mData.begin(); }
+ const_iterator begin() const { return mData.begin(); }
+ iterator end() { return mData.end(); }
+ const_iterator end() const { return mData.end(); }
+
+ iterator find(const Key &key)
+ {
+ for (auto it = mData.begin(); it != mData.end(); ++it)
+ {
+ if (it->first == key)
+ {
+ return it;
+ }
+ }
+ return mData.end();
+ }
+
+ const_iterator find(const Key &key) const
+ {
+ for (auto it = mData.begin(); it != mData.end(); ++it)
+ {
+ if (it->first == key)
+ {
+ return it;
+ }
+ }
+ return mData.end();
+ }
+
+ Value &operator[](const Key &key)
+ {
+ iterator it = find(key);
+ if (it != end())
+ {
+ return it->second;
+ }
+
+ mData.push_back(Pair(key, {}));
+ return mData.back().second;
+ }
+
+ void insert(Pair pair)
+ {
+ ASSERT(!contains(pair.first));
+ mData.push_back(std::move(pair));
+ }
+
+ void insert(const Key &key, Value value) { insert(Pair(key, value)); }
+
+ void erase(iterator pos) { mData.remove_and_permute(pos); }
+
+ bool contains(const Key &key) const { return find(key) != end(); }
+
+ void clear() { mData.clear(); }
+
+ bool get(const Key &key, Value *value) const
+ {
+ auto it = find(key);
+ if (it != end())
+ {
+ *value = it->second;
+ return true;
+ }
+ return false;
+ }
+
+ bool empty() const { return mData.empty(); }
+ size_t size() const { return mData.size(); }
+
+ private:
+ FastVector<Pair, N> mData;
+};
+
+template <class T, size_t N>
+class FlatUnorderedSet final
+{
+ public:
+ using Storage = FastVector<T, N>;
+ using iterator = typename Storage::iterator;
+ using const_iterator = typename Storage::const_iterator;
+
+ FlatUnorderedSet() = default;
+ ~FlatUnorderedSet() = default;
+
+ iterator begin() { return mData.begin(); }
+ const_iterator begin() const { return mData.begin(); }
+ iterator end() { return mData.end(); }
+ const_iterator end() const { return mData.end(); }
+
+ iterator find(const T &value)
+ {
+ for (auto it = mData.begin(); it != mData.end(); ++it)
+ {
+ if (*it == value)
+ {
+ return it;
+ }
+ }
+ return mData.end();
+ }
+
+ const_iterator find(const T &value) const
+ {
+ for (auto it = mData.begin(); it != mData.end(); ++it)
+ {
+ if (*it == value)
+ {
+ return it;
+ }
+ }
+ return mData.end();
+ }
+
+ bool empty() const { return mData.empty(); }
+
+ void insert(const T &value)
+ {
+ ASSERT(!contains(value));
+ mData.push_back(value);
+ }
+
+ void erase(const T &value)
+ {
+ ASSERT(contains(value));
+ mData.remove_and_permute(value);
+ }
+
+ void remove(const T &value) { erase(value); }
+
+ bool contains(const T &value) const { return find(value) != end(); }
+
+ void clear() { mData.clear(); }
+
+ bool operator==(const FlatUnorderedSet<T, N> &other) const { return mData == other.mData; }
+
+ private:
+ Storage mData;
+};
+
+class FastIntegerSet final
+{
+ public:
+ static constexpr size_t kWindowSize = 64;
+ static constexpr size_t kOneLessThanKWindowSize = kWindowSize - 1;
+ static constexpr size_t kShiftForDivision =
+ static_cast<size_t>(rx::Log2(static_cast<unsigned int>(kWindowSize)));
+ using KeyBitSet = angle::BitSet64<kWindowSize>;
+
+ ANGLE_INLINE FastIntegerSet();
+ ANGLE_INLINE ~FastIntegerSet();
+
+ ANGLE_INLINE void ensureCapacity(size_t size)
+ {
+ if (capacity() <= size)
+ {
+ reserve(size * 2);
+ }
+ }
+
+ ANGLE_INLINE void insert(uint64_t key)
+ {
+ size_t sizedKey = static_cast<size_t>(key);
+
+ ASSERT(!contains(sizedKey));
+ ensureCapacity(sizedKey);
+ ASSERT(capacity() > sizedKey);
+
+ size_t index = sizedKey >> kShiftForDivision;
+ size_t offset = sizedKey & kOneLessThanKWindowSize;
+
+ mKeyData[index].set(offset, true);
+ }
+
+ ANGLE_INLINE bool contains(uint64_t key) const
+ {
+ size_t sizedKey = static_cast<size_t>(key);
+
+ size_t index = sizedKey >> kShiftForDivision;
+ size_t offset = sizedKey & kOneLessThanKWindowSize;
+
+ return (sizedKey < capacity()) && (mKeyData[index].test(offset));
+ }
+
+ ANGLE_INLINE void clear()
+ {
+ for (KeyBitSet &it : mKeyData)
+ {
+ it.reset();
+ }
+ }
+
+ ANGLE_INLINE bool empty() const
+ {
+ for (const KeyBitSet &it : mKeyData)
+ {
+ if (it.any())
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ ANGLE_INLINE size_t size() const
+ {
+ size_t valid_entries = 0;
+ for (const KeyBitSet &it : mKeyData)
+ {
+ valid_entries += it.count();
+ }
+ return valid_entries;
+ }
+
+ private:
+ ANGLE_INLINE size_t capacity() const { return kWindowSize * mKeyData.size(); }
+
+ ANGLE_INLINE void reserve(size_t newSize)
+ {
+ size_t alignedSize = rx::roundUpPow2(newSize, kWindowSize);
+ size_t count = alignedSize >> kShiftForDivision;
+
+ mKeyData.resize(count, KeyBitSet::Zero());
+ }
+
+ std::vector<KeyBitSet> mKeyData;
+};
+
+// This is needed to accommodate the chromium style guide error -
+// [chromium-style] Complex constructor has an inlined body.
+ANGLE_INLINE FastIntegerSet::FastIntegerSet() {}
+ANGLE_INLINE FastIntegerSet::~FastIntegerSet() {}
+
+template <typename Value>
+class FastIntegerMap final
+{
+ public:
+ FastIntegerMap() {}
+ ~FastIntegerMap() {}
+
+ ANGLE_INLINE void ensureCapacity(size_t size)
+ {
+ // Ensure key set has capacity
+ mKeySet.ensureCapacity(size);
+
+ // Ensure value vector has capacity
+ ensureCapacityImpl(size);
+ }
+
+ ANGLE_INLINE void insert(uint64_t key, Value value)
+ {
+ // Insert key
+ ASSERT(!mKeySet.contains(key));
+ mKeySet.insert(key);
+
+ // Insert value
+ size_t sizedKey = static_cast<size_t>(key);
+ ensureCapacityImpl(sizedKey);
+ ASSERT(capacity() > sizedKey);
+ mValueData[sizedKey] = value;
+ }
+
+ ANGLE_INLINE bool contains(uint64_t key) const { return mKeySet.contains(key); }
+
+ ANGLE_INLINE bool get(uint64_t key, Value *out) const
+ {
+ if (!mKeySet.contains(key))
+ {
+ return false;
+ }
+
+ size_t sizedKey = static_cast<size_t>(key);
+ *out = mValueData[sizedKey];
+ return true;
+ }
+
+ ANGLE_INLINE void clear() { mKeySet.clear(); }
+
+ ANGLE_INLINE bool empty() const { return mKeySet.empty(); }
+
+ ANGLE_INLINE size_t size() const { return mKeySet.size(); }
+
+ private:
+ ANGLE_INLINE size_t capacity() const { return mValueData.size(); }
+
+ ANGLE_INLINE void ensureCapacityImpl(size_t size)
+ {
+ if (capacity() <= size)
+ {
+ reserve(size * 2);
+ }
+ }
+
+ ANGLE_INLINE void reserve(size_t newSize)
+ {
+ size_t alignedSize = rx::roundUpPow2(newSize, FastIntegerSet::kWindowSize);
+ mValueData.resize(alignedSize);
+ }
+
+ FastIntegerSet mKeySet;
+ std::vector<Value> mValueData;
+};
+} // namespace angle
+
+#endif // COMMON_FASTVECTOR_H_
diff --git a/gfx/angle/checkout/src/common/FixedVector.h b/gfx/angle/checkout/src/common/FixedVector.h
new file mode 100644
index 0000000000..bff87fc969
--- /dev/null
+++ b/gfx/angle/checkout/src/common/FixedVector.h
@@ -0,0 +1,353 @@
+//
+// Copyright 2018 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.
+//
+// FixedVector.h:
+// A vector class with a maximum size and fixed storage.
+//
+
+#ifndef COMMON_FIXEDVECTOR_H_
+#define COMMON_FIXEDVECTOR_H_
+
+#include "common/debug.h"
+
+#include <algorithm>
+#include <array>
+#include <initializer_list>
+
+namespace angle
+{
+template <class T, size_t N, class Storage = std::array<T, N>>
+class FixedVector final
+{
+ public:
+ using value_type = typename Storage::value_type;
+ using size_type = typename Storage::size_type;
+ using reference = typename Storage::reference;
+ using const_reference = typename Storage::const_reference;
+ using pointer = typename Storage::pointer;
+ using const_pointer = typename Storage::const_pointer;
+ using iterator = typename Storage::iterator;
+ using const_iterator = typename Storage::const_iterator;
+ using reverse_iterator = typename Storage::reverse_iterator;
+ using const_reverse_iterator = typename Storage::const_reverse_iterator;
+
+ FixedVector();
+ FixedVector(size_type count, const value_type &value);
+ FixedVector(size_type count);
+
+ FixedVector(const FixedVector<T, N, Storage> &other);
+ FixedVector(FixedVector<T, N, Storage> &&other);
+ FixedVector(std::initializer_list<value_type> init);
+
+ FixedVector<T, N, Storage> &operator=(const FixedVector<T, N, Storage> &other);
+ FixedVector<T, N, Storage> &operator=(FixedVector<T, N, Storage> &&other);
+ FixedVector<T, N, Storage> &operator=(std::initializer_list<value_type> init);
+
+ ~FixedVector();
+
+ reference at(size_type pos);
+ const_reference at(size_type pos) const;
+
+ reference operator[](size_type pos);
+ const_reference operator[](size_type pos) const;
+
+ pointer data();
+ const_pointer data() const;
+
+ iterator begin();
+ const_iterator begin() const;
+
+ iterator end();
+ const_iterator end() const;
+
+ bool empty() const;
+ size_type size() const;
+ static constexpr size_type max_size();
+
+ void clear();
+
+ void push_back(const value_type &value);
+ void push_back(value_type &&value);
+
+ template <class... Args>
+ void emplace_back(Args &&... args);
+
+ void pop_back();
+ reference back();
+ const_reference back() const;
+
+ void swap(FixedVector<T, N, Storage> &other);
+
+ void resize(size_type count);
+ void resize(size_type count, const value_type &value);
+
+ bool full() const;
+
+ private:
+ void assign_from_initializer_list(std::initializer_list<value_type> init);
+
+ Storage mStorage;
+ size_type mSize = 0;
+};
+
+template <class T, size_t N, class Storage>
+bool operator==(const FixedVector<T, N, Storage> &a, const FixedVector<T, N, Storage> &b)
+{
+ return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin());
+}
+
+template <class T, size_t N, class Storage>
+bool operator!=(const FixedVector<T, N, Storage> &a, const FixedVector<T, N, Storage> &b)
+{
+ return !(a == b);
+}
+
+template <class T, size_t N, class Storage>
+FixedVector<T, N, Storage>::FixedVector() = default;
+
+template <class T, size_t N, class Storage>
+FixedVector<T, N, Storage>::FixedVector(size_type count, const value_type &value) : mSize(count)
+{
+ ASSERT(count <= N);
+ std::fill(mStorage.begin(), mStorage.begin() + count, value);
+}
+
+template <class T, size_t N, class Storage>
+FixedVector<T, N, Storage>::FixedVector(size_type count) : mSize(count)
+{
+ ASSERT(count <= N);
+}
+
+template <class T, size_t N, class Storage>
+FixedVector<T, N, Storage>::FixedVector(const FixedVector<T, N, Storage> &other) = default;
+
+template <class T, size_t N, class Storage>
+FixedVector<T, N, Storage>::FixedVector(FixedVector<T, N, Storage> &&other) = default;
+
+template <class T, size_t N, class Storage>
+FixedVector<T, N, Storage>::FixedVector(std::initializer_list<value_type> init)
+{
+ ASSERT(init.size() <= N);
+ assign_from_initializer_list(init);
+}
+
+template <class T, size_t N, class Storage>
+FixedVector<T, N, Storage> &FixedVector<T, N, Storage>::operator=(
+ const FixedVector<T, N, Storage> &other) = default;
+
+template <class T, size_t N, class Storage>
+FixedVector<T, N, Storage> &FixedVector<T, N, Storage>::operator=(
+ FixedVector<T, N, Storage> &&other) = default;
+
+template <class T, size_t N, class Storage>
+FixedVector<T, N, Storage> &FixedVector<T, N, Storage>::operator=(
+ std::initializer_list<value_type> init)
+{
+ clear();
+ ASSERT(init.size() <= N);
+ assign_from_initializer_list(init);
+ return this;
+}
+
+template <class T, size_t N, class Storage>
+FixedVector<T, N, Storage>::~FixedVector()
+{
+ clear();
+}
+
+template <class T, size_t N, class Storage>
+typename FixedVector<T, N, Storage>::reference FixedVector<T, N, Storage>::at(size_type pos)
+{
+ ASSERT(pos < N);
+ return mStorage.at(pos);
+}
+
+template <class T, size_t N, class Storage>
+typename FixedVector<T, N, Storage>::const_reference FixedVector<T, N, Storage>::at(
+ size_type pos) const
+{
+ ASSERT(pos < N);
+ return mStorage.at(pos);
+}
+
+template <class T, size_t N, class Storage>
+typename FixedVector<T, N, Storage>::reference FixedVector<T, N, Storage>::operator[](size_type pos)
+{
+ ASSERT(pos < N);
+ return mStorage[pos];
+}
+
+template <class T, size_t N, class Storage>
+typename FixedVector<T, N, Storage>::const_reference FixedVector<T, N, Storage>::operator[](
+ size_type pos) const
+{
+ ASSERT(pos < N);
+ return mStorage[pos];
+}
+
+template <class T, size_t N, class Storage>
+typename FixedVector<T, N, Storage>::const_pointer angle::FixedVector<T, N, Storage>::data() const
+{
+ return mStorage.data();
+}
+
+template <class T, size_t N, class Storage>
+typename FixedVector<T, N, Storage>::pointer angle::FixedVector<T, N, Storage>::data()
+{
+ return mStorage.data();
+}
+
+template <class T, size_t N, class Storage>
+typename FixedVector<T, N, Storage>::iterator FixedVector<T, N, Storage>::begin()
+{
+ return mStorage.begin();
+}
+
+template <class T, size_t N, class Storage>
+typename FixedVector<T, N, Storage>::const_iterator FixedVector<T, N, Storage>::begin() const
+{
+ return mStorage.begin();
+}
+
+template <class T, size_t N, class Storage>
+typename FixedVector<T, N, Storage>::iterator FixedVector<T, N, Storage>::end()
+{
+ return mStorage.begin() + mSize;
+}
+
+template <class T, size_t N, class Storage>
+typename FixedVector<T, N, Storage>::const_iterator FixedVector<T, N, Storage>::end() const
+{
+ return mStorage.begin() + mSize;
+}
+
+template <class T, size_t N, class Storage>
+bool FixedVector<T, N, Storage>::empty() const
+{
+ return mSize == 0;
+}
+
+template <class T, size_t N, class Storage>
+typename FixedVector<T, N, Storage>::size_type FixedVector<T, N, Storage>::size() const
+{
+ return mSize;
+}
+
+template <class T, size_t N, class Storage>
+constexpr typename FixedVector<T, N, Storage>::size_type FixedVector<T, N, Storage>::max_size()
+{
+ return N;
+}
+
+template <class T, size_t N, class Storage>
+void FixedVector<T, N, Storage>::clear()
+{
+ resize(0);
+}
+
+template <class T, size_t N, class Storage>
+void FixedVector<T, N, Storage>::push_back(const value_type &value)
+{
+ ASSERT(mSize < N);
+ mStorage[mSize] = value;
+ mSize++;
+}
+
+template <class T, size_t N, class Storage>
+void FixedVector<T, N, Storage>::push_back(value_type &&value)
+{
+ ASSERT(mSize < N);
+ mStorage[mSize] = std::move(value);
+ mSize++;
+}
+
+template <class T, size_t N, class Storage>
+template <class... Args>
+void FixedVector<T, N, Storage>::emplace_back(Args &&... args)
+{
+ ASSERT(mSize < N);
+ new (&mStorage[mSize]) T{std::forward<Args>(args)...};
+ mSize++;
+}
+
+template <class T, size_t N, class Storage>
+void FixedVector<T, N, Storage>::pop_back()
+{
+ ASSERT(mSize > 0);
+ mSize--;
+}
+
+template <class T, size_t N, class Storage>
+typename FixedVector<T, N, Storage>::reference FixedVector<T, N, Storage>::back()
+{
+ ASSERT(mSize > 0);
+ return mStorage[mSize - 1];
+}
+
+template <class T, size_t N, class Storage>
+typename FixedVector<T, N, Storage>::const_reference FixedVector<T, N, Storage>::back() const
+{
+ ASSERT(mSize > 0);
+ return mStorage[mSize - 1];
+}
+
+template <class T, size_t N, class Storage>
+void FixedVector<T, N, Storage>::swap(FixedVector<T, N, Storage> &other)
+{
+ std::swap(mSize, other.mSize);
+ std::swap(mStorage, other.mStorage);
+}
+
+template <class T, size_t N, class Storage>
+void FixedVector<T, N, Storage>::resize(size_type count)
+{
+ ASSERT(count <= N);
+ while (mSize > count)
+ {
+ mSize--;
+ mStorage[mSize] = value_type();
+ }
+ while (mSize < count)
+ {
+ mStorage[mSize] = value_type();
+ mSize++;
+ }
+}
+
+template <class T, size_t N, class Storage>
+void FixedVector<T, N, Storage>::resize(size_type count, const value_type &value)
+{
+ ASSERT(count <= N);
+ while (mSize > count)
+ {
+ mSize--;
+ mStorage[mSize] = value_type();
+ }
+ while (mSize < count)
+ {
+ mStorage[mSize] = value;
+ mSize++;
+ }
+}
+
+template <class T, size_t N, class Storage>
+void FixedVector<T, N, Storage>::assign_from_initializer_list(
+ std::initializer_list<value_type> init)
+{
+ for (auto element : init)
+ {
+ mStorage[mSize] = std::move(element);
+ mSize++;
+ }
+}
+
+template <class T, size_t N, class Storage>
+bool FixedVector<T, N, Storage>::full() const
+{
+ return (mSize == N);
+}
+} // namespace angle
+
+#endif // COMMON_FIXEDVECTOR_H_
diff --git a/gfx/angle/checkout/src/common/Float16ToFloat32.cpp b/gfx/angle/checkout/src/common/Float16ToFloat32.cpp
new file mode 100644
index 0000000000..f9dfe23307
--- /dev/null
+++ b/gfx/angle/checkout/src/common/Float16ToFloat32.cpp
@@ -0,0 +1,300 @@
+//
+// Copyright 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.
+//
+
+// This file is automatically generated.
+
+#include "common/mathutil.h"
+
+namespace gl
+{
+
+const static unsigned g_mantissa[2048] = {
+ 0x00000000, 0x33800000, 0x34000000, 0x34400000, 0x34800000, 0x34a00000, 0x34c00000, 0x34e00000,
+ 0x35000000, 0x35100000, 0x35200000, 0x35300000, 0x35400000, 0x35500000, 0x35600000, 0x35700000,
+ 0x35800000, 0x35880000, 0x35900000, 0x35980000, 0x35a00000, 0x35a80000, 0x35b00000, 0x35b80000,
+ 0x35c00000, 0x35c80000, 0x35d00000, 0x35d80000, 0x35e00000, 0x35e80000, 0x35f00000, 0x35f80000,
+ 0x36000000, 0x36040000, 0x36080000, 0x360c0000, 0x36100000, 0x36140000, 0x36180000, 0x361c0000,
+ 0x36200000, 0x36240000, 0x36280000, 0x362c0000, 0x36300000, 0x36340000, 0x36380000, 0x363c0000,
+ 0x36400000, 0x36440000, 0x36480000, 0x364c0000, 0x36500000, 0x36540000, 0x36580000, 0x365c0000,
+ 0x36600000, 0x36640000, 0x36680000, 0x366c0000, 0x36700000, 0x36740000, 0x36780000, 0x367c0000,
+ 0x36800000, 0x36820000, 0x36840000, 0x36860000, 0x36880000, 0x368a0000, 0x368c0000, 0x368e0000,
+ 0x36900000, 0x36920000, 0x36940000, 0x36960000, 0x36980000, 0x369a0000, 0x369c0000, 0x369e0000,
+ 0x36a00000, 0x36a20000, 0x36a40000, 0x36a60000, 0x36a80000, 0x36aa0000, 0x36ac0000, 0x36ae0000,
+ 0x36b00000, 0x36b20000, 0x36b40000, 0x36b60000, 0x36b80000, 0x36ba0000, 0x36bc0000, 0x36be0000,
+ 0x36c00000, 0x36c20000, 0x36c40000, 0x36c60000, 0x36c80000, 0x36ca0000, 0x36cc0000, 0x36ce0000,
+ 0x36d00000, 0x36d20000, 0x36d40000, 0x36d60000, 0x36d80000, 0x36da0000, 0x36dc0000, 0x36de0000,
+ 0x36e00000, 0x36e20000, 0x36e40000, 0x36e60000, 0x36e80000, 0x36ea0000, 0x36ec0000, 0x36ee0000,
+ 0x36f00000, 0x36f20000, 0x36f40000, 0x36f60000, 0x36f80000, 0x36fa0000, 0x36fc0000, 0x36fe0000,
+ 0x37000000, 0x37010000, 0x37020000, 0x37030000, 0x37040000, 0x37050000, 0x37060000, 0x37070000,
+ 0x37080000, 0x37090000, 0x370a0000, 0x370b0000, 0x370c0000, 0x370d0000, 0x370e0000, 0x370f0000,
+ 0x37100000, 0x37110000, 0x37120000, 0x37130000, 0x37140000, 0x37150000, 0x37160000, 0x37170000,
+ 0x37180000, 0x37190000, 0x371a0000, 0x371b0000, 0x371c0000, 0x371d0000, 0x371e0000, 0x371f0000,
+ 0x37200000, 0x37210000, 0x37220000, 0x37230000, 0x37240000, 0x37250000, 0x37260000, 0x37270000,
+ 0x37280000, 0x37290000, 0x372a0000, 0x372b0000, 0x372c0000, 0x372d0000, 0x372e0000, 0x372f0000,
+ 0x37300000, 0x37310000, 0x37320000, 0x37330000, 0x37340000, 0x37350000, 0x37360000, 0x37370000,
+ 0x37380000, 0x37390000, 0x373a0000, 0x373b0000, 0x373c0000, 0x373d0000, 0x373e0000, 0x373f0000,
+ 0x37400000, 0x37410000, 0x37420000, 0x37430000, 0x37440000, 0x37450000, 0x37460000, 0x37470000,
+ 0x37480000, 0x37490000, 0x374a0000, 0x374b0000, 0x374c0000, 0x374d0000, 0x374e0000, 0x374f0000,
+ 0x37500000, 0x37510000, 0x37520000, 0x37530000, 0x37540000, 0x37550000, 0x37560000, 0x37570000,
+ 0x37580000, 0x37590000, 0x375a0000, 0x375b0000, 0x375c0000, 0x375d0000, 0x375e0000, 0x375f0000,
+ 0x37600000, 0x37610000, 0x37620000, 0x37630000, 0x37640000, 0x37650000, 0x37660000, 0x37670000,
+ 0x37680000, 0x37690000, 0x376a0000, 0x376b0000, 0x376c0000, 0x376d0000, 0x376e0000, 0x376f0000,
+ 0x37700000, 0x37710000, 0x37720000, 0x37730000, 0x37740000, 0x37750000, 0x37760000, 0x37770000,
+ 0x37780000, 0x37790000, 0x377a0000, 0x377b0000, 0x377c0000, 0x377d0000, 0x377e0000, 0x377f0000,
+ 0x37800000, 0x37808000, 0x37810000, 0x37818000, 0x37820000, 0x37828000, 0x37830000, 0x37838000,
+ 0x37840000, 0x37848000, 0x37850000, 0x37858000, 0x37860000, 0x37868000, 0x37870000, 0x37878000,
+ 0x37880000, 0x37888000, 0x37890000, 0x37898000, 0x378a0000, 0x378a8000, 0x378b0000, 0x378b8000,
+ 0x378c0000, 0x378c8000, 0x378d0000, 0x378d8000, 0x378e0000, 0x378e8000, 0x378f0000, 0x378f8000,
+ 0x37900000, 0x37908000, 0x37910000, 0x37918000, 0x37920000, 0x37928000, 0x37930000, 0x37938000,
+ 0x37940000, 0x37948000, 0x37950000, 0x37958000, 0x37960000, 0x37968000, 0x37970000, 0x37978000,
+ 0x37980000, 0x37988000, 0x37990000, 0x37998000, 0x379a0000, 0x379a8000, 0x379b0000, 0x379b8000,
+ 0x379c0000, 0x379c8000, 0x379d0000, 0x379d8000, 0x379e0000, 0x379e8000, 0x379f0000, 0x379f8000,
+ 0x37a00000, 0x37a08000, 0x37a10000, 0x37a18000, 0x37a20000, 0x37a28000, 0x37a30000, 0x37a38000,
+ 0x37a40000, 0x37a48000, 0x37a50000, 0x37a58000, 0x37a60000, 0x37a68000, 0x37a70000, 0x37a78000,
+ 0x37a80000, 0x37a88000, 0x37a90000, 0x37a98000, 0x37aa0000, 0x37aa8000, 0x37ab0000, 0x37ab8000,
+ 0x37ac0000, 0x37ac8000, 0x37ad0000, 0x37ad8000, 0x37ae0000, 0x37ae8000, 0x37af0000, 0x37af8000,
+ 0x37b00000, 0x37b08000, 0x37b10000, 0x37b18000, 0x37b20000, 0x37b28000, 0x37b30000, 0x37b38000,
+ 0x37b40000, 0x37b48000, 0x37b50000, 0x37b58000, 0x37b60000, 0x37b68000, 0x37b70000, 0x37b78000,
+ 0x37b80000, 0x37b88000, 0x37b90000, 0x37b98000, 0x37ba0000, 0x37ba8000, 0x37bb0000, 0x37bb8000,
+ 0x37bc0000, 0x37bc8000, 0x37bd0000, 0x37bd8000, 0x37be0000, 0x37be8000, 0x37bf0000, 0x37bf8000,
+ 0x37c00000, 0x37c08000, 0x37c10000, 0x37c18000, 0x37c20000, 0x37c28000, 0x37c30000, 0x37c38000,
+ 0x37c40000, 0x37c48000, 0x37c50000, 0x37c58000, 0x37c60000, 0x37c68000, 0x37c70000, 0x37c78000,
+ 0x37c80000, 0x37c88000, 0x37c90000, 0x37c98000, 0x37ca0000, 0x37ca8000, 0x37cb0000, 0x37cb8000,
+ 0x37cc0000, 0x37cc8000, 0x37cd0000, 0x37cd8000, 0x37ce0000, 0x37ce8000, 0x37cf0000, 0x37cf8000,
+ 0x37d00000, 0x37d08000, 0x37d10000, 0x37d18000, 0x37d20000, 0x37d28000, 0x37d30000, 0x37d38000,
+ 0x37d40000, 0x37d48000, 0x37d50000, 0x37d58000, 0x37d60000, 0x37d68000, 0x37d70000, 0x37d78000,
+ 0x37d80000, 0x37d88000, 0x37d90000, 0x37d98000, 0x37da0000, 0x37da8000, 0x37db0000, 0x37db8000,
+ 0x37dc0000, 0x37dc8000, 0x37dd0000, 0x37dd8000, 0x37de0000, 0x37de8000, 0x37df0000, 0x37df8000,
+ 0x37e00000, 0x37e08000, 0x37e10000, 0x37e18000, 0x37e20000, 0x37e28000, 0x37e30000, 0x37e38000,
+ 0x37e40000, 0x37e48000, 0x37e50000, 0x37e58000, 0x37e60000, 0x37e68000, 0x37e70000, 0x37e78000,
+ 0x37e80000, 0x37e88000, 0x37e90000, 0x37e98000, 0x37ea0000, 0x37ea8000, 0x37eb0000, 0x37eb8000,
+ 0x37ec0000, 0x37ec8000, 0x37ed0000, 0x37ed8000, 0x37ee0000, 0x37ee8000, 0x37ef0000, 0x37ef8000,
+ 0x37f00000, 0x37f08000, 0x37f10000, 0x37f18000, 0x37f20000, 0x37f28000, 0x37f30000, 0x37f38000,
+ 0x37f40000, 0x37f48000, 0x37f50000, 0x37f58000, 0x37f60000, 0x37f68000, 0x37f70000, 0x37f78000,
+ 0x37f80000, 0x37f88000, 0x37f90000, 0x37f98000, 0x37fa0000, 0x37fa8000, 0x37fb0000, 0x37fb8000,
+ 0x37fc0000, 0x37fc8000, 0x37fd0000, 0x37fd8000, 0x37fe0000, 0x37fe8000, 0x37ff0000, 0x37ff8000,
+ 0x38000000, 0x38004000, 0x38008000, 0x3800c000, 0x38010000, 0x38014000, 0x38018000, 0x3801c000,
+ 0x38020000, 0x38024000, 0x38028000, 0x3802c000, 0x38030000, 0x38034000, 0x38038000, 0x3803c000,
+ 0x38040000, 0x38044000, 0x38048000, 0x3804c000, 0x38050000, 0x38054000, 0x38058000, 0x3805c000,
+ 0x38060000, 0x38064000, 0x38068000, 0x3806c000, 0x38070000, 0x38074000, 0x38078000, 0x3807c000,
+ 0x38080000, 0x38084000, 0x38088000, 0x3808c000, 0x38090000, 0x38094000, 0x38098000, 0x3809c000,
+ 0x380a0000, 0x380a4000, 0x380a8000, 0x380ac000, 0x380b0000, 0x380b4000, 0x380b8000, 0x380bc000,
+ 0x380c0000, 0x380c4000, 0x380c8000, 0x380cc000, 0x380d0000, 0x380d4000, 0x380d8000, 0x380dc000,
+ 0x380e0000, 0x380e4000, 0x380e8000, 0x380ec000, 0x380f0000, 0x380f4000, 0x380f8000, 0x380fc000,
+ 0x38100000, 0x38104000, 0x38108000, 0x3810c000, 0x38110000, 0x38114000, 0x38118000, 0x3811c000,
+ 0x38120000, 0x38124000, 0x38128000, 0x3812c000, 0x38130000, 0x38134000, 0x38138000, 0x3813c000,
+ 0x38140000, 0x38144000, 0x38148000, 0x3814c000, 0x38150000, 0x38154000, 0x38158000, 0x3815c000,
+ 0x38160000, 0x38164000, 0x38168000, 0x3816c000, 0x38170000, 0x38174000, 0x38178000, 0x3817c000,
+ 0x38180000, 0x38184000, 0x38188000, 0x3818c000, 0x38190000, 0x38194000, 0x38198000, 0x3819c000,
+ 0x381a0000, 0x381a4000, 0x381a8000, 0x381ac000, 0x381b0000, 0x381b4000, 0x381b8000, 0x381bc000,
+ 0x381c0000, 0x381c4000, 0x381c8000, 0x381cc000, 0x381d0000, 0x381d4000, 0x381d8000, 0x381dc000,
+ 0x381e0000, 0x381e4000, 0x381e8000, 0x381ec000, 0x381f0000, 0x381f4000, 0x381f8000, 0x381fc000,
+ 0x38200000, 0x38204000, 0x38208000, 0x3820c000, 0x38210000, 0x38214000, 0x38218000, 0x3821c000,
+ 0x38220000, 0x38224000, 0x38228000, 0x3822c000, 0x38230000, 0x38234000, 0x38238000, 0x3823c000,
+ 0x38240000, 0x38244000, 0x38248000, 0x3824c000, 0x38250000, 0x38254000, 0x38258000, 0x3825c000,
+ 0x38260000, 0x38264000, 0x38268000, 0x3826c000, 0x38270000, 0x38274000, 0x38278000, 0x3827c000,
+ 0x38280000, 0x38284000, 0x38288000, 0x3828c000, 0x38290000, 0x38294000, 0x38298000, 0x3829c000,
+ 0x382a0000, 0x382a4000, 0x382a8000, 0x382ac000, 0x382b0000, 0x382b4000, 0x382b8000, 0x382bc000,
+ 0x382c0000, 0x382c4000, 0x382c8000, 0x382cc000, 0x382d0000, 0x382d4000, 0x382d8000, 0x382dc000,
+ 0x382e0000, 0x382e4000, 0x382e8000, 0x382ec000, 0x382f0000, 0x382f4000, 0x382f8000, 0x382fc000,
+ 0x38300000, 0x38304000, 0x38308000, 0x3830c000, 0x38310000, 0x38314000, 0x38318000, 0x3831c000,
+ 0x38320000, 0x38324000, 0x38328000, 0x3832c000, 0x38330000, 0x38334000, 0x38338000, 0x3833c000,
+ 0x38340000, 0x38344000, 0x38348000, 0x3834c000, 0x38350000, 0x38354000, 0x38358000, 0x3835c000,
+ 0x38360000, 0x38364000, 0x38368000, 0x3836c000, 0x38370000, 0x38374000, 0x38378000, 0x3837c000,
+ 0x38380000, 0x38384000, 0x38388000, 0x3838c000, 0x38390000, 0x38394000, 0x38398000, 0x3839c000,
+ 0x383a0000, 0x383a4000, 0x383a8000, 0x383ac000, 0x383b0000, 0x383b4000, 0x383b8000, 0x383bc000,
+ 0x383c0000, 0x383c4000, 0x383c8000, 0x383cc000, 0x383d0000, 0x383d4000, 0x383d8000, 0x383dc000,
+ 0x383e0000, 0x383e4000, 0x383e8000, 0x383ec000, 0x383f0000, 0x383f4000, 0x383f8000, 0x383fc000,
+ 0x38400000, 0x38404000, 0x38408000, 0x3840c000, 0x38410000, 0x38414000, 0x38418000, 0x3841c000,
+ 0x38420000, 0x38424000, 0x38428000, 0x3842c000, 0x38430000, 0x38434000, 0x38438000, 0x3843c000,
+ 0x38440000, 0x38444000, 0x38448000, 0x3844c000, 0x38450000, 0x38454000, 0x38458000, 0x3845c000,
+ 0x38460000, 0x38464000, 0x38468000, 0x3846c000, 0x38470000, 0x38474000, 0x38478000, 0x3847c000,
+ 0x38480000, 0x38484000, 0x38488000, 0x3848c000, 0x38490000, 0x38494000, 0x38498000, 0x3849c000,
+ 0x384a0000, 0x384a4000, 0x384a8000, 0x384ac000, 0x384b0000, 0x384b4000, 0x384b8000, 0x384bc000,
+ 0x384c0000, 0x384c4000, 0x384c8000, 0x384cc000, 0x384d0000, 0x384d4000, 0x384d8000, 0x384dc000,
+ 0x384e0000, 0x384e4000, 0x384e8000, 0x384ec000, 0x384f0000, 0x384f4000, 0x384f8000, 0x384fc000,
+ 0x38500000, 0x38504000, 0x38508000, 0x3850c000, 0x38510000, 0x38514000, 0x38518000, 0x3851c000,
+ 0x38520000, 0x38524000, 0x38528000, 0x3852c000, 0x38530000, 0x38534000, 0x38538000, 0x3853c000,
+ 0x38540000, 0x38544000, 0x38548000, 0x3854c000, 0x38550000, 0x38554000, 0x38558000, 0x3855c000,
+ 0x38560000, 0x38564000, 0x38568000, 0x3856c000, 0x38570000, 0x38574000, 0x38578000, 0x3857c000,
+ 0x38580000, 0x38584000, 0x38588000, 0x3858c000, 0x38590000, 0x38594000, 0x38598000, 0x3859c000,
+ 0x385a0000, 0x385a4000, 0x385a8000, 0x385ac000, 0x385b0000, 0x385b4000, 0x385b8000, 0x385bc000,
+ 0x385c0000, 0x385c4000, 0x385c8000, 0x385cc000, 0x385d0000, 0x385d4000, 0x385d8000, 0x385dc000,
+ 0x385e0000, 0x385e4000, 0x385e8000, 0x385ec000, 0x385f0000, 0x385f4000, 0x385f8000, 0x385fc000,
+ 0x38600000, 0x38604000, 0x38608000, 0x3860c000, 0x38610000, 0x38614000, 0x38618000, 0x3861c000,
+ 0x38620000, 0x38624000, 0x38628000, 0x3862c000, 0x38630000, 0x38634000, 0x38638000, 0x3863c000,
+ 0x38640000, 0x38644000, 0x38648000, 0x3864c000, 0x38650000, 0x38654000, 0x38658000, 0x3865c000,
+ 0x38660000, 0x38664000, 0x38668000, 0x3866c000, 0x38670000, 0x38674000, 0x38678000, 0x3867c000,
+ 0x38680000, 0x38684000, 0x38688000, 0x3868c000, 0x38690000, 0x38694000, 0x38698000, 0x3869c000,
+ 0x386a0000, 0x386a4000, 0x386a8000, 0x386ac000, 0x386b0000, 0x386b4000, 0x386b8000, 0x386bc000,
+ 0x386c0000, 0x386c4000, 0x386c8000, 0x386cc000, 0x386d0000, 0x386d4000, 0x386d8000, 0x386dc000,
+ 0x386e0000, 0x386e4000, 0x386e8000, 0x386ec000, 0x386f0000, 0x386f4000, 0x386f8000, 0x386fc000,
+ 0x38700000, 0x38704000, 0x38708000, 0x3870c000, 0x38710000, 0x38714000, 0x38718000, 0x3871c000,
+ 0x38720000, 0x38724000, 0x38728000, 0x3872c000, 0x38730000, 0x38734000, 0x38738000, 0x3873c000,
+ 0x38740000, 0x38744000, 0x38748000, 0x3874c000, 0x38750000, 0x38754000, 0x38758000, 0x3875c000,
+ 0x38760000, 0x38764000, 0x38768000, 0x3876c000, 0x38770000, 0x38774000, 0x38778000, 0x3877c000,
+ 0x38780000, 0x38784000, 0x38788000, 0x3878c000, 0x38790000, 0x38794000, 0x38798000, 0x3879c000,
+ 0x387a0000, 0x387a4000, 0x387a8000, 0x387ac000, 0x387b0000, 0x387b4000, 0x387b8000, 0x387bc000,
+ 0x387c0000, 0x387c4000, 0x387c8000, 0x387cc000, 0x387d0000, 0x387d4000, 0x387d8000, 0x387dc000,
+ 0x387e0000, 0x387e4000, 0x387e8000, 0x387ec000, 0x387f0000, 0x387f4000, 0x387f8000, 0x387fc000,
+ 0x38000000, 0x38002000, 0x38004000, 0x38006000, 0x38008000, 0x3800a000, 0x3800c000, 0x3800e000,
+ 0x38010000, 0x38012000, 0x38014000, 0x38016000, 0x38018000, 0x3801a000, 0x3801c000, 0x3801e000,
+ 0x38020000, 0x38022000, 0x38024000, 0x38026000, 0x38028000, 0x3802a000, 0x3802c000, 0x3802e000,
+ 0x38030000, 0x38032000, 0x38034000, 0x38036000, 0x38038000, 0x3803a000, 0x3803c000, 0x3803e000,
+ 0x38040000, 0x38042000, 0x38044000, 0x38046000, 0x38048000, 0x3804a000, 0x3804c000, 0x3804e000,
+ 0x38050000, 0x38052000, 0x38054000, 0x38056000, 0x38058000, 0x3805a000, 0x3805c000, 0x3805e000,
+ 0x38060000, 0x38062000, 0x38064000, 0x38066000, 0x38068000, 0x3806a000, 0x3806c000, 0x3806e000,
+ 0x38070000, 0x38072000, 0x38074000, 0x38076000, 0x38078000, 0x3807a000, 0x3807c000, 0x3807e000,
+ 0x38080000, 0x38082000, 0x38084000, 0x38086000, 0x38088000, 0x3808a000, 0x3808c000, 0x3808e000,
+ 0x38090000, 0x38092000, 0x38094000, 0x38096000, 0x38098000, 0x3809a000, 0x3809c000, 0x3809e000,
+ 0x380a0000, 0x380a2000, 0x380a4000, 0x380a6000, 0x380a8000, 0x380aa000, 0x380ac000, 0x380ae000,
+ 0x380b0000, 0x380b2000, 0x380b4000, 0x380b6000, 0x380b8000, 0x380ba000, 0x380bc000, 0x380be000,
+ 0x380c0000, 0x380c2000, 0x380c4000, 0x380c6000, 0x380c8000, 0x380ca000, 0x380cc000, 0x380ce000,
+ 0x380d0000, 0x380d2000, 0x380d4000, 0x380d6000, 0x380d8000, 0x380da000, 0x380dc000, 0x380de000,
+ 0x380e0000, 0x380e2000, 0x380e4000, 0x380e6000, 0x380e8000, 0x380ea000, 0x380ec000, 0x380ee000,
+ 0x380f0000, 0x380f2000, 0x380f4000, 0x380f6000, 0x380f8000, 0x380fa000, 0x380fc000, 0x380fe000,
+ 0x38100000, 0x38102000, 0x38104000, 0x38106000, 0x38108000, 0x3810a000, 0x3810c000, 0x3810e000,
+ 0x38110000, 0x38112000, 0x38114000, 0x38116000, 0x38118000, 0x3811a000, 0x3811c000, 0x3811e000,
+ 0x38120000, 0x38122000, 0x38124000, 0x38126000, 0x38128000, 0x3812a000, 0x3812c000, 0x3812e000,
+ 0x38130000, 0x38132000, 0x38134000, 0x38136000, 0x38138000, 0x3813a000, 0x3813c000, 0x3813e000,
+ 0x38140000, 0x38142000, 0x38144000, 0x38146000, 0x38148000, 0x3814a000, 0x3814c000, 0x3814e000,
+ 0x38150000, 0x38152000, 0x38154000, 0x38156000, 0x38158000, 0x3815a000, 0x3815c000, 0x3815e000,
+ 0x38160000, 0x38162000, 0x38164000, 0x38166000, 0x38168000, 0x3816a000, 0x3816c000, 0x3816e000,
+ 0x38170000, 0x38172000, 0x38174000, 0x38176000, 0x38178000, 0x3817a000, 0x3817c000, 0x3817e000,
+ 0x38180000, 0x38182000, 0x38184000, 0x38186000, 0x38188000, 0x3818a000, 0x3818c000, 0x3818e000,
+ 0x38190000, 0x38192000, 0x38194000, 0x38196000, 0x38198000, 0x3819a000, 0x3819c000, 0x3819e000,
+ 0x381a0000, 0x381a2000, 0x381a4000, 0x381a6000, 0x381a8000, 0x381aa000, 0x381ac000, 0x381ae000,
+ 0x381b0000, 0x381b2000, 0x381b4000, 0x381b6000, 0x381b8000, 0x381ba000, 0x381bc000, 0x381be000,
+ 0x381c0000, 0x381c2000, 0x381c4000, 0x381c6000, 0x381c8000, 0x381ca000, 0x381cc000, 0x381ce000,
+ 0x381d0000, 0x381d2000, 0x381d4000, 0x381d6000, 0x381d8000, 0x381da000, 0x381dc000, 0x381de000,
+ 0x381e0000, 0x381e2000, 0x381e4000, 0x381e6000, 0x381e8000, 0x381ea000, 0x381ec000, 0x381ee000,
+ 0x381f0000, 0x381f2000, 0x381f4000, 0x381f6000, 0x381f8000, 0x381fa000, 0x381fc000, 0x381fe000,
+ 0x38200000, 0x38202000, 0x38204000, 0x38206000, 0x38208000, 0x3820a000, 0x3820c000, 0x3820e000,
+ 0x38210000, 0x38212000, 0x38214000, 0x38216000, 0x38218000, 0x3821a000, 0x3821c000, 0x3821e000,
+ 0x38220000, 0x38222000, 0x38224000, 0x38226000, 0x38228000, 0x3822a000, 0x3822c000, 0x3822e000,
+ 0x38230000, 0x38232000, 0x38234000, 0x38236000, 0x38238000, 0x3823a000, 0x3823c000, 0x3823e000,
+ 0x38240000, 0x38242000, 0x38244000, 0x38246000, 0x38248000, 0x3824a000, 0x3824c000, 0x3824e000,
+ 0x38250000, 0x38252000, 0x38254000, 0x38256000, 0x38258000, 0x3825a000, 0x3825c000, 0x3825e000,
+ 0x38260000, 0x38262000, 0x38264000, 0x38266000, 0x38268000, 0x3826a000, 0x3826c000, 0x3826e000,
+ 0x38270000, 0x38272000, 0x38274000, 0x38276000, 0x38278000, 0x3827a000, 0x3827c000, 0x3827e000,
+ 0x38280000, 0x38282000, 0x38284000, 0x38286000, 0x38288000, 0x3828a000, 0x3828c000, 0x3828e000,
+ 0x38290000, 0x38292000, 0x38294000, 0x38296000, 0x38298000, 0x3829a000, 0x3829c000, 0x3829e000,
+ 0x382a0000, 0x382a2000, 0x382a4000, 0x382a6000, 0x382a8000, 0x382aa000, 0x382ac000, 0x382ae000,
+ 0x382b0000, 0x382b2000, 0x382b4000, 0x382b6000, 0x382b8000, 0x382ba000, 0x382bc000, 0x382be000,
+ 0x382c0000, 0x382c2000, 0x382c4000, 0x382c6000, 0x382c8000, 0x382ca000, 0x382cc000, 0x382ce000,
+ 0x382d0000, 0x382d2000, 0x382d4000, 0x382d6000, 0x382d8000, 0x382da000, 0x382dc000, 0x382de000,
+ 0x382e0000, 0x382e2000, 0x382e4000, 0x382e6000, 0x382e8000, 0x382ea000, 0x382ec000, 0x382ee000,
+ 0x382f0000, 0x382f2000, 0x382f4000, 0x382f6000, 0x382f8000, 0x382fa000, 0x382fc000, 0x382fe000,
+ 0x38300000, 0x38302000, 0x38304000, 0x38306000, 0x38308000, 0x3830a000, 0x3830c000, 0x3830e000,
+ 0x38310000, 0x38312000, 0x38314000, 0x38316000, 0x38318000, 0x3831a000, 0x3831c000, 0x3831e000,
+ 0x38320000, 0x38322000, 0x38324000, 0x38326000, 0x38328000, 0x3832a000, 0x3832c000, 0x3832e000,
+ 0x38330000, 0x38332000, 0x38334000, 0x38336000, 0x38338000, 0x3833a000, 0x3833c000, 0x3833e000,
+ 0x38340000, 0x38342000, 0x38344000, 0x38346000, 0x38348000, 0x3834a000, 0x3834c000, 0x3834e000,
+ 0x38350000, 0x38352000, 0x38354000, 0x38356000, 0x38358000, 0x3835a000, 0x3835c000, 0x3835e000,
+ 0x38360000, 0x38362000, 0x38364000, 0x38366000, 0x38368000, 0x3836a000, 0x3836c000, 0x3836e000,
+ 0x38370000, 0x38372000, 0x38374000, 0x38376000, 0x38378000, 0x3837a000, 0x3837c000, 0x3837e000,
+ 0x38380000, 0x38382000, 0x38384000, 0x38386000, 0x38388000, 0x3838a000, 0x3838c000, 0x3838e000,
+ 0x38390000, 0x38392000, 0x38394000, 0x38396000, 0x38398000, 0x3839a000, 0x3839c000, 0x3839e000,
+ 0x383a0000, 0x383a2000, 0x383a4000, 0x383a6000, 0x383a8000, 0x383aa000, 0x383ac000, 0x383ae000,
+ 0x383b0000, 0x383b2000, 0x383b4000, 0x383b6000, 0x383b8000, 0x383ba000, 0x383bc000, 0x383be000,
+ 0x383c0000, 0x383c2000, 0x383c4000, 0x383c6000, 0x383c8000, 0x383ca000, 0x383cc000, 0x383ce000,
+ 0x383d0000, 0x383d2000, 0x383d4000, 0x383d6000, 0x383d8000, 0x383da000, 0x383dc000, 0x383de000,
+ 0x383e0000, 0x383e2000, 0x383e4000, 0x383e6000, 0x383e8000, 0x383ea000, 0x383ec000, 0x383ee000,
+ 0x383f0000, 0x383f2000, 0x383f4000, 0x383f6000, 0x383f8000, 0x383fa000, 0x383fc000, 0x383fe000,
+ 0x38400000, 0x38402000, 0x38404000, 0x38406000, 0x38408000, 0x3840a000, 0x3840c000, 0x3840e000,
+ 0x38410000, 0x38412000, 0x38414000, 0x38416000, 0x38418000, 0x3841a000, 0x3841c000, 0x3841e000,
+ 0x38420000, 0x38422000, 0x38424000, 0x38426000, 0x38428000, 0x3842a000, 0x3842c000, 0x3842e000,
+ 0x38430000, 0x38432000, 0x38434000, 0x38436000, 0x38438000, 0x3843a000, 0x3843c000, 0x3843e000,
+ 0x38440000, 0x38442000, 0x38444000, 0x38446000, 0x38448000, 0x3844a000, 0x3844c000, 0x3844e000,
+ 0x38450000, 0x38452000, 0x38454000, 0x38456000, 0x38458000, 0x3845a000, 0x3845c000, 0x3845e000,
+ 0x38460000, 0x38462000, 0x38464000, 0x38466000, 0x38468000, 0x3846a000, 0x3846c000, 0x3846e000,
+ 0x38470000, 0x38472000, 0x38474000, 0x38476000, 0x38478000, 0x3847a000, 0x3847c000, 0x3847e000,
+ 0x38480000, 0x38482000, 0x38484000, 0x38486000, 0x38488000, 0x3848a000, 0x3848c000, 0x3848e000,
+ 0x38490000, 0x38492000, 0x38494000, 0x38496000, 0x38498000, 0x3849a000, 0x3849c000, 0x3849e000,
+ 0x384a0000, 0x384a2000, 0x384a4000, 0x384a6000, 0x384a8000, 0x384aa000, 0x384ac000, 0x384ae000,
+ 0x384b0000, 0x384b2000, 0x384b4000, 0x384b6000, 0x384b8000, 0x384ba000, 0x384bc000, 0x384be000,
+ 0x384c0000, 0x384c2000, 0x384c4000, 0x384c6000, 0x384c8000, 0x384ca000, 0x384cc000, 0x384ce000,
+ 0x384d0000, 0x384d2000, 0x384d4000, 0x384d6000, 0x384d8000, 0x384da000, 0x384dc000, 0x384de000,
+ 0x384e0000, 0x384e2000, 0x384e4000, 0x384e6000, 0x384e8000, 0x384ea000, 0x384ec000, 0x384ee000,
+ 0x384f0000, 0x384f2000, 0x384f4000, 0x384f6000, 0x384f8000, 0x384fa000, 0x384fc000, 0x384fe000,
+ 0x38500000, 0x38502000, 0x38504000, 0x38506000, 0x38508000, 0x3850a000, 0x3850c000, 0x3850e000,
+ 0x38510000, 0x38512000, 0x38514000, 0x38516000, 0x38518000, 0x3851a000, 0x3851c000, 0x3851e000,
+ 0x38520000, 0x38522000, 0x38524000, 0x38526000, 0x38528000, 0x3852a000, 0x3852c000, 0x3852e000,
+ 0x38530000, 0x38532000, 0x38534000, 0x38536000, 0x38538000, 0x3853a000, 0x3853c000, 0x3853e000,
+ 0x38540000, 0x38542000, 0x38544000, 0x38546000, 0x38548000, 0x3854a000, 0x3854c000, 0x3854e000,
+ 0x38550000, 0x38552000, 0x38554000, 0x38556000, 0x38558000, 0x3855a000, 0x3855c000, 0x3855e000,
+ 0x38560000, 0x38562000, 0x38564000, 0x38566000, 0x38568000, 0x3856a000, 0x3856c000, 0x3856e000,
+ 0x38570000, 0x38572000, 0x38574000, 0x38576000, 0x38578000, 0x3857a000, 0x3857c000, 0x3857e000,
+ 0x38580000, 0x38582000, 0x38584000, 0x38586000, 0x38588000, 0x3858a000, 0x3858c000, 0x3858e000,
+ 0x38590000, 0x38592000, 0x38594000, 0x38596000, 0x38598000, 0x3859a000, 0x3859c000, 0x3859e000,
+ 0x385a0000, 0x385a2000, 0x385a4000, 0x385a6000, 0x385a8000, 0x385aa000, 0x385ac000, 0x385ae000,
+ 0x385b0000, 0x385b2000, 0x385b4000, 0x385b6000, 0x385b8000, 0x385ba000, 0x385bc000, 0x385be000,
+ 0x385c0000, 0x385c2000, 0x385c4000, 0x385c6000, 0x385c8000, 0x385ca000, 0x385cc000, 0x385ce000,
+ 0x385d0000, 0x385d2000, 0x385d4000, 0x385d6000, 0x385d8000, 0x385da000, 0x385dc000, 0x385de000,
+ 0x385e0000, 0x385e2000, 0x385e4000, 0x385e6000, 0x385e8000, 0x385ea000, 0x385ec000, 0x385ee000,
+ 0x385f0000, 0x385f2000, 0x385f4000, 0x385f6000, 0x385f8000, 0x385fa000, 0x385fc000, 0x385fe000,
+ 0x38600000, 0x38602000, 0x38604000, 0x38606000, 0x38608000, 0x3860a000, 0x3860c000, 0x3860e000,
+ 0x38610000, 0x38612000, 0x38614000, 0x38616000, 0x38618000, 0x3861a000, 0x3861c000, 0x3861e000,
+ 0x38620000, 0x38622000, 0x38624000, 0x38626000, 0x38628000, 0x3862a000, 0x3862c000, 0x3862e000,
+ 0x38630000, 0x38632000, 0x38634000, 0x38636000, 0x38638000, 0x3863a000, 0x3863c000, 0x3863e000,
+ 0x38640000, 0x38642000, 0x38644000, 0x38646000, 0x38648000, 0x3864a000, 0x3864c000, 0x3864e000,
+ 0x38650000, 0x38652000, 0x38654000, 0x38656000, 0x38658000, 0x3865a000, 0x3865c000, 0x3865e000,
+ 0x38660000, 0x38662000, 0x38664000, 0x38666000, 0x38668000, 0x3866a000, 0x3866c000, 0x3866e000,
+ 0x38670000, 0x38672000, 0x38674000, 0x38676000, 0x38678000, 0x3867a000, 0x3867c000, 0x3867e000,
+ 0x38680000, 0x38682000, 0x38684000, 0x38686000, 0x38688000, 0x3868a000, 0x3868c000, 0x3868e000,
+ 0x38690000, 0x38692000, 0x38694000, 0x38696000, 0x38698000, 0x3869a000, 0x3869c000, 0x3869e000,
+ 0x386a0000, 0x386a2000, 0x386a4000, 0x386a6000, 0x386a8000, 0x386aa000, 0x386ac000, 0x386ae000,
+ 0x386b0000, 0x386b2000, 0x386b4000, 0x386b6000, 0x386b8000, 0x386ba000, 0x386bc000, 0x386be000,
+ 0x386c0000, 0x386c2000, 0x386c4000, 0x386c6000, 0x386c8000, 0x386ca000, 0x386cc000, 0x386ce000,
+ 0x386d0000, 0x386d2000, 0x386d4000, 0x386d6000, 0x386d8000, 0x386da000, 0x386dc000, 0x386de000,
+ 0x386e0000, 0x386e2000, 0x386e4000, 0x386e6000, 0x386e8000, 0x386ea000, 0x386ec000, 0x386ee000,
+ 0x386f0000, 0x386f2000, 0x386f4000, 0x386f6000, 0x386f8000, 0x386fa000, 0x386fc000, 0x386fe000,
+ 0x38700000, 0x38702000, 0x38704000, 0x38706000, 0x38708000, 0x3870a000, 0x3870c000, 0x3870e000,
+ 0x38710000, 0x38712000, 0x38714000, 0x38716000, 0x38718000, 0x3871a000, 0x3871c000, 0x3871e000,
+ 0x38720000, 0x38722000, 0x38724000, 0x38726000, 0x38728000, 0x3872a000, 0x3872c000, 0x3872e000,
+ 0x38730000, 0x38732000, 0x38734000, 0x38736000, 0x38738000, 0x3873a000, 0x3873c000, 0x3873e000,
+ 0x38740000, 0x38742000, 0x38744000, 0x38746000, 0x38748000, 0x3874a000, 0x3874c000, 0x3874e000,
+ 0x38750000, 0x38752000, 0x38754000, 0x38756000, 0x38758000, 0x3875a000, 0x3875c000, 0x3875e000,
+ 0x38760000, 0x38762000, 0x38764000, 0x38766000, 0x38768000, 0x3876a000, 0x3876c000, 0x3876e000,
+ 0x38770000, 0x38772000, 0x38774000, 0x38776000, 0x38778000, 0x3877a000, 0x3877c000, 0x3877e000,
+ 0x38780000, 0x38782000, 0x38784000, 0x38786000, 0x38788000, 0x3878a000, 0x3878c000, 0x3878e000,
+ 0x38790000, 0x38792000, 0x38794000, 0x38796000, 0x38798000, 0x3879a000, 0x3879c000, 0x3879e000,
+ 0x387a0000, 0x387a2000, 0x387a4000, 0x387a6000, 0x387a8000, 0x387aa000, 0x387ac000, 0x387ae000,
+ 0x387b0000, 0x387b2000, 0x387b4000, 0x387b6000, 0x387b8000, 0x387ba000, 0x387bc000, 0x387be000,
+ 0x387c0000, 0x387c2000, 0x387c4000, 0x387c6000, 0x387c8000, 0x387ca000, 0x387cc000, 0x387ce000,
+ 0x387d0000, 0x387d2000, 0x387d4000, 0x387d6000, 0x387d8000, 0x387da000, 0x387dc000, 0x387de000,
+ 0x387e0000, 0x387e2000, 0x387e4000, 0x387e6000, 0x387e8000, 0x387ea000, 0x387ec000, 0x387ee000,
+ 0x387f0000, 0x387f2000, 0x387f4000, 0x387f6000, 0x387f8000, 0x387fa000, 0x387fc000, 0x387fe000,
+};
+
+const static unsigned g_exponent[64] = {
+ 0x00000000, 0x00800000, 0x01000000, 0x01800000, 0x02000000, 0x02800000, 0x03000000, 0x03800000,
+ 0x04000000, 0x04800000, 0x05000000, 0x05800000, 0x06000000, 0x06800000, 0x07000000, 0x07800000,
+ 0x08000000, 0x08800000, 0x09000000, 0x09800000, 0x0a000000, 0x0a800000, 0x0b000000, 0x0b800000,
+ 0x0c000000, 0x0c800000, 0x0d000000, 0x0d800000, 0x0e000000, 0x0e800000, 0x0f000000, 0x47800000,
+ 0x80000000, 0x80800000, 0x81000000, 0x81800000, 0x82000000, 0x82800000, 0x83000000, 0x83800000,
+ 0x84000000, 0x84800000, 0x85000000, 0x85800000, 0x86000000, 0x86800000, 0x87000000, 0x87800000,
+ 0x88000000, 0x88800000, 0x89000000, 0x89800000, 0x8a000000, 0x8a800000, 0x8b000000, 0x8b800000,
+ 0x8c000000, 0x8c800000, 0x8d000000, 0x8d800000, 0x8e000000, 0x8e800000, 0x8f000000, 0xc7800000,
+};
+
+const static unsigned g_offset[64] = {
+ 0x00000000, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400,
+ 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400,
+ 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400,
+ 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400,
+ 0x00000000, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400,
+ 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400,
+ 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400,
+ 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400, 0x00000400,
+};
+
+float float16ToFloat32(unsigned short h)
+{
+ unsigned i32 = g_mantissa[g_offset[h >> 10] + (h & 0x3ff)] + g_exponent[h >> 10];
+ return bitCast<float>(i32);
+}
+} // namespace gl
diff --git a/gfx/angle/checkout/src/common/MemoryBuffer.cpp b/gfx/angle/checkout/src/common/MemoryBuffer.cpp
new file mode 100644
index 0000000000..aadffe8bbe
--- /dev/null
+++ b/gfx/angle/checkout/src/common/MemoryBuffer.cpp
@@ -0,0 +1,179 @@
+//
+// 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.
+//
+
+#include "common/MemoryBuffer.h"
+
+#include <algorithm>
+#include <cstdlib>
+
+#include "common/debug.h"
+
+namespace angle
+{
+
+// MemoryBuffer implementation.
+MemoryBuffer::~MemoryBuffer()
+{
+ if (mData)
+ {
+ free(mData);
+ mData = nullptr;
+ }
+}
+
+bool MemoryBuffer::resize(size_t size)
+{
+ if (size == 0)
+ {
+ if (mData)
+ {
+ free(mData);
+ mData = nullptr;
+ }
+ mSize = 0;
+ return true;
+ }
+
+ if (size == mSize)
+ {
+ return true;
+ }
+
+ // Only reallocate if the size has changed.
+ uint8_t *newMemory = static_cast<uint8_t *>(malloc(sizeof(uint8_t) * size));
+ if (newMemory == nullptr)
+ {
+ return false;
+ }
+
+ if (mData)
+ {
+ // Copy the intersection of the old data and the new data
+ std::copy(mData, mData + std::min(mSize, size), newMemory);
+ free(mData);
+ }
+
+ mData = newMemory;
+ mSize = size;
+
+ return true;
+}
+
+void MemoryBuffer::fill(uint8_t datum)
+{
+ if (!empty())
+ {
+ std::fill(mData, mData + mSize, datum);
+ }
+}
+
+MemoryBuffer::MemoryBuffer(MemoryBuffer &&other) : MemoryBuffer()
+{
+ *this = std::move(other);
+}
+
+MemoryBuffer &MemoryBuffer::operator=(MemoryBuffer &&other)
+{
+ std::swap(mSize, other.mSize);
+ std::swap(mData, other.mData);
+ return *this;
+}
+
+namespace
+{
+static constexpr uint32_t kDefaultScratchBufferLifetime = 1000u;
+
+} // anonymous namespace
+
+// ScratchBuffer implementation.
+ScratchBuffer::ScratchBuffer() : ScratchBuffer(kDefaultScratchBufferLifetime) {}
+
+ScratchBuffer::ScratchBuffer(uint32_t lifetime) : mLifetime(lifetime), mResetCounter(lifetime) {}
+
+ScratchBuffer::~ScratchBuffer() {}
+
+ScratchBuffer::ScratchBuffer(ScratchBuffer &&other)
+{
+ *this = std::move(other);
+}
+
+ScratchBuffer &ScratchBuffer::operator=(ScratchBuffer &&other)
+{
+ std::swap(mLifetime, other.mLifetime);
+ std::swap(mResetCounter, other.mResetCounter);
+ std::swap(mScratchMemory, other.mScratchMemory);
+ return *this;
+}
+
+bool ScratchBuffer::get(size_t requestedSize, MemoryBuffer **memoryBufferOut)
+{
+ return getImpl(requestedSize, memoryBufferOut, Optional<uint8_t>::Invalid());
+}
+
+bool ScratchBuffer::getInitialized(size_t requestedSize,
+ MemoryBuffer **memoryBufferOut,
+ uint8_t initValue)
+{
+ return getImpl(requestedSize, memoryBufferOut, Optional<uint8_t>(initValue));
+}
+
+bool ScratchBuffer::getImpl(size_t requestedSize,
+ MemoryBuffer **memoryBufferOut,
+ Optional<uint8_t> initValue)
+{
+ if (mScratchMemory.size() == requestedSize)
+ {
+ mResetCounter = mLifetime;
+ *memoryBufferOut = &mScratchMemory;
+ return true;
+ }
+
+ if (mScratchMemory.size() > requestedSize)
+ {
+ tick();
+ }
+
+ if (mScratchMemory.size() < requestedSize)
+ {
+ if (!mScratchMemory.resize(requestedSize))
+ {
+ return false;
+ }
+ mResetCounter = mLifetime;
+ if (initValue.valid())
+ {
+ mScratchMemory.fill(initValue.value());
+ }
+ }
+
+ ASSERT(mScratchMemory.size() >= requestedSize);
+
+ *memoryBufferOut = &mScratchMemory;
+ return true;
+}
+
+void ScratchBuffer::tick()
+{
+ if (mResetCounter > 0)
+ {
+ --mResetCounter;
+ if (mResetCounter == 0)
+ {
+ clear();
+ }
+ }
+}
+
+void ScratchBuffer::clear()
+{
+ mResetCounter = mLifetime;
+ if (mScratchMemory.size() > 0)
+ {
+ mScratchMemory.clear();
+ }
+}
+
+} // namespace angle
diff --git a/gfx/angle/checkout/src/common/MemoryBuffer.h b/gfx/angle/checkout/src/common/MemoryBuffer.h
new file mode 100644
index 0000000000..bcd3aab7a9
--- /dev/null
+++ b/gfx/angle/checkout/src/common/MemoryBuffer.h
@@ -0,0 +1,93 @@
+//
+// 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.
+//
+
+#ifndef COMMON_MEMORYBUFFER_H_
+#define COMMON_MEMORYBUFFER_H_
+
+#include "common/Optional.h"
+#include "common/angleutils.h"
+#include "common/debug.h"
+
+#include <stdint.h>
+#include <cstddef>
+
+namespace angle
+{
+
+class MemoryBuffer final : NonCopyable
+{
+ public:
+ MemoryBuffer() = default;
+ ~MemoryBuffer();
+
+ MemoryBuffer(MemoryBuffer &&other);
+ MemoryBuffer &operator=(MemoryBuffer &&other);
+
+ [[nodiscard]] bool resize(size_t size);
+ void clear() { (void)resize(0); }
+ size_t size() const { return mSize; }
+ bool empty() const { return mSize == 0; }
+
+ const uint8_t *data() const { return mData; }
+ uint8_t *data()
+ {
+ ASSERT(mData);
+ return mData;
+ }
+
+ uint8_t &operator[](size_t pos)
+ {
+ ASSERT(pos < mSize);
+ return mData[pos];
+ }
+ const uint8_t &operator[](size_t pos) const
+ {
+ ASSERT(pos < mSize);
+ return mData[pos];
+ }
+
+ void fill(uint8_t datum);
+
+ private:
+ size_t mSize = 0;
+ uint8_t *mData = nullptr;
+};
+
+class ScratchBuffer final : NonCopyable
+{
+ public:
+ // If we request a scratch buffer requesting a smaller size this many times, release and
+ // recreate the scratch buffer. This ensures we don't have a degenerate case where we are stuck
+ // hogging memory.
+ ScratchBuffer();
+ ScratchBuffer(uint32_t lifetime);
+ ~ScratchBuffer();
+
+ ScratchBuffer(ScratchBuffer &&other);
+ ScratchBuffer &operator=(ScratchBuffer &&other);
+
+ // Returns true with a memory buffer of the requested size, or false on failure.
+ bool get(size_t requestedSize, MemoryBuffer **memoryBufferOut);
+
+ // Same as get, but ensures new values are initialized to a fixed constant.
+ bool getInitialized(size_t requestedSize, MemoryBuffer **memoryBufferOut, uint8_t initValue);
+
+ // Ticks the release counter for the scratch buffer. Also done implicitly in get().
+ void tick();
+
+ void clear();
+
+ private:
+ bool getImpl(size_t requestedSize, MemoryBuffer **memoryBufferOut, Optional<uint8_t> initValue);
+
+ uint32_t mLifetime;
+ uint32_t mResetCounter;
+ MemoryBuffer mScratchMemory;
+};
+
+} // namespace angle
+
+#endif // COMMON_MEMORYBUFFER_H_
diff --git a/gfx/angle/checkout/src/common/Optional.h b/gfx/angle/checkout/src/common/Optional.h
new file mode 100644
index 0000000000..46c65dde4e
--- /dev/null
+++ b/gfx/angle/checkout/src/common/Optional.h
@@ -0,0 +1,74 @@
+//
+// 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.
+//
+// Optional.h:
+// Represents a type that may be invalid, similar to std::optional.
+//
+
+#ifndef COMMON_OPTIONAL_H_
+#define COMMON_OPTIONAL_H_
+
+#include <utility>
+
+template <class T>
+struct Optional
+{
+ Optional() : mValid(false), mValue(T()) {}
+
+ Optional(const T &valueIn) : mValid(true), mValue(valueIn) {}
+
+ Optional(const Optional &other) : mValid(other.mValid), mValue(other.mValue) {}
+
+ Optional &operator=(const Optional &other)
+ {
+ this->mValid = other.mValid;
+ this->mValue = other.mValue;
+ return *this;
+ }
+
+ Optional &operator=(const T &value)
+ {
+ mValue = value;
+ mValid = true;
+ return *this;
+ }
+
+ Optional &operator=(T &&value)
+ {
+ mValue = std::move(value);
+ mValid = true;
+ return *this;
+ }
+
+ void reset() { mValid = false; }
+ T &&release()
+ {
+ mValid = false;
+ return std::move(mValue);
+ }
+
+ static Optional Invalid() { return Optional(); }
+
+ bool valid() const { return mValid; }
+ T &value() { return mValue; }
+ const T &value() const { return mValue; }
+
+ bool operator==(const Optional &other) const
+ {
+ return ((mValid == other.mValid) && (!mValid || (mValue == other.mValue)));
+ }
+
+ bool operator!=(const Optional &other) const { return !(*this == other); }
+
+ bool operator==(const T &value) const { return mValid && (mValue == value); }
+
+ bool operator!=(const T &value) const { return !(*this == value); }
+
+ private:
+ bool mValid;
+ T mValue;
+};
+
+#endif // COMMON_OPTIONAL_H_
diff --git a/gfx/angle/checkout/src/common/PackedEGLEnums_autogen.cpp b/gfx/angle/checkout/src/common/PackedEGLEnums_autogen.cpp
new file mode 100644
index 0000000000..738254bd18
--- /dev/null
+++ b/gfx/angle/checkout/src/common/PackedEGLEnums_autogen.cpp
@@ -0,0 +1,452 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_packed_gl_enums.py using data from packed_egl_enums.json.
+//
+// Copyright 2017 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.
+//
+// PackedEGLEnums_autogen.cpp:
+// Implements ANGLE-specific enums classes for EGLenums and functions operating
+// on them.
+
+#include "common/PackedEGLEnums_autogen.h"
+#include "common/debug.h"
+
+namespace egl
+{
+
+template <>
+ColorSpace FromEGLenum<ColorSpace>(EGLenum from)
+{
+ switch (from)
+ {
+ case EGL_COLORSPACE_sRGB:
+ return ColorSpace::sRGB;
+ case EGL_COLORSPACE_LINEAR:
+ return ColorSpace::Linear;
+ default:
+ return ColorSpace::InvalidEnum;
+ }
+}
+
+EGLenum ToEGLenum(ColorSpace from)
+{
+ switch (from)
+ {
+ case ColorSpace::sRGB:
+ return EGL_COLORSPACE_sRGB;
+ case ColorSpace::Linear:
+ return EGL_COLORSPACE_LINEAR;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+std::ostream &operator<<(std::ostream &os, ColorSpace value)
+{
+ switch (value)
+ {
+ case ColorSpace::sRGB:
+ os << "EGL_COLORSPACE_sRGB";
+ break;
+ case ColorSpace::Linear:
+ os << "EGL_COLORSPACE_LINEAR";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+ return os;
+}
+
+template <>
+CompositorTiming FromEGLenum<CompositorTiming>(EGLenum from)
+{
+ switch (from)
+ {
+ case EGL_COMPOSITE_DEADLINE_ANDROID:
+ return CompositorTiming::CompositeDeadline;
+ case EGL_COMPOSITE_INTERVAL_ANDROID:
+ return CompositorTiming::CompositInterval;
+ case EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID:
+ return CompositorTiming::CompositToPresentLatency;
+ default:
+ return CompositorTiming::InvalidEnum;
+ }
+}
+
+EGLenum ToEGLenum(CompositorTiming from)
+{
+ switch (from)
+ {
+ case CompositorTiming::CompositeDeadline:
+ return EGL_COMPOSITE_DEADLINE_ANDROID;
+ case CompositorTiming::CompositInterval:
+ return EGL_COMPOSITE_INTERVAL_ANDROID;
+ case CompositorTiming::CompositToPresentLatency:
+ return EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+std::ostream &operator<<(std::ostream &os, CompositorTiming value)
+{
+ switch (value)
+ {
+ case CompositorTiming::CompositeDeadline:
+ os << "EGL_COMPOSITE_DEADLINE_ANDROID";
+ break;
+ case CompositorTiming::CompositInterval:
+ os << "EGL_COMPOSITE_INTERVAL_ANDROID";
+ break;
+ case CompositorTiming::CompositToPresentLatency:
+ os << "EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+ return os;
+}
+
+template <>
+ContextPriority FromEGLenum<ContextPriority>(EGLenum from)
+{
+ switch (from)
+ {
+ case EGL_CONTEXT_PRIORITY_LOW_IMG:
+ return ContextPriority::Low;
+ case EGL_CONTEXT_PRIORITY_MEDIUM_IMG:
+ return ContextPriority::Medium;
+ case EGL_CONTEXT_PRIORITY_HIGH_IMG:
+ return ContextPriority::High;
+ default:
+ return ContextPriority::InvalidEnum;
+ }
+}
+
+EGLenum ToEGLenum(ContextPriority from)
+{
+ switch (from)
+ {
+ case ContextPriority::Low:
+ return EGL_CONTEXT_PRIORITY_LOW_IMG;
+ case ContextPriority::Medium:
+ return EGL_CONTEXT_PRIORITY_MEDIUM_IMG;
+ case ContextPriority::High:
+ return EGL_CONTEXT_PRIORITY_HIGH_IMG;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+std::ostream &operator<<(std::ostream &os, ContextPriority value)
+{
+ switch (value)
+ {
+ case ContextPriority::Low:
+ os << "EGL_CONTEXT_PRIORITY_LOW_IMG";
+ break;
+ case ContextPriority::Medium:
+ os << "EGL_CONTEXT_PRIORITY_MEDIUM_IMG";
+ break;
+ case ContextPriority::High:
+ os << "EGL_CONTEXT_PRIORITY_HIGH_IMG";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+ return os;
+}
+
+template <>
+MessageType FromEGLenum<MessageType>(EGLenum from)
+{
+ switch (from)
+ {
+ case EGL_DEBUG_MSG_CRITICAL_KHR:
+ return MessageType::Critical;
+ case EGL_DEBUG_MSG_ERROR_KHR:
+ return MessageType::Error;
+ case EGL_DEBUG_MSG_WARN_KHR:
+ return MessageType::Warn;
+ case EGL_DEBUG_MSG_INFO_KHR:
+ return MessageType::Info;
+ default:
+ return MessageType::InvalidEnum;
+ }
+}
+
+EGLenum ToEGLenum(MessageType from)
+{
+ switch (from)
+ {
+ case MessageType::Critical:
+ return EGL_DEBUG_MSG_CRITICAL_KHR;
+ case MessageType::Error:
+ return EGL_DEBUG_MSG_ERROR_KHR;
+ case MessageType::Warn:
+ return EGL_DEBUG_MSG_WARN_KHR;
+ case MessageType::Info:
+ return EGL_DEBUG_MSG_INFO_KHR;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+std::ostream &operator<<(std::ostream &os, MessageType value)
+{
+ switch (value)
+ {
+ case MessageType::Critical:
+ os << "EGL_DEBUG_MSG_CRITICAL_KHR";
+ break;
+ case MessageType::Error:
+ os << "EGL_DEBUG_MSG_ERROR_KHR";
+ break;
+ case MessageType::Warn:
+ os << "EGL_DEBUG_MSG_WARN_KHR";
+ break;
+ case MessageType::Info:
+ os << "EGL_DEBUG_MSG_INFO_KHR";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+ return os;
+}
+
+template <>
+ObjectType FromEGLenum<ObjectType>(EGLenum from)
+{
+ switch (from)
+ {
+ case EGL_OBJECT_THREAD_KHR:
+ return ObjectType::Thread;
+ case EGL_OBJECT_DISPLAY_KHR:
+ return ObjectType::Display;
+ case EGL_OBJECT_CONTEXT_KHR:
+ return ObjectType::Context;
+ case EGL_OBJECT_SURFACE_KHR:
+ return ObjectType::Surface;
+ case EGL_OBJECT_IMAGE_KHR:
+ return ObjectType::Image;
+ case EGL_OBJECT_SYNC_KHR:
+ return ObjectType::Sync;
+ case EGL_OBJECT_STREAM_KHR:
+ return ObjectType::Stream;
+ default:
+ return ObjectType::InvalidEnum;
+ }
+}
+
+EGLenum ToEGLenum(ObjectType from)
+{
+ switch (from)
+ {
+ case ObjectType::Thread:
+ return EGL_OBJECT_THREAD_KHR;
+ case ObjectType::Display:
+ return EGL_OBJECT_DISPLAY_KHR;
+ case ObjectType::Context:
+ return EGL_OBJECT_CONTEXT_KHR;
+ case ObjectType::Surface:
+ return EGL_OBJECT_SURFACE_KHR;
+ case ObjectType::Image:
+ return EGL_OBJECT_IMAGE_KHR;
+ case ObjectType::Sync:
+ return EGL_OBJECT_SYNC_KHR;
+ case ObjectType::Stream:
+ return EGL_OBJECT_STREAM_KHR;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+std::ostream &operator<<(std::ostream &os, ObjectType value)
+{
+ switch (value)
+ {
+ case ObjectType::Thread:
+ os << "EGL_OBJECT_THREAD_KHR";
+ break;
+ case ObjectType::Display:
+ os << "EGL_OBJECT_DISPLAY_KHR";
+ break;
+ case ObjectType::Context:
+ os << "EGL_OBJECT_CONTEXT_KHR";
+ break;
+ case ObjectType::Surface:
+ os << "EGL_OBJECT_SURFACE_KHR";
+ break;
+ case ObjectType::Image:
+ os << "EGL_OBJECT_IMAGE_KHR";
+ break;
+ case ObjectType::Sync:
+ os << "EGL_OBJECT_SYNC_KHR";
+ break;
+ case ObjectType::Stream:
+ os << "EGL_OBJECT_STREAM_KHR";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+ return os;
+}
+
+template <>
+TextureFormat FromEGLenum<TextureFormat>(EGLenum from)
+{
+ switch (from)
+ {
+ case EGL_NO_TEXTURE:
+ return TextureFormat::NoTexture;
+ case EGL_TEXTURE_RGB:
+ return TextureFormat::RGB;
+ case EGL_TEXTURE_RGBA:
+ return TextureFormat::RGBA;
+ default:
+ return TextureFormat::InvalidEnum;
+ }
+}
+
+EGLenum ToEGLenum(TextureFormat from)
+{
+ switch (from)
+ {
+ case TextureFormat::NoTexture:
+ return EGL_NO_TEXTURE;
+ case TextureFormat::RGB:
+ return EGL_TEXTURE_RGB;
+ case TextureFormat::RGBA:
+ return EGL_TEXTURE_RGBA;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+std::ostream &operator<<(std::ostream &os, TextureFormat value)
+{
+ switch (value)
+ {
+ case TextureFormat::NoTexture:
+ os << "EGL_NO_TEXTURE";
+ break;
+ case TextureFormat::RGB:
+ os << "EGL_TEXTURE_RGB";
+ break;
+ case TextureFormat::RGBA:
+ os << "EGL_TEXTURE_RGBA";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+ return os;
+}
+
+template <>
+Timestamp FromEGLenum<Timestamp>(EGLenum from)
+{
+ switch (from)
+ {
+ case EGL_REQUESTED_PRESENT_TIME_ANDROID:
+ return Timestamp::RequestedPresentTime;
+ case EGL_RENDERING_COMPLETE_TIME_ANDROID:
+ return Timestamp::RenderingCompleteTime;
+ case EGL_COMPOSITION_LATCH_TIME_ANDROID:
+ return Timestamp::CompositionLatchTime;
+ case EGL_FIRST_COMPOSITION_START_TIME_ANDROID:
+ return Timestamp::FirstCompositionStartTime;
+ case EGL_LAST_COMPOSITION_START_TIME_ANDROID:
+ return Timestamp::LastCompositionStartTime;
+ case EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID:
+ return Timestamp::FirstCompositionGPUFinishedTime;
+ case EGL_DISPLAY_PRESENT_TIME_ANDROID:
+ return Timestamp::DisplayPresentTime;
+ case EGL_DEQUEUE_READY_TIME_ANDROID:
+ return Timestamp::DequeueReadyTime;
+ case EGL_READS_DONE_TIME_ANDROID:
+ return Timestamp::ReadsDoneTime;
+ default:
+ return Timestamp::InvalidEnum;
+ }
+}
+
+EGLenum ToEGLenum(Timestamp from)
+{
+ switch (from)
+ {
+ case Timestamp::RequestedPresentTime:
+ return EGL_REQUESTED_PRESENT_TIME_ANDROID;
+ case Timestamp::RenderingCompleteTime:
+ return EGL_RENDERING_COMPLETE_TIME_ANDROID;
+ case Timestamp::CompositionLatchTime:
+ return EGL_COMPOSITION_LATCH_TIME_ANDROID;
+ case Timestamp::FirstCompositionStartTime:
+ return EGL_FIRST_COMPOSITION_START_TIME_ANDROID;
+ case Timestamp::LastCompositionStartTime:
+ return EGL_LAST_COMPOSITION_START_TIME_ANDROID;
+ case Timestamp::FirstCompositionGPUFinishedTime:
+ return EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID;
+ case Timestamp::DisplayPresentTime:
+ return EGL_DISPLAY_PRESENT_TIME_ANDROID;
+ case Timestamp::DequeueReadyTime:
+ return EGL_DEQUEUE_READY_TIME_ANDROID;
+ case Timestamp::ReadsDoneTime:
+ return EGL_READS_DONE_TIME_ANDROID;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+std::ostream &operator<<(std::ostream &os, Timestamp value)
+{
+ switch (value)
+ {
+ case Timestamp::RequestedPresentTime:
+ os << "EGL_REQUESTED_PRESENT_TIME_ANDROID";
+ break;
+ case Timestamp::RenderingCompleteTime:
+ os << "EGL_RENDERING_COMPLETE_TIME_ANDROID";
+ break;
+ case Timestamp::CompositionLatchTime:
+ os << "EGL_COMPOSITION_LATCH_TIME_ANDROID";
+ break;
+ case Timestamp::FirstCompositionStartTime:
+ os << "EGL_FIRST_COMPOSITION_START_TIME_ANDROID";
+ break;
+ case Timestamp::LastCompositionStartTime:
+ os << "EGL_LAST_COMPOSITION_START_TIME_ANDROID";
+ break;
+ case Timestamp::FirstCompositionGPUFinishedTime:
+ os << "EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID";
+ break;
+ case Timestamp::DisplayPresentTime:
+ os << "EGL_DISPLAY_PRESENT_TIME_ANDROID";
+ break;
+ case Timestamp::DequeueReadyTime:
+ os << "EGL_DEQUEUE_READY_TIME_ANDROID";
+ break;
+ case Timestamp::ReadsDoneTime:
+ os << "EGL_READS_DONE_TIME_ANDROID";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+ return os;
+}
+
+} // namespace egl
diff --git a/gfx/angle/checkout/src/common/PackedEGLEnums_autogen.h b/gfx/angle/checkout/src/common/PackedEGLEnums_autogen.h
new file mode 100644
index 0000000000..7794e8509e
--- /dev/null
+++ b/gfx/angle/checkout/src/common/PackedEGLEnums_autogen.h
@@ -0,0 +1,144 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_packed_gl_enums.py using data from packed_egl_enums.json.
+//
+// Copyright 2017 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.
+//
+// PackedEGLEnums_autogen.h:
+// Declares ANGLE-specific enums classes for EGLenums and functions operating
+// on them.
+
+#ifndef COMMON_PACKEDEGLENUMS_AUTOGEN_H_
+#define COMMON_PACKEDEGLENUMS_AUTOGEN_H_
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include <cstdint>
+#include <ostream>
+
+namespace egl
+{
+
+template <typename Enum>
+Enum FromEGLenum(EGLenum from);
+
+enum class ColorSpace : uint8_t
+{
+ sRGB = 0,
+ Linear = 1,
+
+ InvalidEnum = 2,
+ EnumCount = 2,
+};
+
+template <>
+ColorSpace FromEGLenum<ColorSpace>(EGLenum from);
+EGLenum ToEGLenum(ColorSpace from);
+std::ostream &operator<<(std::ostream &os, ColorSpace value);
+
+enum class CompositorTiming : uint8_t
+{
+ CompositeDeadline = 0,
+ CompositInterval = 1,
+ CompositToPresentLatency = 2,
+
+ InvalidEnum = 3,
+ EnumCount = 3,
+};
+
+template <>
+CompositorTiming FromEGLenum<CompositorTiming>(EGLenum from);
+EGLenum ToEGLenum(CompositorTiming from);
+std::ostream &operator<<(std::ostream &os, CompositorTiming value);
+
+enum class ContextPriority : uint8_t
+{
+ Low = 0,
+ Medium = 1,
+ High = 2,
+
+ InvalidEnum = 3,
+ EnumCount = 3,
+};
+
+template <>
+ContextPriority FromEGLenum<ContextPriority>(EGLenum from);
+EGLenum ToEGLenum(ContextPriority from);
+std::ostream &operator<<(std::ostream &os, ContextPriority value);
+
+enum class MessageType : uint8_t
+{
+ Critical = 0,
+ Error = 1,
+ Warn = 2,
+ Info = 3,
+
+ InvalidEnum = 4,
+ EnumCount = 4,
+};
+
+template <>
+MessageType FromEGLenum<MessageType>(EGLenum from);
+EGLenum ToEGLenum(MessageType from);
+std::ostream &operator<<(std::ostream &os, MessageType value);
+
+enum class ObjectType : uint8_t
+{
+ Thread = 0,
+ Display = 1,
+ Context = 2,
+ Surface = 3,
+ Image = 4,
+ Sync = 5,
+ Stream = 6,
+
+ InvalidEnum = 7,
+ EnumCount = 7,
+};
+
+template <>
+ObjectType FromEGLenum<ObjectType>(EGLenum from);
+EGLenum ToEGLenum(ObjectType from);
+std::ostream &operator<<(std::ostream &os, ObjectType value);
+
+enum class TextureFormat : uint8_t
+{
+ NoTexture = 0,
+ RGB = 1,
+ RGBA = 2,
+
+ InvalidEnum = 3,
+ EnumCount = 3,
+};
+
+template <>
+TextureFormat FromEGLenum<TextureFormat>(EGLenum from);
+EGLenum ToEGLenum(TextureFormat from);
+std::ostream &operator<<(std::ostream &os, TextureFormat value);
+
+enum class Timestamp : uint8_t
+{
+ RequestedPresentTime = 0,
+ RenderingCompleteTime = 1,
+ CompositionLatchTime = 2,
+ FirstCompositionStartTime = 3,
+ LastCompositionStartTime = 4,
+ FirstCompositionGPUFinishedTime = 5,
+ DisplayPresentTime = 6,
+ DequeueReadyTime = 7,
+ ReadsDoneTime = 8,
+
+ InvalidEnum = 9,
+ EnumCount = 9,
+};
+
+template <>
+Timestamp FromEGLenum<Timestamp>(EGLenum from);
+EGLenum ToEGLenum(Timestamp from);
+std::ostream &operator<<(std::ostream &os, Timestamp value);
+
+} // namespace egl
+
+#endif // COMMON_PACKEDEGLENUMS_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/common/PackedEnums.cpp b/gfx/angle/checkout/src/common/PackedEnums.cpp
new file mode 100644
index 0000000000..e13a502a42
--- /dev/null
+++ b/gfx/angle/checkout/src/common/PackedEnums.cpp
@@ -0,0 +1,673 @@
+// Copyright 2018 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.
+//
+// PackedGLEnums.cpp:
+// Declares ANGLE-specific enums classes for GLEnum and functions operating
+// on them.
+
+#include "common/PackedEnums.h"
+
+#include "common/utilities.h"
+
+namespace gl
+{
+
+TextureType TextureTargetToType(TextureTarget target)
+{
+ switch (target)
+ {
+ case TextureTarget::CubeMapNegativeX:
+ case TextureTarget::CubeMapNegativeY:
+ case TextureTarget::CubeMapNegativeZ:
+ case TextureTarget::CubeMapPositiveX:
+ case TextureTarget::CubeMapPositiveY:
+ case TextureTarget::CubeMapPositiveZ:
+ return TextureType::CubeMap;
+ case TextureTarget::CubeMapArray:
+ return TextureType::CubeMapArray;
+ case TextureTarget::External:
+ return TextureType::External;
+ case TextureTarget::Rectangle:
+ return TextureType::Rectangle;
+ case TextureTarget::_2D:
+ return TextureType::_2D;
+ case TextureTarget::_2DArray:
+ return TextureType::_2DArray;
+ case TextureTarget::_2DMultisample:
+ return TextureType::_2DMultisample;
+ case TextureTarget::_2DMultisampleArray:
+ return TextureType::_2DMultisampleArray;
+ case TextureTarget::_3D:
+ return TextureType::_3D;
+ case TextureTarget::VideoImage:
+ return TextureType::VideoImage;
+ case TextureTarget::Buffer:
+ return TextureType::Buffer;
+ case TextureTarget::InvalidEnum:
+ return TextureType::InvalidEnum;
+ default:
+ UNREACHABLE();
+ return TextureType::InvalidEnum;
+ }
+}
+
+bool IsCubeMapFaceTarget(TextureTarget target)
+{
+ return TextureTargetToType(target) == TextureType::CubeMap;
+}
+
+TextureTarget NonCubeTextureTypeToTarget(TextureType type)
+{
+ switch (type)
+ {
+ case TextureType::External:
+ return TextureTarget::External;
+ case TextureType::Rectangle:
+ return TextureTarget::Rectangle;
+ case TextureType::_2D:
+ return TextureTarget::_2D;
+ case TextureType::_2DArray:
+ return TextureTarget::_2DArray;
+ case TextureType::_2DMultisample:
+ return TextureTarget::_2DMultisample;
+ case TextureType::_2DMultisampleArray:
+ return TextureTarget::_2DMultisampleArray;
+ case TextureType::_3D:
+ return TextureTarget::_3D;
+ case TextureType::CubeMapArray:
+ return TextureTarget::CubeMapArray;
+ case TextureType::VideoImage:
+ return TextureTarget::VideoImage;
+ case TextureType::Buffer:
+ return TextureTarget::Buffer;
+ default:
+ UNREACHABLE();
+ return TextureTarget::InvalidEnum;
+ }
+}
+
+// Check that we can do arithmetic on TextureTarget to convert from / to cube map faces
+static_assert(static_cast<uint8_t>(TextureTarget::CubeMapNegativeX) -
+ static_cast<uint8_t>(TextureTarget::CubeMapPositiveX) ==
+ 1u,
+ "");
+static_assert(static_cast<uint8_t>(TextureTarget::CubeMapPositiveY) -
+ static_cast<uint8_t>(TextureTarget::CubeMapPositiveX) ==
+ 2u,
+ "");
+static_assert(static_cast<uint8_t>(TextureTarget::CubeMapNegativeY) -
+ static_cast<uint8_t>(TextureTarget::CubeMapPositiveX) ==
+ 3u,
+ "");
+static_assert(static_cast<uint8_t>(TextureTarget::CubeMapPositiveZ) -
+ static_cast<uint8_t>(TextureTarget::CubeMapPositiveX) ==
+ 4u,
+ "");
+static_assert(static_cast<uint8_t>(TextureTarget::CubeMapNegativeZ) -
+ static_cast<uint8_t>(TextureTarget::CubeMapPositiveX) ==
+ 5u,
+ "");
+
+TextureTarget CubeFaceIndexToTextureTarget(size_t face)
+{
+ ASSERT(face < 6u);
+ return static_cast<TextureTarget>(static_cast<uint8_t>(TextureTarget::CubeMapPositiveX) + face);
+}
+
+size_t CubeMapTextureTargetToFaceIndex(TextureTarget target)
+{
+ ASSERT(IsCubeMapFaceTarget(target));
+ return static_cast<uint8_t>(target) - static_cast<uint8_t>(TextureTarget::CubeMapPositiveX);
+}
+
+TextureType SamplerTypeToTextureType(GLenum samplerType)
+{
+ switch (samplerType)
+ {
+ case GL_SAMPLER_2D:
+ case GL_INT_SAMPLER_2D:
+ case GL_UNSIGNED_INT_SAMPLER_2D:
+ case GL_SAMPLER_2D_SHADOW:
+ return TextureType::_2D;
+
+ case GL_SAMPLER_EXTERNAL_OES:
+ case GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT:
+ return TextureType::External;
+
+ case GL_SAMPLER_CUBE:
+ case GL_INT_SAMPLER_CUBE:
+ case GL_UNSIGNED_INT_SAMPLER_CUBE:
+ case GL_SAMPLER_CUBE_SHADOW:
+ return TextureType::CubeMap;
+
+ case GL_SAMPLER_CUBE_MAP_ARRAY:
+ case GL_INT_SAMPLER_CUBE_MAP_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY:
+ case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW:
+ return TextureType::CubeMapArray;
+
+ case GL_SAMPLER_2D_ARRAY:
+ case GL_INT_SAMPLER_2D_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
+ case GL_SAMPLER_2D_ARRAY_SHADOW:
+ return TextureType::_2DArray;
+
+ case GL_SAMPLER_3D:
+ case GL_INT_SAMPLER_3D:
+ case GL_UNSIGNED_INT_SAMPLER_3D:
+ return TextureType::_3D;
+
+ case GL_SAMPLER_2D_MULTISAMPLE:
+ case GL_INT_SAMPLER_2D_MULTISAMPLE:
+ case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
+ return TextureType::_2DMultisample;
+
+ case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ return TextureType::_2DMultisampleArray;
+
+ case GL_SAMPLER_BUFFER:
+ case GL_INT_SAMPLER_BUFFER:
+ case GL_UNSIGNED_INT_SAMPLER_BUFFER:
+ return TextureType::Buffer;
+
+ case GL_SAMPLER_2D_RECT_ANGLE:
+ return TextureType::Rectangle;
+
+ case GL_SAMPLER_VIDEO_IMAGE_WEBGL:
+ return TextureType::VideoImage;
+
+ default:
+ UNREACHABLE();
+ return TextureType::InvalidEnum;
+ }
+}
+
+TextureType ImageTypeToTextureType(GLenum imageType)
+{
+ switch (imageType)
+ {
+ case GL_IMAGE_2D:
+ case GL_INT_IMAGE_2D:
+ case GL_UNSIGNED_INT_IMAGE_2D:
+ return TextureType::_2D;
+
+ case GL_IMAGE_CUBE:
+ case GL_INT_IMAGE_CUBE:
+ case GL_UNSIGNED_INT_IMAGE_CUBE:
+ return TextureType::CubeMap;
+
+ case GL_IMAGE_CUBE_MAP_ARRAY:
+ case GL_INT_IMAGE_CUBE_MAP_ARRAY:
+ case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY:
+ return TextureType::CubeMapArray;
+
+ case GL_IMAGE_2D_ARRAY:
+ case GL_INT_IMAGE_2D_ARRAY:
+ case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
+ return TextureType::_2DArray;
+
+ case GL_IMAGE_3D:
+ case GL_INT_IMAGE_3D:
+ case GL_UNSIGNED_INT_IMAGE_3D:
+ return TextureType::_3D;
+
+ case GL_IMAGE_BUFFER:
+ case GL_INT_IMAGE_BUFFER:
+ case GL_UNSIGNED_INT_IMAGE_BUFFER:
+ return TextureType::Buffer;
+
+ default:
+ UNREACHABLE();
+ return TextureType::InvalidEnum;
+ }
+}
+
+bool IsMultisampled(TextureType type)
+{
+ switch (type)
+ {
+ case TextureType::_2DMultisample:
+ case TextureType::_2DMultisampleArray:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool IsArrayTextureType(TextureType type)
+{
+ switch (type)
+ {
+ case TextureType::_2DArray:
+ case TextureType::_2DMultisampleArray:
+ case TextureType::CubeMapArray:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool IsStaticBufferUsage(BufferUsage useage)
+{
+ switch (useage)
+ {
+ case BufferUsage::StaticCopy:
+ case BufferUsage::StaticDraw:
+ case BufferUsage::StaticRead:
+ return true;
+ default:
+ return false;
+ }
+}
+
+std::ostream &operator<<(std::ostream &os, PrimitiveMode value)
+{
+ switch (value)
+ {
+ case PrimitiveMode::LineLoop:
+ os << "GL_LINE_LOOP";
+ break;
+ case PrimitiveMode::Lines:
+ os << "GL_LINES";
+ break;
+ case PrimitiveMode::LinesAdjacency:
+ os << "GL_LINES_ADJACENCY";
+ break;
+ case PrimitiveMode::LineStrip:
+ os << "GL_LINE_STRIP";
+ break;
+ case PrimitiveMode::LineStripAdjacency:
+ os << "GL_LINE_STRIP_ADJANCENCY";
+ break;
+ case PrimitiveMode::Patches:
+ os << "GL_PATCHES";
+ break;
+ case PrimitiveMode::Points:
+ os << "GL_POINTS";
+ break;
+ case PrimitiveMode::TriangleFan:
+ os << "GL_TRIANGLE_FAN";
+ break;
+ case PrimitiveMode::Triangles:
+ os << "GL_TRIANGLES";
+ break;
+ case PrimitiveMode::TrianglesAdjacency:
+ os << "GL_TRIANGLES_ADJANCENCY";
+ break;
+ case PrimitiveMode::TriangleStrip:
+ os << "GL_TRIANGLE_STRIP";
+ break;
+ case PrimitiveMode::TriangleStripAdjacency:
+ os << "GL_TRIANGLE_STRIP_ADJACENCY";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+ return os;
+}
+
+std::ostream &operator<<(std::ostream &os, DrawElementsType value)
+{
+ switch (value)
+ {
+ case DrawElementsType::UnsignedByte:
+ os << "GL_UNSIGNED_BYTE";
+ break;
+ case DrawElementsType::UnsignedShort:
+ os << "GL_UNSIGNED_SHORT";
+ break;
+ case DrawElementsType::UnsignedInt:
+ os << "GL_UNSIGNED_INT";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+
+ return os;
+}
+
+std::ostream &operator<<(std::ostream &os, BlendEquationType value)
+{
+ switch (value)
+ {
+ case BlendEquationType::Add:
+ os << "GL_FUNC_ADD";
+ break;
+ case BlendEquationType::Min:
+ os << "GL_MIN";
+ break;
+ case BlendEquationType::Max:
+ os << "GL_MAX";
+ break;
+ case BlendEquationType::Subtract:
+ os << "GL_FUNC_SUBTRACT";
+ break;
+ case BlendEquationType::ReverseSubtract:
+ os << "GL_FUNC_REVERSE_SUBTRACT";
+ break;
+ case BlendEquationType::Multiply:
+ os << "GL_MULTIPLY_KHR";
+ break;
+ case BlendEquationType::Screen:
+ os << "GL_SCREEN_KHR";
+ break;
+ case BlendEquationType::Overlay:
+ os << "GL_OVERLAY_KHR";
+ break;
+ case BlendEquationType::Darken:
+ os << "GL_DARKEN_KHR";
+ break;
+ case BlendEquationType::Lighten:
+ os << "GL_LIGHTEN_KHR";
+ break;
+ case BlendEquationType::Colordodge:
+ os << "GL_COLORDODGE_KHR";
+ break;
+ case BlendEquationType::Colorburn:
+ os << "GL_COLORBURN_KHR";
+ break;
+ case BlendEquationType::Hardlight:
+ os << "GL_HARDLIGHT_KHR";
+ break;
+ case BlendEquationType::Softlight:
+ os << "GL_SOFTLIGHT_KHR";
+ break;
+ case BlendEquationType::Difference:
+ os << "GL_DIFFERENCE_KHR";
+ break;
+ case BlendEquationType::Exclusion:
+ os << "GL_EXCLUSION_KHR";
+ break;
+ case BlendEquationType::HslHue:
+ os << "GL_HSL_HUE_KHR";
+ break;
+ case BlendEquationType::HslSaturation:
+ os << "GL_HSL_SATURATION_KHR";
+ break;
+ case BlendEquationType::HslColor:
+ os << "GL_HSL_COLOR_KHR";
+ break;
+ case BlendEquationType::HslLuminosity:
+ os << "GL_HSL_LUMINOSITY_KHR";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+
+ return os;
+}
+
+std::ostream &operator<<(std::ostream &os, BlendFactorType value)
+{
+ switch (value)
+ {
+ case BlendFactorType::Zero:
+ os << "GL_ZERO";
+ break;
+ case BlendFactorType::One:
+ os << "GL_ONE";
+ break;
+ case BlendFactorType::SrcColor:
+ os << "GL_SRC_COLOR";
+ break;
+ case BlendFactorType::OneMinusSrcColor:
+ os << "GL_ONE_MINUS_SRC_COLOR";
+ break;
+ case BlendFactorType::SrcAlpha:
+ os << "GL_SRC_ALPHA";
+ break;
+ case BlendFactorType::OneMinusSrcAlpha:
+ os << "GL_ONE_MINUS_SRC_ALPHA";
+ break;
+ case BlendFactorType::DstAlpha:
+ os << "GL_DST_ALPHA";
+ break;
+ case BlendFactorType::OneMinusDstAlpha:
+ os << "GL_ONE_MINUS_DST_ALPHA";
+ break;
+ case BlendFactorType::DstColor:
+ os << "GL_DST_COLOR";
+ break;
+ case BlendFactorType::OneMinusDstColor:
+ os << "GL_ONE_MINUS_DST_COLOR";
+ break;
+ case BlendFactorType::SrcAlphaSaturate:
+ os << "GL_SRC_ALPHA_SATURATE";
+ break;
+ case BlendFactorType::ConstantColor:
+ os << "GL_CONSTANT_COLOR";
+ break;
+ case BlendFactorType::OneMinusConstantColor:
+ os << "GL_ONE_MINUS_CONSTANT_COLOR";
+ break;
+ case BlendFactorType::ConstantAlpha:
+ os << "GL_CONSTANT_ALPHA";
+ break;
+ case BlendFactorType::OneMinusConstantAlpha:
+ os << "GL_ONE_MINUS_CONSTANT_ALPHA";
+ break;
+ case BlendFactorType::Src1Alpha:
+ os << "GL_SRC1_ALPHA_EXT";
+ break;
+ case BlendFactorType::Src1Color:
+ os << "GL_SRC1_COLOR_EXT";
+ break;
+ case BlendFactorType::OneMinusSrc1Color:
+ os << "GL_ONE_MINUS_SRC1_COLOR_EXT";
+ break;
+ case BlendFactorType::OneMinusSrc1Alpha:
+ os << "GL_ONE_MINUS_SRC1_ALPHA_EXT";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+
+ return os;
+}
+
+std::ostream &operator<<(std::ostream &os, VertexAttribType value)
+{
+ switch (value)
+ {
+ case VertexAttribType::Byte:
+ os << "GL_BYTE";
+ break;
+ case VertexAttribType::Fixed:
+ os << "GL_FIXED";
+ break;
+ case VertexAttribType::Float:
+ os << "GL_FLOAT";
+ break;
+ case VertexAttribType::HalfFloat:
+ os << "GL_HALF_FLOAT";
+ break;
+ case VertexAttribType::HalfFloatOES:
+ os << "GL_HALF_FLOAT_OES";
+ break;
+ case VertexAttribType::Int:
+ os << "GL_INT";
+ break;
+ case VertexAttribType::Int2101010:
+ os << "GL_INT_2_10_10_10_REV";
+ break;
+ case VertexAttribType::Int1010102:
+ os << "GL_INT_10_10_10_2_OES";
+ break;
+ case VertexAttribType::Short:
+ os << "GL_SHORT";
+ break;
+ case VertexAttribType::UnsignedByte:
+ os << "GL_UNSIGNED_BYTE";
+ break;
+ case VertexAttribType::UnsignedInt:
+ os << "GL_UNSIGNED_INT";
+ break;
+ case VertexAttribType::UnsignedInt2101010:
+ os << "GL_UNSIGNED_INT_2_10_10_10_REV";
+ break;
+ case VertexAttribType::UnsignedInt1010102:
+ os << "GL_UNSIGNED_INT_10_10_10_2_OES";
+ break;
+ case VertexAttribType::UnsignedShort:
+ os << "GL_UNSIGNED_SHORT";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+ return os;
+}
+
+std::ostream &operator<<(std::ostream &os, TessEvaluationType value)
+{
+ switch (value)
+ {
+ case TessEvaluationType::Triangles:
+ os << "GL_TRIANGLES";
+ break;
+ case TessEvaluationType::Quads:
+ os << "GL_QUADS";
+ break;
+ case TessEvaluationType::Isolines:
+ os << "GL_ISOLINES";
+ break;
+ case TessEvaluationType::EqualSpacing:
+ os << "GL_EQUAL";
+ break;
+ case TessEvaluationType::FractionalEvenSpacing:
+ os << "GL_FRACTIONAL_EVEN";
+ break;
+ case TessEvaluationType::FractionalOddSpacing:
+ os << "GL_FRACTIONAL_ODD";
+ break;
+ case TessEvaluationType::Cw:
+ os << "GL_CW";
+ break;
+ case TessEvaluationType::Ccw:
+ os << "GL_CCW";
+ break;
+ case TessEvaluationType::PointMode:
+ os << "GL_TESS_GEN_POINT_MODE";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+ return os;
+}
+
+const char *ShaderTypeToString(ShaderType shaderType)
+{
+ constexpr ShaderMap<const char *> kShaderTypeNameMap = {
+ {ShaderType::Vertex, "Vertex"},
+ {ShaderType::TessControl, "Tessellation control"},
+ {ShaderType::TessEvaluation, "Tessellation evaluation"},
+ {ShaderType::Geometry, "Geometry"},
+ {ShaderType::Fragment, "Fragment"},
+ {ShaderType::Compute, "Compute"}};
+ return kShaderTypeNameMap[shaderType];
+}
+
+bool operator<(const UniformLocation &lhs, const UniformLocation &rhs)
+{
+ return lhs.value < rhs.value;
+}
+
+bool IsEmulatedCompressedFormat(GLenum format)
+{
+ // TODO(anglebug.com/6177): Check for all formats ANGLE will use to emulate a compressed texture
+ return format == GL_RGBA || format == GL_RG || format == GL_RED;
+}
+} // namespace gl
+
+namespace egl
+{
+MessageType ErrorCodeToMessageType(EGLint errorCode)
+{
+ switch (errorCode)
+ {
+ case EGL_BAD_ALLOC:
+ case EGL_CONTEXT_LOST:
+ case EGL_NOT_INITIALIZED:
+ return MessageType::Critical;
+
+ case EGL_BAD_ACCESS:
+ case EGL_BAD_ATTRIBUTE:
+ case EGL_BAD_CONFIG:
+ case EGL_BAD_CONTEXT:
+ case EGL_BAD_CURRENT_SURFACE:
+ case EGL_BAD_DISPLAY:
+ case EGL_BAD_MATCH:
+ case EGL_BAD_NATIVE_PIXMAP:
+ case EGL_BAD_NATIVE_WINDOW:
+ case EGL_BAD_PARAMETER:
+ case EGL_BAD_SURFACE:
+ case EGL_BAD_STREAM_KHR:
+ case EGL_BAD_STATE_KHR:
+ case EGL_BAD_DEVICE_EXT:
+ return MessageType::Error;
+
+ case EGL_SUCCESS:
+ default:
+ UNREACHABLE();
+ return MessageType::InvalidEnum;
+ }
+}
+} // namespace egl
+
+namespace egl_gl
+{
+
+gl::TextureTarget EGLCubeMapTargetToCubeMapTarget(EGLenum eglTarget)
+{
+ ASSERT(egl::IsCubeMapTextureTarget(eglTarget));
+ return gl::CubeFaceIndexToTextureTarget(egl::CubeMapTextureTargetToLayerIndex(eglTarget));
+}
+
+gl::TextureTarget EGLImageTargetToTextureTarget(EGLenum eglTarget)
+{
+ switch (eglTarget)
+ {
+ case EGL_GL_TEXTURE_2D_KHR:
+ return gl::TextureTarget::_2D;
+
+ case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
+ case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
+ case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
+ case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
+ case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
+ case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
+ return EGLCubeMapTargetToCubeMapTarget(eglTarget);
+
+ case EGL_GL_TEXTURE_3D_KHR:
+ return gl::TextureTarget::_3D;
+
+ default:
+ UNREACHABLE();
+ return gl::TextureTarget::InvalidEnum;
+ }
+}
+
+gl::TextureType EGLTextureTargetToTextureType(EGLenum eglTarget)
+{
+ switch (eglTarget)
+ {
+ case EGL_TEXTURE_2D:
+ return gl::TextureType::_2D;
+
+ case EGL_TEXTURE_RECTANGLE_ANGLE:
+ return gl::TextureType::Rectangle;
+
+ default:
+ UNREACHABLE();
+ return gl::TextureType::InvalidEnum;
+ }
+}
+} // namespace egl_gl
diff --git a/gfx/angle/checkout/src/common/PackedEnums.h b/gfx/angle/checkout/src/common/PackedEnums.h
new file mode 100644
index 0000000000..81fa6d6f42
--- /dev/null
+++ b/gfx/angle/checkout/src/common/PackedEnums.h
@@ -0,0 +1,859 @@
+// Copyright 2017 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.
+//
+// PackedGLEnums_autogen.h:
+// Declares ANGLE-specific enums classes for GLEnum and functions operating
+// on them.
+
+#ifndef COMMON_PACKEDGLENUMS_H_
+#define COMMON_PACKEDGLENUMS_H_
+
+#include "common/PackedEGLEnums_autogen.h"
+#include "common/PackedGLEnums_autogen.h"
+
+#include <array>
+#include <bitset>
+#include <cstddef>
+
+#include <EGL/egl.h>
+
+#include "common/bitset_utils.h"
+
+namespace angle
+{
+
+// Return the number of elements of a packed enum, including the InvalidEnum element.
+template <typename E>
+constexpr size_t EnumSize()
+{
+ using UnderlyingType = typename std::underlying_type<E>::type;
+ return static_cast<UnderlyingType>(E::EnumCount);
+}
+
+// Implementation of AllEnums which allows iterating over all the possible values for a packed enums
+// like so:
+// for (auto value : AllEnums<MyPackedEnum>()) {
+// // Do something with the enum.
+// }
+
+template <typename E>
+class EnumIterator final
+{
+ private:
+ using UnderlyingType = typename std::underlying_type<E>::type;
+
+ public:
+ EnumIterator(E value) : mValue(static_cast<UnderlyingType>(value)) {}
+ EnumIterator &operator++()
+ {
+ mValue++;
+ return *this;
+ }
+ bool operator==(const EnumIterator &other) const { return mValue == other.mValue; }
+ bool operator!=(const EnumIterator &other) const { return mValue != other.mValue; }
+ E operator*() const { return static_cast<E>(mValue); }
+
+ private:
+ UnderlyingType mValue;
+};
+
+template <typename E, size_t MaxSize = EnumSize<E>()>
+struct AllEnums
+{
+ EnumIterator<E> begin() const { return {static_cast<E>(0)}; }
+ EnumIterator<E> end() const { return {static_cast<E>(MaxSize)}; }
+};
+
+// PackedEnumMap<E, T> is like an std::array<T, E::EnumCount> but is indexed with enum values. It
+// implements all of the std::array interface except with enum values instead of indices.
+template <typename E, typename T, size_t MaxSize = EnumSize<E>()>
+class PackedEnumMap
+{
+ using UnderlyingType = typename std::underlying_type<E>::type;
+ using Storage = std::array<T, MaxSize>;
+
+ public:
+ using InitPair = std::pair<E, T>;
+
+ constexpr PackedEnumMap() = default;
+
+ constexpr PackedEnumMap(std::initializer_list<InitPair> init) : mPrivateData{}
+ {
+ // We use a for loop instead of range-for to work around a limitation in MSVC.
+ for (const InitPair *it = init.begin(); it != init.end(); ++it)
+ {
+ mPrivateData[static_cast<UnderlyingType>(it->first)] = it->second;
+ }
+ }
+
+ // types:
+ using value_type = T;
+ using pointer = T *;
+ using const_pointer = const T *;
+ using reference = T &;
+ using const_reference = const T &;
+
+ using size_type = size_t;
+ using difference_type = ptrdiff_t;
+
+ using iterator = typename Storage::iterator;
+ using const_iterator = typename Storage::const_iterator;
+ using reverse_iterator = std::reverse_iterator<iterator>;
+ using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+
+ // No explicit construct/copy/destroy for aggregate type
+ void fill(const T &u) { mPrivateData.fill(u); }
+ void swap(PackedEnumMap<E, T, MaxSize> &a) noexcept { mPrivateData.swap(a.mPrivateData); }
+
+ // iterators:
+ iterator begin() noexcept { return mPrivateData.begin(); }
+ const_iterator begin() const noexcept { return mPrivateData.begin(); }
+ iterator end() noexcept { return mPrivateData.end(); }
+ const_iterator end() const noexcept { return mPrivateData.end(); }
+
+ reverse_iterator rbegin() noexcept { return mPrivateData.rbegin(); }
+ const_reverse_iterator rbegin() const noexcept { return mPrivateData.rbegin(); }
+ reverse_iterator rend() noexcept { return mPrivateData.rend(); }
+ const_reverse_iterator rend() const noexcept { return mPrivateData.rend(); }
+
+ // capacity:
+ constexpr size_type size() const noexcept { return mPrivateData.size(); }
+ constexpr size_type max_size() const noexcept { return mPrivateData.max_size(); }
+ constexpr bool empty() const noexcept { return mPrivateData.empty(); }
+
+ // element access:
+ reference operator[](E n)
+ {
+ ASSERT(static_cast<size_t>(n) < mPrivateData.size());
+ return mPrivateData[static_cast<UnderlyingType>(n)];
+ }
+
+ constexpr const_reference operator[](E n) const
+ {
+ ASSERT(static_cast<size_t>(n) < mPrivateData.size());
+ return mPrivateData[static_cast<UnderlyingType>(n)];
+ }
+
+ const_reference at(E n) const { return mPrivateData.at(static_cast<UnderlyingType>(n)); }
+ reference at(E n) { return mPrivateData.at(static_cast<UnderlyingType>(n)); }
+
+ reference front() { return mPrivateData.front(); }
+ const_reference front() const { return mPrivateData.front(); }
+ reference back() { return mPrivateData.back(); }
+ const_reference back() const { return mPrivateData.back(); }
+
+ T *data() noexcept { return mPrivateData.data(); }
+ const T *data() const noexcept { return mPrivateData.data(); }
+
+ bool operator==(const PackedEnumMap &rhs) const { return mPrivateData == rhs.mPrivateData; }
+ bool operator!=(const PackedEnumMap &rhs) const { return mPrivateData != rhs.mPrivateData; }
+
+ template <typename SubT = T>
+ typename std::enable_if<std::is_integral<SubT>::value>::type operator+=(
+ const PackedEnumMap<E, SubT, MaxSize> &rhs)
+ {
+ for (E e : AllEnums<E, MaxSize>())
+ {
+ at(e) += rhs[e];
+ }
+ }
+
+ private:
+ Storage mPrivateData;
+};
+
+// PackedEnumBitSetE> is like an std::bitset<E::EnumCount> but is indexed with enum values. It
+// implements the std::bitset interface except with enum values instead of indices.
+template <typename E, typename DataT = uint32_t>
+using PackedEnumBitSet = BitSetT<EnumSize<E>(), DataT, E>;
+
+} // namespace angle
+
+namespace gl
+{
+
+TextureType TextureTargetToType(TextureTarget target);
+TextureTarget NonCubeTextureTypeToTarget(TextureType type);
+
+TextureTarget CubeFaceIndexToTextureTarget(size_t face);
+size_t CubeMapTextureTargetToFaceIndex(TextureTarget target);
+bool IsCubeMapFaceTarget(TextureTarget target);
+
+constexpr TextureTarget kCubeMapTextureTargetMin = TextureTarget::CubeMapPositiveX;
+constexpr TextureTarget kCubeMapTextureTargetMax = TextureTarget::CubeMapNegativeZ;
+constexpr TextureTarget kAfterCubeMapTextureTargetMax =
+ static_cast<TextureTarget>(static_cast<uint8_t>(kCubeMapTextureTargetMax) + 1);
+struct AllCubeFaceTextureTargets
+{
+ angle::EnumIterator<TextureTarget> begin() const { return kCubeMapTextureTargetMin; }
+ angle::EnumIterator<TextureTarget> end() const { return kAfterCubeMapTextureTargetMax; }
+};
+
+constexpr std::array<ShaderType, 2> kAllGLES2ShaderTypes = {ShaderType::Vertex,
+ ShaderType::Fragment};
+
+constexpr ShaderType kShaderTypeMin = ShaderType::Vertex;
+constexpr ShaderType kShaderTypeMax = ShaderType::Compute;
+constexpr ShaderType kAfterShaderTypeMax =
+ static_cast<ShaderType>(static_cast<uint8_t>(kShaderTypeMax) + 1);
+struct AllShaderTypes
+{
+ angle::EnumIterator<ShaderType> begin() const { return kShaderTypeMin; }
+ angle::EnumIterator<ShaderType> end() const { return kAfterShaderTypeMax; }
+};
+
+constexpr size_t kGraphicsShaderCount = static_cast<size_t>(ShaderType::EnumCount) - 1u;
+// Arrange the shader types in the order of rendering pipeline
+constexpr std::array<ShaderType, kGraphicsShaderCount> kAllGraphicsShaderTypes = {
+ ShaderType::Vertex, ShaderType::TessControl, ShaderType::TessEvaluation, ShaderType::Geometry,
+ ShaderType::Fragment};
+
+using ShaderBitSet = angle::PackedEnumBitSet<ShaderType, uint8_t>;
+static_assert(sizeof(ShaderBitSet) == sizeof(uint8_t), "Unexpected size");
+
+template <typename T>
+using ShaderMap = angle::PackedEnumMap<ShaderType, T>;
+
+const char *ShaderTypeToString(ShaderType shaderType);
+
+TextureType SamplerTypeToTextureType(GLenum samplerType);
+TextureType ImageTypeToTextureType(GLenum imageType);
+
+bool IsMultisampled(gl::TextureType type);
+bool IsArrayTextureType(gl::TextureType type);
+
+bool IsStaticBufferUsage(BufferUsage useage);
+
+enum class PrimitiveMode : uint8_t
+{
+ Points = 0x0,
+ Lines = 0x1,
+ LineLoop = 0x2,
+ LineStrip = 0x3,
+ Triangles = 0x4,
+ TriangleStrip = 0x5,
+ TriangleFan = 0x6,
+ Unused1 = 0x7,
+ Unused2 = 0x8,
+ Unused3 = 0x9,
+ LinesAdjacency = 0xA,
+ LineStripAdjacency = 0xB,
+ TrianglesAdjacency = 0xC,
+ TriangleStripAdjacency = 0xD,
+ Patches = 0xE,
+
+ InvalidEnum = 0xF,
+ EnumCount = 0xF,
+};
+
+template <>
+constexpr PrimitiveMode FromGLenum<PrimitiveMode>(GLenum from)
+{
+ if (from >= static_cast<GLenum>(PrimitiveMode::EnumCount))
+ {
+ return PrimitiveMode::InvalidEnum;
+ }
+
+ return static_cast<PrimitiveMode>(from);
+}
+
+constexpr GLenum ToGLenum(PrimitiveMode from)
+{
+ return static_cast<GLenum>(from);
+}
+
+static_assert(ToGLenum(PrimitiveMode::Points) == GL_POINTS, "PrimitiveMode violation");
+static_assert(ToGLenum(PrimitiveMode::Lines) == GL_LINES, "PrimitiveMode violation");
+static_assert(ToGLenum(PrimitiveMode::LineLoop) == GL_LINE_LOOP, "PrimitiveMode violation");
+static_assert(ToGLenum(PrimitiveMode::LineStrip) == GL_LINE_STRIP, "PrimitiveMode violation");
+static_assert(ToGLenum(PrimitiveMode::Triangles) == GL_TRIANGLES, "PrimitiveMode violation");
+static_assert(ToGLenum(PrimitiveMode::TriangleStrip) == GL_TRIANGLE_STRIP,
+ "PrimitiveMode violation");
+static_assert(ToGLenum(PrimitiveMode::TriangleFan) == GL_TRIANGLE_FAN, "PrimitiveMode violation");
+static_assert(ToGLenum(PrimitiveMode::LinesAdjacency) == GL_LINES_ADJACENCY,
+ "PrimitiveMode violation");
+static_assert(ToGLenum(PrimitiveMode::LineStripAdjacency) == GL_LINE_STRIP_ADJACENCY,
+ "PrimitiveMode violation");
+static_assert(ToGLenum(PrimitiveMode::TrianglesAdjacency) == GL_TRIANGLES_ADJACENCY,
+ "PrimitiveMode violation");
+static_assert(ToGLenum(PrimitiveMode::TriangleStripAdjacency) == GL_TRIANGLE_STRIP_ADJACENCY,
+ "PrimitiveMode violation");
+
+std::ostream &operator<<(std::ostream &os, PrimitiveMode value);
+
+enum class DrawElementsType : size_t
+{
+ UnsignedByte = 0,
+ UnsignedShort = 1,
+ UnsignedInt = 2,
+ InvalidEnum = 3,
+ EnumCount = 3,
+};
+
+template <>
+constexpr DrawElementsType FromGLenum<DrawElementsType>(GLenum from)
+{
+
+ GLenum scaled = (from - GL_UNSIGNED_BYTE);
+ // This code sequence generates a ROR instruction on x86/arm. We want to check if the lowest bit
+ // of scaled is set and if (scaled >> 1) is greater than a non-pot value. If we rotate the
+ // lowest bit to the hightest bit both conditions can be checked with a single test.
+ static_assert(sizeof(GLenum) == 4, "Update (scaled << 31) to sizeof(GLenum) * 8 - 1");
+ GLenum packed = (scaled >> 1) | (scaled << 31);
+
+ // operator ? with a simple assignment usually translates to a cmov instruction and thus avoids
+ // a branch.
+ packed = (packed >= static_cast<GLenum>(DrawElementsType::EnumCount))
+ ? static_cast<GLenum>(DrawElementsType::InvalidEnum)
+ : packed;
+
+ return static_cast<DrawElementsType>(packed);
+}
+
+constexpr GLenum ToGLenum(DrawElementsType from)
+{
+ return ((static_cast<GLenum>(from) << 1) + GL_UNSIGNED_BYTE);
+}
+
+#define ANGLE_VALIDATE_PACKED_ENUM(type, packed, glenum) \
+ static_assert(ToGLenum(type::packed) == glenum, #type " violation"); \
+ static_assert(FromGLenum<type>(glenum) == type::packed, #type " violation")
+
+ANGLE_VALIDATE_PACKED_ENUM(DrawElementsType, UnsignedByte, GL_UNSIGNED_BYTE);
+ANGLE_VALIDATE_PACKED_ENUM(DrawElementsType, UnsignedShort, GL_UNSIGNED_SHORT);
+ANGLE_VALIDATE_PACKED_ENUM(DrawElementsType, UnsignedInt, GL_UNSIGNED_INT);
+
+std::ostream &operator<<(std::ostream &os, DrawElementsType value);
+
+enum class BlendEquationType
+{
+ Add = 0, // GLenum == 0x8006
+ Min = 1, // GLenum == 0x8007
+ Max = 2, // GLenum == 0x8008
+ Unused = 3,
+ Subtract = 4, // GLenum == 0x800A
+ ReverseSubtract = 5, // GLenum == 0x800B
+
+ Multiply = 6, // GLenum == 0x9294
+ Screen = 7, // GLenum == 0x9295
+ Overlay = 8, // GLenum == 0x9296
+ Darken = 9, // GLenum == 0x9297
+ Lighten = 10, // GLenum == 0x9298
+ Colordodge = 11, // GLenum == 0x9299
+ Colorburn = 12, // GLenum == 0x929A
+ Hardlight = 13, // GLenum == 0x929B
+ Softlight = 14, // GLenum == 0x929C
+ Unused2 = 15,
+ Difference = 16, // GLenum == 0x929E
+ Unused3 = 17,
+ Exclusion = 18, // GLenum == 0x92A0
+
+ HslHue = 19, // GLenum == 0x92AD
+ HslSaturation = 20, // GLenum == 0x92AE
+ HslColor = 21, // GLenum == 0x92AF
+ HslLuminosity = 22, // GLenum == 0x92B0
+
+ InvalidEnum = 23,
+ EnumCount = InvalidEnum
+};
+
+using BlendEquationBitSet = angle::PackedEnumBitSet<gl::BlendEquationType>;
+
+template <>
+constexpr BlendEquationType FromGLenum<BlendEquationType>(GLenum from)
+{
+ if (from <= GL_FUNC_REVERSE_SUBTRACT)
+ {
+ const GLenum scaled = (from - GL_FUNC_ADD);
+ return (scaled == static_cast<GLenum>(BlendEquationType::Unused))
+ ? BlendEquationType::InvalidEnum
+ : static_cast<BlendEquationType>(scaled);
+ }
+ if (from <= GL_EXCLUSION_KHR)
+ {
+ const GLenum scaled =
+ (from - GL_MULTIPLY_KHR + static_cast<uint32_t>(BlendEquationType::Multiply));
+ return (scaled == static_cast<GLenum>(BlendEquationType::Unused2) ||
+ scaled == static_cast<GLenum>(BlendEquationType::Unused3))
+ ? BlendEquationType::InvalidEnum
+ : static_cast<BlendEquationType>(scaled);
+ }
+ if (from <= GL_HSL_LUMINOSITY_KHR)
+ {
+ return static_cast<BlendEquationType>(from - GL_HSL_HUE_KHR +
+ static_cast<uint32_t>(BlendEquationType::HslHue));
+ }
+ return BlendEquationType::InvalidEnum;
+}
+
+constexpr GLenum ToGLenum(BlendEquationType from)
+{
+ if (from <= BlendEquationType::ReverseSubtract)
+ {
+ return static_cast<GLenum>(from) + GL_FUNC_ADD;
+ }
+ if (from <= BlendEquationType::Exclusion)
+ {
+ return static_cast<GLenum>(from) - static_cast<GLenum>(BlendEquationType::Multiply) +
+ GL_MULTIPLY_KHR;
+ }
+ return static_cast<GLenum>(from) - static_cast<GLenum>(BlendEquationType::HslHue) +
+ GL_HSL_HUE_KHR;
+}
+
+ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Add, GL_FUNC_ADD);
+ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Min, GL_MIN);
+ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Max, GL_MAX);
+ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Subtract, GL_FUNC_SUBTRACT);
+ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, ReverseSubtract, GL_FUNC_REVERSE_SUBTRACT);
+ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Multiply, GL_MULTIPLY_KHR);
+ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Screen, GL_SCREEN_KHR);
+ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Overlay, GL_OVERLAY_KHR);
+ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Darken, GL_DARKEN_KHR);
+ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Lighten, GL_LIGHTEN_KHR);
+ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Colordodge, GL_COLORDODGE_KHR);
+ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Colorburn, GL_COLORBURN_KHR);
+ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Hardlight, GL_HARDLIGHT_KHR);
+ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Softlight, GL_SOFTLIGHT_KHR);
+ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Difference, GL_DIFFERENCE_KHR);
+ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, Exclusion, GL_EXCLUSION_KHR);
+ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, HslHue, GL_HSL_HUE_KHR);
+ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, HslSaturation, GL_HSL_SATURATION_KHR);
+ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, HslColor, GL_HSL_COLOR_KHR);
+ANGLE_VALIDATE_PACKED_ENUM(BlendEquationType, HslLuminosity, GL_HSL_LUMINOSITY_KHR);
+
+std::ostream &operator<<(std::ostream &os, BlendEquationType value);
+
+enum class BlendFactorType
+{
+ Zero = 0, // GLenum == 0
+ One = 1, // GLenum == 1
+
+ MinSrcDstType = 2,
+ SrcColor = 2, // GLenum == 0x0300
+ OneMinusSrcColor = 3, // GLenum == 0x0301
+ SrcAlpha = 4, // GLenum == 0x0302
+ OneMinusSrcAlpha = 5, // GLenum == 0x0303
+ DstAlpha = 6, // GLenum == 0x0304
+ OneMinusDstAlpha = 7, // GLenum == 0x0305
+ DstColor = 8, // GLenum == 0x0306
+ OneMinusDstColor = 9, // GLenum == 0x0307
+ SrcAlphaSaturate = 10, // GLenum == 0x0308
+ MaxSrcDstType = 10,
+
+ MinConstantType = 11,
+ ConstantColor = 11, // GLenum == 0x8001
+ OneMinusConstantColor = 12, // GLenum == 0x8002
+ ConstantAlpha = 13, // GLenum == 0x8003
+ OneMinusConstantAlpha = 14, // GLenum == 0x8004
+ MaxConstantType = 14,
+
+ // GL_EXT_blend_func_extended
+
+ Src1Alpha = 15, // GLenum == 0x8589
+
+ Src1Color = 16, // GLenum == 0x88F9
+ OneMinusSrc1Color = 17, // GLenum == 0x88FA
+ OneMinusSrc1Alpha = 18, // GLenum == 0x88FB
+
+ InvalidEnum = 19,
+ EnumCount = 19
+};
+
+template <>
+constexpr BlendFactorType FromGLenum<BlendFactorType>(GLenum from)
+{
+ if (from <= 1)
+ return static_cast<BlendFactorType>(from);
+ if (from >= GL_SRC_COLOR && from <= GL_SRC_ALPHA_SATURATE)
+ return static_cast<BlendFactorType>(from - GL_SRC_COLOR + 2);
+ if (from >= GL_CONSTANT_COLOR && from <= GL_ONE_MINUS_CONSTANT_ALPHA)
+ return static_cast<BlendFactorType>(from - GL_CONSTANT_COLOR + 11);
+ if (from == GL_SRC1_ALPHA_EXT)
+ return BlendFactorType::Src1Alpha;
+ if (from >= GL_SRC1_COLOR_EXT && from <= GL_ONE_MINUS_SRC1_ALPHA_EXT)
+ return static_cast<BlendFactorType>(from - GL_SRC1_COLOR_EXT + 16);
+ return BlendFactorType::InvalidEnum;
+}
+
+constexpr GLenum ToGLenum(BlendFactorType from)
+{
+ const GLenum value = static_cast<GLenum>(from);
+ if (value <= 1)
+ return value;
+ if (from >= BlendFactorType::MinSrcDstType && from <= BlendFactorType::MaxSrcDstType)
+ return value - 2 + GL_SRC_COLOR;
+ if (from >= BlendFactorType::MinConstantType && from <= BlendFactorType::MaxConstantType)
+ return value - 11 + GL_CONSTANT_COLOR;
+ if (from == BlendFactorType::Src1Alpha)
+ return GL_SRC1_ALPHA_EXT;
+ return value - 16 + GL_SRC1_COLOR_EXT;
+}
+
+ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, Zero, GL_ZERO);
+ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, One, GL_ONE);
+ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, SrcColor, GL_SRC_COLOR);
+ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, OneMinusSrcColor, GL_ONE_MINUS_SRC_COLOR);
+ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, SrcAlpha, GL_SRC_ALPHA);
+ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, OneMinusSrcAlpha, GL_ONE_MINUS_SRC_ALPHA);
+ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, DstAlpha, GL_DST_ALPHA);
+ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, OneMinusDstAlpha, GL_ONE_MINUS_DST_ALPHA);
+ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, DstColor, GL_DST_COLOR);
+ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, OneMinusDstColor, GL_ONE_MINUS_DST_COLOR);
+ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, SrcAlphaSaturate, GL_SRC_ALPHA_SATURATE);
+ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, ConstantColor, GL_CONSTANT_COLOR);
+ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, OneMinusConstantColor, GL_ONE_MINUS_CONSTANT_COLOR);
+ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, ConstantAlpha, GL_CONSTANT_ALPHA);
+ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, OneMinusConstantAlpha, GL_ONE_MINUS_CONSTANT_ALPHA);
+ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, Src1Alpha, GL_SRC1_ALPHA_EXT);
+ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, Src1Color, GL_SRC1_COLOR_EXT);
+ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, OneMinusSrc1Color, GL_ONE_MINUS_SRC1_COLOR_EXT);
+ANGLE_VALIDATE_PACKED_ENUM(BlendFactorType, OneMinusSrc1Alpha, GL_ONE_MINUS_SRC1_ALPHA_EXT);
+
+std::ostream &operator<<(std::ostream &os, BlendFactorType value);
+
+enum class VertexAttribType
+{
+ Byte = 0, // GLenum == 0x1400
+ UnsignedByte = 1, // GLenum == 0x1401
+ Short = 2, // GLenum == 0x1402
+ UnsignedShort = 3, // GLenum == 0x1403
+ Int = 4, // GLenum == 0x1404
+ UnsignedInt = 5, // GLenum == 0x1405
+ Float = 6, // GLenum == 0x1406
+ Unused1 = 7, // GLenum == 0x1407
+ Unused2 = 8, // GLenum == 0x1408
+ Unused3 = 9, // GLenum == 0x1409
+ Unused4 = 10, // GLenum == 0x140A
+ HalfFloat = 11, // GLenum == 0x140B
+ Fixed = 12, // GLenum == 0x140C
+ MaxBasicType = 12,
+ UnsignedInt2101010 = 13, // GLenum == 0x8368
+ HalfFloatOES = 14, // GLenum == 0x8D61
+ Int2101010 = 15, // GLenum == 0x8D9F
+ UnsignedInt1010102 = 16, // GLenum == 0x8DF6
+ Int1010102 = 17, // GLenum == 0x8DF7
+ InvalidEnum = 18,
+ EnumCount = 18,
+};
+
+template <>
+constexpr VertexAttribType FromGLenum<VertexAttribType>(GLenum from)
+{
+ GLenum packed = from - GL_BYTE;
+ if (packed <= static_cast<GLenum>(VertexAttribType::MaxBasicType))
+ return static_cast<VertexAttribType>(packed);
+ if (from == GL_UNSIGNED_INT_2_10_10_10_REV)
+ return VertexAttribType::UnsignedInt2101010;
+ if (from == GL_HALF_FLOAT_OES)
+ return VertexAttribType::HalfFloatOES;
+ if (from == GL_INT_2_10_10_10_REV)
+ return VertexAttribType::Int2101010;
+ if (from == GL_UNSIGNED_INT_10_10_10_2_OES)
+ return VertexAttribType::UnsignedInt1010102;
+ if (from == GL_INT_10_10_10_2_OES)
+ return VertexAttribType::Int1010102;
+ return VertexAttribType::InvalidEnum;
+}
+
+constexpr GLenum ToGLenum(VertexAttribType from)
+{
+ // This could be optimized using a constexpr table.
+ if (from == VertexAttribType::Int2101010)
+ return GL_INT_2_10_10_10_REV;
+ if (from == VertexAttribType::HalfFloatOES)
+ return GL_HALF_FLOAT_OES;
+ if (from == VertexAttribType::UnsignedInt2101010)
+ return GL_UNSIGNED_INT_2_10_10_10_REV;
+ if (from == VertexAttribType::UnsignedInt1010102)
+ return GL_UNSIGNED_INT_10_10_10_2_OES;
+ if (from == VertexAttribType::Int1010102)
+ return GL_INT_10_10_10_2_OES;
+ return static_cast<GLenum>(from) + GL_BYTE;
+}
+
+ANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, Byte, GL_BYTE);
+ANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, UnsignedByte, GL_UNSIGNED_BYTE);
+ANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, Short, GL_SHORT);
+ANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, UnsignedShort, GL_UNSIGNED_SHORT);
+ANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, Int, GL_INT);
+ANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, UnsignedInt, GL_UNSIGNED_INT);
+ANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, Float, GL_FLOAT);
+ANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, HalfFloat, GL_HALF_FLOAT);
+ANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, Fixed, GL_FIXED);
+ANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, Int2101010, GL_INT_2_10_10_10_REV);
+ANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, HalfFloatOES, GL_HALF_FLOAT_OES);
+ANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, UnsignedInt2101010, GL_UNSIGNED_INT_2_10_10_10_REV);
+ANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, Int1010102, GL_INT_10_10_10_2_OES);
+ANGLE_VALIDATE_PACKED_ENUM(VertexAttribType, UnsignedInt1010102, GL_UNSIGNED_INT_10_10_10_2_OES);
+
+std::ostream &operator<<(std::ostream &os, VertexAttribType value);
+
+enum class TessEvaluationType
+{
+ Triangles = 0,
+ Quads = 1,
+ Isolines = 2,
+ EqualSpacing = 3,
+ FractionalEvenSpacing = 4,
+ FractionalOddSpacing = 5,
+ Cw = 6,
+ Ccw = 7,
+ PointMode = 8,
+ InvalidEnum = 9,
+ EnumCount = 9
+};
+
+template <>
+constexpr TessEvaluationType FromGLenum<TessEvaluationType>(GLenum from)
+{
+ if (from == GL_TRIANGLES)
+ return TessEvaluationType::Triangles;
+ if (from == GL_QUADS)
+ return TessEvaluationType::Quads;
+ if (from == GL_ISOLINES)
+ return TessEvaluationType::Isolines;
+ if (from == GL_EQUAL)
+ return TessEvaluationType::EqualSpacing;
+ if (from == GL_FRACTIONAL_EVEN)
+ return TessEvaluationType::FractionalEvenSpacing;
+ if (from == GL_FRACTIONAL_ODD)
+ return TessEvaluationType::FractionalOddSpacing;
+ if (from == GL_CW)
+ return TessEvaluationType::Cw;
+ if (from == GL_CCW)
+ return TessEvaluationType::Ccw;
+ if (from == GL_TESS_GEN_POINT_MODE)
+ return TessEvaluationType::PointMode;
+ return TessEvaluationType::InvalidEnum;
+}
+
+constexpr GLenum ToGLenum(TessEvaluationType from)
+{
+ switch (from)
+ {
+ case TessEvaluationType::Triangles:
+ return GL_TRIANGLES;
+ case TessEvaluationType::Quads:
+ return GL_QUADS;
+ case TessEvaluationType::Isolines:
+ return GL_ISOLINES;
+ case TessEvaluationType::EqualSpacing:
+ return GL_EQUAL;
+ case TessEvaluationType::FractionalEvenSpacing:
+ return GL_FRACTIONAL_EVEN;
+ case TessEvaluationType::FractionalOddSpacing:
+ return GL_FRACTIONAL_ODD;
+ case TessEvaluationType::Cw:
+ return GL_CW;
+ case TessEvaluationType::Ccw:
+ return GL_CCW;
+ case TessEvaluationType::PointMode:
+ return GL_TESS_GEN_POINT_MODE;
+ default:
+ return GL_INVALID_ENUM;
+ }
+}
+
+ANGLE_VALIDATE_PACKED_ENUM(TessEvaluationType, Triangles, GL_TRIANGLES);
+ANGLE_VALIDATE_PACKED_ENUM(TessEvaluationType, Quads, GL_QUADS);
+ANGLE_VALIDATE_PACKED_ENUM(TessEvaluationType, Isolines, GL_ISOLINES);
+ANGLE_VALIDATE_PACKED_ENUM(TessEvaluationType, EqualSpacing, GL_EQUAL);
+ANGLE_VALIDATE_PACKED_ENUM(TessEvaluationType, FractionalEvenSpacing, GL_FRACTIONAL_EVEN);
+ANGLE_VALIDATE_PACKED_ENUM(TessEvaluationType, FractionalOddSpacing, GL_FRACTIONAL_ODD);
+ANGLE_VALIDATE_PACKED_ENUM(TessEvaluationType, Cw, GL_CW);
+ANGLE_VALIDATE_PACKED_ENUM(TessEvaluationType, Ccw, GL_CCW);
+ANGLE_VALIDATE_PACKED_ENUM(TessEvaluationType, PointMode, GL_TESS_GEN_POINT_MODE);
+
+std::ostream &operator<<(std::ostream &os, TessEvaluationType value);
+
+// Typesafe object handles.
+
+template <typename T>
+struct ResourceTypeToID;
+
+template <typename T>
+struct IsResourceIDType;
+
+// Clang Format doesn't like the following X macro.
+// clang-format off
+#define ANGLE_ID_TYPES_OP(X) \
+ X(Buffer) \
+ X(FenceNV) \
+ X(Framebuffer) \
+ X(MemoryObject) \
+ X(Path) \
+ X(ProgramPipeline) \
+ X(Query) \
+ X(Renderbuffer) \
+ X(Sampler) \
+ X(Semaphore) \
+ X(Texture) \
+ X(TransformFeedback) \
+ X(VertexArray)
+// clang-format on
+
+#define ANGLE_DEFINE_ID_TYPE(Type) \
+ class Type; \
+ struct Type##ID \
+ { \
+ GLuint value; \
+ }; \
+ template <> \
+ struct ResourceTypeToID<Type> \
+ { \
+ using IDType = Type##ID; \
+ }; \
+ template <> \
+ struct IsResourceIDType<Type##ID> \
+ { \
+ static constexpr bool value = true; \
+ };
+
+ANGLE_ID_TYPES_OP(ANGLE_DEFINE_ID_TYPE)
+
+#undef ANGLE_DEFINE_ID_TYPE
+#undef ANGLE_ID_TYPES_OP
+
+// Shaders and programs are a bit special as they share IDs.
+struct ShaderProgramID
+{
+ GLuint value;
+};
+
+template <>
+struct IsResourceIDType<ShaderProgramID>
+{
+ constexpr static bool value = true;
+};
+
+class Shader;
+template <>
+struct ResourceTypeToID<Shader>
+{
+ using IDType = ShaderProgramID;
+};
+
+class Program;
+template <>
+struct ResourceTypeToID<Program>
+{
+ using IDType = ShaderProgramID;
+};
+
+template <typename T>
+struct ResourceTypeToID
+{
+ using IDType = void;
+};
+
+template <typename T>
+struct IsResourceIDType
+{
+ static constexpr bool value = false;
+};
+
+template <typename T>
+bool ValueEquals(T lhs, T rhs)
+{
+ return lhs.value == rhs.value;
+}
+
+// Util funcs for resourceIDs
+template <typename T>
+typename std::enable_if<IsResourceIDType<T>::value, bool>::type operator==(const T &lhs,
+ const T &rhs)
+{
+ return lhs.value == rhs.value;
+}
+
+template <typename T>
+typename std::enable_if<IsResourceIDType<T>::value, bool>::type operator!=(const T &lhs,
+ const T &rhs)
+{
+ return lhs.value != rhs.value;
+}
+
+template <typename T>
+typename std::enable_if<IsResourceIDType<T>::value, bool>::type operator<(const T &lhs,
+ const T &rhs)
+{
+ return lhs.value < rhs.value;
+}
+
+// Used to unbox typed values.
+template <typename ResourceIDType>
+GLuint GetIDValue(ResourceIDType id);
+
+template <>
+inline GLuint GetIDValue(GLuint id)
+{
+ return id;
+}
+
+template <typename ResourceIDType>
+inline GLuint GetIDValue(ResourceIDType id)
+{
+ return id.value;
+}
+
+// First case: handling packed enums.
+template <typename EnumT, typename FromT>
+typename std::enable_if<std::is_enum<EnumT>::value, EnumT>::type PackParam(FromT from)
+{
+ return FromGLenum<EnumT>(from);
+}
+
+// Second case: handling non-pointer resource ids.
+template <typename EnumT, typename FromT>
+typename std::enable_if<!std::is_pointer<FromT>::value && !std::is_enum<EnumT>::value, EnumT>::type
+PackParam(FromT from)
+{
+ return {from};
+}
+
+// Third case: handling pointer resource ids.
+template <typename EnumT, typename FromT>
+typename std::enable_if<std::is_pointer<FromT>::value && !std::is_enum<EnumT>::value, EnumT>::type
+PackParam(FromT from)
+{
+ static_assert(sizeof(typename std::remove_pointer<EnumT>::type) ==
+ sizeof(typename std::remove_pointer<FromT>::type),
+ "Types have different sizes");
+ static_assert(
+ std::is_same<
+ decltype(std::remove_pointer<EnumT>::type::value),
+ typename std::remove_const<typename std::remove_pointer<FromT>::type>::type>::value,
+ "Data types are different");
+ return reinterpret_cast<EnumT>(from);
+}
+
+struct UniformLocation
+{
+ int value;
+};
+
+bool operator<(const UniformLocation &lhs, const UniformLocation &rhs);
+
+struct UniformBlockIndex
+{
+ uint32_t value;
+};
+
+bool IsEmulatedCompressedFormat(GLenum format);
+} // namespace gl
+
+namespace egl
+{
+MessageType ErrorCodeToMessageType(EGLint errorCode);
+} // namespace egl
+
+namespace egl_gl
+{
+gl::TextureTarget EGLCubeMapTargetToCubeMapTarget(EGLenum eglTarget);
+gl::TextureTarget EGLImageTargetToTextureTarget(EGLenum eglTarget);
+gl::TextureType EGLTextureTargetToTextureType(EGLenum eglTarget);
+} // namespace egl_gl
+
+#endif // COMMON_PACKEDGLENUMS_H_
diff --git a/gfx/angle/checkout/src/common/PackedGLEnums_autogen.cpp b/gfx/angle/checkout/src/common/PackedGLEnums_autogen.cpp
new file mode 100644
index 0000000000..d025b11a14
--- /dev/null
+++ b/gfx/angle/checkout/src/common/PackedGLEnums_autogen.cpp
@@ -0,0 +1,2449 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_packed_gl_enums.py using data from packed_gl_enums.json.
+//
+// Copyright 2017 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.
+//
+// PackedGLEnums_autogen.cpp:
+// Implements ANGLE-specific enums classes for GLenums and functions operating
+// on them.
+
+#include "common/PackedGLEnums_autogen.h"
+#include "common/debug.h"
+
+namespace gl
+{
+
+template <>
+AlphaTestFunc FromGLenum<AlphaTestFunc>(GLenum from)
+{
+ switch (from)
+ {
+ case GL_ALWAYS:
+ return AlphaTestFunc::AlwaysPass;
+ case GL_EQUAL:
+ return AlphaTestFunc::Equal;
+ case GL_GEQUAL:
+ return AlphaTestFunc::Gequal;
+ case GL_GREATER:
+ return AlphaTestFunc::Greater;
+ case GL_LEQUAL:
+ return AlphaTestFunc::Lequal;
+ case GL_LESS:
+ return AlphaTestFunc::Less;
+ case GL_NEVER:
+ return AlphaTestFunc::Never;
+ case GL_NOTEQUAL:
+ return AlphaTestFunc::NotEqual;
+ default:
+ return AlphaTestFunc::InvalidEnum;
+ }
+}
+
+GLenum ToGLenum(AlphaTestFunc from)
+{
+ switch (from)
+ {
+ case AlphaTestFunc::AlwaysPass:
+ return GL_ALWAYS;
+ case AlphaTestFunc::Equal:
+ return GL_EQUAL;
+ case AlphaTestFunc::Gequal:
+ return GL_GEQUAL;
+ case AlphaTestFunc::Greater:
+ return GL_GREATER;
+ case AlphaTestFunc::Lequal:
+ return GL_LEQUAL;
+ case AlphaTestFunc::Less:
+ return GL_LESS;
+ case AlphaTestFunc::Never:
+ return GL_NEVER;
+ case AlphaTestFunc::NotEqual:
+ return GL_NOTEQUAL;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+std::ostream &operator<<(std::ostream &os, AlphaTestFunc value)
+{
+ switch (value)
+ {
+ case AlphaTestFunc::AlwaysPass:
+ os << "GL_ALWAYS";
+ break;
+ case AlphaTestFunc::Equal:
+ os << "GL_EQUAL";
+ break;
+ case AlphaTestFunc::Gequal:
+ os << "GL_GEQUAL";
+ break;
+ case AlphaTestFunc::Greater:
+ os << "GL_GREATER";
+ break;
+ case AlphaTestFunc::Lequal:
+ os << "GL_LEQUAL";
+ break;
+ case AlphaTestFunc::Less:
+ os << "GL_LESS";
+ break;
+ case AlphaTestFunc::Never:
+ os << "GL_NEVER";
+ break;
+ case AlphaTestFunc::NotEqual:
+ os << "GL_NOTEQUAL";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+ return os;
+}
+
+template <>
+BufferBinding FromGLenum<BufferBinding>(GLenum from)
+{
+ switch (from)
+ {
+ case GL_ARRAY_BUFFER:
+ return BufferBinding::Array;
+ case GL_ATOMIC_COUNTER_BUFFER:
+ return BufferBinding::AtomicCounter;
+ case GL_COPY_READ_BUFFER:
+ return BufferBinding::CopyRead;
+ case GL_COPY_WRITE_BUFFER:
+ return BufferBinding::CopyWrite;
+ case GL_DISPATCH_INDIRECT_BUFFER:
+ return BufferBinding::DispatchIndirect;
+ case GL_DRAW_INDIRECT_BUFFER:
+ return BufferBinding::DrawIndirect;
+ case GL_ELEMENT_ARRAY_BUFFER:
+ return BufferBinding::ElementArray;
+ case GL_PIXEL_PACK_BUFFER:
+ return BufferBinding::PixelPack;
+ case GL_PIXEL_UNPACK_BUFFER:
+ return BufferBinding::PixelUnpack;
+ case GL_SHADER_STORAGE_BUFFER:
+ return BufferBinding::ShaderStorage;
+ case GL_TEXTURE_BUFFER:
+ return BufferBinding::Texture;
+ case GL_TRANSFORM_FEEDBACK_BUFFER:
+ return BufferBinding::TransformFeedback;
+ case GL_UNIFORM_BUFFER:
+ return BufferBinding::Uniform;
+ default:
+ return BufferBinding::InvalidEnum;
+ }
+}
+
+GLenum ToGLenum(BufferBinding from)
+{
+ switch (from)
+ {
+ case BufferBinding::Array:
+ return GL_ARRAY_BUFFER;
+ case BufferBinding::AtomicCounter:
+ return GL_ATOMIC_COUNTER_BUFFER;
+ case BufferBinding::CopyRead:
+ return GL_COPY_READ_BUFFER;
+ case BufferBinding::CopyWrite:
+ return GL_COPY_WRITE_BUFFER;
+ case BufferBinding::DispatchIndirect:
+ return GL_DISPATCH_INDIRECT_BUFFER;
+ case BufferBinding::DrawIndirect:
+ return GL_DRAW_INDIRECT_BUFFER;
+ case BufferBinding::ElementArray:
+ return GL_ELEMENT_ARRAY_BUFFER;
+ case BufferBinding::PixelPack:
+ return GL_PIXEL_PACK_BUFFER;
+ case BufferBinding::PixelUnpack:
+ return GL_PIXEL_UNPACK_BUFFER;
+ case BufferBinding::ShaderStorage:
+ return GL_SHADER_STORAGE_BUFFER;
+ case BufferBinding::Texture:
+ return GL_TEXTURE_BUFFER;
+ case BufferBinding::TransformFeedback:
+ return GL_TRANSFORM_FEEDBACK_BUFFER;
+ case BufferBinding::Uniform:
+ return GL_UNIFORM_BUFFER;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+std::ostream &operator<<(std::ostream &os, BufferBinding value)
+{
+ switch (value)
+ {
+ case BufferBinding::Array:
+ os << "GL_ARRAY_BUFFER";
+ break;
+ case BufferBinding::AtomicCounter:
+ os << "GL_ATOMIC_COUNTER_BUFFER";
+ break;
+ case BufferBinding::CopyRead:
+ os << "GL_COPY_READ_BUFFER";
+ break;
+ case BufferBinding::CopyWrite:
+ os << "GL_COPY_WRITE_BUFFER";
+ break;
+ case BufferBinding::DispatchIndirect:
+ os << "GL_DISPATCH_INDIRECT_BUFFER";
+ break;
+ case BufferBinding::DrawIndirect:
+ os << "GL_DRAW_INDIRECT_BUFFER";
+ break;
+ case BufferBinding::ElementArray:
+ os << "GL_ELEMENT_ARRAY_BUFFER";
+ break;
+ case BufferBinding::PixelPack:
+ os << "GL_PIXEL_PACK_BUFFER";
+ break;
+ case BufferBinding::PixelUnpack:
+ os << "GL_PIXEL_UNPACK_BUFFER";
+ break;
+ case BufferBinding::ShaderStorage:
+ os << "GL_SHADER_STORAGE_BUFFER";
+ break;
+ case BufferBinding::Texture:
+ os << "GL_TEXTURE_BUFFER";
+ break;
+ case BufferBinding::TransformFeedback:
+ os << "GL_TRANSFORM_FEEDBACK_BUFFER";
+ break;
+ case BufferBinding::Uniform:
+ os << "GL_UNIFORM_BUFFER";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+ return os;
+}
+
+template <>
+BufferUsage FromGLenum<BufferUsage>(GLenum from)
+{
+ switch (from)
+ {
+ case GL_DYNAMIC_COPY:
+ return BufferUsage::DynamicCopy;
+ case GL_DYNAMIC_DRAW:
+ return BufferUsage::DynamicDraw;
+ case GL_DYNAMIC_READ:
+ return BufferUsage::DynamicRead;
+ case GL_STATIC_COPY:
+ return BufferUsage::StaticCopy;
+ case GL_STATIC_DRAW:
+ return BufferUsage::StaticDraw;
+ case GL_STATIC_READ:
+ return BufferUsage::StaticRead;
+ case GL_STREAM_COPY:
+ return BufferUsage::StreamCopy;
+ case GL_STREAM_DRAW:
+ return BufferUsage::StreamDraw;
+ case GL_STREAM_READ:
+ return BufferUsage::StreamRead;
+ default:
+ return BufferUsage::InvalidEnum;
+ }
+}
+
+GLenum ToGLenum(BufferUsage from)
+{
+ switch (from)
+ {
+ case BufferUsage::DynamicCopy:
+ return GL_DYNAMIC_COPY;
+ case BufferUsage::DynamicDraw:
+ return GL_DYNAMIC_DRAW;
+ case BufferUsage::DynamicRead:
+ return GL_DYNAMIC_READ;
+ case BufferUsage::StaticCopy:
+ return GL_STATIC_COPY;
+ case BufferUsage::StaticDraw:
+ return GL_STATIC_DRAW;
+ case BufferUsage::StaticRead:
+ return GL_STATIC_READ;
+ case BufferUsage::StreamCopy:
+ return GL_STREAM_COPY;
+ case BufferUsage::StreamDraw:
+ return GL_STREAM_DRAW;
+ case BufferUsage::StreamRead:
+ return GL_STREAM_READ;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+std::ostream &operator<<(std::ostream &os, BufferUsage value)
+{
+ switch (value)
+ {
+ case BufferUsage::DynamicCopy:
+ os << "GL_DYNAMIC_COPY";
+ break;
+ case BufferUsage::DynamicDraw:
+ os << "GL_DYNAMIC_DRAW";
+ break;
+ case BufferUsage::DynamicRead:
+ os << "GL_DYNAMIC_READ";
+ break;
+ case BufferUsage::StaticCopy:
+ os << "GL_STATIC_COPY";
+ break;
+ case BufferUsage::StaticDraw:
+ os << "GL_STATIC_DRAW";
+ break;
+ case BufferUsage::StaticRead:
+ os << "GL_STATIC_READ";
+ break;
+ case BufferUsage::StreamCopy:
+ os << "GL_STREAM_COPY";
+ break;
+ case BufferUsage::StreamDraw:
+ os << "GL_STREAM_DRAW";
+ break;
+ case BufferUsage::StreamRead:
+ os << "GL_STREAM_READ";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+ return os;
+}
+
+template <>
+ClientVertexArrayType FromGLenum<ClientVertexArrayType>(GLenum from)
+{
+ switch (from)
+ {
+ case GL_COLOR_ARRAY:
+ return ClientVertexArrayType::Color;
+ case GL_NORMAL_ARRAY:
+ return ClientVertexArrayType::Normal;
+ case GL_POINT_SIZE_ARRAY_OES:
+ return ClientVertexArrayType::PointSize;
+ case GL_TEXTURE_COORD_ARRAY:
+ return ClientVertexArrayType::TextureCoord;
+ case GL_VERTEX_ARRAY:
+ return ClientVertexArrayType::Vertex;
+ default:
+ return ClientVertexArrayType::InvalidEnum;
+ }
+}
+
+GLenum ToGLenum(ClientVertexArrayType from)
+{
+ switch (from)
+ {
+ case ClientVertexArrayType::Color:
+ return GL_COLOR_ARRAY;
+ case ClientVertexArrayType::Normal:
+ return GL_NORMAL_ARRAY;
+ case ClientVertexArrayType::PointSize:
+ return GL_POINT_SIZE_ARRAY_OES;
+ case ClientVertexArrayType::TextureCoord:
+ return GL_TEXTURE_COORD_ARRAY;
+ case ClientVertexArrayType::Vertex:
+ return GL_VERTEX_ARRAY;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+std::ostream &operator<<(std::ostream &os, ClientVertexArrayType value)
+{
+ switch (value)
+ {
+ case ClientVertexArrayType::Color:
+ os << "GL_COLOR_ARRAY";
+ break;
+ case ClientVertexArrayType::Normal:
+ os << "GL_NORMAL_ARRAY";
+ break;
+ case ClientVertexArrayType::PointSize:
+ os << "GL_POINT_SIZE_ARRAY_OES";
+ break;
+ case ClientVertexArrayType::TextureCoord:
+ os << "GL_TEXTURE_COORD_ARRAY";
+ break;
+ case ClientVertexArrayType::Vertex:
+ os << "GL_VERTEX_ARRAY";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+ return os;
+}
+
+template <>
+CullFaceMode FromGLenum<CullFaceMode>(GLenum from)
+{
+ switch (from)
+ {
+ case GL_BACK:
+ return CullFaceMode::Back;
+ case GL_FRONT:
+ return CullFaceMode::Front;
+ case GL_FRONT_AND_BACK:
+ return CullFaceMode::FrontAndBack;
+ default:
+ return CullFaceMode::InvalidEnum;
+ }
+}
+
+GLenum ToGLenum(CullFaceMode from)
+{
+ switch (from)
+ {
+ case CullFaceMode::Back:
+ return GL_BACK;
+ case CullFaceMode::Front:
+ return GL_FRONT;
+ case CullFaceMode::FrontAndBack:
+ return GL_FRONT_AND_BACK;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+std::ostream &operator<<(std::ostream &os, CullFaceMode value)
+{
+ switch (value)
+ {
+ case CullFaceMode::Back:
+ os << "GL_BACK";
+ break;
+ case CullFaceMode::Front:
+ os << "GL_FRONT";
+ break;
+ case CullFaceMode::FrontAndBack:
+ os << "GL_FRONT_AND_BACK";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+ return os;
+}
+
+template <>
+FilterMode FromGLenum<FilterMode>(GLenum from)
+{
+ switch (from)
+ {
+ case GL_NEAREST:
+ return FilterMode::Nearest;
+ case GL_LINEAR:
+ return FilterMode::Linear;
+ case GL_NEAREST_MIPMAP_NEAREST:
+ return FilterMode::NearestMipmapNearest;
+ case GL_NEAREST_MIPMAP_LINEAR:
+ return FilterMode::NearestMipmapLinear;
+ case GL_LINEAR_MIPMAP_LINEAR:
+ return FilterMode::LinearMipmapLinear;
+ default:
+ return FilterMode::InvalidEnum;
+ }
+}
+
+GLenum ToGLenum(FilterMode from)
+{
+ switch (from)
+ {
+ case FilterMode::Nearest:
+ return GL_NEAREST;
+ case FilterMode::Linear:
+ return GL_LINEAR;
+ case FilterMode::NearestMipmapNearest:
+ return GL_NEAREST_MIPMAP_NEAREST;
+ case FilterMode::NearestMipmapLinear:
+ return GL_NEAREST_MIPMAP_LINEAR;
+ case FilterMode::LinearMipmapLinear:
+ return GL_LINEAR_MIPMAP_LINEAR;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+std::ostream &operator<<(std::ostream &os, FilterMode value)
+{
+ switch (value)
+ {
+ case FilterMode::Nearest:
+ os << "GL_NEAREST";
+ break;
+ case FilterMode::Linear:
+ os << "GL_LINEAR";
+ break;
+ case FilterMode::NearestMipmapNearest:
+ os << "GL_NEAREST_MIPMAP_NEAREST";
+ break;
+ case FilterMode::NearestMipmapLinear:
+ os << "GL_NEAREST_MIPMAP_LINEAR";
+ break;
+ case FilterMode::LinearMipmapLinear:
+ os << "GL_LINEAR_MIPMAP_LINEAR";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+ return os;
+}
+
+template <>
+FogMode FromGLenum<FogMode>(GLenum from)
+{
+ switch (from)
+ {
+ case GL_EXP:
+ return FogMode::Exp;
+ case GL_EXP2:
+ return FogMode::Exp2;
+ case GL_LINEAR:
+ return FogMode::Linear;
+ default:
+ return FogMode::InvalidEnum;
+ }
+}
+
+GLenum ToGLenum(FogMode from)
+{
+ switch (from)
+ {
+ case FogMode::Exp:
+ return GL_EXP;
+ case FogMode::Exp2:
+ return GL_EXP2;
+ case FogMode::Linear:
+ return GL_LINEAR;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+std::ostream &operator<<(std::ostream &os, FogMode value)
+{
+ switch (value)
+ {
+ case FogMode::Exp:
+ os << "GL_EXP";
+ break;
+ case FogMode::Exp2:
+ os << "GL_EXP2";
+ break;
+ case FogMode::Linear:
+ os << "GL_LINEAR";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+ return os;
+}
+
+template <>
+GraphicsResetStatus FromGLenum<GraphicsResetStatus>(GLenum from)
+{
+ switch (from)
+ {
+ case GL_NO_ERROR:
+ return GraphicsResetStatus::NoError;
+ case GL_GUILTY_CONTEXT_RESET:
+ return GraphicsResetStatus::GuiltyContextReset;
+ case GL_INNOCENT_CONTEXT_RESET:
+ return GraphicsResetStatus::InnocentContextReset;
+ case GL_UNKNOWN_CONTEXT_RESET:
+ return GraphicsResetStatus::UnknownContextReset;
+ case GL_PURGED_CONTEXT_RESET_NV:
+ return GraphicsResetStatus::PurgedContextResetNV;
+ default:
+ return GraphicsResetStatus::InvalidEnum;
+ }
+}
+
+GLenum ToGLenum(GraphicsResetStatus from)
+{
+ switch (from)
+ {
+ case GraphicsResetStatus::NoError:
+ return GL_NO_ERROR;
+ case GraphicsResetStatus::GuiltyContextReset:
+ return GL_GUILTY_CONTEXT_RESET;
+ case GraphicsResetStatus::InnocentContextReset:
+ return GL_INNOCENT_CONTEXT_RESET;
+ case GraphicsResetStatus::UnknownContextReset:
+ return GL_UNKNOWN_CONTEXT_RESET;
+ case GraphicsResetStatus::PurgedContextResetNV:
+ return GL_PURGED_CONTEXT_RESET_NV;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+std::ostream &operator<<(std::ostream &os, GraphicsResetStatus value)
+{
+ switch (value)
+ {
+ case GraphicsResetStatus::NoError:
+ os << "GL_NO_ERROR";
+ break;
+ case GraphicsResetStatus::GuiltyContextReset:
+ os << "GL_GUILTY_CONTEXT_RESET";
+ break;
+ case GraphicsResetStatus::InnocentContextReset:
+ os << "GL_INNOCENT_CONTEXT_RESET";
+ break;
+ case GraphicsResetStatus::UnknownContextReset:
+ os << "GL_UNKNOWN_CONTEXT_RESET";
+ break;
+ case GraphicsResetStatus::PurgedContextResetNV:
+ os << "GL_PURGED_CONTEXT_RESET_NV";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+ return os;
+}
+
+template <>
+HandleType FromGLenum<HandleType>(GLenum from)
+{
+ switch (from)
+ {
+ case GL_HANDLE_TYPE_OPAQUE_FD_EXT:
+ return HandleType::OpaqueFd;
+ case GL_HANDLE_TYPE_ZIRCON_VMO_ANGLE:
+ return HandleType::ZirconVmo;
+ case GL_HANDLE_TYPE_ZIRCON_EVENT_ANGLE:
+ return HandleType::ZirconEvent;
+ default:
+ return HandleType::InvalidEnum;
+ }
+}
+
+GLenum ToGLenum(HandleType from)
+{
+ switch (from)
+ {
+ case HandleType::OpaqueFd:
+ return GL_HANDLE_TYPE_OPAQUE_FD_EXT;
+ case HandleType::ZirconVmo:
+ return GL_HANDLE_TYPE_ZIRCON_VMO_ANGLE;
+ case HandleType::ZirconEvent:
+ return GL_HANDLE_TYPE_ZIRCON_EVENT_ANGLE;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+std::ostream &operator<<(std::ostream &os, HandleType value)
+{
+ switch (value)
+ {
+ case HandleType::OpaqueFd:
+ os << "GL_HANDLE_TYPE_OPAQUE_FD_EXT";
+ break;
+ case HandleType::ZirconVmo:
+ os << "GL_HANDLE_TYPE_ZIRCON_VMO_ANGLE";
+ break;
+ case HandleType::ZirconEvent:
+ os << "GL_HANDLE_TYPE_ZIRCON_EVENT_ANGLE";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+ return os;
+}
+
+template <>
+HintSetting FromGLenum<HintSetting>(GLenum from)
+{
+ switch (from)
+ {
+ case GL_DONT_CARE:
+ return HintSetting::DontCare;
+ case GL_FASTEST:
+ return HintSetting::Fastest;
+ case GL_NICEST:
+ return HintSetting::Nicest;
+ default:
+ return HintSetting::InvalidEnum;
+ }
+}
+
+GLenum ToGLenum(HintSetting from)
+{
+ switch (from)
+ {
+ case HintSetting::DontCare:
+ return GL_DONT_CARE;
+ case HintSetting::Fastest:
+ return GL_FASTEST;
+ case HintSetting::Nicest:
+ return GL_NICEST;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+std::ostream &operator<<(std::ostream &os, HintSetting value)
+{
+ switch (value)
+ {
+ case HintSetting::DontCare:
+ os << "GL_DONT_CARE";
+ break;
+ case HintSetting::Fastest:
+ os << "GL_FASTEST";
+ break;
+ case HintSetting::Nicest:
+ os << "GL_NICEST";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+ return os;
+}
+
+template <>
+ImageLayout FromGLenum<ImageLayout>(GLenum from)
+{
+ switch (from)
+ {
+ case GL_NONE:
+ return ImageLayout::Undefined;
+ case GL_LAYOUT_GENERAL_EXT:
+ return ImageLayout::General;
+ case GL_LAYOUT_COLOR_ATTACHMENT_EXT:
+ return ImageLayout::ColorAttachment;
+ case GL_LAYOUT_DEPTH_STENCIL_ATTACHMENT_EXT:
+ return ImageLayout::DepthStencilAttachment;
+ case GL_LAYOUT_DEPTH_STENCIL_READ_ONLY_EXT:
+ return ImageLayout::DepthStencilReadOnlyAttachment;
+ case GL_LAYOUT_SHADER_READ_ONLY_EXT:
+ return ImageLayout::ShaderReadOnly;
+ case GL_LAYOUT_TRANSFER_SRC_EXT:
+ return ImageLayout::TransferSrc;
+ case GL_LAYOUT_TRANSFER_DST_EXT:
+ return ImageLayout::TransferDst;
+ case GL_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_EXT:
+ return ImageLayout::DepthReadOnlyStencilAttachment;
+ case GL_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_EXT:
+ return ImageLayout::DepthAttachmentStencilReadOnly;
+ default:
+ return ImageLayout::InvalidEnum;
+ }
+}
+
+GLenum ToGLenum(ImageLayout from)
+{
+ switch (from)
+ {
+ case ImageLayout::Undefined:
+ return GL_NONE;
+ case ImageLayout::General:
+ return GL_LAYOUT_GENERAL_EXT;
+ case ImageLayout::ColorAttachment:
+ return GL_LAYOUT_COLOR_ATTACHMENT_EXT;
+ case ImageLayout::DepthStencilAttachment:
+ return GL_LAYOUT_DEPTH_STENCIL_ATTACHMENT_EXT;
+ case ImageLayout::DepthStencilReadOnlyAttachment:
+ return GL_LAYOUT_DEPTH_STENCIL_READ_ONLY_EXT;
+ case ImageLayout::ShaderReadOnly:
+ return GL_LAYOUT_SHADER_READ_ONLY_EXT;
+ case ImageLayout::TransferSrc:
+ return GL_LAYOUT_TRANSFER_SRC_EXT;
+ case ImageLayout::TransferDst:
+ return GL_LAYOUT_TRANSFER_DST_EXT;
+ case ImageLayout::DepthReadOnlyStencilAttachment:
+ return GL_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_EXT;
+ case ImageLayout::DepthAttachmentStencilReadOnly:
+ return GL_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_EXT;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+std::ostream &operator<<(std::ostream &os, ImageLayout value)
+{
+ switch (value)
+ {
+ case ImageLayout::Undefined:
+ os << "GL_NONE";
+ break;
+ case ImageLayout::General:
+ os << "GL_LAYOUT_GENERAL_EXT";
+ break;
+ case ImageLayout::ColorAttachment:
+ os << "GL_LAYOUT_COLOR_ATTACHMENT_EXT";
+ break;
+ case ImageLayout::DepthStencilAttachment:
+ os << "GL_LAYOUT_DEPTH_STENCIL_ATTACHMENT_EXT";
+ break;
+ case ImageLayout::DepthStencilReadOnlyAttachment:
+ os << "GL_LAYOUT_DEPTH_STENCIL_READ_ONLY_EXT";
+ break;
+ case ImageLayout::ShaderReadOnly:
+ os << "GL_LAYOUT_SHADER_READ_ONLY_EXT";
+ break;
+ case ImageLayout::TransferSrc:
+ os << "GL_LAYOUT_TRANSFER_SRC_EXT";
+ break;
+ case ImageLayout::TransferDst:
+ os << "GL_LAYOUT_TRANSFER_DST_EXT";
+ break;
+ case ImageLayout::DepthReadOnlyStencilAttachment:
+ os << "GL_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_EXT";
+ break;
+ case ImageLayout::DepthAttachmentStencilReadOnly:
+ os << "GL_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_EXT";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+ return os;
+}
+
+template <>
+LightParameter FromGLenum<LightParameter>(GLenum from)
+{
+ switch (from)
+ {
+ case GL_AMBIENT:
+ return LightParameter::Ambient;
+ case GL_AMBIENT_AND_DIFFUSE:
+ return LightParameter::AmbientAndDiffuse;
+ case GL_CONSTANT_ATTENUATION:
+ return LightParameter::ConstantAttenuation;
+ case GL_DIFFUSE:
+ return LightParameter::Diffuse;
+ case GL_LINEAR_ATTENUATION:
+ return LightParameter::LinearAttenuation;
+ case GL_POSITION:
+ return LightParameter::Position;
+ case GL_QUADRATIC_ATTENUATION:
+ return LightParameter::QuadraticAttenuation;
+ case GL_SPECULAR:
+ return LightParameter::Specular;
+ case GL_SPOT_CUTOFF:
+ return LightParameter::SpotCutoff;
+ case GL_SPOT_DIRECTION:
+ return LightParameter::SpotDirection;
+ case GL_SPOT_EXPONENT:
+ return LightParameter::SpotExponent;
+ default:
+ return LightParameter::InvalidEnum;
+ }
+}
+
+GLenum ToGLenum(LightParameter from)
+{
+ switch (from)
+ {
+ case LightParameter::Ambient:
+ return GL_AMBIENT;
+ case LightParameter::AmbientAndDiffuse:
+ return GL_AMBIENT_AND_DIFFUSE;
+ case LightParameter::ConstantAttenuation:
+ return GL_CONSTANT_ATTENUATION;
+ case LightParameter::Diffuse:
+ return GL_DIFFUSE;
+ case LightParameter::LinearAttenuation:
+ return GL_LINEAR_ATTENUATION;
+ case LightParameter::Position:
+ return GL_POSITION;
+ case LightParameter::QuadraticAttenuation:
+ return GL_QUADRATIC_ATTENUATION;
+ case LightParameter::Specular:
+ return GL_SPECULAR;
+ case LightParameter::SpotCutoff:
+ return GL_SPOT_CUTOFF;
+ case LightParameter::SpotDirection:
+ return GL_SPOT_DIRECTION;
+ case LightParameter::SpotExponent:
+ return GL_SPOT_EXPONENT;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+std::ostream &operator<<(std::ostream &os, LightParameter value)
+{
+ switch (value)
+ {
+ case LightParameter::Ambient:
+ os << "GL_AMBIENT";
+ break;
+ case LightParameter::AmbientAndDiffuse:
+ os << "GL_AMBIENT_AND_DIFFUSE";
+ break;
+ case LightParameter::ConstantAttenuation:
+ os << "GL_CONSTANT_ATTENUATION";
+ break;
+ case LightParameter::Diffuse:
+ os << "GL_DIFFUSE";
+ break;
+ case LightParameter::LinearAttenuation:
+ os << "GL_LINEAR_ATTENUATION";
+ break;
+ case LightParameter::Position:
+ os << "GL_POSITION";
+ break;
+ case LightParameter::QuadraticAttenuation:
+ os << "GL_QUADRATIC_ATTENUATION";
+ break;
+ case LightParameter::Specular:
+ os << "GL_SPECULAR";
+ break;
+ case LightParameter::SpotCutoff:
+ os << "GL_SPOT_CUTOFF";
+ break;
+ case LightParameter::SpotDirection:
+ os << "GL_SPOT_DIRECTION";
+ break;
+ case LightParameter::SpotExponent:
+ os << "GL_SPOT_EXPONENT";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+ return os;
+}
+
+template <>
+LogicalOperation FromGLenum<LogicalOperation>(GLenum from)
+{
+ switch (from)
+ {
+ case GL_AND:
+ return LogicalOperation::And;
+ case GL_AND_INVERTED:
+ return LogicalOperation::AndInverted;
+ case GL_AND_REVERSE:
+ return LogicalOperation::AndReverse;
+ case GL_CLEAR:
+ return LogicalOperation::Clear;
+ case GL_COPY:
+ return LogicalOperation::Copy;
+ case GL_COPY_INVERTED:
+ return LogicalOperation::CopyInverted;
+ case GL_EQUIV:
+ return LogicalOperation::Equiv;
+ case GL_INVERT:
+ return LogicalOperation::Invert;
+ case GL_NAND:
+ return LogicalOperation::Nand;
+ case GL_NOOP:
+ return LogicalOperation::Noop;
+ case GL_NOR:
+ return LogicalOperation::Nor;
+ case GL_OR:
+ return LogicalOperation::Or;
+ case GL_OR_INVERTED:
+ return LogicalOperation::OrInverted;
+ case GL_OR_REVERSE:
+ return LogicalOperation::OrReverse;
+ case GL_SET:
+ return LogicalOperation::Set;
+ case GL_XOR:
+ return LogicalOperation::Xor;
+ default:
+ return LogicalOperation::InvalidEnum;
+ }
+}
+
+GLenum ToGLenum(LogicalOperation from)
+{
+ switch (from)
+ {
+ case LogicalOperation::And:
+ return GL_AND;
+ case LogicalOperation::AndInverted:
+ return GL_AND_INVERTED;
+ case LogicalOperation::AndReverse:
+ return GL_AND_REVERSE;
+ case LogicalOperation::Clear:
+ return GL_CLEAR;
+ case LogicalOperation::Copy:
+ return GL_COPY;
+ case LogicalOperation::CopyInverted:
+ return GL_COPY_INVERTED;
+ case LogicalOperation::Equiv:
+ return GL_EQUIV;
+ case LogicalOperation::Invert:
+ return GL_INVERT;
+ case LogicalOperation::Nand:
+ return GL_NAND;
+ case LogicalOperation::Noop:
+ return GL_NOOP;
+ case LogicalOperation::Nor:
+ return GL_NOR;
+ case LogicalOperation::Or:
+ return GL_OR;
+ case LogicalOperation::OrInverted:
+ return GL_OR_INVERTED;
+ case LogicalOperation::OrReverse:
+ return GL_OR_REVERSE;
+ case LogicalOperation::Set:
+ return GL_SET;
+ case LogicalOperation::Xor:
+ return GL_XOR;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+std::ostream &operator<<(std::ostream &os, LogicalOperation value)
+{
+ switch (value)
+ {
+ case LogicalOperation::And:
+ os << "GL_AND";
+ break;
+ case LogicalOperation::AndInverted:
+ os << "GL_AND_INVERTED";
+ break;
+ case LogicalOperation::AndReverse:
+ os << "GL_AND_REVERSE";
+ break;
+ case LogicalOperation::Clear:
+ os << "GL_CLEAR";
+ break;
+ case LogicalOperation::Copy:
+ os << "GL_COPY";
+ break;
+ case LogicalOperation::CopyInverted:
+ os << "GL_COPY_INVERTED";
+ break;
+ case LogicalOperation::Equiv:
+ os << "GL_EQUIV";
+ break;
+ case LogicalOperation::Invert:
+ os << "GL_INVERT";
+ break;
+ case LogicalOperation::Nand:
+ os << "GL_NAND";
+ break;
+ case LogicalOperation::Noop:
+ os << "GL_NOOP";
+ break;
+ case LogicalOperation::Nor:
+ os << "GL_NOR";
+ break;
+ case LogicalOperation::Or:
+ os << "GL_OR";
+ break;
+ case LogicalOperation::OrInverted:
+ os << "GL_OR_INVERTED";
+ break;
+ case LogicalOperation::OrReverse:
+ os << "GL_OR_REVERSE";
+ break;
+ case LogicalOperation::Set:
+ os << "GL_SET";
+ break;
+ case LogicalOperation::Xor:
+ os << "GL_XOR";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+ return os;
+}
+
+template <>
+MaterialParameter FromGLenum<MaterialParameter>(GLenum from)
+{
+ switch (from)
+ {
+ case GL_AMBIENT:
+ return MaterialParameter::Ambient;
+ case GL_AMBIENT_AND_DIFFUSE:
+ return MaterialParameter::AmbientAndDiffuse;
+ case GL_DIFFUSE:
+ return MaterialParameter::Diffuse;
+ case GL_EMISSION:
+ return MaterialParameter::Emission;
+ case GL_SHININESS:
+ return MaterialParameter::Shininess;
+ case GL_SPECULAR:
+ return MaterialParameter::Specular;
+ default:
+ return MaterialParameter::InvalidEnum;
+ }
+}
+
+GLenum ToGLenum(MaterialParameter from)
+{
+ switch (from)
+ {
+ case MaterialParameter::Ambient:
+ return GL_AMBIENT;
+ case MaterialParameter::AmbientAndDiffuse:
+ return GL_AMBIENT_AND_DIFFUSE;
+ case MaterialParameter::Diffuse:
+ return GL_DIFFUSE;
+ case MaterialParameter::Emission:
+ return GL_EMISSION;
+ case MaterialParameter::Shininess:
+ return GL_SHININESS;
+ case MaterialParameter::Specular:
+ return GL_SPECULAR;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+std::ostream &operator<<(std::ostream &os, MaterialParameter value)
+{
+ switch (value)
+ {
+ case MaterialParameter::Ambient:
+ os << "GL_AMBIENT";
+ break;
+ case MaterialParameter::AmbientAndDiffuse:
+ os << "GL_AMBIENT_AND_DIFFUSE";
+ break;
+ case MaterialParameter::Diffuse:
+ os << "GL_DIFFUSE";
+ break;
+ case MaterialParameter::Emission:
+ os << "GL_EMISSION";
+ break;
+ case MaterialParameter::Shininess:
+ os << "GL_SHININESS";
+ break;
+ case MaterialParameter::Specular:
+ os << "GL_SPECULAR";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+ return os;
+}
+
+template <>
+MatrixType FromGLenum<MatrixType>(GLenum from)
+{
+ switch (from)
+ {
+ case GL_MODELVIEW:
+ return MatrixType::Modelview;
+ case GL_PROJECTION:
+ return MatrixType::Projection;
+ case GL_TEXTURE:
+ return MatrixType::Texture;
+ default:
+ return MatrixType::InvalidEnum;
+ }
+}
+
+GLenum ToGLenum(MatrixType from)
+{
+ switch (from)
+ {
+ case MatrixType::Modelview:
+ return GL_MODELVIEW;
+ case MatrixType::Projection:
+ return GL_PROJECTION;
+ case MatrixType::Texture:
+ return GL_TEXTURE;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+std::ostream &operator<<(std::ostream &os, MatrixType value)
+{
+ switch (value)
+ {
+ case MatrixType::Modelview:
+ os << "GL_MODELVIEW";
+ break;
+ case MatrixType::Projection:
+ os << "GL_PROJECTION";
+ break;
+ case MatrixType::Texture:
+ os << "GL_TEXTURE";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+ return os;
+}
+
+template <>
+PointParameter FromGLenum<PointParameter>(GLenum from)
+{
+ switch (from)
+ {
+ case GL_POINT_SIZE_MIN:
+ return PointParameter::PointSizeMin;
+ case GL_POINT_SIZE_MAX:
+ return PointParameter::PointSizeMax;
+ case GL_POINT_FADE_THRESHOLD_SIZE:
+ return PointParameter::PointFadeThresholdSize;
+ case GL_POINT_DISTANCE_ATTENUATION:
+ return PointParameter::PointDistanceAttenuation;
+ default:
+ return PointParameter::InvalidEnum;
+ }
+}
+
+GLenum ToGLenum(PointParameter from)
+{
+ switch (from)
+ {
+ case PointParameter::PointSizeMin:
+ return GL_POINT_SIZE_MIN;
+ case PointParameter::PointSizeMax:
+ return GL_POINT_SIZE_MAX;
+ case PointParameter::PointFadeThresholdSize:
+ return GL_POINT_FADE_THRESHOLD_SIZE;
+ case PointParameter::PointDistanceAttenuation:
+ return GL_POINT_DISTANCE_ATTENUATION;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+std::ostream &operator<<(std::ostream &os, PointParameter value)
+{
+ switch (value)
+ {
+ case PointParameter::PointSizeMin:
+ os << "GL_POINT_SIZE_MIN";
+ break;
+ case PointParameter::PointSizeMax:
+ os << "GL_POINT_SIZE_MAX";
+ break;
+ case PointParameter::PointFadeThresholdSize:
+ os << "GL_POINT_FADE_THRESHOLD_SIZE";
+ break;
+ case PointParameter::PointDistanceAttenuation:
+ os << "GL_POINT_DISTANCE_ATTENUATION";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+ return os;
+}
+
+template <>
+ProvokingVertexConvention FromGLenum<ProvokingVertexConvention>(GLenum from)
+{
+ switch (from)
+ {
+ case GL_FIRST_VERTEX_CONVENTION:
+ return ProvokingVertexConvention::FirstVertexConvention;
+ case GL_LAST_VERTEX_CONVENTION:
+ return ProvokingVertexConvention::LastVertexConvention;
+ default:
+ return ProvokingVertexConvention::InvalidEnum;
+ }
+}
+
+GLenum ToGLenum(ProvokingVertexConvention from)
+{
+ switch (from)
+ {
+ case ProvokingVertexConvention::FirstVertexConvention:
+ return GL_FIRST_VERTEX_CONVENTION;
+ case ProvokingVertexConvention::LastVertexConvention:
+ return GL_LAST_VERTEX_CONVENTION;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+std::ostream &operator<<(std::ostream &os, ProvokingVertexConvention value)
+{
+ switch (value)
+ {
+ case ProvokingVertexConvention::FirstVertexConvention:
+ os << "GL_FIRST_VERTEX_CONVENTION";
+ break;
+ case ProvokingVertexConvention::LastVertexConvention:
+ os << "GL_LAST_VERTEX_CONVENTION";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+ return os;
+}
+
+template <>
+QueryType FromGLenum<QueryType>(GLenum from)
+{
+ switch (from)
+ {
+ case GL_ANY_SAMPLES_PASSED:
+ return QueryType::AnySamples;
+ case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
+ return QueryType::AnySamplesConservative;
+ case GL_COMMANDS_COMPLETED_CHROMIUM:
+ return QueryType::CommandsCompleted;
+ case GL_PRIMITIVES_GENERATED_EXT:
+ return QueryType::PrimitivesGenerated;
+ case GL_TIME_ELAPSED_EXT:
+ return QueryType::TimeElapsed;
+ case GL_TIMESTAMP_EXT:
+ return QueryType::Timestamp;
+ case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
+ return QueryType::TransformFeedbackPrimitivesWritten;
+ default:
+ return QueryType::InvalidEnum;
+ }
+}
+
+GLenum ToGLenum(QueryType from)
+{
+ switch (from)
+ {
+ case QueryType::AnySamples:
+ return GL_ANY_SAMPLES_PASSED;
+ case QueryType::AnySamplesConservative:
+ return GL_ANY_SAMPLES_PASSED_CONSERVATIVE;
+ case QueryType::CommandsCompleted:
+ return GL_COMMANDS_COMPLETED_CHROMIUM;
+ case QueryType::PrimitivesGenerated:
+ return GL_PRIMITIVES_GENERATED_EXT;
+ case QueryType::TimeElapsed:
+ return GL_TIME_ELAPSED_EXT;
+ case QueryType::Timestamp:
+ return GL_TIMESTAMP_EXT;
+ case QueryType::TransformFeedbackPrimitivesWritten:
+ return GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+std::ostream &operator<<(std::ostream &os, QueryType value)
+{
+ switch (value)
+ {
+ case QueryType::AnySamples:
+ os << "GL_ANY_SAMPLES_PASSED";
+ break;
+ case QueryType::AnySamplesConservative:
+ os << "GL_ANY_SAMPLES_PASSED_CONSERVATIVE";
+ break;
+ case QueryType::CommandsCompleted:
+ os << "GL_COMMANDS_COMPLETED_CHROMIUM";
+ break;
+ case QueryType::PrimitivesGenerated:
+ os << "GL_PRIMITIVES_GENERATED_EXT";
+ break;
+ case QueryType::TimeElapsed:
+ os << "GL_TIME_ELAPSED_EXT";
+ break;
+ case QueryType::Timestamp:
+ os << "GL_TIMESTAMP_EXT";
+ break;
+ case QueryType::TransformFeedbackPrimitivesWritten:
+ os << "GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+ return os;
+}
+
+template <>
+ShaderType FromGLenum<ShaderType>(GLenum from)
+{
+ switch (from)
+ {
+ case GL_VERTEX_SHADER:
+ return ShaderType::Vertex;
+ case GL_TESS_CONTROL_SHADER_EXT:
+ return ShaderType::TessControl;
+ case GL_TESS_EVALUATION_SHADER_EXT:
+ return ShaderType::TessEvaluation;
+ case GL_GEOMETRY_SHADER_EXT:
+ return ShaderType::Geometry;
+ case GL_FRAGMENT_SHADER:
+ return ShaderType::Fragment;
+ case GL_COMPUTE_SHADER:
+ return ShaderType::Compute;
+ default:
+ return ShaderType::InvalidEnum;
+ }
+}
+
+GLenum ToGLenum(ShaderType from)
+{
+ switch (from)
+ {
+ case ShaderType::Vertex:
+ return GL_VERTEX_SHADER;
+ case ShaderType::TessControl:
+ return GL_TESS_CONTROL_SHADER_EXT;
+ case ShaderType::TessEvaluation:
+ return GL_TESS_EVALUATION_SHADER_EXT;
+ case ShaderType::Geometry:
+ return GL_GEOMETRY_SHADER_EXT;
+ case ShaderType::Fragment:
+ return GL_FRAGMENT_SHADER;
+ case ShaderType::Compute:
+ return GL_COMPUTE_SHADER;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+std::ostream &operator<<(std::ostream &os, ShaderType value)
+{
+ switch (value)
+ {
+ case ShaderType::Vertex:
+ os << "GL_VERTEX_SHADER";
+ break;
+ case ShaderType::TessControl:
+ os << "GL_TESS_CONTROL_SHADER_EXT";
+ break;
+ case ShaderType::TessEvaluation:
+ os << "GL_TESS_EVALUATION_SHADER_EXT";
+ break;
+ case ShaderType::Geometry:
+ os << "GL_GEOMETRY_SHADER_EXT";
+ break;
+ case ShaderType::Fragment:
+ os << "GL_FRAGMENT_SHADER";
+ break;
+ case ShaderType::Compute:
+ os << "GL_COMPUTE_SHADER";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+ return os;
+}
+
+template <>
+ShadingModel FromGLenum<ShadingModel>(GLenum from)
+{
+ switch (from)
+ {
+ case GL_FLAT:
+ return ShadingModel::Flat;
+ case GL_SMOOTH:
+ return ShadingModel::Smooth;
+ default:
+ return ShadingModel::InvalidEnum;
+ }
+}
+
+GLenum ToGLenum(ShadingModel from)
+{
+ switch (from)
+ {
+ case ShadingModel::Flat:
+ return GL_FLAT;
+ case ShadingModel::Smooth:
+ return GL_SMOOTH;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+std::ostream &operator<<(std::ostream &os, ShadingModel value)
+{
+ switch (value)
+ {
+ case ShadingModel::Flat:
+ os << "GL_FLAT";
+ break;
+ case ShadingModel::Smooth:
+ os << "GL_SMOOTH";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+ return os;
+}
+
+template <>
+ShadingRate FromGLenum<ShadingRate>(GLenum from)
+{
+ switch (from)
+ {
+ case GL_NONE:
+ return ShadingRate::Undefined;
+ case GL_SHADING_RATE_1X1_PIXELS_QCOM:
+ return ShadingRate::_1x1;
+ case GL_SHADING_RATE_1X2_PIXELS_QCOM:
+ return ShadingRate::_1x2;
+ case GL_SHADING_RATE_2X1_PIXELS_QCOM:
+ return ShadingRate::_2x1;
+ case GL_SHADING_RATE_2X2_PIXELS_QCOM:
+ return ShadingRate::_2x2;
+ case GL_SHADING_RATE_4X2_PIXELS_QCOM:
+ return ShadingRate::_4x2;
+ case GL_SHADING_RATE_4X4_PIXELS_QCOM:
+ return ShadingRate::_4x4;
+ default:
+ return ShadingRate::InvalidEnum;
+ }
+}
+
+GLenum ToGLenum(ShadingRate from)
+{
+ switch (from)
+ {
+ case ShadingRate::Undefined:
+ return GL_NONE;
+ case ShadingRate::_1x1:
+ return GL_SHADING_RATE_1X1_PIXELS_QCOM;
+ case ShadingRate::_1x2:
+ return GL_SHADING_RATE_1X2_PIXELS_QCOM;
+ case ShadingRate::_2x1:
+ return GL_SHADING_RATE_2X1_PIXELS_QCOM;
+ case ShadingRate::_2x2:
+ return GL_SHADING_RATE_2X2_PIXELS_QCOM;
+ case ShadingRate::_4x2:
+ return GL_SHADING_RATE_4X2_PIXELS_QCOM;
+ case ShadingRate::_4x4:
+ return GL_SHADING_RATE_4X4_PIXELS_QCOM;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+std::ostream &operator<<(std::ostream &os, ShadingRate value)
+{
+ switch (value)
+ {
+ case ShadingRate::Undefined:
+ os << "GL_NONE";
+ break;
+ case ShadingRate::_1x1:
+ os << "GL_SHADING_RATE_1X1_PIXELS_QCOM";
+ break;
+ case ShadingRate::_1x2:
+ os << "GL_SHADING_RATE_1X2_PIXELS_QCOM";
+ break;
+ case ShadingRate::_2x1:
+ os << "GL_SHADING_RATE_2X1_PIXELS_QCOM";
+ break;
+ case ShadingRate::_2x2:
+ os << "GL_SHADING_RATE_2X2_PIXELS_QCOM";
+ break;
+ case ShadingRate::_4x2:
+ os << "GL_SHADING_RATE_4X2_PIXELS_QCOM";
+ break;
+ case ShadingRate::_4x4:
+ os << "GL_SHADING_RATE_4X4_PIXELS_QCOM";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+ return os;
+}
+
+template <>
+TextureCombine FromGLenum<TextureCombine>(GLenum from)
+{
+ switch (from)
+ {
+ case GL_ADD:
+ return TextureCombine::Add;
+ case GL_ADD_SIGNED:
+ return TextureCombine::AddSigned;
+ case GL_DOT3_RGB:
+ return TextureCombine::Dot3Rgb;
+ case GL_DOT3_RGBA:
+ return TextureCombine::Dot3Rgba;
+ case GL_INTERPOLATE:
+ return TextureCombine::Interpolate;
+ case GL_MODULATE:
+ return TextureCombine::Modulate;
+ case GL_REPLACE:
+ return TextureCombine::Replace;
+ case GL_SUBTRACT:
+ return TextureCombine::Subtract;
+ default:
+ return TextureCombine::InvalidEnum;
+ }
+}
+
+GLenum ToGLenum(TextureCombine from)
+{
+ switch (from)
+ {
+ case TextureCombine::Add:
+ return GL_ADD;
+ case TextureCombine::AddSigned:
+ return GL_ADD_SIGNED;
+ case TextureCombine::Dot3Rgb:
+ return GL_DOT3_RGB;
+ case TextureCombine::Dot3Rgba:
+ return GL_DOT3_RGBA;
+ case TextureCombine::Interpolate:
+ return GL_INTERPOLATE;
+ case TextureCombine::Modulate:
+ return GL_MODULATE;
+ case TextureCombine::Replace:
+ return GL_REPLACE;
+ case TextureCombine::Subtract:
+ return GL_SUBTRACT;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+std::ostream &operator<<(std::ostream &os, TextureCombine value)
+{
+ switch (value)
+ {
+ case TextureCombine::Add:
+ os << "GL_ADD";
+ break;
+ case TextureCombine::AddSigned:
+ os << "GL_ADD_SIGNED";
+ break;
+ case TextureCombine::Dot3Rgb:
+ os << "GL_DOT3_RGB";
+ break;
+ case TextureCombine::Dot3Rgba:
+ os << "GL_DOT3_RGBA";
+ break;
+ case TextureCombine::Interpolate:
+ os << "GL_INTERPOLATE";
+ break;
+ case TextureCombine::Modulate:
+ os << "GL_MODULATE";
+ break;
+ case TextureCombine::Replace:
+ os << "GL_REPLACE";
+ break;
+ case TextureCombine::Subtract:
+ os << "GL_SUBTRACT";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+ return os;
+}
+
+template <>
+TextureEnvMode FromGLenum<TextureEnvMode>(GLenum from)
+{
+ switch (from)
+ {
+ case GL_ADD:
+ return TextureEnvMode::Add;
+ case GL_BLEND:
+ return TextureEnvMode::Blend;
+ case GL_COMBINE:
+ return TextureEnvMode::Combine;
+ case GL_DECAL:
+ return TextureEnvMode::Decal;
+ case GL_MODULATE:
+ return TextureEnvMode::Modulate;
+ case GL_REPLACE:
+ return TextureEnvMode::Replace;
+ default:
+ return TextureEnvMode::InvalidEnum;
+ }
+}
+
+GLenum ToGLenum(TextureEnvMode from)
+{
+ switch (from)
+ {
+ case TextureEnvMode::Add:
+ return GL_ADD;
+ case TextureEnvMode::Blend:
+ return GL_BLEND;
+ case TextureEnvMode::Combine:
+ return GL_COMBINE;
+ case TextureEnvMode::Decal:
+ return GL_DECAL;
+ case TextureEnvMode::Modulate:
+ return GL_MODULATE;
+ case TextureEnvMode::Replace:
+ return GL_REPLACE;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+std::ostream &operator<<(std::ostream &os, TextureEnvMode value)
+{
+ switch (value)
+ {
+ case TextureEnvMode::Add:
+ os << "GL_ADD";
+ break;
+ case TextureEnvMode::Blend:
+ os << "GL_BLEND";
+ break;
+ case TextureEnvMode::Combine:
+ os << "GL_COMBINE";
+ break;
+ case TextureEnvMode::Decal:
+ os << "GL_DECAL";
+ break;
+ case TextureEnvMode::Modulate:
+ os << "GL_MODULATE";
+ break;
+ case TextureEnvMode::Replace:
+ os << "GL_REPLACE";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+ return os;
+}
+
+template <>
+TextureEnvParameter FromGLenum<TextureEnvParameter>(GLenum from)
+{
+ switch (from)
+ {
+ case GL_TEXTURE_ENV_MODE:
+ return TextureEnvParameter::Mode;
+ case GL_TEXTURE_ENV_COLOR:
+ return TextureEnvParameter::Color;
+ case GL_COMBINE_RGB:
+ return TextureEnvParameter::CombineRgb;
+ case GL_COMBINE_ALPHA:
+ return TextureEnvParameter::CombineAlpha;
+ case GL_RGB_SCALE:
+ return TextureEnvParameter::RgbScale;
+ case GL_ALPHA_SCALE:
+ return TextureEnvParameter::AlphaScale;
+ case GL_SRC0_RGB:
+ return TextureEnvParameter::Src0Rgb;
+ case GL_SRC1_RGB:
+ return TextureEnvParameter::Src1Rgb;
+ case GL_SRC2_RGB:
+ return TextureEnvParameter::Src2Rgb;
+ case GL_SRC0_ALPHA:
+ return TextureEnvParameter::Src0Alpha;
+ case GL_SRC1_ALPHA:
+ return TextureEnvParameter::Src1Alpha;
+ case GL_SRC2_ALPHA:
+ return TextureEnvParameter::Src2Alpha;
+ case GL_OPERAND0_RGB:
+ return TextureEnvParameter::Op0Rgb;
+ case GL_OPERAND1_RGB:
+ return TextureEnvParameter::Op1Rgb;
+ case GL_OPERAND2_RGB:
+ return TextureEnvParameter::Op2Rgb;
+ case GL_OPERAND0_ALPHA:
+ return TextureEnvParameter::Op0Alpha;
+ case GL_OPERAND1_ALPHA:
+ return TextureEnvParameter::Op1Alpha;
+ case GL_OPERAND2_ALPHA:
+ return TextureEnvParameter::Op2Alpha;
+ case GL_COORD_REPLACE_OES:
+ return TextureEnvParameter::PointCoordReplace;
+ default:
+ return TextureEnvParameter::InvalidEnum;
+ }
+}
+
+GLenum ToGLenum(TextureEnvParameter from)
+{
+ switch (from)
+ {
+ case TextureEnvParameter::Mode:
+ return GL_TEXTURE_ENV_MODE;
+ case TextureEnvParameter::Color:
+ return GL_TEXTURE_ENV_COLOR;
+ case TextureEnvParameter::CombineRgb:
+ return GL_COMBINE_RGB;
+ case TextureEnvParameter::CombineAlpha:
+ return GL_COMBINE_ALPHA;
+ case TextureEnvParameter::RgbScale:
+ return GL_RGB_SCALE;
+ case TextureEnvParameter::AlphaScale:
+ return GL_ALPHA_SCALE;
+ case TextureEnvParameter::Src0Rgb:
+ return GL_SRC0_RGB;
+ case TextureEnvParameter::Src1Rgb:
+ return GL_SRC1_RGB;
+ case TextureEnvParameter::Src2Rgb:
+ return GL_SRC2_RGB;
+ case TextureEnvParameter::Src0Alpha:
+ return GL_SRC0_ALPHA;
+ case TextureEnvParameter::Src1Alpha:
+ return GL_SRC1_ALPHA;
+ case TextureEnvParameter::Src2Alpha:
+ return GL_SRC2_ALPHA;
+ case TextureEnvParameter::Op0Rgb:
+ return GL_OPERAND0_RGB;
+ case TextureEnvParameter::Op1Rgb:
+ return GL_OPERAND1_RGB;
+ case TextureEnvParameter::Op2Rgb:
+ return GL_OPERAND2_RGB;
+ case TextureEnvParameter::Op0Alpha:
+ return GL_OPERAND0_ALPHA;
+ case TextureEnvParameter::Op1Alpha:
+ return GL_OPERAND1_ALPHA;
+ case TextureEnvParameter::Op2Alpha:
+ return GL_OPERAND2_ALPHA;
+ case TextureEnvParameter::PointCoordReplace:
+ return GL_COORD_REPLACE_OES;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+std::ostream &operator<<(std::ostream &os, TextureEnvParameter value)
+{
+ switch (value)
+ {
+ case TextureEnvParameter::Mode:
+ os << "GL_TEXTURE_ENV_MODE";
+ break;
+ case TextureEnvParameter::Color:
+ os << "GL_TEXTURE_ENV_COLOR";
+ break;
+ case TextureEnvParameter::CombineRgb:
+ os << "GL_COMBINE_RGB";
+ break;
+ case TextureEnvParameter::CombineAlpha:
+ os << "GL_COMBINE_ALPHA";
+ break;
+ case TextureEnvParameter::RgbScale:
+ os << "GL_RGB_SCALE";
+ break;
+ case TextureEnvParameter::AlphaScale:
+ os << "GL_ALPHA_SCALE";
+ break;
+ case TextureEnvParameter::Src0Rgb:
+ os << "GL_SRC0_RGB";
+ break;
+ case TextureEnvParameter::Src1Rgb:
+ os << "GL_SRC1_RGB";
+ break;
+ case TextureEnvParameter::Src2Rgb:
+ os << "GL_SRC2_RGB";
+ break;
+ case TextureEnvParameter::Src0Alpha:
+ os << "GL_SRC0_ALPHA";
+ break;
+ case TextureEnvParameter::Src1Alpha:
+ os << "GL_SRC1_ALPHA";
+ break;
+ case TextureEnvParameter::Src2Alpha:
+ os << "GL_SRC2_ALPHA";
+ break;
+ case TextureEnvParameter::Op0Rgb:
+ os << "GL_OPERAND0_RGB";
+ break;
+ case TextureEnvParameter::Op1Rgb:
+ os << "GL_OPERAND1_RGB";
+ break;
+ case TextureEnvParameter::Op2Rgb:
+ os << "GL_OPERAND2_RGB";
+ break;
+ case TextureEnvParameter::Op0Alpha:
+ os << "GL_OPERAND0_ALPHA";
+ break;
+ case TextureEnvParameter::Op1Alpha:
+ os << "GL_OPERAND1_ALPHA";
+ break;
+ case TextureEnvParameter::Op2Alpha:
+ os << "GL_OPERAND2_ALPHA";
+ break;
+ case TextureEnvParameter::PointCoordReplace:
+ os << "GL_COORD_REPLACE_OES";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+ return os;
+}
+
+template <>
+TextureEnvTarget FromGLenum<TextureEnvTarget>(GLenum from)
+{
+ switch (from)
+ {
+ case GL_TEXTURE_ENV:
+ return TextureEnvTarget::Env;
+ case GL_POINT_SPRITE_OES:
+ return TextureEnvTarget::PointSprite;
+ default:
+ return TextureEnvTarget::InvalidEnum;
+ }
+}
+
+GLenum ToGLenum(TextureEnvTarget from)
+{
+ switch (from)
+ {
+ case TextureEnvTarget::Env:
+ return GL_TEXTURE_ENV;
+ case TextureEnvTarget::PointSprite:
+ return GL_POINT_SPRITE_OES;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+std::ostream &operator<<(std::ostream &os, TextureEnvTarget value)
+{
+ switch (value)
+ {
+ case TextureEnvTarget::Env:
+ os << "GL_TEXTURE_ENV";
+ break;
+ case TextureEnvTarget::PointSprite:
+ os << "GL_POINT_SPRITE_OES";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+ return os;
+}
+
+template <>
+TextureOp FromGLenum<TextureOp>(GLenum from)
+{
+ switch (from)
+ {
+ case GL_ONE_MINUS_SRC_ALPHA:
+ return TextureOp::OneMinusSrcAlpha;
+ case GL_ONE_MINUS_SRC_COLOR:
+ return TextureOp::OneMinusSrcColor;
+ case GL_SRC_ALPHA:
+ return TextureOp::SrcAlpha;
+ case GL_SRC_COLOR:
+ return TextureOp::SrcColor;
+ default:
+ return TextureOp::InvalidEnum;
+ }
+}
+
+GLenum ToGLenum(TextureOp from)
+{
+ switch (from)
+ {
+ case TextureOp::OneMinusSrcAlpha:
+ return GL_ONE_MINUS_SRC_ALPHA;
+ case TextureOp::OneMinusSrcColor:
+ return GL_ONE_MINUS_SRC_COLOR;
+ case TextureOp::SrcAlpha:
+ return GL_SRC_ALPHA;
+ case TextureOp::SrcColor:
+ return GL_SRC_COLOR;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+std::ostream &operator<<(std::ostream &os, TextureOp value)
+{
+ switch (value)
+ {
+ case TextureOp::OneMinusSrcAlpha:
+ os << "GL_ONE_MINUS_SRC_ALPHA";
+ break;
+ case TextureOp::OneMinusSrcColor:
+ os << "GL_ONE_MINUS_SRC_COLOR";
+ break;
+ case TextureOp::SrcAlpha:
+ os << "GL_SRC_ALPHA";
+ break;
+ case TextureOp::SrcColor:
+ os << "GL_SRC_COLOR";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+ return os;
+}
+
+template <>
+TextureSrc FromGLenum<TextureSrc>(GLenum from)
+{
+ switch (from)
+ {
+ case GL_CONSTANT:
+ return TextureSrc::Constant;
+ case GL_PREVIOUS:
+ return TextureSrc::Previous;
+ case GL_PRIMARY_COLOR:
+ return TextureSrc::PrimaryColor;
+ case GL_TEXTURE:
+ return TextureSrc::Texture;
+ default:
+ return TextureSrc::InvalidEnum;
+ }
+}
+
+GLenum ToGLenum(TextureSrc from)
+{
+ switch (from)
+ {
+ case TextureSrc::Constant:
+ return GL_CONSTANT;
+ case TextureSrc::Previous:
+ return GL_PREVIOUS;
+ case TextureSrc::PrimaryColor:
+ return GL_PRIMARY_COLOR;
+ case TextureSrc::Texture:
+ return GL_TEXTURE;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+std::ostream &operator<<(std::ostream &os, TextureSrc value)
+{
+ switch (value)
+ {
+ case TextureSrc::Constant:
+ os << "GL_CONSTANT";
+ break;
+ case TextureSrc::Previous:
+ os << "GL_PREVIOUS";
+ break;
+ case TextureSrc::PrimaryColor:
+ os << "GL_PRIMARY_COLOR";
+ break;
+ case TextureSrc::Texture:
+ os << "GL_TEXTURE";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+ return os;
+}
+
+template <>
+TextureTarget FromGLenum<TextureTarget>(GLenum from)
+{
+ switch (from)
+ {
+ case GL_TEXTURE_2D:
+ return TextureTarget::_2D;
+ case GL_TEXTURE_2D_ARRAY:
+ return TextureTarget::_2DArray;
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ return TextureTarget::_2DMultisample;
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES:
+ return TextureTarget::_2DMultisampleArray;
+ case GL_TEXTURE_3D:
+ return TextureTarget::_3D;
+ case GL_TEXTURE_EXTERNAL_OES:
+ return TextureTarget::External;
+ case GL_TEXTURE_RECTANGLE_ANGLE:
+ return TextureTarget::Rectangle;
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+ return TextureTarget::CubeMapPositiveX;
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+ return TextureTarget::CubeMapNegativeX;
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+ return TextureTarget::CubeMapPositiveY;
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ return TextureTarget::CubeMapNegativeY;
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+ return TextureTarget::CubeMapPositiveZ;
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ return TextureTarget::CubeMapNegativeZ;
+ case GL_TEXTURE_CUBE_MAP_ARRAY:
+ return TextureTarget::CubeMapArray;
+ case GL_TEXTURE_VIDEO_IMAGE_WEBGL:
+ return TextureTarget::VideoImage;
+ case GL_TEXTURE_BUFFER:
+ return TextureTarget::Buffer;
+ default:
+ return TextureTarget::InvalidEnum;
+ }
+}
+
+GLenum ToGLenum(TextureTarget from)
+{
+ switch (from)
+ {
+ case TextureTarget::_2D:
+ return GL_TEXTURE_2D;
+ case TextureTarget::_2DArray:
+ return GL_TEXTURE_2D_ARRAY;
+ case TextureTarget::_2DMultisample:
+ return GL_TEXTURE_2D_MULTISAMPLE;
+ case TextureTarget::_2DMultisampleArray:
+ return GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES;
+ case TextureTarget::_3D:
+ return GL_TEXTURE_3D;
+ case TextureTarget::External:
+ return GL_TEXTURE_EXTERNAL_OES;
+ case TextureTarget::Rectangle:
+ return GL_TEXTURE_RECTANGLE_ANGLE;
+ case TextureTarget::CubeMapPositiveX:
+ return GL_TEXTURE_CUBE_MAP_POSITIVE_X;
+ case TextureTarget::CubeMapNegativeX:
+ return GL_TEXTURE_CUBE_MAP_NEGATIVE_X;
+ case TextureTarget::CubeMapPositiveY:
+ return GL_TEXTURE_CUBE_MAP_POSITIVE_Y;
+ case TextureTarget::CubeMapNegativeY:
+ return GL_TEXTURE_CUBE_MAP_NEGATIVE_Y;
+ case TextureTarget::CubeMapPositiveZ:
+ return GL_TEXTURE_CUBE_MAP_POSITIVE_Z;
+ case TextureTarget::CubeMapNegativeZ:
+ return GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
+ case TextureTarget::CubeMapArray:
+ return GL_TEXTURE_CUBE_MAP_ARRAY;
+ case TextureTarget::VideoImage:
+ return GL_TEXTURE_VIDEO_IMAGE_WEBGL;
+ case TextureTarget::Buffer:
+ return GL_TEXTURE_BUFFER;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+std::ostream &operator<<(std::ostream &os, TextureTarget value)
+{
+ switch (value)
+ {
+ case TextureTarget::_2D:
+ os << "GL_TEXTURE_2D";
+ break;
+ case TextureTarget::_2DArray:
+ os << "GL_TEXTURE_2D_ARRAY";
+ break;
+ case TextureTarget::_2DMultisample:
+ os << "GL_TEXTURE_2D_MULTISAMPLE";
+ break;
+ case TextureTarget::_2DMultisampleArray:
+ os << "GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES";
+ break;
+ case TextureTarget::_3D:
+ os << "GL_TEXTURE_3D";
+ break;
+ case TextureTarget::External:
+ os << "GL_TEXTURE_EXTERNAL_OES";
+ break;
+ case TextureTarget::Rectangle:
+ os << "GL_TEXTURE_RECTANGLE_ANGLE";
+ break;
+ case TextureTarget::CubeMapPositiveX:
+ os << "GL_TEXTURE_CUBE_MAP_POSITIVE_X";
+ break;
+ case TextureTarget::CubeMapNegativeX:
+ os << "GL_TEXTURE_CUBE_MAP_NEGATIVE_X";
+ break;
+ case TextureTarget::CubeMapPositiveY:
+ os << "GL_TEXTURE_CUBE_MAP_POSITIVE_Y";
+ break;
+ case TextureTarget::CubeMapNegativeY:
+ os << "GL_TEXTURE_CUBE_MAP_NEGATIVE_Y";
+ break;
+ case TextureTarget::CubeMapPositiveZ:
+ os << "GL_TEXTURE_CUBE_MAP_POSITIVE_Z";
+ break;
+ case TextureTarget::CubeMapNegativeZ:
+ os << "GL_TEXTURE_CUBE_MAP_NEGATIVE_Z";
+ break;
+ case TextureTarget::CubeMapArray:
+ os << "GL_TEXTURE_CUBE_MAP_ARRAY";
+ break;
+ case TextureTarget::VideoImage:
+ os << "GL_TEXTURE_VIDEO_IMAGE_WEBGL";
+ break;
+ case TextureTarget::Buffer:
+ os << "GL_TEXTURE_BUFFER";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+ return os;
+}
+
+template <>
+TextureType FromGLenum<TextureType>(GLenum from)
+{
+ switch (from)
+ {
+ case GL_TEXTURE_2D:
+ return TextureType::_2D;
+ case GL_TEXTURE_2D_ARRAY:
+ return TextureType::_2DArray;
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ return TextureType::_2DMultisample;
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES:
+ return TextureType::_2DMultisampleArray;
+ case GL_TEXTURE_3D:
+ return TextureType::_3D;
+ case GL_TEXTURE_EXTERNAL_OES:
+ return TextureType::External;
+ case GL_TEXTURE_RECTANGLE_ANGLE:
+ return TextureType::Rectangle;
+ case GL_TEXTURE_CUBE_MAP:
+ return TextureType::CubeMap;
+ case GL_TEXTURE_CUBE_MAP_ARRAY:
+ return TextureType::CubeMapArray;
+ case GL_TEXTURE_VIDEO_IMAGE_WEBGL:
+ return TextureType::VideoImage;
+ case GL_TEXTURE_BUFFER:
+ return TextureType::Buffer;
+ default:
+ return TextureType::InvalidEnum;
+ }
+}
+
+GLenum ToGLenum(TextureType from)
+{
+ switch (from)
+ {
+ case TextureType::_2D:
+ return GL_TEXTURE_2D;
+ case TextureType::_2DArray:
+ return GL_TEXTURE_2D_ARRAY;
+ case TextureType::_2DMultisample:
+ return GL_TEXTURE_2D_MULTISAMPLE;
+ case TextureType::_2DMultisampleArray:
+ return GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES;
+ case TextureType::_3D:
+ return GL_TEXTURE_3D;
+ case TextureType::External:
+ return GL_TEXTURE_EXTERNAL_OES;
+ case TextureType::Rectangle:
+ return GL_TEXTURE_RECTANGLE_ANGLE;
+ case TextureType::CubeMap:
+ return GL_TEXTURE_CUBE_MAP;
+ case TextureType::CubeMapArray:
+ return GL_TEXTURE_CUBE_MAP_ARRAY;
+ case TextureType::VideoImage:
+ return GL_TEXTURE_VIDEO_IMAGE_WEBGL;
+ case TextureType::Buffer:
+ return GL_TEXTURE_BUFFER;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+std::ostream &operator<<(std::ostream &os, TextureType value)
+{
+ switch (value)
+ {
+ case TextureType::_2D:
+ os << "GL_TEXTURE_2D";
+ break;
+ case TextureType::_2DArray:
+ os << "GL_TEXTURE_2D_ARRAY";
+ break;
+ case TextureType::_2DMultisample:
+ os << "GL_TEXTURE_2D_MULTISAMPLE";
+ break;
+ case TextureType::_2DMultisampleArray:
+ os << "GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES";
+ break;
+ case TextureType::_3D:
+ os << "GL_TEXTURE_3D";
+ break;
+ case TextureType::External:
+ os << "GL_TEXTURE_EXTERNAL_OES";
+ break;
+ case TextureType::Rectangle:
+ os << "GL_TEXTURE_RECTANGLE_ANGLE";
+ break;
+ case TextureType::CubeMap:
+ os << "GL_TEXTURE_CUBE_MAP";
+ break;
+ case TextureType::CubeMapArray:
+ os << "GL_TEXTURE_CUBE_MAP_ARRAY";
+ break;
+ case TextureType::VideoImage:
+ os << "GL_TEXTURE_VIDEO_IMAGE_WEBGL";
+ break;
+ case TextureType::Buffer:
+ os << "GL_TEXTURE_BUFFER";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+ return os;
+}
+
+template <>
+VertexArrayType FromGLenum<VertexArrayType>(GLenum from)
+{
+ switch (from)
+ {
+ case GL_COLOR_ARRAY:
+ return VertexArrayType::Color;
+ case GL_NORMAL_ARRAY:
+ return VertexArrayType::Normal;
+ case GL_POINT_SIZE_ARRAY_OES:
+ return VertexArrayType::PointSize;
+ case GL_TEXTURE_COORD_ARRAY:
+ return VertexArrayType::TextureCoord;
+ case GL_VERTEX_ARRAY:
+ return VertexArrayType::Vertex;
+ default:
+ return VertexArrayType::InvalidEnum;
+ }
+}
+
+GLenum ToGLenum(VertexArrayType from)
+{
+ switch (from)
+ {
+ case VertexArrayType::Color:
+ return GL_COLOR_ARRAY;
+ case VertexArrayType::Normal:
+ return GL_NORMAL_ARRAY;
+ case VertexArrayType::PointSize:
+ return GL_POINT_SIZE_ARRAY_OES;
+ case VertexArrayType::TextureCoord:
+ return GL_TEXTURE_COORD_ARRAY;
+ case VertexArrayType::Vertex:
+ return GL_VERTEX_ARRAY;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+std::ostream &operator<<(std::ostream &os, VertexArrayType value)
+{
+ switch (value)
+ {
+ case VertexArrayType::Color:
+ os << "GL_COLOR_ARRAY";
+ break;
+ case VertexArrayType::Normal:
+ os << "GL_NORMAL_ARRAY";
+ break;
+ case VertexArrayType::PointSize:
+ os << "GL_POINT_SIZE_ARRAY_OES";
+ break;
+ case VertexArrayType::TextureCoord:
+ os << "GL_TEXTURE_COORD_ARRAY";
+ break;
+ case VertexArrayType::Vertex:
+ os << "GL_VERTEX_ARRAY";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+ return os;
+}
+
+template <>
+WrapMode FromGLenum<WrapMode>(GLenum from)
+{
+ switch (from)
+ {
+ case GL_CLAMP_TO_EDGE:
+ return WrapMode::ClampToEdge;
+ case GL_CLAMP_TO_BORDER:
+ return WrapMode::ClampToBorder;
+ case GL_MIRRORED_REPEAT:
+ return WrapMode::MirroredRepeat;
+ case GL_REPEAT:
+ return WrapMode::Repeat;
+ default:
+ return WrapMode::InvalidEnum;
+ }
+}
+
+GLenum ToGLenum(WrapMode from)
+{
+ switch (from)
+ {
+ case WrapMode::ClampToEdge:
+ return GL_CLAMP_TO_EDGE;
+ case WrapMode::ClampToBorder:
+ return GL_CLAMP_TO_BORDER;
+ case WrapMode::MirroredRepeat:
+ return GL_MIRRORED_REPEAT;
+ case WrapMode::Repeat:
+ return GL_REPEAT;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+std::ostream &operator<<(std::ostream &os, WrapMode value)
+{
+ switch (value)
+ {
+ case WrapMode::ClampToEdge:
+ os << "GL_CLAMP_TO_EDGE";
+ break;
+ case WrapMode::ClampToBorder:
+ os << "GL_CLAMP_TO_BORDER";
+ break;
+ case WrapMode::MirroredRepeat:
+ os << "GL_MIRRORED_REPEAT";
+ break;
+ case WrapMode::Repeat:
+ os << "GL_REPEAT";
+ break;
+ default:
+ os << "GL_INVALID_ENUM";
+ break;
+ }
+ return os;
+}
+
+} // namespace gl
diff --git a/gfx/angle/checkout/src/common/PackedGLEnums_autogen.h b/gfx/angle/checkout/src/common/PackedGLEnums_autogen.h
new file mode 100644
index 0000000000..452dca344e
--- /dev/null
+++ b/gfx/angle/checkout/src/common/PackedGLEnums_autogen.h
@@ -0,0 +1,610 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_packed_gl_enums.py using data from packed_gl_enums.json.
+//
+// Copyright 2017 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.
+//
+// PackedGLEnums_autogen.h:
+// Declares ANGLE-specific enums classes for GLenums and functions operating
+// on them.
+
+#ifndef COMMON_PACKEDGLENUMS_AUTOGEN_H_
+#define COMMON_PACKEDGLENUMS_AUTOGEN_H_
+
+#include <angle_gl.h>
+
+#include <cstdint>
+#include <ostream>
+
+namespace gl
+{
+
+template <typename Enum>
+Enum FromGLenum(GLenum from);
+
+enum class AlphaTestFunc : uint8_t
+{
+ AlwaysPass = 0,
+ Equal = 1,
+ Gequal = 2,
+ Greater = 3,
+ Lequal = 4,
+ Less = 5,
+ Never = 6,
+ NotEqual = 7,
+
+ InvalidEnum = 8,
+ EnumCount = 8,
+};
+
+template <>
+AlphaTestFunc FromGLenum<AlphaTestFunc>(GLenum from);
+GLenum ToGLenum(AlphaTestFunc from);
+std::ostream &operator<<(std::ostream &os, AlphaTestFunc value);
+
+enum class BufferBinding : uint8_t
+{
+ Array = 0,
+ AtomicCounter = 1,
+ CopyRead = 2,
+ CopyWrite = 3,
+ DispatchIndirect = 4,
+ DrawIndirect = 5,
+ ElementArray = 6,
+ PixelPack = 7,
+ PixelUnpack = 8,
+ ShaderStorage = 9,
+ Texture = 10,
+ TransformFeedback = 11,
+ Uniform = 12,
+
+ InvalidEnum = 13,
+ EnumCount = 13,
+};
+
+template <>
+BufferBinding FromGLenum<BufferBinding>(GLenum from);
+GLenum ToGLenum(BufferBinding from);
+std::ostream &operator<<(std::ostream &os, BufferBinding value);
+
+enum class BufferUsage : uint8_t
+{
+ DynamicCopy = 0,
+ DynamicDraw = 1,
+ DynamicRead = 2,
+ StaticCopy = 3,
+ StaticDraw = 4,
+ StaticRead = 5,
+ StreamCopy = 6,
+ StreamDraw = 7,
+ StreamRead = 8,
+
+ InvalidEnum = 9,
+ EnumCount = 9,
+};
+
+template <>
+BufferUsage FromGLenum<BufferUsage>(GLenum from);
+GLenum ToGLenum(BufferUsage from);
+std::ostream &operator<<(std::ostream &os, BufferUsage value);
+
+enum class ClientVertexArrayType : uint8_t
+{
+ Color = 0,
+ Normal = 1,
+ PointSize = 2,
+ TextureCoord = 3,
+ Vertex = 4,
+
+ InvalidEnum = 5,
+ EnumCount = 5,
+};
+
+template <>
+ClientVertexArrayType FromGLenum<ClientVertexArrayType>(GLenum from);
+GLenum ToGLenum(ClientVertexArrayType from);
+std::ostream &operator<<(std::ostream &os, ClientVertexArrayType value);
+
+enum class CullFaceMode : uint8_t
+{
+ Back = 0,
+ Front = 1,
+ FrontAndBack = 2,
+
+ InvalidEnum = 3,
+ EnumCount = 3,
+};
+
+template <>
+CullFaceMode FromGLenum<CullFaceMode>(GLenum from);
+GLenum ToGLenum(CullFaceMode from);
+std::ostream &operator<<(std::ostream &os, CullFaceMode value);
+
+enum class FilterMode : uint8_t
+{
+ Nearest = 0,
+ Linear = 1,
+ NearestMipmapNearest = 2,
+ NearestMipmapLinear = 3,
+ LinearMipmapLinear = 4,
+
+ InvalidEnum = 5,
+ EnumCount = 5,
+};
+
+template <>
+FilterMode FromGLenum<FilterMode>(GLenum from);
+GLenum ToGLenum(FilterMode from);
+std::ostream &operator<<(std::ostream &os, FilterMode value);
+
+enum class FogMode : uint8_t
+{
+ Exp = 0,
+ Exp2 = 1,
+ Linear = 2,
+
+ InvalidEnum = 3,
+ EnumCount = 3,
+};
+
+template <>
+FogMode FromGLenum<FogMode>(GLenum from);
+GLenum ToGLenum(FogMode from);
+std::ostream &operator<<(std::ostream &os, FogMode value);
+
+enum class GraphicsResetStatus : uint8_t
+{
+ NoError = 0,
+ GuiltyContextReset = 1,
+ InnocentContextReset = 2,
+ UnknownContextReset = 3,
+ PurgedContextResetNV = 4,
+
+ InvalidEnum = 5,
+ EnumCount = 5,
+};
+
+template <>
+GraphicsResetStatus FromGLenum<GraphicsResetStatus>(GLenum from);
+GLenum ToGLenum(GraphicsResetStatus from);
+std::ostream &operator<<(std::ostream &os, GraphicsResetStatus value);
+
+enum class HandleType : uint8_t
+{
+ OpaqueFd = 0,
+ ZirconVmo = 1,
+ ZirconEvent = 2,
+
+ InvalidEnum = 3,
+ EnumCount = 3,
+};
+
+template <>
+HandleType FromGLenum<HandleType>(GLenum from);
+GLenum ToGLenum(HandleType from);
+std::ostream &operator<<(std::ostream &os, HandleType value);
+
+enum class HintSetting : uint8_t
+{
+ DontCare = 0,
+ Fastest = 1,
+ Nicest = 2,
+
+ InvalidEnum = 3,
+ EnumCount = 3,
+};
+
+template <>
+HintSetting FromGLenum<HintSetting>(GLenum from);
+GLenum ToGLenum(HintSetting from);
+std::ostream &operator<<(std::ostream &os, HintSetting value);
+
+enum class ImageLayout : uint8_t
+{
+ Undefined = 0,
+ General = 1,
+ ColorAttachment = 2,
+ DepthStencilAttachment = 3,
+ DepthStencilReadOnlyAttachment = 4,
+ ShaderReadOnly = 5,
+ TransferSrc = 6,
+ TransferDst = 7,
+ DepthReadOnlyStencilAttachment = 8,
+ DepthAttachmentStencilReadOnly = 9,
+
+ InvalidEnum = 10,
+ EnumCount = 10,
+};
+
+template <>
+ImageLayout FromGLenum<ImageLayout>(GLenum from);
+GLenum ToGLenum(ImageLayout from);
+std::ostream &operator<<(std::ostream &os, ImageLayout value);
+
+enum class LightParameter : uint8_t
+{
+ Ambient = 0,
+ AmbientAndDiffuse = 1,
+ ConstantAttenuation = 2,
+ Diffuse = 3,
+ LinearAttenuation = 4,
+ Position = 5,
+ QuadraticAttenuation = 6,
+ Specular = 7,
+ SpotCutoff = 8,
+ SpotDirection = 9,
+ SpotExponent = 10,
+
+ InvalidEnum = 11,
+ EnumCount = 11,
+};
+
+template <>
+LightParameter FromGLenum<LightParameter>(GLenum from);
+GLenum ToGLenum(LightParameter from);
+std::ostream &operator<<(std::ostream &os, LightParameter value);
+
+enum class LogicalOperation : uint8_t
+{
+ And = 0,
+ AndInverted = 1,
+ AndReverse = 2,
+ Clear = 3,
+ Copy = 4,
+ CopyInverted = 5,
+ Equiv = 6,
+ Invert = 7,
+ Nand = 8,
+ Noop = 9,
+ Nor = 10,
+ Or = 11,
+ OrInverted = 12,
+ OrReverse = 13,
+ Set = 14,
+ Xor = 15,
+
+ InvalidEnum = 16,
+ EnumCount = 16,
+};
+
+template <>
+LogicalOperation FromGLenum<LogicalOperation>(GLenum from);
+GLenum ToGLenum(LogicalOperation from);
+std::ostream &operator<<(std::ostream &os, LogicalOperation value);
+
+enum class MaterialParameter : uint8_t
+{
+ Ambient = 0,
+ AmbientAndDiffuse = 1,
+ Diffuse = 2,
+ Emission = 3,
+ Shininess = 4,
+ Specular = 5,
+
+ InvalidEnum = 6,
+ EnumCount = 6,
+};
+
+template <>
+MaterialParameter FromGLenum<MaterialParameter>(GLenum from);
+GLenum ToGLenum(MaterialParameter from);
+std::ostream &operator<<(std::ostream &os, MaterialParameter value);
+
+enum class MatrixType : uint8_t
+{
+ Modelview = 0,
+ Projection = 1,
+ Texture = 2,
+
+ InvalidEnum = 3,
+ EnumCount = 3,
+};
+
+template <>
+MatrixType FromGLenum<MatrixType>(GLenum from);
+GLenum ToGLenum(MatrixType from);
+std::ostream &operator<<(std::ostream &os, MatrixType value);
+
+enum class PointParameter : uint8_t
+{
+ PointSizeMin = 0,
+ PointSizeMax = 1,
+ PointFadeThresholdSize = 2,
+ PointDistanceAttenuation = 3,
+
+ InvalidEnum = 4,
+ EnumCount = 4,
+};
+
+template <>
+PointParameter FromGLenum<PointParameter>(GLenum from);
+GLenum ToGLenum(PointParameter from);
+std::ostream &operator<<(std::ostream &os, PointParameter value);
+
+enum class ProvokingVertexConvention : uint8_t
+{
+ FirstVertexConvention = 0,
+ LastVertexConvention = 1,
+
+ InvalidEnum = 2,
+ EnumCount = 2,
+};
+
+template <>
+ProvokingVertexConvention FromGLenum<ProvokingVertexConvention>(GLenum from);
+GLenum ToGLenum(ProvokingVertexConvention from);
+std::ostream &operator<<(std::ostream &os, ProvokingVertexConvention value);
+
+enum class QueryType : uint8_t
+{
+ AnySamples = 0,
+ AnySamplesConservative = 1,
+ CommandsCompleted = 2,
+ PrimitivesGenerated = 3,
+ TimeElapsed = 4,
+ Timestamp = 5,
+ TransformFeedbackPrimitivesWritten = 6,
+
+ InvalidEnum = 7,
+ EnumCount = 7,
+};
+
+template <>
+QueryType FromGLenum<QueryType>(GLenum from);
+GLenum ToGLenum(QueryType from);
+std::ostream &operator<<(std::ostream &os, QueryType value);
+
+enum class ShaderType : uint8_t
+{
+ Vertex = 0,
+ TessControl = 1,
+ TessEvaluation = 2,
+ Geometry = 3,
+ Fragment = 4,
+ Compute = 5,
+
+ InvalidEnum = 6,
+ EnumCount = 6,
+};
+
+template <>
+ShaderType FromGLenum<ShaderType>(GLenum from);
+GLenum ToGLenum(ShaderType from);
+std::ostream &operator<<(std::ostream &os, ShaderType value);
+
+enum class ShadingModel : uint8_t
+{
+ Flat = 0,
+ Smooth = 1,
+
+ InvalidEnum = 2,
+ EnumCount = 2,
+};
+
+template <>
+ShadingModel FromGLenum<ShadingModel>(GLenum from);
+GLenum ToGLenum(ShadingModel from);
+std::ostream &operator<<(std::ostream &os, ShadingModel value);
+
+enum class ShadingRate : uint8_t
+{
+ Undefined = 0,
+ _1x1 = 1,
+ _1x2 = 2,
+ _2x1 = 3,
+ _2x2 = 4,
+ _4x2 = 5,
+ _4x4 = 6,
+
+ InvalidEnum = 7,
+ EnumCount = 7,
+};
+
+template <>
+ShadingRate FromGLenum<ShadingRate>(GLenum from);
+GLenum ToGLenum(ShadingRate from);
+std::ostream &operator<<(std::ostream &os, ShadingRate value);
+
+enum class TextureCombine : uint8_t
+{
+ Add = 0,
+ AddSigned = 1,
+ Dot3Rgb = 2,
+ Dot3Rgba = 3,
+ Interpolate = 4,
+ Modulate = 5,
+ Replace = 6,
+ Subtract = 7,
+
+ InvalidEnum = 8,
+ EnumCount = 8,
+};
+
+template <>
+TextureCombine FromGLenum<TextureCombine>(GLenum from);
+GLenum ToGLenum(TextureCombine from);
+std::ostream &operator<<(std::ostream &os, TextureCombine value);
+
+enum class TextureEnvMode : uint8_t
+{
+ Add = 0,
+ Blend = 1,
+ Combine = 2,
+ Decal = 3,
+ Modulate = 4,
+ Replace = 5,
+
+ InvalidEnum = 6,
+ EnumCount = 6,
+};
+
+template <>
+TextureEnvMode FromGLenum<TextureEnvMode>(GLenum from);
+GLenum ToGLenum(TextureEnvMode from);
+std::ostream &operator<<(std::ostream &os, TextureEnvMode value);
+
+enum class TextureEnvParameter : uint8_t
+{
+ Mode = 0,
+ Color = 1,
+ CombineRgb = 2,
+ CombineAlpha = 3,
+ RgbScale = 4,
+ AlphaScale = 5,
+ Src0Rgb = 6,
+ Src1Rgb = 7,
+ Src2Rgb = 8,
+ Src0Alpha = 9,
+ Src1Alpha = 10,
+ Src2Alpha = 11,
+ Op0Rgb = 12,
+ Op1Rgb = 13,
+ Op2Rgb = 14,
+ Op0Alpha = 15,
+ Op1Alpha = 16,
+ Op2Alpha = 17,
+ PointCoordReplace = 18,
+
+ InvalidEnum = 19,
+ EnumCount = 19,
+};
+
+template <>
+TextureEnvParameter FromGLenum<TextureEnvParameter>(GLenum from);
+GLenum ToGLenum(TextureEnvParameter from);
+std::ostream &operator<<(std::ostream &os, TextureEnvParameter value);
+
+enum class TextureEnvTarget : uint8_t
+{
+ Env = 0,
+ PointSprite = 1,
+
+ InvalidEnum = 2,
+ EnumCount = 2,
+};
+
+template <>
+TextureEnvTarget FromGLenum<TextureEnvTarget>(GLenum from);
+GLenum ToGLenum(TextureEnvTarget from);
+std::ostream &operator<<(std::ostream &os, TextureEnvTarget value);
+
+enum class TextureOp : uint8_t
+{
+ OneMinusSrcAlpha = 0,
+ OneMinusSrcColor = 1,
+ SrcAlpha = 2,
+ SrcColor = 3,
+
+ InvalidEnum = 4,
+ EnumCount = 4,
+};
+
+template <>
+TextureOp FromGLenum<TextureOp>(GLenum from);
+GLenum ToGLenum(TextureOp from);
+std::ostream &operator<<(std::ostream &os, TextureOp value);
+
+enum class TextureSrc : uint8_t
+{
+ Constant = 0,
+ Previous = 1,
+ PrimaryColor = 2,
+ Texture = 3,
+
+ InvalidEnum = 4,
+ EnumCount = 4,
+};
+
+template <>
+TextureSrc FromGLenum<TextureSrc>(GLenum from);
+GLenum ToGLenum(TextureSrc from);
+std::ostream &operator<<(std::ostream &os, TextureSrc value);
+
+enum class TextureTarget : uint8_t
+{
+ _2D = 0,
+ _2DArray = 1,
+ _2DMultisample = 2,
+ _2DMultisampleArray = 3,
+ _3D = 4,
+ External = 5,
+ Rectangle = 6,
+ CubeMapPositiveX = 7,
+ CubeMapNegativeX = 8,
+ CubeMapPositiveY = 9,
+ CubeMapNegativeY = 10,
+ CubeMapPositiveZ = 11,
+ CubeMapNegativeZ = 12,
+ CubeMapArray = 13,
+ VideoImage = 14,
+ Buffer = 15,
+
+ InvalidEnum = 16,
+ EnumCount = 16,
+};
+
+template <>
+TextureTarget FromGLenum<TextureTarget>(GLenum from);
+GLenum ToGLenum(TextureTarget from);
+std::ostream &operator<<(std::ostream &os, TextureTarget value);
+
+enum class TextureType : uint8_t
+{
+ _2D = 0,
+ _2DArray = 1,
+ _2DMultisample = 2,
+ _2DMultisampleArray = 3,
+ _3D = 4,
+ External = 5,
+ Rectangle = 6,
+ CubeMap = 7,
+ CubeMapArray = 8,
+ VideoImage = 9,
+ Buffer = 10,
+
+ InvalidEnum = 11,
+ EnumCount = 11,
+};
+
+template <>
+TextureType FromGLenum<TextureType>(GLenum from);
+GLenum ToGLenum(TextureType from);
+std::ostream &operator<<(std::ostream &os, TextureType value);
+
+enum class VertexArrayType : uint8_t
+{
+ Color = 0,
+ Normal = 1,
+ PointSize = 2,
+ TextureCoord = 3,
+ Vertex = 4,
+
+ InvalidEnum = 5,
+ EnumCount = 5,
+};
+
+template <>
+VertexArrayType FromGLenum<VertexArrayType>(GLenum from);
+GLenum ToGLenum(VertexArrayType from);
+std::ostream &operator<<(std::ostream &os, VertexArrayType value);
+
+enum class WrapMode : uint8_t
+{
+ ClampToEdge = 0,
+ ClampToBorder = 1,
+ MirroredRepeat = 2,
+ Repeat = 3,
+
+ InvalidEnum = 4,
+ EnumCount = 4,
+};
+
+template <>
+WrapMode FromGLenum<WrapMode>(GLenum from);
+GLenum ToGLenum(WrapMode from);
+std::ostream &operator<<(std::ostream &os, WrapMode value);
+
+} // namespace gl
+
+#endif // COMMON_PACKEDGLENUMS_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/common/PoolAlloc.cpp b/gfx/angle/checkout/src/common/PoolAlloc.cpp
new file mode 100644
index 0000000000..eef033ca04
--- /dev/null
+++ b/gfx/angle/checkout/src/common/PoolAlloc.cpp
@@ -0,0 +1,487 @@
+//
+// Copyright 2019 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.
+//
+// PoolAlloc.cpp:
+// Implements the class methods for PoolAllocator and Allocation classes.
+//
+
+#include "common/PoolAlloc.h"
+
+#include <assert.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#include "common/angleutils.h"
+#include "common/debug.h"
+#include "common/mathutil.h"
+#include "common/platform.h"
+#include "common/tls.h"
+
+namespace angle
+{
+// If we are using guard blocks, we must track each individual allocation. If we aren't using guard
+// blocks, these never get instantiated, so won't have any impact.
+
+class Allocation
+{
+ public:
+ Allocation(size_t size, unsigned char *mem, Allocation *prev = 0)
+ : mSize(size), mMem(mem), mPrevAlloc(prev)
+ {
+ // Allocations are bracketed:
+ //
+ // [allocationHeader][initialGuardBlock][userData][finalGuardBlock]
+ //
+ // This would be cleaner with if (kGuardBlockSize)..., but that makes the compiler print
+ // warnings about 0 length memsets, even with the if() protecting them.
+#if defined(ANGLE_POOL_ALLOC_GUARD_BLOCKS)
+ memset(preGuard(), kGuardBlockBeginVal, kGuardBlockSize);
+ memset(data(), kUserDataFill, mSize);
+ memset(postGuard(), kGuardBlockEndVal, kGuardBlockSize);
+#endif
+ }
+
+ void checkAllocList() const;
+
+ static size_t AlignedHeaderSize(uint8_t *allocationBasePtr, size_t alignment)
+ {
+ // Make sure that the data offset after the header is aligned to the given alignment.
+ size_t base = reinterpret_cast<size_t>(allocationBasePtr);
+ return rx::roundUpPow2(base + kGuardBlockSize + HeaderSize(), alignment) - base;
+ }
+
+ // Return total size needed to accommodate user buffer of 'size',
+ // plus our tracking data and any necessary alignments.
+ static size_t AllocationSize(uint8_t *allocationBasePtr,
+ size_t size,
+ size_t alignment,
+ size_t *preAllocationPaddingOut)
+ {
+ // The allocation will be laid out as such:
+ //
+ // Aligned to |alignment|
+ // ^
+ // preAllocationPaddingOut |
+ // ___^___ |
+ // / \ |
+ // <padding>[header][guard][data][guard]
+ // \___________ __________/
+ // V
+ // dataOffset
+ //
+ // Note that alignment is at least as much as a pointer alignment, so the pointers in the
+ // header are also necessarily aligned appropriately.
+ //
+ size_t dataOffset = AlignedHeaderSize(allocationBasePtr, alignment);
+ *preAllocationPaddingOut = dataOffset - HeaderSize() - kGuardBlockSize;
+
+ return dataOffset + size + kGuardBlockSize;
+ }
+
+ // Given memory pointing to |header|, returns |data|.
+ static uint8_t *GetDataPointer(uint8_t *memory, size_t alignment)
+ {
+ uint8_t *alignedPtr = memory + kGuardBlockSize + HeaderSize();
+
+ // |memory| must be aligned already such that user data is aligned to |alignment|.
+ ASSERT((reinterpret_cast<uintptr_t>(alignedPtr) & (alignment - 1)) == 0);
+
+ return alignedPtr;
+ }
+
+ private:
+ void checkGuardBlock(unsigned char *blockMem, unsigned char val, const char *locText) const;
+
+ void checkAlloc() const
+ {
+ checkGuardBlock(preGuard(), kGuardBlockBeginVal, "before");
+ checkGuardBlock(postGuard(), kGuardBlockEndVal, "after");
+ }
+
+ // Find offsets to pre and post guard blocks, and user data buffer
+ unsigned char *preGuard() const { return mMem + HeaderSize(); }
+ unsigned char *data() const { return preGuard() + kGuardBlockSize; }
+ unsigned char *postGuard() const { return data() + mSize; }
+ size_t mSize; // size of the user data area
+ unsigned char *mMem; // beginning of our allocation (points to header)
+ Allocation *mPrevAlloc; // prior allocation in the chain
+
+ static constexpr unsigned char kGuardBlockBeginVal = 0xfb;
+ static constexpr unsigned char kGuardBlockEndVal = 0xfe;
+ static constexpr unsigned char kUserDataFill = 0xcd;
+#if defined(ANGLE_POOL_ALLOC_GUARD_BLOCKS)
+ static constexpr size_t kGuardBlockSize = 16;
+ static constexpr size_t HeaderSize() { return sizeof(Allocation); }
+#else
+ static constexpr size_t kGuardBlockSize = 0;
+ static constexpr size_t HeaderSize() { return 0; }
+#endif
+};
+
+#if !defined(ANGLE_DISABLE_POOL_ALLOC)
+class PageHeader
+{
+ public:
+ PageHeader(PageHeader *nextPage, size_t pageCount)
+ : nextPage(nextPage),
+ pageCount(pageCount)
+# if defined(ANGLE_POOL_ALLOC_GUARD_BLOCKS)
+ ,
+ lastAllocation(nullptr)
+# endif
+ {}
+
+ ~PageHeader()
+ {
+# if defined(ANGLE_POOL_ALLOC_GUARD_BLOCKS)
+ if (lastAllocation)
+ {
+ lastAllocation->checkAllocList();
+ }
+# endif
+ }
+
+ PageHeader *nextPage;
+ size_t pageCount;
+# if defined(ANGLE_POOL_ALLOC_GUARD_BLOCKS)
+ Allocation *lastAllocation;
+# endif
+};
+#endif
+
+//
+// Implement the functionality of the PoolAllocator class, which
+// is documented in PoolAlloc.h.
+//
+PoolAllocator::PoolAllocator(int growthIncrement, int allocationAlignment)
+ : mAlignment(allocationAlignment),
+#if !defined(ANGLE_DISABLE_POOL_ALLOC)
+ mPageSize(growthIncrement),
+ mFreeList(nullptr),
+ mInUseList(nullptr),
+ mNumCalls(0),
+ mTotalBytes(0),
+#endif
+ mLocked(false)
+{
+ initialize(growthIncrement, allocationAlignment);
+}
+
+void PoolAllocator::initialize(int pageSize, int alignment)
+{
+ mAlignment = alignment;
+#if !defined(ANGLE_DISABLE_POOL_ALLOC)
+ mPageSize = pageSize;
+ mPageHeaderSkip = sizeof(PageHeader);
+
+ // Alignment == 1 is a special fast-path where fastAllocate() is enabled
+ if (mAlignment != 1)
+ {
+#endif
+ // Adjust mAlignment to be at least pointer aligned and
+ // power of 2.
+ //
+ size_t minAlign = sizeof(void *);
+ if (mAlignment < minAlign)
+ {
+ mAlignment = minAlign;
+ }
+ mAlignment = gl::ceilPow2(static_cast<unsigned int>(mAlignment));
+#if !defined(ANGLE_DISABLE_POOL_ALLOC)
+ }
+ //
+ // Don't allow page sizes we know are smaller than all common
+ // OS page sizes.
+ //
+ if (mPageSize < 4 * 1024)
+ {
+ mPageSize = 4 * 1024;
+ }
+
+ //
+ // A large mCurrentPageOffset indicates a new page needs to
+ // be obtained to allocate memory.
+ //
+ mCurrentPageOffset = mPageSize;
+
+#else // !defined(ANGLE_DISABLE_POOL_ALLOC)
+ mStack.push_back({});
+#endif
+}
+
+PoolAllocator::~PoolAllocator()
+{
+#if !defined(ANGLE_DISABLE_POOL_ALLOC)
+ while (mInUseList)
+ {
+ PageHeader *next = mInUseList->nextPage;
+ mInUseList->~PageHeader();
+ delete[] reinterpret_cast<char *>(mInUseList);
+ mInUseList = next;
+ }
+ // We should not check the guard blocks
+ // here, because we did it already when the block was
+ // placed into the free list.
+ //
+ while (mFreeList)
+ {
+ PageHeader *next = mFreeList->nextPage;
+ delete[] reinterpret_cast<char *>(mFreeList);
+ mFreeList = next;
+ }
+#else // !defined(ANGLE_DISABLE_POOL_ALLOC)
+ for (auto &allocs : mStack)
+ {
+ for (auto alloc : allocs)
+ {
+ free(alloc);
+ }
+ }
+ mStack.clear();
+#endif
+}
+
+//
+// Check a single guard block for damage
+//
+void Allocation::checkGuardBlock(unsigned char *blockMem,
+ unsigned char val,
+ const char *locText) const
+{
+#if defined(ANGLE_POOL_ALLOC_GUARD_BLOCKS)
+ for (size_t x = 0; x < kGuardBlockSize; x++)
+ {
+ if (blockMem[x] != val)
+ {
+ char assertMsg[80];
+ // We don't print the assert message. It's here just to be helpful.
+ snprintf(assertMsg, sizeof(assertMsg),
+ "PoolAlloc: Damage %s %zu byte allocation at 0x%p\n", locText, mSize, data());
+ assert(0 && "PoolAlloc: Damage in guard block");
+ }
+ }
+#endif
+}
+
+void PoolAllocator::push()
+{
+#if !defined(ANGLE_DISABLE_POOL_ALLOC)
+ AllocState state = {mCurrentPageOffset, mInUseList};
+
+ mStack.push_back(state);
+
+ //
+ // Indicate there is no current page to allocate from.
+ //
+ mCurrentPageOffset = mPageSize;
+#else // !defined(ANGLE_DISABLE_POOL_ALLOC)
+ mStack.push_back({});
+#endif
+}
+
+// Do a mass-deallocation of all the individual allocations that have occurred since the last
+// push(), or since the last pop(), or since the object's creation.
+//
+// The deallocated pages are saved for future allocations.
+void PoolAllocator::pop()
+{
+ if (mStack.size() < 1)
+ {
+ return;
+ }
+
+#if !defined(ANGLE_DISABLE_POOL_ALLOC)
+ PageHeader *page = mStack.back().page;
+ mCurrentPageOffset = mStack.back().offset;
+
+ while (mInUseList != page)
+ {
+ // invoke destructor to free allocation list
+ mInUseList->~PageHeader();
+
+ PageHeader *nextInUse = mInUseList->nextPage;
+ if (mInUseList->pageCount > 1)
+ {
+ delete[] reinterpret_cast<char *>(mInUseList);
+ }
+ else
+ {
+ mInUseList->nextPage = mFreeList;
+ mFreeList = mInUseList;
+ }
+ mInUseList = nextInUse;
+ }
+
+ mStack.pop_back();
+#else // !defined(ANGLE_DISABLE_POOL_ALLOC)
+ for (auto &alloc : mStack.back())
+ {
+ free(alloc);
+ }
+ mStack.pop_back();
+#endif
+}
+
+//
+// Do a mass-deallocation of all the individual allocations
+// that have occurred.
+//
+void PoolAllocator::popAll()
+{
+ while (mStack.size() > 0)
+ pop();
+}
+
+void *PoolAllocator::allocate(size_t numBytes)
+{
+ ASSERT(!mLocked);
+
+#if !defined(ANGLE_DISABLE_POOL_ALLOC)
+ //
+ // Just keep some interesting statistics.
+ //
+ ++mNumCalls;
+ mTotalBytes += numBytes;
+
+ uint8_t *currentPagePtr = reinterpret_cast<uint8_t *>(mInUseList) + mCurrentPageOffset;
+
+ size_t preAllocationPadding = 0;
+ size_t allocationSize =
+ Allocation::AllocationSize(currentPagePtr, numBytes, mAlignment, &preAllocationPadding);
+
+ // Integer overflow is unexpected.
+ ASSERT(allocationSize >= numBytes);
+
+ // Do the allocation, most likely case first, for efficiency.
+ if (allocationSize <= mPageSize - mCurrentPageOffset)
+ {
+ // There is enough room to allocate from the current page at mCurrentPageOffset.
+ uint8_t *memory = currentPagePtr + preAllocationPadding;
+ mCurrentPageOffset += allocationSize;
+
+ return initializeAllocation(memory, numBytes);
+ }
+
+ if (allocationSize > mPageSize - mPageHeaderSkip)
+ {
+ // If the allocation is larger than a whole page, do a multi-page allocation. These are not
+ // mixed with the others. The OS is efficient in allocating and freeing multiple pages.
+
+ // We don't know what the alignment of the new allocated memory will be, so conservatively
+ // allocate enough memory for up to alignment extra bytes being needed.
+ allocationSize = Allocation::AllocationSize(reinterpret_cast<uint8_t *>(mPageHeaderSkip),
+ numBytes, mAlignment, &preAllocationPadding);
+
+ size_t numBytesToAlloc = allocationSize + mPageHeaderSkip + mAlignment;
+
+ // Integer overflow is unexpected.
+ ASSERT(numBytesToAlloc >= allocationSize);
+
+ PageHeader *memory = reinterpret_cast<PageHeader *>(::new char[numBytesToAlloc]);
+ if (memory == nullptr)
+ {
+ return nullptr;
+ }
+
+ // Use placement-new to initialize header
+ new (memory) PageHeader(mInUseList, (numBytesToAlloc + mPageSize - 1) / mPageSize);
+ mInUseList = memory;
+
+ // Make next allocation come from a new page
+ mCurrentPageOffset = mPageSize;
+
+ // Now that we actually have the pointer, make sure the data pointer will be aligned.
+ currentPagePtr = reinterpret_cast<uint8_t *>(memory) + mPageHeaderSkip;
+ Allocation::AllocationSize(currentPagePtr, numBytes, mAlignment, &preAllocationPadding);
+
+ return initializeAllocation(currentPagePtr + preAllocationPadding, numBytes);
+ }
+
+ uint8_t *newPageAddr = allocateNewPage(numBytes);
+ return initializeAllocation(newPageAddr, numBytes);
+
+#else // !defined(ANGLE_DISABLE_POOL_ALLOC)
+
+ void *alloc = malloc(numBytes + mAlignment - 1);
+ mStack.back().push_back(alloc);
+
+ intptr_t intAlloc = reinterpret_cast<intptr_t>(alloc);
+ intAlloc = rx::roundUpPow2<intptr_t>(intAlloc, mAlignment);
+ return reinterpret_cast<void *>(intAlloc);
+#endif
+}
+
+#if !defined(ANGLE_DISABLE_POOL_ALLOC)
+uint8_t *PoolAllocator::allocateNewPage(size_t numBytes)
+{
+ // Need a simple page to allocate from. Pick a page from the free list, if any. Otherwise need
+ // to make the allocation.
+ PageHeader *memory;
+ if (mFreeList)
+ {
+ memory = mFreeList;
+ mFreeList = mFreeList->nextPage;
+ }
+ else
+ {
+ memory = reinterpret_cast<PageHeader *>(::new char[mPageSize]);
+ if (memory == nullptr)
+ {
+ return nullptr;
+ }
+ }
+ // Use placement-new to initialize header
+ new (memory) PageHeader(mInUseList, 1);
+ mInUseList = memory;
+
+ // Leave room for the page header.
+ mCurrentPageOffset = mPageHeaderSkip;
+ uint8_t *currentPagePtr = reinterpret_cast<uint8_t *>(mInUseList) + mCurrentPageOffset;
+
+ size_t preAllocationPadding = 0;
+ size_t allocationSize =
+ Allocation::AllocationSize(currentPagePtr, numBytes, mAlignment, &preAllocationPadding);
+
+ mCurrentPageOffset += allocationSize;
+
+ // The new allocation is made after the page header and any alignment required before it.
+ return reinterpret_cast<uint8_t *>(mInUseList) + mPageHeaderSkip + preAllocationPadding;
+}
+
+void *PoolAllocator::initializeAllocation(uint8_t *memory, size_t numBytes)
+{
+# if defined(ANGLE_POOL_ALLOC_GUARD_BLOCKS)
+ new (memory) Allocation(numBytes, memory, mInUseList->lastAllocation);
+ mInUseList->lastAllocation = reinterpret_cast<Allocation *>(memory);
+# endif
+
+ return Allocation::GetDataPointer(memory, mAlignment);
+}
+#endif
+
+void PoolAllocator::lock()
+{
+ ASSERT(!mLocked);
+ mLocked = true;
+}
+
+void PoolAllocator::unlock()
+{
+ ASSERT(mLocked);
+ mLocked = false;
+}
+
+//
+// Check all allocations in a list for damage by calling check on each.
+//
+void Allocation::checkAllocList() const
+{
+ for (const Allocation *alloc = this; alloc != nullptr; alloc = alloc->mPrevAlloc)
+ {
+ alloc->checkAlloc();
+ }
+}
+
+} // namespace angle
diff --git a/gfx/angle/checkout/src/common/PoolAlloc.h b/gfx/angle/checkout/src/common/PoolAlloc.h
new file mode 100644
index 0000000000..536848f198
--- /dev/null
+++ b/gfx/angle/checkout/src/common/PoolAlloc.h
@@ -0,0 +1,181 @@
+//
+// Copyright 2019 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.
+//
+// PoolAlloc.h:
+// Defines the class interface for PoolAllocator.
+//
+
+#ifndef COMMON_POOLALLOC_H_
+#define COMMON_POOLALLOC_H_
+
+#if !defined(NDEBUG)
+# define ANGLE_POOL_ALLOC_GUARD_BLOCKS // define to enable guard block checking
+#endif
+
+//
+// This header defines an allocator that can be used to efficiently
+// allocate a large number of small requests for heap memory, with the
+// intention that they are not individually deallocated, but rather
+// collectively deallocated at one time.
+//
+// This simultaneously
+//
+// * Makes each individual allocation much more efficient; the
+// typical allocation is trivial.
+// * Completely avoids the cost of doing individual deallocation.
+// * Saves the trouble of tracking down and plugging a large class of leaks.
+//
+// Individual classes can use this allocator by supplying their own
+// new and delete methods.
+//
+
+#include "angleutils.h"
+#include "common/debug.h"
+
+namespace angle
+{
+class Allocation;
+class PageHeader;
+
+//
+// There are several stacks. One is to track the pushing and popping
+// of the user, and not yet implemented. The others are simply a
+// repositories of free pages or used pages.
+//
+// Page stacks are linked together with a simple header at the beginning
+// of each allocation obtained from the underlying OS. Multi-page allocations
+// are returned to the OS. Individual page allocations are kept for future
+// re-use.
+//
+// The "page size" used is not, nor must it match, the underlying OS
+// page size. But, having it be about that size or equal to a set of
+// pages is likely most optimal.
+//
+class PoolAllocator : angle::NonCopyable
+{
+ public:
+ static const int kDefaultAlignment = sizeof(void *);
+ //
+ // Create PoolAllocator. If alignment is set to 1 byte then fastAllocate()
+ // function can be used to make allocations with less overhead.
+ //
+ PoolAllocator(int growthIncrement = 8 * 1024, int allocationAlignment = kDefaultAlignment);
+
+ //
+ // Don't call the destructor just to free up the memory, call pop()
+ //
+ ~PoolAllocator();
+
+ //
+ // Initialize page size and alignment after construction
+ //
+ void initialize(int pageSize, int alignment);
+
+ //
+ // Call push() to establish a new place to pop memory to. Does not
+ // have to be called to get things started.
+ //
+ void push();
+
+ //
+ // Call pop() to free all memory allocated since the last call to push(),
+ // or if no last call to push, frees all memory since first allocation.
+ //
+ void pop();
+
+ //
+ // Call popAll() to free all memory allocated.
+ //
+ void popAll();
+
+ //
+ // Call allocate() to actually acquire memory. Returns 0 if no memory
+ // available, otherwise a properly aligned pointer to 'numBytes' of memory.
+ //
+ void *allocate(size_t numBytes);
+
+ //
+ // Call fastAllocate() for a faster allocate function that does minimal bookkeeping
+ // preCondition: Allocator must have been created w/ alignment of 1
+ ANGLE_INLINE uint8_t *fastAllocate(size_t numBytes)
+ {
+#if defined(ANGLE_DISABLE_POOL_ALLOC)
+ return reinterpret_cast<uint8_t *>(allocate(numBytes));
+#else
+ ASSERT(mAlignment == 1);
+ // No multi-page allocations
+ ASSERT(numBytes <= (mPageSize - mPageHeaderSkip));
+ //
+ // Do the allocation, most likely case inline first, for efficiency.
+ //
+ if (numBytes <= mPageSize - mCurrentPageOffset)
+ {
+ //
+ // Safe to allocate from mCurrentPageOffset.
+ //
+ uint8_t *memory = reinterpret_cast<uint8_t *>(mInUseList) + mCurrentPageOffset;
+ mCurrentPageOffset += numBytes;
+ return memory;
+ }
+ return allocateNewPage(numBytes);
+#endif
+ }
+
+ // There is no deallocate. The point of this class is that deallocation can be skipped by the
+ // user of it, as the model of use is to simultaneously deallocate everything at once by calling
+ // pop(), and to not have to solve memory leak problems.
+
+ // Catch unwanted allocations.
+ // TODO(jmadill): Remove this when we remove the global allocator.
+ void lock();
+ void unlock();
+
+ private:
+ size_t mAlignment; // all returned allocations will be aligned at
+ // this granularity, which will be a power of 2
+#if !defined(ANGLE_DISABLE_POOL_ALLOC)
+ struct AllocState
+ {
+ size_t offset;
+ PageHeader *page;
+ };
+ using AllocStack = std::vector<AllocState>;
+
+ // Slow path of allocation when we have to get a new page.
+ uint8_t *allocateNewPage(size_t numBytes);
+ // Track allocations if and only if we're using guard blocks
+ void *initializeAllocation(uint8_t *memory, size_t numBytes);
+
+ // Granularity of allocation from the OS
+ size_t mPageSize;
+ // Amount of memory to skip to make room for the page header (which is the size of the page
+ // header, or PageHeader in PoolAlloc.cpp)
+ size_t mPageHeaderSkip;
+ // Next offset in top of inUseList to allocate from. This offset is not necessarily aligned to
+ // anything. When an allocation is made, the data is aligned to mAlignment, and the header (if
+ // any) will align to pointer size by extension (since mAlignment is made aligned to at least
+ // pointer size).
+ size_t mCurrentPageOffset;
+ // List of popped memory
+ PageHeader *mFreeList;
+ // List of all memory currently being used. The head of this list is where allocations are
+ // currently being made from.
+ PageHeader *mInUseList;
+ // Stack of where to allocate from, to partition pool
+ AllocStack mStack;
+
+ int mNumCalls; // just an interesting statistic
+ size_t mTotalBytes; // just an interesting statistic
+
+#else // !defined(ANGLE_DISABLE_POOL_ALLOC)
+ std::vector<std::vector<void *>> mStack;
+#endif
+
+ bool mLocked;
+};
+
+} // namespace angle
+
+#endif // COMMON_POOLALLOC_H_
diff --git a/gfx/angle/checkout/src/common/Spinlock.h b/gfx/angle/checkout/src/common/Spinlock.h
new file mode 100644
index 0000000000..494da0943e
--- /dev/null
+++ b/gfx/angle/checkout/src/common/Spinlock.h
@@ -0,0 +1,71 @@
+//
+// Copyright 2021 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.
+//
+// Spinlock.h:
+// Spinlock is a lock that loops actively until it gets the resource.
+// Only use it when the lock will be granted in reasonably short time.
+
+#ifndef COMMON_SPINLOCK_H_
+#define COMMON_SPINLOCK_H_
+
+#include <atomic>
+
+// TODO(jplate) Add pause for ARM, http://anglebug.com:6067
+#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
+extern "C" void _mm_pause();
+# pragma intrinsic(_mm_pause)
+# define ANGLE_SMT_PAUSE() _mm_pause()
+#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+# define ANGLE_SMT_PAUSE() __asm__ __volatile__("pause;")
+#else
+# define ANGLE_SMT_PAUSE() static_cast<void>(0)
+#endif
+
+namespace angle
+{
+
+class Spinlock
+{
+ public:
+ Spinlock() noexcept;
+
+ bool try_lock() noexcept;
+ void lock() noexcept;
+ void unlock() noexcept;
+
+ private:
+ std::atomic_bool mLock;
+};
+
+inline Spinlock::Spinlock() noexcept : mLock(false) {}
+
+inline bool Spinlock::try_lock() noexcept
+{
+ // Relaxed check first to prevent unnecessary cache misses.
+ return !mLock.load(std::memory_order_relaxed) &&
+ !mLock.exchange(true, std::memory_order_acquire);
+}
+
+inline void Spinlock::lock() noexcept
+{
+ while (mLock.exchange(true, std::memory_order_acquire))
+ {
+ // Relaxed wait to prevent unnecessary cache misses.
+ while (mLock.load(std::memory_order_relaxed))
+ {
+ // Optimization for simultaneous multithreading.
+ ANGLE_SMT_PAUSE();
+ }
+ }
+}
+
+inline void Spinlock::unlock() noexcept
+{
+ mLock.store(false, std::memory_order_release);
+}
+
+} // namespace angle
+
+#endif // COMMON_SPINLOCK_H_
diff --git a/gfx/angle/checkout/src/common/SynchronizedValue.h b/gfx/angle/checkout/src/common/SynchronizedValue.h
new file mode 100644
index 0000000000..95432cfbcd
--- /dev/null
+++ b/gfx/angle/checkout/src/common/SynchronizedValue.h
@@ -0,0 +1,540 @@
+//
+// Copyright 2021 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.
+//
+// SynchronizedValue.h:
+// A class that ensures that the correct mutex is locked when the encapsulated data is accessed.
+// Based on boost::synchronized_value, which probably becomes part of the next C++ standard.
+// https://www.boost.org/doc/libs/1_76_0/doc/html/thread/sds.html#thread.sds.synchronized_valuesxxx
+
+#ifndef COMMON_SYNCHRONIZEDVALUE_H_
+#define COMMON_SYNCHRONIZEDVALUE_H_
+
+#include "common/debug.h"
+
+#include <mutex>
+#include <type_traits>
+
+namespace angle
+{
+
+template <typename T, typename Lockable = std::mutex>
+class ConstStrictLockPtr
+{
+ public:
+ using value_type = T;
+ using mutex_type = Lockable;
+
+ ConstStrictLockPtr(const T &value, Lockable &mutex) : mLock(mutex), mValue(value) {}
+ ConstStrictLockPtr(const T &value, Lockable &mutex, std::adopt_lock_t) noexcept
+ : mLock(mutex, std::adopt_lock), mValue(value)
+ {}
+
+ ConstStrictLockPtr(ConstStrictLockPtr &&other) noexcept
+ : mLock(std::move(other.mLock)), mValue(other.mValue)
+ {}
+
+ ConstStrictLockPtr(const ConstStrictLockPtr &) = delete;
+ ConstStrictLockPtr &operator=(const ConstStrictLockPtr &) = delete;
+
+ ~ConstStrictLockPtr() = default;
+
+ const T *operator->() const { return &mValue; }
+ const T &operator*() const { return mValue; }
+
+ protected:
+ std::unique_lock<Lockable> mLock;
+ T const &mValue;
+};
+
+template <typename T, typename Lockable = std::mutex>
+class StrictLockPtr : public ConstStrictLockPtr<T, Lockable>
+{
+ private:
+ using BaseType = ConstStrictLockPtr<T, Lockable>;
+
+ public:
+ StrictLockPtr(T &value, Lockable &mutex) : BaseType(value, mutex) {}
+ StrictLockPtr(T &value, Lockable &mutex, std::adopt_lock_t) noexcept
+ : BaseType(value, mutex, std::adopt_lock)
+ {}
+
+ StrictLockPtr(StrictLockPtr &&other) noexcept
+ : BaseType(std::move(static_cast<BaseType &&>(other)))
+ {}
+
+ StrictLockPtr(const StrictLockPtr &) = delete;
+ StrictLockPtr &operator=(const StrictLockPtr &) = delete;
+
+ ~StrictLockPtr() = default;
+
+ T *operator->() { return const_cast<T *>(&this->mValue); }
+ T &operator*() { return const_cast<T &>(this->mValue); }
+};
+
+template <typename SV>
+struct SynchronizedValueStrictLockPtr
+{
+ using type = StrictLockPtr<typename SV::value_type, typename SV::mutex_type>;
+};
+
+template <typename SV>
+struct SynchronizedValueStrictLockPtr<const SV>
+{
+ using type = ConstStrictLockPtr<typename SV::value_type, typename SV::mutex_type>;
+};
+
+template <typename T, typename Lockable = std::mutex>
+class ConstUniqueLockPtr : public std::unique_lock<Lockable>
+{
+ private:
+ using BaseType = std::unique_lock<Lockable>;
+
+ public:
+ using value_type = T;
+ using mutex_type = Lockable;
+
+ ConstUniqueLockPtr(const T &value, Lockable &mutex) : BaseType(mutex), mValue(value) {}
+ ConstUniqueLockPtr(const T &value, Lockable &mutex, std::adopt_lock_t) noexcept
+ : BaseType(mutex, std::adopt_lock), mValue(value)
+ {}
+ ConstUniqueLockPtr(const T &value, Lockable &mutex, std::defer_lock_t) noexcept
+ : BaseType(mutex, std::defer_lock), mValue(value)
+ {}
+ ConstUniqueLockPtr(const T &value, Lockable &mutex, std::try_to_lock_t) noexcept
+ : BaseType(mutex, std::try_to_lock), mValue(value)
+ {}
+
+ ConstUniqueLockPtr(ConstUniqueLockPtr &&other) noexcept
+ : BaseType(std::move(static_cast<BaseType &&>(other))), mValue(other.mValue)
+ {}
+
+ ConstUniqueLockPtr(const ConstUniqueLockPtr &) = delete;
+ ConstUniqueLockPtr &operator=(const ConstUniqueLockPtr &) = delete;
+
+ ~ConstUniqueLockPtr() = default;
+
+ const T *operator->() const
+ {
+ ASSERT(this->owns_lock());
+ return &mValue;
+ }
+ const T &operator*() const
+ {
+ ASSERT(this->owns_lock());
+ return mValue;
+ }
+
+ protected:
+ T const &mValue;
+};
+
+template <typename T, typename Lockable = std::mutex>
+class UniqueLockPtr : public ConstUniqueLockPtr<T, Lockable>
+{
+ private:
+ using BaseType = ConstUniqueLockPtr<T, Lockable>;
+
+ public:
+ UniqueLockPtr(T &value, Lockable &mutex) : BaseType(value, mutex) {}
+ UniqueLockPtr(T &value, Lockable &mutex, std::adopt_lock_t) noexcept
+ : BaseType(value, mutex, std::adopt_lock)
+ {}
+ UniqueLockPtr(T &value, Lockable &mutex, std::defer_lock_t) noexcept
+ : BaseType(value, mutex, std::defer_lock)
+ {}
+ UniqueLockPtr(T &value, Lockable &mutex, std::try_to_lock_t) noexcept
+ : BaseType(value, mutex, std::try_to_lock)
+ {}
+
+ UniqueLockPtr(UniqueLockPtr &&other) noexcept
+ : BaseType(std::move(static_cast<BaseType &&>(other)))
+ {}
+
+ UniqueLockPtr(const UniqueLockPtr &) = delete;
+ UniqueLockPtr &operator=(const UniqueLockPtr &) = delete;
+
+ ~UniqueLockPtr() = default;
+
+ T *operator->()
+ {
+ ASSERT(this->owns_lock());
+ return const_cast<T *>(&this->mValue);
+ }
+ T &operator*()
+ {
+ ASSERT(this->owns_lock());
+ return const_cast<T &>(this->mValue);
+ }
+};
+
+template <typename SV>
+struct SynchronizedValueUniqueLockPtr
+{
+ using type = UniqueLockPtr<typename SV::value_type, typename SV::mutex_type>;
+};
+
+template <typename SV>
+struct SynchronizedValueUniqueLockPtr<const SV>
+{
+ using type = ConstUniqueLockPtr<typename SV::value_type, typename SV::mutex_type>;
+};
+
+template <typename T, typename Lockable = std::mutex>
+class SynchronizedValue
+{
+ public:
+ using value_type = T;
+ using mutex_type = Lockable;
+
+ SynchronizedValue() noexcept(std::is_nothrow_default_constructible<T>::value) : mValue() {}
+
+ SynchronizedValue(const T &other) noexcept(std::is_nothrow_copy_constructible<T>::value)
+ : mValue(other)
+ {}
+
+ SynchronizedValue(T &&other) noexcept(std::is_nothrow_move_constructible<T>::value)
+ : mValue(std::move(other))
+ {}
+
+ template <typename... Args>
+ SynchronizedValue(Args &&... args) noexcept(noexcept(T(std::forward<Args>(args)...)))
+ : mValue(std::forward<Args>(args)...)
+ {}
+
+ SynchronizedValue(const SynchronizedValue &other)
+ {
+ std::lock_guard<Lockable> lock(other.mMutex);
+ mValue = other.mValue;
+ }
+
+ SynchronizedValue(SynchronizedValue &&other)
+ {
+ std::lock_guard<Lockable> lock(other.mMutex);
+ mValue = std::move(other.mValue);
+ }
+
+ SynchronizedValue &operator=(const SynchronizedValue &other)
+ {
+ if (&other != this)
+ {
+ std::unique_lock<Lockable> lock1(mMutex, std::defer_lock);
+ std::unique_lock<Lockable> lock2(other.mMutex, std::defer_lock);
+ std::lock(lock1, lock2);
+ mValue = other.mValue;
+ }
+ return *this;
+ }
+
+ SynchronizedValue &operator=(SynchronizedValue &&other)
+ {
+ if (&other != this)
+ {
+ std::unique_lock<Lockable> lock1(mMutex, std::defer_lock);
+ std::unique_lock<Lockable> lock2(other.mMutex, std::defer_lock);
+ std::lock(lock1, lock2);
+ mValue = std::move(other.mValue);
+ }
+ return *this;
+ }
+
+ SynchronizedValue &operator=(const T &value)
+ {
+ {
+ std::lock_guard<Lockable> lock(mMutex);
+ mValue = value;
+ }
+ return *this;
+ }
+
+ SynchronizedValue &operator=(T &&value)
+ {
+ {
+ std::lock_guard<Lockable> lock(mMutex);
+ mValue = std::move(value);
+ }
+ return *this;
+ }
+
+ T get() const
+ {
+ std::lock_guard<Lockable> lock(mMutex);
+ return mValue;
+ }
+
+ explicit operator T() const { return get(); }
+
+ void swap(SynchronizedValue &other)
+ {
+ if (this == &other)
+ {
+ return;
+ }
+ std::unique_lock<Lockable> lock1(mMutex, std::defer_lock);
+ std::unique_lock<Lockable> lock2(other.mMutex, std::defer_lock);
+ std::lock(lock1, lock2);
+ std::swap(mValue, other.mValue);
+ }
+
+ void swap(T &other)
+ {
+ std::lock_guard<Lockable> lock(mMutex);
+ std::swap(mValue, other);
+ }
+
+ StrictLockPtr<T, Lockable> operator->() { return StrictLockPtr<T, Lockable>(mValue, mMutex); }
+ ConstStrictLockPtr<T, Lockable> operator->() const
+ {
+ return ConstStrictLockPtr<T, Lockable>(mValue, mMutex);
+ }
+
+ StrictLockPtr<T, Lockable> synchronize() { return StrictLockPtr<T, Lockable>(mValue, mMutex); }
+ ConstStrictLockPtr<T, Lockable> synchronize() const
+ {
+ return ConstStrictLockPtr<T, Lockable>(mValue, mMutex);
+ }
+
+ UniqueLockPtr<T, Lockable> unique_synchronize()
+ {
+ return UniqueLockPtr<T, Lockable>(mValue, mMutex);
+ }
+ ConstUniqueLockPtr<T, Lockable> unique_synchronize() const
+ {
+ return ConstUniqueLockPtr<T, Lockable>(mValue, mMutex);
+ }
+
+ UniqueLockPtr<T, Lockable> defer_synchronize() noexcept
+ {
+ return UniqueLockPtr<T, Lockable>(mValue, mMutex, std::defer_lock);
+ }
+ ConstUniqueLockPtr<T, Lockable> defer_synchronize() const noexcept
+ {
+ return ConstUniqueLockPtr<T, Lockable>(mValue, mMutex, std::defer_lock);
+ }
+
+ UniqueLockPtr<T, Lockable> try_to_synchronize() noexcept
+ {
+ return UniqueLockPtr<T, Lockable>(mValue, mMutex, std::try_to_lock);
+ }
+ ConstUniqueLockPtr<T, Lockable> try_to_synchronize() const noexcept
+ {
+ return ConstUniqueLockPtr<T, Lockable>(mValue, mMutex, std::try_to_lock);
+ }
+
+ UniqueLockPtr<T, Lockable> adopt_synchronize() noexcept
+ {
+ return UniqueLockPtr<T, Lockable>(mValue, mMutex, std::adopt_lock);
+ }
+ ConstUniqueLockPtr<T, Lockable> adopt_synchronize() const noexcept
+ {
+ return ConstUniqueLockPtr<T, Lockable>(mValue, mMutex, std::adopt_lock);
+ }
+
+ class DerefValue
+ {
+ public:
+ DerefValue(DerefValue &&other) : mLock(std::move(other.mLock)), mValue(other.mValue) {}
+
+ DerefValue(const DerefValue &) = delete;
+ DerefValue &operator=(const DerefValue &) = delete;
+
+ operator T &() { return mValue; }
+
+ DerefValue &operator=(const T &other)
+ {
+ mValue = other;
+ return *this;
+ }
+
+ private:
+ explicit DerefValue(SynchronizedValue &outer) : mLock(outer.mMutex), mValue(outer.mValue) {}
+
+ std::unique_lock<Lockable> mLock;
+ T &mValue;
+
+ friend class SynchronizedValue;
+ };
+
+ class ConstDerefValue
+ {
+ public:
+ ConstDerefValue(ConstDerefValue &&other)
+ : mLock(std::move(other.mLock)), mValue(other.mValue)
+ {}
+
+ ConstDerefValue(const ConstDerefValue &) = delete;
+ ConstDerefValue &operator=(const ConstDerefValue &) = delete;
+
+ operator const T &() { return mValue; }
+
+ private:
+ explicit ConstDerefValue(const SynchronizedValue &outer)
+ : mLock(outer.mMutex), mValue(outer.mValue)
+ {}
+
+ std::unique_lock<Lockable> mLock;
+ const T &mValue;
+
+ friend class SynchronizedValue;
+ };
+
+ DerefValue operator*() { return DerefValue(*this); }
+ ConstDerefValue operator*() const { return ConstDerefValue(*this); }
+
+ template <typename OStream>
+ void save(OStream &os) const
+ {
+ std::lock_guard<Lockable> lock(mMutex);
+ os << mValue;
+ }
+
+ template <typename IStream>
+ void load(IStream &is)
+ {
+ std::lock_guard<Lockable> lock(mMutex);
+ is >> mValue;
+ }
+
+ bool operator==(const SynchronizedValue &other) const
+ {
+ std::unique_lock<Lockable> lock1(mMutex, std::defer_lock);
+ std::unique_lock<Lockable> lock2(other.mMutex, std::defer_lock);
+ std::lock(lock1, lock2);
+ return mValue == other.mValue;
+ }
+
+ bool operator!=(const SynchronizedValue &other) const
+ {
+ std::unique_lock<Lockable> lock1(mMutex, std::defer_lock);
+ std::unique_lock<Lockable> lock2(other.mMutex, std::defer_lock);
+ std::lock(lock1, lock2);
+ return mValue != other.mValue;
+ }
+
+ bool operator<(const SynchronizedValue &other) const
+ {
+ std::unique_lock<Lockable> lock1(mMutex, std::defer_lock);
+ std::unique_lock<Lockable> lock2(other.mMutex, std::defer_lock);
+ std::lock(lock1, lock2);
+ return mValue < other.mValue;
+ }
+
+ bool operator>(const SynchronizedValue &other) const
+ {
+ std::unique_lock<Lockable> lock1(mMutex, std::defer_lock);
+ std::unique_lock<Lockable> lock2(other.mMutex, std::defer_lock);
+ std::lock(lock1, lock2);
+ return mValue > other.mValue;
+ }
+
+ bool operator<=(const SynchronizedValue &other) const
+ {
+ std::unique_lock<Lockable> lock1(mMutex, std::defer_lock);
+ std::unique_lock<Lockable> lock2(other.mMutex, std::defer_lock);
+ std::lock(lock1, lock2);
+ return mValue <= other.mValue;
+ }
+
+ bool operator>=(const SynchronizedValue &other) const
+ {
+ std::unique_lock<Lockable> lock1(mMutex, std::defer_lock);
+ std::unique_lock<Lockable> lock2(other.mMutex, std::defer_lock);
+ std::lock(lock1, lock2);
+ return mValue >= other.mValue;
+ }
+
+ bool operator==(const T &other) const
+ {
+ std::lock_guard<Lockable> lock(mMutex);
+ return mValue == other;
+ }
+
+ bool operator!=(const T &other) const
+ {
+ std::lock_guard<Lockable> lock(mMutex);
+ return mValue != other;
+ }
+
+ bool operator<(const T &other) const
+ {
+ std::lock_guard<Lockable> lock(mMutex);
+ return mValue < other;
+ }
+
+ bool operator>(const T &other) const
+ {
+ std::lock_guard<Lockable> lock(mMutex);
+ return mValue > other;
+ }
+
+ bool operator<=(const T &other) const
+ {
+ std::lock_guard<Lockable> lock(mMutex);
+ return mValue <= other;
+ }
+
+ bool operator>=(const T &other) const
+ {
+ std::lock_guard<Lockable> lock(mMutex);
+ return mValue >= other;
+ }
+
+ private:
+ T mValue;
+ mutable Lockable mMutex;
+};
+
+template <typename OStream, typename T, typename L>
+inline OStream &operator<<(OStream &os, SynchronizedValue<T, L> const &sv)
+{
+ sv.save(os);
+ return os;
+}
+
+template <typename IStream, typename T, typename L>
+inline IStream &operator>>(IStream &is, SynchronizedValue<T, L> &sv)
+{
+ sv.load(is);
+ return is;
+}
+
+template <typename T, typename L>
+bool operator==(const T &lhs, const SynchronizedValue<T, L> &rhs)
+{
+ return rhs == lhs;
+}
+
+template <typename T, typename L>
+bool operator!=(const T &lhs, const SynchronizedValue<T, L> &rhs)
+{
+ return rhs != lhs;
+}
+
+template <typename T, typename L>
+bool operator<(const T &lhs, const SynchronizedValue<T, L> &rhs)
+{
+ return rhs < lhs;
+}
+
+template <typename T, typename L>
+bool operator>(const T &lhs, const SynchronizedValue<T, L> &rhs)
+{
+ return rhs > lhs;
+}
+
+template <typename T, typename L>
+bool operator<=(const T &lhs, const SynchronizedValue<T, L> &rhs)
+{
+ return rhs <= lhs;
+}
+
+template <typename T, typename L>
+bool operator>=(const T &lhs, const SynchronizedValue<T, L> &rhs)
+{
+ return rhs >= lhs;
+}
+
+} // namespace angle
+
+#endif // COMMON_SYNCHRONIZEDVALUE_H_
diff --git a/gfx/angle/checkout/src/common/aligned_memory.cpp b/gfx/angle/checkout/src/common/aligned_memory.cpp
new file mode 100644
index 0000000000..9798fc0f42
--- /dev/null
+++ b/gfx/angle/checkout/src/common/aligned_memory.cpp
@@ -0,0 +1,64 @@
+//
+// Copyright 2017 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.
+//
+// aligned_memory: An aligned memory allocator. Based on Chrome's base/memory/aligned_memory.
+//
+
+#include "common/aligned_memory.h"
+
+#include "common/debug.h"
+#include "common/platform.h"
+
+#if defined(COMPILER_MSVC)
+# include <malloc.h>
+#else
+# include <stdlib.h>
+#endif
+
+namespace angle
+{
+
+void *AlignedAlloc(size_t size, size_t alignment)
+{
+ ASSERT(size > 0);
+ ASSERT((alignment & (alignment - 1)) == 0);
+ ASSERT((alignment % sizeof(void *)) == 0);
+ void *ptr = nullptr;
+#if defined(ANGLE_PLATFORM_WINDOWS)
+ ptr = _aligned_malloc(size, alignment);
+// Android technically supports posix_memalign(), but does not expose it in
+// the current version of the library headers used by Chrome. Luckily,
+// memalign() on Android returns pointers which can safely be used with
+// free(), so we can use it instead. Issue filed to document this:
+// http://code.google.com/p/android/issues/detail?id=35391
+#elif defined(ANGLE_PLATFORM_ANDROID)
+ ptr = memalign(alignment, size);
+#else
+ if (posix_memalign(&ptr, alignment, size))
+ ptr = nullptr;
+#endif
+ // Since aligned allocations may fail for non-memory related reasons, force a
+ // crash if we encounter a failed allocation.
+ if (!ptr)
+ {
+ ERR() << "If you crashed here, your aligned allocation is incorrect: "
+ << "size=" << size << ", alignment=" << alignment;
+ ASSERT(false);
+ }
+ // Confidence check alignment just to be safe.
+ ASSERT((reinterpret_cast<uintptr_t>(ptr) & (alignment - 1)) == 0);
+ return ptr;
+}
+
+void AlignedFree(void *ptr)
+{
+#if defined(ANGLE_PLATFORM_WINDOWS)
+ _aligned_free(ptr);
+#else
+ free(ptr);
+#endif
+}
+
+} // namespace angle
diff --git a/gfx/angle/checkout/src/common/aligned_memory.h b/gfx/angle/checkout/src/common/aligned_memory.h
new file mode 100644
index 0000000000..dcbb60d1cb
--- /dev/null
+++ b/gfx/angle/checkout/src/common/aligned_memory.h
@@ -0,0 +1,23 @@
+//
+// Copyright 2017 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.
+//
+// aligned_memory: An aligned memory allocator. Based on Chrome's base/memory/aligned_memory.
+//
+
+#ifndef COMMON_ALIGNED_MEMORY_H_
+#define COMMON_ALIGNED_MEMORY_H_
+
+#include <cstddef>
+
+namespace angle
+{
+
+// This can be replaced with std::aligned_malloc when we have C++17.
+void *AlignedAlloc(size_t size, size_t alignment);
+void AlignedFree(void *ptr);
+
+} // namespace angle
+
+#endif // COMMON_ALIGNED_MEMORY_H_
diff --git a/gfx/angle/checkout/src/common/android_util.cpp b/gfx/angle/checkout/src/common/android_util.cpp
new file mode 100644
index 0000000000..8188da21ef
--- /dev/null
+++ b/gfx/angle/checkout/src/common/android_util.cpp
@@ -0,0 +1,424 @@
+//
+// Copyright 2018 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.
+//
+
+// android_util.cpp: Utilities for the using the Android platform
+
+#include "common/android_util.h"
+#include "common/debug.h"
+
+#include <cstdint>
+
+#if defined(ANGLE_PLATFORM_ANDROID) && __ANDROID_API__ >= 26
+# define ANGLE_AHARDWARE_BUFFER_SUPPORT
+// NDK header file for access to Android Hardware Buffers
+# include <android/hardware_buffer.h>
+#endif
+
+// Taken from cutils/native_handle.h:
+// https://android.googlesource.com/platform/system/core/+/master/libcutils/include/cutils/native_handle.h
+typedef struct native_handle
+{
+ int version; /* sizeof(native_handle_t) */
+ int numFds; /* number of file-descriptors at &data[0] */
+ int numInts; /* number of ints at &data[numFds] */
+#if defined(__clang__)
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wzero-length-array"
+#elif defined(_MSC_VER)
+# pragma warning(push)
+# pragma warning(disable : 4200)
+#endif
+ int data[0]; /* numFds + numInts ints */
+#if defined(__clang__)
+# pragma clang diagnostic pop
+#elif defined(_MSC_VER)
+# pragma warning(pop)
+#endif
+} native_handle_t;
+
+// Taken from nativebase/nativebase.h
+// https://android.googlesource.com/platform/frameworks/native/+/master/libs/nativebase/include/nativebase/nativebase.h
+typedef const native_handle_t *buffer_handle_t;
+
+typedef struct android_native_base_t
+{
+ /* a magic value defined by the actual EGL native type */
+ int magic;
+ /* the sizeof() of the actual EGL native type */
+ int version;
+ void *reserved[4];
+ /* reference-counting interface */
+ void (*incRef)(struct android_native_base_t *base);
+ void (*decRef)(struct android_native_base_t *base);
+} android_native_base_t;
+
+typedef struct ANativeWindowBuffer
+{
+ struct android_native_base_t common;
+ int width;
+ int height;
+ int stride;
+ int format;
+ int usage_deprecated;
+ uintptr_t layerCount;
+ void *reserved[1];
+ const native_handle_t *handle;
+ uint64_t usage;
+ // we needed extra space for storing the 64-bits usage flags
+ // the number of slots to use from reserved_proc depends on the
+ // architecture.
+ void *reserved_proc[8 - (sizeof(uint64_t) / sizeof(void *))];
+} ANativeWindowBuffer_t;
+
+// Taken from android/hardware_buffer.h
+// https://android.googlesource.com/platform/frameworks/native/+/master/libs/nativewindow/include/android/hardware_buffer.h
+
+// AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM AHARDWAREBUFFER_FORMAT_B4G4R4A4_UNORM,
+// AHARDWAREBUFFER_FORMAT_B5G5R5A1_UNORM formats were deprecated and re-added explicitly.
+
+// clang-format off
+/**
+ * Buffer pixel formats.
+ */
+enum {
+
+#ifndef ANGLE_AHARDWARE_BUFFER_SUPPORT
+ /**
+ * Corresponding formats:
+ * Vulkan: VK_FORMAT_R8G8B8A8_UNORM
+ * OpenGL ES: GL_RGBA8
+ */
+ AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM = 1,
+
+ /**
+ * 32 bits per pixel, 8 bits per channel format where alpha values are
+ * ignored (always opaque).
+ * Corresponding formats:
+ * Vulkan: VK_FORMAT_R8G8B8A8_UNORM
+ * OpenGL ES: GL_RGB8
+ */
+ AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM = 2,
+
+ /**
+ * Corresponding formats:
+ * Vulkan: VK_FORMAT_R8G8B8_UNORM
+ * OpenGL ES: GL_RGB8
+ */
+ AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM = 3,
+
+ /**
+ * Corresponding formats:
+ * Vulkan: VK_FORMAT_R5G6B5_UNORM_PACK16
+ * OpenGL ES: GL_RGB565
+ */
+ AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM = 4,
+#endif // ANGLE_AHARDWARE_BUFFER_SUPPORT
+
+ AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM = 5,
+ AHARDWAREBUFFER_FORMAT_B5G5R5A1_UNORM = 6,
+ AHARDWAREBUFFER_FORMAT_B4G4R4A4_UNORM = 7,
+
+#ifndef ANGLE_AHARDWARE_BUFFER_SUPPORT
+ /**
+ * Corresponding formats:
+ * Vulkan: VK_FORMAT_R16G16B16A16_SFLOAT
+ * OpenGL ES: GL_RGBA16F
+ */
+ AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT = 0x16,
+
+ /**
+ * Corresponding formats:
+ * Vulkan: VK_FORMAT_A2B10G10R10_UNORM_PACK32
+ * OpenGL ES: GL_RGB10_A2
+ */
+ AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM = 0x2b,
+
+ /**
+ * An opaque binary blob format that must have height 1, with width equal to
+ * the buffer size in bytes.
+ */
+ AHARDWAREBUFFER_FORMAT_BLOB = 0x21,
+
+ /**
+ * Corresponding formats:
+ * Vulkan: VK_FORMAT_D16_UNORM
+ * OpenGL ES: GL_DEPTH_COMPONENT16
+ */
+ AHARDWAREBUFFER_FORMAT_D16_UNORM = 0x30,
+
+ /**
+ * Corresponding formats:
+ * Vulkan: VK_FORMAT_X8_D24_UNORM_PACK32
+ * OpenGL ES: GL_DEPTH_COMPONENT24
+ */
+ AHARDWAREBUFFER_FORMAT_D24_UNORM = 0x31,
+
+ /**
+ * Corresponding formats:
+ * Vulkan: VK_FORMAT_D24_UNORM_S8_UINT
+ * OpenGL ES: GL_DEPTH24_STENCIL8
+ */
+ AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT = 0x32,
+
+ /**
+ * Corresponding formats:
+ * Vulkan: VK_FORMAT_D32_SFLOAT
+ * OpenGL ES: GL_DEPTH_COMPONENT32F
+ */
+ AHARDWAREBUFFER_FORMAT_D32_FLOAT = 0x33,
+
+ /**
+ * Corresponding formats:
+ * Vulkan: VK_FORMAT_D32_SFLOAT_S8_UINT
+ * OpenGL ES: GL_DEPTH32F_STENCIL8
+ */
+ AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT = 0x34,
+
+ /**
+ * Corresponding formats:
+ * Vulkan: VK_FORMAT_S8_UINT
+ * OpenGL ES: GL_STENCIL_INDEX8
+ */
+ AHARDWAREBUFFER_FORMAT_S8_UINT = 0x35,
+
+ /**
+ * YUV 420 888 format.
+ * Must have an even width and height. Can be accessed in OpenGL
+ * shaders through an external sampler. Does not support mip-maps
+ * cube-maps or multi-layered textures.
+ */
+ AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420 = 0x23,
+
+#endif // ANGLE_AHARDWARE_BUFFER_SUPPORT
+
+ AHARDWAREBUFFER_FORMAT_YV12 = 0x32315659,
+ AHARDWAREBUFFER_FORMAT_IMPLEMENTATION_DEFINED = 0x22,
+};
+// clang-format on
+
+namespace
+{
+
+// In the Android system:
+// - AHardwareBuffer is essentially a typedef of GraphicBuffer. Conversion functions simply
+// reinterpret_cast.
+// - GraphicBuffer inherits from two base classes, ANativeWindowBuffer and RefBase.
+//
+// GraphicBuffer implements a getter for ANativeWindowBuffer (getNativeBuffer) by static_casting
+// itself to its base class ANativeWindowBuffer. The offset of the ANativeWindowBuffer pointer
+// from the GraphicBuffer pointer is 16 bytes. This is likely due to two pointers: The vtable of
+// GraphicBuffer and the one pointer member of the RefBase class.
+//
+// This is not future proof at all. We need to look into getting utilities added to Android to
+// perform this cast for us.
+constexpr int kAHardwareBufferToANativeWindowBufferOffset = static_cast<int>(sizeof(void *)) * 2;
+
+template <typename T1, typename T2>
+T1 *OffsetPointer(T2 *ptr, int bytes)
+{
+ return reinterpret_cast<T1 *>(reinterpret_cast<intptr_t>(ptr) + bytes);
+}
+
+GLenum GetPixelFormatInfo(int pixelFormat, bool *isYUV)
+{
+ *isYUV = false;
+ switch (pixelFormat)
+ {
+ case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
+ return GL_RGBA8;
+ case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:
+ return GL_RGB8;
+ case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:
+ return GL_RGB8;
+ case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM:
+ return GL_RGB565;
+ case AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM:
+ return GL_BGRA8_EXT;
+ case AHARDWAREBUFFER_FORMAT_B5G5R5A1_UNORM:
+ return GL_RGB5_A1;
+ case AHARDWAREBUFFER_FORMAT_B4G4R4A4_UNORM:
+ return GL_RGBA4;
+ case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:
+ return GL_RGBA16F;
+ case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:
+ return GL_RGB10_A2;
+ case AHARDWAREBUFFER_FORMAT_BLOB:
+ return GL_NONE;
+ case AHARDWAREBUFFER_FORMAT_D16_UNORM:
+ return GL_DEPTH_COMPONENT16;
+ case AHARDWAREBUFFER_FORMAT_D24_UNORM:
+ return GL_DEPTH_COMPONENT24;
+ case AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT:
+ return GL_DEPTH24_STENCIL8;
+ case AHARDWAREBUFFER_FORMAT_D32_FLOAT:
+ return GL_DEPTH_COMPONENT32F;
+ case AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT:
+ return GL_DEPTH32F_STENCIL8;
+ case AHARDWAREBUFFER_FORMAT_S8_UINT:
+ return GL_STENCIL_INDEX8;
+ case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
+ case AHARDWAREBUFFER_FORMAT_YV12:
+ case AHARDWAREBUFFER_FORMAT_IMPLEMENTATION_DEFINED:
+ *isYUV = true;
+ return GL_RGB8;
+ default:
+ // Treat unknown formats as RGB. They are vendor-specific YUV formats that would sample
+ // as RGB.
+ *isYUV = true;
+ return GL_RGB8;
+ }
+}
+
+} // anonymous namespace
+
+namespace angle
+{
+
+namespace android
+{
+
+ANativeWindowBuffer *ClientBufferToANativeWindowBuffer(EGLClientBuffer clientBuffer)
+{
+ return reinterpret_cast<ANativeWindowBuffer *>(clientBuffer);
+}
+
+uint64_t GetAHBUsage(int eglNativeBufferUsage)
+{
+ uint64_t ahbUsage = 0;
+#if defined(ANGLE_AHARDWARE_BUFFER_SUPPORT)
+ if (eglNativeBufferUsage & EGL_NATIVE_BUFFER_USAGE_PROTECTED_BIT_ANDROID)
+ {
+ ahbUsage |= AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT;
+ }
+ if (eglNativeBufferUsage & EGL_NATIVE_BUFFER_USAGE_RENDERBUFFER_BIT_ANDROID)
+ {
+ ahbUsage |= AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER;
+ }
+ if (eglNativeBufferUsage & EGL_NATIVE_BUFFER_USAGE_TEXTURE_BIT_ANDROID)
+ {
+ ahbUsage |= AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
+ }
+#endif // ANGLE_AHARDWARE_BUFFER_SUPPORT
+ return ahbUsage;
+}
+
+EGLClientBuffer CreateEGLClientBufferFromAHardwareBuffer(int width,
+ int height,
+ int depth,
+ int androidFormat,
+ int usage)
+{
+#if defined(ANGLE_AHARDWARE_BUFFER_SUPPORT)
+
+ // The height and width are number of pixels of size format
+ AHardwareBuffer_Desc aHardwareBufferDescription = {};
+ aHardwareBufferDescription.width = static_cast<uint32_t>(width);
+ aHardwareBufferDescription.height = static_cast<uint32_t>(height);
+ aHardwareBufferDescription.layers = static_cast<uint32_t>(depth);
+ aHardwareBufferDescription.format = androidFormat;
+ aHardwareBufferDescription.usage = GetAHBUsage(usage);
+
+ // Allocate memory from Android Hardware Buffer
+ AHardwareBuffer *aHardwareBuffer = nullptr;
+ int res = AHardwareBuffer_allocate(&aHardwareBufferDescription, &aHardwareBuffer);
+ if (res != 0)
+ {
+ return nullptr;
+ }
+
+ return AHardwareBufferToClientBuffer(aHardwareBuffer);
+#else
+ return nullptr;
+#endif // ANGLE_AHARDWARE_BUFFER_SUPPORT
+}
+
+void GetANativeWindowBufferProperties(const ANativeWindowBuffer *buffer,
+ int *width,
+ int *height,
+ int *depth,
+ int *pixelFormat,
+ uint64_t *usage)
+{
+ *width = buffer->width;
+ *height = buffer->height;
+ *depth = static_cast<int>(buffer->layerCount);
+ *height = buffer->height;
+ *pixelFormat = buffer->format;
+ *usage = buffer->usage;
+}
+
+GLenum NativePixelFormatToGLInternalFormat(int pixelFormat)
+{
+ bool isYuv = false;
+ return GetPixelFormatInfo(pixelFormat, &isYuv);
+}
+
+int GLInternalFormatToNativePixelFormat(GLenum internalFormat)
+{
+ switch (internalFormat)
+ {
+ case GL_RGBA8:
+ return AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
+ case GL_RGB8:
+ return AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM;
+ case GL_RGB565:
+ return AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM;
+ case GL_BGRA8_EXT:
+ return AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM;
+ case GL_RGB5_A1:
+ return AHARDWAREBUFFER_FORMAT_B5G5R5A1_UNORM;
+ case GL_RGBA4:
+ return AHARDWAREBUFFER_FORMAT_B4G4R4A4_UNORM;
+ case GL_RGBA16F:
+ return AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT;
+ case GL_RGB10_A2:
+ return AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM;
+ case GL_NONE:
+ return AHARDWAREBUFFER_FORMAT_BLOB;
+ case GL_DEPTH_COMPONENT16:
+ return AHARDWAREBUFFER_FORMAT_D16_UNORM;
+ case GL_DEPTH_COMPONENT24:
+ return AHARDWAREBUFFER_FORMAT_D24_UNORM;
+ case GL_DEPTH24_STENCIL8:
+ return AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT;
+ case GL_DEPTH_COMPONENT32F:
+ return AHARDWAREBUFFER_FORMAT_D32_FLOAT;
+ case GL_DEPTH32F_STENCIL8:
+ return AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT;
+ case GL_STENCIL_INDEX8:
+ return AHARDWAREBUFFER_FORMAT_S8_UINT;
+ default:
+ WARN() << "Unknown internalFormat: " << internalFormat << ". Treating as 0";
+ return 0;
+ }
+}
+
+bool NativePixelFormatIsYUV(int pixelFormat)
+{
+ bool isYuv = false;
+ GetPixelFormatInfo(pixelFormat, &isYuv);
+ return isYuv;
+}
+
+AHardwareBuffer *ANativeWindowBufferToAHardwareBuffer(ANativeWindowBuffer *windowBuffer)
+{
+ return OffsetPointer<AHardwareBuffer>(windowBuffer,
+ -kAHardwareBufferToANativeWindowBufferOffset);
+}
+
+EGLClientBuffer AHardwareBufferToClientBuffer(const AHardwareBuffer *hardwareBuffer)
+{
+ return OffsetPointer<EGLClientBuffer>(hardwareBuffer,
+ kAHardwareBufferToANativeWindowBufferOffset);
+}
+
+AHardwareBuffer *ClientBufferToAHardwareBuffer(EGLClientBuffer clientBuffer)
+{
+ return OffsetPointer<AHardwareBuffer>(clientBuffer,
+ -kAHardwareBufferToANativeWindowBufferOffset);
+}
+} // namespace android
+} // namespace angle
diff --git a/gfx/angle/checkout/src/common/android_util.h b/gfx/angle/checkout/src/common/android_util.h
new file mode 100644
index 0000000000..eee60ba244
--- /dev/null
+++ b/gfx/angle/checkout/src/common/android_util.h
@@ -0,0 +1,59 @@
+//
+// Copyright 2018 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.
+//
+
+// android_util.h: Utilities for the using the Android platform
+
+#ifndef COMMON_ANDROIDUTIL_H_
+#define COMMON_ANDROIDUTIL_H_
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include <stdint.h>
+#include <array>
+
+#include "angle_gl.h"
+
+struct ANativeWindowBuffer;
+struct AHardwareBuffer;
+
+namespace angle
+{
+
+namespace android
+{
+
+constexpr std::array<GLenum, 3> kSupportedSizedInternalFormats = {GL_RGBA8, GL_RGB8, GL_RGB565};
+
+ANativeWindowBuffer *ClientBufferToANativeWindowBuffer(EGLClientBuffer clientBuffer);
+EGLClientBuffer AHardwareBufferToClientBuffer(const AHardwareBuffer *hardwareBuffer);
+AHardwareBuffer *ClientBufferToAHardwareBuffer(EGLClientBuffer clientBuffer);
+
+EGLClientBuffer CreateEGLClientBufferFromAHardwareBuffer(int width,
+ int height,
+ int depth,
+ int androidFormat,
+ int usage);
+
+void GetANativeWindowBufferProperties(const ANativeWindowBuffer *buffer,
+ int *width,
+ int *height,
+ int *depth,
+ int *pixelFormat,
+ uint64_t *usage);
+GLenum NativePixelFormatToGLInternalFormat(int pixelFormat);
+int GLInternalFormatToNativePixelFormat(GLenum internalFormat);
+
+bool NativePixelFormatIsYUV(int pixelFormat);
+
+AHardwareBuffer *ANativeWindowBufferToAHardwareBuffer(ANativeWindowBuffer *windowBuffer);
+
+uint64_t GetAHBUsage(int eglNativeBufferUsage);
+
+} // namespace android
+} // namespace angle
+
+#endif // COMMON_ANDROIDUTIL_H_
diff --git a/gfx/angle/checkout/src/common/angle_version.h b/gfx/angle/checkout/src/common/angle_version.h
new file mode 100644
index 0000000000..d9d7e8929d
--- /dev/null
+++ b/gfx/angle/checkout/src/common/angle_version.h
@@ -0,0 +1,28 @@
+//
+// 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.
+//
+// angle_version.h: ANGLE version constants. Generated from git commands.
+
+#ifndef COMMON_ANGLE_VERSION_H_
+#define COMMON_ANGLE_VERSION_H_
+
+#include "angle_commit.h"
+
+#define ANGLE_MAJOR_VERSION 2
+#define ANGLE_MINOR_VERSION 1
+
+#ifndef ANGLE_REVISION
+# define ANGLE_REVISION ANGLE_COMMIT_POSITION
+#endif
+
+#define ANGLE_STRINGIFY(x) #x
+#define ANGLE_MACRO_STRINGIFY(x) ANGLE_STRINGIFY(x)
+
+#define ANGLE_VERSION_STRING \
+ ANGLE_MACRO_STRINGIFY(ANGLE_MAJOR_VERSION) \
+ "." ANGLE_MACRO_STRINGIFY(ANGLE_MINOR_VERSION) "." ANGLE_MACRO_STRINGIFY( \
+ ANGLE_REVISION) " git hash: " ANGLE_COMMIT_HASH
+
+#endif // COMMON_ANGLE_VERSION_H_
diff --git a/gfx/angle/checkout/src/common/angle_version_info.cpp b/gfx/angle/checkout/src/common/angle_version_info.cpp
new file mode 100644
index 0000000000..963741a456
--- /dev/null
+++ b/gfx/angle/checkout/src/common/angle_version_info.cpp
@@ -0,0 +1,40 @@
+//
+// Copyright 2021 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_version_info.cpp: ANGLE version queries.
+
+#include "common/angle_version.h"
+
+namespace angle
+{
+int GetANGLERevision()
+{
+ return ANGLE_REVISION;
+}
+
+const char *GetANGLEVersionString()
+{
+ return ANGLE_VERSION_STRING;
+}
+
+const char *GetANGLECommitHash()
+{
+ return ANGLE_COMMIT_HASH;
+}
+
+int GetANGLECommitHashSize()
+{
+ return ANGLE_COMMIT_HASH_SIZE;
+}
+
+bool GetANGLEHasBinaryLoading()
+{
+#ifdef ANGLE_HAS_BINARY_LOADING
+ return true;
+#else
+ return false;
+#endif // #ifndef ANGLE_HAS_BINARY_LOADING
+}
+} // namespace angle
diff --git a/gfx/angle/checkout/src/common/angle_version_info.h b/gfx/angle/checkout/src/common/angle_version_info.h
new file mode 100644
index 0000000000..1d5392068c
--- /dev/null
+++ b/gfx/angle/checkout/src/common/angle_version_info.h
@@ -0,0 +1,20 @@
+//
+// Copyright 2021 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_version_info.h: ANGLE version queries.
+
+#ifndef COMMON_VERSION_INFO_H_
+#define COMMON_VERSION_INFO_H_
+
+namespace angle
+{
+int GetANGLERevision();
+const char *GetANGLEVersionString();
+const char *GetANGLECommitHash();
+int GetANGLECommitHashSize();
+bool GetANGLEHasBinaryLoading();
+} // namespace angle
+
+#endif // COMMON_VERSION_INFO_H_
diff --git a/gfx/angle/checkout/src/common/angleutils.cpp b/gfx/angle/checkout/src/common/angleutils.cpp
new file mode 100644
index 0000000000..2b69f66d74
--- /dev/null
+++ b/gfx/angle/checkout/src/common/angleutils.cpp
@@ -0,0 +1,156 @@
+//
+// 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.
+//
+
+#include "common/angleutils.h"
+#include "common/debug.h"
+
+#include <stdio.h>
+
+#include <limits>
+#include <vector>
+
+namespace angle
+{
+// dirtyPointer is a special value that will make the comparison with any valid pointer fail and
+// force the renderer to re-apply the state.
+const uintptr_t DirtyPointer = std::numeric_limits<uintptr_t>::max();
+
+SaveFileHelper::SaveFileHelper(const std::string &filePathIn)
+ : mOfs(filePathIn, std::ios::binary | std::ios::out), mFilePath(filePathIn)
+{
+ if (!mOfs.is_open())
+ {
+ FATAL() << "Could not open " << filePathIn;
+ }
+}
+
+SaveFileHelper::~SaveFileHelper()
+{
+ printf("Saved '%s'.\n", mFilePath.c_str());
+}
+
+void SaveFileHelper::checkError()
+{
+ if (mOfs.bad())
+ {
+ FATAL() << "Error writing to " << mFilePath;
+ }
+}
+
+void SaveFileHelper::write(const uint8_t *data, size_t size)
+{
+ mOfs.write(reinterpret_cast<const char *>(data), size);
+}
+
+// AMD_performance_monitor helpers.
+
+PerfMonitorCounter::PerfMonitorCounter() = default;
+
+PerfMonitorCounter::~PerfMonitorCounter() = default;
+
+PerfMonitorCounterGroup::PerfMonitorCounterGroup() = default;
+
+PerfMonitorCounterGroup::~PerfMonitorCounterGroup() = default;
+
+uint32_t GetPerfMonitorCounterIndex(const PerfMonitorCounters &counters, const std::string &name)
+{
+ for (uint32_t counterIndex = 0; counterIndex < static_cast<uint32_t>(counters.size());
+ ++counterIndex)
+ {
+ if (counters[counterIndex].name == name)
+ {
+ return counterIndex;
+ }
+ }
+
+ return std::numeric_limits<uint32_t>::max();
+}
+
+uint32_t GetPerfMonitorCounterGroupIndex(const PerfMonitorCounterGroups &groups,
+ const std::string &name)
+{
+ for (uint32_t groupIndex = 0; groupIndex < static_cast<uint32_t>(groups.size()); ++groupIndex)
+ {
+ if (groups[groupIndex].name == name)
+ {
+ return groupIndex;
+ }
+ }
+
+ return std::numeric_limits<uint32_t>::max();
+}
+
+const PerfMonitorCounter &GetPerfMonitorCounter(const PerfMonitorCounters &counters,
+ const std::string &name)
+{
+ return GetPerfMonitorCounter(const_cast<PerfMonitorCounters &>(counters), name);
+}
+
+PerfMonitorCounter &GetPerfMonitorCounter(PerfMonitorCounters &counters, const std::string &name)
+{
+ uint32_t counterIndex = GetPerfMonitorCounterIndex(counters, name);
+ ASSERT(counterIndex < static_cast<uint32_t>(counters.size()));
+ return counters[counterIndex];
+}
+
+const PerfMonitorCounterGroup &GetPerfMonitorCounterGroup(const PerfMonitorCounterGroups &groups,
+ const std::string &name)
+{
+ return GetPerfMonitorCounterGroup(const_cast<PerfMonitorCounterGroups &>(groups), name);
+}
+
+PerfMonitorCounterGroup &GetPerfMonitorCounterGroup(PerfMonitorCounterGroups &groups,
+ const std::string &name)
+{
+ uint32_t groupIndex = GetPerfMonitorCounterGroupIndex(groups, name);
+ ASSERT(groupIndex < static_cast<uint32_t>(groups.size()));
+ return groups[groupIndex];
+}
+} // namespace angle
+
+std::string ArrayString(unsigned int i)
+{
+ // We assume that UINT_MAX and GL_INVALID_INDEX are equal.
+ ASSERT(i != UINT_MAX);
+
+ std::stringstream strstr;
+ strstr << "[";
+ strstr << i;
+ strstr << "]";
+ return strstr.str();
+}
+
+std::string ArrayIndexString(const std::vector<unsigned int> &indices)
+{
+ std::stringstream strstr;
+
+ for (auto indicesIt = indices.rbegin(); indicesIt != indices.rend(); ++indicesIt)
+ {
+ // We assume that UINT_MAX and GL_INVALID_INDEX are equal.
+ ASSERT(*indicesIt != UINT_MAX);
+ strstr << "[";
+ strstr << (*indicesIt);
+ strstr << "]";
+ }
+
+ return strstr.str();
+}
+
+size_t FormatStringIntoVector(const char *fmt, va_list vararg, std::vector<char> &outBuffer)
+{
+ va_list varargCopy;
+ va_copy(varargCopy, vararg);
+
+ int len = vsnprintf(nullptr, 0, fmt, vararg);
+ ASSERT(len >= 0);
+
+ outBuffer.resize(len + 1, 0);
+
+ len = vsnprintf(outBuffer.data(), outBuffer.size(), fmt, varargCopy);
+ va_end(varargCopy);
+ ASSERT(len >= 0);
+ return static_cast<size_t>(len);
+}
diff --git a/gfx/angle/checkout/src/common/angleutils.h b/gfx/angle/checkout/src/common/angleutils.h
new file mode 100644
index 0000000000..bcbcabc782
--- /dev/null
+++ b/gfx/angle/checkout/src/common/angleutils.h
@@ -0,0 +1,601 @@
+//
+// Copyright 2002 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.
+//
+
+// angleutils.h: Common ANGLE utilities.
+
+#ifndef COMMON_ANGLEUTILS_H_
+#define COMMON_ANGLEUTILS_H_
+
+#include "common/platform.h"
+
+#if defined(ANGLE_USE_ABSEIL)
+# include "absl/container/flat_hash_map.h"
+# include "absl/container/flat_hash_set.h"
+#endif // defined(ANGLE_USE_ABSEIL)
+
+#if defined(ANGLE_WITH_LSAN)
+# include <sanitizer/lsan_interface.h>
+#endif // defined(ANGLE_WITH_LSAN)
+
+#include <climits>
+#include <cstdarg>
+#include <cstddef>
+#include <fstream>
+#include <mutex>
+#include <set>
+#include <sstream>
+#include <string>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+// A helper class to disallow copy and assignment operators
+namespace angle
+{
+
+#if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11)
+using Microsoft::WRL::ComPtr;
+#endif // defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11)
+
+#if defined(ANGLE_USE_ABSEIL)
+template <typename Key, typename T, class Hash = absl::container_internal::hash_default_hash<Key>>
+using HashMap = absl::flat_hash_map<Key, T, Hash>;
+template <typename Key, class Hash = absl::container_internal::hash_default_hash<Key>>
+using HashSet = absl::flat_hash_set<Key, Hash>;
+#else
+template <typename Key, typename T, class Hash = std::hash<Key>>
+using HashMap = std::unordered_map<Key, T, Hash>;
+template <typename Key, class Hash = std::hash<Key>>
+using HashSet = std::unordered_set<Key, Hash>;
+#endif // defined(ANGLE_USE_ABSEIL)
+
+class NonCopyable
+{
+ protected:
+ constexpr NonCopyable() = default;
+ ~NonCopyable() = default;
+
+ private:
+ NonCopyable(const NonCopyable &) = delete;
+ void operator=(const NonCopyable &) = delete;
+};
+
+extern const uintptr_t DirtyPointer;
+
+struct SaveFileHelper
+{
+ public:
+ // We always use ios::binary to avoid inconsistent line endings when captured on Linux vs Win.
+ SaveFileHelper(const std::string &filePathIn);
+ ~SaveFileHelper();
+
+ template <typename T>
+ SaveFileHelper &operator<<(const T &value)
+ {
+ mOfs << value;
+ checkError();
+ return *this;
+ }
+
+ void write(const uint8_t *data, size_t size);
+
+ private:
+ void checkError();
+
+ std::ofstream mOfs;
+ std::string mFilePath;
+};
+
+// AMD_performance_monitor helpers.
+constexpr char kPerfMonitorExtensionName[] = "GL_AMD_performance_monitor";
+
+struct PerfMonitorCounter
+{
+ PerfMonitorCounter();
+ ~PerfMonitorCounter();
+
+ std::string name;
+ uint64_t value;
+};
+using PerfMonitorCounters = std::vector<PerfMonitorCounter>;
+
+struct PerfMonitorCounterGroup
+{
+ PerfMonitorCounterGroup();
+ ~PerfMonitorCounterGroup();
+
+ std::string name;
+ PerfMonitorCounters counters;
+};
+using PerfMonitorCounterGroups = std::vector<PerfMonitorCounterGroup>;
+
+uint32_t GetPerfMonitorCounterIndex(const PerfMonitorCounters &counters, const std::string &name);
+const PerfMonitorCounter &GetPerfMonitorCounter(const PerfMonitorCounters &counters,
+ const std::string &name);
+PerfMonitorCounter &GetPerfMonitorCounter(PerfMonitorCounters &counters, const std::string &name);
+uint32_t GetPerfMonitorCounterGroupIndex(const PerfMonitorCounterGroups &groups,
+ const std::string &name);
+const PerfMonitorCounterGroup &GetPerfMonitorCounterGroup(const PerfMonitorCounterGroups &groups,
+ const std::string &name);
+PerfMonitorCounterGroup &GetPerfMonitorCounterGroup(PerfMonitorCounterGroups &groups,
+ const std::string &name);
+
+struct PerfMonitorTriplet
+{
+ uint32_t group;
+ uint32_t counter;
+ uint64_t value;
+};
+
+#define ANGLE_VK_PERF_COUNTERS_X(FN) \
+ FN(commandQueueSubmitCallsTotal) \
+ FN(commandQueueSubmitCallsPerFrame) \
+ FN(vkQueueSubmitCallsTotal) \
+ FN(vkQueueSubmitCallsPerFrame) \
+ FN(renderPasses) \
+ FN(writeDescriptorSets) \
+ FN(flushedOutsideRenderPassCommandBuffers) \
+ FN(swapchainResolveInSubpass) \
+ FN(swapchainResolveOutsideSubpass) \
+ FN(resolveImageCommands) \
+ FN(colorLoadOpClears) \
+ FN(colorLoadOpLoads) \
+ FN(colorLoadOpNones) \
+ FN(colorStoreOpStores) \
+ FN(colorStoreOpNones) \
+ FN(colorClearAttachments) \
+ FN(depthLoadOpClears) \
+ FN(depthLoadOpLoads) \
+ FN(depthLoadOpNones) \
+ FN(depthStoreOpStores) \
+ FN(depthStoreOpNones) \
+ FN(depthClearAttachments) \
+ FN(stencilLoadOpClears) \
+ FN(stencilLoadOpLoads) \
+ FN(stencilLoadOpNones) \
+ FN(stencilStoreOpStores) \
+ FN(stencilStoreOpNones) \
+ FN(stencilClearAttachments) \
+ FN(colorAttachmentUnresolves) \
+ FN(depthAttachmentUnresolves) \
+ FN(stencilAttachmentUnresolves) \
+ FN(colorAttachmentResolves) \
+ FN(depthAttachmentResolves) \
+ FN(stencilAttachmentResolves) \
+ FN(readOnlyDepthStencilRenderPasses) \
+ FN(pipelineCreationCacheHits) \
+ FN(pipelineCreationCacheMisses) \
+ FN(pipelineCreationTotalCacheHitsDurationNs) \
+ FN(pipelineCreationTotalCacheMissesDurationNs) \
+ FN(descriptorSetAllocations) \
+ FN(descriptorSetCacheTotalSize) \
+ FN(descriptorSetCacheKeySizeBytes) \
+ FN(uniformsAndXfbDescriptorSetCacheHits) \
+ FN(uniformsAndXfbDescriptorSetCacheMisses) \
+ FN(uniformsAndXfbDescriptorSetCacheTotalSize) \
+ FN(textureDescriptorSetCacheHits) \
+ FN(textureDescriptorSetCacheMisses) \
+ FN(textureDescriptorSetCacheTotalSize) \
+ FN(shaderResourcesDescriptorSetCacheHits) \
+ FN(mutableTexturesUploaded) \
+ FN(shaderResourcesDescriptorSetCacheMisses) \
+ FN(shaderResourcesDescriptorSetCacheTotalSize) \
+ FN(buffersGhosted) \
+ FN(vertexArraySyncStateCalls) \
+ FN(allocateNewBufferBlockCalls) \
+ FN(dynamicBufferAllocations) \
+ FN(framebufferCacheSize)
+
+#define ANGLE_DECLARE_PERF_COUNTER(COUNTER) uint64_t COUNTER;
+
+struct VulkanPerfCounters
+{
+ ANGLE_VK_PERF_COUNTERS_X(ANGLE_DECLARE_PERF_COUNTER)
+};
+
+#undef ANGLE_DECLARE_PERF_COUNTER
+
+} // namespace angle
+
+template <typename T, size_t N>
+constexpr inline size_t ArraySize(T (&)[N])
+{
+ return N;
+}
+
+template <typename T>
+class WrappedArray final : angle::NonCopyable
+{
+ public:
+ template <size_t N>
+ constexpr WrappedArray(const T (&data)[N]) : mArray(&data[0]), mSize(N)
+ {}
+
+ constexpr WrappedArray() : mArray(nullptr), mSize(0) {}
+ constexpr WrappedArray(const T *data, size_t size) : mArray(data), mSize(size) {}
+
+ WrappedArray(WrappedArray &&other) : WrappedArray()
+ {
+ std::swap(mArray, other.mArray);
+ std::swap(mSize, other.mSize);
+ }
+
+ ~WrappedArray() {}
+
+ constexpr const T *get() const { return mArray; }
+ constexpr size_t size() const { return mSize; }
+
+ private:
+ const T *mArray;
+ size_t mSize;
+};
+
+template <typename T, unsigned int N>
+void SafeRelease(T (&resourceBlock)[N])
+{
+ for (unsigned int i = 0; i < N; i++)
+ {
+ SafeRelease(resourceBlock[i]);
+ }
+}
+
+template <typename T>
+void SafeRelease(T &resource)
+{
+ if (resource)
+ {
+ resource->Release();
+ resource = nullptr;
+ }
+}
+
+template <typename T>
+void SafeDelete(T *&resource)
+{
+ delete resource;
+ resource = nullptr;
+}
+
+template <typename T>
+void SafeDeleteContainer(T &resource)
+{
+ for (auto &element : resource)
+ {
+ SafeDelete(element);
+ }
+ resource.clear();
+}
+
+template <typename T>
+void SafeDeleteArray(T *&resource)
+{
+ delete[] resource;
+ resource = nullptr;
+}
+
+// Provide a less-than function for comparing structs
+// Note: struct memory must be initialized to zero, because of packing gaps
+template <typename T>
+inline bool StructLessThan(const T &a, const T &b)
+{
+ return (memcmp(&a, &b, sizeof(T)) < 0);
+}
+
+// Provide a less-than function for comparing structs
+// Note: struct memory must be initialized to zero, because of packing gaps
+template <typename T>
+inline bool StructEquals(const T &a, const T &b)
+{
+ return (memcmp(&a, &b, sizeof(T)) == 0);
+}
+
+template <typename T>
+inline void StructZero(T *obj)
+{
+ memset(obj, 0, sizeof(T));
+}
+
+template <typename T>
+inline bool IsMaskFlagSet(T mask, T flag)
+{
+ // Handles multibit flags as well
+ return (mask & flag) == flag;
+}
+
+inline const char *MakeStaticString(const std::string &str)
+{
+ // On the heap so that no destructor runs on application exit.
+ static std::set<std::string> *strings = new std::set<std::string>;
+ std::set<std::string>::iterator it = strings->find(str);
+ if (it != strings->end())
+ {
+ return it->c_str();
+ }
+
+ return strings->insert(str).first->c_str();
+}
+
+std::string ArrayString(unsigned int i);
+
+// Indices are stored in vectors with the outermost index in the back. In the output of the function
+// the indices are reversed.
+std::string ArrayIndexString(const std::vector<unsigned int> &indices);
+
+inline std::string Str(int i)
+{
+ std::stringstream strstr;
+ strstr << i;
+ return strstr.str();
+}
+
+template <typename T>
+std::string ToString(const T &value)
+{
+ std::ostringstream o;
+ o << value;
+ return o.str();
+}
+
+inline bool IsLittleEndian()
+{
+ constexpr uint32_t kEndiannessTest = 1;
+ const bool isLittleEndian = *reinterpret_cast<const uint8_t *>(&kEndiannessTest) == 1;
+ return isLittleEndian;
+}
+
+// Helper class to use a mutex with the control of boolean.
+class ConditionalMutex final : angle::NonCopyable
+{
+ public:
+ ConditionalMutex() : mUseMutex(true) {}
+ void init(bool useMutex) { mUseMutex = useMutex; }
+ void lock()
+ {
+ if (mUseMutex)
+ {
+ mMutex.lock();
+ }
+ }
+ void unlock()
+ {
+ if (mUseMutex)
+ {
+ mMutex.unlock();
+ }
+ }
+
+ private:
+ std::mutex mMutex;
+ bool mUseMutex;
+};
+
+// snprintf is not defined with MSVC prior to to msvc14
+#if defined(_MSC_VER) && _MSC_VER < 1900
+# define snprintf _snprintf
+#endif
+
+#define GL_A1RGB5_ANGLEX 0x6AC5
+#define GL_BGRX8_ANGLEX 0x6ABA
+#define GL_BGR565_ANGLEX 0x6ABB
+#define GL_BGRA4_ANGLEX 0x6ABC
+#define GL_BGR5_A1_ANGLEX 0x6ABD
+#define GL_INT_64_ANGLEX 0x6ABE
+#define GL_UINT_64_ANGLEX 0x6ABF
+#define GL_BGRA8_SRGB_ANGLEX 0x6AC0
+#define GL_BGR10_A2_ANGLEX 0x6AF9
+
+// These are fake formats used to fit typeless D3D textures that can be bound to EGL pbuffers into
+// the format system (for extension EGL_ANGLE_d3d_texture_client_buffer):
+#define GL_RGBA8_TYPELESS_ANGLEX 0x6AC1
+#define GL_RGBA8_TYPELESS_SRGB_ANGLEX 0x6AC2
+#define GL_BGRA8_TYPELESS_ANGLEX 0x6AC3
+#define GL_BGRA8_TYPELESS_SRGB_ANGLEX 0x6AC4
+
+#define GL_R8_SSCALED_ANGLEX 0x6AC6
+#define GL_RG8_SSCALED_ANGLEX 0x6AC7
+#define GL_RGB8_SSCALED_ANGLEX 0x6AC8
+#define GL_RGBA8_SSCALED_ANGLEX 0x6AC9
+#define GL_R8_USCALED_ANGLEX 0x6ACA
+#define GL_RG8_USCALED_ANGLEX 0x6ACB
+#define GL_RGB8_USCALED_ANGLEX 0x6ACC
+#define GL_RGBA8_USCALED_ANGLEX 0x6ACD
+
+#define GL_R16_SSCALED_ANGLEX 0x6ACE
+#define GL_RG16_SSCALED_ANGLEX 0x6ACF
+#define GL_RGB16_SSCALED_ANGLEX 0x6AD0
+#define GL_RGBA16_SSCALED_ANGLEX 0x6AD1
+#define GL_R16_USCALED_ANGLEX 0x6AD2
+#define GL_RG16_USCALED_ANGLEX 0x6AD3
+#define GL_RGB16_USCALED_ANGLEX 0x6AD4
+#define GL_RGBA16_USCALED_ANGLEX 0x6AD5
+
+#define GL_R32_SSCALED_ANGLEX 0x6AD6
+#define GL_RG32_SSCALED_ANGLEX 0x6AD7
+#define GL_RGB32_SSCALED_ANGLEX 0x6AD8
+#define GL_RGBA32_SSCALED_ANGLEX 0x6AD9
+#define GL_R32_USCALED_ANGLEX 0x6ADA
+#define GL_RG32_USCALED_ANGLEX 0x6ADB
+#define GL_RGB32_USCALED_ANGLEX 0x6ADC
+#define GL_RGBA32_USCALED_ANGLEX 0x6ADD
+
+#define GL_R32_SNORM_ANGLEX 0x6ADE
+#define GL_RG32_SNORM_ANGLEX 0x6ADF
+#define GL_RGB32_SNORM_ANGLEX 0x6AE0
+#define GL_RGBA32_SNORM_ANGLEX 0x6AE1
+#define GL_R32_UNORM_ANGLEX 0x6AE2
+#define GL_RG32_UNORM_ANGLEX 0x6AE3
+#define GL_RGB32_UNORM_ANGLEX 0x6AE4
+#define GL_RGBA32_UNORM_ANGLEX 0x6AE5
+
+#define GL_R32_FIXED_ANGLEX 0x6AE6
+#define GL_RG32_FIXED_ANGLEX 0x6AE7
+#define GL_RGB32_FIXED_ANGLEX 0x6AE8
+#define GL_RGBA32_FIXED_ANGLEX 0x6AE9
+
+#define GL_RGB10_A2_SINT_ANGLEX 0x6AEA
+#define GL_RGB10_A2_SNORM_ANGLEX 0x6AEB
+#define GL_RGB10_A2_SSCALED_ANGLEX 0x6AEC
+#define GL_RGB10_A2_USCALED_ANGLEX 0x6AED
+
+// EXT_texture_type_2_10_10_10_REV
+#define GL_RGB10_UNORM_ANGLEX 0x6AEE
+
+// These are fake formats for OES_vertex_type_10_10_10_2
+#define GL_A2_RGB10_UNORM_ANGLEX 0x6AEF
+#define GL_A2_RGB10_SNORM_ANGLEX 0x6AF0
+#define GL_A2_RGB10_USCALED_ANGLEX 0x6AF1
+#define GL_A2_RGB10_SSCALED_ANGLEX 0x6AF2
+#define GL_X2_RGB10_UINT_ANGLEX 0x6AF3
+#define GL_X2_RGB10_SINT_ANGLEX 0x6AF4
+#define GL_X2_RGB10_USCALED_ANGLEX 0x6AF5
+#define GL_X2_RGB10_SSCALED_ANGLEX 0x6AF6
+#define GL_X2_RGB10_UNORM_ANGLEX 0x6AF7
+#define GL_X2_RGB10_SNORM_ANGLEX 0x6AF8
+
+#define ANGLE_CHECK_GL_ALLOC(context, result) \
+ ANGLE_CHECK(context, result, "Failed to allocate host memory", GL_OUT_OF_MEMORY)
+
+#define ANGLE_CHECK_GL_MATH(context, result) \
+ ANGLE_CHECK(context, result, "Integer overflow.", GL_INVALID_OPERATION)
+
+#define ANGLE_GL_UNREACHABLE(context) \
+ UNREACHABLE(); \
+ ANGLE_CHECK(context, false, "Unreachable Code.", GL_INVALID_OPERATION)
+
+#if defined(ANGLE_WITH_LSAN)
+# define ANGLE_SCOPED_DISABLE_LSAN() __lsan::ScopedDisabler lsanDisabler
+#else
+# define ANGLE_SCOPED_DISABLE_LSAN()
+#endif
+
+#if defined(ANGLE_WITH_MSAN)
+class MsanScopedDisableInterceptorChecks final : angle::NonCopyable
+{
+ public:
+ MsanScopedDisableInterceptorChecks() { __msan_scoped_disable_interceptor_checks(); }
+ ~MsanScopedDisableInterceptorChecks() { __msan_scoped_enable_interceptor_checks(); }
+};
+# define ANGLE_SCOPED_DISABLE_MSAN() \
+ MsanScopedDisableInterceptorChecks msanScopedDisableInterceptorChecks
+#else
+# define ANGLE_SCOPED_DISABLE_MSAN()
+#endif
+
+// The ANGLE_NO_SANITIZE_MEMORY macro suppresses MemorySanitizer checks for
+// use-of-uninitialized-data. It can be used to decorate functions with known
+// false positives.
+#ifdef __clang__
+# define ANGLE_NO_SANITIZE_MEMORY __attribute__((no_sanitize_memory))
+#else
+# define ANGLE_NO_SANITIZE_MEMORY
+#endif
+
+// Similar to the above, but for thread sanitization.
+#ifdef __clang__
+# define ANGLE_NO_SANITIZE_THREAD __attribute__((no_sanitize_thread))
+#else
+# define ANGLE_NO_SANITIZE_THREAD
+#endif
+
+// The below inlining code lifted from V8.
+#if defined(__clang__) || (defined(__GNUC__) && defined(__has_attribute))
+# define ANGLE_HAS_ATTRIBUTE_ALWAYS_INLINE (__has_attribute(always_inline))
+# define ANGLE_HAS___FORCEINLINE 0
+#elif defined(_MSC_VER)
+# define ANGLE_HAS_ATTRIBUTE_ALWAYS_INLINE 0
+# define ANGLE_HAS___FORCEINLINE 1
+#else
+# define ANGLE_HAS_ATTRIBUTE_ALWAYS_INLINE 0
+# define ANGLE_HAS___FORCEINLINE 0
+#endif
+
+#if defined(NDEBUG) && ANGLE_HAS_ATTRIBUTE_ALWAYS_INLINE
+# define ANGLE_INLINE inline __attribute__((always_inline))
+#elif defined(NDEBUG) && ANGLE_HAS___FORCEINLINE
+# define ANGLE_INLINE __forceinline
+#else
+# define ANGLE_INLINE inline
+#endif
+
+#if defined(__clang__) || (defined(__GNUC__) && defined(__has_attribute))
+# if __has_attribute(noinline)
+# define ANGLE_NOINLINE __attribute__((noinline))
+# else
+# define ANGLE_NOINLINE
+# endif
+#elif defined(_MSC_VER)
+# define ANGLE_NOINLINE __declspec(noinline)
+#else
+# define ANGLE_NOINLINE
+#endif
+
+#if defined(__clang__) || (defined(__GNUC__) && defined(__has_attribute))
+# if __has_attribute(format)
+# define ANGLE_FORMAT_PRINTF(fmt, args) __attribute__((format(__printf__, fmt, args)))
+# else
+# define ANGLE_FORMAT_PRINTF(fmt, args)
+# endif
+#else
+# define ANGLE_FORMAT_PRINTF(fmt, args)
+#endif
+
+ANGLE_FORMAT_PRINTF(1, 0)
+size_t FormatStringIntoVector(const char *fmt, va_list vararg, std::vector<char> &buffer);
+
+// Format messes up the # inside the macro.
+// clang-format off
+#ifndef ANGLE_STRINGIFY
+# define ANGLE_STRINGIFY(x) #x
+#endif
+// clang-format on
+
+#ifndef ANGLE_MACRO_STRINGIFY
+# define ANGLE_MACRO_STRINGIFY(x) ANGLE_STRINGIFY(x)
+#endif
+
+#if __has_cpp_attribute(clang::require_constant_initialization)
+# define ANGLE_REQUIRE_CONSTANT_INIT [[clang::require_constant_initialization]]
+#else
+# define ANGLE_REQUIRE_CONSTANT_INIT
+#endif // __has_cpp_attribute(require_constant_initialization)
+
+// Compiler configs.
+inline bool IsASan()
+{
+#if defined(ANGLE_WITH_ASAN)
+ return true;
+#else
+ return false;
+#endif // defined(ANGLE_WITH_ASAN)
+}
+
+inline bool IsMSan()
+{
+#if defined(ANGLE_WITH_MSAN)
+ return true;
+#else
+ return false;
+#endif // defined(ANGLE_WITH_MSAN)
+}
+
+inline bool IsTSan()
+{
+#if defined(ANGLE_WITH_TSAN)
+ return true;
+#else
+ return false;
+#endif // defined(ANGLE_WITH_TSAN)
+}
+
+inline bool IsUBSan()
+{
+#if defined(ANGLE_WITH_UBSAN)
+ return true;
+#else
+ return false;
+#endif // defined(ANGLE_WITH_UBSAN)
+}
+#endif // COMMON_ANGLEUTILS_H_
diff --git a/gfx/angle/checkout/src/common/apple_platform_utils.h b/gfx/angle/checkout/src/common/apple_platform_utils.h
new file mode 100644
index 0000000000..da932a9207
--- /dev/null
+++ b/gfx/angle/checkout/src/common/apple_platform_utils.h
@@ -0,0 +1,90 @@
+//
+// Copyright 2019 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.
+//
+
+// apple_platform_utils.h: Common utilities for Apple platforms.
+
+#ifndef COMMON_APPLE_PLATFORM_UTILS_H_
+#define COMMON_APPLE_PLATFORM_UTILS_H_
+
+#include "common/platform.h"
+
+// These are macros for substitution of Apple specific directive @available:
+
+// TARGET_OS_MACCATALYST only available in MacSDK 10.15
+
+#if TARGET_OS_MACCATALYST
+// ANGLE_APPLE_AVAILABLE_XCI: check if either of the 3 platforms (OSX/Catalyst/iOS) min verions is
+// available:
+# define ANGLE_APPLE_AVAILABLE_XCI(macVer, macCatalystVer, iOSVer) \
+ @available(macOS macVer, macCatalyst macCatalystVer, iOS iOSVer, *)
+// ANGLE_APPLE_AVAILABLE_XC: check if either of the 2 platforms (OSX/Catalyst) min verions is
+// available:
+# define ANGLE_APPLE_AVAILABLE_XC(macVer, macCatalystVer) \
+ @available(macOS macVer, macCatalyst macCatalystVer, *)
+// ANGLE_APPLE_AVAILABLE_CI: check if either of the 2 platforms (Catalyst/iOS) min verions is
+// available:
+# define ANGLE_APPLE_AVAILABLE_CI(macCatalystVer, iOSVer) \
+ @available(macCatalyst macCatalystVer, iOS iOSVer, *)
+#else
+# define ANGLE_APPLE_AVAILABLE_XCI(macVer, macCatalystVer, iOSVer) \
+ ANGLE_APPLE_AVAILABLE_XI(macVer, iOSVer)
+
+# define ANGLE_APPLE_AVAILABLE_XC(macVer, macCatalystVer) @available(macOS macVer, *)
+# define ANGLE_APPLE_AVAILABLE_CI(macCatalystVer, iOSVer) @available(iOS iOSVer, tvOS iOSVer, *)
+#endif
+
+// ANGLE_APPLE_AVAILABLE_XI: check if either of the 2 platforms (OSX/iOS) min verions is available:
+#define ANGLE_APPLE_AVAILABLE_XI(macVer, iOSVer) \
+ @available(macOS macVer, iOS iOSVer, tvOS iOSVer, *)
+
+// ANGLE_APPLE_AVAILABLE_I: check if a particular iOS version is available
+#define ANGLE_APPLE_AVAILABLE_I(iOSVer) @available(iOS iOSVer, tvOS iOSVer, *)
+
+#if TARGET_OS_IPHONE
+# if !defined(__IPHONE_11_0)
+# define __IPHONE_11_0 110000
+# endif
+# if !defined(ANGLE_IOS_DEPLOY_TARGET)
+# define ANGLE_IOS_DEPLOY_TARGET __IPHONE_11_0
+# endif
+# if !defined(__IPHONE_OS_VERSION_MAX_ALLOWED)
+# define __IPHONE_OS_VERSION_MAX_ALLOWED __IPHONE_11_0
+# endif
+# if !defined(__TV_OS_VERSION_MAX_ALLOWED)
+# define __TV_OS_VERSION_MAX_ALLOWED __IPHONE_11_0
+# endif
+#endif
+
+#if !defined(TARGET_OS_MACCATALYST)
+# define TARGET_OS_MACCATALYST 0
+#endif
+
+#if defined(__ARM_ARCH)
+# define ANGLE_APPLE_IS_ARM (__ARM_ARCH != 0)
+#else
+# define ANGLE_APPLE_IS_ARM 0
+#endif
+
+#define ANGLE_APPLE_OBJC_SCOPE @autoreleasepool
+
+#if !__has_feature(objc_arc)
+# define ANGLE_APPLE_AUTORELEASE autorelease
+# define ANGLE_APPLE_RETAIN retain
+# define ANGLE_APPLE_RELEASE release
+#else
+# define ANGLE_APPLE_AUTORELEASE self
+# define ANGLE_APPLE_RETAIN self
+# define ANGLE_APPLE_RELEASE self
+#endif
+
+#define ANGLE_APPLE_UNUSED __attribute__((unused))
+
+namespace angle
+{
+bool IsMetalRendererAvailable();
+}
+
+#endif
diff --git a/gfx/angle/checkout/src/common/bitset_utils.h b/gfx/angle/checkout/src/common/bitset_utils.h
new file mode 100644
index 0000000000..ee9a3f1b9b
--- /dev/null
+++ b/gfx/angle/checkout/src/common/bitset_utils.h
@@ -0,0 +1,1106 @@
+//
+// 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.
+//
+// bitset_utils:
+// Bitset-related helper classes, such as a fast iterator to scan for set bits.
+//
+
+#ifndef COMMON_BITSETITERATOR_H_
+#define COMMON_BITSETITERATOR_H_
+
+#include <stdint.h>
+
+#include <array>
+
+#include "common/angleutils.h"
+#include "common/debug.h"
+#include "common/mathutil.h"
+#include "common/platform.h"
+
+namespace angle
+{
+// Given x, create 1 << x.
+template <typename BitsT, typename ParamT>
+constexpr BitsT Bit(ParamT x)
+{
+ // It's undefined behavior if the shift size is equal to or larger than the width of the type.
+ ASSERT(static_cast<size_t>(x) < sizeof(BitsT) * 8);
+
+ return (static_cast<BitsT>(1) << static_cast<size_t>(x));
+}
+
+// Given x, create (1 << x) - 1, i.e. a mask with x bits set.
+template <typename BitsT, typename ParamT>
+constexpr BitsT BitMask(ParamT x)
+{
+ if (static_cast<size_t>(x) == 0)
+ {
+ return 0;
+ }
+ return ((Bit<BitsT>(static_cast<ParamT>(static_cast<size_t>(x) - 1)) - 1) << 1) | 1;
+}
+
+template <size_t N, typename BitsT, typename ParamT = std::size_t>
+class BitSetT final
+{
+ public:
+ class Reference final
+ {
+ public:
+ ~Reference() {}
+ Reference &operator=(bool x)
+ {
+ mParent->set(mBit, x);
+ return *this;
+ }
+ explicit operator bool() const { return mParent->test(mBit); }
+
+ private:
+ friend class BitSetT;
+
+ Reference(BitSetT *parent, ParamT bit) : mParent(parent), mBit(bit) {}
+
+ BitSetT *mParent;
+ ParamT mBit;
+ };
+
+ class Iterator final
+ {
+ public:
+ Iterator(const BitSetT &bits);
+ Iterator &operator++();
+
+ bool operator==(const Iterator &other) const;
+ bool operator!=(const Iterator &other) const;
+ ParamT operator*() const;
+
+ // These helper functions allow mutating an iterator in-flight.
+ // They only operate on later bits to ensure we don't iterate the same bit twice.
+ void resetLaterBit(std::size_t index)
+ {
+ ASSERT(index > mCurrentBit);
+ mBitsCopy.reset(index);
+ }
+
+ void setLaterBit(std::size_t index)
+ {
+ ASSERT(index > mCurrentBit);
+ mBitsCopy.set(index);
+ }
+
+ void setLaterBits(const BitSetT &bits)
+ {
+ ASSERT((BitSetT(bits) &= Mask(mCurrentBit + 1)).none());
+ mBitsCopy |= bits;
+ }
+
+ private:
+ std::size_t getNextBit();
+
+ BitSetT mBitsCopy;
+ std::size_t mCurrentBit;
+ };
+
+ using value_type = BitsT;
+ using param_type = ParamT;
+
+ constexpr BitSetT();
+ constexpr explicit BitSetT(BitsT value);
+ constexpr explicit BitSetT(std::initializer_list<ParamT> init);
+
+ constexpr BitSetT(const BitSetT &other);
+ constexpr BitSetT &operator=(const BitSetT &other);
+
+ constexpr bool operator==(const BitSetT &other) const;
+ constexpr bool operator!=(const BitSetT &other) const;
+
+ constexpr bool operator[](ParamT pos) const;
+ Reference operator[](ParamT pos) { return Reference(this, pos); }
+
+ constexpr bool test(ParamT pos) const;
+
+ constexpr bool all() const;
+ constexpr bool any() const;
+ constexpr bool none() const;
+ constexpr std::size_t count() const;
+
+ constexpr static std::size_t size() { return N; }
+
+ constexpr BitSetT &operator&=(const BitSetT &other);
+ constexpr BitSetT &operator|=(const BitSetT &other);
+ constexpr BitSetT &operator^=(const BitSetT &other);
+ constexpr BitSetT operator~() const;
+
+ constexpr BitSetT &operator&=(BitsT value);
+ constexpr BitSetT &operator|=(BitsT value);
+ constexpr BitSetT &operator^=(BitsT value);
+
+ constexpr BitSetT operator<<(std::size_t pos) const;
+ constexpr BitSetT &operator<<=(std::size_t pos);
+ constexpr BitSetT operator>>(std::size_t pos) const;
+ constexpr BitSetT &operator>>=(std::size_t pos);
+
+ constexpr BitSetT &set();
+ constexpr BitSetT &set(ParamT pos, bool value = true);
+
+ constexpr BitSetT &reset();
+ constexpr BitSetT &reset(ParamT pos);
+
+ constexpr BitSetT &flip();
+ constexpr BitSetT &flip(ParamT pos);
+
+ constexpr unsigned long to_ulong() const { return static_cast<unsigned long>(mBits); }
+ constexpr BitsT bits() const { return mBits; }
+
+ Iterator begin() const { return Iterator(*this); }
+ Iterator end() const { return Iterator(BitSetT()); }
+
+ constexpr static BitSetT Zero() { return BitSetT(); }
+
+ constexpr ParamT first() const;
+ constexpr ParamT last() const;
+
+ // Produces a mask of ones up to the "x"th bit.
+ constexpr static BitsT Mask(std::size_t x) { return BitMask<BitsT>(static_cast<ParamT>(x)); }
+
+ private:
+ BitsT mBits;
+};
+
+template <size_t N, typename BitsT, typename ParamT>
+constexpr BitSetT<N, BitsT, ParamT>::BitSetT() : mBits(0)
+{
+ static_assert(N > 0, "Bitset type cannot support zero bits.");
+ static_assert(N <= sizeof(BitsT) * 8, "Bitset type cannot support a size this large.");
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+constexpr BitSetT<N, BitsT, ParamT>::BitSetT(BitsT value) : mBits(value & Mask(N))
+{}
+
+template <size_t N, typename BitsT, typename ParamT>
+constexpr BitSetT<N, BitsT, ParamT>::BitSetT(std::initializer_list<ParamT> init) : mBits(0)
+{
+ for (ParamT element : init)
+ {
+ mBits |= Bit<BitsT>(element);
+ }
+ ASSERT(mBits == (mBits & Mask(N)));
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+constexpr BitSetT<N, BitsT, ParamT>::BitSetT(const BitSetT &other) : mBits(other.mBits)
+{}
+
+template <size_t N, typename BitsT, typename ParamT>
+constexpr BitSetT<N, BitsT, ParamT> &BitSetT<N, BitsT, ParamT>::operator=(const BitSetT &other)
+{
+ mBits = other.mBits;
+ return *this;
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+constexpr bool BitSetT<N, BitsT, ParamT>::operator==(const BitSetT &other) const
+{
+ return mBits == other.mBits;
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+constexpr bool BitSetT<N, BitsT, ParamT>::operator!=(const BitSetT &other) const
+{
+ return mBits != other.mBits;
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+constexpr bool BitSetT<N, BitsT, ParamT>::operator[](ParamT pos) const
+{
+ return test(pos);
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+constexpr bool BitSetT<N, BitsT, ParamT>::test(ParamT pos) const
+{
+ return (mBits & Bit<BitsT>(pos)) != 0;
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+constexpr bool BitSetT<N, BitsT, ParamT>::all() const
+{
+ ASSERT(mBits == (mBits & Mask(N)));
+ return mBits == Mask(N);
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+constexpr bool BitSetT<N, BitsT, ParamT>::any() const
+{
+ ASSERT(mBits == (mBits & Mask(N)));
+ return (mBits != 0);
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+constexpr bool BitSetT<N, BitsT, ParamT>::none() const
+{
+ ASSERT(mBits == (mBits & Mask(N)));
+ return (mBits == 0);
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+constexpr std::size_t BitSetT<N, BitsT, ParamT>::count() const
+{
+ return gl::BitCount(mBits);
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+constexpr BitSetT<N, BitsT, ParamT> &BitSetT<N, BitsT, ParamT>::operator&=(const BitSetT &other)
+{
+ mBits &= other.mBits;
+ return *this;
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+constexpr BitSetT<N, BitsT, ParamT> &BitSetT<N, BitsT, ParamT>::operator|=(const BitSetT &other)
+{
+ mBits |= other.mBits;
+ return *this;
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+constexpr BitSetT<N, BitsT, ParamT> &BitSetT<N, BitsT, ParamT>::operator^=(const BitSetT &other)
+{
+ mBits = mBits ^ other.mBits;
+ return *this;
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+constexpr BitSetT<N, BitsT, ParamT> BitSetT<N, BitsT, ParamT>::operator~() const
+{
+ return BitSetT<N, BitsT, ParamT>(~mBits & Mask(N));
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+constexpr BitSetT<N, BitsT, ParamT> &BitSetT<N, BitsT, ParamT>::operator&=(BitsT value)
+{
+ mBits &= value;
+ return *this;
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+constexpr BitSetT<N, BitsT, ParamT> &BitSetT<N, BitsT, ParamT>::operator|=(BitsT value)
+{
+ mBits |= value;
+ ASSERT(mBits == (mBits & Mask(N)));
+ return *this;
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+constexpr BitSetT<N, BitsT, ParamT> &BitSetT<N, BitsT, ParamT>::operator^=(BitsT value)
+{
+ mBits ^= value;
+ ASSERT(mBits == (mBits & Mask(N)));
+ return *this;
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+constexpr BitSetT<N, BitsT, ParamT> BitSetT<N, BitsT, ParamT>::operator<<(std::size_t pos) const
+{
+ return BitSetT<N, BitsT, ParamT>((mBits << pos) & Mask(N));
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+constexpr BitSetT<N, BitsT, ParamT> &BitSetT<N, BitsT, ParamT>::operator<<=(std::size_t pos)
+{
+ mBits = mBits << pos & Mask(N);
+ return *this;
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+constexpr BitSetT<N, BitsT, ParamT> BitSetT<N, BitsT, ParamT>::operator>>(std::size_t pos) const
+{
+ return BitSetT<N, BitsT, ParamT>(mBits >> pos);
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+constexpr BitSetT<N, BitsT, ParamT> &BitSetT<N, BitsT, ParamT>::operator>>=(std::size_t pos)
+{
+ mBits = (mBits >> pos) & Mask(N);
+ return *this;
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+constexpr BitSetT<N, BitsT, ParamT> &BitSetT<N, BitsT, ParamT>::set()
+{
+ ASSERT(mBits == (mBits & Mask(N)));
+ mBits = Mask(N);
+ return *this;
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+constexpr BitSetT<N, BitsT, ParamT> &BitSetT<N, BitsT, ParamT>::set(ParamT pos, bool value)
+{
+ ASSERT(static_cast<size_t>(pos) < N);
+ if (value)
+ {
+ mBits |= Bit<BitsT>(pos);
+ }
+ else
+ {
+ reset(pos);
+ }
+ ASSERT(mBits == (mBits & Mask(N)));
+ return *this;
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+constexpr BitSetT<N, BitsT, ParamT> &BitSetT<N, BitsT, ParamT>::reset()
+{
+ ASSERT(mBits == (mBits & Mask(N)));
+ mBits = 0;
+ return *this;
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+constexpr BitSetT<N, BitsT, ParamT> &BitSetT<N, BitsT, ParamT>::reset(ParamT pos)
+{
+ ASSERT(static_cast<size_t>(pos) < N);
+ ASSERT(mBits == (mBits & Mask(N)));
+ mBits &= ~Bit<BitsT>(pos);
+ return *this;
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+constexpr BitSetT<N, BitsT, ParamT> &BitSetT<N, BitsT, ParamT>::flip()
+{
+ ASSERT(mBits == (mBits & Mask(N)));
+ mBits ^= Mask(N);
+ return *this;
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+constexpr BitSetT<N, BitsT, ParamT> &BitSetT<N, BitsT, ParamT>::flip(ParamT pos)
+{
+ ASSERT(static_cast<size_t>(pos) < N);
+ mBits ^= Bit<BitsT>(pos);
+ ASSERT(mBits == (mBits & Mask(N)));
+ return *this;
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+constexpr ParamT BitSetT<N, BitsT, ParamT>::first() const
+{
+ ASSERT(!none());
+ return static_cast<ParamT>(gl::ScanForward(mBits));
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+constexpr ParamT BitSetT<N, BitsT, ParamT>::last() const
+{
+ ASSERT(!none());
+ return static_cast<ParamT>(gl::ScanReverse(mBits));
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+BitSetT<N, BitsT, ParamT>::Iterator::Iterator(const BitSetT &bits) : mBitsCopy(bits), mCurrentBit(0)
+{
+ if (bits.any())
+ {
+ mCurrentBit = getNextBit();
+ }
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+ANGLE_INLINE typename BitSetT<N, BitsT, ParamT>::Iterator &
+BitSetT<N, BitsT, ParamT>::Iterator::operator++()
+{
+ ASSERT(mBitsCopy.any());
+ mBitsCopy.reset(static_cast<ParamT>(mCurrentBit));
+ mCurrentBit = getNextBit();
+ return *this;
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+bool BitSetT<N, BitsT, ParamT>::Iterator::operator==(const Iterator &other) const
+{
+ return mBitsCopy == other.mBitsCopy;
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+bool BitSetT<N, BitsT, ParamT>::Iterator::operator!=(const Iterator &other) const
+{
+ return !(*this == other);
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+ParamT BitSetT<N, BitsT, ParamT>::Iterator::operator*() const
+{
+ return static_cast<ParamT>(mCurrentBit);
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+std::size_t BitSetT<N, BitsT, ParamT>::Iterator::getNextBit()
+{
+ if (mBitsCopy.none())
+ {
+ return 0;
+ }
+
+ return gl::ScanForward(mBitsCopy.mBits);
+}
+
+template <size_t N>
+using BitSet8 = BitSetT<N, uint8_t>;
+
+template <size_t N>
+using BitSet16 = BitSetT<N, uint16_t>;
+
+template <size_t N>
+using BitSet32 = BitSetT<N, uint32_t>;
+
+template <size_t N>
+using BitSet64 = BitSetT<N, uint64_t>;
+
+template <std::size_t N>
+class BitSetArray;
+
+namespace priv
+{
+
+template <size_t N, typename T>
+using EnableIfBitsFit = typename std::enable_if<N <= sizeof(T) * 8>::type;
+
+template <size_t N, typename Enable = void>
+struct GetBitSet
+{
+ using Type = BitSetArray<N>;
+};
+
+// Prefer 64-bit bitsets on 64-bit CPUs. They seem faster than 32-bit.
+#if defined(ANGLE_IS_64_BIT_CPU)
+template <size_t N>
+struct GetBitSet<N, EnableIfBitsFit<N, uint64_t>>
+{
+ using Type = BitSet64<N>;
+};
+constexpr std::size_t kDefaultBitSetSize = 64;
+using BaseBitSetType = BitSet64<kDefaultBitSetSize>;
+#else
+template <size_t N>
+struct GetBitSet<N, EnableIfBitsFit<N, uint32_t>>
+{
+ using Type = BitSet32<N>;
+};
+constexpr std::size_t kDefaultBitSetSize = 32;
+using BaseBitSetType = BitSet32<kDefaultBitSetSize>;
+#endif // defined(ANGLE_IS_64_BIT_CPU)
+
+} // namespace priv
+
+template <size_t N>
+using BitSet = typename priv::GetBitSet<N>::Type;
+
+template <std::size_t N>
+class BitSetArray final
+{
+ public:
+ using BaseBitSet = priv::BaseBitSetType;
+ using value_type = BaseBitSet::value_type;
+ using param_type = BaseBitSet::param_type;
+
+ constexpr BitSetArray();
+ constexpr explicit BitSetArray(std::initializer_list<param_type> init);
+
+ BitSetArray(const BitSetArray<N> &other);
+
+ class Reference final
+ {
+ public:
+ ~Reference() {}
+ Reference &operator=(bool x)
+ {
+ mParent.set(mPosition, x);
+ return *this;
+ }
+ explicit operator bool() const { return mParent.test(mPosition); }
+
+ private:
+ friend class BitSetArray;
+
+ Reference(BitSetArray &parent, std::size_t pos) : mParent(parent), mPosition(pos) {}
+
+ BitSetArray &mParent;
+ std::size_t mPosition;
+ };
+ class Iterator final
+ {
+ public:
+ Iterator(const BitSetArray<N> &bitSetArray, std::size_t index);
+ Iterator &operator++();
+ bool operator==(const Iterator &other) const;
+ bool operator!=(const Iterator &other) const;
+ size_t operator*() const;
+
+ // These helper functions allow mutating an iterator in-flight.
+ // They only operate on later bits to ensure we don't iterate the same bit twice.
+ void resetLaterBit(std::size_t pos)
+ {
+ ASSERT(pos > (mIndex * priv::kDefaultBitSetSize) + *mCurrentIterator);
+ prepareCopy();
+ mParentCopy.reset(pos);
+ updateIteratorBit(pos, false);
+ }
+
+ void setLaterBit(std::size_t pos)
+ {
+ ASSERT(pos > (mIndex * priv::kDefaultBitSetSize) + *mCurrentIterator);
+ prepareCopy();
+ mParentCopy.set(pos);
+ updateIteratorBit(pos, true);
+ }
+
+ void setLaterBits(const BitSetArray &bits)
+ {
+ prepareCopy();
+ mParentCopy |= bits;
+ updateIteratorBits(bits);
+ }
+
+ private:
+ ANGLE_INLINE void prepareCopy()
+ {
+ ASSERT(mParent.mBaseBitSetArray[mIndex].end() ==
+ mParentCopy.mBaseBitSetArray[mIndex].end());
+ if (mParentCopy.none())
+ {
+ mParentCopy = mParent;
+ mCurrentParent = &mParentCopy;
+ }
+ }
+
+ ANGLE_INLINE void updateIteratorBit(std::size_t pos, bool setBit)
+ {
+ // Get the index and offset, update current interator if within range
+ size_t index = pos >> kShiftForDivision;
+ size_t offset = pos & kDefaultBitSetSizeMinusOne;
+ if (index == mIndex)
+ {
+ if (setBit)
+ {
+ mCurrentIterator.setLaterBit(offset);
+ }
+ else
+ {
+ mCurrentIterator.resetLaterBit(offset);
+ }
+ }
+ }
+
+ ANGLE_INLINE void updateIteratorBits(const BitSetArray &bits)
+ {
+ mCurrentIterator.setLaterBits(bits.mBaseBitSetArray[mIndex]);
+ }
+
+ // Problem -
+ // We want to provide the fastest path possible for usecases that iterate though the bitset.
+ //
+ // Options -
+ // 1) For non-mutating iterations the const ref <mParent> is set as mCurrentParent and only
+ // for usecases that need to mutate the bitset while iterating we perform a copy of
+ // <mParent> into <mParentCopy> and modify its bits accordingly.
+ // 2) The alternate approach was to perform a copy all the time in the constructor
+ // irrespective of whether it was a mutating usecase or not.
+ //
+ // Experiment -
+ // BitSetIteratorPerfTest was run on a Windows machine with Intel CPU and these were the
+ // results -
+ // 1) Copy only when necessary -
+ // RESULT BitSetIteratorPerf.wall_time: run = 116.1067374961 ns
+ // RESULT BitSetIteratorPerf.trial_steps : run = 8416124 count
+ // RESULT BitSetIteratorPerf.total_steps : run = 16832251 count
+ // 2) Copy always -
+ // RESULT BitSetIteratorPerf.wall_time: run = 242.7446459439 ns
+ // RESULT BitSetIteratorPerf.trial_steps : run = 4171416 count
+ // RESULT BitSetIteratorPerf.total_steps : run = 8342834 count
+ //
+ // Resolution -
+ // We settled on the copy only when necessary path.
+ size_t mIndex;
+ const BitSetArray &mParent;
+ BitSetArray mParentCopy;
+ const BitSetArray *mCurrentParent;
+ typename BaseBitSet::Iterator mCurrentIterator;
+ };
+
+ constexpr static std::size_t size() { return N; }
+ Iterator begin() const { return Iterator(*this, 0); }
+ Iterator end() const { return Iterator(*this, kArraySize); }
+ constexpr unsigned long to_ulong() const
+ {
+ // TODO(anglebug.com/5628): Handle serializing more than kDefaultBitSetSize
+ for (std::size_t index = 1; index < kArraySize; index++)
+ {
+ ASSERT(mBaseBitSetArray[index].none());
+ }
+ return static_cast<unsigned long>(mBaseBitSetArray[0].to_ulong());
+ }
+
+ // Assignment operators
+ constexpr BitSetArray &operator=(const BitSetArray &other);
+ constexpr BitSetArray &operator&=(const BitSetArray &other);
+ constexpr BitSetArray &operator|=(const BitSetArray &other);
+ constexpr BitSetArray &operator^=(const BitSetArray &other);
+
+ // Bitwise operators
+ constexpr BitSetArray<N> operator&(const angle::BitSetArray<N> &other) const;
+ constexpr BitSetArray<N> operator|(const angle::BitSetArray<N> &other) const;
+ constexpr BitSetArray<N> operator^(const angle::BitSetArray<N> &other) const;
+
+ // Relational Operators
+ constexpr bool operator==(const angle::BitSetArray<N> &other) const;
+ constexpr bool operator!=(const angle::BitSetArray<N> &other) const;
+
+ // Unary operators
+ constexpr BitSetArray operator~() const;
+ constexpr bool operator[](std::size_t pos) const;
+ constexpr Reference operator[](std::size_t pos)
+ {
+ ASSERT(pos < size());
+ return Reference(*this, pos);
+ }
+
+ // Setter, getters and other helper methods
+ constexpr BitSetArray &set();
+ constexpr BitSetArray &set(std::size_t pos, bool value = true);
+ constexpr BitSetArray &reset();
+ constexpr BitSetArray &reset(std::size_t pos);
+ constexpr bool test(std::size_t pos) const;
+ constexpr bool all() const;
+ constexpr bool any() const;
+ constexpr bool none() const;
+ constexpr std::size_t count() const;
+ constexpr bool intersects(const BitSetArray &other) const;
+ constexpr BitSetArray<N> &flip();
+ constexpr param_type first() const;
+ constexpr param_type last() const;
+
+ constexpr value_type bits(size_t index) const;
+
+ private:
+ static constexpr std::size_t kDefaultBitSetSizeMinusOne = priv::kDefaultBitSetSize - 1;
+ static constexpr std::size_t kShiftForDivision =
+ static_cast<std::size_t>(rx::Log2(static_cast<unsigned int>(priv::kDefaultBitSetSize)));
+ static constexpr std::size_t kArraySize =
+ ((N + kDefaultBitSetSizeMinusOne) >> kShiftForDivision);
+ constexpr static std::size_t kLastElementCount = (N & kDefaultBitSetSizeMinusOne);
+ constexpr static std::size_t kLastElementMask = priv::BaseBitSetType::Mask(
+ kLastElementCount == 0 ? priv::kDefaultBitSetSize : kLastElementCount);
+
+ std::array<BaseBitSet, kArraySize> mBaseBitSetArray;
+};
+
+template <std::size_t N>
+constexpr BitSetArray<N>::BitSetArray()
+{
+ static_assert(N > priv::kDefaultBitSetSize, "BitSetArray type can't support requested size.");
+ reset();
+}
+
+template <std::size_t N>
+constexpr BitSetArray<N>::BitSetArray(std::initializer_list<param_type> init)
+{
+ reset();
+
+ for (param_type element : init)
+ {
+ size_t index = element >> kShiftForDivision;
+ size_t offset = element & kDefaultBitSetSizeMinusOne;
+ mBaseBitSetArray[index].set(offset, true);
+ }
+}
+
+template <size_t N>
+BitSetArray<N>::BitSetArray(const BitSetArray<N> &other)
+{
+ for (std::size_t index = 0; index < kArraySize; index++)
+ {
+ mBaseBitSetArray[index] = other.mBaseBitSetArray[index];
+ }
+}
+
+template <size_t N>
+BitSetArray<N>::Iterator::Iterator(const BitSetArray<N> &bitSetArray, std::size_t index)
+ : mIndex(index),
+ mParent(bitSetArray),
+ mCurrentParent(&mParent),
+ mCurrentIterator(mParent.mBaseBitSetArray[0].begin())
+{
+ while (mIndex < mCurrentParent->kArraySize)
+ {
+ if (mCurrentParent->mBaseBitSetArray[mIndex].any())
+ {
+ break;
+ }
+ mIndex++;
+ }
+
+ if (mIndex < mCurrentParent->kArraySize)
+ {
+ mCurrentIterator = mCurrentParent->mBaseBitSetArray[mIndex].begin();
+ }
+ else
+ {
+ mCurrentIterator = mCurrentParent->mBaseBitSetArray[mCurrentParent->kArraySize - 1].end();
+ }
+}
+
+template <std::size_t N>
+typename BitSetArray<N>::Iterator &BitSetArray<N>::Iterator::operator++()
+{
+ ++mCurrentIterator;
+ while (mCurrentIterator == mCurrentParent->mBaseBitSetArray[mIndex].end())
+ {
+ mIndex++;
+ if (mIndex >= mCurrentParent->kArraySize)
+ {
+ break;
+ }
+ mCurrentIterator = mCurrentParent->mBaseBitSetArray[mIndex].begin();
+ }
+ return *this;
+}
+
+template <std::size_t N>
+bool BitSetArray<N>::Iterator::operator==(const BitSetArray<N>::Iterator &other) const
+{
+ return mCurrentIterator == other.mCurrentIterator;
+}
+
+template <std::size_t N>
+bool BitSetArray<N>::Iterator::operator!=(const BitSetArray<N>::Iterator &other) const
+{
+ return mCurrentIterator != other.mCurrentIterator;
+}
+
+template <std::size_t N>
+std::size_t BitSetArray<N>::Iterator::operator*() const
+{
+ return (mIndex * priv::kDefaultBitSetSize) + *mCurrentIterator;
+}
+
+template <std::size_t N>
+constexpr BitSetArray<N> &BitSetArray<N>::operator=(const BitSetArray<N> &other)
+{
+ for (std::size_t index = 0; index < kArraySize; index++)
+ {
+ mBaseBitSetArray[index] = other.mBaseBitSetArray[index];
+ }
+ return *this;
+}
+
+template <std::size_t N>
+constexpr BitSetArray<N> &BitSetArray<N>::operator&=(const BitSetArray<N> &other)
+{
+ for (std::size_t index = 0; index < kArraySize; index++)
+ {
+ mBaseBitSetArray[index] &= other.mBaseBitSetArray[index];
+ }
+ return *this;
+}
+
+template <std::size_t N>
+constexpr BitSetArray<N> &BitSetArray<N>::operator|=(const BitSetArray<N> &other)
+{
+ for (std::size_t index = 0; index < kArraySize; index++)
+ {
+ mBaseBitSetArray[index] |= other.mBaseBitSetArray[index];
+ }
+ return *this;
+}
+
+template <std::size_t N>
+constexpr BitSetArray<N> &BitSetArray<N>::operator^=(const BitSetArray<N> &other)
+{
+ for (std::size_t index = 0; index < kArraySize; index++)
+ {
+ mBaseBitSetArray[index] ^= other.mBaseBitSetArray[index];
+ }
+ return *this;
+}
+
+template <std::size_t N>
+constexpr BitSetArray<N> BitSetArray<N>::operator&(const angle::BitSetArray<N> &other) const
+{
+ angle::BitSetArray<N> result(other);
+ result &= *this;
+ return result;
+}
+
+template <std::size_t N>
+constexpr BitSetArray<N> BitSetArray<N>::operator|(const angle::BitSetArray<N> &other) const
+{
+ angle::BitSetArray<N> result(other);
+ result |= *this;
+ return result;
+}
+
+template <std::size_t N>
+constexpr BitSetArray<N> BitSetArray<N>::operator^(const angle::BitSetArray<N> &other) const
+{
+ angle::BitSetArray<N> result(other);
+ result ^= *this;
+ return result;
+}
+
+template <std::size_t N>
+constexpr bool BitSetArray<N>::operator==(const angle::BitSetArray<N> &other) const
+{
+ for (std::size_t index = 0; index < kArraySize; index++)
+ {
+ if (mBaseBitSetArray[index] != other.mBaseBitSetArray[index])
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+template <std::size_t N>
+constexpr bool BitSetArray<N>::operator!=(const angle::BitSetArray<N> &other) const
+{
+ return !(*this == other);
+}
+
+template <std::size_t N>
+constexpr BitSetArray<N> BitSetArray<N>::operator~() const
+{
+ angle::BitSetArray<N> result;
+ for (std::size_t index = 0; index < kArraySize; index++)
+ {
+ result.mBaseBitSetArray[index] |= ~mBaseBitSetArray[index];
+ }
+ // The last element in result may need special handling
+ result.mBaseBitSetArray[kArraySize - 1] &= kLastElementMask;
+
+ return result;
+}
+
+template <std::size_t N>
+constexpr bool BitSetArray<N>::operator[](std::size_t pos) const
+{
+ ASSERT(pos < size());
+ return test(pos);
+}
+
+template <std::size_t N>
+constexpr BitSetArray<N> &BitSetArray<N>::set()
+{
+ for (BaseBitSet &baseBitSet : mBaseBitSetArray)
+ {
+ baseBitSet.set();
+ }
+ // The last element in mBaseBitSetArray may need special handling
+ mBaseBitSetArray[kArraySize - 1] &= kLastElementMask;
+
+ return *this;
+}
+
+template <std::size_t N>
+constexpr BitSetArray<N> &BitSetArray<N>::set(std::size_t pos, bool value)
+{
+ ASSERT(pos < size());
+ // Get the index and offset, then set the bit
+ size_t index = pos >> kShiftForDivision;
+ size_t offset = pos & kDefaultBitSetSizeMinusOne;
+ mBaseBitSetArray[index].set(offset, value);
+ return *this;
+}
+
+template <std::size_t N>
+constexpr BitSetArray<N> &BitSetArray<N>::reset()
+{
+ for (BaseBitSet &baseBitSet : mBaseBitSetArray)
+ {
+ baseBitSet.reset();
+ }
+ return *this;
+}
+
+template <std::size_t N>
+constexpr BitSetArray<N> &BitSetArray<N>::reset(std::size_t pos)
+{
+ ASSERT(pos < size());
+ return set(pos, false);
+}
+
+template <std::size_t N>
+constexpr bool BitSetArray<N>::test(std::size_t pos) const
+{
+ ASSERT(pos < size());
+ // Get the index and offset, then test the bit
+ size_t index = pos >> kShiftForDivision;
+ size_t offset = pos & kDefaultBitSetSizeMinusOne;
+ return mBaseBitSetArray[index].test(offset);
+}
+
+template <std::size_t N>
+constexpr bool BitSetArray<N>::all() const
+{
+ constexpr priv::BaseBitSetType kLastElementBitSet = priv::BaseBitSetType(kLastElementMask);
+
+ for (std::size_t index = 0; index < kArraySize - 1; index++)
+ {
+ if (!mBaseBitSetArray[index].all())
+ {
+ return false;
+ }
+ }
+
+ // The last element in mBaseBitSetArray may need special handling
+ return mBaseBitSetArray[kArraySize - 1] == kLastElementBitSet;
+}
+
+template <std::size_t N>
+constexpr bool BitSetArray<N>::any() const
+{
+ for (const BaseBitSet &baseBitSet : mBaseBitSetArray)
+ {
+ if (baseBitSet.any())
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+template <std::size_t N>
+constexpr bool BitSetArray<N>::none() const
+{
+ for (const BaseBitSet &baseBitSet : mBaseBitSetArray)
+ {
+ if (!baseBitSet.none())
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+template <std::size_t N>
+constexpr std::size_t BitSetArray<N>::count() const
+{
+ size_t count = 0;
+ for (const BaseBitSet &baseBitSet : mBaseBitSetArray)
+ {
+ count += baseBitSet.count();
+ }
+ return count;
+}
+
+template <std::size_t N>
+constexpr bool BitSetArray<N>::intersects(const BitSetArray<N> &other) const
+{
+ for (std::size_t index = 0; index < kArraySize; index++)
+ {
+ if ((mBaseBitSetArray[index].bits() & other.mBaseBitSetArray[index].bits()) != 0)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+template <std::size_t N>
+constexpr BitSetArray<N> &BitSetArray<N>::flip()
+{
+ for (BaseBitSet &baseBitSet : mBaseBitSetArray)
+ {
+ baseBitSet.flip();
+ }
+
+ // The last element in mBaseBitSetArray may need special handling
+ mBaseBitSetArray[kArraySize - 1] &= kLastElementMask;
+ return *this;
+}
+
+template <std::size_t N>
+constexpr typename BitSetArray<N>::param_type BitSetArray<N>::first() const
+{
+ ASSERT(any());
+ for (size_t arrayIndex = 0; arrayIndex < kArraySize; ++arrayIndex)
+ {
+ const BaseBitSet &baseBitSet = mBaseBitSetArray[arrayIndex];
+ if (baseBitSet.any())
+ {
+ return baseBitSet.first() + arrayIndex * priv::kDefaultBitSetSize;
+ }
+ }
+ UNREACHABLE();
+ return 0;
+}
+
+template <std::size_t N>
+constexpr typename BitSetArray<N>::param_type BitSetArray<N>::last() const
+{
+ ASSERT(any());
+ for (size_t arrayIndex = kArraySize; arrayIndex > 0; --arrayIndex)
+ {
+ const BaseBitSet &baseBitSet = mBaseBitSetArray[arrayIndex - 1];
+ if (baseBitSet.any())
+ {
+ return baseBitSet.last() + (arrayIndex - 1) * priv::kDefaultBitSetSize;
+ }
+ }
+ UNREACHABLE();
+ return 0;
+}
+
+template <std::size_t N>
+constexpr typename BitSetArray<N>::value_type BitSetArray<N>::bits(size_t index) const
+{
+ return mBaseBitSetArray[index].bits();
+}
+} // namespace angle
+
+template <size_t N, typename BitsT, typename ParamT>
+inline constexpr angle::BitSetT<N, BitsT, ParamT> operator&(
+ const angle::BitSetT<N, BitsT, ParamT> &lhs,
+ const angle::BitSetT<N, BitsT, ParamT> &rhs)
+{
+ angle::BitSetT<N, BitsT, ParamT> result(lhs);
+ result &= rhs.bits();
+ return result;
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+inline constexpr angle::BitSetT<N, BitsT, ParamT> operator|(
+ const angle::BitSetT<N, BitsT, ParamT> &lhs,
+ const angle::BitSetT<N, BitsT, ParamT> &rhs)
+{
+ angle::BitSetT<N, BitsT, ParamT> result(lhs);
+ result |= rhs.bits();
+ return result;
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+inline constexpr angle::BitSetT<N, BitsT, ParamT> operator^(
+ const angle::BitSetT<N, BitsT, ParamT> &lhs,
+ const angle::BitSetT<N, BitsT, ParamT> &rhs)
+{
+ angle::BitSetT<N, BitsT, ParamT> result(lhs);
+ result ^= rhs.bits();
+ return result;
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+inline bool operator==(angle::BitSetT<N, BitsT, ParamT> &lhs, angle::BitSetT<N, BitsT, ParamT> &rhs)
+{
+ return lhs.bits() == rhs.bits();
+}
+
+template <size_t N, typename BitsT, typename ParamT>
+inline bool operator!=(angle::BitSetT<N, BitsT, ParamT> &lhs, angle::BitSetT<N, BitsT, ParamT> &rhs)
+{
+ return !(lhs == rhs);
+}
+
+#endif // COMMON_BITSETITERATOR_H_
diff --git a/gfx/angle/checkout/src/common/debug.cpp b/gfx/angle/checkout/src/common/debug.cpp
new file mode 100644
index 0000000000..23424d443a
--- /dev/null
+++ b/gfx/angle/checkout/src/common/debug.cpp
@@ -0,0 +1,349 @@
+//
+// Copyright 2002 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.
+//
+
+// debug.cpp: Debugging utilities.
+
+#include "common/debug.h"
+
+#include <stdarg.h>
+
+#include <array>
+#include <cstdio>
+#include <cstring>
+#include <fstream>
+#include <ostream>
+#include <vector>
+
+#if defined(ANGLE_PLATFORM_ANDROID)
+# include <android/log.h>
+#endif
+
+#if defined(ANGLE_PLATFORM_APPLE)
+# include <os/log.h>
+#endif
+
+#if defined(ANGLE_PLATFORM_WINDOWS)
+# include <windows.h>
+#endif
+
+#include "anglebase/no_destructor.h"
+#include "common/Optional.h"
+#include "common/angleutils.h"
+#include "common/entry_points_enum_autogen.h"
+#include "common/system_utils.h"
+
+namespace gl
+{
+
+namespace
+{
+
+DebugAnnotator *g_debugAnnotator = nullptr;
+
+std::mutex *g_debugMutex = nullptr;
+
+constexpr std::array<const char *, LOG_NUM_SEVERITIES> g_logSeverityNames = {
+ {"EVENT", "INFO", "WARN", "ERR", "FATAL"}};
+
+constexpr const char *LogSeverityName(int severity)
+{
+ return (severity >= 0 && severity < LOG_NUM_SEVERITIES) ? g_logSeverityNames[severity]
+ : "UNKNOWN";
+}
+
+bool ShouldCreateLogMessage(LogSeverity severity)
+{
+#if defined(ANGLE_TRACE_ENABLED)
+ return true;
+#elif defined(ANGLE_ENABLE_ASSERTS)
+ return severity == LOG_FATAL || severity == LOG_ERR || severity == LOG_WARN;
+#else
+ return severity == LOG_FATAL || severity == LOG_ERR;
+#endif
+}
+
+} // namespace
+
+namespace priv
+{
+
+bool ShouldCreatePlatformLogMessage(LogSeverity severity)
+{
+#if defined(ANGLE_TRACE_ENABLED)
+ return true;
+#else
+ return severity != LOG_EVENT;
+#endif
+}
+
+// This is never instantiated, it's just used for EAT_STREAM_PARAMETERS to an object of the correct
+// type on the LHS of the unused part of the ternary operator.
+std::ostream *gSwallowStream;
+} // namespace priv
+
+bool DebugAnnotationsActive(const gl::Context *context)
+{
+#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS) || defined(ANGLE_ENABLE_DEBUG_TRACE)
+ return g_debugAnnotator != nullptr && g_debugAnnotator->getStatus(context);
+#else
+ return false;
+#endif
+}
+
+bool ShouldBeginScopedEvent(const gl::Context *context)
+{
+#if defined(ANGLE_ENABLE_ANNOTATOR_RUN_TIME_CHECKS)
+ return DebugAnnotationsActive(context);
+#else
+ return true;
+#endif // defined(ANGLE_ENABLE_ANNOTATOR_RUN_TIME_CHECKS)
+}
+
+bool DebugAnnotationsInitialized()
+{
+ return g_debugAnnotator != nullptr;
+}
+
+void InitializeDebugAnnotations(DebugAnnotator *debugAnnotator)
+{
+ UninitializeDebugAnnotations();
+ g_debugAnnotator = debugAnnotator;
+}
+
+void UninitializeDebugAnnotations()
+{
+ // Pointer is not managed.
+ g_debugAnnotator = nullptr;
+}
+
+void InitializeDebugMutexIfNeeded()
+{
+ if (g_debugMutex == nullptr)
+ {
+ g_debugMutex = new std::mutex();
+ }
+}
+
+std::mutex &GetDebugMutex()
+{
+ ASSERT(g_debugMutex);
+ return *g_debugMutex;
+}
+
+ScopedPerfEventHelper::ScopedPerfEventHelper(gl::Context *context, angle::EntryPoint entryPoint)
+ : mContext(context), mEntryPoint(entryPoint), mFunctionName(nullptr), mCalledBeginEvent(false)
+{}
+
+ScopedPerfEventHelper::~ScopedPerfEventHelper()
+{
+ // EGL_Initialize() and EGL_Terminate() can change g_debugAnnotator. Must check the value of
+ // g_debugAnnotator and whether ScopedPerfEventHelper::begin() initiated a begine that must be
+ // ended now.
+ if (DebugAnnotationsInitialized() && mCalledBeginEvent)
+ {
+ g_debugAnnotator->endEvent(mContext, mFunctionName, mEntryPoint);
+ }
+}
+
+void ScopedPerfEventHelper::begin(const char *format, ...)
+{
+ mFunctionName = GetEntryPointName(mEntryPoint);
+
+ va_list vararg;
+ va_start(vararg, format);
+
+ std::vector<char> buffer;
+ size_t len = FormatStringIntoVector(format, vararg, buffer);
+ va_end(vararg);
+
+ ANGLE_LOG(EVENT) << std::string(&buffer[0], len);
+ if (DebugAnnotationsInitialized())
+ {
+ mCalledBeginEvent = true;
+ g_debugAnnotator->beginEvent(mContext, mEntryPoint, mFunctionName, buffer.data());
+ }
+}
+
+LogMessage::LogMessage(const char *file, const char *function, int line, LogSeverity severity)
+ : mFile(file), mFunction(function), mLine(line), mSeverity(severity)
+{
+ // INFO() and EVENT() do not require additional function(line) info.
+ if (mSeverity > LOG_INFO)
+ {
+ const char *slash = std::max(strrchr(mFile, '/'), strrchr(mFile, '\\'));
+ mStream << (slash ? (slash + 1) : mFile) << ":" << mLine << " (" << mFunction << "): ";
+ }
+}
+
+LogMessage::~LogMessage()
+{
+ {
+ std::unique_lock<std::mutex> lock;
+ if (g_debugMutex != nullptr)
+ {
+ lock = std::unique_lock<std::mutex>(*g_debugMutex);
+ }
+
+ if (DebugAnnotationsInitialized() && (mSeverity > LOG_INFO))
+ {
+ g_debugAnnotator->logMessage(*this);
+ }
+ else
+ {
+ Trace(getSeverity(), getMessage().c_str());
+ }
+ }
+
+ if (mSeverity == LOG_FATAL)
+ {
+ if (angle::IsDebuggerAttached())
+ {
+ angle::BreakDebugger();
+ }
+ else
+ {
+ ANGLE_CRASH();
+ }
+ }
+}
+
+void Trace(LogSeverity severity, const char *message)
+{
+ if (!ShouldCreateLogMessage(severity))
+ {
+ return;
+ }
+
+ std::string str(message);
+
+ if (DebugAnnotationsActive(/*context=*/nullptr))
+ {
+
+ switch (severity)
+ {
+ case LOG_EVENT:
+ // Debugging logging done in ScopedPerfEventHelper
+ break;
+ default:
+ g_debugAnnotator->setMarker(/*context=*/nullptr, message);
+ break;
+ }
+ }
+
+ if (severity == LOG_FATAL || severity == LOG_ERR || severity == LOG_WARN ||
+#if defined(ANGLE_ENABLE_TRACE_ANDROID_LOGCAT) || defined(ANGLE_ENABLE_TRACE_EVENTS)
+ severity == LOG_EVENT ||
+#endif
+ severity == LOG_INFO)
+ {
+#if defined(ANGLE_PLATFORM_ANDROID)
+ android_LogPriority android_priority = ANDROID_LOG_ERROR;
+ switch (severity)
+ {
+ case LOG_INFO:
+ case LOG_EVENT:
+ android_priority = ANDROID_LOG_INFO;
+ break;
+ case LOG_WARN:
+ android_priority = ANDROID_LOG_WARN;
+ break;
+ case LOG_ERR:
+ android_priority = ANDROID_LOG_ERROR;
+ break;
+ case LOG_FATAL:
+ android_priority = ANDROID_LOG_FATAL;
+ break;
+ default:
+ UNREACHABLE();
+ }
+ __android_log_print(android_priority, "ANGLE", "%s: %s\n", LogSeverityName(severity),
+ str.c_str());
+#elif defined(ANGLE_PLATFORM_APPLE)
+ if (__builtin_available(macOS 10.12, iOS 10.0, *))
+ {
+ os_log_type_t apple_log_type = OS_LOG_TYPE_DEFAULT;
+ switch (severity)
+ {
+ case LOG_INFO:
+ apple_log_type = OS_LOG_TYPE_INFO;
+ break;
+ case LOG_WARN:
+ apple_log_type = OS_LOG_TYPE_DEFAULT;
+ break;
+ case LOG_ERR:
+ apple_log_type = OS_LOG_TYPE_ERROR;
+ break;
+ case LOG_FATAL:
+ // OS_LOG_TYPE_FAULT is too severe - grabs the entire process tree.
+ apple_log_type = OS_LOG_TYPE_ERROR;
+ break;
+ default:
+ UNREACHABLE();
+ }
+ os_log_with_type(OS_LOG_DEFAULT, apple_log_type, "ANGLE: %s: %s\n",
+ LogSeverityName(severity), str.c_str());
+ }
+#else
+ // Note: we use fprintf because <iostream> includes static initializers.
+ fprintf((severity >= LOG_WARN) ? stderr : stdout, "%s: %s\n", LogSeverityName(severity),
+ str.c_str());
+#endif
+ }
+
+#if defined(ANGLE_PLATFORM_WINDOWS) && \
+ (defined(ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER) || !defined(NDEBUG))
+# if !defined(ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER)
+ if (severity >= LOG_ERR)
+# endif // !defined(ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER)
+ {
+ OutputDebugStringA(str.c_str());
+ OutputDebugStringA("\n");
+ }
+#endif
+
+#if defined(ANGLE_ENABLE_DEBUG_TRACE)
+# if defined(NDEBUG)
+ if (severity == LOG_EVENT || severity == LOG_WARN || severity == LOG_INFO)
+ {
+ return;
+ }
+# endif // defined(NDEBUG)
+ static angle::base::NoDestructor<std::ofstream> file(TRACE_OUTPUT_FILE, std::ofstream::app);
+ if (file->good())
+ {
+ if (severity > LOG_EVENT)
+ {
+ *file << LogSeverityName(severity) << ": ";
+ }
+ *file << str << "\n";
+ file->flush();
+ }
+#endif // defined(ANGLE_ENABLE_DEBUG_TRACE)
+}
+
+LogSeverity LogMessage::getSeverity() const
+{
+ return mSeverity;
+}
+
+std::string LogMessage::getMessage() const
+{
+ return mStream.str();
+}
+
+#if defined(ANGLE_PLATFORM_WINDOWS)
+priv::FmtHexHelper<HRESULT, char> FmtHR(HRESULT value)
+{
+ return priv::FmtHexHelper<HRESULT, char>("HRESULT: ", value);
+}
+
+priv::FmtHexHelper<DWORD, char> FmtErr(DWORD value)
+{
+ return priv::FmtHexHelper<DWORD, char>("error: ", value);
+}
+#endif // defined(ANGLE_PLATFORM_WINDOWS)
+
+} // namespace gl
diff --git a/gfx/angle/checkout/src/common/debug.h b/gfx/angle/checkout/src/common/debug.h
new file mode 100644
index 0000000000..a9ee795103
--- /dev/null
+++ b/gfx/angle/checkout/src/common/debug.h
@@ -0,0 +1,468 @@
+//
+// Copyright 2002 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.
+//
+
+// debug.h: Debugging utilities. A lot of the logging code is adapted from Chromium's
+// base/logging.h.
+
+#ifndef COMMON_DEBUG_H_
+#define COMMON_DEBUG_H_
+
+#include <assert.h>
+#include <stdio.h>
+
+#include <iomanip>
+#include <ios>
+#include <mutex>
+#include <sstream>
+#include <string>
+
+#include "common/angleutils.h"
+#include "common/entry_points_enum_autogen.h"
+#include "common/platform.h"
+
+#if defined(ANGLE_PLATFORM_WINDOWS)
+# include <sal.h>
+typedef unsigned long DWORD;
+typedef _Return_type_success_(return >= 0) long HRESULT;
+#endif
+
+#if !defined(TRACE_OUTPUT_FILE)
+# define TRACE_OUTPUT_FILE "angle_debug.txt"
+#endif
+
+namespace gl
+{
+class Context;
+
+// Pairs a begin event with an end event.
+class [[nodiscard]] ScopedPerfEventHelper : angle::NonCopyable
+{
+ public:
+ ScopedPerfEventHelper(Context *context, angle::EntryPoint entryPoint);
+ ~ScopedPerfEventHelper();
+ ANGLE_FORMAT_PRINTF(2, 3)
+ void begin(const char *format, ...);
+
+ private:
+ gl::Context *mContext;
+ const angle::EntryPoint mEntryPoint;
+ const char *mFunctionName;
+ bool mCalledBeginEvent;
+};
+
+using LogSeverity = int;
+// Note: the log severities are used to index into the array of names,
+// see g_logSeverityNames.
+constexpr LogSeverity LOG_EVENT = 0;
+constexpr LogSeverity LOG_INFO = 1;
+constexpr LogSeverity LOG_WARN = 2;
+constexpr LogSeverity LOG_ERR = 3;
+constexpr LogSeverity LOG_FATAL = 4;
+constexpr LogSeverity LOG_NUM_SEVERITIES = 5;
+
+void Trace(LogSeverity severity, const char *message);
+
+// This class more or less represents a particular log message. You
+// create an instance of LogMessage and then stream stuff to it.
+// When you finish streaming to it, ~LogMessage is called and the
+// full message gets streamed to the appropriate destination.
+//
+// You shouldn't actually use LogMessage's constructor to log things,
+// though. You should use the ERR() and WARN() macros.
+class LogMessage : angle::NonCopyable
+{
+ public:
+ // Used for ANGLE_LOG(severity).
+ LogMessage(const char *file, const char *function, int line, LogSeverity severity);
+ ~LogMessage();
+ std::ostream &stream() { return mStream; }
+
+ LogSeverity getSeverity() const;
+ std::string getMessage() const;
+
+ private:
+ const char *mFile;
+ const char *mFunction;
+ const int mLine;
+ const LogSeverity mSeverity;
+
+ std::ostringstream mStream;
+};
+
+// Wraps the API/Platform-specific debug annotation functions.
+// Also handles redirecting logging destination.
+class DebugAnnotator : angle::NonCopyable
+{
+ public:
+ DebugAnnotator() {}
+ virtual ~DebugAnnotator() {}
+ virtual void beginEvent(gl::Context *context,
+ angle::EntryPoint entryPoint,
+ const char *eventName,
+ const char *eventMessage) = 0;
+ virtual void endEvent(gl::Context *context,
+ const char *eventName,
+ angle::EntryPoint entryPoint) = 0;
+ virtual void setMarker(gl::Context *context, const char *markerName) = 0;
+ virtual bool getStatus(const gl::Context *context) = 0;
+ // Log Message Handler that gets passed every log message,
+ // when debug annotations are initialized,
+ // replacing default handling by LogMessage.
+ virtual void logMessage(const LogMessage &msg) const = 0;
+};
+
+bool ShouldBeginScopedEvent(const gl::Context *context);
+void InitializeDebugAnnotations(DebugAnnotator *debugAnnotator);
+void UninitializeDebugAnnotations();
+bool DebugAnnotationsActive(const gl::Context *context);
+bool DebugAnnotationsInitialized();
+
+void InitializeDebugMutexIfNeeded();
+
+std::mutex &GetDebugMutex();
+
+namespace priv
+{
+// This class is used to explicitly ignore values in the conditional logging macros. This avoids
+// compiler warnings like "value computed is not used" and "statement has no effect".
+class LogMessageVoidify
+{
+ public:
+ LogMessageVoidify() {}
+ // This has to be an operator with a precedence lower than << but higher than ?:
+ void operator&(std::ostream &) {}
+};
+
+extern std::ostream *gSwallowStream;
+
+// Used by ANGLE_LOG_IS_ON to lazy-evaluate stream arguments.
+bool ShouldCreatePlatformLogMessage(LogSeverity severity);
+
+// N is the width of the output to the stream. The output is padded with zeros
+// if value is less than N characters.
+// S is the stream type, either ostream for ANSI or wostream for wide character.
+// T is the type of the value to output to the stream.
+// C is the type of characters - either char for ANSI or wchar_t for wide char.
+template <int N, typename S, typename T, typename C>
+S &FmtHex(S &stream, T value, const C *zeroX, C zero)
+{
+ stream << zeroX;
+
+ std::ios_base::fmtflags oldFlags = stream.flags();
+ std::streamsize oldWidth = stream.width();
+ typename S::char_type oldFill = stream.fill();
+
+ stream << std::hex << std::uppercase << std::setw(N) << std::setfill(zero) << value;
+
+ stream.flags(oldFlags);
+ stream.width(oldWidth);
+ stream.fill(oldFill);
+
+ return stream;
+}
+
+template <typename S, typename T, typename C>
+S &FmtHexAutoSized(S &stream, T value, const C *prefix, const C *zeroX, C zero)
+{
+ if (prefix)
+ {
+ stream << prefix;
+ }
+
+ constexpr int N = sizeof(T) * 2;
+ return priv::FmtHex<N>(stream, value, zeroX, zero);
+}
+
+template <typename T, typename C>
+class FmtHexHelper
+{
+ public:
+ FmtHexHelper(const C *prefix, T value) : mPrefix(prefix), mValue(value) {}
+ explicit FmtHexHelper(T value) : mPrefix(nullptr), mValue(value) {}
+
+ private:
+ const C *mPrefix;
+ T mValue;
+
+ friend std::ostream &operator<<(std::ostream &os, const FmtHexHelper &fmt)
+ {
+ return FmtHexAutoSized(os, fmt.mValue, fmt.mPrefix, "0x", '0');
+ }
+
+ friend std::wostream &operator<<(std::wostream &wos, const FmtHexHelper &fmt)
+ {
+ return FmtHexAutoSized(wos, fmt.mValue, fmt.mPrefix, L"0x", L'0');
+ }
+};
+
+} // namespace priv
+
+template <typename T, typename C = char>
+priv::FmtHexHelper<T, C> FmtHex(T value)
+{
+ return priv::FmtHexHelper<T, C>(value);
+}
+
+#if defined(ANGLE_PLATFORM_WINDOWS)
+priv::FmtHexHelper<HRESULT, char> FmtHR(HRESULT value);
+priv::FmtHexHelper<DWORD, char> FmtErr(DWORD value);
+#endif // defined(ANGLE_PLATFORM_WINDOWS)
+
+template <typename T>
+std::ostream &FmtHex(std::ostream &os, T value)
+{
+ return priv::FmtHexAutoSized(os, value, "", "0x", '0');
+}
+
+// A few definitions of macros that don't generate much code. These are used
+// by ANGLE_LOG(). Since these are used all over our code, it's
+// better to have compact code for these operations.
+#define COMPACT_ANGLE_LOG_EX_EVENT(ClassName, ...) \
+ ::gl::ClassName(__FILE__, __FUNCTION__, __LINE__, ::gl::LOG_EVENT, ##__VA_ARGS__)
+#define COMPACT_ANGLE_LOG_EX_INFO(ClassName, ...) \
+ ::gl::ClassName(__FILE__, __FUNCTION__, __LINE__, ::gl::LOG_INFO, ##__VA_ARGS__)
+#define COMPACT_ANGLE_LOG_EX_WARN(ClassName, ...) \
+ ::gl::ClassName(__FILE__, __FUNCTION__, __LINE__, ::gl::LOG_WARN, ##__VA_ARGS__)
+#define COMPACT_ANGLE_LOG_EX_ERR(ClassName, ...) \
+ ::gl::ClassName(__FILE__, __FUNCTION__, __LINE__, ::gl::LOG_ERR, ##__VA_ARGS__)
+#define COMPACT_ANGLE_LOG_EX_FATAL(ClassName, ...) \
+ ::gl::ClassName(__FILE__, __FUNCTION__, __LINE__, ::gl::LOG_FATAL, ##__VA_ARGS__)
+
+#define COMPACT_ANGLE_LOG_EVENT COMPACT_ANGLE_LOG_EX_EVENT(LogMessage)
+#define COMPACT_ANGLE_LOG_INFO COMPACT_ANGLE_LOG_EX_INFO(LogMessage)
+#define COMPACT_ANGLE_LOG_WARN COMPACT_ANGLE_LOG_EX_WARN(LogMessage)
+#define COMPACT_ANGLE_LOG_ERR COMPACT_ANGLE_LOG_EX_ERR(LogMessage)
+#define COMPACT_ANGLE_LOG_FATAL COMPACT_ANGLE_LOG_EX_FATAL(LogMessage)
+
+#define ANGLE_LOG_IS_ON(severity) (::gl::priv::ShouldCreatePlatformLogMessage(::gl::LOG_##severity))
+
+// Helper macro which avoids evaluating the arguments to a stream if the condition doesn't hold.
+// Condition is evaluated once and only once.
+#define ANGLE_LAZY_STREAM(stream, condition) \
+ !(condition) ? static_cast<void>(0) : ::gl::priv::LogMessageVoidify() & (stream)
+
+// We use the preprocessor's merging operator, "##", so that, e.g.,
+// ANGLE_LOG(EVENT) becomes the token COMPACT_ANGLE_LOG_EVENT. There's some funny
+// subtle difference between ostream member streaming functions (e.g.,
+// ostream::operator<<(int) and ostream non-member streaming functions
+// (e.g., ::operator<<(ostream&, string&): it turns out that it's
+// impossible to stream something like a string directly to an unnamed
+// ostream. We employ a neat hack by calling the stream() member
+// function of LogMessage which seems to avoid the problem.
+#define ANGLE_LOG_STREAM(severity) COMPACT_ANGLE_LOG_##severity.stream()
+
+#define ANGLE_LOG(severity) ANGLE_LAZY_STREAM(ANGLE_LOG_STREAM(severity), ANGLE_LOG_IS_ON(severity))
+
+} // namespace gl
+
+#if defined(ANGLE_ENABLE_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
+# define ANGLE_TRACE_ENABLED
+#endif
+
+#if !defined(NDEBUG) || defined(ANGLE_ASSERT_ALWAYS_ON)
+# define ANGLE_ENABLE_ASSERTS
+#endif
+
+#define INFO() ANGLE_LOG(INFO)
+#define WARN() ANGLE_LOG(WARN)
+#define ERR() ANGLE_LOG(ERR)
+#define FATAL() ANGLE_LOG(FATAL)
+
+// A macro to log a performance event around a scope.
+#if defined(ANGLE_TRACE_ENABLED)
+# if defined(_MSC_VER)
+# define EVENT(context, entryPoint, message, ...) \
+ gl::ScopedPerfEventHelper scopedPerfEventHelper##__LINE__( \
+ context, angle::EntryPoint::entryPoint); \
+ do \
+ { \
+ if (gl::ShouldBeginScopedEvent(context)) \
+ { \
+ scopedPerfEventHelper##__LINE__.begin( \
+ "%s(" message ")", GetEntryPointName(angle::EntryPoint::entryPoint), \
+ __VA_ARGS__); \
+ } \
+ } while (0)
+# else
+# define EVENT(context, entryPoint, message, ...) \
+ gl::ScopedPerfEventHelper scopedPerfEventHelper(context, \
+ angle::EntryPoint::entryPoint); \
+ do \
+ { \
+ if (gl::ShouldBeginScopedEvent(context)) \
+ { \
+ scopedPerfEventHelper.begin("%s(" message ")", \
+ GetEntryPointName(angle::EntryPoint::entryPoint), \
+ ##__VA_ARGS__); \
+ } \
+ } while (0)
+# endif // _MSC_VER
+#else
+# define EVENT(message, ...) (void(0))
+#endif
+
+// The state tracked by ANGLE will be validated with the driver state before each call
+#if defined(ANGLE_ENABLE_DEBUG_TRACE)
+# define ANGLE_STATE_VALIDATION_ENABLED
+#endif
+
+#if defined(__GNUC__)
+# define ANGLE_CRASH() __builtin_trap()
+#else
+# define ANGLE_CRASH() ((void)(*(volatile char *)0 = 0)), __assume(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) ANGLE_CRASH()
+#endif // !defined(NDEBUG)
+
+// Note that gSwallowStream is used instead of an arbitrary LOG() stream to avoid the creation of an
+// object with a non-trivial destructor (LogMessage). On MSVC x86 (checked on 2015 Update 3), this
+// causes a few additional pointless instructions to be emitted even at full optimization level,
+// even though the : arm of the ternary operator is clearly never executed. Using a simpler object
+// to be &'d with Voidify() avoids these extra instructions. Using a simpler POD object with a
+// templated operator<< also works to avoid these instructions. However, this causes warnings on
+// statically defined implementations of operator<<(std::ostream, ...) in some .cpp files, because
+// they become defined-but-unreferenced functions. A reinterpret_cast of 0 to an ostream* also is
+// not suitable, because some compilers warn of undefined behavior.
+#define ANGLE_EAT_STREAM_PARAMETERS \
+ true ? static_cast<void>(0) : ::gl::priv::LogMessageVoidify() & (*::gl::priv::gSwallowStream)
+
+// A macro asserting a condition and outputting failures to the debug log
+#if defined(ANGLE_ENABLE_ASSERTS)
+# define ASSERT(expression) \
+ (expression ? static_cast<void>(0) \
+ : (FATAL() << "\t! Assert failed in " << __FUNCTION__ << " (" << __FILE__ \
+ << ":" << __LINE__ << "): " << #expression))
+#else
+# define ASSERT(condition) ANGLE_EAT_STREAM_PARAMETERS << !(condition)
+#endif // defined(ANGLE_ENABLE_ASSERTS)
+
+#define ANGLE_UNUSED_VARIABLE(variable) (static_cast<void>(variable))
+
+// A macro to indicate unimplemented functionality
+#ifndef NOASSERT_UNIMPLEMENTED
+# define NOASSERT_UNIMPLEMENTED 1
+#endif
+
+#if defined(ANGLE_TRACE_ENABLED) || defined(ANGLE_ENABLE_ASSERTS)
+# define UNIMPLEMENTED() \
+ do \
+ { \
+ WARN() << "\t! Unimplemented: " << __FUNCTION__ << "(" << __FILE__ << ":" << __LINE__ \
+ << ")"; \
+ ASSERT(NOASSERT_UNIMPLEMENTED); \
+ } while (0)
+
+// A macro for code which is not expected to be reached under valid assumptions
+# define UNREACHABLE() \
+ do \
+ { \
+ FATAL() << "\t! Unreachable reached: " << __FUNCTION__ << "(" << __FILE__ << ":" \
+ << __LINE__ << ")"; \
+ } while (0)
+#else
+# define UNIMPLEMENTED() \
+ do \
+ { \
+ ASSERT(NOASSERT_UNIMPLEMENTED); \
+ } while (0)
+
+// A macro for code which is not expected to be reached under valid assumptions
+# define UNREACHABLE() \
+ do \
+ { \
+ ASSERT(false); \
+ } while (0)
+#endif // defined(ANGLE_TRACE_ENABLED) || defined(ANGLE_ENABLE_ASSERTS)
+
+#if defined(ANGLE_PLATFORM_WINDOWS)
+# define ANGLE_FUNCTION __FUNCTION__
+#else
+# define ANGLE_FUNCTION __func__
+#endif
+
+// Defining ANGLE_ENABLE_STRUCT_PADDING_WARNINGS will enable warnings when members are added to
+// structs to enforce packing. This is helpful for diagnosing unexpected struct sizes when making
+// fast cache variables.
+#if defined(__clang__)
+# define ANGLE_ENABLE_STRUCT_PADDING_WARNINGS \
+ _Pragma("clang diagnostic push") _Pragma("clang diagnostic error \"-Wpadded\"")
+# define ANGLE_DISABLE_STRUCT_PADDING_WARNINGS _Pragma("clang diagnostic pop")
+#elif defined(__GNUC__)
+# define ANGLE_ENABLE_STRUCT_PADDING_WARNINGS \
+ _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic error \"-Wpadded\"")
+# define ANGLE_DISABLE_STRUCT_PADDING_WARNINGS _Pragma("GCC diagnostic pop")
+#elif defined(_MSC_VER)
+# define ANGLE_ENABLE_STRUCT_PADDING_WARNINGS \
+ __pragma(warning(push)) __pragma(warning(error : 4820))
+# define ANGLE_DISABLE_STRUCT_PADDING_WARNINGS __pragma(warning(pop))
+#else
+# define ANGLE_ENABLE_STRUCT_PADDING_WARNINGS
+# define ANGLE_DISABLE_STRUCT_PADDING_WARNINGS
+#endif
+
+#if defined(__clang__)
+# define ANGLE_DISABLE_SUGGEST_OVERRIDE_WARNINGS \
+ _Pragma("clang diagnostic push") \
+ _Pragma("clang diagnostic ignored \"-Wsuggest-destructor-override\"") \
+ _Pragma("clang diagnostic ignored \"-Wsuggest-override\"")
+# define ANGLE_REENABLE_SUGGEST_OVERRIDE_WARNINGS _Pragma("clang diagnostic pop")
+#else
+# define ANGLE_DISABLE_SUGGEST_OVERRIDE_WARNINGS
+# define ANGLE_REENABLE_SUGGEST_OVERRIDE_WARNINGS
+#endif
+
+#if defined(__clang__)
+# define ANGLE_DISABLE_EXTRA_SEMI_WARNING \
+ _Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wextra-semi\"")
+# define ANGLE_REENABLE_EXTRA_SEMI_WARNING _Pragma("clang diagnostic pop")
+#else
+# define ANGLE_DISABLE_EXTRA_SEMI_WARNING
+# define ANGLE_REENABLE_EXTRA_SEMI_WARNING
+#endif
+
+#if defined(__clang__)
+# define ANGLE_DISABLE_EXTRA_SEMI_STMT_WARNING \
+ _Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wextra-semi-stmt\"")
+# define ANGLE_REENABLE_EXTRA_SEMI_STMT_WARNING _Pragma("clang diagnostic pop")
+#else
+# define ANGLE_DISABLE_EXTRA_SEMI_STMT_WARNING
+# define ANGLE_REENABLE_EXTRA_SEMI_STMT_WARNING
+#endif
+
+#if defined(__clang__)
+# define ANGLE_DISABLE_SHADOWING_WARNING \
+ _Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wshadow-field\"")
+# define ANGLE_REENABLE_SHADOWING_WARNING _Pragma("clang diagnostic pop")
+#else
+# define ANGLE_DISABLE_SHADOWING_WARNING
+# define ANGLE_REENABLE_SHADOWING_WARNING
+#endif
+
+#if defined(__clang__)
+# define ANGLE_DISABLE_DESTRUCTOR_OVERRIDE_WARNING \
+ _Pragma("clang diagnostic push") \
+ _Pragma("clang diagnostic ignored \"-Winconsistent-missing-destructor-override\"")
+# define ANGLE_REENABLE_DESTRUCTOR_OVERRIDE_WARNING _Pragma("clang diagnostic pop")
+#else
+# define ANGLE_DISABLE_DESTRUCTOR_OVERRIDE_WARNING
+# define ANGLE_REENABLE_DESTRUCTOR_OVERRIDE_WARNING
+#endif
+
+#if defined(__clang__)
+# define ANGLE_DISABLE_UNUSED_FUNCTION_WARNING \
+ _Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wunused-function\"")
+# define ANGLE_REENABLE_UNUSED_FUNCTION_WARNING _Pragma("clang diagnostic pop")
+#else
+# define ANGLE_DISABLE_UNUSED_FUNCTION_WARNING
+# define ANGLE_REENABLE_UNUSED_FUNCTION_WARNING
+#endif
+
+#endif // COMMON_DEBUG_H_
diff --git a/gfx/angle/checkout/src/common/entry_points_enum_autogen.cpp b/gfx/angle/checkout/src/common/entry_points_enum_autogen.cpp
new file mode 100644
index 0000000000..993eecc8da
--- /dev/null
+++ b/gfx/angle/checkout/src/common/entry_points_enum_autogen.cpp
@@ -0,0 +1,3454 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml and gl_angle_ext.xml.
+//
+// Copyright 2020 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_enum_autogen.cpp:
+// Helper methods for the GL/GLES entry points enumeration.
+
+#include "common/entry_points_enum_autogen.h"
+
+#include "common/debug.h"
+
+namespace angle
+{
+const char *GetEntryPointName(EntryPoint ep)
+{
+ switch (ep)
+ {
+ case EntryPoint::CLBuildProgram:
+ return "clBuildProgram";
+ case EntryPoint::CLCloneKernel:
+ return "clCloneKernel";
+ case EntryPoint::CLCompileProgram:
+ return "clCompileProgram";
+ case EntryPoint::CLCreateBuffer:
+ return "clCreateBuffer";
+ case EntryPoint::CLCreateBufferWithProperties:
+ return "clCreateBufferWithProperties";
+ case EntryPoint::CLCreateCommandQueue:
+ return "clCreateCommandQueue";
+ case EntryPoint::CLCreateCommandQueueWithProperties:
+ return "clCreateCommandQueueWithProperties";
+ case EntryPoint::CLCreateContext:
+ return "clCreateContext";
+ case EntryPoint::CLCreateContextFromType:
+ return "clCreateContextFromType";
+ case EntryPoint::CLCreateImage:
+ return "clCreateImage";
+ case EntryPoint::CLCreateImage2D:
+ return "clCreateImage2D";
+ case EntryPoint::CLCreateImage3D:
+ return "clCreateImage3D";
+ case EntryPoint::CLCreateImageWithProperties:
+ return "clCreateImageWithProperties";
+ case EntryPoint::CLCreateKernel:
+ return "clCreateKernel";
+ case EntryPoint::CLCreateKernelsInProgram:
+ return "clCreateKernelsInProgram";
+ case EntryPoint::CLCreatePipe:
+ return "clCreatePipe";
+ case EntryPoint::CLCreateProgramWithBinary:
+ return "clCreateProgramWithBinary";
+ case EntryPoint::CLCreateProgramWithBuiltInKernels:
+ return "clCreateProgramWithBuiltInKernels";
+ case EntryPoint::CLCreateProgramWithIL:
+ return "clCreateProgramWithIL";
+ case EntryPoint::CLCreateProgramWithSource:
+ return "clCreateProgramWithSource";
+ case EntryPoint::CLCreateSampler:
+ return "clCreateSampler";
+ case EntryPoint::CLCreateSamplerWithProperties:
+ return "clCreateSamplerWithProperties";
+ case EntryPoint::CLCreateSubBuffer:
+ return "clCreateSubBuffer";
+ case EntryPoint::CLCreateSubDevices:
+ return "clCreateSubDevices";
+ case EntryPoint::CLCreateUserEvent:
+ return "clCreateUserEvent";
+ case EntryPoint::CLEnqueueBarrier:
+ return "clEnqueueBarrier";
+ case EntryPoint::CLEnqueueBarrierWithWaitList:
+ return "clEnqueueBarrierWithWaitList";
+ case EntryPoint::CLEnqueueCopyBuffer:
+ return "clEnqueueCopyBuffer";
+ case EntryPoint::CLEnqueueCopyBufferRect:
+ return "clEnqueueCopyBufferRect";
+ case EntryPoint::CLEnqueueCopyBufferToImage:
+ return "clEnqueueCopyBufferToImage";
+ case EntryPoint::CLEnqueueCopyImage:
+ return "clEnqueueCopyImage";
+ case EntryPoint::CLEnqueueCopyImageToBuffer:
+ return "clEnqueueCopyImageToBuffer";
+ case EntryPoint::CLEnqueueFillBuffer:
+ return "clEnqueueFillBuffer";
+ case EntryPoint::CLEnqueueFillImage:
+ return "clEnqueueFillImage";
+ case EntryPoint::CLEnqueueMapBuffer:
+ return "clEnqueueMapBuffer";
+ case EntryPoint::CLEnqueueMapImage:
+ return "clEnqueueMapImage";
+ case EntryPoint::CLEnqueueMarker:
+ return "clEnqueueMarker";
+ case EntryPoint::CLEnqueueMarkerWithWaitList:
+ return "clEnqueueMarkerWithWaitList";
+ case EntryPoint::CLEnqueueMigrateMemObjects:
+ return "clEnqueueMigrateMemObjects";
+ case EntryPoint::CLEnqueueNDRangeKernel:
+ return "clEnqueueNDRangeKernel";
+ case EntryPoint::CLEnqueueNativeKernel:
+ return "clEnqueueNativeKernel";
+ case EntryPoint::CLEnqueueReadBuffer:
+ return "clEnqueueReadBuffer";
+ case EntryPoint::CLEnqueueReadBufferRect:
+ return "clEnqueueReadBufferRect";
+ case EntryPoint::CLEnqueueReadImage:
+ return "clEnqueueReadImage";
+ case EntryPoint::CLEnqueueSVMFree:
+ return "clEnqueueSVMFree";
+ case EntryPoint::CLEnqueueSVMMap:
+ return "clEnqueueSVMMap";
+ case EntryPoint::CLEnqueueSVMMemFill:
+ return "clEnqueueSVMMemFill";
+ case EntryPoint::CLEnqueueSVMMemcpy:
+ return "clEnqueueSVMMemcpy";
+ case EntryPoint::CLEnqueueSVMMigrateMem:
+ return "clEnqueueSVMMigrateMem";
+ case EntryPoint::CLEnqueueSVMUnmap:
+ return "clEnqueueSVMUnmap";
+ case EntryPoint::CLEnqueueTask:
+ return "clEnqueueTask";
+ case EntryPoint::CLEnqueueUnmapMemObject:
+ return "clEnqueueUnmapMemObject";
+ case EntryPoint::CLEnqueueWaitForEvents:
+ return "clEnqueueWaitForEvents";
+ case EntryPoint::CLEnqueueWriteBuffer:
+ return "clEnqueueWriteBuffer";
+ case EntryPoint::CLEnqueueWriteBufferRect:
+ return "clEnqueueWriteBufferRect";
+ case EntryPoint::CLEnqueueWriteImage:
+ return "clEnqueueWriteImage";
+ case EntryPoint::CLFinish:
+ return "clFinish";
+ case EntryPoint::CLFlush:
+ return "clFlush";
+ case EntryPoint::CLGetCommandQueueInfo:
+ return "clGetCommandQueueInfo";
+ case EntryPoint::CLGetContextInfo:
+ return "clGetContextInfo";
+ case EntryPoint::CLGetDeviceAndHostTimer:
+ return "clGetDeviceAndHostTimer";
+ case EntryPoint::CLGetDeviceIDs:
+ return "clGetDeviceIDs";
+ case EntryPoint::CLGetDeviceInfo:
+ return "clGetDeviceInfo";
+ case EntryPoint::CLGetEventInfo:
+ return "clGetEventInfo";
+ case EntryPoint::CLGetEventProfilingInfo:
+ return "clGetEventProfilingInfo";
+ case EntryPoint::CLGetExtensionFunctionAddress:
+ return "clGetExtensionFunctionAddress";
+ case EntryPoint::CLGetExtensionFunctionAddressForPlatform:
+ return "clGetExtensionFunctionAddressForPlatform";
+ case EntryPoint::CLGetHostTimer:
+ return "clGetHostTimer";
+ case EntryPoint::CLGetImageInfo:
+ return "clGetImageInfo";
+ case EntryPoint::CLGetKernelArgInfo:
+ return "clGetKernelArgInfo";
+ case EntryPoint::CLGetKernelInfo:
+ return "clGetKernelInfo";
+ case EntryPoint::CLGetKernelSubGroupInfo:
+ return "clGetKernelSubGroupInfo";
+ case EntryPoint::CLGetKernelWorkGroupInfo:
+ return "clGetKernelWorkGroupInfo";
+ case EntryPoint::CLGetMemObjectInfo:
+ return "clGetMemObjectInfo";
+ case EntryPoint::CLGetPipeInfo:
+ return "clGetPipeInfo";
+ case EntryPoint::CLGetPlatformIDs:
+ return "clGetPlatformIDs";
+ case EntryPoint::CLGetPlatformInfo:
+ return "clGetPlatformInfo";
+ case EntryPoint::CLGetProgramBuildInfo:
+ return "clGetProgramBuildInfo";
+ case EntryPoint::CLGetProgramInfo:
+ return "clGetProgramInfo";
+ case EntryPoint::CLGetSamplerInfo:
+ return "clGetSamplerInfo";
+ case EntryPoint::CLGetSupportedImageFormats:
+ return "clGetSupportedImageFormats";
+ case EntryPoint::CLIcdGetPlatformIDsKHR:
+ return "clIcdGetPlatformIDsKHR";
+ case EntryPoint::CLLinkProgram:
+ return "clLinkProgram";
+ case EntryPoint::CLReleaseCommandQueue:
+ return "clReleaseCommandQueue";
+ case EntryPoint::CLReleaseContext:
+ return "clReleaseContext";
+ case EntryPoint::CLReleaseDevice:
+ return "clReleaseDevice";
+ case EntryPoint::CLReleaseEvent:
+ return "clReleaseEvent";
+ case EntryPoint::CLReleaseKernel:
+ return "clReleaseKernel";
+ case EntryPoint::CLReleaseMemObject:
+ return "clReleaseMemObject";
+ case EntryPoint::CLReleaseProgram:
+ return "clReleaseProgram";
+ case EntryPoint::CLReleaseSampler:
+ return "clReleaseSampler";
+ case EntryPoint::CLRetainCommandQueue:
+ return "clRetainCommandQueue";
+ case EntryPoint::CLRetainContext:
+ return "clRetainContext";
+ case EntryPoint::CLRetainDevice:
+ return "clRetainDevice";
+ case EntryPoint::CLRetainEvent:
+ return "clRetainEvent";
+ case EntryPoint::CLRetainKernel:
+ return "clRetainKernel";
+ case EntryPoint::CLRetainMemObject:
+ return "clRetainMemObject";
+ case EntryPoint::CLRetainProgram:
+ return "clRetainProgram";
+ case EntryPoint::CLRetainSampler:
+ return "clRetainSampler";
+ case EntryPoint::CLSVMAlloc:
+ return "clSVMAlloc";
+ case EntryPoint::CLSVMFree:
+ return "clSVMFree";
+ case EntryPoint::CLSetCommandQueueProperty:
+ return "clSetCommandQueueProperty";
+ case EntryPoint::CLSetContextDestructorCallback:
+ return "clSetContextDestructorCallback";
+ case EntryPoint::CLSetDefaultDeviceCommandQueue:
+ return "clSetDefaultDeviceCommandQueue";
+ case EntryPoint::CLSetEventCallback:
+ return "clSetEventCallback";
+ case EntryPoint::CLSetKernelArg:
+ return "clSetKernelArg";
+ case EntryPoint::CLSetKernelArgSVMPointer:
+ return "clSetKernelArgSVMPointer";
+ case EntryPoint::CLSetKernelExecInfo:
+ return "clSetKernelExecInfo";
+ case EntryPoint::CLSetMemObjectDestructorCallback:
+ return "clSetMemObjectDestructorCallback";
+ case EntryPoint::CLSetProgramReleaseCallback:
+ return "clSetProgramReleaseCallback";
+ case EntryPoint::CLSetProgramSpecializationConstant:
+ return "clSetProgramSpecializationConstant";
+ case EntryPoint::CLSetUserEventStatus:
+ return "clSetUserEventStatus";
+ case EntryPoint::CLUnloadCompiler:
+ return "clUnloadCompiler";
+ case EntryPoint::CLUnloadPlatformCompiler:
+ return "clUnloadPlatformCompiler";
+ case EntryPoint::CLWaitForEvents:
+ return "clWaitForEvents";
+ case EntryPoint::EGLBindAPI:
+ return "eglBindAPI";
+ case EntryPoint::EGLBindTexImage:
+ return "eglBindTexImage";
+ case EntryPoint::EGLChooseConfig:
+ return "eglChooseConfig";
+ case EntryPoint::EGLClientWaitSync:
+ return "eglClientWaitSync";
+ case EntryPoint::EGLClientWaitSyncKHR:
+ return "eglClientWaitSyncKHR";
+ case EntryPoint::EGLCopyBuffers:
+ return "eglCopyBuffers";
+ case EntryPoint::EGLCopyMetalSharedEventANGLE:
+ return "eglCopyMetalSharedEventANGLE";
+ case EntryPoint::EGLCreateContext:
+ return "eglCreateContext";
+ case EntryPoint::EGLCreateDeviceANGLE:
+ return "eglCreateDeviceANGLE";
+ case EntryPoint::EGLCreateImage:
+ return "eglCreateImage";
+ case EntryPoint::EGLCreateImageKHR:
+ return "eglCreateImageKHR";
+ case EntryPoint::EGLCreateNativeClientBufferANDROID:
+ return "eglCreateNativeClientBufferANDROID";
+ case EntryPoint::EGLCreatePbufferFromClientBuffer:
+ return "eglCreatePbufferFromClientBuffer";
+ case EntryPoint::EGLCreatePbufferSurface:
+ return "eglCreatePbufferSurface";
+ case EntryPoint::EGLCreatePixmapSurface:
+ return "eglCreatePixmapSurface";
+ case EntryPoint::EGLCreatePlatformPixmapSurface:
+ return "eglCreatePlatformPixmapSurface";
+ case EntryPoint::EGLCreatePlatformPixmapSurfaceEXT:
+ return "eglCreatePlatformPixmapSurfaceEXT";
+ case EntryPoint::EGLCreatePlatformWindowSurface:
+ return "eglCreatePlatformWindowSurface";
+ case EntryPoint::EGLCreatePlatformWindowSurfaceEXT:
+ return "eglCreatePlatformWindowSurfaceEXT";
+ case EntryPoint::EGLCreateStreamKHR:
+ return "eglCreateStreamKHR";
+ case EntryPoint::EGLCreateStreamProducerD3DTextureANGLE:
+ return "eglCreateStreamProducerD3DTextureANGLE";
+ case EntryPoint::EGLCreateSync:
+ return "eglCreateSync";
+ case EntryPoint::EGLCreateSyncKHR:
+ return "eglCreateSyncKHR";
+ case EntryPoint::EGLCreateWindowSurface:
+ return "eglCreateWindowSurface";
+ case EntryPoint::EGLDebugMessageControlKHR:
+ return "eglDebugMessageControlKHR";
+ case EntryPoint::EGLDestroyContext:
+ return "eglDestroyContext";
+ case EntryPoint::EGLDestroyImage:
+ return "eglDestroyImage";
+ case EntryPoint::EGLDestroyImageKHR:
+ return "eglDestroyImageKHR";
+ case EntryPoint::EGLDestroyStreamKHR:
+ return "eglDestroyStreamKHR";
+ case EntryPoint::EGLDestroySurface:
+ return "eglDestroySurface";
+ case EntryPoint::EGLDestroySync:
+ return "eglDestroySync";
+ case EntryPoint::EGLDestroySyncKHR:
+ return "eglDestroySyncKHR";
+ case EntryPoint::EGLDupNativeFenceFDANDROID:
+ return "eglDupNativeFenceFDANDROID";
+ case EntryPoint::EGLExportVkImageANGLE:
+ return "eglExportVkImageANGLE";
+ case EntryPoint::EGLForceGPUSwitchANGLE:
+ return "eglForceGPUSwitchANGLE";
+ case EntryPoint::EGLGetCompositorTimingANDROID:
+ return "eglGetCompositorTimingANDROID";
+ case EntryPoint::EGLGetCompositorTimingSupportedANDROID:
+ return "eglGetCompositorTimingSupportedANDROID";
+ case EntryPoint::EGLGetConfigAttrib:
+ return "eglGetConfigAttrib";
+ case EntryPoint::EGLGetConfigs:
+ return "eglGetConfigs";
+ case EntryPoint::EGLGetCurrentContext:
+ return "eglGetCurrentContext";
+ case EntryPoint::EGLGetCurrentDisplay:
+ return "eglGetCurrentDisplay";
+ case EntryPoint::EGLGetCurrentSurface:
+ return "eglGetCurrentSurface";
+ case EntryPoint::EGLGetDisplay:
+ return "eglGetDisplay";
+ case EntryPoint::EGLGetError:
+ return "eglGetError";
+ case EntryPoint::EGLGetFrameTimestampSupportedANDROID:
+ return "eglGetFrameTimestampSupportedANDROID";
+ case EntryPoint::EGLGetFrameTimestampsANDROID:
+ return "eglGetFrameTimestampsANDROID";
+ case EntryPoint::EGLGetMscRateANGLE:
+ return "eglGetMscRateANGLE";
+ case EntryPoint::EGLGetNativeClientBufferANDROID:
+ return "eglGetNativeClientBufferANDROID";
+ case EntryPoint::EGLGetNextFrameIdANDROID:
+ return "eglGetNextFrameIdANDROID";
+ case EntryPoint::EGLGetPlatformDisplay:
+ return "eglGetPlatformDisplay";
+ case EntryPoint::EGLGetPlatformDisplayEXT:
+ return "eglGetPlatformDisplayEXT";
+ case EntryPoint::EGLGetProcAddress:
+ return "eglGetProcAddress";
+ case EntryPoint::EGLGetSyncAttrib:
+ return "eglGetSyncAttrib";
+ case EntryPoint::EGLGetSyncAttribKHR:
+ return "eglGetSyncAttribKHR";
+ case EntryPoint::EGLGetSyncValuesCHROMIUM:
+ return "eglGetSyncValuesCHROMIUM";
+ case EntryPoint::EGLHandleGPUSwitchANGLE:
+ return "eglHandleGPUSwitchANGLE";
+ case EntryPoint::EGLInitialize:
+ return "eglInitialize";
+ case EntryPoint::EGLLabelObjectKHR:
+ return "eglLabelObjectKHR";
+ case EntryPoint::EGLLockSurfaceKHR:
+ return "eglLockSurfaceKHR";
+ case EntryPoint::EGLMakeCurrent:
+ return "eglMakeCurrent";
+ case EntryPoint::EGLPostSubBufferNV:
+ return "eglPostSubBufferNV";
+ case EntryPoint::EGLPrepareSwapBuffersANGLE:
+ return "eglPrepareSwapBuffersANGLE";
+ case EntryPoint::EGLPresentationTimeANDROID:
+ return "eglPresentationTimeANDROID";
+ case EntryPoint::EGLProgramCacheGetAttribANGLE:
+ return "eglProgramCacheGetAttribANGLE";
+ case EntryPoint::EGLProgramCachePopulateANGLE:
+ return "eglProgramCachePopulateANGLE";
+ case EntryPoint::EGLProgramCacheQueryANGLE:
+ return "eglProgramCacheQueryANGLE";
+ case EntryPoint::EGLProgramCacheResizeANGLE:
+ return "eglProgramCacheResizeANGLE";
+ case EntryPoint::EGLQueryAPI:
+ return "eglQueryAPI";
+ case EntryPoint::EGLQueryContext:
+ return "eglQueryContext";
+ case EntryPoint::EGLQueryDebugKHR:
+ return "eglQueryDebugKHR";
+ case EntryPoint::EGLQueryDeviceAttribEXT:
+ return "eglQueryDeviceAttribEXT";
+ case EntryPoint::EGLQueryDeviceStringEXT:
+ return "eglQueryDeviceStringEXT";
+ case EntryPoint::EGLQueryDisplayAttribANGLE:
+ return "eglQueryDisplayAttribANGLE";
+ case EntryPoint::EGLQueryDisplayAttribEXT:
+ return "eglQueryDisplayAttribEXT";
+ case EntryPoint::EGLQueryDmaBufFormatsEXT:
+ return "eglQueryDmaBufFormatsEXT";
+ case EntryPoint::EGLQueryDmaBufModifiersEXT:
+ return "eglQueryDmaBufModifiersEXT";
+ case EntryPoint::EGLQueryStreamKHR:
+ return "eglQueryStreamKHR";
+ case EntryPoint::EGLQueryStreamu64KHR:
+ return "eglQueryStreamu64KHR";
+ case EntryPoint::EGLQueryString:
+ return "eglQueryString";
+ case EntryPoint::EGLQueryStringiANGLE:
+ return "eglQueryStringiANGLE";
+ case EntryPoint::EGLQuerySurface:
+ return "eglQuerySurface";
+ case EntryPoint::EGLQuerySurface64KHR:
+ return "eglQuerySurface64KHR";
+ case EntryPoint::EGLQuerySurfacePointerANGLE:
+ return "eglQuerySurfacePointerANGLE";
+ case EntryPoint::EGLReacquireHighPowerGPUANGLE:
+ return "eglReacquireHighPowerGPUANGLE";
+ case EntryPoint::EGLReleaseDeviceANGLE:
+ return "eglReleaseDeviceANGLE";
+ case EntryPoint::EGLReleaseHighPowerGPUANGLE:
+ return "eglReleaseHighPowerGPUANGLE";
+ case EntryPoint::EGLReleaseTexImage:
+ return "eglReleaseTexImage";
+ case EntryPoint::EGLReleaseThread:
+ return "eglReleaseThread";
+ case EntryPoint::EGLSetBlobCacheFuncsANDROID:
+ return "eglSetBlobCacheFuncsANDROID";
+ case EntryPoint::EGLSetDamageRegionKHR:
+ return "eglSetDamageRegionKHR";
+ case EntryPoint::EGLSignalSyncKHR:
+ return "eglSignalSyncKHR";
+ case EntryPoint::EGLStreamAttribKHR:
+ return "eglStreamAttribKHR";
+ case EntryPoint::EGLStreamConsumerAcquireKHR:
+ return "eglStreamConsumerAcquireKHR";
+ case EntryPoint::EGLStreamConsumerGLTextureExternalAttribsNV:
+ return "eglStreamConsumerGLTextureExternalAttribsNV";
+ case EntryPoint::EGLStreamConsumerGLTextureExternalKHR:
+ return "eglStreamConsumerGLTextureExternalKHR";
+ case EntryPoint::EGLStreamConsumerReleaseKHR:
+ return "eglStreamConsumerReleaseKHR";
+ case EntryPoint::EGLStreamPostD3DTextureANGLE:
+ return "eglStreamPostD3DTextureANGLE";
+ case EntryPoint::EGLSurfaceAttrib:
+ return "eglSurfaceAttrib";
+ case EntryPoint::EGLSwapBuffers:
+ return "eglSwapBuffers";
+ case EntryPoint::EGLSwapBuffersWithDamageKHR:
+ return "eglSwapBuffersWithDamageKHR";
+ case EntryPoint::EGLSwapBuffersWithFrameTokenANGLE:
+ return "eglSwapBuffersWithFrameTokenANGLE";
+ case EntryPoint::EGLSwapInterval:
+ return "eglSwapInterval";
+ case EntryPoint::EGLTerminate:
+ return "eglTerminate";
+ case EntryPoint::EGLUnlockSurfaceKHR:
+ return "eglUnlockSurfaceKHR";
+ case EntryPoint::EGLWaitClient:
+ return "eglWaitClient";
+ case EntryPoint::EGLWaitGL:
+ return "eglWaitGL";
+ case EntryPoint::EGLWaitNative:
+ return "eglWaitNative";
+ case EntryPoint::EGLWaitSync:
+ return "eglWaitSync";
+ case EntryPoint::EGLWaitSyncKHR:
+ return "eglWaitSyncKHR";
+ case EntryPoint::GLAccum:
+ return "glAccum";
+ case EntryPoint::GLAcquireTexturesANGLE:
+ return "glAcquireTexturesANGLE";
+ case EntryPoint::GLActiveShaderProgram:
+ return "glActiveShaderProgram";
+ case EntryPoint::GLActiveShaderProgramEXT:
+ return "glActiveShaderProgramEXT";
+ case EntryPoint::GLActiveTexture:
+ return "glActiveTexture";
+ case EntryPoint::GLAlphaFunc:
+ return "glAlphaFunc";
+ case EntryPoint::GLAlphaFuncx:
+ return "glAlphaFuncx";
+ case EntryPoint::GLAreTexturesResident:
+ return "glAreTexturesResident";
+ case EntryPoint::GLArrayElement:
+ return "glArrayElement";
+ case EntryPoint::GLAttachShader:
+ return "glAttachShader";
+ case EntryPoint::GLBegin:
+ return "glBegin";
+ case EntryPoint::GLBeginConditionalRender:
+ return "glBeginConditionalRender";
+ case EntryPoint::GLBeginPerfMonitorAMD:
+ return "glBeginPerfMonitorAMD";
+ case EntryPoint::GLBeginPixelLocalStorageANGLE:
+ return "glBeginPixelLocalStorageANGLE";
+ case EntryPoint::GLBeginQuery:
+ return "glBeginQuery";
+ case EntryPoint::GLBeginQueryEXT:
+ return "glBeginQueryEXT";
+ case EntryPoint::GLBeginQueryIndexed:
+ return "glBeginQueryIndexed";
+ case EntryPoint::GLBeginTransformFeedback:
+ return "glBeginTransformFeedback";
+ case EntryPoint::GLBindAttribLocation:
+ return "glBindAttribLocation";
+ case EntryPoint::GLBindBuffer:
+ return "glBindBuffer";
+ case EntryPoint::GLBindBufferBase:
+ return "glBindBufferBase";
+ case EntryPoint::GLBindBufferRange:
+ return "glBindBufferRange";
+ case EntryPoint::GLBindBuffersBase:
+ return "glBindBuffersBase";
+ case EntryPoint::GLBindBuffersRange:
+ return "glBindBuffersRange";
+ case EntryPoint::GLBindFragDataLocation:
+ return "glBindFragDataLocation";
+ case EntryPoint::GLBindFragDataLocationEXT:
+ return "glBindFragDataLocationEXT";
+ case EntryPoint::GLBindFragDataLocationIndexed:
+ return "glBindFragDataLocationIndexed";
+ case EntryPoint::GLBindFragDataLocationIndexedEXT:
+ return "glBindFragDataLocationIndexedEXT";
+ case EntryPoint::GLBindFramebuffer:
+ return "glBindFramebuffer";
+ case EntryPoint::GLBindFramebufferOES:
+ return "glBindFramebufferOES";
+ case EntryPoint::GLBindImageTexture:
+ return "glBindImageTexture";
+ case EntryPoint::GLBindImageTextures:
+ return "glBindImageTextures";
+ case EntryPoint::GLBindProgramPipeline:
+ return "glBindProgramPipeline";
+ case EntryPoint::GLBindProgramPipelineEXT:
+ return "glBindProgramPipelineEXT";
+ case EntryPoint::GLBindRenderbuffer:
+ return "glBindRenderbuffer";
+ case EntryPoint::GLBindRenderbufferOES:
+ return "glBindRenderbufferOES";
+ case EntryPoint::GLBindSampler:
+ return "glBindSampler";
+ case EntryPoint::GLBindSamplers:
+ return "glBindSamplers";
+ case EntryPoint::GLBindTexture:
+ return "glBindTexture";
+ case EntryPoint::GLBindTextureUnit:
+ return "glBindTextureUnit";
+ case EntryPoint::GLBindTextures:
+ return "glBindTextures";
+ case EntryPoint::GLBindTransformFeedback:
+ return "glBindTransformFeedback";
+ case EntryPoint::GLBindUniformLocationCHROMIUM:
+ return "glBindUniformLocationCHROMIUM";
+ case EntryPoint::GLBindVertexArray:
+ return "glBindVertexArray";
+ case EntryPoint::GLBindVertexArrayOES:
+ return "glBindVertexArrayOES";
+ case EntryPoint::GLBindVertexBuffer:
+ return "glBindVertexBuffer";
+ case EntryPoint::GLBindVertexBuffers:
+ return "glBindVertexBuffers";
+ case EntryPoint::GLBitmap:
+ return "glBitmap";
+ case EntryPoint::GLBlendBarrier:
+ return "glBlendBarrier";
+ case EntryPoint::GLBlendBarrierKHR:
+ return "glBlendBarrierKHR";
+ case EntryPoint::GLBlendColor:
+ return "glBlendColor";
+ case EntryPoint::GLBlendEquation:
+ return "glBlendEquation";
+ case EntryPoint::GLBlendEquationSeparate:
+ return "glBlendEquationSeparate";
+ case EntryPoint::GLBlendEquationSeparatei:
+ return "glBlendEquationSeparatei";
+ case EntryPoint::GLBlendEquationSeparateiEXT:
+ return "glBlendEquationSeparateiEXT";
+ case EntryPoint::GLBlendEquationSeparateiOES:
+ return "glBlendEquationSeparateiOES";
+ case EntryPoint::GLBlendEquationi:
+ return "glBlendEquationi";
+ case EntryPoint::GLBlendEquationiEXT:
+ return "glBlendEquationiEXT";
+ case EntryPoint::GLBlendEquationiOES:
+ return "glBlendEquationiOES";
+ case EntryPoint::GLBlendFunc:
+ return "glBlendFunc";
+ case EntryPoint::GLBlendFuncSeparate:
+ return "glBlendFuncSeparate";
+ case EntryPoint::GLBlendFuncSeparatei:
+ return "glBlendFuncSeparatei";
+ case EntryPoint::GLBlendFuncSeparateiEXT:
+ return "glBlendFuncSeparateiEXT";
+ case EntryPoint::GLBlendFuncSeparateiOES:
+ return "glBlendFuncSeparateiOES";
+ case EntryPoint::GLBlendFunci:
+ return "glBlendFunci";
+ case EntryPoint::GLBlendFunciEXT:
+ return "glBlendFunciEXT";
+ case EntryPoint::GLBlendFunciOES:
+ return "glBlendFunciOES";
+ case EntryPoint::GLBlitFramebuffer:
+ return "glBlitFramebuffer";
+ case EntryPoint::GLBlitFramebufferANGLE:
+ return "glBlitFramebufferANGLE";
+ case EntryPoint::GLBlitFramebufferNV:
+ return "glBlitFramebufferNV";
+ case EntryPoint::GLBlitNamedFramebuffer:
+ return "glBlitNamedFramebuffer";
+ case EntryPoint::GLBufferData:
+ return "glBufferData";
+ case EntryPoint::GLBufferStorage:
+ return "glBufferStorage";
+ case EntryPoint::GLBufferStorageEXT:
+ return "glBufferStorageEXT";
+ case EntryPoint::GLBufferStorageExternalEXT:
+ return "glBufferStorageExternalEXT";
+ case EntryPoint::GLBufferStorageMemEXT:
+ return "glBufferStorageMemEXT";
+ case EntryPoint::GLBufferSubData:
+ return "glBufferSubData";
+ case EntryPoint::GLCallList:
+ return "glCallList";
+ case EntryPoint::GLCallLists:
+ return "glCallLists";
+ case EntryPoint::GLCheckFramebufferStatus:
+ return "glCheckFramebufferStatus";
+ case EntryPoint::GLCheckFramebufferStatusOES:
+ return "glCheckFramebufferStatusOES";
+ case EntryPoint::GLCheckNamedFramebufferStatus:
+ return "glCheckNamedFramebufferStatus";
+ case EntryPoint::GLClampColor:
+ return "glClampColor";
+ case EntryPoint::GLClear:
+ return "glClear";
+ case EntryPoint::GLClearAccum:
+ return "glClearAccum";
+ case EntryPoint::GLClearBufferData:
+ return "glClearBufferData";
+ case EntryPoint::GLClearBufferSubData:
+ return "glClearBufferSubData";
+ case EntryPoint::GLClearBufferfi:
+ return "glClearBufferfi";
+ case EntryPoint::GLClearBufferfv:
+ return "glClearBufferfv";
+ case EntryPoint::GLClearBufferiv:
+ return "glClearBufferiv";
+ case EntryPoint::GLClearBufferuiv:
+ return "glClearBufferuiv";
+ case EntryPoint::GLClearColor:
+ return "glClearColor";
+ case EntryPoint::GLClearColorx:
+ return "glClearColorx";
+ case EntryPoint::GLClearDepth:
+ return "glClearDepth";
+ case EntryPoint::GLClearDepthf:
+ return "glClearDepthf";
+ case EntryPoint::GLClearDepthx:
+ return "glClearDepthx";
+ case EntryPoint::GLClearIndex:
+ return "glClearIndex";
+ case EntryPoint::GLClearNamedBufferData:
+ return "glClearNamedBufferData";
+ case EntryPoint::GLClearNamedBufferSubData:
+ return "glClearNamedBufferSubData";
+ case EntryPoint::GLClearNamedFramebufferfi:
+ return "glClearNamedFramebufferfi";
+ case EntryPoint::GLClearNamedFramebufferfv:
+ return "glClearNamedFramebufferfv";
+ case EntryPoint::GLClearNamedFramebufferiv:
+ return "glClearNamedFramebufferiv";
+ case EntryPoint::GLClearNamedFramebufferuiv:
+ return "glClearNamedFramebufferuiv";
+ case EntryPoint::GLClearStencil:
+ return "glClearStencil";
+ case EntryPoint::GLClearTexImage:
+ return "glClearTexImage";
+ case EntryPoint::GLClearTexSubImage:
+ return "glClearTexSubImage";
+ case EntryPoint::GLClientActiveTexture:
+ return "glClientActiveTexture";
+ case EntryPoint::GLClientWaitSync:
+ return "glClientWaitSync";
+ case EntryPoint::GLClipControl:
+ return "glClipControl";
+ case EntryPoint::GLClipControlEXT:
+ return "glClipControlEXT";
+ case EntryPoint::GLClipPlane:
+ return "glClipPlane";
+ case EntryPoint::GLClipPlanef:
+ return "glClipPlanef";
+ case EntryPoint::GLClipPlanex:
+ return "glClipPlanex";
+ case EntryPoint::GLColor3b:
+ return "glColor3b";
+ case EntryPoint::GLColor3bv:
+ return "glColor3bv";
+ case EntryPoint::GLColor3d:
+ return "glColor3d";
+ case EntryPoint::GLColor3dv:
+ return "glColor3dv";
+ case EntryPoint::GLColor3f:
+ return "glColor3f";
+ case EntryPoint::GLColor3fv:
+ return "glColor3fv";
+ case EntryPoint::GLColor3i:
+ return "glColor3i";
+ case EntryPoint::GLColor3iv:
+ return "glColor3iv";
+ case EntryPoint::GLColor3s:
+ return "glColor3s";
+ case EntryPoint::GLColor3sv:
+ return "glColor3sv";
+ case EntryPoint::GLColor3ub:
+ return "glColor3ub";
+ case EntryPoint::GLColor3ubv:
+ return "glColor3ubv";
+ case EntryPoint::GLColor3ui:
+ return "glColor3ui";
+ case EntryPoint::GLColor3uiv:
+ return "glColor3uiv";
+ case EntryPoint::GLColor3us:
+ return "glColor3us";
+ case EntryPoint::GLColor3usv:
+ return "glColor3usv";
+ case EntryPoint::GLColor4b:
+ return "glColor4b";
+ case EntryPoint::GLColor4bv:
+ return "glColor4bv";
+ case EntryPoint::GLColor4d:
+ return "glColor4d";
+ case EntryPoint::GLColor4dv:
+ return "glColor4dv";
+ case EntryPoint::GLColor4f:
+ return "glColor4f";
+ case EntryPoint::GLColor4fv:
+ return "glColor4fv";
+ case EntryPoint::GLColor4i:
+ return "glColor4i";
+ case EntryPoint::GLColor4iv:
+ return "glColor4iv";
+ case EntryPoint::GLColor4s:
+ return "glColor4s";
+ case EntryPoint::GLColor4sv:
+ return "glColor4sv";
+ case EntryPoint::GLColor4ub:
+ return "glColor4ub";
+ case EntryPoint::GLColor4ubv:
+ return "glColor4ubv";
+ case EntryPoint::GLColor4ui:
+ return "glColor4ui";
+ case EntryPoint::GLColor4uiv:
+ return "glColor4uiv";
+ case EntryPoint::GLColor4us:
+ return "glColor4us";
+ case EntryPoint::GLColor4usv:
+ return "glColor4usv";
+ case EntryPoint::GLColor4x:
+ return "glColor4x";
+ case EntryPoint::GLColorMask:
+ return "glColorMask";
+ case EntryPoint::GLColorMaski:
+ return "glColorMaski";
+ case EntryPoint::GLColorMaskiEXT:
+ return "glColorMaskiEXT";
+ case EntryPoint::GLColorMaskiOES:
+ return "glColorMaskiOES";
+ case EntryPoint::GLColorMaterial:
+ return "glColorMaterial";
+ case EntryPoint::GLColorP3ui:
+ return "glColorP3ui";
+ case EntryPoint::GLColorP3uiv:
+ return "glColorP3uiv";
+ case EntryPoint::GLColorP4ui:
+ return "glColorP4ui";
+ case EntryPoint::GLColorP4uiv:
+ return "glColorP4uiv";
+ case EntryPoint::GLColorPointer:
+ return "glColorPointer";
+ case EntryPoint::GLCompileShader:
+ return "glCompileShader";
+ case EntryPoint::GLCompressedCopyTextureCHROMIUM:
+ return "glCompressedCopyTextureCHROMIUM";
+ case EntryPoint::GLCompressedTexImage1D:
+ return "glCompressedTexImage1D";
+ case EntryPoint::GLCompressedTexImage2D:
+ return "glCompressedTexImage2D";
+ case EntryPoint::GLCompressedTexImage2DRobustANGLE:
+ return "glCompressedTexImage2DRobustANGLE";
+ case EntryPoint::GLCompressedTexImage3D:
+ return "glCompressedTexImage3D";
+ case EntryPoint::GLCompressedTexImage3DOES:
+ return "glCompressedTexImage3DOES";
+ case EntryPoint::GLCompressedTexImage3DRobustANGLE:
+ return "glCompressedTexImage3DRobustANGLE";
+ case EntryPoint::GLCompressedTexSubImage1D:
+ return "glCompressedTexSubImage1D";
+ case EntryPoint::GLCompressedTexSubImage2D:
+ return "glCompressedTexSubImage2D";
+ case EntryPoint::GLCompressedTexSubImage2DRobustANGLE:
+ return "glCompressedTexSubImage2DRobustANGLE";
+ case EntryPoint::GLCompressedTexSubImage3D:
+ return "glCompressedTexSubImage3D";
+ case EntryPoint::GLCompressedTexSubImage3DOES:
+ return "glCompressedTexSubImage3DOES";
+ case EntryPoint::GLCompressedTexSubImage3DRobustANGLE:
+ return "glCompressedTexSubImage3DRobustANGLE";
+ case EntryPoint::GLCompressedTextureSubImage1D:
+ return "glCompressedTextureSubImage1D";
+ case EntryPoint::GLCompressedTextureSubImage2D:
+ return "glCompressedTextureSubImage2D";
+ case EntryPoint::GLCompressedTextureSubImage3D:
+ return "glCompressedTextureSubImage3D";
+ case EntryPoint::GLCopyBufferSubData:
+ return "glCopyBufferSubData";
+ case EntryPoint::GLCopyImageSubData:
+ return "glCopyImageSubData";
+ case EntryPoint::GLCopyImageSubDataEXT:
+ return "glCopyImageSubDataEXT";
+ case EntryPoint::GLCopyImageSubDataOES:
+ return "glCopyImageSubDataOES";
+ case EntryPoint::GLCopyNamedBufferSubData:
+ return "glCopyNamedBufferSubData";
+ case EntryPoint::GLCopyPixels:
+ return "glCopyPixels";
+ case EntryPoint::GLCopySubTexture3DANGLE:
+ return "glCopySubTexture3DANGLE";
+ case EntryPoint::GLCopySubTextureCHROMIUM:
+ return "glCopySubTextureCHROMIUM";
+ case EntryPoint::GLCopyTexImage1D:
+ return "glCopyTexImage1D";
+ case EntryPoint::GLCopyTexImage2D:
+ return "glCopyTexImage2D";
+ case EntryPoint::GLCopyTexSubImage1D:
+ return "glCopyTexSubImage1D";
+ case EntryPoint::GLCopyTexSubImage2D:
+ return "glCopyTexSubImage2D";
+ case EntryPoint::GLCopyTexSubImage3D:
+ return "glCopyTexSubImage3D";
+ case EntryPoint::GLCopyTexSubImage3DOES:
+ return "glCopyTexSubImage3DOES";
+ case EntryPoint::GLCopyTexture3DANGLE:
+ return "glCopyTexture3DANGLE";
+ case EntryPoint::GLCopyTextureCHROMIUM:
+ return "glCopyTextureCHROMIUM";
+ case EntryPoint::GLCopyTextureSubImage1D:
+ return "glCopyTextureSubImage1D";
+ case EntryPoint::GLCopyTextureSubImage2D:
+ return "glCopyTextureSubImage2D";
+ case EntryPoint::GLCopyTextureSubImage3D:
+ return "glCopyTextureSubImage3D";
+ case EntryPoint::GLCoverageModulationCHROMIUM:
+ return "glCoverageModulationCHROMIUM";
+ case EntryPoint::GLCreateBuffers:
+ return "glCreateBuffers";
+ case EntryPoint::GLCreateFramebuffers:
+ return "glCreateFramebuffers";
+ case EntryPoint::GLCreateMemoryObjectsEXT:
+ return "glCreateMemoryObjectsEXT";
+ case EntryPoint::GLCreateProgram:
+ return "glCreateProgram";
+ case EntryPoint::GLCreateProgramPipelines:
+ return "glCreateProgramPipelines";
+ case EntryPoint::GLCreateQueries:
+ return "glCreateQueries";
+ case EntryPoint::GLCreateRenderbuffers:
+ return "glCreateRenderbuffers";
+ case EntryPoint::GLCreateSamplers:
+ return "glCreateSamplers";
+ case EntryPoint::GLCreateShader:
+ return "glCreateShader";
+ case EntryPoint::GLCreateShaderProgramv:
+ return "glCreateShaderProgramv";
+ case EntryPoint::GLCreateShaderProgramvEXT:
+ return "glCreateShaderProgramvEXT";
+ case EntryPoint::GLCreateTextures:
+ return "glCreateTextures";
+ case EntryPoint::GLCreateTransformFeedbacks:
+ return "glCreateTransformFeedbacks";
+ case EntryPoint::GLCreateVertexArrays:
+ return "glCreateVertexArrays";
+ case EntryPoint::GLCullFace:
+ return "glCullFace";
+ case EntryPoint::GLCurrentPaletteMatrixOES:
+ return "glCurrentPaletteMatrixOES";
+ case EntryPoint::GLDebugMessageCallback:
+ return "glDebugMessageCallback";
+ case EntryPoint::GLDebugMessageCallbackKHR:
+ return "glDebugMessageCallbackKHR";
+ case EntryPoint::GLDebugMessageControl:
+ return "glDebugMessageControl";
+ case EntryPoint::GLDebugMessageControlKHR:
+ return "glDebugMessageControlKHR";
+ case EntryPoint::GLDebugMessageInsert:
+ return "glDebugMessageInsert";
+ case EntryPoint::GLDebugMessageInsertKHR:
+ return "glDebugMessageInsertKHR";
+ case EntryPoint::GLDeleteBuffers:
+ return "glDeleteBuffers";
+ case EntryPoint::GLDeleteFencesNV:
+ return "glDeleteFencesNV";
+ case EntryPoint::GLDeleteFramebuffers:
+ return "glDeleteFramebuffers";
+ case EntryPoint::GLDeleteFramebuffersOES:
+ return "glDeleteFramebuffersOES";
+ case EntryPoint::GLDeleteLists:
+ return "glDeleteLists";
+ case EntryPoint::GLDeleteMemoryObjectsEXT:
+ return "glDeleteMemoryObjectsEXT";
+ case EntryPoint::GLDeletePerfMonitorsAMD:
+ return "glDeletePerfMonitorsAMD";
+ case EntryPoint::GLDeleteProgram:
+ return "glDeleteProgram";
+ case EntryPoint::GLDeleteProgramPipelines:
+ return "glDeleteProgramPipelines";
+ case EntryPoint::GLDeleteProgramPipelinesEXT:
+ return "glDeleteProgramPipelinesEXT";
+ case EntryPoint::GLDeleteQueries:
+ return "glDeleteQueries";
+ case EntryPoint::GLDeleteQueriesEXT:
+ return "glDeleteQueriesEXT";
+ case EntryPoint::GLDeleteRenderbuffers:
+ return "glDeleteRenderbuffers";
+ case EntryPoint::GLDeleteRenderbuffersOES:
+ return "glDeleteRenderbuffersOES";
+ case EntryPoint::GLDeleteSamplers:
+ return "glDeleteSamplers";
+ case EntryPoint::GLDeleteSemaphoresEXT:
+ return "glDeleteSemaphoresEXT";
+ case EntryPoint::GLDeleteShader:
+ return "glDeleteShader";
+ case EntryPoint::GLDeleteSync:
+ return "glDeleteSync";
+ case EntryPoint::GLDeleteTextures:
+ return "glDeleteTextures";
+ case EntryPoint::GLDeleteTransformFeedbacks:
+ return "glDeleteTransformFeedbacks";
+ case EntryPoint::GLDeleteVertexArrays:
+ return "glDeleteVertexArrays";
+ case EntryPoint::GLDeleteVertexArraysOES:
+ return "glDeleteVertexArraysOES";
+ case EntryPoint::GLDepthFunc:
+ return "glDepthFunc";
+ case EntryPoint::GLDepthMask:
+ return "glDepthMask";
+ case EntryPoint::GLDepthRange:
+ return "glDepthRange";
+ case EntryPoint::GLDepthRangeArrayv:
+ return "glDepthRangeArrayv";
+ case EntryPoint::GLDepthRangeIndexed:
+ return "glDepthRangeIndexed";
+ case EntryPoint::GLDepthRangef:
+ return "glDepthRangef";
+ case EntryPoint::GLDepthRangex:
+ return "glDepthRangex";
+ case EntryPoint::GLDetachShader:
+ return "glDetachShader";
+ case EntryPoint::GLDisable:
+ return "glDisable";
+ case EntryPoint::GLDisableClientState:
+ return "glDisableClientState";
+ case EntryPoint::GLDisableExtensionANGLE:
+ return "glDisableExtensionANGLE";
+ case EntryPoint::GLDisableVertexArrayAttrib:
+ return "glDisableVertexArrayAttrib";
+ case EntryPoint::GLDisableVertexAttribArray:
+ return "glDisableVertexAttribArray";
+ case EntryPoint::GLDisablei:
+ return "glDisablei";
+ case EntryPoint::GLDisableiEXT:
+ return "glDisableiEXT";
+ case EntryPoint::GLDisableiOES:
+ return "glDisableiOES";
+ case EntryPoint::GLDiscardFramebufferEXT:
+ return "glDiscardFramebufferEXT";
+ case EntryPoint::GLDispatchCompute:
+ return "glDispatchCompute";
+ case EntryPoint::GLDispatchComputeIndirect:
+ return "glDispatchComputeIndirect";
+ case EntryPoint::GLDrawArrays:
+ return "glDrawArrays";
+ case EntryPoint::GLDrawArraysIndirect:
+ return "glDrawArraysIndirect";
+ case EntryPoint::GLDrawArraysInstanced:
+ return "glDrawArraysInstanced";
+ case EntryPoint::GLDrawArraysInstancedANGLE:
+ return "glDrawArraysInstancedANGLE";
+ case EntryPoint::GLDrawArraysInstancedBaseInstance:
+ return "glDrawArraysInstancedBaseInstance";
+ case EntryPoint::GLDrawArraysInstancedBaseInstanceANGLE:
+ return "glDrawArraysInstancedBaseInstanceANGLE";
+ case EntryPoint::GLDrawArraysInstancedBaseInstanceEXT:
+ return "glDrawArraysInstancedBaseInstanceEXT";
+ case EntryPoint::GLDrawArraysInstancedEXT:
+ return "glDrawArraysInstancedEXT";
+ case EntryPoint::GLDrawBuffer:
+ return "glDrawBuffer";
+ case EntryPoint::GLDrawBuffers:
+ return "glDrawBuffers";
+ case EntryPoint::GLDrawBuffersEXT:
+ return "glDrawBuffersEXT";
+ case EntryPoint::GLDrawElements:
+ return "glDrawElements";
+ case EntryPoint::GLDrawElementsBaseVertex:
+ return "glDrawElementsBaseVertex";
+ case EntryPoint::GLDrawElementsBaseVertexEXT:
+ return "glDrawElementsBaseVertexEXT";
+ case EntryPoint::GLDrawElementsBaseVertexOES:
+ return "glDrawElementsBaseVertexOES";
+ case EntryPoint::GLDrawElementsIndirect:
+ return "glDrawElementsIndirect";
+ case EntryPoint::GLDrawElementsInstanced:
+ return "glDrawElementsInstanced";
+ case EntryPoint::GLDrawElementsInstancedANGLE:
+ return "glDrawElementsInstancedANGLE";
+ case EntryPoint::GLDrawElementsInstancedBaseInstance:
+ return "glDrawElementsInstancedBaseInstance";
+ case EntryPoint::GLDrawElementsInstancedBaseInstanceEXT:
+ return "glDrawElementsInstancedBaseInstanceEXT";
+ case EntryPoint::GLDrawElementsInstancedBaseVertex:
+ return "glDrawElementsInstancedBaseVertex";
+ case EntryPoint::GLDrawElementsInstancedBaseVertexBaseInstance:
+ return "glDrawElementsInstancedBaseVertexBaseInstance";
+ case EntryPoint::GLDrawElementsInstancedBaseVertexBaseInstanceANGLE:
+ return "glDrawElementsInstancedBaseVertexBaseInstanceANGLE";
+ case EntryPoint::GLDrawElementsInstancedBaseVertexBaseInstanceEXT:
+ return "glDrawElementsInstancedBaseVertexBaseInstanceEXT";
+ case EntryPoint::GLDrawElementsInstancedBaseVertexEXT:
+ return "glDrawElementsInstancedBaseVertexEXT";
+ case EntryPoint::GLDrawElementsInstancedBaseVertexOES:
+ return "glDrawElementsInstancedBaseVertexOES";
+ case EntryPoint::GLDrawElementsInstancedEXT:
+ return "glDrawElementsInstancedEXT";
+ case EntryPoint::GLDrawPixels:
+ return "glDrawPixels";
+ case EntryPoint::GLDrawRangeElements:
+ return "glDrawRangeElements";
+ case EntryPoint::GLDrawRangeElementsBaseVertex:
+ return "glDrawRangeElementsBaseVertex";
+ case EntryPoint::GLDrawRangeElementsBaseVertexEXT:
+ return "glDrawRangeElementsBaseVertexEXT";
+ case EntryPoint::GLDrawRangeElementsBaseVertexOES:
+ return "glDrawRangeElementsBaseVertexOES";
+ case EntryPoint::GLDrawTexfOES:
+ return "glDrawTexfOES";
+ case EntryPoint::GLDrawTexfvOES:
+ return "glDrawTexfvOES";
+ case EntryPoint::GLDrawTexiOES:
+ return "glDrawTexiOES";
+ case EntryPoint::GLDrawTexivOES:
+ return "glDrawTexivOES";
+ case EntryPoint::GLDrawTexsOES:
+ return "glDrawTexsOES";
+ case EntryPoint::GLDrawTexsvOES:
+ return "glDrawTexsvOES";
+ case EntryPoint::GLDrawTexxOES:
+ return "glDrawTexxOES";
+ case EntryPoint::GLDrawTexxvOES:
+ return "glDrawTexxvOES";
+ case EntryPoint::GLDrawTransformFeedback:
+ return "glDrawTransformFeedback";
+ case EntryPoint::GLDrawTransformFeedbackInstanced:
+ return "glDrawTransformFeedbackInstanced";
+ case EntryPoint::GLDrawTransformFeedbackStream:
+ return "glDrawTransformFeedbackStream";
+ case EntryPoint::GLDrawTransformFeedbackStreamInstanced:
+ return "glDrawTransformFeedbackStreamInstanced";
+ case EntryPoint::GLEGLImageTargetRenderbufferStorageOES:
+ return "glEGLImageTargetRenderbufferStorageOES";
+ case EntryPoint::GLEGLImageTargetTexStorageEXT:
+ return "glEGLImageTargetTexStorageEXT";
+ case EntryPoint::GLEGLImageTargetTexture2DOES:
+ return "glEGLImageTargetTexture2DOES";
+ case EntryPoint::GLEGLImageTargetTextureStorageEXT:
+ return "glEGLImageTargetTextureStorageEXT";
+ case EntryPoint::GLEdgeFlag:
+ return "glEdgeFlag";
+ case EntryPoint::GLEdgeFlagPointer:
+ return "glEdgeFlagPointer";
+ case EntryPoint::GLEdgeFlagv:
+ return "glEdgeFlagv";
+ case EntryPoint::GLEnable:
+ return "glEnable";
+ case EntryPoint::GLEnableClientState:
+ return "glEnableClientState";
+ case EntryPoint::GLEnableVertexArrayAttrib:
+ return "glEnableVertexArrayAttrib";
+ case EntryPoint::GLEnableVertexAttribArray:
+ return "glEnableVertexAttribArray";
+ case EntryPoint::GLEnablei:
+ return "glEnablei";
+ case EntryPoint::GLEnableiEXT:
+ return "glEnableiEXT";
+ case EntryPoint::GLEnableiOES:
+ return "glEnableiOES";
+ case EntryPoint::GLEnd:
+ return "glEnd";
+ case EntryPoint::GLEndConditionalRender:
+ return "glEndConditionalRender";
+ case EntryPoint::GLEndList:
+ return "glEndList";
+ case EntryPoint::GLEndPerfMonitorAMD:
+ return "glEndPerfMonitorAMD";
+ case EntryPoint::GLEndPixelLocalStorageANGLE:
+ return "glEndPixelLocalStorageANGLE";
+ case EntryPoint::GLEndQuery:
+ return "glEndQuery";
+ case EntryPoint::GLEndQueryEXT:
+ return "glEndQueryEXT";
+ case EntryPoint::GLEndQueryIndexed:
+ return "glEndQueryIndexed";
+ case EntryPoint::GLEndTransformFeedback:
+ return "glEndTransformFeedback";
+ case EntryPoint::GLEvalCoord1d:
+ return "glEvalCoord1d";
+ case EntryPoint::GLEvalCoord1dv:
+ return "glEvalCoord1dv";
+ case EntryPoint::GLEvalCoord1f:
+ return "glEvalCoord1f";
+ case EntryPoint::GLEvalCoord1fv:
+ return "glEvalCoord1fv";
+ case EntryPoint::GLEvalCoord2d:
+ return "glEvalCoord2d";
+ case EntryPoint::GLEvalCoord2dv:
+ return "glEvalCoord2dv";
+ case EntryPoint::GLEvalCoord2f:
+ return "glEvalCoord2f";
+ case EntryPoint::GLEvalCoord2fv:
+ return "glEvalCoord2fv";
+ case EntryPoint::GLEvalMesh1:
+ return "glEvalMesh1";
+ case EntryPoint::GLEvalMesh2:
+ return "glEvalMesh2";
+ case EntryPoint::GLEvalPoint1:
+ return "glEvalPoint1";
+ case EntryPoint::GLEvalPoint2:
+ return "glEvalPoint2";
+ case EntryPoint::GLFeedbackBuffer:
+ return "glFeedbackBuffer";
+ case EntryPoint::GLFenceSync:
+ return "glFenceSync";
+ case EntryPoint::GLFinish:
+ return "glFinish";
+ case EntryPoint::GLFinishFenceNV:
+ return "glFinishFenceNV";
+ case EntryPoint::GLFlush:
+ return "glFlush";
+ case EntryPoint::GLFlushMappedBufferRange:
+ return "glFlushMappedBufferRange";
+ case EntryPoint::GLFlushMappedBufferRangeEXT:
+ return "glFlushMappedBufferRangeEXT";
+ case EntryPoint::GLFlushMappedNamedBufferRange:
+ return "glFlushMappedNamedBufferRange";
+ case EntryPoint::GLFogCoordPointer:
+ return "glFogCoordPointer";
+ case EntryPoint::GLFogCoordd:
+ return "glFogCoordd";
+ case EntryPoint::GLFogCoorddv:
+ return "glFogCoorddv";
+ case EntryPoint::GLFogCoordf:
+ return "glFogCoordf";
+ case EntryPoint::GLFogCoordfv:
+ return "glFogCoordfv";
+ case EntryPoint::GLFogf:
+ return "glFogf";
+ case EntryPoint::GLFogfv:
+ return "glFogfv";
+ case EntryPoint::GLFogi:
+ return "glFogi";
+ case EntryPoint::GLFogiv:
+ return "glFogiv";
+ case EntryPoint::GLFogx:
+ return "glFogx";
+ case EntryPoint::GLFogxv:
+ return "glFogxv";
+ case EntryPoint::GLFramebufferFetchBarrierEXT:
+ return "glFramebufferFetchBarrierEXT";
+ case EntryPoint::GLFramebufferMemorylessPixelLocalStorageANGLE:
+ return "glFramebufferMemorylessPixelLocalStorageANGLE";
+ case EntryPoint::GLFramebufferParameteri:
+ return "glFramebufferParameteri";
+ case EntryPoint::GLFramebufferParameteriMESA:
+ return "glFramebufferParameteriMESA";
+ case EntryPoint::GLFramebufferRenderbuffer:
+ return "glFramebufferRenderbuffer";
+ case EntryPoint::GLFramebufferRenderbufferOES:
+ return "glFramebufferRenderbufferOES";
+ case EntryPoint::GLFramebufferTexture:
+ return "glFramebufferTexture";
+ case EntryPoint::GLFramebufferTexture1D:
+ return "glFramebufferTexture1D";
+ case EntryPoint::GLFramebufferTexture2D:
+ return "glFramebufferTexture2D";
+ case EntryPoint::GLFramebufferTexture2DMultisampleEXT:
+ return "glFramebufferTexture2DMultisampleEXT";
+ case EntryPoint::GLFramebufferTexture2DOES:
+ return "glFramebufferTexture2DOES";
+ case EntryPoint::GLFramebufferTexture3D:
+ return "glFramebufferTexture3D";
+ case EntryPoint::GLFramebufferTexture3DOES:
+ return "glFramebufferTexture3DOES";
+ case EntryPoint::GLFramebufferTextureEXT:
+ return "glFramebufferTextureEXT";
+ case EntryPoint::GLFramebufferTextureLayer:
+ return "glFramebufferTextureLayer";
+ case EntryPoint::GLFramebufferTextureMultiviewOVR:
+ return "glFramebufferTextureMultiviewOVR";
+ case EntryPoint::GLFramebufferTextureOES:
+ return "glFramebufferTextureOES";
+ case EntryPoint::GLFramebufferTexturePixelLocalStorageANGLE:
+ return "glFramebufferTexturePixelLocalStorageANGLE";
+ case EntryPoint::GLFrontFace:
+ return "glFrontFace";
+ case EntryPoint::GLFrustum:
+ return "glFrustum";
+ case EntryPoint::GLFrustumf:
+ return "glFrustumf";
+ case EntryPoint::GLFrustumx:
+ return "glFrustumx";
+ case EntryPoint::GLGenBuffers:
+ return "glGenBuffers";
+ case EntryPoint::GLGenFencesNV:
+ return "glGenFencesNV";
+ case EntryPoint::GLGenFramebuffers:
+ return "glGenFramebuffers";
+ case EntryPoint::GLGenFramebuffersOES:
+ return "glGenFramebuffersOES";
+ case EntryPoint::GLGenLists:
+ return "glGenLists";
+ case EntryPoint::GLGenPerfMonitorsAMD:
+ return "glGenPerfMonitorsAMD";
+ case EntryPoint::GLGenProgramPipelines:
+ return "glGenProgramPipelines";
+ case EntryPoint::GLGenProgramPipelinesEXT:
+ return "glGenProgramPipelinesEXT";
+ case EntryPoint::GLGenQueries:
+ return "glGenQueries";
+ case EntryPoint::GLGenQueriesEXT:
+ return "glGenQueriesEXT";
+ case EntryPoint::GLGenRenderbuffers:
+ return "glGenRenderbuffers";
+ case EntryPoint::GLGenRenderbuffersOES:
+ return "glGenRenderbuffersOES";
+ case EntryPoint::GLGenSamplers:
+ return "glGenSamplers";
+ case EntryPoint::GLGenSemaphoresEXT:
+ return "glGenSemaphoresEXT";
+ case EntryPoint::GLGenTextures:
+ return "glGenTextures";
+ case EntryPoint::GLGenTransformFeedbacks:
+ return "glGenTransformFeedbacks";
+ case EntryPoint::GLGenVertexArrays:
+ return "glGenVertexArrays";
+ case EntryPoint::GLGenVertexArraysOES:
+ return "glGenVertexArraysOES";
+ case EntryPoint::GLGenerateMipmap:
+ return "glGenerateMipmap";
+ case EntryPoint::GLGenerateMipmapOES:
+ return "glGenerateMipmapOES";
+ case EntryPoint::GLGenerateTextureMipmap:
+ return "glGenerateTextureMipmap";
+ case EntryPoint::GLGetActiveAtomicCounterBufferiv:
+ return "glGetActiveAtomicCounterBufferiv";
+ case EntryPoint::GLGetActiveAttrib:
+ return "glGetActiveAttrib";
+ case EntryPoint::GLGetActiveSubroutineName:
+ return "glGetActiveSubroutineName";
+ case EntryPoint::GLGetActiveSubroutineUniformName:
+ return "glGetActiveSubroutineUniformName";
+ case EntryPoint::GLGetActiveSubroutineUniformiv:
+ return "glGetActiveSubroutineUniformiv";
+ case EntryPoint::GLGetActiveUniform:
+ return "glGetActiveUniform";
+ case EntryPoint::GLGetActiveUniformBlockName:
+ return "glGetActiveUniformBlockName";
+ case EntryPoint::GLGetActiveUniformBlockiv:
+ return "glGetActiveUniformBlockiv";
+ case EntryPoint::GLGetActiveUniformBlockivRobustANGLE:
+ return "glGetActiveUniformBlockivRobustANGLE";
+ case EntryPoint::GLGetActiveUniformName:
+ return "glGetActiveUniformName";
+ case EntryPoint::GLGetActiveUniformsiv:
+ return "glGetActiveUniformsiv";
+ case EntryPoint::GLGetAttachedShaders:
+ return "glGetAttachedShaders";
+ case EntryPoint::GLGetAttribLocation:
+ return "glGetAttribLocation";
+ case EntryPoint::GLGetBooleani_v:
+ return "glGetBooleani_v";
+ case EntryPoint::GLGetBooleani_vRobustANGLE:
+ return "glGetBooleani_vRobustANGLE";
+ case EntryPoint::GLGetBooleanv:
+ return "glGetBooleanv";
+ case EntryPoint::GLGetBooleanvRobustANGLE:
+ return "glGetBooleanvRobustANGLE";
+ case EntryPoint::GLGetBufferParameteri64v:
+ return "glGetBufferParameteri64v";
+ case EntryPoint::GLGetBufferParameteri64vRobustANGLE:
+ return "glGetBufferParameteri64vRobustANGLE";
+ case EntryPoint::GLGetBufferParameteriv:
+ return "glGetBufferParameteriv";
+ case EntryPoint::GLGetBufferParameterivRobustANGLE:
+ return "glGetBufferParameterivRobustANGLE";
+ case EntryPoint::GLGetBufferPointerv:
+ return "glGetBufferPointerv";
+ case EntryPoint::GLGetBufferPointervOES:
+ return "glGetBufferPointervOES";
+ case EntryPoint::GLGetBufferPointervRobustANGLE:
+ return "glGetBufferPointervRobustANGLE";
+ case EntryPoint::GLGetBufferSubData:
+ return "glGetBufferSubData";
+ case EntryPoint::GLGetClipPlane:
+ return "glGetClipPlane";
+ case EntryPoint::GLGetClipPlanef:
+ return "glGetClipPlanef";
+ case EntryPoint::GLGetClipPlanex:
+ return "glGetClipPlanex";
+ case EntryPoint::GLGetCompressedTexImage:
+ return "glGetCompressedTexImage";
+ case EntryPoint::GLGetCompressedTexImageANGLE:
+ return "glGetCompressedTexImageANGLE";
+ case EntryPoint::GLGetCompressedTextureImage:
+ return "glGetCompressedTextureImage";
+ case EntryPoint::GLGetCompressedTextureSubImage:
+ return "glGetCompressedTextureSubImage";
+ case EntryPoint::GLGetDebugMessageLog:
+ return "glGetDebugMessageLog";
+ case EntryPoint::GLGetDebugMessageLogKHR:
+ return "glGetDebugMessageLogKHR";
+ case EntryPoint::GLGetDoublei_v:
+ return "glGetDoublei_v";
+ case EntryPoint::GLGetDoublev:
+ return "glGetDoublev";
+ case EntryPoint::GLGetError:
+ return "glGetError";
+ case EntryPoint::GLGetFenceivNV:
+ return "glGetFenceivNV";
+ case EntryPoint::GLGetFixedv:
+ return "glGetFixedv";
+ case EntryPoint::GLGetFloati_v:
+ return "glGetFloati_v";
+ case EntryPoint::GLGetFloatv:
+ return "glGetFloatv";
+ case EntryPoint::GLGetFloatvRobustANGLE:
+ return "glGetFloatvRobustANGLE";
+ case EntryPoint::GLGetFragDataIndex:
+ return "glGetFragDataIndex";
+ case EntryPoint::GLGetFragDataIndexEXT:
+ return "glGetFragDataIndexEXT";
+ case EntryPoint::GLGetFragDataLocation:
+ return "glGetFragDataLocation";
+ case EntryPoint::GLGetFramebufferAttachmentParameteriv:
+ return "glGetFramebufferAttachmentParameteriv";
+ case EntryPoint::GLGetFramebufferAttachmentParameterivOES:
+ return "glGetFramebufferAttachmentParameterivOES";
+ case EntryPoint::GLGetFramebufferAttachmentParameterivRobustANGLE:
+ return "glGetFramebufferAttachmentParameterivRobustANGLE";
+ case EntryPoint::GLGetFramebufferParameteriv:
+ return "glGetFramebufferParameteriv";
+ case EntryPoint::GLGetFramebufferParameterivMESA:
+ return "glGetFramebufferParameterivMESA";
+ case EntryPoint::GLGetFramebufferParameterivRobustANGLE:
+ return "glGetFramebufferParameterivRobustANGLE";
+ case EntryPoint::GLGetGraphicsResetStatus:
+ return "glGetGraphicsResetStatus";
+ case EntryPoint::GLGetGraphicsResetStatusEXT:
+ return "glGetGraphicsResetStatusEXT";
+ case EntryPoint::GLGetInteger64i_v:
+ return "glGetInteger64i_v";
+ case EntryPoint::GLGetInteger64i_vRobustANGLE:
+ return "glGetInteger64i_vRobustANGLE";
+ case EntryPoint::GLGetInteger64v:
+ return "glGetInteger64v";
+ case EntryPoint::GLGetInteger64vEXT:
+ return "glGetInteger64vEXT";
+ case EntryPoint::GLGetInteger64vRobustANGLE:
+ return "glGetInteger64vRobustANGLE";
+ case EntryPoint::GLGetIntegeri_v:
+ return "glGetIntegeri_v";
+ case EntryPoint::GLGetIntegeri_vRobustANGLE:
+ return "glGetIntegeri_vRobustANGLE";
+ case EntryPoint::GLGetIntegerv:
+ return "glGetIntegerv";
+ case EntryPoint::GLGetIntegervRobustANGLE:
+ return "glGetIntegervRobustANGLE";
+ case EntryPoint::GLGetInternalformati64v:
+ return "glGetInternalformati64v";
+ case EntryPoint::GLGetInternalformativ:
+ return "glGetInternalformativ";
+ case EntryPoint::GLGetInternalformativRobustANGLE:
+ return "glGetInternalformativRobustANGLE";
+ case EntryPoint::GLGetLightfv:
+ return "glGetLightfv";
+ case EntryPoint::GLGetLightiv:
+ return "glGetLightiv";
+ case EntryPoint::GLGetLightxv:
+ return "glGetLightxv";
+ case EntryPoint::GLGetMapdv:
+ return "glGetMapdv";
+ case EntryPoint::GLGetMapfv:
+ return "glGetMapfv";
+ case EntryPoint::GLGetMapiv:
+ return "glGetMapiv";
+ case EntryPoint::GLGetMaterialfv:
+ return "glGetMaterialfv";
+ case EntryPoint::GLGetMaterialiv:
+ return "glGetMaterialiv";
+ case EntryPoint::GLGetMaterialxv:
+ return "glGetMaterialxv";
+ case EntryPoint::GLGetMemoryObjectParameterivEXT:
+ return "glGetMemoryObjectParameterivEXT";
+ case EntryPoint::GLGetMultisamplefv:
+ return "glGetMultisamplefv";
+ case EntryPoint::GLGetMultisamplefvANGLE:
+ return "glGetMultisamplefvANGLE";
+ case EntryPoint::GLGetMultisamplefvRobustANGLE:
+ return "glGetMultisamplefvRobustANGLE";
+ case EntryPoint::GLGetNamedBufferParameteri64v:
+ return "glGetNamedBufferParameteri64v";
+ case EntryPoint::GLGetNamedBufferParameteriv:
+ return "glGetNamedBufferParameteriv";
+ case EntryPoint::GLGetNamedBufferPointerv:
+ return "glGetNamedBufferPointerv";
+ case EntryPoint::GLGetNamedBufferSubData:
+ return "glGetNamedBufferSubData";
+ case EntryPoint::GLGetNamedFramebufferAttachmentParameteriv:
+ return "glGetNamedFramebufferAttachmentParameteriv";
+ case EntryPoint::GLGetNamedFramebufferParameteriv:
+ return "glGetNamedFramebufferParameteriv";
+ case EntryPoint::GLGetNamedRenderbufferParameteriv:
+ return "glGetNamedRenderbufferParameteriv";
+ case EntryPoint::GLGetObjectLabel:
+ return "glGetObjectLabel";
+ case EntryPoint::GLGetObjectLabelEXT:
+ return "glGetObjectLabelEXT";
+ case EntryPoint::GLGetObjectLabelKHR:
+ return "glGetObjectLabelKHR";
+ case EntryPoint::GLGetObjectPtrLabel:
+ return "glGetObjectPtrLabel";
+ case EntryPoint::GLGetObjectPtrLabelKHR:
+ return "glGetObjectPtrLabelKHR";
+ case EntryPoint::GLGetPerfMonitorCounterDataAMD:
+ return "glGetPerfMonitorCounterDataAMD";
+ case EntryPoint::GLGetPerfMonitorCounterInfoAMD:
+ return "glGetPerfMonitorCounterInfoAMD";
+ case EntryPoint::GLGetPerfMonitorCounterStringAMD:
+ return "glGetPerfMonitorCounterStringAMD";
+ case EntryPoint::GLGetPerfMonitorCountersAMD:
+ return "glGetPerfMonitorCountersAMD";
+ case EntryPoint::GLGetPerfMonitorGroupStringAMD:
+ return "glGetPerfMonitorGroupStringAMD";
+ case EntryPoint::GLGetPerfMonitorGroupsAMD:
+ return "glGetPerfMonitorGroupsAMD";
+ case EntryPoint::GLGetPixelMapfv:
+ return "glGetPixelMapfv";
+ case EntryPoint::GLGetPixelMapuiv:
+ return "glGetPixelMapuiv";
+ case EntryPoint::GLGetPixelMapusv:
+ return "glGetPixelMapusv";
+ case EntryPoint::GLGetPointerv:
+ return "glGetPointerv";
+ case EntryPoint::GLGetPointervKHR:
+ return "glGetPointervKHR";
+ case EntryPoint::GLGetPointervRobustANGLERobustANGLE:
+ return "glGetPointervRobustANGLERobustANGLE";
+ case EntryPoint::GLGetPolygonStipple:
+ return "glGetPolygonStipple";
+ case EntryPoint::GLGetProgramBinary:
+ return "glGetProgramBinary";
+ case EntryPoint::GLGetProgramBinaryOES:
+ return "glGetProgramBinaryOES";
+ case EntryPoint::GLGetProgramInfoLog:
+ return "glGetProgramInfoLog";
+ case EntryPoint::GLGetProgramInterfaceiv:
+ return "glGetProgramInterfaceiv";
+ case EntryPoint::GLGetProgramInterfaceivRobustANGLE:
+ return "glGetProgramInterfaceivRobustANGLE";
+ case EntryPoint::GLGetProgramPipelineInfoLog:
+ return "glGetProgramPipelineInfoLog";
+ case EntryPoint::GLGetProgramPipelineInfoLogEXT:
+ return "glGetProgramPipelineInfoLogEXT";
+ case EntryPoint::GLGetProgramPipelineiv:
+ return "glGetProgramPipelineiv";
+ case EntryPoint::GLGetProgramPipelineivEXT:
+ return "glGetProgramPipelineivEXT";
+ case EntryPoint::GLGetProgramResourceIndex:
+ return "glGetProgramResourceIndex";
+ case EntryPoint::GLGetProgramResourceLocation:
+ return "glGetProgramResourceLocation";
+ case EntryPoint::GLGetProgramResourceLocationIndex:
+ return "glGetProgramResourceLocationIndex";
+ case EntryPoint::GLGetProgramResourceLocationIndexEXT:
+ return "glGetProgramResourceLocationIndexEXT";
+ case EntryPoint::GLGetProgramResourceName:
+ return "glGetProgramResourceName";
+ case EntryPoint::GLGetProgramResourceiv:
+ return "glGetProgramResourceiv";
+ case EntryPoint::GLGetProgramStageiv:
+ return "glGetProgramStageiv";
+ case EntryPoint::GLGetProgramiv:
+ return "glGetProgramiv";
+ case EntryPoint::GLGetProgramivRobustANGLE:
+ return "glGetProgramivRobustANGLE";
+ case EntryPoint::GLGetQueryBufferObjecti64v:
+ return "glGetQueryBufferObjecti64v";
+ case EntryPoint::GLGetQueryBufferObjectiv:
+ return "glGetQueryBufferObjectiv";
+ case EntryPoint::GLGetQueryBufferObjectui64v:
+ return "glGetQueryBufferObjectui64v";
+ case EntryPoint::GLGetQueryBufferObjectuiv:
+ return "glGetQueryBufferObjectuiv";
+ case EntryPoint::GLGetQueryIndexediv:
+ return "glGetQueryIndexediv";
+ case EntryPoint::GLGetQueryObjecti64v:
+ return "glGetQueryObjecti64v";
+ case EntryPoint::GLGetQueryObjecti64vEXT:
+ return "glGetQueryObjecti64vEXT";
+ case EntryPoint::GLGetQueryObjecti64vRobustANGLE:
+ return "glGetQueryObjecti64vRobustANGLE";
+ case EntryPoint::GLGetQueryObjectiv:
+ return "glGetQueryObjectiv";
+ case EntryPoint::GLGetQueryObjectivEXT:
+ return "glGetQueryObjectivEXT";
+ case EntryPoint::GLGetQueryObjectivRobustANGLE:
+ return "glGetQueryObjectivRobustANGLE";
+ case EntryPoint::GLGetQueryObjectui64v:
+ return "glGetQueryObjectui64v";
+ case EntryPoint::GLGetQueryObjectui64vEXT:
+ return "glGetQueryObjectui64vEXT";
+ case EntryPoint::GLGetQueryObjectui64vRobustANGLE:
+ return "glGetQueryObjectui64vRobustANGLE";
+ case EntryPoint::GLGetQueryObjectuiv:
+ return "glGetQueryObjectuiv";
+ case EntryPoint::GLGetQueryObjectuivEXT:
+ return "glGetQueryObjectuivEXT";
+ case EntryPoint::GLGetQueryObjectuivRobustANGLE:
+ return "glGetQueryObjectuivRobustANGLE";
+ case EntryPoint::GLGetQueryiv:
+ return "glGetQueryiv";
+ case EntryPoint::GLGetQueryivEXT:
+ return "glGetQueryivEXT";
+ case EntryPoint::GLGetQueryivRobustANGLE:
+ return "glGetQueryivRobustANGLE";
+ case EntryPoint::GLGetRenderbufferImageANGLE:
+ return "glGetRenderbufferImageANGLE";
+ case EntryPoint::GLGetRenderbufferParameteriv:
+ return "glGetRenderbufferParameteriv";
+ case EntryPoint::GLGetRenderbufferParameterivOES:
+ return "glGetRenderbufferParameterivOES";
+ case EntryPoint::GLGetRenderbufferParameterivRobustANGLE:
+ return "glGetRenderbufferParameterivRobustANGLE";
+ case EntryPoint::GLGetSamplerParameterIiv:
+ return "glGetSamplerParameterIiv";
+ case EntryPoint::GLGetSamplerParameterIivEXT:
+ return "glGetSamplerParameterIivEXT";
+ case EntryPoint::GLGetSamplerParameterIivOES:
+ return "glGetSamplerParameterIivOES";
+ case EntryPoint::GLGetSamplerParameterIivRobustANGLE:
+ return "glGetSamplerParameterIivRobustANGLE";
+ case EntryPoint::GLGetSamplerParameterIuiv:
+ return "glGetSamplerParameterIuiv";
+ case EntryPoint::GLGetSamplerParameterIuivEXT:
+ return "glGetSamplerParameterIuivEXT";
+ case EntryPoint::GLGetSamplerParameterIuivOES:
+ return "glGetSamplerParameterIuivOES";
+ case EntryPoint::GLGetSamplerParameterIuivRobustANGLE:
+ return "glGetSamplerParameterIuivRobustANGLE";
+ case EntryPoint::GLGetSamplerParameterfv:
+ return "glGetSamplerParameterfv";
+ case EntryPoint::GLGetSamplerParameterfvRobustANGLE:
+ return "glGetSamplerParameterfvRobustANGLE";
+ case EntryPoint::GLGetSamplerParameteriv:
+ return "glGetSamplerParameteriv";
+ case EntryPoint::GLGetSamplerParameterivRobustANGLE:
+ return "glGetSamplerParameterivRobustANGLE";
+ case EntryPoint::GLGetSemaphoreParameterui64vEXT:
+ return "glGetSemaphoreParameterui64vEXT";
+ case EntryPoint::GLGetShaderInfoLog:
+ return "glGetShaderInfoLog";
+ case EntryPoint::GLGetShaderPrecisionFormat:
+ return "glGetShaderPrecisionFormat";
+ case EntryPoint::GLGetShaderSource:
+ return "glGetShaderSource";
+ case EntryPoint::GLGetShaderiv:
+ return "glGetShaderiv";
+ case EntryPoint::GLGetShaderivRobustANGLE:
+ return "glGetShaderivRobustANGLE";
+ case EntryPoint::GLGetString:
+ return "glGetString";
+ case EntryPoint::GLGetStringi:
+ return "glGetStringi";
+ case EntryPoint::GLGetSubroutineIndex:
+ return "glGetSubroutineIndex";
+ case EntryPoint::GLGetSubroutineUniformLocation:
+ return "glGetSubroutineUniformLocation";
+ case EntryPoint::GLGetSynciv:
+ return "glGetSynciv";
+ case EntryPoint::GLGetTexEnvfv:
+ return "glGetTexEnvfv";
+ case EntryPoint::GLGetTexEnviv:
+ return "glGetTexEnviv";
+ case EntryPoint::GLGetTexEnvxv:
+ return "glGetTexEnvxv";
+ case EntryPoint::GLGetTexGendv:
+ return "glGetTexGendv";
+ case EntryPoint::GLGetTexGenfv:
+ return "glGetTexGenfv";
+ case EntryPoint::GLGetTexGenfvOES:
+ return "glGetTexGenfvOES";
+ case EntryPoint::GLGetTexGeniv:
+ return "glGetTexGeniv";
+ case EntryPoint::GLGetTexGenivOES:
+ return "glGetTexGenivOES";
+ case EntryPoint::GLGetTexGenxvOES:
+ return "glGetTexGenxvOES";
+ case EntryPoint::GLGetTexImage:
+ return "glGetTexImage";
+ case EntryPoint::GLGetTexImageANGLE:
+ return "glGetTexImageANGLE";
+ case EntryPoint::GLGetTexLevelParameterfv:
+ return "glGetTexLevelParameterfv";
+ case EntryPoint::GLGetTexLevelParameterfvANGLE:
+ return "glGetTexLevelParameterfvANGLE";
+ case EntryPoint::GLGetTexLevelParameterfvRobustANGLE:
+ return "glGetTexLevelParameterfvRobustANGLE";
+ case EntryPoint::GLGetTexLevelParameteriv:
+ return "glGetTexLevelParameteriv";
+ case EntryPoint::GLGetTexLevelParameterivANGLE:
+ return "glGetTexLevelParameterivANGLE";
+ case EntryPoint::GLGetTexLevelParameterivRobustANGLE:
+ return "glGetTexLevelParameterivRobustANGLE";
+ case EntryPoint::GLGetTexParameterIiv:
+ return "glGetTexParameterIiv";
+ case EntryPoint::GLGetTexParameterIivEXT:
+ return "glGetTexParameterIivEXT";
+ case EntryPoint::GLGetTexParameterIivOES:
+ return "glGetTexParameterIivOES";
+ case EntryPoint::GLGetTexParameterIivRobustANGLE:
+ return "glGetTexParameterIivRobustANGLE";
+ case EntryPoint::GLGetTexParameterIuiv:
+ return "glGetTexParameterIuiv";
+ case EntryPoint::GLGetTexParameterIuivEXT:
+ return "glGetTexParameterIuivEXT";
+ case EntryPoint::GLGetTexParameterIuivOES:
+ return "glGetTexParameterIuivOES";
+ case EntryPoint::GLGetTexParameterIuivRobustANGLE:
+ return "glGetTexParameterIuivRobustANGLE";
+ case EntryPoint::GLGetTexParameterfv:
+ return "glGetTexParameterfv";
+ case EntryPoint::GLGetTexParameterfvRobustANGLE:
+ return "glGetTexParameterfvRobustANGLE";
+ case EntryPoint::GLGetTexParameteriv:
+ return "glGetTexParameteriv";
+ case EntryPoint::GLGetTexParameterivRobustANGLE:
+ return "glGetTexParameterivRobustANGLE";
+ case EntryPoint::GLGetTexParameterxv:
+ return "glGetTexParameterxv";
+ case EntryPoint::GLGetTextureImage:
+ return "glGetTextureImage";
+ case EntryPoint::GLGetTextureLevelParameterfv:
+ return "glGetTextureLevelParameterfv";
+ case EntryPoint::GLGetTextureLevelParameteriv:
+ return "glGetTextureLevelParameteriv";
+ case EntryPoint::GLGetTextureParameterIiv:
+ return "glGetTextureParameterIiv";
+ case EntryPoint::GLGetTextureParameterIuiv:
+ return "glGetTextureParameterIuiv";
+ case EntryPoint::GLGetTextureParameterfv:
+ return "glGetTextureParameterfv";
+ case EntryPoint::GLGetTextureParameteriv:
+ return "glGetTextureParameteriv";
+ case EntryPoint::GLGetTextureSubImage:
+ return "glGetTextureSubImage";
+ case EntryPoint::GLGetTransformFeedbackVarying:
+ return "glGetTransformFeedbackVarying";
+ case EntryPoint::GLGetTransformFeedbacki64_v:
+ return "glGetTransformFeedbacki64_v";
+ case EntryPoint::GLGetTransformFeedbacki_v:
+ return "glGetTransformFeedbacki_v";
+ case EntryPoint::GLGetTransformFeedbackiv:
+ return "glGetTransformFeedbackiv";
+ case EntryPoint::GLGetTranslatedShaderSourceANGLE:
+ return "glGetTranslatedShaderSourceANGLE";
+ case EntryPoint::GLGetUniformBlockIndex:
+ return "glGetUniformBlockIndex";
+ case EntryPoint::GLGetUniformIndices:
+ return "glGetUniformIndices";
+ case EntryPoint::GLGetUniformLocation:
+ return "glGetUniformLocation";
+ case EntryPoint::GLGetUniformSubroutineuiv:
+ return "glGetUniformSubroutineuiv";
+ case EntryPoint::GLGetUniformdv:
+ return "glGetUniformdv";
+ case EntryPoint::GLGetUniformfv:
+ return "glGetUniformfv";
+ case EntryPoint::GLGetUniformfvRobustANGLE:
+ return "glGetUniformfvRobustANGLE";
+ case EntryPoint::GLGetUniformiv:
+ return "glGetUniformiv";
+ case EntryPoint::GLGetUniformivRobustANGLE:
+ return "glGetUniformivRobustANGLE";
+ case EntryPoint::GLGetUniformuiv:
+ return "glGetUniformuiv";
+ case EntryPoint::GLGetUniformuivRobustANGLE:
+ return "glGetUniformuivRobustANGLE";
+ case EntryPoint::GLGetUnsignedBytei_vEXT:
+ return "glGetUnsignedBytei_vEXT";
+ case EntryPoint::GLGetUnsignedBytevEXT:
+ return "glGetUnsignedBytevEXT";
+ case EntryPoint::GLGetVertexArrayIndexed64iv:
+ return "glGetVertexArrayIndexed64iv";
+ case EntryPoint::GLGetVertexArrayIndexediv:
+ return "glGetVertexArrayIndexediv";
+ case EntryPoint::GLGetVertexArrayiv:
+ return "glGetVertexArrayiv";
+ case EntryPoint::GLGetVertexAttribIiv:
+ return "glGetVertexAttribIiv";
+ case EntryPoint::GLGetVertexAttribIivRobustANGLE:
+ return "glGetVertexAttribIivRobustANGLE";
+ case EntryPoint::GLGetVertexAttribIuiv:
+ return "glGetVertexAttribIuiv";
+ case EntryPoint::GLGetVertexAttribIuivRobustANGLE:
+ return "glGetVertexAttribIuivRobustANGLE";
+ case EntryPoint::GLGetVertexAttribLdv:
+ return "glGetVertexAttribLdv";
+ case EntryPoint::GLGetVertexAttribPointerv:
+ return "glGetVertexAttribPointerv";
+ case EntryPoint::GLGetVertexAttribPointervRobustANGLE:
+ return "glGetVertexAttribPointervRobustANGLE";
+ case EntryPoint::GLGetVertexAttribdv:
+ return "glGetVertexAttribdv";
+ case EntryPoint::GLGetVertexAttribfv:
+ return "glGetVertexAttribfv";
+ case EntryPoint::GLGetVertexAttribfvRobustANGLE:
+ return "glGetVertexAttribfvRobustANGLE";
+ case EntryPoint::GLGetVertexAttribiv:
+ return "glGetVertexAttribiv";
+ case EntryPoint::GLGetVertexAttribivRobustANGLE:
+ return "glGetVertexAttribivRobustANGLE";
+ case EntryPoint::GLGetnColorTable:
+ return "glGetnColorTable";
+ case EntryPoint::GLGetnCompressedTexImage:
+ return "glGetnCompressedTexImage";
+ case EntryPoint::GLGetnConvolutionFilter:
+ return "glGetnConvolutionFilter";
+ case EntryPoint::GLGetnHistogram:
+ return "glGetnHistogram";
+ case EntryPoint::GLGetnMapdv:
+ return "glGetnMapdv";
+ case EntryPoint::GLGetnMapfv:
+ return "glGetnMapfv";
+ case EntryPoint::GLGetnMapiv:
+ return "glGetnMapiv";
+ case EntryPoint::GLGetnMinmax:
+ return "glGetnMinmax";
+ case EntryPoint::GLGetnPixelMapfv:
+ return "glGetnPixelMapfv";
+ case EntryPoint::GLGetnPixelMapuiv:
+ return "glGetnPixelMapuiv";
+ case EntryPoint::GLGetnPixelMapusv:
+ return "glGetnPixelMapusv";
+ case EntryPoint::GLGetnPolygonStipple:
+ return "glGetnPolygonStipple";
+ case EntryPoint::GLGetnSeparableFilter:
+ return "glGetnSeparableFilter";
+ case EntryPoint::GLGetnTexImage:
+ return "glGetnTexImage";
+ case EntryPoint::GLGetnUniformdv:
+ return "glGetnUniformdv";
+ case EntryPoint::GLGetnUniformfv:
+ return "glGetnUniformfv";
+ case EntryPoint::GLGetnUniformfvEXT:
+ return "glGetnUniformfvEXT";
+ case EntryPoint::GLGetnUniformfvRobustANGLE:
+ return "glGetnUniformfvRobustANGLE";
+ case EntryPoint::GLGetnUniformiv:
+ return "glGetnUniformiv";
+ case EntryPoint::GLGetnUniformivEXT:
+ return "glGetnUniformivEXT";
+ case EntryPoint::GLGetnUniformivRobustANGLE:
+ return "glGetnUniformivRobustANGLE";
+ case EntryPoint::GLGetnUniformuiv:
+ return "glGetnUniformuiv";
+ case EntryPoint::GLGetnUniformuivRobustANGLE:
+ return "glGetnUniformuivRobustANGLE";
+ case EntryPoint::GLHint:
+ return "glHint";
+ case EntryPoint::GLImportMemoryFdEXT:
+ return "glImportMemoryFdEXT";
+ case EntryPoint::GLImportMemoryZirconHandleANGLE:
+ return "glImportMemoryZirconHandleANGLE";
+ case EntryPoint::GLImportSemaphoreFdEXT:
+ return "glImportSemaphoreFdEXT";
+ case EntryPoint::GLImportSemaphoreZirconHandleANGLE:
+ return "glImportSemaphoreZirconHandleANGLE";
+ case EntryPoint::GLIndexMask:
+ return "glIndexMask";
+ case EntryPoint::GLIndexPointer:
+ return "glIndexPointer";
+ case EntryPoint::GLIndexd:
+ return "glIndexd";
+ case EntryPoint::GLIndexdv:
+ return "glIndexdv";
+ case EntryPoint::GLIndexf:
+ return "glIndexf";
+ case EntryPoint::GLIndexfv:
+ return "glIndexfv";
+ case EntryPoint::GLIndexi:
+ return "glIndexi";
+ case EntryPoint::GLIndexiv:
+ return "glIndexiv";
+ case EntryPoint::GLIndexs:
+ return "glIndexs";
+ case EntryPoint::GLIndexsv:
+ return "glIndexsv";
+ case EntryPoint::GLIndexub:
+ return "glIndexub";
+ case EntryPoint::GLIndexubv:
+ return "glIndexubv";
+ case EntryPoint::GLInitNames:
+ return "glInitNames";
+ case EntryPoint::GLInsertEventMarkerEXT:
+ return "glInsertEventMarkerEXT";
+ case EntryPoint::GLInterleavedArrays:
+ return "glInterleavedArrays";
+ case EntryPoint::GLInvalid:
+ return "glInvalid";
+ case EntryPoint::GLInvalidateBufferData:
+ return "glInvalidateBufferData";
+ case EntryPoint::GLInvalidateBufferSubData:
+ return "glInvalidateBufferSubData";
+ case EntryPoint::GLInvalidateFramebuffer:
+ return "glInvalidateFramebuffer";
+ case EntryPoint::GLInvalidateNamedFramebufferData:
+ return "glInvalidateNamedFramebufferData";
+ case EntryPoint::GLInvalidateNamedFramebufferSubData:
+ return "glInvalidateNamedFramebufferSubData";
+ case EntryPoint::GLInvalidateSubFramebuffer:
+ return "glInvalidateSubFramebuffer";
+ case EntryPoint::GLInvalidateTexImage:
+ return "glInvalidateTexImage";
+ case EntryPoint::GLInvalidateTexSubImage:
+ return "glInvalidateTexSubImage";
+ case EntryPoint::GLInvalidateTextureANGLE:
+ return "glInvalidateTextureANGLE";
+ case EntryPoint::GLIsBuffer:
+ return "glIsBuffer";
+ case EntryPoint::GLIsEnabled:
+ return "glIsEnabled";
+ case EntryPoint::GLIsEnabledi:
+ return "glIsEnabledi";
+ case EntryPoint::GLIsEnablediEXT:
+ return "glIsEnablediEXT";
+ case EntryPoint::GLIsEnablediOES:
+ return "glIsEnablediOES";
+ case EntryPoint::GLIsFenceNV:
+ return "glIsFenceNV";
+ case EntryPoint::GLIsFramebuffer:
+ return "glIsFramebuffer";
+ case EntryPoint::GLIsFramebufferOES:
+ return "glIsFramebufferOES";
+ case EntryPoint::GLIsList:
+ return "glIsList";
+ case EntryPoint::GLIsMemoryObjectEXT:
+ return "glIsMemoryObjectEXT";
+ case EntryPoint::GLIsProgram:
+ return "glIsProgram";
+ case EntryPoint::GLIsProgramPipeline:
+ return "glIsProgramPipeline";
+ case EntryPoint::GLIsProgramPipelineEXT:
+ return "glIsProgramPipelineEXT";
+ case EntryPoint::GLIsQuery:
+ return "glIsQuery";
+ case EntryPoint::GLIsQueryEXT:
+ return "glIsQueryEXT";
+ case EntryPoint::GLIsRenderbuffer:
+ return "glIsRenderbuffer";
+ case EntryPoint::GLIsRenderbufferOES:
+ return "glIsRenderbufferOES";
+ case EntryPoint::GLIsSampler:
+ return "glIsSampler";
+ case EntryPoint::GLIsSemaphoreEXT:
+ return "glIsSemaphoreEXT";
+ case EntryPoint::GLIsShader:
+ return "glIsShader";
+ case EntryPoint::GLIsSync:
+ return "glIsSync";
+ case EntryPoint::GLIsTexture:
+ return "glIsTexture";
+ case EntryPoint::GLIsTransformFeedback:
+ return "glIsTransformFeedback";
+ case EntryPoint::GLIsVertexArray:
+ return "glIsVertexArray";
+ case EntryPoint::GLIsVertexArrayOES:
+ return "glIsVertexArrayOES";
+ case EntryPoint::GLLabelObjectEXT:
+ return "glLabelObjectEXT";
+ case EntryPoint::GLLightModelf:
+ return "glLightModelf";
+ case EntryPoint::GLLightModelfv:
+ return "glLightModelfv";
+ case EntryPoint::GLLightModeli:
+ return "glLightModeli";
+ case EntryPoint::GLLightModeliv:
+ return "glLightModeliv";
+ case EntryPoint::GLLightModelx:
+ return "glLightModelx";
+ case EntryPoint::GLLightModelxv:
+ return "glLightModelxv";
+ case EntryPoint::GLLightf:
+ return "glLightf";
+ case EntryPoint::GLLightfv:
+ return "glLightfv";
+ case EntryPoint::GLLighti:
+ return "glLighti";
+ case EntryPoint::GLLightiv:
+ return "glLightiv";
+ case EntryPoint::GLLightx:
+ return "glLightx";
+ case EntryPoint::GLLightxv:
+ return "glLightxv";
+ case EntryPoint::GLLineStipple:
+ return "glLineStipple";
+ case EntryPoint::GLLineWidth:
+ return "glLineWidth";
+ case EntryPoint::GLLineWidthx:
+ return "glLineWidthx";
+ case EntryPoint::GLLinkProgram:
+ return "glLinkProgram";
+ case EntryPoint::GLListBase:
+ return "glListBase";
+ case EntryPoint::GLLoadIdentity:
+ return "glLoadIdentity";
+ case EntryPoint::GLLoadMatrixd:
+ return "glLoadMatrixd";
+ case EntryPoint::GLLoadMatrixf:
+ return "glLoadMatrixf";
+ case EntryPoint::GLLoadMatrixx:
+ return "glLoadMatrixx";
+ case EntryPoint::GLLoadName:
+ return "glLoadName";
+ case EntryPoint::GLLoadPaletteFromModelViewMatrixOES:
+ return "glLoadPaletteFromModelViewMatrixOES";
+ case EntryPoint::GLLoadTransposeMatrixd:
+ return "glLoadTransposeMatrixd";
+ case EntryPoint::GLLoadTransposeMatrixf:
+ return "glLoadTransposeMatrixf";
+ case EntryPoint::GLLogicOp:
+ return "glLogicOp";
+ case EntryPoint::GLLogicOpANGLE:
+ return "glLogicOpANGLE";
+ case EntryPoint::GLLoseContextCHROMIUM:
+ return "glLoseContextCHROMIUM";
+ case EntryPoint::GLMap1d:
+ return "glMap1d";
+ case EntryPoint::GLMap1f:
+ return "glMap1f";
+ case EntryPoint::GLMap2d:
+ return "glMap2d";
+ case EntryPoint::GLMap2f:
+ return "glMap2f";
+ case EntryPoint::GLMapBuffer:
+ return "glMapBuffer";
+ case EntryPoint::GLMapBufferOES:
+ return "glMapBufferOES";
+ case EntryPoint::GLMapBufferRange:
+ return "glMapBufferRange";
+ case EntryPoint::GLMapBufferRangeEXT:
+ return "glMapBufferRangeEXT";
+ case EntryPoint::GLMapGrid1d:
+ return "glMapGrid1d";
+ case EntryPoint::GLMapGrid1f:
+ return "glMapGrid1f";
+ case EntryPoint::GLMapGrid2d:
+ return "glMapGrid2d";
+ case EntryPoint::GLMapGrid2f:
+ return "glMapGrid2f";
+ case EntryPoint::GLMapNamedBuffer:
+ return "glMapNamedBuffer";
+ case EntryPoint::GLMapNamedBufferRange:
+ return "glMapNamedBufferRange";
+ case EntryPoint::GLMaterialf:
+ return "glMaterialf";
+ case EntryPoint::GLMaterialfv:
+ return "glMaterialfv";
+ case EntryPoint::GLMateriali:
+ return "glMateriali";
+ case EntryPoint::GLMaterialiv:
+ return "glMaterialiv";
+ case EntryPoint::GLMaterialx:
+ return "glMaterialx";
+ case EntryPoint::GLMaterialxv:
+ return "glMaterialxv";
+ case EntryPoint::GLMatrixIndexPointerOES:
+ return "glMatrixIndexPointerOES";
+ case EntryPoint::GLMatrixMode:
+ return "glMatrixMode";
+ case EntryPoint::GLMaxShaderCompilerThreadsKHR:
+ return "glMaxShaderCompilerThreadsKHR";
+ case EntryPoint::GLMemoryBarrier:
+ return "glMemoryBarrier";
+ case EntryPoint::GLMemoryBarrierByRegion:
+ return "glMemoryBarrierByRegion";
+ case EntryPoint::GLMemoryObjectParameterivEXT:
+ return "glMemoryObjectParameterivEXT";
+ case EntryPoint::GLMinSampleShading:
+ return "glMinSampleShading";
+ case EntryPoint::GLMinSampleShadingOES:
+ return "glMinSampleShadingOES";
+ case EntryPoint::GLMultMatrixd:
+ return "glMultMatrixd";
+ case EntryPoint::GLMultMatrixf:
+ return "glMultMatrixf";
+ case EntryPoint::GLMultMatrixx:
+ return "glMultMatrixx";
+ case EntryPoint::GLMultTransposeMatrixd:
+ return "glMultTransposeMatrixd";
+ case EntryPoint::GLMultTransposeMatrixf:
+ return "glMultTransposeMatrixf";
+ case EntryPoint::GLMultiDrawArrays:
+ return "glMultiDrawArrays";
+ case EntryPoint::GLMultiDrawArraysANGLE:
+ return "glMultiDrawArraysANGLE";
+ case EntryPoint::GLMultiDrawArraysIndirect:
+ return "glMultiDrawArraysIndirect";
+ case EntryPoint::GLMultiDrawArraysIndirectCount:
+ return "glMultiDrawArraysIndirectCount";
+ case EntryPoint::GLMultiDrawArraysIndirectEXT:
+ return "glMultiDrawArraysIndirectEXT";
+ case EntryPoint::GLMultiDrawArraysInstancedANGLE:
+ return "glMultiDrawArraysInstancedANGLE";
+ case EntryPoint::GLMultiDrawArraysInstancedBaseInstanceANGLE:
+ return "glMultiDrawArraysInstancedBaseInstanceANGLE";
+ case EntryPoint::GLMultiDrawElements:
+ return "glMultiDrawElements";
+ case EntryPoint::GLMultiDrawElementsANGLE:
+ return "glMultiDrawElementsANGLE";
+ case EntryPoint::GLMultiDrawElementsBaseVertex:
+ return "glMultiDrawElementsBaseVertex";
+ case EntryPoint::GLMultiDrawElementsBaseVertexEXT:
+ return "glMultiDrawElementsBaseVertexEXT";
+ case EntryPoint::GLMultiDrawElementsIndirect:
+ return "glMultiDrawElementsIndirect";
+ case EntryPoint::GLMultiDrawElementsIndirectCount:
+ return "glMultiDrawElementsIndirectCount";
+ case EntryPoint::GLMultiDrawElementsIndirectEXT:
+ return "glMultiDrawElementsIndirectEXT";
+ case EntryPoint::GLMultiDrawElementsInstancedANGLE:
+ return "glMultiDrawElementsInstancedANGLE";
+ case EntryPoint::GLMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE:
+ return "glMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE";
+ case EntryPoint::GLMultiTexCoord1d:
+ return "glMultiTexCoord1d";
+ case EntryPoint::GLMultiTexCoord1dv:
+ return "glMultiTexCoord1dv";
+ case EntryPoint::GLMultiTexCoord1f:
+ return "glMultiTexCoord1f";
+ case EntryPoint::GLMultiTexCoord1fv:
+ return "glMultiTexCoord1fv";
+ case EntryPoint::GLMultiTexCoord1i:
+ return "glMultiTexCoord1i";
+ case EntryPoint::GLMultiTexCoord1iv:
+ return "glMultiTexCoord1iv";
+ case EntryPoint::GLMultiTexCoord1s:
+ return "glMultiTexCoord1s";
+ case EntryPoint::GLMultiTexCoord1sv:
+ return "glMultiTexCoord1sv";
+ case EntryPoint::GLMultiTexCoord2d:
+ return "glMultiTexCoord2d";
+ case EntryPoint::GLMultiTexCoord2dv:
+ return "glMultiTexCoord2dv";
+ case EntryPoint::GLMultiTexCoord2f:
+ return "glMultiTexCoord2f";
+ case EntryPoint::GLMultiTexCoord2fv:
+ return "glMultiTexCoord2fv";
+ case EntryPoint::GLMultiTexCoord2i:
+ return "glMultiTexCoord2i";
+ case EntryPoint::GLMultiTexCoord2iv:
+ return "glMultiTexCoord2iv";
+ case EntryPoint::GLMultiTexCoord2s:
+ return "glMultiTexCoord2s";
+ case EntryPoint::GLMultiTexCoord2sv:
+ return "glMultiTexCoord2sv";
+ case EntryPoint::GLMultiTexCoord3d:
+ return "glMultiTexCoord3d";
+ case EntryPoint::GLMultiTexCoord3dv:
+ return "glMultiTexCoord3dv";
+ case EntryPoint::GLMultiTexCoord3f:
+ return "glMultiTexCoord3f";
+ case EntryPoint::GLMultiTexCoord3fv:
+ return "glMultiTexCoord3fv";
+ case EntryPoint::GLMultiTexCoord3i:
+ return "glMultiTexCoord3i";
+ case EntryPoint::GLMultiTexCoord3iv:
+ return "glMultiTexCoord3iv";
+ case EntryPoint::GLMultiTexCoord3s:
+ return "glMultiTexCoord3s";
+ case EntryPoint::GLMultiTexCoord3sv:
+ return "glMultiTexCoord3sv";
+ case EntryPoint::GLMultiTexCoord4d:
+ return "glMultiTexCoord4d";
+ case EntryPoint::GLMultiTexCoord4dv:
+ return "glMultiTexCoord4dv";
+ case EntryPoint::GLMultiTexCoord4f:
+ return "glMultiTexCoord4f";
+ case EntryPoint::GLMultiTexCoord4fv:
+ return "glMultiTexCoord4fv";
+ case EntryPoint::GLMultiTexCoord4i:
+ return "glMultiTexCoord4i";
+ case EntryPoint::GLMultiTexCoord4iv:
+ return "glMultiTexCoord4iv";
+ case EntryPoint::GLMultiTexCoord4s:
+ return "glMultiTexCoord4s";
+ case EntryPoint::GLMultiTexCoord4sv:
+ return "glMultiTexCoord4sv";
+ case EntryPoint::GLMultiTexCoord4x:
+ return "glMultiTexCoord4x";
+ case EntryPoint::GLMultiTexCoordP1ui:
+ return "glMultiTexCoordP1ui";
+ case EntryPoint::GLMultiTexCoordP1uiv:
+ return "glMultiTexCoordP1uiv";
+ case EntryPoint::GLMultiTexCoordP2ui:
+ return "glMultiTexCoordP2ui";
+ case EntryPoint::GLMultiTexCoordP2uiv:
+ return "glMultiTexCoordP2uiv";
+ case EntryPoint::GLMultiTexCoordP3ui:
+ return "glMultiTexCoordP3ui";
+ case EntryPoint::GLMultiTexCoordP3uiv:
+ return "glMultiTexCoordP3uiv";
+ case EntryPoint::GLMultiTexCoordP4ui:
+ return "glMultiTexCoordP4ui";
+ case EntryPoint::GLMultiTexCoordP4uiv:
+ return "glMultiTexCoordP4uiv";
+ case EntryPoint::GLNamedBufferData:
+ return "glNamedBufferData";
+ case EntryPoint::GLNamedBufferStorage:
+ return "glNamedBufferStorage";
+ case EntryPoint::GLNamedBufferStorageExternalEXT:
+ return "glNamedBufferStorageExternalEXT";
+ case EntryPoint::GLNamedBufferSubData:
+ return "glNamedBufferSubData";
+ case EntryPoint::GLNamedFramebufferDrawBuffer:
+ return "glNamedFramebufferDrawBuffer";
+ case EntryPoint::GLNamedFramebufferDrawBuffers:
+ return "glNamedFramebufferDrawBuffers";
+ case EntryPoint::GLNamedFramebufferParameteri:
+ return "glNamedFramebufferParameteri";
+ case EntryPoint::GLNamedFramebufferReadBuffer:
+ return "glNamedFramebufferReadBuffer";
+ case EntryPoint::GLNamedFramebufferRenderbuffer:
+ return "glNamedFramebufferRenderbuffer";
+ case EntryPoint::GLNamedFramebufferTexture:
+ return "glNamedFramebufferTexture";
+ case EntryPoint::GLNamedFramebufferTextureLayer:
+ return "glNamedFramebufferTextureLayer";
+ case EntryPoint::GLNamedRenderbufferStorage:
+ return "glNamedRenderbufferStorage";
+ case EntryPoint::GLNamedRenderbufferStorageMultisample:
+ return "glNamedRenderbufferStorageMultisample";
+ case EntryPoint::GLNewList:
+ return "glNewList";
+ case EntryPoint::GLNormal3b:
+ return "glNormal3b";
+ case EntryPoint::GLNormal3bv:
+ return "glNormal3bv";
+ case EntryPoint::GLNormal3d:
+ return "glNormal3d";
+ case EntryPoint::GLNormal3dv:
+ return "glNormal3dv";
+ case EntryPoint::GLNormal3f:
+ return "glNormal3f";
+ case EntryPoint::GLNormal3fv:
+ return "glNormal3fv";
+ case EntryPoint::GLNormal3i:
+ return "glNormal3i";
+ case EntryPoint::GLNormal3iv:
+ return "glNormal3iv";
+ case EntryPoint::GLNormal3s:
+ return "glNormal3s";
+ case EntryPoint::GLNormal3sv:
+ return "glNormal3sv";
+ case EntryPoint::GLNormal3x:
+ return "glNormal3x";
+ case EntryPoint::GLNormalP3ui:
+ return "glNormalP3ui";
+ case EntryPoint::GLNormalP3uiv:
+ return "glNormalP3uiv";
+ case EntryPoint::GLNormalPointer:
+ return "glNormalPointer";
+ case EntryPoint::GLObjectLabel:
+ return "glObjectLabel";
+ case EntryPoint::GLObjectLabelKHR:
+ return "glObjectLabelKHR";
+ case EntryPoint::GLObjectPtrLabel:
+ return "glObjectPtrLabel";
+ case EntryPoint::GLObjectPtrLabelKHR:
+ return "glObjectPtrLabelKHR";
+ case EntryPoint::GLOrtho:
+ return "glOrtho";
+ case EntryPoint::GLOrthof:
+ return "glOrthof";
+ case EntryPoint::GLOrthox:
+ return "glOrthox";
+ case EntryPoint::GLPassThrough:
+ return "glPassThrough";
+ case EntryPoint::GLPatchParameterfv:
+ return "glPatchParameterfv";
+ case EntryPoint::GLPatchParameteri:
+ return "glPatchParameteri";
+ case EntryPoint::GLPatchParameteriEXT:
+ return "glPatchParameteriEXT";
+ case EntryPoint::GLPauseTransformFeedback:
+ return "glPauseTransformFeedback";
+ case EntryPoint::GLPixelLocalStorageBarrierANGLE:
+ return "glPixelLocalStorageBarrierANGLE";
+ case EntryPoint::GLPixelMapfv:
+ return "glPixelMapfv";
+ case EntryPoint::GLPixelMapuiv:
+ return "glPixelMapuiv";
+ case EntryPoint::GLPixelMapusv:
+ return "glPixelMapusv";
+ case EntryPoint::GLPixelStoref:
+ return "glPixelStoref";
+ case EntryPoint::GLPixelStorei:
+ return "glPixelStorei";
+ case EntryPoint::GLPixelTransferf:
+ return "glPixelTransferf";
+ case EntryPoint::GLPixelTransferi:
+ return "glPixelTransferi";
+ case EntryPoint::GLPixelZoom:
+ return "glPixelZoom";
+ case EntryPoint::GLPointParameterf:
+ return "glPointParameterf";
+ case EntryPoint::GLPointParameterfv:
+ return "glPointParameterfv";
+ case EntryPoint::GLPointParameteri:
+ return "glPointParameteri";
+ case EntryPoint::GLPointParameteriv:
+ return "glPointParameteriv";
+ case EntryPoint::GLPointParameterx:
+ return "glPointParameterx";
+ case EntryPoint::GLPointParameterxv:
+ return "glPointParameterxv";
+ case EntryPoint::GLPointSize:
+ return "glPointSize";
+ case EntryPoint::GLPointSizePointerOES:
+ return "glPointSizePointerOES";
+ case EntryPoint::GLPointSizex:
+ return "glPointSizex";
+ case EntryPoint::GLPolygonMode:
+ return "glPolygonMode";
+ case EntryPoint::GLPolygonOffset:
+ return "glPolygonOffset";
+ case EntryPoint::GLPolygonOffsetClamp:
+ return "glPolygonOffsetClamp";
+ case EntryPoint::GLPolygonOffsetx:
+ return "glPolygonOffsetx";
+ case EntryPoint::GLPolygonStipple:
+ return "glPolygonStipple";
+ case EntryPoint::GLPopAttrib:
+ return "glPopAttrib";
+ case EntryPoint::GLPopClientAttrib:
+ return "glPopClientAttrib";
+ case EntryPoint::GLPopDebugGroup:
+ return "glPopDebugGroup";
+ case EntryPoint::GLPopDebugGroupKHR:
+ return "glPopDebugGroupKHR";
+ case EntryPoint::GLPopGroupMarkerEXT:
+ return "glPopGroupMarkerEXT";
+ case EntryPoint::GLPopMatrix:
+ return "glPopMatrix";
+ case EntryPoint::GLPopName:
+ return "glPopName";
+ case EntryPoint::GLPrimitiveBoundingBox:
+ return "glPrimitiveBoundingBox";
+ case EntryPoint::GLPrimitiveBoundingBoxEXT:
+ return "glPrimitiveBoundingBoxEXT";
+ case EntryPoint::GLPrimitiveBoundingBoxOES:
+ return "glPrimitiveBoundingBoxOES";
+ case EntryPoint::GLPrimitiveRestartIndex:
+ return "glPrimitiveRestartIndex";
+ case EntryPoint::GLPrioritizeTextures:
+ return "glPrioritizeTextures";
+ case EntryPoint::GLProgramBinary:
+ return "glProgramBinary";
+ case EntryPoint::GLProgramBinaryOES:
+ return "glProgramBinaryOES";
+ case EntryPoint::GLProgramParameteri:
+ return "glProgramParameteri";
+ case EntryPoint::GLProgramParameteriEXT:
+ return "glProgramParameteriEXT";
+ case EntryPoint::GLProgramUniform1d:
+ return "glProgramUniform1d";
+ case EntryPoint::GLProgramUniform1dv:
+ return "glProgramUniform1dv";
+ case EntryPoint::GLProgramUniform1f:
+ return "glProgramUniform1f";
+ case EntryPoint::GLProgramUniform1fEXT:
+ return "glProgramUniform1fEXT";
+ case EntryPoint::GLProgramUniform1fv:
+ return "glProgramUniform1fv";
+ case EntryPoint::GLProgramUniform1fvEXT:
+ return "glProgramUniform1fvEXT";
+ case EntryPoint::GLProgramUniform1i:
+ return "glProgramUniform1i";
+ case EntryPoint::GLProgramUniform1iEXT:
+ return "glProgramUniform1iEXT";
+ case EntryPoint::GLProgramUniform1iv:
+ return "glProgramUniform1iv";
+ case EntryPoint::GLProgramUniform1ivEXT:
+ return "glProgramUniform1ivEXT";
+ case EntryPoint::GLProgramUniform1ui:
+ return "glProgramUniform1ui";
+ case EntryPoint::GLProgramUniform1uiEXT:
+ return "glProgramUniform1uiEXT";
+ case EntryPoint::GLProgramUniform1uiv:
+ return "glProgramUniform1uiv";
+ case EntryPoint::GLProgramUniform1uivEXT:
+ return "glProgramUniform1uivEXT";
+ case EntryPoint::GLProgramUniform2d:
+ return "glProgramUniform2d";
+ case EntryPoint::GLProgramUniform2dv:
+ return "glProgramUniform2dv";
+ case EntryPoint::GLProgramUniform2f:
+ return "glProgramUniform2f";
+ case EntryPoint::GLProgramUniform2fEXT:
+ return "glProgramUniform2fEXT";
+ case EntryPoint::GLProgramUniform2fv:
+ return "glProgramUniform2fv";
+ case EntryPoint::GLProgramUniform2fvEXT:
+ return "glProgramUniform2fvEXT";
+ case EntryPoint::GLProgramUniform2i:
+ return "glProgramUniform2i";
+ case EntryPoint::GLProgramUniform2iEXT:
+ return "glProgramUniform2iEXT";
+ case EntryPoint::GLProgramUniform2iv:
+ return "glProgramUniform2iv";
+ case EntryPoint::GLProgramUniform2ivEXT:
+ return "glProgramUniform2ivEXT";
+ case EntryPoint::GLProgramUniform2ui:
+ return "glProgramUniform2ui";
+ case EntryPoint::GLProgramUniform2uiEXT:
+ return "glProgramUniform2uiEXT";
+ case EntryPoint::GLProgramUniform2uiv:
+ return "glProgramUniform2uiv";
+ case EntryPoint::GLProgramUniform2uivEXT:
+ return "glProgramUniform2uivEXT";
+ case EntryPoint::GLProgramUniform3d:
+ return "glProgramUniform3d";
+ case EntryPoint::GLProgramUniform3dv:
+ return "glProgramUniform3dv";
+ case EntryPoint::GLProgramUniform3f:
+ return "glProgramUniform3f";
+ case EntryPoint::GLProgramUniform3fEXT:
+ return "glProgramUniform3fEXT";
+ case EntryPoint::GLProgramUniform3fv:
+ return "glProgramUniform3fv";
+ case EntryPoint::GLProgramUniform3fvEXT:
+ return "glProgramUniform3fvEXT";
+ case EntryPoint::GLProgramUniform3i:
+ return "glProgramUniform3i";
+ case EntryPoint::GLProgramUniform3iEXT:
+ return "glProgramUniform3iEXT";
+ case EntryPoint::GLProgramUniform3iv:
+ return "glProgramUniform3iv";
+ case EntryPoint::GLProgramUniform3ivEXT:
+ return "glProgramUniform3ivEXT";
+ case EntryPoint::GLProgramUniform3ui:
+ return "glProgramUniform3ui";
+ case EntryPoint::GLProgramUniform3uiEXT:
+ return "glProgramUniform3uiEXT";
+ case EntryPoint::GLProgramUniform3uiv:
+ return "glProgramUniform3uiv";
+ case EntryPoint::GLProgramUniform3uivEXT:
+ return "glProgramUniform3uivEXT";
+ case EntryPoint::GLProgramUniform4d:
+ return "glProgramUniform4d";
+ case EntryPoint::GLProgramUniform4dv:
+ return "glProgramUniform4dv";
+ case EntryPoint::GLProgramUniform4f:
+ return "glProgramUniform4f";
+ case EntryPoint::GLProgramUniform4fEXT:
+ return "glProgramUniform4fEXT";
+ case EntryPoint::GLProgramUniform4fv:
+ return "glProgramUniform4fv";
+ case EntryPoint::GLProgramUniform4fvEXT:
+ return "glProgramUniform4fvEXT";
+ case EntryPoint::GLProgramUniform4i:
+ return "glProgramUniform4i";
+ case EntryPoint::GLProgramUniform4iEXT:
+ return "glProgramUniform4iEXT";
+ case EntryPoint::GLProgramUniform4iv:
+ return "glProgramUniform4iv";
+ case EntryPoint::GLProgramUniform4ivEXT:
+ return "glProgramUniform4ivEXT";
+ case EntryPoint::GLProgramUniform4ui:
+ return "glProgramUniform4ui";
+ case EntryPoint::GLProgramUniform4uiEXT:
+ return "glProgramUniform4uiEXT";
+ case EntryPoint::GLProgramUniform4uiv:
+ return "glProgramUniform4uiv";
+ case EntryPoint::GLProgramUniform4uivEXT:
+ return "glProgramUniform4uivEXT";
+ case EntryPoint::GLProgramUniformMatrix2dv:
+ return "glProgramUniformMatrix2dv";
+ case EntryPoint::GLProgramUniformMatrix2fv:
+ return "glProgramUniformMatrix2fv";
+ case EntryPoint::GLProgramUniformMatrix2fvEXT:
+ return "glProgramUniformMatrix2fvEXT";
+ case EntryPoint::GLProgramUniformMatrix2x3dv:
+ return "glProgramUniformMatrix2x3dv";
+ case EntryPoint::GLProgramUniformMatrix2x3fv:
+ return "glProgramUniformMatrix2x3fv";
+ case EntryPoint::GLProgramUniformMatrix2x3fvEXT:
+ return "glProgramUniformMatrix2x3fvEXT";
+ case EntryPoint::GLProgramUniformMatrix2x4dv:
+ return "glProgramUniformMatrix2x4dv";
+ case EntryPoint::GLProgramUniformMatrix2x4fv:
+ return "glProgramUniformMatrix2x4fv";
+ case EntryPoint::GLProgramUniformMatrix2x4fvEXT:
+ return "glProgramUniformMatrix2x4fvEXT";
+ case EntryPoint::GLProgramUniformMatrix3dv:
+ return "glProgramUniformMatrix3dv";
+ case EntryPoint::GLProgramUniformMatrix3fv:
+ return "glProgramUniformMatrix3fv";
+ case EntryPoint::GLProgramUniformMatrix3fvEXT:
+ return "glProgramUniformMatrix3fvEXT";
+ case EntryPoint::GLProgramUniformMatrix3x2dv:
+ return "glProgramUniformMatrix3x2dv";
+ case EntryPoint::GLProgramUniformMatrix3x2fv:
+ return "glProgramUniformMatrix3x2fv";
+ case EntryPoint::GLProgramUniformMatrix3x2fvEXT:
+ return "glProgramUniformMatrix3x2fvEXT";
+ case EntryPoint::GLProgramUniformMatrix3x4dv:
+ return "glProgramUniformMatrix3x4dv";
+ case EntryPoint::GLProgramUniformMatrix3x4fv:
+ return "glProgramUniformMatrix3x4fv";
+ case EntryPoint::GLProgramUniformMatrix3x4fvEXT:
+ return "glProgramUniformMatrix3x4fvEXT";
+ case EntryPoint::GLProgramUniformMatrix4dv:
+ return "glProgramUniformMatrix4dv";
+ case EntryPoint::GLProgramUniformMatrix4fv:
+ return "glProgramUniformMatrix4fv";
+ case EntryPoint::GLProgramUniformMatrix4fvEXT:
+ return "glProgramUniformMatrix4fvEXT";
+ case EntryPoint::GLProgramUniformMatrix4x2dv:
+ return "glProgramUniformMatrix4x2dv";
+ case EntryPoint::GLProgramUniformMatrix4x2fv:
+ return "glProgramUniformMatrix4x2fv";
+ case EntryPoint::GLProgramUniformMatrix4x2fvEXT:
+ return "glProgramUniformMatrix4x2fvEXT";
+ case EntryPoint::GLProgramUniformMatrix4x3dv:
+ return "glProgramUniformMatrix4x3dv";
+ case EntryPoint::GLProgramUniformMatrix4x3fv:
+ return "glProgramUniformMatrix4x3fv";
+ case EntryPoint::GLProgramUniformMatrix4x3fvEXT:
+ return "glProgramUniformMatrix4x3fvEXT";
+ case EntryPoint::GLProvokingVertex:
+ return "glProvokingVertex";
+ case EntryPoint::GLProvokingVertexANGLE:
+ return "glProvokingVertexANGLE";
+ case EntryPoint::GLPushAttrib:
+ return "glPushAttrib";
+ case EntryPoint::GLPushClientAttrib:
+ return "glPushClientAttrib";
+ case EntryPoint::GLPushDebugGroup:
+ return "glPushDebugGroup";
+ case EntryPoint::GLPushDebugGroupKHR:
+ return "glPushDebugGroupKHR";
+ case EntryPoint::GLPushGroupMarkerEXT:
+ return "glPushGroupMarkerEXT";
+ case EntryPoint::GLPushMatrix:
+ return "glPushMatrix";
+ case EntryPoint::GLPushName:
+ return "glPushName";
+ case EntryPoint::GLQueryCounter:
+ return "glQueryCounter";
+ case EntryPoint::GLQueryCounterEXT:
+ return "glQueryCounterEXT";
+ case EntryPoint::GLQueryMatrixxOES:
+ return "glQueryMatrixxOES";
+ case EntryPoint::GLRasterPos2d:
+ return "glRasterPos2d";
+ case EntryPoint::GLRasterPos2dv:
+ return "glRasterPos2dv";
+ case EntryPoint::GLRasterPos2f:
+ return "glRasterPos2f";
+ case EntryPoint::GLRasterPos2fv:
+ return "glRasterPos2fv";
+ case EntryPoint::GLRasterPos2i:
+ return "glRasterPos2i";
+ case EntryPoint::GLRasterPos2iv:
+ return "glRasterPos2iv";
+ case EntryPoint::GLRasterPos2s:
+ return "glRasterPos2s";
+ case EntryPoint::GLRasterPos2sv:
+ return "glRasterPos2sv";
+ case EntryPoint::GLRasterPos3d:
+ return "glRasterPos3d";
+ case EntryPoint::GLRasterPos3dv:
+ return "glRasterPos3dv";
+ case EntryPoint::GLRasterPos3f:
+ return "glRasterPos3f";
+ case EntryPoint::GLRasterPos3fv:
+ return "glRasterPos3fv";
+ case EntryPoint::GLRasterPos3i:
+ return "glRasterPos3i";
+ case EntryPoint::GLRasterPos3iv:
+ return "glRasterPos3iv";
+ case EntryPoint::GLRasterPos3s:
+ return "glRasterPos3s";
+ case EntryPoint::GLRasterPos3sv:
+ return "glRasterPos3sv";
+ case EntryPoint::GLRasterPos4d:
+ return "glRasterPos4d";
+ case EntryPoint::GLRasterPos4dv:
+ return "glRasterPos4dv";
+ case EntryPoint::GLRasterPos4f:
+ return "glRasterPos4f";
+ case EntryPoint::GLRasterPos4fv:
+ return "glRasterPos4fv";
+ case EntryPoint::GLRasterPos4i:
+ return "glRasterPos4i";
+ case EntryPoint::GLRasterPos4iv:
+ return "glRasterPos4iv";
+ case EntryPoint::GLRasterPos4s:
+ return "glRasterPos4s";
+ case EntryPoint::GLRasterPos4sv:
+ return "glRasterPos4sv";
+ case EntryPoint::GLReadBuffer:
+ return "glReadBuffer";
+ case EntryPoint::GLReadPixels:
+ return "glReadPixels";
+ case EntryPoint::GLReadPixelsRobustANGLE:
+ return "glReadPixelsRobustANGLE";
+ case EntryPoint::GLReadnPixels:
+ return "glReadnPixels";
+ case EntryPoint::GLReadnPixelsEXT:
+ return "glReadnPixelsEXT";
+ case EntryPoint::GLReadnPixelsRobustANGLE:
+ return "glReadnPixelsRobustANGLE";
+ case EntryPoint::GLRectd:
+ return "glRectd";
+ case EntryPoint::GLRectdv:
+ return "glRectdv";
+ case EntryPoint::GLRectf:
+ return "glRectf";
+ case EntryPoint::GLRectfv:
+ return "glRectfv";
+ case EntryPoint::GLRecti:
+ return "glRecti";
+ case EntryPoint::GLRectiv:
+ return "glRectiv";
+ case EntryPoint::GLRects:
+ return "glRects";
+ case EntryPoint::GLRectsv:
+ return "glRectsv";
+ case EntryPoint::GLReleaseShaderCompiler:
+ return "glReleaseShaderCompiler";
+ case EntryPoint::GLReleaseTexturesANGLE:
+ return "glReleaseTexturesANGLE";
+ case EntryPoint::GLRenderMode:
+ return "glRenderMode";
+ case EntryPoint::GLRenderbufferStorage:
+ return "glRenderbufferStorage";
+ case EntryPoint::GLRenderbufferStorageMultisample:
+ return "glRenderbufferStorageMultisample";
+ case EntryPoint::GLRenderbufferStorageMultisampleANGLE:
+ return "glRenderbufferStorageMultisampleANGLE";
+ case EntryPoint::GLRenderbufferStorageMultisampleEXT:
+ return "glRenderbufferStorageMultisampleEXT";
+ case EntryPoint::GLRenderbufferStorageOES:
+ return "glRenderbufferStorageOES";
+ case EntryPoint::GLRequestExtensionANGLE:
+ return "glRequestExtensionANGLE";
+ case EntryPoint::GLResumeTransformFeedback:
+ return "glResumeTransformFeedback";
+ case EntryPoint::GLRotated:
+ return "glRotated";
+ case EntryPoint::GLRotatef:
+ return "glRotatef";
+ case EntryPoint::GLRotatex:
+ return "glRotatex";
+ case EntryPoint::GLSampleCoverage:
+ return "glSampleCoverage";
+ case EntryPoint::GLSampleCoveragex:
+ return "glSampleCoveragex";
+ case EntryPoint::GLSampleMaski:
+ return "glSampleMaski";
+ case EntryPoint::GLSampleMaskiANGLE:
+ return "glSampleMaskiANGLE";
+ case EntryPoint::GLSamplerParameterIiv:
+ return "glSamplerParameterIiv";
+ case EntryPoint::GLSamplerParameterIivEXT:
+ return "glSamplerParameterIivEXT";
+ case EntryPoint::GLSamplerParameterIivOES:
+ return "glSamplerParameterIivOES";
+ case EntryPoint::GLSamplerParameterIivRobustANGLE:
+ return "glSamplerParameterIivRobustANGLE";
+ case EntryPoint::GLSamplerParameterIuiv:
+ return "glSamplerParameterIuiv";
+ case EntryPoint::GLSamplerParameterIuivEXT:
+ return "glSamplerParameterIuivEXT";
+ case EntryPoint::GLSamplerParameterIuivOES:
+ return "glSamplerParameterIuivOES";
+ case EntryPoint::GLSamplerParameterIuivRobustANGLE:
+ return "glSamplerParameterIuivRobustANGLE";
+ case EntryPoint::GLSamplerParameterf:
+ return "glSamplerParameterf";
+ case EntryPoint::GLSamplerParameterfv:
+ return "glSamplerParameterfv";
+ case EntryPoint::GLSamplerParameterfvRobustANGLE:
+ return "glSamplerParameterfvRobustANGLE";
+ case EntryPoint::GLSamplerParameteri:
+ return "glSamplerParameteri";
+ case EntryPoint::GLSamplerParameteriv:
+ return "glSamplerParameteriv";
+ case EntryPoint::GLSamplerParameterivRobustANGLE:
+ return "glSamplerParameterivRobustANGLE";
+ case EntryPoint::GLScaled:
+ return "glScaled";
+ case EntryPoint::GLScalef:
+ return "glScalef";
+ case EntryPoint::GLScalex:
+ return "glScalex";
+ case EntryPoint::GLScissor:
+ return "glScissor";
+ case EntryPoint::GLScissorArrayv:
+ return "glScissorArrayv";
+ case EntryPoint::GLScissorIndexed:
+ return "glScissorIndexed";
+ case EntryPoint::GLScissorIndexedv:
+ return "glScissorIndexedv";
+ case EntryPoint::GLSecondaryColor3b:
+ return "glSecondaryColor3b";
+ case EntryPoint::GLSecondaryColor3bv:
+ return "glSecondaryColor3bv";
+ case EntryPoint::GLSecondaryColor3d:
+ return "glSecondaryColor3d";
+ case EntryPoint::GLSecondaryColor3dv:
+ return "glSecondaryColor3dv";
+ case EntryPoint::GLSecondaryColor3f:
+ return "glSecondaryColor3f";
+ case EntryPoint::GLSecondaryColor3fv:
+ return "glSecondaryColor3fv";
+ case EntryPoint::GLSecondaryColor3i:
+ return "glSecondaryColor3i";
+ case EntryPoint::GLSecondaryColor3iv:
+ return "glSecondaryColor3iv";
+ case EntryPoint::GLSecondaryColor3s:
+ return "glSecondaryColor3s";
+ case EntryPoint::GLSecondaryColor3sv:
+ return "glSecondaryColor3sv";
+ case EntryPoint::GLSecondaryColor3ub:
+ return "glSecondaryColor3ub";
+ case EntryPoint::GLSecondaryColor3ubv:
+ return "glSecondaryColor3ubv";
+ case EntryPoint::GLSecondaryColor3ui:
+ return "glSecondaryColor3ui";
+ case EntryPoint::GLSecondaryColor3uiv:
+ return "glSecondaryColor3uiv";
+ case EntryPoint::GLSecondaryColor3us:
+ return "glSecondaryColor3us";
+ case EntryPoint::GLSecondaryColor3usv:
+ return "glSecondaryColor3usv";
+ case EntryPoint::GLSecondaryColorP3ui:
+ return "glSecondaryColorP3ui";
+ case EntryPoint::GLSecondaryColorP3uiv:
+ return "glSecondaryColorP3uiv";
+ case EntryPoint::GLSecondaryColorPointer:
+ return "glSecondaryColorPointer";
+ case EntryPoint::GLSelectBuffer:
+ return "glSelectBuffer";
+ case EntryPoint::GLSelectPerfMonitorCountersAMD:
+ return "glSelectPerfMonitorCountersAMD";
+ case EntryPoint::GLSemaphoreParameterui64vEXT:
+ return "glSemaphoreParameterui64vEXT";
+ case EntryPoint::GLSetFenceNV:
+ return "glSetFenceNV";
+ case EntryPoint::GLShadeModel:
+ return "glShadeModel";
+ case EntryPoint::GLShaderBinary:
+ return "glShaderBinary";
+ case EntryPoint::GLShaderSource:
+ return "glShaderSource";
+ case EntryPoint::GLShaderStorageBlockBinding:
+ return "glShaderStorageBlockBinding";
+ case EntryPoint::GLShadingRateQCOM:
+ return "glShadingRateQCOM";
+ case EntryPoint::GLSignalSemaphoreEXT:
+ return "glSignalSemaphoreEXT";
+ case EntryPoint::GLSpecializeShader:
+ return "glSpecializeShader";
+ case EntryPoint::GLStencilFunc:
+ return "glStencilFunc";
+ case EntryPoint::GLStencilFuncSeparate:
+ return "glStencilFuncSeparate";
+ case EntryPoint::GLStencilMask:
+ return "glStencilMask";
+ case EntryPoint::GLStencilMaskSeparate:
+ return "glStencilMaskSeparate";
+ case EntryPoint::GLStencilOp:
+ return "glStencilOp";
+ case EntryPoint::GLStencilOpSeparate:
+ return "glStencilOpSeparate";
+ case EntryPoint::GLTestFenceNV:
+ return "glTestFenceNV";
+ case EntryPoint::GLTexBuffer:
+ return "glTexBuffer";
+ case EntryPoint::GLTexBufferEXT:
+ return "glTexBufferEXT";
+ case EntryPoint::GLTexBufferOES:
+ return "glTexBufferOES";
+ case EntryPoint::GLTexBufferRange:
+ return "glTexBufferRange";
+ case EntryPoint::GLTexBufferRangeEXT:
+ return "glTexBufferRangeEXT";
+ case EntryPoint::GLTexBufferRangeOES:
+ return "glTexBufferRangeOES";
+ case EntryPoint::GLTexCoord1d:
+ return "glTexCoord1d";
+ case EntryPoint::GLTexCoord1dv:
+ return "glTexCoord1dv";
+ case EntryPoint::GLTexCoord1f:
+ return "glTexCoord1f";
+ case EntryPoint::GLTexCoord1fv:
+ return "glTexCoord1fv";
+ case EntryPoint::GLTexCoord1i:
+ return "glTexCoord1i";
+ case EntryPoint::GLTexCoord1iv:
+ return "glTexCoord1iv";
+ case EntryPoint::GLTexCoord1s:
+ return "glTexCoord1s";
+ case EntryPoint::GLTexCoord1sv:
+ return "glTexCoord1sv";
+ case EntryPoint::GLTexCoord2d:
+ return "glTexCoord2d";
+ case EntryPoint::GLTexCoord2dv:
+ return "glTexCoord2dv";
+ case EntryPoint::GLTexCoord2f:
+ return "glTexCoord2f";
+ case EntryPoint::GLTexCoord2fv:
+ return "glTexCoord2fv";
+ case EntryPoint::GLTexCoord2i:
+ return "glTexCoord2i";
+ case EntryPoint::GLTexCoord2iv:
+ return "glTexCoord2iv";
+ case EntryPoint::GLTexCoord2s:
+ return "glTexCoord2s";
+ case EntryPoint::GLTexCoord2sv:
+ return "glTexCoord2sv";
+ case EntryPoint::GLTexCoord3d:
+ return "glTexCoord3d";
+ case EntryPoint::GLTexCoord3dv:
+ return "glTexCoord3dv";
+ case EntryPoint::GLTexCoord3f:
+ return "glTexCoord3f";
+ case EntryPoint::GLTexCoord3fv:
+ return "glTexCoord3fv";
+ case EntryPoint::GLTexCoord3i:
+ return "glTexCoord3i";
+ case EntryPoint::GLTexCoord3iv:
+ return "glTexCoord3iv";
+ case EntryPoint::GLTexCoord3s:
+ return "glTexCoord3s";
+ case EntryPoint::GLTexCoord3sv:
+ return "glTexCoord3sv";
+ case EntryPoint::GLTexCoord4d:
+ return "glTexCoord4d";
+ case EntryPoint::GLTexCoord4dv:
+ return "glTexCoord4dv";
+ case EntryPoint::GLTexCoord4f:
+ return "glTexCoord4f";
+ case EntryPoint::GLTexCoord4fv:
+ return "glTexCoord4fv";
+ case EntryPoint::GLTexCoord4i:
+ return "glTexCoord4i";
+ case EntryPoint::GLTexCoord4iv:
+ return "glTexCoord4iv";
+ case EntryPoint::GLTexCoord4s:
+ return "glTexCoord4s";
+ case EntryPoint::GLTexCoord4sv:
+ return "glTexCoord4sv";
+ case EntryPoint::GLTexCoordP1ui:
+ return "glTexCoordP1ui";
+ case EntryPoint::GLTexCoordP1uiv:
+ return "glTexCoordP1uiv";
+ case EntryPoint::GLTexCoordP2ui:
+ return "glTexCoordP2ui";
+ case EntryPoint::GLTexCoordP2uiv:
+ return "glTexCoordP2uiv";
+ case EntryPoint::GLTexCoordP3ui:
+ return "glTexCoordP3ui";
+ case EntryPoint::GLTexCoordP3uiv:
+ return "glTexCoordP3uiv";
+ case EntryPoint::GLTexCoordP4ui:
+ return "glTexCoordP4ui";
+ case EntryPoint::GLTexCoordP4uiv:
+ return "glTexCoordP4uiv";
+ case EntryPoint::GLTexCoordPointer:
+ return "glTexCoordPointer";
+ case EntryPoint::GLTexEnvf:
+ return "glTexEnvf";
+ case EntryPoint::GLTexEnvfv:
+ return "glTexEnvfv";
+ case EntryPoint::GLTexEnvi:
+ return "glTexEnvi";
+ case EntryPoint::GLTexEnviv:
+ return "glTexEnviv";
+ case EntryPoint::GLTexEnvx:
+ return "glTexEnvx";
+ case EntryPoint::GLTexEnvxv:
+ return "glTexEnvxv";
+ case EntryPoint::GLTexGend:
+ return "glTexGend";
+ case EntryPoint::GLTexGendv:
+ return "glTexGendv";
+ case EntryPoint::GLTexGenf:
+ return "glTexGenf";
+ case EntryPoint::GLTexGenfOES:
+ return "glTexGenfOES";
+ case EntryPoint::GLTexGenfv:
+ return "glTexGenfv";
+ case EntryPoint::GLTexGenfvOES:
+ return "glTexGenfvOES";
+ case EntryPoint::GLTexGeni:
+ return "glTexGeni";
+ case EntryPoint::GLTexGeniOES:
+ return "glTexGeniOES";
+ case EntryPoint::GLTexGeniv:
+ return "glTexGeniv";
+ case EntryPoint::GLTexGenivOES:
+ return "glTexGenivOES";
+ case EntryPoint::GLTexGenxOES:
+ return "glTexGenxOES";
+ case EntryPoint::GLTexGenxvOES:
+ return "glTexGenxvOES";
+ case EntryPoint::GLTexImage1D:
+ return "glTexImage1D";
+ case EntryPoint::GLTexImage2D:
+ return "glTexImage2D";
+ case EntryPoint::GLTexImage2DExternalANGLE:
+ return "glTexImage2DExternalANGLE";
+ case EntryPoint::GLTexImage2DMultisample:
+ return "glTexImage2DMultisample";
+ case EntryPoint::GLTexImage2DRobustANGLE:
+ return "glTexImage2DRobustANGLE";
+ case EntryPoint::GLTexImage3D:
+ return "glTexImage3D";
+ case EntryPoint::GLTexImage3DMultisample:
+ return "glTexImage3DMultisample";
+ case EntryPoint::GLTexImage3DOES:
+ return "glTexImage3DOES";
+ case EntryPoint::GLTexImage3DRobustANGLE:
+ return "glTexImage3DRobustANGLE";
+ case EntryPoint::GLTexParameterIiv:
+ return "glTexParameterIiv";
+ case EntryPoint::GLTexParameterIivEXT:
+ return "glTexParameterIivEXT";
+ case EntryPoint::GLTexParameterIivOES:
+ return "glTexParameterIivOES";
+ case EntryPoint::GLTexParameterIivRobustANGLE:
+ return "glTexParameterIivRobustANGLE";
+ case EntryPoint::GLTexParameterIuiv:
+ return "glTexParameterIuiv";
+ case EntryPoint::GLTexParameterIuivEXT:
+ return "glTexParameterIuivEXT";
+ case EntryPoint::GLTexParameterIuivOES:
+ return "glTexParameterIuivOES";
+ case EntryPoint::GLTexParameterIuivRobustANGLE:
+ return "glTexParameterIuivRobustANGLE";
+ case EntryPoint::GLTexParameterf:
+ return "glTexParameterf";
+ case EntryPoint::GLTexParameterfv:
+ return "glTexParameterfv";
+ case EntryPoint::GLTexParameterfvRobustANGLE:
+ return "glTexParameterfvRobustANGLE";
+ case EntryPoint::GLTexParameteri:
+ return "glTexParameteri";
+ case EntryPoint::GLTexParameteriv:
+ return "glTexParameteriv";
+ case EntryPoint::GLTexParameterivRobustANGLE:
+ return "glTexParameterivRobustANGLE";
+ case EntryPoint::GLTexParameterx:
+ return "glTexParameterx";
+ case EntryPoint::GLTexParameterxv:
+ return "glTexParameterxv";
+ case EntryPoint::GLTexStorage1D:
+ return "glTexStorage1D";
+ case EntryPoint::GLTexStorage1DEXT:
+ return "glTexStorage1DEXT";
+ case EntryPoint::GLTexStorage2D:
+ return "glTexStorage2D";
+ case EntryPoint::GLTexStorage2DEXT:
+ return "glTexStorage2DEXT";
+ case EntryPoint::GLTexStorage2DMultisample:
+ return "glTexStorage2DMultisample";
+ case EntryPoint::GLTexStorage2DMultisampleANGLE:
+ return "glTexStorage2DMultisampleANGLE";
+ case EntryPoint::GLTexStorage3D:
+ return "glTexStorage3D";
+ case EntryPoint::GLTexStorage3DEXT:
+ return "glTexStorage3DEXT";
+ case EntryPoint::GLTexStorage3DMultisample:
+ return "glTexStorage3DMultisample";
+ case EntryPoint::GLTexStorage3DMultisampleOES:
+ return "glTexStorage3DMultisampleOES";
+ case EntryPoint::GLTexStorageMem2DEXT:
+ return "glTexStorageMem2DEXT";
+ case EntryPoint::GLTexStorageMem2DMultisampleEXT:
+ return "glTexStorageMem2DMultisampleEXT";
+ case EntryPoint::GLTexStorageMem3DEXT:
+ return "glTexStorageMem3DEXT";
+ case EntryPoint::GLTexStorageMem3DMultisampleEXT:
+ return "glTexStorageMem3DMultisampleEXT";
+ case EntryPoint::GLTexStorageMemFlags2DANGLE:
+ return "glTexStorageMemFlags2DANGLE";
+ case EntryPoint::GLTexStorageMemFlags2DMultisampleANGLE:
+ return "glTexStorageMemFlags2DMultisampleANGLE";
+ case EntryPoint::GLTexStorageMemFlags3DANGLE:
+ return "glTexStorageMemFlags3DANGLE";
+ case EntryPoint::GLTexStorageMemFlags3DMultisampleANGLE:
+ return "glTexStorageMemFlags3DMultisampleANGLE";
+ case EntryPoint::GLTexSubImage1D:
+ return "glTexSubImage1D";
+ case EntryPoint::GLTexSubImage2D:
+ return "glTexSubImage2D";
+ case EntryPoint::GLTexSubImage2DRobustANGLE:
+ return "glTexSubImage2DRobustANGLE";
+ case EntryPoint::GLTexSubImage3D:
+ return "glTexSubImage3D";
+ case EntryPoint::GLTexSubImage3DOES:
+ return "glTexSubImage3DOES";
+ case EntryPoint::GLTexSubImage3DRobustANGLE:
+ return "glTexSubImage3DRobustANGLE";
+ case EntryPoint::GLTextureBarrier:
+ return "glTextureBarrier";
+ case EntryPoint::GLTextureBuffer:
+ return "glTextureBuffer";
+ case EntryPoint::GLTextureBufferRange:
+ return "glTextureBufferRange";
+ case EntryPoint::GLTextureParameterIiv:
+ return "glTextureParameterIiv";
+ case EntryPoint::GLTextureParameterIuiv:
+ return "glTextureParameterIuiv";
+ case EntryPoint::GLTextureParameterf:
+ return "glTextureParameterf";
+ case EntryPoint::GLTextureParameterfv:
+ return "glTextureParameterfv";
+ case EntryPoint::GLTextureParameteri:
+ return "glTextureParameteri";
+ case EntryPoint::GLTextureParameteriv:
+ return "glTextureParameteriv";
+ case EntryPoint::GLTextureStorage1D:
+ return "glTextureStorage1D";
+ case EntryPoint::GLTextureStorage2D:
+ return "glTextureStorage2D";
+ case EntryPoint::GLTextureStorage2DMultisample:
+ return "glTextureStorage2DMultisample";
+ case EntryPoint::GLTextureStorage3D:
+ return "glTextureStorage3D";
+ case EntryPoint::GLTextureStorage3DMultisample:
+ return "glTextureStorage3DMultisample";
+ case EntryPoint::GLTextureSubImage1D:
+ return "glTextureSubImage1D";
+ case EntryPoint::GLTextureSubImage2D:
+ return "glTextureSubImage2D";
+ case EntryPoint::GLTextureSubImage3D:
+ return "glTextureSubImage3D";
+ case EntryPoint::GLTextureView:
+ return "glTextureView";
+ case EntryPoint::GLTransformFeedbackBufferBase:
+ return "glTransformFeedbackBufferBase";
+ case EntryPoint::GLTransformFeedbackBufferRange:
+ return "glTransformFeedbackBufferRange";
+ case EntryPoint::GLTransformFeedbackVaryings:
+ return "glTransformFeedbackVaryings";
+ case EntryPoint::GLTranslated:
+ return "glTranslated";
+ case EntryPoint::GLTranslatef:
+ return "glTranslatef";
+ case EntryPoint::GLTranslatex:
+ return "glTranslatex";
+ case EntryPoint::GLUniform1d:
+ return "glUniform1d";
+ case EntryPoint::GLUniform1dv:
+ return "glUniform1dv";
+ case EntryPoint::GLUniform1f:
+ return "glUniform1f";
+ case EntryPoint::GLUniform1fv:
+ return "glUniform1fv";
+ case EntryPoint::GLUniform1i:
+ return "glUniform1i";
+ case EntryPoint::GLUniform1iv:
+ return "glUniform1iv";
+ case EntryPoint::GLUniform1ui:
+ return "glUniform1ui";
+ case EntryPoint::GLUniform1uiv:
+ return "glUniform1uiv";
+ case EntryPoint::GLUniform2d:
+ return "glUniform2d";
+ case EntryPoint::GLUniform2dv:
+ return "glUniform2dv";
+ case EntryPoint::GLUniform2f:
+ return "glUniform2f";
+ case EntryPoint::GLUniform2fv:
+ return "glUniform2fv";
+ case EntryPoint::GLUniform2i:
+ return "glUniform2i";
+ case EntryPoint::GLUniform2iv:
+ return "glUniform2iv";
+ case EntryPoint::GLUniform2ui:
+ return "glUniform2ui";
+ case EntryPoint::GLUniform2uiv:
+ return "glUniform2uiv";
+ case EntryPoint::GLUniform3d:
+ return "glUniform3d";
+ case EntryPoint::GLUniform3dv:
+ return "glUniform3dv";
+ case EntryPoint::GLUniform3f:
+ return "glUniform3f";
+ case EntryPoint::GLUniform3fv:
+ return "glUniform3fv";
+ case EntryPoint::GLUniform3i:
+ return "glUniform3i";
+ case EntryPoint::GLUniform3iv:
+ return "glUniform3iv";
+ case EntryPoint::GLUniform3ui:
+ return "glUniform3ui";
+ case EntryPoint::GLUniform3uiv:
+ return "glUniform3uiv";
+ case EntryPoint::GLUniform4d:
+ return "glUniform4d";
+ case EntryPoint::GLUniform4dv:
+ return "glUniform4dv";
+ case EntryPoint::GLUniform4f:
+ return "glUniform4f";
+ case EntryPoint::GLUniform4fv:
+ return "glUniform4fv";
+ case EntryPoint::GLUniform4i:
+ return "glUniform4i";
+ case EntryPoint::GLUniform4iv:
+ return "glUniform4iv";
+ case EntryPoint::GLUniform4ui:
+ return "glUniform4ui";
+ case EntryPoint::GLUniform4uiv:
+ return "glUniform4uiv";
+ case EntryPoint::GLUniformBlockBinding:
+ return "glUniformBlockBinding";
+ case EntryPoint::GLUniformMatrix2dv:
+ return "glUniformMatrix2dv";
+ case EntryPoint::GLUniformMatrix2fv:
+ return "glUniformMatrix2fv";
+ case EntryPoint::GLUniformMatrix2x3dv:
+ return "glUniformMatrix2x3dv";
+ case EntryPoint::GLUniformMatrix2x3fv:
+ return "glUniformMatrix2x3fv";
+ case EntryPoint::GLUniformMatrix2x4dv:
+ return "glUniformMatrix2x4dv";
+ case EntryPoint::GLUniformMatrix2x4fv:
+ return "glUniformMatrix2x4fv";
+ case EntryPoint::GLUniformMatrix3dv:
+ return "glUniformMatrix3dv";
+ case EntryPoint::GLUniformMatrix3fv:
+ return "glUniformMatrix3fv";
+ case EntryPoint::GLUniformMatrix3x2dv:
+ return "glUniformMatrix3x2dv";
+ case EntryPoint::GLUniformMatrix3x2fv:
+ return "glUniformMatrix3x2fv";
+ case EntryPoint::GLUniformMatrix3x4dv:
+ return "glUniformMatrix3x4dv";
+ case EntryPoint::GLUniformMatrix3x4fv:
+ return "glUniformMatrix3x4fv";
+ case EntryPoint::GLUniformMatrix4dv:
+ return "glUniformMatrix4dv";
+ case EntryPoint::GLUniformMatrix4fv:
+ return "glUniformMatrix4fv";
+ case EntryPoint::GLUniformMatrix4x2dv:
+ return "glUniformMatrix4x2dv";
+ case EntryPoint::GLUniformMatrix4x2fv:
+ return "glUniformMatrix4x2fv";
+ case EntryPoint::GLUniformMatrix4x3dv:
+ return "glUniformMatrix4x3dv";
+ case EntryPoint::GLUniformMatrix4x3fv:
+ return "glUniformMatrix4x3fv";
+ case EntryPoint::GLUniformSubroutinesuiv:
+ return "glUniformSubroutinesuiv";
+ case EntryPoint::GLUnmapBuffer:
+ return "glUnmapBuffer";
+ case EntryPoint::GLUnmapBufferOES:
+ return "glUnmapBufferOES";
+ case EntryPoint::GLUnmapNamedBuffer:
+ return "glUnmapNamedBuffer";
+ case EntryPoint::GLUseProgram:
+ return "glUseProgram";
+ case EntryPoint::GLUseProgramStages:
+ return "glUseProgramStages";
+ case EntryPoint::GLUseProgramStagesEXT:
+ return "glUseProgramStagesEXT";
+ case EntryPoint::GLValidateProgram:
+ return "glValidateProgram";
+ case EntryPoint::GLValidateProgramPipeline:
+ return "glValidateProgramPipeline";
+ case EntryPoint::GLValidateProgramPipelineEXT:
+ return "glValidateProgramPipelineEXT";
+ case EntryPoint::GLVertex2d:
+ return "glVertex2d";
+ case EntryPoint::GLVertex2dv:
+ return "glVertex2dv";
+ case EntryPoint::GLVertex2f:
+ return "glVertex2f";
+ case EntryPoint::GLVertex2fv:
+ return "glVertex2fv";
+ case EntryPoint::GLVertex2i:
+ return "glVertex2i";
+ case EntryPoint::GLVertex2iv:
+ return "glVertex2iv";
+ case EntryPoint::GLVertex2s:
+ return "glVertex2s";
+ case EntryPoint::GLVertex2sv:
+ return "glVertex2sv";
+ case EntryPoint::GLVertex3d:
+ return "glVertex3d";
+ case EntryPoint::GLVertex3dv:
+ return "glVertex3dv";
+ case EntryPoint::GLVertex3f:
+ return "glVertex3f";
+ case EntryPoint::GLVertex3fv:
+ return "glVertex3fv";
+ case EntryPoint::GLVertex3i:
+ return "glVertex3i";
+ case EntryPoint::GLVertex3iv:
+ return "glVertex3iv";
+ case EntryPoint::GLVertex3s:
+ return "glVertex3s";
+ case EntryPoint::GLVertex3sv:
+ return "glVertex3sv";
+ case EntryPoint::GLVertex4d:
+ return "glVertex4d";
+ case EntryPoint::GLVertex4dv:
+ return "glVertex4dv";
+ case EntryPoint::GLVertex4f:
+ return "glVertex4f";
+ case EntryPoint::GLVertex4fv:
+ return "glVertex4fv";
+ case EntryPoint::GLVertex4i:
+ return "glVertex4i";
+ case EntryPoint::GLVertex4iv:
+ return "glVertex4iv";
+ case EntryPoint::GLVertex4s:
+ return "glVertex4s";
+ case EntryPoint::GLVertex4sv:
+ return "glVertex4sv";
+ case EntryPoint::GLVertexArrayAttribBinding:
+ return "glVertexArrayAttribBinding";
+ case EntryPoint::GLVertexArrayAttribFormat:
+ return "glVertexArrayAttribFormat";
+ case EntryPoint::GLVertexArrayAttribIFormat:
+ return "glVertexArrayAttribIFormat";
+ case EntryPoint::GLVertexArrayAttribLFormat:
+ return "glVertexArrayAttribLFormat";
+ case EntryPoint::GLVertexArrayBindingDivisor:
+ return "glVertexArrayBindingDivisor";
+ case EntryPoint::GLVertexArrayElementBuffer:
+ return "glVertexArrayElementBuffer";
+ case EntryPoint::GLVertexArrayVertexBuffer:
+ return "glVertexArrayVertexBuffer";
+ case EntryPoint::GLVertexArrayVertexBuffers:
+ return "glVertexArrayVertexBuffers";
+ case EntryPoint::GLVertexAttrib1d:
+ return "glVertexAttrib1d";
+ case EntryPoint::GLVertexAttrib1dv:
+ return "glVertexAttrib1dv";
+ case EntryPoint::GLVertexAttrib1f:
+ return "glVertexAttrib1f";
+ case EntryPoint::GLVertexAttrib1fv:
+ return "glVertexAttrib1fv";
+ case EntryPoint::GLVertexAttrib1s:
+ return "glVertexAttrib1s";
+ case EntryPoint::GLVertexAttrib1sv:
+ return "glVertexAttrib1sv";
+ case EntryPoint::GLVertexAttrib2d:
+ return "glVertexAttrib2d";
+ case EntryPoint::GLVertexAttrib2dv:
+ return "glVertexAttrib2dv";
+ case EntryPoint::GLVertexAttrib2f:
+ return "glVertexAttrib2f";
+ case EntryPoint::GLVertexAttrib2fv:
+ return "glVertexAttrib2fv";
+ case EntryPoint::GLVertexAttrib2s:
+ return "glVertexAttrib2s";
+ case EntryPoint::GLVertexAttrib2sv:
+ return "glVertexAttrib2sv";
+ case EntryPoint::GLVertexAttrib3d:
+ return "glVertexAttrib3d";
+ case EntryPoint::GLVertexAttrib3dv:
+ return "glVertexAttrib3dv";
+ case EntryPoint::GLVertexAttrib3f:
+ return "glVertexAttrib3f";
+ case EntryPoint::GLVertexAttrib3fv:
+ return "glVertexAttrib3fv";
+ case EntryPoint::GLVertexAttrib3s:
+ return "glVertexAttrib3s";
+ case EntryPoint::GLVertexAttrib3sv:
+ return "glVertexAttrib3sv";
+ case EntryPoint::GLVertexAttrib4Nbv:
+ return "glVertexAttrib4Nbv";
+ case EntryPoint::GLVertexAttrib4Niv:
+ return "glVertexAttrib4Niv";
+ case EntryPoint::GLVertexAttrib4Nsv:
+ return "glVertexAttrib4Nsv";
+ case EntryPoint::GLVertexAttrib4Nub:
+ return "glVertexAttrib4Nub";
+ case EntryPoint::GLVertexAttrib4Nubv:
+ return "glVertexAttrib4Nubv";
+ case EntryPoint::GLVertexAttrib4Nuiv:
+ return "glVertexAttrib4Nuiv";
+ case EntryPoint::GLVertexAttrib4Nusv:
+ return "glVertexAttrib4Nusv";
+ case EntryPoint::GLVertexAttrib4bv:
+ return "glVertexAttrib4bv";
+ case EntryPoint::GLVertexAttrib4d:
+ return "glVertexAttrib4d";
+ case EntryPoint::GLVertexAttrib4dv:
+ return "glVertexAttrib4dv";
+ case EntryPoint::GLVertexAttrib4f:
+ return "glVertexAttrib4f";
+ case EntryPoint::GLVertexAttrib4fv:
+ return "glVertexAttrib4fv";
+ case EntryPoint::GLVertexAttrib4iv:
+ return "glVertexAttrib4iv";
+ case EntryPoint::GLVertexAttrib4s:
+ return "glVertexAttrib4s";
+ case EntryPoint::GLVertexAttrib4sv:
+ return "glVertexAttrib4sv";
+ case EntryPoint::GLVertexAttrib4ubv:
+ return "glVertexAttrib4ubv";
+ case EntryPoint::GLVertexAttrib4uiv:
+ return "glVertexAttrib4uiv";
+ case EntryPoint::GLVertexAttrib4usv:
+ return "glVertexAttrib4usv";
+ case EntryPoint::GLVertexAttribBinding:
+ return "glVertexAttribBinding";
+ case EntryPoint::GLVertexAttribDivisor:
+ return "glVertexAttribDivisor";
+ case EntryPoint::GLVertexAttribDivisorANGLE:
+ return "glVertexAttribDivisorANGLE";
+ case EntryPoint::GLVertexAttribDivisorEXT:
+ return "glVertexAttribDivisorEXT";
+ case EntryPoint::GLVertexAttribFormat:
+ return "glVertexAttribFormat";
+ case EntryPoint::GLVertexAttribI1i:
+ return "glVertexAttribI1i";
+ case EntryPoint::GLVertexAttribI1iv:
+ return "glVertexAttribI1iv";
+ case EntryPoint::GLVertexAttribI1ui:
+ return "glVertexAttribI1ui";
+ case EntryPoint::GLVertexAttribI1uiv:
+ return "glVertexAttribI1uiv";
+ case EntryPoint::GLVertexAttribI2i:
+ return "glVertexAttribI2i";
+ case EntryPoint::GLVertexAttribI2iv:
+ return "glVertexAttribI2iv";
+ case EntryPoint::GLVertexAttribI2ui:
+ return "glVertexAttribI2ui";
+ case EntryPoint::GLVertexAttribI2uiv:
+ return "glVertexAttribI2uiv";
+ case EntryPoint::GLVertexAttribI3i:
+ return "glVertexAttribI3i";
+ case EntryPoint::GLVertexAttribI3iv:
+ return "glVertexAttribI3iv";
+ case EntryPoint::GLVertexAttribI3ui:
+ return "glVertexAttribI3ui";
+ case EntryPoint::GLVertexAttribI3uiv:
+ return "glVertexAttribI3uiv";
+ case EntryPoint::GLVertexAttribI4bv:
+ return "glVertexAttribI4bv";
+ case EntryPoint::GLVertexAttribI4i:
+ return "glVertexAttribI4i";
+ case EntryPoint::GLVertexAttribI4iv:
+ return "glVertexAttribI4iv";
+ case EntryPoint::GLVertexAttribI4sv:
+ return "glVertexAttribI4sv";
+ case EntryPoint::GLVertexAttribI4ubv:
+ return "glVertexAttribI4ubv";
+ case EntryPoint::GLVertexAttribI4ui:
+ return "glVertexAttribI4ui";
+ case EntryPoint::GLVertexAttribI4uiv:
+ return "glVertexAttribI4uiv";
+ case EntryPoint::GLVertexAttribI4usv:
+ return "glVertexAttribI4usv";
+ case EntryPoint::GLVertexAttribIFormat:
+ return "glVertexAttribIFormat";
+ case EntryPoint::GLVertexAttribIPointer:
+ return "glVertexAttribIPointer";
+ case EntryPoint::GLVertexAttribL1d:
+ return "glVertexAttribL1d";
+ case EntryPoint::GLVertexAttribL1dv:
+ return "glVertexAttribL1dv";
+ case EntryPoint::GLVertexAttribL2d:
+ return "glVertexAttribL2d";
+ case EntryPoint::GLVertexAttribL2dv:
+ return "glVertexAttribL2dv";
+ case EntryPoint::GLVertexAttribL3d:
+ return "glVertexAttribL3d";
+ case EntryPoint::GLVertexAttribL3dv:
+ return "glVertexAttribL3dv";
+ case EntryPoint::GLVertexAttribL4d:
+ return "glVertexAttribL4d";
+ case EntryPoint::GLVertexAttribL4dv:
+ return "glVertexAttribL4dv";
+ case EntryPoint::GLVertexAttribLFormat:
+ return "glVertexAttribLFormat";
+ case EntryPoint::GLVertexAttribLPointer:
+ return "glVertexAttribLPointer";
+ case EntryPoint::GLVertexAttribP1ui:
+ return "glVertexAttribP1ui";
+ case EntryPoint::GLVertexAttribP1uiv:
+ return "glVertexAttribP1uiv";
+ case EntryPoint::GLVertexAttribP2ui:
+ return "glVertexAttribP2ui";
+ case EntryPoint::GLVertexAttribP2uiv:
+ return "glVertexAttribP2uiv";
+ case EntryPoint::GLVertexAttribP3ui:
+ return "glVertexAttribP3ui";
+ case EntryPoint::GLVertexAttribP3uiv:
+ return "glVertexAttribP3uiv";
+ case EntryPoint::GLVertexAttribP4ui:
+ return "glVertexAttribP4ui";
+ case EntryPoint::GLVertexAttribP4uiv:
+ return "glVertexAttribP4uiv";
+ case EntryPoint::GLVertexAttribPointer:
+ return "glVertexAttribPointer";
+ case EntryPoint::GLVertexBindingDivisor:
+ return "glVertexBindingDivisor";
+ case EntryPoint::GLVertexP2ui:
+ return "glVertexP2ui";
+ case EntryPoint::GLVertexP2uiv:
+ return "glVertexP2uiv";
+ case EntryPoint::GLVertexP3ui:
+ return "glVertexP3ui";
+ case EntryPoint::GLVertexP3uiv:
+ return "glVertexP3uiv";
+ case EntryPoint::GLVertexP4ui:
+ return "glVertexP4ui";
+ case EntryPoint::GLVertexP4uiv:
+ return "glVertexP4uiv";
+ case EntryPoint::GLVertexPointer:
+ return "glVertexPointer";
+ case EntryPoint::GLViewport:
+ return "glViewport";
+ case EntryPoint::GLViewportArrayv:
+ return "glViewportArrayv";
+ case EntryPoint::GLViewportIndexedf:
+ return "glViewportIndexedf";
+ case EntryPoint::GLViewportIndexedfv:
+ return "glViewportIndexedfv";
+ case EntryPoint::GLWaitSemaphoreEXT:
+ return "glWaitSemaphoreEXT";
+ case EntryPoint::GLWaitSync:
+ return "glWaitSync";
+ case EntryPoint::GLWeightPointerOES:
+ return "glWeightPointerOES";
+ case EntryPoint::GLWindowPos2d:
+ return "glWindowPos2d";
+ case EntryPoint::GLWindowPos2dv:
+ return "glWindowPos2dv";
+ case EntryPoint::GLWindowPos2f:
+ return "glWindowPos2f";
+ case EntryPoint::GLWindowPos2fv:
+ return "glWindowPos2fv";
+ case EntryPoint::GLWindowPos2i:
+ return "glWindowPos2i";
+ case EntryPoint::GLWindowPos2iv:
+ return "glWindowPos2iv";
+ case EntryPoint::GLWindowPos2s:
+ return "glWindowPos2s";
+ case EntryPoint::GLWindowPos2sv:
+ return "glWindowPos2sv";
+ case EntryPoint::GLWindowPos3d:
+ return "glWindowPos3d";
+ case EntryPoint::GLWindowPos3dv:
+ return "glWindowPos3dv";
+ case EntryPoint::GLWindowPos3f:
+ return "glWindowPos3f";
+ case EntryPoint::GLWindowPos3fv:
+ return "glWindowPos3fv";
+ case EntryPoint::GLWindowPos3i:
+ return "glWindowPos3i";
+ case EntryPoint::GLWindowPos3iv:
+ return "glWindowPos3iv";
+ case EntryPoint::GLWindowPos3s:
+ return "glWindowPos3s";
+ case EntryPoint::GLWindowPos3sv:
+ return "glWindowPos3sv";
+ case EntryPoint::WGLChoosePixelFormat:
+ return "wglChoosePixelFormat";
+ case EntryPoint::WGLCopyContext:
+ return "wglCopyContext";
+ case EntryPoint::WGLCreateContext:
+ return "wglCreateContext";
+ case EntryPoint::WGLCreateLayerContext:
+ return "wglCreateLayerContext";
+ case EntryPoint::WGLDeleteContext:
+ return "wglDeleteContext";
+ case EntryPoint::WGLDescribeLayerPlane:
+ return "wglDescribeLayerPlane";
+ case EntryPoint::WGLDescribePixelFormat:
+ return "wglDescribePixelFormat";
+ case EntryPoint::WGLGetCurrentContext:
+ return "wglGetCurrentContext";
+ case EntryPoint::WGLGetCurrentDC:
+ return "wglGetCurrentDC";
+ case EntryPoint::WGLGetEnhMetaFilePixelFormat:
+ return "wglGetEnhMetaFilePixelFormat";
+ case EntryPoint::WGLGetLayerPaletteEntries:
+ return "wglGetLayerPaletteEntries";
+ case EntryPoint::WGLGetPixelFormat:
+ return "wglGetPixelFormat";
+ case EntryPoint::WGLGetProcAddress:
+ return "wglGetProcAddress";
+ case EntryPoint::WGLMakeCurrent:
+ return "wglMakeCurrent";
+ case EntryPoint::WGLRealizeLayerPalette:
+ return "wglRealizeLayerPalette";
+ case EntryPoint::WGLSetLayerPaletteEntries:
+ return "wglSetLayerPaletteEntries";
+ case EntryPoint::WGLSetPixelFormat:
+ return "wglSetPixelFormat";
+ case EntryPoint::WGLShareLists:
+ return "wglShareLists";
+ case EntryPoint::WGLSwapBuffers:
+ return "wglSwapBuffers";
+ case EntryPoint::WGLSwapLayerBuffers:
+ return "wglSwapLayerBuffers";
+ case EntryPoint::WGLUseFontBitmaps:
+ return "wglUseFontBitmaps";
+ case EntryPoint::WGLUseFontBitmapsA:
+ return "wglUseFontBitmapsA";
+ case EntryPoint::WGLUseFontBitmapsW:
+ return "wglUseFontBitmapsW";
+ case EntryPoint::WGLUseFontOutlines:
+ return "wglUseFontOutlines";
+ case EntryPoint::WGLUseFontOutlinesA:
+ return "wglUseFontOutlinesA";
+ case EntryPoint::WGLUseFontOutlinesW:
+ return "wglUseFontOutlinesW";
+ default:
+ UNREACHABLE();
+ return "error";
+ }
+}
+} // namespace angle
diff --git a/gfx/angle/checkout/src/common/entry_points_enum_autogen.h b/gfx/angle/checkout/src/common/entry_points_enum_autogen.h
new file mode 100644
index 0000000000..61c5c76f58
--- /dev/null
+++ b/gfx/angle/checkout/src/common/entry_points_enum_autogen.h
@@ -0,0 +1,1736 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml and gl_angle_ext.xml.
+//
+// Copyright 2020 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_enum_autogen.h:
+// Defines the GL/GLES entry points enumeration.
+
+#ifndef COMMON_ENTRYPOINTSENUM_AUTOGEN_H_
+#define COMMON_ENTRYPOINTSENUM_AUTOGEN_H_
+
+namespace angle
+{
+enum class EntryPoint
+{
+ CLBuildProgram,
+ CLCloneKernel,
+ CLCompileProgram,
+ CLCreateBuffer,
+ CLCreateBufferWithProperties,
+ CLCreateCommandQueue,
+ CLCreateCommandQueueWithProperties,
+ CLCreateContext,
+ CLCreateContextFromType,
+ CLCreateImage,
+ CLCreateImage2D,
+ CLCreateImage3D,
+ CLCreateImageWithProperties,
+ CLCreateKernel,
+ CLCreateKernelsInProgram,
+ CLCreatePipe,
+ CLCreateProgramWithBinary,
+ CLCreateProgramWithBuiltInKernels,
+ CLCreateProgramWithIL,
+ CLCreateProgramWithSource,
+ CLCreateSampler,
+ CLCreateSamplerWithProperties,
+ CLCreateSubBuffer,
+ CLCreateSubDevices,
+ CLCreateUserEvent,
+ CLEnqueueBarrier,
+ CLEnqueueBarrierWithWaitList,
+ CLEnqueueCopyBuffer,
+ CLEnqueueCopyBufferRect,
+ CLEnqueueCopyBufferToImage,
+ CLEnqueueCopyImage,
+ CLEnqueueCopyImageToBuffer,
+ CLEnqueueFillBuffer,
+ CLEnqueueFillImage,
+ CLEnqueueMapBuffer,
+ CLEnqueueMapImage,
+ CLEnqueueMarker,
+ CLEnqueueMarkerWithWaitList,
+ CLEnqueueMigrateMemObjects,
+ CLEnqueueNDRangeKernel,
+ CLEnqueueNativeKernel,
+ CLEnqueueReadBuffer,
+ CLEnqueueReadBufferRect,
+ CLEnqueueReadImage,
+ CLEnqueueSVMFree,
+ CLEnqueueSVMMap,
+ CLEnqueueSVMMemFill,
+ CLEnqueueSVMMemcpy,
+ CLEnqueueSVMMigrateMem,
+ CLEnqueueSVMUnmap,
+ CLEnqueueTask,
+ CLEnqueueUnmapMemObject,
+ CLEnqueueWaitForEvents,
+ CLEnqueueWriteBuffer,
+ CLEnqueueWriteBufferRect,
+ CLEnqueueWriteImage,
+ CLFinish,
+ CLFlush,
+ CLGetCommandQueueInfo,
+ CLGetContextInfo,
+ CLGetDeviceAndHostTimer,
+ CLGetDeviceIDs,
+ CLGetDeviceInfo,
+ CLGetEventInfo,
+ CLGetEventProfilingInfo,
+ CLGetExtensionFunctionAddress,
+ CLGetExtensionFunctionAddressForPlatform,
+ CLGetHostTimer,
+ CLGetImageInfo,
+ CLGetKernelArgInfo,
+ CLGetKernelInfo,
+ CLGetKernelSubGroupInfo,
+ CLGetKernelWorkGroupInfo,
+ CLGetMemObjectInfo,
+ CLGetPipeInfo,
+ CLGetPlatformIDs,
+ CLGetPlatformInfo,
+ CLGetProgramBuildInfo,
+ CLGetProgramInfo,
+ CLGetSamplerInfo,
+ CLGetSupportedImageFormats,
+ CLIcdGetPlatformIDsKHR,
+ CLLinkProgram,
+ CLReleaseCommandQueue,
+ CLReleaseContext,
+ CLReleaseDevice,
+ CLReleaseEvent,
+ CLReleaseKernel,
+ CLReleaseMemObject,
+ CLReleaseProgram,
+ CLReleaseSampler,
+ CLRetainCommandQueue,
+ CLRetainContext,
+ CLRetainDevice,
+ CLRetainEvent,
+ CLRetainKernel,
+ CLRetainMemObject,
+ CLRetainProgram,
+ CLRetainSampler,
+ CLSVMAlloc,
+ CLSVMFree,
+ CLSetCommandQueueProperty,
+ CLSetContextDestructorCallback,
+ CLSetDefaultDeviceCommandQueue,
+ CLSetEventCallback,
+ CLSetKernelArg,
+ CLSetKernelArgSVMPointer,
+ CLSetKernelExecInfo,
+ CLSetMemObjectDestructorCallback,
+ CLSetProgramReleaseCallback,
+ CLSetProgramSpecializationConstant,
+ CLSetUserEventStatus,
+ CLUnloadCompiler,
+ CLUnloadPlatformCompiler,
+ CLWaitForEvents,
+ EGLBindAPI,
+ EGLBindTexImage,
+ EGLChooseConfig,
+ EGLClientWaitSync,
+ EGLClientWaitSyncKHR,
+ EGLCopyBuffers,
+ EGLCopyMetalSharedEventANGLE,
+ EGLCreateContext,
+ EGLCreateDeviceANGLE,
+ EGLCreateImage,
+ EGLCreateImageKHR,
+ EGLCreateNativeClientBufferANDROID,
+ EGLCreatePbufferFromClientBuffer,
+ EGLCreatePbufferSurface,
+ EGLCreatePixmapSurface,
+ EGLCreatePlatformPixmapSurface,
+ EGLCreatePlatformPixmapSurfaceEXT,
+ EGLCreatePlatformWindowSurface,
+ EGLCreatePlatformWindowSurfaceEXT,
+ EGLCreateStreamKHR,
+ EGLCreateStreamProducerD3DTextureANGLE,
+ EGLCreateSync,
+ EGLCreateSyncKHR,
+ EGLCreateWindowSurface,
+ EGLDebugMessageControlKHR,
+ EGLDestroyContext,
+ EGLDestroyImage,
+ EGLDestroyImageKHR,
+ EGLDestroyStreamKHR,
+ EGLDestroySurface,
+ EGLDestroySync,
+ EGLDestroySyncKHR,
+ EGLDupNativeFenceFDANDROID,
+ EGLExportVkImageANGLE,
+ EGLForceGPUSwitchANGLE,
+ EGLGetCompositorTimingANDROID,
+ EGLGetCompositorTimingSupportedANDROID,
+ EGLGetConfigAttrib,
+ EGLGetConfigs,
+ EGLGetCurrentContext,
+ EGLGetCurrentDisplay,
+ EGLGetCurrentSurface,
+ EGLGetDisplay,
+ EGLGetError,
+ EGLGetFrameTimestampSupportedANDROID,
+ EGLGetFrameTimestampsANDROID,
+ EGLGetMscRateANGLE,
+ EGLGetNativeClientBufferANDROID,
+ EGLGetNextFrameIdANDROID,
+ EGLGetPlatformDisplay,
+ EGLGetPlatformDisplayEXT,
+ EGLGetProcAddress,
+ EGLGetSyncAttrib,
+ EGLGetSyncAttribKHR,
+ EGLGetSyncValuesCHROMIUM,
+ EGLHandleGPUSwitchANGLE,
+ EGLInitialize,
+ EGLLabelObjectKHR,
+ EGLLockSurfaceKHR,
+ EGLMakeCurrent,
+ EGLPostSubBufferNV,
+ EGLPrepareSwapBuffersANGLE,
+ EGLPresentationTimeANDROID,
+ EGLProgramCacheGetAttribANGLE,
+ EGLProgramCachePopulateANGLE,
+ EGLProgramCacheQueryANGLE,
+ EGLProgramCacheResizeANGLE,
+ EGLQueryAPI,
+ EGLQueryContext,
+ EGLQueryDebugKHR,
+ EGLQueryDeviceAttribEXT,
+ EGLQueryDeviceStringEXT,
+ EGLQueryDisplayAttribANGLE,
+ EGLQueryDisplayAttribEXT,
+ EGLQueryDmaBufFormatsEXT,
+ EGLQueryDmaBufModifiersEXT,
+ EGLQueryStreamKHR,
+ EGLQueryStreamu64KHR,
+ EGLQueryString,
+ EGLQueryStringiANGLE,
+ EGLQuerySurface,
+ EGLQuerySurface64KHR,
+ EGLQuerySurfacePointerANGLE,
+ EGLReacquireHighPowerGPUANGLE,
+ EGLReleaseDeviceANGLE,
+ EGLReleaseHighPowerGPUANGLE,
+ EGLReleaseTexImage,
+ EGLReleaseThread,
+ EGLSetBlobCacheFuncsANDROID,
+ EGLSetDamageRegionKHR,
+ EGLSignalSyncKHR,
+ EGLStreamAttribKHR,
+ EGLStreamConsumerAcquireKHR,
+ EGLStreamConsumerGLTextureExternalAttribsNV,
+ EGLStreamConsumerGLTextureExternalKHR,
+ EGLStreamConsumerReleaseKHR,
+ EGLStreamPostD3DTextureANGLE,
+ EGLSurfaceAttrib,
+ EGLSwapBuffers,
+ EGLSwapBuffersWithDamageKHR,
+ EGLSwapBuffersWithFrameTokenANGLE,
+ EGLSwapInterval,
+ EGLTerminate,
+ EGLUnlockSurfaceKHR,
+ EGLWaitClient,
+ EGLWaitGL,
+ EGLWaitNative,
+ EGLWaitSync,
+ EGLWaitSyncKHR,
+ GLAccum,
+ GLAcquireTexturesANGLE,
+ GLActiveShaderProgram,
+ GLActiveShaderProgramEXT,
+ GLActiveTexture,
+ GLAlphaFunc,
+ GLAlphaFuncx,
+ GLAreTexturesResident,
+ GLArrayElement,
+ GLAttachShader,
+ GLBegin,
+ GLBeginConditionalRender,
+ GLBeginPerfMonitorAMD,
+ GLBeginPixelLocalStorageANGLE,
+ GLBeginQuery,
+ GLBeginQueryEXT,
+ GLBeginQueryIndexed,
+ GLBeginTransformFeedback,
+ GLBindAttribLocation,
+ GLBindBuffer,
+ GLBindBufferBase,
+ GLBindBufferRange,
+ GLBindBuffersBase,
+ GLBindBuffersRange,
+ GLBindFragDataLocation,
+ GLBindFragDataLocationEXT,
+ GLBindFragDataLocationIndexed,
+ GLBindFragDataLocationIndexedEXT,
+ GLBindFramebuffer,
+ GLBindFramebufferOES,
+ GLBindImageTexture,
+ GLBindImageTextures,
+ GLBindProgramPipeline,
+ GLBindProgramPipelineEXT,
+ GLBindRenderbuffer,
+ GLBindRenderbufferOES,
+ GLBindSampler,
+ GLBindSamplers,
+ GLBindTexture,
+ GLBindTextureUnit,
+ GLBindTextures,
+ GLBindTransformFeedback,
+ GLBindUniformLocationCHROMIUM,
+ GLBindVertexArray,
+ GLBindVertexArrayOES,
+ GLBindVertexBuffer,
+ GLBindVertexBuffers,
+ GLBitmap,
+ GLBlendBarrier,
+ GLBlendBarrierKHR,
+ GLBlendColor,
+ GLBlendEquation,
+ GLBlendEquationSeparate,
+ GLBlendEquationSeparatei,
+ GLBlendEquationSeparateiEXT,
+ GLBlendEquationSeparateiOES,
+ GLBlendEquationi,
+ GLBlendEquationiEXT,
+ GLBlendEquationiOES,
+ GLBlendFunc,
+ GLBlendFuncSeparate,
+ GLBlendFuncSeparatei,
+ GLBlendFuncSeparateiEXT,
+ GLBlendFuncSeparateiOES,
+ GLBlendFunci,
+ GLBlendFunciEXT,
+ GLBlendFunciOES,
+ GLBlitFramebuffer,
+ GLBlitFramebufferANGLE,
+ GLBlitFramebufferNV,
+ GLBlitNamedFramebuffer,
+ GLBufferData,
+ GLBufferStorage,
+ GLBufferStorageEXT,
+ GLBufferStorageExternalEXT,
+ GLBufferStorageMemEXT,
+ GLBufferSubData,
+ GLCallList,
+ GLCallLists,
+ GLCheckFramebufferStatus,
+ GLCheckFramebufferStatusOES,
+ GLCheckNamedFramebufferStatus,
+ GLClampColor,
+ GLClear,
+ GLClearAccum,
+ GLClearBufferData,
+ GLClearBufferSubData,
+ GLClearBufferfi,
+ GLClearBufferfv,
+ GLClearBufferiv,
+ GLClearBufferuiv,
+ GLClearColor,
+ GLClearColorx,
+ GLClearDepth,
+ GLClearDepthf,
+ GLClearDepthx,
+ GLClearIndex,
+ GLClearNamedBufferData,
+ GLClearNamedBufferSubData,
+ GLClearNamedFramebufferfi,
+ GLClearNamedFramebufferfv,
+ GLClearNamedFramebufferiv,
+ GLClearNamedFramebufferuiv,
+ GLClearStencil,
+ GLClearTexImage,
+ GLClearTexSubImage,
+ GLClientActiveTexture,
+ GLClientWaitSync,
+ GLClipControl,
+ GLClipControlEXT,
+ GLClipPlane,
+ GLClipPlanef,
+ GLClipPlanex,
+ GLColor3b,
+ GLColor3bv,
+ GLColor3d,
+ GLColor3dv,
+ GLColor3f,
+ GLColor3fv,
+ GLColor3i,
+ GLColor3iv,
+ GLColor3s,
+ GLColor3sv,
+ GLColor3ub,
+ GLColor3ubv,
+ GLColor3ui,
+ GLColor3uiv,
+ GLColor3us,
+ GLColor3usv,
+ GLColor4b,
+ GLColor4bv,
+ GLColor4d,
+ GLColor4dv,
+ GLColor4f,
+ GLColor4fv,
+ GLColor4i,
+ GLColor4iv,
+ GLColor4s,
+ GLColor4sv,
+ GLColor4ub,
+ GLColor4ubv,
+ GLColor4ui,
+ GLColor4uiv,
+ GLColor4us,
+ GLColor4usv,
+ GLColor4x,
+ GLColorMask,
+ GLColorMaski,
+ GLColorMaskiEXT,
+ GLColorMaskiOES,
+ GLColorMaterial,
+ GLColorP3ui,
+ GLColorP3uiv,
+ GLColorP4ui,
+ GLColorP4uiv,
+ GLColorPointer,
+ GLCompileShader,
+ GLCompressedCopyTextureCHROMIUM,
+ GLCompressedTexImage1D,
+ GLCompressedTexImage2D,
+ GLCompressedTexImage2DRobustANGLE,
+ GLCompressedTexImage3D,
+ GLCompressedTexImage3DOES,
+ GLCompressedTexImage3DRobustANGLE,
+ GLCompressedTexSubImage1D,
+ GLCompressedTexSubImage2D,
+ GLCompressedTexSubImage2DRobustANGLE,
+ GLCompressedTexSubImage3D,
+ GLCompressedTexSubImage3DOES,
+ GLCompressedTexSubImage3DRobustANGLE,
+ GLCompressedTextureSubImage1D,
+ GLCompressedTextureSubImage2D,
+ GLCompressedTextureSubImage3D,
+ GLCopyBufferSubData,
+ GLCopyImageSubData,
+ GLCopyImageSubDataEXT,
+ GLCopyImageSubDataOES,
+ GLCopyNamedBufferSubData,
+ GLCopyPixels,
+ GLCopySubTexture3DANGLE,
+ GLCopySubTextureCHROMIUM,
+ GLCopyTexImage1D,
+ GLCopyTexImage2D,
+ GLCopyTexSubImage1D,
+ GLCopyTexSubImage2D,
+ GLCopyTexSubImage3D,
+ GLCopyTexSubImage3DOES,
+ GLCopyTexture3DANGLE,
+ GLCopyTextureCHROMIUM,
+ GLCopyTextureSubImage1D,
+ GLCopyTextureSubImage2D,
+ GLCopyTextureSubImage3D,
+ GLCoverageModulationCHROMIUM,
+ GLCreateBuffers,
+ GLCreateFramebuffers,
+ GLCreateMemoryObjectsEXT,
+ GLCreateProgram,
+ GLCreateProgramPipelines,
+ GLCreateQueries,
+ GLCreateRenderbuffers,
+ GLCreateSamplers,
+ GLCreateShader,
+ GLCreateShaderProgramv,
+ GLCreateShaderProgramvEXT,
+ GLCreateTextures,
+ GLCreateTransformFeedbacks,
+ GLCreateVertexArrays,
+ GLCullFace,
+ GLCurrentPaletteMatrixOES,
+ GLDebugMessageCallback,
+ GLDebugMessageCallbackKHR,
+ GLDebugMessageControl,
+ GLDebugMessageControlKHR,
+ GLDebugMessageInsert,
+ GLDebugMessageInsertKHR,
+ GLDeleteBuffers,
+ GLDeleteFencesNV,
+ GLDeleteFramebuffers,
+ GLDeleteFramebuffersOES,
+ GLDeleteLists,
+ GLDeleteMemoryObjectsEXT,
+ GLDeletePerfMonitorsAMD,
+ GLDeleteProgram,
+ GLDeleteProgramPipelines,
+ GLDeleteProgramPipelinesEXT,
+ GLDeleteQueries,
+ GLDeleteQueriesEXT,
+ GLDeleteRenderbuffers,
+ GLDeleteRenderbuffersOES,
+ GLDeleteSamplers,
+ GLDeleteSemaphoresEXT,
+ GLDeleteShader,
+ GLDeleteSync,
+ GLDeleteTextures,
+ GLDeleteTransformFeedbacks,
+ GLDeleteVertexArrays,
+ GLDeleteVertexArraysOES,
+ GLDepthFunc,
+ GLDepthMask,
+ GLDepthRange,
+ GLDepthRangeArrayv,
+ GLDepthRangeIndexed,
+ GLDepthRangef,
+ GLDepthRangex,
+ GLDetachShader,
+ GLDisable,
+ GLDisableClientState,
+ GLDisableExtensionANGLE,
+ GLDisableVertexArrayAttrib,
+ GLDisableVertexAttribArray,
+ GLDisablei,
+ GLDisableiEXT,
+ GLDisableiOES,
+ GLDiscardFramebufferEXT,
+ GLDispatchCompute,
+ GLDispatchComputeIndirect,
+ GLDrawArrays,
+ GLDrawArraysIndirect,
+ GLDrawArraysInstanced,
+ GLDrawArraysInstancedANGLE,
+ GLDrawArraysInstancedBaseInstance,
+ GLDrawArraysInstancedBaseInstanceANGLE,
+ GLDrawArraysInstancedBaseInstanceEXT,
+ GLDrawArraysInstancedEXT,
+ GLDrawBuffer,
+ GLDrawBuffers,
+ GLDrawBuffersEXT,
+ GLDrawElements,
+ GLDrawElementsBaseVertex,
+ GLDrawElementsBaseVertexEXT,
+ GLDrawElementsBaseVertexOES,
+ GLDrawElementsIndirect,
+ GLDrawElementsInstanced,
+ GLDrawElementsInstancedANGLE,
+ GLDrawElementsInstancedBaseInstance,
+ GLDrawElementsInstancedBaseInstanceEXT,
+ GLDrawElementsInstancedBaseVertex,
+ GLDrawElementsInstancedBaseVertexBaseInstance,
+ GLDrawElementsInstancedBaseVertexBaseInstanceANGLE,
+ GLDrawElementsInstancedBaseVertexBaseInstanceEXT,
+ GLDrawElementsInstancedBaseVertexEXT,
+ GLDrawElementsInstancedBaseVertexOES,
+ GLDrawElementsInstancedEXT,
+ GLDrawPixels,
+ GLDrawRangeElements,
+ GLDrawRangeElementsBaseVertex,
+ GLDrawRangeElementsBaseVertexEXT,
+ GLDrawRangeElementsBaseVertexOES,
+ GLDrawTexfOES,
+ GLDrawTexfvOES,
+ GLDrawTexiOES,
+ GLDrawTexivOES,
+ GLDrawTexsOES,
+ GLDrawTexsvOES,
+ GLDrawTexxOES,
+ GLDrawTexxvOES,
+ GLDrawTransformFeedback,
+ GLDrawTransformFeedbackInstanced,
+ GLDrawTransformFeedbackStream,
+ GLDrawTransformFeedbackStreamInstanced,
+ GLEGLImageTargetRenderbufferStorageOES,
+ GLEGLImageTargetTexStorageEXT,
+ GLEGLImageTargetTexture2DOES,
+ GLEGLImageTargetTextureStorageEXT,
+ GLEdgeFlag,
+ GLEdgeFlagPointer,
+ GLEdgeFlagv,
+ GLEnable,
+ GLEnableClientState,
+ GLEnableVertexArrayAttrib,
+ GLEnableVertexAttribArray,
+ GLEnablei,
+ GLEnableiEXT,
+ GLEnableiOES,
+ GLEnd,
+ GLEndConditionalRender,
+ GLEndList,
+ GLEndPerfMonitorAMD,
+ GLEndPixelLocalStorageANGLE,
+ GLEndQuery,
+ GLEndQueryEXT,
+ GLEndQueryIndexed,
+ GLEndTransformFeedback,
+ GLEvalCoord1d,
+ GLEvalCoord1dv,
+ GLEvalCoord1f,
+ GLEvalCoord1fv,
+ GLEvalCoord2d,
+ GLEvalCoord2dv,
+ GLEvalCoord2f,
+ GLEvalCoord2fv,
+ GLEvalMesh1,
+ GLEvalMesh2,
+ GLEvalPoint1,
+ GLEvalPoint2,
+ GLFeedbackBuffer,
+ GLFenceSync,
+ GLFinish,
+ GLFinishFenceNV,
+ GLFlush,
+ GLFlushMappedBufferRange,
+ GLFlushMappedBufferRangeEXT,
+ GLFlushMappedNamedBufferRange,
+ GLFogCoordPointer,
+ GLFogCoordd,
+ GLFogCoorddv,
+ GLFogCoordf,
+ GLFogCoordfv,
+ GLFogf,
+ GLFogfv,
+ GLFogi,
+ GLFogiv,
+ GLFogx,
+ GLFogxv,
+ GLFramebufferFetchBarrierEXT,
+ GLFramebufferMemorylessPixelLocalStorageANGLE,
+ GLFramebufferParameteri,
+ GLFramebufferParameteriMESA,
+ GLFramebufferRenderbuffer,
+ GLFramebufferRenderbufferOES,
+ GLFramebufferTexture,
+ GLFramebufferTexture1D,
+ GLFramebufferTexture2D,
+ GLFramebufferTexture2DMultisampleEXT,
+ GLFramebufferTexture2DOES,
+ GLFramebufferTexture3D,
+ GLFramebufferTexture3DOES,
+ GLFramebufferTextureEXT,
+ GLFramebufferTextureLayer,
+ GLFramebufferTextureMultiviewOVR,
+ GLFramebufferTextureOES,
+ GLFramebufferTexturePixelLocalStorageANGLE,
+ GLFrontFace,
+ GLFrustum,
+ GLFrustumf,
+ GLFrustumx,
+ GLGenBuffers,
+ GLGenFencesNV,
+ GLGenFramebuffers,
+ GLGenFramebuffersOES,
+ GLGenLists,
+ GLGenPerfMonitorsAMD,
+ GLGenProgramPipelines,
+ GLGenProgramPipelinesEXT,
+ GLGenQueries,
+ GLGenQueriesEXT,
+ GLGenRenderbuffers,
+ GLGenRenderbuffersOES,
+ GLGenSamplers,
+ GLGenSemaphoresEXT,
+ GLGenTextures,
+ GLGenTransformFeedbacks,
+ GLGenVertexArrays,
+ GLGenVertexArraysOES,
+ GLGenerateMipmap,
+ GLGenerateMipmapOES,
+ GLGenerateTextureMipmap,
+ GLGetActiveAtomicCounterBufferiv,
+ GLGetActiveAttrib,
+ GLGetActiveSubroutineName,
+ GLGetActiveSubroutineUniformName,
+ GLGetActiveSubroutineUniformiv,
+ GLGetActiveUniform,
+ GLGetActiveUniformBlockName,
+ GLGetActiveUniformBlockiv,
+ GLGetActiveUniformBlockivRobustANGLE,
+ GLGetActiveUniformName,
+ GLGetActiveUniformsiv,
+ GLGetAttachedShaders,
+ GLGetAttribLocation,
+ GLGetBooleani_v,
+ GLGetBooleani_vRobustANGLE,
+ GLGetBooleanv,
+ GLGetBooleanvRobustANGLE,
+ GLGetBufferParameteri64v,
+ GLGetBufferParameteri64vRobustANGLE,
+ GLGetBufferParameteriv,
+ GLGetBufferParameterivRobustANGLE,
+ GLGetBufferPointerv,
+ GLGetBufferPointervOES,
+ GLGetBufferPointervRobustANGLE,
+ GLGetBufferSubData,
+ GLGetClipPlane,
+ GLGetClipPlanef,
+ GLGetClipPlanex,
+ GLGetCompressedTexImage,
+ GLGetCompressedTexImageANGLE,
+ GLGetCompressedTextureImage,
+ GLGetCompressedTextureSubImage,
+ GLGetDebugMessageLog,
+ GLGetDebugMessageLogKHR,
+ GLGetDoublei_v,
+ GLGetDoublev,
+ GLGetError,
+ GLGetFenceivNV,
+ GLGetFixedv,
+ GLGetFloati_v,
+ GLGetFloatv,
+ GLGetFloatvRobustANGLE,
+ GLGetFragDataIndex,
+ GLGetFragDataIndexEXT,
+ GLGetFragDataLocation,
+ GLGetFramebufferAttachmentParameteriv,
+ GLGetFramebufferAttachmentParameterivOES,
+ GLGetFramebufferAttachmentParameterivRobustANGLE,
+ GLGetFramebufferParameteriv,
+ GLGetFramebufferParameterivMESA,
+ GLGetFramebufferParameterivRobustANGLE,
+ GLGetGraphicsResetStatus,
+ GLGetGraphicsResetStatusEXT,
+ GLGetInteger64i_v,
+ GLGetInteger64i_vRobustANGLE,
+ GLGetInteger64v,
+ GLGetInteger64vEXT,
+ GLGetInteger64vRobustANGLE,
+ GLGetIntegeri_v,
+ GLGetIntegeri_vRobustANGLE,
+ GLGetIntegerv,
+ GLGetIntegervRobustANGLE,
+ GLGetInternalformati64v,
+ GLGetInternalformativ,
+ GLGetInternalformativRobustANGLE,
+ GLGetLightfv,
+ GLGetLightiv,
+ GLGetLightxv,
+ GLGetMapdv,
+ GLGetMapfv,
+ GLGetMapiv,
+ GLGetMaterialfv,
+ GLGetMaterialiv,
+ GLGetMaterialxv,
+ GLGetMemoryObjectParameterivEXT,
+ GLGetMultisamplefv,
+ GLGetMultisamplefvANGLE,
+ GLGetMultisamplefvRobustANGLE,
+ GLGetNamedBufferParameteri64v,
+ GLGetNamedBufferParameteriv,
+ GLGetNamedBufferPointerv,
+ GLGetNamedBufferSubData,
+ GLGetNamedFramebufferAttachmentParameteriv,
+ GLGetNamedFramebufferParameteriv,
+ GLGetNamedRenderbufferParameteriv,
+ GLGetObjectLabel,
+ GLGetObjectLabelEXT,
+ GLGetObjectLabelKHR,
+ GLGetObjectPtrLabel,
+ GLGetObjectPtrLabelKHR,
+ GLGetPerfMonitorCounterDataAMD,
+ GLGetPerfMonitorCounterInfoAMD,
+ GLGetPerfMonitorCounterStringAMD,
+ GLGetPerfMonitorCountersAMD,
+ GLGetPerfMonitorGroupStringAMD,
+ GLGetPerfMonitorGroupsAMD,
+ GLGetPixelMapfv,
+ GLGetPixelMapuiv,
+ GLGetPixelMapusv,
+ GLGetPointerv,
+ GLGetPointervKHR,
+ GLGetPointervRobustANGLERobustANGLE,
+ GLGetPolygonStipple,
+ GLGetProgramBinary,
+ GLGetProgramBinaryOES,
+ GLGetProgramInfoLog,
+ GLGetProgramInterfaceiv,
+ GLGetProgramInterfaceivRobustANGLE,
+ GLGetProgramPipelineInfoLog,
+ GLGetProgramPipelineInfoLogEXT,
+ GLGetProgramPipelineiv,
+ GLGetProgramPipelineivEXT,
+ GLGetProgramResourceIndex,
+ GLGetProgramResourceLocation,
+ GLGetProgramResourceLocationIndex,
+ GLGetProgramResourceLocationIndexEXT,
+ GLGetProgramResourceName,
+ GLGetProgramResourceiv,
+ GLGetProgramStageiv,
+ GLGetProgramiv,
+ GLGetProgramivRobustANGLE,
+ GLGetQueryBufferObjecti64v,
+ GLGetQueryBufferObjectiv,
+ GLGetQueryBufferObjectui64v,
+ GLGetQueryBufferObjectuiv,
+ GLGetQueryIndexediv,
+ GLGetQueryObjecti64v,
+ GLGetQueryObjecti64vEXT,
+ GLGetQueryObjecti64vRobustANGLE,
+ GLGetQueryObjectiv,
+ GLGetQueryObjectivEXT,
+ GLGetQueryObjectivRobustANGLE,
+ GLGetQueryObjectui64v,
+ GLGetQueryObjectui64vEXT,
+ GLGetQueryObjectui64vRobustANGLE,
+ GLGetQueryObjectuiv,
+ GLGetQueryObjectuivEXT,
+ GLGetQueryObjectuivRobustANGLE,
+ GLGetQueryiv,
+ GLGetQueryivEXT,
+ GLGetQueryivRobustANGLE,
+ GLGetRenderbufferImageANGLE,
+ GLGetRenderbufferParameteriv,
+ GLGetRenderbufferParameterivOES,
+ GLGetRenderbufferParameterivRobustANGLE,
+ GLGetSamplerParameterIiv,
+ GLGetSamplerParameterIivEXT,
+ GLGetSamplerParameterIivOES,
+ GLGetSamplerParameterIivRobustANGLE,
+ GLGetSamplerParameterIuiv,
+ GLGetSamplerParameterIuivEXT,
+ GLGetSamplerParameterIuivOES,
+ GLGetSamplerParameterIuivRobustANGLE,
+ GLGetSamplerParameterfv,
+ GLGetSamplerParameterfvRobustANGLE,
+ GLGetSamplerParameteriv,
+ GLGetSamplerParameterivRobustANGLE,
+ GLGetSemaphoreParameterui64vEXT,
+ GLGetShaderInfoLog,
+ GLGetShaderPrecisionFormat,
+ GLGetShaderSource,
+ GLGetShaderiv,
+ GLGetShaderivRobustANGLE,
+ GLGetString,
+ GLGetStringi,
+ GLGetSubroutineIndex,
+ GLGetSubroutineUniformLocation,
+ GLGetSynciv,
+ GLGetTexEnvfv,
+ GLGetTexEnviv,
+ GLGetTexEnvxv,
+ GLGetTexGendv,
+ GLGetTexGenfv,
+ GLGetTexGenfvOES,
+ GLGetTexGeniv,
+ GLGetTexGenivOES,
+ GLGetTexGenxvOES,
+ GLGetTexImage,
+ GLGetTexImageANGLE,
+ GLGetTexLevelParameterfv,
+ GLGetTexLevelParameterfvANGLE,
+ GLGetTexLevelParameterfvRobustANGLE,
+ GLGetTexLevelParameteriv,
+ GLGetTexLevelParameterivANGLE,
+ GLGetTexLevelParameterivRobustANGLE,
+ GLGetTexParameterIiv,
+ GLGetTexParameterIivEXT,
+ GLGetTexParameterIivOES,
+ GLGetTexParameterIivRobustANGLE,
+ GLGetTexParameterIuiv,
+ GLGetTexParameterIuivEXT,
+ GLGetTexParameterIuivOES,
+ GLGetTexParameterIuivRobustANGLE,
+ GLGetTexParameterfv,
+ GLGetTexParameterfvRobustANGLE,
+ GLGetTexParameteriv,
+ GLGetTexParameterivRobustANGLE,
+ GLGetTexParameterxv,
+ GLGetTextureImage,
+ GLGetTextureLevelParameterfv,
+ GLGetTextureLevelParameteriv,
+ GLGetTextureParameterIiv,
+ GLGetTextureParameterIuiv,
+ GLGetTextureParameterfv,
+ GLGetTextureParameteriv,
+ GLGetTextureSubImage,
+ GLGetTransformFeedbackVarying,
+ GLGetTransformFeedbacki64_v,
+ GLGetTransformFeedbacki_v,
+ GLGetTransformFeedbackiv,
+ GLGetTranslatedShaderSourceANGLE,
+ GLGetUniformBlockIndex,
+ GLGetUniformIndices,
+ GLGetUniformLocation,
+ GLGetUniformSubroutineuiv,
+ GLGetUniformdv,
+ GLGetUniformfv,
+ GLGetUniformfvRobustANGLE,
+ GLGetUniformiv,
+ GLGetUniformivRobustANGLE,
+ GLGetUniformuiv,
+ GLGetUniformuivRobustANGLE,
+ GLGetUnsignedBytei_vEXT,
+ GLGetUnsignedBytevEXT,
+ GLGetVertexArrayIndexed64iv,
+ GLGetVertexArrayIndexediv,
+ GLGetVertexArrayiv,
+ GLGetVertexAttribIiv,
+ GLGetVertexAttribIivRobustANGLE,
+ GLGetVertexAttribIuiv,
+ GLGetVertexAttribIuivRobustANGLE,
+ GLGetVertexAttribLdv,
+ GLGetVertexAttribPointerv,
+ GLGetVertexAttribPointervRobustANGLE,
+ GLGetVertexAttribdv,
+ GLGetVertexAttribfv,
+ GLGetVertexAttribfvRobustANGLE,
+ GLGetVertexAttribiv,
+ GLGetVertexAttribivRobustANGLE,
+ GLGetnColorTable,
+ GLGetnCompressedTexImage,
+ GLGetnConvolutionFilter,
+ GLGetnHistogram,
+ GLGetnMapdv,
+ GLGetnMapfv,
+ GLGetnMapiv,
+ GLGetnMinmax,
+ GLGetnPixelMapfv,
+ GLGetnPixelMapuiv,
+ GLGetnPixelMapusv,
+ GLGetnPolygonStipple,
+ GLGetnSeparableFilter,
+ GLGetnTexImage,
+ GLGetnUniformdv,
+ GLGetnUniformfv,
+ GLGetnUniformfvEXT,
+ GLGetnUniformfvRobustANGLE,
+ GLGetnUniformiv,
+ GLGetnUniformivEXT,
+ GLGetnUniformivRobustANGLE,
+ GLGetnUniformuiv,
+ GLGetnUniformuivRobustANGLE,
+ GLHint,
+ GLImportMemoryFdEXT,
+ GLImportMemoryZirconHandleANGLE,
+ GLImportSemaphoreFdEXT,
+ GLImportSemaphoreZirconHandleANGLE,
+ GLIndexMask,
+ GLIndexPointer,
+ GLIndexd,
+ GLIndexdv,
+ GLIndexf,
+ GLIndexfv,
+ GLIndexi,
+ GLIndexiv,
+ GLIndexs,
+ GLIndexsv,
+ GLIndexub,
+ GLIndexubv,
+ GLInitNames,
+ GLInsertEventMarkerEXT,
+ GLInterleavedArrays,
+ GLInvalid,
+ GLInvalidateBufferData,
+ GLInvalidateBufferSubData,
+ GLInvalidateFramebuffer,
+ GLInvalidateNamedFramebufferData,
+ GLInvalidateNamedFramebufferSubData,
+ GLInvalidateSubFramebuffer,
+ GLInvalidateTexImage,
+ GLInvalidateTexSubImage,
+ GLInvalidateTextureANGLE,
+ GLIsBuffer,
+ GLIsEnabled,
+ GLIsEnabledi,
+ GLIsEnablediEXT,
+ GLIsEnablediOES,
+ GLIsFenceNV,
+ GLIsFramebuffer,
+ GLIsFramebufferOES,
+ GLIsList,
+ GLIsMemoryObjectEXT,
+ GLIsProgram,
+ GLIsProgramPipeline,
+ GLIsProgramPipelineEXT,
+ GLIsQuery,
+ GLIsQueryEXT,
+ GLIsRenderbuffer,
+ GLIsRenderbufferOES,
+ GLIsSampler,
+ GLIsSemaphoreEXT,
+ GLIsShader,
+ GLIsSync,
+ GLIsTexture,
+ GLIsTransformFeedback,
+ GLIsVertexArray,
+ GLIsVertexArrayOES,
+ GLLabelObjectEXT,
+ GLLightModelf,
+ GLLightModelfv,
+ GLLightModeli,
+ GLLightModeliv,
+ GLLightModelx,
+ GLLightModelxv,
+ GLLightf,
+ GLLightfv,
+ GLLighti,
+ GLLightiv,
+ GLLightx,
+ GLLightxv,
+ GLLineStipple,
+ GLLineWidth,
+ GLLineWidthx,
+ GLLinkProgram,
+ GLListBase,
+ GLLoadIdentity,
+ GLLoadMatrixd,
+ GLLoadMatrixf,
+ GLLoadMatrixx,
+ GLLoadName,
+ GLLoadPaletteFromModelViewMatrixOES,
+ GLLoadTransposeMatrixd,
+ GLLoadTransposeMatrixf,
+ GLLogicOp,
+ GLLogicOpANGLE,
+ GLLoseContextCHROMIUM,
+ GLMap1d,
+ GLMap1f,
+ GLMap2d,
+ GLMap2f,
+ GLMapBuffer,
+ GLMapBufferOES,
+ GLMapBufferRange,
+ GLMapBufferRangeEXT,
+ GLMapGrid1d,
+ GLMapGrid1f,
+ GLMapGrid2d,
+ GLMapGrid2f,
+ GLMapNamedBuffer,
+ GLMapNamedBufferRange,
+ GLMaterialf,
+ GLMaterialfv,
+ GLMateriali,
+ GLMaterialiv,
+ GLMaterialx,
+ GLMaterialxv,
+ GLMatrixIndexPointerOES,
+ GLMatrixMode,
+ GLMaxShaderCompilerThreadsKHR,
+ GLMemoryBarrier,
+ GLMemoryBarrierByRegion,
+ GLMemoryObjectParameterivEXT,
+ GLMinSampleShading,
+ GLMinSampleShadingOES,
+ GLMultMatrixd,
+ GLMultMatrixf,
+ GLMultMatrixx,
+ GLMultTransposeMatrixd,
+ GLMultTransposeMatrixf,
+ GLMultiDrawArrays,
+ GLMultiDrawArraysANGLE,
+ GLMultiDrawArraysIndirect,
+ GLMultiDrawArraysIndirectCount,
+ GLMultiDrawArraysIndirectEXT,
+ GLMultiDrawArraysInstancedANGLE,
+ GLMultiDrawArraysInstancedBaseInstanceANGLE,
+ GLMultiDrawElements,
+ GLMultiDrawElementsANGLE,
+ GLMultiDrawElementsBaseVertex,
+ GLMultiDrawElementsBaseVertexEXT,
+ GLMultiDrawElementsIndirect,
+ GLMultiDrawElementsIndirectCount,
+ GLMultiDrawElementsIndirectEXT,
+ GLMultiDrawElementsInstancedANGLE,
+ GLMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE,
+ GLMultiTexCoord1d,
+ GLMultiTexCoord1dv,
+ GLMultiTexCoord1f,
+ GLMultiTexCoord1fv,
+ GLMultiTexCoord1i,
+ GLMultiTexCoord1iv,
+ GLMultiTexCoord1s,
+ GLMultiTexCoord1sv,
+ GLMultiTexCoord2d,
+ GLMultiTexCoord2dv,
+ GLMultiTexCoord2f,
+ GLMultiTexCoord2fv,
+ GLMultiTexCoord2i,
+ GLMultiTexCoord2iv,
+ GLMultiTexCoord2s,
+ GLMultiTexCoord2sv,
+ GLMultiTexCoord3d,
+ GLMultiTexCoord3dv,
+ GLMultiTexCoord3f,
+ GLMultiTexCoord3fv,
+ GLMultiTexCoord3i,
+ GLMultiTexCoord3iv,
+ GLMultiTexCoord3s,
+ GLMultiTexCoord3sv,
+ GLMultiTexCoord4d,
+ GLMultiTexCoord4dv,
+ GLMultiTexCoord4f,
+ GLMultiTexCoord4fv,
+ GLMultiTexCoord4i,
+ GLMultiTexCoord4iv,
+ GLMultiTexCoord4s,
+ GLMultiTexCoord4sv,
+ GLMultiTexCoord4x,
+ GLMultiTexCoordP1ui,
+ GLMultiTexCoordP1uiv,
+ GLMultiTexCoordP2ui,
+ GLMultiTexCoordP2uiv,
+ GLMultiTexCoordP3ui,
+ GLMultiTexCoordP3uiv,
+ GLMultiTexCoordP4ui,
+ GLMultiTexCoordP4uiv,
+ GLNamedBufferData,
+ GLNamedBufferStorage,
+ GLNamedBufferStorageExternalEXT,
+ GLNamedBufferSubData,
+ GLNamedFramebufferDrawBuffer,
+ GLNamedFramebufferDrawBuffers,
+ GLNamedFramebufferParameteri,
+ GLNamedFramebufferReadBuffer,
+ GLNamedFramebufferRenderbuffer,
+ GLNamedFramebufferTexture,
+ GLNamedFramebufferTextureLayer,
+ GLNamedRenderbufferStorage,
+ GLNamedRenderbufferStorageMultisample,
+ GLNewList,
+ GLNormal3b,
+ GLNormal3bv,
+ GLNormal3d,
+ GLNormal3dv,
+ GLNormal3f,
+ GLNormal3fv,
+ GLNormal3i,
+ GLNormal3iv,
+ GLNormal3s,
+ GLNormal3sv,
+ GLNormal3x,
+ GLNormalP3ui,
+ GLNormalP3uiv,
+ GLNormalPointer,
+ GLObjectLabel,
+ GLObjectLabelKHR,
+ GLObjectPtrLabel,
+ GLObjectPtrLabelKHR,
+ GLOrtho,
+ GLOrthof,
+ GLOrthox,
+ GLPassThrough,
+ GLPatchParameterfv,
+ GLPatchParameteri,
+ GLPatchParameteriEXT,
+ GLPauseTransformFeedback,
+ GLPixelLocalStorageBarrierANGLE,
+ GLPixelMapfv,
+ GLPixelMapuiv,
+ GLPixelMapusv,
+ GLPixelStoref,
+ GLPixelStorei,
+ GLPixelTransferf,
+ GLPixelTransferi,
+ GLPixelZoom,
+ GLPointParameterf,
+ GLPointParameterfv,
+ GLPointParameteri,
+ GLPointParameteriv,
+ GLPointParameterx,
+ GLPointParameterxv,
+ GLPointSize,
+ GLPointSizePointerOES,
+ GLPointSizex,
+ GLPolygonMode,
+ GLPolygonOffset,
+ GLPolygonOffsetClamp,
+ GLPolygonOffsetx,
+ GLPolygonStipple,
+ GLPopAttrib,
+ GLPopClientAttrib,
+ GLPopDebugGroup,
+ GLPopDebugGroupKHR,
+ GLPopGroupMarkerEXT,
+ GLPopMatrix,
+ GLPopName,
+ GLPrimitiveBoundingBox,
+ GLPrimitiveBoundingBoxEXT,
+ GLPrimitiveBoundingBoxOES,
+ GLPrimitiveRestartIndex,
+ GLPrioritizeTextures,
+ GLProgramBinary,
+ GLProgramBinaryOES,
+ GLProgramParameteri,
+ GLProgramParameteriEXT,
+ GLProgramUniform1d,
+ GLProgramUniform1dv,
+ GLProgramUniform1f,
+ GLProgramUniform1fEXT,
+ GLProgramUniform1fv,
+ GLProgramUniform1fvEXT,
+ GLProgramUniform1i,
+ GLProgramUniform1iEXT,
+ GLProgramUniform1iv,
+ GLProgramUniform1ivEXT,
+ GLProgramUniform1ui,
+ GLProgramUniform1uiEXT,
+ GLProgramUniform1uiv,
+ GLProgramUniform1uivEXT,
+ GLProgramUniform2d,
+ GLProgramUniform2dv,
+ GLProgramUniform2f,
+ GLProgramUniform2fEXT,
+ GLProgramUniform2fv,
+ GLProgramUniform2fvEXT,
+ GLProgramUniform2i,
+ GLProgramUniform2iEXT,
+ GLProgramUniform2iv,
+ GLProgramUniform2ivEXT,
+ GLProgramUniform2ui,
+ GLProgramUniform2uiEXT,
+ GLProgramUniform2uiv,
+ GLProgramUniform2uivEXT,
+ GLProgramUniform3d,
+ GLProgramUniform3dv,
+ GLProgramUniform3f,
+ GLProgramUniform3fEXT,
+ GLProgramUniform3fv,
+ GLProgramUniform3fvEXT,
+ GLProgramUniform3i,
+ GLProgramUniform3iEXT,
+ GLProgramUniform3iv,
+ GLProgramUniform3ivEXT,
+ GLProgramUniform3ui,
+ GLProgramUniform3uiEXT,
+ GLProgramUniform3uiv,
+ GLProgramUniform3uivEXT,
+ GLProgramUniform4d,
+ GLProgramUniform4dv,
+ GLProgramUniform4f,
+ GLProgramUniform4fEXT,
+ GLProgramUniform4fv,
+ GLProgramUniform4fvEXT,
+ GLProgramUniform4i,
+ GLProgramUniform4iEXT,
+ GLProgramUniform4iv,
+ GLProgramUniform4ivEXT,
+ GLProgramUniform4ui,
+ GLProgramUniform4uiEXT,
+ GLProgramUniform4uiv,
+ GLProgramUniform4uivEXT,
+ GLProgramUniformMatrix2dv,
+ GLProgramUniformMatrix2fv,
+ GLProgramUniformMatrix2fvEXT,
+ GLProgramUniformMatrix2x3dv,
+ GLProgramUniformMatrix2x3fv,
+ GLProgramUniformMatrix2x3fvEXT,
+ GLProgramUniformMatrix2x4dv,
+ GLProgramUniformMatrix2x4fv,
+ GLProgramUniformMatrix2x4fvEXT,
+ GLProgramUniformMatrix3dv,
+ GLProgramUniformMatrix3fv,
+ GLProgramUniformMatrix3fvEXT,
+ GLProgramUniformMatrix3x2dv,
+ GLProgramUniformMatrix3x2fv,
+ GLProgramUniformMatrix3x2fvEXT,
+ GLProgramUniformMatrix3x4dv,
+ GLProgramUniformMatrix3x4fv,
+ GLProgramUniformMatrix3x4fvEXT,
+ GLProgramUniformMatrix4dv,
+ GLProgramUniformMatrix4fv,
+ GLProgramUniformMatrix4fvEXT,
+ GLProgramUniformMatrix4x2dv,
+ GLProgramUniformMatrix4x2fv,
+ GLProgramUniformMatrix4x2fvEXT,
+ GLProgramUniformMatrix4x3dv,
+ GLProgramUniformMatrix4x3fv,
+ GLProgramUniformMatrix4x3fvEXT,
+ GLProvokingVertex,
+ GLProvokingVertexANGLE,
+ GLPushAttrib,
+ GLPushClientAttrib,
+ GLPushDebugGroup,
+ GLPushDebugGroupKHR,
+ GLPushGroupMarkerEXT,
+ GLPushMatrix,
+ GLPushName,
+ GLQueryCounter,
+ GLQueryCounterEXT,
+ GLQueryMatrixxOES,
+ GLRasterPos2d,
+ GLRasterPos2dv,
+ GLRasterPos2f,
+ GLRasterPos2fv,
+ GLRasterPos2i,
+ GLRasterPos2iv,
+ GLRasterPos2s,
+ GLRasterPos2sv,
+ GLRasterPos3d,
+ GLRasterPos3dv,
+ GLRasterPos3f,
+ GLRasterPos3fv,
+ GLRasterPos3i,
+ GLRasterPos3iv,
+ GLRasterPos3s,
+ GLRasterPos3sv,
+ GLRasterPos4d,
+ GLRasterPos4dv,
+ GLRasterPos4f,
+ GLRasterPos4fv,
+ GLRasterPos4i,
+ GLRasterPos4iv,
+ GLRasterPos4s,
+ GLRasterPos4sv,
+ GLReadBuffer,
+ GLReadPixels,
+ GLReadPixelsRobustANGLE,
+ GLReadnPixels,
+ GLReadnPixelsEXT,
+ GLReadnPixelsRobustANGLE,
+ GLRectd,
+ GLRectdv,
+ GLRectf,
+ GLRectfv,
+ GLRecti,
+ GLRectiv,
+ GLRects,
+ GLRectsv,
+ GLReleaseShaderCompiler,
+ GLReleaseTexturesANGLE,
+ GLRenderMode,
+ GLRenderbufferStorage,
+ GLRenderbufferStorageMultisample,
+ GLRenderbufferStorageMultisampleANGLE,
+ GLRenderbufferStorageMultisampleEXT,
+ GLRenderbufferStorageOES,
+ GLRequestExtensionANGLE,
+ GLResumeTransformFeedback,
+ GLRotated,
+ GLRotatef,
+ GLRotatex,
+ GLSampleCoverage,
+ GLSampleCoveragex,
+ GLSampleMaski,
+ GLSampleMaskiANGLE,
+ GLSamplerParameterIiv,
+ GLSamplerParameterIivEXT,
+ GLSamplerParameterIivOES,
+ GLSamplerParameterIivRobustANGLE,
+ GLSamplerParameterIuiv,
+ GLSamplerParameterIuivEXT,
+ GLSamplerParameterIuivOES,
+ GLSamplerParameterIuivRobustANGLE,
+ GLSamplerParameterf,
+ GLSamplerParameterfv,
+ GLSamplerParameterfvRobustANGLE,
+ GLSamplerParameteri,
+ GLSamplerParameteriv,
+ GLSamplerParameterivRobustANGLE,
+ GLScaled,
+ GLScalef,
+ GLScalex,
+ GLScissor,
+ GLScissorArrayv,
+ GLScissorIndexed,
+ GLScissorIndexedv,
+ GLSecondaryColor3b,
+ GLSecondaryColor3bv,
+ GLSecondaryColor3d,
+ GLSecondaryColor3dv,
+ GLSecondaryColor3f,
+ GLSecondaryColor3fv,
+ GLSecondaryColor3i,
+ GLSecondaryColor3iv,
+ GLSecondaryColor3s,
+ GLSecondaryColor3sv,
+ GLSecondaryColor3ub,
+ GLSecondaryColor3ubv,
+ GLSecondaryColor3ui,
+ GLSecondaryColor3uiv,
+ GLSecondaryColor3us,
+ GLSecondaryColor3usv,
+ GLSecondaryColorP3ui,
+ GLSecondaryColorP3uiv,
+ GLSecondaryColorPointer,
+ GLSelectBuffer,
+ GLSelectPerfMonitorCountersAMD,
+ GLSemaphoreParameterui64vEXT,
+ GLSetFenceNV,
+ GLShadeModel,
+ GLShaderBinary,
+ GLShaderSource,
+ GLShaderStorageBlockBinding,
+ GLShadingRateQCOM,
+ GLSignalSemaphoreEXT,
+ GLSpecializeShader,
+ GLStencilFunc,
+ GLStencilFuncSeparate,
+ GLStencilMask,
+ GLStencilMaskSeparate,
+ GLStencilOp,
+ GLStencilOpSeparate,
+ GLTestFenceNV,
+ GLTexBuffer,
+ GLTexBufferEXT,
+ GLTexBufferOES,
+ GLTexBufferRange,
+ GLTexBufferRangeEXT,
+ GLTexBufferRangeOES,
+ GLTexCoord1d,
+ GLTexCoord1dv,
+ GLTexCoord1f,
+ GLTexCoord1fv,
+ GLTexCoord1i,
+ GLTexCoord1iv,
+ GLTexCoord1s,
+ GLTexCoord1sv,
+ GLTexCoord2d,
+ GLTexCoord2dv,
+ GLTexCoord2f,
+ GLTexCoord2fv,
+ GLTexCoord2i,
+ GLTexCoord2iv,
+ GLTexCoord2s,
+ GLTexCoord2sv,
+ GLTexCoord3d,
+ GLTexCoord3dv,
+ GLTexCoord3f,
+ GLTexCoord3fv,
+ GLTexCoord3i,
+ GLTexCoord3iv,
+ GLTexCoord3s,
+ GLTexCoord3sv,
+ GLTexCoord4d,
+ GLTexCoord4dv,
+ GLTexCoord4f,
+ GLTexCoord4fv,
+ GLTexCoord4i,
+ GLTexCoord4iv,
+ GLTexCoord4s,
+ GLTexCoord4sv,
+ GLTexCoordP1ui,
+ GLTexCoordP1uiv,
+ GLTexCoordP2ui,
+ GLTexCoordP2uiv,
+ GLTexCoordP3ui,
+ GLTexCoordP3uiv,
+ GLTexCoordP4ui,
+ GLTexCoordP4uiv,
+ GLTexCoordPointer,
+ GLTexEnvf,
+ GLTexEnvfv,
+ GLTexEnvi,
+ GLTexEnviv,
+ GLTexEnvx,
+ GLTexEnvxv,
+ GLTexGend,
+ GLTexGendv,
+ GLTexGenf,
+ GLTexGenfOES,
+ GLTexGenfv,
+ GLTexGenfvOES,
+ GLTexGeni,
+ GLTexGeniOES,
+ GLTexGeniv,
+ GLTexGenivOES,
+ GLTexGenxOES,
+ GLTexGenxvOES,
+ GLTexImage1D,
+ GLTexImage2D,
+ GLTexImage2DExternalANGLE,
+ GLTexImage2DMultisample,
+ GLTexImage2DRobustANGLE,
+ GLTexImage3D,
+ GLTexImage3DMultisample,
+ GLTexImage3DOES,
+ GLTexImage3DRobustANGLE,
+ GLTexParameterIiv,
+ GLTexParameterIivEXT,
+ GLTexParameterIivOES,
+ GLTexParameterIivRobustANGLE,
+ GLTexParameterIuiv,
+ GLTexParameterIuivEXT,
+ GLTexParameterIuivOES,
+ GLTexParameterIuivRobustANGLE,
+ GLTexParameterf,
+ GLTexParameterfv,
+ GLTexParameterfvRobustANGLE,
+ GLTexParameteri,
+ GLTexParameteriv,
+ GLTexParameterivRobustANGLE,
+ GLTexParameterx,
+ GLTexParameterxv,
+ GLTexStorage1D,
+ GLTexStorage1DEXT,
+ GLTexStorage2D,
+ GLTexStorage2DEXT,
+ GLTexStorage2DMultisample,
+ GLTexStorage2DMultisampleANGLE,
+ GLTexStorage3D,
+ GLTexStorage3DEXT,
+ GLTexStorage3DMultisample,
+ GLTexStorage3DMultisampleOES,
+ GLTexStorageMem2DEXT,
+ GLTexStorageMem2DMultisampleEXT,
+ GLTexStorageMem3DEXT,
+ GLTexStorageMem3DMultisampleEXT,
+ GLTexStorageMemFlags2DANGLE,
+ GLTexStorageMemFlags2DMultisampleANGLE,
+ GLTexStorageMemFlags3DANGLE,
+ GLTexStorageMemFlags3DMultisampleANGLE,
+ GLTexSubImage1D,
+ GLTexSubImage2D,
+ GLTexSubImage2DRobustANGLE,
+ GLTexSubImage3D,
+ GLTexSubImage3DOES,
+ GLTexSubImage3DRobustANGLE,
+ GLTextureBarrier,
+ GLTextureBuffer,
+ GLTextureBufferRange,
+ GLTextureParameterIiv,
+ GLTextureParameterIuiv,
+ GLTextureParameterf,
+ GLTextureParameterfv,
+ GLTextureParameteri,
+ GLTextureParameteriv,
+ GLTextureStorage1D,
+ GLTextureStorage2D,
+ GLTextureStorage2DMultisample,
+ GLTextureStorage3D,
+ GLTextureStorage3DMultisample,
+ GLTextureSubImage1D,
+ GLTextureSubImage2D,
+ GLTextureSubImage3D,
+ GLTextureView,
+ GLTransformFeedbackBufferBase,
+ GLTransformFeedbackBufferRange,
+ GLTransformFeedbackVaryings,
+ GLTranslated,
+ GLTranslatef,
+ GLTranslatex,
+ GLUniform1d,
+ GLUniform1dv,
+ GLUniform1f,
+ GLUniform1fv,
+ GLUniform1i,
+ GLUniform1iv,
+ GLUniform1ui,
+ GLUniform1uiv,
+ GLUniform2d,
+ GLUniform2dv,
+ GLUniform2f,
+ GLUniform2fv,
+ GLUniform2i,
+ GLUniform2iv,
+ GLUniform2ui,
+ GLUniform2uiv,
+ GLUniform3d,
+ GLUniform3dv,
+ GLUniform3f,
+ GLUniform3fv,
+ GLUniform3i,
+ GLUniform3iv,
+ GLUniform3ui,
+ GLUniform3uiv,
+ GLUniform4d,
+ GLUniform4dv,
+ GLUniform4f,
+ GLUniform4fv,
+ GLUniform4i,
+ GLUniform4iv,
+ GLUniform4ui,
+ GLUniform4uiv,
+ GLUniformBlockBinding,
+ GLUniformMatrix2dv,
+ GLUniformMatrix2fv,
+ GLUniformMatrix2x3dv,
+ GLUniformMatrix2x3fv,
+ GLUniformMatrix2x4dv,
+ GLUniformMatrix2x4fv,
+ GLUniformMatrix3dv,
+ GLUniformMatrix3fv,
+ GLUniformMatrix3x2dv,
+ GLUniformMatrix3x2fv,
+ GLUniformMatrix3x4dv,
+ GLUniformMatrix3x4fv,
+ GLUniformMatrix4dv,
+ GLUniformMatrix4fv,
+ GLUniformMatrix4x2dv,
+ GLUniformMatrix4x2fv,
+ GLUniformMatrix4x3dv,
+ GLUniformMatrix4x3fv,
+ GLUniformSubroutinesuiv,
+ GLUnmapBuffer,
+ GLUnmapBufferOES,
+ GLUnmapNamedBuffer,
+ GLUseProgram,
+ GLUseProgramStages,
+ GLUseProgramStagesEXT,
+ GLValidateProgram,
+ GLValidateProgramPipeline,
+ GLValidateProgramPipelineEXT,
+ GLVertex2d,
+ GLVertex2dv,
+ GLVertex2f,
+ GLVertex2fv,
+ GLVertex2i,
+ GLVertex2iv,
+ GLVertex2s,
+ GLVertex2sv,
+ GLVertex3d,
+ GLVertex3dv,
+ GLVertex3f,
+ GLVertex3fv,
+ GLVertex3i,
+ GLVertex3iv,
+ GLVertex3s,
+ GLVertex3sv,
+ GLVertex4d,
+ GLVertex4dv,
+ GLVertex4f,
+ GLVertex4fv,
+ GLVertex4i,
+ GLVertex4iv,
+ GLVertex4s,
+ GLVertex4sv,
+ GLVertexArrayAttribBinding,
+ GLVertexArrayAttribFormat,
+ GLVertexArrayAttribIFormat,
+ GLVertexArrayAttribLFormat,
+ GLVertexArrayBindingDivisor,
+ GLVertexArrayElementBuffer,
+ GLVertexArrayVertexBuffer,
+ GLVertexArrayVertexBuffers,
+ GLVertexAttrib1d,
+ GLVertexAttrib1dv,
+ GLVertexAttrib1f,
+ GLVertexAttrib1fv,
+ GLVertexAttrib1s,
+ GLVertexAttrib1sv,
+ GLVertexAttrib2d,
+ GLVertexAttrib2dv,
+ GLVertexAttrib2f,
+ GLVertexAttrib2fv,
+ GLVertexAttrib2s,
+ GLVertexAttrib2sv,
+ GLVertexAttrib3d,
+ GLVertexAttrib3dv,
+ GLVertexAttrib3f,
+ GLVertexAttrib3fv,
+ GLVertexAttrib3s,
+ GLVertexAttrib3sv,
+ GLVertexAttrib4Nbv,
+ GLVertexAttrib4Niv,
+ GLVertexAttrib4Nsv,
+ GLVertexAttrib4Nub,
+ GLVertexAttrib4Nubv,
+ GLVertexAttrib4Nuiv,
+ GLVertexAttrib4Nusv,
+ GLVertexAttrib4bv,
+ GLVertexAttrib4d,
+ GLVertexAttrib4dv,
+ GLVertexAttrib4f,
+ GLVertexAttrib4fv,
+ GLVertexAttrib4iv,
+ GLVertexAttrib4s,
+ GLVertexAttrib4sv,
+ GLVertexAttrib4ubv,
+ GLVertexAttrib4uiv,
+ GLVertexAttrib4usv,
+ GLVertexAttribBinding,
+ GLVertexAttribDivisor,
+ GLVertexAttribDivisorANGLE,
+ GLVertexAttribDivisorEXT,
+ GLVertexAttribFormat,
+ GLVertexAttribI1i,
+ GLVertexAttribI1iv,
+ GLVertexAttribI1ui,
+ GLVertexAttribI1uiv,
+ GLVertexAttribI2i,
+ GLVertexAttribI2iv,
+ GLVertexAttribI2ui,
+ GLVertexAttribI2uiv,
+ GLVertexAttribI3i,
+ GLVertexAttribI3iv,
+ GLVertexAttribI3ui,
+ GLVertexAttribI3uiv,
+ GLVertexAttribI4bv,
+ GLVertexAttribI4i,
+ GLVertexAttribI4iv,
+ GLVertexAttribI4sv,
+ GLVertexAttribI4ubv,
+ GLVertexAttribI4ui,
+ GLVertexAttribI4uiv,
+ GLVertexAttribI4usv,
+ GLVertexAttribIFormat,
+ GLVertexAttribIPointer,
+ GLVertexAttribL1d,
+ GLVertexAttribL1dv,
+ GLVertexAttribL2d,
+ GLVertexAttribL2dv,
+ GLVertexAttribL3d,
+ GLVertexAttribL3dv,
+ GLVertexAttribL4d,
+ GLVertexAttribL4dv,
+ GLVertexAttribLFormat,
+ GLVertexAttribLPointer,
+ GLVertexAttribP1ui,
+ GLVertexAttribP1uiv,
+ GLVertexAttribP2ui,
+ GLVertexAttribP2uiv,
+ GLVertexAttribP3ui,
+ GLVertexAttribP3uiv,
+ GLVertexAttribP4ui,
+ GLVertexAttribP4uiv,
+ GLVertexAttribPointer,
+ GLVertexBindingDivisor,
+ GLVertexP2ui,
+ GLVertexP2uiv,
+ GLVertexP3ui,
+ GLVertexP3uiv,
+ GLVertexP4ui,
+ GLVertexP4uiv,
+ GLVertexPointer,
+ GLViewport,
+ GLViewportArrayv,
+ GLViewportIndexedf,
+ GLViewportIndexedfv,
+ GLWaitSemaphoreEXT,
+ GLWaitSync,
+ GLWeightPointerOES,
+ GLWindowPos2d,
+ GLWindowPos2dv,
+ GLWindowPos2f,
+ GLWindowPos2fv,
+ GLWindowPos2i,
+ GLWindowPos2iv,
+ GLWindowPos2s,
+ GLWindowPos2sv,
+ GLWindowPos3d,
+ GLWindowPos3dv,
+ GLWindowPos3f,
+ GLWindowPos3fv,
+ GLWindowPos3i,
+ GLWindowPos3iv,
+ GLWindowPos3s,
+ GLWindowPos3sv,
+ WGLChoosePixelFormat,
+ WGLCopyContext,
+ WGLCreateContext,
+ WGLCreateLayerContext,
+ WGLDeleteContext,
+ WGLDescribeLayerPlane,
+ WGLDescribePixelFormat,
+ WGLGetCurrentContext,
+ WGLGetCurrentDC,
+ WGLGetEnhMetaFilePixelFormat,
+ WGLGetLayerPaletteEntries,
+ WGLGetPixelFormat,
+ WGLGetProcAddress,
+ WGLMakeCurrent,
+ WGLRealizeLayerPalette,
+ WGLSetLayerPaletteEntries,
+ WGLSetPixelFormat,
+ WGLShareLists,
+ WGLSwapBuffers,
+ WGLSwapLayerBuffers,
+ WGLUseFontBitmaps,
+ WGLUseFontBitmapsA,
+ WGLUseFontBitmapsW,
+ WGLUseFontOutlines,
+ WGLUseFontOutlinesA,
+ WGLUseFontOutlinesW
+};
+
+const char *GetEntryPointName(EntryPoint ep);
+} // namespace angle
+#endif // COMMON_ENTRY_POINTS_ENUM_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/common/event_tracer.cpp b/gfx/angle/checkout/src/common/event_tracer.cpp
new file mode 100644
index 0000000000..151cb2cd70
--- /dev/null
+++ b/gfx/angle/checkout/src/common/event_tracer.cpp
@@ -0,0 +1,53 @@
+// Copyright 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 "common/event_tracer.h"
+
+#include "common/debug.h"
+
+namespace angle
+{
+
+const unsigned char *GetTraceCategoryEnabledFlag(PlatformMethods *platform, const char *name)
+{
+ ASSERT(platform);
+
+ const unsigned char *categoryEnabledFlag =
+ platform->getTraceCategoryEnabledFlag(platform, name);
+ if (categoryEnabledFlag != nullptr)
+ {
+ return categoryEnabledFlag;
+ }
+
+ static unsigned char disabled = 0;
+ return &disabled;
+}
+
+angle::TraceEventHandle AddTraceEvent(PlatformMethods *platform,
+ char phase,
+ const unsigned char *categoryGroupEnabled,
+ const char *name,
+ unsigned long long id,
+ int numArgs,
+ const char **argNames,
+ const unsigned char *argTypes,
+ const unsigned long long *argValues,
+ unsigned char flags)
+{
+ ASSERT(platform);
+
+ double timestamp = platform->monotonicallyIncreasingTime(platform);
+
+ if (timestamp != 0)
+ {
+ angle::TraceEventHandle handle =
+ platform->addTraceEvent(platform, phase, categoryGroupEnabled, name, id, timestamp,
+ numArgs, argNames, argTypes, argValues, flags);
+ return handle;
+ }
+
+ return static_cast<angle::TraceEventHandle>(0);
+}
+
+} // namespace angle
diff --git a/gfx/angle/checkout/src/common/event_tracer.h b/gfx/angle/checkout/src/common/event_tracer.h
new file mode 100644
index 0000000000..128d88b9e0
--- /dev/null
+++ b/gfx/angle/checkout/src/common/event_tracer.h
@@ -0,0 +1,26 @@
+// Copyright 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 COMMON_EVENT_TRACER_H_
+#define COMMON_EVENT_TRACER_H_
+
+#include "common/platform.h"
+#include "platform/PlatformMethods.h"
+
+namespace angle
+{
+const unsigned char *GetTraceCategoryEnabledFlag(PlatformMethods *platform, const char *name);
+angle::TraceEventHandle AddTraceEvent(PlatformMethods *platform,
+ char phase,
+ const unsigned char *categoryGroupEnabled,
+ const char *name,
+ unsigned long long id,
+ int numArgs,
+ const char **argNames,
+ const unsigned char *argTypes,
+ const unsigned long long *argValues,
+ unsigned char flags);
+} // namespace angle
+
+#endif // COMMON_EVENT_TRACER_H_
diff --git a/gfx/angle/checkout/src/common/hash_utils.h b/gfx/angle/checkout/src/common/hash_utils.h
new file mode 100644
index 0000000000..aec4e7f77c
--- /dev/null
+++ b/gfx/angle/checkout/src/common/hash_utils.h
@@ -0,0 +1,39 @@
+//
+// Copyright 2018 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.
+//
+// hash_utils.h: Hashing based helper functions.
+
+#ifndef COMMON_HASHUTILS_H_
+#define COMMON_HASHUTILS_H_
+
+#include "common/debug.h"
+#include "common/third_party/xxhash/xxhash.h"
+
+namespace angle
+{
+// Computes a hash of "key". Any data passed to this function must be multiples of
+// 4 bytes, since the PMurHash32 method can only operate increments of 4-byte words.
+inline std::size_t ComputeGenericHash(const void *key, size_t keySize)
+{
+ static constexpr unsigned int kSeed = 0xABCDEF98;
+
+ // We can't support "odd" alignments. ComputeGenericHash requires aligned types
+ ASSERT(keySize % 4 == 0);
+#if defined(ANGLE_IS_64_BIT_CPU)
+ return XXH64(key, keySize, kSeed);
+#else
+ return XXH32(key, keySize, kSeed);
+#endif // defined(ANGLE_IS_64_BIT_CPU)
+}
+
+template <typename T>
+std::size_t ComputeGenericHash(const T &key)
+{
+ static_assert(sizeof(key) % 4 == 0, "ComputeGenericHash requires aligned types");
+ return ComputeGenericHash(&key, sizeof(key));
+}
+} // namespace angle
+
+#endif // COMMON_HASHUTILS_H_
diff --git a/gfx/angle/checkout/src/common/mathutil.cpp b/gfx/angle/checkout/src/common/mathutil.cpp
new file mode 100644
index 0000000000..5cbc6a920a
--- /dev/null
+++ b/gfx/angle/checkout/src/common/mathutil.cpp
@@ -0,0 +1,83 @@
+//
+// Copyright 2013 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.
+//
+
+// mathutil.cpp: Math and bit manipulation functions.
+
+#include "common/mathutil.h"
+
+#include <math.h>
+#include <algorithm>
+
+namespace gl
+{
+
+namespace
+{
+
+struct RGB9E5Data
+{
+ unsigned int R : 9;
+ unsigned int G : 9;
+ unsigned int B : 9;
+ unsigned int E : 5;
+};
+
+// B is the exponent bias (15)
+constexpr int g_sharedexp_bias = 15;
+
+// N is the number of mantissa bits per component (9)
+constexpr int g_sharedexp_mantissabits = 9;
+
+// number of mantissa bits per component pre-biased
+constexpr int g_sharedexp_biased_mantissabits = g_sharedexp_bias + g_sharedexp_mantissabits;
+
+// Emax is the maximum allowed biased exponent value (31)
+constexpr int g_sharedexp_maxexponent = 31;
+
+constexpr float g_sharedexp_max =
+ ((static_cast<float>(1 << g_sharedexp_mantissabits) - 1) /
+ static_cast<float>(1 << g_sharedexp_mantissabits)) *
+ static_cast<float>(1 << (g_sharedexp_maxexponent - g_sharedexp_bias));
+
+} // anonymous namespace
+
+unsigned int convertRGBFloatsTo999E5(float red, float green, float blue)
+{
+ const float red_c = std::max<float>(0, std::min(g_sharedexp_max, red));
+ const float green_c = std::max<float>(0, std::min(g_sharedexp_max, green));
+ const float blue_c = std::max<float>(0, std::min(g_sharedexp_max, blue));
+
+ const float max_c = std::max<float>(std::max<float>(red_c, green_c), blue_c);
+ const float exp_p =
+ std::max<float>(-g_sharedexp_bias - 1, floor(log(max_c))) + 1 + g_sharedexp_bias;
+ const int max_s = static_cast<int>(
+ floor((max_c / (pow(2.0f, exp_p - g_sharedexp_biased_mantissabits))) + 0.5f));
+ const int exp_s =
+ static_cast<int>((max_s < pow(2.0f, g_sharedexp_mantissabits)) ? exp_p : exp_p + 1);
+ const float pow2_exp = pow(2.0f, static_cast<float>(exp_s) - g_sharedexp_biased_mantissabits);
+
+ RGB9E5Data output;
+ output.R = static_cast<unsigned int>(floor((red_c / pow2_exp) + 0.5f));
+ output.G = static_cast<unsigned int>(floor((green_c / pow2_exp) + 0.5f));
+ output.B = static_cast<unsigned int>(floor((blue_c / pow2_exp) + 0.5f));
+ output.E = exp_s;
+
+ return bitCast<unsigned int>(output);
+}
+
+void convert999E5toRGBFloats(unsigned int input, float *red, float *green, float *blue)
+{
+ const RGB9E5Data *inputData = reinterpret_cast<const RGB9E5Data *>(&input);
+
+ const float pow2_exp =
+ pow(2.0f, static_cast<float>(inputData->E) - g_sharedexp_biased_mantissabits);
+
+ *red = inputData->R * pow2_exp;
+ *green = inputData->G * pow2_exp;
+ *blue = inputData->B * pow2_exp;
+}
+
+} // namespace gl
diff --git a/gfx/angle/checkout/src/common/mathutil.h b/gfx/angle/checkout/src/common/mathutil.h
new file mode 100644
index 0000000000..560929239f
--- /dev/null
+++ b/gfx/angle/checkout/src/common/mathutil.h
@@ -0,0 +1,1482 @@
+//
+// Copyright 2002 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.
+//
+
+// mathutil.h: Math and bit manipulation functions.
+
+#ifndef COMMON_MATHUTIL_H_
+#define COMMON_MATHUTIL_H_
+
+#include <math.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <algorithm>
+#include <limits>
+
+#include <anglebase/numerics/safe_math.h>
+
+#include "common/debug.h"
+#include "common/platform.h"
+
+namespace angle
+{
+using base::CheckedNumeric;
+using base::IsValueInRangeForNumericType;
+} // namespace angle
+
+namespace gl
+{
+
+const unsigned int Float32One = 0x3F800000;
+const unsigned short Float16One = 0x3C00;
+
+template <typename T>
+inline constexpr bool isPow2(T x)
+{
+ static_assert(std::is_integral<T>::value, "isPow2 must be called on an integer type.");
+ return (x & (x - 1)) == 0 && (x != 0);
+}
+
+template <typename T>
+inline int log2(T x)
+{
+ static_assert(std::is_integral<T>::value, "log2 must be called on an integer type.");
+ int r = 0;
+ while ((x >> r) > 1)
+ r++;
+ return r;
+}
+
+inline unsigned int ceilPow2(unsigned int x)
+{
+ if (x != 0)
+ x--;
+ x |= x >> 1;
+ x |= x >> 2;
+ x |= x >> 4;
+ x |= x >> 8;
+ x |= x >> 16;
+ x++;
+
+ return x;
+}
+
+template <typename DestT, typename SrcT>
+inline DestT clampCast(SrcT value)
+{
+ // For floating-point types with denormalization, min returns the minimum positive normalized
+ // value. To find the value that has no values less than it, use numeric_limits::lowest.
+ constexpr const long double destLo =
+ static_cast<long double>(std::numeric_limits<DestT>::lowest());
+ constexpr const long double destHi =
+ static_cast<long double>(std::numeric_limits<DestT>::max());
+ constexpr const long double srcLo =
+ static_cast<long double>(std::numeric_limits<SrcT>::lowest());
+ constexpr long double srcHi = static_cast<long double>(std::numeric_limits<SrcT>::max());
+
+ if (destHi < srcHi)
+ {
+ DestT destMax = std::numeric_limits<DestT>::max();
+ if (value >= static_cast<SrcT>(destMax))
+ {
+ return destMax;
+ }
+ }
+
+ if (destLo > srcLo)
+ {
+ DestT destLow = std::numeric_limits<DestT>::lowest();
+ if (value <= static_cast<SrcT>(destLow))
+ {
+ return destLow;
+ }
+ }
+
+ return static_cast<DestT>(value);
+}
+
+// Specialize clampCast for bool->int conversion to avoid MSVS 2015 performance warning when the max
+// value is casted to the source type.
+template <>
+inline unsigned int clampCast(bool value)
+{
+ return static_cast<unsigned int>(value);
+}
+
+template <>
+inline int clampCast(bool value)
+{
+ return static_cast<int>(value);
+}
+
+template <typename T, typename MIN, typename MAX>
+inline T clamp(T x, MIN min, MAX max)
+{
+ // Since NaNs fail all comparison tests, a NaN value will default to min
+ return x > min ? (x > max ? max : x) : min;
+}
+
+template <typename T>
+T clampForBitCount(T value, size_t bitCount)
+{
+ static_assert(std::numeric_limits<T>::is_integer, "T must be an integer.");
+
+ if (bitCount == 0)
+ {
+ constexpr T kZero = 0;
+ return kZero;
+ }
+ ASSERT(bitCount <= sizeof(T) * 8);
+
+ constexpr bool kIsSigned = std::numeric_limits<T>::is_signed;
+ ASSERT((bitCount > 1) || !kIsSigned);
+
+ T min = 0;
+ T max = 0;
+ if (bitCount == sizeof(T) * 8)
+ {
+ min = std::numeric_limits<T>::min();
+ max = std::numeric_limits<T>::max();
+ }
+ else
+ {
+ constexpr T kOne = 1;
+ min = (kIsSigned) ? -1 * (kOne << (bitCount - 1)) : 0;
+ max = (kIsSigned) ? (kOne << (bitCount - 1)) - 1 : (kOne << bitCount) - 1;
+ }
+
+ return gl::clamp(value, min, max);
+}
+
+inline float clamp01(float x)
+{
+ return clamp(x, 0.0f, 1.0f);
+}
+
+template <const int n>
+inline unsigned int unorm(float x)
+{
+ const unsigned int max = 0xFFFFFFFF >> (32 - n);
+
+ if (x > 1)
+ {
+ return max;
+ }
+ else if (x < 0)
+ {
+ return 0;
+ }
+ else
+ {
+ return (unsigned int)(max * x + 0.5f);
+ }
+}
+
+inline bool supportsSSE2()
+{
+#if defined(ANGLE_USE_SSE)
+ static bool checked = false;
+ static bool supports = false;
+
+ if (checked)
+ {
+ return supports;
+ }
+
+# if defined(ANGLE_PLATFORM_WINDOWS) && !defined(_M_ARM) && !defined(_M_ARM64)
+ {
+ int info[4];
+ __cpuid(info, 0);
+
+ if (info[0] >= 1)
+ {
+ __cpuid(info, 1);
+
+ supports = (info[3] >> 26) & 1;
+ }
+ }
+# endif // defined(ANGLE_PLATFORM_WINDOWS) && !defined(_M_ARM) && !defined(_M_ARM64)
+ checked = true;
+ return supports;
+#else // defined(ANGLE_USE_SSE)
+ return false;
+#endif
+}
+
+template <typename destType, typename sourceType>
+destType bitCast(const sourceType &source)
+{
+ size_t copySize = std::min(sizeof(destType), sizeof(sourceType));
+ destType output;
+ memcpy(&output, &source, copySize);
+ return output;
+}
+
+// https://stackoverflow.com/a/37581284
+template <typename T>
+static constexpr double normalize(T value)
+{
+ return value < 0 ? -static_cast<double>(value) / std::numeric_limits<T>::min()
+ : static_cast<double>(value) / std::numeric_limits<T>::max();
+}
+
+inline unsigned short float32ToFloat16(float fp32)
+{
+ unsigned int fp32i = bitCast<unsigned int>(fp32);
+ unsigned int sign = (fp32i & 0x80000000) >> 16;
+ unsigned int abs = fp32i & 0x7FFFFFFF;
+
+ if (abs > 0x7F800000)
+ { // NaN
+ return 0x7FFF;
+ }
+ else if (abs > 0x47FFEFFF)
+ { // Infinity
+ return static_cast<uint16_t>(sign | 0x7C00);
+ }
+ else if (abs < 0x38800000) // Denormal
+ {
+ unsigned int mantissa = (abs & 0x007FFFFF) | 0x00800000;
+ int e = 113 - (abs >> 23);
+
+ if (e < 24)
+ {
+ abs = mantissa >> e;
+ }
+ else
+ {
+ abs = 0;
+ }
+
+ return static_cast<unsigned short>(sign | (abs + 0x00000FFF + ((abs >> 13) & 1)) >> 13);
+ }
+ else
+ {
+ return static_cast<unsigned short>(
+ sign | (abs + 0xC8000000 + 0x00000FFF + ((abs >> 13) & 1)) >> 13);
+ }
+}
+
+float float16ToFloat32(unsigned short h);
+
+unsigned int convertRGBFloatsTo999E5(float red, float green, float blue);
+void convert999E5toRGBFloats(unsigned int input, float *red, float *green, float *blue);
+
+inline unsigned short float32ToFloat11(float fp32)
+{
+ const unsigned int float32MantissaMask = 0x7FFFFF;
+ const unsigned int float32ExponentMask = 0x7F800000;
+ const unsigned int float32SignMask = 0x80000000;
+ const unsigned int float32ValueMask = ~float32SignMask;
+ const unsigned int float32ExponentFirstBit = 23;
+ const unsigned int float32ExponentBias = 127;
+
+ const unsigned short float11Max = 0x7BF;
+ const unsigned short float11MantissaMask = 0x3F;
+ const unsigned short float11ExponentMask = 0x7C0;
+ const unsigned short float11BitMask = 0x7FF;
+ const unsigned int float11ExponentBias = 14;
+
+ const unsigned int float32Maxfloat11 = 0x477E0000;
+ const unsigned int float32MinNormfloat11 = 0x38800000;
+ const unsigned int float32MinDenormfloat11 = 0x35000080;
+
+ const unsigned int float32Bits = bitCast<unsigned int>(fp32);
+ const bool float32Sign = (float32Bits & float32SignMask) == float32SignMask;
+
+ unsigned int float32Val = float32Bits & float32ValueMask;
+
+ if ((float32Val & float32ExponentMask) == float32ExponentMask)
+ {
+ // INF or NAN
+ if ((float32Val & float32MantissaMask) != 0)
+ {
+ return float11ExponentMask |
+ (((float32Val >> 17) | (float32Val >> 11) | (float32Val >> 6) | (float32Val)) &
+ float11MantissaMask);
+ }
+ else if (float32Sign)
+ {
+ // -INF is clamped to 0 since float11 is positive only
+ return 0;
+ }
+ else
+ {
+ return float11ExponentMask;
+ }
+ }
+ else if (float32Sign)
+ {
+ // float11 is positive only, so clamp to zero
+ return 0;
+ }
+ else if (float32Val > float32Maxfloat11)
+ {
+ // The number is too large to be represented as a float11, set to max
+ return float11Max;
+ }
+ else if (float32Val < float32MinDenormfloat11)
+ {
+ // The number is too small to be represented as a denormalized float11, set to 0
+ return 0;
+ }
+ else
+ {
+ if (float32Val < float32MinNormfloat11)
+ {
+ // The number is too small to be represented as a normalized float11
+ // Convert it to a denormalized value.
+ const unsigned int shift = (float32ExponentBias - float11ExponentBias) -
+ (float32Val >> float32ExponentFirstBit);
+ ASSERT(shift < 32);
+ float32Val =
+ ((1 << float32ExponentFirstBit) | (float32Val & float32MantissaMask)) >> shift;
+ }
+ else
+ {
+ // Rebias the exponent to represent the value as a normalized float11
+ float32Val += 0xC8000000;
+ }
+
+ return ((float32Val + 0xFFFF + ((float32Val >> 17) & 1)) >> 17) & float11BitMask;
+ }
+}
+
+inline unsigned short float32ToFloat10(float fp32)
+{
+ const unsigned int float32MantissaMask = 0x7FFFFF;
+ const unsigned int float32ExponentMask = 0x7F800000;
+ const unsigned int float32SignMask = 0x80000000;
+ const unsigned int float32ValueMask = ~float32SignMask;
+ const unsigned int float32ExponentFirstBit = 23;
+ const unsigned int float32ExponentBias = 127;
+
+ const unsigned short float10Max = 0x3DF;
+ const unsigned short float10MantissaMask = 0x1F;
+ const unsigned short float10ExponentMask = 0x3E0;
+ const unsigned short float10BitMask = 0x3FF;
+ const unsigned int float10ExponentBias = 14;
+
+ const unsigned int float32Maxfloat10 = 0x477C0000;
+ const unsigned int float32MinNormfloat10 = 0x38800000;
+ const unsigned int float32MinDenormfloat10 = 0x35800040;
+
+ const unsigned int float32Bits = bitCast<unsigned int>(fp32);
+ const bool float32Sign = (float32Bits & float32SignMask) == float32SignMask;
+
+ unsigned int float32Val = float32Bits & float32ValueMask;
+
+ if ((float32Val & float32ExponentMask) == float32ExponentMask)
+ {
+ // INF or NAN
+ if ((float32Val & float32MantissaMask) != 0)
+ {
+ return float10ExponentMask |
+ (((float32Val >> 18) | (float32Val >> 13) | (float32Val >> 3) | (float32Val)) &
+ float10MantissaMask);
+ }
+ else if (float32Sign)
+ {
+ // -INF is clamped to 0 since float10 is positive only
+ return 0;
+ }
+ else
+ {
+ return float10ExponentMask;
+ }
+ }
+ else if (float32Sign)
+ {
+ // float10 is positive only, so clamp to zero
+ return 0;
+ }
+ else if (float32Val > float32Maxfloat10)
+ {
+ // The number is too large to be represented as a float10, set to max
+ return float10Max;
+ }
+ else if (float32Val < float32MinDenormfloat10)
+ {
+ // The number is too small to be represented as a denormalized float10, set to 0
+ return 0;
+ }
+ else
+ {
+ if (float32Val < float32MinNormfloat10)
+ {
+ // The number is too small to be represented as a normalized float10
+ // Convert it to a denormalized value.
+ const unsigned int shift = (float32ExponentBias - float10ExponentBias) -
+ (float32Val >> float32ExponentFirstBit);
+ ASSERT(shift < 32);
+ float32Val =
+ ((1 << float32ExponentFirstBit) | (float32Val & float32MantissaMask)) >> shift;
+ }
+ else
+ {
+ // Rebias the exponent to represent the value as a normalized float10
+ float32Val += 0xC8000000;
+ }
+
+ return ((float32Val + 0x1FFFF + ((float32Val >> 18) & 1)) >> 18) & float10BitMask;
+ }
+}
+
+inline float float11ToFloat32(unsigned short fp11)
+{
+ unsigned short exponent = (fp11 >> 6) & 0x1F;
+ unsigned short mantissa = fp11 & 0x3F;
+
+ if (exponent == 0x1F)
+ {
+ // INF or NAN
+ return bitCast<float>(0x7f800000 | (mantissa << 17));
+ }
+ else
+ {
+ if (exponent != 0)
+ {
+ // normalized
+ }
+ else if (mantissa != 0)
+ {
+ // The value is denormalized
+ exponent = 1;
+
+ do
+ {
+ exponent--;
+ mantissa <<= 1;
+ } while ((mantissa & 0x40) == 0);
+
+ mantissa = mantissa & 0x3F;
+ }
+ else // The value is zero
+ {
+ exponent = static_cast<unsigned short>(-112);
+ }
+
+ return bitCast<float>(((exponent + 112) << 23) | (mantissa << 17));
+ }
+}
+
+inline float float10ToFloat32(unsigned short fp10)
+{
+ unsigned short exponent = (fp10 >> 5) & 0x1F;
+ unsigned short mantissa = fp10 & 0x1F;
+
+ if (exponent == 0x1F)
+ {
+ // INF or NAN
+ return bitCast<float>(0x7f800000 | (mantissa << 17));
+ }
+ else
+ {
+ if (exponent != 0)
+ {
+ // normalized
+ }
+ else if (mantissa != 0)
+ {
+ // The value is denormalized
+ exponent = 1;
+
+ do
+ {
+ exponent--;
+ mantissa <<= 1;
+ } while ((mantissa & 0x20) == 0);
+
+ mantissa = mantissa & 0x1F;
+ }
+ else // The value is zero
+ {
+ exponent = static_cast<unsigned short>(-112);
+ }
+
+ return bitCast<float>(((exponent + 112) << 23) | (mantissa << 18));
+ }
+}
+
+// Converts to and from float and 16.16 fixed point format.
+inline float ConvertFixedToFloat(int32_t fixedInput)
+{
+ return static_cast<float>(fixedInput) / 65536.0f;
+}
+
+inline uint32_t ConvertFloatToFixed(float floatInput)
+{
+ static constexpr uint32_t kHighest = 32767 * 65536 + 65535;
+ static constexpr uint32_t kLowest = static_cast<uint32_t>(-32768 * 65536 + 65535);
+
+ if (floatInput > 32767.65535)
+ {
+ return kHighest;
+ }
+ else if (floatInput < -32768.65535)
+ {
+ return kLowest;
+ }
+ else
+ {
+ return static_cast<uint32_t>(floatInput * 65536);
+ }
+}
+
+template <typename T>
+inline float normalizedToFloat(T input)
+{
+ static_assert(std::numeric_limits<T>::is_integer, "T must be an integer.");
+
+ if (sizeof(T) > 2)
+ {
+ // float has only a 23 bit mantissa, so we need to do the calculation in double precision
+ constexpr double inverseMax = 1.0 / std::numeric_limits<T>::max();
+ return static_cast<float>(input * inverseMax);
+ }
+ else
+ {
+ constexpr float inverseMax = 1.0f / std::numeric_limits<T>::max();
+ return input * inverseMax;
+ }
+}
+
+template <unsigned int inputBitCount, typename T>
+inline float normalizedToFloat(T input)
+{
+ static_assert(std::numeric_limits<T>::is_integer, "T must be an integer.");
+ static_assert(inputBitCount < (sizeof(T) * 8), "T must have more bits than inputBitCount.");
+ ASSERT((input & ~((1 << inputBitCount) - 1)) == 0);
+
+ if (inputBitCount > 23)
+ {
+ // float has only a 23 bit mantissa, so we need to do the calculation in double precision
+ constexpr double inverseMax = 1.0 / ((1 << inputBitCount) - 1);
+ return static_cast<float>(input * inverseMax);
+ }
+ else
+ {
+ constexpr float inverseMax = 1.0f / ((1 << inputBitCount) - 1);
+ return input * inverseMax;
+ }
+}
+
+template <typename T>
+inline T floatToNormalized(float input)
+{
+ if constexpr (sizeof(T) > 2)
+ {
+ // float has only a 23 bit mantissa, so we need to do the calculation in double precision
+ return static_cast<T>(std::numeric_limits<T>::max() * static_cast<double>(input) + 0.5);
+ }
+ else
+ {
+ return static_cast<T>(std::numeric_limits<T>::max() * input + 0.5f);
+ }
+}
+
+template <unsigned int outputBitCount, typename T>
+inline T floatToNormalized(float input)
+{
+ static_assert(outputBitCount < (sizeof(T) * 8), "T must have more bits than outputBitCount.");
+
+ if (outputBitCount > 23)
+ {
+ // float has only a 23 bit mantissa, so we need to do the calculation in double precision
+ return static_cast<T>(((1 << outputBitCount) - 1) * static_cast<double>(input) + 0.5);
+ }
+ else
+ {
+ return static_cast<T>(((1 << outputBitCount) - 1) * input + 0.5f);
+ }
+}
+
+template <unsigned int inputBitCount, unsigned int inputBitStart, typename T>
+inline T getShiftedData(T input)
+{
+ static_assert(inputBitCount + inputBitStart <= (sizeof(T) * 8),
+ "T must have at least as many bits as inputBitCount + inputBitStart.");
+ const T mask = (1 << inputBitCount) - 1;
+ return (input >> inputBitStart) & mask;
+}
+
+template <unsigned int inputBitCount, unsigned int inputBitStart, typename T>
+inline T shiftData(T input)
+{
+ static_assert(inputBitCount + inputBitStart <= (sizeof(T) * 8),
+ "T must have at least as many bits as inputBitCount + inputBitStart.");
+ const T mask = (1 << inputBitCount) - 1;
+ return (input & mask) << inputBitStart;
+}
+
+inline unsigned int CountLeadingZeros(uint32_t x)
+{
+ // Use binary search to find the amount of leading zeros.
+ unsigned int zeros = 32u;
+ uint32_t y;
+
+ y = x >> 16u;
+ if (y != 0)
+ {
+ zeros = zeros - 16u;
+ x = y;
+ }
+ y = x >> 8u;
+ if (y != 0)
+ {
+ zeros = zeros - 8u;
+ x = y;
+ }
+ y = x >> 4u;
+ if (y != 0)
+ {
+ zeros = zeros - 4u;
+ x = y;
+ }
+ y = x >> 2u;
+ if (y != 0)
+ {
+ zeros = zeros - 2u;
+ x = y;
+ }
+ y = x >> 1u;
+ if (y != 0)
+ {
+ return zeros - 2u;
+ }
+ return zeros - x;
+}
+
+inline unsigned char average(unsigned char a, unsigned char b)
+{
+ return ((a ^ b) >> 1) + (a & b);
+}
+
+inline signed char average(signed char a, signed char b)
+{
+ return ((short)a + (short)b) / 2;
+}
+
+inline unsigned short average(unsigned short a, unsigned short b)
+{
+ return ((a ^ b) >> 1) + (a & b);
+}
+
+inline signed short average(signed short a, signed short b)
+{
+ return ((int)a + (int)b) / 2;
+}
+
+inline unsigned int average(unsigned int a, unsigned int b)
+{
+ return ((a ^ b) >> 1) + (a & b);
+}
+
+inline int average(int a, int b)
+{
+ long long average = (static_cast<long long>(a) + static_cast<long long>(b)) / 2LL;
+ return static_cast<int>(average);
+}
+
+inline float average(float a, float b)
+{
+ return (a + b) * 0.5f;
+}
+
+inline unsigned short averageHalfFloat(unsigned short a, unsigned short b)
+{
+ return float32ToFloat16((float16ToFloat32(a) + float16ToFloat32(b)) * 0.5f);
+}
+
+inline unsigned int averageFloat11(unsigned int a, unsigned int b)
+{
+ return float32ToFloat11((float11ToFloat32(static_cast<unsigned short>(a)) +
+ float11ToFloat32(static_cast<unsigned short>(b))) *
+ 0.5f);
+}
+
+inline unsigned int averageFloat10(unsigned int a, unsigned int b)
+{
+ return float32ToFloat10((float10ToFloat32(static_cast<unsigned short>(a)) +
+ float10ToFloat32(static_cast<unsigned short>(b))) *
+ 0.5f);
+}
+
+template <typename T>
+class Range
+{
+ public:
+ Range() {}
+ Range(T lo, T hi) : mLow(lo), mHigh(hi) {}
+
+ T length() const { return (empty() ? 0 : (mHigh - mLow)); }
+
+ bool intersects(Range<T> other)
+ {
+ if (mLow <= other.mLow)
+ {
+ return other.mLow < mHigh;
+ }
+ else
+ {
+ return mLow < other.mHigh;
+ }
+ }
+
+ // Assumes that end is non-inclusive.. for example, extending to 5 will make "end" 6.
+ void extend(T value)
+ {
+ mLow = value < mLow ? value : mLow;
+ mHigh = value >= mHigh ? (value + 1) : mHigh;
+ }
+
+ bool empty() const { return mHigh <= mLow; }
+
+ bool contains(T value) const { return value >= mLow && value < mHigh; }
+
+ class Iterator final
+ {
+ public:
+ Iterator(T value) : mCurrent(value) {}
+
+ Iterator &operator++()
+ {
+ mCurrent++;
+ return *this;
+ }
+ bool operator==(const Iterator &other) const { return mCurrent == other.mCurrent; }
+ bool operator!=(const Iterator &other) const { return mCurrent != other.mCurrent; }
+ T operator*() const { return mCurrent; }
+
+ private:
+ T mCurrent;
+ };
+
+ Iterator begin() const { return Iterator(mLow); }
+
+ Iterator end() const { return Iterator(mHigh); }
+
+ T low() const { return mLow; }
+ T high() const { return mHigh; }
+
+ void invalidate()
+ {
+ mLow = std::numeric_limits<T>::max();
+ mHigh = std::numeric_limits<T>::min();
+ }
+
+ private:
+ T mLow;
+ T mHigh;
+};
+
+typedef Range<int> RangeI;
+typedef Range<unsigned int> RangeUI;
+
+struct IndexRange
+{
+ struct Undefined
+ {};
+ IndexRange(Undefined) {}
+ IndexRange() : IndexRange(0, 0, 0) {}
+ IndexRange(size_t start_, size_t end_, size_t vertexIndexCount_)
+ : start(start_), end(end_), vertexIndexCount(vertexIndexCount_)
+ {
+ ASSERT(start <= end);
+ }
+
+ // Number of vertices in the range.
+ size_t vertexCount() const { return (end - start) + 1; }
+
+ // Inclusive range of indices that are not primitive restart
+ size_t start;
+ size_t end;
+
+ // Number of non-primitive restart indices
+ size_t vertexIndexCount;
+};
+
+// Combine a floating-point value representing a mantissa (x) and an integer exponent (exp) into a
+// floating-point value. As in GLSL ldexp() built-in.
+inline float Ldexp(float x, int exp)
+{
+ if (exp > 128)
+ {
+ return std::numeric_limits<float>::infinity();
+ }
+ if (exp < -126)
+ {
+ return 0.0f;
+ }
+ double result = static_cast<double>(x) * std::pow(2.0, static_cast<double>(exp));
+ return static_cast<float>(result);
+}
+
+// First, both normalized floating-point values are converted into 16-bit integer values.
+// Then, the results are packed into the returned 32-bit unsigned integer.
+// The first float value will be written to the least significant bits of the output;
+// the last float value will be written to the most significant bits.
+// The conversion of each value to fixed point is done as follows :
+// packSnorm2x16 : round(clamp(c, -1, +1) * 32767.0)
+inline uint32_t packSnorm2x16(float f1, float f2)
+{
+ int16_t leastSignificantBits = static_cast<int16_t>(roundf(clamp(f1, -1.0f, 1.0f) * 32767.0f));
+ int16_t mostSignificantBits = static_cast<int16_t>(roundf(clamp(f2, -1.0f, 1.0f) * 32767.0f));
+ return static_cast<uint32_t>(mostSignificantBits) << 16 |
+ (static_cast<uint32_t>(leastSignificantBits) & 0xFFFF);
+}
+
+// First, unpacks a single 32-bit unsigned integer u into a pair of 16-bit unsigned integers. Then,
+// each component is converted to a normalized floating-point value to generate the returned two
+// float values. The first float value will be extracted from the least significant bits of the
+// input; the last float value will be extracted from the most-significant bits. The conversion for
+// unpacked fixed-point value to floating point is done as follows: unpackSnorm2x16 : clamp(f /
+// 32767.0, -1, +1)
+inline void unpackSnorm2x16(uint32_t u, float *f1, float *f2)
+{
+ int16_t leastSignificantBits = static_cast<int16_t>(u & 0xFFFF);
+ int16_t mostSignificantBits = static_cast<int16_t>(u >> 16);
+ *f1 = clamp(static_cast<float>(leastSignificantBits) / 32767.0f, -1.0f, 1.0f);
+ *f2 = clamp(static_cast<float>(mostSignificantBits) / 32767.0f, -1.0f, 1.0f);
+}
+
+// First, both normalized floating-point values are converted into 16-bit integer values.
+// Then, the results are packed into the returned 32-bit unsigned integer.
+// The first float value will be written to the least significant bits of the output;
+// the last float value will be written to the most significant bits.
+// The conversion of each value to fixed point is done as follows:
+// packUnorm2x16 : round(clamp(c, 0, +1) * 65535.0)
+inline uint32_t packUnorm2x16(float f1, float f2)
+{
+ uint16_t leastSignificantBits = static_cast<uint16_t>(roundf(clamp(f1, 0.0f, 1.0f) * 65535.0f));
+ uint16_t mostSignificantBits = static_cast<uint16_t>(roundf(clamp(f2, 0.0f, 1.0f) * 65535.0f));
+ return static_cast<uint32_t>(mostSignificantBits) << 16 |
+ static_cast<uint32_t>(leastSignificantBits);
+}
+
+// First, unpacks a single 32-bit unsigned integer u into a pair of 16-bit unsigned integers. Then,
+// each component is converted to a normalized floating-point value to generate the returned two
+// float values. The first float value will be extracted from the least significant bits of the
+// input; the last float value will be extracted from the most-significant bits. The conversion for
+// unpacked fixed-point value to floating point is done as follows: unpackUnorm2x16 : f / 65535.0
+inline void unpackUnorm2x16(uint32_t u, float *f1, float *f2)
+{
+ uint16_t leastSignificantBits = static_cast<uint16_t>(u & 0xFFFF);
+ uint16_t mostSignificantBits = static_cast<uint16_t>(u >> 16);
+ *f1 = static_cast<float>(leastSignificantBits) / 65535.0f;
+ *f2 = static_cast<float>(mostSignificantBits) / 65535.0f;
+}
+
+// Helper functions intended to be used only here.
+namespace priv
+{
+
+inline uint8_t ToPackedUnorm8(float f)
+{
+ return static_cast<uint8_t>(roundf(clamp(f, 0.0f, 1.0f) * 255.0f));
+}
+
+inline int8_t ToPackedSnorm8(float f)
+{
+ return static_cast<int8_t>(roundf(clamp(f, -1.0f, 1.0f) * 127.0f));
+}
+
+} // namespace priv
+
+// Packs 4 normalized unsigned floating-point values to a single 32-bit unsigned integer. Works
+// similarly to packUnorm2x16. The floats are clamped to the range 0.0 to 1.0, and written to the
+// unsigned integer starting from the least significant bits.
+inline uint32_t PackUnorm4x8(float f1, float f2, float f3, float f4)
+{
+ uint8_t bits[4];
+ bits[0] = priv::ToPackedUnorm8(f1);
+ bits[1] = priv::ToPackedUnorm8(f2);
+ bits[2] = priv::ToPackedUnorm8(f3);
+ bits[3] = priv::ToPackedUnorm8(f4);
+ uint32_t result = 0u;
+ for (int i = 0; i < 4; ++i)
+ {
+ int shift = i * 8;
+ result |= (static_cast<uint32_t>(bits[i]) << shift);
+ }
+ return result;
+}
+
+// Unpacks 4 normalized unsigned floating-point values from a single 32-bit unsigned integer into f.
+// Works similarly to unpackUnorm2x16. The floats are unpacked starting from the least significant
+// bits.
+inline void UnpackUnorm4x8(uint32_t u, float *f)
+{
+ for (int i = 0; i < 4; ++i)
+ {
+ int shift = i * 8;
+ uint8_t bits = static_cast<uint8_t>((u >> shift) & 0xFF);
+ f[i] = static_cast<float>(bits) / 255.0f;
+ }
+}
+
+// Packs 4 normalized signed floating-point values to a single 32-bit unsigned integer. The floats
+// are clamped to the range -1.0 to 1.0, and written to the unsigned integer starting from the least
+// significant bits.
+inline uint32_t PackSnorm4x8(float f1, float f2, float f3, float f4)
+{
+ int8_t bits[4];
+ bits[0] = priv::ToPackedSnorm8(f1);
+ bits[1] = priv::ToPackedSnorm8(f2);
+ bits[2] = priv::ToPackedSnorm8(f3);
+ bits[3] = priv::ToPackedSnorm8(f4);
+ uint32_t result = 0u;
+ for (int i = 0; i < 4; ++i)
+ {
+ int shift = i * 8;
+ result |= ((static_cast<uint32_t>(bits[i]) & 0xFF) << shift);
+ }
+ return result;
+}
+
+// Unpacks 4 normalized signed floating-point values from a single 32-bit unsigned integer into f.
+// Works similarly to unpackSnorm2x16. The floats are unpacked starting from the least significant
+// bits, and clamped to the range -1.0 to 1.0.
+inline void UnpackSnorm4x8(uint32_t u, float *f)
+{
+ for (int i = 0; i < 4; ++i)
+ {
+ int shift = i * 8;
+ int8_t bits = static_cast<int8_t>((u >> shift) & 0xFF);
+ f[i] = clamp(static_cast<float>(bits) / 127.0f, -1.0f, 1.0f);
+ }
+}
+
+// Returns an unsigned integer obtained by converting the two floating-point values to the 16-bit
+// floating-point representation found in the OpenGL ES Specification, and then packing these
+// two 16-bit integers into a 32-bit unsigned integer.
+// f1: The 16 least-significant bits of the result;
+// f2: The 16 most-significant bits.
+inline uint32_t packHalf2x16(float f1, float f2)
+{
+ uint16_t leastSignificantBits = static_cast<uint16_t>(float32ToFloat16(f1));
+ uint16_t mostSignificantBits = static_cast<uint16_t>(float32ToFloat16(f2));
+ return static_cast<uint32_t>(mostSignificantBits) << 16 |
+ static_cast<uint32_t>(leastSignificantBits);
+}
+
+// Returns two floating-point values obtained by unpacking a 32-bit unsigned integer into a pair of
+// 16-bit values, interpreting those values as 16-bit floating-point numbers according to the OpenGL
+// ES Specification, and converting them to 32-bit floating-point values. The first float value is
+// obtained from the 16 least-significant bits of u; the second component is obtained from the 16
+// most-significant bits of u.
+inline void unpackHalf2x16(uint32_t u, float *f1, float *f2)
+{
+ uint16_t leastSignificantBits = static_cast<uint16_t>(u & 0xFFFF);
+ uint16_t mostSignificantBits = static_cast<uint16_t>(u >> 16);
+
+ *f1 = float16ToFloat32(leastSignificantBits);
+ *f2 = float16ToFloat32(mostSignificantBits);
+}
+
+inline uint8_t sRGBToLinear(uint8_t srgbValue)
+{
+ float value = srgbValue / 255.0f;
+ if (value <= 0.04045f)
+ {
+ value = value / 12.92f;
+ }
+ else
+ {
+ value = std::pow((value + 0.055f) / 1.055f, 2.4f);
+ }
+ return static_cast<uint8_t>(clamp(value * 255.0f + 0.5f, 0.0f, 255.0f));
+}
+
+inline uint8_t linearToSRGB(uint8_t linearValue)
+{
+ float value = linearValue / 255.0f;
+ if (value <= 0.0f)
+ {
+ value = 0.0f;
+ }
+ else if (value < 0.0031308f)
+ {
+ value = value * 12.92f;
+ }
+ else if (value < 1.0f)
+ {
+ value = std::pow(value, 0.41666f) * 1.055f - 0.055f;
+ }
+ else
+ {
+ value = 1.0f;
+ }
+ return static_cast<uint8_t>(clamp(value * 255.0f + 0.5f, 0.0f, 255.0f));
+}
+
+// Reverse the order of the bits.
+inline uint32_t BitfieldReverse(uint32_t value)
+{
+ // TODO(oetuaho@nvidia.com): Optimize this if needed. There don't seem to be compiler intrinsics
+ // for this, and right now it's not used in performance-critical paths.
+ uint32_t result = 0u;
+ for (size_t j = 0u; j < 32u; ++j)
+ {
+ result |= (((value >> j) & 1u) << (31u - j));
+ }
+ return result;
+}
+
+// Count the 1 bits.
+#if defined(_MSC_VER) && !defined(__clang__)
+# if defined(_M_IX86) || defined(_M_X64)
+namespace priv
+{
+// Check POPCNT instruction support and cache the result.
+// https://docs.microsoft.com/en-us/cpp/intrinsics/popcnt16-popcnt-popcnt64#remarks
+static const bool kHasPopcnt = [] {
+ int info[4];
+ __cpuid(&info[0], 1);
+ return static_cast<bool>(info[2] & 0x800000);
+}();
+} // namespace priv
+
+// Polyfills for x86/x64 CPUs without POPCNT.
+// https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
+inline int BitCountPolyfill(uint32_t bits)
+{
+ bits = bits - ((bits >> 1) & 0x55555555);
+ bits = (bits & 0x33333333) + ((bits >> 2) & 0x33333333);
+ bits = ((bits + (bits >> 4) & 0x0F0F0F0F) * 0x01010101) >> 24;
+ return static_cast<int>(bits);
+}
+
+inline int BitCountPolyfill(uint64_t bits)
+{
+ bits = bits - ((bits >> 1) & 0x5555555555555555ull);
+ bits = (bits & 0x3333333333333333ull) + ((bits >> 2) & 0x3333333333333333ull);
+ bits = ((bits + (bits >> 4) & 0x0F0F0F0F0F0F0F0Full) * 0x0101010101010101ull) >> 56;
+ return static_cast<int>(bits);
+}
+
+inline int BitCount(uint32_t bits)
+{
+ if (priv::kHasPopcnt)
+ {
+ return static_cast<int>(__popcnt(bits));
+ }
+ return BitCountPolyfill(bits);
+}
+
+inline int BitCount(uint64_t bits)
+{
+ if (priv::kHasPopcnt)
+ {
+# if defined(_M_X64)
+ return static_cast<int>(__popcnt64(bits));
+# else // x86
+ return static_cast<int>(__popcnt(static_cast<uint32_t>(bits >> 32)) +
+ __popcnt(static_cast<uint32_t>(bits)));
+# endif // defined(_M_X64)
+ }
+ return BitCountPolyfill(bits);
+}
+
+# elif defined(_M_ARM) || defined(_M_ARM64)
+
+// MSVC's _CountOneBits* intrinsics are not defined for ARM64, moreover they do not use dedicated
+// NEON instructions.
+
+inline int BitCount(uint32_t bits)
+{
+ // cast bits to 8x8 datatype and use VCNT on it
+ const uint8x8_t vsum = vcnt_u8(vcreate_u8(static_cast<uint64_t>(bits)));
+
+ // pairwise sums: 8x8 -> 16x4 -> 32x2
+ return static_cast<int>(vget_lane_u32(vpaddl_u16(vpaddl_u8(vsum)), 0));
+}
+
+inline int BitCount(uint64_t bits)
+{
+ // cast bits to 8x8 datatype and use VCNT on it
+ const uint8x8_t vsum = vcnt_u8(vcreate_u8(bits));
+
+ // pairwise sums: 8x8 -> 16x4 -> 32x2 -> 64x1
+ return static_cast<int>(vget_lane_u64(vpaddl_u32(vpaddl_u16(vpaddl_u8(vsum))), 0));
+}
+# endif // defined(_M_IX86) || defined(_M_X64)
+#endif // defined(_MSC_VER) && !defined(__clang__)
+
+#if defined(ANGLE_PLATFORM_POSIX) || defined(__clang__)
+inline int BitCount(uint32_t bits)
+{
+ return __builtin_popcount(bits);
+}
+
+inline int BitCount(uint64_t bits)
+{
+ return __builtin_popcountll(bits);
+}
+#endif // defined(ANGLE_PLATFORM_POSIX) || defined(__clang__)
+
+inline int BitCount(uint8_t bits)
+{
+ return BitCount(static_cast<uint32_t>(bits));
+}
+
+inline int BitCount(uint16_t bits)
+{
+ return BitCount(static_cast<uint32_t>(bits));
+}
+
+#if defined(ANGLE_PLATFORM_WINDOWS)
+// Return the index of the least significant bit set. Indexing is such that bit 0 is the least
+// significant bit. Implemented for different bit widths on different platforms.
+inline unsigned long ScanForward(uint32_t bits)
+{
+ ASSERT(bits != 0u);
+ unsigned long firstBitIndex = 0ul;
+ unsigned char ret = _BitScanForward(&firstBitIndex, bits);
+ ASSERT(ret != 0u);
+ return firstBitIndex;
+}
+
+inline unsigned long ScanForward(uint64_t bits)
+{
+ ASSERT(bits != 0u);
+ unsigned long firstBitIndex = 0ul;
+# if defined(ANGLE_IS_64_BIT_CPU)
+ unsigned char ret = _BitScanForward64(&firstBitIndex, bits);
+# else
+ unsigned char ret;
+ if (static_cast<uint32_t>(bits) == 0)
+ {
+ ret = _BitScanForward(&firstBitIndex, static_cast<uint32_t>(bits >> 32));
+ firstBitIndex += 32ul;
+ }
+ else
+ {
+ ret = _BitScanForward(&firstBitIndex, static_cast<uint32_t>(bits));
+ }
+# endif // defined(ANGLE_IS_64_BIT_CPU)
+ ASSERT(ret != 0u);
+ return firstBitIndex;
+}
+
+// Return the index of the most significant bit set. Indexing is such that bit 0 is the least
+// significant bit.
+inline unsigned long ScanReverse(uint32_t bits)
+{
+ ASSERT(bits != 0u);
+ unsigned long lastBitIndex = 0ul;
+ unsigned char ret = _BitScanReverse(&lastBitIndex, bits);
+ ASSERT(ret != 0u);
+ return lastBitIndex;
+}
+
+inline unsigned long ScanReverse(uint64_t bits)
+{
+ ASSERT(bits != 0u);
+ unsigned long lastBitIndex = 0ul;
+# if defined(ANGLE_IS_64_BIT_CPU)
+ unsigned char ret = _BitScanReverse64(&lastBitIndex, bits);
+# else
+ unsigned char ret;
+ if (static_cast<uint32_t>(bits >> 32) == 0)
+ {
+ ret = _BitScanReverse(&lastBitIndex, static_cast<uint32_t>(bits));
+ }
+ else
+ {
+ ret = _BitScanReverse(&lastBitIndex, static_cast<uint32_t>(bits >> 32));
+ lastBitIndex += 32ul;
+ }
+# endif // defined(ANGLE_IS_64_BIT_CPU)
+ ASSERT(ret != 0u);
+ return lastBitIndex;
+}
+#endif // defined(ANGLE_PLATFORM_WINDOWS)
+
+#if defined(ANGLE_PLATFORM_POSIX)
+inline unsigned long ScanForward(uint32_t bits)
+{
+ ASSERT(bits != 0u);
+ return static_cast<unsigned long>(__builtin_ctz(bits));
+}
+
+inline unsigned long ScanForward(uint64_t bits)
+{
+ ASSERT(bits != 0u);
+# if defined(ANGLE_IS_64_BIT_CPU)
+ return static_cast<unsigned long>(__builtin_ctzll(bits));
+# else
+ return static_cast<unsigned long>(static_cast<uint32_t>(bits) == 0
+ ? __builtin_ctz(static_cast<uint32_t>(bits >> 32)) + 32
+ : __builtin_ctz(static_cast<uint32_t>(bits)));
+# endif // defined(ANGLE_IS_64_BIT_CPU)
+}
+
+inline unsigned long ScanReverse(uint32_t bits)
+{
+ ASSERT(bits != 0u);
+ return static_cast<unsigned long>(sizeof(uint32_t) * CHAR_BIT - 1 - __builtin_clz(bits));
+}
+
+inline unsigned long ScanReverse(uint64_t bits)
+{
+ ASSERT(bits != 0u);
+# if defined(ANGLE_IS_64_BIT_CPU)
+ return static_cast<unsigned long>(sizeof(uint64_t) * CHAR_BIT - 1 - __builtin_clzll(bits));
+# else
+ if (static_cast<uint32_t>(bits >> 32) == 0)
+ {
+ return sizeof(uint32_t) * CHAR_BIT - 1 - __builtin_clz(static_cast<uint32_t>(bits));
+ }
+ else
+ {
+ return sizeof(uint32_t) * CHAR_BIT - 1 - __builtin_clz(static_cast<uint32_t>(bits >> 32)) +
+ 32;
+ }
+# endif // defined(ANGLE_IS_64_BIT_CPU)
+}
+#endif // defined(ANGLE_PLATFORM_POSIX)
+
+inline unsigned long ScanForward(uint8_t bits)
+{
+ return ScanForward(static_cast<uint32_t>(bits));
+}
+
+inline unsigned long ScanForward(uint16_t bits)
+{
+ return ScanForward(static_cast<uint32_t>(bits));
+}
+
+inline unsigned long ScanReverse(uint8_t bits)
+{
+ return ScanReverse(static_cast<uint32_t>(bits));
+}
+
+inline unsigned long ScanReverse(uint16_t bits)
+{
+ return ScanReverse(static_cast<uint32_t>(bits));
+}
+
+// Returns -1 on 0, otherwise the index of the least significant 1 bit as in GLSL.
+template <typename T>
+int FindLSB(T bits)
+{
+ static_assert(std::is_integral<T>::value, "must be integral type.");
+ if (bits == 0u)
+ {
+ return -1;
+ }
+ else
+ {
+ return static_cast<int>(ScanForward(bits));
+ }
+}
+
+// Returns -1 on 0, otherwise the index of the most significant 1 bit as in GLSL.
+template <typename T>
+int FindMSB(T bits)
+{
+ static_assert(std::is_integral<T>::value, "must be integral type.");
+ if (bits == 0u)
+ {
+ return -1;
+ }
+ else
+ {
+ return static_cast<int>(ScanReverse(bits));
+ }
+}
+
+// Returns whether the argument is Not a Number.
+// IEEE 754 single precision NaN representation: Exponent(8 bits) - 255, Mantissa(23 bits) -
+// non-zero.
+inline bool isNaN(float f)
+{
+ // Exponent mask: ((1u << 8) - 1u) << 23 = 0x7f800000u
+ // Mantissa mask: ((1u << 23) - 1u) = 0x7fffffu
+ return ((bitCast<uint32_t>(f) & 0x7f800000u) == 0x7f800000u) &&
+ (bitCast<uint32_t>(f) & 0x7fffffu);
+}
+
+// Returns whether the argument is infinity.
+// IEEE 754 single precision infinity representation: Exponent(8 bits) - 255, Mantissa(23 bits) -
+// zero.
+inline bool isInf(float f)
+{
+ // Exponent mask: ((1u << 8) - 1u) << 23 = 0x7f800000u
+ // Mantissa mask: ((1u << 23) - 1u) = 0x7fffffu
+ return ((bitCast<uint32_t>(f) & 0x7f800000u) == 0x7f800000u) &&
+ !(bitCast<uint32_t>(f) & 0x7fffffu);
+}
+
+namespace priv
+{
+template <unsigned int N, unsigned int R>
+struct iSquareRoot
+{
+ static constexpr unsigned int solve()
+ {
+ return (R * R > N)
+ ? 0
+ : ((R * R == N) ? R : static_cast<unsigned int>(iSquareRoot<N, R + 1>::value));
+ }
+ enum Result
+ {
+ value = iSquareRoot::solve()
+ };
+};
+
+template <unsigned int N>
+struct iSquareRoot<N, N>
+{
+ enum result
+ {
+ value = N
+ };
+};
+
+} // namespace priv
+
+template <unsigned int N>
+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);
+}
+
+inline float scaleScreenDimensionToNdc(float dimensionScreen, float viewportDimension)
+{
+ return 2.0f * dimensionScreen / viewportDimension;
+}
+
+inline float scaleScreenCoordinateToNdc(float coordinateScreen, float viewportDimension)
+{
+ float halfShifted = coordinateScreen / viewportDimension;
+ return 2.0f * (halfShifted - 0.5f);
+}
+
+} // namespace gl
+
+namespace rx
+{
+
+template <typename T>
+T roundUp(const T value, const T alignment)
+{
+ auto temp = value + alignment - static_cast<T>(1);
+ return temp - temp % alignment;
+}
+
+template <typename T>
+constexpr T roundUpPow2(const T value, const T alignment)
+{
+ ASSERT(gl::isPow2(alignment));
+ return (value + alignment - 1) & ~(alignment - 1);
+}
+
+template <typename T>
+constexpr T roundDownPow2(const T value, const T alignment)
+{
+ ASSERT(gl::isPow2(alignment));
+ return value & ~(alignment - 1);
+}
+
+template <typename T>
+angle::CheckedNumeric<T> CheckedRoundUp(const T value, const T alignment)
+{
+ angle::CheckedNumeric<T> checkedValue(value);
+ angle::CheckedNumeric<T> checkedAlignment(alignment);
+ return roundUp(checkedValue, checkedAlignment);
+}
+
+inline constexpr unsigned int UnsignedCeilDivide(unsigned int value, unsigned int divisor)
+{
+ unsigned int divided = value / divisor;
+ return (divided + ((value % divisor == 0) ? 0 : 1));
+}
+
+#if defined(__has_builtin)
+# define ANGLE_HAS_BUILTIN(x) __has_builtin(x)
+#else
+# define ANGLE_HAS_BUILTIN(x) 0
+#endif
+
+#if defined(_MSC_VER)
+
+# define ANGLE_ROTL(x, y) _rotl(x, y)
+# define ANGLE_ROTL64(x, y) _rotl64(x, y)
+# define ANGLE_ROTR16(x, y) _rotr16(x, y)
+
+#elif defined(__clang__) && ANGLE_HAS_BUILTIN(__builtin_rotateleft32) && \
+ ANGLE_HAS_BUILTIN(__builtin_rotateleft64) && ANGLE_HAS_BUILTIN(__builtin_rotateright16)
+
+# define ANGLE_ROTL(x, y) __builtin_rotateleft32(x, y)
+# define ANGLE_ROTL64(x, y) __builtin_rotateleft64(x, y)
+# define ANGLE_ROTR16(x, y) __builtin_rotateright16(x, y)
+
+#else
+
+inline uint32_t RotL(uint32_t x, int8_t r)
+{
+ return (x << r) | (x >> (32 - r));
+}
+
+inline uint64_t RotL64(uint64_t x, int8_t r)
+{
+ return (x << r) | (x >> (64 - r));
+}
+
+inline uint16_t RotR16(uint16_t x, int8_t r)
+{
+ return (x >> r) | (x << (16 - r));
+}
+
+# define ANGLE_ROTL(x, y) ::rx::RotL(x, y)
+# define ANGLE_ROTL64(x, y) ::rx::RotL64(x, y)
+# define ANGLE_ROTR16(x, y) ::rx::RotR16(x, y)
+
+#endif // namespace rx
+
+constexpr unsigned int Log2(unsigned int bytes)
+{
+ return bytes == 1 ? 0 : (1 + Log2(bytes / 2));
+}
+} // namespace rx
+
+#endif // COMMON_MATHUTIL_H_
diff --git a/gfx/angle/checkout/src/common/matrix_utils.cpp b/gfx/angle/checkout/src/common/matrix_utils.cpp
new file mode 100644
index 0000000000..59ab4ca437
--- /dev/null
+++ b/gfx/angle/checkout/src/common/matrix_utils.cpp
@@ -0,0 +1,285 @@
+//
+// Copyright 2018 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.
+//
+
+// matrix_utils.cpp: Contains implementations for Mat4 methods.
+
+#include "common/matrix_utils.h"
+
+namespace angle
+{
+
+Mat4::Mat4() : Mat4(1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f)
+{}
+
+Mat4::Mat4(const Matrix<float> generalMatrix) : Matrix(std::vector<float>(16, 0), 4, 4)
+{
+ unsigned int minCols = std::min((unsigned int)4, generalMatrix.columns());
+ unsigned int minRows = std::min((unsigned int)4, generalMatrix.rows());
+ for (unsigned int i = 0; i < minCols; i++)
+ {
+ for (unsigned int j = 0; j < minRows; j++)
+ {
+ mElements[j * minCols + i] = generalMatrix.at(j, i);
+ }
+ }
+}
+
+Mat4::Mat4(const std::vector<float> &elements) : Matrix(elements, 4) {}
+
+Mat4::Mat4(const float *elements) : Matrix(elements, 4) {}
+
+Mat4::Mat4(float m00,
+ float m01,
+ float m02,
+ float m03,
+ float m10,
+ float m11,
+ float m12,
+ float m13,
+ float m20,
+ float m21,
+ float m22,
+ float m23,
+ float m30,
+ float m31,
+ float m32,
+ float m33)
+ : Matrix(std::vector<float>(16, 0), 4, 4)
+{
+ mElements[0] = m00;
+ mElements[1] = m01;
+ mElements[2] = m02;
+ mElements[3] = m03;
+ mElements[4] = m10;
+ mElements[5] = m11;
+ mElements[6] = m12;
+ mElements[7] = m13;
+ mElements[8] = m20;
+ mElements[9] = m21;
+ mElements[10] = m22;
+ mElements[11] = m23;
+ mElements[12] = m30;
+ mElements[13] = m31;
+ mElements[14] = m32;
+ mElements[15] = m33;
+}
+
+// static
+Mat4 Mat4::Rotate(float angle, const Vector3 &axis)
+{
+ auto axis_normalized = axis.normalized();
+ float angle_radians = angle * (3.14159265358979323f / 180.0f);
+ float c = cos(angle_radians);
+ float ci = 1.f - c;
+ float s = sin(angle_radians);
+
+ float x = axis_normalized.x();
+ float y = axis_normalized.y();
+ float z = axis_normalized.z();
+
+ float x2 = x * x;
+ float y2 = y * y;
+ float z2 = z * z;
+
+ float xy = x * y;
+ float yz = y * z;
+ float zx = z * x;
+
+ float r00 = c + ci * x2;
+ float r01 = ci * xy + s * z;
+ float r02 = ci * zx - s * y;
+ float r03 = 0.f;
+
+ float r10 = ci * xy - s * z;
+ float r11 = c + ci * y2;
+ float r12 = ci * yz + s * x;
+ float r13 = 0.f;
+
+ float r20 = ci * zx + s * y;
+ float r21 = ci * yz - s * x;
+ float r22 = c + ci * z2;
+ float r23 = 0.f;
+
+ float r30 = 0.f;
+ float r31 = 0.f;
+ float r32 = 0.f;
+ float r33 = 1.f;
+
+ return Mat4(r00, r01, r02, r03, r10, r11, r12, r13, r20, r21, r22, r23, r30, r31, r32, r33);
+}
+
+// static
+Mat4 Mat4::Translate(const Vector3 &t)
+{
+ float r00 = 1.f;
+ float r01 = 0.f;
+ float r02 = 0.f;
+ float r03 = 0.f;
+
+ float r10 = 0.f;
+ float r11 = 1.f;
+ float r12 = 0.f;
+ float r13 = 0.f;
+
+ float r20 = 0.f;
+ float r21 = 0.f;
+ float r22 = 1.f;
+ float r23 = 0.f;
+
+ float r30 = t.x();
+ float r31 = t.y();
+ float r32 = t.z();
+ float r33 = 1.f;
+
+ return Mat4(r00, r01, r02, r03, r10, r11, r12, r13, r20, r21, r22, r23, r30, r31, r32, r33);
+}
+
+// static
+Mat4 Mat4::Scale(const Vector3 &s)
+{
+ float r00 = s.x();
+ float r01 = 0.f;
+ float r02 = 0.f;
+ float r03 = 0.f;
+
+ float r10 = 0.f;
+ float r11 = s.y();
+ float r12 = 0.f;
+ float r13 = 0.f;
+
+ float r20 = 0.f;
+ float r21 = 0.f;
+ float r22 = s.z();
+ float r23 = 0.f;
+
+ float r30 = 0.f;
+ float r31 = 0.f;
+ float r32 = 0.f;
+ float r33 = 1.f;
+
+ return Mat4(r00, r01, r02, r03, r10, r11, r12, r13, r20, r21, r22, r23, r30, r31, r32, r33);
+}
+
+// static
+Mat4 Mat4::Frustum(float l, float r, float b, float t, float n, float f)
+{
+ float nn = 2.f * n;
+ float fpn = f + n;
+ float fmn = f - n;
+ float tpb = t + b;
+ float tmb = t - b;
+ float rpl = r + l;
+ float rml = r - l;
+
+ float r00 = nn / rml;
+ float r01 = 0.f;
+ float r02 = 0.f;
+ float r03 = 0.f;
+
+ float r10 = 0.f;
+ float r11 = nn / tmb;
+ float r12 = 0.f;
+ float r13 = 0.f;
+
+ float r20 = rpl / rml;
+ float r21 = tpb / tmb;
+ float r22 = -fpn / fmn;
+ float r23 = -1.f;
+
+ float r30 = 0.f;
+ float r31 = 0.f;
+ float r32 = -nn * f / fmn;
+ float r33 = 0.f;
+
+ return Mat4(r00, r01, r02, r03, r10, r11, r12, r13, r20, r21, r22, r23, r30, r31, r32, r33);
+}
+
+// static
+Mat4 Mat4::Perspective(float fov, float aspectRatio, float n, float f)
+{
+ const float frustumHeight = tanf(static_cast<float>(fov / 360.0f * 3.14159265358979323)) * n;
+ const float frustumWidth = frustumHeight * aspectRatio;
+ return Frustum(-frustumWidth, frustumWidth, -frustumHeight, frustumHeight, n, f);
+}
+
+// static
+Mat4 Mat4::Ortho(float l, float r, float b, float t, float n, float f)
+{
+ float fpn = f + n;
+ float fmn = f - n;
+ float tpb = t + b;
+ float tmb = t - b;
+ float rpl = r + l;
+ float rml = r - l;
+
+ float r00 = 2.f / rml;
+ float r01 = 0.f;
+ float r02 = 0.f;
+ float r03 = 0.f;
+
+ float r10 = 0.f;
+ float r11 = 2.f / tmb;
+ float r12 = 0.f;
+ float r13 = 0.f;
+
+ float r20 = 0.f;
+ float r21 = 0.f;
+ float r22 = -2.f / fmn;
+ float r23 = 0.f;
+
+ float r30 = -rpl / rml;
+ float r31 = -tpb / tmb;
+ float r32 = -fpn / fmn;
+ float r33 = 1.f;
+
+ return Mat4(r00, r01, r02, r03, r10, r11, r12, r13, r20, r21, r22, r23, r30, r31, r32, r33);
+}
+
+Mat4 Mat4::product(const Mat4 &m)
+{
+ const float *a = mElements.data();
+ const float *b = m.mElements.data();
+
+ return Mat4(a[0] * b[0] + a[4] * b[1] + a[8] * b[2] + a[12] * b[3],
+ a[1] * b[0] + a[5] * b[1] + a[9] * b[2] + a[13] * b[3],
+ a[2] * b[0] + a[6] * b[1] + a[10] * b[2] + a[14] * b[3],
+ a[3] * b[0] + a[7] * b[1] + a[11] * b[2] + a[15] * b[3],
+
+ a[0] * b[4] + a[4] * b[5] + a[8] * b[6] + a[12] * b[7],
+ a[1] * b[4] + a[5] * b[5] + a[9] * b[6] + a[13] * b[7],
+ a[2] * b[4] + a[6] * b[5] + a[10] * b[6] + a[14] * b[7],
+ a[3] * b[4] + a[7] * b[5] + a[11] * b[6] + a[15] * b[7],
+
+ a[0] * b[8] + a[4] * b[9] + a[8] * b[10] + a[12] * b[11],
+ a[1] * b[8] + a[5] * b[9] + a[9] * b[10] + a[13] * b[11],
+ a[2] * b[8] + a[6] * b[9] + a[10] * b[10] + a[14] * b[11],
+ a[3] * b[8] + a[7] * b[9] + a[11] * b[10] + a[15] * b[11],
+
+ a[0] * b[12] + a[4] * b[13] + a[8] * b[14] + a[12] * b[15],
+ a[1] * b[12] + a[5] * b[13] + a[9] * b[14] + a[13] * b[15],
+ a[2] * b[12] + a[6] * b[13] + a[10] * b[14] + a[14] * b[15],
+ a[3] * b[12] + a[7] * b[13] + a[11] * b[14] + a[15] * b[15]);
+}
+
+Vector4 Mat4::product(const Vector4 &b)
+{
+ return Vector4(
+ mElements[0] * b.x() + mElements[4] * b.y() + mElements[8] * b.z() + mElements[12] * b.w(),
+ mElements[1] * b.x() + mElements[5] * b.y() + mElements[9] * b.z() + mElements[13] * b.w(),
+ mElements[2] * b.x() + mElements[6] * b.y() + mElements[10] * b.z() + mElements[14] * b.w(),
+ mElements[3] * b.x() + mElements[7] * b.y() + mElements[11] * b.z() +
+ mElements[15] * b.w());
+}
+
+void Mat4::dump()
+{
+ printf("[ %f %f %f %f ]\n", mElements[0], mElements[4], mElements[8], mElements[12]);
+ printf("[ %f %f %f %f ]\n", mElements[1], mElements[5], mElements[9], mElements[13]);
+ printf("[ %f %f %f %f ]\n", mElements[2], mElements[6], mElements[10], mElements[14]);
+ printf("[ %f %f %f %f ]\n", mElements[3], mElements[7], mElements[11], mElements[15]);
+}
+
+} // namespace angle
diff --git a/gfx/angle/checkout/src/common/matrix_utils.h b/gfx/angle/checkout/src/common/matrix_utils.h
new file mode 100644
index 0000000000..7cca7a9461
--- /dev/null
+++ b/gfx/angle/checkout/src/common/matrix_utils.h
@@ -0,0 +1,424 @@
+//
+// 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.
+//
+// Matrix:
+// Utility class implementing various matrix operations.
+// Supports matrices with minimum 2 and maximum 4 number of rows/columns.
+//
+// TODO: Check if we can merge Matrix.h in sample_util with this and replace it with this
+// implementation.
+// TODO: Rename this file to Matrix.h once we remove Matrix.h in sample_util.
+
+#ifndef COMMON_MATRIX_UTILS_H_
+#define COMMON_MATRIX_UTILS_H_
+
+#include <vector>
+
+#include "common/debug.h"
+#include "common/mathutil.h"
+#include "common/vector_utils.h"
+
+namespace angle
+{
+
+template <typename T>
+class Matrix
+{
+ public:
+ Matrix(const std::vector<T> &elements, const unsigned int numRows, const unsigned int numCols)
+ : mElements(elements), mRows(numRows), mCols(numCols)
+ {
+ ASSERT(rows() >= 1 && rows() <= 4);
+ ASSERT(columns() >= 1 && columns() <= 4);
+ }
+
+ Matrix(const std::vector<T> &elements, const unsigned int size)
+ : mElements(elements), mRows(size), mCols(size)
+ {
+ ASSERT(rows() >= 1 && rows() <= 4);
+ ASSERT(columns() >= 1 && columns() <= 4);
+ }
+
+ Matrix(const T *elements, const unsigned int size) : mRows(size), mCols(size)
+ {
+ ASSERT(rows() >= 1 && rows() <= 4);
+ ASSERT(columns() >= 1 && columns() <= 4);
+ for (size_t i = 0; i < size * size; i++)
+ mElements.push_back(elements[i]);
+ }
+
+ const T &operator()(const unsigned int rowIndex, const unsigned int columnIndex) const
+ {
+ ASSERT(rowIndex < mRows);
+ ASSERT(columnIndex < mCols);
+ return mElements[rowIndex * columns() + columnIndex];
+ }
+
+ T &operator()(const unsigned int rowIndex, const unsigned int columnIndex)
+ {
+ ASSERT(rowIndex < mRows);
+ ASSERT(columnIndex < mCols);
+ return mElements[rowIndex * columns() + columnIndex];
+ }
+
+ const T &at(const unsigned int rowIndex, const unsigned int columnIndex) const
+ {
+ ASSERT(rowIndex < mRows);
+ ASSERT(columnIndex < mCols);
+ return operator()(rowIndex, columnIndex);
+ }
+
+ Matrix<T> operator*(const Matrix<T> &m)
+ {
+ ASSERT(columns() == m.rows());
+
+ unsigned int resultRows = rows();
+ unsigned int resultCols = m.columns();
+ Matrix<T> result(std::vector<T>(resultRows * resultCols), resultRows, resultCols);
+ for (unsigned int i = 0; i < resultRows; i++)
+ {
+ for (unsigned int j = 0; j < resultCols; j++)
+ {
+ T tmp = 0.0f;
+ for (unsigned int k = 0; k < columns(); k++)
+ tmp += at(i, k) * m(k, j);
+ result(i, j) = tmp;
+ }
+ }
+
+ return result;
+ }
+
+ void operator*=(const Matrix<T> &m)
+ {
+ ASSERT(columns() == m.rows());
+ Matrix<T> res = (*this) * m;
+ size_t numElts = res.elements().size();
+ mElements.resize(numElts);
+ memcpy(mElements.data(), res.data(), numElts * sizeof(float));
+ }
+
+ bool operator==(const Matrix<T> &m) const
+ {
+ ASSERT(columns() == m.columns());
+ ASSERT(rows() == m.rows());
+ return mElements == m.elements();
+ }
+
+ bool operator!=(const Matrix<T> &m) const { return !(mElements == m.elements()); }
+
+ bool nearlyEqual(T epsilon, const Matrix<T> &m) const
+ {
+ ASSERT(columns() == m.columns());
+ ASSERT(rows() == m.rows());
+ const auto &otherElts = m.elements();
+ for (size_t i = 0; i < otherElts.size(); i++)
+ {
+ if ((mElements[i] - otherElts[i] > epsilon) && (otherElts[i] - mElements[i] > epsilon))
+ return false;
+ }
+ return true;
+ }
+
+ unsigned int size() const
+ {
+ ASSERT(rows() == columns());
+ return rows();
+ }
+
+ unsigned int rows() const { return mRows; }
+
+ unsigned int columns() const { return mCols; }
+
+ std::vector<T> elements() const { return mElements; }
+ T *data() { return mElements.data(); }
+ const T *constData() const { return mElements.data(); }
+
+ Matrix<T> compMult(const Matrix<T> &mat1) const
+ {
+ Matrix result(std::vector<T>(mElements.size()), rows(), columns());
+ for (unsigned int i = 0; i < rows(); i++)
+ {
+ for (unsigned int j = 0; j < columns(); j++)
+ {
+ T lhs = at(i, j);
+ T rhs = mat1(i, j);
+ result(i, j) = rhs * lhs;
+ }
+ }
+
+ return result;
+ }
+
+ Matrix<T> outerProduct(const Matrix<T> &mat1) const
+ {
+ unsigned int cols = mat1.columns();
+ Matrix result(std::vector<T>(rows() * cols), rows(), cols);
+ for (unsigned int i = 0; i < rows(); i++)
+ for (unsigned int j = 0; j < cols; j++)
+ result(i, j) = at(i, 0) * mat1(0, j);
+
+ return result;
+ }
+
+ Matrix<T> transpose() const
+ {
+ Matrix result(std::vector<T>(mElements.size()), columns(), rows());
+ for (unsigned int i = 0; i < columns(); i++)
+ for (unsigned int j = 0; j < rows(); j++)
+ result(i, j) = at(j, i);
+
+ return result;
+ }
+
+ T determinant() const
+ {
+ ASSERT(rows() == columns());
+
+ switch (size())
+ {
+ case 2:
+ return at(0, 0) * at(1, 1) - at(0, 1) * at(1, 0);
+
+ case 3:
+ return at(0, 0) * at(1, 1) * at(2, 2) + at(0, 1) * at(1, 2) * at(2, 0) +
+ at(0, 2) * at(1, 0) * at(2, 1) - at(0, 2) * at(1, 1) * at(2, 0) -
+ at(0, 1) * at(1, 0) * at(2, 2) - at(0, 0) * at(1, 2) * at(2, 1);
+
+ case 4:
+ {
+ const float minorMatrices[4][3 * 3] = {{
+ at(1, 1),
+ at(2, 1),
+ at(3, 1),
+ at(1, 2),
+ at(2, 2),
+ at(3, 2),
+ at(1, 3),
+ at(2, 3),
+ at(3, 3),
+ },
+ {
+ at(1, 0),
+ at(2, 0),
+ at(3, 0),
+ at(1, 2),
+ at(2, 2),
+ at(3, 2),
+ at(1, 3),
+ at(2, 3),
+ at(3, 3),
+ },
+ {
+ at(1, 0),
+ at(2, 0),
+ at(3, 0),
+ at(1, 1),
+ at(2, 1),
+ at(3, 1),
+ at(1, 3),
+ at(2, 3),
+ at(3, 3),
+ },
+ {
+ at(1, 0),
+ at(2, 0),
+ at(3, 0),
+ at(1, 1),
+ at(2, 1),
+ at(3, 1),
+ at(1, 2),
+ at(2, 2),
+ at(3, 2),
+ }};
+ return at(0, 0) * Matrix<T>(minorMatrices[0], 3).determinant() -
+ at(0, 1) * Matrix<T>(minorMatrices[1], 3).determinant() +
+ at(0, 2) * Matrix<T>(minorMatrices[2], 3).determinant() -
+ at(0, 3) * Matrix<T>(minorMatrices[3], 3).determinant();
+ }
+
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ return T();
+ }
+
+ Matrix<T> inverse() const
+ {
+ ASSERT(rows() == columns());
+
+ Matrix<T> cof(std::vector<T>(mElements.size()), rows(), columns());
+ switch (size())
+ {
+ case 2:
+ cof(0, 0) = at(1, 1);
+ cof(0, 1) = -at(1, 0);
+ cof(1, 0) = -at(0, 1);
+ cof(1, 1) = at(0, 0);
+ break;
+
+ case 3:
+ cof(0, 0) = at(1, 1) * at(2, 2) - at(2, 1) * at(1, 2);
+ cof(0, 1) = -(at(1, 0) * at(2, 2) - at(2, 0) * at(1, 2));
+ cof(0, 2) = at(1, 0) * at(2, 1) - at(2, 0) * at(1, 1);
+ cof(1, 0) = -(at(0, 1) * at(2, 2) - at(2, 1) * at(0, 2));
+ cof(1, 1) = at(0, 0) * at(2, 2) - at(2, 0) * at(0, 2);
+ cof(1, 2) = -(at(0, 0) * at(2, 1) - at(2, 0) * at(0, 1));
+ cof(2, 0) = at(0, 1) * at(1, 2) - at(1, 1) * at(0, 2);
+ cof(2, 1) = -(at(0, 0) * at(1, 2) - at(1, 0) * at(0, 2));
+ cof(2, 2) = at(0, 0) * at(1, 1) - at(1, 0) * at(0, 1);
+ break;
+
+ case 4:
+ cof(0, 0) = at(1, 1) * at(2, 2) * at(3, 3) + at(2, 1) * at(3, 2) * at(1, 3) +
+ at(3, 1) * at(1, 2) * at(2, 3) - at(1, 1) * at(3, 2) * at(2, 3) -
+ at(2, 1) * at(1, 2) * at(3, 3) - at(3, 1) * at(2, 2) * at(1, 3);
+ cof(0, 1) = -(at(1, 0) * at(2, 2) * at(3, 3) + at(2, 0) * at(3, 2) * at(1, 3) +
+ at(3, 0) * at(1, 2) * at(2, 3) - at(1, 0) * at(3, 2) * at(2, 3) -
+ at(2, 0) * at(1, 2) * at(3, 3) - at(3, 0) * at(2, 2) * at(1, 3));
+ cof(0, 2) = at(1, 0) * at(2, 1) * at(3, 3) + at(2, 0) * at(3, 1) * at(1, 3) +
+ at(3, 0) * at(1, 1) * at(2, 3) - at(1, 0) * at(3, 1) * at(2, 3) -
+ at(2, 0) * at(1, 1) * at(3, 3) - at(3, 0) * at(2, 1) * at(1, 3);
+ cof(0, 3) = -(at(1, 0) * at(2, 1) * at(3, 2) + at(2, 0) * at(3, 1) * at(1, 2) +
+ at(3, 0) * at(1, 1) * at(2, 2) - at(1, 0) * at(3, 1) * at(2, 2) -
+ at(2, 0) * at(1, 1) * at(3, 2) - at(3, 0) * at(2, 1) * at(1, 2));
+ cof(1, 0) = -(at(0, 1) * at(2, 2) * at(3, 3) + at(2, 1) * at(3, 2) * at(0, 3) +
+ at(3, 1) * at(0, 2) * at(2, 3) - at(0, 1) * at(3, 2) * at(2, 3) -
+ at(2, 1) * at(0, 2) * at(3, 3) - at(3, 1) * at(2, 2) * at(0, 3));
+ cof(1, 1) = at(0, 0) * at(2, 2) * at(3, 3) + at(2, 0) * at(3, 2) * at(0, 3) +
+ at(3, 0) * at(0, 2) * at(2, 3) - at(0, 0) * at(3, 2) * at(2, 3) -
+ at(2, 0) * at(0, 2) * at(3, 3) - at(3, 0) * at(2, 2) * at(0, 3);
+ cof(1, 2) = -(at(0, 0) * at(2, 1) * at(3, 3) + at(2, 0) * at(3, 1) * at(0, 3) +
+ at(3, 0) * at(0, 1) * at(2, 3) - at(0, 0) * at(3, 1) * at(2, 3) -
+ at(2, 0) * at(0, 1) * at(3, 3) - at(3, 0) * at(2, 1) * at(0, 3));
+ cof(1, 3) = at(0, 0) * at(2, 1) * at(3, 2) + at(2, 0) * at(3, 1) * at(0, 2) +
+ at(3, 0) * at(0, 1) * at(2, 2) - at(0, 0) * at(3, 1) * at(2, 2) -
+ at(2, 0) * at(0, 1) * at(3, 2) - at(3, 0) * at(2, 1) * at(0, 2);
+ cof(2, 0) = at(0, 1) * at(1, 2) * at(3, 3) + at(1, 1) * at(3, 2) * at(0, 3) +
+ at(3, 1) * at(0, 2) * at(1, 3) - at(0, 1) * at(3, 2) * at(1, 3) -
+ at(1, 1) * at(0, 2) * at(3, 3) - at(3, 1) * at(1, 2) * at(0, 3);
+ cof(2, 1) = -(at(0, 0) * at(1, 2) * at(3, 3) + at(1, 0) * at(3, 2) * at(0, 3) +
+ at(3, 0) * at(0, 2) * at(1, 3) - at(0, 0) * at(3, 2) * at(1, 3) -
+ at(1, 0) * at(0, 2) * at(3, 3) - at(3, 0) * at(1, 2) * at(0, 3));
+ cof(2, 2) = at(0, 0) * at(1, 1) * at(3, 3) + at(1, 0) * at(3, 1) * at(0, 3) +
+ at(3, 0) * at(0, 1) * at(1, 3) - at(0, 0) * at(3, 1) * at(1, 3) -
+ at(1, 0) * at(0, 1) * at(3, 3) - at(3, 0) * at(1, 1) * at(0, 3);
+ cof(2, 3) = -(at(0, 0) * at(1, 1) * at(3, 2) + at(1, 0) * at(3, 1) * at(0, 2) +
+ at(3, 0) * at(0, 1) * at(1, 2) - at(0, 0) * at(3, 1) * at(1, 2) -
+ at(1, 0) * at(0, 1) * at(3, 2) - at(3, 0) * at(1, 1) * at(0, 2));
+ cof(3, 0) = -(at(0, 1) * at(1, 2) * at(2, 3) + at(1, 1) * at(2, 2) * at(0, 3) +
+ at(2, 1) * at(0, 2) * at(1, 3) - at(0, 1) * at(2, 2) * at(1, 3) -
+ at(1, 1) * at(0, 2) * at(2, 3) - at(2, 1) * at(1, 2) * at(0, 3));
+ cof(3, 1) = at(0, 0) * at(1, 2) * at(2, 3) + at(1, 0) * at(2, 2) * at(0, 3) +
+ at(2, 0) * at(0, 2) * at(1, 3) - at(0, 0) * at(2, 2) * at(1, 3) -
+ at(1, 0) * at(0, 2) * at(2, 3) - at(2, 0) * at(1, 2) * at(0, 3);
+ cof(3, 2) = -(at(0, 0) * at(1, 1) * at(2, 3) + at(1, 0) * at(2, 1) * at(0, 3) +
+ at(2, 0) * at(0, 1) * at(1, 3) - at(0, 0) * at(2, 1) * at(1, 3) -
+ at(1, 0) * at(0, 1) * at(2, 3) - at(2, 0) * at(1, 1) * at(0, 3));
+ cof(3, 3) = at(0, 0) * at(1, 1) * at(2, 2) + at(1, 0) * at(2, 1) * at(0, 2) +
+ at(2, 0) * at(0, 1) * at(1, 2) - at(0, 0) * at(2, 1) * at(1, 2) -
+ at(1, 0) * at(0, 1) * at(2, 2) - at(2, 0) * at(1, 1) * at(0, 2);
+ break;
+
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ // The inverse of A is the transpose of the cofactor matrix times the reciprocal of the
+ // determinant of A.
+ Matrix<T> adjugateMatrix(cof.transpose());
+ T det = determinant();
+ Matrix<T> result(std::vector<T>(mElements.size()), rows(), columns());
+ for (unsigned int i = 0; i < rows(); i++)
+ for (unsigned int j = 0; j < columns(); j++)
+ result(i, j) = (det != static_cast<T>(0)) ? adjugateMatrix(i, j) / det : T();
+
+ return result;
+ }
+
+ void setToIdentity()
+ {
+ ASSERT(rows() == columns());
+
+ const auto one = T(1);
+ const auto zero = T(0);
+
+ for (auto &e : mElements)
+ e = zero;
+
+ for (unsigned int i = 0; i < rows(); ++i)
+ {
+ const auto pos = i * columns() + (i % columns());
+ mElements[pos] = one;
+ }
+ }
+
+ template <unsigned int Size>
+ static void setToIdentity(T (&matrix)[Size])
+ {
+ static_assert(gl::iSquareRoot<Size>() != 0, "Matrix is not square.");
+
+ const auto cols = gl::iSquareRoot<Size>();
+ const auto one = T(1);
+ const auto zero = T(0);
+
+ for (auto &e : matrix)
+ e = zero;
+
+ for (unsigned int i = 0; i < cols; ++i)
+ {
+ const auto pos = i * cols + (i % cols);
+ matrix[pos] = one;
+ }
+ }
+
+ protected:
+ std::vector<T> mElements;
+ unsigned int mRows;
+ unsigned int mCols;
+};
+
+class Mat4 : public Matrix<float>
+{
+ public:
+ Mat4();
+ Mat4(const Matrix<float> generalMatrix);
+ Mat4(const std::vector<float> &elements);
+ Mat4(const float *elements);
+ Mat4(float m00,
+ float m01,
+ float m02,
+ float m03,
+ float m10,
+ float m11,
+ float m12,
+ float m13,
+ float m20,
+ float m21,
+ float m22,
+ float m23,
+ float m30,
+ float m31,
+ float m32,
+ float m33);
+
+ static Mat4 Rotate(float angle, const Vector3 &axis);
+ static Mat4 Translate(const Vector3 &t);
+ static Mat4 Scale(const Vector3 &s);
+ static Mat4 Frustum(float l, float r, float b, float t, float n, float f);
+ static Mat4 Perspective(float fov, float aspectRatio, float n, float f);
+ static Mat4 Ortho(float l, float r, float b, float t, float n, float f);
+
+ Mat4 product(const Mat4 &m);
+ Vector4 product(const Vector4 &b);
+ void dump();
+};
+
+} // namespace angle
+
+#endif // COMMON_MATRIX_UTILS_H_
diff --git a/gfx/angle/checkout/src/common/platform.h b/gfx/angle/checkout/src/common/platform.h
new file mode 100644
index 0000000000..77267ab680
--- /dev/null
+++ b/gfx/angle/checkout/src/common/platform.h
@@ -0,0 +1,209 @@
+//
+// 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.
+//
+
+// platform.h: Operating system specific includes and defines.
+
+#ifndef COMMON_PLATFORM_H_
+#define COMMON_PLATFORM_H_
+
+#if defined(_WIN32)
+# define ANGLE_PLATFORM_WINDOWS 1
+#elif defined(__Fuchsia__)
+# define ANGLE_PLATFORM_FUCHSIA 1
+# define ANGLE_PLATFORM_POSIX 1
+#elif defined(__APPLE__)
+# define ANGLE_PLATFORM_APPLE 1
+# define ANGLE_PLATFORM_POSIX 1
+#elif defined(ANDROID)
+# define ANGLE_PLATFORM_ANDROID 1
+# define ANGLE_PLATFORM_POSIX 1
+#elif defined(__ggp__)
+# define ANGLE_PLATFORM_GGP 1
+# define ANGLE_PLATFORM_POSIX 1
+#elif defined(__linux__) || defined(EMSCRIPTEN)
+# define ANGLE_PLATFORM_LINUX 1
+# define ANGLE_PLATFORM_POSIX 1
+#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || \
+ defined(__DragonFly__) || defined(__sun) || defined(__GLIBC__) || defined(__GNU__) || \
+ defined(__QNX__) || defined(__Fuchsia__) || defined(__HAIKU__)
+# define ANGLE_PLATFORM_POSIX 1
+#else
+# error Unsupported platform.
+#endif
+
+#ifdef ANGLE_PLATFORM_WINDOWS
+# ifndef STRICT
+# define STRICT 1
+# endif
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN 1
+# endif
+# ifndef NOMINMAX
+# define NOMINMAX 1
+# endif
+
+# include <intrin.h>
+
+# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP)
+# define ANGLE_ENABLE_WINDOWS_UWP 1
+# endif
+
+# if defined(ANGLE_ENABLE_D3D9)
+# include <d3d9.h>
+# include <d3dcompiler.h>
+# endif
+
+// Include D3D11 headers when OpenGL is enabled on Windows for interop extensions.
+# if defined(ANGLE_ENABLE_D3D11) || defined(ANGLE_ENABLE_OPENGL)
+# include <d3d10_1.h>
+# include <d3d11.h>
+# include <d3d11_3.h>
+# include <d3d11on12.h>
+# include <d3d12.h>
+# include <d3dcompiler.h>
+# include <dxgi.h>
+# include <dxgi1_2.h>
+# include <dxgi1_4.h>
+# endif
+
+# if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11)
+# include <wrl.h>
+# endif
+
+# if defined(ANGLE_ENABLE_WINDOWS_UWP)
+# include <dxgi1_3.h>
+# if defined(_DEBUG)
+# include <DXProgrammableCapture.h>
+# include <dxgidebug.h>
+# endif
+# endif
+
+// Include <windows.h> to ensure tests related files can be built when building
+// vulkan only backend ANGLE on windows.
+# if defined(ANGLE_ENABLE_VULKAN)
+# include <windows.h>
+# endif
+
+// Macros 'near', 'far', 'NEAR' and 'FAR' are defined by 'shared/minwindef.h' in the Windows SDK.
+// Macros 'near' and 'far' are empty. They are not used by other Windows headers and are undefined
+// here to avoid identifier conflicts. Macros 'NEAR' and 'FAR' contain 'near' and 'far'. They are
+// used by other Windows headers and are cleared here to avoid compilation errors.
+# undef near
+# undef far
+# undef NEAR
+# undef FAR
+# define NEAR
+# define FAR
+#endif
+
+#if defined(_MSC_VER) && !defined(_M_ARM) && !defined(_M_ARM64)
+# include <intrin.h>
+# define ANGLE_USE_SSE
+#elif defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__))
+# include <x86intrin.h>
+# define ANGLE_USE_SSE
+#endif
+
+// Mips and arm devices need to include stddef for size_t.
+#if defined(__mips__) || defined(__arm__) || defined(__aarch64__)
+# include <stddef.h>
+#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
+
+// Macro for hinting that an expression is likely to be true/false.
+#if !defined(ANGLE_LIKELY) || !defined(ANGLE_UNLIKELY)
+# if defined(__GNUC__) || defined(__clang__)
+# define ANGLE_LIKELY(x) __builtin_expect(!!(x), 1)
+# define ANGLE_UNLIKELY(x) __builtin_expect(!!(x), 0)
+# else
+# define ANGLE_LIKELY(x) (x)
+# define ANGLE_UNLIKELY(x) (x)
+# endif // defined(__GNUC__) || defined(__clang__)
+#endif // !defined(ANGLE_LIKELY) || !defined(ANGLE_UNLIKELY)
+
+#ifdef ANGLE_PLATFORM_APPLE
+# include <TargetConditionals.h>
+# if TARGET_OS_OSX
+# define ANGLE_PLATFORM_MACOS 1
+# elif TARGET_OS_IPHONE
+# define ANGLE_PLATFORM_IOS 1
+# if TARGET_OS_SIMULATOR
+# define ANGLE_PLATFORM_IOS_SIMULATOR 1
+# endif
+# if TARGET_OS_MACCATALYST
+# define ANGLE_PLATFORM_MACCATALYST 1
+# endif
+# elif TARGET_OS_WATCH
+# define ANGLE_PLATFORM_WATCHOS 1
+# if TARGET_OS_SIMULATOR
+# define ANGLE_PLATFORM_IOS_SIMULATOR 1
+# endif
+# elif TARGET_OS_TV
+# define ANGLE_PLATFORM_APPLETV 1
+# if TARGET_OS_SIMULATOR
+# define ANGLE_PLATFORM_IOS_SIMULATOR 1
+# endif
+# endif
+# // This might be useful globally. At the moment it is used
+# // to differentiate MacCatalyst on Intel and Apple Silicon.
+# if defined(__arm64__) || defined(__aarch64__)
+# define ANGLE_CPU_ARM64 1
+# endif
+# // EAGL should be enabled on iOS, but not Mac Catalyst unless it is running on Apple Silicon.
+# if (defined(ANGLE_PLATFORM_IOS) && !defined(ANGLE_PLATFORM_MACCATALYST)) || \
+ (defined(ANGLE_PLATFORM_MACCATALYST) && defined(ANGLE_CPU_ARM64))
+# define ANGLE_ENABLE_EAGL
+# endif
+# // Identify Metal API >= what shipped on macOS Catalina.
+# if (defined(ANGLE_PLATFORM_MACOS) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 101500) || \
+ (defined(ANGLE_PLATFORM_IOS) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000)
+# define ANGLE_WITH_MODERN_METAL_API 1
+# endif
+#endif
+
+// Define ANGLE_WITH_ASAN macro.
+#if defined(__has_feature)
+# if __has_feature(address_sanitizer)
+# define ANGLE_WITH_ASAN 1
+# endif
+#endif
+
+// Define ANGLE_WITH_MSAN macro.
+#if defined(__has_feature)
+# if __has_feature(memory_sanitizer)
+# define ANGLE_WITH_MSAN 1
+# endif
+#endif
+
+// Define ANGLE_WITH_TSAN macro.
+#if defined(__has_feature)
+# if __has_feature(thread_sanitizer)
+# define ANGLE_WITH_TSAN 1
+# endif
+#endif
+
+// Define ANGLE_WITH_UBSAN macro.
+#if defined(__has_feature)
+# if __has_feature(undefined_behavior_sanitizer)
+# define ANGLE_WITH_UBSAN 1
+# endif
+#endif
+
+#if defined(ANGLE_WITH_ASAN) || defined(ANGLE_WITH_TSAN) || defined(ANGLE_WITH_UBSAN)
+# define ANGLE_WITH_SANITIZER 1
+#endif // defined(ANGLE_WITH_ASAN) || defined(ANGLE_WITH_TSAN) || defined(ANGLE_WITH_UBSAN)
+
+#include <cstdint>
+#if INTPTR_MAX == INT64_MAX
+# define ANGLE_IS_64_BIT_CPU 1
+#else
+# define ANGLE_IS_32_BIT_CPU 1
+#endif
+
+#endif // COMMON_PLATFORM_H_
diff --git a/gfx/angle/checkout/src/common/spirv/spirv_types.h b/gfx/angle/checkout/src/common/spirv/spirv_types.h
new file mode 100644
index 0000000000..faf2174481
--- /dev/null
+++ b/gfx/angle/checkout/src/common/spirv/spirv_types.h
@@ -0,0 +1,133 @@
+//
+// Copyright 2021 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.
+//
+// spirv_types.h:
+// Strong types for SPIR-V Ids to prevent mistakes when using the builder and parser APIs.
+//
+
+#ifndef COMMON_SPIRV_TYPES_H_
+#define COMMON_SPIRV_TYPES_H_
+
+#include "common/FastVector.h"
+
+#include <vector>
+
+namespace angle
+{
+namespace spirv
+{
+template <typename Helper>
+class BoxedUint32
+{
+ public:
+ BoxedUint32() : mValue{0} {}
+ explicit BoxedUint32(uint32_t value) : mValue{value} {}
+ template <typename T>
+ T as() const
+ {
+ return T{mValue};
+ }
+ BoxedUint32(const BoxedUint32 &other) = default;
+ BoxedUint32 &operator=(const BoxedUint32 &other) = default;
+ operator uint32_t() const { return mValue.value; }
+ bool operator==(const BoxedUint32 &other) const { return mValue.value == other.mValue.value; }
+ // Applicable to ids, which cannot be 0.
+ bool valid() const { return static_cast<bool>(mValue.value); }
+
+ private:
+ Helper mValue;
+};
+
+struct IdRefHelper
+{
+ uint32_t value;
+};
+struct LiteralIntegerHelper
+{
+ uint32_t value;
+};
+
+using IdRef = BoxedUint32<IdRefHelper>;
+
+template <>
+inline BoxedUint32<IdRefHelper>::operator uint32_t() const
+{
+ ASSERT(valid());
+ return mValue.value;
+}
+
+// IdResult, IdResultType, IdMemorySemantics and IdScope are all translated as IdRef. This makes
+// the type verification weaker, but stops the API from becoming tediously verbose.
+using IdResult = IdRef;
+using IdResultType = IdRef;
+using IdMemorySemantics = IdRef;
+using IdScope = IdRef;
+using LiteralInteger = BoxedUint32<LiteralIntegerHelper>;
+using LiteralString = const char *;
+// Note: In ANGLE's use cases, all literals fit in 32 bits.
+using LiteralContextDependentNumber = LiteralInteger;
+// TODO(syoussefi): To be made stronger when generating SPIR-V from the translator.
+// http://anglebug.com/4889
+using LiteralExtInstInteger = LiteralInteger;
+
+struct PairLiteralIntegerIdRef
+{
+ LiteralInteger literal;
+ IdRef id;
+};
+
+struct PairIdRefLiteralInteger
+{
+ IdRef id;
+ LiteralInteger literal;
+};
+
+struct PairIdRefIdRef
+{
+ IdRef id1;
+ IdRef id2;
+};
+
+// Some instructions need 4 components. The drivers uniform struct in ANGLE has 8 fields. A value
+// of 8 means almost no instruction would end up making dynamic allocations. Notable exceptions are
+// user-defined structs/blocks and OpEntryPoint.
+constexpr size_t kFastVectorSize = 8;
+
+template <typename T>
+using FastVectorHelper = angle::FastVector<T, kFastVectorSize>;
+
+using IdRefList = FastVectorHelper<IdRef>;
+using LiteralIntegerList = FastVectorHelper<LiteralInteger>;
+using PairLiteralIntegerIdRefList = FastVectorHelper<PairLiteralIntegerIdRef>;
+using PairIdRefLiteralIntegerList = FastVectorHelper<PairIdRefLiteralInteger>;
+using PairIdRefIdRefList = FastVectorHelper<PairIdRefIdRef>;
+
+// Id 0 is invalid in SPIR-V.
+constexpr uint32_t kMinValidId = 1;
+
+// The SPIR-V blob is a sequence of uint32_t's
+using Blob = std::vector<uint32_t>;
+
+// Format of the SPIR-V header.
+// SPIR-V 1.0 Table 1: First Words of Physical Layout
+enum HeaderIndex
+{
+ kHeaderIndexMagic = 0,
+ kHeaderIndexVersion = 1,
+ kHeaderIndexGenerator = 2,
+ kHeaderIndexIndexBound = 3,
+ kHeaderIndexSchema = 4,
+ kHeaderIndexInstructions = 5,
+};
+
+// Returns whether SPIR-V is valid. Useful for ASSERTs. Automatically generates a warning if
+// SPIR-V is not valid.
+bool Validate(const Blob &blob);
+void Print(const Blob &blob);
+
+} // namespace spirv
+} // namespace angle
+
+#endif // COMMON_SPIRV_TYPES_H_
diff --git a/gfx/angle/checkout/src/common/string_utils.cpp b/gfx/angle/checkout/src/common/string_utils.cpp
new file mode 100644
index 0000000000..192d82917c
--- /dev/null
+++ b/gfx/angle/checkout/src/common/string_utils.cpp
@@ -0,0 +1,357 @@
+//
+// 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.
+//
+// string_utils:
+// String helper functions.
+//
+
+#include "common/string_utils.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <algorithm>
+#include <cctype>
+#include <fstream>
+#include <sstream>
+
+#include "common/platform.h"
+#include "common/system_utils.h"
+
+namespace
+{
+
+bool EndsWithSuffix(const char *str,
+ const size_t strLen,
+ const char *suffix,
+ const size_t suffixLen)
+{
+ return suffixLen <= strLen && strncmp(str + strLen - suffixLen, suffix, suffixLen) == 0;
+}
+
+} // anonymous namespace
+
+namespace angle
+{
+
+const char kWhitespaceASCII[] = " \f\n\r\t\v";
+
+std::vector<std::string> SplitString(const std::string &input,
+ const std::string &delimiters,
+ WhitespaceHandling whitespace,
+ SplitResult resultType)
+{
+ std::vector<std::string> result;
+ if (input.empty())
+ {
+ return result;
+ }
+
+ std::string::size_type start = 0;
+ while (start != std::string::npos)
+ {
+ auto end = input.find_first_of(delimiters, start);
+
+ std::string piece;
+ if (end == std::string::npos)
+ {
+ piece = input.substr(start);
+ start = std::string::npos;
+ }
+ else
+ {
+ piece = input.substr(start, end - start);
+ start = end + 1;
+ }
+
+ if (whitespace == TRIM_WHITESPACE)
+ {
+ piece = TrimString(piece, kWhitespaceASCII);
+ }
+
+ if (resultType == SPLIT_WANT_ALL || !piece.empty())
+ {
+ result.push_back(std::move(piece));
+ }
+ }
+
+ return result;
+}
+
+void SplitStringAlongWhitespace(const std::string &input, std::vector<std::string> *tokensOut)
+{
+
+ std::istringstream stream(input);
+ std::string line;
+
+ while (std::getline(stream, line))
+ {
+ size_t prev = 0, pos;
+ while ((pos = line.find_first_of(kWhitespaceASCII, prev)) != std::string::npos)
+ {
+ if (pos > prev)
+ tokensOut->push_back(line.substr(prev, pos - prev));
+ prev = pos + 1;
+ }
+ if (prev < line.length())
+ tokensOut->push_back(line.substr(prev, std::string::npos));
+ }
+}
+
+std::string TrimString(const std::string &input, const std::string &trimChars)
+{
+ auto begin = input.find_first_not_of(trimChars);
+ if (begin == std::string::npos)
+ {
+ return "";
+ }
+
+ std::string::size_type end = input.find_last_not_of(trimChars);
+ if (end == std::string::npos)
+ {
+ return input.substr(begin);
+ }
+
+ return input.substr(begin, end - begin + 1);
+}
+
+std::string GetPrefix(const std::string &input, size_t offset, const char *delimiter)
+{
+ size_t match = input.find(delimiter, offset);
+ if (match == std::string::npos)
+ {
+ return input.substr(offset);
+ }
+ return input.substr(offset, match - offset);
+}
+
+std::string GetPrefix(const std::string &input, size_t offset, char delimiter)
+{
+ size_t match = input.find(delimiter, offset);
+ if (match == std::string::npos)
+ {
+ return input.substr(offset);
+ }
+ return input.substr(offset, match - offset);
+}
+
+bool HexStringToUInt(const std::string &input, unsigned int *uintOut)
+{
+ unsigned int offset = 0;
+
+ if (input.size() >= 2 && input[0] == '0' && input[1] == 'x')
+ {
+ offset = 2u;
+ }
+
+ // Simple validity check
+ if (input.find_first_not_of("0123456789ABCDEFabcdef", offset) != std::string::npos)
+ {
+ return false;
+ }
+
+ std::stringstream inStream(input);
+ inStream >> std::hex >> *uintOut;
+ return !inStream.fail();
+}
+
+bool ReadFileToString(const std::string &path, std::string *stringOut)
+{
+ std::ifstream inFile(path.c_str());
+ if (inFile.fail())
+ {
+ return false;
+ }
+
+ inFile.seekg(0, std::ios::end);
+ stringOut->reserve(static_cast<std::string::size_type>(inFile.tellg()));
+ inFile.seekg(0, std::ios::beg);
+
+ stringOut->assign(std::istreambuf_iterator<char>(inFile), std::istreambuf_iterator<char>());
+ return !inFile.fail();
+}
+
+bool BeginsWith(const std::string &str, const std::string &prefix)
+{
+ return strncmp(str.c_str(), prefix.c_str(), prefix.length()) == 0;
+}
+
+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 BeginsWith(const std::string &str, const std::string &prefix, const size_t prefixLength)
+{
+ return strncmp(str.c_str(), prefix.c_str(), prefixLength) == 0;
+}
+
+bool EndsWith(const std::string &str, const std::string &suffix)
+{
+ return EndsWithSuffix(str.c_str(), str.length(), suffix.c_str(), suffix.length());
+}
+
+bool EndsWith(const std::string &str, const char *suffix)
+{
+ return EndsWithSuffix(str.c_str(), str.length(), suffix, strlen(suffix));
+}
+
+bool EndsWith(const char *str, const char *suffix)
+{
+ return EndsWithSuffix(str, strlen(str), suffix, strlen(suffix));
+}
+
+bool ContainsToken(const std::string &tokenStr, char delimiter, const std::string &token)
+{
+ if (token.empty())
+ {
+ return false;
+ }
+ // Compare token with all sub-strings terminated by delimiter or end of string
+ std::string::size_type start = 0u;
+ do
+ {
+ std::string::size_type end = tokenStr.find(delimiter, start);
+ if (end == std::string::npos)
+ {
+ end = tokenStr.length();
+ }
+ const std::string::size_type length = end - start;
+ if (length == token.length() && tokenStr.compare(start, length, token) == 0)
+ {
+ return true;
+ }
+ start = end + 1u;
+ } while (start < tokenStr.size());
+ return false;
+}
+
+void ToLower(std::string *str)
+{
+ for (char &ch : *str)
+ {
+ ch = static_cast<char>(::tolower(ch));
+ }
+}
+
+void ToUpper(std::string *str)
+{
+ for (char &ch : *str)
+ {
+ ch = static_cast<char>(::toupper(ch));
+ }
+}
+
+bool ReplaceSubstring(std::string *str,
+ const std::string &substring,
+ const std::string &replacement)
+{
+ size_t replacePos = str->find(substring);
+ if (replacePos == std::string::npos)
+ {
+ return false;
+ }
+ str->replace(replacePos, substring.size(), replacement);
+ return true;
+}
+
+int ReplaceAllSubstrings(std::string *str,
+ const std::string &substring,
+ const std::string &replacement)
+{
+ int count = 0;
+ while (ReplaceSubstring(str, substring, replacement))
+ {
+ count++;
+ }
+ return count;
+}
+
+std::string ToCamelCase(const std::string &str)
+{
+ std::string result;
+
+ bool lastWasUnderscore = false;
+ for (char c : str)
+ {
+ if (c == '_')
+ {
+ lastWasUnderscore = true;
+ continue;
+ }
+
+ if (lastWasUnderscore)
+ {
+ c = static_cast<char>(std::toupper(c));
+ lastWasUnderscore = false;
+ }
+ result += c;
+ }
+
+ return result;
+}
+
+std::vector<std::string> GetStringsFromEnvironmentVarOrAndroidProperty(const char *varName,
+ const char *propertyName,
+ const char *separator)
+{
+ std::string environment = GetEnvironmentVarOrAndroidProperty(varName, propertyName);
+ return SplitString(environment, separator, TRIM_WHITESPACE, SPLIT_WANT_NONEMPTY);
+}
+
+std::vector<std::string> GetCachedStringsFromEnvironmentVarOrAndroidProperty(
+ const char *varName,
+ const char *propertyName,
+ const char *separator)
+{
+ std::string environment = GetEnvironmentVarOrAndroidProperty(varName, propertyName);
+ return SplitString(environment, separator, TRIM_WHITESPACE, SPLIT_WANT_NONEMPTY);
+}
+
+// glob can have * as wildcard
+bool NamesMatchWithWildcard(const char *glob, const char *name)
+{
+ // Find the first * in glob.
+ const char *firstWildcard = strchr(glob, '*');
+
+ // If there are no wildcards, match the strings precisely.
+ if (firstWildcard == nullptr)
+ {
+ return strcmp(glob, name) == 0;
+ }
+
+ // Otherwise, match up to the wildcard first.
+ size_t preWildcardLen = firstWildcard - glob;
+ if (strncmp(glob, name, preWildcardLen) != 0)
+ {
+ return false;
+ }
+
+ const char *postWildcardRef = glob + preWildcardLen + 1;
+
+ // As a small optimization, if the wildcard is the last character in glob, accept the match
+ // already.
+ if (postWildcardRef[0] == '\0')
+ {
+ return true;
+ }
+
+ // Try to match the wildcard with a number of characters.
+ for (size_t matchSize = 0; name[matchSize] != '\0'; ++matchSize)
+ {
+ if (NamesMatchWithWildcard(postWildcardRef, name + matchSize))
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+} // namespace angle
diff --git a/gfx/angle/checkout/src/common/string_utils.h b/gfx/angle/checkout/src/common/string_utils.h
new file mode 100644
index 0000000000..7be7efe983
--- /dev/null
+++ b/gfx/angle/checkout/src/common/string_utils.h
@@ -0,0 +1,125 @@
+//
+// 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.
+//
+// string_utils:
+// String helper functions.
+//
+
+#ifndef LIBANGLE_STRING_UTILS_H_
+#define LIBANGLE_STRING_UTILS_H_
+
+#include <string>
+#include <vector>
+
+#include "common/Optional.h"
+
+namespace angle
+{
+
+extern const char kWhitespaceASCII[];
+
+enum WhitespaceHandling
+{
+ KEEP_WHITESPACE,
+ TRIM_WHITESPACE,
+};
+
+enum SplitResult
+{
+ SPLIT_WANT_ALL,
+ SPLIT_WANT_NONEMPTY,
+};
+
+std::vector<std::string> SplitString(const std::string &input,
+ const std::string &delimiters,
+ WhitespaceHandling whitespace,
+ SplitResult resultType);
+
+void SplitStringAlongWhitespace(const std::string &input, std::vector<std::string> *tokensOut);
+
+std::string TrimString(const std::string &input, const std::string &trimChars);
+
+// Return the substring starting at offset and up to the first occurance of the |delimeter|.
+std::string GetPrefix(const std::string &input, size_t offset, const char *delimiter);
+std::string GetPrefix(const std::string &input, size_t offset, char delimiter);
+
+bool HexStringToUInt(const std::string &input, unsigned int *uintOut);
+
+bool ReadFileToString(const std::string &path, std::string *stringOut);
+
+// Check if the string str begins with the given prefix.
+// The comparison is case sensitive.
+bool BeginsWith(const std::string &str, const std::string &prefix);
+
+// 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 begins with the first prefixLength characters of the given prefix.
+// The length of the prefix string should be greater than or equal to prefixLength.
+// The comparison is case sensitive.
+bool BeginsWith(const std::string &str, const std::string &prefix, const size_t prefixLength);
+
+// Check if the string str ends with the given suffix.
+// The comparison is case sensitive.
+bool EndsWith(const std::string &str, const std::string &suffix);
+
+// Check if the string str ends with the given suffix.
+// Suffix may not be NULL and needs to be NULL terminated.
+// The comparison is case sensitive.
+bool EndsWith(const std::string &str, const char *suffix);
+
+// Check if the string str ends with the given suffix.
+// str and suffix may not be NULL and need to be NULL terminated.
+// The comparison is case sensitive.
+bool EndsWith(const char *str, const char *suffix);
+
+// Check if the given token string contains the given token.
+// The tokens are separated by the given delimiter.
+// The comparison is case sensitive.
+bool ContainsToken(const std::string &tokenStr, char delimiter, const std::string &token);
+
+// Convert to lower-case.
+void ToLower(std::string *str);
+
+// Convert to upper-case.
+void ToUpper(std::string *str);
+
+// Replaces the substring 'substring' in 'str' with 'replacement'. Returns true if successful.
+bool ReplaceSubstring(std::string *str,
+ const std::string &substring,
+ const std::string &replacement);
+
+// Replaces all substrings 'substring' in 'str' with 'replacement'. Returns count of replacements.
+int ReplaceAllSubstrings(std::string *str,
+ const std::string &substring,
+ const std::string &replacement);
+
+// Takes a snake_case string and turns it into camelCase.
+std::string ToCamelCase(const std::string &str);
+
+// Split up a string parsed from an environment variable.
+std::vector<std::string> GetStringsFromEnvironmentVarOrAndroidProperty(const char *varName,
+ const char *propertyName,
+ const char *separator);
+
+// Split up a string parsed from environment variable or via Android property, use cached result if
+// available.
+std::vector<std::string> GetCachedStringsFromEnvironmentVarOrAndroidProperty(
+ const char *varName,
+ const char *propertyName,
+ const char *separator);
+
+// glob can have * as wildcard
+bool NamesMatchWithWildcard(const char *glob, const char *name);
+} // namespace angle
+
+#endif // LIBANGLE_STRING_UTILS_H_
diff --git a/gfx/angle/checkout/src/common/system_utils.cpp b/gfx/angle/checkout/src/common/system_utils.cpp
new file mode 100644
index 0000000000..89b632bc17
--- /dev/null
+++ b/gfx/angle/checkout/src/common/system_utils.cpp
@@ -0,0 +1,267 @@
+//
+// Copyright 2018 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.
+//
+
+// system_utils.cpp: Implementation of common functions
+
+#include "common/system_utils.h"
+#include "common/debug.h"
+
+#include <stdlib.h>
+#include <atomic>
+
+#if defined(ANGLE_PLATFORM_ANDROID)
+# include <sys/system_properties.h>
+#endif
+
+#if defined(ANGLE_PLATFORM_APPLE)
+# include <dispatch/dispatch.h>
+# include <pthread.h>
+#endif
+
+namespace angle
+{
+std::string GetExecutableName()
+{
+#if defined(ANGLE_PLATFORM_ANDROID) && __ANDROID_API__ >= 21
+ // Support for "getprogname" function in bionic was introduced in L (API level 21)
+ const char *executableName = getprogname();
+ return (executableName) ? std::string(executableName) : "ANGLE";
+#else
+ std::string executableName = GetExecutablePath();
+ size_t lastPathSepLoc = executableName.find_last_of(GetPathSeparator());
+ return (lastPathSepLoc > 0 ? executableName.substr(lastPathSepLoc + 1, executableName.length())
+ : "ANGLE");
+#endif // ANGLE_PLATFORM_ANDROID
+}
+
+// On Android return value cached in the process environment, if none, call
+// GetEnvironmentVarOrUnCachedAndroidProperty if not in environment.
+std::string GetEnvironmentVarOrAndroidProperty(const char *variableName, const char *propertyName)
+{
+#if defined(ANGLE_PLATFORM_ANDROID) && __ANDROID_API__ >= 21
+ // Can't use GetEnvironmentVar here because that won't allow us to distinguish between the
+ // environment being set to an empty string vs. not set at all.
+ const char *variableValue = getenv(variableName);
+ if (variableValue != nullptr)
+ {
+ std::string value(variableValue);
+ return value;
+ }
+#endif
+ return GetEnvironmentVarOrUnCachedAndroidProperty(variableName, propertyName);
+}
+
+// On Android call out to 'getprop' on a shell to get an Android property. On desktop, return
+// the value of the environment variable.
+std::string GetEnvironmentVarOrUnCachedAndroidProperty(const char *variableName,
+ const char *propertyName)
+{
+#if defined(ANGLE_PLATFORM_ANDROID) && __ANDROID_API__ >= 26
+ std::string propertyValue;
+
+ const prop_info *propertyInfo = __system_property_find(propertyName);
+ if (propertyInfo != nullptr)
+ {
+ __system_property_read_callback(
+ propertyInfo,
+ [](void *cookie, const char *, const char *value, unsigned) {
+ auto propertyValue = reinterpret_cast<std::string *>(cookie);
+ *propertyValue = value;
+ },
+ &propertyValue);
+ }
+
+ return propertyValue;
+#else
+ // Return the environment variable's value.
+ return GetEnvironmentVar(variableName);
+#endif // ANGLE_PLATFORM_ANDROID
+}
+
+// Look up a property and add it to the application's environment.
+// Adding to the env is a performance optimization, as getting properties is expensive.
+// This should only be used in non-Release paths, i.e. when using FrameCapture or DebugUtils.
+// It can cause race conditions in stress testing. See http://anglebug.com/6822
+std::string GetAndSetEnvironmentVarOrUnCachedAndroidProperty(const char *variableName,
+ const char *propertyName)
+{
+ std::string value = GetEnvironmentVarOrUnCachedAndroidProperty(variableName, propertyName);
+
+#if defined(ANGLE_PLATFORM_ANDROID)
+ if (!value.empty())
+ {
+ // Set the environment variable with the value to improve future lookups (avoids
+ SetEnvironmentVar(variableName, value.c_str());
+ }
+#endif
+
+ return value;
+}
+
+bool GetBoolEnvironmentVar(const char *variableName)
+{
+ std::string envVarString = GetEnvironmentVar(variableName);
+ return (!envVarString.empty() && envVarString == "1");
+}
+
+bool PrependPathToEnvironmentVar(const char *variableName, const char *path)
+{
+ std::string oldValue = GetEnvironmentVar(variableName);
+ const char *newValue = nullptr;
+ std::string buf;
+ if (oldValue.empty())
+ {
+ newValue = path;
+ }
+ else
+ {
+ buf = path;
+ buf += GetPathSeparatorForEnvironmentVar();
+ buf += oldValue;
+ newValue = buf.c_str();
+ }
+ return SetEnvironmentVar(variableName, newValue);
+}
+
+bool IsFullPath(std::string dirName)
+{
+ if (dirName.find(GetRootDirectory()) == 0)
+ {
+ return true;
+ }
+ return false;
+}
+
+std::string ConcatenatePath(std::string first, std::string second)
+{
+ if (first.empty())
+ {
+ return second;
+ }
+ if (second.empty())
+ {
+ return first;
+ }
+ if (IsFullPath(second))
+ {
+ return second;
+ }
+ bool firstRedundantPathSeparator = first.find_last_of(GetPathSeparator()) == first.length() - 1;
+ bool secondRedundantPathSeparator = second.find(GetPathSeparator()) == 0;
+ if (firstRedundantPathSeparator && secondRedundantPathSeparator)
+ {
+ return first + second.substr(1);
+ }
+ else if (firstRedundantPathSeparator || secondRedundantPathSeparator)
+ {
+ return first + second;
+ }
+ return first + GetPathSeparator() + second;
+}
+
+Optional<std::string> CreateTemporaryFile()
+{
+ const Optional<std::string> tempDir = GetTempDirectory();
+ if (!tempDir.valid())
+ return Optional<std::string>::Invalid();
+
+ return CreateTemporaryFileInDirectory(tempDir.value());
+}
+
+PageFaultHandler::PageFaultHandler(PageFaultCallback callback) : mCallback(callback) {}
+PageFaultHandler::~PageFaultHandler() {}
+
+Library *OpenSharedLibrary(const char *libraryName, SearchType searchType)
+{
+ void *libraryHandle = OpenSystemLibraryAndGetError(libraryName, searchType, nullptr);
+ return new Library(libraryHandle);
+}
+
+Library *OpenSharedLibraryWithExtension(const char *libraryName, SearchType searchType)
+{
+ void *libraryHandle =
+ OpenSystemLibraryWithExtensionAndGetError(libraryName, searchType, nullptr);
+ return new Library(libraryHandle);
+}
+
+Library *OpenSharedLibraryAndGetError(const char *libraryName,
+ SearchType searchType,
+ std::string *errorOut)
+{
+ void *libraryHandle = OpenSystemLibraryAndGetError(libraryName, searchType, errorOut);
+ return new Library(libraryHandle);
+}
+
+Library *OpenSharedLibraryWithExtensionAndGetError(const char *libraryName,
+ SearchType searchType,
+ std::string *errorOut)
+{
+ void *libraryHandle =
+ OpenSystemLibraryWithExtensionAndGetError(libraryName, searchType, errorOut);
+ return new Library(libraryHandle);
+}
+
+void *OpenSystemLibrary(const char *libraryName, SearchType searchType)
+{
+ return OpenSystemLibraryAndGetError(libraryName, searchType, nullptr);
+}
+
+void *OpenSystemLibraryWithExtension(const char *libraryName, SearchType searchType)
+{
+ return OpenSystemLibraryWithExtensionAndGetError(libraryName, searchType, nullptr);
+}
+
+void *OpenSystemLibraryAndGetError(const char *libraryName,
+ SearchType searchType,
+ std::string *errorOut)
+{
+ std::string libraryWithExtension = std::string(libraryName) + "." + GetSharedLibraryExtension();
+#if ANGLE_PLATFORM_IOS
+ // On iOS, libraryWithExtension is a directory in which the library resides.
+ // The actual library name doesn't have an extension at all.
+ // E.g. "libEGL.framework/libEGL"
+ libraryWithExtension = libraryWithExtension + "/" + libraryName;
+#endif
+ return OpenSystemLibraryWithExtensionAndGetError(libraryWithExtension.c_str(), searchType,
+ errorOut);
+}
+
+std::string StripFilenameFromPath(const std::string &path)
+{
+ size_t lastPathSepLoc = path.find_last_of("\\/");
+ return (lastPathSepLoc != std::string::npos) ? path.substr(0, lastPathSepLoc) : "";
+}
+
+static std::atomic<uint64_t> globalThreadSerial(1);
+
+#if defined(ANGLE_PLATFORM_APPLE)
+// https://anglebug.com/6479, similar to egl::GetCurrentThread() in libGLESv2/global_state.cpp
+uint64_t GetCurrentThreadUniqueId()
+{
+ static pthread_key_t tlsIndex;
+ static dispatch_once_t once;
+ dispatch_once(&once, ^{
+ ASSERT(pthread_key_create(&tlsIndex, nullptr) == 0);
+ });
+
+ void *tlsValue = pthread_getspecific(tlsIndex);
+ if (tlsValue == nullptr)
+ {
+ uint64_t threadId = globalThreadSerial++;
+ ASSERT(pthread_setspecific(tlsIndex, reinterpret_cast<void *>(threadId)) == 0);
+ return threadId;
+ }
+ return reinterpret_cast<uint64_t>(tlsValue);
+}
+#else
+uint64_t GetCurrentThreadUniqueId()
+{
+ thread_local uint64_t threadId(globalThreadSerial++);
+ return threadId;
+}
+#endif
+
+} // namespace angle
diff --git a/gfx/angle/checkout/src/common/system_utils.h b/gfx/angle/checkout/src/common/system_utils.h
new file mode 100644
index 0000000000..d9e435afaa
--- /dev/null
+++ b/gfx/angle/checkout/src/common/system_utils.h
@@ -0,0 +1,224 @@
+//
+// 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.
+//
+
+// system_utils.h: declaration of OS-specific utility functions
+
+#ifndef COMMON_SYSTEM_UTILS_H_
+#define COMMON_SYSTEM_UTILS_H_
+
+#include "common/Optional.h"
+#include "common/angleutils.h"
+
+#include <functional>
+#include <string>
+#include <string_view>
+
+namespace angle
+{
+std::string GetExecutableName();
+std::string GetExecutablePath();
+std::string GetExecutableDirectory();
+std::string GetModuleDirectory();
+const char *GetSharedLibraryExtension();
+const char *GetExecutableExtension();
+char GetPathSeparator();
+Optional<std::string> GetCWD();
+bool SetCWD(const char *dirName);
+bool SetEnvironmentVar(const char *variableName, const char *value);
+bool UnsetEnvironmentVar(const char *variableName);
+bool GetBoolEnvironmentVar(const char *variableName);
+std::string GetEnvironmentVar(const char *variableName);
+std::string GetEnvironmentVarOrUnCachedAndroidProperty(const char *variableName,
+ const char *propertyName);
+std::string GetAndSetEnvironmentVarOrUnCachedAndroidProperty(const char *variableName,
+ const char *propertyName);
+std::string GetEnvironmentVarOrAndroidProperty(const char *variableName, const char *propertyName);
+const char *GetPathSeparatorForEnvironmentVar();
+bool PrependPathToEnvironmentVar(const char *variableName, const char *path);
+bool IsDirectory(const char *filename);
+bool IsFullPath(std::string dirName);
+std::string GetRootDirectory();
+std::string ConcatenatePath(std::string first, std::string second);
+
+Optional<std::string> GetTempDirectory();
+Optional<std::string> CreateTemporaryFileInDirectory(const std::string &directory);
+Optional<std::string> CreateTemporaryFile();
+
+// Get absolute time in seconds. Use this function to get an absolute time with an unknown origin.
+double GetCurrentSystemTime();
+// Get CPU time for current process in seconds.
+double GetCurrentProcessCpuTime();
+
+// Unique thread id (std::this_thread::get_id() gets recycled!)
+uint64_t GetCurrentThreadUniqueId();
+
+// Run an application and get the output. Gets a nullptr-terminated set of args to execute the
+// application with, and returns the stdout and stderr outputs as well as the exit code.
+//
+// Pass nullptr for stdoutOut/stderrOut if you don't need to capture. exitCodeOut is required.
+//
+// Returns false if it fails to actually execute the application.
+bool RunApp(const std::vector<const char *> &args,
+ std::string *stdoutOut,
+ std::string *stderrOut,
+ int *exitCodeOut);
+
+// Use SYSTEM_DIR to bypass loading ANGLE libraries with the same name as system DLLS
+// (e.g. opengl32.dll)
+enum class SearchType
+{
+ // Try to find the library in the same directory as the current module
+ ModuleDir,
+ // Load the library from the system directories
+ SystemDir,
+ // Get a reference to an already loaded shared library.
+ AlreadyLoaded,
+};
+
+void *OpenSystemLibrary(const char *libraryName, SearchType searchType);
+void *OpenSystemLibraryWithExtension(const char *libraryName, SearchType searchType);
+void *OpenSystemLibraryAndGetError(const char *libraryName,
+ SearchType searchType,
+ std::string *errorOut);
+void *OpenSystemLibraryWithExtensionAndGetError(const char *libraryName,
+ SearchType searchType,
+ std::string *errorOut);
+
+void *GetLibrarySymbol(void *libraryHandle, const char *symbolName);
+std::string GetLibraryPath(void *libraryHandle);
+void CloseSystemLibrary(void *libraryHandle);
+
+class Library : angle::NonCopyable
+{
+ public:
+ Library() {}
+ Library(void *libraryHandle) : mLibraryHandle(libraryHandle) {}
+ ~Library() { close(); }
+
+ [[nodiscard]] bool open(const char *libraryName, SearchType searchType)
+ {
+ close();
+ mLibraryHandle = OpenSystemLibrary(libraryName, searchType);
+ return mLibraryHandle != nullptr;
+ }
+
+ [[nodiscard]] bool openWithExtension(const char *libraryName, SearchType searchType)
+ {
+ close();
+ mLibraryHandle = OpenSystemLibraryWithExtension(libraryName, searchType);
+ return mLibraryHandle != nullptr;
+ }
+
+ [[nodiscard]] bool openAndGetError(const char *libraryName,
+ SearchType searchType,
+ std::string *errorOut)
+ {
+ close();
+ mLibraryHandle = OpenSystemLibraryAndGetError(libraryName, searchType, errorOut);
+ return mLibraryHandle != nullptr;
+ }
+
+ [[nodiscard]] bool openWithExtensionAndGetError(const char *libraryName,
+ SearchType searchType,
+ std::string *errorOut)
+ {
+ close();
+ mLibraryHandle =
+ OpenSystemLibraryWithExtensionAndGetError(libraryName, searchType, errorOut);
+ return mLibraryHandle != nullptr;
+ }
+
+ void close()
+ {
+ if (mLibraryHandle)
+ {
+ CloseSystemLibrary(mLibraryHandle);
+ mLibraryHandle = nullptr;
+ }
+ }
+
+ void *getSymbol(const char *symbolName) { return GetLibrarySymbol(mLibraryHandle, symbolName); }
+
+ void *getNative() const { return mLibraryHandle; }
+
+ std::string getPath() const { return GetLibraryPath(mLibraryHandle); }
+
+ template <typename FuncT>
+ void getAs(const char *symbolName, FuncT *funcOut)
+ {
+ *funcOut = reinterpret_cast<FuncT>(getSymbol(symbolName));
+ }
+
+ private:
+ void *mLibraryHandle = nullptr;
+};
+
+Library *OpenSharedLibrary(const char *libraryName, SearchType searchType);
+Library *OpenSharedLibraryWithExtension(const char *libraryName, SearchType searchType);
+Library *OpenSharedLibraryAndGetError(const char *libraryName,
+ SearchType searchType,
+ std::string *errorOut);
+Library *OpenSharedLibraryWithExtensionAndGetError(const char *libraryName,
+ SearchType searchType,
+ std::string *errorOut);
+
+// Returns true if the process is currently being debugged.
+bool IsDebuggerAttached();
+
+// Calls system APIs to break into the debugger.
+void BreakDebugger();
+
+uint64_t GetProcessMemoryUsageKB();
+
+bool ProtectMemory(uintptr_t start, size_t size);
+bool UnprotectMemory(uintptr_t start, size_t size);
+
+size_t GetPageSize();
+
+// Return type of the PageFaultCallback
+enum class PageFaultHandlerRangeType
+{
+ // The memory address was known by the page fault handler
+ InRange,
+ // The memory address was not in the page fault handler's range
+ // and the signal will be forwarded to the default page handler.
+ OutOfRange,
+};
+
+using PageFaultCallback = std::function<PageFaultHandlerRangeType(uintptr_t)>;
+
+class PageFaultHandler : angle::NonCopyable
+{
+ public:
+ PageFaultHandler(PageFaultCallback callback);
+ virtual ~PageFaultHandler();
+
+ // Registers OS level page fault handler for memory protection signals
+ // and enables reception on PageFaultCallback
+ virtual bool enable() = 0;
+
+ // Unregisters OS level page fault handler and deactivates PageFaultCallback
+ virtual bool disable() = 0;
+
+ protected:
+ PageFaultCallback mCallback;
+};
+
+// Creates single instance page fault handler
+PageFaultHandler *CreatePageFaultHandler(PageFaultCallback callback);
+
+#ifdef ANGLE_PLATFORM_WINDOWS
+// Convert an UTF-16 wstring to an UTF-8 string.
+std::string Narrow(const std::wstring_view &utf16);
+
+// Convert an UTF-8 string to an UTF-16 wstring.
+std::wstring Widen(const std::string_view &utf8);
+#endif
+
+std::string StripFilenameFromPath(const std::string &path);
+} // namespace angle
+
+#endif // COMMON_SYSTEM_UTILS_H_
diff --git a/gfx/angle/checkout/src/common/system_utils_apple.cpp b/gfx/angle/checkout/src/common/system_utils_apple.cpp
new file mode 100644
index 0000000000..532714248c
--- /dev/null
+++ b/gfx/angle/checkout/src/common/system_utils_apple.cpp
@@ -0,0 +1,59 @@
+//
+// Copyright 2020 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.
+//
+
+// system_utils_apple.cpp: Implementation of OS-specific functions for Apple platforms
+
+#include "system_utils.h"
+
+#include <unistd.h>
+
+#include <CoreServices/CoreServices.h>
+#include <mach-o/dyld.h>
+#include <mach/mach.h>
+#include <mach/mach_time.h>
+#include <cstdlib>
+#include <vector>
+
+#include <array>
+
+namespace angle
+{
+std::string GetExecutablePath()
+{
+ std::string result;
+
+ uint32_t size = 0;
+ _NSGetExecutablePath(nullptr, &size);
+
+ std::vector<char> buffer;
+ buffer.resize(size + 1);
+
+ _NSGetExecutablePath(buffer.data(), &size);
+ buffer[size] = '\0';
+
+ if (!strrchr(buffer.data(), '/'))
+ {
+ return "";
+ }
+ return buffer.data();
+}
+
+std::string GetExecutableDirectory()
+{
+ std::string executablePath = GetExecutablePath();
+ size_t lastPathSepLoc = executablePath.find_last_of("/");
+ return (lastPathSepLoc != std::string::npos) ? executablePath.substr(0, lastPathSepLoc) : "";
+}
+
+double GetCurrentSystemTime()
+{
+ mach_timebase_info_data_t timebaseInfo;
+ mach_timebase_info(&timebaseInfo);
+
+ double secondCoeff = timebaseInfo.numer * 1e-9 / timebaseInfo.denom;
+ return secondCoeff * mach_absolute_time();
+}
+} // namespace angle
diff --git a/gfx/angle/checkout/src/common/system_utils_linux.cpp b/gfx/angle/checkout/src/common/system_utils_linux.cpp
new file mode 100644
index 0000000000..da0ed86028
--- /dev/null
+++ b/gfx/angle/checkout/src/common/system_utils_linux.cpp
@@ -0,0 +1,55 @@
+//
+// 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.
+//
+
+// system_utils_linux.cpp: Implementation of OS-specific functions for Linux
+
+#include "system_utils.h"
+
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <array>
+
+namespace angle
+{
+std::string GetExecutablePath()
+{
+ // We cannot use lstat to get the size of /proc/self/exe as it always returns 0
+ // so we just use a big buffer and hope the path fits in it.
+ char path[4096];
+
+ ssize_t result = readlink("/proc/self/exe", path, sizeof(path) - 1);
+ if (result < 0 || static_cast<size_t>(result) >= sizeof(path) - 1)
+ {
+ return "";
+ }
+
+ path[result] = '\0';
+ return path;
+}
+
+std::string GetExecutableDirectory()
+{
+ std::string executablePath = GetExecutablePath();
+ size_t lastPathSepLoc = executablePath.find_last_of("/");
+ return (lastPathSepLoc != std::string::npos) ? executablePath.substr(0, lastPathSepLoc) : "";
+}
+
+const char *GetSharedLibraryExtension()
+{
+ return "so";
+}
+
+double GetCurrentSystemTime()
+{
+ struct timespec currentTime;
+ clock_gettime(CLOCK_MONOTONIC, &currentTime);
+ return currentTime.tv_sec + currentTime.tv_nsec * 1e-9;
+}
+
+} // namespace angle
diff --git a/gfx/angle/checkout/src/common/system_utils_mac.cpp b/gfx/angle/checkout/src/common/system_utils_mac.cpp
new file mode 100644
index 0000000000..2c48a7eb04
--- /dev/null
+++ b/gfx/angle/checkout/src/common/system_utils_mac.cpp
@@ -0,0 +1,28 @@
+//
+// 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.
+//
+
+// system_utils_osx.cpp: Implementation of OS-specific functions for OSX
+
+#include "system_utils.h"
+
+#include <unistd.h>
+
+#include <CoreServices/CoreServices.h>
+#include <mach-o/dyld.h>
+#include <mach/mach.h>
+#include <mach/mach_time.h>
+#include <cstdlib>
+#include <vector>
+
+#include <array>
+
+namespace angle
+{
+const char *GetSharedLibraryExtension()
+{
+ return "dylib";
+}
+} // namespace angle
diff --git a/gfx/angle/checkout/src/common/system_utils_posix.cpp b/gfx/angle/checkout/src/common/system_utils_posix.cpp
new file mode 100644
index 0000000000..ab0faee0bc
--- /dev/null
+++ b/gfx/angle/checkout/src/common/system_utils_posix.cpp
@@ -0,0 +1,470 @@
+//
+// Copyright 2018 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.
+//
+
+// system_utils_posix.cpp: Implementation of POSIX OS-specific functions.
+
+#include "common/debug.h"
+#include "system_utils.h"
+
+#include <array>
+#include <iostream>
+
+#include <dlfcn.h>
+#include <grp.h>
+#include <inttypes.h>
+#include <pwd.h>
+#include <signal.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include "common/string_utils.h"
+
+#ifdef ANGLE_PLATFORM_FUCHSIA
+# include <zircon/process.h>
+# include <zircon/syscalls.h>
+#else
+# include <sys/resource.h>
+#endif
+
+namespace angle
+{
+
+namespace
+{
+std::string GetModulePath(void *moduleOrSymbol)
+{
+ Dl_info dlInfo;
+ if (dladdr(moduleOrSymbol, &dlInfo) == 0)
+ {
+ return "";
+ }
+
+ return dlInfo.dli_fname;
+}
+
+void *OpenPosixLibrary(const std::string &fullPath, int extraFlags, std::string *errorOut)
+{
+ void *module = dlopen(fullPath.c_str(), RTLD_NOW | extraFlags);
+ if (module)
+ {
+ if (errorOut)
+ {
+ *errorOut = fullPath;
+ }
+ }
+ else if (errorOut)
+ {
+ *errorOut = "dlopen(";
+ *errorOut += fullPath;
+ *errorOut += ") failed with error: ";
+ *errorOut += dlerror();
+ struct stat sfile;
+ if (-1 == stat(fullPath.c_str(), &sfile))
+ {
+ *errorOut += ", stat() call failed.";
+ }
+ else
+ {
+ *errorOut += ", stat() info: ";
+ struct passwd *pwuser = getpwuid(sfile.st_uid);
+ if (pwuser)
+ {
+ *errorOut += "owner: ";
+ *errorOut += pwuser->pw_name;
+ *errorOut += ", ";
+ }
+ struct group *grpnam = getgrgid(sfile.st_gid);
+ if (grpnam)
+ {
+ *errorOut += "group: ";
+ *errorOut += grpnam->gr_name;
+ *errorOut += ", ";
+ }
+ *errorOut += "perms: ";
+ *errorOut += std::to_string(sfile.st_mode);
+ *errorOut += ", links: ";
+ *errorOut += std::to_string(sfile.st_nlink);
+ *errorOut += ", size: ";
+ *errorOut += std::to_string(sfile.st_size);
+ }
+ }
+ return module;
+}
+} // namespace
+
+Optional<std::string> GetCWD()
+{
+ std::array<char, 4096> pathBuf;
+ char *result = getcwd(pathBuf.data(), pathBuf.size());
+ if (result == nullptr)
+ {
+ return Optional<std::string>::Invalid();
+ }
+ return std::string(pathBuf.data());
+}
+
+bool SetCWD(const char *dirName)
+{
+ return (chdir(dirName) == 0);
+}
+
+bool UnsetEnvironmentVar(const char *variableName)
+{
+ return (unsetenv(variableName) == 0);
+}
+
+bool SetEnvironmentVar(const char *variableName, const char *value)
+{
+ return (setenv(variableName, value, 1) == 0);
+}
+
+std::string GetEnvironmentVar(const char *variableName)
+{
+ const char *value = getenv(variableName);
+ return (value == nullptr ? std::string() : std::string(value));
+}
+
+const char *GetPathSeparatorForEnvironmentVar()
+{
+ return ":";
+}
+
+std::string GetModuleDirectoryAndGetError(std::string *errorOut)
+{
+ std::string directory;
+ static int placeholderSymbol = 0;
+ std::string moduleName = GetModulePath(&placeholderSymbol);
+ if (!moduleName.empty())
+ {
+ directory = moduleName.substr(0, moduleName.find_last_of('/') + 1);
+ }
+
+ // Ensure we return the full path to the module, not the relative path
+ if (!IsFullPath(directory))
+ {
+ if (errorOut)
+ {
+ *errorOut += "Directory: '";
+ *errorOut += directory;
+ *errorOut += "' is not full path";
+ }
+ Optional<std::string> cwd = GetCWD();
+ if (cwd.valid())
+ {
+ directory = ConcatenatePath(cwd.value(), directory);
+ if (errorOut)
+ {
+ *errorOut += ", so it has been modified to: '";
+ *errorOut += directory;
+ *errorOut += "'. ";
+ }
+ }
+ else if (errorOut)
+ {
+ *errorOut += " and getcwd was invalid. ";
+ }
+ }
+ return directory;
+}
+
+std::string GetModuleDirectory()
+{
+ return GetModuleDirectoryAndGetError(nullptr);
+}
+
+void *OpenSystemLibraryWithExtensionAndGetError(const char *libraryName,
+ SearchType searchType,
+ std::string *errorOut)
+{
+ std::string directory;
+ if (searchType == SearchType::ModuleDir)
+ {
+#if ANGLE_PLATFORM_IOS
+ // On iOS, shared libraries must be loaded from within the app bundle.
+ directory = GetExecutableDirectory() + "/Frameworks/";
+#elif ANGLE_PLATFORM_FUCHSIA
+ // On Fuchsia the dynamic loader always looks up libraries in /pkg/lib
+ // and disallows loading of libraries via absolute paths.
+ directory = "";
+#else
+ directory = GetModuleDirectoryAndGetError(errorOut);
+#endif
+ }
+
+ int extraFlags = 0;
+ if (searchType == SearchType::AlreadyLoaded)
+ {
+ extraFlags = RTLD_NOLOAD;
+ }
+
+ std::string fullPath = directory + libraryName;
+ return OpenPosixLibrary(fullPath, extraFlags, errorOut);
+}
+
+void *GetLibrarySymbol(void *libraryHandle, const char *symbolName)
+{
+ if (!libraryHandle)
+ {
+ return nullptr;
+ }
+
+ return dlsym(libraryHandle, symbolName);
+}
+
+std::string GetLibraryPath(void *libraryHandle)
+{
+ if (!libraryHandle)
+ {
+ return "";
+ }
+
+ return GetModulePath(libraryHandle);
+}
+
+void CloseSystemLibrary(void *libraryHandle)
+{
+ if (libraryHandle)
+ {
+ dlclose(libraryHandle);
+ }
+}
+
+bool IsDirectory(const char *filename)
+{
+ struct stat st;
+ int result = stat(filename, &st);
+ return result == 0 && ((st.st_mode & S_IFDIR) == S_IFDIR);
+}
+
+bool IsDebuggerAttached()
+{
+ // This could have a fuller implementation.
+ // See https://cs.chromium.org/chromium/src/base/debug/debugger_posix.cc
+ return false;
+}
+
+void BreakDebugger()
+{
+ // This could have a fuller implementation.
+ // See https://cs.chromium.org/chromium/src/base/debug/debugger_posix.cc
+ abort();
+}
+
+const char *GetExecutableExtension()
+{
+ return "";
+}
+
+char GetPathSeparator()
+{
+ return '/';
+}
+
+std::string GetRootDirectory()
+{
+ return "/";
+}
+
+Optional<std::string> GetTempDirectory()
+{
+ const char *tmp = getenv("TMPDIR");
+ if (tmp != nullptr)
+ {
+ return std::string(tmp);
+ }
+
+#if defined(ANGLE_PLATFORM_ANDROID)
+ // Not used right now in the ANGLE test runner.
+ // return PathService::Get(DIR_CACHE, path);
+ return Optional<std::string>::Invalid();
+#else
+ return std::string("/tmp");
+#endif
+}
+
+Optional<std::string> CreateTemporaryFileInDirectory(const std::string &directory)
+{
+ std::string tempFileTemplate = directory + "/.angle.XXXXXX";
+
+ char tempFile[1000];
+ strcpy(tempFile, tempFileTemplate.c_str());
+
+ int fd = mkstemp(tempFile);
+ close(fd);
+
+ if (fd != -1)
+ {
+ return std::string(tempFile);
+ }
+
+ return Optional<std::string>::Invalid();
+}
+
+double GetCurrentProcessCpuTime()
+{
+#ifdef ANGLE_PLATFORM_FUCHSIA
+ static zx_handle_t me = zx_process_self();
+ zx_info_task_runtime_t task_runtime;
+ zx_object_get_info(me, ZX_INFO_TASK_RUNTIME, &task_runtime, sizeof(task_runtime), nullptr,
+ nullptr);
+ return static_cast<double>(task_runtime.cpu_time) * 1e-9;
+#else
+ // We could also have used /proc/stat, but that requires us to read the
+ // filesystem and convert from jiffies. /proc/stat also relies on jiffies
+ // (lower resolution) while getrusage can potentially use a sched_clock()
+ // underneath that has higher resolution.
+ struct rusage usage;
+ getrusage(RUSAGE_SELF, &usage);
+ double userTime = usage.ru_utime.tv_sec + usage.ru_utime.tv_usec * 1e-6;
+ double systemTime = usage.ru_stime.tv_sec + usage.ru_stime.tv_usec * 1e-6;
+ return userTime + systemTime;
+#endif
+}
+
+namespace
+{
+bool SetMemoryProtection(uintptr_t start, size_t size, int protections)
+{
+ int ret = mprotect(reinterpret_cast<void *>(start), size, protections);
+ if (ret < 0)
+ {
+ perror("mprotect failed");
+ }
+ return ret == 0;
+}
+
+class PosixPageFaultHandler : public PageFaultHandler
+{
+ public:
+ PosixPageFaultHandler(PageFaultCallback callback) : PageFaultHandler(callback) {}
+ ~PosixPageFaultHandler() override {}
+
+ bool enable() override;
+ bool disable() override;
+ void handle(int sig, siginfo_t *info, void *unused);
+
+ private:
+ struct sigaction mDefaultBusAction = {};
+ struct sigaction mDefaultSegvAction = {};
+};
+
+PosixPageFaultHandler *gPosixPageFaultHandler = nullptr;
+void SegfaultHandlerFunction(int sig, siginfo_t *info, void *unused)
+{
+ gPosixPageFaultHandler->handle(sig, info, unused);
+}
+
+void PosixPageFaultHandler::handle(int sig, siginfo_t *info, void *unused)
+{
+ bool found = false;
+ if ((sig == SIGSEGV || sig == SIGBUS) &&
+ (info->si_code == SEGV_ACCERR || info->si_code == SEGV_MAPERR))
+ {
+ found = mCallback(reinterpret_cast<uintptr_t>(info->si_addr)) ==
+ PageFaultHandlerRangeType::InRange;
+ }
+
+ // Fall back to default signal handler
+ if (!found)
+ {
+ if (sig == SIGSEGV)
+ {
+ mDefaultSegvAction.sa_sigaction(sig, info, unused);
+ }
+ else if (sig == SIGBUS)
+ {
+ mDefaultBusAction.sa_sigaction(sig, info, unused);
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+ }
+}
+
+bool PosixPageFaultHandler::disable()
+{
+ return sigaction(SIGSEGV, &mDefaultSegvAction, nullptr) == 0 &&
+ sigaction(SIGBUS, &mDefaultBusAction, nullptr) == 0;
+}
+
+bool PosixPageFaultHandler::enable()
+{
+ struct sigaction sigAction = {};
+ sigAction.sa_flags = SA_SIGINFO;
+ sigAction.sa_sigaction = &SegfaultHandlerFunction;
+ sigemptyset(&sigAction.sa_mask);
+
+ // Some POSIX implementations use SIGBUS for mprotect faults
+ return sigaction(SIGSEGV, &sigAction, &mDefaultSegvAction) == 0 &&
+ sigaction(SIGBUS, &sigAction, &mDefaultBusAction) == 0;
+}
+} // namespace
+
+// Set write protection
+bool ProtectMemory(uintptr_t start, size_t size)
+{
+ return SetMemoryProtection(start, size, PROT_READ);
+}
+
+// Allow reading and writing
+bool UnprotectMemory(uintptr_t start, size_t size)
+{
+ return SetMemoryProtection(start, size, PROT_READ | PROT_WRITE);
+}
+
+size_t GetPageSize()
+{
+ long pageSize = sysconf(_SC_PAGE_SIZE);
+ if (pageSize < 0)
+ {
+ perror("Could not get sysconf page size");
+ return 0;
+ }
+ return static_cast<size_t>(pageSize);
+}
+
+PageFaultHandler *CreatePageFaultHandler(PageFaultCallback callback)
+{
+ gPosixPageFaultHandler = new PosixPageFaultHandler(callback);
+ return gPosixPageFaultHandler;
+}
+
+uint64_t GetProcessMemoryUsageKB()
+{
+ FILE *file = fopen("/proc/self/status", "r");
+
+ if (!file)
+ {
+ return 0;
+ }
+
+ const char *kSearchString = "VmRSS:";
+ constexpr size_t kMaxLineSize = 100;
+ std::array<char, kMaxLineSize> line = {};
+
+ uint64_t kb = 0;
+
+ while (fgets(line.data(), line.size(), file) != nullptr)
+ {
+ if (strncmp(line.data(), kSearchString, strlen(kSearchString)) == 0)
+ {
+ std::vector<std::string> strings;
+ SplitStringAlongWhitespace(line.data(), &strings);
+
+ sscanf(strings[1].c_str(), "%" SCNu64, &kb);
+ break;
+ }
+ }
+ fclose(file);
+
+ return kb;
+}
+} // namespace angle
diff --git a/gfx/angle/checkout/src/common/system_utils_win.cpp b/gfx/angle/checkout/src/common/system_utils_win.cpp
new file mode 100644
index 0000000000..8770235cd7
--- /dev/null
+++ b/gfx/angle/checkout/src/common/system_utils_win.cpp
@@ -0,0 +1,264 @@
+//
+// 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.
+//
+
+// system_utils_win.cpp: Implementation of OS-specific functions for Windows
+
+#include "system_utils.h"
+
+#include <stdarg.h>
+#include <windows.h>
+#include <array>
+#include <vector>
+
+namespace angle
+{
+
+namespace
+{
+
+std::string GetPath(HMODULE module)
+{
+ std::array<wchar_t, MAX_PATH> executableFileBuf;
+ DWORD executablePathLen = GetModuleFileNameW(module, executableFileBuf.data(),
+ static_cast<DWORD>(executableFileBuf.size()));
+ return Narrow(executablePathLen > 0 ? executableFileBuf.data() : L"");
+}
+
+std::string GetDirectory(HMODULE module)
+{
+ std::string executablePath = GetPath(module);
+ return StripFilenameFromPath(executablePath);
+}
+
+} // anonymous namespace
+
+std::string GetExecutablePath()
+{
+ return GetPath(nullptr);
+}
+
+std::string GetExecutableDirectory()
+{
+ return GetDirectory(nullptr);
+}
+
+const char *GetSharedLibraryExtension()
+{
+ return "dll";
+}
+
+Optional<std::string> GetCWD()
+{
+ std::array<wchar_t, MAX_PATH> pathBuf;
+ DWORD result = GetCurrentDirectoryW(static_cast<DWORD>(pathBuf.size()), pathBuf.data());
+ if (result == 0)
+ {
+ return Optional<std::string>::Invalid();
+ }
+ return Narrow(pathBuf.data());
+}
+
+bool SetCWD(const char *dirName)
+{
+ return (SetCurrentDirectoryW(Widen(dirName).c_str()) == TRUE);
+}
+
+const char *GetPathSeparatorForEnvironmentVar()
+{
+ return ";";
+}
+
+double GetCurrentSystemTime()
+{
+ LARGE_INTEGER frequency = {};
+ QueryPerformanceFrequency(&frequency);
+
+ LARGE_INTEGER curTime;
+ QueryPerformanceCounter(&curTime);
+
+ return static_cast<double>(curTime.QuadPart) / frequency.QuadPart;
+}
+
+double GetCurrentProcessCpuTime()
+{
+ FILETIME creationTime = {};
+ FILETIME exitTime = {};
+ FILETIME kernelTime = {};
+ FILETIME userTime = {};
+
+ // Note this will not give accurate results if the current thread is
+ // scheduled for less than the tick rate, which is often 15 ms. In that
+ // case, GetProcessTimes will not return different values, making it
+ // possible to end up with 0 ms for a process that takes 93% of a core
+ // (14/15 ms)! An alternative is QueryProcessCycleTime but there is no
+ // simple way to convert cycles back to seconds, and on top of that, it's
+ // not supported pre-Windows Vista.
+
+ // Returns 100-ns intervals, so we want to divide by 1e7 to get seconds
+ GetProcessTimes(GetCurrentProcess(), &creationTime, &exitTime, &kernelTime, &userTime);
+
+ ULARGE_INTEGER kernelInt64;
+ kernelInt64.LowPart = kernelTime.dwLowDateTime;
+ kernelInt64.HighPart = kernelTime.dwHighDateTime;
+ double systemTimeSeconds = static_cast<double>(kernelInt64.QuadPart) * 1e-7;
+
+ ULARGE_INTEGER userInt64;
+ userInt64.LowPart = userTime.dwLowDateTime;
+ userInt64.HighPart = userTime.dwHighDateTime;
+ double userTimeSeconds = static_cast<double>(userInt64.QuadPart) * 1e-7;
+
+ return systemTimeSeconds + userTimeSeconds;
+}
+
+bool IsDirectory(const char *filename)
+{
+ WIN32_FILE_ATTRIBUTE_DATA fileInformation;
+
+ BOOL result =
+ GetFileAttributesExW(Widen(filename).c_str(), GetFileExInfoStandard, &fileInformation);
+ if (result)
+ {
+ DWORD attribs = fileInformation.dwFileAttributes;
+ return (attribs != INVALID_FILE_ATTRIBUTES) && ((attribs & FILE_ATTRIBUTE_DIRECTORY) > 0);
+ }
+
+ return false;
+}
+
+bool IsDebuggerAttached()
+{
+ return !!::IsDebuggerPresent();
+}
+
+void BreakDebugger()
+{
+ __debugbreak();
+}
+
+const char *GetExecutableExtension()
+{
+ return ".exe";
+}
+
+char GetPathSeparator()
+{
+ return '\\';
+}
+
+std::string GetModuleDirectory()
+{
+// GetModuleHandleEx is unavailable on UWP
+#if !defined(ANGLE_IS_WINUWP)
+ static int placeholderSymbol = 0;
+ HMODULE module = nullptr;
+ if (GetModuleHandleExW(
+ GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
+ reinterpret_cast<LPCWSTR>(&placeholderSymbol), &module))
+ {
+ return GetDirectory(module);
+ }
+#endif
+ return GetDirectory(nullptr);
+}
+
+std::string GetRootDirectory()
+{
+ return "C:\\";
+}
+
+Optional<std::string> GetTempDirectory()
+{
+ char tempDirOut[MAX_PATH + 1];
+ GetTempPathA(MAX_PATH + 1, tempDirOut);
+ std::string tempDir = std::string(tempDirOut);
+
+ if (tempDir.length() < 0 || tempDir.length() > MAX_PATH)
+ {
+ return Optional<std::string>::Invalid();
+ }
+
+ if (tempDir.length() > 0 && tempDir.back() == '\\')
+ {
+ tempDir.pop_back();
+ }
+
+ return tempDir;
+}
+
+Optional<std::string> CreateTemporaryFileInDirectory(const std::string &directory)
+{
+ char fileName[MAX_PATH + 1];
+ if (GetTempFileNameA(directory.c_str(), "ANGLE", 0, fileName) == 0)
+ return Optional<std::string>::Invalid();
+
+ return std::string(fileName);
+}
+
+std::string GetLibraryPath(void *libraryHandle)
+{
+ if (!libraryHandle)
+ {
+ return "";
+ }
+
+ std::array<wchar_t, MAX_PATH> buffer;
+ if (GetModuleFileNameW(reinterpret_cast<HMODULE>(libraryHandle), buffer.data(),
+ buffer.size()) == 0)
+ {
+ return "";
+ }
+
+ return Narrow(buffer.data());
+}
+
+void *GetLibrarySymbol(void *libraryHandle, const char *symbolName)
+{
+ if (!libraryHandle)
+ {
+ fprintf(stderr, "Module was not loaded\n");
+ return nullptr;
+ }
+
+ return reinterpret_cast<void *>(
+ GetProcAddress(reinterpret_cast<HMODULE>(libraryHandle), symbolName));
+}
+
+void CloseSystemLibrary(void *libraryHandle)
+{
+ if (libraryHandle)
+ {
+ FreeLibrary(reinterpret_cast<HMODULE>(libraryHandle));
+ }
+}
+std::string Narrow(const std::wstring_view &utf16)
+{
+ if (utf16.empty())
+ {
+ return {};
+ }
+ int requiredSize = WideCharToMultiByte(CP_UTF8, 0, utf16.data(), static_cast<int>(utf16.size()),
+ nullptr, 0, nullptr, nullptr);
+ std::string utf8(requiredSize, '\0');
+ WideCharToMultiByte(CP_UTF8, 0, utf16.data(), static_cast<int>(utf16.size()), &utf8[0],
+ requiredSize, nullptr, nullptr);
+ return utf8;
+}
+
+std::wstring Widen(const std::string_view &utf8)
+{
+ if (utf8.empty())
+ {
+ return {};
+ }
+ int requiredSize =
+ MultiByteToWideChar(CP_UTF8, 0, utf8.data(), static_cast<int>(utf8.size()), nullptr, 0);
+ std::wstring utf16(requiredSize, L'\0');
+ MultiByteToWideChar(CP_UTF8, 0, utf8.data(), static_cast<int>(utf8.size()), &utf16[0],
+ requiredSize);
+ return utf16;
+}
+
+} // namespace angle
diff --git a/gfx/angle/checkout/src/common/system_utils_win32.cpp b/gfx/angle/checkout/src/common/system_utils_win32.cpp
new file mode 100644
index 0000000000..5bcfa2347e
--- /dev/null
+++ b/gfx/angle/checkout/src/common/system_utils_win32.cpp
@@ -0,0 +1,235 @@
+//
+// Copyright 2019 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.
+//
+// system_utils_win32.cpp: Implementation of OS-specific functions for Windows.
+
+#include "common/FastVector.h"
+#include "system_utils.h"
+
+#include <array>
+
+// Must be included in this order.
+// clang-format off
+#include <windows.h>
+#include <psapi.h>
+// clang-format on
+
+namespace angle
+{
+bool UnsetEnvironmentVar(const char *variableName)
+{
+ return (SetEnvironmentVariableW(Widen(variableName).c_str(), nullptr) == TRUE);
+}
+
+bool SetEnvironmentVar(const char *variableName, const char *value)
+{
+ return (SetEnvironmentVariableW(Widen(variableName).c_str(), Widen(value).c_str()) == TRUE);
+}
+
+std::string GetEnvironmentVar(const char *variableName)
+{
+ std::wstring variableNameUtf16 = Widen(variableName);
+ FastVector<wchar_t, MAX_PATH> value;
+
+ DWORD result;
+
+ // First get the length of the variable, including the null terminator
+ result = GetEnvironmentVariableW(variableNameUtf16.c_str(), nullptr, 0);
+
+ // Zero means the variable was not found, so return now.
+ if (result == 0)
+ {
+ return std::string();
+ }
+
+ // Now size the vector to fit the data, and read the environment variable.
+ value.resize(result, 0);
+ result = GetEnvironmentVariableW(variableNameUtf16.c_str(), value.data(), result);
+
+ return Narrow(value.data());
+}
+
+void *OpenSystemLibraryWithExtensionAndGetError(const char *libraryName,
+ SearchType searchType,
+ std::string *errorOut)
+{
+ char buffer[MAX_PATH];
+ int ret = snprintf(buffer, MAX_PATH, "%s.%s", libraryName, GetSharedLibraryExtension());
+ if (ret <= 0 || ret >= MAX_PATH)
+ {
+ fprintf(stderr, "Error loading shared library: 0x%x", ret);
+ return nullptr;
+ }
+
+ HMODULE libraryModule = nullptr;
+
+ switch (searchType)
+ {
+ case SearchType::ModuleDir:
+ {
+ std::string moduleRelativePath = ConcatenatePath(GetModuleDirectory(), libraryName);
+ if (errorOut)
+ {
+ *errorOut = moduleRelativePath;
+ }
+ libraryModule = LoadLibraryW(Widen(moduleRelativePath).c_str());
+ break;
+ }
+
+ case SearchType::SystemDir:
+ {
+ if (errorOut)
+ {
+ *errorOut = libraryName;
+ }
+ libraryModule =
+ LoadLibraryExW(Widen(libraryName).c_str(), nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
+ break;
+ }
+
+ case SearchType::AlreadyLoaded:
+ {
+ if (errorOut)
+ {
+ *errorOut = libraryName;
+ }
+ libraryModule = GetModuleHandleW(Widen(libraryName).c_str());
+ break;
+ }
+ }
+
+ return reinterpret_cast<void *>(libraryModule);
+}
+
+namespace
+{
+class Win32PageFaultHandler : public PageFaultHandler
+{
+ public:
+ Win32PageFaultHandler(PageFaultCallback callback) : PageFaultHandler(callback) {}
+ ~Win32PageFaultHandler() override {}
+
+ bool enable() override;
+ bool disable() override;
+
+ LONG handle(PEXCEPTION_POINTERS pExceptionInfo);
+
+ private:
+ void *mVectoredExceptionHandler = nullptr;
+};
+
+Win32PageFaultHandler *gWin32PageFaultHandler = nullptr;
+static LONG CALLBACK VectoredExceptionHandler(PEXCEPTION_POINTERS info)
+{
+ return gWin32PageFaultHandler->handle(info);
+}
+
+bool SetMemoryProtection(uintptr_t start, size_t size, DWORD protections)
+{
+ DWORD oldProtect;
+ BOOL res = VirtualProtect(reinterpret_cast<LPVOID>(start), size, protections, &oldProtect);
+ if (!res)
+ {
+ DWORD lastError = GetLastError();
+ fprintf(stderr, "VirtualProtect failed: 0x%lx\n", lastError);
+ return false;
+ }
+
+ return true;
+}
+
+LONG Win32PageFaultHandler::handle(PEXCEPTION_POINTERS info)
+{
+ bool found = false;
+
+ if (info->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION &&
+ info->ExceptionRecord->NumberParameters >= 2 &&
+ info->ExceptionRecord->ExceptionInformation[0] == 1)
+ {
+ found = mCallback(static_cast<uintptr_t>(info->ExceptionRecord->ExceptionInformation[1])) ==
+ PageFaultHandlerRangeType::InRange;
+ }
+
+ if (found)
+ {
+ return EXCEPTION_CONTINUE_EXECUTION;
+ }
+ else
+ {
+ return EXCEPTION_CONTINUE_SEARCH;
+ }
+}
+
+bool Win32PageFaultHandler::disable()
+{
+ if (mVectoredExceptionHandler)
+ {
+ ULONG res = RemoveVectoredExceptionHandler(mVectoredExceptionHandler);
+ mVectoredExceptionHandler = nullptr;
+ if (res == 0)
+ {
+ DWORD lastError = GetLastError();
+ fprintf(stderr, "RemoveVectoredExceptionHandler failed: 0x%lx\n", lastError);
+ return false;
+ }
+ }
+ return true;
+}
+
+bool Win32PageFaultHandler::enable()
+{
+ if (mVectoredExceptionHandler)
+ {
+ return true;
+ }
+
+ PVECTORED_EXCEPTION_HANDLER handler =
+ reinterpret_cast<PVECTORED_EXCEPTION_HANDLER>(&VectoredExceptionHandler);
+
+ mVectoredExceptionHandler = AddVectoredExceptionHandler(1, handler);
+
+ if (!mVectoredExceptionHandler)
+ {
+ DWORD lastError = GetLastError();
+ fprintf(stderr, "AddVectoredExceptionHandler failed: 0x%lx\n", lastError);
+ return false;
+ }
+ return true;
+}
+} // namespace
+
+// Set write protection
+bool ProtectMemory(uintptr_t start, size_t size)
+{
+ return SetMemoryProtection(start, size, PAGE_READONLY);
+}
+
+// Allow reading and writing
+bool UnprotectMemory(uintptr_t start, size_t size)
+{
+ return SetMemoryProtection(start, size, PAGE_READWRITE);
+}
+
+size_t GetPageSize()
+{
+ SYSTEM_INFO info;
+ GetSystemInfo(&info);
+ return static_cast<size_t>(info.dwPageSize);
+}
+
+PageFaultHandler *CreatePageFaultHandler(PageFaultCallback callback)
+{
+ gWin32PageFaultHandler = new Win32PageFaultHandler(callback);
+ return gWin32PageFaultHandler;
+}
+
+uint64_t GetProcessMemoryUsageKB()
+{
+ PROCESS_MEMORY_COUNTERS_EX pmc;
+ ::GetProcessMemoryInfo(::GetCurrentProcess(), reinterpret_cast<PROCESS_MEMORY_COUNTERS *>(&pmc),
+ sizeof(pmc));
+ return static_cast<uint64_t>(pmc.PrivateUsage) / 1024ull;
+}
+} // namespace angle
diff --git a/gfx/angle/checkout/src/common/third_party/base/anglebase/base_export.h b/gfx/angle/checkout/src/common/third_party/base/anglebase/base_export.h
new file mode 100644
index 0000000000..426047a992
--- /dev/null
+++ b/gfx/angle/checkout/src/common/third_party/base/anglebase/base_export.h
@@ -0,0 +1,13 @@
+//
+// Copyright 2017 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.
+//
+// base_export.h: Compatiblity hacks for importing Chromium's base/SHA1.
+
+#ifndef ANGLEBASE_BASE_EXPORT_H_
+#define ANGLEBASE_BASE_EXPORT_H_
+
+#define ANGLEBASE_EXPORT
+
+#endif // ANGLEBASE_BASE_EXPORT_H_
diff --git a/gfx/angle/checkout/src/common/third_party/base/anglebase/containers/mru_cache.h b/gfx/angle/checkout/src/common/third_party/base/anglebase/containers/mru_cache.h
new file mode 100644
index 0000000000..30b564aff6
--- /dev/null
+++ b/gfx/angle/checkout/src/common/third_party/base/anglebase/containers/mru_cache.h
@@ -0,0 +1,275 @@
+// Copyright (c) 2011 The Chromium 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 file contains a template for a Most Recently Used cache that allows
+// constant-time access to items using a key, but easy identification of the
+// least-recently-used items for removal. Each key can only be associated with
+// one payload item at a time.
+//
+// The key object will be stored twice, so it should support efficient copying.
+//
+// NOTE: While all operations are O(1), this code is written for
+// legibility rather than optimality. If future profiling identifies this as
+// a bottleneck, there is room for smaller values of 1 in the O(1). :]
+
+#ifndef ANGLEBASE_CONTAINERS_MRU_CACHE_H_
+#define ANGLEBASE_CONTAINERS_MRU_CACHE_H_
+
+#include <stddef.h>
+
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <map>
+#include <unordered_map>
+#include <utility>
+
+#include "anglebase/logging.h"
+#include "anglebase/macros.h"
+
+namespace angle
+{
+
+namespace base
+{
+
+// MRUCacheBase ----------------------------------------------------------------
+
+// This template is used to standardize map type containers that can be used
+// by MRUCacheBase. This level of indirection is necessary because of the way
+// that template template params and default template params interact.
+template <class KeyType, class ValueType, class CompareType>
+struct MRUCacheStandardMap
+{
+ typedef std::map<KeyType, ValueType, CompareType> Type;
+};
+
+// Base class for the MRU cache specializations defined below.
+template <class KeyType,
+ class PayloadType,
+ class HashOrCompareType,
+ template <typename, typename, typename> class MapType = MRUCacheStandardMap>
+class MRUCacheBase
+{
+ public:
+ // The payload of the list. This maintains a copy of the key so we can
+ // efficiently delete things given an element of the list.
+ typedef std::pair<KeyType, PayloadType> value_type;
+
+ private:
+ typedef std::list<value_type> PayloadList;
+ typedef
+ typename MapType<KeyType, typename PayloadList::iterator, HashOrCompareType>::Type KeyIndex;
+
+ public:
+ typedef typename PayloadList::size_type size_type;
+
+ typedef typename PayloadList::iterator iterator;
+ typedef typename PayloadList::const_iterator const_iterator;
+ typedef typename PayloadList::reverse_iterator reverse_iterator;
+ typedef typename PayloadList::const_reverse_iterator const_reverse_iterator;
+
+ enum
+ {
+ NO_AUTO_EVICT = 0
+ };
+
+ // The max_size is the size at which the cache will prune its members to when
+ // a new item is inserted. If the caller wants to manager this itself (for
+ // example, maybe it has special work to do when something is evicted), it
+ // can pass NO_AUTO_EVICT to not restrict the cache size.
+ explicit MRUCacheBase(size_type max_size) : max_size_(max_size) {}
+
+ virtual ~MRUCacheBase() {}
+
+ size_type max_size() const { return max_size_; }
+
+ // Inserts a payload item with the given key. If an existing item has
+ // the same key, it is removed prior to insertion. An iterator indicating the
+ // inserted item will be returned (this will always be the front of the list).
+ //
+ // The payload will be forwarded.
+ template <typename Payload>
+ iterator Put(const KeyType &key, Payload &&payload)
+ {
+ // Remove any existing payload with that key.
+ typename KeyIndex::iterator index_iter = index_.find(key);
+ if (index_iter != index_.end())
+ {
+ // Erase the reference to it. The index reference will be replaced in the
+ // code below.
+ Erase(index_iter->second);
+ }
+ else if (max_size_ != NO_AUTO_EVICT)
+ {
+ // New item is being inserted which might make it larger than the maximum
+ // size: kick the oldest thing out if necessary.
+ ShrinkToSize(max_size_ - 1);
+ }
+
+ ordering_.emplace_front(key, std::forward<Payload>(payload));
+ index_.emplace(key, ordering_.begin());
+ return ordering_.begin();
+ }
+
+ // Retrieves the contents of the given key, or end() if not found. This method
+ // has the side effect of moving the requested item to the front of the
+ // recency list.
+ iterator Get(const KeyType &key)
+ {
+ typename KeyIndex::iterator index_iter = index_.find(key);
+ if (index_iter == index_.end())
+ return end();
+ typename PayloadList::iterator iter = index_iter->second;
+
+ // Move the touched item to the front of the recency ordering.
+ ordering_.splice(ordering_.begin(), ordering_, iter);
+ return ordering_.begin();
+ }
+
+ // Retrieves the payload associated with a given key and returns it via
+ // result without affecting the ordering (unlike Get).
+ iterator Peek(const KeyType &key)
+ {
+ typename KeyIndex::const_iterator index_iter = index_.find(key);
+ if (index_iter == index_.end())
+ return end();
+ return index_iter->second;
+ }
+
+ const_iterator Peek(const KeyType &key) const
+ {
+ typename KeyIndex::const_iterator index_iter = index_.find(key);
+ if (index_iter == index_.end())
+ return end();
+ return index_iter->second;
+ }
+
+ // Exchanges the contents of |this| by the contents of the |other|.
+ void Swap(MRUCacheBase &other)
+ {
+ ordering_.swap(other.ordering_);
+ index_.swap(other.index_);
+ std::swap(max_size_, other.max_size_);
+ }
+
+ // Erases the item referenced by the given iterator. An iterator to the item
+ // following it will be returned. The iterator must be valid.
+ iterator Erase(iterator pos)
+ {
+ index_.erase(pos->first);
+ return ordering_.erase(pos);
+ }
+
+ // MRUCache entries are often processed in reverse order, so we add this
+ // convenience function (not typically defined by STL containers).
+ reverse_iterator Erase(reverse_iterator pos)
+ {
+ // We have to actually give it the incremented iterator to delete, since
+ // the forward iterator that base() returns is actually one past the item
+ // being iterated over.
+ return reverse_iterator(Erase((++pos).base()));
+ }
+
+ // Shrinks the cache so it only holds |new_size| items. If |new_size| is
+ // bigger or equal to the current number of items, this will do nothing.
+ void ShrinkToSize(size_type new_size)
+ {
+ for (size_type i = size(); i > new_size; i--)
+ Erase(rbegin());
+ }
+
+ // Deletes everything from the cache.
+ void Clear()
+ {
+ index_.clear();
+ ordering_.clear();
+ }
+
+ // Returns the number of elements in the cache.
+ size_type size() const
+ {
+ // We don't use ordering_.size() for the return value because
+ // (as a linked list) it can be O(n).
+ DCHECK(index_.size() == ordering_.size());
+ return index_.size();
+ }
+
+ // Allows iteration over the list. Forward iteration starts with the most
+ // recent item and works backwards.
+ //
+ // Note that since these iterators are actually iterators over a list, you
+ // can keep them as you insert or delete things (as long as you don't delete
+ // the one you are pointing to) and they will still be valid.
+ iterator begin() { return ordering_.begin(); }
+ const_iterator begin() const { return ordering_.begin(); }
+ iterator end() { return ordering_.end(); }
+ const_iterator end() const { return ordering_.end(); }
+
+ reverse_iterator rbegin() { return ordering_.rbegin(); }
+ const_reverse_iterator rbegin() const { return ordering_.rbegin(); }
+ reverse_iterator rend() { return ordering_.rend(); }
+ const_reverse_iterator rend() const { return ordering_.rend(); }
+
+ bool empty() const { return ordering_.empty(); }
+
+ private:
+ PayloadList ordering_;
+ KeyIndex index_;
+
+ size_type max_size_;
+
+ DISALLOW_COPY_AND_ASSIGN(MRUCacheBase);
+};
+
+// MRUCache --------------------------------------------------------------------
+
+// A container that does not do anything to free its data. Use this when storing
+// value types (as opposed to pointers) in the list.
+template <class KeyType, class PayloadType, class CompareType = std::less<KeyType>>
+class MRUCache : public MRUCacheBase<KeyType, PayloadType, CompareType>
+{
+ private:
+ using ParentType = MRUCacheBase<KeyType, PayloadType, CompareType>;
+
+ public:
+ // See MRUCacheBase, noting the possibility of using NO_AUTO_EVICT.
+ explicit MRUCache(typename ParentType::size_type max_size) : ParentType(max_size) {}
+ virtual ~MRUCache() {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MRUCache);
+};
+
+// HashingMRUCache ------------------------------------------------------------
+
+template <class KeyType, class ValueType, class HashType>
+struct MRUCacheHashMap
+{
+ typedef std::unordered_map<KeyType, ValueType, HashType> Type;
+};
+
+// This class is similar to MRUCache, except that it uses std::unordered_map as
+// the map type instead of std::map. Note that your KeyType must be hashable to
+// use this cache or you need to provide a hashing class.
+template <class KeyType, class PayloadType, class HashType = std::hash<KeyType>>
+class HashingMRUCache : public MRUCacheBase<KeyType, PayloadType, HashType, MRUCacheHashMap>
+{
+ private:
+ using ParentType = MRUCacheBase<KeyType, PayloadType, HashType, MRUCacheHashMap>;
+
+ public:
+ // See MRUCacheBase, noting the possibility of using NO_AUTO_EVICT.
+ explicit HashingMRUCache(typename ParentType::size_type max_size) : ParentType(max_size) {}
+ virtual ~HashingMRUCache() override {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(HashingMRUCache);
+};
+
+} // namespace base
+
+} // namespace angle
+
+#endif // ANGLEBASE_CONTAINERS_MRU_CACHE_H_
diff --git a/gfx/angle/checkout/src/common/third_party/base/anglebase/logging.h b/gfx/angle/checkout/src/common/third_party/base/anglebase/logging.h
new file mode 100644
index 0000000000..73f81e87f2
--- /dev/null
+++ b/gfx/angle/checkout/src/common/third_party/base/anglebase/logging.h
@@ -0,0 +1,26 @@
+//
+// 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.
+//
+// logging.h: Compatiblity hacks for importing Chromium's base/numerics.
+
+#ifndef ANGLEBASE_LOGGING_H_
+#define ANGLEBASE_LOGGING_H_
+
+#include "common/debug.h"
+
+#ifndef DCHECK
+# define DCHECK(X) ASSERT(X)
+#endif
+
+#ifndef CHECK
+# define CHECK(X) ASSERT(X)
+#endif
+
+// Unfortunately ANGLE relies on ASSERT being an empty statement, which these libs don't respect.
+#ifndef NOTREACHED
+# define NOTREACHED() ({ UNREACHABLE(); })
+#endif
+
+#endif // ANGLEBASE_LOGGING_H_
diff --git a/gfx/angle/checkout/src/common/third_party/base/anglebase/macros.h b/gfx/angle/checkout/src/common/third_party/base/anglebase/macros.h
new file mode 100644
index 0000000000..06391784e4
--- /dev/null
+++ b/gfx/angle/checkout/src/common/third_party/base/anglebase/macros.h
@@ -0,0 +1,17 @@
+//
+// Copyright 2017 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.
+//
+// macros.h: Compatiblity hacks for importing Chromium's MRUCache.
+
+#ifndef ANGLEBASE_MACROS_H_
+#define ANGLEBASE_MACROS_H_
+
+// A macro to disallow the copy constructor and operator= functions.
+// This should be used in the private: declarations for a class.
+#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
+ TypeName(const TypeName &) = delete; \
+ void operator=(const TypeName &) = delete
+
+#endif // ANGLEBASE_MACROS_H_
diff --git a/gfx/angle/checkout/src/common/third_party/base/anglebase/no_destructor.h b/gfx/angle/checkout/src/common/third_party/base/anglebase/no_destructor.h
new file mode 100644
index 0000000000..5090dd9817
--- /dev/null
+++ b/gfx/angle/checkout/src/common/third_party/base/anglebase/no_destructor.h
@@ -0,0 +1,106 @@
+// Copyright 2018 The Chromium 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 ANGLEBASE_NO_DESTRUCTOR_H_
+#define ANGLEBASE_NO_DESTRUCTOR_H_
+
+#include <new>
+#include <utility>
+
+namespace angle
+{
+
+namespace base
+{
+
+// A wrapper that makes it easy to create an object of type T with static
+// storage duration that:
+// - is only constructed on first access
+// - never invokes the destructor
+// in order to satisfy the styleguide ban on global constructors and
+// destructors.
+//
+// Runtime constant example:
+// const std::string& GetLineSeparator() {
+// // Forwards to std::string(size_t, char, const Allocator&) constructor.
+// static const base::NoDestructor<std::string> s(5, '-');
+// return *s;
+// }
+//
+// More complex initialization with a lambda:
+// const std::string& GetSessionNonce() {
+// static const base::NoDestructor<std::string> nonce([] {
+// std::string s(16);
+// crypto::RandString(s.data(), s.size());
+// return s;
+// }());
+// return *nonce;
+// }
+//
+// NoDestructor<T> stores the object inline, so it also avoids a pointer
+// indirection and a malloc. Also note that since C++11 static local variable
+// initialization is thread-safe and so is this pattern. Code should prefer to
+// use NoDestructor<T> over:
+// - A function scoped static T* or T& that is dynamically initialized.
+// - A global base::LazyInstance<T>.
+//
+// Note that since the destructor is never run, this *will* leak memory if used
+// as a stack or member variable. Furthermore, a NoDestructor<T> should never
+// have global scope as that may require a static initializer.
+template <typename T>
+class NoDestructor
+{
+ public:
+ // Not constexpr; just write static constexpr T x = ...; if the value should
+ // be a constexpr.
+ template <typename... Args>
+ explicit NoDestructor(Args &&... args)
+ {
+ new (storage_) T(std::forward<Args>(args)...);
+ }
+
+ // Allows copy and move construction of the contained type, to allow
+ // construction from an initializer list, e.g. for std::vector.
+ explicit NoDestructor(const T &x) { new (storage_) T(x); }
+ explicit NoDestructor(T &&x) { new (storage_) T(std::move(x)); }
+
+ NoDestructor(const NoDestructor &) = delete;
+ NoDestructor &operator=(const NoDestructor &) = delete;
+
+ ~NoDestructor() = default;
+
+ const T &operator*() const { return *get(); }
+ T &operator*() { return *get(); }
+
+ const T *operator->() const { return get(); }
+ T *operator->() { return get(); }
+
+ const T *get() const { return reinterpret_cast<const T *>(storage_); }
+ T *get() { return reinterpret_cast<T *>(storage_); }
+
+ private:
+ alignas(T) char storage_[sizeof(T)];
+
+#if defined(LEAK_SANITIZER)
+ // TODO(https://crbug.com/812277): This is a hack to work around the fact
+ // that LSan doesn't seem to treat NoDestructor as a root for reachability
+ // analysis. This means that code like this:
+ // static base::NoDestructor<std::vector<int>> v({1, 2, 3});
+ // is considered a leak. Using the standard leak sanitizer annotations to
+ // suppress leaks doesn't work: std::vector is implicitly constructed before
+ // calling the base::NoDestructor constructor.
+ //
+ // Unfortunately, I haven't been able to demonstrate this issue in simpler
+ // reproductions: until that's resolved, hold an explicit pointer to the
+ // placement-new'd object in leak sanitizer mode to help LSan realize that
+ // objects allocated by the contained type are still reachable.
+ T *storage_ptr_ = reinterpret_cast<T *>(storage_);
+#endif // defined(LEAK_SANITIZER)
+};
+
+} // namespace base
+
+} // namespace angle
+
+#endif // ANGLEBASE_NO_DESTRUCTOR_H_
diff --git a/gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/checked_math.h b/gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/checked_math.h
new file mode 100644
index 0000000000..18bceb7468
--- /dev/null
+++ b/gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/checked_math.h
@@ -0,0 +1,384 @@
+// Copyright 2017 The Chromium 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 BASE_NUMERICS_CHECKED_MATH_H_
+#define BASE_NUMERICS_CHECKED_MATH_H_
+
+#include <stddef.h>
+
+#include <limits>
+#include <type_traits>
+
+#include "anglebase/numerics/checked_math_impl.h"
+
+namespace angle
+{
+namespace base
+{
+namespace internal
+{
+
+template <typename T>
+class CheckedNumeric
+{
+ static_assert(std::is_arithmetic<T>::value, "CheckedNumeric<T>: T must be a numeric type.");
+
+ public:
+ template <typename Src>
+ friend class CheckedNumeric;
+
+ using type = T;
+
+ constexpr CheckedNumeric() = default;
+
+ // Copy constructor.
+ template <typename Src>
+ constexpr CheckedNumeric(const CheckedNumeric<Src> &rhs)
+ : state_(rhs.state_.value(), rhs.IsValid())
+ {}
+
+ // This is not an explicit constructor because we implicitly upgrade regular
+ // numerics to CheckedNumerics to make them easier to use.
+ template <typename Src>
+ constexpr CheckedNumeric(Src value) // NOLINT(runtime/explicit)
+ : state_(value)
+ {
+ static_assert(std::is_arithmetic<Src>::value, "Argument must be numeric.");
+ }
+
+ // This is not an explicit constructor because we want a seamless conversion
+ // from StrictNumeric types.
+ template <typename Src>
+ constexpr CheckedNumeric(StrictNumeric<Src> value) // NOLINT(runtime/explicit)
+ : state_(static_cast<Src>(value))
+ {}
+
+ // IsValid() - The public API to test if a CheckedNumeric is currently valid.
+ // A range checked destination type can be supplied using the Dst template
+ // parameter.
+ template <typename Dst = T>
+ constexpr bool IsValid() const
+ {
+ return state_.is_valid() && IsValueInRangeForNumericType<Dst>(state_.value());
+ }
+
+ // AssignIfValid(Dst) - Assigns the underlying value if it is currently valid
+ // and is within the range supported by the destination type. Returns true if
+ // successful and false otherwise.
+ template <typename Dst>
+#if defined(__clang__) || defined(__GNUC__)
+ __attribute__((warn_unused_result))
+#elif defined(_MSC_VER)
+ _Check_return_
+#endif
+ constexpr bool
+ AssignIfValid(Dst *result) const
+ {
+ return BASE_NUMERICS_LIKELY(IsValid<Dst>())
+ ? ((*result = static_cast<Dst>(state_.value())), true)
+ : false;
+ }
+
+ // ValueOrDie() - The primary accessor for the underlying value. If the
+ // current state is not valid it will CHECK and crash.
+ // A range checked destination type can be supplied using the Dst template
+ // parameter, which will trigger a CHECK if the value is not in bounds for
+ // the destination.
+ // The CHECK behavior can be overridden by supplying a handler as a
+ // template parameter, for test code, etc. However, the handler cannot access
+ // the underlying value, and it is not available through other means.
+ template <typename Dst = T, class CheckHandler = CheckOnFailure>
+ constexpr StrictNumeric<Dst> ValueOrDie() const
+ {
+ return BASE_NUMERICS_LIKELY(IsValid<Dst>()) ? static_cast<Dst>(state_.value())
+ : CheckHandler::template HandleFailure<Dst>();
+ }
+
+ // ValueOrDefault(T default_value) - A convenience method that returns the
+ // current value if the state is valid, and the supplied default_value for
+ // any other state.
+ // A range checked destination type can be supplied using the Dst template
+ // parameter. WARNING: This function may fail to compile or CHECK at runtime
+ // if the supplied default_value is not within range of the destination type.
+ template <typename Dst = T, typename Src>
+ constexpr StrictNumeric<Dst> ValueOrDefault(const Src default_value) const
+ {
+ return BASE_NUMERICS_LIKELY(IsValid<Dst>()) ? static_cast<Dst>(state_.value())
+ : checked_cast<Dst>(default_value);
+ }
+
+ // Returns a checked numeric of the specified type, cast from the current
+ // CheckedNumeric. If the current state is invalid or the destination cannot
+ // represent the result then the returned CheckedNumeric will be invalid.
+ template <typename Dst>
+ constexpr CheckedNumeric<typename UnderlyingType<Dst>::type> Cast() const
+ {
+ return *this;
+ }
+
+ // This friend method is available solely for providing more detailed logging
+ // in the tests. Do not implement it in production code, because the
+ // underlying values may change at any time.
+ template <typename U>
+ friend U GetNumericValueForTest(const CheckedNumeric<U> &src);
+
+ // Prototypes for the supported arithmetic operator overloads.
+ template <typename Src>
+ constexpr CheckedNumeric &operator+=(const Src rhs);
+ template <typename Src>
+ constexpr CheckedNumeric &operator-=(const Src rhs);
+ template <typename Src>
+ constexpr CheckedNumeric &operator*=(const Src rhs);
+ template <typename Src>
+ constexpr CheckedNumeric &operator/=(const Src rhs);
+ template <typename Src>
+ constexpr CheckedNumeric &operator%=(const Src rhs);
+ template <typename Src>
+ constexpr CheckedNumeric &operator<<=(const Src rhs);
+ template <typename Src>
+ constexpr CheckedNumeric &operator>>=(const Src rhs);
+ template <typename Src>
+ constexpr CheckedNumeric &operator&=(const Src rhs);
+ template <typename Src>
+ constexpr CheckedNumeric &operator|=(const Src rhs);
+ template <typename Src>
+ constexpr CheckedNumeric &operator^=(const Src rhs);
+
+ constexpr CheckedNumeric operator-() const
+ {
+ // Use an optimized code path for a known run-time variable.
+ if (!MustTreatAsConstexpr(state_.value()) && std::is_signed<T>::value &&
+ std::is_floating_point<T>::value)
+ {
+ return FastRuntimeNegate();
+ }
+ // The negation of two's complement int min is int min.
+ const bool is_valid =
+ IsValid() && (!std::is_signed<T>::value || std::is_floating_point<T>::value ||
+ NegateWrapper(state_.value()) != std::numeric_limits<T>::lowest());
+ return CheckedNumeric<T>(NegateWrapper(state_.value()), is_valid);
+ }
+
+ constexpr CheckedNumeric operator~() const
+ {
+ return CheckedNumeric<decltype(InvertWrapper(T()))>(InvertWrapper(state_.value()),
+ IsValid());
+ }
+
+ constexpr CheckedNumeric Abs() const
+ {
+ return !IsValueNegative(state_.value()) ? *this : -*this;
+ }
+
+ template <typename U>
+ constexpr CheckedNumeric<typename MathWrapper<CheckedMaxOp, T, U>::type> Max(const U rhs) const
+ {
+ return CheckMax(*this, rhs);
+ }
+
+ template <typename U>
+ constexpr CheckedNumeric<typename MathWrapper<CheckedMinOp, T, U>::type> Min(const U rhs) const
+ {
+ return CheckMin(*this, rhs);
+ }
+
+ // This function is available only for integral types. It returns an unsigned
+ // integer of the same width as the source type, containing the absolute value
+ // of the source, and properly handling signed min.
+ constexpr CheckedNumeric<typename UnsignedOrFloatForSize<T>::type> UnsignedAbs() const
+ {
+ return CheckedNumeric<typename UnsignedOrFloatForSize<T>::type>(
+ SafeUnsignedAbs(state_.value()), state_.is_valid());
+ }
+
+ constexpr CheckedNumeric &operator++()
+ {
+ *this += 1;
+ return *this;
+ }
+
+ constexpr CheckedNumeric operator++(int)
+ {
+ CheckedNumeric value = *this;
+ *this += 1;
+ return value;
+ }
+
+ constexpr CheckedNumeric &operator--()
+ {
+ *this -= 1;
+ return *this;
+ }
+
+ constexpr CheckedNumeric operator--(int)
+ {
+ // TODO(pkasting): Consider std::exchange() once it's constexpr in C++20.
+ const CheckedNumeric value = *this;
+ *this -= 1;
+ return value;
+ }
+
+ // These perform the actual math operations on the CheckedNumerics.
+ // Binary arithmetic operations.
+ template <template <typename, typename, typename> class M, typename L, typename R>
+ static constexpr CheckedNumeric MathOp(const L lhs, const R rhs)
+ {
+ using Math = typename MathWrapper<M, L, R>::math;
+ T result = 0;
+ const bool is_valid = Wrapper<L>::is_valid(lhs) && Wrapper<R>::is_valid(rhs) &&
+ Math::Do(Wrapper<L>::value(lhs), Wrapper<R>::value(rhs), &result);
+ return CheckedNumeric<T>(result, is_valid);
+ }
+
+ // Assignment arithmetic operations.
+ template <template <typename, typename, typename> class M, typename R>
+ constexpr CheckedNumeric &MathOp(const R rhs)
+ {
+ using Math = typename MathWrapper<M, T, R>::math;
+ T result = 0; // Using T as the destination saves a range check.
+ const bool is_valid = state_.is_valid() && Wrapper<R>::is_valid(rhs) &&
+ Math::Do(state_.value(), Wrapper<R>::value(rhs), &result);
+ *this = CheckedNumeric<T>(result, is_valid);
+ return *this;
+ }
+
+ private:
+ CheckedNumericState<T> state_;
+
+ CheckedNumeric FastRuntimeNegate() const
+ {
+ T result;
+ const bool success = CheckedSubOp<T, T>::Do(T(0), state_.value(), &result);
+ return CheckedNumeric<T>(result, IsValid() && success);
+ }
+
+ template <typename Src>
+ constexpr CheckedNumeric(Src value, bool is_valid) : state_(value, is_valid)
+ {}
+
+ // These wrappers allow us to handle state the same way for both
+ // CheckedNumeric and POD arithmetic types.
+ template <typename Src>
+ struct Wrapper
+ {
+ static constexpr bool is_valid(Src) { return true; }
+ static constexpr Src value(Src value) { return value; }
+ };
+
+ template <typename Src>
+ struct Wrapper<CheckedNumeric<Src>>
+ {
+ static constexpr bool is_valid(const CheckedNumeric<Src> v) { return v.IsValid(); }
+ static constexpr Src value(const CheckedNumeric<Src> v) { return v.state_.value(); }
+ };
+
+ template <typename Src>
+ struct Wrapper<StrictNumeric<Src>>
+ {
+ static constexpr bool is_valid(const StrictNumeric<Src>) { return true; }
+ static constexpr Src value(const StrictNumeric<Src> v) { return static_cast<Src>(v); }
+ };
+};
+
+// Convenience functions to avoid the ugly template disambiguator syntax.
+template <typename Dst, typename Src>
+constexpr bool IsValidForType(const CheckedNumeric<Src> value)
+{
+ return value.template IsValid<Dst>();
+}
+
+template <typename Dst, typename Src>
+constexpr StrictNumeric<Dst> ValueOrDieForType(const CheckedNumeric<Src> value)
+{
+ return value.template ValueOrDie<Dst>();
+}
+
+template <typename Dst, typename Src, typename Default>
+constexpr StrictNumeric<Dst> ValueOrDefaultForType(const CheckedNumeric<Src> value,
+ const Default default_value)
+{
+ return value.template ValueOrDefault<Dst>(default_value);
+}
+
+// Convience wrapper to return a new CheckedNumeric from the provided arithmetic
+// or CheckedNumericType.
+template <typename T>
+constexpr CheckedNumeric<typename UnderlyingType<T>::type> MakeCheckedNum(const T value)
+{
+ return value;
+}
+
+// These implement the variadic wrapper for the math operations.
+template <template <typename, typename, typename> class M, typename L, typename R>
+constexpr CheckedNumeric<typename MathWrapper<M, L, R>::type> CheckMathOp(const L lhs, const R rhs)
+{
+ using Math = typename MathWrapper<M, L, R>::math;
+ return CheckedNumeric<typename Math::result_type>::template MathOp<M>(lhs, rhs);
+}
+
+// General purpose wrapper template for arithmetic operations.
+template <template <typename, typename, typename> class M, typename L, typename R, typename... Args>
+constexpr auto CheckMathOp(const L lhs, const R rhs, const Args... args)
+{
+ return CheckMathOp<M>(CheckMathOp<M>(lhs, rhs), args...);
+}
+
+BASE_NUMERIC_ARITHMETIC_OPERATORS(Checked, Check, Add, +, +=)
+BASE_NUMERIC_ARITHMETIC_OPERATORS(Checked, Check, Sub, -, -=)
+BASE_NUMERIC_ARITHMETIC_OPERATORS(Checked, Check, Mul, *, *=)
+BASE_NUMERIC_ARITHMETIC_OPERATORS(Checked, Check, Div, /, /=)
+BASE_NUMERIC_ARITHMETIC_OPERATORS(Checked, Check, Mod, %, %=)
+BASE_NUMERIC_ARITHMETIC_OPERATORS(Checked, Check, Lsh, <<, <<=)
+BASE_NUMERIC_ARITHMETIC_OPERATORS(Checked, Check, Rsh, >>, >>=)
+BASE_NUMERIC_ARITHMETIC_OPERATORS(Checked, Check, And, &, &=)
+BASE_NUMERIC_ARITHMETIC_OPERATORS(Checked, Check, Or, |, |=)
+BASE_NUMERIC_ARITHMETIC_OPERATORS(Checked, Check, Xor, ^, ^=)
+BASE_NUMERIC_ARITHMETIC_VARIADIC(Checked, Check, Max)
+BASE_NUMERIC_ARITHMETIC_VARIADIC(Checked, Check, Min)
+
+// These are some extra StrictNumeric operators to support simple pointer
+// arithmetic with our result types. Since wrapping on a pointer is always
+// bad, we trigger the CHECK condition here.
+template <typename L, typename R>
+L *operator+(L *lhs, const StrictNumeric<R> rhs)
+{
+ const uintptr_t result =
+ CheckAdd(reinterpret_cast<uintptr_t>(lhs), CheckMul(sizeof(L), static_cast<R>(rhs)))
+ .template ValueOrDie<uintptr_t>();
+ return reinterpret_cast<L *>(result);
+}
+
+template <typename L, typename R>
+L *operator-(L *lhs, const StrictNumeric<R> rhs)
+{
+ const uintptr_t result =
+ CheckSub(reinterpret_cast<uintptr_t>(lhs), CheckMul(sizeof(L), static_cast<R>(rhs)))
+ .template ValueOrDie<uintptr_t>();
+ return reinterpret_cast<L *>(result);
+}
+
+} // namespace internal
+
+using internal::CheckAdd;
+using internal::CheckAnd;
+using internal::CheckDiv;
+using internal::CheckedNumeric;
+using internal::CheckLsh;
+using internal::CheckMax;
+using internal::CheckMin;
+using internal::CheckMod;
+using internal::CheckMul;
+using internal::CheckOr;
+using internal::CheckRsh;
+using internal::CheckSub;
+using internal::CheckXor;
+using internal::IsValidForType;
+using internal::MakeCheckedNum;
+using internal::ValueOrDefaultForType;
+using internal::ValueOrDieForType;
+
+} // namespace base
+} // namespace angle
+
+#endif // BASE_NUMERICS_CHECKED_MATH_H_
diff --git a/gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/checked_math_impl.h b/gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/checked_math_impl.h
new file mode 100644
index 0000000000..e4b6082770
--- /dev/null
+++ b/gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/checked_math_impl.h
@@ -0,0 +1,641 @@
+// Copyright 2017 The Chromium 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 BASE_NUMERICS_CHECKED_MATH_IMPL_H_
+#define BASE_NUMERICS_CHECKED_MATH_IMPL_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <climits>
+#include <cmath>
+#include <cstdlib>
+#include <limits>
+#include <type_traits>
+
+#include "anglebase/numerics/safe_conversions.h"
+#include "anglebase/numerics/safe_math_shared_impl.h"
+
+namespace angle
+{
+namespace base
+{
+namespace internal
+{
+
+template <typename T>
+constexpr bool CheckedAddImpl(T x, T y, T *result)
+{
+ static_assert(std::is_integral<T>::value, "Type must be integral");
+ // Since the value of x+y is undefined if we have a signed type, we compute
+ // it using the unsigned type of the same size.
+ using UnsignedDst = typename std::make_unsigned<T>::type;
+ using SignedDst = typename std::make_signed<T>::type;
+ const UnsignedDst ux = static_cast<UnsignedDst>(x);
+ const UnsignedDst uy = static_cast<UnsignedDst>(y);
+ const UnsignedDst uresult = static_cast<UnsignedDst>(ux + uy);
+ // Addition is valid if the sign of (x + y) is equal to either that of x or
+ // that of y.
+ if (std::is_signed<T>::value ? static_cast<SignedDst>((uresult ^ ux) & (uresult ^ uy)) < 0
+ : uresult < uy) // Unsigned is either valid or underflow.
+ return false;
+ *result = static_cast<T>(uresult);
+ return true;
+}
+
+template <typename T, typename U, class Enable = void>
+struct CheckedAddOp
+{};
+
+template <typename T, typename U>
+struct CheckedAddOp<
+ T,
+ U,
+ typename std::enable_if<std::is_integral<T>::value && std::is_integral<U>::value>::type>
+{
+ using result_type = typename MaxExponentPromotion<T, U>::type;
+ template <typename V>
+ static constexpr bool Do(T x, U y, V *result)
+ {
+ if constexpr (CheckedAddFastOp<T, U>::is_supported)
+ return CheckedAddFastOp<T, U>::Do(x, y, result);
+
+ // Double the underlying type up to a full machine word.
+ using FastPromotion = typename FastIntegerArithmeticPromotion<T, U>::type;
+ using Promotion =
+ typename std::conditional<(IntegerBitsPlusSign<FastPromotion>::value >
+ IntegerBitsPlusSign<intptr_t>::value),
+ typename BigEnoughPromotion<T, U>::type, FastPromotion>::type;
+ // Fail if either operand is out of range for the promoted type.
+ // TODO(jschuh): This could be made to work for a broader range of values.
+ if (BASE_NUMERICS_UNLIKELY(!IsValueInRangeForNumericType<Promotion>(x) ||
+ !IsValueInRangeForNumericType<Promotion>(y)))
+ {
+ return false;
+ }
+
+ Promotion presult = {};
+ bool is_valid = true;
+ if constexpr (IsIntegerArithmeticSafe<Promotion, T, U>::value)
+ {
+ presult = static_cast<Promotion>(x) + static_cast<Promotion>(y);
+ }
+ else
+ {
+ is_valid =
+ CheckedAddImpl(static_cast<Promotion>(x), static_cast<Promotion>(y), &presult);
+ }
+ if (!is_valid || !IsValueInRangeForNumericType<V>(presult))
+ return false;
+ *result = static_cast<V>(presult);
+ return true;
+ }
+};
+
+template <typename T>
+constexpr bool CheckedSubImpl(T x, T y, T *result)
+{
+ static_assert(std::is_integral<T>::value, "Type must be integral");
+ // Since the value of x+y is undefined if we have a signed type, we compute
+ // it using the unsigned type of the same size.
+ using UnsignedDst = typename std::make_unsigned<T>::type;
+ using SignedDst = typename std::make_signed<T>::type;
+ const UnsignedDst ux = static_cast<UnsignedDst>(x);
+ const UnsignedDst uy = static_cast<UnsignedDst>(y);
+ const UnsignedDst uresult = static_cast<UnsignedDst>(ux - uy);
+ // Subtraction is valid if either x and y have same sign, or (x-y) and x have
+ // the same sign.
+ if (std::is_signed<T>::value ? static_cast<SignedDst>((uresult ^ ux) & (ux ^ uy)) < 0 : x < y)
+ return false;
+ *result = static_cast<T>(uresult);
+ return true;
+}
+
+template <typename T, typename U, class Enable = void>
+struct CheckedSubOp
+{};
+
+template <typename T, typename U>
+struct CheckedSubOp<
+ T,
+ U,
+ typename std::enable_if<std::is_integral<T>::value && std::is_integral<U>::value>::type>
+{
+ using result_type = typename MaxExponentPromotion<T, U>::type;
+ template <typename V>
+ static constexpr bool Do(T x, U y, V *result)
+ {
+ if constexpr (CheckedSubFastOp<T, U>::is_supported)
+ return CheckedSubFastOp<T, U>::Do(x, y, result);
+
+ // Double the underlying type up to a full machine word.
+ using FastPromotion = typename FastIntegerArithmeticPromotion<T, U>::type;
+ using Promotion =
+ typename std::conditional<(IntegerBitsPlusSign<FastPromotion>::value >
+ IntegerBitsPlusSign<intptr_t>::value),
+ typename BigEnoughPromotion<T, U>::type, FastPromotion>::type;
+ // Fail if either operand is out of range for the promoted type.
+ // TODO(jschuh): This could be made to work for a broader range of values.
+ if (BASE_NUMERICS_UNLIKELY(!IsValueInRangeForNumericType<Promotion>(x) ||
+ !IsValueInRangeForNumericType<Promotion>(y)))
+ {
+ return false;
+ }
+
+ Promotion presult = {};
+ bool is_valid = true;
+ if constexpr (IsIntegerArithmeticSafe<Promotion, T, U>::value)
+ {
+ presult = static_cast<Promotion>(x) - static_cast<Promotion>(y);
+ }
+ else
+ {
+ is_valid =
+ CheckedSubImpl(static_cast<Promotion>(x), static_cast<Promotion>(y), &presult);
+ }
+ if (!is_valid || !IsValueInRangeForNumericType<V>(presult))
+ return false;
+ *result = static_cast<V>(presult);
+ return true;
+ }
+};
+
+template <typename T>
+constexpr bool CheckedMulImpl(T x, T y, T *result)
+{
+ static_assert(std::is_integral<T>::value, "Type must be integral");
+ // Since the value of x*y is potentially undefined if we have a signed type,
+ // we compute it using the unsigned type of the same size.
+ using UnsignedDst = typename std::make_unsigned<T>::type;
+ using SignedDst = typename std::make_signed<T>::type;
+ const UnsignedDst ux = SafeUnsignedAbs(x);
+ const UnsignedDst uy = SafeUnsignedAbs(y);
+ const UnsignedDst uresult = static_cast<UnsignedDst>(ux * uy);
+ const bool is_negative = std::is_signed<T>::value && static_cast<SignedDst>(x ^ y) < 0;
+ // We have a fast out for unsigned identity or zero on the second operand.
+ // After that it's an unsigned overflow check on the absolute value, with
+ // a +1 bound for a negative result.
+ if (uy > UnsignedDst(!std::is_signed<T>::value || is_negative) &&
+ ux > (std::numeric_limits<T>::max() + UnsignedDst(is_negative)) / uy)
+ return false;
+ *result = is_negative ? 0 - uresult : uresult;
+ return true;
+}
+
+template <typename T, typename U, class Enable = void>
+struct CheckedMulOp
+{};
+
+template <typename T, typename U>
+struct CheckedMulOp<
+ T,
+ U,
+ typename std::enable_if<std::is_integral<T>::value && std::is_integral<U>::value>::type>
+{
+ using result_type = typename MaxExponentPromotion<T, U>::type;
+ template <typename V>
+ static constexpr bool Do(T x, U y, V *result)
+ {
+ if constexpr (CheckedMulFastOp<T, U>::is_supported)
+ return CheckedMulFastOp<T, U>::Do(x, y, result);
+
+ using Promotion = typename FastIntegerArithmeticPromotion<T, U>::type;
+ // Verify the destination type can hold the result (always true for 0).
+ if (BASE_NUMERICS_UNLIKELY((!IsValueInRangeForNumericType<Promotion>(x) ||
+ !IsValueInRangeForNumericType<Promotion>(y)) &&
+ x && y))
+ {
+ return false;
+ }
+
+ Promotion presult = {};
+ bool is_valid = true;
+ if constexpr (CheckedMulFastOp<Promotion, Promotion>::is_supported)
+ {
+ // The fast op may be available with the promoted type.
+ is_valid = CheckedMulFastOp<Promotion, Promotion>::Do(x, y, &presult);
+ }
+ else if (IsIntegerArithmeticSafe<Promotion, T, U>::value)
+ {
+ presult = static_cast<Promotion>(x) * static_cast<Promotion>(y);
+ }
+ else
+ {
+ is_valid =
+ CheckedMulImpl(static_cast<Promotion>(x), static_cast<Promotion>(y), &presult);
+ }
+ if (!is_valid || !IsValueInRangeForNumericType<V>(presult))
+ return false;
+ *result = static_cast<V>(presult);
+ return true;
+ }
+};
+
+// Division just requires a check for a zero denominator or an invalid negation
+// on signed min/-1.
+template <typename T, typename U, class Enable = void>
+struct CheckedDivOp
+{};
+
+template <typename T, typename U>
+struct CheckedDivOp<
+ T,
+ U,
+ typename std::enable_if<std::is_integral<T>::value && std::is_integral<U>::value>::type>
+{
+ using result_type = typename MaxExponentPromotion<T, U>::type;
+ template <typename V>
+ static constexpr bool Do(T x, U y, V *result)
+ {
+ if (BASE_NUMERICS_UNLIKELY(!y))
+ return false;
+
+ // The overflow check can be compiled away if we don't have the exact
+ // combination of types needed to trigger this case.
+ using Promotion = typename BigEnoughPromotion<T, U>::type;
+ if (BASE_NUMERICS_UNLIKELY(
+ (std::is_signed<T>::value && std::is_signed<U>::value &&
+ IsTypeInRangeForNumericType<T, Promotion>::value &&
+ static_cast<Promotion>(x) == std::numeric_limits<Promotion>::lowest() &&
+ y == static_cast<U>(-1))))
+ {
+ return false;
+ }
+
+ // This branch always compiles away if the above branch wasn't removed.
+ if (BASE_NUMERICS_UNLIKELY((!IsValueInRangeForNumericType<Promotion>(x) ||
+ !IsValueInRangeForNumericType<Promotion>(y)) &&
+ x))
+ {
+ return false;
+ }
+
+ const Promotion presult = Promotion(x) / Promotion(y);
+ if (!IsValueInRangeForNumericType<V>(presult))
+ return false;
+ *result = static_cast<V>(presult);
+ return true;
+ }
+};
+
+template <typename T, typename U, class Enable = void>
+struct CheckedModOp
+{};
+
+template <typename T, typename U>
+struct CheckedModOp<
+ T,
+ U,
+ typename std::enable_if<std::is_integral<T>::value && std::is_integral<U>::value>::type>
+{
+ using result_type = typename MaxExponentPromotion<T, U>::type;
+ template <typename V>
+ static constexpr bool Do(T x, U y, V *result)
+ {
+ if (BASE_NUMERICS_UNLIKELY(!y))
+ return false;
+
+ using Promotion = typename BigEnoughPromotion<T, U>::type;
+ if (BASE_NUMERICS_UNLIKELY(
+ (std::is_signed<T>::value && std::is_signed<U>::value &&
+ IsTypeInRangeForNumericType<T, Promotion>::value &&
+ static_cast<Promotion>(x) == std::numeric_limits<Promotion>::lowest() &&
+ y == static_cast<U>(-1))))
+ {
+ *result = 0;
+ return true;
+ }
+
+ const Promotion presult = static_cast<Promotion>(x) % static_cast<Promotion>(y);
+ if (!IsValueInRangeForNumericType<V>(presult))
+ return false;
+ *result = static_cast<Promotion>(presult);
+ return true;
+ }
+};
+
+template <typename T, typename U, class Enable = void>
+struct CheckedLshOp
+{};
+
+// Left shift. Shifts less than 0 or greater than or equal to the number
+// of bits in the promoted type are undefined. Shifts of negative values
+// are undefined. Otherwise it is defined when the result fits.
+template <typename T, typename U>
+struct CheckedLshOp<
+ T,
+ U,
+ typename std::enable_if<std::is_integral<T>::value && std::is_integral<U>::value>::type>
+{
+ using result_type = T;
+ template <typename V>
+ static constexpr bool Do(T x, U shift, V *result)
+ {
+ // Disallow negative numbers and verify the shift is in bounds.
+ if (BASE_NUMERICS_LIKELY(!IsValueNegative(x) &&
+ as_unsigned(shift) < as_unsigned(std::numeric_limits<T>::digits)))
+ {
+ // Shift as unsigned to avoid undefined behavior.
+ *result = static_cast<V>(as_unsigned(x) << shift);
+ // If the shift can be reversed, we know it was valid.
+ return *result >> shift == x;
+ }
+
+ // Handle the legal corner-case of a full-width signed shift of zero.
+ if (!std::is_signed<T>::value || x ||
+ as_unsigned(shift) != as_unsigned(std::numeric_limits<T>::digits))
+ return false;
+ *result = 0;
+ return true;
+ }
+};
+
+template <typename T, typename U, class Enable = void>
+struct CheckedRshOp
+{};
+
+// Right shift. Shifts less than 0 or greater than or equal to the number
+// of bits in the promoted type are undefined. Otherwise, it is always defined,
+// but a right shift of a negative value is implementation-dependent.
+template <typename T, typename U>
+struct CheckedRshOp<
+ T,
+ U,
+ typename std::enable_if<std::is_integral<T>::value && std::is_integral<U>::value>::type>
+{
+ using result_type = T;
+ template <typename V>
+ static bool Do(T x, U shift, V *result)
+ {
+ // Use sign conversion to push negative values out of range.
+ if (BASE_NUMERICS_UNLIKELY(as_unsigned(shift) >= IntegerBitsPlusSign<T>::value))
+ {
+ return false;
+ }
+
+ const T tmp = x >> shift;
+ if (!IsValueInRangeForNumericType<V>(tmp))
+ return false;
+ *result = static_cast<V>(tmp);
+ return true;
+ }
+};
+
+template <typename T, typename U, class Enable = void>
+struct CheckedAndOp
+{};
+
+// For simplicity we support only unsigned integer results.
+template <typename T, typename U>
+struct CheckedAndOp<
+ T,
+ U,
+ typename std::enable_if<std::is_integral<T>::value && std::is_integral<U>::value>::type>
+{
+ using result_type =
+ typename std::make_unsigned<typename MaxExponentPromotion<T, U>::type>::type;
+ template <typename V>
+ static constexpr bool Do(T x, U y, V *result)
+ {
+ const result_type tmp = static_cast<result_type>(x) & static_cast<result_type>(y);
+ if (!IsValueInRangeForNumericType<V>(tmp))
+ return false;
+ *result = static_cast<V>(tmp);
+ return true;
+ }
+};
+
+template <typename T, typename U, class Enable = void>
+struct CheckedOrOp
+{};
+
+// For simplicity we support only unsigned integers.
+template <typename T, typename U>
+struct CheckedOrOp<
+ T,
+ U,
+ typename std::enable_if<std::is_integral<T>::value && std::is_integral<U>::value>::type>
+{
+ using result_type =
+ typename std::make_unsigned<typename MaxExponentPromotion<T, U>::type>::type;
+ template <typename V>
+ static constexpr bool Do(T x, U y, V *result)
+ {
+ const result_type tmp = static_cast<result_type>(x) | static_cast<result_type>(y);
+ if (!IsValueInRangeForNumericType<V>(tmp))
+ return false;
+ *result = static_cast<V>(tmp);
+ return true;
+ }
+};
+
+template <typename T, typename U, class Enable = void>
+struct CheckedXorOp
+{};
+
+// For simplicity we support only unsigned integers.
+template <typename T, typename U>
+struct CheckedXorOp<
+ T,
+ U,
+ typename std::enable_if<std::is_integral<T>::value && std::is_integral<U>::value>::type>
+{
+ using result_type =
+ typename std::make_unsigned<typename MaxExponentPromotion<T, U>::type>::type;
+ template <typename V>
+ static constexpr bool Do(T x, U y, V *result)
+ {
+ const result_type tmp = static_cast<result_type>(x) ^ static_cast<result_type>(y);
+ if (!IsValueInRangeForNumericType<V>(tmp))
+ return false;
+ *result = static_cast<V>(tmp);
+ return true;
+ }
+};
+
+// Max doesn't really need to be implemented this way because it can't fail,
+// but it makes the code much cleaner to use the MathOp wrappers.
+template <typename T, typename U, class Enable = void>
+struct CheckedMaxOp
+{};
+
+template <typename T, typename U>
+struct CheckedMaxOp<
+ T,
+ U,
+ typename std::enable_if<std::is_arithmetic<T>::value && std::is_arithmetic<U>::value>::type>
+{
+ using result_type = typename MaxExponentPromotion<T, U>::type;
+ template <typename V>
+ static constexpr bool Do(T x, U y, V *result)
+ {
+ const result_type tmp =
+ IsGreater<T, U>::Test(x, y) ? static_cast<result_type>(x) : static_cast<result_type>(y);
+ if (!IsValueInRangeForNumericType<V>(tmp))
+ return false;
+ *result = static_cast<V>(tmp);
+ return true;
+ }
+};
+
+// Min doesn't really need to be implemented this way because it can't fail,
+// but it makes the code much cleaner to use the MathOp wrappers.
+template <typename T, typename U, class Enable = void>
+struct CheckedMinOp
+{};
+
+template <typename T, typename U>
+struct CheckedMinOp<
+ T,
+ U,
+ typename std::enable_if<std::is_arithmetic<T>::value && std::is_arithmetic<U>::value>::type>
+{
+ using result_type = typename LowestValuePromotion<T, U>::type;
+ template <typename V>
+ static constexpr bool Do(T x, U y, V *result)
+ {
+ const result_type tmp =
+ IsLess<T, U>::Test(x, y) ? static_cast<result_type>(x) : static_cast<result_type>(y);
+ if (!IsValueInRangeForNumericType<V>(tmp))
+ return false;
+ *result = static_cast<V>(tmp);
+ return true;
+ }
+};
+
+// This is just boilerplate that wraps the standard floating point arithmetic.
+// A macro isn't the nicest solution, but it beats rewriting these repeatedly.
+#define BASE_FLOAT_ARITHMETIC_OPS(NAME, OP) \
+ template <typename T, typename U> \
+ struct Checked##NAME##Op<T, U, \
+ typename std::enable_if<std::is_floating_point<T>::value || \
+ std::is_floating_point<U>::value>::type> \
+ { \
+ using result_type = typename MaxExponentPromotion<T, U>::type; \
+ template <typename V> \
+ static constexpr bool Do(T x, U y, V *result) \
+ { \
+ using Promotion = typename MaxExponentPromotion<T, U>::type; \
+ const Promotion presult = x OP y; \
+ if (!IsValueInRangeForNumericType<V>(presult)) \
+ return false; \
+ *result = static_cast<V>(presult); \
+ return true; \
+ } \
+ };
+
+BASE_FLOAT_ARITHMETIC_OPS(Add, +)
+BASE_FLOAT_ARITHMETIC_OPS(Sub, -)
+BASE_FLOAT_ARITHMETIC_OPS(Mul, *)
+BASE_FLOAT_ARITHMETIC_OPS(Div, /)
+
+#undef BASE_FLOAT_ARITHMETIC_OPS
+
+// Floats carry around their validity state with them, but integers do not. So,
+// we wrap the underlying value in a specialization in order to hide that detail
+// and expose an interface via accessors.
+enum NumericRepresentation
+{
+ NUMERIC_INTEGER,
+ NUMERIC_FLOATING,
+ NUMERIC_UNKNOWN
+};
+
+template <typename NumericType>
+struct GetNumericRepresentation
+{
+ static const NumericRepresentation value =
+ std::is_integral<NumericType>::value
+ ? NUMERIC_INTEGER
+ : (std::is_floating_point<NumericType>::value ? NUMERIC_FLOATING : NUMERIC_UNKNOWN);
+};
+
+template <typename T, NumericRepresentation type = GetNumericRepresentation<T>::value>
+class CheckedNumericState
+{};
+
+// Integrals require quite a bit of additional housekeeping to manage state.
+template <typename T>
+class CheckedNumericState<T, NUMERIC_INTEGER>
+{
+ public:
+ template <typename Src = int>
+ constexpr explicit CheckedNumericState(Src value = 0, bool is_valid = true)
+ : is_valid_(is_valid && IsValueInRangeForNumericType<T>(value)),
+ value_(WellDefinedConversionOrZero(value, is_valid_))
+ {
+ static_assert(std::is_arithmetic<Src>::value, "Argument must be numeric.");
+ }
+
+ template <typename Src>
+ constexpr CheckedNumericState(const CheckedNumericState<Src> &rhs)
+ : CheckedNumericState(rhs.value(), rhs.is_valid())
+ {}
+
+ constexpr bool is_valid() const { return is_valid_; }
+
+ constexpr T value() const { return value_; }
+
+ private:
+ // Ensures that a type conversion does not trigger undefined behavior.
+ template <typename Src>
+ static constexpr T WellDefinedConversionOrZero(Src value, bool is_valid)
+ {
+ using SrcType = typename internal::UnderlyingType<Src>::type;
+ return (std::is_integral<SrcType>::value || is_valid) ? static_cast<T>(value) : 0;
+ }
+
+ // is_valid_ precedes value_ because member intializers in the constructors
+ // are evaluated in field order, and is_valid_ must be read when initializing
+ // value_.
+ bool is_valid_;
+ T value_;
+};
+
+// Floating points maintain their own validity, but need translation wrappers.
+template <typename T>
+class CheckedNumericState<T, NUMERIC_FLOATING>
+{
+ public:
+ template <typename Src = double>
+ constexpr explicit CheckedNumericState(Src value = 0.0, bool is_valid = true)
+ : value_(
+ WellDefinedConversionOrNaN(value, is_valid && IsValueInRangeForNumericType<T>(value)))
+ {}
+
+ template <typename Src>
+ constexpr CheckedNumericState(const CheckedNumericState<Src> &rhs)
+ : CheckedNumericState(rhs.value(), rhs.is_valid())
+ {}
+
+ constexpr bool is_valid() const
+ {
+ // Written this way because std::isfinite is not reliably constexpr.
+ return MustTreatAsConstexpr(value_) ? value_ <= std::numeric_limits<T>::max() &&
+ value_ >= std::numeric_limits<T>::lowest()
+ : std::isfinite(value_);
+ }
+
+ constexpr T value() const { return value_; }
+
+ private:
+ // Ensures that a type conversion does not trigger undefined behavior.
+ template <typename Src>
+ static constexpr T WellDefinedConversionOrNaN(Src value, bool is_valid)
+ {
+ using SrcType = typename internal::UnderlyingType<Src>::type;
+ return (StaticDstRangeRelationToSrcRange<T, SrcType>::value == NUMERIC_RANGE_CONTAINED ||
+ is_valid)
+ ? static_cast<T>(value)
+ : std::numeric_limits<T>::quiet_NaN();
+ }
+
+ T value_;
+};
+
+} // namespace internal
+} // namespace base
+} // namespace angle
+
+#endif // BASE_NUMERICS_CHECKED_MATH_IMPL_H_
diff --git a/gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/clamped_math.h b/gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/clamped_math.h
new file mode 100644
index 0000000000..33d2e4b233
--- /dev/null
+++ b/gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/clamped_math.h
@@ -0,0 +1,270 @@
+// Copyright 2017 The Chromium 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 BASE_NUMERICS_CLAMPED_MATH_H_
+#define BASE_NUMERICS_CLAMPED_MATH_H_
+
+#include <stddef.h>
+
+#include <limits>
+#include <type_traits>
+
+#include "anglebase/numerics/clamped_math_impl.h"
+
+namespace angle
+{
+namespace base
+{
+namespace internal
+{
+
+template <typename T>
+class ClampedNumeric
+{
+ static_assert(std::is_arithmetic<T>::value, "ClampedNumeric<T>: T must be a numeric type.");
+
+ public:
+ using type = T;
+
+ constexpr ClampedNumeric() : value_(0) {}
+
+ // Copy constructor.
+ template <typename Src>
+ constexpr ClampedNumeric(const ClampedNumeric<Src> &rhs) : value_(saturated_cast<T>(rhs.value_))
+ {}
+
+ template <typename Src>
+ friend class ClampedNumeric;
+
+ // This is not an explicit constructor because we implicitly upgrade regular
+ // numerics to ClampedNumerics to make them easier to use.
+ template <typename Src>
+ constexpr ClampedNumeric(Src value) // NOLINT(runtime/explicit)
+ : value_(saturated_cast<T>(value))
+ {
+ static_assert(std::is_arithmetic<Src>::value, "Argument must be numeric.");
+ }
+
+ // This is not an explicit constructor because we want a seamless conversion
+ // from StrictNumeric types.
+ template <typename Src>
+ constexpr ClampedNumeric(StrictNumeric<Src> value) // NOLINT(runtime/explicit)
+ : value_(saturated_cast<T>(static_cast<Src>(value)))
+ {}
+
+ // Returns a ClampedNumeric of the specified type, cast from the current
+ // ClampedNumeric, and saturated to the destination type.
+ template <typename Dst>
+ constexpr ClampedNumeric<typename UnderlyingType<Dst>::type> Cast() const
+ {
+ return *this;
+ }
+
+ // Prototypes for the supported arithmetic operator overloads.
+ template <typename Src>
+ constexpr ClampedNumeric &operator+=(const Src rhs);
+ template <typename Src>
+ constexpr ClampedNumeric &operator-=(const Src rhs);
+ template <typename Src>
+ constexpr ClampedNumeric &operator*=(const Src rhs);
+ template <typename Src>
+ constexpr ClampedNumeric &operator/=(const Src rhs);
+ template <typename Src>
+ constexpr ClampedNumeric &operator%=(const Src rhs);
+ template <typename Src>
+ constexpr ClampedNumeric &operator<<=(const Src rhs);
+ template <typename Src>
+ constexpr ClampedNumeric &operator>>=(const Src rhs);
+ template <typename Src>
+ constexpr ClampedNumeric &operator&=(const Src rhs);
+ template <typename Src>
+ constexpr ClampedNumeric &operator|=(const Src rhs);
+ template <typename Src>
+ constexpr ClampedNumeric &operator^=(const Src rhs);
+
+ constexpr ClampedNumeric operator-() const
+ {
+ // The negation of two's complement int min is int min, so that's the
+ // only overflow case where we will saturate.
+ return ClampedNumeric<T>(SaturatedNegWrapper(value_));
+ }
+
+ constexpr ClampedNumeric operator~() const
+ {
+ return ClampedNumeric<decltype(InvertWrapper(T()))>(InvertWrapper(value_));
+ }
+
+ constexpr ClampedNumeric Abs() const
+ {
+ // The negation of two's complement int min is int min, so that's the
+ // only overflow case where we will saturate.
+ return ClampedNumeric<T>(SaturatedAbsWrapper(value_));
+ }
+
+ template <typename U>
+ constexpr ClampedNumeric<typename MathWrapper<ClampedMaxOp, T, U>::type> Max(const U rhs) const
+ {
+ using result_type = typename MathWrapper<ClampedMaxOp, T, U>::type;
+ return ClampedNumeric<result_type>(ClampedMaxOp<T, U>::Do(value_, Wrapper<U>::value(rhs)));
+ }
+
+ template <typename U>
+ constexpr ClampedNumeric<typename MathWrapper<ClampedMinOp, T, U>::type> Min(const U rhs) const
+ {
+ using result_type = typename MathWrapper<ClampedMinOp, T, U>::type;
+ return ClampedNumeric<result_type>(ClampedMinOp<T, U>::Do(value_, Wrapper<U>::value(rhs)));
+ }
+
+ // This function is available only for integral types. It returns an unsigned
+ // integer of the same width as the source type, containing the absolute value
+ // of the source, and properly handling signed min.
+ constexpr ClampedNumeric<typename UnsignedOrFloatForSize<T>::type> UnsignedAbs() const
+ {
+ return ClampedNumeric<typename UnsignedOrFloatForSize<T>::type>(SafeUnsignedAbs(value_));
+ }
+
+ constexpr ClampedNumeric &operator++()
+ {
+ *this += 1;
+ return *this;
+ }
+
+ constexpr ClampedNumeric operator++(int)
+ {
+ ClampedNumeric value = *this;
+ *this += 1;
+ return value;
+ }
+
+ constexpr ClampedNumeric &operator--()
+ {
+ *this -= 1;
+ return *this;
+ }
+
+ constexpr ClampedNumeric operator--(int)
+ {
+ ClampedNumeric value = *this;
+ *this -= 1;
+ return value;
+ }
+
+ // These perform the actual math operations on the ClampedNumerics.
+ // Binary arithmetic operations.
+ template <template <typename, typename, typename> class M, typename L, typename R>
+ static constexpr ClampedNumeric MathOp(const L lhs, const R rhs)
+ {
+ using Math = typename MathWrapper<M, L, R>::math;
+ return ClampedNumeric<T>(
+ Math::template Do<T>(Wrapper<L>::value(lhs), Wrapper<R>::value(rhs)));
+ }
+
+ // Assignment arithmetic operations.
+ template <template <typename, typename, typename> class M, typename R>
+ constexpr ClampedNumeric &MathOp(const R rhs)
+ {
+ using Math = typename MathWrapper<M, T, R>::math;
+ *this = ClampedNumeric<T>(Math::template Do<T>(value_, Wrapper<R>::value(rhs)));
+ return *this;
+ }
+
+ template <typename Dst>
+ constexpr operator Dst() const
+ {
+ return saturated_cast<typename ArithmeticOrUnderlyingEnum<Dst>::type>(value_);
+ }
+
+ // This method extracts the raw integer value without saturating it to the
+ // destination type as the conversion operator does. This is useful when
+ // e.g. assigning to an auto type or passing as a deduced template parameter.
+ constexpr T RawValue() const { return value_; }
+
+ private:
+ T value_;
+
+ // These wrappers allow us to handle state the same way for both
+ // ClampedNumeric and POD arithmetic types.
+ template <typename Src>
+ struct Wrapper
+ {
+ static constexpr Src value(Src value)
+ {
+ return static_cast<typename UnderlyingType<Src>::type>(value);
+ }
+ };
+};
+
+// Convience wrapper to return a new ClampedNumeric from the provided arithmetic
+// or ClampedNumericType.
+template <typename T>
+constexpr ClampedNumeric<typename UnderlyingType<T>::type> MakeClampedNum(const T value)
+{
+ return value;
+}
+
+#if !BASE_NUMERICS_DISABLE_OSTREAM_OPERATORS
+// Overload the ostream output operator to make logging work nicely.
+template <typename T>
+std::ostream &operator<<(std::ostream &os, const ClampedNumeric<T> &value)
+{
+ os << static_cast<T>(value);
+ return os;
+}
+#endif
+
+// These implement the variadic wrapper for the math operations.
+template <template <typename, typename, typename> class M, typename L, typename R>
+constexpr ClampedNumeric<typename MathWrapper<M, L, R>::type> ClampMathOp(const L lhs, const R rhs)
+{
+ using Math = typename MathWrapper<M, L, R>::math;
+ return ClampedNumeric<typename Math::result_type>::template MathOp<M>(lhs, rhs);
+}
+
+// General purpose wrapper template for arithmetic operations.
+template <template <typename, typename, typename> class M, typename L, typename R, typename... Args>
+constexpr auto ClampMathOp(const L lhs, const R rhs, const Args... args)
+{
+ return ClampMathOp<M>(ClampMathOp<M>(lhs, rhs), args...);
+}
+
+BASE_NUMERIC_ARITHMETIC_OPERATORS(Clamped, Clamp, Add, +, +=)
+BASE_NUMERIC_ARITHMETIC_OPERATORS(Clamped, Clamp, Sub, -, -=)
+BASE_NUMERIC_ARITHMETIC_OPERATORS(Clamped, Clamp, Mul, *, *=)
+BASE_NUMERIC_ARITHMETIC_OPERATORS(Clamped, Clamp, Div, /, /=)
+BASE_NUMERIC_ARITHMETIC_OPERATORS(Clamped, Clamp, Mod, %, %=)
+BASE_NUMERIC_ARITHMETIC_OPERATORS(Clamped, Clamp, Lsh, <<, <<=)
+BASE_NUMERIC_ARITHMETIC_OPERATORS(Clamped, Clamp, Rsh, >>, >>=)
+BASE_NUMERIC_ARITHMETIC_OPERATORS(Clamped, Clamp, And, &, &=)
+BASE_NUMERIC_ARITHMETIC_OPERATORS(Clamped, Clamp, Or, |, |=)
+BASE_NUMERIC_ARITHMETIC_OPERATORS(Clamped, Clamp, Xor, ^, ^=)
+BASE_NUMERIC_ARITHMETIC_VARIADIC(Clamped, Clamp, Max)
+BASE_NUMERIC_ARITHMETIC_VARIADIC(Clamped, Clamp, Min)
+BASE_NUMERIC_COMPARISON_OPERATORS(Clamped, IsLess, <)
+BASE_NUMERIC_COMPARISON_OPERATORS(Clamped, IsLessOrEqual, <=)
+BASE_NUMERIC_COMPARISON_OPERATORS(Clamped, IsGreater, >)
+BASE_NUMERIC_COMPARISON_OPERATORS(Clamped, IsGreaterOrEqual, >=)
+BASE_NUMERIC_COMPARISON_OPERATORS(Clamped, IsEqual, ==)
+BASE_NUMERIC_COMPARISON_OPERATORS(Clamped, IsNotEqual, !=)
+
+} // namespace internal
+
+using internal::ClampAdd;
+using internal::ClampAnd;
+using internal::ClampDiv;
+using internal::ClampedNumeric;
+using internal::ClampLsh;
+using internal::ClampMax;
+using internal::ClampMin;
+using internal::ClampMod;
+using internal::ClampMul;
+using internal::ClampOr;
+using internal::ClampRsh;
+using internal::ClampSub;
+using internal::ClampXor;
+using internal::MakeClampedNum;
+
+} // namespace base
+} // namespace angle
+
+#endif // BASE_NUMERICS_CLAMPED_MATH_H_
diff --git a/gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/clamped_math_impl.h b/gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/clamped_math_impl.h
new file mode 100644
index 0000000000..198723eeaa
--- /dev/null
+++ b/gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/clamped_math_impl.h
@@ -0,0 +1,368 @@
+// Copyright 2017 The Chromium 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 BASE_NUMERICS_CLAMPED_MATH_IMPL_H_
+#define BASE_NUMERICS_CLAMPED_MATH_IMPL_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <climits>
+#include <cmath>
+#include <cstdlib>
+#include <limits>
+#include <type_traits>
+
+#include "anglebase/numerics/checked_math.h"
+#include "anglebase/numerics/safe_conversions.h"
+#include "anglebase/numerics/safe_math_shared_impl.h"
+
+namespace angle
+{
+namespace base
+{
+namespace internal
+{
+
+template <typename T,
+ typename std::enable_if<std::is_integral<T>::value && std::is_signed<T>::value>::type * =
+ nullptr>
+constexpr T SaturatedNegWrapper(T value)
+{
+ return MustTreatAsConstexpr(value) || !ClampedNegFastOp<T>::is_supported
+ ? (NegateWrapper(value) != std::numeric_limits<T>::lowest()
+ ? NegateWrapper(value)
+ : std::numeric_limits<T>::max())
+ : ClampedNegFastOp<T>::Do(value);
+}
+
+template <typename T,
+ typename std::enable_if<std::is_integral<T>::value && !std::is_signed<T>::value>::type * =
+ nullptr>
+constexpr T SaturatedNegWrapper(T value)
+{
+ return T(0);
+}
+
+template <typename T, typename std::enable_if<std::is_floating_point<T>::value>::type * = nullptr>
+constexpr T SaturatedNegWrapper(T value)
+{
+ return -value;
+}
+
+template <typename T, typename std::enable_if<std::is_integral<T>::value>::type * = nullptr>
+constexpr T SaturatedAbsWrapper(T value)
+{
+ // The calculation below is a static identity for unsigned types, but for
+ // signed integer types it provides a non-branching, saturated absolute value.
+ // This works because SafeUnsignedAbs() returns an unsigned type, which can
+ // represent the absolute value of all negative numbers of an equal-width
+ // integer type. The call to IsValueNegative() then detects overflow in the
+ // special case of numeric_limits<T>::min(), by evaluating the bit pattern as
+ // a signed integer value. If it is the overflow case, we end up subtracting
+ // one from the unsigned result, thus saturating to numeric_limits<T>::max().
+ return static_cast<T>(SafeUnsignedAbs(value) - IsValueNegative<T>(SafeUnsignedAbs(value)));
+}
+
+template <typename T, typename std::enable_if<std::is_floating_point<T>::value>::type * = nullptr>
+constexpr T SaturatedAbsWrapper(T value)
+{
+ return value < 0 ? -value : value;
+}
+
+template <typename T, typename U, class Enable = void>
+struct ClampedAddOp
+{};
+
+template <typename T, typename U>
+struct ClampedAddOp<
+ T,
+ U,
+ typename std::enable_if<std::is_integral<T>::value && std::is_integral<U>::value>::type>
+{
+ using result_type = typename MaxExponentPromotion<T, U>::type;
+ template <typename V = result_type>
+ static constexpr V Do(T x, U y)
+ {
+ if (ClampedAddFastOp<T, U>::is_supported)
+ return ClampedAddFastOp<T, U>::template Do<V>(x, y);
+
+ static_assert(
+ std::is_same<V, result_type>::value || IsTypeInRangeForNumericType<U, V>::value,
+ "The saturation result cannot be determined from the "
+ "provided types.");
+ const V saturated = CommonMaxOrMin<V>(IsValueNegative(y));
+ V result = {};
+ return BASE_NUMERICS_LIKELY((CheckedAddOp<T, U>::Do(x, y, &result))) ? result : saturated;
+ }
+};
+
+template <typename T, typename U, class Enable = void>
+struct ClampedSubOp
+{};
+
+template <typename T, typename U>
+struct ClampedSubOp<
+ T,
+ U,
+ typename std::enable_if<std::is_integral<T>::value && std::is_integral<U>::value>::type>
+{
+ using result_type = typename MaxExponentPromotion<T, U>::type;
+ template <typename V = result_type>
+ static constexpr V Do(T x, U y)
+ {
+ if constexpr (ClampedSubFastOp<T, U>::is_supported)
+ return ClampedSubFastOp<T, U>::template Do<V>(x, y);
+
+ static_assert(
+ std::is_same<V, result_type>::value || IsTypeInRangeForNumericType<U, V>::value,
+ "The saturation result cannot be determined from the "
+ "provided types.");
+ const V saturated = CommonMaxOrMin<V>(!IsValueNegative(y));
+ V result = {};
+ return BASE_NUMERICS_LIKELY((CheckedSubOp<T, U>::Do(x, y, &result))) ? result : saturated;
+ }
+};
+
+template <typename T, typename U, class Enable = void>
+struct ClampedMulOp
+{};
+
+template <typename T, typename U>
+struct ClampedMulOp<
+ T,
+ U,
+ typename std::enable_if<std::is_integral<T>::value && std::is_integral<U>::value>::type>
+{
+ using result_type = typename MaxExponentPromotion<T, U>::type;
+ template <typename V = result_type>
+ static constexpr V Do(T x, U y)
+ {
+ if constexpr (ClampedMulFastOp<T, U>::is_supported)
+ return ClampedMulFastOp<T, U>::template Do<V>(x, y);
+
+ V result = {};
+ const V saturated = CommonMaxOrMin<V>(IsValueNegative(x) ^ IsValueNegative(y));
+ return BASE_NUMERICS_LIKELY((CheckedMulOp<T, U>::Do(x, y, &result))) ? result : saturated;
+ }
+};
+
+template <typename T, typename U, class Enable = void>
+struct ClampedDivOp
+{};
+
+template <typename T, typename U>
+struct ClampedDivOp<
+ T,
+ U,
+ typename std::enable_if<std::is_integral<T>::value && std::is_integral<U>::value>::type>
+{
+ using result_type = typename MaxExponentPromotion<T, U>::type;
+ template <typename V = result_type>
+ static constexpr V Do(T x, U y)
+ {
+ V result = {};
+ if (BASE_NUMERICS_LIKELY((CheckedDivOp<T, U>::Do(x, y, &result))))
+ return result;
+ // Saturation goes to max, min, or NaN (if x is zero).
+ return x ? CommonMaxOrMin<V>(IsValueNegative(x) ^ IsValueNegative(y))
+ : SaturationDefaultLimits<V>::NaN();
+ }
+};
+
+template <typename T, typename U, class Enable = void>
+struct ClampedModOp
+{};
+
+template <typename T, typename U>
+struct ClampedModOp<
+ T,
+ U,
+ typename std::enable_if<std::is_integral<T>::value && std::is_integral<U>::value>::type>
+{
+ using result_type = typename MaxExponentPromotion<T, U>::type;
+ template <typename V = result_type>
+ static constexpr V Do(T x, U y)
+ {
+ V result = {};
+ return BASE_NUMERICS_LIKELY((CheckedModOp<T, U>::Do(x, y, &result))) ? result : x;
+ }
+};
+
+template <typename T, typename U, class Enable = void>
+struct ClampedLshOp
+{};
+
+// Left shift. Non-zero values saturate in the direction of the sign. A zero
+// shifted by any value always results in zero.
+template <typename T, typename U>
+struct ClampedLshOp<
+ T,
+ U,
+ typename std::enable_if<std::is_integral<T>::value && std::is_integral<U>::value>::type>
+{
+ using result_type = T;
+ template <typename V = result_type>
+ static constexpr V Do(T x, U shift)
+ {
+ static_assert(!std::is_signed<U>::value, "Shift value must be unsigned.");
+ if (BASE_NUMERICS_LIKELY(shift < std::numeric_limits<T>::digits))
+ {
+ // Shift as unsigned to avoid undefined behavior.
+ V result = static_cast<V>(as_unsigned(x) << shift);
+ // If the shift can be reversed, we know it was valid.
+ if (BASE_NUMERICS_LIKELY(result >> shift == x))
+ return result;
+ }
+ return x ? CommonMaxOrMin<V>(IsValueNegative(x)) : 0;
+ }
+};
+
+template <typename T, typename U, class Enable = void>
+struct ClampedRshOp
+{};
+
+// Right shift. Negative values saturate to -1. Positive or 0 saturates to 0.
+template <typename T, typename U>
+struct ClampedRshOp<
+ T,
+ U,
+ typename std::enable_if<std::is_integral<T>::value && std::is_integral<U>::value>::type>
+{
+ using result_type = T;
+ template <typename V = result_type>
+ static constexpr V Do(T x, U shift)
+ {
+ static_assert(!std::is_signed<U>::value, "Shift value must be unsigned.");
+ // Signed right shift is odd, because it saturates to -1 or 0.
+ const V saturated = as_unsigned(V(0)) - IsValueNegative(x);
+ return BASE_NUMERICS_LIKELY(shift < IntegerBitsPlusSign<T>::value)
+ ? saturated_cast<V>(x >> shift)
+ : saturated;
+ }
+};
+
+template <typename T, typename U, class Enable = void>
+struct ClampedAndOp
+{};
+
+template <typename T, typename U>
+struct ClampedAndOp<
+ T,
+ U,
+ typename std::enable_if<std::is_integral<T>::value && std::is_integral<U>::value>::type>
+{
+ using result_type =
+ typename std::make_unsigned<typename MaxExponentPromotion<T, U>::type>::type;
+ template <typename V>
+ static constexpr V Do(T x, U y)
+ {
+ return static_cast<result_type>(x) & static_cast<result_type>(y);
+ }
+};
+
+template <typename T, typename U, class Enable = void>
+struct ClampedOrOp
+{};
+
+// For simplicity we promote to unsigned integers.
+template <typename T, typename U>
+struct ClampedOrOp<
+ T,
+ U,
+ typename std::enable_if<std::is_integral<T>::value && std::is_integral<U>::value>::type>
+{
+ using result_type =
+ typename std::make_unsigned<typename MaxExponentPromotion<T, U>::type>::type;
+ template <typename V>
+ static constexpr V Do(T x, U y)
+ {
+ return static_cast<result_type>(x) | static_cast<result_type>(y);
+ }
+};
+
+template <typename T, typename U, class Enable = void>
+struct ClampedXorOp
+{};
+
+// For simplicity we support only unsigned integers.
+template <typename T, typename U>
+struct ClampedXorOp<
+ T,
+ U,
+ typename std::enable_if<std::is_integral<T>::value && std::is_integral<U>::value>::type>
+{
+ using result_type =
+ typename std::make_unsigned<typename MaxExponentPromotion<T, U>::type>::type;
+ template <typename V>
+ static constexpr V Do(T x, U y)
+ {
+ return static_cast<result_type>(x) ^ static_cast<result_type>(y);
+ }
+};
+
+template <typename T, typename U, class Enable = void>
+struct ClampedMaxOp
+{};
+
+template <typename T, typename U>
+struct ClampedMaxOp<
+ T,
+ U,
+ typename std::enable_if<std::is_arithmetic<T>::value && std::is_arithmetic<U>::value>::type>
+{
+ using result_type = typename MaxExponentPromotion<T, U>::type;
+ template <typename V = result_type>
+ static constexpr V Do(T x, U y)
+ {
+ return IsGreater<T, U>::Test(x, y) ? saturated_cast<V>(x) : saturated_cast<V>(y);
+ }
+};
+
+template <typename T, typename U, class Enable = void>
+struct ClampedMinOp
+{};
+
+template <typename T, typename U>
+struct ClampedMinOp<
+ T,
+ U,
+ typename std::enable_if<std::is_arithmetic<T>::value && std::is_arithmetic<U>::value>::type>
+{
+ using result_type = typename LowestValuePromotion<T, U>::type;
+ template <typename V = result_type>
+ static constexpr V Do(T x, U y)
+ {
+ return IsLess<T, U>::Test(x, y) ? saturated_cast<V>(x) : saturated_cast<V>(y);
+ }
+};
+
+// This is just boilerplate that wraps the standard floating point arithmetic.
+// A macro isn't the nicest solution, but it beats rewriting these repeatedly.
+#define BASE_FLOAT_ARITHMETIC_OPS(NAME, OP) \
+ template <typename T, typename U> \
+ struct Clamped##NAME##Op<T, U, \
+ typename std::enable_if<std::is_floating_point<T>::value || \
+ std::is_floating_point<U>::value>::type> \
+ { \
+ using result_type = typename MaxExponentPromotion<T, U>::type; \
+ template <typename V = result_type> \
+ static constexpr V Do(T x, U y) \
+ { \
+ return saturated_cast<V>(x OP y); \
+ } \
+ };
+
+BASE_FLOAT_ARITHMETIC_OPS(Add, +)
+BASE_FLOAT_ARITHMETIC_OPS(Sub, -)
+BASE_FLOAT_ARITHMETIC_OPS(Mul, *)
+BASE_FLOAT_ARITHMETIC_OPS(Div, /)
+
+#undef BASE_FLOAT_ARITHMETIC_OPS
+
+} // namespace internal
+} // namespace base
+} // namespace angle
+
+#endif // BASE_NUMERICS_CLAMPED_MATH_IMPL_H_
diff --git a/gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/math_constants.h b/gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/math_constants.h
new file mode 100644
index 0000000000..385ce3970f
--- /dev/null
+++ b/gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/math_constants.h
@@ -0,0 +1,20 @@
+// Copyright 2017 The Chromium 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 BASE_NUMERICS_MATH_CONSTANTS_H_
+#define BASE_NUMERICS_MATH_CONSTANTS_H_
+
+namespace base
+{
+
+constexpr double kPiDouble = 3.14159265358979323846;
+constexpr float kPiFloat = 3.14159265358979323846f;
+
+// The mean acceleration due to gravity on Earth in m/s^2.
+constexpr double kMeanGravityDouble = 9.80665;
+constexpr float kMeanGravityFloat = 9.80665f;
+
+} // namespace base
+
+#endif // BASE_NUMERICS_MATH_CONSTANTS_H_
diff --git a/gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/ranges.h b/gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/ranges.h
new file mode 100644
index 0000000000..55a5a295af
--- /dev/null
+++ b/gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/ranges.h
@@ -0,0 +1,39 @@
+// Copyright 2017 The Chromium 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 BASE_NUMERICS_RANGES_H_
+#define BASE_NUMERICS_RANGES_H_
+
+#include <algorithm>
+#include <cmath>
+
+namespace base
+{
+
+// DO NOT USE THIS FUNCTION. IT IS DUE TO BE REMOVED. https://crbug.com/1231569
+// Please use base::clamp() from base/cxx17_backports.h instead.
+//
+// This function, unlike base::clamp(), does not check if `min` is greater than
+// `max`, and returns a bogus answer if it is. Please migrate all code that
+// calls this function to use base::clamp() instead.
+//
+// If, for some reason the broken behavior is required, please re-create this
+// min/max nesting inline in the host code and explain with a comment why it
+// is needed.
+template <class T>
+constexpr const T &BrokenClampThatShouldNotBeUsed(const T &value, const T &min, const T &max)
+{
+ return std::min(std::max(value, min), max);
+}
+
+template <typename T>
+constexpr bool IsApproximatelyEqual(T lhs, T rhs, T tolerance)
+{
+ static_assert(std::is_arithmetic<T>::value, "Argument must be arithmetic");
+ return std::abs(rhs - lhs) <= tolerance;
+}
+
+} // namespace base
+
+#endif // BASE_NUMERICS_RANGES_H_
diff --git a/gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/safe_conversions.h b/gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/safe_conversions.h
new file mode 100644
index 0000000000..3aa80c7ed0
--- /dev/null
+++ b/gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/safe_conversions.h
@@ -0,0 +1,403 @@
+// Copyright 2014 The Chromium 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 BASE_NUMERICS_SAFE_CONVERSIONS_H_
+#define BASE_NUMERICS_SAFE_CONVERSIONS_H_
+
+#include <stddef.h>
+
+#include <cmath>
+#include <limits>
+#include <type_traits>
+
+#include "anglebase/numerics/safe_conversions_impl.h"
+
+#if defined(__ARMEL__) && !defined(__native_client__)
+# include "anglebase/numerics/safe_conversions_arm_impl.h"
+# define BASE_HAS_OPTIMIZED_SAFE_CONVERSIONS (1)
+#else
+# define BASE_HAS_OPTIMIZED_SAFE_CONVERSIONS (0)
+#endif
+
+#if !BASE_NUMERICS_DISABLE_OSTREAM_OPERATORS
+# include <ostream>
+#endif
+
+namespace angle
+{
+namespace base
+{
+namespace internal
+{
+
+#if !BASE_HAS_OPTIMIZED_SAFE_CONVERSIONS
+template <typename Dst, typename Src>
+struct SaturateFastAsmOp
+{
+ static constexpr bool is_supported = false;
+ static constexpr Dst Do(Src)
+ {
+ // Force a compile failure if instantiated.
+ return CheckOnFailure::template HandleFailure<Dst>();
+ }
+};
+#endif // BASE_HAS_OPTIMIZED_SAFE_CONVERSIONS
+#undef BASE_HAS_OPTIMIZED_SAFE_CONVERSIONS
+
+// The following special case a few specific integer conversions where we can
+// eke out better performance than range checking.
+template <typename Dst, typename Src, typename Enable = void>
+struct IsValueInRangeFastOp
+{
+ static constexpr bool is_supported = false;
+ static constexpr bool Do(Src value)
+ {
+ // Force a compile failure if instantiated.
+ return CheckOnFailure::template HandleFailure<bool>();
+ }
+};
+
+// Signed to signed range comparison.
+template <typename Dst, typename Src>
+struct IsValueInRangeFastOp<
+ Dst,
+ Src,
+ typename std::enable_if<std::is_integral<Dst>::value && std::is_integral<Src>::value &&
+ std::is_signed<Dst>::value && std::is_signed<Src>::value &&
+ !IsTypeInRangeForNumericType<Dst, Src>::value>::type>
+{
+ static constexpr bool is_supported = true;
+
+ static constexpr bool Do(Src value)
+ {
+ // Just downcast to the smaller type, sign extend it back to the original
+ // type, and then see if it matches the original value.
+ return value == static_cast<Dst>(value);
+ }
+};
+
+// Signed to unsigned range comparison.
+template <typename Dst, typename Src>
+struct IsValueInRangeFastOp<
+ Dst,
+ Src,
+ typename std::enable_if<std::is_integral<Dst>::value && std::is_integral<Src>::value &&
+ !std::is_signed<Dst>::value && std::is_signed<Src>::value &&
+ !IsTypeInRangeForNumericType<Dst, Src>::value>::type>
+{
+ static constexpr bool is_supported = true;
+
+ static constexpr bool Do(Src value)
+ {
+ // We cast a signed as unsigned to overflow negative values to the top,
+ // then compare against whichever maximum is smaller, as our upper bound.
+ return as_unsigned(value) <= as_unsigned(CommonMax<Src, Dst>());
+ }
+};
+
+// Convenience function that returns true if the supplied value is in range
+// for the destination type.
+template <typename Dst, typename Src>
+constexpr bool IsValueInRangeForNumericType(Src value)
+{
+ using SrcType = typename internal::UnderlyingType<Src>::type;
+ return internal::IsValueInRangeFastOp<Dst, SrcType>::is_supported
+ ? internal::IsValueInRangeFastOp<Dst, SrcType>::Do(static_cast<SrcType>(value))
+ : internal::DstRangeRelationToSrcRange<Dst>(static_cast<SrcType>(value)).IsValid();
+}
+
+// checked_cast<> is analogous to static_cast<> for numeric types,
+// except that it CHECKs that the specified numeric conversion will not
+// overflow or underflow. NaN source will always trigger a CHECK.
+template <typename Dst, class CheckHandler = internal::CheckOnFailure, typename Src>
+constexpr Dst checked_cast(Src value)
+{
+ // This throws a compile-time error on evaluating the constexpr if it can be
+ // determined at compile-time as failing, otherwise it will CHECK at runtime.
+ using SrcType = typename internal::UnderlyingType<Src>::type;
+ return BASE_NUMERICS_LIKELY((IsValueInRangeForNumericType<Dst>(value)))
+ ? static_cast<Dst>(static_cast<SrcType>(value))
+ : CheckHandler::template HandleFailure<Dst>();
+}
+
+// Default boundaries for integral/float: max/infinity, lowest/-infinity, 0/NaN.
+// You may provide your own limits (e.g. to saturated_cast) so long as you
+// implement all of the static constexpr member functions in the class below.
+template <typename T>
+struct SaturationDefaultLimits : public std::numeric_limits<T>
+{
+ static constexpr T NaN()
+ {
+ return std::numeric_limits<T>::has_quiet_NaN ? std::numeric_limits<T>::quiet_NaN() : T();
+ }
+ using std::numeric_limits<T>::max;
+ static constexpr T Overflow()
+ {
+ return std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity()
+ : std::numeric_limits<T>::max();
+ }
+ using std::numeric_limits<T>::lowest;
+ static constexpr T Underflow()
+ {
+ return std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() * -1
+ : std::numeric_limits<T>::lowest();
+ }
+};
+
+template <typename Dst, template <typename> class S, typename Src>
+constexpr Dst saturated_cast_impl(Src value, RangeCheck constraint)
+{
+ // For some reason clang generates much better code when the branch is
+ // structured exactly this way, rather than a sequence of checks.
+ return !constraint.IsOverflowFlagSet()
+ ? (!constraint.IsUnderflowFlagSet() ? static_cast<Dst>(value) : S<Dst>::Underflow())
+ // Skip this check for integral Src, which cannot be NaN.
+ : (std::is_integral<Src>::value || !constraint.IsUnderflowFlagSet()
+ ? S<Dst>::Overflow()
+ : S<Dst>::NaN());
+}
+
+// We can reduce the number of conditions and get slightly better performance
+// for normal signed and unsigned integer ranges. And in the specific case of
+// Arm, we can use the optimized saturation instructions.
+template <typename Dst, typename Src, typename Enable = void>
+struct SaturateFastOp
+{
+ static constexpr bool is_supported = false;
+ static constexpr Dst Do(Src value)
+ {
+ // Force a compile failure if instantiated.
+ return CheckOnFailure::template HandleFailure<Dst>();
+ }
+};
+
+template <typename Dst, typename Src>
+struct SaturateFastOp<
+ Dst,
+ Src,
+ typename std::enable_if<std::is_integral<Src>::value && std::is_integral<Dst>::value &&
+ SaturateFastAsmOp<Dst, Src>::is_supported>::type>
+{
+ static constexpr bool is_supported = true;
+ static constexpr Dst Do(Src value) { return SaturateFastAsmOp<Dst, Src>::Do(value); }
+};
+
+template <typename Dst, typename Src>
+struct SaturateFastOp<
+ Dst,
+ Src,
+ typename std::enable_if<std::is_integral<Src>::value && std::is_integral<Dst>::value &&
+ !SaturateFastAsmOp<Dst, Src>::is_supported>::type>
+{
+ static constexpr bool is_supported = true;
+ static constexpr Dst Do(Src value)
+ {
+ // The exact order of the following is structured to hit the correct
+ // optimization heuristics across compilers. Do not change without
+ // checking the emitted code.
+ const Dst saturated = CommonMaxOrMin<Dst, Src>(
+ IsMaxInRangeForNumericType<Dst, Src>() ||
+ (!IsMinInRangeForNumericType<Dst, Src>() && IsValueNegative(value)));
+ return BASE_NUMERICS_LIKELY(IsValueInRangeForNumericType<Dst>(value))
+ ? static_cast<Dst>(value)
+ : saturated;
+ }
+};
+
+// saturated_cast<> is analogous to static_cast<> for numeric types, except
+// that the specified numeric conversion will saturate by default rather than
+// overflow or underflow, and NaN assignment to an integral will return 0.
+// All boundary condition behaviors can be overriden with a custom handler.
+template <typename Dst,
+ template <typename> class SaturationHandler = SaturationDefaultLimits,
+ typename Src>
+constexpr Dst saturated_cast(Src value)
+{
+ using SrcType = typename UnderlyingType<Src>::type;
+ return !IsCompileTimeConstant(value) && SaturateFastOp<Dst, SrcType>::is_supported &&
+ std::is_same<SaturationHandler<Dst>, SaturationDefaultLimits<Dst>>::value
+ ? SaturateFastOp<Dst, SrcType>::Do(static_cast<SrcType>(value))
+ : saturated_cast_impl<Dst, SaturationHandler, SrcType>(
+ static_cast<SrcType>(value),
+ DstRangeRelationToSrcRange<Dst, SaturationHandler, SrcType>(
+ static_cast<SrcType>(value)));
+}
+
+// strict_cast<> is analogous to static_cast<> for numeric types, except that
+// it will cause a compile failure if the destination type is not large enough
+// to contain any value in the source type. It performs no runtime checking.
+template <typename Dst, typename Src>
+constexpr Dst strict_cast(Src value)
+{
+ using SrcType = typename UnderlyingType<Src>::type;
+ static_assert(UnderlyingType<Src>::is_numeric, "Argument must be numeric.");
+ static_assert(std::is_arithmetic<Dst>::value, "Result must be numeric.");
+
+ // If you got here from a compiler error, it's because you tried to assign
+ // from a source type to a destination type that has insufficient range.
+ // The solution may be to change the destination type you're assigning to,
+ // and use one large enough to represent the source.
+ // Alternatively, you may be better served with the checked_cast<> or
+ // saturated_cast<> template functions for your particular use case.
+ static_assert(StaticDstRangeRelationToSrcRange<Dst, SrcType>::value == NUMERIC_RANGE_CONTAINED,
+ "The source type is out of range for the destination type. "
+ "Please see strict_cast<> comments for more information.");
+
+ return static_cast<Dst>(static_cast<SrcType>(value));
+}
+
+// Some wrappers to statically check that a type is in range.
+template <typename Dst, typename Src, class Enable = void>
+struct IsNumericRangeContained
+{
+ static constexpr bool value = false;
+};
+
+template <typename Dst, typename Src>
+struct IsNumericRangeContained<
+ Dst,
+ Src,
+ typename std::enable_if<ArithmeticOrUnderlyingEnum<Dst>::value &&
+ ArithmeticOrUnderlyingEnum<Src>::value>::type>
+{
+ static constexpr bool value =
+ StaticDstRangeRelationToSrcRange<Dst, Src>::value == NUMERIC_RANGE_CONTAINED;
+};
+
+// StrictNumeric implements compile time range checking between numeric types by
+// wrapping assignment operations in a strict_cast. This class is intended to be
+// used for function arguments and return types, to ensure the destination type
+// can always contain the source type. This is essentially the same as enforcing
+// -Wconversion in gcc and C4302 warnings on MSVC, but it can be applied
+// incrementally at API boundaries, making it easier to convert code so that it
+// compiles cleanly with truncation warnings enabled.
+// This template should introduce no runtime overhead, but it also provides no
+// runtime checking of any of the associated mathematical operations. Use
+// CheckedNumeric for runtime range checks of the actual value being assigned.
+template <typename T>
+class StrictNumeric
+{
+ public:
+ using type = T;
+
+ constexpr StrictNumeric() : value_(0) {}
+
+ // Copy constructor.
+ template <typename Src>
+ constexpr StrictNumeric(const StrictNumeric<Src> &rhs) : value_(strict_cast<T>(rhs.value_))
+ {}
+
+ // This is not an explicit constructor because we implicitly upgrade regular
+ // numerics to StrictNumerics to make them easier to use.
+ template <typename Src>
+ constexpr StrictNumeric(Src value) // NOLINT(runtime/explicit)
+ : value_(strict_cast<T>(value))
+ {}
+
+ // If you got here from a compiler error, it's because you tried to assign
+ // from a source type to a destination type that has insufficient range.
+ // The solution may be to change the destination type you're assigning to,
+ // and use one large enough to represent the source.
+ // If you're assigning from a CheckedNumeric<> class, you may be able to use
+ // the AssignIfValid() member function, specify a narrower destination type to
+ // the member value functions (e.g. val.template ValueOrDie<Dst>()), use one
+ // of the value helper functions (e.g. ValueOrDieForType<Dst>(val)).
+ // If you've encountered an _ambiguous overload_ you can use a static_cast<>
+ // to explicitly cast the result to the destination type.
+ // If none of that works, you may be better served with the checked_cast<> or
+ // saturated_cast<> template functions for your particular use case.
+ template <typename Dst,
+ typename std::enable_if<IsNumericRangeContained<Dst, T>::value>::type * = nullptr>
+ constexpr operator Dst() const
+ {
+ return static_cast<typename ArithmeticOrUnderlyingEnum<Dst>::type>(value_);
+ }
+
+ private:
+ const T value_;
+};
+
+// Convience wrapper returns a StrictNumeric from the provided arithmetic type.
+template <typename T>
+constexpr StrictNumeric<typename UnderlyingType<T>::type> MakeStrictNum(const T value)
+{
+ return value;
+}
+
+#if !BASE_NUMERICS_DISABLE_OSTREAM_OPERATORS
+// Overload the ostream output operator to make logging work nicely.
+template <typename T>
+std::ostream &operator<<(std::ostream &os, const StrictNumeric<T> &value)
+{
+ os << static_cast<T>(value);
+ return os;
+}
+#endif
+
+#define BASE_NUMERIC_COMPARISON_OPERATORS(CLASS, NAME, OP) \
+ template <typename L, typename R, \
+ typename std::enable_if<internal::Is##CLASS##Op<L, R>::value>::type * = nullptr> \
+ constexpr bool operator OP(const L lhs, const R rhs) \
+ { \
+ return SafeCompare<NAME, typename UnderlyingType<L>::type, \
+ typename UnderlyingType<R>::type>(lhs, rhs); \
+ }
+
+BASE_NUMERIC_COMPARISON_OPERATORS(Strict, IsLess, <)
+BASE_NUMERIC_COMPARISON_OPERATORS(Strict, IsLessOrEqual, <=)
+BASE_NUMERIC_COMPARISON_OPERATORS(Strict, IsGreater, >)
+BASE_NUMERIC_COMPARISON_OPERATORS(Strict, IsGreaterOrEqual, >=)
+BASE_NUMERIC_COMPARISON_OPERATORS(Strict, IsEqual, ==)
+BASE_NUMERIC_COMPARISON_OPERATORS(Strict, IsNotEqual, !=)
+
+} // namespace internal
+
+using internal::as_signed;
+using internal::as_unsigned;
+using internal::checked_cast;
+using internal::IsTypeInRangeForNumericType;
+using internal::IsValueInRangeForNumericType;
+using internal::IsValueNegative;
+using internal::MakeStrictNum;
+using internal::SafeUnsignedAbs;
+using internal::saturated_cast;
+using internal::strict_cast;
+using internal::StrictNumeric;
+
+// Explicitly make a shorter size_t alias for convenience.
+using SizeT = StrictNumeric<size_t>;
+
+// floating -> integral conversions that saturate and thus can actually return
+// an integral type. In most cases, these should be preferred over the std::
+// versions.
+template <
+ typename Dst = int,
+ typename Src,
+ typename = std::enable_if_t<std::is_integral<Dst>::value && std::is_floating_point<Src>::value>>
+Dst ClampFloor(Src value)
+{
+ return saturated_cast<Dst>(std::floor(value));
+}
+template <
+ typename Dst = int,
+ typename Src,
+ typename = std::enable_if_t<std::is_integral<Dst>::value && std::is_floating_point<Src>::value>>
+Dst ClampCeil(Src value)
+{
+ return saturated_cast<Dst>(std::ceil(value));
+}
+template <
+ typename Dst = int,
+ typename Src,
+ typename = std::enable_if_t<std::is_integral<Dst>::value && std::is_floating_point<Src>::value>>
+Dst ClampRound(Src value)
+{
+ const Src rounded = (value >= 0.0f) ? std::floor(value + 0.5f) : std::ceil(value - 0.5f);
+ return saturated_cast<Dst>(rounded);
+}
+
+} // namespace base
+} // namespace angle
+
+#endif // BASE_NUMERICS_SAFE_CONVERSIONS_H_
diff --git a/gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/safe_conversions_arm_impl.h b/gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/safe_conversions_arm_impl.h
new file mode 100644
index 0000000000..74e5bcc0c6
--- /dev/null
+++ b/gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/safe_conversions_arm_impl.h
@@ -0,0 +1,60 @@
+// Copyright 2017 The Chromium 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 BASE_NUMERICS_SAFE_CONVERSIONS_ARM_IMPL_H_
+#define BASE_NUMERICS_SAFE_CONVERSIONS_ARM_IMPL_H_
+
+#include <cassert>
+#include <limits>
+#include <type_traits>
+
+#include "anglebase/numerics/safe_conversions_impl.h"
+
+namespace angle
+{
+namespace base
+{
+namespace internal
+{
+
+// Fast saturation to a destination type.
+template <typename Dst, typename Src>
+struct SaturateFastAsmOp
+{
+ static constexpr bool is_supported =
+ std::is_signed<Src>::value && std::is_integral<Dst>::value &&
+ std::is_integral<Src>::value &&
+ IntegerBitsPlusSign<Src>::value <= IntegerBitsPlusSign<int32_t>::value &&
+ IntegerBitsPlusSign<Dst>::value <= IntegerBitsPlusSign<int32_t>::value &&
+ !IsTypeInRangeForNumericType<Dst, Src>::value;
+
+ __attribute__((always_inline)) static Dst Do(Src value)
+ {
+ int32_t src = value;
+ typename std::conditional<std::is_signed<Dst>::value, int32_t, uint32_t>::type result;
+ if (std::is_signed<Dst>::value)
+ {
+ asm("ssat %[dst], %[shift], %[src]"
+ : [dst] "=r"(result)
+ : [src] "r"(src), [shift] "n"(IntegerBitsPlusSign<Dst>::value <= 32
+ ? IntegerBitsPlusSign<Dst>::value
+ : 32));
+ }
+ else
+ {
+ asm("usat %[dst], %[shift], %[src]"
+ : [dst] "=r"(result)
+ : [src] "r"(src), [shift] "n"(IntegerBitsPlusSign<Dst>::value < 32
+ ? IntegerBitsPlusSign<Dst>::value
+ : 31));
+ }
+ return static_cast<Dst>(result);
+ }
+};
+
+} // namespace internal
+} // namespace base
+} // namespace angle
+
+#endif // BASE_NUMERICS_SAFE_CONVERSIONS_ARM_IMPL_H_
diff --git a/gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/safe_conversions_impl.h b/gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/safe_conversions_impl.h
new file mode 100644
index 0000000000..7d0f031754
--- /dev/null
+++ b/gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/safe_conversions_impl.h
@@ -0,0 +1,893 @@
+// Copyright 2014 The Chromium 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 BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_
+#define BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_
+
+#include <stdint.h>
+
+#include <limits>
+#include <type_traits>
+
+#if defined(__GNUC__) || defined(__clang__)
+# define BASE_NUMERICS_LIKELY(x) __builtin_expect(!!(x), 1)
+# define BASE_NUMERICS_UNLIKELY(x) __builtin_expect(!!(x), 0)
+#else
+# define BASE_NUMERICS_LIKELY(x) (x)
+# define BASE_NUMERICS_UNLIKELY(x) (x)
+#endif
+
+namespace angle
+{
+namespace base
+{
+namespace internal
+{
+
+// The std library doesn't provide a binary max_exponent for integers, however
+// we can compute an analog using std::numeric_limits<>::digits.
+template <typename NumericType>
+struct MaxExponent
+{
+ static const int value = std::is_floating_point<NumericType>::value
+ ? std::numeric_limits<NumericType>::max_exponent
+ : std::numeric_limits<NumericType>::digits + 1;
+};
+
+// The number of bits (including the sign) in an integer. Eliminates sizeof
+// hacks.
+template <typename NumericType>
+struct IntegerBitsPlusSign
+{
+ static const int value =
+ std::numeric_limits<NumericType>::digits + std::is_signed<NumericType>::value;
+};
+
+// Helper templates for integer manipulations.
+
+template <typename Integer>
+struct PositionOfSignBit
+{
+ static const size_t value = IntegerBitsPlusSign<Integer>::value - 1;
+};
+
+// Determines if a numeric value is negative without throwing compiler
+// warnings on: unsigned(value) < 0.
+template <typename T, typename std::enable_if<std::is_signed<T>::value>::type * = nullptr>
+constexpr bool IsValueNegative(T value)
+{
+ static_assert(std::is_arithmetic<T>::value, "Argument must be numeric.");
+ return value < 0;
+}
+
+template <typename T, typename std::enable_if<!std::is_signed<T>::value>::type * = nullptr>
+constexpr bool IsValueNegative(T)
+{
+ static_assert(std::is_arithmetic<T>::value, "Argument must be numeric.");
+ return false;
+}
+
+// This performs a fast negation, returning a signed value. It works on unsigned
+// arguments, but probably doesn't do what you want for any unsigned value
+// larger than max / 2 + 1 (i.e. signed min cast to unsigned).
+template <typename T>
+constexpr typename std::make_signed<T>::type ConditionalNegate(T x, bool is_negative)
+{
+ static_assert(std::is_integral<T>::value, "Type must be integral");
+ using SignedT = typename std::make_signed<T>::type;
+ using UnsignedT = typename std::make_unsigned<T>::type;
+ return static_cast<SignedT>((static_cast<UnsignedT>(x) ^ -SignedT(is_negative)) + is_negative);
+}
+
+// This performs a safe, absolute value via unsigned overflow.
+template <typename T>
+constexpr typename std::make_unsigned<T>::type SafeUnsignedAbs(T value)
+{
+ static_assert(std::is_integral<T>::value, "Type must be integral");
+ using UnsignedT = typename std::make_unsigned<T>::type;
+ return IsValueNegative(value) ? static_cast<UnsignedT>(0u - static_cast<UnsignedT>(value))
+ : static_cast<UnsignedT>(value);
+}
+
+// This allows us to switch paths on known compile-time constants.
+#if defined(__clang__) || defined(__GNUC__)
+constexpr bool CanDetectCompileTimeConstant()
+{
+ return true;
+}
+template <typename T>
+constexpr bool IsCompileTimeConstant(const T v)
+{
+ return __builtin_constant_p(v);
+}
+#else
+constexpr bool CanDetectCompileTimeConstant()
+{
+ return false;
+}
+template <typename T>
+constexpr bool IsCompileTimeConstant(const T)
+{
+ return false;
+}
+#endif
+template <typename T>
+constexpr bool MustTreatAsConstexpr(const T v)
+{
+ // Either we can't detect a compile-time constant, and must always use the
+ // constexpr path, or we know we have a compile-time constant.
+ return !CanDetectCompileTimeConstant() || IsCompileTimeConstant(v);
+}
+
+// Forces a crash, like a CHECK(false). Used for numeric boundary errors.
+// Also used in a constexpr template to trigger a compilation failure on
+// an error condition.
+struct CheckOnFailure
+{
+ template <typename T>
+ static T HandleFailure()
+ {
+#if defined(_MSC_VER)
+ __debugbreak();
+#elif defined(__GNUC__) || defined(__clang__)
+ __builtin_trap();
+#else
+ ((void)(*(volatile char *)0 = 0));
+#endif
+ return T();
+ }
+};
+
+enum IntegerRepresentation
+{
+ INTEGER_REPRESENTATION_UNSIGNED,
+ INTEGER_REPRESENTATION_SIGNED
+};
+
+// A range for a given nunmeric Src type is contained for a given numeric Dst
+// type if both numeric_limits<Src>::max() <= numeric_limits<Dst>::max() and
+// numeric_limits<Src>::lowest() >= numeric_limits<Dst>::lowest() are true.
+// We implement this as template specializations rather than simple static
+// comparisons to ensure type correctness in our comparisons.
+enum NumericRangeRepresentation
+{
+ NUMERIC_RANGE_NOT_CONTAINED,
+ NUMERIC_RANGE_CONTAINED
+};
+
+// Helper templates to statically determine if our destination type can contain
+// maximum and minimum values represented by the source type.
+
+template <
+ typename Dst,
+ typename Src,
+ IntegerRepresentation DstSign = std::is_signed<Dst>::value ? INTEGER_REPRESENTATION_SIGNED
+ : INTEGER_REPRESENTATION_UNSIGNED,
+ IntegerRepresentation SrcSign = std::is_signed<Src>::value ? INTEGER_REPRESENTATION_SIGNED
+ : INTEGER_REPRESENTATION_UNSIGNED>
+struct StaticDstRangeRelationToSrcRange;
+
+// Same sign: Dst is guaranteed to contain Src only if its range is equal or
+// larger.
+template <typename Dst, typename Src, IntegerRepresentation Sign>
+struct StaticDstRangeRelationToSrcRange<Dst, Src, Sign, Sign>
+{
+ static const NumericRangeRepresentation value =
+ MaxExponent<Dst>::value >= MaxExponent<Src>::value ? NUMERIC_RANGE_CONTAINED
+ : NUMERIC_RANGE_NOT_CONTAINED;
+};
+
+// Unsigned to signed: Dst is guaranteed to contain source only if its range is
+// larger.
+template <typename Dst, typename Src>
+struct StaticDstRangeRelationToSrcRange<Dst,
+ Src,
+ INTEGER_REPRESENTATION_SIGNED,
+ INTEGER_REPRESENTATION_UNSIGNED>
+{
+ static const NumericRangeRepresentation value =
+ MaxExponent<Dst>::value > MaxExponent<Src>::value ? NUMERIC_RANGE_CONTAINED
+ : NUMERIC_RANGE_NOT_CONTAINED;
+};
+
+// Signed to unsigned: Dst cannot be statically determined to contain Src.
+template <typename Dst, typename Src>
+struct StaticDstRangeRelationToSrcRange<Dst,
+ Src,
+ INTEGER_REPRESENTATION_UNSIGNED,
+ INTEGER_REPRESENTATION_SIGNED>
+{
+ static const NumericRangeRepresentation value = NUMERIC_RANGE_NOT_CONTAINED;
+};
+
+// This class wraps the range constraints as separate booleans so the compiler
+// can identify constants and eliminate unused code paths.
+class RangeCheck
+{
+ public:
+ constexpr RangeCheck(bool is_in_lower_bound, bool is_in_upper_bound)
+ : is_underflow_(!is_in_lower_bound), is_overflow_(!is_in_upper_bound)
+ {}
+ constexpr RangeCheck() : is_underflow_(0), is_overflow_(0) {}
+ constexpr bool IsValid() const { return !is_overflow_ && !is_underflow_; }
+ constexpr bool IsInvalid() const { return is_overflow_ && is_underflow_; }
+ constexpr bool IsOverflow() const { return is_overflow_ && !is_underflow_; }
+ constexpr bool IsUnderflow() const { return !is_overflow_ && is_underflow_; }
+ constexpr bool IsOverflowFlagSet() const { return is_overflow_; }
+ constexpr bool IsUnderflowFlagSet() const { return is_underflow_; }
+ constexpr bool operator==(const RangeCheck rhs) const
+ {
+ return is_underflow_ == rhs.is_underflow_ && is_overflow_ == rhs.is_overflow_;
+ }
+ constexpr bool operator!=(const RangeCheck rhs) const { return !(*this == rhs); }
+
+ private:
+ // Do not change the order of these member variables. The integral conversion
+ // optimization depends on this exact order.
+ const bool is_underflow_;
+ const bool is_overflow_;
+};
+
+// The following helper template addresses a corner case in range checks for
+// conversion from a floating-point type to an integral type of smaller range
+// but larger precision (e.g. float -> unsigned). The problem is as follows:
+// 1. Integral maximum is always one less than a power of two, so it must be
+// truncated to fit the mantissa of the floating point. The direction of
+// rounding is implementation defined, but by default it's always IEEE
+// floats, which round to nearest and thus result in a value of larger
+// magnitude than the integral value.
+// Example: float f = UINT_MAX; // f is 4294967296f but UINT_MAX
+// // is 4294967295u.
+// 2. If the floating point value is equal to the promoted integral maximum
+// value, a range check will erroneously pass.
+// Example: (4294967296f <= 4294967295u) // This is true due to a precision
+// // loss in rounding up to float.
+// 3. When the floating point value is then converted to an integral, the
+// resulting value is out of range for the target integral type and
+// thus is implementation defined.
+// Example: unsigned u = (float)INT_MAX; // u will typically overflow to 0.
+// To fix this bug we manually truncate the maximum value when the destination
+// type is an integral of larger precision than the source floating-point type,
+// such that the resulting maximum is represented exactly as a floating point.
+template <typename Dst, typename Src, template <typename> class Bounds>
+struct NarrowingRange
+{
+ using SrcLimits = std::numeric_limits<Src>;
+ using DstLimits = typename std::numeric_limits<Dst>;
+
+ // Computes the mask required to make an accurate comparison between types.
+ static const int kShift =
+ (MaxExponent<Src>::value > MaxExponent<Dst>::value && SrcLimits::digits < DstLimits::digits)
+ ? (DstLimits::digits - SrcLimits::digits)
+ : 0;
+ template <typename T, typename std::enable_if<std::is_integral<T>::value>::type * = nullptr>
+
+ // Masks out the integer bits that are beyond the precision of the
+ // intermediate type used for comparison.
+ static constexpr T Adjust(T value)
+ {
+ static_assert(std::is_same<T, Dst>::value, "");
+ static_assert(kShift < DstLimits::digits, "");
+ return static_cast<T>(ConditionalNegate(SafeUnsignedAbs(value) & ~((T(1) << kShift) - T(1)),
+ IsValueNegative(value)));
+ }
+
+ template <typename T,
+ typename std::enable_if<std::is_floating_point<T>::value>::type * = nullptr>
+ static constexpr T Adjust(T value)
+ {
+ static_assert(std::is_same<T, Dst>::value, "");
+ static_assert(kShift == 0, "");
+ return value;
+ }
+
+ static constexpr Dst max() { return Adjust(Bounds<Dst>::max()); }
+ static constexpr Dst lowest() { return Adjust(Bounds<Dst>::lowest()); }
+};
+
+template <
+ typename Dst,
+ typename Src,
+ template <typename>
+ class Bounds,
+ IntegerRepresentation DstSign = std::is_signed<Dst>::value ? INTEGER_REPRESENTATION_SIGNED
+ : INTEGER_REPRESENTATION_UNSIGNED,
+ IntegerRepresentation SrcSign = std::is_signed<Src>::value ? INTEGER_REPRESENTATION_SIGNED
+ : INTEGER_REPRESENTATION_UNSIGNED,
+ NumericRangeRepresentation DstRange = StaticDstRangeRelationToSrcRange<Dst, Src>::value>
+struct DstRangeRelationToSrcRangeImpl;
+
+// The following templates are for ranges that must be verified at runtime. We
+// split it into checks based on signedness to avoid confusing casts and
+// compiler warnings on signed an unsigned comparisons.
+
+// Same sign narrowing: The range is contained for normal limits.
+template <typename Dst,
+ typename Src,
+ template <typename>
+ class Bounds,
+ IntegerRepresentation DstSign,
+ IntegerRepresentation SrcSign>
+struct DstRangeRelationToSrcRangeImpl<Dst, Src, Bounds, DstSign, SrcSign, NUMERIC_RANGE_CONTAINED>
+{
+ static constexpr RangeCheck Check(Src value)
+ {
+ using SrcLimits = std::numeric_limits<Src>;
+ using DstLimits = NarrowingRange<Dst, Src, Bounds>;
+ return RangeCheck(static_cast<Dst>(SrcLimits::lowest()) >= DstLimits::lowest() ||
+ static_cast<Dst>(value) >= DstLimits::lowest(),
+ static_cast<Dst>(SrcLimits::max()) <= DstLimits::max() ||
+ static_cast<Dst>(value) <= DstLimits::max());
+ }
+};
+
+// Signed to signed narrowing: Both the upper and lower boundaries may be
+// exceeded for standard limits.
+template <typename Dst, typename Src, template <typename> class Bounds>
+struct DstRangeRelationToSrcRangeImpl<Dst,
+ Src,
+ Bounds,
+ INTEGER_REPRESENTATION_SIGNED,
+ INTEGER_REPRESENTATION_SIGNED,
+ NUMERIC_RANGE_NOT_CONTAINED>
+{
+ static constexpr RangeCheck Check(Src value)
+ {
+ using DstLimits = NarrowingRange<Dst, Src, Bounds>;
+ return RangeCheck(value >= DstLimits::lowest(), value <= DstLimits::max());
+ }
+};
+
+// Unsigned to unsigned narrowing: Only the upper bound can be exceeded for
+// standard limits.
+template <typename Dst, typename Src, template <typename> class Bounds>
+struct DstRangeRelationToSrcRangeImpl<Dst,
+ Src,
+ Bounds,
+ INTEGER_REPRESENTATION_UNSIGNED,
+ INTEGER_REPRESENTATION_UNSIGNED,
+ NUMERIC_RANGE_NOT_CONTAINED>
+{
+ static constexpr RangeCheck Check(Src value)
+ {
+ using DstLimits = NarrowingRange<Dst, Src, Bounds>;
+ return RangeCheck(DstLimits::lowest() == Dst(0) || value >= DstLimits::lowest(),
+ value <= DstLimits::max());
+ }
+};
+
+// Unsigned to signed: Only the upper bound can be exceeded for standard limits.
+template <typename Dst, typename Src, template <typename> class Bounds>
+struct DstRangeRelationToSrcRangeImpl<Dst,
+ Src,
+ Bounds,
+ INTEGER_REPRESENTATION_SIGNED,
+ INTEGER_REPRESENTATION_UNSIGNED,
+ NUMERIC_RANGE_NOT_CONTAINED>
+{
+ static constexpr RangeCheck Check(Src value)
+ {
+ using DstLimits = NarrowingRange<Dst, Src, Bounds>;
+ using Promotion = decltype(Src() + Dst());
+ return RangeCheck(
+ DstLimits::lowest() <= Dst(0) ||
+ static_cast<Promotion>(value) >= static_cast<Promotion>(DstLimits::lowest()),
+ static_cast<Promotion>(value) <= static_cast<Promotion>(DstLimits::max()));
+ }
+};
+
+// Signed to unsigned: The upper boundary may be exceeded for a narrower Dst,
+// and any negative value exceeds the lower boundary for standard limits.
+template <typename Dst, typename Src, template <typename> class Bounds>
+struct DstRangeRelationToSrcRangeImpl<Dst,
+ Src,
+ Bounds,
+ INTEGER_REPRESENTATION_UNSIGNED,
+ INTEGER_REPRESENTATION_SIGNED,
+ NUMERIC_RANGE_NOT_CONTAINED>
+{
+ static constexpr RangeCheck Check(Src value)
+ {
+ using SrcLimits = std::numeric_limits<Src>;
+ using DstLimits = NarrowingRange<Dst, Src, Bounds>;
+ using Promotion = decltype(Src() + Dst());
+ bool ge_zero = false;
+ // Converting floating-point to integer will discard fractional part, so
+ // values in (-1.0, -0.0) will truncate to 0 and fit in Dst.
+ if (std::is_floating_point<Src>::value)
+ {
+ ge_zero = value > Src(-1);
+ }
+ else
+ {
+ ge_zero = value >= Src(0);
+ }
+ return RangeCheck(
+ ge_zero && (DstLimits::lowest() == 0 || static_cast<Dst>(value) >= DstLimits::lowest()),
+ static_cast<Promotion>(SrcLimits::max()) <= static_cast<Promotion>(DstLimits::max()) ||
+ static_cast<Promotion>(value) <= static_cast<Promotion>(DstLimits::max()));
+ }
+};
+
+// Simple wrapper for statically checking if a type's range is contained.
+template <typename Dst, typename Src>
+struct IsTypeInRangeForNumericType
+{
+ static const bool value =
+ StaticDstRangeRelationToSrcRange<Dst, Src>::value == NUMERIC_RANGE_CONTAINED;
+};
+
+template <typename Dst, template <typename> class Bounds = std::numeric_limits, typename Src>
+constexpr RangeCheck DstRangeRelationToSrcRange(Src value)
+{
+ static_assert(std::is_arithmetic<Src>::value, "Argument must be numeric.");
+ static_assert(std::is_arithmetic<Dst>::value, "Result must be numeric.");
+ static_assert(Bounds<Dst>::lowest() < Bounds<Dst>::max(), "");
+ return DstRangeRelationToSrcRangeImpl<Dst, Src, Bounds>::Check(value);
+}
+
+// Integer promotion templates used by the portable checked integer arithmetic.
+template <size_t Size, bool IsSigned>
+struct IntegerForDigitsAndSign;
+
+#define INTEGER_FOR_DIGITS_AND_SIGN(I) \
+ template <> \
+ struct IntegerForDigitsAndSign<IntegerBitsPlusSign<I>::value, std::is_signed<I>::value> \
+ { \
+ using type = I; \
+ }
+
+INTEGER_FOR_DIGITS_AND_SIGN(int8_t);
+INTEGER_FOR_DIGITS_AND_SIGN(uint8_t);
+INTEGER_FOR_DIGITS_AND_SIGN(int16_t);
+INTEGER_FOR_DIGITS_AND_SIGN(uint16_t);
+INTEGER_FOR_DIGITS_AND_SIGN(int32_t);
+INTEGER_FOR_DIGITS_AND_SIGN(uint32_t);
+INTEGER_FOR_DIGITS_AND_SIGN(int64_t);
+INTEGER_FOR_DIGITS_AND_SIGN(uint64_t);
+#undef INTEGER_FOR_DIGITS_AND_SIGN
+
+// WARNING: We have no IntegerForSizeAndSign<16, *>. If we ever add one to
+// support 128-bit math, then the ArithmeticPromotion template below will need
+// to be updated (or more likely replaced with a decltype expression).
+static_assert(IntegerBitsPlusSign<intmax_t>::value == 64,
+ "Max integer size not supported for this toolchain.");
+
+template <typename Integer, bool IsSigned = std::is_signed<Integer>::value>
+struct TwiceWiderInteger
+{
+ using type =
+ typename IntegerForDigitsAndSign<IntegerBitsPlusSign<Integer>::value * 2, IsSigned>::type;
+};
+
+enum ArithmeticPromotionCategory
+{
+ LEFT_PROMOTION, // Use the type of the left-hand argument.
+ RIGHT_PROMOTION // Use the type of the right-hand argument.
+};
+
+// Determines the type that can represent the largest positive value.
+template <typename Lhs,
+ typename Rhs,
+ ArithmeticPromotionCategory Promotion =
+ (MaxExponent<Lhs>::value > MaxExponent<Rhs>::value) ? LEFT_PROMOTION
+ : RIGHT_PROMOTION>
+struct MaxExponentPromotion;
+
+template <typename Lhs, typename Rhs>
+struct MaxExponentPromotion<Lhs, Rhs, LEFT_PROMOTION>
+{
+ using type = Lhs;
+};
+
+template <typename Lhs, typename Rhs>
+struct MaxExponentPromotion<Lhs, Rhs, RIGHT_PROMOTION>
+{
+ using type = Rhs;
+};
+
+// Determines the type that can represent the lowest arithmetic value.
+template <typename Lhs,
+ typename Rhs,
+ ArithmeticPromotionCategory Promotion =
+ std::is_signed<Lhs>::value
+ ? (std::is_signed<Rhs>::value
+ ? (MaxExponent<Lhs>::value > MaxExponent<Rhs>::value ? LEFT_PROMOTION
+ : RIGHT_PROMOTION)
+ : LEFT_PROMOTION)
+ : (std::is_signed<Rhs>::value
+ ? RIGHT_PROMOTION
+ : (MaxExponent<Lhs>::value < MaxExponent<Rhs>::value ? LEFT_PROMOTION
+ : RIGHT_PROMOTION))>
+struct LowestValuePromotion;
+
+template <typename Lhs, typename Rhs>
+struct LowestValuePromotion<Lhs, Rhs, LEFT_PROMOTION>
+{
+ using type = Lhs;
+};
+
+template <typename Lhs, typename Rhs>
+struct LowestValuePromotion<Lhs, Rhs, RIGHT_PROMOTION>
+{
+ using type = Rhs;
+};
+
+// Determines the type that is best able to represent an arithmetic result.
+template <typename Lhs,
+ typename Rhs = Lhs,
+ bool is_intmax_type =
+ std::is_integral<typename MaxExponentPromotion<Lhs, Rhs>::type>::value
+ &&IntegerBitsPlusSign<typename MaxExponentPromotion<Lhs, Rhs>::type>::value ==
+ IntegerBitsPlusSign<intmax_t>::value,
+ bool is_max_exponent =
+ StaticDstRangeRelationToSrcRange<typename MaxExponentPromotion<Lhs, Rhs>::type,
+ Lhs>::value ==
+ NUMERIC_RANGE_CONTAINED
+ &&StaticDstRangeRelationToSrcRange<typename MaxExponentPromotion<Lhs, Rhs>::type,
+ Rhs>::value == NUMERIC_RANGE_CONTAINED>
+struct BigEnoughPromotion;
+
+// The side with the max exponent is big enough.
+template <typename Lhs, typename Rhs, bool is_intmax_type>
+struct BigEnoughPromotion<Lhs, Rhs, is_intmax_type, true>
+{
+ using type = typename MaxExponentPromotion<Lhs, Rhs>::type;
+ static const bool is_contained = true;
+};
+
+// We can use a twice wider type to fit.
+template <typename Lhs, typename Rhs>
+struct BigEnoughPromotion<Lhs, Rhs, false, false>
+{
+ using type =
+ typename TwiceWiderInteger<typename MaxExponentPromotion<Lhs, Rhs>::type,
+ std::is_signed<Lhs>::value || std::is_signed<Rhs>::value>::type;
+ static const bool is_contained = true;
+};
+
+// No type is large enough.
+template <typename Lhs, typename Rhs>
+struct BigEnoughPromotion<Lhs, Rhs, true, false>
+{
+ using type = typename MaxExponentPromotion<Lhs, Rhs>::type;
+ static const bool is_contained = false;
+};
+
+// We can statically check if operations on the provided types can wrap, so we
+// can skip the checked operations if they're not needed. So, for an integer we
+// care if the destination type preserves the sign and is twice the width of
+// the source.
+template <typename T, typename Lhs, typename Rhs = Lhs>
+struct IsIntegerArithmeticSafe
+{
+ static const bool value =
+ !std::is_floating_point<T>::value && !std::is_floating_point<Lhs>::value &&
+ !std::is_floating_point<Rhs>::value &&
+ std::is_signed<T>::value >= std::is_signed<Lhs>::value &&
+ IntegerBitsPlusSign<T>::value >= (2 * IntegerBitsPlusSign<Lhs>::value) &&
+ std::is_signed<T>::value >= std::is_signed<Rhs>::value &&
+ IntegerBitsPlusSign<T>::value >= (2 * IntegerBitsPlusSign<Rhs>::value);
+};
+
+// Promotes to a type that can represent any possible result of a binary
+// arithmetic operation with the source types.
+template <typename Lhs,
+ typename Rhs,
+ bool is_promotion_possible = IsIntegerArithmeticSafe<
+ typename std::conditional<std::is_signed<Lhs>::value || std::is_signed<Rhs>::value,
+ intmax_t,
+ uintmax_t>::type,
+ typename MaxExponentPromotion<Lhs, Rhs>::type>::value>
+struct FastIntegerArithmeticPromotion;
+
+template <typename Lhs, typename Rhs>
+struct FastIntegerArithmeticPromotion<Lhs, Rhs, true>
+{
+ using type =
+ typename TwiceWiderInteger<typename MaxExponentPromotion<Lhs, Rhs>::type,
+ std::is_signed<Lhs>::value || std::is_signed<Rhs>::value>::type;
+ static_assert(IsIntegerArithmeticSafe<type, Lhs, Rhs>::value, "");
+ static const bool is_contained = true;
+};
+
+template <typename Lhs, typename Rhs>
+struct FastIntegerArithmeticPromotion<Lhs, Rhs, false>
+{
+ using type = typename BigEnoughPromotion<Lhs, Rhs>::type;
+ static const bool is_contained = false;
+};
+
+// Extracts the underlying type from an enum.
+template <typename T, bool is_enum = std::is_enum<T>::value>
+struct ArithmeticOrUnderlyingEnum;
+
+template <typename T>
+struct ArithmeticOrUnderlyingEnum<T, true>
+{
+ using type = typename std::underlying_type<T>::type;
+ static const bool value = std::is_arithmetic<type>::value;
+};
+
+template <typename T>
+struct ArithmeticOrUnderlyingEnum<T, false>
+{
+ using type = T;
+ static const bool value = std::is_arithmetic<type>::value;
+};
+
+// The following are helper templates used in the CheckedNumeric class.
+template <typename T>
+class CheckedNumeric;
+
+template <typename T>
+class ClampedNumeric;
+
+template <typename T>
+class StrictNumeric;
+
+// Used to treat CheckedNumeric and arithmetic underlying types the same.
+template <typename T>
+struct UnderlyingType
+{
+ using type = typename ArithmeticOrUnderlyingEnum<T>::type;
+ static const bool is_numeric = std::is_arithmetic<type>::value;
+ static const bool is_checked = false;
+ static const bool is_clamped = false;
+ static const bool is_strict = false;
+};
+
+template <typename T>
+struct UnderlyingType<CheckedNumeric<T>>
+{
+ using type = T;
+ static const bool is_numeric = true;
+ static const bool is_checked = true;
+ static const bool is_clamped = false;
+ static const bool is_strict = false;
+};
+
+template <typename T>
+struct UnderlyingType<ClampedNumeric<T>>
+{
+ using type = T;
+ static const bool is_numeric = true;
+ static const bool is_checked = false;
+ static const bool is_clamped = true;
+ static const bool is_strict = false;
+};
+
+template <typename T>
+struct UnderlyingType<StrictNumeric<T>>
+{
+ using type = T;
+ static const bool is_numeric = true;
+ static const bool is_checked = false;
+ static const bool is_clamped = false;
+ static const bool is_strict = true;
+};
+
+template <typename L, typename R>
+struct IsCheckedOp
+{
+ static const bool value = UnderlyingType<L>::is_numeric && UnderlyingType<R>::is_numeric &&
+ (UnderlyingType<L>::is_checked || UnderlyingType<R>::is_checked);
+};
+
+template <typename L, typename R>
+struct IsClampedOp
+{
+ static const bool value = UnderlyingType<L>::is_numeric && UnderlyingType<R>::is_numeric &&
+ (UnderlyingType<L>::is_clamped || UnderlyingType<R>::is_clamped) &&
+ !(UnderlyingType<L>::is_checked || UnderlyingType<R>::is_checked);
+};
+
+template <typename L, typename R>
+struct IsStrictOp
+{
+ static const bool value = UnderlyingType<L>::is_numeric && UnderlyingType<R>::is_numeric &&
+ (UnderlyingType<L>::is_strict || UnderlyingType<R>::is_strict) &&
+ !(UnderlyingType<L>::is_checked || UnderlyingType<R>::is_checked) &&
+ !(UnderlyingType<L>::is_clamped || UnderlyingType<R>::is_clamped);
+};
+
+// as_signed<> returns the supplied integral value (or integral castable
+// Numeric template) cast as a signed integral of equivalent precision.
+// I.e. it's mostly an alias for: static_cast<std::make_signed<T>::type>(t)
+template <typename Src>
+constexpr typename std::make_signed<typename base::internal::UnderlyingType<Src>::type>::type
+as_signed(const Src value)
+{
+ static_assert(std::is_integral<decltype(as_signed(value))>::value,
+ "Argument must be a signed or unsigned integer type.");
+ return static_cast<decltype(as_signed(value))>(value);
+}
+
+// as_unsigned<> returns the supplied integral value (or integral castable
+// Numeric template) cast as an unsigned integral of equivalent precision.
+// I.e. it's mostly an alias for: static_cast<std::make_unsigned<T>::type>(t)
+template <typename Src>
+constexpr typename std::make_unsigned<typename base::internal::UnderlyingType<Src>::type>::type
+as_unsigned(const Src value)
+{
+ static_assert(std::is_integral<decltype(as_unsigned(value))>::value,
+ "Argument must be a signed or unsigned integer type.");
+ return static_cast<decltype(as_unsigned(value))>(value);
+}
+
+template <typename L, typename R>
+constexpr bool IsLessImpl(const L lhs,
+ const R rhs,
+ const RangeCheck l_range,
+ const RangeCheck r_range)
+{
+ return l_range.IsUnderflow() || r_range.IsOverflow() ||
+ (l_range == r_range &&
+ static_cast<decltype(lhs + rhs)>(lhs) < static_cast<decltype(lhs + rhs)>(rhs));
+}
+
+template <typename L, typename R>
+struct IsLess
+{
+ static_assert(std::is_arithmetic<L>::value && std::is_arithmetic<R>::value,
+ "Types must be numeric.");
+ static constexpr bool Test(const L lhs, const R rhs)
+ {
+ return IsLessImpl(lhs, rhs, DstRangeRelationToSrcRange<R>(lhs),
+ DstRangeRelationToSrcRange<L>(rhs));
+ }
+};
+
+template <typename L, typename R>
+constexpr bool IsLessOrEqualImpl(const L lhs,
+ const R rhs,
+ const RangeCheck l_range,
+ const RangeCheck r_range)
+{
+ return l_range.IsUnderflow() || r_range.IsOverflow() ||
+ (l_range == r_range &&
+ static_cast<decltype(lhs + rhs)>(lhs) <= static_cast<decltype(lhs + rhs)>(rhs));
+}
+
+template <typename L, typename R>
+struct IsLessOrEqual
+{
+ static_assert(std::is_arithmetic<L>::value && std::is_arithmetic<R>::value,
+ "Types must be numeric.");
+ static constexpr bool Test(const L lhs, const R rhs)
+ {
+ return IsLessOrEqualImpl(lhs, rhs, DstRangeRelationToSrcRange<R>(lhs),
+ DstRangeRelationToSrcRange<L>(rhs));
+ }
+};
+
+template <typename L, typename R>
+constexpr bool IsGreaterImpl(const L lhs,
+ const R rhs,
+ const RangeCheck l_range,
+ const RangeCheck r_range)
+{
+ return l_range.IsOverflow() || r_range.IsUnderflow() ||
+ (l_range == r_range &&
+ static_cast<decltype(lhs + rhs)>(lhs) > static_cast<decltype(lhs + rhs)>(rhs));
+}
+
+template <typename L, typename R>
+struct IsGreater
+{
+ static_assert(std::is_arithmetic<L>::value && std::is_arithmetic<R>::value,
+ "Types must be numeric.");
+ static constexpr bool Test(const L lhs, const R rhs)
+ {
+ return IsGreaterImpl(lhs, rhs, DstRangeRelationToSrcRange<R>(lhs),
+ DstRangeRelationToSrcRange<L>(rhs));
+ }
+};
+
+template <typename L, typename R>
+constexpr bool IsGreaterOrEqualImpl(const L lhs,
+ const R rhs,
+ const RangeCheck l_range,
+ const RangeCheck r_range)
+{
+ return l_range.IsOverflow() || r_range.IsUnderflow() ||
+ (l_range == r_range &&
+ static_cast<decltype(lhs + rhs)>(lhs) >= static_cast<decltype(lhs + rhs)>(rhs));
+}
+
+template <typename L, typename R>
+struct IsGreaterOrEqual
+{
+ static_assert(std::is_arithmetic<L>::value && std::is_arithmetic<R>::value,
+ "Types must be numeric.");
+ static constexpr bool Test(const L lhs, const R rhs)
+ {
+ return IsGreaterOrEqualImpl(lhs, rhs, DstRangeRelationToSrcRange<R>(lhs),
+ DstRangeRelationToSrcRange<L>(rhs));
+ }
+};
+
+template <typename L, typename R>
+struct IsEqual
+{
+ static_assert(std::is_arithmetic<L>::value && std::is_arithmetic<R>::value,
+ "Types must be numeric.");
+ static constexpr bool Test(const L lhs, const R rhs)
+ {
+ return DstRangeRelationToSrcRange<R>(lhs) == DstRangeRelationToSrcRange<L>(rhs) &&
+ static_cast<decltype(lhs + rhs)>(lhs) == static_cast<decltype(lhs + rhs)>(rhs);
+ }
+};
+
+template <typename L, typename R>
+struct IsNotEqual
+{
+ static_assert(std::is_arithmetic<L>::value && std::is_arithmetic<R>::value,
+ "Types must be numeric.");
+ static constexpr bool Test(const L lhs, const R rhs)
+ {
+ return DstRangeRelationToSrcRange<R>(lhs) != DstRangeRelationToSrcRange<L>(rhs) ||
+ static_cast<decltype(lhs + rhs)>(lhs) != static_cast<decltype(lhs + rhs)>(rhs);
+ }
+};
+
+// These perform the actual math operations on the CheckedNumerics.
+// Binary arithmetic operations.
+template <template <typename, typename> class C, typename L, typename R>
+constexpr bool SafeCompare(const L lhs, const R rhs)
+{
+ static_assert(std::is_arithmetic<L>::value && std::is_arithmetic<R>::value,
+ "Types must be numeric.");
+ using Promotion = BigEnoughPromotion<L, R>;
+ using BigType = typename Promotion::type;
+ return Promotion::is_contained
+ // Force to a larger type for speed if both are contained.
+ ? C<BigType, BigType>::Test(static_cast<BigType>(static_cast<L>(lhs)),
+ static_cast<BigType>(static_cast<R>(rhs)))
+ // Let the template functions figure it out for mixed types.
+ : C<L, R>::Test(lhs, rhs);
+}
+
+template <typename Dst, typename Src>
+constexpr bool IsMaxInRangeForNumericType()
+{
+ return IsGreaterOrEqual<Dst, Src>::Test(std::numeric_limits<Dst>::max(),
+ std::numeric_limits<Src>::max());
+}
+
+template <typename Dst, typename Src>
+constexpr bool IsMinInRangeForNumericType()
+{
+ return IsLessOrEqual<Dst, Src>::Test(std::numeric_limits<Dst>::lowest(),
+ std::numeric_limits<Src>::lowest());
+}
+
+template <typename Dst, typename Src>
+constexpr Dst CommonMax()
+{
+ return !IsMaxInRangeForNumericType<Dst, Src>() ? Dst(std::numeric_limits<Dst>::max())
+ : Dst(std::numeric_limits<Src>::max());
+}
+
+template <typename Dst, typename Src>
+constexpr Dst CommonMin()
+{
+ return !IsMinInRangeForNumericType<Dst, Src>() ? Dst(std::numeric_limits<Dst>::lowest())
+ : Dst(std::numeric_limits<Src>::lowest());
+}
+
+// This is a wrapper to generate return the max or min for a supplied type.
+// If the argument is false, the returned value is the maximum. If true the
+// returned value is the minimum.
+template <typename Dst, typename Src = Dst>
+constexpr Dst CommonMaxOrMin(bool is_min)
+{
+ return is_min ? CommonMin<Dst, Src>() : CommonMax<Dst, Src>();
+}
+
+} // namespace internal
+} // namespace base
+} // namespace angle
+
+#endif // BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_
diff --git a/gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/safe_math.h b/gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/safe_math.h
new file mode 100644
index 0000000000..a708cfddc2
--- /dev/null
+++ b/gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/safe_math.h
@@ -0,0 +1,12 @@
+// Copyright 2017 The Chromium 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 BASE_NUMERICS_SAFE_MATH_H_
+#define BASE_NUMERICS_SAFE_MATH_H_
+
+#include "anglebase/numerics/checked_math.h"
+#include "anglebase/numerics/clamped_math.h"
+#include "anglebase/numerics/safe_conversions.h"
+
+#endif // BASE_NUMERICS_SAFE_MATH_H_
diff --git a/gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/safe_math_arm_impl.h b/gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/safe_math_arm_impl.h
new file mode 100644
index 0000000000..3efdf2596d
--- /dev/null
+++ b/gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/safe_math_arm_impl.h
@@ -0,0 +1,131 @@
+// Copyright 2017 The Chromium 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 BASE_NUMERICS_SAFE_MATH_ARM_IMPL_H_
+#define BASE_NUMERICS_SAFE_MATH_ARM_IMPL_H_
+
+#include <cassert>
+#include <type_traits>
+
+#include "anglebase/numerics/safe_conversions.h"
+
+namespace angle
+{
+namespace base
+{
+namespace internal
+{
+
+template <typename T, typename U>
+struct CheckedMulFastAsmOp
+{
+ static const bool is_supported = FastIntegerArithmeticPromotion<T, U>::is_contained;
+
+ // The following is much more efficient than the Clang and GCC builtins for
+ // performing overflow-checked multiplication when a twice wider type is
+ // available. The below compiles down to 2-3 instructions, depending on the
+ // width of the types in use.
+ // As an example, an int32_t multiply compiles to:
+ // smull r0, r1, r0, r1
+ // cmp r1, r1, asr #31
+ // And an int16_t multiply compiles to:
+ // smulbb r1, r1, r0
+ // asr r2, r1, #16
+ // cmp r2, r1, asr #15
+ template <typename V>
+ __attribute__((always_inline)) static bool Do(T x, U y, V *result)
+ {
+ using Promotion = typename FastIntegerArithmeticPromotion<T, U>::type;
+ Promotion presult;
+
+ presult = static_cast<Promotion>(x) * static_cast<Promotion>(y);
+ if (!IsValueInRangeForNumericType<V>(presult))
+ return false;
+ *result = static_cast<V>(presult);
+ return true;
+ }
+};
+
+template <typename T, typename U>
+struct ClampedAddFastAsmOp
+{
+ static const bool is_supported =
+ BigEnoughPromotion<T, U>::is_contained &&
+ IsTypeInRangeForNumericType<int32_t, typename BigEnoughPromotion<T, U>::type>::value;
+
+ template <typename V>
+ __attribute__((always_inline)) static V Do(T x, U y)
+ {
+ // This will get promoted to an int, so let the compiler do whatever is
+ // clever and rely on the saturated cast to bounds check.
+ if (IsIntegerArithmeticSafe<int, T, U>::value)
+ return saturated_cast<V>(x + y);
+
+ int32_t result;
+ int32_t x_i32 = checked_cast<int32_t>(x);
+ int32_t y_i32 = checked_cast<int32_t>(y);
+
+ asm("qadd %[result], %[first], %[second]"
+ : [result] "=r"(result)
+ : [first] "r"(x_i32), [second] "r"(y_i32));
+ return saturated_cast<V>(result);
+ }
+};
+
+template <typename T, typename U>
+struct ClampedSubFastAsmOp
+{
+ static const bool is_supported =
+ BigEnoughPromotion<T, U>::is_contained &&
+ IsTypeInRangeForNumericType<int32_t, typename BigEnoughPromotion<T, U>::type>::value;
+
+ template <typename V>
+ __attribute__((always_inline)) static V Do(T x, U y)
+ {
+ // This will get promoted to an int, so let the compiler do whatever is
+ // clever and rely on the saturated cast to bounds check.
+ if (IsIntegerArithmeticSafe<int, T, U>::value)
+ return saturated_cast<V>(x - y);
+
+ int32_t result;
+ int32_t x_i32 = checked_cast<int32_t>(x);
+ int32_t y_i32 = checked_cast<int32_t>(y);
+
+ asm("qsub %[result], %[first], %[second]"
+ : [result] "=r"(result)
+ : [first] "r"(x_i32), [second] "r"(y_i32));
+ return saturated_cast<V>(result);
+ }
+};
+
+template <typename T, typename U>
+struct ClampedMulFastAsmOp
+{
+ static const bool is_supported = CheckedMulFastAsmOp<T, U>::is_supported;
+
+ template <typename V>
+ __attribute__((always_inline)) static V Do(T x, U y)
+ {
+ // Use the CheckedMulFastAsmOp for full-width 32-bit values, because
+ // it's fewer instructions than promoting and then saturating.
+ if (!IsIntegerArithmeticSafe<int32_t, T, U>::value &&
+ !IsIntegerArithmeticSafe<uint32_t, T, U>::value)
+ {
+ V result;
+ return CheckedMulFastAsmOp<T, U>::Do(x, y, &result)
+ ? result
+ : CommonMaxOrMin<V>(IsValueNegative(x) ^ IsValueNegative(y));
+ }
+
+ assert((FastIntegerArithmeticPromotion<T, U>::is_contained));
+ using Promotion = typename FastIntegerArithmeticPromotion<T, U>::type;
+ return saturated_cast<V>(static_cast<Promotion>(x) * static_cast<Promotion>(y));
+ }
+};
+
+} // namespace internal
+} // namespace base
+} // namespace angle
+
+#endif // BASE_NUMERICS_SAFE_MATH_ARM_IMPL_H_
diff --git a/gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/safe_math_clang_gcc_impl.h b/gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/safe_math_clang_gcc_impl.h
new file mode 100644
index 0000000000..0f6a1e14d6
--- /dev/null
+++ b/gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/safe_math_clang_gcc_impl.h
@@ -0,0 +1,182 @@
+// Copyright 2017 The Chromium 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 BASE_NUMERICS_SAFE_MATH_CLANG_GCC_IMPL_H_
+#define BASE_NUMERICS_SAFE_MATH_CLANG_GCC_IMPL_H_
+
+#include <cassert>
+#include <limits>
+#include <type_traits>
+
+#include "anglebase/numerics/safe_conversions.h"
+
+#if !defined(__native_client__) && (defined(__ARMEL__) || defined(__arch64__))
+# include "anglebase/numerics/safe_math_arm_impl.h"
+# define BASE_HAS_ASSEMBLER_SAFE_MATH (1)
+#else
+# define BASE_HAS_ASSEMBLER_SAFE_MATH (0)
+#endif
+
+namespace angle
+{
+namespace base
+{
+namespace internal
+{
+
+// These are the non-functioning boilerplate implementations of the optimized
+// safe math routines.
+#if !BASE_HAS_ASSEMBLER_SAFE_MATH
+template <typename T, typename U>
+struct CheckedMulFastAsmOp
+{
+ static const bool is_supported = false;
+ template <typename V>
+ static constexpr bool Do(T, U, V *)
+ {
+ // Force a compile failure if instantiated.
+ return CheckOnFailure::template HandleFailure<bool>();
+ }
+};
+
+template <typename T, typename U>
+struct ClampedAddFastAsmOp
+{
+ static const bool is_supported = false;
+ template <typename V>
+ static constexpr V Do(T, U)
+ {
+ // Force a compile failure if instantiated.
+ return CheckOnFailure::template HandleFailure<V>();
+ }
+};
+
+template <typename T, typename U>
+struct ClampedSubFastAsmOp
+{
+ static const bool is_supported = false;
+ template <typename V>
+ static constexpr V Do(T, U)
+ {
+ // Force a compile failure if instantiated.
+ return CheckOnFailure::template HandleFailure<V>();
+ }
+};
+
+template <typename T, typename U>
+struct ClampedMulFastAsmOp
+{
+ static const bool is_supported = false;
+ template <typename V>
+ static constexpr V Do(T, U)
+ {
+ // Force a compile failure if instantiated.
+ return CheckOnFailure::template HandleFailure<V>();
+ }
+};
+#endif // BASE_HAS_ASSEMBLER_SAFE_MATH
+#undef BASE_HAS_ASSEMBLER_SAFE_MATH
+
+template <typename T, typename U>
+struct CheckedAddFastOp
+{
+ static const bool is_supported = true;
+ template <typename V>
+ __attribute__((always_inline)) static constexpr bool Do(T x, U y, V *result)
+ {
+ return !__builtin_add_overflow(x, y, result);
+ }
+};
+
+template <typename T, typename U>
+struct CheckedSubFastOp
+{
+ static const bool is_supported = true;
+ template <typename V>
+ __attribute__((always_inline)) static constexpr bool Do(T x, U y, V *result)
+ {
+ return !__builtin_sub_overflow(x, y, result);
+ }
+};
+
+template <typename T, typename U>
+struct CheckedMulFastOp
+{
+#if defined(__clang__)
+ // TODO(jschuh): Get the Clang runtime library issues sorted out so we can
+ // support full-width, mixed-sign multiply builtins.
+ // https://crbug.com/613003
+ // We can support intptr_t, uintptr_t, or a smaller common type.
+ static const bool is_supported = (IsTypeInRangeForNumericType<intptr_t, T>::value &&
+ IsTypeInRangeForNumericType<intptr_t, U>::value) ||
+ (IsTypeInRangeForNumericType<uintptr_t, T>::value &&
+ IsTypeInRangeForNumericType<uintptr_t, U>::value);
+#else
+ static const bool is_supported = true;
+#endif
+ template <typename V>
+ __attribute__((always_inline)) static constexpr bool Do(T x, U y, V *result)
+ {
+ return CheckedMulFastAsmOp<T, U>::is_supported ? CheckedMulFastAsmOp<T, U>::Do(x, y, result)
+ : !__builtin_mul_overflow(x, y, result);
+ }
+};
+
+template <typename T, typename U>
+struct ClampedAddFastOp
+{
+ static const bool is_supported = ClampedAddFastAsmOp<T, U>::is_supported;
+ template <typename V>
+ __attribute__((always_inline)) static V Do(T x, U y)
+ {
+ return ClampedAddFastAsmOp<T, U>::template Do<V>(x, y);
+ }
+};
+
+template <typename T, typename U>
+struct ClampedSubFastOp
+{
+ static const bool is_supported = ClampedSubFastAsmOp<T, U>::is_supported;
+ template <typename V>
+ __attribute__((always_inline)) static V Do(T x, U y)
+ {
+ return ClampedSubFastAsmOp<T, U>::template Do<V>(x, y);
+ }
+};
+
+template <typename T, typename U>
+struct ClampedMulFastOp
+{
+ static const bool is_supported = ClampedMulFastAsmOp<T, U>::is_supported;
+ template <typename V>
+ __attribute__((always_inline)) static V Do(T x, U y)
+ {
+ return ClampedMulFastAsmOp<T, U>::template Do<V>(x, y);
+ }
+};
+
+template <typename T>
+struct ClampedNegFastOp
+{
+ static const bool is_supported = std::is_signed<T>::value;
+ __attribute__((always_inline)) static T Do(T value)
+ {
+ // Use this when there is no assembler path available.
+ if (!ClampedSubFastAsmOp<T, T>::is_supported)
+ {
+ T result;
+ return !__builtin_sub_overflow(T(0), value, &result) ? result
+ : std::numeric_limits<T>::max();
+ }
+
+ // Fallback to the normal subtraction path.
+ return ClampedSubFastOp<T, T>::template Do<T>(T(0), value);
+ }
+};
+
+} // namespace internal
+} // namespace base
+} // namespace angle
+
+#endif // BASE_NUMERICS_SAFE_MATH_CLANG_GCC_IMPL_H_
diff --git a/gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/safe_math_shared_impl.h b/gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/safe_math_shared_impl.h
new file mode 100644
index 0000000000..6f46f12e5f
--- /dev/null
+++ b/gfx/angle/checkout/src/common/third_party/base/anglebase/numerics/safe_math_shared_impl.h
@@ -0,0 +1,227 @@
+// Copyright 2017 The Chromium 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 BASE_NUMERICS_SAFE_MATH_SHARED_IMPL_H_
+#define BASE_NUMERICS_SAFE_MATH_SHARED_IMPL_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <cassert>
+#include <climits>
+#include <cmath>
+#include <cstdlib>
+#include <limits>
+#include <type_traits>
+
+#include "anglebase/numerics/safe_conversions.h"
+
+#if defined(OS_ASMJS)
+// Optimized safe math instructions are incompatible with asmjs.
+# define BASE_HAS_OPTIMIZED_SAFE_MATH (0)
+// Where available use builtin math overflow support on Clang and GCC.
+#elif !defined(__native_client__) && \
+ ((defined(__clang__) && \
+ ((__clang_major__ > 3) || (__clang_major__ == 3 && __clang_minor__ >= 4))) || \
+ (defined(__GNUC__) && __GNUC__ >= 5))
+# include "anglebase/numerics/safe_math_clang_gcc_impl.h"
+# define BASE_HAS_OPTIMIZED_SAFE_MATH (1)
+#else
+# define BASE_HAS_OPTIMIZED_SAFE_MATH (0)
+#endif
+
+namespace angle
+{
+namespace base
+{
+namespace internal
+{
+
+// These are the non-functioning boilerplate implementations of the optimized
+// safe math routines.
+#if !BASE_HAS_OPTIMIZED_SAFE_MATH
+template <typename T, typename U>
+struct CheckedAddFastOp
+{
+ static const bool is_supported = false;
+ template <typename V>
+ static constexpr bool Do(T, U, V *)
+ {
+ // Force a compile failure if instantiated.
+ return CheckOnFailure::template HandleFailure<bool>();
+ }
+};
+
+template <typename T, typename U>
+struct CheckedSubFastOp
+{
+ static const bool is_supported = false;
+ template <typename V>
+ static constexpr bool Do(T, U, V *)
+ {
+ // Force a compile failure if instantiated.
+ return CheckOnFailure::template HandleFailure<bool>();
+ }
+};
+
+template <typename T, typename U>
+struct CheckedMulFastOp
+{
+ static const bool is_supported = false;
+ template <typename V>
+ static constexpr bool Do(T, U, V *)
+ {
+ // Force a compile failure if instantiated.
+ return CheckOnFailure::template HandleFailure<bool>();
+ }
+};
+
+template <typename T, typename U>
+struct ClampedAddFastOp
+{
+ static const bool is_supported = false;
+ template <typename V>
+ static constexpr V Do(T, U)
+ {
+ // Force a compile failure if instantiated.
+ return CheckOnFailure::template HandleFailure<V>();
+ }
+};
+
+template <typename T, typename U>
+struct ClampedSubFastOp
+{
+ static const bool is_supported = false;
+ template <typename V>
+ static constexpr V Do(T, U)
+ {
+ // Force a compile failure if instantiated.
+ return CheckOnFailure::template HandleFailure<V>();
+ }
+};
+
+template <typename T, typename U>
+struct ClampedMulFastOp
+{
+ static const bool is_supported = false;
+ template <typename V>
+ static constexpr V Do(T, U)
+ {
+ // Force a compile failure if instantiated.
+ return CheckOnFailure::template HandleFailure<V>();
+ }
+};
+
+template <typename T>
+struct ClampedNegFastOp
+{
+ static const bool is_supported = false;
+ static constexpr T Do(T)
+ {
+ // Force a compile failure if instantiated.
+ return CheckOnFailure::template HandleFailure<T>();
+ }
+};
+#endif // BASE_HAS_OPTIMIZED_SAFE_MATH
+#undef BASE_HAS_OPTIMIZED_SAFE_MATH
+
+// This is used for UnsignedAbs, where we need to support floating-point
+// template instantiations even though we don't actually support the operations.
+// However, there is no corresponding implementation of e.g. SafeUnsignedAbs,
+// so the float versions will not compile.
+template <typename Numeric,
+ bool IsInteger = std::is_integral<Numeric>::value,
+ bool IsFloat = std::is_floating_point<Numeric>::value>
+struct UnsignedOrFloatForSize;
+
+template <typename Numeric>
+struct UnsignedOrFloatForSize<Numeric, true, false>
+{
+ using type = typename std::make_unsigned<Numeric>::type;
+};
+
+template <typename Numeric>
+struct UnsignedOrFloatForSize<Numeric, false, true>
+{
+ using type = Numeric;
+};
+
+// Wrap the unary operations to allow SFINAE when instantiating integrals versus
+// floating points. These don't perform any overflow checking. Rather, they
+// exhibit well-defined overflow semantics and rely on the caller to detect
+// if an overflow occured.
+
+template <typename T, typename std::enable_if<std::is_integral<T>::value>::type * = nullptr>
+constexpr T NegateWrapper(T value)
+{
+ using UnsignedT = typename std::make_unsigned<T>::type;
+ // This will compile to a NEG on Intel, and is normal negation on ARM.
+ return static_cast<T>(UnsignedT(0) - static_cast<UnsignedT>(value));
+}
+
+template <typename T, typename std::enable_if<std::is_floating_point<T>::value>::type * = nullptr>
+constexpr T NegateWrapper(T value)
+{
+ return -value;
+}
+
+template <typename T, typename std::enable_if<std::is_integral<T>::value>::type * = nullptr>
+constexpr typename std::make_unsigned<T>::type InvertWrapper(T value)
+{
+ return ~value;
+}
+
+template <typename T, typename std::enable_if<std::is_integral<T>::value>::type * = nullptr>
+constexpr T AbsWrapper(T value)
+{
+ return static_cast<T>(SafeUnsignedAbs(value));
+}
+
+template <typename T, typename std::enable_if<std::is_floating_point<T>::value>::type * = nullptr>
+constexpr T AbsWrapper(T value)
+{
+ return value < 0 ? -value : value;
+}
+
+template <template <typename, typename, typename> class M, typename L, typename R>
+struct MathWrapper
+{
+ using math = M<typename UnderlyingType<L>::type, typename UnderlyingType<R>::type, void>;
+ using type = typename math::result_type;
+};
+
+// The following macros are just boilerplate for the standard arithmetic
+// operator overloads and variadic function templates. A macro isn't the nicest
+// solution, but it beats rewriting these over and over again.
+#define BASE_NUMERIC_ARITHMETIC_VARIADIC(CLASS, CL_ABBR, OP_NAME) \
+ template <typename L, typename R, typename... Args> \
+ constexpr auto CL_ABBR##OP_NAME(const L lhs, const R rhs, const Args... args) \
+ { \
+ return CL_ABBR##MathOp<CLASS##OP_NAME##Op, L, R, Args...>(lhs, rhs, args...); \
+ }
+
+#define BASE_NUMERIC_ARITHMETIC_OPERATORS(CLASS, CL_ABBR, OP_NAME, OP, CMP_OP) \
+ /* Binary arithmetic operator for all CLASS##Numeric operations. */ \
+ template <typename L, typename R, \
+ typename std::enable_if<Is##CLASS##Op<L, R>::value>::type * = nullptr> \
+ constexpr CLASS##Numeric<typename MathWrapper<CLASS##OP_NAME##Op, L, R>::type> operator OP( \
+ const L lhs, const R rhs) \
+ { \
+ return decltype(lhs OP rhs)::template MathOp<CLASS##OP_NAME##Op>(lhs, rhs); \
+ } \
+ /* Assignment arithmetic operator implementation from CLASS##Numeric. */ \
+ template <typename L> \
+ template <typename R> \
+ constexpr CLASS##Numeric<L> &CLASS##Numeric<L>::operator CMP_OP(const R rhs) \
+ { \
+ return MathOp<CLASS##OP_NAME##Op>(rhs); \
+ } \
+ /* Variadic arithmetic functions that return CLASS##Numeric. */ \
+ BASE_NUMERIC_ARITHMETIC_VARIADIC(CLASS, CL_ABBR, OP_NAME)
+
+} // namespace internal
+} // namespace base
+} // namespace angle
+
+#endif // BASE_NUMERICS_SAFE_MATH_SHARED_IMPL_H_
diff --git a/gfx/angle/checkout/src/common/third_party/base/anglebase/sha1.cc b/gfx/angle/checkout/src/common/third_party/base/anglebase/sha1.cc
new file mode 100644
index 0000000000..cb88ba06e1
--- /dev/null
+++ b/gfx/angle/checkout/src/common/third_party/base/anglebase/sha1.cc
@@ -0,0 +1,245 @@
+// Copyright (c) 2011 The Chromium 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 "anglebase/sha1.h"
+
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "anglebase/sys_byteorder.h"
+
+namespace angle
+{
+
+namespace base
+{
+
+// Implementation of SHA-1. Only handles data in byte-sized blocks,
+// which simplifies the code a fair bit.
+
+// Identifier names follow notation in FIPS PUB 180-3, where you'll
+// also find a description of the algorithm:
+// http://csrc.nist.gov/publications/fips/fips180-3/fips180-3_final.pdf
+
+// Usage example:
+//
+// SecureHashAlgorithm sha;
+// while(there is data to hash)
+// sha.Update(moredata, size of data);
+// sha.Final();
+// memcpy(somewhere, sha.Digest(), 20);
+//
+// to reuse the instance of sha, call sha.Init();
+
+// TODO(jhawkins): Replace this implementation with a per-platform
+// implementation using each platform's crypto library. See
+// http://crbug.com/47218
+
+class SecureHashAlgorithm
+{
+ public:
+ SecureHashAlgorithm() { Init(); }
+
+ static const int kDigestSizeBytes;
+
+ void Init();
+ void Update(const void *data, size_t nbytes);
+ void Final();
+
+ // 20 bytes of message digest.
+ const unsigned char *Digest() const { return reinterpret_cast<const unsigned char *>(H); }
+
+ private:
+ void Pad();
+ void Process();
+
+ uint32_t A, B, C, D, E;
+
+ uint32_t H[5];
+
+ union {
+ uint32_t W[80];
+ uint8_t M[64];
+ };
+
+ uint32_t cursor;
+ uint64_t l;
+};
+
+static inline uint32_t f(uint32_t t, uint32_t B, uint32_t C, uint32_t D)
+{
+ if (t < 20)
+ {
+ return (B & C) | ((~B) & D);
+ }
+ else if (t < 40)
+ {
+ return B ^ C ^ D;
+ }
+ else if (t < 60)
+ {
+ return (B & C) | (B & D) | (C & D);
+ }
+ else
+ {
+ return B ^ C ^ D;
+ }
+}
+
+static inline uint32_t S(uint32_t n, uint32_t X)
+{
+ return (X << n) | (X >> (32 - n));
+}
+
+static inline uint32_t K(uint32_t t)
+{
+ if (t < 20)
+ {
+ return 0x5a827999;
+ }
+ else if (t < 40)
+ {
+ return 0x6ed9eba1;
+ }
+ else if (t < 60)
+ {
+ return 0x8f1bbcdc;
+ }
+ else
+ {
+ return 0xca62c1d6;
+ }
+}
+
+const int SecureHashAlgorithm::kDigestSizeBytes = 20;
+
+void SecureHashAlgorithm::Init()
+{
+ A = 0;
+ B = 0;
+ C = 0;
+ D = 0;
+ E = 0;
+ cursor = 0;
+ l = 0;
+ H[0] = 0x67452301;
+ H[1] = 0xefcdab89;
+ H[2] = 0x98badcfe;
+ H[3] = 0x10325476;
+ H[4] = 0xc3d2e1f0;
+}
+
+void SecureHashAlgorithm::Final()
+{
+ Pad();
+ Process();
+
+ for (int t = 0; t < 5; ++t)
+ H[t] = ByteSwap(H[t]);
+}
+
+void SecureHashAlgorithm::Update(const void *data, size_t nbytes)
+{
+ const uint8_t *d = reinterpret_cast<const uint8_t *>(data);
+ while (nbytes--)
+ {
+ M[cursor++] = *d++;
+ if (cursor >= 64)
+ Process();
+ l += 8;
+ }
+}
+
+void SecureHashAlgorithm::Pad()
+{
+ M[cursor++] = 0x80;
+
+ if (cursor > 64 - 8)
+ {
+ // pad out to next block
+ while (cursor < 64)
+ M[cursor++] = 0;
+
+ Process();
+ }
+
+ while (cursor < 64 - 8)
+ M[cursor++] = 0;
+
+ M[cursor++] = (l >> 56) & 0xff;
+ M[cursor++] = (l >> 48) & 0xff;
+ M[cursor++] = (l >> 40) & 0xff;
+ M[cursor++] = (l >> 32) & 0xff;
+ M[cursor++] = (l >> 24) & 0xff;
+ M[cursor++] = (l >> 16) & 0xff;
+ M[cursor++] = (l >> 8) & 0xff;
+ M[cursor++] = l & 0xff;
+}
+
+void SecureHashAlgorithm::Process()
+{
+ uint32_t t;
+
+ // Each a...e corresponds to a section in the FIPS 180-3 algorithm.
+
+ // a.
+ //
+ // W and M are in a union, so no need to memcpy.
+ // memcpy(W, M, sizeof(M));
+ for (t = 0; t < 16; ++t)
+ W[t] = ByteSwap(W[t]);
+
+ // b.
+ for (t = 16; t < 80; ++t)
+ W[t] = S(1, W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16]);
+
+ // c.
+ A = H[0];
+ B = H[1];
+ C = H[2];
+ D = H[3];
+ E = H[4];
+
+ // d.
+ for (t = 0; t < 80; ++t)
+ {
+ uint32_t TEMP = S(5, A) + f(t, B, C, D) + E + W[t] + K(t);
+ E = D;
+ D = C;
+ C = S(30, B);
+ B = A;
+ A = TEMP;
+ }
+
+ // e.
+ H[0] += A;
+ H[1] += B;
+ H[2] += C;
+ H[3] += D;
+ H[4] += E;
+
+ cursor = 0;
+}
+
+std::string SHA1HashString(const std::string &str)
+{
+ char hash[SecureHashAlgorithm::kDigestSizeBytes];
+ SHA1HashBytes(reinterpret_cast<const unsigned char *>(str.c_str()), str.length(),
+ reinterpret_cast<unsigned char *>(hash));
+ return std::string(hash, SecureHashAlgorithm::kDigestSizeBytes);
+}
+
+void SHA1HashBytes(const unsigned char *data, size_t len, unsigned char *hash)
+{
+ SecureHashAlgorithm sha;
+ sha.Update(data, len);
+ sha.Final();
+
+ memcpy(hash, sha.Digest(), SecureHashAlgorithm::kDigestSizeBytes);
+}
+
+} // namespace base
+
+} // namespace angle
diff --git a/gfx/angle/checkout/src/common/third_party/base/anglebase/sha1.h b/gfx/angle/checkout/src/common/third_party/base/anglebase/sha1.h
new file mode 100644
index 0000000000..a60908814f
--- /dev/null
+++ b/gfx/angle/checkout/src/common/third_party/base/anglebase/sha1.h
@@ -0,0 +1,36 @@
+// Copyright (c) 2011 The Chromium 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 ANGLEBASE_SHA1_H_
+#define ANGLEBASE_SHA1_H_
+
+#include <stddef.h>
+
+#include <string>
+
+#include "anglebase/base_export.h"
+
+namespace angle
+{
+
+namespace base
+{
+
+// These functions perform SHA-1 operations.
+
+static const size_t kSHA1Length = 20; // Length in bytes of a SHA-1 hash.
+
+// Computes the SHA-1 hash of the input string |str| and returns the full
+// hash.
+ANGLEBASE_EXPORT std::string SHA1HashString(const std::string &str);
+
+// Computes the SHA-1 hash of the |len| bytes in |data| and puts the hash
+// in |hash|. |hash| must be kSHA1Length bytes long.
+ANGLEBASE_EXPORT void SHA1HashBytes(const unsigned char *data, size_t len, unsigned char *hash);
+
+} // namespace base
+
+} // namespace angle
+
+#endif // ANGLEBASE_SHA1_H_
diff --git a/gfx/angle/checkout/src/common/third_party/base/anglebase/sys_byteorder.h b/gfx/angle/checkout/src/common/third_party/base/anglebase/sys_byteorder.h
new file mode 100644
index 0000000000..70d9c275e6
--- /dev/null
+++ b/gfx/angle/checkout/src/common/third_party/base/anglebase/sys_byteorder.h
@@ -0,0 +1,49 @@
+//
+// Copyright 2017 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.
+//
+// sys_byteorder.h: Compatiblity hacks for importing Chromium's base/SHA1.
+
+#ifndef ANGLEBASE_SYS_BYTEORDER_H_
+#define ANGLEBASE_SYS_BYTEORDER_H_
+
+namespace angle
+{
+
+namespace base
+{
+
+// Returns a value with all bytes in |x| swapped, i.e. reverses the endianness.
+inline uint16_t ByteSwap(uint16_t x)
+{
+#if defined(_MSC_VER)
+ return _byteswap_ushort(x);
+#else
+ return __builtin_bswap16(x);
+#endif
+}
+
+inline uint32_t ByteSwap(uint32_t x)
+{
+#if defined(_MSC_VER)
+ return _byteswap_ulong(x);
+#else
+ return __builtin_bswap32(x);
+#endif
+}
+
+inline uint64_t ByteSwap(uint64_t x)
+{
+#if defined(_MSC_VER)
+ return _byteswap_uint64(x);
+#else
+ return __builtin_bswap64(x);
+#endif
+}
+
+} // namespace base
+
+} // namespace angle
+
+#endif // ANGLEBASE_SYS_BYTEORDER_H_
diff --git a/gfx/angle/checkout/src/common/third_party/smhasher/src/PMurHash.cpp b/gfx/angle/checkout/src/common/third_party/smhasher/src/PMurHash.cpp
new file mode 100644
index 0000000000..379e5ce3d5
--- /dev/null
+++ b/gfx/angle/checkout/src/common/third_party/smhasher/src/PMurHash.cpp
@@ -0,0 +1,339 @@
+/*-----------------------------------------------------------------------------
+ * MurmurHash3 was written by Austin Appleby, and is placed in the public
+ * domain.
+ *
+ * This implementation was written by Shane Day, and is also public domain.
+ *
+ * This is a portable ANSI C implementation of MurmurHash3_x86_32 (Murmur3A)
+ * with support for progressive processing.
+ */
+
+/*-----------------------------------------------------------------------------
+
+If you want to understand the MurmurHash algorithm you would be much better
+off reading the original source. Just point your browser at:
+http://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp
+
+
+What this version provides?
+
+1. Progressive data feeding. Useful when the entire payload to be hashed
+does not fit in memory or when the data is streamed through the application.
+Also useful when hashing a number of strings with a common prefix. A partial
+hash of a prefix string can be generated and reused for each suffix string.
+
+2. Portability. Plain old C so that it should compile on any old compiler.
+Both CPU endian and access-alignment neutral, but avoiding inefficient code
+when possible depending on CPU capabilities.
+
+3. Drop in. I personally like nice self contained public domain code, making it
+easy to pilfer without loads of refactoring to work properly in the existing
+application code & makefile structure and mucking around with licence files.
+Just copy PMurHash.h and PMurHash.c and you're ready to go.
+
+
+How does it work?
+
+We can only process entire 32 bit chunks of input, except for the very end
+that may be shorter. So along with the partial hash we need to give back to
+the caller a carry containing up to 3 bytes that we were unable to process.
+This carry also needs to record the number of bytes the carry holds. I use
+the low 2 bits as a count (0..3) and the carry bytes are shifted into the
+high byte in stream order.
+
+To handle endianess I simply use a macro that reads a uint32_t and define
+that macro to be a direct read on little endian machines, a read and swap
+on big endian machines, or a byte-by-byte read if the endianess is unknown.
+
+-----------------------------------------------------------------------------*/
+
+#include "PMurHash.h"
+#include <stdint.h>
+
+/* I used ugly type names in the header to avoid potential conflicts with
+ * application or system typedefs & defines. Since I'm not including any more
+ * headers below here I can rename these so that the code reads like C99 */
+#undef uint32_t
+#define uint32_t MH_UINT32
+#undef uint8_t
+#define uint8_t MH_UINT8
+
+/* MSVC warnings we choose to ignore */
+#if defined(_MSC_VER)
+# pragma warning(disable : 4127) /* conditional expression is constant */
+#endif
+
+/*-----------------------------------------------------------------------------
+ * Endianess, misalignment capabilities and util macros
+ *
+ * The following 3 macros are defined in this section. The other macros defined
+ * are only needed to help derive these 3.
+ *
+ * READ_UINT32(x) Read a little endian unsigned 32-bit int
+ * UNALIGNED_SAFE Defined if READ_UINT32 works on non-word boundaries
+ * ROTL32(x,r) Rotate x left by r bits
+ */
+
+/* Convention is to define __BYTE_ORDER == to one of these values */
+#if !defined(__BIG_ENDIAN)
+# define __BIG_ENDIAN 4321
+#endif
+#if !defined(__LITTLE_ENDIAN)
+# define __LITTLE_ENDIAN 1234
+#endif
+
+/* I386 */
+#if defined(_M_IX86) || defined(__i386__) || defined(__i386) || defined(i386)
+# define __BYTE_ORDER __LITTLE_ENDIAN
+# define UNALIGNED_SAFE
+#endif
+
+/* gcc 'may' define __LITTLE_ENDIAN__ or __BIG_ENDIAN__ to 1 (Note the trailing __),
+ * or even _LITTLE_ENDIAN or _BIG_ENDIAN (Note the single _ prefix) */
+#if !defined(__BYTE_ORDER)
+# if defined(__LITTLE_ENDIAN__) && __LITTLE_ENDIAN__ == 1 || \
+ defined(_LITTLE_ENDIAN) && _LITTLE_ENDIAN == 1
+# define __BYTE_ORDER __LITTLE_ENDIAN
+# elif defined(__BIG_ENDIAN__) && __BIG_ENDIAN__ == 1 || defined(_BIG_ENDIAN) && _BIG_ENDIAN == 1
+# define __BYTE_ORDER __BIG_ENDIAN
+# endif
+#endif
+
+/* gcc (usually) defines xEL/EB macros for ARM and MIPS endianess */
+#if !defined(__BYTE_ORDER)
+# if defined(__ARMEL__) || defined(__MIPSEL__)
+# define __BYTE_ORDER __LITTLE_ENDIAN
+# endif
+# if defined(__ARMEB__) || defined(__MIPSEB__)
+# define __BYTE_ORDER __BIG_ENDIAN
+# endif
+#endif
+
+/* Now find best way we can to READ_UINT32 */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+/* CPU endian matches murmurhash algorithm, so read 32-bit word directly */
+# define READ_UINT32(ptr) (*((uint32_t *)(ptr)))
+#elif __BYTE_ORDER == __BIG_ENDIAN
+/* TODO: Add additional cases below where a compiler provided bswap32 is available */
+# if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
+# define READ_UINT32(ptr) (__builtin_bswap32(*((uint32_t *)(ptr))))
+# else
+/* Without a known fast bswap32 we're just as well off doing this */
+# define READ_UINT32(ptr) (ptr[0] | ptr[1] << 8 | ptr[2] << 16 | ptr[3] << 24)
+# define UNALIGNED_SAFE
+# endif
+#else
+/* Unknown endianess so last resort is to read individual bytes */
+# define READ_UINT32(ptr) (ptr[0] | ptr[1] << 8 | ptr[2] << 16 | ptr[3] << 24)
+
+/* Since we're not doing word-reads we can skip the messing about with realignment */
+# define UNALIGNED_SAFE
+#endif
+
+/* Find best way to ROTL32 */
+#if defined(_MSC_VER)
+# include <stdlib.h> /* Microsoft put _rotl declaration in here */
+# define ROTL32(x, r) _rotl(x, r)
+#else
+/* gcc recognises this code and generates a rotate instruction for CPUs with one */
+# define ROTL32(x, r) (((uint32_t)x << r) | ((uint32_t)x >> (32 - r)))
+#endif
+
+/*-----------------------------------------------------------------------------
+ * Core murmurhash algorithm macros */
+
+#define C1 (0xcc9e2d51)
+#define C2 (0x1b873593)
+
+/* This is the main processing body of the algorithm. It operates
+ * on each full 32-bits of input. */
+#define DOBLOCK(h1, k1) \
+ do \
+ { \
+ k1 *= C1; \
+ k1 = ROTL32(k1, 15); \
+ k1 *= C2; \
+ \
+ h1 ^= k1; \
+ h1 = ROTL32(h1, 13); \
+ h1 = h1 * 5 + 0xe6546b64; \
+ } while (0)
+
+/* Append unaligned bytes to carry, forcing hash churn if we have 4 bytes */
+/* cnt=bytes to process, h1=name of h1 var, c=carry, n=bytes in c, ptr/len=payload */
+#define DOBYTES(cnt, h1, c, n, ptr, len) \
+ do \
+ { \
+ int _i = cnt; \
+ while (_i--) \
+ { \
+ c = c >> 8 | *ptr++ << 24; \
+ n++; \
+ len--; \
+ if (n == 4) \
+ { \
+ DOBLOCK(h1, c); \
+ n = 0; \
+ } \
+ } \
+ } while (0)
+
+/*---------------------------------------------------------------------------*/
+
+namespace angle
+{
+/* Main hashing function. Initialise carry to 0 and h1 to 0 or an initial seed
+ * if wanted. Both ph1 and pcarry are required arguments. */
+void PMurHash32_Process(uint32_t *ph1, uint32_t *pcarry, const void *key, int len)
+{
+ uint32_t h1 = *ph1;
+ uint32_t c = *pcarry;
+
+ const uint8_t *ptr = (uint8_t *)key;
+ const uint8_t *end;
+
+ /* Extract carry count from low 2 bits of c value */
+ int n = c & 3;
+
+#if defined(UNALIGNED_SAFE)
+ /* This CPU handles unaligned word access */
+
+ /* Consume any carry bytes */
+ int i = (4 - n) & 3;
+ if (i && i <= len)
+ {
+ DOBYTES(i, h1, c, n, ptr, len);
+ }
+
+ /* Process 32-bit chunks */
+ end = ptr + len / 4 * 4;
+ for (; ptr < end; ptr += 4)
+ {
+ uint32_t k1 = READ_UINT32(ptr);
+ DOBLOCK(h1, k1);
+ }
+
+#else /*UNALIGNED_SAFE*/
+ /* This CPU does not handle unaligned word access */
+
+ /* Consume enough so that the next data byte is word aligned */
+ int i = -(intptr_t)ptr & 3;
+ if (i && i <= len)
+ {
+ DOBYTES(i, h1, c, n, ptr, len);
+ }
+
+ /* We're now aligned. Process in aligned blocks. Specialise for each possible carry count */
+ end = ptr + len / 4 * 4;
+ switch (n)
+ { /* how many bytes in c */
+ case 0: /* c=[----] w=[3210] b=[3210]=w c'=[----] */
+ for (; ptr < end; ptr += 4)
+ {
+ uint32_t k1 = READ_UINT32(ptr);
+ DOBLOCK(h1, k1);
+ }
+ break;
+ case 1: /* c=[0---] w=[4321] b=[3210]=c>>24|w<<8 c'=[4---] */
+ for (; ptr < end; ptr += 4)
+ {
+ uint32_t k1 = c >> 24;
+ c = READ_UINT32(ptr);
+ k1 |= c << 8;
+ DOBLOCK(h1, k1);
+ }
+ break;
+ case 2: /* c=[10--] w=[5432] b=[3210]=c>>16|w<<16 c'=[54--] */
+ for (; ptr < end; ptr += 4)
+ {
+ uint32_t k1 = c >> 16;
+ c = READ_UINT32(ptr);
+ k1 |= c << 16;
+ DOBLOCK(h1, k1);
+ }
+ break;
+ case 3: /* c=[210-] w=[6543] b=[3210]=c>>8|w<<24 c'=[654-] */
+ for (; ptr < end; ptr += 4)
+ {
+ uint32_t k1 = c >> 8;
+ c = READ_UINT32(ptr);
+ k1 |= c << 24;
+ DOBLOCK(h1, k1);
+ }
+ }
+#endif /*UNALIGNED_SAFE*/
+
+ /* Advance over whole 32-bit chunks, possibly leaving 1..3 bytes */
+ len -= len / 4 * 4;
+
+ /* Append any remaining bytes into carry */
+ DOBYTES(len, h1, c, n, ptr, len);
+
+ /* Copy out new running hash and carry */
+ *ph1 = h1;
+ *pcarry = (c & ~0xff) | n;
+}
+
+/*---------------------------------------------------------------------------*/
+
+/* Finalize a hash. To match the original Murmur3A the total_length must be provided */
+uint32_t PMurHash32_Result(uint32_t h, uint32_t carry, uint32_t total_length)
+{
+ uint32_t k1;
+ int n = carry & 3;
+ if (n)
+ {
+ k1 = carry >> (4 - n) * 8;
+ k1 *= C1;
+ k1 = ROTL32(k1, 15);
+ k1 *= C2;
+ h ^= k1;
+ }
+ h ^= total_length;
+
+ /* fmix */
+ h ^= h >> 16;
+ h *= 0x85ebca6b;
+ h ^= h >> 13;
+ h *= 0xc2b2ae35;
+ h ^= h >> 16;
+
+ return h;
+}
+
+/*---------------------------------------------------------------------------*/
+
+/* Murmur3A compatable all-at-once */
+uint32_t PMurHash32(uint32_t seed, const void *key, int len)
+{
+ uint32_t h1 = seed, carry = 0;
+ PMurHash32_Process(&h1, &carry, key, len);
+ return PMurHash32_Result(h1, carry, len);
+}
+
+/*---------------------------------------------------------------------------*/
+
+/* Provide an API suitable for smhasher */
+void PMurHash32_test(const void *key, int len, uint32_t seed, void *out)
+{
+ uint32_t h1 = seed, carry = 0;
+ const uint8_t *ptr = (uint8_t *)key;
+ const uint8_t *end = ptr + len;
+
+#if 0 /* Exercise the progressive processing */
+ while(ptr < end) {
+ //const uint8_t *mid = ptr + rand()%(end-ptr)+1;
+ const uint8_t *mid = ptr + (rand()&0xF);
+ mid = mid<end?mid:end;
+ PMurHash32_Process(&h1, &carry, ptr, mid-ptr);
+ ptr = mid;
+ }
+#else
+ PMurHash32_Process(&h1, &carry, ptr, (int)(end - ptr));
+#endif
+ h1 = PMurHash32_Result(h1, carry, len);
+ *(uint32_t *)out = h1;
+}
+} // namespace angle
+
+/*---------------------------------------------------------------------------*/
diff --git a/gfx/angle/checkout/src/common/third_party/smhasher/src/PMurHash.h b/gfx/angle/checkout/src/common/third_party/smhasher/src/PMurHash.h
new file mode 100644
index 0000000000..0a3c96fa14
--- /dev/null
+++ b/gfx/angle/checkout/src/common/third_party/smhasher/src/PMurHash.h
@@ -0,0 +1,57 @@
+/*-----------------------------------------------------------------------------
+ * MurmurHash3 was written by Austin Appleby, and is placed in the public
+ * domain.
+ *
+ * This implementation was written by Shane Day, and is also public domain.
+ *
+ * This is a portable ANSI C implementation of MurmurHash3_x86_32 (Murmur3A)
+ * with support for progressive processing.
+ */
+
+/* ------------------------------------------------------------------------- */
+/* Determine what native type to use for uint32_t */
+
+/* We can't use the name 'uint32_t' here because it will conflict with
+ * any version provided by the system headers or application. */
+
+/* First look for special cases */
+#if defined(_MSC_VER)
+# define MH_UINT32 unsigned long
+#endif
+
+/* If the compiler says it's C99 then take its word for it */
+#if !defined(MH_UINT32) && (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L)
+# include <stdint.h>
+# define MH_UINT32 uint32_t
+#endif
+
+/* Otherwise try testing against max value macros from limit.h */
+#if !defined(MH_UINT32)
+# include <limits.h>
+# if (USHRT_MAX == 0xffffffffUL)
+# define MH_UINT32 unsigned short
+# elif (UINT_MAX == 0xffffffffUL)
+# define MH_UINT32 unsigned int
+# elif (ULONG_MAX == 0xffffffffUL)
+# define MH_UINT32 unsigned long
+# endif
+#endif
+
+#if !defined(MH_UINT32)
+# error Unable to determine type name for unsigned 32-bit int
+#endif
+
+/* I'm yet to work on a platform where 'unsigned char' is not 8 bits */
+#define MH_UINT8 unsigned char
+
+/* ------------------------------------------------------------------------- */
+/* Prototypes */
+
+namespace angle
+{
+void PMurHash32_Process(MH_UINT32 *ph1, MH_UINT32 *pcarry, const void *key, int len);
+MH_UINT32 PMurHash32_Result(MH_UINT32 h1, MH_UINT32 carry, MH_UINT32 total_length);
+MH_UINT32 PMurHash32(MH_UINT32 seed, const void *key, int len);
+
+void PMurHash32_test(const void *key, int len, MH_UINT32 seed, void *out);
+} // namespace angle
diff --git a/gfx/angle/checkout/src/common/third_party/xxhash/xxhash.c b/gfx/angle/checkout/src/common/third_party/xxhash/xxhash.c
new file mode 100644
index 0000000000..ae9a55116c
--- /dev/null
+++ b/gfx/angle/checkout/src/common/third_party/xxhash/xxhash.c
@@ -0,0 +1,1030 @@
+/*
+* xxHash - Fast Hash algorithm
+* Copyright (C) 2012-2016, Yann Collet
+*
+* BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following disclaimer
+* in the documentation and/or other materials provided with the
+* distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+* You can contact the author at :
+* - xxHash homepage: http://www.xxhash.com
+* - xxHash source repository : https://github.com/Cyan4973/xxHash
+*/
+
+
+/* *************************************
+* Tuning parameters
+***************************************/
+/*!XXH_FORCE_MEMORY_ACCESS :
+ * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable.
+ * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal.
+ * The below switch allow to select different access method for improved performance.
+ * Method 0 (default) : use `memcpy()`. Safe and portable.
+ * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable).
+ * This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`.
+ * Method 2 : direct access. This method doesn't depend on compiler but violate C standard.
+ * It can generate buggy code on targets which do not support unaligned memory accesses.
+ * But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6)
+ * See http://stackoverflow.com/a/32095106/646947 for details.
+ * Prefer these methods in priority order (0 > 1 > 2)
+ */
+#ifndef XXH_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */
+# if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
+ || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \
+ || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) )
+# define XXH_FORCE_MEMORY_ACCESS 2
+# elif (defined(__INTEL_COMPILER) && !defined(_WIN32)) || \
+ (defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
+ || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \
+ || defined(__ARM_ARCH_7S__) ))
+# define XXH_FORCE_MEMORY_ACCESS 1
+# endif
+#endif
+
+/*!XXH_ACCEPT_NULL_INPUT_POINTER :
+ * If input pointer is NULL, xxHash default behavior is to dereference it, triggering a segfault.
+ * When this macro is enabled, xxHash actively checks input for null pointer.
+ * It it is, result for null input pointers is the same as a null-length input.
+ */
+#ifndef XXH_ACCEPT_NULL_INPUT_POINTER /* can be defined externally */
+# define XXH_ACCEPT_NULL_INPUT_POINTER 0
+#endif
+
+/*!XXH_FORCE_NATIVE_FORMAT :
+ * By default, xxHash library provides endian-independent Hash values, based on little-endian convention.
+ * Results are therefore identical for little-endian and big-endian CPU.
+ * This comes at a performance cost for big-endian CPU, since some swapping is required to emulate little-endian format.
+ * Should endian-independence be of no importance for your application, you may set the #define below to 1,
+ * to improve speed for Big-endian CPU.
+ * This option has no impact on Little_Endian CPU.
+ */
+#ifndef XXH_FORCE_NATIVE_FORMAT /* can be defined externally */
+# define XXH_FORCE_NATIVE_FORMAT 0
+#endif
+
+/*!XXH_FORCE_ALIGN_CHECK :
+ * This is a minor performance trick, only useful with lots of very small keys.
+ * It means : check for aligned/unaligned input.
+ * The check costs one initial branch per hash;
+ * set it to 0 when the input is guaranteed to be aligned,
+ * or when alignment doesn't matter for performance.
+ */
+#ifndef XXH_FORCE_ALIGN_CHECK /* can be defined externally */
+# if defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)
+# define XXH_FORCE_ALIGN_CHECK 0
+# else
+# define XXH_FORCE_ALIGN_CHECK 1
+# endif
+#endif
+
+
+/* *************************************
+* Includes & Memory related functions
+***************************************/
+/*! Modify the local functions below should you wish to use some other memory routines
+* for malloc(), free() */
+#include <stdlib.h>
+static void* XXH_malloc(size_t s) { return malloc(s); }
+static void XXH_free (void* p) { free(p); }
+/*! and for memcpy() */
+#include <string.h>
+static void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcpy(dest,src,size); }
+
+#include <assert.h> /* assert */
+
+#define XXH_STATIC_LINKING_ONLY
+#include "xxhash.h"
+
+
+/* *************************************
+* Compiler Specific Options
+***************************************/
+#ifdef _MSC_VER /* Visual Studio */
+# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
+# define FORCE_INLINE static __forceinline
+#else
+# if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
+# ifdef __GNUC__
+# define FORCE_INLINE static inline __attribute__((always_inline))
+# else
+# define FORCE_INLINE static inline
+# endif
+# else
+# define FORCE_INLINE static
+# endif /* __STDC_VERSION__ */
+#endif
+
+
+/* *************************************
+* Basic Types
+***************************************/
+#ifndef MEM_MODULE
+# if !defined (__VMS) \
+ && (defined (__cplusplus) \
+ || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
+# include <stdint.h>
+ typedef uint8_t BYTE;
+ typedef uint16_t U16;
+ typedef uint32_t U32;
+# else
+ typedef unsigned char BYTE;
+ typedef unsigned short U16;
+ typedef unsigned int U32;
+# endif
+#endif
+
+#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2))
+
+/* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */
+static U32 XXH_read32(const void* memPtr) { return *(const U32*) memPtr; }
+
+#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1))
+
+/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */
+/* currently only defined for gcc and icc */
+typedef union { U32 u32; } __attribute__((packed)) unalign;
+static U32 XXH_read32(const void* ptr) { return ((const unalign*)ptr)->u32; }
+
+#else
+
+/* portable and safe solution. Generally efficient.
+ * see : http://stackoverflow.com/a/32095106/646947
+ */
+static U32 XXH_read32(const void* memPtr)
+{
+ U32 val;
+ memcpy(&val, memPtr, sizeof(val));
+ return val;
+}
+
+#endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */
+
+
+/* ****************************************
+* Compiler-specific Functions and Macros
+******************************************/
+#define XXH_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
+
+/* Note : although _rotl exists for minGW (GCC under windows), performance seems poor */
+#if defined(_MSC_VER)
+# define XXH_rotl32(x,r) _rotl(x,r)
+# define XXH_rotl64(x,r) _rotl64(x,r)
+#else
+# define XXH_rotl32(x,r) ((x << r) | (x >> (32 - r)))
+# define XXH_rotl64(x,r) ((x << r) | (x >> (64 - r)))
+#endif
+
+#if defined(_MSC_VER) /* Visual Studio */
+# define XXH_swap32 _byteswap_ulong
+#elif XXH_GCC_VERSION >= 403
+# define XXH_swap32 __builtin_bswap32
+#else
+static U32 XXH_swap32 (U32 x)
+{
+ return ((x << 24) & 0xff000000 ) |
+ ((x << 8) & 0x00ff0000 ) |
+ ((x >> 8) & 0x0000ff00 ) |
+ ((x >> 24) & 0x000000ff );
+}
+#endif
+
+
+/* *************************************
+* Architecture Macros
+***************************************/
+typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess;
+
+/* XXH_CPU_LITTLE_ENDIAN can be defined externally, for example on the compiler command line */
+#ifndef XXH_CPU_LITTLE_ENDIAN
+static int XXH_isLittleEndian(void)
+{
+ const union { U32 u; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */
+ return one.c[0];
+}
+# define XXH_CPU_LITTLE_ENDIAN (XXH_isLittleEndian())
+#endif
+
+
+/* ***************************
+* Memory reads
+*****************************/
+typedef enum { XXH_aligned, XXH_unaligned } XXH_alignment;
+
+FORCE_INLINE U32 XXH_readLE32_align(const void* ptr, XXH_endianess endian, XXH_alignment align)
+{
+ if (align==XXH_unaligned)
+ return endian==XXH_littleEndian ? XXH_read32(ptr) : XXH_swap32(XXH_read32(ptr));
+ else
+ return endian==XXH_littleEndian ? *(const U32*)ptr : XXH_swap32(*(const U32*)ptr);
+}
+
+FORCE_INLINE U32 XXH_readLE32(const void* ptr, XXH_endianess endian)
+{
+ return XXH_readLE32_align(ptr, endian, XXH_unaligned);
+}
+
+static U32 XXH_readBE32(const void* ptr)
+{
+ return XXH_CPU_LITTLE_ENDIAN ? XXH_swap32(XXH_read32(ptr)) : XXH_read32(ptr);
+}
+
+
+/* *************************************
+* Macros
+***************************************/
+#define XXH_STATIC_ASSERT(c) do { enum { XXH_sa = 1/(int)(!!(c)) }; } while(0) /* use after variable declarations */
+XXH_PUBLIC_API unsigned XXH_versionNumber (void) { return XXH_VERSION_NUMBER; }
+
+
+/* *******************************************************************
+* 32-bit hash functions
+*********************************************************************/
+static const U32 PRIME32_1 = 2654435761U; /* 0b10011110001101110111100110110001 */
+static const U32 PRIME32_2 = 2246822519U; /* 0b10000101111010111100101001110111 */
+static const U32 PRIME32_3 = 3266489917U; /* 0b11000010101100101010111000111101 */
+static const U32 PRIME32_4 = 668265263U; /* 0b00100111110101001110101100101111 */
+static const U32 PRIME32_5 = 374761393U; /* 0b00010110010101100110011110110001 */
+
+static U32 XXH32_round(U32 seed, U32 input)
+{
+ seed += input * PRIME32_2;
+ seed = XXH_rotl32(seed, 13);
+ seed *= PRIME32_1;
+ return seed;
+}
+
+/* mix all bits */
+static U32 XXH32_avalanche(U32 h32)
+{
+ h32 ^= h32 >> 15;
+ h32 *= PRIME32_2;
+ h32 ^= h32 >> 13;
+ h32 *= PRIME32_3;
+ h32 ^= h32 >> 16;
+ return(h32);
+}
+
+#define XXH_get32bits(p) XXH_readLE32_align(p, endian, align)
+
+static U32
+XXH32_finalize(U32 h32, const void* ptr, size_t len,
+ XXH_endianess endian, XXH_alignment align)
+
+{
+ const BYTE* p = (const BYTE*)ptr;
+
+#define PROCESS1 \
+ h32 += (*p++) * PRIME32_5; \
+ h32 = XXH_rotl32(h32, 11) * PRIME32_1
+
+#define PROCESS4 \
+ h32 += XXH_get32bits(p) * PRIME32_3; \
+ p+=4; \
+ h32 = XXH_rotl32(h32, 17) * PRIME32_4
+
+ switch(len&15) /* or switch(bEnd - p) */
+ {
+ case 12: PROCESS4;
+ /* fallthrough */
+ case 8: PROCESS4;
+ /* fallthrough */
+ case 4: PROCESS4;
+ return XXH32_avalanche(h32);
+
+ case 13: PROCESS4;
+ /* fallthrough */
+ case 9: PROCESS4;
+ /* fallthrough */
+ case 5: PROCESS4;
+ PROCESS1;
+ return XXH32_avalanche(h32);
+
+ case 14: PROCESS4;
+ /* fallthrough */
+ case 10: PROCESS4;
+ /* fallthrough */
+ case 6: PROCESS4;
+ PROCESS1;
+ PROCESS1;
+ return XXH32_avalanche(h32);
+
+ case 15: PROCESS4;
+ /* fallthrough */
+ case 11: PROCESS4;
+ /* fallthrough */
+ case 7: PROCESS4;
+ /* fallthrough */
+ case 3: PROCESS1;
+ /* fallthrough */
+ case 2: PROCESS1;
+ /* fallthrough */
+ case 1: PROCESS1;
+ /* fallthrough */
+ case 0: return XXH32_avalanche(h32);
+ }
+ assert(0);
+ return h32; /* reaching this point is deemed impossible */
+}
+
+
+FORCE_INLINE U32
+XXH32_endian_align(const void* input, size_t len, U32 seed,
+ XXH_endianess endian, XXH_alignment align)
+{
+ const BYTE* p = (const BYTE*)input;
+ const BYTE* bEnd = p + len;
+ U32 h32;
+
+#if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1)
+ if (p==NULL) {
+ len=0;
+ bEnd=p=(const BYTE*)(size_t)16;
+ }
+#endif
+
+ if (len>=16) {
+ const BYTE* const limit = bEnd - 15;
+ U32 v1 = seed + PRIME32_1 + PRIME32_2;
+ U32 v2 = seed + PRIME32_2;
+ U32 v3 = seed + 0;
+ U32 v4 = seed - PRIME32_1;
+
+ do {
+ v1 = XXH32_round(v1, XXH_get32bits(p)); p+=4;
+ v2 = XXH32_round(v2, XXH_get32bits(p)); p+=4;
+ v3 = XXH32_round(v3, XXH_get32bits(p)); p+=4;
+ v4 = XXH32_round(v4, XXH_get32bits(p)); p+=4;
+ } while (p < limit);
+
+ h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7)
+ + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18);
+ } else {
+ h32 = seed + PRIME32_5;
+ }
+
+ h32 += (U32)len;
+
+ return XXH32_finalize(h32, p, len&15, endian, align);
+}
+
+
+XXH_PUBLIC_API unsigned int XXH32 (const void* input, size_t len, unsigned int seed)
+{
+#if 0
+ /* Simple version, good for code maintenance, but unfortunately slow for small inputs */
+ XXH32_state_t state;
+ XXH32_reset(&state, seed);
+ XXH32_update(&state, input, len);
+ return XXH32_digest(&state);
+#else
+ XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
+
+ if (XXH_FORCE_ALIGN_CHECK) {
+ if ((((size_t)input) & 3) == 0) { /* Input is 4-bytes aligned, leverage the speed benefit */
+ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
+ return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned);
+ else
+ return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned);
+ } }
+
+ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
+ return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned);
+ else
+ return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned);
+#endif
+}
+
+
+
+/*====== Hash streaming ======*/
+
+XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void)
+{
+ return (XXH32_state_t*)XXH_malloc(sizeof(XXH32_state_t));
+}
+XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr)
+{
+ XXH_free(statePtr);
+ return XXH_OK;
+}
+
+XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dstState, const XXH32_state_t* srcState)
+{
+ memcpy(dstState, srcState, sizeof(*dstState));
+}
+
+XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, unsigned int seed)
+{
+ XXH32_state_t state; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */
+ memset(&state, 0, sizeof(state));
+ state.v1 = seed + PRIME32_1 + PRIME32_2;
+ state.v2 = seed + PRIME32_2;
+ state.v3 = seed + 0;
+ state.v4 = seed - PRIME32_1;
+ /* do not write into reserved, planned to be removed in a future version */
+ memcpy(statePtr, &state, sizeof(state) - sizeof(state.reserved));
+ return XXH_OK;
+}
+
+
+FORCE_INLINE XXH_errorcode
+XXH32_update_endian(XXH32_state_t* state, const void* input, size_t len, XXH_endianess endian)
+{
+ if (input==NULL)
+#if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1)
+ return XXH_OK;
+#else
+ return XXH_ERROR;
+#endif
+
+ { const BYTE* p = (const BYTE*)input;
+ const BYTE* const bEnd = p + len;
+
+ state->total_len_32 += (unsigned)len;
+ state->large_len |= (len>=16) | (state->total_len_32>=16);
+
+ if (state->memsize + len < 16) { /* fill in tmp buffer */
+ XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, len);
+ state->memsize += (unsigned)len;
+ return XXH_OK;
+ }
+
+ if (state->memsize) { /* some data left from previous update */
+ XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, 16-state->memsize);
+ { const U32* p32 = state->mem32;
+ state->v1 = XXH32_round(state->v1, XXH_readLE32(p32, endian)); p32++;
+ state->v2 = XXH32_round(state->v2, XXH_readLE32(p32, endian)); p32++;
+ state->v3 = XXH32_round(state->v3, XXH_readLE32(p32, endian)); p32++;
+ state->v4 = XXH32_round(state->v4, XXH_readLE32(p32, endian));
+ }
+ p += 16-state->memsize;
+ state->memsize = 0;
+ }
+
+ if (p <= bEnd-16) {
+ const BYTE* const limit = bEnd - 16;
+ U32 v1 = state->v1;
+ U32 v2 = state->v2;
+ U32 v3 = state->v3;
+ U32 v4 = state->v4;
+
+ do {
+ v1 = XXH32_round(v1, XXH_readLE32(p, endian)); p+=4;
+ v2 = XXH32_round(v2, XXH_readLE32(p, endian)); p+=4;
+ v3 = XXH32_round(v3, XXH_readLE32(p, endian)); p+=4;
+ v4 = XXH32_round(v4, XXH_readLE32(p, endian)); p+=4;
+ } while (p<=limit);
+
+ state->v1 = v1;
+ state->v2 = v2;
+ state->v3 = v3;
+ state->v4 = v4;
+ }
+
+ if (p < bEnd) {
+ XXH_memcpy(state->mem32, p, (size_t)(bEnd-p));
+ state->memsize = (unsigned)(bEnd-p);
+ }
+ }
+
+ return XXH_OK;
+}
+
+
+XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* state_in, const void* input, size_t len)
+{
+ XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
+
+ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
+ return XXH32_update_endian(state_in, input, len, XXH_littleEndian);
+ else
+ return XXH32_update_endian(state_in, input, len, XXH_bigEndian);
+}
+
+
+FORCE_INLINE U32
+XXH32_digest_endian (const XXH32_state_t* state, XXH_endianess endian)
+{
+ U32 h32;
+
+ if (state->large_len) {
+ h32 = XXH_rotl32(state->v1, 1)
+ + XXH_rotl32(state->v2, 7)
+ + XXH_rotl32(state->v3, 12)
+ + XXH_rotl32(state->v4, 18);
+ } else {
+ h32 = state->v3 /* == seed */ + PRIME32_5;
+ }
+
+ h32 += state->total_len_32;
+
+ return XXH32_finalize(h32, state->mem32, state->memsize, endian, XXH_aligned);
+}
+
+
+XXH_PUBLIC_API unsigned int XXH32_digest (const XXH32_state_t* state_in)
+{
+ XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
+
+ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
+ return XXH32_digest_endian(state_in, XXH_littleEndian);
+ else
+ return XXH32_digest_endian(state_in, XXH_bigEndian);
+}
+
+
+/*====== Canonical representation ======*/
+
+/*! Default XXH result types are basic unsigned 32 and 64 bits.
+* The canonical representation follows human-readable write convention, aka big-endian (large digits first).
+* These functions allow transformation of hash result into and from its canonical format.
+* This way, hash values can be written into a file or buffer, remaining comparable across different systems.
+*/
+
+XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash)
+{
+ XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t));
+ if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap32(hash);
+ memcpy(dst, &hash, sizeof(*dst));
+}
+
+XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src)
+{
+ return XXH_readBE32(src);
+}
+
+
+#ifndef XXH_NO_LONG_LONG
+
+/* *******************************************************************
+* 64-bit hash functions
+*********************************************************************/
+
+/*====== Memory access ======*/
+
+#ifndef MEM_MODULE
+# define MEM_MODULE
+# if !defined (__VMS) \
+ && (defined (__cplusplus) \
+ || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
+# include <stdint.h>
+ typedef uint64_t U64;
+# else
+ /* if compiler doesn't support unsigned long long, replace by another 64-bit type */
+ typedef unsigned long long U64;
+# endif
+#endif
+
+
+#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2))
+
+/* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */
+static U64 XXH_read64(const void* memPtr) { return *(const U64*) memPtr; }
+
+#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1))
+
+/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */
+/* currently only defined for gcc and icc */
+typedef union { U32 u32; U64 u64; } __attribute__((packed)) unalign64;
+static U64 XXH_read64(const void* ptr) { return ((const unalign64*)ptr)->u64; }
+
+#else
+
+/* portable and safe solution. Generally efficient.
+ * see : http://stackoverflow.com/a/32095106/646947
+ */
+
+static U64 XXH_read64(const void* memPtr)
+{
+ U64 val;
+ memcpy(&val, memPtr, sizeof(val));
+ return val;
+}
+
+#endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */
+
+#if defined(_MSC_VER) /* Visual Studio */
+# define XXH_swap64 _byteswap_uint64
+#elif XXH_GCC_VERSION >= 403
+# define XXH_swap64 __builtin_bswap64
+#else
+static U64 XXH_swap64 (U64 x)
+{
+ return ((x << 56) & 0xff00000000000000ULL) |
+ ((x << 40) & 0x00ff000000000000ULL) |
+ ((x << 24) & 0x0000ff0000000000ULL) |
+ ((x << 8) & 0x000000ff00000000ULL) |
+ ((x >> 8) & 0x00000000ff000000ULL) |
+ ((x >> 24) & 0x0000000000ff0000ULL) |
+ ((x >> 40) & 0x000000000000ff00ULL) |
+ ((x >> 56) & 0x00000000000000ffULL);
+}
+#endif
+
+FORCE_INLINE U64 XXH_readLE64_align(const void* ptr, XXH_endianess endian, XXH_alignment align)
+{
+ if (align==XXH_unaligned)
+ return endian==XXH_littleEndian ? XXH_read64(ptr) : XXH_swap64(XXH_read64(ptr));
+ else
+ return endian==XXH_littleEndian ? *(const U64*)ptr : XXH_swap64(*(const U64*)ptr);
+}
+
+FORCE_INLINE U64 XXH_readLE64(const void* ptr, XXH_endianess endian)
+{
+ return XXH_readLE64_align(ptr, endian, XXH_unaligned);
+}
+
+static U64 XXH_readBE64(const void* ptr)
+{
+ return XXH_CPU_LITTLE_ENDIAN ? XXH_swap64(XXH_read64(ptr)) : XXH_read64(ptr);
+}
+
+
+/*====== xxh64 ======*/
+
+static const U64 PRIME64_1 = 11400714785074694791ULL; /* 0b1001111000110111011110011011000110000101111010111100101010000111 */
+static const U64 PRIME64_2 = 14029467366897019727ULL; /* 0b1100001010110010101011100011110100100111110101001110101101001111 */
+static const U64 PRIME64_3 = 1609587929392839161ULL; /* 0b0001011001010110011001111011000110011110001101110111100111111001 */
+static const U64 PRIME64_4 = 9650029242287828579ULL; /* 0b1000010111101011110010100111011111000010101100101010111001100011 */
+static const U64 PRIME64_5 = 2870177450012600261ULL; /* 0b0010011111010100111010110010111100010110010101100110011111000101 */
+
+static U64 XXH64_round(U64 acc, U64 input)
+{
+ acc += input * PRIME64_2;
+ acc = XXH_rotl64(acc, 31);
+ acc *= PRIME64_1;
+ return acc;
+}
+
+static U64 XXH64_mergeRound(U64 acc, U64 val)
+{
+ val = XXH64_round(0, val);
+ acc ^= val;
+ acc = acc * PRIME64_1 + PRIME64_4;
+ return acc;
+}
+
+static U64 XXH64_avalanche(U64 h64)
+{
+ h64 ^= h64 >> 33;
+ h64 *= PRIME64_2;
+ h64 ^= h64 >> 29;
+ h64 *= PRIME64_3;
+ h64 ^= h64 >> 32;
+ return h64;
+}
+
+
+#define XXH_get64bits(p) XXH_readLE64_align(p, endian, align)
+
+static U64
+XXH64_finalize(U64 h64, const void* ptr, size_t len,
+ XXH_endianess endian, XXH_alignment align)
+{
+ const BYTE* p = (const BYTE*)ptr;
+
+#define PROCESS1_64 \
+ h64 ^= (*p++) * PRIME64_5; \
+ h64 = XXH_rotl64(h64, 11) * PRIME64_1
+
+#define PROCESS4_64 \
+ h64 ^= (U64)(XXH_get32bits(p)) * PRIME64_1; \
+ p+=4; \
+ h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3
+
+#define PROCESS8_64 do { \
+ U64 const k1 = XXH64_round(0, XXH_get64bits(p)); \
+ p+=8; \
+ h64 ^= k1; \
+ h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4; \
+} while (0)
+
+ switch(len&31) {
+ case 24: PROCESS8_64;
+ /* fallthrough */
+ case 16: PROCESS8_64;
+ /* fallthrough */
+ case 8: PROCESS8_64;
+ return XXH64_avalanche(h64);
+
+ case 28: PROCESS8_64;
+ /* fallthrough */
+ case 20: PROCESS8_64;
+ /* fallthrough */
+ case 12: PROCESS8_64;
+ /* fallthrough */
+ case 4: PROCESS4_64;
+ return XXH64_avalanche(h64);
+
+ case 25: PROCESS8_64;
+ /* fallthrough */
+ case 17: PROCESS8_64;
+ /* fallthrough */
+ case 9: PROCESS8_64;
+ PROCESS1_64;
+ return XXH64_avalanche(h64);
+
+ case 29: PROCESS8_64;
+ /* fallthrough */
+ case 21: PROCESS8_64;
+ /* fallthrough */
+ case 13: PROCESS8_64;
+ /* fallthrough */
+ case 5: PROCESS4_64;
+ PROCESS1_64;
+ return XXH64_avalanche(h64);
+
+ case 26: PROCESS8_64;
+ /* fallthrough */
+ case 18: PROCESS8_64;
+ /* fallthrough */
+ case 10: PROCESS8_64;
+ PROCESS1_64;
+ PROCESS1_64;
+ return XXH64_avalanche(h64);
+
+ case 30: PROCESS8_64;
+ /* fallthrough */
+ case 22: PROCESS8_64;
+ /* fallthrough */
+ case 14: PROCESS8_64;
+ /* fallthrough */
+ case 6: PROCESS4_64;
+ PROCESS1_64;
+ PROCESS1_64;
+ return XXH64_avalanche(h64);
+
+ case 27: PROCESS8_64;
+ /* fallthrough */
+ case 19: PROCESS8_64;
+ /* fallthrough */
+ case 11: PROCESS8_64;
+ PROCESS1_64;
+ PROCESS1_64;
+ PROCESS1_64;
+ return XXH64_avalanche(h64);
+
+ case 31: PROCESS8_64;
+ /* fallthrough */
+ case 23: PROCESS8_64;
+ /* fallthrough */
+ case 15: PROCESS8_64;
+ /* fallthrough */
+ case 7: PROCESS4_64;
+ /* fallthrough */
+ case 3: PROCESS1_64;
+ /* fallthrough */
+ case 2: PROCESS1_64;
+ /* fallthrough */
+ case 1: PROCESS1_64;
+ /* fallthrough */
+ case 0: return XXH64_avalanche(h64);
+ }
+
+ /* impossible to reach */
+ assert(0);
+ return 0; /* unreachable, but some compilers complain without it */
+}
+
+FORCE_INLINE U64
+XXH64_endian_align(const void* input, size_t len, U64 seed,
+ XXH_endianess endian, XXH_alignment align)
+{
+ const BYTE* p = (const BYTE*)input;
+ const BYTE* bEnd = p + len;
+ U64 h64;
+
+#if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1)
+ if (p==NULL) {
+ len=0;
+ bEnd=p=(const BYTE*)(size_t)32;
+ }
+#endif
+
+ if (len>=32) {
+ const BYTE* const limit = bEnd - 32;
+ U64 v1 = seed + PRIME64_1 + PRIME64_2;
+ U64 v2 = seed + PRIME64_2;
+ U64 v3 = seed + 0;
+ U64 v4 = seed - PRIME64_1;
+
+ do {
+ v1 = XXH64_round(v1, XXH_get64bits(p)); p+=8;
+ v2 = XXH64_round(v2, XXH_get64bits(p)); p+=8;
+ v3 = XXH64_round(v3, XXH_get64bits(p)); p+=8;
+ v4 = XXH64_round(v4, XXH_get64bits(p)); p+=8;
+ } while (p<=limit);
+
+ h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);
+ h64 = XXH64_mergeRound(h64, v1);
+ h64 = XXH64_mergeRound(h64, v2);
+ h64 = XXH64_mergeRound(h64, v3);
+ h64 = XXH64_mergeRound(h64, v4);
+
+ } else {
+ h64 = seed + PRIME64_5;
+ }
+
+ h64 += (U64) len;
+
+ return XXH64_finalize(h64, p, len, endian, align);
+}
+
+
+XXH_PUBLIC_API unsigned long long XXH64 (const void* input, size_t len, unsigned long long seed)
+{
+#if 0
+ /* Simple version, good for code maintenance, but unfortunately slow for small inputs */
+ XXH64_state_t state;
+ XXH64_reset(&state, seed);
+ XXH64_update(&state, input, len);
+ return XXH64_digest(&state);
+#else
+ XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
+
+ if (XXH_FORCE_ALIGN_CHECK) {
+ if ((((size_t)input) & 7)==0) { /* Input is aligned, let's leverage the speed advantage */
+ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
+ return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned);
+ else
+ return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned);
+ } }
+
+ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
+ return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned);
+ else
+ return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned);
+#endif
+}
+
+/*====== Hash Streaming ======*/
+
+XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void)
+{
+ return (XXH64_state_t*)XXH_malloc(sizeof(XXH64_state_t));
+}
+XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr)
+{
+ XXH_free(statePtr);
+ return XXH_OK;
+}
+
+XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* dstState, const XXH64_state_t* srcState)
+{
+ memcpy(dstState, srcState, sizeof(*dstState));
+}
+
+XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t* statePtr, unsigned long long seed)
+{
+ XXH64_state_t state; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */
+ memset(&state, 0, sizeof(state));
+ state.v1 = seed + PRIME64_1 + PRIME64_2;
+ state.v2 = seed + PRIME64_2;
+ state.v3 = seed + 0;
+ state.v4 = seed - PRIME64_1;
+ /* do not write into reserved, planned to be removed in a future version */
+ memcpy(statePtr, &state, sizeof(state) - sizeof(state.reserved));
+ return XXH_OK;
+}
+
+FORCE_INLINE XXH_errorcode
+XXH64_update_endian (XXH64_state_t* state, const void* input, size_t len, XXH_endianess endian)
+{
+ if (input==NULL)
+#if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1)
+ return XXH_OK;
+#else
+ return XXH_ERROR;
+#endif
+
+ { const BYTE* p = (const BYTE*)input;
+ const BYTE* const bEnd = p + len;
+
+ state->total_len += len;
+
+ if (state->memsize + len < 32) { /* fill in tmp buffer */
+ XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, len);
+ state->memsize += (U32)len;
+ return XXH_OK;
+ }
+
+ if (state->memsize) { /* tmp buffer is full */
+ XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, 32-state->memsize);
+ state->v1 = XXH64_round(state->v1, XXH_readLE64(state->mem64+0, endian));
+ state->v2 = XXH64_round(state->v2, XXH_readLE64(state->mem64+1, endian));
+ state->v3 = XXH64_round(state->v3, XXH_readLE64(state->mem64+2, endian));
+ state->v4 = XXH64_round(state->v4, XXH_readLE64(state->mem64+3, endian));
+ p += 32-state->memsize;
+ state->memsize = 0;
+ }
+
+ if (p+32 <= bEnd) {
+ const BYTE* const limit = bEnd - 32;
+ U64 v1 = state->v1;
+ U64 v2 = state->v2;
+ U64 v3 = state->v3;
+ U64 v4 = state->v4;
+
+ do {
+ v1 = XXH64_round(v1, XXH_readLE64(p, endian)); p+=8;
+ v2 = XXH64_round(v2, XXH_readLE64(p, endian)); p+=8;
+ v3 = XXH64_round(v3, XXH_readLE64(p, endian)); p+=8;
+ v4 = XXH64_round(v4, XXH_readLE64(p, endian)); p+=8;
+ } while (p<=limit);
+
+ state->v1 = v1;
+ state->v2 = v2;
+ state->v3 = v3;
+ state->v4 = v4;
+ }
+
+ if (p < bEnd) {
+ XXH_memcpy(state->mem64, p, (size_t)(bEnd-p));
+ state->memsize = (unsigned)(bEnd-p);
+ }
+ }
+
+ return XXH_OK;
+}
+
+XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* state_in, const void* input, size_t len)
+{
+ XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
+
+ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
+ return XXH64_update_endian(state_in, input, len, XXH_littleEndian);
+ else
+ return XXH64_update_endian(state_in, input, len, XXH_bigEndian);
+}
+
+FORCE_INLINE U64 XXH64_digest_endian (const XXH64_state_t* state, XXH_endianess endian)
+{
+ U64 h64;
+
+ if (state->total_len >= 32) {
+ U64 const v1 = state->v1;
+ U64 const v2 = state->v2;
+ U64 const v3 = state->v3;
+ U64 const v4 = state->v4;
+
+ h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);
+ h64 = XXH64_mergeRound(h64, v1);
+ h64 = XXH64_mergeRound(h64, v2);
+ h64 = XXH64_mergeRound(h64, v3);
+ h64 = XXH64_mergeRound(h64, v4);
+ } else {
+ h64 = state->v3 /*seed*/ + PRIME64_5;
+ }
+
+ h64 += (U64) state->total_len;
+
+ return XXH64_finalize(h64, state->mem64, (size_t)state->total_len, endian, XXH_aligned);
+}
+
+XXH_PUBLIC_API unsigned long long XXH64_digest (const XXH64_state_t* state_in)
+{
+ XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
+
+ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
+ return XXH64_digest_endian(state_in, XXH_littleEndian);
+ else
+ return XXH64_digest_endian(state_in, XXH_bigEndian);
+}
+
+
+/*====== Canonical representation ======*/
+
+XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash)
+{
+ XXH_STATIC_ASSERT(sizeof(XXH64_canonical_t) == sizeof(XXH64_hash_t));
+ if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap64(hash);
+ memcpy(dst, &hash, sizeof(*dst));
+}
+
+XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src)
+{
+ return XXH_readBE64(src);
+}
+
+#endif /* XXH_NO_LONG_LONG */
diff --git a/gfx/angle/checkout/src/common/third_party/xxhash/xxhash.h b/gfx/angle/checkout/src/common/third_party/xxhash/xxhash.h
new file mode 100644
index 0000000000..0de203c947
--- /dev/null
+++ b/gfx/angle/checkout/src/common/third_party/xxhash/xxhash.h
@@ -0,0 +1,341 @@
+/*
+ xxHash - Extremely Fast Hash algorithm
+ Header File
+ Copyright (C) 2012-2016, Yann Collet.
+
+ BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following disclaimer
+ in the documentation and/or other materials provided with the
+ distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ You can contact the author at :
+ - xxHash source repository : https://github.com/Cyan4973/xxHash
+*/
+
+/* Notice extracted from xxHash homepage :
+
+xxHash is an extremely fast Hash algorithm, running at RAM speed limits.
+It also successfully passes all tests from the SMHasher suite.
+
+Comparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2 Duo @3GHz)
+
+Name Speed Q.Score Author
+xxHash 5.4 GB/s 10
+CrapWow 3.2 GB/s 2 Andrew
+MumurHash 3a 2.7 GB/s 10 Austin Appleby
+SpookyHash 2.0 GB/s 10 Bob Jenkins
+SBox 1.4 GB/s 9 Bret Mulvey
+Lookup3 1.2 GB/s 9 Bob Jenkins
+SuperFastHash 1.2 GB/s 1 Paul Hsieh
+CityHash64 1.05 GB/s 10 Pike & Alakuijala
+FNV 0.55 GB/s 5 Fowler, Noll, Vo
+CRC32 0.43 GB/s 9
+MD5-32 0.33 GB/s 10 Ronald L. Rivest
+SHA1-32 0.28 GB/s 10
+
+Q.Score is a measure of quality of the hash function.
+It depends on successfully passing SMHasher test set.
+10 is a perfect score.
+
+A 64-bit version, named XXH64, is available since r35.
+It offers much better speed, but for 64-bit applications only.
+Name Speed on 64 bits Speed on 32 bits
+XXH64 13.8 GB/s 1.9 GB/s
+XXH32 6.8 GB/s 6.0 GB/s
+*/
+
+#ifndef XXHASH_H_5627135585666179
+#define XXHASH_H_5627135585666179 1
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/* ****************************
+ * Definitions
+ ******************************/
+#include <stddef.h> /* size_t */
+typedef enum
+{
+ XXH_OK = 0,
+ XXH_ERROR
+} XXH_errorcode;
+
+/* ****************************
+ * API modifier
+ ******************************/
+/** XXH_INLINE_ALL (and XXH_PRIVATE_API)
+ * This is useful to include xxhash functions in `static` mode
+ * in order to inline them, and remove their symbol from the public list.
+ * Inlining can offer dramatic performance improvement on small keys.
+ * Methodology :
+ * #define XXH_INLINE_ALL
+ * #include "xxhash.h"
+ * `xxhash.c` is automatically included.
+ * It's not useful to compile and link it as a separate module.
+ */
+#if defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API)
+# ifndef XXH_STATIC_LINKING_ONLY
+# define XXH_STATIC_LINKING_ONLY
+# endif
+# if defined(__GNUC__)
+# define XXH_PUBLIC_API static __inline __attribute__((unused))
+#elif defined(__cplusplus) || (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 \
+ */)
+# define XXH_PUBLIC_API static inline
+# elif defined(_MSC_VER)
+# define XXH_PUBLIC_API static __inline
+# else
+/* this version may generate warnings for unused static functions */
+# define XXH_PUBLIC_API static
+# endif
+#else
+# define XXH_PUBLIC_API /* do nothing */
+#endif /* XXH_INLINE_ALL || XXH_PRIVATE_API */
+
+/*! XXH_NAMESPACE, aka Namespace Emulation :
+ *
+ * If you want to include _and expose_ xxHash functions from within your own library,
+ * but also want to avoid symbol collisions with other libraries which may also include xxHash,
+ *
+ * you can use XXH_NAMESPACE, to automatically prefix any public symbol from xxhash library
+ * with the value of XXH_NAMESPACE (therefore, avoid NULL and numeric values).
+ *
+ * Note that no change is required within the calling program as long as it includes `xxhash.h` :
+ * regular symbol name will be automatically translated by this header.
+ */
+#ifdef XXH_NAMESPACE
+# define XXH_CAT(A, B) A##B
+# define XXH_NAME2(A, B) XXH_CAT(A, B)
+# define XXH_versionNumber XXH_NAME2(XXH_NAMESPACE, XXH_versionNumber)
+# define XXH32 XXH_NAME2(XXH_NAMESPACE, XXH32)
+# define XXH32_createState XXH_NAME2(XXH_NAMESPACE, XXH32_createState)
+# define XXH32_freeState XXH_NAME2(XXH_NAMESPACE, XXH32_freeState)
+# define XXH32_reset XXH_NAME2(XXH_NAMESPACE, XXH32_reset)
+# define XXH32_update XXH_NAME2(XXH_NAMESPACE, XXH32_update)
+# define XXH32_digest XXH_NAME2(XXH_NAMESPACE, XXH32_digest)
+# define XXH32_copyState XXH_NAME2(XXH_NAMESPACE, XXH32_copyState)
+# define XXH32_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH32_canonicalFromHash)
+# define XXH32_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH32_hashFromCanonical)
+# define XXH64 XXH_NAME2(XXH_NAMESPACE, XXH64)
+# define XXH64_createState XXH_NAME2(XXH_NAMESPACE, XXH64_createState)
+# define XXH64_freeState XXH_NAME2(XXH_NAMESPACE, XXH64_freeState)
+# define XXH64_reset XXH_NAME2(XXH_NAMESPACE, XXH64_reset)
+# define XXH64_update XXH_NAME2(XXH_NAMESPACE, XXH64_update)
+# define XXH64_digest XXH_NAME2(XXH_NAMESPACE, XXH64_digest)
+# define XXH64_copyState XXH_NAME2(XXH_NAMESPACE, XXH64_copyState)
+# define XXH64_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH64_canonicalFromHash)
+# define XXH64_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH64_hashFromCanonical)
+#endif
+
+/* *************************************
+ * Version
+ ***************************************/
+#define XXH_VERSION_MAJOR 0
+#define XXH_VERSION_MINOR 6
+#define XXH_VERSION_RELEASE 5
+#define XXH_VERSION_NUMBER \
+ (XXH_VERSION_MAJOR * 100 * 100 + XXH_VERSION_MINOR * 100 + XXH_VERSION_RELEASE)
+XXH_PUBLIC_API unsigned XXH_versionNumber(void);
+
+/*-**********************************************************************
+ * 32-bit hash
+ ************************************************************************/
+typedef unsigned int XXH32_hash_t;
+
+/*! XXH32() :
+ Calculate the 32-bit hash of sequence "length" bytes stored at memory address "input".
+ The memory between input & input+length must be valid (allocated and read-accessible).
+ "seed" can be used to alter the result predictably.
+ Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s */
+XXH_PUBLIC_API XXH32_hash_t XXH32(const void *input, size_t length, unsigned int seed);
+
+/*====== Streaming ======*/
+typedef struct XXH32_state_s XXH32_state_t; /* incomplete type */
+XXH_PUBLIC_API XXH32_state_t *XXH32_createState(void);
+XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t *statePtr);
+XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t *dst_state, const XXH32_state_t *src_state);
+
+XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t *statePtr, unsigned int seed);
+XXH_PUBLIC_API XXH_errorcode XXH32_update(XXH32_state_t *statePtr,
+ const void *input,
+ size_t length);
+XXH_PUBLIC_API XXH32_hash_t XXH32_digest(const XXH32_state_t *statePtr);
+
+/*
+ * Streaming functions generate the xxHash of an input provided in multiple segments.
+ * Note that, for small input, they are slower than single-call functions, due to state
+ * management. For small inputs, prefer `XXH32()` and `XXH64()`, which are better optimized.
+ *
+ * XXH state must first be allocated, using XXH*_createState() .
+ *
+ * Start a new hash by initializing state with a seed, using XXH*_reset().
+ *
+ * Then, feed the hash state by calling XXH*_update() as many times as necessary.
+ * The function returns an error code, with 0 meaning OK, and any other value meaning there is
+ * an error.
+ *
+ * Finally, a hash value can be produced anytime, by using XXH*_digest().
+ * This function returns the nn-bits hash as an int or long long.
+ *
+ * It's still possible to continue inserting input into the hash state after a digest,
+ * and generate some new hashes later on, by calling again XXH*_digest().
+ *
+ * When done, free XXH state space if it was allocated dynamically.
+ */
+
+/*====== Canonical representation ======*/
+
+typedef struct
+{
+ unsigned char digest[4];
+} XXH32_canonical_t;
+XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t *dst, XXH32_hash_t hash);
+XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t *src);
+
+/* Default result type for XXH functions are primitive unsigned 32 and 64 bits.
+ * The canonical representation uses human-readable write convention, aka big-endian (large
+ * digits first). These functions allow transformation of hash result into and from its
+ * canonical format. This way, hash values can be written into a file / memory, and remain
+ * comparable on different systems and programs.
+ */
+
+#ifndef XXH_NO_LONG_LONG
+/*-**********************************************************************
+ * 64-bit hash
+ ************************************************************************/
+typedef unsigned long long XXH64_hash_t;
+
+/*! XXH64() :
+ Calculate the 64-bit hash of sequence of length "len" stored at memory address "input".
+ "seed" can be used to alter the result predictably.
+ This function runs faster on 64-bit systems, but slower on 32-bit systems (see benchmark).
+*/
+XXH_PUBLIC_API XXH64_hash_t XXH64(const void *input, size_t length, unsigned long long seed);
+
+/*====== Streaming ======*/
+typedef struct XXH64_state_s XXH64_state_t; /* incomplete type */
+XXH_PUBLIC_API XXH64_state_t *XXH64_createState(void);
+XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t *statePtr);
+XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t *dst_state, const XXH64_state_t *src_state);
+
+XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t *statePtr, unsigned long long seed);
+XXH_PUBLIC_API XXH_errorcode XXH64_update(XXH64_state_t *statePtr,
+ const void *input,
+ size_t length);
+XXH_PUBLIC_API XXH64_hash_t XXH64_digest(const XXH64_state_t *statePtr);
+
+/*====== Canonical representation ======*/
+typedef struct
+{
+ unsigned char digest[8];
+} XXH64_canonical_t;
+XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t *dst, XXH64_hash_t hash);
+XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t *src);
+#endif /* XXH_NO_LONG_LONG */
+
+#ifdef XXH_STATIC_LINKING_ONLY
+
+/* ================================================================================================
+ This section contains declarations which are not guaranteed to remain stable.
+ They may change in future versions, becoming incompatible with a different version of the
+library. These declarations should only be used with static linking. Never use them in
+association with dynamic linking !
+===================================================================================================
+*/
+
+/* These definitions are only present to allow
+ * static allocation of XXH state, on stack or in a struct for example.
+ * Never **ever** use members directly. */
+
+# if !defined(__VMS) && (defined(__cplusplus) || (defined(__STDC_VERSION__) && \
+ (__STDC_VERSION__ >= 199901L) /* C99 */))
+# include <stdint.h>
+
+struct XXH32_state_s
+{
+ uint32_t total_len_32;
+ uint32_t large_len;
+ uint32_t v1;
+ uint32_t v2;
+ uint32_t v3;
+ uint32_t v4;
+ uint32_t mem32[4];
+ uint32_t memsize;
+ uint32_t reserved; /* never read nor write, might be removed in a future version */
+}; /* typedef'd to XXH32_state_t */
+
+struct XXH64_state_s
+{
+ uint64_t total_len;
+ uint64_t v1;
+ uint64_t v2;
+ uint64_t v3;
+ uint64_t v4;
+ uint64_t mem64[4];
+ uint32_t memsize;
+ uint32_t reserved[2]; /* never read nor write, might be removed in a future version */
+}; /* typedef'd to XXH64_state_t */
+
+# else
+
+struct XXH32_state_s
+{
+ unsigned total_len_32;
+ unsigned large_len;
+ unsigned v1;
+ unsigned v2;
+ unsigned v3;
+ unsigned v4;
+ unsigned mem32[4];
+ unsigned memsize;
+ unsigned reserved; /* never read nor write, might be removed in a future version */
+}; /* typedef'd to XXH32_state_t */
+
+# ifndef XXH_NO_LONG_LONG /* remove 64-bit support */
+struct XXH64_state_s
+{
+ unsigned long long total_len;
+ unsigned long long v1;
+ unsigned long long v2;
+ unsigned long long v3;
+ unsigned long long v4;
+ unsigned long long mem64[4];
+ unsigned memsize;
+ unsigned reserved[2]; /* never read nor write, might be removed in a future version */
+}; /* typedef'd to XXH64_state_t */
+# endif
+
+# endif
+
+# if defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API)
+# include "xxhash.c" /* include xxhash function bodies as `static`, for inlining */
+# endif
+
+#endif /* XXH_STATIC_LINKING_ONLY */
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* XXHASH_H_5627135585666179 */
diff --git a/gfx/angle/checkout/src/common/tls.cpp b/gfx/angle/checkout/src/common/tls.cpp
new file mode 100644
index 0000000000..458f5b816f
--- /dev/null
+++ b/gfx/angle/checkout/src/common/tls.cpp
@@ -0,0 +1,156 @@
+//
+// 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.
+//
+
+// tls.cpp: Simple cross-platform interface for thread local storage.
+
+#include "common/tls.h"
+
+#include "common/debug.h"
+
+#ifdef ANGLE_ENABLE_WINDOWS_UWP
+# include <map>
+# include <mutex>
+# include <set>
+# include <vector>
+
+# include <Windows.System.Threading.h>
+# include <wrl/async.h>
+# include <wrl/client.h>
+
+using namespace std;
+using namespace Windows::Foundation;
+using namespace ABI::Windows::System::Threading;
+
+// Thread local storage for Windows Store support
+typedef vector<void *> ThreadLocalData;
+
+static __declspec(thread) ThreadLocalData *currentThreadData = nullptr;
+static set<ThreadLocalData *> allThreadData;
+static DWORD nextTlsIndex = 0;
+static vector<DWORD> freeTlsIndices;
+
+#endif
+
+TLSIndex CreateTLSIndex(PthreadKeyDestructor destructor)
+{
+ TLSIndex index;
+
+#ifdef ANGLE_PLATFORM_WINDOWS
+# ifdef ANGLE_ENABLE_WINDOWS_UWP
+ if (!freeTlsIndices.empty())
+ {
+ DWORD result = freeTlsIndices.back();
+ freeTlsIndices.pop_back();
+ index = result;
+ }
+ else
+ {
+ index = nextTlsIndex++;
+ }
+# else
+ index = TlsAlloc();
+# endif
+
+#elif defined(ANGLE_PLATFORM_POSIX)
+ // Create pthread key
+ if ((pthread_key_create(&index, destructor)) != 0)
+ {
+ index = TLS_INVALID_INDEX;
+ }
+#endif
+
+ ASSERT(index != TLS_INVALID_INDEX && "CreateTLSIndex: Unable to allocate Thread Local Storage");
+ return index;
+}
+
+bool DestroyTLSIndex(TLSIndex index)
+{
+ ASSERT(index != TLS_INVALID_INDEX && "DestroyTLSIndex(): Invalid TLS Index");
+ if (index == TLS_INVALID_INDEX)
+ {
+ return false;
+ }
+
+#ifdef ANGLE_PLATFORM_WINDOWS
+# ifdef ANGLE_ENABLE_WINDOWS_UWP
+ ASSERT(index < nextTlsIndex);
+ ASSERT(find(freeTlsIndices.begin(), freeTlsIndices.end(), index) == freeTlsIndices.end());
+
+ freeTlsIndices.push_back(index);
+ for (auto threadData : allThreadData)
+ {
+ if (threadData->size() > index)
+ {
+ threadData->at(index) = nullptr;
+ }
+ }
+ return true;
+# else
+ return (TlsFree(index) == TRUE);
+# endif
+#elif defined(ANGLE_PLATFORM_POSIX)
+ return (pthread_key_delete(index) == 0);
+#endif
+}
+
+bool SetTLSValue(TLSIndex index, void *value)
+{
+ ASSERT(index != TLS_INVALID_INDEX && "SetTLSValue(): Invalid TLS Index");
+ if (index == TLS_INVALID_INDEX)
+ {
+ return false;
+ }
+
+#ifdef ANGLE_PLATFORM_WINDOWS
+# ifdef ANGLE_ENABLE_WINDOWS_UWP
+ ThreadLocalData *threadData = currentThreadData;
+ if (!threadData)
+ {
+ threadData = new ThreadLocalData(index + 1, nullptr);
+ allThreadData.insert(threadData);
+ currentThreadData = threadData;
+ }
+ else if (threadData->size() <= index)
+ {
+ threadData->resize(index + 1, nullptr);
+ }
+
+ threadData->at(index) = value;
+ return true;
+# else
+ return (TlsSetValue(index, value) == TRUE);
+# endif
+#elif defined(ANGLE_PLATFORM_POSIX)
+ return (pthread_setspecific(index, value) == 0);
+#endif
+}
+
+void *GetTLSValue(TLSIndex index)
+{
+ ASSERT(index != TLS_INVALID_INDEX && "GetTLSValue(): Invalid TLS Index");
+ if (index == TLS_INVALID_INDEX)
+ {
+ return nullptr;
+ }
+
+#ifdef ANGLE_PLATFORM_WINDOWS
+# ifdef ANGLE_ENABLE_WINDOWS_UWP
+ ThreadLocalData *threadData = currentThreadData;
+ if (threadData && threadData->size() > index)
+ {
+ return threadData->at(index);
+ }
+ else
+ {
+ return nullptr;
+ }
+# else
+ return TlsGetValue(index);
+# endif
+#elif defined(ANGLE_PLATFORM_POSIX)
+ return pthread_getspecific(index);
+#endif
+}
diff --git a/gfx/angle/checkout/src/common/tls.h b/gfx/angle/checkout/src/common/tls.h
new file mode 100644
index 0000000000..4075f3c030
--- /dev/null
+++ b/gfx/angle/checkout/src/common/tls.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.
+//
+
+// tls.h: Simple cross-platform interface for thread local storage.
+
+#ifndef COMMON_TLS_H_
+#define COMMON_TLS_H_
+
+#include "common/angleutils.h"
+#include "common/platform.h"
+
+#ifdef ANGLE_PLATFORM_WINDOWS
+# include <windows.h>
+#endif
+
+namespace gl
+{
+class Context;
+}
+
+#ifdef ANGLE_PLATFORM_WINDOWS
+
+// TLS does not exist for Windows Store and needs to be emulated
+# ifdef ANGLE_ENABLE_WINDOWS_UWP
+# ifndef TLS_OUT_OF_INDEXES
+# define TLS_OUT_OF_INDEXES static_cast<DWORD>(0xFFFFFFFF)
+# endif
+# ifndef CREATE_SUSPENDED
+# define CREATE_SUSPENDED 0x00000004
+# endif
+# endif
+typedef DWORD TLSIndex;
+# define TLS_INVALID_INDEX (TLS_OUT_OF_INDEXES)
+#elif defined(ANGLE_PLATFORM_POSIX)
+# include <errno.h>
+# include <pthread.h>
+# include <semaphore.h>
+typedef pthread_key_t TLSIndex;
+# define TLS_INVALID_INDEX (static_cast<TLSIndex>(-1))
+#else
+# error Unsupported platform.
+#endif
+
+using PthreadKeyDestructor = void (*)(void *);
+TLSIndex CreateTLSIndex(PthreadKeyDestructor destructor);
+bool DestroyTLSIndex(TLSIndex index);
+
+bool SetTLSValue(TLSIndex index, void *value);
+void *GetTLSValue(TLSIndex index);
+
+#endif // COMMON_TLS_H_
diff --git a/gfx/angle/checkout/src/common/uniform_type_info_autogen.cpp b/gfx/angle/checkout/src/common/uniform_type_info_autogen.cpp
new file mode 100644
index 0000000000..70249981a8
--- /dev/null
+++ b/gfx/angle/checkout/src/common/uniform_type_info_autogen.cpp
@@ -0,0 +1,378 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_uniform_type_table.py.
+//
+// Copyright 2017 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.
+//
+// Uniform type info table:
+// Metadata about a particular uniform format, indexed by GL type.
+
+#include <array>
+#include "common/utilities.h"
+
+using namespace angle;
+
+namespace gl
+{
+
+namespace
+{
+constexpr std::array<UniformTypeInfo, 77> kInfoTable = {
+ {{GL_NONE, GL_NONE, GL_NONE, GL_NONE, GL_NONE, SamplerFormat::InvalidEnum, 0, 0, 0, 0, 0 * 0,
+ 0 * 0, false, false, false},
+ {GL_BOOL, GL_BOOL, GL_NONE, GL_NONE, GL_NONE, SamplerFormat::InvalidEnum, 1, 1, 1,
+ sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, false, false, false},
+ {GL_BOOL_VEC2, GL_BOOL, GL_NONE, GL_NONE, GL_BOOL_VEC2, SamplerFormat::InvalidEnum, 1, 2, 2,
+ sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 2, false, false, false},
+ {GL_BOOL_VEC3, GL_BOOL, GL_NONE, GL_NONE, GL_BOOL_VEC3, SamplerFormat::InvalidEnum, 1, 3, 3,
+ sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 3, false, false, false},
+ {GL_BOOL_VEC4, GL_BOOL, GL_NONE, GL_NONE, GL_BOOL_VEC4, SamplerFormat::InvalidEnum, 1, 4, 4,
+ sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 4, false, false, false},
+ {GL_FLOAT, GL_FLOAT, GL_NONE, GL_NONE, GL_BOOL, SamplerFormat::InvalidEnum, 1, 1, 1,
+ sizeof(GLfloat), sizeof(GLfloat) * 4, sizeof(GLfloat) * 1, false, false, false},
+ {GL_FLOAT_MAT2, GL_FLOAT, GL_NONE, GL_FLOAT_MAT2, GL_NONE, SamplerFormat::InvalidEnum, 2, 2, 4,
+ sizeof(GLfloat), sizeof(GLfloat) * 8, sizeof(GLfloat) * 4, false, true, false},
+ {GL_FLOAT_MAT2x3, GL_FLOAT, GL_NONE, GL_FLOAT_MAT3x2, GL_NONE, SamplerFormat::InvalidEnum, 3,
+ 2, 6, sizeof(GLfloat), sizeof(GLfloat) * 12, sizeof(GLfloat) * 6, false, true, false},
+ {GL_FLOAT_MAT2x4, GL_FLOAT, GL_NONE, GL_FLOAT_MAT4x2, GL_NONE, SamplerFormat::InvalidEnum, 4,
+ 2, 8, sizeof(GLfloat), sizeof(GLfloat) * 16, sizeof(GLfloat) * 8, false, true, false},
+ {GL_FLOAT_MAT3, GL_FLOAT, GL_NONE, GL_FLOAT_MAT3, GL_NONE, SamplerFormat::InvalidEnum, 3, 3, 9,
+ sizeof(GLfloat), sizeof(GLfloat) * 12, sizeof(GLfloat) * 9, false, true, false},
+ {GL_FLOAT_MAT3x2, GL_FLOAT, GL_NONE, GL_FLOAT_MAT2x3, GL_NONE, SamplerFormat::InvalidEnum, 2,
+ 3, 6, sizeof(GLfloat), sizeof(GLfloat) * 8, sizeof(GLfloat) * 6, false, true, false},
+ {GL_FLOAT_MAT3x4, GL_FLOAT, GL_NONE, GL_FLOAT_MAT4x3, GL_NONE, SamplerFormat::InvalidEnum, 4,
+ 3, 12, sizeof(GLfloat), sizeof(GLfloat) * 16, sizeof(GLfloat) * 12, false, true, false},
+ {GL_FLOAT_MAT4, GL_FLOAT, GL_NONE, GL_FLOAT_MAT4, GL_NONE, SamplerFormat::InvalidEnum, 4, 4,
+ 16, sizeof(GLfloat), sizeof(GLfloat) * 16, sizeof(GLfloat) * 16, false, true, false},
+ {GL_FLOAT_MAT4x2, GL_FLOAT, GL_NONE, GL_FLOAT_MAT2x4, GL_NONE, SamplerFormat::InvalidEnum, 2,
+ 4, 8, sizeof(GLfloat), sizeof(GLfloat) * 8, sizeof(GLfloat) * 8, false, true, false},
+ {GL_FLOAT_MAT4x3, GL_FLOAT, GL_NONE, GL_FLOAT_MAT3x4, GL_NONE, SamplerFormat::InvalidEnum, 3,
+ 4, 12, sizeof(GLfloat), sizeof(GLfloat) * 12, sizeof(GLfloat) * 12, false, true, false},
+ {GL_FLOAT_VEC2, GL_FLOAT, GL_NONE, GL_NONE, GL_BOOL_VEC2, SamplerFormat::InvalidEnum, 1, 2, 2,
+ sizeof(GLfloat), sizeof(GLfloat) * 4, sizeof(GLfloat) * 2, false, false, false},
+ {GL_FLOAT_VEC3, GL_FLOAT, GL_NONE, GL_NONE, GL_BOOL_VEC3, SamplerFormat::InvalidEnum, 1, 3, 3,
+ sizeof(GLfloat), sizeof(GLfloat) * 4, sizeof(GLfloat) * 3, false, false, false},
+ {GL_FLOAT_VEC4, GL_FLOAT, GL_NONE, GL_NONE, GL_BOOL_VEC4, SamplerFormat::InvalidEnum, 1, 4, 4,
+ sizeof(GLfloat), sizeof(GLfloat) * 4, sizeof(GLfloat) * 4, false, false, false},
+ {GL_IMAGE_2D, GL_INT, GL_TEXTURE_2D, GL_NONE, GL_NONE, SamplerFormat::InvalidEnum, 1, 1, 1,
+ sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, false, false, true},
+ {GL_IMAGE_2D_ARRAY, GL_INT, GL_TEXTURE_2D_ARRAY, GL_NONE, GL_NONE, SamplerFormat::InvalidEnum,
+ 1, 1, 1, sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, false, false, true},
+ {GL_IMAGE_3D, GL_INT, GL_TEXTURE_3D, GL_NONE, GL_NONE, SamplerFormat::InvalidEnum, 1, 1, 1,
+ sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, false, false, true},
+ {GL_IMAGE_CUBE, GL_INT, GL_TEXTURE_CUBE_MAP, GL_NONE, GL_NONE, SamplerFormat::InvalidEnum, 1,
+ 1, 1, sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, false, false, true},
+ {GL_IMAGE_CUBE_MAP_ARRAY, GL_INT, GL_TEXTURE_CUBE_MAP_ARRAY, GL_NONE, GL_NONE,
+ SamplerFormat::InvalidEnum, 1, 1, 1, sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1,
+ false, false, true},
+ {GL_IMAGE_BUFFER, GL_INT, GL_TEXTURE_BUFFER, GL_NONE, GL_NONE, SamplerFormat::InvalidEnum, 1,
+ 1, 1, sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, false, false, true},
+ {GL_INT, GL_INT, GL_NONE, GL_NONE, GL_BOOL, SamplerFormat::InvalidEnum, 1, 1, 1, sizeof(GLint),
+ sizeof(GLint) * 4, sizeof(GLint) * 1, false, false, false},
+ {GL_INT_IMAGE_2D, GL_INT, GL_TEXTURE_2D, GL_NONE, GL_NONE, SamplerFormat::InvalidEnum, 1, 1, 1,
+ sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, false, false, true},
+ {GL_INT_IMAGE_2D_ARRAY, GL_INT, GL_TEXTURE_2D_ARRAY, GL_NONE, GL_NONE,
+ SamplerFormat::InvalidEnum, 1, 1, 1, sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1,
+ false, false, true},
+ {GL_INT_IMAGE_3D, GL_INT, GL_TEXTURE_3D, GL_NONE, GL_NONE, SamplerFormat::InvalidEnum, 1, 1, 1,
+ sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, false, false, true},
+ {GL_INT_IMAGE_CUBE, GL_INT, GL_TEXTURE_CUBE_MAP, GL_NONE, GL_NONE, SamplerFormat::InvalidEnum,
+ 1, 1, 1, sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, false, false, true},
+ {GL_INT_IMAGE_CUBE_MAP_ARRAY, GL_INT, GL_TEXTURE_CUBE_MAP_ARRAY, GL_NONE, GL_NONE,
+ SamplerFormat::InvalidEnum, 1, 1, 1, sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1,
+ false, false, true},
+ {GL_INT_IMAGE_BUFFER, GL_INT, GL_TEXTURE_BUFFER, GL_NONE, GL_NONE, SamplerFormat::InvalidEnum,
+ 1, 1, 1, sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, false, false, true},
+ {GL_INT_SAMPLER_2D, GL_INT, GL_TEXTURE_2D, GL_NONE, GL_NONE, SamplerFormat::Signed, 1, 1, 1,
+ sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
+ {GL_INT_SAMPLER_2D_ARRAY, GL_INT, GL_TEXTURE_2D_ARRAY, GL_NONE, GL_NONE, SamplerFormat::Signed,
+ 1, 1, 1, sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
+ {GL_INT_SAMPLER_2D_MULTISAMPLE, GL_INT, GL_TEXTURE_2D_MULTISAMPLE, GL_NONE, GL_NONE,
+ SamplerFormat::Signed, 1, 1, 1, sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, true,
+ false, false},
+ {GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY, GL_INT, GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_NONE,
+ GL_NONE, SamplerFormat::Signed, 1, 1, 1, sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1,
+ true, false, false},
+ {GL_INT_SAMPLER_3D, GL_INT, GL_TEXTURE_3D, GL_NONE, GL_NONE, SamplerFormat::Signed, 1, 1, 1,
+ sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
+ {GL_INT_SAMPLER_CUBE, GL_INT, GL_TEXTURE_CUBE_MAP, GL_NONE, GL_NONE, SamplerFormat::Signed, 1,
+ 1, 1, sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
+ {GL_INT_SAMPLER_CUBE_MAP_ARRAY, GL_INT, GL_TEXTURE_CUBE_MAP_ARRAY, GL_NONE, GL_NONE,
+ SamplerFormat::Signed, 1, 1, 1, sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, true,
+ false, false},
+ {GL_INT_SAMPLER_BUFFER, GL_INT, GL_TEXTURE_BUFFER, GL_NONE, GL_NONE, SamplerFormat::Signed, 1,
+ 1, 1, sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
+ {GL_INT_VEC2, GL_INT, GL_NONE, GL_NONE, GL_BOOL_VEC2, SamplerFormat::InvalidEnum, 1, 2, 2,
+ sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 2, false, false, false},
+ {GL_INT_VEC3, GL_INT, GL_NONE, GL_NONE, GL_BOOL_VEC3, SamplerFormat::InvalidEnum, 1, 3, 3,
+ sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 3, false, false, false},
+ {GL_INT_VEC4, GL_INT, GL_NONE, GL_NONE, GL_BOOL_VEC4, SamplerFormat::InvalidEnum, 1, 4, 4,
+ sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 4, false, false, false},
+ {GL_SAMPLER_2D, GL_INT, GL_TEXTURE_2D, GL_NONE, GL_NONE, SamplerFormat::Float, 1, 1, 1,
+ sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
+ {GL_SAMPLER_2D_ARRAY, GL_INT, GL_TEXTURE_2D_ARRAY, GL_NONE, GL_NONE, SamplerFormat::Float, 1,
+ 1, 1, sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
+ {GL_SAMPLER_2D_ARRAY_SHADOW, GL_INT, GL_TEXTURE_2D_ARRAY, GL_NONE, GL_NONE,
+ SamplerFormat::Shadow, 1, 1, 1, sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, true,
+ false, false},
+ {GL_SAMPLER_2D_MULTISAMPLE, GL_INT, GL_TEXTURE_2D_MULTISAMPLE, GL_NONE, GL_NONE,
+ SamplerFormat::Float, 1, 1, 1, sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, true,
+ false, false},
+ {GL_SAMPLER_2D_MULTISAMPLE_ARRAY, GL_INT, GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_NONE, GL_NONE,
+ SamplerFormat::Float, 1, 1, 1, sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, true,
+ false, false},
+ {GL_SAMPLER_2D_RECT_ANGLE, GL_INT, GL_TEXTURE_2D, GL_NONE, GL_NONE, SamplerFormat::Float, 1, 1,
+ 1, sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
+ {GL_SAMPLER_2D_SHADOW, GL_INT, GL_TEXTURE_2D, GL_NONE, GL_NONE, SamplerFormat::Shadow, 1, 1, 1,
+ sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
+ {GL_SAMPLER_3D, GL_INT, GL_TEXTURE_3D, GL_NONE, GL_NONE, SamplerFormat::Float, 1, 1, 1,
+ sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
+ {GL_SAMPLER_CUBE, GL_INT, GL_TEXTURE_CUBE_MAP, GL_NONE, GL_NONE, SamplerFormat::Float, 1, 1, 1,
+ sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
+ {GL_SAMPLER_CUBE_MAP_ARRAY, GL_INT, GL_TEXTURE_CUBE_MAP_ARRAY, GL_NONE, GL_NONE,
+ SamplerFormat::Float, 1, 1, 1, sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, true,
+ false, false},
+ {GL_SAMPLER_BUFFER, GL_INT, GL_TEXTURE_BUFFER, GL_NONE, GL_NONE, SamplerFormat::Float, 1, 1, 1,
+ sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
+ {GL_SAMPLER_CUBE_SHADOW, GL_INT, GL_TEXTURE_CUBE_MAP, GL_NONE, GL_NONE, SamplerFormat::Shadow,
+ 1, 1, 1, sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
+ {GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW, GL_INT, GL_NONE, GL_NONE, GL_NONE, SamplerFormat::Shadow, 1,
+ 1, 1, sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false},
+ {GL_SAMPLER_EXTERNAL_OES, GL_INT, GL_TEXTURE_EXTERNAL_OES, GL_NONE, GL_NONE,
+ SamplerFormat::Float, 1, 1, 1, sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, true,
+ false, false},
+ {GL_UNSIGNED_INT, GL_UNSIGNED_INT, GL_NONE, GL_NONE, GL_BOOL, SamplerFormat::InvalidEnum, 1, 1,
+ 1, sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 1, false, false, false},
+ {GL_UNSIGNED_INT_ATOMIC_COUNTER, GL_UNSIGNED_INT, GL_NONE, GL_NONE, GL_NONE,
+ SamplerFormat::InvalidEnum, 1, 1, 1, sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 1,
+ false, false, false},
+ {GL_UNSIGNED_INT_IMAGE_2D, GL_UNSIGNED_INT, GL_TEXTURE_2D, GL_NONE, GL_NONE,
+ SamplerFormat::InvalidEnum, 1, 1, 1, sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 1,
+ false, false, true},
+ {GL_UNSIGNED_INT_IMAGE_2D_ARRAY, GL_UNSIGNED_INT, GL_TEXTURE_2D_ARRAY, GL_NONE, GL_NONE,
+ SamplerFormat::InvalidEnum, 1, 1, 1, sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 1,
+ false, false, true},
+ {GL_UNSIGNED_INT_IMAGE_3D, GL_UNSIGNED_INT, GL_TEXTURE_3D, GL_NONE, GL_NONE,
+ SamplerFormat::InvalidEnum, 1, 1, 1, sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 1,
+ false, false, true},
+ {GL_UNSIGNED_INT_IMAGE_CUBE, GL_UNSIGNED_INT, GL_TEXTURE_CUBE_MAP, GL_NONE, GL_NONE,
+ SamplerFormat::InvalidEnum, 1, 1, 1, sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 1,
+ false, false, true},
+ {GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY, GL_UNSIGNED_INT, GL_TEXTURE_CUBE_MAP_ARRAY, GL_NONE,
+ GL_NONE, SamplerFormat::InvalidEnum, 1, 1, 1, sizeof(GLuint), sizeof(GLuint) * 4,
+ sizeof(GLuint) * 1, false, false, true},
+ {GL_UNSIGNED_INT_IMAGE_BUFFER, GL_UNSIGNED_INT, GL_TEXTURE_BUFFER, GL_NONE, GL_NONE,
+ SamplerFormat::InvalidEnum, 1, 1, 1, sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 1,
+ false, false, true},
+ {GL_UNSIGNED_INT_SAMPLER_2D, GL_UNSIGNED_INT, GL_TEXTURE_2D, GL_NONE, GL_NONE,
+ SamplerFormat::Unsigned, 1, 1, 1, sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 1,
+ true, false, false},
+ {GL_UNSIGNED_INT_SAMPLER_2D_ARRAY, GL_UNSIGNED_INT, GL_TEXTURE_2D_ARRAY, GL_NONE, GL_NONE,
+ SamplerFormat::Unsigned, 1, 1, 1, sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 1,
+ true, false, false},
+ {GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE, GL_UNSIGNED_INT, GL_TEXTURE_2D_MULTISAMPLE, GL_NONE,
+ GL_NONE, SamplerFormat::Unsigned, 1, 1, 1, sizeof(GLuint), sizeof(GLuint) * 4,
+ sizeof(GLuint) * 1, true, false, false},
+ {GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY, GL_UNSIGNED_INT,
+ GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_NONE, GL_NONE, SamplerFormat::Unsigned, 1, 1, 1,
+ sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 1, true, false, false},
+ {GL_UNSIGNED_INT_SAMPLER_3D, GL_UNSIGNED_INT, GL_TEXTURE_3D, GL_NONE, GL_NONE,
+ SamplerFormat::Unsigned, 1, 1, 1, sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 1,
+ true, false, false},
+ {GL_UNSIGNED_INT_SAMPLER_CUBE, GL_UNSIGNED_INT, GL_TEXTURE_CUBE_MAP, GL_NONE, GL_NONE,
+ SamplerFormat::Unsigned, 1, 1, 1, sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 1,
+ true, false, false},
+ {GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY, GL_UNSIGNED_INT, GL_TEXTURE_CUBE_MAP_ARRAY, GL_NONE,
+ GL_NONE, SamplerFormat::Unsigned, 1, 1, 1, sizeof(GLuint), sizeof(GLuint) * 4,
+ sizeof(GLuint) * 1, true, false, false},
+ {GL_UNSIGNED_INT_SAMPLER_BUFFER, GL_UNSIGNED_INT, GL_TEXTURE_BUFFER, GL_NONE, GL_NONE,
+ SamplerFormat::Unsigned, 1, 1, 1, sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 1,
+ true, false, false},
+ {GL_UNSIGNED_INT_VEC2, GL_UNSIGNED_INT, GL_NONE, GL_NONE, GL_BOOL_VEC2,
+ SamplerFormat::InvalidEnum, 1, 2, 2, sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 2,
+ false, false, false},
+ {GL_UNSIGNED_INT_VEC3, GL_UNSIGNED_INT, GL_NONE, GL_NONE, GL_BOOL_VEC3,
+ SamplerFormat::InvalidEnum, 1, 3, 3, sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 3,
+ false, false, false},
+ {GL_UNSIGNED_INT_VEC4, GL_UNSIGNED_INT, GL_NONE, GL_NONE, GL_BOOL_VEC4,
+ SamplerFormat::InvalidEnum, 1, 4, 4, sizeof(GLuint), sizeof(GLuint) * 4, sizeof(GLuint) * 4,
+ false, false, false},
+ {GL_SAMPLER_VIDEO_IMAGE_WEBGL, GL_INT, GL_TEXTURE_VIDEO_IMAGE_WEBGL, GL_NONE, GL_NONE,
+ SamplerFormat::Float, 1, 1, 1, sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, true,
+ false, false},
+ {GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT, GL_INT, GL_NONE, GL_NONE, GL_NONE, SamplerFormat::Float, 1, 1,
+ 1, sizeof(GLint), sizeof(GLint) * 4, sizeof(GLint) * 1, true, false, false}}};
+
+size_t GetTypeInfoIndex(GLenum uniformType)
+{
+ switch (uniformType)
+ {
+ case GL_NONE:
+ return 0;
+ case GL_BOOL:
+ return 1;
+ case GL_BOOL_VEC2:
+ return 2;
+ case GL_BOOL_VEC3:
+ return 3;
+ case GL_BOOL_VEC4:
+ return 4;
+ case GL_FLOAT:
+ return 5;
+ case GL_FLOAT_MAT2:
+ return 6;
+ case GL_FLOAT_MAT2x3:
+ return 7;
+ case GL_FLOAT_MAT2x4:
+ return 8;
+ case GL_FLOAT_MAT3:
+ return 9;
+ case GL_FLOAT_MAT3x2:
+ return 10;
+ case GL_FLOAT_MAT3x4:
+ return 11;
+ case GL_FLOAT_MAT4:
+ return 12;
+ case GL_FLOAT_MAT4x2:
+ return 13;
+ case GL_FLOAT_MAT4x3:
+ return 14;
+ case GL_FLOAT_VEC2:
+ return 15;
+ case GL_FLOAT_VEC3:
+ return 16;
+ case GL_FLOAT_VEC4:
+ return 17;
+ case GL_IMAGE_2D:
+ return 18;
+ case GL_IMAGE_2D_ARRAY:
+ return 19;
+ case GL_IMAGE_3D:
+ return 20;
+ case GL_IMAGE_CUBE:
+ return 21;
+ case GL_IMAGE_CUBE_MAP_ARRAY:
+ return 22;
+ case GL_IMAGE_BUFFER:
+ return 23;
+ case GL_INT:
+ return 24;
+ case GL_INT_IMAGE_2D:
+ return 25;
+ case GL_INT_IMAGE_2D_ARRAY:
+ return 26;
+ case GL_INT_IMAGE_3D:
+ return 27;
+ case GL_INT_IMAGE_CUBE:
+ return 28;
+ case GL_INT_IMAGE_CUBE_MAP_ARRAY:
+ return 29;
+ case GL_INT_IMAGE_BUFFER:
+ return 30;
+ case GL_INT_SAMPLER_2D:
+ return 31;
+ case GL_INT_SAMPLER_2D_ARRAY:
+ return 32;
+ case GL_INT_SAMPLER_2D_MULTISAMPLE:
+ return 33;
+ case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ return 34;
+ case GL_INT_SAMPLER_3D:
+ return 35;
+ case GL_INT_SAMPLER_CUBE:
+ return 36;
+ case GL_INT_SAMPLER_CUBE_MAP_ARRAY:
+ return 37;
+ case GL_INT_SAMPLER_BUFFER:
+ return 38;
+ case GL_INT_VEC2:
+ return 39;
+ case GL_INT_VEC3:
+ return 40;
+ case GL_INT_VEC4:
+ return 41;
+ case GL_SAMPLER_2D:
+ return 42;
+ case GL_SAMPLER_2D_ARRAY:
+ return 43;
+ case GL_SAMPLER_2D_ARRAY_SHADOW:
+ return 44;
+ case GL_SAMPLER_2D_MULTISAMPLE:
+ return 45;
+ case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ return 46;
+ case GL_SAMPLER_2D_RECT_ANGLE:
+ return 47;
+ case GL_SAMPLER_2D_SHADOW:
+ return 48;
+ case GL_SAMPLER_3D:
+ return 49;
+ case GL_SAMPLER_CUBE:
+ return 50;
+ case GL_SAMPLER_CUBE_MAP_ARRAY:
+ return 51;
+ case GL_SAMPLER_BUFFER:
+ return 52;
+ case GL_SAMPLER_CUBE_SHADOW:
+ return 53;
+ case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW:
+ return 54;
+ case GL_SAMPLER_EXTERNAL_OES:
+ return 55;
+ case GL_UNSIGNED_INT:
+ return 56;
+ case GL_UNSIGNED_INT_ATOMIC_COUNTER:
+ return 57;
+ case GL_UNSIGNED_INT_IMAGE_2D:
+ return 58;
+ case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
+ return 59;
+ case GL_UNSIGNED_INT_IMAGE_3D:
+ return 60;
+ case GL_UNSIGNED_INT_IMAGE_CUBE:
+ return 61;
+ case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY:
+ return 62;
+ case GL_UNSIGNED_INT_IMAGE_BUFFER:
+ return 63;
+ case GL_UNSIGNED_INT_SAMPLER_2D:
+ return 64;
+ case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
+ return 65;
+ case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
+ return 66;
+ case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ return 67;
+ case GL_UNSIGNED_INT_SAMPLER_3D:
+ return 68;
+ case GL_UNSIGNED_INT_SAMPLER_CUBE:
+ return 69;
+ case GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY:
+ return 70;
+ case GL_UNSIGNED_INT_SAMPLER_BUFFER:
+ return 71;
+ case GL_UNSIGNED_INT_VEC2:
+ return 72;
+ case GL_UNSIGNED_INT_VEC3:
+ return 73;
+ case GL_UNSIGNED_INT_VEC4:
+ return 74;
+ case GL_SAMPLER_VIDEO_IMAGE_WEBGL:
+ return 75;
+ case GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT:
+ return 76;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+} // anonymous namespace
+
+const UniformTypeInfo &GetUniformTypeInfo(GLenum uniformType)
+{
+ ASSERT(kInfoTable[GetTypeInfoIndex(uniformType)].type == uniformType);
+ return kInfoTable[GetTypeInfoIndex(uniformType)];
+}
+
+} // namespace gl
diff --git a/gfx/angle/checkout/src/common/utilities.cpp b/gfx/angle/checkout/src/common/utilities.cpp
new file mode 100644
index 0000000000..f08774523c
--- /dev/null
+++ b/gfx/angle/checkout/src/common/utilities.cpp
@@ -0,0 +1,1509 @@
+//
+// Copyright 2002 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.
+//
+
+// utilities.cpp: Conversion functions and other utility routines.
+
+#include "common/utilities.h"
+#include "GLES3/gl3.h"
+#include "common/mathutil.h"
+#include "common/platform.h"
+#include "common/string_utils.h"
+
+#include <set>
+
+#if defined(ANGLE_ENABLE_WINDOWS_UWP)
+# include <windows.applicationmodel.core.h>
+# include <windows.graphics.display.h>
+# include <wrl.h>
+# include <wrl/wrappers/corewrappers.h>
+#endif
+
+namespace
+{
+
+template <class IndexType>
+gl::IndexRange ComputeTypedIndexRange(const IndexType *indices,
+ size_t count,
+ bool primitiveRestartEnabled,
+ GLuint primitiveRestartIndex)
+{
+ ASSERT(count > 0);
+
+ IndexType minIndex = 0;
+ IndexType maxIndex = 0;
+ size_t nonPrimitiveRestartIndices = 0;
+
+ if (primitiveRestartEnabled)
+ {
+ // Find the first non-primitive restart index to initialize the min and max values
+ size_t i = 0;
+ for (; i < count; i++)
+ {
+ if (indices[i] != primitiveRestartIndex)
+ {
+ minIndex = indices[i];
+ maxIndex = indices[i];
+ nonPrimitiveRestartIndices++;
+ break;
+ }
+ }
+
+ // Loop over the rest of the indices
+ for (; i < count; i++)
+ {
+ if (indices[i] != primitiveRestartIndex)
+ {
+ if (minIndex > indices[i])
+ {
+ minIndex = indices[i];
+ }
+ if (maxIndex < indices[i])
+ {
+ maxIndex = indices[i];
+ }
+ nonPrimitiveRestartIndices++;
+ }
+ }
+ }
+ else
+ {
+ minIndex = indices[0];
+ maxIndex = indices[0];
+ nonPrimitiveRestartIndices = count;
+
+ for (size_t i = 1; i < count; i++)
+ {
+ if (minIndex > indices[i])
+ {
+ minIndex = indices[i];
+ }
+ if (maxIndex < indices[i])
+ {
+ maxIndex = indices[i];
+ }
+ }
+ }
+
+ return gl::IndexRange(static_cast<size_t>(minIndex), static_cast<size_t>(maxIndex),
+ nonPrimitiveRestartIndices);
+}
+
+} // anonymous namespace
+
+namespace gl
+{
+
+int VariableComponentCount(GLenum type)
+{
+ return VariableRowCount(type) * VariableColumnCount(type);
+}
+
+GLenum VariableComponentType(GLenum type)
+{
+ switch (type)
+ {
+ case GL_BOOL:
+ case GL_BOOL_VEC2:
+ case GL_BOOL_VEC3:
+ case GL_BOOL_VEC4:
+ return GL_BOOL;
+ case GL_FLOAT:
+ case GL_FLOAT_VEC2:
+ case GL_FLOAT_VEC3:
+ case GL_FLOAT_VEC4:
+ case GL_FLOAT_MAT2:
+ case GL_FLOAT_MAT3:
+ case GL_FLOAT_MAT4:
+ case GL_FLOAT_MAT2x3:
+ case GL_FLOAT_MAT3x2:
+ case GL_FLOAT_MAT2x4:
+ case GL_FLOAT_MAT4x2:
+ case GL_FLOAT_MAT3x4:
+ case GL_FLOAT_MAT4x3:
+ return GL_FLOAT;
+ case GL_INT:
+ case GL_SAMPLER_2D:
+ case GL_SAMPLER_2D_RECT_ANGLE:
+ case GL_SAMPLER_3D:
+ case GL_SAMPLER_CUBE:
+ case GL_SAMPLER_CUBE_MAP_ARRAY:
+ case GL_SAMPLER_2D_ARRAY:
+ case GL_SAMPLER_EXTERNAL_OES:
+ case GL_SAMPLER_2D_MULTISAMPLE:
+ case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ case GL_INT_SAMPLER_BUFFER:
+ case GL_INT_SAMPLER_2D:
+ case GL_INT_SAMPLER_3D:
+ case GL_INT_SAMPLER_CUBE:
+ case GL_INT_SAMPLER_CUBE_MAP_ARRAY:
+ case GL_INT_SAMPLER_2D_ARRAY:
+ case GL_INT_SAMPLER_2D_MULTISAMPLE:
+ case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_2D:
+ case GL_UNSIGNED_INT_SAMPLER_3D:
+ case GL_UNSIGNED_INT_SAMPLER_CUBE:
+ case GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
+ case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ case GL_SAMPLER_2D_SHADOW:
+ case GL_SAMPLER_BUFFER:
+ case GL_SAMPLER_CUBE_SHADOW:
+ case GL_SAMPLER_2D_ARRAY_SHADOW:
+ case GL_INT_VEC2:
+ case GL_INT_VEC3:
+ case GL_INT_VEC4:
+ case GL_IMAGE_2D:
+ case GL_INT_IMAGE_2D:
+ case GL_UNSIGNED_INT_IMAGE_2D:
+ case GL_IMAGE_3D:
+ case GL_INT_IMAGE_3D:
+ case GL_UNSIGNED_INT_IMAGE_3D:
+ case GL_IMAGE_2D_ARRAY:
+ case GL_INT_IMAGE_2D_ARRAY:
+ case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
+ case GL_IMAGE_CUBE:
+ case GL_INT_IMAGE_CUBE:
+ case GL_UNSIGNED_INT_IMAGE_CUBE:
+ case GL_IMAGE_CUBE_MAP_ARRAY:
+ case GL_INT_IMAGE_CUBE_MAP_ARRAY:
+ case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY:
+ case GL_IMAGE_BUFFER:
+ case GL_INT_IMAGE_BUFFER:
+ case GL_UNSIGNED_INT_SAMPLER_BUFFER:
+ case GL_UNSIGNED_INT_IMAGE_BUFFER:
+ case GL_UNSIGNED_INT_ATOMIC_COUNTER:
+ case GL_SAMPLER_VIDEO_IMAGE_WEBGL:
+ case GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT:
+ return GL_INT;
+ case GL_UNSIGNED_INT:
+ case GL_UNSIGNED_INT_VEC2:
+ case GL_UNSIGNED_INT_VEC3:
+ case GL_UNSIGNED_INT_VEC4:
+ return GL_UNSIGNED_INT;
+ default:
+ UNREACHABLE();
+ }
+
+ return GL_NONE;
+}
+
+size_t VariableComponentSize(GLenum type)
+{
+ switch (type)
+ {
+ case GL_BOOL:
+ return sizeof(GLint);
+ case GL_FLOAT:
+ return sizeof(GLfloat);
+ case GL_INT:
+ return sizeof(GLint);
+ case GL_UNSIGNED_INT:
+ return sizeof(GLuint);
+ default:
+ UNREACHABLE();
+ }
+
+ return 0;
+}
+
+size_t VariableInternalSize(GLenum type)
+{
+ // Expanded to 4-element vectors
+ return VariableComponentSize(VariableComponentType(type)) * VariableRowCount(type) * 4;
+}
+
+size_t VariableExternalSize(GLenum type)
+{
+ return VariableComponentSize(VariableComponentType(type)) * VariableComponentCount(type);
+}
+
+std::string GetGLSLTypeString(GLenum type)
+{
+ switch (type)
+ {
+ case GL_BOOL:
+ return "bool";
+ case GL_INT:
+ return "int";
+ case GL_UNSIGNED_INT:
+ return "uint";
+ case GL_FLOAT:
+ return "float";
+ case GL_BOOL_VEC2:
+ return "bvec2";
+ case GL_BOOL_VEC3:
+ return "bvec3";
+ case GL_BOOL_VEC4:
+ return "bvec4";
+ case GL_INT_VEC2:
+ return "ivec2";
+ case GL_INT_VEC3:
+ return "ivec3";
+ case GL_INT_VEC4:
+ return "ivec4";
+ case GL_FLOAT_VEC2:
+ return "vec2";
+ case GL_FLOAT_VEC3:
+ return "vec3";
+ case GL_FLOAT_VEC4:
+ return "vec4";
+ case GL_UNSIGNED_INT_VEC2:
+ return "uvec2";
+ case GL_UNSIGNED_INT_VEC3:
+ return "uvec3";
+ case GL_UNSIGNED_INT_VEC4:
+ return "uvec4";
+ case GL_FLOAT_MAT2:
+ return "mat2";
+ case GL_FLOAT_MAT3:
+ return "mat3";
+ case GL_FLOAT_MAT4:
+ return "mat4";
+ default:
+ UNREACHABLE();
+ return "";
+ }
+}
+
+GLenum VariableBoolVectorType(GLenum type)
+{
+ switch (type)
+ {
+ case GL_FLOAT:
+ case GL_INT:
+ case GL_UNSIGNED_INT:
+ return GL_BOOL;
+ case GL_FLOAT_VEC2:
+ case GL_INT_VEC2:
+ case GL_UNSIGNED_INT_VEC2:
+ return GL_BOOL_VEC2;
+ case GL_FLOAT_VEC3:
+ case GL_INT_VEC3:
+ case GL_UNSIGNED_INT_VEC3:
+ return GL_BOOL_VEC3;
+ case GL_FLOAT_VEC4:
+ case GL_INT_VEC4:
+ case GL_UNSIGNED_INT_VEC4:
+ return GL_BOOL_VEC4;
+
+ default:
+ UNREACHABLE();
+ return GL_NONE;
+ }
+}
+
+int VariableRowCount(GLenum type)
+{
+ switch (type)
+ {
+ case GL_NONE:
+ return 0;
+ case GL_BOOL:
+ case GL_FLOAT:
+ case GL_INT:
+ case GL_UNSIGNED_INT:
+ case GL_BOOL_VEC2:
+ case GL_FLOAT_VEC2:
+ case GL_INT_VEC2:
+ case GL_UNSIGNED_INT_VEC2:
+ case GL_BOOL_VEC3:
+ case GL_FLOAT_VEC3:
+ case GL_INT_VEC3:
+ case GL_UNSIGNED_INT_VEC3:
+ case GL_BOOL_VEC4:
+ case GL_FLOAT_VEC4:
+ case GL_INT_VEC4:
+ case GL_UNSIGNED_INT_VEC4:
+ case GL_SAMPLER_2D:
+ case GL_SAMPLER_3D:
+ case GL_SAMPLER_CUBE:
+ case GL_SAMPLER_2D_ARRAY:
+ case GL_SAMPLER_EXTERNAL_OES:
+ case GL_SAMPLER_2D_RECT_ANGLE:
+ case GL_SAMPLER_2D_MULTISAMPLE:
+ case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ case GL_SAMPLER_CUBE_MAP_ARRAY:
+ case GL_SAMPLER_BUFFER:
+ case GL_INT_SAMPLER_2D:
+ case GL_INT_SAMPLER_3D:
+ case GL_INT_SAMPLER_CUBE:
+ case GL_INT_SAMPLER_2D_ARRAY:
+ case GL_INT_SAMPLER_2D_MULTISAMPLE:
+ case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ case GL_INT_SAMPLER_CUBE_MAP_ARRAY:
+ case GL_INT_SAMPLER_BUFFER:
+ case GL_UNSIGNED_INT_SAMPLER_2D:
+ case GL_UNSIGNED_INT_SAMPLER_3D:
+ case GL_UNSIGNED_INT_SAMPLER_CUBE:
+ case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
+ case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_BUFFER:
+ case GL_SAMPLER_2D_SHADOW:
+ case GL_SAMPLER_CUBE_SHADOW:
+ case GL_SAMPLER_2D_ARRAY_SHADOW:
+ case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW:
+ case GL_IMAGE_2D:
+ case GL_INT_IMAGE_2D:
+ case GL_UNSIGNED_INT_IMAGE_2D:
+ case GL_IMAGE_2D_ARRAY:
+ case GL_INT_IMAGE_2D_ARRAY:
+ case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
+ case GL_IMAGE_3D:
+ case GL_INT_IMAGE_3D:
+ case GL_UNSIGNED_INT_IMAGE_3D:
+ case GL_IMAGE_CUBE:
+ case GL_INT_IMAGE_CUBE:
+ case GL_UNSIGNED_INT_IMAGE_CUBE:
+ case GL_UNSIGNED_INT_ATOMIC_COUNTER:
+ case GL_IMAGE_CUBE_MAP_ARRAY:
+ case GL_INT_IMAGE_CUBE_MAP_ARRAY:
+ case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY:
+ case GL_IMAGE_BUFFER:
+ case GL_INT_IMAGE_BUFFER:
+ case GL_UNSIGNED_INT_IMAGE_BUFFER:
+ case GL_SAMPLER_VIDEO_IMAGE_WEBGL:
+ case GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT:
+ return 1;
+ case GL_FLOAT_MAT2:
+ case GL_FLOAT_MAT3x2:
+ case GL_FLOAT_MAT4x2:
+ return 2;
+ case GL_FLOAT_MAT3:
+ case GL_FLOAT_MAT2x3:
+ case GL_FLOAT_MAT4x3:
+ return 3;
+ case GL_FLOAT_MAT4:
+ case GL_FLOAT_MAT2x4:
+ case GL_FLOAT_MAT3x4:
+ return 4;
+ default:
+ UNREACHABLE();
+ }
+
+ return 0;
+}
+
+int VariableColumnCount(GLenum type)
+{
+ switch (type)
+ {
+ case GL_NONE:
+ return 0;
+ case GL_BOOL:
+ case GL_FLOAT:
+ case GL_INT:
+ case GL_UNSIGNED_INT:
+ case GL_SAMPLER_2D:
+ case GL_SAMPLER_3D:
+ case GL_SAMPLER_CUBE:
+ case GL_SAMPLER_2D_ARRAY:
+ case GL_SAMPLER_2D_MULTISAMPLE:
+ case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ case GL_SAMPLER_CUBE_MAP_ARRAY:
+ case GL_SAMPLER_BUFFER:
+ case GL_INT_SAMPLER_2D:
+ case GL_INT_SAMPLER_3D:
+ case GL_INT_SAMPLER_CUBE:
+ case GL_INT_SAMPLER_2D_ARRAY:
+ case GL_INT_SAMPLER_2D_MULTISAMPLE:
+ case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ case GL_INT_SAMPLER_CUBE_MAP_ARRAY:
+ case GL_INT_SAMPLER_BUFFER:
+ case GL_SAMPLER_EXTERNAL_OES:
+ case GL_SAMPLER_2D_RECT_ANGLE:
+ case GL_UNSIGNED_INT_SAMPLER_2D:
+ case GL_UNSIGNED_INT_SAMPLER_3D:
+ case GL_UNSIGNED_INT_SAMPLER_CUBE:
+ case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
+ case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_BUFFER:
+ case GL_SAMPLER_2D_SHADOW:
+ case GL_SAMPLER_CUBE_SHADOW:
+ case GL_SAMPLER_2D_ARRAY_SHADOW:
+ case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW:
+ case GL_IMAGE_2D:
+ case GL_INT_IMAGE_2D:
+ case GL_UNSIGNED_INT_IMAGE_2D:
+ case GL_IMAGE_3D:
+ case GL_INT_IMAGE_3D:
+ case GL_UNSIGNED_INT_IMAGE_3D:
+ case GL_IMAGE_2D_ARRAY:
+ case GL_INT_IMAGE_2D_ARRAY:
+ case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
+ case GL_IMAGE_CUBE_MAP_ARRAY:
+ case GL_INT_IMAGE_CUBE_MAP_ARRAY:
+ case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY:
+ case GL_IMAGE_BUFFER:
+ case GL_INT_IMAGE_BUFFER:
+ case GL_UNSIGNED_INT_IMAGE_BUFFER:
+ case GL_IMAGE_CUBE:
+ case GL_INT_IMAGE_CUBE:
+ case GL_UNSIGNED_INT_IMAGE_CUBE:
+ case GL_UNSIGNED_INT_ATOMIC_COUNTER:
+ case GL_SAMPLER_VIDEO_IMAGE_WEBGL:
+ case GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT:
+ return 1;
+ case GL_BOOL_VEC2:
+ case GL_FLOAT_VEC2:
+ case GL_INT_VEC2:
+ case GL_UNSIGNED_INT_VEC2:
+ case GL_FLOAT_MAT2:
+ case GL_FLOAT_MAT2x3:
+ case GL_FLOAT_MAT2x4:
+ return 2;
+ case GL_BOOL_VEC3:
+ case GL_FLOAT_VEC3:
+ case GL_INT_VEC3:
+ case GL_UNSIGNED_INT_VEC3:
+ case GL_FLOAT_MAT3:
+ case GL_FLOAT_MAT3x2:
+ case GL_FLOAT_MAT3x4:
+ return 3;
+ case GL_BOOL_VEC4:
+ case GL_FLOAT_VEC4:
+ case GL_INT_VEC4:
+ case GL_UNSIGNED_INT_VEC4:
+ case GL_FLOAT_MAT4:
+ case GL_FLOAT_MAT4x2:
+ case GL_FLOAT_MAT4x3:
+ return 4;
+ default:
+ UNREACHABLE();
+ }
+
+ return 0;
+}
+
+bool IsSamplerType(GLenum type)
+{
+ switch (type)
+ {
+ case GL_SAMPLER_2D:
+ case GL_SAMPLER_3D:
+ case GL_SAMPLER_CUBE:
+ case GL_SAMPLER_2D_ARRAY:
+ case GL_SAMPLER_EXTERNAL_OES:
+ case GL_SAMPLER_2D_MULTISAMPLE:
+ case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ case GL_SAMPLER_CUBE_MAP_ARRAY:
+ case GL_SAMPLER_BUFFER:
+ case GL_SAMPLER_2D_RECT_ANGLE:
+ case GL_INT_SAMPLER_2D:
+ case GL_INT_SAMPLER_3D:
+ case GL_INT_SAMPLER_CUBE:
+ case GL_INT_SAMPLER_2D_ARRAY:
+ case GL_INT_SAMPLER_2D_MULTISAMPLE:
+ case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ case GL_INT_SAMPLER_CUBE_MAP_ARRAY:
+ case GL_INT_SAMPLER_BUFFER:
+ case GL_UNSIGNED_INT_SAMPLER_2D:
+ case GL_UNSIGNED_INT_SAMPLER_3D:
+ case GL_UNSIGNED_INT_SAMPLER_CUBE:
+ case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
+ case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_BUFFER:
+ case GL_SAMPLER_2D_SHADOW:
+ case GL_SAMPLER_CUBE_SHADOW:
+ case GL_SAMPLER_2D_ARRAY_SHADOW:
+ case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW:
+ case GL_SAMPLER_VIDEO_IMAGE_WEBGL:
+ case GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT:
+ return true;
+ }
+
+ return false;
+}
+
+bool IsSamplerCubeType(GLenum type)
+{
+ switch (type)
+ {
+ case GL_SAMPLER_CUBE:
+ case GL_INT_SAMPLER_CUBE:
+ case GL_UNSIGNED_INT_SAMPLER_CUBE:
+ case GL_SAMPLER_CUBE_SHADOW:
+ return true;
+ }
+
+ return false;
+}
+
+bool IsSamplerYUVType(GLenum type)
+{
+ switch (type)
+ {
+ case GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+bool IsImageType(GLenum type)
+{
+ switch (type)
+ {
+ case GL_IMAGE_2D:
+ case GL_INT_IMAGE_2D:
+ case GL_UNSIGNED_INT_IMAGE_2D:
+ case GL_IMAGE_3D:
+ case GL_INT_IMAGE_3D:
+ case GL_UNSIGNED_INT_IMAGE_3D:
+ case GL_IMAGE_2D_ARRAY:
+ case GL_INT_IMAGE_2D_ARRAY:
+ case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
+ case GL_IMAGE_CUBE_MAP_ARRAY:
+ case GL_INT_IMAGE_CUBE_MAP_ARRAY:
+ case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY:
+ case GL_IMAGE_BUFFER:
+ case GL_INT_IMAGE_BUFFER:
+ case GL_UNSIGNED_INT_IMAGE_BUFFER:
+ case GL_IMAGE_CUBE:
+ case GL_INT_IMAGE_CUBE:
+ case GL_UNSIGNED_INT_IMAGE_CUBE:
+ return true;
+ }
+ return false;
+}
+
+bool IsImage2DType(GLenum type)
+{
+ switch (type)
+ {
+ case GL_IMAGE_2D:
+ case GL_INT_IMAGE_2D:
+ case GL_UNSIGNED_INT_IMAGE_2D:
+ return true;
+ case GL_IMAGE_3D:
+ case GL_INT_IMAGE_3D:
+ case GL_UNSIGNED_INT_IMAGE_3D:
+ case GL_IMAGE_2D_ARRAY:
+ case GL_INT_IMAGE_2D_ARRAY:
+ case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
+ case GL_IMAGE_CUBE_MAP_ARRAY:
+ case GL_INT_IMAGE_CUBE_MAP_ARRAY:
+ case GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY:
+ case GL_IMAGE_CUBE:
+ case GL_INT_IMAGE_CUBE:
+ case GL_UNSIGNED_INT_IMAGE_CUBE:
+ case GL_IMAGE_BUFFER:
+ case GL_INT_IMAGE_BUFFER:
+ case GL_UNSIGNED_INT_IMAGE_BUFFER:
+ return false;
+ default:
+ UNREACHABLE();
+ return false;
+ }
+}
+
+bool IsAtomicCounterType(GLenum type)
+{
+ return type == GL_UNSIGNED_INT_ATOMIC_COUNTER;
+}
+
+bool IsOpaqueType(GLenum type)
+{
+ // ESSL 3.10 section 4.1.7 defines opaque types as: samplers, images and atomic counters.
+ return IsImageType(type) || IsSamplerType(type) || IsAtomicCounterType(type);
+}
+
+bool IsMatrixType(GLenum type)
+{
+ return VariableRowCount(type) > 1;
+}
+
+GLenum TransposeMatrixType(GLenum type)
+{
+ if (!IsMatrixType(type))
+ {
+ return type;
+ }
+
+ switch (type)
+ {
+ case GL_FLOAT_MAT2:
+ return GL_FLOAT_MAT2;
+ case GL_FLOAT_MAT3:
+ return GL_FLOAT_MAT3;
+ case GL_FLOAT_MAT4:
+ return GL_FLOAT_MAT4;
+ case GL_FLOAT_MAT2x3:
+ return GL_FLOAT_MAT3x2;
+ case GL_FLOAT_MAT3x2:
+ return GL_FLOAT_MAT2x3;
+ case GL_FLOAT_MAT2x4:
+ return GL_FLOAT_MAT4x2;
+ case GL_FLOAT_MAT4x2:
+ return GL_FLOAT_MAT2x4;
+ case GL_FLOAT_MAT3x4:
+ return GL_FLOAT_MAT4x3;
+ case GL_FLOAT_MAT4x3:
+ return GL_FLOAT_MAT3x4;
+ default:
+ UNREACHABLE();
+ return GL_NONE;
+ }
+}
+
+int MatrixRegisterCount(GLenum type, bool isRowMajorMatrix)
+{
+ ASSERT(IsMatrixType(type));
+ return isRowMajorMatrix ? VariableRowCount(type) : VariableColumnCount(type);
+}
+
+int MatrixComponentCount(GLenum type, bool isRowMajorMatrix)
+{
+ ASSERT(IsMatrixType(type));
+ return isRowMajorMatrix ? VariableColumnCount(type) : VariableRowCount(type);
+}
+
+int VariableRegisterCount(GLenum type)
+{
+ return IsMatrixType(type) ? VariableColumnCount(type) : 1;
+}
+
+int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize)
+{
+ ASSERT(allocationSize <= bitsSize);
+
+ unsigned int mask = std::numeric_limits<unsigned int>::max() >>
+ (std::numeric_limits<unsigned int>::digits - allocationSize);
+
+ for (unsigned int i = 0; i < bitsSize - allocationSize + 1; i++)
+ {
+ if ((*bits & mask) == 0)
+ {
+ *bits |= mask;
+ return i;
+ }
+
+ mask <<= 1;
+ }
+
+ return -1;
+}
+
+IndexRange ComputeIndexRange(DrawElementsType indexType,
+ const GLvoid *indices,
+ size_t count,
+ bool primitiveRestartEnabled)
+{
+ switch (indexType)
+ {
+ case DrawElementsType::UnsignedByte:
+ return ComputeTypedIndexRange(static_cast<const GLubyte *>(indices), count,
+ primitiveRestartEnabled,
+ GetPrimitiveRestartIndex(indexType));
+ case DrawElementsType::UnsignedShort:
+ return ComputeTypedIndexRange(static_cast<const GLushort *>(indices), count,
+ primitiveRestartEnabled,
+ GetPrimitiveRestartIndex(indexType));
+ case DrawElementsType::UnsignedInt:
+ return ComputeTypedIndexRange(static_cast<const GLuint *>(indices), count,
+ primitiveRestartEnabled,
+ GetPrimitiveRestartIndex(indexType));
+ default:
+ UNREACHABLE();
+ return IndexRange();
+ }
+}
+
+GLuint GetPrimitiveRestartIndex(DrawElementsType indexType)
+{
+ switch (indexType)
+ {
+ case DrawElementsType::UnsignedByte:
+ return 0xFF;
+ case DrawElementsType::UnsignedShort:
+ return 0xFFFF;
+ case DrawElementsType::UnsignedInt:
+ return 0xFFFFFFFF;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+bool IsTriangleMode(PrimitiveMode drawMode)
+{
+ switch (drawMode)
+ {
+ case PrimitiveMode::Triangles:
+ case PrimitiveMode::TriangleFan:
+ case PrimitiveMode::TriangleStrip:
+ return true;
+ case PrimitiveMode::Points:
+ case PrimitiveMode::Lines:
+ case PrimitiveMode::LineLoop:
+ case PrimitiveMode::LineStrip:
+ return false;
+ default:
+ UNREACHABLE();
+ }
+
+ return false;
+}
+
+bool IsPolygonMode(PrimitiveMode mode)
+{
+ switch (mode)
+ {
+ case PrimitiveMode::Points:
+ case PrimitiveMode::Lines:
+ case PrimitiveMode::LineStrip:
+ case PrimitiveMode::LineLoop:
+ case PrimitiveMode::LinesAdjacency:
+ case PrimitiveMode::LineStripAdjacency:
+ return false;
+ default:
+ break;
+ }
+
+ return true;
+}
+
+namespace priv
+{
+const angle::PackedEnumMap<PrimitiveMode, bool> gLineModes = {
+ {{PrimitiveMode::LineLoop, true},
+ {PrimitiveMode::LineStrip, true},
+ {PrimitiveMode::LineStripAdjacency, true},
+ {PrimitiveMode::Lines, true}}};
+} // namespace priv
+
+bool IsIntegerFormat(GLenum unsizedFormat)
+{
+ switch (unsizedFormat)
+ {
+ case GL_RGBA_INTEGER:
+ case GL_RGB_INTEGER:
+ case GL_RG_INTEGER:
+ case GL_RED_INTEGER:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+// [OpenGL ES SL 3.00.4] Section 11 p. 120
+// Vertex Outs/Fragment Ins packing priorities
+int VariableSortOrder(GLenum type)
+{
+ switch (type)
+ {
+ // 1. Arrays of mat4 and mat4
+ // Non-square matrices of type matCxR consume the same space as a square
+ // matrix of type matN where N is the greater of C and R
+ case GL_FLOAT_MAT4:
+ case GL_FLOAT_MAT2x4:
+ case GL_FLOAT_MAT3x4:
+ case GL_FLOAT_MAT4x2:
+ case GL_FLOAT_MAT4x3:
+ return 0;
+
+ // 2. Arrays of mat2 and mat2 (since they occupy full rows)
+ case GL_FLOAT_MAT2:
+ return 1;
+
+ // 3. Arrays of vec4 and vec4
+ case GL_FLOAT_VEC4:
+ case GL_INT_VEC4:
+ case GL_BOOL_VEC4:
+ case GL_UNSIGNED_INT_VEC4:
+ return 2;
+
+ // 4. Arrays of mat3 and mat3
+ case GL_FLOAT_MAT3:
+ case GL_FLOAT_MAT2x3:
+ case GL_FLOAT_MAT3x2:
+ return 3;
+
+ // 5. Arrays of vec3 and vec3
+ case GL_FLOAT_VEC3:
+ case GL_INT_VEC3:
+ case GL_BOOL_VEC3:
+ case GL_UNSIGNED_INT_VEC3:
+ return 4;
+
+ // 6. Arrays of vec2 and vec2
+ case GL_FLOAT_VEC2:
+ case GL_INT_VEC2:
+ case GL_BOOL_VEC2:
+ case GL_UNSIGNED_INT_VEC2:
+ return 5;
+
+ // 7. Single component types
+ case GL_FLOAT:
+ case GL_INT:
+ case GL_BOOL:
+ case GL_UNSIGNED_INT:
+ case GL_SAMPLER_2D:
+ case GL_SAMPLER_CUBE:
+ case GL_SAMPLER_EXTERNAL_OES:
+ case GL_SAMPLER_2D_RECT_ANGLE:
+ case GL_SAMPLER_2D_ARRAY:
+ case GL_SAMPLER_2D_MULTISAMPLE:
+ case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ case GL_SAMPLER_3D:
+ case GL_INT_SAMPLER_2D:
+ case GL_INT_SAMPLER_3D:
+ case GL_INT_SAMPLER_CUBE:
+ case GL_INT_SAMPLER_2D_ARRAY:
+ case GL_INT_SAMPLER_2D_MULTISAMPLE:
+ case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_2D:
+ case GL_UNSIGNED_INT_SAMPLER_3D:
+ case GL_UNSIGNED_INT_SAMPLER_CUBE:
+ case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
+ case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
+ case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
+ case GL_SAMPLER_2D_SHADOW:
+ case GL_SAMPLER_2D_ARRAY_SHADOW:
+ case GL_SAMPLER_CUBE_SHADOW:
+ case GL_IMAGE_2D:
+ case GL_INT_IMAGE_2D:
+ case GL_UNSIGNED_INT_IMAGE_2D:
+ case GL_IMAGE_3D:
+ case GL_INT_IMAGE_3D:
+ case GL_UNSIGNED_INT_IMAGE_3D:
+ case GL_IMAGE_2D_ARRAY:
+ case GL_INT_IMAGE_2D_ARRAY:
+ case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
+ case GL_IMAGE_CUBE:
+ case GL_INT_IMAGE_CUBE:
+ case GL_UNSIGNED_INT_IMAGE_CUBE:
+ case GL_UNSIGNED_INT_ATOMIC_COUNTER:
+ case GL_SAMPLER_VIDEO_IMAGE_WEBGL:
+ case GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT:
+ return 6;
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+std::string ParseResourceName(const std::string &name, std::vector<unsigned int> *outSubscripts)
+{
+ if (outSubscripts)
+ {
+ outSubscripts->clear();
+ }
+ // Strip any trailing array indexing operators and retrieve the subscripts.
+ size_t baseNameLength = name.length();
+ bool hasIndex = true;
+ while (hasIndex)
+ {
+ size_t open = name.find_last_of('[', baseNameLength - 1);
+ size_t close = name.find_last_of(']', baseNameLength - 1);
+ hasIndex = (open != std::string::npos) && (close == baseNameLength - 1);
+ if (hasIndex)
+ {
+ baseNameLength = open;
+ if (outSubscripts)
+ {
+ int index = atoi(name.substr(open + 1).c_str());
+ if (index >= 0)
+ {
+ outSubscripts->push_back(index);
+ }
+ else
+ {
+ outSubscripts->push_back(GL_INVALID_INDEX);
+ }
+ }
+ }
+ }
+
+ return name.substr(0, baseNameLength);
+}
+
+bool IsBuiltInName(const char *name)
+{
+ return angle::BeginsWith(name, "gl_");
+}
+
+std::string StripLastArrayIndex(const std::string &name)
+{
+ size_t strippedNameLength = name.find_last_of('[');
+ if (strippedNameLength != std::string::npos && name.back() == ']')
+ {
+ return name.substr(0, strippedNameLength);
+ }
+ return name;
+}
+
+bool SamplerNameContainsNonZeroArrayElement(const std::string &name)
+{
+ constexpr char kZERO_ELEMENT[] = "[0]";
+
+ size_t start = 0;
+ while (true)
+ {
+ start = name.find(kZERO_ELEMENT[0], start);
+ if (start == std::string::npos)
+ {
+ break;
+ }
+ if (name.compare(start, strlen(kZERO_ELEMENT), kZERO_ELEMENT) != 0)
+ {
+ return true;
+ }
+ start++;
+ }
+ return false;
+}
+
+unsigned int ArraySizeProduct(const std::vector<unsigned int> &arraySizes)
+{
+ unsigned int arraySizeProduct = 1u;
+ for (unsigned int arraySize : arraySizes)
+ {
+ arraySizeProduct *= arraySize;
+ }
+ return arraySizeProduct;
+}
+
+unsigned int InnerArraySizeProduct(const std::vector<unsigned int> &arraySizes)
+{
+ unsigned int arraySizeProduct = 1u;
+ for (size_t index = 0; index + 1 < arraySizes.size(); ++index)
+ {
+ arraySizeProduct *= arraySizes[index];
+ }
+ return arraySizeProduct;
+}
+
+unsigned int OutermostArraySize(const std::vector<unsigned int> &arraySizes)
+{
+ return arraySizes.empty() || arraySizes.back() == 0 ? 1 : arraySizes.back();
+}
+
+unsigned int ParseArrayIndex(const std::string &name, size_t *nameLengthWithoutArrayIndexOut)
+{
+ ASSERT(nameLengthWithoutArrayIndexOut != nullptr);
+
+ // Strip any trailing array operator and retrieve the subscript
+ size_t open = name.find_last_of('[');
+ if (open != std::string::npos && name.back() == ']')
+ {
+ bool indexIsValidDecimalNumber = true;
+ for (size_t i = open + 1; i < name.length() - 1u; ++i)
+ {
+ if (!isdigit(name[i]))
+ {
+ indexIsValidDecimalNumber = false;
+ break;
+ }
+
+ // Leading zeroes are invalid
+ if ((i == (open + 1)) && (name[i] == '0') && (name[i + 1] != ']'))
+ {
+ indexIsValidDecimalNumber = false;
+ break;
+ }
+ }
+ if (indexIsValidDecimalNumber)
+ {
+ errno = 0; // reset global error flag.
+ unsigned long subscript =
+ strtoul(name.c_str() + open + 1, /*endptr*/ nullptr, /*radix*/ 10);
+
+ // Check if resulting integer is out-of-range or conversion error.
+ if (angle::base::IsValueInRangeForNumericType<uint32_t>(subscript) &&
+ !(subscript == ULONG_MAX && errno == ERANGE) && !(errno != 0 && subscript == 0))
+ {
+ *nameLengthWithoutArrayIndexOut = open;
+ return static_cast<unsigned int>(subscript);
+ }
+ }
+ }
+
+ *nameLengthWithoutArrayIndexOut = name.length();
+ return GL_INVALID_INDEX;
+}
+
+const char *GetGenericErrorMessage(GLenum error)
+{
+ switch (error)
+ {
+ case GL_NO_ERROR:
+ return "";
+ case GL_INVALID_ENUM:
+ return "Invalid enum.";
+ case GL_INVALID_VALUE:
+ return "Invalid value.";
+ case GL_INVALID_OPERATION:
+ return "Invalid operation.";
+ case GL_STACK_OVERFLOW:
+ return "Stack overflow.";
+ case GL_STACK_UNDERFLOW:
+ return "Stack underflow.";
+ case GL_OUT_OF_MEMORY:
+ return "Out of memory.";
+ case GL_INVALID_FRAMEBUFFER_OPERATION:
+ return "Invalid framebuffer operation.";
+ default:
+ UNREACHABLE();
+ return "Unknown error.";
+ }
+}
+
+unsigned int ElementTypeSize(GLenum elementType)
+{
+ switch (elementType)
+ {
+ case GL_UNSIGNED_BYTE:
+ return sizeof(GLubyte);
+ case GL_UNSIGNED_SHORT:
+ return sizeof(GLushort);
+ case GL_UNSIGNED_INT:
+ return sizeof(GLuint);
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+bool IsMipmapFiltered(GLenum minFilterMode)
+{
+ switch (minFilterMode)
+ {
+ case GL_NEAREST:
+ case GL_LINEAR:
+ return false;
+ case GL_NEAREST_MIPMAP_NEAREST:
+ case GL_LINEAR_MIPMAP_NEAREST:
+ case GL_NEAREST_MIPMAP_LINEAR:
+ case GL_LINEAR_MIPMAP_LINEAR:
+ return true;
+ default:
+ UNREACHABLE();
+ return false;
+ }
+}
+
+PipelineType GetPipelineType(ShaderType type)
+{
+ switch (type)
+ {
+ case ShaderType::Vertex:
+ case ShaderType::Fragment:
+ case ShaderType::Geometry:
+ return PipelineType::GraphicsPipeline;
+ case ShaderType::Compute:
+ return PipelineType::ComputePipeline;
+ default:
+ UNREACHABLE();
+ return PipelineType::GraphicsPipeline;
+ }
+}
+
+const char *GetDebugMessageSourceString(GLenum source)
+{
+ switch (source)
+ {
+ case GL_DEBUG_SOURCE_API:
+ return "API";
+ case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
+ return "Window System";
+ case GL_DEBUG_SOURCE_SHADER_COMPILER:
+ return "Shader Compiler";
+ case GL_DEBUG_SOURCE_THIRD_PARTY:
+ return "Third Party";
+ case GL_DEBUG_SOURCE_APPLICATION:
+ return "Application";
+ case GL_DEBUG_SOURCE_OTHER:
+ return "Other";
+ default:
+ return "Unknown Source";
+ }
+}
+
+const char *GetDebugMessageTypeString(GLenum type)
+{
+ switch (type)
+ {
+ case GL_DEBUG_TYPE_ERROR:
+ return "Error";
+ case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
+ return "Deprecated behavior";
+ case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
+ return "Undefined behavior";
+ case GL_DEBUG_TYPE_PORTABILITY:
+ return "Portability";
+ case GL_DEBUG_TYPE_PERFORMANCE:
+ return "Performance";
+ case GL_DEBUG_TYPE_OTHER:
+ return "Other";
+ case GL_DEBUG_TYPE_MARKER:
+ return "Marker";
+ default:
+ return "Unknown Type";
+ }
+}
+
+const char *GetDebugMessageSeverityString(GLenum severity)
+{
+ switch (severity)
+ {
+ case GL_DEBUG_SEVERITY_HIGH:
+ return "High";
+ case GL_DEBUG_SEVERITY_MEDIUM:
+ return "Medium";
+ case GL_DEBUG_SEVERITY_LOW:
+ return "Low";
+ case GL_DEBUG_SEVERITY_NOTIFICATION:
+ return "Notification";
+ default:
+ return "Unknown Severity";
+ }
+}
+
+ShaderType GetShaderTypeFromBitfield(size_t singleShaderType)
+{
+ switch (singleShaderType)
+ {
+ case GL_VERTEX_SHADER_BIT:
+ return ShaderType::Vertex;
+ case GL_FRAGMENT_SHADER_BIT:
+ return ShaderType::Fragment;
+ case GL_COMPUTE_SHADER_BIT:
+ return ShaderType::Compute;
+ case GL_GEOMETRY_SHADER_BIT:
+ return ShaderType::Geometry;
+ case GL_TESS_CONTROL_SHADER_BIT:
+ return ShaderType::TessControl;
+ case GL_TESS_EVALUATION_SHADER_BIT:
+ return ShaderType::TessEvaluation;
+ default:
+ return ShaderType::InvalidEnum;
+ }
+}
+
+GLbitfield GetBitfieldFromShaderType(ShaderType shaderType)
+{
+ switch (shaderType)
+ {
+ case ShaderType::Vertex:
+ return GL_VERTEX_SHADER_BIT;
+ case ShaderType::Fragment:
+ return GL_FRAGMENT_SHADER_BIT;
+ case ShaderType::Compute:
+ return GL_COMPUTE_SHADER_BIT;
+ case ShaderType::Geometry:
+ return GL_GEOMETRY_SHADER_BIT;
+ case ShaderType::TessControl:
+ return GL_TESS_CONTROL_SHADER_BIT;
+ case ShaderType::TessEvaluation:
+ return GL_TESS_EVALUATION_SHADER_BIT;
+ default:
+ UNREACHABLE();
+ return GL_ZERO;
+ }
+}
+
+bool ShaderTypeSupportsTransformFeedback(ShaderType shaderType)
+{
+ switch (shaderType)
+ {
+ case ShaderType::Vertex:
+ case ShaderType::Geometry:
+ case ShaderType::TessEvaluation:
+ return true;
+ default:
+ return false;
+ }
+}
+
+ShaderType GetLastPreFragmentStage(ShaderBitSet shaderTypes)
+{
+ shaderTypes.reset(ShaderType::Fragment);
+ shaderTypes.reset(ShaderType::Compute);
+ return shaderTypes.any() ? shaderTypes.last() : ShaderType::InvalidEnum;
+}
+} // namespace gl
+
+namespace egl
+{
+static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 1,
+ "Unexpected EGL cube map enum value.");
+static_assert(EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 2,
+ "Unexpected EGL cube map enum value.");
+static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 3,
+ "Unexpected EGL cube map enum value.");
+static_assert(EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 4,
+ "Unexpected EGL cube map enum value.");
+static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 5,
+ "Unexpected EGL cube map enum value.");
+
+bool IsCubeMapTextureTarget(EGLenum target)
+{
+ return (target >= FirstCubeMapTextureTarget && target <= LastCubeMapTextureTarget);
+}
+
+size_t CubeMapTextureTargetToLayerIndex(EGLenum target)
+{
+ ASSERT(IsCubeMapTextureTarget(target));
+ return target - static_cast<size_t>(FirstCubeMapTextureTarget);
+}
+
+EGLenum LayerIndexToCubeMapTextureTarget(size_t index)
+{
+ ASSERT(index <= (LastCubeMapTextureTarget - FirstCubeMapTextureTarget));
+ return FirstCubeMapTextureTarget + static_cast<GLenum>(index);
+}
+
+bool IsTextureTarget(EGLenum target)
+{
+ switch (target)
+ {
+ case EGL_GL_TEXTURE_2D_KHR:
+ case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
+ case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
+ case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
+ case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
+ case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
+ case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
+ case EGL_GL_TEXTURE_3D_KHR:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+bool IsRenderbufferTarget(EGLenum target)
+{
+ return target == EGL_GL_RENDERBUFFER_KHR;
+}
+
+bool IsExternalImageTarget(EGLenum target)
+{
+ switch (target)
+ {
+ case EGL_NATIVE_BUFFER_ANDROID:
+ case EGL_D3D11_TEXTURE_ANGLE:
+ case EGL_LINUX_DMA_BUF_EXT:
+ case EGL_METAL_TEXTURE_ANGLE:
+ case EGL_VULKAN_IMAGE_ANGLE:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+const char *GetGenericErrorMessage(EGLint error)
+{
+ switch (error)
+ {
+ case EGL_SUCCESS:
+ return "";
+ case EGL_NOT_INITIALIZED:
+ return "Not initialized.";
+ case EGL_BAD_ACCESS:
+ return "Bad access.";
+ case EGL_BAD_ALLOC:
+ return "Bad allocation.";
+ case EGL_BAD_ATTRIBUTE:
+ return "Bad attribute.";
+ case EGL_BAD_CONFIG:
+ return "Bad config.";
+ case EGL_BAD_CONTEXT:
+ return "Bad context.";
+ case EGL_BAD_CURRENT_SURFACE:
+ return "Bad current surface.";
+ case EGL_BAD_DISPLAY:
+ return "Bad display.";
+ case EGL_BAD_MATCH:
+ return "Bad match.";
+ case EGL_BAD_NATIVE_WINDOW:
+ return "Bad native window.";
+ case EGL_BAD_NATIVE_PIXMAP:
+ return "Bad native pixmap.";
+ case EGL_BAD_PARAMETER:
+ return "Bad parameter.";
+ case EGL_BAD_SURFACE:
+ return "Bad surface.";
+ case EGL_CONTEXT_LOST:
+ return "Context lost.";
+ case EGL_BAD_STREAM_KHR:
+ return "Bad stream.";
+ case EGL_BAD_STATE_KHR:
+ return "Bad state.";
+ case EGL_BAD_DEVICE_EXT:
+ return "Bad device.";
+ default:
+ UNREACHABLE();
+ return "Unknown error.";
+ }
+}
+
+} // namespace egl
+
+namespace egl_gl
+{
+GLuint EGLClientBufferToGLObjectHandle(EGLClientBuffer buffer)
+{
+ return static_cast<GLuint>(reinterpret_cast<uintptr_t>(buffer));
+}
+} // namespace egl_gl
+
+namespace gl_egl
+{
+EGLenum GLComponentTypeToEGLColorComponentType(GLenum glComponentType)
+{
+ switch (glComponentType)
+ {
+ case GL_FLOAT:
+ return EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT;
+
+ case GL_UNSIGNED_NORMALIZED:
+ return EGL_COLOR_COMPONENT_TYPE_FIXED_EXT;
+
+ default:
+ UNREACHABLE();
+ return EGL_NONE;
+ }
+}
+
+EGLClientBuffer GLObjectHandleToEGLClientBuffer(GLuint handle)
+{
+ return reinterpret_cast<EGLClientBuffer>(static_cast<uintptr_t>(handle));
+}
+
+} // namespace gl_egl
+
+namespace angle
+{
+bool IsDrawEntryPoint(EntryPoint entryPoint)
+{
+ switch (entryPoint)
+ {
+ case EntryPoint::GLDrawArrays:
+ case EntryPoint::GLDrawArraysIndirect:
+ case EntryPoint::GLDrawArraysInstanced:
+ case EntryPoint::GLDrawArraysInstancedANGLE:
+ case EntryPoint::GLDrawArraysInstancedBaseInstance:
+ case EntryPoint::GLDrawArraysInstancedBaseInstanceANGLE:
+ case EntryPoint::GLDrawArraysInstancedEXT:
+ case EntryPoint::GLDrawElements:
+ case EntryPoint::GLDrawElementsBaseVertex:
+ case EntryPoint::GLDrawElementsBaseVertexEXT:
+ case EntryPoint::GLDrawElementsBaseVertexOES:
+ case EntryPoint::GLDrawElementsIndirect:
+ case EntryPoint::GLDrawElementsInstanced:
+ case EntryPoint::GLDrawElementsInstancedANGLE:
+ case EntryPoint::GLDrawElementsInstancedBaseInstance:
+ case EntryPoint::GLDrawElementsInstancedBaseVertex:
+ case EntryPoint::GLDrawElementsInstancedBaseVertexBaseInstance:
+ case EntryPoint::GLDrawElementsInstancedBaseVertexBaseInstanceANGLE:
+ case EntryPoint::GLDrawElementsInstancedBaseVertexEXT:
+ case EntryPoint::GLDrawElementsInstancedBaseVertexOES:
+ case EntryPoint::GLDrawElementsInstancedEXT:
+ case EntryPoint::GLDrawPixels:
+ case EntryPoint::GLDrawRangeElements:
+ case EntryPoint::GLDrawRangeElementsBaseVertex:
+ case EntryPoint::GLDrawRangeElementsBaseVertexEXT:
+ case EntryPoint::GLDrawRangeElementsBaseVertexOES:
+ case EntryPoint::GLDrawTexfOES:
+ case EntryPoint::GLDrawTexfvOES:
+ case EntryPoint::GLDrawTexiOES:
+ case EntryPoint::GLDrawTexivOES:
+ case EntryPoint::GLDrawTexsOES:
+ case EntryPoint::GLDrawTexsvOES:
+ case EntryPoint::GLDrawTexxOES:
+ case EntryPoint::GLDrawTexxvOES:
+ case EntryPoint::GLDrawTransformFeedback:
+ case EntryPoint::GLDrawTransformFeedbackInstanced:
+ case EntryPoint::GLDrawTransformFeedbackStream:
+ case EntryPoint::GLDrawTransformFeedbackStreamInstanced:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool IsDispatchEntryPoint(EntryPoint entryPoint)
+{
+ switch (entryPoint)
+ {
+ case EntryPoint::GLDispatchCompute:
+ case EntryPoint::GLDispatchComputeIndirect:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool IsClearEntryPoint(EntryPoint entryPoint)
+{
+ switch (entryPoint)
+ {
+ case EntryPoint::GLClear:
+ case EntryPoint::GLClearBufferfi:
+ case EntryPoint::GLClearBufferfv:
+ case EntryPoint::GLClearBufferiv:
+ case EntryPoint::GLClearBufferuiv:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool IsQueryEntryPoint(EntryPoint entryPoint)
+{
+ switch (entryPoint)
+ {
+ case EntryPoint::GLBeginQuery:
+ case EntryPoint::GLBeginQueryEXT:
+ case EntryPoint::GLBeginQueryIndexed:
+ case EntryPoint::GLEndQuery:
+ case EntryPoint::GLEndQueryEXT:
+ case EntryPoint::GLEndQueryIndexed:
+ return true;
+ default:
+ return false;
+ }
+}
+} // namespace angle
+
+#if !defined(ANGLE_ENABLE_WINDOWS_UWP)
+void writeFile(const char *path, const void *content, size_t size)
+{
+ FILE *file = fopen(path, "w");
+ if (!file)
+ {
+ UNREACHABLE();
+ return;
+ }
+
+ fwrite(content, sizeof(char), size, file);
+ fclose(file);
+}
+#endif // !ANGLE_ENABLE_WINDOWS_UWP
+
+#if defined(ANGLE_PLATFORM_WINDOWS)
+
+// Causes the thread to relinquish the remainder of its time slice to any
+// other thread that is ready to run.If there are no other threads ready
+// to run, the function returns immediately, and the thread continues execution.
+void ScheduleYield()
+{
+ Sleep(0);
+}
+
+#endif
diff --git a/gfx/angle/checkout/src/common/utilities.h b/gfx/angle/checkout/src/common/utilities.h
new file mode 100644
index 0000000000..cae620d03b
--- /dev/null
+++ b/gfx/angle/checkout/src/common/utilities.h
@@ -0,0 +1,336 @@
+//
+// Copyright 2002 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.
+//
+
+// utilities.h: Conversion functions and other utility routines.
+
+#ifndef COMMON_UTILITIES_H_
+#define COMMON_UTILITIES_H_
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLSLANG/ShaderLang.h>
+
+#include <math.h>
+#include <string>
+#include <vector>
+
+#include "angle_gl.h"
+
+#include "common/PackedEnums.h"
+#include "common/mathutil.h"
+#include "common/platform.h"
+
+namespace sh
+{
+struct ShaderVariable;
+}
+
+constexpr bool ShPixelLocalStorageTypeUsesImages(ShPixelLocalStorageType type)
+{
+ return type == ShPixelLocalStorageType::ImageStoreR32PackedFormats ||
+ type == ShPixelLocalStorageType::ImageStoreNativeFormats;
+}
+
+namespace gl
+{
+
+int VariableComponentCount(GLenum type);
+GLenum VariableComponentType(GLenum type);
+size_t VariableComponentSize(GLenum type);
+size_t VariableInternalSize(GLenum type);
+size_t VariableExternalSize(GLenum type);
+int VariableRowCount(GLenum type);
+int VariableColumnCount(GLenum type);
+bool IsSamplerType(GLenum type);
+bool IsSamplerCubeType(GLenum type);
+bool IsSamplerYUVType(GLenum type);
+bool IsImageType(GLenum type);
+bool IsImage2DType(GLenum type);
+bool IsAtomicCounterType(GLenum type);
+bool IsOpaqueType(GLenum type);
+bool IsMatrixType(GLenum type);
+GLenum TransposeMatrixType(GLenum type);
+int VariableRegisterCount(GLenum type);
+int MatrixRegisterCount(GLenum type, bool isRowMajorMatrix);
+int MatrixComponentCount(GLenum type, bool isRowMajorMatrix);
+int VariableSortOrder(GLenum type);
+GLenum VariableBoolVectorType(GLenum type);
+std::string GetGLSLTypeString(GLenum type);
+
+int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize);
+
+// Parse the base resource name and array indices. Returns the base name of the resource.
+// If the provided name doesn't index an array, the outSubscripts vector will be empty.
+// If the provided name indexes an array, the outSubscripts vector will contain indices with
+// outermost array indices in the back. If an array index is invalid, GL_INVALID_INDEX is added to
+// outSubscripts.
+std::string ParseResourceName(const std::string &name, std::vector<unsigned int> *outSubscripts);
+
+bool IsBuiltInName(const char *name);
+ANGLE_INLINE bool IsBuiltInName(const std::string &name)
+{
+ return IsBuiltInName(name.c_str());
+}
+
+// Strips only the last array index from a resource name.
+std::string StripLastArrayIndex(const std::string &name);
+
+bool SamplerNameContainsNonZeroArrayElement(const std::string &name);
+
+// Find the range of index values in the provided indices pointer. Primitive restart indices are
+// only counted in the range if primitive restart is disabled.
+IndexRange ComputeIndexRange(DrawElementsType indexType,
+ const GLvoid *indices,
+ size_t count,
+ bool primitiveRestartEnabled);
+
+// Get the primitive restart index value for the given index type.
+GLuint GetPrimitiveRestartIndex(DrawElementsType indexType);
+
+// Get the primitive restart index value with the given C++ type.
+template <typename T>
+constexpr T GetPrimitiveRestartIndexFromType()
+{
+ return std::numeric_limits<T>::max();
+}
+
+static_assert(GetPrimitiveRestartIndexFromType<uint8_t>() == 0xFF,
+ "verify restart index for uint8_t values");
+static_assert(GetPrimitiveRestartIndexFromType<uint16_t>() == 0xFFFF,
+ "verify restart index for uint8_t values");
+static_assert(GetPrimitiveRestartIndexFromType<uint32_t>() == 0xFFFFFFFF,
+ "verify restart index for uint8_t values");
+
+bool IsTriangleMode(PrimitiveMode drawMode);
+bool IsPolygonMode(PrimitiveMode mode);
+
+namespace priv
+{
+extern const angle::PackedEnumMap<PrimitiveMode, bool> gLineModes;
+} // namespace priv
+
+ANGLE_INLINE bool IsLineMode(PrimitiveMode primitiveMode)
+{
+ return priv::gLineModes[primitiveMode];
+}
+
+bool IsIntegerFormat(GLenum unsizedFormat);
+
+// Returns the product of the sizes in the vector, or 1 if the vector is empty. Doesn't currently
+// perform overflow checks.
+unsigned int ArraySizeProduct(const std::vector<unsigned int> &arraySizes);
+// Returns the product of the sizes in the vector except for the outermost dimension, or 1 if the
+// vector is empty.
+unsigned int InnerArraySizeProduct(const std::vector<unsigned int> &arraySizes);
+// Returns the outermost array dimension, or 1 if the vector is empty.
+unsigned int OutermostArraySize(const std::vector<unsigned int> &arraySizes);
+
+// Return the array index at the end of name, and write the length of name before the final array
+// index into nameLengthWithoutArrayIndexOut. In case name doesn't include an array index, return
+// GL_INVALID_INDEX and write the length of the original string.
+unsigned int ParseArrayIndex(const std::string &name, size_t *nameLengthWithoutArrayIndexOut);
+
+enum class SamplerFormat : uint8_t
+{
+ Float = 0,
+ Unsigned = 1,
+ Signed = 2,
+ Shadow = 3,
+
+ InvalidEnum = 4,
+ EnumCount = 4,
+};
+
+struct UniformTypeInfo final : angle::NonCopyable
+{
+ inline constexpr UniformTypeInfo(GLenum type,
+ GLenum componentType,
+ GLenum textureType,
+ GLenum transposedMatrixType,
+ GLenum boolVectorType,
+ SamplerFormat samplerFormat,
+ int rowCount,
+ int columnCount,
+ int componentCount,
+ size_t componentSize,
+ size_t internalSize,
+ size_t externalSize,
+ bool isSampler,
+ bool isMatrixType,
+ bool isImageType);
+
+ GLenum type;
+ GLenum componentType;
+ GLenum textureType;
+ GLenum transposedMatrixType;
+ GLenum boolVectorType;
+ SamplerFormat samplerFormat;
+ int rowCount;
+ int columnCount;
+ int componentCount;
+ size_t componentSize;
+ size_t internalSize;
+ size_t externalSize;
+ bool isSampler;
+ bool isMatrixType;
+ bool isImageType;
+};
+
+inline constexpr UniformTypeInfo::UniformTypeInfo(GLenum type,
+ GLenum componentType,
+ GLenum textureType,
+ GLenum transposedMatrixType,
+ GLenum boolVectorType,
+ SamplerFormat samplerFormat,
+ int rowCount,
+ int columnCount,
+ int componentCount,
+ size_t componentSize,
+ size_t internalSize,
+ size_t externalSize,
+ bool isSampler,
+ bool isMatrixType,
+ bool isImageType)
+ : type(type),
+ componentType(componentType),
+ textureType(textureType),
+ transposedMatrixType(transposedMatrixType),
+ boolVectorType(boolVectorType),
+ samplerFormat(samplerFormat),
+ rowCount(rowCount),
+ columnCount(columnCount),
+ componentCount(componentCount),
+ componentSize(componentSize),
+ internalSize(internalSize),
+ externalSize(externalSize),
+ isSampler(isSampler),
+ isMatrixType(isMatrixType),
+ isImageType(isImageType)
+{}
+
+const UniformTypeInfo &GetUniformTypeInfo(GLenum uniformType);
+
+const char *GetGenericErrorMessage(GLenum error);
+
+unsigned int ElementTypeSize(GLenum elementType);
+
+bool IsMipmapFiltered(GLenum minFilterMode);
+
+template <typename T>
+T GetClampedVertexCount(size_t vertexCount)
+{
+ static constexpr size_t kMax = static_cast<size_t>(std::numeric_limits<T>::max());
+ return static_cast<T>(vertexCount > kMax ? kMax : vertexCount);
+}
+
+enum class PipelineType
+{
+ GraphicsPipeline = 0,
+ ComputePipeline = 1,
+};
+
+PipelineType GetPipelineType(ShaderType shaderType);
+
+// For use with KHR_debug.
+const char *GetDebugMessageSourceString(GLenum source);
+const char *GetDebugMessageTypeString(GLenum type);
+const char *GetDebugMessageSeverityString(GLenum severity);
+
+// For use with EXT_texture_format_sRGB_override and EXT_texture_sRGB_decode
+// A texture may be forced to decode to a nonlinear colorspace, to a linear colorspace, or to the
+// default colorspace of its current format.
+//
+// Default corresponds to "the texture should use the imageview that corresponds to its format"
+// Linear corresponds to "the texture has sRGB decoding disabled by extension, and should use a
+// linear imageview even if it is in a nonlinear format" NonLinear corresponds to "the texture has
+// sRGB override enabled by extension, and should use a nonlinear imageview even if it is in a
+// linear format"
+enum class SrgbOverride
+{
+ Default = 0,
+ SRGB,
+ Linear
+};
+
+// For use with EXT_sRGB_write_control
+// A render target may be forced to convert to a linear colorspace, or may be allowed to do whatever
+// colorspace conversion is appropriate for its format. There is no option to force linear->sRGB, it
+// can only convert from sRGB->linear
+enum class SrgbWriteControlMode
+{
+ Default = 0,
+ Linear = 1
+};
+
+// For use with EXT_YUV_target
+// A sampler of external YUV textures may either implicitly perform RGB conversion (regular
+// samplerExternalOES) or skip the conversion and sample raw YUV values (__samplerExternal2DY2Y).
+enum class YuvSamplingMode
+{
+ Default = 0,
+ Y2Y = 1
+};
+
+ShaderType GetShaderTypeFromBitfield(size_t singleShaderType);
+GLbitfield GetBitfieldFromShaderType(ShaderType shaderType);
+bool ShaderTypeSupportsTransformFeedback(ShaderType shaderType);
+// Given a set of shader stages, returns the last vertex processing stage. This is the stage that
+// interfaces the fragment shader.
+ShaderType GetLastPreFragmentStage(ShaderBitSet shaderTypes);
+
+} // namespace gl
+
+namespace egl
+{
+static const EGLenum FirstCubeMapTextureTarget = EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR;
+static const EGLenum LastCubeMapTextureTarget = EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR;
+bool IsCubeMapTextureTarget(EGLenum target);
+size_t CubeMapTextureTargetToLayerIndex(EGLenum target);
+EGLenum LayerIndexToCubeMapTextureTarget(size_t index);
+bool IsTextureTarget(EGLenum target);
+bool IsRenderbufferTarget(EGLenum target);
+bool IsExternalImageTarget(EGLenum target);
+
+const char *GetGenericErrorMessage(EGLint error);
+} // namespace egl
+
+namespace egl_gl
+{
+GLuint EGLClientBufferToGLObjectHandle(EGLClientBuffer buffer);
+}
+
+namespace gl_egl
+{
+EGLenum GLComponentTypeToEGLColorComponentType(GLenum glComponentType);
+EGLClientBuffer GLObjectHandleToEGLClientBuffer(GLuint handle);
+} // namespace gl_egl
+
+namespace angle
+{
+bool IsDrawEntryPoint(EntryPoint entryPoint);
+bool IsDispatchEntryPoint(EntryPoint entryPoint);
+bool IsClearEntryPoint(EntryPoint entryPoint);
+bool IsQueryEntryPoint(EntryPoint entryPoint);
+} // namespace angle
+
+#if !defined(ANGLE_ENABLE_WINDOWS_UWP)
+void writeFile(const char *path, const void *data, size_t size);
+#endif
+
+#if defined(ANGLE_PLATFORM_WINDOWS)
+void ScheduleYield();
+#endif
+
+// Get the underlying type. Useful for indexing into arrays with enum values by avoiding the clutter
+// of the extraneous static_cast<>() calls.
+// https://stackoverflow.com/a/8357462
+template <typename E>
+constexpr typename std::underlying_type<E>::type ToUnderlying(E e) noexcept
+{
+ return static_cast<typename std::underlying_type<E>::type>(e);
+}
+
+#endif // COMMON_UTILITIES_H_
diff --git a/gfx/angle/checkout/src/common/vector_utils.h b/gfx/angle/checkout/src/common/vector_utils.h
new file mode 100644
index 0000000000..88c7492e72
--- /dev/null
+++ b/gfx/angle/checkout/src/common/vector_utils.h
@@ -0,0 +1,523 @@
+//
+// 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.
+//
+// vector_utils.h: Utility classes implementing various vector operations
+
+#ifndef COMMON_VECTOR_UTILS_H_
+#define COMMON_VECTOR_UTILS_H_
+
+#include <cmath>
+#include <cstddef>
+#include <ostream>
+#include <type_traits>
+
+namespace angle
+{
+
+template <size_t Dimension, typename Type>
+class Vector;
+
+using Vector2 = Vector<2, float>;
+using Vector3 = Vector<3, float>;
+using Vector4 = Vector<4, float>;
+
+using Vector2I = Vector<2, int>;
+using Vector3I = Vector<3, int>;
+using Vector4I = Vector<4, int>;
+
+using Vector2U = Vector<2, unsigned int>;
+using Vector3U = Vector<3, unsigned int>;
+using Vector4U = Vector<4, unsigned int>;
+
+template <size_t Dimension, typename Type>
+class VectorBase
+{
+ public:
+ using VectorN = Vector<Dimension, Type>;
+
+ // Constructors
+ VectorBase() = default;
+ explicit VectorBase(Type element);
+
+ template <typename Type2>
+ VectorBase(const VectorBase<Dimension, Type2> &other);
+
+ template <typename Arg1, typename Arg2, typename... Args>
+ VectorBase(const Arg1 &arg1, const Arg2 &arg2, const Args &...args);
+
+ // Access the vector backing storage directly
+ const Type *data() const { return mData; }
+ Type *data() { return mData; }
+ constexpr size_t size() const { return Dimension; }
+
+ // Load or store the pointer from / to raw data
+ static VectorN Load(const Type *source);
+ static void Store(const VectorN &source, Type *destination);
+
+ // Index the vector
+ Type &operator[](size_t i) { return mData[i]; }
+ const Type &operator[](size_t i) const { return mData[i]; }
+
+ // Basic arithmetic operations
+ VectorN operator+() const;
+ VectorN operator-() const;
+ VectorN operator+(const VectorN &other) const;
+ VectorN operator-(const VectorN &other) const;
+ VectorN operator*(const VectorN &other) const;
+ VectorN operator/(const VectorN &other) const;
+ VectorN operator*(Type other) const;
+ VectorN operator/(Type other) const;
+ friend VectorN operator*(Type a, const VectorN &b) { return b * a; }
+
+ // Compound arithmetic operations
+ VectorN &operator+=(const VectorN &other);
+ VectorN &operator-=(const VectorN &other);
+ VectorN &operator*=(const VectorN &other);
+ VectorN &operator/=(const VectorN &other);
+ VectorN &operator*=(Type other);
+ VectorN &operator/=(Type other);
+
+ // Comparison operators
+ bool operator==(const VectorBase<Dimension, Type> &other) const;
+ bool operator!=(const VectorBase<Dimension, Type> &other) const;
+
+ // Other arithmetic operations
+ Type length() const;
+ Type lengthSquared() const;
+ Type dot(const VectorBase<Dimension, Type> &other) const;
+ VectorN normalized() const;
+
+ protected:
+ template <size_t CurrentIndex, size_t OtherDimension, typename OtherType, typename... Args>
+ void initWithList(const Vector<OtherDimension, OtherType> &arg1, const Args &...args);
+
+ // Some old compilers consider this function an alternative for initWithList(Vector)
+ // when the variant above is more precise. Use SFINAE on the return value to hide
+ // this variant for non-arithmetic types. The return value is still void.
+ template <size_t CurrentIndex, typename OtherType, typename... Args>
+ typename std::enable_if<std::is_arithmetic<OtherType>::value>::type initWithList(
+ OtherType arg1,
+ const Args &...args);
+
+ template <size_t CurrentIndex>
+ void initWithList() const;
+
+ template <size_t Dimension2, typename Type2>
+ friend class VectorBase;
+
+ Type mData[Dimension];
+};
+
+template <size_t Dimension, typename Type>
+std::ostream &operator<<(std::ostream &ostream, const VectorBase<Dimension, Type> &vector);
+
+template <typename Type>
+class Vector<2, Type> : public VectorBase<2, Type>
+{
+ public:
+ // Import the constructors defined in VectorBase
+ using VectorBase<2, Type>::VectorBase;
+
+ // Element shorthands
+ Type &x() { return this->mData[0]; }
+ Type &y() { return this->mData[1]; }
+
+ const Type &x() const { return this->mData[0]; }
+ const Type &y() const { return this->mData[1]; }
+};
+
+template <typename Type>
+std::ostream &operator<<(std::ostream &ostream, const Vector<2, Type> &vector);
+
+template <typename Type>
+class Vector<3, Type> : public VectorBase<3, Type>
+{
+ public:
+ // Import the constructors defined in VectorBase
+ using VectorBase<3, Type>::VectorBase;
+
+ // Additional operations
+ Vector<3, Type> cross(const Vector<3, Type> &other) const;
+
+ // Element shorthands
+ Type &x() { return this->mData[0]; }
+ Type &y() { return this->mData[1]; }
+ Type &z() { return this->mData[2]; }
+
+ const Type &x() const { return this->mData[0]; }
+ const Type &y() const { return this->mData[1]; }
+ const Type &z() const { return this->mData[2]; }
+};
+
+template <typename Type>
+std::ostream &operator<<(std::ostream &ostream, const Vector<3, Type> &vector);
+
+template <typename Type>
+class Vector<4, Type> : public VectorBase<4, Type>
+{
+ public:
+ // Import the constructors defined in VectorBase
+ using VectorBase<4, Type>::VectorBase;
+
+ // Element shorthands
+ Type &x() { return this->mData[0]; }
+ Type &y() { return this->mData[1]; }
+ Type &z() { return this->mData[2]; }
+ Type &w() { return this->mData[3]; }
+
+ const Type &x() const { return this->mData[0]; }
+ const Type &y() const { return this->mData[1]; }
+ const Type &z() const { return this->mData[2]; }
+ const Type &w() const { return this->mData[3]; }
+};
+
+template <typename Type>
+std::ostream &operator<<(std::ostream &ostream, const Vector<4, Type> &vector);
+
+// Implementation of constructors and misc operations
+
+template <size_t Dimension, typename Type>
+VectorBase<Dimension, Type>::VectorBase(Type element)
+{
+ for (size_t i = 0; i < Dimension; ++i)
+ {
+ mData[i] = element;
+ }
+}
+
+template <size_t Dimension, typename Type>
+template <typename Type2>
+VectorBase<Dimension, Type>::VectorBase(const VectorBase<Dimension, Type2> &other)
+{
+ for (size_t i = 0; i < Dimension; ++i)
+ {
+ mData[i] = static_cast<Type>(other.mData[i]);
+ }
+}
+
+// Ideally we would like to have only two constructors:
+// - a scalar constructor that takes Type as a parameter
+// - a compound constructor
+// However if we define the compound constructor for when it has a single arguments, then calling
+// Vector2(0.0) will be ambiguous. To solve this we take advantage of there being a single compound
+// constructor with a single argument, which is the copy constructor. We end up with three
+// constructors:
+// - the scalar constructor
+// - the copy constructor
+// - the compound constructor for two or more arguments, hence the arg1, and arg2 here.
+template <size_t Dimension, typename Type>
+template <typename Arg1, typename Arg2, typename... Args>
+VectorBase<Dimension, Type>::VectorBase(const Arg1 &arg1, const Arg2 &arg2, const Args &...args)
+{
+ initWithList<0>(arg1, arg2, args...);
+}
+
+template <size_t Dimension, typename Type>
+template <size_t CurrentIndex, size_t OtherDimension, typename OtherType, typename... Args>
+void VectorBase<Dimension, Type>::initWithList(const Vector<OtherDimension, OtherType> &arg1,
+ const Args &...args)
+{
+ static_assert(CurrentIndex + OtherDimension <= Dimension,
+ "Too much data in the vector constructor.");
+ for (size_t i = 0; i < OtherDimension; ++i)
+ {
+ mData[CurrentIndex + i] = static_cast<Type>(arg1.mData[i]);
+ }
+ initWithList<CurrentIndex + OtherDimension>(args...);
+}
+
+template <size_t Dimension, typename Type>
+template <size_t CurrentIndex, typename OtherType, typename... Args>
+typename std::enable_if<std::is_arithmetic<OtherType>::value>::type
+VectorBase<Dimension, Type>::initWithList(OtherType arg1, const Args &...args)
+{
+ static_assert(CurrentIndex + 1 <= Dimension, "Too much data in the vector constructor.");
+ mData[CurrentIndex] = static_cast<Type>(arg1);
+ initWithList<CurrentIndex + 1>(args...);
+}
+
+template <size_t Dimension, typename Type>
+template <size_t CurrentIndex>
+void VectorBase<Dimension, Type>::initWithList() const
+{
+ static_assert(CurrentIndex == Dimension, "Not enough data in the vector constructor.");
+}
+
+template <size_t Dimension, typename Type>
+Vector<Dimension, Type> VectorBase<Dimension, Type>::Load(const Type *source)
+{
+ Vector<Dimension, Type> result;
+ for (size_t i = 0; i < Dimension; ++i)
+ {
+ result.mData[i] = source[i];
+ }
+ return result;
+}
+
+template <size_t Dimension, typename Type>
+void VectorBase<Dimension, Type>::Store(const Vector<Dimension, Type> &source, Type *destination)
+{
+ for (size_t i = 0; i < Dimension; ++i)
+ {
+ destination[i] = source.mData[i];
+ }
+}
+
+// Implementation of basic arithmetic operations
+template <size_t Dimension, typename Type>
+Vector<Dimension, Type> VectorBase<Dimension, Type>::operator+() const
+{
+ Vector<Dimension, Type> result;
+ for (size_t i = 0; i < Dimension; ++i)
+ {
+ result.mData[i] = +mData[i];
+ }
+ return result;
+}
+
+template <size_t Dimension, typename Type>
+Vector<Dimension, Type> VectorBase<Dimension, Type>::operator-() const
+{
+ Vector<Dimension, Type> result;
+ for (size_t i = 0; i < Dimension; ++i)
+ {
+ result.mData[i] = -mData[i];
+ }
+ return result;
+}
+
+template <size_t Dimension, typename Type>
+Vector<Dimension, Type> VectorBase<Dimension, Type>::operator+(
+ const Vector<Dimension, Type> &other) const
+{
+ Vector<Dimension, Type> result;
+ for (size_t i = 0; i < Dimension; ++i)
+ {
+ result.mData[i] = mData[i] + other.mData[i];
+ }
+ return result;
+}
+
+template <size_t Dimension, typename Type>
+Vector<Dimension, Type> VectorBase<Dimension, Type>::operator-(
+ const Vector<Dimension, Type> &other) const
+{
+ Vector<Dimension, Type> result;
+ for (size_t i = 0; i < Dimension; ++i)
+ {
+ result.mData[i] = mData[i] - other.mData[i];
+ }
+ return result;
+}
+
+template <size_t Dimension, typename Type>
+Vector<Dimension, Type> VectorBase<Dimension, Type>::operator*(
+ const Vector<Dimension, Type> &other) const
+{
+ Vector<Dimension, Type> result;
+ for (size_t i = 0; i < Dimension; ++i)
+ {
+ result.mData[i] = mData[i] * other.mData[i];
+ }
+ return result;
+}
+
+template <size_t Dimension, typename Type>
+Vector<Dimension, Type> VectorBase<Dimension, Type>::operator/(
+ const Vector<Dimension, Type> &other) const
+{
+ Vector<Dimension, Type> result;
+ for (size_t i = 0; i < Dimension; ++i)
+ {
+ result.mData[i] = mData[i] / other.mData[i];
+ }
+ return result;
+}
+
+template <size_t Dimension, typename Type>
+Vector<Dimension, Type> VectorBase<Dimension, Type>::operator*(Type other) const
+{
+ Vector<Dimension, Type> result;
+ for (size_t i = 0; i < Dimension; ++i)
+ {
+ result.mData[i] = mData[i] * other;
+ }
+ return result;
+}
+
+template <size_t Dimension, typename Type>
+Vector<Dimension, Type> VectorBase<Dimension, Type>::operator/(Type other) const
+{
+ Vector<Dimension, Type> result;
+ for (size_t i = 0; i < Dimension; ++i)
+ {
+ result.mData[i] = mData[i] / other;
+ }
+ return result;
+}
+
+// Implementation of compound arithmetic operations
+template <size_t Dimension, typename Type>
+Vector<Dimension, Type> &VectorBase<Dimension, Type>::operator+=(
+ const Vector<Dimension, Type> &other)
+{
+ for (size_t i = 0; i < Dimension; ++i)
+ {
+ mData[i] += other.mData[i];
+ }
+ return *static_cast<Vector<Dimension, Type> *>(this);
+}
+
+template <size_t Dimension, typename Type>
+Vector<Dimension, Type> &VectorBase<Dimension, Type>::operator-=(
+ const Vector<Dimension, Type> &other)
+{
+ for (size_t i = 0; i < Dimension; ++i)
+ {
+ mData[i] -= other.mData[i];
+ }
+ return *static_cast<Vector<Dimension, Type> *>(this);
+}
+
+template <size_t Dimension, typename Type>
+Vector<Dimension, Type> &VectorBase<Dimension, Type>::operator*=(
+ const Vector<Dimension, Type> &other)
+{
+ for (size_t i = 0; i < Dimension; ++i)
+ {
+ mData[i] *= other.mData[i];
+ }
+ return *static_cast<Vector<Dimension, Type> *>(this);
+}
+
+template <size_t Dimension, typename Type>
+Vector<Dimension, Type> &VectorBase<Dimension, Type>::operator/=(
+ const Vector<Dimension, Type> &other)
+{
+ for (size_t i = 0; i < Dimension; ++i)
+ {
+ mData[i] /= other.mData[i];
+ }
+ return *static_cast<Vector<Dimension, Type> *>(this);
+}
+
+template <size_t Dimension, typename Type>
+Vector<Dimension, Type> &VectorBase<Dimension, Type>::operator*=(Type other)
+{
+ for (size_t i = 0; i < Dimension; ++i)
+ {
+ mData[i] *= other;
+ }
+ return *static_cast<Vector<Dimension, Type> *>(this);
+}
+
+template <size_t Dimension, typename Type>
+Vector<Dimension, Type> &VectorBase<Dimension, Type>::operator/=(Type other)
+{
+ for (size_t i = 0; i < Dimension; ++i)
+ {
+ mData[i] /= other;
+ }
+ return *static_cast<Vector<Dimension, Type> *>(this);
+}
+
+// Implementation of comparison operators
+template <size_t Dimension, typename Type>
+bool VectorBase<Dimension, Type>::operator==(const VectorBase<Dimension, Type> &other) const
+{
+ for (size_t i = 0; i < Dimension; ++i)
+ {
+ if (mData[i] != other.mData[i])
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+template <size_t Dimension, typename Type>
+bool VectorBase<Dimension, Type>::operator!=(const VectorBase<Dimension, Type> &other) const
+{
+ return !(*this == other);
+}
+
+// Implementation of other arithmetic operations
+template <size_t Dimension, typename Type>
+Type VectorBase<Dimension, Type>::length() const
+{
+ static_assert(std::is_floating_point<Type>::value,
+ "VectorN::length is only defined for floating point vectors");
+ return std::sqrt(lengthSquared());
+}
+
+template <size_t Dimension, typename Type>
+Type VectorBase<Dimension, Type>::lengthSquared() const
+{
+ return dot(*this);
+}
+
+template <size_t Dimension, typename Type>
+Type VectorBase<Dimension, Type>::dot(const VectorBase<Dimension, Type> &other) const
+{
+ Type sum = Type();
+ for (size_t i = 0; i < Dimension; ++i)
+ {
+ sum += mData[i] * other.mData[i];
+ }
+ return sum;
+}
+
+template <size_t Dimension, typename Type>
+std::ostream &operator<<(std::ostream &ostream, const VectorBase<Dimension, Type> &vector)
+{
+ ostream << "[ ";
+ for (size_t elementIdx = 0; elementIdx < Dimension; elementIdx++)
+ {
+ if (elementIdx > 0)
+ {
+ ostream << ", ";
+ }
+ ostream << vector.data()[elementIdx];
+ }
+ ostream << " ]";
+ return ostream;
+}
+
+template <size_t Dimension, typename Type>
+Vector<Dimension, Type> VectorBase<Dimension, Type>::normalized() const
+{
+ static_assert(std::is_floating_point<Type>::value,
+ "VectorN::normalized is only defined for floating point vectors");
+ return *this / length();
+}
+
+template <typename Type>
+std::ostream &operator<<(std::ostream &ostream, const Vector<2, Type> &vector)
+{
+ return ostream << static_cast<const VectorBase<2, Type> &>(vector);
+}
+
+template <typename Type>
+Vector<3, Type> Vector<3, Type>::cross(const Vector<3, Type> &other) const
+{
+ return Vector<3, Type>(y() * other.z() - z() * other.y(), z() * other.x() - x() * other.z(),
+ x() * other.y() - y() * other.x());
+}
+
+template <typename Type>
+std::ostream &operator<<(std::ostream &ostream, const Vector<3, Type> &vector)
+{
+ return ostream << static_cast<const VectorBase<3, Type> &>(vector);
+}
+
+template <typename Type>
+std::ostream &operator<<(std::ostream &ostream, const Vector<4, Type> &vector)
+{
+ return ostream << static_cast<const VectorBase<4, Type> &>(vector);
+}
+
+} // namespace angle
+
+#endif // COMMON_VECTOR_UTILS_H_
diff --git a/gfx/angle/checkout/src/common/vulkan/libvulkan_loader.cpp b/gfx/angle/checkout/src/common/vulkan/libvulkan_loader.cpp
new file mode 100644
index 0000000000..dafe092732
--- /dev/null
+++ b/gfx/angle/checkout/src/common/vulkan/libvulkan_loader.cpp
@@ -0,0 +1,57 @@
+//
+// Copyright 2021 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.
+//
+// libvulkan_loader.cpp:
+// Helper functions for the loading Vulkan libraries.
+//
+
+#include "common/vulkan/libvulkan_loader.h"
+
+#include "common/system_utils.h"
+
+namespace angle
+{
+namespace vk
+{
+void *OpenLibVulkan()
+{
+ constexpr const char *kLibVulkanNames[] = {
+#if defined(ANGLE_PLATFORM_WINDOWS)
+ "vulkan-1.dll",
+#elif defined(ANGLE_PLATFORM_APPLE)
+ "libvulkan.dylib",
+ "libvulkan.1.dylib",
+ "libMoltenVK.dylib"
+#else
+ "libvulkan.so",
+ "libvulkan.so.1",
+#endif
+ };
+
+ constexpr SearchType kSearchTypes[] = {
+// On Android, Fuchsia and GGP we use the system libvulkan.
+#if defined(ANGLE_USE_CUSTOM_LIBVULKAN)
+ SearchType::ModuleDir,
+#else
+ SearchType::SystemDir,
+#endif // defined(ANGLE_USE_CUSTOM_LIBVULKAN)
+ };
+
+ for (angle::SearchType searchType : kSearchTypes)
+ {
+ for (const char *libraryName : kLibVulkanNames)
+ {
+ void *library = OpenSystemLibraryWithExtension(libraryName, searchType);
+ if (library)
+ {
+ return library;
+ }
+ }
+ }
+
+ return nullptr;
+}
+} // namespace vk
+} // namespace angle
diff --git a/gfx/angle/checkout/src/common/vulkan/libvulkan_loader.h b/gfx/angle/checkout/src/common/vulkan/libvulkan_loader.h
new file mode 100644
index 0000000000..1a73c87b68
--- /dev/null
+++ b/gfx/angle/checkout/src/common/vulkan/libvulkan_loader.h
@@ -0,0 +1,23 @@
+//
+// Copyright 2021 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.
+//
+// libvulkan_loader.h:
+// Helper functions for the loading Vulkan libraries.
+//
+
+#include <memory>
+
+#ifndef LIBANGLE_COMMON_VULKAN_LIBVULKAN_LOADER_H_
+# define LIBANGLE_COMMON_VULKAN_LIBVULKAN_LOADER_H_
+
+namespace angle
+{
+namespace vk
+{
+void *OpenLibVulkan();
+}
+} // namespace angle
+
+#endif // LIBANGLE_COMMON_VULKAN_LIBVULKAN_LOADER_H_
diff --git a/gfx/angle/checkout/src/common/vulkan/vk_google_filtering_precision.h b/gfx/angle/checkout/src/common/vulkan/vk_google_filtering_precision.h
new file mode 100644
index 0000000000..934dc793c6
--- /dev/null
+++ b/gfx/angle/checkout/src/common/vulkan/vk_google_filtering_precision.h
@@ -0,0 +1,57 @@
+// Copyright 2020 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef CUSTOM_VK_GOOGLE_SAMPLER_FILTERING_PRECISION_H_
+#define CUSTOM_VK_GOOGLE_SAMPLER_FILTERING_PRECISION_H_
+
+#include "vk_headers.h"
+
+// THIS FILE SHOULD BE DELETED IF VK_GOOGLE_sampler_filtering_precision IS EVER ADDED TO THE VULKAN
+// HEADERS
+#ifdef VK_GOOGLE_sampler_filtering_precision
+# error \
+ "VK_GOOGLE_sampler_filtering_precision is already defined in the Vulkan headers, you can delete this file"
+#endif
+
+static constexpr VkStructureType VK_STRUCTURE_TYPE_SAMPLER_FILTERING_PRECISION_GOOGLE =
+ static_cast<VkStructureType>(1000264000);
+
+#define VK_GOOGLE_sampler_filtering_precision 1
+#define VK_GOOGLE_SAMPLER_FILTERING_PRECISION_SPEC_VERSION 1
+#define VK_GOOGLE_SAMPLER_FILTERING_PRECISION_EXTENSION_NAME "VK_GOOGLE_sampler_filtering_precision"
+
+const int TEXTURE_FILTERING_HINT_CHROMIUM = 0x8AF0;
+
+typedef enum VkSamplerFilteringPrecisionModeGOOGLE
+{
+ VK_SAMPLER_FILTERING_PRECISION_MODE_LOW_GOOGLE = 0,
+ VK_SAMPLER_FILTERING_PRECISION_MODE_HIGH_GOOGLE = 1,
+ VK_SAMPLER_FILTERING_PRECISION_MODE_BEGIN_RANGE_GOOGLE =
+ VK_SAMPLER_FILTERING_PRECISION_MODE_LOW_GOOGLE,
+ VK_SAMPLER_FILTERING_PRECISION_MODE_END_RANGE_GOOGLE =
+ VK_SAMPLER_FILTERING_PRECISION_MODE_HIGH_GOOGLE,
+ VK_SAMPLER_FILTERING_PRECISION_MODE_RANGE_SIZE_GOOGLE =
+ (VK_SAMPLER_FILTERING_PRECISION_MODE_HIGH_GOOGLE -
+ VK_SAMPLER_FILTERING_PRECISION_MODE_LOW_GOOGLE + 1),
+ VK_SAMPLER_FILTERING_PRECISION_MODE_MAX_ENUM_GOOGLE = 0x7FFFFFFF
+} VkSamplerFilteringPrecisionModeGOOGLE;
+
+typedef struct VkSamplerFilteringPrecisionGOOGLE
+{
+ VkStructureType sType;
+ const void *pNext;
+ VkSamplerFilteringPrecisionModeGOOGLE samplerFilteringPrecisionMode;
+} VkSamplerFilteringPrecisionGOOGLE;
+
+#endif // CUSTOM_VK_GOOGLE_SAMPLER_FILTERING_PRECISION_H_
diff --git a/gfx/angle/checkout/src/common/vulkan/vk_headers.h b/gfx/angle/checkout/src/common/vulkan/vk_headers.h
new file mode 100644
index 0000000000..a16938a872
--- /dev/null
+++ b/gfx/angle/checkout/src/common/vulkan/vk_headers.h
@@ -0,0 +1,163 @@
+//
+// 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.
+//
+// vk_headers:
+// This file should be included to ensure the vulkan headers are included
+//
+
+#ifndef LIBANGLE_RENDERER_VULKAN_VK_HEADERS_H_
+#define LIBANGLE_RENDERER_VULKAN_VK_HEADERS_H_
+
+#if ANGLE_SHARED_LIBVULKAN
+# include "third_party/volk/volk.h"
+#else
+# include <vulkan/vulkan.h>
+#endif
+
+// For the unreleased VK_GOOGLEX_multisampled_render_to_single_sampled
+#if !defined(VK_GOOGLEX_multisampled_render_to_single_sampled)
+# define VK_GOOGLEX_multisampled_render_to_single_sampled 1
+# define VK_GOOGLEX_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_SPEC_VERSION 1
+# define VK_GOOGLEX_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_EXTENSION_NAME \
+ "VK_GOOGLEX_multisampled_render_to_single_sampled"
+
+# define VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_FEATURES_GOOGLEX \
+ ((VkStructureType)(1000376000))
+# define VK_STRUCTURE_TYPE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_INFO_GOOGLEX \
+ ((VkStructureType)(1000376001))
+
+typedef struct VkPhysicalDeviceMultisampledRenderToSingleSampledFeaturesGOOGLEX
+{
+ VkStructureType sType;
+ const void *pNext;
+ VkBool32 multisampledRenderToSingleSampled;
+} VkPhysicalDeviceMultisampledRenderToSingleSampledFeaturesGOOGLEX;
+
+typedef struct VkMultisampledRenderToSingleSampledInfoGOOGLEX
+{
+ VkStructureType sType;
+ const void *pNext;
+ VkBool32 multisampledRenderToSingleSampledEnable;
+ VkSampleCountFlagBits rasterizationSamples;
+ VkResolveModeFlagBits depthResolveMode;
+ VkResolveModeFlagBits stencilResolveMode;
+} VkMultisampledRenderToSingleSampledInfoGOOGLEX;
+#endif /* VK_GOOGLEX_multisampled_render_to_single_sampled */
+
+#if !defined(ANGLE_SHARED_LIBVULKAN)
+
+namespace rx
+{
+// VK_EXT_debug_utils
+extern PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessengerEXT;
+extern PFN_vkDestroyDebugUtilsMessengerEXT vkDestroyDebugUtilsMessengerEXT;
+extern PFN_vkCmdBeginDebugUtilsLabelEXT vkCmdBeginDebugUtilsLabelEXT;
+extern PFN_vkCmdEndDebugUtilsLabelEXT vkCmdEndDebugUtilsLabelEXT;
+extern PFN_vkCmdInsertDebugUtilsLabelEXT vkCmdInsertDebugUtilsLabelEXT;
+extern PFN_vkSetDebugUtilsObjectNameEXT vkSetDebugUtilsObjectNameEXT;
+
+// VK_EXT_debug_report
+extern PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT;
+extern PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT;
+
+// VK_KHR_get_physical_device_properties2
+extern PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR;
+extern PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR;
+extern PFN_vkGetPhysicalDeviceMemoryProperties2KHR vkGetPhysicalDeviceMemoryProperties2KHR;
+
+// VK_KHR_external_semaphore_fd
+extern PFN_vkImportSemaphoreFdKHR vkImportSemaphoreFdKHR;
+
+// VK_EXT_external_memory_host
+extern PFN_vkGetMemoryHostPointerPropertiesEXT vkGetMemoryHostPointerPropertiesEXT;
+
+// VK_EXT_host_query_reset
+extern PFN_vkResetQueryPoolEXT vkResetQueryPoolEXT;
+
+// VK_EXT_transform_feedback
+extern PFN_vkCmdBindTransformFeedbackBuffersEXT vkCmdBindTransformFeedbackBuffersEXT;
+extern PFN_vkCmdBeginTransformFeedbackEXT vkCmdBeginTransformFeedbackEXT;
+extern PFN_vkCmdEndTransformFeedbackEXT vkCmdEndTransformFeedbackEXT;
+extern PFN_vkCmdBeginQueryIndexedEXT vkCmdBeginQueryIndexedEXT;
+extern PFN_vkCmdEndQueryIndexedEXT vkCmdEndQueryIndexedEXT;
+extern PFN_vkCmdDrawIndirectByteCountEXT vkCmdDrawIndirectByteCountEXT;
+
+// VK_KHR_get_memory_requirements2
+extern PFN_vkGetBufferMemoryRequirements2KHR vkGetBufferMemoryRequirements2KHR;
+extern PFN_vkGetImageMemoryRequirements2KHR vkGetImageMemoryRequirements2KHR;
+
+// VK_KHR_bind_memory2
+extern PFN_vkBindBufferMemory2KHR vkBindBufferMemory2KHR;
+extern PFN_vkBindImageMemory2KHR vkBindImageMemory2KHR;
+
+// VK_KHR_external_fence_capabilities
+extern PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR
+ vkGetPhysicalDeviceExternalFencePropertiesKHR;
+
+// VK_KHR_external_fence_fd
+extern PFN_vkGetFenceFdKHR vkGetFenceFdKHR;
+extern PFN_vkImportFenceFdKHR vkImportFenceFdKHR;
+
+// VK_KHR_external_semaphore_capabilities
+extern PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR
+ vkGetPhysicalDeviceExternalSemaphorePropertiesKHR;
+
+// VK_KHR_sampler_ycbcr_conversion
+extern PFN_vkCreateSamplerYcbcrConversionKHR vkCreateSamplerYcbcrConversionKHR;
+extern PFN_vkDestroySamplerYcbcrConversionKHR vkDestroySamplerYcbcrConversionKHR;
+
+// VK_KHR_create_renderpass2
+extern PFN_vkCreateRenderPass2KHR vkCreateRenderPass2KHR;
+
+# if defined(ANGLE_PLATFORM_FUCHSIA)
+// VK_FUCHSIA_imagepipe_surface
+extern PFN_vkCreateImagePipeSurfaceFUCHSIA vkCreateImagePipeSurfaceFUCHSIA;
+# endif
+
+# if defined(ANGLE_PLATFORM_ANDROID)
+extern PFN_vkGetAndroidHardwareBufferPropertiesANDROID vkGetAndroidHardwareBufferPropertiesANDROID;
+extern PFN_vkGetMemoryAndroidHardwareBufferANDROID vkGetMemoryAndroidHardwareBufferANDROID;
+# endif
+
+# if defined(ANGLE_PLATFORM_GGP)
+extern PFN_vkCreateStreamDescriptorSurfaceGGP vkCreateStreamDescriptorSurfaceGGP;
+# endif // defined(ANGLE_PLATFORM_GGP)
+
+// VK_KHR_shared_presentable_image
+extern PFN_vkGetSwapchainStatusKHR vkGetSwapchainStatusKHR;
+
+// VK_EXT_extended_dynamic_state
+extern PFN_vkCmdBindVertexBuffers2EXT vkCmdBindVertexBuffers2EXT;
+extern PFN_vkCmdSetCullModeEXT vkCmdSetCullModeEXT;
+extern PFN_vkCmdSetDepthBoundsTestEnableEXT vkCmdSetDepthBoundsTestEnableEXT;
+extern PFN_vkCmdSetDepthCompareOpEXT vkCmdSetDepthCompareOpEXT;
+extern PFN_vkCmdSetDepthTestEnableEXT vkCmdSetDepthTestEnableEXT;
+extern PFN_vkCmdSetDepthWriteEnableEXT vkCmdSetDepthWriteEnableEXT;
+extern PFN_vkCmdSetFrontFaceEXT vkCmdSetFrontFaceEXT;
+extern PFN_vkCmdSetPrimitiveTopologyEXT vkCmdSetPrimitiveTopologyEXT;
+extern PFN_vkCmdSetScissorWithCountEXT vkCmdSetScissorWithCountEXT;
+extern PFN_vkCmdSetStencilOpEXT vkCmdSetStencilOpEXT;
+extern PFN_vkCmdSetStencilTestEnableEXT vkCmdSetStencilTestEnableEXT;
+extern PFN_vkCmdSetViewportWithCountEXT vkCmdSetViewportWithCountEXT;
+
+// VK_EXT_extended_dynamic_state2
+extern PFN_vkCmdSetDepthBiasEnableEXT vkCmdSetDepthBiasEnableEXT;
+extern PFN_vkCmdSetLogicOpEXT vkCmdSetLogicOpEXT;
+extern PFN_vkCmdSetPatchControlPointsEXT vkCmdSetPatchControlPointsEXT;
+extern PFN_vkCmdSetPrimitiveRestartEnableEXT vkCmdSetPrimitiveRestartEnableEXT;
+extern PFN_vkCmdSetRasterizerDiscardEnableEXT vkCmdSetRasterizerDiscardEnableEXT;
+
+// VK_KHR_fragment_shading_rate
+extern PFN_vkGetPhysicalDeviceFragmentShadingRatesKHR vkGetPhysicalDeviceFragmentShadingRatesKHR;
+extern PFN_vkCmdSetFragmentShadingRateKHR vkCmdSetFragmentShadingRateKHR;
+
+// VK_GOOGLE_display_timing
+extern PFN_vkGetPastPresentationTimingGOOGLE vkGetPastPresentationTimingGOOGLE;
+
+} // namespace rx
+
+#endif // ANGLE_SHARED_LIBVULKAN
+
+#endif // LIBANGLE_RENDERER_VULKAN_VK_HEADERS_H_
diff --git a/gfx/angle/checkout/src/common/vulkan/vulkan_icd.cpp b/gfx/angle/checkout/src/common/vulkan/vulkan_icd.cpp
new file mode 100644
index 0000000000..22502c0457
--- /dev/null
+++ b/gfx/angle/checkout/src/common/vulkan/vulkan_icd.cpp
@@ -0,0 +1,349 @@
+//
+// Copyright 2020 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.
+//
+
+// vulkan_icd.cpp : Helper for creating vulkan instances & selecting physical device.
+
+#include "common/vulkan/vulkan_icd.h"
+
+#include <functional>
+#include <vector>
+
+#include "common/Optional.h"
+#include "common/bitset_utils.h"
+#include "common/debug.h"
+#include "common/system_utils.h"
+
+#include "common/vulkan/vk_google_filtering_precision.h"
+
+namespace
+{
+void ResetEnvironmentVar(const char *variableName, const Optional<std::string> &value)
+{
+ if (!value.valid())
+ {
+ return;
+ }
+
+ if (value.value().empty())
+ {
+ angle::UnsetEnvironmentVar(variableName);
+ }
+ else
+ {
+ angle::SetEnvironmentVar(variableName, value.value().c_str());
+ }
+}
+} // namespace
+
+namespace angle
+{
+
+namespace vk
+{
+
+namespace
+{
+
+[[maybe_unused]] const std::string WrapICDEnvironment(const char *icdEnvironment)
+{
+ // The libraries are bundled into the module directory
+ std::string ret = ConcatenatePath(angle::GetModuleDirectory(), icdEnvironment);
+ return ret;
+}
+
+[[maybe_unused]] constexpr char kLoaderLayersPathEnv[] = "VK_LAYER_PATH";
+[[maybe_unused]] constexpr char kLayerEnablesEnv[] = "VK_LAYER_ENABLES";
+
+constexpr char kLoaderICDFilenamesEnv[] = "VK_ICD_FILENAMES";
+constexpr char kANGLEPreferredDeviceEnv[] = "ANGLE_PREFERRED_DEVICE";
+constexpr char kValidationLayersCustomSTypeListEnv[] = "VK_LAYER_CUSTOM_STYPE_LIST";
+constexpr char kNoDeviceSelect[] = "NODEVICE_SELECT";
+
+constexpr uint32_t kMockVendorID = 0xba5eba11;
+constexpr uint32_t kMockDeviceID = 0xf005ba11;
+constexpr char kMockDeviceName[] = "Vulkan Mock Device";
+
+constexpr uint32_t kGoogleVendorID = 0x1AE0;
+constexpr uint32_t kSwiftShaderDeviceID = 0xC0DE;
+constexpr char kSwiftShaderDeviceName[] = "SwiftShader Device";
+
+using ICDFilterFunc = std::function<bool(const VkPhysicalDeviceProperties &)>;
+
+ICDFilterFunc GetFilterForICD(vk::ICD preferredICD)
+{
+ switch (preferredICD)
+ {
+ case vk::ICD::Mock:
+ return [](const VkPhysicalDeviceProperties &deviceProperties) {
+ return ((deviceProperties.vendorID == kMockVendorID) &&
+ (deviceProperties.deviceID == kMockDeviceID) &&
+ (strcmp(deviceProperties.deviceName, kMockDeviceName) == 0));
+ };
+ case vk::ICD::SwiftShader:
+ return [](const VkPhysicalDeviceProperties &deviceProperties) {
+ return ((deviceProperties.vendorID == kGoogleVendorID) &&
+ (deviceProperties.deviceID == kSwiftShaderDeviceID) &&
+ (strncmp(deviceProperties.deviceName, kSwiftShaderDeviceName,
+ strlen(kSwiftShaderDeviceName)) == 0));
+ };
+ default:
+ const std::string anglePreferredDevice =
+ angle::GetEnvironmentVar(kANGLEPreferredDeviceEnv);
+ return [anglePreferredDevice](const VkPhysicalDeviceProperties &deviceProperties) {
+ return (anglePreferredDevice == deviceProperties.deviceName);
+ };
+ }
+}
+
+} // namespace
+
+// If we're loading the validation layers, we could be running from any random directory.
+// Change to the executable directory so we can find the layers, then change back to the
+// previous directory to be safe we don't disrupt the application.
+ScopedVkLoaderEnvironment::ScopedVkLoaderEnvironment(bool enableValidationLayers, vk::ICD icd)
+ : mEnableValidationLayers(enableValidationLayers),
+ mICD(icd),
+ mChangedCWD(false),
+ mChangedICDEnv(false),
+ mChangedNoDeviceSelect(false)
+{
+// Changing CWD and setting environment variables makes no sense on Android,
+// since this code is a part of Java application there.
+// Android Vulkan loader doesn't need this either.
+#if !defined(ANGLE_PLATFORM_ANDROID) && !defined(ANGLE_PLATFORM_GGP)
+ if (icd == vk::ICD::Mock)
+ {
+ if (!setICDEnvironment(WrapICDEnvironment(ANGLE_VK_MOCK_ICD_JSON).c_str()))
+ {
+ ERR() << "Error setting environment for Mock/Null Driver.";
+ }
+ }
+# if defined(ANGLE_VK_SWIFTSHADER_ICD_JSON)
+ else if (icd == vk::ICD::SwiftShader)
+ {
+ if (!setICDEnvironment(WrapICDEnvironment(ANGLE_VK_SWIFTSHADER_ICD_JSON).c_str()))
+ {
+ ERR() << "Error setting environment for SwiftShader.";
+ }
+ }
+# endif // defined(ANGLE_VK_SWIFTSHADER_ICD_JSON)
+
+# if !defined(ANGLE_PLATFORM_MACOS)
+ if (mEnableValidationLayers || icd != vk::ICD::Default)
+ {
+ const auto &cwd = angle::GetCWD();
+ if (!cwd.valid())
+ {
+ ERR() << "Error getting CWD for Vulkan layers init.";
+ mEnableValidationLayers = false;
+ mICD = vk::ICD::Default;
+ }
+ else
+ {
+ mPreviousCWD = cwd.value();
+ std::string moduleDir = angle::GetModuleDirectory();
+ mChangedCWD = angle::SetCWD(moduleDir.c_str());
+ if (!mChangedCWD)
+ {
+ ERR() << "Error setting CWD for Vulkan layers init.";
+ mEnableValidationLayers = false;
+ mICD = vk::ICD::Default;
+ }
+ }
+ }
+# endif // defined(ANGLE_PLATFORM_MACOS)
+
+ // Override environment variable to use the ANGLE layers.
+ if (mEnableValidationLayers)
+ {
+# if defined(ANGLE_VK_LAYERS_DIR)
+ if (!angle::PrependPathToEnvironmentVar(kLoaderLayersPathEnv, ANGLE_VK_LAYERS_DIR))
+ {
+ ERR() << "Error setting environment for Vulkan layers init.";
+ mEnableValidationLayers = false;
+ }
+# endif // defined(ANGLE_VK_LAYERS_DIR)
+
+ if (!angle::PrependPathToEnvironmentVar(
+ kLayerEnablesEnv, "VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION"))
+ {
+ ERR() << "Error setting synchronization validation environment for Vulkan validation "
+ "layers init.";
+ }
+
+ if (!setCustomExtensionsEnvironment())
+ {
+ ERR() << "Error setting custom list for custom extensions for Vulkan layers init.";
+ mEnableValidationLayers = false;
+ }
+ }
+#endif // !defined(ANGLE_PLATFORM_ANDROID)
+
+ if (IsMSan() || IsASan())
+ {
+ // device select layer cause memory sanitizer false positive, so disable
+ // it for msan build.
+ mPreviousNoDeviceSelectEnv = angle::GetEnvironmentVar(kNoDeviceSelect);
+ angle::SetEnvironmentVar(kNoDeviceSelect, "1");
+ mChangedNoDeviceSelect = true;
+ }
+}
+
+ScopedVkLoaderEnvironment::~ScopedVkLoaderEnvironment()
+{
+ if (mChangedCWD)
+ {
+#if !defined(ANGLE_PLATFORM_ANDROID)
+ ASSERT(mPreviousCWD.valid());
+ angle::SetCWD(mPreviousCWD.value().c_str());
+#endif // !defined(ANGLE_PLATFORM_ANDROID)
+ }
+ if (mChangedICDEnv)
+ {
+ ResetEnvironmentVar(kLoaderICDFilenamesEnv, mPreviousICDEnv);
+ }
+
+ ResetEnvironmentVar(kValidationLayersCustomSTypeListEnv, mPreviousCustomExtensionsEnv);
+
+ if (mChangedNoDeviceSelect)
+ {
+ ResetEnvironmentVar(kNoDeviceSelect, mPreviousNoDeviceSelectEnv);
+ }
+}
+
+bool ScopedVkLoaderEnvironment::setICDEnvironment(const char *icd)
+{
+ // Override environment variable to use built Mock ICD
+ // ANGLE_VK_ICD_JSON gets set to the built mock ICD in BUILD.gn
+ mPreviousICDEnv = angle::GetEnvironmentVar(kLoaderICDFilenamesEnv);
+ mChangedICDEnv = angle::SetEnvironmentVar(kLoaderICDFilenamesEnv, icd);
+
+ if (!mChangedICDEnv)
+ {
+ mICD = vk::ICD::Default;
+ }
+ return mChangedICDEnv;
+}
+
+bool ScopedVkLoaderEnvironment::setCustomExtensionsEnvironment()
+{
+ struct CustomExtension
+ {
+ VkStructureType type;
+ size_t size;
+ };
+
+ CustomExtension customExtensions[] = {
+
+ {VK_STRUCTURE_TYPE_SAMPLER_FILTERING_PRECISION_GOOGLE,
+ sizeof(VkSamplerFilteringPrecisionGOOGLE)},
+
+ };
+
+ mPreviousCustomExtensionsEnv = angle::GetEnvironmentVar(kValidationLayersCustomSTypeListEnv);
+
+ std::stringstream strstr;
+ for (CustomExtension &extension : customExtensions)
+ {
+ if (strstr.tellp() != std::streampos(0))
+ {
+ strstr << angle::GetPathSeparatorForEnvironmentVar();
+ }
+
+ strstr << extension.type << angle::GetPathSeparatorForEnvironmentVar() << extension.size;
+ }
+
+ return angle::PrependPathToEnvironmentVar(kValidationLayersCustomSTypeListEnv,
+ strstr.str().c_str());
+}
+
+void ChoosePhysicalDevice(PFN_vkGetPhysicalDeviceProperties pGetPhysicalDeviceProperties,
+ const std::vector<VkPhysicalDevice> &physicalDevices,
+ vk::ICD preferredICD,
+ uint32_t preferredVendorID,
+ uint32_t preferredDeviceID,
+ VkPhysicalDevice *physicalDeviceOut,
+ VkPhysicalDeviceProperties *physicalDevicePropertiesOut)
+{
+ ASSERT(!physicalDevices.empty());
+
+ ICDFilterFunc filter = GetFilterForICD(preferredICD);
+
+ const bool shouldChooseByID = (preferredVendorID != 0 || preferredDeviceID != 0);
+
+ for (const VkPhysicalDevice &physicalDevice : physicalDevices)
+ {
+ pGetPhysicalDeviceProperties(physicalDevice, physicalDevicePropertiesOut);
+ if (filter(*physicalDevicePropertiesOut))
+ {
+ *physicalDeviceOut = physicalDevice;
+ return;
+ }
+
+ if (shouldChooseByID)
+ {
+ // NOTE: If the system has multiple GPUs with the same vendor and
+ // device IDs, this will arbitrarily select one of them.
+ bool matchVendorID = true;
+ bool matchDeviceID = true;
+
+ if (preferredVendorID != 0 &&
+ preferredVendorID != physicalDevicePropertiesOut->vendorID)
+ {
+ matchVendorID = false;
+ }
+
+ if (preferredDeviceID != 0 &&
+ preferredDeviceID != physicalDevicePropertiesOut->deviceID)
+ {
+ matchDeviceID = false;
+ }
+
+ if (matchVendorID && matchDeviceID)
+ {
+ *physicalDeviceOut = physicalDevice;
+ return;
+ }
+ }
+ }
+
+ Optional<VkPhysicalDevice> integratedDevice;
+ VkPhysicalDeviceProperties integratedDeviceProperties;
+ for (const VkPhysicalDevice &physicalDevice : physicalDevices)
+ {
+ pGetPhysicalDeviceProperties(physicalDevice, physicalDevicePropertiesOut);
+ // If discrete GPU exists, uses it by default.
+ if (physicalDevicePropertiesOut->deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
+ {
+ *physicalDeviceOut = physicalDevice;
+ return;
+ }
+ if (physicalDevicePropertiesOut->deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU &&
+ !integratedDevice.valid())
+ {
+ integratedDevice = physicalDevice;
+ integratedDeviceProperties = *physicalDevicePropertiesOut;
+ continue;
+ }
+ }
+
+ // If only integrated GPU exists, use it by default.
+ if (integratedDevice.valid())
+ {
+ *physicalDeviceOut = integratedDevice.value();
+ *physicalDevicePropertiesOut = integratedDeviceProperties;
+ return;
+ }
+
+ WARN() << "Preferred device ICD not found. Using default physicalDevice instead.";
+ // Fallback to the first device.
+ *physicalDeviceOut = physicalDevices[0];
+ pGetPhysicalDeviceProperties(*physicalDeviceOut, physicalDevicePropertiesOut);
+}
+
+} // namespace vk
+
+} // namespace angle
diff --git a/gfx/angle/checkout/src/common/vulkan/vulkan_icd.h b/gfx/angle/checkout/src/common/vulkan/vulkan_icd.h
new file mode 100644
index 0000000000..b2921f8203
--- /dev/null
+++ b/gfx/angle/checkout/src/common/vulkan/vulkan_icd.h
@@ -0,0 +1,72 @@
+//
+// Copyright 2020 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.
+//
+// vulkan_icd.h : Helper for creating vulkan instances & selecting physical device.
+
+#ifndef COMMON_VULKAN_VULKAN_ICD_H_
+#define COMMON_VULKAN_VULKAN_ICD_H_
+
+#include <string>
+
+#include "common/Optional.h"
+#include "common/angleutils.h"
+#include "common/vulkan/vk_headers.h"
+
+namespace angle
+{
+
+namespace vk
+{
+
+enum class ICD
+{
+ Default,
+ Mock,
+ SwiftShader,
+};
+
+struct SimpleDisplayWindow
+{
+ uint16_t width;
+ uint16_t height;
+};
+
+class [[nodiscard]] ScopedVkLoaderEnvironment : angle::NonCopyable
+{
+ public:
+ ScopedVkLoaderEnvironment(bool enableValidationLayers, vk::ICD icd);
+ ~ScopedVkLoaderEnvironment();
+
+ bool canEnableValidationLayers() const { return mEnableValidationLayers; }
+ vk::ICD getEnabledICD() const { return mICD; }
+
+ private:
+ bool setICDEnvironment(const char *icd);
+ bool setCustomExtensionsEnvironment();
+
+ bool mEnableValidationLayers;
+ vk::ICD mICD;
+ bool mChangedCWD;
+ Optional<std::string> mPreviousCWD;
+ bool mChangedICDEnv;
+ Optional<std::string> mPreviousICDEnv;
+ Optional<std::string> mPreviousCustomExtensionsEnv;
+ bool mChangedNoDeviceSelect;
+ Optional<std::string> mPreviousNoDeviceSelectEnv;
+};
+
+void ChoosePhysicalDevice(PFN_vkGetPhysicalDeviceProperties pGetPhysicalDeviceProperties,
+ const std::vector<VkPhysicalDevice> &physicalDevices,
+ vk::ICD preferredICD,
+ uint32_t preferredVendorID,
+ uint32_t preferredDeviceID,
+ VkPhysicalDevice *physicalDeviceOut,
+ VkPhysicalDeviceProperties *physicalDevicePropertiesOut);
+
+} // namespace vk
+
+} // namespace angle
+
+#endif // COMMON_VULKAN_VULKAN_ICD_H_
diff --git a/gfx/angle/checkout/src/compiler/preprocessor/DiagnosticsBase.cpp b/gfx/angle/checkout/src/compiler/preprocessor/DiagnosticsBase.cpp
new file mode 100644
index 0000000000..1d613ec4f4
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/preprocessor/DiagnosticsBase.cpp
@@ -0,0 +1,148 @@
+//
+// Copyright 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/preprocessor/DiagnosticsBase.h"
+
+#include "common/debug.h"
+
+namespace angle
+{
+
+namespace pp
+{
+
+Diagnostics::~Diagnostics() {}
+
+void Diagnostics::report(ID id, const SourceLocation &loc, const std::string &text)
+{
+ print(id, loc, text);
+}
+
+bool Diagnostics::isError(ID id)
+{
+ if ((id > PP_ERROR_BEGIN) && (id < PP_ERROR_END))
+ return true;
+
+ if ((id > PP_WARNING_BEGIN) && (id < PP_WARNING_END))
+ return false;
+
+ UNREACHABLE();
+ return true;
+}
+
+const char *Diagnostics::message(ID id)
+{
+ switch (id)
+ {
+ // Errors begin.
+ case PP_INTERNAL_ERROR:
+ return "internal error";
+ case PP_OUT_OF_MEMORY:
+ return "out of memory";
+ case PP_INVALID_CHARACTER:
+ return "invalid character";
+ case PP_INVALID_NUMBER:
+ return "invalid number";
+ case PP_INTEGER_OVERFLOW:
+ return "integer overflow";
+ case PP_FLOAT_OVERFLOW:
+ return "float overflow";
+ case PP_TOKEN_TOO_LONG:
+ return "token too long";
+ case PP_INVALID_EXPRESSION:
+ return "invalid expression";
+ case PP_DIVISION_BY_ZERO:
+ return "division by zero";
+ case PP_EOF_IN_COMMENT:
+ return "unexpected end of file found in comment";
+ case PP_UNEXPECTED_TOKEN:
+ return "unexpected token";
+ case PP_DIRECTIVE_INVALID_NAME:
+ return "invalid directive name";
+ case PP_MACRO_NAME_RESERVED:
+ return "macro name is reserved";
+ case PP_MACRO_REDEFINED:
+ return "macro redefined";
+ case PP_MACRO_PREDEFINED_REDEFINED:
+ return "predefined macro redefined";
+ case PP_MACRO_PREDEFINED_UNDEFINED:
+ 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:
+ return "Too many arguments for macro";
+ case PP_MACRO_DUPLICATE_PARAMETER_NAMES:
+ return "duplicate macro parameter name";
+ case PP_MACRO_INVOCATION_CHAIN_TOO_DEEP:
+ return "macro invocation chain too deep";
+ case PP_CONDITIONAL_ENDIF_WITHOUT_IF:
+ return "unexpected #endif found without a matching #if";
+ case PP_CONDITIONAL_ELSE_WITHOUT_IF:
+ return "unexpected #else found without a matching #if";
+ case PP_CONDITIONAL_ELSE_AFTER_ELSE:
+ return "unexpected #else found after another #else";
+ case PP_CONDITIONAL_ELIF_WITHOUT_IF:
+ return "unexpected #elif found without a matching #if";
+ case PP_CONDITIONAL_ELIF_AFTER_ELSE:
+ return "unexpected #elif found after #else";
+ case PP_CONDITIONAL_UNTERMINATED:
+ return "unexpected end of file found in conditional block";
+ case PP_INVALID_EXTENSION_NAME:
+ return "invalid extension name";
+ case PP_INVALID_EXTENSION_BEHAVIOR:
+ return "invalid extension behavior";
+ case PP_INVALID_EXTENSION_DIRECTIVE:
+ return "invalid extension directive";
+ case PP_INVALID_VERSION_NUMBER:
+ return "invalid version number";
+ case PP_INVALID_VERSION_DIRECTIVE:
+ return "invalid version directive";
+ case PP_VERSION_NOT_FIRST_STATEMENT:
+ return "#version directive must occur before anything else, "
+ "except for comments and white space";
+ case PP_VERSION_NOT_FIRST_LINE_ESSL3:
+ return "#version directive must occur on the first line of the shader";
+ case PP_INVALID_LINE_NUMBER:
+ return "invalid line number";
+ case PP_INVALID_FILE_NUMBER:
+ return "invalid file number";
+ case PP_INVALID_LINE_DIRECTIVE:
+ return "invalid line directive";
+ case PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL1:
+ return "extension directive must occur before any non-preprocessor tokens in ESSL1";
+ 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";
+ case PP_TOKENIZER_ERROR:
+ return "internal tokenizer error";
+ // Errors end.
+ // Warnings begin.
+ case PP_EOF_IN_DIRECTIVE:
+ return "unexpected end of file found in directive";
+ case PP_CONDITIONAL_UNEXPECTED_TOKEN:
+ return "unexpected token after conditional expression";
+ case PP_UNRECOGNIZED_PRAGMA:
+ return "unrecognized pragma";
+ case PP_NON_PP_TOKEN_BEFORE_EXTENSION_WEBGL:
+ return "extension directive should occur before any non-preprocessor tokens";
+ case PP_WARNING_MACRO_NAME_RESERVED:
+ return "macro name with a double underscore is reserved - unintented behavior is "
+ "possible";
+ // Warnings end.
+ default:
+ UNREACHABLE();
+ return "";
+ }
+}
+
+} // namespace pp
+
+} // namespace angle
diff --git a/gfx/angle/checkout/src/compiler/preprocessor/DiagnosticsBase.h b/gfx/angle/checkout/src/compiler/preprocessor/DiagnosticsBase.h
new file mode 100644
index 0000000000..36f717c4a2
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/preprocessor/DiagnosticsBase.h
@@ -0,0 +1,102 @@
+//
+// Copyright 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_PREPROCESSOR_DIAGNOSTICSBASE_H_
+#define COMPILER_PREPROCESSOR_DIAGNOSTICSBASE_H_
+
+#include <string>
+
+namespace angle
+{
+
+namespace pp
+{
+
+struct SourceLocation;
+
+// Base class for reporting diagnostic messages.
+// Derived classes are responsible for formatting and printing the messages.
+class Diagnostics
+{
+ public:
+ enum ID
+ {
+ PP_ERROR_BEGIN,
+ PP_INTERNAL_ERROR,
+ PP_OUT_OF_MEMORY,
+ PP_INVALID_CHARACTER,
+ PP_INVALID_NUMBER,
+ PP_INTEGER_OVERFLOW,
+ PP_FLOAT_OVERFLOW,
+ PP_TOKEN_TOO_LONG,
+ PP_INVALID_EXPRESSION,
+ PP_DIVISION_BY_ZERO,
+ PP_EOF_IN_COMMENT,
+ PP_UNEXPECTED_TOKEN,
+ PP_DIRECTIVE_INVALID_NAME,
+ PP_MACRO_NAME_RESERVED,
+ PP_MACRO_REDEFINED,
+ 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,
+ PP_MACRO_INVOCATION_CHAIN_TOO_DEEP,
+ PP_CONDITIONAL_ENDIF_WITHOUT_IF,
+ PP_CONDITIONAL_ELSE_WITHOUT_IF,
+ PP_CONDITIONAL_ELSE_AFTER_ELSE,
+ PP_CONDITIONAL_ELIF_WITHOUT_IF,
+ PP_CONDITIONAL_ELIF_AFTER_ELSE,
+ PP_CONDITIONAL_UNTERMINATED,
+ PP_CONDITIONAL_UNEXPECTED_TOKEN,
+ PP_INVALID_EXTENSION_NAME,
+ PP_INVALID_EXTENSION_BEHAVIOR,
+ PP_INVALID_EXTENSION_DIRECTIVE,
+ PP_INVALID_VERSION_NUMBER,
+ PP_INVALID_VERSION_DIRECTIVE,
+ PP_VERSION_NOT_FIRST_STATEMENT,
+ PP_VERSION_NOT_FIRST_LINE_ESSL3,
+ PP_INVALID_LINE_NUMBER,
+ PP_INVALID_FILE_NUMBER,
+ PP_INVALID_LINE_DIRECTIVE,
+ // This is just a warning on CHROME OS http://anglebug.com/4023
+#if !defined(ANGLE_PLATFORM_CHROMEOS)
+ PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL1,
+#endif
+ PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL3,
+ PP_UNDEFINED_SHIFT,
+ PP_TOKENIZER_ERROR,
+ PP_ERROR_END,
+
+ PP_WARNING_BEGIN,
+ PP_EOF_IN_DIRECTIVE,
+ PP_UNRECOGNIZED_PRAGMA,
+#if defined(ANGLE_PLATFORM_CHROMEOS)
+ PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL1,
+#endif
+ PP_NON_PP_TOKEN_BEFORE_EXTENSION_WEBGL,
+ PP_WARNING_MACRO_NAME_RESERVED,
+ PP_WARNING_END
+ };
+
+ virtual ~Diagnostics();
+
+ void report(ID id, const SourceLocation &loc, const std::string &text);
+
+ protected:
+ bool isError(ID id);
+ const char *message(ID id);
+
+ virtual void print(ID id, const SourceLocation &loc, const std::string &text) = 0;
+};
+
+} // namespace pp
+
+} // namespace angle
+
+#endif // COMPILER_PREPROCESSOR_DIAGNOSTICSBASE_H_
diff --git a/gfx/angle/checkout/src/compiler/preprocessor/DirectiveHandlerBase.cpp b/gfx/angle/checkout/src/compiler/preprocessor/DirectiveHandlerBase.cpp
new file mode 100644
index 0000000000..7612d136e8
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/preprocessor/DirectiveHandlerBase.cpp
@@ -0,0 +1,19 @@
+//
+// Copyright 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/preprocessor/DirectiveHandlerBase.h"
+
+namespace angle
+{
+
+namespace pp
+{
+
+DirectiveHandler::~DirectiveHandler() {}
+
+} // namespace pp
+
+} // namespace angle
diff --git a/gfx/angle/checkout/src/compiler/preprocessor/DirectiveHandlerBase.h b/gfx/angle/checkout/src/compiler/preprocessor/DirectiveHandlerBase.h
new file mode 100644
index 0000000000..c1fd44510d
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/preprocessor/DirectiveHandlerBase.h
@@ -0,0 +1,49 @@
+//
+// Copyright 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_PREPROCESSOR_DIRECTIVEHANDLERBASE_H_
+#define COMPILER_PREPROCESSOR_DIRECTIVEHANDLERBASE_H_
+
+#include <string>
+#include "GLSLANG/ShaderLang.h"
+
+namespace angle
+{
+
+namespace pp
+{
+
+struct SourceLocation;
+
+// Base class for handling directives.
+// Preprocessor uses this class to notify the clients about certain
+// preprocessor directives. Derived classes are responsible for
+// handling them in an appropriate manner.
+class DirectiveHandler
+{
+ public:
+ virtual ~DirectiveHandler();
+
+ virtual void handleError(const SourceLocation &loc, const std::string &msg) = 0;
+
+ // Handle pragma of form: #pragma name[(value)]
+ virtual void handlePragma(const SourceLocation &loc,
+ const std::string &name,
+ const std::string &value,
+ bool stdgl) = 0;
+
+ virtual void handleExtension(const SourceLocation &loc,
+ const std::string &name,
+ const std::string &behavior) = 0;
+
+ virtual void handleVersion(const SourceLocation &loc, int version, ShShaderSpec spec) = 0;
+};
+
+} // namespace pp
+
+} // namespace angle
+
+#endif // COMPILER_PREPROCESSOR_DIRECTIVEHANDLERBASE_H_
diff --git a/gfx/angle/checkout/src/compiler/preprocessor/DirectiveParser.cpp b/gfx/angle/checkout/src/compiler/preprocessor/DirectiveParser.cpp
new file mode 100644
index 0000000000..30167e2a5a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/preprocessor/DirectiveParser.cpp
@@ -0,0 +1,981 @@
+//
+// Copyright 2011 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/preprocessor/DirectiveParser.h"
+
+#include <algorithm>
+#include <cstdlib>
+#include <sstream>
+
+#include "GLSLANG/ShaderLang.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 angle
+{
+
+namespace
+{
+enum DirectiveType
+{
+ DIRECTIVE_NONE,
+ DIRECTIVE_DEFINE,
+ DIRECTIVE_UNDEF,
+ DIRECTIVE_IF,
+ DIRECTIVE_IFDEF,
+ DIRECTIVE_IFNDEF,
+ DIRECTIVE_ELSE,
+ DIRECTIVE_ELIF,
+ DIRECTIVE_ENDIF,
+ DIRECTIVE_ERROR,
+ DIRECTIVE_PRAGMA,
+ DIRECTIVE_EXTENSION,
+ DIRECTIVE_VERSION,
+ DIRECTIVE_LINE
+};
+
+DirectiveType getDirective(const pp::Token *token)
+{
+ const char kDirectiveDefine[] = "define";
+ const char kDirectiveUndef[] = "undef";
+ const char kDirectiveIf[] = "if";
+ const char kDirectiveIfdef[] = "ifdef";
+ const char kDirectiveIfndef[] = "ifndef";
+ const char kDirectiveElse[] = "else";
+ const char kDirectiveElif[] = "elif";
+ const char kDirectiveEndif[] = "endif";
+ const char kDirectiveError[] = "error";
+ const char kDirectivePragma[] = "pragma";
+ const char kDirectiveExtension[] = "extension";
+ const char kDirectiveVersion[] = "version";
+ const char kDirectiveLine[] = "line";
+
+ if (token->type != pp::Token::IDENTIFIER)
+ return DIRECTIVE_NONE;
+
+ if (token->text == kDirectiveDefine)
+ return DIRECTIVE_DEFINE;
+ if (token->text == kDirectiveUndef)
+ return DIRECTIVE_UNDEF;
+ if (token->text == kDirectiveIf)
+ return DIRECTIVE_IF;
+ if (token->text == kDirectiveIfdef)
+ return DIRECTIVE_IFDEF;
+ if (token->text == kDirectiveIfndef)
+ return DIRECTIVE_IFNDEF;
+ if (token->text == kDirectiveElse)
+ return DIRECTIVE_ELSE;
+ if (token->text == kDirectiveElif)
+ return DIRECTIVE_ELIF;
+ if (token->text == kDirectiveEndif)
+ return DIRECTIVE_ENDIF;
+ if (token->text == kDirectiveError)
+ return DIRECTIVE_ERROR;
+ if (token->text == kDirectivePragma)
+ return DIRECTIVE_PRAGMA;
+ if (token->text == kDirectiveExtension)
+ return DIRECTIVE_EXTENSION;
+ if (token->text == kDirectiveVersion)
+ return DIRECTIVE_VERSION;
+ if (token->text == kDirectiveLine)
+ return DIRECTIVE_LINE;
+
+ return DIRECTIVE_NONE;
+}
+
+bool isConditionalDirective(DirectiveType directive)
+{
+ switch (directive)
+ {
+ case DIRECTIVE_IF:
+ case DIRECTIVE_IFDEF:
+ case DIRECTIVE_IFNDEF:
+ case DIRECTIVE_ELSE:
+ case DIRECTIVE_ELIF:
+ case DIRECTIVE_ENDIF:
+ return true;
+ default:
+ return false;
+ }
+}
+
+// Returns true if the token represents End Of Directive.
+bool isEOD(const pp::Token *token)
+{
+ return (token->type == '\n') || (token->type == pp::Token::LAST);
+}
+
+void skipUntilEOD(pp::Lexer *lexer, pp::Token *token)
+{
+ while (!isEOD(token))
+ {
+ lexer->lex(token);
+ }
+}
+
+bool isMacroNameReserved(const std::string &name)
+{
+ // Names prefixed with "GL_" and the name "defined" are reserved.
+ return name == "defined" || (name.substr(0, 3) == "GL_");
+}
+
+bool hasDoubleUnderscores(const std::string &name)
+{
+ return (name.find("__") != std::string::npos);
+}
+
+bool isMacroPredefined(const std::string &name, const pp::MacroSet &macroSet)
+{
+ pp::MacroSet::const_iterator iter = macroSet.find(name);
+ return iter != macroSet.end() ? iter->second->predefined : false;
+}
+
+} // namespace
+
+namespace pp
+{
+DirectiveParser::DirectiveParser(Tokenizer *tokenizer,
+ MacroSet *macroSet,
+ Diagnostics *diagnostics,
+ DirectiveHandler *directiveHandler,
+ const PreprocessorSettings &settings)
+ : mPastFirstStatement(false),
+ mSeenNonPreprocessorToken(false),
+ mTokenizer(tokenizer),
+ mMacroSet(macroSet),
+ mDiagnostics(diagnostics),
+ mDirectiveHandler(directiveHandler),
+ mShaderVersion(100),
+ mSettings(settings)
+{}
+
+DirectiveParser::~DirectiveParser() {}
+
+void DirectiveParser::lex(Token *token)
+{
+ do
+ {
+ mTokenizer->lex(token);
+
+ if (token->type == Token::PP_HASH)
+ {
+ parseDirective(token);
+ mPastFirstStatement = true;
+ }
+ else if (!isEOD(token) && !skipping())
+ {
+ mSeenNonPreprocessorToken = true;
+ }
+
+ if (token->type == Token::LAST)
+ {
+ if (!mConditionalStack.empty())
+ {
+ const ConditionalBlock &block = mConditionalStack.back();
+ mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNTERMINATED, block.location,
+ block.type);
+ }
+ break;
+ }
+
+ } while (skipping() || (token->type == '\n'));
+
+ mPastFirstStatement = true;
+}
+
+void DirectiveParser::parseDirective(Token *token)
+{
+ ASSERT(token->type == Token::PP_HASH);
+
+ mTokenizer->lex(token);
+ if (isEOD(token))
+ {
+ // Empty Directive.
+ return;
+ }
+
+ DirectiveType directive = getDirective(token);
+
+ // While in an excluded conditional block/group,
+ // we only parse conditional directives.
+ if (skipping() && !isConditionalDirective(directive))
+ {
+ skipUntilEOD(mTokenizer, token);
+ return;
+ }
+
+ switch (directive)
+ {
+ case DIRECTIVE_NONE:
+ mDiagnostics->report(Diagnostics::PP_DIRECTIVE_INVALID_NAME, token->location,
+ token->text);
+ skipUntilEOD(mTokenizer, token);
+ break;
+ case DIRECTIVE_DEFINE:
+ parseDefine(token);
+ break;
+ case DIRECTIVE_UNDEF:
+ parseUndef(token);
+ break;
+ case DIRECTIVE_IF:
+ parseIf(token);
+ break;
+ case DIRECTIVE_IFDEF:
+ parseIfdef(token);
+ break;
+ case DIRECTIVE_IFNDEF:
+ parseIfndef(token);
+ break;
+ case DIRECTIVE_ELSE:
+ parseElse(token);
+ break;
+ case DIRECTIVE_ELIF:
+ parseElif(token);
+ break;
+ case DIRECTIVE_ENDIF:
+ parseEndif(token);
+ break;
+ case DIRECTIVE_ERROR:
+ parseError(token);
+ break;
+ case DIRECTIVE_PRAGMA:
+ parsePragma(token);
+ break;
+ case DIRECTIVE_EXTENSION:
+ parseExtension(token);
+ break;
+ case DIRECTIVE_VERSION:
+ parseVersion(token);
+ break;
+ case DIRECTIVE_LINE:
+ parseLine(token);
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ skipUntilEOD(mTokenizer, token);
+ if (token->type == Token::LAST)
+ {
+ mDiagnostics->report(Diagnostics::PP_EOF_IN_DIRECTIVE, token->location, token->text);
+ }
+}
+
+void DirectiveParser::parseDefine(Token *token)
+{
+ ASSERT(getDirective(token) == DIRECTIVE_DEFINE);
+
+ mTokenizer->lex(token);
+ if (token->type != Token::IDENTIFIER)
+ {
+ mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text);
+ return;
+ }
+ if (isMacroPredefined(token->text, *mMacroSet))
+ {
+ mDiagnostics->report(Diagnostics::PP_MACRO_PREDEFINED_REDEFINED, token->location,
+ token->text);
+ return;
+ }
+ if (isMacroNameReserved(token->text))
+ {
+ mDiagnostics->report(Diagnostics::PP_MACRO_NAME_RESERVED, token->location, token->text);
+ return;
+ }
+ // Using double underscores is allowed, but may result in unintended
+ // behavior, so a warning is issued. At the time of writing this was
+ // specified in ESSL 3.10, but the intent judging from Khronos
+ // discussions and dEQP tests was that double underscores should be
+ // allowed in earlier ESSL versions too.
+ if (hasDoubleUnderscores(token->text))
+ {
+ mDiagnostics->report(Diagnostics::PP_WARNING_MACRO_NAME_RESERVED, token->location,
+ token->text);
+ }
+
+ std::shared_ptr<Macro> macro = std::make_shared<Macro>();
+ macro->type = Macro::kTypeObj;
+ macro->name = token->text;
+
+ mTokenizer->lex(token);
+ if (token->type == '(' && !token->hasLeadingSpace())
+ {
+ // Function-like macro. Collect arguments.
+ macro->type = Macro::kTypeFunc;
+ do
+ {
+ mTokenizer->lex(token);
+ if (token->type != Token::IDENTIFIER)
+ break;
+
+ if (std::find(macro->parameters.begin(), macro->parameters.end(), token->text) !=
+ macro->parameters.end())
+ {
+ mDiagnostics->report(Diagnostics::PP_MACRO_DUPLICATE_PARAMETER_NAMES,
+ token->location, token->text);
+ return;
+ }
+
+ macro->parameters.push_back(token->text);
+
+ mTokenizer->lex(token); // Get ','.
+ } while (token->type == ',');
+
+ if (token->type != ')')
+ {
+ mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text);
+ return;
+ }
+ mTokenizer->lex(token); // Get ')'.
+ }
+
+ while ((token->type != '\n') && (token->type != Token::LAST))
+ {
+ // Reset the token location because it is unnecessary in replacement
+ // list. Resetting it also allows us to reuse Token::equals() to
+ // compare macros.
+ token->location = SourceLocation();
+ macro->replacements.push_back(*token);
+ mTokenizer->lex(token);
+ }
+ if (!macro->replacements.empty())
+ {
+ // Whitespace preceding the replacement list is not considered part of
+ // the replacement list for either form of macro.
+ macro->replacements.front().setHasLeadingSpace(false);
+ }
+
+ // Check for macro redefinition.
+ MacroSet::const_iterator iter = mMacroSet->find(macro->name);
+ if (iter != mMacroSet->end() && !macro->equals(*iter->second))
+ {
+ mDiagnostics->report(Diagnostics::PP_MACRO_REDEFINED, token->location, macro->name);
+ return;
+ }
+ mMacroSet->insert(std::make_pair(macro->name, macro));
+}
+
+void DirectiveParser::parseUndef(Token *token)
+{
+ ASSERT(getDirective(token) == DIRECTIVE_UNDEF);
+
+ mTokenizer->lex(token);
+ if (token->type != Token::IDENTIFIER)
+ {
+ mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text);
+ return;
+ }
+
+ MacroSet::iterator iter = mMacroSet->find(token->text);
+ if (iter != mMacroSet->end())
+ {
+ if (iter->second->predefined)
+ {
+ 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
+ {
+ mMacroSet->erase(iter);
+ }
+ }
+
+ mTokenizer->lex(token);
+ if (!isEOD(token))
+ {
+ mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text);
+ skipUntilEOD(mTokenizer, token);
+ }
+}
+
+void DirectiveParser::parseIf(Token *token)
+{
+ ASSERT(getDirective(token) == DIRECTIVE_IF);
+ parseConditionalIf(token);
+}
+
+void DirectiveParser::parseIfdef(Token *token)
+{
+ ASSERT(getDirective(token) == DIRECTIVE_IFDEF);
+ parseConditionalIf(token);
+}
+
+void DirectiveParser::parseIfndef(Token *token)
+{
+ ASSERT(getDirective(token) == DIRECTIVE_IFNDEF);
+ parseConditionalIf(token);
+}
+
+void DirectiveParser::parseElse(Token *token)
+{
+ ASSERT(getDirective(token) == DIRECTIVE_ELSE);
+
+ if (mConditionalStack.empty())
+ {
+ mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ELSE_WITHOUT_IF, token->location,
+ token->text);
+ skipUntilEOD(mTokenizer, token);
+ return;
+ }
+
+ ConditionalBlock &block = mConditionalStack.back();
+ if (block.skipBlock)
+ {
+ // No diagnostics. Just skip the whole line.
+ skipUntilEOD(mTokenizer, token);
+ return;
+ }
+ if (block.foundElseGroup)
+ {
+ mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ELSE_AFTER_ELSE, token->location,
+ token->text);
+ skipUntilEOD(mTokenizer, token);
+ return;
+ }
+
+ block.foundElseGroup = true;
+ block.skipGroup = block.foundValidGroup;
+ block.foundValidGroup = true;
+
+ // Check if there are extra tokens after #else.
+ mTokenizer->lex(token);
+ if (!isEOD(token))
+ {
+ mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN, token->location,
+ token->text);
+ skipUntilEOD(mTokenizer, token);
+ }
+}
+
+void DirectiveParser::parseElif(Token *token)
+{
+ ASSERT(getDirective(token) == DIRECTIVE_ELIF);
+
+ if (mConditionalStack.empty())
+ {
+ mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ELIF_WITHOUT_IF, token->location,
+ token->text);
+ skipUntilEOD(mTokenizer, token);
+ return;
+ }
+
+ ConditionalBlock &block = mConditionalStack.back();
+ if (block.skipBlock)
+ {
+ // No diagnostics. Just skip the whole line.
+ skipUntilEOD(mTokenizer, token);
+ return;
+ }
+ if (block.foundElseGroup)
+ {
+ mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ELIF_AFTER_ELSE, token->location,
+ token->text);
+ skipUntilEOD(mTokenizer, token);
+ return;
+ }
+ if (block.foundValidGroup)
+ {
+ // Do not parse the expression.
+ // Also be careful not to emit a diagnostic.
+ block.skipGroup = true;
+ skipUntilEOD(mTokenizer, token);
+ return;
+ }
+
+ int expression = parseExpressionIf(token);
+ block.skipGroup = expression == 0;
+ block.foundValidGroup = expression != 0;
+}
+
+void DirectiveParser::parseEndif(Token *token)
+{
+ ASSERT(getDirective(token) == DIRECTIVE_ENDIF);
+
+ if (mConditionalStack.empty())
+ {
+ mDiagnostics->report(Diagnostics::PP_CONDITIONAL_ENDIF_WITHOUT_IF, token->location,
+ token->text);
+ skipUntilEOD(mTokenizer, token);
+ return;
+ }
+
+ mConditionalStack.pop_back();
+
+ // Check if there are tokens after #endif.
+ mTokenizer->lex(token);
+ if (!isEOD(token))
+ {
+ mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN, token->location,
+ token->text);
+ skipUntilEOD(mTokenizer, token);
+ }
+}
+
+void DirectiveParser::parseError(Token *token)
+{
+ ASSERT(getDirective(token) == DIRECTIVE_ERROR);
+
+ std::ostringstream stream;
+ mTokenizer->lex(token);
+ while ((token->type != '\n') && (token->type != Token::LAST))
+ {
+ stream << *token;
+ mTokenizer->lex(token);
+ }
+ mDirectiveHandler->handleError(token->location, stream.str());
+}
+
+// Parses pragma of form: #pragma name[(value)].
+void DirectiveParser::parsePragma(Token *token)
+{
+ ASSERT(getDirective(token) == DIRECTIVE_PRAGMA);
+
+ enum State
+ {
+ PRAGMA_NAME,
+ LEFT_PAREN,
+ PRAGMA_VALUE,
+ RIGHT_PAREN
+ };
+
+ bool valid = true;
+ std::string name, value;
+ int state = PRAGMA_NAME;
+
+ mTokenizer->lex(token);
+ bool stdgl = token->text == "STDGL";
+ if (stdgl)
+ {
+ mTokenizer->lex(token);
+ }
+ while ((token->type != '\n') && (token->type != Token::LAST))
+ {
+ switch (state++)
+ {
+ case PRAGMA_NAME:
+ name = token->text;
+ valid = valid && (token->type == Token::IDENTIFIER);
+ break;
+ case LEFT_PAREN:
+ valid = valid && (token->type == '(');
+ break;
+ case PRAGMA_VALUE:
+ value = token->text;
+ valid = valid && (token->type == Token::IDENTIFIER);
+ break;
+ case RIGHT_PAREN:
+ valid = valid && (token->type == ')');
+ break;
+ default:
+ valid = false;
+ break;
+ }
+ mTokenizer->lex(token);
+ }
+
+ valid = valid && ((state == PRAGMA_NAME) || // Empty pragma.
+ (state == LEFT_PAREN) || // Without value.
+ (state == RIGHT_PAREN + 1)); // With value.
+ if (!valid)
+ {
+ mDiagnostics->report(Diagnostics::PP_UNRECOGNIZED_PRAGMA, token->location, name);
+ }
+ else if (state > PRAGMA_NAME) // Do not notify for empty pragma.
+ {
+ mDirectiveHandler->handlePragma(token->location, name, value, stdgl);
+ }
+}
+
+void DirectiveParser::parseExtension(Token *token)
+{
+ ASSERT(getDirective(token) == DIRECTIVE_EXTENSION);
+
+ enum State
+ {
+ EXT_NAME,
+ COLON,
+ EXT_BEHAVIOR
+ };
+
+ bool valid = true;
+ std::string name, behavior;
+ int state = EXT_NAME;
+
+ mTokenizer->lex(token);
+ while ((token->type != '\n') && (token->type != Token::LAST))
+ {
+ switch (state++)
+ {
+ case EXT_NAME:
+ if (valid && (token->type != Token::IDENTIFIER))
+ {
+ mDiagnostics->report(Diagnostics::PP_INVALID_EXTENSION_NAME, token->location,
+ token->text);
+ valid = false;
+ }
+ if (valid)
+ name = token->text;
+ break;
+ case COLON:
+ if (valid && (token->type != ':'))
+ {
+ mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location,
+ token->text);
+ valid = false;
+ }
+ break;
+ case EXT_BEHAVIOR:
+ if (valid && (token->type != Token::IDENTIFIER))
+ {
+ mDiagnostics->report(Diagnostics::PP_INVALID_EXTENSION_BEHAVIOR,
+ token->location, token->text);
+ valid = false;
+ }
+ if (valid)
+ behavior = token->text;
+ break;
+ default:
+ if (valid)
+ {
+ mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location,
+ token->text);
+ valid = false;
+ }
+ break;
+ }
+ mTokenizer->lex(token);
+ }
+ if (valid && (state != EXT_BEHAVIOR + 1))
+ {
+ mDiagnostics->report(Diagnostics::PP_INVALID_EXTENSION_DIRECTIVE, token->location,
+ token->text);
+ valid = false;
+ }
+ if (valid && mSeenNonPreprocessorToken)
+ {
+ if (mShaderVersion >= 300)
+ {
+ mDiagnostics->report(Diagnostics::PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL3,
+ token->location, token->text);
+ valid = false;
+ }
+ else
+ {
+ if (mSettings.shaderSpec == SH_WEBGL_SPEC)
+ {
+ mDiagnostics->report(Diagnostics::PP_NON_PP_TOKEN_BEFORE_EXTENSION_WEBGL,
+ token->location, token->text);
+ }
+ else
+ {
+ mDiagnostics->report(Diagnostics::PP_NON_PP_TOKEN_BEFORE_EXTENSION_ESSL1,
+ token->location, token->text);
+ // This is just a warning on CHROME OS http://anglebug.com/4023
+#if !defined(ANGLE_PLATFORM_CHROMEOS)
+ valid = false;
+#endif
+ }
+ }
+ }
+ if (valid)
+ mDirectiveHandler->handleExtension(token->location, name, behavior);
+}
+
+void DirectiveParser::parseVersion(Token *token)
+{
+ ASSERT(getDirective(token) == DIRECTIVE_VERSION);
+
+ if (mPastFirstStatement)
+ {
+ mDiagnostics->report(Diagnostics::PP_VERSION_NOT_FIRST_STATEMENT, token->location,
+ token->text);
+ skipUntilEOD(mTokenizer, token);
+ return;
+ }
+
+ enum State
+ {
+ VERSION_NUMBER,
+ VERSION_PROFILE_ES,
+ VERSION_PROFILE_GL,
+ VERSION_ENDLINE
+ };
+
+ bool valid = true;
+ int version = 0;
+ int state = VERSION_NUMBER;
+
+ mTokenizer->lex(token);
+ while (valid && (token->type != '\n') && (token->type != Token::LAST))
+ {
+ switch (state)
+ {
+ case VERSION_NUMBER:
+ if (token->type != Token::CONST_INT)
+ {
+ mDiagnostics->report(Diagnostics::PP_INVALID_VERSION_NUMBER, token->location,
+ token->text);
+ valid = false;
+ }
+ if (valid && !token->iValue(&version))
+ {
+ mDiagnostics->report(Diagnostics::PP_INTEGER_OVERFLOW, token->location,
+ token->text);
+ valid = false;
+ }
+ if (valid)
+ {
+ if (sh::IsDesktopGLSpec(mSettings.shaderSpec))
+ {
+ state = VERSION_PROFILE_GL;
+ }
+ else if (version < 300)
+ {
+ state = VERSION_ENDLINE;
+ }
+ else
+ {
+ state = VERSION_PROFILE_ES;
+ }
+ }
+ break;
+ case VERSION_PROFILE_ES:
+ ASSERT(!sh::IsDesktopGLSpec(mSettings.shaderSpec));
+ if (token->type != Token::IDENTIFIER || token->text != "es")
+ {
+ mDiagnostics->report(Diagnostics::PP_INVALID_VERSION_DIRECTIVE, token->location,
+ token->text);
+ valid = false;
+ }
+ state = VERSION_ENDLINE;
+ break;
+ case VERSION_PROFILE_GL:
+ ASSERT(sh::IsDesktopGLSpec(mSettings.shaderSpec));
+ if (token->type != Token::IDENTIFIER || token->text != "core")
+ {
+ mDiagnostics->report(Diagnostics::PP_INVALID_VERSION_DIRECTIVE, token->location,
+ token->text);
+ valid = false;
+ }
+ state = VERSION_ENDLINE;
+ break;
+ default:
+ mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location,
+ token->text);
+ valid = false;
+ break;
+ }
+
+ mTokenizer->lex(token);
+
+ if (token->type == '\n' && state == VERSION_PROFILE_GL)
+ {
+ state = VERSION_ENDLINE;
+ }
+ }
+
+ if (valid && (state != VERSION_ENDLINE))
+ {
+ mDiagnostics->report(Diagnostics::PP_INVALID_VERSION_DIRECTIVE, token->location,
+ token->text);
+ valid = false;
+ }
+
+ if (valid && version >= 300 && token->location.line > 1)
+ {
+ mDiagnostics->report(Diagnostics::PP_VERSION_NOT_FIRST_LINE_ESSL3, token->location,
+ token->text);
+ valid = false;
+ }
+
+ if (valid)
+ {
+ mDirectiveHandler->handleVersion(token->location, version, mSettings.shaderSpec);
+ mShaderVersion = version;
+ PredefineMacro(mMacroSet, "__VERSION__", version);
+ }
+}
+
+void DirectiveParser::parseLine(Token *token)
+{
+ ASSERT(getDirective(token) == DIRECTIVE_LINE);
+
+ bool valid = true;
+ bool parsedFileNumber = false;
+ int line = 0, file = 0;
+
+ MacroExpander macroExpander(mTokenizer, mMacroSet, mDiagnostics, mSettings, false);
+
+ // Lex the first token after "#line" so we can check it for EOD.
+ macroExpander.lex(token);
+
+ if (isEOD(token))
+ {
+ mDiagnostics->report(Diagnostics::PP_INVALID_LINE_DIRECTIVE, token->location, token->text);
+ valid = false;
+ }
+ else
+ {
+ ExpressionParser expressionParser(&macroExpander, mDiagnostics);
+ ExpressionParser::ErrorSettings errorSettings;
+
+ // See GLES3 section 12.42
+ errorSettings.integerLiteralsMustFit32BitSignedRange = true;
+
+ errorSettings.unexpectedIdentifier = Diagnostics::PP_INVALID_LINE_NUMBER;
+ // The first token was lexed earlier to check if it was EOD. Include
+ // the token in parsing for a second time by setting the
+ // parsePresetToken flag to true.
+ expressionParser.parse(token, &line, true, errorSettings, &valid);
+ if (!isEOD(token) && valid)
+ {
+ errorSettings.unexpectedIdentifier = Diagnostics::PP_INVALID_FILE_NUMBER;
+ // After parsing the line expression expressionParser has also
+ // advanced to the first token of the file expression - this is the
+ // token that makes the parser reduce the "input" rule for the line
+ // expression and stop. So we're using parsePresetToken = true here
+ // as well.
+ expressionParser.parse(token, &file, true, errorSettings, &valid);
+ parsedFileNumber = true;
+ }
+ if (!isEOD(token))
+ {
+ if (valid)
+ {
+ mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location,
+ token->text);
+ valid = false;
+ }
+ skipUntilEOD(mTokenizer, token);
+ }
+ }
+
+ if (valid)
+ {
+ mTokenizer->setLineNumber(line);
+ if (parsedFileNumber)
+ mTokenizer->setFileNumber(file);
+ }
+}
+
+bool DirectiveParser::skipping() const
+{
+ if (mConditionalStack.empty())
+ return false;
+
+ const ConditionalBlock &block = mConditionalStack.back();
+ return block.skipBlock || block.skipGroup;
+}
+
+void DirectiveParser::parseConditionalIf(Token *token)
+{
+ ConditionalBlock block;
+ block.type = token->text;
+ block.location = token->location;
+
+ if (skipping())
+ {
+ // This conditional block is inside another conditional group
+ // which is skipped. As a consequence this whole block is skipped.
+ // Be careful not to parse the conditional expression that might
+ // emit a diagnostic.
+ skipUntilEOD(mTokenizer, token);
+ block.skipBlock = true;
+ }
+ else
+ {
+ DirectiveType directive = getDirective(token);
+
+ int expression = 0;
+ switch (directive)
+ {
+ case DIRECTIVE_IF:
+ expression = parseExpressionIf(token);
+ break;
+ case DIRECTIVE_IFDEF:
+ expression = parseExpressionIfdef(token);
+ break;
+ case DIRECTIVE_IFNDEF:
+ expression = parseExpressionIfdef(token) == 0 ? 1 : 0;
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ block.skipGroup = expression == 0;
+ block.foundValidGroup = expression != 0;
+ }
+ mConditionalStack.push_back(block);
+}
+
+int DirectiveParser::parseExpressionIf(Token *token)
+{
+ ASSERT((getDirective(token) == DIRECTIVE_IF) || (getDirective(token) == DIRECTIVE_ELIF));
+
+ MacroExpander macroExpander(mTokenizer, mMacroSet, mDiagnostics, mSettings, true);
+ ExpressionParser expressionParser(&macroExpander, mDiagnostics);
+
+ int expression = 0;
+ ExpressionParser::ErrorSettings errorSettings;
+ errorSettings.integerLiteralsMustFit32BitSignedRange = false;
+ errorSettings.unexpectedIdentifier = Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN;
+
+ bool valid = true;
+ expressionParser.parse(token, &expression, false, errorSettings, &valid);
+
+ // Check if there are tokens after #if expression.
+ if (!isEOD(token))
+ {
+ mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN, token->location,
+ token->text);
+ skipUntilEOD(mTokenizer, token);
+ }
+
+ return expression;
+}
+
+int DirectiveParser::parseExpressionIfdef(Token *token)
+{
+ ASSERT((getDirective(token) == DIRECTIVE_IFDEF) || (getDirective(token) == DIRECTIVE_IFNDEF));
+
+ mTokenizer->lex(token);
+ if (token->type != Token::IDENTIFIER)
+ {
+ mDiagnostics->report(Diagnostics::PP_UNEXPECTED_TOKEN, token->location, token->text);
+ skipUntilEOD(mTokenizer, token);
+ return 0;
+ }
+
+ MacroSet::const_iterator iter = mMacroSet->find(token->text);
+ int expression = iter != mMacroSet->end() ? 1 : 0;
+
+ // Check if there are tokens after #ifdef expression.
+ mTokenizer->lex(token);
+ if (!isEOD(token))
+ {
+ mDiagnostics->report(Diagnostics::PP_CONDITIONAL_UNEXPECTED_TOKEN, token->location,
+ token->text);
+ skipUntilEOD(mTokenizer, token);
+ }
+ return expression;
+}
+
+} // namespace pp
+
+} // namespace angle
diff --git a/gfx/angle/checkout/src/compiler/preprocessor/DirectiveParser.h b/gfx/angle/checkout/src/compiler/preprocessor/DirectiveParser.h
new file mode 100644
index 0000000000..16be79d9a1
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/preprocessor/DirectiveParser.h
@@ -0,0 +1,88 @@
+//
+// Copyright 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_PREPROCESSOR_DIRECTIVEPARSER_H_
+#define COMPILER_PREPROCESSOR_DIRECTIVEPARSER_H_
+
+#include "compiler/preprocessor/Lexer.h"
+#include "compiler/preprocessor/Macro.h"
+#include "compiler/preprocessor/Preprocessor.h"
+#include "compiler/preprocessor/SourceLocation.h"
+
+namespace angle
+{
+
+namespace pp
+{
+
+class Diagnostics;
+class DirectiveHandler;
+class Tokenizer;
+
+class DirectiveParser : public Lexer
+{
+ public:
+ DirectiveParser(Tokenizer *tokenizer,
+ MacroSet *macroSet,
+ Diagnostics *diagnostics,
+ DirectiveHandler *directiveHandler,
+ const PreprocessorSettings &settings);
+ ~DirectiveParser() override;
+
+ void lex(Token *token) override;
+
+ private:
+ void parseDirective(Token *token);
+ void parseDefine(Token *token);
+ void parseUndef(Token *token);
+ void parseIf(Token *token);
+ void parseIfdef(Token *token);
+ void parseIfndef(Token *token);
+ void parseElse(Token *token);
+ void parseElif(Token *token);
+ void parseEndif(Token *token);
+ void parseError(Token *token);
+ void parsePragma(Token *token);
+ void parseExtension(Token *token);
+ void parseVersion(Token *token);
+ void parseLine(Token *token);
+
+ bool skipping() const;
+ void parseConditionalIf(Token *token);
+ int parseExpressionIf(Token *token);
+ int parseExpressionIfdef(Token *token);
+
+ struct ConditionalBlock
+ {
+ std::string type;
+ SourceLocation location;
+ bool skipBlock;
+ bool skipGroup;
+ bool foundValidGroup;
+ bool foundElseGroup;
+
+ ConditionalBlock()
+ : skipBlock(false), skipGroup(false), foundValidGroup(false), foundElseGroup(false)
+ {}
+ };
+ bool mPastFirstStatement;
+ bool mSeenNonPreprocessorToken; // Tracks if a non-preprocessor token has been seen yet. Some
+ // macros, such as
+ // #extension must be declared before all shader code.
+ std::vector<ConditionalBlock> mConditionalStack;
+ Tokenizer *mTokenizer;
+ MacroSet *mMacroSet;
+ Diagnostics *mDiagnostics;
+ DirectiveHandler *mDirectiveHandler;
+ int mShaderVersion;
+ const PreprocessorSettings mSettings;
+};
+
+} // namespace pp
+
+} // namespace angle
+
+#endif // COMPILER_PREPROCESSOR_DIRECTIVEPARSER_H_
diff --git a/gfx/angle/checkout/src/compiler/preprocessor/ExpressionParser.h b/gfx/angle/checkout/src/compiler/preprocessor/ExpressionParser.h
new file mode 100644
index 0000000000..3bb9d13c20
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/preprocessor/ExpressionParser.h
@@ -0,0 +1,48 @@
+//
+// Copyright 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_PREPROCESSOR_EXPRESSIONPARSER_H_
+#define COMPILER_PREPROCESSOR_EXPRESSIONPARSER_H_
+
+#include "common/angleutils.h"
+#include "compiler/preprocessor/DiagnosticsBase.h"
+
+namespace angle
+{
+
+namespace pp
+{
+
+class Lexer;
+struct Token;
+
+class ExpressionParser : angle::NonCopyable
+{
+ public:
+ struct ErrorSettings
+ {
+ Diagnostics::ID unexpectedIdentifier;
+ bool integerLiteralsMustFit32BitSignedRange;
+ };
+
+ ExpressionParser(Lexer *lexer, Diagnostics *diagnostics);
+
+ bool parse(Token *token,
+ int *result,
+ bool parsePresetToken,
+ const ErrorSettings &errorSettings,
+ bool *valid);
+
+ private:
+ Lexer *mLexer;
+ Diagnostics *mDiagnostics;
+};
+
+} // namespace pp
+
+} // namespace angle
+
+#endif // COMPILER_PREPROCESSOR_EXPRESSIONPARSER_H_
diff --git a/gfx/angle/checkout/src/compiler/preprocessor/Input.cpp b/gfx/angle/checkout/src/compiler/preprocessor/Input.cpp
new file mode 100644
index 0000000000..2ddb9467d2
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/preprocessor/Input.cpp
@@ -0,0 +1,130 @@
+//
+// Copyright 2011 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/preprocessor/Input.h"
+
+#include <algorithm>
+#include <cstring>
+
+#include "common/debug.h"
+
+namespace angle
+{
+
+namespace pp
+{
+
+Input::Input() : mCount(0), mString(0) {}
+
+Input::~Input() {}
+
+Input::Input(size_t count, const char *const string[], const int length[])
+ : mCount(count), mString(string)
+{
+ mLength.reserve(mCount);
+ for (size_t i = 0; i < mCount; ++i)
+ {
+ int len = length ? length[i] : -1;
+ mLength.push_back(len < 0 ? std::strlen(mString[i]) : len);
+ }
+}
+
+const char *Input::skipChar()
+{
+ // This function should only be called when there is a character to skip.
+ ASSERT(mReadLoc.cIndex < mLength[mReadLoc.sIndex]);
+ ++mReadLoc.cIndex;
+ if (mReadLoc.cIndex == mLength[mReadLoc.sIndex])
+ {
+ ++mReadLoc.sIndex;
+ mReadLoc.cIndex = 0;
+ }
+ if (mReadLoc.sIndex >= mCount)
+ {
+ return nullptr;
+ }
+ return mString[mReadLoc.sIndex] + mReadLoc.cIndex;
+}
+
+size_t Input::read(char *buf, size_t maxSize, int *lineNo)
+{
+ size_t nRead = 0;
+ // The previous call to read might have stopped copying the string when encountering a line
+ // continuation. Check for this possibility first.
+ if (mReadLoc.sIndex < mCount && maxSize > 0)
+ {
+ const char *c = mString[mReadLoc.sIndex] + mReadLoc.cIndex;
+ if ((*c) == '\\')
+ {
+ c = skipChar();
+ if (c != nullptr && (*c) == '\n')
+ {
+ // Line continuation of backslash + newline.
+ skipChar();
+ // Fake an EOF if the line number would overflow.
+ if (*lineNo == INT_MAX)
+ {
+ return 0;
+ }
+ ++(*lineNo);
+ }
+ else if (c != nullptr && (*c) == '\r')
+ {
+ // Line continuation. Could be backslash + '\r\n' or just backslash + '\r'.
+ c = skipChar();
+ if (c != nullptr && (*c) == '\n')
+ {
+ skipChar();
+ }
+ // Fake an EOF if the line number would overflow.
+ if (*lineNo == INT_MAX)
+ {
+ return 0;
+ }
+ ++(*lineNo);
+ }
+ else
+ {
+ // Not line continuation, so write the skipped backslash to buf.
+ *buf = '\\';
+ ++nRead;
+ }
+ }
+ }
+
+ size_t maxRead = maxSize;
+ while ((nRead < maxRead) && (mReadLoc.sIndex < mCount))
+ {
+ size_t size = mLength[mReadLoc.sIndex] - mReadLoc.cIndex;
+ size = std::min(size, maxSize);
+ for (size_t i = 0; i < size; ++i)
+ {
+ // Stop if a possible line continuation is encountered.
+ // It will be processed on the next call on input, which skips it
+ // and increments line number if necessary.
+ if (*(mString[mReadLoc.sIndex] + mReadLoc.cIndex + i) == '\\')
+ {
+ size = i;
+ maxRead = nRead + size; // Stop reading right before the backslash.
+ }
+ }
+ std::memcpy(buf + nRead, mString[mReadLoc.sIndex] + mReadLoc.cIndex, size);
+ nRead += size;
+ mReadLoc.cIndex += size;
+
+ // Advance string if we reached the end of current string.
+ if (mReadLoc.cIndex == mLength[mReadLoc.sIndex])
+ {
+ ++mReadLoc.sIndex;
+ mReadLoc.cIndex = 0;
+ }
+ }
+ return nRead;
+}
+
+} // namespace pp
+
+} // namespace angle
diff --git a/gfx/angle/checkout/src/compiler/preprocessor/Input.h b/gfx/angle/checkout/src/compiler/preprocessor/Input.h
new file mode 100644
index 0000000000..6f42a112d4
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/preprocessor/Input.h
@@ -0,0 +1,59 @@
+//
+// Copyright 2011 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_PREPROCESSOR_INPUT_H_
+#define COMPILER_PREPROCESSOR_INPUT_H_
+
+#include <cstddef>
+#include <vector>
+
+namespace angle
+{
+
+namespace pp
+{
+
+// Holds and reads input for Lexer.
+class Input
+{
+ public:
+ Input();
+ ~Input();
+ Input(size_t count, const char *const string[], const int length[]);
+
+ size_t count() const { return mCount; }
+ const char *string(size_t index) const { return mString[index]; }
+ size_t length(size_t index) const { return mLength[index]; }
+
+ size_t read(char *buf, size_t maxSize, int *lineNo);
+
+ struct Location
+ {
+ size_t sIndex; // String index;
+ size_t cIndex; // Char index.
+
+ Location() : sIndex(0), cIndex(0) {}
+ };
+ const Location &readLoc() const { return mReadLoc; }
+
+ private:
+ // Skip a character and return the next character after the one that was skipped.
+ // Return nullptr if data runs out.
+ const char *skipChar();
+
+ // Input.
+ size_t mCount;
+ const char *const *mString;
+ std::vector<size_t> mLength;
+
+ Location mReadLoc;
+};
+
+} // namespace pp
+
+} // namespace angle
+
+#endif // COMPILER_PREPROCESSOR_INPUT_H_
diff --git a/gfx/angle/checkout/src/compiler/preprocessor/Lexer.cpp b/gfx/angle/checkout/src/compiler/preprocessor/Lexer.cpp
new file mode 100644
index 0000000000..49bd15fe90
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/preprocessor/Lexer.cpp
@@ -0,0 +1,19 @@
+//
+// Copyright 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/preprocessor/Lexer.h"
+
+namespace angle
+{
+
+namespace pp
+{
+
+Lexer::~Lexer() {}
+
+} // namespace pp
+
+} // namespace angle
diff --git a/gfx/angle/checkout/src/compiler/preprocessor/Lexer.h b/gfx/angle/checkout/src/compiler/preprocessor/Lexer.h
new file mode 100644
index 0000000000..42fd5b0d8f
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/preprocessor/Lexer.h
@@ -0,0 +1,32 @@
+//
+// Copyright 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_PREPROCESSOR_LEXER_H_
+#define COMPILER_PREPROCESSOR_LEXER_H_
+
+#include "common/angleutils.h"
+
+namespace angle
+{
+
+namespace pp
+{
+
+struct Token;
+
+class Lexer : angle::NonCopyable
+{
+ public:
+ virtual ~Lexer();
+
+ virtual void lex(Token *token) = 0;
+};
+
+} // namespace pp
+
+} // namespace angle
+
+#endif // COMPILER_PREPROCESSOR_LEXER_H_
diff --git a/gfx/angle/checkout/src/compiler/preprocessor/Macro.cpp b/gfx/angle/checkout/src/compiler/preprocessor/Macro.cpp
new file mode 100644
index 0000000000..132145bd23
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/preprocessor/Macro.cpp
@@ -0,0 +1,45 @@
+//
+// Copyright 2011 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/preprocessor/Macro.h"
+
+#include "common/angleutils.h"
+#include "compiler/preprocessor/Token.h"
+
+namespace angle
+{
+
+namespace pp
+{
+
+Macro::Macro() : predefined(false), disabled(false), expansionCount(0), type(kTypeObj) {}
+
+Macro::~Macro() {}
+
+bool Macro::equals(const Macro &other) const
+{
+ return (type == other.type) && (name == other.name) && (parameters == other.parameters) &&
+ (replacements == other.replacements);
+}
+
+void PredefineMacro(MacroSet *macroSet, const char *name, int value)
+{
+ Token token;
+ token.type = Token::CONST_INT;
+ token.text = ToString(value);
+
+ std::shared_ptr<Macro> macro = std::make_shared<Macro>();
+ macro->predefined = true;
+ macro->type = Macro::kTypeObj;
+ macro->name = name;
+ macro->replacements.push_back(token);
+
+ (*macroSet)[name] = macro;
+}
+
+} // namespace pp
+
+} // namespace angle
diff --git a/gfx/angle/checkout/src/compiler/preprocessor/Macro.h b/gfx/angle/checkout/src/compiler/preprocessor/Macro.h
new file mode 100644
index 0000000000..bd6312c047
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/preprocessor/Macro.h
@@ -0,0 +1,55 @@
+//
+// Copyright 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_PREPROCESSOR_MACRO_H_
+#define COMPILER_PREPROCESSOR_MACRO_H_
+
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace angle
+{
+
+namespace pp
+{
+
+struct Token;
+
+struct Macro
+{
+ enum Type
+ {
+ kTypeObj,
+ kTypeFunc
+ };
+ typedef std::vector<std::string> Parameters;
+ typedef std::vector<Token> Replacements;
+
+ Macro();
+ ~Macro();
+ bool equals(const Macro &other) const;
+
+ bool predefined;
+ mutable bool disabled;
+ mutable int expansionCount;
+
+ Type type;
+ std::string name;
+ Parameters parameters;
+ Replacements replacements;
+};
+
+typedef std::map<std::string, std::shared_ptr<Macro>> MacroSet;
+
+void PredefineMacro(MacroSet *macroSet, const char *name, int value);
+
+} // namespace pp
+
+} // namespace angle
+
+#endif // COMPILER_PREPROCESSOR_MACRO_H_
diff --git a/gfx/angle/checkout/src/compiler/preprocessor/MacroExpander.cpp b/gfx/angle/checkout/src/compiler/preprocessor/MacroExpander.cpp
new file mode 100644
index 0000000000..759617b5a1
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/preprocessor/MacroExpander.cpp
@@ -0,0 +1,531 @@
+//
+// Copyright 2011 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/preprocessor/MacroExpander.h"
+
+#include <GLSLANG/ShaderLang.h>
+#include <algorithm>
+
+#include "common/debug.h"
+#include "compiler/preprocessor/DiagnosticsBase.h"
+#include "compiler/preprocessor/Token.h"
+
+namespace angle
+{
+
+namespace pp
+{
+
+namespace
+{
+
+const size_t kMaxContextTokens = 10000;
+
+class TokenLexer : public Lexer
+{
+ public:
+ typedef std::vector<Token> TokenVector;
+
+ TokenLexer(TokenVector *tokens)
+ {
+ tokens->swap(mTokens);
+ mIter = mTokens.begin();
+ }
+
+ void lex(Token *token) override
+ {
+ if (mIter == mTokens.end())
+ {
+ token->reset();
+ token->type = Token::LAST;
+ }
+ else
+ {
+ *token = *mIter++;
+ }
+ }
+
+ private:
+ TokenVector mTokens;
+ TokenVector::const_iterator mIter;
+};
+
+} // anonymous namespace
+
+class [[nodiscard]] MacroExpander::ScopedMacroReenabler final : angle::NonCopyable
+{
+ public:
+ ScopedMacroReenabler(MacroExpander *expander);
+ ~ScopedMacroReenabler();
+
+ private:
+ MacroExpander *mExpander;
+};
+
+MacroExpander::ScopedMacroReenabler::ScopedMacroReenabler(MacroExpander *expander)
+ : mExpander(expander)
+{
+ mExpander->mDeferReenablingMacros = true;
+}
+
+MacroExpander::ScopedMacroReenabler::~ScopedMacroReenabler()
+{
+ mExpander->mDeferReenablingMacros = false;
+ for (const std::shared_ptr<Macro> &macro : mExpander->mMacrosToReenable)
+ {
+ // Copying the string here by using substr is a check for use-after-free. It detects
+ // use-after-free more reliably than just toggling the disabled flag.
+ ASSERT(macro->name.substr() != "");
+ macro->disabled = false;
+ }
+ mExpander->mMacrosToReenable.clear();
+}
+
+MacroExpander::MacroExpander(Lexer *lexer,
+ MacroSet *macroSet,
+ Diagnostics *diagnostics,
+ const PreprocessorSettings &settings,
+ bool parseDefined)
+ : mLexer(lexer),
+ mMacroSet(macroSet),
+ mDiagnostics(diagnostics),
+ mParseDefined(parseDefined),
+ mTotalTokensInContexts(0),
+ mSettings(settings),
+ mDeferReenablingMacros(false)
+{}
+
+MacroExpander::~MacroExpander()
+{
+ ASSERT(mMacrosToReenable.empty());
+ for (MacroContext *context : mContextStack)
+ {
+ delete context;
+ }
+}
+
+void MacroExpander::lex(Token *token)
+{
+ while (true)
+ {
+ 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)
+ {
+ // Defined inside a macro is forbidden in WebGL.
+ if (!mContextStack.empty() && sh::IsWebGLBasedSpec(mSettings.shaderSpec))
+ break;
+
+ 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;
+
+ MacroSet::const_iterator iter = mMacroSet->find(token->text);
+ if (iter == mMacroSet->end())
+ break;
+
+ std::shared_ptr<Macro> macro = iter->second;
+ if (macro->disabled)
+ {
+ // If a particular token is not expanded, it is never expanded.
+ token->setExpansionDisabled(true);
+ break;
+ }
+
+ // Bump the expansion count before peeking if the next token is a '('
+ // otherwise there could be a #undef of the macro before the next token.
+ macro->expansionCount++;
+ if ((macro->type == Macro::kTypeFunc) && !isNextTokenLeftParen())
+ {
+ // If the token immediately after the macro name is not a '(',
+ // this macro should not be expanded.
+ macro->expansionCount--;
+ break;
+ }
+
+ pushMacro(macro, *token);
+ }
+}
+
+void MacroExpander::getToken(Token *token)
+{
+ if (mReserveToken.get())
+ {
+ *token = *mReserveToken;
+ mReserveToken.reset();
+ return;
+ }
+
+ // First pop all empty macro contexts.
+ while (!mContextStack.empty() && mContextStack.back()->empty())
+ {
+ popMacro();
+ }
+
+ if (!mContextStack.empty())
+ {
+ *token = mContextStack.back()->get();
+ }
+ else
+ {
+ ASSERT(mTotalTokensInContexts == 0);
+ mLexer->lex(token);
+ }
+}
+
+void MacroExpander::ungetToken(const Token &token)
+{
+ if (!mContextStack.empty())
+ {
+ MacroContext *context = mContextStack.back();
+ context->unget();
+ ASSERT(context->replacements[context->index] == token);
+ }
+ else
+ {
+ ASSERT(!mReserveToken.get());
+ mReserveToken.reset(new Token(token));
+ }
+}
+
+bool MacroExpander::isNextTokenLeftParen()
+{
+ Token token;
+ getToken(&token);
+
+ bool lparen = token.type == '(';
+ ungetToken(token);
+
+ return lparen;
+}
+
+bool MacroExpander::pushMacro(std::shared_ptr<Macro> macro, const Token &identifier)
+{
+ ASSERT(!macro->disabled);
+ ASSERT(!identifier.expansionDisabled());
+ ASSERT(identifier.type == Token::IDENTIFIER);
+ ASSERT(identifier.text == macro->name);
+
+ std::vector<Token> replacements;
+ if (!expandMacro(*macro, identifier, &replacements))
+ return false;
+
+ // Macro is disabled for expansion until it is popped off the stack.
+ macro->disabled = true;
+
+ MacroContext *context = new MacroContext;
+ context->macro = macro;
+ context->replacements.swap(replacements);
+ mContextStack.push_back(context);
+ mTotalTokensInContexts += context->replacements.size();
+ return true;
+}
+
+void MacroExpander::popMacro()
+{
+ ASSERT(!mContextStack.empty());
+
+ MacroContext *context = mContextStack.back();
+ mContextStack.pop_back();
+
+ ASSERT(context->empty());
+ ASSERT(context->macro->disabled);
+ ASSERT(context->macro->expansionCount > 0);
+ if (mDeferReenablingMacros)
+ {
+ mMacrosToReenable.push_back(context->macro);
+ }
+ else
+ {
+ context->macro->disabled = false;
+ }
+ context->macro->expansionCount--;
+ mTotalTokensInContexts -= context->replacements.size();
+ delete context;
+}
+
+bool MacroExpander::expandMacro(const Macro &macro,
+ const Token &identifier,
+ std::vector<Token> *replacements)
+{
+ replacements->clear();
+
+ // In the case of an object-like macro, the replacement list gets its location
+ // from the identifier, but in the case of a function-like macro, the replacement
+ // list gets its location from the closing parenthesis of the macro invocation.
+ // This is tested by dEQP-GLES3.functional.shaders.preprocessor.predefined_macros.*
+ SourceLocation replacementLocation = identifier.location;
+ if (macro.type == Macro::kTypeObj)
+ {
+ replacements->assign(macro.replacements.begin(), macro.replacements.end());
+
+ if (macro.predefined)
+ {
+ const char kLine[] = "__LINE__";
+ const char kFile[] = "__FILE__";
+
+ ASSERT(replacements->size() == 1);
+ Token &repl = replacements->front();
+ if (macro.name == kLine)
+ {
+ repl.text = ToString(identifier.location.line);
+ }
+ else if (macro.name == kFile)
+ {
+ repl.text = ToString(identifier.location.file);
+ }
+ }
+ }
+ else
+ {
+ ASSERT(macro.type == Macro::kTypeFunc);
+ std::vector<MacroArg> args;
+ args.reserve(macro.parameters.size());
+ if (!collectMacroArgs(macro, identifier, &args, &replacementLocation))
+ return false;
+
+ replaceMacroParams(macro, args, replacements);
+ }
+
+ for (std::size_t i = 0; i < replacements->size(); ++i)
+ {
+ Token &repl = replacements->at(i);
+ if (i == 0)
+ {
+ // The first token in the replacement list inherits the padding
+ // properties of the identifier token.
+ repl.setAtStartOfLine(identifier.atStartOfLine());
+ repl.setHasLeadingSpace(identifier.hasLeadingSpace());
+ }
+ repl.location = replacementLocation;
+ }
+ return true;
+}
+
+bool MacroExpander::collectMacroArgs(const Macro &macro,
+ const Token &identifier,
+ std::vector<MacroArg> *args,
+ SourceLocation *closingParenthesisLocation)
+{
+ Token token;
+ getToken(&token);
+ ASSERT(token.type == '(');
+
+ args->push_back(MacroArg());
+
+ // Defer reenabling macros until args collection is finished to avoid the possibility of
+ // infinite recursion. Otherwise infinite recursion might happen when expanding the args after
+ // macros have been popped from the context stack when parsing the args.
+ ScopedMacroReenabler deferReenablingMacros(this);
+
+ int openParens = 1;
+ while (openParens != 0)
+ {
+ getToken(&token);
+
+ if (token.type == Token::LAST)
+ {
+ mDiagnostics->report(Diagnostics::PP_MACRO_UNTERMINATED_INVOCATION, identifier.location,
+ identifier.text);
+ // Do not lose EOF token.
+ ungetToken(token);
+ return false;
+ }
+
+ bool isArg = false; // True if token is part of the current argument.
+ switch (token.type)
+ {
+ case '(':
+ ++openParens;
+ isArg = true;
+ break;
+ case ')':
+ --openParens;
+ isArg = openParens != 0;
+ *closingParenthesisLocation = token.location;
+ break;
+ case ',':
+ // The individual arguments are separated by comma tokens, but
+ // the comma tokens between matching inner parentheses do not
+ // seperate arguments.
+ if (openParens == 1)
+ args->push_back(MacroArg());
+ isArg = openParens != 1;
+ break;
+ default:
+ isArg = true;
+ break;
+ }
+ if (isArg)
+ {
+ MacroArg &arg = args->back();
+ // Initial whitespace is not part of the argument.
+ if (arg.empty())
+ token.setHasLeadingSpace(false);
+ arg.push_back(token);
+ }
+ }
+
+ const Macro::Parameters &params = macro.parameters;
+ // If there is only one empty argument, it is equivalent to no argument.
+ if (params.empty() && (args->size() == 1) && args->front().empty())
+ {
+ args->clear();
+ }
+ // Validate the number of arguments.
+ if (args->size() != params.size())
+ {
+ Diagnostics::ID id = args->size() < macro.parameters.size()
+ ? Diagnostics::PP_MACRO_TOO_FEW_ARGS
+ : Diagnostics::PP_MACRO_TOO_MANY_ARGS;
+ mDiagnostics->report(id, identifier.location, identifier.text);
+ return false;
+ }
+
+ // Pre-expand each argument before substitution.
+ // This step expands each argument individually before they are
+ // inserted into the macro body.
+ size_t numTokens = 0;
+ for (auto &arg : *args)
+ {
+ TokenLexer lexer(&arg);
+ if (mSettings.maxMacroExpansionDepth < 1)
+ {
+ mDiagnostics->report(Diagnostics::PP_MACRO_INVOCATION_CHAIN_TOO_DEEP, token.location,
+ token.text);
+ return false;
+ }
+ PreprocessorSettings nestedSettings(mSettings.shaderSpec);
+ nestedSettings.maxMacroExpansionDepth = mSettings.maxMacroExpansionDepth - 1;
+ MacroExpander expander(&lexer, mMacroSet, mDiagnostics, nestedSettings, mParseDefined);
+
+ arg.clear();
+ expander.lex(&token);
+ while (token.type != Token::LAST)
+ {
+ 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;
+}
+
+void MacroExpander::replaceMacroParams(const Macro &macro,
+ const std::vector<MacroArg> &args,
+ std::vector<Token> *replacements)
+{
+ 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)
+ {
+ replacements->push_back(repl);
+ continue;
+ }
+
+ // TODO(alokp): Optimize this.
+ // There is no need to search for macro params every time.
+ // The param index can be cached with the replacement token.
+ Macro::Parameters::const_iterator iter =
+ std::find(macro.parameters.begin(), macro.parameters.end(), repl.text);
+ if (iter == macro.parameters.end())
+ {
+ replacements->push_back(repl);
+ continue;
+ }
+
+ std::size_t iArg = std::distance(macro.parameters.begin(), iter);
+ const MacroArg &arg = args[iArg];
+ if (arg.empty())
+ {
+ continue;
+ }
+ std::size_t iRepl = replacements->size();
+ replacements->insert(replacements->end(), arg.begin(), arg.end());
+ // The replacement token inherits padding properties from
+ // macro replacement token.
+ replacements->at(iRepl).setHasLeadingSpace(repl.hasLeadingSpace());
+ }
+}
+
+MacroExpander::MacroContext::MacroContext() : macro(0), index(0) {}
+
+MacroExpander::MacroContext::~MacroContext() {}
+
+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
+
+} // namespace angle
diff --git a/gfx/angle/checkout/src/compiler/preprocessor/MacroExpander.h b/gfx/angle/checkout/src/compiler/preprocessor/MacroExpander.h
new file mode 100644
index 0000000000..10aee6fc39
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/preprocessor/MacroExpander.h
@@ -0,0 +1,91 @@
+//
+// Copyright 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_PREPROCESSOR_MACROEXPANDER_H_
+#define COMPILER_PREPROCESSOR_MACROEXPANDER_H_
+
+#include <memory>
+#include <vector>
+
+#include "compiler/preprocessor/Lexer.h"
+#include "compiler/preprocessor/Macro.h"
+#include "compiler/preprocessor/Preprocessor.h"
+
+namespace angle
+{
+
+namespace pp
+{
+
+class Diagnostics;
+struct SourceLocation;
+
+class MacroExpander : public Lexer
+{
+ public:
+ MacroExpander(Lexer *lexer,
+ MacroSet *macroSet,
+ Diagnostics *diagnostics,
+ const PreprocessorSettings &settings,
+ bool parseDefined);
+ ~MacroExpander() override;
+
+ void lex(Token *token) override;
+
+ private:
+ void getToken(Token *token);
+ void ungetToken(const Token &token);
+ bool isNextTokenLeftParen();
+
+ bool pushMacro(std::shared_ptr<Macro> macro, const Token &identifier);
+ void popMacro();
+
+ bool expandMacro(const Macro &macro, const Token &identifier, std::vector<Token> *replacements);
+
+ typedef std::vector<Token> MacroArg;
+ bool collectMacroArgs(const Macro &macro,
+ const Token &identifier,
+ std::vector<MacroArg> *args,
+ SourceLocation *closingParenthesisLocation);
+ void replaceMacroParams(const Macro &macro,
+ const std::vector<MacroArg> &args,
+ std::vector<Token> *replacements);
+
+ struct MacroContext
+ {
+ MacroContext();
+ ~MacroContext();
+ bool empty() const;
+ const Token &get();
+ void unget();
+
+ std::shared_ptr<Macro> macro;
+ std::size_t index;
+ std::vector<Token> replacements;
+ };
+
+ Lexer *mLexer;
+ MacroSet *mMacroSet;
+ Diagnostics *mDiagnostics;
+ bool mParseDefined;
+
+ std::unique_ptr<Token> mReserveToken;
+ std::vector<MacroContext *> mContextStack;
+ size_t mTotalTokensInContexts;
+
+ PreprocessorSettings mSettings;
+
+ bool mDeferReenablingMacros;
+ std::vector<std::shared_ptr<Macro>> mMacrosToReenable;
+
+ class ScopedMacroReenabler;
+};
+
+} // namespace pp
+
+} // namespace angle
+
+#endif // COMPILER_PREPROCESSOR_MACROEXPANDER_H_
diff --git a/gfx/angle/checkout/src/compiler/preprocessor/Preprocessor.cpp b/gfx/angle/checkout/src/compiler/preprocessor/Preprocessor.cpp
new file mode 100644
index 0000000000..8ff4a76632
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/preprocessor/Preprocessor.cpp
@@ -0,0 +1,107 @@
+//
+// Copyright 2011 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/preprocessor/Preprocessor.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 angle
+{
+
+namespace pp
+{
+
+struct PreprocessorImpl
+{
+ Diagnostics *diagnostics;
+ MacroSet macroSet;
+ Tokenizer tokenizer;
+ DirectiveParser directiveParser;
+ MacroExpander macroExpander;
+
+ PreprocessorImpl(Diagnostics *diag,
+ DirectiveHandler *directiveHandler,
+ const PreprocessorSettings &settings)
+ : diagnostics(diag),
+ tokenizer(diag),
+ directiveParser(&tokenizer, &macroSet, diag, directiveHandler, settings),
+ macroExpander(&directiveParser, &macroSet, diag, settings, false)
+ {}
+};
+
+Preprocessor::Preprocessor(Diagnostics *diagnostics,
+ DirectiveHandler *directiveHandler,
+ const PreprocessorSettings &settings)
+{
+ mImpl = new PreprocessorImpl(diagnostics, directiveHandler, settings);
+}
+
+Preprocessor::~Preprocessor()
+{
+ delete mImpl;
+}
+
+bool Preprocessor::init(size_t count, const char *const string[], const int length[])
+{
+ static const int kDefaultGLSLVersion = 100;
+
+ // Add standard pre-defined macros.
+ predefineMacro("__LINE__", 0);
+ predefineMacro("__FILE__", 0);
+ predefineMacro("__VERSION__", kDefaultGLSLVersion);
+ predefineMacro("GL_ES", 1);
+
+ return mImpl->tokenizer.init(count, string, length);
+}
+
+void Preprocessor::predefineMacro(const char *name, int value)
+{
+ PredefineMacro(&mImpl->macroSet, name, value);
+}
+
+void Preprocessor::lex(Token *token)
+{
+ bool validToken = false;
+ while (!validToken)
+ {
+ mImpl->macroExpander.lex(token);
+ switch (token->type)
+ {
+ // We should not be returning internal preprocessing tokens.
+ // Convert preprocessing tokens to compiler tokens or report
+ // diagnostics.
+ case Token::PP_HASH:
+ UNREACHABLE();
+ break;
+ case Token::PP_NUMBER:
+ mImpl->diagnostics->report(Diagnostics::PP_INVALID_NUMBER, token->location,
+ token->text);
+ break;
+ case Token::PP_OTHER:
+ mImpl->diagnostics->report(Diagnostics::PP_INVALID_CHARACTER, token->location,
+ token->text);
+ break;
+ default:
+ validToken = true;
+ break;
+ }
+ }
+}
+
+void Preprocessor::setMaxTokenSize(size_t maxTokenSize)
+{
+ mImpl->tokenizer.setMaxTokenSize(maxTokenSize);
+}
+
+} // namespace pp
+
+} // namespace angle
diff --git a/gfx/angle/checkout/src/compiler/preprocessor/Preprocessor.h b/gfx/angle/checkout/src/compiler/preprocessor/Preprocessor.h
new file mode 100644
index 0000000000..566904de14
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/preprocessor/Preprocessor.h
@@ -0,0 +1,72 @@
+//
+// Copyright 2011 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_PREPROCESSOR_PREPROCESSOR_H_
+#define COMPILER_PREPROCESSOR_PREPROCESSOR_H_
+
+#include <cstddef>
+
+#include "GLSLANG/ShaderLang.h"
+#include "common/angleutils.h"
+
+namespace angle
+{
+
+namespace pp
+{
+
+class Diagnostics;
+class DirectiveHandler;
+struct PreprocessorImpl;
+struct Token;
+
+struct PreprocessorSettings final
+{
+ PreprocessorSettings(ShShaderSpec shaderSpec)
+ : maxMacroExpansionDepth(1000), shaderSpec(shaderSpec)
+ {}
+
+ PreprocessorSettings(const PreprocessorSettings &other) = default;
+
+ int maxMacroExpansionDepth;
+ ShShaderSpec shaderSpec;
+};
+
+class Preprocessor : angle::NonCopyable
+{
+ public:
+ Preprocessor(Diagnostics *diagnostics,
+ DirectiveHandler *directiveHandler,
+ const PreprocessorSettings &settings);
+ ~Preprocessor();
+
+ // count: specifies the number of elements in the string and length arrays.
+ // string: specifies an array of pointers to strings.
+ // length: specifies an array of string lengths.
+ // If length is NULL, each string is assumed to be null terminated.
+ // If length is a value other than NULL, it points to an array containing
+ // a string length for each of the corresponding elements of string.
+ // Each element in the length array may contain the length of the
+ // corresponding string or a value less than 0 to indicate that the string
+ // is null terminated.
+ bool init(size_t count, const char *const string[], const int length[]);
+ // Adds a pre-defined macro.
+ void predefineMacro(const char *name, int value);
+
+ void lex(Token *token);
+
+ // Set maximum preprocessor token size
+ void setMaxTokenSize(size_t maxTokenSize);
+
+ private:
+ PreprocessorImpl *mImpl;
+};
+
+} // namespace pp
+
+} // namespace angle
+
+#endif // COMPILER_PREPROCESSOR_PREPROCESSOR_H_
diff --git a/gfx/angle/checkout/src/compiler/preprocessor/SourceLocation.h b/gfx/angle/checkout/src/compiler/preprocessor/SourceLocation.h
new file mode 100644
index 0000000000..de48abcdb6
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/preprocessor/SourceLocation.h
@@ -0,0 +1,44 @@
+//
+// Copyright 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_PREPROCESSOR_SOURCELOCATION_H_
+#define COMPILER_PREPROCESSOR_SOURCELOCATION_H_
+
+namespace angle
+{
+
+namespace pp
+{
+
+struct SourceLocation
+{
+ SourceLocation() : file(0), line(0) {}
+ SourceLocation(int f, int l) : file(f), line(l) {}
+
+ bool equals(const SourceLocation &other) const
+ {
+ return (file == other.file) && (line == other.line);
+ }
+
+ int file;
+ int line;
+};
+
+inline bool operator==(const SourceLocation &lhs, const SourceLocation &rhs)
+{
+ return lhs.equals(rhs);
+}
+
+inline bool operator!=(const SourceLocation &lhs, const SourceLocation &rhs)
+{
+ return !lhs.equals(rhs);
+}
+
+} // namespace pp
+
+} // namespace angle
+
+#endif // COMPILER_PREPROCESSOR_SOURCELOCATION_H_
diff --git a/gfx/angle/checkout/src/compiler/preprocessor/Token.cpp b/gfx/angle/checkout/src/compiler/preprocessor/Token.cpp
new file mode 100644
index 0000000000..72d917a39a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/preprocessor/Token.cpp
@@ -0,0 +1,79 @@
+//
+// Copyright 2011 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/preprocessor/Token.h"
+
+#include "common/debug.h"
+#include "compiler/preprocessor/numeric_lex.h"
+
+namespace angle
+{
+
+namespace pp
+{
+
+void Token::reset()
+{
+ type = 0;
+ flags = 0;
+ location = SourceLocation();
+ text.clear();
+}
+
+bool Token::equals(const Token &other) const
+{
+ return (type == other.type) && (flags == other.flags) && (location == other.location) &&
+ (text == other.text);
+}
+
+void Token::setAtStartOfLine(bool start)
+{
+ if (start)
+ flags |= AT_START_OF_LINE;
+ else
+ flags &= ~AT_START_OF_LINE;
+}
+
+void Token::setHasLeadingSpace(bool space)
+{
+ if (space)
+ flags |= HAS_LEADING_SPACE;
+ else
+ flags &= ~HAS_LEADING_SPACE;
+}
+
+void Token::setExpansionDisabled(bool disable)
+{
+ if (disable)
+ flags |= EXPANSION_DISABLED;
+ else
+ flags &= ~EXPANSION_DISABLED;
+}
+
+bool Token::iValue(int *value) const
+{
+ ASSERT(type == CONST_INT);
+ return numeric_lex_int(text, value);
+}
+
+bool Token::uValue(unsigned int *value) const
+{
+ ASSERT(type == CONST_INT);
+ return numeric_lex_int(text, value);
+}
+
+std::ostream &operator<<(std::ostream &out, const Token &token)
+{
+ if (token.hasLeadingSpace())
+ out << " ";
+
+ out << token.text;
+ return out;
+}
+
+} // namespace pp
+
+} // namespace angle
diff --git a/gfx/angle/checkout/src/compiler/preprocessor/Token.h b/gfx/angle/checkout/src/compiler/preprocessor/Token.h
new file mode 100644
index 0000000000..1c65f2fe41
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/preprocessor/Token.h
@@ -0,0 +1,115 @@
+//
+// Copyright 2011 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_PREPROCESSOR_TOKEN_H_
+#define COMPILER_PREPROCESSOR_TOKEN_H_
+
+#include <ostream>
+#include <string>
+
+#include "compiler/preprocessor/SourceLocation.h"
+
+namespace angle
+{
+
+namespace pp
+{
+
+struct Token
+{
+ enum Type
+ {
+ // Calling this ERROR causes a conflict with wingdi.h
+ GOT_ERROR = -1,
+ LAST = 0, // EOF.
+
+ IDENTIFIER = 258,
+
+ CONST_INT,
+ CONST_FLOAT,
+
+ OP_INC,
+ OP_DEC,
+ OP_LEFT,
+ OP_RIGHT,
+ OP_LE,
+ OP_GE,
+ OP_EQ,
+ OP_NE,
+ OP_AND,
+ OP_XOR,
+ OP_OR,
+ OP_ADD_ASSIGN,
+ OP_SUB_ASSIGN,
+ OP_MUL_ASSIGN,
+ OP_DIV_ASSIGN,
+ OP_MOD_ASSIGN,
+ OP_LEFT_ASSIGN,
+ OP_RIGHT_ASSIGN,
+ OP_AND_ASSIGN,
+ OP_XOR_ASSIGN,
+ OP_OR_ASSIGN,
+
+ // Preprocessing token types.
+ // These types are used by the preprocessor internally.
+ // Preprocessor clients must not depend or check for them.
+ PP_HASH,
+ PP_NUMBER,
+ PP_OTHER
+ };
+ enum Flags
+ {
+ AT_START_OF_LINE = 1 << 0,
+ HAS_LEADING_SPACE = 1 << 1,
+ EXPANSION_DISABLED = 1 << 2
+ };
+
+ Token() : type(0), flags(0) {}
+
+ void reset();
+ bool equals(const Token &other) const;
+
+ // Returns true if this is the first token on line.
+ // It disregards any leading whitespace.
+ bool atStartOfLine() const { return (flags & AT_START_OF_LINE) != 0; }
+ void setAtStartOfLine(bool start);
+
+ bool hasLeadingSpace() const { return (flags & HAS_LEADING_SPACE) != 0; }
+ void setHasLeadingSpace(bool space);
+
+ bool expansionDisabled() const { return (flags & EXPANSION_DISABLED) != 0; }
+ void setExpansionDisabled(bool disable);
+
+ // Converts text into numeric value for CONST_INT and CONST_FLOAT token.
+ // Returns false if the parsed value cannot fit into an int or float.
+ bool iValue(int *value) const;
+ bool uValue(unsigned int *value) const;
+
+ int type;
+ unsigned int flags;
+ SourceLocation location;
+ std::string text;
+};
+
+inline bool operator==(const Token &lhs, const Token &rhs)
+{
+ return lhs.equals(rhs);
+}
+
+inline bool operator!=(const Token &lhs, const Token &rhs)
+{
+ return !lhs.equals(rhs);
+}
+
+std::ostream &operator<<(std::ostream &out, const Token &token);
+
+constexpr char kDefined[] = "defined";
+
+} // namespace pp
+
+} // namespace angle
+
+#endif // COMPILER_PREPROCESSOR_TOKEN_H_
diff --git a/gfx/angle/checkout/src/compiler/preprocessor/Tokenizer.h b/gfx/angle/checkout/src/compiler/preprocessor/Tokenizer.h
new file mode 100644
index 0000000000..ec6a8ed83a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/preprocessor/Tokenizer.h
@@ -0,0 +1,63 @@
+//
+// Copyright 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_PREPROCESSOR_TOKENIZER_H_
+#define COMPILER_PREPROCESSOR_TOKENIZER_H_
+
+#include "common/angleutils.h"
+#include "compiler/preprocessor/Input.h"
+#include "compiler/preprocessor/Lexer.h"
+
+namespace angle
+{
+
+namespace pp
+{
+
+class Diagnostics;
+
+class Tokenizer : public Lexer
+{
+ public:
+ struct Context
+ {
+ Diagnostics *diagnostics;
+
+ Input input;
+ // The location where yytext points to. Token location should track
+ // scanLoc instead of Input::mReadLoc because they may not be the same
+ // if text is buffered up in the scanner input buffer.
+ Input::Location scanLoc;
+
+ bool leadingSpace;
+ bool lineStart;
+ };
+
+ Tokenizer(Diagnostics *diagnostics);
+ ~Tokenizer() override;
+
+ bool init(size_t count, const char *const string[], const int length[]);
+
+ void setFileNumber(int file);
+ void setLineNumber(int line);
+ void setMaxTokenSize(size_t maxTokenSize);
+
+ void lex(Token *token) override;
+
+ private:
+ bool initScanner();
+ void destroyScanner();
+
+ void *mHandle; // Scanner handle.
+ Context mContext; // Scanner extra.
+ size_t mMaxTokenSize; // Maximum token size
+};
+
+} // namespace pp
+
+} // namespace angle
+
+#endif // COMPILER_PREPROCESSOR_TOKENIZER_H_
diff --git a/gfx/angle/checkout/src/compiler/preprocessor/numeric_lex.h b/gfx/angle/checkout/src/compiler/preprocessor/numeric_lex.h
new file mode 100644
index 0000000000..dc505ad8b5
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/preprocessor/numeric_lex.h
@@ -0,0 +1,54 @@
+//
+// Copyright 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.
+//
+
+// numeric_lex.h: Functions to extract numeric values from string.
+
+#ifndef COMPILER_PREPROCESSOR_NUMERICLEX_H_
+#define COMPILER_PREPROCESSOR_NUMERICLEX_H_
+
+#include <sstream>
+
+namespace angle
+{
+
+namespace pp
+{
+
+inline std::ios::fmtflags numeric_base_int(const std::string &str)
+{
+ if ((str.size() >= 2) && (str[0] == '0') && (str[1] == 'x' || str[1] == 'X'))
+ {
+ return std::ios::hex;
+ }
+ if ((str.size() >= 1) && (str[0] == '0'))
+ {
+ return std::ios::oct;
+ }
+ return std::ios::dec;
+}
+
+// The following functions parse the given string to extract a numerical
+// value of the given type. These functions assume that the string is
+// of the correct form. They can only fail if the parsed value is too big,
+// in which case false is returned.
+
+template <typename IntType>
+bool numeric_lex_int(const std::string &str, IntType *value)
+{
+ std::istringstream stream(str);
+ // This should not be necessary, but MSVS has a buggy implementation.
+ // It returns incorrect results if the base is not specified.
+ stream.setf(numeric_base_int(str), std::ios::basefield);
+
+ stream >> (*value);
+ return !stream.fail();
+}
+
+} // namespace pp
+
+} // namespace angle
+
+#endif // COMPILER_PREPROCESSOR_NUMERICLEX_H_
diff --git a/gfx/angle/checkout/src/compiler/preprocessor/preprocessor_lex_autogen.cpp b/gfx/angle/checkout/src/compiler/preprocessor/preprocessor_lex_autogen.cpp
new file mode 100644
index 0000000000..190d53a47a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/preprocessor/preprocessor_lex_autogen.cpp
@@ -0,0 +1,2626 @@
+#line 16 "preprocessor.l"
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_parser.py from preprocessor.l
+//
+// Copyright 2019 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.
+//
+// preprocessor.l:
+// Lexer for the OpenGL shading language preprocessor.
+
+#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 6
+#define YY_FLEX_SUBMINOR_VERSION 4
+#if YY_FLEX_SUBMINOR_VERSION > 0
+# define FLEX_BETA
+#endif
+
+#ifdef yy_create_buffer
+# define pp_create_buffer_ALREADY_DEFINED
+#else
+# define yy_create_buffer pp_create_buffer
+#endif
+
+#ifdef yy_delete_buffer
+# define pp_delete_buffer_ALREADY_DEFINED
+#else
+# define yy_delete_buffer pp_delete_buffer
+#endif
+
+#ifdef yy_scan_buffer
+# define pp_scan_buffer_ALREADY_DEFINED
+#else
+# define yy_scan_buffer pp_scan_buffer
+#endif
+
+#ifdef yy_scan_string
+# define pp_scan_string_ALREADY_DEFINED
+#else
+# define yy_scan_string pp_scan_string
+#endif
+
+#ifdef yy_scan_bytes
+# define pp_scan_bytes_ALREADY_DEFINED
+#else
+# define yy_scan_bytes pp_scan_bytes
+#endif
+
+#ifdef yy_init_buffer
+# define pp_init_buffer_ALREADY_DEFINED
+#else
+# define yy_init_buffer pp_init_buffer
+#endif
+
+#ifdef yy_flush_buffer
+# define pp_flush_buffer_ALREADY_DEFINED
+#else
+# define yy_flush_buffer pp_flush_buffer
+#endif
+
+#ifdef yy_load_buffer_state
+# define pp_load_buffer_state_ALREADY_DEFINED
+#else
+# define yy_load_buffer_state pp_load_buffer_state
+#endif
+
+#ifdef yy_switch_to_buffer
+# define pp_switch_to_buffer_ALREADY_DEFINED
+#else
+# define yy_switch_to_buffer pp_switch_to_buffer
+#endif
+
+#ifdef yypush_buffer_state
+# define pppush_buffer_state_ALREADY_DEFINED
+#else
+# define yypush_buffer_state pppush_buffer_state
+#endif
+
+#ifdef yypop_buffer_state
+# define pppop_buffer_state_ALREADY_DEFINED
+#else
+# define yypop_buffer_state pppop_buffer_state
+#endif
+
+#ifdef yyensure_buffer_stack
+# define ppensure_buffer_stack_ALREADY_DEFINED
+#else
+# define yyensure_buffer_stack ppensure_buffer_stack
+#endif
+
+#ifdef yylex
+# define pplex_ALREADY_DEFINED
+#else
+# define yylex pplex
+#endif
+
+#ifdef yyrestart
+# define pprestart_ALREADY_DEFINED
+#else
+# define yyrestart pprestart
+#endif
+
+#ifdef yylex_init
+# define pplex_init_ALREADY_DEFINED
+#else
+# define yylex_init pplex_init
+#endif
+
+#ifdef yylex_init_extra
+# define pplex_init_extra_ALREADY_DEFINED
+#else
+# define yylex_init_extra pplex_init_extra
+#endif
+
+#ifdef yylex_destroy
+# define pplex_destroy_ALREADY_DEFINED
+#else
+# define yylex_destroy pplex_destroy
+#endif
+
+#ifdef yyget_debug
+# define ppget_debug_ALREADY_DEFINED
+#else
+# define yyget_debug ppget_debug
+#endif
+
+#ifdef yyset_debug
+# define ppset_debug_ALREADY_DEFINED
+#else
+# define yyset_debug ppset_debug
+#endif
+
+#ifdef yyget_extra
+# define ppget_extra_ALREADY_DEFINED
+#else
+# define yyget_extra ppget_extra
+#endif
+
+#ifdef yyset_extra
+# define ppset_extra_ALREADY_DEFINED
+#else
+# define yyset_extra ppset_extra
+#endif
+
+#ifdef yyget_in
+# define ppget_in_ALREADY_DEFINED
+#else
+# define yyget_in ppget_in
+#endif
+
+#ifdef yyset_in
+# define ppset_in_ALREADY_DEFINED
+#else
+# define yyset_in ppset_in
+#endif
+
+#ifdef yyget_out
+# define ppget_out_ALREADY_DEFINED
+#else
+# define yyget_out ppget_out
+#endif
+
+#ifdef yyset_out
+# define ppset_out_ALREADY_DEFINED
+#else
+# define yyset_out ppset_out
+#endif
+
+#ifdef yyget_leng
+# define ppget_leng_ALREADY_DEFINED
+#else
+# define yyget_leng ppget_leng
+#endif
+
+#ifdef yyget_text
+# define ppget_text_ALREADY_DEFINED
+#else
+# define yyget_text ppget_text
+#endif
+
+#ifdef yyget_lineno
+# define ppget_lineno_ALREADY_DEFINED
+#else
+# define yyget_lineno ppget_lineno
+#endif
+
+#ifdef yyset_lineno
+# define ppset_lineno_ALREADY_DEFINED
+#else
+# define yyset_lineno ppset_lineno
+#endif
+
+#ifdef yyget_column
+# define ppget_column_ALREADY_DEFINED
+#else
+# define yyget_column ppget_column
+#endif
+
+#ifdef yyset_column
+# define ppset_column_ALREADY_DEFINED
+#else
+# define yyset_column ppset_column
+#endif
+
+#ifdef yywrap
+# define ppwrap_ALREADY_DEFINED
+#else
+# define yywrap ppwrap
+#endif
+
+#ifdef yyget_lval
+# define ppget_lval_ALREADY_DEFINED
+#else
+# define yyget_lval ppget_lval
+#endif
+
+#ifdef yyset_lval
+# define ppset_lval_ALREADY_DEFINED
+#else
+# define yyset_lval ppset_lval
+#endif
+
+#ifdef yyget_lloc
+# define ppget_lloc_ALREADY_DEFINED
+#else
+# define yyget_lloc ppget_lloc
+#endif
+
+#ifdef yyset_lloc
+# define ppset_lloc_ALREADY_DEFINED
+#else
+# define yyset_lloc ppset_lloc
+#endif
+
+#ifdef yyalloc
+# define ppalloc_ALREADY_DEFINED
+#else
+# define yyalloc ppalloc
+#endif
+
+#ifdef yyrealloc
+# define pprealloc_ALREADY_DEFINED
+#else
+# define yyrealloc pprealloc
+#endif
+
+#ifdef yyfree
+# define ppfree_ALREADY_DEFINED
+#else
+# define yyfree ppfree
+#endif
+
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+# define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+# if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+# ifndef __STDC_LIMIT_MACROS
+# define __STDC_LIMIT_MACROS 1
+# endif
+
+# include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+# else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+
+/* Limits of integral types. */
+# ifndef INT8_MIN
+# define INT8_MIN (-128)
+# endif
+# ifndef INT16_MIN
+# define INT16_MIN (-32767 - 1)
+# endif
+# ifndef INT32_MIN
+# define INT32_MIN (-2147483647 - 1)
+# endif
+# ifndef INT8_MAX
+# define INT8_MAX (127)
+# endif
+# ifndef INT16_MAX
+# define INT16_MAX (32767)
+# endif
+# ifndef INT32_MAX
+# define INT32_MAX (2147483647)
+# endif
+# ifndef UINT8_MAX
+# define UINT8_MAX (255U)
+# endif
+# ifndef UINT16_MAX
+# define UINT16_MAX (65535U)
+# endif
+# ifndef UINT32_MAX
+# define UINT32_MAX (4294967295U)
+# endif
+
+# ifndef SIZE_MAX
+# define SIZE_MAX (~(size_t)0)
+# endif
+
+# endif /* ! C99 */
+
+#endif /* ! FLEXINT_H */
+
+/* begin standard C++ headers. */
+
+/* TODO: this is always defined, so inline it */
+#define yyconst const
+
+#if defined(__GNUC__) && __GNUC__ >= 3
+# define yynoreturn __attribute__((__noreturn__))
+#else
+# define yynoreturn
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an
+ * integer in range [0..255] for use as an array index.
+ */
+#define YY_SC_TO_UI(c) ((YY_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
+#define yyout yyg->yyout_r
+#define yyextra yyg->yyextra_r
+#define yyleng yyg->yyleng_r
+#define yytext yyg->yytext_r
+#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
+#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.
+ */
+#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 yyrestart(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;
+#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 \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg); \
+ *yy_cp = yyg->yy_hold_char; \
+ YY_RESTORE_YY_MORE_OFFSET \
+ yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } 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.
+ */
+ int yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ 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
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ 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.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+
+# define YY_BUFFER_NEW 0
+# define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via yyrestart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+# define YY_BUFFER_EOF_PENDING 2
+};
+#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".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER \
+ (yyg->yy_buffer_stack ? 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 yyrestart(FILE *input_file, yyscan_t yyscanner);
+void yy_switch_to_buffer(YY_BUFFER_STATE new_buffer, yyscan_t yyscanner);
+YY_BUFFER_STATE yy_create_buffer(FILE *file, int size, yyscan_t yyscanner);
+void yy_delete_buffer(YY_BUFFER_STATE b, yyscan_t yyscanner);
+void yy_flush_buffer(YY_BUFFER_STATE b, yyscan_t yyscanner);
+void yypush_buffer_state(YY_BUFFER_STATE new_buffer, yyscan_t yyscanner);
+void yypop_buffer_state(yyscan_t yyscanner);
+
+static void yyensure_buffer_stack(yyscan_t yyscanner);
+static void yy_load_buffer_state(yyscan_t yyscanner);
+static void yy_init_buffer(YY_BUFFER_STATE b, FILE *file, yyscan_t yyscanner);
+#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER, yyscanner)
+
+YY_BUFFER_STATE yy_scan_buffer(char *base, yy_size_t size, yyscan_t yyscanner);
+YY_BUFFER_STATE yy_scan_string(const char *yy_str, yyscan_t yyscanner);
+YY_BUFFER_STATE yy_scan_bytes(const char *bytes, int len, yyscan_t yyscanner);
+
+void *yyalloc(yy_size_t, yyscan_t yyscanner);
+void *yyrealloc(void *, yy_size_t, yyscan_t yyscanner);
+void yyfree(void *, yyscan_t yyscanner);
+
+#define yy_new_buffer yy_create_buffer
+#define yy_set_interactive(is_interactive) \
+ { \
+ if (!YY_CURRENT_BUFFER) \
+ { \
+ yyensure_buffer_stack(yyscanner); \
+ YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin, YY_BUF_SIZE, yyscanner); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+ }
+#define yy_set_bol(at_bol) \
+ { \
+ if (!YY_CURRENT_BUFFER) \
+ { \
+ yyensure_buffer_stack(yyscanner); \
+ YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin, YY_BUF_SIZE, 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) (/*CONSTCOND*/ 1)
+#define YY_SKIP_YYWRAP
+typedef flex_uint8_t 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 yynoreturn yy_fatal_error(const 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 = (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 37
+#define YY_END_OF_BUFFER 38
+/* This struct is not used in this scanner,
+ but its presence is necessary. */
+struct yy_trans_info
+{
+ flex_int32_t yy_verify;
+ flex_int32_t yy_nxt;
+};
+static const flex_int16_t yy_accept[95] = {
+ 0, 0, 0, 0, 0, 38, 36, 34, 35, 35, 33, 7, 33, 33, 33, 33, 33, 33, 33, 33, 9, 9, 33, 33,
+ 33, 8, 33, 33, 3, 5, 5, 4, 34, 35, 19, 27, 20, 30, 25, 12, 23, 13, 24, 10, 2, 1, 26, 10,
+ 9, 11, 11, 11, 9, 11, 9, 9, 14, 16, 18, 17, 15, 8, 31, 21, 32, 22, 3, 5, 6, 11, 10, 11,
+ 10, 1, 10, 11, 10, 0, 10, 9, 9, 9, 28, 29, 0, 10, 10, 10, 10, 9, 10, 10, 9, 10, 0
+
+};
+
+static const 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,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 5, 1, 6, 1, 7, 8, 1, 9, 9,
+ 10, 11, 9, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, 17, 17, 9, 9, 18, 19, 20,
+ 9, 1, 21, 21, 21, 21, 22, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 25, 24, 24, 26, 24, 24, 9, 1, 9, 27, 24, 1, 21, 21, 21, 21,
+
+ 22, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 24, 24, 26, 24,
+ 24, 9, 28, 9, 9, 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, 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, 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, 1, 1, 1, 1, 1, 1};
+
+static const YY_CHAR yy_meta[29] = {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};
+
+static const flex_int16_t yy_base[100] = {
+ 0, 0, 0, 26, 28, 133, 195, 130, 195, 128, 105, 195, 104, 25, 195, 100, 23,
+ 27, 32, 31, 38, 50, 38, 93, 49, 0, 16, 51, 0, 195, 105, 87, 93, 195,
+ 195, 195, 195, 195, 195, 195, 195, 195, 195, 67, 195, 0, 195, 81, 55, 84, 98,
+ 110, 53, 61, 0, 52, 39, 195, 195, 195, 33, 0, 195, 195, 195, 195, 0, 195,
+ 195, 113, 0, 126, 0, 0, 0, 133, 0, 56, 128, 0, 133, 0, 195, 195, 101,
+ 141, 143, 145, 0, 15, 154, 195, 0, 195, 195, 177, 32, 182, 187, 189
+
+};
+
+static const flex_int16_t yy_def[100] = {
+ 0, 94, 1, 95, 95, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 20, 94, 94, 94, 96, 94, 94, 97, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+ 94, 94, 94, 98, 94, 94, 20, 20, 49, 50, 50, 99, 21, 50, 94, 94, 94, 94, 94, 96, 94,
+ 94, 94, 94, 97, 94, 94, 43, 43, 69, 69, 98, 47, 50, 50, 94, 51, 50, 99, 50, 94, 94,
+ 94, 71, 75, 94, 50, 50, 94, 94, 50, 94, 0, 94, 94, 94, 94, 94
+
+};
+
+static const flex_int16_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, 25, 25,
+ 25, 25, 25, 25, 26, 27, 29, 30, 29, 30, 36, 39, 62, 31, 61, 31, 41, 92, 44, 40, 63, 37, 45,
+ 42, 43, 43, 43, 46, 47, 83, 48, 48, 49, 56, 57, 82, 50, 51, 50, 50, 52, 53, 54, 54, 54, 59,
+ 60, 64, 87, 87, 87, 50, 55, 50, 81, 79, 65, 69, 50, 70, 70, 70, 50, 50, 50, 69, 71, 72, 69,
+ 69, 69, 50, 32, 74, 74, 74, 49, 49,
+
+ 68, 50, 75, 76, 50, 50, 50, 67, 50, 50, 50, 58, 50, 50, 50, 90, 90, 90, 38, 50, 77, 77, 35,
+ 34, 78, 78, 78, 69, 69, 69, 33, 32, 94, 94, 69, 69, 84, 84, 94, 94, 85, 85, 85, 84, 84, 50,
+ 94, 86, 86, 86, 88, 94, 94, 94, 94, 94, 50, 89, 50, 87, 87, 87, 94, 72, 94, 76, 94, 91, 90,
+ 90, 90, 94, 94, 94, 94, 94, 93, 28, 28, 28, 28, 28, 66, 94, 94, 66, 66, 73, 94, 73, 73, 73,
+ 80, 80, 5, 94, 94, 94, 94, 94,
+
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94};
+
+static const flex_int16_t yy_chk[224] = {
+ 0, 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, 3, 3, 4, 4, 13, 16, 26, 3, 96, 4, 17, 89, 19, 16, 26, 13, 19,
+ 17, 18, 18, 18, 19, 20, 60, 20, 20, 20, 22, 22, 56, 20, 20, 20, 20, 20, 20, 21, 21, 21, 24,
+ 24, 27, 77, 77, 77, 53, 21, 21, 55, 52, 27, 43, 48, 43, 43, 43, 53, 53, 53, 43, 43, 43, 43,
+ 43, 43, 47, 32, 47, 47, 47, 49, 49,
+
+ 31, 47, 47, 47, 47, 47, 47, 30, 49, 49, 50, 23, 50, 50, 50, 84, 84, 84, 15, 50, 51, 51, 12,
+ 10, 51, 51, 51, 69, 69, 69, 9, 7, 5, 0, 69, 69, 71, 71, 78, 78, 71, 71, 71, 75, 75, 80,
+ 0, 75, 75, 75, 78, 85, 85, 86, 86, 0, 80, 80, 80, 87, 87, 87, 0, 85, 0, 86, 0, 87, 90,
+ 90, 90, 0, 0, 0, 0, 0, 90, 95, 95, 95, 95, 95, 97, 0, 0, 97, 97, 98, 0, 98, 98, 98,
+ 99, 99, 94, 94, 94, 94, 94, 94,
+
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94};
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+/*
+//
+// Copyright 2002 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 file contains the Lex specification for GLSL ES preprocessor.
+Based on Microsoft Visual Studio 2010 Preprocessor Grammar:
+http://msdn.microsoft.com/en-us/library/2scxys89.aspx
+
+IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN scripts/run_code_generation.py
+*/
+
+#if defined(_MSC_VER)
+# pragma warning(disable : 4005)
+#endif
+
+#include "compiler/preprocessor/Tokenizer.h"
+
+#include "compiler/preprocessor/DiagnosticsBase.h"
+#include "compiler/preprocessor/Token.h"
+
+#if defined(__GNUC__)
+// Triggered by the auto-generated yy_fatal_error function.
+# pragma GCC diagnostic ignored "-Wmissing-noreturn"
+#elif defined(_MSC_VER)
+# pragma warning(disable : 4244)
+#endif
+#if defined(__clang__)
+// Flex uses `/*FALLTHROUGH*/` instead of dedicated statements.
+# pragma clang diagnostic ignored "-Wimplicit-fallthrough"
+# if defined(__APPLE__)
+// Older clang versions don't have -Wextra-semi-stmt, and detecting Apple clang versions is
+// difficult because they use different yet overlapping version numbers vs. regular clang.
+# pragma clang diagnostic ignored "-Wunknown-warning-option"
+# endif
+// Flex isn't semi-colon clean.
+# pragma clang diagnostic ignored "-Wextra-semi-stmt"
+# pragma clang diagnostic ignored "-Wunreachable-code"
+#endif
+
+// Workaround for flex using the register keyword, deprecated in C++11.
+#ifdef __cplusplus
+# if __cplusplus > 199711L
+# define register
+# endif
+#endif
+
+typedef std::string YYSTYPE;
+typedef angle::pp::SourceLocation YYLTYPE;
+
+// Use the unused yycolumn variable to track file (string) number.
+#define yyfileno yycolumn
+
+#define YY_USER_INIT \
+ do \
+ { \
+ yyfileno = 0; \
+ yylineno = 1; \
+ yyextra->leadingSpace = false; \
+ yyextra->lineStart = true; \
+ } while (0);
+
+#define YY_NO_INPUT
+#define YY_USER_ACTION \
+ do \
+ { \
+ angle::pp::Input *input = &yyextra->input; \
+ angle::pp::Input::Location *scanLoc = &yyextra->scanLoc; \
+ while ((scanLoc->sIndex < input->count()) && \
+ (scanLoc->cIndex >= input->length(scanLoc->sIndex))) \
+ { \
+ scanLoc->cIndex -= input->length(scanLoc->sIndex++); \
+ ++yyfileno; \
+ yylineno = 1; \
+ } \
+ yylloc->file = yyfileno; \
+ yylloc->line = yylineno; \
+ scanLoc->cIndex += yyleng; \
+ } while (0);
+
+#define YY_INPUT(buf, result, maxSize) result = yyextra->input.read(buf, maxSize, &yylineno);
+
+#define INITIAL 0
+#define COMMENT 1
+
+#define YY_EXTRA_TYPE angle::pp::Tokenizer::Context *
+
+/* Holds the entire state of the reentrant scanner. */
+struct yyguts_t
+{
+
+ /* User-defined. Not touched by flex. */
+ YY_EXTRA_TYPE yyextra_r;
+
+ /* The rest are the same as the globals declared in the non-reentrant scanner. */
+ FILE *yyin_r, *yyout_r;
+ size_t yy_buffer_stack_top; /**< index of top of stack. */
+ size_t yy_buffer_stack_max; /**< capacity of stack. */
+ YY_BUFFER_STATE *yy_buffer_stack; /**< Stack as an array. */
+ char yy_hold_char;
+ int yy_n_chars;
+ int yyleng_r;
+ char *yy_c_buf_p;
+ int yy_init;
+ int yy_start;
+ int yy_did_buffer_switch_on_eof;
+ int yy_start_stack_ptr;
+ int yy_start_stack_depth;
+ int *yy_start_stack;
+ yy_state_type yy_last_accepting_state;
+ char *yy_last_accepting_cpos;
+
+ 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 yylex_init(yyscan_t *scanner);
+
+int yylex_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 yylex_destroy(yyscan_t yyscanner);
+
+int yyget_debug(yyscan_t yyscanner);
+
+void yyset_debug(int debug_flag, yyscan_t yyscanner);
+
+YY_EXTRA_TYPE yyget_extra(yyscan_t yyscanner);
+
+void yyset_extra(YY_EXTRA_TYPE user_defined, yyscan_t yyscanner);
+
+FILE *yyget_in(yyscan_t yyscanner);
+
+void yyset_in(FILE *_in_str, yyscan_t yyscanner);
+
+FILE *yyget_out(yyscan_t yyscanner);
+
+void yyset_out(FILE *_out_str, yyscan_t yyscanner);
+
+int yyget_leng(yyscan_t yyscanner);
+
+char *yyget_text(yyscan_t yyscanner);
+
+int yyget_lineno(yyscan_t yyscanner);
+
+void yyset_lineno(int _line_number, yyscan_t yyscanner);
+
+int yyget_column(yyscan_t yyscanner);
+
+void yyset_column(int _column_no, yyscan_t yyscanner);
+
+YYSTYPE *yyget_lval(yyscan_t yyscanner);
+
+void yyset_lval(YYSTYPE *yylval_param, yyscan_t yyscanner);
+
+YYLTYPE *yyget_lloc(yyscan_t yyscanner);
+
+void yyset_lloc(YYLTYPE *yylloc_param, yyscan_t yyscanner);
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+# ifdef __cplusplus
+extern "C" int yywrap(yyscan_t yyscanner);
+# else
+extern int yywrap(yyscan_t yyscanner);
+# endif
+#endif
+
+#ifndef YY_NO_UNPUT
+
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy(char *, const char *, int, yyscan_t yyscanner);
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen(const char *, yyscan_t yyscanner);
+#endif
+
+#ifndef YY_NO_INPUT
+# ifdef __cplusplus
+static int yyinput(yyscan_t yyscanner);
+# else
+static int input(yyscan_t yyscanner);
+# endif
+
+#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, (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".
+ */
+#ifndef YY_INPUT
+# define YY_INPUT(buf, result, max_size) \
+ if (YY_CURRENT_BUFFER_LVALUE->yy_is_interactive) \
+ { \
+ int c = '*'; \
+ int n; \
+ for (n = 0; n < max_size && (c = getc(yyin)) != EOF && c != '\n'; ++n) \
+ buf[n] = (char)c; \
+ if (c == '\n') \
+ buf[n++] = (char)c; \
+ if (c == EOF && ferror(yyin)) \
+ YY_FATAL_ERROR("input in flex scanner failed"); \
+ result = n; \
+ } \
+ else \
+ { \
+ errno = 0; \
+ while ((result = (int)fread(buf, 1, (yy_size_t)max_size, yyin)) == 0 && ferror(yyin)) \
+ { \
+ if (errno != EINTR) \
+ { \
+ YY_FATAL_ERROR("input in flex scanner failed"); \
+ break; \
+ } \
+ errno = 0; \
+ clearerr(yyin); \
+ } \
+ }
+
+#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.
+ */
+#ifndef yyterminate
+# 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 yylex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param, yyscan_t yyscanner);
+
+# define YY_DECL int yylex(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.
+ */
+#ifndef YY_USER_ACTION
+# define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_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
+{
+ 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;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if (!yyg->yy_start)
+ yyg->yy_start = 1; /* first start state */
+
+ if (!yyin)
+ yyin = stdin;
+
+ if (!yyout)
+ yyout = stdout;
+
+ if (!YY_CURRENT_BUFFER)
+ {
+ yyensure_buffer_stack(yyscanner);
+ YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin, YY_BUF_SIZE, yyscanner);
+ }
+
+ yy_load_buffer_state(yyscanner);
+ }
+
+ {
+
+ /* Line comment */
+
+ while (/*CONSTCOND*/ 1) /* loops until end-of-file is reached */
+ {
+ yy_cp = yyg->yy_c_buf_p;
+
+ /* Support of yytext. */
+ *yy_cp = yyg->yy_hold_char;
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = yyg->yy_start;
+ yy_match:
+ do
+ {
+ 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;
+ yyg->yy_last_accepting_cpos = yy_cp;
+ }
+ while (yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state)
+ {
+ yy_current_state = (int)yy_def[yy_current_state];
+ if (yy_current_state >= 95)
+ yy_c = yy_meta[yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
+ ++yy_cp;
+ } while (yy_current_state != 94);
+ yy_cp = yyg->yy_last_accepting_cpos;
+ yy_current_state = yyg->yy_last_accepting_state;
+
+ yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+
+ 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 */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = yyg->yy_hold_char;
+ yy_cp = yyg->yy_last_accepting_cpos;
+ yy_current_state = yyg->yy_last_accepting_state;
+ goto yy_find_action;
+
+ case 1:
+ YY_RULE_SETUP
+
+ YY_BREAK
+ /* Block comment */
+ /* Line breaks are just counted - not returned. */
+ /* The comment is replaced by a single space. */
+ case 2:
+ YY_RULE_SETUP
+ {
+ BEGIN(COMMENT);
+ }
+ YY_BREAK
+ case 3:
+ YY_RULE_SETUP
+
+ YY_BREAK
+ case 4:
+ YY_RULE_SETUP
+
+ YY_BREAK
+ case 5:
+ /* rule 5 can match eol */
+ YY_RULE_SETUP
+ {
+ if (yylineno == INT_MAX)
+ {
+ *yylval = "Integer overflow on line number";
+ return angle::pp::Token::GOT_ERROR;
+ }
+ ++yylineno;
+ }
+ YY_BREAK
+ case 6:
+ YY_RULE_SETUP
+ {
+ yyextra->leadingSpace = true;
+ BEGIN(INITIAL);
+ }
+ YY_BREAK
+ case 7:
+ YY_RULE_SETUP
+ {
+ // # is only valid at start of line for preprocessor directives.
+ yylval->assign(1, yytext[0]);
+ return yyextra->lineStart ? angle::pp::Token::PP_HASH
+ : angle::pp::Token::PP_OTHER;
+ }
+ YY_BREAK
+ case 8:
+ YY_RULE_SETUP
+ {
+ yylval->assign(yytext, yyleng);
+ return angle::pp::Token::IDENTIFIER;
+ }
+ YY_BREAK
+ case 9:
+ YY_RULE_SETUP
+ {
+ yylval->assign(yytext, yyleng);
+ return angle::pp::Token::CONST_INT;
+ }
+ YY_BREAK
+ case 10:
+ YY_RULE_SETUP
+ {
+ yylval->assign(yytext, yyleng);
+ return angle::pp::Token::CONST_FLOAT;
+ }
+ YY_BREAK
+ /* Anything that starts with a {DIGIT} or .{DIGIT} must be a number. */
+ /* Rule to catch all invalid integers and floats. */
+ case 11:
+ YY_RULE_SETUP
+ {
+ yylval->assign(yytext, yyleng);
+ return angle::pp::Token::PP_NUMBER;
+ }
+ YY_BREAK
+ case 12:
+ YY_RULE_SETUP
+ {
+ yylval->assign(yytext, yyleng);
+ return angle::pp::Token::OP_INC;
+ }
+ YY_BREAK
+ case 13:
+ YY_RULE_SETUP
+ {
+ yylval->assign(yytext, yyleng);
+ return angle::pp::Token::OP_DEC;
+ }
+ YY_BREAK
+ case 14:
+ YY_RULE_SETUP
+ {
+ yylval->assign(yytext, yyleng);
+ return angle::pp::Token::OP_LEFT;
+ }
+ YY_BREAK
+ case 15:
+ YY_RULE_SETUP
+ {
+ yylval->assign(yytext, yyleng);
+ return angle::pp::Token::OP_RIGHT;
+ }
+ YY_BREAK
+ case 16:
+ YY_RULE_SETUP
+ {
+ yylval->assign(yytext, yyleng);
+ return angle::pp::Token::OP_LE;
+ }
+ YY_BREAK
+ case 17:
+ YY_RULE_SETUP
+ {
+ yylval->assign(yytext, yyleng);
+ return angle::pp::Token::OP_GE;
+ }
+ YY_BREAK
+ case 18:
+ YY_RULE_SETUP
+ {
+ yylval->assign(yytext, yyleng);
+ return angle::pp::Token::OP_EQ;
+ }
+ YY_BREAK
+ case 19:
+ YY_RULE_SETUP
+ {
+ yylval->assign(yytext, yyleng);
+ return angle::pp::Token::OP_NE;
+ }
+ YY_BREAK
+ case 20:
+ YY_RULE_SETUP
+ {
+ yylval->assign(yytext, yyleng);
+ return angle::pp::Token::OP_AND;
+ }
+ YY_BREAK
+ case 21:
+ YY_RULE_SETUP
+ {
+ yylval->assign(yytext, yyleng);
+ return angle::pp::Token::OP_XOR;
+ }
+ YY_BREAK
+ case 22:
+ YY_RULE_SETUP
+ {
+ yylval->assign(yytext, yyleng);
+ return angle::pp::Token::OP_OR;
+ }
+ YY_BREAK
+ case 23:
+ YY_RULE_SETUP
+ {
+ yylval->assign(yytext, yyleng);
+ return angle::pp::Token::OP_ADD_ASSIGN;
+ }
+ YY_BREAK
+ case 24:
+ YY_RULE_SETUP
+ {
+ yylval->assign(yytext, yyleng);
+ return angle::pp::Token::OP_SUB_ASSIGN;
+ }
+ YY_BREAK
+ case 25:
+ YY_RULE_SETUP
+ {
+ yylval->assign(yytext, yyleng);
+ return angle::pp::Token::OP_MUL_ASSIGN;
+ }
+ YY_BREAK
+ case 26:
+ YY_RULE_SETUP
+ {
+ yylval->assign(yytext, yyleng);
+ return angle::pp::Token::OP_DIV_ASSIGN;
+ }
+ YY_BREAK
+ case 27:
+ YY_RULE_SETUP
+ {
+ yylval->assign(yytext, yyleng);
+ return angle::pp::Token::OP_MOD_ASSIGN;
+ }
+ YY_BREAK
+ case 28:
+ YY_RULE_SETUP
+ {
+ yylval->assign(yytext, yyleng);
+ return angle::pp::Token::OP_LEFT_ASSIGN;
+ }
+ YY_BREAK
+ case 29:
+ YY_RULE_SETUP
+ {
+ yylval->assign(yytext, yyleng);
+ return angle::pp::Token::OP_RIGHT_ASSIGN;
+ }
+ YY_BREAK
+ case 30:
+ YY_RULE_SETUP
+ {
+ yylval->assign(yytext, yyleng);
+ return angle::pp::Token::OP_AND_ASSIGN;
+ }
+ YY_BREAK
+ case 31:
+ YY_RULE_SETUP
+ {
+ yylval->assign(yytext, yyleng);
+ return angle::pp::Token::OP_XOR_ASSIGN;
+ }
+ YY_BREAK
+ case 32:
+ YY_RULE_SETUP
+ {
+ yylval->assign(yytext, yyleng);
+ return angle::pp::Token::OP_OR_ASSIGN;
+ }
+ YY_BREAK
+ case 33:
+ YY_RULE_SETUP
+ {
+ yylval->assign(1, yytext[0]);
+ return yytext[0];
+ }
+ YY_BREAK
+ case 34:
+ YY_RULE_SETUP
+ {
+ yyextra->leadingSpace = true;
+ }
+ YY_BREAK
+ case 35:
+ /* rule 35 can match eol */
+ YY_RULE_SETUP
+ {
+ if (yylineno == INT_MAX)
+ {
+ *yylval = "Integer overflow on line number";
+ return angle::pp::Token::GOT_ERROR;
+ }
+ ++yylineno;
+ yylval->assign(1, '\n');
+ return '\n';
+ }
+ YY_BREAK
+ case 36:
+ YY_RULE_SETUP
+ {
+ yylval->assign(1, yytext[0]);
+ return angle::pp::Token::PP_OTHER;
+ }
+ YY_BREAK
+ case YY_STATE_EOF(INITIAL):
+ case YY_STATE_EOF(COMMENT):
+ {
+ // YY_USER_ACTION is not invoked for handling EOF.
+ // Set the location for EOF token manually.
+ angle::pp::Input *input = &yyextra->input;
+ angle::pp::Input::Location *scanLoc = &yyextra->scanLoc;
+ yy_size_t sIndexMax = input->count() ? input->count() - 1 : 0;
+ if (scanLoc->sIndex != sIndexMax)
+ {
+ // We can only reach here if there are empty strings at the
+ // end of the input.
+ scanLoc->sIndex = sIndexMax;
+ scanLoc->cIndex = 0;
+ // FIXME: this is not 64-bit clean.
+ yyfileno = static_cast<int>(sIndexMax);
+ yylineno = 1;
+ }
+ yylloc->file = yyfileno;
+ yylloc->line = yylineno;
+ yylval->clear();
+
+ // Line number overflows fake EOFs to exit early, check for this case.
+ if (yylineno == INT_MAX)
+ {
+ yyextra->diagnostics->report(angle::pp::Diagnostics::PP_TOKENIZER_ERROR,
+ angle::pp::SourceLocation(yyfileno, yylineno),
+ "Integer overflow on line number");
+ }
+ else if (YY_START == COMMENT)
+ {
+ yyextra->diagnostics->report(angle::pp::Diagnostics::PP_EOF_IN_COMMENT,
+ angle::pp::SourceLocation(yyfileno, yylineno),
+ "EOF while in a comment");
+ }
+ yyterminate();
+ }
+ YY_BREAK
+ case 37:
+ YY_RULE_SETUP
+ ECHO;
+ YY_BREAK
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int)(yy_cp - yyg->yytext_ptr) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = yyg->yy_hold_char;
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if (YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW)
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * yylex(). If so, then we have to assure
+ * consistency between YY_CURRENT_BUFFER and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if (yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars])
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state(yyscanner);
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans(yy_current_state, yyscanner);
+
+ yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+
+ if (yy_next_state)
+ {
+ /* Consume the NUL. */
+ yy_cp = ++yyg->yy_c_buf_p;
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = yyg->yy_last_accepting_cpos;
+ yy_current_state = yyg->yy_last_accepting_state;
+ goto yy_find_action;
+ }
+ }
+
+ else
+ switch (yy_get_next_buffer(yyscanner))
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ yyg->yy_did_buffer_switch_on_eof = 0;
+
+ if (yywrap(yyscanner))
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if (!yyg->yy_did_buffer_switch_on_eof)
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state(yyscanner);
+
+ yy_cp = yyg->yy_c_buf_p;
+ yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ yyg->yy_c_buf_p =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars];
+
+ yy_current_state = yy_get_previous_state(yyscanner);
+
+ yy_cp = yyg->yy_c_buf_p;
+ yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR("fatal flex scanner internal error--no action found");
+ } /* end of action switch */
+ } /* end of scanning one token */
+ } /* end of user's declarations */
+} /* end of yylex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ char *source = yyg->yytext_ptr;
+ int 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])
+ YY_FATAL_ERROR("fatal flex scanner internal error--end of buffer missed");
+
+ if (YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0)
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if (yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1)
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* 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);
+
+ for (i = 0; i < number_to_move; ++i)
+ *(dest++) = *(source++);
+
+ if (YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING)
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0;
+
+ else
+ {
+ int num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+ while (num_to_read <= 0)
+ { /* Not enough room in the buffer - grow it. */
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;
+
+ int yy_c_buf_p_offset = (int)(yyg->yy_c_buf_p - b->yy_ch_buf);
+
+ if (b->yy_is_our_buffer)
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if (new_size <= 0)
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ yyrealloc((void *)b->yy_ch_buf, (yy_size_t)(b->yy_buf_size + 2), yyscanner);
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = NULL;
+
+ if (!b->yy_ch_buf)
+ YY_FATAL_ERROR("fatal error - scanner input buffer overflow");
+
+ 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;
+ }
+
+ if (num_to_read > YY_READ_BUF_SIZE)
+ 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]), ret, num_to_read);
+ yyg->yy_n_chars = static_cast<int>(ret);
+
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+ }
+
+ if (yyg->yy_n_chars == 0)
+ {
+ if (number_to_move == YY_MORE_ADJ)
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ yyrestart(yyin, yyscanner);
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ if ((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_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *)yyrealloc(
+ (void *)YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t)new_size, yyscanner);
+ if (!YY_CURRENT_BUFFER_LVALUE->yy_ch_buf)
+ YY_FATAL_ERROR("out of dynamic memory in yy_get_next_buffer()");
+ /* "- 2" to take care of EOB's */
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int)(new_size - 2);
+ }
+
+ yyg->yy_n_chars += 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;
+
+ yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+ 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)
+{
+ 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)
+ {
+ 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;
+ yyg->yy_last_accepting_cpos = yy_cp;
+ }
+ while (yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state)
+ {
+ yy_current_state = (int)yy_def[yy_current_state];
+ if (yy_current_state >= 95)
+ yy_c = yy_meta[yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
+ }
+
+ return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+static yy_state_type yy_try_NUL_trans(yy_state_type yy_current_state, yyscan_t yyscanner)
+{
+ int yy_is_jam;
+ struct yyguts_t *yyg =
+ (struct yyguts_t *)yyscanner; /* This var may be unused depending upon options. */
+ char *yy_cp = yyg->yy_c_buf_p;
+
+ YY_CHAR yy_c = 1;
+ if (yy_accept[yy_current_state])
+ {
+ yyg->yy_last_accepting_state = yy_current_state;
+ yyg->yy_last_accepting_cpos = yy_cp;
+ }
+ while (yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state)
+ {
+ yy_current_state = (int)yy_def[yy_current_state];
+ if (yy_current_state >= 95)
+ yy_c = yy_meta[yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
+ yy_is_jam = (yy_current_state == 94);
+
+ (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)
+# else
+static int input(yyscan_t yyscanner)
+# endif
+
+{
+ int c;
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+
+ *yyg->yy_c_buf_p = yyg->yy_hold_char;
+
+ if (*yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR)
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if (yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars])
+ /* This was really a NUL. */
+ *yyg->yy_c_buf_p = '\0';
+
+ else
+ { /* need more input */
+ int offset = (int)(yyg->yy_c_buf_p - yyg->yytext_ptr);
+ ++yyg->yy_c_buf_p;
+
+ switch (yy_get_next_buffer(yyscanner))
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ yyrestart(yyin, yyscanner);
+
+ /*FALLTHROUGH*/
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if (yywrap(yyscanner))
+ return 0;
+
+ if (!yyg->yy_did_buffer_switch_on_eof)
+ YY_NEW_FILE;
+# ifdef __cplusplus
+ return yyinput(yyscanner);
+# else
+ return input(yyscanner);
+# endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yyg->yy_c_buf_p = yyg->yytext_ptr + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *)yyg->yy_c_buf_p; /* cast for 8-bit char's */
+ *yyg->yy_c_buf_p = '\0'; /* preserve yytext */
+ yyg->yy_hold_char = *++yyg->yy_c_buf_p;
+
+ return c;
+}
+#endif /* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ * @param yyscanner The scanner object.
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+void yyrestart(FILE *input_file, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+
+ if (!YY_CURRENT_BUFFER)
+ {
+ yyensure_buffer_stack(yyscanner);
+ YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin, YY_BUF_SIZE, yyscanner);
+ }
+
+ yy_init_buffer(YY_CURRENT_BUFFER, input_file, yyscanner);
+ yy_load_buffer_state(yyscanner);
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ * @param yyscanner The scanner object.
+ */
+void yy_switch_to_buffer(YY_BUFFER_STATE new_buffer, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+
+ /* TODO. We should be able to replace this entire function body
+ * with
+ * yypop_buffer_state();
+ * yypush_buffer_state(new_buffer);
+ */
+ yyensure_buffer_stack(yyscanner);
+ if (YY_CURRENT_BUFFER == new_buffer)
+ return;
+
+ if (YY_CURRENT_BUFFER)
+ {
+ /* Flush out information for old buffer. */
+ *yyg->yy_c_buf_p = yyg->yy_hold_char;
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+ }
+
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+ yy_load_buffer_state(yyscanner);
+
+ /* We don't actually know whether we did this switch during
+ * EOF (yywrap()) processing, but the only time this flag
+ * is looked at is after yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ yyg->yy_did_buffer_switch_on_eof = 1;
+}
+
+static void yy_load_buffer_state(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+ yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+ yyg->yy_hold_char = *yyg->yy_c_buf_p;
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ * @param yyscanner The scanner object.
+ * @return the allocated buffer state.
+ */
+YY_BUFFER_STATE yy_create_buffer(FILE *file, int size, yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE)yyalloc(sizeof(struct yy_buffer_state), yyscanner);
+ if (!b)
+ YY_FATAL_ERROR("out of dynamic memory in yy_create_buffer()");
+
+ b->yy_buf_size = 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.
+ */
+ b->yy_ch_buf = (char *)yyalloc((yy_size_t)(b->yy_buf_size + 2), yyscanner);
+ if (!b->yy_ch_buf)
+ YY_FATAL_ERROR("out of dynamic memory in yy_create_buffer()");
+
+ b->yy_is_our_buffer = 1;
+
+ yy_init_buffer(b, file, yyscanner);
+
+ return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with yy_create_buffer()
+ * @param yyscanner The scanner object.
+ */
+void yy_delete_buffer(YY_BUFFER_STATE b, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+
+ if (!b)
+ return;
+
+ if (b == YY_CURRENT_BUFFER) /* Not sure if we should pop here. */
+ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE)0;
+
+ if (b->yy_is_our_buffer)
+ yyfree((void *)b->yy_ch_buf, yyscanner);
+
+ yyfree((void *)b, yyscanner);
+}
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a yyrestart() or at EOF.
+ */
+static void yy_init_buffer(YY_BUFFER_STATE b, FILE *file, yyscan_t yyscanner)
+
+{
+ int oerrno = errno;
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+
+ yy_flush_buffer(b, yyscanner);
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+ /* If b is the current buffer, then yy_init_buffer was _probably_
+ * called from yyrestart() or through yy_get_next_buffer.
+ * In that case, we don't want to reset the lineno or column.
+ */
+ if (b != YY_CURRENT_BUFFER)
+ {
+ b->yy_bs_lineno = 1;
+ b->yy_bs_column = 0;
+ }
+
+ b->yy_is_interactive = 0;
+
+ errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ * @param yyscanner The scanner object.
+ */
+void yy_flush_buffer(YY_BUFFER_STATE b, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ if (!b)
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if (b == YY_CURRENT_BUFFER)
+ yy_load_buffer_state(yyscanner);
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ * the current state. This function will allocate the stack
+ * if necessary.
+ * @param new_buffer The new state.
+ * @param yyscanner The scanner object.
+ */
+void yypush_buffer_state(YY_BUFFER_STATE new_buffer, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ if (new_buffer == NULL)
+ return;
+
+ yyensure_buffer_stack(yyscanner);
+
+ /* This block is copied from yy_switch_to_buffer. */
+ if (YY_CURRENT_BUFFER)
+ {
+ /* Flush out information for old buffer. */
+ *yyg->yy_c_buf_p = yyg->yy_hold_char;
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+ }
+
+ /* Only push if top exists. Otherwise, replace top. */
+ if (YY_CURRENT_BUFFER)
+ yyg->yy_buffer_stack_top++;
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+ /* copied from yy_switch_to_buffer. */
+ yy_load_buffer_state(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.
+ */
+void yypop_buffer_state(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ yy_delete_buffer(YY_CURRENT_BUFFER, yyscanner);
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ if (yyg->yy_buffer_stack_top > 0)
+ --yyg->yy_buffer_stack_top;
+
+ if (YY_CURRENT_BUFFER)
+ {
+ yy_load_buffer_state(yyscanner);
+ yyg->yy_did_buffer_switch_on_eof = 1;
+ }
+}
+
+/* Allocates the stack if it does not exist.
+ * Guarantees space for at least one push.
+ */
+static void yyensure_buffer_stack(yyscan_t yyscanner)
+{
+ yy_size_t num_to_alloc;
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+
+ if (!yyg->yy_buffer_stack)
+ {
+
+ /* First allocation is just for 2 elements, since we don't know if this
+ * 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; /* After all that talk, this was set to 1 anyways... */
+ yyg->yy_buffer_stack = (struct yy_buffer_state **)yyalloc(
+ num_to_alloc * sizeof(struct yy_buffer_state *), yyscanner);
+ if (!yyg->yy_buffer_stack)
+ YY_FATAL_ERROR("out of dynamic memory in yyensure_buffer_stack()");
+
+ memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state *));
+
+ yyg->yy_buffer_stack_max = num_to_alloc;
+ yyg->yy_buffer_stack_top = 0;
+ return;
+ }
+
+ if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1)
+ {
+
+ /* Increase the buffer to prepare for a possible push. */
+ 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 **)yyrealloc(
+ yyg->yy_buffer_stack, num_to_alloc * sizeof(struct yy_buffer_state *), yyscanner);
+ if (!yyg->yy_buffer_stack)
+ YY_FATAL_ERROR("out of dynamic memory in yyensure_buffer_stack()");
+
+ /* zero only the new slots.*/
+ memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0,
+ grow_size * sizeof(struct yy_buffer_state *));
+ yyg->yy_buffer_stack_max = num_to_alloc;
+ }
+}
+
+/** 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
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_buffer(char *base, yy_size_t size, yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+
+ if (size < 2 || 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 NULL;
+
+ b = (YY_BUFFER_STATE)yyalloc(sizeof(struct yy_buffer_state), yyscanner);
+ if (!b)
+ YY_FATAL_ERROR("out of dynamic memory in yy_scan_buffer()");
+
+ b->yy_buf_size = (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;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ yy_switch_to_buffer(b, yyscanner);
+
+ return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to yylex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ * yy_scan_bytes() instead.
+ */
+YY_BUFFER_STATE yy_scan_string(const char *yystr, yyscan_t yyscanner)
+{
+
+ return yy_scan_bytes(yystr, (int)strlen(yystr), yyscanner);
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
+ * scan from a @e copy of @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_bytes(const char *yybytes, int _yybytes_len, yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = (yy_size_t)(_yybytes_len + 2);
+ buf = (char *)yyalloc(n, yyscanner);
+ if (!buf)
+ YY_FATAL_ERROR("out of dynamic memory in yy_scan_bytes()");
+
+ for (i = 0; i < _yybytes_len; ++i)
+ buf[i] = yybytes[i];
+
+ buf[_yybytes_len] = buf[_yybytes_len + 1] = YY_END_OF_BUFFER_CHAR;
+
+ b = yy_scan_buffer(buf, n, yyscanner);
+ if (!b)
+ YY_FATAL_ERROR("bad buffer in yy_scan_bytes()");
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+# define YY_EXIT_FAILURE 2
+#endif
+
+static void yynoreturn yy_fatal_error(const char *msg, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ (void)yyg;
+ fprintf(stderr, "%s\n", msg);
+ exit(YY_EXIT_FAILURE);
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg); \
+ yytext[yyleng] = yyg->yy_hold_char; \
+ yyg->yy_c_buf_p = yytext + yyless_macro_arg; \
+ yyg->yy_hold_char = *yyg->yy_c_buf_p; \
+ *yyg->yy_c_buf_p = '\0'; \
+ yyleng = yyless_macro_arg; \
+ } while (0)
+
+/* Accessor methods (get/set functions) to struct members. */
+
+/** Get the user-defined data for this scanner.
+ * @param yyscanner The scanner object.
+ */
+YY_EXTRA_TYPE yyget_extra(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ return yyextra;
+}
+
+/** Get the current line number.
+ * @param yyscanner The scanner object.
+ */
+int yyget_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.
+ */
+int yyget_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.
+ */
+FILE *yyget_in(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ return yyin;
+}
+
+/** Get the output stream.
+ * @param yyscanner The scanner object.
+ */
+FILE *yyget_out(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ return yyout;
+}
+
+/** Get the length of the current token.
+ * @param yyscanner The scanner object.
+ */
+int yyget_leng(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ return yyleng;
+}
+
+/** Get the current token.
+ * @param yyscanner The scanner object.
+ */
+
+char *yyget_text(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_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.
+ */
+void yyset_extra(YY_EXTRA_TYPE user_defined, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ yyextra = user_defined;
+}
+
+/** Set the current line number.
+ * @param _line_number line number
+ * @param yyscanner The scanner object.
+ */
+void yyset_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("yyset_lineno called with no buffer");
+
+ yylineno = _line_number;
+}
+
+/** Set the current column.
+ * @param _column_no column number
+ * @param yyscanner The scanner object.
+ */
+void yyset_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("yyset_column called with no buffer");
+
+ yycolumn = _column_no;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param _in_str A readable stream.
+ * @param yyscanner The scanner object.
+ * @see yy_switch_to_buffer
+ */
+void yyset_in(FILE *_in_str, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ yyin = _in_str;
+}
+
+void yyset_out(FILE *_out_str, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ yyout = _out_str;
+}
+
+int yyget_debug(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ return yy_flex_debug;
+}
+
+void yyset_debug(int _bdebug, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ yy_flex_debug = _bdebug;
+}
+
+/* Accessor methods for yylval and yylloc */
+
+YYSTYPE *yyget_lval(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ return yylval;
+}
+
+void yyset_lval(YYSTYPE *yylval_param, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ yylval = yylval_param;
+}
+
+YYLTYPE *yyget_lloc(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ return yylloc;
+}
+
+void yyset_lloc(YYLTYPE *yylloc_param, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ yylloc = yylloc_param;
+}
+
+/* User-visible API */
+
+/* yylex_init is special because it creates the scanner itself, so it is
+ * the ONLY reentrant function that doesn't take the scanner as the last argument.
+ * That's why we explicitly handle the declaration, instead of using our macros.
+ */
+int yylex_init(yyscan_t *ptr_yy_globals)
+{
+ if (ptr_yy_globals == NULL)
+ {
+ errno = EINVAL;
+ return 1;
+ }
+
+ *ptr_yy_globals = (yyscan_t)yyalloc(sizeof(struct yyguts_t), NULL);
+
+ if (*ptr_yy_globals == NULL)
+ {
+ errno = ENOMEM;
+ return 1;
+ }
+
+ /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */
+ memset(*ptr_yy_globals, 0x00, sizeof(struct yyguts_t));
+
+ return yy_init_globals(*ptr_yy_globals);
+}
+
+/* yylex_init_extra has the same functionality as yylex_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
+ * is the reason, too, why this function also must handle its own declaration).
+ * The user defined value in the first argument will be available to yyalloc in
+ * the yyextra field.
+ */
+int yylex_init_extra(YY_EXTRA_TYPE yy_user_defined, yyscan_t *ptr_yy_globals)
+{
+ struct yyguts_t dummy_yyguts;
+
+ yyset_extra(yy_user_defined, &dummy_yyguts);
+
+ if (ptr_yy_globals == NULL)
+ {
+ errno = EINVAL;
+ return 1;
+ }
+
+ *ptr_yy_globals = (yyscan_t)yyalloc(sizeof(struct yyguts_t), &dummy_yyguts);
+
+ if (*ptr_yy_globals == NULL)
+ {
+ errno = ENOMEM;
+ return 1;
+ }
+
+ /* By setting to 0xAA, we expose bugs in
+ yy_init_globals. Leave at 0x00 for releases. */
+ memset(*ptr_yy_globals, 0x00, sizeof(struct yyguts_t));
+
+ yyset_extra(yy_user_defined, *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;
+ /* Initialization is the same as for the non-reentrant scanner.
+ * This function is called from yylex_destroy(), so don't allocate here.
+ */
+
+ yyg->yy_buffer_stack = NULL;
+ yyg->yy_buffer_stack_top = 0;
+ yyg->yy_buffer_stack_max = 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 = NULL;
+ yyout = NULL;
+#endif
+
+ /* For future reference: Set errno on error, since we are called by
+ * yylex_init()
+ */
+ return 0;
+}
+
+/* yylex_destroy is for both reentrant and non-reentrant scanners. */
+int yylex_destroy(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+
+ /* Pop the buffer stack, destroying each element. */
+ while (YY_CURRENT_BUFFER)
+ {
+ yy_delete_buffer(YY_CURRENT_BUFFER, yyscanner);
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ yypop_buffer_state(yyscanner);
+ }
+
+ /* Destroy the stack itself. */
+ yyfree(yyg->yy_buffer_stack, yyscanner);
+ yyg->yy_buffer_stack = NULL;
+
+ /* Destroy the start condition stack. */
+ yyfree(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
+ * yylex() is called, initialization will occur. */
+ yy_init_globals(yyscanner);
+
+ /* Destroy the main struct (reentrant only). */
+ yyfree(yyscanner, yyscanner);
+ yyscanner = NULL;
+ return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy(char *s1, const char *s2, int n, yyscan_t yyscanner)
+{
+ 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(const char *s, yyscan_t yyscanner)
+{
+ int n;
+ for (n = 0; s[n]; ++n)
+ ;
+
+ return n;
+}
+#endif
+
+void *yyalloc(yy_size_t size, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ (void)yyg;
+ return malloc(size);
+}
+
+void *yyrealloc(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
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return realloc(ptr, size);
+}
+
+void yyfree(void *ptr, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ (void)yyg;
+ free((char *)ptr); /* see yyrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+namespace angle
+{
+
+namespace pp
+{
+
+Tokenizer::Tokenizer(Diagnostics *diagnostics) : mHandle(nullptr), mMaxTokenSize(256)
+{
+ mContext.diagnostics = diagnostics;
+}
+
+Tokenizer::~Tokenizer()
+{
+ destroyScanner();
+}
+
+bool Tokenizer::init(size_t count, const char *const string[], const int length[])
+{
+ if ((count > 0) && (string == 0))
+ return false;
+
+ mContext.input = Input(count, string, length);
+ return initScanner();
+}
+
+void Tokenizer::setFileNumber(int file)
+{
+ // We use column number as file number.
+ // See macro yyfileno.
+ yyset_column(file, mHandle);
+}
+
+void Tokenizer::setLineNumber(int line)
+{
+ yyset_lineno(line, mHandle);
+}
+
+void Tokenizer::setMaxTokenSize(size_t maxTokenSize)
+{
+ mMaxTokenSize = maxTokenSize;
+}
+
+void Tokenizer::lex(Token *token)
+{
+ int tokenType = yylex(&token->text, &token->location, mHandle);
+
+ if (tokenType == Token::GOT_ERROR)
+ {
+ mContext.diagnostics->report(Diagnostics::PP_TOKENIZER_ERROR, token->location, token->text);
+ token->type = Token::LAST;
+ }
+ else
+ {
+ token->type = tokenType;
+ }
+
+ if (token->text.size() > mMaxTokenSize)
+ {
+ mContext.diagnostics->report(Diagnostics::PP_TOKEN_TOO_LONG, token->location, token->text);
+ token->text.erase(mMaxTokenSize);
+ }
+
+ token->flags = 0;
+
+ token->setAtStartOfLine(mContext.lineStart);
+ mContext.lineStart = token->type == '\n';
+
+ token->setHasLeadingSpace(mContext.leadingSpace);
+ mContext.leadingSpace = false;
+}
+
+bool Tokenizer::initScanner()
+{
+ if ((mHandle == nullptr) && yylex_init_extra(&mContext, &mHandle))
+ return false;
+
+ yyrestart(0, mHandle);
+ return true;
+}
+
+void Tokenizer::destroyScanner()
+{
+ if (mHandle == nullptr)
+ return;
+
+ yylex_destroy(mHandle);
+ mHandle = nullptr;
+}
+
+} // namespace pp
+
+} // namespace angle
diff --git a/gfx/angle/checkout/src/compiler/preprocessor/preprocessor_tab_autogen.cpp b/gfx/angle/checkout/src/compiler/preprocessor/preprocessor_tab_autogen.cpp
new file mode 100644
index 0000000000..a7607c9e52
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/preprocessor/preprocessor_tab_autogen.cpp
@@ -0,0 +1,1773 @@
+/* A Bison parser, made by GNU Bison 3.8.2. */
+
+/* Bison implementation for Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
+ Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+ simplifying the original so-called "semantic" parser. */
+
+/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
+ especially those whose name start with YY_ or yy_. They are
+ private implementation details that can be changed or removed. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+/* Identify Bison output, and Bison version. */
+#define YYBISON 30802
+
+/* Bison version string. */
+#define YYBISON_VERSION "3.8.2"
+
+/* Skeleton name. */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers. */
+#define YYPURE 1
+
+/* Push parsers. */
+#define YYPUSH 0
+
+/* Pull parsers. */
+#define YYPULL 1
+
+/* Substitute the type names. */
+#define YYSTYPE PPSTYPE
+/* Substitute the variable and function names. */
+#define yyparse ppparse
+#define yylex pplex
+#define yyerror pperror
+#define yydebug ppdebug
+#define yynerrs ppnerrs
+
+/* First part of user prologue. */
+
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_parser.py from preprocessor.y
+//
+// Copyright 2019 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.
+//
+// preprocessor.y:
+// Parser for the OpenGL shading language preprocessor.
+
+#if defined(__GNUC__)
+// Triggered by the auto-generated pplval variable.
+# if !defined(__clang__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))
+# pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+# else
+# pragma GCC diagnostic ignored "-Wuninitialized"
+# endif
+#elif defined(_MSC_VER)
+# pragma warning(disable : 4065 4244 4701 4702)
+#endif
+#if defined(__clang__)
+# pragma clang diagnostic ignored "-Wunreachable-code"
+# pragma clang diagnostic ignored "-Wunused-but-set-variable"
+#endif
+
+#include "ExpressionParser.h"
+
+#if defined(_MSC_VER)
+# include <malloc.h>
+#else
+# include <stdlib.h>
+#endif
+
+#include <stdint.h>
+#include <cassert>
+#include <sstream>
+
+#include "DiagnosticsBase.h"
+#include "Lexer.h"
+#include "Token.h"
+#include "common/mathutil.h"
+
+typedef int32_t YYSTYPE;
+typedef uint32_t UNSIGNED_TYPE;
+
+#define YYENABLE_NLS 0
+#define YYLTYPE_IS_TRIVIAL 1
+#define YYSTYPE_IS_TRIVIAL 1
+#define YYSTYPE_IS_DECLARED 1
+
+namespace
+{
+struct Context
+{
+ angle::pp::Diagnostics *diagnostics;
+ angle::pp::Lexer *lexer;
+ angle::pp::Token *token;
+ int *result;
+ bool parsePresetToken;
+
+ angle::pp::ExpressionParser::ErrorSettings errorSettings;
+ bool *valid;
+
+ void startIgnoreErrors() { ++ignoreErrors; }
+ void endIgnoreErrors() { --ignoreErrors; }
+
+ bool isIgnoringErrors() { return ignoreErrors > 0; }
+
+ int ignoreErrors;
+};
+} // namespace
+
+static int yylex(YYSTYPE *lvalp, Context *context);
+static void yyerror(Context *context, const char *reason);
+
+#ifndef YY_CAST
+# ifdef __cplusplus
+# define YY_CAST(Type, Val) static_cast<Type>(Val)
+# define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast<Type>(Val)
+# else
+# define YY_CAST(Type, Val) ((Type)(Val))
+# define YY_REINTERPRET_CAST(Type, Val) ((Type)(Val))
+# endif
+#endif
+#ifndef YY_NULLPTR
+# if defined __cplusplus
+# if 201103L <= __cplusplus
+# define YY_NULLPTR nullptr
+# else
+# define YY_NULLPTR 0
+# endif
+# else
+# define YY_NULLPTR ((void *)0)
+# endif
+#endif
+
+/* Debug traces. */
+#ifndef PPDEBUG
+# if defined YYDEBUG
+# if YYDEBUG
+# define PPDEBUG 1
+# else
+# define PPDEBUG 0
+# endif
+# else /* ! defined YYDEBUG */
+# define PPDEBUG 0
+# endif /* ! defined YYDEBUG */
+#endif /* ! defined PPDEBUG */
+#if PPDEBUG
+extern int ppdebug;
+#endif
+
+/* Token kinds. */
+#ifndef PPTOKENTYPE
+# define PPTOKENTYPE
+enum pptokentype
+{
+ PPEMPTY = -2,
+ PPEOF = 0, /* "end of file" */
+ PPerror = 256, /* error */
+ PPUNDEF = 257, /* "invalid token" */
+ TOK_CONST_INT = 258, /* TOK_CONST_INT */
+ TOK_IDENTIFIER = 259, /* TOK_IDENTIFIER */
+ TOK_OP_OR = 260, /* TOK_OP_OR */
+ TOK_OP_AND = 261, /* TOK_OP_AND */
+ TOK_OP_EQ = 262, /* TOK_OP_EQ */
+ TOK_OP_NE = 263, /* TOK_OP_NE */
+ TOK_OP_LE = 264, /* TOK_OP_LE */
+ TOK_OP_GE = 265, /* TOK_OP_GE */
+ TOK_OP_LEFT = 266, /* TOK_OP_LEFT */
+ TOK_OP_RIGHT = 267, /* TOK_OP_RIGHT */
+ TOK_UNARY = 268 /* TOK_UNARY */
+};
+typedef enum pptokentype pptoken_kind_t;
+#endif
+
+/* Value type. */
+#if !defined PPSTYPE && !defined PPSTYPE_IS_DECLARED
+typedef int PPSTYPE;
+# define PPSTYPE_IS_TRIVIAL 1
+# define PPSTYPE_IS_DECLARED 1
+#endif
+
+int ppparse(Context *context);
+
+/* Symbol kind. */
+enum yysymbol_kind_t
+{
+ YYSYMBOL_YYEMPTY = -2,
+ YYSYMBOL_YYEOF = 0, /* "end of file" */
+ YYSYMBOL_YYerror = 1, /* error */
+ YYSYMBOL_YYUNDEF = 2, /* "invalid token" */
+ YYSYMBOL_TOK_CONST_INT = 3, /* TOK_CONST_INT */
+ YYSYMBOL_TOK_IDENTIFIER = 4, /* TOK_IDENTIFIER */
+ YYSYMBOL_TOK_OP_OR = 5, /* TOK_OP_OR */
+ YYSYMBOL_TOK_OP_AND = 6, /* TOK_OP_AND */
+ YYSYMBOL_7_ = 7, /* '|' */
+ YYSYMBOL_8_ = 8, /* '^' */
+ YYSYMBOL_9_ = 9, /* '&' */
+ YYSYMBOL_TOK_OP_EQ = 10, /* TOK_OP_EQ */
+ YYSYMBOL_TOK_OP_NE = 11, /* TOK_OP_NE */
+ YYSYMBOL_12_ = 12, /* '<' */
+ YYSYMBOL_13_ = 13, /* '>' */
+ YYSYMBOL_TOK_OP_LE = 14, /* TOK_OP_LE */
+ YYSYMBOL_TOK_OP_GE = 15, /* TOK_OP_GE */
+ YYSYMBOL_TOK_OP_LEFT = 16, /* TOK_OP_LEFT */
+ YYSYMBOL_TOK_OP_RIGHT = 17, /* TOK_OP_RIGHT */
+ YYSYMBOL_18_ = 18, /* '+' */
+ YYSYMBOL_19_ = 19, /* '-' */
+ YYSYMBOL_20_ = 20, /* '*' */
+ YYSYMBOL_21_ = 21, /* '/' */
+ YYSYMBOL_22_ = 22, /* '%' */
+ YYSYMBOL_TOK_UNARY = 23, /* TOK_UNARY */
+ YYSYMBOL_24_ = 24, /* '!' */
+ YYSYMBOL_25_ = 25, /* '~' */
+ YYSYMBOL_26_ = 26, /* '(' */
+ YYSYMBOL_27_ = 27, /* ')' */
+ YYSYMBOL_YYACCEPT = 28, /* $accept */
+ YYSYMBOL_input = 29, /* input */
+ YYSYMBOL_expression = 30, /* expression */
+ YYSYMBOL_31_1 = 31, /* $@1 */
+ YYSYMBOL_32_2 = 32 /* $@2 */
+};
+typedef enum yysymbol_kind_t yysymbol_kind_t;
+
+#ifdef short
+# undef short
+#endif
+
+/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure
+ <limits.h> and (if available) <stdint.h> are included
+ so that the code can choose integer types of a good width. */
+
+#ifndef __PTRDIFF_MAX__
+# include <limits.h> /* INFRINGES ON USER NAME SPACE */
+# if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
+# include <stdint.h> /* INFRINGES ON USER NAME SPACE */
+# define YY_STDINT_H
+# endif
+#endif
+
+/* Narrow types that promote to a signed type and that can represent a
+ signed or unsigned integer of at least N bits. In tables they can
+ save space and decrease cache pressure. Promoting to a signed type
+ helps avoid bugs in integer arithmetic. */
+
+#ifdef __INT_LEAST8_MAX__
+typedef __INT_LEAST8_TYPE__ yytype_int8;
+#elif defined YY_STDINT_H
+typedef int_least8_t yytype_int8;
+#else
+typedef signed char yytype_int8;
+#endif
+
+#ifdef __INT_LEAST16_MAX__
+typedef __INT_LEAST16_TYPE__ yytype_int16;
+#elif defined YY_STDINT_H
+typedef int_least16_t yytype_int16;
+#else
+typedef short yytype_int16;
+#endif
+
+/* Work around bug in HP-UX 11.23, which defines these macros
+ incorrectly for preprocessor constants. This workaround can likely
+ be removed in 2023, as HPE has promised support for HP-UX 11.23
+ (aka HP-UX 11i v2) only through the end of 2022; see Table 2 of
+ <https://h20195.www2.hpe.com/V2/getpdf.aspx/4AA4-7673ENW.pdf>. */
+#ifdef __hpux
+# undef UINT_LEAST8_MAX
+# undef UINT_LEAST16_MAX
+# define UINT_LEAST8_MAX 255
+# define UINT_LEAST16_MAX 65535
+#endif
+
+#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__
+typedef __UINT_LEAST8_TYPE__ yytype_uint8;
+#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H && UINT_LEAST8_MAX <= INT_MAX)
+typedef uint_least8_t yytype_uint8;
+#elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX
+typedef unsigned char yytype_uint8;
+#else
+typedef short yytype_uint8;
+#endif
+
+#if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__
+typedef __UINT_LEAST16_TYPE__ yytype_uint16;
+#elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H && UINT_LEAST16_MAX <= INT_MAX)
+typedef uint_least16_t yytype_uint16;
+#elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX
+typedef unsigned short yytype_uint16;
+#else
+typedef int yytype_uint16;
+#endif
+
+#ifndef YYPTRDIFF_T
+# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__
+# define YYPTRDIFF_T __PTRDIFF_TYPE__
+# define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__
+# elif defined PTRDIFF_MAX
+# ifndef ptrdiff_t
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# endif
+# define YYPTRDIFF_T ptrdiff_t
+# define YYPTRDIFF_MAXIMUM PTRDIFF_MAX
+# else
+# define YYPTRDIFF_T long
+# define YYPTRDIFF_MAXIMUM LONG_MAX
+# endif
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+# define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+# define YYSIZE_T size_t
+# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# else
+# define YYSIZE_T unsigned
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM \
+ YY_CAST(YYPTRDIFF_T, (YYPTRDIFF_MAXIMUM < YY_CAST(YYSIZE_T, -1) ? YYPTRDIFF_MAXIMUM \
+ : YY_CAST(YYSIZE_T, -1)))
+
+#define YYSIZEOF(X) YY_CAST(YYPTRDIFF_T, sizeof(X))
+
+/* Stored state numbers (used for stacks). */
+typedef yytype_int8 yy_state_t;
+
+/* State numbers in computations. */
+typedef int yy_state_fast_t;
+
+#ifndef YY_
+# if defined YYENABLE_NLS && YYENABLE_NLS
+# if ENABLE_NLS
+# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+# define YY_(Msgid) dgettext("bison-runtime", Msgid)
+# endif
+# endif
+# ifndef YY_
+# define YY_(Msgid) Msgid
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE_PURE
+# if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__)
+# define YY_ATTRIBUTE_PURE __attribute__((__pure__))
+# else
+# define YY_ATTRIBUTE_PURE
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE_UNUSED
+# if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__)
+# define YY_ATTRIBUTE_UNUSED __attribute__((__unused__))
+# else
+# define YY_ATTRIBUTE_UNUSED
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E. */
+#if !defined lint || defined __GNUC__
+# define YY_USE(E) ((void)(E))
+#else
+# define YY_USE(E) /* empty */
+#endif
+
+/* Suppress an incorrect diagnostic about yylval being uninitialized. */
+#if defined __GNUC__ && !defined __ICC && 406 <= __GNUC__ * 100 + __GNUC_MINOR__
+# if __GNUC__ * 100 + __GNUC_MINOR__ < 407
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+ _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wuninitialized\"")
+# else
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+ _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wuninitialized\"") \
+ _Pragma("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
+# endif
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END _Pragma("GCC diagnostic pop")
+#else
+# define YY_INITIAL_VALUE(Value) Value
+#endif
+#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END
+#endif
+#ifndef YY_INITIAL_VALUE
+# define YY_INITIAL_VALUE(Value) /* Nothing. */
+#endif
+
+#if defined __cplusplus && defined __GNUC__ && !defined __ICC && 6 <= __GNUC__
+# define YY_IGNORE_USELESS_CAST_BEGIN \
+ _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wuseless-cast\"")
+# define YY_IGNORE_USELESS_CAST_END _Pragma("GCC diagnostic pop")
+#endif
+#ifndef YY_IGNORE_USELESS_CAST_BEGIN
+# define YY_IGNORE_USELESS_CAST_BEGIN
+# define YY_IGNORE_USELESS_CAST_END
+#endif
+
+#define YY_ASSERT(E) ((void)(0 && (E)))
+
+#if !defined yyoverflow
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# ifdef YYSTACK_USE_ALLOCA
+# if YYSTACK_USE_ALLOCA
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# elif defined __BUILTIN_VA_ARG_INCR
+# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+# elif defined _AIX
+# define YYSTACK_ALLOC __alloca
+# elif defined _MSC_VER
+# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+# define alloca _alloca
+# else
+# define YYSTACK_ALLOC alloca
+# if !defined _ALLOCA_H && !defined EXIT_SUCCESS
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+/* Use EXIT_SUCCESS as a witness for stdlib.h. */
+# ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
+# endif
+# endif
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+/* Pacify GCC's 'empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) \
+ do \
+ { /* empty */ \
+ ; \
+ } while (0)
+# ifndef YYSTACK_ALLOC_MAXIMUM
+/* The OS might guarantee only one guard page at the bottom of the stack,
+ and a page size can be as small as 4096 bytes. So we cannot safely
+ invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
+ to allow for a few compiler-allocated temporary stack slots. */
+# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+# endif
+# else
+# define YYSTACK_ALLOC YYMALLOC
+# define YYSTACK_FREE YYFREE
+# ifndef YYSTACK_ALLOC_MAXIMUM
+# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+# endif
+# if (defined __cplusplus && !defined EXIT_SUCCESS && \
+ !((defined YYMALLOC || defined malloc) && (defined YYFREE || defined free)))
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
+# endif
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# if !defined malloc && !defined EXIT_SUCCESS
+void *malloc(YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# ifndef YYFREE
+# define YYFREE free
+# if !defined free && !defined EXIT_SUCCESS
+void free(void *); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# endif
+#endif /* !defined yyoverflow */
+
+#if (!defined yyoverflow && \
+ (!defined __cplusplus || (defined PPSTYPE_IS_TRIVIAL && PPSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ yy_state_t yyss_alloc;
+ YYSTYPE yyvs_alloc;
+};
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAXIMUM (YYSIZEOF(union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# define YYSTACK_BYTES(N) \
+ ((N) * (YYSIZEOF(yy_state_t) + YYSIZEOF(YYSTYPE)) + YYSTACK_GAP_MAXIMUM)
+
+# define YYCOPY_NEEDED 1
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
+ do \
+ { \
+ YYPTRDIFF_T yynewbytes; \
+ YYCOPY(&yyptr->Stack_alloc, Stack, yysize); \
+ Stack = &yyptr->Stack_alloc; \
+ yynewbytes = yystacksize * YYSIZEOF(*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / YYSIZEOF(*yyptr); \
+ } while (0)
+
+#endif
+
+#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
+/* Copy COUNT objects from SRC to DST. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if defined __GNUC__ && 1 < __GNUC__
+# define YYCOPY(Dst, Src, Count) \
+ __builtin_memcpy(Dst, Src, YY_CAST(YYSIZE_T, (Count)) * sizeof(*(Src)))
+# else
+# define YYCOPY(Dst, Src, Count) \
+ do \
+ { \
+ YYPTRDIFF_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (Dst)[yyi] = (Src)[yyi]; \
+ } while (0)
+# endif
+# endif
+#endif /* !YYCOPY_NEEDED */
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 15
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST 176
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 28
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 5
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 29
+/* YYNSTATES -- Number of states. */
+#define YYNSTATES 55
+
+/* YYMAXUTOK -- Last valid token kind. */
+#define YYMAXUTOK 268
+
+/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
+ as returned by yylex, with out-of-bounds checking. */
+#define YYTRANSLATE(YYX) \
+ (0 <= (YYX) && (YYX) <= YYMAXUTOK ? YY_CAST(yysymbol_kind_t, yytranslate[YYX]) \
+ : YYSYMBOL_YYUNDEF)
+
+/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
+ as returned by yylex. */
+static const yytype_int8 yytranslate[] = {
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 24, 2, 2, 2, 22, 9, 2, 26, 27, 20, 18, 2, 19, 2, 21, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 12, 2, 13, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 7, 2, 25, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 10, 11, 14, 15, 16, 17, 23};
+
+#if PPDEBUG
+/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
+static const yytype_int16 yyrline[] = {0, 114, 114, 121, 122, 133, 133, 154, 154, 175,
+ 178, 181, 184, 187, 190, 193, 196, 199, 202, 227,
+ 249, 252, 255, 281, 308, 311, 314, 317, 329, 332};
+#endif
+
+/** Accessing symbol of state STATE. */
+#define YY_ACCESSING_SYMBOL(State) YY_CAST(yysymbol_kind_t, yystos[State])
+
+#if PPDEBUG || 0
+/* The user-facing name of the symbol whose (internal) number is
+ YYSYMBOL. No bounds checking. */
+static const char *yysymbol_name(yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED;
+
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] = {"\"end of file\"",
+ "error",
+ "\"invalid token\"",
+ "TOK_CONST_INT",
+ "TOK_IDENTIFIER",
+ "TOK_OP_OR",
+ "TOK_OP_AND",
+ "'|'",
+ "'^'",
+ "'&'",
+ "TOK_OP_EQ",
+ "TOK_OP_NE",
+ "'<'",
+ "'>'",
+ "TOK_OP_LE",
+ "TOK_OP_GE",
+ "TOK_OP_LEFT",
+ "TOK_OP_RIGHT",
+ "'+'",
+ "'-'",
+ "'*'",
+ "'/'",
+ "'%'",
+ "TOK_UNARY",
+ "'!'",
+ "'~'",
+ "'('",
+ "')'",
+ "$accept",
+ "input",
+ "expression",
+ "$@1",
+ "$@2",
+ YY_NULLPTR};
+
+static const char *yysymbol_name(yysymbol_kind_t yysymbol)
+{
+ return yytname[yysymbol];
+}
+#endif
+
+#define YYPACT_NINF (-12)
+
+#define yypact_value_is_default(Yyn) ((Yyn) == YYPACT_NINF)
+
+#define YYTABLE_NINF (-1)
+
+#define yytable_value_is_error(Yyn) 0
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+static const yytype_int16 yypact[] = {
+ 31, -12, -12, 31, 31, 31, 31, 31, 51, 76, -12, -12, -12, -12, 53, -12, -12, -12, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, -12, 31, 31, 124,
+ 138, 26, 149, 149, -11, -11, -11, -11, 154, 154, -8, -8, -12, -12, -12, 93, 109};
+
+/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
+ Performed when YYTABLE does not specify something else to do. Zero
+ means the default is an error. */
+static const yytype_int8 yydefact[] = {0, 3, 4, 0, 0, 0, 0, 0, 0, 2, 28, 27, 25, 26,
+ 0, 1, 5, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 29, 0, 0, 9, 10, 11, 13, 12,
+ 17, 16, 15, 14, 19, 18, 21, 20, 24, 23, 22, 6, 8};
+
+/* YYPGOTO[NTERM-NUM]. */
+static const yytype_int8 yypgoto[] = {-12, -12, -3, -12, -12};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const yytype_int8 yydefgoto[] = {0, 8, 9, 35, 36};
+
+/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule whose
+ number is the opposite. If YYTABLE_NINF, syntax error. */
+static const yytype_int8 yytable[] = {
+ 10, 11, 12, 13, 14, 27, 28, 29, 30, 31, 32, 33, 31, 32, 33, 37, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 0, 53, 54, 1, 2, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 3, 4, 15, 0, 0, 0, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, 31, 32, 33, 0, 0, 0, 0, 34, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, 31, 32, 33, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 29, 30, 31, 32, 33};
+
+static const yytype_int8 yycheck[] = {
+ 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 20, 21, 22, 18, 19, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, 32, 33, -1, 35, 36, 3, 4, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 18, 19, 0, -1, -1, -1, 24, 25, 26, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, -1, -1, -1, -1, 27, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+ 22, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 8, 9, 10, 11, 12, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+ 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 18, 19, 20, 21, 22};
+
+/* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of
+ state STATE-NUM. */
+static const yytype_int8 yystos[] = {0, 3, 4, 18, 19, 24, 25, 26, 29, 30, 30, 30, 30, 30,
+ 30, 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 27, 31, 32, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30};
+
+/* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */
+static const yytype_int8 yyr1[] = {0, 28, 29, 30, 30, 31, 30, 32, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30};
+
+/* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */
+static const yytype_int8 yyr2[] = {0, 2, 1, 1, 1, 0, 4, 0, 4, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 3};
+
+enum
+{
+ YYENOMEM = -2
+};
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = PPEMPTY)
+
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrorlab
+#define YYNOMEM goto yyexhaustedlab
+
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+ do \
+ if (yychar == PPEMPTY) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ YYPOPSTACK(yylen); \
+ yystate = *yyssp; \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror(context, YY_("syntax error: cannot back up")); \
+ YYERROR; \
+ } \
+ while (0)
+
+/* Backward compatibility with an undocumented macro.
+ Use PPerror or PPUNDEF. */
+#define YYERRCODE PPUNDEF
+
+/* Enable debugging if requested. */
+#if PPDEBUG
+
+# ifndef YYFPRINTF
+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+ do \
+ { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+ } while (0)
+
+# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \
+ do \
+ { \
+ if (yydebug) \
+ { \
+ YYFPRINTF(stderr, "%s ", Title); \
+ yy_symbol_print(stderr, Kind, Value, context); \
+ YYFPRINTF(stderr, "\n"); \
+ } \
+ } while (0)
+
+/*-----------------------------------.
+| Print this symbol's value on YYO. |
+`-----------------------------------*/
+
+static void yy_symbol_value_print(FILE *yyo,
+ yysymbol_kind_t yykind,
+ YYSTYPE const *const yyvaluep,
+ Context *context)
+{
+ FILE *yyoutput = yyo;
+ YY_USE(yyoutput);
+ YY_USE(context);
+ if (!yyvaluep)
+ return;
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ YY_USE(yykind);
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+}
+
+/*---------------------------.
+| Print this symbol on YYO. |
+`---------------------------*/
+
+static void yy_symbol_print(FILE *yyo,
+ yysymbol_kind_t yykind,
+ YYSTYPE const *const yyvaluep,
+ Context *context)
+{
+ YYFPRINTF(yyo, "%s %s (", yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name(yykind));
+
+ yy_symbol_value_print(yyo, yykind, yyvaluep, context);
+ YYFPRINTF(yyo, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included). |
+`------------------------------------------------------------------*/
+
+static void yy_stack_print(yy_state_t *yybottom, yy_state_t *yytop)
+{
+ YYFPRINTF(stderr, "Stack now");
+ for (; yybottom <= yytop; yybottom++)
+ {
+ int yybot = *yybottom;
+ YYFPRINTF(stderr, " %d", yybot);
+ }
+ YYFPRINTF(stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top) \
+ do \
+ { \
+ if (yydebug) \
+ yy_stack_print((Bottom), (Top)); \
+ } while (0)
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced. |
+`------------------------------------------------*/
+
+static void yy_reduce_print(yy_state_t *yyssp, YYSTYPE *yyvsp, int yyrule, Context *context)
+{
+ int yylno = yyrline[yyrule];
+ int yynrhs = yyr2[yyrule];
+ int yyi;
+ YYFPRINTF(stderr, "Reducing stack by rule %d (line %d):\n", yyrule - 1, yylno);
+ /* The symbols being reduced. */
+ for (yyi = 0; yyi < yynrhs; yyi++)
+ {
+ YYFPRINTF(stderr, " $%d = ", yyi + 1);
+ yy_symbol_print(stderr, YY_ACCESSING_SYMBOL(+yyssp[yyi + 1 - yynrhs]),
+ &yyvsp[(yyi + 1) - (yynrhs)], context);
+ YYFPRINTF(stderr, "\n");
+ }
+}
+
+# define YY_REDUCE_PRINT(Rule) \
+ do \
+ { \
+ if (yydebug) \
+ yy_reduce_print(yyssp, yyvsp, Rule, context); \
+ } while (0)
+
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !PPDEBUG */
+# define YYDPRINTF(Args) ((void)0)
+# define YY_SYMBOL_PRINT(Title, Kind, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !PPDEBUG */
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+static void yydestruct(const char *yymsg,
+ yysymbol_kind_t yykind,
+ YYSTYPE *yyvaluep,
+ Context *context)
+{
+ YY_USE(yyvaluep);
+ YY_USE(context);
+ if (!yymsg)
+ yymsg = "Deleting";
+ YY_SYMBOL_PRINT(yymsg, yykind, yyvaluep, yylocationp);
+
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ YY_USE(yykind);
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+}
+
+/*----------.
+| yyparse. |
+`----------*/
+
+int yyparse(Context *context)
+{
+ /* Lookahead token kind. */
+ int yychar;
+
+ /* The semantic value of the lookahead symbol. */
+ /* Default value used for initialization, for pacifying older GCCs
+ or non-GCC compilers. */
+ YY_INITIAL_VALUE(static YYSTYPE yyval_default;)
+ YYSTYPE yylval YY_INITIAL_VALUE(= yyval_default);
+
+ /* Number of syntax errors so far. */
+ int yynerrs = 0;
+
+ yy_state_fast_t yystate = 0;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus = 0;
+
+ /* Refer to the stacks through separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* Their size. */
+ YYPTRDIFF_T yystacksize = YYINITDEPTH;
+
+ /* The state stack: array, bottom, top. */
+ yy_state_t yyssa[YYINITDEPTH];
+ yy_state_t *yyss = yyssa;
+ yy_state_t *yyssp = yyss;
+
+ /* The semantic value stack: array, bottom, top. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs = yyvsa;
+ YYSTYPE *yyvsp = yyvs;
+
+ int yyn;
+ /* The return value of yyparse. */
+ int yyresult;
+ /* Lookahead symbol kind. */
+ yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY;
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+
+#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
+
+ /* The number of symbols on the RHS of the reduced rule.
+ Keep to zero when no symbol should be popped. */
+ int yylen = 0;
+
+ YYDPRINTF((stderr, "Starting parse\n"));
+
+ yychar = PPEMPTY; /* Cause a token to be read. */
+
+ goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. So pushing a state here evens the stacks. */
+ yyssp++;
+
+/*--------------------------------------------------------------------.
+| yysetstate -- set current state (the top of the stack) to yystate. |
+`--------------------------------------------------------------------*/
+yysetstate:
+ YYDPRINTF((stderr, "Entering state %d\n", yystate));
+ YY_ASSERT(0 <= yystate && yystate < YYNSTATES);
+ YY_IGNORE_USELESS_CAST_BEGIN
+ *yyssp = YY_CAST(yy_state_t, yystate);
+ YY_IGNORE_USELESS_CAST_END
+ YY_STACK_PRINT(yyss, yyssp);
+
+ if (yyss + yystacksize - 1 <= yyssp)
+#if !defined yyoverflow && !defined YYSTACK_RELOCATE
+ YYNOMEM;
+#else
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYPTRDIFF_T yysize = yyssp - yyss + 1;
+
+# if defined yyoverflow
+ {
+ /* Give user a chance to reallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ yy_state_t *yyss1 = yyss;
+ YYSTYPE *yyvs1 = yyvs;
+
+ /* Each stack pointer address is followed by the size of the
+ data in use in that stack, in bytes. This used to be a
+ conditional around just the two extra args, but that might
+ be undefined if yyoverflow is a macro. */
+ yyoverflow(YY_("memory exhausted"), &yyss1, yysize * YYSIZEOF(*yyssp), &yyvs1,
+ yysize * YYSIZEOF(*yyvsp), &yystacksize);
+ yyss = yyss1;
+ yyvs = yyvs1;
+ }
+# else /* defined YYSTACK_RELOCATE */
+ /* Extend the stack our own way. */
+ if (YYMAXDEPTH <= yystacksize)
+ YYNOMEM;
+ yystacksize *= 2;
+ if (YYMAXDEPTH < yystacksize)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ yy_state_t *yyss1 = yyss;
+ union yyalloc *yyptr = YY_CAST(
+ union yyalloc *, YYSTACK_ALLOC(YY_CAST(YYSIZE_T, YYSTACK_BYTES(yystacksize))));
+ if (!yyptr)
+ YYNOMEM;
+ YYSTACK_RELOCATE(yyss_alloc, yyss);
+ YYSTACK_RELOCATE(yyvs_alloc, yyvs);
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE(yyss1);
+ }
+# endif
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;
+
+ YY_IGNORE_USELESS_CAST_BEGIN
+ YYDPRINTF((stderr, "Stack size increased to %ld\n", YY_CAST(long, yystacksize)));
+ YY_IGNORE_USELESS_CAST_END
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ YYABORT;
+ }
+#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
+
+ if (yystate == YYFINAL)
+ YYACCEPT;
+
+ goto yybackup;
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+ /* Do appropriate processing given the current state. Read a
+ lookahead token if we need one and don't already have one. */
+
+ /* First try to decide what to do without reference to lookahead token. */
+ yyn = yypact[yystate];
+ if (yypact_value_is_default(yyn))
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* YYCHAR is either empty, or end-of-input, or a valid lookahead. */
+ if (yychar == PPEMPTY)
+ {
+ YYDPRINTF((stderr, "Reading a token\n"));
+ yychar = yylex(&yylval, context);
+ }
+
+ if (yychar <= PPEOF)
+ {
+ yychar = PPEOF;
+ yytoken = YYSYMBOL_YYEOF;
+ YYDPRINTF((stderr, "Now at end of input.\n"));
+ }
+ else if (yychar == PPerror)
+ {
+ /* The scanner already issued an error message, process directly
+ to error recovery. But do not keep the error token as
+ lookahead, it is too special and may lead us to an endless
+ loop in error recovery. */
+ yychar = PPUNDEF;
+ yytoken = YYSYMBOL_YYerror;
+ goto yyerrlab1;
+ }
+ else
+ {
+ yytoken = YYTRANSLATE(yychar);
+ YY_SYMBOL_PRINT("Next token is", yytoken, &yylval, &yylloc);
+ }
+
+ /* If the proper action on seeing token YYTOKEN is to reduce or to
+ detect an error, take that action. */
+ yyn += yytoken;
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+ goto yydefault;
+ yyn = yytable[yyn];
+ if (yyn <= 0)
+ {
+ if (yytable_value_is_error(yyn))
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ /* Shift the lookahead token. */
+ YY_SYMBOL_PRINT("Shifting", yytoken, &yylval, &yylloc);
+ yystate = yyn;
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ *++yyvsp = yylval;
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+
+ /* Discard the shifted token. */
+ yychar = PPEMPTY;
+ goto yynewstate;
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state. |
+`-----------------------------------------------------------*/
+yydefault:
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+/*-----------------------------.
+| yyreduce -- do a reduction. |
+`-----------------------------*/
+yyreduce:
+ /* yyn is the number of a rule to reduce with. */
+ yylen = yyr2[yyn];
+
+ /* If YYLEN is nonzero, implement the default value of the action:
+ '$$ = $1'.
+
+ Otherwise, the following line sets YYVAL to garbage.
+ This behavior is undocumented and Bison
+ users should not rely upon it. Assigning to YYVAL
+ unconditionally makes the parser a bit smaller, and it avoids a
+ GCC warning that YYVAL may be used uninitialized. */
+ yyval = yyvsp[1 - yylen];
+
+ YY_REDUCE_PRINT(yyn);
+ switch (yyn)
+ {
+ case 2: /* input: expression */
+ {
+ *(context->result) = static_cast<int>(yyvsp[0]);
+ YYACCEPT;
+ }
+ break;
+
+ case 4: /* expression: TOK_IDENTIFIER */
+ {
+ if (!context->isIgnoringErrors())
+ {
+ // This rule should be applied right after the token is lexed, so we can
+ // refer to context->token in the error message.
+ context->diagnostics->report(context->errorSettings.unexpectedIdentifier,
+ context->token->location, context->token->text);
+ *(context->valid) = false;
+ }
+ yyval = yyvsp[0];
+ }
+ break;
+
+ case 5: /* $@1: %empty */
+ {
+ if (yyvsp[-1] != 0)
+ {
+ // Ignore errors in the short-circuited part of the expression.
+ // ESSL3.00 section 3.4:
+ // If an operand is not evaluated, the presence of undefined identifiers
+ // in the operand will not cause an error.
+ // Unevaluated division by zero should not cause an error either.
+ context->startIgnoreErrors();
+ }
+ }
+ break;
+
+ case 6: /* expression: expression TOK_OP_OR $@1 expression */
+ {
+ if (yyvsp[-3] != 0)
+ {
+ context->endIgnoreErrors();
+ yyval = static_cast<YYSTYPE>(1);
+ }
+ else
+ {
+ yyval = yyvsp[-3] || yyvsp[0];
+ }
+ }
+ break;
+
+ case 7: /* $@2: %empty */
+ {
+ if (yyvsp[-1] == 0)
+ {
+ // Ignore errors in the short-circuited part of the expression.
+ // ESSL3.00 section 3.4:
+ // If an operand is not evaluated, the presence of undefined identifiers
+ // in the operand will not cause an error.
+ // Unevaluated division by zero should not cause an error either.
+ context->startIgnoreErrors();
+ }
+ }
+ break;
+
+ case 8: /* expression: expression TOK_OP_AND $@2 expression */
+ {
+ if (yyvsp[-3] == 0)
+ {
+ context->endIgnoreErrors();
+ yyval = static_cast<YYSTYPE>(0);
+ }
+ else
+ {
+ yyval = yyvsp[-3] && yyvsp[0];
+ }
+ }
+ break;
+
+ case 9: /* expression: expression '|' expression */
+ {
+ yyval = yyvsp[-2] | yyvsp[0];
+ }
+ break;
+
+ case 10: /* expression: expression '^' expression */
+ {
+ yyval = yyvsp[-2] ^ yyvsp[0];
+ }
+ break;
+
+ case 11: /* expression: expression '&' expression */
+ {
+ yyval = yyvsp[-2] & yyvsp[0];
+ }
+ break;
+
+ case 12: /* expression: expression TOK_OP_NE expression */
+ {
+ yyval = yyvsp[-2] != yyvsp[0];
+ }
+ break;
+
+ case 13: /* expression: expression TOK_OP_EQ expression */
+ {
+ yyval = yyvsp[-2] == yyvsp[0];
+ }
+ break;
+
+ case 14: /* expression: expression TOK_OP_GE expression */
+ {
+ yyval = yyvsp[-2] >= yyvsp[0];
+ }
+ break;
+
+ case 15: /* expression: expression TOK_OP_LE expression */
+ {
+ yyval = yyvsp[-2] <= yyvsp[0];
+ }
+ break;
+
+ case 16: /* expression: expression '>' expression */
+ {
+ yyval = yyvsp[-2] > yyvsp[0];
+ }
+ break;
+
+ case 17: /* expression: expression '<' expression */
+ {
+ yyval = yyvsp[-2] < yyvsp[0];
+ }
+ break;
+
+ case 18: /* expression: expression TOK_OP_RIGHT expression */
+ {
+ 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(angle::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;
+
+ case 19: /* expression: expression TOK_OP_LEFT expression */
+ {
+ 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(angle::pp::Diagnostics::PP_UNDEFINED_SHIFT,
+ context->token->location, text.c_str());
+ *(context->valid) = false;
+ }
+ yyval = static_cast<YYSTYPE>(0);
+ }
+ else
+ {
+ // Logical shift left. Casting to unsigned is needed to ensure there's no signed
+ // integer overflow, which some tools treat as an error.
+ yyval = static_cast<YYSTYPE>(static_cast<UNSIGNED_TYPE>(yyvsp[-2]) << yyvsp[0]);
+ }
+ }
+ break;
+
+ case 20: /* expression: expression '-' expression */
+ {
+ yyval = gl::WrappingDiff<YYSTYPE>(yyvsp[-2], yyvsp[0]);
+ }
+ break;
+
+ case 21: /* expression: expression '+' expression */
+ {
+ yyval = gl::WrappingSum<YYSTYPE>(yyvsp[-2], yyvsp[0]);
+ }
+ break;
+
+ case 22: /* expression: expression '%' expression */
+ {
+ if (yyvsp[0] == 0)
+ {
+ if (!context->isIgnoringErrors())
+ {
+ std::ostringstream stream;
+ stream << yyvsp[-2] << " % " << yyvsp[0];
+ std::string text = stream.str();
+ context->diagnostics->report(angle::pp::Diagnostics::PP_DIVISION_BY_ZERO,
+ context->token->location, text.c_str());
+ *(context->valid) = false;
+ }
+ 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 has undefined results.
+ yyval = 0;
+ }
+ else
+ {
+ yyval = yyvsp[-2] % yyvsp[0];
+ }
+ }
+ break;
+
+ case 23: /* expression: expression '/' expression */
+ {
+ if (yyvsp[0] == 0)
+ {
+ if (!context->isIgnoringErrors())
+ {
+ std::ostringstream stream;
+ stream << yyvsp[-2] << " / " << yyvsp[0];
+ std::string text = stream.str();
+ context->diagnostics->report(angle::pp::Diagnostics::PP_DIVISION_BY_ZERO,
+ context->token->location, text.c_str());
+ *(context->valid) = false;
+ }
+ 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];
+ }
+ }
+ break;
+
+ case 24: /* expression: expression '*' expression */
+ {
+ yyval = gl::WrappingMul(yyvsp[-2], yyvsp[0]);
+ }
+ break;
+
+ case 25: /* expression: '!' expression */
+ {
+ yyval = !yyvsp[0];
+ }
+ break;
+
+ case 26: /* expression: '~' expression */
+ {
+ yyval = ~yyvsp[0];
+ }
+ break;
+
+ case 27: /* expression: '-' expression */
+ {
+ // 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;
+
+ case 28: /* expression: '+' expression */
+ {
+ yyval = +yyvsp[0];
+ }
+ break;
+
+ case 29: /* expression: '(' expression ')' */
+ {
+ yyval = yyvsp[-1];
+ }
+ break;
+
+ default:
+ break;
+ }
+ /* User semantic actions sometimes alter yychar, and that requires
+ that yytoken be updated with the new translation. We take the
+ approach of translating immediately before every use of yytoken.
+ One alternative is translating here after every semantic action,
+ but that translation would be missed if the semantic action invokes
+ YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
+ if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an
+ incorrect destructor might then be invoked immediately. In the
+ case of YYERROR or YYBACKUP, subsequent parser actions might lead
+ to an incorrect destructor call or verbose syntax error message
+ before the lookahead is translated. */
+ YY_SYMBOL_PRINT("-> $$ =", YY_CAST(yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc);
+
+ YYPOPSTACK(yylen);
+ yylen = 0;
+
+ *++yyvsp = yyval;
+
+ /* Now 'shift' the result of the reduction. Determine what state
+ that goes to, based on the state we popped back to and the rule
+ number reduced by. */
+ {
+ const int yylhs = yyr1[yyn] - YYNTOKENS;
+ const int yyi = yypgoto[yylhs] + *yyssp;
+ yystate =
+ (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp ? yytable[yyi] : yydefgoto[yylhs]);
+ }
+
+ goto yynewstate;
+
+/*--------------------------------------.
+| yyerrlab -- here on detecting error. |
+`--------------------------------------*/
+yyerrlab:
+ /* Make sure we have latest lookahead translation. See comments at
+ user semantic actions for why this is necessary. */
+ yytoken = yychar == PPEMPTY ? YYSYMBOL_YYEMPTY : YYTRANSLATE(yychar);
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+ yyerror(context, YY_("syntax error"));
+ }
+
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse lookahead token after an
+ error, discard it. */
+
+ if (yychar <= PPEOF)
+ {
+ /* Return failure if at end of input. */
+ if (yychar == PPEOF)
+ YYABORT;
+ }
+ else
+ {
+ yydestruct("Error: discarding", yytoken, &yylval, context);
+ yychar = PPEMPTY;
+ }
+ }
+
+ /* Else will try to reuse lookahead token after shifting the error
+ token. */
+ goto yyerrlab1;
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR. |
+`---------------------------------------------------*/
+yyerrorlab:
+ /* Pacify compilers when the user code never invokes YYERROR and the
+ label yyerrorlab therefore never appears in user code. */
+ if (0)
+ YYERROR;
+ ++yynerrs;
+
+ /* Do not reclaim the symbols of the rule whose action triggered
+ this YYERROR. */
+ YYPOPSTACK(yylen);
+ yylen = 0;
+ YY_STACK_PRINT(yyss, yyssp);
+ yystate = *yyssp;
+ goto yyerrlab1;
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR. |
+`-------------------------------------------------------------*/
+yyerrlab1:
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
+
+ /* Pop stack until we find a state that shifts the error token. */
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (!yypact_value_is_default(yyn))
+ {
+ yyn += YYSYMBOL_YYerror;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror)
+ {
+ yyn = yytable[yyn];
+ if (0 < yyn)
+ break;
+ }
+ }
+
+ /* Pop the current state because it cannot handle the error token. */
+ if (yyssp == yyss)
+ YYABORT;
+
+ yydestruct("Error: popping", YY_ACCESSING_SYMBOL(yystate), yyvsp, context);
+ YYPOPSTACK(1);
+ yystate = *yyssp;
+ YY_STACK_PRINT(yyss, yyssp);
+ }
+
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ *++yyvsp = yylval;
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+
+ /* Shift the error token. */
+ YY_SYMBOL_PRINT("Shifting", YY_ACCESSING_SYMBOL(yyn), yyvsp, yylsp);
+
+ yystate = yyn;
+ goto yynewstate;
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturnlab;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yyresult = 1;
+ goto yyreturnlab;
+
+/*-----------------------------------------------------------.
+| yyexhaustedlab -- YYNOMEM (memory exhaustion) comes here. |
+`-----------------------------------------------------------*/
+yyexhaustedlab:
+ yyerror(context, YY_("memory exhausted"));
+ yyresult = 2;
+ goto yyreturnlab;
+
+/*----------------------------------------------------------.
+| yyreturnlab -- parsing is finished, clean up and return. |
+`----------------------------------------------------------*/
+yyreturnlab:
+ if (yychar != PPEMPTY)
+ {
+ /* Make sure we have latest lookahead translation. See comments at
+ user semantic actions for why this is necessary. */
+ yytoken = YYTRANSLATE(yychar);
+ yydestruct("Cleanup: discarding lookahead", yytoken, &yylval, context);
+ }
+ /* Do not reclaim the symbols of the rule whose action triggered
+ this YYABORT or YYACCEPT. */
+ YYPOPSTACK(yylen);
+ YY_STACK_PRINT(yyss, yyssp);
+ while (yyssp != yyss)
+ {
+ yydestruct("Cleanup: popping", YY_ACCESSING_SYMBOL(+*yyssp), yyvsp, context);
+ YYPOPSTACK(1);
+ }
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE(yyss);
+#endif
+
+ return yyresult;
+}
+
+int yylex(YYSTYPE *lvalp, Context *context)
+{
+ angle::pp::Token *token = context->token;
+ if (!context->parsePresetToken)
+ {
+ context->lexer->lex(token);
+ }
+ context->parsePresetToken = false;
+
+ int type = 0;
+
+ switch (token->type)
+ {
+ case angle::pp::Token::CONST_INT:
+ {
+ unsigned int val = 0;
+ int testVal = 0;
+ if (!token->uValue(&val) ||
+ (!token->iValue(&testVal) &&
+ context->errorSettings.integerLiteralsMustFit32BitSignedRange))
+ {
+ context->diagnostics->report(angle::pp::Diagnostics::PP_INTEGER_OVERFLOW,
+ token->location, token->text);
+ *(context->valid) = false;
+ }
+ *lvalp = static_cast<YYSTYPE>(val);
+ type = TOK_CONST_INT;
+ break;
+ }
+ case angle::pp::Token::IDENTIFIER:
+ *lvalp = static_cast<YYSTYPE>(-1);
+ type = TOK_IDENTIFIER;
+ break;
+ case angle::pp::Token::OP_OR:
+ type = TOK_OP_OR;
+ break;
+ case angle::pp::Token::OP_AND:
+ type = TOK_OP_AND;
+ break;
+ case angle::pp::Token::OP_NE:
+ type = TOK_OP_NE;
+ break;
+ case angle::pp::Token::OP_EQ:
+ type = TOK_OP_EQ;
+ break;
+ case angle::pp::Token::OP_GE:
+ type = TOK_OP_GE;
+ break;
+ case angle::pp::Token::OP_LE:
+ type = TOK_OP_LE;
+ break;
+ case angle::pp::Token::OP_RIGHT:
+ type = TOK_OP_RIGHT;
+ break;
+ case angle::pp::Token::OP_LEFT:
+ type = TOK_OP_LEFT;
+ break;
+ case '|':
+ case '^':
+ case '&':
+ case '>':
+ case '<':
+ case '-':
+ case '+':
+ case '%':
+ case '/':
+ case '*':
+ case '!':
+ case '~':
+ case '(':
+ case ')':
+ type = token->type;
+ break;
+
+ default:
+ break;
+ }
+
+ return type;
+}
+
+void yyerror(Context *context, const char *reason)
+{
+ context->diagnostics->report(angle::pp::Diagnostics::PP_INVALID_EXPRESSION,
+ context->token->location, reason);
+}
+
+namespace angle
+{
+
+namespace pp
+{
+
+ExpressionParser::ExpressionParser(Lexer *lexer, Diagnostics *diagnostics)
+ : mLexer(lexer), mDiagnostics(diagnostics)
+{}
+
+bool ExpressionParser::parse(Token *token,
+ int *result,
+ bool parsePresetToken,
+ const ErrorSettings &errorSettings,
+ bool *valid)
+{
+ Context context;
+ context.diagnostics = mDiagnostics;
+ context.lexer = mLexer;
+ context.token = token;
+ context.result = result;
+ context.ignoreErrors = 0;
+ context.parsePresetToken = parsePresetToken;
+ context.errorSettings = errorSettings;
+ context.valid = valid;
+ int ret = yyparse(&context);
+ switch (ret)
+ {
+ case 0:
+ case 1:
+ break;
+
+ case 2:
+ mDiagnostics->report(Diagnostics::PP_OUT_OF_MEMORY, token->location, "");
+ break;
+
+ default:
+ assert(false);
+ mDiagnostics->report(Diagnostics::PP_INTERNAL_ERROR, token->location, "");
+ break;
+ }
+
+ return ret == 0;
+}
+
+} // namespace pp
+
+} // namespace angle
diff --git a/gfx/angle/checkout/src/compiler/translator/ASTMetadataHLSL.cpp b/gfx/angle/checkout/src/compiler/translator/ASTMetadataHLSL.cpp
new file mode 100644
index 0000000000..69b50c5d7d
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ASTMetadataHLSL.cpp
@@ -0,0 +1,445 @@
+//
+// Copyright 2002 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.
+//
+
+// Analysis of the AST needed for HLSL generation
+
+#include "compiler/translator/ASTMetadataHLSL.h"
+
+#include "compiler/translator/CallDAG.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+// Class used to traverse the AST of a function definition, checking if the
+// function uses a gradient, and writing the set of control flow using gradients.
+// It assumes that the analysis has already been made for the function's
+// callees.
+class PullGradient : public TIntermTraverser
+{
+ public:
+ PullGradient(MetadataList *metadataList, size_t index, const CallDAG &dag)
+ : TIntermTraverser(true, false, true),
+ mMetadataList(metadataList),
+ mMetadata(&(*metadataList)[index]),
+ mIndex(index),
+ mDag(dag)
+ {
+ ASSERT(index < metadataList->size());
+
+ // ESSL 100 builtin gradient functions
+ mGradientBuiltinFunctions.insert(ImmutableString("texture2D"));
+ mGradientBuiltinFunctions.insert(ImmutableString("texture2DProj"));
+ mGradientBuiltinFunctions.insert(ImmutableString("textureCube"));
+
+ // ESSL 300 builtin gradient functions
+ mGradientBuiltinFunctions.insert(ImmutableString("dFdx"));
+ mGradientBuiltinFunctions.insert(ImmutableString("dFdy"));
+ mGradientBuiltinFunctions.insert(ImmutableString("fwidth"));
+ mGradientBuiltinFunctions.insert(ImmutableString("texture"));
+ mGradientBuiltinFunctions.insert(ImmutableString("textureProj"));
+ mGradientBuiltinFunctions.insert(ImmutableString("textureOffset"));
+ mGradientBuiltinFunctions.insert(ImmutableString("textureProjOffset"));
+
+ // ESSL 310 doesn't add builtin gradient functions
+ }
+
+ void traverse(TIntermFunctionDefinition *node)
+ {
+ node->traverse(this);
+ ASSERT(mParents.empty());
+ }
+
+ // Called when a gradient operation or a call to a function using a gradient is found.
+ void onGradient()
+ {
+ mMetadata->mUsesGradient = true;
+ // Mark the latest control flow as using a gradient.
+ if (!mParents.empty())
+ {
+ mMetadata->mControlFlowsContainingGradient.insert(mParents.back());
+ }
+ }
+
+ void visitControlFlow(Visit visit, TIntermNode *node)
+ {
+ if (visit == PreVisit)
+ {
+ mParents.push_back(node);
+ }
+ else if (visit == PostVisit)
+ {
+ ASSERT(mParents.back() == node);
+ mParents.pop_back();
+ // A control flow's using a gradient means its parents are too.
+ if (mMetadata->mControlFlowsContainingGradient.count(node) > 0 && !mParents.empty())
+ {
+ mMetadata->mControlFlowsContainingGradient.insert(mParents.back());
+ }
+ }
+ }
+
+ bool visitLoop(Visit visit, TIntermLoop *loop) override
+ {
+ visitControlFlow(visit, loop);
+ return true;
+ }
+
+ bool visitIfElse(Visit visit, TIntermIfElse *ifElse) override
+ {
+ visitControlFlow(visit, ifElse);
+ return true;
+ }
+
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override
+ {
+ if (visit == PreVisit)
+ {
+ if (node->getOp() == EOpCallFunctionInAST)
+ {
+ size_t calleeIndex = mDag.findIndex(node->getFunction()->uniqueId());
+ ASSERT(calleeIndex != CallDAG::InvalidIndex && calleeIndex < mIndex);
+
+ if ((*mMetadataList)[calleeIndex].mUsesGradient)
+ {
+ onGradient();
+ }
+ }
+ else if (BuiltInGroup::IsBuiltIn(node->getOp()) && !BuiltInGroup::IsMath(node->getOp()))
+ {
+ if (mGradientBuiltinFunctions.find(node->getFunction()->name()) !=
+ mGradientBuiltinFunctions.end())
+ {
+ onGradient();
+ }
+ }
+ }
+
+ return true;
+ }
+
+ private:
+ MetadataList *mMetadataList;
+ ASTMetadataHLSL *mMetadata;
+ size_t mIndex;
+ const CallDAG &mDag;
+
+ // Contains a stack of the control flow nodes that are parents of the node being
+ // currently visited. It is used to mark control flows using a gradient.
+ std::vector<TIntermNode *> mParents;
+
+ // A list of builtin functions that use gradients
+ std::set<ImmutableString> mGradientBuiltinFunctions;
+};
+
+// Traverses the AST of a function definition to compute the the discontinuous loops
+// and the if statements containing gradient loops. It assumes that the gradient loops
+// (loops that contain a gradient) have already been computed and that it has already
+// traversed the current function's callees.
+class PullComputeDiscontinuousAndGradientLoops : public TIntermTraverser
+{
+ public:
+ PullComputeDiscontinuousAndGradientLoops(MetadataList *metadataList,
+ size_t index,
+ const CallDAG &dag)
+ : TIntermTraverser(true, false, true),
+ mMetadataList(metadataList),
+ mMetadata(&(*metadataList)[index]),
+ mIndex(index),
+ mDag(dag)
+ {}
+
+ void traverse(TIntermFunctionDefinition *node)
+ {
+ node->traverse(this);
+ ASSERT(mLoopsAndSwitches.empty());
+ ASSERT(mIfs.empty());
+ }
+
+ // Called when traversing a gradient loop or a call to a function with a
+ // gradient loop in its call graph.
+ void onGradientLoop()
+ {
+ mMetadata->mHasGradientLoopInCallGraph = true;
+ // Mark the latest if as using a discontinuous loop.
+ if (!mIfs.empty())
+ {
+ mMetadata->mIfsContainingGradientLoop.insert(mIfs.back());
+ }
+ }
+
+ bool visitLoop(Visit visit, TIntermLoop *loop) override
+ {
+ if (visit == PreVisit)
+ {
+ mLoopsAndSwitches.push_back(loop);
+
+ if (mMetadata->hasGradientInCallGraph(loop))
+ {
+ onGradientLoop();
+ }
+ }
+ else if (visit == PostVisit)
+ {
+ ASSERT(mLoopsAndSwitches.back() == loop);
+ mLoopsAndSwitches.pop_back();
+ }
+
+ return true;
+ }
+
+ bool visitIfElse(Visit visit, TIntermIfElse *node) override
+ {
+ if (visit == PreVisit)
+ {
+ mIfs.push_back(node);
+ }
+ else if (visit == PostVisit)
+ {
+ ASSERT(mIfs.back() == node);
+ mIfs.pop_back();
+ // An if using a discontinuous loop means its parents ifs are also discontinuous.
+ if (mMetadata->mIfsContainingGradientLoop.count(node) > 0 && !mIfs.empty())
+ {
+ mMetadata->mIfsContainingGradientLoop.insert(mIfs.back());
+ }
+ }
+
+ return true;
+ }
+
+ bool visitBranch(Visit visit, TIntermBranch *node) override
+ {
+ if (visit == PreVisit)
+ {
+ switch (node->getFlowOp())
+ {
+ case EOpBreak:
+ {
+ ASSERT(!mLoopsAndSwitches.empty());
+ TIntermLoop *loop = mLoopsAndSwitches.back()->getAsLoopNode();
+ if (loop != nullptr)
+ {
+ mMetadata->mDiscontinuousLoops.insert(loop);
+ }
+ }
+ break;
+ case EOpContinue:
+ {
+ ASSERT(!mLoopsAndSwitches.empty());
+ TIntermLoop *loop = nullptr;
+ size_t i = mLoopsAndSwitches.size();
+ while (loop == nullptr && i > 0)
+ {
+ --i;
+ loop = mLoopsAndSwitches.at(i)->getAsLoopNode();
+ }
+ ASSERT(loop != nullptr);
+ mMetadata->mDiscontinuousLoops.insert(loop);
+ }
+ break;
+ case EOpKill:
+ case EOpReturn:
+ // A return or discard jumps out of all the enclosing loops
+ if (!mLoopsAndSwitches.empty())
+ {
+ for (TIntermNode *intermNode : mLoopsAndSwitches)
+ {
+ TIntermLoop *loop = intermNode->getAsLoopNode();
+ if (loop)
+ {
+ mMetadata->mDiscontinuousLoops.insert(loop);
+ }
+ }
+ }
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ return true;
+ }
+
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override
+ {
+ if (visit == PreVisit && node->getOp() == EOpCallFunctionInAST)
+ {
+ size_t calleeIndex = mDag.findIndex(node->getFunction()->uniqueId());
+ ASSERT(calleeIndex != CallDAG::InvalidIndex && calleeIndex < mIndex);
+
+ if ((*mMetadataList)[calleeIndex].mHasGradientLoopInCallGraph)
+ {
+ onGradientLoop();
+ }
+ }
+
+ return true;
+ }
+
+ bool visitSwitch(Visit visit, TIntermSwitch *node) override
+ {
+ if (visit == PreVisit)
+ {
+ mLoopsAndSwitches.push_back(node);
+ }
+ else if (visit == PostVisit)
+ {
+ ASSERT(mLoopsAndSwitches.back() == node);
+ mLoopsAndSwitches.pop_back();
+ }
+ return true;
+ }
+
+ private:
+ MetadataList *mMetadataList;
+ ASTMetadataHLSL *mMetadata;
+ size_t mIndex;
+ const CallDAG &mDag;
+
+ std::vector<TIntermNode *> mLoopsAndSwitches;
+ std::vector<TIntermIfElse *> mIfs;
+};
+
+// Tags all the functions called in a discontinuous loop
+class PushDiscontinuousLoops : public TIntermTraverser
+{
+ public:
+ PushDiscontinuousLoops(MetadataList *metadataList, size_t index, const CallDAG &dag)
+ : TIntermTraverser(true, true, true),
+ mMetadataList(metadataList),
+ mMetadata(&(*metadataList)[index]),
+ mIndex(index),
+ mDag(dag),
+ mNestedDiscont(mMetadata->mCalledInDiscontinuousLoop ? 1 : 0)
+ {}
+
+ void traverse(TIntermFunctionDefinition *node)
+ {
+ node->traverse(this);
+ ASSERT(mNestedDiscont == (mMetadata->mCalledInDiscontinuousLoop ? 1 : 0));
+ }
+
+ bool visitLoop(Visit visit, TIntermLoop *loop) override
+ {
+ bool isDiscontinuous = mMetadata->mDiscontinuousLoops.count(loop) > 0;
+
+ if (visit == PreVisit && isDiscontinuous)
+ {
+ mNestedDiscont++;
+ }
+ else if (visit == PostVisit && isDiscontinuous)
+ {
+ mNestedDiscont--;
+ }
+
+ return true;
+ }
+
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override
+ {
+ switch (node->getOp())
+ {
+ case EOpCallFunctionInAST:
+ if (visit == PreVisit && mNestedDiscont > 0)
+ {
+ size_t calleeIndex = mDag.findIndex(node->getFunction()->uniqueId());
+ ASSERT(calleeIndex != CallDAG::InvalidIndex && calleeIndex < mIndex);
+
+ (*mMetadataList)[calleeIndex].mCalledInDiscontinuousLoop = true;
+ }
+ break;
+ default:
+ break;
+ }
+ return true;
+ }
+
+ private:
+ MetadataList *mMetadataList;
+ ASTMetadataHLSL *mMetadata;
+ size_t mIndex;
+ const CallDAG &mDag;
+
+ int mNestedDiscont;
+};
+} // namespace
+
+bool ASTMetadataHLSL::hasGradientInCallGraph(TIntermLoop *node)
+{
+ return mControlFlowsContainingGradient.count(node) > 0;
+}
+
+bool ASTMetadataHLSL::hasGradientLoop(TIntermIfElse *node)
+{
+ return mIfsContainingGradientLoop.count(node) > 0;
+}
+
+MetadataList CreateASTMetadataHLSL(TIntermNode *root, const CallDAG &callDag)
+{
+ MetadataList metadataList(callDag.size());
+
+ // Compute all the information related to when gradient operations are used.
+ // We want to know for each function and control flow operation if they have
+ // a gradient operation in their call graph (shortened to "using a gradient"
+ // in the rest of the file).
+ //
+ // This computation is logically split in three steps:
+ // 1 - For each function compute if it uses a gradient in its body, ignoring
+ // calls to other user-defined functions.
+ // 2 - For each function determine if it uses a gradient in its call graph,
+ // using the result of step 1 and the CallDAG to know its callees.
+ // 3 - For each control flow statement of each function, check if it uses a
+ // gradient in the function's body, or if it calls a user-defined function that
+ // uses a gradient.
+ //
+ // We take advantage of the call graph being a DAG and instead compute 1, 2 and 3
+ // for leaves first, then going down the tree. This is correct because 1 doesn't
+ // depend on other functions, and 2 and 3 depend only on callees.
+ for (size_t i = 0; i < callDag.size(); i++)
+ {
+ PullGradient pull(&metadataList, i, callDag);
+ pull.traverse(callDag.getRecordFromIndex(i).node);
+ }
+
+ // Compute which loops are discontinuous and which function are called in
+ // these loops. The same way computing gradient usage is a "pull" process,
+ // computing "bing used in a discont. loop" is a push process. However we also
+ // need to know what ifs have a discontinuous loop inside so we do the same type
+ // of callgraph analysis as for the gradient.
+
+ // First compute which loops are discontinuous (no specific order) and pull
+ // the ifs and functions using a gradient loop.
+ for (size_t i = 0; i < callDag.size(); i++)
+ {
+ PullComputeDiscontinuousAndGradientLoops pull(&metadataList, i, callDag);
+ pull.traverse(callDag.getRecordFromIndex(i).node);
+ }
+
+ // Then push the information to callees, either from the a local discontinuous
+ // loop or from the caller being called in a discontinuous loop already
+ for (size_t i = callDag.size(); i-- > 0;)
+ {
+ PushDiscontinuousLoops push(&metadataList, i, callDag);
+ push.traverse(callDag.getRecordFromIndex(i).node);
+ }
+
+ // We create "Lod0" version of functions with the gradient operations replaced
+ // by non-gradient operations so that the D3D compiler is happier with discont
+ // loops.
+ for (auto &metadata : metadataList)
+ {
+ metadata.mNeedsLod0 = metadata.mCalledInDiscontinuousLoop && metadata.mUsesGradient;
+ }
+
+ return metadataList;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/ASTMetadataHLSL.h b/gfx/angle/checkout/src/compiler/translator/ASTMetadataHLSL.h
new file mode 100644
index 0000000000..8278f9fafe
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ASTMetadataHLSL.h
@@ -0,0 +1,62 @@
+//
+// Copyright 2002 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.
+//
+
+// Defines analyses of the AST needed for HLSL generation
+
+#ifndef COMPILER_TRANSLATOR_ASTMETADATAHLSL_H_
+#define COMPILER_TRANSLATOR_ASTMETADATAHLSL_H_
+
+#include <set>
+#include <vector>
+
+namespace sh
+{
+
+class CallDAG;
+class TIntermNode;
+class TIntermIfElse;
+class TIntermLoop;
+
+struct ASTMetadataHLSL
+{
+ ASTMetadataHLSL()
+ : mUsesGradient(false),
+ mCalledInDiscontinuousLoop(false),
+ mHasGradientLoopInCallGraph(false),
+ mNeedsLod0(false)
+ {}
+
+ // 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(TIntermIfElse *node);
+
+ // Does the function use a gradient.
+ bool mUsesGradient;
+
+ // Even if usesGradient is true, some control flow might not use a gradient
+ // so we store the set of all gradient-using control flows.
+ std::set<TIntermNode *> mControlFlowsContainingGradient;
+
+ // Remember information about the discontinuous loops and which functions
+ // are called in such loops.
+ bool mCalledInDiscontinuousLoop;
+ bool mHasGradientLoopInCallGraph;
+ std::set<TIntermLoop *> mDiscontinuousLoops;
+ std::set<TIntermIfElse *> mIfsContainingGradientLoop;
+
+ // Will we need to generate a Lod0 version of the function.
+ bool mNeedsLod0;
+};
+
+typedef std::vector<ASTMetadataHLSL> MetadataList;
+
+// Return the AST analysis result, in the order defined by the call DAG
+MetadataList CreateASTMetadataHLSL(TIntermNode *root, const CallDAG &callDag);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_ASTMETADATAHLSL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/AtomicCounterFunctionHLSL.cpp b/gfx/angle/checkout/src/compiler/translator/AtomicCounterFunctionHLSL.cpp
new file mode 100644
index 0000000000..b900bc4d81
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/AtomicCounterFunctionHLSL.cpp
@@ -0,0 +1,112 @@
+//
+// Copyright 2018 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.
+//
+// AtomicCounterFunctionHLSL: Class for writing implementation of atomic counter functions into HLSL
+// output.
+//
+
+#include "compiler/translator/AtomicCounterFunctionHLSL.h"
+
+#include "compiler/translator/Common.h"
+#include "compiler/translator/ImmutableStringBuilder.h"
+#include "compiler/translator/InfoSink.h"
+#include "compiler/translator/IntermNode.h"
+
+namespace sh
+{
+
+namespace
+{
+constexpr ImmutableString kAtomicCounter("atomicCounter");
+constexpr ImmutableString kAtomicCounterIncrement("atomicCounterIncrement");
+constexpr ImmutableString kAtomicCounterDecrement("atomicCounterDecrement");
+constexpr ImmutableString kAtomicCounterBaseName("_acbase_");
+} // namespace
+
+AtomicCounterFunctionHLSL::AtomicCounterFunctionHLSL(bool forceResolution)
+ : mForceResolution(forceResolution)
+{}
+
+ImmutableString AtomicCounterFunctionHLSL::useAtomicCounterFunction(const ImmutableString &name)
+{
+ // The largest string that will be create created is "_acbase_increment" or "_acbase_decrement"
+ ImmutableStringBuilder hlslFunctionNameSB(kAtomicCounterBaseName.length() +
+ strlen("increment"));
+ hlslFunctionNameSB << kAtomicCounterBaseName;
+
+ AtomicCounterFunction atomicMethod;
+ if (kAtomicCounter == name)
+ {
+ atomicMethod = AtomicCounterFunction::LOAD;
+ hlslFunctionNameSB << "load";
+ }
+ else if (kAtomicCounterIncrement == name)
+ {
+ atomicMethod = AtomicCounterFunction::INCREMENT;
+ hlslFunctionNameSB << "increment";
+ }
+ else if (kAtomicCounterDecrement == name)
+ {
+ atomicMethod = AtomicCounterFunction::DECREMENT;
+ hlslFunctionNameSB << "decrement";
+ }
+ else
+ {
+ atomicMethod = AtomicCounterFunction::INVALID;
+ UNREACHABLE();
+ }
+
+ ImmutableString hlslFunctionName(hlslFunctionNameSB);
+ mAtomicCounterFunctions[hlslFunctionName] = atomicMethod;
+
+ return hlslFunctionName;
+}
+
+void AtomicCounterFunctionHLSL::atomicCounterFunctionHeader(TInfoSinkBase &out)
+{
+ for (auto &atomicFunction : mAtomicCounterFunctions)
+ {
+ out << "uint " << atomicFunction.first
+ << "(in RWByteAddressBuffer counter, int address)\n"
+ "{\n"
+ " uint ret;\n";
+
+ switch (atomicFunction.second)
+ {
+ case AtomicCounterFunction::INCREMENT:
+ out << " counter.InterlockedAdd(address, 1u, ret);\n";
+ break;
+ case AtomicCounterFunction::DECREMENT:
+ out << " counter.InterlockedAdd(address, 0u - 1u, ret);\n"
+ " ret -= 1u;\n"; // atomicCounterDecrement is a post-decrement op
+ break;
+ case AtomicCounterFunction::LOAD:
+ out << " ret = counter.Load(address);\n";
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ if (mForceResolution && atomicFunction.second != AtomicCounterFunction::LOAD)
+ {
+ out << " if (ret == 0) {\n"
+ " ret = 0 - ret;\n"
+ " }\n";
+ }
+
+ out << " return ret;\n"
+ "}\n\n";
+ }
+}
+
+ImmutableString getAtomicCounterNameForBinding(int binding)
+{
+ std::stringstream counterName = sh::InitializeStream<std::stringstream>();
+ counterName << kAtomicCounterBaseName << binding;
+ return ImmutableString(counterName.str());
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/AtomicCounterFunctionHLSL.h b/gfx/angle/checkout/src/compiler/translator/AtomicCounterFunctionHLSL.h
new file mode 100644
index 0000000000..669e567476
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/AtomicCounterFunctionHLSL.h
@@ -0,0 +1,50 @@
+//
+// Copyright 2018 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.
+//
+// AtomicCounterFunctionHLSL: Class for writing implementation of atomic counter functions into HLSL
+// output.
+//
+
+#ifndef COMPILER_TRANSLATOR_ATOMICCOUNTERFUNCTIONHLSL_H_
+#define COMPILER_TRANSLATOR_ATOMICCOUNTERFUNCTIONHLSL_H_
+
+#include <map>
+
+#include "compiler/translator/Common.h"
+#include "compiler/translator/ImmutableString.h"
+
+namespace sh
+{
+
+class TInfoSinkBase;
+struct TLayoutQualifier;
+
+class AtomicCounterFunctionHLSL final : angle::NonCopyable
+{
+ public:
+ AtomicCounterFunctionHLSL(bool forceResolution);
+
+ ImmutableString useAtomicCounterFunction(const ImmutableString &name);
+
+ void atomicCounterFunctionHeader(TInfoSinkBase &out);
+
+ private:
+ enum class AtomicCounterFunction
+ {
+ LOAD,
+ INCREMENT,
+ DECREMENT,
+ INVALID
+ };
+
+ std::map<ImmutableString, AtomicCounterFunction> mAtomicCounterFunctions;
+ bool mForceResolution;
+};
+
+ImmutableString getAtomicCounterNameForBinding(int binding);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_ATOMICCOUNTERFUNCTIONHLSL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/BaseTypes.cpp b/gfx/angle/checkout/src/compiler/translator/BaseTypes.cpp
new file mode 100644
index 0000000000..15a3ebebc8
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/BaseTypes.cpp
@@ -0,0 +1,64 @@
+//
+// Copyright 2022 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 "BaseTypes.h"
+
+#include "common/PackedEnums.h"
+
+namespace sh
+{
+namespace
+{
+constexpr gl::BlendEquationBitSet kAdvancedBlendBits{
+ gl::BlendEquationType::Multiply, gl::BlendEquationType::Screen,
+ gl::BlendEquationType::Overlay, gl::BlendEquationType::Darken,
+ gl::BlendEquationType::Lighten, gl::BlendEquationType::Colordodge,
+ gl::BlendEquationType::Colorburn, gl::BlendEquationType::Hardlight,
+ gl::BlendEquationType::Softlight, gl::BlendEquationType::Difference,
+ gl::BlendEquationType::Exclusion, gl::BlendEquationType::HslHue,
+ gl::BlendEquationType::HslSaturation, gl::BlendEquationType::HslColor,
+ gl::BlendEquationType::HslLuminosity,
+};
+
+constexpr gl::BlendEquationBitSet kAdvancedBlendHslBits{
+ gl::BlendEquationType::HslHue,
+ gl::BlendEquationType::HslSaturation,
+ gl::BlendEquationType::HslColor,
+ gl::BlendEquationType::HslLuminosity,
+};
+
+bool IsValidAdvancedBlendBitSet(uint32_t enabledEquations)
+{
+ return (gl::BlendEquationBitSet(enabledEquations) & ~kAdvancedBlendBits).none();
+}
+} // anonymous namespace
+
+bool AdvancedBlendEquations::any() const
+{
+ ASSERT(IsValidAdvancedBlendBitSet(mEnabledBlendEquations));
+ return mEnabledBlendEquations != 0;
+}
+
+bool AdvancedBlendEquations::anyHsl() const
+{
+ ASSERT(IsValidAdvancedBlendBitSet(mEnabledBlendEquations));
+ return (gl::BlendEquationBitSet(mEnabledBlendEquations) & kAdvancedBlendHslBits).any();
+}
+
+void AdvancedBlendEquations::setAll()
+{
+ ASSERT(IsValidAdvancedBlendBitSet(mEnabledBlendEquations));
+ mEnabledBlendEquations = kAdvancedBlendBits.bits();
+}
+
+void AdvancedBlendEquations::set(uint32_t blendEquation)
+{
+ gl::BlendEquationType eq = static_cast<gl::BlendEquationType>(blendEquation);
+ mEnabledBlendEquations = gl::BlendEquationBitSet(mEnabledBlendEquations).set(eq).bits();
+ ASSERT(IsValidAdvancedBlendBitSet(mEnabledBlendEquations));
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/BaseTypes.h b/gfx/angle/checkout/src/compiler/translator/BaseTypes.h
new file mode 100644
index 0000000000..7e569f4e9d
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/BaseTypes.h
@@ -0,0 +1,1782 @@
+//
+// Copyright 2002 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_BASETYPES_H_
+#define COMPILER_TRANSLATOR_BASETYPES_H_
+
+#include <algorithm>
+#include <array>
+
+#include "GLSLANG/ShaderLang.h"
+#include "common/debug.h"
+#include "compiler/translator/ImmutableString.h"
+
+namespace sh
+{
+
+//
+// Precision qualifiers
+//
+enum TPrecision
+{
+ // These need to be kept sorted
+ EbpUndefined,
+ EbpLow,
+ EbpMedium,
+ EbpHigh,
+
+ // end of list
+ EbpLast
+};
+
+inline const char *getPrecisionString(TPrecision p)
+{
+ switch (p)
+ {
+ case EbpHigh:
+ return "highp";
+ case EbpMedium:
+ return "mediump";
+ case EbpLow:
+ return "lowp";
+ default:
+ return "mediump"; // Safest fallback
+ }
+}
+
+//
+// Basic type. Arrays, vectors, etc., are orthogonal to this.
+//
+enum TBasicType
+{
+ EbtVoid,
+ EbtFloat,
+ EbtDouble,
+ EbtInt,
+ EbtUInt,
+ EbtBool,
+
+ EbtAtomicCounter,
+ EbtYuvCscStandardEXT, // Only valid if EXT_YUV_target exists.
+
+ EbtGuardSamplerBegin, // non type: see implementation of IsSampler()
+ EbtSampler2D = EbtGuardSamplerBegin,
+ EbtSampler3D,
+ EbtSamplerCube,
+ EbtSampler2DArray,
+ EbtSamplerExternalOES, // Only valid if OES_EGL_image_external exists.
+ EbtSamplerExternal2DY2YEXT, // Only valid if GL_EXT_YUV_target exists.
+ EbtSampler2DRect, // Only valid if GL_ARB_texture_rectangle exists.
+ EbtSampler2DMS,
+ EbtSampler2DMSArray,
+ EbtISampler2D,
+ EbtISampler3D,
+ EbtISamplerCube,
+ EbtISampler2DArray,
+ EbtISampler2DMS,
+ EbtISampler2DMSArray,
+ EbtUSampler2D,
+ EbtUSampler3D,
+ EbtUSamplerCube,
+ EbtUSampler2DArray,
+ EbtUSampler2DMS,
+ EbtUSampler2DMSArray,
+ EbtSampler2DShadow,
+ EbtSamplerCubeShadow,
+ EbtSampler2DArrayShadow,
+ EbtSampler1D, // Desktop GLSL sampler types
+ EbtSampler1DArray,
+ EbtSampler1DArrayShadow,
+ EbtSamplerBuffer,
+ EbtSamplerCubeArray,
+ EbtSamplerCubeArrayShadow,
+ EbtSampler1DShadow,
+ EbtSampler2DRectShadow,
+ EbtISampler1D,
+ EbtISampler1DArray,
+ EbtISampler2DRect,
+ EbtISamplerBuffer,
+ EbtISamplerCubeArray,
+ EbtUSampler1D,
+ EbtUSampler1DArray,
+ EbtUSampler2DRect,
+ EbtUSamplerBuffer,
+ EbtUSamplerCubeArray,
+ EbtSamplerVideoWEBGL,
+ EbtGuardSamplerEnd = EbtSamplerVideoWEBGL, // non type: see implementation of IsSampler()
+
+ // images
+ EbtGuardImageBegin,
+ EbtImage2D = EbtGuardImageBegin,
+ EbtImage3D,
+ EbtImage2DArray,
+ EbtImageCube,
+ EbtImage1D,
+ EbtImage1DArray,
+ EbtImage2DMS,
+ EbtImage2DMSArray,
+ EbtImageCubeArray,
+ EbtImageRect,
+ EbtImageBuffer,
+ EbtIImage2D,
+ EbtIImage3D,
+ EbtIImage2DArray,
+ EbtIImageCube,
+ EbtIImage1D,
+ EbtIImage1DArray,
+ EbtIImage2DMS,
+ EbtIImage2DMSArray,
+ EbtIImageCubeArray,
+ EbtIImageRect,
+ EbtIImageBuffer,
+ EbtGuardUIntImageBegin,
+ EbtUImage2D = EbtGuardUIntImageBegin,
+ EbtUImage3D,
+ EbtUImage2DArray,
+ EbtUImageCube,
+ EbtUImage1D,
+ EbtUImage1DArray,
+ EbtUImage2DMS,
+ EbtUImage2DMSArray,
+ EbtUImageCubeArray,
+ EbtUImageRect,
+ EbtUImageBuffer,
+ EbtGuardUIntImageEnd = EbtUImageBuffer,
+ EbtGuardImageEnd = EbtGuardUIntImageEnd,
+
+ // ANGLE_shader_pixel_local_storage
+ EbtGuardPixelLocalBegin,
+ EbtPixelLocalANGLE = EbtGuardPixelLocalBegin,
+ EbtIPixelLocalANGLE,
+ EbtUPixelLocalANGLE,
+ EbtGuardPixelLocalEnd = EbtUPixelLocalANGLE,
+
+ // Subpass Input
+ EbtGuardSubpassInputBegin,
+ EbtSubpassInput = EbtGuardSubpassInputBegin,
+ EbtISubpassInput,
+ EbtUSubpassInput,
+ EbtSubpassInputMS,
+ EbtISubpassInputMS,
+ EbtUSubpassInputMS,
+ EbtGuardSubpassInputEnd = EbtUSubpassInputMS,
+
+ EbtLastSimpleType = EbtGuardSubpassInputEnd,
+
+ EbtStruct,
+ EbtInterfaceBlock,
+
+ // end of list
+ EbtLast = EbtInterfaceBlock
+};
+
+class TBasicMangledName
+{
+ public:
+ constexpr TBasicMangledName(TBasicType t) : mName{'\0', '\0'}
+ {
+ if (t > EbtLastSimpleType)
+ {
+ mName[0] = '{';
+ mName[1] = '\0';
+ }
+ else if (t < 26)
+ {
+ mName[0] = '0';
+ mName[1] = static_cast<char>('A' + t);
+ }
+ else if (t < 52)
+ {
+ mName[0] = '0';
+ mName[1] = static_cast<char>('a' - 26 + t);
+ }
+ else if (t < 78)
+ {
+ mName[0] = '1';
+ mName[1] = static_cast<char>('A' - 52 + t);
+ }
+ else if (t < 104)
+ {
+ mName[0] = '1';
+ mName[1] = static_cast<char>('a' - 78 + t);
+ }
+ }
+
+ constexpr char *getName() { return mName; }
+
+ static constexpr int mangledNameSize = 2;
+
+ private:
+ char mName[mangledNameSize];
+};
+
+const char *getBasicString(TBasicType t);
+
+inline bool IsSampler(TBasicType type)
+{
+ return type >= EbtGuardSamplerBegin && type <= EbtGuardSamplerEnd;
+}
+
+inline bool IsImage(TBasicType type)
+{
+ return type >= EbtGuardImageBegin && type <= EbtGuardImageEnd;
+}
+
+inline bool IsUIntImage(TBasicType type)
+{
+ return type >= EbtGuardUIntImageBegin && type <= EbtGuardUIntImageEnd;
+}
+
+inline bool IsAtomicCounter(TBasicType type)
+{
+ return type == EbtAtomicCounter;
+}
+
+inline bool IsPixelLocal(TBasicType type)
+{
+ return type >= EbtGuardPixelLocalBegin && type <= EbtGuardPixelLocalEnd;
+}
+
+inline bool IsSubpassInputType(TBasicType type)
+{
+ return type >= EbtGuardSubpassInputBegin && type <= EbtGuardSubpassInputEnd;
+}
+
+inline bool IsOpaqueType(TBasicType type)
+{
+ return IsSampler(type) || IsImage(type) || IsAtomicCounter(type) || IsPixelLocal(type) ||
+ IsSubpassInputType(type);
+}
+
+inline bool IsIntegerSampler(TBasicType type)
+{
+ switch (type)
+ {
+ case EbtISampler2D:
+ case EbtISampler3D:
+ case EbtISamplerCube:
+ case EbtISampler2DArray:
+ case EbtISampler2DMS:
+ case EbtISampler2DMSArray:
+ case EbtUSampler2D:
+ case EbtUSampler3D:
+ case EbtUSamplerCube:
+ case EbtUSampler2DArray:
+ case EbtUSampler2DMS:
+ case EbtUSampler2DMSArray:
+ case EbtISampler1D:
+ case EbtISampler1DArray:
+ case EbtISampler2DRect:
+ case EbtISamplerBuffer:
+ case EbtISamplerCubeArray:
+ case EbtUSampler1D:
+ case EbtUSampler1DArray:
+ case EbtUSampler2DRect:
+ case EbtUSamplerBuffer:
+ case EbtUSamplerCubeArray:
+ return true;
+ case EbtSampler2D:
+ case EbtSampler3D:
+ case EbtSamplerCube:
+ case EbtSamplerExternalOES:
+ case EbtSamplerExternal2DY2YEXT:
+ case EbtSampler2DRect:
+ case EbtSampler2DArray:
+ case EbtSampler2DShadow:
+ case EbtSamplerCubeShadow:
+ case EbtSampler2DArrayShadow:
+ case EbtSampler2DMS:
+ case EbtSampler2DMSArray:
+ case EbtSampler1D:
+ case EbtSampler1DArray:
+ case EbtSampler1DArrayShadow:
+ case EbtSamplerBuffer:
+ case EbtSamplerCubeArray:
+ case EbtSamplerCubeArrayShadow:
+ case EbtSampler1DShadow:
+ case EbtSampler2DRectShadow:
+ case EbtSamplerVideoWEBGL:
+ return false;
+ default:
+ ASSERT(!IsSampler(type));
+ }
+
+ return false;
+}
+
+inline bool IsIntegerSamplerUnsigned(TBasicType type)
+{
+ switch (type)
+ {
+ case EbtISampler2D:
+ case EbtISampler3D:
+ case EbtISamplerCube:
+ case EbtISampler2DArray:
+ case EbtISampler2DMS:
+ case EbtISampler2DMSArray:
+ case EbtISampler1D:
+ case EbtISampler1DArray:
+ case EbtISampler2DRect:
+ case EbtISamplerBuffer:
+ case EbtISamplerCubeArray:
+ return false;
+ case EbtUSampler2D:
+ case EbtUSampler3D:
+ case EbtUSamplerCube:
+ case EbtUSampler2DArray:
+ case EbtUSampler2DMS:
+ case EbtUSampler2DMSArray:
+ case EbtUSampler1D:
+ case EbtUSampler1DArray:
+ case EbtUSampler2DRect:
+ case EbtUSamplerBuffer:
+ case EbtUSamplerCubeArray:
+ return true;
+ default:
+ ASSERT(!IsIntegerSampler(type));
+ }
+
+ return false;
+}
+
+inline bool IsSampler2DMS(TBasicType type)
+{
+ switch (type)
+ {
+ case EbtSampler2DMS:
+ case EbtISampler2DMS:
+ case EbtUSampler2DMS:
+ return true;
+ default:
+ return false;
+ }
+}
+
+inline bool IsSampler2DMSArray(TBasicType type)
+{
+ switch (type)
+ {
+ case EbtSampler2DMSArray:
+ case EbtISampler2DMSArray:
+ case EbtUSampler2DMSArray:
+ return true;
+ default:
+ return false;
+ }
+}
+
+inline bool IsSamplerMS(TBasicType type)
+{
+ return IsSampler2DMS(type) || IsSampler2DMSArray(type);
+}
+
+inline bool IsImageMS(TBasicType type)
+{
+ switch (type)
+ {
+ case EbtImage2DMS:
+ case EbtImage2DMSArray:
+ case EbtIImage2DMS:
+ case EbtIImage2DMSArray:
+ case EbtUImage2DMS:
+ case EbtUImage2DMSArray:
+ return true;
+ default:
+ return false;
+ }
+}
+
+inline bool IsFloatImage(TBasicType type)
+{
+ switch (type)
+ {
+ case EbtImage1D:
+ case EbtImage2D:
+ case EbtImage3D:
+ case EbtImage1DArray:
+ case EbtImage2DArray:
+ case EbtImageCube:
+ case EbtImage2DMS:
+ case EbtImage2DMSArray:
+ case EbtImageCubeArray:
+ case EbtImageRect:
+ case EbtImageBuffer:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+}
+
+inline bool IsIntegerImage(TBasicType type)
+{
+
+ switch (type)
+ {
+ case EbtIImage1D:
+ case EbtIImage2D:
+ case EbtIImage3D:
+ case EbtIImage1DArray:
+ case EbtIImage2DArray:
+ case EbtIImageCube:
+ case EbtIImage2DMS:
+ case EbtIImage2DMSArray:
+ case EbtIImageCubeArray:
+ case EbtIImageRect:
+ case EbtIImageBuffer:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+}
+
+inline bool IsUnsignedImage(TBasicType type)
+{
+
+ switch (type)
+ {
+ case EbtUImage1D:
+ case EbtUImage2D:
+ case EbtUImage3D:
+ case EbtUImage1DArray:
+ case EbtUImage2DArray:
+ case EbtUImageCube:
+ case EbtUImage2DMS:
+ case EbtUImage2DMSArray:
+ case EbtUImageCubeArray:
+ case EbtUImageRect:
+ case EbtUImageBuffer:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+}
+
+// Samplers are divided into 4 disjoint categories: 2D, cube, 3D, and array.
+// Array samplers are not 2D samplers.
+inline bool IsSampler2D(TBasicType type)
+{
+ switch (type)
+ {
+ case EbtSampler2D:
+ case EbtISampler2D:
+ case EbtUSampler2D:
+ case EbtSampler2DRect:
+ case EbtISampler2DRect:
+ case EbtUSampler2DRect:
+ case EbtSampler2DRectShadow:
+ case EbtSamplerExternalOES:
+ case EbtSamplerExternal2DY2YEXT:
+ case EbtSampler2DShadow:
+ case EbtSampler2DMS:
+ case EbtISampler2DMS:
+ case EbtUSampler2DMS:
+ case EbtSamplerVideoWEBGL:
+ return true;
+ case EbtSampler2DArray:
+ case EbtISampler2DArray:
+ case EbtUSampler2DArray:
+ case EbtSampler2DMSArray:
+ case EbtISampler2DMSArray:
+ case EbtUSampler2DMSArray:
+ case EbtSampler2DArrayShadow:
+ case EbtSampler3D:
+ case EbtISampler3D:
+ case EbtUSampler3D:
+ case EbtISamplerCube:
+ case EbtUSamplerCube:
+ case EbtSamplerCube:
+ case EbtSamplerCubeShadow:
+ case EbtSampler1D:
+ case EbtSampler1DArray:
+ case EbtSampler1DArrayShadow:
+ case EbtSamplerBuffer:
+ case EbtSamplerCubeArray:
+ case EbtSamplerCubeArrayShadow:
+ case EbtSampler1DShadow:
+ case EbtISampler1D:
+ case EbtISampler1DArray:
+ case EbtISamplerBuffer:
+ case EbtISamplerCubeArray:
+ case EbtUSampler1D:
+ case EbtUSampler1DArray:
+ case EbtUSamplerBuffer:
+ case EbtUSamplerCubeArray:
+ return false;
+ default:
+ ASSERT(!IsSampler(type));
+ }
+
+ return false;
+}
+
+inline bool IsSamplerCube(TBasicType type)
+{
+ switch (type)
+ {
+ case EbtSamplerCube:
+ case EbtISamplerCube:
+ case EbtUSamplerCube:
+ case EbtSamplerCubeShadow:
+ return true;
+ case EbtSampler2D:
+ case EbtSampler3D:
+ case EbtSamplerExternalOES:
+ case EbtSamplerExternal2DY2YEXT:
+ case EbtSampler2DRect:
+ case EbtSampler2DArray:
+ case EbtSampler2DMS:
+ case EbtSampler2DMSArray:
+ case EbtISampler2D:
+ case EbtISampler3D:
+ case EbtISampler2DArray:
+ case EbtISampler2DMS:
+ case EbtISampler2DMSArray:
+ case EbtUSampler2D:
+ case EbtUSampler3D:
+ case EbtUSampler2DArray:
+ case EbtUSampler2DMS:
+ case EbtUSampler2DMSArray:
+ case EbtSampler2DShadow:
+ case EbtSampler2DArrayShadow:
+ case EbtSampler1D:
+ case EbtSampler1DArray:
+ case EbtSampler1DArrayShadow:
+ case EbtSamplerBuffer:
+ case EbtSamplerCubeArray:
+ case EbtSamplerCubeArrayShadow:
+ case EbtSampler1DShadow:
+ case EbtSampler2DRectShadow:
+ case EbtISampler1D:
+ case EbtISampler1DArray:
+ case EbtISampler2DRect:
+ case EbtISamplerBuffer:
+ case EbtISamplerCubeArray:
+ case EbtUSampler1D:
+ case EbtUSampler1DArray:
+ case EbtUSampler2DRect:
+ case EbtUSamplerBuffer:
+ case EbtUSamplerCubeArray:
+ case EbtSamplerVideoWEBGL:
+ return false;
+ default:
+ ASSERT(!IsSampler(type));
+ }
+
+ return false;
+}
+
+inline bool IsSampler3D(TBasicType type)
+{
+ switch (type)
+ {
+ case EbtSampler3D:
+ case EbtISampler3D:
+ case EbtUSampler3D:
+ return true;
+ case EbtSampler2D:
+ case EbtSamplerCube:
+ case EbtSamplerExternalOES:
+ case EbtSamplerExternal2DY2YEXT:
+ case EbtSampler2DRect:
+ case EbtSampler2DArray:
+ case EbtSampler2DMS:
+ case EbtSampler2DMSArray:
+ case EbtISampler2D:
+ case EbtISamplerCube:
+ case EbtISampler2DArray:
+ case EbtISampler2DMS:
+ case EbtISampler2DMSArray:
+ case EbtUSampler2D:
+ case EbtUSamplerCube:
+ case EbtUSampler2DArray:
+ case EbtUSampler2DMS:
+ case EbtUSampler2DMSArray:
+ case EbtSampler2DShadow:
+ case EbtSamplerCubeShadow:
+ case EbtSampler2DArrayShadow:
+ case EbtSampler1D:
+ case EbtSampler1DArray:
+ case EbtSampler1DArrayShadow:
+ case EbtSamplerBuffer:
+ case EbtSamplerCubeArray:
+ case EbtSamplerCubeArrayShadow:
+ case EbtSampler1DShadow:
+ case EbtSampler2DRectShadow:
+ case EbtISampler1D:
+ case EbtISampler1DArray:
+ case EbtISampler2DRect:
+ case EbtISamplerBuffer:
+ case EbtISamplerCubeArray:
+ case EbtUSampler1D:
+ case EbtUSampler1DArray:
+ case EbtUSampler2DRect:
+ case EbtUSamplerBuffer:
+ case EbtUSamplerCubeArray:
+ case EbtSamplerVideoWEBGL:
+ return false;
+ default:
+ ASSERT(!IsSampler(type));
+ }
+
+ return false;
+}
+
+inline bool IsSamplerArray(TBasicType type)
+{
+ switch (type)
+ {
+ case EbtSampler1DArray:
+ case EbtISampler1DArray:
+ case EbtUSampler1DArray:
+ case EbtSampler1DArrayShadow:
+ case EbtSampler2DArray:
+ case EbtISampler2DArray:
+ case EbtUSampler2DArray:
+ case EbtSampler2DMSArray:
+ case EbtISampler2DMSArray:
+ case EbtUSampler2DMSArray:
+ case EbtSampler2DArrayShadow:
+ case EbtSamplerCubeArray:
+ case EbtISamplerCubeArray:
+ case EbtUSamplerCubeArray:
+ case EbtSamplerCubeArrayShadow:
+ return true;
+ case EbtSampler2D:
+ case EbtISampler2D:
+ case EbtUSampler2D:
+ case EbtSampler2DRect:
+ case EbtSamplerExternalOES:
+ case EbtSamplerExternal2DY2YEXT:
+ case EbtSampler3D:
+ case EbtISampler3D:
+ case EbtUSampler3D:
+ case EbtISamplerCube:
+ case EbtUSamplerCube:
+ case EbtSamplerCube:
+ case EbtSampler2DShadow:
+ case EbtSamplerCubeShadow:
+ case EbtSampler2DMS:
+ case EbtISampler2DMS:
+ case EbtUSampler2DMS:
+ case EbtSampler1D:
+ case EbtSamplerBuffer:
+ case EbtSampler1DShadow:
+ case EbtSampler2DRectShadow:
+ case EbtISampler1D:
+ case EbtISampler2DRect:
+ case EbtISamplerBuffer:
+ case EbtUSampler1D:
+ case EbtUSampler2DRect:
+ case EbtUSamplerBuffer:
+ case EbtSamplerVideoWEBGL:
+ return false;
+ default:
+ ASSERT(!IsSampler(type));
+ }
+
+ return false;
+}
+
+inline bool IsSampler1D(TBasicType type)
+{
+ switch (type)
+ {
+ case EbtSampler1D:
+ case EbtISampler1D:
+ case EbtUSampler1D:
+ case EbtSampler1DShadow:
+ return true;
+ case EbtSampler2D:
+ case EbtSamplerCube:
+ case EbtSampler3D:
+ case EbtISampler3D:
+ case EbtUSampler3D:
+ case EbtSamplerExternalOES:
+ case EbtSamplerExternal2DY2YEXT:
+ case EbtSampler2DRect:
+ case EbtSampler2DArray:
+ case EbtSampler2DMS:
+ case EbtSampler2DMSArray:
+ case EbtISampler2D:
+ case EbtISamplerCube:
+ case EbtISampler2DArray:
+ case EbtISampler2DMS:
+ case EbtISampler2DMSArray:
+ case EbtUSampler2D:
+ case EbtUSamplerCube:
+ case EbtUSampler2DArray:
+ case EbtUSampler2DMS:
+ case EbtUSampler2DMSArray:
+ case EbtSampler2DShadow:
+ case EbtSamplerCubeShadow:
+ case EbtSampler2DArrayShadow:
+ case EbtSampler1DArray:
+ case EbtSampler1DArrayShadow:
+ case EbtSamplerBuffer:
+ case EbtSamplerCubeArray:
+ case EbtSamplerCubeArrayShadow:
+ case EbtSampler2DRectShadow:
+ case EbtISampler1DArray:
+ case EbtISampler2DRect:
+ case EbtISamplerBuffer:
+ case EbtISamplerCubeArray:
+ case EbtUSampler1DArray:
+ case EbtUSampler2DRect:
+ case EbtUSamplerBuffer:
+ case EbtUSamplerCubeArray:
+ case EbtSamplerVideoWEBGL:
+ return false;
+ default:
+ ASSERT(!IsSampler(type));
+ }
+
+ return false;
+}
+
+inline bool IsSamplerBuffer(TBasicType type)
+{
+ switch (type)
+ {
+ case EbtSamplerBuffer:
+ case EbtISamplerBuffer:
+ case EbtUSamplerBuffer:
+ return true;
+ default:
+ return false;
+ }
+}
+
+inline bool IsShadowSampler(TBasicType type)
+{
+ switch (type)
+ {
+ case EbtSampler1DShadow:
+ case EbtSampler2DShadow:
+ case EbtSamplerCubeShadow:
+ case EbtSampler1DArrayShadow:
+ case EbtSampler2DArrayShadow:
+ case EbtSamplerCubeArrayShadow:
+ case EbtSampler2DRectShadow:
+ return true;
+ case EbtISampler2D:
+ case EbtISampler3D:
+ case EbtISamplerCube:
+ case EbtISampler2DArray:
+ case EbtISampler2DMS:
+ case EbtISampler2DMSArray:
+ case EbtUSampler2D:
+ case EbtUSampler3D:
+ case EbtUSamplerCube:
+ case EbtUSampler2DArray:
+ case EbtUSampler2DMS:
+ case EbtUSampler2DMSArray:
+ case EbtSampler2D:
+ case EbtSampler3D:
+ case EbtSamplerCube:
+ case EbtSamplerExternalOES:
+ case EbtSamplerExternal2DY2YEXT:
+ case EbtSampler2DRect:
+ case EbtSampler2DArray:
+ case EbtSampler2DMS:
+ case EbtSampler2DMSArray:
+ case EbtSampler1D:
+ case EbtSampler1DArray:
+ case EbtSamplerBuffer:
+ case EbtSamplerCubeArray:
+ case EbtISampler1D:
+ case EbtISampler1DArray:
+ case EbtISampler2DRect:
+ case EbtISamplerBuffer:
+ case EbtISamplerCubeArray:
+ case EbtUSampler1D:
+ case EbtUSampler1DArray:
+ case EbtUSampler2DRect:
+ case EbtUSamplerBuffer:
+ case EbtUSamplerCubeArray:
+ case EbtSamplerVideoWEBGL:
+ return false;
+ default:
+ ASSERT(!IsSampler(type));
+ }
+
+ return false;
+}
+
+inline bool IsImage2D(TBasicType type)
+{
+ switch (type)
+ {
+ case EbtImage2D:
+ case EbtIImage2D:
+ case EbtUImage2D:
+ case EbtImage2DMS:
+ case EbtIImage2DMS:
+ case EbtUImage2DMS:
+ return true;
+ case EbtImage3D:
+ case EbtIImage3D:
+ case EbtUImage3D:
+ case EbtImage2DArray:
+ case EbtIImage2DArray:
+ case EbtUImage2DArray:
+ case EbtImageCube:
+ case EbtIImageCube:
+ case EbtUImageCube:
+ case EbtImage1D:
+ case EbtIImage1D:
+ case EbtUImage1D:
+ case EbtImage1DArray:
+ case EbtIImage1DArray:
+ case EbtUImage1DArray:
+ case EbtImage2DMSArray:
+ case EbtIImage2DMSArray:
+ case EbtUImage2DMSArray:
+ case EbtImageCubeArray:
+ case EbtIImageCubeArray:
+ case EbtUImageCubeArray:
+ case EbtImageRect:
+ case EbtIImageRect:
+ case EbtUImageRect:
+ case EbtImageBuffer:
+ case EbtIImageBuffer:
+ case EbtUImageBuffer:
+ return false;
+ default:
+ ASSERT(!IsImage(type));
+ }
+
+ return false;
+}
+
+inline bool IsImage3D(TBasicType type)
+{
+ switch (type)
+ {
+ case EbtImage3D:
+ case EbtIImage3D:
+ case EbtUImage3D:
+ return true;
+ case EbtImage2D:
+ case EbtIImage2D:
+ case EbtUImage2D:
+ case EbtImage2DArray:
+ case EbtIImage2DArray:
+ case EbtUImage2DArray:
+ case EbtImageCube:
+ case EbtIImageCube:
+ case EbtUImageCube:
+ case EbtImage1D:
+ case EbtIImage1D:
+ case EbtUImage1D:
+ case EbtImage1DArray:
+ case EbtIImage1DArray:
+ case EbtUImage1DArray:
+ case EbtImage2DMS:
+ case EbtIImage2DMS:
+ case EbtUImage2DMS:
+ case EbtImage2DMSArray:
+ case EbtIImage2DMSArray:
+ case EbtUImage2DMSArray:
+ case EbtImageCubeArray:
+ case EbtIImageCubeArray:
+ case EbtUImageCubeArray:
+ case EbtImageRect:
+ case EbtIImageRect:
+ case EbtUImageRect:
+ case EbtImageBuffer:
+ case EbtIImageBuffer:
+ case EbtUImageBuffer:
+ return false;
+ default:
+ ASSERT(!IsImage(type));
+ }
+
+ return false;
+}
+
+inline bool IsImage2DArray(TBasicType type)
+{
+ switch (type)
+ {
+ case EbtImage2DArray:
+ case EbtIImage2DArray:
+ case EbtUImage2DArray:
+ case EbtImage2DMSArray:
+ case EbtIImage2DMSArray:
+ case EbtUImage2DMSArray:
+ return true;
+ case EbtImage2D:
+ case EbtIImage2D:
+ case EbtUImage2D:
+ case EbtImage3D:
+ case EbtIImage3D:
+ case EbtUImage3D:
+ case EbtImageCube:
+ case EbtIImageCube:
+ case EbtUImageCube:
+ case EbtImage1D:
+ case EbtIImage1D:
+ case EbtUImage1D:
+ case EbtImage1DArray:
+ case EbtIImage1DArray:
+ case EbtUImage1DArray:
+ case EbtImage2DMS:
+ case EbtIImage2DMS:
+ case EbtUImage2DMS:
+ case EbtImageCubeArray:
+ case EbtIImageCubeArray:
+ case EbtUImageCubeArray:
+ case EbtImageRect:
+ case EbtIImageRect:
+ case EbtUImageRect:
+ case EbtImageBuffer:
+ case EbtIImageBuffer:
+ case EbtUImageBuffer:
+ return false;
+ default:
+ ASSERT(!IsImage(type));
+ }
+
+ return false;
+}
+
+inline bool IsImageCube(TBasicType type)
+{
+ switch (type)
+ {
+ case EbtImageCube:
+ case EbtIImageCube:
+ case EbtUImageCube:
+ return true;
+ case EbtImage2D:
+ case EbtIImage2D:
+ case EbtUImage2D:
+ case EbtImage3D:
+ case EbtIImage3D:
+ case EbtUImage3D:
+ case EbtImage2DArray:
+ case EbtIImage2DArray:
+ case EbtUImage2DArray:
+ case EbtImage1D:
+ case EbtIImage1D:
+ case EbtUImage1D:
+ case EbtImage1DArray:
+ case EbtIImage1DArray:
+ case EbtUImage1DArray:
+ case EbtImage2DMS:
+ case EbtIImage2DMS:
+ case EbtUImage2DMS:
+ case EbtImage2DMSArray:
+ case EbtIImage2DMSArray:
+ case EbtUImage2DMSArray:
+ case EbtImageCubeArray:
+ case EbtIImageCubeArray:
+ case EbtUImageCubeArray:
+ case EbtImageRect:
+ case EbtIImageRect:
+ case EbtUImageRect:
+ case EbtImageBuffer:
+ case EbtIImageBuffer:
+ case EbtUImageBuffer:
+ return false;
+ default:
+ ASSERT(!IsImage(type));
+ }
+
+ return false;
+}
+
+inline bool IsImageBuffer(TBasicType type)
+{
+ switch (type)
+ {
+ case EbtImageBuffer:
+ case EbtIImageBuffer:
+ case EbtUImageBuffer:
+ return true;
+ default:
+ return false;
+ }
+}
+
+inline bool IsInteger(TBasicType type)
+{
+ return type == EbtInt || type == EbtUInt;
+}
+
+inline bool SupportsPrecision(TBasicType type)
+{
+ return type == EbtFloat || type == EbtInt || type == EbtUInt || IsOpaqueType(type);
+}
+
+//
+// Qualifiers and built-ins. These are mainly used to see what can be read
+// or written, and by the machine dependent translator to know which registers
+// to allocate variables in. Since built-ins tend to go to different registers
+// than varying or uniform, it makes sense they are peers, not sub-classes.
+//
+enum TQualifier
+{
+ EvqTemporary, // For temporaries (within a function), read/write
+ EvqGlobal, // For globals read/write
+ EvqConst, // User defined constants
+ EvqAttribute, // Readonly
+ EvqVaryingIn, // readonly, fragment shaders only
+ EvqVaryingOut, // vertex shaders only read/write
+ EvqUniform, // Readonly, vertex and fragment
+ EvqBuffer, // read/write, vertex, fragment and compute shader
+ EvqPatch, // EXT_tessellation_shader storage qualifier
+
+ EvqVertexIn, // Vertex shader input
+ EvqFragmentOut, // Fragment shader output
+ EvqVertexOut, // Vertex shader output
+ EvqFragmentIn, // Fragment shader input
+
+ EvqFragmentInOut, // EXT_shader_framebuffer_fetch qualifier
+
+ // parameters
+ EvqParamIn,
+ EvqParamOut,
+ EvqParamInOut,
+ EvqParamConst,
+
+ // built-ins read by vertex shader
+ EvqInstanceID,
+ EvqVertexID,
+
+ // built-ins written by vertex shader
+ EvqPosition,
+ EvqPointSize,
+
+ EvqDrawID, // ANGLE_multi_draw
+
+ // built-ins read by fragment shader
+ EvqFragCoord,
+ EvqFrontFacing,
+ EvqPointCoord,
+ EvqHelperInvocation,
+
+ // built-ins written by fragment shader
+ EvqFragColor,
+ EvqFragData,
+ EvqFragDepth, // gl_FragDepth for ESSL300, or gl_FragDepthEXT for ESSL100, EXT_frag_depth.
+
+ EvqSecondaryFragColorEXT, // EXT_blend_func_extended
+ EvqSecondaryFragDataEXT, // EXT_blend_func_extended
+
+ EvqViewIDOVR, // OVR_multiview
+ EvqViewportIndex, // gl_ViewportIndex
+
+ EvqClipDistance, // APPLE_clip_distance/EXT_clip_cull_distance
+ EvqCullDistance, // EXT_clip_cull_distance
+
+ // built-ins written by the shader_framebuffer_fetch extension(s)
+ EvqLastFragColor,
+ EvqLastFragData,
+
+ // GLSL ES 3.0 vertex output and fragment input
+ EvqSmooth, // Incomplete qualifier, smooth is the default
+ EvqFlat, // Incomplete qualifier
+ EvqNoPerspective, // Incomplete qualifier
+ EvqCentroid, // Incomplete qualifier
+ EvqSample,
+ EvqSmoothOut,
+ EvqFlatOut,
+ EvqNoPerspectiveOut,
+ EvqCentroidOut, // Implies smooth
+ EvqSampleOut,
+ EvqSmoothIn,
+ EvqFlatIn,
+ EvqNoPerspectiveIn,
+ EvqCentroidIn, // Implies smooth
+ EvqSampleIn,
+
+ // GLSL ES 3.0 extension OES_sample_variables
+ EvqSampleID,
+ EvqSamplePosition,
+ EvqSampleMaskIn,
+ EvqSampleMask,
+ EvqNumSamples,
+
+ // GLSL ES 3.1 compute shader special variables
+ EvqShared,
+ EvqComputeIn,
+ EvqNumWorkGroups,
+ EvqWorkGroupSize,
+ EvqWorkGroupID,
+ EvqLocalInvocationID,
+ EvqGlobalInvocationID,
+ EvqLocalInvocationIndex,
+
+ // GLSL ES 3.1 memory qualifiers
+ EvqReadOnly,
+ EvqWriteOnly,
+ EvqCoherent,
+ EvqRestrict,
+ EvqVolatile,
+
+ // GLSL ES 3.1 extension EXT_geometry_shader qualifiers
+ EvqGeometryIn,
+ EvqGeometryOut,
+ EvqPerVertexIn, // gl_in
+ EvqPrimitiveIDIn, // gl_PrimitiveIDIn
+ EvqInvocationID, // gl_InvocationID
+ EvqPrimitiveID, // gl_PrimitiveID
+ EvqLayerOut, // gl_Layer (GS output)
+ EvqLayerIn, // gl_Layer (FS input)
+
+ // GLSL ES 3.1 extension EXT_gpu_shader5 qualifiers
+ EvqPrecise,
+
+ // GLES ES 3.1 extension EXT_tessellation_shader qualifiers
+ EvqPatchIn,
+ EvqPatchOut,
+
+ EvqTessControlIn,
+ EvqTessControlOut,
+ EvqPerVertexOut,
+ EvqPatchVerticesIn,
+ EvqTessLevelOuter,
+ EvqTessLevelInner,
+
+ // GLES ES 3.1 extension EXT_primitive_bounding_box/OES_primitive_bounding_box
+ EvqBoundingBox,
+
+ EvqTessEvaluationIn,
+ EvqTessEvaluationOut,
+ EvqTessCoord,
+
+ // A specialization constant, which is not valid GLSL ES, but is there to support Vulkan output
+ // generation. In that case, TLayoutQualifier::location will contain the somewhat equivalent
+ // constant_id.
+ EvqSpecConst,
+
+ // end of list
+ EvqLast
+};
+
+inline bool IsQualifierUnspecified(TQualifier qualifier)
+{
+ return (qualifier == EvqTemporary || qualifier == EvqGlobal);
+}
+
+inline bool IsStorageBuffer(TQualifier qualifier)
+{
+ return qualifier == EvqBuffer;
+}
+
+inline bool IsShaderIn(TQualifier qualifier)
+{
+ switch (qualifier)
+ {
+ case EvqVertexIn:
+ case EvqTessControlIn:
+ case EvqTessEvaluationIn:
+ case EvqGeometryIn:
+ case EvqFragmentIn:
+ case EvqPerVertexIn:
+ case EvqAttribute:
+ case EvqVaryingIn:
+ case EvqSmoothIn:
+ case EvqFlatIn:
+ case EvqNoPerspectiveIn:
+ case EvqCentroidIn:
+ case EvqSampleIn:
+ case EvqPatchIn:
+ return true;
+ default:
+ return false;
+ }
+}
+
+inline bool IsShaderOut(TQualifier qualifier)
+{
+ switch (qualifier)
+ {
+ case EvqVertexOut:
+ case EvqTessControlOut:
+ case EvqTessEvaluationOut:
+ case EvqGeometryOut:
+ case EvqFragmentOut:
+ case EvqPerVertexOut:
+ case EvqVaryingOut:
+ case EvqSmoothOut:
+ case EvqFlatOut:
+ case EvqNoPerspectiveOut:
+ case EvqCentroidOut:
+ case EvqSampleOut:
+ case EvqPatchOut:
+ case EvqFragmentInOut:
+ return true;
+ default:
+ return false;
+ }
+}
+
+inline bool IsShaderIoBlock(TQualifier qualifier)
+{
+ switch (qualifier)
+ {
+ case EvqPerVertexIn:
+ case EvqPerVertexOut:
+ case EvqVertexOut:
+ case EvqTessControlIn:
+ case EvqTessControlOut:
+ case EvqTessEvaluationIn:
+ case EvqTessEvaluationOut:
+ case EvqPatchIn:
+ case EvqPatchOut:
+ case EvqGeometryIn:
+ case EvqGeometryOut:
+ case EvqFragmentIn:
+ return true;
+ default:
+ return false;
+ }
+}
+
+enum TLayoutImageInternalFormat
+{
+ EiifUnspecified,
+ EiifRGBA32F,
+ EiifRGBA16F,
+ EiifR32F,
+ EiifRGBA32UI,
+ EiifRGBA16UI,
+ EiifRGBA8UI,
+ EiifR32UI,
+ EiifRGBA32I,
+ EiifRGBA16I,
+ EiifRGBA8I,
+ EiifR32I,
+ EiifRGBA8,
+ EiifRGBA8_SNORM,
+
+ EiifLast = EiifRGBA8_SNORM,
+};
+
+enum TLayoutMatrixPacking
+{
+ EmpUnspecified,
+ EmpRowMajor,
+ EmpColumnMajor,
+
+ EmpLast = EmpColumnMajor,
+};
+
+enum TLayoutBlockStorage
+{
+ EbsUnspecified,
+ EbsShared,
+ EbsPacked,
+ EbsStd140,
+ EbsStd430,
+
+ EbsLast = EbsStd430,
+};
+
+enum TYuvCscStandardEXT
+{
+ EycsUndefined,
+ EycsItu601,
+ EycsItu601FullRange,
+ EycsItu709
+};
+
+enum TLayoutPrimitiveType
+{
+ EptUndefined,
+ EptPoints,
+ EptLines,
+ EptLinesAdjacency,
+ EptTriangles,
+ EptTrianglesAdjacency,
+ EptLineStrip,
+ EptTriangleStrip
+};
+
+enum TLayoutTessEvaluationType
+{
+ EtetUndefined,
+ EtetTriangles,
+ EtetQuads,
+ EtetIsolines,
+ EtetEqualSpacing,
+ EtetFractionalEvenSpacing,
+ EtetFractionalOddSpacing,
+ EtetCw,
+ EtetCcw,
+ EtetPointMode
+};
+
+class AdvancedBlendEquations
+{
+ public:
+ // Must have a trivial default constructor since it is used in YYSTYPE.
+ AdvancedBlendEquations() = default;
+ explicit constexpr AdvancedBlendEquations(uint32_t initialState)
+ : mEnabledBlendEquations(initialState)
+ {}
+
+ bool any() const;
+ bool anyHsl() const;
+
+ void setAll();
+ void reset() { mEnabledBlendEquations = 0; }
+
+ // Parameter is gl::BlendEquationType, but PackedEnums.h include is not possible here.
+ void set(uint32_t blendEquation);
+
+ uint32_t bits() const { return mEnabledBlendEquations; }
+
+ AdvancedBlendEquations operator|=(AdvancedBlendEquations other)
+ {
+ mEnabledBlendEquations |= other.mEnabledBlendEquations;
+ return *this;
+ }
+
+ private:
+ uint32_t mEnabledBlendEquations;
+};
+
+struct TLayoutQualifier
+{
+ // Must have a trivial default constructor since it is used in YYSTYPE.
+ TLayoutQualifier() = default;
+
+ constexpr static TLayoutQualifier Create() { return TLayoutQualifier(0); }
+
+ bool isEmpty() const
+ {
+ return location == -1 && binding == -1 && offset == -1 && numViews == -1 && yuv == false &&
+ earlyFragmentTests == false && matrixPacking == EmpUnspecified &&
+ blockStorage == EbsUnspecified && !localSize.isAnyValueSet() &&
+ imageInternalFormat == EiifUnspecified && primitiveType == EptUndefined &&
+ invocations == 0 && maxVertices == -1 && vertices == 0 &&
+ tesPrimitiveType == EtetUndefined && tesVertexSpacingType == EtetUndefined &&
+ tesOrderingType == EtetUndefined && tesPointType == EtetUndefined && index == -1 &&
+ inputAttachmentIndex == -1 && noncoherent == false &&
+ !advancedBlendEquations.any() && !pushConstant;
+ }
+
+ bool isCombinationValid() const
+ {
+ bool workGroupSizeSpecified = localSize.isAnyValueSet();
+ bool numViewsSet = (numViews != -1);
+ bool geometryShaderSpecified =
+ (primitiveType != EptUndefined) || (invocations != 0) || (maxVertices != -1);
+ bool subpassInputSpecified = (inputAttachmentIndex != -1);
+ bool otherLayoutQualifiersSpecified =
+ (location != -1 || binding != -1 || index != -1 || matrixPacking != EmpUnspecified ||
+ blockStorage != EbsUnspecified || imageInternalFormat != EiifUnspecified);
+ bool blendEquationSpecified = advancedBlendEquations.any();
+
+ // we can have either the work group size specified, or number of views,
+ // or yuv layout qualifier, or early_fragment_tests layout qualifier, or the other layout
+ // qualifiers.
+ return (workGroupSizeSpecified ? 1 : 0) + (numViewsSet ? 1 : 0) + (yuv ? 1 : 0) +
+ (earlyFragmentTests ? 1 : 0) + (otherLayoutQualifiersSpecified ? 1 : 0) +
+ (geometryShaderSpecified ? 1 : 0) + (subpassInputSpecified ? 1 : 0) +
+ (noncoherent ? 1 : 0) + (blendEquationSpecified ? 1 : 0) <=
+ 1;
+ }
+
+ bool isLocalSizeEqual(const WorkGroupSize &localSizeIn) const
+ {
+ return localSize.isWorkGroupSizeMatching(localSizeIn);
+ }
+
+ int location;
+ unsigned int locationsSpecified;
+ TLayoutMatrixPacking matrixPacking;
+ TLayoutBlockStorage blockStorage;
+
+ // Compute shader layout qualifiers.
+ WorkGroupSize localSize;
+
+ int binding;
+ int offset;
+
+ bool pushConstant;
+
+ // Image format layout qualifier
+ TLayoutImageInternalFormat imageInternalFormat;
+
+ // OVR_multiview num_views.
+ int numViews;
+
+ // EXT_YUV_target yuv layout qualifier.
+ bool yuv;
+
+ // early_fragment_tests qualifier.
+ bool earlyFragmentTests;
+
+ // OES_geometry_shader layout qualifiers.
+ TLayoutPrimitiveType primitiveType;
+ int invocations;
+ int maxVertices;
+
+ // EXT_tessellation_shader shader layout qualifiers
+ int vertices;
+ TLayoutTessEvaluationType tesPrimitiveType;
+ TLayoutTessEvaluationType tesVertexSpacingType;
+ TLayoutTessEvaluationType tesOrderingType;
+ TLayoutTessEvaluationType tesPointType;
+
+ // EXT_blend_func_extended fragment output layout qualifier
+ int index;
+
+ // EXT_shader_framebuffer_fetch layout qualifiers.
+ int inputAttachmentIndex;
+ bool noncoherent;
+
+ // KHR_blend_equation_advanced layout qualifiers.
+ AdvancedBlendEquations advancedBlendEquations;
+
+ // D3D 11.3 Rasterizer Order Views (ROVs).
+ // This qualifier is only used internally by ANGLE; it is not visible to the application.
+ bool rasterOrdered;
+
+ private:
+ explicit constexpr TLayoutQualifier(int /*placeholder*/)
+ : location(-1),
+ locationsSpecified(0),
+ matrixPacking(EmpUnspecified),
+ blockStorage(EbsUnspecified),
+ localSize(-1),
+ binding(-1),
+ offset(-1),
+ pushConstant(false),
+ imageInternalFormat(EiifUnspecified),
+ numViews(-1),
+ yuv(false),
+ earlyFragmentTests(false),
+ primitiveType(EptUndefined),
+ invocations(0),
+ maxVertices(-1),
+ vertices(0),
+ tesPrimitiveType(EtetUndefined),
+ tesVertexSpacingType(EtetUndefined),
+ tesOrderingType(EtetUndefined),
+ tesPointType(EtetUndefined),
+ index(-1),
+ inputAttachmentIndex(-1),
+ noncoherent(false),
+ advancedBlendEquations(0),
+ rasterOrdered(false)
+ {}
+};
+
+struct TMemoryQualifier
+{
+ // Must have a trivial default constructor since it is used in YYSTYPE.
+ TMemoryQualifier() = default;
+
+ bool isEmpty() const
+ {
+ return !readonly && !writeonly && !coherent && !restrictQualifier && !volatileQualifier;
+ }
+
+ constexpr static TMemoryQualifier Create() { return TMemoryQualifier(0); }
+
+ // GLSL ES 3.10 Revision 4, 4.9 Memory Access Qualifiers
+ // An image can be qualified as both readonly and writeonly. It still can be can be used with
+ // imageSize().
+ bool readonly;
+ bool writeonly;
+ bool coherent;
+
+ // restrict and volatile are reserved keywords in C/C++
+ bool restrictQualifier;
+ bool volatileQualifier;
+
+ private:
+ explicit constexpr TMemoryQualifier(int /*placeholder*/)
+ : readonly(false),
+ writeonly(false),
+ coherent(false),
+ restrictQualifier(false),
+ volatileQualifier(false)
+ {}
+};
+
+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";
+ }
+}
+
+// Used for GLSL generation, debugging and error messages.
+inline const char *getQualifierString(TQualifier q)
+{
+ // clang-format off
+ switch(q)
+ {
+ case EvqTemporary: return "Temporary";
+ case EvqGlobal: return "Global";
+ case EvqConst: return "const";
+ case EvqAttribute: return "attribute";
+ case EvqVaryingIn: return "varying";
+ case EvqVaryingOut: return "varying";
+ case EvqUniform: return "uniform";
+ case EvqBuffer: return "buffer";
+ case EvqPatch: return "patch";
+ case EvqVertexIn: return "in";
+ case EvqFragmentOut: return "out";
+ case EvqVertexOut: return "out";
+ case EvqFragmentIn: return "in";
+ case EvqParamIn: return "in";
+ case EvqParamOut: return "out";
+ case EvqParamInOut: return "inout";
+ case EvqParamConst: return "const";
+ case EvqInstanceID: return "InstanceID";
+ case EvqVertexID: return "VertexID";
+ case EvqPosition: return "Position";
+ case EvqPointSize: return "PointSize";
+ case EvqDrawID: return "DrawID";
+ case EvqFragCoord: return "FragCoord";
+ case EvqFrontFacing: return "FrontFacing";
+ case EvqHelperInvocation: return "HelperInvocation";
+ case EvqPointCoord: return "PointCoord";
+ case EvqFragColor: return "FragColor";
+ case EvqFragData: return "FragData";
+ case EvqFragDepth: return "FragDepth";
+ case EvqSecondaryFragColorEXT: return "SecondaryFragColorEXT";
+ case EvqSecondaryFragDataEXT: return "SecondaryFragDataEXT";
+ case EvqViewIDOVR: return "ViewIDOVR";
+ case EvqViewportIndex: return "ViewportIndex";
+ case EvqLayerOut: return "LayerOut";
+ case EvqLayerIn: return "LayerIn";
+ case EvqLastFragColor: return "LastFragColor";
+ case EvqLastFragData: return "LastFragData";
+ case EvqFragmentInOut: return "inout";
+ case EvqSmoothOut: return "smooth out";
+ case EvqCentroidOut: return "smooth centroid out";
+ case EvqFlatOut: return "flat out";
+ case EvqNoPerspectiveOut: return "noperspective out";
+ case EvqSmoothIn: return "smooth in";
+ case EvqFlatIn: return "flat in";
+ case EvqNoPerspectiveIn: return "noperspective in";
+ case EvqCentroidIn: return "smooth centroid in";
+ case EvqCentroid: return "centroid";
+ case EvqFlat: return "flat";
+ case EvqNoPerspective: return "noperspective";
+ case EvqSmooth: return "smooth";
+ case EvqShared: return "shared";
+ 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";
+ case EvqReadOnly: return "readonly";
+ case EvqWriteOnly: return "writeonly";
+ case EvqGeometryIn: return "in";
+ case EvqGeometryOut: return "out";
+ case EvqPerVertexIn: return "gl_in";
+ case EvqPrimitiveIDIn: return "gl_PrimitiveIDIn";
+ case EvqInvocationID: return "gl_InvocationID";
+ case EvqPrimitiveID: return "gl_PrimitiveID";
+ case EvqPrecise: return "precise";
+ case EvqClipDistance: return "ClipDistance";
+ case EvqCullDistance: return "CullDistance";
+ case EvqSample: return "sample";
+ case EvqSampleIn: return "sample in";
+ case EvqSampleOut: return "sample out";
+ case EvqSampleID: return "SampleID";
+ case EvqSamplePosition: return "SamplePosition";
+ case EvqSampleMaskIn: return "SampleMaskIn";
+ case EvqSampleMask: return "SampleMask";
+ case EvqNumSamples: return "NumSamples";
+ case EvqPatchIn: return "patch in";
+ case EvqPatchOut: return "patch out";
+ case EvqTessControlIn: return "in";
+ case EvqTessControlOut: return "out";
+ case EvqPerVertexOut: return "gl_out";
+ case EvqPatchVerticesIn: return "PatchVerticesIn";
+ case EvqTessLevelOuter: return "TessLevelOuter";
+ case EvqTessLevelInner: return "TessLevelInner";
+ case EvqBoundingBox: return "BoundingBox";
+ case EvqTessEvaluationIn: return "in";
+ case EvqTessEvaluationOut: return "out";
+ case EvqTessCoord: return "TessCoord";
+ case EvqSpecConst: return "const";
+ default: UNREACHABLE(); return "unknown qualifier";
+ }
+ // clang-format on
+}
+
+inline const char *getMatrixPackingString(TLayoutMatrixPacking mpq)
+{
+ switch (mpq)
+ {
+ case EmpUnspecified:
+ return "mp_unspecified";
+ case EmpRowMajor:
+ return "row_major";
+ case EmpColumnMajor:
+ return "column_major";
+ default:
+ UNREACHABLE();
+ return "unknown matrix packing";
+ }
+}
+
+inline const char *getBlockStorageString(TLayoutBlockStorage bsq)
+{
+ switch (bsq)
+ {
+ case EbsUnspecified:
+ return "bs_unspecified";
+ case EbsShared:
+ return "shared";
+ case EbsPacked:
+ return "packed";
+ case EbsStd140:
+ return "std140";
+ case EbsStd430:
+ return "std430";
+ default:
+ UNREACHABLE();
+ return "unknown block storage";
+ }
+}
+
+inline const char *getImageInternalFormatString(TLayoutImageInternalFormat iifq)
+{
+ switch (iifq)
+ {
+ case EiifRGBA32F:
+ return "rgba32f";
+ case EiifRGBA16F:
+ return "rgba16f";
+ case EiifR32F:
+ return "r32f";
+ case EiifRGBA32UI:
+ return "rgba32ui";
+ case EiifRGBA16UI:
+ return "rgba16ui";
+ case EiifRGBA8UI:
+ return "rgba8ui";
+ case EiifR32UI:
+ return "r32ui";
+ case EiifRGBA32I:
+ return "rgba32i";
+ case EiifRGBA16I:
+ return "rgba16i";
+ case EiifRGBA8I:
+ return "rgba8i";
+ case EiifR32I:
+ return "r32i";
+ case EiifRGBA8:
+ return "rgba8";
+ case EiifRGBA8_SNORM:
+ return "rgba8_snorm";
+ default:
+ UNREACHABLE();
+ return "unknown internal image format";
+ }
+}
+
+inline TYuvCscStandardEXT getYuvCscStandardEXT(const ImmutableString &str)
+{
+ if (str == "itu_601")
+ return EycsItu601;
+ else if (str == "itu_601_full_range")
+ return EycsItu601FullRange;
+ else if (str == "itu_709")
+ return EycsItu709;
+ return EycsUndefined;
+}
+
+inline const char *getYuvCscStandardEXTString(TYuvCscStandardEXT ycsq)
+{
+ switch (ycsq)
+ {
+ case EycsItu601:
+ return "itu_601";
+ case EycsItu601FullRange:
+ return "itu_601_full_range";
+ case EycsItu709:
+ return "itu_709";
+ default:
+ UNREACHABLE();
+ return "unknown color space conversion standard";
+ }
+}
+
+inline const char *getGeometryShaderPrimitiveTypeString(TLayoutPrimitiveType primitiveType)
+{
+ switch (primitiveType)
+ {
+ case EptPoints:
+ return "points";
+ case EptLines:
+ return "lines";
+ case EptTriangles:
+ return "triangles";
+ case EptLinesAdjacency:
+ return "lines_adjacency";
+ case EptTrianglesAdjacency:
+ return "triangles_adjacency";
+ case EptLineStrip:
+ return "line_strip";
+ case EptTriangleStrip:
+ return "triangle_strip";
+ default:
+ UNREACHABLE();
+ return "unknown geometry shader primitive type";
+ }
+}
+
+inline const char *getTessEvaluationShaderTypeString(TLayoutTessEvaluationType type)
+{
+ switch (type)
+ {
+ case EtetTriangles:
+ return "triangles";
+ case EtetQuads:
+ return "quads";
+ case EtetIsolines:
+ return "isolines";
+ case EtetEqualSpacing:
+ return "equal_spacing";
+ case EtetFractionalEvenSpacing:
+ return "fractional_even_spacing";
+ case EtetFractionalOddSpacing:
+ return "fractional_odd_spacing";
+ case EtetCw:
+ return "cw";
+ case EtetCcw:
+ return "ccw";
+ case EtetPointMode:
+ return "point_mode";
+ default:
+ UNREACHABLE();
+ return "unknown tessellation evaluation shader variable type";
+ }
+}
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_BASETYPES_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulator.cpp b/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulator.cpp
new file mode 100644
index 0000000000..34b43365cf
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulator.cpp
@@ -0,0 +1,161 @@
+//
+// Copyright 2002 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/BuiltInFunctionEmulator.h"
+#include "angle_gl.h"
+#include "compiler/translator/Symbol.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+class BuiltInFunctionEmulator::BuiltInFunctionEmulationMarker : public TIntermTraverser
+{
+ public:
+ BuiltInFunctionEmulationMarker(BuiltInFunctionEmulator &emulator)
+ : TIntermTraverser(true, false, false), mEmulator(emulator)
+ {}
+
+ bool visitUnary(Visit visit, TIntermUnary *node) override
+ {
+ if (node->getFunction())
+ {
+ bool needToEmulate = mEmulator.setFunctionCalled(node->getFunction());
+ if (needToEmulate)
+ node->setUseEmulatedFunction();
+ }
+ return true;
+ }
+
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override
+ {
+ // Here we handle all the math built-in functions, not just the ones that are currently
+ // identified as problematic.
+ if (!BuiltInGroup::IsMath(node->getOp()))
+ {
+ return true;
+ }
+ bool needToEmulate = mEmulator.setFunctionCalled(node->getFunction());
+ if (needToEmulate)
+ node->setUseEmulatedFunction();
+ return true;
+ }
+
+ private:
+ BuiltInFunctionEmulator &mEmulator;
+};
+
+BuiltInFunctionEmulator::BuiltInFunctionEmulator() {}
+
+void BuiltInFunctionEmulator::addEmulatedFunction(const TSymbolUniqueId &uniqueId,
+ const char *emulatedFunctionDefinition)
+{
+ mEmulatedFunctions[uniqueId.get()] = std::string(emulatedFunctionDefinition);
+}
+
+void BuiltInFunctionEmulator::addEmulatedFunctionWithDependency(
+ const TSymbolUniqueId &dependency,
+ const TSymbolUniqueId &uniqueId,
+ const char *emulatedFunctionDefinition)
+{
+ mEmulatedFunctions[uniqueId.get()] = std::string(emulatedFunctionDefinition);
+ mFunctionDependencies[uniqueId.get()] = dependency.get();
+}
+
+bool BuiltInFunctionEmulator::isOutputEmpty() const
+{
+ return (mFunctions.size() == 0);
+}
+
+void BuiltInFunctionEmulator::outputEmulatedFunctions(TInfoSinkBase &out) const
+{
+ for (const auto &function : mFunctions)
+ {
+ const char *body = findEmulatedFunction(function);
+ ASSERT(body);
+ out << body;
+ out << "\n\n";
+ }
+}
+
+const char *BuiltInFunctionEmulator::findEmulatedFunction(int uniqueId) const
+{
+ for (const auto &queryFunction : mQueryFunctions)
+ {
+ const char *result = queryFunction(uniqueId);
+ if (result)
+ {
+ return result;
+ }
+ }
+
+ const auto &result = mEmulatedFunctions.find(uniqueId);
+ if (result != mEmulatedFunctions.end())
+ {
+ return result->second.c_str();
+ }
+
+ return nullptr;
+}
+
+bool BuiltInFunctionEmulator::setFunctionCalled(const TFunction *function)
+{
+ ASSERT(function != nullptr);
+ return setFunctionCalled(function->uniqueId().get());
+}
+
+bool BuiltInFunctionEmulator::setFunctionCalled(int uniqueId)
+{
+ if (!findEmulatedFunction(uniqueId))
+ {
+ return false;
+ }
+
+ for (size_t i = 0; i < mFunctions.size(); ++i)
+ {
+ if (mFunctions[i] == uniqueId)
+ return true;
+ }
+ // If the function depends on another, mark the dependency as called.
+ auto dependency = mFunctionDependencies.find(uniqueId);
+ if (dependency != mFunctionDependencies.end())
+ {
+ setFunctionCalled((*dependency).second);
+ }
+ mFunctions.push_back(uniqueId);
+ return true;
+}
+
+void BuiltInFunctionEmulator::markBuiltInFunctionsForEmulation(TIntermNode *root)
+{
+ ASSERT(root);
+
+ if (mEmulatedFunctions.empty() && mQueryFunctions.empty())
+ return;
+
+ BuiltInFunctionEmulationMarker marker(*this);
+ root->traverse(&marker);
+}
+
+void BuiltInFunctionEmulator::cleanup()
+{
+ mFunctions.clear();
+ mFunctionDependencies.clear();
+}
+
+void BuiltInFunctionEmulator::addFunctionMap(BuiltinQueryFunc queryFunc)
+{
+ mQueryFunctions.push_back(queryFunc);
+}
+
+// static
+void BuiltInFunctionEmulator::WriteEmulatedFunctionName(TInfoSinkBase &out, const char *name)
+{
+ ASSERT(name[strlen(name) - 1] != '(');
+ out << name << "_emu";
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulator.h b/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulator.h
new file mode 100644
index 0000000000..7ebd6bc087
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulator.h
@@ -0,0 +1,80 @@
+//
+// Copyright 2011 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_BUILTINFUNCTIONEMULATOR_H_
+#define COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATOR_H_
+
+#include "compiler/translator/InfoSink.h"
+
+namespace sh
+{
+
+class TIntermNode;
+class TFunction;
+class TSymbolUniqueId;
+
+using BuiltinQueryFunc = const char *(int);
+
+//
+// This class decides which built-in functions need to be replaced with the emulated ones. It can be
+// used to work around driver bugs or implement functions that are not natively implemented on a
+// specific platform.
+//
+class BuiltInFunctionEmulator
+{
+ public:
+ BuiltInFunctionEmulator();
+
+ void markBuiltInFunctionsForEmulation(TIntermNode *root);
+
+ void cleanup();
+
+ // "name" gets written as "name_emu".
+ static void WriteEmulatedFunctionName(TInfoSinkBase &out, const char *name);
+
+ bool isOutputEmpty() const;
+
+ // Output function emulation definition. This should be before any other shader source.
+ void outputEmulatedFunctions(TInfoSinkBase &out) const;
+
+ // Add functions that need to be emulated.
+ void addEmulatedFunction(const TSymbolUniqueId &uniqueId,
+ const char *emulatedFunctionDefinition);
+
+ void addEmulatedFunctionWithDependency(const TSymbolUniqueId &dependency,
+ const TSymbolUniqueId &uniqueId,
+ const char *emulatedFunctionDefinition);
+
+ void addFunctionMap(BuiltinQueryFunc queryFunc);
+
+ private:
+ class BuiltInFunctionEmulationMarker;
+
+ // Records that a function is called by the shader and might need to be emulated. If the
+ // function is not in mEmulatedFunctions, this becomes a no-op. Returns true if the function
+ // call needs to be replaced with an emulated one.
+ bool setFunctionCalled(const TFunction *function);
+ bool setFunctionCalled(int uniqueId);
+
+ const char *findEmulatedFunction(int uniqueId) const;
+
+ // Map from function unique id to emulated function definition
+ std::map<int, std::string> mEmulatedFunctions;
+
+ // Map from dependent functions to their dependencies. This structure allows each function to
+ // have at most one dependency.
+ std::map<int, int> mFunctionDependencies;
+
+ // Called function ids
+ std::vector<int> mFunctions;
+
+ // Constexpr function tables.
+ std::vector<BuiltinQueryFunc *> mQueryFunctions;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATOR_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp b/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp
new file mode 100644
index 0000000000..9212336585
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorGLSL.cpp
@@ -0,0 +1,284 @@
+//
+// Copyright 2002 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/BuiltInFunctionEmulatorGLSL.h"
+
+#include "angle_gl.h"
+#include "compiler/translator/BuiltInFunctionEmulator.h"
+#include "compiler/translator/VersionGLSL.h"
+#include "compiler/translator/tree_util/BuiltIn.h"
+
+namespace sh
+{
+
+void InitBuiltInAbsFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu,
+ sh::GLenum shaderType)
+{
+ if (shaderType == GL_VERTEX_SHADER)
+ {
+ emu->addEmulatedFunction(BuiltInId::abs_Int1, "int 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;
+
+ // !(x > 0.0 || x < 0.0 || x == 0.0) will be optimized and always equal to false.
+ emu->addEmulatedFunction(
+ BuiltInId::isnan_Float1,
+ "bool isnan_emu(float x) { return (x > 0.0 || x < 0.0) ? false : x != 0.0; }");
+ emu->addEmulatedFunction(
+ BuiltInId::isnan_Float2,
+ "bvec2 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(
+ BuiltInId::isnan_Float3,
+ "bvec3 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(
+ BuiltInId::isnan_Float4,
+ "bvec4 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");
+}
+
+void InitBuiltInAtanFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu)
+{
+ emu->addEmulatedFunction(BuiltInId::atan_Float1_Float1,
+ "emu_precision float atan_emu(emu_precision float y, emu_precision "
+ "float x)\n"
+ "{\n"
+ " if (x > 0.0) return atan(y / x);\n"
+ " else if (x < 0.0 && y >= 0.0) return atan(y / x) + 3.14159265;\n"
+ " else if (x < 0.0 && y < 0.0) return atan(y / x) - 3.14159265;\n"
+ " else return 1.57079632 * sign(y);\n"
+ "}\n");
+ static const std::array<TSymbolUniqueId, 4> ids = {
+ BuiltInId::atan_Float1_Float1,
+ BuiltInId::atan_Float2_Float2,
+ BuiltInId::atan_Float3_Float3,
+ BuiltInId::atan_Float4_Float4,
+ };
+ for (int dim = 2; dim <= 4; ++dim)
+ {
+ std::stringstream ss = sh::InitializeStream<std::stringstream>();
+ ss << "emu_precision vec" << dim << " atan_emu(emu_precision vec" << dim
+ << " y, emu_precision vec" << dim << " x)\n"
+ << "{\n"
+ " return vec"
+ << dim << "(";
+ for (int i = 0; i < dim; ++i)
+ {
+ ss << "atan_emu(y[" << i << "], x[" << i << "])";
+ if (i < dim - 1)
+ {
+ ss << ", ";
+ }
+ }
+ ss << ");\n"
+ "}\n";
+ emu->addEmulatedFunctionWithDependency(BuiltInId::atan_Float1_Float1, ids[dim - 1],
+ ss.str().c_str());
+ }
+}
+
+// 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)
+ {
+ // clang-format off
+ emu->addEmulatedFunction(BuiltInId::packUnorm2x16_Float2,
+ "uint 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(BuiltInId::unpackUnorm2x16_UInt1,
+ "vec2 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)
+ {
+ // clang-format off
+ emu->addEmulatedFunction(BuiltInId::packSnorm2x16_Float2,
+ "uint packSnorm2x16_emu(vec2 v)\n"
+ "{\n"
+ " #if defined(GL_ARB_shading_language_packing)\n"
+ " return packSnorm2x16(v);\n"
+ " #else\n"
+ " int x = int(round(clamp(v.x, -1.0, 1.0) * 32767.0));\n"
+ " int y = int(round(clamp(v.y, -1.0, 1.0) * 32767.0));\n"
+ " return uint((y << 16) | (x & 0xFFFF));\n"
+ " #endif\n"
+ "}\n");
+ emu->addEmulatedFunction(BuiltInId::unpackSnorm2x16_UInt1,
+ "#if !defined(GL_ARB_shading_language_packing)\n"
+ " float fromSnorm(uint x)\n"
+ " {\n"
+ " int xi = (int(x) & 0x7FFF) - (int(x) & 0x8000);\n"
+ " return clamp(float(xi) / 32767.0, -1.0, 1.0);\n"
+ " }\n"
+ "#endif\n"
+ "\n"
+ "vec2 unpackSnorm2x16_emu(uint u)\n"
+ "{\n"
+ " #if defined(GL_ARB_shading_language_packing)\n"
+ " return unpackSnorm2x16(u);\n"
+ " #else\n"
+ " uint y = (u >> 16);\n"
+ " uint x = u;\n"
+ " return vec2(fromSnorm(x), fromSnorm(y));\n"
+ " #endif\n"
+ "}\n");
+ // Functions uint f32tof16(float val) and float f16tof32(uint val) are
+ // based on the OpenGL redbook Appendix Session "Floating-Point Formats Used in OpenGL".
+ emu->addEmulatedFunction(BuiltInId::packHalf2x16_Float2,
+ "#if !defined(GL_ARB_shading_language_packing)\n"
+ " uint f32tof16(float val)\n"
+ " {\n"
+ " uint f32 = floatBitsToUint(val);\n"
+ " uint f16 = 0u;\n"
+ " uint sign = (f32 >> 16) & 0x8000u;\n"
+ " int exponent = int((f32 >> 23) & 0xFFu) - 127;\n"
+ " uint mantissa = f32 & 0x007FFFFFu;\n"
+ " if (exponent == 128)\n"
+ " {\n"
+ " // Infinity or NaN\n"
+ " // NaN bits that are masked out by 0x3FF get discarded.\n"
+ " // This can turn some NaNs to infinity, but this is allowed by the spec.\n"
+ " f16 = sign | (0x1Fu << 10);\n"
+ " f16 |= (mantissa & 0x3FFu);\n"
+ " }\n"
+ " else if (exponent > 15)\n"
+ " {\n"
+ " // Overflow - flush to Infinity\n"
+ " f16 = sign | (0x1Fu << 10);\n"
+ " }\n"
+ " else if (exponent > -15)\n"
+ " {\n"
+ " // Representable value\n"
+ " exponent += 15;\n"
+ " mantissa >>= 13;\n"
+ " f16 = sign | uint(exponent << 10) | mantissa;\n"
+ " }\n"
+ " else\n"
+ " {\n"
+ " f16 = sign;\n"
+ " }\n"
+ " return f16;\n"
+ " }\n"
+ "#endif\n"
+ "\n"
+ "uint packHalf2x16_emu(vec2 v)\n"
+ "{\n"
+ " #if defined(GL_ARB_shading_language_packing)\n"
+ " return packHalf2x16(v);\n"
+ " #else\n"
+ " uint x = f32tof16(v.x);\n"
+ " uint y = f32tof16(v.y);\n"
+ " return (y << 16) | x;\n"
+ " #endif\n"
+ "}\n");
+ emu->addEmulatedFunction(BuiltInId::unpackHalf2x16_UInt1,
+ "#if !defined(GL_ARB_shading_language_packing)\n"
+ " float f16tof32(uint val)\n"
+ " {\n"
+ " uint sign = (val & 0x8000u) << 16;\n"
+ " int exponent = int((val & 0x7C00u) >> 10);\n"
+ " uint mantissa = val & 0x03FFu;\n"
+ " float f32 = 0.0;\n"
+ " if(exponent == 0)\n"
+ " {\n"
+ " if (mantissa != 0u)\n"
+ " {\n"
+ " const float scale = 1.0 / (1 << 24);\n"
+ " f32 = scale * mantissa;\n"
+ " }\n"
+ " }\n"
+ " else if (exponent == 31)\n"
+ " {\n"
+ " return uintBitsToFloat(sign | 0x7F800000u | mantissa);\n"
+ " }\n"
+ " else\n"
+ " {\n"
+ " exponent -= 15;\n"
+ " float scale;\n"
+ " if(exponent < 0)\n"
+ " {\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"
+ " scale = 1 << exponent;\n"
+ " }\n"
+ " float decimal = 1.0 + float(mantissa) / float(1 << 10);\n"
+ " f32 = scale * decimal;\n"
+ " }\n"
+ "\n"
+ " if (sign != 0u)\n"
+ " {\n"
+ " f32 = -f32;\n"
+ " }\n"
+ "\n"
+ " return f32;\n"
+ " }\n"
+ "#endif\n"
+ "\n"
+ "vec2 unpackHalf2x16_emu(uint u)\n"
+ "{\n"
+ " #if defined(GL_ARB_shading_language_packing)\n"
+ " return unpackHalf2x16(u);\n"
+ " #else\n"
+ " uint y = (u >> 16);\n"
+ " uint x = u & 0xFFFFu;\n"
+ " return vec2(f16tof32(x), f16tof32(y));\n"
+ " #endif\n"
+ "}\n");
+ // clang-format on
+ }
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorGLSL.h b/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorGLSL.h
new file mode 100644
index 0000000000..91ba67f3aa
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorGLSL.h
@@ -0,0 +1,40 @@
+//
+// Copyright 2011 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_BUILTINFUNCTIONEMULATORGLSL_H_
+#define COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATORGLSL_H_
+
+#include "GLSLANG/ShaderLang.h"
+
+namespace sh
+{
+class BuiltInFunctionEmulator;
+
+//
+// This works around bug in Intel Mac drivers.
+//
+void InitBuiltInAbsFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu,
+ sh::GLenum shaderType);
+
+//
+// This works around isnan() bug in Intel Mac drivers
+//
+void InitBuiltInIsnanFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu,
+ int targetGLSLVersion);
+//
+// This works around atan(y, x) bug in NVIDIA drivers.
+//
+void InitBuiltInAtanFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu);
+
+//
+// This function is emulating built-in functions missing from GLSL 1.30 and higher.
+//
+void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator *emu,
+ sh::GLenum shaderType,
+ int targetGLSLVersion);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATORGLSL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp b/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp
new file mode 100644
index 0000000000..66a0be39e7
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp
@@ -0,0 +1,173 @@
+//
+// 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.
+//
+
+#include "compiler/translator/BuiltInFunctionEmulatorHLSL.h"
+#include "angle_gl.h"
+#include "compiler/translator/BuiltInFunctionEmulator.h"
+#include "compiler/translator/VersionGLSL.h"
+#include "compiler/translator/tree_util/BuiltIn.h"
+
+namespace sh
+{
+
+// Defined in emulated_builtin_functions_hlsl_autogen.cpp.
+const char *FindHLSLFunction(int uniqueId);
+
+void InitBuiltInIsnanFunctionEmulatorForHLSLWorkarounds(BuiltInFunctionEmulator *emu,
+ int targetGLSLVersion)
+{
+ if (targetGLSLVersion < GLSL_VERSION_130)
+ return;
+
+ emu->addEmulatedFunction(BuiltInId::isnan_Float1,
+ "bool isnan_emu(float x)\n"
+ "{\n"
+ " return (x > 0.0 || x < 0.0) ? false : x != 0.0;\n"
+ "}\n"
+ "\n");
+
+ emu->addEmulatedFunction(
+ BuiltInId::isnan_Float2,
+ "bool2 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(
+ BuiltInId::isnan_Float3,
+ "bool3 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(
+ BuiltInId::isnan_Float4,
+ "bool4 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)
+{
+ emu->addFunctionMap(FindHLSLFunction);
+
+ // (a + b2^16) * (c + d2^16) = ac + (ad + bc) * 2^16 + bd * 2^32
+ // Also note that below, a * d + ((a * c) >> 16) is guaranteed not to overflow, because:
+ // a <= 0xffff, d <= 0xffff, ((a * c) >> 16) <= 0xffff and 0xffff * 0xffff + 0xffff = 0xffff0000
+ emu->addEmulatedFunction(BuiltInId::umulExtended_UInt1_UInt1_UInt1_UInt1,
+ "void umulExtended_emu(uint x, uint y, out uint msb, out uint lsb)\n"
+ "{\n"
+ " lsb = x * y;\n"
+ " uint a = (x & 0xffffu);\n"
+ " uint b = (x >> 16);\n"
+ " uint c = (y & 0xffffu);\n"
+ " uint d = (y >> 16);\n"
+ " uint ad = a * d + ((a * c) >> 16);\n"
+ " uint bc = b * c;\n"
+ " uint carry = uint(ad > (0xffffffffu - bc));\n"
+ " msb = ((ad + bc) >> 16) + (carry << 16) + b * d;\n"
+ "}\n");
+ emu->addEmulatedFunctionWithDependency(
+ BuiltInId::umulExtended_UInt1_UInt1_UInt1_UInt1,
+ BuiltInId::umulExtended_UInt2_UInt2_UInt2_UInt2,
+ "void umulExtended_emu(uint2 x, uint2 y, out uint2 msb, out uint2 lsb)\n"
+ "{\n"
+ " umulExtended_emu(x.x, y.x, msb.x, lsb.x);\n"
+ " umulExtended_emu(x.y, y.y, msb.y, lsb.y);\n"
+ "}\n");
+ emu->addEmulatedFunctionWithDependency(
+ BuiltInId::umulExtended_UInt1_UInt1_UInt1_UInt1,
+ BuiltInId::umulExtended_UInt3_UInt3_UInt3_UInt3,
+ "void umulExtended_emu(uint3 x, uint3 y, out uint3 msb, out uint3 lsb)\n"
+ "{\n"
+ " umulExtended_emu(x.x, y.x, msb.x, lsb.x);\n"
+ " umulExtended_emu(x.y, y.y, msb.y, lsb.y);\n"
+ " umulExtended_emu(x.z, y.z, msb.z, lsb.z);\n"
+ "}\n");
+ emu->addEmulatedFunctionWithDependency(
+ BuiltInId::umulExtended_UInt1_UInt1_UInt1_UInt1,
+ BuiltInId::umulExtended_UInt4_UInt4_UInt4_UInt4,
+ "void umulExtended_emu(uint4 x, uint4 y, out uint4 msb, out uint4 lsb)\n"
+ "{\n"
+ " umulExtended_emu(x.x, y.x, msb.x, lsb.x);\n"
+ " umulExtended_emu(x.y, y.y, msb.y, lsb.y);\n"
+ " umulExtended_emu(x.z, y.z, msb.z, lsb.z);\n"
+ " umulExtended_emu(x.w, y.w, msb.w, lsb.w);\n"
+ "}\n");
+
+ // The imul emulation does two's complement negation on the lsb and msb manually in case the
+ // result needs to be negative.
+ // TODO(oetuaho): Note that this code doesn't take one edge case into account, where x or y is
+ // -2^31. abs(-2^31) is undefined.
+ emu->addEmulatedFunctionWithDependency(
+ BuiltInId::umulExtended_UInt1_UInt1_UInt1_UInt1,
+ BuiltInId::imulExtended_Int1_Int1_Int1_Int1,
+ "void imulExtended_emu(int x, int y, out int msb, out int lsb)\n"
+ "{\n"
+ " uint unsignedMsb;\n"
+ " uint unsignedLsb;\n"
+ " bool negative = (x < 0) != (y < 0);\n"
+ " umulExtended_emu(uint(abs(x)), uint(abs(y)), unsignedMsb, unsignedLsb);\n"
+ " lsb = asint(unsignedLsb);\n"
+ " msb = asint(unsignedMsb);\n"
+ " if (negative)\n"
+ " {\n"
+ " lsb = ~lsb;\n"
+ " msb = ~msb;\n"
+ " if (lsb == 0xffffffff)\n"
+ " {\n"
+ " lsb = 0;\n"
+ " msb += 1;\n"
+ " }\n"
+ " else\n"
+ " {\n"
+ " lsb += 1;\n"
+ " }\n"
+ " }\n"
+ "}\n");
+ emu->addEmulatedFunctionWithDependency(
+ BuiltInId::imulExtended_Int1_Int1_Int1_Int1, BuiltInId::imulExtended_Int2_Int2_Int2_Int2,
+ "void imulExtended_emu(int2 x, int2 y, out int2 msb, out int2 lsb)\n"
+ "{\n"
+ " imulExtended_emu(x.x, y.x, msb.x, lsb.x);\n"
+ " imulExtended_emu(x.y, y.y, msb.y, lsb.y);\n"
+ "}\n");
+ emu->addEmulatedFunctionWithDependency(
+ BuiltInId::imulExtended_Int1_Int1_Int1_Int1, BuiltInId::imulExtended_Int3_Int3_Int3_Int3,
+ "void imulExtended_emu(int3 x, int3 y, out int3 msb, out int3 lsb)\n"
+ "{\n"
+ " imulExtended_emu(x.x, y.x, msb.x, lsb.x);\n"
+ " imulExtended_emu(x.y, y.y, msb.y, lsb.y);\n"
+ " imulExtended_emu(x.z, y.z, msb.z, lsb.z);\n"
+ "}\n");
+ emu->addEmulatedFunctionWithDependency(
+ BuiltInId::imulExtended_Int1_Int1_Int1_Int1, BuiltInId::imulExtended_Int4_Int4_Int4_Int4,
+ "void imulExtended_emu(int4 x, int4 y, out int4 msb, out int4 lsb)\n"
+ "{\n"
+ " imulExtended_emu(x.x, y.x, msb.x, lsb.x);\n"
+ " imulExtended_emu(x.y, y.y, msb.y, lsb.y);\n"
+ " imulExtended_emu(x.z, y.z, msb.z, lsb.z);\n"
+ " imulExtended_emu(x.w, y.w, msb.w, lsb.w);\n"
+ "}\n");
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorHLSL.h b/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorHLSL.h
new file mode 100644
index 0000000000..e5c6070fe6
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/BuiltInFunctionEmulatorHLSL.h
@@ -0,0 +1,27 @@
+//
+// 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.
+//
+
+#ifndef COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATORHLSL_H_
+#define COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATORHLSL_H_
+
+#include "GLSLANG/ShaderLang.h"
+
+namespace sh
+{
+
+class BuiltInFunctionEmulator;
+
+void InitBuiltInFunctionEmulatorForHLSL(BuiltInFunctionEmulator *emu);
+
+//
+// This works around isnan() bug on some Intel drivers.
+//
+void InitBuiltInIsnanFunctionEmulatorForHLSLWorkarounds(BuiltInFunctionEmulator *emu,
+ int targetGLSLVersion);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_BUILTINFUNCTIONEMULATORHLSL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/BuiltinsWorkaroundGLSL.cpp b/gfx/angle/checkout/src/compiler/translator/BuiltinsWorkaroundGLSL.cpp
new file mode 100644
index 0000000000..6409f85c3c
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/BuiltinsWorkaroundGLSL.cpp
@@ -0,0 +1,109 @@
+//
+// Copyright 2019 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/BuiltinsWorkaroundGLSL.h"
+
+#include "angle_gl.h"
+#include "compiler/translator/Symbol.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/BuiltIn.h"
+
+namespace sh
+{
+
+namespace
+{
+constexpr const ImmutableString kGlInstanceIDString("gl_InstanceID");
+constexpr const ImmutableString kGlVertexIDString("gl_VertexID");
+
+class TBuiltinsWorkaroundGLSL : public TIntermTraverser
+{
+ public:
+ TBuiltinsWorkaroundGLSL(TSymbolTable *symbolTable, const ShCompileOptions &options);
+
+ void visitSymbol(TIntermSymbol *node) override;
+ bool visitDeclaration(Visit, TIntermDeclaration *node) override;
+
+ private:
+ void ensureVersionIsAtLeast(int version);
+
+ const ShCompileOptions &mCompileOptions;
+
+ bool isBaseInstanceDeclared = false;
+};
+
+TBuiltinsWorkaroundGLSL::TBuiltinsWorkaroundGLSL(TSymbolTable *symbolTable,
+ const ShCompileOptions &options)
+ : TIntermTraverser(true, false, false, symbolTable), mCompileOptions(options)
+{}
+
+void TBuiltinsWorkaroundGLSL::visitSymbol(TIntermSymbol *node)
+{
+ if (node->variable().symbolType() == SymbolType::BuiltIn)
+ {
+ if (node->getName() == kGlInstanceIDString)
+ {
+ TIntermSymbol *instanceIndexRef =
+ new TIntermSymbol(BuiltInVariable::gl_InstanceIndex());
+
+ if (isBaseInstanceDeclared)
+ {
+ TIntermSymbol *baseInstanceRef =
+ new TIntermSymbol(BuiltInVariable::angle_BaseInstance());
+
+ TIntermBinary *subBaseInstance =
+ new TIntermBinary(EOpSub, instanceIndexRef, baseInstanceRef);
+ queueReplacement(subBaseInstance, OriginalNode::IS_DROPPED);
+ }
+ else
+ {
+ queueReplacement(instanceIndexRef, OriginalNode::IS_DROPPED);
+ }
+ }
+ else if (node->getName() == kGlVertexIDString)
+ {
+ TIntermSymbol *vertexIndexRef = new TIntermSymbol(BuiltInVariable::gl_VertexIndex());
+ queueReplacement(vertexIndexRef, OriginalNode::IS_DROPPED);
+ }
+ }
+}
+
+bool TBuiltinsWorkaroundGLSL::visitDeclaration(Visit, TIntermDeclaration *node)
+{
+ const TIntermSequence &sequence = *(node->getSequence());
+ ASSERT(!sequence.empty());
+
+ for (TIntermNode *variableNode : sequence)
+ {
+ TIntermSymbol *variable = variableNode->getAsSymbolNode();
+ if (variable && variable->variable().symbolType() == SymbolType::BuiltIn)
+ {
+ if (variable->getName() == "angle_BaseInstance")
+ {
+ isBaseInstanceDeclared = true;
+ }
+ }
+ }
+ return true;
+}
+
+} // anonymous namespace
+
+[[nodiscard]] bool ShaderBuiltinsWorkaround(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ const ShCompileOptions &compileOptions)
+{
+ TBuiltinsWorkaroundGLSL builtins(symbolTable, compileOptions);
+ root->traverse(&builtins);
+ if (!builtins.updateTree(compiler, root))
+ {
+ return false;
+ }
+ return true;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/BuiltinsWorkaroundGLSL.h b/gfx/angle/checkout/src/compiler/translator/BuiltinsWorkaroundGLSL.h
new file mode 100644
index 0000000000..e49273dae9
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/BuiltinsWorkaroundGLSL.h
@@ -0,0 +1,24 @@
+//
+// Copyright 2019 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_BUILTINSWORKAROUNDGLSL_H_
+#define COMPILER_TRANSLATOR_BUILTINSWORKAROUNDGLSL_H_
+
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+#include "compiler/translator/Pragma.h"
+
+namespace sh
+{
+
+[[nodiscard]] bool ShaderBuiltinsWorkaround(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ const ShCompileOptions &compileOptions);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_BUILTINSWORKAROUNDGLSL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/CallDAG.cpp b/gfx/angle/checkout/src/compiler/translator/CallDAG.cpp
new file mode 100644
index 0000000000..5d47518eba
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/CallDAG.cpp
@@ -0,0 +1,316 @@
+//
+// Copyright 2002 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.
+//
+
+// CallDAG.h: Implements a call graph DAG of functions to be re-used accross
+// analyses, allows to efficiently traverse the functions in topological
+// order.
+
+#include "compiler/translator/CallDAG.h"
+
+#include "compiler/translator/Diagnostics.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+// The CallDAGCreator does all the processing required to create the CallDAG
+// structure so that the latter contains only the necessary variables.
+class CallDAG::CallDAGCreator : public TIntermTraverser
+{
+ public:
+ CallDAGCreator(TDiagnostics *diagnostics)
+ : TIntermTraverser(true, false, false),
+ mDiagnostics(diagnostics),
+ mCurrentFunction(nullptr),
+ mCurrentIndex(0)
+ {}
+
+ InitResult assignIndices()
+ {
+ int skipped = 0;
+ for (auto &it : mFunctions)
+ {
+ // Skip unimplemented functions
+ if (it.second.definitionNode)
+ {
+ InitResult result = assignIndicesInternal(&it.second);
+ if (result != INITDAG_SUCCESS)
+ {
+ return result;
+ }
+ }
+ else
+ {
+ skipped++;
+ }
+ }
+
+ ASSERT(mFunctions.size() == mCurrentIndex + skipped);
+ return INITDAG_SUCCESS;
+ }
+
+ void fillDataStructures(std::vector<Record> *records, std::map<int, int> *idToIndex)
+ {
+ ASSERT(records->empty());
+ ASSERT(idToIndex->empty());
+
+ records->resize(mCurrentIndex);
+
+ for (auto &it : mFunctions)
+ {
+ CreatorFunctionData &data = it.second;
+ // Skip unimplemented functions
+ if (!data.definitionNode)
+ {
+ continue;
+ }
+ ASSERT(data.index < records->size());
+ Record &record = (*records)[data.index];
+
+ record.node = data.definitionNode;
+
+ record.callees.reserve(data.callees.size());
+ for (auto &callee : data.callees)
+ {
+ record.callees.push_back(static_cast<int>(callee->index));
+ }
+
+ (*idToIndex)[it.first] = static_cast<int>(data.index);
+ }
+ }
+
+ private:
+ struct CreatorFunctionData
+ {
+ CreatorFunctionData()
+ : definitionNode(nullptr), name(""), index(0), indexAssigned(false), visiting(false)
+ {}
+
+ std::set<CreatorFunctionData *> callees;
+ TIntermFunctionDefinition *definitionNode;
+ ImmutableString name;
+ size_t index;
+ bool indexAssigned;
+ bool visiting;
+ };
+
+ bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override
+ {
+ // Create the record if need be and remember the definition node.
+ mCurrentFunction = &mFunctions[node->getFunction()->uniqueId().get()];
+ // Name will be overwritten here. If we've already traversed the prototype of this function,
+ // it should have had the same name.
+ ASSERT(mCurrentFunction->name == "" ||
+ mCurrentFunction->name == node->getFunction()->name());
+ mCurrentFunction->name = node->getFunction()->name();
+ mCurrentFunction->definitionNode = node;
+
+ node->getBody()->traverse(this);
+ mCurrentFunction = nullptr;
+ return false;
+ }
+
+ void visitFunctionPrototype(TIntermFunctionPrototype *node) override
+ {
+ ASSERT(mCurrentFunction == nullptr);
+
+ // Function declaration, create an empty record.
+ auto &record = mFunctions[node->getFunction()->uniqueId().get()];
+ record.name = node->getFunction()->name();
+ }
+
+ // Track functions called from another function.
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override
+ {
+ if (node->getOp() == EOpCallFunctionInAST)
+ {
+ // Function call, add the callees
+ auto it = mFunctions.find(node->getFunction()->uniqueId().get());
+ ASSERT(it != mFunctions.end());
+
+ // We might be traversing the initializer of a global variable. Even though function
+ // calls in global scope are forbidden by the parser, some subsequent AST
+ // transformations can add them to emulate particular features.
+ if (mCurrentFunction)
+ {
+ mCurrentFunction->callees.insert(&it->second);
+ }
+ }
+ return true;
+ }
+
+ // Recursively assigns indices to a sub DAG
+ InitResult assignIndicesInternal(CreatorFunctionData *root)
+ {
+ // 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).
+
+ ASSERT(root);
+
+ if (root->indexAssigned)
+ {
+ return INITDAG_SUCCESS;
+ }
+
+ // 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;
+
+ std::stringstream errorStream = sh::InitializeStream<std::stringstream>();
+
+ while (!functionsToProcess.empty())
+ {
+ CreatorFunctionData *function = functionsToProcess.back();
+
+ if (function->visiting)
+ {
+ function->visiting = false;
+ function->index = mCurrentIndex++;
+ function->indexAssigned = true;
+
+ functionsToProcess.pop_back();
+ continue;
+ }
+
+ if (!function->definitionNode)
+ {
+ errorStream << "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)
+ {
+ errorStream << "Recursive function call in the following call chain:";
+ result = INITDAG_RECURSION;
+ break;
+ }
+ }
+
+ if (result != INITDAG_SUCCESS)
+ {
+ break;
+ }
+ }
+
+ // The call chain is made of the function we were visiting when the error was detected.
+ if (result != INITDAG_SUCCESS)
+ {
+ bool first = true;
+ for (auto function : functionsToProcess)
+ {
+ if (function->visiting)
+ {
+ if (!first)
+ {
+ errorStream << " -> ";
+ }
+ errorStream << function->name << ")";
+ first = false;
+ }
+ }
+ if (mDiagnostics)
+ {
+ std::string errorStr = errorStream.str();
+ mDiagnostics->globalError(errorStr.c_str());
+ }
+ }
+
+ return result;
+ }
+
+ TDiagnostics *mDiagnostics;
+
+ std::map<int, CreatorFunctionData> mFunctions;
+ CreatorFunctionData *mCurrentFunction;
+ size_t mCurrentIndex;
+};
+
+// CallDAG
+
+CallDAG::CallDAG() {}
+
+CallDAG::~CallDAG() {}
+
+const size_t CallDAG::InvalidIndex = std::numeric_limits<size_t>::max();
+
+size_t CallDAG::findIndex(const TSymbolUniqueId &id) const
+{
+ auto it = mFunctionIdToIndex.find(id.get());
+
+ if (it == mFunctionIdToIndex.end())
+ {
+ return InvalidIndex;
+ }
+ else
+ {
+ return it->second;
+ }
+}
+
+const CallDAG::Record &CallDAG::getRecordFromIndex(size_t index) const
+{
+ ASSERT(index != InvalidIndex && index < mRecords.size());
+ return mRecords[index];
+}
+
+size_t CallDAG::size() const
+{
+ return mRecords.size();
+}
+
+void CallDAG::clear()
+{
+ mRecords.clear();
+ mFunctionIdToIndex.clear();
+}
+
+CallDAG::InitResult CallDAG::init(TIntermNode *root, TDiagnostics *diagnostics)
+{
+ CallDAGCreator creator(diagnostics);
+
+ // Creates the mapping of functions to callees
+ root->traverse(&creator);
+
+ // Does the topological sort and detects recursions
+ InitResult result = creator.assignIndices();
+ if (result != INITDAG_SUCCESS)
+ {
+ return result;
+ }
+
+ creator.fillDataStructures(&mRecords, &mFunctionIdToIndex);
+ return INITDAG_SUCCESS;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/CallDAG.h b/gfx/angle/checkout/src/compiler/translator/CallDAG.h
new file mode 100644
index 0000000000..7e80f2e855
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/CallDAG.h
@@ -0,0 +1,77 @@
+//
+// Copyright 2002 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.
+//
+
+// CallDAG.h: Defines a call graph DAG of functions to be re-used accross
+// analyses, allows to efficiently traverse the functions in topological
+// order.
+
+#ifndef COMPILER_TRANSLATOR_CALLDAG_H_
+#define COMPILER_TRANSLATOR_CALLDAG_H_
+
+#include <map>
+
+#include "compiler/translator/IntermNode.h"
+
+namespace sh
+{
+
+// The translator needs to analyze the the graph of the function calls
+// to run checks and analyses; since in GLSL recursion is not allowed
+// that graph is a DAG.
+// This class is used to precompute that function call DAG so that it
+// can be reused by multiple analyses.
+//
+// It stores a vector of function records, with one record per defined function.
+// Records are accessed by index but a function symbol id can be converted
+// to the index of the corresponding record. The records contain the AST node
+// of the function definition and the indices of the function's callees.
+//
+// In addition, records are in reverse topological order: a function F being
+// called by a function G will have index index(F) < index(G), that way
+// depth-first analysis becomes analysis in the order of indices.
+
+class CallDAG : angle::NonCopyable
+{
+ public:
+ CallDAG();
+ ~CallDAG();
+
+ struct Record
+ {
+ TIntermFunctionDefinition *node; // Guaranteed to be non-null.
+ std::vector<int> callees;
+ };
+
+ enum InitResult
+ {
+ INITDAG_SUCCESS,
+ INITDAG_RECURSION,
+ INITDAG_UNDEFINED,
+ };
+
+ // Returns INITDAG_SUCCESS if it was able to create the DAG, otherwise prints
+ // the initialization error in diagnostics, if present.
+ InitResult init(TIntermNode *root, TDiagnostics *diagnostics);
+
+ // Returns InvalidIndex if the function wasn't found
+ size_t findIndex(const TSymbolUniqueId &id) const;
+
+ const Record &getRecordFromIndex(size_t index) const;
+ size_t size() const;
+ void clear();
+
+ const static size_t InvalidIndex;
+
+ private:
+ std::vector<Record> mRecords;
+ std::map<int, int> mFunctionIdToIndex;
+
+ class CallDAGCreator;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_CALLDAG_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/CodeGen.cpp b/gfx/angle/checkout/src/compiler/translator/CodeGen.cpp
new file mode 100644
index 0000000000..497ef881e2
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/CodeGen.cpp
@@ -0,0 +1,96 @@
+//
+// Copyright 2013 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.
+//
+
+#ifdef ANGLE_ENABLE_ESSL
+# include "compiler/translator/TranslatorESSL.h"
+#endif // ANGLE_ENABLE_ESSL
+
+#ifdef ANGLE_ENABLE_GLSL
+# include "compiler/translator/TranslatorGLSL.h"
+#endif // ANGLE_ENABLE_GLSL
+
+#ifdef ANGLE_ENABLE_HLSL
+# include "compiler/translator/TranslatorHLSL.h"
+#endif // ANGLE_ENABLE_HLSL
+
+#ifdef ANGLE_ENABLE_VULKAN
+# include "compiler/translator/TranslatorVulkan.h"
+#endif // ANGLE_ENABLE_VULKAN
+
+#ifdef ANGLE_ENABLE_METAL
+# include "compiler/translator/TranslatorMetalDirect.h"
+#endif // ANGLE_ENABLE_METAL
+
+#ifdef ANGLE_ENABLE_METAL_SPIRV
+# include "compiler/translator/TranslatorMetal.h"
+#endif // ANGLE_ENABLE_METAL_SPIRV
+
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+//
+// This function must be provided to create the actual
+// compile object used by higher level code. It returns
+// a subclass of TCompiler.
+//
+TCompiler *ConstructCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output)
+{
+#ifdef ANGLE_ENABLE_ESSL
+ if (IsOutputESSL(output))
+ {
+ return new TranslatorESSL(type, spec);
+ }
+#endif // ANGLE_ENABLE_ESSL
+
+#ifdef ANGLE_ENABLE_GLSL
+ if (IsOutputGLSL(output))
+ {
+ return new TranslatorGLSL(type, spec, output);
+ }
+#endif // ANGLE_ENABLE_GLSL
+
+#ifdef ANGLE_ENABLE_HLSL
+ if (IsOutputHLSL(output))
+ {
+ return new TranslatorHLSL(type, spec, output);
+ }
+#endif // ANGLE_ENABLE_HLSL
+
+#ifdef ANGLE_ENABLE_VULKAN
+ if (IsOutputVulkan(output))
+ {
+ return new TranslatorVulkan(type, spec);
+ }
+#endif // ANGLE_ENABLE_VULKAN
+
+#ifdef ANGLE_ENABLE_METAL_SPIRV
+ if (IsOutputMetal(output))
+ {
+ return new TranslatorMetal(type, spec);
+ }
+#endif
+#ifdef ANGLE_ENABLE_METAL
+ if (IsOutputMetalDirect(output))
+ {
+ return new TranslatorMetalDirect(type, spec, output);
+ }
+#endif // ANGLE_ENABLE_METAL
+
+ // Unsupported compiler or unknown format. Return nullptr per the sh::ConstructCompiler API.
+ return nullptr;
+}
+
+//
+// Delete the compiler made by ConstructCompiler
+//
+void DeleteCompiler(TCompiler *compiler)
+{
+ SafeDelete(compiler);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/CollectVariables.cpp b/gfx/angle/checkout/src/compiler/translator/CollectVariables.cpp
new file mode 100644
index 0000000000..d6c58bebcb
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/CollectVariables.cpp
@@ -0,0 +1,1288 @@
+//
+// Copyright 2002 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.
+//
+// CollectVariables.cpp: Collect lists of shader interface variables based on the AST.
+
+#include "compiler/translator/CollectVariables.h"
+
+#include "angle_gl.h"
+#include "common/utilities.h"
+#include "compiler/translator/HashNames.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+BlockLayoutType GetBlockLayoutType(TLayoutBlockStorage blockStorage)
+{
+ switch (blockStorage)
+ {
+ case EbsPacked:
+ return BLOCKLAYOUT_PACKED;
+ case EbsShared:
+ return BLOCKLAYOUT_SHARED;
+ case EbsStd140:
+ return BLOCKLAYOUT_STD140;
+ case EbsStd430:
+ return BLOCKLAYOUT_STD430;
+ default:
+ UNREACHABLE();
+ return BLOCKLAYOUT_SHARED;
+ }
+}
+
+BlockType GetBlockType(TQualifier qualifier)
+{
+ switch (qualifier)
+ {
+ case EvqUniform:
+ return BlockType::BLOCK_UNIFORM;
+ case EvqBuffer:
+ return BlockType::BLOCK_BUFFER;
+ default:
+ UNREACHABLE();
+ return BlockType::BLOCK_UNIFORM;
+ }
+}
+
+template <class VarT>
+VarT *FindVariable(const ImmutableString &name, std::vector<VarT> *infoList)
+{
+ // TODO(zmo): optimize this function.
+ for (size_t ii = 0; ii < infoList->size(); ++ii)
+ {
+ if (name == (*infoList)[ii].name)
+ return &((*infoList)[ii]);
+ }
+
+ return nullptr;
+}
+
+void MarkActive(ShaderVariable *variable)
+{
+ if (!variable->active)
+ {
+ if (variable->isStruct())
+ {
+ // Conservatively assume all fields are statically used as well.
+ for (auto &field : variable->fields)
+ {
+ MarkActive(&field);
+ }
+ }
+ variable->staticUse = true;
+ variable->active = true;
+ }
+}
+
+ShaderVariable *FindVariableInInterfaceBlock(const ImmutableString &name,
+ const TInterfaceBlock *interfaceBlock,
+ std::vector<InterfaceBlock> *infoList)
+{
+ ASSERT(interfaceBlock);
+ InterfaceBlock *namedBlock = FindVariable(interfaceBlock->name(), infoList);
+ ASSERT(namedBlock);
+
+ // Set static use on the parent interface block here
+ namedBlock->staticUse = true;
+ namedBlock->active = true;
+ return FindVariable(name, &namedBlock->fields);
+}
+
+ShaderVariable *FindShaderIOBlockVariable(const ImmutableString &blockName,
+ std::vector<ShaderVariable> *infoList)
+{
+ for (size_t index = 0; index < infoList->size(); ++index)
+ {
+ if (blockName == (*infoList)[index].structOrBlockName)
+ return &(*infoList)[index];
+ }
+
+ return nullptr;
+}
+
+// Traverses the intermediate tree to collect all attributes, uniforms, varyings, fragment outputs,
+// shared data and interface blocks.
+class CollectVariablesTraverser : public TIntermTraverser
+{
+ public:
+ CollectVariablesTraverser(std::vector<ShaderVariable> *attribs,
+ std::vector<ShaderVariable> *outputVariables,
+ std::vector<ShaderVariable> *uniforms,
+ std::vector<ShaderVariable> *inputVaryings,
+ std::vector<ShaderVariable> *outputVaryings,
+ std::vector<ShaderVariable> *sharedVariables,
+ std::vector<InterfaceBlock> *uniformBlocks,
+ std::vector<InterfaceBlock> *shaderStorageBlocks,
+ ShHashFunction64 hashFunction,
+ TSymbolTable *symbolTable,
+ GLenum shaderType,
+ const TExtensionBehavior &extensionBehavior,
+ const ShBuiltInResources &resources,
+ int tessControlShaderOutputVertices);
+
+ bool visitGlobalQualifierDeclaration(Visit visit,
+ TIntermGlobalQualifierDeclaration *node) override;
+ void visitSymbol(TIntermSymbol *symbol) override;
+ bool visitDeclaration(Visit, TIntermDeclaration *node) override;
+ bool visitBinary(Visit visit, TIntermBinary *binaryNode) override;
+
+ private:
+ std::string getMappedName(const TSymbol *symbol) const;
+
+ void setFieldOrVariableProperties(const TType &type,
+ bool staticUse,
+ bool isShaderIOBlock,
+ bool isPatch,
+ ShaderVariable *variableOut) const;
+ void setFieldProperties(const TType &type,
+ const ImmutableString &name,
+ bool staticUse,
+ bool isShaderIOBlock,
+ bool isPatch,
+ SymbolType symbolType,
+ ShaderVariable *variableOut) const;
+ void setCommonVariableProperties(const TType &type,
+ const TVariable &variable,
+ ShaderVariable *variableOut) const;
+
+ ShaderVariable recordAttribute(const TIntermSymbol &variable) const;
+ ShaderVariable recordOutputVariable(const TIntermSymbol &variable) const;
+ ShaderVariable recordVarying(const TIntermSymbol &variable) const;
+ void recordInterfaceBlock(const char *instanceName,
+ const TType &interfaceBlockType,
+ InterfaceBlock *interfaceBlock) const;
+ ShaderVariable recordUniform(const TIntermSymbol &variable) const;
+
+ void setBuiltInInfoFromSymbol(const TVariable &variable, ShaderVariable *info);
+
+ void recordBuiltInVaryingUsed(const TVariable &variable,
+ bool *addedFlag,
+ std::vector<ShaderVariable> *varyings);
+ void recordBuiltInFragmentOutputUsed(const TVariable &variable, bool *addedFlag);
+ void recordBuiltInAttributeUsed(const TVariable &variable, bool *addedFlag);
+ InterfaceBlock *findNamedInterfaceBlock(const ImmutableString &name) const;
+
+ std::vector<ShaderVariable> *mAttribs;
+ std::vector<ShaderVariable> *mOutputVariables;
+ std::vector<ShaderVariable> *mUniforms;
+ std::vector<ShaderVariable> *mInputVaryings;
+ std::vector<ShaderVariable> *mOutputVaryings;
+ std::vector<ShaderVariable> *mSharedVariables;
+ std::vector<InterfaceBlock> *mUniformBlocks;
+ std::vector<InterfaceBlock> *mShaderStorageBlocks;
+
+ std::map<std::string, ShaderVariable *> mInterfaceBlockFields;
+
+ // Shader uniforms
+ bool mDepthRangeAdded;
+ bool mNumSamplesAdded;
+
+ // Compute Shader builtins
+ bool mNumWorkGroupsAdded;
+ bool mWorkGroupIDAdded;
+ bool mLocalInvocationIDAdded;
+ bool mGlobalInvocationIDAdded;
+ bool mLocalInvocationIndexAdded;
+
+ // Vertex Shader builtins
+ bool mInstanceIDAdded;
+ bool mVertexIDAdded;
+ bool mPointSizeAdded;
+ bool mDrawIDAdded;
+
+ // Vertex Shader and Geometry Shader builtins
+ bool mPositionAdded;
+ bool mClipDistanceAdded;
+ bool mCullDistanceAdded;
+
+ // Fragment Shader builtins
+ bool mPointCoordAdded;
+ bool mFrontFacingAdded;
+ bool mHelperInvocationAdded;
+ bool mFragCoordAdded;
+ bool mLastFragDataAdded;
+ bool mFragColorAdded;
+ bool mFragDataAdded;
+ bool mFragDepthAdded;
+ bool mSecondaryFragColorEXTAdded;
+ bool mSecondaryFragDataEXTAdded;
+ bool mSampleIDAdded;
+ bool mSamplePositionAdded;
+ bool mSampleMaskAdded;
+ bool mSampleMaskInAdded;
+
+ // Geometry and Tessellation Shader builtins
+ bool mPerVertexInAdded;
+ bool mPerVertexOutAdded;
+
+ // Geometry Shader builtins
+ bool mPrimitiveIDInAdded;
+ bool mInvocationIDAdded;
+
+ // Geometry Shader and Fragment Shader builtins
+ bool mPrimitiveIDAdded;
+ bool mLayerAdded;
+
+ // Shared memory variables
+ bool mSharedVariableAdded;
+
+ // Tessellation Shader builtins
+ bool mPatchVerticesInAdded;
+ bool mTessLevelOuterAdded;
+ bool mTessLevelInnerAdded;
+ bool mBoundingBoxAdded;
+ bool mTessCoordAdded;
+ const int mTessControlShaderOutputVertices;
+
+ ShHashFunction64 mHashFunction;
+
+ GLenum mShaderType;
+ const TExtensionBehavior &mExtensionBehavior;
+ const ShBuiltInResources &mResources;
+};
+
+CollectVariablesTraverser::CollectVariablesTraverser(
+ std::vector<sh::ShaderVariable> *attribs,
+ std::vector<sh::ShaderVariable> *outputVariables,
+ std::vector<sh::ShaderVariable> *uniforms,
+ std::vector<sh::ShaderVariable> *inputVaryings,
+ std::vector<sh::ShaderVariable> *outputVaryings,
+ std::vector<sh::ShaderVariable> *sharedVariables,
+ std::vector<sh::InterfaceBlock> *uniformBlocks,
+ std::vector<sh::InterfaceBlock> *shaderStorageBlocks,
+ ShHashFunction64 hashFunction,
+ TSymbolTable *symbolTable,
+ GLenum shaderType,
+ const TExtensionBehavior &extensionBehavior,
+ const ShBuiltInResources &resources,
+ int tessControlShaderOutputVertices)
+ : TIntermTraverser(true, false, false, symbolTable),
+ mAttribs(attribs),
+ mOutputVariables(outputVariables),
+ mUniforms(uniforms),
+ mInputVaryings(inputVaryings),
+ mOutputVaryings(outputVaryings),
+ mSharedVariables(sharedVariables),
+ mUniformBlocks(uniformBlocks),
+ mShaderStorageBlocks(shaderStorageBlocks),
+ mDepthRangeAdded(false),
+ mNumSamplesAdded(false),
+ mNumWorkGroupsAdded(false),
+ mWorkGroupIDAdded(false),
+ mLocalInvocationIDAdded(false),
+ mGlobalInvocationIDAdded(false),
+ mLocalInvocationIndexAdded(false),
+ mInstanceIDAdded(false),
+ mVertexIDAdded(false),
+ mPointSizeAdded(false),
+ mDrawIDAdded(false),
+ mPositionAdded(false),
+ mClipDistanceAdded(false),
+ mCullDistanceAdded(false),
+ mPointCoordAdded(false),
+ mFrontFacingAdded(false),
+ mHelperInvocationAdded(false),
+ mFragCoordAdded(false),
+ mLastFragDataAdded(false),
+ mFragColorAdded(false),
+ mFragDataAdded(false),
+ mFragDepthAdded(false),
+ mSecondaryFragColorEXTAdded(false),
+ mSecondaryFragDataEXTAdded(false),
+ mSampleIDAdded(false),
+ mSamplePositionAdded(false),
+ mSampleMaskAdded(false),
+ mSampleMaskInAdded(false),
+ mPerVertexInAdded(false),
+ mPerVertexOutAdded(false),
+ mPrimitiveIDInAdded(false),
+ mInvocationIDAdded(false),
+ mPrimitiveIDAdded(false),
+ mLayerAdded(false),
+ mSharedVariableAdded(false),
+ mPatchVerticesInAdded(false),
+ mTessLevelOuterAdded(false),
+ mTessLevelInnerAdded(false),
+ mBoundingBoxAdded(false),
+ mTessCoordAdded(false),
+ mTessControlShaderOutputVertices(tessControlShaderOutputVertices),
+ mHashFunction(hashFunction),
+ mShaderType(shaderType),
+ mExtensionBehavior(extensionBehavior),
+ mResources(resources)
+{}
+
+std::string CollectVariablesTraverser::getMappedName(const TSymbol *symbol) const
+{
+ return HashName(symbol, mHashFunction, nullptr).data();
+}
+
+void CollectVariablesTraverser::setBuiltInInfoFromSymbol(const TVariable &variable,
+ ShaderVariable *info)
+{
+ const TType &type = variable.getType();
+
+ info->name = variable.name().data();
+ info->mappedName = variable.name().data();
+
+ bool isShaderIOBlock =
+ IsShaderIoBlock(type.getQualifier()) && type.getInterfaceBlock() != nullptr;
+ bool isPatch = type.getQualifier() == EvqTessLevelInner ||
+ type.getQualifier() == EvqTessLevelOuter ||
+ type.getQualifier() == EvqBoundingBox;
+
+ setFieldOrVariableProperties(type, true, isShaderIOBlock, isPatch, info);
+}
+
+void CollectVariablesTraverser::recordBuiltInVaryingUsed(const TVariable &variable,
+ bool *addedFlag,
+ std::vector<ShaderVariable> *varyings)
+{
+ ASSERT(varyings);
+ if (!(*addedFlag))
+ {
+ ShaderVariable info;
+ setBuiltInInfoFromSymbol(variable, &info);
+ info.active = true;
+ info.isInvariant = mSymbolTable->isVaryingInvariant(variable);
+
+ varyings->push_back(info);
+ (*addedFlag) = true;
+ }
+}
+
+void CollectVariablesTraverser::recordBuiltInFragmentOutputUsed(const TVariable &variable,
+ bool *addedFlag)
+{
+ if (!(*addedFlag))
+ {
+ ShaderVariable info;
+ setBuiltInInfoFromSymbol(variable, &info);
+ info.active = true;
+ mOutputVariables->push_back(info);
+ (*addedFlag) = true;
+ }
+}
+
+void CollectVariablesTraverser::recordBuiltInAttributeUsed(const TVariable &variable,
+ bool *addedFlag)
+{
+ if (!(*addedFlag))
+ {
+ ShaderVariable info;
+ setBuiltInInfoFromSymbol(variable, &info);
+ info.active = true;
+ info.location = -1;
+ mAttribs->push_back(info);
+ (*addedFlag) = true;
+ }
+}
+
+bool CollectVariablesTraverser::visitGlobalQualifierDeclaration(
+ Visit visit,
+ TIntermGlobalQualifierDeclaration *node)
+{
+ // We should not mark variables as active just based on an invariant/precise declaration, so we
+ // don't traverse the symbols declared invariant.
+ return false;
+}
+
+// We want to check whether a uniform/varying is active because we need to skip updating inactive
+// ones. We also only count the active ones in packing computing. Also, gl_FragCoord, gl_PointCoord,
+// and gl_FrontFacing count toward varying counting if they are active in a fragment shader.
+void CollectVariablesTraverser::visitSymbol(TIntermSymbol *symbol)
+{
+ ASSERT(symbol != nullptr);
+
+ if (symbol->variable().symbolType() == SymbolType::AngleInternal ||
+ symbol->variable().symbolType() == SymbolType::Empty)
+ {
+ // Internal variables or nameless variables are not collected.
+ return;
+ }
+
+ ShaderVariable *var = nullptr;
+
+ const ImmutableString &symbolName = symbol->getName();
+
+ // Check the qualifier from the variable, not from the symbol node. The node may have a
+ // different qualifier if it's the result of a folded ternary node.
+ TQualifier qualifier = symbol->variable().getType().getQualifier();
+ const TInterfaceBlock *interfaceBlock = symbol->getType().getInterfaceBlock();
+
+ if (IsVaryingIn(qualifier))
+ {
+ if (interfaceBlock)
+ {
+ var = FindShaderIOBlockVariable(interfaceBlock->name(), mInputVaryings);
+ }
+ else
+ {
+ var = FindVariable(symbolName, mInputVaryings);
+ }
+ }
+ else if (IsVaryingOut(qualifier))
+ {
+ if (interfaceBlock)
+ {
+ var = FindShaderIOBlockVariable(interfaceBlock->name(), mOutputVaryings);
+ }
+ else
+ {
+ var = FindVariable(symbolName, mOutputVaryings);
+ }
+ }
+ else if (symbol->getType().getBasicType() == EbtInterfaceBlock)
+ {
+ UNREACHABLE();
+ }
+ else if (symbolName == "gl_DepthRange")
+ {
+ ASSERT(qualifier == EvqUniform);
+
+ if (!mDepthRangeAdded)
+ {
+ ShaderVariable info;
+ const char kName[] = "gl_DepthRange";
+ info.name = kName;
+ info.mappedName = kName;
+ info.type = GL_NONE;
+ info.precision = GL_NONE;
+ info.staticUse = true;
+ info.active = true;
+
+ ShaderVariable nearInfo(GL_FLOAT);
+ const char kNearName[] = "near";
+ nearInfo.name = kNearName;
+ nearInfo.mappedName = kNearName;
+ nearInfo.precision = GL_HIGH_FLOAT;
+ nearInfo.staticUse = true;
+ nearInfo.active = true;
+
+ ShaderVariable farInfo(GL_FLOAT);
+ const char kFarName[] = "far";
+ farInfo.name = kFarName;
+ farInfo.mappedName = kFarName;
+ farInfo.precision = GL_HIGH_FLOAT;
+ farInfo.staticUse = true;
+ farInfo.active = true;
+
+ ShaderVariable diffInfo(GL_FLOAT);
+ const char kDiffName[] = "diff";
+ diffInfo.name = kDiffName;
+ diffInfo.mappedName = kDiffName;
+ diffInfo.precision = GL_HIGH_FLOAT;
+ diffInfo.staticUse = true;
+ diffInfo.active = true;
+
+ info.fields.push_back(nearInfo);
+ info.fields.push_back(farInfo);
+ info.fields.push_back(diffInfo);
+
+ mUniforms->push_back(info);
+ mDepthRangeAdded = true;
+ }
+ }
+ else if (symbolName == "gl_NumSamples")
+ {
+ ASSERT(qualifier == EvqUniform);
+
+ if (!mNumSamplesAdded)
+ {
+ ShaderVariable info;
+ const char kName[] = "gl_NumSamples";
+ info.name = kName;
+ info.mappedName = kName;
+ info.type = GL_INT;
+ info.precision = GL_LOW_INT;
+ info.staticUse = true;
+ info.active = true;
+
+ mUniforms->push_back(info);
+ mNumSamplesAdded = true;
+ }
+ }
+ else
+ {
+ switch (qualifier)
+ {
+ case EvqAttribute:
+ case EvqVertexIn:
+ var = FindVariable(symbolName, mAttribs);
+ break;
+ case EvqFragmentOut:
+ case EvqFragmentInOut:
+ var = FindVariable(symbolName, mOutputVariables);
+ var->isFragmentInOut = qualifier == EvqFragmentInOut;
+ break;
+ case EvqUniform:
+ {
+ if (interfaceBlock)
+ {
+ var = FindVariableInInterfaceBlock(symbolName, interfaceBlock, mUniformBlocks);
+ }
+ else
+ {
+ var = FindVariable(symbolName, mUniforms);
+ }
+
+ // It's an internal error to reference an undefined user uniform
+ ASSERT(!gl::IsBuiltInName(symbolName.data()) || var);
+ }
+ break;
+ case EvqBuffer:
+ {
+ var =
+ FindVariableInInterfaceBlock(symbolName, interfaceBlock, mShaderStorageBlocks);
+ }
+ break;
+ case EvqFragCoord:
+ recordBuiltInVaryingUsed(symbol->variable(), &mFragCoordAdded, mInputVaryings);
+ return;
+ case EvqFrontFacing:
+ recordBuiltInVaryingUsed(symbol->variable(), &mFrontFacingAdded, mInputVaryings);
+ return;
+ case EvqHelperInvocation:
+ recordBuiltInVaryingUsed(symbol->variable(), &mHelperInvocationAdded,
+ mInputVaryings);
+ return;
+ case EvqPointCoord:
+ recordBuiltInVaryingUsed(symbol->variable(), &mPointCoordAdded, mInputVaryings);
+ return;
+ case EvqNumWorkGroups:
+ recordBuiltInAttributeUsed(symbol->variable(), &mNumWorkGroupsAdded);
+ return;
+ case EvqWorkGroupID:
+ recordBuiltInAttributeUsed(symbol->variable(), &mWorkGroupIDAdded);
+ return;
+ case EvqLocalInvocationID:
+ recordBuiltInAttributeUsed(symbol->variable(), &mLocalInvocationIDAdded);
+ return;
+ case EvqGlobalInvocationID:
+ recordBuiltInAttributeUsed(symbol->variable(), &mGlobalInvocationIDAdded);
+ return;
+ case EvqLocalInvocationIndex:
+ recordBuiltInAttributeUsed(symbol->variable(), &mLocalInvocationIndexAdded);
+ return;
+ case EvqInstanceID:
+ // Whenever the initializeBuiltinsForInstancedMultiview option is set,
+ // gl_InstanceID is added inside expressions to initialize ViewID_OVR and
+ // InstanceID. Note that gl_InstanceID is not added to the symbol table for ESSL1
+ // shaders.
+ recordBuiltInAttributeUsed(symbol->variable(), &mInstanceIDAdded);
+ return;
+ case EvqVertexID:
+ recordBuiltInAttributeUsed(symbol->variable(), &mVertexIDAdded);
+ return;
+ case EvqPosition:
+ recordBuiltInVaryingUsed(symbol->variable(), &mPositionAdded, mOutputVaryings);
+ return;
+ case EvqPointSize:
+ recordBuiltInVaryingUsed(symbol->variable(), &mPointSizeAdded, mOutputVaryings);
+ return;
+ case EvqDrawID:
+ recordBuiltInAttributeUsed(symbol->variable(), &mDrawIDAdded);
+ return;
+ case EvqLastFragData:
+ recordBuiltInVaryingUsed(symbol->variable(), &mLastFragDataAdded, mInputVaryings);
+ return;
+ case EvqFragColor:
+ recordBuiltInFragmentOutputUsed(symbol->variable(), &mFragColorAdded);
+ return;
+ case EvqFragData:
+ recordBuiltInFragmentOutputUsed(symbol->variable(), &mFragDataAdded);
+ return;
+ case EvqFragDepth:
+ recordBuiltInFragmentOutputUsed(symbol->variable(), &mFragDepthAdded);
+ return;
+ case EvqSecondaryFragColorEXT:
+ recordBuiltInFragmentOutputUsed(symbol->variable(), &mSecondaryFragColorEXTAdded);
+ return;
+ case EvqSecondaryFragDataEXT:
+ recordBuiltInFragmentOutputUsed(symbol->variable(), &mSecondaryFragDataEXTAdded);
+ return;
+ case EvqInvocationID:
+ recordBuiltInVaryingUsed(symbol->variable(), &mInvocationIDAdded, mInputVaryings);
+ break;
+ case EvqPrimitiveIDIn:
+ recordBuiltInVaryingUsed(symbol->variable(), &mPrimitiveIDInAdded, mInputVaryings);
+ break;
+ case EvqPrimitiveID:
+ if (mShaderType == GL_GEOMETRY_SHADER_EXT)
+ {
+ recordBuiltInVaryingUsed(symbol->variable(), &mPrimitiveIDAdded,
+ mOutputVaryings);
+ }
+ else
+ {
+ ASSERT(mShaderType == GL_FRAGMENT_SHADER ||
+ mShaderType == GL_TESS_CONTROL_SHADER ||
+ mShaderType == GL_TESS_EVALUATION_SHADER);
+ recordBuiltInVaryingUsed(symbol->variable(), &mPrimitiveIDAdded,
+ mInputVaryings);
+ }
+ break;
+ case EvqLayerOut:
+ if (mShaderType == GL_GEOMETRY_SHADER_EXT)
+ {
+ recordBuiltInVaryingUsed(symbol->variable(), &mLayerAdded, mOutputVaryings);
+ }
+ else
+ {
+ ASSERT(mShaderType == GL_VERTEX_SHADER &&
+ (IsExtensionEnabled(mExtensionBehavior, TExtension::OVR_multiview2) ||
+ IsExtensionEnabled(mExtensionBehavior, TExtension::OVR_multiview)));
+ }
+ break;
+ case EvqLayerIn:
+ ASSERT(mShaderType == GL_FRAGMENT_SHADER);
+ recordBuiltInVaryingUsed(symbol->variable(), &mLayerAdded, mInputVaryings);
+ break;
+ case EvqShared:
+ if (mShaderType == GL_COMPUTE_SHADER)
+ {
+ recordBuiltInVaryingUsed(symbol->variable(), &mSharedVariableAdded,
+ mSharedVariables);
+ }
+ break;
+ case EvqClipDistance:
+ recordBuiltInVaryingUsed(
+ symbol->variable(), &mClipDistanceAdded,
+ mShaderType == GL_FRAGMENT_SHADER ? mInputVaryings : mOutputVaryings);
+ return;
+ case EvqCullDistance:
+ recordBuiltInVaryingUsed(
+ symbol->variable(), &mCullDistanceAdded,
+ mShaderType == GL_FRAGMENT_SHADER ? mInputVaryings : mOutputVaryings);
+ return;
+ case EvqSampleID:
+ recordBuiltInVaryingUsed(symbol->variable(), &mSampleIDAdded, mInputVaryings);
+ return;
+ case EvqSamplePosition:
+ recordBuiltInVaryingUsed(symbol->variable(), &mSamplePositionAdded, mInputVaryings);
+ return;
+ case EvqSampleMaskIn:
+ recordBuiltInVaryingUsed(symbol->variable(), &mSampleMaskInAdded, mInputVaryings);
+ return;
+ case EvqSampleMask:
+ recordBuiltInFragmentOutputUsed(symbol->variable(), &mSampleMaskAdded);
+ return;
+ case EvqPatchVerticesIn:
+ recordBuiltInVaryingUsed(symbol->variable(), &mPatchVerticesInAdded,
+ mInputVaryings);
+ break;
+ case EvqTessCoord:
+ recordBuiltInVaryingUsed(symbol->variable(), &mTessCoordAdded, mInputVaryings);
+ break;
+ case EvqTessLevelOuter:
+ if (mShaderType == GL_TESS_CONTROL_SHADER)
+ {
+ recordBuiltInVaryingUsed(symbol->variable(), &mTessLevelOuterAdded,
+ mOutputVaryings);
+ }
+ else
+ {
+ ASSERT(mShaderType == GL_TESS_EVALUATION_SHADER);
+ recordBuiltInVaryingUsed(symbol->variable(), &mTessLevelOuterAdded,
+ mInputVaryings);
+ }
+ break;
+ case EvqTessLevelInner:
+ if (mShaderType == GL_TESS_CONTROL_SHADER)
+ {
+ recordBuiltInVaryingUsed(symbol->variable(), &mTessLevelInnerAdded,
+ mOutputVaryings);
+ }
+ else
+ {
+ ASSERT(mShaderType == GL_TESS_EVALUATION_SHADER);
+ recordBuiltInVaryingUsed(symbol->variable(), &mTessLevelInnerAdded,
+ mInputVaryings);
+ }
+ break;
+ case EvqBoundingBox:
+ recordBuiltInVaryingUsed(symbol->variable(), &mBoundingBoxAdded, mOutputVaryings);
+ break;
+ default:
+ break;
+ }
+ }
+ if (var)
+ {
+ MarkActive(var);
+ }
+}
+
+void CollectVariablesTraverser::setFieldOrVariableProperties(const TType &type,
+ bool staticUse,
+ bool isShaderIOBlock,
+ bool isPatch,
+ ShaderVariable *variableOut) const
+{
+ ASSERT(variableOut);
+
+ variableOut->staticUse = staticUse;
+ variableOut->isShaderIOBlock = isShaderIOBlock;
+ variableOut->isPatch = isPatch;
+
+ const TStructure *structure = type.getStruct();
+ const TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
+ if (structure)
+ {
+ // Structures use a NONE type that isn't exposed outside ANGLE.
+ variableOut->type = GL_NONE;
+ if (structure->symbolType() != SymbolType::Empty)
+ {
+ variableOut->structOrBlockName = structure->name().data();
+ }
+
+ const TFieldList &fields = structure->fields();
+
+ for (const TField *field : fields)
+ {
+ // Regardless of the variable type (uniform, in/out etc.) its fields are always plain
+ // ShaderVariable objects.
+ ShaderVariable fieldVariable;
+ setFieldProperties(*field->type(), field->name(), staticUse, isShaderIOBlock, isPatch,
+ field->symbolType(), &fieldVariable);
+ variableOut->fields.push_back(fieldVariable);
+ }
+ }
+ else if (interfaceBlock && isShaderIOBlock)
+ {
+ const bool isPerVertex = (interfaceBlock->name() == "gl_PerVertex");
+ variableOut->type = GL_NONE;
+ if (interfaceBlock->symbolType() != SymbolType::Empty)
+ {
+ variableOut->structOrBlockName = interfaceBlock->name().data();
+ variableOut->mappedStructOrBlockName =
+ isPerVertex ? interfaceBlock->name().data()
+ : HashName(interfaceBlock->name(), mHashFunction, nullptr).data();
+ }
+ const TFieldList &fields = interfaceBlock->fields();
+ for (const TField *field : fields)
+ {
+ ShaderVariable fieldVariable;
+
+ setFieldProperties(*field->type(), field->name(), staticUse, true, isPatch,
+ field->symbolType(), &fieldVariable);
+ fieldVariable.isShaderIOBlock = true;
+ variableOut->fields.push_back(fieldVariable);
+ }
+ }
+ else
+ {
+ variableOut->type = GLVariableType(type);
+ variableOut->precision = GLVariablePrecision(type);
+ }
+
+ const TSpan<const unsigned int> &arraySizes = type.getArraySizes();
+ if (!arraySizes.empty())
+ {
+ variableOut->arraySizes.assign(arraySizes.begin(), arraySizes.end());
+
+ if (arraySizes[0] == 0)
+ {
+ // Tessellation Control & Evaluation shader inputs:
+ // Declaring an array size is optional. If no size is specified, it will be taken from
+ // the implementation-dependent maximum patch size (gl_MaxPatchVertices).
+ if (type.getQualifier() == EvqTessControlIn ||
+ type.getQualifier() == EvqTessEvaluationIn)
+ {
+ variableOut->arraySizes[0] = mResources.MaxPatchVertices;
+ }
+
+ // Tessellation Control shader outputs:
+ // Declaring an array size is optional. If no size is specified, it will be taken from
+ // output patch size declared in the shader.
+ if (type.getQualifier() == EvqTessControlOut)
+ {
+ ASSERT(mTessControlShaderOutputVertices > 0);
+ variableOut->arraySizes[0] = mTessControlShaderOutputVertices;
+ }
+ }
+ }
+}
+
+void CollectVariablesTraverser::setFieldProperties(const TType &type,
+ const ImmutableString &name,
+ bool staticUse,
+ bool isShaderIOBlock,
+ bool isPatch,
+ SymbolType symbolType,
+ ShaderVariable *variableOut) const
+{
+ ASSERT(variableOut);
+ setFieldOrVariableProperties(type, staticUse, isShaderIOBlock, isPatch, variableOut);
+ variableOut->name.assign(name.data(), name.length());
+ variableOut->mappedName = (symbolType == SymbolType::BuiltIn)
+ ? name.data()
+ : HashName(name, mHashFunction, nullptr).data();
+}
+
+void CollectVariablesTraverser::setCommonVariableProperties(const TType &type,
+ const TVariable &variable,
+ ShaderVariable *variableOut) const
+{
+ ASSERT(variableOut);
+ ASSERT(type.getInterfaceBlock() == nullptr || IsShaderIoBlock(type.getQualifier()) ||
+ type.getQualifier() == EvqPatchIn || type.getQualifier() == EvqPatchOut);
+
+ const bool staticUse = mSymbolTable->isStaticallyUsed(variable);
+ const bool isShaderIOBlock = type.getInterfaceBlock() != nullptr;
+ const bool isPatch = type.getQualifier() == EvqPatchIn || type.getQualifier() == EvqPatchOut;
+
+ setFieldOrVariableProperties(type, staticUse, isShaderIOBlock, isPatch, variableOut);
+
+ const bool isNamed = variable.symbolType() != SymbolType::Empty;
+
+ ASSERT(isNamed || isShaderIOBlock);
+ if (isNamed)
+ {
+ variableOut->name.assign(variable.name().data(), variable.name().length());
+ variableOut->mappedName = getMappedName(&variable);
+ }
+
+ // For I/O blocks, additionally store the name of the block as blockName. If the variable is
+ // unnamed, this name will be used instead for the purpose of interface matching.
+ if (isShaderIOBlock)
+ {
+ const TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
+ ASSERT(interfaceBlock);
+
+ variableOut->structOrBlockName.assign(interfaceBlock->name().data(),
+ interfaceBlock->name().length());
+ variableOut->mappedStructOrBlockName =
+ HashName(interfaceBlock->name(), mHashFunction, nullptr).data();
+ variableOut->isShaderIOBlock = true;
+ }
+}
+
+ShaderVariable CollectVariablesTraverser::recordAttribute(const TIntermSymbol &variable) const
+{
+ const TType &type = variable.getType();
+ ASSERT(!type.getStruct());
+
+ ShaderVariable attribute;
+ setCommonVariableProperties(type, variable.variable(), &attribute);
+
+ attribute.location = type.getLayoutQualifier().location;
+ return attribute;
+}
+
+ShaderVariable CollectVariablesTraverser::recordOutputVariable(const TIntermSymbol &variable) const
+{
+ const TType &type = variable.getType();
+ ASSERT(!type.getStruct());
+
+ ShaderVariable outputVariable;
+ setCommonVariableProperties(type, variable.variable(), &outputVariable);
+
+ outputVariable.location = type.getLayoutQualifier().location;
+ outputVariable.index = type.getLayoutQualifier().index;
+ outputVariable.yuv = type.getLayoutQualifier().yuv;
+ return outputVariable;
+}
+
+ShaderVariable CollectVariablesTraverser::recordVarying(const TIntermSymbol &variable) const
+{
+ const TType &type = variable.getType();
+
+ ShaderVariable varying;
+ setCommonVariableProperties(type, variable.variable(), &varying);
+ varying.location = type.getLayoutQualifier().location;
+
+ switch (type.getQualifier())
+ {
+ case EvqVaryingIn:
+ case EvqVaryingOut:
+ case EvqVertexOut:
+ case EvqSmoothOut:
+ case EvqFlatOut:
+ case EvqNoPerspectiveOut:
+ case EvqCentroidOut:
+ case EvqGeometryOut:
+ case EvqSampleOut:
+ if (mSymbolTable->isVaryingInvariant(variable.variable()) || type.isInvariant())
+ {
+ varying.isInvariant = true;
+ }
+ break;
+ case EvqPatchIn:
+ case EvqPatchOut:
+ varying.isPatch = true;
+ break;
+ default:
+ break;
+ }
+
+ varying.interpolation = GetInterpolationType(type.getQualifier());
+
+ // Shader I/O block properties
+ if (type.getBasicType() == EbtInterfaceBlock)
+ {
+ bool isBlockImplicitLocation = false;
+ int location = type.getLayoutQualifier().location;
+
+ // when a interface has not location in layout, assign to the zero.
+ if (location < 0)
+ {
+ location = 0;
+ isBlockImplicitLocation = true;
+ }
+
+ const TInterfaceBlock *blockType = type.getInterfaceBlock();
+ ASSERT(blockType->fields().size() == varying.fields.size());
+
+ for (size_t fieldIndex = 0; fieldIndex < varying.fields.size(); ++fieldIndex)
+ {
+ const TField *blockField = blockType->fields()[fieldIndex];
+ ShaderVariable &fieldVariable = varying.fields[fieldIndex];
+ const TType &fieldType = *blockField->type();
+
+ fieldVariable.hasImplicitLocation = isBlockImplicitLocation;
+ fieldVariable.isPatch = varying.isPatch;
+
+ int fieldLocation = fieldType.getLayoutQualifier().location;
+ if (fieldLocation >= 0)
+ {
+ fieldVariable.hasImplicitLocation = false;
+ fieldVariable.location = fieldLocation;
+ location = fieldLocation;
+ }
+ else
+ {
+ fieldVariable.location = location;
+ location += fieldType.getLocationCount();
+ }
+
+ if (fieldType.getQualifier() != EvqGlobal)
+ {
+ fieldVariable.interpolation = GetFieldInterpolationType(fieldType.getQualifier());
+ }
+ }
+ }
+
+ return varying;
+}
+
+void CollectVariablesTraverser::recordInterfaceBlock(const char *instanceName,
+ const TType &interfaceBlockType,
+ InterfaceBlock *interfaceBlock) const
+{
+ ASSERT(interfaceBlockType.getBasicType() == EbtInterfaceBlock);
+ ASSERT(interfaceBlock);
+
+ const TInterfaceBlock *blockType = interfaceBlockType.getInterfaceBlock();
+ ASSERT(blockType);
+
+ interfaceBlock->name = blockType->name().data();
+ interfaceBlock->mappedName = getMappedName(blockType);
+
+ const bool isGLInBuiltin = (instanceName != nullptr) && strncmp(instanceName, "gl_in", 5u) == 0;
+ if (instanceName != nullptr)
+ {
+ interfaceBlock->instanceName = instanceName;
+ const TSymbol *blockSymbol = nullptr;
+ if (isGLInBuiltin)
+ {
+ blockSymbol = mSymbolTable->getGlInVariableWithArraySize();
+ }
+ else
+ {
+ blockSymbol = mSymbolTable->findGlobal(ImmutableString(instanceName));
+ }
+ ASSERT(blockSymbol && blockSymbol->isVariable());
+ interfaceBlock->staticUse =
+ mSymbolTable->isStaticallyUsed(*static_cast<const TVariable *>(blockSymbol));
+ }
+
+ ASSERT(!interfaceBlockType.isArrayOfArrays()); // Disallowed by GLSL ES 3.10 section 4.3.9
+ interfaceBlock->arraySize =
+ interfaceBlockType.isArray() ? interfaceBlockType.getOutermostArraySize() : 0;
+
+ interfaceBlock->blockType = GetBlockType(interfaceBlockType.getQualifier());
+ if (interfaceBlock->blockType == BlockType::BLOCK_UNIFORM ||
+ interfaceBlock->blockType == BlockType::BLOCK_BUFFER)
+ {
+ // TODO(oetuaho): Remove setting isRowMajorLayout.
+ interfaceBlock->isRowMajorLayout = false;
+ interfaceBlock->binding = blockType->blockBinding();
+ interfaceBlock->layout = GetBlockLayoutType(blockType->blockStorage());
+ }
+
+ // Gather field information
+ bool anyFieldStaticallyUsed = false;
+
+ for (const TField *field : blockType->fields())
+ {
+ const TType &fieldType = *field->type();
+
+ bool staticUse = false;
+ if (instanceName == nullptr)
+ {
+ // Static use of individual fields has been recorded, since they are present in the
+ // symbol table as variables.
+ const TSymbol *fieldSymbol = mSymbolTable->findGlobal(field->name());
+ ASSERT(fieldSymbol && fieldSymbol->isVariable());
+ staticUse =
+ mSymbolTable->isStaticallyUsed(*static_cast<const TVariable *>(fieldSymbol));
+ if (staticUse)
+ {
+ anyFieldStaticallyUsed = true;
+ }
+ }
+
+ ShaderVariable fieldVariable;
+ setFieldProperties(fieldType, field->name(), staticUse, false, false, field->symbolType(),
+ &fieldVariable);
+ fieldVariable.isRowMajorLayout =
+ (fieldType.getLayoutQualifier().matrixPacking == EmpRowMajor);
+ interfaceBlock->fields.push_back(fieldVariable);
+ }
+ if (anyFieldStaticallyUsed)
+ {
+ interfaceBlock->staticUse = true;
+ }
+}
+
+ShaderVariable CollectVariablesTraverser::recordUniform(const TIntermSymbol &variable) const
+{
+ ShaderVariable uniform;
+ setCommonVariableProperties(variable.getType(), variable.variable(), &uniform);
+ uniform.binding = variable.getType().getLayoutQualifier().binding;
+ uniform.imageUnitFormat =
+ GetImageInternalFormatType(variable.getType().getLayoutQualifier().imageInternalFormat);
+ uniform.location = variable.getType().getLayoutQualifier().location;
+ uniform.offset = variable.getType().getLayoutQualifier().offset;
+ uniform.rasterOrdered = variable.getType().getLayoutQualifier().rasterOrdered;
+ uniform.readonly = variable.getType().getMemoryQualifier().readonly;
+ uniform.writeonly = variable.getType().getMemoryQualifier().writeonly;
+ return uniform;
+}
+
+bool CollectVariablesTraverser::visitDeclaration(Visit, TIntermDeclaration *node)
+{
+ const TIntermSequence &sequence = *(node->getSequence());
+ ASSERT(!sequence.empty());
+
+ const TIntermTyped &typedNode = *(sequence.front()->getAsTyped());
+ TQualifier qualifier = typedNode.getQualifier();
+
+ bool isShaderVariable = qualifier == EvqAttribute || qualifier == EvqVertexIn ||
+ qualifier == EvqFragmentOut || qualifier == EvqFragmentInOut ||
+ qualifier == EvqUniform || IsVarying(qualifier);
+
+ if (typedNode.getBasicType() != EbtInterfaceBlock && !isShaderVariable)
+ {
+ return true;
+ }
+
+ for (TIntermNode *variableNode : sequence)
+ {
+ // The only case in which the sequence will not contain a TIntermSymbol node is
+ // initialization. It will contain a TInterBinary node in that case. Since attributes,
+ // uniforms, varyings, outputs and interface blocks cannot be initialized in a shader, we
+ // must have only TIntermSymbol nodes in the sequence in the cases we are interested in.
+ const TIntermSymbol &variable = *variableNode->getAsSymbolNode();
+ if (variable.variable().symbolType() == SymbolType::AngleInternal)
+ {
+ // Internal variables are not collected.
+ continue;
+ }
+
+ // SpirvTransformer::transform uses a map of ShaderVariables, it needs member variables and
+ // (named or unnamed) structure as ShaderVariable. at link between two shaders, validation
+ // between of named and unnamed, needs the same structure, its members, and members order
+ // except instance name.
+ if (typedNode.getBasicType() == EbtInterfaceBlock && !IsShaderIoBlock(qualifier) &&
+ qualifier != EvqPatchIn && qualifier != EvqPatchOut)
+ {
+ InterfaceBlock interfaceBlock;
+ bool isUnnamed = variable.variable().symbolType() == SymbolType::Empty;
+ const TType &type = variable.getType();
+ recordInterfaceBlock(isUnnamed ? nullptr : variable.getName().data(), type,
+ &interfaceBlock);
+
+ // all fields in interface block will be added for updating interface variables because
+ // the temporal structure variable will be ignored.
+ switch (qualifier)
+ {
+ case EvqUniform:
+ mUniformBlocks->push_back(interfaceBlock);
+ break;
+ case EvqBuffer:
+ mShaderStorageBlocks->push_back(interfaceBlock);
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+ else
+ {
+ ASSERT(variable.variable().symbolType() != SymbolType::Empty ||
+ IsShaderIoBlock(qualifier) || qualifier == EvqPatchIn ||
+ qualifier == EvqPatchOut);
+ switch (qualifier)
+ {
+ case EvqAttribute:
+ case EvqVertexIn:
+ mAttribs->push_back(recordAttribute(variable));
+ break;
+ case EvqFragmentOut:
+ case EvqFragmentInOut:
+ mOutputVariables->push_back(recordOutputVariable(variable));
+ break;
+ case EvqUniform:
+ mUniforms->push_back(recordUniform(variable));
+ break;
+ default:
+ if (IsVaryingIn(qualifier))
+ {
+ mInputVaryings->push_back(recordVarying(variable));
+ }
+ else
+ {
+ ASSERT(IsVaryingOut(qualifier));
+ mOutputVaryings->push_back(recordVarying(variable));
+ }
+ break;
+ }
+ }
+ }
+
+ // None of the recorded variables can have initializers, so we don't need to traverse the
+ // declarators.
+ return false;
+}
+
+InterfaceBlock *CollectVariablesTraverser::findNamedInterfaceBlock(
+ const ImmutableString &blockName) const
+{
+ InterfaceBlock *namedBlock = FindVariable(blockName, mUniformBlocks);
+ if (!namedBlock)
+ {
+ namedBlock = FindVariable(blockName, mShaderStorageBlocks);
+ }
+ return namedBlock;
+}
+
+bool CollectVariablesTraverser::visitBinary(Visit, TIntermBinary *binaryNode)
+{
+ if (binaryNode->getOp() == EOpIndexDirectInterfaceBlock)
+ {
+ // NOTE: we do not determine static use / activeness for individual blocks of an array.
+ TIntermTyped *blockNode = binaryNode->getLeft()->getAsTyped();
+ ASSERT(blockNode);
+
+ TIntermConstantUnion *constantUnion = binaryNode->getRight()->getAsConstantUnion();
+ ASSERT(constantUnion);
+
+ InterfaceBlock *namedBlock = nullptr;
+
+ bool traverseIndexExpression = false;
+ TIntermBinary *interfaceIndexingNode = blockNode->getAsBinaryNode();
+ if (interfaceIndexingNode)
+ {
+ ASSERT(interfaceIndexingNode->getOp() == EOpIndexDirect ||
+ interfaceIndexingNode->getOp() == EOpIndexIndirect);
+ traverseIndexExpression = true;
+ blockNode = interfaceIndexingNode->getLeft();
+ }
+
+ const TType &interfaceNodeType = blockNode->getType();
+ const TInterfaceBlock *interfaceBlock = interfaceNodeType.getInterfaceBlock();
+ const TQualifier qualifier = interfaceNodeType.getQualifier();
+
+ // If it's a shader I/O block, look in varyings
+ ShaderVariable *ioBlockVar = nullptr;
+ if (qualifier == EvqPerVertexIn)
+ {
+ TIntermSymbol *symbolNode = blockNode->getAsSymbolNode();
+ ASSERT(symbolNode);
+ recordBuiltInVaryingUsed(symbolNode->variable(), &mPerVertexInAdded, mInputVaryings);
+ ioBlockVar = FindShaderIOBlockVariable(interfaceBlock->name(), mInputVaryings);
+ }
+ else if (IsVaryingIn(qualifier))
+ {
+ ioBlockVar = FindShaderIOBlockVariable(interfaceBlock->name(), mInputVaryings);
+ }
+ else if (qualifier == EvqPerVertexOut)
+ {
+ TIntermSymbol *symbolNode = blockNode->getAsSymbolNode();
+ ASSERT(symbolNode);
+ recordBuiltInVaryingUsed(symbolNode->variable(), &mPerVertexOutAdded, mOutputVaryings);
+ ioBlockVar = FindShaderIOBlockVariable(interfaceBlock->name(), mOutputVaryings);
+ }
+ else if (IsVaryingOut(qualifier))
+ {
+ ioBlockVar = FindShaderIOBlockVariable(interfaceBlock->name(), mOutputVaryings);
+ }
+
+ if (ioBlockVar)
+ {
+ MarkActive(ioBlockVar);
+ }
+ else
+ {
+ if (!namedBlock)
+ {
+ namedBlock = findNamedInterfaceBlock(interfaceBlock->name());
+ }
+ ASSERT(namedBlock);
+ ASSERT(namedBlock->staticUse);
+ namedBlock->active = true;
+ unsigned int fieldIndex = static_cast<unsigned int>(constantUnion->getIConst(0));
+ ASSERT(fieldIndex < namedBlock->fields.size());
+ // TODO(oetuaho): Would be nicer to record static use of fields of named interface
+ // blocks more accurately at parse time - now we only mark the fields statically used if
+ // they are active. http://anglebug.com/2440 We need to mark this field and all of its
+ // sub-fields, as static/active
+ MarkActive(&namedBlock->fields[fieldIndex]);
+ }
+
+ if (traverseIndexExpression)
+ {
+ ASSERT(interfaceIndexingNode);
+ interfaceIndexingNode->getRight()->traverse(this);
+ }
+ return false;
+ }
+
+ return true;
+}
+
+} // anonymous namespace
+
+void CollectVariables(TIntermBlock *root,
+ std::vector<ShaderVariable> *attributes,
+ std::vector<ShaderVariable> *outputVariables,
+ std::vector<ShaderVariable> *uniforms,
+ std::vector<ShaderVariable> *inputVaryings,
+ std::vector<ShaderVariable> *outputVaryings,
+ std::vector<ShaderVariable> *sharedVariables,
+ std::vector<InterfaceBlock> *uniformBlocks,
+ std::vector<InterfaceBlock> *shaderStorageBlocks,
+ ShHashFunction64 hashFunction,
+ TSymbolTable *symbolTable,
+ GLenum shaderType,
+ const TExtensionBehavior &extensionBehavior,
+ const ShBuiltInResources &resources,
+ int tessControlShaderOutputVertices)
+{
+ CollectVariablesTraverser collect(
+ attributes, outputVariables, uniforms, inputVaryings, outputVaryings, sharedVariables,
+ uniformBlocks, shaderStorageBlocks, hashFunction, symbolTable, shaderType,
+ extensionBehavior, resources, tessControlShaderOutputVertices);
+ root->traverse(&collect);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/CollectVariables.h b/gfx/angle/checkout/src/compiler/translator/CollectVariables.h
new file mode 100644
index 0000000000..6ea4b172a0
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/CollectVariables.h
@@ -0,0 +1,38 @@
+//
+// Copyright 2002 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.
+//
+// CollectVariables.h: Collect lists of shader interface variables based on the AST.
+
+#ifndef COMPILER_TRANSLATOR_COLLECTVARIABLES_H_
+#define COMPILER_TRANSLATOR_COLLECTVARIABLES_H_
+
+#include <GLSLANG/ShaderLang.h>
+
+#include "compiler/translator/ExtensionBehavior.h"
+
+namespace sh
+{
+
+class TIntermBlock;
+class TSymbolTable;
+
+void CollectVariables(TIntermBlock *root,
+ std::vector<ShaderVariable> *attributes,
+ std::vector<ShaderVariable> *outputVariables,
+ std::vector<ShaderVariable> *uniforms,
+ std::vector<ShaderVariable> *inputVaryings,
+ std::vector<ShaderVariable> *outputVaryings,
+ std::vector<ShaderVariable> *sharedVariables,
+ std::vector<InterfaceBlock> *uniformBlocks,
+ std::vector<InterfaceBlock> *shaderStorageBlocks,
+ ShHashFunction64 hashFunction,
+ TSymbolTable *symbolTable,
+ GLenum shaderType,
+ const TExtensionBehavior &extensionBehavior,
+ const ShBuiltInResources &resources,
+ int tessControlShaderOutputVertices);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_COLLECTVARIABLES_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/Common.h b/gfx/angle/checkout/src/compiler/translator/Common.h
new file mode 100644
index 0000000000..77907fc3a4
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/Common.h
@@ -0,0 +1,256 @@
+//
+// Copyright 2002 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_COMMON_H_
+#define COMPILER_TRANSLATOR_COMMON_H_
+
+#include <stdio.h>
+#include <limits>
+#include <map>
+#include <sstream>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+#include "common/angleutils.h"
+#include "common/debug.h"
+#include "common/third_party/smhasher/src/PMurHash.h"
+#include "compiler/translator/PoolAlloc.h"
+
+namespace sh
+{
+
+struct TSourceLoc
+{
+ int first_file;
+ int first_line;
+ int last_file;
+ int last_line;
+};
+
+constexpr TSourceLoc kNoSourceLoc{-1, -1, -1, -1};
+
+//
+// Put POOL_ALLOCATOR_NEW_DELETE in base classes to make them use this scheme.
+//
+#define POOL_ALLOCATOR_NEW_DELETE \
+ void *operator new(size_t s) { return GetGlobalPoolAllocator()->allocate(s); } \
+ void *operator new(size_t, void *_Where) { return (_Where); } \
+ void operator delete(void *) {} \
+ void operator delete(void *, void *) {} \
+ void *operator new[](size_t s) { return GetGlobalPoolAllocator()->allocate(s); } \
+ void *operator new[](size_t, void *_Where) { return (_Where); } \
+ void operator delete[](void *) {} \
+ void operator delete[](void *, void *) {}
+
+//
+// Pool version of string.
+//
+typedef pool_allocator<char> TStringAllocator;
+typedef std::basic_string<char, std::char_traits<char>, TStringAllocator> TString;
+typedef std::basic_ostringstream<char, std::char_traits<char>, TStringAllocator> TStringStream;
+
+//
+// Persistent memory. Should only be used for strings that survive across compiles.
+//
+using TPersistString = std::string;
+using TPersistStringStream = std::ostringstream;
+
+//
+// Pool allocator versions of vectors, lists, and maps
+//
+template <class T>
+class TVector : public std::vector<T, pool_allocator<T>>
+{
+ public:
+ POOL_ALLOCATOR_NEW_DELETE
+
+ typedef typename std::vector<T, pool_allocator<T>>::size_type size_type;
+ TVector() : std::vector<T, pool_allocator<T>>() {}
+ TVector(const pool_allocator<T> &a) : std::vector<T, pool_allocator<T>>(a) {}
+ TVector(size_type i) : std::vector<T, pool_allocator<T>>(i) {}
+ TVector(size_type i, const T &value) : std::vector<T, pool_allocator<T>>(i, value) {}
+ template <typename InputIt>
+ TVector(InputIt first, InputIt last) : std::vector<T, pool_allocator<T>>(first, last)
+ {}
+ TVector(std::initializer_list<T> init) : std::vector<T, pool_allocator<T>>(init) {}
+};
+
+template <class K, class D, class H = std::hash<K>, class CMP = std::equal_to<K>>
+class TUnorderedMap : public std::unordered_map<K, D, H, CMP, pool_allocator<std::pair<const K, D>>>
+{
+ public:
+ POOL_ALLOCATOR_NEW_DELETE
+ typedef pool_allocator<std::pair<const K, D>> tAllocator;
+
+ TUnorderedMap() : std::unordered_map<K, D, H, CMP, tAllocator>() {}
+ // use correct two-stage name lookup supported in gcc 3.4 and above
+ TUnorderedMap(const tAllocator &a)
+ : std::unordered_map<K, D, H, CMP, tAllocator>(
+ std::unordered_map<K, D, H, CMP, tAllocator>::key_compare(),
+ a)
+ {}
+};
+
+template <class K, class D, class CMP = std::less<K>>
+class TMap : public std::map<K, D, CMP, pool_allocator<std::pair<const K, D>>>
+{
+ public:
+ POOL_ALLOCATOR_NEW_DELETE
+ typedef pool_allocator<std::pair<const K, D>> tAllocator;
+
+ TMap() : std::map<K, D, CMP, tAllocator>() {}
+ // use correct two-stage name lookup supported in gcc 3.4 and above
+ TMap(const tAllocator &a)
+ : std::map<K, D, CMP, tAllocator>(std::map<K, D, CMP, tAllocator>::key_compare(), a)
+ {}
+};
+
+// Basic implementation of C++20's span for use with pool-allocated containers (TVector) or static
+// arrays. This is used by the array sizes member of TType to allow arrayed types to be
+// constexpr-constructed.
+// See the reference for std::span here: https://en.cppreference.com/w/cpp/container/span
+template <typename T>
+class TSpan
+{
+ public:
+ typedef size_t size_type;
+
+ constexpr TSpan() {}
+ constexpr TSpan(T *ptr, size_type size) : mData(ptr), mSize(size) {}
+
+ constexpr TSpan(const TSpan &that) : mData(that.mData), mSize(that.mSize) {}
+ constexpr TSpan &operator=(const TSpan &that)
+ {
+ mData = that.mData;
+ mSize = that.mSize;
+ return *this;
+ }
+
+ // Note: the pointer is taken out of the TVector because TVector's memory is pool allocated,
+ // so the memory will live on even if the TVector is destroyed.
+ template <typename S>
+ TSpan(const TVector<S> &vec) : mData(vec.data()), mSize(vec.size())
+ {}
+ template <typename S>
+ TSpan &operator=(const TVector<S> &vec)
+ {
+ mData = vec.data();
+ mSize = vec.size();
+ return *this;
+ }
+
+ constexpr bool operator==(const TSpan &that) const
+ {
+ if (mSize != that.mSize)
+ {
+ return false;
+ }
+
+ if (mData == that.mData)
+ {
+ return true;
+ }
+
+ for (size_type index = 0; index < mSize; ++index)
+ {
+ if (mData[index] != that.mData[index])
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ constexpr bool operator!=(const TSpan &that) const { return !(*this == that); }
+
+ constexpr T *data() const { return mData; }
+ constexpr size_type size() const { return mSize; }
+ constexpr bool empty() const { return mSize == 0; }
+
+ constexpr T &operator[](size_type index) const { return mData[index]; }
+ constexpr T &front() const { return mData[0]; }
+ constexpr T &back() const { return mData[mSize - 1]; }
+
+ constexpr T *begin() const { return mData; }
+ constexpr T *end() const { return mData + mSize; }
+
+ constexpr std::reverse_iterator<T *> rbegin() const
+ {
+ return std::make_reverse_iterator(end());
+ }
+ constexpr std::reverse_iterator<T *> rend() const
+ {
+ return std::make_reverse_iterator(begin());
+ }
+
+ constexpr TSpan first(size_type count) const
+ {
+ ASSERT(count <= mSize);
+ return count == 0 ? TSpan() : TSpan(mData, count);
+ }
+ constexpr TSpan last(size_type count) const
+ {
+ ASSERT(count <= mSize);
+ return count == 0 ? TSpan() : TSpan(mData + mSize - count, count);
+ }
+ constexpr TSpan subspan(size_type offset, size_type count) const
+ {
+ ASSERT(offset + count <= mSize);
+ return count == 0 ? TSpan() : TSpan(mData + offset, count);
+ }
+
+ private:
+ T *mData = nullptr;
+ size_t mSize = 0;
+};
+
+// Integer to TString conversion
+template <typename T>
+inline TString str(T i)
+{
+ ASSERT(std::numeric_limits<T>::is_integer);
+ char buffer[((8 * sizeof(T)) / 3) + 3];
+ const char *formatStr = std::numeric_limits<T>::is_signed ? "%d" : "%u";
+ snprintf(buffer, sizeof(buffer), formatStr, i);
+ return buffer;
+}
+
+// Allocate a char array in the global memory pool. str must be a null terminated string. strLength
+// is the length without the null terminator.
+inline const char *AllocatePoolCharArray(const char *str, size_t strLength)
+{
+ size_t requiredSize = strLength + 1;
+ char *buffer = static_cast<char *>(GetGlobalPoolAllocator()->allocate(requiredSize));
+ memcpy(buffer, str, requiredSize);
+ ASSERT(buffer[strLength] == '\0');
+ return buffer;
+}
+
+// Initialize a new stream which must be imbued with the classic locale
+template <typename T>
+T InitializeStream()
+{
+ T stream;
+ stream.imbue(std::locale::classic());
+ return stream;
+}
+
+} // namespace sh
+
+namespace std
+{
+template <>
+struct hash<sh::TString>
+{
+ size_t operator()(const sh::TString &s) const
+ {
+ return angle::PMurHash32(0, s.data(), static_cast<int>(s.length()));
+ }
+};
+} // namespace std
+
+#endif // COMPILER_TRANSLATOR_COMMON_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/Compiler.cpp b/gfx/angle/checkout/src/compiler/translator/Compiler.cpp
new file mode 100644
index 0000000000..891d1ddf61
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/Compiler.cpp
@@ -0,0 +1,1746 @@
+//
+// Copyright 2002 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/Compiler.h"
+
+#include <sstream>
+
+#include "angle_gl.h"
+#include "common/utilities.h"
+#include "compiler/translator/CallDAG.h"
+#include "compiler/translator/CollectVariables.h"
+#include "compiler/translator/Initialize.h"
+#include "compiler/translator/IsASTDepthBelowLimit.h"
+#include "compiler/translator/OutputTree.h"
+#include "compiler/translator/ParseContext.h"
+#include "compiler/translator/ValidateBarrierFunctionCall.h"
+#include "compiler/translator/ValidateClipCullDistance.h"
+#include "compiler/translator/ValidateLimitations.h"
+#include "compiler/translator/ValidateMaxParameters.h"
+#include "compiler/translator/ValidateOutputs.h"
+#include "compiler/translator/ValidateTypeSizeLimitations.h"
+#include "compiler/translator/ValidateVaryingLocations.h"
+#include "compiler/translator/VariablePacker.h"
+#include "compiler/translator/tree_ops/ClampIndirectIndices.h"
+#include "compiler/translator/tree_ops/ClampPointSize.h"
+#include "compiler/translator/tree_ops/DeclareAndInitBuiltinsForInstancedMultiview.h"
+#include "compiler/translator/tree_ops/DeferGlobalInitializers.h"
+#include "compiler/translator/tree_ops/EmulateGLFragColorBroadcast.h"
+#include "compiler/translator/tree_ops/EmulateMultiDrawShaderBuiltins.h"
+#include "compiler/translator/tree_ops/FoldExpressions.h"
+#include "compiler/translator/tree_ops/ForcePrecisionQualifier.h"
+#include "compiler/translator/tree_ops/InitializeVariables.h"
+#include "compiler/translator/tree_ops/MonomorphizeUnsupportedFunctions.h"
+#include "compiler/translator/tree_ops/PruneEmptyCases.h"
+#include "compiler/translator/tree_ops/PruneNoOps.h"
+#include "compiler/translator/tree_ops/RemoveArrayLengthMethod.h"
+#include "compiler/translator/tree_ops/RemoveDynamicIndexing.h"
+#include "compiler/translator/tree_ops/RemoveInvariantDeclaration.h"
+#include "compiler/translator/tree_ops/RemoveUnreferencedVariables.h"
+#include "compiler/translator/tree_ops/RewritePixelLocalStorage.h"
+#include "compiler/translator/tree_ops/ScalarizeVecAndMatConstructorArgs.h"
+#include "compiler/translator/tree_ops/SeparateDeclarations.h"
+#include "compiler/translator/tree_ops/SimplifyLoopConditions.h"
+#include "compiler/translator/tree_ops/SplitSequenceOperator.h"
+#include "compiler/translator/tree_ops/apple/AddAndTrueToLoopCondition.h"
+#include "compiler/translator/tree_ops/apple/RewriteDoWhile.h"
+#include "compiler/translator/tree_ops/apple/UnfoldShortCircuitAST.h"
+#include "compiler/translator/tree_ops/gl/ClampFragDepth.h"
+#include "compiler/translator/tree_ops/gl/RegenerateStructNames.h"
+#include "compiler/translator/tree_ops/gl/RewriteRepeatedAssignToSwizzled.h"
+#include "compiler/translator/tree_ops/gl/UseInterfaceBlockFields.h"
+#include "compiler/translator/tree_util/BuiltIn.h"
+#include "compiler/translator/tree_util/IntermNodePatternMatcher.h"
+#include "compiler/translator/tree_util/ReplaceShadowingVariables.h"
+#include "compiler/translator/util.h"
+
+// #define ANGLE_FUZZER_CORPUS_OUTPUT_DIR "corpus/"
+
+#if defined(ANGLE_FUZZER_CORPUS_OUTPUT_DIR)
+# include "common/hash_utils.h"
+# include "common/mathutil.h"
+#endif
+
+namespace sh
+{
+
+namespace
+{
+// Helper that returns if a top-level node is unused. If it's a function, the function prototype is
+// returned as well.
+bool IsTopLevelNodeUnusedFunction(const CallDAG &callDag,
+ const std::vector<TFunctionMetadata> &metadata,
+ TIntermNode *node,
+ const TFunction **functionOut)
+{
+ const TIntermFunctionPrototype *asFunctionPrototype = node->getAsFunctionPrototypeNode();
+ const TIntermFunctionDefinition *asFunctionDefinition = node->getAsFunctionDefinition();
+
+ *functionOut = nullptr;
+
+ if (asFunctionDefinition)
+ {
+ *functionOut = asFunctionDefinition->getFunction();
+ }
+ else if (asFunctionPrototype)
+ {
+ *functionOut = asFunctionPrototype->getFunction();
+ }
+ if (*functionOut == nullptr)
+ {
+ return false;
+ }
+
+ size_t callDagIndex = callDag.findIndex((*functionOut)->uniqueId());
+ if (callDagIndex == CallDAG::InvalidIndex)
+ {
+ // This happens only for unimplemented prototypes which are thus unused
+ ASSERT(asFunctionPrototype);
+ return true;
+ }
+
+ ASSERT(callDagIndex < metadata.size());
+ return !metadata[callDagIndex].used;
+}
+
+#if defined(ANGLE_FUZZER_CORPUS_OUTPUT_DIR)
+void DumpFuzzerCase(char const *const *shaderStrings,
+ size_t numStrings,
+ uint32_t type,
+ uint32_t spec,
+ uint32_t output,
+ const ShCompileOptions &options)
+{
+ ShaderDumpHeader header{};
+ header.type = type;
+ header.spec = spec;
+ header.output = output;
+ memcpy(&header.basicCompileOptions, &options, offsetof(ShCompileOptions, metal));
+ static_assert(offsetof(ShCompileOptions, metal) <= sizeof(header.basicCompileOptions));
+ memcpy(&header.metalCompileOptions, &options.metal, sizeof(options.metal));
+ static_assert(sizeof(options.metal) <= sizeof(header.metalCompileOptions));
+ memcpy(&header.plsCompileOptions, &options.pls, sizeof(options.pls));
+ static_assert(sizeof(options.pls) <= sizeof(header.plsCompileOptions));
+ size_t contentsLength = sizeof(header) + 1; // Extra: header + nul terminator.
+ for (size_t i = 0; i < numStrings; i++)
+ {
+ contentsLength += strlen(shaderStrings[i]);
+ }
+ std::vector<uint8_t> contents(rx::roundUp<size_t>(contentsLength, 4), 0);
+ memcpy(&contents[0], &header, sizeof(header));
+ uint8_t *data = &contents[sizeof(header)];
+ for (size_t i = 0; i < numStrings; i++)
+ {
+ auto length = strlen(shaderStrings[i]);
+ memcpy(data, shaderStrings[i], length);
+ data += length;
+ }
+ auto hash = angle::ComputeGenericHash(contents.data(), contents.size());
+
+ std::ostringstream o = sh::InitializeStream<std::ostringstream>();
+ o << ANGLE_FUZZER_CORPUS_OUTPUT_DIR << std::hex << std::setw(16) << std::setfill('0') << hash
+ << ".sample";
+ std::string s = o.str();
+
+ // Must match the input format of the fuzzer
+ FILE *f = fopen(s.c_str(), "w");
+ fwrite(contents.data(), sizeof(char), contentsLength, f);
+ fclose(f);
+}
+#endif // defined(ANGLE_FUZZER_CORPUS_OUTPUT_DIR)
+} // anonymous namespace
+
+bool IsGLSL130OrNewer(ShShaderOutput output)
+{
+ return (output == SH_GLSL_130_OUTPUT || output == SH_GLSL_140_OUTPUT ||
+ output == SH_GLSL_150_CORE_OUTPUT || output == SH_GLSL_330_CORE_OUTPUT ||
+ output == SH_GLSL_400_CORE_OUTPUT || output == SH_GLSL_410_CORE_OUTPUT ||
+ output == SH_GLSL_420_CORE_OUTPUT || output == SH_GLSL_430_CORE_OUTPUT ||
+ output == SH_GLSL_440_CORE_OUTPUT || output == SH_GLSL_450_CORE_OUTPUT);
+}
+
+bool IsGLSL420OrNewer(ShShaderOutput output)
+{
+ return (output == SH_GLSL_420_CORE_OUTPUT || output == SH_GLSL_430_CORE_OUTPUT ||
+ output == SH_GLSL_440_CORE_OUTPUT || output == SH_GLSL_450_CORE_OUTPUT);
+}
+
+bool IsGLSL410OrOlder(ShShaderOutput output)
+{
+ return (output == SH_GLSL_130_OUTPUT || output == SH_GLSL_140_OUTPUT ||
+ output == SH_GLSL_150_CORE_OUTPUT || output == SH_GLSL_330_CORE_OUTPUT ||
+ output == SH_GLSL_400_CORE_OUTPUT || output == SH_GLSL_410_CORE_OUTPUT);
+}
+
+bool RemoveInvariant(sh::GLenum shaderType,
+ int shaderVersion,
+ ShShaderOutput outputType,
+ const ShCompileOptions &compileOptions)
+{
+ if (shaderType == GL_FRAGMENT_SHADER && IsGLSL420OrNewer(outputType))
+ return true;
+
+ if (compileOptions.removeInvariantAndCentroidForESSL3 && shaderVersion >= 300 &&
+ shaderType == GL_VERTEX_SHADER)
+ return true;
+
+ return false;
+}
+
+size_t GetGlobalMaxTokenSize(ShShaderSpec spec)
+{
+ // WebGL defines a max token length of 256, while ES2 leaves max token
+ // size undefined. ES3 defines a max size of 1024 characters.
+ switch (spec)
+ {
+ case SH_WEBGL_SPEC:
+ return 256;
+ default:
+ return 1024;
+ }
+}
+
+int GetMaxUniformVectorsForShaderType(GLenum shaderType, const ShBuiltInResources &resources)
+{
+ switch (shaderType)
+ {
+ case GL_VERTEX_SHADER:
+ return resources.MaxVertexUniformVectors;
+ case GL_FRAGMENT_SHADER:
+ return resources.MaxFragmentUniformVectors;
+
+ // TODO (jiawei.shao@intel.com): check if we need finer-grained component counting
+ case GL_COMPUTE_SHADER:
+ return resources.MaxComputeUniformComponents / 4;
+ case GL_GEOMETRY_SHADER_EXT:
+ return resources.MaxGeometryUniformComponents / 4;
+ default:
+ UNREACHABLE();
+ return -1;
+ }
+}
+
+namespace
+{
+
+class [[nodiscard]] TScopedPoolAllocator
+{
+ public:
+ TScopedPoolAllocator(angle::PoolAllocator *allocator) : mAllocator(allocator)
+ {
+ mAllocator->push();
+ SetGlobalPoolAllocator(mAllocator);
+ }
+ ~TScopedPoolAllocator()
+ {
+ SetGlobalPoolAllocator(nullptr);
+ mAllocator->pop();
+ }
+
+ private:
+ angle::PoolAllocator *mAllocator;
+};
+
+class [[nodiscard]] TScopedSymbolTableLevel
+{
+ public:
+ TScopedSymbolTableLevel(TSymbolTable *table) : mTable(table)
+ {
+ ASSERT(mTable->isEmpty());
+ mTable->push();
+ }
+ ~TScopedSymbolTableLevel()
+ {
+ while (!mTable->isEmpty())
+ mTable->pop();
+ }
+
+ private:
+ TSymbolTable *mTable;
+};
+
+int GetMaxShaderVersionForSpec(ShShaderSpec spec)
+{
+ switch (spec)
+ {
+ case SH_GLES2_SPEC:
+ case SH_WEBGL_SPEC:
+ return 100;
+ case SH_GLES3_SPEC:
+ case SH_WEBGL2_SPEC:
+ return 300;
+ case SH_GLES3_1_SPEC:
+ case SH_WEBGL3_SPEC:
+ return 310;
+ case SH_GLES3_2_SPEC:
+ return 320;
+ case SH_GL_CORE_SPEC:
+ case SH_GL_COMPATIBILITY_SPEC:
+ return 460;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+bool ValidateFragColorAndFragData(GLenum shaderType,
+ int shaderVersion,
+ const TSymbolTable &symbolTable,
+ TDiagnostics *diagnostics)
+{
+ if (shaderVersion > 100 || shaderType != GL_FRAGMENT_SHADER)
+ {
+ return true;
+ }
+
+ bool usesFragColor = false;
+ bool usesFragData = false;
+ // This validation is a bit stricter than the spec - it's only an error to write to
+ // both FragData and FragColor. But because it's better not to have reads from undefined
+ // variables, we always return an error if they are both referenced, rather than only if they
+ // are written.
+ if (symbolTable.isStaticallyUsed(*BuiltInVariable::gl_FragColor()) ||
+ symbolTable.isStaticallyUsed(*BuiltInVariable::gl_SecondaryFragColorEXT()))
+ {
+ usesFragColor = true;
+ }
+ // Extension variables may not always be initialized (saves some time at symbol table init).
+ bool secondaryFragDataUsed =
+ symbolTable.gl_SecondaryFragDataEXT() != nullptr &&
+ symbolTable.isStaticallyUsed(*symbolTable.gl_SecondaryFragDataEXT());
+ if (symbolTable.isStaticallyUsed(*symbolTable.gl_FragData()) || secondaryFragDataUsed)
+ {
+ usesFragData = true;
+ }
+ if (usesFragColor && usesFragData)
+ {
+ const char *errorMessage = "cannot use both gl_FragData and gl_FragColor";
+ if (symbolTable.isStaticallyUsed(*BuiltInVariable::gl_SecondaryFragColorEXT()) ||
+ secondaryFragDataUsed)
+ {
+ errorMessage =
+ "cannot use both output variable sets (gl_FragData, gl_SecondaryFragDataEXT)"
+ " and (gl_FragColor, gl_SecondaryFragColorEXT)";
+ }
+ diagnostics->globalError(errorMessage);
+ return false;
+ }
+ return true;
+}
+
+} // namespace
+
+TShHandleBase::TShHandleBase()
+{
+ allocator.push();
+ SetGlobalPoolAllocator(&allocator);
+}
+
+TShHandleBase::~TShHandleBase()
+{
+ SetGlobalPoolAllocator(nullptr);
+ allocator.popAll();
+}
+
+TCompiler::TCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output)
+ : mVariablesCollected(false),
+ mGLPositionInitialized(false),
+ mShaderType(type),
+ mShaderSpec(spec),
+ mOutputType(output),
+ mBuiltInFunctionEmulator(),
+ mDiagnostics(mInfoSink.info),
+ mSourcePath(nullptr),
+ mComputeShaderLocalSizeDeclared(false),
+ mComputeShaderLocalSize(1),
+ mGeometryShaderMaxVertices(-1),
+ mGeometryShaderInvocations(0),
+ mGeometryShaderInputPrimitiveType(EptUndefined),
+ mGeometryShaderOutputPrimitiveType(EptUndefined),
+ mTessControlShaderOutputVertices(0),
+ mTessEvaluationShaderInputPrimitiveType(EtetUndefined),
+ mTessEvaluationShaderInputVertexSpacingType(EtetUndefined),
+ mTessEvaluationShaderInputOrderingType(EtetUndefined),
+ mTessEvaluationShaderInputPointType(EtetUndefined),
+ mHasAnyPreciseType(false),
+ mAdvancedBlendEquations(0),
+ mHasPixelLocalStorageUniforms(false),
+ mCompileOptions{}
+{}
+
+TCompiler::~TCompiler() {}
+
+bool TCompiler::isHighPrecisionSupported() const
+{
+ return mShaderVersion > 100 || mShaderType != GL_FRAGMENT_SHADER ||
+ mResources.FragmentPrecisionHigh == 1;
+}
+
+bool TCompiler::shouldRunLoopAndIndexingValidation(const 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
+ // of ESSL 1.00 as in Appendix A of the spec).
+ return (IsWebGLBasedSpec(mShaderSpec) && mShaderVersion == 100) ||
+ compileOptions.validateLoopIndexing;
+}
+
+bool TCompiler::shouldLimitTypeSizes() const
+{
+ // WebGL shaders limit the size of variables' types in shaders,
+ // including arrays, structs and interface blocks.
+ return IsWebGLBasedSpec(mShaderSpec);
+}
+
+bool TCompiler::Init(const ShBuiltInResources &resources)
+{
+ SetGlobalPoolAllocator(&allocator);
+
+ // Generate built-in symbol table.
+ if (!initBuiltInSymbolTable(resources))
+ return false;
+
+ mResources = resources;
+ setResourceString();
+
+ InitExtensionBehavior(resources, mExtensionBehavior);
+ return true;
+}
+
+TIntermBlock *TCompiler::compileTreeForTesting(const char *const shaderStrings[],
+ size_t numStrings,
+ const ShCompileOptions &compileOptions)
+{
+ return compileTreeImpl(shaderStrings, numStrings, compileOptions);
+}
+
+TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[],
+ size_t numStrings,
+ const ShCompileOptions &compileOptions)
+{
+ // Remember the compile options for helper functions such as validateAST.
+ mCompileOptions = compileOptions;
+
+ clearResults();
+
+ ASSERT(numStrings > 0);
+ ASSERT(GetGlobalPoolAllocator());
+
+ // Reset the extension behavior for each compilation unit.
+ ResetExtensionBehavior(mResources, mExtensionBehavior, compileOptions);
+
+ // If gl_DrawID is not supported, remove it from the available extensions
+ // Currently we only allow emulation of gl_DrawID
+ const bool glDrawIDSupported = compileOptions.emulateGLDrawID;
+ if (!glDrawIDSupported)
+ {
+ auto it = mExtensionBehavior.find(TExtension::ANGLE_multi_draw);
+ if (it != mExtensionBehavior.end())
+ {
+ mExtensionBehavior.erase(it);
+ }
+ }
+
+ const bool glBaseVertexBaseInstanceSupported = compileOptions.emulateGLBaseVertexBaseInstance;
+ if (!glBaseVertexBaseInstanceSupported)
+ {
+ auto it =
+ mExtensionBehavior.find(TExtension::ANGLE_base_vertex_base_instance_shader_builtin);
+ if (it != mExtensionBehavior.end())
+ {
+ mExtensionBehavior.erase(it);
+ }
+ }
+
+ // First string is path of source file if flag is set. The actual source follows.
+ size_t firstSource = 0;
+ if (compileOptions.sourcePath)
+ {
+ mSourcePath = shaderStrings[0];
+ ++firstSource;
+ }
+
+ TParseContext parseContext(mSymbolTable, mExtensionBehavior, mShaderType, mShaderSpec,
+ compileOptions, !IsDesktopGLSpec(mShaderSpec), &mDiagnostics,
+ getResources(), getOutputType());
+
+ parseContext.setFragmentPrecisionHighOnESSL1(mResources.FragmentPrecisionHigh == 1);
+
+ // We preserve symbols at the built-in level from compile-to-compile.
+ // Start pushing the user-defined symbols at global level.
+ TScopedSymbolTableLevel globalLevel(&mSymbolTable);
+ ASSERT(mSymbolTable.atGlobalLevel());
+
+ // Parse shader.
+ if (PaParseStrings(numStrings - firstSource, &shaderStrings[firstSource], nullptr,
+ &parseContext) != 0)
+ {
+ return nullptr;
+ }
+
+ if (!postParseChecks(parseContext))
+ {
+ return nullptr;
+ }
+
+ setASTMetadata(parseContext);
+
+ if (!checkShaderVersion(&parseContext))
+ {
+ return nullptr;
+ }
+
+ TIntermBlock *root = parseContext.getTreeRoot();
+ if (!checkAndSimplifyAST(root, parseContext, compileOptions))
+ {
+ return nullptr;
+ }
+
+ return root;
+}
+
+bool TCompiler::checkShaderVersion(TParseContext *parseContext)
+{
+ if (GetMaxShaderVersionForSpec(mShaderSpec) < mShaderVersion)
+ {
+ mDiagnostics.globalError("unsupported shader version");
+ return false;
+ }
+
+ ASSERT(parseContext);
+ switch (mShaderType)
+ {
+ case GL_COMPUTE_SHADER:
+ if (mShaderVersion < 310)
+ {
+ mDiagnostics.globalError("Compute shader is not supported in this shader version.");
+ return false;
+ }
+ break;
+
+ case GL_GEOMETRY_SHADER_EXT:
+ if (mShaderVersion < 310)
+ {
+ mDiagnostics.globalError(
+ "Geometry shader is not supported in this shader version.");
+ return false;
+ }
+ else if (mShaderVersion == 310)
+ {
+ if (!parseContext->checkCanUseOneOfExtensions(
+ sh::TSourceLoc(),
+ std::array<TExtension, 2u>{
+ {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}}))
+ {
+ return false;
+ }
+ }
+ break;
+
+ case GL_TESS_CONTROL_SHADER_EXT:
+ case GL_TESS_EVALUATION_SHADER_EXT:
+ if (mShaderVersion < 310)
+ {
+ mDiagnostics.globalError(
+ "Tessellation shaders are not supported in this shader version.");
+ return false;
+ }
+ else if (mShaderVersion == 310)
+ {
+ if (!parseContext->checkCanUseExtension(sh::TSourceLoc(),
+ TExtension::EXT_tessellation_shader))
+ {
+ return false;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return true;
+}
+
+void TCompiler::setASTMetadata(const TParseContext &parseContext)
+{
+ mShaderVersion = parseContext.getShaderVersion();
+
+ mPragma = parseContext.pragma();
+ mSymbolTable.setGlobalInvariant(mPragma.stdgl.invariantAll);
+
+ mEarlyFragmentTestsSpecified = parseContext.isEarlyFragmentTestsSpecified();
+
+ mHasDiscard = parseContext.hasDiscard();
+
+ mEnablesPerSampleShading = parseContext.isSampleQualifierSpecified();
+
+ mComputeShaderLocalSizeDeclared = parseContext.isComputeShaderLocalSizeDeclared();
+ mComputeShaderLocalSize = parseContext.getComputeShaderLocalSize();
+
+ mNumViews = parseContext.getNumViews();
+
+ mHasAnyPreciseType = parseContext.hasAnyPreciseType();
+
+ if (mShaderType == GL_FRAGMENT_SHADER)
+ {
+ mAdvancedBlendEquations = parseContext.getAdvancedBlendEquations();
+ mHasPixelLocalStorageUniforms = !parseContext.pixelLocalStorageBindings().empty();
+ }
+ if (mShaderType == GL_GEOMETRY_SHADER_EXT)
+ {
+ mGeometryShaderInputPrimitiveType = parseContext.getGeometryShaderInputPrimitiveType();
+ mGeometryShaderOutputPrimitiveType = parseContext.getGeometryShaderOutputPrimitiveType();
+ mGeometryShaderMaxVertices = parseContext.getGeometryShaderMaxVertices();
+ mGeometryShaderInvocations = parseContext.getGeometryShaderInvocations();
+ }
+ if (mShaderType == GL_TESS_CONTROL_SHADER_EXT)
+ {
+ mTessControlShaderOutputVertices = parseContext.getTessControlShaderOutputVertices();
+ }
+ if (mShaderType == GL_TESS_EVALUATION_SHADER_EXT)
+ {
+ mTessEvaluationShaderInputPrimitiveType =
+ parseContext.getTessEvaluationShaderInputPrimitiveType();
+ mTessEvaluationShaderInputVertexSpacingType =
+ parseContext.getTessEvaluationShaderInputVertexSpacingType();
+ mTessEvaluationShaderInputOrderingType =
+ parseContext.getTessEvaluationShaderInputOrderingType();
+ mTessEvaluationShaderInputPointType = parseContext.getTessEvaluationShaderInputPointType();
+ }
+}
+
+unsigned int TCompiler::getSharedMemorySize() const
+{
+ unsigned int sharedMemSize = 0;
+ for (const sh::ShaderVariable &var : mSharedVariables)
+ {
+ sharedMemSize += var.getExternalSize();
+ }
+
+ return sharedMemSize;
+}
+
+bool TCompiler::validateAST(TIntermNode *root)
+{
+ if (mCompileOptions.validateAST)
+ {
+ bool valid = ValidateAST(root, &mDiagnostics, mValidateASTOptions);
+
+#if defined(ANGLE_ENABLE_ASSERTS)
+ if (!valid)
+ {
+ OutputTree(root, mInfoSink.info);
+ fprintf(stderr, "AST validation error(s):\n%s\n", mInfoSink.info.c_str());
+ }
+#endif
+ // In debug, assert validation. In release, validation errors will be returned back to the
+ // application as internal ANGLE errors.
+ ASSERT(valid);
+
+ return valid;
+ }
+ return true;
+}
+
+bool TCompiler::disableValidateFunctionCall()
+{
+ bool wasEnabled = mValidateASTOptions.validateFunctionCall;
+ mValidateASTOptions.validateFunctionCall = false;
+ return wasEnabled;
+}
+
+void TCompiler::restoreValidateFunctionCall(bool enable)
+{
+ ASSERT(!mValidateASTOptions.validateFunctionCall);
+ mValidateASTOptions.validateFunctionCall = enable;
+}
+
+bool TCompiler::disableValidateVariableReferences()
+{
+ bool wasEnabled = mValidateASTOptions.validateVariableReferences;
+ mValidateASTOptions.validateVariableReferences = false;
+ return wasEnabled;
+}
+
+void TCompiler::restoreValidateVariableReferences(bool enable)
+{
+ ASSERT(!mValidateASTOptions.validateVariableReferences);
+ mValidateASTOptions.validateVariableReferences = enable;
+}
+
+void TCompiler::enableValidateNoMoreTransformations()
+{
+ mValidateASTOptions.validateNoMoreTransformations = true;
+}
+
+bool TCompiler::checkAndSimplifyAST(TIntermBlock *root,
+ const TParseContext &parseContext,
+ const ShCompileOptions &compileOptions)
+{
+ mValidateASTOptions = {};
+
+ // Desktop GLSL shaders don't have precision, so don't expect them to be specified.
+ mValidateASTOptions.validatePrecision = !IsDesktopGLSpec(mShaderSpec);
+
+ if (!validateAST(root))
+ {
+ return false;
+ }
+
+ // For now, rewrite pixel local storage before collecting variables or any operations on images.
+ //
+ // TODO(anglebug.com/7279):
+ // Should this actually run after collecting variables?
+ // Do we need more introspection?
+ // Do we want to hide rewritten shader image uniforms from glGetActiveUniform?
+ if (hasPixelLocalStorageUniforms())
+ {
+ ASSERT(
+ IsExtensionEnabled(mExtensionBehavior, TExtension::ANGLE_shader_pixel_local_storage));
+ if (!RewritePixelLocalStorage(this, root, getSymbolTable(), compileOptions,
+ getShaderVersion()))
+ {
+ mDiagnostics.globalError("internal compiler error translating pixel local storage");
+ return false;
+ }
+ }
+
+ // Disallow expressions deemed too complex.
+ if (compileOptions.limitExpressionComplexity && !limitExpressionComplexity(root))
+ {
+ return false;
+ }
+
+ if (shouldRunLoopAndIndexingValidation(compileOptions) &&
+ !ValidateLimitations(root, mShaderType, &mSymbolTable, &mDiagnostics))
+ {
+ return false;
+ }
+
+ if (shouldLimitTypeSizes() && !ValidateTypeSizeLimitations(root, &mSymbolTable, &mDiagnostics))
+ {
+ return false;
+ }
+
+ if (!ValidateFragColorAndFragData(mShaderType, mShaderVersion, mSymbolTable, &mDiagnostics))
+ {
+ return false;
+ }
+
+ // Fold expressions that could not be folded before validation that was done as a part of
+ // parsing.
+ if (!FoldExpressions(this, root, &mDiagnostics))
+ {
+ return false;
+ }
+ // Folding should only be able to generate warnings.
+ ASSERT(mDiagnostics.numErrors() == 0);
+
+ // Validate no barrier() after return before prunning it in |PruneNoOps()| below.
+ if (mShaderType == GL_TESS_CONTROL_SHADER && !ValidateBarrierFunctionCall(root, &mDiagnostics))
+ {
+ return false;
+ }
+
+ // We prune no-ops to work around driver bugs and to keep AST processing and output simple.
+ // The following kinds of no-ops are pruned:
+ // 1. Empty declarations "int;".
+ // 2. Literal statements: "1.0;". The ESSL output doesn't define a default precision
+ // for float, so float literal statements would end up with no precision which is
+ // invalid ESSL.
+ // 3. Any unreachable statement after a discard, return, break or continue.
+ // After this empty declarations are not allowed in the AST.
+ if (!PruneNoOps(this, root, &mSymbolTable))
+ {
+ return false;
+ }
+ mValidateASTOptions.validateNoStatementsAfterBranch = true;
+
+ // We need to generate globals early if we have non constant initializers enabled
+ bool initializeLocalsAndGlobals =
+ compileOptions.initializeUninitializedLocals && !IsOutputHLSL(getOutputType());
+ bool canUseLoopsToInitialize = !compileOptions.dontUseLoopsToInitializeVariables;
+ bool highPrecisionSupported = isHighPrecisionSupported();
+ bool enableNonConstantInitializers = IsExtensionEnabled(
+ mExtensionBehavior, TExtension::EXT_shader_non_constant_global_initializers);
+ // forceDeferGlobalInitializers is needed for MSL
+ // to convert a non-const global. For example:
+ //
+ // int someGlobal = 123;
+ //
+ // to
+ //
+ // int someGlobal;
+ // void main() {
+ // someGlobal = 123;
+ //
+ // This is because MSL doesn't allow statically initialized globals.
+ bool forceDeferGlobalInitializers = getOutputType() == SH_MSL_METAL_OUTPUT;
+
+ if (enableNonConstantInitializers &&
+ !DeferGlobalInitializers(this, root, initializeLocalsAndGlobals, canUseLoopsToInitialize,
+ highPrecisionSupported, forceDeferGlobalInitializers,
+ &mSymbolTable))
+ {
+ return false;
+ }
+
+ // Create the function DAG and check there is no recursion
+ if (!initCallDag(root))
+ {
+ return false;
+ }
+
+ if (compileOptions.limitCallStackDepth && !checkCallDepth())
+ {
+ return false;
+ }
+
+ // Checks which functions are used and if "main" exists
+ mFunctionMetadata.clear();
+ mFunctionMetadata.resize(mCallDag.size());
+ if (!tagUsedFunctions())
+ {
+ return false;
+ }
+
+ if (!pruneUnusedFunctions(root))
+ {
+ return false;
+ }
+
+ if (IsSpecWithFunctionBodyNewScope(mShaderSpec, mShaderVersion))
+ {
+ if (!ReplaceShadowingVariables(this, root, &mSymbolTable))
+ {
+ return false;
+ }
+ }
+
+ if (mShaderVersion >= 310 && !ValidateVaryingLocations(root, &mDiagnostics, mShaderType))
+ {
+ return false;
+ }
+
+ // anglebug.com/7484: The ESSL spec has a bug with images as function arguments. The recommended
+ // workaround is to inline functions that accept image arguments.
+ if (mShaderVersion >= 310 && !MonomorphizeUnsupportedFunctions(
+ this, root, &mSymbolTable, compileOptions,
+ UnsupportedFunctionArgsBitSet{UnsupportedFunctionArgs::Image}))
+ {
+ return false;
+ }
+
+ if (mShaderVersion >= 300 && mShaderType == GL_FRAGMENT_SHADER &&
+ !ValidateOutputs(root, getExtensionBehavior(), mResources.MaxDrawBuffers, &mDiagnostics))
+ {
+ return false;
+ }
+
+ if (parseContext.isExtensionEnabled(TExtension::EXT_clip_cull_distance))
+ {
+ if (!ValidateClipCullDistance(root, &mDiagnostics,
+ mResources.MaxCombinedClipAndCullDistances))
+ {
+ return false;
+ }
+ }
+
+ // Clamping uniform array bounds needs to happen after validateLimitations pass.
+ if (compileOptions.clampIndirectArrayBounds)
+ {
+ if (!ClampIndirectIndices(this, root, &mSymbolTable))
+ {
+ return false;
+ }
+ }
+
+ if (compileOptions.initializeBuiltinsForInstancedMultiview &&
+ (parseContext.isExtensionEnabled(TExtension::OVR_multiview2) ||
+ parseContext.isExtensionEnabled(TExtension::OVR_multiview)) &&
+ getShaderType() != GL_COMPUTE_SHADER)
+ {
+ if (!DeclareAndInitBuiltinsForInstancedMultiview(
+ this, root, mNumViews, mShaderType, compileOptions, mOutputType, &mSymbolTable))
+ {
+ return false;
+ }
+ }
+
+ // This pass might emit short circuits so keep it before the short circuit unfolding
+ if (compileOptions.rewriteDoWhileLoops)
+ {
+ if (!RewriteDoWhile(this, root, &mSymbolTable))
+ {
+ return false;
+ }
+ }
+
+ if (compileOptions.addAndTrueToLoopCondition)
+ {
+ if (!AddAndTrueToLoopCondition(this, root))
+ {
+ return false;
+ }
+ }
+
+ if (compileOptions.unfoldShortCircuit)
+ {
+ if (!UnfoldShortCircuitAST(this, root))
+ {
+ return false;
+ }
+ }
+
+ if (compileOptions.regenerateStructNames)
+ {
+ if (!RegenerateStructNames(this, root, &mSymbolTable))
+ {
+ return false;
+ }
+ }
+
+ if (mShaderType == GL_VERTEX_SHADER &&
+ IsExtensionEnabled(mExtensionBehavior, TExtension::ANGLE_multi_draw))
+ {
+ if (compileOptions.emulateGLDrawID)
+ {
+ if (!EmulateGLDrawID(this, root, &mSymbolTable, &mUniforms,
+ shouldCollectVariables(compileOptions)))
+ {
+ return false;
+ }
+ }
+ }
+
+ if (mShaderType == GL_VERTEX_SHADER &&
+ IsExtensionEnabled(mExtensionBehavior,
+ TExtension::ANGLE_base_vertex_base_instance_shader_builtin))
+ {
+ if (compileOptions.emulateGLBaseVertexBaseInstance)
+ {
+ if (!EmulateGLBaseVertexBaseInstance(this, root, &mSymbolTable, &mUniforms,
+ shouldCollectVariables(compileOptions),
+ compileOptions.addBaseVertexToVertexID))
+ {
+ return false;
+ }
+ }
+ }
+
+ if (mShaderType == GL_FRAGMENT_SHADER && mShaderVersion == 100 && mResources.EXT_draw_buffers &&
+ mResources.MaxDrawBuffers > 1 &&
+ IsExtensionEnabled(mExtensionBehavior, TExtension::EXT_draw_buffers))
+ {
+ if (!EmulateGLFragColorBroadcast(this, root, mResources.MaxDrawBuffers, &mOutputVariables,
+ &mSymbolTable, mShaderVersion))
+ {
+ return false;
+ }
+ }
+
+ int simplifyScalarized = compileOptions.scalarizeVecAndMatConstructorArgs
+ ? IntermNodePatternMatcher::kScalarizedVecOrMatConstructor
+ : 0;
+
+ // Split multi declarations and remove calls to array length().
+ // 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.
+ if (!SimplifyLoopConditions(this, root,
+ IntermNodePatternMatcher::kMultiDeclaration |
+ IntermNodePatternMatcher::kArrayLengthMethod |
+ simplifyScalarized,
+ &getSymbolTable()))
+ {
+ return false;
+ }
+
+ // Note that separate declarations need to be run before other AST transformations that
+ // generate new statements from expressions.
+ if (!SeparateDeclarations(this, root, &getSymbolTable()))
+ {
+ return false;
+ }
+ mValidateASTOptions.validateMultiDeclarations = true;
+
+ if (!SplitSequenceOperator(this, root,
+ IntermNodePatternMatcher::kArrayLengthMethod | simplifyScalarized,
+ &getSymbolTable()))
+ {
+ return false;
+ }
+
+ if (!RemoveArrayLengthMethod(this, root))
+ {
+ return false;
+ }
+
+ if (!RemoveUnreferencedVariables(this, root, &mSymbolTable))
+ {
+ return false;
+ }
+
+ // In case the last case inside a switch statement is a certain type of no-op, GLSL compilers in
+ // drivers may not accept it. In this case we clean up the dead code from the end of switch
+ // statements. This is also required because PruneNoOps or RemoveUnreferencedVariables may have
+ // left switch statements that only contained an empty declaration inside the final case in an
+ // invalid state. Relies on that PruneNoOps and RemoveUnreferencedVariables have already been
+ // run.
+ if (!PruneEmptyCases(this, root))
+ {
+ return false;
+ }
+
+ // Built-in function emulation needs to happen after validateLimitations pass.
+ GetGlobalPoolAllocator()->lock();
+ initBuiltInFunctionEmulator(&mBuiltInFunctionEmulator, compileOptions);
+ GetGlobalPoolAllocator()->unlock();
+ mBuiltInFunctionEmulator.markBuiltInFunctionsForEmulation(root);
+
+ if (compileOptions.scalarizeVecAndMatConstructorArgs)
+ {
+ if (!ScalarizeVecAndMatConstructorArgs(this, root, &mSymbolTable))
+ {
+ return false;
+ }
+ }
+
+ if (compileOptions.forceShaderPrecisionHighpToMediump)
+ {
+ if (!ForceShaderPrecisionToMediump(root, &mSymbolTable, mShaderType))
+ {
+ return false;
+ }
+ }
+
+ if (shouldCollectVariables(compileOptions))
+ {
+ ASSERT(!mVariablesCollected);
+ CollectVariables(root, &mAttributes, &mOutputVariables, &mUniforms, &mInputVaryings,
+ &mOutputVaryings, &mSharedVariables, &mUniformBlocks,
+ &mShaderStorageBlocks, mResources.HashFunction, &mSymbolTable, mShaderType,
+ mExtensionBehavior, mResources, mTessControlShaderOutputVertices);
+ collectInterfaceBlocks();
+ mVariablesCollected = true;
+ if (compileOptions.useUnusedStandardSharedBlocks)
+ {
+ if (!useAllMembersInUnusedStandardAndSharedBlocks(root))
+ {
+ return false;
+ }
+ }
+ if (compileOptions.enforcePackingRestrictions)
+ {
+ int maxUniformVectors = GetMaxUniformVectorsForShaderType(mShaderType, mResources);
+ // Returns true if, after applying the packing rules in the GLSL ES 1.00.17 spec
+ // Appendix A, section 7, the shader does not use too many uniforms.
+ if (!CheckVariablesInPackingLimits(maxUniformVectors, mUniforms))
+ {
+ mDiagnostics.globalError("too many uniforms");
+ return false;
+ }
+ }
+ bool needInitializeOutputVariables =
+ compileOptions.initOutputVariables && mShaderType != GL_COMPUTE_SHADER;
+ needInitializeOutputVariables |=
+ compileOptions.initFragmentOutputVariables && mShaderType == GL_FRAGMENT_SHADER;
+ if (needInitializeOutputVariables)
+ {
+ if (!initializeOutputVariables(root))
+ {
+ return false;
+ }
+ }
+ }
+
+ // Removing invariant declarations must be done after collecting variables.
+ // Otherwise, built-in invariant declarations don't apply.
+ if (RemoveInvariant(mShaderType, mShaderVersion, mOutputType, compileOptions))
+ {
+ if (!RemoveInvariantDeclaration(this, root))
+ {
+ return false;
+ }
+ }
+
+ // gl_Position is always written in compatibility output mode.
+ // It may have been already initialized among other output variables, in that case we don't
+ // need to initialize it twice.
+ if (mShaderType == GL_VERTEX_SHADER && !mGLPositionInitialized &&
+ (compileOptions.initGLPosition || mOutputType == SH_GLSL_COMPATIBILITY_OUTPUT))
+ {
+ if (!initializeGLPosition(root))
+ {
+ return false;
+ }
+ mGLPositionInitialized = true;
+ }
+
+ if (mShaderType == GL_VERTEX_SHADER && compileOptions.initGLPointSize)
+ {
+ sh::ShaderVariable var(GL_FLOAT);
+ var.name = "gl_PointSize";
+ if (!InitializeVariables(this, root, {var}, &mSymbolTable, mShaderVersion,
+ mExtensionBehavior, false, false))
+ {
+ return false;
+ }
+ }
+
+ // DeferGlobalInitializers needs to be run before other AST transformations that generate new
+ // statements from expressions. But it's fine to run DeferGlobalInitializers after the above
+ // SplitSequenceOperator and RemoveArrayLengthMethod since they only have an effect on the AST
+ // on ESSL >= 3.00, and the initializers that need to be deferred can only exist in ESSL < 3.00.
+ // Exception: if EXT_shader_non_constant_global_initializers is enabled, we must generate global
+ // initializers before we generate the DAG, since initializers may call functions which must not
+ // be optimized out
+ if (!enableNonConstantInitializers &&
+ !DeferGlobalInitializers(this, root, initializeLocalsAndGlobals, canUseLoopsToInitialize,
+ highPrecisionSupported, forceDeferGlobalInitializers,
+ &mSymbolTable))
+ {
+ return false;
+ }
+
+ if (initializeLocalsAndGlobals)
+ {
+ // Initialize uninitialized local variables.
+ // In some cases initializing can generate extra statements in the parent block, such as
+ // when initializing nameless structs or initializing arrays in ESSL 1.00. In that case
+ // we need to first simplify loop conditions. We've already separated declarations
+ // earlier, which is also required. If we don't follow the Appendix A limitations, loop
+ // init statements can declare arrays or nameless structs and have multiple
+ // declarations.
+
+ if (!shouldRunLoopAndIndexingValidation(compileOptions))
+ {
+ if (!SimplifyLoopConditions(this, root,
+ IntermNodePatternMatcher::kArrayDeclaration |
+ IntermNodePatternMatcher::kNamelessStructDeclaration,
+ &getSymbolTable()))
+ {
+ return false;
+ }
+ }
+
+ if (!InitializeUninitializedLocals(this, root, getShaderVersion(), canUseLoopsToInitialize,
+ highPrecisionSupported, &getSymbolTable()))
+ {
+ return false;
+ }
+ }
+
+ if (getShaderType() == GL_VERTEX_SHADER && compileOptions.clampPointSize)
+ {
+ if (!ClampPointSize(this, root, mResources.MaxPointSize, &getSymbolTable()))
+ {
+ return false;
+ }
+ }
+
+ if (getShaderType() == GL_FRAGMENT_SHADER && compileOptions.clampFragDepth)
+ {
+ if (!ClampFragDepth(this, root, &getSymbolTable()))
+ {
+ return false;
+ }
+ }
+
+ if (compileOptions.rewriteRepeatedAssignToSwizzled)
+ {
+ if (!sh::RewriteRepeatedAssignToSwizzled(this, root))
+ {
+ return false;
+ }
+ }
+
+ if (compileOptions.removeDynamicIndexingOfSwizzledVector)
+ {
+ if (!sh::RemoveDynamicIndexingOfSwizzledVector(this, root, &getSymbolTable(), nullptr))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool TCompiler::postParseChecks(const TParseContext &parseContext)
+{
+ std::stringstream errorMessage;
+
+ if (parseContext.getTreeRoot() == nullptr)
+ {
+ errorMessage << "Shader parsing failed (mTreeRoot == nullptr)";
+ }
+
+ for (TType *type : parseContext.getDeferredArrayTypesToSize())
+ {
+ errorMessage << "Unsized global array type: " << type->getBasicString();
+ }
+
+ if (!errorMessage.str().empty())
+ {
+ mDiagnostics.globalError(errorMessage.str().c_str());
+ return false;
+ }
+
+ return true;
+}
+
+bool TCompiler::compile(const char *const shaderStrings[],
+ size_t numStrings,
+ const ShCompileOptions &compileOptionsIn)
+{
+#if defined(ANGLE_FUZZER_CORPUS_OUTPUT_DIR)
+ DumpFuzzerCase(shaderStrings, numStrings, mShaderType, mShaderSpec, mOutputType,
+ compileOptionsIn);
+#endif // defined(ANGLE_FUZZER_CORPUS_OUTPUT_DIR)
+
+ 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.flattenPragmaSTDGLInvariantAll = true;
+ }
+
+ TScopedPoolAllocator scopedAlloc(&allocator);
+ TIntermBlock *root = compileTreeImpl(shaderStrings, numStrings, compileOptions);
+
+ if (root)
+ {
+ if (compileOptions.intermediateTree)
+ {
+ OutputTree(root, mInfoSink.info);
+ }
+
+ if (compileOptions.objectCode)
+ {
+ PerformanceDiagnostics perfDiagnostics(&mDiagnostics);
+ if (!translate(root, compileOptions, &perfDiagnostics))
+ {
+ return false;
+ }
+ }
+
+ if (mShaderType == GL_VERTEX_SHADER)
+ {
+ bool lookForDrawID =
+ IsExtensionEnabled(mExtensionBehavior, TExtension::ANGLE_multi_draw) &&
+ compileOptions.emulateGLDrawID;
+ bool lookForBaseVertexBaseInstance =
+ IsExtensionEnabled(mExtensionBehavior,
+ TExtension::ANGLE_base_vertex_base_instance_shader_builtin) &&
+ compileOptions.emulateGLBaseVertexBaseInstance;
+
+ if (lookForDrawID || lookForBaseVertexBaseInstance)
+ {
+ for (auto &uniform : mUniforms)
+ {
+ if (lookForDrawID && uniform.name == "angle_DrawID" &&
+ uniform.mappedName == "angle_DrawID")
+ {
+ uniform.name = "gl_DrawID";
+ }
+ else if (lookForBaseVertexBaseInstance && uniform.name == "angle_BaseVertex" &&
+ uniform.mappedName == "angle_BaseVertex")
+ {
+ uniform.name = "gl_BaseVertex";
+ }
+ else if (lookForBaseVertexBaseInstance &&
+ uniform.name == "angle_BaseInstance" &&
+ uniform.mappedName == "angle_BaseInstance")
+ {
+ uniform.name = "gl_BaseInstance";
+ }
+ }
+ }
+ }
+
+ // The IntermNode tree doesn't need to be deleted here, since the
+ // memory will be freed in a big chunk by the PoolAllocator.
+ return true;
+ }
+ return false;
+}
+
+bool TCompiler::initBuiltInSymbolTable(const ShBuiltInResources &resources)
+{
+ if (resources.MaxDrawBuffers < 1)
+ {
+ return false;
+ }
+ if (resources.EXT_blend_func_extended && resources.MaxDualSourceDrawBuffers < 1)
+ {
+ return false;
+ }
+
+ mSymbolTable.initializeBuiltIns(mShaderType, mShaderSpec, resources);
+
+ return true;
+}
+
+void TCompiler::setResourceString()
+{
+ std::ostringstream strstream = sh::InitializeStream<std::ostringstream>();
+
+ // clang-format off
+ strstream << ":MaxVertexAttribs:" << mResources.MaxVertexAttribs
+ << ":MaxVertexUniformVectors:" << mResources.MaxVertexUniformVectors
+ << ":MaxVaryingVectors:" << mResources.MaxVaryingVectors
+ << ":MaxVertexTextureImageUnits:" << mResources.MaxVertexTextureImageUnits
+ << ":MaxCombinedTextureImageUnits:" << mResources.MaxCombinedTextureImageUnits
+ << ":MaxTextureImageUnits:" << mResources.MaxTextureImageUnits
+ << ":MaxFragmentUniformVectors:" << mResources.MaxFragmentUniformVectors
+ << ":MaxDrawBuffers:" << mResources.MaxDrawBuffers
+ << ":OES_standard_derivatives:" << mResources.OES_standard_derivatives
+ << ":OES_EGL_image_external:" << mResources.OES_EGL_image_external
+ << ":OES_EGL_image_external_essl3:" << mResources.OES_EGL_image_external_essl3
+ << ":NV_EGL_stream_consumer_external:" << mResources.NV_EGL_stream_consumer_external
+ << ":ARB_texture_rectangle:" << mResources.ARB_texture_rectangle
+ << ":EXT_draw_buffers:" << mResources.EXT_draw_buffers
+ << ":FragmentPrecisionHigh:" << mResources.FragmentPrecisionHigh
+ << ":MaxExpressionComplexity:" << mResources.MaxExpressionComplexity
+ << ":MaxCallStackDepth:" << mResources.MaxCallStackDepth
+ << ":MaxFunctionParameters:" << mResources.MaxFunctionParameters
+ << ":EXT_blend_func_extended:" << mResources.EXT_blend_func_extended
+ << ":EXT_frag_depth:" << mResources.EXT_frag_depth
+ << ":EXT_primitive_bounding_box:" << mResources.EXT_primitive_bounding_box
+ << ":OES_primitive_bounding_box:" << mResources.OES_primitive_bounding_box
+ << ":EXT_shader_texture_lod:" << mResources.EXT_shader_texture_lod
+ << ":EXT_shader_framebuffer_fetch:" << mResources.EXT_shader_framebuffer_fetch
+ << ":EXT_shader_framebuffer_fetch_non_coherent:" << mResources.EXT_shader_framebuffer_fetch_non_coherent
+ << ":NV_shader_framebuffer_fetch:" << mResources.NV_shader_framebuffer_fetch
+ << ":ARM_shader_framebuffer_fetch:" << mResources.ARM_shader_framebuffer_fetch
+ << ":OVR_multiview2:" << mResources.OVR_multiview2
+ << ":OVR_multiview:" << mResources.OVR_multiview
+ << ":EXT_YUV_target:" << mResources.EXT_YUV_target
+ << ":EXT_geometry_shader:" << mResources.EXT_geometry_shader
+ << ":OES_geometry_shader:" << mResources.OES_geometry_shader
+ << ":OES_shader_io_blocks:" << mResources.OES_shader_io_blocks
+ << ":EXT_shader_io_blocks:" << mResources.EXT_shader_io_blocks
+ << ":EXT_gpu_shader5:" << mResources.EXT_gpu_shader5
+ << ":OES_texture_3D:" << mResources.OES_texture_3D
+ << ":MaxVertexOutputVectors:" << mResources.MaxVertexOutputVectors
+ << ":MaxFragmentInputVectors:" << mResources.MaxFragmentInputVectors
+ << ":MinProgramTexelOffset:" << mResources.MinProgramTexelOffset
+ << ":MaxProgramTexelOffset:" << mResources.MaxProgramTexelOffset
+ << ":MaxDualSourceDrawBuffers:" << mResources.MaxDualSourceDrawBuffers
+ << ":MaxViewsOVR:" << mResources.MaxViewsOVR
+ << ":NV_draw_buffers:" << mResources.NV_draw_buffers
+ << ":ANGLE_multi_draw:" << mResources.ANGLE_multi_draw
+ << ":ANGLE_base_vertex_base_instance_shader_builtin:" << mResources.ANGLE_base_vertex_base_instance_shader_builtin
+ << ":APPLE_clip_distance:" << mResources.APPLE_clip_distance
+ << ":OES_texture_cube_map_array:" << mResources.OES_texture_cube_map_array
+ << ":EXT_texture_cube_map_array:" << mResources.EXT_texture_cube_map_array
+ << ":EXT_shadow_samplers:" << mResources.EXT_shadow_samplers
+ << ":OES_shader_multisample_interpolation:" << mResources.OES_shader_multisample_interpolation
+ << ":OES_shader_image_atomic:" << mResources.OES_shader_image_atomic
+ << ":EXT_tessellation_shader:" << mResources.EXT_tessellation_shader
+ << ":OES_texture_buffer:" << mResources.OES_texture_buffer
+ << ":EXT_texture_buffer:" << mResources.EXT_texture_buffer
+ << ":OES_sample_variables:" << mResources.OES_sample_variables
+ << ":EXT_clip_cull_distance:" << mResources.EXT_clip_cull_distance
+ << ":MinProgramTextureGatherOffset:" << mResources.MinProgramTextureGatherOffset
+ << ":MaxProgramTextureGatherOffset:" << mResources.MaxProgramTextureGatherOffset
+ << ":MaxImageUnits:" << mResources.MaxImageUnits
+ << ":MaxSamples:" << mResources.MaxSamples
+ << ":MaxVertexImageUniforms:" << mResources.MaxVertexImageUniforms
+ << ":MaxFragmentImageUniforms:" << mResources.MaxFragmentImageUniforms
+ << ":MaxComputeImageUniforms:" << mResources.MaxComputeImageUniforms
+ << ":MaxCombinedImageUniforms:" << mResources.MaxCombinedImageUniforms
+ << ":MaxCombinedShaderOutputResources:" << mResources.MaxCombinedShaderOutputResources
+ << ":MaxComputeWorkGroupCountX:" << mResources.MaxComputeWorkGroupCount[0]
+ << ":MaxComputeWorkGroupCountY:" << mResources.MaxComputeWorkGroupCount[1]
+ << ":MaxComputeWorkGroupCountZ:" << mResources.MaxComputeWorkGroupCount[2]
+ << ":MaxComputeWorkGroupSizeX:" << mResources.MaxComputeWorkGroupSize[0]
+ << ":MaxComputeWorkGroupSizeY:" << mResources.MaxComputeWorkGroupSize[1]
+ << ":MaxComputeWorkGroupSizeZ:" << mResources.MaxComputeWorkGroupSize[2]
+ << ":MaxComputeUniformComponents:" << mResources.MaxComputeUniformComponents
+ << ":MaxComputeTextureImageUnits:" << mResources.MaxComputeTextureImageUnits
+ << ":MaxComputeAtomicCounters:" << mResources.MaxComputeAtomicCounters
+ << ":MaxComputeAtomicCounterBuffers:" << mResources.MaxComputeAtomicCounterBuffers
+ << ":MaxVertexAtomicCounters:" << mResources.MaxVertexAtomicCounters
+ << ":MaxFragmentAtomicCounters:" << mResources.MaxFragmentAtomicCounters
+ << ":MaxCombinedAtomicCounters:" << mResources.MaxCombinedAtomicCounters
+ << ":MaxAtomicCounterBindings:" << mResources.MaxAtomicCounterBindings
+ << ":MaxVertexAtomicCounterBuffers:" << mResources.MaxVertexAtomicCounterBuffers
+ << ":MaxFragmentAtomicCounterBuffers:" << mResources.MaxFragmentAtomicCounterBuffers
+ << ":MaxCombinedAtomicCounterBuffers:" << mResources.MaxCombinedAtomicCounterBuffers
+ << ":MaxAtomicCounterBufferSize:" << mResources.MaxAtomicCounterBufferSize
+ << ":MaxGeometryUniformComponents:" << mResources.MaxGeometryUniformComponents
+ << ":MaxGeometryUniformBlocks:" << mResources.MaxGeometryUniformBlocks
+ << ":MaxGeometryInputComponents:" << mResources.MaxGeometryInputComponents
+ << ":MaxGeometryOutputComponents:" << mResources.MaxGeometryOutputComponents
+ << ":MaxGeometryOutputVertices:" << mResources.MaxGeometryOutputVertices
+ << ":MaxGeometryTotalOutputComponents:" << mResources.MaxGeometryTotalOutputComponents
+ << ":MaxGeometryTextureImageUnits:" << mResources.MaxGeometryTextureImageUnits
+ << ":MaxGeometryAtomicCounterBuffers:" << mResources.MaxGeometryAtomicCounterBuffers
+ << ":MaxGeometryAtomicCounters:" << mResources.MaxGeometryAtomicCounters
+ << ":MaxGeometryShaderStorageBlocks:" << mResources.MaxGeometryShaderStorageBlocks
+ << ":MaxGeometryShaderInvocations:" << mResources.MaxGeometryShaderInvocations
+ << ":MaxGeometryImageUniforms:" << mResources.MaxGeometryImageUniforms
+ << ":MaxClipDistances" << mResources.MaxClipDistances
+ << ":MaxCullDistances" << mResources.MaxCullDistances
+ << ":MaxCombinedClipAndCullDistances" << mResources.MaxCombinedClipAndCullDistances
+ << ":MaxTessControlInputComponents:" << mResources.MaxTessControlInputComponents
+ << ":MaxTessControlOutputComponents:" << mResources.MaxTessControlOutputComponents
+ << ":MaxTessControlTextureImageUnits:" << mResources.MaxTessControlTextureImageUnits
+ << ":MaxTessControlUniformComponents:" << mResources.MaxTessControlUniformComponents
+ << ":MaxTessControlTotalOutputComponents:" << mResources.MaxTessControlTotalOutputComponents
+ << ":MaxTessControlImageUniforms:" << mResources.MaxTessControlImageUniforms
+ << ":MaxTessControlAtomicCounters:" << mResources.MaxTessControlAtomicCounters
+ << ":MaxTessControlAtomicCounterBuffers:" << mResources.MaxTessControlAtomicCounterBuffers
+ << ":MaxTessPatchComponents:" << mResources.MaxTessPatchComponents
+ << ":MaxPatchVertices:" << mResources.MaxPatchVertices
+ << ":MaxTessGenLevel:" << mResources.MaxTessGenLevel
+ << ":MaxTessEvaluationInputComponents:" << mResources.MaxTessEvaluationInputComponents
+ << ":MaxTessEvaluationOutputComponents:" << mResources.MaxTessEvaluationOutputComponents
+ << ":MaxTessEvaluationTextureImageUnits:" << mResources.MaxTessEvaluationTextureImageUnits
+ << ":MaxTessEvaluationUniformComponents:" << mResources.MaxTessEvaluationUniformComponents
+ << ":MaxTessEvaluationImageUniforms:" << mResources.MaxTessEvaluationImageUniforms
+ << ":MaxTessEvaluationAtomicCounters:" << mResources.MaxTessEvaluationAtomicCounters
+ << ":MaxTessEvaluationAtomicCounterBuffers:" << mResources.MaxTessEvaluationAtomicCounterBuffers;
+ // clang-format on
+
+ mBuiltInResourcesString = strstream.str();
+}
+
+void TCompiler::collectInterfaceBlocks()
+{
+ ASSERT(mInterfaceBlocks.empty());
+ mInterfaceBlocks.reserve(mUniformBlocks.size() + mShaderStorageBlocks.size());
+ mInterfaceBlocks.insert(mInterfaceBlocks.end(), mUniformBlocks.begin(), mUniformBlocks.end());
+ mInterfaceBlocks.insert(mInterfaceBlocks.end(), mShaderStorageBlocks.begin(),
+ mShaderStorageBlocks.end());
+}
+
+void TCompiler::clearResults()
+{
+ mInfoSink.info.erase();
+ mInfoSink.obj.erase();
+ mInfoSink.debug.erase();
+ mDiagnostics.resetErrorCount();
+
+ mAttributes.clear();
+ mOutputVariables.clear();
+ mUniforms.clear();
+ mInputVaryings.clear();
+ mOutputVaryings.clear();
+ mSharedVariables.clear();
+ mInterfaceBlocks.clear();
+ mUniformBlocks.clear();
+ mShaderStorageBlocks.clear();
+ mVariablesCollected = false;
+ mGLPositionInitialized = false;
+
+ mNumViews = -1;
+
+ mGeometryShaderInputPrimitiveType = EptUndefined;
+ mGeometryShaderOutputPrimitiveType = EptUndefined;
+ mGeometryShaderInvocations = 0;
+ mGeometryShaderMaxVertices = -1;
+
+ mTessControlShaderOutputVertices = 0;
+ mTessEvaluationShaderInputPrimitiveType = EtetUndefined;
+ mTessEvaluationShaderInputVertexSpacingType = EtetUndefined;
+ mTessEvaluationShaderInputOrderingType = EtetUndefined;
+ mTessEvaluationShaderInputPointType = EtetUndefined;
+
+ mBuiltInFunctionEmulator.cleanup();
+
+ mNameMap.clear();
+
+ mSourcePath = nullptr;
+
+ mSymbolTable.clearCompilationResults();
+}
+
+bool TCompiler::initCallDag(TIntermNode *root)
+{
+ mCallDag.clear();
+
+ switch (mCallDag.init(root, &mDiagnostics))
+ {
+ case CallDAG::INITDAG_SUCCESS:
+ return true;
+ case CallDAG::INITDAG_RECURSION:
+ case CallDAG::INITDAG_UNDEFINED:
+ // Error message has already been written out.
+ ASSERT(mDiagnostics.numErrors() > 0);
+ return false;
+ }
+
+ UNREACHABLE();
+ return true;
+}
+
+bool TCompiler::checkCallDepth()
+{
+ std::vector<int> depths(mCallDag.size());
+
+ for (size_t i = 0; i < mCallDag.size(); i++)
+ {
+ int depth = 0;
+ const CallDAG::Record &record = mCallDag.getRecordFromIndex(i);
+
+ for (int calleeIndex : record.callees)
+ {
+ depth = std::max(depth, depths[calleeIndex] + 1);
+ }
+
+ depths[i] = depth;
+
+ if (depth >= mResources.MaxCallStackDepth)
+ {
+ // Trace back the function chain to have a meaningful info log.
+ std::stringstream errorStream = sh::InitializeStream<std::stringstream>();
+ errorStream << "Call stack too deep (larger than " << mResources.MaxCallStackDepth
+ << ") with the following call chain: "
+ << record.node->getFunction()->name();
+
+ int currentFunction = static_cast<int>(i);
+ int currentDepth = depth;
+
+ while (currentFunction != -1)
+ {
+ errorStream
+ << " -> "
+ << mCallDag.getRecordFromIndex(currentFunction).node->getFunction()->name();
+
+ int nextFunction = -1;
+ for (const int &calleeIndex : mCallDag.getRecordFromIndex(currentFunction).callees)
+ {
+ if (depths[calleeIndex] == currentDepth - 1)
+ {
+ currentDepth--;
+ nextFunction = calleeIndex;
+ }
+ }
+
+ currentFunction = nextFunction;
+ }
+
+ std::string errorStr = errorStream.str();
+ mDiagnostics.globalError(errorStr.c_str());
+
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool TCompiler::tagUsedFunctions()
+{
+ // Search from main, starting from the end of the DAG as it usually is the root.
+ for (size_t i = mCallDag.size(); i-- > 0;)
+ {
+ if (mCallDag.getRecordFromIndex(i).node->getFunction()->isMain())
+ {
+ internalTagUsedFunction(i);
+ return true;
+ }
+ }
+
+ mDiagnostics.globalError("Missing main()");
+ return false;
+}
+
+void TCompiler::internalTagUsedFunction(size_t index)
+{
+ if (mFunctionMetadata[index].used)
+ {
+ return;
+ }
+
+ mFunctionMetadata[index].used = true;
+
+ for (int calleeIndex : mCallDag.getRecordFromIndex(index).callees)
+ {
+ internalTagUsedFunction(calleeIndex);
+ }
+}
+
+bool TCompiler::pruneUnusedFunctions(TIntermBlock *root)
+{
+ TIntermSequence *sequence = root->getSequence();
+
+ size_t writeIndex = 0;
+ for (size_t readIndex = 0; readIndex < sequence->size(); ++readIndex)
+ {
+ TIntermNode *node = sequence->at(readIndex);
+
+ // Keep anything that's not unused.
+ const TFunction *function = nullptr;
+ const bool shouldPrune =
+ IsTopLevelNodeUnusedFunction(mCallDag, mFunctionMetadata, node, &function);
+ if (!shouldPrune)
+ {
+ (*sequence)[writeIndex++] = node;
+ continue;
+ }
+
+ // If a function is unused, it may have a struct declaration in its return value which
+ // shouldn't be pruned. In that case, replace the function definition with the struct
+ // definition.
+ ASSERT(function != nullptr);
+ const TType &returnType = function->getReturnType();
+ if (!returnType.isStructSpecifier())
+ {
+ continue;
+ }
+
+ TVariable *structVariable =
+ new TVariable(&mSymbolTable, kEmptyImmutableString, &returnType, SymbolType::Empty);
+ TIntermSymbol *structSymbol = new TIntermSymbol(structVariable);
+ TIntermDeclaration *structDeclaration = new TIntermDeclaration;
+ structDeclaration->appendDeclarator(structSymbol);
+
+ structSymbol->setLine(node->getLine());
+ structDeclaration->setLine(node->getLine());
+
+ (*sequence)[writeIndex++] = structDeclaration;
+ }
+
+ sequence->resize(writeIndex);
+
+ return validateAST(root);
+}
+
+bool TCompiler::limitExpressionComplexity(TIntermBlock *root)
+{
+ if (!IsASTDepthBelowLimit(root, mResources.MaxExpressionComplexity))
+ {
+ mDiagnostics.globalError("Expression too complex.");
+ return false;
+ }
+
+ if (!ValidateMaxParameters(root, mResources.MaxFunctionParameters))
+ {
+ mDiagnostics.globalError("Function has too many parameters.");
+ return false;
+ }
+
+ return true;
+}
+
+bool TCompiler::shouldCollectVariables(const ShCompileOptions &compileOptions)
+{
+ return compileOptions.variables;
+}
+
+bool TCompiler::wereVariablesCollected() const
+{
+ return mVariablesCollected;
+}
+
+bool TCompiler::initializeGLPosition(TIntermBlock *root)
+{
+ sh::ShaderVariable var(GL_FLOAT_VEC4);
+ var.name = "gl_Position";
+ return InitializeVariables(this, root, {var}, &mSymbolTable, mShaderVersion, mExtensionBehavior,
+ false, false);
+}
+
+bool TCompiler::useAllMembersInUnusedStandardAndSharedBlocks(TIntermBlock *root)
+{
+ sh::InterfaceBlockList list;
+
+ for (const sh::InterfaceBlock &block : mUniformBlocks)
+ {
+ if (!block.staticUse &&
+ (block.layout == sh::BLOCKLAYOUT_STD140 || block.layout == sh::BLOCKLAYOUT_SHARED))
+ {
+ list.push_back(block);
+ }
+ }
+
+ return sh::UseInterfaceBlockFields(this, root, list, mSymbolTable);
+}
+
+bool TCompiler::initializeOutputVariables(TIntermBlock *root)
+{
+ InitVariableList list;
+ list.reserve(mOutputVaryings.size());
+ if (mShaderType == GL_VERTEX_SHADER || mShaderType == GL_GEOMETRY_SHADER_EXT)
+ {
+ for (const sh::ShaderVariable &var : mOutputVaryings)
+ {
+ list.push_back(var);
+ if (var.name == "gl_Position")
+ {
+ ASSERT(!mGLPositionInitialized);
+ mGLPositionInitialized = true;
+ }
+ }
+ }
+ else
+ {
+ ASSERT(mShaderType == GL_FRAGMENT_SHADER);
+ for (const sh::ShaderVariable &var : mOutputVariables)
+ {
+ // in-out variables represent the context of the framebuffer
+ // when the draw call starts, so they have to be considered
+ // as already initialized.
+ if (!var.isFragmentInOut)
+ {
+ list.push_back(var);
+ }
+ }
+ }
+ return InitializeVariables(this, root, list, &mSymbolTable, mShaderVersion, mExtensionBehavior,
+ false, false);
+}
+
+const TExtensionBehavior &TCompiler::getExtensionBehavior() const
+{
+ return mExtensionBehavior;
+}
+
+const char *TCompiler::getSourcePath() const
+{
+ return mSourcePath;
+}
+
+const ShBuiltInResources &TCompiler::getResources() const
+{
+ return mResources;
+}
+
+const BuiltInFunctionEmulator &TCompiler::getBuiltInFunctionEmulator() const
+{
+ return mBuiltInFunctionEmulator;
+}
+
+bool TCompiler::isVaryingDefined(const char *varyingName)
+{
+ ASSERT(mVariablesCollected);
+ for (size_t ii = 0; ii < mInputVaryings.size(); ++ii)
+ {
+ if (mInputVaryings[ii].name == varyingName)
+ {
+ return true;
+ }
+ }
+ for (size_t ii = 0; ii < mOutputVaryings.size(); ++ii)
+ {
+ if (mOutputVaryings[ii].name == varyingName)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/Compiler.h b/gfx/angle/checkout/src/compiler/translator/Compiler.h
new file mode 100644
index 0000000000..8a87d5ea24
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/Compiler.h
@@ -0,0 +1,397 @@
+//
+// Copyright 2002 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_COMPILER_H_
+#define COMPILER_TRANSLATOR_COMPILER_H_
+
+//
+// Machine independent part of the compiler private objects
+// sent as ShHandle to the driver.
+//
+// This should not be included by driver code.
+//
+
+#include <GLSLANG/ShaderVars.h>
+
+#include "common/PackedEnums.h"
+#include "compiler/translator/BuiltInFunctionEmulator.h"
+#include "compiler/translator/CallDAG.h"
+#include "compiler/translator/Diagnostics.h"
+#include "compiler/translator/ExtensionBehavior.h"
+#include "compiler/translator/HashNames.h"
+#include "compiler/translator/InfoSink.h"
+#include "compiler/translator/Pragma.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/ValidateAST.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TParseContext;
+#ifdef ANGLE_ENABLE_HLSL
+class TranslatorHLSL;
+#endif // ANGLE_ENABLE_HLSL
+#ifdef ANGLE_ENABLE_METAL
+class TranslatorMetalDirect;
+#endif // ANGLE_ENABLE_METAL
+
+using SpecConstUsageBits = angle::PackedEnumBitSet<vk::SpecConstUsage, uint32_t>;
+
+//
+// Helper function to check if the shader type is GLSL.
+//
+bool IsGLSL130OrNewer(ShShaderOutput output);
+bool IsGLSL420OrNewer(ShShaderOutput output);
+bool IsGLSL410OrOlder(ShShaderOutput output);
+
+//
+// Helper function to check if the invariant qualifier can be removed.
+//
+bool RemoveInvariant(sh::GLenum shaderType,
+ int shaderVersion,
+ ShShaderOutput outputType,
+ const ShCompileOptions &compileOptions);
+
+//
+// The base class used to back handles returned to the driver.
+//
+class TShHandleBase
+{
+ public:
+ TShHandleBase();
+ virtual ~TShHandleBase();
+ virtual TCompiler *getAsCompiler() { return 0; }
+#ifdef ANGLE_ENABLE_HLSL
+ virtual TranslatorHLSL *getAsTranslatorHLSL() { return 0; }
+#endif // ANGLE_ENABLE_HLSL
+#ifdef ANGLE_ENABLE_METAL
+ virtual TranslatorMetalDirect *getAsTranslatorMetalDirect() { return nullptr; }
+#endif // ANGLE_ENABLE_METAL
+
+ protected:
+ // Memory allocator. Allocates and tracks memory required by the compiler.
+ // Deallocates all memory when compiler is destructed.
+ angle::PoolAllocator allocator;
+};
+
+struct TFunctionMetadata
+{
+ bool used = false;
+};
+
+//
+// The base class for the machine dependent compiler to derive from
+// for managing object code from the compile.
+//
+class TCompiler : public TShHandleBase
+{
+ public:
+ TCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output);
+ ~TCompiler() override;
+ TCompiler *getAsCompiler() override { return this; }
+
+ bool Init(const ShBuiltInResources &resources);
+
+ // 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 nullptr whenever there are compilation errors.
+ TIntermBlock *compileTreeForTesting(const char *const shaderStrings[],
+ size_t numStrings,
+ const ShCompileOptions &compileOptions);
+
+ bool compile(const char *const shaderStrings[],
+ size_t numStrings,
+ const ShCompileOptions &compileOptions);
+
+ // Get results of the last compilation.
+ int getShaderVersion() const { return mShaderVersion; }
+ TInfoSink &getInfoSink() { return mInfoSink; }
+
+ bool specifyEarlyFragmentTests() { return mEarlyFragmentTestsSpecified = true; }
+ bool isEarlyFragmentTestsSpecified() const { return mEarlyFragmentTestsSpecified; }
+ bool hasDiscard() const { return mHasDiscard; }
+ bool enablesPerSampleShading() const { return mEnablesPerSampleShading; }
+ SpecConstUsageBits getSpecConstUsageBits() const { return mSpecConstUsageBits; }
+
+ bool isComputeShaderLocalSizeDeclared() const { return mComputeShaderLocalSizeDeclared; }
+ const sh::WorkGroupSize &getComputeShaderLocalSize() const { return mComputeShaderLocalSize; }
+ int getNumViews() const { return mNumViews; }
+
+ // Clears the results from the previous compilation.
+ void clearResults();
+
+ const std::vector<sh::ShaderVariable> &getAttributes() const { return mAttributes; }
+ const std::vector<sh::ShaderVariable> &getOutputVariables() const { return mOutputVariables; }
+ const std::vector<sh::ShaderVariable> &getUniforms() const { return mUniforms; }
+ const std::vector<sh::ShaderVariable> &getInputVaryings() const { return mInputVaryings; }
+ const std::vector<sh::ShaderVariable> &getOutputVaryings() const { return mOutputVaryings; }
+ const std::vector<sh::InterfaceBlock> &getInterfaceBlocks() const { return mInterfaceBlocks; }
+ const std::vector<sh::InterfaceBlock> &getUniformBlocks() const { return mUniformBlocks; }
+ const std::vector<sh::InterfaceBlock> &getShaderStorageBlocks() const
+ {
+ return mShaderStorageBlocks;
+ }
+
+ ShHashFunction64 getHashFunction() const { return mResources.HashFunction; }
+ NameMap &getNameMap() { return mNameMap; }
+ TSymbolTable &getSymbolTable() { return mSymbolTable; }
+ ShShaderSpec getShaderSpec() const { return mShaderSpec; }
+ ShShaderOutput getOutputType() const { return mOutputType; }
+ ShBuiltInResources getBuiltInResources() const { return mResources; }
+ const std::string &getBuiltInResourcesString() const { return mBuiltInResourcesString; }
+
+ bool isHighPrecisionSupported() const;
+
+ bool shouldRunLoopAndIndexingValidation(const ShCompileOptions &compileOptions) const;
+ bool shouldLimitTypeSizes() const;
+
+ // Get the resources set by InitBuiltInSymbolTable
+ const ShBuiltInResources &getResources() const;
+
+ const TPragma &getPragma() const { return mPragma; }
+
+ int getGeometryShaderMaxVertices() const { return mGeometryShaderMaxVertices; }
+ int getGeometryShaderInvocations() const { return mGeometryShaderInvocations; }
+ TLayoutPrimitiveType getGeometryShaderInputPrimitiveType() const
+ {
+ return mGeometryShaderInputPrimitiveType;
+ }
+ TLayoutPrimitiveType getGeometryShaderOutputPrimitiveType() const
+ {
+ return mGeometryShaderOutputPrimitiveType;
+ }
+
+ unsigned int getStructSize(const ShaderVariable &var) const;
+
+ int getTessControlShaderOutputVertices() const { return mTessControlShaderOutputVertices; }
+ TLayoutTessEvaluationType getTessEvaluationShaderInputPrimitiveType() const
+ {
+ return mTessEvaluationShaderInputPrimitiveType;
+ }
+ TLayoutTessEvaluationType getTessEvaluationShaderInputVertexSpacingType() const
+ {
+ return mTessEvaluationShaderInputVertexSpacingType;
+ }
+ TLayoutTessEvaluationType getTessEvaluationShaderInputOrderingType() const
+ {
+ return mTessEvaluationShaderInputOrderingType;
+ }
+ TLayoutTessEvaluationType getTessEvaluationShaderInputPointType() const
+ {
+ return mTessEvaluationShaderInputPointType;
+ }
+
+ bool hasAnyPreciseType() const { return mHasAnyPreciseType; }
+
+ AdvancedBlendEquations getAdvancedBlendEquations() const { return mAdvancedBlendEquations; }
+
+ bool hasPixelLocalStorageUniforms() const { return mHasPixelLocalStorageUniforms; }
+
+ unsigned int getSharedMemorySize() const;
+
+ sh::GLenum getShaderType() const { return mShaderType; }
+
+ // Validate the AST and produce errors if it is inconsistent.
+ bool validateAST(TIntermNode *root);
+ // Some transformations may need to temporarily disable validation until they are complete. A
+ // set of disable/enable helpers are used for this purpose.
+ bool disableValidateFunctionCall();
+ void restoreValidateFunctionCall(bool enable);
+ bool disableValidateVariableReferences();
+ void restoreValidateVariableReferences(bool enable);
+ // When the AST is post-processed (such as to determine precise-ness of intermediate nodes),
+ // it's expected to no longer transform.
+ void enableValidateNoMoreTransformations();
+
+ protected:
+ // Add emulated functions to the built-in function emulator.
+ virtual void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu,
+ const ShCompileOptions &compileOptions)
+ {}
+ // Translate to object code. May generate performance warnings through the diagnostics.
+ [[nodiscard]] virtual bool translate(TIntermBlock *root,
+ const ShCompileOptions &compileOptions,
+ PerformanceDiagnostics *perfDiagnostics) = 0;
+ // Get built-in extensions with default behavior.
+ const TExtensionBehavior &getExtensionBehavior() const;
+ const char *getSourcePath() const;
+ // Relies on collectVariables having been called.
+ bool isVaryingDefined(const char *varyingName);
+
+ const BuiltInFunctionEmulator &getBuiltInFunctionEmulator() const;
+
+ virtual bool shouldFlattenPragmaStdglInvariantAll() = 0;
+ virtual bool shouldCollectVariables(const ShCompileOptions &compileOptions);
+
+ bool wereVariablesCollected() const;
+ std::vector<sh::ShaderVariable> mAttributes;
+ std::vector<sh::ShaderVariable> mOutputVariables;
+ std::vector<sh::ShaderVariable> mUniforms;
+ std::vector<sh::ShaderVariable> mInputVaryings;
+ std::vector<sh::ShaderVariable> mOutputVaryings;
+ std::vector<sh::ShaderVariable> mSharedVariables;
+ std::vector<sh::InterfaceBlock> mInterfaceBlocks;
+ std::vector<sh::InterfaceBlock> mUniformBlocks;
+ std::vector<sh::InterfaceBlock> mShaderStorageBlocks;
+
+ // Track what should be validated given passes currently applied.
+ ValidateASTOptions mValidateASTOptions;
+
+ // Specialization constant usage bits
+ SpecConstUsageBits mSpecConstUsageBits;
+
+ private:
+ // Initialize symbol-table with built-in symbols.
+ bool initBuiltInSymbolTable(const ShBuiltInResources &resources);
+ // Compute the string representation of the built-in resources
+ void setResourceString();
+ // Return false if the call depth is exceeded.
+ bool checkCallDepth();
+ // Insert statements to reference all members in unused uniform blocks with standard and shared
+ // layout. This is to work around a Mac driver that treats unused standard/shared
+ // uniform blocks as inactive.
+ [[nodiscard]] bool useAllMembersInUnusedStandardAndSharedBlocks(TIntermBlock *root);
+ // Insert statements to initialize output variables in the beginning of main().
+ // This is to avoid undefined behaviors.
+ [[nodiscard]] bool initializeOutputVariables(TIntermBlock *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.
+ [[nodiscard]] bool initializeGLPosition(TIntermBlock *root);
+ // Return true if the maximum expression complexity is below the limit.
+ bool limitExpressionComplexity(TIntermBlock *root);
+ // Creates the function call DAG for further analysis, returning false if there is a recursion
+ bool initCallDag(TIntermNode *root);
+ // Return false if "main" doesn't exist
+ bool tagUsedFunctions();
+ void internalTagUsedFunction(size_t index);
+
+ void collectInterfaceBlocks();
+
+ bool mVariablesCollected;
+
+ bool mGLPositionInitialized;
+
+ // Removes unused function declarations and prototypes from the AST
+ bool pruneUnusedFunctions(TIntermBlock *root);
+
+ TIntermBlock *compileTreeImpl(const char *const shaderStrings[],
+ size_t numStrings,
+ const ShCompileOptions &compileOptions);
+
+ // Fetches and stores shader metadata that is not stored within the AST itself, such as shader
+ // version.
+ void setASTMetadata(const TParseContext &parseContext);
+
+ // Check if shader version meets the requirement.
+ bool checkShaderVersion(TParseContext *parseContext);
+
+ // Does checks that need to be run after parsing is complete and returns true if they pass.
+ bool checkAndSimplifyAST(TIntermBlock *root,
+ const TParseContext &parseContext,
+ const ShCompileOptions &compileOptions);
+
+ bool postParseChecks(const TParseContext &parseContext);
+
+ sh::GLenum mShaderType;
+ ShShaderSpec mShaderSpec;
+ ShShaderOutput mOutputType;
+
+ CallDAG mCallDag;
+ std::vector<TFunctionMetadata> mFunctionMetadata;
+
+ ShBuiltInResources mResources;
+ std::string mBuiltInResourcesString;
+
+ // Built-in symbol table for the given language, spec, and resources.
+ // It is preserved from compile-to-compile.
+ TSymbolTable mSymbolTable;
+ // Built-in extensions with default behavior.
+ TExtensionBehavior mExtensionBehavior;
+
+ BuiltInFunctionEmulator mBuiltInFunctionEmulator;
+
+ // Results of compilation.
+ int mShaderVersion;
+ TInfoSink mInfoSink; // Output sink.
+ TDiagnostics mDiagnostics;
+ const char *mSourcePath; // Path of source file or NULL
+
+ // Fragment shader early fragment tests
+ bool mEarlyFragmentTestsSpecified;
+
+ // Fragment shader has the discard instruction
+ bool mHasDiscard;
+
+ // Whether per-sample shading is enabled by the shader. In OpenGL, this keyword should
+ // implicitly trigger per-sample shading without the API enabling it.
+ bool mEnablesPerSampleShading;
+
+ // compute shader local group size
+ bool mComputeShaderLocalSizeDeclared;
+ sh::WorkGroupSize mComputeShaderLocalSize;
+
+ // GL_OVR_multiview num_views.
+ int mNumViews;
+
+ // geometry shader parameters.
+ int mGeometryShaderMaxVertices;
+ int mGeometryShaderInvocations;
+ TLayoutPrimitiveType mGeometryShaderInputPrimitiveType;
+ TLayoutPrimitiveType mGeometryShaderOutputPrimitiveType;
+
+ // tesssellation shader parameters
+ int mTessControlShaderOutputVertices;
+ TLayoutTessEvaluationType mTessEvaluationShaderInputPrimitiveType;
+ TLayoutTessEvaluationType mTessEvaluationShaderInputVertexSpacingType;
+ TLayoutTessEvaluationType mTessEvaluationShaderInputOrderingType;
+ TLayoutTessEvaluationType mTessEvaluationShaderInputPointType;
+
+ bool mHasAnyPreciseType;
+
+ // advanced blend equation parameters
+ AdvancedBlendEquations mAdvancedBlendEquations;
+
+ // ANGLE_shader_pixel_local_storage.
+ bool mHasPixelLocalStorageUniforms;
+
+ // name hashing.
+ NameMap mNameMap;
+
+ TPragma mPragma;
+
+ ShCompileOptions mCompileOptions;
+};
+
+//
+// This is the interface between the machine independent code
+// and the machine dependent code.
+//
+// The machine dependent code should derive from the classes
+// above. Then Construct*() and Delete*() will create and
+// destroy the machine dependent objects, which contain the
+// above machine independent information.
+//
+TCompiler *ConstructCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output);
+void DeleteCompiler(TCompiler *);
+
+struct ShaderDumpHeader
+{
+ uint32_t type;
+ uint32_t spec;
+ uint32_t output;
+ uint8_t basicCompileOptions[32];
+ uint8_t metalCompileOptions[32];
+ uint8_t plsCompileOptions[32];
+ uint8_t padding[20];
+};
+static_assert(sizeof(ShaderDumpHeader) == 128);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_COMPILER_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/ConstantUnion.cpp b/gfx/angle/checkout/src/compiler/translator/ConstantUnion.cpp
new file mode 100644
index 0000000000..99af1c4f6c
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ConstantUnion.cpp
@@ -0,0 +1,803 @@
+//
+// 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 "common/mathutil.h"
+#include "compiler/translator/Diagnostics.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+float CheckedSum(float lhs, float rhs, TDiagnostics *diag, const TSourceLoc &line)
+{
+ float result = lhs + rhs;
+ if (gl::isNaN(result) && !gl::isNaN(lhs) && !gl::isNaN(rhs))
+ {
+ diag->warning(line, "Constant folded undefined addition generated NaN", "+");
+ }
+ else if (gl::isInf(result) && !gl::isInf(lhs) && !gl::isInf(rhs))
+ {
+ diag->warning(line, "Constant folded addition overflowed to infinity", "+");
+ }
+ return result;
+}
+
+float CheckedDiff(float lhs, float rhs, TDiagnostics *diag, const TSourceLoc &line)
+{
+ float result = lhs - rhs;
+ if (gl::isNaN(result) && !gl::isNaN(lhs) && !gl::isNaN(rhs))
+ {
+ diag->warning(line, "Constant folded undefined subtraction generated NaN", "-");
+ }
+ else if (gl::isInf(result) && !gl::isInf(lhs) && !gl::isInf(rhs))
+ {
+ diag->warning(line, "Constant folded subtraction overflowed to infinity", "-");
+ }
+ return result;
+}
+
+float CheckedMul(float lhs, float rhs, TDiagnostics *diag, const TSourceLoc &line)
+{
+ float result = lhs * rhs;
+ if (gl::isNaN(result) && !gl::isNaN(lhs) && !gl::isNaN(rhs))
+ {
+ diag->warning(line, "Constant folded undefined multiplication generated NaN", "*");
+ }
+ else if (gl::isInf(result) && !gl::isInf(lhs) && !gl::isInf(rhs))
+ {
+ diag->warning(line, "Constant folded multiplication overflowed to infinity", "*");
+ }
+ return result;
+}
+
+bool IsValidShiftOffset(const TConstantUnion &rhs)
+{
+ return (rhs.getType() == EbtInt && (rhs.getIConst() >= 0 && rhs.getIConst() <= 31)) ||
+ (rhs.getType() == EbtUInt && rhs.getUConst() <= 31u);
+}
+
+} // anonymous namespace
+
+TConstantUnion::TConstantUnion() : iConst(0), type(EbtVoid) {}
+
+TConstantUnion::TConstantUnion(int i) : iConst(i), type(EbtInt) {}
+
+TConstantUnion::TConstantUnion(unsigned int u) : uConst(u), type(EbtUInt) {}
+
+TConstantUnion::TConstantUnion(float f) : fConst(f), type(EbtFloat) {}
+
+TConstantUnion::TConstantUnion(bool b) : bConst(b), type(EbtBool) {}
+
+int TConstantUnion::getIConst() const
+{
+ ASSERT(type == EbtInt);
+ return iConst;
+}
+
+unsigned int TConstantUnion::getUConst() const
+{
+ ASSERT(type == EbtUInt);
+ return uConst;
+}
+
+float TConstantUnion::getFConst() const
+{
+ switch (type)
+ {
+ case EbtInt:
+ return static_cast<float>(iConst);
+ case EbtUInt:
+ return static_cast<float>(uConst);
+ default:
+ ASSERT(type == EbtFloat);
+ return fConst;
+ }
+}
+
+bool TConstantUnion::getBConst() const
+{
+ ASSERT(type == EbtBool);
+ return bConst;
+}
+
+bool TConstantUnion::isZero() const
+{
+ switch (type)
+ {
+ case EbtInt:
+ return getIConst() == 0;
+ case EbtUInt:
+ return getUConst() == 0;
+ case EbtFloat:
+ return getFConst() == 0.0f;
+ case EbtBool:
+ return getBConst() == false;
+ default:
+ return false;
+ }
+}
+
+TYuvCscStandardEXT TConstantUnion::getYuvCscStandardEXTConst() const
+{
+ ASSERT(type == EbtYuvCscStandardEXT);
+ return yuvCscStandardEXTConst;
+}
+
+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:
+ if (constant.getFConst() < 0.0f)
+ {
+ // Avoid undefined behavior in C++ by first casting to signed int.
+ setUConst(
+ static_cast<unsigned int>(static_cast<int>(constant.getFConst())));
+ }
+ else
+ {
+ 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;
+ case EbtYuvCscStandardEXT:
+ switch (constant.type)
+ {
+ case EbtYuvCscStandardEXT:
+ setYuvCscStandardEXTConst(constant.getYuvCscStandardEXTConst());
+ break;
+ default:
+ return false;
+ }
+ break;
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+bool TConstantUnion::operator==(const int i) const
+{
+ switch (type)
+ {
+ case EbtFloat:
+ return static_cast<float>(i) == fConst;
+ default:
+ return i == iConst;
+ }
+}
+
+bool TConstantUnion::operator==(const unsigned int u) const
+{
+ switch (type)
+ {
+ case EbtFloat:
+ return static_cast<float>(u) == fConst;
+ default:
+ return u == uConst;
+ }
+}
+
+bool TConstantUnion::operator==(const float f) const
+{
+ switch (type)
+ {
+ case EbtInt:
+ return f == static_cast<float>(iConst);
+ case EbtUInt:
+ return f == static_cast<float>(uConst);
+ default:
+ return f == fConst;
+ }
+}
+
+bool TConstantUnion::operator==(const bool b) const
+{
+ return b == bConst;
+}
+
+bool TConstantUnion::operator==(const TYuvCscStandardEXT s) const
+{
+ return s == yuvCscStandardEXTConst;
+}
+
+bool TConstantUnion::operator==(const TConstantUnion &constant) const
+{
+ ImplicitTypeConversion conversion = GetConversion(constant.type, type);
+ if (conversion == ImplicitTypeConversion::Same)
+ {
+ 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;
+ case EbtYuvCscStandardEXT:
+ return constant.yuvCscStandardEXTConst == yuvCscStandardEXTConst;
+ default:
+ return false;
+ }
+ }
+ else if (conversion == ImplicitTypeConversion::Invalid)
+ {
+ return false;
+ }
+ else
+ {
+ return constant.getFConst() == getFConst();
+ }
+}
+
+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 TYuvCscStandardEXT s) const
+{
+ return !operator==(s);
+}
+
+bool TConstantUnion::operator!=(const TConstantUnion &constant) const
+{
+ return !operator==(constant);
+}
+
+bool TConstantUnion::operator>(const TConstantUnion &constant) const
+{
+
+ ImplicitTypeConversion conversion = GetConversion(constant.type, type);
+ if (conversion == ImplicitTypeConversion::Same)
+ {
+ 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
+ }
+ }
+ else
+ {
+ ASSERT(conversion != ImplicitTypeConversion::Invalid);
+ return getFConst() > constant.getFConst();
+ }
+}
+
+bool TConstantUnion::operator<(const TConstantUnion &constant) const
+{
+ ImplicitTypeConversion conversion = GetConversion(constant.type, type);
+ if (conversion == ImplicitTypeConversion::Same)
+ {
+ 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
+ }
+ }
+ else
+ {
+ ASSERT(conversion != ImplicitTypeConversion::Invalid);
+ return getFConst() < constant.getFConst();
+ }
+}
+
+// static
+TConstantUnion TConstantUnion::add(const TConstantUnion &lhs,
+ const TConstantUnion &rhs,
+ TDiagnostics *diag,
+ const TSourceLoc &line)
+{
+ TConstantUnion returnValue;
+
+ ImplicitTypeConversion conversion = GetConversion(lhs.type, rhs.type);
+ if (conversion == ImplicitTypeConversion::Same)
+ {
+ 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(lhs.fConst, rhs.fConst, diag, line));
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+ else
+ {
+ ASSERT(conversion != ImplicitTypeConversion::Invalid);
+ returnValue.setFConst(CheckedSum(lhs.getFConst(), rhs.getFConst(), diag, line));
+ }
+
+ return returnValue;
+}
+
+// static
+TConstantUnion TConstantUnion::sub(const TConstantUnion &lhs,
+ const TConstantUnion &rhs,
+ TDiagnostics *diag,
+ const TSourceLoc &line)
+{
+ TConstantUnion returnValue;
+
+ ImplicitTypeConversion conversion = GetConversion(lhs.type, rhs.type);
+ if (conversion == ImplicitTypeConversion::Same)
+ {
+ 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(lhs.fConst, rhs.fConst, diag, line));
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+ else
+ {
+ ASSERT(conversion != ImplicitTypeConversion::Invalid);
+ returnValue.setFConst(CheckedDiff(lhs.getFConst(), rhs.getFConst(), diag, line));
+ }
+
+ return returnValue;
+}
+
+// static
+TConstantUnion TConstantUnion::mul(const TConstantUnion &lhs,
+ const TConstantUnion &rhs,
+ TDiagnostics *diag,
+ const TSourceLoc &line)
+{
+ TConstantUnion returnValue;
+
+ ImplicitTypeConversion conversion = GetConversion(lhs.type, rhs.type);
+ if (conversion == ImplicitTypeConversion::Same)
+ {
+ 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(lhs.fConst, rhs.fConst, diag, line));
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+ else
+ {
+ ASSERT(conversion != ImplicitTypeConversion::Invalid);
+ returnValue.setFConst(CheckedMul(lhs.getFConst(), rhs.getFConst(), diag, line));
+ }
+
+ 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 (!IsValidShiftOffset(rhs))
+ {
+ diag->warning(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:
+ {
+ unsigned int shiftOffset = 0;
+ switch (rhs.type)
+ {
+ case EbtInt:
+ shiftOffset = static_cast<unsigned int>(rhs.iConst);
+ break;
+ case EbtUInt:
+ shiftOffset = rhs.uConst;
+ break;
+ default:
+ UNREACHABLE();
+ }
+ if (shiftOffset > 0)
+ {
+ // ESSL 3.00.6 section 5.9: "If E1 is a signed integer, the right-shift will extend
+ // the sign bit." In C++ shifting negative integers is undefined, so we implement
+ // extending the sign bit manually.
+ int lhsSafe = lhs.iConst;
+ if (lhsSafe == std::numeric_limits<int>::min())
+ {
+ // The min integer needs special treatment because only bit it has set is the
+ // sign bit, which we clear later to implement safe right shift of negative
+ // numbers.
+ lhsSafe = -0x40000000;
+ --shiftOffset;
+ }
+ if (shiftOffset > 0)
+ {
+ bool extendSignBit = false;
+ if (lhsSafe < 0)
+ {
+ extendSignBit = true;
+ // Clear the sign bit so that bitshift right is defined in C++.
+ lhsSafe &= 0x7fffffff;
+ ASSERT(lhsSafe > 0);
+ }
+ returnValue.setIConst(lhsSafe >> shiftOffset);
+
+ // Manually fill in the extended sign bit if necessary.
+ if (extendSignBit)
+ {
+ int extendedSignBit = static_cast<int>(0xffffffffu << (31 - shiftOffset));
+ returnValue.setIConst(returnValue.getIConst() | extendedSignBit);
+ }
+ }
+ else
+ {
+ returnValue.setIConst(lhsSafe);
+ }
+ }
+ else
+ {
+ returnValue.setIConst(lhs.iConst);
+ }
+ 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 (!IsValidShiftOffset(rhs))
+ {
+ diag->warning(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)
+ {
+ // Cast to unsigned integer before shifting, since ESSL 3.00.6 section 5.9 says that
+ // lhs is "interpreted as a bit pattern". This also avoids the possibility of signed
+ // integer overflow or undefined shift of a negative integer.
+ case EbtInt:
+ returnValue.setIConst(
+ static_cast<int>(static_cast<uint32_t>(lhs.iConst) << rhs.iConst));
+ break;
+ case EbtUInt:
+ returnValue.setIConst(
+ static_cast<int>(static_cast<uint32_t>(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;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/ConstantUnion.h b/gfx/angle/checkout/src/compiler/translator/ConstantUnion.h
new file mode 100644
index 0000000000..df53857dd3
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ConstantUnion.h
@@ -0,0 +1,122 @@
+//
+// Copyright 2002 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_CONSTANTUNION_H_
+#define COMPILER_TRANSLATOR_CONSTANTUNION_H_
+
+#include "compiler/translator/BaseTypes.h"
+#include "compiler/translator/Common.h"
+
+namespace sh
+{
+
+class TDiagnostics;
+
+class TConstantUnion
+{
+ public:
+ POOL_ALLOCATOR_NEW_DELETE
+ TConstantUnion();
+ TConstantUnion(int i);
+ TConstantUnion(unsigned int u);
+ TConstantUnion(float f);
+ TConstantUnion(bool b);
+
+ bool cast(TBasicType newType, const TConstantUnion &constant);
+
+ void setIConst(int i)
+ {
+ iConst = i;
+ type = EbtInt;
+ }
+ void setUConst(unsigned int u)
+ {
+ uConst = u;
+ type = EbtUInt;
+ }
+ void setFConst(float f)
+ {
+ fConst = f;
+ type = EbtFloat;
+ }
+ void setBConst(bool b)
+ {
+ bConst = b;
+ type = EbtBool;
+ }
+
+ void setYuvCscStandardEXTConst(TYuvCscStandardEXT s)
+ {
+ yuvCscStandardEXTConst = s;
+ type = EbtYuvCscStandardEXT;
+ }
+
+ int getIConst() const;
+ unsigned int getUConst() const;
+ float getFConst() const;
+ bool getBConst() const;
+ bool isZero() const;
+ TYuvCscStandardEXT getYuvCscStandardEXTConst() 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 TYuvCscStandardEXT s) 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 TYuvCscStandardEXT s) 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
+ TYuvCscStandardEXT yuvCscStandardEXTConst;
+ };
+
+ TBasicType type;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_CONSTANTUNION_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/Declarator.cpp b/gfx/angle/checkout/src/compiler/translator/Declarator.cpp
new file mode 100644
index 0000000000..7680c054d3
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/Declarator.cpp
@@ -0,0 +1,33 @@
+//
+// Copyright 2017 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.
+//
+// Declarator.cpp:
+// Declarator type for parsing structure field declarators.
+
+#include "compiler/translator/Declarator.h"
+
+namespace sh
+{
+
+TDeclarator::TDeclarator(const ImmutableString &name, const TSourceLoc &line)
+ : mName(name), mArraySizes(nullptr), mLine(line)
+{
+ ASSERT(mName != "");
+}
+
+TDeclarator::TDeclarator(const ImmutableString &name,
+ const TVector<unsigned int> *arraySizes,
+ const TSourceLoc &line)
+ : mName(name), mArraySizes(arraySizes), mLine(line)
+{
+ ASSERT(mArraySizes);
+}
+
+bool TDeclarator::isArray() const
+{
+ return mArraySizes != nullptr && mArraySizes->size() > 0;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/Declarator.h b/gfx/angle/checkout/src/compiler/translator/Declarator.h
new file mode 100644
index 0000000000..5268334946
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/Declarator.h
@@ -0,0 +1,49 @@
+//
+// Copyright 2017 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.
+//
+// Declarator.h:
+// Declarator type for parsing structure field declarators.
+
+#ifndef COMPILER_TRANSLATOR_DECLARATOR_H_
+#define COMPILER_TRANSLATOR_DECLARATOR_H_
+
+#include "compiler/translator/Common.h"
+#include "compiler/translator/ImmutableString.h"
+
+namespace sh
+{
+
+// Declarator like "a[2][4]". Only used for parsing structure field declarators.
+class TDeclarator : angle::NonCopyable
+{
+ public:
+ POOL_ALLOCATOR_NEW_DELETE
+ TDeclarator(const ImmutableString &name, const TSourceLoc &line);
+
+ TDeclarator(const ImmutableString &name,
+ const TVector<unsigned int> *arraySizes,
+ const TSourceLoc &line);
+
+ const ImmutableString &name() const { return mName; }
+
+ bool isArray() const;
+ const TVector<unsigned int> *arraySizes() const { return mArraySizes; }
+
+ const TSourceLoc &line() const { return mLine; }
+
+ private:
+ const ImmutableString mName;
+
+ // Outermost array size is stored at the end of the vector.
+ const TVector<unsigned int> *const mArraySizes;
+
+ const TSourceLoc mLine;
+};
+
+using TDeclaratorList = TVector<TDeclarator *>;
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_DECLARATOR_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/Diagnostics.cpp b/gfx/angle/checkout/src/compiler/translator/Diagnostics.cpp
new file mode 100644
index 0000000000..03066a319d
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/Diagnostics.cpp
@@ -0,0 +1,106 @@
+//
+// Copyright 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/Diagnostics.h"
+
+#include "common/debug.h"
+#include "compiler/preprocessor/SourceLocation.h"
+#include "compiler/translator/Common.h"
+#include "compiler/translator/InfoSink.h"
+
+namespace sh
+{
+
+TDiagnostics::TDiagnostics(TInfoSinkBase &infoSink)
+ : mInfoSink(infoSink), mNumErrors(0), mNumWarnings(0)
+{}
+
+TDiagnostics::~TDiagnostics() {}
+
+void TDiagnostics::writeInfo(Severity severity,
+ const angle::pp::SourceLocation &loc,
+ const char *reason,
+ const char *token)
+{
+ switch (severity)
+ {
+ case SH_ERROR:
+ ++mNumErrors;
+ break;
+ case SH_WARNING:
+ ++mNumWarnings;
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ /* VC++ format: file(linenum) : error #: 'token' : extrainfo */
+ mInfoSink.prefix(severity);
+ mInfoSink.location(loc.file, loc.line);
+ mInfoSink << "'" << token << "' : " << reason << "\n";
+}
+
+void TDiagnostics::globalError(const char *message)
+{
+ ++mNumErrors;
+ mInfoSink.prefix(SH_ERROR);
+ mInfoSink << message << "\n";
+}
+
+void TDiagnostics::error(const angle::pp::SourceLocation &loc,
+ const char *reason,
+ const char *token)
+{
+ writeInfo(SH_ERROR, loc, reason, token);
+}
+
+void TDiagnostics::warning(const angle::pp::SourceLocation &loc,
+ const char *reason,
+ const char *token)
+{
+ writeInfo(SH_WARNING, loc, reason, token);
+}
+
+void TDiagnostics::error(const TSourceLoc &loc, const char *reason, const char *token)
+{
+ angle::pp::SourceLocation srcLoc;
+ srcLoc.file = loc.first_file;
+ srcLoc.line = loc.first_line;
+ error(srcLoc, reason, token);
+}
+
+void TDiagnostics::warning(const TSourceLoc &loc, const char *reason, const char *token)
+{
+ angle::pp::SourceLocation srcLoc;
+ srcLoc.file = loc.first_file;
+ srcLoc.line = loc.first_line;
+ warning(srcLoc, reason, token);
+}
+
+void TDiagnostics::print(ID id, const angle::pp::SourceLocation &loc, const std::string &text)
+{
+ writeInfo(isError(id) ? SH_ERROR : SH_WARNING, loc, message(id), text.c_str());
+}
+
+void TDiagnostics::resetErrorCount()
+{
+ mNumErrors = 0;
+ mNumWarnings = 0;
+}
+
+PerformanceDiagnostics::PerformanceDiagnostics(TDiagnostics *diagnostics)
+ : mDiagnostics(diagnostics)
+{
+ ASSERT(diagnostics);
+}
+
+void PerformanceDiagnostics::warning(const TSourceLoc &loc, const char *reason, const char *token)
+{
+ mDiagnostics->warning(loc, reason, token);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/Diagnostics.h b/gfx/angle/checkout/src/compiler/translator/Diagnostics.h
new file mode 100644
index 0000000000..8ed71b3d2b
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/Diagnostics.h
@@ -0,0 +1,67 @@
+//
+// Copyright 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_DIAGNOSTICS_H_
+#define COMPILER_TRANSLATOR_DIAGNOSTICS_H_
+
+#include "common/angleutils.h"
+#include "compiler/preprocessor/DiagnosticsBase.h"
+#include "compiler/translator/Severity.h"
+
+namespace sh
+{
+
+class TInfoSinkBase;
+struct TSourceLoc;
+
+class TDiagnostics : public angle::pp::Diagnostics, angle::NonCopyable
+{
+ public:
+ TDiagnostics(TInfoSinkBase &infoSink);
+ ~TDiagnostics() override;
+
+ int numErrors() const { return mNumErrors; }
+ int numWarnings() const { return mNumWarnings; }
+
+ void error(const angle::pp::SourceLocation &loc, const char *reason, const char *token);
+ void warning(const angle::pp::SourceLocation &loc, const char *reason, const char *token);
+
+ void error(const TSourceLoc &loc, const char *reason, const char *token);
+ void warning(const TSourceLoc &loc, const char *reason, const char *token);
+
+ void globalError(const char *message);
+
+ void resetErrorCount();
+
+ protected:
+ void writeInfo(Severity severity,
+ const angle::pp::SourceLocation &loc,
+ const char *reason,
+ const char *token);
+
+ void print(ID id, const angle::pp::SourceLocation &loc, const std::string &text) override;
+
+ private:
+ TInfoSinkBase &mInfoSink;
+ int mNumErrors;
+ int mNumWarnings;
+};
+
+// Diagnostics wrapper to use when the code is only allowed to generate warnings.
+class PerformanceDiagnostics : public angle::NonCopyable
+{
+ public:
+ PerformanceDiagnostics(TDiagnostics *diagnostics);
+
+ void warning(const TSourceLoc &loc, const char *reason, const char *token);
+
+ private:
+ TDiagnostics *mDiagnostics;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_DIAGNOSTICS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/DirectiveHandler.cpp b/gfx/angle/checkout/src/compiler/translator/DirectiveHandler.cpp
new file mode 100644
index 0000000000..80b238e055
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/DirectiveHandler.cpp
@@ -0,0 +1,304 @@
+//
+// Copyright 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/DirectiveHandler.h"
+
+#include <sstream>
+
+#include "angle_gl.h"
+#include "common/debug.h"
+#include "compiler/translator/Common.h"
+#include "compiler/translator/Diagnostics.h"
+
+namespace sh
+{
+
+static TBehavior getBehavior(const std::string &str)
+{
+ const char kRequire[] = "require";
+ const char kEnable[] = "enable";
+ const char kDisable[] = "disable";
+ const char kWarn[] = "warn";
+
+ if (str == kRequire)
+ return EBhRequire;
+ else if (str == kEnable)
+ return EBhEnable;
+ else if (str == kDisable)
+ return EBhDisable;
+ else if (str == kWarn)
+ return EBhWarn;
+ return EBhUndefined;
+}
+
+TDirectiveHandler::TDirectiveHandler(TExtensionBehavior &extBehavior,
+ TDiagnostics &diagnostics,
+ int &shaderVersion,
+ sh::GLenum shaderType)
+ : mExtensionBehavior(extBehavior),
+ mDiagnostics(diagnostics),
+ mShaderVersion(shaderVersion),
+ mShaderType(shaderType)
+{}
+
+TDirectiveHandler::~TDirectiveHandler() {}
+
+void TDirectiveHandler::handleError(const angle::pp::SourceLocation &loc, const std::string &msg)
+{
+ mDiagnostics.error(loc, msg.c_str(), "");
+}
+
+void TDirectiveHandler::handlePragma(const angle::pp::SourceLocation &loc,
+ const std::string &name,
+ const std::string &value,
+ bool stdgl)
+{
+ if (stdgl)
+ {
+ const char kInvariant[] = "invariant";
+ const char kAll[] = "all";
+
+ if (name == kInvariant && value == kAll)
+ {
+ if (mShaderVersion == 300 && mShaderType == GL_FRAGMENT_SHADER)
+ {
+ // ESSL 3.00.4 section 4.6.1
+ mDiagnostics.error(
+ loc, "#pragma STDGL invariant(all) can not be used in fragment shader",
+ name.c_str());
+ }
+ mPragma.stdgl.invariantAll = true;
+ }
+ // The STDGL pragma is used to reserve pragmas for use by future
+ // revisions of GLSL. Do not generate an error on unexpected
+ // name and value.
+ return;
+ }
+ else
+ {
+ const char kOptimize[] = "optimize";
+ const char kDebug[] = "debug";
+ const char kOn[] = "on";
+ const char kOff[] = "off";
+
+ bool invalidValue = false;
+ if (name == kOptimize)
+ {
+ if (value == kOn)
+ mPragma.optimize = true;
+ else if (value == kOff)
+ mPragma.optimize = false;
+ else
+ invalidValue = true;
+ }
+ else if (name == kDebug)
+ {
+ if (value == kOn)
+ mPragma.debug = true;
+ else if (value == kOff)
+ mPragma.debug = false;
+ else
+ invalidValue = true;
+ }
+ else
+ {
+ mDiagnostics.report(angle::pp::Diagnostics::PP_UNRECOGNIZED_PRAGMA, loc, name);
+ return;
+ }
+
+ if (invalidValue)
+ {
+ mDiagnostics.error(loc, "invalid pragma value - 'on' or 'off' expected", value.c_str());
+ }
+ }
+}
+
+void TDirectiveHandler::handleExtension(const angle::pp::SourceLocation &loc,
+ const std::string &name,
+ const std::string &behavior)
+{
+ const char kExtAll[] = "all";
+
+ TBehavior behaviorVal = getBehavior(behavior);
+ if (behaviorVal == EBhUndefined)
+ {
+ mDiagnostics.error(loc, "behavior invalid", name.c_str());
+ return;
+ }
+
+ if (name == kExtAll)
+ {
+ if (behaviorVal == EBhRequire)
+ {
+ mDiagnostics.error(loc, "extension cannot have 'require' behavior", name.c_str());
+ }
+ else if (behaviorVal == EBhEnable)
+ {
+ mDiagnostics.error(loc, "extension cannot have 'enable' behavior", name.c_str());
+ }
+ else
+ {
+ for (TExtensionBehavior::iterator iter = mExtensionBehavior.begin();
+ iter != mExtensionBehavior.end(); ++iter)
+ iter->second = behaviorVal;
+ }
+ return;
+ }
+
+ TExtensionBehavior::iterator iter = mExtensionBehavior.find(GetExtensionByName(name.c_str()));
+ if (iter != mExtensionBehavior.end())
+ {
+ iter->second = behaviorVal;
+ // OVR_multiview is implicitly enabled when OVR_multiview2 is enabled
+ if (name == "GL_OVR_multiview2")
+ {
+ constexpr char kMultiviewExtName[] = "GL_OVR_multiview";
+ iter = mExtensionBehavior.find(GetExtensionByName(kMultiviewExtName));
+ if (iter != mExtensionBehavior.end())
+ {
+ iter->second = behaviorVal;
+ }
+ }
+ // All the extensions listed in the spec here:
+ // https://www.khronos.org/registry/OpenGL/extensions/ANDROID/ANDROID_extension_pack_es31a.txt
+ // are implicitly enabled when GL_ANDROID_extension_pack_es31a is enabled
+ if (name == "GL_ANDROID_extension_pack_es31a")
+ {
+ constexpr char kGeometryShaderExtName[] = "GL_EXT_geometry_shader";
+ constexpr char kTessellationShaderExtName[] = "GL_EXT_tessellation_shader";
+ constexpr char kGpuShader5ExtName[] = "GL_EXT_gpu_shader5";
+ constexpr char kTextureBufferExtName[] = "GL_EXT_texture_buffer";
+ constexpr char kTextureCubeMapArrayExtName[] = "GL_EXT_texture_cube_map_array";
+ constexpr char kSampleVariablesExtName[] = "GL_OES_sample_variables";
+ constexpr char kShaderMultisampleInterpolationExtName[] =
+ "GL_OES_shader_multisample_interpolation";
+ constexpr char kShaderImageAtomicExtName[] = "GL_OES_shader_image_atomic";
+ constexpr char kTextureStorageMultisample2dArrayExtName[] =
+ "GL_OES_texture_storage_multisample_2d_array";
+ iter = mExtensionBehavior.find(GetExtensionByName(kGeometryShaderExtName));
+ if (iter != mExtensionBehavior.end())
+ {
+ iter->second = behaviorVal;
+ }
+
+ iter = mExtensionBehavior.find(GetExtensionByName(kTessellationShaderExtName));
+ if (iter != mExtensionBehavior.end())
+ {
+ iter->second = behaviorVal;
+ }
+
+ iter = mExtensionBehavior.find(GetExtensionByName(kGpuShader5ExtName));
+ if (iter != mExtensionBehavior.end())
+ {
+ iter->second = behaviorVal;
+ }
+
+ iter = mExtensionBehavior.find(GetExtensionByName(kTextureBufferExtName));
+ if (iter != mExtensionBehavior.end())
+ {
+ iter->second = behaviorVal;
+ }
+
+ iter = mExtensionBehavior.find(GetExtensionByName(kTextureCubeMapArrayExtName));
+ if (iter != mExtensionBehavior.end())
+ {
+ iter->second = behaviorVal;
+ }
+
+ iter = mExtensionBehavior.find(GetExtensionByName(kSampleVariablesExtName));
+ if (iter != mExtensionBehavior.end())
+ {
+ iter->second = behaviorVal;
+ }
+
+ iter =
+ mExtensionBehavior.find(GetExtensionByName(kShaderMultisampleInterpolationExtName));
+ if (iter != mExtensionBehavior.end())
+ {
+ iter->second = behaviorVal;
+ }
+
+ iter = mExtensionBehavior.find(GetExtensionByName(kShaderImageAtomicExtName));
+ if (iter != mExtensionBehavior.end())
+ {
+ iter->second = behaviorVal;
+ }
+
+ iter = mExtensionBehavior.find(
+ GetExtensionByName(kTextureStorageMultisample2dArrayExtName));
+ if (iter != mExtensionBehavior.end())
+ {
+ iter->second = behaviorVal;
+ }
+ }
+ // EXT_shader_io_blocks is implicitly enabled when EXT_geometry_shader or
+ // EXT_tessellation_shader is enabled.
+ if (name == "GL_EXT_geometry_shader" || name == "GL_EXT_tessellation_shader")
+ {
+ constexpr char kIOBlocksExtName[] = "GL_EXT_shader_io_blocks";
+ iter = mExtensionBehavior.find(GetExtensionByName(kIOBlocksExtName));
+ if (iter != mExtensionBehavior.end())
+ {
+ iter->second = behaviorVal;
+ }
+ }
+ // GL_APPLE_clip_distance is implicitly enabled when GL_EXT_clip_cull_distance is enabled
+ else if (name == "GL_EXT_clip_cull_distance")
+ {
+ // This extension only can be enabled on greater than ESSL 300
+ if (mShaderVersion < 300)
+ {
+ mDiagnostics.error(loc, "extension can be enabled on greater than ESSL 300",
+ name.c_str());
+ return;
+ }
+
+ constexpr char kAPPLEClipDistanceEXTName[] = "GL_APPLE_clip_distance";
+ iter = mExtensionBehavior.find(GetExtensionByName(kAPPLEClipDistanceEXTName));
+ if (iter != mExtensionBehavior.end())
+ {
+ iter->second = behaviorVal;
+ }
+ }
+ return;
+ }
+
+ switch (behaviorVal)
+ {
+ case EBhRequire:
+ mDiagnostics.error(loc, "extension is not supported", name.c_str());
+ break;
+ case EBhEnable:
+ case EBhWarn:
+ case EBhDisable:
+ mDiagnostics.warning(loc, "extension is not supported", name.c_str());
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+void TDirectiveHandler::handleVersion(const angle::pp::SourceLocation &loc,
+ int version,
+ ShShaderSpec spec)
+{
+ if (((version == 100 || version == 300 || version == 310 || version == 320) &&
+ !IsDesktopGLSpec(spec)) ||
+ IsDesktopGLSpec(spec))
+ {
+ mShaderVersion = version;
+ }
+ else
+ {
+ std::stringstream stream = sh::InitializeStream<std::stringstream>();
+ stream << version;
+ std::string str = stream.str();
+ mDiagnostics.error(loc, "client/version number not supported", str.c_str());
+ }
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/DirectiveHandler.h b/gfx/angle/checkout/src/compiler/translator/DirectiveHandler.h
new file mode 100644
index 0000000000..6fb54558ef
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/DirectiveHandler.h
@@ -0,0 +1,57 @@
+//
+// Copyright 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_DIRECTIVEHANDLER_H_
+#define COMPILER_TRANSLATOR_DIRECTIVEHANDLER_H_
+
+#include "GLSLANG/ShaderLang.h"
+#include "common/angleutils.h"
+#include "compiler/preprocessor/DirectiveHandlerBase.h"
+#include "compiler/translator/ExtensionBehavior.h"
+#include "compiler/translator/Pragma.h"
+
+namespace sh
+{
+class TDiagnostics;
+
+class TDirectiveHandler : public angle::pp::DirectiveHandler, angle::NonCopyable
+{
+ public:
+ TDirectiveHandler(TExtensionBehavior &extBehavior,
+ TDiagnostics &diagnostics,
+ int &shaderVersion,
+ sh::GLenum shaderType);
+ ~TDirectiveHandler() override;
+
+ const TPragma &pragma() const { return mPragma; }
+ const TExtensionBehavior &extensionBehavior() const { return mExtensionBehavior; }
+
+ void handleError(const angle::pp::SourceLocation &loc, const std::string &msg) override;
+
+ void handlePragma(const angle::pp::SourceLocation &loc,
+ const std::string &name,
+ const std::string &value,
+ bool stdgl) override;
+
+ void handleExtension(const angle::pp::SourceLocation &loc,
+ const std::string &name,
+ const std::string &behavior) override;
+
+ void handleVersion(const angle::pp::SourceLocation &loc,
+ int version,
+ ShShaderSpec spec) override;
+
+ private:
+ TPragma mPragma;
+ TExtensionBehavior &mExtensionBehavior;
+ TDiagnostics &mDiagnostics;
+ int &mShaderVersion;
+ sh::GLenum mShaderType;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_DIRECTIVEHANDLER_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/DriverUniformMetal.h b/gfx/angle/checkout/src/compiler/translator/DriverUniformMetal.h
new file mode 100644
index 0000000000..47e075b2e7
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/DriverUniformMetal.h
@@ -0,0 +1,33 @@
+//
+// Copyright 2020 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.
+//
+// DriverUniformMetal:
+// Struct defining the default driver uniforms for direct and SpirV based ANGLE translation
+//
+
+#ifndef LIBANGLE_RENDERER_METAL_DRIVERUNIFORMMETAL_H_
+#define LIBANGLE_RENDERER_METAL_DRIVERUNIFORMMETAL_H_
+
+#include "compiler/translator/tree_util/DriverUniform.h"
+
+namespace sh
+{
+
+class DriverUniformMetal : public DriverUniformExtended
+{
+ public:
+ DriverUniformMetal(DriverUniformMode mode) : DriverUniformExtended(mode) {}
+ DriverUniformMetal() : DriverUniformExtended(DriverUniformMode::InterfaceBlock) {}
+ ~DriverUniformMetal() override {}
+
+ TIntermTyped *getCoverageMaskField() const;
+
+ protected:
+ TFieldList *createUniformFields(TSymbolTable *symbolTable) override;
+};
+
+} // namespace sh
+
+#endif /* LIBANGLE_RENDERER_METAL_DRIVERUNIFORMMETAL_H_ */
diff --git a/gfx/angle/checkout/src/compiler/translator/ExtensionBehavior.cpp b/gfx/angle/checkout/src/compiler/translator/ExtensionBehavior.cpp
new file mode 100644
index 0000000000..9c16393272
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ExtensionBehavior.cpp
@@ -0,0 +1,125 @@
+//
+// Copyright 2017 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.
+//
+// ExtensionBehavior.cpp: Extension name enumeration and data structures for storing extension
+// behavior.
+
+#include "compiler/translator/ExtensionBehavior.h"
+
+#include "common/debug.h"
+
+#include <string.h>
+
+#define LIST_EXTENSIONS(OP) \
+ OP(ANDROID_extension_pack_es31a) \
+ OP(ANGLE_base_vertex_base_instance_shader_builtin) \
+ OP(ANGLE_multi_draw) \
+ OP(ANGLE_shader_pixel_local_storage) \
+ OP(ANGLE_texture_multisample) \
+ OP(APPLE_clip_distance) \
+ OP(ARB_texture_rectangle) \
+ OP(ARM_shader_framebuffer_fetch) \
+ OP(EXT_blend_func_extended) \
+ OP(EXT_clip_cull_distance) \
+ OP(EXT_draw_buffers) \
+ OP(EXT_frag_depth) \
+ OP(EXT_geometry_shader) \
+ OP(OES_geometry_shader) \
+ OP(OES_shader_io_blocks) \
+ OP(EXT_shader_io_blocks) \
+ OP(EXT_gpu_shader5) \
+ OP(EXT_primitive_bounding_box) \
+ OP(OES_primitive_bounding_box) \
+ OP(EXT_shader_framebuffer_fetch) \
+ OP(EXT_shader_framebuffer_fetch_non_coherent) \
+ OP(EXT_shader_non_constant_global_initializers) \
+ OP(EXT_shader_texture_lod) \
+ OP(EXT_shadow_samplers) \
+ OP(EXT_tessellation_shader) \
+ OP(EXT_texture_buffer) \
+ OP(EXT_texture_cube_map_array) \
+ OP(EXT_YUV_target) \
+ OP(KHR_blend_equation_advanced) \
+ OP(NV_EGL_stream_consumer_external) \
+ OP(NV_shader_framebuffer_fetch) \
+ OP(NV_shader_noperspective_interpolation) \
+ OP(OES_EGL_image_external) \
+ OP(OES_EGL_image_external_essl3) \
+ OP(OES_sample_variables) \
+ OP(OES_shader_multisample_interpolation) \
+ OP(OES_shader_image_atomic) \
+ OP(OES_standard_derivatives) \
+ OP(OES_texture_3D) \
+ OP(OES_texture_buffer) \
+ OP(OES_texture_cube_map_array) \
+ OP(OES_texture_storage_multisample_2d_array) \
+ OP(OVR_multiview) \
+ OP(OVR_multiview2) \
+ OP(WEBGL_video_texture)
+
+namespace sh
+{
+
+#define RETURN_EXTENSION_NAME_CASE(ext) \
+ case TExtension::ext: \
+ return "GL_" #ext;
+
+const char *GetExtensionNameString(TExtension extension)
+{
+ switch (extension)
+ {
+ LIST_EXTENSIONS(RETURN_EXTENSION_NAME_CASE)
+ default:
+ UNREACHABLE();
+ return "";
+ }
+}
+
+#define RETURN_EXTENSION_IF_NAME_MATCHES(ext) \
+ if (strcmp(extWithoutGLPrefix, #ext) == 0) \
+ { \
+ return TExtension::ext; \
+ }
+
+TExtension GetExtensionByName(const char *extension)
+{
+ // If first characters of the extension don't equal "GL_", early out.
+ if (strncmp(extension, "GL_", 3) != 0)
+ {
+ return TExtension::UNDEFINED;
+ }
+ const char *extWithoutGLPrefix = extension + 3;
+
+ LIST_EXTENSIONS(RETURN_EXTENSION_IF_NAME_MATCHES)
+
+ return TExtension::UNDEFINED;
+}
+
+const char *GetBehaviorString(TBehavior b)
+{
+ switch (b)
+ {
+ case EBhRequire:
+ return "require";
+ case EBhEnable:
+ return "enable";
+ case EBhWarn:
+ return "warn";
+ case EBhDisable:
+ return "disable";
+ default:
+ return nullptr;
+ }
+}
+
+bool IsExtensionEnabled(const TExtensionBehavior &extBehavior, TExtension extension)
+{
+ ASSERT(extension != TExtension::UNDEFINED);
+ auto iter = extBehavior.find(extension);
+ return iter != extBehavior.end() &&
+ (iter->second == EBhEnable || iter->second == EBhRequire || iter->second == EBhWarn);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/ExtensionBehavior.h b/gfx/angle/checkout/src/compiler/translator/ExtensionBehavior.h
new file mode 100644
index 0000000000..64b0748854
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ExtensionBehavior.h
@@ -0,0 +1,93 @@
+//
+// Copyright 2002 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.
+//
+// ExtensionBehavior.h: Extension name enumeration and data structures for storing extension
+// behavior.
+
+#ifndef COMPILER_TRANSLATOR_EXTENSIONBEHAVIOR_H_
+#define COMPILER_TRANSLATOR_EXTENSIONBEHAVIOR_H_
+
+#include <cstdint>
+#include <map>
+
+namespace sh
+{
+
+enum class TExtension : uint8_t
+{
+ UNDEFINED, // Special value used to indicate no extension.
+
+ ANDROID_extension_pack_es31a,
+ ANGLE_base_vertex_base_instance_shader_builtin,
+ ANGLE_multi_draw,
+ ANGLE_shader_pixel_local_storage,
+ ANGLE_texture_multisample,
+ APPLE_clip_distance,
+ ARB_fragment_shader_interlock,
+ ARB_texture_rectangle,
+ ARM_shader_framebuffer_fetch,
+ EXT_YUV_target,
+ EXT_blend_func_extended,
+ EXT_clip_cull_distance,
+ EXT_draw_buffers,
+ EXT_frag_depth,
+ EXT_geometry_shader,
+ EXT_gpu_shader5,
+ EXT_primitive_bounding_box,
+ EXT_shader_framebuffer_fetch,
+ EXT_shader_framebuffer_fetch_non_coherent,
+ EXT_shader_io_blocks,
+ EXT_shader_non_constant_global_initializers,
+ EXT_shader_texture_lod,
+ EXT_shadow_samplers,
+ EXT_tessellation_shader,
+ EXT_texture_buffer,
+ EXT_texture_cube_map_array,
+ INTEL_fragment_shader_ordering,
+ KHR_blend_equation_advanced,
+ NV_EGL_stream_consumer_external,
+ NV_fragment_shader_interlock,
+ NV_shader_framebuffer_fetch,
+ NV_shader_noperspective_interpolation,
+ OES_EGL_image_external,
+ OES_EGL_image_external_essl3,
+ OES_geometry_shader,
+ OES_primitive_bounding_box,
+ OES_sample_variables,
+ OES_shader_image_atomic,
+ OES_shader_io_blocks,
+ OES_shader_multisample_interpolation,
+ OES_standard_derivatives,
+ OES_texture_3D,
+ OES_texture_buffer,
+ OES_texture_cube_map_array,
+ OES_texture_storage_multisample_2d_array,
+ OVR_multiview,
+ OVR_multiview2,
+ WEBGL_video_texture,
+};
+
+enum TBehavior : uint8_t
+{
+ EBhRequire,
+ EBhEnable,
+ EBhWarn,
+ EBhDisable,
+ EBhUndefined
+};
+
+const char *GetExtensionNameString(TExtension extension);
+TExtension GetExtensionByName(const char *extension);
+
+const char *GetBehaviorString(TBehavior b);
+
+// Mapping between extension id and behavior.
+typedef std::map<TExtension, TBehavior> TExtensionBehavior;
+
+bool IsExtensionEnabled(const TExtensionBehavior &extBehavior, TExtension extension);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_EXTENSIONBEHAVIOR_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/ExtensionGLSL.cpp b/gfx/angle/checkout/src/compiler/translator/ExtensionGLSL.cpp
new file mode 100644
index 0000000000..563dbab185
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ExtensionGLSL.cpp
@@ -0,0 +1,118 @@
+//
+// 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.
+//
+// ExtensionGLSL.cpp: Implements the TExtensionGLSL class that tracks GLSL extension requirements
+// of shaders.
+
+#include "compiler/translator/ExtensionGLSL.h"
+
+#include "compiler/translator/VersionGLSL.h"
+
+namespace sh
+{
+
+TExtensionGLSL::TExtensionGLSL(ShShaderOutput output)
+ : TIntermTraverser(true, false, false), mTargetVersion(ShaderOutputTypeToGLSLVersion(output))
+{}
+
+const std::set<std::string> &TExtensionGLSL::getEnabledExtensions() const
+{
+ return mEnabledExtensions;
+}
+
+const std::set<std::string> &TExtensionGLSL::getRequiredExtensions() const
+{
+ return mRequiredExtensions;
+}
+
+bool TExtensionGLSL::visitUnary(Visit, TIntermUnary *node)
+{
+ checkOperator(node);
+
+ return true;
+}
+
+bool TExtensionGLSL::visitAggregate(Visit, TIntermAggregate *node)
+{
+ checkOperator(node);
+
+ return true;
+}
+
+void TExtensionGLSL::checkOperator(TIntermOperator *node)
+{
+ if (mTargetVersion < GLSL_VERSION_130)
+ {
+ return;
+ }
+
+ switch (node->getOp())
+ {
+ case EOpAbs:
+ break;
+
+ case EOpSign:
+ break;
+
+ case EOpMix:
+ break;
+
+ case EOpFloatBitsToInt:
+ case EOpFloatBitsToUint:
+ case EOpIntBitsToFloat:
+ case EOpUintBitsToFloat:
+ if (mTargetVersion < GLSL_VERSION_330)
+ {
+ // Bit conversion functions cannot be emulated.
+ mRequiredExtensions.insert("GL_ARB_shader_bit_encoding");
+ }
+ break;
+
+ case EOpPackSnorm2x16:
+ case EOpPackHalf2x16:
+ case EOpUnpackSnorm2x16:
+ case EOpUnpackHalf2x16:
+ if (mTargetVersion < GLSL_VERSION_420)
+ {
+ mEnabledExtensions.insert("GL_ARB_shading_language_packing");
+
+ if (mTargetVersion < GLSL_VERSION_330)
+ {
+ // floatBitsToUint and uintBitsToFloat are needed to emulate
+ // packHalf2x16 and unpackHalf2x16 respectively and cannot be
+ // emulated themselves.
+ mRequiredExtensions.insert("GL_ARB_shader_bit_encoding");
+ }
+ }
+ break;
+
+ case EOpPackUnorm2x16:
+ case EOpUnpackUnorm2x16:
+ if (mTargetVersion < GLSL_VERSION_410)
+ {
+ mEnabledExtensions.insert("GL_ARB_shading_language_packing");
+ }
+ break;
+
+ case EOpBeginInvocationInterlockNV:
+ case EOpEndInvocationInterlockNV:
+ mRequiredExtensions.insert("GL_NV_fragment_shader_interlock");
+ break;
+
+ case EOpBeginFragmentShaderOrderingINTEL:
+ mRequiredExtensions.insert("GL_INTEL_fragment_shader_ordering");
+ break;
+
+ case EOpBeginInvocationInterlockARB:
+ case EOpEndInvocationInterlockARB:
+ mRequiredExtensions.insert("GL_ARB_fragment_shader_interlock");
+ break;
+
+ default:
+ break;
+ }
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/ExtensionGLSL.h b/gfx/angle/checkout/src/compiler/translator/ExtensionGLSL.h
new file mode 100644
index 0000000000..b07e4e95a9
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ExtensionGLSL.h
@@ -0,0 +1,44 @@
+//
+// 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.
+//
+// ExtensionGLSL.h: Defines the TExtensionGLSL class that tracks GLSL extension requirements of
+// shaders.
+
+#ifndef COMPILER_TRANSLATOR_EXTENSIONGLSL_H_
+#define COMPILER_TRANSLATOR_EXTENSIONGLSL_H_
+
+#include <set>
+#include <string>
+
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+// Traverses the intermediate tree to determine which GLSL extensions are required
+// to support the shader.
+class TExtensionGLSL : public TIntermTraverser
+{
+ public:
+ TExtensionGLSL(ShShaderOutput output);
+
+ const std::set<std::string> &getEnabledExtensions() const;
+ const std::set<std::string> &getRequiredExtensions() const;
+
+ bool visitUnary(Visit visit, TIntermUnary *node) override;
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override;
+
+ private:
+ void checkOperator(TIntermOperator *node);
+
+ int mTargetVersion;
+
+ std::set<std::string> mEnabledExtensions;
+ std::set<std::string> mRequiredExtensions;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_EXTENSIONGLSL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/FlagStd140Structs.cpp b/gfx/angle/checkout/src/compiler/translator/FlagStd140Structs.cpp
new file mode 100644
index 0000000000..729e452893
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/FlagStd140Structs.cpp
@@ -0,0 +1,76 @@
+//
+// Copyright 2013 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.
+//
+// FlagStd140Structs.cpp: Find structs in std140 blocks, where the padding added in the translator
+// conflicts with the "natural" unpadded type.
+
+#include "compiler/translator/FlagStd140Structs.h"
+
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class FlagStd140StructsTraverser : public TIntermTraverser
+{
+ public:
+ FlagStd140StructsTraverser() : TIntermTraverser(true, false, false) {}
+
+ const std::vector<MappedStruct> getMappedStructs() const { return mMappedStructs; }
+
+ protected:
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
+
+ private:
+ void mapBlockStructMembers(TIntermSymbol *blockDeclarator, const TInterfaceBlock *block);
+
+ std::vector<MappedStruct> mMappedStructs;
+};
+
+void FlagStd140StructsTraverser::mapBlockStructMembers(TIntermSymbol *blockDeclarator,
+ const TInterfaceBlock *block)
+{
+ for (auto *field : block->fields())
+ {
+ if (field->type()->getBasicType() == EbtStruct)
+ {
+ MappedStruct mappedStruct;
+ mappedStruct.blockDeclarator = blockDeclarator;
+ mappedStruct.field = field;
+ mMappedStructs.push_back(mappedStruct);
+ }
+ }
+}
+
+bool FlagStd140StructsTraverser::visitDeclaration(Visit visit, TIntermDeclaration *node)
+{
+ TIntermTyped *declarator = node->getSequence()->back()->getAsTyped();
+ if (declarator->getBasicType() == EbtInterfaceBlock)
+ {
+ const TInterfaceBlock *block = declarator->getType().getInterfaceBlock();
+ if (block->blockStorage() == EbsStd140)
+ {
+ mapBlockStructMembers(declarator->getAsSymbolNode(), block);
+ }
+ }
+ return false;
+}
+
+} // anonymous namespace
+
+std::vector<MappedStruct> FlagStd140Structs(TIntermNode *node)
+{
+ FlagStd140StructsTraverser flaggingTraversal;
+
+ node->traverse(&flaggingTraversal);
+
+ return flaggingTraversal.getMappedStructs();
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/FlagStd140Structs.h b/gfx/angle/checkout/src/compiler/translator/FlagStd140Structs.h
new file mode 100644
index 0000000000..2ff10b2319
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/FlagStd140Structs.h
@@ -0,0 +1,30 @@
+//
+// Copyright 2013 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.
+//
+// FlagStd140Structs.h: Find structs in std140 blocks, where the padding added in the translator
+// conflicts with the "natural" unpadded type.
+
+#ifndef COMPILER_TRANSLATOR_FLAGSTD140STRUCTS_H_
+#define COMPILER_TRANSLATOR_FLAGSTD140STRUCTS_H_
+
+#include <vector>
+
+namespace sh
+{
+
+class TField;
+class TIntermNode;
+class TIntermSymbol;
+
+struct MappedStruct
+{
+ TIntermSymbol *blockDeclarator;
+ TField *field;
+};
+
+std::vector<MappedStruct> FlagStd140Structs(TIntermNode *node);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_FLAGSTD140STRUCTS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/FunctionLookup.cpp b/gfx/angle/checkout/src/compiler/translator/FunctionLookup.cpp
new file mode 100644
index 0000000000..8b574e9363
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/FunctionLookup.cpp
@@ -0,0 +1,179 @@
+//
+// Copyright 2018 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.
+//
+// FunctionLookup.cpp: Used for storing function calls that have not yet been resolved during
+// parsing.
+//
+
+#include "compiler/translator/FunctionLookup.h"
+#include "compiler/translator/ImmutableStringBuilder.h"
+
+namespace sh
+{
+
+namespace
+{
+
+const char kFunctionMangledNameSeparator = '(';
+
+constexpr const ImmutableString kEmptyName("");
+
+// Helper function for GetMangledNames
+// Gets all ordered combinations of elements in list[currentIndex, end]
+std::vector<std::vector<int>> GetImplicitConversionCombinations(const std::vector<int> &list)
+{
+ std::vector<std::vector<int>> target;
+ target.push_back(std::vector<int>());
+
+ for (size_t currentIndex = 0; currentIndex < list.size(); currentIndex++)
+ {
+ size_t prevIterSize = target.size();
+ for (size_t copyIndex = 0; copyIndex < prevIterSize; copyIndex++)
+ {
+ std::vector<int> combination = target[copyIndex];
+ combination.push_back(list[currentIndex]);
+ target.push_back(combination);
+ }
+ }
+
+ return target;
+}
+
+} // anonymous namespace
+
+TFunctionLookup::TFunctionLookup(const ImmutableString &name,
+ const TType *constructorType,
+ const TSymbol *symbol)
+ : mName(name), mConstructorType(constructorType), mThisNode(nullptr), mSymbol(symbol)
+{}
+
+// static
+TFunctionLookup *TFunctionLookup::CreateConstructor(const TType *type)
+{
+ ASSERT(type != nullptr);
+ return new TFunctionLookup(kEmptyName, type, nullptr);
+}
+
+// static
+TFunctionLookup *TFunctionLookup::CreateFunctionCall(const ImmutableString &name,
+ const TSymbol *symbol)
+{
+ ASSERT(name != "");
+ return new TFunctionLookup(name, nullptr, symbol);
+}
+
+const ImmutableString &TFunctionLookup::name() const
+{
+ return mName;
+}
+
+ImmutableString TFunctionLookup::getMangledName() const
+{
+ return GetMangledName(mName.data(), mArguments);
+}
+
+ImmutableString TFunctionLookup::GetMangledName(const char *functionName,
+ const TIntermSequence &arguments)
+{
+ std::string newName(functionName);
+ newName += kFunctionMangledNameSeparator;
+
+ for (TIntermNode *argument : arguments)
+ {
+ newName += argument->getAsTyped()->getType().getMangledName();
+ }
+ return ImmutableString(newName);
+}
+
+std::vector<ImmutableString> GetMangledNames(const char *functionName,
+ const TIntermSequence &arguments)
+{
+ std::vector<ImmutableString> target;
+
+ std::vector<int> indexes;
+ for (int i = 0; i < static_cast<int>(arguments.size()); i++)
+ {
+ TIntermNode *argument = arguments[i];
+ TBasicType argType = argument->getAsTyped()->getType().getBasicType();
+ if (argType == EbtInt || argType == EbtUInt)
+ {
+ indexes.push_back(i);
+ }
+ }
+
+ std::vector<std::vector<int>> combinations = GetImplicitConversionCombinations(indexes);
+ for (const std::vector<int> &combination : combinations)
+ {
+ // combination: ordered list of indexes for arguments that should be converted to float
+ std::string newName(functionName);
+ newName += kFunctionMangledNameSeparator;
+ // combination[currentIndex] represents index of next argument to be converted
+ int currentIndex = 0;
+ for (int i = 0; i < (int)arguments.size(); i++)
+ {
+ TIntermNode *argument = arguments[i];
+
+ if (currentIndex != static_cast<int>(combination.size()) &&
+ combination[currentIndex] == i)
+ {
+ // Convert
+ TType type = argument->getAsTyped()->getType();
+ type.setBasicType(EbtFloat);
+ newName += type.getMangledName();
+ currentIndex++;
+ }
+ else
+ {
+ // Don't convert
+ newName += argument->getAsTyped()->getType().getMangledName();
+ }
+ }
+ target.push_back(ImmutableString(newName));
+ }
+
+ return target;
+}
+
+std::vector<ImmutableString> TFunctionLookup::getMangledNamesForImplicitConversions() const
+{
+ return GetMangledNames(mName.data(), mArguments);
+}
+
+bool TFunctionLookup::isConstructor() const
+{
+ return mConstructorType != nullptr;
+}
+
+const TType &TFunctionLookup::constructorType() const
+{
+ return *mConstructorType;
+}
+
+void TFunctionLookup::setThisNode(TIntermTyped *thisNode)
+{
+ mThisNode = thisNode;
+}
+
+TIntermTyped *TFunctionLookup::thisNode() const
+{
+ return mThisNode;
+}
+
+void TFunctionLookup::addArgument(TIntermTyped *argument)
+{
+ mArguments.push_back(argument);
+}
+
+TIntermSequence &TFunctionLookup::arguments()
+{
+ return mArguments;
+}
+
+const TSymbol *TFunctionLookup::symbol() const
+{
+ return mSymbol;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/FunctionLookup.h b/gfx/angle/checkout/src/compiler/translator/FunctionLookup.h
new file mode 100644
index 0000000000..6565c205eb
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/FunctionLookup.h
@@ -0,0 +1,60 @@
+//
+// Copyright 2018 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.
+//
+// FunctionLookup.h: Used for storing function calls that have not yet been resolved during parsing.
+//
+
+#ifndef COMPILER_TRANSLATOR_FUNCTIONLOOKUP_H_
+#define COMPILER_TRANSLATOR_FUNCTIONLOOKUP_H_
+
+#include "compiler/translator/ImmutableString.h"
+#include "compiler/translator/IntermNode.h"
+
+namespace sh
+{
+
+// A function look-up.
+class TFunctionLookup : angle::NonCopyable
+{
+ public:
+ POOL_ALLOCATOR_NEW_DELETE
+
+ static TFunctionLookup *CreateConstructor(const TType *type);
+ static TFunctionLookup *CreateFunctionCall(const ImmutableString &name, const TSymbol *symbol);
+
+ const ImmutableString &name() const;
+ ImmutableString getMangledName() const;
+ static ImmutableString GetMangledName(const char *functionName,
+ const TIntermSequence &arguments);
+ std::vector<ImmutableString> getMangledNamesForImplicitConversions() const;
+
+ bool isConstructor() const;
+ const TType &constructorType() const;
+
+ void setThisNode(TIntermTyped *thisNode);
+ TIntermTyped *thisNode() const;
+
+ void addArgument(TIntermTyped *argument);
+ TIntermSequence &arguments();
+
+ // Symbol looked up in the lexical phase using only the name of the function.
+ // This does not necessarily correspond to the correct overloaded function.
+ const TSymbol *symbol() const;
+
+ private:
+ TFunctionLookup(const ImmutableString &name,
+ const TType *constructorType,
+ const TSymbol *symbol);
+
+ const ImmutableString mName;
+ const TType *const mConstructorType;
+ TIntermTyped *mThisNode;
+ TIntermSequence mArguments;
+ const TSymbol *mSymbol;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_FUNCTIONLOOKUP_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/HashNames.cpp b/gfx/angle/checkout/src/compiler/translator/HashNames.cpp
new file mode 100644
index 0000000000..fc188ff582
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/HashNames.cpp
@@ -0,0 +1,99 @@
+//
+// Copyright 2017 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/HashNames.h"
+
+#include "compiler/translator/ImmutableString.h"
+#include "compiler/translator/ImmutableStringBuilder.h"
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/Symbol.h"
+
+namespace sh
+{
+
+namespace
+{
+constexpr const ImmutableString kHashedNamePrefix("webgl_");
+
+ImmutableString HashName(const ImmutableString &name, ShHashFunction64 hashFunction)
+{
+ ASSERT(!name.empty());
+ ASSERT(hashFunction);
+ khronos_uint64_t number = (*hashFunction)(name.data(), name.length());
+
+ // Build the hashed name in place.
+ static const unsigned int kHexStrMaxLength = sizeof(number) * 2;
+ static const size_t kHashedNameMaxLength = kHashedNamePrefix.length() + kHexStrMaxLength;
+
+ ImmutableStringBuilder hashedName(kHashedNameMaxLength);
+ hashedName << kHashedNamePrefix;
+
+ hashedName.appendHex(number);
+
+ return hashedName;
+}
+
+void AddToNameMapIfNotMapped(const ImmutableString &name,
+ const ImmutableString &hashedName,
+ NameMap *nameMap)
+{
+ if (nameMap)
+ {
+ NameMap::const_iterator it = nameMap->find(name.data());
+ if (it != nameMap->end())
+ {
+ // (How bout returning?)
+ return;
+ }
+ (*nameMap)[name.data()] = hashedName.data();
+ }
+}
+
+} // anonymous namespace
+
+ImmutableString HashName(const ImmutableString &name,
+ ShHashFunction64 hashFunction,
+ NameMap *nameMap)
+{
+ const ImmutableString kUnhashedNamePrefix(kUserDefinedNamePrefix);
+
+ if (hashFunction == nullptr)
+ {
+ if (name.length() + kUnhashedNamePrefix.length() > kESSLMaxIdentifierLength)
+ {
+ // If the identifier length is already close to the limit, we can't prefix it. This is
+ // not a problem since there are no builtins or ANGLE's internal variables that would
+ // have as long names and could conflict.
+ return name;
+ }
+ ImmutableStringBuilder prefixedName(kUnhashedNamePrefix.length() + name.length());
+ prefixedName << kUnhashedNamePrefix << name;
+ ImmutableString res = prefixedName;
+ AddToNameMapIfNotMapped(name, res, nameMap);
+ return res;
+ }
+
+ // Has a hash function
+ ImmutableString hashedName = HashName(name, hashFunction);
+ AddToNameMapIfNotMapped(name, hashedName, nameMap);
+ return hashedName;
+}
+
+ImmutableString HashName(const TSymbol *symbol, ShHashFunction64 hashFunction, NameMap *nameMap)
+{
+ if (symbol->symbolType() == SymbolType::Empty)
+ {
+ return kEmptyImmutableString;
+ }
+ if (symbol->symbolType() == SymbolType::AngleInternal ||
+ symbol->symbolType() == SymbolType::BuiltIn)
+ {
+ return symbol->name();
+ }
+ return HashName(symbol->name(), hashFunction, nameMap);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/HashNames.h b/gfx/angle/checkout/src/compiler/translator/HashNames.h
new file mode 100644
index 0000000000..3742095129
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/HashNames.h
@@ -0,0 +1,33 @@
+//
+// Copyright 2002 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_HASHNAMES_H_
+#define COMPILER_TRANSLATOR_HASHNAMES_H_
+
+#include <map>
+
+#include "GLSLANG/ShaderLang.h"
+#include "compiler/translator/Common.h"
+
+namespace sh
+{
+
+typedef std::map<TPersistString, TPersistString> NameMap;
+
+class ImmutableString;
+class TSymbol;
+
+ImmutableString HashName(const ImmutableString &name,
+ ShHashFunction64 hashFunction,
+ NameMap *nameMap);
+
+// Hash user-defined name for GLSL output, with special handling for internal names.
+// The nameMap parameter is optional and is used to cache hashed names if set.
+ImmutableString HashName(const TSymbol *symbol, ShHashFunction64 hashFunction, NameMap *nameMap);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_HASHNAMES_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/ImageFunctionHLSL.cpp b/gfx/angle/checkout/src/compiler/translator/ImageFunctionHLSL.cpp
new file mode 100644
index 0000000000..51d1a1abdd
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ImageFunctionHLSL.cpp
@@ -0,0 +1,401 @@
+//
+// Copyright 2017 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.
+//
+// ImageFunctionHLSL: Class for writing implementations of ESSL image functions into HLSL output.
+//
+
+#include "compiler/translator/ImageFunctionHLSL.h"
+#include "compiler/translator/ImmutableStringBuilder.h"
+#include "compiler/translator/UtilsHLSL.h"
+
+namespace sh
+{
+
+// static
+ImmutableString ImageFunctionHLSL::GetImageReference(
+ TInfoSinkBase &out,
+ const ImageFunctionHLSL::ImageFunction &imageFunction)
+{
+ static const ImmutableString kImageIndexStr("[index]");
+ if (imageFunction.readonly)
+ {
+ static const ImmutableString kReadonlyImagesStr("readonlyImages");
+ ImmutableString suffix(
+ TextureGroupSuffix(imageFunction.image, imageFunction.imageInternalFormat));
+ out << " const uint index = imageIndex - readonlyImageIndexOffset" << suffix.data()
+ << ";\n";
+ ImmutableStringBuilder imageRefBuilder(kReadonlyImagesStr.length() + suffix.length() +
+ kImageIndexStr.length());
+ imageRefBuilder << kReadonlyImagesStr << suffix << kImageIndexStr;
+ return imageRefBuilder;
+ }
+ else
+ {
+ static const ImmutableString kImagesStr("images");
+ ImmutableString suffix(
+ RWTextureGroupSuffix(imageFunction.image, imageFunction.imageInternalFormat));
+ out << " const uint index = imageIndex - imageIndexOffset" << suffix.data() << ";\n";
+ ImmutableStringBuilder imageRefBuilder(kImagesStr.length() + suffix.length() +
+ kImageIndexStr.length());
+ imageRefBuilder << kImagesStr << suffix << kImageIndexStr;
+ return imageRefBuilder;
+ }
+}
+
+void ImageFunctionHLSL::OutputImageFunctionArgumentList(
+ TInfoSinkBase &out,
+ const ImageFunctionHLSL::ImageFunction &imageFunction)
+{
+ out << "uint imageIndex";
+
+ if (imageFunction.method == ImageFunctionHLSL::ImageFunction::Method::LOAD ||
+ imageFunction.method == ImageFunctionHLSL::ImageFunction::Method::STORE)
+ {
+ switch (imageFunction.image)
+ {
+ case EbtImage2D:
+ case EbtIImage2D:
+ case EbtUImage2D:
+ out << ", int2 p";
+ break;
+ case EbtImage3D:
+ case EbtIImage3D:
+ case EbtUImage3D:
+ case EbtImageCube:
+ case EbtIImageCube:
+ case EbtUImageCube:
+ case EbtImage2DArray:
+ case EbtIImage2DArray:
+ case EbtUImage2DArray:
+ out << ", int3 p";
+ break;
+ case EbtUImageBuffer:
+ case EbtIImageBuffer:
+ case EbtImageBuffer:
+ out << ", int p";
+ break;
+
+ default:
+ UNREACHABLE();
+ }
+
+ if (imageFunction.method == ImageFunctionHLSL::ImageFunction::Method::STORE)
+ {
+ switch (imageFunction.image)
+ {
+ case EbtImage2D:
+ case EbtImage3D:
+ case EbtImageCube:
+ case EbtImage2DArray:
+ case EbtImageBuffer:
+ out << ", float4 data";
+ break;
+ case EbtIImage2D:
+ case EbtIImage3D:
+ case EbtIImageCube:
+ case EbtIImage2DArray:
+ case EbtIImageBuffer:
+ out << ", int4 data";
+ break;
+ case EbtUImage2D:
+ case EbtUImage3D:
+ case EbtUImageCube:
+ case EbtUImage2DArray:
+ case EbtUImageBuffer:
+ out << ", uint4 data";
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+ }
+}
+
+// static
+void ImageFunctionHLSL::OutputImageSizeFunctionBody(
+ TInfoSinkBase &out,
+ const ImageFunctionHLSL::ImageFunction &imageFunction,
+ const ImmutableString &imageReference)
+{
+ if (IsImage3D(imageFunction.image) || IsImage2DArray(imageFunction.image) ||
+ IsImageCube(imageFunction.image))
+ {
+ // "depth" stores either the number of layers in an array texture or 3D depth
+ out << " uint width; uint height; uint depth;\n"
+ << " " << imageReference << ".GetDimensions(width, height, depth);\n";
+ }
+ else if (IsImage2D(imageFunction.image))
+ {
+ out << " uint width; uint height;\n"
+ << " " << imageReference << ".GetDimensions(width, height);\n";
+ }
+ else if (IsImageBuffer(imageFunction.image))
+ {
+ out << " uint width;\n"
+ << " " << imageReference << ".GetDimensions(width);\n";
+ }
+ else
+ UNREACHABLE();
+
+ if (strcmp(imageFunction.getReturnType(), "int3") == 0)
+ {
+ out << " return int3(width, height, depth);\n";
+ }
+ else if (strcmp(imageFunction.getReturnType(), "int2") == 0)
+ {
+ out << " return int2(width, height);\n";
+ }
+ else if (strcmp(imageFunction.getReturnType(), "int") == 0)
+ out << " return int(width);\n";
+ else
+ UNREACHABLE();
+}
+
+// static
+void ImageFunctionHLSL::OutputImageLoadFunctionBody(
+ TInfoSinkBase &out,
+ const ImageFunctionHLSL::ImageFunction &imageFunction,
+ const ImmutableString &imageReference)
+{
+ if (IsImage3D(imageFunction.image) || IsImage2DArray(imageFunction.image) ||
+ IsImageCube(imageFunction.image))
+ {
+ out << " return " << imageReference << "[uint3(p.x, p.y, p.z)];\n";
+ }
+ else if (IsImage2D(imageFunction.image))
+ {
+ out << " return " << imageReference << "[uint2(p.x, p.y)];\n";
+ }
+ else if (IsImageBuffer(imageFunction.image))
+ {
+ out << " return " << imageReference << "[uint(p.x)];\n";
+ }
+ else
+ UNREACHABLE();
+}
+
+// static
+void ImageFunctionHLSL::OutputImageStoreFunctionBody(
+ TInfoSinkBase &out,
+ const ImageFunctionHLSL::ImageFunction &imageFunction,
+ const ImmutableString &imageReference)
+{
+ if (IsImage3D(imageFunction.image) || IsImage2DArray(imageFunction.image) ||
+ IsImage2D(imageFunction.image) || IsImageCube(imageFunction.image) ||
+ IsImageBuffer(imageFunction.image))
+ {
+ out << " " << imageReference << "[p] = data;\n";
+ }
+ else
+ UNREACHABLE();
+}
+
+ImmutableString ImageFunctionHLSL::ImageFunction::name() const
+{
+ static const ImmutableString kGlImageName("gl_image");
+
+ ImmutableString suffix(nullptr);
+ if (readonly)
+ {
+ suffix = ImmutableString(TextureTypeSuffix(image, imageInternalFormat));
+ }
+ else
+ {
+ suffix = ImmutableString(RWTextureTypeSuffix(image, imageInternalFormat));
+ }
+
+ ImmutableStringBuilder name(kGlImageName.length() + suffix.length() + 5u);
+
+ name << kGlImageName << suffix;
+
+ switch (method)
+ {
+ case Method::SIZE:
+ name << "Size";
+ break;
+ case Method::LOAD:
+ name << "Load";
+ break;
+ case Method::STORE:
+ name << "Store";
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ return name;
+}
+
+ImageFunctionHLSL::ImageFunction::DataType ImageFunctionHLSL::ImageFunction::getDataType(
+ TLayoutImageInternalFormat format) const
+{
+ switch (format)
+ {
+ case EiifRGBA32F:
+ case EiifRGBA16F:
+ case EiifR32F:
+ return ImageFunction::DataType::FLOAT4;
+ case EiifRGBA32UI:
+ case EiifRGBA16UI:
+ case EiifRGBA8UI:
+ case EiifR32UI:
+ return ImageFunction::DataType::UINT4;
+ case EiifRGBA32I:
+ case EiifRGBA16I:
+ case EiifRGBA8I:
+ case EiifR32I:
+ return ImageFunction::DataType::INT4;
+ case EiifRGBA8:
+ return ImageFunction::DataType::UNORM_FLOAT4;
+ case EiifRGBA8_SNORM:
+ return ImageFunction::DataType::SNORM_FLOAT4;
+ default:
+ UNREACHABLE();
+ }
+
+ return ImageFunction::DataType::NONE;
+}
+
+const char *ImageFunctionHLSL::ImageFunction::getReturnType() const
+{
+ if (method == ImageFunction::Method::SIZE)
+ {
+ switch (image)
+ {
+ case EbtImage2D:
+ case EbtIImage2D:
+ case EbtUImage2D:
+ case EbtImageCube:
+ case EbtIImageCube:
+ case EbtUImageCube:
+ return "int2";
+ case EbtImage3D:
+ case EbtIImage3D:
+ case EbtUImage3D:
+ case EbtImage2DArray:
+ case EbtIImage2DArray:
+ case EbtUImage2DArray:
+ return "int3";
+ case EbtImageBuffer:
+ case EbtIImageBuffer:
+ case EbtUImageBuffer:
+ return "int";
+ default:
+ UNREACHABLE();
+ }
+ }
+ else if (method == ImageFunction::Method::LOAD)
+ {
+ switch (image)
+ {
+ case EbtImageBuffer:
+ case EbtImage2D:
+ case EbtImage3D:
+ case EbtImageCube:
+ case EbtImage2DArray:
+ return "float4";
+ case EbtIImageBuffer:
+ case EbtIImage2D:
+ case EbtIImage3D:
+ case EbtIImageCube:
+ case EbtIImage2DArray:
+ return "int4";
+ case EbtUImageBuffer:
+ case EbtUImage2D:
+ case EbtUImage3D:
+ case EbtUImageCube:
+ case EbtUImage2DArray:
+ return "uint4";
+ default:
+ UNREACHABLE();
+ }
+ }
+ else if (method == ImageFunction::Method::STORE)
+ {
+ return "void";
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+ return "";
+}
+
+bool ImageFunctionHLSL::ImageFunction::operator<(const ImageFunction &rhs) const
+{
+ return std::tie(image, type, method, readonly) <
+ std::tie(rhs.image, rhs.type, rhs.method, rhs.readonly);
+}
+
+ImmutableString ImageFunctionHLSL::useImageFunction(const ImmutableString &name,
+ const TBasicType &type,
+ TLayoutImageInternalFormat imageInternalFormat,
+ bool readonly)
+{
+ ASSERT(IsImage(type));
+ ImageFunction imageFunction;
+ imageFunction.image = type;
+ imageFunction.imageInternalFormat = imageInternalFormat;
+ imageFunction.readonly = readonly;
+ imageFunction.type = imageFunction.getDataType(imageInternalFormat);
+
+ if (name == "imageSize")
+ {
+ imageFunction.method = ImageFunction::Method::SIZE;
+ }
+ else if (name == "imageLoad")
+ {
+ imageFunction.method = ImageFunction::Method::LOAD;
+ }
+ else if (name == "imageStore")
+ {
+ imageFunction.method = ImageFunction::Method::STORE;
+ }
+ else
+ UNREACHABLE();
+
+ mUsesImage.insert(imageFunction);
+ return imageFunction.name();
+}
+
+void ImageFunctionHLSL::imageFunctionHeader(TInfoSinkBase &out)
+{
+ for (const ImageFunction &imageFunction : mUsesImage)
+ {
+ // Skip to generate image2D functions here, dynamically generate these
+ // functions when linking, or after dispatch or draw.
+ if (IsImage2D(imageFunction.image))
+ {
+ mUsedImage2DFunctionNames.insert(imageFunction.name().data());
+ continue;
+ }
+ // Function header
+ out << imageFunction.getReturnType() << " " << imageFunction.name() << "(";
+
+ OutputImageFunctionArgumentList(out, imageFunction);
+
+ out << ")\n"
+ "{\n";
+
+ ImmutableString imageReference = GetImageReference(out, imageFunction);
+ if (imageFunction.method == ImageFunction::Method::SIZE)
+ {
+ OutputImageSizeFunctionBody(out, imageFunction, imageReference);
+ }
+ else if (imageFunction.method == ImageFunction::Method::LOAD)
+ {
+ OutputImageLoadFunctionBody(out, imageFunction, imageReference);
+ }
+ else
+ {
+ OutputImageStoreFunctionBody(out, imageFunction, imageReference);
+ }
+
+ out << "}\n"
+ "\n";
+ }
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/ImageFunctionHLSL.h b/gfx/angle/checkout/src/compiler/translator/ImageFunctionHLSL.h
new file mode 100644
index 0000000000..12a4a9de27
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ImageFunctionHLSL.h
@@ -0,0 +1,96 @@
+//
+// Copyright 2017 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.
+//
+// ImageFunctionHLSL: Class for writing implementations of ESSL image functions into HLSL output.
+//
+
+#ifndef COMPILER_TRANSLATOR_IMAGEFUNCTIONHLSL_H_
+#define COMPILER_TRANSLATOR_IMAGEFUNCTIONHLSL_H_
+
+#include <set>
+
+#include "GLSLANG/ShaderLang.h"
+#include "compiler/translator/BaseTypes.h"
+#include "compiler/translator/Common.h"
+#include "compiler/translator/InfoSink.h"
+#include "compiler/translator/Types.h"
+
+namespace sh
+{
+
+class ImageFunctionHLSL final : angle::NonCopyable
+{
+ public:
+ // Returns the name of the image function implementation to caller.
+ // The name that's passed in is the name of the GLSL image function that it should implement.
+ ImmutableString useImageFunction(const ImmutableString &name,
+ const TBasicType &type,
+ TLayoutImageInternalFormat imageInternalFormat,
+ bool readonly);
+
+ void imageFunctionHeader(TInfoSinkBase &out);
+ const std::set<std::string> &getUsedImage2DFunctionNames() const
+ {
+ return mUsedImage2DFunctionNames;
+ }
+
+ private:
+ struct ImageFunction
+ {
+ // See ESSL 3.10.4 section 8.12 for reference about what the different methods below do.
+ enum class Method
+ {
+ SIZE,
+ LOAD,
+ STORE
+ };
+
+ enum class DataType
+ {
+ NONE,
+ FLOAT4,
+ UINT4,
+ INT4,
+ UNORM_FLOAT4,
+ SNORM_FLOAT4
+ };
+
+ ImmutableString name() const;
+
+ bool operator<(const ImageFunction &rhs) const;
+
+ DataType getDataType(TLayoutImageInternalFormat format) const;
+
+ const char *getReturnType() const;
+
+ TBasicType image;
+ TLayoutImageInternalFormat imageInternalFormat;
+ bool readonly;
+ Method method;
+ DataType type;
+ };
+
+ static ImmutableString GetImageReference(TInfoSinkBase &out,
+ const ImageFunctionHLSL::ImageFunction &imageFunction);
+ static void OutputImageFunctionArgumentList(
+ TInfoSinkBase &out,
+ const ImageFunctionHLSL::ImageFunction &imageFunction);
+ static void OutputImageSizeFunctionBody(TInfoSinkBase &out,
+ const ImageFunctionHLSL::ImageFunction &imageFunction,
+ const ImmutableString &imageReference);
+ static void OutputImageLoadFunctionBody(TInfoSinkBase &out,
+ const ImageFunctionHLSL::ImageFunction &imageFunction,
+ const ImmutableString &imageReference);
+ static void OutputImageStoreFunctionBody(TInfoSinkBase &out,
+ const ImageFunctionHLSL::ImageFunction &imageFunction,
+ const ImmutableString &imageReference);
+ using ImageFunctionSet = std::set<ImageFunction>;
+ ImageFunctionSet mUsesImage;
+ std::set<std::string> mUsedImage2DFunctionNames;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_IMAGEFUNCTIONHLSL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/ImmutableString.h b/gfx/angle/checkout/src/compiler/translator/ImmutableString.h
new file mode 100644
index 0000000000..f172708d7d
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ImmutableString.h
@@ -0,0 +1,143 @@
+//
+// Copyright 2018 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.
+//
+// ImmutableString.h: Wrapper for static or pool allocated char arrays, that are guaranteed to be
+// valid and unchanged for the duration of the compilation.
+//
+
+#ifndef COMPILER_TRANSLATOR_IMMUTABLESTRING_H_
+#define COMPILER_TRANSLATOR_IMMUTABLESTRING_H_
+
+#include <string>
+
+#include "common/string_utils.h"
+#include "compiler/translator/Common.h"
+
+namespace sh
+{
+
+namespace
+{
+constexpr size_t constStrlen(const char *str)
+{
+ if (str == nullptr)
+ {
+ return 0u;
+ }
+ size_t len = 0u;
+ while (*(str + len) != '\0')
+ {
+ ++len;
+ }
+ return len;
+}
+} // namespace
+
+class ImmutableString
+{
+ public:
+ // The data pointer passed in must be one of:
+ // 1. nullptr (only valid with length 0).
+ // 2. a null-terminated static char array like a string literal.
+ // 3. a null-terminated pool allocated char array. This can't be c_str() of a local TString,
+ // since when a TString goes out of scope it clears its first character.
+ explicit constexpr ImmutableString(const char *data) : mData(data), mLength(constStrlen(data))
+ {}
+
+ constexpr ImmutableString(const char *data, size_t length) : mData(data), mLength(length) {}
+
+ ImmutableString(const std::string &str)
+ : mData(AllocatePoolCharArray(str.c_str(), str.size())), mLength(str.size())
+ {}
+
+ constexpr ImmutableString(const ImmutableString &) = default;
+
+ ImmutableString &operator=(const ImmutableString &) = default;
+
+ constexpr const char *data() const { return mData ? mData : ""; }
+ constexpr size_t length() const { return mLength; }
+
+ char operator[](size_t index) const { return data()[index]; }
+
+ constexpr bool empty() const { return mLength == 0; }
+ bool beginsWith(const char *prefix) const { return angle::BeginsWith(data(), prefix); }
+ constexpr bool beginsWith(const ImmutableString &prefix) const
+ {
+ return mLength >= prefix.length() && memcmp(data(), prefix.data(), prefix.length()) == 0;
+ }
+ bool contains(const char *substr) const { return strstr(data(), substr) != nullptr; }
+
+ constexpr bool operator==(const ImmutableString &b) const
+ {
+ if (mLength != b.mLength)
+ {
+ return false;
+ }
+ return memcmp(data(), b.data(), mLength) == 0;
+ }
+ constexpr bool operator!=(const ImmutableString &b) const { return !(*this == b); }
+ constexpr bool operator==(const char *b) const
+ {
+ if (b == nullptr)
+ {
+ return empty();
+ }
+ return strcmp(data(), b) == 0;
+ }
+ constexpr bool operator!=(const char *b) const { return !(*this == b); }
+ bool operator==(const std::string &b) const
+ {
+ return mLength == b.length() && memcmp(data(), b.c_str(), mLength) == 0;
+ }
+ bool operator!=(const std::string &b) const { return !(*this == b); }
+
+ constexpr bool operator<(const ImmutableString &b) const
+ {
+ if (mLength < b.mLength)
+ {
+ return true;
+ }
+ if (mLength > b.mLength)
+ {
+ return false;
+ }
+ return (memcmp(data(), b.data(), mLength) < 0);
+ }
+
+ template <size_t hashBytes>
+ struct FowlerNollVoHash
+ {
+ static const size_t kFnvOffsetBasis;
+ static const size_t kFnvPrime;
+
+ constexpr size_t operator()(const ImmutableString &a) const
+ {
+ const char *data = a.data();
+ size_t hash = kFnvOffsetBasis;
+ while ((*data) != '\0')
+ {
+ hash = hash ^ (*data);
+ hash = hash * kFnvPrime;
+ ++data;
+ }
+ return hash;
+ }
+ };
+
+ // Perfect hash functions
+ uint32_t mangledNameHash() const;
+ uint32_t unmangledNameHash() const;
+
+ private:
+ const char *mData;
+ size_t mLength;
+};
+
+constexpr ImmutableString kEmptyImmutableString("");
+} // namespace sh
+
+std::ostream &operator<<(std::ostream &os, const sh::ImmutableString &str);
+
+#endif // COMPILER_TRANSLATOR_IMMUTABLESTRING_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/ImmutableStringBuilder.cpp b/gfx/angle/checkout/src/compiler/translator/ImmutableStringBuilder.cpp
new file mode 100644
index 0000000000..3c7c01041f
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ImmutableStringBuilder.cpp
@@ -0,0 +1,63 @@
+//
+// Copyright 2018 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.
+//
+// ImmutableStringBuilder.cpp: Stringstream-like utility for building pool allocated strings where
+// the maximum length is known in advance.
+//
+
+#include "compiler/translator/ImmutableStringBuilder.h"
+
+#include <stdio.h>
+
+namespace sh
+{
+
+ImmutableStringBuilder &ImmutableStringBuilder::operator<<(const ImmutableString &str)
+{
+ ASSERT(mData != nullptr);
+ ASSERT(mPos + str.length() <= mMaxLength);
+ memcpy(mData + mPos, str.data(), str.length());
+ mPos += str.length();
+ return *this;
+}
+
+ImmutableStringBuilder &ImmutableStringBuilder::operator<<(const char *str)
+{
+ ASSERT(mData != nullptr);
+ size_t len = strlen(str);
+ ASSERT(mPos + len <= mMaxLength);
+ memcpy(mData + mPos, str, len);
+ mPos += len;
+ return *this;
+}
+
+ImmutableStringBuilder &ImmutableStringBuilder::operator<<(const char &c)
+{
+ ASSERT(mData != nullptr);
+ ASSERT(mPos + 1 <= mMaxLength);
+ mData[mPos++] = c;
+ return *this;
+}
+
+void ImmutableStringBuilder::appendDecimal(const uint32_t &u)
+{
+ int numChars = snprintf(mData + mPos, mMaxLength - mPos, "%d", u);
+ ASSERT(numChars >= 0);
+ ASSERT(mPos + numChars <= mMaxLength);
+ mPos += numChars;
+}
+
+ImmutableStringBuilder::operator ImmutableString()
+{
+ mData[mPos] = '\0';
+ ImmutableString str(static_cast<const char *>(mData), mPos);
+#if defined(ANGLE_ENABLE_ASSERTS)
+ // Make sure that nothing is added to the string after it is finalized.
+ mData = nullptr;
+#endif
+ return str;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/ImmutableStringBuilder.h b/gfx/angle/checkout/src/compiler/translator/ImmutableStringBuilder.h
new file mode 100644
index 0000000000..2af963821c
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ImmutableStringBuilder.h
@@ -0,0 +1,80 @@
+//
+// Copyright 2018 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.
+//
+// ImmutableStringBuilder.h: Stringstream-like utility for building pool allocated strings where the
+// maximum length is known in advance.
+//
+
+#ifndef COMPILER_TRANSLATOR_IMMUTABLESTRINGBUILDER_H_
+#define COMPILER_TRANSLATOR_IMMUTABLESTRINGBUILDER_H_
+
+#include "compiler/translator/ImmutableString.h"
+
+namespace sh
+{
+
+class ImmutableStringBuilder
+{
+ public:
+ ImmutableStringBuilder(size_t maxLength)
+ : mPos(0u), mMaxLength(maxLength), mData(AllocateEmptyPoolCharArray(maxLength))
+ {}
+
+ ImmutableStringBuilder &operator<<(const ImmutableString &str);
+
+ ImmutableStringBuilder &operator<<(const char *str);
+
+ ImmutableStringBuilder &operator<<(const char &c);
+
+ // This invalidates the ImmutableStringBuilder, so it should only be called once.
+ operator ImmutableString();
+
+ void appendDecimal(const uint32_t &i);
+
+ template <typename T>
+ void appendHex(T number)
+ {
+ ASSERT(mData != nullptr);
+ ASSERT(mPos + sizeof(T) * 2u <= mMaxLength);
+ int index = static_cast<int>(sizeof(T)) * 2 - 1;
+ // Loop through leading zeroes.
+ while (((number >> (index * 4)) & 0xfu) == 0 && index > 0)
+ {
+ --index;
+ }
+ // Write the rest of the hex digits.
+ while (index >= 0)
+ {
+ char digit = static_cast<char>((number >> (index * 4)) & 0xfu);
+ char digitChar = (digit < 10) ? (digit + '0') : (digit + ('a' - 10));
+ mData[mPos++] = digitChar;
+ --index;
+ }
+ }
+
+ template <typename T>
+ static constexpr size_t GetHexCharCount()
+ {
+ return sizeof(T) * 2;
+ }
+
+ private:
+ inline static char *AllocateEmptyPoolCharArray(size_t strLength)
+ {
+ size_t requiredSize = strLength + 1u;
+ return static_cast<char *>(GetGlobalPoolAllocator()->allocate(requiredSize));
+ }
+
+ size_t mPos;
+ size_t mMaxLength;
+ char *mData;
+};
+
+// GLSL ES 3.00.6 section 3.9: the maximum length of an identifier is 1024 characters.
+constexpr unsigned int kESSLMaxIdentifierLength = 1024u;
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_IMMUTABLESTRINGBUILDER_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/ImmutableString_ESSL_autogen.cpp b/gfx/angle/checkout/src/compiler/translator/ImmutableString_ESSL_autogen.cpp
new file mode 100644
index 0000000000..6199adb2b4
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ImmutableString_ESSL_autogen.cpp
@@ -0,0 +1,345 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_builtin_symbols.py using data from builtin_variables.json and
+// builtin_function_declarations.txt.
+//
+// Copyright 2020 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.
+//
+// ImmutableString_ESSL_autogen.cpp: Wrapper for static or pool allocated char arrays, that are
+// guaranteed to be valid and unchanged for the duration of the compilation. Implements
+// mangledNameHash using perfect hash function from gen_builtin_symbols.py
+
+#include "compiler/translator/ImmutableString.h"
+
+std::ostream &operator<<(std::ostream &os, const sh::ImmutableString &str)
+{
+ return os.write(str.data(), str.length());
+}
+
+#if defined(_MSC_VER)
+# pragma warning(disable : 4309) // truncation of constant value
+#endif
+
+namespace
+{
+
+constexpr int mangledkT1[] = {3297, 2629, 2651, 2337, 2303, 3220, 3385, 1210, 2130, 1919,
+ 3300, 2529, 2310, 3215, 1751, 2155, 96, 2644, 3105, 1639,
+ 1010, 851, 1501, 558, 2641, 328, 1973, 296, 1999, 2273,
+ 441, 2860, 911, 1153, 2602, 1727, 2732, 521, 1672, 1330};
+constexpr int mangledkT2[] = {1661, 42, 548, 942, 2329, 3201, 841, 3274, 1976, 3379,
+ 1752, 1024, 961, 2388, 3033, 1547, 591, 2585, 1383, 473,
+ 319, 3081, 1789, 734, 478, 219, 1353, 381, 1660, 408,
+ 1440, 2281, 2126, 1243, 1080, 2835, 3286, 168, 458, 1343};
+constexpr int mangledkG[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1017, 0, 0, 2710, 0, 0, 0,
+ 0, 0, 2927, 578, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 2927, 632, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1534, 0, 0, 0, 1494, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 3388, 0, 0, 0, 0, 575, 0, 1229, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 2918, 0, 0, 0, 0, 0, 0, 479, 0, 0, 0,
+ 1595, 0, 0, 0, 3263, 0, 3229, 372, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3123, 0, 0, 900, 0, 0,
+ 0, 459, 0, 0, 0, 0, 0, 0, 2582, 1333, 0, 172, 126, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 2180, 0, 841, 0, 0, 0, 2145, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 954, 0, 811, 0, 0, 0, 677, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1862, 2279, 0, 2634, 0, 0, 2477, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 2784, 0, 0, 0, 3384, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 2761, 0, 0, 0, 1572, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 905,
+ 0, 0, 0, 3350, 0, 0, 0, 0, 1371, 2614, 0, 0, 3227, 0, 0, 0,
+ 1772, 0, 601, 0, 944, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1928,
+ 0, 0, 0, 0, 0, 0, 0, 0, 2236, 0, 0, 0, 3179, 0, 0, 619,
+ 0, 0, 3251, 0, 0, 0, 0, 0, 0, 203, 0, 0, 0, 0, 0, 1825,
+ 0, 0, 0, 0, 3177, 2489, 0, 0, 70, 0, 519, 0, 505, 1676, 0, 0,
+ 0, 0, 0, 1871, 0, 0, 2289, 0, 0, 0, 1192, 0, 2362, 776, 2964, 0,
+ 0, 0, 2478, 0, 1303, 0, 96, 0, 0, 3408, 0, 0, 0, 2894, 250, 0,
+ 0, 0, 0, 0, 0, 0, 0, 2894, 0, 3389, 930, 2489, 0, 2755, 0, 1807,
+ 701, 2938, 0, 0, 0, 0, 609, 0, 0, 0, 1985, 343, 0, 2608, 0, 368,
+ 1367, 1387, 0, 0, 3160, 0, 0, 0, 2036, 0, 0, 2231, 0, 0, 2248, 2652,
+ 0, 306, 0, 0, 3308, 0, 0, 0, 525, 0, 0, 1300, 0, 0, 1432, 2594,
+ 2612, 53, 1093, 0, 1779, 3020, 3237, 458, 47, 0, 0, 526, 1378, 0, 0, 0,
+ 442, 1063, 3293, 0, 0, 0, 0, 0, 0, 832, 2958, 1452, 0, 0, 349, 0,
+ 1871, 0, 0, 2548, 1826, 441, 2846, 0, 2601, 1910, 1415, 0, 0, 0, 420, 0,
+ 3073, 620, 0, 0, 1333, 1133, 0, 0, 1402, 0, 0, 0, 0, 292, 0, 0,
+ 0, 0, 0, 1598, 364, 0, 1161, 0, 0, 0, 0, 218, 0, 2572, 226, 0,
+ 527, 270, 2558, 2814, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1796, 0,
+ 0, 173, 610, 2959, 0, 0, 0, 0, 0, 301, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1954, 0, 0, 0, 0, 414, 0, 0, 0, 0, 0, 0, 0, 265,
+ 0, 0, 0, 0, 230, 0, 502, 0, 1243, 0, 0, 2474, 0, 0, 0, 0,
+ 23, 0, 668, 0, 3125, 0, 3209, 0, 0, 928, 402, 0, 39, 117, 443, 852,
+ 0, 767, 0, 0, 0, 0, 3067, 0, 0, 0, 1532, 0, 0, 0, 3202, 0,
+ 0, 0, 0, 0, 2801, 0, 2221, 0, 0, 3, 0, 0, 0, 0, 0, 3241,
+ 1620, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 665, 0, 0, 1803, 0,
+ 2475, 0, 0, 0, 499, 0, 1386, 3147, 0, 0, 1168, 0, 0, 0, 1824, 0,
+ 0, 78, 935, 136, 0, 0, 882, 0, 0, 421, 257, 381, 0, 0, 643, 0,
+ 0, 284, 0, 2581, 0, 0, 0, 0, 0, 0, 963, 0, 0, 0, 3217, 681,
+ 479, 0, 529, 0, 0, 0, 0, 0, 2901, 0, 1026, 0, 1190, 0, 0, 0,
+ 0, 0, 0, 3265, 0, 0, 2287, 0, 0, 0, 0, 594, 0, 0, 0, 0,
+ 0, 114, 0, 608, 0, 2750, 0, 3179, 0, 161, 0, 0, 0, 556, 3087, 2490,
+ 1878, 0, 0, 0, 0, 2550, 0, 0, 0, 0, 0, 1638, 0, 746, 0, 0,
+ 338, 0, 1430, 0, 0, 1407, 0, 1134, 0, 0, 0, 0, 0, 0, 0, 0,
+ 113, 227, 0, 433, 927, 0, 0, 0, 1526, 1343, 38, 0, 2017, 1986, 3079, 0,
+ 3409, 0, 0, 0, 0, 2612, 1300, 138, 0, 0, 2020, 486, 0, 0, 1627, 0,
+ 0, 209, 0, 2406, 563, 97, 0, 578, 0, 0, 1064, 0, 1394, 61, 1962, 1613,
+ 534, 134, 994, 0, 0, 3180, 0, 0, 0, 0, 0, 0, 0, 1648, 0, 0,
+ 0, 0, 0, 0, 0, 2627, 0, 0, 955, 3301, 0, 414, 395, 0, 467, 681,
+ 0, 0, 0, 3070, 747, 1612, 0, 2987, 429, 0, 0, 438, 0, 627, 2229, 0,
+ 0, 0, 0, 0, 0, 2486, 35, 0, 307, 450, 0, 0, 0, 0, 0, 3382,
+ 2994, 3119, 0, 992, 1257, 781, 1249, 0, 915, 981, 837, 3177, 0, 0, 0, 0,
+ 748, 0, 0, 66, 3212, 0, 0, 3142, 0, 311, 744, 767, 0, 0, 0, 0,
+ 0, 0, 1164, 0, 1138, 757, 67, 1332, 724, 2680, 0, 0, 0, 275, 1321, 0,
+ 0, 750, 1072, 0, 660, 1228, 546, 0, 543, 0, 0, 0, 0, 1429, 356, 0,
+ 1200, 0, 0, 914, 1270, 0, 149, 474, 936, 336, 2834, 0, 0, 0, 0, 0,
+ 93, 0, 0, 0, 588, 0, 2776, 0, 1485, 0, 3193, 1133, 0, 0, 1386, 0,
+ 0, 0, 435, 87, 0, 0, 679, 1588, 321, 0, 0, 0, 2574, 0, 0, 0,
+ 0, 1079, 156, 0, 0, 582, 0, 793, 3388, 2758, 2508, 2915, 0, 0, 1326, 925,
+ 2685, 0, 0, 3305, 0, 469, 0, 1874, 120, 0, 0, 0, 0, 567, 549, 0,
+ 1237, 0, 0, 0, 2254, 0, 0, 1747, 348, 0, 0, 0, 2774, 0, 0, 0,
+ 0, 572, 0, 0, 1785, 251, 0, 767, 0, 3365, 0, 586, 1354, 0, 1039, 0,
+ 0, 625, 0, 0, 34, 2733, 0, 888, 522, 0, 518, 0, 2166, 0, 1502, 2652,
+ 0, 1277, 2808, 0, 1369, 1428, 0, 0, 0, 711, 0, 159, 1118, 0, 0, 0,
+ 248, 996, 2274, 0, 537, 2856, 0, 0, 0, 0, 0, 0, 2313, 769, 0, 0,
+ 0, 1145, 0, 0, 0, 0, 0, 0, 0, 0, 1582, 1138, 0, 0, 0, 967,
+ 1194, 0, 273, 1590, 459, 0, 0, 1620, 0, 0, 0, 1331, 0, 661, 0, 0,
+ 339, 0, 1582, 807, 0, 0, 1082, 0, 0, 0, 0, 0, 0, 0, 293, 0,
+ 1065, 1277, 0, 0, 949, 916, 36, 867, 0, 1335, 1355, 0, 997, 1273, 0, 0,
+ 0, 1508, 0, 0, 1632, 896, 0, 3338, 0, 1280, 1145, 278, 0, 1361, 2064, 1030,
+ 0, 435, 0, 0, 384, 2984, 0, 0, 0, 0, 909, 0, 0, 0, 149, 539,
+ 2604, 0, 463, 1583, 554, 1663, 0, 446, 0, 0, 0, 1075, 0, 2395, 0, 82,
+ 258, 0, 580, 0, 0, 549, 1508, 0, 1160, 0, 108, 195, 0, 136, 0, 704,
+ 0, 0, 3108, 0, 0, 0, 1625, 0, 359, 986, 3338, 1596, 1316, 47, 718, 479,
+ 560, 0, 33, 0, 879, 0, 0, 3021, 0, 616, 342, 0, 882, 776, 3251, 0,
+ 32, 513, 273, 232, 745, 1184, 0, 3288, 364, 0, 0, 3102, 0, 3193, 481, 0,
+ 842, 0, 3113, 647, 0, 0, 0, 2239, 0, 720, 0, 1193, 0, 980, 0, 0,
+ 0, 0, 661, 1493, 3369, 3348, 31, 1970, 0, 1251, 1513, 0, 0, 2199, 673, 562,
+ 33, 186, 1457, 0, 788, 0, 1036, 0, 0, 1998, 0, 0, 0, 1906, 0, 1148,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1047, 980, 0, 1363, 0, 0, 2893,
+ 0, 0, 0, 1442, 0, 0, 2735, 1044, 0, 0, 1197, 0, 434, 0, 420, 1008,
+ 3104, 0, 2979, 823, 0, 0, 0, 98, 2814, 1534, 2319, 996, 2897, 0, 0, 2194,
+ 961, 0, 0, 1551, 0, 0, 0, 0, 0, 0, 0, 0, 565, 2808, 0, 1868,
+ 667, 0, 0, 0, 0, 1017, 139, 0, 0, 0, 154, 0, 3155, 0, 769, 2996,
+ 1247, 1113, 0, 0, 3203, 0, 1183, 0, 1469, 0, 1193, 375, 88, 0, 0, 0,
+ 0, 0, 0, 1037, 0, 3370, 180, 1947, 0, 0, 0, 2759, 2065, 0, 0, 0,
+ 3345, 564, 0, 2730, 0, 2979, 0, 5, 0, 2986, 155, 0, 393, 1884, 1845, 0,
+ 0, 2673, 0, 453, 945, 123, 1252, 0, 550, 1599, 231, 150, 1215, 0, 233, 3394,
+ 3370, 455, 0, 1620, 0, 0, 2860, 0, 1569, 0, 2095, 0, 1392, 0, 0, 373,
+ 0, 388, 0, 0, 2856, 2919, 2416, 0, 0, 0, 0, 0, 0, 933, 2108, 0,
+ 1536, 666, 675, 495, 0, 1705, 0, 0, 656, 0, 0, 63, 1484, 0, 0, 1033,
+ 0, 914, 3397, 0, 2927, 193, 597, 2666, 0, 1035, 0, 0, 0, 0, 1726, 1719,
+ 3405, 0, 0, 1644, 0, 0, 555, 0, 58, 1168, 0, 430, 236, 997, 935, 0,
+ 0, 659, 402, 3243, 0, 1010, 0, 2241, 0, 1140, 2556, 0, 1002, 748, 539, 213,
+ 0, 1602, 263, 0, 0, 0, 1286, 669, 333, 2327, 0, 0, 911, 0, 157, 716,
+ 0, 0, 0, 0, 180, 0, 0, 0, 359, 0, 3042, 0, 0, 808, 982, 732,
+ 1539, 0, 324, 0, 0, 0, 0, 3325, 698, 0, 1799, 0, 2942, 2667, 0, 519,
+ 2898, 1068, 0, 0, 0, 1460, 3022, 0, 0, 0, 2842, 927, 3152, 0, 0, 1521,
+ 1362, 0, 0, 588, 0, 34, 2910, 0, 0, 0, 2621, 0, 2712, 315, 2628, 0,
+ 286, 718, 0, 267, 775, 76, 0, 0, 0, 0, 0, 0, 0, 3229, 0, 1924,
+ 0, 0, 0, 0, 1454, 1384, 2952, 0, 0, 154, 0, 0, 0, 271, 0, 0,
+ 289, 179, 2419, 2348, 0, 766, 0, 1462, 2514, 930, 768, 0, 0, 0, 0, 0,
+ 0, 0, 331, 1380, 0, 1161, 0, 0, 3313, 0, 3367, 0, 0, 0, 0, 0,
+ 1147, 0, 1866, 0, 0, 1649, 0, 0, 0, 858, 964, 0, 1975, 0, 0, 0,
+ 0, 1031, 0, 0, 2901, 3008, 0, 0, 2440, 1174, 910, 1006, 3125, 0, 2724, 825,
+ 0, 2250, 1465, 0, 0, 0, 1104, 476, 1673, 0, 1429, 130, 1183, 1909, 183, 650,
+ 487, 0, 0, 676, 0, 1528, 0, 0, 426, 2746, 731, 0, 0, 1225, 0, 0,
+ 662, 2458, 0, 2203, 0, 0, 998, 0, 3016, 223, 0, 2759, 1006, 0, 0, 3356,
+ 1197, 0, 0, 1165, 940, 1424, 365, 1120, 0, 0, 0, 0, 838, 0, 2166, 0,
+ 1592, 2396, 859, 1542, 0, 0, 0, 406, 0, 1468, 1315, 3385, 186, 672, 3019, 853,
+ 301, 2253, 1429, 1225, 845, 1067, 128, 0, 0, 1144, 0, 207, 0, 400, 0, 1051,
+ 0, 492, 0, 0, 0, 0, 283, 0, 161, 0, 2649, 1013, 0, 3075, 0, 62,
+ 2968, 1449, 0, 641, 2728, 0, 1912, 1170, 1553, 1466, 120, 0, 0, 812, 0, 188,
+ 0, 0, 1278, 3176, 0, 0, 0, 0, 2742, 0, 0, 1772, 0, 874, 680, 0,
+ 1378, 2733, 53, 0, 0, 329, 2, 1014, 2786, 719, 1868, 0, 2296, 0, 357, 0,
+ 0, 0, 0, 2371, 1203, 1109, 1302, 3047, 2319, 0, 2834, 1711, 0, 849, 1658, 131,
+ 0, 1191, 268, 1519, 0, 1080, 0, 0, 488, 0, 46, 0, 658, 0, 0, 1838,
+ 0, 0, 0, 0, 1741, 2096, 1701, 0, 0, 691, 3262, 950, 0, 0, 0, 704,
+ 734, 2177, 3260, 0, 0, 897, 291, 1318, 866, 3105, 3161, 1205, 0, 0, 0, 0,
+ 0, 0, 0, 835, 0, 0, 0, 0, 0, 0, 1283, 0, 0, 772, 0, 1482,
+ 1609, 1279, 1121, 870, 0, 3184, 818, 1521, 0, 0, 297, 0, 0, 1360, 0, 0,
+ 249, 0, 2112, 72, 0, 1110, 2278, 619, 0, 1014, 809, 397, 0, 0, 1406, 0,
+ 905, 0, 690, 751, 0, 0, 0, 19, 3355, 0, 0, 0, 0, 1345, 114, 945,
+ 0, 122, 173, 0, 133, 0, 971, 0, 453, 1183, 0, 0, 2729, 632, 678, 1572,
+ 0, 1304, 1433, 926, 0, 0, 302, 941, 0, 0, 0, 0, 0, 1222, 0, 0,
+ 0, 0, 1771, 0, 884, 872, 0, 0, 1234, 1928, 3190, 0, 0, 0, 0, 0,
+ 238, 615, 522, 287, 654, 798, 0, 1264, 0, 0, 0, 0, 466, 395, 1175, 1406,
+ 633, 1146, 3235, 3347, 62, 237, 0, 0, 0, 0, 0, 10, 1461, 0, 0, 1914,
+ 447, 0, 3148, 1253, 1970, 0, 1404, 744, 3377, 1362, 3085, 0, 3083, 1529, 0, 0,
+ 1441, 0, 1476, 0, 955, 156, 0, 0, 1753, 1212, 0, 45, 1193, 1605, 0, 0,
+ 0, 0, 209, 180, 447, 1584, 25, 1520, 2177, 0, 74, 0, 3334, 2718, 0, 728,
+ 0, 1000, 0, 1366, 978, 0, 0, 1488, 3222, 122, 388, 1642, 946, 0, 0, 0,
+ 0, 0, 741, 0, 0, 0, 0, 1875, 1116, 880, 0, 343, 1376, 0, 1700, 0,
+ 2350, 605, 132, 0, 0, 1430, 0, 0, 528, 564, 0, 1571, 1265, 0, 0, 625,
+ 3052, 1040, 1470, 266, 603, 3325, 0, 679, 0, 1902, 265, 2718, 1591, 671, 3356, 0,
+ 0, 321, 0, 3219, 990, 0, 408, 0, 716, 0, 0, 0, 823, 99, 754, 780,
+ 3334, 365, 0, 1681, 2332, 0, 3209, 0, 0, 774, 589, 0, 0, 841, 138, 679,
+ 320, 0, 0, 2355, 491, 3001, 0, 3280, 0, 0, 1743, 0, 0, 0, 2191, 0,
+ 1177, 0, 0, 0, 0, 0, 1143, 0, 0, 0, 580, 0, 0, 0, 0, 0,
+ 0, 620, 0, 1207, 0, 1603, 494, 433, 0, 847, 44, 2265, 2101, 2457, 0, 0,
+ 0, 389, 1429, 2257, 3104, 455, 0, 0, 0, 0, 0, 0, 1468, 966, 978, 1878,
+ 1217, 3122, 2407, 0, 3022, 0, 0, 910, 466, 0, 2931, 2770, 173, 209, 1004, 0,
+ 160, 0, 1405, 0, 965, 0, 0, 1455, 1314, 2643, 0, 713, 1544, 0, 0, 0,
+ 544, 0, 476, 847, 1029, 983, 231, 285, 2181, 0, 0, 513, 739, 336, 0, 1206,
+ 0, 3020, 492, 0, 0, 596, 0, 0, 1282, 0, 121, 0, 0, 667, 873, 0,
+ 0, 1015, 196, 0, 1390, 469, 563, 1091, 349, 0, 2300, 0, 0, 104, 0, 23,
+ 1619, 0, 1649, 0, 0, 499, 558, 0, 0, 0, 0, 0, 1089, 0, 2932, 473,
+ 700, 2599, 0, 3, 3365, 557, 1347, 1138, 380, 2427, 0, 1084, 0, 0, 0, 701,
+ 0, 0, 2747, 0, 0, 1481, 0, 2017, 1487, 0, 0, 0, 0, 0, 2867, 609,
+ 0, 1453, 1383, 0, 0, 489, 0, 663, 3399, 0, 0, 2629, 1525, 2947, 0, 1472,
+ 0, 0, 744, 14, 0, 2982, 639, 0, 741, 389, 0, 0, 795, 0, 527, 0,
+ 0, 0, 404, 768, 2738, 1877, 0, 900, 82, 0, 0, 967, 0, 573, 103, 0,
+ 0, 498, 2837, 0, 0, 0, 340, 1070, 0, 0, 1127, 0, 1028, 1166, 0, 0,
+ 0, 0, 1111, 0, 1238, 2206, 222, 0, 632, 0, 3368, 923, 433, 0, 705, 57,
+ 536, 1427, 0, 0, 1232, 101, 0, 0, 255, 1427, 828, 0, 160, 613, 2986, 0,
+ 1010, 0, 0, 0, 2915, 2185, 1519, 2988, 2817, 3387, 3090, 1538, 43, 0, 781, 0,
+ 0, 0, 0, 0, 804, 2815, 3088, 3021, 1095, 0, 0, 0, 0, 1285, 0, 0,
+ 244, 0, 713, 0, 899, 0, 0, 0, 142, 16, 0, 1655, 119, 22, 2957, 0,
+ 785, 2620, 666, 0, 263, 0, 2359, 1150, 0, 243, 0, 946, 988, 1510, 637, 1271,
+ 1038, 0, 2893, 0, 0, 938, 0, 0, 175, 0, 0, 0, 0, 0, 0, 277,
+ 0, 2910, 0, 0, 0, 0, 1516, 2054, 0, 3270, 0, 3088, 410, 0, 3203, 1216,
+ 0, 0, 0, 1076, 590, 141, 282, 0, 0, 193, 2844, 225, 2981, 0, 0, 555,
+ 0, 1054, 275, 0, 1142, 0, 504, 1045, 550, 0, 799, 188, 2264, 1137, 0, 298,
+ 2843, 3120, 3365, 0, 881, 1430, 2165, 2552, 0, 0, 2305, 0, 1944, 0, 2030, 606,
+ 3296, 3028, 274, 936, 3036, 1285, 642, 0, 116, 834, 0, 1485, 1322, 0, 1667, 0,
+ 697, 2746, 893, 1561, 1264, 102, 0, 0, 362, 1242, 142, 0, 225, 957, 1153, 117,
+ 0, 515, 0, 0, 1393, 365, 266, 834, 0, 1317, 0, 0, 2334, 0, 0, 0,
+ 0, 0, 0, 165, 1293, 526, 17, 0, 71, 0, 2986, 0, 808, 1195, 6, 1124,
+ 0, 0, 0, 0, 0, 274, 0, 0, 0, 0, 0, 0, 1511, 380, 0, 250,
+ 0, 2324, 771, 0, 195, 0, 393, 0, 2126, 258, 0, 21, 354, 0, 0, 198,
+ 0, 0, 514, 0, 0, 0, 0, 0, 0, 0, 0, 564, 1284, 0, 0, 735,
+ 2316, 1196, 831, 1279, 2599, 504, 0, 1174, 3177, 0, 1224, 1308, 574, 119, 1426, 1969,
+ 0, 197, 1029, 0, 860, 928, 0, 1114, 767, 2884, 0, 0, 492, 1549, 2358, 0,
+ 2878, 930, 581, 1368, 0, 1223, 0, 96, 0, 3313, 868, 0, 2962, 2697, 2823, 1086,
+ 3239, 448, 0, 0, 0, 1236, 0, 0, 1310, 886, 531, 0, 9, 0, 0, 293,
+ 0, 0, 2627, 3078, 3408, 1297, 883, 115, 0, 2906, 3009, 0, 1405, 1046, 1101, 0,
+ 1556, 1118, 1103, 0, 0, 2284, 434, 922, 0, 0, 941, 3194, 1069, 2741, 307, 668,
+ 2373, 3061, 945, 643, 0, 1503, 0, 561, 0, 618, 0, 1172, 3050, 3218, 0, 752,
+ 2992, 0, 0, 0, 0, 839, 1252, 348, 144, 0, 29, 1190, 441, 3202, 705, 2600,
+ 1516, 73, 472, 814, 3042, 360, 0, 3256, 0, 0, 0, 0, 0, 0, 1748, 1007,
+ 3384, 0, 0, 1412, 473, 0, 0, 1325, 0, 3170, 541, 0, 1066, 1126, 1215, 0,
+ 0, 624, 0, 1219, 0, 949, 0, 730, 1376, 2256, 733, 0, 1577, 0, 576, 1594,
+ 181, 0, 461, 3238, 1436, 0, 900, 2191, 0, 894, 698, 0, 777, 59, 845, 2941,
+ 0, 0, 1408, 0, 224, 0, 0, 0, 2322, 1129, 1511, 0, 870, 239, 3365, 0,
+ 918, 1107, 0, 2483, 0, 0, 0, 0, 0, 0, 235, 1152, 1300, 304, 0, 396,
+ 0, 0, 130, 0, 0, 0, 0, 0, 212, 0, 0, 0, 0, 1554, 0, 0,
+ 394, 3180, 1050, 0, 1363, 861, 0, 1069, 1015, 0, 3146, 0, 1352, 0, 876, 1221,
+ 0, 325, 0, 0, 53, 107, 0, 2951, 0, 0, 310, 424, 49, 0, 0, 815,
+ 0, 749, 0, 3227, 1192, 2310, 1281, 3210, 0, 252, 380, 0, 514, 0, 1404, 908,
+ 0, 0, 300, 920, 0, 0, 2257, 1566, 0, 396, 558, 0, 0, 936, 0, 663,
+ 2840, 0, 0, 1325, 2928, 1798, 0, 2180, 1327, 568, 1585, 662, 0, 0, 0, 1910,
+ 976, 0, 58, 0, 0, 3353, 0, 0, 0, 2580, 2798, 3201, 1146, 1352, 0, 858,
+ 104, 0, 1668, 0, 3186, 781, 987, 0, 571, 193, 13, 415, 657, 52, 0, 0,
+ 333, 729, 207, 696, 0, 3378, 1198, 2332, 0, 1327, 1564, 1009, 0, 0, 0, 0,
+ 153, 2698, 89, 1114, 3368, 2898, 3117, 2837, 0, 2690, 0, 2278, 2025, 921, 3232, 0,
+ 0, 1036, 2620, 0, 0, 0, 0, 300, 0, 1075, 1668, 0, 0, 0, 3159, 0,
+ 3032, 0, 3083, 982, 1684, 0, 0, 0, 523, 0, 0, 0, 0, 0, 294, 0,
+ 434, 52, 2034, 0, 0, 497, 2951, 1499, 0, 1874, 0, 2853, 0, 3319, 442, 1411,
+ 0, 2945, 0, 1324, 251, 3096, 0, 723, 3150, 0, 0, 0, 0, 570, 0, 3295,
+ 1259, 0, 1395, 2545, 885, 1991, 1730, 1268, 2599, 0, 1289, 275, 0, 0, 113, 1835,
+ 885, 1259, 2295, 682, 0, 0, 932, 0, 286, 0, 0, 60, 864, 0, 0, 1483,
+ 0, 86, 587, 9, 459, 0, 1342, 0, 1287, 416, 14, 371, 0, 0, 507, 0,
+ 350, 2826, 0, 0, 0, 3293, 3183, 0, 238, 0, 1501, 2720, 0, 3107, 0, 2340,
+ 1602, 2599, 0, 314, 0, 0, 1062, 347, 0, 1546, 0, 0, 0, 0, 895, 158,
+ 217, 1351, 0, 0, 2160, 0, 0, 120, 755, 407, 2490, 305, 288, 0, 182, 745,
+ 0, 1666, 3220, 177, 0, 0, 958, 0, 0, 0, 0, 2293, 0, 0, 0, 503,
+ 0, 0, 0, 1256, 2600, 987, 2318, 529, 1617, 3147, 1601, 0, 3178, 2050, 569, 0,
+ 513, 0, 0, 689, 1308, 0, 0, 0, 0, 746, 0, 398, 2399, 1141, 0, 3356,
+ 214, 0, 0, 2903, 0, 431, 2902, 356, 1944, 1430, 1478, 6, 0, 0, 117, 0,
+ 2887, 2267};
+
+int MangledHashG(const char *key, const int *T)
+{
+ int sum = 0;
+
+ for (int i = 0; key[i] != '\0'; i++)
+ {
+ sum += T[i] * key[i];
+ sum %= 3410;
+ }
+ return mangledkG[sum];
+}
+
+int MangledPerfectHash(const char *key)
+{
+ if (strlen(key) > 40)
+ return 0;
+
+ return (MangledHashG(key, mangledkT1) + MangledHashG(key, mangledkT2)) % 3410;
+}
+
+constexpr int unmangledkT1[] = {258, 260, 73, 6, 294, 235, 86, 89, 66, 164, 215,
+ 28, 84, 215, 207, 246, 53, 166, 227, 83, 238, 195,
+ 109, 294, 270, 27, 167, 281, 55, 194, 257, 4};
+constexpr int unmangledkT2[] = {67, 64, 203, 266, 212, 293, 215, 33, 106, 81, 61,
+ 214, 272, 162, 248, 114, 4, 202, 197, 98, 169, 304,
+ 196, 197, 294, 217, 1, 201, 74, 46, 38, 221};
+constexpr int unmangledkG[] = {
+ 0, 0, 0, 0, 132, 0, 0, 123, 0, 152, 0, 87, 196, 305, 0, 0, 229, 273,
+ 130, 0, 87, 27, 163, 284, 0, 0, 0, 179, 233, 88, 0, 0, 0, 0, 12, 0,
+ 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 126, 0, 104, 0, 222, 0, 0, 0,
+ 0, 0, 171, 36, 129, 0, 0, 0, 113, 0, 142, 303, 0, 138, 246, 0, 21, 0,
+ 121, 0, 162, 0, 0, 0, 0, 0, 147, 205, 0, 0, 232, 19, 0, 200, 0, 0,
+ 0, 68, 277, 68, 63, 0, 31, 0, 0, 255, 0, 0, 122, 0, 0, 108, 1, 63,
+ 74, 20, 130, 0, 0, 284, 0, 98, 158, 245, 0, 22, 2, 157, 195, 0, 257, 0,
+ 0, 0, 2, 172, 0, 0, 0, 0, 0, 132, 0, 0, 72, 27, 35, 269, 224, 0,
+ 216, 45, 151, 44, 9, 21, 0, 0, 188, 0, 229, 132, 212, 0, 75, 279, 119, 0,
+ 0, 0, 261, 25, 3, 180, 0, 0, 42, 40, 133, 200, 51, 0, 0, 232, 137, 128,
+ 9, 0, 0, 0, 278, 0, 0, 100, 0, 0, 0, 11, 137, 0, 0, 6, 0, 97,
+ 63, 0, 0, 166, 86, 0, 43, 228, 0, 0, 88, 272, 242, 61, 25, 99, 0, 260,
+ 169, 0, 0, 0, 99, 123, 39, 289, 77, 83, 0, 0, 33, 167, 0, 305, 0, 230,
+ 22, 0, 284, 0, 85, 26, 0, 80, 0, 0, 19, 206, 266, 0, 292, 74, 233, 86,
+ 218, 0, 63, 104, 15, 0, 0, 26, 132, 303, 0, 155, 256, 0, 109, 0, 215, 52,
+ 0, 0, 155, 95, 240, 112, 0, 95, 54, 89, 0, 171, 0, 158, 0, 51, 23, 125,
+ 276, 16, 107, 177, 92, 113, 32, 45, 136, 0, 0, 90, 241, 279, 38, 185, 0, 169};
+
+int UnmangledHashG(const char *key, const int *T)
+{
+ int sum = 0;
+
+ for (int i = 0; key[i] != '\0'; i++)
+ {
+ sum += T[i] * key[i];
+ sum %= 306;
+ }
+ return unmangledkG[sum];
+}
+
+int UnmangledPerfectHash(const char *key)
+{
+ if (strlen(key) > 32)
+ return 0;
+
+ return (UnmangledHashG(key, unmangledkT1) + UnmangledHashG(key, unmangledkT2)) % 306;
+}
+
+} // namespace
+
+namespace sh
+{
+
+template <>
+const size_t ImmutableString::FowlerNollVoHash<4>::kFnvPrime = 16777619u;
+
+template <>
+const size_t ImmutableString::FowlerNollVoHash<4>::kFnvOffsetBasis = 0x811c9dc5u;
+
+template <>
+const size_t ImmutableString::FowlerNollVoHash<8>::kFnvPrime =
+ static_cast<size_t>(1099511628211ull);
+
+template <>
+const size_t ImmutableString::FowlerNollVoHash<8>::kFnvOffsetBasis =
+ static_cast<size_t>(0xcbf29ce484222325ull);
+
+uint32_t ImmutableString::mangledNameHash() const
+{
+ return MangledPerfectHash(data());
+}
+
+uint32_t ImmutableString::unmangledNameHash() const
+{
+ return UnmangledPerfectHash(data());
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/InfoSink.cpp b/gfx/angle/checkout/src/compiler/translator/InfoSink.cpp
new file mode 100644
index 0000000000..0e67d7324e
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/InfoSink.cpp
@@ -0,0 +1,124 @@
+//
+// Copyright 2002 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/ImmutableString.h"
+#include "compiler/translator/Symbol.h"
+#include "compiler/translator/Types.h"
+
+namespace sh
+{
+
+void TInfoSinkBase::prefix(Severity severity)
+{
+ switch (severity)
+ {
+ case SH_WARNING:
+ sink.append("WARNING: ");
+ break;
+ case SH_ERROR:
+ sink.append("ERROR: ");
+ break;
+ default:
+ sink.append("UNKOWN ERROR: ");
+ break;
+ }
+}
+
+TInfoSinkBase &TInfoSinkBase::operator<<(const ImmutableString &str)
+{
+ sink.append(str.data());
+ return *this;
+}
+
+TInfoSinkBase &TInfoSinkBase::operator<<(const TType &type)
+{
+ if (type.isInvariant())
+ sink.append("invariant ");
+ if (type.getQualifier() != EvqTemporary && type.getQualifier() != EvqGlobal)
+ {
+ sink.append(type.getQualifierString());
+ sink.append(" ");
+ }
+ if (type.getPrecision() != EbpUndefined)
+ {
+ sink.append(type.getPrecisionString());
+ sink.append(" ");
+ }
+
+ const TMemoryQualifier &memoryQualifier = type.getMemoryQualifier();
+ if (memoryQualifier.readonly)
+ {
+ sink.append("readonly ");
+ }
+ if (memoryQualifier.writeonly)
+ {
+ sink.append("writeonly ");
+ }
+ if (memoryQualifier.coherent)
+ {
+ sink.append("coherent ");
+ }
+ if (memoryQualifier.restrictQualifier)
+ {
+ sink.append("restrict ");
+ }
+ if (memoryQualifier.volatileQualifier)
+ {
+ sink.append("volatile ");
+ }
+
+ if (type.isArray())
+ {
+ for (auto arraySizeIter = type.getArraySizes().rbegin();
+ arraySizeIter != type.getArraySizes().rend(); ++arraySizeIter)
+ {
+ *this << "array[" << (*arraySizeIter) << "] of ";
+ }
+ }
+ if (type.isMatrix())
+ {
+ *this << static_cast<uint32_t>(type.getCols()) << "X"
+ << static_cast<uint32_t>(type.getRows()) << " matrix of ";
+ }
+ else if (type.isVector())
+ *this << static_cast<uint32_t>(type.getNominalSize()) << "-component vector of ";
+
+ sink.append(type.getBasicString());
+
+ if (type.getStruct() != nullptr)
+ {
+ if (type.getStruct()->symbolType() == SymbolType::Empty)
+ {
+ *this << " <anonymous>";
+ }
+ else
+ {
+ *this << " '" << type.getStruct()->name() << "'";
+ }
+ if (type.isStructSpecifier())
+ {
+ *this << " (specifier)";
+ }
+ }
+
+ return *this;
+}
+
+void TInfoSinkBase::location(int file, int line)
+{
+ TPersistStringStream stream = sh::InitializeStream<TPersistStringStream>();
+ if (line)
+ stream << file << ":" << line;
+ else
+ stream << file << ":? ";
+ stream << ": ";
+
+ sink.append(stream.str());
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/InfoSink.h b/gfx/angle/checkout/src/compiler/translator/InfoSink.h
new file mode 100644
index 0000000000..bf6df8800c
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/InfoSink.h
@@ -0,0 +1,152 @@
+//
+// Copyright 2002 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_INFOSINK_H_
+#define COMPILER_TRANSLATOR_INFOSINK_H_
+
+#include <math.h>
+#include <stdlib.h>
+#include "GLSLANG/ShaderLang.h"
+#include "compiler/translator/Common.h"
+#include "compiler/translator/Severity.h"
+
+namespace sh
+{
+
+class ImmutableString;
+class TType;
+
+// Returns the fractional part of the given floating-point number.
+inline float fractionalPart(float f)
+{
+ float intPart = 0.0f;
+ return modff(f, &intPart);
+}
+
+class ImmutableString;
+
+//
+// Encapsulate info logs for all objects that have them.
+//
+// The methods are a general set of tools for getting a variety of
+// messages and types inserted into the log.
+//
+class TInfoSinkBase
+{
+ public:
+ TInfoSinkBase() {}
+
+ template <typename T>
+ TInfoSinkBase &operator<<(const T &t)
+ {
+ TPersistStringStream stream = sh::InitializeStream<TPersistStringStream>();
+ stream << t;
+ sink.append(stream.str());
+ return *this;
+ }
+ // Override << operator for specific types. It is faster to append strings
+ // and characters directly to the sink.
+ TInfoSinkBase &operator<<(char c)
+ {
+ sink.append(1, c);
+ return *this;
+ }
+ TInfoSinkBase &operator<<(const char *str)
+ {
+ sink.append(str);
+ return *this;
+ }
+ TInfoSinkBase &operator<<(const TPersistString &str)
+ {
+ sink.append(str);
+ return *this;
+ }
+ TInfoSinkBase &operator<<(const TString &str)
+ {
+ sink.append(str.c_str());
+ return *this;
+ }
+ TInfoSinkBase &operator<<(const ImmutableString &str);
+
+ TInfoSinkBase &operator<<(const TType &type);
+
+ // Make sure floats are written with correct precision.
+ TInfoSinkBase &operator<<(float f)
+ {
+ // Make sure that at least one decimal point is written. If a number
+ // does not have a fractional part, the default precision format does
+ // not write the decimal portion which gets interpreted as integer by
+ // the compiler.
+ TPersistStringStream stream = sh::InitializeStream<TPersistStringStream>();
+ if (fractionalPart(f) == 0.0f)
+ {
+ stream.precision(1);
+ stream << std::showpoint << std::fixed << f;
+ }
+ else
+ {
+ stream.unsetf(std::ios::fixed);
+ stream.unsetf(std::ios::scientific);
+ stream.precision(8);
+ stream << f;
+ }
+ sink.append(stream.str());
+ return *this;
+ }
+ // Write boolean values as their names instead of integral value.
+ TInfoSinkBase &operator<<(bool b)
+ {
+ const char *str = b ? "true" : "false";
+ sink.append(str);
+ return *this;
+ }
+
+ void erase()
+ {
+ sink.clear();
+ binarySink.clear();
+ }
+ int size() { return static_cast<int>(isBinary() ? binarySink.size() : sink.size()); }
+
+ const TPersistString &str() const
+ {
+ ASSERT(!isBinary());
+ return sink;
+ }
+ const char *c_str() const
+ {
+ ASSERT(!isBinary());
+ return sink.c_str();
+ }
+
+ void prefix(Severity severity);
+ void location(int file, int line);
+
+ bool isBinary() const { return !binarySink.empty(); }
+ void setBinary(BinaryBlob &&binary) { binarySink = std::move(binary); }
+ const BinaryBlob &getBinary() const
+ {
+ ASSERT(isBinary());
+ return binarySink;
+ }
+
+ private:
+ // The data in the info sink is either in human readable form (|sink|) or binary (|binarySink|).
+ TPersistString sink;
+ BinaryBlob binarySink;
+};
+
+class TInfoSink
+{
+ public:
+ TInfoSinkBase info;
+ TInfoSinkBase debug;
+ TInfoSinkBase obj;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_INFOSINK_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/Initialize.cpp b/gfx/angle/checkout/src/compiler/translator/Initialize.cpp
new file mode 100644
index 0000000000..287765db8f
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/Initialize.cpp
@@ -0,0 +1,223 @@
+//
+// Copyright 2002 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/Initialize.h"
+
+namespace sh
+{
+
+void InitExtensionBehavior(const ShBuiltInResources &resources, TExtensionBehavior &extBehavior)
+{
+ if (resources.OES_standard_derivatives)
+ {
+ extBehavior[TExtension::OES_standard_derivatives] = EBhUndefined;
+ }
+ if (resources.OES_EGL_image_external)
+ {
+ extBehavior[TExtension::OES_EGL_image_external] = EBhUndefined;
+ }
+ if (resources.OES_EGL_image_external_essl3)
+ {
+ extBehavior[TExtension::OES_EGL_image_external_essl3] = EBhUndefined;
+ }
+ if (resources.NV_EGL_stream_consumer_external)
+ {
+ extBehavior[TExtension::NV_EGL_stream_consumer_external] = EBhUndefined;
+ }
+ if (resources.ARB_texture_rectangle)
+ {
+ // Special: ARB_texture_rectangle extension does not follow the standard for #extension
+ // directives - it is enabled by default. An extension directive may still disable it.
+ extBehavior[TExtension::ARB_texture_rectangle] = EBhEnable;
+ }
+ if (resources.EXT_blend_func_extended)
+ {
+ extBehavior[TExtension::EXT_blend_func_extended] = EBhUndefined;
+ }
+ if (resources.EXT_draw_buffers)
+ {
+ extBehavior[TExtension::EXT_draw_buffers] = EBhUndefined;
+ }
+ if (resources.EXT_frag_depth)
+ {
+ extBehavior[TExtension::EXT_frag_depth] = EBhUndefined;
+ }
+ if (resources.EXT_primitive_bounding_box)
+ {
+ extBehavior[TExtension::EXT_primitive_bounding_box] = EBhUndefined;
+ }
+ if (resources.OES_primitive_bounding_box)
+ {
+ extBehavior[TExtension::OES_primitive_bounding_box] = EBhUndefined;
+ }
+ if (resources.EXT_shader_texture_lod)
+ {
+ extBehavior[TExtension::EXT_shader_texture_lod] = EBhUndefined;
+ }
+ if (resources.EXT_shader_framebuffer_fetch)
+ {
+ extBehavior[TExtension::EXT_shader_framebuffer_fetch] = EBhUndefined;
+ }
+ if (resources.EXT_shader_framebuffer_fetch_non_coherent)
+ {
+ extBehavior[TExtension::EXT_shader_framebuffer_fetch_non_coherent] = EBhUndefined;
+ }
+ if (resources.NV_shader_framebuffer_fetch)
+ {
+ extBehavior[TExtension::NV_shader_framebuffer_fetch] = EBhUndefined;
+ }
+ if (resources.NV_shader_noperspective_interpolation)
+ {
+ extBehavior[TExtension::NV_shader_noperspective_interpolation] = EBhUndefined;
+ }
+ if (resources.ARM_shader_framebuffer_fetch)
+ {
+ extBehavior[TExtension::ARM_shader_framebuffer_fetch] = EBhUndefined;
+ }
+ if (resources.OVR_multiview)
+ {
+ extBehavior[TExtension::OVR_multiview] = EBhUndefined;
+ }
+ if (resources.OVR_multiview2)
+ {
+ extBehavior[TExtension::OVR_multiview2] = EBhUndefined;
+ }
+ if (resources.EXT_YUV_target)
+ {
+ extBehavior[TExtension::EXT_YUV_target] = EBhUndefined;
+ }
+ if (resources.EXT_geometry_shader)
+ {
+ extBehavior[TExtension::EXT_geometry_shader] = EBhUndefined;
+ }
+ if (resources.OES_geometry_shader)
+ {
+ extBehavior[TExtension::OES_geometry_shader] = EBhUndefined;
+ }
+ if (resources.OES_shader_io_blocks)
+ {
+ extBehavior[TExtension::OES_shader_io_blocks] = EBhUndefined;
+ }
+ if (resources.EXT_shader_io_blocks)
+ {
+ extBehavior[TExtension::EXT_shader_io_blocks] = EBhUndefined;
+ }
+ if (resources.EXT_gpu_shader5)
+ {
+ extBehavior[TExtension::EXT_gpu_shader5] = EBhUndefined;
+ }
+ if (resources.EXT_shader_non_constant_global_initializers)
+ {
+ extBehavior[TExtension::EXT_shader_non_constant_global_initializers] = EBhUndefined;
+ }
+ if (resources.OES_texture_storage_multisample_2d_array)
+ {
+ extBehavior[TExtension::OES_texture_storage_multisample_2d_array] = EBhUndefined;
+ }
+ if (resources.OES_texture_3D)
+ {
+ extBehavior[TExtension::OES_texture_3D] = EBhUndefined;
+ }
+ if (resources.ANGLE_shader_pixel_local_storage)
+ {
+ extBehavior[TExtension::ANGLE_shader_pixel_local_storage] = EBhUndefined;
+ }
+ if (resources.ANGLE_texture_multisample)
+ {
+ extBehavior[TExtension::ANGLE_texture_multisample] = EBhUndefined;
+ }
+ if (resources.ANGLE_multi_draw)
+ {
+ extBehavior[TExtension::ANGLE_multi_draw] = EBhUndefined;
+ }
+ if (resources.ANGLE_base_vertex_base_instance_shader_builtin)
+ {
+ extBehavior[TExtension::ANGLE_base_vertex_base_instance_shader_builtin] = EBhUndefined;
+ }
+ if (resources.WEBGL_video_texture)
+ {
+ extBehavior[TExtension::WEBGL_video_texture] = EBhUndefined;
+ }
+ if (resources.APPLE_clip_distance)
+ {
+ extBehavior[TExtension::APPLE_clip_distance] = EBhUndefined;
+ }
+ if (resources.OES_texture_cube_map_array)
+ {
+ extBehavior[TExtension::OES_texture_cube_map_array] = EBhUndefined;
+ }
+ if (resources.EXT_texture_cube_map_array)
+ {
+ extBehavior[TExtension::EXT_texture_cube_map_array] = EBhUndefined;
+ }
+ if (resources.EXT_shadow_samplers)
+ {
+ extBehavior[TExtension::EXT_shadow_samplers] = EBhUndefined;
+ }
+ if (resources.OES_shader_multisample_interpolation)
+ {
+ extBehavior[TExtension::OES_shader_multisample_interpolation] = EBhUndefined;
+ }
+ if (resources.OES_shader_image_atomic)
+ {
+ extBehavior[TExtension::OES_shader_image_atomic] = EBhUndefined;
+ }
+ if (resources.EXT_tessellation_shader)
+ {
+ extBehavior[TExtension::EXT_tessellation_shader] = EBhUndefined;
+ }
+ if (resources.OES_texture_buffer)
+ {
+ extBehavior[TExtension::OES_texture_buffer] = EBhUndefined;
+ }
+ if (resources.EXT_texture_buffer)
+ {
+ extBehavior[TExtension::EXT_texture_buffer] = EBhUndefined;
+ }
+ if (resources.OES_sample_variables)
+ {
+ extBehavior[TExtension::OES_sample_variables] = EBhUndefined;
+ }
+ if (resources.EXT_clip_cull_distance)
+ {
+ extBehavior[TExtension::EXT_clip_cull_distance] = EBhUndefined;
+ }
+ if (resources.ANDROID_extension_pack_es31a)
+ {
+ extBehavior[TExtension::ANDROID_extension_pack_es31a] = EBhUndefined;
+ }
+ if (resources.KHR_blend_equation_advanced)
+ {
+ extBehavior[TExtension::KHR_blend_equation_advanced] = EBhUndefined;
+ }
+}
+
+void ResetExtensionBehavior(const ShBuiltInResources &resources,
+ TExtensionBehavior &extBehavior,
+ const ShCompileOptions &compileOptions)
+{
+ for (auto &ext : extBehavior)
+ {
+ ext.second = EBhUndefined;
+ }
+ if (resources.ARB_texture_rectangle)
+ {
+ if (compileOptions.disableARBTextureRectangle)
+ {
+ // Remove ARB_texture_rectangle so it can't be enabled by extension directives.
+ extBehavior.erase(TExtension::ARB_texture_rectangle);
+ }
+ else
+ {
+ // Restore ARB_texture_rectangle in case it was removed during an earlier reset. As
+ // noted above, it doesn't follow the standard for extension directives and is
+ // enabled by default.
+ extBehavior[TExtension::ARB_texture_rectangle] = EBhEnable;
+ }
+ }
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/Initialize.h b/gfx/angle/checkout/src/compiler/translator/Initialize.h
new file mode 100644
index 0000000000..727e44e277
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/Initialize.h
@@ -0,0 +1,30 @@
+//
+// Copyright 2002 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_INITIALIZE_H_
+#define COMPILER_TRANSLATOR_INITIALIZE_H_
+
+#include "compiler/translator/Common.h"
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/SymbolTable.h"
+
+namespace sh
+{
+
+void InitExtensionBehavior(const ShBuiltInResources &resources,
+ TExtensionBehavior &extensionBehavior);
+
+// Resets the behavior of the extensions listed in |extensionBehavior| to the
+// undefined state. These extensions will only be those initially supported in
+// the ShBuiltInResources object for this compiler instance. All other
+// extensions will remain unsupported.
+void ResetExtensionBehavior(const ShBuiltInResources &resources,
+ TExtensionBehavior &extensionBehavior,
+ const ShCompileOptions &compileOptions);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_INITIALIZE_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/InitializeDll.cpp b/gfx/angle/checkout/src/compiler/translator/InitializeDll.cpp
new file mode 100644
index 0000000000..99a0fea19b
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/InitializeDll.cpp
@@ -0,0 +1,33 @@
+//
+// Copyright 2002 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/InitializeDll.h"
+#include "compiler/translator/InitializeGlobals.h"
+
+#include "common/platform.h"
+
+#include <assert.h>
+
+namespace sh
+{
+
+bool InitProcess()
+{
+ if (!InitializePoolIndex())
+ {
+ assert(0 && "InitProcess(): Failed to initalize global pool");
+ return false;
+ }
+
+ return true;
+}
+
+void DetachProcess()
+{
+ FreePoolIndex();
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/InitializeDll.h b/gfx/angle/checkout/src/compiler/translator/InitializeDll.h
new file mode 100644
index 0000000000..a75a13c2d9
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/InitializeDll.h
@@ -0,0 +1,15 @@
+//
+// Copyright 2002 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_INITIALIZEDLL_H_
+#define COMPILER_TRANSLATOR_INITIALIZEDLL_H_
+
+namespace sh
+{
+bool InitProcess();
+void DetachProcess();
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_INITIALIZEDLL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/InitializeGlobals.h b/gfx/angle/checkout/src/compiler/translator/InitializeGlobals.h
new file mode 100644
index 0000000000..cf431ef4f1
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/InitializeGlobals.h
@@ -0,0 +1,13 @@
+//
+// Copyright 2002 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_INITIALIZEGLOBALS_H_
+#define COMPILER_TRANSLATOR_INITIALIZEGLOBALS_H_
+
+bool InitializePoolIndex();
+void FreePoolIndex();
+
+#endif // COMPILER_TRANSLATOR_INITIALIZEGLOBALS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp b/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp
new file mode 100644
index 0000000000..a932b534be
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp
@@ -0,0 +1,4226 @@
+//
+// Copyright 2002 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.
+//
+
+//
+// Build the intermediate representation.
+//
+
+#include <float.h>
+#include <limits.h>
+#include <math.h>
+#include <stdlib.h>
+#include <algorithm>
+#include <vector>
+
+#include "common/mathutil.h"
+#include "common/matrix_utils.h"
+#include "common/utilities.h"
+#include "compiler/translator/Diagnostics.h"
+#include "compiler/translator/ImmutableString.h"
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+const float kPi = 3.14159265358979323846f;
+const float kDegreesToRadiansMultiplier = kPi / 180.0f;
+const float kRadiansToDegreesMultiplier = 180.0f / kPi;
+
+TPrecision GetHigherPrecision(TPrecision left, TPrecision right)
+{
+ return left > right ? left : right;
+}
+
+TConstantUnion *Vectorize(const TConstantUnion &constant, size_t size)
+{
+ TConstantUnion *constUnion = new TConstantUnion[size];
+ for (size_t i = 0; i < size; ++i)
+ constUnion[i] = constant;
+
+ return constUnion;
+}
+
+void UndefinedConstantFoldingError(const TSourceLoc &loc,
+ const TFunction *function,
+ TBasicType basicType,
+ TDiagnostics *diagnostics,
+ TConstantUnion *result)
+{
+ diagnostics->warning(loc, "operation result is undefined for the values passed in",
+ function->name().data());
+
+ switch (basicType)
+ {
+ case EbtFloat:
+ result->setFConst(0.0f);
+ break;
+ case EbtInt:
+ result->setIConst(0);
+ break;
+ case EbtUInt:
+ result->setUConst(0u);
+ break;
+ case EbtBool:
+ result->setBConst(false);
+ break;
+ default:
+ break;
+ }
+}
+
+float VectorLength(const TConstantUnion *paramArray, size_t paramArraySize)
+{
+ float result = 0.0f;
+ for (size_t i = 0; i < paramArraySize; i++)
+ {
+ float f = paramArray[i].getFConst();
+ result += f * f;
+ }
+ return sqrtf(result);
+}
+
+float VectorDotProduct(const TConstantUnion *paramArray1,
+ const TConstantUnion *paramArray2,
+ size_t paramArraySize)
+{
+ float result = 0.0f;
+ for (size_t i = 0; i < paramArraySize; i++)
+ result += paramArray1[i].getFConst() * paramArray2[i].getFConst();
+ return result;
+}
+
+TIntermTyped *CreateFoldedNode(const TConstantUnion *constArray, const TIntermTyped *originalNode)
+{
+ ASSERT(constArray != nullptr);
+ // Note that we inherit whatever qualifier the folded node had. Nodes may be constant folded
+ // without being qualified as constant.
+ TIntermTyped *folded = new TIntermConstantUnion(constArray, originalNode->getType());
+ folded->setLine(originalNode->getLine());
+ return folded;
+}
+
+angle::Matrix<float> GetMatrix(const TConstantUnion *paramArray,
+ const unsigned int rows,
+ const unsigned int cols)
+{
+ std::vector<float> elements;
+ 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. 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)
+{
+ std::vector<float> elements;
+ for (size_t i = 0; i < size * size; 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, size).transpose();
+}
+
+void SetUnionArrayFromMatrix(const angle::Matrix<float> &m, TConstantUnion *resultArray)
+{
+ // Transpose is used since the input Matrix is in row-major order,
+ // whereas the actual result should be in column-major order.
+ angle::Matrix<float> result = m.transpose();
+ std::vector<float> resultElements = result.elements();
+ for (size_t i = 0; i < resultElements.size(); i++)
+ resultArray[i].setFConst(resultElements[i]);
+}
+
+bool CanFoldAggregateBuiltInOp(TOperator op)
+{
+ switch (op)
+ {
+ case EOpAtan:
+ case EOpPow:
+ case EOpMod:
+ case EOpMin:
+ case EOpMax:
+ case EOpClamp:
+ case EOpMix:
+ case EOpStep:
+ case EOpSmoothstep:
+ case EOpFma:
+ case EOpLdexp:
+ case EOpMatrixCompMult:
+ case EOpOuterProduct:
+ case EOpEqualComponentWise:
+ case EOpNotEqualComponentWise:
+ case EOpLessThanComponentWise:
+ case EOpLessThanEqualComponentWise:
+ case EOpGreaterThanComponentWise:
+ case EOpGreaterThanEqualComponentWise:
+ case EOpDistance:
+ case EOpDot:
+ case EOpCross:
+ case EOpFaceforward:
+ case EOpReflect:
+ case EOpRefract:
+ case EOpBitfieldExtract:
+ case EOpBitfieldInsert:
+ case EOpDFdx:
+ case EOpDFdy:
+ case EOpFwidth:
+ return true;
+ default:
+ return false;
+ }
+}
+
+void PropagatePrecisionIfApplicable(TIntermTyped *node, TPrecision precision)
+{
+ if (precision == EbpUndefined || node->getPrecision() != EbpUndefined)
+ {
+ return;
+ }
+
+ if (IsPrecisionApplicableToType(node->getBasicType()))
+ {
+ node->propagatePrecision(precision);
+ }
+}
+
+} // namespace
+
+////////////////////////////////////////////////////////////////
+//
+// Member functions of the nodes used for building the tree.
+//
+////////////////////////////////////////////////////////////////
+
+TIntermExpression::TIntermExpression(const TType &t) : TIntermTyped(), mType(t) {}
+
+#define REPLACE_IF_IS(node, type, original, replacement) \
+ do \
+ { \
+ if (node == original) \
+ { \
+ node = static_cast<type *>(replacement); \
+ return true; \
+ } \
+ } while (0)
+
+size_t TIntermSymbol::getChildCount() const
+{
+ return 0;
+}
+
+TIntermNode *TIntermSymbol::getChildNode(size_t index) const
+{
+ UNREACHABLE();
+ return nullptr;
+}
+
+size_t TIntermConstantUnion::getChildCount() const
+{
+ return 0;
+}
+
+TIntermNode *TIntermConstantUnion::getChildNode(size_t index) const
+{
+ UNREACHABLE();
+ return nullptr;
+}
+
+size_t TIntermLoop::getChildCount() const
+{
+ return (mInit ? 1 : 0) + (mCond ? 1 : 0) + (mExpr ? 1 : 0) + (mBody ? 1 : 0);
+}
+
+TIntermNode *TIntermLoop::getChildNode(size_t index) const
+{
+ TIntermNode *children[4];
+ unsigned int childIndex = 0;
+ if (mInit)
+ {
+ children[childIndex] = mInit;
+ ++childIndex;
+ }
+ if (mCond)
+ {
+ children[childIndex] = mCond;
+ ++childIndex;
+ }
+ if (mExpr)
+ {
+ children[childIndex] = mExpr;
+ ++childIndex;
+ }
+ if (mBody)
+ {
+ children[childIndex] = mBody;
+ ++childIndex;
+ }
+ ASSERT(index < childIndex);
+ return children[index];
+}
+
+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);
+ REPLACE_IF_IS(mBody, TIntermBlock, original, replacement);
+ return false;
+}
+
+TIntermBranch::TIntermBranch(const TIntermBranch &node)
+ : TIntermBranch(node.mFlowOp, node.mExpression ? node.mExpression->deepCopy() : nullptr)
+{}
+
+size_t TIntermBranch::getChildCount() const
+{
+ return (mExpression ? 1 : 0);
+}
+
+TIntermNode *TIntermBranch::getChildNode(size_t index) const
+{
+ ASSERT(mExpression);
+ ASSERT(index == 0);
+ return mExpression;
+}
+
+bool TIntermBranch::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
+{
+ REPLACE_IF_IS(mExpression, TIntermTyped, original, replacement);
+ return false;
+}
+
+size_t TIntermSwizzle::getChildCount() const
+{
+ return 1;
+}
+
+TIntermNode *TIntermSwizzle::getChildNode(size_t index) const
+{
+ ASSERT(mOperand);
+ ASSERT(index == 0);
+ return mOperand;
+}
+
+bool TIntermSwizzle::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
+{
+ ASSERT(original->getAsTyped()->getType() == replacement->getAsTyped()->getType());
+ REPLACE_IF_IS(mOperand, TIntermTyped, original, replacement);
+ return false;
+}
+
+size_t TIntermBinary::getChildCount() const
+{
+ return 2;
+}
+
+TIntermNode *TIntermBinary::getChildNode(size_t index) const
+{
+ ASSERT(index < 2);
+ if (index == 0)
+ {
+ return mLeft;
+ }
+ return mRight;
+}
+
+bool TIntermBinary::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
+{
+ REPLACE_IF_IS(mLeft, TIntermTyped, original, replacement);
+ REPLACE_IF_IS(mRight, TIntermTyped, original, replacement);
+ return false;
+}
+
+size_t TIntermUnary::getChildCount() const
+{
+ return 1;
+}
+
+TIntermNode *TIntermUnary::getChildNode(size_t index) const
+{
+ ASSERT(mOperand);
+ ASSERT(index == 0);
+ return mOperand;
+}
+
+bool TIntermUnary::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
+{
+ ASSERT(original->getAsTyped()->getType() == replacement->getAsTyped()->getType());
+ REPLACE_IF_IS(mOperand, TIntermTyped, original, replacement);
+ return false;
+}
+
+size_t TIntermGlobalQualifierDeclaration::getChildCount() const
+{
+ return 1;
+}
+
+TIntermNode *TIntermGlobalQualifierDeclaration::getChildNode(size_t index) const
+{
+ ASSERT(mSymbol);
+ ASSERT(index == 0);
+ return mSymbol;
+}
+
+bool TIntermGlobalQualifierDeclaration::replaceChildNode(TIntermNode *original,
+ TIntermNode *replacement)
+{
+ REPLACE_IF_IS(mSymbol, TIntermSymbol, original, replacement);
+ return false;
+}
+
+size_t TIntermFunctionDefinition::getChildCount() const
+{
+ return 2;
+}
+
+TIntermNode *TIntermFunctionDefinition::getChildNode(size_t index) const
+{
+ ASSERT(index < 2);
+ if (index == 0)
+ {
+ return mPrototype;
+ }
+ return mBody;
+}
+
+bool TIntermFunctionDefinition::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
+{
+ REPLACE_IF_IS(mPrototype, TIntermFunctionPrototype, original, replacement);
+ REPLACE_IF_IS(mBody, TIntermBlock, original, replacement);
+ return false;
+}
+
+size_t TIntermAggregate::getChildCount() const
+{
+ return mArguments.size();
+}
+
+TIntermNode *TIntermAggregate::getChildNode(size_t index) const
+{
+ return mArguments[index];
+}
+
+bool TIntermAggregate::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
+{
+ return replaceChildNodeInternal(original, replacement);
+}
+
+TIntermBlock::TIntermBlock(const TIntermBlock &node)
+{
+ for (TIntermNode *intermNode : node.mStatements)
+ {
+ mStatements.push_back(intermNode->deepCopy());
+ }
+
+ ASSERT(!node.mIsTreeRoot);
+ mIsTreeRoot = false;
+}
+
+TIntermBlock::TIntermBlock(std::initializer_list<TIntermNode *> stmts)
+{
+ for (TIntermNode *stmt : stmts)
+ {
+ appendStatement(stmt);
+ }
+}
+
+size_t TIntermBlock::getChildCount() const
+{
+ return mStatements.size();
+}
+
+TIntermNode *TIntermBlock::getChildNode(size_t index) const
+{
+ return mStatements[index];
+}
+
+bool TIntermBlock::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
+{
+ return replaceChildNodeInternal(original, replacement);
+}
+
+void TIntermBlock::replaceAllChildren(const TIntermSequence &newStatements)
+{
+ mStatements.clear();
+ mStatements.insert(mStatements.begin(), newStatements.begin(), newStatements.end());
+}
+
+size_t TIntermFunctionPrototype::getChildCount() const
+{
+ return 0;
+}
+
+TIntermNode *TIntermFunctionPrototype::getChildNode(size_t index) const
+{
+ UNREACHABLE();
+ return nullptr;
+}
+
+bool TIntermFunctionPrototype::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
+{
+ return false;
+}
+
+TIntermDeclaration::TIntermDeclaration(const TVariable *var, TIntermTyped *initExpr)
+{
+ if (initExpr)
+ {
+ appendDeclarator(
+ new TIntermBinary(TOperator::EOpInitialize, new TIntermSymbol(var), initExpr));
+ }
+ else
+ {
+ appendDeclarator(new TIntermSymbol(var));
+ }
+}
+
+TIntermDeclaration::TIntermDeclaration(std::initializer_list<const TVariable *> declarators)
+ : TIntermDeclaration()
+{
+ for (const TVariable *d : declarators)
+ {
+ appendDeclarator(new TIntermSymbol(d));
+ }
+}
+
+TIntermDeclaration::TIntermDeclaration(std::initializer_list<TIntermTyped *> declarators)
+ : TIntermDeclaration()
+{
+ for (TIntermTyped *d : declarators)
+ {
+ appendDeclarator(d);
+ }
+}
+
+size_t TIntermDeclaration::getChildCount() const
+{
+ return mDeclarators.size();
+}
+
+TIntermNode *TIntermDeclaration::getChildNode(size_t index) const
+{
+ return mDeclarators[index];
+}
+
+bool TIntermDeclaration::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
+{
+ return replaceChildNodeInternal(original, replacement);
+}
+
+TIntermDeclaration::TIntermDeclaration(const TIntermDeclaration &node)
+{
+ for (TIntermNode *intermNode : node.mDeclarators)
+ {
+ mDeclarators.push_back(intermNode->deepCopy());
+ }
+}
+
+bool TIntermAggregateBase::replaceChildNodeInternal(TIntermNode *original, TIntermNode *replacement)
+{
+ for (size_t ii = 0; ii < getSequence()->size(); ++ii)
+ {
+ REPLACE_IF_IS((*getSequence())[ii], TIntermNode, original, replacement);
+ }
+ return false;
+}
+
+bool TIntermAggregateBase::replaceChildNodeWithMultiple(TIntermNode *original,
+ const TIntermSequence &replacements)
+{
+ for (auto it = getSequence()->begin(); it < getSequence()->end(); ++it)
+ {
+ if (*it == original)
+ {
+ it = getSequence()->erase(it);
+ getSequence()->insert(it, replacements.begin(), replacements.end());
+ return true;
+ }
+ }
+ return false;
+}
+
+bool TIntermAggregateBase::insertChildNodes(TIntermSequence::size_type position,
+ const TIntermSequence &insertions)
+{
+ if (position > getSequence()->size())
+ {
+ return false;
+ }
+ auto it = getSequence()->begin() + position;
+ getSequence()->insert(it, insertions.begin(), insertions.end());
+ return true;
+}
+
+TIntermSymbol::TIntermSymbol(const TVariable *variable) : TIntermTyped(), mVariable(variable) {}
+
+bool TIntermSymbol::hasConstantValue() const
+{
+ return variable().getConstPointer() != nullptr;
+}
+
+const TConstantUnion *TIntermSymbol::getConstantValue() const
+{
+ return variable().getConstPointer();
+}
+
+const TSymbolUniqueId &TIntermSymbol::uniqueId() const
+{
+ return mVariable->uniqueId();
+}
+
+ImmutableString TIntermSymbol::getName() const
+{
+ return mVariable->name();
+}
+
+const TType &TIntermSymbol::getType() const
+{
+ return mVariable->getType();
+}
+
+void TIntermSymbol::propagatePrecision(TPrecision precision)
+{
+ // Every declared variable should already have a precision. Some built-ins don't have a defined
+ // precision. This is not asserted however:
+ //
+ // - A shader with no precision specified either globally or on a variable will fail with a
+ // compilation error later on.
+ // - Transformations declaring variables without precision will be caught by AST validation.
+}
+
+TIntermAggregate *TIntermAggregate::CreateFunctionCall(const TFunction &func,
+ TIntermSequence *arguments)
+{
+ return new TIntermAggregate(&func, func.getReturnType(), EOpCallFunctionInAST, arguments);
+}
+
+TIntermAggregate *TIntermAggregate::CreateRawFunctionCall(const TFunction &func,
+ TIntermSequence *arguments)
+{
+ return new TIntermAggregate(&func, func.getReturnType(), EOpCallInternalRawFunction, arguments);
+}
+
+TIntermAggregate *TIntermAggregate::CreateBuiltInFunctionCall(const TFunction &func,
+ TIntermSequence *arguments)
+{
+ // Every built-in function should have an op.
+ ASSERT(func.getBuiltInOp() != EOpNull);
+ return new TIntermAggregate(&func, func.getReturnType(), func.getBuiltInOp(), arguments);
+}
+
+TIntermAggregate *TIntermAggregate::CreateConstructor(const TType &type, TIntermSequence *arguments)
+{
+ return new TIntermAggregate(nullptr, type, EOpConstruct, arguments);
+}
+
+TIntermAggregate *TIntermAggregate::CreateConstructor(
+ const TType &type,
+ const std::initializer_list<TIntermNode *> &arguments)
+{
+ TIntermSequence argSequence(arguments);
+ return CreateConstructor(type, &argSequence);
+}
+
+TIntermAggregate::TIntermAggregate(const TFunction *func,
+ const TType &type,
+ TOperator op,
+ TIntermSequence *arguments)
+ : TIntermOperator(op, type), mUseEmulatedFunction(false), mFunction(func)
+{
+ if (arguments != nullptr)
+ {
+ mArguments.swap(*arguments);
+ }
+ ASSERT(mFunction == nullptr || mFunction->symbolType() != SymbolType::Empty);
+ setPrecisionAndQualifier();
+}
+
+void TIntermAggregate::setPrecisionAndQualifier()
+{
+ mType.setQualifier(EvqTemporary);
+ if ((!BuiltInGroup::IsBuiltIn(mOp) && !isFunctionCall()) || BuiltInGroup::IsMath(mOp))
+ {
+ if (areChildrenConstQualified())
+ {
+ mType.setQualifier(EvqConst);
+ }
+ }
+
+ propagatePrecision(derivePrecision());
+}
+
+bool TIntermAggregate::areChildrenConstQualified()
+{
+ for (TIntermNode *arg : mArguments)
+ {
+ TIntermTyped *typedArg = arg->getAsTyped();
+ if (typedArg && typedArg->getQualifier() != EvqConst)
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+// Derive precision from children nodes
+TPrecision TIntermAggregate::derivePrecision() const
+{
+ if (getBasicType() == EbtBool || getBasicType() == EbtVoid || getBasicType() == EbtStruct)
+ {
+ return EbpUndefined;
+ }
+
+ // For AST function calls, take the qualifier from the declared one.
+ if (isFunctionCall())
+ {
+ return mType.getPrecision();
+ }
+
+ // Some built-ins explicitly specify their precision.
+ switch (mOp)
+ {
+ case EOpBitfieldExtract:
+ return mArguments[0]->getAsTyped()->getPrecision();
+ case EOpBitfieldInsert:
+ return GetHigherPrecision(mArguments[0]->getAsTyped()->getPrecision(),
+ mArguments[1]->getAsTyped()->getPrecision());
+ case EOpTextureSize:
+ case EOpImageSize:
+ case EOpUaddCarry:
+ case EOpUsubBorrow:
+ case EOpUmulExtended:
+ case EOpImulExtended:
+ case EOpFrexp:
+ case EOpLdexp:
+ return EbpHigh;
+ default:
+ break;
+ }
+
+ // The rest of the math operations and constructors get their precision from their arguments.
+ if (BuiltInGroup::IsMath(mOp) || mOp == EOpConstruct)
+ {
+ TPrecision precision = EbpUndefined;
+ for (TIntermNode *argument : mArguments)
+ {
+ precision = GetHigherPrecision(argument->getAsTyped()->getPrecision(), precision);
+ }
+ return precision;
+ }
+
+ // Atomic operations return highp.
+ if (BuiltInGroup::IsImageAtomic(mOp) || BuiltInGroup::IsAtomicCounter(mOp) ||
+ BuiltInGroup::IsAtomicMemory(mOp))
+ {
+ return EbpHigh;
+ }
+
+ // Texture functions return the same precision as that of the sampler (textureSize returns
+ // highp, but that's handled above). imageLoad similar takes the precision of the image. The
+ // same is true for dFd*, interpolateAt* and subpassLoad operations.
+ if (BuiltInGroup::IsTexture(mOp) || BuiltInGroup::IsImageLoad(mOp) ||
+ BuiltInGroup::IsDerivativesFS(mOp) || BuiltInGroup::IsInterpolationFS(mOp) ||
+ mOp == EOpSubpassLoad)
+ {
+ return mArguments[0]->getAsTyped()->getPrecision();
+ }
+
+ // Every possibility must be explicitly handled, except for desktop-GLSL-specific built-ins
+ // for which precision does't matter.
+ return EbpUndefined;
+}
+
+// Propagate precision to children nodes that don't already have it defined.
+void TIntermAggregate::propagatePrecision(TPrecision precision)
+{
+ mType.setPrecision(precision);
+
+ // For constructors, propagate precision to arguments.
+ if (isConstructor())
+ {
+ for (TIntermNode *arg : mArguments)
+ {
+ PropagatePrecisionIfApplicable(arg->getAsTyped(), precision);
+ }
+ return;
+ }
+
+ // For function calls, propagate precision of each parameter to its corresponding argument.
+ if (isFunctionCall())
+ {
+ for (size_t paramIndex = 0; paramIndex < mFunction->getParamCount(); ++paramIndex)
+ {
+ const TVariable *paramVariable = mFunction->getParam(paramIndex);
+ PropagatePrecisionIfApplicable(mArguments[paramIndex]->getAsTyped(),
+ paramVariable->getType().getPrecision());
+ }
+ return;
+ }
+
+ // Some built-ins explicitly specify the precision of their parameters.
+ switch (mOp)
+ {
+ case EOpUaddCarry:
+ case EOpUsubBorrow:
+ case EOpUmulExtended:
+ case EOpImulExtended:
+ PropagatePrecisionIfApplicable(mArguments[0]->getAsTyped(), EbpHigh);
+ PropagatePrecisionIfApplicable(mArguments[1]->getAsTyped(), EbpHigh);
+ break;
+ case EOpFindMSB:
+ case EOpFrexp:
+ case EOpLdexp:
+ PropagatePrecisionIfApplicable(mArguments[0]->getAsTyped(), EbpHigh);
+ break;
+ default:
+ break;
+ }
+}
+
+const char *TIntermAggregate::functionName() const
+{
+ ASSERT(!isConstructor());
+ switch (mOp)
+ {
+ case EOpCallInternalRawFunction:
+ case EOpCallFunctionInAST:
+ return mFunction->name().data();
+ default:
+ if (BuiltInGroup::IsBuiltIn(mOp))
+ {
+ return mFunction->name().data();
+ }
+ return GetOperatorString(mOp);
+ }
+}
+
+bool TIntermAggregate::hasConstantValue() const
+{
+ if (!isConstructor())
+ {
+ return false;
+ }
+ for (TIntermNode *constructorArg : mArguments)
+ {
+ if (!constructorArg->getAsTyped()->hasConstantValue())
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool TIntermAggregate::isConstantNullValue() const
+{
+ if (!isConstructor())
+ {
+ return false;
+ }
+ for (TIntermNode *constructorArg : mArguments)
+ {
+ if (!constructorArg->getAsTyped()->isConstantNullValue())
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+const TConstantUnion *TIntermAggregate::getConstantValue() const
+{
+ if (!hasConstantValue())
+ {
+ return nullptr;
+ }
+ ASSERT(isConstructor());
+ ASSERT(mArguments.size() > 0u);
+
+ TConstantUnion *constArray = nullptr;
+ if (isArray())
+ {
+ size_t elementSize = mArguments.front()->getAsTyped()->getType().getObjectSize();
+ constArray = new TConstantUnion[elementSize * getOutermostArraySize()];
+
+ size_t elementOffset = 0u;
+ for (TIntermNode *constructorArg : mArguments)
+ {
+ const TConstantUnion *elementConstArray =
+ constructorArg->getAsTyped()->getConstantValue();
+ ASSERT(elementConstArray);
+ size_t elementSizeBytes = sizeof(TConstantUnion) * elementSize;
+ memcpy(static_cast<void *>(&constArray[elementOffset]),
+ static_cast<const void *>(elementConstArray), elementSizeBytes);
+ elementOffset += elementSize;
+ }
+ return constArray;
+ }
+
+ size_t resultSize = getType().getObjectSize();
+ constArray = new TConstantUnion[resultSize];
+ TBasicType basicType = getBasicType();
+
+ size_t resultIndex = 0u;
+
+ if (mArguments.size() == 1u)
+ {
+ TIntermNode *argument = mArguments.front();
+ TIntermTyped *argumentTyped = argument->getAsTyped();
+ const TConstantUnion *argumentConstantValue = argumentTyped->getConstantValue();
+ // Check the special case of constructing a matrix diagonal from a single scalar,
+ // or a vector from a single scalar.
+ if (argumentTyped->getType().getObjectSize() == 1u)
+ {
+ if (isMatrix())
+ {
+ const uint8_t resultCols = getType().getCols();
+ const uint8_t resultRows = getType().getRows();
+ for (uint8_t col = 0; col < resultCols; ++col)
+ {
+ for (uint8_t row = 0; row < resultRows; ++row)
+ {
+ if (col == row)
+ {
+ constArray[resultIndex].cast(basicType, argumentConstantValue[0]);
+ }
+ else
+ {
+ constArray[resultIndex].setFConst(0.0f);
+ }
+ ++resultIndex;
+ }
+ }
+ }
+ else
+ {
+ while (resultIndex < resultSize)
+ {
+ constArray[resultIndex].cast(basicType, argumentConstantValue[0]);
+ ++resultIndex;
+ }
+ }
+ ASSERT(resultIndex == resultSize);
+ return constArray;
+ }
+ else if (isMatrix() && argumentTyped->isMatrix())
+ {
+ // The special case of constructing a matrix from a matrix.
+ const uint8_t argumentCols = argumentTyped->getType().getCols();
+ const uint8_t argumentRows = argumentTyped->getType().getRows();
+ const uint8_t resultCols = getType().getCols();
+ const uint8_t resultRows = getType().getRows();
+ for (uint8_t col = 0; col < resultCols; ++col)
+ {
+ for (uint8_t row = 0; row < resultRows; ++row)
+ {
+ if (col < argumentCols && row < argumentRows)
+ {
+ constArray[resultIndex].cast(
+ basicType, argumentConstantValue[col * argumentRows + row]);
+ }
+ else if (col == row)
+ {
+ constArray[resultIndex].setFConst(1.0f);
+ }
+ else
+ {
+ constArray[resultIndex].setFConst(0.0f);
+ }
+ ++resultIndex;
+ }
+ }
+ ASSERT(resultIndex == resultSize);
+ return constArray;
+ }
+ }
+
+ for (TIntermNode *argument : mArguments)
+ {
+ TIntermTyped *argumentTyped = argument->getAsTyped();
+ size_t argumentSize = argumentTyped->getType().getObjectSize();
+ const TConstantUnion *argumentConstantValue = argumentTyped->getConstantValue();
+ for (size_t i = 0u; i < argumentSize; ++i)
+ {
+ if (resultIndex >= resultSize)
+ break;
+ constArray[resultIndex].cast(basicType, argumentConstantValue[i]);
+ ++resultIndex;
+ }
+ }
+ ASSERT(resultIndex == resultSize);
+ return constArray;
+}
+
+bool TIntermAggregate::hasSideEffects() const
+{
+ if (getQualifier() == EvqConst)
+ {
+ return false;
+ }
+
+ // If the function itself is known to have a side effect, the expression has a side effect.
+ const bool calledFunctionHasSideEffects =
+ mFunction != nullptr && !mFunction->isKnownToNotHaveSideEffects();
+
+ if (calledFunctionHasSideEffects)
+ {
+ return true;
+ }
+
+ // Otherwise it only has a side effect if one of the arguments does.
+ for (TIntermNode *arg : mArguments)
+ {
+ if (arg->getAsTyped()->hasSideEffects())
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+void TIntermBlock::appendStatement(TIntermNode *statement)
+{
+ // Declaration nodes with no children can appear if it was an empty declaration or if all the
+ // declarators just added constants to the symbol table instead of generating code. We still
+ // need to add the declaration to the AST in that case because it might be relevant to the
+ // validity of switch/case.
+ if (statement != nullptr)
+ {
+ mStatements.push_back(statement);
+ }
+}
+
+void TIntermBlock::insertStatement(size_t insertPosition, TIntermNode *statement)
+{
+ ASSERT(statement != nullptr);
+ mStatements.insert(mStatements.begin() + insertPosition, statement);
+}
+
+void TIntermDeclaration::appendDeclarator(TIntermTyped *declarator)
+{
+ ASSERT(declarator != nullptr);
+ ASSERT(declarator->getAsSymbolNode() != nullptr ||
+ (declarator->getAsBinaryNode() != nullptr &&
+ declarator->getAsBinaryNode()->getOp() == EOpInitialize));
+ ASSERT(mDeclarators.empty() ||
+ declarator->getType().sameNonArrayType(mDeclarators.back()->getAsTyped()->getType()));
+ mDeclarators.push_back(declarator);
+}
+
+size_t TIntermTernary::getChildCount() const
+{
+ return 3;
+}
+
+TIntermNode *TIntermTernary::getChildNode(size_t index) const
+{
+ ASSERT(index < 3);
+ if (index == 0)
+ {
+ return mCondition;
+ }
+ if (index == 1)
+ {
+ return mTrueExpression;
+ }
+ return mFalseExpression;
+}
+
+bool TIntermTernary::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
+{
+ REPLACE_IF_IS(mCondition, TIntermTyped, original, replacement);
+ REPLACE_IF_IS(mTrueExpression, TIntermTyped, original, replacement);
+ REPLACE_IF_IS(mFalseExpression, TIntermTyped, original, replacement);
+ return false;
+}
+
+size_t TIntermIfElse::getChildCount() const
+{
+ return 1 + (mTrueBlock ? 1 : 0) + (mFalseBlock ? 1 : 0);
+}
+
+TIntermNode *TIntermIfElse::getChildNode(size_t index) const
+{
+ if (index == 0)
+ {
+ return mCondition;
+ }
+ if (mTrueBlock && index == 1)
+ {
+ return mTrueBlock;
+ }
+ return mFalseBlock;
+}
+
+bool TIntermIfElse::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
+{
+ REPLACE_IF_IS(mCondition, TIntermTyped, original, replacement);
+ REPLACE_IF_IS(mTrueBlock, TIntermBlock, original, replacement);
+ REPLACE_IF_IS(mFalseBlock, TIntermBlock, original, replacement);
+ return false;
+}
+
+size_t TIntermSwitch::getChildCount() const
+{
+ return 2;
+}
+
+TIntermNode *TIntermSwitch::getChildNode(size_t index) const
+{
+ ASSERT(index < 2);
+ if (index == 0)
+ {
+ return mInit;
+ }
+ return mStatementList;
+}
+
+bool TIntermSwitch::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
+{
+ REPLACE_IF_IS(mInit, TIntermTyped, original, replacement);
+ REPLACE_IF_IS(mStatementList, TIntermBlock, original, replacement);
+ ASSERT(mStatementList);
+ return false;
+}
+
+TIntermCase::TIntermCase(const TIntermCase &node) : TIntermCase(node.mCondition->deepCopy()) {}
+
+size_t TIntermCase::getChildCount() const
+{
+ return (mCondition ? 1 : 0);
+}
+
+TIntermNode *TIntermCase::getChildNode(size_t index) const
+{
+ ASSERT(index == 0);
+ ASSERT(mCondition);
+ return mCondition;
+}
+
+bool TIntermCase::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
+{
+ REPLACE_IF_IS(mCondition, TIntermTyped, original, replacement);
+ return false;
+}
+
+TIntermTyped::TIntermTyped() : mIsPrecise(false) {}
+TIntermTyped::TIntermTyped(const TIntermTyped &node) : TIntermTyped()
+{
+ // Copy constructor is disallowed for TIntermNode in order to disallow it for subclasses that
+ // don't explicitly allow it, so normal TIntermNode constructor is used to construct the copy.
+ // We need to manually copy any fields of TIntermNode.
+ mLine = node.mLine;
+
+ // Once deteremined, the tree is not expected to transform.
+ ASSERT(!mIsPrecise);
+}
+
+bool TIntermTyped::hasConstantValue() const
+{
+ return false;
+}
+
+bool TIntermTyped::isConstantNullValue() const
+{
+ return false;
+}
+
+const TConstantUnion *TIntermTyped::getConstantValue() const
+{
+ return nullptr;
+}
+
+TPrecision TIntermTyped::derivePrecision() const
+{
+ UNREACHABLE();
+ return EbpUndefined;
+}
+
+void TIntermTyped::propagatePrecision(TPrecision precision)
+{
+ UNREACHABLE();
+}
+
+TIntermConstantUnion::TIntermConstantUnion(const TIntermConstantUnion &node)
+ : TIntermExpression(node)
+{
+ mUnionArrayPointer = node.mUnionArrayPointer;
+}
+
+TIntermFunctionPrototype::TIntermFunctionPrototype(const TFunction *function)
+ : TIntermTyped(), mFunction(function)
+{
+ ASSERT(mFunction->symbolType() != SymbolType::Empty);
+}
+
+const TType &TIntermFunctionPrototype::getType() const
+{
+ return mFunction->getReturnType();
+}
+
+TIntermAggregate::TIntermAggregate(const TIntermAggregate &node)
+ : TIntermOperator(node),
+ mUseEmulatedFunction(node.mUseEmulatedFunction),
+ mFunction(node.mFunction)
+{
+ for (TIntermNode *arg : node.mArguments)
+ {
+ TIntermTyped *typedArg = arg->getAsTyped();
+ ASSERT(typedArg != nullptr);
+ TIntermTyped *argCopy = typedArg->deepCopy();
+ mArguments.push_back(argCopy);
+ }
+}
+
+TIntermAggregate *TIntermAggregate::shallowCopy() const
+{
+ TIntermSequence copySeq;
+ copySeq.insert(copySeq.begin(), getSequence()->begin(), getSequence()->end());
+ TIntermAggregate *copyNode = new TIntermAggregate(mFunction, mType, mOp, &copySeq);
+ copyNode->setLine(mLine);
+ return copyNode;
+}
+
+TIntermSwizzle::TIntermSwizzle(const TIntermSwizzle &node) : TIntermExpression(node)
+{
+ TIntermTyped *operandCopy = node.mOperand->deepCopy();
+ ASSERT(operandCopy != nullptr);
+ mOperand = operandCopy;
+ mSwizzleOffsets = node.mSwizzleOffsets;
+ mHasFoldedDuplicateOffsets = node.mHasFoldedDuplicateOffsets;
+}
+
+TIntermBinary::TIntermBinary(const TIntermBinary &node) : TIntermOperator(node)
+{
+ TIntermTyped *leftCopy = node.mLeft->deepCopy();
+ TIntermTyped *rightCopy = node.mRight->deepCopy();
+ ASSERT(leftCopy != nullptr && rightCopy != nullptr);
+ mLeft = leftCopy;
+ mRight = rightCopy;
+}
+
+TIntermUnary::TIntermUnary(const TIntermUnary &node)
+ : TIntermOperator(node),
+ mUseEmulatedFunction(node.mUseEmulatedFunction),
+ mFunction(node.mFunction)
+{
+ TIntermTyped *operandCopy = node.mOperand->deepCopy();
+ ASSERT(operandCopy != nullptr);
+ mOperand = operandCopy;
+}
+
+TIntermTernary::TIntermTernary(const TIntermTernary &node) : TIntermExpression(node)
+{
+ TIntermTyped *conditionCopy = node.mCondition->deepCopy();
+ TIntermTyped *trueCopy = node.mTrueExpression->deepCopy();
+ TIntermTyped *falseCopy = node.mFalseExpression->deepCopy();
+ ASSERT(conditionCopy != nullptr && trueCopy != nullptr && falseCopy != nullptr);
+ mCondition = conditionCopy;
+ mTrueExpression = trueCopy;
+ mFalseExpression = falseCopy;
+}
+
+bool TIntermOperator::isAssignment() const
+{
+ return IsAssignment(mOp);
+}
+
+bool TIntermOperator::isMultiplication() const
+{
+ switch (mOp)
+ {
+ case EOpMul:
+ case EOpMatrixTimesMatrix:
+ case EOpMatrixTimesVector:
+ case EOpMatrixTimesScalar:
+ case EOpVectorTimesMatrix:
+ case EOpVectorTimesScalar:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool TIntermOperator::isConstructor() const
+{
+ return (mOp == EOpConstruct);
+}
+
+bool TIntermOperator::isFunctionCall() const
+{
+ switch (mOp)
+ {
+ case EOpCallFunctionInAST:
+ case EOpCallInternalRawFunction:
+ return true;
+ default:
+ return false;
+ }
+}
+
+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()
+{
+ if (mOp == EOpArrayLength)
+ {
+ // Special case: the qualifier of .length() doesn't depend on the operand qualifier.
+ setType(TType(EbtInt, EbpHigh, EvqConst));
+ return;
+ }
+
+ TQualifier resultQualifier = EvqTemporary;
+ if (mOperand->getQualifier() == EvqConst)
+ resultQualifier = EvqConst;
+
+ TType resultType = mOperand->getType();
+ resultType.setQualifier(resultQualifier);
+
+ // Result is an intermediate value, so make sure it's identified as such.
+ resultType.setInterfaceBlock(nullptr);
+
+ // Override type properties for special built-ins. Precision is determined later by
+ // |derivePrecision|.
+ switch (mOp)
+ {
+ case EOpFloatBitsToInt:
+ resultType.setBasicType(EbtInt);
+ break;
+ case EOpFloatBitsToUint:
+ resultType.setBasicType(EbtUInt);
+ break;
+ case EOpIntBitsToFloat:
+ case EOpUintBitsToFloat:
+ resultType.setBasicType(EbtFloat);
+ break;
+ case EOpPackSnorm2x16:
+ case EOpPackUnorm2x16:
+ case EOpPackHalf2x16:
+ case EOpPackUnorm4x8:
+ case EOpPackSnorm4x8:
+ resultType.setBasicType(EbtUInt);
+ resultType.setPrimarySize(1);
+ break;
+ case EOpUnpackSnorm2x16:
+ case EOpUnpackUnorm2x16:
+ case EOpUnpackHalf2x16:
+ resultType.setBasicType(EbtFloat);
+ resultType.setPrimarySize(2);
+ break;
+ case EOpUnpackUnorm4x8:
+ case EOpUnpackSnorm4x8:
+ resultType.setBasicType(EbtFloat);
+ resultType.setPrimarySize(4);
+ break;
+ case EOpAny:
+ case EOpAll:
+ resultType.setBasicType(EbtBool);
+ resultType.setPrimarySize(1);
+ break;
+ case EOpLength:
+ case EOpDeterminant:
+ resultType.setBasicType(EbtFloat);
+ resultType.setPrimarySize(1);
+ resultType.setSecondarySize(1);
+ break;
+ case EOpTranspose:
+ ASSERT(resultType.getBasicType() == EbtFloat);
+ resultType.setPrimarySize(mOperand->getType().getRows());
+ resultType.setSecondarySize(mOperand->getType().getCols());
+ break;
+ case EOpIsinf:
+ case EOpIsnan:
+ resultType.setBasicType(EbtBool);
+ break;
+ case EOpBitCount:
+ case EOpFindLSB:
+ case EOpFindMSB:
+ resultType.setBasicType(EbtInt);
+ break;
+ default:
+ break;
+ }
+
+ setType(resultType);
+ propagatePrecision(derivePrecision());
+}
+
+// Derive precision from children nodes
+TPrecision TIntermUnary::derivePrecision() const
+{
+ // Unary operators generally derive their precision from their operand, except for a few
+ // built-ins where this is overriden.
+ switch (mOp)
+ {
+ case EOpArrayLength:
+ case EOpFloatBitsToInt:
+ case EOpFloatBitsToUint:
+ case EOpIntBitsToFloat:
+ case EOpUintBitsToFloat:
+ case EOpPackSnorm2x16:
+ case EOpPackUnorm2x16:
+ case EOpPackHalf2x16:
+ case EOpPackUnorm4x8:
+ case EOpPackSnorm4x8:
+ case EOpUnpackSnorm2x16:
+ case EOpUnpackUnorm2x16:
+ case EOpBitfieldReverse:
+ return EbpHigh;
+ case EOpUnpackHalf2x16:
+ case EOpUnpackUnorm4x8:
+ case EOpUnpackSnorm4x8:
+ return EbpMedium;
+ case EOpBitCount:
+ case EOpFindLSB:
+ case EOpFindMSB:
+ return EbpLow;
+ case EOpAny:
+ case EOpAll:
+ case EOpIsinf:
+ case EOpIsnan:
+ return EbpUndefined;
+ default:
+ return mOperand->getPrecision();
+ }
+}
+
+void TIntermUnary::propagatePrecision(TPrecision precision)
+{
+ mType.setPrecision(precision);
+
+ // Generally precision of the operand and the precision of the result match. A few built-ins
+ // are exceptional.
+ switch (mOp)
+ {
+ case EOpArrayLength:
+ case EOpPackSnorm2x16:
+ case EOpPackUnorm2x16:
+ case EOpPackUnorm4x8:
+ case EOpPackSnorm4x8:
+ case EOpPackHalf2x16:
+ case EOpBitCount:
+ case EOpFindLSB:
+ case EOpFindMSB:
+ case EOpIsinf:
+ case EOpIsnan:
+ // Precision of result does not affect the operand in any way.
+ break;
+ case EOpFloatBitsToInt:
+ case EOpFloatBitsToUint:
+ case EOpIntBitsToFloat:
+ case EOpUintBitsToFloat:
+ case EOpUnpackSnorm2x16:
+ case EOpUnpackUnorm2x16:
+ case EOpUnpackUnorm4x8:
+ case EOpUnpackSnorm4x8:
+ case EOpUnpackHalf2x16:
+ case EOpBitfieldReverse:
+ PropagatePrecisionIfApplicable(mOperand, EbpHigh);
+ break;
+ default:
+ PropagatePrecisionIfApplicable(mOperand, precision);
+ }
+}
+
+TIntermSwizzle::TIntermSwizzle(TIntermTyped *operand, const TVector<int> &swizzleOffsets)
+ : TIntermExpression(TType(EbtFloat, EbpUndefined)),
+ mOperand(operand),
+ mSwizzleOffsets(swizzleOffsets),
+ mHasFoldedDuplicateOffsets(false)
+{
+ ASSERT(mOperand);
+ ASSERT(mOperand->getType().isVector());
+ ASSERT(mSwizzleOffsets.size() <= 4);
+ promote();
+}
+
+TIntermUnary::TIntermUnary(TOperator op, TIntermTyped *operand, const TFunction *function)
+ : TIntermOperator(op), mOperand(operand), mUseEmulatedFunction(false), mFunction(function)
+{
+ ASSERT(mOperand);
+ ASSERT(!BuiltInGroup::IsBuiltIn(op) || (function != nullptr && function->getBuiltInOp() == op));
+ promote();
+}
+
+TIntermBinary::TIntermBinary(TOperator op, TIntermTyped *left, TIntermTyped *right)
+ : TIntermOperator(op), mLeft(left), mRight(right)
+{
+ ASSERT(mLeft);
+ ASSERT(mRight);
+ promote();
+}
+
+TIntermBinary *TIntermBinary::CreateComma(TIntermTyped *left,
+ TIntermTyped *right,
+ int shaderVersion)
+{
+ TIntermBinary *node = new TIntermBinary(EOpComma, left, right);
+ node->getTypePointer()->setQualifier(GetCommaQualifier(shaderVersion, left, right));
+ return node;
+}
+
+TIntermGlobalQualifierDeclaration::TIntermGlobalQualifierDeclaration(TIntermSymbol *symbol,
+ bool isPrecise,
+ const TSourceLoc &line)
+ : TIntermNode(), mSymbol(symbol), mIsPrecise(isPrecise)
+{
+ ASSERT(symbol);
+ setLine(line);
+}
+
+TIntermGlobalQualifierDeclaration::TIntermGlobalQualifierDeclaration(
+ const TIntermGlobalQualifierDeclaration &node)
+ : TIntermGlobalQualifierDeclaration(static_cast<TIntermSymbol *>(node.mSymbol->deepCopy()),
+ node.mIsPrecise,
+ node.mLine)
+{}
+
+TIntermTernary::TIntermTernary(TIntermTyped *cond,
+ TIntermTyped *trueExpression,
+ TIntermTyped *falseExpression)
+ : TIntermExpression(trueExpression->getType()),
+ mCondition(cond),
+ mTrueExpression(trueExpression),
+ mFalseExpression(falseExpression)
+{
+ ASSERT(mCondition);
+ ASSERT(mTrueExpression);
+ ASSERT(mFalseExpression);
+ getTypePointer()->setQualifier(
+ TIntermTernary::DetermineQualifier(cond, trueExpression, falseExpression));
+
+ propagatePrecision(derivePrecision());
+}
+
+TIntermLoop::TIntermLoop(TLoopType type,
+ TIntermNode *init,
+ TIntermTyped *cond,
+ TIntermTyped *expr,
+ TIntermBlock *body)
+ : mType(type), mInit(init), mCond(cond), mExpr(expr), mBody(body)
+{
+ // Declaration nodes with no children can appear if all the declarators just added constants to
+ // the symbol table instead of generating code. They're no-ops so don't add them to the tree.
+ if (mInit && mInit->getAsDeclarationNode() &&
+ mInit->getAsDeclarationNode()->getSequence()->empty())
+ {
+ mInit = nullptr;
+ }
+}
+
+TIntermLoop::TIntermLoop(const TIntermLoop &node)
+ : TIntermLoop(node.mType,
+ node.mInit ? node.mInit->deepCopy() : nullptr,
+ node.mCond ? node.mCond->deepCopy() : nullptr,
+ node.mExpr ? node.mExpr->deepCopy() : nullptr,
+ node.mBody ? node.mBody->deepCopy() : nullptr)
+{}
+
+TIntermIfElse::TIntermIfElse(TIntermTyped *cond, TIntermBlock *trueB, TIntermBlock *falseB)
+ : TIntermNode(), mCondition(cond), mTrueBlock(trueB), mFalseBlock(falseB)
+{
+ ASSERT(mCondition);
+ // Prune empty false blocks so that there won't be unnecessary operations done on it.
+ if (mFalseBlock && mFalseBlock->getSequence()->empty())
+ {
+ mFalseBlock = nullptr;
+ }
+}
+
+TIntermIfElse::TIntermIfElse(const TIntermIfElse &node)
+ : TIntermIfElse(node.mCondition->deepCopy(),
+ node.mTrueBlock->deepCopy(),
+ node.mFalseBlock ? node.mFalseBlock->deepCopy() : nullptr)
+{}
+
+TIntermSwitch::TIntermSwitch(TIntermTyped *init, TIntermBlock *statementList)
+ : TIntermNode(), mInit(init), mStatementList(statementList)
+{
+ ASSERT(mInit);
+ ASSERT(mStatementList);
+}
+
+TIntermSwitch::TIntermSwitch(const TIntermSwitch &node)
+ : TIntermSwitch(node.mInit->deepCopy(), node.mStatementList->deepCopy())
+{}
+
+void TIntermSwitch::setStatementList(TIntermBlock *statementList)
+{
+ ASSERT(statementList);
+ mStatementList = statementList;
+}
+
+// static
+TQualifier TIntermTernary::DetermineQualifier(TIntermTyped *cond,
+ TIntermTyped *trueExpression,
+ TIntermTyped *falseExpression)
+{
+ if (cond->getQualifier() == EvqConst && trueExpression->getQualifier() == EvqConst &&
+ falseExpression->getQualifier() == EvqConst)
+ {
+ return EvqConst;
+ }
+ return EvqTemporary;
+}
+
+// Derive precision from children nodes
+TPrecision TIntermTernary::derivePrecision() const
+{
+ return GetHigherPrecision(mTrueExpression->getPrecision(), mFalseExpression->getPrecision());
+}
+
+void TIntermTernary::propagatePrecision(TPrecision precision)
+{
+ mType.setPrecision(precision);
+
+ PropagatePrecisionIfApplicable(mTrueExpression, precision);
+ PropagatePrecisionIfApplicable(mFalseExpression, precision);
+}
+
+TIntermTyped *TIntermTernary::fold(TDiagnostics * /* diagnostics */)
+{
+ if (mCondition->getAsConstantUnion())
+ {
+ if (mCondition->getAsConstantUnion()->getBConst(0))
+ {
+ return mTrueExpression;
+ }
+ else
+ {
+ return mFalseExpression;
+ }
+ }
+ return this;
+}
+
+void TIntermSwizzle::promote()
+{
+ TQualifier resultQualifier = EvqTemporary;
+ if (mOperand->getQualifier() == EvqConst)
+ resultQualifier = EvqConst;
+
+ size_t numFields = mSwizzleOffsets.size();
+ setType(TType(mOperand->getBasicType(), EbpUndefined, resultQualifier,
+ static_cast<uint8_t>(numFields)));
+ propagatePrecision(derivePrecision());
+}
+
+// Derive precision from children nodes
+TPrecision TIntermSwizzle::derivePrecision() const
+{
+ return mOperand->getPrecision();
+}
+
+void TIntermSwizzle::propagatePrecision(TPrecision precision)
+{
+ mType.setPrecision(precision);
+
+ PropagatePrecisionIfApplicable(mOperand, precision);
+}
+
+bool TIntermSwizzle::hasDuplicateOffsets() const
+{
+ if (mHasFoldedDuplicateOffsets)
+ {
+ return true;
+ }
+ int offsetCount[4] = {0u, 0u, 0u, 0u};
+ for (const auto offset : mSwizzleOffsets)
+ {
+ offsetCount[offset]++;
+ if (offsetCount[offset] > 1)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+void TIntermSwizzle::setHasFoldedDuplicateOffsets(bool hasFoldedDuplicateOffsets)
+{
+ mHasFoldedDuplicateOffsets = hasFoldedDuplicateOffsets;
+}
+
+bool TIntermSwizzle::offsetsMatch(int offset) const
+{
+ return mSwizzleOffsets.size() == 1 && mSwizzleOffsets[0] == offset;
+}
+
+void TIntermSwizzle::writeOffsetsAsXYZW(TInfoSinkBase *out) const
+{
+ for (const int offset : mSwizzleOffsets)
+ {
+ switch (offset)
+ {
+ case 0:
+ *out << "x";
+ break;
+ case 1:
+ *out << "y";
+ break;
+ case 2:
+ *out << "z";
+ break;
+ case 3:
+ *out << "w";
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+}
+
+TQualifier TIntermBinary::GetCommaQualifier(int shaderVersion,
+ const TIntermTyped *left,
+ const TIntermTyped *right)
+{
+ // ESSL3.00 section 12.43: The result of a sequence operator is not a constant-expression.
+ if (shaderVersion >= 300 || left->getQualifier() != EvqConst ||
+ right->getQualifier() != EvqConst)
+ {
+ return EvqTemporary;
+ }
+ return EvqConst;
+}
+
+// Establishes the type of the result of the binary operation.
+void TIntermBinary::promote()
+{
+ ASSERT(!isMultiplication() ||
+ mOp == GetMulOpBasedOnOperands(mLeft->getType(), mRight->getType()));
+
+ // Comma is handled as a special case. Note that the comma node qualifier depends on the shader
+ // version and so is not being set here.
+ if (mOp == EOpComma)
+ {
+ setType(mRight->getType());
+ return;
+ }
+
+ // Base assumption: just make the type the same as the left
+ // operand. Then only deviations from this need be coded.
+ setType(mLeft->getType());
+
+ TQualifier resultQualifier = EvqConst;
+ // Binary operations results in temporary variables unless both
+ // operands are const. If initializing a specialization constant, make the declarator also
+ // EvqSpecConst.
+ const bool isSpecConstInit = mOp == EOpInitialize && mLeft->getQualifier() == EvqSpecConst;
+ const bool isEitherNonConst =
+ mLeft->getQualifier() != EvqConst || mRight->getQualifier() != EvqConst;
+ if (!isSpecConstInit && isEitherNonConst)
+ {
+ resultQualifier = EvqTemporary;
+ getTypePointer()->setQualifier(EvqTemporary);
+ }
+
+ // Result is an intermediate value, so make sure it's identified as such. That's not true for
+ // interface block arrays being indexed.
+ if (mOp != EOpIndexDirect && mOp != EOpIndexIndirect)
+ {
+ getTypePointer()->setInterfaceBlock(nullptr);
+ }
+
+ // Handle indexing ops.
+ switch (mOp)
+ {
+ case EOpIndexDirect:
+ case EOpIndexIndirect:
+ if (mLeft->isArray())
+ {
+ mType.toArrayElementType();
+ }
+ else if (mLeft->isMatrix())
+ {
+ mType.toMatrixColumnType();
+ }
+ else if (mLeft->isVector())
+ {
+ mType.toComponentType();
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+ return;
+ case EOpIndexDirectStruct:
+ {
+ const TFieldList &fields = mLeft->getType().getStruct()->fields();
+ const int fieldIndex = mRight->getAsConstantUnion()->getIConst(0);
+ setType(*fields[fieldIndex]->type());
+ getTypePointer()->setQualifier(resultQualifier);
+ return;
+ }
+ case EOpIndexDirectInterfaceBlock:
+ {
+ const TFieldList &fields = mLeft->getType().getInterfaceBlock()->fields();
+ const int fieldIndex = mRight->getAsConstantUnion()->getIConst(0);
+ setType(*fields[fieldIndex]->type());
+ getTypePointer()->setQualifier(resultQualifier);
+ return;
+ }
+ default:
+ break;
+ }
+
+ ASSERT(mLeft->isArray() == mRight->isArray());
+
+ const uint8_t nominalSize = std::max(mLeft->getNominalSize(), mRight->getNominalSize());
+
+ switch (mOp)
+ {
+ case EOpMul:
+ break;
+ case EOpMatrixTimesScalar:
+ if (mRight->isMatrix())
+ {
+ getTypePointer()->setPrimarySize(mRight->getCols());
+ getTypePointer()->setSecondarySize(mRight->getRows());
+ }
+ break;
+ case EOpMatrixTimesVector:
+ getTypePointer()->setPrimarySize(mLeft->getRows());
+ getTypePointer()->setSecondarySize(1);
+ break;
+ case EOpMatrixTimesMatrix:
+ getTypePointer()->setPrimarySize(mRight->getCols());
+ getTypePointer()->setSecondarySize(mLeft->getRows());
+ break;
+ case EOpVectorTimesScalar:
+ getTypePointer()->setPrimarySize(nominalSize);
+ break;
+ case EOpVectorTimesMatrix:
+ getTypePointer()->setPrimarySize(mRight->getCols());
+ ASSERT(getType().getSecondarySize() == 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:
+ {
+ ASSERT(!mLeft->isArray() && !mRight->isArray());
+ const uint8_t secondarySize =
+ std::max(mLeft->getSecondarySize(), mRight->getSecondarySize());
+ getTypePointer()->setPrimarySize(nominalSize);
+ getTypePointer()->setSecondarySize(secondarySize);
+ 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, resultQualifier));
+ break;
+
+ //
+ // And and Or operate on conditionals
+ //
+ case EOpLogicalAnd:
+ case EOpLogicalXor:
+ case EOpLogicalOr:
+ ASSERT(mLeft->getBasicType() == EbtBool && mRight->getBasicType() == EbtBool);
+ break;
+
+ case EOpIndexDirect:
+ case EOpIndexIndirect:
+ case EOpIndexDirectInterfaceBlock:
+ case EOpIndexDirectStruct:
+ // These ops should be already fully handled.
+ UNREACHABLE();
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ propagatePrecision(derivePrecision());
+}
+
+// Derive precision from children nodes
+TPrecision TIntermBinary::derivePrecision() const
+{
+ // Assignments use the type and precision of the lvalue-expression
+ // GLSL ES spec section 5.8: Assignments
+ // "The assignment operator stores the value of rvalue-expression into the l-value and returns
+ // an r-value with the type and precision of lvalue-expression."
+ if (IsAssignment(mOp))
+ {
+ return mLeft->getPrecision();
+ }
+
+ const TPrecision higherPrecision =
+ GetHigherPrecision(mLeft->getPrecision(), mRight->getPrecision());
+
+ switch (mOp)
+ {
+ case EOpComma:
+ // Comma takes the right node's value.
+ return mRight->getPrecision();
+
+ case EOpIndexDirect:
+ case EOpIndexIndirect:
+ case EOpBitShiftLeft:
+ case EOpBitShiftRight:
+ // When indexing an array, the precision of the array is preserved (which is the left
+ // node).
+ // For shift operations, the precision is derived from the expression being shifted
+ // (which is also the left node).
+ return mLeft->getPrecision();
+
+ case EOpIndexDirectStruct:
+ case EOpIndexDirectInterfaceBlock:
+ {
+ // When selecting the field of a block, the precision is taken from the field's
+ // declaration.
+ const TFieldList &fields = mOp == EOpIndexDirectStruct
+ ? mLeft->getType().getStruct()->fields()
+ : mLeft->getType().getInterfaceBlock()->fields();
+ const int fieldIndex = mRight->getAsConstantUnion()->getIConst(0);
+ return fields[fieldIndex]->type()->getPrecision();
+ }
+
+ case EOpEqual:
+ case EOpNotEqual:
+ case EOpLessThan:
+ case EOpGreaterThan:
+ case EOpLessThanEqual:
+ case EOpGreaterThanEqual:
+ case EOpLogicalAnd:
+ case EOpLogicalXor:
+ case EOpLogicalOr:
+ // No precision specified on bool results.
+ return EbpUndefined;
+
+ default:
+ // All other operations are evaluated at the higher of the two operands' precisions.
+ return higherPrecision;
+ }
+}
+
+void TIntermBinary::propagatePrecision(TPrecision precision)
+{
+ getTypePointer()->setPrecision(precision);
+
+ if (mOp != EOpComma)
+ {
+ PropagatePrecisionIfApplicable(mLeft, precision);
+ }
+
+ if (mOp != EOpIndexDirect && mOp != EOpIndexIndirect && mOp != EOpIndexDirectStruct &&
+ mOp != EOpIndexDirectInterfaceBlock)
+ {
+ PropagatePrecisionIfApplicable(mRight, precision);
+ }
+
+ // For indices, always apply highp. This is purely for the purpose of making sure constant and
+ // constructor nodes are also given a precision, so if they are hoisted to a temp variable,
+ // there would be a precision to apply to that variable.
+ if (mOp == EOpIndexDirect || mOp == EOpIndexIndirect)
+ {
+ PropagatePrecisionIfApplicable(mRight, EbpHigh);
+ }
+}
+
+bool TIntermConstantUnion::hasConstantValue() const
+{
+ return true;
+}
+
+bool TIntermConstantUnion::isConstantNullValue() const
+{
+ const size_t size = mType.getObjectSize();
+ for (size_t index = 0; index < size; ++index)
+ {
+ if (!mUnionArrayPointer[index].isZero())
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+const TConstantUnion *TIntermConstantUnion::getConstantValue() const
+{
+ return mUnionArrayPointer;
+}
+
+const TConstantUnion *TIntermConstantUnion::FoldIndexing(const TType &type,
+ const TConstantUnion *constArray,
+ int index)
+{
+ if (type.isArray())
+ {
+ ASSERT(index < static_cast<int>(type.getOutermostArraySize()));
+ TType arrayElementType(type);
+ arrayElementType.toArrayElementType();
+ size_t arrayElementSize = arrayElementType.getObjectSize();
+ return &constArray[arrayElementSize * index];
+ }
+ else if (type.isMatrix())
+ {
+ ASSERT(index < type.getCols());
+ const uint8_t size = type.getRows();
+ return &constArray[size * index];
+ }
+ else if (type.isVector())
+ {
+ ASSERT(index < type.getNominalSize());
+ return &constArray[index];
+ }
+ else
+ {
+ UNREACHABLE();
+ return nullptr;
+ }
+}
+
+TIntermTyped *TIntermSwizzle::fold(TDiagnostics * /* diagnostics */)
+{
+ TIntermSwizzle *operandSwizzle = mOperand->getAsSwizzleNode();
+ if (operandSwizzle)
+ {
+ // We need to fold the two swizzles into one, so that repeated swizzling can't cause stack
+ // overflow in ParseContext::checkCanBeLValue().
+ bool hadDuplicateOffsets = operandSwizzle->hasDuplicateOffsets();
+ TVector<int> foldedOffsets;
+ for (int offset : mSwizzleOffsets)
+ {
+ // Offset should already be validated.
+ ASSERT(static_cast<size_t>(offset) < operandSwizzle->mSwizzleOffsets.size());
+ foldedOffsets.push_back(operandSwizzle->mSwizzleOffsets[offset]);
+ }
+ operandSwizzle->mSwizzleOffsets = foldedOffsets;
+ operandSwizzle->setType(getType());
+ operandSwizzle->setHasFoldedDuplicateOffsets(hadDuplicateOffsets);
+ return operandSwizzle;
+ }
+ TIntermConstantUnion *operandConstant = mOperand->getAsConstantUnion();
+ if (operandConstant == nullptr)
+ {
+ return this;
+ }
+
+ TConstantUnion *constArray = new TConstantUnion[mSwizzleOffsets.size()];
+ for (size_t i = 0; i < mSwizzleOffsets.size(); ++i)
+ {
+ constArray[i] = *TIntermConstantUnion::FoldIndexing(
+ operandConstant->getType(), operandConstant->getConstantValue(), mSwizzleOffsets.at(i));
+ }
+ return CreateFoldedNode(constArray, this);
+}
+
+TIntermTyped *TIntermBinary::fold(TDiagnostics *diagnostics)
+{
+ const TConstantUnion *rightConstant = mRight->getConstantValue();
+ switch (mOp)
+ {
+ case EOpComma:
+ {
+ if (mLeft->hasSideEffects())
+ {
+ return this;
+ }
+ return mRight;
+ }
+ case EOpIndexDirect:
+ case EOpIndexDirectStruct:
+ {
+ if (rightConstant == nullptr)
+ {
+ return this;
+ }
+ size_t index = static_cast<size_t>(rightConstant->getIConst());
+ TIntermAggregate *leftAggregate = mLeft->getAsAggregate();
+ if (leftAggregate && leftAggregate->isConstructor() && leftAggregate->isArray() &&
+ !leftAggregate->hasSideEffects())
+ {
+ ASSERT(index < leftAggregate->getSequence()->size());
+ // This transformation can't add complexity as we're eliminating the constructor
+ // entirely.
+ return leftAggregate->getSequence()->at(index)->getAsTyped();
+ }
+
+ // If the indexed value is already a constant union, we can't increase duplication of
+ // data by folding the indexing. Also fold the node in case it's generally beneficial to
+ // replace this type of node with a constant union even if that would mean duplicating
+ // data.
+ if (mLeft->getAsConstantUnion() || getType().canReplaceWithConstantUnion())
+ {
+ const TConstantUnion *constantValue = getConstantValue();
+ if (constantValue == nullptr)
+ {
+ return this;
+ }
+ return CreateFoldedNode(constantValue, this);
+ }
+ return this;
+ }
+ case EOpIndexIndirect:
+ case EOpIndexDirectInterfaceBlock:
+ case EOpInitialize:
+ // Can never be constant folded.
+ return this;
+ default:
+ {
+ if (rightConstant == nullptr)
+ {
+ return this;
+ }
+ const TConstantUnion *leftConstant = mLeft->getConstantValue();
+ if (leftConstant == nullptr)
+ {
+ return this;
+ }
+ const TConstantUnion *constArray =
+ TIntermConstantUnion::FoldBinary(mOp, leftConstant, mLeft->getType(), rightConstant,
+ mRight->getType(), diagnostics, mLeft->getLine());
+ if (!constArray)
+ {
+ return this;
+ }
+ return CreateFoldedNode(constArray, this);
+ }
+ }
+}
+
+bool TIntermBinary::hasConstantValue() const
+{
+ switch (mOp)
+ {
+ case EOpIndexDirect:
+ case EOpIndexDirectStruct:
+ {
+ if (mLeft->hasConstantValue() && mRight->hasConstantValue())
+ {
+ return true;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ return false;
+}
+
+const TConstantUnion *TIntermBinary::getConstantValue() const
+{
+ if (!hasConstantValue())
+ {
+ return nullptr;
+ }
+
+ const TConstantUnion *leftConstantValue = mLeft->getConstantValue();
+ int index = mRight->getConstantValue()->getIConst();
+ const TConstantUnion *constIndexingResult = nullptr;
+ if (mOp == EOpIndexDirect)
+ {
+ constIndexingResult =
+ TIntermConstantUnion::FoldIndexing(mLeft->getType(), leftConstantValue, index);
+ }
+ else
+ {
+ ASSERT(mOp == EOpIndexDirectStruct);
+ const TFieldList &fields = mLeft->getType().getStruct()->fields();
+
+ size_t previousFieldsSize = 0;
+ for (int i = 0; i < index; ++i)
+ {
+ previousFieldsSize += fields[i]->type()->getObjectSize();
+ }
+ constIndexingResult = leftConstantValue + previousFieldsSize;
+ }
+ return constIndexingResult;
+}
+
+const ImmutableString &TIntermBinary::getIndexStructFieldName() const
+{
+ ASSERT(mOp == EOpIndexDirectStruct);
+
+ const TType &lhsType = mLeft->getType();
+ const TStructure *structure = lhsType.getStruct();
+ const int index = mRight->getAsConstantUnion()->getIConst(0);
+
+ return structure->fields()[index]->name();
+}
+
+TIntermTyped *TIntermUnary::fold(TDiagnostics *diagnostics)
+{
+ TConstantUnion *constArray = nullptr;
+
+ if (mOp == EOpArrayLength)
+ {
+ // The size of runtime-sized arrays may only be determined at runtime.
+ if (mOperand->hasSideEffects() || mOperand->getType().isUnsizedArray())
+ {
+ return this;
+ }
+ constArray = new TConstantUnion[1];
+ constArray->setIConst(mOperand->getOutermostArraySize());
+ }
+ else
+ {
+ TIntermConstantUnion *operandConstant = mOperand->getAsConstantUnion();
+ if (operandConstant == nullptr)
+ {
+ return this;
+ }
+
+ switch (mOp)
+ {
+ case EOpAny:
+ case EOpAll:
+ case EOpLength:
+ case EOpTranspose:
+ case EOpDeterminant:
+ case EOpInverse:
+ case EOpPackSnorm2x16:
+ case EOpUnpackSnorm2x16:
+ case EOpPackUnorm2x16:
+ case EOpUnpackUnorm2x16:
+ case EOpPackHalf2x16:
+ case EOpUnpackHalf2x16:
+ case EOpPackUnorm4x8:
+ case EOpPackSnorm4x8:
+ case EOpUnpackUnorm4x8:
+ case EOpUnpackSnorm4x8:
+ constArray = operandConstant->foldUnaryNonComponentWise(mOp);
+ break;
+ default:
+ constArray = operandConstant->foldUnaryComponentWise(mOp, mFunction, diagnostics);
+ break;
+ }
+ }
+ if (constArray == nullptr)
+ {
+ return this;
+ }
+ return CreateFoldedNode(constArray, this);
+}
+
+TIntermTyped *TIntermAggregate::fold(TDiagnostics *diagnostics)
+{
+ // Make sure that all params are constant before actual constant folding.
+ for (auto *param : *getSequence())
+ {
+ if (param->getAsConstantUnion() == nullptr)
+ {
+ return this;
+ }
+ }
+ const TConstantUnion *constArray = nullptr;
+ if (isConstructor())
+ {
+ if (mType.canReplaceWithConstantUnion())
+ {
+ constArray = getConstantValue();
+ if (constArray && mType.getBasicType() == EbtUInt)
+ {
+ // Check if we converted a negative float to uint and issue a warning in that case.
+ size_t sizeRemaining = mType.getObjectSize();
+ for (TIntermNode *arg : mArguments)
+ {
+ TIntermTyped *typedArg = arg->getAsTyped();
+ if (typedArg->getBasicType() == EbtFloat)
+ {
+ const TConstantUnion *argValue = typedArg->getConstantValue();
+ size_t castSize =
+ std::min(typedArg->getType().getObjectSize(), sizeRemaining);
+ for (size_t i = 0; i < castSize; ++i)
+ {
+ if (argValue[i].getFConst() < 0.0f)
+ {
+ // ESSL 3.00.6 section 5.4.1.
+ diagnostics->warning(
+ mLine, "casting a negative float to uint is undefined",
+ mType.getBuiltInTypeNameString());
+ }
+ }
+ }
+ sizeRemaining -= typedArg->getType().getObjectSize();
+ }
+ }
+ }
+ }
+ else if (CanFoldAggregateBuiltInOp(mOp))
+ {
+ constArray = TIntermConstantUnion::FoldAggregateBuiltIn(this, diagnostics);
+ }
+ if (constArray == nullptr)
+ {
+ return this;
+ }
+ return CreateFoldedNode(constArray, this);
+}
+
+//
+// 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.
+//
+const TConstantUnion *TIntermConstantUnion::FoldBinary(TOperator op,
+ const TConstantUnion *leftArray,
+ const TType &leftType,
+ const TConstantUnion *rightArray,
+ const TType &rightType,
+ TDiagnostics *diagnostics,
+ const TSourceLoc &line)
+{
+ ASSERT(leftArray && rightArray);
+
+ size_t objectSize = leftType.getObjectSize();
+
+ // for a case like float f = vec4(2, 3, 4, 5) + 1.2;
+ if (rightType.getObjectSize() == 1 && objectSize > 1)
+ {
+ rightArray = Vectorize(*rightArray, objectSize);
+ }
+ else if (rightType.getObjectSize() > 1 && objectSize == 1)
+ {
+ // for a case like float f = 1.2 + vec4(2, 3, 4, 5);
+ leftArray = Vectorize(*leftArray, rightType.getObjectSize());
+ objectSize = rightType.getObjectSize();
+ }
+
+ TConstantUnion *resultArray = nullptr;
+
+ switch (op)
+ {
+ case EOpAdd:
+ resultArray = new TConstantUnion[objectSize];
+ for (size_t i = 0; i < objectSize; 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] =
+ TConstantUnion::sub(leftArray[i], rightArray[i], diagnostics, line);
+ break;
+
+ case EOpMul:
+ case EOpVectorTimesScalar:
+ case EOpMatrixTimesScalar:
+ resultArray = new TConstantUnion[objectSize];
+ for (size_t i = 0; i < objectSize; i++)
+ resultArray[i] =
+ TConstantUnion::mul(leftArray[i], rightArray[i], diagnostics, line);
+ break;
+
+ case EOpMatrixTimesMatrix:
+ {
+ // TODO(jmadll): This code should check for overflows.
+ ASSERT(leftType.getBasicType() == EbtFloat && rightType.getBasicType() == EbtFloat);
+
+ const uint8_t leftCols = leftType.getCols();
+ const uint8_t leftRows = leftType.getRows();
+ const uint8_t rightCols = rightType.getCols();
+ const uint8_t rightRows = rightType.getRows();
+ const uint8_t resultCols = rightCols;
+ const uint8_t resultRows = leftRows;
+
+ resultArray = new TConstantUnion[resultCols * resultRows];
+ for (uint8_t row = 0; row < resultRows; row++)
+ {
+ for (uint8_t column = 0; column < resultCols; column++)
+ {
+ resultArray[resultRows * column + row].setFConst(0.0f);
+ for (uint8_t i = 0; i < leftCols; i++)
+ {
+ resultArray[resultRows * column + row].setFConst(
+ resultArray[resultRows * column + row].getFConst() +
+ leftArray[i * leftRows + row].getFConst() *
+ rightArray[column * rightRows + i].getFConst());
+ }
+ }
+ }
+ }
+ break;
+
+ case EOpDiv:
+ case EOpIMod:
+ {
+ resultArray = new TConstantUnion[objectSize];
+ for (size_t i = 0; i < objectSize; i++)
+ {
+ if (IsFloatDivision(leftType.getBasicType(), rightType.getBasicType()))
+ {
+ // Float division requested, possibly with implicit conversion
+ ASSERT(op == EOpDiv);
+ float dividend = leftArray[i].getFConst();
+ float divisor = rightArray[i].getFConst();
+
+ if (divisor == 0.0f)
+ {
+ if (dividend == 0.0f)
+ {
+ diagnostics->warning(line,
+ "Zero divided by zero during constant "
+ "folding generated NaN",
+ "/");
+ resultArray[i].setFConst(std::numeric_limits<float>::quiet_NaN());
+ }
+ else
+ {
+ diagnostics->warning(line, "Divide by zero during constant folding",
+ "/");
+ bool negativeResult = std::signbit(dividend) != std::signbit(divisor);
+ resultArray[i].setFConst(negativeResult
+ ? -std::numeric_limits<float>::infinity()
+ : std::numeric_limits<float>::infinity());
+ }
+ }
+ else if (gl::isInf(dividend) && gl::isInf(divisor))
+ {
+ diagnostics->warning(line,
+ "Infinity divided by infinity during constant "
+ "folding generated NaN",
+ "/");
+ resultArray[i].setFConst(std::numeric_limits<float>::quiet_NaN());
+ }
+ else
+ {
+ float result = dividend / divisor;
+ if (!gl::isInf(dividend) && gl::isInf(result))
+ {
+ diagnostics->warning(
+ line, "Constant folded division overflowed to infinity", "/");
+ }
+ resultArray[i].setFConst(result);
+ }
+ }
+ else
+ {
+ // Types are either both int or both uint
+ switch (leftType.getBasicType())
+ {
+ case EbtInt:
+ {
+ if (rightArray[i] == 0)
+ {
+ diagnostics->warning(
+ line, "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)
+ {
+ // 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);
+ 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(line,
+ "Negative modulus operator operand "
+ "encountered during constant folding. "
+ "Results are undefined.",
+ "%");
+ resultArray[i].setIConst(0);
+ }
+ else
+ {
+ resultArray[i].setIConst(lhs % divisor);
+ }
+ }
+ }
+ break;
+ }
+ case EbtUInt:
+ {
+ if (rightArray[i] == 0)
+ {
+ diagnostics->warning(
+ line, "Divide by zero error during constant folding", "/");
+ resultArray[i].setUConst(UINT_MAX);
+ }
+ else
+ {
+ if (op == EOpDiv)
+ {
+ resultArray[i].setUConst(leftArray[i].getUConst() /
+ rightArray[i].getUConst());
+ }
+ else
+ {
+ ASSERT(op == EOpIMod);
+ resultArray[i].setUConst(leftArray[i].getUConst() %
+ rightArray[i].getUConst());
+ }
+ }
+ break;
+ }
+ default:
+ UNREACHABLE();
+ return nullptr;
+ }
+ }
+ }
+ }
+ break;
+
+ case EOpMatrixTimesVector:
+ {
+ // TODO(jmadll): This code should check for overflows.
+ ASSERT(rightType.getBasicType() == EbtFloat);
+
+ const uint8_t matrixCols = leftType.getCols();
+ const uint8_t matrixRows = leftType.getRows();
+
+ resultArray = new TConstantUnion[matrixRows];
+
+ for (uint8_t matrixRow = 0; matrixRow < matrixRows; matrixRow++)
+ {
+ resultArray[matrixRow].setFConst(0.0f);
+ for (uint8_t col = 0; col < matrixCols; col++)
+ {
+ resultArray[matrixRow].setFConst(
+ resultArray[matrixRow].getFConst() +
+ leftArray[col * matrixRows + matrixRow].getFConst() *
+ rightArray[col].getFConst());
+ }
+ }
+ }
+ break;
+
+ case EOpVectorTimesMatrix:
+ {
+ // TODO(jmadll): This code should check for overflows.
+ ASSERT(leftType.getBasicType() == EbtFloat);
+
+ const uint8_t matrixCols = rightType.getCols();
+ const uint8_t matrixRows = rightType.getRows();
+
+ resultArray = new TConstantUnion[matrixCols];
+
+ for (uint8_t matrixCol = 0; matrixCol < matrixCols; matrixCol++)
+ {
+ resultArray[matrixCol].setFConst(0.0f);
+ for (uint8_t matrixRow = 0; matrixRow < matrixRows; matrixRow++)
+ {
+ resultArray[matrixCol].setFConst(
+ resultArray[matrixCol].getFConst() +
+ leftArray[matrixRow].getFConst() *
+ rightArray[matrixCol * matrixRows + matrixRow].getFConst());
+ }
+ }
+ }
+ break;
+
+ case EOpLogicalAnd:
+ {
+ resultArray = new TConstantUnion[objectSize];
+ for (size_t i = 0; i < objectSize; i++)
+ {
+ resultArray[i] = leftArray[i] && rightArray[i];
+ }
+ }
+ break;
+
+ case EOpLogicalOr:
+ {
+ resultArray = new TConstantUnion[objectSize];
+ for (size_t i = 0; i < objectSize; i++)
+ {
+ resultArray[i] = leftArray[i] || rightArray[i];
+ }
+ }
+ break;
+
+ case EOpLogicalXor:
+ {
+ ASSERT(leftType.getBasicType() == EbtBool);
+ resultArray = new TConstantUnion[objectSize];
+ for (size_t i = 0; i < objectSize; i++)
+ {
+ resultArray[i].setBConst(leftArray[i] != rightArray[i]);
+ }
+ }
+ break;
+
+ case EOpBitwiseAnd:
+ resultArray = new TConstantUnion[objectSize];
+ for (size_t i = 0; i < objectSize; i++)
+ resultArray[i] = leftArray[i] & rightArray[i];
+ break;
+ case EOpBitwiseXor:
+ resultArray = new TConstantUnion[objectSize];
+ for (size_t i = 0; i < objectSize; i++)
+ resultArray[i] = leftArray[i] ^ rightArray[i];
+ break;
+ case EOpBitwiseOr:
+ resultArray = new TConstantUnion[objectSize];
+ for (size_t i = 0; i < objectSize; i++)
+ resultArray[i] = leftArray[i] | rightArray[i];
+ break;
+ case EOpBitShiftLeft:
+ resultArray = new TConstantUnion[objectSize];
+ for (size_t i = 0; i < objectSize; 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] =
+ TConstantUnion::rshift(leftArray[i], rightArray[i], diagnostics, line);
+ break;
+
+ case EOpLessThan:
+ ASSERT(objectSize == 1);
+ resultArray = new TConstantUnion[1];
+ resultArray->setBConst(*leftArray < *rightArray);
+ break;
+
+ case EOpGreaterThan:
+ ASSERT(objectSize == 1);
+ resultArray = new TConstantUnion[1];
+ resultArray->setBConst(*leftArray > *rightArray);
+ break;
+
+ case EOpLessThanEqual:
+ ASSERT(objectSize == 1);
+ resultArray = new TConstantUnion[1];
+ resultArray->setBConst(!(*leftArray > *rightArray));
+ break;
+
+ case EOpGreaterThanEqual:
+ ASSERT(objectSize == 1);
+ resultArray = new TConstantUnion[1];
+ resultArray->setBConst(!(*leftArray < *rightArray));
+ break;
+
+ case EOpEqual:
+ case EOpNotEqual:
+ {
+ resultArray = new TConstantUnion[1];
+ bool equal = true;
+ for (size_t i = 0; i < objectSize; i++)
+ {
+ if (leftArray[i] != rightArray[i])
+ {
+ equal = false;
+ break; // break out of for loop
+ }
+ }
+ if (op == EOpEqual)
+ {
+ resultArray->setBConst(equal);
+ }
+ else
+ {
+ resultArray->setBConst(!equal);
+ }
+ }
+ break;
+
+ default:
+ UNREACHABLE();
+ return nullptr;
+ }
+ return resultArray;
+}
+
+// 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 may have a different number of components compared to the
+ // operand type.
+
+ const TConstantUnion *operandArray = getConstantValue();
+ ASSERT(operandArray);
+
+ size_t objectSize = getType().getObjectSize();
+ TConstantUnion *resultArray = nullptr;
+ switch (op)
+ {
+ case EOpAny:
+ ASSERT(getType().getBasicType() == EbtBool);
+ resultArray = new TConstantUnion();
+ resultArray->setBConst(false);
+ for (size_t i = 0; i < objectSize; i++)
+ {
+ if (operandArray[i].getBConst())
+ {
+ resultArray->setBConst(true);
+ break;
+ }
+ }
+ break;
+
+ case EOpAll:
+ ASSERT(getType().getBasicType() == EbtBool);
+ resultArray = new TConstantUnion();
+ resultArray->setBConst(true);
+ for (size_t i = 0; i < objectSize; i++)
+ {
+ if (!operandArray[i].getBConst())
+ {
+ resultArray->setBConst(false);
+ break;
+ }
+ }
+ break;
+
+ case EOpLength:
+ ASSERT(getType().getBasicType() == EbtFloat);
+ resultArray = new TConstantUnion();
+ resultArray->setFConst(VectorLength(operandArray, objectSize));
+ break;
+
+ case EOpTranspose:
+ {
+ ASSERT(getType().getBasicType() == EbtFloat);
+ resultArray = new TConstantUnion[objectSize];
+ angle::Matrix<float> result =
+ GetMatrix(operandArray, getType().getRows(), getType().getCols()).transpose();
+ SetUnionArrayFromMatrix(result, resultArray);
+ break;
+ }
+
+ case EOpDeterminant:
+ {
+ ASSERT(getType().getBasicType() == EbtFloat);
+ const uint8_t size = getType().getNominalSize();
+ ASSERT(size >= 2 && size <= 4);
+ resultArray = new TConstantUnion();
+ resultArray->setFConst(GetMatrix(operandArray, size).determinant());
+ break;
+ }
+
+ case EOpInverse:
+ {
+ ASSERT(getType().getBasicType() == EbtFloat);
+ const uint8_t size = getType().getNominalSize();
+ ASSERT(size >= 2 && size <= 4);
+ resultArray = new TConstantUnion[objectSize];
+ angle::Matrix<float> result = GetMatrix(operandArray, size).inverse();
+ SetUnionArrayFromMatrix(result, resultArray);
+ break;
+ }
+
+ case EOpPackSnorm2x16:
+ ASSERT(getType().getBasicType() == EbtFloat);
+ ASSERT(getType().getNominalSize() == 2);
+ resultArray = new TConstantUnion();
+ resultArray->setUConst(
+ gl::packSnorm2x16(operandArray[0].getFConst(), operandArray[1].getFConst()));
+ break;
+
+ case EOpUnpackSnorm2x16:
+ {
+ ASSERT(getType().getBasicType() == EbtUInt);
+ resultArray = new TConstantUnion[2];
+ float f1, f2;
+ gl::unpackSnorm2x16(operandArray[0].getUConst(), &f1, &f2);
+ resultArray[0].setFConst(f1);
+ resultArray[1].setFConst(f2);
+ break;
+ }
+
+ case EOpPackUnorm2x16:
+ ASSERT(getType().getBasicType() == EbtFloat);
+ ASSERT(getType().getNominalSize() == 2);
+ resultArray = new TConstantUnion();
+ resultArray->setUConst(
+ gl::packUnorm2x16(operandArray[0].getFConst(), operandArray[1].getFConst()));
+ break;
+
+ case EOpUnpackUnorm2x16:
+ {
+ ASSERT(getType().getBasicType() == EbtUInt);
+ resultArray = new TConstantUnion[2];
+ float f1, f2;
+ gl::unpackUnorm2x16(operandArray[0].getUConst(), &f1, &f2);
+ resultArray[0].setFConst(f1);
+ resultArray[1].setFConst(f2);
+ break;
+ }
+
+ case EOpPackHalf2x16:
+ ASSERT(getType().getBasicType() == EbtFloat);
+ ASSERT(getType().getNominalSize() == 2);
+ resultArray = new TConstantUnion();
+ resultArray->setUConst(
+ gl::packHalf2x16(operandArray[0].getFConst(), operandArray[1].getFConst()));
+ break;
+
+ case EOpUnpackHalf2x16:
+ {
+ ASSERT(getType().getBasicType() == EbtUInt);
+ resultArray = new TConstantUnion[2];
+ float f1, f2;
+ gl::unpackHalf2x16(operandArray[0].getUConst(), &f1, &f2);
+ resultArray[0].setFConst(f1);
+ resultArray[1].setFConst(f2);
+ break;
+ }
+
+ case EOpPackUnorm4x8:
+ {
+ ASSERT(getType().getBasicType() == EbtFloat);
+ resultArray = new TConstantUnion();
+ resultArray->setUConst(
+ gl::PackUnorm4x8(operandArray[0].getFConst(), operandArray[1].getFConst(),
+ operandArray[2].getFConst(), operandArray[3].getFConst()));
+ break;
+ }
+ case EOpPackSnorm4x8:
+ {
+ ASSERT(getType().getBasicType() == EbtFloat);
+ resultArray = new TConstantUnion();
+ resultArray->setUConst(
+ gl::PackSnorm4x8(operandArray[0].getFConst(), operandArray[1].getFConst(),
+ operandArray[2].getFConst(), operandArray[3].getFConst()));
+ break;
+ }
+ case EOpUnpackUnorm4x8:
+ {
+ ASSERT(getType().getBasicType() == EbtUInt);
+ resultArray = new TConstantUnion[4];
+ float f[4];
+ gl::UnpackUnorm4x8(operandArray[0].getUConst(), f);
+ for (size_t i = 0; i < 4; ++i)
+ {
+ resultArray[i].setFConst(f[i]);
+ }
+ break;
+ }
+ case EOpUnpackSnorm4x8:
+ {
+ ASSERT(getType().getBasicType() == EbtUInt);
+ resultArray = new TConstantUnion[4];
+ float f[4];
+ gl::UnpackSnorm4x8(operandArray[0].getUConst(), f);
+ for (size_t i = 0; i < 4; ++i)
+ {
+ resultArray[i].setFConst(f[i]);
+ }
+ break;
+ }
+
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ return resultArray;
+}
+
+TConstantUnion *TIntermConstantUnion::foldUnaryComponentWise(TOperator op,
+ const TFunction *function,
+ TDiagnostics *diagnostics)
+{
+ // 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 = getConstantValue();
+ ASSERT(operandArray);
+
+ size_t objectSize = getType().getObjectSize();
+
+ TConstantUnion *resultArray = new TConstantUnion[objectSize];
+ for (size_t i = 0; i < objectSize; i++)
+ {
+ switch (op)
+ {
+ 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;
+
+ 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;
+
+ case EOpLogicalNot:
+ switch (getType().getBasicType())
+ {
+ case EbtBool:
+ resultArray[i].setBConst(!operandArray[i].getBConst());
+ break;
+ default:
+ UNREACHABLE();
+ 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());
+ break;
+ default:
+ UNREACHABLE();
+ return nullptr;
+ }
+ break;
+
+ case EOpRadians:
+ ASSERT(getType().getBasicType() == EbtFloat);
+ resultArray[i].setFConst(kDegreesToRadiansMultiplier * operandArray[i].getFConst());
+ break;
+
+ case EOpDegrees:
+ ASSERT(getType().getBasicType() == EbtFloat);
+ resultArray[i].setFConst(kRadiansToDegreesMultiplier * operandArray[i].getFConst());
+ break;
+
+ case EOpSin:
+ foldFloatTypeUnary(operandArray[i], &sinf, &resultArray[i]);
+ break;
+
+ case EOpCos:
+ foldFloatTypeUnary(operandArray[i], &cosf, &resultArray[i]);
+ break;
+
+ case EOpTan:
+ foldFloatTypeUnary(operandArray[i], &tanf, &resultArray[i]);
+ 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(), function, getType().getBasicType(),
+ diagnostics, &resultArray[i]);
+ else
+ foldFloatTypeUnary(operandArray[i], &asinf, &resultArray[i]);
+ 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(), function, getType().getBasicType(),
+ diagnostics, &resultArray[i]);
+ else
+ foldFloatTypeUnary(operandArray[i], &acosf, &resultArray[i]);
+ break;
+
+ case EOpAtan:
+ foldFloatTypeUnary(operandArray[i], &atanf, &resultArray[i]);
+ break;
+
+ case EOpSinh:
+ foldFloatTypeUnary(operandArray[i], &sinhf, &resultArray[i]);
+ break;
+
+ case EOpCosh:
+ foldFloatTypeUnary(operandArray[i], &coshf, &resultArray[i]);
+ break;
+
+ case EOpTanh:
+ foldFloatTypeUnary(operandArray[i], &tanhf, &resultArray[i]);
+ break;
+
+ case EOpAsinh:
+ foldFloatTypeUnary(operandArray[i], &asinhf, &resultArray[i]);
+ break;
+
+ 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(), function, getType().getBasicType(),
+ diagnostics, &resultArray[i]);
+ else
+ foldFloatTypeUnary(operandArray[i], &acoshf, &resultArray[i]);
+ break;
+
+ 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(), function, getType().getBasicType(),
+ diagnostics, &resultArray[i]);
+ else
+ foldFloatTypeUnary(operandArray[i], &atanhf, &resultArray[i]);
+ break;
+
+ case EOpAbs:
+ switch (getType().getBasicType())
+ {
+ 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 EOpSign:
+ switch (getType().getBasicType())
+ {
+ 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;
+
+ case EOpFloor:
+ foldFloatTypeUnary(operandArray[i], &floorf, &resultArray[i]);
+ break;
+
+ case EOpTrunc:
+ foldFloatTypeUnary(operandArray[i], &truncf, &resultArray[i]);
+ break;
+
+ case EOpRound:
+ foldFloatTypeUnary(operandArray[i], &roundf, &resultArray[i]);
+ break;
+
+ case EOpRoundEven:
+ {
+ ASSERT(getType().getBasicType() == EbtFloat);
+ float x = operandArray[i].getFConst();
+ float result;
+ float fractPart = modff(x, &result);
+ if (fabsf(fractPart) == 0.5f)
+ result = 2.0f * roundf(x / 2.0f);
+ else
+ result = roundf(x);
+ resultArray[i].setFConst(result);
+ break;
+ }
+
+ case EOpCeil:
+ foldFloatTypeUnary(operandArray[i], &ceilf, &resultArray[i]);
+ break;
+
+ case EOpFract:
+ {
+ ASSERT(getType().getBasicType() == EbtFloat);
+ float x = operandArray[i].getFConst();
+ resultArray[i].setFConst(x - floorf(x));
+ break;
+ }
+
+ case EOpIsnan:
+ ASSERT(getType().getBasicType() == EbtFloat);
+ resultArray[i].setBConst(gl::isNaN(operandArray[0].getFConst()));
+ break;
+
+ case EOpIsinf:
+ ASSERT(getType().getBasicType() == EbtFloat);
+ resultArray[i].setBConst(gl::isInf(operandArray[0].getFConst()));
+ break;
+
+ case EOpFloatBitsToInt:
+ ASSERT(getType().getBasicType() == EbtFloat);
+ resultArray[i].setIConst(gl::bitCast<int32_t>(operandArray[0].getFConst()));
+ break;
+
+ case EOpFloatBitsToUint:
+ ASSERT(getType().getBasicType() == EbtFloat);
+ resultArray[i].setUConst(gl::bitCast<uint32_t>(operandArray[0].getFConst()));
+ break;
+
+ case EOpIntBitsToFloat:
+ ASSERT(getType().getBasicType() == EbtInt);
+ resultArray[i].setFConst(gl::bitCast<float>(operandArray[0].getIConst()));
+ break;
+
+ case EOpUintBitsToFloat:
+ ASSERT(getType().getBasicType() == EbtUInt);
+ resultArray[i].setFConst(gl::bitCast<float>(operandArray[0].getUConst()));
+ 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 (operandArray[i].getFConst() <= 0.0f)
+ UndefinedConstantFoldingError(getLine(), function, getType().getBasicType(),
+ diagnostics, &resultArray[i]);
+ else
+ foldFloatTypeUnary(operandArray[i], &logf, &resultArray[i]);
+ 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 (operandArray[i].getFConst() <= 0.0f)
+ UndefinedConstantFoldingError(getLine(), function, 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 (operandArray[i].getFConst() < 0.0f)
+ UndefinedConstantFoldingError(getLine(), function, 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 (operandArray[i].getFConst() <= 0.0f)
+ UndefinedConstantFoldingError(getLine(), function, getType().getBasicType(),
+ diagnostics, &resultArray[i]);
+ else
+ {
+ foldFloatTypeUnary(operandArray[i], &sqrtf, &resultArray[i]);
+ resultArray[i].setFConst(1.0f / resultArray[i].getFConst());
+ }
+ break;
+
+ case EOpNotComponentWise:
+ ASSERT(getType().getBasicType() == EbtBool);
+ resultArray[i].setBConst(!operandArray[i].getBConst());
+ break;
+
+ case EOpNormalize:
+ {
+ ASSERT(getType().getBasicType() == EbtFloat);
+ float x = operandArray[i].getFConst();
+ float length = VectorLength(operandArray, objectSize);
+ if (length != 0.0f)
+ resultArray[i].setFConst(x / length);
+ else
+ UndefinedConstantFoldingError(getLine(), function, getType().getBasicType(),
+ diagnostics, &resultArray[i]);
+ break;
+ }
+ case EOpBitfieldReverse:
+ {
+ uint32_t value;
+ if (getType().getBasicType() == EbtInt)
+ {
+ value = static_cast<uint32_t>(operandArray[i].getIConst());
+ }
+ else
+ {
+ ASSERT(getType().getBasicType() == EbtUInt);
+ value = operandArray[i].getUConst();
+ }
+ uint32_t result = gl::BitfieldReverse(value);
+ if (getType().getBasicType() == EbtInt)
+ {
+ resultArray[i].setIConst(static_cast<int32_t>(result));
+ }
+ else
+ {
+ resultArray[i].setUConst(result);
+ }
+ break;
+ }
+ case EOpBitCount:
+ {
+ uint32_t value;
+ if (getType().getBasicType() == EbtInt)
+ {
+ value = static_cast<uint32_t>(operandArray[i].getIConst());
+ }
+ else
+ {
+ ASSERT(getType().getBasicType() == EbtUInt);
+ value = operandArray[i].getUConst();
+ }
+ int result = gl::BitCount(value);
+ resultArray[i].setIConst(result);
+ break;
+ }
+ case EOpFindLSB:
+ {
+ uint32_t value;
+ if (getType().getBasicType() == EbtInt)
+ {
+ value = static_cast<uint32_t>(operandArray[i].getIConst());
+ }
+ else
+ {
+ ASSERT(getType().getBasicType() == EbtUInt);
+ value = operandArray[i].getUConst();
+ }
+ resultArray[i].setIConst(gl::FindLSB(value));
+ break;
+ }
+ case EOpFindMSB:
+ {
+ uint32_t value;
+ if (getType().getBasicType() == EbtInt)
+ {
+ int intValue = operandArray[i].getIConst();
+ value = static_cast<uint32_t>(intValue);
+ if (intValue < 0)
+ {
+ // Look for zero instead of one in value. This also handles the intValue ==
+ // -1 special case, where the return value needs to be -1.
+ value = ~value;
+ }
+ }
+ else
+ {
+ ASSERT(getType().getBasicType() == EbtUInt);
+ value = operandArray[i].getUConst();
+ }
+ resultArray[i].setIConst(gl::FindMSB(value));
+ break;
+ }
+
+ default:
+ return nullptr;
+ }
+ }
+
+ return resultArray;
+}
+
+void TIntermConstantUnion::foldFloatTypeUnary(const TConstantUnion &parameter,
+ FloatTypeUnaryFunc builtinFunc,
+ TConstantUnion *result) const
+{
+ ASSERT(builtinFunc);
+
+ ASSERT(getType().getBasicType() == EbtFloat);
+ result->setFConst(builtinFunc(parameter.getFConst()));
+}
+
+void TIntermConstantUnion::propagatePrecision(TPrecision precision)
+{
+ mType.setPrecision(precision);
+}
+
+// static
+TConstantUnion *TIntermConstantUnion::FoldAggregateBuiltIn(TIntermAggregate *aggregate,
+ TDiagnostics *diagnostics)
+{
+ const TOperator op = aggregate->getOp();
+ const TFunction *function = aggregate->getFunction();
+ TIntermSequence *arguments = aggregate->getSequence();
+ unsigned int argsCount = static_cast<unsigned int>(arguments->size());
+ std::vector<const TConstantUnion *> unionArrays(argsCount);
+ std::vector<size_t> objectSizes(argsCount);
+ size_t maxObjectSize = 0;
+ TBasicType basicType = EbtVoid;
+ TSourceLoc loc;
+ for (unsigned int i = 0; i < argsCount; i++)
+ {
+ TIntermConstantUnion *argConstant = (*arguments)[i]->getAsConstantUnion();
+ ASSERT(argConstant != nullptr); // Should be checked already.
+
+ if (i == 0)
+ {
+ basicType = argConstant->getType().getBasicType();
+ loc = argConstant->getLine();
+ }
+ unionArrays[i] = argConstant->getConstantValue();
+ objectSizes[i] = argConstant->getType().getObjectSize();
+ if (objectSizes[i] > maxObjectSize)
+ maxObjectSize = objectSizes[i];
+ }
+
+ if (!(*arguments)[0]->getAsTyped()->isMatrix() && aggregate->getOp() != EOpOuterProduct)
+ {
+ for (unsigned int i = 0; i < argsCount; i++)
+ if (objectSizes[i] != maxObjectSize)
+ unionArrays[i] = Vectorize(*unionArrays[i], maxObjectSize);
+ }
+
+ TConstantUnion *resultArray = nullptr;
+
+ switch (op)
+ {
+ case EOpAtan:
+ {
+ ASSERT(basicType == EbtFloat);
+ 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, function, basicType, diagnostics,
+ &resultArray[i]);
+ else
+ resultArray[i].setFConst(atan2f(y, x));
+ }
+ break;
+ }
+
+ case EOpPow:
+ {
+ ASSERT(basicType == EbtFloat);
+ 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, function, basicType, diagnostics,
+ &resultArray[i]);
+ else if (x == 0.0f && y <= 0.0f)
+ UndefinedConstantFoldingError(loc, function, basicType, diagnostics,
+ &resultArray[i]);
+ else
+ resultArray[i].setFConst(powf(x, y));
+ }
+ break;
+ }
+
+ case EOpMod:
+ {
+ ASSERT(basicType == EbtFloat);
+ 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));
+ }
+ break;
+ }
+
+ 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;
+ }
+ }
+ break;
+ }
+
+ 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;
+ }
+ }
+ break;
+ }
+
+ case EOpStep:
+ {
+ 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;
+ }
+
+ case EOpLessThanComponentWise:
+ {
+ 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;
+ }
+ }
+ break;
+ }
+
+ case EOpLessThanEqualComponentWise:
+ {
+ 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;
+ }
+ }
+ break;
+ }
+
+ case EOpGreaterThanComponentWise:
+ {
+ 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;
+ }
+ }
+ break;
+ }
+ case EOpGreaterThanEqualComponentWise:
+ {
+ 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;
+ }
+ }
+ }
+ break;
+
+ case EOpEqualComponentWise:
+ {
+ 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;
+ }
+ }
+ break;
+ }
+
+ case EOpNotEqualComponentWise:
+ {
+ 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;
+ }
+ }
+ break;
+ }
+
+ case EOpDistance:
+ {
+ ASSERT(basicType == EbtFloat);
+ TConstantUnion *distanceArray = new TConstantUnion[maxObjectSize];
+ resultArray = new TConstantUnion();
+ for (size_t i = 0; i < maxObjectSize; i++)
+ {
+ float x = unionArrays[0][i].getFConst();
+ float y = unionArrays[1][i].getFConst();
+ distanceArray[i].setFConst(x - y);
+ }
+ resultArray->setFConst(VectorLength(distanceArray, maxObjectSize));
+ break;
+ }
+
+ case EOpDot:
+ ASSERT(basicType == EbtFloat);
+ resultArray = new TConstantUnion();
+ resultArray->setFConst(VectorDotProduct(unionArrays[0], unionArrays[1], maxObjectSize));
+ break;
+
+ 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();
+ resultArray[0].setFConst(x1 * y2 - y1 * x2);
+ resultArray[1].setFConst(x2 * y0 - y2 * x0);
+ resultArray[2].setFConst(x0 * y1 - y0 * x1);
+ break;
+ }
+
+ case EOpReflect:
+ {
+ ASSERT(basicType == EbtFloat);
+ // genType reflect (genType I, genType N) :
+ // For the incident vector I and surface orientation N, returns the reflection
+ // direction:
+ // I - 2 * dot(N, I) * N.
+ resultArray = new TConstantUnion[maxObjectSize];
+ float dotProduct = VectorDotProduct(unionArrays[1], unionArrays[0], maxObjectSize);
+ for (size_t i = 0; i < maxObjectSize; i++)
+ {
+ float result = unionArrays[0][i].getFConst() -
+ 2.0f * dotProduct * unionArrays[1][i].getFConst();
+ resultArray[i].setFConst(result);
+ }
+ break;
+ }
+
+ case EOpMatrixCompMult:
+ {
+ ASSERT(basicType == EbtFloat && (*arguments)[0]->getAsTyped()->isMatrix() &&
+ (*arguments)[1]->getAsTyped()->isMatrix());
+ // Perform component-wise matrix multiplication.
+ resultArray = new TConstantUnion[maxObjectSize];
+ const uint8_t rows = (*arguments)[0]->getAsTyped()->getRows();
+ const uint8_t cols = (*arguments)[0]->getAsTyped()->getCols();
+ angle::Matrix<float> lhs = GetMatrix(unionArrays[0], rows, cols);
+ angle::Matrix<float> rhs = GetMatrix(unionArrays[1], rows, cols);
+ angle::Matrix<float> result = lhs.compMult(rhs);
+ SetUnionArrayFromMatrix(result, resultArray);
+ break;
+ }
+
+ case EOpOuterProduct:
+ {
+ ASSERT(basicType == EbtFloat);
+ size_t numRows = (*arguments)[0]->getAsTyped()->getType().getObjectSize();
+ size_t numCols = (*arguments)[1]->getAsTyped()->getType().getObjectSize();
+ resultArray = new TConstantUnion[numRows * numCols];
+ angle::Matrix<float> result =
+ GetMatrix(unionArrays[0], static_cast<int>(numRows), 1)
+ .outerProduct(GetMatrix(unionArrays[1], 1, static_cast<int>(numCols)));
+ SetUnionArrayFromMatrix(result, resultArray);
+ break;
+ }
+
+ case EOpClamp:
+ {
+ resultArray = new TConstantUnion[maxObjectSize];
+ for (size_t i = 0; i < maxObjectSize; i++)
+ {
+ switch (basicType)
+ {
+ case EbtFloat:
+ {
+ 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, function, basicType, diagnostics,
+ &resultArray[i]);
+ else
+ resultArray[i].setFConst(gl::clamp(x, min, max));
+ break;
+ }
+
+ case EbtInt:
+ {
+ 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, function, basicType, diagnostics,
+ &resultArray[i]);
+ else
+ resultArray[i].setIConst(gl::clamp(x, min, max));
+ break;
+ }
+ case EbtUInt:
+ {
+ 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, function, basicType, diagnostics,
+ &resultArray[i]);
+ else
+ resultArray[i].setUConst(gl::clamp(x, min, max));
+ break;
+ }
+ default:
+ UNREACHABLE();
+ break;
+ }
+ }
+ break;
+ }
+
+ case EOpMix:
+ {
+ resultArray = new TConstantUnion[maxObjectSize];
+ for (size_t i = 0; i < maxObjectSize; i++)
+ {
+ TBasicType type = (*arguments)[2]->getAsTyped()->getType().getBasicType();
+ if (type == EbtFloat)
+ {
+ ASSERT(basicType == EbtFloat);
+ float x = unionArrays[0][i].getFConst();
+ float y = unionArrays[1][i].getFConst();
+
+ // 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();
+ switch (basicType)
+ {
+ case EbtFloat:
+ {
+ float x = unionArrays[0][i].getFConst();
+ float y = unionArrays[1][i].getFConst();
+ resultArray[i].setFConst(a ? y : x);
+ }
+ break;
+ case EbtInt:
+ {
+ int x = unionArrays[0][i].getIConst();
+ int y = unionArrays[1][i].getIConst();
+ resultArray[i].setIConst(a ? y : x);
+ }
+ break;
+ case EbtUInt:
+ {
+ unsigned int x = unionArrays[0][i].getUConst();
+ unsigned int y = unionArrays[1][i].getUConst();
+ resultArray[i].setUConst(a ? y : x);
+ }
+ break;
+ case EbtBool:
+ {
+ bool x = unionArrays[0][i].getBConst();
+ bool y = unionArrays[1][i].getBConst();
+ resultArray[i].setBConst(a ? y : x);
+ }
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ }
+ }
+ break;
+ }
+
+ case EOpSmoothstep:
+ {
+ ASSERT(basicType == EbtFloat);
+ 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)
+ {
+ UndefinedConstantFoldingError(loc, function, 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));
+ }
+ }
+ break;
+ }
+
+ case EOpFma:
+ {
+ ASSERT(basicType == EbtFloat);
+ resultArray = new TConstantUnion[maxObjectSize];
+ for (size_t i = 0; i < maxObjectSize; i++)
+ {
+ float a = unionArrays[0][i].getFConst();
+ float b = unionArrays[1][i].getFConst();
+ float c = unionArrays[2][i].getFConst();
+
+ // Returns a * b + c.
+ resultArray[i].setFConst(a * b + c);
+ }
+ break;
+ }
+
+ case EOpLdexp:
+ {
+ resultArray = new TConstantUnion[maxObjectSize];
+ for (size_t i = 0; i < maxObjectSize; i++)
+ {
+ float x = unionArrays[0][i].getFConst();
+ int exp = unionArrays[1][i].getIConst();
+ if (exp > 128)
+ {
+ UndefinedConstantFoldingError(loc, function, basicType, diagnostics,
+ &resultArray[i]);
+ }
+ else
+ {
+ resultArray[i].setFConst(gl::Ldexp(x, exp));
+ }
+ }
+ break;
+ }
+
+ 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];
+ float dotProduct = VectorDotProduct(unionArrays[2], unionArrays[1], maxObjectSize);
+ for (size_t i = 0; i < maxObjectSize; i++)
+ {
+ if (dotProduct < 0)
+ resultArray[i].setFConst(unionArrays[0][i].getFConst());
+ else
+ resultArray[i].setFConst(-unionArrays[0][i].getFConst());
+ }
+ break;
+ }
+
+ 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,
+ // 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];
+ 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);
+ 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());
+ }
+ break;
+ }
+ case EOpBitfieldExtract:
+ {
+ resultArray = new TConstantUnion[maxObjectSize];
+ for (size_t i = 0; i < maxObjectSize; ++i)
+ {
+ int offset = unionArrays[1][0].getIConst();
+ int bits = unionArrays[2][0].getIConst();
+ if (bits == 0)
+ {
+ if (aggregate->getBasicType() == EbtInt)
+ {
+ resultArray[i].setIConst(0);
+ }
+ else
+ {
+ ASSERT(aggregate->getBasicType() == EbtUInt);
+ resultArray[i].setUConst(0);
+ }
+ }
+ else if (offset < 0 || bits < 0 || offset >= 32 || bits > 32 || offset + bits > 32)
+ {
+ UndefinedConstantFoldingError(loc, function, aggregate->getBasicType(),
+ diagnostics, &resultArray[i]);
+ }
+ else
+ {
+ // bits can be 32 here, so we need to avoid bit shift overflow.
+ uint32_t maskMsb = 1u << (bits - 1);
+ uint32_t mask = ((maskMsb - 1u) | maskMsb) << offset;
+ if (aggregate->getBasicType() == EbtInt)
+ {
+ uint32_t value = static_cast<uint32_t>(unionArrays[0][i].getIConst());
+ uint32_t resultUnsigned = (value & mask) >> offset;
+ if ((resultUnsigned & maskMsb) != 0)
+ {
+ // The most significant bits (from bits+1 to the most significant bit)
+ // should be set to 1.
+ uint32_t higherBitsMask = ((1u << (32 - bits)) - 1u) << bits;
+ resultUnsigned |= higherBitsMask;
+ }
+ resultArray[i].setIConst(static_cast<int32_t>(resultUnsigned));
+ }
+ else
+ {
+ ASSERT(aggregate->getBasicType() == EbtUInt);
+ uint32_t value = unionArrays[0][i].getUConst();
+ resultArray[i].setUConst((value & mask) >> offset);
+ }
+ }
+ }
+ break;
+ }
+ case EOpBitfieldInsert:
+ {
+ resultArray = new TConstantUnion[maxObjectSize];
+ for (size_t i = 0; i < maxObjectSize; ++i)
+ {
+ int offset = unionArrays[2][0].getIConst();
+ int bits = unionArrays[3][0].getIConst();
+ if (bits == 0)
+ {
+ if (aggregate->getBasicType() == EbtInt)
+ {
+ int32_t base = unionArrays[0][i].getIConst();
+ resultArray[i].setIConst(base);
+ }
+ else
+ {
+ ASSERT(aggregate->getBasicType() == EbtUInt);
+ uint32_t base = unionArrays[0][i].getUConst();
+ resultArray[i].setUConst(base);
+ }
+ }
+ else if (offset < 0 || bits < 0 || offset >= 32 || bits > 32 || offset + bits > 32)
+ {
+ UndefinedConstantFoldingError(loc, function, aggregate->getBasicType(),
+ diagnostics, &resultArray[i]);
+ }
+ else
+ {
+ // bits can be 32 here, so we need to avoid bit shift overflow.
+ uint32_t maskMsb = 1u << (bits - 1);
+ uint32_t insertMask = ((maskMsb - 1u) | maskMsb) << offset;
+ uint32_t baseMask = ~insertMask;
+ if (aggregate->getBasicType() == EbtInt)
+ {
+ uint32_t base = static_cast<uint32_t>(unionArrays[0][i].getIConst());
+ uint32_t insert = static_cast<uint32_t>(unionArrays[1][i].getIConst());
+ uint32_t resultUnsigned =
+ (base & baseMask) | ((insert << offset) & insertMask);
+ resultArray[i].setIConst(static_cast<int32_t>(resultUnsigned));
+ }
+ else
+ {
+ ASSERT(aggregate->getBasicType() == EbtUInt);
+ uint32_t base = unionArrays[0][i].getUConst();
+ uint32_t insert = unionArrays[1][i].getUConst();
+ resultArray[i].setUConst((base & baseMask) |
+ ((insert << offset) & insertMask));
+ }
+ }
+ }
+ break;
+ }
+ case EOpDFdx:
+ case EOpDFdy:
+ case EOpFwidth:
+ ASSERT(basicType == EbtFloat);
+ resultArray = new TConstantUnion[maxObjectSize];
+ for (size_t i = 0; i < maxObjectSize; i++)
+ {
+ // Derivatives of constant arguments should be 0.
+ resultArray[i].setFConst(0.0f);
+ }
+ break;
+
+ default:
+ UNREACHABLE();
+ return nullptr;
+ }
+ return resultArray;
+}
+
+bool TIntermConstantUnion::IsFloatDivision(TBasicType t1, TBasicType t2)
+{
+ ImplicitTypeConversion conversion = GetConversion(t1, t2);
+ ASSERT(conversion != ImplicitTypeConversion::Invalid);
+ if (conversion == ImplicitTypeConversion::Same)
+ {
+ if (t1 == EbtFloat)
+ return true;
+ return false;
+ }
+ ASSERT(t1 == EbtFloat || t2 == EbtFloat);
+ return true;
+}
+
+// TIntermPreprocessorDirective implementation.
+TIntermPreprocessorDirective::TIntermPreprocessorDirective(PreprocessorDirective directive,
+ ImmutableString command)
+ : mDirective(directive), mCommand(std::move(command))
+{}
+
+TIntermPreprocessorDirective::TIntermPreprocessorDirective(const TIntermPreprocessorDirective &node)
+ : TIntermPreprocessorDirective(node.mDirective, node.mCommand)
+{}
+
+TIntermPreprocessorDirective::~TIntermPreprocessorDirective() = default;
+
+size_t TIntermPreprocessorDirective::getChildCount() const
+{
+ return 0;
+}
+
+TIntermNode *TIntermPreprocessorDirective::getChildNode(size_t index) const
+{
+ UNREACHABLE();
+ return nullptr;
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/IntermNode.h b/gfx/angle/checkout/src/compiler/translator/IntermNode.h
new file mode 100644
index 0000000000..81b5fcce43
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/IntermNode.h
@@ -0,0 +1,1046 @@
+//
+// Copyright 2002 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.
+//
+
+//
+// Definition of the in-memory high-level intermediate representation
+// of shaders. This is a tree that parser creates.
+//
+// Nodes in the tree are defined as a hierarchy of classes derived from
+// TIntermNode. Each is a node in a tree. There is no preset branching factor;
+// each node can have it's own type of list of children.
+//
+
+#ifndef COMPILER_TRANSLATOR_INTERMNODE_H_
+#define COMPILER_TRANSLATOR_INTERMNODE_H_
+
+#include "GLSLANG/ShaderLang.h"
+
+#include <algorithm>
+#include <queue>
+
+#include "common/angleutils.h"
+#include "compiler/translator/Common.h"
+#include "compiler/translator/ConstantUnion.h"
+#include "compiler/translator/ImmutableString.h"
+#include "compiler/translator/Operator_autogen.h"
+#include "compiler/translator/SymbolUniqueId.h"
+#include "compiler/translator/Types.h"
+#include "compiler/translator/tree_util/Visit.h"
+
+namespace sh
+{
+
+class TDiagnostics;
+
+class TIntermTraverser;
+class TIntermAggregate;
+class TIntermBlock;
+class TIntermGlobalQualifierDeclaration;
+class TIntermDeclaration;
+class TIntermFunctionPrototype;
+class TIntermFunctionDefinition;
+class TIntermSwizzle;
+class TIntermBinary;
+class TIntermUnary;
+class TIntermConstantUnion;
+class TIntermTernary;
+class TIntermIfElse;
+class TIntermSwitch;
+class TIntermCase;
+class TIntermTyped;
+class TIntermSymbol;
+class TIntermLoop;
+class TInfoSink;
+class TInfoSinkBase;
+class TIntermBranch;
+class TIntermPreprocessorDirective;
+
+class TSymbolTable;
+class TFunction;
+class TVariable;
+
+//
+// Base class for the tree nodes
+//
+class TIntermNode : angle::NonCopyable
+{
+ public:
+ POOL_ALLOCATOR_NEW_DELETE
+ TIntermNode()
+ {
+ // TODO: Move this to TSourceLoc constructor
+ // after getting rid of TPublicType.
+ mLine.first_file = mLine.last_file = 0;
+ mLine.first_line = mLine.last_line = 0;
+ }
+ virtual ~TIntermNode() {}
+
+ const TSourceLoc &getLine() const { return mLine; }
+ void setLine(const TSourceLoc &l) { mLine = l; }
+
+ virtual void traverse(TIntermTraverser *it);
+ virtual bool visit(Visit visit, TIntermTraverser *it) = 0;
+
+ virtual TIntermTyped *getAsTyped() { return nullptr; }
+ virtual TIntermConstantUnion *getAsConstantUnion() { return nullptr; }
+ virtual TIntermFunctionDefinition *getAsFunctionDefinition() { return nullptr; }
+ virtual TIntermAggregate *getAsAggregate() { return nullptr; }
+ virtual TIntermBlock *getAsBlock() { return nullptr; }
+ virtual TIntermFunctionPrototype *getAsFunctionPrototypeNode() { return nullptr; }
+ virtual TIntermGlobalQualifierDeclaration *getAsGlobalQualifierDeclarationNode()
+ {
+ return nullptr;
+ }
+ virtual TIntermDeclaration *getAsDeclarationNode() { return nullptr; }
+ virtual TIntermSwizzle *getAsSwizzleNode() { return nullptr; }
+ virtual TIntermBinary *getAsBinaryNode() { return nullptr; }
+ virtual TIntermUnary *getAsUnaryNode() { return nullptr; }
+ virtual TIntermTernary *getAsTernaryNode() { return nullptr; }
+ virtual TIntermIfElse *getAsIfElseNode() { return nullptr; }
+ virtual TIntermSwitch *getAsSwitchNode() { return nullptr; }
+ virtual TIntermCase *getAsCaseNode() { return nullptr; }
+ virtual TIntermSymbol *getAsSymbolNode() { return nullptr; }
+ virtual TIntermLoop *getAsLoopNode() { return nullptr; }
+ virtual TIntermBranch *getAsBranchNode() { return nullptr; }
+ virtual TIntermPreprocessorDirective *getAsPreprocessorDirective() { return nullptr; }
+
+ virtual TIntermNode *deepCopy() const = 0;
+
+ virtual size_t getChildCount() const = 0;
+ virtual TIntermNode *getChildNode(size_t index) const = 0;
+ // Replace a child node. Return true if |original| is a child
+ // node and it is replaced; otherwise, return false.
+ virtual bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) = 0;
+
+ protected:
+ TSourceLoc mLine;
+};
+
+//
+// This is just to help yacc.
+//
+struct TIntermNodePair
+{
+ TIntermNode *node1;
+ TIntermNode *node2;
+};
+
+//
+// Intermediate class for nodes that have a type.
+//
+class TIntermTyped : public TIntermNode
+{
+ public:
+ TIntermTyped();
+
+ virtual TIntermTyped *deepCopy() const override = 0;
+
+ TIntermTyped *getAsTyped() override { return this; }
+
+ virtual TIntermTyped *fold(TDiagnostics *diagnostics) { return this; }
+
+ // getConstantValue() returns the constant value that this node represents, if any. It
+ // should only be used after nodes have been replaced with their folded versions returned
+ // from fold(). hasConstantValue() returns true if getConstantValue() will return a value.
+ virtual bool hasConstantValue() const;
+ virtual bool isConstantNullValue() const;
+ virtual const TConstantUnion *getConstantValue() const;
+
+ // True if executing the expression represented by this node affects state, like values of
+ // variables. False if the executing the expression only computes its return value without
+ // affecting state. May return true conservatively.
+ virtual bool hasSideEffects() const = 0;
+
+ virtual const TType &getType() const = 0;
+
+ // Derive the precision of the node based on its children's.
+ virtual TPrecision derivePrecision() const;
+ // Set precision of the current node and propagate it to any child node that doesn't have
+ // precision. This should be the case only for TIntermConstantUnion nodes as every other node
+ // would already need to have its precision specified or derived.
+ virtual void propagatePrecision(TPrecision precision);
+
+ TBasicType getBasicType() const { return getType().getBasicType(); }
+ TQualifier getQualifier() const { return getType().getQualifier(); }
+ TPrecision getPrecision() const { return getType().getPrecision(); }
+ TMemoryQualifier getMemoryQualifier() const { return getType().getMemoryQualifier(); }
+ uint8_t getCols() const { return getType().getCols(); }
+ uint8_t getRows() const { return getType().getRows(); }
+ uint8_t getNominalSize() const { return getType().getNominalSize(); }
+ uint8_t getSecondarySize() const { return getType().getSecondarySize(); }
+
+ bool isInterfaceBlock() const { return getType().isInterfaceBlock(); }
+ bool isMatrix() const { return getType().isMatrix(); }
+ bool isArray() const { return getType().isArray(); }
+ bool isVector() const { return getType().isVector(); }
+ bool isScalar() const { return getType().isScalar(); }
+ bool isScalarInt() const { return getType().isScalarInt(); }
+ const char *getBasicString() const { return getType().getBasicString(); }
+
+ unsigned int getOutermostArraySize() const { return getType().getOutermostArraySize(); }
+
+ // After every transformation is done and just before outputting the tree (i.e. when the tree
+ // nodes are no longer going to change), the tree is traversed to gather some information to be
+ // stored in the intermediate nodes:
+ //
+ // - Precise-ness, which is set for arithmetic nodes that are involved in the calculation of a
+ // value assigned to a |precise| variable.
+ void setIsPrecise() { mIsPrecise = true; }
+ bool isPrecise() const { return mIsPrecise; }
+
+ protected:
+ TIntermTyped(const TIntermTyped &node);
+
+ bool mIsPrecise;
+};
+
+//
+// Handle for, do-while, and while loops.
+//
+enum TLoopType
+{
+ ELoopFor,
+ ELoopWhile,
+ ELoopDoWhile
+};
+
+class TIntermLoop : public TIntermNode
+{
+ public:
+ TIntermLoop(TLoopType type,
+ TIntermNode *init,
+ TIntermTyped *cond,
+ TIntermTyped *expr,
+ TIntermBlock *body);
+
+ TIntermLoop *getAsLoopNode() override { return this; }
+ void traverse(TIntermTraverser *it) final;
+ bool visit(Visit visit, TIntermTraverser *it) final;
+
+ size_t getChildCount() const final;
+ TIntermNode *getChildNode(size_t index) const final;
+ bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
+
+ TLoopType getType() const { return mType; }
+ TIntermNode *getInit() { return mInit; }
+ TIntermTyped *getCondition() { return mCond; }
+ TIntermTyped *getExpression() { return mExpr; }
+ TIntermBlock *getBody() { return mBody; }
+
+ void setInit(TIntermNode *init) { mInit = init; }
+ void setCondition(TIntermTyped *condition) { mCond = condition; }
+ void setExpression(TIntermTyped *expression) { mExpr = expression; }
+ void setBody(TIntermBlock *body) { mBody = body; }
+
+ virtual TIntermLoop *deepCopy() const override { return new TIntermLoop(*this); }
+
+ protected:
+ TLoopType mType;
+ TIntermNode *mInit; // for-loop initialization
+ TIntermTyped *mCond; // loop exit condition
+ TIntermTyped *mExpr; // for-loop expression
+ TIntermBlock *mBody; // loop body
+
+ private:
+ TIntermLoop(const TIntermLoop &);
+};
+
+//
+// Handle break, continue, return, and kill.
+//
+class TIntermBranch : public TIntermNode
+{
+ public:
+ TIntermBranch(TOperator op, TIntermTyped *e) : mFlowOp(op), mExpression(e) {}
+
+ TIntermBranch *getAsBranchNode() override { return this; }
+ bool visit(Visit visit, TIntermTraverser *it) final;
+
+ size_t getChildCount() const final;
+ TIntermNode *getChildNode(size_t index) const final;
+ bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
+
+ TOperator getFlowOp() { return mFlowOp; }
+ TIntermTyped *getExpression() { return mExpression; }
+
+ virtual TIntermBranch *deepCopy() const override { return new TIntermBranch(*this); }
+
+ protected:
+ TOperator mFlowOp;
+ TIntermTyped *mExpression; // zero except for "return exp;" statements
+
+ private:
+ TIntermBranch(const TIntermBranch &);
+};
+
+// Nodes that correspond to variable symbols in the source code. These may be regular variables or
+// interface block instances. In declarations that only declare a struct type but no variables, a
+// TIntermSymbol node with an empty variable is used to store the type.
+class TIntermSymbol : public TIntermTyped
+{
+ public:
+ TIntermSymbol(const TVariable *variable);
+
+ TIntermTyped *deepCopy() const override { return new TIntermSymbol(*this); }
+
+ bool hasConstantValue() const override;
+ const TConstantUnion *getConstantValue() const override;
+
+ bool hasSideEffects() const override { return false; }
+
+ const TType &getType() const override;
+
+ const TSymbolUniqueId &uniqueId() const;
+ ImmutableString getName() const;
+ const TVariable &variable() const { return *mVariable; }
+
+ TIntermSymbol *getAsSymbolNode() override { return this; }
+ void traverse(TIntermTraverser *it) final;
+ bool visit(Visit visit, TIntermTraverser *it) final;
+
+ size_t getChildCount() const final;
+ TIntermNode *getChildNode(size_t index) const final;
+ bool replaceChildNode(TIntermNode *, TIntermNode *) override { return false; }
+
+ private:
+ TIntermSymbol(const TIntermSymbol &) = default; // Note: not deleted, just private!
+ void propagatePrecision(TPrecision precision) override;
+
+ const TVariable *const mVariable; // Guaranteed to be non-null
+};
+
+// A typed expression that is not just representing a symbol table symbol.
+class TIntermExpression : public TIntermTyped
+{
+ public:
+ TIntermExpression(const TType &t);
+
+ const TType &getType() const override { return mType; }
+
+ protected:
+ TType *getTypePointer() { return &mType; }
+ void setType(const TType &t) { mType = t; }
+
+ TIntermExpression(const TIntermExpression &node) = default;
+
+ TType mType;
+};
+
+// Constant folded node.
+// Note that nodes may be constant folded and not be constant expressions with the EvqConst
+// qualifier. This happens for example when the following expression is processed:
+// "true ? 1.0 : non_constant"
+// Other nodes than TIntermConstantUnion may also be constant expressions.
+//
+class TIntermConstantUnion : public TIntermExpression
+{
+ public:
+ TIntermConstantUnion(const TConstantUnion *unionPointer, const TType &type)
+ : TIntermExpression(type), mUnionArrayPointer(unionPointer)
+ {
+ ASSERT(unionPointer);
+ }
+
+ TIntermTyped *deepCopy() const override { return new TIntermConstantUnion(*this); }
+
+ bool hasConstantValue() const override;
+ bool isConstantNullValue() const override;
+ const TConstantUnion *getConstantValue() const override;
+
+ bool hasSideEffects() const override { return false; }
+
+ int getIConst(size_t index) const
+ {
+ return mUnionArrayPointer ? mUnionArrayPointer[index].getIConst() : 0;
+ }
+ unsigned int getUConst(size_t index) const
+ {
+ return mUnionArrayPointer ? mUnionArrayPointer[index].getUConst() : 0;
+ }
+ float getFConst(size_t index) const
+ {
+ return mUnionArrayPointer ? mUnionArrayPointer[index].getFConst() : 0.0f;
+ }
+ bool getBConst(size_t index) const
+ {
+ return mUnionArrayPointer ? mUnionArrayPointer[index].getBConst() : false;
+ }
+ bool isZero(size_t index) const
+ {
+ return mUnionArrayPointer ? mUnionArrayPointer[index].isZero() : false;
+ }
+
+ TIntermConstantUnion *getAsConstantUnion() override { return this; }
+ void traverse(TIntermTraverser *it) final;
+ bool visit(Visit visit, TIntermTraverser *it) final;
+
+ size_t getChildCount() const final;
+ TIntermNode *getChildNode(size_t index) const final;
+ bool replaceChildNode(TIntermNode *, TIntermNode *) override { return false; }
+
+ TConstantUnion *foldUnaryNonComponentWise(TOperator op);
+ TConstantUnion *foldUnaryComponentWise(TOperator op,
+ const TFunction *function,
+ TDiagnostics *diagnostics);
+
+ static const TConstantUnion *FoldBinary(TOperator op,
+ const TConstantUnion *leftArray,
+ const TType &leftType,
+ const TConstantUnion *rightArray,
+ const TType &rightType,
+ TDiagnostics *diagnostics,
+ const TSourceLoc &line);
+
+ static const TConstantUnion *FoldIndexing(const TType &type,
+ const TConstantUnion *constArray,
+ int index);
+ static TConstantUnion *FoldAggregateBuiltIn(TIntermAggregate *aggregate,
+ TDiagnostics *diagnostics);
+ static bool IsFloatDivision(TBasicType t1, TBasicType t2);
+
+ protected:
+ // Same data may be shared between multiple constant unions, so it can't be modified.
+ const TConstantUnion *mUnionArrayPointer;
+
+ private:
+ typedef float (*FloatTypeUnaryFunc)(float);
+ void foldFloatTypeUnary(const TConstantUnion &parameter,
+ FloatTypeUnaryFunc builtinFunc,
+ TConstantUnion *result) const;
+ void propagatePrecision(TPrecision precision) override;
+
+ TIntermConstantUnion(const TIntermConstantUnion &node); // Note: not deleted, just private!
+};
+
+//
+// Intermediate class for node types that hold operators.
+//
+class TIntermOperator : public TIntermExpression
+{
+ public:
+ TOperator getOp() const { return mOp; }
+
+ bool isAssignment() const;
+ bool isMultiplication() const;
+ bool isConstructor() const;
+
+ // Returns true for calls mapped to EOpCall*, false for all built-ins.
+ bool isFunctionCall() const;
+
+ bool hasSideEffects() const override { return isAssignment(); }
+
+ protected:
+ TIntermOperator(TOperator op) : TIntermExpression(TType(EbtFloat, EbpUndefined)), mOp(op) {}
+ TIntermOperator(TOperator op, const TType &type) : TIntermExpression(type), mOp(op) {}
+
+ TIntermOperator(const TIntermOperator &) = default;
+
+ const TOperator mOp;
+};
+
+// Node for vector swizzles.
+class TIntermSwizzle : public TIntermExpression
+{
+ 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; }
+ bool visit(Visit visit, TIntermTraverser *it) final;
+
+ size_t getChildCount() const final;
+ TIntermNode *getChildNode(size_t index) const final;
+ bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
+
+ bool hasSideEffects() const override { return mOperand->hasSideEffects(); }
+
+ TIntermTyped *getOperand() { return mOperand; }
+ void writeOffsetsAsXYZW(TInfoSinkBase *out) const;
+
+ const TVector<int> &getSwizzleOffsets() { return mSwizzleOffsets; }
+
+ bool hasDuplicateOffsets() const;
+ void setHasFoldedDuplicateOffsets(bool hasFoldedDuplicateOffsets);
+ bool offsetsMatch(int offset) const;
+
+ TIntermTyped *fold(TDiagnostics *diagnostics) override;
+
+ protected:
+ TIntermTyped *mOperand;
+ TVector<int> mSwizzleOffsets;
+ bool mHasFoldedDuplicateOffsets;
+
+ private:
+ void promote();
+ TPrecision derivePrecision() const override;
+ void propagatePrecision(TPrecision precision) override;
+
+ TIntermSwizzle(const TIntermSwizzle &node); // Note: not deleted, just private!
+};
+
+//
+// Nodes for all the basic binary math operators.
+//
+class TIntermBinary : public TIntermOperator
+{
+ public:
+ // This constructor determines the type of the binary node based on the operands and op.
+ TIntermBinary(TOperator op, TIntermTyped *left, TIntermTyped *right);
+ // Comma qualifier depends on the shader version, so use this to create comma nodes:
+ static TIntermBinary *CreateComma(TIntermTyped *left, TIntermTyped *right, int shaderVersion);
+
+ TIntermTyped *deepCopy() const override { return new TIntermBinary(*this); }
+
+ bool hasConstantValue() const override;
+ const TConstantUnion *getConstantValue() const override;
+
+ 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) final;
+ bool visit(Visit visit, TIntermTraverser *it) final;
+
+ size_t getChildCount() const final;
+ TIntermNode *getChildNode(size_t index) const final;
+ bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
+
+ bool hasSideEffects() const override
+ {
+ return isAssignment() || mLeft->hasSideEffects() || mRight->hasSideEffects();
+ }
+
+ TIntermTyped *getLeft() const { return mLeft; }
+ TIntermTyped *getRight() const { return mRight; }
+ TIntermTyped *fold(TDiagnostics *diagnostics) override;
+
+ // This method is only valid for EOpIndexDirectStruct. It returns the name of the field.
+ const ImmutableString &getIndexStructFieldName() const;
+
+ protected:
+ TIntermTyped *mLeft;
+ TIntermTyped *mRight;
+
+ private:
+ void promote();
+ TPrecision derivePrecision() const override;
+ void propagatePrecision(TPrecision precision) override;
+
+ static TQualifier GetCommaQualifier(int shaderVersion,
+ const TIntermTyped *left,
+ const TIntermTyped *right);
+
+ TIntermBinary(const TIntermBinary &node); // Note: not deleted, just private!
+};
+
+//
+// Nodes for unary math operators.
+//
+class TIntermUnary : public TIntermOperator
+{
+ public:
+ TIntermUnary(TOperator op, TIntermTyped *operand, const TFunction *function);
+
+ TIntermTyped *deepCopy() const override { return new TIntermUnary(*this); }
+
+ TIntermUnary *getAsUnaryNode() override { return this; }
+ void traverse(TIntermTraverser *it) final;
+ bool visit(Visit visit, TIntermTraverser *it) final;
+
+ size_t getChildCount() const final;
+ TIntermNode *getChildNode(size_t index) const final;
+ bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
+
+ bool hasSideEffects() const override { return isAssignment() || mOperand->hasSideEffects(); }
+
+ TIntermTyped *getOperand() { return mOperand; }
+ TIntermTyped *fold(TDiagnostics *diagnostics) override;
+
+ const TFunction *getFunction() const { return mFunction; }
+
+ void setUseEmulatedFunction() { mUseEmulatedFunction = true; }
+ bool getUseEmulatedFunction() { return mUseEmulatedFunction; }
+
+ protected:
+ TIntermTyped *mOperand;
+
+ // If set to true, replace the built-in function call with an emulated one
+ // to work around driver bugs.
+ bool mUseEmulatedFunction;
+
+ const TFunction *const mFunction;
+
+ private:
+ void promote();
+ TPrecision derivePrecision() const override;
+ void propagatePrecision(TPrecision precision) override;
+
+ TIntermUnary(const TIntermUnary &node); // note: not deleted, just private!
+};
+
+typedef TVector<TIntermNode *> TIntermSequence;
+typedef TVector<int> TQualifierList;
+
+// Interface for node classes that have an arbitrarily sized set of children.
+class TIntermAggregateBase
+{
+ public:
+ virtual ~TIntermAggregateBase() {}
+
+ virtual TIntermSequence *getSequence() = 0;
+ virtual const TIntermSequence *getSequence() const = 0;
+
+ bool replaceChildNodeWithMultiple(TIntermNode *original, const TIntermSequence &replacements);
+ bool insertChildNodes(TIntermSequence::size_type position, const TIntermSequence &insertions);
+
+ protected:
+ TIntermAggregateBase() {}
+
+ bool replaceChildNodeInternal(TIntermNode *original, TIntermNode *replacement);
+};
+
+//
+// Nodes that operate on an arbitrary sized set of children.
+//
+class TIntermAggregate : public TIntermOperator, public TIntermAggregateBase
+{
+ public:
+ static TIntermAggregate *CreateFunctionCall(const TFunction &func, TIntermSequence *arguments);
+
+ static TIntermAggregate *CreateRawFunctionCall(const TFunction &func,
+ TIntermSequence *arguments);
+
+ // This covers all built-in function calls.
+ static TIntermAggregate *CreateBuiltInFunctionCall(const TFunction &func,
+ TIntermSequence *arguments);
+ static TIntermAggregate *CreateConstructor(const TType &type, TIntermSequence *arguments);
+ static TIntermAggregate *CreateConstructor(
+ const TType &type,
+ const std::initializer_list<TIntermNode *> &arguments);
+ ~TIntermAggregate() override {}
+
+ // Note: only supported for nodes that can be a part of an expression.
+ TIntermTyped *deepCopy() const override { return new TIntermAggregate(*this); }
+
+ TIntermAggregate *shallowCopy() const;
+
+ bool hasConstantValue() const override;
+ bool isConstantNullValue() const override;
+ const TConstantUnion *getConstantValue() const override;
+
+ TIntermAggregate *getAsAggregate() override { return this; }
+ void traverse(TIntermTraverser *it) final;
+ bool visit(Visit visit, TIntermTraverser *it) final;
+
+ size_t getChildCount() const final;
+ TIntermNode *getChildNode(size_t index) const final;
+ bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
+
+ bool hasSideEffects() const override;
+
+ TIntermTyped *fold(TDiagnostics *diagnostics) override;
+
+ TIntermSequence *getSequence() override { return &mArguments; }
+ const TIntermSequence *getSequence() const override { return &mArguments; }
+
+ void setUseEmulatedFunction() { mUseEmulatedFunction = true; }
+ bool getUseEmulatedFunction() { return mUseEmulatedFunction; }
+
+ const TFunction *getFunction() const { return mFunction; }
+
+ // Get the function name to display to the user in an error message.
+ const char *functionName() const;
+
+ protected:
+ TIntermSequence mArguments;
+
+ // If set to true, replace the built-in function call with an emulated one
+ // to work around driver bugs. Only for calls mapped to ops other than EOpCall*.
+ bool mUseEmulatedFunction;
+
+ const TFunction *const mFunction;
+
+ private:
+ TIntermAggregate(const TFunction *func,
+ const TType &type,
+ TOperator op,
+ TIntermSequence *arguments);
+
+ TIntermAggregate(const TIntermAggregate &node); // note: not deleted, just private!
+
+ void setPrecisionAndQualifier();
+ TPrecision derivePrecision() const override;
+ void propagatePrecision(TPrecision precision) override;
+
+ bool areChildrenConstQualified();
+};
+
+// A list of statements. Either the root node which contains declarations and function definitions,
+// or a block that can be marked with curly braces {}.
+class TIntermBlock : public TIntermNode, public TIntermAggregateBase
+{
+ public:
+ TIntermBlock() : TIntermNode(), mIsTreeRoot(false) {}
+ TIntermBlock(std::initializer_list<TIntermNode *> stmts);
+ ~TIntermBlock() override {}
+
+ TIntermBlock *getAsBlock() override { return this; }
+ void traverse(TIntermTraverser *it) final;
+ bool visit(Visit visit, TIntermTraverser *it) final;
+
+ size_t getChildCount() const final;
+ TIntermNode *getChildNode(size_t index) const final;
+ bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
+ void replaceAllChildren(const TIntermSequence &newStatements);
+
+ // Only intended for initially building the block.
+ void appendStatement(TIntermNode *statement);
+ void insertStatement(size_t insertPosition, TIntermNode *statement);
+
+ TIntermSequence *getSequence() override { return &mStatements; }
+ const TIntermSequence *getSequence() const override { return &mStatements; }
+
+ TIntermBlock *deepCopy() const override { return new TIntermBlock(*this); }
+
+ void setIsTreeRoot() { mIsTreeRoot = true; }
+ bool isTreeRoot() const { return mIsTreeRoot; }
+
+ protected:
+ TIntermSequence mStatements;
+
+ // Used to distinguish the tree root from the other blocks. When validating the AST, some
+ // validations are not applicable if not run on the entire tree and are thus skipped.
+ bool mIsTreeRoot;
+
+ private:
+ TIntermBlock(const TIntermBlock &);
+};
+
+// Function prototype. May be in the AST either as a function prototype declaration or as a part of
+// a function definition. The type of the node is the function return type.
+class TIntermFunctionPrototype : public TIntermTyped
+{
+ public:
+ TIntermFunctionPrototype(const TFunction *function);
+ ~TIntermFunctionPrototype() override {}
+
+ TIntermFunctionPrototype *getAsFunctionPrototypeNode() override { return this; }
+ void traverse(TIntermTraverser *it) final;
+ bool visit(Visit visit, TIntermTraverser *it) final;
+
+ size_t getChildCount() const final;
+ TIntermNode *getChildNode(size_t index) const final;
+ bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
+
+ const TType &getType() const override;
+
+ TIntermTyped *deepCopy() const override
+ {
+ UNREACHABLE();
+ return nullptr;
+ }
+ bool hasSideEffects() const override
+ {
+ UNREACHABLE();
+ return true;
+ }
+
+ const TFunction *getFunction() const { return mFunction; }
+
+ protected:
+ const TFunction *const mFunction;
+};
+
+// Node for function definitions. The prototype child node stores the function header including
+// parameters, and the body child node stores the function body.
+class TIntermFunctionDefinition : public TIntermNode
+{
+ public:
+ TIntermFunctionDefinition(TIntermFunctionPrototype *prototype, TIntermBlock *body)
+ : TIntermNode(), mPrototype(prototype), mBody(body)
+ {
+ ASSERT(prototype != nullptr);
+ ASSERT(body != nullptr);
+ }
+
+ TIntermFunctionDefinition *getAsFunctionDefinition() override { return this; }
+ void traverse(TIntermTraverser *it) final;
+ bool visit(Visit visit, TIntermTraverser *it) final;
+
+ size_t getChildCount() const final;
+ TIntermNode *getChildNode(size_t index) const final;
+ bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
+
+ TIntermFunctionPrototype *getFunctionPrototype() const { return mPrototype; }
+ TIntermBlock *getBody() const { return mBody; }
+
+ const TFunction *getFunction() const { return mPrototype->getFunction(); }
+
+ TIntermNode *deepCopy() const override
+ {
+ UNREACHABLE();
+ return nullptr;
+ }
+
+ private:
+ TIntermFunctionPrototype *mPrototype;
+ TIntermBlock *mBody;
+};
+
+// Struct, interface block or variable declaration. Can contain multiple variable declarators.
+class TIntermDeclaration : public TIntermNode, public TIntermAggregateBase
+{
+ public:
+ TIntermDeclaration() : TIntermNode() {}
+ TIntermDeclaration(const TVariable *var, TIntermTyped *initExpr);
+ TIntermDeclaration(std::initializer_list<const TVariable *> declarators);
+ TIntermDeclaration(std::initializer_list<TIntermTyped *> declarators);
+ ~TIntermDeclaration() override {}
+
+ TIntermDeclaration *getAsDeclarationNode() override { return this; }
+ bool visit(Visit visit, TIntermTraverser *it) final;
+
+ size_t getChildCount() const final;
+ TIntermNode *getChildNode(size_t index) const final;
+ bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
+
+ // Only intended for initially building the declaration.
+ // The declarator node should be either TIntermSymbol or TIntermBinary with op set to
+ // EOpInitialize.
+ void appendDeclarator(TIntermTyped *declarator);
+
+ TIntermSequence *getSequence() override { return &mDeclarators; }
+ const TIntermSequence *getSequence() const override { return &mDeclarators; }
+
+ TIntermDeclaration *deepCopy() const override
+ {
+ // Note: This is only useful as support for deepCopy of TIntermBlock and TIntermLoop, but is
+ // not sufficient as it will be redeclaring the same TVariable. If a function body is
+ // duplicated for example, it means that both functions reference the same TVariable pointer
+ // which works, but is technically not correct. In particular, maps with TVariable * as key
+ // can get confused.
+ //
+ // After deepCopy() is issued, ReplaceVariables must be used to replace every declared
+ // variable with a duplicate. This is NOT automatically done when deepCopy-ing TIntermBlock
+ // and TIntermLoop nodes.
+ return new TIntermDeclaration(*this);
+ }
+
+ protected:
+ TIntermDeclaration(const TIntermDeclaration &node);
+
+ TIntermSequence mDeclarators;
+};
+
+// Specialized declarations for attributing invariance.
+class TIntermGlobalQualifierDeclaration : public TIntermNode
+{
+ public:
+ TIntermGlobalQualifierDeclaration(TIntermSymbol *symbol,
+ bool isPrecise,
+ const TSourceLoc &line);
+
+ virtual TIntermGlobalQualifierDeclaration *getAsGlobalQualifierDeclarationNode() override
+ {
+ return this;
+ }
+ bool visit(Visit visit, TIntermTraverser *it) final;
+
+ TIntermSymbol *getSymbol() { return mSymbol; }
+ bool isInvariant() const { return !mIsPrecise; }
+ bool isPrecise() const { return mIsPrecise; }
+
+ size_t getChildCount() const final;
+ TIntermNode *getChildNode(size_t index) const final;
+ bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
+
+ TIntermGlobalQualifierDeclaration *deepCopy() const override
+ {
+ return new TIntermGlobalQualifierDeclaration(*this);
+ }
+
+ private:
+ TIntermSymbol *mSymbol;
+ // Either |precise| or |invariant|, determined based on this flag.
+ bool mIsPrecise;
+
+ TIntermGlobalQualifierDeclaration(const TIntermGlobalQualifierDeclaration &);
+};
+
+// For ternary operators like a ? b : c.
+class TIntermTernary : public TIntermExpression
+{
+ public:
+ TIntermTernary(TIntermTyped *cond, TIntermTyped *trueExpression, TIntermTyped *falseExpression);
+
+ TIntermTernary *getAsTernaryNode() override { return this; }
+ bool visit(Visit visit, TIntermTraverser *it) final;
+
+ size_t getChildCount() const final;
+ TIntermNode *getChildNode(size_t index) const final;
+ bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
+
+ TIntermTyped *getCondition() const { return mCondition; }
+ TIntermTyped *getTrueExpression() const { return mTrueExpression; }
+ TIntermTyped *getFalseExpression() const { return mFalseExpression; }
+
+ TIntermTyped *deepCopy() const override { return new TIntermTernary(*this); }
+
+ bool hasSideEffects() const override
+ {
+ return mCondition->hasSideEffects() || mTrueExpression->hasSideEffects() ||
+ mFalseExpression->hasSideEffects();
+ }
+
+ TIntermTyped *fold(TDiagnostics *diagnostics) override;
+
+ private:
+ TIntermTernary(const TIntermTernary &node); // Note: not deleted, just private!
+
+ static TQualifier DetermineQualifier(TIntermTyped *cond,
+ TIntermTyped *trueExpression,
+ TIntermTyped *falseExpression);
+ TPrecision derivePrecision() const override;
+ void propagatePrecision(TPrecision precision) override;
+
+ TIntermTyped *mCondition;
+ TIntermTyped *mTrueExpression;
+ TIntermTyped *mFalseExpression;
+};
+
+class TIntermIfElse : public TIntermNode
+{
+ public:
+ TIntermIfElse(TIntermTyped *cond, TIntermBlock *trueB, TIntermBlock *falseB);
+
+ TIntermIfElse *getAsIfElseNode() override { return this; }
+ bool visit(Visit visit, TIntermTraverser *it) final;
+
+ size_t getChildCount() const final;
+ TIntermNode *getChildNode(size_t index) const final;
+ bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
+
+ TIntermTyped *getCondition() const { return mCondition; }
+ TIntermBlock *getTrueBlock() const { return mTrueBlock; }
+ TIntermBlock *getFalseBlock() const { return mFalseBlock; }
+
+ TIntermIfElse *deepCopy() const override { return new TIntermIfElse(*this); }
+
+ protected:
+ TIntermTyped *mCondition;
+ TIntermBlock *mTrueBlock;
+ TIntermBlock *mFalseBlock;
+
+ private:
+ TIntermIfElse(const TIntermIfElse &);
+};
+
+//
+// Switch statement.
+//
+class TIntermSwitch : public TIntermNode
+{
+ public:
+ TIntermSwitch(TIntermTyped *init, TIntermBlock *statementList);
+
+ TIntermSwitch *getAsSwitchNode() override { return this; }
+ bool visit(Visit visit, TIntermTraverser *it) final;
+
+ size_t getChildCount() const final;
+ TIntermNode *getChildNode(size_t index) const final;
+ bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
+
+ TIntermTyped *getInit() { return mInit; }
+ TIntermBlock *getStatementList() { return mStatementList; }
+
+ // Must be called with a non-null statementList.
+ void setStatementList(TIntermBlock *statementList);
+
+ TIntermSwitch *deepCopy() const override { return new TIntermSwitch(*this); }
+
+ protected:
+ TIntermTyped *mInit;
+ TIntermBlock *mStatementList;
+
+ private:
+ TIntermSwitch(const TIntermSwitch &);
+};
+
+//
+// Case label.
+//
+class TIntermCase : public TIntermNode
+{
+ public:
+ TIntermCase(TIntermTyped *condition) : TIntermNode(), mCondition(condition) {}
+
+ TIntermCase *getAsCaseNode() override { return this; }
+ bool visit(Visit visit, TIntermTraverser *it) final;
+
+ size_t getChildCount() const final;
+ TIntermNode *getChildNode(size_t index) const final;
+ bool replaceChildNode(TIntermNode *original, TIntermNode *replacement) override;
+
+ bool hasCondition() const { return mCondition != nullptr; }
+ TIntermTyped *getCondition() const { return mCondition; }
+
+ TIntermCase *deepCopy() const override { return new TIntermCase(*this); }
+
+ protected:
+ TIntermTyped *mCondition;
+
+ private:
+ TIntermCase(const TIntermCase &);
+};
+
+//
+// Preprocessor Directive.
+// #ifdef, #define, #if, #endif, etc.
+//
+
+enum class PreprocessorDirective
+{
+ Define,
+ Ifdef,
+ If,
+ Endif,
+};
+
+class TIntermPreprocessorDirective final : public TIntermNode
+{
+ public:
+ // This could also take an ImmutableString as an argument.
+ TIntermPreprocessorDirective(PreprocessorDirective directive, ImmutableString command);
+ ~TIntermPreprocessorDirective() final;
+
+ void traverse(TIntermTraverser *it) final;
+ bool visit(Visit visit, TIntermTraverser *it) final;
+ bool replaceChildNode(TIntermNode *, TIntermNode *) final { return false; }
+
+ TIntermPreprocessorDirective *getAsPreprocessorDirective() final { return this; }
+ size_t getChildCount() const final;
+ TIntermNode *getChildNode(size_t index) const final;
+
+ PreprocessorDirective getDirective() const { return mDirective; }
+ const ImmutableString &getCommand() const { return mCommand; }
+
+ TIntermPreprocessorDirective *deepCopy() const override
+ {
+ return new TIntermPreprocessorDirective(*this);
+ }
+
+ private:
+ PreprocessorDirective mDirective;
+ ImmutableString mCommand;
+
+ TIntermPreprocessorDirective(const TIntermPreprocessorDirective &);
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_INTERMNODE_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/IsASTDepthBelowLimit.cpp b/gfx/angle/checkout/src/compiler/translator/IsASTDepthBelowLimit.cpp
new file mode 100644
index 0000000000..74a1b55807
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/IsASTDepthBelowLimit.cpp
@@ -0,0 +1,37 @@
+//
+// Copyright 2017 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/IsASTDepthBelowLimit.h"
+
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+// Traverse the tree and compute max depth. Takes a maximum depth limit to prevent stack overflow.
+class MaxDepthTraverser : public TIntermTraverser
+{
+ public:
+ MaxDepthTraverser(int depthLimit) : TIntermTraverser(true, false, false, nullptr)
+ {
+ setMaxAllowedDepth(depthLimit);
+ }
+};
+
+} // anonymous namespace
+
+bool IsASTDepthBelowLimit(TIntermNode *root, int maxDepth)
+{
+ MaxDepthTraverser traverser(maxDepth + 1);
+ root->traverse(&traverser);
+
+ return traverser.getMaxDepth() <= maxDepth;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/IsASTDepthBelowLimit.h b/gfx/angle/checkout/src/compiler/translator/IsASTDepthBelowLimit.h
new file mode 100644
index 0000000000..17f85b513a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/IsASTDepthBelowLimit.h
@@ -0,0 +1,20 @@
+//
+// Copyright 2017 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.
+//
+// IsASTDepthBelowLimit: Check whether AST depth is below a specific limit.
+
+#ifndef COMPILER_TRANSLATOR_ISASTDEPTHBELOWLIMIT_H_
+#define COMPILER_TRANSLATOR_ISASTDEPTHBELOWLIMIT_H_
+
+namespace sh
+{
+
+class TIntermNode;
+
+bool IsASTDepthBelowLimit(TIntermNode *root, int maxDepth);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_ISASTDEPTHBELOWLIMIT_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/Operator.cpp b/gfx/angle/checkout/src/compiler/translator/Operator.cpp
new file mode 100644
index 0000000000..3b636ad2af
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/Operator.cpp
@@ -0,0 +1,171 @@
+//
+// Copyright 2002 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/Operator_autogen.h"
+
+#include "common/debug.h"
+
+namespace sh
+{
+
+const char *GetOperatorString(TOperator op)
+{
+ switch (op)
+ {
+ // Note: EOpNull and EOpCall* can't be handled here.
+
+ case EOpNegative:
+ return "-";
+ case EOpPositive:
+ return "+";
+ case EOpLogicalNot:
+ return "!";
+ case EOpBitwiseNot:
+ return "~";
+
+ case EOpPostIncrement:
+ return "++";
+ case EOpPostDecrement:
+ return "--";
+ case EOpPreIncrement:
+ return "++";
+ case EOpPreDecrement:
+ return "--";
+
+ case EOpArrayLength:
+ return ".length()";
+
+ case EOpAdd:
+ return "+";
+ case EOpSub:
+ return "-";
+ case EOpMul:
+ return "*";
+ case EOpDiv:
+ return "/";
+ case EOpIMod:
+ return "%";
+
+ case EOpEqual:
+ return "==";
+ case EOpNotEqual:
+ return "!=";
+ case EOpLessThan:
+ return "<";
+ case EOpGreaterThan:
+ return ">";
+ case EOpLessThanEqual:
+ return "<=";
+ case EOpGreaterThanEqual:
+ return ">=";
+
+ case EOpComma:
+ return ",";
+
+ // Fall-through.
+ case EOpVectorTimesScalar:
+ case EOpVectorTimesMatrix:
+ case EOpMatrixTimesVector:
+ case EOpMatrixTimesScalar:
+ case EOpMatrixTimesMatrix:
+ return "*";
+
+ case EOpLogicalOr:
+ return "||";
+ case EOpLogicalXor:
+ return "^^";
+ case EOpLogicalAnd:
+ return "&&";
+
+ case EOpBitShiftLeft:
+ return "<<";
+ case EOpBitShiftRight:
+ return ">>";
+
+ case EOpBitwiseAnd:
+ return "&";
+ case EOpBitwiseXor:
+ return "^";
+ case EOpBitwiseOr:
+ return "|";
+
+ // Fall-through.
+ case EOpIndexDirect:
+ case EOpIndexIndirect:
+ return "[]";
+
+ case EOpIndexDirectStruct:
+ case EOpIndexDirectInterfaceBlock:
+ return ".";
+
+ case EOpAssign:
+ case EOpInitialize:
+ return "=";
+ case EOpAddAssign:
+ return "+=";
+ case EOpSubAssign:
+ return "-=";
+
+ // Fall-through.
+ case EOpMulAssign:
+ case EOpVectorTimesMatrixAssign:
+ case EOpVectorTimesScalarAssign:
+ case EOpMatrixTimesScalarAssign:
+ case EOpMatrixTimesMatrixAssign:
+ return "*=";
+
+ case EOpDivAssign:
+ return "/=";
+ case EOpIModAssign:
+ return "%=";
+ case EOpBitShiftLeftAssign:
+ return "<<=";
+ case EOpBitShiftRightAssign:
+ return ">>=";
+ case EOpBitwiseAndAssign:
+ return "&=";
+ case EOpBitwiseXorAssign:
+ return "^=";
+ case EOpBitwiseOrAssign:
+ return "|=";
+
+ default:
+ UNREACHABLE();
+ break;
+ }
+ 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;
+ }
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/Operator_autogen.h b/gfx/angle/checkout/src/compiler/translator/Operator_autogen.h
new file mode 100644
index 0000000000..153dcb6339
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/Operator_autogen.h
@@ -0,0 +1,578 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_builtin_symbols.py using data from builtin_function_declarations.txt.
+//
+// Copyright 2021 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.
+//
+// Operator_autogen.h:
+// Operators used by the high-level (parse tree) representation.
+
+#ifndef COMPILER_TRANSLATOR_OPERATOR_AUTOGEN_H_
+#define COMPILER_TRANSLATOR_OPERATOR_AUTOGEN_H_
+
+#include <stdint.h>
+
+namespace sh
+{
+
+enum TOperator : uint16_t
+{
+ EOpNull, // if in a node, should only mean a node is still being built
+
+ // Call a function defined in the AST. This might be a user-defined function or a function
+ // inserted by an AST transformation.
+ EOpCallFunctionInAST,
+
+ // Call an internal helper function with a raw implementation - the implementation can't be
+ // subject to AST transformations. Raw functions have a few constraints to keep them compatible
+ // with AST traversers:
+ // * They should not return arrays.
+ // * They should not have out parameters.
+ //
+ // DEPRECATED; DO NOT USE. TODO: remove this. http://anglebug.com/6059
+ //
+ EOpCallInternalRawFunction,
+
+ //
+ // Branch (TIntermBranch)
+ //
+
+ EOpKill, // Fragment only
+ EOpReturn,
+ EOpBreak,
+ EOpContinue,
+
+ //
+ // Constructor (TIntermAggregate)
+ //
+
+ EOpConstruct,
+
+ //
+ // Unary operators with special GLSL syntax (TIntermUnary).
+ //
+
+ EOpNegative,
+ EOpPositive,
+ EOpLogicalNot,
+ EOpBitwiseNot,
+
+ EOpPostIncrement,
+ EOpPostDecrement,
+ EOpPreIncrement,
+ EOpPreDecrement,
+
+ EOpArrayLength,
+
+ //
+ // Binary operators with special GLSL syntax (TIntermBinary).
+ //
+
+ EOpAdd,
+ EOpSub,
+ EOpMul,
+ EOpDiv,
+ EOpIMod,
+
+ EOpEqual,
+ EOpNotEqual,
+ EOpLessThan,
+ EOpGreaterThan,
+ EOpLessThanEqual,
+ EOpGreaterThanEqual,
+
+ EOpComma,
+
+ EOpVectorTimesScalar,
+ EOpVectorTimesMatrix,
+ EOpMatrixTimesVector,
+ EOpMatrixTimesScalar,
+ EOpMatrixTimesMatrix,
+
+ EOpLogicalOr,
+ EOpLogicalXor,
+ EOpLogicalAnd,
+
+ EOpBitShiftLeft,
+ EOpBitShiftRight,
+
+ EOpBitwiseAnd,
+ EOpBitwiseXor,
+ EOpBitwiseOr,
+
+ EOpIndexDirect,
+ EOpIndexIndirect,
+ EOpIndexDirectStruct,
+ EOpIndexDirectInterfaceBlock,
+
+ //
+ // Moves (TIntermBinary)
+ //
+
+ EOpAssign,
+ EOpInitialize,
+ EOpAddAssign,
+ EOpSubAssign,
+
+ EOpMulAssign,
+ EOpVectorTimesMatrixAssign,
+ EOpVectorTimesScalarAssign,
+ EOpMatrixTimesScalarAssign,
+ EOpMatrixTimesMatrixAssign,
+
+ EOpDivAssign,
+ EOpIModAssign,
+ EOpBitShiftLeftAssign,
+ EOpBitShiftRightAssign,
+ EOpBitwiseAndAssign,
+ EOpBitwiseXorAssign,
+ EOpBitwiseOrAssign,
+
+ // Not an op, but a marker for the start of built-in ops.
+ EOpLastNonBuiltIn = EOpBitwiseOrAssign,
+
+ //
+ // Built-in functions mapped to operators (either unary (TIntermUnary) or with multiple
+ // parameters (TIntermAggregate))
+ //
+
+ // Group Math
+
+ // Group MathTrigonometric
+ EOpRadians, // Unary
+ EOpDegrees, // Unary
+ EOpSin, // Unary
+ EOpCos, // Unary
+ EOpTan, // Unary
+ EOpAsin, // Unary
+ EOpAcos, // Unary
+ EOpAtan,
+ EOpSinh, // Unary
+ EOpCosh, // Unary
+ EOpTanh, // Unary
+ EOpAsinh, // Unary
+ EOpAcosh, // Unary
+ EOpAtanh, // Unary
+
+ // Group MathExponential
+ EOpPow,
+ EOpExp, // Unary
+ EOpLog, // Unary
+ EOpExp2, // Unary
+ EOpLog2, // Unary
+ EOpSqrt, // Unary
+ EOpInversesqrt, // Unary
+
+ // Group MathCommon
+ EOpAbs, // Unary
+ EOpSign, // Unary
+ EOpFloor, // Unary
+ EOpTrunc, // Unary
+ EOpRound, // Unary
+ EOpRoundEven, // Unary
+ EOpCeil, // Unary
+ EOpFract, // Unary
+ EOpMod,
+ EOpMin,
+ EOpMax,
+ EOpClamp,
+ EOpMix,
+ EOpStep,
+ EOpSmoothstep,
+ EOpModf,
+ EOpIsnan, // Unary
+ EOpIsinf, // Unary
+ EOpFloatBitsToInt, // Unary
+ EOpFloatBitsToUint, // Unary
+ EOpIntBitsToFloat, // Unary
+ EOpUintBitsToFloat, // Unary
+ EOpFma,
+ EOpFrexp,
+ EOpLdexp,
+ EOpPackSnorm2x16, // Unary
+ EOpPackHalf2x16, // Unary
+ EOpUnpackSnorm2x16, // Unary
+ EOpUnpackHalf2x16, // Unary
+ EOpPackUnorm2x16, // Unary
+ EOpUnpackUnorm2x16, // Unary
+ EOpPackUnorm4x8, // Unary
+ EOpPackSnorm4x8, // Unary
+ EOpUnpackUnorm4x8, // Unary
+ EOpUnpackSnorm4x8, // Unary
+ EOpPackDouble2x32, // Unary
+ EOpUnpackDouble2x32, // Unary
+
+ // Group MathGeometric
+ EOpLength, // Unary
+ EOpDistance,
+ EOpDot,
+ EOpCross,
+ EOpNormalize, // Unary
+ EOpFaceforward,
+ EOpReflect,
+ EOpRefract,
+
+ // Group MathGeometricVS
+ EOpFtransform,
+
+ // Group MathMatrix
+ EOpMatrixCompMult,
+ EOpOuterProduct,
+ EOpTranspose, // Unary
+ EOpDeterminant, // Unary
+ EOpInverse, // Unary
+
+ // Group MathVector
+ EOpLessThanComponentWise,
+ EOpLessThanEqualComponentWise,
+ EOpGreaterThanComponentWise,
+ EOpGreaterThanEqualComponentWise,
+ EOpEqualComponentWise,
+ EOpNotEqualComponentWise,
+ EOpAny, // Unary
+ EOpAll, // Unary
+ EOpNotComponentWise, // Unary
+
+ // Group MathInteger
+ EOpBitfieldExtract,
+ EOpBitfieldInsert,
+ EOpBitfieldReverse, // Unary
+ EOpBitCount, // Unary
+ EOpFindLSB, // Unary
+ EOpFindMSB, // Unary
+ EOpUaddCarry,
+ EOpUsubBorrow,
+ EOpUmulExtended,
+ EOpImulExtended,
+
+ // Group Texture
+
+ // Group TextureFirstVersions
+ EOpTexture2D,
+ EOpTexture2DProj,
+ EOpTextureCube,
+ EOpTexture1D,
+ EOpTexture1DProj,
+ EOpTexture3D,
+ EOpTexture3DProj,
+ EOpShadow1D,
+ EOpShadow1DProj,
+ EOpShadow2D,
+ EOpShadow2DProj,
+ EOpShadow2DEXT,
+ EOpShadow2DProjEXT,
+ EOpTexture2DRect,
+ EOpTexture2DRectProj,
+ EOpTexture2DGradEXT,
+ EOpTexture2DProjGradEXT,
+ EOpTextureCubeGradEXT,
+ EOpTextureVideoWEBGL,
+
+ // Group TextureFirstVersionsBias
+ EOpTexture2DBias,
+ EOpTexture2DProjBias,
+ EOpTextureCubeBias,
+ EOpTexture3DBias,
+ EOpTexture3DProjBias,
+ EOpTexture1DBias,
+ EOpTexture1DProjBias,
+ EOpShadow1DBias,
+ EOpShadow1DProjBias,
+ EOpShadow2DBias,
+ EOpShadow2DProjBias,
+
+ // Group TextureFirstVersionsLod
+ EOpTexture2DLod,
+ EOpTexture2DProjLod,
+ EOpTextureCubeLod,
+ EOpTexture1DLod,
+ EOpTexture1DProjLod,
+ EOpShadow1DLod,
+ EOpShadow1DProjLod,
+ EOpShadow2DLod,
+ EOpShadow2DProjLod,
+ EOpTexture3DLod,
+ EOpTexture3DProjLod,
+
+ // Group TextureFirstVersionsLodVS
+ EOpTexture2DLodVS,
+ EOpTexture2DProjLodVS,
+ EOpTextureCubeLodVS,
+
+ // Group TextureFirstVersionsLodFS
+ EOpTexture2DLodEXTFS,
+ EOpTexture2DProjLodEXTFS,
+ EOpTextureCubeLodEXTFS,
+
+ // Group TextureNoBias
+ EOpTexture,
+ EOpTextureProj,
+ EOpTextureLod,
+ EOpTextureSize,
+ EOpTextureProjLod,
+ EOpTexelFetch,
+ EOpTextureGrad,
+ EOpTextureProjGrad,
+ EOpTextureQueryLevels,
+ EOpTextureSamples,
+
+ // Group TextureBias
+ EOpTextureBias,
+ EOpTextureProjBias,
+
+ // Group TextureQueryLod
+ EOpTextureQueryLod,
+
+ // Group TextureOffsetNoBias
+ EOpTextureOffset,
+ EOpTextureProjOffset,
+ EOpTextureLodOffset,
+ EOpTextureProjLodOffset,
+ EOpTexelFetchOffset,
+ EOpTextureGradOffset,
+ EOpTextureProjGradOffset,
+
+ // Group TextureOffsetBias
+ EOpTextureOffsetBias,
+ EOpTextureProjOffsetBias,
+
+ // Group TextureGather
+ EOpTextureGather,
+
+ // Group TextureGatherOffset
+
+ // Group TextureGatherOffsetNoComp
+ EOpTextureGatherOffset,
+
+ // Group TextureGatherOffsetComp
+ EOpTextureGatherOffsetComp,
+
+ // Group TextureGatherOffsets
+
+ // Group TextureGatherOffsetsNoComp
+ EOpTextureGatherOffsets,
+
+ // Group TextureGatherOffsetsComp
+ EOpTextureGatherOffsetsComp,
+
+ // Group EXT_YUV_target
+ EOpRgb_2_yuv,
+ EOpYuv_2_rgb,
+
+ // Group DerivativesFS
+ EOpDFdx,
+ EOpDFdy,
+ EOpFwidth,
+ EOpDFdxFine,
+ EOpDFdyFine,
+ EOpDFdxCoarse,
+ EOpDFdyCoarse,
+ EOpFwidthFine,
+ EOpFwidthCoarse,
+
+ // Group InterpolationFS
+ EOpInterpolateAtCentroid,
+ EOpInterpolateAtSample,
+ EOpInterpolateAtOffset,
+
+ // Group AtomicCounter
+ EOpAtomicCounter,
+ EOpAtomicCounterIncrement,
+ EOpAtomicCounterDecrement,
+ EOpAtomicCounterAdd,
+ EOpAtomicCounterSubtract,
+ EOpAtomicCounterMin,
+ EOpAtomicCounterMax,
+ EOpAtomicCounterAnd,
+ EOpAtomicCounterOr,
+ EOpAtomicCounterXor,
+ EOpAtomicCounterExchange,
+ EOpAtomicCounterCompSwap,
+
+ // Group AtomicMemory
+ EOpAtomicAdd,
+ EOpAtomicMin,
+ EOpAtomicMax,
+ EOpAtomicAnd,
+ EOpAtomicOr,
+ EOpAtomicXor,
+ EOpAtomicExchange,
+ EOpAtomicCompSwap,
+
+ // Group Image
+ EOpImageSize,
+ EOpImageSamples,
+
+ // Group ImageStore
+ EOpImageStore,
+
+ // Group ImageLoad
+ EOpImageLoad,
+
+ // Group ImageAtomic
+ EOpImageAtomicAdd,
+ EOpImageAtomicMin,
+ EOpImageAtomicMax,
+ EOpImageAtomicAnd,
+ EOpImageAtomicOr,
+ EOpImageAtomicXor,
+ EOpImageAtomicExchange,
+ EOpImageAtomicCompSwap,
+
+ // Group PixelLocal
+
+ // Group PixelLocalLoad
+ EOpPixelLocalLoadANGLE,
+
+ // Group PixelLocalStore
+ EOpPixelLocalStoreANGLE,
+
+ // Group FragmentSynchronization
+ EOpBeginInvocationInterlockNV,
+ EOpEndInvocationInterlockNV,
+ EOpBeginFragmentShaderOrderingINTEL,
+ EOpBeginInvocationInterlockARB,
+ EOpEndInvocationInterlockARB,
+
+ // Group Noise
+ EOpNoise1,
+ EOpNoise2,
+ EOpNoise3,
+ EOpNoise4,
+
+ // Group Barrier
+ EOpMemoryBarrier,
+ EOpMemoryBarrierAtomicCounter,
+ EOpMemoryBarrierBuffer,
+ EOpMemoryBarrierImage,
+
+ // Group ESSL310CS
+ EOpBarrier,
+ EOpMemoryBarrierShared,
+ EOpGroupMemoryBarrier,
+
+ // Group ESSL310TCS
+ EOpBarrierTCS,
+
+ // Group GS
+ EOpEmitVertex,
+ EOpEndPrimitive,
+ EOpEmitStreamVertex,
+ EOpEndStreamPrimitive,
+
+ // Group SubpassInput
+ EOpSubpassLoad,
+
+ // Group ShaderInvocationGroup
+ EOpAnyInvocation,
+ EOpAllInvocations,
+ EOpAllInvocationsEqual,
+};
+
+// Returns the string corresponding to the operator in GLSL. For built-in functions use the
+// function name directly.
+const char *GetOperatorString(TOperator op);
+
+// Say whether or not a binary or unary operation changes the value of a variable.
+bool IsAssignment(TOperator op);
+
+namespace BuiltInGroup
+{
+static inline bool IsBuiltIn(TOperator op)
+{
+ return op > EOpLastNonBuiltIn;
+}
+static inline bool IsMath(TOperator op)
+{
+ return op >= EOpRadians && op <= EOpImulExtended;
+}
+static inline bool IsTextureOffsetNoBias(TOperator op)
+{
+ return op >= EOpTextureOffset && op <= EOpTextureProjGradOffset;
+}
+static inline bool IsTextureOffsetBias(TOperator op)
+{
+ return op >= EOpTextureOffsetBias && op <= EOpTextureProjOffsetBias;
+}
+static inline bool IsTextureGatherOffsetNoComp(TOperator op)
+{
+ return op >= EOpTextureGatherOffset && op <= EOpTextureGatherOffset;
+}
+static inline bool IsTextureGatherOffsetComp(TOperator op)
+{
+ return op >= EOpTextureGatherOffsetComp && op <= EOpTextureGatherOffsetComp;
+}
+static inline bool IsTextureGatherOffset(TOperator op)
+{
+ return op >= EOpTextureGatherOffset && op <= EOpTextureGatherOffsetComp;
+}
+static inline bool IsTextureGatherOffsetsNoComp(TOperator op)
+{
+ return op >= EOpTextureGatherOffsets && op <= EOpTextureGatherOffsets;
+}
+static inline bool IsTextureGatherOffsetsComp(TOperator op)
+{
+ return op >= EOpTextureGatherOffsetsComp && op <= EOpTextureGatherOffsetsComp;
+}
+static inline bool IsTextureGatherOffsets(TOperator op)
+{
+ return op >= EOpTextureGatherOffsets && op <= EOpTextureGatherOffsetsComp;
+}
+static inline bool IsTextureGather(TOperator op)
+{
+ return op >= EOpTextureGather && op <= EOpTextureGatherOffsetsComp;
+}
+static inline bool IsTexture(TOperator op)
+{
+ return op >= EOpTexture2D && op <= EOpTextureGatherOffsetsComp;
+}
+static inline bool IsDerivativesFS(TOperator op)
+{
+ return op >= EOpDFdx && op <= EOpFwidthCoarse;
+}
+static inline bool IsInterpolationFS(TOperator op)
+{
+ return op >= EOpInterpolateAtCentroid && op <= EOpInterpolateAtOffset;
+}
+static inline bool IsAtomicCounter(TOperator op)
+{
+ return op >= EOpAtomicCounter && op <= EOpAtomicCounterCompSwap;
+}
+static inline bool IsAtomicMemory(TOperator op)
+{
+ return op >= EOpAtomicAdd && op <= EOpAtomicCompSwap;
+}
+static inline bool IsImageStore(TOperator op)
+{
+ return op >= EOpImageStore && op <= EOpImageStore;
+}
+static inline bool IsImageLoad(TOperator op)
+{
+ return op >= EOpImageLoad && op <= EOpImageLoad;
+}
+static inline bool IsImageAtomic(TOperator op)
+{
+ return op >= EOpImageAtomicAdd && op <= EOpImageAtomicCompSwap;
+}
+static inline bool IsImage(TOperator op)
+{
+ return op >= EOpImageSize && op <= EOpImageAtomicCompSwap;
+}
+static inline bool IsPixelLocalLoad(TOperator op)
+{
+ return op >= EOpPixelLocalLoadANGLE && op <= EOpPixelLocalLoadANGLE;
+}
+static inline bool IsPixelLocalStore(TOperator op)
+{
+ return op >= EOpPixelLocalStoreANGLE && op <= EOpPixelLocalStoreANGLE;
+}
+static inline bool IsPixelLocal(TOperator op)
+{
+ return op >= EOpPixelLocalLoadANGLE && op <= EOpPixelLocalStoreANGLE;
+}
+} // namespace BuiltInGroup
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_OPERATOR_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/OutputESSL.cpp b/gfx/angle/checkout/src/compiler/translator/OutputESSL.cpp
new file mode 100644
index 0000000000..95c7e1e0be
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/OutputESSL.cpp
@@ -0,0 +1,55 @@
+//
+// Copyright 2002 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/OutputESSL.h"
+
+namespace sh
+{
+
+TOutputESSL::TOutputESSL(TCompiler *compiler,
+ TInfoSinkBase &objSink,
+ const ShCompileOptions &compileOptions)
+ : TOutputGLSLBase(compiler, objSink, compileOptions)
+{}
+
+bool TOutputESSL::writeVariablePrecision(TPrecision precision)
+{
+ if (precision == EbpUndefined)
+ return false;
+
+ if (precision == EbpHigh && !isHighPrecisionSupported())
+ {
+ precision = EbpMedium;
+ }
+
+ TInfoSinkBase &out = objSink();
+ out << getPrecisionString(precision);
+ return true;
+}
+
+ImmutableString TOutputESSL::translateTextureFunction(const ImmutableString &name,
+ const ShCompileOptions &option)
+{
+ // Check WEBGL_video_texture invocation first.
+ if (name == "textureVideoWEBGL")
+ {
+ if (option.takeVideoTextureAsExternalOES)
+ {
+ // TODO(http://anglebug.com/3889): Implement external image situation.
+ UNIMPLEMENTED();
+ return ImmutableString("");
+ }
+ else
+ {
+ // Default translating textureVideoWEBGL to texture2D.
+ return ImmutableString("texture2D");
+ }
+ }
+
+ return name;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/OutputESSL.h b/gfx/angle/checkout/src/compiler/translator/OutputESSL.h
new file mode 100644
index 0000000000..9d14de2081
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/OutputESSL.h
@@ -0,0 +1,30 @@
+//
+// Copyright 2002 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_OUTPUTESSL_H_
+#define COMPILER_TRANSLATOR_OUTPUTESSL_H_
+
+#include "compiler/translator/OutputGLSLBase.h"
+
+namespace sh
+{
+
+class TOutputESSL : public TOutputGLSLBase
+{
+ public:
+ TOutputESSL(TCompiler *compiler,
+ TInfoSinkBase &objSink,
+ const ShCompileOptions &compileOptions);
+
+ protected:
+ bool writeVariablePrecision(TPrecision precision) override;
+ ImmutableString translateTextureFunction(const ImmutableString &name,
+ const ShCompileOptions &option) override;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_OUTPUTESSL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/OutputGLSL.cpp b/gfx/angle/checkout/src/compiler/translator/OutputGLSL.cpp
new file mode 100644
index 0000000000..0045a76dfc
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/OutputGLSL.cpp
@@ -0,0 +1,122 @@
+//
+// Copyright 2002 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/OutputGLSL.h"
+
+#include "compiler/translator/Compiler.h"
+
+namespace sh
+{
+
+TOutputGLSL::TOutputGLSL(TCompiler *compiler,
+ TInfoSinkBase &objSink,
+ const ShCompileOptions &compileOptions)
+ : TOutputGLSLBase(compiler, objSink, compileOptions)
+{}
+
+bool TOutputGLSL::writeVariablePrecision(TPrecision)
+{
+ return false;
+}
+
+void TOutputGLSL::visitSymbol(TIntermSymbol *node)
+{
+ TInfoSinkBase &out = objSink();
+
+ // All the special cases are built-ins, so if it's not a built-in we can return early.
+ if (node->variable().symbolType() != SymbolType::BuiltIn)
+ {
+ TOutputGLSLBase::visitSymbol(node);
+ return;
+ }
+
+ // Some built-ins get a special translation.
+ const ImmutableString &name = node->getName();
+ if (name == "gl_FragDepthEXT")
+ {
+ out << "gl_FragDepth";
+ }
+ else if (name == "gl_FragColor" && sh::IsGLSL130OrNewer(getShaderOutput()))
+ {
+ out << "webgl_FragColor";
+ }
+ else if (name == "gl_FragData" && sh::IsGLSL130OrNewer(getShaderOutput()))
+ {
+ out << "webgl_FragData";
+ }
+ else if (name == "gl_SecondaryFragColorEXT")
+ {
+ out << "webgl_SecondaryFragColor";
+ }
+ else if (name == "gl_SecondaryFragDataEXT")
+ {
+ out << "webgl_SecondaryFragData";
+ }
+ else
+ {
+ TOutputGLSLBase::visitSymbol(node);
+ }
+}
+
+ImmutableString TOutputGLSL::translateTextureFunction(const ImmutableString &name,
+ const ShCompileOptions &option)
+{
+ // Check WEBGL_video_texture invocation first.
+ if (name == "textureVideoWEBGL")
+ {
+ if (option.takeVideoTextureAsExternalOES)
+ {
+ // TODO(http://anglebug.com/3889): Implement external image situation.
+ UNIMPLEMENTED();
+ return ImmutableString("");
+ }
+ else
+ {
+ // Default translating textureVideoWEBGL to texture2D.
+ return ImmutableString("texture2D");
+ }
+ }
+
+ static const char *simpleRename[] = {"texture2DLodEXT",
+ "texture2DLod",
+ "texture2DProjLodEXT",
+ "texture2DProjLod",
+ "textureCubeLodEXT",
+ "textureCubeLod",
+ "texture2DGradEXT",
+ "texture2DGradARB",
+ "texture2DProjGradEXT",
+ "texture2DProjGradARB",
+ "textureCubeGradEXT",
+ "textureCubeGradARB",
+ nullptr,
+ nullptr};
+ static const char *legacyToCoreRename[] = {
+ "texture2D", "texture", "texture2DProj", "textureProj", "texture2DLod", "textureLod",
+ "texture2DProjLod", "textureProjLod", "texture2DRect", "texture", "texture2DRectProj",
+ "textureProj", "textureCube", "texture", "textureCubeLod", "textureLod",
+ // Extensions
+ "texture2DLodEXT", "textureLod", "texture2DProjLodEXT", "textureProjLod",
+ "textureCubeLodEXT", "textureLod", "texture2DGradEXT", "textureGrad",
+ "texture2DProjGradEXT", "textureProjGrad", "textureCubeGradEXT", "textureGrad", "texture3D",
+ "texture", "texture3DProj", "textureProj", "texture3DLod", "textureLod", "texture3DProjLod",
+ "textureProjLod", "shadow2DEXT", "texture", "shadow2DProjEXT", "textureProj", nullptr,
+ nullptr};
+ const char **mapping =
+ (sh::IsGLSL130OrNewer(getShaderOutput())) ? legacyToCoreRename : simpleRename;
+
+ for (int i = 0; mapping[i] != nullptr; i += 2)
+ {
+ if (name == mapping[i])
+ {
+ return ImmutableString(mapping[i + 1]);
+ }
+ }
+
+ return name;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/OutputGLSL.h b/gfx/angle/checkout/src/compiler/translator/OutputGLSL.h
new file mode 100644
index 0000000000..ff55e16a2a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/OutputGLSL.h
@@ -0,0 +1,31 @@
+//
+// Copyright 2002 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_OUTPUTGLSL_H_
+#define COMPILER_TRANSLATOR_OUTPUTGLSL_H_
+
+#include "compiler/translator/OutputGLSLBase.h"
+
+namespace sh
+{
+
+class TOutputGLSL : public TOutputGLSLBase
+{
+ public:
+ TOutputGLSL(TCompiler *compiler,
+ TInfoSinkBase &objSink,
+ const ShCompileOptions &compileOptions);
+
+ protected:
+ bool writeVariablePrecision(TPrecision) override;
+ void visitSymbol(TIntermSymbol *node) override;
+ ImmutableString translateTextureFunction(const ImmutableString &name,
+ const ShCompileOptions &option) override;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_OUTPUTGLSL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/OutputGLSLBase.cpp b/gfx/angle/checkout/src/compiler/translator/OutputGLSLBase.cpp
new file mode 100644
index 0000000000..9536fe1d03
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/OutputGLSLBase.cpp
@@ -0,0 +1,1513 @@
+//
+// Copyright 2002 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/OutputGLSLBase.h"
+
+#include "angle_gl.h"
+#include "common/debug.h"
+#include "common/mathutil.h"
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/util.h"
+
+#include <cfloat>
+
+namespace sh
+{
+
+namespace
+{
+
+bool isSingleStatement(TIntermNode *node)
+{
+ if (node->getAsFunctionDefinition())
+ {
+ return false;
+ }
+ else if (node->getAsBlock())
+ {
+ return false;
+ }
+ else if (node->getAsIfElseNode())
+ {
+ return false;
+ }
+ else if (node->getAsLoopNode())
+ {
+ return false;
+ }
+ else if (node->getAsSwitchNode())
+ {
+ return false;
+ }
+ else if (node->getAsCaseNode())
+ {
+ return false;
+ }
+ else if (node->getAsPreprocessorDirective())
+ {
+ return false;
+ }
+ return true;
+}
+
+class CommaSeparatedListItemPrefixGenerator
+{
+ public:
+ CommaSeparatedListItemPrefixGenerator() : mFirst(true) {}
+
+ private:
+ bool mFirst;
+
+ template <typename Stream>
+ friend Stream &operator<<(Stream &out, CommaSeparatedListItemPrefixGenerator &gen);
+};
+
+template <typename Stream>
+Stream &operator<<(Stream &out, CommaSeparatedListItemPrefixGenerator &gen)
+{
+ if (gen.mFirst)
+ {
+ gen.mFirst = false;
+ }
+ else
+ {
+ out << ", ";
+ }
+ return out;
+}
+
+} // namespace
+
+TOutputGLSLBase::TOutputGLSLBase(TCompiler *compiler,
+ TInfoSinkBase &objSink,
+ const ShCompileOptions &compileOptions)
+ : TIntermTraverser(true, true, true, &compiler->getSymbolTable()),
+ mObjSink(objSink),
+ mDeclaringVariable(false),
+ mHashFunction(compiler->getHashFunction()),
+ mNameMap(compiler->getNameMap()),
+ mShaderType(compiler->getShaderType()),
+ mShaderVersion(compiler->getShaderVersion()),
+ mOutput(compiler->getOutputType()),
+ mHighPrecisionSupported(compiler->isHighPrecisionSupported()),
+ // If pixel local storage introduces new fragment outputs, we are now required to specify a
+ // location for _all_ fragment outputs, including previously valid outputs that had an
+ // implicit location of zero.
+ mAlwaysSpecifyFragOutLocation(compiler->hasPixelLocalStorageUniforms() &&
+ compileOptions.pls.type ==
+ ShPixelLocalStorageType::FramebufferFetch),
+ mCompileOptions(compileOptions)
+{}
+
+void TOutputGLSLBase::writeInvariantQualifier(const TType &type)
+{
+ if (!sh::RemoveInvariant(mShaderType, mShaderVersion, mOutput, mCompileOptions))
+ {
+ TInfoSinkBase &out = objSink();
+ out << "invariant ";
+ }
+}
+
+void TOutputGLSLBase::writePreciseQualifier(const TType &type)
+{
+ TInfoSinkBase &out = objSink();
+ out << "precise ";
+}
+
+void TOutputGLSLBase::writeFloat(TInfoSinkBase &out, float f)
+{
+ if ((gl::isInf(f) || gl::isNaN(f)) && mShaderVersion >= 300)
+ {
+ out << "uintBitsToFloat(" << gl::bitCast<uint32_t>(f) << "u)";
+ }
+ else
+ {
+ out << std::min(FLT_MAX, std::max(-FLT_MAX, f));
+ }
+}
+
+void TOutputGLSLBase::writeTriplet(Visit visit,
+ const char *preStr,
+ const char *inStr,
+ const char *postStr)
+{
+ TInfoSinkBase &out = objSink();
+ if (visit == PreVisit && preStr)
+ out << preStr;
+ else if (visit == InVisit && inStr)
+ out << inStr;
+ else if (visit == PostVisit && postStr)
+ out << postStr;
+}
+
+void TOutputGLSLBase::writeFunctionTriplet(Visit visit,
+ const ImmutableString &functionName,
+ bool useEmulatedFunction)
+{
+ TInfoSinkBase &out = objSink();
+ if (visit == PreVisit)
+ {
+ if (useEmulatedFunction)
+ {
+ BuiltInFunctionEmulator::WriteEmulatedFunctionName(out, functionName.data());
+ }
+ else
+ {
+ out << functionName;
+ }
+ out << "(";
+ }
+ else
+ {
+ writeTriplet(visit, nullptr, ", ", ")");
+ }
+}
+
+// Outputs what goes inside layout(), except for location and binding qualifiers, as they are
+// handled differently between GL GLSL and Vulkan GLSL.
+std::string TOutputGLSLBase::getCommonLayoutQualifiers(TIntermSymbol *variable)
+{
+ std::ostringstream out;
+ CommaSeparatedListItemPrefixGenerator listItemPrefix;
+
+ const TType &type = variable->getType();
+ const TLayoutQualifier &layoutQualifier = type.getLayoutQualifier();
+
+ if (type.getQualifier() == EvqFragmentOut || type.getQualifier() == EvqFragmentInOut)
+ {
+ if (layoutQualifier.index >= 0)
+ {
+ out << listItemPrefix << "index = " << layoutQualifier.index;
+ }
+ if (layoutQualifier.yuv)
+ {
+ out << listItemPrefix << "yuv";
+ }
+ }
+
+ if (type.getQualifier() == EvqFragmentInOut && layoutQualifier.noncoherent)
+ {
+ out << listItemPrefix << "noncoherent";
+ }
+
+ if (IsImage(type.getBasicType()))
+ {
+ if (layoutQualifier.imageInternalFormat != EiifUnspecified)
+ {
+ ASSERT(type.getQualifier() == EvqTemporary || type.getQualifier() == EvqUniform);
+ out << listItemPrefix
+ << getImageInternalFormatString(layoutQualifier.imageInternalFormat);
+ }
+ }
+
+ if (IsAtomicCounter(type.getBasicType()))
+ {
+ out << listItemPrefix << "offset = " << layoutQualifier.offset;
+ }
+
+ return out.str();
+}
+
+// Outputs memory qualifiers applied to images, buffers and its fields, as well as image function
+// arguments.
+std::string TOutputGLSLBase::getMemoryQualifiers(const TType &type)
+{
+ std::ostringstream out;
+
+ const TMemoryQualifier &memoryQualifier = type.getMemoryQualifier();
+ if (memoryQualifier.readonly)
+ {
+ out << "readonly ";
+ }
+
+ if (memoryQualifier.writeonly)
+ {
+ out << "writeonly ";
+ }
+
+ if (memoryQualifier.coherent)
+ {
+ out << "coherent ";
+ }
+
+ if (memoryQualifier.restrictQualifier)
+ {
+ out << "restrict ";
+ }
+
+ if (memoryQualifier.volatileQualifier)
+ {
+ out << "volatile ";
+ }
+
+ return out.str();
+}
+
+void TOutputGLSLBase::writeLayoutQualifier(TIntermSymbol *variable)
+{
+ const TType &type = variable->getType();
+
+ if (!needsToWriteLayoutQualifier(type))
+ {
+ return;
+ }
+
+ if (type.getBasicType() == EbtInterfaceBlock)
+ {
+ declareInterfaceBlockLayout(type);
+ return;
+ }
+
+ TInfoSinkBase &out = objSink();
+ const TLayoutQualifier &layoutQualifier = type.getLayoutQualifier();
+ out << "layout(";
+
+ CommaSeparatedListItemPrefixGenerator listItemPrefix;
+
+ if (IsFragmentOutput(type.getQualifier()) || type.getQualifier() == EvqVertexIn ||
+ IsVarying(type.getQualifier()))
+ {
+ if (layoutQualifier.location >= 0 ||
+ (mAlwaysSpecifyFragOutLocation && IsFragmentOutput(type.getQualifier())))
+ {
+ out << listItemPrefix << "location = " << std::max(layoutQualifier.location, 0);
+ }
+ }
+
+ if (IsOpaqueType(type.getBasicType()))
+ {
+ if (layoutQualifier.binding >= 0)
+ {
+ out << listItemPrefix << "binding = " << layoutQualifier.binding;
+ }
+ }
+
+ std::string otherQualifiers = getCommonLayoutQualifiers(variable);
+ if (!otherQualifiers.empty())
+ {
+ out << listItemPrefix << otherQualifiers;
+ }
+
+ out << ") ";
+}
+
+void TOutputGLSLBase::writeFieldLayoutQualifier(const TField *field)
+{
+ if (!field->type()->isMatrix() && !field->type()->isStructureContainingMatrices())
+ {
+ return;
+ }
+
+ TInfoSinkBase &out = objSink();
+
+ out << "layout(";
+ switch (field->type()->getLayoutQualifier().matrixPacking)
+ {
+ case EmpUnspecified:
+ case EmpColumnMajor:
+ // Default matrix packing is column major.
+ out << "column_major";
+ break;
+
+ case EmpRowMajor:
+ out << "row_major";
+ break;
+
+ default:
+ UNREACHABLE();
+ break;
+ }
+ out << ") ";
+}
+
+void TOutputGLSLBase::writeQualifier(TQualifier qualifier, const TType &type, const TSymbol *symbol)
+{
+ const char *result = mapQualifierToString(qualifier);
+ if (result && result[0] != '\0')
+ {
+ objSink() << result << " ";
+ }
+
+ objSink() << getMemoryQualifiers(type);
+}
+
+const char *TOutputGLSLBase::mapQualifierToString(TQualifier qualifier)
+{
+ if (sh::IsGLSL410OrOlder(mOutput) && mShaderVersion >= 300 &&
+ mCompileOptions.removeInvariantAndCentroidForESSL3)
+ {
+ switch (qualifier)
+ {
+ // The return string is consistent with sh::getQualifierString() from
+ // BaseTypes.h minus the "centroid" keyword.
+ case EvqCentroid:
+ return "";
+ case EvqCentroidIn:
+ return "smooth in";
+ case EvqCentroidOut:
+ return "smooth out";
+ default:
+ break;
+ }
+ }
+ if (sh::IsGLSL130OrNewer(mOutput))
+ {
+ switch (qualifier)
+ {
+ case EvqAttribute:
+ return "in";
+ case EvqVaryingIn:
+ return "in";
+ case EvqVaryingOut:
+ return "out";
+ default:
+ break;
+ }
+ }
+
+ switch (qualifier)
+ {
+ // gl_ClipDistance / gl_CullDistance require different qualifiers based on shader type.
+ case EvqClipDistance:
+ case EvqCullDistance:
+ return mShaderType == GL_FRAGMENT_SHADER ? "in" : "out";
+
+ // gl_LastFragColor / gl_LastFragData have no qualifiers.
+ case EvqLastFragData:
+ case EvqLastFragColor:
+ return nullptr;
+
+ default:
+ return sh::getQualifierString(qualifier);
+ }
+}
+
+namespace
+{
+
+constexpr char kIndent[] = " "; // 10x2 spaces
+constexpr int kIndentWidth = 2;
+constexpr int kMaxIndentLevel = sizeof(kIndent) / kIndentWidth;
+
+} // namespace
+
+const char *TOutputGLSLBase::getIndentPrefix(int extraIndentation)
+{
+ int indentDepth = std::min(kMaxIndentLevel, getCurrentBlockDepth() + extraIndentation);
+ ASSERT(indentDepth >= 0);
+ return kIndent + (kMaxIndentLevel - indentDepth) * kIndentWidth;
+}
+
+void TOutputGLSLBase::writeVariableType(const TType &type,
+ const TSymbol *symbol,
+ bool isFunctionArgument)
+{
+ TQualifier qualifier = type.getQualifier();
+ TInfoSinkBase &out = objSink();
+ if (type.isInvariant())
+ {
+ writeInvariantQualifier(type);
+ }
+ if (type.isPrecise())
+ {
+ writePreciseQualifier(type);
+ }
+ if (qualifier != EvqTemporary && qualifier != EvqGlobal)
+ {
+ writeQualifier(qualifier, type, symbol);
+ }
+ if (isFunctionArgument)
+ {
+ // Function arguments are the only place (other than image/SSBO/field declaration) where
+ // memory qualifiers can appear.
+ out << getMemoryQualifiers(type);
+ }
+
+ // Declare the struct.
+ if (type.isStructSpecifier())
+ {
+ const TStructure *structure = type.getStruct();
+
+ declareStruct(structure);
+ }
+ else if (type.getBasicType() == EbtInterfaceBlock)
+ {
+ declareInterfaceBlock(type);
+ }
+ else
+ {
+ if (writeVariablePrecision(type.getPrecision()))
+ out << " ";
+ out << getTypeName(type);
+ }
+}
+
+void TOutputGLSLBase::writeFunctionParameters(const TFunction *func)
+{
+ TInfoSinkBase &out = objSink();
+ size_t paramCount = func->getParamCount();
+ for (size_t i = 0; i < paramCount; ++i)
+ {
+ const TVariable *param = func->getParam(i);
+ const TType &type = param->getType();
+ writeVariableType(type, param, true);
+
+ if (param->symbolType() != SymbolType::Empty)
+ {
+ out << " " << hashName(param);
+ }
+ if (type.isArray())
+ {
+ out << ArrayString(type);
+ }
+
+ // Put a comma if this is not the last argument.
+ if (i != paramCount - 1)
+ out << ", ";
+ }
+}
+
+const TConstantUnion *TOutputGLSLBase::writeConstantUnion(const TType &type,
+ const TConstantUnion *pConstUnion)
+{
+ TInfoSinkBase &out = objSink();
+
+ if (type.getBasicType() == EbtStruct)
+ {
+ const TStructure *structure = type.getStruct();
+ out << hashName(structure) << "(";
+
+ const TFieldList &fields = structure->fields();
+ for (size_t i = 0; i < fields.size(); ++i)
+ {
+ const TType *fieldType = fields[i]->type();
+ ASSERT(fieldType != nullptr);
+ pConstUnion = writeConstantUnion(*fieldType, pConstUnion);
+ if (i != fields.size() - 1)
+ out << ", ";
+ }
+ out << ")";
+ }
+ else
+ {
+ size_t size = type.getObjectSize();
+ bool writeType = size > 1;
+ if (writeType)
+ out << getTypeName(type) << "(";
+ for (size_t i = 0; i < size; ++i, ++pConstUnion)
+ {
+ switch (pConstUnion->getType())
+ {
+ case EbtFloat:
+ writeFloat(out, pConstUnion->getFConst());
+ break;
+ case EbtInt:
+ out << pConstUnion->getIConst();
+ break;
+ case EbtUInt:
+ out << pConstUnion->getUConst() << "u";
+ break;
+ case EbtBool:
+ out << pConstUnion->getBConst();
+ break;
+ case EbtYuvCscStandardEXT:
+ out << getYuvCscStandardEXTString(pConstUnion->getYuvCscStandardEXTConst());
+ break;
+ default:
+ UNREACHABLE();
+ }
+ if (i != size - 1)
+ out << ", ";
+ }
+ if (writeType)
+ out << ")";
+ }
+ return pConstUnion;
+}
+
+void TOutputGLSLBase::writeConstructorTriplet(Visit visit, const TType &type)
+{
+ TInfoSinkBase &out = objSink();
+ if (visit == PreVisit)
+ {
+ if (type.isArray())
+ {
+ out << getTypeName(type);
+ out << ArrayString(type);
+ out << "(";
+ }
+ else
+ {
+ out << getTypeName(type) << "(";
+ }
+ }
+ else
+ {
+ writeTriplet(visit, nullptr, ", ", ")");
+ }
+}
+
+void TOutputGLSLBase::visitSymbol(TIntermSymbol *node)
+{
+ TInfoSinkBase &out = objSink();
+ out << hashName(&node->variable());
+
+ if (mDeclaringVariable && node->getType().isArray())
+ out << ArrayString(node->getType());
+}
+
+void TOutputGLSLBase::visitConstantUnion(TIntermConstantUnion *node)
+{
+ writeConstantUnion(node->getType(), node->getConstantValue());
+}
+
+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;
+ TInfoSinkBase &out = objSink();
+ switch (node->getOp())
+ {
+ case EOpComma:
+ writeTriplet(visit, "(", ", ", ")");
+ break;
+ case EOpInitialize:
+ if (visit == InVisit)
+ {
+ out << " = ";
+ // RHS of initialize is not being declared.
+ mDeclaringVariable = false;
+ }
+ break;
+ case EOpAssign:
+ writeTriplet(visit, "(", " = ", ")");
+ break;
+ case EOpAddAssign:
+ writeTriplet(visit, "(", " += ", ")");
+ break;
+ case EOpSubAssign:
+ writeTriplet(visit, "(", " -= ", ")");
+ break;
+ case EOpDivAssign:
+ writeTriplet(visit, "(", " /= ", ")");
+ break;
+ case EOpIModAssign:
+ writeTriplet(visit, "(", " %= ", ")");
+ break;
+ // Notice the fall-through.
+ case EOpMulAssign:
+ case EOpVectorTimesMatrixAssign:
+ case EOpVectorTimesScalarAssign:
+ case EOpMatrixTimesScalarAssign:
+ case EOpMatrixTimesMatrixAssign:
+ writeTriplet(visit, "(", " *= ", ")");
+ break;
+ case EOpBitShiftLeftAssign:
+ writeTriplet(visit, "(", " <<= ", ")");
+ break;
+ case EOpBitShiftRightAssign:
+ writeTriplet(visit, "(", " >>= ", ")");
+ break;
+ case EOpBitwiseAndAssign:
+ writeTriplet(visit, "(", " &= ", ")");
+ break;
+ case EOpBitwiseXorAssign:
+ writeTriplet(visit, "(", " ^= ", ")");
+ break;
+ case EOpBitwiseOrAssign:
+ writeTriplet(visit, "(", " |= ", ")");
+ break;
+
+ case EOpIndexDirect:
+ case EOpIndexIndirect:
+ writeTriplet(visit, nullptr, "[", "]");
+ break;
+ case EOpIndexDirectStruct:
+ if (visit == InVisit)
+ {
+ // Here we are writing out "foo.bar", where "foo" is struct
+ // and "bar" is field. In AST, it is represented as a binary
+ // node, where left child represents "foo" and right child "bar".
+ // The node itself represents ".". The struct field "bar" is
+ // actually stored as an index into TStructure::fields.
+ out << ".";
+ const TStructure *structure = node->getLeft()->getType().getStruct();
+ const TIntermConstantUnion *index = node->getRight()->getAsConstantUnion();
+ const TField *field = structure->fields()[index->getIConst(0)];
+
+ out << hashFieldName(field);
+ visitChildren = false;
+ }
+ break;
+ case EOpIndexDirectInterfaceBlock:
+ if (visit == InVisit)
+ {
+ out << ".";
+ const TInterfaceBlock *interfaceBlock =
+ node->getLeft()->getType().getInterfaceBlock();
+ const TIntermConstantUnion *index = node->getRight()->getAsConstantUnion();
+ const TField *field = interfaceBlock->fields()[index->getIConst(0)];
+ out << hashFieldName(field);
+ visitChildren = false;
+ }
+ break;
+
+ case EOpAdd:
+ writeTriplet(visit, "(", " + ", ")");
+ break;
+ case EOpSub:
+ writeTriplet(visit, "(", " - ", ")");
+ break;
+ case EOpMul:
+ writeTriplet(visit, "(", " * ", ")");
+ break;
+ case EOpDiv:
+ writeTriplet(visit, "(", " / ", ")");
+ break;
+ case EOpIMod:
+ writeTriplet(visit, "(", " % ", ")");
+ break;
+ case EOpBitShiftLeft:
+ writeTriplet(visit, "(", " << ", ")");
+ break;
+ case EOpBitShiftRight:
+ writeTriplet(visit, "(", " >> ", ")");
+ break;
+ case EOpBitwiseAnd:
+ writeTriplet(visit, "(", " & ", ")");
+ break;
+ case EOpBitwiseXor:
+ writeTriplet(visit, "(", " ^ ", ")");
+ break;
+ case EOpBitwiseOr:
+ writeTriplet(visit, "(", " | ", ")");
+ break;
+
+ case EOpEqual:
+ writeTriplet(visit, "(", " == ", ")");
+ break;
+ case EOpNotEqual:
+ writeTriplet(visit, "(", " != ", ")");
+ break;
+ case EOpLessThan:
+ writeTriplet(visit, "(", " < ", ")");
+ break;
+ case EOpGreaterThan:
+ writeTriplet(visit, "(", " > ", ")");
+ break;
+ case EOpLessThanEqual:
+ writeTriplet(visit, "(", " <= ", ")");
+ break;
+ case EOpGreaterThanEqual:
+ writeTriplet(visit, "(", " >= ", ")");
+ break;
+
+ // Notice the fall-through.
+ case EOpVectorTimesScalar:
+ case EOpVectorTimesMatrix:
+ case EOpMatrixTimesVector:
+ case EOpMatrixTimesScalar:
+ case EOpMatrixTimesMatrix:
+ writeTriplet(visit, "(", " * ", ")");
+ break;
+
+ case EOpLogicalOr:
+ writeTriplet(visit, "(", " || ", ")");
+ break;
+ case EOpLogicalXor:
+ writeTriplet(visit, "(", " ^^ ", ")");
+ break;
+ case EOpLogicalAnd:
+ writeTriplet(visit, "(", " && ", ")");
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ return visitChildren;
+}
+
+bool TOutputGLSLBase::visitUnary(Visit visit, TIntermUnary *node)
+{
+ const char *preString = "";
+ const char *postString = ")";
+
+ switch (node->getOp())
+ {
+ case EOpNegative:
+ preString = "(-";
+ break;
+ case EOpPositive:
+ preString = "(+";
+ break;
+ case EOpLogicalNot:
+ preString = "(!";
+ break;
+ case EOpBitwiseNot:
+ preString = "(~";
+ break;
+
+ case EOpPostIncrement:
+ preString = "(";
+ postString = "++)";
+ break;
+ case EOpPostDecrement:
+ preString = "(";
+ postString = "--)";
+ break;
+ case EOpPreIncrement:
+ preString = "(++";
+ break;
+ case EOpPreDecrement:
+ preString = "(--";
+ break;
+ case EOpArrayLength:
+ preString = "((";
+ postString = ").length())";
+ break;
+
+ default:
+ writeFunctionTriplet(visit, node->getFunction()->name(),
+ node->getUseEmulatedFunction());
+ return true;
+ }
+
+ writeTriplet(visit, preString, nullptr, postString);
+
+ return true;
+}
+
+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;
+}
+
+bool TOutputGLSLBase::visitIfElse(Visit visit, TIntermIfElse *node)
+{
+ TInfoSinkBase &out = objSink();
+
+ out << "if (";
+ node->getCondition()->traverse(this);
+ out << ")\n";
+
+ visitCodeBlock(node->getTrueBlock());
+
+ if (node->getFalseBlock())
+ {
+ out << getIndentPrefix() << "else\n";
+ visitCodeBlock(node->getFalseBlock());
+ }
+ return false;
+}
+
+bool TOutputGLSLBase::visitSwitch(Visit visit, TIntermSwitch *node)
+{
+ ASSERT(node->getStatementList());
+ writeTriplet(visit, "switch (", ") ", nullptr);
+ // The curly braces get written when visiting the statementList aggregate
+ return true;
+}
+
+bool TOutputGLSLBase::visitCase(Visit visit, TIntermCase *node)
+{
+ if (node->hasCondition())
+ {
+ writeTriplet(visit, "case (", nullptr, "):\n");
+ return true;
+ }
+ else
+ {
+ TInfoSinkBase &out = objSink();
+ out << "default:\n";
+ return false;
+ }
+}
+
+bool TOutputGLSLBase::visitBlock(Visit visit, TIntermBlock *node)
+{
+ TInfoSinkBase &out = objSink();
+ // Scope the blocks except when at the global scope.
+ if (getCurrentTraversalDepth() > 0)
+ {
+ out << "{\n";
+ }
+
+ for (TIntermSequence::const_iterator iter = node->getSequence()->begin();
+ iter != node->getSequence()->end(); ++iter)
+ {
+ TIntermNode *curNode = *iter;
+ ASSERT(curNode != nullptr);
+
+ out << getIndentPrefix(curNode->getAsCaseNode() ? -1 : 0);
+
+ curNode->traverse(this);
+
+ if (isSingleStatement(curNode))
+ out << ";\n";
+ }
+
+ // Scope the blocks except when at the global scope.
+ if (getCurrentTraversalDepth() > 0)
+ {
+ out << getIndentPrefix(-1) << "}\n";
+ }
+ return false;
+}
+
+bool TOutputGLSLBase::visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node)
+{
+ TIntermFunctionPrototype *prototype = node->getFunctionPrototype();
+ prototype->traverse(this);
+ visitCodeBlock(node->getBody());
+
+ // Fully processed; no need to visit children.
+ return false;
+}
+
+bool TOutputGLSLBase::visitGlobalQualifierDeclaration(Visit visit,
+ TIntermGlobalQualifierDeclaration *node)
+{
+ TInfoSinkBase &out = objSink();
+ ASSERT(visit == PreVisit);
+ const TIntermSymbol *symbol = node->getSymbol();
+ out << (node->isPrecise() ? "precise " : "invariant ") << hashName(&symbol->variable());
+ return false;
+}
+
+void TOutputGLSLBase::visitFunctionPrototype(TIntermFunctionPrototype *node)
+{
+ TInfoSinkBase &out = objSink();
+
+ const TType &type = node->getType();
+ writeVariableType(type, node->getFunction(), false);
+ if (type.isArray())
+ out << ArrayString(type);
+
+ out << " " << hashFunctionNameIfNeeded(node->getFunction());
+
+ out << "(";
+ writeFunctionParameters(node->getFunction());
+ out << ")";
+}
+
+bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
+{
+ bool visitChildren = true;
+ if (node->getOp() == EOpConstruct)
+ {
+ writeConstructorTriplet(visit, node->getType());
+ }
+ else
+ {
+ // Function call.
+ ImmutableString functionName = node->getFunction()->name();
+ if (visit == PreVisit)
+ {
+ // No raw function is expected.
+ ASSERT(node->getOp() != EOpCallInternalRawFunction);
+
+ if (node->getOp() == EOpCallFunctionInAST)
+ {
+ functionName = hashFunctionNameIfNeeded(node->getFunction());
+ }
+ else
+ {
+ functionName =
+ translateTextureFunction(node->getFunction()->name(), mCompileOptions);
+ }
+ }
+ writeFunctionTriplet(visit, functionName, node->getUseEmulatedFunction());
+ }
+ return visitChildren;
+}
+
+bool TOutputGLSLBase::visitDeclaration(Visit visit, TIntermDeclaration *node)
+{
+ TInfoSinkBase &out = objSink();
+
+ // Variable declaration.
+ if (visit == PreVisit)
+ {
+ const TIntermSequence &sequence = *(node->getSequence());
+ TIntermTyped *decl = sequence.front()->getAsTyped();
+ TIntermSymbol *symbolNode = decl->getAsSymbolNode();
+ if (symbolNode == nullptr)
+ {
+ ASSERT(decl->getAsBinaryNode() && decl->getAsBinaryNode()->getOp() == EOpInitialize);
+ symbolNode = decl->getAsBinaryNode()->getLeft()->getAsSymbolNode();
+ }
+ ASSERT(symbolNode);
+
+ if (symbolNode->getName() != "gl_ClipDistance" &&
+ symbolNode->getName() != "gl_CullDistance")
+ {
+ // gl_Clip/CullDistance re-declaration doesn't need layout.
+ writeLayoutQualifier(symbolNode);
+ }
+
+ writeVariableType(symbolNode->getType(), &symbolNode->variable(), false);
+ if (symbolNode->variable().symbolType() != SymbolType::Empty)
+ {
+ out << " ";
+ }
+ mDeclaringVariable = true;
+ }
+ else if (visit == InVisit)
+ {
+ UNREACHABLE();
+ }
+ else
+ {
+ mDeclaringVariable = false;
+ }
+ return true;
+}
+
+bool TOutputGLSLBase::visitLoop(Visit visit, TIntermLoop *node)
+{
+ TInfoSinkBase &out = objSink();
+
+ TLoopType loopType = node->getType();
+
+ if (loopType == ELoopFor) // for loop
+ {
+ out << "for (";
+ if (node->getInit())
+ node->getInit()->traverse(this);
+ out << "; ";
+
+ if (node->getCondition())
+ node->getCondition()->traverse(this);
+ out << "; ";
+
+ if (node->getExpression())
+ node->getExpression()->traverse(this);
+ out << ")\n";
+
+ visitCodeBlock(node->getBody());
+ }
+ else if (loopType == ELoopWhile) // while loop
+ {
+ out << "while (";
+ ASSERT(node->getCondition() != nullptr);
+ node->getCondition()->traverse(this);
+ out << ")\n";
+
+ visitCodeBlock(node->getBody());
+ }
+ else // do-while loop
+ {
+ ASSERT(loopType == ELoopDoWhile);
+ out << "do\n";
+
+ visitCodeBlock(node->getBody());
+
+ out << "while (";
+ ASSERT(node->getCondition() != nullptr);
+ node->getCondition()->traverse(this);
+ out << ");\n";
+ }
+
+ // No need to visit children. They have been already processed in
+ // this function.
+ return false;
+}
+
+bool TOutputGLSLBase::visitBranch(Visit visit, TIntermBranch *node)
+{
+ switch (node->getFlowOp())
+ {
+ case EOpKill:
+ writeTriplet(visit, "discard", nullptr, nullptr);
+ break;
+ case EOpBreak:
+ writeTriplet(visit, "break", nullptr, nullptr);
+ break;
+ case EOpContinue:
+ writeTriplet(visit, "continue", nullptr, nullptr);
+ break;
+ case EOpReturn:
+ writeTriplet(visit, "return ", nullptr, nullptr);
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ return true;
+}
+
+void TOutputGLSLBase::visitCodeBlock(TIntermBlock *node)
+{
+ TInfoSinkBase &out = objSink();
+ if (node != nullptr)
+ {
+ out << getIndentPrefix();
+ node->traverse(this);
+ // Single statements not part of a sequence need to be terminated
+ // with semi-colon.
+ if (isSingleStatement(node))
+ out << ";\n";
+ }
+ else
+ {
+ out << "{\n}\n"; // Empty code block.
+ }
+}
+
+void TOutputGLSLBase::visitPreprocessorDirective(TIntermPreprocessorDirective *node)
+{
+ TInfoSinkBase &out = objSink();
+
+ out << "\n";
+
+ switch (node->getDirective())
+ {
+ case PreprocessorDirective::Define:
+ out << "#define";
+ break;
+ case PreprocessorDirective::Endif:
+ out << "#endif";
+ break;
+ case PreprocessorDirective::If:
+ out << "#if";
+ break;
+ case PreprocessorDirective::Ifdef:
+ out << "#ifdef";
+ break;
+
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ if (!node->getCommand().empty())
+ {
+ out << " " << node->getCommand();
+ }
+
+ out << "\n";
+}
+
+ImmutableString TOutputGLSLBase::getTypeName(const TType &type)
+{
+ if (type.getBasicType() == EbtSamplerVideoWEBGL)
+ {
+ // TODO(http://anglebug.com/3889): translate SamplerVideoWEBGL into different token
+ // when necessary (e.g. on Android devices)
+ return ImmutableString("sampler2D");
+ }
+
+ return GetTypeName(type, mHashFunction, &mNameMap);
+}
+
+ImmutableString TOutputGLSLBase::hashName(const TSymbol *symbol)
+{
+ return HashName(symbol, mHashFunction, &mNameMap);
+}
+
+ImmutableString TOutputGLSLBase::hashFieldName(const TField *field)
+{
+ ASSERT(field->symbolType() != SymbolType::Empty);
+ if (field->symbolType() == SymbolType::UserDefined)
+ {
+ return HashName(field->name(), mHashFunction, &mNameMap);
+ }
+
+ return field->name();
+}
+
+ImmutableString TOutputGLSLBase::hashFunctionNameIfNeeded(const TFunction *func)
+{
+ if (func->isMain())
+ {
+ return func->name();
+ }
+ else
+ {
+ return hashName(func);
+ }
+}
+
+void TOutputGLSLBase::declareStruct(const TStructure *structure)
+{
+ TInfoSinkBase &out = objSink();
+
+ out << "struct ";
+
+ if (structure->symbolType() != SymbolType::Empty)
+ {
+ out << hashName(structure) << " ";
+ }
+ out << "{\n";
+ const TFieldList &fields = structure->fields();
+ for (size_t i = 0; i < fields.size(); ++i)
+ {
+ out << getIndentPrefix(1);
+ const TField *field = fields[i];
+ const TType &fieldType = *field->type();
+ if (writeVariablePrecision(fieldType.getPrecision()))
+ {
+ out << " ";
+ }
+ if (fieldType.isPrecise())
+ {
+ writePreciseQualifier(fieldType);
+ }
+ out << getTypeName(fieldType) << " " << hashFieldName(field);
+ if (fieldType.isArray())
+ {
+ out << ArrayString(fieldType);
+ }
+ out << ";\n";
+ }
+ out << getIndentPrefix() << "}";
+}
+
+void TOutputGLSLBase::declareInterfaceBlockLayout(const TType &type)
+{
+ // 4.4.5 Uniform and Shader Storage Block Layout Qualifiers in GLSL 4.5 spec.
+ // Layout qualifiers can be used for uniform and shader storage blocks,
+ // but not for non-block uniform declarations.
+ if (IsShaderIoBlock(type.getQualifier()))
+ {
+ return;
+ }
+
+ const TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
+ TInfoSinkBase &out = objSink();
+
+ out << "layout(";
+
+ switch (interfaceBlock->blockStorage())
+ {
+ case EbsUnspecified:
+ case EbsShared:
+ // Default block storage is shared.
+ out << "shared";
+ break;
+
+ case EbsPacked:
+ out << "packed";
+ break;
+
+ case EbsStd140:
+ out << "std140";
+ break;
+
+ case EbsStd430:
+ out << "std430";
+ break;
+
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ if (interfaceBlock->blockBinding() >= 0)
+ {
+ out << ", ";
+ out << "binding = " << interfaceBlock->blockBinding();
+ }
+
+ out << ") ";
+}
+
+const char *getVariableInterpolation(TQualifier qualifier)
+{
+ switch (qualifier)
+ {
+ case EvqSmoothOut:
+ return "smooth out ";
+ case EvqFlatOut:
+ return "flat out ";
+ case EvqNoPerspectiveOut:
+ return "noperspective out ";
+ case EvqCentroidOut:
+ return "centroid out ";
+ case EvqSmoothIn:
+ return "smooth in ";
+ case EvqFlatIn:
+ return "flat in ";
+ case EvqNoPerspectiveIn:
+ return "noperspective in ";
+ case EvqCentroidIn:
+ return "centroid in ";
+ default:
+ break;
+ }
+ return nullptr;
+}
+
+void TOutputGLSLBase::declareInterfaceBlock(const TType &type)
+{
+ const TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
+ TInfoSinkBase &out = objSink();
+
+ out << hashName(interfaceBlock) << "{\n";
+ const TFieldList &fields = interfaceBlock->fields();
+ for (const TField *field : fields)
+ {
+ out << getIndentPrefix(1);
+ if (!IsShaderIoBlock(type.getQualifier()) && type.getQualifier() != EvqPatchIn &&
+ type.getQualifier() != EvqPatchOut)
+ {
+ writeFieldLayoutQualifier(field);
+ }
+
+ const TType &fieldType = *field->type();
+
+ out << getMemoryQualifiers(fieldType);
+ if (writeVariablePrecision(fieldType.getPrecision()))
+ out << " ";
+ if (fieldType.isInvariant())
+ {
+ writeInvariantQualifier(fieldType);
+ }
+ if (fieldType.isPrecise())
+ {
+ writePreciseQualifier(fieldType);
+ }
+
+ const char *qualifier = getVariableInterpolation(fieldType.getQualifier());
+ if (qualifier != nullptr)
+ out << qualifier;
+
+ out << getTypeName(fieldType) << " " << hashFieldName(field);
+
+ if (fieldType.isArray())
+ out << ArrayString(fieldType);
+ out << ";\n";
+ }
+ out << "}";
+}
+
+void WritePragma(TInfoSinkBase &out, const ShCompileOptions &compileOptions, const TPragma &pragma)
+{
+ if (!compileOptions.flattenPragmaSTDGLInvariantAll)
+ {
+ if (pragma.stdgl.invariantAll)
+ out << "#pragma STDGL invariant(all)\n";
+ }
+}
+
+void WriteGeometryShaderLayoutQualifiers(TInfoSinkBase &out,
+ sh::TLayoutPrimitiveType inputPrimitive,
+ int invocations,
+ sh::TLayoutPrimitiveType outputPrimitive,
+ int maxVertices)
+{
+ // Omit 'invocations = 1'
+ if (inputPrimitive != EptUndefined || invocations > 1)
+ {
+ out << "layout (";
+
+ if (inputPrimitive != EptUndefined)
+ {
+ out << getGeometryShaderPrimitiveTypeString(inputPrimitive);
+ }
+
+ if (invocations > 1)
+ {
+ if (inputPrimitive != EptUndefined)
+ {
+ out << ", ";
+ }
+ out << "invocations = " << invocations;
+ }
+ out << ") in;\n";
+ }
+
+ if (outputPrimitive != EptUndefined || maxVertices != -1)
+ {
+ out << "layout (";
+
+ if (outputPrimitive != EptUndefined)
+ {
+ out << getGeometryShaderPrimitiveTypeString(outputPrimitive);
+ }
+
+ if (maxVertices != -1)
+ {
+ if (outputPrimitive != EptUndefined)
+ {
+ out << ", ";
+ }
+ out << "max_vertices = " << maxVertices;
+ }
+ out << ") out;\n";
+ }
+}
+
+void WriteTessControlShaderLayoutQualifiers(TInfoSinkBase &out, int inputVertices)
+{
+ if (inputVertices != 0)
+ {
+ out << "layout (vertices = " << inputVertices << ") out;\n";
+ }
+}
+
+void WriteTessEvaluationShaderLayoutQualifiers(TInfoSinkBase &out,
+ sh::TLayoutTessEvaluationType inputPrimitive,
+ sh::TLayoutTessEvaluationType inputVertexSpacing,
+ sh::TLayoutTessEvaluationType inputOrdering,
+ sh::TLayoutTessEvaluationType inputPoint)
+{
+ if (inputPrimitive != EtetUndefined)
+ {
+ out << "layout (";
+ out << getTessEvaluationShaderTypeString(inputPrimitive);
+ if (inputVertexSpacing != EtetUndefined)
+ {
+ out << ", " << getTessEvaluationShaderTypeString(inputVertexSpacing);
+ }
+ if (inputOrdering != EtetUndefined)
+ {
+ out << ", " << getTessEvaluationShaderTypeString(inputOrdering);
+ }
+ if (inputPoint != EtetUndefined)
+ {
+ out << ", " << getTessEvaluationShaderTypeString(inputPoint);
+ }
+ out << ") in;\n";
+ }
+}
+
+// If SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS is enabled, layout qualifiers are spilled whenever
+// variables with specified layout qualifiers are copied. Additional checks are needed against the
+// type and storage qualifier of the variable to verify that layout qualifiers have to be outputted.
+// TODO (mradev): Fix layout qualifier spilling in ScalarizeVecAndMatConstructorArgs and remove
+// NeedsToWriteLayoutQualifier.
+bool TOutputGLSLBase::needsToWriteLayoutQualifier(const TType &type)
+{
+ if (type.getBasicType() == EbtInterfaceBlock)
+ {
+ return true;
+ }
+
+ const TLayoutQualifier &layoutQualifier = type.getLayoutQualifier();
+
+ if (IsFragmentOutput(type.getQualifier()) || type.getQualifier() == EvqVertexIn ||
+ IsVarying(type.getQualifier()))
+ {
+ if (layoutQualifier.location >= 0 ||
+ (mAlwaysSpecifyFragOutLocation && IsFragmentOutput(type.getQualifier())))
+ {
+ return true;
+ }
+ }
+
+ if (type.getQualifier() == EvqFragmentOut || type.getQualifier() == EvqFragmentInOut)
+ {
+ if (layoutQualifier.index >= 0)
+ {
+ return true;
+ }
+ if (layoutQualifier.yuv)
+ {
+ return true;
+ }
+ }
+
+ if (type.getQualifier() == EvqFragmentInOut && layoutQualifier.noncoherent)
+ {
+ return true;
+ }
+
+ if (IsOpaqueType(type.getBasicType()) && layoutQualifier.binding != -1)
+ {
+ return true;
+ }
+
+ if (IsImage(type.getBasicType()) && layoutQualifier.imageInternalFormat != EiifUnspecified)
+ {
+ return true;
+ }
+ return false;
+}
+
+void EmitEarlyFragmentTestsGLSL(const TCompiler &compiler, TInfoSinkBase &sink)
+{
+ if (compiler.isEarlyFragmentTestsSpecified())
+ {
+ sink << "layout (early_fragment_tests) in;\n";
+ }
+}
+
+void EmitWorkGroupSizeGLSL(const TCompiler &compiler, TInfoSinkBase &sink)
+{
+ if (compiler.isComputeShaderLocalSizeDeclared())
+ {
+ const sh::WorkGroupSize &localSize = compiler.getComputeShaderLocalSize();
+ sink << "layout (local_size_x=" << localSize[0] << ", local_size_y=" << localSize[1]
+ << ", local_size_z=" << localSize[2] << ") in;\n";
+ }
+}
+
+void EmitMultiviewGLSL(const TCompiler &compiler,
+ const ShCompileOptions &compileOptions,
+ const TExtension extension,
+ const TBehavior behavior,
+ TInfoSinkBase &sink)
+{
+ ASSERT(behavior != EBhUndefined);
+ if (behavior == EBhDisable)
+ return;
+
+ const bool isVertexShader = (compiler.getShaderType() == GL_VERTEX_SHADER);
+ if (compileOptions.initializeBuiltinsForInstancedMultiview)
+ {
+ // Emit ARB_shader_viewport_layer_array/NV_viewport_array2 in a vertex shader if the
+ // SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER option is set and the
+ // OVR_multiview(2) extension is requested.
+ if (isVertexShader && compileOptions.selectViewInNvGLSLVertexShader)
+ {
+ sink << "#if defined(GL_ARB_shader_viewport_layer_array)\n"
+ << "#extension GL_ARB_shader_viewport_layer_array : require\n"
+ << "#elif defined(GL_NV_viewport_array2)\n"
+ << "#extension GL_NV_viewport_array2 : require\n"
+ << "#endif\n";
+ }
+ }
+ else
+ {
+ sink << "#extension GL_OVR_multiview";
+ if (extension == TExtension::OVR_multiview2)
+ {
+ sink << "2";
+ }
+ sink << " : " << GetBehaviorString(behavior) << "\n";
+
+ const auto &numViews = compiler.getNumViews();
+ if (isVertexShader && numViews != -1)
+ {
+ sink << "layout(num_views=" << numViews << ") in;\n";
+ }
+ }
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/OutputGLSLBase.h b/gfx/angle/checkout/src/compiler/translator/OutputGLSLBase.h
new file mode 100644
index 0000000000..5552eb606f
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/OutputGLSLBase.h
@@ -0,0 +1,154 @@
+//
+// Copyright 2002 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_OUTPUTGLSLBASE_H_
+#define COMPILER_TRANSLATOR_OUTPUTGLSLBASE_H_
+
+#include <set>
+
+#include "compiler/translator/ExtensionBehavior.h"
+#include "compiler/translator/HashNames.h"
+#include "compiler/translator/InfoSink.h"
+#include "compiler/translator/Pragma.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+class TCompiler;
+
+class TOutputGLSLBase : public TIntermTraverser
+{
+ public:
+ TOutputGLSLBase(TCompiler *compiler,
+ TInfoSinkBase &objSink,
+ const ShCompileOptions &compileOptions);
+
+ ShShaderOutput getShaderOutput() const { return mOutput; }
+
+ // Return the original name if hash function pointer is NULL;
+ // otherwise return the hashed name. Has special handling for internal names and built-ins,
+ // which are not hashed.
+ ImmutableString hashName(const TSymbol *symbol);
+
+ protected:
+ TInfoSinkBase &objSink() { return mObjSink; }
+ void writeFloat(TInfoSinkBase &out, float f);
+ void writeTriplet(Visit visit, const char *preStr, const char *inStr, const char *postStr);
+ std::string getCommonLayoutQualifiers(TIntermSymbol *variable);
+ std::string getMemoryQualifiers(const TType &type);
+ virtual void writeLayoutQualifier(TIntermSymbol *variable);
+ void writeFieldLayoutQualifier(const TField *field);
+ void writeInvariantQualifier(const TType &type);
+ void writePreciseQualifier(const TType &type);
+ virtual void writeVariableType(const TType &type,
+ const TSymbol *symbol,
+ bool isFunctionArgument);
+ virtual bool writeVariablePrecision(TPrecision precision) = 0;
+ void writeFunctionParameters(const TFunction *func);
+ const TConstantUnion *writeConstantUnion(const TType &type, const TConstantUnion *pConstUnion);
+ void writeConstructorTriplet(Visit visit, const TType &type);
+ ImmutableString 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 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;
+ void visitFunctionPrototype(TIntermFunctionPrototype *node) override;
+ bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override;
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override;
+ bool visitBlock(Visit visit, TIntermBlock *node) override;
+ bool visitGlobalQualifierDeclaration(Visit visit,
+ TIntermGlobalQualifierDeclaration *node) override;
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
+ bool visitLoop(Visit visit, TIntermLoop *node) override;
+ bool visitBranch(Visit visit, TIntermBranch *node) override;
+ void visitPreprocessorDirective(TIntermPreprocessorDirective *node) override;
+
+ void visitCodeBlock(TIntermBlock *node);
+
+ ImmutableString hashFieldName(const TField *field);
+ // Same as hashName(), but without hashing "main".
+ ImmutableString hashFunctionNameIfNeeded(const TFunction *func);
+ // Used to translate function names for differences between ESSL and GLSL
+ virtual ImmutableString translateTextureFunction(const ImmutableString &name,
+ const ShCompileOptions &option)
+ {
+ return name;
+ }
+
+ void declareStruct(const TStructure *structure);
+ void writeQualifier(TQualifier qualifier, const TType &type, const TSymbol *symbol);
+
+ const char *mapQualifierToString(TQualifier qualifier);
+
+ sh::GLenum getShaderType() const { return mShaderType; }
+ bool isHighPrecisionSupported() const { return mHighPrecisionSupported; }
+ const char *getIndentPrefix(int extraIndentDepth = 0);
+
+ bool needsToWriteLayoutQualifier(const TType &type);
+
+ private:
+ void declareInterfaceBlockLayout(const TType &type);
+ void declareInterfaceBlock(const TType &type);
+
+ void writeFunctionTriplet(Visit visit,
+ const ImmutableString &functionName,
+ bool useEmulatedFunction);
+
+ TInfoSinkBase &mObjSink;
+ bool mDeclaringVariable;
+
+ // name hashing.
+ ShHashFunction64 mHashFunction;
+ NameMap &mNameMap;
+
+ sh::GLenum mShaderType;
+ const int mShaderVersion;
+ ShShaderOutput mOutput;
+
+ bool mHighPrecisionSupported;
+
+ // Emit "layout(locaton = 0)" for fragment outputs whose location is unspecified. This is for
+ // transformations like pixel local storage, where new outputs are introduced to the shader, and
+ // previously valid fragment outputs with an implicit location of 0 are now required to specify
+ // their location.
+ bool mAlwaysSpecifyFragOutLocation;
+
+ const ShCompileOptions &mCompileOptions;
+};
+
+void WritePragma(TInfoSinkBase &out, const ShCompileOptions &compileOptions, const TPragma &pragma);
+
+void WriteGeometryShaderLayoutQualifiers(TInfoSinkBase &out,
+ sh::TLayoutPrimitiveType inputPrimitive,
+ int invocations,
+ sh::TLayoutPrimitiveType outputPrimitive,
+ int maxVertices);
+
+void WriteTessControlShaderLayoutQualifiers(TInfoSinkBase &out, int inputVertices);
+
+void WriteTessEvaluationShaderLayoutQualifiers(TInfoSinkBase &out,
+ sh::TLayoutTessEvaluationType inputPrimitive,
+ sh::TLayoutTessEvaluationType inputVertexSpacing,
+ sh::TLayoutTessEvaluationType inputOrdering,
+ sh::TLayoutTessEvaluationType inputPoint);
+
+void EmitEarlyFragmentTestsGLSL(const TCompiler &, TInfoSinkBase &sink);
+void EmitWorkGroupSizeGLSL(const TCompiler &, TInfoSinkBase &sink);
+void EmitMultiviewGLSL(const TCompiler &,
+ const ShCompileOptions &,
+ const TExtension,
+ const TBehavior,
+ TInfoSinkBase &sink);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_OUTPUTGLSLBASE_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/OutputHLSL.cpp b/gfx/angle/checkout/src/compiler/translator/OutputHLSL.cpp
new file mode 100644
index 0000000000..12f220b448
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/OutputHLSL.cpp
@@ -0,0 +1,3700 @@
+//
+// Copyright 2002 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/OutputHLSL.h"
+
+#include <stdio.h>
+#include <algorithm>
+#include <cfloat>
+
+#include "common/angleutils.h"
+#include "common/debug.h"
+#include "common/utilities.h"
+#include "compiler/translator/AtomicCounterFunctionHLSL.h"
+#include "compiler/translator/BuiltInFunctionEmulator.h"
+#include "compiler/translator/BuiltInFunctionEmulatorHLSL.h"
+#include "compiler/translator/ImageFunctionHLSL.h"
+#include "compiler/translator/InfoSink.h"
+#include "compiler/translator/ResourcesHLSL.h"
+#include "compiler/translator/StructureHLSL.h"
+#include "compiler/translator/TextureFunctionHLSL.h"
+#include "compiler/translator/TranslatorHLSL.h"
+#include "compiler/translator/UtilsHLSL.h"
+#include "compiler/translator/blocklayout.h"
+#include "compiler/translator/tree_ops/d3d/RemoveSwitchFallThrough.h"
+#include "compiler/translator/tree_util/FindSymbolNode.h"
+#include "compiler/translator/tree_util/NodeSearch.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+constexpr const char kImage2DFunctionString[] = "// @@ IMAGE2D DECLARATION FUNCTION STRING @@";
+
+TString ArrayHelperFunctionName(const char *prefix, const TType &type)
+{
+ TStringStream fnName = sh::InitializeStream<TStringStream>();
+ fnName << prefix << "_";
+ if (type.isArray())
+ {
+ for (unsigned int arraySize : type.getArraySizes())
+ {
+ fnName << arraySize << "_";
+ }
+ }
+ fnName << TypeString(type);
+ return fnName.str();
+}
+
+bool IsDeclarationWrittenOut(TIntermDeclaration *node)
+{
+ TIntermSequence *sequence = node->getSequence();
+ TIntermTyped *variable = (*sequence)[0]->getAsTyped();
+ ASSERT(sequence->size() == 1);
+ ASSERT(variable);
+ return (variable->getQualifier() == EvqTemporary || variable->getQualifier() == EvqGlobal ||
+ variable->getQualifier() == EvqConst || variable->getQualifier() == EvqShared);
+}
+
+bool IsInStd140UniformBlock(TIntermTyped *node)
+{
+ TIntermBinary *binaryNode = node->getAsBinaryNode();
+
+ if (binaryNode)
+ {
+ return IsInStd140UniformBlock(binaryNode->getLeft());
+ }
+
+ const TType &type = node->getType();
+
+ if (type.getQualifier() == EvqUniform)
+ {
+ // determine if we are in the standard layout
+ const TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
+ if (interfaceBlock)
+ {
+ return (interfaceBlock->blockStorage() == EbsStd140);
+ }
+ }
+
+ return false;
+}
+
+const TInterfaceBlock *GetInterfaceBlockOfUniformBlockNearestIndexOperator(TIntermTyped *node)
+{
+ const TIntermBinary *binaryNode = node->getAsBinaryNode();
+ if (binaryNode)
+ {
+ if (binaryNode->getOp() == EOpIndexDirectInterfaceBlock)
+ {
+ return binaryNode->getLeft()->getType().getInterfaceBlock();
+ }
+ }
+
+ const TIntermSymbol *symbolNode = node->getAsSymbolNode();
+ if (symbolNode)
+ {
+ const TVariable &variable = symbolNode->variable();
+ const TType &variableType = variable.getType();
+
+ if (variableType.getQualifier() == EvqUniform &&
+ variable.symbolType() == SymbolType::UserDefined)
+ {
+ return variableType.getInterfaceBlock();
+ }
+ }
+
+ return nullptr;
+}
+
+const char *GetHLSLAtomicFunctionStringAndLeftParenthesis(TOperator op)
+{
+ switch (op)
+ {
+ case EOpAtomicAdd:
+ return "InterlockedAdd(";
+ case EOpAtomicMin:
+ return "InterlockedMin(";
+ case EOpAtomicMax:
+ return "InterlockedMax(";
+ case EOpAtomicAnd:
+ return "InterlockedAnd(";
+ case EOpAtomicOr:
+ return "InterlockedOr(";
+ case EOpAtomicXor:
+ return "InterlockedXor(";
+ case EOpAtomicExchange:
+ return "InterlockedExchange(";
+ case EOpAtomicCompSwap:
+ return "InterlockedCompareExchange(";
+ default:
+ UNREACHABLE();
+ return "";
+ }
+}
+
+bool IsAtomicFunctionForSharedVariableDirectAssign(const TIntermBinary &node)
+{
+ TIntermAggregate *aggregateNode = node.getRight()->getAsAggregate();
+ if (aggregateNode == nullptr)
+ {
+ return false;
+ }
+
+ if (node.getOp() == EOpAssign && BuiltInGroup::IsAtomicMemory(aggregateNode->getOp()))
+ {
+ return !IsInShaderStorageBlock((*aggregateNode->getSequence())[0]->getAsTyped());
+ }
+
+ return false;
+}
+
+const char *kZeros = "_ANGLE_ZEROS_";
+constexpr int kZeroCount = 256;
+std::string DefineZeroArray()
+{
+ std::stringstream ss = sh::InitializeStream<std::stringstream>();
+ // For 'static', if the declaration does not include an initializer, the value is set to zero.
+ // https://docs.microsoft.com/en-us/windows/desktop/direct3dhlsl/dx-graphics-hlsl-variable-syntax
+ ss << "static uint " << kZeros << "[" << kZeroCount << "];\n";
+ return ss.str();
+}
+
+std::string GetZeroInitializer(size_t size)
+{
+ std::stringstream ss = sh::InitializeStream<std::stringstream>();
+ size_t quotient = size / kZeroCount;
+ size_t reminder = size % kZeroCount;
+
+ for (size_t i = 0; i < quotient; ++i)
+ {
+ if (i != 0)
+ {
+ ss << ", ";
+ }
+ ss << kZeros;
+ }
+
+ for (size_t i = 0; i < reminder; ++i)
+ {
+ if (quotient != 0 || i != 0)
+ {
+ ss << ", ";
+ }
+ ss << "0";
+ }
+
+ return ss.str();
+}
+
+} // anonymous namespace
+
+TReferencedBlock::TReferencedBlock(const TInterfaceBlock *aBlock,
+ const TVariable *aInstanceVariable)
+ : block(aBlock), instanceVariable(aInstanceVariable)
+{}
+
+bool OutputHLSL::needStructMapping(TIntermTyped *node)
+{
+ ASSERT(node->getBasicType() == EbtStruct);
+ for (unsigned int n = 0u; getAncestorNode(n) != nullptr; ++n)
+ {
+ TIntermNode *ancestor = getAncestorNode(n);
+ const TIntermBinary *ancestorBinary = ancestor->getAsBinaryNode();
+ if (ancestorBinary)
+ {
+ switch (ancestorBinary->getOp())
+ {
+ case EOpIndexDirectStruct:
+ {
+ const TStructure *structure = ancestorBinary->getLeft()->getType().getStruct();
+ const TIntermConstantUnion *index =
+ ancestorBinary->getRight()->getAsConstantUnion();
+ const TField *field = structure->fields()[index->getIConst(0)];
+ if (field->type()->getStruct() == nullptr)
+ {
+ return false;
+ }
+ break;
+ }
+ case EOpIndexDirect:
+ case EOpIndexIndirect:
+ break;
+ default:
+ return true;
+ }
+ }
+ else
+ {
+ const TIntermAggregate *ancestorAggregate = ancestor->getAsAggregate();
+ if (ancestorAggregate)
+ {
+ return true;
+ }
+ return false;
+ }
+ }
+ return true;
+}
+
+void OutputHLSL::writeFloat(TInfoSinkBase &out, float f)
+{
+ // This is known not to work for NaN on all drivers but make the best effort to output NaNs
+ // regardless.
+ if ((gl::isInf(f) || gl::isNaN(f)) && mShaderVersion >= 300 &&
+ mOutputType == SH_HLSL_4_1_OUTPUT)
+ {
+ out << "asfloat(" << gl::bitCast<uint32_t>(f) << "u)";
+ }
+ else
+ {
+ out << std::min(FLT_MAX, std::max(-FLT_MAX, f));
+ }
+}
+
+void OutputHLSL::writeSingleConstant(TInfoSinkBase &out, const TConstantUnion *const constUnion)
+{
+ ASSERT(constUnion != nullptr);
+ switch (constUnion->getType())
+ {
+ case EbtFloat:
+ writeFloat(out, constUnion->getFConst());
+ break;
+ case EbtInt:
+ out << constUnion->getIConst();
+ break;
+ case EbtUInt:
+ out << constUnion->getUConst();
+ break;
+ case EbtBool:
+ out << constUnion->getBConst();
+ break;
+ default:
+ UNREACHABLE();
+ }
+}
+
+const TConstantUnion *OutputHLSL::writeConstantUnionArray(TInfoSinkBase &out,
+ const TConstantUnion *const constUnion,
+ const size_t size)
+{
+ const TConstantUnion *constUnionIterated = constUnion;
+ for (size_t i = 0; i < size; i++, constUnionIterated++)
+ {
+ writeSingleConstant(out, constUnionIterated);
+
+ if (i != size - 1)
+ {
+ out << ", ";
+ }
+ }
+ return constUnionIterated;
+}
+
+OutputHLSL::OutputHLSL(sh::GLenum shaderType,
+ ShShaderSpec shaderSpec,
+ int shaderVersion,
+ const TExtensionBehavior &extensionBehavior,
+ const char *sourcePath,
+ ShShaderOutput outputType,
+ int numRenderTargets,
+ int maxDualSourceDrawBuffers,
+ const std::vector<ShaderVariable> &uniforms,
+ const ShCompileOptions &compileOptions,
+ sh::WorkGroupSize workGroupSize,
+ TSymbolTable *symbolTable,
+ PerformanceDiagnostics *perfDiagnostics,
+ const std::map<int, const TInterfaceBlock *> &uniformBlockOptimizedMap,
+ const std::vector<InterfaceBlock> &shaderStorageBlocks,
+ bool isEarlyFragmentTestsSpecified)
+ : TIntermTraverser(true, true, true, symbolTable),
+ mShaderType(shaderType),
+ mShaderSpec(shaderSpec),
+ mShaderVersion(shaderVersion),
+ mExtensionBehavior(extensionBehavior),
+ mSourcePath(sourcePath),
+ mOutputType(outputType),
+ mCompileOptions(compileOptions),
+ mInsideFunction(false),
+ mInsideMain(false),
+ mUniformBlockOptimizedMap(uniformBlockOptimizedMap),
+ mNumRenderTargets(numRenderTargets),
+ mMaxDualSourceDrawBuffers(maxDualSourceDrawBuffers),
+ mCurrentFunctionMetadata(nullptr),
+ mWorkGroupSize(workGroupSize),
+ mPerfDiagnostics(perfDiagnostics),
+ mIsEarlyFragmentTestsSpecified(isEarlyFragmentTestsSpecified),
+ mNeedStructMapping(false)
+{
+ mUsesFragColor = false;
+ mUsesFragData = false;
+ mUsesDepthRange = false;
+ mUsesFragCoord = false;
+ mUsesPointCoord = false;
+ mUsesFrontFacing = false;
+ mUsesHelperInvocation = false;
+ mUsesPointSize = false;
+ mUsesInstanceID = false;
+ mHasMultiviewExtensionEnabled =
+ IsExtensionEnabled(mExtensionBehavior, TExtension::OVR_multiview) ||
+ IsExtensionEnabled(mExtensionBehavior, TExtension::OVR_multiview2);
+ mUsesViewID = false;
+ mUsesVertexID = false;
+ mUsesFragDepth = false;
+ mUsesNumWorkGroups = false;
+ mUsesWorkGroupID = false;
+ mUsesLocalInvocationID = false;
+ mUsesGlobalInvocationID = false;
+ mUsesLocalInvocationIndex = false;
+ mUsesXor = false;
+ mUsesDiscardRewriting = false;
+ mUsesNestedBreak = false;
+ mRequiresIEEEStrictCompiling = false;
+ mUseZeroArray = false;
+ mUsesSecondaryColor = false;
+
+ mUniqueIndex = 0;
+
+ mOutputLod0Function = false;
+ mInsideDiscontinuousLoop = false;
+ mNestedLoopDepth = 0;
+
+ mExcessiveLoopIndex = nullptr;
+
+ mStructureHLSL = new StructureHLSL;
+ mTextureFunctionHLSL = new TextureFunctionHLSL;
+ mImageFunctionHLSL = new ImageFunctionHLSL;
+ mAtomicCounterFunctionHLSL =
+ new AtomicCounterFunctionHLSL(compileOptions.forceAtomicValueResolution);
+
+ unsigned int firstUniformRegister = compileOptions.skipD3DConstantRegisterZero ? 1u : 0u;
+ mResourcesHLSL = new ResourcesHLSL(mStructureHLSL, outputType, uniforms, firstUniformRegister);
+
+ if (mOutputType == SH_HLSL_3_0_OUTPUT)
+ {
+ // Fragment shaders need dx_DepthRange, dx_ViewCoords, dx_DepthFront,
+ // and dx_FragCoordOffset.
+ // Vertex shaders need a slightly different set: dx_DepthRange, dx_ViewCoords and
+ // dx_ViewAdjust.
+ if (mShaderType == GL_VERTEX_SHADER)
+ {
+ mResourcesHLSL->reserveUniformRegisters(3);
+ }
+ else
+ {
+ mResourcesHLSL->reserveUniformRegisters(4);
+ }
+ }
+
+ // Reserve registers for the default uniform block and driver constants
+ mResourcesHLSL->reserveUniformBlockRegisters(2);
+
+ mSSBOOutputHLSL = new ShaderStorageBlockOutputHLSL(this, mResourcesHLSL, shaderStorageBlocks);
+}
+
+OutputHLSL::~OutputHLSL()
+{
+ SafeDelete(mSSBOOutputHLSL);
+ SafeDelete(mStructureHLSL);
+ SafeDelete(mResourcesHLSL);
+ SafeDelete(mTextureFunctionHLSL);
+ SafeDelete(mImageFunctionHLSL);
+ SafeDelete(mAtomicCounterFunctionHLSL);
+ for (auto &eqFunction : mStructEqualityFunctions)
+ {
+ SafeDelete(eqFunction);
+ }
+ for (auto &eqFunction : mArrayEqualityFunctions)
+ {
+ SafeDelete(eqFunction);
+ }
+}
+
+void OutputHLSL::output(TIntermNode *treeRoot, TInfoSinkBase &objSink)
+{
+ BuiltInFunctionEmulator builtInFunctionEmulator;
+ InitBuiltInFunctionEmulatorForHLSL(&builtInFunctionEmulator);
+ if (mCompileOptions.emulateIsnanFloatFunction)
+ {
+ InitBuiltInIsnanFunctionEmulatorForHLSLWorkarounds(&builtInFunctionEmulator,
+ mShaderVersion);
+ }
+
+ builtInFunctionEmulator.markBuiltInFunctionsForEmulation(treeRoot);
+
+ // Now that we are done changing the AST, do the analyses need for HLSL generation
+ CallDAG::InitResult success = mCallDag.init(treeRoot, nullptr);
+ ASSERT(success == CallDAG::INITDAG_SUCCESS);
+ mASTMetadataList = CreateASTMetadataHLSL(treeRoot, mCallDag);
+
+ const std::vector<MappedStruct> std140Structs = FlagStd140Structs(treeRoot);
+ // TODO(oetuaho): The std140Structs could be filtered based on which ones actually get used in
+ // the shader code. When we add shader storage blocks we might also consider an alternative
+ // solution, since the struct mapping won't work very well for shader storage blocks.
+
+ // Output the body and footer first to determine what has to go in the header
+ mInfoSinkStack.push(&mBody);
+ treeRoot->traverse(this);
+ mInfoSinkStack.pop();
+
+ mInfoSinkStack.push(&mFooter);
+ mInfoSinkStack.pop();
+
+ mInfoSinkStack.push(&mHeader);
+ header(mHeader, std140Structs, &builtInFunctionEmulator);
+ mInfoSinkStack.pop();
+
+ objSink << mHeader.c_str();
+ objSink << mBody.c_str();
+ objSink << mFooter.c_str();
+
+ builtInFunctionEmulator.cleanup();
+}
+
+const std::map<std::string, unsigned int> &OutputHLSL::getShaderStorageBlockRegisterMap() const
+{
+ return mResourcesHLSL->getShaderStorageBlockRegisterMap();
+}
+
+const std::map<std::string, unsigned int> &OutputHLSL::getUniformBlockRegisterMap() const
+{
+ return mResourcesHLSL->getUniformBlockRegisterMap();
+}
+
+const std::map<std::string, bool> &OutputHLSL::getUniformBlockUseStructuredBufferMap() const
+{
+ return mResourcesHLSL->getUniformBlockUseStructuredBufferMap();
+}
+
+const std::map<std::string, unsigned int> &OutputHLSL::getUniformRegisterMap() const
+{
+ return mResourcesHLSL->getUniformRegisterMap();
+}
+
+unsigned int OutputHLSL::getReadonlyImage2DRegisterIndex() const
+{
+ return mResourcesHLSL->getReadonlyImage2DRegisterIndex();
+}
+
+unsigned int OutputHLSL::getImage2DRegisterIndex() const
+{
+ return mResourcesHLSL->getImage2DRegisterIndex();
+}
+
+const std::set<std::string> &OutputHLSL::getUsedImage2DFunctionNames() const
+{
+ return mImageFunctionHLSL->getUsedImage2DFunctionNames();
+}
+
+TString OutputHLSL::structInitializerString(int indent,
+ const TType &type,
+ const TString &name) const
+{
+ TString init;
+
+ TString indentString;
+ for (int spaces = 0; spaces < indent; spaces++)
+ {
+ indentString += " ";
+ }
+
+ if (type.isArray())
+ {
+ init += indentString + "{\n";
+ for (unsigned int arrayIndex = 0u; arrayIndex < type.getOutermostArraySize(); ++arrayIndex)
+ {
+ TStringStream indexedString = sh::InitializeStream<TStringStream>();
+ indexedString << name << "[" << arrayIndex << "]";
+ TType elementType = type;
+ elementType.toArrayElementType();
+ init += structInitializerString(indent + 1, elementType, indexedString.str());
+ if (arrayIndex < type.getOutermostArraySize() - 1)
+ {
+ init += ",";
+ }
+ init += "\n";
+ }
+ init += indentString + "}";
+ }
+ else if (type.getBasicType() == EbtStruct)
+ {
+ init += indentString + "{\n";
+ const TStructure &structure = *type.getStruct();
+ const TFieldList &fields = structure.fields();
+ for (unsigned int fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
+ {
+ const TField &field = *fields[fieldIndex];
+ const TString &fieldName = name + "." + Decorate(field.name());
+ const TType &fieldType = *field.type();
+
+ init += structInitializerString(indent + 1, fieldType, fieldName);
+ if (fieldIndex < fields.size() - 1)
+ {
+ init += ",";
+ }
+ init += "\n";
+ }
+ init += indentString + "}";
+ }
+ else
+ {
+ init += indentString + name;
+ }
+
+ return init;
+}
+
+TString OutputHLSL::generateStructMapping(const std::vector<MappedStruct> &std140Structs) const
+{
+ TString mappedStructs;
+
+ for (auto &mappedStruct : std140Structs)
+ {
+ const TInterfaceBlock *interfaceBlock =
+ mappedStruct.blockDeclarator->getType().getInterfaceBlock();
+ TQualifier qualifier = mappedStruct.blockDeclarator->getType().getQualifier();
+ switch (qualifier)
+ {
+ case EvqUniform:
+ if (mReferencedUniformBlocks.count(interfaceBlock->uniqueId().get()) == 0)
+ {
+ continue;
+ }
+ break;
+ case EvqBuffer:
+ continue;
+ default:
+ UNREACHABLE();
+ return mappedStructs;
+ }
+
+ unsigned int instanceCount = 1u;
+ bool isInstanceArray = mappedStruct.blockDeclarator->isArray();
+ if (isInstanceArray)
+ {
+ instanceCount = mappedStruct.blockDeclarator->getOutermostArraySize();
+ }
+
+ for (unsigned int instanceArrayIndex = 0; instanceArrayIndex < instanceCount;
+ ++instanceArrayIndex)
+ {
+ TString originalName;
+ TString mappedName("map");
+
+ if (mappedStruct.blockDeclarator->variable().symbolType() != SymbolType::Empty)
+ {
+ const ImmutableString &instanceName =
+ mappedStruct.blockDeclarator->variable().name();
+ unsigned int instanceStringArrayIndex = GL_INVALID_INDEX;
+ if (isInstanceArray)
+ instanceStringArrayIndex = instanceArrayIndex;
+ TString instanceString = mResourcesHLSL->InterfaceBlockInstanceString(
+ instanceName, instanceStringArrayIndex);
+ originalName += instanceString;
+ mappedName += instanceString;
+ originalName += ".";
+ mappedName += "_";
+ }
+
+ TString fieldName = Decorate(mappedStruct.field->name());
+ originalName += fieldName;
+ mappedName += fieldName;
+
+ TType *structType = mappedStruct.field->type();
+ mappedStructs +=
+ "static " + Decorate(structType->getStruct()->name()) + " " + mappedName;
+
+ if (structType->isArray())
+ {
+ mappedStructs += ArrayString(*mappedStruct.field->type()).data();
+ }
+
+ mappedStructs += " =\n";
+ mappedStructs += structInitializerString(0, *structType, originalName);
+ mappedStructs += ";\n";
+ }
+ }
+ return mappedStructs;
+}
+
+void OutputHLSL::writeReferencedAttributes(TInfoSinkBase &out) const
+{
+ for (const auto &attribute : mReferencedAttributes)
+ {
+ const TType &type = attribute.second->getType();
+ const ImmutableString &name = attribute.second->name();
+
+ out << "static " << TypeString(type) << " " << Decorate(name) << ArrayString(type) << " = "
+ << zeroInitializer(type) << ";\n";
+ }
+}
+
+void OutputHLSL::writeReferencedVaryings(TInfoSinkBase &out) const
+{
+ for (const auto &varying : mReferencedVaryings)
+ {
+ const TType &type = varying.second->getType();
+
+ // Program linking depends on this exact format
+ out << "static " << InterpolationString(type.getQualifier()) << " " << TypeString(type)
+ << " " << DecorateVariableIfNeeded(*varying.second) << ArrayString(type) << " = "
+ << zeroInitializer(type) << ";\n";
+ }
+}
+
+void OutputHLSL::header(TInfoSinkBase &out,
+ const std::vector<MappedStruct> &std140Structs,
+ const BuiltInFunctionEmulator *builtInFunctionEmulator) const
+{
+ TString mappedStructs;
+ if (mNeedStructMapping)
+ {
+ mappedStructs = generateStructMapping(std140Structs);
+ }
+
+ // Suppress some common warnings:
+ // 3556 : Integer divides might be much slower, try using uints if possible.
+ // 3571 : The pow(f, e) intrinsic function won't work for negative f, use abs(f) or
+ // conditionally handle negative values if you expect them.
+ out << "#pragma warning( disable: 3556 3571 )\n";
+
+ out << mStructureHLSL->structsHeader();
+
+ mResourcesHLSL->uniformsHeader(out, mOutputType, mReferencedUniforms, mSymbolTable);
+ out << mResourcesHLSL->uniformBlocksHeader(mReferencedUniformBlocks, mUniformBlockOptimizedMap);
+ mSSBOOutputHLSL->writeShaderStorageBlocksHeader(mShaderType, out);
+
+ if (!mEqualityFunctions.empty())
+ {
+ out << "\n// Equality functions\n\n";
+ for (const auto &eqFunction : mEqualityFunctions)
+ {
+ out << eqFunction->functionDefinition << "\n";
+ }
+ }
+ if (!mArrayAssignmentFunctions.empty())
+ {
+ out << "\n// Assignment functions\n\n";
+ for (const auto &assignmentFunction : mArrayAssignmentFunctions)
+ {
+ out << assignmentFunction.functionDefinition << "\n";
+ }
+ }
+ if (!mArrayConstructIntoFunctions.empty())
+ {
+ out << "\n// Array constructor functions\n\n";
+ for (const auto &constructIntoFunction : mArrayConstructIntoFunctions)
+ {
+ out << constructIntoFunction.functionDefinition << "\n";
+ }
+ }
+
+ if (mUsesDiscardRewriting)
+ {
+ out << "#define ANGLE_USES_DISCARD_REWRITING\n";
+ }
+
+ if (mUsesNestedBreak)
+ {
+ out << "#define ANGLE_USES_NESTED_BREAK\n";
+ }
+
+ if (mRequiresIEEEStrictCompiling)
+ {
+ out << "#define ANGLE_REQUIRES_IEEE_STRICT_COMPILING\n";
+ }
+
+ out << "#ifdef ANGLE_ENABLE_LOOP_FLATTEN\n"
+ "#define LOOP [loop]\n"
+ "#define FLATTEN [flatten]\n"
+ "#else\n"
+ "#define LOOP\n"
+ "#define FLATTEN\n"
+ "#endif\n";
+
+ // array stride for atomic counter buffers is always 4 per original extension
+ // ARB_shader_atomic_counters and discussion on
+ // https://github.com/KhronosGroup/OpenGL-API/issues/5
+ out << "\n#define ATOMIC_COUNTER_ARRAY_STRIDE 4\n\n";
+
+ if (mUseZeroArray)
+ {
+ out << DefineZeroArray() << "\n";
+ }
+
+ if (mShaderType == GL_FRAGMENT_SHADER)
+ {
+ const bool usingMRTExtension =
+ IsExtensionEnabled(mExtensionBehavior, TExtension::EXT_draw_buffers);
+ const bool usingBFEExtension =
+ IsExtensionEnabled(mExtensionBehavior, TExtension::EXT_blend_func_extended);
+
+ out << "// Varyings\n";
+ writeReferencedVaryings(out);
+ out << "\n";
+
+ if ((IsDesktopGLSpec(mShaderSpec) && mShaderVersion >= 130) ||
+ (!IsDesktopGLSpec(mShaderSpec) && mShaderVersion >= 300))
+ {
+ for (const auto &outputVariable : mReferencedOutputVariables)
+ {
+ const ImmutableString &variableName = outputVariable.second->name();
+ const TType &variableType = outputVariable.second->getType();
+
+ out << "static " << TypeString(variableType) << " out_" << variableName
+ << ArrayString(variableType) << " = " << zeroInitializer(variableType) << ";\n";
+ }
+ }
+ else
+ {
+ const unsigned int numColorValues = usingMRTExtension ? mNumRenderTargets : 1;
+
+ out << "static float4 gl_Color[" << numColorValues
+ << "] =\n"
+ "{\n";
+ for (unsigned int i = 0; i < numColorValues; i++)
+ {
+ out << " float4(0, 0, 0, 0)";
+ if (i + 1 != numColorValues)
+ {
+ out << ",";
+ }
+ out << "\n";
+ }
+
+ out << "};\n";
+
+ if (usingBFEExtension && mUsesSecondaryColor)
+ {
+ out << "static float4 gl_SecondaryColor[" << mMaxDualSourceDrawBuffers
+ << "] = \n"
+ "{\n";
+ for (int i = 0; i < mMaxDualSourceDrawBuffers; i++)
+ {
+ out << " float4(0, 0, 0, 0)";
+ if (i + 1 != mMaxDualSourceDrawBuffers)
+ {
+ out << ",";
+ }
+ out << "\n";
+ }
+ out << "};\n";
+ }
+ }
+
+ if (mUsesFragDepth)
+ {
+ out << "static float gl_Depth = 0.0;\n";
+ }
+
+ if (mUsesFragCoord)
+ {
+ out << "static float4 gl_FragCoord = float4(0, 0, 0, 0);\n";
+ }
+
+ if (mUsesPointCoord)
+ {
+ out << "static float2 gl_PointCoord = float2(0.5, 0.5);\n";
+ }
+
+ if (mUsesFrontFacing)
+ {
+ out << "static bool gl_FrontFacing = false;\n";
+ }
+
+ if (mUsesHelperInvocation)
+ {
+ out << "static bool gl_HelperInvocation = false;\n";
+ }
+
+ out << "\n";
+
+ if (mUsesDepthRange)
+ {
+ out << "struct gl_DepthRangeParameters\n"
+ "{\n"
+ " float near;\n"
+ " float far;\n"
+ " float diff;\n"
+ "};\n"
+ "\n";
+ }
+
+ if (mOutputType == SH_HLSL_4_1_OUTPUT || mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT)
+ {
+ out << "cbuffer DriverConstants : register(b1)\n"
+ "{\n";
+
+ if (mUsesDepthRange)
+ {
+ out << " float3 dx_DepthRange : packoffset(c0);\n";
+ }
+
+ if (mUsesFragCoord)
+ {
+ out << " float4 dx_ViewCoords : packoffset(c1);\n";
+ out << " float2 dx_FragCoordOffset : packoffset(c3);\n";
+ }
+
+ if (mUsesFragCoord || mUsesFrontFacing)
+ {
+ out << " float3 dx_DepthFront : packoffset(c2);\n";
+ }
+
+ if (mUsesFragCoord)
+ {
+ // dx_ViewScale is only used in the fragment shader to correct
+ // the value for glFragCoord if necessary
+ out << " float2 dx_ViewScale : packoffset(c3.z);\n";
+ }
+
+ if (mHasMultiviewExtensionEnabled)
+ {
+ // We have to add a value which we can use to keep track of which multi-view code
+ // path is to be selected in the GS.
+ out << " float multiviewSelectViewportIndex : packoffset(c4.x);\n";
+ }
+
+ if (mOutputType == SH_HLSL_4_1_OUTPUT)
+ {
+ unsigned int registerIndex = 5;
+ mResourcesHLSL->samplerMetadataUniforms(out, registerIndex);
+ // Sampler metadata struct must be two 4-vec, 32 bytes.
+ registerIndex += mResourcesHLSL->getSamplerCount() * 2;
+ mResourcesHLSL->imageMetadataUniforms(out, registerIndex);
+ }
+
+ out << "};\n";
+
+ if (mOutputType == SH_HLSL_4_1_OUTPUT && mResourcesHLSL->hasImages())
+ {
+ out << kImage2DFunctionString << "\n";
+ }
+ }
+ else
+ {
+ if (mUsesDepthRange)
+ {
+ out << "uniform float3 dx_DepthRange : register(c0);";
+ }
+
+ if (mUsesFragCoord)
+ {
+ out << "uniform float4 dx_ViewCoords : register(c1);\n";
+ }
+
+ if (mUsesFragCoord || mUsesFrontFacing)
+ {
+ out << "uniform float3 dx_DepthFront : register(c2);\n";
+ out << "uniform float2 dx_FragCoordOffset : register(c3);\n";
+ }
+ }
+
+ out << "\n";
+
+ if (mUsesDepthRange)
+ {
+ out << "static gl_DepthRangeParameters gl_DepthRange = {dx_DepthRange.x, "
+ "dx_DepthRange.y, dx_DepthRange.z};\n"
+ "\n";
+ }
+
+ if (usingMRTExtension && mNumRenderTargets > 1)
+ {
+ out << "#define GL_USES_MRT\n";
+ }
+
+ if (mUsesFragColor)
+ {
+ out << "#define GL_USES_FRAG_COLOR\n";
+ }
+
+ if (mUsesFragData)
+ {
+ out << "#define GL_USES_FRAG_DATA\n";
+ }
+
+ if (mShaderVersion < 300 && usingBFEExtension && mUsesSecondaryColor)
+ {
+ out << "#define GL_USES_SECONDARY_COLOR\n";
+ }
+ }
+ else if (mShaderType == GL_VERTEX_SHADER)
+ {
+ out << "// Attributes\n";
+ writeReferencedAttributes(out);
+ out << "\n"
+ "static float4 gl_Position = float4(0, 0, 0, 0);\n";
+
+ if (mUsesPointSize)
+ {
+ out << "static float gl_PointSize = float(1);\n";
+ }
+
+ if (mUsesInstanceID)
+ {
+ out << "static int gl_InstanceID;";
+ }
+
+ if (mUsesVertexID)
+ {
+ out << "static int gl_VertexID;";
+ }
+
+ out << "\n"
+ "// Varyings\n";
+ writeReferencedVaryings(out);
+ out << "\n";
+
+ if (mUsesDepthRange)
+ {
+ out << "struct gl_DepthRangeParameters\n"
+ "{\n"
+ " float near;\n"
+ " float far;\n"
+ " float diff;\n"
+ "};\n"
+ "\n";
+ }
+
+ if (mOutputType == SH_HLSL_4_1_OUTPUT || mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT)
+ {
+ out << "cbuffer DriverConstants : register(b1)\n"
+ "{\n";
+
+ if (mUsesDepthRange)
+ {
+ out << " float3 dx_DepthRange : packoffset(c0);\n";
+ }
+
+ // dx_ViewAdjust and dx_ViewCoords will only be used in Feature Level 9
+ // shaders. However, we declare it for all shaders (including Feature Level 10+).
+ // The bytecode is the same whether we declare it or not, since D3DCompiler removes it
+ // if it's unused.
+ out << " float4 dx_ViewAdjust : packoffset(c1);\n";
+ out << " float2 dx_ViewCoords : packoffset(c2);\n";
+ out << " float2 dx_ViewScale : packoffset(c3);\n";
+
+ if (mHasMultiviewExtensionEnabled)
+ {
+ // We have to add a value which we can use to keep track of which multi-view code
+ // path is to be selected in the GS.
+ out << " float multiviewSelectViewportIndex : packoffset(c3.z);\n";
+ }
+
+ out << " float clipControlOrigin : packoffset(c3.w);\n";
+ out << " float clipControlZeroToOne : packoffset(c4);\n";
+
+ if (mOutputType == SH_HLSL_4_1_OUTPUT)
+ {
+ mResourcesHLSL->samplerMetadataUniforms(out, 5);
+ }
+
+ if (mUsesVertexID)
+ {
+ out << " uint dx_VertexID : packoffset(c4.y);\n";
+ }
+
+ out << "};\n"
+ "\n";
+ }
+ else
+ {
+ if (mUsesDepthRange)
+ {
+ out << "uniform float3 dx_DepthRange : register(c0);\n";
+ }
+
+ out << "uniform float4 dx_ViewAdjust : register(c1);\n";
+ out << "uniform float2 dx_ViewCoords : register(c2);\n";
+
+ out << "static const float clipControlOrigin = -1.0f;\n";
+ out << "static const float clipControlZeroToOne = 0.0f;\n";
+
+ out << "\n";
+ }
+
+ if (mUsesDepthRange)
+ {
+ out << "static gl_DepthRangeParameters gl_DepthRange = {dx_DepthRange.x, "
+ "dx_DepthRange.y, dx_DepthRange.z};\n"
+ "\n";
+ }
+ }
+ else // Compute shader
+ {
+ ASSERT(mShaderType == GL_COMPUTE_SHADER);
+
+ out << "cbuffer DriverConstants : register(b1)\n"
+ "{\n";
+ if (mUsesNumWorkGroups)
+ {
+ out << " uint3 gl_NumWorkGroups : packoffset(c0);\n";
+ }
+ ASSERT(mOutputType == SH_HLSL_4_1_OUTPUT);
+ unsigned int registerIndex = 1;
+ mResourcesHLSL->samplerMetadataUniforms(out, registerIndex);
+ // Sampler metadata struct must be two 4-vec, 32 bytes.
+ registerIndex += mResourcesHLSL->getSamplerCount() * 2;
+ mResourcesHLSL->imageMetadataUniforms(out, registerIndex);
+ out << "};\n";
+
+ out << kImage2DFunctionString << "\n";
+
+ std::ostringstream systemValueDeclaration = sh::InitializeStream<std::ostringstream>();
+ std::ostringstream glBuiltinInitialization = sh::InitializeStream<std::ostringstream>();
+
+ systemValueDeclaration << "\nstruct CS_INPUT\n{\n";
+ glBuiltinInitialization << "\nvoid initGLBuiltins(CS_INPUT input)\n"
+ << "{\n";
+
+ if (mUsesWorkGroupID)
+ {
+ out << "static uint3 gl_WorkGroupID = uint3(0, 0, 0);\n";
+ systemValueDeclaration << " uint3 dx_WorkGroupID : "
+ << "SV_GroupID;\n";
+ glBuiltinInitialization << " gl_WorkGroupID = input.dx_WorkGroupID;\n";
+ }
+
+ if (mUsesLocalInvocationID)
+ {
+ out << "static uint3 gl_LocalInvocationID = uint3(0, 0, 0);\n";
+ systemValueDeclaration << " uint3 dx_LocalInvocationID : "
+ << "SV_GroupThreadID;\n";
+ glBuiltinInitialization << " gl_LocalInvocationID = input.dx_LocalInvocationID;\n";
+ }
+
+ if (mUsesGlobalInvocationID)
+ {
+ out << "static uint3 gl_GlobalInvocationID = uint3(0, 0, 0);\n";
+ systemValueDeclaration << " uint3 dx_GlobalInvocationID : "
+ << "SV_DispatchThreadID;\n";
+ glBuiltinInitialization << " gl_GlobalInvocationID = input.dx_GlobalInvocationID;\n";
+ }
+
+ if (mUsesLocalInvocationIndex)
+ {
+ out << "static uint gl_LocalInvocationIndex = uint(0);\n";
+ systemValueDeclaration << " uint dx_LocalInvocationIndex : "
+ << "SV_GroupIndex;\n";
+ glBuiltinInitialization
+ << " gl_LocalInvocationIndex = input.dx_LocalInvocationIndex;\n";
+ }
+
+ systemValueDeclaration << "};\n\n";
+ glBuiltinInitialization << "};\n\n";
+
+ out << systemValueDeclaration.str();
+ out << glBuiltinInitialization.str();
+ }
+
+ if (!mappedStructs.empty())
+ {
+ out << "// Structures from std140 blocks with padding removed\n";
+ out << "\n";
+ out << mappedStructs;
+ out << "\n";
+ }
+
+ bool getDimensionsIgnoresBaseLevel = mCompileOptions.HLSLGetDimensionsIgnoresBaseLevel;
+ mTextureFunctionHLSL->textureFunctionHeader(out, mOutputType, getDimensionsIgnoresBaseLevel);
+ mImageFunctionHLSL->imageFunctionHeader(out);
+ mAtomicCounterFunctionHLSL->atomicCounterFunctionHeader(out);
+
+ if (mUsesFragCoord)
+ {
+ out << "#define GL_USES_FRAG_COORD\n";
+ }
+
+ if (mUsesPointCoord)
+ {
+ out << "#define GL_USES_POINT_COORD\n";
+ }
+
+ if (mUsesFrontFacing)
+ {
+ out << "#define GL_USES_FRONT_FACING\n";
+ }
+
+ if (mUsesHelperInvocation)
+ {
+ out << "#define GL_USES_HELPER_INVOCATION\n";
+ }
+
+ if (mUsesPointSize)
+ {
+ out << "#define GL_USES_POINT_SIZE\n";
+ }
+
+ if (mHasMultiviewExtensionEnabled)
+ {
+ out << "#define GL_ANGLE_MULTIVIEW_ENABLED\n";
+ }
+
+ if (mUsesVertexID)
+ {
+ out << "#define GL_USES_VERTEX_ID\n";
+ }
+
+ if (mUsesViewID)
+ {
+ out << "#define GL_USES_VIEW_ID\n";
+ }
+
+ if (mUsesFragDepth)
+ {
+ out << "#define GL_USES_FRAG_DEPTH\n";
+ }
+
+ if (mUsesDepthRange)
+ {
+ out << "#define GL_USES_DEPTH_RANGE\n";
+ }
+
+ if (mUsesXor)
+ {
+ out << "bool xor(bool p, bool q)\n"
+ "{\n"
+ " return (p || q) && !(p && q);\n"
+ "}\n"
+ "\n";
+ }
+
+ builtInFunctionEmulator->outputEmulatedFunctions(out);
+}
+
+void OutputHLSL::visitSymbol(TIntermSymbol *node)
+{
+ const TVariable &variable = node->variable();
+
+ // Empty symbols can only appear in declarations and function arguments, and in either of those
+ // cases the symbol nodes are not visited.
+ ASSERT(variable.symbolType() != SymbolType::Empty);
+
+ TInfoSinkBase &out = getInfoSink();
+
+ // Handle accessing std140 structs by value
+ if (IsInStd140UniformBlock(node) && node->getBasicType() == EbtStruct &&
+ needStructMapping(node))
+ {
+ mNeedStructMapping = true;
+ out << "map";
+ }
+
+ const ImmutableString &name = variable.name();
+ const TSymbolUniqueId &uniqueId = variable.uniqueId();
+
+ if (name == "gl_DepthRange")
+ {
+ mUsesDepthRange = true;
+ out << name;
+ }
+ else if (IsAtomicCounter(variable.getType().getBasicType()))
+ {
+ const TType &variableType = variable.getType();
+ if (variableType.getQualifier() == EvqUniform)
+ {
+ TLayoutQualifier layout = variableType.getLayoutQualifier();
+ mReferencedUniforms[uniqueId.get()] = &variable;
+ out << getAtomicCounterNameForBinding(layout.binding) << ", " << layout.offset;
+ }
+ else
+ {
+ TString varName = DecorateVariableIfNeeded(variable);
+ out << varName << ", " << varName << "_offset";
+ }
+ }
+ else
+ {
+ const TType &variableType = variable.getType();
+ TQualifier qualifier = variable.getType().getQualifier();
+
+ ensureStructDefined(variableType);
+
+ if (qualifier == EvqUniform)
+ {
+ const TInterfaceBlock *interfaceBlock = variableType.getInterfaceBlock();
+
+ if (interfaceBlock)
+ {
+ if (mReferencedUniformBlocks.count(interfaceBlock->uniqueId().get()) == 0)
+ {
+ const TVariable *instanceVariable = nullptr;
+ if (variableType.isInterfaceBlock())
+ {
+ instanceVariable = &variable;
+ }
+ mReferencedUniformBlocks[interfaceBlock->uniqueId().get()] =
+ new TReferencedBlock(interfaceBlock, instanceVariable);
+ }
+ }
+ else
+ {
+ mReferencedUniforms[uniqueId.get()] = &variable;
+ }
+
+ out << DecorateVariableIfNeeded(variable);
+ }
+ else if (qualifier == EvqBuffer)
+ {
+ UNREACHABLE();
+ }
+ else if (qualifier == EvqAttribute || qualifier == EvqVertexIn)
+ {
+ mReferencedAttributes[uniqueId.get()] = &variable;
+ out << Decorate(name);
+ }
+ else if (IsVarying(qualifier))
+ {
+ mReferencedVaryings[uniqueId.get()] = &variable;
+ out << DecorateVariableIfNeeded(variable);
+ if (variable.symbolType() == SymbolType::AngleInternal && name == "ViewID_OVR")
+ {
+ mUsesViewID = true;
+ }
+ }
+ else if (qualifier == EvqFragmentOut)
+ {
+ mReferencedOutputVariables[uniqueId.get()] = &variable;
+ out << "out_" << name;
+ }
+ else if (qualifier == EvqFragColor)
+ {
+ out << "gl_Color[0]";
+ mUsesFragColor = true;
+ }
+ else if (qualifier == EvqFragData)
+ {
+ out << "gl_Color";
+ mUsesFragData = true;
+ }
+ else if (qualifier == EvqSecondaryFragColorEXT)
+ {
+ out << "gl_SecondaryColor[0]";
+ mUsesSecondaryColor = true;
+ }
+ else if (qualifier == EvqSecondaryFragDataEXT)
+ {
+ out << "gl_SecondaryColor";
+ mUsesSecondaryColor = true;
+ }
+ else if (qualifier == EvqFragCoord)
+ {
+ mUsesFragCoord = true;
+ out << name;
+ }
+ else if (qualifier == EvqPointCoord)
+ {
+ mUsesPointCoord = true;
+ out << name;
+ }
+ else if (qualifier == EvqFrontFacing)
+ {
+ mUsesFrontFacing = true;
+ out << name;
+ }
+ else if (qualifier == EvqHelperInvocation)
+ {
+ mUsesHelperInvocation = true;
+ out << name;
+ }
+ else if (qualifier == EvqPointSize)
+ {
+ mUsesPointSize = true;
+ out << name;
+ }
+ else if (qualifier == EvqInstanceID)
+ {
+ mUsesInstanceID = true;
+ out << name;
+ }
+ else if (qualifier == EvqVertexID)
+ {
+ mUsesVertexID = true;
+ out << name;
+ }
+ else if (name == "gl_FragDepthEXT" || name == "gl_FragDepth")
+ {
+ mUsesFragDepth = true;
+ out << "gl_Depth";
+ }
+ else if (qualifier == EvqNumWorkGroups)
+ {
+ mUsesNumWorkGroups = true;
+ out << name;
+ }
+ else if (qualifier == EvqWorkGroupID)
+ {
+ mUsesWorkGroupID = true;
+ out << name;
+ }
+ else if (qualifier == EvqLocalInvocationID)
+ {
+ mUsesLocalInvocationID = true;
+ out << name;
+ }
+ else if (qualifier == EvqGlobalInvocationID)
+ {
+ mUsesGlobalInvocationID = true;
+ out << name;
+ }
+ else if (qualifier == EvqLocalInvocationIndex)
+ {
+ mUsesLocalInvocationIndex = true;
+ out << name;
+ }
+ else
+ {
+ out << DecorateVariableIfNeeded(variable);
+ }
+ }
+}
+
+void OutputHLSL::outputEqual(Visit visit, const TType &type, TOperator op, TInfoSinkBase &out)
+{
+ if (type.isScalar() && !type.isArray())
+ {
+ if (op == EOpEqual)
+ {
+ outputTriplet(out, visit, "(", " == ", ")");
+ }
+ else
+ {
+ outputTriplet(out, visit, "(", " != ", ")");
+ }
+ }
+ else
+ {
+ if (visit == PreVisit && op == EOpNotEqual)
+ {
+ out << "!";
+ }
+
+ if (type.isArray())
+ {
+ const TString &functionName = addArrayEqualityFunction(type);
+ outputTriplet(out, visit, (functionName + "(").c_str(), ", ", ")");
+ }
+ else if (type.getBasicType() == EbtStruct)
+ {
+ const TStructure &structure = *type.getStruct();
+ const TString &functionName = addStructEqualityFunction(structure);
+ outputTriplet(out, visit, (functionName + "(").c_str(), ", ", ")");
+ }
+ else
+ {
+ ASSERT(type.isMatrix() || type.isVector());
+ outputTriplet(out, visit, "all(", " == ", ")");
+ }
+ }
+}
+
+void OutputHLSL::outputAssign(Visit visit, const TType &type, TInfoSinkBase &out)
+{
+ if (type.isArray())
+ {
+ const TString &functionName = addArrayAssignmentFunction(type);
+ outputTriplet(out, visit, (functionName + "(").c_str(), ", ", ")");
+ }
+ else
+ {
+ outputTriplet(out, visit, "(", " = ", ")");
+ }
+}
+
+bool OutputHLSL::ancestorEvaluatesToSamplerInStruct()
+{
+ for (unsigned int n = 0u; getAncestorNode(n) != nullptr; ++n)
+ {
+ TIntermNode *ancestor = getAncestorNode(n);
+ const TIntermBinary *ancestorBinary = ancestor->getAsBinaryNode();
+ if (ancestorBinary == nullptr)
+ {
+ return false;
+ }
+ switch (ancestorBinary->getOp())
+ {
+ case EOpIndexDirectStruct:
+ {
+ const TStructure *structure = ancestorBinary->getLeft()->getType().getStruct();
+ const TIntermConstantUnion *index =
+ ancestorBinary->getRight()->getAsConstantUnion();
+ const TField *field = structure->fields()[index->getIConst(0)];
+ if (IsSampler(field->type()->getBasicType()))
+ {
+ return true;
+ }
+ break;
+ }
+ case EOpIndexDirect:
+ break;
+ default:
+ // Returning a sampler from indirect indexing is not supported.
+ return false;
+ }
+ }
+ 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();
+
+ switch (node->getOp())
+ {
+ case EOpComma:
+ outputTriplet(out, visit, "(", ", ", ")");
+ break;
+ case EOpAssign:
+ if (node->isArray())
+ {
+ TIntermAggregate *rightAgg = node->getRight()->getAsAggregate();
+ if (rightAgg != nullptr && rightAgg->isConstructor())
+ {
+ const TString &functionName = addArrayConstructIntoFunction(node->getType());
+ out << functionName << "(";
+ node->getLeft()->traverse(this);
+ TIntermSequence *seq = rightAgg->getSequence();
+ for (auto &arrayElement : *seq)
+ {
+ out << ", ";
+ arrayElement->traverse(this);
+ }
+ out << ")";
+ return false;
+ }
+ // ArrayReturnValueToOutParameter should have eliminated expressions where a
+ // function call is assigned.
+ ASSERT(rightAgg == nullptr);
+ }
+ // Assignment expressions with atomic functions should be transformed into atomic
+ // function calls in HLSL.
+ // e.g. original_value = atomicAdd(dest, value) should be translated into
+ // InterlockedAdd(dest, value, original_value);
+ else if (IsAtomicFunctionForSharedVariableDirectAssign(*node))
+ {
+ TIntermAggregate *atomicFunctionNode = node->getRight()->getAsAggregate();
+ TOperator atomicFunctionOp = atomicFunctionNode->getOp();
+ out << GetHLSLAtomicFunctionStringAndLeftParenthesis(atomicFunctionOp);
+ TIntermSequence *argumentSeq = atomicFunctionNode->getSequence();
+ ASSERT(argumentSeq->size() >= 2u);
+ for (auto &argument : *argumentSeq)
+ {
+ argument->traverse(this);
+ out << ", ";
+ }
+ node->getLeft()->traverse(this);
+ out << ")";
+ return false;
+ }
+ else if (IsInShaderStorageBlock(node->getLeft()))
+ {
+ mSSBOOutputHLSL->outputStoreFunctionCallPrefix(node->getLeft());
+ out << ", ";
+ if (IsInShaderStorageBlock(node->getRight()))
+ {
+ mSSBOOutputHLSL->outputLoadFunctionCall(node->getRight());
+ }
+ else
+ {
+ node->getRight()->traverse(this);
+ }
+
+ out << ")";
+ return false;
+ }
+ else if (IsInShaderStorageBlock(node->getRight()))
+ {
+ node->getLeft()->traverse(this);
+ out << " = ";
+ mSSBOOutputHLSL->outputLoadFunctionCall(node->getRight());
+ return false;
+ }
+
+ outputAssign(visit, node->getType(), out);
+ break;
+ case EOpInitialize:
+ if (visit == PreVisit)
+ {
+ TIntermSymbol *symbolNode = node->getLeft()->getAsSymbolNode();
+ ASSERT(symbolNode);
+ TIntermTyped *initializer = node->getRight();
+
+ // Global initializers must be constant at this point.
+ ASSERT(symbolNode->getQualifier() != EvqGlobal || initializer->hasConstantValue());
+
+ // GLSL allows to write things like "float x = x;" where a new variable x is defined
+ // and the value of an existing variable x is assigned. HLSL uses C semantics (the
+ // new variable is created before the assignment is evaluated), so we need to
+ // convert
+ // this to "float t = x, x = t;".
+ if (writeSameSymbolInitializer(out, symbolNode, initializer))
+ {
+ // Skip initializing the rest of the expression
+ return false;
+ }
+ else if (writeConstantInitialization(out, symbolNode, initializer))
+ {
+ return false;
+ }
+ }
+ else if (visit == InVisit)
+ {
+ out << " = ";
+ if (IsInShaderStorageBlock(node->getRight()))
+ {
+ mSSBOOutputHLSL->outputLoadFunctionCall(node->getRight());
+ return false;
+ }
+ }
+ break;
+ case EOpAddAssign:
+ outputTriplet(out, visit, "(", " += ", ")");
+ break;
+ case EOpSubAssign:
+ outputTriplet(out, visit, "(", " -= ", ")");
+ break;
+ case EOpMulAssign:
+ outputTriplet(out, visit, "(", " *= ", ")");
+ break;
+ case EOpVectorTimesScalarAssign:
+ outputTriplet(out, visit, "(", " *= ", ")");
+ break;
+ case EOpMatrixTimesScalarAssign:
+ outputTriplet(out, visit, "(", " *= ", ")");
+ break;
+ case EOpVectorTimesMatrixAssign:
+ if (visit == PreVisit)
+ {
+ out << "(";
+ }
+ else if (visit == InVisit)
+ {
+ out << " = mul(";
+ node->getLeft()->traverse(this);
+ out << ", transpose(";
+ }
+ else
+ {
+ out << ")))";
+ }
+ break;
+ case EOpMatrixTimesMatrixAssign:
+ if (visit == PreVisit)
+ {
+ out << "(";
+ }
+ else if (visit == InVisit)
+ {
+ out << " = transpose(mul(transpose(";
+ node->getLeft()->traverse(this);
+ out << "), transpose(";
+ }
+ else
+ {
+ out << "))))";
+ }
+ break;
+ case EOpDivAssign:
+ outputTriplet(out, visit, "(", " /= ", ")");
+ break;
+ case EOpIModAssign:
+ outputTriplet(out, visit, "(", " %= ", ")");
+ break;
+ case EOpBitShiftLeftAssign:
+ outputTriplet(out, visit, "(", " <<= ", ")");
+ break;
+ case EOpBitShiftRightAssign:
+ outputTriplet(out, visit, "(", " >>= ", ")");
+ break;
+ case EOpBitwiseAndAssign:
+ outputTriplet(out, visit, "(", " &= ", ")");
+ break;
+ case EOpBitwiseXorAssign:
+ outputTriplet(out, visit, "(", " ^= ", ")");
+ break;
+ case EOpBitwiseOrAssign:
+ outputTriplet(out, visit, "(", " |= ", ")");
+ break;
+ case EOpIndexDirect:
+ {
+ const TType &leftType = node->getLeft()->getType();
+ if (leftType.isInterfaceBlock())
+ {
+ if (visit == PreVisit)
+ {
+ TIntermSymbol *instanceArraySymbol = node->getLeft()->getAsSymbolNode();
+ const TInterfaceBlock *interfaceBlock = leftType.getInterfaceBlock();
+
+ ASSERT(leftType.getQualifier() == EvqUniform);
+ if (mReferencedUniformBlocks.count(interfaceBlock->uniqueId().get()) == 0)
+ {
+ mReferencedUniformBlocks[interfaceBlock->uniqueId().get()] =
+ new TReferencedBlock(interfaceBlock, &instanceArraySymbol->variable());
+ }
+ const int arrayIndex = node->getRight()->getAsConstantUnion()->getIConst(0);
+ out << mResourcesHLSL->InterfaceBlockInstanceString(
+ instanceArraySymbol->getName(), arrayIndex);
+ return false;
+ }
+ }
+ else if (ancestorEvaluatesToSamplerInStruct())
+ {
+ // All parts of an expression that access a sampler in a struct need to use _ as
+ // separator to access the sampler variable that has been moved out of the struct.
+ outputTriplet(out, visit, "", "_", "");
+ }
+ else if (IsAtomicCounter(leftType.getBasicType()))
+ {
+ outputTriplet(out, visit, "", " + (", ") * ATOMIC_COUNTER_ARRAY_STRIDE");
+ }
+ else
+ {
+ outputTriplet(out, visit, "", "[", "]");
+ if (visit == PostVisit)
+ {
+ const TInterfaceBlock *interfaceBlock =
+ GetInterfaceBlockOfUniformBlockNearestIndexOperator(node->getLeft());
+ if (interfaceBlock &&
+ mUniformBlockOptimizedMap.count(interfaceBlock->uniqueId().get()) != 0)
+ {
+ // If the uniform block member's type is not structure, we had explicitly
+ // packed the member into a structure, so need to add an operator of field
+ // slection.
+ const TField *field = interfaceBlock->fields()[0];
+ const TType *fieldType = field->type();
+ if (fieldType->isMatrix() || fieldType->isVectorArray() ||
+ fieldType->isScalarArray())
+ {
+ out << "." << Decorate(field->name());
+ }
+ }
+ }
+ }
+ }
+ break;
+ case EOpIndexIndirect:
+ {
+ // We do not currently support indirect references to interface blocks
+ ASSERT(node->getLeft()->getBasicType() != EbtInterfaceBlock);
+
+ const TType &leftType = node->getLeft()->getType();
+ if (IsAtomicCounter(leftType.getBasicType()))
+ {
+ outputTriplet(out, visit, "", " + (", ") * ATOMIC_COUNTER_ARRAY_STRIDE");
+ }
+ else
+ {
+ outputTriplet(out, visit, "", "[", "]");
+ if (visit == PostVisit)
+ {
+ const TInterfaceBlock *interfaceBlock =
+ GetInterfaceBlockOfUniformBlockNearestIndexOperator(node->getLeft());
+ if (interfaceBlock &&
+ mUniformBlockOptimizedMap.count(interfaceBlock->uniqueId().get()) != 0)
+ {
+ // If the uniform block member's type is not structure, we had explicitly
+ // packed the member into a structure, so need to add an operator of field
+ // slection.
+ const TField *field = interfaceBlock->fields()[0];
+ const TType *fieldType = field->type();
+ if (fieldType->isMatrix() || fieldType->isVectorArray() ||
+ fieldType->isScalarArray())
+ {
+ out << "." << Decorate(field->name());
+ }
+ }
+ }
+ }
+ break;
+ }
+ case EOpIndexDirectStruct:
+ {
+ const TStructure *structure = node->getLeft()->getType().getStruct();
+ const TIntermConstantUnion *index = node->getRight()->getAsConstantUnion();
+ const TField *field = structure->fields()[index->getIConst(0)];
+
+ // In cases where indexing returns a sampler, we need to access the sampler variable
+ // that has been moved out of the struct.
+ bool indexingReturnsSampler = IsSampler(field->type()->getBasicType());
+ if (visit == PreVisit && indexingReturnsSampler)
+ {
+ // Samplers extracted from structs have "angle" prefix to avoid name conflicts.
+ // This prefix is only output at the beginning of the indexing expression, which
+ // may have multiple parts.
+ out << "angle";
+ }
+ if (!indexingReturnsSampler)
+ {
+ // All parts of an expression that access a sampler in a struct need to use _ as
+ // separator to access the sampler variable that has been moved out of the struct.
+ indexingReturnsSampler = ancestorEvaluatesToSamplerInStruct();
+ }
+ if (visit == InVisit)
+ {
+ if (indexingReturnsSampler)
+ {
+ out << "_" << field->name();
+ }
+ else
+ {
+ out << "." << DecorateField(field->name(), *structure);
+ }
+
+ return false;
+ }
+ }
+ break;
+ case EOpIndexDirectInterfaceBlock:
+ {
+ ASSERT(!IsInShaderStorageBlock(node->getLeft()));
+ bool structInStd140UniformBlock = node->getBasicType() == EbtStruct &&
+ IsInStd140UniformBlock(node->getLeft()) &&
+ needStructMapping(node);
+ if (visit == PreVisit && structInStd140UniformBlock)
+ {
+ mNeedStructMapping = true;
+ out << "map";
+ }
+ if (visit == InVisit)
+ {
+ const TInterfaceBlock *interfaceBlock =
+ node->getLeft()->getType().getInterfaceBlock();
+ const TIntermConstantUnion *index = node->getRight()->getAsConstantUnion();
+ const TField *field = interfaceBlock->fields()[index->getIConst(0)];
+ if (structInStd140UniformBlock ||
+ mUniformBlockOptimizedMap.count(interfaceBlock->uniqueId().get()) != 0)
+ {
+ out << "_";
+ }
+ else
+ {
+ out << ".";
+ }
+ out << Decorate(field->name());
+
+ return false;
+ }
+ break;
+ }
+ case EOpAdd:
+ outputTriplet(out, visit, "(", " + ", ")");
+ break;
+ case EOpSub:
+ outputTriplet(out, visit, "(", " - ", ")");
+ break;
+ case EOpMul:
+ outputTriplet(out, visit, "(", " * ", ")");
+ break;
+ case EOpDiv:
+ outputTriplet(out, visit, "(", " / ", ")");
+ break;
+ case EOpIMod:
+ outputTriplet(out, visit, "(", " % ", ")");
+ break;
+ case EOpBitShiftLeft:
+ outputTriplet(out, visit, "(", " << ", ")");
+ break;
+ case EOpBitShiftRight:
+ outputTriplet(out, visit, "(", " >> ", ")");
+ break;
+ case EOpBitwiseAnd:
+ outputTriplet(out, visit, "(", " & ", ")");
+ break;
+ case EOpBitwiseXor:
+ outputTriplet(out, visit, "(", " ^ ", ")");
+ break;
+ case EOpBitwiseOr:
+ outputTriplet(out, visit, "(", " | ", ")");
+ break;
+ case EOpEqual:
+ case EOpNotEqual:
+ outputEqual(visit, node->getLeft()->getType(), node->getOp(), out);
+ break;
+ case EOpLessThan:
+ outputTriplet(out, visit, "(", " < ", ")");
+ break;
+ case EOpGreaterThan:
+ outputTriplet(out, visit, "(", " > ", ")");
+ break;
+ case EOpLessThanEqual:
+ outputTriplet(out, visit, "(", " <= ", ")");
+ break;
+ case EOpGreaterThanEqual:
+ outputTriplet(out, visit, "(", " >= ", ")");
+ break;
+ case EOpVectorTimesScalar:
+ outputTriplet(out, visit, "(", " * ", ")");
+ break;
+ case EOpMatrixTimesScalar:
+ outputTriplet(out, visit, "(", " * ", ")");
+ break;
+ case EOpVectorTimesMatrix:
+ outputTriplet(out, visit, "mul(", ", transpose(", "))");
+ break;
+ case EOpMatrixTimesVector:
+ outputTriplet(out, visit, "mul(transpose(", "), ", ")");
+ break;
+ case EOpMatrixTimesMatrix:
+ outputTriplet(out, visit, "transpose(mul(transpose(", "), transpose(", ")))");
+ break;
+ case EOpLogicalOr:
+ // HLSL doesn't short-circuit ||, so we assume that || affected by short-circuiting have
+ // been unfolded.
+ ASSERT(!node->getRight()->hasSideEffects());
+ outputTriplet(out, visit, "(", " || ", ")");
+ return true;
+ case EOpLogicalXor:
+ mUsesXor = true;
+ outputTriplet(out, visit, "xor(", ", ", ")");
+ break;
+ case EOpLogicalAnd:
+ // HLSL doesn't short-circuit &&, so we assume that && affected by short-circuiting have
+ // been unfolded.
+ ASSERT(!node->getRight()->hasSideEffects());
+ outputTriplet(out, visit, "(", " && ", ")");
+ return true;
+ default:
+ UNREACHABLE();
+ }
+
+ return true;
+}
+
+bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node)
+{
+ TInfoSinkBase &out = getInfoSink();
+
+ switch (node->getOp())
+ {
+ case EOpNegative:
+ outputTriplet(out, visit, "(-", "", ")");
+ break;
+ case EOpPositive:
+ outputTriplet(out, visit, "(+", "", ")");
+ break;
+ case EOpLogicalNot:
+ outputTriplet(out, visit, "(!", "", ")");
+ break;
+ case EOpBitwiseNot:
+ outputTriplet(out, visit, "(~", "", ")");
+ break;
+ case EOpPostIncrement:
+ outputTriplet(out, visit, "(", "", "++)");
+ break;
+ case EOpPostDecrement:
+ outputTriplet(out, visit, "(", "", "--)");
+ break;
+ case EOpPreIncrement:
+ outputTriplet(out, visit, "(++", "", ")");
+ break;
+ case EOpPreDecrement:
+ outputTriplet(out, visit, "(--", "", ")");
+ break;
+ case EOpRadians:
+ outputTriplet(out, visit, "radians(", "", ")");
+ break;
+ case EOpDegrees:
+ outputTriplet(out, visit, "degrees(", "", ")");
+ break;
+ case EOpSin:
+ outputTriplet(out, visit, "sin(", "", ")");
+ break;
+ case EOpCos:
+ outputTriplet(out, visit, "cos(", "", ")");
+ break;
+ case EOpTan:
+ outputTriplet(out, visit, "tan(", "", ")");
+ break;
+ case EOpAsin:
+ outputTriplet(out, visit, "asin(", "", ")");
+ break;
+ case EOpAcos:
+ outputTriplet(out, visit, "acos(", "", ")");
+ break;
+ case EOpAtan:
+ outputTriplet(out, visit, "atan(", "", ")");
+ break;
+ case EOpSinh:
+ outputTriplet(out, visit, "sinh(", "", ")");
+ break;
+ case EOpCosh:
+ outputTriplet(out, visit, "cosh(", "", ")");
+ break;
+ case EOpTanh:
+ case EOpAsinh:
+ case EOpAcosh:
+ case EOpAtanh:
+ ASSERT(node->getUseEmulatedFunction());
+ writeEmulatedFunctionTriplet(out, visit, node->getFunction());
+ break;
+ case EOpExp:
+ outputTriplet(out, visit, "exp(", "", ")");
+ break;
+ case EOpLog:
+ outputTriplet(out, visit, "log(", "", ")");
+ break;
+ case EOpExp2:
+ outputTriplet(out, visit, "exp2(", "", ")");
+ break;
+ case EOpLog2:
+ outputTriplet(out, visit, "log2(", "", ")");
+ break;
+ case EOpSqrt:
+ outputTriplet(out, visit, "sqrt(", "", ")");
+ break;
+ case EOpInversesqrt:
+ outputTriplet(out, visit, "rsqrt(", "", ")");
+ break;
+ case EOpAbs:
+ outputTriplet(out, visit, "abs(", "", ")");
+ break;
+ case EOpSign:
+ outputTriplet(out, visit, "sign(", "", ")");
+ break;
+ case EOpFloor:
+ outputTriplet(out, visit, "floor(", "", ")");
+ break;
+ case EOpTrunc:
+ outputTriplet(out, visit, "trunc(", "", ")");
+ break;
+ case EOpRound:
+ outputTriplet(out, visit, "round(", "", ")");
+ break;
+ case EOpRoundEven:
+ ASSERT(node->getUseEmulatedFunction());
+ writeEmulatedFunctionTriplet(out, visit, node->getFunction());
+ break;
+ case EOpCeil:
+ outputTriplet(out, visit, "ceil(", "", ")");
+ break;
+ case EOpFract:
+ outputTriplet(out, visit, "frac(", "", ")");
+ break;
+ case EOpIsnan:
+ if (node->getUseEmulatedFunction())
+ writeEmulatedFunctionTriplet(out, visit, node->getFunction());
+ else
+ outputTriplet(out, visit, "isnan(", "", ")");
+ mRequiresIEEEStrictCompiling = true;
+ break;
+ case EOpIsinf:
+ outputTriplet(out, visit, "isinf(", "", ")");
+ break;
+ case EOpFloatBitsToInt:
+ outputTriplet(out, visit, "asint(", "", ")");
+ break;
+ case EOpFloatBitsToUint:
+ outputTriplet(out, visit, "asuint(", "", ")");
+ break;
+ case EOpIntBitsToFloat:
+ outputTriplet(out, visit, "asfloat(", "", ")");
+ break;
+ case EOpUintBitsToFloat:
+ outputTriplet(out, visit, "asfloat(", "", ")");
+ break;
+ case EOpPackSnorm2x16:
+ case EOpPackUnorm2x16:
+ case EOpPackHalf2x16:
+ case EOpUnpackSnorm2x16:
+ case EOpUnpackUnorm2x16:
+ case EOpUnpackHalf2x16:
+ case EOpPackUnorm4x8:
+ case EOpPackSnorm4x8:
+ case EOpUnpackUnorm4x8:
+ case EOpUnpackSnorm4x8:
+ ASSERT(node->getUseEmulatedFunction());
+ writeEmulatedFunctionTriplet(out, visit, node->getFunction());
+ break;
+ case EOpLength:
+ outputTriplet(out, visit, "length(", "", ")");
+ break;
+ case EOpNormalize:
+ outputTriplet(out, visit, "normalize(", "", ")");
+ break;
+ case EOpTranspose:
+ outputTriplet(out, visit, "transpose(", "", ")");
+ break;
+ case EOpDeterminant:
+ outputTriplet(out, visit, "determinant(transpose(", "", "))");
+ break;
+ case EOpInverse:
+ ASSERT(node->getUseEmulatedFunction());
+ writeEmulatedFunctionTriplet(out, visit, node->getFunction());
+ break;
+
+ case EOpAny:
+ outputTriplet(out, visit, "any(", "", ")");
+ break;
+ case EOpAll:
+ outputTriplet(out, visit, "all(", "", ")");
+ break;
+ case EOpNotComponentWise:
+ outputTriplet(out, visit, "(!", "", ")");
+ break;
+ case EOpBitfieldReverse:
+ outputTriplet(out, visit, "reversebits(", "", ")");
+ break;
+ case EOpBitCount:
+ outputTriplet(out, visit, "countbits(", "", ")");
+ break;
+ case EOpFindLSB:
+ // Note that it's unclear from the HLSL docs what this returns for 0, but this is tested
+ // in GLSLTest and results are consistent with GL.
+ outputTriplet(out, visit, "firstbitlow(", "", ")");
+ break;
+ case EOpFindMSB:
+ // Note that it's unclear from the HLSL docs what this returns for 0 or -1, but this is
+ // tested in GLSLTest and results are consistent with GL.
+ outputTriplet(out, visit, "firstbithigh(", "", ")");
+ break;
+ case EOpArrayLength:
+ {
+ TIntermTyped *operand = node->getOperand();
+ ASSERT(IsInShaderStorageBlock(operand));
+ mSSBOOutputHLSL->outputLengthFunctionCall(operand);
+ return false;
+ }
+ default:
+ UNREACHABLE();
+ }
+
+ return true;
+}
+
+ImmutableString OutputHLSL::samplerNamePrefixFromStruct(TIntermTyped *node)
+{
+ if (node->getAsSymbolNode())
+ {
+ ASSERT(node->getAsSymbolNode()->variable().symbolType() != SymbolType::Empty);
+ return node->getAsSymbolNode()->getName();
+ }
+ TIntermBinary *nodeBinary = node->getAsBinaryNode();
+ switch (nodeBinary->getOp())
+ {
+ case EOpIndexDirect:
+ {
+ int index = nodeBinary->getRight()->getAsConstantUnion()->getIConst(0);
+
+ std::stringstream prefixSink = sh::InitializeStream<std::stringstream>();
+ prefixSink << samplerNamePrefixFromStruct(nodeBinary->getLeft()) << "_" << index;
+ return ImmutableString(prefixSink.str());
+ }
+ case EOpIndexDirectStruct:
+ {
+ const TStructure *s = nodeBinary->getLeft()->getAsTyped()->getType().getStruct();
+ int index = nodeBinary->getRight()->getAsConstantUnion()->getIConst(0);
+ const TField *field = s->fields()[index];
+
+ std::stringstream prefixSink = sh::InitializeStream<std::stringstream>();
+ prefixSink << samplerNamePrefixFromStruct(nodeBinary->getLeft()) << "_"
+ << field->name();
+ return ImmutableString(prefixSink.str());
+ }
+ default:
+ UNREACHABLE();
+ return kEmptyImmutableString;
+ }
+}
+
+bool OutputHLSL::visitBlock(Visit visit, TIntermBlock *node)
+{
+ TInfoSinkBase &out = getInfoSink();
+
+ bool isMainBlock = mInsideMain && getParentNode()->getAsFunctionDefinition();
+
+ if (mInsideFunction)
+ {
+ outputLineDirective(out, node->getLine().first_line);
+ out << "{\n";
+ if (isMainBlock)
+ {
+ if (mShaderType == GL_COMPUTE_SHADER)
+ {
+ out << "initGLBuiltins(input);\n";
+ }
+ else
+ {
+ out << "@@ MAIN PROLOGUE @@\n";
+ }
+ }
+ }
+
+ for (TIntermNode *statement : *node->getSequence())
+ {
+ outputLineDirective(out, statement->getLine().first_line);
+
+ statement->traverse(this);
+
+ // 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 the output code is clearer if we don't output ; after statements where it is not
+ // needed:
+ // * if statements
+ // * switch statements
+ // * blocks
+ // * function definitions
+ // * loops (do-while loops output the semicolon in VisitLoop)
+ // * declarations that don't generate output.
+ if (statement->getAsCaseNode() == nullptr && statement->getAsIfElseNode() == nullptr &&
+ statement->getAsBlock() == nullptr && statement->getAsLoopNode() == nullptr &&
+ statement->getAsSwitchNode() == nullptr &&
+ statement->getAsFunctionDefinition() == nullptr &&
+ (statement->getAsDeclarationNode() == nullptr ||
+ IsDeclarationWrittenOut(statement->getAsDeclarationNode())) &&
+ statement->getAsGlobalQualifierDeclarationNode() == nullptr)
+ {
+ out << ";\n";
+ }
+ }
+
+ if (mInsideFunction)
+ {
+ outputLineDirective(out, node->getLine().last_line);
+ if (isMainBlock && shaderNeedsGenerateOutput())
+ {
+ // We could have an empty main, a main function without a branch at the end, or a main
+ // function with a discard statement at the end. In these cases we need to add a return
+ // statement.
+ bool needReturnStatement =
+ node->getSequence()->empty() || !node->getSequence()->back()->getAsBranchNode() ||
+ node->getSequence()->back()->getAsBranchNode()->getFlowOp() != EOpReturn;
+ if (needReturnStatement)
+ {
+ out << "return " << generateOutputCall() << ";\n";
+ }
+ }
+ out << "}\n";
+ }
+
+ return false;
+}
+
+bool OutputHLSL::visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node)
+{
+ TInfoSinkBase &out = getInfoSink();
+
+ ASSERT(mCurrentFunctionMetadata == nullptr);
+
+ size_t index = mCallDag.findIndex(node->getFunction()->uniqueId());
+ ASSERT(index != CallDAG::InvalidIndex);
+ mCurrentFunctionMetadata = &mASTMetadataList[index];
+
+ const TFunction *func = node->getFunction();
+
+ if (func->isMain())
+ {
+ // The stub strings below are replaced when shader is dynamically defined by its layout:
+ switch (mShaderType)
+ {
+ case GL_VERTEX_SHADER:
+ out << "@@ VERTEX ATTRIBUTES @@\n\n"
+ << "@@ VERTEX OUTPUT @@\n\n"
+ << "VS_OUTPUT main(VS_INPUT input)";
+ break;
+ case GL_FRAGMENT_SHADER:
+ out << "@@ PIXEL OUTPUT @@\n\n";
+ if (mIsEarlyFragmentTestsSpecified)
+ {
+ out << "[earlydepthstencil]\n";
+ }
+ out << "PS_OUTPUT main(@@ PIXEL MAIN PARAMETERS @@)";
+ break;
+ case GL_COMPUTE_SHADER:
+ out << "[numthreads(" << mWorkGroupSize[0] << ", " << mWorkGroupSize[1] << ", "
+ << mWorkGroupSize[2] << ")]\n";
+ out << "void main(CS_INPUT input)";
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ }
+ else
+ {
+ out << TypeString(node->getFunctionPrototype()->getType()) << " ";
+ out << DecorateFunctionIfNeeded(func) << DisambiguateFunctionName(func)
+ << (mOutputLod0Function ? "Lod0(" : "(");
+
+ size_t paramCount = func->getParamCount();
+ for (unsigned int i = 0; i < paramCount; i++)
+ {
+ const TVariable *param = func->getParam(i);
+ ensureStructDefined(param->getType());
+
+ writeParameter(param, out);
+
+ if (i < paramCount - 1)
+ {
+ out << ", ";
+ }
+ }
+
+ out << ")\n";
+ }
+
+ mInsideFunction = true;
+ if (func->isMain())
+ {
+ mInsideMain = true;
+ }
+ // The function body node will output braces.
+ node->getBody()->traverse(this);
+ mInsideFunction = false;
+ mInsideMain = false;
+
+ mCurrentFunctionMetadata = nullptr;
+
+ bool needsLod0 = mASTMetadataList[index].mNeedsLod0;
+ if (needsLod0 && !mOutputLod0Function && mShaderType == GL_FRAGMENT_SHADER)
+ {
+ ASSERT(!node->getFunction()->isMain());
+ mOutputLod0Function = true;
+ node->traverse(this);
+ mOutputLod0Function = false;
+ }
+
+ return false;
+}
+
+bool OutputHLSL::visitDeclaration(Visit visit, TIntermDeclaration *node)
+{
+ if (visit == PreVisit)
+ {
+ TIntermSequence *sequence = node->getSequence();
+ TIntermTyped *declarator = (*sequence)[0]->getAsTyped();
+ ASSERT(sequence->size() == 1);
+ ASSERT(declarator);
+
+ if (IsDeclarationWrittenOut(node))
+ {
+ TInfoSinkBase &out = getInfoSink();
+ ensureStructDefined(declarator->getType());
+
+ if (!declarator->getAsSymbolNode() ||
+ declarator->getAsSymbolNode()->variable().symbolType() !=
+ SymbolType::Empty) // Variable declaration
+ {
+ if (declarator->getQualifier() == EvqShared)
+ {
+ out << "groupshared ";
+ }
+ else if (!mInsideFunction)
+ {
+ out << "static ";
+ }
+
+ out << TypeString(declarator->getType()) + " ";
+
+ TIntermSymbol *symbol = declarator->getAsSymbolNode();
+
+ if (symbol)
+ {
+ symbol->traverse(this);
+ out << ArrayString(symbol->getType());
+ // Temporarily disable shadred memory initialization. It is very slow for D3D11
+ // drivers to compile a compute shader if we add code to initialize a
+ // groupshared array variable with a large array size. And maybe produce
+ // incorrect result. See http://anglebug.com/3226.
+ if (declarator->getQualifier() != EvqShared)
+ {
+ out << " = " + zeroInitializer(symbol->getType());
+ }
+ }
+ else
+ {
+ declarator->traverse(this);
+ }
+ }
+ }
+ else if (IsVaryingOut(declarator->getQualifier()))
+ {
+ TIntermSymbol *symbol = declarator->getAsSymbolNode();
+ ASSERT(symbol); // Varying declarations can't have initializers.
+
+ const TVariable &variable = symbol->variable();
+
+ if (variable.symbolType() != SymbolType::Empty)
+ {
+ // Vertex outputs which are declared but not written to should still be declared to
+ // allow successful linking.
+ mReferencedVaryings[symbol->uniqueId().get()] = &variable;
+ }
+ }
+ }
+ return false;
+}
+
+bool OutputHLSL::visitGlobalQualifierDeclaration(Visit visit,
+ TIntermGlobalQualifierDeclaration *node)
+{
+ // Do not do any translation
+ return false;
+}
+
+void OutputHLSL::visitFunctionPrototype(TIntermFunctionPrototype *node)
+{
+ TInfoSinkBase &out = getInfoSink();
+
+ size_t index = mCallDag.findIndex(node->getFunction()->uniqueId());
+ // Skip the prototype if it is not implemented (and thus not used)
+ if (index == CallDAG::InvalidIndex)
+ {
+ return;
+ }
+
+ const TFunction *func = node->getFunction();
+
+ TString name = DecorateFunctionIfNeeded(func);
+ out << TypeString(node->getType()) << " " << name << DisambiguateFunctionName(func)
+ << (mOutputLod0Function ? "Lod0(" : "(");
+
+ size_t paramCount = func->getParamCount();
+ for (unsigned int i = 0; i < paramCount; i++)
+ {
+ writeParameter(func->getParam(i), out);
+
+ if (i < paramCount - 1)
+ {
+ out << ", ";
+ }
+ }
+
+ out << ");\n";
+
+ // Also prototype the Lod0 variant if needed
+ bool needsLod0 = mASTMetadataList[index].mNeedsLod0;
+ if (needsLod0 && !mOutputLod0Function && mShaderType == GL_FRAGMENT_SHADER)
+ {
+ mOutputLod0Function = true;
+ node->traverse(this);
+ mOutputLod0Function = false;
+ }
+}
+
+bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
+{
+ TInfoSinkBase &out = getInfoSink();
+
+ switch (node->getOp())
+ {
+ case EOpCallFunctionInAST:
+ case EOpCallInternalRawFunction:
+ default:
+ {
+ TIntermSequence *arguments = node->getSequence();
+
+ bool lod0 = (mInsideDiscontinuousLoop || mOutputLod0Function) &&
+ mShaderType == GL_FRAGMENT_SHADER;
+
+ // No raw function is expected.
+ ASSERT(node->getOp() != EOpCallInternalRawFunction);
+
+ if (node->getOp() == EOpCallFunctionInAST)
+ {
+ if (node->isArray())
+ {
+ UNIMPLEMENTED();
+ }
+ size_t index = mCallDag.findIndex(node->getFunction()->uniqueId());
+ ASSERT(index != CallDAG::InvalidIndex);
+ lod0 &= mASTMetadataList[index].mNeedsLod0;
+
+ out << DecorateFunctionIfNeeded(node->getFunction());
+ out << DisambiguateFunctionName(node->getSequence());
+ out << (lod0 ? "Lod0(" : "(");
+ }
+ else if (node->getFunction()->isImageFunction())
+ {
+ const ImmutableString &name = node->getFunction()->name();
+ TType type = (*arguments)[0]->getAsTyped()->getType();
+ const ImmutableString &imageFunctionName = mImageFunctionHLSL->useImageFunction(
+ name, type.getBasicType(), type.getLayoutQualifier().imageInternalFormat,
+ type.getMemoryQualifier().readonly);
+ out << imageFunctionName << "(";
+ }
+ else if (node->getFunction()->isAtomicCounterFunction())
+ {
+ const ImmutableString &name = node->getFunction()->name();
+ ImmutableString atomicFunctionName =
+ mAtomicCounterFunctionHLSL->useAtomicCounterFunction(name);
+ out << atomicFunctionName << "(";
+ }
+ else
+ {
+ const ImmutableString &name = node->getFunction()->name();
+ TBasicType samplerType = (*arguments)[0]->getAsTyped()->getType().getBasicType();
+ int coords = 0; // textureSize(gsampler2DMS) doesn't have a second argument.
+ if (arguments->size() > 1)
+ {
+ coords = (*arguments)[1]->getAsTyped()->getNominalSize();
+ }
+ const ImmutableString &textureFunctionName =
+ mTextureFunctionHLSL->useTextureFunction(name, samplerType, coords,
+ arguments->size(), lod0, mShaderType);
+ out << textureFunctionName << "(";
+ }
+
+ for (TIntermSequence::iterator arg = arguments->begin(); arg != arguments->end(); arg++)
+ {
+ TIntermTyped *typedArg = (*arg)->getAsTyped();
+ if (mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT && IsSampler(typedArg->getBasicType()))
+ {
+ out << "texture_";
+ (*arg)->traverse(this);
+ out << ", sampler_";
+ }
+
+ (*arg)->traverse(this);
+
+ if (typedArg->getType().isStructureContainingSamplers())
+ {
+ const TType &argType = typedArg->getType();
+ TVector<const TVariable *> samplerSymbols;
+ ImmutableString structName = samplerNamePrefixFromStruct(typedArg);
+ std::string namePrefix = "angle_";
+ namePrefix += structName.data();
+ argType.createSamplerSymbols(ImmutableString(namePrefix), "", &samplerSymbols,
+ nullptr, mSymbolTable);
+ for (const TVariable *sampler : samplerSymbols)
+ {
+ if (mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT)
+ {
+ out << ", texture_" << sampler->name();
+ out << ", sampler_" << sampler->name();
+ }
+ else
+ {
+ // In case of HLSL 4.1+, this symbol is the sampler index, and in case
+ // of D3D9, it's the sampler variable.
+ out << ", " << sampler->name();
+ }
+ }
+ }
+
+ if (arg < arguments->end() - 1)
+ {
+ out << ", ";
+ }
+ }
+
+ out << ")";
+
+ return false;
+ }
+ case EOpConstruct:
+ outputConstructor(out, visit, node);
+ break;
+ case EOpEqualComponentWise:
+ outputTriplet(out, visit, "(", " == ", ")");
+ break;
+ case EOpNotEqualComponentWise:
+ outputTriplet(out, visit, "(", " != ", ")");
+ break;
+ case EOpLessThanComponentWise:
+ outputTriplet(out, visit, "(", " < ", ")");
+ break;
+ case EOpGreaterThanComponentWise:
+ outputTriplet(out, visit, "(", " > ", ")");
+ break;
+ case EOpLessThanEqualComponentWise:
+ outputTriplet(out, visit, "(", " <= ", ")");
+ break;
+ case EOpGreaterThanEqualComponentWise:
+ outputTriplet(out, visit, "(", " >= ", ")");
+ break;
+ case EOpMod:
+ ASSERT(node->getUseEmulatedFunction());
+ writeEmulatedFunctionTriplet(out, visit, node->getFunction());
+ break;
+ case EOpModf:
+ outputTriplet(out, visit, "modf(", ", ", ")");
+ break;
+ case EOpPow:
+ outputTriplet(out, visit, "pow(", ", ", ")");
+ break;
+ case EOpAtan:
+ ASSERT(node->getSequence()->size() == 2); // atan(x) is a unary operator
+ ASSERT(node->getUseEmulatedFunction());
+ writeEmulatedFunctionTriplet(out, visit, node->getFunction());
+ break;
+ case EOpMin:
+ outputTriplet(out, visit, "min(", ", ", ")");
+ break;
+ case EOpMax:
+ outputTriplet(out, visit, "max(", ", ", ")");
+ break;
+ case EOpClamp:
+ outputTriplet(out, visit, "clamp(", ", ", ")");
+ break;
+ case EOpMix:
+ {
+ TIntermTyped *lastParamNode = (*(node->getSequence()))[2]->getAsTyped();
+ if (lastParamNode->getType().getBasicType() == EbtBool)
+ {
+ // There is no HLSL equivalent for ESSL3 built-in "genType mix (genType x, genType
+ // y, genBType a)",
+ // so use emulated version.
+ ASSERT(node->getUseEmulatedFunction());
+ writeEmulatedFunctionTriplet(out, visit, node->getFunction());
+ }
+ else
+ {
+ outputTriplet(out, visit, "lerp(", ", ", ")");
+ }
+ break;
+ }
+ case EOpStep:
+ outputTriplet(out, visit, "step(", ", ", ")");
+ break;
+ case EOpSmoothstep:
+ outputTriplet(out, visit, "smoothstep(", ", ", ")");
+ break;
+ case EOpFma:
+ outputTriplet(out, visit, "mad(", ", ", ")");
+ break;
+ case EOpFrexp:
+ case EOpLdexp:
+ ASSERT(node->getUseEmulatedFunction());
+ writeEmulatedFunctionTriplet(out, visit, node->getFunction());
+ break;
+ case EOpDistance:
+ outputTriplet(out, visit, "distance(", ", ", ")");
+ break;
+ case EOpDot:
+ outputTriplet(out, visit, "dot(", ", ", ")");
+ break;
+ case EOpCross:
+ outputTriplet(out, visit, "cross(", ", ", ")");
+ break;
+ case EOpFaceforward:
+ ASSERT(node->getUseEmulatedFunction());
+ writeEmulatedFunctionTriplet(out, visit, node->getFunction());
+ break;
+ case EOpReflect:
+ outputTriplet(out, visit, "reflect(", ", ", ")");
+ break;
+ case EOpRefract:
+ outputTriplet(out, visit, "refract(", ", ", ")");
+ break;
+ case EOpOuterProduct:
+ ASSERT(node->getUseEmulatedFunction());
+ writeEmulatedFunctionTriplet(out, visit, node->getFunction());
+ break;
+ case EOpMatrixCompMult:
+ outputTriplet(out, visit, "(", " * ", ")");
+ break;
+ case EOpBitfieldExtract:
+ case EOpBitfieldInsert:
+ case EOpUaddCarry:
+ case EOpUsubBorrow:
+ case EOpUmulExtended:
+ case EOpImulExtended:
+ ASSERT(node->getUseEmulatedFunction());
+ writeEmulatedFunctionTriplet(out, visit, node->getFunction());
+ break;
+ case EOpDFdx:
+ if (mInsideDiscontinuousLoop || mOutputLod0Function)
+ {
+ outputTriplet(out, visit, "(", "", ", 0.0)");
+ }
+ else
+ {
+ outputTriplet(out, visit, "ddx(", "", ")");
+ }
+ break;
+ case EOpDFdy:
+ if (mInsideDiscontinuousLoop || mOutputLod0Function)
+ {
+ outputTriplet(out, visit, "(", "", ", 0.0)");
+ }
+ else
+ {
+ outputTriplet(out, visit, "ddy(", "", ")");
+ }
+ break;
+ case EOpFwidth:
+ if (mInsideDiscontinuousLoop || mOutputLod0Function)
+ {
+ outputTriplet(out, visit, "(", "", ", 0.0)");
+ }
+ else
+ {
+ outputTriplet(out, visit, "fwidth(", "", ")");
+ }
+ break;
+ case EOpBarrier:
+ // barrier() is translated to GroupMemoryBarrierWithGroupSync(), which is the
+ // cheapest *WithGroupSync() function, without any functionality loss, but
+ // with the potential for severe performance loss.
+ outputTriplet(out, visit, "GroupMemoryBarrierWithGroupSync(", "", ")");
+ break;
+ case EOpMemoryBarrierShared:
+ outputTriplet(out, visit, "GroupMemoryBarrier(", "", ")");
+ break;
+ case EOpMemoryBarrierAtomicCounter:
+ case EOpMemoryBarrierBuffer:
+ case EOpMemoryBarrierImage:
+ outputTriplet(out, visit, "DeviceMemoryBarrier(", "", ")");
+ break;
+ case EOpGroupMemoryBarrier:
+ case EOpMemoryBarrier:
+ outputTriplet(out, visit, "AllMemoryBarrier(", "", ")");
+ break;
+
+ // Single atomic function calls without return value.
+ // e.g. atomicAdd(dest, value) should be translated into InterlockedAdd(dest, value).
+ case EOpAtomicAdd:
+ case EOpAtomicMin:
+ case EOpAtomicMax:
+ case EOpAtomicAnd:
+ case EOpAtomicOr:
+ case EOpAtomicXor:
+ // The parameter 'original_value' of InterlockedExchange(dest, value, original_value)
+ // and InterlockedCompareExchange(dest, compare_value, value, original_value) is not
+ // optional.
+ // https://docs.microsoft.com/en-us/windows/desktop/direct3dhlsl/interlockedexchange
+ // https://docs.microsoft.com/en-us/windows/desktop/direct3dhlsl/interlockedcompareexchange
+ // So all the call of atomicExchange(dest, value) and atomicCompSwap(dest,
+ // compare_value, value) should all be modified into the form of "int temp; temp =
+ // atomicExchange(dest, value);" and "int temp; temp = atomicCompSwap(dest,
+ // compare_value, value);" in the intermediate tree before traversing outputHLSL.
+ case EOpAtomicExchange:
+ case EOpAtomicCompSwap:
+ {
+ ASSERT(node->getChildCount() > 1);
+ TIntermTyped *memNode = (*node->getSequence())[0]->getAsTyped();
+ if (IsInShaderStorageBlock(memNode))
+ {
+ // Atomic memory functions for SSBO.
+ // "_ssbo_atomicXXX_TYPE(RWByteAddressBuffer buffer, uint loc" is written to |out|.
+ mSSBOOutputHLSL->outputAtomicMemoryFunctionCallPrefix(memNode, node->getOp());
+ // Write the rest argument list to |out|.
+ for (size_t i = 1; i < node->getChildCount(); i++)
+ {
+ out << ", ";
+ TIntermTyped *argument = (*node->getSequence())[i]->getAsTyped();
+ if (IsInShaderStorageBlock(argument))
+ {
+ mSSBOOutputHLSL->outputLoadFunctionCall(argument);
+ }
+ else
+ {
+ argument->traverse(this);
+ }
+ }
+
+ out << ")";
+ return false;
+ }
+ else
+ {
+ // Atomic memory functions for shared variable.
+ if (node->getOp() != EOpAtomicExchange && node->getOp() != EOpAtomicCompSwap)
+ {
+ outputTriplet(out, visit,
+ GetHLSLAtomicFunctionStringAndLeftParenthesis(node->getOp()), ",",
+ ")");
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+ }
+
+ break;
+ }
+ }
+
+ return true;
+}
+
+void OutputHLSL::writeIfElse(TInfoSinkBase &out, TIntermIfElse *node)
+{
+ out << "if (";
+
+ node->getCondition()->traverse(this);
+
+ out << ")\n";
+
+ outputLineDirective(out, node->getLine().first_line);
+
+ bool discard = false;
+
+ if (node->getTrueBlock())
+ {
+ // The trueBlock child node will output braces.
+ node->getTrueBlock()->traverse(this);
+
+ // Detect true discard
+ discard = (discard || FindDiscard::search(node->getTrueBlock()));
+ }
+ else
+ {
+ // TODO(oetuaho): Check if the semicolon inside is necessary.
+ // It's there as a result of conservative refactoring of the output.
+ out << "{;}\n";
+ }
+
+ outputLineDirective(out, node->getLine().first_line);
+
+ if (node->getFalseBlock())
+ {
+ out << "else\n";
+
+ outputLineDirective(out, node->getFalseBlock()->getLine().first_line);
+
+ // The falseBlock child node will output braces.
+ node->getFalseBlock()->traverse(this);
+
+ outputLineDirective(out, node->getFalseBlock()->getLine().first_line);
+
+ // Detect false discard
+ discard = (discard || FindDiscard::search(node->getFalseBlock()));
+ }
+
+ // ANGLE issue 486: Detect problematic conditional discard
+ if (discard)
+ {
+ mUsesDiscardRewriting = true;
+ }
+}
+
+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(mInsideFunction);
+
+ // D3D errors when there is a gradient operation in a loop in an unflattened if.
+ if (mShaderType == GL_FRAGMENT_SHADER && mCurrentFunctionMetadata->hasGradientLoop(node))
+ {
+ out << "FLATTEN ";
+ }
+
+ writeIfElse(out, node);
+
+ return false;
+}
+
+bool OutputHLSL::visitSwitch(Visit visit, TIntermSwitch *node)
+{
+ TInfoSinkBase &out = getInfoSink();
+
+ ASSERT(node->getStatementList());
+ if (visit == PreVisit)
+ {
+ node->setStatementList(RemoveSwitchFallThrough(node->getStatementList(), mPerfDiagnostics));
+ }
+ outputTriplet(out, visit, "switch (", ") ", "");
+ // The curly braces get written when visiting the statementList block.
+ return true;
+}
+
+bool OutputHLSL::visitCase(Visit visit, TIntermCase *node)
+{
+ TInfoSinkBase &out = getInfoSink();
+
+ if (node->hasCondition())
+ {
+ outputTriplet(out, visit, "case (", "", "):\n");
+ return true;
+ }
+ else
+ {
+ out << "default:\n";
+ return false;
+ }
+}
+
+void OutputHLSL::visitConstantUnion(TIntermConstantUnion *node)
+{
+ TInfoSinkBase &out = getInfoSink();
+ writeConstantUnion(out, node->getType(), node->getConstantValue());
+}
+
+bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node)
+{
+ mNestedLoopDepth++;
+
+ bool wasDiscontinuous = mInsideDiscontinuousLoop;
+ mInsideDiscontinuousLoop =
+ mInsideDiscontinuousLoop || mCurrentFunctionMetadata->mDiscontinuousLoops.count(node) > 0;
+
+ TInfoSinkBase &out = getInfoSink();
+
+ if (mOutputType == SH_HLSL_3_0_OUTPUT)
+ {
+ if (handleExcessiveLoop(out, node))
+ {
+ mInsideDiscontinuousLoop = wasDiscontinuous;
+ mNestedLoopDepth--;
+
+ return false;
+ }
+ }
+
+ const char *unroll = mCurrentFunctionMetadata->hasGradientInCallGraph(node) ? "LOOP" : "";
+ if (node->getType() == ELoopDoWhile)
+ {
+ out << "{" << unroll << " do\n";
+
+ outputLineDirective(out, node->getLine().first_line);
+ }
+ else
+ {
+ out << "{" << unroll << " for(";
+
+ if (node->getInit())
+ {
+ node->getInit()->traverse(this);
+ }
+
+ out << "; ";
+
+ if (node->getCondition())
+ {
+ node->getCondition()->traverse(this);
+ }
+
+ out << "; ";
+
+ if (node->getExpression())
+ {
+ node->getExpression()->traverse(this);
+ }
+
+ out << ")\n";
+
+ outputLineDirective(out, node->getLine().first_line);
+ }
+
+ if (node->getBody())
+ {
+ // The loop body node will output braces.
+ node->getBody()->traverse(this);
+ }
+ else
+ {
+ // TODO(oetuaho): Check if the semicolon inside is necessary.
+ // It's there as a result of conservative refactoring of the output.
+ out << "{;}\n";
+ }
+
+ outputLineDirective(out, node->getLine().first_line);
+
+ if (node->getType() == ELoopDoWhile)
+ {
+ outputLineDirective(out, node->getCondition()->getLine().first_line);
+ out << "while (";
+
+ node->getCondition()->traverse(this);
+
+ out << ");\n";
+ }
+
+ out << "}\n";
+
+ mInsideDiscontinuousLoop = wasDiscontinuous;
+ mNestedLoopDepth--;
+
+ return false;
+}
+
+bool OutputHLSL::visitBranch(Visit visit, TIntermBranch *node)
+{
+ if (visit == PreVisit)
+ {
+ TInfoSinkBase &out = getInfoSink();
+
+ switch (node->getFlowOp())
+ {
+ case EOpKill:
+ out << "discard";
+ break;
+ case EOpBreak:
+ if (mNestedLoopDepth > 1)
+ {
+ mUsesNestedBreak = true;
+ }
+
+ if (mExcessiveLoopIndex)
+ {
+ out << "{Break";
+ mExcessiveLoopIndex->traverse(this);
+ out << " = true; break;}\n";
+ }
+ else
+ {
+ out << "break";
+ }
+ break;
+ case EOpContinue:
+ out << "continue";
+ break;
+ case EOpReturn:
+ if (node->getExpression())
+ {
+ ASSERT(!mInsideMain);
+ out << "return ";
+ if (IsInShaderStorageBlock(node->getExpression()))
+ {
+ mSSBOOutputHLSL->outputLoadFunctionCall(node->getExpression());
+ return false;
+ }
+ }
+ else
+ {
+ if (mInsideMain && shaderNeedsGenerateOutput())
+ {
+ out << "return " << generateOutputCall();
+ }
+ else
+ {
+ out << "return";
+ }
+ }
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ return true;
+}
+
+// Handle loops with more than 254 iterations (unsupported by D3D9) by splitting them
+// (The D3D documentation says 255 iterations, but the compiler complains at anything more than
+// 254).
+bool OutputHLSL::handleExcessiveLoop(TInfoSinkBase &out, TIntermLoop *node)
+{
+ const int MAX_LOOP_ITERATIONS = 254;
+
+ // Parse loops of the form:
+ // for(int index = initial; index [comparator] limit; index += increment)
+ TIntermSymbol *index = nullptr;
+ TOperator comparator = EOpNull;
+ int initial = 0;
+ int limit = 0;
+ int increment = 0;
+
+ // Parse index name and intial value
+ if (node->getInit())
+ {
+ TIntermDeclaration *init = node->getInit()->getAsDeclarationNode();
+
+ if (init)
+ {
+ TIntermSequence *sequence = init->getSequence();
+ TIntermTyped *variable = (*sequence)[0]->getAsTyped();
+
+ if (variable && variable->getQualifier() == EvqTemporary)
+ {
+ TIntermBinary *assign = variable->getAsBinaryNode();
+
+ if (assign != nullptr && assign->getOp() == EOpInitialize)
+ {
+ TIntermSymbol *symbol = assign->getLeft()->getAsSymbolNode();
+ TIntermConstantUnion *constant = assign->getRight()->getAsConstantUnion();
+
+ if (symbol && constant)
+ {
+ if (constant->getBasicType() == EbtInt && constant->isScalar())
+ {
+ index = symbol;
+ initial = constant->getIConst(0);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Parse comparator and limit value
+ if (index != nullptr && node->getCondition())
+ {
+ TIntermBinary *test = node->getCondition()->getAsBinaryNode();
+
+ if (test && test->getLeft()->getAsSymbolNode()->uniqueId() == index->uniqueId())
+ {
+ TIntermConstantUnion *constant = test->getRight()->getAsConstantUnion();
+
+ if (constant)
+ {
+ if (constant->getBasicType() == EbtInt && constant->isScalar())
+ {
+ comparator = test->getOp();
+ limit = constant->getIConst(0);
+ }
+ }
+ }
+ }
+
+ // Parse increment
+ if (index != nullptr && comparator != EOpNull && node->getExpression())
+ {
+ TIntermBinary *binaryTerminal = node->getExpression()->getAsBinaryNode();
+ TIntermUnary *unaryTerminal = node->getExpression()->getAsUnaryNode();
+
+ if (binaryTerminal)
+ {
+ TOperator op = binaryTerminal->getOp();
+ TIntermConstantUnion *constant = binaryTerminal->getRight()->getAsConstantUnion();
+
+ if (constant)
+ {
+ if (constant->getBasicType() == EbtInt && constant->isScalar())
+ {
+ int value = constant->getIConst(0);
+
+ switch (op)
+ {
+ case EOpAddAssign:
+ increment = value;
+ break;
+ case EOpSubAssign:
+ increment = -value;
+ break;
+ default:
+ UNIMPLEMENTED();
+ }
+ }
+ }
+ }
+ else if (unaryTerminal)
+ {
+ TOperator op = unaryTerminal->getOp();
+
+ switch (op)
+ {
+ case EOpPostIncrement:
+ increment = 1;
+ break;
+ case EOpPostDecrement:
+ increment = -1;
+ break;
+ case EOpPreIncrement:
+ increment = 1;
+ break;
+ case EOpPreDecrement:
+ increment = -1;
+ break;
+ default:
+ UNIMPLEMENTED();
+ }
+ }
+ }
+
+ if (index != nullptr && comparator != EOpNull && increment != 0)
+ {
+ if (comparator == EOpLessThanEqual)
+ {
+ comparator = EOpLessThan;
+ limit += 1;
+ }
+
+ if (comparator == EOpLessThan)
+ {
+ int iterations = (limit - initial) / increment;
+
+ if (iterations <= MAX_LOOP_ITERATIONS)
+ {
+ return false; // Not an excessive loop
+ }
+
+ TIntermSymbol *restoreIndex = mExcessiveLoopIndex;
+ mExcessiveLoopIndex = index;
+
+ out << "{int ";
+ index->traverse(this);
+ out << ";\n"
+ "bool Break";
+ index->traverse(this);
+ out << " = false;\n";
+
+ bool firstLoopFragment = true;
+
+ while (iterations > 0)
+ {
+ int clampedLimit = initial + increment * std::min(MAX_LOOP_ITERATIONS, iterations);
+
+ if (!firstLoopFragment)
+ {
+ out << "if (!Break";
+ index->traverse(this);
+ out << ") {\n";
+ }
+
+ if (iterations <= MAX_LOOP_ITERATIONS) // Last loop fragment
+ {
+ mExcessiveLoopIndex = nullptr; // Stops setting the Break flag
+ }
+
+ // for(int index = initial; index < clampedLimit; index += increment)
+ const char *unroll =
+ mCurrentFunctionMetadata->hasGradientInCallGraph(node) ? "LOOP" : "";
+
+ out << unroll << " for(";
+ index->traverse(this);
+ out << " = ";
+ out << initial;
+
+ out << "; ";
+ index->traverse(this);
+ out << " < ";
+ out << clampedLimit;
+
+ out << "; ";
+ index->traverse(this);
+ out << " += ";
+ out << increment;
+ out << ")\n";
+
+ outputLineDirective(out, node->getLine().first_line);
+ out << "{\n";
+
+ if (node->getBody())
+ {
+ node->getBody()->traverse(this);
+ }
+
+ outputLineDirective(out, node->getLine().first_line);
+ out << ";}\n";
+
+ if (!firstLoopFragment)
+ {
+ out << "}\n";
+ }
+
+ firstLoopFragment = false;
+
+ initial += MAX_LOOP_ITERATIONS * increment;
+ iterations -= MAX_LOOP_ITERATIONS;
+ }
+
+ out << "}";
+
+ mExcessiveLoopIndex = restoreIndex;
+
+ return true;
+ }
+ else
+ UNIMPLEMENTED();
+ }
+
+ return false; // Not handled as an excessive loop
+}
+
+void OutputHLSL::outputTriplet(TInfoSinkBase &out,
+ Visit visit,
+ const char *preString,
+ const char *inString,
+ const char *postString)
+{
+ if (visit == PreVisit)
+ {
+ out << preString;
+ }
+ else if (visit == InVisit)
+ {
+ out << inString;
+ }
+ else if (visit == PostVisit)
+ {
+ out << postString;
+ }
+}
+
+void OutputHLSL::outputLineDirective(TInfoSinkBase &out, int line)
+{
+ if (mCompileOptions.lineDirectives && line > 0)
+ {
+ out << "\n";
+ out << "#line " << line;
+
+ if (mSourcePath)
+ {
+ out << " \"" << mSourcePath << "\"";
+ }
+
+ out << "\n";
+ }
+}
+
+void OutputHLSL::writeParameter(const TVariable *param, TInfoSinkBase &out)
+{
+ const TType &type = param->getType();
+ TQualifier qualifier = type.getQualifier();
+
+ TString nameStr = DecorateVariableIfNeeded(*param);
+ ASSERT(nameStr != ""); // HLSL demands named arguments, also for prototypes
+
+ if (IsSampler(type.getBasicType()))
+ {
+ if (mOutputType == SH_HLSL_4_1_OUTPUT)
+ {
+ // Samplers are passed as indices to the sampler array.
+ ASSERT(qualifier != EvqParamOut && qualifier != EvqParamInOut);
+ out << "const uint " << nameStr << ArrayString(type);
+ return;
+ }
+ if (mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT)
+ {
+ out << QualifierString(qualifier) << " " << TextureString(type.getBasicType())
+ << " texture_" << nameStr << ArrayString(type) << ", " << QualifierString(qualifier)
+ << " " << SamplerString(type.getBasicType()) << " sampler_" << nameStr
+ << ArrayString(type);
+ return;
+ }
+ }
+
+ // If the parameter is an atomic counter, we need to add an extra parameter to keep track of the
+ // buffer offset.
+ if (IsAtomicCounter(type.getBasicType()))
+ {
+ out << QualifierString(qualifier) << " " << TypeString(type) << " " << nameStr << ", int "
+ << nameStr << "_offset";
+ }
+ else
+ {
+ out << QualifierString(qualifier) << " " << TypeString(type) << " " << nameStr
+ << ArrayString(type);
+ }
+
+ // If the structure parameter contains samplers, they need to be passed into the function as
+ // separate parameters. HLSL doesn't natively support samplers in structs.
+ if (type.isStructureContainingSamplers())
+ {
+ ASSERT(qualifier != EvqParamOut && qualifier != EvqParamInOut);
+ TVector<const TVariable *> samplerSymbols;
+ std::string namePrefix = "angle";
+ namePrefix += nameStr.c_str();
+ type.createSamplerSymbols(ImmutableString(namePrefix), "", &samplerSymbols, nullptr,
+ mSymbolTable);
+ for (const TVariable *sampler : samplerSymbols)
+ {
+ const TType &samplerType = sampler->getType();
+ if (mOutputType == SH_HLSL_4_1_OUTPUT)
+ {
+ out << ", const uint " << sampler->name() << ArrayString(samplerType);
+ }
+ else if (mOutputType == SH_HLSL_4_0_FL9_3_OUTPUT)
+ {
+ ASSERT(IsSampler(samplerType.getBasicType()));
+ out << ", " << QualifierString(qualifier) << " "
+ << TextureString(samplerType.getBasicType()) << " texture_" << sampler->name()
+ << ArrayString(samplerType) << ", " << QualifierString(qualifier) << " "
+ << SamplerString(samplerType.getBasicType()) << " sampler_" << sampler->name()
+ << ArrayString(samplerType);
+ }
+ else
+ {
+ ASSERT(IsSampler(samplerType.getBasicType()));
+ out << ", " << QualifierString(qualifier) << " " << TypeString(samplerType) << " "
+ << sampler->name() << ArrayString(samplerType);
+ }
+ }
+ }
+}
+
+TString OutputHLSL::zeroInitializer(const TType &type) const
+{
+ TString string;
+
+ size_t size = type.getObjectSize();
+ if (size >= kZeroCount)
+ {
+ mUseZeroArray = true;
+ }
+ string = GetZeroInitializer(size).c_str();
+
+ return "{" + string + "}";
+}
+
+void OutputHLSL::outputConstructor(TInfoSinkBase &out, Visit visit, TIntermAggregate *node)
+{
+ // Array constructors should have been already pruned from the code.
+ ASSERT(!node->getType().isArray());
+
+ if (visit == PreVisit)
+ {
+ TString constructorName;
+ if (node->getBasicType() == EbtStruct)
+ {
+ constructorName = mStructureHLSL->addStructConstructor(*node->getType().getStruct());
+ }
+ else
+ {
+ constructorName =
+ mStructureHLSL->addBuiltInConstructor(node->getType(), node->getSequence());
+ }
+ out << constructorName << "(";
+ }
+ else if (visit == InVisit)
+ {
+ out << ", ";
+ }
+ else if (visit == PostVisit)
+ {
+ out << ")";
+ }
+}
+
+const TConstantUnion *OutputHLSL::writeConstantUnion(TInfoSinkBase &out,
+ const TType &type,
+ const TConstantUnion *const constUnion)
+{
+ ASSERT(!type.isArray());
+
+ const TConstantUnion *constUnionIterated = constUnion;
+
+ const TStructure *structure = type.getStruct();
+ if (structure)
+ {
+ out << mStructureHLSL->addStructConstructor(*structure) << "(";
+
+ const TFieldList &fields = structure->fields();
+
+ for (size_t i = 0; i < fields.size(); i++)
+ {
+ const TType *fieldType = fields[i]->type();
+ constUnionIterated = writeConstantUnion(out, *fieldType, constUnionIterated);
+
+ if (i != fields.size() - 1)
+ {
+ out << ", ";
+ }
+ }
+
+ out << ")";
+ }
+ else
+ {
+ size_t size = type.getObjectSize();
+ bool writeType = size > 1;
+
+ if (writeType)
+ {
+ out << TypeString(type) << "(";
+ }
+ constUnionIterated = writeConstantUnionArray(out, constUnionIterated, size);
+ if (writeType)
+ {
+ out << ")";
+ }
+ }
+
+ return constUnionIterated;
+}
+
+void OutputHLSL::writeEmulatedFunctionTriplet(TInfoSinkBase &out,
+ Visit visit,
+ const TFunction *function)
+{
+ if (visit == PreVisit)
+ {
+ ASSERT(function != nullptr);
+ BuiltInFunctionEmulator::WriteEmulatedFunctionName(out, function->name().data());
+ out << "(";
+ }
+ else
+ {
+ outputTriplet(out, visit, nullptr, ", ", ")");
+ }
+}
+
+bool OutputHLSL::writeSameSymbolInitializer(TInfoSinkBase &out,
+ TIntermSymbol *symbolNode,
+ TIntermTyped *expression)
+{
+ ASSERT(symbolNode->variable().symbolType() != SymbolType::Empty);
+ const TIntermSymbol *symbolInInitializer = FindSymbolNode(expression, symbolNode->getName());
+
+ if (symbolInInitializer)
+ {
+ // Type already printed
+ out << "t" + str(mUniqueIndex) + " = ";
+ expression->traverse(this);
+ out << ", ";
+ symbolNode->traverse(this);
+ out << " = t" + str(mUniqueIndex);
+
+ mUniqueIndex++;
+ return true;
+ }
+
+ return false;
+}
+
+bool OutputHLSL::writeConstantInitialization(TInfoSinkBase &out,
+ TIntermSymbol *symbolNode,
+ TIntermTyped *initializer)
+{
+ if (initializer->hasConstantValue())
+ {
+ symbolNode->traverse(this);
+ out << ArrayString(symbolNode->getType());
+ out << " = {";
+ writeConstantUnionArray(out, initializer->getConstantValue(),
+ initializer->getType().getObjectSize());
+ out << "}";
+ return true;
+ }
+ return false;
+}
+
+TString OutputHLSL::addStructEqualityFunction(const TStructure &structure)
+{
+ const TFieldList &fields = structure.fields();
+
+ for (const auto &eqFunction : mStructEqualityFunctions)
+ {
+ if (eqFunction->structure == &structure)
+ {
+ return eqFunction->functionName;
+ }
+ }
+
+ const TString &structNameString = StructNameString(structure);
+
+ StructEqualityFunction *function = new StructEqualityFunction();
+ function->structure = &structure;
+ function->functionName = "angle_eq_" + structNameString;
+
+ TInfoSinkBase fnOut;
+
+ fnOut << "bool " << function->functionName << "(" << structNameString << " a, "
+ << structNameString + " b)\n"
+ << "{\n"
+ " return ";
+
+ for (size_t i = 0; i < fields.size(); i++)
+ {
+ const TField *field = fields[i];
+ const TType *fieldType = field->type();
+
+ const TString &fieldNameA = "a." + Decorate(field->name());
+ const TString &fieldNameB = "b." + Decorate(field->name());
+
+ if (i > 0)
+ {
+ fnOut << " && ";
+ }
+
+ fnOut << "(";
+ outputEqual(PreVisit, *fieldType, EOpEqual, fnOut);
+ fnOut << fieldNameA;
+ outputEqual(InVisit, *fieldType, EOpEqual, fnOut);
+ fnOut << fieldNameB;
+ outputEqual(PostVisit, *fieldType, EOpEqual, fnOut);
+ fnOut << ")";
+ }
+
+ fnOut << ";\n"
+ << "}\n";
+
+ function->functionDefinition = fnOut.c_str();
+
+ mStructEqualityFunctions.push_back(function);
+ mEqualityFunctions.push_back(function);
+
+ return function->functionName;
+}
+
+TString OutputHLSL::addArrayEqualityFunction(const TType &type)
+{
+ for (const auto &eqFunction : mArrayEqualityFunctions)
+ {
+ if (eqFunction->type == type)
+ {
+ return eqFunction->functionName;
+ }
+ }
+
+ TType elementType(type);
+ elementType.toArrayElementType();
+
+ ArrayHelperFunction *function = new ArrayHelperFunction();
+ function->type = type;
+
+ function->functionName = ArrayHelperFunctionName("angle_eq", type);
+
+ TInfoSinkBase fnOut;
+
+ const TString &typeName = TypeString(type);
+ fnOut << "bool " << function->functionName << "(" << typeName << " a" << ArrayString(type)
+ << ", " << typeName << " b" << ArrayString(type) << ")\n"
+ << "{\n"
+ " for (int i = 0; i < "
+ << type.getOutermostArraySize()
+ << "; ++i)\n"
+ " {\n"
+ " if (";
+
+ outputEqual(PreVisit, elementType, EOpNotEqual, fnOut);
+ fnOut << "a[i]";
+ outputEqual(InVisit, elementType, EOpNotEqual, fnOut);
+ fnOut << "b[i]";
+ outputEqual(PostVisit, elementType, EOpNotEqual, fnOut);
+
+ fnOut << ") { return false; }\n"
+ " }\n"
+ " return true;\n"
+ "}\n";
+
+ function->functionDefinition = fnOut.c_str();
+
+ mArrayEqualityFunctions.push_back(function);
+ mEqualityFunctions.push_back(function);
+
+ return function->functionName;
+}
+
+TString OutputHLSL::addArrayAssignmentFunction(const TType &type)
+{
+ for (const auto &assignFunction : mArrayAssignmentFunctions)
+ {
+ if (assignFunction.type == type)
+ {
+ return assignFunction.functionName;
+ }
+ }
+
+ TType elementType(type);
+ elementType.toArrayElementType();
+
+ ArrayHelperFunction function;
+ function.type = type;
+
+ function.functionName = ArrayHelperFunctionName("angle_assign", type);
+
+ TInfoSinkBase fnOut;
+
+ const TString &typeName = TypeString(type);
+ fnOut << "void " << function.functionName << "(out " << typeName << " a" << ArrayString(type)
+ << ", " << typeName << " b" << ArrayString(type) << ")\n"
+ << "{\n"
+ " for (int i = 0; i < "
+ << type.getOutermostArraySize()
+ << "; ++i)\n"
+ " {\n"
+ " ";
+
+ outputAssign(PreVisit, elementType, fnOut);
+ fnOut << "a[i]";
+ outputAssign(InVisit, elementType, fnOut);
+ fnOut << "b[i]";
+ outputAssign(PostVisit, elementType, fnOut);
+
+ fnOut << ";\n"
+ " }\n"
+ "}\n";
+
+ function.functionDefinition = fnOut.c_str();
+
+ mArrayAssignmentFunctions.push_back(function);
+
+ return function.functionName;
+}
+
+TString OutputHLSL::addArrayConstructIntoFunction(const TType &type)
+{
+ for (const auto &constructIntoFunction : mArrayConstructIntoFunctions)
+ {
+ if (constructIntoFunction.type == type)
+ {
+ return constructIntoFunction.functionName;
+ }
+ }
+
+ TType elementType(type);
+ elementType.toArrayElementType();
+
+ ArrayHelperFunction function;
+ function.type = type;
+
+ function.functionName = ArrayHelperFunctionName("angle_construct_into", type);
+
+ TInfoSinkBase fnOut;
+
+ const TString &typeName = TypeString(type);
+ fnOut << "void " << function.functionName << "(out " << typeName << " a" << ArrayString(type);
+ for (unsigned int i = 0u; i < type.getOutermostArraySize(); ++i)
+ {
+ fnOut << ", " << typeName << " b" << i << ArrayString(elementType);
+ }
+ fnOut << ")\n"
+ "{\n";
+
+ for (unsigned int i = 0u; i < type.getOutermostArraySize(); ++i)
+ {
+ fnOut << " ";
+ outputAssign(PreVisit, elementType, fnOut);
+ fnOut << "a[" << i << "]";
+ outputAssign(InVisit, elementType, fnOut);
+ fnOut << "b" << i;
+ outputAssign(PostVisit, elementType, fnOut);
+ fnOut << ";\n";
+ }
+ fnOut << "}\n";
+
+ function.functionDefinition = fnOut.c_str();
+
+ mArrayConstructIntoFunctions.push_back(function);
+
+ return function.functionName;
+}
+
+void OutputHLSL::ensureStructDefined(const TType &type)
+{
+ const TStructure *structure = type.getStruct();
+ if (structure)
+ {
+ ASSERT(type.getBasicType() == EbtStruct);
+ mStructureHLSL->ensureStructDefined(*structure);
+ }
+}
+
+bool OutputHLSL::shaderNeedsGenerateOutput() const
+{
+ return mShaderType == GL_VERTEX_SHADER || mShaderType == GL_FRAGMENT_SHADER;
+}
+
+const char *OutputHLSL::generateOutputCall() const
+{
+ if (mShaderType == GL_VERTEX_SHADER)
+ {
+ return "generateOutput(input)";
+ }
+ else
+ {
+ return "generateOutput()";
+ }
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/OutputHLSL.h b/gfx/angle/checkout/src/compiler/translator/OutputHLSL.h
new file mode 100644
index 0000000000..06cc22d486
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/OutputHLSL.h
@@ -0,0 +1,289 @@
+//
+// Copyright 2002 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_OUTPUTHLSL_H_
+#define COMPILER_TRANSLATOR_OUTPUTHLSL_H_
+
+#include <list>
+#include <map>
+#include <stack>
+
+#include "angle_gl.h"
+#include "compiler/translator/ASTMetadataHLSL.h"
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/FlagStd140Structs.h"
+#include "compiler/translator/ImmutableString.h"
+#include "compiler/translator/ShaderStorageBlockOutputHLSL.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+class BuiltInFunctionEmulator;
+
+namespace sh
+{
+class AtomicCounterFunctionHLSL;
+class ImageFunctionHLSL;
+class ResourcesHLSL;
+class StructureHLSL;
+class TextureFunctionHLSL;
+class TSymbolTable;
+class TVariable;
+class UnfoldShortCircuit;
+
+using ReferencedVariables = std::map<int, const TVariable *>;
+
+class OutputHLSL : public TIntermTraverser
+{
+ public:
+ OutputHLSL(sh::GLenum shaderType,
+ ShShaderSpec shaderSpec,
+ int shaderVersion,
+ const TExtensionBehavior &extensionBehavior,
+ const char *sourcePath,
+ ShShaderOutput outputType,
+ int numRenderTargets,
+ int maxDualSourceDrawBuffers,
+ const std::vector<ShaderVariable> &uniforms,
+ const ShCompileOptions &compileOptions,
+ sh::WorkGroupSize workGroupSize,
+ TSymbolTable *symbolTable,
+ PerformanceDiagnostics *perfDiagnostics,
+ const std::map<int, const TInterfaceBlock *> &uniformBlockOptimizedMap,
+ const std::vector<InterfaceBlock> &shaderStorageBlocks,
+ bool isEarlyFragmentTestsSpecified);
+
+ ~OutputHLSL() override;
+
+ void output(TIntermNode *treeRoot, TInfoSinkBase &objSink);
+
+ const std::map<std::string, unsigned int> &getShaderStorageBlockRegisterMap() const;
+ const std::map<std::string, unsigned int> &getUniformBlockRegisterMap() const;
+ const std::map<std::string, bool> &getUniformBlockUseStructuredBufferMap() const;
+ const std::map<std::string, unsigned int> &getUniformRegisterMap() const;
+ unsigned int getReadonlyImage2DRegisterIndex() const;
+ unsigned int getImage2DRegisterIndex() const;
+ const std::set<std::string> &getUsedImage2DFunctionNames() const;
+
+ TInfoSinkBase &getInfoSink()
+ {
+ ASSERT(!mInfoSinkStack.empty());
+ return *mInfoSinkStack.top();
+ }
+
+ protected:
+ friend class ShaderStorageBlockOutputHLSL;
+
+ TString zeroInitializer(const TType &type) const;
+
+ void writeReferencedAttributes(TInfoSinkBase &out) const;
+ void writeReferencedVaryings(TInfoSinkBase &out) const;
+ void header(TInfoSinkBase &out,
+ const std::vector<MappedStruct> &std140Structs,
+ const BuiltInFunctionEmulator *builtInFunctionEmulator) const;
+
+ void writeFloat(TInfoSinkBase &out, float f);
+ void writeSingleConstant(TInfoSinkBase &out, const TConstantUnion *const constUnion);
+ const TConstantUnion *writeConstantUnionArray(TInfoSinkBase &out,
+ const TConstantUnion *const constUnion,
+ const size_t size);
+
+ // Visit AST nodes and output their code to the body stream
+ 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 visitTernary(Visit visit, TIntermTernary *) override;
+ bool visitIfElse(Visit visit, TIntermIfElse *) override;
+ bool visitSwitch(Visit visit, TIntermSwitch *) override;
+ bool visitCase(Visit visit, TIntermCase *) override;
+ void visitFunctionPrototype(TIntermFunctionPrototype *node) override;
+ bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override;
+ bool visitAggregate(Visit visit, TIntermAggregate *) override;
+ bool visitBlock(Visit visit, TIntermBlock *node) override;
+ bool visitGlobalQualifierDeclaration(Visit visit,
+ TIntermGlobalQualifierDeclaration *node) override;
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
+ bool visitLoop(Visit visit, TIntermLoop *) override;
+ bool visitBranch(Visit visit, TIntermBranch *) override;
+
+ bool handleExcessiveLoop(TInfoSinkBase &out, TIntermLoop *node);
+
+ // Emit one of three strings depending on traverse phase. Called with literal strings so using
+ // const char* instead of TString.
+ void outputTriplet(TInfoSinkBase &out,
+ Visit visit,
+ const char *preString,
+ const char *inString,
+ const char *postString);
+ void outputLineDirective(TInfoSinkBase &out, int line);
+ void writeParameter(const TVariable *param, TInfoSinkBase &out);
+
+ void outputConstructor(TInfoSinkBase &out, Visit visit, TIntermAggregate *node);
+ const TConstantUnion *writeConstantUnion(TInfoSinkBase &out,
+ const TType &type,
+ const TConstantUnion *constUnion);
+
+ void outputEqual(Visit visit, const TType &type, TOperator op, TInfoSinkBase &out);
+ void outputAssign(Visit visit, const TType &type, TInfoSinkBase &out);
+
+ void writeEmulatedFunctionTriplet(TInfoSinkBase &out, Visit visit, const TFunction *function);
+
+ // Returns true if it found a 'same symbol' initializer (initializer that references the
+ // variable it's initting)
+ bool writeSameSymbolInitializer(TInfoSinkBase &out,
+ TIntermSymbol *symbolNode,
+ TIntermTyped *expression);
+ // Returns true if variable initializer could be written using literal {} notation.
+ bool writeConstantInitialization(TInfoSinkBase &out,
+ TIntermSymbol *symbolNode,
+ TIntermTyped *expression);
+
+ void writeIfElse(TInfoSinkBase &out, TIntermIfElse *node);
+
+ // Returns the function name
+ TString addStructEqualityFunction(const TStructure &structure);
+ TString addArrayEqualityFunction(const TType &type);
+ TString addArrayAssignmentFunction(const TType &type);
+ TString addArrayConstructIntoFunction(const TType &type);
+
+ // Ensures if the type is a struct, the struct is defined
+ void ensureStructDefined(const TType &type);
+
+ bool shaderNeedsGenerateOutput() const;
+ const char *generateOutputCall() const;
+
+ sh::GLenum mShaderType;
+ ShShaderSpec mShaderSpec;
+ int mShaderVersion;
+ const TExtensionBehavior &mExtensionBehavior;
+ const char *mSourcePath;
+ const ShShaderOutput mOutputType;
+ const ShCompileOptions &mCompileOptions;
+
+ bool mInsideFunction;
+ bool mInsideMain;
+
+ // Output streams
+ TInfoSinkBase mHeader;
+ TInfoSinkBase mBody;
+ TInfoSinkBase mFooter;
+
+ // A stack is useful when we want to traverse in the header, or in helper functions, but not
+ // always write to the body. Instead use an InfoSink stack to keep our current state intact.
+ // TODO (jmadill): Just passing an InfoSink in function parameters would be simpler.
+ std::stack<TInfoSinkBase *> mInfoSinkStack;
+
+ ReferencedVariables mReferencedUniforms;
+
+ // Indexed by block id, not instance id.
+ ReferencedInterfaceBlocks mReferencedUniformBlocks;
+
+ std::map<int, const TInterfaceBlock *> mUniformBlockOptimizedMap;
+
+ ReferencedVariables mReferencedAttributes;
+ ReferencedVariables mReferencedVaryings;
+ ReferencedVariables mReferencedOutputVariables;
+
+ StructureHLSL *mStructureHLSL;
+ ResourcesHLSL *mResourcesHLSL;
+ TextureFunctionHLSL *mTextureFunctionHLSL;
+ ImageFunctionHLSL *mImageFunctionHLSL;
+ AtomicCounterFunctionHLSL *mAtomicCounterFunctionHLSL;
+
+ // Parameters determining what goes in the header output
+ bool mUsesFragColor;
+ bool mUsesFragData;
+ bool mUsesDepthRange;
+ bool mUsesFragCoord;
+ bool mUsesPointCoord;
+ bool mUsesFrontFacing;
+ bool mUsesHelperInvocation;
+ bool mUsesPointSize;
+ bool mUsesInstanceID;
+ bool mHasMultiviewExtensionEnabled;
+ bool mUsesViewID;
+ bool mUsesVertexID;
+ bool mUsesFragDepth;
+ bool mUsesNumWorkGroups;
+ bool mUsesWorkGroupID;
+ bool mUsesLocalInvocationID;
+ bool mUsesGlobalInvocationID;
+ bool mUsesLocalInvocationIndex;
+ bool mUsesXor;
+ bool mUsesDiscardRewriting;
+ bool mUsesNestedBreak;
+ bool mRequiresIEEEStrictCompiling;
+ mutable bool mUseZeroArray;
+ bool mUsesSecondaryColor;
+
+ int mNumRenderTargets;
+ int mMaxDualSourceDrawBuffers;
+
+ int mUniqueIndex; // For creating unique names
+
+ CallDAG mCallDag;
+ MetadataList mASTMetadataList;
+ ASTMetadataHLSL *mCurrentFunctionMetadata;
+ bool mOutputLod0Function;
+ bool mInsideDiscontinuousLoop;
+ int mNestedLoopDepth;
+
+ TIntermSymbol *mExcessiveLoopIndex;
+
+ TString structInitializerString(int indent, const TType &type, const TString &name) const;
+
+ struct HelperFunction
+ {
+ TString functionName;
+ TString functionDefinition;
+
+ virtual ~HelperFunction() {}
+ };
+
+ // A list of all equality comparison functions. It's important to preserve the order at
+ // which we add the functions, since nested structures call each other recursively, and
+ // structure equality functions may need to call array equality functions and vice versa.
+ // The ownership of the pointers is maintained by the type-specific arrays.
+ std::vector<HelperFunction *> mEqualityFunctions;
+
+ struct StructEqualityFunction : public HelperFunction
+ {
+ const TStructure *structure;
+ };
+ std::vector<StructEqualityFunction *> mStructEqualityFunctions;
+
+ struct ArrayHelperFunction : public HelperFunction
+ {
+ TType type;
+ };
+ std::vector<ArrayHelperFunction *> mArrayEqualityFunctions;
+
+ std::vector<ArrayHelperFunction> mArrayAssignmentFunctions;
+
+ // The construct-into functions are functions that fill an N-element array passed as an out
+ // parameter with the other N parameters of the function. This is used to work around that
+ // arrays can't be return values in HLSL.
+ std::vector<ArrayHelperFunction> mArrayConstructIntoFunctions;
+
+ sh::WorkGroupSize mWorkGroupSize;
+
+ PerformanceDiagnostics *mPerfDiagnostics;
+
+ private:
+ TString generateStructMapping(const std::vector<MappedStruct> &std140Structs) const;
+ ImmutableString samplerNamePrefixFromStruct(TIntermTyped *node);
+ bool ancestorEvaluatesToSamplerInStruct();
+ // We need to do struct mapping when pass the struct to a function or copy the struct via
+ // assignment.
+ bool needStructMapping(TIntermTyped *node);
+
+ ShaderStorageBlockOutputHLSL *mSSBOOutputHLSL;
+ bool mIsEarlyFragmentTestsSpecified;
+ bool mNeedStructMapping;
+};
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_OUTPUTHLSL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/OutputTree.cpp b/gfx/angle/checkout/src/compiler/translator/OutputTree.cpp
new file mode 100644
index 0000000000..f51e891ce8
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/OutputTree.cpp
@@ -0,0 +1,723 @@
+//
+// Copyright 2002 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/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+void OutputFunction(TInfoSinkBase &out, const char *str, const TFunction *func)
+{
+ const char *internal =
+ (func->symbolType() == SymbolType::AngleInternal) ? " (internal function)" : "";
+ out << str << internal << ": " << func->name() << " (symbol id " << func->uniqueId().get()
+ << ")";
+}
+
+// Two purposes:
+// 1. Show an example of how to iterate tree. Functions can also directly call traverse() on
+// children themselves to have finer grained control over the process than shown here, though
+// that's not recommended if it can be avoided.
+// 2. Print out a text based description of the tree.
+
+// The traverser subclass is used to carry along data from node to node in the traversal.
+class TOutputTraverser : public TIntermTraverser
+{
+ public:
+ TOutputTraverser(TInfoSinkBase &out)
+ : TIntermTraverser(true, false, false), mOut(out), mIndentDepth(0)
+ {}
+
+ 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 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;
+ void visitFunctionPrototype(TIntermFunctionPrototype *node) override;
+ bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override;
+ bool visitAggregate(Visit visit, TIntermAggregate *) override;
+ bool visitBlock(Visit visit, TIntermBlock *) override;
+ bool visitGlobalQualifierDeclaration(Visit visit,
+ TIntermGlobalQualifierDeclaration *node) override;
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
+ bool visitLoop(Visit visit, TIntermLoop *) override;
+ bool visitBranch(Visit visit, TIntermBranch *) override;
+
+ int getCurrentIndentDepth() const { return mIndentDepth + getCurrentTraversalDepth(); }
+
+ TInfoSinkBase &mOut;
+ int mIndentDepth;
+};
+
+//
+// Helper functions for printing, not part of traversing.
+//
+void OutputTreeText(TInfoSinkBase &out, TIntermNode *node, const int depth)
+{
+ int i;
+
+ out.location(node->getLine().first_file, node->getLine().first_line);
+
+ for (i = 0; i < depth; ++i)
+ out << " ";
+}
+
+//
+// The rest of the file are the traversal functions. The last one
+// is the one that starts the traversal.
+//
+// Return true from interior nodes to have the external traversal
+// continue on to children. If you process children yourself,
+// return false.
+//
+
+void TOutputTraverser::visitSymbol(TIntermSymbol *node)
+{
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+
+ if (node->variable().symbolType() == SymbolType::Empty)
+ {
+ mOut << "''";
+ }
+ else
+ {
+ mOut << "'" << node->getName() << "' ";
+ }
+ mOut << "(symbol id " << node->uniqueId().get() << ") ";
+ mOut << "(" << node->getType() << ")";
+ mOut << "\n";
+}
+
+bool TOutputTraverser::visitSwizzle(Visit visit, TIntermSwizzle *node)
+{
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+ mOut << "vector swizzle (";
+ node->writeOffsetsAsXYZW(&mOut);
+ mOut << ")";
+
+ mOut << " (" << node->getType() << ")";
+ mOut << "\n";
+ return true;
+}
+
+bool TOutputTraverser::visitBinary(Visit visit, TIntermBinary *node)
+{
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+
+ switch (node->getOp())
+ {
+ case EOpComma:
+ mOut << "comma";
+ break;
+ case EOpAssign:
+ mOut << "move second child to first child";
+ break;
+ case EOpInitialize:
+ mOut << "initialize first child with second child";
+ break;
+ case EOpAddAssign:
+ mOut << "add second child into first child";
+ break;
+ case EOpSubAssign:
+ mOut << "subtract second child into first child";
+ break;
+ case EOpMulAssign:
+ mOut << "multiply second child into first child";
+ break;
+ case EOpVectorTimesMatrixAssign:
+ mOut << "matrix mult second child into first child";
+ break;
+ case EOpVectorTimesScalarAssign:
+ mOut << "vector scale second child into first child";
+ break;
+ case EOpMatrixTimesScalarAssign:
+ mOut << "matrix scale second child into first child";
+ break;
+ case EOpMatrixTimesMatrixAssign:
+ mOut << "matrix mult second child into first child";
+ break;
+ case EOpDivAssign:
+ mOut << "divide second child into first child";
+ break;
+ case EOpIModAssign:
+ mOut << "modulo second child into first child";
+ break;
+ case EOpBitShiftLeftAssign:
+ mOut << "bit-wise shift first child left by second child";
+ break;
+ case EOpBitShiftRightAssign:
+ mOut << "bit-wise shift first child right by second child";
+ break;
+ case EOpBitwiseAndAssign:
+ mOut << "bit-wise and second child into first child";
+ break;
+ case EOpBitwiseXorAssign:
+ mOut << "bit-wise xor second child into first child";
+ break;
+ case EOpBitwiseOrAssign:
+ mOut << "bit-wise or second child into first child";
+ break;
+
+ case EOpIndexDirect:
+ mOut << "direct index";
+ break;
+ case EOpIndexIndirect:
+ mOut << "indirect index";
+ break;
+ case EOpIndexDirectStruct:
+ mOut << "direct index for structure";
+ break;
+ case EOpIndexDirectInterfaceBlock:
+ mOut << "direct index for interface block";
+ break;
+
+ case EOpAdd:
+ mOut << "add";
+ break;
+ case EOpSub:
+ mOut << "subtract";
+ break;
+ case EOpMul:
+ mOut << "component-wise multiply";
+ break;
+ case EOpDiv:
+ mOut << "divide";
+ break;
+ case EOpIMod:
+ mOut << "modulo";
+ break;
+ case EOpBitShiftLeft:
+ mOut << "bit-wise shift left";
+ break;
+ case EOpBitShiftRight:
+ mOut << "bit-wise shift right";
+ break;
+ case EOpBitwiseAnd:
+ mOut << "bit-wise and";
+ break;
+ case EOpBitwiseXor:
+ mOut << "bit-wise xor";
+ break;
+ case EOpBitwiseOr:
+ mOut << "bit-wise or";
+ break;
+
+ case EOpEqual:
+ mOut << "Compare Equal";
+ break;
+ case EOpNotEqual:
+ mOut << "Compare Not Equal";
+ break;
+ case EOpLessThan:
+ mOut << "Compare Less Than";
+ break;
+ case EOpGreaterThan:
+ mOut << "Compare Greater Than";
+ break;
+ case EOpLessThanEqual:
+ mOut << "Compare Less Than or Equal";
+ break;
+ case EOpGreaterThanEqual:
+ mOut << "Compare Greater Than or Equal";
+ break;
+
+ case EOpVectorTimesScalar:
+ mOut << "vector-scale";
+ break;
+ case EOpVectorTimesMatrix:
+ mOut << "vector-times-matrix";
+ break;
+ case EOpMatrixTimesVector:
+ mOut << "matrix-times-vector";
+ break;
+ case EOpMatrixTimesScalar:
+ mOut << "matrix-scale";
+ break;
+ case EOpMatrixTimesMatrix:
+ mOut << "matrix-multiply";
+ break;
+
+ case EOpLogicalOr:
+ mOut << "logical-or";
+ break;
+ case EOpLogicalXor:
+ mOut << "logical-xor";
+ break;
+ case EOpLogicalAnd:
+ mOut << "logical-and";
+ break;
+ default:
+ mOut << "<unknown op>";
+ }
+
+ mOut << " (" << node->getType() << ")";
+
+ mOut << "\n";
+
+ // Special handling for direct indexes. Because constant
+ // unions are not aware they are struct indexes, treat them
+ // here where we have that contextual knowledge.
+ if (node->getOp() == EOpIndexDirectStruct || node->getOp() == EOpIndexDirectInterfaceBlock)
+ {
+ node->getLeft()->traverse(this);
+
+ TIntermConstantUnion *intermConstantUnion = node->getRight()->getAsConstantUnion();
+ ASSERT(intermConstantUnion);
+
+ OutputTreeText(mOut, intermConstantUnion, getCurrentIndentDepth() + 1);
+
+ // The following code finds the field name from the constant union
+ const TConstantUnion *constantUnion = intermConstantUnion->getConstantValue();
+ const TStructure *structure = node->getLeft()->getType().getStruct();
+ const TInterfaceBlock *interfaceBlock = node->getLeft()->getType().getInterfaceBlock();
+ ASSERT(structure || interfaceBlock);
+
+ const TFieldList &fields = structure ? structure->fields() : interfaceBlock->fields();
+
+ const TField *field = fields[constantUnion->getIConst()];
+
+ mOut << constantUnion->getIConst() << " (field '" << field->name() << "')";
+
+ mOut << "\n";
+
+ return false;
+ }
+
+ return true;
+}
+
+bool TOutputTraverser::visitUnary(Visit visit, TIntermUnary *node)
+{
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+
+ const TOperator op = node->getOp();
+
+ switch (op)
+ {
+ // Give verbose names for ops that have special syntax and some built-in functions that are
+ // easy to confuse with others, but mostly use GLSL names for functions.
+ case EOpNegative:
+ mOut << "Negate value";
+ break;
+ case EOpPositive:
+ mOut << "Positive sign";
+ break;
+ case EOpLogicalNot:
+ mOut << "negation";
+ break;
+ case EOpBitwiseNot:
+ mOut << "bit-wise not";
+ break;
+
+ case EOpPostIncrement:
+ mOut << "Post-Increment";
+ break;
+ case EOpPostDecrement:
+ mOut << "Post-Decrement";
+ break;
+ case EOpPreIncrement:
+ mOut << "Pre-Increment";
+ break;
+ case EOpPreDecrement:
+ mOut << "Pre-Decrement";
+ break;
+
+ case EOpArrayLength:
+ mOut << "Array length";
+ break;
+
+ case EOpNotComponentWise:
+ mOut << "component-wise not";
+ break;
+
+ default:
+ if (BuiltInGroup::IsBuiltIn(op))
+ {
+ OutputFunction(mOut, "Call a built-in function", node->getFunction());
+ }
+ else
+ {
+ mOut << GetOperatorString(node->getOp());
+ }
+ break;
+ }
+
+ mOut << " (" << node->getType() << ")";
+
+ mOut << "\n";
+
+ return true;
+}
+
+bool TOutputTraverser::visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node)
+{
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+ mOut << "Function Definition:\n";
+ return true;
+}
+
+bool TOutputTraverser::visitGlobalQualifierDeclaration(Visit visit,
+ TIntermGlobalQualifierDeclaration *node)
+{
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+ if (node->isPrecise())
+ {
+ mOut << "Precise Declaration:\n";
+ }
+ else
+ {
+ mOut << "Invariant Declaration:\n";
+ }
+ return true;
+}
+
+void TOutputTraverser::visitFunctionPrototype(TIntermFunctionPrototype *node)
+{
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+ OutputFunction(mOut, "Function Prototype", node->getFunction());
+ mOut << " (" << node->getType() << ")";
+ mOut << "\n";
+ size_t paramCount = node->getFunction()->getParamCount();
+ for (size_t i = 0; i < paramCount; ++i)
+ {
+ const TVariable *param = node->getFunction()->getParam(i);
+ OutputTreeText(mOut, node, getCurrentIndentDepth() + 1);
+ mOut << "parameter: " << param->name() << " (" << param->getType() << ")\n";
+ }
+}
+
+bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
+{
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+
+ const TOperator op = node->getOp();
+
+ if (op == EOpNull)
+ {
+ mOut.prefix(SH_ERROR);
+ mOut << "node is still EOpNull!\n";
+ return true;
+ }
+
+ // Give verbose names for some built-in functions that are easy to confuse with others, but
+ // mostly use GLSL names for functions.
+ switch (op)
+ {
+ case EOpCallFunctionInAST:
+ OutputFunction(mOut, "Call a user-defined function", node->getFunction());
+ break;
+ case EOpCallInternalRawFunction:
+ OutputFunction(mOut, "Call an internal function with raw implementation",
+ node->getFunction());
+ break;
+
+ case EOpConstruct:
+ // The type of the constructor will be printed below.
+ mOut << "Construct";
+ break;
+
+ case EOpEqualComponentWise:
+ mOut << "component-wise equal";
+ break;
+ case EOpNotEqualComponentWise:
+ mOut << "component-wise not equal";
+ break;
+ case EOpLessThanComponentWise:
+ mOut << "component-wise less than";
+ break;
+ case EOpGreaterThanComponentWise:
+ mOut << "component-wise greater than";
+ break;
+ case EOpLessThanEqualComponentWise:
+ mOut << "component-wise less than or equal";
+ break;
+ case EOpGreaterThanEqualComponentWise:
+ mOut << "component-wise greater than or equal";
+ break;
+
+ case EOpDot:
+ mOut << "dot product";
+ break;
+ case EOpCross:
+ mOut << "cross product";
+ break;
+ case EOpMatrixCompMult:
+ mOut << "component-wise multiply";
+ break;
+
+ default:
+ if (BuiltInGroup::IsBuiltIn(op))
+ {
+ OutputFunction(mOut, "Call a built-in function", node->getFunction());
+ }
+ else
+ {
+ mOut << GetOperatorString(node->getOp());
+ }
+ break;
+ }
+
+ mOut << " (" << node->getType() << ")";
+
+ mOut << "\n";
+
+ return true;
+}
+
+bool TOutputTraverser::visitBlock(Visit visit, TIntermBlock *node)
+{
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+ mOut << "Code block\n";
+
+ return true;
+}
+
+bool TOutputTraverser::visitDeclaration(Visit visit, TIntermDeclaration *node)
+{
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+ mOut << "Declaration\n";
+
+ return true;
+}
+
+bool TOutputTraverser::visitTernary(Visit visit, TIntermTernary *node)
+{
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+
+ mOut << "Ternary selection";
+ mOut << " (" << node->getType() << ")\n";
+
+ ++mIndentDepth;
+
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+ mOut << "Condition\n";
+ node->getCondition()->traverse(this);
+
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+ if (node->getTrueExpression())
+ {
+ mOut << "true case\n";
+ node->getTrueExpression()->traverse(this);
+ }
+ if (node->getFalseExpression())
+ {
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+ mOut << "false case\n";
+ node->getFalseExpression()->traverse(this);
+ }
+
+ --mIndentDepth;
+
+ return false;
+}
+
+bool TOutputTraverser::visitIfElse(Visit visit, TIntermIfElse *node)
+{
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+
+ mOut << "If test\n";
+
+ ++mIndentDepth;
+
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+ mOut << "Condition\n";
+ node->getCondition()->traverse(this);
+
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+ if (node->getTrueBlock())
+ {
+ mOut << "true case\n";
+ node->getTrueBlock()->traverse(this);
+ }
+ else
+ {
+ mOut << "true case is null\n";
+ }
+
+ if (node->getFalseBlock())
+ {
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+ mOut << "false case\n";
+ node->getFalseBlock()->traverse(this);
+ }
+
+ --mIndentDepth;
+
+ return false;
+}
+
+bool TOutputTraverser::visitSwitch(Visit visit, TIntermSwitch *node)
+{
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+
+ mOut << "Switch\n";
+
+ return true;
+}
+
+bool TOutputTraverser::visitCase(Visit visit, TIntermCase *node)
+{
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+
+ if (node->getCondition() == nullptr)
+ {
+ mOut << "Default\n";
+ }
+ else
+ {
+ mOut << "Case\n";
+ }
+
+ return true;
+}
+
+void TOutputTraverser::visitConstantUnion(TIntermConstantUnion *node)
+{
+ size_t size = node->getType().getObjectSize();
+
+ for (size_t i = 0; i < size; i++)
+ {
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+ switch (node->getConstantValue()[i].getType())
+ {
+ case EbtBool:
+ if (node->getConstantValue()[i].getBConst())
+ mOut << "true";
+ else
+ mOut << "false";
+
+ mOut << " ("
+ << "const bool"
+ << ")";
+ mOut << "\n";
+ break;
+ case EbtFloat:
+ mOut << node->getConstantValue()[i].getFConst();
+ mOut << " (const float)\n";
+ break;
+ case EbtInt:
+ mOut << node->getConstantValue()[i].getIConst();
+ mOut << " (const int)\n";
+ break;
+ case EbtUInt:
+ mOut << node->getConstantValue()[i].getUConst();
+ mOut << " (const uint)\n";
+ break;
+ case EbtYuvCscStandardEXT:
+ mOut << getYuvCscStandardEXTString(
+ node->getConstantValue()[i].getYuvCscStandardEXTConst());
+ mOut << " (const yuvCscStandardEXT)\n";
+ break;
+ default:
+ mOut.prefix(SH_ERROR);
+ mOut << "Unknown constant\n";
+ break;
+ }
+ }
+}
+
+bool TOutputTraverser::visitLoop(Visit visit, TIntermLoop *node)
+{
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+
+ mOut << "Loop with condition ";
+ if (node->getType() == ELoopDoWhile)
+ mOut << "not ";
+ mOut << "tested first\n";
+
+ ++mIndentDepth;
+
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+ if (node->getCondition())
+ {
+ mOut << "Loop Condition\n";
+ node->getCondition()->traverse(this);
+ }
+ else
+ {
+ mOut << "No loop condition\n";
+ }
+
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+ if (node->getBody())
+ {
+ mOut << "Loop Body\n";
+ node->getBody()->traverse(this);
+ }
+ else
+ {
+ mOut << "No loop body\n";
+ }
+
+ if (node->getExpression())
+ {
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+ mOut << "Loop Terminal Expression\n";
+ node->getExpression()->traverse(this);
+ }
+
+ --mIndentDepth;
+
+ return false;
+}
+
+bool TOutputTraverser::visitBranch(Visit visit, TIntermBranch *node)
+{
+ OutputTreeText(mOut, node, getCurrentIndentDepth());
+
+ switch (node->getFlowOp())
+ {
+ case EOpKill:
+ mOut << "Branch: Kill";
+ break;
+ case EOpBreak:
+ mOut << "Branch: Break";
+ break;
+ case EOpContinue:
+ mOut << "Branch: Continue";
+ break;
+ case EOpReturn:
+ mOut << "Branch: Return";
+ break;
+ default:
+ mOut << "Branch: Unknown Branch";
+ break;
+ }
+
+ if (node->getExpression())
+ {
+ mOut << " with expression\n";
+ ++mIndentDepth;
+ node->getExpression()->traverse(this);
+ --mIndentDepth;
+ }
+ else
+ {
+ mOut << "\n";
+ }
+
+ return false;
+}
+
+} // anonymous namespace
+
+void OutputTree(TIntermNode *root, TInfoSinkBase &out)
+{
+ TOutputTraverser it(out);
+ ASSERT(root);
+ root->traverse(&it);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/OutputTree.h b/gfx/angle/checkout/src/compiler/translator/OutputTree.h
new file mode 100644
index 0000000000..29bca65642
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/OutputTree.h
@@ -0,0 +1,22 @@
+//
+// Copyright 2017 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.
+//
+// Output the AST intermediate representation of the GLSL code.
+
+#ifndef COMPILER_TRANSLATOR_OUTPUTTREE_H_
+#define COMPILER_TRANSLATOR_OUTPUTTREE_H_
+
+namespace sh
+{
+
+class TIntermNode;
+class TInfoSinkBase;
+
+// Output the AST along with metadata.
+void OutputTree(TIntermNode *root, TInfoSinkBase &out);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_OUTPUTTREE_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/ParseContext.cpp b/gfx/angle/checkout/src/compiler/translator/ParseContext.cpp
new file mode 100644
index 0000000000..4312c2c966
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ParseContext.cpp
@@ -0,0 +1,7538 @@
+//
+// Copyright 2002 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/ParseContext.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#include "common/mathutil.h"
+#include "common/utilities.h"
+#include "compiler/preprocessor/SourceLocation.h"
+#include "compiler/translator/Declarator.h"
+#include "compiler/translator/StaticType.h"
+#include "compiler/translator/ValidateGlobalInitializer.h"
+#include "compiler/translator/ValidateSwitch.h"
+#include "compiler/translator/glslang.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+///////////////////////////////////////////////////////////////////////
+//
+// Sub- vector and matrix fields
+//
+////////////////////////////////////////////////////////////////////////
+
+namespace
+{
+
+const int kWebGLMaxStructNesting = 4;
+
+bool ContainsSampler(const TStructure *structType);
+
+bool ContainsSampler(const TType &type)
+{
+ if (IsSampler(type.getBasicType()))
+ {
+ return true;
+ }
+ if (type.getBasicType() == EbtStruct)
+ {
+ return ContainsSampler(type.getStruct());
+ }
+
+ return false;
+}
+
+bool ContainsSampler(const TStructure *structType)
+{
+ for (const auto &field : structType->fields())
+ {
+ if (ContainsSampler(*field->type()))
+ return true;
+ }
+ return false;
+}
+
+// Get a token from an image argument to use as an error message token.
+const char *GetImageArgumentToken(TIntermTyped *imageNode)
+{
+ ASSERT(IsImage(imageNode->getBasicType()));
+ while (imageNode->getAsBinaryNode() &&
+ (imageNode->getAsBinaryNode()->getOp() == EOpIndexIndirect ||
+ imageNode->getAsBinaryNode()->getOp() == EOpIndexDirect))
+ {
+ imageNode = imageNode->getAsBinaryNode()->getLeft();
+ }
+ TIntermSymbol *imageSymbol = imageNode->getAsSymbolNode();
+ if (imageSymbol)
+ {
+ return imageSymbol->getName().data();
+ }
+ return "image";
+}
+
+bool CanSetDefaultPrecisionOnType(const TPublicType &type)
+{
+ if (!SupportsPrecision(type.getBasicType()))
+ {
+ return false;
+ }
+ if (type.getBasicType() == EbtUInt)
+ {
+ // ESSL 3.00.4 section 4.5.4
+ return false;
+ }
+ if (type.isAggregate())
+ {
+ // Not allowed to set for aggregate types
+ return false;
+ }
+ return true;
+}
+
+// Map input primitive types to input array sizes in a geometry shader.
+GLuint GetGeometryShaderInputArraySize(TLayoutPrimitiveType primitiveType)
+{
+ switch (primitiveType)
+ {
+ case EptPoints:
+ return 1u;
+ case EptLines:
+ return 2u;
+ case EptTriangles:
+ return 3u;
+ case EptLinesAdjacency:
+ return 4u;
+ case EptTrianglesAdjacency:
+ return 6u;
+ default:
+ UNREACHABLE();
+ return 0u;
+ }
+}
+
+bool IsBufferOrSharedVariable(TIntermTyped *var)
+{
+ if (var->isInterfaceBlock() || var->getQualifier() == EvqBuffer ||
+ var->getQualifier() == EvqShared)
+ {
+ return true;
+ }
+ return false;
+}
+
+TIntermTyped *FindLValueBase(TIntermTyped *node)
+{
+ do
+ {
+ const TIntermBinary *binary = node->getAsBinaryNode();
+ if (binary == nullptr)
+ {
+ return node;
+ }
+
+ TOperator op = binary->getOp();
+ if (op != EOpIndexDirect && op != EOpIndexIndirect)
+ {
+ return static_cast<TIntermTyped *>(nullptr);
+ }
+
+ node = binary->getLeft();
+ } while (true);
+}
+
+void AddAdvancedBlendEquation(gl::BlendEquationType eq, TLayoutQualifier *qualifier)
+{
+ qualifier->advancedBlendEquations.set(static_cast<uint32_t>(eq));
+}
+
+constexpr bool IsValidWithPixelLocalStorage(TLayoutImageInternalFormat internalFormat)
+{
+ switch (internalFormat)
+ {
+ case EiifRGBA8:
+ case EiifRGBA8I:
+ case EiifRGBA8UI:
+ case EiifR32F:
+ case EiifR32UI:
+ return true;
+ default:
+ return false;
+ }
+}
+} // namespace
+
+// This tracks each binding point's current default offset for inheritance of subsequent
+// variables using the same binding, and keeps offsets unique and non overlapping.
+// See GLSL ES 3.1, section 4.4.6.
+class TParseContext::AtomicCounterBindingState
+{
+ public:
+ AtomicCounterBindingState() : mDefaultOffset(0) {}
+ // Inserts a new span and returns -1 if overlapping, else returns the starting offset of
+ // newly inserted span.
+ int insertSpan(int start, size_t length)
+ {
+ gl::RangeI newSpan(start, start + static_cast<int>(length));
+ for (const auto &span : mSpans)
+ {
+ if (newSpan.intersects(span))
+ {
+ return -1;
+ }
+ }
+ mSpans.push_back(newSpan);
+ mDefaultOffset = newSpan.high();
+ return start;
+ }
+ // Inserts a new span starting from the default offset.
+ int appendSpan(size_t length) { return insertSpan(mDefaultOffset, length); }
+ void setDefaultOffset(int offset) { mDefaultOffset = offset; }
+
+ private:
+ int mDefaultOffset;
+ std::vector<gl::RangeI> mSpans;
+};
+
+TParseContext::TParseContext(TSymbolTable &symt,
+ TExtensionBehavior &ext,
+ sh::GLenum type,
+ ShShaderSpec spec,
+ const ShCompileOptions &options,
+ bool checksPrecErrors,
+ TDiagnostics *diagnostics,
+ const ShBuiltInResources &resources,
+ ShShaderOutput outputType)
+ : symbolTable(symt),
+ mDeferredNonEmptyDeclarationErrorCheck(false),
+ mShaderType(type),
+ mShaderSpec(spec),
+ mCompileOptions(options),
+ mShaderVersion(100),
+ mTreeRoot(nullptr),
+ mLoopNestingLevel(0),
+ mStructNestingLevel(0),
+ mSwitchNestingLevel(0),
+ mCurrentFunctionType(nullptr),
+ mFunctionReturnsValue(false),
+ mChecksPrecisionErrors(checksPrecErrors),
+ mFragmentPrecisionHighOnESSL1(false),
+ mEarlyFragmentTestsSpecified(false),
+ mHasDiscard(false),
+ mSampleQualifierSpecified(false),
+ mDefaultUniformMatrixPacking(EmpColumnMajor),
+ mDefaultUniformBlockStorage(sh::IsWebGLBasedSpec(spec) ? EbsStd140 : EbsShared),
+ mDefaultBufferMatrixPacking(EmpColumnMajor),
+ mDefaultBufferBlockStorage(sh::IsWebGLBasedSpec(spec) ? EbsStd140 : EbsShared),
+ mDiagnostics(diagnostics),
+ mDirectiveHandler(ext, *mDiagnostics, mShaderVersion, mShaderType),
+ mPreprocessor(mDiagnostics, &mDirectiveHandler, angle::pp::PreprocessorSettings(spec)),
+ mScanner(nullptr),
+ mMinProgramTexelOffset(resources.MinProgramTexelOffset),
+ mMaxProgramTexelOffset(resources.MaxProgramTexelOffset),
+ mMinProgramTextureGatherOffset(resources.MinProgramTextureGatherOffset),
+ mMaxProgramTextureGatherOffset(resources.MaxProgramTextureGatherOffset),
+ mComputeShaderLocalSizeDeclared(false),
+ mComputeShaderLocalSize(-1),
+ mNumViews(-1),
+ mMaxNumViews(resources.MaxViewsOVR),
+ mMaxImageUnits(resources.MaxImageUnits),
+ mMaxCombinedTextureImageUnits(resources.MaxCombinedTextureImageUnits),
+ mMaxUniformLocations(resources.MaxUniformLocations),
+ mMaxUniformBufferBindings(resources.MaxUniformBufferBindings),
+ mMaxVertexAttribs(resources.MaxVertexAttribs),
+ mMaxAtomicCounterBindings(resources.MaxAtomicCounterBindings),
+ mMaxShaderStorageBufferBindings(resources.MaxShaderStorageBufferBindings),
+ mDeclaringFunction(false),
+ mGeometryShaderInputPrimitiveType(EptUndefined),
+ mGeometryShaderOutputPrimitiveType(EptUndefined),
+ mGeometryShaderInvocations(0),
+ mGeometryShaderMaxVertices(-1),
+ mMaxGeometryShaderInvocations(resources.MaxGeometryShaderInvocations),
+ mMaxGeometryShaderMaxVertices(resources.MaxGeometryOutputVertices),
+ mGeometryInputArraySize(0),
+ mMaxPatchVertices(resources.MaxPatchVertices),
+ mTessControlShaderOutputVertices(0),
+ mTessEvaluationShaderInputPrimitiveType(EtetUndefined),
+ mTessEvaluationShaderInputVertexSpacingType(EtetUndefined),
+ mTessEvaluationShaderInputOrderingType(EtetUndefined),
+ mTessEvaluationShaderInputPointType(EtetUndefined),
+ mHasAnyPreciseType(false),
+ mAdvancedBlendEquations(0),
+ mFunctionBodyNewScope(false),
+ mOutputType(outputType)
+{}
+
+TParseContext::~TParseContext() {}
+
+bool TParseContext::anyMultiviewExtensionAvailable()
+{
+ return isExtensionEnabled(TExtension::OVR_multiview) ||
+ isExtensionEnabled(TExtension::OVR_multiview2);
+}
+
+bool TParseContext::parseVectorFields(const TSourceLoc &line,
+ const ImmutableString &compString,
+ int vecSize,
+ TVector<int> *fieldOffsets)
+{
+ ASSERT(fieldOffsets);
+ size_t fieldCount = compString.length();
+ if (fieldCount > 4u)
+ {
+ error(line, "illegal vector field selection", compString);
+ return false;
+ }
+ fieldOffsets->resize(fieldCount);
+
+ enum
+ {
+ exyzw,
+ ergba,
+ estpq
+ } fieldSet[4];
+
+ for (unsigned int i = 0u; i < fieldOffsets->size(); ++i)
+ {
+ switch (compString[i])
+ {
+ case 'x':
+ (*fieldOffsets)[i] = 0;
+ fieldSet[i] = exyzw;
+ break;
+ case 'r':
+ (*fieldOffsets)[i] = 0;
+ fieldSet[i] = ergba;
+ break;
+ case 's':
+ (*fieldOffsets)[i] = 0;
+ fieldSet[i] = estpq;
+ break;
+ case 'y':
+ (*fieldOffsets)[i] = 1;
+ fieldSet[i] = exyzw;
+ break;
+ case 'g':
+ (*fieldOffsets)[i] = 1;
+ fieldSet[i] = ergba;
+ break;
+ case 't':
+ (*fieldOffsets)[i] = 1;
+ fieldSet[i] = estpq;
+ break;
+ case 'z':
+ (*fieldOffsets)[i] = 2;
+ fieldSet[i] = exyzw;
+ break;
+ case 'b':
+ (*fieldOffsets)[i] = 2;
+ fieldSet[i] = ergba;
+ break;
+ case 'p':
+ (*fieldOffsets)[i] = 2;
+ fieldSet[i] = estpq;
+ break;
+
+ case 'w':
+ (*fieldOffsets)[i] = 3;
+ fieldSet[i] = exyzw;
+ break;
+ case 'a':
+ (*fieldOffsets)[i] = 3;
+ fieldSet[i] = ergba;
+ break;
+ case 'q':
+ (*fieldOffsets)[i] = 3;
+ fieldSet[i] = estpq;
+ break;
+ default:
+ error(line, "illegal vector field selection", compString);
+ return false;
+ }
+ }
+
+ for (unsigned int i = 0u; i < fieldOffsets->size(); ++i)
+ {
+ if ((*fieldOffsets)[i] >= vecSize)
+ {
+ error(line, "vector field selection out of range", compString);
+ return false;
+ }
+
+ if (i > 0)
+ {
+ if (fieldSet[i] != fieldSet[i - 1])
+ {
+ error(line, "illegal - vector component fields not from the same set", compString);
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+///////////////////////////////////////////////////////////////////////
+//
+// Errors
+//
+////////////////////////////////////////////////////////////////////////
+
+//
+// Used by flex/bison to output all syntax and parsing errors.
+//
+void TParseContext::error(const TSourceLoc &loc, const char *reason, const char *token)
+{
+ mDiagnostics->error(loc, reason, token);
+}
+
+void TParseContext::error(const TSourceLoc &loc, const char *reason, const ImmutableString &token)
+{
+ mDiagnostics->error(loc, reason, token.data());
+}
+
+void TParseContext::warning(const TSourceLoc &loc, const char *reason, const char *token)
+{
+ mDiagnostics->warning(loc, reason, token);
+}
+
+void TParseContext::errorIfPLSDeclared(const TSourceLoc &loc, PLSIllegalOperations op)
+{
+ if (!isExtensionEnabled(TExtension::ANGLE_shader_pixel_local_storage))
+ {
+ return;
+ }
+ if (mPLSBindings.empty())
+ {
+ // No pixel local storage uniforms have been declared yet. Remember this potential error in
+ // case PLS gets declared later.
+ mPLSPotentialErrors.emplace_back(loc, op);
+ return;
+ }
+ switch (op)
+ {
+ case PLSIllegalOperations::Discard:
+ error(loc, "illegal discard when pixel local storage is declared", "discard");
+ break;
+ case PLSIllegalOperations::ReturnFromMain:
+ error(loc, "illegal return from main when pixel local storage is declared", "return");
+ break;
+ case PLSIllegalOperations::AssignFragDepth:
+ error(loc, "value not assignable when pixel local storage is declared", "gl_FragDepth");
+ break;
+ case PLSIllegalOperations::AssignSampleMask:
+ error(loc, "value not assignable when pixel local storage is declared",
+ "gl_SampleMask");
+ break;
+ }
+}
+
+void TParseContext::outOfRangeError(bool isError,
+ const TSourceLoc &loc,
+ const char *reason,
+ const char *token)
+{
+ if (isError)
+ {
+ error(loc, reason, token);
+ }
+ else
+ {
+ warning(loc, reason, token);
+ }
+}
+
+void TParseContext::setTreeRoot(TIntermBlock *treeRoot)
+{
+ mTreeRoot = treeRoot;
+ mTreeRoot->setIsTreeRoot();
+}
+
+//
+// Same error message for all places assignments don't work.
+//
+void TParseContext::assignError(const TSourceLoc &line,
+ const char *op,
+ const TType &left,
+ const TType &right)
+{
+ TInfoSinkBase reasonStream;
+ reasonStream << "cannot convert from '" << right << "' to '" << left << "'";
+ error(line, reasonStream.c_str(), op);
+}
+
+//
+// Same error message for all places unary operations don't work.
+//
+void TParseContext::unaryOpError(const TSourceLoc &line, const char *op, const TType &operand)
+{
+ TInfoSinkBase reasonStream;
+ reasonStream << "wrong operand type - no operation '" << op
+ << "' exists that takes an operand of type " << operand
+ << " (or there is no acceptable conversion)";
+ error(line, reasonStream.c_str(), op);
+}
+
+//
+// Same error message for all binary operations don't work.
+//
+void TParseContext::binaryOpError(const TSourceLoc &line,
+ const char *op,
+ const TType &left,
+ const TType &right)
+{
+ TInfoSinkBase reasonStream;
+ reasonStream << "wrong operand types - no operation '" << op
+ << "' exists that takes a left-hand operand of type '" << left
+ << "' and a right operand of type '" << right
+ << "' (or there is no acceptable conversion)";
+ error(line, reasonStream.c_str(), op);
+}
+
+void TParseContext::checkPrecisionSpecified(const TSourceLoc &line,
+ TPrecision precision,
+ TBasicType type)
+{
+ if (!mChecksPrecisionErrors)
+ 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;
+ case EbtInt:
+ case EbtUInt:
+ UNREACHABLE(); // there's always a predeclared qualifier
+ error(line, "No precision specified (int)", "");
+ return;
+ default:
+ if (IsOpaqueType(type))
+ {
+ error(line, "No precision specified", getBasicString(type));
+ return;
+ }
+ }
+ }
+}
+
+void TParseContext::markStaticReadIfSymbol(TIntermNode *node)
+{
+ TIntermSwizzle *swizzleNode = node->getAsSwizzleNode();
+ if (swizzleNode)
+ {
+ markStaticReadIfSymbol(swizzleNode->getOperand());
+ return;
+ }
+ TIntermBinary *binaryNode = node->getAsBinaryNode();
+ if (binaryNode)
+ {
+ switch (binaryNode->getOp())
+ {
+ case EOpIndexDirect:
+ case EOpIndexIndirect:
+ case EOpIndexDirectStruct:
+ case EOpIndexDirectInterfaceBlock:
+ markStaticReadIfSymbol(binaryNode->getLeft());
+ return;
+ default:
+ return;
+ }
+ }
+ TIntermSymbol *symbolNode = node->getAsSymbolNode();
+ if (symbolNode)
+ {
+ symbolTable.markStaticRead(symbolNode->variable());
+ }
+}
+
+// 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.
+bool TParseContext::checkCanBeLValue(const TSourceLoc &line, const char *op, TIntermTyped *node)
+{
+ TIntermSwizzle *swizzleNode = node->getAsSwizzleNode();
+ if (swizzleNode)
+ {
+ 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;
+ }
+
+ TIntermBinary *binaryNode = node->getAsBinaryNode();
+ if (binaryNode)
+ {
+ switch (binaryNode->getOp())
+ {
+ case EOpIndexDirect:
+ case EOpIndexIndirect:
+ case EOpIndexDirectStruct:
+ case EOpIndexDirectInterfaceBlock:
+ if (node->getMemoryQualifier().readonly)
+ {
+ error(line, "can't modify a readonly variable", op);
+ return false;
+ }
+ return checkCanBeLValue(line, op, binaryNode->getLeft());
+ default:
+ break;
+ }
+ error(line, " l-value required", op);
+ return false;
+ }
+
+ std::string message;
+ switch (node->getQualifier())
+ {
+ case EvqConst:
+ message = "can't modify a const";
+ break;
+ case EvqParamConst:
+ message = "can't modify a const";
+ break;
+ case EvqAttribute:
+ message = "can't modify an attribute";
+ break;
+ case EvqFragmentIn:
+ case EvqVertexIn:
+ case EvqGeometryIn:
+ case EvqTessControlIn:
+ case EvqTessEvaluationIn:
+ case EvqFlatIn:
+ case EvqNoPerspectiveIn:
+ case EvqSmoothIn:
+ case EvqCentroidIn:
+ case EvqSampleIn:
+ message = "can't modify an input";
+ break;
+ case EvqUniform:
+ message = "can't modify a uniform";
+ break;
+ case EvqVaryingIn:
+ message = "can't modify a varying";
+ break;
+ case EvqFragCoord:
+ message = "can't modify gl_FragCoord";
+ break;
+ case EvqFrontFacing:
+ message = "can't modify gl_FrontFacing";
+ break;
+ case EvqHelperInvocation:
+ message = "can't modify gl_HelperInvocation";
+ break;
+ 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 EvqViewIDOVR:
+ message = "can't modify gl_ViewID_OVR";
+ break;
+ case EvqComputeIn:
+ message = "can't modify work group size variable";
+ break;
+ case EvqPerVertexIn:
+ message = "can't modify any member in gl_in";
+ break;
+ case EvqPrimitiveIDIn:
+ message = "can't modify gl_PrimitiveIDIn";
+ break;
+ case EvqInvocationID:
+ message = "can't modify gl_InvocationID";
+ break;
+ case EvqPrimitiveID:
+ if (mShaderType == GL_FRAGMENT_SHADER)
+ {
+ message = "can't modify gl_PrimitiveID in a fragment shader";
+ }
+ break;
+ case EvqLayerIn:
+ message = "can't modify gl_Layer in a fragment shader";
+ break;
+ case EvqSampleID:
+ message = "can't modify gl_SampleID";
+ break;
+ case EvqSampleMaskIn:
+ message = "can't modify gl_SampleMaskIn";
+ break;
+ case EvqSamplePosition:
+ message = "can't modify gl_SamplePosition";
+ break;
+ case EvqClipDistance:
+ if (mShaderType == GL_FRAGMENT_SHADER)
+ {
+ message = "can't modify gl_ClipDistance in a fragment shader";
+ }
+ break;
+ case EvqCullDistance:
+ if (mShaderType == GL_FRAGMENT_SHADER)
+ {
+ message = "can't modify gl_CullDistance in a fragment shader";
+ }
+ break;
+ case EvqFragDepth:
+ errorIfPLSDeclared(line, PLSIllegalOperations::AssignFragDepth);
+ break;
+ case EvqSampleMask:
+ errorIfPLSDeclared(line, PLSIllegalOperations::AssignSampleMask);
+ break;
+ default:
+ //
+ // Type that can't be written to?
+ //
+ if (node->getBasicType() == EbtVoid)
+ {
+ message = "can't modify void";
+ }
+ if (IsOpaqueType(node->getBasicType()))
+ {
+ message = "can't modify a variable with type ";
+ message += getBasicString(node->getBasicType());
+ }
+ else if (node->getMemoryQualifier().readonly)
+ {
+ message = "can't modify a readonly variable";
+ }
+ }
+
+ ASSERT(binaryNode == nullptr && swizzleNode == nullptr);
+ TIntermSymbol *symNode = node->getAsSymbolNode();
+ if (message.empty() && symNode != nullptr)
+ {
+ symbolTable.markStaticWrite(symNode->variable());
+ return true;
+ }
+
+ std::stringstream reasonStream = sh::InitializeStream<std::stringstream>();
+ reasonStream << "l-value required";
+ if (!message.empty())
+ {
+ if (symNode)
+ {
+ // Symbol inside an expression can't be nameless.
+ ASSERT(symNode->variable().symbolType() != SymbolType::Empty);
+ const ImmutableString &symbol = symNode->getName();
+ reasonStream << " (" << message << " \"" << symbol << "\")";
+ }
+ else
+ {
+ reasonStream << " (" << message << ")";
+ }
+ }
+ std::string reason = reasonStream.str();
+ error(line, reason.c_str(), op);
+
+ return false;
+}
+
+// Both test, and if necessary spit out an error, to see if the node is really
+// a constant.
+void TParseContext::checkIsConst(TIntermTyped *node)
+{
+ 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.
+void TParseContext::checkIsScalarInteger(TIntermTyped *node, const char *token)
+{
+ 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.
+bool TParseContext::checkIsAtGlobalLevel(const TSourceLoc &line, const char *token)
+{
+ if (!symbolTable.atGlobalLevel())
+ {
+ error(line, "only allowed at global scope", token);
+ return false;
+ }
+ return true;
+}
+
+// ESSL 3.00.5 sections 3.8 and 3.9.
+// If it starts "gl_" or contains two consecutive underscores, it's reserved.
+// Also checks for "webgl_" and "_webgl_" reserved identifiers if parsing a webgl shader.
+bool TParseContext::checkIsNotReserved(const TSourceLoc &line, const ImmutableString &identifier)
+{
+ static const char *reservedErrMsg = "reserved built-in name";
+ if (gl::IsBuiltInName(identifier.data()))
+ {
+ error(line, reservedErrMsg, "gl_");
+ return false;
+ }
+ if (sh::IsWebGLBasedSpec(mShaderSpec))
+ {
+ if (identifier.beginsWith("webgl_"))
+ {
+ error(line, reservedErrMsg, "webgl_");
+ return false;
+ }
+ if (identifier.beginsWith("_webgl_"))
+ {
+ error(line, reservedErrMsg, "_webgl_");
+ return false;
+ }
+ }
+ if (identifier.contains("__"))
+ {
+ if (sh::IsWebGLBasedSpec(mShaderSpec))
+ {
+ error(line,
+ "identifiers containing two consecutive underscores (__) are reserved as "
+ "possible future keywords",
+ identifier);
+ return false;
+ }
+ else
+ {
+ // Using double underscores is allowed, but may result in unintended behaviors, so a
+ // warning is issued.
+ // OpenGL ES Shader Language 3.2 specification:
+ // > 3.7. Keywords
+ // > ...
+ // > In addition, all identifiers containing two consecutive underscores (__) are
+ // > reserved for use by underlying software layers. Defining such a name in a shader
+ // > does not itself result in an error, but may result in unintended behaviors that
+ // > stem from having multiple definitions of the same name.
+ warning(line,
+ "all identifiers containing two consecutive underscores (__) are reserved - "
+ "unintented behaviors are possible",
+ identifier.data());
+ }
+ }
+ return true;
+}
+
+// Make sure the argument types are correct for constructing a specific type.
+bool TParseContext::checkConstructorArguments(const TSourceLoc &line,
+ const TIntermSequence &arguments,
+ const TType &type)
+{
+ if (arguments.empty())
+ {
+ error(line, "constructor does not have any arguments", "constructor");
+ return false;
+ }
+
+ for (TIntermNode *arg : arguments)
+ {
+ markStaticReadIfSymbol(arg);
+ const TIntermTyped *argTyped = arg->getAsTyped();
+ ASSERT(argTyped != nullptr);
+ if (type.getBasicType() != EbtStruct && IsOpaqueType(argTyped->getBasicType()))
+ {
+ std::string reason("cannot convert a variable with type ");
+ reason += getBasicString(argTyped->getBasicType());
+ error(line, reason.c_str(), "constructor");
+ return false;
+ }
+ else if (argTyped->getMemoryQualifier().writeonly)
+ {
+ error(line, "cannot convert a variable with writeonly", "constructor");
+ return false;
+ }
+ if (argTyped->getBasicType() == EbtVoid)
+ {
+ error(line, "cannot convert a void", "constructor");
+ return false;
+ }
+ }
+
+ if (type.isArray())
+ {
+ // The size of an unsized constructor should already have been determined.
+ ASSERT(!type.isUnsizedArray());
+ if (static_cast<size_t>(type.getOutermostArraySize()) != arguments.size())
+ {
+ error(line, "array constructor needs one argument per array element", "constructor");
+ return false;
+ }
+ // GLSL ES 3.00 section 5.4.4: Each argument must be the same type as the element type of
+ // the array.
+ for (TIntermNode *const &argNode : arguments)
+ {
+ const TType &argType = argNode->getAsTyped()->getType();
+ if (mShaderVersion < 310 && argType.isArray())
+ {
+ error(line, "constructing from a non-dereferenced array", "constructor");
+ return false;
+ }
+ if (!argType.isElementTypeOf(type))
+ {
+ error(line, "Array constructor argument has an incorrect type", "constructor");
+ return false;
+ }
+ }
+ }
+ else if (type.getBasicType() == EbtStruct)
+ {
+ const TFieldList &fields = type.getStruct()->fields();
+ if (fields.size() != arguments.size())
+ {
+ error(line,
+ "Number of constructor parameters does not match the number of structure fields",
+ "constructor");
+ return false;
+ }
+
+ for (size_t i = 0; i < fields.size(); i++)
+ {
+ if (i >= arguments.size() ||
+ arguments[i]->getAsTyped()->getType() != *fields[i]->type())
+ {
+ error(line, "Structure constructor arguments do not match structure fields",
+ "constructor");
+ return false;
+ }
+ }
+ }
+ else
+ {
+ // We're constructing a scalar, vector, or matrix.
+
+ // Note: It's okay to have too many components available, but not okay to have unused
+ // arguments. 'full' will go to true when enough args have been seen. If we loop again,
+ // there is an extra argument, so 'overFull' will become true.
+
+ size_t size = 0;
+ bool full = false;
+ bool overFull = false;
+ bool matrixArg = false;
+ for (TIntermNode *arg : arguments)
+ {
+ const TIntermTyped *argTyped = arg->getAsTyped();
+ ASSERT(argTyped != nullptr);
+
+ if (argTyped->getBasicType() == EbtStruct)
+ {
+ error(line, "a struct cannot be used as a constructor argument for this type",
+ "constructor");
+ return false;
+ }
+ if (argTyped->getType().isArray())
+ {
+ error(line, "constructing from a non-dereferenced array", "constructor");
+ return false;
+ }
+ if (argTyped->getType().isMatrix())
+ {
+ matrixArg = true;
+ }
+
+ size += argTyped->getType().getObjectSize();
+ if (full)
+ {
+ overFull = true;
+ }
+ if (size >= type.getObjectSize())
+ {
+ full = true;
+ }
+ }
+
+ if (type.isMatrix() && matrixArg)
+ {
+ if (arguments.size() != 1)
+ {
+ error(line, "constructing matrix from matrix can only take one argument",
+ "constructor");
+ return false;
+ }
+ }
+ else
+ {
+ if (size != 1 && size < type.getObjectSize())
+ {
+ error(line, "not enough data provided for construction", "constructor");
+ return false;
+ }
+ if (overFull)
+ {
+ error(line, "too many arguments", "constructor");
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+// This function checks to see if a void variable has been declared and raise an error message for
+// such a case
+//
+// returns true in case of an error
+//
+bool TParseContext::checkIsNonVoid(const TSourceLoc &line,
+ const ImmutableString &identifier,
+ const TBasicType &type)
+{
+ if (type == EbtVoid)
+ {
+ error(line, "illegal use of type 'void'", identifier);
+ return false;
+ }
+
+ return true;
+}
+
+// This function checks to see if the node (for the expression) contains a scalar boolean expression
+// or not.
+bool TParseContext::checkIsScalarBool(const TSourceLoc &line, const TIntermTyped *type)
+{
+ if (type->getBasicType() != EbtBool || !type->isScalar())
+ {
+ error(line, "boolean expression expected", "");
+ return false;
+ }
+ return true;
+}
+
+// This function checks to see if the node (for the expression) contains a scalar boolean expression
+// or not.
+void TParseContext::checkIsScalarBool(const TSourceLoc &line, const TPublicType &pType)
+{
+ if (pType.getBasicType() != EbtBool || pType.isAggregate())
+ {
+ error(line, "boolean expression expected", "");
+ }
+}
+
+bool TParseContext::checkIsNotOpaqueType(const TSourceLoc &line,
+ const TTypeSpecifierNonArray &pType,
+ const char *reason)
+{
+ if (pType.type == EbtStruct)
+ {
+ if (ContainsSampler(pType.userDef))
+ {
+ std::stringstream reasonStream = sh::InitializeStream<std::stringstream>();
+ reasonStream << reason << " (structure contains a sampler)";
+ std::string reasonStr = reasonStream.str();
+ error(line, reasonStr.c_str(), getBasicString(pType.type));
+ return false;
+ }
+ // only samplers need to be checked from structs, since other opaque types can't be struct
+ // members.
+ return true;
+ }
+ else if (IsOpaqueType(pType.type))
+ {
+ error(line, reason, getBasicString(pType.type));
+ return false;
+ }
+
+ return true;
+}
+
+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");
+ }
+}
+
+void TParseContext::checkLocationIsNotSpecified(const TSourceLoc &location,
+ const TLayoutQualifier &layoutQualifier)
+{
+ if (layoutQualifier.location != -1)
+ {
+ const char *errorMsg = "invalid layout qualifier: only valid on program inputs and outputs";
+ if (mShaderVersion >= 310)
+ {
+ errorMsg =
+ "invalid layout qualifier: only valid on shader inputs, outputs, and uniforms";
+ }
+ error(location, errorMsg, "location");
+ }
+}
+
+void TParseContext::checkStd430IsForShaderStorageBlock(const TSourceLoc &location,
+ const TLayoutBlockStorage &blockStorage,
+ const TQualifier &qualifier)
+{
+ if (blockStorage == EbsStd430 && qualifier != EvqBuffer)
+ {
+ error(location, "The std430 layout is supported only for shader storage blocks.", "std430");
+ }
+}
+
+void TParseContext::checkOutParameterIsNotOpaqueType(const TSourceLoc &line,
+ TQualifier qualifier,
+ const TType &type)
+{
+ ASSERT(qualifier == EvqParamOut || qualifier == EvqParamInOut);
+ if (IsOpaqueType(type.getBasicType()))
+ {
+ error(line, "opaque types cannot be output parameters", type.getBasicString());
+ }
+}
+
+// Do size checking for an array type's size.
+unsigned int TParseContext::checkIsValidArraySize(const TSourceLoc &line, TIntermTyped *expr)
+{
+ TIntermConstantUnion *constant = expr->getAsConstantUnion();
+
+ // ANGLE should be able to fold any EvqConst expressions resulting in an integer - but to be
+ // safe against corner cases we still check for constant folding. Some interpretations of the
+ // spec have allowed constant expressions with side effects - like array length() method on a
+ // non-constant array.
+ if (expr->getQualifier() != EvqConst || constant == nullptr || !constant->isScalarInt())
+ {
+ error(line, "array size must be a constant integer expression", "");
+ return 1u;
+ }
+
+ unsigned int size = 0u;
+
+ if (constant->getBasicType() == EbtUInt)
+ {
+ size = constant->getUConst(0);
+ }
+ else
+ {
+ int signedSize = constant->getIConst(0);
+
+ if (signedSize < 0)
+ {
+ error(line, "array size must be non-negative", "");
+ return 1u;
+ }
+
+ size = static_cast<unsigned int>(signedSize);
+ }
+
+ if (size == 0u)
+ {
+ error(line, "array size must be greater than zero", "");
+ return 1u;
+ }
+
+ if (IsOutputHLSL(getOutputType()))
+ {
+ // The size of arrays is restricted here to prevent issues further down the
+ // compiler/translator/driver stack. Shader Model 5 generation hardware is limited to
+ // 4096 registers so this should be reasonable even for aggressively optimizable code.
+ const unsigned int sizeLimit = 65536;
+
+ if (size > sizeLimit)
+ {
+ error(line, "array size too large", "");
+ return 1u;
+ }
+ }
+
+ return size;
+}
+
+// See if this qualifier can be an array.
+bool TParseContext::checkIsValidQualifierForArray(const TSourceLoc &line,
+ const TPublicType &elementQualifier)
+{
+ if ((elementQualifier.qualifier == EvqAttribute) ||
+ (elementQualifier.qualifier == EvqVertexIn) ||
+ (elementQualifier.qualifier == EvqConst && mShaderVersion < 300))
+ {
+ error(line, "cannot declare arrays of this qualifier",
+ TType(elementQualifier).getQualifierString());
+ return false;
+ }
+
+ return true;
+}
+
+// See if this element type can be formed into an array.
+bool TParseContext::checkArrayElementIsNotArray(const TSourceLoc &line,
+ const TPublicType &elementType)
+{
+ if (mShaderVersion < 310 && elementType.isArray())
+ {
+ TInfoSinkBase typeString;
+ typeString << TType(elementType);
+ error(line, "cannot declare arrays of arrays", typeString.c_str());
+ return false;
+ }
+ return true;
+}
+
+// Check for array-of-arrays being used as non-allowed shader inputs/outputs.
+bool TParseContext::checkArrayOfArraysInOut(const TSourceLoc &line,
+ const TPublicType &elementType,
+ const TType &arrayType)
+{
+ if (arrayType.isArrayOfArrays())
+ {
+ if (elementType.qualifier == EvqVertexOut)
+ {
+ error(line, "vertex shader output cannot be an array of arrays",
+ TType(elementType).getQualifierString());
+ return false;
+ }
+ if (elementType.qualifier == EvqFragmentIn)
+ {
+ error(line, "fragment shader input cannot be an array of arrays",
+ TType(elementType).getQualifierString());
+ return false;
+ }
+ if (elementType.qualifier == EvqFragmentOut || elementType.qualifier == EvqFragmentInOut)
+ {
+ error(line, "fragment shader output cannot be an array of arrays",
+ TType(elementType).getQualifierString());
+ return false;
+ }
+ }
+ return true;
+}
+
+// Check if this qualified element type can be formed into an array. This is only called when array
+// brackets are associated with an identifier in a declaration, like this:
+// float a[2];
+// Similar checks are done in addFullySpecifiedType for array declarations where the array brackets
+// are associated with the type, like this:
+// float[2] a;
+bool TParseContext::checkIsValidTypeAndQualifierForArray(const TSourceLoc &indexLocation,
+ const TPublicType &elementType)
+{
+ if (!checkArrayElementIsNotArray(indexLocation, elementType))
+ {
+ 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).
+ // Geometry shader requires each user-defined input be declared as arrays or inside input
+ // blocks declared as arrays (GL_EXT_geometry_shader section 11.1gs.4.3). For the purposes of
+ // interface matching, such variables and blocks are treated as though they were not declared
+ // as arrays (GL_EXT_geometry_shader section 7.4.1).
+ if (mShaderVersion >= 300 && elementType.getBasicType() == EbtStruct &&
+ sh::IsVarying(elementType.qualifier) &&
+ !IsGeometryShaderInput(mShaderType, elementType.qualifier) &&
+ !IsTessellationControlShaderInput(mShaderType, elementType.qualifier) &&
+ !IsTessellationEvaluationShaderInput(mShaderType, elementType.qualifier) &&
+ !IsTessellationControlShaderOutput(mShaderType, elementType.qualifier))
+ {
+ TInfoSinkBase typeString;
+ typeString << TType(elementType);
+ error(indexLocation, "cannot declare arrays of structs of this qualifier",
+ typeString.c_str());
+ return false;
+ }
+ return checkIsValidQualifierForArray(indexLocation, elementType);
+}
+
+// Enforce non-initializer type/qualifier rules.
+void TParseContext::checkCanBeDeclaredWithoutInitializer(const TSourceLoc &line,
+ const ImmutableString &identifier,
+ TType *type)
+{
+ ASSERT(type != nullptr);
+ if (type->getQualifier() == EvqConst)
+ {
+ // Make the qualifier make sense.
+ type->setQualifier(EvqTemporary);
+
+ // Generate informative error messages for ESSL1.
+ // In ESSL3 arrays and structures containing arrays can be constant.
+ if (mShaderVersion < 300 && type->isStructureContainingArrays())
+ {
+ error(line,
+ "structures containing arrays may not be declared constant since they cannot be "
+ "initialized",
+ identifier);
+ }
+ else
+ {
+ error(line, "variables with qualifier 'const' must be initialized", identifier);
+ }
+ }
+
+ // Implicitly declared arrays are only allowed with tessellation or geometry shader inputs
+ if (type->isArray() &&
+ ((mShaderType != GL_TESS_CONTROL_SHADER && mShaderType != GL_TESS_EVALUATION_SHADER &&
+ mShaderType != GL_GEOMETRY_SHADER) ||
+ (mShaderType == GL_GEOMETRY_SHADER && type->getQualifier() == EvqGeometryOut)))
+ {
+ const TSpan<const unsigned int> &arraySizes = type->getArraySizes();
+ for (unsigned int size : arraySizes)
+ {
+ if (size == 0)
+ {
+ error(line,
+ "implicitly sized arrays only allowed for tessellation shaders "
+ "or geometry shader inputs",
+ identifier);
+ }
+ }
+ }
+}
+
+// Do some simple checks that are shared between all variable declarations,
+// and update the symbol table.
+//
+// Returns true if declaring the variable succeeded.
+//
+bool TParseContext::declareVariable(const TSourceLoc &line,
+ const ImmutableString &identifier,
+ const TType *type,
+ TVariable **variable)
+{
+ ASSERT((*variable) == nullptr);
+
+ SymbolType symbolType = SymbolType::UserDefined;
+ switch (type->getQualifier())
+ {
+ case EvqClipDistance:
+ case EvqCullDistance:
+ case EvqLastFragData:
+ symbolType = SymbolType::BuiltIn;
+ break;
+ default:
+ break;
+ }
+
+ (*variable) = new TVariable(&symbolTable, identifier, type, symbolType);
+
+ ASSERT(type->getLayoutQualifier().index == -1 ||
+ (isExtensionEnabled(TExtension::EXT_blend_func_extended) &&
+ mShaderType == GL_FRAGMENT_SHADER && mShaderVersion >= 300));
+ if (type->getQualifier() == EvqFragmentOut)
+ {
+ if (type->getLayoutQualifier().index != -1 && type->getLayoutQualifier().location == -1)
+ {
+ error(line,
+ "If index layout qualifier is specified for a fragment output, location must "
+ "also be specified.",
+ "index");
+ return false;
+ }
+ }
+ else
+ {
+ checkIndexIsNotSpecified(line, type->getLayoutQualifier().index);
+ }
+
+ if (!((identifier.beginsWith("gl_LastFragData") || type->getQualifier() == EvqFragmentInOut) &&
+ (isExtensionEnabled(TExtension::EXT_shader_framebuffer_fetch) ||
+ isExtensionEnabled(TExtension::EXT_shader_framebuffer_fetch_non_coherent))))
+ {
+ checkNoncoherentIsNotSpecified(line, type->getLayoutQualifier().noncoherent);
+ }
+ else if (isExtensionEnabled(TExtension::EXT_shader_framebuffer_fetch_non_coherent) &&
+ !isExtensionEnabled(TExtension::EXT_shader_framebuffer_fetch))
+ {
+ checkNoncoherentIsSpecified(line, type->getLayoutQualifier().noncoherent);
+ }
+
+ checkBindingIsValid(line, *type);
+
+ bool needsReservedCheck = true;
+
+ // gl_LastFragData may be redeclared with a new precision qualifier
+ if (type->isArray() && identifier.beginsWith("gl_LastFragData"))
+ {
+ const TVariable *maxDrawBuffers = static_cast<const TVariable *>(
+ symbolTable.findBuiltIn(ImmutableString("gl_MaxDrawBuffers"), mShaderVersion));
+ if (type->isArrayOfArrays())
+ {
+ error(line, "redeclaration of gl_LastFragData as an array of arrays", identifier);
+ return false;
+ }
+ else if (static_cast<int>(type->getOutermostArraySize()) ==
+ maxDrawBuffers->getConstPointer()->getIConst())
+ {
+ if (const TSymbol *builtInSymbol = symbolTable.findBuiltIn(identifier, mShaderVersion))
+ {
+ needsReservedCheck = !checkCanUseOneOfExtensions(line, builtInSymbol->extensions());
+ }
+ }
+ else
+ {
+ error(line, "redeclaration of gl_LastFragData with size != gl_MaxDrawBuffers",
+ identifier);
+ return false;
+ }
+ }
+ else if (type->isArray() && identifier == "gl_ClipDistance")
+ {
+ // gl_ClipDistance can be redeclared with smaller size than gl_MaxClipDistances
+ const TVariable *maxClipDistances = static_cast<const TVariable *>(
+ symbolTable.findBuiltIn(ImmutableString("gl_MaxClipDistances"), mShaderVersion));
+ if (!maxClipDistances)
+ {
+ // Unsupported extension
+ needsReservedCheck = true;
+ }
+ else if (type->isArrayOfArrays())
+ {
+ error(line, "redeclaration of gl_ClipDistance as an array of arrays", identifier);
+ return false;
+ }
+ else if (static_cast<int>(type->getOutermostArraySize()) <=
+ maxClipDistances->getConstPointer()->getIConst())
+ {
+ const TSymbol *builtInSymbol = symbolTable.findBuiltIn(identifier, mShaderVersion);
+ if (builtInSymbol)
+ {
+ needsReservedCheck = !checkCanUseOneOfExtensions(line, builtInSymbol->extensions());
+ }
+ }
+ else
+ {
+ error(line, "redeclaration of gl_ClipDistance with size > gl_MaxClipDistances",
+ identifier);
+ return false;
+ }
+ }
+ else if (type->isArray() && identifier == "gl_CullDistance")
+ {
+ // gl_CullDistance can be redeclared with smaller size than gl_MaxCullDistances
+ const TVariable *maxCullDistances = static_cast<const TVariable *>(
+ symbolTable.findBuiltIn(ImmutableString("gl_MaxCullDistances"), mShaderVersion));
+ if (!maxCullDistances)
+ {
+ // Unsupported extension
+ needsReservedCheck = true;
+ }
+ else if (type->isArrayOfArrays())
+ {
+ error(line, "redeclaration of gl_CullDistance as an array of arrays", identifier);
+ return false;
+ }
+ else if (static_cast<int>(type->getOutermostArraySize()) <=
+ maxCullDistances->getConstPointer()->getIConst())
+ {
+ if (const TSymbol *builtInSymbol = symbolTable.findBuiltIn(identifier, mShaderVersion))
+ {
+ needsReservedCheck = !checkCanUseOneOfExtensions(line, builtInSymbol->extensions());
+ }
+ }
+ else
+ {
+ error(line, "redeclaration of gl_CullDistance with size > gl_MaxCullDistances",
+ identifier);
+ return false;
+ }
+ }
+
+ if (needsReservedCheck && !checkIsNotReserved(line, identifier))
+ return false;
+
+ if (!symbolTable.declare(*variable))
+ {
+ error(line, "redefinition", identifier);
+ return false;
+ }
+
+ if (!checkIsNonVoid(line, identifier, type->getBasicType()))
+ return false;
+
+ return true;
+}
+
+void TParseContext::checkIsParameterQualifierValid(
+ const TSourceLoc &line,
+ const TTypeQualifierBuilder &typeQualifierBuilder,
+ TType *type)
+{
+ // The only parameter qualifiers a parameter can have are in, out, inout or const.
+ TTypeQualifier typeQualifier =
+ typeQualifierBuilder.getParameterTypeQualifier(type->getBasicType(), mDiagnostics);
+
+ if (typeQualifier.qualifier == EvqParamOut || typeQualifier.qualifier == EvqParamInOut)
+ {
+ checkOutParameterIsNotOpaqueType(line, typeQualifier.qualifier, *type);
+ }
+
+ if (!IsImage(type->getBasicType()))
+ {
+ checkMemoryQualifierIsNotSpecified(typeQualifier.memoryQualifier, line);
+ }
+ else
+ {
+ type->setMemoryQualifier(typeQualifier.memoryQualifier);
+ }
+
+ type->setQualifier(typeQualifier.qualifier);
+
+ if (typeQualifier.precision != EbpUndefined)
+ {
+ type->setPrecision(typeQualifier.precision);
+ }
+
+ if (typeQualifier.precise)
+ {
+ type->setPrecise(true);
+ }
+}
+
+template <size_t size>
+bool TParseContext::checkCanUseOneOfExtensions(const TSourceLoc &line,
+ const std::array<TExtension, size> &extensions)
+{
+ ASSERT(!extensions.empty());
+ const TExtensionBehavior &extBehavior = extensionBehavior();
+
+ bool canUseWithWarning = false;
+ bool canUseWithoutWarning = false;
+
+ const char *errorMsgString = "";
+ TExtension errorMsgExtension = TExtension::UNDEFINED;
+
+ for (TExtension extension : extensions)
+ {
+ auto extIter = extBehavior.find(extension);
+ if (canUseWithWarning)
+ {
+ // We already have an extension that we can use, but with a warning.
+ // See if we can use the alternative extension without a warning.
+ if (extIter == extBehavior.end())
+ {
+ continue;
+ }
+ if (extIter->second == EBhEnable || extIter->second == EBhRequire)
+ {
+ canUseWithoutWarning = true;
+ break;
+ }
+ continue;
+ }
+ if (extension == TExtension::UNDEFINED)
+ {
+ continue;
+ }
+ else if (extIter == extBehavior.end())
+ {
+ errorMsgString = "extension is not supported";
+ errorMsgExtension = extension;
+ }
+ else if (extIter->second == EBhUndefined || extIter->second == EBhDisable)
+ {
+ errorMsgString = "extension is disabled";
+ errorMsgExtension = extension;
+ }
+ else if (extIter->second == EBhWarn)
+ {
+ errorMsgExtension = extension;
+ canUseWithWarning = true;
+ }
+ else
+ {
+ ASSERT(extIter->second == EBhEnable || extIter->second == EBhRequire);
+ canUseWithoutWarning = true;
+ break;
+ }
+ }
+
+ if (canUseWithoutWarning)
+ {
+ return true;
+ }
+ if (canUseWithWarning)
+ {
+ warning(line, "extension is being used", GetExtensionNameString(errorMsgExtension));
+ return true;
+ }
+ error(line, errorMsgString, GetExtensionNameString(errorMsgExtension));
+ return false;
+}
+
+template bool TParseContext::checkCanUseOneOfExtensions(
+ const TSourceLoc &line,
+ const std::array<TExtension, 1> &extensions);
+template bool TParseContext::checkCanUseOneOfExtensions(
+ const TSourceLoc &line,
+ const std::array<TExtension, 2> &extensions);
+template bool TParseContext::checkCanUseOneOfExtensions(
+ const TSourceLoc &line,
+ const std::array<TExtension, 3> &extensions);
+
+bool TParseContext::checkCanUseExtension(const TSourceLoc &line, TExtension extension)
+{
+ ASSERT(extension != TExtension::UNDEFINED);
+ return checkCanUseOneOfExtensions(line, std::array<TExtension, 1u>{{extension}});
+}
+
+// ESSL 3.00.6 section 4.8 Empty Declarations: "The combinations of qualifiers that cause
+// compile-time or link-time errors are the same whether or not the declaration is empty".
+// This function implements all the checks that are done on qualifiers regardless of if the
+// declaration is empty.
+void TParseContext::declarationQualifierErrorCheck(const sh::TQualifier qualifier,
+ const sh::TLayoutQualifier &layoutQualifier,
+ const TSourceLoc &location)
+{
+ if (qualifier == EvqShared && !layoutQualifier.isEmpty())
+ {
+ error(location, "Shared memory declarations cannot have layout specified", "layout");
+ }
+
+ if (layoutQualifier.matrixPacking != EmpUnspecified)
+ {
+ error(location, "layout qualifier only valid for interface blocks",
+ getMatrixPackingString(layoutQualifier.matrixPacking));
+ return;
+ }
+
+ if (layoutQualifier.blockStorage != EbsUnspecified)
+ {
+ error(location, "layout qualifier only valid for interface blocks",
+ getBlockStorageString(layoutQualifier.blockStorage));
+ return;
+ }
+
+ if (qualifier == EvqFragmentOut)
+ {
+ if (layoutQualifier.location != -1 && layoutQualifier.yuv == true)
+ {
+ error(location, "invalid layout qualifier combination", "yuv");
+ return;
+ }
+ }
+ else
+ {
+ checkYuvIsNotSpecified(location, layoutQualifier.yuv);
+ }
+
+ if (qualifier != EvqFragmentIn)
+ {
+ checkEarlyFragmentTestsIsNotSpecified(location, layoutQualifier.earlyFragmentTests);
+ }
+
+ // If multiview extension is enabled, "in" qualifier is allowed in the vertex shader in previous
+ // parsing steps. So it needs to be checked here.
+ if (anyMultiviewExtensionAvailable() && mShaderVersion < 300 && qualifier == EvqVertexIn)
+ {
+ error(location, "storage qualifier supported in GLSL ES 3.00 and above only", "in");
+ }
+
+ bool canHaveLocation = qualifier == EvqVertexIn || qualifier == EvqFragmentOut;
+ if (mShaderVersion >= 300 &&
+ (isExtensionEnabled(TExtension::EXT_shader_framebuffer_fetch) ||
+ isExtensionEnabled(TExtension::EXT_shader_framebuffer_fetch_non_coherent)))
+ {
+ // In the case of EXT_shader_framebuffer_fetch or EXT_shader_framebuffer_fetch_non_coherent
+ // extension, the location of inout qualifier is used to set the input attachment index
+ canHaveLocation = canHaveLocation || qualifier == EvqFragmentInOut;
+ }
+ if (mShaderVersion >= 310)
+ {
+ canHaveLocation = canHaveLocation || qualifier == EvqUniform || IsVarying(qualifier);
+ // We're not checking whether the uniform location is in range here since that depends on
+ // the type of the variable.
+ // The type can only be fully determined for non-empty declarations.
+ }
+ if (!canHaveLocation)
+ {
+ checkLocationIsNotSpecified(location, layoutQualifier);
+ }
+}
+
+void TParseContext::atomicCounterQualifierErrorCheck(const TPublicType &publicType,
+ const TSourceLoc &location)
+{
+ if (publicType.precision != EbpHigh)
+ {
+ error(location, "Can only be highp", "atomic counter");
+ }
+ // dEQP enforces compile error if location is specified. See uniform_location.test.
+ if (publicType.layoutQualifier.location != -1)
+ {
+ error(location, "location must not be set for atomic_uint", "layout");
+ }
+ if (publicType.layoutQualifier.binding == -1)
+ {
+ error(location, "no binding specified", "atomic counter");
+ }
+}
+
+void TParseContext::emptyDeclarationErrorCheck(const TType &type, const TSourceLoc &location)
+{
+ if (type.isUnsizedArray())
+ {
+ // ESSL3 spec section 4.1.9: Array declaration which leaves the size unspecified is an
+ // error. It is assumed that this applies to empty declarations as well.
+ error(location, "empty array declaration needs to specify a size", "");
+ }
+
+ if (type.getQualifier() != EvqFragmentOut)
+ {
+ checkIndexIsNotSpecified(location, type.getLayoutQualifier().index);
+ }
+}
+
+// These checks are done for all declarations that are non-empty. They're done for non-empty
+// declarations starting a declarator list, and declarators that follow an empty declaration.
+void TParseContext::nonEmptyDeclarationErrorCheck(const TPublicType &publicType,
+ const TSourceLoc &identifierLocation)
+{
+ switch (publicType.qualifier)
+ {
+ case EvqVaryingIn:
+ case EvqVaryingOut:
+ case EvqAttribute:
+ case EvqVertexIn:
+ case EvqFragmentOut:
+ case EvqFragmentInOut:
+ case EvqComputeIn:
+ if (publicType.getBasicType() == EbtStruct)
+ {
+ error(identifierLocation, "cannot be used with a structure",
+ getQualifierString(publicType.qualifier));
+ return;
+ }
+ break;
+ case EvqBuffer:
+ if (publicType.getBasicType() != EbtInterfaceBlock)
+ {
+ error(identifierLocation,
+ "cannot declare buffer variables at global scope(outside a block)",
+ getQualifierString(publicType.qualifier));
+ return;
+ }
+ break;
+ default:
+ break;
+ }
+ std::string reason(getBasicString(publicType.getBasicType()));
+ reason += "s must be uniform";
+ if (publicType.qualifier != EvqUniform &&
+ !checkIsNotOpaqueType(identifierLocation, publicType.typeSpecifierNonArray, reason.c_str()))
+ {
+ return;
+ }
+
+ if ((publicType.qualifier != EvqTemporary && publicType.qualifier != EvqGlobal &&
+ publicType.qualifier != EvqConst) &&
+ publicType.getBasicType() == EbtYuvCscStandardEXT)
+ {
+ error(identifierLocation, "cannot be used with a yuvCscStandardEXT",
+ getQualifierString(publicType.qualifier));
+ return;
+ }
+
+ if (mShaderVersion >= 310 && publicType.qualifier == EvqUniform)
+ {
+ // Valid uniform declarations can't be unsized arrays since uniforms can't be initialized.
+ // But invalid shaders may still reach here with an unsized array declaration.
+ TType type(publicType);
+ if (!type.isUnsizedArray())
+ {
+ checkUniformLocationInRange(identifierLocation, type.getLocationCount(),
+ publicType.layoutQualifier);
+ }
+ }
+
+ if (mShaderVersion >= 300 && publicType.qualifier == EvqVertexIn)
+ {
+ // Valid vertex input declarations can't be unsized arrays since they can't be initialized.
+ // But invalid shaders may still reach here with an unsized array declaration.
+ TType type(publicType);
+ if (!type.isUnsizedArray())
+ {
+ checkAttributeLocationInRange(identifierLocation, type.getLocationCount(),
+ publicType.layoutQualifier);
+ }
+ }
+
+ // check for layout qualifier issues
+ const TLayoutQualifier layoutQualifier = publicType.layoutQualifier;
+
+ if (IsImage(publicType.getBasicType()))
+ {
+
+ switch (layoutQualifier.imageInternalFormat)
+ {
+ case EiifRGBA32F:
+ case EiifRGBA16F:
+ case EiifR32F:
+ case EiifRGBA8:
+ case EiifRGBA8_SNORM:
+ if (!IsFloatImage(publicType.getBasicType()))
+ {
+ error(identifierLocation,
+ "internal image format requires a floating image type",
+ getBasicString(publicType.getBasicType()));
+ return;
+ }
+ break;
+ case EiifRGBA32I:
+ case EiifRGBA16I:
+ case EiifRGBA8I:
+ case EiifR32I:
+ if (!IsIntegerImage(publicType.getBasicType()))
+ {
+ error(identifierLocation,
+ "internal image format requires an integer image type",
+ getBasicString(publicType.getBasicType()));
+ return;
+ }
+ break;
+ case EiifRGBA32UI:
+ case EiifRGBA16UI:
+ case EiifRGBA8UI:
+ case EiifR32UI:
+ if (!IsUnsignedImage(publicType.getBasicType()))
+ {
+ error(identifierLocation,
+ "internal image format requires an unsigned image type",
+ getBasicString(publicType.getBasicType()));
+ return;
+ }
+ break;
+ case EiifUnspecified:
+ error(identifierLocation, "layout qualifier", "No image internal format specified");
+ return;
+ default:
+ error(identifierLocation, "layout qualifier", "unrecognized token");
+ return;
+ }
+
+ // GLSL ES 3.10 Revision 4, 4.9 Memory Access Qualifiers
+ switch (layoutQualifier.imageInternalFormat)
+ {
+ case EiifR32F:
+ case EiifR32I:
+ case EiifR32UI:
+ break;
+ default:
+ if (!publicType.memoryQualifier.readonly && !publicType.memoryQualifier.writeonly)
+ {
+ error(identifierLocation, "layout qualifier",
+ "Except for images with the r32f, r32i and r32ui format qualifiers, "
+ "image variables must be qualified readonly and/or writeonly");
+ return;
+ }
+ break;
+ }
+ }
+ else if (IsPixelLocal(publicType.getBasicType()))
+ {
+ if (getShaderType() != GL_FRAGMENT_SHADER)
+ {
+ error(identifierLocation,
+ "undefined use of pixel local storage outside a fragment shader",
+ getBasicString(publicType.getBasicType()));
+ return;
+ }
+ switch (layoutQualifier.imageInternalFormat)
+ {
+ case EiifR32F:
+ case EiifRGBA8:
+ if (publicType.getBasicType() != EbtPixelLocalANGLE)
+ {
+ error(identifierLocation, "pixel local storage format requires pixelLocalANGLE",
+ getImageInternalFormatString(layoutQualifier.imageInternalFormat));
+ }
+ break;
+ case EiifRGBA8I:
+ if (publicType.getBasicType() != EbtIPixelLocalANGLE)
+ {
+ error(identifierLocation,
+ "pixel local storage format requires ipixelLocalANGLE",
+ getImageInternalFormatString(layoutQualifier.imageInternalFormat));
+ }
+ break;
+ case EiifR32UI:
+ case EiifRGBA8UI:
+ if (publicType.getBasicType() != EbtUPixelLocalANGLE)
+ {
+ error(identifierLocation,
+ "pixel local storage format requires upixelLocalANGLE",
+ getImageInternalFormatString(layoutQualifier.imageInternalFormat));
+ }
+ break;
+ case EiifR32I:
+ case EiifRGBA8_SNORM:
+ case EiifRGBA16F:
+ case EiifRGBA32F:
+ case EiifRGBA16I:
+ case EiifRGBA32I:
+ case EiifRGBA16UI:
+ case EiifRGBA32UI:
+ default:
+ ASSERT(!IsValidWithPixelLocalStorage(layoutQualifier.imageInternalFormat));
+ error(identifierLocation, "illegal pixel local storage format",
+ getImageInternalFormatString(layoutQualifier.imageInternalFormat));
+ break;
+ case EiifUnspecified:
+ error(identifierLocation, "pixel local storage requires a format specifier",
+ "layout qualifier");
+ break;
+ }
+ checkMemoryQualifierIsNotSpecified(publicType.memoryQualifier, identifierLocation);
+ checkDeclaratorLocationIsNotSpecified(identifierLocation, publicType);
+ }
+ else
+ {
+ checkInternalFormatIsNotSpecified(identifierLocation, layoutQualifier.imageInternalFormat);
+ checkMemoryQualifierIsNotSpecified(publicType.memoryQualifier, identifierLocation);
+ }
+
+ if (IsAtomicCounter(publicType.getBasicType()))
+ {
+ atomicCounterQualifierErrorCheck(publicType, identifierLocation);
+ }
+ else
+ {
+ checkOffsetIsNotSpecified(identifierLocation, layoutQualifier.offset);
+ }
+}
+
+void TParseContext::checkBindingIsValid(const TSourceLoc &identifierLocation, const TType &type)
+{
+ TLayoutQualifier layoutQualifier = type.getLayoutQualifier();
+ // Note that the ESSL 3.10 section 4.4.5 is not particularly clear on how the binding qualifier
+ // on arrays of arrays should be handled. We interpret the spec so that the binding value is
+ // incremented for each element of the innermost nested arrays. This is in line with how arrays
+ // of arrays of blocks are specified to behave in GLSL 4.50 and a conservative interpretation
+ // when it comes to which shaders are accepted by the compiler.
+ int arrayTotalElementCount = type.getArraySizeProduct();
+ if (IsPixelLocal(type.getBasicType()))
+ {
+ checkPixelLocalStorageBindingIsValid(identifierLocation, type);
+ }
+ else if (mShaderVersion < 310)
+ {
+ checkBindingIsNotSpecified(identifierLocation, layoutQualifier.binding);
+ }
+ else if (IsImage(type.getBasicType()))
+ {
+ checkImageBindingIsValid(identifierLocation, layoutQualifier.binding,
+ arrayTotalElementCount);
+ }
+ else if (IsSampler(type.getBasicType()))
+ {
+ checkSamplerBindingIsValid(identifierLocation, layoutQualifier.binding,
+ arrayTotalElementCount);
+ }
+ else if (IsAtomicCounter(type.getBasicType()))
+ {
+ checkAtomicCounterBindingIsValid(identifierLocation, layoutQualifier.binding);
+ }
+ else
+ {
+ ASSERT(!IsOpaqueType(type.getBasicType()));
+ checkBindingIsNotSpecified(identifierLocation, layoutQualifier.binding);
+ }
+}
+
+void TParseContext::checkCanUseLayoutQualifier(const TSourceLoc &location)
+{
+ constexpr std::array<TExtension, 4u> extensions{
+ {TExtension::EXT_shader_framebuffer_fetch,
+ TExtension::EXT_shader_framebuffer_fetch_non_coherent,
+ TExtension::KHR_blend_equation_advanced, TExtension::ANGLE_shader_pixel_local_storage}};
+ if (getShaderVersion() < 300 && !checkCanUseOneOfExtensions(location, extensions))
+ {
+ error(location, "qualifier supported in GLSL ES 3.00 and above only", "layout");
+ }
+}
+
+bool TParseContext::checkLayoutQualifierSupported(const TSourceLoc &location,
+ const ImmutableString &layoutQualifierName,
+ int versionRequired)
+{
+
+ if (mShaderVersion < versionRequired)
+ {
+ error(location, "invalid layout qualifier: not supported", layoutQualifierName);
+ return false;
+ }
+ return true;
+}
+
+bool TParseContext::checkWorkGroupSizeIsNotSpecified(const TSourceLoc &location,
+ const TLayoutQualifier &layoutQualifier)
+{
+ const sh::WorkGroupSize &localSize = layoutQualifier.localSize;
+ for (size_t i = 0u; i < localSize.size(); ++i)
+ {
+ if (localSize[i] != -1)
+ {
+ error(location,
+ "invalid layout qualifier: only valid when used with 'in' in a compute shader "
+ "global layout declaration",
+ getWorkGroupSizeString(i));
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void TParseContext::checkInternalFormatIsNotSpecified(const TSourceLoc &location,
+ TLayoutImageInternalFormat internalFormat)
+{
+ if (internalFormat != EiifUnspecified)
+ {
+ if (mShaderVersion < 310)
+ {
+ if (IsValidWithPixelLocalStorage(internalFormat))
+ {
+ error(location,
+ "invalid layout qualifier: not supported before GLSL ES 3.10, except pixel "
+ "local storage",
+ getImageInternalFormatString(internalFormat));
+ }
+ else
+ {
+ error(location, "invalid layout qualifier: not supported before GLSL ES 3.10",
+ getImageInternalFormatString(internalFormat));
+ }
+ }
+ else
+ {
+ if (IsValidWithPixelLocalStorage(internalFormat))
+ {
+ error(location,
+ "invalid layout qualifier: only valid when used with images or pixel local "
+ "storage ",
+ getImageInternalFormatString(internalFormat));
+ }
+ else
+ {
+ error(location, "invalid layout qualifier: only valid when used with images",
+ getImageInternalFormatString(internalFormat));
+ }
+ }
+ }
+}
+
+void TParseContext::checkIndexIsNotSpecified(const TSourceLoc &location, int index)
+{
+ if (index != -1)
+ {
+ error(location,
+ "invalid layout qualifier: only valid when used with a fragment shader output in "
+ "ESSL version >= 3.00 and EXT_blend_func_extended is enabled",
+ "index");
+ }
+}
+
+void TParseContext::checkBindingIsNotSpecified(const TSourceLoc &location, int binding)
+{
+ if (binding != -1)
+ {
+ if (mShaderVersion < 310)
+ {
+ error(location,
+ "invalid layout qualifier: only valid when used with pixel local storage",
+ "binding");
+ }
+ else
+ {
+ error(location,
+ "invalid layout qualifier: only valid when used with opaque types or blocks",
+ "binding");
+ }
+ }
+}
+
+void TParseContext::checkOffsetIsNotSpecified(const TSourceLoc &location, int offset)
+{
+ if (offset != -1)
+ {
+ error(location, "invalid layout qualifier: only valid when used with atomic counters",
+ "offset");
+ }
+}
+
+void TParseContext::checkImageBindingIsValid(const TSourceLoc &location,
+ int binding,
+ int arrayTotalElementCount)
+{
+ // Expects arraySize to be 1 when setting binding for only a single variable.
+ if (binding >= 0 && binding + arrayTotalElementCount > mMaxImageUnits)
+ {
+ error(location, "image binding greater than gl_MaxImageUnits", "binding");
+ }
+}
+
+void TParseContext::checkSamplerBindingIsValid(const TSourceLoc &location,
+ int binding,
+ int arrayTotalElementCount)
+{
+ // Expects arraySize to be 1 when setting binding for only a single variable.
+ if (binding >= 0 && binding + arrayTotalElementCount > mMaxCombinedTextureImageUnits)
+ {
+ error(location, "sampler binding greater than maximum texture units", "binding");
+ }
+}
+
+void TParseContext::checkBlockBindingIsValid(const TSourceLoc &location,
+ const TQualifier &qualifier,
+ int binding,
+ int arraySize)
+{
+ int size = (arraySize == 0 ? 1 : arraySize);
+ if (qualifier == EvqUniform)
+ {
+ if (binding + size > mMaxUniformBufferBindings)
+ {
+ error(location, "uniform block binding greater than MAX_UNIFORM_BUFFER_BINDINGS",
+ "binding");
+ }
+ }
+ else if (qualifier == EvqBuffer)
+ {
+ if (binding + size > mMaxShaderStorageBufferBindings)
+ {
+ error(location,
+ "shader storage block binding greater than MAX_SHADER_STORAGE_BUFFER_BINDINGS",
+ "binding");
+ }
+ }
+}
+void TParseContext::checkAtomicCounterBindingIsValid(const TSourceLoc &location, int binding)
+{
+ if (binding >= mMaxAtomicCounterBindings)
+ {
+ error(location, "atomic counter binding greater than gl_MaxAtomicCounterBindings",
+ "binding");
+ }
+}
+
+void TParseContext::checkPixelLocalStorageBindingIsValid(const TSourceLoc &location,
+ const TType &type)
+{
+ TLayoutQualifier layoutQualifier = type.getLayoutQualifier();
+ if (type.isArray())
+ {
+ // PLS is not allowed in arrays.
+ // TODO(anglebug.com/7279): Consider allowing this once more backends are implemented.
+ error(location, "pixel local storage handles cannot be aggregated in arrays", "array");
+ }
+ else if (layoutQualifier.binding < 0)
+ {
+ error(location, "pixel local storage requires a binding index", "layout qualifier");
+ }
+ // TODO(anglebug.com/7279):
+ // else if (binding >= GL_MAX_LOCAL_STORAGE_PLANES_ANGLE)
+ // {
+ // }
+ else if (mPLSBindings.find(layoutQualifier.binding) != mPLSBindings.end())
+ {
+ error(location, "duplicate pixel local storage binding index",
+ std::to_string(layoutQualifier.binding).c_str());
+ }
+ else
+ {
+ mPLSBindings[layoutQualifier.binding] = layoutQualifier.imageInternalFormat;
+ // "mPLSBindings" is how we know whether pixel local storage uniforms have been declared, so
+ // flush the queue of potential errors once mPLSBindings isn't empty.
+ if (!mPLSPotentialErrors.empty())
+ {
+ for (const auto &[loc, op] : mPLSPotentialErrors)
+ {
+ errorIfPLSDeclared(loc, op);
+ }
+ mPLSPotentialErrors.clear();
+ }
+ }
+}
+
+void TParseContext::checkUniformLocationInRange(const TSourceLoc &location,
+ int objectLocationCount,
+ const TLayoutQualifier &layoutQualifier)
+{
+ int loc = layoutQualifier.location;
+ if (loc >= 0) // Shader-specified location
+ {
+ if (loc >= mMaxUniformLocations || objectLocationCount > mMaxUniformLocations ||
+ static_cast<unsigned int>(loc) + static_cast<unsigned int>(objectLocationCount) >
+ static_cast<unsigned int>(mMaxUniformLocations))
+ {
+ error(location, "Uniform location out of range", "location");
+ }
+ }
+}
+
+void TParseContext::checkAttributeLocationInRange(const TSourceLoc &location,
+ int objectLocationCount,
+ const TLayoutQualifier &layoutQualifier)
+{
+ int loc = layoutQualifier.location;
+ if (loc >= 0) // Shader-specified location
+ {
+ if (loc >= mMaxVertexAttribs || objectLocationCount > mMaxVertexAttribs ||
+ static_cast<unsigned int>(loc) + static_cast<unsigned int>(objectLocationCount) >
+ static_cast<unsigned int>(mMaxVertexAttribs))
+ {
+ error(location, "Attribute location out of range", "location");
+ }
+ }
+}
+
+void TParseContext::checkYuvIsNotSpecified(const TSourceLoc &location, bool yuv)
+{
+ if (yuv != false)
+ {
+ error(location, "invalid layout qualifier: only valid on program outputs", "yuv");
+ }
+}
+
+void TParseContext::checkEarlyFragmentTestsIsNotSpecified(const TSourceLoc &location,
+ bool earlyFragmentTests)
+{
+ if (earlyFragmentTests != false)
+ {
+ error(location,
+ "invalid layout qualifier: only valid when used with 'in' in a fragment shader",
+ "early_fragment_tests");
+ }
+}
+
+void TParseContext::checkNoncoherentIsSpecified(const TSourceLoc &location, bool noncoherent)
+{
+ if (noncoherent == false)
+ {
+ error(location,
+ "'noncoherent' qualifier must be used when "
+ "GL_EXT_shader_framebuffer_fetch_non_coherent extension is used",
+ "noncoherent");
+ }
+}
+
+void TParseContext::checkNoncoherentIsNotSpecified(const TSourceLoc &location, bool noncoherent)
+{
+ if (noncoherent != false)
+ {
+ error(location,
+ "invalid layout qualifier: only valid when used with 'gl_LastFragData' or the "
+ "variable decorated with 'inout' in a fragment shader",
+ "noncoherent");
+ }
+}
+
+void TParseContext::checkTCSOutVarIndexIsValid(TIntermBinary *binaryExpression,
+ const TSourceLoc &location)
+{
+ ASSERT(binaryExpression->getOp() == EOpIndexIndirect ||
+ binaryExpression->getOp() == EOpIndexDirect);
+ const TIntermSymbol *intermSymbol = binaryExpression->getRight()->getAsSymbolNode();
+ if ((intermSymbol == nullptr) || (intermSymbol->getName() != "gl_InvocationID"))
+ {
+ error(location,
+ "tessellation-control per-vertex output l-value must be indexed with "
+ "gl_InvocationID",
+ "[");
+ }
+}
+
+void TParseContext::functionCallRValueLValueErrorCheck(const TFunction *fnCandidate,
+ TIntermAggregate *fnCall)
+{
+ for (size_t i = 0; i < fnCandidate->getParamCount(); ++i)
+ {
+ TQualifier qual = fnCandidate->getParam(i)->getType().getQualifier();
+ TIntermTyped *argument = (*(fnCall->getSequence()))[i]->getAsTyped();
+ bool argumentIsRead = (IsQualifierUnspecified(qual) || qual == EvqParamIn ||
+ qual == EvqParamInOut || qual == EvqParamConst);
+ if (argumentIsRead)
+ {
+ markStaticReadIfSymbol(argument);
+ if (!IsImage(argument->getBasicType()))
+ {
+ if (argument->getMemoryQualifier().writeonly)
+ {
+ error(argument->getLine(),
+ "Writeonly value cannot be passed for 'in' or 'inout' parameters.",
+ fnCall->functionName());
+ return;
+ }
+ }
+ }
+ if (qual == EvqParamOut || qual == EvqParamInOut)
+ {
+ if (!checkCanBeLValue(argument->getLine(), "assign", argument))
+ {
+ error(argument->getLine(),
+ "Constant value cannot be passed for 'out' or 'inout' parameters.",
+ fnCall->functionName());
+ return;
+ }
+ }
+ }
+}
+
+void TParseContext::checkInvariantVariableQualifier(bool invariant,
+ const TQualifier qualifier,
+ const TSourceLoc &invariantLocation)
+{
+ 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
+ {
+ if (!sh::CanBeInvariantESSL3OrGreater(qualifier))
+ {
+ error(invariantLocation, "Cannot be qualified as invariant.", "invariant");
+ }
+ }
+}
+
+void TParseContext::checkAdvancedBlendEquationsNotSpecified(
+ const TSourceLoc &location,
+ const AdvancedBlendEquations &advancedBlendEquations,
+ const TQualifier &qualifier)
+{
+ if (advancedBlendEquations.any() && qualifier != EvqFragmentOut)
+ {
+ error(location,
+ "invalid layout qualifier: blending equation qualifiers are only permitted on the "
+ "fragment 'out' qualifier ",
+ "blend_support_qualifier");
+ }
+}
+
+bool TParseContext::isExtensionEnabled(TExtension extension) const
+{
+ return IsExtensionEnabled(extensionBehavior(), extension);
+}
+
+void TParseContext::handleExtensionDirective(const TSourceLoc &loc,
+ const char *extName,
+ const char *behavior)
+{
+ angle::pp::SourceLocation srcLoc;
+ srcLoc.file = loc.first_file;
+ srcLoc.line = loc.first_line;
+ mDirectiveHandler.handleExtension(srcLoc, extName, behavior);
+}
+
+void TParseContext::handlePragmaDirective(const TSourceLoc &loc,
+ const char *name,
+ const char *value,
+ bool stdgl)
+{
+ angle::pp::SourceLocation srcLoc;
+ srcLoc.file = loc.first_file;
+ srcLoc.line = loc.first_line;
+ mDirectiveHandler.handlePragma(srcLoc, name, value, stdgl);
+}
+
+sh::WorkGroupSize TParseContext::getComputeShaderLocalSize() const
+{
+ sh::WorkGroupSize result(-1);
+ for (size_t i = 0u; i < result.size(); ++i)
+ {
+ if (mComputeShaderLocalSizeDeclared && mComputeShaderLocalSize[i] == -1)
+ {
+ result[i] = 1;
+ }
+ else
+ {
+ result[i] = mComputeShaderLocalSize[i];
+ }
+ }
+ return result;
+}
+
+TIntermConstantUnion *TParseContext::addScalarLiteral(const TConstantUnion *constantUnion,
+ const TSourceLoc &line)
+{
+ TIntermConstantUnion *node = new TIntermConstantUnion(
+ constantUnion, TType(constantUnion->getType(), EbpUndefined, EvqConst));
+ node->setLine(line);
+ return node;
+}
+
+/////////////////////////////////////////////////////////////////////////////////
+//
+// Non-Errors.
+//
+/////////////////////////////////////////////////////////////////////////////////
+
+const TVariable *TParseContext::getNamedVariable(const TSourceLoc &location,
+ const ImmutableString &name,
+ const TSymbol *symbol)
+{
+ if (!symbol)
+ {
+ error(location, "undeclared identifier", name);
+ return nullptr;
+ }
+
+ if (!symbol->isVariable())
+ {
+ error(location, "variable expected", name);
+ return nullptr;
+ }
+
+ const TVariable *variable = static_cast<const TVariable *>(symbol);
+
+ if (!variable->extensions().empty() && variable->extensions()[0] != TExtension::UNDEFINED)
+ {
+ checkCanUseOneOfExtensions(location, variable->extensions());
+ }
+
+ // GLSL ES 3.1 Revision 4, 7.1.3 Compute Shader Special Variables
+ if (getShaderType() == GL_COMPUTE_SHADER && !mComputeShaderLocalSizeDeclared &&
+ variable->getType().getQualifier() == EvqWorkGroupSize)
+ {
+ error(location,
+ "It is an error to use gl_WorkGroupSize before declaring the local group size",
+ "gl_WorkGroupSize");
+ }
+
+ // If EXT_shader_framebuffer_fetch_non_coherent is used, gl_LastFragData should be decorated
+ // with 'layout(noncoherent)' EXT_shader_framebuffer_fetch_non_coherent spec: "Unless the
+ // GL_EXT_shader_framebuffer_fetch extension has been enabled in addition, it's an error to use
+ // gl_LastFragData if it hasn't been explicitly redeclared with layout(noncoherent)."
+ if (isExtensionEnabled(TExtension::EXT_shader_framebuffer_fetch_non_coherent) &&
+ !isExtensionEnabled(TExtension::EXT_shader_framebuffer_fetch) &&
+ variable->getType().getQualifier() == EvqLastFragData)
+ {
+ checkNoncoherentIsSpecified(location, variable->getType().getLayoutQualifier().noncoherent);
+ }
+ return variable;
+}
+
+TIntermTyped *TParseContext::parseVariableIdentifier(const TSourceLoc &location,
+ const ImmutableString &name,
+ const TSymbol *symbol)
+{
+ const TVariable *variable = getNamedVariable(location, name, symbol);
+
+ if (!variable)
+ {
+ TIntermTyped *node = CreateZeroNode(TType(EbtFloat, EbpHigh, EvqConst));
+ node->setLine(location);
+ return node;
+ }
+
+ const TType &variableType = variable->getType();
+ TIntermTyped *node = nullptr;
+
+ if (variable->getConstPointer() && variableType.canReplaceWithConstantUnion())
+ {
+ const TConstantUnion *constArray = variable->getConstPointer();
+ node = new TIntermConstantUnion(constArray, variableType);
+ }
+ else if (variableType.getQualifier() == EvqWorkGroupSize && mComputeShaderLocalSizeDeclared)
+ {
+ // gl_WorkGroupSize can be used to size arrays according to the ESSL 3.10.4 spec, so it
+ // needs to be added to the AST as a constant and not as a symbol.
+ sh::WorkGroupSize workGroupSize = getComputeShaderLocalSize();
+ TConstantUnion *constArray = new TConstantUnion[3];
+ for (size_t i = 0; i < 3; ++i)
+ {
+ constArray[i].setUConst(static_cast<unsigned int>(workGroupSize[i]));
+ }
+
+ ASSERT(variableType.getBasicType() == EbtUInt);
+ ASSERT(variableType.getObjectSize() == 3);
+
+ TType type(variableType);
+ type.setQualifier(EvqConst);
+ node = new TIntermConstantUnion(constArray, type);
+ }
+ else if ((mGeometryShaderInputPrimitiveType != EptUndefined) &&
+ (variableType.getQualifier() == EvqPerVertexIn))
+ {
+ ASSERT(symbolTable.getGlInVariableWithArraySize() != nullptr);
+ node = new TIntermSymbol(symbolTable.getGlInVariableWithArraySize());
+ }
+ else
+ {
+ node = new TIntermSymbol(variable);
+ }
+ ASSERT(node != nullptr);
+ node->setLine(location);
+ return node;
+}
+
+void TParseContext::adjustRedeclaredBuiltInType(const ImmutableString &identifier, TType *type)
+{
+ if (identifier == "gl_ClipDistance")
+ {
+ type->setQualifier(EvqClipDistance);
+ }
+ else if (identifier == "gl_CullDistance")
+ {
+ type->setQualifier(EvqCullDistance);
+ }
+ else if (identifier == "gl_LastFragData")
+ {
+ type->setQualifier(EvqLastFragData);
+ }
+}
+
+// Initializers show up in several places in the grammar. Have one set of
+// code to handle them here.
+//
+// Returns true on success.
+bool TParseContext::executeInitializer(const TSourceLoc &line,
+ const ImmutableString &identifier,
+ TType *type,
+ TIntermTyped *initializer,
+ TIntermBinary **initNode)
+{
+ ASSERT(initNode != nullptr);
+ ASSERT(*initNode == nullptr);
+
+ if (type->isUnsizedArray())
+ {
+ // In case initializer is not an array or type has more dimensions than initializer, this
+ // will default to setting array sizes to 1. We have not checked yet whether the initializer
+ // actually is an array or not. Having a non-array initializer for an unsized array will
+ // result in an error later, so we don't generate an error message here.
+ type->sizeUnsizedArrays(initializer->getType().getArraySizes());
+ }
+
+ const TQualifier qualifier = type->getQualifier();
+
+ bool constError = false;
+ if (qualifier == EvqConst)
+ {
+ if (EvqConst != initializer->getType().getQualifier())
+ {
+ TInfoSinkBase reasonStream;
+ reasonStream << "assigning non-constant to '" << *type << "'";
+ error(line, reasonStream.c_str(), "=");
+
+ // We're still going to declare the variable to avoid extra error messages.
+ type->setQualifier(EvqTemporary);
+ constError = true;
+ }
+ }
+
+ TVariable *variable = nullptr;
+ if (!declareVariable(line, identifier, type, &variable))
+ {
+ return false;
+ }
+
+ if (constError)
+ {
+ return false;
+ }
+
+ bool nonConstGlobalInitializers =
+ IsExtensionEnabled(mDirectiveHandler.extensionBehavior(),
+ TExtension::EXT_shader_non_constant_global_initializers);
+ bool globalInitWarning = false;
+ if (symbolTable.atGlobalLevel() &&
+ !ValidateGlobalInitializer(initializer, mShaderVersion, sh::IsWebGLBasedSpec(mShaderSpec),
+ nonConstGlobalInitializers, &globalInitWarning))
+ {
+ // Error message does not completely match behavior with ESSL 1.00, but
+ // we want to steer developers towards only using constant expressions.
+ error(line, "global variable initializers must be constant expressions", "=");
+ return false;
+ }
+ if (globalInitWarning)
+ {
+ warning(
+ line,
+ "global variable initializers should be constant expressions "
+ "(uniforms and globals are allowed in global initializers for legacy compatibility)",
+ "=");
+ }
+
+ // identifier must be of type constant, a global, or a temporary
+ if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal) && (qualifier != EvqConst))
+ {
+ error(line, " cannot initialize this type of qualifier ",
+ variable->getType().getQualifierString());
+ return false;
+ }
+
+ TIntermSymbol *intermSymbol = new TIntermSymbol(variable);
+ intermSymbol->setLine(line);
+
+ if (!binaryOpCommonCheck(EOpInitialize, intermSymbol, initializer, line))
+ {
+ assignError(line, "=", variable->getType(), initializer->getType());
+ return false;
+ }
+
+ if (qualifier == EvqConst)
+ {
+ // Save the constant folded value to the variable if possible.
+ const TConstantUnion *constArray = initializer->getConstantValue();
+ if (constArray)
+ {
+ variable->shareConstPointer(constArray);
+ if (initializer->getType().canReplaceWithConstantUnion())
+ {
+ ASSERT(*initNode == nullptr);
+ return true;
+ }
+ }
+ }
+
+ *initNode = new TIntermBinary(EOpInitialize, intermSymbol, initializer);
+ markStaticReadIfSymbol(initializer);
+ (*initNode)->setLine(line);
+ return true;
+}
+
+TIntermNode *TParseContext::addConditionInitializer(const TPublicType &pType,
+ const ImmutableString &identifier,
+ TIntermTyped *initializer,
+ const TSourceLoc &loc)
+{
+ checkIsScalarBool(loc, pType);
+ TIntermBinary *initNode = nullptr;
+ TType *type = new TType(pType);
+ if (executeInitializer(loc, identifier, type, initializer, &initNode))
+ {
+ // The initializer is valid. The init condition needs to have a node - either the
+ // initializer node, or a constant node in case the initialized variable is const and won't
+ // be recorded in the AST.
+ if (initNode == nullptr)
+ {
+ return initializer;
+ }
+ else
+ {
+ TIntermDeclaration *declaration = new TIntermDeclaration();
+ declaration->appendDeclarator(initNode);
+ return declaration;
+ }
+ }
+ return nullptr;
+}
+
+TIntermNode *TParseContext::addLoop(TLoopType type,
+ TIntermNode *init,
+ TIntermNode *cond,
+ TIntermTyped *expr,
+ TIntermNode *body,
+ const TSourceLoc &line)
+{
+ TIntermNode *node = nullptr;
+ TIntermTyped *typedCond = nullptr;
+ if (cond)
+ {
+ markStaticReadIfSymbol(cond);
+ typedCond = cond->getAsTyped();
+ }
+ if (expr)
+ {
+ markStaticReadIfSymbol(expr);
+ }
+ // In case the loop body was not parsed as a block and contains a statement that simply refers
+ // to a variable, we need to mark it as statically used.
+ if (body)
+ {
+ markStaticReadIfSymbol(body);
+ }
+ if (cond == nullptr || typedCond)
+ {
+ if (type == ELoopDoWhile && typedCond)
+ {
+ checkIsScalarBool(line, typedCond);
+ }
+ // In the case of other loops, it was checked before that the condition is a scalar boolean.
+ ASSERT(mDiagnostics->numErrors() > 0 || typedCond == nullptr ||
+ (typedCond->getBasicType() == EbtBool && !typedCond->isArray() &&
+ !typedCond->isVector()));
+
+ node = new TIntermLoop(type, init, typedCond, expr, EnsureBlock(body));
+ node->setLine(line);
+ return node;
+ }
+
+ ASSERT(type != ELoopDoWhile);
+
+ TIntermDeclaration *declaration = cond->getAsDeclarationNode();
+ ASSERT(declaration);
+ TIntermBinary *declarator = declaration->getSequence()->front()->getAsBinaryNode();
+ ASSERT(declarator->getLeft()->getAsSymbolNode());
+
+ // The condition is a declaration. In the AST representation we don't support declarations as
+ // loop conditions. Wrap the loop to a block that declares the condition variable and contains
+ // the loop.
+ TIntermBlock *block = new TIntermBlock();
+
+ TIntermDeclaration *declareCondition = new TIntermDeclaration();
+ declareCondition->appendDeclarator(declarator->getLeft()->deepCopy());
+ block->appendStatement(declareCondition);
+
+ TIntermBinary *conditionInit = new TIntermBinary(EOpAssign, declarator->getLeft()->deepCopy(),
+ declarator->getRight()->deepCopy());
+ TIntermLoop *loop = new TIntermLoop(type, init, conditionInit, expr, EnsureBlock(body));
+ block->appendStatement(loop);
+ loop->setLine(line);
+ block->setLine(line);
+ return block;
+}
+
+TIntermNode *TParseContext::addIfElse(TIntermTyped *cond,
+ TIntermNodePair code,
+ const TSourceLoc &loc)
+{
+ bool isScalarBool = checkIsScalarBool(loc, cond);
+ // In case the conditional statements were not parsed as blocks and contain a statement that
+ // simply refers to a variable, we need to mark them as statically used.
+ if (code.node1)
+ {
+ markStaticReadIfSymbol(code.node1);
+ }
+ if (code.node2)
+ {
+ markStaticReadIfSymbol(code.node2);
+ }
+
+ // For compile time constant conditions, prune the code now.
+ if (isScalarBool && cond->getAsConstantUnion())
+ {
+ if (cond->getAsConstantUnion()->getBConst(0) == true)
+ {
+ return EnsureBlock(code.node1);
+ }
+ else
+ {
+ return EnsureBlock(code.node2);
+ }
+ }
+
+ TIntermIfElse *node = new TIntermIfElse(cond, EnsureBlock(code.node1), EnsureBlock(code.node2));
+ markStaticReadIfSymbol(cond);
+ node->setLine(loc);
+
+ return node;
+}
+
+void TParseContext::addFullySpecifiedType(TPublicType *typeSpecifier)
+{
+ checkPrecisionSpecified(typeSpecifier->getLine(), typeSpecifier->precision,
+ typeSpecifier->getBasicType());
+
+ if (mShaderVersion < 300 && typeSpecifier->isArray())
+ {
+ error(typeSpecifier->getLine(), "not supported", "first-class array");
+ typeSpecifier->clearArrayness();
+ }
+}
+
+TPublicType TParseContext::addFullySpecifiedType(const TTypeQualifierBuilder &typeQualifierBuilder,
+ const TPublicType &typeSpecifier)
+{
+ TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(mDiagnostics);
+
+ TPublicType returnType = typeSpecifier;
+ returnType.qualifier = typeQualifier.qualifier;
+ returnType.invariant = typeQualifier.invariant;
+ returnType.precise = typeQualifier.precise;
+ returnType.layoutQualifier = typeQualifier.layoutQualifier;
+ returnType.memoryQualifier = typeQualifier.memoryQualifier;
+ 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);
+
+ checkEarlyFragmentTestsIsNotSpecified(typeSpecifier.getLine(),
+ returnType.layoutQualifier.earlyFragmentTests);
+
+ if (returnType.qualifier == EvqSampleIn || returnType.qualifier == EvqSampleOut)
+ {
+ mSampleQualifierSpecified = true;
+ }
+
+ if (mShaderVersion < 300)
+ {
+ if (typeSpecifier.isArray())
+ {
+ error(typeSpecifier.getLine(), "not supported", "first-class array");
+ returnType.clearArrayness();
+ }
+
+ if (returnType.qualifier == EvqAttribute &&
+ (typeSpecifier.getBasicType() == EbtBool || typeSpecifier.getBasicType() == EbtInt))
+ {
+ error(typeSpecifier.getLine(), "cannot be bool or int",
+ getQualifierString(returnType.qualifier));
+ }
+
+ if ((returnType.qualifier == EvqVaryingIn || returnType.qualifier == EvqVaryingOut) &&
+ (typeSpecifier.getBasicType() == EbtBool || typeSpecifier.getBasicType() == EbtInt))
+ {
+ error(typeSpecifier.getLine(), "cannot be bool or int",
+ getQualifierString(returnType.qualifier));
+ }
+ }
+ else
+ {
+ if (!returnType.layoutQualifier.isEmpty())
+ {
+ checkIsAtGlobalLevel(typeSpecifier.getLine(), "layout");
+ }
+ if (sh::IsVarying(returnType.qualifier) || returnType.qualifier == EvqVertexIn ||
+ returnType.qualifier == EvqFragmentOut || returnType.qualifier == EvqFragmentInOut)
+ {
+ 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::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.getBasicType() == EbtBool)
+ {
+ error(qualifierLocation, "cannot be bool", getQualifierString(qualifier));
+ }
+
+ // Specific restrictions apply for vertex shader inputs and fragment shader outputs.
+ switch (qualifier)
+ {
+ case EvqVertexIn:
+ // ESSL 3.00 section 4.3.4
+ if (type.isArray())
+ {
+ error(qualifierLocation, "cannot be array", getQualifierString(qualifier));
+ }
+ // Vertex inputs with a struct type are disallowed in nonEmptyDeclarationErrorCheck
+ return;
+ case EvqFragmentOut:
+ case EvqFragmentInOut:
+ // ESSL 3.00 section 4.3.6
+ if (type.typeSpecifierNonArray.isMatrix())
+ {
+ error(qualifierLocation, "cannot be matrix", getQualifierString(qualifier));
+ }
+ // Fragment outputs with a struct type are disallowed in nonEmptyDeclarationErrorCheck
+ return;
+ default:
+ break;
+ }
+
+ // Vertex shader outputs / fragment shader inputs have a different, slightly more lenient set of
+ // restrictions.
+ bool typeContainsIntegers =
+ (type.getBasicType() == EbtInt || type.getBasicType() == EbtUInt ||
+ type.isStructureContainingType(EbtInt) || type.isStructureContainingType(EbtUInt));
+ bool extendedShaderTypes = mShaderVersion >= 320 ||
+ isExtensionEnabled(TExtension::EXT_geometry_shader) ||
+ isExtensionEnabled(TExtension::OES_geometry_shader) ||
+ isExtensionEnabled(TExtension::EXT_tessellation_shader);
+ if (typeContainsIntegers && qualifier != EvqFlatIn && qualifier != EvqFlatOut &&
+ (!extendedShaderTypes || mShaderType == GL_FRAGMENT_SHADER))
+ {
+ error(qualifierLocation, "must use 'flat' interpolation here",
+ getQualifierString(qualifier));
+ }
+
+ 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
+ // the ESSL 3.10 spec lists these restrictions explicitly.
+ if (type.isArray())
+ {
+ error(qualifierLocation, "cannot be an array of structures",
+ getQualifierString(qualifier));
+ }
+ if (type.isStructureContainingArrays())
+ {
+ error(qualifierLocation, "cannot be a structure containing an array",
+ getQualifierString(qualifier));
+ }
+ if (type.isStructureContainingType(EbtStruct))
+ {
+ error(qualifierLocation, "cannot be a structure containing a structure",
+ getQualifierString(qualifier));
+ }
+ if (type.isStructureContainingType(EbtBool))
+ {
+ error(qualifierLocation, "cannot be a structure containing a bool",
+ getQualifierString(qualifier));
+ }
+ }
+}
+
+void TParseContext::checkLocalVariableConstStorageQualifier(const TQualifierWrapperBase &qualifier)
+{
+ if (qualifier.getType() == QtStorage)
+ {
+ const TStorageQualifierWrapper &storageQualifier =
+ static_cast<const TStorageQualifierWrapper &>(qualifier);
+ if (!declaringFunction() && storageQualifier.getQualifier() != EvqConst &&
+ !symbolTable.atGlobalLevel())
+ {
+ error(storageQualifier.getLine(),
+ "Local variables can only use the const storage qualifier.",
+ storageQualifier.getQualifierString());
+ }
+ }
+}
+
+void TParseContext::checkMemoryQualifierIsNotSpecified(const TMemoryQualifier &memoryQualifier,
+ const TSourceLoc &location)
+{
+ const std::string reason(
+ "Only allowed with shader storage blocks, variables declared within shader storage blocks "
+ "and variables declared as image types.");
+ if (memoryQualifier.readonly)
+ {
+ error(location, reason.c_str(), "readonly");
+ }
+ if (memoryQualifier.writeonly)
+ {
+ error(location, reason.c_str(), "writeonly");
+ }
+ if (memoryQualifier.coherent)
+ {
+ error(location, reason.c_str(), "coherent");
+ }
+ if (memoryQualifier.restrictQualifier)
+ {
+ error(location, reason.c_str(), "restrict");
+ }
+ if (memoryQualifier.volatileQualifier)
+ {
+ error(location, reason.c_str(), "volatile");
+ }
+}
+
+// Make sure there is no offset overlapping, and store the newly assigned offset to "type" in
+// intermediate tree.
+void TParseContext::checkAtomicCounterOffsetDoesNotOverlap(bool forceAppend,
+ const TSourceLoc &loc,
+ TType *type)
+{
+ const size_t size = type->isArray() ? kAtomicCounterArrayStride * type->getArraySizeProduct()
+ : kAtomicCounterSize;
+ TLayoutQualifier layoutQualifier = type->getLayoutQualifier();
+ auto &bindingState = mAtomicCounterBindingStates[layoutQualifier.binding];
+ int offset;
+ if (layoutQualifier.offset == -1 || forceAppend)
+ {
+ offset = bindingState.appendSpan(size);
+ }
+ else
+ {
+ offset = bindingState.insertSpan(layoutQualifier.offset, size);
+ }
+ if (offset == -1)
+ {
+ error(loc, "Offset overlapping", "atomic counter");
+ return;
+ }
+ layoutQualifier.offset = offset;
+ type->setLayoutQualifier(layoutQualifier);
+}
+
+void TParseContext::checkAtomicCounterOffsetAlignment(const TSourceLoc &location, const TType &type)
+{
+ TLayoutQualifier layoutQualifier = type.getLayoutQualifier();
+
+ // OpenGL ES 3.1 Table 6.5, Atomic counter offset must be a multiple of 4
+ if (layoutQualifier.offset % 4 != 0)
+ {
+ error(location, "Offset must be multiple of 4", "atomic counter");
+ }
+}
+
+void TParseContext::checkGeometryShaderInputAndSetArraySize(const TSourceLoc &location,
+ const ImmutableString &token,
+ TType *type)
+{
+ if (IsGeometryShaderInput(mShaderType, type->getQualifier()))
+ {
+ if (type->isArray() && type->getOutermostArraySize() == 0u)
+ {
+ // Set size for the unsized geometry shader inputs if they are declared after a valid
+ // input primitive declaration.
+ if (mGeometryShaderInputPrimitiveType != EptUndefined)
+ {
+ ASSERT(symbolTable.getGlInVariableWithArraySize() != nullptr);
+ type->sizeOutermostUnsizedArray(
+ symbolTable.getGlInVariableWithArraySize()->getType().getOutermostArraySize());
+ }
+ else
+ {
+ // [GLSL ES 3.2 SPEC Chapter 4.4.1.2]
+ // An input can be declared without an array size if there is a previous layout
+ // which specifies the size.
+ warning(location,
+ "Missing a valid input primitive declaration before declaring an unsized "
+ "array input",
+ "Deferred");
+ mDeferredArrayTypesToSize.push_back(type);
+ }
+ }
+ else if (type->isArray())
+ {
+ setGeometryShaderInputArraySize(type->getOutermostArraySize(), location);
+ }
+ else
+ {
+ error(location, "Geometry shader input variable must be declared as an array", token);
+ }
+ }
+}
+
+void TParseContext::checkTessellationShaderUnsizedArraysAndSetSize(const TSourceLoc &location,
+ const ImmutableString &token,
+ TType *type)
+{
+ TQualifier qualifier = type->getQualifier();
+ if (!IsTessellationControlShaderOutput(mShaderType, qualifier) &&
+ !IsTessellationControlShaderInput(mShaderType, qualifier) &&
+ !IsTessellationEvaluationShaderInput(mShaderType, qualifier))
+ {
+ return;
+ }
+
+ // Such variables must be declared as arrays or inside output blocks declared as arrays.
+ if (!type->isArray())
+ {
+ error(location, "Tessellation interface variables must be declared as an array", token);
+ return;
+ }
+
+ // If a size is specified, it must match the maximum patch size.
+ unsigned int outermostSize = type->getOutermostArraySize();
+ if (outermostSize == 0u)
+ {
+ switch (qualifier)
+ {
+ case EvqTessControlIn:
+ case EvqTessEvaluationIn:
+ case EvqFlatIn:
+ case EvqCentroidIn:
+ case EvqSmoothIn:
+ case EvqSampleIn:
+ // Declaring an array size is optional. If no size is specified, it will be taken
+ // from the implementation-dependent maximum patch size (gl_MaxPatchVertices).
+ ASSERT(mMaxPatchVertices > 0);
+ type->sizeOutermostUnsizedArray(mMaxPatchVertices);
+ break;
+ case EvqTessControlOut:
+ case EvqFlatOut:
+ case EvqCentroidOut:
+ case EvqSmoothOut:
+ case EvqSampleOut:
+ // Declaring an array size is optional. If no size is specified, it will be taken
+ // from output patch size declared in the shader. If the patch size is not yet
+ // declared, this is deferred until such time as it does.
+ if (mTessControlShaderOutputVertices == 0)
+ {
+ mDeferredArrayTypesToSize.push_back(type);
+ }
+ else
+ {
+ type->sizeOutermostUnsizedArray(mTessControlShaderOutputVertices);
+ }
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ return;
+ }
+
+ if (IsTessellationControlShaderInput(mShaderType, qualifier) ||
+ IsTessellationEvaluationShaderInput(mShaderType, qualifier))
+ {
+ if (outermostSize != static_cast<unsigned int>(mMaxPatchVertices))
+ {
+ error(location,
+ "If a size is specified for a tessellation control or evaluation user-defined "
+ "input variable, it must match the maximum patch size (gl_MaxPatchVertices).",
+ token);
+ }
+ }
+ else if (IsTessellationControlShaderOutput(mShaderType, qualifier))
+ {
+ if (outermostSize != static_cast<unsigned int>(mTessControlShaderOutputVertices) &&
+ mTessControlShaderOutputVertices != 0)
+ {
+ error(location,
+ "If a size is specified for a tessellation control user-defined per-vertex "
+ "output variable, it must match the the number of vertices in the output "
+ "patch.",
+ token);
+ }
+ }
+}
+
+TIntermDeclaration *TParseContext::parseSingleDeclaration(
+ TPublicType &publicType,
+ const TSourceLoc &identifierOrTypeLocation,
+ const ImmutableString &identifier)
+{
+ TType *type = new TType(publicType);
+ if (mCompileOptions.flattenPragmaSTDGLInvariantAll &&
+ 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.
+ if (qualifier == EvqVaryingOut || qualifier == EvqVertexOut)
+ {
+ type->setInvariant(true);
+ }
+ }
+
+ checkGeometryShaderInputAndSetArraySize(identifierOrTypeLocation, identifier, type);
+ checkTessellationShaderUnsizedArraysAndSetSize(identifierOrTypeLocation, identifier, type);
+
+ declarationQualifierErrorCheck(publicType.qualifier, publicType.layoutQualifier,
+ identifierOrTypeLocation);
+
+ bool emptyDeclaration = (identifier == "");
+ mDeferredNonEmptyDeclarationErrorCheck = emptyDeclaration;
+
+ TIntermSymbol *symbol = nullptr;
+ if (emptyDeclaration)
+ {
+ emptyDeclarationErrorCheck(*type, identifierOrTypeLocation);
+ // In most cases we don't need to create a symbol node for an empty declaration.
+ // But if the empty declaration is declaring a struct type, the symbol node will store that.
+ if (type->getBasicType() == EbtStruct)
+ {
+ TVariable *emptyVariable =
+ new TVariable(&symbolTable, kEmptyImmutableString, type, SymbolType::Empty);
+ symbol = new TIntermSymbol(emptyVariable);
+ }
+ else if (IsAtomicCounter(publicType.getBasicType()))
+ {
+ setAtomicCounterBindingDefaultOffset(publicType, identifierOrTypeLocation);
+ }
+ }
+ else
+ {
+ nonEmptyDeclarationErrorCheck(publicType, identifierOrTypeLocation);
+
+ checkCanBeDeclaredWithoutInitializer(identifierOrTypeLocation, identifier, type);
+
+ if (IsAtomicCounter(type->getBasicType()))
+ {
+ checkAtomicCounterOffsetDoesNotOverlap(false, identifierOrTypeLocation, type);
+
+ checkAtomicCounterOffsetAlignment(identifierOrTypeLocation, *type);
+ }
+
+ TVariable *variable = nullptr;
+ if (declareVariable(identifierOrTypeLocation, identifier, type, &variable))
+ {
+ symbol = new TIntermSymbol(variable);
+ }
+ }
+
+ TIntermDeclaration *declaration = new TIntermDeclaration();
+ declaration->setLine(identifierOrTypeLocation);
+ if (symbol)
+ {
+ symbol->setLine(identifierOrTypeLocation);
+ declaration->appendDeclarator(symbol);
+ }
+ return declaration;
+}
+
+TIntermDeclaration *TParseContext::parseSingleArrayDeclaration(
+ TPublicType &elementType,
+ const TSourceLoc &identifierLocation,
+ const ImmutableString &identifier,
+ const TSourceLoc &indexLocation,
+ const TVector<unsigned int> &arraySizes)
+{
+ mDeferredNonEmptyDeclarationErrorCheck = false;
+
+ declarationQualifierErrorCheck(elementType.qualifier, elementType.layoutQualifier,
+ identifierLocation);
+
+ nonEmptyDeclarationErrorCheck(elementType, identifierLocation);
+
+ checkIsValidTypeAndQualifierForArray(indexLocation, elementType);
+
+ TType *arrayType = new TType(elementType);
+ arrayType->makeArrays(arraySizes);
+
+ checkArrayOfArraysInOut(indexLocation, elementType, *arrayType);
+
+ checkGeometryShaderInputAndSetArraySize(indexLocation, identifier, arrayType);
+ checkTessellationShaderUnsizedArraysAndSetSize(indexLocation, identifier, arrayType);
+
+ checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, arrayType);
+
+ if (IsAtomicCounter(arrayType->getBasicType()))
+ {
+ checkAtomicCounterOffsetDoesNotOverlap(false, identifierLocation, arrayType);
+
+ checkAtomicCounterOffsetAlignment(identifierLocation, *arrayType);
+ }
+
+ adjustRedeclaredBuiltInType(identifier, arrayType);
+
+ TIntermDeclaration *declaration = new TIntermDeclaration();
+ declaration->setLine(identifierLocation);
+
+ TVariable *variable = nullptr;
+ if (declareVariable(identifierLocation, identifier, arrayType, &variable))
+ {
+ TIntermSymbol *symbol = new TIntermSymbol(variable);
+ symbol->setLine(identifierLocation);
+ declaration->appendDeclarator(symbol);
+ }
+
+ return declaration;
+}
+
+TIntermDeclaration *TParseContext::parseSingleInitDeclaration(const TPublicType &publicType,
+ const TSourceLoc &identifierLocation,
+ const ImmutableString &identifier,
+ const TSourceLoc &initLocation,
+ TIntermTyped *initializer)
+{
+ mDeferredNonEmptyDeclarationErrorCheck = false;
+
+ declarationQualifierErrorCheck(publicType.qualifier, publicType.layoutQualifier,
+ identifierLocation);
+
+ nonEmptyDeclarationErrorCheck(publicType, identifierLocation);
+
+ TIntermDeclaration *declaration = new TIntermDeclaration();
+ declaration->setLine(identifierLocation);
+
+ TIntermBinary *initNode = nullptr;
+ TType *type = new TType(publicType);
+ if (executeInitializer(identifierLocation, identifier, type, initializer, &initNode))
+ {
+ if (initNode)
+ {
+ declaration->appendDeclarator(initNode);
+ }
+ else if (publicType.isStructSpecifier())
+ {
+ // The initialization got constant folded. If it's a struct, declare the struct anyway.
+ TVariable *emptyVariable =
+ new TVariable(&symbolTable, kEmptyImmutableString, type, SymbolType::Empty);
+ TIntermSymbol *symbol = new TIntermSymbol(emptyVariable);
+ symbol->setLine(publicType.getLine());
+ declaration->appendDeclarator(symbol);
+ }
+ }
+ return declaration;
+}
+
+TIntermDeclaration *TParseContext::parseSingleArrayInitDeclaration(
+ TPublicType &elementType,
+ const TSourceLoc &identifierLocation,
+ const ImmutableString &identifier,
+ const TSourceLoc &indexLocation,
+ const TVector<unsigned int> &arraySizes,
+ const TSourceLoc &initLocation,
+ TIntermTyped *initializer)
+{
+ mDeferredNonEmptyDeclarationErrorCheck = false;
+
+ declarationQualifierErrorCheck(elementType.qualifier, elementType.layoutQualifier,
+ identifierLocation);
+
+ nonEmptyDeclarationErrorCheck(elementType, identifierLocation);
+
+ checkIsValidTypeAndQualifierForArray(indexLocation, elementType);
+
+ TType *arrayType = new TType(elementType);
+ arrayType->makeArrays(arraySizes);
+
+ TIntermDeclaration *declaration = new TIntermDeclaration();
+ declaration->setLine(identifierLocation);
+
+ // initNode will correspond to the whole of "type b[n] = initializer".
+ TIntermBinary *initNode = nullptr;
+ if (executeInitializer(identifierLocation, identifier, arrayType, initializer, &initNode))
+ {
+ if (initNode)
+ {
+ declaration->appendDeclarator(initNode);
+ }
+ }
+
+ return declaration;
+}
+
+TIntermGlobalQualifierDeclaration *TParseContext::parseGlobalQualifierDeclaration(
+ const TTypeQualifierBuilder &typeQualifierBuilder,
+ const TSourceLoc &identifierLoc,
+ const ImmutableString &identifier,
+ const TSymbol *symbol)
+{
+ TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(mDiagnostics);
+
+ if (!typeQualifier.invariant && !typeQualifier.precise)
+ {
+ error(identifierLoc, "Expected invariant or precise", identifier);
+ return nullptr;
+ }
+ if (typeQualifier.invariant && !checkIsAtGlobalLevel(identifierLoc, "invariant varying"))
+ {
+ return nullptr;
+ }
+ if (!symbol)
+ {
+ error(identifierLoc, "undeclared identifier declared as invariant or precise", identifier);
+ return nullptr;
+ }
+ if (!IsQualifierUnspecified(typeQualifier.qualifier))
+ {
+ error(identifierLoc, "invariant or precise declaration specifies qualifier",
+ getQualifierString(typeQualifier.qualifier));
+ }
+ if (typeQualifier.precision != EbpUndefined)
+ {
+ error(identifierLoc, "invariant or precise declaration specifies precision",
+ getPrecisionString(typeQualifier.precision));
+ }
+ if (!typeQualifier.layoutQualifier.isEmpty())
+ {
+ error(identifierLoc, "invariant or precise declaration specifies layout", "'layout'");
+ }
+
+ const TVariable *variable = getNamedVariable(identifierLoc, identifier, symbol);
+ if (!variable)
+ {
+ return nullptr;
+ }
+ const TType &type = variable->getType();
+
+ checkInvariantVariableQualifier(typeQualifier.invariant, type.getQualifier(),
+ typeQualifier.line);
+ checkMemoryQualifierIsNotSpecified(typeQualifier.memoryQualifier, typeQualifier.line);
+
+ symbolTable.addInvariantVarying(*variable);
+
+ TIntermSymbol *intermSymbol = new TIntermSymbol(variable);
+ intermSymbol->setLine(identifierLoc);
+
+ return new TIntermGlobalQualifierDeclaration(intermSymbol, typeQualifier.precise,
+ identifierLoc);
+}
+
+void TParseContext::parseDeclarator(TPublicType &publicType,
+ const TSourceLoc &identifierLocation,
+ const ImmutableString &identifier,
+ TIntermDeclaration *declarationOut)
+{
+ // If the declaration starting this declarator list was empty (example: int,), some checks were
+ // not performed.
+ if (mDeferredNonEmptyDeclarationErrorCheck)
+ {
+ nonEmptyDeclarationErrorCheck(publicType, identifierLocation);
+ mDeferredNonEmptyDeclarationErrorCheck = false;
+ }
+
+ checkDeclaratorLocationIsNotSpecified(identifierLocation, publicType);
+
+ TType *type = new TType(publicType);
+
+ checkGeometryShaderInputAndSetArraySize(identifierLocation, identifier, type);
+ checkTessellationShaderUnsizedArraysAndSetSize(identifierLocation, identifier, type);
+
+ checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, type);
+
+ if (IsAtomicCounter(type->getBasicType()))
+ {
+ checkAtomicCounterOffsetDoesNotOverlap(true, identifierLocation, type);
+
+ checkAtomicCounterOffsetAlignment(identifierLocation, *type);
+ }
+
+ adjustRedeclaredBuiltInType(identifier, type);
+
+ TVariable *variable = nullptr;
+ if (declareVariable(identifierLocation, identifier, type, &variable))
+ {
+ TIntermSymbol *symbol = new TIntermSymbol(variable);
+ symbol->setLine(identifierLocation);
+ declarationOut->appendDeclarator(symbol);
+ }
+}
+
+void TParseContext::parseArrayDeclarator(TPublicType &elementType,
+ const TSourceLoc &identifierLocation,
+ const ImmutableString &identifier,
+ const TSourceLoc &arrayLocation,
+ const TVector<unsigned int> &arraySizes,
+ TIntermDeclaration *declarationOut)
+{
+ // If the declaration starting this declarator list was empty (example: int,), some checks were
+ // not performed.
+ if (mDeferredNonEmptyDeclarationErrorCheck)
+ {
+ nonEmptyDeclarationErrorCheck(elementType, identifierLocation);
+ mDeferredNonEmptyDeclarationErrorCheck = false;
+ }
+
+ checkDeclaratorLocationIsNotSpecified(identifierLocation, elementType);
+
+ if (checkIsValidTypeAndQualifierForArray(arrayLocation, elementType))
+ {
+ TType *arrayType = new TType(elementType);
+ arrayType->makeArrays(arraySizes);
+
+ checkGeometryShaderInputAndSetArraySize(identifierLocation, identifier, arrayType);
+ checkTessellationShaderUnsizedArraysAndSetSize(identifierLocation, identifier, arrayType);
+
+ checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, arrayType);
+
+ if (IsAtomicCounter(arrayType->getBasicType()))
+ {
+ checkAtomicCounterOffsetDoesNotOverlap(true, identifierLocation, arrayType);
+
+ checkAtomicCounterOffsetAlignment(identifierLocation, *arrayType);
+ }
+
+ adjustRedeclaredBuiltInType(identifier, arrayType);
+
+ TVariable *variable = nullptr;
+ if (declareVariable(identifierLocation, identifier, arrayType, &variable))
+ {
+ TIntermSymbol *symbol = new TIntermSymbol(variable);
+ symbol->setLine(identifierLocation);
+ declarationOut->appendDeclarator(symbol);
+ }
+ }
+}
+
+void TParseContext::parseInitDeclarator(const TPublicType &publicType,
+ const TSourceLoc &identifierLocation,
+ const ImmutableString &identifier,
+ const TSourceLoc &initLocation,
+ TIntermTyped *initializer,
+ TIntermDeclaration *declarationOut)
+{
+ // If the declaration starting this declarator list was empty (example: int,), some checks were
+ // not performed.
+ if (mDeferredNonEmptyDeclarationErrorCheck)
+ {
+ nonEmptyDeclarationErrorCheck(publicType, identifierLocation);
+ mDeferredNonEmptyDeclarationErrorCheck = false;
+ }
+
+ checkDeclaratorLocationIsNotSpecified(identifierLocation, publicType);
+
+ TIntermBinary *initNode = nullptr;
+ TType *type = new TType(publicType);
+ if (executeInitializer(identifierLocation, identifier, type, initializer, &initNode))
+ {
+ //
+ // build the intermediate representation
+ //
+ if (initNode)
+ {
+ declarationOut->appendDeclarator(initNode);
+ }
+ }
+}
+
+void TParseContext::parseArrayInitDeclarator(const TPublicType &elementType,
+ const TSourceLoc &identifierLocation,
+ const ImmutableString &identifier,
+ const TSourceLoc &indexLocation,
+ const TVector<unsigned int> &arraySizes,
+ const TSourceLoc &initLocation,
+ TIntermTyped *initializer,
+ TIntermDeclaration *declarationOut)
+{
+ // If the declaration starting this declarator list was empty (example: int,), some checks were
+ // not performed.
+ if (mDeferredNonEmptyDeclarationErrorCheck)
+ {
+ nonEmptyDeclarationErrorCheck(elementType, identifierLocation);
+ mDeferredNonEmptyDeclarationErrorCheck = false;
+ }
+
+ checkDeclaratorLocationIsNotSpecified(identifierLocation, elementType);
+
+ checkIsValidTypeAndQualifierForArray(indexLocation, elementType);
+
+ TType *arrayType = new TType(elementType);
+ arrayType->makeArrays(arraySizes);
+
+ // initNode will correspond to the whole of "b[n] = initializer".
+ TIntermBinary *initNode = nullptr;
+ if (executeInitializer(identifierLocation, identifier, arrayType, initializer, &initNode))
+ {
+ if (initNode)
+ {
+ declarationOut->appendDeclarator(initNode);
+ }
+ }
+}
+
+TIntermNode *TParseContext::addEmptyStatement(const TSourceLoc &location)
+{
+ // It's simpler to parse an empty statement as a constant expression rather than having a
+ // different type of node just for empty statements, that will be pruned from the AST anyway.
+ TIntermNode *node = CreateZeroNode(TType(EbtInt, EbpMedium));
+ node->setLine(location);
+ return node;
+}
+
+void TParseContext::setAtomicCounterBindingDefaultOffset(const TPublicType &publicType,
+ const TSourceLoc &location)
+{
+ const TLayoutQualifier &layoutQualifier = publicType.layoutQualifier;
+ checkAtomicCounterBindingIsValid(location, layoutQualifier.binding);
+ if (layoutQualifier.binding == -1 || layoutQualifier.offset == -1)
+ {
+ error(location, "Requires both binding and offset", "layout");
+ return;
+ }
+ mAtomicCounterBindingStates[layoutQualifier.binding].setDefaultOffset(layoutQualifier.offset);
+}
+
+void TParseContext::parseDefaultPrecisionQualifier(const TPrecision precision,
+ const TPublicType &type,
+ const TSourceLoc &loc)
+{
+ if ((precision == EbpHigh) && (getShaderType() == GL_FRAGMENT_SHADER) &&
+ !getFragmentPrecisionHigh())
+ {
+ error(loc, "precision is not supported in fragment shader", "highp");
+ }
+
+ if (!CanSetDefaultPrecisionOnType(type))
+ {
+ error(loc, "illegal type argument for default precision qualifier",
+ getBasicString(type.getBasicType()));
+ return;
+ }
+ symbolTable.setDefaultPrecision(type.getBasicType(), precision);
+}
+
+bool TParseContext::checkPrimitiveTypeMatchesTypeQualifier(const TTypeQualifier &typeQualifier)
+{
+ switch (typeQualifier.layoutQualifier.primitiveType)
+ {
+ case EptLines:
+ case EptLinesAdjacency:
+ case EptTriangles:
+ case EptTrianglesAdjacency:
+ return typeQualifier.qualifier == EvqGeometryIn;
+
+ case EptLineStrip:
+ case EptTriangleStrip:
+ return typeQualifier.qualifier == EvqGeometryOut;
+
+ case EptPoints:
+ return true;
+
+ default:
+ UNREACHABLE();
+ return false;
+ }
+}
+
+void TParseContext::setGeometryShaderInputArraySize(unsigned int inputArraySize,
+ const TSourceLoc &line)
+{
+ if (!symbolTable.setGlInArraySize(inputArraySize))
+ {
+ error(line,
+ "Array size or input primitive declaration doesn't match the size of earlier sized "
+ "array inputs.",
+ "layout");
+ }
+ mGeometryInputArraySize = inputArraySize;
+}
+
+bool TParseContext::parseGeometryShaderInputLayoutQualifier(const TTypeQualifier &typeQualifier)
+{
+ ASSERT(typeQualifier.qualifier == EvqGeometryIn);
+
+ const TLayoutQualifier &layoutQualifier = typeQualifier.layoutQualifier;
+
+ if (layoutQualifier.maxVertices != -1)
+ {
+ error(typeQualifier.line,
+ "max_vertices can only be declared in 'out' layout in a geometry shader", "layout");
+ return false;
+ }
+
+ // Set mGeometryInputPrimitiveType if exists
+ if (layoutQualifier.primitiveType != EptUndefined)
+ {
+ if (!checkPrimitiveTypeMatchesTypeQualifier(typeQualifier))
+ {
+ error(typeQualifier.line, "invalid primitive type for 'in' layout", "layout");
+ return false;
+ }
+
+ if (mGeometryShaderInputPrimitiveType == EptUndefined)
+ {
+ mGeometryShaderInputPrimitiveType = layoutQualifier.primitiveType;
+ setGeometryShaderInputArraySize(
+ GetGeometryShaderInputArraySize(mGeometryShaderInputPrimitiveType),
+ typeQualifier.line);
+ }
+ else if (mGeometryShaderInputPrimitiveType != layoutQualifier.primitiveType)
+ {
+ error(typeQualifier.line, "primitive doesn't match earlier input primitive declaration",
+ "layout");
+ return false;
+ }
+
+ // Size any implicitly sized arrays that have already been declared.
+ for (TType *type : mDeferredArrayTypesToSize)
+ {
+ type->sizeOutermostUnsizedArray(
+ symbolTable.getGlInVariableWithArraySize()->getType().getOutermostArraySize());
+ }
+ mDeferredArrayTypesToSize.clear();
+ }
+
+ // Set mGeometryInvocations if exists
+ if (layoutQualifier.invocations > 0)
+ {
+ if (mGeometryShaderInvocations == 0)
+ {
+ mGeometryShaderInvocations = layoutQualifier.invocations;
+ }
+ else if (mGeometryShaderInvocations != layoutQualifier.invocations)
+ {
+ error(typeQualifier.line, "invocations contradicts to the earlier declaration",
+ "layout");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool TParseContext::parseGeometryShaderOutputLayoutQualifier(const TTypeQualifier &typeQualifier)
+{
+ ASSERT(typeQualifier.qualifier == EvqGeometryOut);
+
+ const TLayoutQualifier &layoutQualifier = typeQualifier.layoutQualifier;
+
+ if (layoutQualifier.invocations > 0)
+ {
+ error(typeQualifier.line,
+ "invocations can only be declared in 'in' layout in a geometry shader", "layout");
+ return false;
+ }
+
+ // Set mGeometryOutputPrimitiveType if exists
+ if (layoutQualifier.primitiveType != EptUndefined)
+ {
+ if (!checkPrimitiveTypeMatchesTypeQualifier(typeQualifier))
+ {
+ error(typeQualifier.line, "invalid primitive type for 'out' layout", "layout");
+ return false;
+ }
+
+ if (mGeometryShaderOutputPrimitiveType == EptUndefined)
+ {
+ mGeometryShaderOutputPrimitiveType = layoutQualifier.primitiveType;
+ }
+ else if (mGeometryShaderOutputPrimitiveType != layoutQualifier.primitiveType)
+ {
+ error(typeQualifier.line,
+ "primitive doesn't match earlier output primitive declaration", "layout");
+ return false;
+ }
+ }
+
+ // Set mGeometryMaxVertices if exists
+ if (layoutQualifier.maxVertices > -1)
+ {
+ if (mGeometryShaderMaxVertices == -1)
+ {
+ mGeometryShaderMaxVertices = layoutQualifier.maxVertices;
+ }
+ else if (mGeometryShaderMaxVertices != layoutQualifier.maxVertices)
+ {
+ error(typeQualifier.line, "max_vertices contradicts to the earlier declaration",
+ "layout");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool TParseContext::parseTessControlShaderOutputLayoutQualifier(const TTypeQualifier &typeQualifier)
+{
+ ASSERT(typeQualifier.qualifier == EvqTessControlOut);
+
+ const TLayoutQualifier &layoutQualifier = typeQualifier.layoutQualifier;
+
+ if (layoutQualifier.vertices == 0)
+ {
+ error(typeQualifier.line, "No vertices specified", "layout");
+ return false;
+ }
+
+ // Set mTessControlShaderOutputVertices if exists
+ if (mTessControlShaderOutputVertices == 0)
+ {
+ mTessControlShaderOutputVertices = layoutQualifier.vertices;
+
+ // Size any implicitly sized arrays that have already been declared.
+ for (TType *type : mDeferredArrayTypesToSize)
+ {
+ type->sizeOutermostUnsizedArray(mTessControlShaderOutputVertices);
+ }
+ mDeferredArrayTypesToSize.clear();
+ }
+ else
+ {
+ error(typeQualifier.line, "Duplicated vertices specified", "layout");
+ }
+ return true;
+}
+
+bool TParseContext::parseTessEvaluationShaderInputLayoutQualifier(
+ const TTypeQualifier &typeQualifier)
+{
+ ASSERT(typeQualifier.qualifier == EvqTessEvaluationIn);
+
+ const TLayoutQualifier &layoutQualifier = typeQualifier.layoutQualifier;
+
+ // Set mTessEvaluationShaderInputPrimitiveType if exists
+ if (layoutQualifier.tesPrimitiveType != EtetUndefined)
+ {
+ if (mTessEvaluationShaderInputPrimitiveType == EtetUndefined)
+ {
+ mTessEvaluationShaderInputPrimitiveType = layoutQualifier.tesPrimitiveType;
+ }
+ else
+ {
+ error(typeQualifier.line, "Duplicated primitive type declaration", "layout");
+ }
+ }
+ // Set mTessEvaluationShaderVertexSpacingType if exists
+ if (layoutQualifier.tesVertexSpacingType != EtetUndefined)
+ {
+ if (mTessEvaluationShaderInputVertexSpacingType == EtetUndefined)
+ {
+ mTessEvaluationShaderInputVertexSpacingType = layoutQualifier.tesVertexSpacingType;
+ }
+ else
+ {
+ error(typeQualifier.line, "Duplicated vertex spacing declaration", "layout");
+ }
+ }
+ // Set mTessEvaluationShaderInputOrderingType if exists
+ if (layoutQualifier.tesOrderingType != EtetUndefined)
+ {
+ if (mTessEvaluationShaderInputOrderingType == EtetUndefined)
+ {
+ mTessEvaluationShaderInputOrderingType = layoutQualifier.tesOrderingType;
+ }
+ else
+ {
+ error(typeQualifier.line, "Duplicated ordering declaration", "layout");
+ }
+ }
+ // Set mTessEvaluationShaderInputPointType if exists
+ if (layoutQualifier.tesPointType != EtetUndefined)
+ {
+ if (mTessEvaluationShaderInputPointType == EtetUndefined)
+ {
+ mTessEvaluationShaderInputPointType = layoutQualifier.tesPointType;
+ }
+ else
+ {
+ error(typeQualifier.line, "Duplicated point type declaration", "layout");
+ }
+ }
+
+ return true;
+}
+
+void TParseContext::parseGlobalLayoutQualifier(const TTypeQualifierBuilder &typeQualifierBuilder)
+{
+ TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(mDiagnostics);
+ const TLayoutQualifier layoutQualifier = typeQualifier.layoutQualifier;
+
+ 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, "Error during layout qualifier parsing.", "?");
+ return;
+ }
+
+ if (!layoutQualifier.isCombinationValid())
+ {
+ error(typeQualifier.line, "invalid layout qualifier combination", "layout");
+ return;
+ }
+
+ checkIndexIsNotSpecified(typeQualifier.line, layoutQualifier.index);
+
+ checkBindingIsNotSpecified(typeQualifier.line, layoutQualifier.binding);
+
+ checkMemoryQualifierIsNotSpecified(typeQualifier.memoryQualifier, typeQualifier.line);
+
+ checkInternalFormatIsNotSpecified(typeQualifier.line, layoutQualifier.imageInternalFormat);
+
+ checkYuvIsNotSpecified(typeQualifier.line, layoutQualifier.yuv);
+
+ checkOffsetIsNotSpecified(typeQualifier.line, layoutQualifier.offset);
+
+ checkStd430IsForShaderStorageBlock(typeQualifier.line, layoutQualifier.blockStorage,
+ typeQualifier.qualifier);
+
+ checkAdvancedBlendEquationsNotSpecified(
+ typeQualifier.line, layoutQualifier.advancedBlendEquations, typeQualifier.qualifier);
+
+ if (typeQualifier.qualifier != EvqFragmentIn)
+ {
+ checkEarlyFragmentTestsIsNotSpecified(typeQualifier.line,
+ layoutQualifier.earlyFragmentTests);
+ }
+
+ if (typeQualifier.qualifier == EvqComputeIn)
+ {
+ if (mComputeShaderLocalSizeDeclared &&
+ !layoutQualifier.isLocalSizeEqual(mComputeShaderLocalSize))
+ {
+ error(typeQualifier.line, "Work group size does not match the previous declaration",
+ "layout");
+ return;
+ }
+
+ 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(ImmutableString("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 reasonStream = sh::InitializeStream<std::stringstream>();
+ reasonStream << "invalid value: Value must be at least 1 and no greater than "
+ << maxComputeWorkGroupSizeValue;
+ const std::string &reason = reasonStream.str();
+
+ error(typeQualifier.line, reason.c_str(), getWorkGroupSizeString(i));
+ return;
+ }
+ }
+ }
+
+ mComputeShaderLocalSizeDeclared = true;
+ }
+ else if (typeQualifier.qualifier == EvqGeometryIn)
+ {
+ if (mShaderVersion < 310)
+ {
+ error(typeQualifier.line, "in type qualifier supported in GLSL ES 3.10 only", "layout");
+ return;
+ }
+
+ if (!parseGeometryShaderInputLayoutQualifier(typeQualifier))
+ {
+ return;
+ }
+ }
+ else if (typeQualifier.qualifier == EvqGeometryOut)
+ {
+ if (mShaderVersion < 310)
+ {
+ error(typeQualifier.line, "out type qualifier supported in GLSL ES 3.10 only",
+ "layout");
+ return;
+ }
+
+ if (!parseGeometryShaderOutputLayoutQualifier(typeQualifier))
+ {
+ return;
+ }
+ }
+ else if (anyMultiviewExtensionAvailable() && typeQualifier.qualifier == EvqVertexIn)
+ {
+ // This error is only specified in WebGL, but tightens unspecified behavior in the native
+ // specification.
+ if (mNumViews != -1 && layoutQualifier.numViews != mNumViews)
+ {
+ error(typeQualifier.line, "Number of views does not match the previous declaration",
+ "layout");
+ return;
+ }
+
+ if (layoutQualifier.numViews == -1)
+ {
+ error(typeQualifier.line, "No num_views specified", "layout");
+ return;
+ }
+
+ if (layoutQualifier.numViews > mMaxNumViews)
+ {
+ error(typeQualifier.line, "num_views greater than the value of GL_MAX_VIEWS_OVR",
+ "layout");
+ return;
+ }
+
+ mNumViews = layoutQualifier.numViews;
+ }
+ else if (typeQualifier.qualifier == EvqFragmentIn)
+ {
+ if (mShaderVersion < 310)
+ {
+ error(typeQualifier.line,
+ "in type qualifier without variable declaration supported in GLSL ES 3.10 and "
+ "after",
+ "layout");
+ return;
+ }
+
+ if (!layoutQualifier.earlyFragmentTests)
+ {
+ error(typeQualifier.line,
+ "only early_fragment_tests is allowed as layout qualifier when not declaring a "
+ "variable",
+ "layout");
+ return;
+ }
+
+ mEarlyFragmentTestsSpecified = true;
+ }
+ else if (typeQualifier.qualifier == EvqFragmentOut)
+ {
+ if (mShaderVersion < 320 && !isExtensionEnabled(TExtension::KHR_blend_equation_advanced))
+ {
+ error(typeQualifier.line,
+ "out type qualifier without variable declaration is supported in GLSL ES 3.20,"
+ " or if GL_KHR_blend_equation_advanced is enabled",
+ "layout");
+ return;
+ }
+
+ if (!layoutQualifier.advancedBlendEquations.any())
+ {
+ error(typeQualifier.line,
+ "only blend equations are allowed as layout qualifier when not declaring a "
+ "variable",
+ "layout");
+ return;
+ }
+
+ mAdvancedBlendEquations |= layoutQualifier.advancedBlendEquations;
+ }
+ else if (typeQualifier.qualifier == EvqTessControlOut)
+ {
+ if (mShaderVersion < 310)
+ {
+ error(typeQualifier.line, "out type qualifier supported in GLSL ES 3.10 and after",
+ "layout");
+ return;
+ }
+
+ if (!parseTessControlShaderOutputLayoutQualifier(typeQualifier))
+ {
+ return;
+ }
+ }
+ else if (typeQualifier.qualifier == EvqTessEvaluationIn)
+ {
+ if (mShaderVersion < 310)
+ {
+ error(typeQualifier.line, "in type qualifier supported in GLSL ES 3.10 and after",
+ "layout");
+ return;
+ }
+
+ if (!parseTessEvaluationShaderInputLayoutQualifier(typeQualifier))
+ {
+ return;
+ }
+ }
+ else
+ {
+ if (!checkWorkGroupSizeIsNotSpecified(typeQualifier.line, layoutQualifier))
+ {
+ return;
+ }
+
+ if (typeQualifier.qualifier != EvqUniform && typeQualifier.qualifier != EvqBuffer)
+ {
+ error(typeQualifier.line, "invalid qualifier: global layout can only be set for blocks",
+ getQualifierString(typeQualifier.qualifier));
+ return;
+ }
+
+ if (mShaderVersion < 300)
+ {
+ error(typeQualifier.line, "layout qualifiers supported in GLSL ES 3.00 and after",
+ "layout");
+ return;
+ }
+
+ checkLocationIsNotSpecified(typeQualifier.line, layoutQualifier);
+
+ if (layoutQualifier.matrixPacking != EmpUnspecified)
+ {
+ if (typeQualifier.qualifier == EvqUniform)
+ {
+ mDefaultUniformMatrixPacking = layoutQualifier.matrixPacking;
+ }
+ else if (typeQualifier.qualifier == EvqBuffer)
+ {
+ mDefaultBufferMatrixPacking = layoutQualifier.matrixPacking;
+ }
+ }
+
+ if (layoutQualifier.blockStorage != EbsUnspecified)
+ {
+ if (typeQualifier.qualifier == EvqUniform)
+ {
+ mDefaultUniformBlockStorage = layoutQualifier.blockStorage;
+ }
+ else if (typeQualifier.qualifier == EvqBuffer)
+ {
+ mDefaultBufferBlockStorage = layoutQualifier.blockStorage;
+ }
+ }
+ }
+}
+
+TIntermFunctionPrototype *TParseContext::createPrototypeNodeFromFunction(
+ const TFunction &function,
+ const TSourceLoc &location,
+ bool insertParametersToSymbolTable)
+{
+ checkIsNotReserved(location, function.name());
+
+ TIntermFunctionPrototype *prototype = new TIntermFunctionPrototype(&function);
+ prototype->setLine(location);
+
+ for (size_t i = 0; i < function.getParamCount(); i++)
+ {
+ const TVariable *param = function.getParam(i);
+
+ // If the parameter has no name, it's not an error, just don't add it to symbol table (could
+ // be used for unused args).
+ if (param->symbolType() != SymbolType::Empty)
+ {
+ if (insertParametersToSymbolTable)
+ {
+ if (!symbolTable.declare(const_cast<TVariable *>(param)))
+ {
+ error(location, "redefinition", param->name());
+ }
+ }
+ // Unsized type of a named parameter should have already been checked and sanitized.
+ ASSERT(!param->getType().isUnsizedArray());
+ }
+ else
+ {
+ if (param->getType().isUnsizedArray())
+ {
+ error(location, "function parameter array must be sized at compile time", "[]");
+ // We don't need to size the arrays since the parameter is unnamed and hence
+ // inaccessible.
+ }
+ }
+ }
+ return prototype;
+}
+
+TIntermFunctionPrototype *TParseContext::addFunctionPrototypeDeclaration(
+ const TFunction &parsedFunction,
+ const TSourceLoc &location)
+{
+ // Note: function found from the symbol table could be the same as parsedFunction if this is the
+ // first declaration. Either way the instance in the symbol table is used to track whether the
+ // function is declared multiple times.
+ bool hadPrototypeDeclaration = false;
+ const TFunction *function = symbolTable.markFunctionHasPrototypeDeclaration(
+ parsedFunction.getMangledName(), &hadPrototypeDeclaration);
+
+ if (hadPrototypeDeclaration && mShaderVersion == 100)
+ {
+ // 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");
+ }
+
+ TIntermFunctionPrototype *prototype =
+ createPrototypeNodeFromFunction(*function, location, false);
+
+ symbolTable.pop();
+
+ if (!symbolTable.atGlobalLevel())
+ {
+ // ESSL 3.00.4 section 4.2.4.
+ error(location, "local function prototype declarations are not allowed", "function");
+ }
+
+ return prototype;
+}
+
+TIntermFunctionDefinition *TParseContext::addFunctionDefinition(
+ TIntermFunctionPrototype *functionPrototype,
+ TIntermBlock *functionBody,
+ const TSourceLoc &location)
+{
+ // Undo push at end of parseFunctionDefinitionHeader() below for ESSL1.00 case
+ if (mFunctionBodyNewScope)
+ {
+ mFunctionBodyNewScope = false;
+ symbolTable.pop();
+ }
+
+ // Check that non-void functions have at least one return statement.
+ if (mCurrentFunctionType->getBasicType() != EbtVoid && !mFunctionReturnsValue)
+ {
+ error(location,
+ "function does not return a value:", functionPrototype->getFunction()->name());
+ }
+
+ if (functionBody == nullptr)
+ {
+ functionBody = new TIntermBlock();
+ functionBody->setLine(location);
+ }
+ TIntermFunctionDefinition *functionNode =
+ new TIntermFunctionDefinition(functionPrototype, functionBody);
+ functionNode->setLine(location);
+
+ symbolTable.pop();
+ return functionNode;
+}
+
+void TParseContext::parseFunctionDefinitionHeader(const TSourceLoc &location,
+ const TFunction *function,
+ TIntermFunctionPrototype **prototypeOut)
+{
+ ASSERT(function);
+
+ bool wasDefined = false;
+ function = symbolTable.setFunctionParameterNamesFromDefinition(function, &wasDefined);
+ if (wasDefined)
+ {
+ error(location, "function already has a body", function->name());
+ }
+
+ // Remember the return type for later checking for return statements.
+ mCurrentFunctionType = &(function->getReturnType());
+ mFunctionReturnsValue = false;
+
+ *prototypeOut = createPrototypeNodeFromFunction(*function, location, true);
+ setLoopNestingLevel(0);
+
+ // ESSL 1.00 spec allows for variable in function body to redefine parameter
+ if (IsSpecWithFunctionBodyNewScope(mShaderSpec, mShaderVersion))
+ {
+ mFunctionBodyNewScope = true;
+ symbolTable.push();
+ }
+}
+
+TFunction *TParseContext::parseFunctionDeclarator(const TSourceLoc &location, TFunction *function)
+{
+ //
+ // We don't know at this point whether this is a function definition or a prototype.
+ // The definition production code will check for redefinitions.
+ // In the case of ESSL 1.00 the prototype production code will also check for redeclarations.
+ //
+
+ for (size_t i = 0u; i < function->getParamCount(); ++i)
+ {
+ const TVariable *param = function->getParam(i);
+ const TType &paramType = param->getType();
+
+ if (paramType.isStructSpecifier())
+ {
+ // ESSL 3.00.6 section 12.10.
+ error(location, "Function parameter type cannot be a structure definition",
+ function->name());
+ }
+
+ checkPrecisionSpecified(location, paramType.getPrecision(), paramType.getBasicType());
+ }
+
+ if (getShaderVersion() >= 300)
+ {
+ if (symbolTable.isUnmangledBuiltInName(function->name(), getShaderVersion(),
+ extensionBehavior()))
+ {
+ // With ESSL 3.00 and above, names of built-in functions cannot be redeclared as
+ // functions. Therefore overloading or redefining builtin functions is an error.
+ error(location, "Name of a built-in function cannot be redeclared as function",
+ function->name());
+ }
+ }
+ else
+ {
+ // ESSL 1.00.17 section 4.2.6: built-ins can be overloaded but not redefined. We assume that
+ // this applies to redeclarations as well.
+ const TSymbol *builtIn =
+ symbolTable.findBuiltIn(function->getMangledName(), getShaderVersion());
+ if (builtIn)
+ {
+ error(location, "built-in functions cannot be redefined", function->name());
+ }
+ }
+
+ // Return types and parameter qualifiers must match in all redeclarations, so those are checked
+ // here.
+ const TFunction *prevDec =
+ static_cast<const TFunction *>(symbolTable.findGlobal(function->getMangledName()));
+ if (prevDec)
+ {
+ if (prevDec->getReturnType() != function->getReturnType())
+ {
+ error(location, "function must have the same return type in all of its declarations",
+ function->getReturnType().getBasicString());
+ }
+ for (size_t i = 0; i < prevDec->getParamCount(); ++i)
+ {
+ if (prevDec->getParam(i)->getType().getQualifier() !=
+ function->getParam(i)->getType().getQualifier())
+ {
+ error(location,
+ "function must have the same parameter qualifiers in all of its declarations",
+ function->getParam(i)->getType().getQualifierString());
+ }
+ }
+ }
+
+ // Check for previously declared variables using the same name.
+ const TSymbol *prevSym = symbolTable.find(function->name(), getShaderVersion());
+ bool insertUnmangledName = true;
+ if (prevSym)
+ {
+ if (!prevSym->isFunction())
+ {
+ error(location, "redefinition of a function", function->name());
+ }
+ insertUnmangledName = false;
+ }
+ // Parsing is at the inner scope level of the function's arguments and body statement at this
+ // point, but declareUserDefinedFunction takes care of declaring the function at the global
+ // scope.
+ symbolTable.declareUserDefinedFunction(function, insertUnmangledName);
+
+ // Raise error message if main function takes any parameters or return anything other than void
+ if (function->isMain())
+ {
+ if (function->getParamCount() > 0)
+ {
+ error(location, "function cannot take any parameter(s)", "main");
+ }
+ if (function->getReturnType().getBasicType() != EbtVoid)
+ {
+ error(location, "main function cannot return a value",
+ function->getReturnType().getBasicString());
+ }
+ }
+
+ mDeclaringMain = function->isMain();
+
+ //
+ // If this is a redeclaration, it could also be a definition, in which case, we want to use the
+ // variable names from this one, and not the one that's
+ // being redeclared. So, pass back up this declaration, not the one in the symbol table.
+ //
+ return function;
+}
+
+TFunction *TParseContext::parseFunctionHeader(const TPublicType &type,
+ const ImmutableString &name,
+ const TSourceLoc &location)
+{
+ if (type.qualifier != EvqGlobal && type.qualifier != EvqTemporary)
+ {
+ error(location, "no qualifiers allowed for function return",
+ getQualifierString(type.qualifier));
+ }
+ if (!type.layoutQualifier.isEmpty())
+ {
+ error(location, "no qualifiers allowed for function return", "layout");
+ }
+ // make sure an opaque type is not involved as well...
+ std::string reason(getBasicString(type.getBasicType()));
+ reason += "s can't be function return values";
+ checkIsNotOpaqueType(location, type.typeSpecifierNonArray, reason.c_str());
+ if (mShaderVersion < 300)
+ {
+ // Array return values are forbidden, but there's also no valid syntax for declaring array
+ // return values in ESSL 1.00.
+ ASSERT(!type.isArray() || mDiagnostics->numErrors() > 0);
+
+ if (type.isStructureContainingArrays())
+ {
+ // ESSL 1.00.17 section 6.1 Function Definitions
+ TInfoSinkBase typeString;
+ typeString << TType(type);
+ error(location, "structures containing arrays can't be function return values",
+ typeString.c_str());
+ }
+ }
+
+ // Add the function as a prototype after parsing it (we do not support recursion)
+ return new TFunction(&symbolTable, name, SymbolType::UserDefined, new TType(type), false);
+}
+
+TFunctionLookup *TParseContext::addNonConstructorFunc(const ImmutableString &name,
+ const TSymbol *symbol)
+{
+ return TFunctionLookup::CreateFunctionCall(name, symbol);
+}
+
+TFunctionLookup *TParseContext::addConstructorFunc(const TPublicType &publicType)
+{
+ if (mShaderVersion < 300 && publicType.isArray())
+ {
+ error(publicType.getLine(), "array constructor supported in GLSL ES 3.00 and above only",
+ "[]");
+ }
+ if (publicType.isStructSpecifier())
+ {
+ error(publicType.getLine(), "constructor can't be a structure definition",
+ getBasicString(publicType.getBasicType()));
+ }
+
+ TType *type = new TType(publicType);
+ if (!type->canBeConstructed())
+ {
+ error(publicType.getLine(), "cannot construct this type",
+ getBasicString(publicType.getBasicType()));
+ type->setBasicType(EbtFloat);
+ }
+ return TFunctionLookup::CreateConstructor(type);
+}
+
+void TParseContext::checkIsNotUnsizedArray(const TSourceLoc &line,
+ const char *errorMessage,
+ const ImmutableString &token,
+ TType *arrayType)
+{
+ if (arrayType->isUnsizedArray())
+ {
+ error(line, errorMessage, token);
+ arrayType->sizeUnsizedArrays(TSpan<const unsigned int>());
+ }
+}
+
+TParameter TParseContext::parseParameterDeclarator(TType *type,
+ const ImmutableString &name,
+ const TSourceLoc &nameLoc)
+{
+ ASSERT(type);
+ checkIsNotUnsizedArray(nameLoc, "function parameter array must specify a size", name, type);
+ if (type->getBasicType() == EbtVoid)
+ {
+ error(nameLoc, "illegal use of type 'void'", name);
+ }
+ checkIsNotReserved(nameLoc, name);
+ TParameter param = {name.data(), type};
+ return param;
+}
+
+TParameter TParseContext::parseParameterDeclarator(const TPublicType &publicType,
+ const ImmutableString &name,
+ const TSourceLoc &nameLoc)
+{
+ TType *type = new TType(publicType);
+ return parseParameterDeclarator(type, name, nameLoc);
+}
+
+TParameter TParseContext::parseParameterArrayDeclarator(const ImmutableString &name,
+ const TSourceLoc &nameLoc,
+ const TVector<unsigned int> &arraySizes,
+ const TSourceLoc &arrayLoc,
+ TPublicType *elementType)
+{
+ checkArrayElementIsNotArray(arrayLoc, *elementType);
+ TType *arrayType = new TType(*elementType);
+ arrayType->makeArrays(arraySizes);
+ return parseParameterDeclarator(arrayType, name, nameLoc);
+}
+
+bool TParseContext::checkUnsizedArrayConstructorArgumentDimensionality(
+ const TIntermSequence &arguments,
+ TType type,
+ const TSourceLoc &line)
+{
+ if (arguments.empty())
+ {
+ error(line, "implicitly sized array constructor must have at least one argument", "[]");
+ return false;
+ }
+ for (TIntermNode *arg : arguments)
+ {
+ const TIntermTyped *element = arg->getAsTyped();
+ ASSERT(element);
+ size_t dimensionalityFromElement = element->getType().getNumArraySizes() + 1u;
+ if (dimensionalityFromElement > type.getNumArraySizes())
+ {
+ error(line, "constructing from a non-dereferenced array", "constructor");
+ return false;
+ }
+ else if (dimensionalityFromElement < type.getNumArraySizes())
+ {
+ if (dimensionalityFromElement == 1u)
+ {
+ error(line, "implicitly sized array of arrays constructor argument is not an array",
+ "constructor");
+ }
+ else
+ {
+ error(line,
+ "implicitly sized array of arrays constructor argument dimensionality is too "
+ "low",
+ "constructor");
+ }
+ return false;
+ }
+ }
+ return true;
+}
+
+// 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 a node to add to the tree regardless of if an error was generated or not.
+//
+TIntermTyped *TParseContext::addConstructor(TFunctionLookup *fnCall, const TSourceLoc &line)
+{
+ TType type = fnCall->constructorType();
+ TIntermSequence &arguments = fnCall->arguments();
+ if (type.isUnsizedArray())
+ {
+ if (!checkUnsizedArrayConstructorArgumentDimensionality(arguments, type, line))
+ {
+ type.sizeUnsizedArrays(TSpan<const unsigned int>());
+ return CreateZeroNode(type);
+ }
+ TIntermTyped *firstElement = arguments.at(0)->getAsTyped();
+ ASSERT(firstElement);
+ if (type.getOutermostArraySize() == 0u)
+ {
+ type.sizeOutermostUnsizedArray(static_cast<unsigned int>(arguments.size()));
+ }
+ for (size_t i = 0; i < firstElement->getType().getNumArraySizes(); ++i)
+ {
+ if (type.getArraySizes()[i] == 0u)
+ {
+ type.setArraySize(i, firstElement->getType().getArraySizes()[i]);
+ }
+ }
+ ASSERT(!type.isUnsizedArray());
+ }
+
+ if (!checkConstructorArguments(line, arguments, type))
+ {
+ return CreateZeroNode(type);
+ }
+
+ TIntermAggregate *constructorNode = TIntermAggregate::CreateConstructor(type, &arguments);
+ constructorNode->setLine(line);
+
+ return constructorNode->fold(mDiagnostics);
+}
+
+//
+// Interface/uniform blocks
+TIntermDeclaration *TParseContext::addInterfaceBlock(
+ const TTypeQualifierBuilder &typeQualifierBuilder,
+ const TSourceLoc &nameLine,
+ const ImmutableString &blockName,
+ TFieldList *fieldList,
+ const ImmutableString &instanceName,
+ const TSourceLoc &instanceLine,
+ const TVector<unsigned int> *arraySizes,
+ const TSourceLoc &arraySizesLine)
+{
+ const bool isGLPerVertex = blockName == "gl_PerVertex";
+ // gl_PerVertex is allowed to be redefined and therefore not reserved
+ if (!isGLPerVertex)
+ {
+ checkIsNotReserved(nameLine, blockName);
+ }
+
+ TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(mDiagnostics);
+
+ const bool isUniformOrBuffer =
+ typeQualifier.qualifier == EvqUniform || typeQualifier.qualifier == EvqBuffer;
+ const bool isShaderIoBlock = IsShaderIoBlock(typeQualifier.qualifier);
+
+ if (mShaderVersion < 310 && typeQualifier.qualifier != EvqUniform)
+ {
+ error(typeQualifier.line,
+ "invalid qualifier: interface blocks must be uniform in version lower than GLSL ES "
+ "3.10",
+ getQualifierString(typeQualifier.qualifier));
+ }
+ else if (typeQualifier.qualifier == EvqPatchOut)
+ {
+ if ((!isExtensionEnabled(TExtension::EXT_tessellation_shader) && mShaderVersion < 320) ||
+ mShaderType != GL_TESS_CONTROL_SHADER)
+ {
+ error(typeQualifier.line,
+ "invalid qualifier: 'patch out' requires a tessellation control shader",
+ getQualifierString(typeQualifier.qualifier));
+ }
+ }
+ else if (typeQualifier.qualifier == EvqPatchIn)
+ {
+ if ((!isExtensionEnabled(TExtension::EXT_tessellation_shader) && mShaderVersion < 320) ||
+ mShaderType != GL_TESS_EVALUATION_SHADER)
+ {
+ error(typeQualifier.line,
+ "invalid qualifier: 'patch in' requires a tessellation evaluation shader",
+ getQualifierString(typeQualifier.qualifier));
+ }
+ }
+ else if (typeQualifier.qualifier != EvqUniform && typeQualifier.qualifier != EvqBuffer)
+ {
+ if (isShaderIoBlock)
+ {
+ if (!isExtensionEnabled(TExtension::OES_shader_io_blocks) &&
+ !isExtensionEnabled(TExtension::EXT_shader_io_blocks) &&
+ !isExtensionEnabled(TExtension::OES_geometry_shader) &&
+ !isExtensionEnabled(TExtension::EXT_geometry_shader) && mShaderVersion < 320)
+ {
+ error(typeQualifier.line,
+ "invalid qualifier: shader IO blocks need shader io block extension",
+ getQualifierString(typeQualifier.qualifier));
+ }
+
+ // Both inputs and outputs of tessellation control shaders must be arrays.
+ // For tessellation evaluation shaders, only inputs must necessarily be arrays.
+ const bool isTCS = mShaderType == GL_TESS_CONTROL_SHADER;
+ const bool isTESIn =
+ mShaderType == GL_TESS_EVALUATION_SHADER && IsShaderIn(typeQualifier.qualifier);
+ if (arraySizes == nullptr && (isTCS || isTESIn))
+ {
+ error(typeQualifier.line, "type must be an array", blockName);
+ }
+ }
+ else
+ {
+ error(typeQualifier.line,
+ "invalid qualifier: interface blocks must be uniform or buffer",
+ getQualifierString(typeQualifier.qualifier));
+ }
+ }
+
+ if (typeQualifier.invariant)
+ {
+ error(typeQualifier.line, "invalid qualifier on interface block", "invariant");
+ }
+
+ if (typeQualifier.qualifier != EvqBuffer)
+ {
+ checkMemoryQualifierIsNotSpecified(typeQualifier.memoryQualifier, typeQualifier.line);
+ }
+
+ // Verify array sizes
+ if (arraySizes)
+ {
+ if (isUniformOrBuffer)
+ {
+ if (arraySizes->size() == 0)
+ {
+ error(arraySizesLine, "unsized arrays are not allowed with interface blocks", "");
+ }
+ if (arraySizes->size() > 1)
+ {
+ error(arraySizesLine, "array of arrays are not allowed with interface blocks", "");
+ }
+ }
+ else if (isShaderIoBlock)
+ {
+ size_t arrayDimensions = arraySizes->size();
+
+ // Geometry shader inputs have a level arrayness that must be ignored.
+ if (mShaderType == GL_GEOMETRY_SHADER_EXT && IsVaryingIn(typeQualifier.qualifier))
+ {
+ ASSERT(arrayDimensions > 0);
+ --arrayDimensions;
+
+ // Validate that the array size of input matches the geometry layout
+ // declaration, if not automatic (specified as []).
+ const unsigned int geometryDim = arraySizes->back();
+ if (geometryDim > 0 && geometryDim != mGeometryInputArraySize)
+ {
+ error(arraySizesLine,
+ "geometry shader input block array size inconsistent "
+ "with primitive",
+ "");
+ }
+ }
+
+ if (arrayDimensions > 1)
+ {
+ error(arraySizesLine, "array of arrays are not allowed with I/O blocks", "");
+ }
+ }
+ }
+ else if (isShaderIoBlock && mShaderType == GL_GEOMETRY_SHADER_EXT &&
+ IsVaryingIn(typeQualifier.qualifier))
+ {
+ error(arraySizesLine, "geometry shader input blocks must be an array", "");
+ }
+
+ checkIndexIsNotSpecified(typeQualifier.line, typeQualifier.layoutQualifier.index);
+
+ if (mShaderVersion < 310)
+ {
+ checkBindingIsNotSpecified(typeQualifier.line, typeQualifier.layoutQualifier.binding);
+ }
+ else
+ {
+ unsigned int arraySize =
+ arraySizes == nullptr || arraySizes->empty() ? 0 : (*arraySizes)[0];
+ checkBlockBindingIsValid(typeQualifier.line, typeQualifier.qualifier,
+ typeQualifier.layoutQualifier.binding, arraySize);
+ }
+
+ checkYuvIsNotSpecified(typeQualifier.line, typeQualifier.layoutQualifier.yuv);
+ checkEarlyFragmentTestsIsNotSpecified(typeQualifier.line,
+ typeQualifier.layoutQualifier.earlyFragmentTests);
+ checkNoncoherentIsNotSpecified(typeQualifier.line, typeQualifier.layoutQualifier.noncoherent);
+
+ TLayoutQualifier blockLayoutQualifier = typeQualifier.layoutQualifier;
+ if (!IsShaderIoBlock(typeQualifier.qualifier) && typeQualifier.qualifier != EvqPatchIn &&
+ typeQualifier.qualifier != EvqPatchOut)
+ {
+ checkLocationIsNotSpecified(typeQualifier.line, blockLayoutQualifier);
+ }
+ checkStd430IsForShaderStorageBlock(typeQualifier.line, blockLayoutQualifier.blockStorage,
+ typeQualifier.qualifier);
+
+ if (blockLayoutQualifier.matrixPacking == EmpUnspecified)
+ {
+ if (typeQualifier.qualifier == EvqUniform)
+ {
+ blockLayoutQualifier.matrixPacking = mDefaultUniformMatrixPacking;
+ }
+ else if (typeQualifier.qualifier == EvqBuffer)
+ {
+ blockLayoutQualifier.matrixPacking = mDefaultBufferMatrixPacking;
+ }
+ }
+
+ if (blockLayoutQualifier.blockStorage == EbsUnspecified)
+ {
+ if (typeQualifier.qualifier == EvqUniform)
+ {
+ blockLayoutQualifier.blockStorage = mDefaultUniformBlockStorage;
+ }
+ else if (typeQualifier.qualifier == EvqBuffer)
+ {
+ blockLayoutQualifier.blockStorage = mDefaultBufferBlockStorage;
+ }
+ }
+
+ checkWorkGroupSizeIsNotSpecified(nameLine, blockLayoutQualifier);
+
+ checkInternalFormatIsNotSpecified(nameLine, blockLayoutQualifier.imageInternalFormat);
+
+ // check for sampler types and apply layout qualifiers
+ for (size_t memberIndex = 0; memberIndex < fieldList->size(); ++memberIndex)
+ {
+ TField *field = (*fieldList)[memberIndex];
+ TType *fieldType = field->type();
+ if (IsOpaqueType(fieldType->getBasicType()))
+ {
+ std::string reason("unsupported type - ");
+ reason += fieldType->getBasicString();
+ reason += " types are not allowed in interface blocks";
+ error(field->line(), reason.c_str(), fieldType->getBasicString());
+ }
+
+ const TQualifier qualifier = fieldType->getQualifier();
+ switch (qualifier)
+ {
+ case EvqGlobal:
+ break;
+ case EvqUniform:
+ if (typeQualifier.qualifier == EvqBuffer)
+ {
+ error(field->line(), "invalid qualifier on shader storage block member",
+ getQualifierString(qualifier));
+ }
+ break;
+ case EvqBuffer:
+ if (typeQualifier.qualifier == EvqUniform)
+ {
+ error(field->line(), "invalid qualifier on uniform block member",
+ getQualifierString(qualifier));
+ }
+ break;
+ // a member variable in io block may have different interpolation.
+ case EvqFlatIn:
+ case EvqFlatOut:
+ case EvqNoPerspectiveIn:
+ case EvqNoPerspectiveOut:
+ case EvqSmoothIn:
+ case EvqSmoothOut:
+ case EvqCentroidIn:
+ case EvqCentroidOut:
+ break;
+ // a member variable can have an incomplete qualifier because shader io block has either
+ // in or out.
+ case EvqSmooth:
+ case EvqFlat:
+ case EvqNoPerspective:
+ case EvqCentroid:
+ case EvqGeometryIn:
+ case EvqGeometryOut:
+ if (!IsShaderIoBlock(typeQualifier.qualifier) &&
+ typeQualifier.qualifier != EvqPatchIn &&
+ typeQualifier.qualifier != EvqPatchOut &&
+ typeQualifier.qualifier != EvqGeometryIn &&
+ typeQualifier.qualifier != EvqGeometryOut)
+ {
+ error(field->line(), "invalid qualifier on interface block member",
+ getQualifierString(qualifier));
+ }
+ break;
+ default:
+ error(field->line(), "invalid qualifier on interface block member",
+ getQualifierString(qualifier));
+ break;
+ }
+
+ // On interface block members, invariant is only applicable to output I/O blocks.
+ const bool isOutputShaderIoBlock = isShaderIoBlock && IsShaderOut(typeQualifier.qualifier);
+ if (fieldType->isInvariant() && !isOutputShaderIoBlock)
+ {
+ error(field->line(), "invalid qualifier on interface block member", "invariant");
+ }
+
+ // check layout qualifiers
+ TLayoutQualifier fieldLayoutQualifier = fieldType->getLayoutQualifier();
+ checkIndexIsNotSpecified(field->line(), fieldLayoutQualifier.index);
+ checkBindingIsNotSpecified(field->line(), fieldLayoutQualifier.binding);
+
+ if (fieldLayoutQualifier.blockStorage != EbsUnspecified)
+ {
+ error(field->line(), "invalid layout qualifier: cannot be used here",
+ getBlockStorageString(fieldLayoutQualifier.blockStorage));
+ }
+
+ if (fieldLayoutQualifier.matrixPacking == EmpUnspecified)
+ {
+ fieldLayoutQualifier.matrixPacking = blockLayoutQualifier.matrixPacking;
+ }
+ else if (!fieldType->isMatrix() && fieldType->getBasicType() != EbtStruct)
+ {
+ warning(field->line(),
+ "extraneous layout qualifier: only has an effect on matrix types",
+ getMatrixPackingString(fieldLayoutQualifier.matrixPacking));
+ }
+
+ fieldType->setLayoutQualifier(fieldLayoutQualifier);
+
+ if (mShaderVersion < 310 || memberIndex != fieldList->size() - 1u ||
+ typeQualifier.qualifier != EvqBuffer)
+ {
+ // ESSL 3.10 spec section 4.1.9 allows for runtime-sized arrays.
+ checkIsNotUnsizedArray(field->line(),
+ "array members of interface blocks must specify a size",
+ field->name(), field->type());
+ }
+
+ if (typeQualifier.qualifier == EvqBuffer)
+ {
+ // set memory qualifiers
+ // GLSL ES 3.10 session 4.9 [Memory Access Qualifiers]. When a block declaration is
+ // qualified with a memory qualifier, it is as if all of its members were declared with
+ // the same memory qualifier.
+ const TMemoryQualifier &blockMemoryQualifier = typeQualifier.memoryQualifier;
+ TMemoryQualifier fieldMemoryQualifier = fieldType->getMemoryQualifier();
+ fieldMemoryQualifier.readonly |= blockMemoryQualifier.readonly;
+ fieldMemoryQualifier.writeonly |= blockMemoryQualifier.writeonly;
+ fieldMemoryQualifier.coherent |= blockMemoryQualifier.coherent;
+ fieldMemoryQualifier.restrictQualifier |= blockMemoryQualifier.restrictQualifier;
+ fieldMemoryQualifier.volatileQualifier |= blockMemoryQualifier.volatileQualifier;
+ // TODO(jiajia.qin@intel.com): Decide whether if readonly and writeonly buffer variable
+ // is legal. See bug https://github.com/KhronosGroup/OpenGL-API/issues/7
+ fieldType->setMemoryQualifier(fieldMemoryQualifier);
+ }
+ }
+
+ SymbolType instanceSymbolType = SymbolType::UserDefined;
+ if (isGLPerVertex)
+ {
+ instanceSymbolType = SymbolType::BuiltIn;
+ }
+ TInterfaceBlock *interfaceBlock = new TInterfaceBlock(&symbolTable, blockName, fieldList,
+ blockLayoutQualifier, instanceSymbolType);
+ if (!symbolTable.declare(interfaceBlock) && isUniformOrBuffer)
+ {
+ error(nameLine, "redefinition of an interface block name", blockName);
+ }
+
+ TType *interfaceBlockType =
+ new TType(interfaceBlock, typeQualifier.qualifier, blockLayoutQualifier);
+ if (arraySizes)
+ {
+ interfaceBlockType->makeArrays(*arraySizes);
+
+ checkGeometryShaderInputAndSetArraySize(instanceLine, instanceName, interfaceBlockType);
+ checkTessellationShaderUnsizedArraysAndSetSize(instanceLine, instanceName,
+ interfaceBlockType);
+ }
+
+ // The instance variable gets created to refer to the interface block type from the AST
+ // regardless of if there's an instance name. It's created as an empty symbol if there is no
+ // instance name.
+ TVariable *instanceVariable =
+ new TVariable(&symbolTable, instanceName, interfaceBlockType,
+ instanceName.empty() ? SymbolType::Empty : SymbolType::UserDefined);
+
+ if (instanceVariable->symbolType() == SymbolType::Empty)
+ {
+ // define symbols for the members of the interface block
+ for (size_t memberIndex = 0; memberIndex < fieldList->size(); ++memberIndex)
+ {
+ TField *field = (*fieldList)[memberIndex];
+ TType *fieldType = new TType(*field->type());
+
+ // set parent pointer of the field variable
+ fieldType->setInterfaceBlockField(interfaceBlock, memberIndex);
+
+ fieldType->setQualifier(typeQualifier.qualifier);
+
+ SymbolType symbolType = SymbolType::UserDefined;
+ if (field->name() == "gl_Position" || field->name() == "gl_PointSize" ||
+ field->name() == "gl_ClipDistance" || field->name() == "gl_CullDistance")
+ {
+ // These builtins can be redifined only when used within a redefiend gl_PerVertex
+ // block
+ if (interfaceBlock->name() != "gl_PerVertex")
+ {
+ error(field->line(), "redefinition in an invalid interface block",
+ field->name());
+ }
+ symbolType = SymbolType::BuiltIn;
+ }
+ TVariable *fieldVariable =
+ new TVariable(&symbolTable, field->name(), fieldType, symbolType);
+ if (!symbolTable.declare(fieldVariable))
+ {
+ error(field->line(), "redefinition of an interface block member name",
+ field->name());
+ }
+ }
+ }
+ else
+ {
+ checkIsNotReserved(instanceLine, instanceName);
+
+ // add a symbol for this interface block
+ if (!symbolTable.declare(instanceVariable))
+ {
+ error(instanceLine, "redefinition of an interface block instance name", instanceName);
+ }
+ }
+
+ TIntermSymbol *blockSymbol = new TIntermSymbol(instanceVariable);
+ blockSymbol->setLine(typeQualifier.line);
+ TIntermDeclaration *declaration = new TIntermDeclaration();
+ declaration->appendDeclarator(blockSymbol);
+ declaration->setLine(nameLine);
+
+ exitStructDeclaration();
+ return declaration;
+}
+
+void TParseContext::enterStructDeclaration(const TSourceLoc &line,
+ const ImmutableString &identifier)
+{
+ ++mStructNestingLevel;
+
+ // Embedded structure definitions are not supported per GLSL ES spec.
+ // ESSL 1.00.17 section 10.9. ESSL 3.00.6 section 12.11.
+ if (mStructNestingLevel > 1)
+ {
+ error(line, "Embedded struct definitions are not allowed", "struct");
+ }
+}
+
+void TParseContext::exitStructDeclaration()
+{
+ --mStructNestingLevel;
+}
+
+void TParseContext::checkIsBelowStructNestingLimit(const TSourceLoc &line, const TField &field)
+{
+ if (!sh::IsWebGLBasedSpec(mShaderSpec))
+ {
+ return;
+ }
+
+ if (field.type()->getBasicType() != EbtStruct)
+ {
+ return;
+ }
+
+ // We're already inside a structure definition at this point, so add
+ // one to the field's struct nesting.
+ if (1 + field.type()->getDeepestStructNesting() > kWebGLMaxStructNesting)
+ {
+ std::stringstream reasonStream = sh::InitializeStream<std::stringstream>();
+ if (field.type()->getStruct()->symbolType() == SymbolType::Empty)
+ {
+ // This may happen in case there are nested struct definitions. While they are also
+ // invalid GLSL, they don't cause a syntax error.
+ reasonStream << "Struct nesting";
+ }
+ else
+ {
+ reasonStream << "Reference of struct type " << field.type()->getStruct()->name();
+ }
+ reasonStream << " exceeds maximum allowed nesting level of " << kWebGLMaxStructNesting;
+ std::string reason = reasonStream.str();
+ error(line, reason.c_str(), field.name());
+ return;
+ }
+}
+
+//
+// Parse an array index expression
+//
+TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression,
+ const TSourceLoc &location,
+ TIntermTyped *indexExpression)
+{
+ if (!baseExpression->isArray() && !baseExpression->isMatrix() && !baseExpression->isVector())
+ {
+ if (baseExpression->getAsSymbolNode())
+ {
+ error(location, " left of '[' is not of type array, matrix, or vector ",
+ baseExpression->getAsSymbolNode()->getName());
+ }
+ else
+ {
+ error(location, " left of '[' is not of type array, matrix, or vector ", "expression");
+ }
+
+ return CreateZeroNode(TType(EbtFloat, EbpHigh, EvqConst));
+ }
+
+ if (baseExpression->getQualifier() == EvqPerVertexIn)
+ {
+ if (mGeometryShaderInputPrimitiveType == EptUndefined &&
+ mShaderType == GL_GEOMETRY_SHADER_EXT)
+ {
+ error(location, "missing input primitive declaration before indexing gl_in.", "[");
+ return CreateZeroNode(TType(EbtFloat, EbpHigh, EvqConst));
+ }
+ }
+
+ TIntermConstantUnion *indexConstantUnion = indexExpression->getAsConstantUnion();
+
+ // ES3.2 or ES3.1's EXT_gpu_shader5 allow dynamically uniform expressions to be used as indices
+ // of opaque types (samplers and atomic counters) as well as UBOs, but not SSBOs and images.
+ bool allowUniformIndices =
+ mShaderVersion >= 320 || isExtensionEnabled(TExtension::EXT_gpu_shader5);
+
+ // ANGLE should be able to fold any constant expressions resulting in an integer - but to be
+ // safe we don't treat "EvqConst" that's evaluated according to the spec as being sufficient
+ // for constness. Some interpretations of the spec have allowed constant expressions with side
+ // effects - like array length() method on a non-constant array.
+ if (indexExpression->getQualifier() != EvqConst || indexConstantUnion == nullptr)
+ {
+ if (baseExpression->isInterfaceBlock())
+ {
+ switch (baseExpression->getQualifier())
+ {
+ case EvqPerVertexIn:
+ break;
+ case EvqUniform:
+ if (!allowUniformIndices)
+ {
+ error(location,
+ "array indexes for uniform block arrays must be constant integral "
+ "expressions",
+ "[");
+ }
+ break;
+ case EvqBuffer:
+ error(location,
+ "array indexes for shader storage block arrays must be constant integral "
+ "expressions",
+ "[");
+ break;
+ default:
+ // It's ok for shader I/O blocks to be dynamically indexed
+ if (!IsShaderIoBlock(baseExpression->getQualifier()) &&
+ baseExpression->getQualifier() != EvqPatchIn &&
+ baseExpression->getQualifier() != EvqPatchOut)
+ {
+ // We can reach here only in error cases.
+ ASSERT(mDiagnostics->numErrors() > 0);
+ }
+ break;
+ }
+ }
+ else if (baseExpression->getQualifier() == EvqFragmentOut)
+ {
+ error(location,
+ "array indexes for fragment outputs must be constant integral expressions", "[");
+ }
+ else if (mShaderSpec == SH_WEBGL2_SPEC && baseExpression->getQualifier() == EvqFragData)
+ {
+ error(location, "array index for gl_FragData must be constant zero", "[");
+ }
+ else if (baseExpression->isArray())
+ {
+ TBasicType elementType = baseExpression->getType().getBasicType();
+
+ // Note: In Section 12.30 of the ESSL 3.00 spec on p143-144:
+ //
+ // Indexing of arrays of samplers by constant-index-expressions is
+ // supported in GLSL ES 1.00. A constant-index-expression is an
+ // expression formed from constant-expressions and certain loop indices,
+ // defined for a subset of loop constructs. Should this functionality be
+ // included in GLSL ES 3.00?
+ //
+ // RESOLUTION: No. Arrays of samplers may only be indexed by constant-
+ // integral-expressions.
+ if (IsSampler(elementType) && !allowUniformIndices && mShaderVersion > 100)
+ {
+ error(location, "array index for samplers must be constant integral expressions",
+ "[");
+ }
+ else if (IsImage(elementType))
+ {
+ error(location,
+ "array indexes for image arrays must be constant integral expressions", "[");
+ }
+ }
+ }
+
+ if (indexConstantUnion)
+ {
+ // 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 = 0;
+ if (indexConstantUnion->getBasicType() == EbtInt)
+ {
+ index = indexConstantUnion->getIConst(0);
+ }
+ else if (indexConstantUnion->getBasicType() == EbtUInt)
+ {
+ index = static_cast<int>(indexConstantUnion->getUConst(0));
+ }
+
+ int safeIndex = -1;
+
+ if (index < 0)
+ {
+ outOfRangeError(outOfRangeIndexIsError, location, "index expression is negative", "[]");
+ safeIndex = 0;
+ }
+
+ if (!baseExpression->getType().isUnsizedArray())
+ {
+ if (baseExpression->isArray())
+ {
+ if (baseExpression->getQualifier() == EvqFragData && index > 0)
+ {
+ if (!isExtensionEnabled(TExtension::EXT_draw_buffers))
+ {
+ outOfRangeError(outOfRangeIndexIsError, location,
+ "array index for gl_FragData must be zero when "
+ "GL_EXT_draw_buffers is disabled",
+ "[]");
+ safeIndex = 0;
+ }
+ }
+ }
+ // Only do generic out-of-range check if similar error hasn't already been reported.
+ if (safeIndex < 0)
+ {
+ if (baseExpression->isArray())
+ {
+ safeIndex = checkIndexLessThan(outOfRangeIndexIsError, location, index,
+ baseExpression->getOutermostArraySize(),
+ "array index out of range");
+ }
+ else if (baseExpression->isMatrix())
+ {
+ safeIndex = checkIndexLessThan(outOfRangeIndexIsError, location, index,
+ baseExpression->getType().getCols(),
+ "matrix field selection out of range");
+ }
+ else
+ {
+ ASSERT(baseExpression->isVector());
+ safeIndex = checkIndexLessThan(outOfRangeIndexIsError, location, index,
+ baseExpression->getType().getNominalSize(),
+ "vector field selection out of range");
+ }
+ }
+
+ 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 || indexConstantUnion->getBasicType() != EbtInt)
+ {
+ TConstantUnion *safeConstantUnion = new TConstantUnion();
+ safeConstantUnion->setIConst(safeIndex);
+ indexExpression =
+ new TIntermConstantUnion(safeConstantUnion, TType(indexExpression->getType()));
+ }
+
+ TIntermBinary *node =
+ new TIntermBinary(EOpIndexDirect, baseExpression, indexExpression);
+ node->setLine(location);
+ return expressionOrFoldedResult(node);
+ }
+ }
+
+ markStaticReadIfSymbol(indexExpression);
+ TIntermBinary *node = new TIntermBinary(EOpIndexIndirect, baseExpression, indexExpression);
+ node->setLine(location);
+ // Indirect indexing can never be constant folded.
+ return node;
+}
+
+int TParseContext::checkIndexLessThan(bool outOfRangeIndexIsError,
+ const TSourceLoc &location,
+ int index,
+ int arraySize,
+ const char *reason)
+{
+ // Should not reach here with an unsized / runtime-sized array.
+ ASSERT(arraySize > 0);
+ // A negative index should already have been checked.
+ ASSERT(index >= 0);
+ if (index >= arraySize)
+ {
+ std::stringstream reasonStream = sh::InitializeStream<std::stringstream>();
+ reasonStream << reason << " '" << index << "'";
+ std::string token = reasonStream.str();
+ outOfRangeError(outOfRangeIndexIsError, location, reason, "[]");
+ return arraySize - 1;
+ }
+ return index;
+}
+
+TIntermTyped *TParseContext::addFieldSelectionExpression(TIntermTyped *baseExpression,
+ const TSourceLoc &dotLocation,
+ const ImmutableString &fieldString,
+ const TSourceLoc &fieldLocation)
+{
+ if (baseExpression->isArray())
+ {
+ error(fieldLocation, "cannot apply dot operator to an array", ".");
+ return baseExpression;
+ }
+
+ if (baseExpression->isVector())
+ {
+ TVector<int> fieldOffsets;
+ if (!parseVectorFields(fieldLocation, fieldString, baseExpression->getNominalSize(),
+ &fieldOffsets))
+ {
+ fieldOffsets.resize(1);
+ fieldOffsets[0] = 0;
+ }
+ TIntermSwizzle *node = new TIntermSwizzle(baseExpression, fieldOffsets);
+ node->setLine(dotLocation);
+
+ return node->fold(mDiagnostics);
+ }
+ else if (baseExpression->getBasicType() == EbtStruct)
+ {
+ const TFieldList &fields = baseExpression->getType().getStruct()->fields();
+ if (fields.empty())
+ {
+ error(dotLocation, "structure has no fields", "Internal Error");
+ return baseExpression;
+ }
+ else
+ {
+ bool fieldFound = false;
+ unsigned int i;
+ for (i = 0; i < fields.size(); ++i)
+ {
+ if (fields[i]->name() == fieldString)
+ {
+ fieldFound = true;
+ break;
+ }
+ }
+ if (fieldFound)
+ {
+ TIntermTyped *index = CreateIndexNode(i);
+ index->setLine(fieldLocation);
+ TIntermBinary *node =
+ new TIntermBinary(EOpIndexDirectStruct, baseExpression, index);
+ node->setLine(dotLocation);
+ return expressionOrFoldedResult(node);
+ }
+ else
+ {
+ error(dotLocation, " no such field in structure", fieldString);
+ return baseExpression;
+ }
+ }
+ }
+ else if (baseExpression->isInterfaceBlock())
+ {
+ const TFieldList &fields = baseExpression->getType().getInterfaceBlock()->fields();
+ if (fields.empty())
+ {
+ error(dotLocation, "interface block has no fields", "Internal Error");
+ return baseExpression;
+ }
+ else
+ {
+ bool fieldFound = false;
+ unsigned int i;
+ for (i = 0; i < fields.size(); ++i)
+ {
+ if (fields[i]->name() == fieldString)
+ {
+ fieldFound = true;
+ break;
+ }
+ }
+ if (fieldFound)
+ {
+ TIntermTyped *index = CreateIndexNode(i);
+ index->setLine(fieldLocation);
+ TIntermBinary *node =
+ new TIntermBinary(EOpIndexDirectInterfaceBlock, baseExpression, index);
+ node->setLine(dotLocation);
+ // Indexing interface blocks can never be constant folded.
+ return node;
+ }
+ else
+ {
+ error(dotLocation, " no such field in interface block", fieldString);
+ return baseExpression;
+ }
+ }
+ }
+ else
+ {
+ if (mShaderVersion < 300)
+ {
+ error(dotLocation, " field selection requires structure or vector on left hand side",
+ fieldString);
+ }
+ else
+ {
+ error(dotLocation,
+ " field selection requires structure, vector, or interface block on left hand "
+ "side",
+ fieldString);
+ }
+ return baseExpression;
+ }
+}
+
+TLayoutQualifier TParseContext::parseLayoutQualifier(const ImmutableString &qualifierType,
+ const TSourceLoc &qualifierTypeLine)
+{
+ TLayoutQualifier qualifier = TLayoutQualifier::Create();
+
+ if (qualifierType == "shared")
+ {
+ if (sh::IsWebGLBasedSpec(mShaderSpec))
+ {
+ error(qualifierTypeLine, "Only std140 layout is allowed in WebGL", "shared");
+ }
+ qualifier.blockStorage = EbsShared;
+ }
+ else if (qualifierType == "packed")
+ {
+ if (sh::IsWebGLBasedSpec(mShaderSpec))
+ {
+ error(qualifierTypeLine, "Only std140 layout is allowed in WebGL", "packed");
+ }
+ qualifier.blockStorage = EbsPacked;
+ }
+ else if (qualifierType == "std430")
+ {
+ checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
+ qualifier.blockStorage = EbsStd430;
+ }
+ else if (qualifierType == "std140")
+ {
+ qualifier.blockStorage = EbsStd140;
+ }
+ else if (qualifierType == "row_major")
+ {
+ qualifier.matrixPacking = EmpRowMajor;
+ }
+ else if (qualifierType == "column_major")
+ {
+ qualifier.matrixPacking = EmpColumnMajor;
+ }
+ else if (qualifierType == "location")
+ {
+ error(qualifierTypeLine, "invalid layout qualifier: location requires an argument",
+ qualifierType);
+ }
+ else if (qualifierType == "yuv" && mShaderType == GL_FRAGMENT_SHADER)
+ {
+ if (checkCanUseExtension(qualifierTypeLine, TExtension::EXT_YUV_target))
+ {
+ qualifier.yuv = true;
+ }
+ }
+ else if (qualifierType == "early_fragment_tests")
+ {
+ checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
+ qualifier.earlyFragmentTests = true;
+ }
+ else if (qualifierType == "rgba32f")
+ {
+ checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
+ qualifier.imageInternalFormat = EiifRGBA32F;
+ }
+ else if (qualifierType == "rgba16f")
+ {
+ checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
+ qualifier.imageInternalFormat = EiifRGBA16F;
+ }
+ else if (qualifierType == "r32f")
+ {
+ if (!isExtensionEnabled(TExtension::ANGLE_shader_pixel_local_storage))
+ {
+ checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
+ }
+ qualifier.imageInternalFormat = EiifR32F;
+ }
+ else if (qualifierType == "rgba8")
+ {
+ if (!isExtensionEnabled(TExtension::ANGLE_shader_pixel_local_storage))
+ {
+ checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
+ }
+ qualifier.imageInternalFormat = EiifRGBA8;
+ }
+ else if (qualifierType == "rgba8_snorm")
+ {
+ checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
+ qualifier.imageInternalFormat = EiifRGBA8_SNORM;
+ }
+ else if (qualifierType == "rgba32i")
+ {
+ checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
+ qualifier.imageInternalFormat = EiifRGBA32I;
+ }
+ else if (qualifierType == "rgba16i")
+ {
+ checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
+ qualifier.imageInternalFormat = EiifRGBA16I;
+ }
+ else if (qualifierType == "rgba8i")
+ {
+ if (!isExtensionEnabled(TExtension::ANGLE_shader_pixel_local_storage))
+ {
+ checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
+ }
+ qualifier.imageInternalFormat = EiifRGBA8I;
+ }
+ else if (qualifierType == "r32i")
+ {
+ checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
+ qualifier.imageInternalFormat = EiifR32I;
+ }
+ else if (qualifierType == "rgba32ui")
+ {
+ checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
+ qualifier.imageInternalFormat = EiifRGBA32UI;
+ }
+ else if (qualifierType == "rgba16ui")
+ {
+ checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
+ qualifier.imageInternalFormat = EiifRGBA16UI;
+ }
+ else if (qualifierType == "rgba8ui")
+ {
+ if (!isExtensionEnabled(TExtension::ANGLE_shader_pixel_local_storage))
+ {
+ checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
+ }
+ qualifier.imageInternalFormat = EiifRGBA8UI;
+ }
+ else if (qualifierType == "r32ui")
+ {
+ if (!isExtensionEnabled(TExtension::ANGLE_shader_pixel_local_storage))
+ {
+ checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
+ }
+ qualifier.imageInternalFormat = EiifR32UI;
+ }
+ else if (mShaderType == GL_GEOMETRY_SHADER_EXT &&
+ (mShaderVersion >= 320 ||
+ (checkCanUseOneOfExtensions(
+ qualifierTypeLine,
+ std::array<TExtension, 2u>{
+ {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}}) &&
+ checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310))))
+ {
+ if (qualifierType == "points")
+ {
+ qualifier.primitiveType = EptPoints;
+ }
+ else if (qualifierType == "lines")
+ {
+ qualifier.primitiveType = EptLines;
+ }
+ else if (qualifierType == "lines_adjacency")
+ {
+ qualifier.primitiveType = EptLinesAdjacency;
+ }
+ else if (qualifierType == "triangles")
+ {
+ qualifier.primitiveType = EptTriangles;
+ }
+ else if (qualifierType == "triangles_adjacency")
+ {
+ qualifier.primitiveType = EptTrianglesAdjacency;
+ }
+ else if (qualifierType == "line_strip")
+ {
+ qualifier.primitiveType = EptLineStrip;
+ }
+ else if (qualifierType == "triangle_strip")
+ {
+ qualifier.primitiveType = EptTriangleStrip;
+ }
+ else
+ {
+ error(qualifierTypeLine, "invalid layout qualifier", qualifierType);
+ }
+ }
+ else if (mShaderType == GL_TESS_EVALUATION_SHADER_EXT &&
+ (mShaderVersion >= 320 ||
+ (checkCanUseExtension(qualifierTypeLine, TExtension::EXT_tessellation_shader) &&
+ checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310))))
+ {
+ if (qualifierType == "triangles")
+ {
+ qualifier.tesPrimitiveType = EtetTriangles;
+ }
+ else if (qualifierType == "quads")
+ {
+ qualifier.tesPrimitiveType = EtetQuads;
+ }
+ else if (qualifierType == "isolines")
+ {
+ qualifier.tesPrimitiveType = EtetIsolines;
+ }
+ else if (qualifierType == "equal_spacing")
+ {
+ qualifier.tesVertexSpacingType = EtetEqualSpacing;
+ }
+ else if (qualifierType == "fractional_even_spacing")
+ {
+ qualifier.tesVertexSpacingType = EtetFractionalEvenSpacing;
+ }
+ else if (qualifierType == "fractional_odd_spacing")
+ {
+ qualifier.tesVertexSpacingType = EtetFractionalOddSpacing;
+ }
+ else if (qualifierType == "cw")
+ {
+ qualifier.tesOrderingType = EtetCw;
+ }
+ else if (qualifierType == "ccw")
+ {
+ qualifier.tesOrderingType = EtetCcw;
+ }
+ else if (qualifierType == "point_mode")
+ {
+ qualifier.tesPointType = EtetPointMode;
+ }
+ else
+ {
+ error(qualifierTypeLine, "invalid layout qualifier", qualifierType);
+ }
+ }
+ else if (mShaderType == GL_FRAGMENT_SHADER)
+ {
+ if (qualifierType == "noncoherent")
+ {
+ if (checkCanUseOneOfExtensions(
+ qualifierTypeLine,
+ std::array<TExtension, 2u>{
+ {TExtension::EXT_shader_framebuffer_fetch,
+ TExtension::EXT_shader_framebuffer_fetch_non_coherent}}))
+ {
+ checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 100);
+ qualifier.noncoherent = true;
+ }
+ }
+ else if (qualifierType == "blend_support_multiply")
+ {
+ AddAdvancedBlendEquation(gl::BlendEquationType::Multiply, &qualifier);
+ }
+ else if (qualifierType == "blend_support_screen")
+ {
+ AddAdvancedBlendEquation(gl::BlendEquationType::Screen, &qualifier);
+ }
+ else if (qualifierType == "blend_support_overlay")
+ {
+ AddAdvancedBlendEquation(gl::BlendEquationType::Overlay, &qualifier);
+ }
+ else if (qualifierType == "blend_support_darken")
+ {
+ AddAdvancedBlendEquation(gl::BlendEquationType::Darken, &qualifier);
+ }
+ else if (qualifierType == "blend_support_lighten")
+ {
+ AddAdvancedBlendEquation(gl::BlendEquationType::Lighten, &qualifier);
+ }
+ else if (qualifierType == "blend_support_colordodge")
+ {
+ AddAdvancedBlendEquation(gl::BlendEquationType::Colordodge, &qualifier);
+ }
+ else if (qualifierType == "blend_support_colorburn")
+ {
+ AddAdvancedBlendEquation(gl::BlendEquationType::Colorburn, &qualifier);
+ }
+ else if (qualifierType == "blend_support_hardlight")
+ {
+ AddAdvancedBlendEquation(gl::BlendEquationType::Hardlight, &qualifier);
+ }
+ else if (qualifierType == "blend_support_softlight")
+ {
+ AddAdvancedBlendEquation(gl::BlendEquationType::Softlight, &qualifier);
+ }
+ else if (qualifierType == "blend_support_difference")
+ {
+ AddAdvancedBlendEquation(gl::BlendEquationType::Difference, &qualifier);
+ }
+ else if (qualifierType == "blend_support_exclusion")
+ {
+ AddAdvancedBlendEquation(gl::BlendEquationType::Exclusion, &qualifier);
+ }
+ else if (qualifierType == "blend_support_hsl_hue")
+ {
+ AddAdvancedBlendEquation(gl::BlendEquationType::HslHue, &qualifier);
+ }
+ else if (qualifierType == "blend_support_hsl_saturation")
+ {
+ AddAdvancedBlendEquation(gl::BlendEquationType::HslSaturation, &qualifier);
+ }
+ else if (qualifierType == "blend_support_hsl_color")
+ {
+ AddAdvancedBlendEquation(gl::BlendEquationType::HslColor, &qualifier);
+ }
+ else if (qualifierType == "blend_support_hsl_luminosity")
+ {
+ AddAdvancedBlendEquation(gl::BlendEquationType::HslLuminosity, &qualifier);
+ }
+ else if (qualifierType == "blend_support_all_equations")
+ {
+ qualifier.advancedBlendEquations.setAll();
+ }
+ else
+ {
+ error(qualifierTypeLine, "invalid layout qualifier", qualifierType);
+ }
+
+ if (qualifier.advancedBlendEquations.any() && mShaderVersion < 320)
+ {
+ if (!checkCanUseExtension(qualifierTypeLine, TExtension::KHR_blend_equation_advanced))
+ {
+ qualifier.advancedBlendEquations.reset();
+ }
+ }
+ }
+ else
+ {
+ error(qualifierTypeLine, "invalid layout qualifier", qualifierType);
+ }
+
+ return qualifier;
+}
+
+void TParseContext::parseLocalSize(const ImmutableString &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::stringstream reasonStream = sh::InitializeStream<std::stringstream>();
+ reasonStream << "out of range: " << getWorkGroupSizeString(index) << " must be positive";
+ std::string reason = reasonStream.str();
+ error(intValueLine, reason.c_str(), intValueString.c_str());
+ }
+ (*localSize)[index] = intValue;
+}
+
+void TParseContext::parseNumViews(int intValue,
+ const TSourceLoc &intValueLine,
+ const std::string &intValueString,
+ int *numViews)
+{
+ // This error is only specified in WebGL, but tightens unspecified behavior in the native
+ // specification.
+ if (intValue < 1)
+ {
+ error(intValueLine, "out of range: num_views must be positive", intValueString.c_str());
+ }
+ *numViews = intValue;
+}
+
+void TParseContext::parseInvocations(int intValue,
+ const TSourceLoc &intValueLine,
+ const std::string &intValueString,
+ int *numInvocations)
+{
+ // Although SPEC isn't clear whether invocations can be less than 1, we add this limit because
+ // it doesn't make sense to accept invocations <= 0.
+ if (intValue < 1 || intValue > mMaxGeometryShaderInvocations)
+ {
+ error(intValueLine,
+ "out of range: invocations must be in the range of [1, "
+ "MAX_GEOMETRY_SHADER_INVOCATIONS_OES]",
+ intValueString.c_str());
+ }
+ else
+ {
+ *numInvocations = intValue;
+ }
+}
+
+void TParseContext::parseMaxVertices(int intValue,
+ const TSourceLoc &intValueLine,
+ const std::string &intValueString,
+ int *maxVertices)
+{
+ // Although SPEC isn't clear whether max_vertices can be less than 0, we add this limit because
+ // it doesn't make sense to accept max_vertices < 0.
+ if (intValue < 0 || intValue > mMaxGeometryShaderMaxVertices)
+ {
+ error(
+ intValueLine,
+ "out of range: max_vertices must be in the range of [0, gl_MaxGeometryOutputVertices]",
+ intValueString.c_str());
+ }
+ else
+ {
+ *maxVertices = intValue;
+ }
+}
+
+void TParseContext::parseVertices(int intValue,
+ const TSourceLoc &intValueLine,
+ const std::string &intValueString,
+ int *vertices)
+{
+ if (intValue < 1 || intValue > mMaxPatchVertices)
+ {
+ error(intValueLine,
+ "out of range : vertices must be in the range of [1, gl_MaxPatchVertices]",
+ intValueString.c_str());
+ }
+ else
+ {
+ *vertices = intValue;
+ }
+}
+
+void TParseContext::parseIndexLayoutQualifier(int intValue,
+ const TSourceLoc &intValueLine,
+ const std::string &intValueString,
+ int *index)
+{
+ // EXT_blend_func_extended specifies that most validation should happen at link time, but since
+ // we're validating output variable locations at compile time, it makes sense to validate that
+ // index is 0 or 1 also at compile time. Also since we use "-1" as a placeholder for unspecified
+ // index, we can't accept it here.
+ if (intValue < 0 || intValue > 1)
+ {
+ error(intValueLine, "out of range: index layout qualifier can only be 0 or 1",
+ intValueString.c_str());
+ }
+ else
+ {
+ *index = intValue;
+ }
+}
+
+TLayoutQualifier TParseContext::parseLayoutQualifier(const ImmutableString &qualifierType,
+ const TSourceLoc &qualifierTypeLine,
+ int intValue,
+ const TSourceLoc &intValueLine)
+{
+ TLayoutQualifier qualifier = TLayoutQualifier::Create();
+
+ std::string intValueString = Str(intValue);
+
+ if (qualifierType == "location")
+ {
+ // must check that location is non-negative
+ if (intValue < 0)
+ {
+ error(intValueLine, "out of range: location must be non-negative",
+ intValueString.c_str());
+ }
+ else
+ {
+ qualifier.location = intValue;
+ qualifier.locationsSpecified = 1;
+ }
+ }
+ else if (qualifierType == "binding")
+ {
+ if (!isExtensionEnabled(TExtension::ANGLE_shader_pixel_local_storage))
+ {
+ checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
+ }
+ if (intValue < 0)
+ {
+ error(intValueLine, "out of range: binding must be non-negative",
+ intValueString.c_str());
+ }
+ else
+ {
+ qualifier.binding = intValue;
+ }
+ }
+ else if (qualifierType == "offset")
+ {
+ checkLayoutQualifierSupported(qualifierTypeLine, qualifierType, 310);
+ if (intValue < 0)
+ {
+ error(intValueLine, "out of range: offset must be non-negative",
+ intValueString.c_str());
+ }
+ else
+ {
+ qualifier.offset = intValue;
+ }
+ }
+ else if (qualifierType == "local_size_x")
+ {
+ parseLocalSize(qualifierType, qualifierTypeLine, intValue, intValueLine, intValueString, 0u,
+ &qualifier.localSize);
+ }
+ else if (qualifierType == "local_size_y")
+ {
+ parseLocalSize(qualifierType, qualifierTypeLine, intValue, intValueLine, intValueString, 1u,
+ &qualifier.localSize);
+ }
+ else if (qualifierType == "local_size_z")
+ {
+ parseLocalSize(qualifierType, qualifierTypeLine, intValue, intValueLine, intValueString, 2u,
+ &qualifier.localSize);
+ }
+ else if (qualifierType == "num_views" && mShaderType == GL_VERTEX_SHADER)
+ {
+ if (checkCanUseOneOfExtensions(
+ qualifierTypeLine, std::array<TExtension, 2u>{
+ {TExtension::OVR_multiview, TExtension::OVR_multiview2}}))
+ {
+ parseNumViews(intValue, intValueLine, intValueString, &qualifier.numViews);
+ }
+ }
+ else if (qualifierType == "invocations" && mShaderType == GL_GEOMETRY_SHADER_EXT &&
+ (mShaderVersion >= 320 ||
+ checkCanUseOneOfExtensions(
+ qualifierTypeLine,
+ std::array<TExtension, 2u>{
+ {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}})))
+ {
+ parseInvocations(intValue, intValueLine, intValueString, &qualifier.invocations);
+ }
+ else if (qualifierType == "max_vertices" && mShaderType == GL_GEOMETRY_SHADER_EXT &&
+ (mShaderVersion >= 320 ||
+ checkCanUseOneOfExtensions(
+ qualifierTypeLine,
+ std::array<TExtension, 2u>{
+ {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}})))
+ {
+ parseMaxVertices(intValue, intValueLine, intValueString, &qualifier.maxVertices);
+ }
+ else if (qualifierType == "index" && mShaderType == GL_FRAGMENT_SHADER &&
+ checkCanUseExtension(qualifierTypeLine, TExtension::EXT_blend_func_extended))
+ {
+ parseIndexLayoutQualifier(intValue, intValueLine, intValueString, &qualifier.index);
+ }
+ else if (qualifierType == "vertices" && mShaderType == GL_TESS_CONTROL_SHADER_EXT &&
+ (mShaderVersion >= 320 ||
+ checkCanUseExtension(qualifierTypeLine, TExtension::EXT_tessellation_shader)))
+ {
+ parseVertices(intValue, intValueLine, intValueString, &qualifier.vertices);
+ }
+ else
+ {
+ error(qualifierTypeLine, "invalid layout qualifier", qualifierType);
+ }
+
+ return qualifier;
+}
+
+TTypeQualifierBuilder *TParseContext::createTypeQualifierBuilder(const TSourceLoc &loc)
+{
+ return new TTypeQualifierBuilder(
+ new TStorageQualifierWrapper(symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary, loc),
+ mShaderVersion);
+}
+
+TStorageQualifierWrapper *TParseContext::parseGlobalStorageQualifier(TQualifier qualifier,
+ const TSourceLoc &loc)
+{
+ checkIsAtGlobalLevel(loc, getQualifierString(qualifier));
+ return new TStorageQualifierWrapper(qualifier, loc);
+}
+
+TStorageQualifierWrapper *TParseContext::parseVaryingQualifier(const TSourceLoc &loc)
+{
+ if (getShaderType() == GL_VERTEX_SHADER)
+ {
+ return parseGlobalStorageQualifier(EvqVaryingOut, loc);
+ }
+ return parseGlobalStorageQualifier(EvqVaryingIn, loc);
+}
+
+TStorageQualifierWrapper *TParseContext::parseInQualifier(const TSourceLoc &loc)
+{
+ if (declaringFunction())
+ {
+ return new TStorageQualifierWrapper(EvqParamIn, loc);
+ }
+
+ switch (getShaderType())
+ {
+ case GL_VERTEX_SHADER:
+ {
+ if (mShaderVersion < 300 && !anyMultiviewExtensionAvailable() &&
+ !IsDesktopGLSpec(mShaderSpec))
+ {
+ error(loc, "storage qualifier supported in GLSL ES 3.00 and above only", "in");
+ }
+ return new TStorageQualifierWrapper(EvqVertexIn, loc);
+ }
+ case GL_FRAGMENT_SHADER:
+ {
+ if (mShaderVersion < 300 && !IsDesktopGLSpec(mShaderSpec))
+ {
+ error(loc, "storage qualifier supported in GLSL ES 3.00 and above only", "in");
+ }
+ return new TStorageQualifierWrapper(EvqFragmentIn, loc);
+ }
+ case GL_COMPUTE_SHADER:
+ {
+ return new TStorageQualifierWrapper(EvqComputeIn, loc);
+ }
+ case GL_GEOMETRY_SHADER:
+ {
+ return new TStorageQualifierWrapper(EvqGeometryIn, loc);
+ }
+ case GL_TESS_CONTROL_SHADER:
+ {
+ return new TStorageQualifierWrapper(EvqTessControlIn, loc);
+ }
+ case GL_TESS_EVALUATION_SHADER:
+ {
+ return new TStorageQualifierWrapper(EvqTessEvaluationIn, loc);
+ }
+ default:
+ {
+ UNREACHABLE();
+ return new TStorageQualifierWrapper(EvqLast, loc);
+ }
+ }
+}
+
+TStorageQualifierWrapper *TParseContext::parseOutQualifier(const TSourceLoc &loc)
+{
+ if (declaringFunction())
+ {
+ return new TStorageQualifierWrapper(EvqParamOut, loc);
+ }
+ switch (getShaderType())
+ {
+ case GL_VERTEX_SHADER:
+ {
+ if (mShaderVersion < 300 && !IsDesktopGLSpec(mShaderSpec))
+ {
+ error(loc, "storage qualifier supported in GLSL ES 3.00 and above only", "out");
+ }
+ return new TStorageQualifierWrapper(EvqVertexOut, loc);
+ }
+ case GL_FRAGMENT_SHADER:
+ {
+ if (mShaderVersion < 300 && !IsDesktopGLSpec(mShaderSpec))
+ {
+ error(loc, "storage qualifier supported in GLSL ES 3.00 and above only", "out");
+ }
+ return new TStorageQualifierWrapper(EvqFragmentOut, loc);
+ }
+ case GL_COMPUTE_SHADER:
+ {
+ error(loc, "storage qualifier isn't supported in compute shaders", "out");
+ return new TStorageQualifierWrapper(EvqParamOut, loc);
+ }
+ case GL_GEOMETRY_SHADER_EXT:
+ {
+ return new TStorageQualifierWrapper(EvqGeometryOut, loc);
+ }
+ case GL_TESS_CONTROL_SHADER_EXT:
+ {
+ return new TStorageQualifierWrapper(EvqTessControlOut, loc);
+ }
+ case GL_TESS_EVALUATION_SHADER_EXT:
+ {
+ return new TStorageQualifierWrapper(EvqTessEvaluationOut, loc);
+ }
+ default:
+ {
+ UNREACHABLE();
+ return new TStorageQualifierWrapper(EvqLast, loc);
+ }
+ }
+}
+
+TStorageQualifierWrapper *TParseContext::parseInOutQualifier(const TSourceLoc &loc)
+{
+ if (!declaringFunction())
+ {
+ if (mShaderVersion < 300 && !IsDesktopGLSpec(mShaderSpec))
+ {
+ error(loc, "storage qualifier supported in GLSL ES 3.00 and above only", "inout");
+ }
+
+ if (getShaderType() != GL_FRAGMENT_SHADER)
+ {
+ error(loc, "storage qualifier isn't supported in non-fragment shaders", "inout");
+ }
+
+ if (isExtensionEnabled(TExtension::EXT_shader_framebuffer_fetch) ||
+ isExtensionEnabled(TExtension::EXT_shader_framebuffer_fetch_non_coherent))
+ {
+ return new TStorageQualifierWrapper(EvqFragmentInOut, loc);
+ }
+
+ error(loc,
+ "invalid qualifier: can be used with either function parameters or the variables for "
+ "fetching input attachment data",
+ "inout");
+ }
+ return new TStorageQualifierWrapper(EvqParamInOut, loc);
+}
+
+TLayoutQualifier TParseContext::joinLayoutQualifiers(TLayoutQualifier leftQualifier,
+ TLayoutQualifier rightQualifier,
+ const TSourceLoc &rightQualifierLocation)
+{
+ return sh::JoinLayoutQualifiers(leftQualifier, rightQualifier, rightQualifierLocation,
+ mDiagnostics);
+}
+
+TDeclarator *TParseContext::parseStructDeclarator(const ImmutableString &identifier,
+ const TSourceLoc &loc)
+{
+ return new TDeclarator(identifier, loc);
+}
+
+TDeclarator *TParseContext::parseStructArrayDeclarator(const ImmutableString &identifier,
+ const TSourceLoc &loc,
+ const TVector<unsigned int> *arraySizes)
+{
+ return new TDeclarator(identifier, arraySizes, loc);
+}
+
+void TParseContext::checkDoesNotHaveDuplicateFieldName(const TFieldList::const_iterator begin,
+ const TFieldList::const_iterator end,
+ const ImmutableString &name,
+ const TSourceLoc &location)
+{
+ for (auto fieldIter = begin; fieldIter != end; ++fieldIter)
+ {
+ if ((*fieldIter)->name() == name)
+ {
+ error(location, "duplicate field name in structure", name);
+ }
+ }
+}
+
+TFieldList *TParseContext::addStructFieldList(TFieldList *fields, const TSourceLoc &location)
+{
+ for (TFieldList::const_iterator fieldIter = fields->begin(); fieldIter != fields->end();
+ ++fieldIter)
+ {
+ checkDoesNotHaveDuplicateFieldName(fields->begin(), fieldIter, (*fieldIter)->name(),
+ location);
+ }
+ return fields;
+}
+
+TFieldList *TParseContext::combineStructFieldLists(TFieldList *processedFields,
+ const TFieldList *newlyAddedFields,
+ const TSourceLoc &location)
+{
+ for (TField *field : *newlyAddedFields)
+ {
+ checkDoesNotHaveDuplicateFieldName(processedFields->begin(), processedFields->end(),
+ field->name(), location);
+ processedFields->push_back(field);
+ }
+ return processedFields;
+}
+
+TFieldList *TParseContext::addStructDeclaratorListWithQualifiers(
+ const TTypeQualifierBuilder &typeQualifierBuilder,
+ TPublicType *typeSpecifier,
+ const TDeclaratorList *declaratorList)
+{
+ TTypeQualifier typeQualifier = typeQualifierBuilder.getVariableTypeQualifier(mDiagnostics);
+
+ typeSpecifier->qualifier = typeQualifier.qualifier;
+ typeSpecifier->layoutQualifier = typeQualifier.layoutQualifier;
+ typeSpecifier->memoryQualifier = typeQualifier.memoryQualifier;
+ typeSpecifier->invariant = typeQualifier.invariant;
+ typeSpecifier->precise = typeQualifier.precise;
+ if (typeQualifier.precision != EbpUndefined)
+ {
+ typeSpecifier->precision = typeQualifier.precision;
+ }
+ return addStructDeclaratorList(*typeSpecifier, declaratorList);
+}
+
+TFieldList *TParseContext::addStructDeclaratorList(const TPublicType &typeSpecifier,
+ const TDeclaratorList *declaratorList)
+{
+ checkPrecisionSpecified(typeSpecifier.getLine(), typeSpecifier.precision,
+ typeSpecifier.getBasicType());
+
+ checkIsNonVoid(typeSpecifier.getLine(), (*declaratorList)[0]->name(),
+ typeSpecifier.getBasicType());
+
+ checkWorkGroupSizeIsNotSpecified(typeSpecifier.getLine(), typeSpecifier.layoutQualifier);
+ checkEarlyFragmentTestsIsNotSpecified(typeSpecifier.getLine(),
+ typeSpecifier.layoutQualifier.earlyFragmentTests);
+ checkNoncoherentIsNotSpecified(typeSpecifier.getLine(),
+ typeSpecifier.layoutQualifier.noncoherent);
+
+ TFieldList *fieldList = new TFieldList();
+
+ for (const TDeclarator *declarator : *declaratorList)
+ {
+ TType *type = new TType(typeSpecifier);
+ if (declarator->isArray())
+ {
+ // Don't allow arrays of arrays in ESSL < 3.10.
+ checkArrayElementIsNotArray(typeSpecifier.getLine(), typeSpecifier);
+ type->makeArrays(*declarator->arraySizes());
+ }
+
+ SymbolType symbolType = SymbolType::UserDefined;
+ if (declarator->name() == "gl_Position" || declarator->name() == "gl_PointSize" ||
+ declarator->name() == "gl_ClipDistance" || declarator->name() == "gl_CullDistance")
+ {
+ symbolType = SymbolType::BuiltIn;
+ }
+ else
+ {
+ checkIsNotReserved(typeSpecifier.getLine(), declarator->name());
+ }
+ TField *field = new TField(type, declarator->name(), declarator->line(), symbolType);
+ checkIsBelowStructNestingLimit(typeSpecifier.getLine(), *field);
+ fieldList->push_back(field);
+ }
+
+ return fieldList;
+}
+
+TTypeSpecifierNonArray TParseContext::addStructure(const TSourceLoc &structLine,
+ const TSourceLoc &nameLine,
+ const ImmutableString &structName,
+ TFieldList *fieldList)
+{
+ SymbolType structSymbolType = SymbolType::UserDefined;
+ if (structName.empty())
+ {
+ structSymbolType = SymbolType::Empty;
+ }
+ TStructure *structure = new TStructure(&symbolTable, structName, fieldList, structSymbolType);
+
+ // 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->setAtGlobalScope(symbolTable.atGlobalLevel());
+
+ if (structSymbolType != SymbolType::Empty)
+ {
+ checkIsNotReserved(nameLine, structName);
+ if (!symbolTable.declare(structure))
+ {
+ error(nameLine, "redefinition of a struct", structName);
+ }
+ }
+
+ // ensure we do not specify any storage qualifiers on the struct members
+ for (unsigned int typeListIndex = 0; typeListIndex < fieldList->size(); typeListIndex++)
+ {
+ TField &field = *(*fieldList)[typeListIndex];
+ const TQualifier qualifier = field.type()->getQualifier();
+ switch (qualifier)
+ {
+ case EvqGlobal:
+ case EvqTemporary:
+ break;
+ default:
+ error(field.line(), "invalid qualifier on struct member",
+ getQualifierString(qualifier));
+ break;
+ }
+ if (field.type()->isInvariant())
+ {
+ error(field.line(), "invalid qualifier on struct member", "invariant");
+ }
+ // ESSL 3.10 section 4.1.8 -- atomic_uint or images are not allowed as structure member.
+ // ANGLE_shader_pixel_local_storage also disallows PLS as struct members.
+ if (IsImage(field.type()->getBasicType()) ||
+ IsAtomicCounter(field.type()->getBasicType()) ||
+ IsPixelLocal(field.type()->getBasicType()))
+ {
+ error(field.line(), "disallowed type in struct", field.type()->getBasicString());
+ }
+
+ checkIsNotUnsizedArray(field.line(), "array members of structs must specify a size",
+ field.name(), field.type());
+
+ checkMemoryQualifierIsNotSpecified(field.type()->getMemoryQualifier(), field.line());
+
+ checkIndexIsNotSpecified(field.line(), field.type()->getLayoutQualifier().index);
+
+ checkBindingIsNotSpecified(field.line(), field.type()->getLayoutQualifier().binding);
+
+ checkLocationIsNotSpecified(field.line(), field.type()->getLayoutQualifier());
+ }
+
+ TTypeSpecifierNonArray typeSpecifierNonArray;
+ typeSpecifierNonArray.initializeStruct(structure, true, structLine);
+ exitStructDeclaration();
+
+ return typeSpecifierNonArray;
+}
+
+TIntermSwitch *TParseContext::addSwitch(TIntermTyped *init,
+ TIntermBlock *statementList,
+ const TSourceLoc &loc)
+{
+ TBasicType switchType = init->getBasicType();
+ if ((switchType != EbtInt && switchType != EbtUInt) || init->isMatrix() || init->isArray() ||
+ init->isVector())
+ {
+ error(init->getLine(), "init-expression in a switch statement must be a scalar integer",
+ "switch");
+ return nullptr;
+ }
+
+ ASSERT(statementList);
+ if (!ValidateSwitchStatementList(switchType, mDiagnostics, statementList, loc))
+ {
+ ASSERT(mDiagnostics->numErrors() > 0);
+ return nullptr;
+ }
+
+ markStaticReadIfSymbol(init);
+ TIntermSwitch *node = new TIntermSwitch(init, statementList);
+ node->setLine(loc);
+ return node;
+}
+
+TIntermCase *TParseContext::addCase(TIntermTyped *condition, const TSourceLoc &loc)
+{
+ if (mSwitchNestingLevel == 0)
+ {
+ error(loc, "case labels need to be inside switch statements", "case");
+ return nullptr;
+ }
+ if (condition == nullptr)
+ {
+ error(loc, "case label must have a condition", "case");
+ 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");
+ }
+ TIntermConstantUnion *conditionConst = condition->getAsConstantUnion();
+ // ANGLE should be able to fold any EvqConst expressions resulting in an integer - but to be
+ // safe against corner cases we still check for conditionConst. Some interpretations of the
+ // spec have allowed constant expressions with side effects - like array length() method on a
+ // non-constant array.
+ if (condition->getQualifier() != EvqConst || conditionConst == nullptr)
+ {
+ error(condition->getLine(), "case label must be constant", "case");
+ }
+ TIntermCase *node = new TIntermCase(condition);
+ node->setLine(loc);
+ return node;
+}
+
+TIntermCase *TParseContext::addDefault(const TSourceLoc &loc)
+{
+ if (mSwitchNestingLevel == 0)
+ {
+ error(loc, "default labels need to be inside switch statements", "default");
+ return nullptr;
+ }
+ TIntermCase *node = new TIntermCase(nullptr);
+ node->setLine(loc);
+ return node;
+}
+
+TIntermTyped *TParseContext::createUnaryMath(TOperator op,
+ TIntermTyped *child,
+ const TSourceLoc &loc,
+ const TFunction *func)
+{
+ ASSERT(child != nullptr);
+
+ switch (op)
+ {
+ case EOpLogicalNot:
+ if (child->getBasicType() != EbtBool || child->isMatrix() || child->isArray() ||
+ child->isVector())
+ {
+ unaryOpError(loc, GetOperatorString(op), child->getType());
+ return nullptr;
+ }
+ break;
+ case EOpBitwiseNot:
+ if ((child->getBasicType() != EbtInt && child->getBasicType() != EbtUInt) ||
+ child->isMatrix() || child->isArray())
+ {
+ unaryOpError(loc, GetOperatorString(op), child->getType());
+ return nullptr;
+ }
+ break;
+ case EOpPostIncrement:
+ case EOpPreIncrement:
+ case EOpPostDecrement:
+ case EOpPreDecrement:
+ case EOpNegative:
+ case EOpPositive:
+ if (child->getBasicType() == EbtStruct || child->isInterfaceBlock() ||
+ child->getBasicType() == EbtBool || child->isArray() ||
+ child->getBasicType() == EbtVoid || IsOpaqueType(child->getBasicType()))
+ {
+ unaryOpError(loc, GetOperatorString(op), child->getType());
+ return nullptr;
+ }
+ break;
+ // Operators for math built-ins are already type checked against their prototype.
+ default:
+ break;
+ }
+
+ if (child->getMemoryQualifier().writeonly)
+ {
+ const char *opStr =
+ BuiltInGroup::IsBuiltIn(op) ? func->name().data() : GetOperatorString(op);
+ unaryOpError(loc, opStr, child->getType());
+ return nullptr;
+ }
+
+ markStaticReadIfSymbol(child);
+ TIntermUnary *node = new TIntermUnary(op, child, func);
+ node->setLine(loc);
+
+ return node->fold(mDiagnostics);
+}
+
+TIntermTyped *TParseContext::addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc)
+{
+ ASSERT(op != EOpNull);
+ TIntermTyped *node = createUnaryMath(op, child, loc, nullptr);
+ if (node == nullptr)
+ {
+ return child;
+ }
+ return node;
+}
+
+TIntermTyped *TParseContext::addUnaryMathLValue(TOperator op,
+ TIntermTyped *child,
+ const TSourceLoc &loc)
+{
+ checkCanBeLValue(loc, GetOperatorString(op), child);
+ return addUnaryMath(op, child, loc);
+}
+
+TIntermTyped *TParseContext::expressionOrFoldedResult(TIntermTyped *expression)
+{
+ // If we can, we should return the folded version of the expression for subsequent parsing. This
+ // enables folding the containing expression during parsing as well, instead of the separate
+ // FoldExpressions() step where folding nested expressions requires multiple full AST
+ // traversals.
+
+ // Even if folding fails the fold() functions return some node representing the expression,
+ // typically the original node. So "folded" can be assumed to be non-null.
+ TIntermTyped *folded = expression->fold(mDiagnostics);
+ ASSERT(folded != nullptr);
+ if (folded->getQualifier() == expression->getQualifier())
+ {
+ // We need this expression to have the correct qualifier when validating the consuming
+ // expression. So we can only return the folded node from here in case it has the same
+ // qualifier as the original expression. In this kind of a cases the qualifier of the folded
+ // node is EvqConst, whereas the qualifier of the expression is EvqTemporary:
+ // 1. (true ? 1.0 : non_constant)
+ // 2. (non_constant, 1.0)
+ return folded;
+ }
+ return expression;
+}
+
+bool TParseContext::binaryOpCommonCheck(TOperator op,
+ TIntermTyped *left,
+ TIntermTyped *right,
+ const TSourceLoc &loc)
+{
+ // Check opaque types are not allowed to be operands in expressions other than array indexing
+ // and structure member selection.
+ if (IsOpaqueType(left->getBasicType()) || IsOpaqueType(right->getBasicType()))
+ {
+ switch (op)
+ {
+ case EOpIndexDirect:
+ case EOpIndexIndirect:
+ break;
+
+ default:
+ ASSERT(op != EOpIndexDirectStruct);
+ error(loc, "Invalid operation for variables with an opaque type",
+ GetOperatorString(op));
+ return false;
+ }
+ }
+
+ if (right->getMemoryQualifier().writeonly)
+ {
+ error(loc, "Invalid operation for variables with writeonly", GetOperatorString(op));
+ return false;
+ }
+
+ if (left->getMemoryQualifier().writeonly)
+ {
+ switch (op)
+ {
+ case EOpAssign:
+ case EOpInitialize:
+ case EOpIndexDirect:
+ case EOpIndexIndirect:
+ case EOpIndexDirectStruct:
+ case EOpIndexDirectInterfaceBlock:
+ break;
+ default:
+ error(loc, "Invalid operation for variables with writeonly", GetOperatorString(op));
+ return false;
+ }
+ }
+
+ 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->isInterfaceBlock() || right->isInterfaceBlock())
+ {
+ switch (op)
+ {
+ case EOpIndexDirectInterfaceBlock:
+ ASSERT(left->getType().getInterfaceBlock());
+ break;
+ default:
+ error(loc, "Invalid operation for interface blocks", GetOperatorString(op));
+ return false;
+ }
+ }
+
+ if (left->isArray() != right->isArray())
+ {
+ error(loc, "array / non-array mismatch", GetOperatorString(op));
+ return false;
+ }
+
+ if (left->isArray())
+ {
+ ASSERT(right->isArray());
+ if (mShaderVersion < 300)
+ {
+ error(loc, "Invalid operation for arrays", GetOperatorString(op));
+ return false;
+ }
+
+ switch (op)
+ {
+ case EOpEqual:
+ case EOpNotEqual:
+ case EOpAssign:
+ case EOpInitialize:
+ break;
+ default:
+ error(loc, "Invalid operation for arrays", GetOperatorString(op));
+ return false;
+ }
+ // At this point, size of implicitly sized arrays should be resolved.
+ if (left->getType().getArraySizes() != right->getType().getArraySizes())
+ {
+ error(loc, "array size mismatch", GetOperatorString(op));
+ return false;
+ }
+ }
+
+ // Check ops which require integer / ivec parameters
+ bool isBitShift = false;
+ switch (op)
+ {
+ case EOpBitShiftLeft:
+ case EOpBitShiftRight:
+ case EOpBitShiftLeftAssign:
+ case EOpBitShiftRightAssign:
+ // Unsigned can be bit-shifted by signed and vice versa, but we need to
+ // check that the basic type is an integer type.
+ isBitShift = true;
+ if (!IsInteger(left->getBasicType()) || !IsInteger(right->getBasicType()))
+ {
+ return false;
+ }
+ break;
+ case EOpBitwiseAnd:
+ case EOpBitwiseXor:
+ case EOpBitwiseOr:
+ case EOpBitwiseAndAssign:
+ case EOpBitwiseXorAssign:
+ case EOpBitwiseOrAssign:
+ // It is enough to check the type of only one operand, since later it
+ // is checked that the operand types match.
+ if (!IsInteger(left->getBasicType()))
+ {
+ return false;
+ }
+ break;
+ default:
+ break;
+ }
+
+ ImplicitTypeConversion conversion = GetConversion(left->getBasicType(), right->getBasicType());
+
+ // Implicit type casting only supported for GL shaders
+ if (!isBitShift && conversion != ImplicitTypeConversion::Same &&
+ (!IsDesktopGLSpec(mShaderSpec) || !IsValidImplicitConversion(conversion, op)))
+ {
+ return false;
+ }
+
+ // 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:
+ case EOpInitialize:
+ case EOpEqual:
+ case EOpNotEqual:
+ // ESSL 1.00 sections 5.7, 5.8, 5.9
+ if (mShaderVersion < 300 && left->getType().isStructureContainingArrays())
+ {
+ error(loc, "undefined operation for structs containing arrays",
+ GetOperatorString(op));
+ return false;
+ }
+ // Samplers as l-values are disallowed also in ESSL 3.00, see section 4.1.7,
+ // we interpret the spec so that this extends to structs containing samplers,
+ // similarly to ESSL 1.00 spec.
+ if ((mShaderVersion < 300 || op == EOpAssign || op == EOpInitialize) &&
+ left->getType().isStructureContainingSamplers())
+ {
+ error(loc, "undefined operation for structs containing samplers",
+ GetOperatorString(op));
+ return false;
+ }
+
+ if ((left->getNominalSize() != right->getNominalSize()) ||
+ (left->getSecondarySize() != right->getSecondarySize()))
+ {
+ error(loc, "dimension mismatch", GetOperatorString(op));
+ return false;
+ }
+ break;
+ case EOpLessThan:
+ case EOpGreaterThan:
+ case EOpLessThanEqual:
+ case EOpGreaterThanEqual:
+ if (!left->isScalar() || !right->isScalar())
+ {
+ error(loc, "comparison operator only defined for scalars", GetOperatorString(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;
+ }
+
+ 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,
+ const TSourceLoc &loc)
+{
+ if (!binaryOpCommonCheck(op, left, right, loc))
+ return nullptr;
+
+ switch (op)
+ {
+ case EOpEqual:
+ case EOpNotEqual:
+ case EOpLessThan:
+ case EOpGreaterThan:
+ case EOpLessThanEqual:
+ case EOpGreaterThanEqual:
+ break;
+ case EOpLogicalOr:
+ case EOpLogicalXor:
+ case EOpLogicalAnd:
+ ASSERT(!left->isArray() && !right->isArray() && !left->getType().getStruct() &&
+ !right->getType().getStruct());
+ if (left->getBasicType() != EbtBool || !left->isScalar() || !right->isScalar())
+ {
+ return nullptr;
+ }
+ // Basic types matching should have been already checked.
+ ASSERT(right->getBasicType() == EbtBool);
+ break;
+ case EOpAdd:
+ case EOpSub:
+ case EOpDiv:
+ case EOpMul:
+ 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() && !left->getType().getStruct() &&
+ !right->getType().getStruct());
+ // Note that this is only for the % operator, not for mod()
+ if (left->getBasicType() == EbtBool || left->getBasicType() == EbtFloat)
+ {
+ return nullptr;
+ }
+ break;
+ default:
+ break;
+ }
+
+ 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);
+ ASSERT(op != EOpAssign);
+ markStaticReadIfSymbol(left);
+ markStaticReadIfSymbol(right);
+ node->setLine(loc);
+ return expressionOrFoldedResult(node);
+}
+
+TIntermTyped *TParseContext::addBinaryMath(TOperator op,
+ TIntermTyped *left,
+ TIntermTyped *right,
+ const TSourceLoc &loc)
+{
+ TIntermTyped *node = addBinaryMathInternal(op, left, right, loc);
+ if (node == 0)
+ {
+ binaryOpError(loc, GetOperatorString(op), left->getType(), right->getType());
+ return left;
+ }
+ return node;
+}
+
+TIntermTyped *TParseContext::addBinaryMathBooleanResult(TOperator op,
+ TIntermTyped *left,
+ TIntermTyped *right,
+ const TSourceLoc &loc)
+{
+ TIntermTyped *node = addBinaryMathInternal(op, left, right, loc);
+ if (node == nullptr)
+ {
+ binaryOpError(loc, GetOperatorString(op), left->getType(), right->getType());
+ node = CreateBoolNode(false);
+ node->setLine(loc);
+ }
+ return node;
+}
+
+TIntermTyped *TParseContext::addAssign(TOperator op,
+ TIntermTyped *left,
+ TIntermTyped *right,
+ const TSourceLoc &loc)
+{
+ checkCanBeLValue(loc, "assign", left);
+ TIntermBinary *node = nullptr;
+ if (binaryOpCommonCheck(op, left, right, loc))
+ {
+ TIntermBinary *lValue = left->getAsBinaryNode();
+ if ((lValue != nullptr) &&
+ (lValue->getOp() == EOpIndexIndirect || lValue->getOp() == EOpIndexDirect) &&
+ IsTessellationControlShaderOutput(mShaderType, lValue->getLeft()->getQualifier()))
+ {
+ checkTCSOutVarIndexIsValid(lValue, loc);
+ }
+
+ if (op == EOpMulAssign)
+ {
+ op = TIntermBinary::GetMulAssignOpBasedOnOperands(left->getType(), right->getType());
+ if (isMultiplicationTypeCombinationValid(op, left->getType(), right->getType()))
+ {
+ node = new TIntermBinary(op, left, right);
+ }
+ }
+ else
+ {
+ node = new TIntermBinary(op, left, right);
+ }
+ }
+ if (node == nullptr)
+ {
+ assignError(loc, "assign", left->getType(), right->getType());
+ return left;
+ }
+ if (op != EOpAssign)
+ {
+ markStaticReadIfSymbol(left);
+ }
+ markStaticReadIfSymbol(right);
+ node->setLine(loc);
+ return node;
+}
+
+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",
+ ",");
+ }
+
+ TIntermBinary *commaNode = TIntermBinary::CreateComma(left, right, mShaderVersion);
+ markStaticReadIfSymbol(left);
+ markStaticReadIfSymbol(right);
+ commaNode->setLine(loc);
+
+ return expressionOrFoldedResult(commaNode);
+}
+
+TIntermBranch *TParseContext::addBranch(TOperator op, const TSourceLoc &loc)
+{
+ switch (op)
+ {
+ case EOpContinue:
+ if (mLoopNestingLevel <= 0)
+ {
+ error(loc, "continue statement only allowed in loops", "");
+ }
+ break;
+ case EOpBreak:
+ if (mLoopNestingLevel <= 0 && mSwitchNestingLevel <= 0)
+ {
+ error(loc, "break statement only allowed in loops and switch statements", "");
+ }
+ break;
+ case EOpReturn:
+ if (mCurrentFunctionType->getBasicType() != EbtVoid)
+ {
+ error(loc, "non-void function must return a value", "return");
+ }
+ if (mDeclaringMain)
+ {
+ errorIfPLSDeclared(loc, PLSIllegalOperations::ReturnFromMain);
+ }
+ break;
+ case EOpKill:
+ if (mShaderType != GL_FRAGMENT_SHADER)
+ {
+ error(loc, "discard supported in fragment shaders only", "discard");
+ }
+ else
+ {
+ errorIfPLSDeclared(loc, PLSIllegalOperations::Discard);
+ }
+ mHasDiscard = true;
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ return addBranch(op, nullptr, loc);
+}
+
+TIntermBranch *TParseContext::addBranch(TOperator op,
+ TIntermTyped *expression,
+ const TSourceLoc &loc)
+{
+ if (expression != nullptr)
+ {
+ markStaticReadIfSymbol(expression);
+ ASSERT(op == EOpReturn);
+ mFunctionReturnsValue = true;
+ if (mCurrentFunctionType->getBasicType() == EbtVoid)
+ {
+ error(loc, "void function cannot return a value", "return");
+ }
+ else if (*mCurrentFunctionType != expression->getType())
+ {
+ error(loc, "function return is not matching type:", "return");
+ }
+ }
+ TIntermBranch *node = new TIntermBranch(op, expression);
+ node->setLine(loc);
+ return node;
+}
+
+void TParseContext::appendStatement(TIntermBlock *block, TIntermNode *statement)
+{
+ if (statement != nullptr)
+ {
+ markStaticReadIfSymbol(statement);
+ block->appendStatement(statement);
+ }
+}
+
+void TParseContext::checkTextureGather(TIntermAggregate *functionCall)
+{
+ const TOperator op = functionCall->getOp();
+ const TFunction *func = functionCall->getFunction();
+ if (BuiltInGroup::IsTextureGather(op))
+ {
+ bool isTextureGatherOffsetOrOffsets =
+ BuiltInGroup::IsTextureGatherOffset(op) || BuiltInGroup::IsTextureGatherOffsets(op);
+ TIntermNode *componentNode = nullptr;
+ TIntermSequence *arguments = functionCall->getSequence();
+ ASSERT(arguments->size() >= 2u && arguments->size() <= 4u);
+ const TIntermTyped *sampler = arguments->front()->getAsTyped();
+ ASSERT(sampler != nullptr);
+ switch (sampler->getBasicType())
+ {
+ case EbtSampler2D:
+ case EbtISampler2D:
+ case EbtUSampler2D:
+ case EbtSampler2DArray:
+ case EbtISampler2DArray:
+ case EbtUSampler2DArray:
+ if ((!isTextureGatherOffsetOrOffsets && arguments->size() == 3u) ||
+ (isTextureGatherOffsetOrOffsets && arguments->size() == 4u))
+ {
+ componentNode = arguments->back();
+ }
+ break;
+ case EbtSamplerCube:
+ case EbtISamplerCube:
+ case EbtUSamplerCube:
+ case EbtSamplerCubeArray:
+ case EbtISamplerCubeArray:
+ case EbtUSamplerCubeArray:
+ ASSERT(!isTextureGatherOffsetOrOffsets);
+ if (arguments->size() == 3u)
+ {
+ componentNode = arguments->back();
+ }
+ break;
+ case EbtSampler2DShadow:
+ case EbtSampler2DArrayShadow:
+ case EbtSamplerCubeShadow:
+ case EbtSamplerCubeArrayShadow:
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ if (componentNode)
+ {
+ const TIntermConstantUnion *componentConstantUnion =
+ componentNode->getAsConstantUnion();
+ if (componentNode->getAsTyped()->getQualifier() != EvqConst || !componentConstantUnion)
+ {
+ error(functionCall->getLine(), "Texture component must be a constant expression",
+ func->name());
+ }
+ else
+ {
+ int component = componentConstantUnion->getIConst(0);
+ if (component < 0 || component > 3)
+ {
+ error(functionCall->getLine(), "Component must be in the range [0;3]",
+ func->name());
+ }
+ }
+ }
+ }
+}
+
+void TParseContext::checkTextureOffset(TIntermAggregate *functionCall)
+{
+ const TOperator op = functionCall->getOp();
+ const TFunction *func = functionCall->getFunction();
+ TIntermNode *offset = nullptr;
+ TIntermSequence *arguments = functionCall->getSequence();
+
+ if (BuiltInGroup::IsTextureOffsetNoBias(op) || BuiltInGroup::IsTextureGatherOffsetNoComp(op) ||
+ BuiltInGroup::IsTextureGatherOffsetsNoComp(op))
+ {
+ offset = arguments->back();
+ }
+ else if (BuiltInGroup::IsTextureOffsetBias(op) || BuiltInGroup::IsTextureGatherOffsetComp(op) ||
+ BuiltInGroup::IsTextureGatherOffsetsComp(op))
+ {
+ // A bias or comp parameter follows the offset parameter.
+ ASSERT(arguments->size() >= 3);
+ offset = (*arguments)[2];
+ }
+
+ // If not one of the above built-ins, there's nothing to do here.
+ if (offset == nullptr)
+ {
+ return;
+ }
+
+ bool isTextureGatherOffset = BuiltInGroup::IsTextureGatherOffset(op);
+ bool isTextureGatherOffsets = BuiltInGroup::IsTextureGatherOffsets(op);
+ bool useTextureGatherOffsetConstraints = isTextureGatherOffset || isTextureGatherOffsets;
+
+ int minOffsetValue =
+ useTextureGatherOffsetConstraints ? mMinProgramTextureGatherOffset : mMinProgramTexelOffset;
+ int maxOffsetValue =
+ useTextureGatherOffsetConstraints ? mMaxProgramTextureGatherOffset : mMaxProgramTexelOffset;
+
+ if (isTextureGatherOffsets)
+ {
+ // If textureGatherOffsets, the offsets parameter is an array, which is expected as an
+ // aggregate constructor node or as a symbol node with a constant value.
+ TIntermAggregate *offsetAggregate = offset->getAsAggregate();
+ TIntermSymbol *offsetSymbol = offset->getAsSymbolNode();
+
+ const TConstantUnion *offsetValues = offsetAggregate ? offsetAggregate->getConstantValue()
+ : offsetSymbol ? offsetSymbol->getConstantValue()
+ : nullptr;
+
+ if (offsetValues == nullptr)
+ {
+ error(functionCall->getLine(), "Texture offsets must be a constant expression",
+ func->name());
+ return;
+ }
+
+ constexpr unsigned int kOffsetsCount = 4;
+ const TType &offsetType =
+ offsetAggregate != nullptr ? offsetAggregate->getType() : offsetSymbol->getType();
+ if (offsetType.getNumArraySizes() != 1 || offsetType.getArraySizes()[0] != kOffsetsCount)
+ {
+ error(functionCall->getLine(), "Texture offsets must be an array of 4 elements",
+ func->name());
+ return;
+ }
+
+ size_t size = offsetType.getObjectSize() / kOffsetsCount;
+ for (unsigned int i = 0; i < kOffsetsCount; ++i)
+ {
+ checkSingleTextureOffset(offset->getLine(), &offsetValues[i * size], size,
+ minOffsetValue, maxOffsetValue);
+ }
+ }
+ else
+ {
+ // If textureOffset or textureGatherOffset, the offset is expected to be found as a constant
+ // union.
+ TIntermConstantUnion *offsetConstantUnion = offset->getAsConstantUnion();
+
+ // ES3.2 or ES3.1's EXT_gpu_shader5 allow non-const offsets to be passed to
+ // textureGatherOffset.
+ bool textureGatherOffsetMustBeConst =
+ mShaderVersion <= 310 && !isExtensionEnabled(TExtension::EXT_gpu_shader5);
+
+ bool isOffsetConst =
+ offset->getAsTyped()->getQualifier() == EvqConst && offsetConstantUnion != nullptr;
+ bool offsetMustBeConst = !isTextureGatherOffset || textureGatherOffsetMustBeConst;
+
+ if (!isOffsetConst && offsetMustBeConst)
+ {
+ error(functionCall->getLine(), "Texture offset must be a constant expression",
+ func->name());
+ return;
+ }
+
+ // We cannot verify non-constant offsets to textureGatherOffset.
+ if (offsetConstantUnion == nullptr)
+ {
+ ASSERT(!offsetMustBeConst);
+ return;
+ }
+
+ size_t size = offsetConstantUnion->getType().getObjectSize();
+ const TConstantUnion *values = offsetConstantUnion->getConstantValue();
+ checkSingleTextureOffset(offset->getLine(), values, size, minOffsetValue, maxOffsetValue);
+ }
+}
+
+void TParseContext::checkSingleTextureOffset(const TSourceLoc &line,
+ const TConstantUnion *values,
+ size_t size,
+ int minOffsetValue,
+ int maxOffsetValue)
+{
+ for (size_t i = 0u; i < size; ++i)
+ {
+ ASSERT(values[i].getType() == EbtInt);
+ int offsetValue = values[i].getIConst();
+ if (offsetValue > maxOffsetValue || offsetValue < minOffsetValue)
+ {
+ std::stringstream tokenStream = sh::InitializeStream<std::stringstream>();
+ tokenStream << offsetValue;
+ std::string token = tokenStream.str();
+ error(line, "Texture offset value out of valid range", token.c_str());
+ }
+ }
+}
+
+void TParseContext::checkInterpolationFS(TIntermAggregate *functionCall)
+{
+ const TFunction *func = functionCall->getFunction();
+ if (!BuiltInGroup::IsInterpolationFS(functionCall->getOp()))
+ {
+ return;
+ }
+
+ TIntermTyped *arg0 = nullptr;
+
+ if (functionCall->getAsAggregate())
+ {
+ const TIntermSequence *argp = functionCall->getSequence();
+ if (argp->size() > 0)
+ arg0 = (*argp)[0]->getAsTyped();
+ }
+ else
+ {
+ assert(functionCall->getAsUnaryNode());
+ arg0 = functionCall->getAsUnaryNode()->getOperand();
+ }
+
+ // Make sure the first argument is an interpolant, or an array element of an interpolant
+ if (!IsVaryingIn(arg0->getType().getQualifier()))
+ {
+ // It might still be an array element.
+ const TIntermTyped *base = FindLValueBase(arg0);
+
+ if (base == nullptr || (!IsVaryingIn(base->getType().getQualifier())))
+ error(arg0->getLine(),
+ "first argument must be an interpolant, or interpolant-array element",
+ func->name());
+ }
+}
+
+void TParseContext::checkAtomicMemoryBuiltinFunctions(TIntermAggregate *functionCall)
+{
+ const TFunction *func = functionCall->getFunction();
+ if (BuiltInGroup::IsAtomicMemory(functionCall->getOp()))
+ {
+ TIntermSequence *arguments = functionCall->getSequence();
+ TIntermTyped *memNode = (*arguments)[0]->getAsTyped();
+
+ if (IsBufferOrSharedVariable(memNode))
+ {
+ return;
+ }
+
+ while (memNode->getAsBinaryNode() || memNode->getAsSwizzleNode())
+ {
+ // Child 0 is "left" if binary, and the expression being swizzled if swizzle.
+ // Note: we don't need to check that the binary operation is one of EOp*Index*, as any
+ // other operation will result in a temp value which cannot be passed to this
+ // out/inout parameter anyway.
+ memNode = memNode->getChildNode(0)->getAsTyped();
+ if (IsBufferOrSharedVariable(memNode))
+ {
+ return;
+ }
+ }
+
+ error(memNode->getLine(),
+ "The value passed to the mem argument of an atomic memory function does not "
+ "correspond to a buffer or shared variable.",
+ func->name());
+ }
+}
+
+// GLSL ES 3.10 Revision 4, 4.9 Memory Access Qualifiers
+void TParseContext::checkImageMemoryAccessForBuiltinFunctions(TIntermAggregate *functionCall)
+{
+ const TOperator op = functionCall->getOp();
+
+ if (BuiltInGroup::IsImage(op))
+ {
+ TIntermSequence *arguments = functionCall->getSequence();
+ TIntermTyped *imageNode = (*arguments)[0]->getAsTyped();
+
+ const TMemoryQualifier &memoryQualifier = imageNode->getMemoryQualifier();
+
+ if (BuiltInGroup::IsImageStore(op))
+ {
+ if (memoryQualifier.readonly)
+ {
+ error(imageNode->getLine(),
+ "'imageStore' cannot be used with images qualified as 'readonly'",
+ GetImageArgumentToken(imageNode));
+ }
+ }
+ else if (BuiltInGroup::IsImageLoad(op))
+ {
+ if (memoryQualifier.writeonly)
+ {
+ error(imageNode->getLine(),
+ "'imageLoad' cannot be used with images qualified as 'writeonly'",
+ GetImageArgumentToken(imageNode));
+ }
+ }
+ else if (BuiltInGroup::IsImageAtomic(op))
+ {
+ if (memoryQualifier.readonly)
+ {
+ error(imageNode->getLine(),
+ "'imageAtomic' cannot be used with images qualified as 'readonly'",
+ GetImageArgumentToken(imageNode));
+ }
+ if (memoryQualifier.writeonly)
+ {
+ error(imageNode->getLine(),
+ "'imageAtomic' cannot be used with images qualified as 'writeonly'",
+ GetImageArgumentToken(imageNode));
+ }
+ }
+ }
+}
+
+// GLSL ES 3.10 Revision 4, 13.51 Matching of Memory Qualifiers in Function Parameters
+void TParseContext::checkImageMemoryAccessForUserDefinedFunctions(
+ const TFunction *functionDefinition,
+ const TIntermAggregate *functionCall)
+{
+ ASSERT(functionCall->getOp() == EOpCallFunctionInAST);
+
+ const TIntermSequence &arguments = *functionCall->getSequence();
+
+ ASSERT(functionDefinition->getParamCount() == arguments.size());
+
+ for (size_t i = 0; i < arguments.size(); ++i)
+ {
+ TIntermTyped *typedArgument = arguments[i]->getAsTyped();
+ const TType &functionArgumentType = typedArgument->getType();
+ const TType &functionParameterType = functionDefinition->getParam(i)->getType();
+ ASSERT(functionArgumentType.getBasicType() == functionParameterType.getBasicType());
+
+ if (IsImage(functionArgumentType.getBasicType()))
+ {
+ const TMemoryQualifier &functionArgumentMemoryQualifier =
+ functionArgumentType.getMemoryQualifier();
+ const TMemoryQualifier &functionParameterMemoryQualifier =
+ functionParameterType.getMemoryQualifier();
+ if (functionArgumentMemoryQualifier.readonly &&
+ !functionParameterMemoryQualifier.readonly)
+ {
+ error(functionCall->getLine(),
+ "Function call discards the 'readonly' qualifier from image",
+ GetImageArgumentToken(typedArgument));
+ }
+
+ if (functionArgumentMemoryQualifier.writeonly &&
+ !functionParameterMemoryQualifier.writeonly)
+ {
+ error(functionCall->getLine(),
+ "Function call discards the 'writeonly' qualifier from image",
+ GetImageArgumentToken(typedArgument));
+ }
+
+ if (functionArgumentMemoryQualifier.coherent &&
+ !functionParameterMemoryQualifier.coherent)
+ {
+ error(functionCall->getLine(),
+ "Function call discards the 'coherent' qualifier from image",
+ GetImageArgumentToken(typedArgument));
+ }
+
+ if (functionArgumentMemoryQualifier.volatileQualifier &&
+ !functionParameterMemoryQualifier.volatileQualifier)
+ {
+ error(functionCall->getLine(),
+ "Function call discards the 'volatile' qualifier from image",
+ GetImageArgumentToken(typedArgument));
+ }
+ }
+ }
+}
+
+TIntermTyped *TParseContext::addFunctionCallOrMethod(TFunctionLookup *fnCall, const TSourceLoc &loc)
+{
+ if (fnCall->thisNode() != nullptr)
+ {
+ return addMethod(fnCall, loc);
+ }
+ if (fnCall->isConstructor())
+ {
+ return addConstructor(fnCall, loc);
+ }
+ return addNonConstructorFunctionCall(fnCall, loc);
+}
+
+TIntermTyped *TParseContext::addMethod(TFunctionLookup *fnCall, const TSourceLoc &loc)
+{
+ TIntermTyped *thisNode = fnCall->thisNode();
+ // It's possible for the name pointer in the TFunction to be null in case it gets parsed as
+ // a constructor. But such a TFunction can't reach here, since the lexer goes into FIELDS
+ // mode after a dot, which makes type identifiers to be parsed as FIELD_SELECTION instead.
+ // So accessing fnCall->name() below is safe.
+ if (fnCall->name() != "length")
+ {
+ error(loc, "invalid method", fnCall->name());
+ }
+ else if (!fnCall->arguments().empty())
+ {
+ error(loc, "method takes no parameters", "length");
+ }
+ else if (!thisNode->isArray())
+ {
+ error(loc, "length can only be called on arrays", "length");
+ }
+ else if (thisNode->getQualifier() == EvqPerVertexIn &&
+ mGeometryShaderInputPrimitiveType == EptUndefined)
+ {
+ ASSERT(mShaderType == GL_GEOMETRY_SHADER_EXT);
+ error(loc, "missing input primitive declaration before calling length on gl_in", "length");
+ }
+ else
+ {
+ TIntermUnary *node = new TIntermUnary(EOpArrayLength, thisNode, nullptr);
+ markStaticReadIfSymbol(thisNode);
+ node->setLine(loc);
+ return node->fold(mDiagnostics);
+ }
+ return CreateZeroNode(TType(EbtInt, EbpUndefined, EvqConst));
+}
+
+TIntermTyped *TParseContext::addNonConstructorFunctionCall(TFunctionLookup *fnCall,
+ const TSourceLoc &loc)
+{
+ // First check whether the function has been hidden by a variable name or struct typename by
+ // using the symbol looked up in the lexical phase. If the function is not hidden, look for one
+ // with a matching argument list.
+ if (fnCall->symbol() != nullptr && !fnCall->symbol()->isFunction())
+ {
+ error(loc, "function name expected", fnCall->name());
+ }
+ else
+ {
+ // There are no inner functions, so it's enough to look for user-defined functions in the
+ // global scope.
+ const TSymbol *symbol = symbolTable.findGlobal(fnCall->getMangledName());
+
+ if (symbol == nullptr && IsDesktopGLSpec(mShaderSpec))
+ {
+ // If using Desktop GL spec, need to check for implicit conversion
+ symbol = symbolTable.findGlobalWithConversion(
+ fnCall->getMangledNamesForImplicitConversions());
+ }
+
+ if (symbol != nullptr)
+ {
+ // A user-defined function - could be an overloaded built-in as well.
+ ASSERT(symbol->symbolType() == SymbolType::UserDefined);
+ const TFunction *fnCandidate = static_cast<const TFunction *>(symbol);
+ TIntermAggregate *callNode =
+ TIntermAggregate::CreateFunctionCall(*fnCandidate, &fnCall->arguments());
+ callNode->setLine(loc);
+ checkImageMemoryAccessForUserDefinedFunctions(fnCandidate, callNode);
+ functionCallRValueLValueErrorCheck(fnCandidate, callNode);
+ return callNode;
+ }
+
+ symbol = symbolTable.findBuiltIn(fnCall->getMangledName(), mShaderVersion);
+
+ if (symbol == nullptr && IsDesktopGLSpec(mShaderSpec))
+ {
+ // If using Desktop GL spec, need to check for implicit conversion
+ symbol = symbolTable.findBuiltInWithConversion(
+ fnCall->getMangledNamesForImplicitConversions(), mShaderVersion);
+ }
+
+ if (symbol != nullptr)
+ {
+ // A built-in function.
+ ASSERT(symbol->symbolType() == SymbolType::BuiltIn);
+ const TFunction *fnCandidate = static_cast<const TFunction *>(symbol);
+
+ if (!fnCandidate->extensions().empty() &&
+ fnCandidate->extensions()[0] != TExtension::UNDEFINED)
+ {
+ checkCanUseOneOfExtensions(loc, fnCandidate->extensions());
+ }
+
+ // All function calls are mapped to a built-in operation.
+ TOperator op = fnCandidate->getBuiltInOp();
+ if (BuiltInGroup::IsMath(op) && fnCandidate->getParamCount() == 1)
+ {
+ // Treat it like a built-in unary operator.
+ TIntermNode *unaryParamNode = fnCall->arguments().front();
+ TIntermTyped *callNode =
+ createUnaryMath(op, unaryParamNode->getAsTyped(), loc, fnCandidate);
+ ASSERT(callNode != nullptr);
+ return callNode;
+ }
+
+ TIntermAggregate *callNode =
+ TIntermAggregate::CreateBuiltInFunctionCall(*fnCandidate, &fnCall->arguments());
+ callNode->setLine(loc);
+
+ checkAtomicMemoryBuiltinFunctions(callNode);
+ checkTextureOffset(callNode);
+ checkTextureGather(callNode);
+ checkInterpolationFS(callNode);
+ checkImageMemoryAccessForBuiltinFunctions(callNode);
+
+ // Some built-in functions have out parameters too.
+ functionCallRValueLValueErrorCheck(fnCandidate, callNode);
+
+ // See if we can constant fold a built-in. Note that this may be possible
+ // even if it is not const-qualified.
+ return callNode->fold(mDiagnostics);
+ }
+ else
+ {
+ error(loc, "no matching overloaded function found", fnCall->name());
+ }
+ }
+
+ // Error message was already written. Put on an unused node for error recovery.
+ return CreateZeroNode(TType(EbtFloat, EbpMedium, EvqConst));
+}
+
+TIntermTyped *TParseContext::addTernarySelection(TIntermTyped *cond,
+ TIntermTyped *trueExpression,
+ TIntermTyped *falseExpression,
+ const TSourceLoc &loc)
+{
+ if (!checkIsScalarBool(loc, cond))
+ {
+ return falseExpression;
+ }
+
+ if (trueExpression->getType() != falseExpression->getType())
+ {
+ TInfoSinkBase reasonStream;
+ reasonStream << "mismatching ternary operator operand types '" << trueExpression->getType()
+ << " and '" << falseExpression->getType() << "'";
+ error(loc, reasonStream.c_str(), "?:");
+ return falseExpression;
+ }
+ if (IsOpaqueType(trueExpression->getBasicType()))
+ {
+ // ESSL 1.00 section 4.1.7
+ // ESSL 3.00.6 section 4.1.7
+ // Opaque/sampler types are not allowed in most types of expressions, including ternary.
+ // Note that structs containing opaque types don't need to be checked as structs are
+ // forbidden below.
+ error(loc, "ternary operator is not allowed for opaque types", "?:");
+ return falseExpression;
+ }
+
+ if (cond->getMemoryQualifier().writeonly || trueExpression->getMemoryQualifier().writeonly ||
+ falseExpression->getMemoryQualifier().writeonly)
+ {
+ error(loc, "ternary operator is not allowed for variables with writeonly", "?:");
+ return falseExpression;
+ }
+
+ // ESSL 1.00.17 sections 5.2 and 5.7:
+ // Ternary operator is not among the operators allowed for structures/arrays.
+ // ESSL 3.00.6 section 5.7:
+ // Ternary operator support is optional for arrays. No certainty that it works across all
+ // devices with struct either, so we err on the side of caution here. TODO (oetuaho@nvidia.com):
+ // Would be nice to make the spec and implementation agree completely here.
+ if (trueExpression->isArray() || trueExpression->getBasicType() == EbtStruct)
+ {
+ error(loc, "ternary operator is not allowed for structures or arrays", "?:");
+ return falseExpression;
+ }
+ if (trueExpression->getBasicType() == EbtInterfaceBlock)
+ {
+ error(loc, "ternary operator is not allowed for interface blocks", "?:");
+ return falseExpression;
+ }
+
+ // 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;
+ }
+
+ TIntermTernary *node = new TIntermTernary(cond, trueExpression, falseExpression);
+ markStaticReadIfSymbol(cond);
+ markStaticReadIfSymbol(trueExpression);
+ markStaticReadIfSymbol(falseExpression);
+ node->setLine(loc);
+ return expressionOrFoldedResult(node);
+}
+
+//
+// Parse an array of strings using yyparse.
+//
+// Returns 0 for success.
+//
+int PaParseStrings(size_t count,
+ const char *const string[],
+ const int length[],
+ TParseContext *context)
+{
+ if ((count == 0) || (string == nullptr))
+ return 1;
+
+ if (glslang_initialize(context))
+ return 1;
+
+ int error = glslang_scan(count, string, length, context);
+ if (!error)
+ error = glslang_parse(context);
+
+ glslang_finalize(context);
+
+ return (error == 0) && (context->numErrors() == 0) ? 0 : 1;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/ParseContext.h b/gfx/angle/checkout/src/compiler/translator/ParseContext.h
new file mode 100644
index 0000000000..666f5e3851
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ParseContext.h
@@ -0,0 +1,818 @@
+//
+// Copyright 2002 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_PARSECONTEXT_H_
+#define COMPILER_TRANSLATOR_PARSECONTEXT_H_
+
+#include "compiler/preprocessor/Preprocessor.h"
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/Declarator.h"
+#include "compiler/translator/Diagnostics.h"
+#include "compiler/translator/DirectiveHandler.h"
+#include "compiler/translator/FunctionLookup.h"
+#include "compiler/translator/QualifierTypes.h"
+#include "compiler/translator/SymbolTable.h"
+
+namespace sh
+{
+
+struct TMatrixFields
+{
+ bool wholeRow;
+ bool wholeCol;
+ int row;
+ int col;
+};
+
+//
+// The following are extra variables needed during parsing, grouped together so
+// they can be passed to the parser without needing a global.
+//
+class TParseContext : angle::NonCopyable
+{
+ public:
+ TParseContext(TSymbolTable &symt,
+ TExtensionBehavior &ext,
+ sh::GLenum type,
+ ShShaderSpec spec,
+ const ShCompileOptions &options,
+ bool checksPrecErrors,
+ TDiagnostics *diagnostics,
+ const ShBuiltInResources &resources,
+ ShShaderOutput outputType);
+ ~TParseContext();
+
+ bool anyMultiviewExtensionAvailable();
+ const angle::pp::Preprocessor &getPreprocessor() const { return mPreprocessor; }
+ angle::pp::Preprocessor &getPreprocessor() { return mPreprocessor; }
+ void *getScanner() const { return mScanner; }
+ void setScanner(void *scanner) { mScanner = scanner; }
+ int getShaderVersion() const { return mShaderVersion; }
+ sh::GLenum getShaderType() const { return mShaderType; }
+ ShShaderSpec getShaderSpec() const { return mShaderSpec; }
+ int numErrors() const { return mDiagnostics->numErrors(); }
+ void error(const TSourceLoc &loc, const char *reason, const char *token);
+ void error(const TSourceLoc &loc, const char *reason, const ImmutableString &token);
+ void warning(const TSourceLoc &loc, const char *reason, const char *token);
+
+ // If isError is false, a warning will be reported instead.
+ void outOfRangeError(bool isError,
+ const TSourceLoc &loc,
+ const char *reason,
+ const char *token);
+
+ TIntermBlock *getTreeRoot() const { return mTreeRoot; }
+ void setTreeRoot(TIntermBlock *treeRoot);
+
+ bool getFragmentPrecisionHigh() const
+ {
+ return mFragmentPrecisionHighOnESSL1 || mShaderVersion >= 300;
+ }
+ void setFragmentPrecisionHighOnESSL1(bool fragmentPrecisionHigh)
+ {
+ mFragmentPrecisionHighOnESSL1 = fragmentPrecisionHigh;
+ }
+
+ bool isEarlyFragmentTestsSpecified() const { return mEarlyFragmentTestsSpecified; }
+ bool hasDiscard() const { return mHasDiscard; }
+ bool isSampleQualifierSpecified() const { return mSampleQualifierSpecified; }
+
+ void setLoopNestingLevel(int loopNestintLevel) { mLoopNestingLevel = loopNestintLevel; }
+
+ void incrLoopNestingLevel() { ++mLoopNestingLevel; }
+ void decrLoopNestingLevel() { --mLoopNestingLevel; }
+
+ void incrSwitchNestingLevel() { ++mSwitchNestingLevel; }
+ void decrSwitchNestingLevel() { --mSwitchNestingLevel; }
+
+ bool isComputeShaderLocalSizeDeclared() const { return mComputeShaderLocalSizeDeclared; }
+ sh::WorkGroupSize getComputeShaderLocalSize() const;
+
+ int getNumViews() const { return mNumViews; }
+
+ const std::map<int, TLayoutImageInternalFormat> &pixelLocalStorageBindings() const
+ {
+ return mPLSBindings;
+ }
+
+ void enterFunctionDeclaration() { mDeclaringFunction = true; }
+
+ void exitFunctionDeclaration() { mDeclaringFunction = false; }
+
+ bool declaringFunction() const { return mDeclaringFunction; }
+
+ TIntermConstantUnion *addScalarLiteral(const TConstantUnion *constantUnion,
+ const TSourceLoc &line);
+
+ // This method is guaranteed to succeed, even if no variable with 'name' exists.
+ const TVariable *getNamedVariable(const TSourceLoc &location,
+ const ImmutableString &name,
+ const TSymbol *symbol);
+ TIntermTyped *parseVariableIdentifier(const TSourceLoc &location,
+ const ImmutableString &name,
+ const TSymbol *symbol);
+
+ // Look at a '.' field selector string and change it into offsets for a vector.
+ bool parseVectorFields(const TSourceLoc &line,
+ const ImmutableString &compString,
+ int vecSize,
+ TVector<int> *fieldOffsets);
+
+ void assignError(const TSourceLoc &line, const char *op, const TType &left, const TType &right);
+ void unaryOpError(const TSourceLoc &line, const char *op, const TType &operand);
+ void binaryOpError(const TSourceLoc &line,
+ const char *op,
+ const TType &left,
+ const TType &right);
+
+ // Check functions - the ones that return bool return false if an error was generated.
+
+ bool checkIsNotReserved(const TSourceLoc &line, const ImmutableString &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,
+ const TIntermSequence &arguments,
+ 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 checkArrayElementIsNotArray(const TSourceLoc &line, const TPublicType &elementType);
+ bool checkArrayOfArraysInOut(const TSourceLoc &line,
+ const TPublicType &elementType,
+ const TType &arrayType);
+ bool checkIsNonVoid(const TSourceLoc &line,
+ const ImmutableString &identifier,
+ const TBasicType &type);
+ bool checkIsScalarBool(const TSourceLoc &line, const TIntermTyped *type);
+ void checkIsScalarBool(const TSourceLoc &line, const TPublicType &pType);
+ bool checkIsNotOpaqueType(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 checkStd430IsForShaderStorageBlock(const TSourceLoc &location,
+ const TLayoutBlockStorage &blockStorage,
+ const TQualifier &qualifier);
+ void checkIsParameterQualifierValid(const TSourceLoc &line,
+ const TTypeQualifierBuilder &typeQualifierBuilder,
+ TType *type);
+
+ // Check if at least one of the specified extensions can be used, and generate error/warning as
+ // appropriate according to the spec.
+ // This function is only needed for a few different small constant sizes of extension array, and
+ // we want to avoid unnecessary dynamic allocations. That's why checkCanUseOneOfExtensions is a
+ // template function rather than one taking a vector.
+ template <size_t size>
+ bool checkCanUseOneOfExtensions(const TSourceLoc &line,
+ const std::array<TExtension, size> &extensions);
+ bool checkCanUseExtension(const TSourceLoc &line, TExtension extension);
+
+ // Done for all declarations, whether empty or not.
+ void declarationQualifierErrorCheck(const sh::TQualifier qualifier,
+ const sh::TLayoutQualifier &layoutQualifier,
+ const TSourceLoc &location);
+ // Done for the first non-empty declarator in a declaration.
+ void nonEmptyDeclarationErrorCheck(const TPublicType &publicType,
+ const TSourceLoc &identifierLocation);
+ // Done only for empty declarations.
+ void emptyDeclarationErrorCheck(const TType &type, const TSourceLoc &location);
+
+ void checkCanUseLayoutQualifier(const TSourceLoc &location);
+ bool checkLayoutQualifierSupported(const TSourceLoc &location,
+ const ImmutableString &layoutQualifierName,
+ int versionRequired);
+ bool checkWorkGroupSizeIsNotSpecified(const TSourceLoc &location,
+ const TLayoutQualifier &layoutQualifier);
+ void functionCallRValueLValueErrorCheck(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);
+ void checkLocalVariableConstStorageQualifier(const TQualifierWrapperBase &qualifier);
+ void checkTCSOutVarIndexIsValid(TIntermBinary *binaryExpression, const TSourceLoc &location);
+
+ void checkAdvancedBlendEquationsNotSpecified(
+ const TSourceLoc &location,
+ const AdvancedBlendEquations &advancedBlendEquations,
+ const TQualifier &qualifier);
+
+ const TPragma &pragma() const { return mDirectiveHandler.pragma(); }
+ const TExtensionBehavior &extensionBehavior() const
+ {
+ return mDirectiveHandler.extensionBehavior();
+ }
+
+ bool isExtensionEnabled(TExtension extension) const;
+ void handleExtensionDirective(const TSourceLoc &loc, const char *extName, const char *behavior);
+ void handlePragmaDirective(const TSourceLoc &loc,
+ const char *name,
+ const char *value,
+ bool stdgl);
+
+ // For built-ins that can be redeclared, adjusts the type qualifier so transformations can
+ // identify them correctly.
+ void adjustRedeclaredBuiltInType(const ImmutableString &identifier, TType *type);
+
+ // Returns true on success. *initNode may still be nullptr on success in case the initialization
+ // is not needed in the AST.
+ bool executeInitializer(const TSourceLoc &line,
+ const ImmutableString &identifier,
+ TType *type,
+ TIntermTyped *initializer,
+ TIntermBinary **initNode);
+ TIntermNode *addConditionInitializer(const TPublicType &pType,
+ const ImmutableString &identifier,
+ TIntermTyped *initializer,
+ const TSourceLoc &loc);
+ TIntermNode *addLoop(TLoopType type,
+ TIntermNode *init,
+ TIntermNode *cond,
+ TIntermTyped *expr,
+ TIntermNode *body,
+ const TSourceLoc &loc);
+
+ // For "if" test nodes. There are three children: a condition, a true path, and a false path.
+ // The two paths are in TIntermNodePair code.
+ TIntermNode *addIfElse(TIntermTyped *cond, TIntermNodePair code, const TSourceLoc &loc);
+
+ void addFullySpecifiedType(TPublicType *typeSpecifier);
+ TPublicType addFullySpecifiedType(const TTypeQualifierBuilder &typeQualifierBuilder,
+ const TPublicType &typeSpecifier);
+
+ TIntermDeclaration *parseSingleDeclaration(TPublicType &publicType,
+ const TSourceLoc &identifierOrTypeLocation,
+ const ImmutableString &identifier);
+ TIntermDeclaration *parseSingleArrayDeclaration(TPublicType &elementType,
+ const TSourceLoc &identifierLocation,
+ const ImmutableString &identifier,
+ const TSourceLoc &indexLocation,
+ const TVector<unsigned int> &arraySizes);
+ TIntermDeclaration *parseSingleInitDeclaration(const TPublicType &publicType,
+ const TSourceLoc &identifierLocation,
+ const ImmutableString &identifier,
+ const TSourceLoc &initLocation,
+ TIntermTyped *initializer);
+
+ // Parse a declaration like "type a[n] = initializer"
+ // Note that this does not apply to declarations like "type[n] a = initializer"
+ TIntermDeclaration *parseSingleArrayInitDeclaration(TPublicType &elementType,
+ const TSourceLoc &identifierLocation,
+ const ImmutableString &identifier,
+ const TSourceLoc &indexLocation,
+ const TVector<unsigned int> &arraySizes,
+ const TSourceLoc &initLocation,
+ TIntermTyped *initializer);
+
+ TIntermGlobalQualifierDeclaration *parseGlobalQualifierDeclaration(
+ const TTypeQualifierBuilder &typeQualifierBuilder,
+ const TSourceLoc &identifierLoc,
+ const ImmutableString &identifier,
+ const TSymbol *symbol);
+
+ void parseDeclarator(TPublicType &publicType,
+ const TSourceLoc &identifierLocation,
+ const ImmutableString &identifier,
+ TIntermDeclaration *declarationOut);
+ void parseArrayDeclarator(TPublicType &elementType,
+ const TSourceLoc &identifierLocation,
+ const ImmutableString &identifier,
+ const TSourceLoc &arrayLocation,
+ const TVector<unsigned int> &arraySizes,
+ TIntermDeclaration *declarationOut);
+ void parseInitDeclarator(const TPublicType &publicType,
+ const TSourceLoc &identifierLocation,
+ const ImmutableString &identifier,
+ const TSourceLoc &initLocation,
+ TIntermTyped *initializer,
+ TIntermDeclaration *declarationOut);
+
+ // Parse a declarator like "a[n] = initializer"
+ void parseArrayInitDeclarator(const TPublicType &elementType,
+ const TSourceLoc &identifierLocation,
+ const ImmutableString &identifier,
+ const TSourceLoc &indexLocation,
+ const TVector<unsigned int> &arraySizes,
+ const TSourceLoc &initLocation,
+ TIntermTyped *initializer,
+ TIntermDeclaration *declarationOut);
+
+ TIntermNode *addEmptyStatement(const TSourceLoc &location);
+
+ void parseDefaultPrecisionQualifier(const TPrecision precision,
+ const TPublicType &type,
+ const TSourceLoc &loc);
+ void parseGlobalLayoutQualifier(const TTypeQualifierBuilder &typeQualifierBuilder);
+
+ TIntermFunctionPrototype *addFunctionPrototypeDeclaration(const TFunction &parsedFunction,
+ const TSourceLoc &location);
+ TIntermFunctionDefinition *addFunctionDefinition(TIntermFunctionPrototype *functionPrototype,
+ TIntermBlock *functionBody,
+ const TSourceLoc &location);
+ void parseFunctionDefinitionHeader(const TSourceLoc &location,
+ const TFunction *function,
+ TIntermFunctionPrototype **prototypeOut);
+ TFunction *parseFunctionDeclarator(const TSourceLoc &location, TFunction *function);
+ TFunction *parseFunctionHeader(const TPublicType &type,
+ const ImmutableString &name,
+ const TSourceLoc &location);
+
+ TFunctionLookup *addNonConstructorFunc(const ImmutableString &name, const TSymbol *symbol);
+ TFunctionLookup *addConstructorFunc(const TPublicType &publicType);
+
+ TParameter parseParameterDeclarator(const TPublicType &publicType,
+ const ImmutableString &name,
+ const TSourceLoc &nameLoc);
+
+ TParameter parseParameterArrayDeclarator(const ImmutableString &name,
+ const TSourceLoc &nameLoc,
+ const TVector<unsigned int> &arraySizes,
+ const TSourceLoc &arrayLoc,
+ TPublicType *elementType);
+
+ TIntermTyped *addIndexExpression(TIntermTyped *baseExpression,
+ const TSourceLoc &location,
+ TIntermTyped *indexExpression);
+ TIntermTyped *addFieldSelectionExpression(TIntermTyped *baseExpression,
+ const TSourceLoc &dotLocation,
+ const ImmutableString &fieldString,
+ const TSourceLoc &fieldLocation);
+
+ // Parse declarator for a single field
+ TDeclarator *parseStructDeclarator(const ImmutableString &identifier, const TSourceLoc &loc);
+ TDeclarator *parseStructArrayDeclarator(const ImmutableString &identifier,
+ const TSourceLoc &loc,
+ const TVector<unsigned int> *arraySizes);
+
+ void checkDoesNotHaveDuplicateFieldName(const TFieldList::const_iterator begin,
+ const TFieldList::const_iterator end,
+ const ImmutableString &name,
+ const TSourceLoc &location);
+ TFieldList *addStructFieldList(TFieldList *fields, const TSourceLoc &location);
+ TFieldList *combineStructFieldLists(TFieldList *processedFields,
+ const TFieldList *newlyAddedFields,
+ const TSourceLoc &location);
+ TFieldList *addStructDeclaratorListWithQualifiers(
+ const TTypeQualifierBuilder &typeQualifierBuilder,
+ TPublicType *typeSpecifier,
+ const TDeclaratorList *declaratorList);
+ TFieldList *addStructDeclaratorList(const TPublicType &typeSpecifier,
+ const TDeclaratorList *declaratorList);
+ TTypeSpecifierNonArray addStructure(const TSourceLoc &structLine,
+ const TSourceLoc &nameLine,
+ const ImmutableString &structName,
+ TFieldList *fieldList);
+
+ TIntermDeclaration *addInterfaceBlock(const TTypeQualifierBuilder &typeQualifierBuilder,
+ const TSourceLoc &nameLine,
+ const ImmutableString &blockName,
+ TFieldList *fieldList,
+ const ImmutableString &instanceName,
+ const TSourceLoc &instanceLine,
+ const TVector<unsigned int> *arraySizes,
+ const TSourceLoc &arraySizesLine);
+
+ void parseLocalSize(const ImmutableString &qualifierType,
+ const TSourceLoc &qualifierTypeLine,
+ int intValue,
+ const TSourceLoc &intValueLine,
+ const std::string &intValueString,
+ size_t index,
+ sh::WorkGroupSize *localSize);
+ void parseNumViews(int intValue,
+ const TSourceLoc &intValueLine,
+ const std::string &intValueString,
+ int *numViews);
+ void parseInvocations(int intValue,
+ const TSourceLoc &intValueLine,
+ const std::string &intValueString,
+ int *numInvocations);
+ void parseMaxVertices(int intValue,
+ const TSourceLoc &intValueLine,
+ const std::string &intValueString,
+ int *numMaxVertices);
+ void parseVertices(int intValue,
+ const TSourceLoc &intValueLine,
+ const std::string &intValueString,
+ int *numVertices);
+ void parseIndexLayoutQualifier(int intValue,
+ const TSourceLoc &intValueLine,
+ const std::string &intValueString,
+ int *index);
+ TLayoutQualifier parseLayoutQualifier(const ImmutableString &qualifierType,
+ const TSourceLoc &qualifierTypeLine);
+ TLayoutQualifier parseLayoutQualifier(const ImmutableString &qualifierType,
+ const TSourceLoc &qualifierTypeLine,
+ int intValue,
+ const TSourceLoc &intValueLine);
+ TTypeQualifierBuilder *createTypeQualifierBuilder(const TSourceLoc &loc);
+ TStorageQualifierWrapper *parseGlobalStorageQualifier(TQualifier qualifier,
+ const TSourceLoc &loc);
+ TStorageQualifierWrapper *parseVaryingQualifier(const TSourceLoc &loc);
+ TStorageQualifierWrapper *parseInQualifier(const TSourceLoc &loc);
+ TStorageQualifierWrapper *parseOutQualifier(const TSourceLoc &loc);
+ TStorageQualifierWrapper *parseInOutQualifier(const TSourceLoc &loc);
+ TLayoutQualifier joinLayoutQualifiers(TLayoutQualifier leftQualifier,
+ TLayoutQualifier rightQualifier,
+ const TSourceLoc &rightQualifierLocation);
+
+ // Performs an error check for embedded struct declarations.
+ void enterStructDeclaration(const TSourceLoc &line, const ImmutableString &identifier);
+ void exitStructDeclaration();
+
+ void checkIsBelowStructNestingLimit(const TSourceLoc &line, const TField &field);
+
+ TIntermSwitch *addSwitch(TIntermTyped *init,
+ TIntermBlock *statementList,
+ const TSourceLoc &loc);
+ TIntermCase *addCase(TIntermTyped *condition, const TSourceLoc &loc);
+ TIntermCase *addDefault(const TSourceLoc &loc);
+
+ TIntermTyped *addUnaryMath(TOperator op, TIntermTyped *child, const TSourceLoc &loc);
+ TIntermTyped *addUnaryMathLValue(TOperator op, TIntermTyped *child, const TSourceLoc &loc);
+ TIntermTyped *addBinaryMath(TOperator op,
+ TIntermTyped *left,
+ TIntermTyped *right,
+ const TSourceLoc &loc);
+ TIntermTyped *addBinaryMathBooleanResult(TOperator op,
+ TIntermTyped *left,
+ TIntermTyped *right,
+ const TSourceLoc &loc);
+ TIntermTyped *addAssign(TOperator op,
+ TIntermTyped *left,
+ TIntermTyped *right,
+ const TSourceLoc &loc);
+
+ TIntermTyped *addComma(TIntermTyped *left, TIntermTyped *right, const TSourceLoc &loc);
+
+ TIntermBranch *addBranch(TOperator op, const TSourceLoc &loc);
+ TIntermBranch *addBranch(TOperator op, TIntermTyped *expression, const TSourceLoc &loc);
+
+ void appendStatement(TIntermBlock *block, TIntermNode *statement);
+
+ void checkTextureGather(TIntermAggregate *functionCall);
+ void checkTextureOffset(TIntermAggregate *functionCall);
+ void checkImageMemoryAccessForBuiltinFunctions(TIntermAggregate *functionCall);
+ void checkImageMemoryAccessForUserDefinedFunctions(const TFunction *functionDefinition,
+ const TIntermAggregate *functionCall);
+ void checkAtomicMemoryBuiltinFunctions(TIntermAggregate *functionCall);
+ void checkInterpolationFS(TIntermAggregate *functionCall);
+
+ // fnCall is only storing the built-in op, and function name or constructor type. arguments
+ // has the arguments.
+ TIntermTyped *addFunctionCallOrMethod(TFunctionLookup *fnCall, const TSourceLoc &loc);
+
+ TIntermTyped *addTernarySelection(TIntermTyped *cond,
+ TIntermTyped *trueExpression,
+ TIntermTyped *falseExpression,
+ const TSourceLoc &line);
+
+ int getGeometryShaderMaxVertices() const { return mGeometryShaderMaxVertices; }
+ int getGeometryShaderInvocations() const
+ {
+ return (mGeometryShaderInvocations > 0) ? mGeometryShaderInvocations : 1;
+ }
+ TLayoutPrimitiveType getGeometryShaderInputPrimitiveType() const
+ {
+ return mGeometryShaderInputPrimitiveType;
+ }
+ TLayoutPrimitiveType getGeometryShaderOutputPrimitiveType() const
+ {
+ return mGeometryShaderOutputPrimitiveType;
+ }
+ int getTessControlShaderOutputVertices() const { return mTessControlShaderOutputVertices; }
+ TLayoutTessEvaluationType getTessEvaluationShaderInputPrimitiveType() const
+ {
+ return mTessEvaluationShaderInputPrimitiveType;
+ }
+ TLayoutTessEvaluationType getTessEvaluationShaderInputVertexSpacingType() const
+ {
+ return mTessEvaluationShaderInputVertexSpacingType;
+ }
+ TLayoutTessEvaluationType getTessEvaluationShaderInputOrderingType() const
+ {
+ return mTessEvaluationShaderInputOrderingType;
+ }
+ TLayoutTessEvaluationType getTessEvaluationShaderInputPointType() const
+ {
+ return mTessEvaluationShaderInputPointType;
+ }
+
+ const TVector<TType *> &getDeferredArrayTypesToSize() const
+ {
+ return mDeferredArrayTypesToSize;
+ }
+
+ void markShaderHasPrecise() { mHasAnyPreciseType = true; }
+ bool hasAnyPreciseType() const { return mHasAnyPreciseType; }
+ AdvancedBlendEquations getAdvancedBlendEquations() const { return mAdvancedBlendEquations; }
+
+ ShShaderOutput getOutputType() const { return mOutputType; }
+
+ // TODO(jmadill): make this private
+ TSymbolTable &symbolTable; // symbol table that goes with the language currently being parsed
+
+ private:
+ class AtomicCounterBindingState;
+ constexpr static size_t kAtomicCounterSize = 4;
+ // UNIFORM_ARRAY_STRIDE for atomic counter arrays is an implementation-dependent value which
+ // can be queried after a program is linked according to ES 3.10 section 7.7.1. This is
+ // controversial with the offset inheritance as described in ESSL 3.10 section 4.4.6. Currently
+ // we treat it as always 4 in favour of the original interpretation in
+ // "ARB_shader_atomic_counters".
+ // TODO(jie.a.chen@intel.com): Double check this once the spec vagueness is resolved.
+ // Note that there may be tests in AtomicCounter_test that will need to be updated as well.
+ constexpr static size_t kAtomicCounterArrayStride = 4;
+
+ void markStaticReadIfSymbol(TIntermNode *node);
+
+ // Returns a clamped index. If it prints out an error message, the token is "[]".
+ int checkIndexLessThan(bool outOfRangeIndexIsError,
+ const TSourceLoc &location,
+ int index,
+ int arraySize,
+ const char *reason);
+
+ bool declareVariable(const TSourceLoc &line,
+ const ImmutableString &identifier,
+ const TType *type,
+ TVariable **variable);
+
+ void checkCanBeDeclaredWithoutInitializer(const TSourceLoc &line,
+ const ImmutableString &identifier,
+ TType *type);
+
+ TParameter parseParameterDeclarator(TType *type,
+ const ImmutableString &name,
+ const TSourceLoc &nameLoc);
+
+ bool checkIsValidTypeAndQualifierForArray(const TSourceLoc &indexLocation,
+ const TPublicType &elementType);
+ // Done for all atomic counter declarations, whether empty or not.
+ void atomicCounterQualifierErrorCheck(const TPublicType &publicType,
+ const TSourceLoc &location);
+
+ // Assumes that multiplication op has already been set based on the types.
+ bool isMultiplicationTypeCombinationValid(TOperator op, const TType &left, const TType &right);
+
+ void checkOutParameterIsNotOpaqueType(const TSourceLoc &line,
+ TQualifier qualifier,
+ const TType &type);
+
+ void checkInternalFormatIsNotSpecified(const TSourceLoc &location,
+ TLayoutImageInternalFormat internalFormat);
+ void checkMemoryQualifierIsNotSpecified(const TMemoryQualifier &memoryQualifier,
+ const TSourceLoc &location);
+ void checkAtomicCounterOffsetDoesNotOverlap(bool forceAppend,
+ const TSourceLoc &loc,
+ TType *type);
+ void checkAtomicCounterOffsetAlignment(const TSourceLoc &location, const TType &type);
+
+ void checkIndexIsNotSpecified(const TSourceLoc &location, int index);
+ void checkBindingIsValid(const TSourceLoc &identifierLocation, const TType &type);
+ void checkBindingIsNotSpecified(const TSourceLoc &location, int binding);
+ void checkOffsetIsNotSpecified(const TSourceLoc &location, int offset);
+ void checkImageBindingIsValid(const TSourceLoc &location,
+ int binding,
+ int arrayTotalElementCount);
+ void checkSamplerBindingIsValid(const TSourceLoc &location,
+ int binding,
+ int arrayTotalElementCount);
+ void checkBlockBindingIsValid(const TSourceLoc &location,
+ const TQualifier &qualifier,
+ int binding,
+ int arraySize);
+ void checkAtomicCounterBindingIsValid(const TSourceLoc &location, int binding);
+ void checkPixelLocalStorageBindingIsValid(const TSourceLoc &, const TType &);
+
+ void checkUniformLocationInRange(const TSourceLoc &location,
+ int objectLocationCount,
+ const TLayoutQualifier &layoutQualifier);
+ void checkAttributeLocationInRange(const TSourceLoc &location,
+ int objectLocationCount,
+ const TLayoutQualifier &layoutQualifier);
+
+ void checkYuvIsNotSpecified(const TSourceLoc &location, bool yuv);
+
+ void checkEarlyFragmentTestsIsNotSpecified(const TSourceLoc &location, bool earlyFragmentTests);
+
+ void checkNoncoherentIsSpecified(const TSourceLoc &location, bool noncoherent);
+
+ void checkNoncoherentIsNotSpecified(const TSourceLoc &location, bool noncoherent);
+
+ bool checkUnsizedArrayConstructorArgumentDimensionality(const TIntermSequence &arguments,
+ TType type,
+ const TSourceLoc &line);
+
+ void checkCombinedClipCullDistanceIsValid(const TSourceLoc &line,
+ const ImmutableString &identifier,
+ const int arraySize);
+
+ // Check texture offset is within range.
+ void checkSingleTextureOffset(const TSourceLoc &line,
+ const TConstantUnion *values,
+ size_t size,
+ int minOffsetValue,
+ int maxOffsetValue);
+
+ // Will set the size of the outermost array according to geometry shader input layout.
+ void checkGeometryShaderInputAndSetArraySize(const TSourceLoc &location,
+ const ImmutableString &token,
+ TType *type);
+
+ // Similar, for tessellation shaders.
+ void checkTessellationShaderUnsizedArraysAndSetSize(const TSourceLoc &location,
+ const ImmutableString &token,
+ TType *type);
+
+ // Will size any unsized array type so unsized arrays won't need to be taken into account
+ // further along the line in parsing.
+ void checkIsNotUnsizedArray(const TSourceLoc &line,
+ const char *errorMessage,
+ const ImmutableString &token,
+ TType *arrayType);
+
+ TIntermTyped *addBinaryMathInternal(TOperator op,
+ TIntermTyped *left,
+ TIntermTyped *right,
+ const TSourceLoc &loc);
+ TIntermTyped *createUnaryMath(TOperator op,
+ TIntermTyped *child,
+ const TSourceLoc &loc,
+ const TFunction *func);
+
+ TIntermTyped *addMethod(TFunctionLookup *fnCall, const TSourceLoc &loc);
+ TIntermTyped *addConstructor(TFunctionLookup *fnCall, const TSourceLoc &line);
+ TIntermTyped *addNonConstructorFunctionCall(TFunctionLookup *fnCall, const TSourceLoc &loc);
+
+ // Return either the original expression or the folded version of the expression in case the
+ // folded node will validate the same way during subsequent parsing.
+ TIntermTyped *expressionOrFoldedResult(TIntermTyped *expression);
+
+ // Return true if the checks pass
+ bool binaryOpCommonCheck(TOperator op,
+ TIntermTyped *left,
+ TIntermTyped *right,
+ const TSourceLoc &loc);
+
+ TIntermFunctionPrototype *createPrototypeNodeFromFunction(const TFunction &function,
+ const TSourceLoc &location,
+ bool insertParametersToSymbolTable);
+
+ void setAtomicCounterBindingDefaultOffset(const TPublicType &declaration,
+ const TSourceLoc &location);
+
+ bool checkPrimitiveTypeMatchesTypeQualifier(const TTypeQualifier &typeQualifier);
+ bool parseGeometryShaderInputLayoutQualifier(const TTypeQualifier &typeQualifier);
+ bool parseGeometryShaderOutputLayoutQualifier(const TTypeQualifier &typeQualifier);
+ void setGeometryShaderInputArraySize(unsigned int inputArraySize, const TSourceLoc &line);
+
+ bool parseTessControlShaderOutputLayoutQualifier(const TTypeQualifier &typeQualifier);
+ bool parseTessEvaluationShaderInputLayoutQualifier(const TTypeQualifier &typeQualifier);
+
+ // Certain operations become illegal only iff the shader declares pixel local storage uniforms.
+ enum class PLSIllegalOperations
+ {
+ // When polyfilled with shader images, pixel local storage requires early_fragment_tests,
+ // which causes discard to interact differently with the depth and stencil tests.
+ //
+ // To ensure identical behavior across all backends (some of which may not have access to
+ // early_fragment_tests), we disallow discard if pixel local storage uniforms have been
+ // declared.
+ Discard,
+
+ // ARB_fragment_shader_interlock functions cannot be called within flow control, which
+ // includes any code that might execute after a return statement. To keep things simple, and
+ // since these "interlock" calls are automatically injected by the compiler inside of
+ // main(), we disallow return from main() if pixel local storage uniforms have been
+ // declared.
+ ReturnFromMain,
+
+ // When polyfilled with shader images, pixel local storage requires early_fragment_tests,
+ // which causes assignments to gl_FragDepth(EXT) and gl_SampleMask to be ignored.
+ //
+ // To ensure identical behavior across all backends, we disallow assignment to these values
+ // if pixel local storage uniforms have been declared.
+ AssignFragDepth,
+ AssignSampleMask
+ };
+
+ // Generates an error if any pixel local storage uniforms have been declared (more specifically,
+ // if mPLSBindings is not empty).
+ //
+ // If no pixel local storage uniforms have been declared, and if the PLS extension is enabled,
+ // saves the potential error to mPLSPotentialErrors in case we encounter a PLS uniform later.
+ void errorIfPLSDeclared(const TSourceLoc &, PLSIllegalOperations);
+
+ // Set to true when the last/current declarator list was started with an empty declaration. The
+ // non-empty declaration error check will need to be performed if the empty declaration is
+ // followed by a declarator.
+ bool mDeferredNonEmptyDeclarationErrorCheck;
+
+ sh::GLenum mShaderType; // vertex/fragment/geometry/etc shader
+ ShShaderSpec mShaderSpec; // The language specification compiler conforms to - GLES/WebGL/etc.
+ ShCompileOptions mCompileOptions; // Options passed to TCompiler
+ int mShaderVersion;
+ TIntermBlock *mTreeRoot; // root of parse tree being created
+ int mLoopNestingLevel; // 0 if outside all loops
+ 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
+ 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 mFragmentPrecisionHighOnESSL1; // true if highp precision is supported when compiling
+ // ESSL1.
+ bool mEarlyFragmentTestsSpecified; // true if |layout(early_fragment_tests) in| is specified.
+ bool mHasDiscard; // true if |discard| is encountered in the shader.
+ bool mSampleQualifierSpecified; // true if the |sample| qualifier is used.
+ TLayoutMatrixPacking mDefaultUniformMatrixPacking;
+ TLayoutBlockStorage mDefaultUniformBlockStorage;
+ TLayoutMatrixPacking mDefaultBufferMatrixPacking;
+ TLayoutBlockStorage mDefaultBufferBlockStorage;
+ TString mHashErrMsg;
+ TDiagnostics *mDiagnostics;
+ TDirectiveHandler mDirectiveHandler;
+ angle::pp::Preprocessor mPreprocessor;
+ void *mScanner;
+ int mMinProgramTexelOffset;
+ int mMaxProgramTexelOffset;
+
+ int mMinProgramTextureGatherOffset;
+ int mMaxProgramTextureGatherOffset;
+
+ // keep track of local group size declared in layout. It should be declared only once.
+ bool mComputeShaderLocalSizeDeclared;
+ sh::WorkGroupSize mComputeShaderLocalSize;
+ // keep track of number of views declared in layout.
+ int mNumViews;
+ int mMaxNumViews;
+ int mMaxImageUnits;
+ int mMaxCombinedTextureImageUnits;
+ int mMaxUniformLocations;
+ int mMaxUniformBufferBindings;
+ int mMaxVertexAttribs;
+ int mMaxAtomicCounterBindings;
+ int mMaxShaderStorageBufferBindings;
+
+ // keeps track whether we are declaring / defining a function
+ bool mDeclaringFunction;
+
+ // keeps track whether we are declaring / defining the function main().
+ bool mDeclaringMain;
+
+ // Track the state of each atomic counter binding.
+ std::map<int, AtomicCounterBindingState> mAtomicCounterBindingStates;
+
+ // Track the format of each pixel local storage binding.
+ std::map<int, TLayoutImageInternalFormat> mPLSBindings;
+
+ // Potential errors to generate immediately upon encountering a pixel local storage uniform.
+ std::vector<std::tuple<const TSourceLoc, PLSIllegalOperations>> mPLSPotentialErrors;
+
+ // Track the geometry shader global parameters declared in layout.
+ TLayoutPrimitiveType mGeometryShaderInputPrimitiveType;
+ TLayoutPrimitiveType mGeometryShaderOutputPrimitiveType;
+ int mGeometryShaderInvocations;
+ int mGeometryShaderMaxVertices;
+ int mMaxGeometryShaderInvocations;
+ int mMaxGeometryShaderMaxVertices;
+ unsigned int mGeometryInputArraySize;
+
+ int mMaxPatchVertices;
+ int mTessControlShaderOutputVertices;
+ TLayoutTessEvaluationType mTessEvaluationShaderInputPrimitiveType;
+ TLayoutTessEvaluationType mTessEvaluationShaderInputVertexSpacingType;
+ TLayoutTessEvaluationType mTessEvaluationShaderInputOrderingType;
+ TLayoutTessEvaluationType mTessEvaluationShaderInputPointType;
+ // List of array declarations without an explicit size that have come before layout(vertices=N).
+ // Once the vertex count is specified, these arrays are sized.
+ TVector<TType *> mDeferredArrayTypesToSize;
+ // Whether the |precise| keyword has been seen in the shader.
+ bool mHasAnyPreciseType;
+
+ AdvancedBlendEquations mAdvancedBlendEquations;
+
+ // Track when we add new scope for func body in ESSL 1.00 spec
+ bool mFunctionBodyNewScope;
+
+ ShShaderOutput mOutputType;
+};
+
+int PaParseStrings(size_t count,
+ const char *const string[],
+ const int length[],
+ TParseContext *context);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_PARSECONTEXT_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/PoolAlloc.cpp b/gfx/angle/checkout/src/compiler/translator/PoolAlloc.cpp
new file mode 100644
index 0000000000..1d770c6229
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/PoolAlloc.cpp
@@ -0,0 +1,40 @@
+//
+// Copyright 2002 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/PoolAlloc.h"
+
+#include "common/debug.h"
+#include "common/tls.h"
+
+TLSIndex PoolIndex = TLS_INVALID_INDEX;
+
+bool InitializePoolIndex()
+{
+ ASSERT(PoolIndex == TLS_INVALID_INDEX);
+
+ PoolIndex = CreateTLSIndex(nullptr);
+ return PoolIndex != TLS_INVALID_INDEX;
+}
+
+void FreePoolIndex()
+{
+ ASSERT(PoolIndex != TLS_INVALID_INDEX);
+
+ DestroyTLSIndex(PoolIndex);
+ PoolIndex = TLS_INVALID_INDEX;
+}
+
+angle::PoolAllocator *GetGlobalPoolAllocator()
+{
+ ASSERT(PoolIndex != TLS_INVALID_INDEX);
+ return static_cast<angle::PoolAllocator *>(GetTLSValue(PoolIndex));
+}
+
+void SetGlobalPoolAllocator(angle::PoolAllocator *poolAllocator)
+{
+ ASSERT(PoolIndex != TLS_INVALID_INDEX);
+ SetTLSValue(PoolIndex, poolAllocator);
+}
diff --git a/gfx/angle/checkout/src/compiler/translator/PoolAlloc.h b/gfx/angle/checkout/src/compiler/translator/PoolAlloc.h
new file mode 100644
index 0000000000..98f549b179
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/PoolAlloc.h
@@ -0,0 +1,102 @@
+//
+// Copyright 2002 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_POOLALLOC_H_
+#define COMPILER_TRANSLATOR_POOLALLOC_H_
+
+//
+// This header defines the pool_allocator class that allows STL containers
+// to use the angle::PoolAllocator class by using the pool_allocator
+// class as the allocator (second) template argument.
+//
+// It also defines functions for managing the GlobalPoolAllocator used by the compiler.
+//
+
+#include <stddef.h>
+#include <string.h>
+#include <vector>
+
+#include "common/PoolAlloc.h"
+
+//
+// There could potentially be many pools with pops happening at
+// different times. But a simple use is to have a global pop
+// with everyone using the same global allocator.
+//
+extern angle::PoolAllocator *GetGlobalPoolAllocator();
+extern void SetGlobalPoolAllocator(angle::PoolAllocator *poolAllocator);
+
+//
+// This STL compatible allocator is intended to be used as the allocator
+// parameter to templatized STL containers, like vector and map.
+//
+// It will use the pools for allocation, and not
+// do any deallocation, but will still do destruction.
+//
+template <class T>
+class pool_allocator
+{
+ public:
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef T *pointer;
+ typedef const T *const_pointer;
+ typedef T &reference;
+ typedef const T &const_reference;
+ typedef T value_type;
+
+ template <class Other>
+ struct rebind
+ {
+ typedef pool_allocator<Other> other;
+ };
+ pointer address(reference x) const { return &x; }
+ const_pointer address(const_reference x) const { return &x; }
+
+ pool_allocator() {}
+
+ template <class Other>
+ pool_allocator(const pool_allocator<Other> &p)
+ {}
+
+ template <class Other>
+ pool_allocator<T> &operator=(const pool_allocator<Other> &p)
+ {
+ return *this;
+ }
+
+#if defined(__SUNPRO_CC) && !defined(_RWSTD_ALLOCATOR)
+ // libCStd on some platforms have a different allocate/deallocate interface.
+ // Caller pre-bakes sizeof(T) into 'n' which is the number of bytes to be
+ // allocated, not the number of elements.
+ void *allocate(size_type n) { return getAllocator().allocate(n); }
+ void *allocate(size_type n, const void *) { return getAllocator().allocate(n); }
+ void deallocate(void *, size_type) {}
+#else
+ pointer allocate(size_type n)
+ {
+ return static_cast<pointer>(getAllocator().allocate(n * sizeof(T)));
+ }
+ pointer allocate(size_type n, const void *)
+ {
+ return static_cast<pointer>(getAllocator().allocate(n * sizeof(T)));
+ }
+ void deallocate(pointer, size_type) {}
+#endif // _RWSTD_ALLOCATOR
+
+ void construct(pointer p, const T &val) { new ((void *)p) T(val); }
+ void destroy(pointer p) { p->T::~T(); }
+
+ bool operator==(const pool_allocator &rhs) const { return true; }
+ bool operator!=(const pool_allocator &rhs) const { return false; }
+
+ size_type max_size() const { return static_cast<size_type>(-1) / sizeof(T); }
+ size_type max_size(int size) const { return static_cast<size_type>(-1) / size; }
+
+ angle::PoolAllocator &getAllocator() const { return *GetGlobalPoolAllocator(); }
+};
+
+#endif // COMPILER_TRANSLATOR_POOLALLOC_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/Pragma.h b/gfx/angle/checkout/src/compiler/translator/Pragma.h
new file mode 100644
index 0000000000..c3f5ca2f46
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/Pragma.h
@@ -0,0 +1,28 @@
+//
+// Copyright 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_PRAGMA_H_
+#define COMPILER_TRANSLATOR_PRAGMA_H_
+
+struct TPragma
+{
+ struct STDGL
+ {
+ STDGL() : invariantAll(false) {}
+
+ bool invariantAll;
+ };
+
+ // By default optimization is turned on and debug is turned off.
+ TPragma() : optimize(true), debug(false) {}
+ TPragma(bool o, bool d) : optimize(o), debug(d) {}
+
+ bool optimize;
+ bool debug;
+ STDGL stdgl;
+};
+
+#endif // COMPILER_TRANSLATOR_PRAGMA_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/QualifierTypes.cpp b/gfx/angle/checkout/src/compiler/translator/QualifierTypes.cpp
new file mode 100644
index 0000000000..e524146cd3
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/QualifierTypes.cpp
@@ -0,0 +1,1007 @@
+//
+// Copyright 2002 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 "compiler/translator/ImmutableStringBuilder.h"
+
+#include <algorithm>
+
+namespace sh
+{
+
+namespace
+{
+
+constexpr const ImmutableString kSpecifiedMultipleTimes(" specified multiple times");
+constexpr const ImmutableString kInvariantMultipleTimes(
+ "The invariant qualifier specified multiple times.");
+constexpr const ImmutableString kPreciseMultipleTimes(
+ "The precise qualifier specified multiple times.");
+constexpr const ImmutableString kPrecisionMultipleTimes(
+ "The precision qualifier specified multiple times.");
+constexpr const ImmutableString kLayoutMultipleTimes(
+ "The layout qualifier specified multiple times.");
+constexpr const ImmutableString kLayoutAndInvariantDisallowed(
+ "The layout qualifier and invariant qualifier cannot coexist in the same "
+ "declaration according to the grammar.");
+constexpr const ImmutableString kInterpolationMultipleTimes(
+ "The interpolation qualifier specified multiple times.");
+constexpr const ImmutableString kOutputLayoutMultipleTimes(
+ "Output layout location specified multiple times.");
+constexpr const ImmutableString kInvariantQualifierFirst(
+ "The invariant qualifier has to be first in the expression.");
+constexpr const ImmutableString kStorageAfterInterpolation(
+ "Storage qualifiers have to be after interpolation qualifiers.");
+constexpr const ImmutableString kPrecisionAfterInterpolation(
+ "Precision qualifiers have to be after interpolation qualifiers.");
+constexpr const ImmutableString kStorageAfterLayout(
+ "Storage qualifiers have to be after layout qualifiers.");
+constexpr const ImmutableString kPrecisionAfterLayout(
+ "Precision qualifiers have to be after layout qualifiers.");
+constexpr const ImmutableString kPrecisionAfterStorage(
+ "Precision qualifiers have to be after storage qualifiers.");
+constexpr const ImmutableString kPrecisionAfterMemory(
+ "Precision qualifiers have to be after memory qualifiers.");
+
+// 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;
+}
+
+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/precise 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]);
+}
+
+ImmutableString QualifierSpecifiedMultipleTimesErrorMessage(const ImmutableString &qualifierString)
+{
+ ImmutableStringBuilder errorMsg(qualifierString.length() + kSpecifiedMultipleTimes.length());
+ errorMsg << qualifierString << kSpecifiedMultipleTimes;
+ return errorMsg;
+}
+
+// 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,
+ ImmutableString *errorMessage)
+{
+ bool invariantFound = false;
+ bool preciseFound = 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 = kInvariantMultipleTimes;
+ return true;
+ }
+ invariantFound = true;
+ break;
+ }
+ case QtPrecise:
+ {
+ if (preciseFound)
+ {
+ *errorMessage = kPreciseMultipleTimes;
+ return true;
+ }
+ preciseFound = true;
+ break;
+ }
+ case QtPrecision:
+ {
+ if (precisionFound)
+ {
+ *errorMessage = kPrecisionMultipleTimes;
+ return true;
+ }
+ precisionFound = true;
+ break;
+ }
+ case QtLayout:
+ {
+ if (layoutFound && !areQualifierChecksRelaxed)
+ {
+ *errorMessage = kLayoutMultipleTimes;
+ 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 = kLayoutAndInvariantDisallowed;
+ return true;
+ }
+ layoutFound = true;
+ const TLayoutQualifier &currentQualifier =
+ 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 = kInterpolationMultipleTimes;
+ 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 ||
+ currentQualifier == EvqFragmentInOut)
+ {
+ 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 = QualifierSpecifiedMultipleTimesErrorMessage(
+ previousQualifierWrapper->getQualifierString());
+ return true;
+ }
+ }
+ }
+ break;
+ }
+ case QtMemory:
+ {
+ // Go over all of the memory qualifiers up until the current one and check for
+ // repetitions.
+ // Having both readonly and writeonly in a sequence is valid.
+ // GLSL ES 3.10 Revision 4, 4.9 Memory Access Qualifiers
+ TQualifier currentQualifier =
+ static_cast<const TMemoryQualifierWrapper *>(qualifiers[i])->getQualifier();
+ for (size_t j = 1; j < i; ++j)
+ {
+ if (qualifiers[j]->getType() == QtMemory)
+ {
+ const TMemoryQualifierWrapper *previousQualifierWrapper =
+ static_cast<const TMemoryQualifierWrapper *>(qualifiers[j]);
+ TQualifier previousQualifier = previousQualifierWrapper->getQualifier();
+ if (currentQualifier == previousQualifier)
+ {
+ *errorMessage = QualifierSpecifiedMultipleTimesErrorMessage(
+ previousQualifierWrapper->getQualifierString());
+ 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 = kOutputLayoutMultipleTimes;
+ 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.
+//
+// GLSL ES 3.1 relaxes the order of qualification:
+// When multiple qualifiers are present in a declaration, they may appear in any order, but they
+// must all appear before the type.
+bool AreQualifiersInOrder(const TTypeQualifierBuilder::QualifierSequence &qualifiers,
+ int shaderVersion,
+ ImmutableString *errorMessage)
+{
+ if (shaderVersion >= 310)
+ {
+ return true;
+ }
+
+ 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 = kInvariantQualifierFirst;
+ return false;
+ }
+ break;
+ case QtInterpolation:
+ if (foundStorage)
+ {
+ *errorMessage = kStorageAfterInterpolation;
+ return false;
+ }
+ else if (foundPrecision)
+ {
+ *errorMessage = kPrecisionAfterInterpolation;
+ return false;
+ }
+ foundInterpolation = true;
+ break;
+ case QtLayout:
+ if (foundStorage)
+ {
+ *errorMessage = kStorageAfterLayout;
+ return false;
+ }
+ else if (foundPrecision)
+ {
+ *errorMessage = kPrecisionAfterLayout;
+ return false;
+ }
+ break;
+ case QtStorage:
+ if (foundPrecision)
+ {
+ *errorMessage = kPrecisionAfterStorage;
+ return false;
+ }
+ foundStorage = true;
+ break;
+ case QtMemory:
+ if (foundPrecision)
+ {
+ *errorMessage = kPrecisionAfterMemory;
+ return false;
+ }
+ break;
+ case QtPrecision:
+ foundPrecision = true;
+ break;
+ case QtPrecise:
+ // This keyword is available in ES3.1 (with extension) or in ES3.2, but the function
+ // should early-out in such a case as the spec doesn't require a particular order to
+ // the qualifiers.
+ UNREACHABLE();
+ 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:
+ case EvqGeometryOut:
+ case EvqTessControlOut:
+ case EvqTessEvaluationOut:
+ *joinedQualifier = EvqSmoothOut;
+ break;
+ case EvqFragmentIn:
+ case EvqGeometryIn:
+ case EvqTessControlIn:
+ case EvqTessEvaluationIn:
+ *joinedQualifier = EvqSmoothIn;
+ break;
+ default:
+ return false;
+ }
+ break;
+ }
+ case EvqFlat:
+ {
+ switch (storageQualifier)
+ {
+ case EvqCentroid:
+ *joinedQualifier = EvqFlat;
+ break;
+ case EvqVertexOut:
+ case EvqGeometryOut:
+ case EvqTessControlOut:
+ case EvqTessEvaluationOut:
+ *joinedQualifier = EvqFlatOut;
+ break;
+ case EvqFragmentIn:
+ case EvqGeometryIn:
+ case EvqTessControlIn:
+ case EvqTessEvaluationIn:
+ *joinedQualifier = EvqFlatIn;
+ break;
+ default:
+ return false;
+ }
+ break;
+ }
+ case EvqNoPerspective:
+ {
+ switch (storageQualifier)
+ {
+ case EvqCentroid:
+ *joinedQualifier = EvqNoPerspective;
+ break;
+ case EvqVertexOut:
+ case EvqGeometryOut:
+ case EvqTessControlOut:
+ case EvqTessEvaluationOut:
+ *joinedQualifier = EvqNoPerspectiveOut;
+ break;
+ case EvqFragmentIn:
+ case EvqGeometryIn:
+ case EvqTessControlIn:
+ case EvqTessEvaluationIn:
+ *joinedQualifier = EvqNoPerspectiveIn;
+ break;
+ default:
+ return false;
+ }
+ break;
+ }
+ case EvqCentroid:
+ {
+ switch (storageQualifier)
+ {
+ case EvqVertexOut:
+ case EvqGeometryOut:
+ case EvqTessControlOut:
+ case EvqTessEvaluationOut:
+ *joinedQualifier = EvqCentroidOut;
+ break;
+ case EvqFragmentIn:
+ case EvqGeometryIn:
+ case EvqTessControlIn:
+ case EvqTessEvaluationIn:
+ *joinedQualifier = EvqCentroidIn;
+ break;
+ default:
+ return false;
+ }
+ break;
+ }
+ case EvqSample:
+ {
+ switch (storageQualifier)
+ {
+ case EvqVertexOut:
+ case EvqGeometryOut:
+ case EvqTessControlOut:
+ case EvqTessEvaluationOut:
+ *joinedQualifier = EvqSampleOut;
+ break;
+ case EvqFragmentIn:
+ case EvqGeometryIn:
+ case EvqTessControlIn:
+ case EvqTessEvaluationIn:
+ *joinedQualifier = EvqSampleIn;
+ break;
+ default:
+ return false;
+ }
+ break;
+ }
+ case EvqPatch:
+ {
+ switch (storageQualifier)
+ {
+ case EvqTessControlOut:
+ *joinedQualifier = EvqPatchOut;
+ break;
+ case EvqTessEvaluationIn:
+ *joinedQualifier = EvqPatchIn;
+ 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 EvqParamIn:
+ *joinedQualifier = EvqParamConst;
+ break;
+ default:
+ return false;
+ }
+ break;
+ }
+ default:
+ return false;
+ }
+ return true;
+}
+
+bool JoinMemoryQualifier(TMemoryQualifier *joinedMemoryQualifier, TQualifier memoryQualifier)
+{
+ switch (memoryQualifier)
+ {
+ case EvqReadOnly:
+ joinedMemoryQualifier->readonly = true;
+ break;
+ case EvqWriteOnly:
+ joinedMemoryQualifier->writeonly = true;
+ break;
+ case EvqCoherent:
+ joinedMemoryQualifier->coherent = true;
+ break;
+ case EvqRestrict:
+ joinedMemoryQualifier->restrictQualifier = true;
+ break;
+ case EvqVolatile:
+ // Variables having the volatile qualifier are automatcally treated as coherent as well.
+ // GLSL ES 3.10, Revision 4, 4.9 Memory Access Qualifiers
+ joinedMemoryQualifier->volatileQualifier = true;
+ joinedMemoryQualifier->coherent = true;
+ break;
+ default:
+ UNREACHABLE();
+ }
+ 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 QtPrecise:
+ isQualifierValid = true;
+ typeQualifier.precise = 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;
+ case QtMemory:
+ isQualifierValid = JoinMemoryQualifier(
+ &typeQualifier.memoryQualifier,
+ static_cast<const TMemoryQualifierWrapper *>(qualifier)->getQualifier());
+ break;
+ default:
+ UNREACHABLE();
+ }
+ if (!isQualifierValid)
+ {
+ const ImmutableString &qualifierString = qualifier->getQualifierString();
+ diagnostics->error(qualifier->getLine(), "invalid qualifier combination",
+ qualifierString.data());
+ break;
+ }
+ }
+ return typeQualifier;
+}
+
+TTypeQualifier GetParameterTypeQualifierFromSortedSequence(
+ TBasicType parameterBasicType,
+ 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 QtMemory:
+ isQualifierValid = JoinMemoryQualifier(
+ &typeQualifier.memoryQualifier,
+ static_cast<const TMemoryQualifierWrapper *>(qualifier)->getQualifier());
+ 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;
+ case QtPrecise:
+ isQualifierValid = true;
+ typeQualifier.precise = true;
+ break;
+ default:
+ UNREACHABLE();
+ }
+ if (!isQualifierValid)
+ {
+ const ImmutableString &qualifierString = qualifier->getQualifierString();
+ diagnostics->error(qualifier->getLine(), "invalid parameter qualifier",
+ qualifierString.data());
+ break;
+ }
+ }
+
+ switch (typeQualifier.qualifier)
+ {
+ case EvqParamIn:
+ case EvqParamConst: // const in
+ case EvqParamOut:
+ case EvqParamInOut:
+ break;
+ case EvqConst:
+ // Opaque parameters can only be |in|. |const| is allowed, but is meaningless and is
+ // dropped.
+ typeQualifier.qualifier = IsOpaqueType(parameterBasicType) ? EvqParamIn : EvqParamConst;
+ break;
+ case EvqTemporary:
+ // no qualifier has been specified, set it to EvqParamIn which is the default
+ typeQualifier.qualifier = EvqParamIn;
+ break;
+ default:
+ diagnostics->error(sortedSequence[0]->getLine(), "Invalid parameter qualifier ",
+ getQualifierString(typeQualifier.qualifier));
+ }
+ return typeQualifier;
+}
+} // namespace
+
+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.yuv != false)
+ {
+ joinedQualifier.yuv = rightQualifier.yuv;
+ }
+ if (rightQualifier.earlyFragmentTests != false)
+ {
+ joinedQualifier.earlyFragmentTests = rightQualifier.earlyFragmentTests;
+ }
+ if (rightQualifier.binding != -1)
+ {
+ joinedQualifier.binding = rightQualifier.binding;
+ }
+ if (rightQualifier.offset != -1)
+ {
+ joinedQualifier.offset = rightQualifier.offset;
+ }
+ if (rightQualifier.matrixPacking != EmpUnspecified)
+ {
+ joinedQualifier.matrixPacking = rightQualifier.matrixPacking;
+ }
+ if (rightQualifier.blockStorage != EbsUnspecified)
+ {
+ joinedQualifier.blockStorage = rightQualifier.blockStorage;
+ }
+ if (rightQualifier.noncoherent != false)
+ {
+ joinedQualifier.noncoherent = rightQualifier.noncoherent;
+ }
+
+ 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];
+ }
+ }
+
+ if (rightQualifier.numViews != -1)
+ {
+ joinedQualifier.numViews = rightQualifier.numViews;
+ }
+
+ if (rightQualifier.imageInternalFormat != EiifUnspecified)
+ {
+ joinedQualifier.imageInternalFormat = rightQualifier.imageInternalFormat;
+ }
+
+ if (rightQualifier.primitiveType != EptUndefined)
+ {
+ if (joinedQualifier.primitiveType != EptUndefined &&
+ joinedQualifier.primitiveType != rightQualifier.primitiveType)
+ {
+ diagnostics->error(rightQualifierLocation,
+ "Cannot have multiple different primitive specifiers",
+ getGeometryShaderPrimitiveTypeString(rightQualifier.primitiveType));
+ }
+ joinedQualifier.primitiveType = rightQualifier.primitiveType;
+ }
+
+ if (rightQualifier.invocations != 0)
+ {
+ if (joinedQualifier.invocations != 0 &&
+ joinedQualifier.invocations != rightQualifier.invocations)
+ {
+ diagnostics->error(rightQualifierLocation,
+ "Cannot have multiple different invocations specifiers",
+ "invocations");
+ }
+ joinedQualifier.invocations = rightQualifier.invocations;
+ }
+
+ if (rightQualifier.maxVertices != -1)
+ {
+ if (joinedQualifier.maxVertices != -1 &&
+ joinedQualifier.maxVertices != rightQualifier.maxVertices)
+ {
+ diagnostics->error(rightQualifierLocation,
+ "Cannot have multiple different max_vertices specifiers",
+ "max_vertices");
+ }
+ joinedQualifier.maxVertices = rightQualifier.maxVertices;
+ }
+
+ if (rightQualifier.tesPrimitiveType != EtetUndefined)
+ {
+ if (joinedQualifier.tesPrimitiveType == EtetUndefined)
+ {
+ joinedQualifier.tesPrimitiveType = rightQualifier.tesPrimitiveType;
+ }
+ }
+
+ if (rightQualifier.tesVertexSpacingType != EtetUndefined)
+ {
+ if (joinedQualifier.tesVertexSpacingType == EtetUndefined)
+ {
+ joinedQualifier.tesVertexSpacingType = rightQualifier.tesVertexSpacingType;
+ }
+ }
+
+ if (rightQualifier.tesOrderingType != EtetUndefined)
+ {
+ if (joinedQualifier.tesOrderingType == EtetUndefined)
+ {
+ joinedQualifier.tesOrderingType = rightQualifier.tesOrderingType;
+ }
+ }
+
+ if (rightQualifier.tesPointType != EtetUndefined)
+ {
+ if (joinedQualifier.tesPointType == EtetUndefined)
+ {
+ joinedQualifier.tesPointType = rightQualifier.tesPointType;
+ }
+ }
+
+ if (rightQualifier.vertices != 0)
+ {
+ if (joinedQualifier.vertices != 0 && joinedQualifier.vertices != rightQualifier.vertices)
+ {
+ diagnostics->error(rightQualifierLocation,
+ "Cannot have multiple different vertices specifiers", "vertices");
+ }
+ joinedQualifier.vertices = rightQualifier.vertices;
+ }
+
+ if (rightQualifier.index != -1)
+ {
+ if (joinedQualifier.index != -1)
+ {
+ // EXT_blend_func_extended spec: "Each of these qualifiers may appear at most once"
+ diagnostics->error(rightQualifierLocation, "Cannot have multiple index specifiers",
+ "index");
+ }
+ joinedQualifier.index = rightQualifier.index;
+ }
+
+ if (rightQualifier.advancedBlendEquations.any())
+ {
+ joinedQualifier.advancedBlendEquations |= rightQualifier.advancedBlendEquations;
+ }
+
+ return joinedQualifier;
+}
+
+unsigned int TInvariantQualifierWrapper::getRank() const
+{
+ return 0u;
+}
+
+unsigned int TPreciseQualifierWrapper::getRank() const
+{
+ return 1u;
+}
+
+unsigned int TInterpolationQualifierWrapper::getRank() const
+{
+ return 2u;
+}
+
+unsigned int TLayoutQualifierWrapper::getRank() const
+{
+ return 3u;
+}
+
+unsigned int TStorageQualifierWrapper::getRank() const
+{
+ // Force the 'centroid' auxilary storage qualifier to be always first among all storage
+ // qualifiers.
+ if (mStorageQualifier == EvqCentroid)
+ {
+ return 4u;
+ }
+ else
+ {
+ return 5u;
+ }
+}
+
+unsigned int TMemoryQualifierWrapper::getRank() const
+{
+ return 5u;
+}
+
+unsigned int TPrecisionQualifierWrapper::getRank() const
+{
+ return 6u;
+}
+
+TTypeQualifier::TTypeQualifier(TQualifier scope, const TSourceLoc &loc)
+ : layoutQualifier(TLayoutQualifier::Create()),
+ memoryQualifier(TMemoryQualifier::Create()),
+ precision(EbpUndefined),
+ qualifier(scope),
+ invariant(false),
+ precise(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);
+ ImmutableString errorMessage("");
+ if (HasRepeatingQualifiers(mQualifiers, areQualifierChecksRelaxed, &errorMessage))
+ {
+ diagnostics->error(mQualifiers[0]->getLine(), errorMessage.data(), "qualifier sequence");
+ return false;
+ }
+
+ if (!areQualifierChecksRelaxed &&
+ !AreQualifiersInOrder(mQualifiers, mShaderVersion, &errorMessage))
+ {
+ diagnostics->error(mQualifiers[0]->getLine(), errorMessage.data(), "qualifier sequence");
+ return false;
+ }
+
+ return true;
+}
+
+TTypeQualifier TTypeQualifierBuilder::getParameterTypeQualifier(TBasicType parameterBasicType,
+ 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(parameterBasicType,
+ sortedQualifierSequence, diagnostics);
+ }
+ return GetParameterTypeQualifierFromSortedSequence(parameterBasicType, 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);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/QualifierTypes.h b/gfx/angle/checkout/src/compiler/translator/QualifierTypes.h
new file mode 100644
index 0000000000..b98f300ce8
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/QualifierTypes.h
@@ -0,0 +1,214 @@
+//
+// Copyright 2002 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/ImmutableString.h"
+#include "compiler/translator/Types.h"
+
+namespace sh
+{
+class TDiagnostics;
+
+TLayoutQualifier JoinLayoutQualifiers(TLayoutQualifier leftQualifier,
+ TLayoutQualifier rightQualifier,
+ const TSourceLoc &rightQualifierLocation,
+ TDiagnostics *diagnostics);
+
+enum TQualifierType
+{
+ QtInvariant,
+ QtPrecise,
+ QtInterpolation,
+ QtLayout,
+ QtStorage,
+ QtPrecision,
+ QtMemory
+};
+
+class TQualifierWrapperBase : angle::NonCopyable
+{
+ public:
+ POOL_ALLOCATOR_NEW_DELETE
+ TQualifierWrapperBase(const TSourceLoc &line) : mLine(line) {}
+ virtual ~TQualifierWrapperBase() {}
+ virtual TQualifierType getType() const = 0;
+ virtual ImmutableString 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() override {}
+
+ TQualifierType getType() const override { return QtInvariant; }
+ ImmutableString getQualifierString() const override { return ImmutableString("invariant"); }
+ unsigned int getRank() const override;
+};
+
+class TPreciseQualifierWrapper final : public TQualifierWrapperBase
+{
+ public:
+ TPreciseQualifierWrapper(const TSourceLoc &line) : TQualifierWrapperBase(line) {}
+ ~TPreciseQualifierWrapper() override {}
+
+ TQualifierType getType() const override { return QtPrecise; }
+ ImmutableString getQualifierString() const override { return ImmutableString("precise"); }
+ unsigned int getRank() const override;
+};
+
+class TInterpolationQualifierWrapper final : public TQualifierWrapperBase
+{
+ public:
+ TInterpolationQualifierWrapper(TQualifier interpolationQualifier, const TSourceLoc &line)
+ : TQualifierWrapperBase(line), mInterpolationQualifier(interpolationQualifier)
+ {}
+ ~TInterpolationQualifierWrapper() override {}
+
+ TQualifierType getType() const override { return QtInterpolation; }
+ ImmutableString getQualifierString() const override
+ {
+ return ImmutableString(sh::getQualifierString(mInterpolationQualifier));
+ }
+ TQualifier getQualifier() const { return mInterpolationQualifier; }
+ unsigned int getRank() const override;
+
+ private:
+ TQualifier mInterpolationQualifier;
+};
+
+class TLayoutQualifierWrapper final : public TQualifierWrapperBase
+{
+ public:
+ TLayoutQualifierWrapper(TLayoutQualifier layoutQualifier, const TSourceLoc &line)
+ : TQualifierWrapperBase(line), mLayoutQualifier(layoutQualifier)
+ {}
+ ~TLayoutQualifierWrapper() override {}
+
+ TQualifierType getType() const override { return QtLayout; }
+ ImmutableString getQualifierString() const override { return ImmutableString("layout"); }
+ const TLayoutQualifier &getQualifier() const { return mLayoutQualifier; }
+ unsigned int getRank() const override;
+
+ private:
+ TLayoutQualifier mLayoutQualifier;
+};
+
+class TStorageQualifierWrapper final : public TQualifierWrapperBase
+{
+ public:
+ TStorageQualifierWrapper(TQualifier storageQualifier, const TSourceLoc &line)
+ : TQualifierWrapperBase(line), mStorageQualifier(storageQualifier)
+ {}
+ ~TStorageQualifierWrapper() override {}
+
+ TQualifierType getType() const override { return QtStorage; }
+ ImmutableString getQualifierString() const override
+ {
+ return ImmutableString(sh::getQualifierString(mStorageQualifier));
+ }
+ TQualifier getQualifier() const { return mStorageQualifier; }
+ unsigned int getRank() const override;
+
+ private:
+ TQualifier mStorageQualifier;
+};
+
+class TPrecisionQualifierWrapper final : public TQualifierWrapperBase
+{
+ public:
+ TPrecisionQualifierWrapper(TPrecision precisionQualifier, const TSourceLoc &line)
+ : TQualifierWrapperBase(line), mPrecisionQualifier(precisionQualifier)
+ {}
+ ~TPrecisionQualifierWrapper() override {}
+
+ TQualifierType getType() const override { return QtPrecision; }
+ ImmutableString getQualifierString() const override
+ {
+ return ImmutableString(sh::getPrecisionString(mPrecisionQualifier));
+ }
+ TPrecision getQualifier() const { return mPrecisionQualifier; }
+ unsigned int getRank() const override;
+
+ private:
+ TPrecision mPrecisionQualifier;
+};
+
+class TMemoryQualifierWrapper final : public TQualifierWrapperBase
+{
+ public:
+ TMemoryQualifierWrapper(TQualifier memoryQualifier, const TSourceLoc &line)
+ : TQualifierWrapperBase(line), mMemoryQualifier(memoryQualifier)
+ {}
+ ~TMemoryQualifierWrapper() override {}
+
+ TQualifierType getType() const override { return QtMemory; }
+ ImmutableString getQualifierString() const override
+ {
+ return ImmutableString(sh::getQualifierString(mMemoryQualifier));
+ }
+ TQualifier getQualifier() const { return mMemoryQualifier; }
+ unsigned int getRank() const override;
+
+ private:
+ TQualifier mMemoryQualifier;
+};
+
+// 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;
+ TMemoryQualifier memoryQualifier;
+ TPrecision precision;
+ TQualifier qualifier;
+ bool invariant;
+ bool precise;
+ 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(TBasicType parameterBasicType,
+ 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;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_QUALIFIER_TYPES_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/ResourcesHLSL.cpp b/gfx/angle/checkout/src/compiler/translator/ResourcesHLSL.cpp
new file mode 100644
index 0000000000..e43bd44d4a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ResourcesHLSL.cpp
@@ -0,0 +1,989 @@
+//
+// 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.
+//
+// ResourcesHLSL.cpp:
+// Methods for GLSL to HLSL translation for uniforms and interface blocks.
+//
+
+#include "compiler/translator/ResourcesHLSL.h"
+
+#include "common/utilities.h"
+#include "compiler/translator/AtomicCounterFunctionHLSL.h"
+#include "compiler/translator/ImmutableStringBuilder.h"
+#include "compiler/translator/StructureHLSL.h"
+#include "compiler/translator/UtilsHLSL.h"
+#include "compiler/translator/blocklayoutHLSL.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+constexpr const ImmutableString kAngleDecorString("angle_");
+
+static const char *UniformRegisterPrefix(const TType &type)
+{
+ if (IsSampler(type.getBasicType()))
+ {
+ return "s";
+ }
+ else
+ {
+ return "c";
+ }
+}
+
+static TString InterfaceBlockFieldTypeString(const TField &field,
+ TLayoutBlockStorage blockStorage,
+ bool usedStructuredbuffer)
+{
+ const TType &fieldType = *field.type();
+ const TLayoutMatrixPacking matrixPacking = fieldType.getLayoutQualifier().matrixPacking;
+ ASSERT(matrixPacking != EmpUnspecified);
+ const TStructure *structure = fieldType.getStruct();
+
+ if (fieldType.isMatrix())
+ {
+ // Use HLSL row-major packing for GLSL column-major matrices
+ const TString &matrixPackString =
+ (matrixPacking == EmpRowMajor ? "column_major" : "row_major");
+ return matrixPackString + " " + TypeString(fieldType);
+ }
+ else if (structure)
+ {
+ // If uniform block's layout is std140 and translating it to StructuredBuffer,
+ // should pack structure in the end, in order to fit API buffer.
+ bool forcePackingEnd = usedStructuredbuffer && (blockStorage == EbsStd140);
+ // Use HLSL row-major packing for GLSL column-major matrices
+ return QualifiedStructNameString(*structure, matrixPacking == EmpColumnMajor,
+ blockStorage == EbsStd140, forcePackingEnd);
+ }
+ else
+ {
+ return TypeString(fieldType);
+ }
+}
+
+static TString InterfaceBlockStructName(const TInterfaceBlock &interfaceBlock)
+{
+ return DecoratePrivate(interfaceBlock.name()) + "_type";
+}
+
+void OutputUniformIndexArrayInitializer(TInfoSinkBase &out,
+ const TType &type,
+ unsigned int startIndex)
+{
+ out << "{";
+ TType elementType(type);
+ elementType.toArrayElementType();
+ for (unsigned int i = 0u; i < type.getOutermostArraySize(); ++i)
+ {
+ if (i > 0u)
+ {
+ out << ", ";
+ }
+ if (elementType.isArray())
+ {
+ OutputUniformIndexArrayInitializer(out, elementType,
+ startIndex + i * elementType.getArraySizeProduct());
+ }
+ else
+ {
+ out << (startIndex + i);
+ }
+ }
+ out << "}";
+}
+
+static TString InterfaceBlockScalarVectorFieldPaddingString(const TType &type)
+{
+ switch (type.getBasicType())
+ {
+ case EbtFloat:
+ switch (type.getNominalSize())
+ {
+ case 1:
+ return "float3 padding;";
+ case 2:
+ return "float2 padding;";
+ case 3:
+ return "float padding;";
+ default:
+ break;
+ }
+ break;
+ case EbtInt:
+ switch (type.getNominalSize())
+ {
+ case 1:
+ return "int3 padding;";
+ case 2:
+ return "int2 padding;";
+ case 3:
+ return "int padding";
+ default:
+ break;
+ }
+ break;
+ case EbtUInt:
+ switch (type.getNominalSize())
+ {
+ case 1:
+ return "uint3 padding;";
+ case 2:
+ return "uint2 padding;";
+ case 3:
+ return "uint padding;";
+ default:
+ break;
+ }
+ break;
+ case EbtBool:
+ switch (type.getNominalSize())
+ {
+ case 1:
+ return "bool3 padding;";
+ case 2:
+ return "bool2 padding;";
+ case 3:
+ return "bool padding;";
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ return "";
+}
+
+static bool IsAnyRasterOrdered(const TVector<const TVariable *> &imageVars)
+{
+ for (const TVariable *imageVar : imageVars)
+ {
+ if (imageVar->getType().getLayoutQualifier().rasterOrdered)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+} // anonymous namespace
+
+ResourcesHLSL::ResourcesHLSL(StructureHLSL *structureHLSL,
+ ShShaderOutput outputType,
+ const std::vector<ShaderVariable> &uniforms,
+ unsigned int firstUniformRegister)
+ : mUniformRegister(firstUniformRegister),
+ mUniformBlockRegister(0),
+ mSRVRegister(0),
+ mUAVRegister(0),
+ mSamplerCount(0),
+ mStructureHLSL(structureHLSL),
+ mOutputType(outputType),
+ mUniforms(uniforms)
+{}
+
+void ResourcesHLSL::reserveUniformRegisters(unsigned int registerCount)
+{
+ mUniformRegister = registerCount;
+}
+
+void ResourcesHLSL::reserveUniformBlockRegisters(unsigned int registerCount)
+{
+ mUniformBlockRegister = registerCount;
+}
+
+const ShaderVariable *ResourcesHLSL::findUniformByName(const ImmutableString &name) const
+{
+ for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); ++uniformIndex)
+ {
+ if (name == mUniforms[uniformIndex].name)
+ {
+ return &mUniforms[uniformIndex];
+ }
+ }
+
+ return nullptr;
+}
+
+unsigned int ResourcesHLSL::assignUniformRegister(const TType &type,
+ const ImmutableString &name,
+ unsigned int *outRegisterCount)
+{
+ unsigned int registerIndex;
+ const ShaderVariable *uniform = findUniformByName(name);
+ ASSERT(uniform);
+
+ if (IsSampler(type.getBasicType()) ||
+ (IsImage(type.getBasicType()) && type.getMemoryQualifier().readonly))
+ {
+ registerIndex = mSRVRegister;
+ }
+ else if (IsImage(type.getBasicType()))
+ {
+ registerIndex = mUAVRegister;
+ }
+ else
+ {
+ registerIndex = mUniformRegister;
+ }
+
+ if (uniform->name == "angle_DrawID" && uniform->mappedName == "angle_DrawID")
+ {
+ mUniformRegisterMap["gl_DrawID"] = registerIndex;
+ }
+ else
+ {
+ mUniformRegisterMap[uniform->name] = registerIndex;
+ }
+
+ if (uniform->name == "angle_BaseVertex" && uniform->mappedName == "angle_BaseVertex")
+ {
+ mUniformRegisterMap["gl_BaseVertex"] = registerIndex;
+ }
+ else
+ {
+ mUniformRegisterMap[uniform->name] = registerIndex;
+ }
+
+ if (uniform->name == "angle_BaseInstance" && uniform->mappedName == "angle_BaseInstance")
+ {
+ mUniformRegisterMap["gl_BaseInstance"] = registerIndex;
+ }
+ else
+ {
+ mUniformRegisterMap[uniform->name] = registerIndex;
+ }
+
+ unsigned int registerCount = HLSLVariableRegisterCount(*uniform, mOutputType);
+
+ if (IsSampler(type.getBasicType()) ||
+ (IsImage(type.getBasicType()) && type.getMemoryQualifier().readonly))
+ {
+ mSRVRegister += registerCount;
+ }
+ else if (IsImage(type.getBasicType()))
+ {
+ mUAVRegister += registerCount;
+ }
+ else
+ {
+ mUniformRegister += registerCount;
+ }
+ if (outRegisterCount)
+ {
+ *outRegisterCount = registerCount;
+ }
+ return registerIndex;
+}
+
+unsigned int ResourcesHLSL::assignSamplerInStructUniformRegister(const TType &type,
+ const TString &name,
+ unsigned int *outRegisterCount)
+{
+ // Sampler that is a field of a uniform structure.
+ ASSERT(IsSampler(type.getBasicType()));
+ unsigned int registerIndex = mSRVRegister;
+ mUniformRegisterMap[std::string(name.c_str())] = registerIndex;
+ unsigned int registerCount = type.isArray() ? type.getArraySizeProduct() : 1u;
+ mSRVRegister += registerCount;
+ if (outRegisterCount)
+ {
+ *outRegisterCount = registerCount;
+ }
+ return registerIndex;
+}
+
+void ResourcesHLSL::outputHLSLSamplerUniformGroup(
+ TInfoSinkBase &out,
+ const HLSLTextureGroup textureGroup,
+ const TVector<const TVariable *> &group,
+ const TMap<const TVariable *, TString> &samplerInStructSymbolsToAPINames,
+ unsigned int *groupTextureRegisterIndex)
+{
+ if (group.empty())
+ {
+ return;
+ }
+ unsigned int groupRegisterCount = 0;
+ for (const TVariable *uniform : group)
+ {
+ const TType &type = uniform->getType();
+ const ImmutableString &name = uniform->name();
+ unsigned int registerCount;
+
+ // The uniform might be just a regular sampler or one extracted from a struct.
+ unsigned int samplerArrayIndex = 0u;
+ const ShaderVariable *uniformByName = findUniformByName(name);
+ if (uniformByName)
+ {
+ samplerArrayIndex = assignUniformRegister(type, name, &registerCount);
+ }
+ else
+ {
+ ASSERT(samplerInStructSymbolsToAPINames.find(uniform) !=
+ samplerInStructSymbolsToAPINames.end());
+ samplerArrayIndex = assignSamplerInStructUniformRegister(
+ type, samplerInStructSymbolsToAPINames.at(uniform), &registerCount);
+ }
+ groupRegisterCount += registerCount;
+
+ if (type.isArray())
+ {
+ out << "static const uint " << DecorateVariableIfNeeded(*uniform) << ArrayString(type)
+ << " = ";
+ OutputUniformIndexArrayInitializer(out, type, samplerArrayIndex);
+ out << ";\n";
+ }
+ else
+ {
+ out << "static const uint " << DecorateVariableIfNeeded(*uniform) << " = "
+ << samplerArrayIndex << ";\n";
+ }
+ }
+ TString suffix = TextureGroupSuffix(textureGroup);
+ // Since HLSL_TEXTURE_2D is the first group, it has a fixed offset of zero.
+ if (textureGroup != HLSL_TEXTURE_2D)
+ {
+ out << "static const uint textureIndexOffset" << suffix << " = "
+ << (*groupTextureRegisterIndex) << ";\n";
+ out << "static const uint samplerIndexOffset" << suffix << " = "
+ << (*groupTextureRegisterIndex) << ";\n";
+ }
+ out << "uniform " << TextureString(textureGroup) << " textures" << suffix << "["
+ << groupRegisterCount << "]"
+ << " : register(t" << (*groupTextureRegisterIndex) << ");\n";
+ out << "uniform " << SamplerString(textureGroup) << " samplers" << suffix << "["
+ << groupRegisterCount << "]"
+ << " : register(s" << (*groupTextureRegisterIndex) << ");\n";
+ *groupTextureRegisterIndex += groupRegisterCount;
+}
+
+void ResourcesHLSL::outputHLSLImageUniformIndices(TInfoSinkBase &out,
+ const TVector<const TVariable *> &group,
+ unsigned int imageArrayIndex,
+ unsigned int *groupRegisterCount)
+{
+ for (const TVariable *uniform : group)
+ {
+ const TType &type = uniform->getType();
+ const ImmutableString &name = uniform->name();
+ unsigned int registerCount = 0;
+
+ assignUniformRegister(type, name, &registerCount);
+ *groupRegisterCount += registerCount;
+
+ if (type.isArray())
+ {
+ out << "static const uint " << DecorateVariableIfNeeded(*uniform) << ArrayString(type)
+ << " = ";
+ OutputUniformIndexArrayInitializer(out, type, imageArrayIndex);
+ out << ";\n";
+ }
+ else
+ {
+ out << "static const uint " << DecorateVariableIfNeeded(*uniform) << " = "
+ << imageArrayIndex << ";\n";
+ }
+
+ imageArrayIndex += registerCount;
+ }
+}
+
+void ResourcesHLSL::outputHLSLReadonlyImageUniformGroup(TInfoSinkBase &out,
+ const HLSLTextureGroup textureGroup,
+ const TVector<const TVariable *> &group,
+ unsigned int *groupTextureRegisterIndex)
+{
+ if (group.empty())
+ {
+ return;
+ }
+
+ unsigned int groupRegisterCount = 0;
+ outputHLSLImageUniformIndices(out, group, *groupTextureRegisterIndex, &groupRegisterCount);
+
+ TString suffix = TextureGroupSuffix(textureGroup);
+ out << "static const uint readonlyImageIndexOffset" << suffix << " = "
+ << (*groupTextureRegisterIndex) << ";\n";
+ out << "uniform " << TextureString(textureGroup) << " readonlyImages" << suffix << "["
+ << groupRegisterCount << "]"
+ << " : register(t" << (*groupTextureRegisterIndex) << ");\n";
+ *groupTextureRegisterIndex += groupRegisterCount;
+}
+
+void ResourcesHLSL::outputHLSLImageUniformGroup(TInfoSinkBase &out,
+ const HLSLRWTextureGroup textureGroup,
+ const TVector<const TVariable *> &group,
+ unsigned int *groupTextureRegisterIndex)
+{
+ if (group.empty())
+ {
+ return;
+ }
+
+ // ROVs should all be written out in DynamicImage2DHLSL.cpp.
+ ASSERT(!IsAnyRasterOrdered(group));
+
+ unsigned int groupRegisterCount = 0;
+ outputHLSLImageUniformIndices(out, group, *groupTextureRegisterIndex, &groupRegisterCount);
+
+ TString suffix = RWTextureGroupSuffix(textureGroup);
+ out << "static const uint imageIndexOffset" << suffix << " = " << (*groupTextureRegisterIndex)
+ << ";\n";
+ out << "uniform " << RWTextureString(textureGroup) << " images" << suffix << "["
+ << groupRegisterCount << "]"
+ << " : register(u" << (*groupTextureRegisterIndex) << ");\n";
+ *groupTextureRegisterIndex += groupRegisterCount;
+}
+
+void ResourcesHLSL::outputHLSL4_0_FL9_3Sampler(TInfoSinkBase &out,
+ const TType &type,
+ const TVariable &variable,
+ const unsigned int registerIndex)
+{
+ out << "uniform " << SamplerString(type.getBasicType()) << " sampler_"
+ << DecorateVariableIfNeeded(variable) << ArrayString(type) << " : register(s"
+ << str(registerIndex) << ");\n";
+ out << "uniform " << TextureString(type.getBasicType()) << " texture_"
+ << DecorateVariableIfNeeded(variable) << ArrayString(type) << " : register(t"
+ << str(registerIndex) << ");\n";
+}
+
+void ResourcesHLSL::outputUniform(TInfoSinkBase &out,
+ const TType &type,
+ const TVariable &variable,
+ const unsigned int registerIndex)
+{
+ const TStructure *structure = type.getStruct();
+ // If this is a nameless struct, we need to use its full definition, rather than its (empty)
+ // name.
+ // TypeString() will invoke defineNameless in this case; qualifier prefixes are unnecessary for
+ // nameless structs in ES, as nameless structs cannot be used anywhere that layout qualifiers
+ // are permitted.
+ const TString &typeName = ((structure && structure->symbolType() != SymbolType::Empty)
+ ? QualifiedStructNameString(*structure, false, false, false)
+ : TypeString(type));
+
+ const TString &registerString =
+ TString("register(") + UniformRegisterPrefix(type) + str(registerIndex) + ")";
+
+ out << "uniform " << typeName << " ";
+
+ out << DecorateVariableIfNeeded(variable);
+
+ out << ArrayString(type) << " : " << registerString << ";\n";
+}
+
+void ResourcesHLSL::outputAtomicCounterBuffer(TInfoSinkBase &out,
+ const int binding,
+ const unsigned int registerIndex)
+{
+ // Atomic counter memory access is not incoherent
+ out << "uniform globallycoherent RWByteAddressBuffer "
+ << getAtomicCounterNameForBinding(binding) << " : register(u" << registerIndex << ");\n";
+}
+
+void ResourcesHLSL::uniformsHeader(TInfoSinkBase &out,
+ ShShaderOutput outputType,
+ const ReferencedVariables &referencedUniforms,
+ TSymbolTable *symbolTable)
+{
+ if (!referencedUniforms.empty())
+ {
+ out << "// Uniforms\n\n";
+ }
+ // In the case of HLSL 4, sampler uniforms need to be grouped by type before the code is
+ // written. They are grouped based on the combination of the HLSL texture type and
+ // HLSL sampler type, enumerated in HLSLTextureSamplerGroup.
+ TVector<TVector<const TVariable *>> groupedSamplerUniforms(HLSL_TEXTURE_MAX + 1);
+ TMap<const TVariable *, TString> samplerInStructSymbolsToAPINames;
+ TVector<TVector<const TVariable *>> groupedReadonlyImageUniforms(HLSL_TEXTURE_MAX + 1);
+ TVector<TVector<const TVariable *>> groupedImageUniforms(HLSL_RWTEXTURE_MAX + 1);
+
+ TUnorderedMap<int, unsigned int> assignedAtomicCounterBindings;
+ unsigned int reservedReadonlyImageRegisterCount = 0, reservedImageRegisterCount = 0;
+ for (auto &uniformIt : referencedUniforms)
+ {
+ // Output regular uniforms. Group sampler uniforms by type.
+ const TVariable &variable = *uniformIt.second;
+ const TType &type = variable.getType();
+
+ if (outputType == SH_HLSL_4_1_OUTPUT && IsSampler(type.getBasicType()))
+ {
+ HLSLTextureGroup group = TextureGroup(type.getBasicType());
+ groupedSamplerUniforms[group].push_back(&variable);
+ }
+ else if (outputType == SH_HLSL_4_0_FL9_3_OUTPUT && IsSampler(type.getBasicType()))
+ {
+ unsigned int registerIndex = assignUniformRegister(type, variable.name(), nullptr);
+ outputHLSL4_0_FL9_3Sampler(out, type, variable, registerIndex);
+ }
+ else if (outputType == SH_HLSL_4_1_OUTPUT && IsImage(type.getBasicType()))
+ {
+ if (IsImage2D(type.getBasicType()))
+ {
+ const ShaderVariable *uniform = findUniformByName(variable.name());
+ if (type.getMemoryQualifier().readonly)
+ {
+ reservedReadonlyImageRegisterCount +=
+ HLSLVariableRegisterCount(*uniform, mOutputType);
+ }
+ else
+ {
+ reservedImageRegisterCount += HLSLVariableRegisterCount(*uniform, mOutputType);
+ }
+ continue;
+ }
+ if (type.getMemoryQualifier().readonly)
+ {
+ HLSLTextureGroup group = TextureGroup(
+ type.getBasicType(), type.getLayoutQualifier().imageInternalFormat);
+ groupedReadonlyImageUniforms[group].push_back(&variable);
+ }
+ else
+ {
+ HLSLRWTextureGroup group = RWTextureGroup(
+ type.getBasicType(), type.getLayoutQualifier().imageInternalFormat);
+ groupedImageUniforms[group].push_back(&variable);
+ }
+ }
+ else if (outputType == SH_HLSL_4_1_OUTPUT && IsAtomicCounter(type.getBasicType()))
+ {
+ TLayoutQualifier layout = type.getLayoutQualifier();
+ int binding = layout.binding;
+ unsigned int registerIndex;
+ if (assignedAtomicCounterBindings.find(binding) == assignedAtomicCounterBindings.end())
+ {
+ registerIndex = mUAVRegister++;
+ assignedAtomicCounterBindings[binding] = registerIndex;
+ outputAtomicCounterBuffer(out, binding, registerIndex);
+ }
+ else
+ {
+ registerIndex = assignedAtomicCounterBindings[binding];
+ }
+ const ShaderVariable *uniform = findUniformByName(variable.name());
+ mUniformRegisterMap[uniform->name] = registerIndex;
+ }
+ else
+ {
+ if (type.isStructureContainingSamplers())
+ {
+ TVector<const TVariable *> samplerSymbols;
+ TMap<const TVariable *, TString> symbolsToAPINames;
+ ImmutableStringBuilder namePrefix(kAngleDecorString.length() +
+ variable.name().length());
+ namePrefix << kAngleDecorString;
+ namePrefix << variable.name();
+ type.createSamplerSymbols(namePrefix, TString(variable.name().data()),
+ &samplerSymbols, &symbolsToAPINames, symbolTable);
+ for (const TVariable *sampler : samplerSymbols)
+ {
+ const TType &samplerType = sampler->getType();
+
+ if (outputType == SH_HLSL_4_1_OUTPUT)
+ {
+ HLSLTextureGroup group = TextureGroup(samplerType.getBasicType());
+ groupedSamplerUniforms[group].push_back(sampler);
+ samplerInStructSymbolsToAPINames[sampler] = symbolsToAPINames[sampler];
+ }
+ else if (outputType == SH_HLSL_4_0_FL9_3_OUTPUT)
+ {
+ unsigned int registerIndex = assignSamplerInStructUniformRegister(
+ samplerType, symbolsToAPINames[sampler], nullptr);
+ outputHLSL4_0_FL9_3Sampler(out, samplerType, *sampler, registerIndex);
+ }
+ else
+ {
+ ASSERT(outputType == SH_HLSL_3_0_OUTPUT);
+ unsigned int registerIndex = assignSamplerInStructUniformRegister(
+ samplerType, symbolsToAPINames[sampler], nullptr);
+ outputUniform(out, samplerType, *sampler, registerIndex);
+ }
+ }
+ }
+ unsigned int registerIndex = assignUniformRegister(type, variable.name(), nullptr);
+ outputUniform(out, type, variable, registerIndex);
+ }
+ }
+
+ if (outputType == SH_HLSL_4_1_OUTPUT)
+ {
+ unsigned int groupTextureRegisterIndex = 0;
+ // Atomic counters and RW texture share the same resources. Therefore, RW texture need to
+ // start counting after the last atomic counter.
+ unsigned int groupRWTextureRegisterIndex = mUAVRegister;
+ // TEXTURE_2D is special, index offset is assumed to be 0 and omitted in that case.
+ ASSERT(HLSL_TEXTURE_MIN == HLSL_TEXTURE_2D);
+ for (int groupId = HLSL_TEXTURE_MIN; groupId < HLSL_TEXTURE_MAX; ++groupId)
+ {
+ outputHLSLSamplerUniformGroup(
+ out, HLSLTextureGroup(groupId), groupedSamplerUniforms[groupId],
+ samplerInStructSymbolsToAPINames, &groupTextureRegisterIndex);
+ }
+ mSamplerCount = groupTextureRegisterIndex;
+
+ // Reserve t type register for readonly image2D variables.
+ mReadonlyImage2DRegisterIndex = mSRVRegister;
+ groupTextureRegisterIndex += reservedReadonlyImageRegisterCount;
+ mSRVRegister += reservedReadonlyImageRegisterCount;
+
+ for (int groupId = HLSL_TEXTURE_MIN; groupId < HLSL_TEXTURE_MAX; ++groupId)
+ {
+ outputHLSLReadonlyImageUniformGroup(out, HLSLTextureGroup(groupId),
+ groupedReadonlyImageUniforms[groupId],
+ &groupTextureRegisterIndex);
+ }
+ mReadonlyImageCount = groupTextureRegisterIndex - mReadonlyImage2DRegisterIndex;
+ if (mReadonlyImageCount)
+ {
+ out << "static const uint readonlyImageIndexStart = " << mReadonlyImage2DRegisterIndex
+ << ";\n";
+ }
+
+ // Reserve u type register for writable image2D variables.
+ mImage2DRegisterIndex = mUAVRegister;
+ groupRWTextureRegisterIndex += reservedImageRegisterCount;
+ mUAVRegister += reservedImageRegisterCount;
+
+ for (int groupId = HLSL_RWTEXTURE_MIN; groupId < HLSL_RWTEXTURE_MAX; ++groupId)
+ {
+ outputHLSLImageUniformGroup(out, HLSLRWTextureGroup(groupId),
+ groupedImageUniforms[groupId],
+ &groupRWTextureRegisterIndex);
+ }
+ mImageCount = groupRWTextureRegisterIndex - mImage2DRegisterIndex;
+ if (mImageCount)
+ {
+ out << "static const uint imageIndexStart = " << mImage2DRegisterIndex << ";\n";
+ }
+ }
+}
+
+void ResourcesHLSL::samplerMetadataUniforms(TInfoSinkBase &out, unsigned int regIndex)
+{
+ // If mSamplerCount is 0 the shader doesn't use any textures for samplers.
+ if (mSamplerCount > 0)
+ {
+ out << " struct SamplerMetadata\n"
+ " {\n"
+ " int baseLevel;\n"
+ " int internalFormatBits;\n"
+ " int wrapModes;\n"
+ " int padding;\n"
+ " int4 intBorderColor;\n"
+ " };\n"
+ " SamplerMetadata samplerMetadata["
+ << mSamplerCount << "] : packoffset(c" << regIndex << ");\n";
+ }
+}
+
+void ResourcesHLSL::imageMetadataUniforms(TInfoSinkBase &out, unsigned int regIndex)
+{
+ if (mReadonlyImageCount > 0 || mImageCount > 0)
+ {
+ out << " struct ImageMetadata\n"
+ " {\n"
+ " int layer;\n"
+ " uint level;\n"
+ " int2 padding;\n"
+ " };\n";
+
+ if (mReadonlyImageCount > 0)
+ {
+ out << " ImageMetadata readonlyImageMetadata[" << mReadonlyImageCount
+ << "] : packoffset(c" << regIndex << ");\n";
+ }
+
+ if (mImageCount > 0)
+ {
+ out << " ImageMetadata imageMetadata[" << mImageCount << "] : packoffset(c"
+ << regIndex + mReadonlyImageCount << ");\n";
+ }
+ }
+}
+
+TString ResourcesHLSL::uniformBlocksHeader(
+ const ReferencedInterfaceBlocks &referencedInterfaceBlocks,
+ const std::map<int, const TInterfaceBlock *> &uniformBlockOptimizedMap)
+{
+ TString interfaceBlocks;
+
+ for (const auto &blockReference : referencedInterfaceBlocks)
+ {
+ const TInterfaceBlock &interfaceBlock = *blockReference.second->block;
+ const TVariable *instanceVariable = blockReference.second->instanceVariable;
+ if (instanceVariable != nullptr)
+ {
+ interfaceBlocks += uniformBlockStructString(interfaceBlock);
+ }
+
+ // In order to avoid compile performance issue, translate uniform block to structured
+ // buffer. anglebug.com/3682.
+ if (uniformBlockOptimizedMap.count(interfaceBlock.uniqueId().get()) != 0)
+ {
+ unsigned int structuredBufferRegister = mSRVRegister;
+ if (instanceVariable != nullptr && instanceVariable->getType().isArray())
+ {
+ unsigned int instanceArraySize =
+ instanceVariable->getType().getOutermostArraySize();
+ for (unsigned int arrayIndex = 0; arrayIndex < instanceArraySize; arrayIndex++)
+ {
+ interfaceBlocks += uniformBlockWithOneLargeArrayMemberString(
+ interfaceBlock, instanceVariable, structuredBufferRegister + arrayIndex,
+ arrayIndex);
+ }
+ mSRVRegister += instanceArraySize;
+ }
+ else
+ {
+ interfaceBlocks += uniformBlockWithOneLargeArrayMemberString(
+ interfaceBlock, instanceVariable, structuredBufferRegister, GL_INVALID_INDEX);
+ mSRVRegister += 1u;
+ }
+ mUniformBlockRegisterMap[interfaceBlock.name().data()] = structuredBufferRegister;
+ mUniformBlockUseStructuredBufferMap[interfaceBlock.name().data()] = true;
+ continue;
+ }
+
+ unsigned int activeRegister = mUniformBlockRegister;
+ mUniformBlockRegisterMap[interfaceBlock.name().data()] = activeRegister;
+
+ if (instanceVariable != nullptr && instanceVariable->getType().isArray())
+ {
+ unsigned int instanceArraySize = instanceVariable->getType().getOutermostArraySize();
+ for (unsigned int arrayIndex = 0; arrayIndex < instanceArraySize; arrayIndex++)
+ {
+ interfaceBlocks += uniformBlockString(interfaceBlock, instanceVariable,
+ activeRegister + arrayIndex, arrayIndex);
+ }
+ mUniformBlockRegister += instanceArraySize;
+ }
+ else
+ {
+ interfaceBlocks += uniformBlockString(interfaceBlock, instanceVariable, activeRegister,
+ GL_INVALID_INDEX);
+ mUniformBlockRegister += 1u;
+ }
+ }
+
+ return (interfaceBlocks.empty() ? "" : ("// Uniform Blocks\n\n" + interfaceBlocks));
+}
+
+void ResourcesHLSL::allocateShaderStorageBlockRegisters(
+ const ReferencedInterfaceBlocks &referencedInterfaceBlocks)
+{
+ for (const auto &interfaceBlockReference : referencedInterfaceBlocks)
+ {
+ const TInterfaceBlock &interfaceBlock = *interfaceBlockReference.second->block;
+ const TVariable *instanceVariable = interfaceBlockReference.second->instanceVariable;
+
+ mShaderStorageBlockRegisterMap[interfaceBlock.name().data()] = mUAVRegister;
+
+ if (instanceVariable != nullptr && instanceVariable->getType().isArray())
+ {
+ mUAVRegister += instanceVariable->getType().getOutermostArraySize();
+ }
+ else
+ {
+ mUAVRegister += 1u;
+ }
+ }
+}
+
+TString ResourcesHLSL::shaderStorageBlocksHeader(
+ const ReferencedInterfaceBlocks &referencedInterfaceBlocks)
+{
+ TString interfaceBlocks;
+
+ for (const auto &interfaceBlockReference : referencedInterfaceBlocks)
+ {
+ const TInterfaceBlock &interfaceBlock = *interfaceBlockReference.second->block;
+ const TVariable *instanceVariable = interfaceBlockReference.second->instanceVariable;
+
+ unsigned int activeRegister = mShaderStorageBlockRegisterMap[interfaceBlock.name().data()];
+
+ if (instanceVariable != nullptr && instanceVariable->getType().isArray())
+ {
+ unsigned int instanceArraySize = instanceVariable->getType().getOutermostArraySize();
+ for (unsigned int arrayIndex = 0; arrayIndex < instanceArraySize; arrayIndex++)
+ {
+ interfaceBlocks += shaderStorageBlockString(
+ interfaceBlock, instanceVariable, activeRegister + arrayIndex, arrayIndex);
+ }
+ }
+ else
+ {
+ interfaceBlocks += shaderStorageBlockString(interfaceBlock, instanceVariable,
+ activeRegister, GL_INVALID_INDEX);
+ }
+ }
+
+ return interfaceBlocks;
+}
+
+TString ResourcesHLSL::uniformBlockString(const TInterfaceBlock &interfaceBlock,
+ const TVariable *instanceVariable,
+ unsigned int registerIndex,
+ unsigned int arrayIndex)
+{
+ const TString &arrayIndexString = (arrayIndex != GL_INVALID_INDEX ? str(arrayIndex) : "");
+ const TString &blockName = TString(interfaceBlock.name().data()) + arrayIndexString;
+ TString hlsl;
+
+ hlsl += "cbuffer " + blockName + " : register(b" + str(registerIndex) +
+ ")\n"
+ "{\n";
+
+ if (instanceVariable != nullptr)
+ {
+ hlsl += " " + InterfaceBlockStructName(interfaceBlock) + " " +
+ InterfaceBlockInstanceString(instanceVariable->name(), arrayIndex) + ";\n";
+ }
+ else
+ {
+ const TLayoutBlockStorage blockStorage = interfaceBlock.blockStorage();
+ hlsl += uniformBlockMembersString(interfaceBlock, blockStorage);
+ }
+
+ hlsl += "};\n\n";
+
+ return hlsl;
+}
+
+TString ResourcesHLSL::uniformBlockWithOneLargeArrayMemberString(
+ const TInterfaceBlock &interfaceBlock,
+ const TVariable *instanceVariable,
+ unsigned int registerIndex,
+ unsigned int arrayIndex)
+{
+ TString hlsl, typeString;
+
+ const TField &field = *interfaceBlock.fields()[0];
+ const TLayoutBlockStorage blockStorage = interfaceBlock.blockStorage();
+ typeString = InterfaceBlockFieldTypeString(field, blockStorage, true);
+ const TType &fieldType = *field.type();
+ if (fieldType.isMatrix())
+ {
+ if (arrayIndex == GL_INVALID_INDEX || arrayIndex == 0)
+ {
+ hlsl += "struct pack" + Decorate(interfaceBlock.name()) + " { " + typeString + " " +
+ Decorate(field.name()) + "; };\n";
+ }
+ typeString = "pack" + Decorate(interfaceBlock.name());
+ }
+ else if (fieldType.isVectorArray() || fieldType.isScalarArray())
+ {
+ // If the member is an array of scalars or vectors, std140 rules require the base array
+ // stride are rounded up to the base alignment of a vec4.
+ if (arrayIndex == GL_INVALID_INDEX || arrayIndex == 0)
+ {
+ hlsl += "struct pack" + Decorate(interfaceBlock.name()) + " { " + typeString + " " +
+ Decorate(field.name()) + ";\n";
+ hlsl += InterfaceBlockScalarVectorFieldPaddingString(fieldType) + " };\n";
+ }
+ typeString = "pack" + Decorate(interfaceBlock.name());
+ }
+
+ if (instanceVariable != nullptr)
+ {
+
+ hlsl += "StructuredBuffer <" + typeString + "> " +
+ InterfaceBlockInstanceString(instanceVariable->name(), arrayIndex) + "_" +
+ Decorate(field.name()) + +" : register(t" + str(registerIndex) + ");\n";
+ }
+ else
+ {
+ hlsl += "StructuredBuffer <" + typeString + "> " + Decorate(field.name()) +
+ " : register(t" + str(registerIndex) + ");\n";
+ }
+
+ return hlsl;
+}
+
+TString ResourcesHLSL::shaderStorageBlockString(const TInterfaceBlock &interfaceBlock,
+ const TVariable *instanceVariable,
+ unsigned int registerIndex,
+ unsigned int arrayIndex)
+{
+ TString hlsl;
+ if (instanceVariable != nullptr)
+ {
+ hlsl += "RWByteAddressBuffer " +
+ InterfaceBlockInstanceString(instanceVariable->name(), arrayIndex) +
+ ": register(u" + str(registerIndex) + ");\n";
+ }
+ else
+ {
+ hlsl += "RWByteAddressBuffer " + Decorate(interfaceBlock.name()) + ": register(u" +
+ str(registerIndex) + ");\n";
+ }
+ return hlsl;
+}
+
+TString ResourcesHLSL::InterfaceBlockInstanceString(const ImmutableString &instanceName,
+ unsigned int arrayIndex)
+{
+ if (arrayIndex != GL_INVALID_INDEX)
+ {
+ return DecoratePrivate(instanceName) + "_" + str(arrayIndex);
+ }
+ else
+ {
+ return Decorate(instanceName);
+ }
+}
+
+TString ResourcesHLSL::uniformBlockMembersString(const TInterfaceBlock &interfaceBlock,
+ TLayoutBlockStorage blockStorage)
+{
+ TString hlsl;
+
+ Std140PaddingHelper padHelper = mStructureHLSL->getPaddingHelper();
+
+ const unsigned int fieldCount = static_cast<unsigned int>(interfaceBlock.fields().size());
+ for (unsigned int typeIndex = 0; typeIndex < fieldCount; typeIndex++)
+ {
+ const TField &field = *interfaceBlock.fields()[typeIndex];
+ const TType &fieldType = *field.type();
+
+ if (blockStorage == EbsStd140)
+ {
+ // 2 and 3 component vector types in some cases need pre-padding
+ hlsl += padHelper.prePaddingString(fieldType, false);
+ }
+
+ hlsl += " " + InterfaceBlockFieldTypeString(field, blockStorage, false) + " " +
+ Decorate(field.name()) + ArrayString(fieldType).data() + ";\n";
+
+ // must pad out after matrices and arrays, where HLSL usually allows itself room to pack
+ // stuff
+ if (blockStorage == EbsStd140)
+ {
+ const bool useHLSLRowMajorPacking =
+ (fieldType.getLayoutQualifier().matrixPacking == EmpColumnMajor);
+ hlsl += padHelper.postPaddingString(fieldType, useHLSLRowMajorPacking,
+ typeIndex == fieldCount - 1, false);
+ }
+ }
+
+ return hlsl;
+}
+
+TString ResourcesHLSL::uniformBlockStructString(const TInterfaceBlock &interfaceBlock)
+{
+ const TLayoutBlockStorage blockStorage = interfaceBlock.blockStorage();
+
+ return "struct " + InterfaceBlockStructName(interfaceBlock) +
+ "\n"
+ "{\n" +
+ uniformBlockMembersString(interfaceBlock, blockStorage) + "};\n\n";
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/ResourcesHLSL.h b/gfx/angle/checkout/src/compiler/translator/ResourcesHLSL.h
new file mode 100644
index 0000000000..a13ba036eb
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ResourcesHLSL.h
@@ -0,0 +1,155 @@
+//
+// 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.
+//
+// ResourcesHLSL.h:
+// Methods for GLSL to HLSL translation for uniforms and interface blocks.
+//
+
+#ifndef COMPILER_TRANSLATOR_RESOURCESHLSL_H_
+#define COMPILER_TRANSLATOR_RESOURCESHLSL_H_
+
+#include "compiler/translator/OutputHLSL.h"
+#include "compiler/translator/UtilsHLSL.h"
+
+namespace sh
+{
+class ImmutableString;
+class StructureHLSL;
+class TSymbolTable;
+
+class ResourcesHLSL : angle::NonCopyable
+{
+ public:
+ ResourcesHLSL(StructureHLSL *structureHLSL,
+ ShShaderOutput outputType,
+ const std::vector<ShaderVariable> &uniforms,
+ unsigned int firstUniformRegister);
+
+ void reserveUniformRegisters(unsigned int registerCount);
+ void reserveUniformBlockRegisters(unsigned int registerCount);
+ void uniformsHeader(TInfoSinkBase &out,
+ ShShaderOutput outputType,
+ const ReferencedVariables &referencedUniforms,
+ TSymbolTable *symbolTable);
+
+ // Must be called after uniformsHeader
+ void samplerMetadataUniforms(TInfoSinkBase &out, unsigned int regIndex);
+ unsigned int getSamplerCount() const { return mSamplerCount; }
+ void imageMetadataUniforms(TInfoSinkBase &out, unsigned int regIndex);
+ TString uniformBlocksHeader(
+ const ReferencedInterfaceBlocks &referencedInterfaceBlocks,
+ const std::map<int, const TInterfaceBlock *> &uniformBlockOptimizedMap);
+ void allocateShaderStorageBlockRegisters(
+ const ReferencedInterfaceBlocks &referencedInterfaceBlocks);
+ TString shaderStorageBlocksHeader(const ReferencedInterfaceBlocks &referencedInterfaceBlocks);
+
+ // Used for direct index references
+ static TString InterfaceBlockInstanceString(const ImmutableString &instanceName,
+ unsigned int arrayIndex);
+
+ const std::map<std::string, unsigned int> &getShaderStorageBlockRegisterMap() const
+ {
+ return mShaderStorageBlockRegisterMap;
+ }
+
+ const std::map<std::string, unsigned int> &getUniformBlockRegisterMap() const
+ {
+ return mUniformBlockRegisterMap;
+ }
+
+ const std::map<std::string, bool> &getUniformBlockUseStructuredBufferMap() const
+ {
+ return mUniformBlockUseStructuredBufferMap;
+ }
+
+ const std::map<std::string, unsigned int> &getUniformRegisterMap() const
+ {
+ return mUniformRegisterMap;
+ }
+
+ unsigned int getReadonlyImage2DRegisterIndex() const { return mReadonlyImage2DRegisterIndex; }
+ unsigned int getImage2DRegisterIndex() const { return mImage2DRegisterIndex; }
+ bool hasImages() const { return mReadonlyImageCount > 0 || mImageCount > 0; }
+
+ private:
+ TString uniformBlockString(const TInterfaceBlock &interfaceBlock,
+ const TVariable *instanceVariable,
+ unsigned int registerIndex,
+ unsigned int arrayIndex);
+ TString uniformBlockWithOneLargeArrayMemberString(const TInterfaceBlock &interfaceBlock,
+ const TVariable *instanceVariable,
+ unsigned int registerIndex,
+ unsigned int arrayIndex);
+
+ TString shaderStorageBlockString(const TInterfaceBlock &interfaceBlock,
+ const TVariable *instanceVariable,
+ unsigned int registerIndex,
+ unsigned int arrayIndex);
+ TString uniformBlockMembersString(const TInterfaceBlock &interfaceBlock,
+ TLayoutBlockStorage blockStorage);
+ TString uniformBlockStructString(const TInterfaceBlock &interfaceBlock);
+ const ShaderVariable *findUniformByName(const ImmutableString &name) const;
+
+ void outputHLSL4_0_FL9_3Sampler(TInfoSinkBase &out,
+ const TType &type,
+ const TVariable &variable,
+ const unsigned int registerIndex);
+ void outputUniform(TInfoSinkBase &out,
+ const TType &type,
+ const TVariable &variable,
+ const unsigned int registerIndex);
+ void outputAtomicCounterBuffer(TInfoSinkBase &out,
+ const int binding,
+ const unsigned int registerIndex);
+
+ // Returns the uniform's register index
+ unsigned int assignUniformRegister(const TType &type,
+ const ImmutableString &name,
+ unsigned int *outRegisterCount);
+ unsigned int assignSamplerInStructUniformRegister(const TType &type,
+ const TString &name,
+ unsigned int *outRegisterCount);
+
+ void outputHLSLSamplerUniformGroup(
+ TInfoSinkBase &out,
+ const HLSLTextureGroup textureGroup,
+ const TVector<const TVariable *> &group,
+ const TMap<const TVariable *, TString> &samplerInStructSymbolsToAPINames,
+ unsigned int *groupTextureRegisterIndex);
+
+ void outputHLSLImageUniformIndices(TInfoSinkBase &out,
+ const TVector<const TVariable *> &group,
+ unsigned int imageArrayIndex,
+ unsigned int *groupRegisterCount);
+ void outputHLSLReadonlyImageUniformGroup(TInfoSinkBase &out,
+ const HLSLTextureGroup textureGroup,
+ const TVector<const TVariable *> &group,
+ unsigned int *groupTextureRegisterIndex);
+ void outputHLSLImageUniformGroup(TInfoSinkBase &out,
+ const HLSLRWTextureGroup textureGroup,
+ const TVector<const TVariable *> &group,
+ unsigned int *groupTextureRegisterIndex);
+
+ unsigned int mUniformRegister;
+ unsigned int mUniformBlockRegister;
+ unsigned int mSRVRegister;
+ unsigned int mUAVRegister;
+ unsigned int mSamplerCount;
+ unsigned int mReadonlyImageCount = 0;
+ unsigned int mImageCount = 0;
+ StructureHLSL *mStructureHLSL;
+ ShShaderOutput mOutputType;
+
+ const std::vector<ShaderVariable> &mUniforms;
+ std::map<std::string, unsigned int> mUniformBlockRegisterMap;
+ std::map<std::string, unsigned int> mShaderStorageBlockRegisterMap;
+ std::map<std::string, unsigned int> mUniformRegisterMap;
+ std::map<std::string, bool> mUniformBlockUseStructuredBufferMap;
+ unsigned int mReadonlyImage2DRegisterIndex;
+ unsigned int mImage2DRegisterIndex;
+};
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_RESOURCESHLSL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/Severity.h b/gfx/angle/checkout/src/compiler/translator/Severity.h
new file mode 100644
index 0000000000..dccd45375d
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/Severity.h
@@ -0,0 +1,22 @@
+//
+// 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.
+//
+
+#ifndef COMPILER_TRANSLATOR_SEVERITY_H_
+#define COMPILER_TRANSLATOR_SEVERITY_H_
+
+namespace sh
+{
+
+// Severity is used to classify info log messages.
+enum Severity
+{
+ SH_WARNING,
+ SH_ERROR
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_SEVERITY_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/ShaderLang.cpp b/gfx/angle/checkout/src/compiler/translator/ShaderLang.cpp
new file mode 100644
index 0000000000..abc680656a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ShaderLang.cpp
@@ -0,0 +1,1091 @@
+//
+// Copyright 2002 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.
+//
+
+//
+// Implement the top-level of interface to the compiler,
+// as defined in ShaderLang.h
+//
+
+#include "GLSLANG/ShaderLang.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/InitializeDll.h"
+#include "compiler/translator/glslang_wrapper.h"
+#include "compiler/translator/length_limits.h"
+#ifdef ANGLE_ENABLE_HLSL
+# include "compiler/translator/TranslatorHLSL.h"
+#endif // ANGLE_ENABLE_HLSL
+#include "angle_gl.h"
+#include "compiler/translator/VariablePacker.h"
+
+namespace sh
+{
+
+namespace
+{
+
+bool isInitialized = false;
+
+// glslang can only be initialized/finalized once per process. Otherwise, the following EGL commands
+// will call GlslangFinalize() without ever being able to GlslangInitialize() again, leading to
+// crashes since GlslangFinalize() cleans up glslang for the entire process.
+// dpy1 = eglGetPlatformDisplay() |
+// eglInitialize(dpy1) | GlslangInitialize()
+// dpy2 = eglGetPlatformDisplay() |
+// eglInitialize(dpy2) | GlslangInitialize()
+// eglTerminate(dpy2) | GlslangFinalize()
+// eglInitialize(dpy1) | Display::isInitialized() == true, no GlslangInitialize()
+int initializeGlslangRefCount = 0;
+
+//
+// This is the platform independent interface between an OGL driver
+// and the shading language compiler.
+//
+
+template <typename VarT>
+const std::vector<VarT> *GetVariableList(const TCompiler *compiler);
+
+template <>
+const std::vector<InterfaceBlock> *GetVariableList(const TCompiler *compiler)
+{
+ return &compiler->getInterfaceBlocks();
+}
+
+TCompiler *GetCompilerFromHandle(ShHandle handle)
+{
+ if (!handle)
+ {
+ return nullptr;
+ }
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ return base->getAsCompiler();
+}
+
+template <typename VarT>
+const std::vector<VarT> *GetShaderVariables(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ if (!compiler)
+ {
+ return nullptr;
+ }
+
+ return GetVariableList<VarT>(compiler);
+}
+
+#ifdef ANGLE_ENABLE_HLSL
+TranslatorHLSL *GetTranslatorHLSLFromHandle(ShHandle handle)
+{
+ if (!handle)
+ return nullptr;
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ return base->getAsTranslatorHLSL();
+}
+#endif // ANGLE_ENABLE_HLSL
+
+GLenum GetGeometryShaderPrimitiveTypeEnum(sh::TLayoutPrimitiveType primitiveType)
+{
+ switch (primitiveType)
+ {
+ case EptPoints:
+ return GL_POINTS;
+ case EptLines:
+ return GL_LINES;
+ case EptLinesAdjacency:
+ return GL_LINES_ADJACENCY_EXT;
+ case EptTriangles:
+ return GL_TRIANGLES;
+ case EptTrianglesAdjacency:
+ return GL_TRIANGLES_ADJACENCY_EXT;
+
+ case EptLineStrip:
+ return GL_LINE_STRIP;
+ case EptTriangleStrip:
+ return GL_TRIANGLE_STRIP;
+
+ case EptUndefined:
+ default:
+ UNREACHABLE();
+ return GL_INVALID_VALUE;
+ }
+}
+
+GLenum GetTessellationShaderTypeEnum(sh::TLayoutTessEvaluationType type)
+{
+ switch (type)
+ {
+ case EtetTriangles:
+ return GL_TRIANGLES;
+ case EtetQuads:
+ return GL_QUADS;
+ case EtetIsolines:
+ return GL_ISOLINES;
+ case EtetEqualSpacing:
+ return GL_EQUAL;
+ case EtetFractionalEvenSpacing:
+ return GL_FRACTIONAL_EVEN;
+ case EtetFractionalOddSpacing:
+ return GL_FRACTIONAL_ODD;
+ case EtetCw:
+ return GL_CW;
+ case EtetCcw:
+ return GL_CCW;
+ case EtetPointMode:
+ return GL_TESS_GEN_POINT_MODE;
+
+ case EtetUndefined:
+ default:
+ UNREACHABLE();
+ return GL_INVALID_VALUE;
+ }
+}
+
+} // anonymous namespace
+
+//
+// Driver must call this first, once, before doing any other compiler operations.
+// Subsequent calls to this function are no-op.
+//
+bool Initialize()
+{
+ if (!isInitialized)
+ {
+ isInitialized = InitProcess();
+ }
+ return isInitialized;
+}
+
+//
+// Cleanup symbol tables
+//
+bool Finalize()
+{
+ if (isInitialized)
+ {
+ DetachProcess();
+ isInitialized = false;
+ }
+ return true;
+}
+
+//
+// Initialize built-in resources with minimum expected values.
+//
+void InitBuiltInResources(ShBuiltInResources *resources)
+{
+ // Make comparable.
+ memset(resources, 0, sizeof(*resources));
+
+ // Constants.
+ resources->MaxVertexAttribs = 8;
+ resources->MaxVertexUniformVectors = 128;
+ resources->MaxVaryingVectors = 8;
+ resources->MaxVertexTextureImageUnits = 0;
+ resources->MaxCombinedTextureImageUnits = 8;
+ resources->MaxTextureImageUnits = 8;
+ resources->MaxFragmentUniformVectors = 16;
+ resources->MaxDrawBuffers = 1;
+
+ // Extensions.
+ resources->OES_standard_derivatives = 0;
+ resources->OES_EGL_image_external = 0;
+ resources->OES_EGL_image_external_essl3 = 0;
+ resources->NV_EGL_stream_consumer_external = 0;
+ resources->ARB_texture_rectangle = 0;
+ resources->EXT_blend_func_extended = 0;
+ resources->EXT_draw_buffers = 0;
+ resources->EXT_frag_depth = 0;
+ resources->EXT_shader_texture_lod = 0;
+ resources->EXT_shader_framebuffer_fetch = 0;
+ resources->EXT_shader_framebuffer_fetch_non_coherent = 0;
+ resources->NV_shader_framebuffer_fetch = 0;
+ resources->ARM_shader_framebuffer_fetch = 0;
+ resources->OVR_multiview = 0;
+ resources->OVR_multiview2 = 0;
+ resources->EXT_YUV_target = 0;
+ resources->EXT_geometry_shader = 0;
+ resources->OES_geometry_shader = 0;
+ resources->EXT_gpu_shader5 = 0;
+ resources->OES_shader_io_blocks = 0;
+ resources->EXT_shader_io_blocks = 0;
+ resources->EXT_shader_non_constant_global_initializers = 0;
+ resources->NV_shader_noperspective_interpolation = 0;
+ resources->OES_texture_storage_multisample_2d_array = 0;
+ resources->OES_texture_3D = 0;
+ resources->ANGLE_shader_pixel_local_storage = 0;
+ resources->ANGLE_texture_multisample = 0;
+ resources->ANGLE_multi_draw = 0;
+ resources->ANGLE_base_vertex_base_instance = 0;
+ resources->ANGLE_base_vertex_base_instance_shader_builtin = 0;
+ resources->WEBGL_video_texture = 0;
+ resources->APPLE_clip_distance = 0;
+ resources->OES_texture_cube_map_array = 0;
+ resources->EXT_texture_cube_map_array = 0;
+ resources->EXT_shadow_samplers = 0;
+ resources->OES_shader_multisample_interpolation = 0;
+ resources->NV_draw_buffers = 0;
+ resources->OES_shader_image_atomic = 0;
+ resources->EXT_tessellation_shader = 0;
+ resources->OES_texture_buffer = 0;
+ resources->EXT_texture_buffer = 0;
+ resources->OES_sample_variables = 0;
+ resources->EXT_clip_cull_distance = 0;
+ resources->KHR_blend_equation_advanced = 0;
+
+ resources->MaxClipDistances = 8;
+ resources->MaxCullDistances = 8;
+ resources->MaxCombinedClipAndCullDistances = 8;
+
+ // Disable highp precision in fragment shader by default.
+ resources->FragmentPrecisionHigh = 0;
+
+ // GLSL ES 3.0 constants.
+ resources->MaxVertexOutputVectors = 16;
+ resources->MaxFragmentInputVectors = 15;
+ resources->MinProgramTexelOffset = -8;
+ resources->MaxProgramTexelOffset = 7;
+
+ // Extensions constants.
+ resources->MaxDualSourceDrawBuffers = 0;
+
+ resources->MaxViewsOVR = 4;
+
+ // Disable name hashing by default.
+ resources->HashFunction = nullptr;
+
+ resources->MaxExpressionComplexity = 256;
+ resources->MaxCallStackDepth = 256;
+ resources->MaxFunctionParameters = 1024;
+
+ // ES 3.1 Revision 4, 7.2 Built-in Constants
+
+ // ES 3.1, Revision 4, 8.13 Texture minification
+ // "The value of MIN_PROGRAM_TEXTURE_GATHER_OFFSET must be less than or equal to the value of
+ // MIN_PROGRAM_TEXEL_OFFSET. The value of MAX_PROGRAM_TEXTURE_GATHER_OFFSET must be greater than
+ // or equal to the value of MAX_PROGRAM_TEXEL_OFFSET"
+ resources->MinProgramTextureGatherOffset = -8;
+ resources->MaxProgramTextureGatherOffset = 7;
+
+ resources->MaxImageUnits = 4;
+ resources->MaxVertexImageUniforms = 0;
+ resources->MaxFragmentImageUniforms = 0;
+ resources->MaxComputeImageUniforms = 4;
+ resources->MaxCombinedImageUniforms = 4;
+
+ resources->MaxUniformLocations = 1024;
+
+ 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;
+
+ resources->MaxUniformBufferBindings = 32;
+ resources->MaxShaderStorageBufferBindings = 4;
+
+ resources->MaxGeometryUniformComponents = 1024;
+ resources->MaxGeometryUniformBlocks = 12;
+ resources->MaxGeometryInputComponents = 64;
+ resources->MaxGeometryOutputComponents = 64;
+ resources->MaxGeometryOutputVertices = 256;
+ resources->MaxGeometryTotalOutputComponents = 1024;
+ resources->MaxGeometryTextureImageUnits = 16;
+ resources->MaxGeometryAtomicCounterBuffers = 0;
+ resources->MaxGeometryAtomicCounters = 0;
+ resources->MaxGeometryShaderStorageBlocks = 0;
+ resources->MaxGeometryShaderInvocations = 32;
+ resources->MaxGeometryImageUniforms = 0;
+
+ resources->MaxTessControlInputComponents = 64;
+ resources->MaxTessControlOutputComponents = 64;
+ resources->MaxTessControlTextureImageUnits = 16;
+ resources->MaxTessControlUniformComponents = 1024;
+ resources->MaxTessControlTotalOutputComponents = 2048;
+ resources->MaxTessControlImageUniforms = 0;
+ resources->MaxTessControlAtomicCounters = 0;
+ resources->MaxTessControlAtomicCounterBuffers = 0;
+
+ resources->MaxTessPatchComponents = 120;
+ resources->MaxPatchVertices = 32;
+ resources->MaxTessGenLevel = 64;
+
+ resources->MaxTessEvaluationInputComponents = 64;
+ resources->MaxTessEvaluationOutputComponents = 64;
+ resources->MaxTessEvaluationTextureImageUnits = 16;
+ resources->MaxTessEvaluationUniformComponents = 1024;
+ resources->MaxTessEvaluationImageUniforms = 0;
+ resources->MaxTessEvaluationAtomicCounters = 0;
+ resources->MaxTessEvaluationAtomicCounterBuffers = 0;
+
+ resources->SubPixelBits = 8;
+
+ resources->MaxSamples = 4;
+}
+
+//
+// Driver calls these to create and destroy compiler objects.
+//
+ShHandle ConstructCompiler(sh::GLenum type,
+ ShShaderSpec spec,
+ ShShaderOutput output,
+ const ShBuiltInResources *resources)
+{
+ TShHandleBase *base = static_cast<TShHandleBase *>(ConstructCompiler(type, spec, output));
+ if (base == nullptr)
+ {
+ return 0;
+ }
+
+ TCompiler *compiler = base->getAsCompiler();
+ if (compiler == nullptr)
+ {
+ return 0;
+ }
+
+ // Generate built-in symbol table.
+ if (!compiler->Init(*resources))
+ {
+ Destruct(base);
+ return 0;
+ }
+
+ return base;
+}
+
+void Destruct(ShHandle handle)
+{
+ if (handle == 0)
+ return;
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+
+ if (base->getAsCompiler())
+ DeleteCompiler(base->getAsCompiler());
+}
+
+ShBuiltInResources GetBuiltInResources(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ ASSERT(compiler);
+ return compiler->getBuiltInResources();
+}
+
+const std::string &GetBuiltInResourcesString(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ ASSERT(compiler);
+ return compiler->getBuiltInResourcesString();
+}
+
+//
+// Do an actual compile on the given strings. The result is left
+// in the given compile object.
+//
+// Return: The return value of ShCompile is really boolean, indicating
+// success or failure.
+//
+bool Compile(const ShHandle handle,
+ const char *const shaderStrings[],
+ size_t numStrings,
+ const ShCompileOptions &compileOptions)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ ASSERT(compiler);
+
+ return compiler->compile(shaderStrings, numStrings, compileOptions);
+}
+
+void ClearResults(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ ASSERT(compiler);
+ compiler->clearResults();
+}
+
+int GetShaderVersion(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ ASSERT(compiler);
+ return compiler->getShaderVersion();
+}
+
+ShShaderOutput GetShaderOutputType(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ ASSERT(compiler);
+ return compiler->getOutputType();
+}
+
+//
+// Return any compiler log of messages for the application.
+//
+const std::string &GetInfoLog(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ ASSERT(compiler);
+
+ TInfoSink &infoSink = compiler->getInfoSink();
+ return infoSink.info.str();
+}
+
+//
+// Return any object code.
+//
+const std::string &GetObjectCode(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ ASSERT(compiler);
+
+ TInfoSink &infoSink = compiler->getInfoSink();
+ return infoSink.obj.str();
+}
+
+//
+// Return any object binary code.
+//
+const BinaryBlob &GetObjectBinaryBlob(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ ASSERT(compiler);
+
+ TInfoSink &infoSink = compiler->getInfoSink();
+ return infoSink.obj.getBinary();
+}
+
+const std::map<std::string, std::string> *GetNameHashingMap(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ ASSERT(compiler);
+ return &(compiler->getNameMap());
+}
+
+const std::vector<ShaderVariable> *GetUniforms(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ if (!compiler)
+ {
+ return nullptr;
+ }
+ return &compiler->getUniforms();
+}
+
+const std::vector<ShaderVariable> *GetInputVaryings(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ if (compiler == nullptr)
+ {
+ return nullptr;
+ }
+ return &compiler->getInputVaryings();
+}
+
+const std::vector<ShaderVariable> *GetOutputVaryings(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ if (compiler == nullptr)
+ {
+ return nullptr;
+ }
+ return &compiler->getOutputVaryings();
+}
+
+const std::vector<ShaderVariable> *GetVaryings(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ if (compiler == nullptr)
+ {
+ return nullptr;
+ }
+
+ switch (compiler->getShaderType())
+ {
+ case GL_VERTEX_SHADER:
+ return &compiler->getOutputVaryings();
+ case GL_FRAGMENT_SHADER:
+ return &compiler->getInputVaryings();
+ case GL_COMPUTE_SHADER:
+ ASSERT(compiler->getOutputVaryings().empty() && compiler->getInputVaryings().empty());
+ return &compiler->getOutputVaryings();
+ // Since geometry shaders have both input and output varyings, we shouldn't call GetVaryings
+ // on a geometry shader.
+ default:
+ return nullptr;
+ }
+}
+
+const std::vector<ShaderVariable> *GetAttributes(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ if (!compiler)
+ {
+ return nullptr;
+ }
+ return &compiler->getAttributes();
+}
+
+const std::vector<ShaderVariable> *GetOutputVariables(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ if (!compiler)
+ {
+ return nullptr;
+ }
+ return &compiler->getOutputVariables();
+}
+
+const std::vector<InterfaceBlock> *GetInterfaceBlocks(const ShHandle handle)
+{
+ return GetShaderVariables<InterfaceBlock>(handle);
+}
+
+const std::vector<InterfaceBlock> *GetUniformBlocks(const ShHandle handle)
+{
+ ASSERT(handle);
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return &compiler->getUniformBlocks();
+}
+
+const std::vector<InterfaceBlock> *GetShaderStorageBlocks(const ShHandle handle)
+{
+ ASSERT(handle);
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return &compiler->getShaderStorageBlocks();
+}
+
+WorkGroupSize GetComputeShaderLocalGroupSize(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return compiler->getComputeShaderLocalSize();
+}
+
+int GetVertexShaderNumViews(const ShHandle handle)
+{
+ ASSERT(handle);
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return compiler->getNumViews();
+}
+
+bool EnablesPerSampleShading(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ if (compiler == nullptr)
+ {
+ return false;
+ }
+ return compiler->enablesPerSampleShading();
+}
+
+uint32_t GetShaderSpecConstUsageBits(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ if (compiler == nullptr)
+ {
+ return 0;
+ }
+ return compiler->getSpecConstUsageBits().bits();
+}
+
+bool CheckVariablesWithinPackingLimits(int maxVectors, const std::vector<ShaderVariable> &variables)
+{
+ return CheckVariablesInPackingLimits(maxVectors, variables);
+}
+
+bool GetShaderStorageBlockRegister(const ShHandle handle,
+ const std::string &shaderStorageBlockName,
+ unsigned int *indexOut)
+{
+#ifdef ANGLE_ENABLE_HLSL
+ ASSERT(indexOut);
+
+ TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
+ ASSERT(translator);
+
+ if (!translator->hasShaderStorageBlock(shaderStorageBlockName))
+ {
+ return false;
+ }
+
+ *indexOut = translator->getShaderStorageBlockRegister(shaderStorageBlockName);
+ return true;
+#else
+ return false;
+#endif // ANGLE_ENABLE_HLSL
+}
+
+bool GetUniformBlockRegister(const ShHandle handle,
+ const std::string &uniformBlockName,
+ unsigned int *indexOut)
+{
+#ifdef ANGLE_ENABLE_HLSL
+ ASSERT(indexOut);
+
+ TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
+ ASSERT(translator);
+
+ if (!translator->hasUniformBlock(uniformBlockName))
+ {
+ return false;
+ }
+
+ *indexOut = translator->getUniformBlockRegister(uniformBlockName);
+ return true;
+#else
+ return false;
+#endif // ANGLE_ENABLE_HLSL
+}
+
+bool ShouldUniformBlockUseStructuredBuffer(const ShHandle handle,
+ const std::string &uniformBlockName)
+{
+#ifdef ANGLE_ENABLE_HLSL
+ TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
+ ASSERT(translator);
+
+ return translator->shouldUniformBlockUseStructuredBuffer(uniformBlockName);
+#else
+ return false;
+#endif // ANGLE_ENABLE_HLSL
+}
+
+const std::map<std::string, unsigned int> *GetUniformRegisterMap(const ShHandle handle)
+{
+#ifdef ANGLE_ENABLE_HLSL
+ TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
+ ASSERT(translator);
+
+ return translator->getUniformRegisterMap();
+#else
+ return nullptr;
+#endif // ANGLE_ENABLE_HLSL
+}
+
+const std::set<std::string> *GetSlowCompilingUniformBlockSet(const ShHandle handle)
+{
+#ifdef ANGLE_ENABLE_HLSL
+ TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
+ ASSERT(translator);
+
+ return translator->getSlowCompilingUniformBlockSet();
+#else
+ return nullptr;
+#endif // ANGLE_ENABLE_HLSL
+}
+
+unsigned int GetReadonlyImage2DRegisterIndex(const ShHandle handle)
+{
+#ifdef ANGLE_ENABLE_HLSL
+ TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
+ ASSERT(translator);
+
+ return translator->getReadonlyImage2DRegisterIndex();
+#else
+ return 0;
+#endif // ANGLE_ENABLE_HLSL
+}
+
+unsigned int GetImage2DRegisterIndex(const ShHandle handle)
+{
+#ifdef ANGLE_ENABLE_HLSL
+ TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
+ ASSERT(translator);
+
+ return translator->getImage2DRegisterIndex();
+#else
+ return 0;
+#endif // ANGLE_ENABLE_HLSL
+}
+
+const std::set<std::string> *GetUsedImage2DFunctionNames(const ShHandle handle)
+{
+#ifdef ANGLE_ENABLE_HLSL
+ TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
+ ASSERT(translator);
+
+ return translator->getUsedImage2DFunctionNames();
+#else
+ return nullptr;
+#endif // ANGLE_ENABLE_HLSL
+}
+
+bool HasDiscardInFragmentShader(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return compiler->getShaderType() == GL_FRAGMENT_SHADER && compiler->hasDiscard();
+}
+
+bool HasValidGeometryShaderInputPrimitiveType(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return compiler->getGeometryShaderInputPrimitiveType() != EptUndefined;
+}
+
+bool HasValidGeometryShaderOutputPrimitiveType(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return compiler->getGeometryShaderOutputPrimitiveType() != EptUndefined;
+}
+
+bool HasValidGeometryShaderMaxVertices(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return compiler->getGeometryShaderMaxVertices() >= 0;
+}
+
+bool HasValidTessGenMode(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return compiler->getTessEvaluationShaderInputPrimitiveType() != EtetUndefined;
+}
+
+bool HasValidTessGenSpacing(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return compiler->getTessEvaluationShaderInputVertexSpacingType() != EtetUndefined;
+}
+
+bool HasValidTessGenVertexOrder(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return compiler->getTessEvaluationShaderInputOrderingType() != EtetUndefined;
+}
+
+bool HasValidTessGenPointMode(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return compiler->getTessEvaluationShaderInputPointType() != EtetUndefined;
+}
+
+GLenum GetGeometryShaderInputPrimitiveType(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return GetGeometryShaderPrimitiveTypeEnum(compiler->getGeometryShaderInputPrimitiveType());
+}
+
+GLenum GetGeometryShaderOutputPrimitiveType(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return GetGeometryShaderPrimitiveTypeEnum(compiler->getGeometryShaderOutputPrimitiveType());
+}
+
+int GetGeometryShaderInvocations(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return compiler->getGeometryShaderInvocations();
+}
+
+int GetGeometryShaderMaxVertices(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ int maxVertices = compiler->getGeometryShaderMaxVertices();
+ ASSERT(maxVertices >= 0);
+ return maxVertices;
+}
+
+int GetTessControlShaderVertices(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ int vertices = compiler->getTessControlShaderOutputVertices();
+ return vertices;
+}
+
+GLenum GetTessGenMode(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return GetTessellationShaderTypeEnum(compiler->getTessEvaluationShaderInputPrimitiveType());
+}
+
+GLenum GetTessGenSpacing(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return GetTessellationShaderTypeEnum(compiler->getTessEvaluationShaderInputVertexSpacingType());
+}
+
+GLenum GetTessGenVertexOrder(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return GetTessellationShaderTypeEnum(compiler->getTessEvaluationShaderInputOrderingType());
+}
+
+GLenum GetTessGenPointMode(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ return GetTessellationShaderTypeEnum(compiler->getTessEvaluationShaderInputPointType());
+}
+
+unsigned int GetShaderSharedMemorySize(const ShHandle handle)
+{
+ ASSERT(handle);
+
+ TShHandleBase *base = static_cast<TShHandleBase *>(handle);
+ TCompiler *compiler = base->getAsCompiler();
+ ASSERT(compiler);
+
+ unsigned int sharedMemorySize = compiler->getSharedMemorySize();
+ return sharedMemorySize;
+}
+
+uint32_t GetAdvancedBlendEquations(const ShHandle handle)
+{
+ TCompiler *compiler = GetCompilerFromHandle(handle);
+ ASSERT(compiler);
+
+ return compiler->getAdvancedBlendEquations().bits();
+}
+
+void InitializeGlslang()
+{
+ if (initializeGlslangRefCount == 0)
+ {
+ GlslangInitialize();
+ }
+ ++initializeGlslangRefCount;
+ ASSERT(initializeGlslangRefCount < std::numeric_limits<int>::max());
+}
+
+void FinalizeGlslang()
+{
+ --initializeGlslangRefCount;
+ ASSERT(initializeGlslangRefCount >= 0);
+ if (initializeGlslangRefCount == 0)
+ {
+ GlslangFinalize();
+ }
+}
+
+// Can't prefix with just _ because then we might introduce a double underscore, which is not safe
+// in GLSL (ESSL 3.00.6 section 3.8: All identifiers containing a double underscore are reserved for
+// use by the underlying implementation). u is short for user-defined.
+const char kUserDefinedNamePrefix[] = "_u";
+
+namespace vk
+{
+// Interface block name containing the aggregate default uniforms
+const char kDefaultUniformsNameVS[] = "defaultUniformsVS";
+const char kDefaultUniformsNameTCS[] = "defaultUniformsTCS";
+const char kDefaultUniformsNameTES[] = "defaultUniformsTES";
+const char kDefaultUniformsNameGS[] = "defaultUniformsGS";
+const char kDefaultUniformsNameFS[] = "defaultUniformsFS";
+const char kDefaultUniformsNameCS[] = "defaultUniformsCS";
+
+// Interface block and variable names containing driver uniforms
+const char kDriverUniformsBlockName[] = "ANGLEUniformBlock";
+const char kDriverUniformsVarName[] = "ANGLEUniforms";
+
+// Interface block array name used for atomic counter emulation
+const char kAtomicCountersBlockName[] = "ANGLEAtomicCounters";
+
+const char kXfbEmulationGetOffsetsFunctionName[] = "ANGLEGetXfbOffsets";
+const char kXfbEmulationCaptureFunctionName[] = "ANGLECaptureXfb";
+const char kXfbEmulationBufferBlockName[] = "ANGLEXfbBuffer";
+const char kXfbEmulationBufferName[] = "ANGLEXfb";
+const char kXfbEmulationBufferFieldName[] = "xfbOut";
+
+const char kTransformPositionFunctionName[] = "ANGLETransformPosition";
+
+const char kXfbExtensionPositionOutName[] = "ANGLEXfbPosition";
+
+// EXT_shader_framebuffer_fetch / EXT_shader_framebuffer_fetch_non_coherent
+const char kInputAttachmentName[] = "ANGLEInputAttachment";
+
+} // namespace vk
+
+const char *BlockLayoutTypeToString(BlockLayoutType type)
+{
+ switch (type)
+ {
+ case BlockLayoutType::BLOCKLAYOUT_STD140:
+ return "std140";
+ case BlockLayoutType::BLOCKLAYOUT_STD430:
+ return "std430";
+ case BlockLayoutType::BLOCKLAYOUT_PACKED:
+ return "packed";
+ case BlockLayoutType::BLOCKLAYOUT_SHARED:
+ return "shared";
+ default:
+ return "invalid";
+ }
+}
+
+const char *BlockTypeToString(BlockType type)
+{
+ switch (type)
+ {
+ case BlockType::BLOCK_BUFFER:
+ return "buffer";
+ case BlockType::BLOCK_UNIFORM:
+ return "uniform";
+ default:
+ return "invalid";
+ }
+}
+
+const char *InterpolationTypeToString(InterpolationType type)
+{
+ switch (type)
+ {
+ case InterpolationType::INTERPOLATION_SMOOTH:
+ return "smooth";
+ case InterpolationType::INTERPOLATION_CENTROID:
+ return "centroid";
+ case InterpolationType::INTERPOLATION_SAMPLE:
+ return "sample";
+ case InterpolationType::INTERPOLATION_FLAT:
+ return "flat";
+ case InterpolationType::INTERPOLATION_NOPERSPECTIVE:
+ return "noperspective";
+ default:
+ return "invalid";
+ }
+}
+} // namespace sh
+
+ShCompileOptions::ShCompileOptions()
+{
+ memset(this, 0, sizeof(*this));
+}
+
+ShCompileOptions::ShCompileOptions(const ShCompileOptions &other)
+{
+ memcpy(this, &other, sizeof(*this));
+}
+ShCompileOptions &ShCompileOptions::operator=(const ShCompileOptions &other)
+{
+ memcpy(this, &other, sizeof(*this));
+ return *this;
+}
+
+ShBuiltInResources::ShBuiltInResources()
+{
+ memset(this, 0, sizeof(*this));
+}
+
+ShBuiltInResources::ShBuiltInResources(const ShBuiltInResources &other)
+{
+ memcpy(this, &other, sizeof(*this));
+}
+ShBuiltInResources &ShBuiltInResources::operator=(const ShBuiltInResources &other)
+{
+ memcpy(this, &other, sizeof(*this));
+ return *this;
+}
diff --git a/gfx/angle/checkout/src/compiler/translator/ShaderStorageBlockFunctionHLSL.cpp b/gfx/angle/checkout/src/compiler/translator/ShaderStorageBlockFunctionHLSL.cpp
new file mode 100644
index 0000000000..f4eeab5ab9
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ShaderStorageBlockFunctionHLSL.cpp
@@ -0,0 +1,439 @@
+//
+// Copyright 2018 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.
+//
+// ShaderStorageBlockFunctionHLSL: Wrapper functions for RWByteAddressBuffer Load/Store functions.
+//
+
+#include "compiler/translator/ShaderStorageBlockFunctionHLSL.h"
+
+#include "common/utilities.h"
+#include "compiler/translator/UtilsHLSL.h"
+#include "compiler/translator/blocklayout.h"
+#include "compiler/translator/blocklayoutHLSL.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+// static
+void ShaderStorageBlockFunctionHLSL::OutputSSBOLoadFunctionBody(
+ TInfoSinkBase &out,
+ const ShaderStorageBlockFunction &ssboFunction)
+{
+ const char *convertString;
+ switch (ssboFunction.type.getBasicType())
+ {
+ case EbtFloat:
+ convertString = "asfloat(";
+ break;
+ case EbtInt:
+ convertString = "asint(";
+ break;
+ case EbtUInt:
+ convertString = "asuint(";
+ break;
+ case EbtBool:
+ convertString = "asint(";
+ break;
+ default:
+ UNREACHABLE();
+ return;
+ }
+
+ size_t bytesPerComponent =
+ gl::VariableComponentSize(gl::VariableComponentType(GLVariableType(ssboFunction.type)));
+ out << " " << ssboFunction.typeString << " result";
+ if (ssboFunction.type.isScalar())
+ {
+ size_t offset = ssboFunction.swizzleOffsets[0] * bytesPerComponent;
+ out << " = " << convertString << "buffer.Load(loc + " << offset << "));\n ";
+ }
+ else if (ssboFunction.type.isVector())
+ {
+ if (ssboFunction.rowMajor || !ssboFunction.isDefaultSwizzle)
+ {
+ size_t componentStride = bytesPerComponent;
+ if (ssboFunction.rowMajor)
+ {
+ componentStride = ssboFunction.matrixStride;
+ }
+
+ out << " = {";
+ for (const int offset : ssboFunction.swizzleOffsets)
+ {
+ size_t offsetInBytes = offset * componentStride;
+ out << convertString << "buffer.Load(loc + " << offsetInBytes << ")),";
+ }
+ out << "};\n";
+ }
+ else
+ {
+ out << " = " << convertString << "buffer.Load"
+ << static_cast<uint32_t>(ssboFunction.type.getNominalSize()) << "(loc));\n";
+ }
+ }
+ else if (ssboFunction.type.isMatrix())
+ {
+ if (ssboFunction.rowMajor)
+ {
+ out << ";";
+ out << " float" << static_cast<uint32_t>(ssboFunction.type.getRows()) << "x"
+ << static_cast<uint32_t>(ssboFunction.type.getCols()) << " tmp_ = {";
+ for (uint8_t rowIndex = 0; rowIndex < ssboFunction.type.getRows(); rowIndex++)
+ {
+ out << "asfloat(buffer.Load" << static_cast<uint32_t>(ssboFunction.type.getCols())
+ << "(loc + " << rowIndex * ssboFunction.matrixStride << ")), ";
+ }
+ out << "};\n";
+ out << " result = transpose(tmp_);\n";
+ }
+ else
+ {
+ out << " = {";
+ for (uint8_t columnIndex = 0; columnIndex < ssboFunction.type.getCols(); columnIndex++)
+ {
+ out << "asfloat(buffer.Load" << static_cast<uint32_t>(ssboFunction.type.getRows())
+ << "(loc + " << columnIndex * ssboFunction.matrixStride << ")), ";
+ }
+ out << "};\n";
+ }
+ }
+ else
+ {
+ // TODO(jiajia.qin@intel.com): Process all possible return types. http://anglebug.com/1951
+ out << ";\n";
+ }
+
+ out << " return result;\n";
+ return;
+}
+
+// static
+void ShaderStorageBlockFunctionHLSL::OutputSSBOStoreFunctionBody(
+ TInfoSinkBase &out,
+ const ShaderStorageBlockFunction &ssboFunction)
+{
+ size_t bytesPerComponent =
+ gl::VariableComponentSize(gl::VariableComponentType(GLVariableType(ssboFunction.type)));
+ if (ssboFunction.type.isScalar())
+ {
+ size_t offset = ssboFunction.swizzleOffsets[0] * bytesPerComponent;
+ if (ssboFunction.type.getBasicType() == EbtBool)
+ {
+ out << " buffer.Store(loc + " << offset << ", uint(value));\n";
+ }
+ else
+ {
+ out << " buffer.Store(loc + " << offset << ", asuint(value));\n";
+ }
+ }
+ else if (ssboFunction.type.isVector())
+ {
+ out << " uint" << static_cast<uint32_t>(ssboFunction.type.getNominalSize())
+ << " _value;\n";
+ if (ssboFunction.type.getBasicType() == EbtBool)
+ {
+ out << " _value = uint" << static_cast<uint32_t>(ssboFunction.type.getNominalSize())
+ << "(value);\n";
+ }
+ else
+ {
+ out << " _value = asuint(value);\n";
+ }
+
+ if (ssboFunction.rowMajor || !ssboFunction.isDefaultSwizzle)
+ {
+ size_t componentStride = bytesPerComponent;
+ if (ssboFunction.rowMajor)
+ {
+ componentStride = ssboFunction.matrixStride;
+ }
+ const TVector<int> &swizzleOffsets = ssboFunction.swizzleOffsets;
+ for (int index = 0; index < static_cast<int>(swizzleOffsets.size()); index++)
+ {
+ size_t offsetInBytes = swizzleOffsets[index] * componentStride;
+ out << "buffer.Store(loc + " << offsetInBytes << ", _value[" << index << "]);\n";
+ }
+ }
+ else
+ {
+ out << " buffer.Store" << static_cast<uint32_t>(ssboFunction.type.getNominalSize())
+ << "(loc, _value);\n";
+ }
+ }
+ else if (ssboFunction.type.isMatrix())
+ {
+ if (ssboFunction.rowMajor)
+ {
+ out << " float" << static_cast<uint32_t>(ssboFunction.type.getRows()) << "x"
+ << static_cast<uint32_t>(ssboFunction.type.getCols())
+ << " tmp_ = transpose(value);\n";
+ for (uint8_t rowIndex = 0; rowIndex < ssboFunction.type.getRows(); rowIndex++)
+ {
+ out << " buffer.Store" << static_cast<uint32_t>(ssboFunction.type.getCols())
+ << "(loc + " << rowIndex * ssboFunction.matrixStride << ", asuint(tmp_["
+ << static_cast<uint32_t>(rowIndex) << "]));\n";
+ }
+ }
+ else
+ {
+ for (uint8_t columnIndex = 0; columnIndex < ssboFunction.type.getCols(); columnIndex++)
+ {
+ out << " buffer.Store" << static_cast<uint32_t>(ssboFunction.type.getRows())
+ << "(loc + " << columnIndex * ssboFunction.matrixStride << ", asuint(value["
+ << static_cast<uint32_t>(columnIndex) << "]));\n";
+ }
+ }
+ }
+ else
+ {
+ // TODO(jiajia.qin@intel.com): Process all possible return types. http://anglebug.com/1951
+ }
+}
+
+// static
+void ShaderStorageBlockFunctionHLSL::OutputSSBOLengthFunctionBody(TInfoSinkBase &out,
+ int unsizedArrayStride)
+{
+ out << " uint dim = 0;\n";
+ out << " buffer.GetDimensions(dim);\n";
+ out << " return int((dim - loc)/uint(" << unsizedArrayStride << "));\n";
+}
+
+// static
+void ShaderStorageBlockFunctionHLSL::OutputSSBOAtomicMemoryFunctionBody(
+ TInfoSinkBase &out,
+ const ShaderStorageBlockFunction &ssboFunction)
+{
+ out << " " << ssboFunction.typeString << " original_value;\n";
+ switch (ssboFunction.method)
+ {
+ case SSBOMethod::ATOMIC_ADD:
+ out << " buffer.InterlockedAdd(loc, value, original_value);\n";
+ break;
+ case SSBOMethod::ATOMIC_MIN:
+ out << " buffer.InterlockedMin(loc, value, original_value);\n";
+ break;
+ case SSBOMethod::ATOMIC_MAX:
+ out << " buffer.InterlockedMax(loc, value, original_value);\n";
+ break;
+ case SSBOMethod::ATOMIC_AND:
+ out << " buffer.InterlockedAnd(loc, value, original_value);\n";
+ break;
+ case SSBOMethod::ATOMIC_OR:
+ out << " buffer.InterlockedOr(loc, value, original_value);\n";
+ break;
+ case SSBOMethod::ATOMIC_XOR:
+ out << " buffer.InterlockedXor(loc, value, original_value);\n";
+ break;
+ case SSBOMethod::ATOMIC_EXCHANGE:
+ out << " buffer.InterlockedExchange(loc, value, original_value);\n";
+ break;
+ case SSBOMethod::ATOMIC_COMPSWAP:
+ out << " buffer.InterlockedCompareExchange(loc, compare_value, value, "
+ "original_value);\n";
+ break;
+ default:
+ UNREACHABLE();
+ }
+ out << " return original_value;\n";
+}
+
+bool ShaderStorageBlockFunctionHLSL::ShaderStorageBlockFunction::operator<(
+ const ShaderStorageBlockFunction &rhs) const
+{
+ return functionName < rhs.functionName;
+}
+
+TString ShaderStorageBlockFunctionHLSL::registerShaderStorageBlockFunction(
+ const TType &type,
+ SSBOMethod method,
+ TLayoutBlockStorage storage,
+ bool rowMajor,
+ int matrixStride,
+ int unsizedArrayStride,
+ TIntermSwizzle *swizzleNode)
+{
+ ShaderStorageBlockFunction ssboFunction;
+ ssboFunction.typeString = TypeString(type);
+ ssboFunction.method = method;
+ switch (method)
+ {
+ case SSBOMethod::LOAD:
+ ssboFunction.functionName = "_Load_";
+ break;
+ case SSBOMethod::STORE:
+ ssboFunction.functionName = "_Store_";
+ break;
+ case SSBOMethod::LENGTH:
+ ssboFunction.unsizedArrayStride = unsizedArrayStride;
+ ssboFunction.functionName = "_Length_" + str(unsizedArrayStride);
+ mRegisteredShaderStorageBlockFunctions.insert(ssboFunction);
+ return ssboFunction.functionName;
+ case SSBOMethod::ATOMIC_ADD:
+ ssboFunction.functionName = "_ssbo_atomicAdd_" + ssboFunction.typeString;
+ mRegisteredShaderStorageBlockFunctions.insert(ssboFunction);
+ return ssboFunction.functionName;
+ case SSBOMethod::ATOMIC_MIN:
+ ssboFunction.functionName = "_ssbo_atomicMin_" + ssboFunction.typeString;
+ mRegisteredShaderStorageBlockFunctions.insert(ssboFunction);
+ return ssboFunction.functionName;
+ case SSBOMethod::ATOMIC_MAX:
+ ssboFunction.functionName = "_ssbo_atomicMax_" + ssboFunction.typeString;
+ mRegisteredShaderStorageBlockFunctions.insert(ssboFunction);
+ return ssboFunction.functionName;
+ case SSBOMethod::ATOMIC_AND:
+ ssboFunction.functionName = "_ssbo_atomicAnd_" + ssboFunction.typeString;
+ mRegisteredShaderStorageBlockFunctions.insert(ssboFunction);
+ return ssboFunction.functionName;
+ case SSBOMethod::ATOMIC_OR:
+ ssboFunction.functionName = "_ssbo_atomicOr_" + ssboFunction.typeString;
+ mRegisteredShaderStorageBlockFunctions.insert(ssboFunction);
+ return ssboFunction.functionName;
+ case SSBOMethod::ATOMIC_XOR:
+ ssboFunction.functionName = "_ssbo_atomicXor_" + ssboFunction.typeString;
+ mRegisteredShaderStorageBlockFunctions.insert(ssboFunction);
+ return ssboFunction.functionName;
+ case SSBOMethod::ATOMIC_EXCHANGE:
+ ssboFunction.functionName = "_ssbo_atomicExchange_" + ssboFunction.typeString;
+ mRegisteredShaderStorageBlockFunctions.insert(ssboFunction);
+ return ssboFunction.functionName;
+ case SSBOMethod::ATOMIC_COMPSWAP:
+ ssboFunction.functionName = "_ssbo_atomicCompSwap_" + ssboFunction.typeString;
+ mRegisteredShaderStorageBlockFunctions.insert(ssboFunction);
+ return ssboFunction.functionName;
+ default:
+ UNREACHABLE();
+ }
+
+ ssboFunction.functionName += ssboFunction.typeString;
+ ssboFunction.type = type;
+ if (swizzleNode != nullptr)
+ {
+ ssboFunction.swizzleOffsets = swizzleNode->getSwizzleOffsets();
+ ssboFunction.isDefaultSwizzle = false;
+ }
+ else
+ {
+ if (ssboFunction.type.getNominalSize() > 1)
+ {
+ for (uint8_t index = 0; index < ssboFunction.type.getNominalSize(); index++)
+ {
+ ssboFunction.swizzleOffsets.push_back(index);
+ }
+ }
+ else
+ {
+ ssboFunction.swizzleOffsets.push_back(0);
+ }
+
+ ssboFunction.isDefaultSwizzle = true;
+ }
+ ssboFunction.rowMajor = rowMajor;
+ ssboFunction.matrixStride = matrixStride;
+ ssboFunction.functionName += "_" + TString(getBlockStorageString(storage));
+
+ if (rowMajor)
+ {
+ ssboFunction.functionName += "_rm_";
+ }
+ else
+ {
+ ssboFunction.functionName += "_cm_";
+ }
+
+ for (const int offset : ssboFunction.swizzleOffsets)
+ {
+ switch (offset)
+ {
+ case 0:
+ ssboFunction.functionName += "x";
+ break;
+ case 1:
+ ssboFunction.functionName += "y";
+ break;
+ case 2:
+ ssboFunction.functionName += "z";
+ break;
+ case 3:
+ ssboFunction.functionName += "w";
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ mRegisteredShaderStorageBlockFunctions.insert(ssboFunction);
+ return ssboFunction.functionName;
+}
+
+void ShaderStorageBlockFunctionHLSL::shaderStorageBlockFunctionHeader(TInfoSinkBase &out)
+{
+ for (const ShaderStorageBlockFunction &ssboFunction : mRegisteredShaderStorageBlockFunctions)
+ {
+ switch (ssboFunction.method)
+ {
+ case SSBOMethod::LOAD:
+ {
+ // Function header
+ out << ssboFunction.typeString << " " << ssboFunction.functionName
+ << "(RWByteAddressBuffer buffer, uint loc)\n";
+ out << "{\n";
+ OutputSSBOLoadFunctionBody(out, ssboFunction);
+ break;
+ }
+ case SSBOMethod::STORE:
+ {
+ // Function header
+ out << "void " << ssboFunction.functionName
+ << "(RWByteAddressBuffer buffer, uint loc, " << ssboFunction.typeString
+ << " value)\n";
+ out << "{\n";
+ OutputSSBOStoreFunctionBody(out, ssboFunction);
+ break;
+ }
+ case SSBOMethod::LENGTH:
+ {
+ out << "int " << ssboFunction.functionName
+ << "(RWByteAddressBuffer buffer, uint loc)\n";
+ out << "{\n";
+ OutputSSBOLengthFunctionBody(out, ssboFunction.unsizedArrayStride);
+ break;
+ }
+ case SSBOMethod::ATOMIC_ADD:
+ case SSBOMethod::ATOMIC_MIN:
+ case SSBOMethod::ATOMIC_MAX:
+ case SSBOMethod::ATOMIC_AND:
+ case SSBOMethod::ATOMIC_OR:
+ case SSBOMethod::ATOMIC_XOR:
+ case SSBOMethod::ATOMIC_EXCHANGE:
+ {
+ out << ssboFunction.typeString << " " << ssboFunction.functionName
+ << "(RWByteAddressBuffer buffer, uint loc, " << ssboFunction.typeString
+ << " value)\n";
+ out << "{\n";
+
+ OutputSSBOAtomicMemoryFunctionBody(out, ssboFunction);
+ break;
+ }
+ case SSBOMethod::ATOMIC_COMPSWAP:
+ {
+ out << ssboFunction.typeString << " " << ssboFunction.functionName
+ << "(RWByteAddressBuffer buffer, uint loc, " << ssboFunction.typeString
+ << " compare_value, " << ssboFunction.typeString << " value)\n";
+ out << "{\n";
+ OutputSSBOAtomicMemoryFunctionBody(out, ssboFunction);
+ break;
+ }
+ default:
+ UNREACHABLE();
+ }
+
+ out << "}\n"
+ "\n";
+ }
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/ShaderStorageBlockFunctionHLSL.h b/gfx/angle/checkout/src/compiler/translator/ShaderStorageBlockFunctionHLSL.h
new file mode 100644
index 0000000000..0d3cd0291b
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ShaderStorageBlockFunctionHLSL.h
@@ -0,0 +1,94 @@
+//
+// Copyright 2018 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.
+//
+// ShaderStorageBlockOutputHLSL: A traverser to translate a ssbo_access_chain to an offset of
+// RWByteAddressBuffer.
+// //EOpIndexDirectInterfaceBlock
+// ssbo_variable :=
+// | the name of the SSBO
+// | the name of a variable in an SSBO backed interface block
+
+// // EOpIndexInDirect
+// // EOpIndexDirect
+// ssbo_array_indexing := ssbo_access_chain[expr_no_ssbo]
+
+// // EOpIndexDirectStruct
+// ssbo_structure_access := ssbo_access_chain.identifier
+
+// ssbo_access_chain :=
+// | ssbo_variable
+// | ssbo_array_indexing
+// | ssbo_structure_access
+//
+
+#ifndef COMPILER_TRANSLATOR_SHADERSTORAGEBLOCKFUNCTIONHLSL_H_
+#define COMPILER_TRANSLATOR_SHADERSTORAGEBLOCKFUNCTIONHLSL_H_
+
+#include <set>
+
+#include "compiler/translator/InfoSink.h"
+#include "compiler/translator/Types.h"
+
+namespace sh
+{
+
+class TIntermSwizzle;
+enum class SSBOMethod
+{
+ LOAD,
+ STORE,
+ LENGTH,
+ ATOMIC_ADD,
+ ATOMIC_MIN,
+ ATOMIC_MAX,
+ ATOMIC_AND,
+ ATOMIC_OR,
+ ATOMIC_XOR,
+ ATOMIC_EXCHANGE,
+ ATOMIC_COMPSWAP
+};
+
+class ShaderStorageBlockFunctionHLSL final : angle::NonCopyable
+{
+ public:
+ TString registerShaderStorageBlockFunction(const TType &type,
+ SSBOMethod method,
+ TLayoutBlockStorage storage,
+ bool rowMajor,
+ int matrixStride,
+ int unsizedArrayStride,
+ TIntermSwizzle *node);
+
+ void shaderStorageBlockFunctionHeader(TInfoSinkBase &out);
+
+ private:
+ struct ShaderStorageBlockFunction
+ {
+ bool operator<(const ShaderStorageBlockFunction &rhs) const;
+ TString functionName;
+ TString typeString;
+ SSBOMethod method;
+ TType type;
+ bool rowMajor;
+ int matrixStride;
+ int unsizedArrayStride;
+ TVector<int> swizzleOffsets;
+ bool isDefaultSwizzle;
+ };
+
+ static void OutputSSBOLoadFunctionBody(TInfoSinkBase &out,
+ const ShaderStorageBlockFunction &ssboFunction);
+ static void OutputSSBOStoreFunctionBody(TInfoSinkBase &out,
+ const ShaderStorageBlockFunction &ssboFunction);
+ static void OutputSSBOLengthFunctionBody(TInfoSinkBase &out, int unsizedArrayStride);
+ static void OutputSSBOAtomicMemoryFunctionBody(TInfoSinkBase &out,
+ const ShaderStorageBlockFunction &ssboFunction);
+ using ShaderStorageBlockFunctionSet = std::set<ShaderStorageBlockFunction>;
+ ShaderStorageBlockFunctionSet mRegisteredShaderStorageBlockFunctions;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_SHADERSTORAGEBLOCKFUNCTIONHLSL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/ShaderStorageBlockOutputHLSL.cpp b/gfx/angle/checkout/src/compiler/translator/ShaderStorageBlockOutputHLSL.cpp
new file mode 100644
index 0000000000..2ff01e439e
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ShaderStorageBlockOutputHLSL.cpp
@@ -0,0 +1,667 @@
+//
+// Copyright 2018 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.
+//
+// ShaderStorageBlockOutputHLSL: A traverser to translate a ssbo_access_chain to an offset of
+// RWByteAddressBuffer.
+// //EOpIndexDirectInterfaceBlock
+// ssbo_variable :=
+// | the name of the SSBO
+// | the name of a variable in an SSBO backed interface block
+
+// // EOpIndexInDirect
+// // EOpIndexDirect
+// ssbo_array_indexing := ssbo_access_chain[expr_no_ssbo]
+
+// // EOpIndexDirectStruct
+// ssbo_structure_access := ssbo_access_chain.identifier
+
+// ssbo_access_chain :=
+// | ssbo_variable
+// | ssbo_array_indexing
+// | ssbo_structure_access
+//
+
+#include "compiler/translator/ShaderStorageBlockOutputHLSL.h"
+
+#include "compiler/translator/ResourcesHLSL.h"
+#include "compiler/translator/blocklayoutHLSL.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+constexpr const char kShaderStorageDeclarationString[] =
+ "// @@ SHADER STORAGE DECLARATION STRING @@";
+
+void GetBlockLayoutInfo(TIntermTyped *node,
+ bool rowMajorAlreadyAssigned,
+ TLayoutBlockStorage *storage,
+ bool *rowMajor)
+{
+ TIntermSwizzle *swizzleNode = node->getAsSwizzleNode();
+ if (swizzleNode)
+ {
+ return GetBlockLayoutInfo(swizzleNode->getOperand(), rowMajorAlreadyAssigned, storage,
+ rowMajor);
+ }
+
+ TIntermBinary *binaryNode = node->getAsBinaryNode();
+ if (binaryNode)
+ {
+ switch (binaryNode->getOp())
+ {
+ case EOpIndexDirectInterfaceBlock:
+ {
+ // The column_major/row_major qualifier of a field member overrides the interface
+ // block's row_major/column_major. So we can assign rowMajor here and don't need to
+ // assign it again. But we still need to call recursively to get the storage's
+ // value.
+ const TType &type = node->getType();
+ *rowMajor = type.getLayoutQualifier().matrixPacking == EmpRowMajor;
+ return GetBlockLayoutInfo(binaryNode->getLeft(), true, storage, rowMajor);
+ }
+ case EOpIndexIndirect:
+ case EOpIndexDirect:
+ case EOpIndexDirectStruct:
+ return GetBlockLayoutInfo(binaryNode->getLeft(), rowMajorAlreadyAssigned, storage,
+ rowMajor);
+ default:
+ UNREACHABLE();
+ return;
+ }
+ }
+
+ const TType &type = node->getType();
+ ASSERT(type.getQualifier() == EvqBuffer);
+ const TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
+ ASSERT(interfaceBlock);
+ *storage = interfaceBlock->blockStorage();
+ // If the block doesn't have an instance name, rowMajorAlreadyAssigned will be false. In
+ // this situation, we still need to set rowMajor's value.
+ if (!rowMajorAlreadyAssigned)
+ {
+ *rowMajor = type.getLayoutQualifier().matrixPacking == EmpRowMajor;
+ }
+}
+
+// It's possible that the current type has lost the original layout information. So we should pass
+// the right layout information to GetBlockMemberInfoByType.
+const BlockMemberInfo GetBlockMemberInfoByType(const TType &type,
+ TLayoutBlockStorage storage,
+ bool rowMajor)
+{
+ sh::Std140BlockEncoder std140Encoder;
+ sh::Std430BlockEncoder std430Encoder;
+ sh::HLSLBlockEncoder hlslEncoder(sh::HLSLBlockEncoder::ENCODE_PACKED, false);
+ sh::BlockLayoutEncoder *encoder = nullptr;
+
+ if (storage == EbsStd140)
+ {
+ encoder = &std140Encoder;
+ }
+ else if (storage == EbsStd430)
+ {
+ encoder = &std430Encoder;
+ }
+ else
+ {
+ encoder = &hlslEncoder;
+ }
+
+ std::vector<unsigned int> arraySizes;
+ const TSpan<const unsigned int> &typeArraySizes = type.getArraySizes();
+ if (!typeArraySizes.empty())
+ {
+ arraySizes.assign(typeArraySizes.begin(), typeArraySizes.end());
+ }
+ return encoder->encodeType(GLVariableType(type), arraySizes, rowMajor);
+}
+
+const TField *GetFieldMemberInShaderStorageBlock(const TInterfaceBlock *interfaceBlock,
+ const ImmutableString &variableName)
+{
+ for (const TField *field : interfaceBlock->fields())
+ {
+ if (field->name() == variableName)
+ {
+ return field;
+ }
+ }
+ return nullptr;
+}
+
+const InterfaceBlock *FindInterfaceBlock(const TInterfaceBlock *needle,
+ const std::vector<InterfaceBlock> &haystack)
+{
+ for (const InterfaceBlock &block : haystack)
+ {
+ if (strcmp(block.name.c_str(), needle->name().data()) == 0)
+ {
+ ASSERT(block.fields.size() == needle->fields().size());
+ return &block;
+ }
+ }
+
+ UNREACHABLE();
+ return nullptr;
+}
+
+std::string StripArrayIndices(const std::string &nameIn)
+{
+ std::string name = nameIn;
+ size_t pos = name.find('[');
+ while (pos != std::string::npos)
+ {
+ size_t closePos = name.find(']', pos);
+ ASSERT(closePos != std::string::npos);
+ name.erase(pos, closePos - pos + 1);
+ pos = name.find('[', pos);
+ }
+ ASSERT(name.find(']') == std::string::npos);
+ return name;
+}
+
+// Does not include any array indices.
+void MapVariableToField(const ShaderVariable &variable,
+ const TField *field,
+ std::string currentName,
+ ShaderVarToFieldMap *shaderVarToFieldMap)
+{
+ ASSERT((field->type()->getStruct() == nullptr) == variable.fields.empty());
+ (*shaderVarToFieldMap)[currentName] = field;
+
+ if (!variable.fields.empty())
+ {
+ const TStructure *subStruct = field->type()->getStruct();
+ ASSERT(variable.fields.size() == subStruct->fields().size());
+
+ for (size_t index = 0; index < variable.fields.size(); ++index)
+ {
+ const TField *subField = subStruct->fields()[index];
+ const ShaderVariable &subVariable = variable.fields[index];
+ std::string subName = currentName + "." + subVariable.name;
+ MapVariableToField(subVariable, subField, subName, shaderVarToFieldMap);
+ }
+ }
+}
+
+class BlockInfoVisitor final : public BlockEncoderVisitor
+{
+ public:
+ BlockInfoVisitor(const std::string &prefix,
+ TLayoutBlockStorage storage,
+ const ShaderVarToFieldMap &shaderVarToFieldMap,
+ BlockMemberInfoMap *blockInfoOut)
+ : BlockEncoderVisitor(prefix, "", getEncoder(storage)),
+ mShaderVarToFieldMap(shaderVarToFieldMap),
+ mBlockInfoOut(blockInfoOut),
+ mHLSLEncoder(HLSLBlockEncoder::ENCODE_PACKED, false),
+ mStorage(storage)
+ {}
+
+ BlockLayoutEncoder *getEncoder(TLayoutBlockStorage storage)
+ {
+ switch (storage)
+ {
+ case EbsStd140:
+ return &mStd140Encoder;
+ case EbsStd430:
+ return &mStd430Encoder;
+ default:
+ return &mHLSLEncoder;
+ }
+ }
+
+ void enterStructAccess(const ShaderVariable &structVar, bool isRowMajor) override
+ {
+ BlockEncoderVisitor::enterStructAccess(structVar, isRowMajor);
+
+ std::string variableName = StripArrayIndices(collapseNameStack());
+
+ // Remove the trailing "."
+ variableName.pop_back();
+
+ BlockInfoVisitor childVisitor(variableName, mStorage, mShaderVarToFieldMap, mBlockInfoOut);
+ childVisitor.getEncoder(mStorage)->enterAggregateType(structVar);
+ TraverseShaderVariables(structVar.fields, isRowMajor, &childVisitor);
+ childVisitor.getEncoder(mStorage)->exitAggregateType(structVar);
+
+ int offset = static_cast<int>(getEncoder(mStorage)->getCurrentOffset());
+ int arrayStride = static_cast<int>(childVisitor.getEncoder(mStorage)->getCurrentOffset());
+
+ auto iter = mShaderVarToFieldMap.find(variableName);
+ if (iter == mShaderVarToFieldMap.end())
+ return;
+
+ const TField *structField = iter->second;
+ if (mBlockInfoOut->count(structField) == 0)
+ {
+ mBlockInfoOut->emplace(structField, BlockMemberInfo(offset, arrayStride, -1, false));
+ }
+ }
+
+ void encodeVariable(const ShaderVariable &variable,
+ const BlockMemberInfo &variableInfo,
+ const std::string &name,
+ const std::string &mappedName) override
+ {
+ auto iter = mShaderVarToFieldMap.find(StripArrayIndices(name));
+ if (iter == mShaderVarToFieldMap.end())
+ return;
+
+ const TField *field = iter->second;
+ if (mBlockInfoOut->count(field) == 0)
+ {
+ mBlockInfoOut->emplace(field, variableInfo);
+ }
+ }
+
+ private:
+ const ShaderVarToFieldMap &mShaderVarToFieldMap;
+ BlockMemberInfoMap *mBlockInfoOut;
+ Std140BlockEncoder mStd140Encoder;
+ Std430BlockEncoder mStd430Encoder;
+ HLSLBlockEncoder mHLSLEncoder;
+ TLayoutBlockStorage mStorage;
+};
+
+void GetShaderStorageBlockMembersInfo(const TInterfaceBlock *interfaceBlock,
+ const std::vector<InterfaceBlock> &shaderStorageBlocks,
+ BlockMemberInfoMap *blockInfoOut)
+{
+ // Find the sh::InterfaceBlock.
+ const InterfaceBlock *block = FindInterfaceBlock(interfaceBlock, shaderStorageBlocks);
+ ASSERT(block);
+
+ // Map ShaderVariable to TField.
+ ShaderVarToFieldMap shaderVarToFieldMap;
+ for (size_t index = 0; index < block->fields.size(); ++index)
+ {
+ const TField *field = interfaceBlock->fields()[index];
+ const ShaderVariable &variable = block->fields[index];
+ MapVariableToField(variable, field, variable.name, &shaderVarToFieldMap);
+ }
+
+ BlockInfoVisitor visitor("", interfaceBlock->blockStorage(), shaderVarToFieldMap, blockInfoOut);
+ TraverseShaderVariables(block->fields, false, &visitor);
+}
+
+TIntermTyped *Mul(TIntermTyped *left, TIntermTyped *right)
+{
+ return left && right ? new TIntermBinary(EOpMul, left, right) : nullptr;
+}
+
+TIntermTyped *Add(TIntermTyped *left, TIntermTyped *right)
+{
+ return left ? right ? new TIntermBinary(EOpAdd, left, right) : left : right;
+}
+
+} // anonymous namespace
+
+ShaderStorageBlockOutputHLSL::ShaderStorageBlockOutputHLSL(
+ OutputHLSL *outputHLSL,
+ ResourcesHLSL *resourcesHLSL,
+ const std::vector<InterfaceBlock> &shaderStorageBlocks)
+ : mOutputHLSL(outputHLSL),
+ mResourcesHLSL(resourcesHLSL),
+ mShaderStorageBlocks(shaderStorageBlocks)
+{
+ mSSBOFunctionHLSL = new ShaderStorageBlockFunctionHLSL;
+}
+
+ShaderStorageBlockOutputHLSL::~ShaderStorageBlockOutputHLSL()
+{
+ SafeDelete(mSSBOFunctionHLSL);
+}
+
+void ShaderStorageBlockOutputHLSL::outputStoreFunctionCallPrefix(TIntermTyped *node)
+{
+ traverseSSBOAccess(node, SSBOMethod::STORE);
+}
+
+void ShaderStorageBlockOutputHLSL::outputLoadFunctionCall(TIntermTyped *node)
+{
+ traverseSSBOAccess(node, SSBOMethod::LOAD);
+ mOutputHLSL->getInfoSink() << ")";
+}
+
+void ShaderStorageBlockOutputHLSL::outputLengthFunctionCall(TIntermTyped *node)
+{
+ traverseSSBOAccess(node, SSBOMethod::LENGTH);
+ mOutputHLSL->getInfoSink() << ")";
+}
+
+void ShaderStorageBlockOutputHLSL::outputAtomicMemoryFunctionCallPrefix(TIntermTyped *node,
+ TOperator op)
+{
+ switch (op)
+ {
+ case EOpAtomicAdd:
+ traverseSSBOAccess(node, SSBOMethod::ATOMIC_ADD);
+ break;
+ case EOpAtomicMin:
+ traverseSSBOAccess(node, SSBOMethod::ATOMIC_MIN);
+ break;
+ case EOpAtomicMax:
+ traverseSSBOAccess(node, SSBOMethod::ATOMIC_MAX);
+ break;
+ case EOpAtomicAnd:
+ traverseSSBOAccess(node, SSBOMethod::ATOMIC_AND);
+ break;
+ case EOpAtomicOr:
+ traverseSSBOAccess(node, SSBOMethod::ATOMIC_OR);
+ break;
+ case EOpAtomicXor:
+ traverseSSBOAccess(node, SSBOMethod::ATOMIC_XOR);
+ break;
+ case EOpAtomicExchange:
+ traverseSSBOAccess(node, SSBOMethod::ATOMIC_EXCHANGE);
+ break;
+ case EOpAtomicCompSwap:
+ traverseSSBOAccess(node, SSBOMethod::ATOMIC_COMPSWAP);
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+// Note that we must calculate the matrix stride here instead of ShaderStorageBlockFunctionHLSL.
+// It's because that if the current node's type is a vector which comes from a matrix, we will
+// lose the matrix type info once we enter ShaderStorageBlockFunctionHLSL.
+int ShaderStorageBlockOutputHLSL::getMatrixStride(TIntermTyped *node,
+ TLayoutBlockStorage storage,
+ bool rowMajor,
+ bool *isRowMajorMatrix) const
+{
+ if (node->getType().isMatrix())
+ {
+ *isRowMajorMatrix = rowMajor;
+ return GetBlockMemberInfoByType(node->getType(), storage, rowMajor).matrixStride;
+ }
+
+ if (node->getType().isVector())
+ {
+ TIntermBinary *binaryNode = node->getAsBinaryNode();
+ if (binaryNode)
+ {
+ return getMatrixStride(binaryNode->getLeft(), storage, rowMajor, isRowMajorMatrix);
+ }
+ else
+ {
+ TIntermSwizzle *swizzleNode = node->getAsSwizzleNode();
+ if (swizzleNode)
+ {
+ return getMatrixStride(swizzleNode->getOperand(), storage, rowMajor,
+ isRowMajorMatrix);
+ }
+ }
+ }
+ return 0;
+}
+
+void ShaderStorageBlockOutputHLSL::collectShaderStorageBlocks(TIntermTyped *node)
+{
+ TIntermSwizzle *swizzleNode = node->getAsSwizzleNode();
+ if (swizzleNode)
+ {
+ return collectShaderStorageBlocks(swizzleNode->getOperand());
+ }
+
+ TIntermBinary *binaryNode = node->getAsBinaryNode();
+ if (binaryNode)
+ {
+ switch (binaryNode->getOp())
+ {
+ case EOpIndexDirectInterfaceBlock:
+ case EOpIndexIndirect:
+ case EOpIndexDirect:
+ case EOpIndexDirectStruct:
+ return collectShaderStorageBlocks(binaryNode->getLeft());
+ default:
+ UNREACHABLE();
+ return;
+ }
+ }
+
+ const TIntermSymbol *symbolNode = node->getAsSymbolNode();
+ const TType &type = symbolNode->getType();
+ ASSERT(type.getQualifier() == EvqBuffer);
+ const TVariable &variable = symbolNode->variable();
+
+ const TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
+ ASSERT(interfaceBlock);
+ if (mReferencedShaderStorageBlocks.count(interfaceBlock->uniqueId().get()) == 0)
+ {
+ const TVariable *instanceVariable = nullptr;
+ if (type.isInterfaceBlock())
+ {
+ instanceVariable = &variable;
+ }
+ mReferencedShaderStorageBlocks[interfaceBlock->uniqueId().get()] =
+ new TReferencedBlock(interfaceBlock, instanceVariable);
+ GetShaderStorageBlockMembersInfo(interfaceBlock, mShaderStorageBlocks,
+ &mBlockMemberInfoMap);
+ }
+}
+
+void ShaderStorageBlockOutputHLSL::traverseSSBOAccess(TIntermTyped *node, SSBOMethod method)
+{
+ // TODO: Merge collectShaderStorageBlocks and GetBlockLayoutInfo to simplify the code.
+ collectShaderStorageBlocks(node);
+
+ // Note that we don't have correct BlockMemberInfo from mBlockMemberInfoMap at the current
+ // point. But we must use those information to generate the right function name. So here we have
+ // to calculate them again.
+ TLayoutBlockStorage storage;
+ bool rowMajor;
+ GetBlockLayoutInfo(node, false, &storage, &rowMajor);
+ int unsizedArrayStride = 0;
+ if (node->getType().isUnsizedArray())
+ {
+ // The unsized array member must be the last member of a shader storage block.
+ TIntermBinary *binaryNode = node->getAsBinaryNode();
+ if (binaryNode)
+ {
+ const TInterfaceBlock *interfaceBlock =
+ binaryNode->getLeft()->getType().getInterfaceBlock();
+ ASSERT(interfaceBlock);
+ const TIntermConstantUnion *index = binaryNode->getRight()->getAsConstantUnion();
+ const TField *field = interfaceBlock->fields()[index->getIConst(0)];
+ auto fieldInfoIter = mBlockMemberInfoMap.find(field);
+ ASSERT(fieldInfoIter != mBlockMemberInfoMap.end());
+ unsizedArrayStride = fieldInfoIter->second.arrayStride;
+ }
+ else
+ {
+ const TIntermSymbol *symbolNode = node->getAsSymbolNode();
+ const TVariable &variable = symbolNode->variable();
+ const TInterfaceBlock *interfaceBlock = symbolNode->getType().getInterfaceBlock();
+ ASSERT(interfaceBlock);
+ const TField *field =
+ GetFieldMemberInShaderStorageBlock(interfaceBlock, variable.name());
+ auto fieldInfoIter = mBlockMemberInfoMap.find(field);
+ ASSERT(fieldInfoIter != mBlockMemberInfoMap.end());
+ unsizedArrayStride = fieldInfoIter->second.arrayStride;
+ }
+ }
+ bool isRowMajorMatrix = false;
+ int matrixStride = getMatrixStride(node, storage, rowMajor, &isRowMajorMatrix);
+
+ const TString &functionName = mSSBOFunctionHLSL->registerShaderStorageBlockFunction(
+ node->getType(), method, storage, isRowMajorMatrix, matrixStride, unsizedArrayStride,
+ node->getAsSwizzleNode());
+ TInfoSinkBase &out = mOutputHLSL->getInfoSink();
+ out << functionName;
+ out << "(";
+ BlockMemberInfo blockMemberInfo;
+ TIntermNode *loc = traverseNode(out, node, &blockMemberInfo);
+ out << ", ";
+ loc->traverse(mOutputHLSL);
+}
+
+void ShaderStorageBlockOutputHLSL::writeShaderStorageBlocksHeader(GLenum shaderType,
+ TInfoSinkBase &out) const
+{
+ if (mReferencedShaderStorageBlocks.empty())
+ {
+ return;
+ }
+
+ mResourcesHLSL->allocateShaderStorageBlockRegisters(mReferencedShaderStorageBlocks);
+ out << "// Shader Storage Blocks\n\n";
+ if (shaderType == GL_COMPUTE_SHADER)
+ {
+ out << mResourcesHLSL->shaderStorageBlocksHeader(mReferencedShaderStorageBlocks);
+ }
+ else
+ {
+ out << kShaderStorageDeclarationString << "\n";
+ }
+ mSSBOFunctionHLSL->shaderStorageBlockFunctionHeader(out);
+}
+
+TIntermTyped *ShaderStorageBlockOutputHLSL::traverseNode(TInfoSinkBase &out,
+ TIntermTyped *node,
+ BlockMemberInfo *blockMemberInfo)
+{
+ if (TIntermSymbol *symbolNode = node->getAsSymbolNode())
+ {
+ const TVariable &variable = symbolNode->variable();
+ const TType &type = variable.getType();
+ if (type.isInterfaceBlock())
+ {
+ out << DecorateVariableIfNeeded(variable);
+ }
+ else
+ {
+ const TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
+ out << Decorate(interfaceBlock->name());
+ const TField *field =
+ GetFieldMemberInShaderStorageBlock(interfaceBlock, variable.name());
+ return createFieldOffset(field, blockMemberInfo);
+ }
+ }
+ else if (TIntermSwizzle *swizzleNode = node->getAsSwizzleNode())
+ {
+ return traverseNode(out, swizzleNode->getOperand(), blockMemberInfo);
+ }
+ else if (TIntermBinary *binaryNode = node->getAsBinaryNode())
+ {
+ switch (binaryNode->getOp())
+ {
+ case EOpIndexDirect:
+ {
+ const TType &leftType = binaryNode->getLeft()->getType();
+ if (leftType.isInterfaceBlock())
+ {
+ ASSERT(leftType.getQualifier() == EvqBuffer);
+ TIntermSymbol *instanceArraySymbol = binaryNode->getLeft()->getAsSymbolNode();
+
+ const int arrayIndex =
+ binaryNode->getRight()->getAsConstantUnion()->getIConst(0);
+ out << mResourcesHLSL->InterfaceBlockInstanceString(
+ instanceArraySymbol->getName(), arrayIndex);
+ }
+ else
+ {
+ return writeEOpIndexDirectOrIndirectOutput(out, binaryNode, blockMemberInfo);
+ }
+ break;
+ }
+ case EOpIndexIndirect:
+ {
+ // We do not currently support indirect references to interface blocks
+ ASSERT(binaryNode->getLeft()->getBasicType() != EbtInterfaceBlock);
+ return writeEOpIndexDirectOrIndirectOutput(out, binaryNode, blockMemberInfo);
+ }
+ case EOpIndexDirectStruct:
+ {
+ // We do not currently support direct references to interface blocks
+ ASSERT(binaryNode->getLeft()->getBasicType() != EbtInterfaceBlock);
+ TIntermTyped *left = traverseNode(out, binaryNode->getLeft(), blockMemberInfo);
+ const TStructure *structure = binaryNode->getLeft()->getType().getStruct();
+ const TIntermConstantUnion *index = binaryNode->getRight()->getAsConstantUnion();
+ const TField *field = structure->fields()[index->getIConst(0)];
+ return Add(createFieldOffset(field, blockMemberInfo), left);
+ }
+ case EOpIndexDirectInterfaceBlock:
+ {
+ ASSERT(IsInShaderStorageBlock(binaryNode->getLeft()));
+ traverseNode(out, binaryNode->getLeft(), blockMemberInfo);
+ const TInterfaceBlock *interfaceBlock =
+ binaryNode->getLeft()->getType().getInterfaceBlock();
+ const TIntermConstantUnion *index = binaryNode->getRight()->getAsConstantUnion();
+ const TField *field = interfaceBlock->fields()[index->getIConst(0)];
+ return createFieldOffset(field, blockMemberInfo);
+ }
+ default:
+ return nullptr;
+ }
+ }
+ return nullptr;
+}
+
+TIntermTyped *ShaderStorageBlockOutputHLSL::writeEOpIndexDirectOrIndirectOutput(
+ TInfoSinkBase &out,
+ TIntermBinary *node,
+ BlockMemberInfo *blockMemberInfo)
+{
+ ASSERT(IsInShaderStorageBlock(node->getLeft()));
+ TIntermTyped *left = traverseNode(out, node->getLeft(), blockMemberInfo);
+ TIntermTyped *right = node->getRight()->deepCopy();
+ const TType &type = node->getLeft()->getType();
+ TLayoutBlockStorage storage;
+ bool rowMajor;
+ GetBlockLayoutInfo(node, false, &storage, &rowMajor);
+
+ if (type.isArray())
+ {
+ const TSpan<const unsigned int> &arraySizes = type.getArraySizes();
+ for (unsigned int i = 0; i < arraySizes.size() - 1; i++)
+ {
+ right = Mul(CreateUIntNode(arraySizes[i]), right);
+ }
+ right = Mul(CreateUIntNode(blockMemberInfo->arrayStride), right);
+ }
+ else if (type.isMatrix())
+ {
+ if (rowMajor)
+ {
+ right = Mul(CreateUIntNode(BlockLayoutEncoder::kBytesPerComponent), right);
+ }
+ else
+ {
+ right = Mul(CreateUIntNode(blockMemberInfo->matrixStride), right);
+ }
+ }
+ else if (type.isVector())
+ {
+ if (blockMemberInfo->isRowMajorMatrix)
+ {
+ right = Mul(CreateUIntNode(blockMemberInfo->matrixStride), right);
+ }
+ else
+ {
+ right = Mul(CreateUIntNode(BlockLayoutEncoder::kBytesPerComponent), right);
+ }
+ }
+ return Add(left, right);
+}
+
+TIntermTyped *ShaderStorageBlockOutputHLSL::createFieldOffset(const TField *field,
+ BlockMemberInfo *blockMemberInfo)
+{
+ auto fieldInfoIter = mBlockMemberInfoMap.find(field);
+ ASSERT(fieldInfoIter != mBlockMemberInfoMap.end());
+ *blockMemberInfo = fieldInfoIter->second;
+ return CreateUIntNode(blockMemberInfo->offset);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/ShaderStorageBlockOutputHLSL.h b/gfx/angle/checkout/src/compiler/translator/ShaderStorageBlockOutputHLSL.h
new file mode 100644
index 0000000000..2acf06a0ea
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ShaderStorageBlockOutputHLSL.h
@@ -0,0 +1,86 @@
+//
+// Copyright 2018 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.
+//
+// ShaderStorageBlockOutputHLSL: A traverser to translate a buffer variable of shader storage block
+// to an offset of RWByteAddressBuffer.
+//
+
+#ifndef COMPILER_TRANSLATOR_SHADERSTORAGEBLOCKOUTPUTHLSL_H_
+#define COMPILER_TRANSLATOR_SHADERSTORAGEBLOCKOUTPUTHLSL_H_
+
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/ShaderStorageBlockFunctionHLSL.h"
+#include "compiler/translator/blocklayout.h"
+
+namespace sh
+{
+class ResourcesHLSL;
+class OutputHLSL;
+class TSymbolTable;
+
+struct TReferencedBlock : angle::NonCopyable
+{
+ POOL_ALLOCATOR_NEW_DELETE
+ TReferencedBlock(const TInterfaceBlock *block, const TVariable *instanceVariable);
+ const TInterfaceBlock *block;
+ const TVariable *instanceVariable; // May be nullptr if the block is not instanced.
+};
+
+// Maps from uniqueId to a variable.
+using ReferencedInterfaceBlocks = std::map<int, const TReferencedBlock *>;
+
+// Used to save shader storage block field member information.
+using BlockMemberInfoMap = std::map<const TField *, BlockMemberInfo>;
+
+using ShaderVarToFieldMap = std::map<std::string, const TField *>;
+
+class ShaderStorageBlockOutputHLSL
+{
+ public:
+ ShaderStorageBlockOutputHLSL(OutputHLSL *outputHLSL,
+ ResourcesHLSL *resourcesHLSL,
+ const std::vector<InterfaceBlock> &shaderStorageBlocks);
+
+ ~ShaderStorageBlockOutputHLSL();
+
+ // This writes part of the function call to store a value to a SSBO to the output stream. After
+ // calling this, ", <stored value>)" should be written to the output stream to complete the
+ // function call.
+ void outputStoreFunctionCallPrefix(TIntermTyped *node);
+ // This writes the function call to load a SSBO value to the output stream.
+ void outputLoadFunctionCall(TIntermTyped *node);
+ // This writes the function call to get the lengh of unsized array member of SSBO.
+ void outputLengthFunctionCall(TIntermTyped *node);
+ // Writes the atomic memory function calls for SSBO.
+ void outputAtomicMemoryFunctionCallPrefix(TIntermTyped *node, TOperator op);
+
+ void writeShaderStorageBlocksHeader(GLenum shaderType, TInfoSinkBase &out) const;
+
+ private:
+ void traverseSSBOAccess(TIntermTyped *node, SSBOMethod method);
+ TIntermTyped *traverseNode(TInfoSinkBase &out,
+ TIntermTyped *node,
+ BlockMemberInfo *blockMemberInfo);
+ int getMatrixStride(TIntermTyped *node,
+ TLayoutBlockStorage storage,
+ bool rowMajor,
+ bool *isRowMajor) const;
+ TIntermTyped *writeEOpIndexDirectOrIndirectOutput(TInfoSinkBase &out,
+ TIntermBinary *node,
+ BlockMemberInfo *blockMemberInfo);
+ // Common part in dot operations.
+ TIntermTyped *createFieldOffset(const TField *field, BlockMemberInfo *blockMemberInfo);
+ void collectShaderStorageBlocks(TIntermTyped *node);
+ OutputHLSL *mOutputHLSL;
+ ShaderStorageBlockFunctionHLSL *mSSBOFunctionHLSL;
+ ResourcesHLSL *mResourcesHLSL;
+ ReferencedInterfaceBlocks mReferencedShaderStorageBlocks;
+
+ BlockMemberInfoMap mBlockMemberInfoMap;
+ const std::vector<InterfaceBlock> &mShaderStorageBlocks;
+};
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_SHADERSTORAGEBLOCKOUTPUTHLSL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/ShaderVars.cpp b/gfx/angle/checkout/src/compiler/translator/ShaderVars.cpp
new file mode 100644
index 0000000000..85d87e2be4
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ShaderVars.cpp
@@ -0,0 +1,625 @@
+//
+// 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.
+//
+// ShaderVars.cpp:
+// Methods for GL variable types (varyings, uniforms, etc)
+//
+
+#include <GLSLANG/ShaderLang.h>
+
+#include "common/debug.h"
+#include "common/utilities.h"
+
+namespace sh
+{
+
+namespace
+{
+
+InterpolationType GetNonAuxiliaryInterpolationType(InterpolationType interpolation)
+{
+ return (interpolation == INTERPOLATION_CENTROID ? INTERPOLATION_SMOOTH : interpolation);
+}
+} // namespace
+// The ES 3.0 spec is not clear on this point, but the ES 3.1 spec, and discussion
+// on Khronos.org, clarifies that a smooth/flat mismatch produces a link error,
+// but auxiliary qualifier mismatch (centroid) does not.
+bool InterpolationTypesMatch(InterpolationType a, InterpolationType b)
+{
+ return (GetNonAuxiliaryInterpolationType(a) == GetNonAuxiliaryInterpolationType(b));
+}
+
+ShaderVariable::ShaderVariable() : ShaderVariable(GL_NONE) {}
+
+ShaderVariable::ShaderVariable(GLenum typeIn)
+ : type(typeIn),
+ precision(0),
+ staticUse(false),
+ active(false),
+ isRowMajorLayout(false),
+ location(-1),
+ hasImplicitLocation(false),
+ binding(-1),
+ imageUnitFormat(GL_NONE),
+ offset(-1),
+ rasterOrdered(false),
+ readonly(false),
+ writeonly(false),
+ isFragmentInOut(false),
+ index(-1),
+ yuv(false),
+ interpolation(INTERPOLATION_SMOOTH),
+ isInvariant(false),
+ isShaderIOBlock(false),
+ isPatch(false),
+ texelFetchStaticUse(false),
+ flattenedOffsetInParentArrays(-1)
+{}
+
+ShaderVariable::ShaderVariable(GLenum typeIn, unsigned int arraySizeIn) : ShaderVariable(typeIn)
+{
+ ASSERT(arraySizeIn != 0);
+ arraySizes.push_back(arraySizeIn);
+}
+
+ShaderVariable::~ShaderVariable() {}
+
+ShaderVariable::ShaderVariable(const ShaderVariable &other)
+ : type(other.type),
+ precision(other.precision),
+ name(other.name),
+ mappedName(other.mappedName),
+ arraySizes(other.arraySizes),
+ staticUse(other.staticUse),
+ active(other.active),
+ fields(other.fields),
+ structOrBlockName(other.structOrBlockName),
+ mappedStructOrBlockName(other.mappedStructOrBlockName),
+ isRowMajorLayout(other.isRowMajorLayout),
+ location(other.location),
+ hasImplicitLocation(other.hasImplicitLocation),
+ binding(other.binding),
+ imageUnitFormat(other.imageUnitFormat),
+ offset(other.offset),
+ rasterOrdered(other.rasterOrdered),
+ readonly(other.readonly),
+ writeonly(other.writeonly),
+ isFragmentInOut(other.isFragmentInOut),
+ index(other.index),
+ yuv(other.yuv),
+ interpolation(other.interpolation),
+ isInvariant(other.isInvariant),
+ isShaderIOBlock(other.isShaderIOBlock),
+ isPatch(other.isPatch),
+ texelFetchStaticUse(other.texelFetchStaticUse),
+ flattenedOffsetInParentArrays(other.flattenedOffsetInParentArrays)
+{}
+
+ShaderVariable &ShaderVariable::operator=(const ShaderVariable &other)
+{
+ type = other.type;
+ precision = other.precision;
+ name = other.name;
+ mappedName = other.mappedName;
+ arraySizes = other.arraySizes;
+ staticUse = other.staticUse;
+ active = other.active;
+ fields = other.fields;
+ structOrBlockName = other.structOrBlockName;
+ mappedStructOrBlockName = other.mappedStructOrBlockName;
+ isRowMajorLayout = other.isRowMajorLayout;
+ flattenedOffsetInParentArrays = other.flattenedOffsetInParentArrays;
+ location = other.location;
+ hasImplicitLocation = other.hasImplicitLocation;
+ binding = other.binding;
+ imageUnitFormat = other.imageUnitFormat;
+ offset = other.offset;
+ rasterOrdered = other.rasterOrdered;
+ readonly = other.readonly;
+ writeonly = other.writeonly;
+ isFragmentInOut = other.isFragmentInOut;
+ index = other.index;
+ yuv = other.yuv;
+ interpolation = other.interpolation;
+ isInvariant = other.isInvariant;
+ isShaderIOBlock = other.isShaderIOBlock;
+ isPatch = other.isPatch;
+ texelFetchStaticUse = other.texelFetchStaticUse;
+ return *this;
+}
+
+bool ShaderVariable::operator==(const ShaderVariable &other) const
+{
+ if (type != other.type || precision != other.precision || name != other.name ||
+ mappedName != other.mappedName || arraySizes != other.arraySizes ||
+ staticUse != other.staticUse || active != other.active ||
+ fields.size() != other.fields.size() || structOrBlockName != other.structOrBlockName ||
+ mappedStructOrBlockName != other.mappedStructOrBlockName ||
+ isRowMajorLayout != other.isRowMajorLayout || location != other.location ||
+ hasImplicitLocation != other.hasImplicitLocation || binding != other.binding ||
+ imageUnitFormat != other.imageUnitFormat || offset != other.offset ||
+ rasterOrdered != other.rasterOrdered || readonly != other.readonly ||
+ writeonly != other.writeonly || index != other.index || yuv != other.yuv ||
+ interpolation != other.interpolation || isInvariant != other.isInvariant ||
+ isShaderIOBlock != other.isShaderIOBlock || isPatch != other.isPatch ||
+ texelFetchStaticUse != other.texelFetchStaticUse ||
+ isFragmentInOut != other.isFragmentInOut)
+ {
+ return false;
+ }
+ for (size_t ii = 0; ii < fields.size(); ++ii)
+ {
+ if (fields[ii] != other.fields[ii])
+ return false;
+ }
+ return true;
+}
+
+void ShaderVariable::setArraySize(unsigned int size)
+{
+ arraySizes.clear();
+ if (size != 0)
+ {
+ arraySizes.push_back(size);
+ }
+}
+
+unsigned int ShaderVariable::getInnerArraySizeProduct() const
+{
+ return gl::InnerArraySizeProduct(arraySizes);
+}
+
+unsigned int ShaderVariable::getArraySizeProduct() const
+{
+ return gl::ArraySizeProduct(arraySizes);
+}
+
+void ShaderVariable::indexIntoArray(unsigned int arrayIndex)
+{
+ ASSERT(isArray());
+ flattenedOffsetInParentArrays = arrayIndex + getOutermostArraySize() * parentArrayIndex();
+ arraySizes.pop_back();
+}
+
+unsigned int ShaderVariable::getNestedArraySize(unsigned int arrayNestingIndex) const
+{
+ ASSERT(arraySizes.size() > arrayNestingIndex);
+ unsigned int arraySize = arraySizes[arraySizes.size() - 1u - arrayNestingIndex];
+
+ if (arraySize == 0)
+ {
+ // Unsized array, so give it at least 1 entry
+ arraySize = 1;
+ }
+
+ return arraySize;
+}
+
+unsigned int ShaderVariable::getBasicTypeElementCount() const
+{
+ // GLES 3.1 Nov 2016 section 7.3.1.1 page 77 specifies that a separate entry should be generated
+ // for each array element when dealing with an array of arrays or an array of structs.
+ ASSERT(!isArrayOfArrays());
+ ASSERT(!isStruct() || !isArray());
+
+ // GLES 3.1 Nov 2016 page 82.
+ if (isArray())
+ {
+ return getOutermostArraySize();
+ }
+ return 1u;
+}
+
+unsigned int ShaderVariable::getExternalSize() const
+{
+ unsigned int memorySize = 0;
+
+ if (isStruct())
+ {
+ // Have a structure, need to compute the structure size.
+ for (const auto &field : fields)
+ {
+ memorySize += field.getExternalSize();
+ }
+ }
+ else
+ {
+ memorySize += gl::VariableExternalSize(type);
+ }
+
+ // multiply by array size to get total memory size of this variable / struct.
+ memorySize *= getArraySizeProduct();
+
+ return memorySize;
+}
+
+bool ShaderVariable::findInfoByMappedName(const std::string &mappedFullName,
+ const ShaderVariable **leafVar,
+ std::string *originalFullName) const
+{
+ ASSERT(leafVar && originalFullName);
+ // There are three cases:
+ // 1) the top variable is of struct type;
+ // 2) the top variable is an array;
+ // 3) otherwise.
+ size_t pos = mappedFullName.find_first_of(".[");
+
+ if (pos == std::string::npos)
+ {
+ // Case 3.
+ if (mappedFullName != this->mappedName)
+ return false;
+ *originalFullName = this->name;
+ *leafVar = this;
+ return true;
+ }
+ else
+ {
+ std::string topName = mappedFullName.substr(0, pos);
+ if (topName != this->mappedName)
+ return false;
+ std::string originalName = this->name;
+ std::string remaining;
+ if (mappedFullName[pos] == '[')
+ {
+ // Case 2.
+ size_t closePos = mappedFullName.find_first_of(']');
+ if (closePos < pos || closePos == std::string::npos)
+ return false;
+ // Append '[index]'.
+ originalName += mappedFullName.substr(pos, closePos - pos + 1);
+ if (closePos + 1 == mappedFullName.size())
+ {
+ *originalFullName = originalName;
+ *leafVar = this;
+ return true;
+ }
+ else
+ {
+ // In the form of 'a[0].b', so after ']', '.' is expected.
+ if (mappedFullName[closePos + 1] != '.')
+ return false;
+ remaining = mappedFullName.substr(closePos + 2); // Skip "]."
+ }
+ }
+ else
+ {
+ // Case 1.
+ remaining = mappedFullName.substr(pos + 1); // Skip "."
+ }
+ for (size_t ii = 0; ii < this->fields.size(); ++ii)
+ {
+ const ShaderVariable *fieldVar = nullptr;
+ std::string originalFieldName;
+ bool found = fields[ii].findInfoByMappedName(remaining, &fieldVar, &originalFieldName);
+ if (found)
+ {
+ *originalFullName = originalName + "." + originalFieldName;
+ *leafVar = fieldVar;
+ return true;
+ }
+ }
+ return false;
+ }
+}
+
+const sh::ShaderVariable *ShaderVariable::findField(const std::string &fullName,
+ uint32_t *fieldIndexOut) const
+{
+ if (fields.empty())
+ {
+ return nullptr;
+ }
+ size_t pos = fullName.find_first_of(".");
+ std::string topName, fieldName;
+ if (pos == std::string::npos)
+ {
+ // If this is a shader I/O block without an instance name, return the field given only the
+ // field name.
+ if (!isShaderIOBlock || !name.empty())
+ {
+ return nullptr;
+ }
+
+ fieldName = fullName;
+ }
+ else
+ {
+ std::string baseName = isShaderIOBlock ? structOrBlockName : name;
+ topName = fullName.substr(0, pos);
+ if (topName != baseName)
+ {
+ return nullptr;
+ }
+ fieldName = fullName.substr(pos + 1);
+ }
+ if (fieldName.empty())
+ {
+ return nullptr;
+ }
+ for (size_t field = 0; field < fields.size(); ++field)
+ {
+ if (fields[field].name == fieldName)
+ {
+ *fieldIndexOut = static_cast<GLuint>(field);
+ return &fields[field];
+ }
+ }
+ return nullptr;
+}
+
+bool ShaderVariable::isBuiltIn() const
+{
+ return gl::IsBuiltInName(name);
+}
+
+bool ShaderVariable::isEmulatedBuiltIn() const
+{
+ return isBuiltIn() && name != mappedName;
+}
+
+bool ShaderVariable::isSameVariableAtLinkTime(const ShaderVariable &other,
+ bool matchPrecision,
+ bool matchName) const
+{
+ if (type != other.type)
+ return false;
+ if (matchPrecision && precision != other.precision)
+ return false;
+ if (matchName && name != other.name)
+ return false;
+ ASSERT(!matchName || mappedName == other.mappedName);
+ if (arraySizes != other.arraySizes)
+ return false;
+ if (isRowMajorLayout != other.isRowMajorLayout)
+ return false;
+ if (fields.size() != other.fields.size())
+ return false;
+
+ // [OpenGL ES 3.1 SPEC Chapter 7.4.1]
+ // Variables declared as structures are considered to match in type if and only if structure
+ // members match in name, type, qualification, and declaration order.
+ for (size_t ii = 0; ii < fields.size(); ++ii)
+ {
+ if (!fields[ii].isSameVariableAtLinkTime(other.fields[ii], matchPrecision, true))
+ {
+ return false;
+ }
+ }
+ if (structOrBlockName != other.structOrBlockName ||
+ mappedStructOrBlockName != other.mappedStructOrBlockName)
+ return false;
+ return true;
+}
+
+void ShaderVariable::updateEffectiveLocation(const sh::ShaderVariable &parent)
+{
+ if ((location < 0 || hasImplicitLocation) && !parent.hasImplicitLocation)
+ {
+ location = parent.location;
+ }
+}
+
+void ShaderVariable::resetEffectiveLocation()
+{
+ if (hasImplicitLocation)
+ {
+ location = -1;
+ }
+}
+
+bool ShaderVariable::isSameUniformAtLinkTime(const ShaderVariable &other) const
+{
+ // Enforce a consistent match.
+ // https://cvs.khronos.org/bugzilla/show_bug.cgi?id=16261
+ if (binding != -1 && other.binding != -1 && binding != other.binding)
+ {
+ return false;
+ }
+ if (imageUnitFormat != other.imageUnitFormat)
+ {
+ return false;
+ }
+ if (location != -1 && other.location != -1 && location != other.location)
+ {
+ return false;
+ }
+ if (offset != other.offset)
+ {
+ return false;
+ }
+ if (rasterOrdered != other.rasterOrdered)
+ {
+ return false;
+ }
+ if (readonly != other.readonly || writeonly != other.writeonly)
+ {
+ return false;
+ }
+ return ShaderVariable::isSameVariableAtLinkTime(other, true, true);
+}
+
+bool ShaderVariable::isSameInterfaceBlockFieldAtLinkTime(const ShaderVariable &other) const
+{
+ return (ShaderVariable::isSameVariableAtLinkTime(other, true, true));
+}
+
+bool ShaderVariable::isSameVaryingAtLinkTime(const ShaderVariable &other) const
+{
+ return isSameVaryingAtLinkTime(other, 100);
+}
+
+bool ShaderVariable::isSameVaryingAtLinkTime(const ShaderVariable &other, int shaderVersion) const
+{
+ return ShaderVariable::isSameVariableAtLinkTime(other, false, false) &&
+ InterpolationTypesMatch(interpolation, other.interpolation) &&
+ (shaderVersion >= 300 || isInvariant == other.isInvariant) &&
+ (isPatch == other.isPatch) && location == other.location &&
+ (isSameNameAtLinkTime(other) || (shaderVersion >= 310 && location >= 0));
+}
+
+bool ShaderVariable::isSameNameAtLinkTime(const ShaderVariable &other) const
+{
+ if (isShaderIOBlock != other.isShaderIOBlock)
+ {
+ return false;
+ }
+
+ if (isShaderIOBlock)
+ {
+ // Shader I/O blocks match by block name.
+ return structOrBlockName == other.structOrBlockName;
+ }
+
+ // Otherwise match by name.
+ return name == other.name;
+}
+
+InterfaceBlock::InterfaceBlock()
+ : arraySize(0),
+ layout(BLOCKLAYOUT_PACKED),
+ isRowMajorLayout(false),
+ binding(-1),
+ staticUse(false),
+ active(false),
+ blockType(BlockType::BLOCK_UNIFORM)
+{}
+
+InterfaceBlock::~InterfaceBlock() {}
+
+InterfaceBlock::InterfaceBlock(const InterfaceBlock &other)
+ : name(other.name),
+ mappedName(other.mappedName),
+ instanceName(other.instanceName),
+ arraySize(other.arraySize),
+ layout(other.layout),
+ isRowMajorLayout(other.isRowMajorLayout),
+ binding(other.binding),
+ staticUse(other.staticUse),
+ active(other.active),
+ blockType(other.blockType),
+ fields(other.fields)
+{}
+
+InterfaceBlock &InterfaceBlock::operator=(const InterfaceBlock &other)
+{
+ name = other.name;
+ mappedName = other.mappedName;
+ instanceName = other.instanceName;
+ arraySize = other.arraySize;
+ layout = other.layout;
+ isRowMajorLayout = other.isRowMajorLayout;
+ binding = other.binding;
+ staticUse = other.staticUse;
+ active = other.active;
+ blockType = other.blockType;
+ fields = other.fields;
+ return *this;
+}
+
+std::string InterfaceBlock::fieldPrefix() const
+{
+ return instanceName.empty() ? "" : name;
+}
+
+std::string InterfaceBlock::fieldMappedPrefix() const
+{
+ return instanceName.empty() ? "" : mappedName;
+}
+
+bool InterfaceBlock::isSameInterfaceBlockAtLinkTime(const InterfaceBlock &other) const
+{
+ if (name != other.name || mappedName != other.mappedName || arraySize != other.arraySize ||
+ layout != other.layout || isRowMajorLayout != other.isRowMajorLayout ||
+ binding != other.binding || blockType != other.blockType ||
+ 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;
+}
+
+bool InterfaceBlock::isBuiltIn() const
+{
+ return gl::IsBuiltInName(name);
+}
+
+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/gfx/angle/checkout/src/compiler/translator/StaticType.h b/gfx/angle/checkout/src/compiler/translator/StaticType.h
new file mode 100644
index 0000000000..641daadebd
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/StaticType.h
@@ -0,0 +1,296 @@
+//
+// Copyright 2017 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.
+//
+// Compile-time instances of many common TType values. These are looked up
+// (statically or dynamically) through the methods defined in the namespace.
+//
+
+#ifndef COMPILER_TRANSLATOR_STATIC_TYPE_H_
+#define COMPILER_TRANSLATOR_STATIC_TYPE_H_
+
+#include "compiler/translator/Types.h"
+
+namespace sh
+{
+
+namespace StaticType
+{
+
+namespace Helpers
+{
+
+//
+// Generation and static allocation of type mangled name values.
+//
+
+// Size of the constexpr-generated mangled name.
+// If this value is too small, the compiler will produce errors.
+static constexpr size_t kStaticMangledNameLength = TBasicMangledName::mangledNameSize + 1;
+
+// Type which holds the mangled names for constexpr-generated TTypes.
+// This simple struct is needed so that a char array can be returned by value.
+struct StaticMangledName
+{
+ // If this array is too small, the compiler will produce errors.
+ char name[kStaticMangledNameLength + 1] = {};
+};
+
+// Generates a mangled name for a TType given its parameters.
+constexpr StaticMangledName BuildStaticMangledName(TBasicType basicType,
+ TPrecision precision,
+ TQualifier qualifier,
+ uint8_t primarySize,
+ uint8_t secondarySize)
+{
+ StaticMangledName name = {};
+ name.name[0] = TType::GetSizeMangledName(primarySize, secondarySize);
+ TBasicMangledName typeName(basicType);
+ char *mangledName = typeName.getName();
+ static_assert(TBasicMangledName::mangledNameSize == 2, "Mangled name size is not 2");
+ name.name[1] = mangledName[0];
+ name.name[2] = mangledName[1];
+ name.name[3] = '\0';
+ return name;
+}
+
+// Similar mangled name builder but for array types. Currently, only single-dimension arrays of
+// single-digit size are necessary and supported.
+static constexpr size_t kStaticArrayMangledNameLength = kStaticMangledNameLength + 2;
+struct StaticArrayMangledName
+{
+ char name[kStaticArrayMangledNameLength + 1] = {};
+};
+constexpr StaticArrayMangledName BuildStaticArrayMangledName(TBasicType basicType,
+ TPrecision precision,
+ TQualifier qualifier,
+ uint8_t primarySize,
+ uint8_t secondarySize,
+ const unsigned int *arraySizes,
+ size_t numArraySizes)
+{
+ StaticMangledName nonArrayName =
+ BuildStaticMangledName(basicType, precision, qualifier, primarySize, secondarySize);
+
+ StaticArrayMangledName arrayName = {};
+ static_assert(kStaticMangledNameLength == 3, "Static mangled name size is not 3");
+
+ arrayName.name[0] = nonArrayName.name[0];
+ arrayName.name[1] = nonArrayName.name[1];
+ arrayName.name[2] = nonArrayName.name[2];
+ arrayName.name[3] = 'x';
+ arrayName.name[4] = static_cast<char>('0' + arraySizes[0]);
+ arrayName.name[5] = '\0';
+ return arrayName;
+}
+
+// This "variable" contains the mangled names for every constexpr-generated TType.
+// If kMangledNameInstance<B, P, Q, PS, SS> is used anywhere (specifally
+// in instance, below), this is where the appropriate type will be stored.
+template <TBasicType basicType,
+ TPrecision precision,
+ TQualifier qualifier,
+ uint8_t primarySize,
+ uint8_t secondarySize>
+static constexpr StaticMangledName kMangledNameInstance =
+ BuildStaticMangledName(basicType, precision, qualifier, primarySize, secondarySize);
+
+// Same as kMangledNameInstance, but for array types.
+template <TBasicType basicType,
+ TPrecision precision,
+ TQualifier qualifier,
+ uint8_t primarySize,
+ uint8_t secondarySize,
+ const unsigned int *arraySizes,
+ size_t numArraySizes>
+static constexpr StaticArrayMangledName kMangledNameArrayInstance =
+ BuildStaticArrayMangledName(basicType,
+ precision,
+ qualifier,
+ primarySize,
+ secondarySize,
+ arraySizes,
+ numArraySizes);
+
+//
+// Generation and static allocation of TType values.
+//
+
+// This "variable" contains every constexpr-generated TType.
+// If instance<B, P, Q, PS, SS> is used anywhere (specifally
+// in Get, below), this is where the appropriate type will be stored.
+//
+// TODO(crbug.com/981610): This is constexpr but doesn't follow the kConstant naming convention
+// because TType has a mutable member that prevents it from being in .data.rel.ro and makes the
+// Android Binary Size builder complain when ANGLE is rolled in Chromium.
+template <TBasicType basicType,
+ TPrecision precision,
+ TQualifier qualifier,
+ uint8_t primarySize,
+ uint8_t secondarySize>
+static constexpr TType instance =
+ TType(basicType,
+ precision,
+ qualifier,
+ primarySize,
+ secondarySize,
+ TSpan<const unsigned int>(),
+ kMangledNameInstance<basicType, precision, qualifier, primarySize, secondarySize>.name);
+
+// Same as instance, but for array types.
+template <TBasicType basicType,
+ TPrecision precision,
+ TQualifier qualifier,
+ uint8_t primarySize,
+ uint8_t secondarySize,
+ const unsigned int *arraySizes,
+ size_t numArraySizes>
+static constexpr TType arrayInstance =
+ TType(basicType,
+ precision,
+ qualifier,
+ primarySize,
+ secondarySize,
+ TSpan<const unsigned int>(arraySizes, numArraySizes),
+ kMangledNameArrayInstance<basicType, precision, qualifier, primarySize, secondarySize, arraySizes, numArraySizes>.name);
+
+} // namespace Helpers
+
+//
+// Fully-qualified type lookup.
+//
+
+template <TBasicType basicType,
+ TPrecision precision,
+ TQualifier qualifier,
+ uint8_t primarySize,
+ uint8_t secondarySize>
+constexpr const TType *Get()
+{
+ static_assert(1 <= primarySize && primarySize <= 4, "primarySize out of bounds");
+ static_assert(1 <= secondarySize && secondarySize <= 4, "secondarySize out of bounds");
+ return &Helpers::instance<basicType, precision, qualifier, primarySize, secondarySize>;
+}
+
+template <TBasicType basicType,
+ TPrecision precision,
+ TQualifier qualifier,
+ uint8_t primarySize,
+ uint8_t secondarySize,
+ const unsigned int *arraySizes,
+ size_t numArraySizes>
+constexpr const TType *GetArray()
+{
+ static_assert(1 <= primarySize && primarySize <= 4, "primarySize out of bounds");
+ static_assert(1 <= secondarySize && secondarySize <= 4, "secondarySize out of bounds");
+ static_assert(numArraySizes == 1, "only single-dimension static types are supported");
+ static_assert(arraySizes[0] < 10, "only single-digit dimensions are supported in static types");
+ return &Helpers::arrayInstance<basicType, precision, qualifier, primarySize, secondarySize,
+ arraySizes, numArraySizes>;
+}
+
+//
+// Overloads
+//
+
+template <TBasicType basicType,
+ TPrecision precision,
+ uint8_t primarySize = 1,
+ uint8_t secondarySize = 1>
+constexpr const TType *GetBasic()
+{
+ return Get<basicType, precision, EvqGlobal, primarySize, secondarySize>();
+}
+
+template <TBasicType basicType,
+ TPrecision precision,
+ uint8_t primarySize = 1,
+ uint8_t secondarySize = 1>
+constexpr const TType *GetTemporary()
+{
+ return Get<basicType, precision, EvqTemporary, primarySize, secondarySize>();
+}
+
+template <TBasicType basicType,
+ TPrecision precision,
+ TQualifier qualifier,
+ uint8_t primarySize = 1,
+ uint8_t secondarySize = 1>
+const TType *GetQualified()
+{
+ return Get<basicType, precision, qualifier, primarySize, secondarySize>();
+}
+
+// Dynamic lookup methods (convert runtime values to template args)
+
+namespace Helpers
+{
+
+// Helper which takes secondarySize statically but primarySize dynamically.
+template <TBasicType basicType, TPrecision precision, TQualifier qualifier, uint8_t secondarySize>
+constexpr const TType *GetForVecMatHelper(uint8_t primarySize)
+{
+ static_assert(basicType == EbtFloat || basicType == EbtInt || basicType == EbtUInt ||
+ basicType == EbtBool,
+ "unsupported basicType");
+ switch (primarySize)
+ {
+ case 1:
+ return Get<basicType, precision, qualifier, 1, secondarySize>();
+ case 2:
+ return Get<basicType, precision, qualifier, 2, secondarySize>();
+ case 3:
+ return Get<basicType, precision, qualifier, 3, secondarySize>();
+ case 4:
+ return Get<basicType, precision, qualifier, 4, secondarySize>();
+ default:
+ UNREACHABLE();
+ return GetBasic<EbtVoid, EbpUndefined>();
+ }
+}
+
+} // namespace Helpers
+
+template <TBasicType basicType, TPrecision precision, TQualifier qualifier = EvqGlobal>
+constexpr const TType *GetForVecMat(uint8_t primarySize, uint8_t secondarySize = 1)
+{
+ static_assert(basicType == EbtFloat || basicType == EbtInt || basicType == EbtUInt ||
+ basicType == EbtBool,
+ "unsupported basicType");
+ switch (secondarySize)
+ {
+ case 1:
+ return Helpers::GetForVecMatHelper<basicType, precision, qualifier, 1>(primarySize);
+ case 2:
+ return Helpers::GetForVecMatHelper<basicType, precision, qualifier, 2>(primarySize);
+ case 3:
+ return Helpers::GetForVecMatHelper<basicType, precision, qualifier, 3>(primarySize);
+ case 4:
+ return Helpers::GetForVecMatHelper<basicType, precision, qualifier, 4>(primarySize);
+ default:
+ UNREACHABLE();
+ return GetBasic<EbtVoid, EbpUndefined>();
+ }
+}
+
+template <TBasicType basicType, TPrecision precision>
+constexpr const TType *GetForVec(TQualifier qualifier, uint8_t size)
+{
+ switch (qualifier)
+ {
+ case EvqGlobal:
+ return Helpers::GetForVecMatHelper<basicType, precision, EvqGlobal, 1>(size);
+ case EvqParamOut:
+ return Helpers::GetForVecMatHelper<basicType, precision, EvqParamOut, 1>(size);
+ default:
+ UNREACHABLE();
+ return GetBasic<EbtVoid, EbpUndefined>();
+ }
+}
+
+} // namespace StaticType
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_STATIC_TYPE_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/StructureHLSL.cpp b/gfx/angle/checkout/src/compiler/translator/StructureHLSL.cpp
new file mode 100644
index 0000000000..eae602f5ea
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/StructureHLSL.cpp
@@ -0,0 +1,668 @@
+//
+// 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.
+//
+// StructureHLSL.cpp:
+// HLSL translation of GLSL constructors and structures.
+//
+
+#include "compiler/translator/StructureHLSL.h"
+#include "common/utilities.h"
+#include "compiler/translator/OutputHLSL.h"
+#include "compiler/translator/Types.h"
+#include "compiler/translator/UtilsHLSL.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+TString Define(const TStructure &structure,
+ bool useHLSLRowMajorPacking,
+ bool useStd140Packing,
+ bool forcePadding,
+ Std140PaddingHelper *padHelper)
+{
+ const TFieldList &fields = structure.fields();
+ const bool isNameless = (structure.symbolType() == SymbolType::Empty);
+ const TString &structName = QualifiedStructNameString(structure, useHLSLRowMajorPacking,
+ useStd140Packing, forcePadding);
+ const TString declareString = (isNameless ? "struct" : "struct " + structName);
+
+ TString string;
+ string += declareString +
+ "\n"
+ "{\n";
+
+ size_t memberSize = fields.size();
+ for (const TField *field : fields)
+ {
+ memberSize--;
+ const TType &fieldType = *field->type();
+ if (!IsSampler(fieldType.getBasicType()))
+ {
+ const TStructure *fieldStruct = fieldType.getStruct();
+ const TString &fieldTypeString =
+ fieldStruct ? QualifiedStructNameString(*fieldStruct, useHLSLRowMajorPacking,
+ useStd140Packing, false)
+ : TypeString(fieldType);
+
+ if (padHelper)
+ {
+ string += padHelper->prePaddingString(
+ fieldType, (memberSize != fields.size() - 1) && forcePadding);
+ }
+
+ string += " " + fieldTypeString + " " + DecorateField(field->name(), structure) +
+ ArrayString(fieldType).data() + ";\n";
+
+ if (padHelper)
+ {
+ string += padHelper->postPaddingString(fieldType, useHLSLRowMajorPacking,
+ memberSize == 0, forcePadding);
+ }
+ }
+ }
+
+ // Nameless structs do not finish with a semicolon and newline, to leave room for an instance
+ // variable
+ string += (isNameless ? "} " : "};\n");
+
+ return string;
+}
+
+TString WriteParameterList(const std::vector<TType> &parameters)
+{
+ TString parameterList;
+ for (size_t parameter = 0u; parameter < parameters.size(); parameter++)
+ {
+ const TType &paramType = parameters[parameter];
+
+ parameterList +=
+ TypeString(paramType) + " x" + str(parameter) + ArrayString(paramType).data();
+
+ if (parameter < parameters.size() - 1u)
+ {
+ parameterList += ", ";
+ }
+ }
+ return parameterList;
+}
+
+int GetElementPadding(int elementIndex, int alignment)
+{
+ const int paddingOffset = elementIndex % alignment;
+ return paddingOffset != 0 ? (alignment - paddingOffset) : 0;
+}
+
+} // anonymous namespace
+
+Std140PaddingHelper::Std140PaddingHelper(const std::map<TString, int> &structElementIndexes,
+ unsigned *uniqueCounter)
+ : mPaddingCounter(uniqueCounter), mElementIndex(0), mStructElementIndexes(&structElementIndexes)
+{}
+
+Std140PaddingHelper::Std140PaddingHelper(const Std140PaddingHelper &other)
+ : mPaddingCounter(other.mPaddingCounter),
+ mElementIndex(other.mElementIndex),
+ mStructElementIndexes(other.mStructElementIndexes)
+{}
+
+Std140PaddingHelper &Std140PaddingHelper::operator=(const Std140PaddingHelper &other)
+{
+ mPaddingCounter = other.mPaddingCounter;
+ mElementIndex = other.mElementIndex;
+ mStructElementIndexes = other.mStructElementIndexes;
+ return *this;
+}
+
+TString Std140PaddingHelper::next()
+{
+ unsigned value = (*mPaddingCounter)++;
+ return str(value);
+}
+
+int Std140PaddingHelper::prePadding(const TType &type, bool forcePadding)
+{
+ if (type.getBasicType() == EbtStruct || type.isMatrix() || type.isArray())
+ {
+ if (forcePadding)
+ {
+ // Add padding between the structure's members to follow the std140 rules manually.
+ const int forcePaddingCount = GetElementPadding(mElementIndex, 4);
+ mElementIndex = 0;
+ return forcePaddingCount;
+ }
+ else
+ {
+ // no padding needed, HLSL will align the field to a new register
+ mElementIndex = 0;
+ return 0;
+ }
+ }
+
+ const GLenum glType = GLVariableType(type);
+ const int numComponents = gl::VariableComponentCount(glType);
+
+ if (numComponents >= 4)
+ {
+ if (forcePadding)
+ {
+ // Add padding between the structure's members to follow the std140 rules manually.
+ const int forcePaddingCount = GetElementPadding(mElementIndex, 4);
+ mElementIndex = numComponents % 4;
+ return forcePaddingCount;
+ }
+ else
+ {
+ // no padding needed, HLSL will align the field to a new register
+ mElementIndex = 0;
+ return 0;
+ }
+ }
+
+ if (mElementIndex + numComponents > 4)
+ {
+ if (forcePadding)
+ {
+ // Add padding between the structure's members to follow the std140 rules manually.
+ const int forcePaddingCount = GetElementPadding(mElementIndex, 4);
+ mElementIndex = numComponents;
+ return forcePaddingCount;
+ }
+ else
+ {
+ // no padding needed, HLSL will align the field to a new register
+ mElementIndex = numComponents;
+ return 0;
+ }
+ }
+
+ const int alignment = numComponents == 3 ? 4 : numComponents;
+ const int paddingCount = GetElementPadding(mElementIndex, alignment);
+
+ mElementIndex += paddingCount;
+ mElementIndex += numComponents;
+ mElementIndex %= 4;
+
+ return paddingCount;
+}
+
+TString Std140PaddingHelper::prePaddingString(const TType &type, bool forcePadding)
+{
+ int paddingCount = prePadding(type, forcePadding);
+
+ TString padding;
+
+ for (int paddingIndex = 0; paddingIndex < paddingCount; paddingIndex++)
+ {
+ padding += " float pad_" + next() + ";\n";
+ }
+
+ return padding;
+}
+
+TString Std140PaddingHelper::postPaddingString(const TType &type,
+ bool useHLSLRowMajorPacking,
+ bool isLastElement,
+ bool forcePadding)
+{
+ if (!type.isMatrix() && !type.isArray() && type.getBasicType() != EbtStruct)
+ {
+ if (forcePadding)
+ {
+ const GLenum glType = GLVariableType(type);
+ const int numComponents = gl::VariableComponentCount(glType);
+ if (isLastElement || (numComponents >= 4))
+ {
+ // If this structure will be used as HLSL StructuredBuffer member's type, in
+ // order to follow the std140 rules, add padding at the end of the structure
+ // if necessary. Or if the current element straddles a vec4 boundary, add
+ // padding to round up the base offset of the next element to the base
+ // alignment of a vec4.
+ TString forcePaddingStr;
+ const int paddingCount = GetElementPadding(mElementIndex, 4);
+ for (int paddingIndex = 0; paddingIndex < paddingCount; paddingIndex++)
+ {
+ forcePaddingStr += " float pad_" + next() + ";\n";
+ }
+ mElementIndex = 0;
+ return forcePaddingStr;
+ }
+ }
+
+ return "";
+ }
+
+ int numComponents = 0;
+ const TStructure *structure = type.getStruct();
+
+ if (type.isMatrix())
+ {
+ // This method can also be called from structureString, which does not use layout
+ // qualifiers.
+ // Thus, use the method parameter for determining the matrix packing.
+ //
+ // Note HLSL row major packing corresponds to GL API column-major, and vice-versa, since we
+ // wish to always transpose GL matrices to play well with HLSL's matrix array indexing.
+ //
+ const bool isRowMajorMatrix = !useHLSLRowMajorPacking;
+ const GLenum glType = GLVariableType(type);
+ numComponents = gl::MatrixComponentCount(glType, isRowMajorMatrix);
+ }
+ else if (structure)
+ {
+ const TString &structName =
+ QualifiedStructNameString(*structure, useHLSLRowMajorPacking, true, false);
+ numComponents = mStructElementIndexes->find(structName)->second;
+
+ if (numComponents == 0)
+ {
+ return "";
+ }
+ }
+ else
+ {
+ const GLenum glType = GLVariableType(type);
+ numComponents = gl::VariableComponentCount(glType);
+ }
+
+ TString padding;
+ for (int paddingOffset = numComponents; paddingOffset < 4; paddingOffset++)
+ {
+ padding += " float pad_" + next() + ";\n";
+ }
+ return padding;
+}
+
+StructureHLSL::StructureHLSL() : mUniquePaddingCounter(0) {}
+
+Std140PaddingHelper StructureHLSL::getPaddingHelper()
+{
+ return Std140PaddingHelper(mStd140StructElementIndexes, &mUniquePaddingCounter);
+}
+
+TString StructureHLSL::defineQualified(const TStructure &structure,
+ bool useHLSLRowMajorPacking,
+ bool useStd140Packing,
+ bool forcePadding)
+{
+ if (useStd140Packing)
+ {
+ Std140PaddingHelper padHelper = getPaddingHelper();
+ return Define(structure, useHLSLRowMajorPacking, useStd140Packing, forcePadding,
+ &padHelper);
+ }
+ else
+ {
+ return Define(structure, useHLSLRowMajorPacking, useStd140Packing, false, nullptr);
+ }
+}
+
+TString StructureHLSL::defineNameless(const TStructure &structure)
+{
+ return Define(structure, false, false, false, nullptr);
+}
+
+StructureHLSL::DefinedStructs::iterator StructureHLSL::defineVariants(const TStructure &structure,
+ const TString &name)
+{
+ ASSERT(mDefinedStructs.find(name) == mDefinedStructs.end());
+
+ for (const TField *field : structure.fields())
+ {
+ const TType *fieldType = field->type();
+ if (fieldType->getBasicType() == EbtStruct)
+ {
+ ensureStructDefined(*fieldType->getStruct());
+ }
+ }
+
+ DefinedStructs::iterator addedStruct =
+ mDefinedStructs.insert(std::make_pair(name, new TStructProperties())).first;
+ // Add element index
+ storeStd140ElementIndex(structure, false);
+ storeStd140ElementIndex(structure, true);
+
+ const TString &structString = defineQualified(structure, false, false, false);
+
+ ASSERT(std::find(mStructDeclarations.begin(), mStructDeclarations.end(), structString) ==
+ mStructDeclarations.end());
+ // Add row-major packed struct for interface blocks
+ TString rowMajorString = "#pragma pack_matrix(row_major)\n" +
+ defineQualified(structure, true, false, false) +
+ "#pragma pack_matrix(column_major)\n";
+
+ TString std140String = defineQualified(structure, false, true, false);
+ TString std140RowMajorString = "#pragma pack_matrix(row_major)\n" +
+ defineQualified(structure, true, true, false) +
+ "#pragma pack_matrix(column_major)\n";
+
+ // Must force to pad the structure's elements for StructuredBuffer's element type, if qualifier
+ // of structure is std140.
+ TString std140ForcePaddingString = defineQualified(structure, false, true, true);
+ TString std140RowMajorForcePaddingString = "#pragma pack_matrix(row_major)\n" +
+ defineQualified(structure, true, true, true) +
+ "#pragma pack_matrix(column_major)\n";
+
+ mStructDeclarations.push_back(structString);
+ mStructDeclarations.push_back(rowMajorString);
+ mStructDeclarations.push_back(std140String);
+ mStructDeclarations.push_back(std140RowMajorString);
+ mStructDeclarations.push_back(std140ForcePaddingString);
+ mStructDeclarations.push_back(std140RowMajorForcePaddingString);
+ return addedStruct;
+}
+
+void StructureHLSL::ensureStructDefined(const TStructure &structure)
+{
+ const TString name = StructNameString(structure);
+ if (name == "")
+ {
+ return; // Nameless structures are not defined
+ }
+ if (mDefinedStructs.find(name) == mDefinedStructs.end())
+ {
+ defineVariants(structure, name);
+ }
+}
+
+TString StructureHLSL::addStructConstructor(const TStructure &structure)
+{
+ const TString name = StructNameString(structure);
+
+ if (name == "")
+ {
+ return TString(); // Nameless structures don't have constructors
+ }
+
+ auto definedStruct = mDefinedStructs.find(name);
+ if (definedStruct == mDefinedStructs.end())
+ {
+ definedStruct = defineVariants(structure, name);
+ }
+ const TString constructorFunctionName = TString(name) + "_ctor";
+ TString *constructor = &definedStruct->second->constructor;
+ if (!constructor->empty())
+ {
+ return constructorFunctionName; // Already added
+ }
+ *constructor += name + " " + constructorFunctionName + "(";
+
+ std::vector<TType> ctorParameters;
+ const TFieldList &fields = structure.fields();
+ for (const TField *field : fields)
+ {
+ const TType *fieldType = field->type();
+ if (!IsSampler(fieldType->getBasicType()))
+ {
+ ctorParameters.push_back(*fieldType);
+ }
+ }
+ // Structs that have sampler members should not have constructor calls, and otherwise structs
+ // are guaranteed to be non-empty by the grammar. Structs can't contain empty declarations
+ // either.
+ ASSERT(!ctorParameters.empty());
+
+ *constructor += WriteParameterList(ctorParameters);
+
+ *constructor +=
+ ")\n"
+ "{\n"
+ " " +
+ name + " structure = { ";
+
+ for (size_t parameterIndex = 0u; parameterIndex < ctorParameters.size(); ++parameterIndex)
+ {
+ *constructor += "x" + str(parameterIndex);
+ if (parameterIndex < ctorParameters.size() - 1u)
+ {
+ *constructor += ", ";
+ }
+ }
+ *constructor +=
+ "};\n"
+ " return structure;\n"
+ "}\n";
+
+ return constructorFunctionName;
+}
+
+TString StructureHLSL::addBuiltInConstructor(const TType &type, const TIntermSequence *parameters)
+{
+ ASSERT(!type.isArray());
+ ASSERT(type.getStruct() == nullptr);
+ ASSERT(parameters);
+
+ TType ctorType = type;
+ ctorType.setPrecision(EbpHigh);
+ ctorType.setQualifier(EvqTemporary);
+
+ const TString constructorFunctionName =
+ TString(type.getBuiltInTypeNameString()) + "_ctor" + DisambiguateFunctionName(parameters);
+ TString constructor = TypeString(ctorType) + " " + constructorFunctionName + "(";
+
+ std::vector<TType> ctorParameters;
+ for (auto parameter : *parameters)
+ {
+ const TType &paramType = parameter->getAsTyped()->getType();
+ ASSERT(!paramType.isArray());
+ ctorParameters.push_back(paramType);
+ }
+ constructor += WriteParameterList(ctorParameters);
+
+ constructor +=
+ ")\n"
+ "{\n"
+ " return " +
+ TypeString(ctorType) + "(";
+
+ if (ctorType.isMatrix() && ctorParameters.size() == 1)
+ {
+ uint8_t rows = ctorType.getRows();
+ uint8_t cols = ctorType.getCols();
+ const TType &parameter = ctorParameters[0];
+
+ if (parameter.isScalar())
+ {
+ for (uint8_t col = 0; col < cols; col++)
+ {
+ for (uint8_t row = 0; row < rows; row++)
+ {
+ constructor += TString((row == col) ? "x0" : "0.0");
+
+ if (row < rows - 1 || col < cols - 1)
+ {
+ constructor += ", ";
+ }
+ }
+ }
+ }
+ else if (parameter.isMatrix())
+ {
+ for (uint8_t col = 0; col < cols; col++)
+ {
+ for (uint8_t row = 0; row < rows; row++)
+ {
+ if (row < parameter.getRows() && col < parameter.getCols())
+ {
+ constructor += TString("x0") + "[" + str(col) + "][" + str(row) + "]";
+ }
+ else
+ {
+ constructor += TString((row == col) ? "1.0" : "0.0");
+ }
+
+ if (row < rows - 1 || col < cols - 1)
+ {
+ constructor += ", ";
+ }
+ }
+ }
+ }
+ else
+ {
+ ASSERT(rows == 2 && cols == 2 && parameter.isVector() &&
+ parameter.getNominalSize() == 4);
+
+ constructor += "x0";
+ }
+ }
+ else
+ {
+ size_t remainingComponents = ctorType.getObjectSize();
+ size_t parameterIndex = 0;
+
+ while (remainingComponents > 0)
+ {
+ const TType &parameter = ctorParameters[parameterIndex];
+ const size_t parameterSize = parameter.getObjectSize();
+ bool moreParameters = parameterIndex + 1 < ctorParameters.size();
+
+ constructor += "x" + str(parameterIndex);
+
+ if (parameter.isScalar())
+ {
+ remainingComponents -= parameter.getObjectSize();
+ }
+ else if (parameter.isVector())
+ {
+ if (remainingComponents == parameterSize || moreParameters)
+ {
+ ASSERT(parameterSize <= remainingComponents);
+ remainingComponents -= parameterSize;
+ }
+ else if (remainingComponents < static_cast<size_t>(parameter.getNominalSize()))
+ {
+ switch (remainingComponents)
+ {
+ case 1:
+ constructor += ".x";
+ break;
+ case 2:
+ constructor += ".xy";
+ break;
+ case 3:
+ constructor += ".xyz";
+ break;
+ case 4:
+ constructor += ".xyzw";
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ remainingComponents = 0;
+ }
+ else
+ UNREACHABLE();
+ }
+ else if (parameter.isMatrix())
+ {
+ uint8_t column = 0;
+ while (remainingComponents > 0 && column < parameter.getCols())
+ {
+ constructor += "[" + str(column) + "]";
+
+ if (remainingComponents < static_cast<size_t>(parameter.getRows()))
+ {
+ switch (remainingComponents)
+ {
+ case 1:
+ constructor += ".x";
+ break;
+ case 2:
+ constructor += ".xy";
+ break;
+ case 3:
+ constructor += ".xyz";
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ remainingComponents = 0;
+ }
+ else
+ {
+ remainingComponents -= parameter.getRows();
+
+ if (remainingComponents > 0)
+ {
+ constructor += ", x" + str(parameterIndex);
+ }
+ }
+
+ column++;
+ }
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+
+ if (moreParameters)
+ {
+ parameterIndex++;
+ }
+
+ if (remainingComponents)
+ {
+ constructor += ", ";
+ }
+ }
+ }
+
+ constructor +=
+ ");\n"
+ "}\n";
+
+ mBuiltInConstructors.insert(constructor);
+
+ return constructorFunctionName;
+}
+
+std::string StructureHLSL::structsHeader() const
+{
+ TInfoSinkBase out;
+
+ for (auto &declaration : mStructDeclarations)
+ {
+ out << declaration;
+ }
+
+ for (auto &structure : mDefinedStructs)
+ {
+ out << structure.second->constructor;
+ }
+
+ for (auto &constructor : mBuiltInConstructors)
+ {
+ out << constructor;
+ }
+
+ return out.str();
+}
+
+void StructureHLSL::storeStd140ElementIndex(const TStructure &structure,
+ bool useHLSLRowMajorPacking)
+{
+ Std140PaddingHelper padHelper = getPaddingHelper();
+ const TFieldList &fields = structure.fields();
+
+ for (const TField *field : fields)
+ {
+ padHelper.prePadding(*field->type(), false);
+ }
+
+ // Add remaining element index to the global map, for use with nested structs in standard
+ // layouts
+ const TString &structName =
+ QualifiedStructNameString(structure, useHLSLRowMajorPacking, true, false);
+ mStd140StructElementIndexes[structName] = padHelper.elementIndex();
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/StructureHLSL.h b/gfx/angle/checkout/src/compiler/translator/StructureHLSL.h
new file mode 100644
index 0000000000..7f3b0356f7
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/StructureHLSL.h
@@ -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.
+//
+// StructureHLSL.h:
+// HLSL translation of GLSL constructors and structures.
+//
+
+#ifndef COMPILER_TRANSLATOR_STRUCTUREHLSL_H_
+#define COMPILER_TRANSLATOR_STRUCTUREHLSL_H_
+
+#include "compiler/translator/Common.h"
+#include "compiler/translator/IntermNode.h"
+
+#include <set>
+
+class TInfoSinkBase;
+class TScopeBracket;
+
+namespace sh
+{
+
+// This helper class assists structure and interface block definitions in determining
+// how to pack std140 structs within HLSL's packing rules.
+class Std140PaddingHelper
+{
+ public:
+ explicit Std140PaddingHelper(const std::map<TString, int> &structElementIndexes,
+ unsigned int *uniqueCounter);
+ Std140PaddingHelper(const Std140PaddingHelper &other);
+ Std140PaddingHelper &operator=(const Std140PaddingHelper &other);
+
+ int elementIndex() const { return mElementIndex; }
+ int prePadding(const TType &type, bool forcePadding);
+ TString prePaddingString(const TType &type, bool forcePadding);
+ TString postPaddingString(const TType &type,
+ bool useHLSLRowMajorPacking,
+ bool isLastElement,
+ bool forcePadding);
+
+ private:
+ TString next();
+
+ unsigned *mPaddingCounter;
+ int mElementIndex;
+ const std::map<TString, int> *mStructElementIndexes;
+};
+
+class StructureHLSL : angle::NonCopyable
+{
+ public:
+ StructureHLSL();
+
+ // Returns the name of the constructor function.
+ TString addStructConstructor(const TStructure &structure);
+ TString addBuiltInConstructor(const TType &type, const TIntermSequence *parameters);
+
+ static TString defineNameless(const TStructure &structure);
+ void ensureStructDefined(const TStructure &structure);
+
+ std::string structsHeader() const;
+
+ Std140PaddingHelper getPaddingHelper();
+
+ private:
+ unsigned mUniquePaddingCounter;
+
+ std::map<TString, int> mStd140StructElementIndexes;
+
+ struct TStructProperties : public angle::NonCopyable
+ {
+ POOL_ALLOCATOR_NEW_DELETE
+
+ TStructProperties() {}
+
+ // Constructor is an empty string in case the struct doesn't have a constructor yet.
+ TString constructor;
+ };
+
+ // Map from struct name to struct properties.
+ typedef std::map<TString, TStructProperties *> DefinedStructs;
+ DefinedStructs mDefinedStructs;
+
+ // Struct declarations need to be kept in a vector instead of having them inside mDefinedStructs
+ // since maintaining the original order is necessary for nested structs.
+ typedef std::vector<TString> StructDeclarations;
+ StructDeclarations mStructDeclarations;
+
+ typedef std::set<TString> BuiltInConstructors;
+ BuiltInConstructors mBuiltInConstructors;
+
+ void storeStd140ElementIndex(const TStructure &structure, bool useHLSLRowMajorPacking);
+ TString defineQualified(const TStructure &structure,
+ bool useHLSLRowMajorPacking,
+ bool useStd140Packing,
+ bool forcePackingEnd);
+ DefinedStructs::iterator defineVariants(const TStructure &structure, const TString &name);
+};
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_STRUCTUREHLSL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/Symbol.cpp b/gfx/angle/checkout/src/compiler/translator/Symbol.cpp
new file mode 100644
index 0000000000..dddf770715
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/Symbol.cpp
@@ -0,0 +1,254 @@
+//
+// Copyright 2017 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.
+//
+// Symbol.cpp: Symbols representing variables, functions, structures and interface blocks.
+//
+
+#if defined(_MSC_VER)
+# pragma warning(disable : 4718)
+#endif
+
+#include "compiler/translator/Symbol.h"
+
+#include "compiler/translator/ImmutableStringBuilder.h"
+#include "compiler/translator/SymbolTable.h"
+
+namespace sh
+{
+
+namespace
+{
+
+constexpr const ImmutableString kMainName("main");
+constexpr const ImmutableString kImageLoadName("imageLoad");
+constexpr const ImmutableString kImageStoreName("imageStore");
+constexpr const ImmutableString kImageSizeName("imageSize");
+constexpr const ImmutableString kImageAtomicExchangeName("imageAtomicExchange");
+constexpr const ImmutableString kAtomicCounterName("atomicCounter");
+
+static const char kFunctionMangledNameSeparator = '(';
+
+} // anonymous namespace
+
+TSymbol::TSymbol(TSymbolTable *symbolTable,
+ const ImmutableString &name,
+ SymbolType symbolType,
+ SymbolClass symbolClass,
+ TExtension extension)
+ : mName(name),
+ mUniqueId(symbolTable->nextUniqueId()),
+ mExtensions(
+ std::array<TExtension, 3u>{{extension, TExtension::UNDEFINED, TExtension::UNDEFINED}}),
+ mSymbolType(symbolType),
+ mSymbolClass(symbolClass)
+{
+ ASSERT(mSymbolType == SymbolType::BuiltIn || extension == TExtension::UNDEFINED);
+ ASSERT(mName != "" || mSymbolType == SymbolType::AngleInternal ||
+ mSymbolType == SymbolType::Empty);
+}
+
+TSymbol::TSymbol(TSymbolTable *symbolTable,
+ const ImmutableString &name,
+ SymbolType symbolType,
+ SymbolClass symbolClass,
+ const std::array<TExtension, 3u> &extensions)
+ : mName(name),
+ mUniqueId(symbolTable->nextUniqueId()),
+ mExtensions(extensions),
+ mSymbolType(symbolType),
+ mSymbolClass(symbolClass)
+{
+ ASSERT(mSymbolType == SymbolType::BuiltIn || extensions[0] == TExtension::UNDEFINED);
+ ASSERT(mName != "" || mSymbolType == SymbolType::AngleInternal ||
+ mSymbolType == SymbolType::Empty);
+}
+
+ImmutableString TSymbol::name() const
+{
+ if (!mName.empty())
+ {
+ return mName;
+ }
+ // This can be called for nameless function parameters in HLSL.
+ ASSERT(mSymbolType == SymbolType::AngleInternal ||
+ (mSymbolType == SymbolType::Empty && isVariable()));
+ int uniqueId = mUniqueId.get();
+ ImmutableStringBuilder symbolNameOut(sizeof(uniqueId) * 2u + 1u);
+ symbolNameOut << 's';
+ symbolNameOut.appendHex(mUniqueId.get());
+ return symbolNameOut;
+}
+
+ImmutableString TSymbol::getMangledName() const
+{
+ if (mSymbolClass == SymbolClass::Function)
+ {
+ // We do this instead of using proper virtual functions so that we can better support
+ // constexpr symbols.
+ return static_cast<const TFunction *>(this)->getFunctionMangledName();
+ }
+ ASSERT(mSymbolType != SymbolType::Empty);
+ return name();
+}
+
+TVariable::TVariable(TSymbolTable *symbolTable,
+ const ImmutableString &name,
+ const TType *type,
+ SymbolType symbolType,
+ TExtension extension)
+ : TSymbol(symbolTable, name, symbolType, SymbolClass::Variable, extension),
+ mType(type),
+ unionArray(nullptr)
+{
+ ASSERT(mType);
+ ASSERT(name.empty() || symbolType != SymbolType::Empty);
+}
+
+TVariable::TVariable(TSymbolTable *symbolTable,
+ const ImmutableString &name,
+ const TType *type,
+ SymbolType symbolType,
+ const std::array<TExtension, 3u> &extensions)
+ : TSymbol(symbolTable, name, symbolType, SymbolClass::Variable, extensions),
+ mType(type),
+ unionArray(nullptr)
+{
+ ASSERT(mType);
+ ASSERT(name.empty() || symbolType != SymbolType::Empty);
+}
+
+TStructure::TStructure(TSymbolTable *symbolTable,
+ const ImmutableString &name,
+ const TFieldList *fields,
+ SymbolType symbolType)
+ : TSymbol(symbolTable, name, symbolType, SymbolClass::Struct), TFieldListCollection(fields)
+{}
+
+void TStructure::createSamplerSymbols(const char *namePrefix,
+ const TString &apiNamePrefix,
+ TVector<const TVariable *> *outputSymbols,
+ TMap<const TVariable *, TString> *outputSymbolsToAPINames,
+ TSymbolTable *symbolTable) const
+{
+ ASSERT(containsSamplers());
+ for (const auto *field : *mFields)
+ {
+ const TType *fieldType = field->type();
+ if (IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers())
+ {
+ std::stringstream fieldName = sh::InitializeStream<std::stringstream>();
+ fieldName << namePrefix << "_" << field->name();
+ TString fieldApiName = apiNamePrefix + ".";
+ fieldApiName += field->name().data();
+ fieldType->createSamplerSymbols(ImmutableString(fieldName.str()), fieldApiName,
+ outputSymbols, outputSymbolsToAPINames, symbolTable);
+ }
+ }
+}
+
+void TStructure::setName(const ImmutableString &name)
+{
+ ImmutableString *mutableName = const_cast<ImmutableString *>(&mName);
+ *mutableName = name;
+}
+
+TInterfaceBlock::TInterfaceBlock(TSymbolTable *symbolTable,
+ const ImmutableString &name,
+ const TFieldList *fields,
+ const TLayoutQualifier &layoutQualifier,
+ SymbolType symbolType,
+ TExtension extension)
+ : TSymbol(symbolTable, name, symbolType, SymbolClass::InterfaceBlock, extension),
+ TFieldListCollection(fields),
+ mBlockStorage(layoutQualifier.blockStorage),
+ mBinding(layoutQualifier.binding)
+{
+ ASSERT(name != nullptr);
+}
+
+TInterfaceBlock::TInterfaceBlock(TSymbolTable *symbolTable,
+ const ImmutableString &name,
+ const TFieldList *fields,
+ const TLayoutQualifier &layoutQualifier,
+ SymbolType symbolType,
+ const std::array<TExtension, 3u> &extensions)
+ : TSymbol(symbolTable, name, symbolType, SymbolClass::InterfaceBlock, extensions),
+ TFieldListCollection(fields),
+ mBlockStorage(layoutQualifier.blockStorage),
+ mBinding(layoutQualifier.binding)
+{
+ ASSERT(name != nullptr);
+}
+
+TFunction::TFunction(TSymbolTable *symbolTable,
+ const ImmutableString &name,
+ SymbolType symbolType,
+ const TType *retType,
+ bool knownToNotHaveSideEffects)
+ : TSymbol(symbolTable, name, symbolType, SymbolClass::Function, TExtension::UNDEFINED),
+ mParametersVector(new TParamVector()),
+ mParameters(nullptr),
+ returnType(retType),
+ mMangledName(""),
+ mParamCount(0u),
+ mOp(EOpNull),
+ defined(false),
+ mHasPrototypeDeclaration(false),
+ mKnownToNotHaveSideEffects(knownToNotHaveSideEffects),
+ mHasVoidParameter(false)
+{
+ // Functions with an empty name are not allowed.
+ ASSERT(symbolType != SymbolType::Empty);
+ ASSERT(name != nullptr || symbolType == SymbolType::AngleInternal);
+}
+
+void TFunction::addParameter(const TVariable *p)
+{
+ ASSERT(mParametersVector);
+ mParametersVector->push_back(p);
+ mParameters = mParametersVector->data();
+ mParamCount = mParametersVector->size();
+ mMangledName = kEmptyImmutableString;
+}
+
+void TFunction::shareParameters(const TFunction &parametersSource)
+{
+ mParametersVector = nullptr;
+ mParameters = parametersSource.mParameters;
+ mParamCount = parametersSource.mParamCount;
+ ASSERT(parametersSource.name() == name());
+ mMangledName = parametersSource.mMangledName;
+}
+
+ImmutableString TFunction::buildMangledName() const
+{
+ ImmutableString name = this->name();
+ std::string newName(name.data(), name.length());
+ newName += kFunctionMangledNameSeparator;
+
+ for (size_t i = 0u; i < mParamCount; ++i)
+ {
+ newName += mParameters[i]->getType().getMangledName();
+ }
+ return ImmutableString(newName);
+}
+
+bool TFunction::isMain() const
+{
+ return symbolType() == SymbolType::UserDefined && name() == kMainName;
+}
+
+bool TFunction::isImageFunction() const
+{
+ return symbolType() == SymbolType::BuiltIn &&
+ (name() == kImageSizeName || name() == kImageLoadName || name() == kImageStoreName ||
+ name() == kImageAtomicExchangeName);
+}
+
+bool TFunction::isAtomicCounterFunction() const
+{
+ return SymbolType() == SymbolType::BuiltIn && name().beginsWith(kAtomicCounterName);
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/Symbol.h b/gfx/angle/checkout/src/compiler/translator/Symbol.h
new file mode 100644
index 0000000000..cb34306be8
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/Symbol.h
@@ -0,0 +1,402 @@
+//
+// Copyright 2017 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.
+//
+// Symbol.h: Symbols representing variables, functions, structures and interface blocks.
+//
+
+#ifndef COMPILER_TRANSLATOR_SYMBOL_H_
+#define COMPILER_TRANSLATOR_SYMBOL_H_
+
+#include "common/angleutils.h"
+#include "compiler/translator/ExtensionBehavior.h"
+#include "compiler/translator/ImmutableString.h"
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/SymbolUniqueId.h"
+
+namespace sh
+{
+
+class TSymbolTable;
+
+// Symbol base class. (Can build functions or variables out of these...)
+class TSymbol : angle::NonCopyable
+{
+ public:
+ POOL_ALLOCATOR_NEW_DELETE
+ TSymbol(TSymbolTable *symbolTable,
+ const ImmutableString &name,
+ SymbolType symbolType,
+ SymbolClass symbolClass,
+ TExtension extension = TExtension::UNDEFINED);
+
+ TSymbol(TSymbolTable *symbolTable,
+ const ImmutableString &name,
+ SymbolType symbolType,
+ SymbolClass symbolClass,
+ const std::array<TExtension, 3u> &extensions);
+
+ // Note that we can't have a virtual destructor in order to support constexpr symbols. Data is
+ // either statically allocated or pool allocated.
+ ~TSymbol() = default;
+
+ // Calling name() for empty symbols (symbolType == SymbolType::Empty) generates a similar name
+ // as for internal variables.
+ ImmutableString name() const;
+ // Don't call getMangledName() for empty symbols (symbolType == SymbolType::Empty).
+ ImmutableString getMangledName() const;
+
+ bool isFunction() const { return mSymbolClass == SymbolClass::Function; }
+ bool isVariable() const { return mSymbolClass == SymbolClass::Variable; }
+ bool isStruct() const { return mSymbolClass == SymbolClass::Struct; }
+ bool isInterfaceBlock() const { return mSymbolClass == SymbolClass::InterfaceBlock; }
+
+ const TSymbolUniqueId &uniqueId() const { return mUniqueId; }
+ SymbolType symbolType() const { return mSymbolType; }
+ const std::array<TExtension, 3u> extensions() const { return mExtensions; }
+
+ template <size_t ExtensionCount>
+ constexpr const std::array<TExtension, 3u> CreateExtensionList(
+ const std::array<TExtension, ExtensionCount> &extensions)
+ {
+ switch (extensions.size())
+ {
+ case 1:
+ return std::array<TExtension, 3u>{
+ {extensions[0], TExtension::UNDEFINED, TExtension::UNDEFINED}};
+ case 2:
+ return std::array<TExtension, 3u>{
+ {extensions[0], extensions[1], TExtension::UNDEFINED}};
+ case 3:
+ return std::array<TExtension, 3u>{{extensions[0], extensions[1], extensions[2]}};
+ default:
+ UNREACHABLE();
+ return std::array<TExtension, 3u>{
+ {TExtension::UNDEFINED, TExtension::UNDEFINED, TExtension::UNDEFINED}};
+ }
+ }
+
+ protected:
+ template <size_t ExtensionCount>
+ constexpr TSymbol(const TSymbolUniqueId &id,
+ const ImmutableString &name,
+ SymbolType symbolType,
+ const std::array<TExtension, ExtensionCount> &extensions,
+ SymbolClass symbolClass)
+ : mName(name),
+ mUniqueId(id),
+ mExtensions(CreateExtensionList(extensions)),
+ mSymbolType(symbolType),
+ mSymbolClass(symbolClass)
+ {}
+
+ const ImmutableString mName;
+
+ private:
+ const TSymbolUniqueId mUniqueId;
+ const std::array<TExtension, 3u> mExtensions;
+ const SymbolType mSymbolType : 4;
+
+ // We use this instead of having virtual functions for querying the class in order to support
+ // constexpr symbols.
+ const SymbolClass mSymbolClass : 4;
+};
+
+static_assert(sizeof(TSymbol) <= 24, "Size check failed");
+
+// Variable.
+// May store the value of a constant variable of any type (float, int, bool or struct).
+class TVariable : public TSymbol
+{
+ public:
+ TVariable(TSymbolTable *symbolTable,
+ const ImmutableString &name,
+ const TType *type,
+ SymbolType symbolType,
+ TExtension ext = TExtension::UNDEFINED);
+
+ TVariable(TSymbolTable *symbolTable,
+ const ImmutableString &name,
+ const TType *type,
+ SymbolType symbolType,
+ const std::array<TExtension, 3u> &extensions);
+
+ const TType &getType() const { return *mType; }
+
+ const TConstantUnion *getConstPointer() const { return unionArray; }
+
+ void shareConstPointer(const TConstantUnion *constArray) { unionArray = constArray; }
+
+ // Note: only to be used for built-in variables with autogenerated ids!
+ constexpr TVariable(const TSymbolUniqueId &id,
+ const ImmutableString &name,
+ SymbolType symbolType,
+ TExtension extension,
+ const TType *type)
+ : TSymbol(id,
+ name,
+ symbolType,
+ std::array<TExtension, 1u>{{extension}},
+ SymbolClass::Variable),
+ mType(type),
+ unionArray(nullptr)
+ {}
+
+ template <size_t ExtensionCount>
+ constexpr TVariable(const TSymbolUniqueId &id,
+ const ImmutableString &name,
+ SymbolType symbolType,
+ const std::array<TExtension, ExtensionCount> &extensions,
+ const TType *type)
+ : TSymbol(id, name, symbolType, extensions, SymbolClass::Variable),
+ mType(type),
+ unionArray(nullptr)
+ {}
+
+ private:
+ const TType *mType;
+ const TConstantUnion *unionArray;
+};
+
+// Struct type.
+class TStructure : public TSymbol, public TFieldListCollection
+{
+ public:
+ TStructure(TSymbolTable *symbolTable,
+ const ImmutableString &name,
+ const TFieldList *fields,
+ SymbolType symbolType);
+
+ // The char arrays passed in must be pool allocated or static.
+ void createSamplerSymbols(const char *namePrefix,
+ const TString &apiNamePrefix,
+ TVector<const TVariable *> *outputSymbols,
+ TMap<const TVariable *, TString> *outputSymbolsToAPINames,
+ TSymbolTable *symbolTable) const;
+
+ void setAtGlobalScope(bool atGlobalScope) { mAtGlobalScope = atGlobalScope; }
+ bool atGlobalScope() const { return mAtGlobalScope; }
+
+ private:
+ friend class TSymbolTable;
+ // For creating built-in structs.
+ TStructure(const TSymbolUniqueId &id,
+ const ImmutableString &name,
+ TExtension extension,
+ const TFieldList *fields)
+ : TSymbol(id,
+ name,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{extension}},
+ SymbolClass::Struct),
+ TFieldListCollection(fields)
+ {}
+
+ template <size_t ExtensionCount>
+ TStructure(const TSymbolUniqueId &id,
+ const ImmutableString &name,
+ const std::array<TExtension, ExtensionCount> &extensions,
+ const TFieldList *fields)
+ : TSymbol(id, name, SymbolType::BuiltIn, extensions, SymbolClass::Struct),
+ TFieldListCollection(fields)
+ {}
+
+ // TODO(zmo): Find a way to get rid of the const_cast in function
+ // setName(). At the moment keep this function private so only
+ // friend class RegenerateStructNames may call it.
+ friend class RegenerateStructNamesTraverser;
+ void setName(const ImmutableString &name);
+
+ bool mAtGlobalScope;
+};
+
+// Interface block. Note that this contains the block name, not the instance name. Interface block
+// instances are stored as TVariable.
+class TInterfaceBlock : public TSymbol, public TFieldListCollection
+{
+ public:
+ TInterfaceBlock(TSymbolTable *symbolTable,
+ const ImmutableString &name,
+ const TFieldList *fields,
+ const TLayoutQualifier &layoutQualifier,
+ SymbolType symbolType,
+ TExtension extension = TExtension::UNDEFINED);
+
+ TInterfaceBlock(TSymbolTable *symbolTable,
+ const ImmutableString &name,
+ const TFieldList *fields,
+ const TLayoutQualifier &layoutQualifier,
+ SymbolType symbolType,
+ const std::array<TExtension, 3u> &extensions);
+
+ TLayoutBlockStorage blockStorage() const { return mBlockStorage; }
+ int blockBinding() const { return mBinding; }
+
+ private:
+ friend class TSymbolTable;
+ // For creating built-in interface blocks.
+ TInterfaceBlock(const TSymbolUniqueId &id,
+ const ImmutableString &name,
+ TExtension extension,
+ const TFieldList *fields)
+ : TSymbol(id,
+ name,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{extension}},
+ SymbolClass::InterfaceBlock),
+ TFieldListCollection(fields),
+ mBlockStorage(EbsUnspecified),
+ mBinding(0)
+ {}
+
+ template <size_t ExtensionCount>
+ TInterfaceBlock(const TSymbolUniqueId &id,
+ const ImmutableString &name,
+ const std::array<TExtension, ExtensionCount> &extensions,
+ const TFieldList *fields)
+ : TSymbol(id, name, SymbolType::BuiltIn, extensions, SymbolClass::InterfaceBlock),
+ TFieldListCollection(fields),
+ mBlockStorage(EbsUnspecified),
+ mBinding(0)
+ {}
+
+ TLayoutBlockStorage mBlockStorage;
+ int mBinding;
+
+ // Note that we only record matrix packing on a per-field granularity.
+};
+
+// Parameter class used for parsing user-defined function parameters.
+struct TParameter
+{
+ // Destructively converts to TVariable.
+ // This method resets name and type to nullptrs to make sure
+ // their content cannot be modified after the call.
+ const TVariable *createVariable(TSymbolTable *symbolTable)
+ {
+ const ImmutableString constName(name);
+ const TType *constType = type;
+ name = nullptr;
+ type = nullptr;
+ return new TVariable(symbolTable, constName, constType,
+ constName.empty() ? SymbolType::Empty : SymbolType::UserDefined);
+ }
+
+ const char *name; // either pool allocated or static.
+ TType *type;
+};
+
+// The function sub-class of a symbol.
+class TFunction : public TSymbol
+{
+ public:
+ // User-defined function
+ TFunction(TSymbolTable *symbolTable,
+ const ImmutableString &name,
+ SymbolType symbolType,
+ const TType *retType,
+ bool knownToNotHaveSideEffects);
+
+ void addParameter(const TVariable *p);
+ void shareParameters(const TFunction &parametersSource);
+
+ ImmutableString getFunctionMangledName() const
+ {
+ ASSERT(symbolType() != SymbolType::BuiltIn);
+ if (mMangledName.empty())
+ {
+ mMangledName = buildMangledName();
+ }
+ return mMangledName;
+ }
+
+ const TType &getReturnType() const { return *returnType; }
+
+ TOperator getBuiltInOp() const { return mOp; }
+
+ void setDefined() { defined = true; }
+ bool isDefined() const { return defined; }
+ void setHasPrototypeDeclaration() { mHasPrototypeDeclaration = true; }
+ bool hasPrototypeDeclaration() const { return mHasPrototypeDeclaration; }
+ void setHasVoidParameter() { mHasVoidParameter = true; }
+ bool hasVoidParameter() const { return mHasVoidParameter; }
+
+ size_t getParamCount() const { return mParamCount; }
+ const TVariable *getParam(size_t i) const { return mParameters[i]; }
+
+ bool isKnownToNotHaveSideEffects() const { return mKnownToNotHaveSideEffects; }
+
+ bool isMain() const;
+ bool isImageFunction() const;
+ bool isAtomicCounterFunction() const;
+
+ // Note: Only to be used for static built-in functions!
+ constexpr TFunction(const TSymbolUniqueId &id,
+ const ImmutableString &name,
+ TExtension extension,
+ const TVariable *const *parameters,
+ size_t paramCount,
+ const TType *retType,
+ TOperator op,
+ bool knownToNotHaveSideEffects)
+ : TSymbol(id,
+ name,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{extension}},
+ SymbolClass::Function),
+ mParametersVector(nullptr),
+ mParameters(parameters),
+ returnType(retType),
+ mMangledName(nullptr),
+ mParamCount(paramCount),
+ mOp(op),
+ defined(false),
+ mHasPrototypeDeclaration(false),
+ mKnownToNotHaveSideEffects(knownToNotHaveSideEffects),
+ mHasVoidParameter(false)
+ {}
+
+ template <size_t ExtensionCount>
+ constexpr TFunction(const TSymbolUniqueId &id,
+ const ImmutableString &name,
+ const std::array<TExtension, ExtensionCount> &extensions,
+ const TVariable *const *parameters,
+ size_t paramCount,
+ const TType *retType,
+ TOperator op,
+ bool knownToNotHaveSideEffects)
+ : TSymbol(id, name, SymbolType::BuiltIn, extensions, SymbolClass::Function),
+ mParametersVector(nullptr),
+ mParameters(parameters),
+ returnType(retType),
+ mMangledName(nullptr),
+ mParamCount(paramCount),
+ mOp(op),
+ defined(false),
+ mHasPrototypeDeclaration(false),
+ mKnownToNotHaveSideEffects(knownToNotHaveSideEffects),
+ mHasVoidParameter(false)
+ {}
+
+ private:
+ ImmutableString buildMangledName() const;
+
+ typedef TVector<const TVariable *> TParamVector;
+ TParamVector *mParametersVector;
+ const TVariable *const *mParameters;
+ const TType *const returnType;
+ mutable ImmutableString mMangledName;
+ size_t mParamCount : 32;
+ const TOperator mOp; // Only set for built-ins
+ bool defined : 1;
+ bool mHasPrototypeDeclaration : 1;
+ bool mKnownToNotHaveSideEffects : 1;
+ // Whether the parameter list of the function starts with void. This is used to generate an
+ // error if any other parameter follows.
+ bool mHasVoidParameter : 1;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_SYMBOL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/SymbolTable.cpp b/gfx/angle/checkout/src/compiler/translator/SymbolTable.cpp
new file mode 100644
index 0000000000..8424f474f7
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/SymbolTable.cpp
@@ -0,0 +1,559 @@
+//
+// Copyright 2002 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.
+//
+// Symbol table for parsing. The design principles and most of the functionality are documented in
+// the header file.
+//
+
+#if defined(_MSC_VER)
+# pragma warning(disable : 4718)
+#endif
+
+#include "compiler/translator/SymbolTable.h"
+
+#include "angle_gl.h"
+#include "compiler/translator/ImmutableString.h"
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/StaticType.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+namespace
+{
+bool CheckShaderType(Shader expected, GLenum actual)
+{
+ switch (expected)
+ {
+ case Shader::ALL:
+ return true;
+ case Shader::FRAGMENT:
+ return actual == GL_FRAGMENT_SHADER;
+ case Shader::VERTEX:
+ return actual == GL_VERTEX_SHADER;
+ case Shader::COMPUTE:
+ return actual == GL_COMPUTE_SHADER;
+ case Shader::GEOMETRY:
+ return actual == GL_GEOMETRY_SHADER;
+ case Shader::GEOMETRY_EXT:
+ return actual == GL_GEOMETRY_SHADER_EXT;
+ case Shader::TESS_CONTROL_EXT:
+ return actual == GL_TESS_CONTROL_SHADER_EXT;
+ case Shader::TESS_EVALUATION_EXT:
+ return actual == GL_TESS_EVALUATION_SHADER_EXT;
+ case Shader::NOT_COMPUTE:
+ return actual != GL_COMPUTE_SHADER;
+ default:
+ UNREACHABLE();
+ return false;
+ }
+}
+
+bool CheckExtension(uint32_t extensionIndex, const ShBuiltInResources &resources)
+{
+ const int *resourcePtr = reinterpret_cast<const int *>(&resources);
+ return resourcePtr[extensionIndex] > 0;
+}
+} // namespace
+
+class TSymbolTable::TSymbolTableLevel
+{
+ public:
+ TSymbolTableLevel() = default;
+
+ bool insert(TSymbol *symbol);
+
+ // Insert a function using its unmangled name as the key.
+ void insertUnmangled(TFunction *function);
+
+ TSymbol *find(const ImmutableString &name) const;
+
+ private:
+ using tLevel = TUnorderedMap<ImmutableString,
+ TSymbol *,
+ ImmutableString::FowlerNollVoHash<sizeof(size_t)>>;
+ using tLevelPair = const tLevel::value_type;
+ using tInsertResult = std::pair<tLevel::iterator, bool>;
+
+ tLevel level;
+};
+
+bool TSymbolTable::TSymbolTableLevel::insert(TSymbol *symbol)
+{
+ // returning true means symbol was added to the table
+ tInsertResult result = level.insert(tLevelPair(symbol->getMangledName(), symbol));
+ return result.second;
+}
+
+void TSymbolTable::TSymbolTableLevel::insertUnmangled(TFunction *function)
+{
+ level.insert(tLevelPair(function->name(), function));
+}
+
+TSymbol *TSymbolTable::TSymbolTableLevel::find(const ImmutableString &name) const
+{
+ tLevel::const_iterator it = level.find(name);
+ if (it == level.end())
+ return nullptr;
+ else
+ return (*it).second;
+}
+
+TSymbolTable::TSymbolTable()
+ : mGlobalInvariant(false),
+ mUniqueIdCounter(0),
+ mShaderType(GL_FRAGMENT_SHADER),
+ mShaderSpec(SH_GLES2_SPEC),
+ mGlInVariableWithArraySize(nullptr)
+{}
+
+TSymbolTable::~TSymbolTable() = default;
+
+bool TSymbolTable::isEmpty() const
+{
+ return mTable.empty();
+}
+
+bool TSymbolTable::atGlobalLevel() const
+{
+ return mTable.size() == 1u;
+}
+
+void TSymbolTable::push()
+{
+ mTable.emplace_back(new TSymbolTableLevel);
+ mPrecisionStack.emplace_back(new PrecisionStackLevel);
+}
+
+void TSymbolTable::pop()
+{
+ mTable.pop_back();
+ mPrecisionStack.pop_back();
+}
+
+const TFunction *TSymbolTable::markFunctionHasPrototypeDeclaration(
+ const ImmutableString &mangledName,
+ bool *hadPrototypeDeclarationOut) const
+{
+ TFunction *function = findUserDefinedFunction(mangledName);
+ *hadPrototypeDeclarationOut = function->hasPrototypeDeclaration();
+ function->setHasPrototypeDeclaration();
+ return function;
+}
+
+const TFunction *TSymbolTable::setFunctionParameterNamesFromDefinition(const TFunction *function,
+ bool *wasDefinedOut) const
+{
+ TFunction *firstDeclaration = findUserDefinedFunction(function->getMangledName());
+ ASSERT(firstDeclaration);
+ // Note: 'firstDeclaration' could be 'function' if this is the first time we've seen function as
+ // it would have just been put in the symbol table. Otherwise, we're looking up an earlier
+ // occurance.
+ if (function != firstDeclaration)
+ {
+ // The previous declaration should have the same parameters as the function definition
+ // (parameter names may differ).
+ firstDeclaration->shareParameters(*function);
+ }
+
+ *wasDefinedOut = firstDeclaration->isDefined();
+ firstDeclaration->setDefined();
+ return firstDeclaration;
+}
+
+bool TSymbolTable::setGlInArraySize(unsigned int inputArraySize)
+{
+ if (mGlInVariableWithArraySize)
+ {
+ return mGlInVariableWithArraySize->getType().getOutermostArraySize() == inputArraySize;
+ }
+ const TInterfaceBlock *glPerVertex = static_cast<const TInterfaceBlock *>(m_gl_PerVertex);
+ TType *glInType = new TType(glPerVertex, EvqPerVertexIn, TLayoutQualifier::Create());
+ glInType->makeArray(inputArraySize);
+ mGlInVariableWithArraySize =
+ new TVariable(this, ImmutableString("gl_in"), glInType, SymbolType::BuiltIn,
+ TExtension::EXT_geometry_shader);
+ return true;
+}
+
+TVariable *TSymbolTable::getGlInVariableWithArraySize() const
+{
+ return mGlInVariableWithArraySize;
+}
+
+const TVariable *TSymbolTable::gl_FragData() const
+{
+ return static_cast<const TVariable *>(m_gl_FragData);
+}
+
+const TVariable *TSymbolTable::gl_SecondaryFragDataEXT() const
+{
+ return static_cast<const TVariable *>(m_gl_SecondaryFragDataEXT);
+}
+
+TSymbolTable::VariableMetadata *TSymbolTable::getOrCreateVariableMetadata(const TVariable &variable)
+{
+ int id = variable.uniqueId().get();
+ auto iter = mVariableMetadata.find(id);
+ if (iter == mVariableMetadata.end())
+ {
+ iter = mVariableMetadata.insert(std::make_pair(id, VariableMetadata())).first;
+ }
+ return &iter->second;
+}
+
+void TSymbolTable::markStaticWrite(const TVariable &variable)
+{
+ auto metadata = getOrCreateVariableMetadata(variable);
+ metadata->staticWrite = true;
+}
+
+void TSymbolTable::markStaticRead(const TVariable &variable)
+{
+ auto metadata = getOrCreateVariableMetadata(variable);
+ metadata->staticRead = true;
+}
+
+bool TSymbolTable::isStaticallyUsed(const TVariable &variable) const
+{
+ ASSERT(!variable.getConstPointer());
+ int id = variable.uniqueId().get();
+ auto iter = mVariableMetadata.find(id);
+ return iter != mVariableMetadata.end() && (iter->second.staticRead || iter->second.staticWrite);
+}
+
+void TSymbolTable::addInvariantVarying(const TVariable &variable)
+{
+ ASSERT(atGlobalLevel());
+ auto metadata = getOrCreateVariableMetadata(variable);
+ metadata->invariant = true;
+}
+
+bool TSymbolTable::isVaryingInvariant(const TVariable &variable) const
+{
+ ASSERT(atGlobalLevel());
+ if (mGlobalInvariant && (IsShaderOutput(variable.getType().getQualifier())))
+ {
+ return true;
+ }
+ int id = variable.uniqueId().get();
+ auto iter = mVariableMetadata.find(id);
+ return iter != mVariableMetadata.end() && iter->second.invariant;
+}
+
+void TSymbolTable::setGlobalInvariant(bool invariant)
+{
+ ASSERT(atGlobalLevel());
+ mGlobalInvariant = invariant;
+}
+
+const TSymbol *TSymbolTable::find(const ImmutableString &name, int shaderVersion) const
+{
+ const TSymbol *userSymbol = findUserDefined(name);
+ if (userSymbol)
+ {
+ return userSymbol;
+ }
+
+ return findBuiltIn(name, shaderVersion);
+}
+
+const TSymbol *TSymbolTable::findUserDefined(const ImmutableString &name) const
+{
+ int userDefinedLevel = static_cast<int>(mTable.size()) - 1;
+ while (userDefinedLevel >= 0)
+ {
+ const TSymbol *symbol = mTable[userDefinedLevel]->find(name);
+ if (symbol)
+ {
+ return symbol;
+ }
+ userDefinedLevel--;
+ }
+
+ return nullptr;
+}
+
+TFunction *TSymbolTable::findUserDefinedFunction(const ImmutableString &name) const
+{
+ // User-defined functions are always declared at the global level.
+ ASSERT(!mTable.empty());
+ return static_cast<TFunction *>(mTable[0]->find(name));
+}
+
+const TSymbol *TSymbolTable::findGlobal(const ImmutableString &name) const
+{
+ ASSERT(!mTable.empty());
+ return mTable[0]->find(name);
+}
+
+const TSymbol *TSymbolTable::findGlobalWithConversion(
+ const std::vector<ImmutableString> &names) const
+{
+ for (const ImmutableString &name : names)
+ {
+ const TSymbol *target = findGlobal(name);
+ if (target != nullptr)
+ return target;
+ }
+ return nullptr;
+}
+
+const TSymbol *TSymbolTable::findBuiltInWithConversion(const std::vector<ImmutableString> &names,
+ int shaderVersion) const
+{
+ for (const ImmutableString &name : names)
+ {
+ const TSymbol *target = findBuiltIn(name, shaderVersion);
+ if (target != nullptr)
+ return target;
+ }
+ return nullptr;
+}
+
+bool TSymbolTable::declare(TSymbol *symbol)
+{
+ ASSERT(!mTable.empty());
+ // The following built-ins may be redeclared by the shader: gl_ClipDistance, gl_CullDistance and
+ // gl_LastFragData.
+ ASSERT(symbol->symbolType() == SymbolType::UserDefined ||
+ (symbol->symbolType() == SymbolType::BuiltIn && IsRedeclarableBuiltIn(symbol->name())));
+ ASSERT(!symbol->isFunction());
+ return mTable.back()->insert(symbol);
+}
+
+bool TSymbolTable::declareInternal(TSymbol *symbol)
+{
+ ASSERT(!mTable.empty());
+ ASSERT(symbol->symbolType() == SymbolType::AngleInternal);
+ ASSERT(!symbol->isFunction());
+ return mTable.back()->insert(symbol);
+}
+
+void TSymbolTable::declareUserDefinedFunction(TFunction *function, bool insertUnmangledName)
+{
+ ASSERT(!mTable.empty());
+ if (insertUnmangledName)
+ {
+ // Insert the unmangled name to detect potential future redefinition as a variable.
+ mTable[0]->insertUnmangled(function);
+ }
+ mTable[0]->insert(function);
+}
+
+void TSymbolTable::setDefaultPrecision(TBasicType type, TPrecision prec)
+{
+ int indexOfLastElement = static_cast<int>(mPrecisionStack.size()) - 1;
+ // Uses map operator [], overwrites the current value
+ (*mPrecisionStack[indexOfLastElement])[type] = prec;
+}
+
+TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const
+{
+ if (!SupportsPrecision(type))
+ return EbpUndefined;
+
+ // unsigned integers use the same precision as signed
+ TBasicType baseType = (type == EbtUInt) ? EbtInt : type;
+
+ int level = static_cast<int>(mPrecisionStack.size()) - 1;
+ ASSERT(level >= 0); // Just to be safe. Should not happen.
+ // If we dont find anything we return this. Some types don't have predefined default precision.
+ TPrecision prec = EbpUndefined;
+ while (level >= 0)
+ {
+ PrecisionStackLevel::iterator it = mPrecisionStack[level]->find(baseType);
+ if (it != mPrecisionStack[level]->end())
+ {
+ prec = (*it).second;
+ break;
+ }
+ level--;
+ }
+ return prec;
+}
+
+void TSymbolTable::clearCompilationResults()
+{
+ mGlobalInvariant = false;
+ mUniqueIdCounter = kLastBuiltInId + 1;
+ mVariableMetadata.clear();
+ mGlInVariableWithArraySize = nullptr;
+
+ // User-defined scopes should have already been cleared when the compilation finished.
+ ASSERT(mTable.empty());
+}
+
+int TSymbolTable::nextUniqueIdValue()
+{
+ ASSERT(mUniqueIdCounter < std::numeric_limits<int>::max());
+ return ++mUniqueIdCounter;
+}
+
+void TSymbolTable::initializeBuiltIns(sh::GLenum type,
+ ShShaderSpec spec,
+ const ShBuiltInResources &resources)
+{
+ mShaderType = type;
+ mShaderSpec = spec;
+ mResources = resources;
+
+ // We need just one precision stack level for predefined precisions.
+ mPrecisionStack.emplace_back(new PrecisionStackLevel);
+
+ if (IsDesktopGLSpec(spec))
+ {
+ setDefaultPrecision(EbtInt, EbpUndefined);
+ setDefaultPrecision(EbtFloat, EbpUndefined);
+ }
+ else
+ {
+ switch (type)
+ {
+ case GL_FRAGMENT_SHADER:
+ setDefaultPrecision(EbtInt, EbpMedium);
+ break;
+ case GL_VERTEX_SHADER:
+ case GL_COMPUTE_SHADER:
+ case GL_GEOMETRY_SHADER_EXT:
+ case GL_TESS_CONTROL_SHADER_EXT:
+ case GL_TESS_EVALUATION_SHADER_EXT:
+ setDefaultPrecision(EbtInt, EbpHigh);
+ setDefaultPrecision(EbtFloat, EbpHigh);
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ // Set defaults for sampler types that have default precision, even those that are
+ // only available if an extension exists.
+ // New sampler types in ESSL3 don't have default precision. ESSL1 types do.
+ initSamplerDefaultPrecision(EbtSampler2D);
+ initSamplerDefaultPrecision(EbtSamplerCube);
+ // SamplerExternalOES is specified in the extension to have default precision.
+ initSamplerDefaultPrecision(EbtSamplerExternalOES);
+ // SamplerExternal2DY2YEXT is specified in the extension to have default precision.
+ initSamplerDefaultPrecision(EbtSamplerExternal2DY2YEXT);
+ // It isn't specified whether Sampler2DRect has default precision.
+ initSamplerDefaultPrecision(EbtSampler2DRect);
+
+ if (spec < SH_GLES3_SPEC)
+ {
+ // Only set the default precision of shadow samplers in ESLL1. They become core in ESSL3
+ // where they do not have a defalut precision.
+ initSamplerDefaultPrecision(EbtSampler2DShadow);
+ }
+
+ setDefaultPrecision(EbtAtomicCounter, EbpHigh);
+
+ initializeBuiltInVariables(type, spec, resources);
+ mUniqueIdCounter = kLastBuiltInId + 1;
+}
+
+void TSymbolTable::initSamplerDefaultPrecision(TBasicType samplerType)
+{
+ ASSERT(samplerType >= EbtGuardSamplerBegin && samplerType <= EbtGuardSamplerEnd);
+ setDefaultPrecision(samplerType, EbpLow);
+}
+
+TSymbolTable::VariableMetadata::VariableMetadata()
+ : staticRead(false), staticWrite(false), invariant(false)
+{}
+
+const TSymbol *SymbolRule::get(ShShaderSpec shaderSpec,
+ int shaderVersion,
+ sh::GLenum shaderType,
+ const ShBuiltInResources &resources,
+ const TSymbolTableBase &symbolTable) const
+{
+ if (IsDesktopGLSpec(shaderSpec) != (mIsDesktop == 1))
+ return nullptr;
+
+ if (mVersion == kESSL1Only && shaderVersion != static_cast<int>(kESSL1Only))
+ return nullptr;
+
+ if (mVersion > shaderVersion)
+ return nullptr;
+
+ if (!CheckShaderType(static_cast<Shader>(mShaders), shaderType))
+ return nullptr;
+
+ if (mExtensionIndex != 0 && !CheckExtension(mExtensionIndex, resources))
+ return nullptr;
+
+ return mIsVar > 0 ? symbolTable.*(mSymbolOrVar.var) : mSymbolOrVar.symbol;
+}
+
+const TSymbol *FindMangledBuiltIn(ShShaderSpec shaderSpec,
+ int shaderVersion,
+ sh::GLenum shaderType,
+ const ShBuiltInResources &resources,
+ const TSymbolTableBase &symbolTable,
+ const SymbolRule *rules,
+ uint16_t startIndex,
+ uint16_t endIndex)
+{
+ for (uint32_t ruleIndex = startIndex; ruleIndex < endIndex; ++ruleIndex)
+ {
+ const TSymbol *symbol =
+ rules[ruleIndex].get(shaderSpec, shaderVersion, shaderType, resources, symbolTable);
+ if (symbol)
+ {
+ return symbol;
+ }
+ }
+
+ return nullptr;
+}
+
+bool UnmangledEntry::matches(const ImmutableString &name,
+ ShShaderSpec shaderSpec,
+ int shaderVersion,
+ sh::GLenum shaderType,
+ const TExtensionBehavior &extensions) const
+{
+ if (name != mName)
+ return false;
+
+ if (!CheckShaderType(static_cast<Shader>(mShaderType), shaderType))
+ return false;
+
+ if (IsDesktopGLSpec(shaderSpec))
+ {
+ if (mGLSLVersion > shaderVersion)
+ return false;
+
+ if (mGLSLExtension == TExtension::UNDEFINED)
+ return true;
+
+ return IsExtensionEnabled(extensions, mGLSLExtension);
+ }
+ else
+ {
+ if (mESSLVersion == kESSL1Only && shaderVersion != static_cast<int>(kESSL1Only))
+ return false;
+
+ if (mESSLVersion > shaderVersion)
+ return false;
+
+ bool anyExtension = false;
+ bool anyExtensionEnabled = false;
+ for (TExtension ext : mESSLExtensions)
+ {
+ if (ext != TExtension::UNDEFINED)
+ {
+ anyExtension = true;
+ anyExtensionEnabled = anyExtensionEnabled || IsExtensionEnabled(extensions, ext);
+ }
+ }
+
+ if (!anyExtension)
+ return true;
+
+ return anyExtensionEnabled;
+ }
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/SymbolTable.h b/gfx/angle/checkout/src/compiler/translator/SymbolTable.h
new file mode 100644
index 0000000000..fb05729981
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/SymbolTable.h
@@ -0,0 +1,363 @@
+//
+// Copyright 2002 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_SYMBOLTABLE_H_
+#define COMPILER_TRANSLATOR_SYMBOLTABLE_H_
+
+//
+// Symbol table for parsing. Has these design characteristics:
+//
+// * Same symbol table can be used to compile many shaders, to preserve
+// effort of creating and loading with the large numbers of built-in
+// symbols.
+//
+// * Name mangling will be used to give each function a unique name
+// so that symbol table lookups are never ambiguous. This allows
+// a simpler symbol table structure.
+//
+// * Pushing and popping of scope, so symbol table will really be a stack
+// of symbol tables. Searched from the top, with new inserts going into
+// the top.
+//
+// * Constants: Compile time constant symbols will keep their values
+// in the symbol table. The parser can substitute constants at parse
+// time, including doing constant folding and constant propagation.
+//
+// * No temporaries: Temporaries made from operations (+, --, .xy, etc.)
+// are tracked in the intermediate representation, not the symbol table.
+//
+
+#include <limits>
+#include <memory>
+#include <set>
+
+#include "common/angleutils.h"
+#include "compiler/translator/ExtensionBehavior.h"
+#include "compiler/translator/ImmutableString.h"
+#include "compiler/translator/InfoSink.h"
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/Symbol.h"
+#include "compiler/translator/SymbolTable_autogen.h"
+
+enum class Shader : uint8_t
+{
+ ALL,
+ FRAGMENT, // GL_FRAGMENT_SHADER
+ VERTEX, // GL_VERTEX_SHADER
+ COMPUTE, // GL_COMPUTE_SHADER
+ GEOMETRY, // GL_GEOMETRY_SHADER
+ GEOMETRY_EXT, // GL_GEOMETRY_SHADER_EXT
+ TESS_CONTROL_EXT, // GL_TESS_CONTROL_SHADER_EXT
+ TESS_EVALUATION_EXT, // GL_TESS_EVALUATION_SHADER_EXT
+ NOT_COMPUTE
+};
+
+namespace sh
+{
+
+struct UnmangledBuiltIn
+{
+ constexpr UnmangledBuiltIn(TExtension extension) : extension(extension) {}
+
+ TExtension extension;
+};
+
+using VarPointer = TSymbol *(TSymbolTableBase::*);
+using ValidateExtension = int ShBuiltInResources::*;
+
+enum class Spec : uint8_t
+{
+ GLSL,
+ ESSL
+};
+
+constexpr uint16_t kESSL1Only = 100;
+// Some built-ins from backend shader languages are made available internally to ESSL for use in
+// tree transformations. This (invalid) shader version is used to select those built-ins. This
+// value needs to be larger than all other shader versions.
+constexpr uint16_t kESSLInternalBackendBuiltIns = 0x3FFF;
+
+// The version assigned to |kESSLInternalBackendBuiltIns| should be good until OpenGL 20.0!
+static_assert(kESSLInternalBackendBuiltIns > 2000,
+ "Accidentally exposing internal backend built-ins in OpenGL");
+
+static_assert(offsetof(ShBuiltInResources, OES_standard_derivatives) != 0,
+ "Update SymbolTable extension logic");
+
+#define EXT_INDEX(Ext) (offsetof(ShBuiltInResources, Ext) / sizeof(int))
+
+class SymbolRule
+{
+ public:
+ const TSymbol *get(ShShaderSpec shaderSpec,
+ int shaderVersion,
+ sh::GLenum shaderType,
+ const ShBuiltInResources &resources,
+ const TSymbolTableBase &symbolTable) const;
+
+ template <Spec spec, int version, Shader shaders, size_t extensionIndex, typename T>
+ constexpr static SymbolRule Get(T value);
+
+ private:
+ constexpr SymbolRule(Spec spec,
+ int version,
+ Shader shaders,
+ size_t extensionIndex,
+ const TSymbol *symbol);
+
+ constexpr SymbolRule(Spec spec,
+ int version,
+ Shader shaders,
+ size_t extensionIndex,
+ VarPointer resourceVar);
+
+ union SymbolOrVar
+ {
+ constexpr SymbolOrVar(const TSymbol *symbolIn) : symbol(symbolIn) {}
+ constexpr SymbolOrVar(VarPointer varIn) : var(varIn) {}
+
+ const TSymbol *symbol;
+ VarPointer var;
+ };
+
+ uint16_t mIsDesktop : 1;
+ uint16_t mIsVar : 1;
+ uint16_t mVersion : 14;
+ uint8_t mShaders;
+ uint8_t mExtensionIndex;
+ SymbolOrVar mSymbolOrVar;
+};
+
+constexpr SymbolRule::SymbolRule(Spec spec,
+ int version,
+ Shader shaders,
+ size_t extensionIndex,
+ const TSymbol *symbol)
+ : mIsDesktop(spec == Spec::GLSL ? 1u : 0u),
+ mIsVar(0u),
+ mVersion(static_cast<uint16_t>(version)),
+ mShaders(static_cast<uint8_t>(shaders)),
+ mExtensionIndex(extensionIndex),
+ mSymbolOrVar(symbol)
+{}
+
+constexpr SymbolRule::SymbolRule(Spec spec,
+ int version,
+ Shader shaders,
+ size_t extensionIndex,
+ VarPointer resourceVar)
+ : mIsDesktop(spec == Spec::GLSL ? 1u : 0u),
+ mIsVar(1u),
+ mVersion(static_cast<uint16_t>(version)),
+ mShaders(static_cast<uint8_t>(shaders)),
+ mExtensionIndex(extensionIndex),
+ mSymbolOrVar(resourceVar)
+{}
+
+template <Spec spec, int version, Shader shaders, size_t extensionIndex, typename T>
+// static
+constexpr SymbolRule SymbolRule::Get(T value)
+{
+ static_assert(version < 0x4000u, "version OOR");
+ static_assert(static_cast<uint8_t>(shaders) < 0xFFu, "shaders OOR");
+ static_assert(static_cast<uint8_t>(extensionIndex) < 0xFF, "extensionIndex OOR");
+ return SymbolRule(spec, version, shaders, extensionIndex, value);
+}
+
+const TSymbol *FindMangledBuiltIn(ShShaderSpec shaderSpec,
+ int shaderVersion,
+ sh::GLenum shaderType,
+ const ShBuiltInResources &resources,
+ const TSymbolTableBase &symbolTable,
+ const SymbolRule *rules,
+ uint16_t startIndex,
+ uint16_t endIndex);
+
+class UnmangledEntry
+{
+ public:
+ template <size_t ESSLExtCount>
+ constexpr UnmangledEntry(const char *name,
+ const std::array<TExtension, ESSLExtCount> &esslExtensions,
+ TExtension glslExtension,
+ int esslVersion,
+ int glslVersion,
+ Shader shaderType);
+
+ bool matches(const ImmutableString &name,
+ ShShaderSpec shaderSpec,
+ int shaderVersion,
+ sh::GLenum shaderType,
+ const TExtensionBehavior &extensions) const;
+
+ private:
+ const char *mName;
+ std::array<TExtension, 2u> mESSLExtensions;
+ TExtension mGLSLExtension;
+ uint8_t mShaderType;
+ uint16_t mESSLVersion;
+ uint16_t mGLSLVersion;
+};
+
+template <size_t ESSLExtCount>
+constexpr UnmangledEntry::UnmangledEntry(const char *name,
+ const std::array<TExtension, ESSLExtCount> &esslExtensions,
+ TExtension glslExtension,
+ int esslVersion,
+ int glslVersion,
+ Shader shaderType)
+ : mName(name),
+ mESSLExtensions{(ESSLExtCount >= 1) ? esslExtensions[0] : TExtension::UNDEFINED,
+ (ESSLExtCount >= 2) ? esslExtensions[1] : TExtension::UNDEFINED},
+ mGLSLExtension(glslExtension),
+ mShaderType(static_cast<uint8_t>(shaderType)),
+ mESSLVersion(esslVersion < 0 ? std::numeric_limits<uint16_t>::max()
+ : static_cast<uint16_t>(esslVersion)),
+ mGLSLVersion(glslVersion < 0 ? std::numeric_limits<uint16_t>::max()
+ : static_cast<uint16_t>(glslVersion))
+{}
+
+class TSymbolTable : angle::NonCopyable, TSymbolTableBase
+{
+ public:
+ TSymbolTable();
+ // To start using the symbol table after construction:
+ // * initializeBuiltIns() needs to be called.
+ // * push() needs to be called to push the global level.
+
+ ~TSymbolTable();
+
+ bool isEmpty() const;
+ bool atGlobalLevel() const;
+
+ void push();
+ void pop();
+
+ // Declare a non-function symbol at the current scope. Return true in case the declaration was
+ // successful, and false if the declaration failed due to redefinition.
+ bool declare(TSymbol *symbol);
+
+ // Only used to declare internal variables.
+ bool declareInternal(TSymbol *symbol);
+
+ // Functions are always declared at global scope.
+ void declareUserDefinedFunction(TFunction *function, bool insertUnmangledName);
+
+ // These return the TFunction pointer to keep using to refer to this function.
+ const TFunction *markFunctionHasPrototypeDeclaration(const ImmutableString &mangledName,
+ bool *hadPrototypeDeclarationOut) const;
+ const TFunction *setFunctionParameterNamesFromDefinition(const TFunction *function,
+ bool *wasDefinedOut) const;
+
+ // Return false if the gl_in array size has already been initialized with a mismatching value.
+ bool setGlInArraySize(unsigned int inputArraySize);
+ TVariable *getGlInVariableWithArraySize() const;
+
+ const TVariable *gl_FragData() const;
+ const TVariable *gl_SecondaryFragDataEXT() const;
+
+ void markStaticRead(const TVariable &variable);
+ void markStaticWrite(const TVariable &variable);
+
+ // Note: Should not call this for constant variables.
+ bool isStaticallyUsed(const TVariable &variable) const;
+
+ // find() is guaranteed not to retain a reference to the ImmutableString, so an ImmutableString
+ // with a reference to a short-lived char * is fine to pass here.
+ const TSymbol *find(const ImmutableString &name, int shaderVersion) const;
+
+ const TSymbol *findUserDefined(const ImmutableString &name) const;
+
+ TFunction *findUserDefinedFunction(const ImmutableString &name) const;
+
+ const TSymbol *findGlobal(const ImmutableString &name) const;
+ const TSymbol *findGlobalWithConversion(const std::vector<ImmutableString> &names) const;
+
+ const TSymbol *findBuiltIn(const ImmutableString &name, int shaderVersion) const;
+ const TSymbol *findBuiltInWithConversion(const std::vector<ImmutableString> &names,
+ int shaderVersion) const;
+
+ void setDefaultPrecision(TBasicType type, TPrecision prec);
+
+ // Searches down the precisionStack for a precision qualifier
+ // for the specified TBasicType
+ TPrecision getDefaultPrecision(TBasicType type) const;
+
+ // This records invariant varyings declared through "invariant varying_name;".
+ void addInvariantVarying(const TVariable &variable);
+
+ // If this returns false, the varying could still be invariant if it is set as invariant during
+ // the varying variable declaration - this piece of information is stored in the variable's
+ // type, not here.
+ bool isVaryingInvariant(const TVariable &variable) const;
+
+ void setGlobalInvariant(bool invariant);
+
+ const TSymbolUniqueId nextUniqueId() { return TSymbolUniqueId(this); }
+
+ // Gets the built-in accessible by a shader with the specified version, if any.
+ bool isUnmangledBuiltInName(const ImmutableString &name,
+ int shaderVersion,
+ const TExtensionBehavior &extensions) const;
+
+ void initializeBuiltIns(sh::GLenum type,
+ ShShaderSpec spec,
+ const ShBuiltInResources &resources);
+ void clearCompilationResults();
+
+ ShShaderSpec getShaderSpec() const { return mShaderSpec; }
+
+ private:
+ friend class TSymbolUniqueId;
+
+ struct VariableMetadata
+ {
+ VariableMetadata();
+ bool staticRead;
+ bool staticWrite;
+ bool invariant;
+ };
+
+ int nextUniqueIdValue();
+
+ class TSymbolTableLevel;
+
+ void initSamplerDefaultPrecision(TBasicType samplerType);
+
+ void initializeBuiltInVariables(sh::GLenum shaderType,
+ ShShaderSpec spec,
+ const ShBuiltInResources &resources);
+
+ VariableMetadata *getOrCreateVariableMetadata(const TVariable &variable);
+
+ std::vector<std::unique_ptr<TSymbolTableLevel>> mTable;
+
+ // There's one precision stack level for predefined precisions and then one level for each scope
+ // in table.
+ typedef TMap<TBasicType, TPrecision> PrecisionStackLevel;
+ std::vector<std::unique_ptr<PrecisionStackLevel>> mPrecisionStack;
+
+ bool mGlobalInvariant;
+
+ int mUniqueIdCounter;
+
+ static const int kLastBuiltInId;
+
+ sh::GLenum mShaderType;
+ ShShaderSpec mShaderSpec;
+ ShBuiltInResources mResources;
+
+ // Indexed by unique id. Map instead of vector since the variables are fairly sparse.
+ std::map<int, VariableMetadata> mVariableMetadata;
+
+ // Store gl_in variable with its array size once the array size can be determined. The array
+ // size can also be checked against latter input primitive type declaration.
+ TVariable *mGlInVariableWithArraySize;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_SYMBOLTABLE_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/SymbolTable_ESSL_autogen.cpp b/gfx/angle/checkout/src/compiler/translator/SymbolTable_ESSL_autogen.cpp
new file mode 100644
index 0000000000..483e9b4748
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/SymbolTable_ESSL_autogen.cpp
@@ -0,0 +1,30071 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_builtin_symbols.py using data from builtin_variables.json and
+// builtin_function_declarations.txt.
+//
+// Copyright 2020 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.
+//
+// SymbolTable_ESSL_autogen.cpp:
+// Compile-time initialized built-ins.
+
+#include <cmath>
+
+#include "compiler/translator/SymbolTable.h"
+
+#include "angle_gl.h"
+#include "compiler/translator/ImmutableString.h"
+#include "compiler/translator/StaticType.h"
+#include "compiler/translator/Symbol.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/BuiltIn.h"
+
+namespace sh
+{
+using Resources = ShBuiltInResources;
+using TableBase = TSymbolTableBase;
+
+const int TSymbolTable::kLastBuiltInId = 5603;
+
+namespace BuiltInName
+{
+
+constexpr const ImmutableString _empty("");
+constexpr const ImmutableString EmitVertex("EmitVertex");
+constexpr const ImmutableString EmitVertexES3_2("EmitVertex");
+constexpr const ImmutableString EndPrimitive("EndPrimitive");
+constexpr const ImmutableString EndPrimitiveES3_2("EndPrimitive");
+constexpr const ImmutableString abs("abs");
+constexpr const ImmutableString acos("acos");
+constexpr const ImmutableString acosh("acosh");
+constexpr const ImmutableString all("all");
+constexpr const ImmutableString angle_BaseInstance("angle_BaseInstance");
+constexpr const ImmutableString angle_BaseVertex("angle_BaseVertex");
+constexpr const ImmutableString any("any");
+constexpr const ImmutableString asin("asin");
+constexpr const ImmutableString asinh("asinh");
+constexpr const ImmutableString atan("atan");
+constexpr const ImmutableString atanh("atanh");
+constexpr const ImmutableString atomicAdd("atomicAdd");
+constexpr const ImmutableString atomicAnd("atomicAnd");
+constexpr const ImmutableString atomicCompSwap("atomicCompSwap");
+constexpr const ImmutableString atomicCounter("atomicCounter");
+constexpr const ImmutableString atomicCounterDecrement("atomicCounterDecrement");
+constexpr const ImmutableString atomicCounterIncrement("atomicCounterIncrement");
+constexpr const ImmutableString atomicExchange("atomicExchange");
+constexpr const ImmutableString atomicMax("atomicMax");
+constexpr const ImmutableString atomicMin("atomicMin");
+constexpr const ImmutableString atomicOr("atomicOr");
+constexpr const ImmutableString atomicXor("atomicXor");
+constexpr const ImmutableString barrier("barrier");
+constexpr const ImmutableString barrierTCS("barrier");
+constexpr const ImmutableString barrierTCSES3_2("barrier");
+constexpr const ImmutableString beginFragmentShaderOrderingINTEL(
+ "beginFragmentShaderOrderingINTEL");
+constexpr const ImmutableString beginInvocationInterlockARB("beginInvocationInterlockARB");
+constexpr const ImmutableString beginInvocationInterlockNV("beginInvocationInterlockNV");
+constexpr const ImmutableString bitCount("bitCount");
+constexpr const ImmutableString bitfieldExtract("bitfieldExtract");
+constexpr const ImmutableString bitfieldInsert("bitfieldInsert");
+constexpr const ImmutableString bitfieldReverse("bitfieldReverse");
+constexpr const ImmutableString ceil("ceil");
+constexpr const ImmutableString clamp("clamp");
+constexpr const ImmutableString cos("cos");
+constexpr const ImmutableString cosh("cosh");
+constexpr const ImmutableString cross("cross");
+constexpr const ImmutableString dFdx("dFdx");
+constexpr const ImmutableString dFdxExt("dFdx");
+constexpr const ImmutableString dFdy("dFdy");
+constexpr const ImmutableString dFdyExt("dFdy");
+constexpr const ImmutableString degrees("degrees");
+constexpr const ImmutableString determinant("determinant");
+constexpr const ImmutableString diff("diff");
+constexpr const ImmutableString distance("distance");
+constexpr const ImmutableString dot("dot");
+constexpr const ImmutableString endInvocationInterlockARB("endInvocationInterlockARB");
+constexpr const ImmutableString endInvocationInterlockNV("endInvocationInterlockNV");
+constexpr const ImmutableString equal("equal");
+constexpr const ImmutableString exp("exp");
+constexpr const ImmutableString exp2("exp2");
+constexpr const ImmutableString faceforward("faceforward");
+constexpr const ImmutableString far("far");
+constexpr const ImmutableString findLSB("findLSB");
+constexpr const ImmutableString findMSB("findMSB");
+constexpr const ImmutableString floatBitsToInt("floatBitsToInt");
+constexpr const ImmutableString floatBitsToUint("floatBitsToUint");
+constexpr const ImmutableString floor("floor");
+constexpr const ImmutableString fma("fma");
+constexpr const ImmutableString fmaExt("fma");
+constexpr const ImmutableString fract("fract");
+constexpr const ImmutableString frexp("frexp");
+constexpr const ImmutableString fwidth("fwidth");
+constexpr const ImmutableString fwidthExt("fwidth");
+constexpr const ImmutableString gl_BaseInstance("gl_BaseInstance");
+constexpr const ImmutableString gl_BaseVertex("gl_BaseVertex");
+constexpr const ImmutableString gl_BoundingBox("gl_BoundingBox");
+constexpr const ImmutableString gl_BoundingBoxEXT("gl_BoundingBoxEXT");
+constexpr const ImmutableString gl_BoundingBoxOES("gl_BoundingBoxOES");
+constexpr const ImmutableString gl_ClipDistance("gl_ClipDistance");
+constexpr const ImmutableString gl_CullDistance("gl_CullDistance");
+constexpr const ImmutableString gl_DepthRange("gl_DepthRange");
+constexpr const ImmutableString gl_DepthRangeParameters("gl_DepthRangeParameters");
+constexpr const ImmutableString gl_DrawID("gl_DrawID");
+constexpr const ImmutableString gl_FragColor("gl_FragColor");
+constexpr const ImmutableString gl_FragCoord("gl_FragCoord");
+constexpr const ImmutableString gl_FragData("gl_FragData");
+constexpr const ImmutableString gl_FragDepth("gl_FragDepth");
+constexpr const ImmutableString gl_FragDepthEXT("gl_FragDepthEXT");
+constexpr const ImmutableString gl_FrontFacing("gl_FrontFacing");
+constexpr const ImmutableString gl_GlobalInvocationID("gl_GlobalInvocationID");
+constexpr const ImmutableString gl_HelperInvocation("gl_HelperInvocation");
+constexpr const ImmutableString gl_InstanceID("gl_InstanceID");
+constexpr const ImmutableString gl_InstanceIndex("gl_InstanceIndex");
+constexpr const ImmutableString gl_InvocationID("gl_InvocationID");
+constexpr const ImmutableString gl_LastFragColor("gl_LastFragColor");
+constexpr const ImmutableString gl_LastFragColorARM("gl_LastFragColorARM");
+constexpr const ImmutableString gl_LastFragData("gl_LastFragData");
+constexpr const ImmutableString gl_Layer("gl_Layer");
+constexpr const ImmutableString gl_LocalInvocationID("gl_LocalInvocationID");
+constexpr const ImmutableString gl_LocalInvocationIndex("gl_LocalInvocationIndex");
+constexpr const ImmutableString gl_MaxAtomicCounterBindings("gl_MaxAtomicCounterBindings");
+constexpr const ImmutableString gl_MaxAtomicCounterBufferSize("gl_MaxAtomicCounterBufferSize");
+constexpr const ImmutableString gl_MaxClipDistances("gl_MaxClipDistances");
+constexpr const ImmutableString gl_MaxCombinedAtomicCounterBuffers(
+ "gl_MaxCombinedAtomicCounterBuffers");
+constexpr const ImmutableString gl_MaxCombinedAtomicCounters("gl_MaxCombinedAtomicCounters");
+constexpr const ImmutableString gl_MaxCombinedClipAndCullDistances(
+ "gl_MaxCombinedClipAndCullDistances");
+constexpr const ImmutableString gl_MaxCombinedImageUniforms("gl_MaxCombinedImageUniforms");
+constexpr const ImmutableString gl_MaxCombinedShaderOutputResources(
+ "gl_MaxCombinedShaderOutputResources");
+constexpr const ImmutableString gl_MaxCombinedTextureImageUnits("gl_MaxCombinedTextureImageUnits");
+constexpr const ImmutableString gl_MaxComputeAtomicCounterBuffers(
+ "gl_MaxComputeAtomicCounterBuffers");
+constexpr const ImmutableString gl_MaxComputeAtomicCounters("gl_MaxComputeAtomicCounters");
+constexpr const ImmutableString gl_MaxComputeImageUniforms("gl_MaxComputeImageUniforms");
+constexpr const ImmutableString gl_MaxComputeTextureImageUnits("gl_MaxComputeTextureImageUnits");
+constexpr const ImmutableString gl_MaxComputeUniformComponents("gl_MaxComputeUniformComponents");
+constexpr const ImmutableString gl_MaxComputeWorkGroupCount("gl_MaxComputeWorkGroupCount");
+constexpr const ImmutableString gl_MaxComputeWorkGroupSize("gl_MaxComputeWorkGroupSize");
+constexpr const ImmutableString gl_MaxCullDistances("gl_MaxCullDistances");
+constexpr const ImmutableString gl_MaxDrawBuffers("gl_MaxDrawBuffers");
+constexpr const ImmutableString gl_MaxDualSourceDrawBuffersEXT("gl_MaxDualSourceDrawBuffersEXT");
+constexpr const ImmutableString gl_MaxFragmentAtomicCounterBuffers(
+ "gl_MaxFragmentAtomicCounterBuffers");
+constexpr const ImmutableString gl_MaxFragmentAtomicCounters("gl_MaxFragmentAtomicCounters");
+constexpr const ImmutableString gl_MaxFragmentImageUniforms("gl_MaxFragmentImageUniforms");
+constexpr const ImmutableString gl_MaxFragmentInputVectors("gl_MaxFragmentInputVectors");
+constexpr const ImmutableString gl_MaxFragmentUniformVectors("gl_MaxFragmentUniformVectors");
+constexpr const ImmutableString gl_MaxGeometryAtomicCounterBuffers(
+ "gl_MaxGeometryAtomicCounterBuffers");
+constexpr const ImmutableString gl_MaxGeometryAtomicCounters("gl_MaxGeometryAtomicCounters");
+constexpr const ImmutableString gl_MaxGeometryImageUniforms("gl_MaxGeometryImageUniforms");
+constexpr const ImmutableString gl_MaxGeometryInputComponents("gl_MaxGeometryInputComponents");
+constexpr const ImmutableString gl_MaxGeometryOutputComponents("gl_MaxGeometryOutputComponents");
+constexpr const ImmutableString gl_MaxGeometryOutputVertices("gl_MaxGeometryOutputVertices");
+constexpr const ImmutableString gl_MaxGeometryTextureImageUnits("gl_MaxGeometryTextureImageUnits");
+constexpr const ImmutableString gl_MaxGeometryTotalOutputComponents(
+ "gl_MaxGeometryTotalOutputComponents");
+constexpr const ImmutableString gl_MaxGeometryUniformComponents("gl_MaxGeometryUniformComponents");
+constexpr const ImmutableString gl_MaxImageUnits("gl_MaxImageUnits");
+constexpr const ImmutableString gl_MaxPatchVertices("gl_MaxPatchVertices");
+constexpr const ImmutableString gl_MaxProgramTexelOffset("gl_MaxProgramTexelOffset");
+constexpr const ImmutableString gl_MaxSamples("gl_MaxSamples");
+constexpr const ImmutableString gl_MaxTessControlAtomicCounterBuffers(
+ "gl_MaxTessControlAtomicCounterBuffers");
+constexpr const ImmutableString gl_MaxTessControlAtomicCounters("gl_MaxTessControlAtomicCounters");
+constexpr const ImmutableString gl_MaxTessControlImageUniforms("gl_MaxTessControlImageUniforms");
+constexpr const ImmutableString gl_MaxTessControlInputComponents(
+ "gl_MaxTessControlInputComponents");
+constexpr const ImmutableString gl_MaxTessControlOutputComponents(
+ "gl_MaxTessControlOutputComponents");
+constexpr const ImmutableString gl_MaxTessControlTextureImageUnits(
+ "gl_MaxTessControlTextureImageUnits");
+constexpr const ImmutableString gl_MaxTessControlTotalOutputComponents(
+ "gl_MaxTessControlTotalOutputComponents");
+constexpr const ImmutableString gl_MaxTessControlUniformComponents(
+ "gl_MaxTessControlUniformComponents");
+constexpr const ImmutableString gl_MaxTessEvaluationAtomicCounterBuffers(
+ "gl_MaxTessEvaluationAtomicCounterBuffers");
+constexpr const ImmutableString gl_MaxTessEvaluationAtomicCounters(
+ "gl_MaxTessEvaluationAtomicCounters");
+constexpr const ImmutableString gl_MaxTessEvaluationImageUniforms(
+ "gl_MaxTessEvaluationImageUniforms");
+constexpr const ImmutableString gl_MaxTessEvaluationInputComponents(
+ "gl_MaxTessEvaluationInputComponents");
+constexpr const ImmutableString gl_MaxTessEvaluationOutputComponents(
+ "gl_MaxTessEvaluationOutputComponents");
+constexpr const ImmutableString gl_MaxTessEvaluationTextureImageUnits(
+ "gl_MaxTessEvaluationTextureImageUnits");
+constexpr const ImmutableString gl_MaxTessEvaluationUniformComponents(
+ "gl_MaxTessEvaluationUniformComponents");
+constexpr const ImmutableString gl_MaxTessGenLevel("gl_MaxTessGenLevel");
+constexpr const ImmutableString gl_MaxTessPatchComponents("gl_MaxTessPatchComponents");
+constexpr const ImmutableString gl_MaxTextureImageUnits("gl_MaxTextureImageUnits");
+constexpr const ImmutableString gl_MaxVaryingVectors("gl_MaxVaryingVectors");
+constexpr const ImmutableString gl_MaxVertexAtomicCounterBuffers(
+ "gl_MaxVertexAtomicCounterBuffers");
+constexpr const ImmutableString gl_MaxVertexAtomicCounters("gl_MaxVertexAtomicCounters");
+constexpr const ImmutableString gl_MaxVertexAttribs("gl_MaxVertexAttribs");
+constexpr const ImmutableString gl_MaxVertexImageUniforms("gl_MaxVertexImageUniforms");
+constexpr const ImmutableString gl_MaxVertexOutputVectors("gl_MaxVertexOutputVectors");
+constexpr const ImmutableString gl_MaxVertexTextureImageUnits("gl_MaxVertexTextureImageUnits");
+constexpr const ImmutableString gl_MaxVertexUniformVectors("gl_MaxVertexUniformVectors");
+constexpr const ImmutableString gl_MinProgramTexelOffset("gl_MinProgramTexelOffset");
+constexpr const ImmutableString gl_NumSamples("gl_NumSamples");
+constexpr const ImmutableString gl_NumWorkGroups("gl_NumWorkGroups");
+constexpr const ImmutableString gl_PatchVerticesIn("gl_PatchVerticesIn");
+constexpr const ImmutableString gl_PerVertex("gl_PerVertex");
+constexpr const ImmutableString gl_PointCoord("gl_PointCoord");
+constexpr const ImmutableString gl_PointSize("gl_PointSize");
+constexpr const ImmutableString gl_Position("gl_Position");
+constexpr const ImmutableString gl_PrimitiveID("gl_PrimitiveID");
+constexpr const ImmutableString gl_PrimitiveIDIn("gl_PrimitiveIDIn");
+constexpr const ImmutableString gl_SampleID("gl_SampleID");
+constexpr const ImmutableString gl_SampleMask("gl_SampleMask");
+constexpr const ImmutableString gl_SampleMaskIn("gl_SampleMaskIn");
+constexpr const ImmutableString gl_SamplePosition("gl_SamplePosition");
+constexpr const ImmutableString gl_SecondaryFragColorEXT("gl_SecondaryFragColorEXT");
+constexpr const ImmutableString gl_SecondaryFragDataEXT("gl_SecondaryFragDataEXT");
+constexpr const ImmutableString gl_TessCoord("gl_TessCoord");
+constexpr const ImmutableString gl_TessLevelInner("gl_TessLevelInner");
+constexpr const ImmutableString gl_TessLevelOuter("gl_TessLevelOuter");
+constexpr const ImmutableString gl_VertexID("gl_VertexID");
+constexpr const ImmutableString gl_VertexIndex("gl_VertexIndex");
+constexpr const ImmutableString gl_ViewID_OVR("gl_ViewID_OVR");
+constexpr const ImmutableString gl_ViewportIndex("gl_ViewportIndex");
+constexpr const ImmutableString gl_WorkGroupID("gl_WorkGroupID");
+constexpr const ImmutableString gl_WorkGroupSize("gl_WorkGroupSize");
+constexpr const ImmutableString gl_in("gl_in");
+constexpr const ImmutableString gl_out("gl_out");
+constexpr const ImmutableString greaterThan("greaterThan");
+constexpr const ImmutableString greaterThanEqual("greaterThanEqual");
+constexpr const ImmutableString groupMemoryBarrier("groupMemoryBarrier");
+constexpr const ImmutableString imageAtomicAdd("imageAtomicAdd");
+constexpr const ImmutableString imageAtomicAddExt("imageAtomicAdd");
+constexpr const ImmutableString imageAtomicAnd("imageAtomicAnd");
+constexpr const ImmutableString imageAtomicAndExt("imageAtomicAnd");
+constexpr const ImmutableString imageAtomicCompSwap("imageAtomicCompSwap");
+constexpr const ImmutableString imageAtomicCompSwapExt("imageAtomicCompSwap");
+constexpr const ImmutableString imageAtomicExchange("imageAtomicExchange");
+constexpr const ImmutableString imageAtomicExchangeExt("imageAtomicExchange");
+constexpr const ImmutableString imageAtomicMax("imageAtomicMax");
+constexpr const ImmutableString imageAtomicMaxExt("imageAtomicMax");
+constexpr const ImmutableString imageAtomicMin("imageAtomicMin");
+constexpr const ImmutableString imageAtomicMinExt("imageAtomicMin");
+constexpr const ImmutableString imageAtomicOr("imageAtomicOr");
+constexpr const ImmutableString imageAtomicOrExt("imageAtomicOr");
+constexpr const ImmutableString imageAtomicXor("imageAtomicXor");
+constexpr const ImmutableString imageAtomicXorExt("imageAtomicXor");
+constexpr const ImmutableString imageLoad("imageLoad");
+constexpr const ImmutableString imageLoadExt("imageLoad");
+constexpr const ImmutableString imageSize("imageSize");
+constexpr const ImmutableString imageSizeExt("imageSize");
+constexpr const ImmutableString imageStore("imageStore");
+constexpr const ImmutableString imageStoreExt("imageStore");
+constexpr const ImmutableString imulExtended("imulExtended");
+constexpr const ImmutableString intBitsToFloat("intBitsToFloat");
+constexpr const ImmutableString interpolateAtCentroid("interpolateAtCentroid");
+constexpr const ImmutableString interpolateAtCentroidExt("interpolateAtCentroid");
+constexpr const ImmutableString interpolateAtOffset("interpolateAtOffset");
+constexpr const ImmutableString interpolateAtOffsetExt("interpolateAtOffset");
+constexpr const ImmutableString interpolateAtSample("interpolateAtSample");
+constexpr const ImmutableString interpolateAtSampleExt("interpolateAtSample");
+constexpr const ImmutableString inverse("inverse");
+constexpr const ImmutableString inversesqrt("inversesqrt");
+constexpr const ImmutableString isinf("isinf");
+constexpr const ImmutableString isnan("isnan");
+constexpr const ImmutableString ldexp("ldexp");
+constexpr const ImmutableString length("length");
+constexpr const ImmutableString lessThan("lessThan");
+constexpr const ImmutableString lessThanEqual("lessThanEqual");
+constexpr const ImmutableString log("log");
+constexpr const ImmutableString log2("log2");
+constexpr const ImmutableString matrixCompMult("matrixCompMult");
+constexpr const ImmutableString max("max");
+constexpr const ImmutableString memoryBarrier("memoryBarrier");
+constexpr const ImmutableString memoryBarrierAtomicCounter("memoryBarrierAtomicCounter");
+constexpr const ImmutableString memoryBarrierBuffer("memoryBarrierBuffer");
+constexpr const ImmutableString memoryBarrierImage("memoryBarrierImage");
+constexpr const ImmutableString memoryBarrierShared("memoryBarrierShared");
+constexpr const ImmutableString min("min");
+constexpr const ImmutableString mix("mix");
+constexpr const ImmutableString mod("mod");
+constexpr const ImmutableString modf("modf");
+constexpr const ImmutableString near("near");
+constexpr const ImmutableString normalize("normalize");
+constexpr const ImmutableString notEqual("notEqual");
+constexpr const ImmutableString notFunc("not");
+constexpr const ImmutableString outerProduct("outerProduct");
+constexpr const ImmutableString packHalf2x16("packHalf2x16");
+constexpr const ImmutableString packSnorm2x16("packSnorm2x16");
+constexpr const ImmutableString packSnorm4x8("packSnorm4x8");
+constexpr const ImmutableString packUnorm2x16("packUnorm2x16");
+constexpr const ImmutableString packUnorm4x8("packUnorm4x8");
+constexpr const ImmutableString pixelLocalLoadANGLE("pixelLocalLoadANGLE");
+constexpr const ImmutableString pixelLocalStoreANGLE("pixelLocalStoreANGLE");
+constexpr const ImmutableString pow("pow");
+constexpr const ImmutableString radians("radians");
+constexpr const ImmutableString reflect("reflect");
+constexpr const ImmutableString refract("refract");
+constexpr const ImmutableString rgb_2_yuv("rgb_2_yuv");
+constexpr const ImmutableString round("round");
+constexpr const ImmutableString roundEven("roundEven");
+constexpr const ImmutableString shadow2DEXT("shadow2DEXT");
+constexpr const ImmutableString shadow2DProjEXT("shadow2DProjEXT");
+constexpr const ImmutableString sign("sign");
+constexpr const ImmutableString sin("sin");
+constexpr const ImmutableString sinh("sinh");
+constexpr const ImmutableString smoothstep("smoothstep");
+constexpr const ImmutableString sqrt("sqrt");
+constexpr const ImmutableString step("step");
+constexpr const ImmutableString subpassLoad("subpassLoad");
+constexpr const ImmutableString tan("tan");
+constexpr const ImmutableString tanh("tanh");
+constexpr const ImmutableString texelFetch("texelFetch");
+constexpr const ImmutableString texelFetchExt("texelFetch");
+constexpr const ImmutableString texelFetchOffset("texelFetchOffset");
+constexpr const ImmutableString texture("texture");
+constexpr const ImmutableString texture2D("texture2D");
+constexpr const ImmutableString texture2DGradEXT("texture2DGradEXT");
+constexpr const ImmutableString texture2DLod("texture2DLod");
+constexpr const ImmutableString texture2DLodEXT("texture2DLodEXT");
+constexpr const ImmutableString texture2DProj("texture2DProj");
+constexpr const ImmutableString texture2DProjGradEXT("texture2DProjGradEXT");
+constexpr const ImmutableString texture2DProjLod("texture2DProjLod");
+constexpr const ImmutableString texture2DProjLodEXT("texture2DProjLodEXT");
+constexpr const ImmutableString texture2DRect("texture2DRect");
+constexpr const ImmutableString texture2DRectProj("texture2DRectProj");
+constexpr const ImmutableString texture3D("texture3D");
+constexpr const ImmutableString texture3DLod("texture3DLod");
+constexpr const ImmutableString texture3DProj("texture3DProj");
+constexpr const ImmutableString texture3DProjLod("texture3DProjLod");
+constexpr const ImmutableString textureCube("textureCube");
+constexpr const ImmutableString textureCubeGradEXT("textureCubeGradEXT");
+constexpr const ImmutableString textureCubeLod("textureCubeLod");
+constexpr const ImmutableString textureCubeLodEXT("textureCubeLodEXT");
+constexpr const ImmutableString textureExt("texture");
+constexpr const ImmutableString textureGather("textureGather");
+constexpr const ImmutableString textureGatherExt("textureGather");
+constexpr const ImmutableString textureGatherOffset("textureGatherOffset");
+constexpr const ImmutableString textureGatherOffsets("textureGatherOffsets");
+constexpr const ImmutableString textureGatherOffsetsExt("textureGatherOffsets");
+constexpr const ImmutableString textureGrad("textureGrad");
+constexpr const ImmutableString textureGradExt("textureGrad");
+constexpr const ImmutableString textureGradOffset("textureGradOffset");
+constexpr const ImmutableString textureLod("textureLod");
+constexpr const ImmutableString textureLodExt("textureLod");
+constexpr const ImmutableString textureLodOffset("textureLodOffset");
+constexpr const ImmutableString textureOffset("textureOffset");
+constexpr const ImmutableString textureProj("textureProj");
+constexpr const ImmutableString textureProjGrad("textureProjGrad");
+constexpr const ImmutableString textureProjGradOffset("textureProjGradOffset");
+constexpr const ImmutableString textureProjLod("textureProjLod");
+constexpr const ImmutableString textureProjLodOffset("textureProjLodOffset");
+constexpr const ImmutableString textureProjOffset("textureProjOffset");
+constexpr const ImmutableString textureSize("textureSize");
+constexpr const ImmutableString textureSizeExt("textureSize");
+constexpr const ImmutableString textureVideoWEBGL("textureVideoWEBGL");
+constexpr const ImmutableString transpose("transpose");
+constexpr const ImmutableString trunc("trunc");
+constexpr const ImmutableString uaddCarry("uaddCarry");
+constexpr const ImmutableString uintBitsToFloat("uintBitsToFloat");
+constexpr const ImmutableString umulExtended("umulExtended");
+constexpr const ImmutableString unpackHalf2x16("unpackHalf2x16");
+constexpr const ImmutableString unpackSnorm2x16("unpackSnorm2x16");
+constexpr const ImmutableString unpackSnorm4x8("unpackSnorm4x8");
+constexpr const ImmutableString unpackUnorm2x16("unpackUnorm2x16");
+constexpr const ImmutableString unpackUnorm4x8("unpackUnorm4x8");
+constexpr const ImmutableString usubBorrow("usubBorrow");
+constexpr const ImmutableString yuv_2_rgb("yuv_2_rgb");
+
+} // namespace BuiltInName
+
+// TODO(oetuaho): Would be nice to make this a class instead of a namespace so that we could friend
+// this from TVariable. Now symbol constructors taking an id have to be public even though they're
+// not supposed to be accessible from outside of here. http://anglebug.com/2390
+namespace BuiltInVariable
+{
+
+constexpr const unsigned int kArraySize4[1] = {4};
+
+constexpr const TVariable kangle_BaseInstance(
+ BuiltInId::angle_BaseInstance,
+ BuiltInName::angle_BaseInstance,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::ANGLE_base_vertex_base_instance_shader_builtin}},
+ StaticType::Get<EbtInt, EbpHigh, EvqUniform, 1, 1>());
+constexpr const TVariable kangle_BaseVertex(
+ BuiltInId::angle_BaseVertex,
+ BuiltInName::angle_BaseVertex,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::ANGLE_base_vertex_base_instance_shader_builtin}},
+ StaticType::Get<EbtInt, EbpHigh, EvqUniform, 1, 1>());
+constexpr const TVariable kgl_BaseInstance(
+ BuiltInId::gl_BaseInstance,
+ BuiltInName::gl_BaseInstance,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::ANGLE_base_vertex_base_instance_shader_builtin}},
+ StaticType::Get<EbtInt, EbpHigh, EvqUniform, 1, 1>());
+constexpr const TVariable kgl_BaseVertex(
+ BuiltInId::gl_BaseVertex,
+ BuiltInName::gl_BaseVertex,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::ANGLE_base_vertex_base_instance_shader_builtin}},
+ StaticType::Get<EbtInt, EbpHigh, EvqUniform, 1, 1>());
+constexpr const TVariable kgl_DrawID(BuiltInId::gl_DrawID,
+ BuiltInName::gl_DrawID,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::ANGLE_multi_draw}},
+ StaticType::Get<EbtInt, EbpHigh, EvqDrawID, 1, 1>());
+constexpr const TVariable kgl_FragColor(BuiltInId::gl_FragColor,
+ BuiltInName::gl_FragColor,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpMedium, EvqFragColor, 4, 1>());
+constexpr const TVariable kgl_FragCoord(BuiltInId::gl_FragCoord,
+ BuiltInName::gl_FragCoord,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpMedium, EvqFragCoord, 4, 1>());
+constexpr const TVariable kgl_FragCoord300(
+ BuiltInId::gl_FragCoord300,
+ BuiltInName::gl_FragCoord,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpHigh, EvqFragCoord, 4, 1>());
+constexpr const TVariable kgl_FragDepth(BuiltInId::gl_FragDepth,
+ BuiltInName::gl_FragDepth,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpHigh, EvqFragDepth, 1, 1>());
+constexpr const TVariable kgl_FrontFacing(
+ BuiltInId::gl_FrontFacing,
+ BuiltInName::gl_FrontFacing,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtBool, EbpUndefined, EvqFrontFacing, 1, 1>());
+constexpr const TVariable kgl_GlobalInvocationID(
+ BuiltInId::gl_GlobalInvocationID,
+ BuiltInName::gl_GlobalInvocationID,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobalInvocationID, 3, 1>());
+constexpr const TVariable kgl_HelperInvocation(
+ BuiltInId::gl_HelperInvocation,
+ BuiltInName::gl_HelperInvocation,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtBool, EbpUndefined, EvqHelperInvocation, 1, 1>());
+constexpr const TVariable kgl_InstanceID(BuiltInId::gl_InstanceID,
+ BuiltInName::gl_InstanceID,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpHigh, EvqInstanceID, 1, 1>());
+constexpr const TVariable kgl_InstanceIndex(
+ BuiltInId::gl_InstanceIndex,
+ BuiltInName::gl_InstanceIndex,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpHigh, EvqInstanceID, 1, 1>());
+constexpr const TVariable kgl_InvocationID(
+ BuiltInId::gl_InvocationID,
+ BuiltInName::gl_InvocationID,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 2u>{{TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}},
+ StaticType::Get<EbtInt, EbpHigh, EvqInvocationID, 1, 1>());
+constexpr const TVariable kgl_InvocationIDES3_2(
+ BuiltInId::gl_InvocationIDES3_2,
+ BuiltInName::gl_InvocationID,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpHigh, EvqInvocationID, 1, 1>());
+constexpr const TVariable kgl_InvocationIDTCS(
+ BuiltInId::gl_InvocationIDTCS,
+ BuiltInName::gl_InvocationID,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpHigh, EvqInvocationID, 1, 1>());
+constexpr const TVariable kgl_InvocationIDTCSES3_2(
+ BuiltInId::gl_InvocationIDTCSES3_2,
+ BuiltInName::gl_InvocationID,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpHigh, EvqInvocationID, 1, 1>());
+constexpr const TVariable kgl_LastFragColor(
+ BuiltInId::gl_LastFragColor,
+ BuiltInName::gl_LastFragColor,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::NV_shader_framebuffer_fetch}},
+ StaticType::Get<EbtFloat, EbpMedium, EvqLastFragColor, 4, 1>());
+constexpr const TVariable kgl_LastFragColorARM(
+ BuiltInId::gl_LastFragColorARM,
+ BuiltInName::gl_LastFragColorARM,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::ARM_shader_framebuffer_fetch}},
+ StaticType::Get<EbtFloat, EbpMedium, EvqLastFragColor, 4, 1>());
+constexpr const TVariable kgl_Layer(BuiltInId::gl_Layer,
+ BuiltInName::gl_Layer,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 2u>{{TExtension::EXT_geometry_shader,
+ TExtension::OES_geometry_shader}},
+ StaticType::Get<EbtInt, EbpHigh, EvqLayerIn, 1, 1>());
+constexpr const TVariable kgl_LayerES3_2(BuiltInId::gl_LayerES3_2,
+ BuiltInName::gl_Layer,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpHigh, EvqLayerIn, 1, 1>());
+constexpr const TVariable kgl_LayerGS(BuiltInId::gl_LayerGS,
+ BuiltInName::gl_Layer,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 2u>{{TExtension::EXT_geometry_shader,
+ TExtension::OES_geometry_shader}},
+ StaticType::Get<EbtInt, EbpHigh, EvqLayerOut, 1, 1>());
+constexpr const TVariable kgl_LayerGSES3_2(BuiltInId::gl_LayerGSES3_2,
+ BuiltInName::gl_Layer,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpHigh, EvqLayerOut, 1, 1>());
+constexpr const TVariable kgl_LayerVS(BuiltInId::gl_LayerVS,
+ BuiltInName::gl_Layer,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpHigh, EvqLayerOut, 1, 1>());
+constexpr const TVariable kgl_LocalInvocationID(
+ BuiltInId::gl_LocalInvocationID,
+ BuiltInName::gl_LocalInvocationID,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUInt, EbpUndefined, EvqLocalInvocationID, 3, 1>());
+constexpr const TVariable kgl_LocalInvocationIndex(
+ BuiltInId::gl_LocalInvocationIndex,
+ BuiltInName::gl_LocalInvocationIndex,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUInt, EbpUndefined, EvqLocalInvocationIndex, 1, 1>());
+constexpr const TVariable kgl_NumSamples(BuiltInId::gl_NumSamples,
+ BuiltInName::gl_NumSamples,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{
+ {TExtension::OES_sample_variables}},
+ StaticType::Get<EbtInt, EbpLow, EvqUniform, 1, 1>());
+constexpr const TVariable kgl_NumSamplesES3_2(BuiltInId::gl_NumSamplesES3_2,
+ BuiltInName::gl_NumSamples,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpLow, EvqUniform, 1, 1>());
+constexpr const TVariable kgl_NumWorkGroups(
+ BuiltInId::gl_NumWorkGroups,
+ BuiltInName::gl_NumWorkGroups,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUInt, EbpUndefined, EvqNumWorkGroups, 3, 1>());
+constexpr const TVariable kgl_PatchVerticesInTCS(
+ BuiltInId::gl_PatchVerticesInTCS,
+ BuiltInName::gl_PatchVerticesIn,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpHigh, EvqPatchVerticesIn, 1, 1>());
+constexpr const TVariable kgl_PatchVerticesInTCSES3_2(
+ BuiltInId::gl_PatchVerticesInTCSES3_2,
+ BuiltInName::gl_PatchVerticesIn,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpHigh, EvqPatchVerticesIn, 1, 1>());
+constexpr const TVariable kgl_PatchVerticesInTES(
+ BuiltInId::gl_PatchVerticesInTES,
+ BuiltInName::gl_PatchVerticesIn,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpHigh, EvqPatchVerticesIn, 1, 1>());
+constexpr const TVariable kgl_PatchVerticesInTESES3_2(
+ BuiltInId::gl_PatchVerticesInTESES3_2,
+ BuiltInName::gl_PatchVerticesIn,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpHigh, EvqPatchVerticesIn, 1, 1>());
+constexpr const TVariable kgl_PointCoord(
+ BuiltInId::gl_PointCoord,
+ BuiltInName::gl_PointCoord,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpMedium, EvqPointCoord, 2, 1>());
+constexpr const TVariable kgl_PointSize(BuiltInId::gl_PointSize,
+ BuiltInName::gl_PointSize,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpMedium, EvqPointSize, 1, 1>());
+constexpr const TVariable kgl_PointSize300(
+ BuiltInId::gl_PointSize300,
+ BuiltInName::gl_PointSize,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpHigh, EvqPointSize, 1, 1>());
+constexpr const TVariable kgl_Position(BuiltInId::gl_Position,
+ BuiltInName::gl_Position,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpHigh, EvqPosition, 4, 1>());
+constexpr const TVariable kgl_PrimitiveID(
+ BuiltInId::gl_PrimitiveID,
+ BuiltInName::gl_PrimitiveID,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 2u>{{TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}},
+ StaticType::Get<EbtInt, EbpHigh, EvqPrimitiveID, 1, 1>());
+constexpr const TVariable kgl_PrimitiveIDES3_2(
+ BuiltInId::gl_PrimitiveIDES3_2,
+ BuiltInName::gl_PrimitiveID,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpHigh, EvqPrimitiveID, 1, 1>());
+constexpr const TVariable kgl_PrimitiveIDGS(
+ BuiltInId::gl_PrimitiveIDGS,
+ BuiltInName::gl_PrimitiveID,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 2u>{{TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}},
+ StaticType::Get<EbtInt, EbpHigh, EvqPrimitiveID, 1, 1>());
+constexpr const TVariable kgl_PrimitiveIDGSES3_2(
+ BuiltInId::gl_PrimitiveIDGSES3_2,
+ BuiltInName::gl_PrimitiveID,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpHigh, EvqPrimitiveID, 1, 1>());
+constexpr const TVariable kgl_PrimitiveIDIn(
+ BuiltInId::gl_PrimitiveIDIn,
+ BuiltInName::gl_PrimitiveIDIn,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 2u>{{TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}},
+ StaticType::Get<EbtInt, EbpHigh, EvqPrimitiveIDIn, 1, 1>());
+constexpr const TVariable kgl_PrimitiveIDInES3_2(
+ BuiltInId::gl_PrimitiveIDInES3_2,
+ BuiltInName::gl_PrimitiveIDIn,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpHigh, EvqPrimitiveIDIn, 1, 1>());
+constexpr const TVariable kgl_PrimitiveIDTCS(
+ BuiltInId::gl_PrimitiveIDTCS,
+ BuiltInName::gl_PrimitiveID,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpHigh, EvqPrimitiveID, 1, 1>());
+constexpr const TVariable kgl_PrimitiveIDTCSES3_2(
+ BuiltInId::gl_PrimitiveIDTCSES3_2,
+ BuiltInName::gl_PrimitiveID,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpHigh, EvqPrimitiveID, 1, 1>());
+constexpr const TVariable kgl_PrimitiveIDTES(
+ BuiltInId::gl_PrimitiveIDTES,
+ BuiltInName::gl_PrimitiveID,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpHigh, EvqPrimitiveID, 1, 1>());
+constexpr const TVariable kgl_PrimitiveIDTESES3_2(
+ BuiltInId::gl_PrimitiveIDTESES3_2,
+ BuiltInName::gl_PrimitiveID,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpHigh, EvqPrimitiveID, 1, 1>());
+constexpr const TVariable kgl_SampleID(BuiltInId::gl_SampleID,
+ BuiltInName::gl_SampleID,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{
+ {TExtension::OES_sample_variables}},
+ StaticType::Get<EbtInt, EbpLow, EvqSampleID, 1, 1>());
+constexpr const TVariable kgl_SampleIDES3_2(BuiltInId::gl_SampleIDES3_2,
+ BuiltInName::gl_SampleID,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpLow, EvqSampleID, 1, 1>());
+constexpr const TVariable kgl_SamplePosition(
+ BuiltInId::gl_SamplePosition,
+ BuiltInName::gl_SamplePosition,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::OES_sample_variables}},
+ StaticType::Get<EbtFloat, EbpMedium, EvqSamplePosition, 2, 1>());
+constexpr const TVariable kgl_SamplePositionES3_2(
+ BuiltInId::gl_SamplePositionES3_2,
+ BuiltInName::gl_SamplePosition,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpMedium, EvqSamplePosition, 2, 1>());
+constexpr const TVariable kgl_SecondaryFragColorEXT(
+ BuiltInId::gl_SecondaryFragColorEXT,
+ BuiltInName::gl_SecondaryFragColorEXT,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_blend_func_extended}},
+ StaticType::Get<EbtFloat, EbpMedium, EvqSecondaryFragColorEXT, 4, 1>());
+constexpr const TVariable kgl_TessCoord(BuiltInId::gl_TessCoord,
+ BuiltInName::gl_TessCoord,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpHigh, EvqTessCoord, 3, 1>());
+constexpr const TVariable kgl_VertexID(BuiltInId::gl_VertexID,
+ BuiltInName::gl_VertexID,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpHigh, EvqVertexID, 1, 1>());
+constexpr const TVariable kgl_VertexIndex(BuiltInId::gl_VertexIndex,
+ BuiltInName::gl_VertexIndex,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpHigh, EvqVertexID, 1, 1>());
+constexpr const TVariable kgl_ViewID_OVR(BuiltInId::gl_ViewID_OVR,
+ BuiltInName::gl_ViewID_OVR,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::OVR_multiview}},
+ StaticType::Get<EbtUInt, EbpHigh, EvqViewIDOVR, 1, 1>());
+constexpr const TVariable kgl_ViewportIndex(
+ BuiltInId::gl_ViewportIndex,
+ BuiltInName::gl_ViewportIndex,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpHigh, EvqViewportIndex, 1, 1>());
+constexpr const TVariable kgl_WorkGroupID(
+ BuiltInId::gl_WorkGroupID,
+ BuiltInName::gl_WorkGroupID,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUInt, EbpUndefined, EvqWorkGroupID, 3, 1>());
+constexpr const TVariable kgl_WorkGroupSize(
+ BuiltInId::gl_WorkGroupSize,
+ BuiltInName::gl_WorkGroupSize,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUInt, EbpUndefined, EvqWorkGroupSize, 3, 1>());
+constexpr const TVariable kpt00B(BuiltInId::pt00B,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00D(BuiltInId::pt00D,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00E(BuiltInId::pt00E,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00F(BuiltInId::pt00F,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00G(
+ BuiltInId::pt00G,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtAtomicCounter, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00H(
+ BuiltInId::pt00H,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtYuvCscStandardEXT, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00I(BuiltInId::pt00I,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtSampler2D, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00J(BuiltInId::pt00J,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtSampler3D, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00K(BuiltInId::pt00K,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtSamplerCube, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00L(
+ BuiltInId::pt00L,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtSampler2DArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00M(
+ BuiltInId::pt00M,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtSamplerExternalOES, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00N(
+ BuiltInId::pt00N,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtSamplerExternal2DY2YEXT, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00O(
+ BuiltInId::pt00O,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtSampler2DRect, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00P(BuiltInId::pt00P,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtSampler2DMS, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00Q(
+ BuiltInId::pt00Q,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtSampler2DMSArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00R(BuiltInId::pt00R,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtISampler2D, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00S(BuiltInId::pt00S,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtISampler3D, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00T(BuiltInId::pt00T,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtISamplerCube, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00U(
+ BuiltInId::pt00U,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtISampler2DArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00V(BuiltInId::pt00V,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtISampler2DMS, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00W(
+ BuiltInId::pt00W,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtISampler2DMSArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00X(BuiltInId::pt00X,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUSampler2D, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00Y(BuiltInId::pt00Y,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUSampler3D, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00Z(BuiltInId::pt00Z,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUSamplerCube, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00a(
+ BuiltInId::pt00a,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUSampler2DArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00b(BuiltInId::pt00b,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUSampler2DMS, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00c(
+ BuiltInId::pt00c,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUSampler2DMSArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00d(
+ BuiltInId::pt00d,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtSampler2DShadow, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00e(
+ BuiltInId::pt00e,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtSamplerCubeShadow, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00f(
+ BuiltInId::pt00f,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtSampler2DArrayShadow, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00j(
+ BuiltInId::pt00j,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtSamplerBuffer, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00k(
+ BuiltInId::pt00k,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtSamplerCubeArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00l(
+ BuiltInId::pt00l,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtSamplerCubeArrayShadow, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00r(
+ BuiltInId::pt00r,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtISamplerBuffer, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00s(
+ BuiltInId::pt00s,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtISamplerCubeArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00w(
+ BuiltInId::pt00w,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUSamplerBuffer, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00x(
+ BuiltInId::pt00x,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUSamplerCubeArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00y(
+ BuiltInId::pt00y,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtSamplerVideoWEBGL, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt00z(BuiltInId::pt00z,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtImage2D, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01A(BuiltInId::pt01A,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtImage3D, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01B(BuiltInId::pt01B,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtImage2DArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01C(BuiltInId::pt01C,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtImageCube, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01D(BuiltInId::pt01D,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtImage1D, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01E(BuiltInId::pt01E,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtImage1DArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01F(BuiltInId::pt01F,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtImage2DMS, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01G(
+ BuiltInId::pt01G,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtImage2DMSArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01H(
+ BuiltInId::pt01H,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtImageCubeArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01I(BuiltInId::pt01I,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtImageRect, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01J(BuiltInId::pt01J,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtImageBuffer, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01K(BuiltInId::pt01K,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtIImage2D, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01L(BuiltInId::pt01L,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtIImage3D, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01M(
+ BuiltInId::pt01M,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtIImage2DArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01N(BuiltInId::pt01N,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtIImageCube, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01O(BuiltInId::pt01O,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtIImage1D, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01P(
+ BuiltInId::pt01P,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtIImage1DArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01Q(BuiltInId::pt01Q,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtIImage2DMS, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01R(
+ BuiltInId::pt01R,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtIImage2DMSArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01S(
+ BuiltInId::pt01S,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtIImageCubeArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01T(BuiltInId::pt01T,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtIImageRect, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01U(BuiltInId::pt01U,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtIImageBuffer, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01V(BuiltInId::pt01V,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUImage2D, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01W(BuiltInId::pt01W,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUImage3D, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01X(
+ BuiltInId::pt01X,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUImage2DArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01Y(BuiltInId::pt01Y,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUImageCube, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01Z(BuiltInId::pt01Z,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUImage1D, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01a(
+ BuiltInId::pt01a,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUImage1DArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01b(BuiltInId::pt01b,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUImage2DMS, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01c(
+ BuiltInId::pt01c,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUImage2DMSArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01d(
+ BuiltInId::pt01d,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUImageCubeArray, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01e(BuiltInId::pt01e,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUImageRect, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01f(BuiltInId::pt01f,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUImageBuffer, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01g(
+ BuiltInId::pt01g,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtPixelLocalANGLE, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01h(
+ BuiltInId::pt01h,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtIPixelLocalANGLE, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01i(
+ BuiltInId::pt01i,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUPixelLocalANGLE, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01j(BuiltInId::pt01j,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtSubpassInput, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01k(
+ BuiltInId::pt01k,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtISubpassInput, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01l(
+ BuiltInId::pt01l,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUSubpassInput, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01m(
+ BuiltInId::pt01m,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtSubpassInputMS, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01n(
+ BuiltInId::pt01n,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtISubpassInputMS, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt01o(
+ BuiltInId::pt01o,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUSubpassInputMS, EbpUndefined, EvqGlobal, 1, 1>());
+constexpr const TVariable kpt10B(BuiltInId::pt10B,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>());
+constexpr const TVariable kpt10D(BuiltInId::pt10D,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>());
+constexpr const TVariable kpt10Dx4(
+ BuiltInId::pt10Dx4,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::GetArray<EbtInt, EbpUndefined, EvqGlobal, 2, 1, kArraySize4, 1>());
+constexpr const TVariable kpt10E(BuiltInId::pt10E,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 2, 1>());
+constexpr const TVariable kpt10F(BuiltInId::pt10F,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>());
+constexpr const TVariable kpt20B(BuiltInId::pt20B,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>());
+constexpr const TVariable kpt20D(BuiltInId::pt20D,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>());
+constexpr const TVariable kpt20E(BuiltInId::pt20E,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 3, 1>());
+constexpr const TVariable kpt20F(BuiltInId::pt20F,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>());
+constexpr const TVariable kpt30B(BuiltInId::pt30B,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>());
+constexpr const TVariable kpt30D(BuiltInId::pt30D,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>());
+constexpr const TVariable kpt30E(BuiltInId::pt30E,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>());
+constexpr const TVariable kpt30F(BuiltInId::pt30F,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>());
+constexpr const TVariable kpt50B(BuiltInId::pt50B,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 2>());
+constexpr const TVariable kpt60B(BuiltInId::pt60B,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 2>());
+constexpr const TVariable kpt70B(BuiltInId::pt70B,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 2>());
+constexpr const TVariable kpt90B(BuiltInId::pt90B,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 3>());
+constexpr const TVariable kptA0B(BuiltInId::ptA0B,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 3>());
+constexpr const TVariable kptB0B(BuiltInId::ptB0B,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 3>());
+constexpr const TVariable kptD0B(BuiltInId::ptD0B,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 4>());
+constexpr const TVariable kptE0B(BuiltInId::ptE0B,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 4>());
+constexpr const TVariable kptF0B(BuiltInId::ptF0B,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 4>());
+constexpr const TVariable kpt_io_00D(BuiltInId::pt_io_00D,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpUndefined, EvqParamInOut, 1, 1>());
+constexpr const TVariable kpt_io_00E(BuiltInId::pt_io_00E,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUInt, EbpUndefined, EvqParamInOut, 1, 1>());
+constexpr const TVariable kpt_o_00B(BuiltInId::pt_o_00B,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpUndefined, EvqParamOut, 1, 1>());
+constexpr const TVariable kpt_o_00D(BuiltInId::pt_o_00D,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpUndefined, EvqParamOut, 1, 1>());
+constexpr const TVariable kpt_o_00E(BuiltInId::pt_o_00E,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUInt, EbpUndefined, EvqParamOut, 1, 1>());
+constexpr const TVariable kpt_o_10B(BuiltInId::pt_o_10B,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpUndefined, EvqParamOut, 2, 1>());
+constexpr const TVariable kpt_o_10D(BuiltInId::pt_o_10D,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpUndefined, EvqParamOut, 2, 1>());
+constexpr const TVariable kpt_o_10E(BuiltInId::pt_o_10E,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUInt, EbpUndefined, EvqParamOut, 2, 1>());
+constexpr const TVariable kpt_o_20B(BuiltInId::pt_o_20B,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpUndefined, EvqParamOut, 3, 1>());
+constexpr const TVariable kpt_o_20D(BuiltInId::pt_o_20D,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpUndefined, EvqParamOut, 3, 1>());
+constexpr const TVariable kpt_o_20E(BuiltInId::pt_o_20E,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUInt, EbpUndefined, EvqParamOut, 3, 1>());
+constexpr const TVariable kpt_o_30B(BuiltInId::pt_o_30B,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtFloat, EbpUndefined, EvqParamOut, 4, 1>());
+constexpr const TVariable kpt_o_30D(BuiltInId::pt_o_30D,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpUndefined, EvqParamOut, 4, 1>());
+constexpr const TVariable kpt_o_30E(BuiltInId::pt_o_30E,
+ BuiltInName::_empty,
+ SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtUInt, EbpUndefined, EvqParamOut, 4, 1>());
+
+const TVariable *angle_BaseInstance()
+{
+ return &kangle_BaseInstance;
+}
+
+const TVariable *angle_BaseVertex()
+{
+ return &kangle_BaseVertex;
+}
+
+const TVariable *gl_BaseInstance()
+{
+ return &kgl_BaseInstance;
+}
+
+const TVariable *gl_BaseVertex()
+{
+ return &kgl_BaseVertex;
+}
+
+const TVariable *gl_DrawID()
+{
+ return &kgl_DrawID;
+}
+
+const TVariable *gl_FragColor()
+{
+ return &kgl_FragColor;
+}
+
+const TVariable *gl_FragCoord()
+{
+ return &kgl_FragCoord;
+}
+
+const TVariable *gl_FragCoord300()
+{
+ return &kgl_FragCoord300;
+}
+
+const TVariable *gl_FragDepth()
+{
+ return &kgl_FragDepth;
+}
+
+const TVariable *gl_FrontFacing()
+{
+ return &kgl_FrontFacing;
+}
+
+const TVariable *gl_GlobalInvocationID()
+{
+ return &kgl_GlobalInvocationID;
+}
+
+const TVariable *gl_HelperInvocation()
+{
+ return &kgl_HelperInvocation;
+}
+
+const TVariable *gl_InstanceID()
+{
+ return &kgl_InstanceID;
+}
+
+const TVariable *gl_InstanceIndex()
+{
+ return &kgl_InstanceIndex;
+}
+
+const TVariable *gl_InvocationID()
+{
+ return &kgl_InvocationID;
+}
+
+const TVariable *gl_InvocationIDES3_2()
+{
+ return &kgl_InvocationIDES3_2;
+}
+
+const TVariable *gl_InvocationIDTCS()
+{
+ return &kgl_InvocationIDTCS;
+}
+
+const TVariable *gl_InvocationIDTCSES3_2()
+{
+ return &kgl_InvocationIDTCSES3_2;
+}
+
+const TVariable *gl_LastFragColor()
+{
+ return &kgl_LastFragColor;
+}
+
+const TVariable *gl_LastFragColorARM()
+{
+ return &kgl_LastFragColorARM;
+}
+
+const TVariable *gl_Layer()
+{
+ return &kgl_Layer;
+}
+
+const TVariable *gl_LayerES3_2()
+{
+ return &kgl_LayerES3_2;
+}
+
+const TVariable *gl_LayerGS()
+{
+ return &kgl_LayerGS;
+}
+
+const TVariable *gl_LayerGSES3_2()
+{
+ return &kgl_LayerGSES3_2;
+}
+
+const TVariable *gl_LayerVS()
+{
+ return &kgl_LayerVS;
+}
+
+const TVariable *gl_LocalInvocationID()
+{
+ return &kgl_LocalInvocationID;
+}
+
+const TVariable *gl_LocalInvocationIndex()
+{
+ return &kgl_LocalInvocationIndex;
+}
+
+const TVariable *gl_NumSamples()
+{
+ return &kgl_NumSamples;
+}
+
+const TVariable *gl_NumSamplesES3_2()
+{
+ return &kgl_NumSamplesES3_2;
+}
+
+const TVariable *gl_NumWorkGroups()
+{
+ return &kgl_NumWorkGroups;
+}
+
+const TVariable *gl_PatchVerticesInTCS()
+{
+ return &kgl_PatchVerticesInTCS;
+}
+
+const TVariable *gl_PatchVerticesInTCSES3_2()
+{
+ return &kgl_PatchVerticesInTCSES3_2;
+}
+
+const TVariable *gl_PatchVerticesInTES()
+{
+ return &kgl_PatchVerticesInTES;
+}
+
+const TVariable *gl_PatchVerticesInTESES3_2()
+{
+ return &kgl_PatchVerticesInTESES3_2;
+}
+
+const TVariable *gl_PointCoord()
+{
+ return &kgl_PointCoord;
+}
+
+const TVariable *gl_PointSize()
+{
+ return &kgl_PointSize;
+}
+
+const TVariable *gl_PointSize300()
+{
+ return &kgl_PointSize300;
+}
+
+const TVariable *gl_Position()
+{
+ return &kgl_Position;
+}
+
+const TVariable *gl_PrimitiveID()
+{
+ return &kgl_PrimitiveID;
+}
+
+const TVariable *gl_PrimitiveIDES3_2()
+{
+ return &kgl_PrimitiveIDES3_2;
+}
+
+const TVariable *gl_PrimitiveIDGS()
+{
+ return &kgl_PrimitiveIDGS;
+}
+
+const TVariable *gl_PrimitiveIDGSES3_2()
+{
+ return &kgl_PrimitiveIDGSES3_2;
+}
+
+const TVariable *gl_PrimitiveIDIn()
+{
+ return &kgl_PrimitiveIDIn;
+}
+
+const TVariable *gl_PrimitiveIDInES3_2()
+{
+ return &kgl_PrimitiveIDInES3_2;
+}
+
+const TVariable *gl_PrimitiveIDTCS()
+{
+ return &kgl_PrimitiveIDTCS;
+}
+
+const TVariable *gl_PrimitiveIDTCSES3_2()
+{
+ return &kgl_PrimitiveIDTCSES3_2;
+}
+
+const TVariable *gl_PrimitiveIDTES()
+{
+ return &kgl_PrimitiveIDTES;
+}
+
+const TVariable *gl_PrimitiveIDTESES3_2()
+{
+ return &kgl_PrimitiveIDTESES3_2;
+}
+
+const TVariable *gl_SampleID()
+{
+ return &kgl_SampleID;
+}
+
+const TVariable *gl_SampleIDES3_2()
+{
+ return &kgl_SampleIDES3_2;
+}
+
+const TVariable *gl_SamplePosition()
+{
+ return &kgl_SamplePosition;
+}
+
+const TVariable *gl_SamplePositionES3_2()
+{
+ return &kgl_SamplePositionES3_2;
+}
+
+const TVariable *gl_SecondaryFragColorEXT()
+{
+ return &kgl_SecondaryFragColorEXT;
+}
+
+const TVariable *gl_TessCoord()
+{
+ return &kgl_TessCoord;
+}
+
+const TVariable *gl_VertexID()
+{
+ return &kgl_VertexID;
+}
+
+const TVariable *gl_VertexIndex()
+{
+ return &kgl_VertexIndex;
+}
+
+const TVariable *gl_ViewID_OVR()
+{
+ return &kgl_ViewID_OVR;
+}
+
+const TVariable *gl_ViewportIndex()
+{
+ return &kgl_ViewportIndex;
+}
+
+const TVariable *gl_WorkGroupID()
+{
+ return &kgl_WorkGroupID;
+}
+
+const TVariable *gl_WorkGroupSize()
+{
+ return &kgl_WorkGroupSize;
+}
+
+} // namespace BuiltInVariable
+
+namespace BuiltInParameters
+{
+
+constexpr const TVariable **empty = nullptr;
+constexpr const TVariable *p00B00B00B[3] = {&BuiltInVariable::kpt00B, &BuiltInVariable::kpt00B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00B00B00F[3] = {&BuiltInVariable::kpt00B, &BuiltInVariable::kpt00B,
+ &BuiltInVariable::kpt00F};
+constexpr const TVariable *p00B00B10B[3] = {&BuiltInVariable::kpt00B, &BuiltInVariable::kpt00B,
+ &BuiltInVariable::kpt10B};
+constexpr const TVariable *p00B00B20B[3] = {&BuiltInVariable::kpt00B, &BuiltInVariable::kpt00B,
+ &BuiltInVariable::kpt20B};
+constexpr const TVariable *p00B00B30B[3] = {&BuiltInVariable::kpt00B, &BuiltInVariable::kpt00B,
+ &BuiltInVariable::kpt30B};
+constexpr const TVariable *p00B00D[2] = {&BuiltInVariable::kpt00B, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00B10B[2] = {&BuiltInVariable::kpt00B, &BuiltInVariable::kpt10B};
+constexpr const TVariable *p00B20B[2] = {&BuiltInVariable::kpt00B, &BuiltInVariable::kpt20B};
+constexpr const TVariable *p00B30B[2] = {&BuiltInVariable::kpt00B, &BuiltInVariable::kpt30B};
+constexpr const TVariable *p00B_o_00B[2] = {&BuiltInVariable::kpt00B, &BuiltInVariable::kpt_o_00B};
+constexpr const TVariable *p00B_o_00D[2] = {&BuiltInVariable::kpt00B, &BuiltInVariable::kpt_o_00D};
+constexpr const TVariable *p00D00D00D00D[4] = {&BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00D00D00F[3] = {&BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00F};
+constexpr const TVariable *p00D00D_o_00D_o_00D[4] = {
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D, &BuiltInVariable::kpt_o_00D,
+ &BuiltInVariable::kpt_o_00D};
+constexpr const TVariable *p00E00D00D[3] = {&BuiltInVariable::kpt00E, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00E00E00D00D[4] = {&BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00E00E00E[3] = {&BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E,
+ &BuiltInVariable::kpt00E};
+constexpr const TVariable *p00E00E00F[3] = {&BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E,
+ &BuiltInVariable::kpt00F};
+constexpr const TVariable *p00E00E_o_00E_o_00E[4] = {
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E, &BuiltInVariable::kpt_o_00E,
+ &BuiltInVariable::kpt_o_00E};
+constexpr const TVariable *p00F00F00F[3] = {&BuiltInVariable::kpt00F, &BuiltInVariable::kpt00F,
+ &BuiltInVariable::kpt00F};
+constexpr const TVariable *p00G[1] = {&BuiltInVariable::kpt00G};
+constexpr const TVariable *p00I00D[2] = {&BuiltInVariable::kpt00I, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00I10B00B10D[4] = {&BuiltInVariable::kpt00I, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt00B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00I10B00D[3] = {&BuiltInVariable::kpt00I, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00I10B10B10B10D[5] = {
+ &BuiltInVariable::kpt00I, &BuiltInVariable::kpt10B, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00I10B10D00B[4] = {&BuiltInVariable::kpt00I, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00I10B10D00D[4] = {&BuiltInVariable::kpt00I, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00I10B10Dx400D[4] = {&BuiltInVariable::kpt00I, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10Dx4,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00I10D00D10D[4] = {&BuiltInVariable::kpt00I, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00I20B00B10D[4] = {&BuiltInVariable::kpt00I, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00I20B10B10B10D[5] = {
+ &BuiltInVariable::kpt00I, &BuiltInVariable::kpt20B, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00I20B10D00B[4] = {&BuiltInVariable::kpt00I, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00I30B00B10D[4] = {&BuiltInVariable::kpt00I, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt00B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00I30B10B10B10D[5] = {
+ &BuiltInVariable::kpt00I, &BuiltInVariable::kpt30B, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00I30B10D00B[4] = {&BuiltInVariable::kpt00I, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00J00D[2] = {&BuiltInVariable::kpt00J, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00J20B00B20D[4] = {&BuiltInVariable::kpt00J, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00B, &BuiltInVariable::kpt20D};
+constexpr const TVariable *p00J20B20B20B20D[5] = {
+ &BuiltInVariable::kpt00J, &BuiltInVariable::kpt20B, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt20B, &BuiltInVariable::kpt20D};
+constexpr const TVariable *p00J20B20D00B[4] = {&BuiltInVariable::kpt00J, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt20D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00J20D00D20D[4] = {&BuiltInVariable::kpt00J, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt20D};
+constexpr const TVariable *p00J30B00B20D[4] = {&BuiltInVariable::kpt00J, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt00B, &BuiltInVariable::kpt20D};
+constexpr const TVariable *p00J30B20B20B20D[5] = {
+ &BuiltInVariable::kpt00J, &BuiltInVariable::kpt30B, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt20B, &BuiltInVariable::kpt20D};
+constexpr const TVariable *p00J30B20D00B[4] = {&BuiltInVariable::kpt00J, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt20D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00K00D[2] = {&BuiltInVariable::kpt00K, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00K20B00B[3] = {&BuiltInVariable::kpt00K, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00K20B00D[3] = {&BuiltInVariable::kpt00K, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00K20B20B20B[4] = {&BuiltInVariable::kpt00K, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt20B, &BuiltInVariable::kpt20B};
+constexpr const TVariable *p00L00D[2] = {&BuiltInVariable::kpt00L, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00L20B00B10D[4] = {&BuiltInVariable::kpt00L, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00L20B00D[3] = {&BuiltInVariable::kpt00L, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00L20B10B10B10D[5] = {
+ &BuiltInVariable::kpt00L, &BuiltInVariable::kpt20B, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00L20B10D00B[4] = {&BuiltInVariable::kpt00L, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00L20B10D00D[4] = {&BuiltInVariable::kpt00L, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00L20B10Dx400D[4] = {&BuiltInVariable::kpt00L, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt10Dx4,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00L20D00D10D[4] = {&BuiltInVariable::kpt00L, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00M00D[2] = {&BuiltInVariable::kpt00M, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00M10B00B[3] = {&BuiltInVariable::kpt00M, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00M10D00D[3] = {&BuiltInVariable::kpt00M, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00M20B00B[3] = {&BuiltInVariable::kpt00M, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00M30B00B[3] = {&BuiltInVariable::kpt00M, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00N00D[2] = {&BuiltInVariable::kpt00N, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00N10B00B[3] = {&BuiltInVariable::kpt00N, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00N10D00D[3] = {&BuiltInVariable::kpt00N, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00N20B00B[3] = {&BuiltInVariable::kpt00N, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00N30B00B[3] = {&BuiltInVariable::kpt00N, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00O10B[2] = {&BuiltInVariable::kpt00O, &BuiltInVariable::kpt10B};
+constexpr const TVariable *p00O20B[2] = {&BuiltInVariable::kpt00O, &BuiltInVariable::kpt20B};
+constexpr const TVariable *p00O30B[2] = {&BuiltInVariable::kpt00O, &BuiltInVariable::kpt30B};
+constexpr const TVariable *p00P10D00D[3] = {&BuiltInVariable::kpt00P, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00Q20D00D[3] = {&BuiltInVariable::kpt00Q, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00R00D[2] = {&BuiltInVariable::kpt00R, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00R10B00B10D[4] = {&BuiltInVariable::kpt00R, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt00B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00R10B00D[3] = {&BuiltInVariable::kpt00R, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00R10B10B10B10D[5] = {
+ &BuiltInVariable::kpt00R, &BuiltInVariable::kpt10B, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00R10B10D00B[4] = {&BuiltInVariable::kpt00R, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00R10B10D00D[4] = {&BuiltInVariable::kpt00R, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00R10B10Dx400D[4] = {&BuiltInVariable::kpt00R, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10Dx4,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00R10D00D10D[4] = {&BuiltInVariable::kpt00R, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00R20B00B10D[4] = {&BuiltInVariable::kpt00R, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00R20B10B10B10D[5] = {
+ &BuiltInVariable::kpt00R, &BuiltInVariable::kpt20B, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00R20B10D00B[4] = {&BuiltInVariable::kpt00R, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00R30B00B10D[4] = {&BuiltInVariable::kpt00R, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt00B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00R30B10B10B10D[5] = {
+ &BuiltInVariable::kpt00R, &BuiltInVariable::kpt30B, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00R30B10D00B[4] = {&BuiltInVariable::kpt00R, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00S00D[2] = {&BuiltInVariable::kpt00S, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00S20B00B20D[4] = {&BuiltInVariable::kpt00S, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00B, &BuiltInVariable::kpt20D};
+constexpr const TVariable *p00S20B20B20B20D[5] = {
+ &BuiltInVariable::kpt00S, &BuiltInVariable::kpt20B, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt20B, &BuiltInVariable::kpt20D};
+constexpr const TVariable *p00S20B20D00B[4] = {&BuiltInVariable::kpt00S, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt20D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00S20D00D20D[4] = {&BuiltInVariable::kpt00S, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt20D};
+constexpr const TVariable *p00S30B00B20D[4] = {&BuiltInVariable::kpt00S, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt00B, &BuiltInVariable::kpt20D};
+constexpr const TVariable *p00S30B20B20B20D[5] = {
+ &BuiltInVariable::kpt00S, &BuiltInVariable::kpt30B, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt20B, &BuiltInVariable::kpt20D};
+constexpr const TVariable *p00S30B20D00B[4] = {&BuiltInVariable::kpt00S, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt20D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00T00D[2] = {&BuiltInVariable::kpt00T, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00T20B00B[3] = {&BuiltInVariable::kpt00T, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00T20B00D[3] = {&BuiltInVariable::kpt00T, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00T20B20B20B[4] = {&BuiltInVariable::kpt00T, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt20B, &BuiltInVariable::kpt20B};
+constexpr const TVariable *p00U00D[2] = {&BuiltInVariable::kpt00U, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00U20B00B10D[4] = {&BuiltInVariable::kpt00U, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00U20B00D[3] = {&BuiltInVariable::kpt00U, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00U20B10B10B10D[5] = {
+ &BuiltInVariable::kpt00U, &BuiltInVariable::kpt20B, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00U20B10D00B[4] = {&BuiltInVariable::kpt00U, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00U20B10D00D[4] = {&BuiltInVariable::kpt00U, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00U20B10Dx400D[4] = {&BuiltInVariable::kpt00U, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt10Dx4,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00U20D00D10D[4] = {&BuiltInVariable::kpt00U, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00V10D00D[3] = {&BuiltInVariable::kpt00V, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00W20D00D[3] = {&BuiltInVariable::kpt00W, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00X00D[2] = {&BuiltInVariable::kpt00X, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00X10B00B10D[4] = {&BuiltInVariable::kpt00X, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt00B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00X10B00D[3] = {&BuiltInVariable::kpt00X, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00X10B10B10B10D[5] = {
+ &BuiltInVariable::kpt00X, &BuiltInVariable::kpt10B, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00X10B10D00B[4] = {&BuiltInVariable::kpt00X, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00X10B10D00D[4] = {&BuiltInVariable::kpt00X, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00X10B10Dx400D[4] = {&BuiltInVariable::kpt00X, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10Dx4,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00X10D00D10D[4] = {&BuiltInVariable::kpt00X, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00X20B00B10D[4] = {&BuiltInVariable::kpt00X, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00X20B10B10B10D[5] = {
+ &BuiltInVariable::kpt00X, &BuiltInVariable::kpt20B, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00X20B10D00B[4] = {&BuiltInVariable::kpt00X, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00X30B00B10D[4] = {&BuiltInVariable::kpt00X, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt00B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00X30B10B10B10D[5] = {
+ &BuiltInVariable::kpt00X, &BuiltInVariable::kpt30B, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00X30B10D00B[4] = {&BuiltInVariable::kpt00X, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00Y00D[2] = {&BuiltInVariable::kpt00Y, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00Y20B00B20D[4] = {&BuiltInVariable::kpt00Y, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00B, &BuiltInVariable::kpt20D};
+constexpr const TVariable *p00Y20B20B20B20D[5] = {
+ &BuiltInVariable::kpt00Y, &BuiltInVariable::kpt20B, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt20B, &BuiltInVariable::kpt20D};
+constexpr const TVariable *p00Y20B20D00B[4] = {&BuiltInVariable::kpt00Y, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt20D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00Y20D00D20D[4] = {&BuiltInVariable::kpt00Y, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt20D};
+constexpr const TVariable *p00Y30B00B20D[4] = {&BuiltInVariable::kpt00Y, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt00B, &BuiltInVariable::kpt20D};
+constexpr const TVariable *p00Y30B20B20B20D[5] = {
+ &BuiltInVariable::kpt00Y, &BuiltInVariable::kpt30B, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt20B, &BuiltInVariable::kpt20D};
+constexpr const TVariable *p00Y30B20D00B[4] = {&BuiltInVariable::kpt00Y, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt20D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00Z00D[2] = {&BuiltInVariable::kpt00Z, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00Z20B00B[3] = {&BuiltInVariable::kpt00Z, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00Z20B00D[3] = {&BuiltInVariable::kpt00Z, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00Z20B20B20B[4] = {&BuiltInVariable::kpt00Z, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt20B, &BuiltInVariable::kpt20B};
+constexpr const TVariable *p00a00D[2] = {&BuiltInVariable::kpt00a, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00a20B00B10D[4] = {&BuiltInVariable::kpt00a, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00a20B00D[3] = {&BuiltInVariable::kpt00a, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00a20B10B10B10D[5] = {
+ &BuiltInVariable::kpt00a, &BuiltInVariable::kpt20B, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00a20B10D00B[4] = {&BuiltInVariable::kpt00a, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00a20B10D00D[4] = {&BuiltInVariable::kpt00a, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00a20B10Dx400D[4] = {&BuiltInVariable::kpt00a, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt10Dx4,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00a20D00D10D[4] = {&BuiltInVariable::kpt00a, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00b10D00D[3] = {&BuiltInVariable::kpt00b, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00c20D00D[3] = {&BuiltInVariable::kpt00c, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00d00D[2] = {&BuiltInVariable::kpt00d, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00d10B00B10Dx4[4] = {&BuiltInVariable::kpt00d, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt00B,
+ &BuiltInVariable::kpt10Dx4};
+constexpr const TVariable *p00d20B00B10D[4] = {&BuiltInVariable::kpt00d, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00d20B10B10B10D[5] = {
+ &BuiltInVariable::kpt00d, &BuiltInVariable::kpt20B, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00d20B10D00B[4] = {&BuiltInVariable::kpt00d, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00d30B00B10D[4] = {&BuiltInVariable::kpt00d, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt00B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00d30B10B10B10D[5] = {
+ &BuiltInVariable::kpt00d, &BuiltInVariable::kpt30B, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00d30B10D00B[4] = {&BuiltInVariable::kpt00d, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00e00D[2] = {&BuiltInVariable::kpt00e, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00e20B00B[3] = {&BuiltInVariable::kpt00e, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00e30B00B[3] = {&BuiltInVariable::kpt00e, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00e30B20B20B[4] = {&BuiltInVariable::kpt00e, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt20B, &BuiltInVariable::kpt20B};
+constexpr const TVariable *p00f00D[2] = {&BuiltInVariable::kpt00f, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00f20B00B10Dx4[4] = {&BuiltInVariable::kpt00f, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00B,
+ &BuiltInVariable::kpt10Dx4};
+constexpr const TVariable *p00f30B10B10B10D[5] = {
+ &BuiltInVariable::kpt00f, &BuiltInVariable::kpt30B, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p00j00D[2] = {&BuiltInVariable::kpt00j, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00k00D[2] = {&BuiltInVariable::kpt00k, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00k30B00B[3] = {&BuiltInVariable::kpt00k, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00k30B00D[3] = {&BuiltInVariable::kpt00k, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00k30B20B20B[4] = {&BuiltInVariable::kpt00k, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt20B, &BuiltInVariable::kpt20B};
+constexpr const TVariable *p00l00D[2] = {&BuiltInVariable::kpt00l, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00l30B00B[3] = {&BuiltInVariable::kpt00l, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00r00D[2] = {&BuiltInVariable::kpt00r, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00s00D[2] = {&BuiltInVariable::kpt00s, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00s30B00B[3] = {&BuiltInVariable::kpt00s, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00s30B00D[3] = {&BuiltInVariable::kpt00s, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00s30B20B20B[4] = {&BuiltInVariable::kpt00s, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt20B, &BuiltInVariable::kpt20B};
+constexpr const TVariable *p00w00D[2] = {&BuiltInVariable::kpt00w, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00x00D[2] = {&BuiltInVariable::kpt00x, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00x30B00B[3] = {&BuiltInVariable::kpt00x, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00x30B00D[3] = {&BuiltInVariable::kpt00x, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00x30B20B20B[4] = {&BuiltInVariable::kpt00x, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt20B, &BuiltInVariable::kpt20B};
+constexpr const TVariable *p00y10B[2] = {&BuiltInVariable::kpt00y, &BuiltInVariable::kpt10B};
+constexpr const TVariable *p00z10D00B[3] = {&BuiltInVariable::kpt00z, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p00z10D00D00D[4] = {&BuiltInVariable::kpt00z, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p00z10D00E00E[4] = {&BuiltInVariable::kpt00z, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p00z10D30B[3] = {&BuiltInVariable::kpt00z, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt30B};
+constexpr const TVariable *p01A20D00B[3] = {&BuiltInVariable::kpt01A, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01A20D00D00D[4] = {&BuiltInVariable::kpt01A, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01A20D00E00E[4] = {&BuiltInVariable::kpt01A, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01A20D30B[3] = {&BuiltInVariable::kpt01A, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt30B};
+constexpr const TVariable *p01B20D00B[3] = {&BuiltInVariable::kpt01B, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01B20D00D00D[4] = {&BuiltInVariable::kpt01B, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01B20D00E00E[4] = {&BuiltInVariable::kpt01B, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01B20D30B[3] = {&BuiltInVariable::kpt01B, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt30B};
+constexpr const TVariable *p01C20D00B[3] = {&BuiltInVariable::kpt01C, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01C20D00D00D[4] = {&BuiltInVariable::kpt01C, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01C20D00E00E[4] = {&BuiltInVariable::kpt01C, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01C20D30B[3] = {&BuiltInVariable::kpt01C, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt30B};
+constexpr const TVariable *p01D00D00B[3] = {&BuiltInVariable::kpt01D, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01D00D00D00D[4] = {&BuiltInVariable::kpt01D, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01D00D00E00E[4] = {&BuiltInVariable::kpt01D, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01E10D00B[3] = {&BuiltInVariable::kpt01E, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01E10D00D00D[4] = {&BuiltInVariable::kpt01E, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01E10D00E00E[4] = {&BuiltInVariable::kpt01E, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01F10D00D00B[4] = {&BuiltInVariable::kpt01F, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01F10D00D00D00D[5] = {
+ &BuiltInVariable::kpt01F, &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01F10D00D00E00E[5] = {
+ &BuiltInVariable::kpt01F, &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01G20D00D00B[4] = {&BuiltInVariable::kpt01G, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01G20D00D00D00D[5] = {
+ &BuiltInVariable::kpt01G, &BuiltInVariable::kpt20D, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01G20D00D00E00E[5] = {
+ &BuiltInVariable::kpt01G, &BuiltInVariable::kpt20D, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01H20D00B[3] = {&BuiltInVariable::kpt01H, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01H20D00D00D[4] = {&BuiltInVariable::kpt01H, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01H20D00E00E[4] = {&BuiltInVariable::kpt01H, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01H20D30B[3] = {&BuiltInVariable::kpt01H, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt30B};
+constexpr const TVariable *p01I10D00B[3] = {&BuiltInVariable::kpt01I, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01I10D00D00D[4] = {&BuiltInVariable::kpt01I, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01I10D00E00E[4] = {&BuiltInVariable::kpt01I, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01J00D00B[3] = {&BuiltInVariable::kpt01J, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01J00D00D00D[4] = {&BuiltInVariable::kpt01J, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01J00D00E00E[4] = {&BuiltInVariable::kpt01J, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01J00D30B[3] = {&BuiltInVariable::kpt01J, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt30B};
+constexpr const TVariable *p01K10D00B[3] = {&BuiltInVariable::kpt01K, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01K10D00D00D[4] = {&BuiltInVariable::kpt01K, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01K10D00E00E[4] = {&BuiltInVariable::kpt01K, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01K10D30D[3] = {&BuiltInVariable::kpt01K, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt30D};
+constexpr const TVariable *p01L20D00B[3] = {&BuiltInVariable::kpt01L, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01L20D00D00D[4] = {&BuiltInVariable::kpt01L, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01L20D00E00E[4] = {&BuiltInVariable::kpt01L, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01L20D30D[3] = {&BuiltInVariable::kpt01L, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt30D};
+constexpr const TVariable *p01M20D00B[3] = {&BuiltInVariable::kpt01M, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01M20D00D00D[4] = {&BuiltInVariable::kpt01M, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01M20D00E00E[4] = {&BuiltInVariable::kpt01M, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01M20D30D[3] = {&BuiltInVariable::kpt01M, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt30D};
+constexpr const TVariable *p01N20D00B[3] = {&BuiltInVariable::kpt01N, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01N20D00D00D[4] = {&BuiltInVariable::kpt01N, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01N20D00E00E[4] = {&BuiltInVariable::kpt01N, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01N20D30D[3] = {&BuiltInVariable::kpt01N, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt30D};
+constexpr const TVariable *p01O00D00B[3] = {&BuiltInVariable::kpt01O, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01O00D00D00D[4] = {&BuiltInVariable::kpt01O, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01O00D00E00E[4] = {&BuiltInVariable::kpt01O, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01P10D00B[3] = {&BuiltInVariable::kpt01P, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01P10D00D00D[4] = {&BuiltInVariable::kpt01P, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01P10D00E00E[4] = {&BuiltInVariable::kpt01P, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01Q10D00D00B[4] = {&BuiltInVariable::kpt01Q, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01Q10D00D00D00D[5] = {
+ &BuiltInVariable::kpt01Q, &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01Q10D00D00E00E[5] = {
+ &BuiltInVariable::kpt01Q, &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01R20D00D00B[4] = {&BuiltInVariable::kpt01R, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01R20D00D00D00D[5] = {
+ &BuiltInVariable::kpt01R, &BuiltInVariable::kpt20D, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01R20D00D00E00E[5] = {
+ &BuiltInVariable::kpt01R, &BuiltInVariable::kpt20D, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01S20D00B[3] = {&BuiltInVariable::kpt01S, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01S20D00D00D[4] = {&BuiltInVariable::kpt01S, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01S20D00E00E[4] = {&BuiltInVariable::kpt01S, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01S20D30D[3] = {&BuiltInVariable::kpt01S, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt30D};
+constexpr const TVariable *p01T10D00B[3] = {&BuiltInVariable::kpt01T, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01T10D00D00D[4] = {&BuiltInVariable::kpt01T, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01T10D00E00E[4] = {&BuiltInVariable::kpt01T, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01U00D00B[3] = {&BuiltInVariable::kpt01U, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01U00D00D00D[4] = {&BuiltInVariable::kpt01U, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01U00D00E00E[4] = {&BuiltInVariable::kpt01U, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01U00D30D[3] = {&BuiltInVariable::kpt01U, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt30D};
+constexpr const TVariable *p01V10D00B[3] = {&BuiltInVariable::kpt01V, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01V10D00D00D[4] = {&BuiltInVariable::kpt01V, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01V10D00E00E[4] = {&BuiltInVariable::kpt01V, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01V10D30E[3] = {&BuiltInVariable::kpt01V, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt30E};
+constexpr const TVariable *p01W20D00B[3] = {&BuiltInVariable::kpt01W, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01W20D00D00D[4] = {&BuiltInVariable::kpt01W, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01W20D00E00E[4] = {&BuiltInVariable::kpt01W, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01W20D30E[3] = {&BuiltInVariable::kpt01W, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt30E};
+constexpr const TVariable *p01X20D00B[3] = {&BuiltInVariable::kpt01X, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01X20D00D00D[4] = {&BuiltInVariable::kpt01X, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01X20D00E00E[4] = {&BuiltInVariable::kpt01X, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01X20D30E[3] = {&BuiltInVariable::kpt01X, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt30E};
+constexpr const TVariable *p01Y20D00B[3] = {&BuiltInVariable::kpt01Y, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01Y20D00D00D[4] = {&BuiltInVariable::kpt01Y, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01Y20D00E00E[4] = {&BuiltInVariable::kpt01Y, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01Y20D30E[3] = {&BuiltInVariable::kpt01Y, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt30E};
+constexpr const TVariable *p01Z00D00B[3] = {&BuiltInVariable::kpt01Z, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01Z00D00D00D[4] = {&BuiltInVariable::kpt01Z, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01Z00D00E00E[4] = {&BuiltInVariable::kpt01Z, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01a10D00B[3] = {&BuiltInVariable::kpt01a, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01a10D00D00D[4] = {&BuiltInVariable::kpt01a, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01a10D00E00E[4] = {&BuiltInVariable::kpt01a, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01b10D00D00B[4] = {&BuiltInVariable::kpt01b, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01b10D00D00D00D[5] = {
+ &BuiltInVariable::kpt01b, &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01b10D00D00E00E[5] = {
+ &BuiltInVariable::kpt01b, &BuiltInVariable::kpt10D, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01c20D00D00B[4] = {&BuiltInVariable::kpt01c, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01c20D00D00D00D[5] = {
+ &BuiltInVariable::kpt01c, &BuiltInVariable::kpt20D, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01c20D00D00E00E[5] = {
+ &BuiltInVariable::kpt01c, &BuiltInVariable::kpt20D, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01d20D00B[3] = {&BuiltInVariable::kpt01d, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01d20D00D00D[4] = {&BuiltInVariable::kpt01d, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01d20D00E00E[4] = {&BuiltInVariable::kpt01d, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01d20D30E[3] = {&BuiltInVariable::kpt01d, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt30E};
+constexpr const TVariable *p01e10D00B[3] = {&BuiltInVariable::kpt01e, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01e10D00D00D[4] = {&BuiltInVariable::kpt01e, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01e10D00E00E[4] = {&BuiltInVariable::kpt01e, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01f00D00B[3] = {&BuiltInVariable::kpt01f, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p01f00D00D00D[4] = {&BuiltInVariable::kpt01f, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01f00D00E00E[4] = {&BuiltInVariable::kpt01f, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+constexpr const TVariable *p01f00D30E[3] = {&BuiltInVariable::kpt01f, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt30E};
+constexpr const TVariable *p01g30B[2] = {&BuiltInVariable::kpt01g, &BuiltInVariable::kpt30B};
+constexpr const TVariable *p01h30D[2] = {&BuiltInVariable::kpt01h, &BuiltInVariable::kpt30D};
+constexpr const TVariable *p01i30E[2] = {&BuiltInVariable::kpt01i, &BuiltInVariable::kpt30E};
+constexpr const TVariable *p01j[1] = {&BuiltInVariable::kpt01j};
+constexpr const TVariable *p01k[1] = {&BuiltInVariable::kpt01k};
+constexpr const TVariable *p01l[1] = {&BuiltInVariable::kpt01l};
+constexpr const TVariable *p01m00D[2] = {&BuiltInVariable::kpt01m, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01n00D[2] = {&BuiltInVariable::kpt01n, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p01o00D[2] = {&BuiltInVariable::kpt01o, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p10B00B00B[3] = {&BuiltInVariable::kpt10B, &BuiltInVariable::kpt00B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p10B00D[2] = {&BuiltInVariable::kpt10B, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p10B10B00B[3] = {&BuiltInVariable::kpt10B, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p10B10B10B[3] = {&BuiltInVariable::kpt10B, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10B};
+constexpr const TVariable *p10B10B10F[3] = {&BuiltInVariable::kpt10B, &BuiltInVariable::kpt10B,
+ &BuiltInVariable::kpt10F};
+constexpr const TVariable *p10B10D[2] = {&BuiltInVariable::kpt10B, &BuiltInVariable::kpt10D};
+constexpr const TVariable *p10B20B[2] = {&BuiltInVariable::kpt10B, &BuiltInVariable::kpt20B};
+constexpr const TVariable *p10B30B[2] = {&BuiltInVariable::kpt10B, &BuiltInVariable::kpt30B};
+constexpr const TVariable *p10B_o_10B[2] = {&BuiltInVariable::kpt10B, &BuiltInVariable::kpt_o_10B};
+constexpr const TVariable *p10B_o_10D[2] = {&BuiltInVariable::kpt10B, &BuiltInVariable::kpt_o_10D};
+constexpr const TVariable *p10D00D00D[3] = {&BuiltInVariable::kpt10D, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p10D10D00D00D[4] = {&BuiltInVariable::kpt10D, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p10D10D10D[3] = {&BuiltInVariable::kpt10D, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt10D};
+constexpr const TVariable *p10D10D10F[3] = {&BuiltInVariable::kpt10D, &BuiltInVariable::kpt10D,
+ &BuiltInVariable::kpt10F};
+constexpr const TVariable *p10D10D_o_10D_o_10D[4] = {
+ &BuiltInVariable::kpt10D, &BuiltInVariable::kpt10D, &BuiltInVariable::kpt_o_10D,
+ &BuiltInVariable::kpt_o_10D};
+constexpr const TVariable *p10E00D00D[3] = {&BuiltInVariable::kpt10E, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p10E00E00E[3] = {&BuiltInVariable::kpt10E, &BuiltInVariable::kpt00E,
+ &BuiltInVariable::kpt00E};
+constexpr const TVariable *p10E10E00D00D[4] = {&BuiltInVariable::kpt10E, &BuiltInVariable::kpt10E,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p10E10E10E[3] = {&BuiltInVariable::kpt10E, &BuiltInVariable::kpt10E,
+ &BuiltInVariable::kpt10E};
+constexpr const TVariable *p10E10E10F[3] = {&BuiltInVariable::kpt10E, &BuiltInVariable::kpt10E,
+ &BuiltInVariable::kpt10F};
+constexpr const TVariable *p10E10E_o_10E_o_10E[4] = {
+ &BuiltInVariable::kpt10E, &BuiltInVariable::kpt10E, &BuiltInVariable::kpt_o_10E,
+ &BuiltInVariable::kpt_o_10E};
+constexpr const TVariable *p10F10F10F[3] = {&BuiltInVariable::kpt10F, &BuiltInVariable::kpt10F,
+ &BuiltInVariable::kpt10F};
+constexpr const TVariable *p20B00B00B[3] = {&BuiltInVariable::kpt20B, &BuiltInVariable::kpt00B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p20B00D[2] = {&BuiltInVariable::kpt20B, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p20B00H[2] = {&BuiltInVariable::kpt20B, &BuiltInVariable::kpt00H};
+constexpr const TVariable *p20B10B[2] = {&BuiltInVariable::kpt20B, &BuiltInVariable::kpt10B};
+constexpr const TVariable *p20B20B00B[3] = {&BuiltInVariable::kpt20B, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p20B20B20B[3] = {&BuiltInVariable::kpt20B, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt20B};
+constexpr const TVariable *p20B20B20F[3] = {&BuiltInVariable::kpt20B, &BuiltInVariable::kpt20B,
+ &BuiltInVariable::kpt20F};
+constexpr const TVariable *p20B20D[2] = {&BuiltInVariable::kpt20B, &BuiltInVariable::kpt20D};
+constexpr const TVariable *p20B30B[2] = {&BuiltInVariable::kpt20B, &BuiltInVariable::kpt30B};
+constexpr const TVariable *p20B_o_20B[2] = {&BuiltInVariable::kpt20B, &BuiltInVariable::kpt_o_20B};
+constexpr const TVariable *p20B_o_20D[2] = {&BuiltInVariable::kpt20B, &BuiltInVariable::kpt_o_20D};
+constexpr const TVariable *p20D00D00D[3] = {&BuiltInVariable::kpt20D, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p20D20D00D00D[4] = {&BuiltInVariable::kpt20D, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p20D20D20D[3] = {&BuiltInVariable::kpt20D, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt20D};
+constexpr const TVariable *p20D20D20F[3] = {&BuiltInVariable::kpt20D, &BuiltInVariable::kpt20D,
+ &BuiltInVariable::kpt20F};
+constexpr const TVariable *p20D20D_o_20D_o_20D[4] = {
+ &BuiltInVariable::kpt20D, &BuiltInVariable::kpt20D, &BuiltInVariable::kpt_o_20D,
+ &BuiltInVariable::kpt_o_20D};
+constexpr const TVariable *p20E00D00D[3] = {&BuiltInVariable::kpt20E, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p20E00E00E[3] = {&BuiltInVariable::kpt20E, &BuiltInVariable::kpt00E,
+ &BuiltInVariable::kpt00E};
+constexpr const TVariable *p20E20E00D00D[4] = {&BuiltInVariable::kpt20E, &BuiltInVariable::kpt20E,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p20E20E20E[3] = {&BuiltInVariable::kpt20E, &BuiltInVariable::kpt20E,
+ &BuiltInVariable::kpt20E};
+constexpr const TVariable *p20E20E20F[3] = {&BuiltInVariable::kpt20E, &BuiltInVariable::kpt20E,
+ &BuiltInVariable::kpt20F};
+constexpr const TVariable *p20E20E_o_20E_o_20E[4] = {
+ &BuiltInVariable::kpt20E, &BuiltInVariable::kpt20E, &BuiltInVariable::kpt_o_20E,
+ &BuiltInVariable::kpt_o_20E};
+constexpr const TVariable *p20F20F20F[3] = {&BuiltInVariable::kpt20F, &BuiltInVariable::kpt20F,
+ &BuiltInVariable::kpt20F};
+constexpr const TVariable *p30B00B00B[3] = {&BuiltInVariable::kpt30B, &BuiltInVariable::kpt00B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p30B00D[2] = {&BuiltInVariable::kpt30B, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p30B10B[2] = {&BuiltInVariable::kpt30B, &BuiltInVariable::kpt10B};
+constexpr const TVariable *p30B20B[2] = {&BuiltInVariable::kpt30B, &BuiltInVariable::kpt20B};
+constexpr const TVariable *p30B30B00B[3] = {&BuiltInVariable::kpt30B, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt00B};
+constexpr const TVariable *p30B30B30B[3] = {&BuiltInVariable::kpt30B, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt30B};
+constexpr const TVariable *p30B30B30F[3] = {&BuiltInVariable::kpt30B, &BuiltInVariable::kpt30B,
+ &BuiltInVariable::kpt30F};
+constexpr const TVariable *p30B30D[2] = {&BuiltInVariable::kpt30B, &BuiltInVariable::kpt30D};
+constexpr const TVariable *p30B_o_30B[2] = {&BuiltInVariable::kpt30B, &BuiltInVariable::kpt_o_30B};
+constexpr const TVariable *p30B_o_30D[2] = {&BuiltInVariable::kpt30B, &BuiltInVariable::kpt_o_30D};
+constexpr const TVariable *p30D00D00D[3] = {&BuiltInVariable::kpt30D, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p30D30D00D00D[4] = {&BuiltInVariable::kpt30D, &BuiltInVariable::kpt30D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p30D30D30D[3] = {&BuiltInVariable::kpt30D, &BuiltInVariable::kpt30D,
+ &BuiltInVariable::kpt30D};
+constexpr const TVariable *p30D30D30F[3] = {&BuiltInVariable::kpt30D, &BuiltInVariable::kpt30D,
+ &BuiltInVariable::kpt30F};
+constexpr const TVariable *p30D30D_o_30D_o_30D[4] = {
+ &BuiltInVariable::kpt30D, &BuiltInVariable::kpt30D, &BuiltInVariable::kpt_o_30D,
+ &BuiltInVariable::kpt_o_30D};
+constexpr const TVariable *p30E00D00D[3] = {&BuiltInVariable::kpt30E, &BuiltInVariable::kpt00D,
+ &BuiltInVariable::kpt00D};
+constexpr const TVariable *p30E00E00E[3] = {&BuiltInVariable::kpt30E, &BuiltInVariable::kpt00E,
+ &BuiltInVariable::kpt00E};
+constexpr const TVariable *p30E30E00D00D[4] = {&BuiltInVariable::kpt30E, &BuiltInVariable::kpt30E,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p30E30E30E[3] = {&BuiltInVariable::kpt30E, &BuiltInVariable::kpt30E,
+ &BuiltInVariable::kpt30E};
+constexpr const TVariable *p30E30E30F[3] = {&BuiltInVariable::kpt30E, &BuiltInVariable::kpt30E,
+ &BuiltInVariable::kpt30F};
+constexpr const TVariable *p30E30E_o_30E_o_30E[4] = {
+ &BuiltInVariable::kpt30E, &BuiltInVariable::kpt30E, &BuiltInVariable::kpt_o_30E,
+ &BuiltInVariable::kpt_o_30E};
+constexpr const TVariable *p30F30F30F[3] = {&BuiltInVariable::kpt30F, &BuiltInVariable::kpt30F,
+ &BuiltInVariable::kpt30F};
+constexpr const TVariable *p50B50B[2] = {&BuiltInVariable::kpt50B, &BuiltInVariable::kpt50B};
+constexpr const TVariable *p60B60B[2] = {&BuiltInVariable::kpt60B, &BuiltInVariable::kpt60B};
+constexpr const TVariable *p70B70B[2] = {&BuiltInVariable::kpt70B, &BuiltInVariable::kpt70B};
+constexpr const TVariable *p90B90B[2] = {&BuiltInVariable::kpt90B, &BuiltInVariable::kpt90B};
+constexpr const TVariable *pA0BA0B[2] = {&BuiltInVariable::kptA0B, &BuiltInVariable::kptA0B};
+constexpr const TVariable *pB0BB0B[2] = {&BuiltInVariable::kptB0B, &BuiltInVariable::kptB0B};
+constexpr const TVariable *pD0BD0B[2] = {&BuiltInVariable::kptD0B, &BuiltInVariable::kptD0B};
+constexpr const TVariable *pE0BE0B[2] = {&BuiltInVariable::kptE0B, &BuiltInVariable::kptE0B};
+constexpr const TVariable *pF0BF0B[2] = {&BuiltInVariable::kptF0B, &BuiltInVariable::kptF0B};
+constexpr const TVariable *p_io_00D00D00D[3] = {&BuiltInVariable::kpt_io_00D,
+ &BuiltInVariable::kpt00D, &BuiltInVariable::kpt00D};
+constexpr const TVariable *p_io_00E00E00E[3] = {&BuiltInVariable::kpt_io_00E,
+ &BuiltInVariable::kpt00E, &BuiltInVariable::kpt00E};
+
+} // namespace BuiltInParameters
+
+// TODO(oetuaho): Would be nice to make this a class instead of a namespace so that we could friend
+// this from TFunction. Now symbol constructors taking an id have to be public even though they're
+// not supposed to be accessible from outside of here. http://anglebug.com/2390
+namespace Func
+{
+
+constexpr const TFunction radians_00B(BuiltInId::radians_Float1,
+ BuiltInName::radians,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpRadians,
+ true);
+constexpr const TFunction radians_10B(BuiltInId::radians_Float2,
+ BuiltInName::radians,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpRadians,
+ true);
+constexpr const TFunction radians_20B(BuiltInId::radians_Float3,
+ BuiltInName::radians,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpRadians,
+ true);
+constexpr const TFunction radians_30B(BuiltInId::radians_Float4,
+ BuiltInName::radians,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpRadians,
+ true);
+constexpr const TFunction degrees_00B(BuiltInId::degrees_Float1,
+ BuiltInName::degrees,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpDegrees,
+ true);
+constexpr const TFunction degrees_10B(BuiltInId::degrees_Float2,
+ BuiltInName::degrees,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpDegrees,
+ true);
+constexpr const TFunction degrees_20B(BuiltInId::degrees_Float3,
+ BuiltInName::degrees,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpDegrees,
+ true);
+constexpr const TFunction degrees_30B(BuiltInId::degrees_Float4,
+ BuiltInName::degrees,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpDegrees,
+ true);
+constexpr const TFunction sin_00B(BuiltInId::sin_Float1,
+ BuiltInName::sin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpSin,
+ true);
+constexpr const TFunction sin_10B(BuiltInId::sin_Float2,
+ BuiltInName::sin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpSin,
+ true);
+constexpr const TFunction sin_20B(BuiltInId::sin_Float3,
+ BuiltInName::sin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpSin,
+ true);
+constexpr const TFunction sin_30B(BuiltInId::sin_Float4,
+ BuiltInName::sin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpSin,
+ true);
+constexpr const TFunction cos_00B(BuiltInId::cos_Float1,
+ BuiltInName::cos,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpCos,
+ true);
+constexpr const TFunction cos_10B(BuiltInId::cos_Float2,
+ BuiltInName::cos,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpCos,
+ true);
+constexpr const TFunction cos_20B(BuiltInId::cos_Float3,
+ BuiltInName::cos,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpCos,
+ true);
+constexpr const TFunction cos_30B(BuiltInId::cos_Float4,
+ BuiltInName::cos,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpCos,
+ true);
+constexpr const TFunction tan_00B(BuiltInId::tan_Float1,
+ BuiltInName::tan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTan,
+ true);
+constexpr const TFunction tan_10B(BuiltInId::tan_Float2,
+ BuiltInName::tan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpTan,
+ true);
+constexpr const TFunction tan_20B(BuiltInId::tan_Float3,
+ BuiltInName::tan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTan,
+ true);
+constexpr const TFunction tan_30B(BuiltInId::tan_Float4,
+ BuiltInName::tan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTan,
+ true);
+constexpr const TFunction asin_00B(BuiltInId::asin_Float1,
+ BuiltInName::asin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAsin,
+ true);
+constexpr const TFunction asin_10B(BuiltInId::asin_Float2,
+ BuiltInName::asin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpAsin,
+ true);
+constexpr const TFunction asin_20B(BuiltInId::asin_Float3,
+ BuiltInName::asin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpAsin,
+ true);
+constexpr const TFunction asin_30B(BuiltInId::asin_Float4,
+ BuiltInName::asin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpAsin,
+ true);
+constexpr const TFunction acos_00B(BuiltInId::acos_Float1,
+ BuiltInName::acos,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAcos,
+ true);
+constexpr const TFunction acos_10B(BuiltInId::acos_Float2,
+ BuiltInName::acos,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpAcos,
+ true);
+constexpr const TFunction acos_20B(BuiltInId::acos_Float3,
+ BuiltInName::acos,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpAcos,
+ true);
+constexpr const TFunction acos_30B(BuiltInId::acos_Float4,
+ BuiltInName::acos,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpAcos,
+ true);
+constexpr const TFunction atan_00B00B(BuiltInId::atan_Float1_Float1,
+ BuiltInName::atan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtan,
+ true);
+constexpr const TFunction atan_10B10B(BuiltInId::atan_Float2_Float2,
+ BuiltInName::atan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpAtan,
+ true);
+constexpr const TFunction atan_20B20B(BuiltInId::atan_Float3_Float3,
+ BuiltInName::atan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpAtan,
+ true);
+constexpr const TFunction atan_30B30B(BuiltInId::atan_Float4_Float4,
+ BuiltInName::atan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpAtan,
+ true);
+constexpr const TFunction atan_00B(BuiltInId::atan_Float1,
+ BuiltInName::atan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtan,
+ true);
+constexpr const TFunction atan_10B(BuiltInId::atan_Float2,
+ BuiltInName::atan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpAtan,
+ true);
+constexpr const TFunction atan_20B(BuiltInId::atan_Float3,
+ BuiltInName::atan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpAtan,
+ true);
+constexpr const TFunction atan_30B(BuiltInId::atan_Float4,
+ BuiltInName::atan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpAtan,
+ true);
+constexpr const TFunction sinh_00B(BuiltInId::sinh_Float1,
+ BuiltInName::sinh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpSinh,
+ true);
+constexpr const TFunction sinh_10B(BuiltInId::sinh_Float2,
+ BuiltInName::sinh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpSinh,
+ true);
+constexpr const TFunction sinh_20B(BuiltInId::sinh_Float3,
+ BuiltInName::sinh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpSinh,
+ true);
+constexpr const TFunction sinh_30B(BuiltInId::sinh_Float4,
+ BuiltInName::sinh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpSinh,
+ true);
+constexpr const TFunction cosh_00B(BuiltInId::cosh_Float1,
+ BuiltInName::cosh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpCosh,
+ true);
+constexpr const TFunction cosh_10B(BuiltInId::cosh_Float2,
+ BuiltInName::cosh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpCosh,
+ true);
+constexpr const TFunction cosh_20B(BuiltInId::cosh_Float3,
+ BuiltInName::cosh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpCosh,
+ true);
+constexpr const TFunction cosh_30B(BuiltInId::cosh_Float4,
+ BuiltInName::cosh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpCosh,
+ true);
+constexpr const TFunction tanh_00B(BuiltInId::tanh_Float1,
+ BuiltInName::tanh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTanh,
+ true);
+constexpr const TFunction tanh_10B(BuiltInId::tanh_Float2,
+ BuiltInName::tanh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpTanh,
+ true);
+constexpr const TFunction tanh_20B(BuiltInId::tanh_Float3,
+ BuiltInName::tanh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTanh,
+ true);
+constexpr const TFunction tanh_30B(BuiltInId::tanh_Float4,
+ BuiltInName::tanh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTanh,
+ true);
+constexpr const TFunction asinh_00B(BuiltInId::asinh_Float1,
+ BuiltInName::asinh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAsinh,
+ true);
+constexpr const TFunction asinh_10B(BuiltInId::asinh_Float2,
+ BuiltInName::asinh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpAsinh,
+ true);
+constexpr const TFunction asinh_20B(BuiltInId::asinh_Float3,
+ BuiltInName::asinh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpAsinh,
+ true);
+constexpr const TFunction asinh_30B(BuiltInId::asinh_Float4,
+ BuiltInName::asinh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpAsinh,
+ true);
+constexpr const TFunction acosh_00B(BuiltInId::acosh_Float1,
+ BuiltInName::acosh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAcosh,
+ true);
+constexpr const TFunction acosh_10B(BuiltInId::acosh_Float2,
+ BuiltInName::acosh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpAcosh,
+ true);
+constexpr const TFunction acosh_20B(BuiltInId::acosh_Float3,
+ BuiltInName::acosh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpAcosh,
+ true);
+constexpr const TFunction acosh_30B(BuiltInId::acosh_Float4,
+ BuiltInName::acosh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpAcosh,
+ true);
+constexpr const TFunction atanh_00B(BuiltInId::atanh_Float1,
+ BuiltInName::atanh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtanh,
+ true);
+constexpr const TFunction atanh_10B(BuiltInId::atanh_Float2,
+ BuiltInName::atanh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpAtanh,
+ true);
+constexpr const TFunction atanh_20B(BuiltInId::atanh_Float3,
+ BuiltInName::atanh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpAtanh,
+ true);
+constexpr const TFunction atanh_30B(BuiltInId::atanh_Float4,
+ BuiltInName::atanh,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpAtanh,
+ true);
+constexpr const TFunction pow_00B00B(BuiltInId::pow_Float1_Float1,
+ BuiltInName::pow,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpPow,
+ true);
+constexpr const TFunction pow_10B10B(BuiltInId::pow_Float2_Float2,
+ BuiltInName::pow,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpPow,
+ true);
+constexpr const TFunction pow_20B20B(BuiltInId::pow_Float3_Float3,
+ BuiltInName::pow,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpPow,
+ true);
+constexpr const TFunction pow_30B30B(BuiltInId::pow_Float4_Float4,
+ BuiltInName::pow,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpPow,
+ true);
+constexpr const TFunction exp_00B(BuiltInId::exp_Float1,
+ BuiltInName::exp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpExp,
+ true);
+constexpr const TFunction exp_10B(BuiltInId::exp_Float2,
+ BuiltInName::exp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpExp,
+ true);
+constexpr const TFunction exp_20B(BuiltInId::exp_Float3,
+ BuiltInName::exp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpExp,
+ true);
+constexpr const TFunction exp_30B(BuiltInId::exp_Float4,
+ BuiltInName::exp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpExp,
+ true);
+constexpr const TFunction log_00B(BuiltInId::log_Float1,
+ BuiltInName::log,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpLog,
+ true);
+constexpr const TFunction log_10B(BuiltInId::log_Float2,
+ BuiltInName::log,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpLog,
+ true);
+constexpr const TFunction log_20B(BuiltInId::log_Float3,
+ BuiltInName::log,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpLog,
+ true);
+constexpr const TFunction log_30B(BuiltInId::log_Float4,
+ BuiltInName::log,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpLog,
+ true);
+constexpr const TFunction exp2_00B(BuiltInId::exp2_Float1,
+ BuiltInName::exp2,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpExp2,
+ true);
+constexpr const TFunction exp2_10B(BuiltInId::exp2_Float2,
+ BuiltInName::exp2,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpExp2,
+ true);
+constexpr const TFunction exp2_20B(BuiltInId::exp2_Float3,
+ BuiltInName::exp2,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpExp2,
+ true);
+constexpr const TFunction exp2_30B(BuiltInId::exp2_Float4,
+ BuiltInName::exp2,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpExp2,
+ true);
+constexpr const TFunction log2_00B(BuiltInId::log2_Float1,
+ BuiltInName::log2,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpLog2,
+ true);
+constexpr const TFunction log2_10B(BuiltInId::log2_Float2,
+ BuiltInName::log2,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpLog2,
+ true);
+constexpr const TFunction log2_20B(BuiltInId::log2_Float3,
+ BuiltInName::log2,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpLog2,
+ true);
+constexpr const TFunction log2_30B(BuiltInId::log2_Float4,
+ BuiltInName::log2,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpLog2,
+ true);
+constexpr const TFunction sqrt_00B(BuiltInId::sqrt_Float1,
+ BuiltInName::sqrt,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpSqrt,
+ true);
+constexpr const TFunction sqrt_10B(BuiltInId::sqrt_Float2,
+ BuiltInName::sqrt,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpSqrt,
+ true);
+constexpr const TFunction sqrt_20B(BuiltInId::sqrt_Float3,
+ BuiltInName::sqrt,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpSqrt,
+ true);
+constexpr const TFunction sqrt_30B(BuiltInId::sqrt_Float4,
+ BuiltInName::sqrt,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpSqrt,
+ true);
+constexpr const TFunction inversesqrt_00B(
+ BuiltInId::inversesqrt_Float1,
+ BuiltInName::inversesqrt,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpInversesqrt,
+ true);
+constexpr const TFunction inversesqrt_10B(
+ BuiltInId::inversesqrt_Float2,
+ BuiltInName::inversesqrt,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpInversesqrt,
+ true);
+constexpr const TFunction inversesqrt_20B(
+ BuiltInId::inversesqrt_Float3,
+ BuiltInName::inversesqrt,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpInversesqrt,
+ true);
+constexpr const TFunction inversesqrt_30B(
+ BuiltInId::inversesqrt_Float4,
+ BuiltInName::inversesqrt,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpInversesqrt,
+ true);
+constexpr const TFunction abs_00B(BuiltInId::abs_Float1,
+ BuiltInName::abs,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAbs,
+ true);
+constexpr const TFunction abs_10B(BuiltInId::abs_Float2,
+ BuiltInName::abs,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpAbs,
+ true);
+constexpr const TFunction abs_20B(BuiltInId::abs_Float3,
+ BuiltInName::abs,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpAbs,
+ true);
+constexpr const TFunction abs_30B(BuiltInId::abs_Float4,
+ BuiltInName::abs,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpAbs,
+ true);
+constexpr const TFunction abs_00D(BuiltInId::abs_Int1,
+ BuiltInName::abs,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00D00D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAbs,
+ true);
+constexpr const TFunction abs_10D(BuiltInId::abs_Int2,
+ BuiltInName::abs,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpAbs,
+ true);
+constexpr const TFunction abs_20D(BuiltInId::abs_Int3,
+ BuiltInName::abs,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpAbs,
+ true);
+constexpr const TFunction abs_30D(BuiltInId::abs_Int4,
+ BuiltInName::abs,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpAbs,
+ true);
+constexpr const TFunction sign_00B(BuiltInId::sign_Float1,
+ BuiltInName::sign,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpSign,
+ true);
+constexpr const TFunction sign_10B(BuiltInId::sign_Float2,
+ BuiltInName::sign,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpSign,
+ true);
+constexpr const TFunction sign_20B(BuiltInId::sign_Float3,
+ BuiltInName::sign,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpSign,
+ true);
+constexpr const TFunction sign_30B(BuiltInId::sign_Float4,
+ BuiltInName::sign,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpSign,
+ true);
+constexpr const TFunction sign_00D(BuiltInId::sign_Int1,
+ BuiltInName::sign,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00D00D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpSign,
+ true);
+constexpr const TFunction sign_10D(BuiltInId::sign_Int2,
+ BuiltInName::sign,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpSign,
+ true);
+constexpr const TFunction sign_20D(BuiltInId::sign_Int3,
+ BuiltInName::sign,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpSign,
+ true);
+constexpr const TFunction sign_30D(BuiltInId::sign_Int4,
+ BuiltInName::sign,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpSign,
+ true);
+constexpr const TFunction floor_00B(BuiltInId::floor_Float1,
+ BuiltInName::floor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpFloor,
+ true);
+constexpr const TFunction floor_10B(BuiltInId::floor_Float2,
+ BuiltInName::floor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpFloor,
+ true);
+constexpr const TFunction floor_20B(BuiltInId::floor_Float3,
+ BuiltInName::floor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpFloor,
+ true);
+constexpr const TFunction floor_30B(BuiltInId::floor_Float4,
+ BuiltInName::floor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpFloor,
+ true);
+constexpr const TFunction trunc_00B(BuiltInId::trunc_Float1,
+ BuiltInName::trunc,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTrunc,
+ true);
+constexpr const TFunction trunc_10B(BuiltInId::trunc_Float2,
+ BuiltInName::trunc,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpTrunc,
+ true);
+constexpr const TFunction trunc_20B(BuiltInId::trunc_Float3,
+ BuiltInName::trunc,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTrunc,
+ true);
+constexpr const TFunction trunc_30B(BuiltInId::trunc_Float4,
+ BuiltInName::trunc,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTrunc,
+ true);
+constexpr const TFunction round_00B(BuiltInId::round_Float1,
+ BuiltInName::round,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpRound,
+ true);
+constexpr const TFunction round_10B(BuiltInId::round_Float2,
+ BuiltInName::round,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpRound,
+ true);
+constexpr const TFunction round_20B(BuiltInId::round_Float3,
+ BuiltInName::round,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpRound,
+ true);
+constexpr const TFunction round_30B(BuiltInId::round_Float4,
+ BuiltInName::round,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpRound,
+ true);
+constexpr const TFunction roundEven_00B(BuiltInId::roundEven_Float1,
+ BuiltInName::roundEven,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpRoundEven,
+ true);
+constexpr const TFunction roundEven_10B(BuiltInId::roundEven_Float2,
+ BuiltInName::roundEven,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpRoundEven,
+ true);
+constexpr const TFunction roundEven_20B(BuiltInId::roundEven_Float3,
+ BuiltInName::roundEven,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpRoundEven,
+ true);
+constexpr const TFunction roundEven_30B(BuiltInId::roundEven_Float4,
+ BuiltInName::roundEven,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpRoundEven,
+ true);
+constexpr const TFunction ceil_00B(BuiltInId::ceil_Float1,
+ BuiltInName::ceil,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpCeil,
+ true);
+constexpr const TFunction ceil_10B(BuiltInId::ceil_Float2,
+ BuiltInName::ceil,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpCeil,
+ true);
+constexpr const TFunction ceil_20B(BuiltInId::ceil_Float3,
+ BuiltInName::ceil,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpCeil,
+ true);
+constexpr const TFunction ceil_30B(BuiltInId::ceil_Float4,
+ BuiltInName::ceil,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpCeil,
+ true);
+constexpr const TFunction fract_00B(BuiltInId::fract_Float1,
+ BuiltInName::fract,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpFract,
+ true);
+constexpr const TFunction fract_10B(BuiltInId::fract_Float2,
+ BuiltInName::fract,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpFract,
+ true);
+constexpr const TFunction fract_20B(BuiltInId::fract_Float3,
+ BuiltInName::fract,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpFract,
+ true);
+constexpr const TFunction fract_30B(BuiltInId::fract_Float4,
+ BuiltInName::fract,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpFract,
+ true);
+constexpr const TFunction mod_00B00B(BuiltInId::mod_Float1_Float1,
+ BuiltInName::mod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpMod,
+ true);
+constexpr const TFunction mod_10B00B(BuiltInId::mod_Float2_Float1,
+ BuiltInName::mod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpMod,
+ true);
+constexpr const TFunction mod_20B00B(BuiltInId::mod_Float3_Float1,
+ BuiltInName::mod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpMod,
+ true);
+constexpr const TFunction mod_30B00B(BuiltInId::mod_Float4_Float1,
+ BuiltInName::mod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpMod,
+ true);
+constexpr const TFunction mod_10B10B(BuiltInId::mod_Float2_Float2,
+ BuiltInName::mod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpMod,
+ true);
+constexpr const TFunction mod_20B20B(BuiltInId::mod_Float3_Float3,
+ BuiltInName::mod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpMod,
+ true);
+constexpr const TFunction mod_30B30B(BuiltInId::mod_Float4_Float4,
+ BuiltInName::mod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpMod,
+ true);
+constexpr const TFunction min_00B00B(BuiltInId::min_Float1_Float1,
+ BuiltInName::min,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpMin,
+ true);
+constexpr const TFunction min_10B00B(BuiltInId::min_Float2_Float1,
+ BuiltInName::min,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpMin,
+ true);
+constexpr const TFunction min_20B00B(BuiltInId::min_Float3_Float1,
+ BuiltInName::min,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpMin,
+ true);
+constexpr const TFunction min_30B00B(BuiltInId::min_Float4_Float1,
+ BuiltInName::min,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpMin,
+ true);
+constexpr const TFunction min_10B10B(BuiltInId::min_Float2_Float2,
+ BuiltInName::min,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpMin,
+ true);
+constexpr const TFunction min_20B20B(BuiltInId::min_Float3_Float3,
+ BuiltInName::min,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpMin,
+ true);
+constexpr const TFunction min_30B30B(BuiltInId::min_Float4_Float4,
+ BuiltInName::min,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpMin,
+ true);
+constexpr const TFunction min_00D00D(BuiltInId::min_Int1_Int1,
+ BuiltInName::min,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00D00D00D00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpMin,
+ true);
+constexpr const TFunction min_10D10D(BuiltInId::min_Int2_Int2,
+ BuiltInName::min,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D10D00D00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpMin,
+ true);
+constexpr const TFunction min_20D20D(BuiltInId::min_Int3_Int3,
+ BuiltInName::min,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D20D00D00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpMin,
+ true);
+constexpr const TFunction min_30D30D(BuiltInId::min_Int4_Int4,
+ BuiltInName::min,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D30D00D00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpMin,
+ true);
+constexpr const TFunction min_10D00D(BuiltInId::min_Int2_Int1,
+ BuiltInName::min,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D00D00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpMin,
+ true);
+constexpr const TFunction min_20D00D(BuiltInId::min_Int3_Int1,
+ BuiltInName::min,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D00D00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpMin,
+ true);
+constexpr const TFunction min_30D00D(BuiltInId::min_Int4_Int1,
+ BuiltInName::min,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D00D00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpMin,
+ true);
+constexpr const TFunction min_00E00E(BuiltInId::min_UInt1_UInt1,
+ BuiltInName::min,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00E00E00D00D,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpMin,
+ true);
+constexpr const TFunction min_10E10E(BuiltInId::min_UInt2_UInt2,
+ BuiltInName::min,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E10E00D00D,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpMin,
+ true);
+constexpr const TFunction min_20E20E(BuiltInId::min_UInt3_UInt3,
+ BuiltInName::min,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E20E00D00D,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpMin,
+ true);
+constexpr const TFunction min_30E30E(BuiltInId::min_UInt4_UInt4,
+ BuiltInName::min,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E30E00D00D,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpMin,
+ true);
+constexpr const TFunction min_10E00E(BuiltInId::min_UInt2_UInt1,
+ BuiltInName::min,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E00E00E,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpMin,
+ true);
+constexpr const TFunction min_20E00E(BuiltInId::min_UInt3_UInt1,
+ BuiltInName::min,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E00E00E,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpMin,
+ true);
+constexpr const TFunction min_30E00E(BuiltInId::min_UInt4_UInt1,
+ BuiltInName::min,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E00E00E,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpMin,
+ true);
+constexpr const TFunction max_00B00B(BuiltInId::max_Float1_Float1,
+ BuiltInName::max,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpMax,
+ true);
+constexpr const TFunction max_10B00B(BuiltInId::max_Float2_Float1,
+ BuiltInName::max,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpMax,
+ true);
+constexpr const TFunction max_20B00B(BuiltInId::max_Float3_Float1,
+ BuiltInName::max,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpMax,
+ true);
+constexpr const TFunction max_30B00B(BuiltInId::max_Float4_Float1,
+ BuiltInName::max,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpMax,
+ true);
+constexpr const TFunction max_10B10B(BuiltInId::max_Float2_Float2,
+ BuiltInName::max,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpMax,
+ true);
+constexpr const TFunction max_20B20B(BuiltInId::max_Float3_Float3,
+ BuiltInName::max,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpMax,
+ true);
+constexpr const TFunction max_30B30B(BuiltInId::max_Float4_Float4,
+ BuiltInName::max,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpMax,
+ true);
+constexpr const TFunction max_00D00D(BuiltInId::max_Int1_Int1,
+ BuiltInName::max,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00D00D00D00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpMax,
+ true);
+constexpr const TFunction max_10D10D(BuiltInId::max_Int2_Int2,
+ BuiltInName::max,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D10D00D00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpMax,
+ true);
+constexpr const TFunction max_20D20D(BuiltInId::max_Int3_Int3,
+ BuiltInName::max,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D20D00D00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpMax,
+ true);
+constexpr const TFunction max_30D30D(BuiltInId::max_Int4_Int4,
+ BuiltInName::max,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D30D00D00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpMax,
+ true);
+constexpr const TFunction max_10D00D(BuiltInId::max_Int2_Int1,
+ BuiltInName::max,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D00D00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpMax,
+ true);
+constexpr const TFunction max_20D00D(BuiltInId::max_Int3_Int1,
+ BuiltInName::max,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D00D00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpMax,
+ true);
+constexpr const TFunction max_30D00D(BuiltInId::max_Int4_Int1,
+ BuiltInName::max,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D00D00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpMax,
+ true);
+constexpr const TFunction max_00E00E(BuiltInId::max_UInt1_UInt1,
+ BuiltInName::max,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00E00E00D00D,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpMax,
+ true);
+constexpr const TFunction max_10E10E(BuiltInId::max_UInt2_UInt2,
+ BuiltInName::max,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E10E00D00D,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpMax,
+ true);
+constexpr const TFunction max_20E20E(BuiltInId::max_UInt3_UInt3,
+ BuiltInName::max,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E20E00D00D,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpMax,
+ true);
+constexpr const TFunction max_30E30E(BuiltInId::max_UInt4_UInt4,
+ BuiltInName::max,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E30E00D00D,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpMax,
+ true);
+constexpr const TFunction max_10E00E(BuiltInId::max_UInt2_UInt1,
+ BuiltInName::max,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E00E00E,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpMax,
+ true);
+constexpr const TFunction max_20E00E(BuiltInId::max_UInt3_UInt1,
+ BuiltInName::max,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E00E00E,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpMax,
+ true);
+constexpr const TFunction max_30E00E(BuiltInId::max_UInt4_UInt1,
+ BuiltInName::max,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E00E00E,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpMax,
+ true);
+constexpr const TFunction clamp_00B00B00B(
+ BuiltInId::clamp_Float1_Float1_Float1,
+ BuiltInName::clamp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpClamp,
+ true);
+constexpr const TFunction clamp_10B00B00B(
+ BuiltInId::clamp_Float2_Float1_Float1,
+ BuiltInName::clamp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpClamp,
+ true);
+constexpr const TFunction clamp_20B00B00B(
+ BuiltInId::clamp_Float3_Float1_Float1,
+ BuiltInName::clamp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpClamp,
+ true);
+constexpr const TFunction clamp_30B00B00B(
+ BuiltInId::clamp_Float4_Float1_Float1,
+ BuiltInName::clamp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpClamp,
+ true);
+constexpr const TFunction clamp_10B10B10B(
+ BuiltInId::clamp_Float2_Float2_Float2,
+ BuiltInName::clamp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B10B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpClamp,
+ true);
+constexpr const TFunction clamp_20B20B20B(
+ BuiltInId::clamp_Float3_Float3_Float3,
+ BuiltInName::clamp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B20B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpClamp,
+ true);
+constexpr const TFunction clamp_30B30B30B(
+ BuiltInId::clamp_Float4_Float4_Float4,
+ BuiltInName::clamp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B30B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpClamp,
+ true);
+constexpr const TFunction clamp_00D00D00D(BuiltInId::clamp_Int1_Int1_Int1,
+ BuiltInName::clamp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00D00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpClamp,
+ true);
+constexpr const TFunction clamp_10D00D00D(BuiltInId::clamp_Int2_Int1_Int1,
+ BuiltInName::clamp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpClamp,
+ true);
+constexpr const TFunction clamp_20D00D00D(BuiltInId::clamp_Int3_Int1_Int1,
+ BuiltInName::clamp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpClamp,
+ true);
+constexpr const TFunction clamp_30D00D00D(BuiltInId::clamp_Int4_Int1_Int1,
+ BuiltInName::clamp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpClamp,
+ true);
+constexpr const TFunction clamp_10D10D10D(BuiltInId::clamp_Int2_Int2_Int2,
+ BuiltInName::clamp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D10D10D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpClamp,
+ true);
+constexpr const TFunction clamp_20D20D20D(BuiltInId::clamp_Int3_Int3_Int3,
+ BuiltInName::clamp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D20D20D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpClamp,
+ true);
+constexpr const TFunction clamp_30D30D30D(BuiltInId::clamp_Int4_Int4_Int4,
+ BuiltInName::clamp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D30D30D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpClamp,
+ true);
+constexpr const TFunction clamp_00E00E00E(BuiltInId::clamp_UInt1_UInt1_UInt1,
+ BuiltInName::clamp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00E00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpClamp,
+ true);
+constexpr const TFunction clamp_10E00E00E(BuiltInId::clamp_UInt2_UInt1_UInt1,
+ BuiltInName::clamp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpClamp,
+ true);
+constexpr const TFunction clamp_20E00E00E(BuiltInId::clamp_UInt3_UInt1_UInt1,
+ BuiltInName::clamp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpClamp,
+ true);
+constexpr const TFunction clamp_30E00E00E(BuiltInId::clamp_UInt4_UInt1_UInt1,
+ BuiltInName::clamp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpClamp,
+ true);
+constexpr const TFunction clamp_10E10E10E(BuiltInId::clamp_UInt2_UInt2_UInt2,
+ BuiltInName::clamp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E10E10E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpClamp,
+ true);
+constexpr const TFunction clamp_20E20E20E(BuiltInId::clamp_UInt3_UInt3_UInt3,
+ BuiltInName::clamp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E20E20E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpClamp,
+ true);
+constexpr const TFunction clamp_30E30E30E(BuiltInId::clamp_UInt4_UInt4_UInt4,
+ BuiltInName::clamp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E30E30E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpClamp,
+ true);
+constexpr const TFunction mix_00B00B00B(BuiltInId::mix_Float1_Float1_Float1,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_10B10B00B(BuiltInId::mix_Float2_Float2_Float1,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_20B20B00B(BuiltInId::mix_Float3_Float3_Float1,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_30B30B00B(BuiltInId::mix_Float4_Float4_Float1,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_10B10B10B(BuiltInId::mix_Float2_Float2_Float2,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B10B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_20B20B20B(BuiltInId::mix_Float3_Float3_Float3,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B20B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_30B30B30B(BuiltInId::mix_Float4_Float4_Float4,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B30B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_00B00B00F(BuiltInId::mix_Float1_Float1_Bool1,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00F,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_10B10B10F(BuiltInId::mix_Float2_Float2_Bool2,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B10F,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_20B20B20F(BuiltInId::mix_Float3_Float3_Bool3,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B20F,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_30B30B30F(BuiltInId::mix_Float4_Float4_Bool4,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B30F,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_00D00D00F(BuiltInId::mix_Int1_Int1_Bool1,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00D00D00F,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_10D10D10F(BuiltInId::mix_Int2_Int2_Bool2,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D10D10F,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_20D20D20F(BuiltInId::mix_Int3_Int3_Bool3,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D20D20F,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_30D30D30F(BuiltInId::mix_Int4_Int4_Bool4,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D30D30F,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_00E00E00F(BuiltInId::mix_UInt1_UInt1_Bool1,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00E00E00F,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_10E10E10F(BuiltInId::mix_UInt2_UInt2_Bool2,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E10E10F,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_20E20E20F(BuiltInId::mix_UInt3_UInt3_Bool3,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E20E20F,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_30E30E30F(BuiltInId::mix_UInt4_UInt4_Bool4,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E30E30F,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_00F00F00F(BuiltInId::mix_Bool1_Bool1_Bool1,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00F00F00F,
+ 3,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_10F10F10F(BuiltInId::mix_Bool2_Bool2_Bool2,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10F10F10F,
+ 3,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_20F20F20F(BuiltInId::mix_Bool3_Bool3_Bool3,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20F20F20F,
+ 3,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction mix_30F30F30F(BuiltInId::mix_Bool4_Bool4_Bool4,
+ BuiltInName::mix,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30F30F30F,
+ 3,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpMix,
+ true);
+constexpr const TFunction step_00B00B(BuiltInId::step_Float1_Float1,
+ BuiltInName::step,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpStep,
+ true);
+constexpr const TFunction step_10B10B(BuiltInId::step_Float2_Float2,
+ BuiltInName::step,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpStep,
+ true);
+constexpr const TFunction step_20B20B(BuiltInId::step_Float3_Float3,
+ BuiltInName::step,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpStep,
+ true);
+constexpr const TFunction step_30B30B(BuiltInId::step_Float4_Float4,
+ BuiltInName::step,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpStep,
+ true);
+constexpr const TFunction step_00B10B(BuiltInId::step_Float1_Float2,
+ BuiltInName::step,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B10B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpStep,
+ true);
+constexpr const TFunction step_00B20B(BuiltInId::step_Float1_Float3,
+ BuiltInName::step,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B20B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpStep,
+ true);
+constexpr const TFunction step_00B30B(BuiltInId::step_Float1_Float4,
+ BuiltInName::step,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B30B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpStep,
+ true);
+constexpr const TFunction smoothstep_00B00B00B(
+ BuiltInId::smoothstep_Float1_Float1_Float1,
+ BuiltInName::smoothstep,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpSmoothstep,
+ true);
+constexpr const TFunction smoothstep_10B10B10B(
+ BuiltInId::smoothstep_Float2_Float2_Float2,
+ BuiltInName::smoothstep,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B10B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpSmoothstep,
+ true);
+constexpr const TFunction smoothstep_20B20B20B(
+ BuiltInId::smoothstep_Float3_Float3_Float3,
+ BuiltInName::smoothstep,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B20B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpSmoothstep,
+ true);
+constexpr const TFunction smoothstep_30B30B30B(
+ BuiltInId::smoothstep_Float4_Float4_Float4,
+ BuiltInName::smoothstep,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B30B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpSmoothstep,
+ true);
+constexpr const TFunction smoothstep_00B00B10B(
+ BuiltInId::smoothstep_Float1_Float1_Float2,
+ BuiltInName::smoothstep,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B10B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpSmoothstep,
+ true);
+constexpr const TFunction smoothstep_00B00B20B(
+ BuiltInId::smoothstep_Float1_Float1_Float3,
+ BuiltInName::smoothstep,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B20B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpSmoothstep,
+ true);
+constexpr const TFunction smoothstep_00B00B30B(
+ BuiltInId::smoothstep_Float1_Float1_Float4,
+ BuiltInName::smoothstep,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B30B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpSmoothstep,
+ true);
+constexpr const TFunction modf_00B00B(BuiltInId::modf_Float1_Float1,
+ BuiltInName::modf,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B_o_00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpModf,
+ false);
+constexpr const TFunction modf_10B10B(BuiltInId::modf_Float2_Float2,
+ BuiltInName::modf,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B_o_10B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpModf,
+ false);
+constexpr const TFunction modf_20B20B(BuiltInId::modf_Float3_Float3,
+ BuiltInName::modf,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B_o_20B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpModf,
+ false);
+constexpr const TFunction modf_30B30B(BuiltInId::modf_Float4_Float4,
+ BuiltInName::modf,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B_o_30B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpModf,
+ false);
+constexpr const TFunction isnan_00B(BuiltInId::isnan_Float1,
+ BuiltInName::isnan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpIsnan,
+ true);
+constexpr const TFunction isnan_10B(BuiltInId::isnan_Float2,
+ BuiltInName::isnan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpIsnan,
+ true);
+constexpr const TFunction isnan_20B(BuiltInId::isnan_Float3,
+ BuiltInName::isnan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpIsnan,
+ true);
+constexpr const TFunction isnan_30B(BuiltInId::isnan_Float4,
+ BuiltInName::isnan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpIsnan,
+ true);
+constexpr const TFunction isinf_00B(BuiltInId::isinf_Float1,
+ BuiltInName::isinf,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpIsinf,
+ true);
+constexpr const TFunction isinf_10B(BuiltInId::isinf_Float2,
+ BuiltInName::isinf,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpIsinf,
+ true);
+constexpr const TFunction isinf_20B(BuiltInId::isinf_Float3,
+ BuiltInName::isinf,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpIsinf,
+ true);
+constexpr const TFunction isinf_30B(BuiltInId::isinf_Float4,
+ BuiltInName::isinf,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpIsinf,
+ true);
+constexpr const TFunction floatBitsToInt_00B(
+ BuiltInId::floatBitsToInt_Float1,
+ BuiltInName::floatBitsToInt,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpFloatBitsToInt,
+ true);
+constexpr const TFunction floatBitsToInt_10B(
+ BuiltInId::floatBitsToInt_Float2,
+ BuiltInName::floatBitsToInt,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpFloatBitsToInt,
+ true);
+constexpr const TFunction floatBitsToInt_20B(
+ BuiltInId::floatBitsToInt_Float3,
+ BuiltInName::floatBitsToInt,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpFloatBitsToInt,
+ true);
+constexpr const TFunction floatBitsToInt_30B(
+ BuiltInId::floatBitsToInt_Float4,
+ BuiltInName::floatBitsToInt,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpFloatBitsToInt,
+ true);
+constexpr const TFunction floatBitsToUint_00B(
+ BuiltInId::floatBitsToUint_Float1,
+ BuiltInName::floatBitsToUint,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpFloatBitsToUint,
+ true);
+constexpr const TFunction floatBitsToUint_10B(
+ BuiltInId::floatBitsToUint_Float2,
+ BuiltInName::floatBitsToUint,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpFloatBitsToUint,
+ true);
+constexpr const TFunction floatBitsToUint_20B(
+ BuiltInId::floatBitsToUint_Float3,
+ BuiltInName::floatBitsToUint,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpFloatBitsToUint,
+ true);
+constexpr const TFunction floatBitsToUint_30B(
+ BuiltInId::floatBitsToUint_Float4,
+ BuiltInName::floatBitsToUint,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpFloatBitsToUint,
+ true);
+constexpr const TFunction intBitsToFloat_00D(
+ BuiltInId::intBitsToFloat_Int1,
+ BuiltInName::intBitsToFloat,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00D00D00D00D,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpIntBitsToFloat,
+ true);
+constexpr const TFunction intBitsToFloat_10D(
+ BuiltInId::intBitsToFloat_Int2,
+ BuiltInName::intBitsToFloat,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D00D00D,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpIntBitsToFloat,
+ true);
+constexpr const TFunction intBitsToFloat_20D(
+ BuiltInId::intBitsToFloat_Int3,
+ BuiltInName::intBitsToFloat,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D00D00D,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpIntBitsToFloat,
+ true);
+constexpr const TFunction intBitsToFloat_30D(
+ BuiltInId::intBitsToFloat_Int4,
+ BuiltInName::intBitsToFloat,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D00D00D,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpIntBitsToFloat,
+ true);
+constexpr const TFunction uintBitsToFloat_00E(
+ BuiltInId::uintBitsToFloat_UInt1,
+ BuiltInName::uintBitsToFloat,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00E00D00D,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpUintBitsToFloat,
+ true);
+constexpr const TFunction uintBitsToFloat_10E(
+ BuiltInId::uintBitsToFloat_UInt2,
+ BuiltInName::uintBitsToFloat,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E00D00D,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpUintBitsToFloat,
+ true);
+constexpr const TFunction uintBitsToFloat_20E(
+ BuiltInId::uintBitsToFloat_UInt3,
+ BuiltInName::uintBitsToFloat,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E00D00D,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpUintBitsToFloat,
+ true);
+constexpr const TFunction uintBitsToFloat_30E(
+ BuiltInId::uintBitsToFloat_UInt4,
+ BuiltInName::uintBitsToFloat,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E00D00D,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpUintBitsToFloat,
+ true);
+constexpr const TFunction fma_00B00B00B(BuiltInId::fma_Float1_Float1_Float1,
+ BuiltInName::fma,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpFma,
+ true);
+constexpr const TFunction fma_10B10B10B(BuiltInId::fma_Float2_Float2_Float2,
+ BuiltInName::fma,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B10B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpFma,
+ true);
+constexpr const TFunction fma_20B20B20B(BuiltInId::fma_Float3_Float3_Float3,
+ BuiltInName::fma,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B20B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpFma,
+ true);
+constexpr const TFunction fma_30B30B30B(BuiltInId::fma_Float4_Float4_Float4,
+ BuiltInName::fma,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B30B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpFma,
+ true);
+constexpr const TFunction fmaExt_00B00B00B(
+ BuiltInId::fmaExt_Float1_Float1_Float1,
+ BuiltInName::fmaExt,
+ std::array<TExtension, 1u>{{TExtension::EXT_gpu_shader5}},
+ BuiltInParameters::p00B00B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpFma,
+ true);
+constexpr const TFunction fmaExt_10B10B10B(
+ BuiltInId::fmaExt_Float2_Float2_Float2,
+ BuiltInName::fmaExt,
+ std::array<TExtension, 1u>{{TExtension::EXT_gpu_shader5}},
+ BuiltInParameters::p10B10B10B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpFma,
+ true);
+constexpr const TFunction fmaExt_20B20B20B(
+ BuiltInId::fmaExt_Float3_Float3_Float3,
+ BuiltInName::fmaExt,
+ std::array<TExtension, 1u>{{TExtension::EXT_gpu_shader5}},
+ BuiltInParameters::p20B20B20B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpFma,
+ true);
+constexpr const TFunction fmaExt_30B30B30B(
+ BuiltInId::fmaExt_Float4_Float4_Float4,
+ BuiltInName::fmaExt,
+ std::array<TExtension, 1u>{{TExtension::EXT_gpu_shader5}},
+ BuiltInParameters::p30B30B30B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpFma,
+ true);
+constexpr const TFunction frexp_00B00D(BuiltInId::frexp_Float1_Int1,
+ BuiltInName::frexp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B_o_00D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpFrexp,
+ false);
+constexpr const TFunction frexp_10B10D(BuiltInId::frexp_Float2_Int2,
+ BuiltInName::frexp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B_o_10D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpFrexp,
+ false);
+constexpr const TFunction frexp_20B20D(BuiltInId::frexp_Float3_Int3,
+ BuiltInName::frexp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B_o_20D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpFrexp,
+ false);
+constexpr const TFunction frexp_30B30D(BuiltInId::frexp_Float4_Int4,
+ BuiltInName::frexp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B_o_30D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpFrexp,
+ false);
+constexpr const TFunction ldexp_00B00D(BuiltInId::ldexp_Float1_Int1,
+ BuiltInName::ldexp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpLdexp,
+ true);
+constexpr const TFunction ldexp_10B10D(BuiltInId::ldexp_Float2_Int2,
+ BuiltInName::ldexp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpLdexp,
+ true);
+constexpr const TFunction ldexp_20B20D(BuiltInId::ldexp_Float3_Int3,
+ BuiltInName::ldexp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpLdexp,
+ true);
+constexpr const TFunction ldexp_30B30D(BuiltInId::ldexp_Float4_Int4,
+ BuiltInName::ldexp,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpLdexp,
+ true);
+constexpr const TFunction packSnorm2x16_10B(
+ BuiltInId::packSnorm2x16_Float2,
+ BuiltInName::packSnorm2x16,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpPackSnorm2x16,
+ true);
+constexpr const TFunction packHalf2x16_10B(
+ BuiltInId::packHalf2x16_Float2,
+ BuiltInName::packHalf2x16,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpPackHalf2x16,
+ true);
+constexpr const TFunction unpackSnorm2x16_00E(
+ BuiltInId::unpackSnorm2x16_UInt1,
+ BuiltInName::unpackSnorm2x16,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00E00D00D,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpUnpackSnorm2x16,
+ true);
+constexpr const TFunction unpackHalf2x16_00E(
+ BuiltInId::unpackHalf2x16_UInt1,
+ BuiltInName::unpackHalf2x16,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00E00D00D,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpUnpackHalf2x16,
+ true);
+constexpr const TFunction packUnorm2x16_10B(
+ BuiltInId::packUnorm2x16_Float2,
+ BuiltInName::packUnorm2x16,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpPackUnorm2x16,
+ true);
+constexpr const TFunction unpackUnorm2x16_00E(
+ BuiltInId::unpackUnorm2x16_UInt1,
+ BuiltInName::unpackUnorm2x16,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00E00D00D,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpUnpackUnorm2x16,
+ true);
+constexpr const TFunction packUnorm4x8_30B(
+ BuiltInId::packUnorm4x8_Float4,
+ BuiltInName::packUnorm4x8,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpPackUnorm4x8,
+ true);
+constexpr const TFunction packSnorm4x8_30B(
+ BuiltInId::packSnorm4x8_Float4,
+ BuiltInName::packSnorm4x8,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpPackSnorm4x8,
+ true);
+constexpr const TFunction unpackUnorm4x8_00E(
+ BuiltInId::unpackUnorm4x8_UInt1,
+ BuiltInName::unpackUnorm4x8,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00E00D00D,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpUnpackUnorm4x8,
+ true);
+constexpr const TFunction unpackSnorm4x8_00E(
+ BuiltInId::unpackSnorm4x8_UInt1,
+ BuiltInName::unpackSnorm4x8,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00E00D00D,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpUnpackSnorm4x8,
+ true);
+constexpr const TFunction length_00B(BuiltInId::length_Float1,
+ BuiltInName::length,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpLength,
+ true);
+constexpr const TFunction length_10B(BuiltInId::length_Float2,
+ BuiltInName::length,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpLength,
+ true);
+constexpr const TFunction length_20B(BuiltInId::length_Float3,
+ BuiltInName::length,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpLength,
+ true);
+constexpr const TFunction length_30B(BuiltInId::length_Float4,
+ BuiltInName::length,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpLength,
+ true);
+constexpr const TFunction distance_00B00B(
+ BuiltInId::distance_Float1_Float1,
+ BuiltInName::distance,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpDistance,
+ true);
+constexpr const TFunction distance_10B10B(
+ BuiltInId::distance_Float2_Float2,
+ BuiltInName::distance,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpDistance,
+ true);
+constexpr const TFunction distance_20B20B(
+ BuiltInId::distance_Float3_Float3,
+ BuiltInName::distance,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpDistance,
+ true);
+constexpr const TFunction distance_30B30B(
+ BuiltInId::distance_Float4_Float4,
+ BuiltInName::distance,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpDistance,
+ true);
+constexpr const TFunction dot_00B00B(BuiltInId::dot_Float1_Float1,
+ BuiltInName::dot,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpDot,
+ true);
+constexpr const TFunction dot_10B10B(BuiltInId::dot_Float2_Float2,
+ BuiltInName::dot,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpDot,
+ true);
+constexpr const TFunction dot_20B20B(BuiltInId::dot_Float3_Float3,
+ BuiltInName::dot,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpDot,
+ true);
+constexpr const TFunction dot_30B30B(BuiltInId::dot_Float4_Float4,
+ BuiltInName::dot,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpDot,
+ true);
+constexpr const TFunction cross_20B20B(BuiltInId::cross_Float3_Float3,
+ BuiltInName::cross,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpCross,
+ true);
+constexpr const TFunction normalize_00B(BuiltInId::normalize_Float1,
+ BuiltInName::normalize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpNormalize,
+ true);
+constexpr const TFunction normalize_10B(BuiltInId::normalize_Float2,
+ BuiltInName::normalize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpNormalize,
+ true);
+constexpr const TFunction normalize_20B(BuiltInId::normalize_Float3,
+ BuiltInName::normalize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpNormalize,
+ true);
+constexpr const TFunction normalize_30B(BuiltInId::normalize_Float4,
+ BuiltInName::normalize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpNormalize,
+ true);
+constexpr const TFunction faceforward_00B00B00B(
+ BuiltInId::faceforward_Float1_Float1_Float1,
+ BuiltInName::faceforward,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpFaceforward,
+ true);
+constexpr const TFunction faceforward_10B10B10B(
+ BuiltInId::faceforward_Float2_Float2_Float2,
+ BuiltInName::faceforward,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B10B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpFaceforward,
+ true);
+constexpr const TFunction faceforward_20B20B20B(
+ BuiltInId::faceforward_Float3_Float3_Float3,
+ BuiltInName::faceforward,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B20B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpFaceforward,
+ true);
+constexpr const TFunction faceforward_30B30B30B(
+ BuiltInId::faceforward_Float4_Float4_Float4,
+ BuiltInName::faceforward,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B30B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpFaceforward,
+ true);
+constexpr const TFunction reflect_00B00B(BuiltInId::reflect_Float1_Float1,
+ BuiltInName::reflect,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpReflect,
+ true);
+constexpr const TFunction reflect_10B10B(BuiltInId::reflect_Float2_Float2,
+ BuiltInName::reflect,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpReflect,
+ true);
+constexpr const TFunction reflect_20B20B(BuiltInId::reflect_Float3_Float3,
+ BuiltInName::reflect,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpReflect,
+ true);
+constexpr const TFunction reflect_30B30B(BuiltInId::reflect_Float4_Float4,
+ BuiltInName::reflect,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpReflect,
+ true);
+constexpr const TFunction refract_00B00B00B(
+ BuiltInId::refract_Float1_Float1_Float1,
+ BuiltInName::refract,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpRefract,
+ true);
+constexpr const TFunction refract_10B10B00B(
+ BuiltInId::refract_Float2_Float2_Float1,
+ BuiltInName::refract,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpRefract,
+ true);
+constexpr const TFunction refract_20B20B00B(
+ BuiltInId::refract_Float3_Float3_Float1,
+ BuiltInName::refract,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpRefract,
+ true);
+constexpr const TFunction refract_30B30B00B(
+ BuiltInId::refract_Float4_Float4_Float1,
+ BuiltInName::refract,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpRefract,
+ true);
+constexpr const TFunction matrixCompMult_50B50B(
+ BuiltInId::matrixCompMult_Float2x2_Float2x2,
+ BuiltInName::matrixCompMult,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p50B50B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 2>(),
+ EOpMatrixCompMult,
+ true);
+constexpr const TFunction matrixCompMult_A0BA0B(
+ BuiltInId::matrixCompMult_Float3x3_Float3x3,
+ BuiltInName::matrixCompMult,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::pA0BA0B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 3>(),
+ EOpMatrixCompMult,
+ true);
+constexpr const TFunction matrixCompMult_F0BF0B(
+ BuiltInId::matrixCompMult_Float4x4_Float4x4,
+ BuiltInName::matrixCompMult,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::pF0BF0B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 4>(),
+ EOpMatrixCompMult,
+ true);
+constexpr const TFunction matrixCompMult_90B90B(
+ BuiltInId::matrixCompMult_Float2x3_Float2x3,
+ BuiltInName::matrixCompMult,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p90B90B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 3>(),
+ EOpMatrixCompMult,
+ true);
+constexpr const TFunction matrixCompMult_60B60B(
+ BuiltInId::matrixCompMult_Float3x2_Float3x2,
+ BuiltInName::matrixCompMult,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p60B60B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 2>(),
+ EOpMatrixCompMult,
+ true);
+constexpr const TFunction matrixCompMult_D0BD0B(
+ BuiltInId::matrixCompMult_Float2x4_Float2x4,
+ BuiltInName::matrixCompMult,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::pD0BD0B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 4>(),
+ EOpMatrixCompMult,
+ true);
+constexpr const TFunction matrixCompMult_70B70B(
+ BuiltInId::matrixCompMult_Float4x2_Float4x2,
+ BuiltInName::matrixCompMult,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p70B70B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 2>(),
+ EOpMatrixCompMult,
+ true);
+constexpr const TFunction matrixCompMult_E0BE0B(
+ BuiltInId::matrixCompMult_Float3x4_Float3x4,
+ BuiltInName::matrixCompMult,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::pE0BE0B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 4>(),
+ EOpMatrixCompMult,
+ true);
+constexpr const TFunction matrixCompMult_B0BB0B(
+ BuiltInId::matrixCompMult_Float4x3_Float4x3,
+ BuiltInName::matrixCompMult,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::pB0BB0B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 3>(),
+ EOpMatrixCompMult,
+ true);
+constexpr const TFunction outerProduct_10B10B(
+ BuiltInId::outerProduct_Float2_Float2,
+ BuiltInName::outerProduct,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 2>(),
+ EOpOuterProduct,
+ true);
+constexpr const TFunction outerProduct_20B20B(
+ BuiltInId::outerProduct_Float3_Float3,
+ BuiltInName::outerProduct,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 3>(),
+ EOpOuterProduct,
+ true);
+constexpr const TFunction outerProduct_30B30B(
+ BuiltInId::outerProduct_Float4_Float4,
+ BuiltInName::outerProduct,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 4>(),
+ EOpOuterProduct,
+ true);
+constexpr const TFunction outerProduct_20B10B(
+ BuiltInId::outerProduct_Float3_Float2,
+ BuiltInName::outerProduct,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B10B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 3>(),
+ EOpOuterProduct,
+ true);
+constexpr const TFunction outerProduct_10B20B(
+ BuiltInId::outerProduct_Float2_Float3,
+ BuiltInName::outerProduct,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B20B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 2>(),
+ EOpOuterProduct,
+ true);
+constexpr const TFunction outerProduct_30B10B(
+ BuiltInId::outerProduct_Float4_Float2,
+ BuiltInName::outerProduct,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B10B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 4>(),
+ EOpOuterProduct,
+ true);
+constexpr const TFunction outerProduct_10B30B(
+ BuiltInId::outerProduct_Float2_Float4,
+ BuiltInName::outerProduct,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B30B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 2>(),
+ EOpOuterProduct,
+ true);
+constexpr const TFunction outerProduct_30B20B(
+ BuiltInId::outerProduct_Float4_Float3,
+ BuiltInName::outerProduct,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B20B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 4>(),
+ EOpOuterProduct,
+ true);
+constexpr const TFunction outerProduct_20B30B(
+ BuiltInId::outerProduct_Float3_Float4,
+ BuiltInName::outerProduct,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B30B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 3>(),
+ EOpOuterProduct,
+ true);
+constexpr const TFunction transpose_50B(BuiltInId::transpose_Float2x2,
+ BuiltInName::transpose,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p50B50B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 2>(),
+ EOpTranspose,
+ true);
+constexpr const TFunction transpose_A0B(BuiltInId::transpose_Float3x3,
+ BuiltInName::transpose,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::pA0BA0B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 3>(),
+ EOpTranspose,
+ true);
+constexpr const TFunction transpose_F0B(BuiltInId::transpose_Float4x4,
+ BuiltInName::transpose,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::pF0BF0B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 4>(),
+ EOpTranspose,
+ true);
+constexpr const TFunction transpose_60B(BuiltInId::transpose_Float3x2,
+ BuiltInName::transpose,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p60B60B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 3>(),
+ EOpTranspose,
+ true);
+constexpr const TFunction transpose_90B(BuiltInId::transpose_Float2x3,
+ BuiltInName::transpose,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p90B90B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 2>(),
+ EOpTranspose,
+ true);
+constexpr const TFunction transpose_70B(BuiltInId::transpose_Float4x2,
+ BuiltInName::transpose,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p70B70B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 4>(),
+ EOpTranspose,
+ true);
+constexpr const TFunction transpose_D0B(BuiltInId::transpose_Float2x4,
+ BuiltInName::transpose,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::pD0BD0B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 2>(),
+ EOpTranspose,
+ true);
+constexpr const TFunction transpose_B0B(BuiltInId::transpose_Float4x3,
+ BuiltInName::transpose,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::pB0BB0B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 4>(),
+ EOpTranspose,
+ true);
+constexpr const TFunction transpose_E0B(BuiltInId::transpose_Float3x4,
+ BuiltInName::transpose,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::pE0BE0B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 3>(),
+ EOpTranspose,
+ true);
+constexpr const TFunction determinant_50B(
+ BuiltInId::determinant_Float2x2,
+ BuiltInName::determinant,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p50B50B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpDeterminant,
+ true);
+constexpr const TFunction determinant_A0B(
+ BuiltInId::determinant_Float3x3,
+ BuiltInName::determinant,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::pA0BA0B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpDeterminant,
+ true);
+constexpr const TFunction determinant_F0B(
+ BuiltInId::determinant_Float4x4,
+ BuiltInName::determinant,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::pF0BF0B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpDeterminant,
+ true);
+constexpr const TFunction inverse_50B(BuiltInId::inverse_Float2x2,
+ BuiltInName::inverse,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p50B50B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 2>(),
+ EOpInverse,
+ true);
+constexpr const TFunction inverse_A0B(BuiltInId::inverse_Float3x3,
+ BuiltInName::inverse,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::pA0BA0B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 3>(),
+ EOpInverse,
+ true);
+constexpr const TFunction inverse_F0B(BuiltInId::inverse_Float4x4,
+ BuiltInName::inverse,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::pF0BF0B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 4>(),
+ EOpInverse,
+ true);
+constexpr const TFunction lessThan_10B10B(BuiltInId::lessThan_Float2_Float2,
+ BuiltInName::lessThan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B00B,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpLessThanComponentWise,
+ true);
+constexpr const TFunction lessThan_20B20B(BuiltInId::lessThan_Float3_Float3,
+ BuiltInName::lessThan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B00B,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpLessThanComponentWise,
+ true);
+constexpr const TFunction lessThan_30B30B(BuiltInId::lessThan_Float4_Float4,
+ BuiltInName::lessThan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B00B,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpLessThanComponentWise,
+ true);
+constexpr const TFunction lessThan_10D10D(BuiltInId::lessThan_Int2_Int2,
+ BuiltInName::lessThan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D10D00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpLessThanComponentWise,
+ true);
+constexpr const TFunction lessThan_20D20D(BuiltInId::lessThan_Int3_Int3,
+ BuiltInName::lessThan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D20D00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpLessThanComponentWise,
+ true);
+constexpr const TFunction lessThan_30D30D(BuiltInId::lessThan_Int4_Int4,
+ BuiltInName::lessThan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D30D00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpLessThanComponentWise,
+ true);
+constexpr const TFunction lessThan_10E10E(BuiltInId::lessThan_UInt2_UInt2,
+ BuiltInName::lessThan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E10E00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpLessThanComponentWise,
+ true);
+constexpr const TFunction lessThan_20E20E(BuiltInId::lessThan_UInt3_UInt3,
+ BuiltInName::lessThan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E20E00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpLessThanComponentWise,
+ true);
+constexpr const TFunction lessThan_30E30E(BuiltInId::lessThan_UInt4_UInt4,
+ BuiltInName::lessThan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E30E00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpLessThanComponentWise,
+ true);
+constexpr const TFunction lessThanEqual_10B10B(
+ BuiltInId::lessThanEqual_Float2_Float2,
+ BuiltInName::lessThanEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B00B,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpLessThanEqualComponentWise,
+ true);
+constexpr const TFunction lessThanEqual_20B20B(
+ BuiltInId::lessThanEqual_Float3_Float3,
+ BuiltInName::lessThanEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B00B,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpLessThanEqualComponentWise,
+ true);
+constexpr const TFunction lessThanEqual_30B30B(
+ BuiltInId::lessThanEqual_Float4_Float4,
+ BuiltInName::lessThanEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B00B,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpLessThanEqualComponentWise,
+ true);
+constexpr const TFunction lessThanEqual_10D10D(
+ BuiltInId::lessThanEqual_Int2_Int2,
+ BuiltInName::lessThanEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D10D00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpLessThanEqualComponentWise,
+ true);
+constexpr const TFunction lessThanEqual_20D20D(
+ BuiltInId::lessThanEqual_Int3_Int3,
+ BuiltInName::lessThanEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D20D00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpLessThanEqualComponentWise,
+ true);
+constexpr const TFunction lessThanEqual_30D30D(
+ BuiltInId::lessThanEqual_Int4_Int4,
+ BuiltInName::lessThanEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D30D00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpLessThanEqualComponentWise,
+ true);
+constexpr const TFunction lessThanEqual_10E10E(
+ BuiltInId::lessThanEqual_UInt2_UInt2,
+ BuiltInName::lessThanEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E10E00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpLessThanEqualComponentWise,
+ true);
+constexpr const TFunction lessThanEqual_20E20E(
+ BuiltInId::lessThanEqual_UInt3_UInt3,
+ BuiltInName::lessThanEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E20E00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpLessThanEqualComponentWise,
+ true);
+constexpr const TFunction lessThanEqual_30E30E(
+ BuiltInId::lessThanEqual_UInt4_UInt4,
+ BuiltInName::lessThanEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E30E00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpLessThanEqualComponentWise,
+ true);
+constexpr const TFunction greaterThan_10B10B(
+ BuiltInId::greaterThan_Float2_Float2,
+ BuiltInName::greaterThan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B00B,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpGreaterThanComponentWise,
+ true);
+constexpr const TFunction greaterThan_20B20B(
+ BuiltInId::greaterThan_Float3_Float3,
+ BuiltInName::greaterThan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B00B,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpGreaterThanComponentWise,
+ true);
+constexpr const TFunction greaterThan_30B30B(
+ BuiltInId::greaterThan_Float4_Float4,
+ BuiltInName::greaterThan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B00B,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpGreaterThanComponentWise,
+ true);
+constexpr const TFunction greaterThan_10D10D(
+ BuiltInId::greaterThan_Int2_Int2,
+ BuiltInName::greaterThan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D10D00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpGreaterThanComponentWise,
+ true);
+constexpr const TFunction greaterThan_20D20D(
+ BuiltInId::greaterThan_Int3_Int3,
+ BuiltInName::greaterThan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D20D00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpGreaterThanComponentWise,
+ true);
+constexpr const TFunction greaterThan_30D30D(
+ BuiltInId::greaterThan_Int4_Int4,
+ BuiltInName::greaterThan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D30D00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpGreaterThanComponentWise,
+ true);
+constexpr const TFunction greaterThan_10E10E(
+ BuiltInId::greaterThan_UInt2_UInt2,
+ BuiltInName::greaterThan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E10E00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpGreaterThanComponentWise,
+ true);
+constexpr const TFunction greaterThan_20E20E(
+ BuiltInId::greaterThan_UInt3_UInt3,
+ BuiltInName::greaterThan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E20E00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpGreaterThanComponentWise,
+ true);
+constexpr const TFunction greaterThan_30E30E(
+ BuiltInId::greaterThan_UInt4_UInt4,
+ BuiltInName::greaterThan,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E30E00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpGreaterThanComponentWise,
+ true);
+constexpr const TFunction greaterThanEqual_10B10B(
+ BuiltInId::greaterThanEqual_Float2_Float2,
+ BuiltInName::greaterThanEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B00B,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpGreaterThanEqualComponentWise,
+ true);
+constexpr const TFunction greaterThanEqual_20B20B(
+ BuiltInId::greaterThanEqual_Float3_Float3,
+ BuiltInName::greaterThanEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B00B,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpGreaterThanEqualComponentWise,
+ true);
+constexpr const TFunction greaterThanEqual_30B30B(
+ BuiltInId::greaterThanEqual_Float4_Float4,
+ BuiltInName::greaterThanEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B00B,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpGreaterThanEqualComponentWise,
+ true);
+constexpr const TFunction greaterThanEqual_10D10D(
+ BuiltInId::greaterThanEqual_Int2_Int2,
+ BuiltInName::greaterThanEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D10D00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpGreaterThanEqualComponentWise,
+ true);
+constexpr const TFunction greaterThanEqual_20D20D(
+ BuiltInId::greaterThanEqual_Int3_Int3,
+ BuiltInName::greaterThanEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D20D00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpGreaterThanEqualComponentWise,
+ true);
+constexpr const TFunction greaterThanEqual_30D30D(
+ BuiltInId::greaterThanEqual_Int4_Int4,
+ BuiltInName::greaterThanEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D30D00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpGreaterThanEqualComponentWise,
+ true);
+constexpr const TFunction greaterThanEqual_10E10E(
+ BuiltInId::greaterThanEqual_UInt2_UInt2,
+ BuiltInName::greaterThanEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E10E00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpGreaterThanEqualComponentWise,
+ true);
+constexpr const TFunction greaterThanEqual_20E20E(
+ BuiltInId::greaterThanEqual_UInt3_UInt3,
+ BuiltInName::greaterThanEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E20E00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpGreaterThanEqualComponentWise,
+ true);
+constexpr const TFunction greaterThanEqual_30E30E(
+ BuiltInId::greaterThanEqual_UInt4_UInt4,
+ BuiltInName::greaterThanEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E30E00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpGreaterThanEqualComponentWise,
+ true);
+constexpr const TFunction equal_10B10B(BuiltInId::equal_Float2_Float2,
+ BuiltInName::equal,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B00B,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpEqualComponentWise,
+ true);
+constexpr const TFunction equal_20B20B(BuiltInId::equal_Float3_Float3,
+ BuiltInName::equal,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B00B,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpEqualComponentWise,
+ true);
+constexpr const TFunction equal_30B30B(BuiltInId::equal_Float4_Float4,
+ BuiltInName::equal,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B00B,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpEqualComponentWise,
+ true);
+constexpr const TFunction equal_10D10D(BuiltInId::equal_Int2_Int2,
+ BuiltInName::equal,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D10D00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpEqualComponentWise,
+ true);
+constexpr const TFunction equal_20D20D(BuiltInId::equal_Int3_Int3,
+ BuiltInName::equal,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D20D00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpEqualComponentWise,
+ true);
+constexpr const TFunction equal_30D30D(BuiltInId::equal_Int4_Int4,
+ BuiltInName::equal,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D30D00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpEqualComponentWise,
+ true);
+constexpr const TFunction equal_10E10E(BuiltInId::equal_UInt2_UInt2,
+ BuiltInName::equal,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E10E00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpEqualComponentWise,
+ true);
+constexpr const TFunction equal_20E20E(BuiltInId::equal_UInt3_UInt3,
+ BuiltInName::equal,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E20E00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpEqualComponentWise,
+ true);
+constexpr const TFunction equal_30E30E(BuiltInId::equal_UInt4_UInt4,
+ BuiltInName::equal,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E30E00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpEqualComponentWise,
+ true);
+constexpr const TFunction equal_10F10F(BuiltInId::equal_Bool2_Bool2,
+ BuiltInName::equal,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10F10F10F,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpEqualComponentWise,
+ true);
+constexpr const TFunction equal_20F20F(BuiltInId::equal_Bool3_Bool3,
+ BuiltInName::equal,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20F20F20F,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpEqualComponentWise,
+ true);
+constexpr const TFunction equal_30F30F(BuiltInId::equal_Bool4_Bool4,
+ BuiltInName::equal,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30F30F30F,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpEqualComponentWise,
+ true);
+constexpr const TFunction notEqual_10B10B(BuiltInId::notEqual_Float2_Float2,
+ BuiltInName::notEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B00B,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpNotEqualComponentWise,
+ true);
+constexpr const TFunction notEqual_20B20B(BuiltInId::notEqual_Float3_Float3,
+ BuiltInName::notEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B20B00B,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpNotEqualComponentWise,
+ true);
+constexpr const TFunction notEqual_30B30B(BuiltInId::notEqual_Float4_Float4,
+ BuiltInName::notEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B30B00B,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpNotEqualComponentWise,
+ true);
+constexpr const TFunction notEqual_10D10D(BuiltInId::notEqual_Int2_Int2,
+ BuiltInName::notEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D10D00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpNotEqualComponentWise,
+ true);
+constexpr const TFunction notEqual_20D20D(BuiltInId::notEqual_Int3_Int3,
+ BuiltInName::notEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D20D00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpNotEqualComponentWise,
+ true);
+constexpr const TFunction notEqual_30D30D(BuiltInId::notEqual_Int4_Int4,
+ BuiltInName::notEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D30D00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpNotEqualComponentWise,
+ true);
+constexpr const TFunction notEqual_10E10E(BuiltInId::notEqual_UInt2_UInt2,
+ BuiltInName::notEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E10E00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpNotEqualComponentWise,
+ true);
+constexpr const TFunction notEqual_20E20E(BuiltInId::notEqual_UInt3_UInt3,
+ BuiltInName::notEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E20E00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpNotEqualComponentWise,
+ true);
+constexpr const TFunction notEqual_30E30E(BuiltInId::notEqual_UInt4_UInt4,
+ BuiltInName::notEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E30E00D00D,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpNotEqualComponentWise,
+ true);
+constexpr const TFunction notEqual_10F10F(BuiltInId::notEqual_Bool2_Bool2,
+ BuiltInName::notEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10F10F10F,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpNotEqualComponentWise,
+ true);
+constexpr const TFunction notEqual_20F20F(BuiltInId::notEqual_Bool3_Bool3,
+ BuiltInName::notEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20F20F20F,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpNotEqualComponentWise,
+ true);
+constexpr const TFunction notEqual_30F30F(BuiltInId::notEqual_Bool4_Bool4,
+ BuiltInName::notEqual,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30F30F30F,
+ 2,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpNotEqualComponentWise,
+ true);
+constexpr const TFunction any_10F(BuiltInId::any_Bool2,
+ BuiltInName::any,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10F10F10F,
+ 1,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAny,
+ true);
+constexpr const TFunction any_20F(BuiltInId::any_Bool3,
+ BuiltInName::any,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20F20F20F,
+ 1,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAny,
+ true);
+constexpr const TFunction any_30F(BuiltInId::any_Bool4,
+ BuiltInName::any,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30F30F30F,
+ 1,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAny,
+ true);
+constexpr const TFunction all_10F(BuiltInId::all_Bool2,
+ BuiltInName::all,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10F10F10F,
+ 1,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAll,
+ true);
+constexpr const TFunction all_20F(BuiltInId::all_Bool3,
+ BuiltInName::all,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20F20F20F,
+ 1,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAll,
+ true);
+constexpr const TFunction all_30F(BuiltInId::all_Bool4,
+ BuiltInName::all,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30F30F30F,
+ 1,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAll,
+ true);
+constexpr const TFunction notFunc_10F(BuiltInId::notFunc_Bool2,
+ BuiltInName::notFunc,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10F10F10F,
+ 1,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpNotComponentWise,
+ true);
+constexpr const TFunction notFunc_20F(BuiltInId::notFunc_Bool3,
+ BuiltInName::notFunc,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20F20F20F,
+ 1,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpNotComponentWise,
+ true);
+constexpr const TFunction notFunc_30F(BuiltInId::notFunc_Bool4,
+ BuiltInName::notFunc,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30F30F30F,
+ 1,
+ StaticType::Get<EbtBool, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpNotComponentWise,
+ true);
+constexpr const TFunction bitfieldExtract_00D00D00D(
+ BuiltInId::bitfieldExtract_Int1_Int1_Int1,
+ BuiltInName::bitfieldExtract,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00D00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpBitfieldExtract,
+ true);
+constexpr const TFunction bitfieldExtract_10D00D00D(
+ BuiltInId::bitfieldExtract_Int2_Int1_Int1,
+ BuiltInName::bitfieldExtract,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpBitfieldExtract,
+ true);
+constexpr const TFunction bitfieldExtract_20D00D00D(
+ BuiltInId::bitfieldExtract_Int3_Int1_Int1,
+ BuiltInName::bitfieldExtract,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpBitfieldExtract,
+ true);
+constexpr const TFunction bitfieldExtract_30D00D00D(
+ BuiltInId::bitfieldExtract_Int4_Int1_Int1,
+ BuiltInName::bitfieldExtract,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpBitfieldExtract,
+ true);
+constexpr const TFunction bitfieldExtract_00E00D00D(
+ BuiltInId::bitfieldExtract_UInt1_Int1_Int1,
+ BuiltInName::bitfieldExtract,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00E00D00D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpBitfieldExtract,
+ true);
+constexpr const TFunction bitfieldExtract_10E00D00D(
+ BuiltInId::bitfieldExtract_UInt2_Int1_Int1,
+ BuiltInName::bitfieldExtract,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E00D00D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpBitfieldExtract,
+ true);
+constexpr const TFunction bitfieldExtract_20E00D00D(
+ BuiltInId::bitfieldExtract_UInt3_Int1_Int1,
+ BuiltInName::bitfieldExtract,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E00D00D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpBitfieldExtract,
+ true);
+constexpr const TFunction bitfieldExtract_30E00D00D(
+ BuiltInId::bitfieldExtract_UInt4_Int1_Int1,
+ BuiltInName::bitfieldExtract,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E00D00D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpBitfieldExtract,
+ true);
+constexpr const TFunction bitfieldInsert_00D00D00D00D(
+ BuiltInId::bitfieldInsert_Int1_Int1_Int1_Int1,
+ BuiltInName::bitfieldInsert,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpBitfieldInsert,
+ true);
+constexpr const TFunction bitfieldInsert_10D10D00D00D(
+ BuiltInId::bitfieldInsert_Int2_Int2_Int1_Int1,
+ BuiltInName::bitfieldInsert,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D10D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpBitfieldInsert,
+ true);
+constexpr const TFunction bitfieldInsert_20D20D00D00D(
+ BuiltInId::bitfieldInsert_Int3_Int3_Int1_Int1,
+ BuiltInName::bitfieldInsert,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpBitfieldInsert,
+ true);
+constexpr const TFunction bitfieldInsert_30D30D00D00D(
+ BuiltInId::bitfieldInsert_Int4_Int4_Int1_Int1,
+ BuiltInName::bitfieldInsert,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D30D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpBitfieldInsert,
+ true);
+constexpr const TFunction bitfieldInsert_00E00E00D00D(
+ BuiltInId::bitfieldInsert_UInt1_UInt1_Int1_Int1,
+ BuiltInName::bitfieldInsert,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00E00E00D00D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpBitfieldInsert,
+ true);
+constexpr const TFunction bitfieldInsert_10E10E00D00D(
+ BuiltInId::bitfieldInsert_UInt2_UInt2_Int1_Int1,
+ BuiltInName::bitfieldInsert,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E10E00D00D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpBitfieldInsert,
+ true);
+constexpr const TFunction bitfieldInsert_20E20E00D00D(
+ BuiltInId::bitfieldInsert_UInt3_UInt3_Int1_Int1,
+ BuiltInName::bitfieldInsert,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E20E00D00D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpBitfieldInsert,
+ true);
+constexpr const TFunction bitfieldInsert_30E30E00D00D(
+ BuiltInId::bitfieldInsert_UInt4_UInt4_Int1_Int1,
+ BuiltInName::bitfieldInsert,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E30E00D00D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpBitfieldInsert,
+ true);
+constexpr const TFunction bitfieldReverse_00D(
+ BuiltInId::bitfieldReverse_Int1,
+ BuiltInName::bitfieldReverse,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00D00D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpBitfieldReverse,
+ true);
+constexpr const TFunction bitfieldReverse_10D(
+ BuiltInId::bitfieldReverse_Int2,
+ BuiltInName::bitfieldReverse,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpBitfieldReverse,
+ true);
+constexpr const TFunction bitfieldReverse_20D(
+ BuiltInId::bitfieldReverse_Int3,
+ BuiltInName::bitfieldReverse,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpBitfieldReverse,
+ true);
+constexpr const TFunction bitfieldReverse_30D(
+ BuiltInId::bitfieldReverse_Int4,
+ BuiltInName::bitfieldReverse,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpBitfieldReverse,
+ true);
+constexpr const TFunction bitfieldReverse_00E(
+ BuiltInId::bitfieldReverse_UInt1,
+ BuiltInName::bitfieldReverse,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00E00D00D,
+ 1,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpBitfieldReverse,
+ true);
+constexpr const TFunction bitfieldReverse_10E(
+ BuiltInId::bitfieldReverse_UInt2,
+ BuiltInName::bitfieldReverse,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E00D00D,
+ 1,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpBitfieldReverse,
+ true);
+constexpr const TFunction bitfieldReverse_20E(
+ BuiltInId::bitfieldReverse_UInt3,
+ BuiltInName::bitfieldReverse,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E00D00D,
+ 1,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpBitfieldReverse,
+ true);
+constexpr const TFunction bitfieldReverse_30E(
+ BuiltInId::bitfieldReverse_UInt4,
+ BuiltInName::bitfieldReverse,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E00D00D,
+ 1,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpBitfieldReverse,
+ true);
+constexpr const TFunction bitCount_00D(BuiltInId::bitCount_Int1,
+ BuiltInName::bitCount,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00D00D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpBitCount,
+ true);
+constexpr const TFunction bitCount_10D(BuiltInId::bitCount_Int2,
+ BuiltInName::bitCount,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpBitCount,
+ true);
+constexpr const TFunction bitCount_20D(BuiltInId::bitCount_Int3,
+ BuiltInName::bitCount,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpBitCount,
+ true);
+constexpr const TFunction bitCount_30D(BuiltInId::bitCount_Int4,
+ BuiltInName::bitCount,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpBitCount,
+ true);
+constexpr const TFunction bitCount_00E(BuiltInId::bitCount_UInt1,
+ BuiltInName::bitCount,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00E00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpBitCount,
+ true);
+constexpr const TFunction bitCount_10E(BuiltInId::bitCount_UInt2,
+ BuiltInName::bitCount,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpBitCount,
+ true);
+constexpr const TFunction bitCount_20E(BuiltInId::bitCount_UInt3,
+ BuiltInName::bitCount,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpBitCount,
+ true);
+constexpr const TFunction bitCount_30E(BuiltInId::bitCount_UInt4,
+ BuiltInName::bitCount,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpBitCount,
+ true);
+constexpr const TFunction findLSB_00D(BuiltInId::findLSB_Int1,
+ BuiltInName::findLSB,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00D00D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpFindLSB,
+ true);
+constexpr const TFunction findLSB_10D(BuiltInId::findLSB_Int2,
+ BuiltInName::findLSB,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpFindLSB,
+ true);
+constexpr const TFunction findLSB_20D(BuiltInId::findLSB_Int3,
+ BuiltInName::findLSB,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpFindLSB,
+ true);
+constexpr const TFunction findLSB_30D(BuiltInId::findLSB_Int4,
+ BuiltInName::findLSB,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpFindLSB,
+ true);
+constexpr const TFunction findLSB_00E(BuiltInId::findLSB_UInt1,
+ BuiltInName::findLSB,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00E00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpFindLSB,
+ true);
+constexpr const TFunction findLSB_10E(BuiltInId::findLSB_UInt2,
+ BuiltInName::findLSB,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpFindLSB,
+ true);
+constexpr const TFunction findLSB_20E(BuiltInId::findLSB_UInt3,
+ BuiltInName::findLSB,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpFindLSB,
+ true);
+constexpr const TFunction findLSB_30E(BuiltInId::findLSB_UInt4,
+ BuiltInName::findLSB,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpFindLSB,
+ true);
+constexpr const TFunction findMSB_00D(BuiltInId::findMSB_Int1,
+ BuiltInName::findMSB,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00D00D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpFindMSB,
+ true);
+constexpr const TFunction findMSB_10D(BuiltInId::findMSB_Int2,
+ BuiltInName::findMSB,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpFindMSB,
+ true);
+constexpr const TFunction findMSB_20D(BuiltInId::findMSB_Int3,
+ BuiltInName::findMSB,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpFindMSB,
+ true);
+constexpr const TFunction findMSB_30D(BuiltInId::findMSB_Int4,
+ BuiltInName::findMSB,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpFindMSB,
+ true);
+constexpr const TFunction findMSB_00E(BuiltInId::findMSB_UInt1,
+ BuiltInName::findMSB,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00E00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpFindMSB,
+ true);
+constexpr const TFunction findMSB_10E(BuiltInId::findMSB_UInt2,
+ BuiltInName::findMSB,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpFindMSB,
+ true);
+constexpr const TFunction findMSB_20E(BuiltInId::findMSB_UInt3,
+ BuiltInName::findMSB,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpFindMSB,
+ true);
+constexpr const TFunction findMSB_30E(BuiltInId::findMSB_UInt4,
+ BuiltInName::findMSB,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E00D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpFindMSB,
+ true);
+constexpr const TFunction uaddCarry_00E00E00E(
+ BuiltInId::uaddCarry_UInt1_UInt1_UInt1,
+ BuiltInName::uaddCarry,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00E00E_o_00E_o_00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpUaddCarry,
+ false);
+constexpr const TFunction uaddCarry_10E10E10E(
+ BuiltInId::uaddCarry_UInt2_UInt2_UInt2,
+ BuiltInName::uaddCarry,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E10E_o_10E_o_10E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpUaddCarry,
+ false);
+constexpr const TFunction uaddCarry_20E20E20E(
+ BuiltInId::uaddCarry_UInt3_UInt3_UInt3,
+ BuiltInName::uaddCarry,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E20E_o_20E_o_20E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpUaddCarry,
+ false);
+constexpr const TFunction uaddCarry_30E30E30E(
+ BuiltInId::uaddCarry_UInt4_UInt4_UInt4,
+ BuiltInName::uaddCarry,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E30E_o_30E_o_30E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpUaddCarry,
+ false);
+constexpr const TFunction usubBorrow_00E00E00E(
+ BuiltInId::usubBorrow_UInt1_UInt1_UInt1,
+ BuiltInName::usubBorrow,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00E00E_o_00E_o_00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpUsubBorrow,
+ false);
+constexpr const TFunction usubBorrow_10E10E10E(
+ BuiltInId::usubBorrow_UInt2_UInt2_UInt2,
+ BuiltInName::usubBorrow,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E10E_o_10E_o_10E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpUsubBorrow,
+ false);
+constexpr const TFunction usubBorrow_20E20E20E(
+ BuiltInId::usubBorrow_UInt3_UInt3_UInt3,
+ BuiltInName::usubBorrow,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E20E_o_20E_o_20E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpUsubBorrow,
+ false);
+constexpr const TFunction usubBorrow_30E30E30E(
+ BuiltInId::usubBorrow_UInt4_UInt4_UInt4,
+ BuiltInName::usubBorrow,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E30E_o_30E_o_30E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpUsubBorrow,
+ false);
+constexpr const TFunction umulExtended_00E00E00E00E(
+ BuiltInId::umulExtended_UInt1_UInt1_UInt1_UInt1,
+ BuiltInName::umulExtended,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00E00E_o_00E_o_00E,
+ 4,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpUmulExtended,
+ false);
+constexpr const TFunction umulExtended_10E10E10E10E(
+ BuiltInId::umulExtended_UInt2_UInt2_UInt2_UInt2,
+ BuiltInName::umulExtended,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10E10E_o_10E_o_10E,
+ 4,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpUmulExtended,
+ false);
+constexpr const TFunction umulExtended_20E20E20E20E(
+ BuiltInId::umulExtended_UInt3_UInt3_UInt3_UInt3,
+ BuiltInName::umulExtended,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20E20E_o_20E_o_20E,
+ 4,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpUmulExtended,
+ false);
+constexpr const TFunction umulExtended_30E30E30E30E(
+ BuiltInId::umulExtended_UInt4_UInt4_UInt4_UInt4,
+ BuiltInName::umulExtended,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30E30E_o_30E_o_30E,
+ 4,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpUmulExtended,
+ false);
+constexpr const TFunction imulExtended_00D00D00D00D(
+ BuiltInId::imulExtended_Int1_Int1_Int1_Int1,
+ BuiltInName::imulExtended,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00D00D_o_00D_o_00D,
+ 4,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImulExtended,
+ false);
+constexpr const TFunction imulExtended_10D10D10D10D(
+ BuiltInId::imulExtended_Int2_Int2_Int2_Int2,
+ BuiltInName::imulExtended,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10D10D_o_10D_o_10D,
+ 4,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImulExtended,
+ false);
+constexpr const TFunction imulExtended_20D20D20D20D(
+ BuiltInId::imulExtended_Int3_Int3_Int3_Int3,
+ BuiltInName::imulExtended,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20D20D_o_20D_o_20D,
+ 4,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImulExtended,
+ false);
+constexpr const TFunction imulExtended_30D30D30D30D(
+ BuiltInId::imulExtended_Int4_Int4_Int4_Int4,
+ BuiltInName::imulExtended,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30D30D_o_30D_o_30D,
+ 4,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImulExtended,
+ false);
+constexpr const TFunction texture2D_00I10B(
+ BuiltInId::texture2D_Sampler2D1_Float2,
+ BuiltInName::texture2D,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I10B00B10D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture2D,
+ false);
+constexpr const TFunction texture2DProj_00I20B(
+ BuiltInId::texture2DProj_Sampler2D1_Float3,
+ BuiltInName::texture2DProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I20B00B10D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture2DProj,
+ false);
+constexpr const TFunction texture2DProj_00I30B(
+ BuiltInId::texture2DProj_Sampler2D1_Float4,
+ BuiltInName::texture2DProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I30B00B10D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture2DProj,
+ false);
+constexpr const TFunction textureCube_00K20B(
+ BuiltInId::textureCube_SamplerCube1_Float3,
+ BuiltInName::textureCube,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00K20B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureCube,
+ false);
+constexpr const TFunction texture3D_00J20B(
+ BuiltInId::texture3D_Sampler3D1_Float3,
+ BuiltInName::texture3D,
+ std::array<TExtension, 1u>{{TExtension::OES_texture_3D}},
+ BuiltInParameters::p00J20B00B20D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture3D,
+ false);
+constexpr const TFunction texture3DProj_00J30B(
+ BuiltInId::texture3DProj_Sampler3D1_Float4,
+ BuiltInName::texture3DProj,
+ std::array<TExtension, 1u>{{TExtension::OES_texture_3D}},
+ BuiltInParameters::p00J30B00B20D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture3DProj,
+ false);
+constexpr const TFunction shadow2DEXT_00d20B(
+ BuiltInId::shadow2DEXT_Sampler2DShadow1_Float3,
+ BuiltInName::shadow2DEXT,
+ std::array<TExtension, 1u>{{TExtension::EXT_shadow_samplers}},
+ BuiltInParameters::p00d20B00B10D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpShadow2DEXT,
+ false);
+constexpr const TFunction shadow2DProjEXT_00d30B(
+ BuiltInId::shadow2DProjEXT_Sampler2DShadow1_Float4,
+ BuiltInName::shadow2DProjEXT,
+ std::array<TExtension, 1u>{{TExtension::EXT_shadow_samplers}},
+ BuiltInParameters::p00d30B00B10D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpShadow2DProjEXT,
+ false);
+constexpr const TFunction texture2D_00M10B(
+ BuiltInId::texture2D_SamplerExternalOES1_Float2,
+ BuiltInName::texture2D,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_EGL_image_external, TExtension::NV_EGL_stream_consumer_external}},
+ BuiltInParameters::p00M10B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture2D,
+ false);
+constexpr const TFunction texture2DProj_00M20B(
+ BuiltInId::texture2DProj_SamplerExternalOES1_Float3,
+ BuiltInName::texture2DProj,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_EGL_image_external, TExtension::NV_EGL_stream_consumer_external}},
+ BuiltInParameters::p00M20B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture2DProj,
+ false);
+constexpr const TFunction texture2DProj_00M30B(
+ BuiltInId::texture2DProj_SamplerExternalOES1_Float4,
+ BuiltInName::texture2DProj,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_EGL_image_external, TExtension::NV_EGL_stream_consumer_external}},
+ BuiltInParameters::p00M30B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture2DProj,
+ false);
+constexpr const TFunction texture2DRect_00O10B(
+ BuiltInId::texture2DRect_Sampler2DRect1_Float2,
+ BuiltInName::texture2DRect,
+ std::array<TExtension, 1u>{{TExtension::ARB_texture_rectangle}},
+ BuiltInParameters::p00O10B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture2DRect,
+ false);
+constexpr const TFunction texture2DRectProj_00O20B(
+ BuiltInId::texture2DRectProj_Sampler2DRect1_Float3,
+ BuiltInName::texture2DRectProj,
+ std::array<TExtension, 1u>{{TExtension::ARB_texture_rectangle}},
+ BuiltInParameters::p00O20B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture2DRectProj,
+ false);
+constexpr const TFunction texture2DRectProj_00O30B(
+ BuiltInId::texture2DRectProj_Sampler2DRect1_Float4,
+ BuiltInName::texture2DRectProj,
+ std::array<TExtension, 1u>{{TExtension::ARB_texture_rectangle}},
+ BuiltInParameters::p00O30B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture2DRectProj,
+ false);
+constexpr const TFunction texture2DGradEXT_00I10B10B10B(
+ BuiltInId::texture2DGradEXT_Sampler2D1_Float2_Float2_Float2,
+ BuiltInName::texture2DGradEXT,
+ std::array<TExtension, 1u>{{TExtension::EXT_shader_texture_lod}},
+ BuiltInParameters::p00I10B10B10B10D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture2DGradEXT,
+ false);
+constexpr const TFunction texture2DProjGradEXT_00I20B10B10B(
+ BuiltInId::texture2DProjGradEXT_Sampler2D1_Float3_Float2_Float2,
+ BuiltInName::texture2DProjGradEXT,
+ std::array<TExtension, 1u>{{TExtension::EXT_shader_texture_lod}},
+ BuiltInParameters::p00I20B10B10B10D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture2DProjGradEXT,
+ false);
+constexpr const TFunction texture2DProjGradEXT_00I30B10B10B(
+ BuiltInId::texture2DProjGradEXT_Sampler2D1_Float4_Float2_Float2,
+ BuiltInName::texture2DProjGradEXT,
+ std::array<TExtension, 1u>{{TExtension::EXT_shader_texture_lod}},
+ BuiltInParameters::p00I30B10B10B10D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture2DProjGradEXT,
+ false);
+constexpr const TFunction textureCubeGradEXT_00K20B20B20B(
+ BuiltInId::textureCubeGradEXT_SamplerCube1_Float3_Float3_Float3,
+ BuiltInName::textureCubeGradEXT,
+ std::array<TExtension, 1u>{{TExtension::EXT_shader_texture_lod}},
+ BuiltInParameters::p00K20B20B20B,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureCubeGradEXT,
+ false);
+constexpr const TFunction textureVideoWEBGL_00y10B(
+ BuiltInId::textureVideoWEBGL_SamplerVideoWEBGL1_Float2,
+ BuiltInName::textureVideoWEBGL,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00y10B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureVideoWEBGL,
+ false);
+constexpr const TFunction texture2D_00I10B00B(
+ BuiltInId::texture2D_Sampler2D1_Float2_Float1,
+ BuiltInName::texture2D,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I10B00B10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture2DBias,
+ false);
+constexpr const TFunction texture2DProj_00I20B00B(
+ BuiltInId::texture2DProj_Sampler2D1_Float3_Float1,
+ BuiltInName::texture2DProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I20B00B10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture2DProjBias,
+ false);
+constexpr const TFunction texture2DProj_00I30B00B(
+ BuiltInId::texture2DProj_Sampler2D1_Float4_Float1,
+ BuiltInName::texture2DProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I30B00B10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture2DProjBias,
+ false);
+constexpr const TFunction textureCube_00K20B00B(
+ BuiltInId::textureCube_SamplerCube1_Float3_Float1,
+ BuiltInName::textureCube,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00K20B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureCubeBias,
+ false);
+constexpr const TFunction texture3D_00J20B00B(
+ BuiltInId::texture3D_Sampler3D1_Float3_Float1,
+ BuiltInName::texture3D,
+ std::array<TExtension, 1u>{{TExtension::OES_texture_3D}},
+ BuiltInParameters::p00J20B00B20D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture3DBias,
+ false);
+constexpr const TFunction texture3DProj_00J30B00B(
+ BuiltInId::texture3DProj_Sampler3D1_Float4_Float1,
+ BuiltInName::texture3DProj,
+ std::array<TExtension, 1u>{{TExtension::OES_texture_3D}},
+ BuiltInParameters::p00J30B00B20D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture3DProjBias,
+ false);
+constexpr const TFunction texture3DLod_00J20B00B(
+ BuiltInId::texture3DLod_Sampler3D1_Float3_Float1,
+ BuiltInName::texture3DLod,
+ std::array<TExtension, 1u>{{TExtension::OES_texture_3D}},
+ BuiltInParameters::p00J20B00B20D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture3DLod,
+ false);
+constexpr const TFunction texture3DProjLod_00J30B00B(
+ BuiltInId::texture3DProjLod_Sampler3D1_Float4_Float1,
+ BuiltInName::texture3DProjLod,
+ std::array<TExtension, 1u>{{TExtension::OES_texture_3D}},
+ BuiltInParameters::p00J30B00B20D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture3DProjLod,
+ false);
+constexpr const TFunction texture2DLod_00I10B00B(
+ BuiltInId::texture2DLod_Sampler2D1_Float2_Float1,
+ BuiltInName::texture2DLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I10B00B10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture2DLodVS,
+ false);
+constexpr const TFunction texture2DProjLod_00I20B00B(
+ BuiltInId::texture2DProjLod_Sampler2D1_Float3_Float1,
+ BuiltInName::texture2DProjLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I20B00B10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture2DProjLodVS,
+ false);
+constexpr const TFunction texture2DProjLod_00I30B00B(
+ BuiltInId::texture2DProjLod_Sampler2D1_Float4_Float1,
+ BuiltInName::texture2DProjLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I30B00B10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture2DProjLodVS,
+ false);
+constexpr const TFunction textureCubeLod_00K20B00B(
+ BuiltInId::textureCubeLod_SamplerCube1_Float3_Float1,
+ BuiltInName::textureCubeLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00K20B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureCubeLodVS,
+ false);
+constexpr const TFunction texture2DLodEXT_00I10B00B(
+ BuiltInId::texture2DLodEXT_Sampler2D1_Float2_Float1,
+ BuiltInName::texture2DLodEXT,
+ std::array<TExtension, 1u>{{TExtension::EXT_shader_texture_lod}},
+ BuiltInParameters::p00I10B00B10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture2DLodEXTFS,
+ false);
+constexpr const TFunction texture2DProjLodEXT_00I20B00B(
+ BuiltInId::texture2DProjLodEXT_Sampler2D1_Float3_Float1,
+ BuiltInName::texture2DProjLodEXT,
+ std::array<TExtension, 1u>{{TExtension::EXT_shader_texture_lod}},
+ BuiltInParameters::p00I20B00B10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture2DProjLodEXTFS,
+ false);
+constexpr const TFunction texture2DProjLodEXT_00I30B00B(
+ BuiltInId::texture2DProjLodEXT_Sampler2D1_Float4_Float1,
+ BuiltInName::texture2DProjLodEXT,
+ std::array<TExtension, 1u>{{TExtension::EXT_shader_texture_lod}},
+ BuiltInParameters::p00I30B00B10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture2DProjLodEXTFS,
+ false);
+constexpr const TFunction textureCubeLodEXT_00K20B00B(
+ BuiltInId::textureCubeLodEXT_SamplerCube1_Float3_Float1,
+ BuiltInName::textureCubeLodEXT,
+ std::array<TExtension, 1u>{{TExtension::EXT_shader_texture_lod}},
+ BuiltInParameters::p00K20B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureCubeLodEXTFS,
+ false);
+constexpr const TFunction texture_00I10B(BuiltInId::texture_Sampler2D1_Float2,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I10B00B10D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00R10B(BuiltInId::texture_ISampler2D1_Float2,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R10B00B10D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00X10B(BuiltInId::texture_USampler2D1_Float2,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X10B00B10D,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00J20B(BuiltInId::texture_Sampler3D1_Float3,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00J20B00B20D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00S20B(BuiltInId::texture_ISampler3D1_Float3,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00S20B00B20D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00Y20B(BuiltInId::texture_USampler3D1_Float3,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Y20B00B20D,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00K20B(BuiltInId::texture_SamplerCube1_Float3,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00K20B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00T20B(BuiltInId::texture_ISamplerCube1_Float3,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00T20B00B,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00Z20B(BuiltInId::texture_USamplerCube1_Float3,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Z20B00B,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00L20B(BuiltInId::texture_Sampler2DArray1_Float3,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00L20B00B10D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00U20B(BuiltInId::texture_ISampler2DArray1_Float3,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00U20B00B10D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00a20B(BuiltInId::texture_USampler2DArray1_Float3,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00a20B00B10D,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00d20B(BuiltInId::texture_Sampler2DShadow1_Float3,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00d20B00B10D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00e30B(BuiltInId::texture_SamplerCubeShadow1_Float4,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00e30B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00f30B(BuiltInId::texture_Sampler2DArrayShadow1_Float4,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00f30B10B10B10D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00k30B(BuiltInId::texture_SamplerCubeArray1_Float4,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00k30B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00s30B(BuiltInId::texture_ISamplerCubeArray1_Float4,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00s30B00B,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00x30B(BuiltInId::texture_USamplerCubeArray1_Float4,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00x30B00B,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00l30B00B(
+ BuiltInId::texture_SamplerCubeArrayShadow1_Float4_Float1,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00l30B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction textureExt_00k30B(
+ BuiltInId::textureExt_SamplerCubeArray1_Float4,
+ BuiltInName::textureExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00k30B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction textureExt_00s30B(
+ BuiltInId::textureExt_ISamplerCubeArray1_Float4,
+ BuiltInName::textureExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00s30B00B,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction textureExt_00x30B(
+ BuiltInId::textureExt_USamplerCubeArray1_Float4,
+ BuiltInName::textureExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00x30B00B,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction textureExt_00l30B00B(
+ BuiltInId::textureExt_SamplerCubeArrayShadow1_Float4_Float1,
+ BuiltInName::textureExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00l30B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00M10B(BuiltInId::texture_SamplerExternalOES1_Float2,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{
+ {TExtension::OES_EGL_image_external_essl3}},
+ BuiltInParameters::p00M10B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00N10B(BuiltInId::texture_SamplerExternal2DY2YEXT1_Float2,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::EXT_YUV_target}},
+ BuiltInParameters::p00N10B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00O10B(BuiltInId::texture_Sampler2DRect1_Float2,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{
+ {TExtension::ARB_texture_rectangle}},
+ BuiltInParameters::p00O10B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction texture_00y10B(BuiltInId::texture_SamplerVideoWEBGL1_Float2,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00y10B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexture,
+ false);
+constexpr const TFunction textureProj_00I20B(
+ BuiltInId::textureProj_Sampler2D1_Float3,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I20B00B10D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProj,
+ false);
+constexpr const TFunction textureProj_00R20B(
+ BuiltInId::textureProj_ISampler2D1_Float3,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R20B00B10D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProj,
+ false);
+constexpr const TFunction textureProj_00X20B(
+ BuiltInId::textureProj_USampler2D1_Float3,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X20B00B10D,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProj,
+ false);
+constexpr const TFunction textureProj_00I30B(
+ BuiltInId::textureProj_Sampler2D1_Float4,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I30B00B10D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProj,
+ false);
+constexpr const TFunction textureProj_00R30B(
+ BuiltInId::textureProj_ISampler2D1_Float4,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R30B00B10D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProj,
+ false);
+constexpr const TFunction textureProj_00X30B(
+ BuiltInId::textureProj_USampler2D1_Float4,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X30B00B10D,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProj,
+ false);
+constexpr const TFunction textureProj_00J30B(
+ BuiltInId::textureProj_Sampler3D1_Float4,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00J30B00B20D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProj,
+ false);
+constexpr const TFunction textureProj_00S30B(
+ BuiltInId::textureProj_ISampler3D1_Float4,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00S30B00B20D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProj,
+ false);
+constexpr const TFunction textureProj_00Y30B(
+ BuiltInId::textureProj_USampler3D1_Float4,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Y30B00B20D,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProj,
+ false);
+constexpr const TFunction textureProj_00d30B(
+ BuiltInId::textureProj_Sampler2DShadow1_Float4,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00d30B00B10D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureProj,
+ false);
+constexpr const TFunction textureProj_00M20B(
+ BuiltInId::textureProj_SamplerExternalOES1_Float3,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::OES_EGL_image_external_essl3}},
+ BuiltInParameters::p00M20B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProj,
+ false);
+constexpr const TFunction textureProj_00M30B(
+ BuiltInId::textureProj_SamplerExternalOES1_Float4,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::OES_EGL_image_external_essl3}},
+ BuiltInParameters::p00M30B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProj,
+ false);
+constexpr const TFunction textureProj_00N20B(
+ BuiltInId::textureProj_SamplerExternal2DY2YEXT1_Float3,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::EXT_YUV_target}},
+ BuiltInParameters::p00N20B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProj,
+ false);
+constexpr const TFunction textureProj_00N30B(
+ BuiltInId::textureProj_SamplerExternal2DY2YEXT1_Float4,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::EXT_YUV_target}},
+ BuiltInParameters::p00N30B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProj,
+ false);
+constexpr const TFunction textureProj_00O20B(
+ BuiltInId::textureProj_Sampler2DRect1_Float3,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::ARB_texture_rectangle}},
+ BuiltInParameters::p00O20B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProj,
+ false);
+constexpr const TFunction textureProj_00O30B(
+ BuiltInId::textureProj_Sampler2DRect1_Float4,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::ARB_texture_rectangle}},
+ BuiltInParameters::p00O30B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProj,
+ false);
+constexpr const TFunction textureLod_00I10B00B(
+ BuiltInId::textureLod_Sampler2D1_Float2_Float1,
+ BuiltInName::textureLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I10B00B10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLod,
+ false);
+constexpr const TFunction textureLod_00R10B00B(
+ BuiltInId::textureLod_ISampler2D1_Float2_Float1,
+ BuiltInName::textureLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R10B00B10D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLod,
+ false);
+constexpr const TFunction textureLod_00X10B00B(
+ BuiltInId::textureLod_USampler2D1_Float2_Float1,
+ BuiltInName::textureLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X10B00B10D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLod,
+ false);
+constexpr const TFunction textureLod_00J20B00B(
+ BuiltInId::textureLod_Sampler3D1_Float3_Float1,
+ BuiltInName::textureLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00J20B00B20D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLod,
+ false);
+constexpr const TFunction textureLod_00S20B00B(
+ BuiltInId::textureLod_ISampler3D1_Float3_Float1,
+ BuiltInName::textureLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00S20B00B20D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLod,
+ false);
+constexpr const TFunction textureLod_00Y20B00B(
+ BuiltInId::textureLod_USampler3D1_Float3_Float1,
+ BuiltInName::textureLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Y20B00B20D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLod,
+ false);
+constexpr const TFunction textureLod_00K20B00B(
+ BuiltInId::textureLod_SamplerCube1_Float3_Float1,
+ BuiltInName::textureLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00K20B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLod,
+ false);
+constexpr const TFunction textureLod_00T20B00B(
+ BuiltInId::textureLod_ISamplerCube1_Float3_Float1,
+ BuiltInName::textureLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00T20B00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLod,
+ false);
+constexpr const TFunction textureLod_00Z20B00B(
+ BuiltInId::textureLod_USamplerCube1_Float3_Float1,
+ BuiltInName::textureLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Z20B00B,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLod,
+ false);
+constexpr const TFunction textureLod_00L20B00B(
+ BuiltInId::textureLod_Sampler2DArray1_Float3_Float1,
+ BuiltInName::textureLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00L20B00B10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLod,
+ false);
+constexpr const TFunction textureLod_00U20B00B(
+ BuiltInId::textureLod_ISampler2DArray1_Float3_Float1,
+ BuiltInName::textureLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00U20B00B10D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLod,
+ false);
+constexpr const TFunction textureLod_00a20B00B(
+ BuiltInId::textureLod_USampler2DArray1_Float3_Float1,
+ BuiltInName::textureLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00a20B00B10D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLod,
+ false);
+constexpr const TFunction textureLod_00d20B00B(
+ BuiltInId::textureLod_Sampler2DShadow1_Float3_Float1,
+ BuiltInName::textureLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00d20B00B10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureLod,
+ false);
+constexpr const TFunction textureLod_00k30B00B(
+ BuiltInId::textureLod_SamplerCubeArray1_Float4_Float1,
+ BuiltInName::textureLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00k30B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLod,
+ false);
+constexpr const TFunction textureLod_00s30B00B(
+ BuiltInId::textureLod_ISamplerCubeArray1_Float4_Float1,
+ BuiltInName::textureLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00s30B00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLod,
+ false);
+constexpr const TFunction textureLod_00x30B00B(
+ BuiltInId::textureLod_USamplerCubeArray1_Float4_Float1,
+ BuiltInName::textureLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00x30B00B,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLod,
+ false);
+constexpr const TFunction textureLodExt_00k30B00B(
+ BuiltInId::textureLodExt_SamplerCubeArray1_Float4_Float1,
+ BuiltInName::textureLodExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00k30B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLod,
+ false);
+constexpr const TFunction textureLodExt_00s30B00B(
+ BuiltInId::textureLodExt_ISamplerCubeArray1_Float4_Float1,
+ BuiltInName::textureLodExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00s30B00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLod,
+ false);
+constexpr const TFunction textureLodExt_00x30B00B(
+ BuiltInId::textureLodExt_USamplerCubeArray1_Float4_Float1,
+ BuiltInName::textureLodExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00x30B00B,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLod,
+ false);
+constexpr const TFunction textureSize_00I00D(
+ BuiltInId::textureSize_Sampler2D1_Int1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00R00D(
+ BuiltInId::textureSize_ISampler2D1_Int1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00X00D(
+ BuiltInId::textureSize_USampler2D1_Int1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00J00D(
+ BuiltInId::textureSize_Sampler3D1_Int1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00J00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00S00D(
+ BuiltInId::textureSize_ISampler3D1_Int1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00S00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00Y00D(
+ BuiltInId::textureSize_USampler3D1_Int1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Y00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00K00D(
+ BuiltInId::textureSize_SamplerCube1_Int1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00K00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00T00D(
+ BuiltInId::textureSize_ISamplerCube1_Int1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00T00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00Z00D(
+ BuiltInId::textureSize_USamplerCube1_Int1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Z00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00L00D(
+ BuiltInId::textureSize_Sampler2DArray1_Int1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00L00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00U00D(
+ BuiltInId::textureSize_ISampler2DArray1_Int1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00U00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00a00D(
+ BuiltInId::textureSize_USampler2DArray1_Int1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00a00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00d00D(
+ BuiltInId::textureSize_Sampler2DShadow1_Int1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00d00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00e00D(
+ BuiltInId::textureSize_SamplerCubeShadow1_Int1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00e00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00f00D(
+ BuiltInId::textureSize_Sampler2DArrayShadow1_Int1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00f00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00k00D(
+ BuiltInId::textureSize_SamplerCubeArray1_Int1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00k00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00s00D(
+ BuiltInId::textureSize_ISamplerCubeArray1_Int1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00s00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00x00D(
+ BuiltInId::textureSize_USamplerCubeArray1_Int1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00x00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00l00D(
+ BuiltInId::textureSize_SamplerCubeArrayShadow1_Int1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00l00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSizeExt_00k00D(
+ BuiltInId::textureSizeExt_SamplerCubeArray1_Int1,
+ BuiltInName::textureSizeExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00k00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSizeExt_00s00D(
+ BuiltInId::textureSizeExt_ISamplerCubeArray1_Int1,
+ BuiltInName::textureSizeExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00s00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSizeExt_00x00D(
+ BuiltInId::textureSizeExt_USamplerCubeArray1_Int1,
+ BuiltInName::textureSizeExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00x00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSizeExt_00l00D(
+ BuiltInId::textureSizeExt_SamplerCubeArrayShadow1_Int1,
+ BuiltInName::textureSizeExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00l00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00j(BuiltInId::textureSize_SamplerBuffer1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00j00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00r(BuiltInId::textureSize_ISamplerBuffer1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00r00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00w(BuiltInId::textureSize_USamplerBuffer1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00w00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSizeExt_00j(
+ BuiltInId::textureSizeExt_SamplerBuffer1,
+ BuiltInName::textureSizeExt,
+ std::array<TExtension, 2u>{{TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer}},
+ BuiltInParameters::p00j00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSizeExt_00r(
+ BuiltInId::textureSizeExt_ISamplerBuffer1,
+ BuiltInName::textureSizeExt,
+ std::array<TExtension, 2u>{{TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer}},
+ BuiltInParameters::p00r00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSizeExt_00w(
+ BuiltInId::textureSizeExt_USamplerBuffer1,
+ BuiltInName::textureSizeExt,
+ std::array<TExtension, 2u>{{TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer}},
+ BuiltInParameters::p00w00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00P(BuiltInId::textureSize_Sampler2DMS1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00P10D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00V(BuiltInId::textureSize_ISampler2DMS1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00V10D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00b(BuiltInId::textureSize_USampler2DMS1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00b10D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSizeExt_00P(
+ BuiltInId::textureSizeExt_Sampler2DMS1,
+ BuiltInName::textureSizeExt,
+ std::array<TExtension, 1u>{{TExtension::ANGLE_texture_multisample}},
+ BuiltInParameters::p00P10D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSizeExt_00V(
+ BuiltInId::textureSizeExt_ISampler2DMS1,
+ BuiltInName::textureSizeExt,
+ std::array<TExtension, 1u>{{TExtension::ANGLE_texture_multisample}},
+ BuiltInParameters::p00V10D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSizeExt_00b(
+ BuiltInId::textureSizeExt_USampler2DMS1,
+ BuiltInName::textureSizeExt,
+ std::array<TExtension, 1u>{{TExtension::ANGLE_texture_multisample}},
+ BuiltInParameters::p00b10D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00Q(BuiltInId::textureSize_Sampler2DMSArray1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Q20D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00W(BuiltInId::textureSize_ISampler2DMSArray1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00W20D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00c(BuiltInId::textureSize_USampler2DMSArray1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00c20D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSizeExt_00Q(
+ BuiltInId::textureSizeExt_Sampler2DMSArray1,
+ BuiltInName::textureSizeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_texture_storage_multisample_2d_array}},
+ BuiltInParameters::p00Q20D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSizeExt_00W(
+ BuiltInId::textureSizeExt_ISampler2DMSArray1,
+ BuiltInName::textureSizeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_texture_storage_multisample_2d_array}},
+ BuiltInParameters::p00W20D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSizeExt_00c(
+ BuiltInId::textureSizeExt_USampler2DMSArray1,
+ BuiltInName::textureSizeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_texture_storage_multisample_2d_array}},
+ BuiltInParameters::p00c20D00D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00M00D(
+ BuiltInId::textureSize_SamplerExternalOES1_Int1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::OES_EGL_image_external_essl3}},
+ BuiltInParameters::p00M00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureSize_00N00D(
+ BuiltInId::textureSize_SamplerExternal2DY2YEXT1_Int1,
+ BuiltInName::textureSize,
+ std::array<TExtension, 1u>{{TExtension::EXT_YUV_target}},
+ BuiltInParameters::p00N00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpTextureSize,
+ false);
+constexpr const TFunction textureProjLod_00I20B00B(
+ BuiltInId::textureProjLod_Sampler2D1_Float3_Float1,
+ BuiltInName::textureProjLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I20B00B10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjLod,
+ false);
+constexpr const TFunction textureProjLod_00R20B00B(
+ BuiltInId::textureProjLod_ISampler2D1_Float3_Float1,
+ BuiltInName::textureProjLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R20B00B10D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjLod,
+ false);
+constexpr const TFunction textureProjLod_00X20B00B(
+ BuiltInId::textureProjLod_USampler2D1_Float3_Float1,
+ BuiltInName::textureProjLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X20B00B10D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjLod,
+ false);
+constexpr const TFunction textureProjLod_00I30B00B(
+ BuiltInId::textureProjLod_Sampler2D1_Float4_Float1,
+ BuiltInName::textureProjLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I30B00B10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjLod,
+ false);
+constexpr const TFunction textureProjLod_00R30B00B(
+ BuiltInId::textureProjLod_ISampler2D1_Float4_Float1,
+ BuiltInName::textureProjLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R30B00B10D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjLod,
+ false);
+constexpr const TFunction textureProjLod_00X30B00B(
+ BuiltInId::textureProjLod_USampler2D1_Float4_Float1,
+ BuiltInName::textureProjLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X30B00B10D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjLod,
+ false);
+constexpr const TFunction textureProjLod_00J30B00B(
+ BuiltInId::textureProjLod_Sampler3D1_Float4_Float1,
+ BuiltInName::textureProjLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00J30B00B20D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjLod,
+ false);
+constexpr const TFunction textureProjLod_00S30B00B(
+ BuiltInId::textureProjLod_ISampler3D1_Float4_Float1,
+ BuiltInName::textureProjLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00S30B00B20D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjLod,
+ false);
+constexpr const TFunction textureProjLod_00Y30B00B(
+ BuiltInId::textureProjLod_USampler3D1_Float4_Float1,
+ BuiltInName::textureProjLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Y30B00B20D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjLod,
+ false);
+constexpr const TFunction textureProjLod_00d30B00B(
+ BuiltInId::textureProjLod_Sampler2DShadow1_Float4_Float1,
+ BuiltInName::textureProjLod,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00d30B00B10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureProjLod,
+ false);
+constexpr const TFunction texelFetch_00I10D00D(
+ BuiltInId::texelFetch_Sampler2D1_Int2_Int1,
+ BuiltInName::texelFetch,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I10D00D10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetch_00R10D00D(
+ BuiltInId::texelFetch_ISampler2D1_Int2_Int1,
+ BuiltInName::texelFetch,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R10D00D10D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetch_00X10D00D(
+ BuiltInId::texelFetch_USampler2D1_Int2_Int1,
+ BuiltInName::texelFetch,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X10D00D10D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetch_00J20D00D(
+ BuiltInId::texelFetch_Sampler3D1_Int3_Int1,
+ BuiltInName::texelFetch,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00J20D00D20D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetch_00S20D00D(
+ BuiltInId::texelFetch_ISampler3D1_Int3_Int1,
+ BuiltInName::texelFetch,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00S20D00D20D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetch_00Y20D00D(
+ BuiltInId::texelFetch_USampler3D1_Int3_Int1,
+ BuiltInName::texelFetch,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Y20D00D20D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetch_00L20D00D(
+ BuiltInId::texelFetch_Sampler2DArray1_Int3_Int1,
+ BuiltInName::texelFetch,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00L20D00D10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetch_00U20D00D(
+ BuiltInId::texelFetch_ISampler2DArray1_Int3_Int1,
+ BuiltInName::texelFetch,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00U20D00D10D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetch_00a20D00D(
+ BuiltInId::texelFetch_USampler2DArray1_Int3_Int1,
+ BuiltInName::texelFetch,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00a20D00D10D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetch_00j00D(
+ BuiltInId::texelFetch_SamplerBuffer1_Int1,
+ BuiltInName::texelFetch,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00j00D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetch_00r00D(
+ BuiltInId::texelFetch_ISamplerBuffer1_Int1,
+ BuiltInName::texelFetch,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00r00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetch_00w00D(
+ BuiltInId::texelFetch_USamplerBuffer1_Int1,
+ BuiltInName::texelFetch,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00w00D,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetchExt_00j00D(
+ BuiltInId::texelFetchExt_SamplerBuffer1_Int1,
+ BuiltInName::texelFetchExt,
+ std::array<TExtension, 2u>{{TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer}},
+ BuiltInParameters::p00j00D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetchExt_00r00D(
+ BuiltInId::texelFetchExt_ISamplerBuffer1_Int1,
+ BuiltInName::texelFetchExt,
+ std::array<TExtension, 2u>{{TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer}},
+ BuiltInParameters::p00r00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetchExt_00w00D(
+ BuiltInId::texelFetchExt_USamplerBuffer1_Int1,
+ BuiltInName::texelFetchExt,
+ std::array<TExtension, 2u>{{TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer}},
+ BuiltInParameters::p00w00D,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetch_00P10D00D(
+ BuiltInId::texelFetch_Sampler2DMS1_Int2_Int1,
+ BuiltInName::texelFetch,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00P10D00D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetch_00V10D00D(
+ BuiltInId::texelFetch_ISampler2DMS1_Int2_Int1,
+ BuiltInName::texelFetch,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00V10D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetch_00b10D00D(
+ BuiltInId::texelFetch_USampler2DMS1_Int2_Int1,
+ BuiltInName::texelFetch,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00b10D00D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetchExt_00P10D00D(
+ BuiltInId::texelFetchExt_Sampler2DMS1_Int2_Int1,
+ BuiltInName::texelFetchExt,
+ std::array<TExtension, 1u>{{TExtension::ANGLE_texture_multisample}},
+ BuiltInParameters::p00P10D00D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetchExt_00V10D00D(
+ BuiltInId::texelFetchExt_ISampler2DMS1_Int2_Int1,
+ BuiltInName::texelFetchExt,
+ std::array<TExtension, 1u>{{TExtension::ANGLE_texture_multisample}},
+ BuiltInParameters::p00V10D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetchExt_00b10D00D(
+ BuiltInId::texelFetchExt_USampler2DMS1_Int2_Int1,
+ BuiltInName::texelFetchExt,
+ std::array<TExtension, 1u>{{TExtension::ANGLE_texture_multisample}},
+ BuiltInParameters::p00b10D00D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetch_00Q20D00D(
+ BuiltInId::texelFetch_Sampler2DMSArray1_Int3_Int1,
+ BuiltInName::texelFetch,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Q20D00D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetch_00W20D00D(
+ BuiltInId::texelFetch_ISampler2DMSArray1_Int3_Int1,
+ BuiltInName::texelFetch,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00W20D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetch_00c20D00D(
+ BuiltInId::texelFetch_USampler2DMSArray1_Int3_Int1,
+ BuiltInName::texelFetch,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00c20D00D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetchExt_00Q20D00D(
+ BuiltInId::texelFetchExt_Sampler2DMSArray1_Int3_Int1,
+ BuiltInName::texelFetchExt,
+ std::array<TExtension, 1u>{{TExtension::OES_texture_storage_multisample_2d_array}},
+ BuiltInParameters::p00Q20D00D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetchExt_00W20D00D(
+ BuiltInId::texelFetchExt_ISampler2DMSArray1_Int3_Int1,
+ BuiltInName::texelFetchExt,
+ std::array<TExtension, 1u>{{TExtension::OES_texture_storage_multisample_2d_array}},
+ BuiltInParameters::p00W20D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetchExt_00c20D00D(
+ BuiltInId::texelFetchExt_USampler2DMSArray1_Int3_Int1,
+ BuiltInName::texelFetchExt,
+ std::array<TExtension, 1u>{{TExtension::OES_texture_storage_multisample_2d_array}},
+ BuiltInParameters::p00c20D00D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetch_00M10D00D(
+ BuiltInId::texelFetch_SamplerExternalOES1_Int2_Int1,
+ BuiltInName::texelFetch,
+ std::array<TExtension, 1u>{{TExtension::OES_EGL_image_external_essl3}},
+ BuiltInParameters::p00M10D00D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction texelFetch_00N10D00D(
+ BuiltInId::texelFetch_SamplerExternal2DY2YEXT1_Int2_Int1,
+ BuiltInName::texelFetch,
+ std::array<TExtension, 1u>{{TExtension::EXT_YUV_target}},
+ BuiltInParameters::p00N10D00D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetch,
+ false);
+constexpr const TFunction textureGrad_00I10B10B10B(
+ BuiltInId::textureGrad_Sampler2D1_Float2_Float2_Float2,
+ BuiltInName::textureGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I10B10B10B10D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGrad,
+ false);
+constexpr const TFunction textureGrad_00R10B10B10B(
+ BuiltInId::textureGrad_ISampler2D1_Float2_Float2_Float2,
+ BuiltInName::textureGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R10B10B10B10D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGrad,
+ false);
+constexpr const TFunction textureGrad_00X10B10B10B(
+ BuiltInId::textureGrad_USampler2D1_Float2_Float2_Float2,
+ BuiltInName::textureGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X10B10B10B10D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGrad,
+ false);
+constexpr const TFunction textureGrad_00J20B20B20B(
+ BuiltInId::textureGrad_Sampler3D1_Float3_Float3_Float3,
+ BuiltInName::textureGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00J20B20B20B20D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGrad,
+ false);
+constexpr const TFunction textureGrad_00S20B20B20B(
+ BuiltInId::textureGrad_ISampler3D1_Float3_Float3_Float3,
+ BuiltInName::textureGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00S20B20B20B20D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGrad,
+ false);
+constexpr const TFunction textureGrad_00Y20B20B20B(
+ BuiltInId::textureGrad_USampler3D1_Float3_Float3_Float3,
+ BuiltInName::textureGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Y20B20B20B20D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGrad,
+ false);
+constexpr const TFunction textureGrad_00K20B20B20B(
+ BuiltInId::textureGrad_SamplerCube1_Float3_Float3_Float3,
+ BuiltInName::textureGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00K20B20B20B,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGrad,
+ false);
+constexpr const TFunction textureGrad_00T20B20B20B(
+ BuiltInId::textureGrad_ISamplerCube1_Float3_Float3_Float3,
+ BuiltInName::textureGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00T20B20B20B,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGrad,
+ false);
+constexpr const TFunction textureGrad_00Z20B20B20B(
+ BuiltInId::textureGrad_USamplerCube1_Float3_Float3_Float3,
+ BuiltInName::textureGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Z20B20B20B,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGrad,
+ false);
+constexpr const TFunction textureGrad_00d20B10B10B(
+ BuiltInId::textureGrad_Sampler2DShadow1_Float3_Float2_Float2,
+ BuiltInName::textureGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00d20B10B10B10D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureGrad,
+ false);
+constexpr const TFunction textureGrad_00e30B20B20B(
+ BuiltInId::textureGrad_SamplerCubeShadow1_Float4_Float3_Float3,
+ BuiltInName::textureGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00e30B20B20B,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureGrad,
+ false);
+constexpr const TFunction textureGrad_00L20B10B10B(
+ BuiltInId::textureGrad_Sampler2DArray1_Float3_Float2_Float2,
+ BuiltInName::textureGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00L20B10B10B10D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGrad,
+ false);
+constexpr const TFunction textureGrad_00U20B10B10B(
+ BuiltInId::textureGrad_ISampler2DArray1_Float3_Float2_Float2,
+ BuiltInName::textureGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00U20B10B10B10D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGrad,
+ false);
+constexpr const TFunction textureGrad_00a20B10B10B(
+ BuiltInId::textureGrad_USampler2DArray1_Float3_Float2_Float2,
+ BuiltInName::textureGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00a20B10B10B10D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGrad,
+ false);
+constexpr const TFunction textureGrad_00f30B10B10B(
+ BuiltInId::textureGrad_Sampler2DArrayShadow1_Float4_Float2_Float2,
+ BuiltInName::textureGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00f30B10B10B10D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureGrad,
+ false);
+constexpr const TFunction textureGrad_00k30B20B20B(
+ BuiltInId::textureGrad_SamplerCubeArray1_Float4_Float3_Float3,
+ BuiltInName::textureGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00k30B20B20B,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGrad,
+ false);
+constexpr const TFunction textureGrad_00s30B20B20B(
+ BuiltInId::textureGrad_ISamplerCubeArray1_Float4_Float3_Float3,
+ BuiltInName::textureGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00s30B20B20B,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGrad,
+ false);
+constexpr const TFunction textureGrad_00x30B20B20B(
+ BuiltInId::textureGrad_USamplerCubeArray1_Float4_Float3_Float3,
+ BuiltInName::textureGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00x30B20B20B,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGrad,
+ false);
+constexpr const TFunction textureGradExt_00k30B20B20B(
+ BuiltInId::textureGradExt_SamplerCubeArray1_Float4_Float3_Float3,
+ BuiltInName::textureGradExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00k30B20B20B,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGrad,
+ false);
+constexpr const TFunction textureGradExt_00s30B20B20B(
+ BuiltInId::textureGradExt_ISamplerCubeArray1_Float4_Float3_Float3,
+ BuiltInName::textureGradExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00s30B20B20B,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGrad,
+ false);
+constexpr const TFunction textureGradExt_00x30B20B20B(
+ BuiltInId::textureGradExt_USamplerCubeArray1_Float4_Float3_Float3,
+ BuiltInName::textureGradExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00x30B20B20B,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGrad,
+ false);
+constexpr const TFunction textureProjGrad_00I20B10B10B(
+ BuiltInId::textureProjGrad_Sampler2D1_Float3_Float2_Float2,
+ BuiltInName::textureProjGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I20B10B10B10D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjGrad,
+ false);
+constexpr const TFunction textureProjGrad_00R20B10B10B(
+ BuiltInId::textureProjGrad_ISampler2D1_Float3_Float2_Float2,
+ BuiltInName::textureProjGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R20B10B10B10D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjGrad,
+ false);
+constexpr const TFunction textureProjGrad_00X20B10B10B(
+ BuiltInId::textureProjGrad_USampler2D1_Float3_Float2_Float2,
+ BuiltInName::textureProjGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X20B10B10B10D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjGrad,
+ false);
+constexpr const TFunction textureProjGrad_00I30B10B10B(
+ BuiltInId::textureProjGrad_Sampler2D1_Float4_Float2_Float2,
+ BuiltInName::textureProjGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I30B10B10B10D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjGrad,
+ false);
+constexpr const TFunction textureProjGrad_00R30B10B10B(
+ BuiltInId::textureProjGrad_ISampler2D1_Float4_Float2_Float2,
+ BuiltInName::textureProjGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R30B10B10B10D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjGrad,
+ false);
+constexpr const TFunction textureProjGrad_00X30B10B10B(
+ BuiltInId::textureProjGrad_USampler2D1_Float4_Float2_Float2,
+ BuiltInName::textureProjGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X30B10B10B10D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjGrad,
+ false);
+constexpr const TFunction textureProjGrad_00J30B20B20B(
+ BuiltInId::textureProjGrad_Sampler3D1_Float4_Float3_Float3,
+ BuiltInName::textureProjGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00J30B20B20B20D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjGrad,
+ false);
+constexpr const TFunction textureProjGrad_00S30B20B20B(
+ BuiltInId::textureProjGrad_ISampler3D1_Float4_Float3_Float3,
+ BuiltInName::textureProjGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00S30B20B20B20D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjGrad,
+ false);
+constexpr const TFunction textureProjGrad_00Y30B20B20B(
+ BuiltInId::textureProjGrad_USampler3D1_Float4_Float3_Float3,
+ BuiltInName::textureProjGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Y30B20B20B20D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjGrad,
+ false);
+constexpr const TFunction textureProjGrad_00d30B10B10B(
+ BuiltInId::textureProjGrad_Sampler2DShadow1_Float4_Float2_Float2,
+ BuiltInName::textureProjGrad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00d30B10B10B10D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureProjGrad,
+ false);
+constexpr const TFunction texture_00I10B00B(
+ BuiltInId::texture_Sampler2D1_Float2_Float1,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I10B00B10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction texture_00R10B00B(
+ BuiltInId::texture_ISampler2D1_Float2_Float1,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R10B00B10D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction texture_00X10B00B(
+ BuiltInId::texture_USampler2D1_Float2_Float1,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X10B00B10D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction texture_00J20B00B(
+ BuiltInId::texture_Sampler3D1_Float3_Float1,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00J20B00B20D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction texture_00S20B00B(
+ BuiltInId::texture_ISampler3D1_Float3_Float1,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00S20B00B20D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction texture_00Y20B00B(
+ BuiltInId::texture_USampler3D1_Float3_Float1,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Y20B00B20D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction texture_00K20B00B(
+ BuiltInId::texture_SamplerCube1_Float3_Float1,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00K20B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction texture_00T20B00B(
+ BuiltInId::texture_ISamplerCube1_Float3_Float1,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00T20B00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction texture_00Z20B00B(
+ BuiltInId::texture_USamplerCube1_Float3_Float1,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Z20B00B,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction texture_00L20B00B(
+ BuiltInId::texture_Sampler2DArray1_Float3_Float1,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00L20B00B10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction texture_00U20B00B(
+ BuiltInId::texture_ISampler2DArray1_Float3_Float1,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00U20B00B10D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction texture_00a20B00B(
+ BuiltInId::texture_USampler2DArray1_Float3_Float1,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00a20B00B10D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction textureProj_00I20B00B(
+ BuiltInId::textureProj_Sampler2D1_Float3_Float1,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I20B00B10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjBias,
+ false);
+constexpr const TFunction textureProj_00R20B00B(
+ BuiltInId::textureProj_ISampler2D1_Float3_Float1,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R20B00B10D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjBias,
+ false);
+constexpr const TFunction textureProj_00X20B00B(
+ BuiltInId::textureProj_USampler2D1_Float3_Float1,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X20B00B10D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjBias,
+ false);
+constexpr const TFunction textureProj_00I30B00B(
+ BuiltInId::textureProj_Sampler2D1_Float4_Float1,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I30B00B10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjBias,
+ false);
+constexpr const TFunction textureProj_00R30B00B(
+ BuiltInId::textureProj_ISampler2D1_Float4_Float1,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R30B00B10D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjBias,
+ false);
+constexpr const TFunction textureProj_00X30B00B(
+ BuiltInId::textureProj_USampler2D1_Float4_Float1,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X30B00B10D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjBias,
+ false);
+constexpr const TFunction textureProj_00J30B00B(
+ BuiltInId::textureProj_Sampler3D1_Float4_Float1,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00J30B00B20D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjBias,
+ false);
+constexpr const TFunction textureProj_00S30B00B(
+ BuiltInId::textureProj_ISampler3D1_Float4_Float1,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00S30B00B20D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjBias,
+ false);
+constexpr const TFunction textureProj_00Y30B00B(
+ BuiltInId::textureProj_USampler3D1_Float4_Float1,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Y30B00B20D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjBias,
+ false);
+constexpr const TFunction texture_00d20B00B(
+ BuiltInId::texture_Sampler2DShadow1_Float3_Float1,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00d20B00B10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction texture_00e30B00B(
+ BuiltInId::texture_SamplerCubeShadow1_Float4_Float1,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00e30B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction textureProj_00d30B00B(
+ BuiltInId::textureProj_Sampler2DShadow1_Float4_Float1,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00d30B00B10D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureProjBias,
+ false);
+constexpr const TFunction texture_00k30B00B(
+ BuiltInId::texture_SamplerCubeArray1_Float4_Float1,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00k30B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction texture_00s30B00B(
+ BuiltInId::texture_ISamplerCubeArray1_Float4_Float1,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00s30B00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction texture_00x30B00B(
+ BuiltInId::texture_USamplerCubeArray1_Float4_Float1,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00x30B00B,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction textureExt_00k30B00B(
+ BuiltInId::textureExt_SamplerCubeArray1_Float4_Float1,
+ BuiltInName::textureExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00k30B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction textureExt_00s30B00B(
+ BuiltInId::textureExt_ISamplerCubeArray1_Float4_Float1,
+ BuiltInName::textureExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00s30B00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction textureExt_00x30B00B(
+ BuiltInId::textureExt_USamplerCubeArray1_Float4_Float1,
+ BuiltInName::textureExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00x30B00B,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction texture_00M10B00B(
+ BuiltInId::texture_SamplerExternalOES1_Float2_Float1,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::OES_EGL_image_external_essl3}},
+ BuiltInParameters::p00M10B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction textureProj_00M20B00B(
+ BuiltInId::textureProj_SamplerExternalOES1_Float3_Float1,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::OES_EGL_image_external_essl3}},
+ BuiltInParameters::p00M20B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjBias,
+ false);
+constexpr const TFunction textureProj_00M30B00B(
+ BuiltInId::textureProj_SamplerExternalOES1_Float4_Float1,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::OES_EGL_image_external_essl3}},
+ BuiltInParameters::p00M30B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjBias,
+ false);
+constexpr const TFunction texture_00N10B00B(
+ BuiltInId::texture_SamplerExternal2DY2YEXT1_Float2_Float1,
+ BuiltInName::texture,
+ std::array<TExtension, 1u>{{TExtension::EXT_YUV_target}},
+ BuiltInParameters::p00N10B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureBias,
+ false);
+constexpr const TFunction textureProj_00N20B00B(
+ BuiltInId::textureProj_SamplerExternal2DY2YEXT1_Float3_Float1,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::EXT_YUV_target}},
+ BuiltInParameters::p00N20B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjBias,
+ false);
+constexpr const TFunction textureProj_00N30B00B(
+ BuiltInId::textureProj_SamplerExternal2DY2YEXT1_Float4_Float1,
+ BuiltInName::textureProj,
+ std::array<TExtension, 1u>{{TExtension::EXT_YUV_target}},
+ BuiltInParameters::p00N30B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjBias,
+ false);
+constexpr const TFunction textureOffset_00I10B10D(
+ BuiltInId::textureOffset_Sampler2D1_Float2_Int2,
+ BuiltInName::textureOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I10B10D00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureOffset,
+ false);
+constexpr const TFunction textureOffset_00R10B10D(
+ BuiltInId::textureOffset_ISampler2D1_Float2_Int2,
+ BuiltInName::textureOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R10B10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureOffset,
+ false);
+constexpr const TFunction textureOffset_00X10B10D(
+ BuiltInId::textureOffset_USampler2D1_Float2_Int2,
+ BuiltInName::textureOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X10B10D00B,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureOffset,
+ false);
+constexpr const TFunction textureOffset_00J20B20D(
+ BuiltInId::textureOffset_Sampler3D1_Float3_Int3,
+ BuiltInName::textureOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00J20B20D00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureOffset,
+ false);
+constexpr const TFunction textureOffset_00S20B20D(
+ BuiltInId::textureOffset_ISampler3D1_Float3_Int3,
+ BuiltInName::textureOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00S20B20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureOffset,
+ false);
+constexpr const TFunction textureOffset_00Y20B20D(
+ BuiltInId::textureOffset_USampler3D1_Float3_Int3,
+ BuiltInName::textureOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Y20B20D00B,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureOffset,
+ false);
+constexpr const TFunction textureOffset_00d20B10D(
+ BuiltInId::textureOffset_Sampler2DShadow1_Float3_Int2,
+ BuiltInName::textureOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00d20B10D00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureOffset,
+ false);
+constexpr const TFunction textureOffset_00L20B10D(
+ BuiltInId::textureOffset_Sampler2DArray1_Float3_Int2,
+ BuiltInName::textureOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00L20B10D00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureOffset,
+ false);
+constexpr const TFunction textureOffset_00U20B10D(
+ BuiltInId::textureOffset_ISampler2DArray1_Float3_Int2,
+ BuiltInName::textureOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00U20B10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureOffset,
+ false);
+constexpr const TFunction textureOffset_00a20B10D(
+ BuiltInId::textureOffset_USampler2DArray1_Float3_Int2,
+ BuiltInName::textureOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00a20B10D00B,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureOffset,
+ false);
+constexpr const TFunction textureProjOffset_00I20B10D(
+ BuiltInId::textureProjOffset_Sampler2D1_Float3_Int2,
+ BuiltInName::textureProjOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I20B10D00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjOffset,
+ false);
+constexpr const TFunction textureProjOffset_00R20B10D(
+ BuiltInId::textureProjOffset_ISampler2D1_Float3_Int2,
+ BuiltInName::textureProjOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R20B10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjOffset,
+ false);
+constexpr const TFunction textureProjOffset_00X20B10D(
+ BuiltInId::textureProjOffset_USampler2D1_Float3_Int2,
+ BuiltInName::textureProjOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X20B10D00B,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjOffset,
+ false);
+constexpr const TFunction textureProjOffset_00I30B10D(
+ BuiltInId::textureProjOffset_Sampler2D1_Float4_Int2,
+ BuiltInName::textureProjOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I30B10D00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjOffset,
+ false);
+constexpr const TFunction textureProjOffset_00R30B10D(
+ BuiltInId::textureProjOffset_ISampler2D1_Float4_Int2,
+ BuiltInName::textureProjOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R30B10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjOffset,
+ false);
+constexpr const TFunction textureProjOffset_00X30B10D(
+ BuiltInId::textureProjOffset_USampler2D1_Float4_Int2,
+ BuiltInName::textureProjOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X30B10D00B,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjOffset,
+ false);
+constexpr const TFunction textureProjOffset_00J30B20D(
+ BuiltInId::textureProjOffset_Sampler3D1_Float4_Int3,
+ BuiltInName::textureProjOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00J30B20D00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjOffset,
+ false);
+constexpr const TFunction textureProjOffset_00S30B20D(
+ BuiltInId::textureProjOffset_ISampler3D1_Float4_Int3,
+ BuiltInName::textureProjOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00S30B20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjOffset,
+ false);
+constexpr const TFunction textureProjOffset_00Y30B20D(
+ BuiltInId::textureProjOffset_USampler3D1_Float4_Int3,
+ BuiltInName::textureProjOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Y30B20D00B,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjOffset,
+ false);
+constexpr const TFunction textureProjOffset_00d30B10D(
+ BuiltInId::textureProjOffset_Sampler2DShadow1_Float4_Int2,
+ BuiltInName::textureProjOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00d30B10D00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureProjOffset,
+ false);
+constexpr const TFunction textureLodOffset_00I10B00B10D(
+ BuiltInId::textureLodOffset_Sampler2D1_Float2_Float1_Int2,
+ BuiltInName::textureLodOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I10B00B10D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLodOffset,
+ false);
+constexpr const TFunction textureLodOffset_00R10B00B10D(
+ BuiltInId::textureLodOffset_ISampler2D1_Float2_Float1_Int2,
+ BuiltInName::textureLodOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R10B00B10D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLodOffset,
+ false);
+constexpr const TFunction textureLodOffset_00X10B00B10D(
+ BuiltInId::textureLodOffset_USampler2D1_Float2_Float1_Int2,
+ BuiltInName::textureLodOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X10B00B10D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLodOffset,
+ false);
+constexpr const TFunction textureLodOffset_00J20B00B20D(
+ BuiltInId::textureLodOffset_Sampler3D1_Float3_Float1_Int3,
+ BuiltInName::textureLodOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00J20B00B20D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLodOffset,
+ false);
+constexpr const TFunction textureLodOffset_00S20B00B20D(
+ BuiltInId::textureLodOffset_ISampler3D1_Float3_Float1_Int3,
+ BuiltInName::textureLodOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00S20B00B20D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLodOffset,
+ false);
+constexpr const TFunction textureLodOffset_00Y20B00B20D(
+ BuiltInId::textureLodOffset_USampler3D1_Float3_Float1_Int3,
+ BuiltInName::textureLodOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Y20B00B20D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLodOffset,
+ false);
+constexpr const TFunction textureLodOffset_00d20B00B10D(
+ BuiltInId::textureLodOffset_Sampler2DShadow1_Float3_Float1_Int2,
+ BuiltInName::textureLodOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00d20B00B10D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureLodOffset,
+ false);
+constexpr const TFunction textureLodOffset_00L20B00B10D(
+ BuiltInId::textureLodOffset_Sampler2DArray1_Float3_Float1_Int2,
+ BuiltInName::textureLodOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00L20B00B10D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLodOffset,
+ false);
+constexpr const TFunction textureLodOffset_00U20B00B10D(
+ BuiltInId::textureLodOffset_ISampler2DArray1_Float3_Float1_Int2,
+ BuiltInName::textureLodOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00U20B00B10D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLodOffset,
+ false);
+constexpr const TFunction textureLodOffset_00a20B00B10D(
+ BuiltInId::textureLodOffset_USampler2DArray1_Float3_Float1_Int2,
+ BuiltInName::textureLodOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00a20B00B10D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureLodOffset,
+ false);
+constexpr const TFunction textureProjLodOffset_00I20B00B10D(
+ BuiltInId::textureProjLodOffset_Sampler2D1_Float3_Float1_Int2,
+ BuiltInName::textureProjLodOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I20B00B10D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjLodOffset,
+ false);
+constexpr const TFunction textureProjLodOffset_00R20B00B10D(
+ BuiltInId::textureProjLodOffset_ISampler2D1_Float3_Float1_Int2,
+ BuiltInName::textureProjLodOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R20B00B10D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjLodOffset,
+ false);
+constexpr const TFunction textureProjLodOffset_00X20B00B10D(
+ BuiltInId::textureProjLodOffset_USampler2D1_Float3_Float1_Int2,
+ BuiltInName::textureProjLodOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X20B00B10D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjLodOffset,
+ false);
+constexpr const TFunction textureProjLodOffset_00I30B00B10D(
+ BuiltInId::textureProjLodOffset_Sampler2D1_Float4_Float1_Int2,
+ BuiltInName::textureProjLodOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I30B00B10D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjLodOffset,
+ false);
+constexpr const TFunction textureProjLodOffset_00R30B00B10D(
+ BuiltInId::textureProjLodOffset_ISampler2D1_Float4_Float1_Int2,
+ BuiltInName::textureProjLodOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R30B00B10D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjLodOffset,
+ false);
+constexpr const TFunction textureProjLodOffset_00X30B00B10D(
+ BuiltInId::textureProjLodOffset_USampler2D1_Float4_Float1_Int2,
+ BuiltInName::textureProjLodOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X30B00B10D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjLodOffset,
+ false);
+constexpr const TFunction textureProjLodOffset_00J30B00B20D(
+ BuiltInId::textureProjLodOffset_Sampler3D1_Float4_Float1_Int3,
+ BuiltInName::textureProjLodOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00J30B00B20D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjLodOffset,
+ false);
+constexpr const TFunction textureProjLodOffset_00S30B00B20D(
+ BuiltInId::textureProjLodOffset_ISampler3D1_Float4_Float1_Int3,
+ BuiltInName::textureProjLodOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00S30B00B20D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjLodOffset,
+ false);
+constexpr const TFunction textureProjLodOffset_00Y30B00B20D(
+ BuiltInId::textureProjLodOffset_USampler3D1_Float4_Float1_Int3,
+ BuiltInName::textureProjLodOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Y30B00B20D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjLodOffset,
+ false);
+constexpr const TFunction textureProjLodOffset_00d30B00B10D(
+ BuiltInId::textureProjLodOffset_Sampler2DShadow1_Float4_Float1_Int2,
+ BuiltInName::textureProjLodOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00d30B00B10D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureProjLodOffset,
+ false);
+constexpr const TFunction texelFetchOffset_00I10D00D10D(
+ BuiltInId::texelFetchOffset_Sampler2D1_Int2_Int1_Int2,
+ BuiltInName::texelFetchOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I10D00D10D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetchOffset,
+ false);
+constexpr const TFunction texelFetchOffset_00R10D00D10D(
+ BuiltInId::texelFetchOffset_ISampler2D1_Int2_Int1_Int2,
+ BuiltInName::texelFetchOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R10D00D10D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetchOffset,
+ false);
+constexpr const TFunction texelFetchOffset_00X10D00D10D(
+ BuiltInId::texelFetchOffset_USampler2D1_Int2_Int1_Int2,
+ BuiltInName::texelFetchOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X10D00D10D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetchOffset,
+ false);
+constexpr const TFunction texelFetchOffset_00J20D00D20D(
+ BuiltInId::texelFetchOffset_Sampler3D1_Int3_Int1_Int3,
+ BuiltInName::texelFetchOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00J20D00D20D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetchOffset,
+ false);
+constexpr const TFunction texelFetchOffset_00S20D00D20D(
+ BuiltInId::texelFetchOffset_ISampler3D1_Int3_Int1_Int3,
+ BuiltInName::texelFetchOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00S20D00D20D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetchOffset,
+ false);
+constexpr const TFunction texelFetchOffset_00Y20D00D20D(
+ BuiltInId::texelFetchOffset_USampler3D1_Int3_Int1_Int3,
+ BuiltInName::texelFetchOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Y20D00D20D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetchOffset,
+ false);
+constexpr const TFunction texelFetchOffset_00L20D00D10D(
+ BuiltInId::texelFetchOffset_Sampler2DArray1_Int3_Int1_Int2,
+ BuiltInName::texelFetchOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00L20D00D10D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetchOffset,
+ false);
+constexpr const TFunction texelFetchOffset_00U20D00D10D(
+ BuiltInId::texelFetchOffset_ISampler2DArray1_Int3_Int1_Int2,
+ BuiltInName::texelFetchOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00U20D00D10D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetchOffset,
+ false);
+constexpr const TFunction texelFetchOffset_00a20D00D10D(
+ BuiltInId::texelFetchOffset_USampler2DArray1_Int3_Int1_Int2,
+ BuiltInName::texelFetchOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00a20D00D10D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTexelFetchOffset,
+ false);
+constexpr const TFunction textureGradOffset_00I10B10B10B10D(
+ BuiltInId::textureGradOffset_Sampler2D1_Float2_Float2_Float2_Int2,
+ BuiltInName::textureGradOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I10B10B10B10D,
+ 5,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGradOffset,
+ false);
+constexpr const TFunction textureGradOffset_00R10B10B10B10D(
+ BuiltInId::textureGradOffset_ISampler2D1_Float2_Float2_Float2_Int2,
+ BuiltInName::textureGradOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R10B10B10B10D,
+ 5,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGradOffset,
+ false);
+constexpr const TFunction textureGradOffset_00X10B10B10B10D(
+ BuiltInId::textureGradOffset_USampler2D1_Float2_Float2_Float2_Int2,
+ BuiltInName::textureGradOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X10B10B10B10D,
+ 5,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGradOffset,
+ false);
+constexpr const TFunction textureGradOffset_00J20B20B20B20D(
+ BuiltInId::textureGradOffset_Sampler3D1_Float3_Float3_Float3_Int3,
+ BuiltInName::textureGradOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00J20B20B20B20D,
+ 5,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGradOffset,
+ false);
+constexpr const TFunction textureGradOffset_00S20B20B20B20D(
+ BuiltInId::textureGradOffset_ISampler3D1_Float3_Float3_Float3_Int3,
+ BuiltInName::textureGradOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00S20B20B20B20D,
+ 5,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGradOffset,
+ false);
+constexpr const TFunction textureGradOffset_00Y20B20B20B20D(
+ BuiltInId::textureGradOffset_USampler3D1_Float3_Float3_Float3_Int3,
+ BuiltInName::textureGradOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Y20B20B20B20D,
+ 5,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGradOffset,
+ false);
+constexpr const TFunction textureGradOffset_00d20B10B10B10D(
+ BuiltInId::textureGradOffset_Sampler2DShadow1_Float3_Float2_Float2_Int2,
+ BuiltInName::textureGradOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00d20B10B10B10D,
+ 5,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureGradOffset,
+ false);
+constexpr const TFunction textureGradOffset_00L20B10B10B10D(
+ BuiltInId::textureGradOffset_Sampler2DArray1_Float3_Float2_Float2_Int2,
+ BuiltInName::textureGradOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00L20B10B10B10D,
+ 5,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGradOffset,
+ false);
+constexpr const TFunction textureGradOffset_00U20B10B10B10D(
+ BuiltInId::textureGradOffset_ISampler2DArray1_Float3_Float2_Float2_Int2,
+ BuiltInName::textureGradOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00U20B10B10B10D,
+ 5,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGradOffset,
+ false);
+constexpr const TFunction textureGradOffset_00a20B10B10B10D(
+ BuiltInId::textureGradOffset_USampler2DArray1_Float3_Float2_Float2_Int2,
+ BuiltInName::textureGradOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00a20B10B10B10D,
+ 5,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGradOffset,
+ false);
+constexpr const TFunction textureGradOffset_00f30B10B10B10D(
+ BuiltInId::textureGradOffset_Sampler2DArrayShadow1_Float4_Float2_Float2_Int2,
+ BuiltInName::textureGradOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00f30B10B10B10D,
+ 5,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureGradOffset,
+ false);
+constexpr const TFunction textureProjGradOffset_00I20B10B10B10D(
+ BuiltInId::textureProjGradOffset_Sampler2D1_Float3_Float2_Float2_Int2,
+ BuiltInName::textureProjGradOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I20B10B10B10D,
+ 5,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjGradOffset,
+ false);
+constexpr const TFunction textureProjGradOffset_00R20B10B10B10D(
+ BuiltInId::textureProjGradOffset_ISampler2D1_Float3_Float2_Float2_Int2,
+ BuiltInName::textureProjGradOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R20B10B10B10D,
+ 5,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjGradOffset,
+ false);
+constexpr const TFunction textureProjGradOffset_00X20B10B10B10D(
+ BuiltInId::textureProjGradOffset_USampler2D1_Float3_Float2_Float2_Int2,
+ BuiltInName::textureProjGradOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X20B10B10B10D,
+ 5,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjGradOffset,
+ false);
+constexpr const TFunction textureProjGradOffset_00I30B10B10B10D(
+ BuiltInId::textureProjGradOffset_Sampler2D1_Float4_Float2_Float2_Int2,
+ BuiltInName::textureProjGradOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I30B10B10B10D,
+ 5,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjGradOffset,
+ false);
+constexpr const TFunction textureProjGradOffset_00R30B10B10B10D(
+ BuiltInId::textureProjGradOffset_ISampler2D1_Float4_Float2_Float2_Int2,
+ BuiltInName::textureProjGradOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R30B10B10B10D,
+ 5,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjGradOffset,
+ false);
+constexpr const TFunction textureProjGradOffset_00X30B10B10B10D(
+ BuiltInId::textureProjGradOffset_USampler2D1_Float4_Float2_Float2_Int2,
+ BuiltInName::textureProjGradOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X30B10B10B10D,
+ 5,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjGradOffset,
+ false);
+constexpr const TFunction textureProjGradOffset_00J30B20B20B20D(
+ BuiltInId::textureProjGradOffset_Sampler3D1_Float4_Float3_Float3_Int3,
+ BuiltInName::textureProjGradOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00J30B20B20B20D,
+ 5,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjGradOffset,
+ false);
+constexpr const TFunction textureProjGradOffset_00S30B20B20B20D(
+ BuiltInId::textureProjGradOffset_ISampler3D1_Float4_Float3_Float3_Int3,
+ BuiltInName::textureProjGradOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00S30B20B20B20D,
+ 5,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjGradOffset,
+ false);
+constexpr const TFunction textureProjGradOffset_00Y30B20B20B20D(
+ BuiltInId::textureProjGradOffset_USampler3D1_Float4_Float3_Float3_Int3,
+ BuiltInName::textureProjGradOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Y30B20B20B20D,
+ 5,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjGradOffset,
+ false);
+constexpr const TFunction textureProjGradOffset_00d30B10B10B10D(
+ BuiltInId::textureProjGradOffset_Sampler2DShadow1_Float4_Float2_Float2_Int2,
+ BuiltInName::textureProjGradOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00d30B10B10B10D,
+ 5,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureProjGradOffset,
+ false);
+constexpr const TFunction textureOffset_00I10B10D00B(
+ BuiltInId::textureOffset_Sampler2D1_Float2_Int2_Float1,
+ BuiltInName::textureOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I10B10D00B,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureOffsetBias,
+ false);
+constexpr const TFunction textureOffset_00R10B10D00B(
+ BuiltInId::textureOffset_ISampler2D1_Float2_Int2_Float1,
+ BuiltInName::textureOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R10B10D00B,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureOffsetBias,
+ false);
+constexpr const TFunction textureOffset_00X10B10D00B(
+ BuiltInId::textureOffset_USampler2D1_Float2_Int2_Float1,
+ BuiltInName::textureOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X10B10D00B,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureOffsetBias,
+ false);
+constexpr const TFunction textureOffset_00J20B20D00B(
+ BuiltInId::textureOffset_Sampler3D1_Float3_Int3_Float1,
+ BuiltInName::textureOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00J20B20D00B,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureOffsetBias,
+ false);
+constexpr const TFunction textureOffset_00S20B20D00B(
+ BuiltInId::textureOffset_ISampler3D1_Float3_Int3_Float1,
+ BuiltInName::textureOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00S20B20D00B,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureOffsetBias,
+ false);
+constexpr const TFunction textureOffset_00Y20B20D00B(
+ BuiltInId::textureOffset_USampler3D1_Float3_Int3_Float1,
+ BuiltInName::textureOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Y20B20D00B,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureOffsetBias,
+ false);
+constexpr const TFunction textureOffset_00d20B10D00B(
+ BuiltInId::textureOffset_Sampler2DShadow1_Float3_Int2_Float1,
+ BuiltInName::textureOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00d20B10D00B,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureOffsetBias,
+ false);
+constexpr const TFunction textureOffset_00L20B10D00B(
+ BuiltInId::textureOffset_Sampler2DArray1_Float3_Int2_Float1,
+ BuiltInName::textureOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00L20B10D00B,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureOffsetBias,
+ false);
+constexpr const TFunction textureOffset_00U20B10D00B(
+ BuiltInId::textureOffset_ISampler2DArray1_Float3_Int2_Float1,
+ BuiltInName::textureOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00U20B10D00B,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureOffsetBias,
+ false);
+constexpr const TFunction textureOffset_00a20B10D00B(
+ BuiltInId::textureOffset_USampler2DArray1_Float3_Int2_Float1,
+ BuiltInName::textureOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00a20B10D00B,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureOffsetBias,
+ false);
+constexpr const TFunction textureProjOffset_00I20B10D00B(
+ BuiltInId::textureProjOffset_Sampler2D1_Float3_Int2_Float1,
+ BuiltInName::textureProjOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I20B10D00B,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjOffsetBias,
+ false);
+constexpr const TFunction textureProjOffset_00R20B10D00B(
+ BuiltInId::textureProjOffset_ISampler2D1_Float3_Int2_Float1,
+ BuiltInName::textureProjOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R20B10D00B,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjOffsetBias,
+ false);
+constexpr const TFunction textureProjOffset_00X20B10D00B(
+ BuiltInId::textureProjOffset_USampler2D1_Float3_Int2_Float1,
+ BuiltInName::textureProjOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X20B10D00B,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjOffsetBias,
+ false);
+constexpr const TFunction textureProjOffset_00I30B10D00B(
+ BuiltInId::textureProjOffset_Sampler2D1_Float4_Int2_Float1,
+ BuiltInName::textureProjOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I30B10D00B,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjOffsetBias,
+ false);
+constexpr const TFunction textureProjOffset_00R30B10D00B(
+ BuiltInId::textureProjOffset_ISampler2D1_Float4_Int2_Float1,
+ BuiltInName::textureProjOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R30B10D00B,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjOffsetBias,
+ false);
+constexpr const TFunction textureProjOffset_00X30B10D00B(
+ BuiltInId::textureProjOffset_USampler2D1_Float4_Int2_Float1,
+ BuiltInName::textureProjOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X30B10D00B,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjOffsetBias,
+ false);
+constexpr const TFunction textureProjOffset_00J30B20D00B(
+ BuiltInId::textureProjOffset_Sampler3D1_Float4_Int3_Float1,
+ BuiltInName::textureProjOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00J30B20D00B,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjOffsetBias,
+ false);
+constexpr const TFunction textureProjOffset_00S30B20D00B(
+ BuiltInId::textureProjOffset_ISampler3D1_Float4_Int3_Float1,
+ BuiltInName::textureProjOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00S30B20D00B,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjOffsetBias,
+ false);
+constexpr const TFunction textureProjOffset_00Y30B20D00B(
+ BuiltInId::textureProjOffset_USampler3D1_Float4_Int3_Float1,
+ BuiltInName::textureProjOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Y30B20D00B,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureProjOffsetBias,
+ false);
+constexpr const TFunction textureProjOffset_00d30B10D00B(
+ BuiltInId::textureProjOffset_Sampler2DShadow1_Float4_Int2_Float1,
+ BuiltInName::textureProjOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00d30B10D00B,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpTextureProjOffsetBias,
+ false);
+constexpr const TFunction textureGather_00I10B(
+ BuiltInId::textureGather_Sampler2D1_Float2,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I10B00B10D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00R10B(
+ BuiltInId::textureGather_ISampler2D1_Float2,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R10B00B10D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00X10B(
+ BuiltInId::textureGather_USampler2D1_Float2,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X10B00B10D,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00I10B00D(
+ BuiltInId::textureGather_Sampler2D1_Float2_Int1,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I10B00D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00R10B00D(
+ BuiltInId::textureGather_ISampler2D1_Float2_Int1,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R10B00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00X10B00D(
+ BuiltInId::textureGather_USampler2D1_Float2_Int1,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X10B00D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00L20B(
+ BuiltInId::textureGather_Sampler2DArray1_Float3,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00L20B00B10D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00U20B(
+ BuiltInId::textureGather_ISampler2DArray1_Float3,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00U20B00B10D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00a20B(
+ BuiltInId::textureGather_USampler2DArray1_Float3,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00a20B00B10D,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00L20B00D(
+ BuiltInId::textureGather_Sampler2DArray1_Float3_Int1,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00L20B00D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00U20B00D(
+ BuiltInId::textureGather_ISampler2DArray1_Float3_Int1,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00U20B00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00a20B00D(
+ BuiltInId::textureGather_USampler2DArray1_Float3_Int1,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00a20B00D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00K20B(
+ BuiltInId::textureGather_SamplerCube1_Float3,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00K20B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00T20B(
+ BuiltInId::textureGather_ISamplerCube1_Float3,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00T20B00B,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00Z20B(
+ BuiltInId::textureGather_USamplerCube1_Float3,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Z20B00B,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00K20B00D(
+ BuiltInId::textureGather_SamplerCube1_Float3_Int1,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00K20B00D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00T20B00D(
+ BuiltInId::textureGather_ISamplerCube1_Float3_Int1,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00T20B00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00Z20B00D(
+ BuiltInId::textureGather_USamplerCube1_Float3_Int1,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00Z20B00D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00k30B(
+ BuiltInId::textureGather_SamplerCubeArray1_Float4,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00k30B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00s30B(
+ BuiltInId::textureGather_ISamplerCubeArray1_Float4,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00s30B00B,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00x30B(
+ BuiltInId::textureGather_USamplerCubeArray1_Float4,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00x30B00B,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00k30B00D(
+ BuiltInId::textureGather_SamplerCubeArray1_Float4_Int1,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00k30B00D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00s30B00D(
+ BuiltInId::textureGather_ISamplerCubeArray1_Float4_Int1,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00s30B00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00x30B00D(
+ BuiltInId::textureGather_USamplerCubeArray1_Float4_Int1,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00x30B00D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00l30B00B(
+ BuiltInId::textureGather_SamplerCubeArrayShadow1_Float4_Float1,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00l30B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGatherExt_00k30B(
+ BuiltInId::textureGatherExt_SamplerCubeArray1_Float4,
+ BuiltInName::textureGatherExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00k30B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGatherExt_00s30B(
+ BuiltInId::textureGatherExt_ISamplerCubeArray1_Float4,
+ BuiltInName::textureGatherExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00s30B00B,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGatherExt_00x30B(
+ BuiltInId::textureGatherExt_USamplerCubeArray1_Float4,
+ BuiltInName::textureGatherExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00x30B00B,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGatherExt_00k30B00D(
+ BuiltInId::textureGatherExt_SamplerCubeArray1_Float4_Int1,
+ BuiltInName::textureGatherExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00k30B00D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGatherExt_00s30B00D(
+ BuiltInId::textureGatherExt_ISamplerCubeArray1_Float4_Int1,
+ BuiltInName::textureGatherExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00s30B00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGatherExt_00x30B00D(
+ BuiltInId::textureGatherExt_USamplerCubeArray1_Float4_Int1,
+ BuiltInName::textureGatherExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00x30B00D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGatherExt_00l30B00B(
+ BuiltInId::textureGatherExt_SamplerCubeArrayShadow1_Float4_Float1,
+ BuiltInName::textureGatherExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p00l30B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00d10B(
+ BuiltInId::textureGather_Sampler2DShadow1_Float2,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00d10B00B10Dx4,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00d10B00B(
+ BuiltInId::textureGather_Sampler2DShadow1_Float2_Float1,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00d10B00B10Dx4,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00f20B(
+ BuiltInId::textureGather_Sampler2DArrayShadow1_Float3,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00f20B00B10Dx4,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00f20B00B(
+ BuiltInId::textureGather_Sampler2DArrayShadow1_Float3_Float1,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00f20B00B10Dx4,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00e20B(
+ BuiltInId::textureGather_SamplerCubeShadow1_Float3,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00e20B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGather_00e20B00B(
+ BuiltInId::textureGather_SamplerCubeShadow1_Float3_Float1,
+ BuiltInName::textureGather,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00e20B00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGather,
+ false);
+constexpr const TFunction textureGatherOffset_00I10B10D(
+ BuiltInId::textureGatherOffset_Sampler2D1_Float2_Int2,
+ BuiltInName::textureGatherOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I10B10D00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffset,
+ false);
+constexpr const TFunction textureGatherOffset_00R10B10D(
+ BuiltInId::textureGatherOffset_ISampler2D1_Float2_Int2,
+ BuiltInName::textureGatherOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R10B10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffset,
+ false);
+constexpr const TFunction textureGatherOffset_00X10B10D(
+ BuiltInId::textureGatherOffset_USampler2D1_Float2_Int2,
+ BuiltInName::textureGatherOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X10B10D00B,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffset,
+ false);
+constexpr const TFunction textureGatherOffset_00L20B10D(
+ BuiltInId::textureGatherOffset_Sampler2DArray1_Float3_Int2,
+ BuiltInName::textureGatherOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00L20B10D00B,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffset,
+ false);
+constexpr const TFunction textureGatherOffset_00U20B10D(
+ BuiltInId::textureGatherOffset_ISampler2DArray1_Float3_Int2,
+ BuiltInName::textureGatherOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00U20B10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffset,
+ false);
+constexpr const TFunction textureGatherOffset_00a20B10D(
+ BuiltInId::textureGatherOffset_USampler2DArray1_Float3_Int2,
+ BuiltInName::textureGatherOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00a20B10D00B,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffset,
+ false);
+constexpr const TFunction textureGatherOffset_00d10B00B10D(
+ BuiltInId::textureGatherOffset_Sampler2DShadow1_Float2_Float1_Int2,
+ BuiltInName::textureGatherOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00d10B00B10Dx4,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffset,
+ false);
+constexpr const TFunction textureGatherOffset_00f20B00B10D(
+ BuiltInId::textureGatherOffset_Sampler2DArrayShadow1_Float3_Float1_Int2,
+ BuiltInName::textureGatherOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00f20B00B10Dx4,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffset,
+ false);
+constexpr const TFunction textureGatherOffset_00I10B10D00D(
+ BuiltInId::textureGatherOffset_Sampler2D1_Float2_Int2_Int1,
+ BuiltInName::textureGatherOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I10B10D00D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsetComp,
+ false);
+constexpr const TFunction textureGatherOffset_00R10B10D00D(
+ BuiltInId::textureGatherOffset_ISampler2D1_Float2_Int2_Int1,
+ BuiltInName::textureGatherOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R10B10D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsetComp,
+ false);
+constexpr const TFunction textureGatherOffset_00X10B10D00D(
+ BuiltInId::textureGatherOffset_USampler2D1_Float2_Int2_Int1,
+ BuiltInName::textureGatherOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X10B10D00D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsetComp,
+ false);
+constexpr const TFunction textureGatherOffset_00L20B10D00D(
+ BuiltInId::textureGatherOffset_Sampler2DArray1_Float3_Int2_Int1,
+ BuiltInName::textureGatherOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00L20B10D00D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsetComp,
+ false);
+constexpr const TFunction textureGatherOffset_00U20B10D00D(
+ BuiltInId::textureGatherOffset_ISampler2DArray1_Float3_Int2_Int1,
+ BuiltInName::textureGatherOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00U20B10D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsetComp,
+ false);
+constexpr const TFunction textureGatherOffset_00a20B10D00D(
+ BuiltInId::textureGatherOffset_USampler2DArray1_Float3_Int2_Int1,
+ BuiltInName::textureGatherOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00a20B10D00D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsetComp,
+ false);
+constexpr const TFunction textureGatherOffsets_00I10B10Dx4(
+ BuiltInId::textureGatherOffsets_Sampler2D1_Float2_4xInt2,
+ BuiltInName::textureGatherOffsets,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I10B10Dx400D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsets,
+ false);
+constexpr const TFunction textureGatherOffsets_00R10B10Dx4(
+ BuiltInId::textureGatherOffsets_ISampler2D1_Float2_4xInt2,
+ BuiltInName::textureGatherOffsets,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R10B10Dx400D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsets,
+ false);
+constexpr const TFunction textureGatherOffsets_00X10B10Dx4(
+ BuiltInId::textureGatherOffsets_USampler2D1_Float2_4xInt2,
+ BuiltInName::textureGatherOffsets,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X10B10Dx400D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsets,
+ false);
+constexpr const TFunction textureGatherOffsets_00L20B10Dx4(
+ BuiltInId::textureGatherOffsets_Sampler2DArray1_Float3_4xInt2,
+ BuiltInName::textureGatherOffsets,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00L20B10Dx400D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsets,
+ false);
+constexpr const TFunction textureGatherOffsets_00U20B10Dx4(
+ BuiltInId::textureGatherOffsets_ISampler2DArray1_Float3_4xInt2,
+ BuiltInName::textureGatherOffsets,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00U20B10Dx400D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsets,
+ false);
+constexpr const TFunction textureGatherOffsets_00a20B10Dx4(
+ BuiltInId::textureGatherOffsets_USampler2DArray1_Float3_4xInt2,
+ BuiltInName::textureGatherOffsets,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00a20B10Dx400D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsets,
+ false);
+constexpr const TFunction textureGatherOffsets_00d10B00B10Dx4(
+ BuiltInId::textureGatherOffsets_Sampler2DShadow1_Float2_Float1_4xInt2,
+ BuiltInName::textureGatherOffsets,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00d10B00B10Dx4,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsets,
+ false);
+constexpr const TFunction textureGatherOffsets_00f20B00B10Dx4(
+ BuiltInId::textureGatherOffsets_Sampler2DArrayShadow1_Float3_Float1_4xInt2,
+ BuiltInName::textureGatherOffsets,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00f20B00B10Dx4,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsets,
+ false);
+constexpr const TFunction textureGatherOffsetsExt_00I10B10Dx4(
+ BuiltInId::textureGatherOffsetsExt_Sampler2D1_Float2_4xInt2,
+ BuiltInName::textureGatherOffsetsExt,
+ std::array<TExtension, 1u>{{TExtension::EXT_gpu_shader5}},
+ BuiltInParameters::p00I10B10Dx400D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsets,
+ false);
+constexpr const TFunction textureGatherOffsetsExt_00R10B10Dx4(
+ BuiltInId::textureGatherOffsetsExt_ISampler2D1_Float2_4xInt2,
+ BuiltInName::textureGatherOffsetsExt,
+ std::array<TExtension, 1u>{{TExtension::EXT_gpu_shader5}},
+ BuiltInParameters::p00R10B10Dx400D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsets,
+ false);
+constexpr const TFunction textureGatherOffsetsExt_00X10B10Dx4(
+ BuiltInId::textureGatherOffsetsExt_USampler2D1_Float2_4xInt2,
+ BuiltInName::textureGatherOffsetsExt,
+ std::array<TExtension, 1u>{{TExtension::EXT_gpu_shader5}},
+ BuiltInParameters::p00X10B10Dx400D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsets,
+ false);
+constexpr const TFunction textureGatherOffsetsExt_00L20B10Dx4(
+ BuiltInId::textureGatherOffsetsExt_Sampler2DArray1_Float3_4xInt2,
+ BuiltInName::textureGatherOffsetsExt,
+ std::array<TExtension, 1u>{{TExtension::EXT_gpu_shader5}},
+ BuiltInParameters::p00L20B10Dx400D,
+ 3,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsets,
+ false);
+constexpr const TFunction textureGatherOffsetsExt_00U20B10Dx4(
+ BuiltInId::textureGatherOffsetsExt_ISampler2DArray1_Float3_4xInt2,
+ BuiltInName::textureGatherOffsetsExt,
+ std::array<TExtension, 1u>{{TExtension::EXT_gpu_shader5}},
+ BuiltInParameters::p00U20B10Dx400D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsets,
+ false);
+constexpr const TFunction textureGatherOffsetsExt_00a20B10Dx4(
+ BuiltInId::textureGatherOffsetsExt_USampler2DArray1_Float3_4xInt2,
+ BuiltInName::textureGatherOffsetsExt,
+ std::array<TExtension, 1u>{{TExtension::EXT_gpu_shader5}},
+ BuiltInParameters::p00a20B10Dx400D,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsets,
+ false);
+constexpr const TFunction textureGatherOffsetsExt_00d10B00B10Dx4(
+ BuiltInId::textureGatherOffsetsExt_Sampler2DShadow1_Float2_Float1_4xInt2,
+ BuiltInName::textureGatherOffsetsExt,
+ std::array<TExtension, 1u>{{TExtension::EXT_gpu_shader5}},
+ BuiltInParameters::p00d10B00B10Dx4,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsets,
+ false);
+constexpr const TFunction textureGatherOffsetsExt_00f20B00B10Dx4(
+ BuiltInId::textureGatherOffsetsExt_Sampler2DArrayShadow1_Float3_Float1_4xInt2,
+ BuiltInName::textureGatherOffsetsExt,
+ std::array<TExtension, 1u>{{TExtension::EXT_gpu_shader5}},
+ BuiltInParameters::p00f20B00B10Dx4,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsets,
+ false);
+constexpr const TFunction textureGatherOffsets_00I10B10Dx400D(
+ BuiltInId::textureGatherOffsets_Sampler2D1_Float2_4xInt2_Int1,
+ BuiltInName::textureGatherOffsets,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00I10B10Dx400D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsetsComp,
+ false);
+constexpr const TFunction textureGatherOffsets_00R10B10Dx400D(
+ BuiltInId::textureGatherOffsets_ISampler2D1_Float2_4xInt2_Int1,
+ BuiltInName::textureGatherOffsets,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00R10B10Dx400D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsetsComp,
+ false);
+constexpr const TFunction textureGatherOffsets_00X10B10Dx400D(
+ BuiltInId::textureGatherOffsets_USampler2D1_Float2_4xInt2_Int1,
+ BuiltInName::textureGatherOffsets,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00X10B10Dx400D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsetsComp,
+ false);
+constexpr const TFunction textureGatherOffsets_00L20B10Dx400D(
+ BuiltInId::textureGatherOffsets_Sampler2DArray1_Float3_4xInt2_Int1,
+ BuiltInName::textureGatherOffsets,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00L20B10Dx400D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsetsComp,
+ false);
+constexpr const TFunction textureGatherOffsets_00U20B10Dx400D(
+ BuiltInId::textureGatherOffsets_ISampler2DArray1_Float3_4xInt2_Int1,
+ BuiltInName::textureGatherOffsets,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00U20B10Dx400D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsetsComp,
+ false);
+constexpr const TFunction textureGatherOffsets_00a20B10Dx400D(
+ BuiltInId::textureGatherOffsets_USampler2DArray1_Float3_4xInt2_Int1,
+ BuiltInName::textureGatherOffsets,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00a20B10Dx400D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsetsComp,
+ false);
+constexpr const TFunction textureGatherOffsetsExt_00I10B10Dx400D(
+ BuiltInId::textureGatherOffsetsExt_Sampler2D1_Float2_4xInt2_Int1,
+ BuiltInName::textureGatherOffsetsExt,
+ std::array<TExtension, 1u>{{TExtension::EXT_gpu_shader5}},
+ BuiltInParameters::p00I10B10Dx400D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsetsComp,
+ false);
+constexpr const TFunction textureGatherOffsetsExt_00R10B10Dx400D(
+ BuiltInId::textureGatherOffsetsExt_ISampler2D1_Float2_4xInt2_Int1,
+ BuiltInName::textureGatherOffsetsExt,
+ std::array<TExtension, 1u>{{TExtension::EXT_gpu_shader5}},
+ BuiltInParameters::p00R10B10Dx400D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsetsComp,
+ false);
+constexpr const TFunction textureGatherOffsetsExt_00X10B10Dx400D(
+ BuiltInId::textureGatherOffsetsExt_USampler2D1_Float2_4xInt2_Int1,
+ BuiltInName::textureGatherOffsetsExt,
+ std::array<TExtension, 1u>{{TExtension::EXT_gpu_shader5}},
+ BuiltInParameters::p00X10B10Dx400D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsetsComp,
+ false);
+constexpr const TFunction textureGatherOffsetsExt_00L20B10Dx400D(
+ BuiltInId::textureGatherOffsetsExt_Sampler2DArray1_Float3_4xInt2_Int1,
+ BuiltInName::textureGatherOffsetsExt,
+ std::array<TExtension, 1u>{{TExtension::EXT_gpu_shader5}},
+ BuiltInParameters::p00L20B10Dx400D,
+ 4,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsetsComp,
+ false);
+constexpr const TFunction textureGatherOffsetsExt_00U20B10Dx400D(
+ BuiltInId::textureGatherOffsetsExt_ISampler2DArray1_Float3_4xInt2_Int1,
+ BuiltInName::textureGatherOffsetsExt,
+ std::array<TExtension, 1u>{{TExtension::EXT_gpu_shader5}},
+ BuiltInParameters::p00U20B10Dx400D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsetsComp,
+ false);
+constexpr const TFunction textureGatherOffsetsExt_00a20B10Dx400D(
+ BuiltInId::textureGatherOffsetsExt_USampler2DArray1_Float3_4xInt2_Int1,
+ BuiltInName::textureGatherOffsetsExt,
+ std::array<TExtension, 1u>{{TExtension::EXT_gpu_shader5}},
+ BuiltInParameters::p00a20B10Dx400D,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpTextureGatherOffsetsComp,
+ false);
+constexpr const TFunction rgb_2_yuv_20B00H(
+ BuiltInId::rgb_2_yuv_Float3_YuvCscStandardEXT1,
+ BuiltInName::rgb_2_yuv,
+ std::array<TExtension, 1u>{{TExtension::EXT_YUV_target}},
+ BuiltInParameters::p20B00H,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpRgb_2_yuv,
+ false);
+constexpr const TFunction yuv_2_rgb_20B00H(
+ BuiltInId::yuv_2_rgb_Float3_YuvCscStandardEXT1,
+ BuiltInName::yuv_2_rgb,
+ std::array<TExtension, 1u>{{TExtension::EXT_YUV_target}},
+ BuiltInParameters::p20B00H,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpYuv_2_rgb,
+ false);
+constexpr const TFunction dFdxExt_00B(BuiltInId::dFdxExt_Float1,
+ BuiltInName::dFdxExt,
+ std::array<TExtension, 1u>{
+ {TExtension::OES_standard_derivatives}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpDFdx,
+ false);
+constexpr const TFunction dFdxExt_10B(BuiltInId::dFdxExt_Float2,
+ BuiltInName::dFdxExt,
+ std::array<TExtension, 1u>{
+ {TExtension::OES_standard_derivatives}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpDFdx,
+ false);
+constexpr const TFunction dFdxExt_20B(BuiltInId::dFdxExt_Float3,
+ BuiltInName::dFdxExt,
+ std::array<TExtension, 1u>{
+ {TExtension::OES_standard_derivatives}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpDFdx,
+ false);
+constexpr const TFunction dFdxExt_30B(BuiltInId::dFdxExt_Float4,
+ BuiltInName::dFdxExt,
+ std::array<TExtension, 1u>{
+ {TExtension::OES_standard_derivatives}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpDFdx,
+ false);
+constexpr const TFunction dFdyExt_00B(BuiltInId::dFdyExt_Float1,
+ BuiltInName::dFdyExt,
+ std::array<TExtension, 1u>{
+ {TExtension::OES_standard_derivatives}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpDFdy,
+ false);
+constexpr const TFunction dFdyExt_10B(BuiltInId::dFdyExt_Float2,
+ BuiltInName::dFdyExt,
+ std::array<TExtension, 1u>{
+ {TExtension::OES_standard_derivatives}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpDFdy,
+ false);
+constexpr const TFunction dFdyExt_20B(BuiltInId::dFdyExt_Float3,
+ BuiltInName::dFdyExt,
+ std::array<TExtension, 1u>{
+ {TExtension::OES_standard_derivatives}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpDFdy,
+ false);
+constexpr const TFunction dFdyExt_30B(BuiltInId::dFdyExt_Float4,
+ BuiltInName::dFdyExt,
+ std::array<TExtension, 1u>{
+ {TExtension::OES_standard_derivatives}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpDFdy,
+ false);
+constexpr const TFunction fwidthExt_00B(BuiltInId::fwidthExt_Float1,
+ BuiltInName::fwidthExt,
+ std::array<TExtension, 1u>{
+ {TExtension::OES_standard_derivatives}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpFwidth,
+ false);
+constexpr const TFunction fwidthExt_10B(BuiltInId::fwidthExt_Float2,
+ BuiltInName::fwidthExt,
+ std::array<TExtension, 1u>{
+ {TExtension::OES_standard_derivatives}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpFwidth,
+ false);
+constexpr const TFunction fwidthExt_20B(BuiltInId::fwidthExt_Float3,
+ BuiltInName::fwidthExt,
+ std::array<TExtension, 1u>{
+ {TExtension::OES_standard_derivatives}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpFwidth,
+ false);
+constexpr const TFunction fwidthExt_30B(BuiltInId::fwidthExt_Float4,
+ BuiltInName::fwidthExt,
+ std::array<TExtension, 1u>{
+ {TExtension::OES_standard_derivatives}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpFwidth,
+ false);
+constexpr const TFunction dFdx_00B(BuiltInId::dFdx_Float1,
+ BuiltInName::dFdx,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpDFdx,
+ false);
+constexpr const TFunction dFdx_10B(BuiltInId::dFdx_Float2,
+ BuiltInName::dFdx,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpDFdx,
+ false);
+constexpr const TFunction dFdx_20B(BuiltInId::dFdx_Float3,
+ BuiltInName::dFdx,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpDFdx,
+ false);
+constexpr const TFunction dFdx_30B(BuiltInId::dFdx_Float4,
+ BuiltInName::dFdx,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpDFdx,
+ false);
+constexpr const TFunction dFdy_00B(BuiltInId::dFdy_Float1,
+ BuiltInName::dFdy,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpDFdy,
+ false);
+constexpr const TFunction dFdy_10B(BuiltInId::dFdy_Float2,
+ BuiltInName::dFdy,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpDFdy,
+ false);
+constexpr const TFunction dFdy_20B(BuiltInId::dFdy_Float3,
+ BuiltInName::dFdy,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpDFdy,
+ false);
+constexpr const TFunction dFdy_30B(BuiltInId::dFdy_Float4,
+ BuiltInName::dFdy,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpDFdy,
+ false);
+constexpr const TFunction fwidth_00B(BuiltInId::fwidth_Float1,
+ BuiltInName::fwidth,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpFwidth,
+ false);
+constexpr const TFunction fwidth_10B(BuiltInId::fwidth_Float2,
+ BuiltInName::fwidth,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpFwidth,
+ false);
+constexpr const TFunction fwidth_20B(BuiltInId::fwidth_Float3,
+ BuiltInName::fwidth,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpFwidth,
+ false);
+constexpr const TFunction fwidth_30B(BuiltInId::fwidth_Float4,
+ BuiltInName::fwidth,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpFwidth,
+ false);
+constexpr const TFunction interpolateAtCentroid_00B(
+ BuiltInId::interpolateAtCentroid_Float1,
+ BuiltInName::interpolateAtCentroid,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpInterpolateAtCentroid,
+ false);
+constexpr const TFunction interpolateAtCentroid_10B(
+ BuiltInId::interpolateAtCentroid_Float2,
+ BuiltInName::interpolateAtCentroid,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpInterpolateAtCentroid,
+ false);
+constexpr const TFunction interpolateAtCentroid_20B(
+ BuiltInId::interpolateAtCentroid_Float3,
+ BuiltInName::interpolateAtCentroid,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpInterpolateAtCentroid,
+ false);
+constexpr const TFunction interpolateAtCentroid_30B(
+ BuiltInId::interpolateAtCentroid_Float4,
+ BuiltInName::interpolateAtCentroid,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpInterpolateAtCentroid,
+ false);
+constexpr const TFunction interpolateAtSample_00B00D(
+ BuiltInId::interpolateAtSample_Float1_Int1,
+ BuiltInName::interpolateAtSample,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B00D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpInterpolateAtSample,
+ false);
+constexpr const TFunction interpolateAtSample_10B00D(
+ BuiltInId::interpolateAtSample_Float2_Int1,
+ BuiltInName::interpolateAtSample,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B00D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpInterpolateAtSample,
+ false);
+constexpr const TFunction interpolateAtSample_20B00D(
+ BuiltInId::interpolateAtSample_Float3_Int1,
+ BuiltInName::interpolateAtSample,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B00D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpInterpolateAtSample,
+ false);
+constexpr const TFunction interpolateAtSample_30B00D(
+ BuiltInId::interpolateAtSample_Float4_Int1,
+ BuiltInName::interpolateAtSample,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B00D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpInterpolateAtSample,
+ false);
+constexpr const TFunction interpolateAtOffset_00B10B(
+ BuiltInId::interpolateAtOffset_Float1_Float2,
+ BuiltInName::interpolateAtOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00B10B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpInterpolateAtOffset,
+ false);
+constexpr const TFunction interpolateAtOffset_10B10B(
+ BuiltInId::interpolateAtOffset_Float2_Float2,
+ BuiltInName::interpolateAtOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p10B10B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpInterpolateAtOffset,
+ false);
+constexpr const TFunction interpolateAtOffset_20B10B(
+ BuiltInId::interpolateAtOffset_Float3_Float2,
+ BuiltInName::interpolateAtOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p20B10B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpInterpolateAtOffset,
+ false);
+constexpr const TFunction interpolateAtOffset_30B10B(
+ BuiltInId::interpolateAtOffset_Float4_Float2,
+ BuiltInName::interpolateAtOffset,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p30B10B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpInterpolateAtOffset,
+ false);
+constexpr const TFunction interpolateAtCentroidExt_00B(
+ BuiltInId::interpolateAtCentroidExt_Float1,
+ BuiltInName::interpolateAtCentroidExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_multisample_interpolation}},
+ BuiltInParameters::p00B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpInterpolateAtCentroid,
+ false);
+constexpr const TFunction interpolateAtCentroidExt_10B(
+ BuiltInId::interpolateAtCentroidExt_Float2,
+ BuiltInName::interpolateAtCentroidExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_multisample_interpolation}},
+ BuiltInParameters::p10B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpInterpolateAtCentroid,
+ false);
+constexpr const TFunction interpolateAtCentroidExt_20B(
+ BuiltInId::interpolateAtCentroidExt_Float3,
+ BuiltInName::interpolateAtCentroidExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_multisample_interpolation}},
+ BuiltInParameters::p20B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpInterpolateAtCentroid,
+ false);
+constexpr const TFunction interpolateAtCentroidExt_30B(
+ BuiltInId::interpolateAtCentroidExt_Float4,
+ BuiltInName::interpolateAtCentroidExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_multisample_interpolation}},
+ BuiltInParameters::p30B00B00B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpInterpolateAtCentroid,
+ false);
+constexpr const TFunction interpolateAtSampleExt_00B00D(
+ BuiltInId::interpolateAtSampleExt_Float1_Int1,
+ BuiltInName::interpolateAtSampleExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_multisample_interpolation}},
+ BuiltInParameters::p00B00D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpInterpolateAtSample,
+ false);
+constexpr const TFunction interpolateAtSampleExt_10B00D(
+ BuiltInId::interpolateAtSampleExt_Float2_Int1,
+ BuiltInName::interpolateAtSampleExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_multisample_interpolation}},
+ BuiltInParameters::p10B00D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpInterpolateAtSample,
+ false);
+constexpr const TFunction interpolateAtSampleExt_20B00D(
+ BuiltInId::interpolateAtSampleExt_Float3_Int1,
+ BuiltInName::interpolateAtSampleExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_multisample_interpolation}},
+ BuiltInParameters::p20B00D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpInterpolateAtSample,
+ false);
+constexpr const TFunction interpolateAtSampleExt_30B00D(
+ BuiltInId::interpolateAtSampleExt_Float4_Int1,
+ BuiltInName::interpolateAtSampleExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_multisample_interpolation}},
+ BuiltInParameters::p30B00D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpInterpolateAtSample,
+ false);
+constexpr const TFunction interpolateAtOffsetExt_00B10B(
+ BuiltInId::interpolateAtOffsetExt_Float1_Float2,
+ BuiltInName::interpolateAtOffsetExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_multisample_interpolation}},
+ BuiltInParameters::p00B10B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpInterpolateAtOffset,
+ false);
+constexpr const TFunction interpolateAtOffsetExt_10B10B(
+ BuiltInId::interpolateAtOffsetExt_Float2_Float2,
+ BuiltInName::interpolateAtOffsetExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_multisample_interpolation}},
+ BuiltInParameters::p10B10B00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpInterpolateAtOffset,
+ false);
+constexpr const TFunction interpolateAtOffsetExt_20B10B(
+ BuiltInId::interpolateAtOffsetExt_Float3_Float2,
+ BuiltInName::interpolateAtOffsetExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_multisample_interpolation}},
+ BuiltInParameters::p20B10B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpInterpolateAtOffset,
+ false);
+constexpr const TFunction interpolateAtOffsetExt_30B10B(
+ BuiltInId::interpolateAtOffsetExt_Float4_Float2,
+ BuiltInName::interpolateAtOffsetExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_multisample_interpolation}},
+ BuiltInParameters::p30B10B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpInterpolateAtOffset,
+ false);
+constexpr const TFunction atomicCounter_00G(
+ BuiltInId::atomicCounter_AtomicCounter1,
+ BuiltInName::atomicCounter,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00G,
+ 1,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtomicCounter,
+ false);
+constexpr const TFunction atomicCounterIncrement_00G(
+ BuiltInId::atomicCounterIncrement_AtomicCounter1,
+ BuiltInName::atomicCounterIncrement,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00G,
+ 1,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtomicCounterIncrement,
+ false);
+constexpr const TFunction atomicCounterDecrement_00G(
+ BuiltInId::atomicCounterDecrement_AtomicCounter1,
+ BuiltInName::atomicCounterDecrement,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00G,
+ 1,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtomicCounterDecrement,
+ false);
+constexpr const TFunction atomicAdd_00E00E(
+ BuiltInId::atomicAdd_UInt1_UInt1,
+ BuiltInName::atomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p_io_00E00E00E,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtomicAdd,
+ false);
+constexpr const TFunction atomicAdd_00D00D(BuiltInId::atomicAdd_Int1_Int1,
+ BuiltInName::atomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p_io_00D00D00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtomicAdd,
+ false);
+constexpr const TFunction atomicMin_00E00E(
+ BuiltInId::atomicMin_UInt1_UInt1,
+ BuiltInName::atomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p_io_00E00E00E,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtomicMin,
+ false);
+constexpr const TFunction atomicMin_00D00D(BuiltInId::atomicMin_Int1_Int1,
+ BuiltInName::atomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p_io_00D00D00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtomicMin,
+ false);
+constexpr const TFunction atomicMax_00E00E(
+ BuiltInId::atomicMax_UInt1_UInt1,
+ BuiltInName::atomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p_io_00E00E00E,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtomicMax,
+ false);
+constexpr const TFunction atomicMax_00D00D(BuiltInId::atomicMax_Int1_Int1,
+ BuiltInName::atomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p_io_00D00D00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtomicMax,
+ false);
+constexpr const TFunction atomicAnd_00E00E(
+ BuiltInId::atomicAnd_UInt1_UInt1,
+ BuiltInName::atomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p_io_00E00E00E,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtomicAnd,
+ false);
+constexpr const TFunction atomicAnd_00D00D(BuiltInId::atomicAnd_Int1_Int1,
+ BuiltInName::atomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p_io_00D00D00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtomicAnd,
+ false);
+constexpr const TFunction atomicOr_00E00E(BuiltInId::atomicOr_UInt1_UInt1,
+ BuiltInName::atomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p_io_00E00E00E,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtomicOr,
+ false);
+constexpr const TFunction atomicOr_00D00D(BuiltInId::atomicOr_Int1_Int1,
+ BuiltInName::atomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p_io_00D00D00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtomicOr,
+ false);
+constexpr const TFunction atomicXor_00E00E(
+ BuiltInId::atomicXor_UInt1_UInt1,
+ BuiltInName::atomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p_io_00E00E00E,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtomicXor,
+ false);
+constexpr const TFunction atomicXor_00D00D(BuiltInId::atomicXor_Int1_Int1,
+ BuiltInName::atomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p_io_00D00D00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtomicXor,
+ false);
+constexpr const TFunction atomicExchange_00E00E(
+ BuiltInId::atomicExchange_UInt1_UInt1,
+ BuiltInName::atomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p_io_00E00E00E,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtomicExchange,
+ false);
+constexpr const TFunction atomicExchange_00D00D(
+ BuiltInId::atomicExchange_Int1_Int1,
+ BuiltInName::atomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p_io_00D00D00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtomicExchange,
+ false);
+constexpr const TFunction atomicCompSwap_00E00E00E(
+ BuiltInId::atomicCompSwap_UInt1_UInt1_UInt1,
+ BuiltInName::atomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p_io_00E00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtomicCompSwap,
+ false);
+constexpr const TFunction atomicCompSwap_00D00D00D(
+ BuiltInId::atomicCompSwap_Int1_Int1_Int1,
+ BuiltInName::atomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p_io_00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpAtomicCompSwap,
+ false);
+constexpr const TFunction imageSize_00z(BuiltInId::imageSize_Image2D1,
+ BuiltInName::imageSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00z10D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSize_01K(BuiltInId::imageSize_IImage2D1,
+ BuiltInName::imageSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01K10D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSize_01V(BuiltInId::imageSize_UImage2D1,
+ BuiltInName::imageSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01V10D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSize_01A(BuiltInId::imageSize_Image3D1,
+ BuiltInName::imageSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01A20D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSize_01L(BuiltInId::imageSize_IImage3D1,
+ BuiltInName::imageSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01L20D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSize_01W(BuiltInId::imageSize_UImage3D1,
+ BuiltInName::imageSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01W20D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSize_01B(BuiltInId::imageSize_Image2DArray1,
+ BuiltInName::imageSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01B20D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSize_01M(BuiltInId::imageSize_IImage2DArray1,
+ BuiltInName::imageSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01M20D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSize_01X(BuiltInId::imageSize_UImage2DArray1,
+ BuiltInName::imageSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01X20D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSize_01C(BuiltInId::imageSize_ImageCube1,
+ BuiltInName::imageSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01C20D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSize_01N(BuiltInId::imageSize_IImageCube1,
+ BuiltInName::imageSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01N20D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSize_01Y(BuiltInId::imageSize_UImageCube1,
+ BuiltInName::imageSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Y20D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 2, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSize_01H(BuiltInId::imageSize_ImageCubeArray1,
+ BuiltInName::imageSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01H20D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSize_01S(BuiltInId::imageSize_IImageCubeArray1,
+ BuiltInName::imageSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01S20D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSize_01d(BuiltInId::imageSize_UImageCubeArray1,
+ BuiltInName::imageSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01d20D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSizeExt_01H(BuiltInId::imageSizeExt_ImageCubeArray1,
+ BuiltInName::imageSizeExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array,
+ TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p01H20D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSizeExt_01S(BuiltInId::imageSizeExt_IImageCubeArray1,
+ BuiltInName::imageSizeExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array,
+ TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p01S20D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSizeExt_01d(BuiltInId::imageSizeExt_UImageCubeArray1,
+ BuiltInName::imageSizeExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array,
+ TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p01d20D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 3, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSize_01J(BuiltInId::imageSize_ImageBuffer1,
+ BuiltInName::imageSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01J00D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSize_01U(BuiltInId::imageSize_IImageBuffer1,
+ BuiltInName::imageSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01U00D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSize_01f(BuiltInId::imageSize_UImageBuffer1,
+ BuiltInName::imageSize,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01f00D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSizeExt_01J(
+ BuiltInId::imageSizeExt_ImageBuffer1,
+ BuiltInName::imageSizeExt,
+ std::array<TExtension, 2u>{{TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer}},
+ BuiltInParameters::p01J00D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSizeExt_01U(
+ BuiltInId::imageSizeExt_IImageBuffer1,
+ BuiltInName::imageSizeExt,
+ std::array<TExtension, 2u>{{TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer}},
+ BuiltInParameters::p01U00D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageSizeExt_01f(
+ BuiltInId::imageSizeExt_UImageBuffer1,
+ BuiltInName::imageSizeExt,
+ std::array<TExtension, 2u>{{TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer}},
+ BuiltInParameters::p01f00D00B,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageSize,
+ false);
+constexpr const TFunction imageStore_00z10D30B(
+ BuiltInId::imageStore_Image2D1_Int2_Float4,
+ BuiltInName::imageStore,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00z10D30B,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStore_01K10D30D(
+ BuiltInId::imageStore_IImage2D1_Int2_Int4,
+ BuiltInName::imageStore,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01K10D30D,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStore_01V10D30E(
+ BuiltInId::imageStore_UImage2D1_Int2_UInt4,
+ BuiltInName::imageStore,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01V10D30E,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStore_01A20D30B(
+ BuiltInId::imageStore_Image3D1_Int3_Float4,
+ BuiltInName::imageStore,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01A20D30B,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStore_01L20D30D(
+ BuiltInId::imageStore_IImage3D1_Int3_Int4,
+ BuiltInName::imageStore,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01L20D30D,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStore_01W20D30E(
+ BuiltInId::imageStore_UImage3D1_Int3_UInt4,
+ BuiltInName::imageStore,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01W20D30E,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStore_01B20D30B(
+ BuiltInId::imageStore_Image2DArray1_Int3_Float4,
+ BuiltInName::imageStore,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01B20D30B,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStore_01M20D30D(
+ BuiltInId::imageStore_IImage2DArray1_Int3_Int4,
+ BuiltInName::imageStore,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01M20D30D,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStore_01X20D30E(
+ BuiltInId::imageStore_UImage2DArray1_Int3_UInt4,
+ BuiltInName::imageStore,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01X20D30E,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStore_01C20D30B(
+ BuiltInId::imageStore_ImageCube1_Int3_Float4,
+ BuiltInName::imageStore,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01C20D30B,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStore_01N20D30D(
+ BuiltInId::imageStore_IImageCube1_Int3_Int4,
+ BuiltInName::imageStore,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01N20D30D,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStore_01Y20D30E(
+ BuiltInId::imageStore_UImageCube1_Int3_UInt4,
+ BuiltInName::imageStore,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Y20D30E,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStore_01H20D30B(
+ BuiltInId::imageStore_ImageCubeArray1_Int3_Float4,
+ BuiltInName::imageStore,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01H20D30B,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStore_01S20D30D(
+ BuiltInId::imageStore_IImageCubeArray1_Int3_Int4,
+ BuiltInName::imageStore,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01S20D30D,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStore_01d20D30E(
+ BuiltInId::imageStore_UImageCubeArray1_Int3_UInt4,
+ BuiltInName::imageStore,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01d20D30E,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStoreExt_01H20D30B(
+ BuiltInId::imageStoreExt_ImageCubeArray1_Int3_Float4,
+ BuiltInName::imageStoreExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p01H20D30B,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStoreExt_01S20D30D(
+ BuiltInId::imageStoreExt_IImageCubeArray1_Int3_Int4,
+ BuiltInName::imageStoreExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p01S20D30D,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStoreExt_01d20D30E(
+ BuiltInId::imageStoreExt_UImageCubeArray1_Int3_UInt4,
+ BuiltInName::imageStoreExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p01d20D30E,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStore_01J00D30B(
+ BuiltInId::imageStore_ImageBuffer1_Int1_Float4,
+ BuiltInName::imageStore,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01J00D30B,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStore_01U00D30D(
+ BuiltInId::imageStore_IImageBuffer1_Int1_Int4,
+ BuiltInName::imageStore,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01U00D30D,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStore_01f00D30E(
+ BuiltInId::imageStore_UImageBuffer1_Int1_UInt4,
+ BuiltInName::imageStore,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01f00D30E,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStoreExt_01J00D30B(
+ BuiltInId::imageStoreExt_ImageBuffer1_Int1_Float4,
+ BuiltInName::imageStoreExt,
+ std::array<TExtension, 2u>{{TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer}},
+ BuiltInParameters::p01J00D30B,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStoreExt_01U00D30D(
+ BuiltInId::imageStoreExt_IImageBuffer1_Int1_Int4,
+ BuiltInName::imageStoreExt,
+ std::array<TExtension, 2u>{{TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer}},
+ BuiltInParameters::p01U00D30D,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageStoreExt_01f00D30E(
+ BuiltInId::imageStoreExt_UImageBuffer1_Int1_UInt4,
+ BuiltInName::imageStoreExt,
+ std::array<TExtension, 2u>{{TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer}},
+ BuiltInParameters::p01f00D30E,
+ 3,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageStore,
+ false);
+constexpr const TFunction imageLoad_00z10D(
+ BuiltInId::imageLoad_Image2D1_Int2,
+ BuiltInName::imageLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00z10D00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoad_01K10D(BuiltInId::imageLoad_IImage2D1_Int2,
+ BuiltInName::imageLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01K10D00B,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoad_01V10D(
+ BuiltInId::imageLoad_UImage2D1_Int2,
+ BuiltInName::imageLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01V10D00B,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoad_01A20D(
+ BuiltInId::imageLoad_Image3D1_Int3,
+ BuiltInName::imageLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01A20D00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoad_01L20D(BuiltInId::imageLoad_IImage3D1_Int3,
+ BuiltInName::imageLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01L20D00B,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoad_01W20D(
+ BuiltInId::imageLoad_UImage3D1_Int3,
+ BuiltInName::imageLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01W20D00B,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoad_01B20D(
+ BuiltInId::imageLoad_Image2DArray1_Int3,
+ BuiltInName::imageLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01B20D00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoad_01M20D(BuiltInId::imageLoad_IImage2DArray1_Int3,
+ BuiltInName::imageLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01M20D00B,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoad_01X20D(
+ BuiltInId::imageLoad_UImage2DArray1_Int3,
+ BuiltInName::imageLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01X20D00B,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoad_01C20D(
+ BuiltInId::imageLoad_ImageCube1_Int3,
+ BuiltInName::imageLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01C20D00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoad_01N20D(BuiltInId::imageLoad_IImageCube1_Int3,
+ BuiltInName::imageLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01N20D00B,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoad_01Y20D(
+ BuiltInId::imageLoad_UImageCube1_Int3,
+ BuiltInName::imageLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Y20D00B,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoad_01H20D(
+ BuiltInId::imageLoad_ImageCubeArray1_Int3,
+ BuiltInName::imageLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01H20D00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoad_01S20D(BuiltInId::imageLoad_IImageCubeArray1_Int3,
+ BuiltInName::imageLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01S20D00B,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoad_01d20D(
+ BuiltInId::imageLoad_UImageCubeArray1_Int3,
+ BuiltInName::imageLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01d20D00B,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoadExt_01H20D(
+ BuiltInId::imageLoadExt_ImageCubeArray1_Int3,
+ BuiltInName::imageLoadExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p01H20D00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoadExt_01S20D(
+ BuiltInId::imageLoadExt_IImageCubeArray1_Int3,
+ BuiltInName::imageLoadExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p01S20D00B,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoadExt_01d20D(
+ BuiltInId::imageLoadExt_UImageCubeArray1_Int3,
+ BuiltInName::imageLoadExt,
+ std::array<TExtension, 2u>{
+ {TExtension::OES_texture_cube_map_array, TExtension::EXT_texture_cube_map_array}},
+ BuiltInParameters::p01d20D00B,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoad_01J00D(
+ BuiltInId::imageLoad_ImageBuffer1_Int1,
+ BuiltInName::imageLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01J00D00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoad_01U00D(BuiltInId::imageLoad_IImageBuffer1_Int1,
+ BuiltInName::imageLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01U00D00B,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoad_01f00D(
+ BuiltInId::imageLoad_UImageBuffer1_Int1,
+ BuiltInName::imageLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01f00D00B,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoadExt_01J00D(
+ BuiltInId::imageLoadExt_ImageBuffer1_Int1,
+ BuiltInName::imageLoadExt,
+ std::array<TExtension, 2u>{{TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer}},
+ BuiltInParameters::p01J00D00B,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoadExt_01U00D(
+ BuiltInId::imageLoadExt_IImageBuffer1_Int1,
+ BuiltInName::imageLoadExt,
+ std::array<TExtension, 2u>{{TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer}},
+ BuiltInParameters::p01U00D00B,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageLoadExt_01f00D(
+ BuiltInId::imageLoadExt_UImageBuffer1_Int1,
+ BuiltInName::imageLoadExt,
+ std::array<TExtension, 2u>{{TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer}},
+ BuiltInParameters::p01f00D00B,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpImageLoad,
+ false);
+constexpr const TFunction imageAtomicAdd_00z10D00E(
+ BuiltInId::imageAtomicAdd_Image2D1_Int2_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00z10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01K10D00E(
+ BuiltInId::imageAtomicAdd_IImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01K10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01V10D00E(
+ BuiltInId::imageAtomicAdd_UImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01V10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01A20D00E(
+ BuiltInId::imageAtomicAdd_Image3D1_Int3_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01A20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01L20D00E(
+ BuiltInId::imageAtomicAdd_IImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01L20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01W20D00E(
+ BuiltInId::imageAtomicAdd_UImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01W20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01C20D00E(
+ BuiltInId::imageAtomicAdd_ImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01C20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01N20D00E(
+ BuiltInId::imageAtomicAdd_IImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01N20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01Y20D00E(
+ BuiltInId::imageAtomicAdd_UImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Y20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01J00D00E(
+ BuiltInId::imageAtomicAdd_ImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01J00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01U00D00E(
+ BuiltInId::imageAtomicAdd_IImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01U00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01f00D00E(
+ BuiltInId::imageAtomicAdd_UImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01f00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01B20D00E(
+ BuiltInId::imageAtomicAdd_Image2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01B20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01M20D00E(
+ BuiltInId::imageAtomicAdd_IImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01M20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01X20D00E(
+ BuiltInId::imageAtomicAdd_UImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01X20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01H20D00E(
+ BuiltInId::imageAtomicAdd_ImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01H20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01S20D00E(
+ BuiltInId::imageAtomicAdd_IImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01S20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01d20D00E(
+ BuiltInId::imageAtomicAdd_UImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01d20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01D00D00E(
+ BuiltInId::imageAtomicAdd_Image1D1_Int1_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01D00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01O00D00E(
+ BuiltInId::imageAtomicAdd_IImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01O00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01Z00D00E(
+ BuiltInId::imageAtomicAdd_UImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Z00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01E10D00E(
+ BuiltInId::imageAtomicAdd_Image1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01E10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01P10D00E(
+ BuiltInId::imageAtomicAdd_IImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01P10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01a10D00E(
+ BuiltInId::imageAtomicAdd_UImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01a10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01I10D00E(
+ BuiltInId::imageAtomicAdd_ImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01I10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01T10D00E(
+ BuiltInId::imageAtomicAdd_IImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01T10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01e10D00E(
+ BuiltInId::imageAtomicAdd_UImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01e10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01F10D00D00E(
+ BuiltInId::imageAtomicAdd_Image2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01F10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01Q10D00D00E(
+ BuiltInId::imageAtomicAdd_IImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Q10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01b10D00D00E(
+ BuiltInId::imageAtomicAdd_UImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01b10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01G20D00D00E(
+ BuiltInId::imageAtomicAdd_Image2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01G20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01R20D00D00E(
+ BuiltInId::imageAtomicAdd_IImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01R20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01c20D00D00E(
+ BuiltInId::imageAtomicAdd_UImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01c20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_00z10D00D(
+ BuiltInId::imageAtomicAdd_Image2D1_Int2_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00z10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01K10D00D(
+ BuiltInId::imageAtomicAdd_IImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01K10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01V10D00D(
+ BuiltInId::imageAtomicAdd_UImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01V10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01A20D00D(
+ BuiltInId::imageAtomicAdd_Image3D1_Int3_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01A20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01L20D00D(
+ BuiltInId::imageAtomicAdd_IImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01L20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01W20D00D(
+ BuiltInId::imageAtomicAdd_UImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01W20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01C20D00D(
+ BuiltInId::imageAtomicAdd_ImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01C20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01N20D00D(
+ BuiltInId::imageAtomicAdd_IImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01N20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01Y20D00D(
+ BuiltInId::imageAtomicAdd_UImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Y20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01J00D00D(
+ BuiltInId::imageAtomicAdd_ImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01J00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01U00D00D(
+ BuiltInId::imageAtomicAdd_IImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01U00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01f00D00D(
+ BuiltInId::imageAtomicAdd_UImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01f00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01B20D00D(
+ BuiltInId::imageAtomicAdd_Image2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01B20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01M20D00D(
+ BuiltInId::imageAtomicAdd_IImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01M20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01X20D00D(
+ BuiltInId::imageAtomicAdd_UImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01X20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01H20D00D(
+ BuiltInId::imageAtomicAdd_ImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01H20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01S20D00D(
+ BuiltInId::imageAtomicAdd_IImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01S20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01d20D00D(
+ BuiltInId::imageAtomicAdd_UImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01d20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01D00D00D(
+ BuiltInId::imageAtomicAdd_Image1D1_Int1_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01D00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01O00D00D(
+ BuiltInId::imageAtomicAdd_IImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01O00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01Z00D00D(
+ BuiltInId::imageAtomicAdd_UImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Z00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01E10D00D(
+ BuiltInId::imageAtomicAdd_Image1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01E10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01P10D00D(
+ BuiltInId::imageAtomicAdd_IImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01P10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01a10D00D(
+ BuiltInId::imageAtomicAdd_UImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01a10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01I10D00D(
+ BuiltInId::imageAtomicAdd_ImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01I10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01T10D00D(
+ BuiltInId::imageAtomicAdd_IImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01T10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01e10D00D(
+ BuiltInId::imageAtomicAdd_UImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01e10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01F10D00D00D(
+ BuiltInId::imageAtomicAdd_Image2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01F10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01Q10D00D00D(
+ BuiltInId::imageAtomicAdd_IImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Q10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01b10D00D00D(
+ BuiltInId::imageAtomicAdd_UImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01b10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01G20D00D00D(
+ BuiltInId::imageAtomicAdd_Image2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01G20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01R20D00D00D(
+ BuiltInId::imageAtomicAdd_IImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01R20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAdd_01c20D00D00D(
+ BuiltInId::imageAtomicAdd_UImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicAdd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01c20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicMin_00z10D00E(
+ BuiltInId::imageAtomicMin_Image2D1_Int2_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00z10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01K10D00E(
+ BuiltInId::imageAtomicMin_IImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01K10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01V10D00E(
+ BuiltInId::imageAtomicMin_UImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01V10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01A20D00E(
+ BuiltInId::imageAtomicMin_Image3D1_Int3_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01A20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01L20D00E(
+ BuiltInId::imageAtomicMin_IImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01L20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01W20D00E(
+ BuiltInId::imageAtomicMin_UImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01W20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01C20D00E(
+ BuiltInId::imageAtomicMin_ImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01C20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01N20D00E(
+ BuiltInId::imageAtomicMin_IImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01N20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01Y20D00E(
+ BuiltInId::imageAtomicMin_UImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Y20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01J00D00E(
+ BuiltInId::imageAtomicMin_ImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01J00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01U00D00E(
+ BuiltInId::imageAtomicMin_IImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01U00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01f00D00E(
+ BuiltInId::imageAtomicMin_UImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01f00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01B20D00E(
+ BuiltInId::imageAtomicMin_Image2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01B20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01M20D00E(
+ BuiltInId::imageAtomicMin_IImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01M20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01X20D00E(
+ BuiltInId::imageAtomicMin_UImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01X20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01H20D00E(
+ BuiltInId::imageAtomicMin_ImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01H20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01S20D00E(
+ BuiltInId::imageAtomicMin_IImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01S20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01d20D00E(
+ BuiltInId::imageAtomicMin_UImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01d20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01D00D00E(
+ BuiltInId::imageAtomicMin_Image1D1_Int1_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01D00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01O00D00E(
+ BuiltInId::imageAtomicMin_IImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01O00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01Z00D00E(
+ BuiltInId::imageAtomicMin_UImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Z00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01E10D00E(
+ BuiltInId::imageAtomicMin_Image1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01E10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01P10D00E(
+ BuiltInId::imageAtomicMin_IImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01P10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01a10D00E(
+ BuiltInId::imageAtomicMin_UImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01a10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01I10D00E(
+ BuiltInId::imageAtomicMin_ImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01I10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01T10D00E(
+ BuiltInId::imageAtomicMin_IImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01T10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01e10D00E(
+ BuiltInId::imageAtomicMin_UImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01e10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01F10D00D00E(
+ BuiltInId::imageAtomicMin_Image2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01F10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01Q10D00D00E(
+ BuiltInId::imageAtomicMin_IImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Q10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01b10D00D00E(
+ BuiltInId::imageAtomicMin_UImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01b10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01G20D00D00E(
+ BuiltInId::imageAtomicMin_Image2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01G20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01R20D00D00E(
+ BuiltInId::imageAtomicMin_IImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01R20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01c20D00D00E(
+ BuiltInId::imageAtomicMin_UImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01c20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_00z10D00D(
+ BuiltInId::imageAtomicMin_Image2D1_Int2_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00z10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01K10D00D(
+ BuiltInId::imageAtomicMin_IImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01K10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01V10D00D(
+ BuiltInId::imageAtomicMin_UImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01V10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01A20D00D(
+ BuiltInId::imageAtomicMin_Image3D1_Int3_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01A20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01L20D00D(
+ BuiltInId::imageAtomicMin_IImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01L20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01W20D00D(
+ BuiltInId::imageAtomicMin_UImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01W20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01C20D00D(
+ BuiltInId::imageAtomicMin_ImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01C20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01N20D00D(
+ BuiltInId::imageAtomicMin_IImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01N20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01Y20D00D(
+ BuiltInId::imageAtomicMin_UImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Y20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01J00D00D(
+ BuiltInId::imageAtomicMin_ImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01J00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01U00D00D(
+ BuiltInId::imageAtomicMin_IImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01U00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01f00D00D(
+ BuiltInId::imageAtomicMin_UImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01f00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01B20D00D(
+ BuiltInId::imageAtomicMin_Image2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01B20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01M20D00D(
+ BuiltInId::imageAtomicMin_IImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01M20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01X20D00D(
+ BuiltInId::imageAtomicMin_UImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01X20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01H20D00D(
+ BuiltInId::imageAtomicMin_ImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01H20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01S20D00D(
+ BuiltInId::imageAtomicMin_IImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01S20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01d20D00D(
+ BuiltInId::imageAtomicMin_UImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01d20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01D00D00D(
+ BuiltInId::imageAtomicMin_Image1D1_Int1_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01D00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01O00D00D(
+ BuiltInId::imageAtomicMin_IImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01O00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01Z00D00D(
+ BuiltInId::imageAtomicMin_UImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Z00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01E10D00D(
+ BuiltInId::imageAtomicMin_Image1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01E10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01P10D00D(
+ BuiltInId::imageAtomicMin_IImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01P10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01a10D00D(
+ BuiltInId::imageAtomicMin_UImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01a10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01I10D00D(
+ BuiltInId::imageAtomicMin_ImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01I10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01T10D00D(
+ BuiltInId::imageAtomicMin_IImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01T10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01e10D00D(
+ BuiltInId::imageAtomicMin_UImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01e10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01F10D00D00D(
+ BuiltInId::imageAtomicMin_Image2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01F10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01Q10D00D00D(
+ BuiltInId::imageAtomicMin_IImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Q10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01b10D00D00D(
+ BuiltInId::imageAtomicMin_UImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01b10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01G20D00D00D(
+ BuiltInId::imageAtomicMin_Image2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01G20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01R20D00D00D(
+ BuiltInId::imageAtomicMin_IImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01R20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMin_01c20D00D00D(
+ BuiltInId::imageAtomicMin_UImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicMin,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01c20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMax_00z10D00E(
+ BuiltInId::imageAtomicMax_Image2D1_Int2_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00z10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01K10D00E(
+ BuiltInId::imageAtomicMax_IImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01K10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01V10D00E(
+ BuiltInId::imageAtomicMax_UImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01V10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01A20D00E(
+ BuiltInId::imageAtomicMax_Image3D1_Int3_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01A20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01L20D00E(
+ BuiltInId::imageAtomicMax_IImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01L20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01W20D00E(
+ BuiltInId::imageAtomicMax_UImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01W20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01C20D00E(
+ BuiltInId::imageAtomicMax_ImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01C20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01N20D00E(
+ BuiltInId::imageAtomicMax_IImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01N20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01Y20D00E(
+ BuiltInId::imageAtomicMax_UImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Y20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01J00D00E(
+ BuiltInId::imageAtomicMax_ImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01J00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01U00D00E(
+ BuiltInId::imageAtomicMax_IImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01U00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01f00D00E(
+ BuiltInId::imageAtomicMax_UImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01f00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01B20D00E(
+ BuiltInId::imageAtomicMax_Image2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01B20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01M20D00E(
+ BuiltInId::imageAtomicMax_IImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01M20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01X20D00E(
+ BuiltInId::imageAtomicMax_UImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01X20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01H20D00E(
+ BuiltInId::imageAtomicMax_ImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01H20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01S20D00E(
+ BuiltInId::imageAtomicMax_IImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01S20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01d20D00E(
+ BuiltInId::imageAtomicMax_UImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01d20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01D00D00E(
+ BuiltInId::imageAtomicMax_Image1D1_Int1_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01D00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01O00D00E(
+ BuiltInId::imageAtomicMax_IImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01O00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01Z00D00E(
+ BuiltInId::imageAtomicMax_UImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Z00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01E10D00E(
+ BuiltInId::imageAtomicMax_Image1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01E10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01P10D00E(
+ BuiltInId::imageAtomicMax_IImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01P10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01a10D00E(
+ BuiltInId::imageAtomicMax_UImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01a10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01I10D00E(
+ BuiltInId::imageAtomicMax_ImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01I10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01T10D00E(
+ BuiltInId::imageAtomicMax_IImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01T10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01e10D00E(
+ BuiltInId::imageAtomicMax_UImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01e10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01F10D00D00E(
+ BuiltInId::imageAtomicMax_Image2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01F10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01Q10D00D00E(
+ BuiltInId::imageAtomicMax_IImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Q10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01b10D00D00E(
+ BuiltInId::imageAtomicMax_UImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01b10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01G20D00D00E(
+ BuiltInId::imageAtomicMax_Image2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01G20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01R20D00D00E(
+ BuiltInId::imageAtomicMax_IImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01R20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01c20D00D00E(
+ BuiltInId::imageAtomicMax_UImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01c20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_00z10D00D(
+ BuiltInId::imageAtomicMax_Image2D1_Int2_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00z10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01K10D00D(
+ BuiltInId::imageAtomicMax_IImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01K10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01V10D00D(
+ BuiltInId::imageAtomicMax_UImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01V10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01A20D00D(
+ BuiltInId::imageAtomicMax_Image3D1_Int3_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01A20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01L20D00D(
+ BuiltInId::imageAtomicMax_IImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01L20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01W20D00D(
+ BuiltInId::imageAtomicMax_UImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01W20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01C20D00D(
+ BuiltInId::imageAtomicMax_ImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01C20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01N20D00D(
+ BuiltInId::imageAtomicMax_IImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01N20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01Y20D00D(
+ BuiltInId::imageAtomicMax_UImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Y20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01J00D00D(
+ BuiltInId::imageAtomicMax_ImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01J00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01U00D00D(
+ BuiltInId::imageAtomicMax_IImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01U00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01f00D00D(
+ BuiltInId::imageAtomicMax_UImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01f00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01B20D00D(
+ BuiltInId::imageAtomicMax_Image2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01B20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01M20D00D(
+ BuiltInId::imageAtomicMax_IImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01M20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01X20D00D(
+ BuiltInId::imageAtomicMax_UImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01X20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01H20D00D(
+ BuiltInId::imageAtomicMax_ImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01H20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01S20D00D(
+ BuiltInId::imageAtomicMax_IImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01S20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01d20D00D(
+ BuiltInId::imageAtomicMax_UImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01d20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01D00D00D(
+ BuiltInId::imageAtomicMax_Image1D1_Int1_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01D00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01O00D00D(
+ BuiltInId::imageAtomicMax_IImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01O00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01Z00D00D(
+ BuiltInId::imageAtomicMax_UImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Z00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01E10D00D(
+ BuiltInId::imageAtomicMax_Image1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01E10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01P10D00D(
+ BuiltInId::imageAtomicMax_IImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01P10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01a10D00D(
+ BuiltInId::imageAtomicMax_UImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01a10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01I10D00D(
+ BuiltInId::imageAtomicMax_ImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01I10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01T10D00D(
+ BuiltInId::imageAtomicMax_IImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01T10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01e10D00D(
+ BuiltInId::imageAtomicMax_UImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01e10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01F10D00D00D(
+ BuiltInId::imageAtomicMax_Image2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01F10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01Q10D00D00D(
+ BuiltInId::imageAtomicMax_IImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Q10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01b10D00D00D(
+ BuiltInId::imageAtomicMax_UImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01b10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01G20D00D00D(
+ BuiltInId::imageAtomicMax_Image2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01G20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01R20D00D00D(
+ BuiltInId::imageAtomicMax_IImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01R20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMax_01c20D00D00D(
+ BuiltInId::imageAtomicMax_UImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicMax,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01c20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicAnd_00z10D00E(
+ BuiltInId::imageAtomicAnd_Image2D1_Int2_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00z10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01K10D00E(
+ BuiltInId::imageAtomicAnd_IImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01K10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01V10D00E(
+ BuiltInId::imageAtomicAnd_UImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01V10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01A20D00E(
+ BuiltInId::imageAtomicAnd_Image3D1_Int3_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01A20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01L20D00E(
+ BuiltInId::imageAtomicAnd_IImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01L20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01W20D00E(
+ BuiltInId::imageAtomicAnd_UImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01W20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01C20D00E(
+ BuiltInId::imageAtomicAnd_ImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01C20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01N20D00E(
+ BuiltInId::imageAtomicAnd_IImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01N20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01Y20D00E(
+ BuiltInId::imageAtomicAnd_UImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Y20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01J00D00E(
+ BuiltInId::imageAtomicAnd_ImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01J00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01U00D00E(
+ BuiltInId::imageAtomicAnd_IImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01U00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01f00D00E(
+ BuiltInId::imageAtomicAnd_UImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01f00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01B20D00E(
+ BuiltInId::imageAtomicAnd_Image2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01B20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01M20D00E(
+ BuiltInId::imageAtomicAnd_IImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01M20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01X20D00E(
+ BuiltInId::imageAtomicAnd_UImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01X20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01H20D00E(
+ BuiltInId::imageAtomicAnd_ImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01H20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01S20D00E(
+ BuiltInId::imageAtomicAnd_IImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01S20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01d20D00E(
+ BuiltInId::imageAtomicAnd_UImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01d20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01D00D00E(
+ BuiltInId::imageAtomicAnd_Image1D1_Int1_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01D00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01O00D00E(
+ BuiltInId::imageAtomicAnd_IImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01O00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01Z00D00E(
+ BuiltInId::imageAtomicAnd_UImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Z00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01E10D00E(
+ BuiltInId::imageAtomicAnd_Image1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01E10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01P10D00E(
+ BuiltInId::imageAtomicAnd_IImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01P10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01a10D00E(
+ BuiltInId::imageAtomicAnd_UImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01a10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01I10D00E(
+ BuiltInId::imageAtomicAnd_ImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01I10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01T10D00E(
+ BuiltInId::imageAtomicAnd_IImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01T10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01e10D00E(
+ BuiltInId::imageAtomicAnd_UImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01e10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01F10D00D00E(
+ BuiltInId::imageAtomicAnd_Image2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01F10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01Q10D00D00E(
+ BuiltInId::imageAtomicAnd_IImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Q10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01b10D00D00E(
+ BuiltInId::imageAtomicAnd_UImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01b10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01G20D00D00E(
+ BuiltInId::imageAtomicAnd_Image2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01G20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01R20D00D00E(
+ BuiltInId::imageAtomicAnd_IImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01R20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01c20D00D00E(
+ BuiltInId::imageAtomicAnd_UImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01c20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_00z10D00D(
+ BuiltInId::imageAtomicAnd_Image2D1_Int2_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00z10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01K10D00D(
+ BuiltInId::imageAtomicAnd_IImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01K10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01V10D00D(
+ BuiltInId::imageAtomicAnd_UImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01V10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01A20D00D(
+ BuiltInId::imageAtomicAnd_Image3D1_Int3_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01A20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01L20D00D(
+ BuiltInId::imageAtomicAnd_IImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01L20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01W20D00D(
+ BuiltInId::imageAtomicAnd_UImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01W20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01C20D00D(
+ BuiltInId::imageAtomicAnd_ImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01C20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01N20D00D(
+ BuiltInId::imageAtomicAnd_IImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01N20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01Y20D00D(
+ BuiltInId::imageAtomicAnd_UImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Y20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01J00D00D(
+ BuiltInId::imageAtomicAnd_ImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01J00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01U00D00D(
+ BuiltInId::imageAtomicAnd_IImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01U00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01f00D00D(
+ BuiltInId::imageAtomicAnd_UImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01f00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01B20D00D(
+ BuiltInId::imageAtomicAnd_Image2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01B20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01M20D00D(
+ BuiltInId::imageAtomicAnd_IImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01M20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01X20D00D(
+ BuiltInId::imageAtomicAnd_UImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01X20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01H20D00D(
+ BuiltInId::imageAtomicAnd_ImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01H20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01S20D00D(
+ BuiltInId::imageAtomicAnd_IImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01S20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01d20D00D(
+ BuiltInId::imageAtomicAnd_UImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01d20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01D00D00D(
+ BuiltInId::imageAtomicAnd_Image1D1_Int1_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01D00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01O00D00D(
+ BuiltInId::imageAtomicAnd_IImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01O00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01Z00D00D(
+ BuiltInId::imageAtomicAnd_UImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Z00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01E10D00D(
+ BuiltInId::imageAtomicAnd_Image1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01E10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01P10D00D(
+ BuiltInId::imageAtomicAnd_IImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01P10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01a10D00D(
+ BuiltInId::imageAtomicAnd_UImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01a10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01I10D00D(
+ BuiltInId::imageAtomicAnd_ImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01I10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01T10D00D(
+ BuiltInId::imageAtomicAnd_IImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01T10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01e10D00D(
+ BuiltInId::imageAtomicAnd_UImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01e10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01F10D00D00D(
+ BuiltInId::imageAtomicAnd_Image2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01F10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01Q10D00D00D(
+ BuiltInId::imageAtomicAnd_IImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Q10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01b10D00D00D(
+ BuiltInId::imageAtomicAnd_UImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01b10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01G20D00D00D(
+ BuiltInId::imageAtomicAnd_Image2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01G20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01R20D00D00D(
+ BuiltInId::imageAtomicAnd_IImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01R20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAnd_01c20D00D00D(
+ BuiltInId::imageAtomicAnd_UImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicAnd,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01c20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicOr_00z10D00E(
+ BuiltInId::imageAtomicOr_Image2D1_Int2_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00z10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01K10D00E(
+ BuiltInId::imageAtomicOr_IImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01K10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01V10D00E(
+ BuiltInId::imageAtomicOr_UImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01V10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01A20D00E(
+ BuiltInId::imageAtomicOr_Image3D1_Int3_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01A20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01L20D00E(
+ BuiltInId::imageAtomicOr_IImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01L20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01W20D00E(
+ BuiltInId::imageAtomicOr_UImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01W20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01C20D00E(
+ BuiltInId::imageAtomicOr_ImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01C20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01N20D00E(
+ BuiltInId::imageAtomicOr_IImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01N20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01Y20D00E(
+ BuiltInId::imageAtomicOr_UImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Y20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01J00D00E(
+ BuiltInId::imageAtomicOr_ImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01J00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01U00D00E(
+ BuiltInId::imageAtomicOr_IImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01U00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01f00D00E(
+ BuiltInId::imageAtomicOr_UImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01f00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01B20D00E(
+ BuiltInId::imageAtomicOr_Image2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01B20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01M20D00E(
+ BuiltInId::imageAtomicOr_IImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01M20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01X20D00E(
+ BuiltInId::imageAtomicOr_UImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01X20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01H20D00E(
+ BuiltInId::imageAtomicOr_ImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01H20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01S20D00E(
+ BuiltInId::imageAtomicOr_IImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01S20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01d20D00E(
+ BuiltInId::imageAtomicOr_UImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01d20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01D00D00E(
+ BuiltInId::imageAtomicOr_Image1D1_Int1_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01D00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01O00D00E(
+ BuiltInId::imageAtomicOr_IImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01O00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01Z00D00E(
+ BuiltInId::imageAtomicOr_UImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Z00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01E10D00E(
+ BuiltInId::imageAtomicOr_Image1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01E10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01P10D00E(
+ BuiltInId::imageAtomicOr_IImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01P10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01a10D00E(
+ BuiltInId::imageAtomicOr_UImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01a10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01I10D00E(
+ BuiltInId::imageAtomicOr_ImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01I10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01T10D00E(
+ BuiltInId::imageAtomicOr_IImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01T10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01e10D00E(
+ BuiltInId::imageAtomicOr_UImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01e10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01F10D00D00E(
+ BuiltInId::imageAtomicOr_Image2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01F10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01Q10D00D00E(
+ BuiltInId::imageAtomicOr_IImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Q10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01b10D00D00E(
+ BuiltInId::imageAtomicOr_UImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01b10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01G20D00D00E(
+ BuiltInId::imageAtomicOr_Image2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01G20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01R20D00D00E(
+ BuiltInId::imageAtomicOr_IImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01R20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01c20D00D00E(
+ BuiltInId::imageAtomicOr_UImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01c20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_00z10D00D(
+ BuiltInId::imageAtomicOr_Image2D1_Int2_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00z10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01K10D00D(
+ BuiltInId::imageAtomicOr_IImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01K10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01V10D00D(
+ BuiltInId::imageAtomicOr_UImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01V10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01A20D00D(
+ BuiltInId::imageAtomicOr_Image3D1_Int3_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01A20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01L20D00D(
+ BuiltInId::imageAtomicOr_IImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01L20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01W20D00D(
+ BuiltInId::imageAtomicOr_UImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01W20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01C20D00D(
+ BuiltInId::imageAtomicOr_ImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01C20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01N20D00D(
+ BuiltInId::imageAtomicOr_IImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01N20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01Y20D00D(
+ BuiltInId::imageAtomicOr_UImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Y20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01J00D00D(
+ BuiltInId::imageAtomicOr_ImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01J00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01U00D00D(
+ BuiltInId::imageAtomicOr_IImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01U00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01f00D00D(
+ BuiltInId::imageAtomicOr_UImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01f00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01B20D00D(
+ BuiltInId::imageAtomicOr_Image2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01B20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01M20D00D(
+ BuiltInId::imageAtomicOr_IImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01M20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01X20D00D(
+ BuiltInId::imageAtomicOr_UImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01X20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01H20D00D(
+ BuiltInId::imageAtomicOr_ImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01H20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01S20D00D(
+ BuiltInId::imageAtomicOr_IImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01S20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01d20D00D(
+ BuiltInId::imageAtomicOr_UImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01d20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01D00D00D(
+ BuiltInId::imageAtomicOr_Image1D1_Int1_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01D00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01O00D00D(
+ BuiltInId::imageAtomicOr_IImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01O00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01Z00D00D(
+ BuiltInId::imageAtomicOr_UImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Z00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01E10D00D(
+ BuiltInId::imageAtomicOr_Image1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01E10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01P10D00D(
+ BuiltInId::imageAtomicOr_IImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01P10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01a10D00D(
+ BuiltInId::imageAtomicOr_UImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01a10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01I10D00D(
+ BuiltInId::imageAtomicOr_ImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01I10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01T10D00D(
+ BuiltInId::imageAtomicOr_IImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01T10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01e10D00D(
+ BuiltInId::imageAtomicOr_UImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01e10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01F10D00D00D(
+ BuiltInId::imageAtomicOr_Image2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01F10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01Q10D00D00D(
+ BuiltInId::imageAtomicOr_IImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Q10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01b10D00D00D(
+ BuiltInId::imageAtomicOr_UImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01b10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01G20D00D00D(
+ BuiltInId::imageAtomicOr_Image2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01G20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01R20D00D00D(
+ BuiltInId::imageAtomicOr_IImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01R20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOr_01c20D00D00D(
+ BuiltInId::imageAtomicOr_UImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicOr,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01c20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicXor_00z10D00E(
+ BuiltInId::imageAtomicXor_Image2D1_Int2_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00z10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01K10D00E(
+ BuiltInId::imageAtomicXor_IImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01K10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01V10D00E(
+ BuiltInId::imageAtomicXor_UImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01V10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01A20D00E(
+ BuiltInId::imageAtomicXor_Image3D1_Int3_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01A20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01L20D00E(
+ BuiltInId::imageAtomicXor_IImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01L20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01W20D00E(
+ BuiltInId::imageAtomicXor_UImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01W20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01C20D00E(
+ BuiltInId::imageAtomicXor_ImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01C20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01N20D00E(
+ BuiltInId::imageAtomicXor_IImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01N20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01Y20D00E(
+ BuiltInId::imageAtomicXor_UImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Y20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01J00D00E(
+ BuiltInId::imageAtomicXor_ImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01J00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01U00D00E(
+ BuiltInId::imageAtomicXor_IImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01U00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01f00D00E(
+ BuiltInId::imageAtomicXor_UImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01f00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01B20D00E(
+ BuiltInId::imageAtomicXor_Image2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01B20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01M20D00E(
+ BuiltInId::imageAtomicXor_IImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01M20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01X20D00E(
+ BuiltInId::imageAtomicXor_UImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01X20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01H20D00E(
+ BuiltInId::imageAtomicXor_ImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01H20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01S20D00E(
+ BuiltInId::imageAtomicXor_IImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01S20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01d20D00E(
+ BuiltInId::imageAtomicXor_UImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01d20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01D00D00E(
+ BuiltInId::imageAtomicXor_Image1D1_Int1_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01D00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01O00D00E(
+ BuiltInId::imageAtomicXor_IImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01O00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01Z00D00E(
+ BuiltInId::imageAtomicXor_UImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Z00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01E10D00E(
+ BuiltInId::imageAtomicXor_Image1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01E10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01P10D00E(
+ BuiltInId::imageAtomicXor_IImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01P10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01a10D00E(
+ BuiltInId::imageAtomicXor_UImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01a10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01I10D00E(
+ BuiltInId::imageAtomicXor_ImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01I10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01T10D00E(
+ BuiltInId::imageAtomicXor_IImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01T10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01e10D00E(
+ BuiltInId::imageAtomicXor_UImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01e10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01F10D00D00E(
+ BuiltInId::imageAtomicXor_Image2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01F10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01Q10D00D00E(
+ BuiltInId::imageAtomicXor_IImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Q10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01b10D00D00E(
+ BuiltInId::imageAtomicXor_UImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01b10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01G20D00D00E(
+ BuiltInId::imageAtomicXor_Image2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01G20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01R20D00D00E(
+ BuiltInId::imageAtomicXor_IImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01R20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01c20D00D00E(
+ BuiltInId::imageAtomicXor_UImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01c20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_00z10D00D(
+ BuiltInId::imageAtomicXor_Image2D1_Int2_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00z10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01K10D00D(
+ BuiltInId::imageAtomicXor_IImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01K10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01V10D00D(
+ BuiltInId::imageAtomicXor_UImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01V10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01A20D00D(
+ BuiltInId::imageAtomicXor_Image3D1_Int3_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01A20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01L20D00D(
+ BuiltInId::imageAtomicXor_IImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01L20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01W20D00D(
+ BuiltInId::imageAtomicXor_UImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01W20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01C20D00D(
+ BuiltInId::imageAtomicXor_ImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01C20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01N20D00D(
+ BuiltInId::imageAtomicXor_IImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01N20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01Y20D00D(
+ BuiltInId::imageAtomicXor_UImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Y20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01J00D00D(
+ BuiltInId::imageAtomicXor_ImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01J00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01U00D00D(
+ BuiltInId::imageAtomicXor_IImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01U00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01f00D00D(
+ BuiltInId::imageAtomicXor_UImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01f00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01B20D00D(
+ BuiltInId::imageAtomicXor_Image2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01B20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01M20D00D(
+ BuiltInId::imageAtomicXor_IImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01M20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01X20D00D(
+ BuiltInId::imageAtomicXor_UImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01X20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01H20D00D(
+ BuiltInId::imageAtomicXor_ImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01H20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01S20D00D(
+ BuiltInId::imageAtomicXor_IImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01S20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01d20D00D(
+ BuiltInId::imageAtomicXor_UImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01d20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01D00D00D(
+ BuiltInId::imageAtomicXor_Image1D1_Int1_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01D00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01O00D00D(
+ BuiltInId::imageAtomicXor_IImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01O00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01Z00D00D(
+ BuiltInId::imageAtomicXor_UImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Z00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01E10D00D(
+ BuiltInId::imageAtomicXor_Image1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01E10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01P10D00D(
+ BuiltInId::imageAtomicXor_IImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01P10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01a10D00D(
+ BuiltInId::imageAtomicXor_UImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01a10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01I10D00D(
+ BuiltInId::imageAtomicXor_ImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01I10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01T10D00D(
+ BuiltInId::imageAtomicXor_IImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01T10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01e10D00D(
+ BuiltInId::imageAtomicXor_UImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01e10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01F10D00D00D(
+ BuiltInId::imageAtomicXor_Image2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01F10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01Q10D00D00D(
+ BuiltInId::imageAtomicXor_IImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Q10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01b10D00D00D(
+ BuiltInId::imageAtomicXor_UImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01b10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01G20D00D00D(
+ BuiltInId::imageAtomicXor_Image2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01G20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01R20D00D00D(
+ BuiltInId::imageAtomicXor_IImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01R20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXor_01c20D00D00D(
+ BuiltInId::imageAtomicXor_UImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicXor,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01c20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicExchange_00z10D00E(
+ BuiltInId::imageAtomicExchange_Image2D1_Int2_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00z10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01K10D00E(
+ BuiltInId::imageAtomicExchange_IImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01K10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01V10D00E(
+ BuiltInId::imageAtomicExchange_UImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01V10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01A20D00E(
+ BuiltInId::imageAtomicExchange_Image3D1_Int3_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01A20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01L20D00E(
+ BuiltInId::imageAtomicExchange_IImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01L20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01W20D00E(
+ BuiltInId::imageAtomicExchange_UImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01W20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01C20D00E(
+ BuiltInId::imageAtomicExchange_ImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01C20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01N20D00E(
+ BuiltInId::imageAtomicExchange_IImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01N20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01Y20D00E(
+ BuiltInId::imageAtomicExchange_UImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Y20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01J00D00E(
+ BuiltInId::imageAtomicExchange_ImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01J00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01U00D00E(
+ BuiltInId::imageAtomicExchange_IImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01U00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01f00D00E(
+ BuiltInId::imageAtomicExchange_UImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01f00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01B20D00E(
+ BuiltInId::imageAtomicExchange_Image2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01B20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01M20D00E(
+ BuiltInId::imageAtomicExchange_IImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01M20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01X20D00E(
+ BuiltInId::imageAtomicExchange_UImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01X20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01H20D00E(
+ BuiltInId::imageAtomicExchange_ImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01H20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01S20D00E(
+ BuiltInId::imageAtomicExchange_IImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01S20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01d20D00E(
+ BuiltInId::imageAtomicExchange_UImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01d20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01D00D00E(
+ BuiltInId::imageAtomicExchange_Image1D1_Int1_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01D00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01O00D00E(
+ BuiltInId::imageAtomicExchange_IImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01O00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01Z00D00E(
+ BuiltInId::imageAtomicExchange_UImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Z00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01E10D00E(
+ BuiltInId::imageAtomicExchange_Image1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01E10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01P10D00E(
+ BuiltInId::imageAtomicExchange_IImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01P10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01a10D00E(
+ BuiltInId::imageAtomicExchange_UImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01a10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01I10D00E(
+ BuiltInId::imageAtomicExchange_ImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01I10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01T10D00E(
+ BuiltInId::imageAtomicExchange_IImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01T10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01e10D00E(
+ BuiltInId::imageAtomicExchange_UImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01e10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01F10D00D00E(
+ BuiltInId::imageAtomicExchange_Image2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01F10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01Q10D00D00E(
+ BuiltInId::imageAtomicExchange_IImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Q10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01b10D00D00E(
+ BuiltInId::imageAtomicExchange_UImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01b10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01G20D00D00E(
+ BuiltInId::imageAtomicExchange_Image2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01G20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01R20D00D00E(
+ BuiltInId::imageAtomicExchange_IImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01R20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01c20D00D00E(
+ BuiltInId::imageAtomicExchange_UImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01c20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_00z10D00D(
+ BuiltInId::imageAtomicExchange_Image2D1_Int2_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00z10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01K10D00D(
+ BuiltInId::imageAtomicExchange_IImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01K10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01V10D00D(
+ BuiltInId::imageAtomicExchange_UImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01V10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01A20D00D(
+ BuiltInId::imageAtomicExchange_Image3D1_Int3_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01A20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01L20D00D(
+ BuiltInId::imageAtomicExchange_IImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01L20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01W20D00D(
+ BuiltInId::imageAtomicExchange_UImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01W20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01C20D00D(
+ BuiltInId::imageAtomicExchange_ImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01C20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01N20D00D(
+ BuiltInId::imageAtomicExchange_IImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01N20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01Y20D00D(
+ BuiltInId::imageAtomicExchange_UImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Y20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01J00D00D(
+ BuiltInId::imageAtomicExchange_ImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01J00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01U00D00D(
+ BuiltInId::imageAtomicExchange_IImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01U00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01f00D00D(
+ BuiltInId::imageAtomicExchange_UImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01f00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01B20D00D(
+ BuiltInId::imageAtomicExchange_Image2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01B20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01M20D00D(
+ BuiltInId::imageAtomicExchange_IImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01M20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01X20D00D(
+ BuiltInId::imageAtomicExchange_UImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01X20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01H20D00D(
+ BuiltInId::imageAtomicExchange_ImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01H20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01S20D00D(
+ BuiltInId::imageAtomicExchange_IImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01S20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01d20D00D(
+ BuiltInId::imageAtomicExchange_UImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01d20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01D00D00D(
+ BuiltInId::imageAtomicExchange_Image1D1_Int1_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01D00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01O00D00D(
+ BuiltInId::imageAtomicExchange_IImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01O00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01Z00D00D(
+ BuiltInId::imageAtomicExchange_UImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Z00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01E10D00D(
+ BuiltInId::imageAtomicExchange_Image1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01E10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01P10D00D(
+ BuiltInId::imageAtomicExchange_IImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01P10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01a10D00D(
+ BuiltInId::imageAtomicExchange_UImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01a10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01I10D00D(
+ BuiltInId::imageAtomicExchange_ImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01I10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01T10D00D(
+ BuiltInId::imageAtomicExchange_IImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01T10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01e10D00D(
+ BuiltInId::imageAtomicExchange_UImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01e10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01F10D00D00D(
+ BuiltInId::imageAtomicExchange_Image2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01F10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01Q10D00D00D(
+ BuiltInId::imageAtomicExchange_IImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Q10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01b10D00D00D(
+ BuiltInId::imageAtomicExchange_UImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01b10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01G20D00D00D(
+ BuiltInId::imageAtomicExchange_Image2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01G20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01R20D00D00D(
+ BuiltInId::imageAtomicExchange_IImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01R20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01c20D00D00D(
+ BuiltInId::imageAtomicExchange_UImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01c20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_00z10D00B(
+ BuiltInId::imageAtomicExchange_Image2D1_Int2_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00z10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01K10D00B(
+ BuiltInId::imageAtomicExchange_IImage2D1_Int2_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01K10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01V10D00B(
+ BuiltInId::imageAtomicExchange_UImage2D1_Int2_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01V10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01A20D00B(
+ BuiltInId::imageAtomicExchange_Image3D1_Int3_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01A20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01L20D00B(
+ BuiltInId::imageAtomicExchange_IImage3D1_Int3_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01L20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01W20D00B(
+ BuiltInId::imageAtomicExchange_UImage3D1_Int3_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01W20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01C20D00B(
+ BuiltInId::imageAtomicExchange_ImageCube1_Int3_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01C20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01N20D00B(
+ BuiltInId::imageAtomicExchange_IImageCube1_Int3_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01N20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01Y20D00B(
+ BuiltInId::imageAtomicExchange_UImageCube1_Int3_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Y20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01J00D00B(
+ BuiltInId::imageAtomicExchange_ImageBuffer1_Int1_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01J00D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01U00D00B(
+ BuiltInId::imageAtomicExchange_IImageBuffer1_Int1_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01U00D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01f00D00B(
+ BuiltInId::imageAtomicExchange_UImageBuffer1_Int1_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01f00D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01B20D00B(
+ BuiltInId::imageAtomicExchange_Image2DArray1_Int3_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01B20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01M20D00B(
+ BuiltInId::imageAtomicExchange_IImage2DArray1_Int3_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01M20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01X20D00B(
+ BuiltInId::imageAtomicExchange_UImage2DArray1_Int3_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01X20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01H20D00B(
+ BuiltInId::imageAtomicExchange_ImageCubeArray1_Int3_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01H20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01S20D00B(
+ BuiltInId::imageAtomicExchange_IImageCubeArray1_Int3_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01S20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01d20D00B(
+ BuiltInId::imageAtomicExchange_UImageCubeArray1_Int3_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01d20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01D00D00B(
+ BuiltInId::imageAtomicExchange_Image1D1_Int1_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01D00D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01O00D00B(
+ BuiltInId::imageAtomicExchange_IImage1D1_Int1_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01O00D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01Z00D00B(
+ BuiltInId::imageAtomicExchange_UImage1D1_Int1_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Z00D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01E10D00B(
+ BuiltInId::imageAtomicExchange_Image1DArray1_Int2_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01E10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01P10D00B(
+ BuiltInId::imageAtomicExchange_IImage1DArray1_Int2_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01P10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01a10D00B(
+ BuiltInId::imageAtomicExchange_UImage1DArray1_Int2_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01a10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01I10D00B(
+ BuiltInId::imageAtomicExchange_ImageRect1_Int2_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01I10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01T10D00B(
+ BuiltInId::imageAtomicExchange_IImageRect1_Int2_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01T10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01e10D00B(
+ BuiltInId::imageAtomicExchange_UImageRect1_Int2_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01e10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01F10D00D00B(
+ BuiltInId::imageAtomicExchange_Image2DMS1_Int2_Int1_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01F10D00D00B,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01Q10D00D00B(
+ BuiltInId::imageAtomicExchange_IImage2DMS1_Int2_Int1_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Q10D00D00B,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01b10D00D00B(
+ BuiltInId::imageAtomicExchange_UImage2DMS1_Int2_Int1_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01b10D00D00B,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01G20D00D00B(
+ BuiltInId::imageAtomicExchange_Image2DMSArray1_Int3_Int1_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01G20D00D00B,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01R20D00D00B(
+ BuiltInId::imageAtomicExchange_IImage2DMSArray1_Int3_Int1_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01R20D00D00B,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchange_01c20D00D00B(
+ BuiltInId::imageAtomicExchange_UImage2DMSArray1_Int3_Int1_Float1,
+ BuiltInName::imageAtomicExchange,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01c20D00D00B,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicCompSwap_00z10D00E00E(
+ BuiltInId::imageAtomicCompSwap_Image2D1_Int2_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00z10D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01K10D00E00E(
+ BuiltInId::imageAtomicCompSwap_IImage2D1_Int2_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01K10D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01V10D00E00E(
+ BuiltInId::imageAtomicCompSwap_UImage2D1_Int2_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01V10D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01A20D00E00E(
+ BuiltInId::imageAtomicCompSwap_Image3D1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01A20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01L20D00E00E(
+ BuiltInId::imageAtomicCompSwap_IImage3D1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01L20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01W20D00E00E(
+ BuiltInId::imageAtomicCompSwap_UImage3D1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01W20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01C20D00E00E(
+ BuiltInId::imageAtomicCompSwap_ImageCube1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01C20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01N20D00E00E(
+ BuiltInId::imageAtomicCompSwap_IImageCube1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01N20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01Y20D00E00E(
+ BuiltInId::imageAtomicCompSwap_UImageCube1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Y20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01J00D00E00E(
+ BuiltInId::imageAtomicCompSwap_ImageBuffer1_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01J00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01U00D00E00E(
+ BuiltInId::imageAtomicCompSwap_IImageBuffer1_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01U00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01f00D00E00E(
+ BuiltInId::imageAtomicCompSwap_UImageBuffer1_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01f00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01B20D00E00E(
+ BuiltInId::imageAtomicCompSwap_Image2DArray1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01B20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01M20D00E00E(
+ BuiltInId::imageAtomicCompSwap_IImage2DArray1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01M20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01X20D00E00E(
+ BuiltInId::imageAtomicCompSwap_UImage2DArray1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01X20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01H20D00E00E(
+ BuiltInId::imageAtomicCompSwap_ImageCubeArray1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01H20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01S20D00E00E(
+ BuiltInId::imageAtomicCompSwap_IImageCubeArray1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01S20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01d20D00E00E(
+ BuiltInId::imageAtomicCompSwap_UImageCubeArray1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01d20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01D00D00E00E(
+ BuiltInId::imageAtomicCompSwap_Image1D1_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01O00D00E00E(
+ BuiltInId::imageAtomicCompSwap_IImage1D1_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01O00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01Z00D00E00E(
+ BuiltInId::imageAtomicCompSwap_UImage1D1_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Z00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01E10D00E00E(
+ BuiltInId::imageAtomicCompSwap_Image1DArray1_Int2_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01E10D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01P10D00E00E(
+ BuiltInId::imageAtomicCompSwap_IImage1DArray1_Int2_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01P10D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01a10D00E00E(
+ BuiltInId::imageAtomicCompSwap_UImage1DArray1_Int2_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01a10D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01I10D00E00E(
+ BuiltInId::imageAtomicCompSwap_ImageRect1_Int2_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01I10D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01T10D00E00E(
+ BuiltInId::imageAtomicCompSwap_IImageRect1_Int2_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01T10D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01e10D00E00E(
+ BuiltInId::imageAtomicCompSwap_UImageRect1_Int2_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01e10D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01F10D00D00E00E(
+ BuiltInId::imageAtomicCompSwap_Image2DMS1_Int2_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01F10D00D00E00E,
+ 5,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01Q10D00D00E00E(
+ BuiltInId::imageAtomicCompSwap_IImage2DMS1_Int2_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Q10D00D00E00E,
+ 5,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01b10D00D00E00E(
+ BuiltInId::imageAtomicCompSwap_UImage2DMS1_Int2_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01b10D00D00E00E,
+ 5,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01G20D00D00E00E(
+ BuiltInId::imageAtomicCompSwap_Image2DMSArray1_Int3_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01G20D00D00E00E,
+ 5,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01R20D00D00E00E(
+ BuiltInId::imageAtomicCompSwap_IImage2DMSArray1_Int3_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01R20D00D00E00E,
+ 5,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01c20D00D00E00E(
+ BuiltInId::imageAtomicCompSwap_UImage2DMSArray1_Int3_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01c20D00D00E00E,
+ 5,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_00z10D00D00D(
+ BuiltInId::imageAtomicCompSwap_Image2D1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p00z10D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01K10D00D00D(
+ BuiltInId::imageAtomicCompSwap_IImage2D1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01K10D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01V10D00D00D(
+ BuiltInId::imageAtomicCompSwap_UImage2D1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01V10D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01A20D00D00D(
+ BuiltInId::imageAtomicCompSwap_Image3D1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01A20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01L20D00D00D(
+ BuiltInId::imageAtomicCompSwap_IImage3D1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01L20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01W20D00D00D(
+ BuiltInId::imageAtomicCompSwap_UImage3D1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01W20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01C20D00D00D(
+ BuiltInId::imageAtomicCompSwap_ImageCube1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01C20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01N20D00D00D(
+ BuiltInId::imageAtomicCompSwap_IImageCube1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01N20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01Y20D00D00D(
+ BuiltInId::imageAtomicCompSwap_UImageCube1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Y20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01J00D00D00D(
+ BuiltInId::imageAtomicCompSwap_ImageBuffer1_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01J00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01U00D00D00D(
+ BuiltInId::imageAtomicCompSwap_IImageBuffer1_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01U00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01f00D00D00D(
+ BuiltInId::imageAtomicCompSwap_UImageBuffer1_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01f00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01B20D00D00D(
+ BuiltInId::imageAtomicCompSwap_Image2DArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01B20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01M20D00D00D(
+ BuiltInId::imageAtomicCompSwap_IImage2DArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01M20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01X20D00D00D(
+ BuiltInId::imageAtomicCompSwap_UImage2DArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01X20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01H20D00D00D(
+ BuiltInId::imageAtomicCompSwap_ImageCubeArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01H20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01S20D00D00D(
+ BuiltInId::imageAtomicCompSwap_IImageCubeArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01S20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01d20D00D00D(
+ BuiltInId::imageAtomicCompSwap_UImageCubeArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01d20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01D00D00D00D(
+ BuiltInId::imageAtomicCompSwap_Image1D1_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01O00D00D00D(
+ BuiltInId::imageAtomicCompSwap_IImage1D1_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01O00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01Z00D00D00D(
+ BuiltInId::imageAtomicCompSwap_UImage1D1_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Z00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01E10D00D00D(
+ BuiltInId::imageAtomicCompSwap_Image1DArray1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01E10D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01P10D00D00D(
+ BuiltInId::imageAtomicCompSwap_IImage1DArray1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01P10D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01a10D00D00D(
+ BuiltInId::imageAtomicCompSwap_UImage1DArray1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01a10D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01I10D00D00D(
+ BuiltInId::imageAtomicCompSwap_ImageRect1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01I10D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01T10D00D00D(
+ BuiltInId::imageAtomicCompSwap_IImageRect1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01T10D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01e10D00D00D(
+ BuiltInId::imageAtomicCompSwap_UImageRect1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01e10D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01F10D00D00D00D(
+ BuiltInId::imageAtomicCompSwap_Image2DMS1_Int2_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01F10D00D00D00D,
+ 5,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01Q10D00D00D00D(
+ BuiltInId::imageAtomicCompSwap_IImage2DMS1_Int2_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01Q10D00D00D00D,
+ 5,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01b10D00D00D00D(
+ BuiltInId::imageAtomicCompSwap_UImage2DMS1_Int2_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01b10D00D00D00D,
+ 5,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01G20D00D00D00D(
+ BuiltInId::imageAtomicCompSwap_Image2DMSArray1_Int3_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01G20D00D00D00D,
+ 5,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01R20D00D00D00D(
+ BuiltInId::imageAtomicCompSwap_IImage2DMSArray1_Int3_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01R20D00D00D00D,
+ 5,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwap_01c20D00D00D00D(
+ BuiltInId::imageAtomicCompSwap_UImage2DMSArray1_Int3_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwap,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01c20D00D00D00D,
+ 5,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicAddExt_00z10D00E(
+ BuiltInId::imageAtomicAddExt_Image2D1_Int2_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p00z10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01K10D00E(
+ BuiltInId::imageAtomicAddExt_IImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01K10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01V10D00E(
+ BuiltInId::imageAtomicAddExt_UImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01V10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01A20D00E(
+ BuiltInId::imageAtomicAddExt_Image3D1_Int3_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01A20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01L20D00E(
+ BuiltInId::imageAtomicAddExt_IImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01L20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01W20D00E(
+ BuiltInId::imageAtomicAddExt_UImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01W20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01C20D00E(
+ BuiltInId::imageAtomicAddExt_ImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01C20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01N20D00E(
+ BuiltInId::imageAtomicAddExt_IImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01N20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01Y20D00E(
+ BuiltInId::imageAtomicAddExt_UImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Y20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01J00D00E(
+ BuiltInId::imageAtomicAddExt_ImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01J00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01U00D00E(
+ BuiltInId::imageAtomicAddExt_IImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01U00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01f00D00E(
+ BuiltInId::imageAtomicAddExt_UImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01f00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01B20D00E(
+ BuiltInId::imageAtomicAddExt_Image2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01B20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01M20D00E(
+ BuiltInId::imageAtomicAddExt_IImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01M20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01X20D00E(
+ BuiltInId::imageAtomicAddExt_UImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01X20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01H20D00E(
+ BuiltInId::imageAtomicAddExt_ImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01H20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01S20D00E(
+ BuiltInId::imageAtomicAddExt_IImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01S20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01d20D00E(
+ BuiltInId::imageAtomicAddExt_UImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01d20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01D00D00E(
+ BuiltInId::imageAtomicAddExt_Image1D1_Int1_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01D00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01O00D00E(
+ BuiltInId::imageAtomicAddExt_IImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01O00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01Z00D00E(
+ BuiltInId::imageAtomicAddExt_UImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Z00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01E10D00E(
+ BuiltInId::imageAtomicAddExt_Image1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01E10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01P10D00E(
+ BuiltInId::imageAtomicAddExt_IImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01P10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01a10D00E(
+ BuiltInId::imageAtomicAddExt_UImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01a10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01I10D00E(
+ BuiltInId::imageAtomicAddExt_ImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01I10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01T10D00E(
+ BuiltInId::imageAtomicAddExt_IImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01T10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01e10D00E(
+ BuiltInId::imageAtomicAddExt_UImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01e10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01F10D00D00E(
+ BuiltInId::imageAtomicAddExt_Image2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01F10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01Q10D00D00E(
+ BuiltInId::imageAtomicAddExt_IImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Q10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01b10D00D00E(
+ BuiltInId::imageAtomicAddExt_UImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01b10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01G20D00D00E(
+ BuiltInId::imageAtomicAddExt_Image2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01G20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01R20D00D00E(
+ BuiltInId::imageAtomicAddExt_IImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01R20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01c20D00D00E(
+ BuiltInId::imageAtomicAddExt_UImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01c20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_00z10D00D(
+ BuiltInId::imageAtomicAddExt_Image2D1_Int2_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p00z10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01K10D00D(
+ BuiltInId::imageAtomicAddExt_IImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01K10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01V10D00D(
+ BuiltInId::imageAtomicAddExt_UImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01V10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01A20D00D(
+ BuiltInId::imageAtomicAddExt_Image3D1_Int3_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01A20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01L20D00D(
+ BuiltInId::imageAtomicAddExt_IImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01L20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01W20D00D(
+ BuiltInId::imageAtomicAddExt_UImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01W20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01C20D00D(
+ BuiltInId::imageAtomicAddExt_ImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01C20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01N20D00D(
+ BuiltInId::imageAtomicAddExt_IImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01N20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01Y20D00D(
+ BuiltInId::imageAtomicAddExt_UImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Y20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01J00D00D(
+ BuiltInId::imageAtomicAddExt_ImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01J00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01U00D00D(
+ BuiltInId::imageAtomicAddExt_IImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01U00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01f00D00D(
+ BuiltInId::imageAtomicAddExt_UImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01f00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01B20D00D(
+ BuiltInId::imageAtomicAddExt_Image2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01B20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01M20D00D(
+ BuiltInId::imageAtomicAddExt_IImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01M20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01X20D00D(
+ BuiltInId::imageAtomicAddExt_UImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01X20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01H20D00D(
+ BuiltInId::imageAtomicAddExt_ImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01H20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01S20D00D(
+ BuiltInId::imageAtomicAddExt_IImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01S20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01d20D00D(
+ BuiltInId::imageAtomicAddExt_UImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01d20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01D00D00D(
+ BuiltInId::imageAtomicAddExt_Image1D1_Int1_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01D00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01O00D00D(
+ BuiltInId::imageAtomicAddExt_IImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01O00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01Z00D00D(
+ BuiltInId::imageAtomicAddExt_UImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Z00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01E10D00D(
+ BuiltInId::imageAtomicAddExt_Image1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01E10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01P10D00D(
+ BuiltInId::imageAtomicAddExt_IImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01P10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01a10D00D(
+ BuiltInId::imageAtomicAddExt_UImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01a10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01I10D00D(
+ BuiltInId::imageAtomicAddExt_ImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01I10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01T10D00D(
+ BuiltInId::imageAtomicAddExt_IImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01T10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01e10D00D(
+ BuiltInId::imageAtomicAddExt_UImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01e10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01F10D00D00D(
+ BuiltInId::imageAtomicAddExt_Image2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01F10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01Q10D00D00D(
+ BuiltInId::imageAtomicAddExt_IImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Q10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01b10D00D00D(
+ BuiltInId::imageAtomicAddExt_UImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01b10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01G20D00D00D(
+ BuiltInId::imageAtomicAddExt_Image2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01G20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01R20D00D00D(
+ BuiltInId::imageAtomicAddExt_IImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01R20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicAddExt_01c20D00D00D(
+ BuiltInId::imageAtomicAddExt_UImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicAddExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01c20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAdd,
+ false);
+constexpr const TFunction imageAtomicMinExt_00z10D00E(
+ BuiltInId::imageAtomicMinExt_Image2D1_Int2_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p00z10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01K10D00E(
+ BuiltInId::imageAtomicMinExt_IImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01K10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01V10D00E(
+ BuiltInId::imageAtomicMinExt_UImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01V10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01A20D00E(
+ BuiltInId::imageAtomicMinExt_Image3D1_Int3_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01A20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01L20D00E(
+ BuiltInId::imageAtomicMinExt_IImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01L20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01W20D00E(
+ BuiltInId::imageAtomicMinExt_UImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01W20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01C20D00E(
+ BuiltInId::imageAtomicMinExt_ImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01C20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01N20D00E(
+ BuiltInId::imageAtomicMinExt_IImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01N20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01Y20D00E(
+ BuiltInId::imageAtomicMinExt_UImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Y20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01J00D00E(
+ BuiltInId::imageAtomicMinExt_ImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01J00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01U00D00E(
+ BuiltInId::imageAtomicMinExt_IImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01U00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01f00D00E(
+ BuiltInId::imageAtomicMinExt_UImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01f00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01B20D00E(
+ BuiltInId::imageAtomicMinExt_Image2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01B20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01M20D00E(
+ BuiltInId::imageAtomicMinExt_IImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01M20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01X20D00E(
+ BuiltInId::imageAtomicMinExt_UImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01X20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01H20D00E(
+ BuiltInId::imageAtomicMinExt_ImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01H20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01S20D00E(
+ BuiltInId::imageAtomicMinExt_IImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01S20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01d20D00E(
+ BuiltInId::imageAtomicMinExt_UImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01d20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01D00D00E(
+ BuiltInId::imageAtomicMinExt_Image1D1_Int1_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01D00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01O00D00E(
+ BuiltInId::imageAtomicMinExt_IImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01O00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01Z00D00E(
+ BuiltInId::imageAtomicMinExt_UImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Z00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01E10D00E(
+ BuiltInId::imageAtomicMinExt_Image1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01E10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01P10D00E(
+ BuiltInId::imageAtomicMinExt_IImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01P10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01a10D00E(
+ BuiltInId::imageAtomicMinExt_UImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01a10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01I10D00E(
+ BuiltInId::imageAtomicMinExt_ImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01I10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01T10D00E(
+ BuiltInId::imageAtomicMinExt_IImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01T10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01e10D00E(
+ BuiltInId::imageAtomicMinExt_UImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01e10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01F10D00D00E(
+ BuiltInId::imageAtomicMinExt_Image2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01F10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01Q10D00D00E(
+ BuiltInId::imageAtomicMinExt_IImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Q10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01b10D00D00E(
+ BuiltInId::imageAtomicMinExt_UImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01b10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01G20D00D00E(
+ BuiltInId::imageAtomicMinExt_Image2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01G20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01R20D00D00E(
+ BuiltInId::imageAtomicMinExt_IImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01R20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01c20D00D00E(
+ BuiltInId::imageAtomicMinExt_UImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01c20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_00z10D00D(
+ BuiltInId::imageAtomicMinExt_Image2D1_Int2_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p00z10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01K10D00D(
+ BuiltInId::imageAtomicMinExt_IImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01K10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01V10D00D(
+ BuiltInId::imageAtomicMinExt_UImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01V10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01A20D00D(
+ BuiltInId::imageAtomicMinExt_Image3D1_Int3_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01A20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01L20D00D(
+ BuiltInId::imageAtomicMinExt_IImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01L20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01W20D00D(
+ BuiltInId::imageAtomicMinExt_UImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01W20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01C20D00D(
+ BuiltInId::imageAtomicMinExt_ImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01C20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01N20D00D(
+ BuiltInId::imageAtomicMinExt_IImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01N20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01Y20D00D(
+ BuiltInId::imageAtomicMinExt_UImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Y20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01J00D00D(
+ BuiltInId::imageAtomicMinExt_ImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01J00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01U00D00D(
+ BuiltInId::imageAtomicMinExt_IImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01U00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01f00D00D(
+ BuiltInId::imageAtomicMinExt_UImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01f00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01B20D00D(
+ BuiltInId::imageAtomicMinExt_Image2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01B20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01M20D00D(
+ BuiltInId::imageAtomicMinExt_IImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01M20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01X20D00D(
+ BuiltInId::imageAtomicMinExt_UImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01X20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01H20D00D(
+ BuiltInId::imageAtomicMinExt_ImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01H20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01S20D00D(
+ BuiltInId::imageAtomicMinExt_IImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01S20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01d20D00D(
+ BuiltInId::imageAtomicMinExt_UImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01d20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01D00D00D(
+ BuiltInId::imageAtomicMinExt_Image1D1_Int1_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01D00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01O00D00D(
+ BuiltInId::imageAtomicMinExt_IImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01O00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01Z00D00D(
+ BuiltInId::imageAtomicMinExt_UImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Z00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01E10D00D(
+ BuiltInId::imageAtomicMinExt_Image1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01E10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01P10D00D(
+ BuiltInId::imageAtomicMinExt_IImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01P10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01a10D00D(
+ BuiltInId::imageAtomicMinExt_UImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01a10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01I10D00D(
+ BuiltInId::imageAtomicMinExt_ImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01I10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01T10D00D(
+ BuiltInId::imageAtomicMinExt_IImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01T10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01e10D00D(
+ BuiltInId::imageAtomicMinExt_UImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01e10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01F10D00D00D(
+ BuiltInId::imageAtomicMinExt_Image2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01F10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01Q10D00D00D(
+ BuiltInId::imageAtomicMinExt_IImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Q10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01b10D00D00D(
+ BuiltInId::imageAtomicMinExt_UImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01b10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01G20D00D00D(
+ BuiltInId::imageAtomicMinExt_Image2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01G20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01R20D00D00D(
+ BuiltInId::imageAtomicMinExt_IImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01R20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMinExt_01c20D00D00D(
+ BuiltInId::imageAtomicMinExt_UImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicMinExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01c20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMin,
+ false);
+constexpr const TFunction imageAtomicMaxExt_00z10D00E(
+ BuiltInId::imageAtomicMaxExt_Image2D1_Int2_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p00z10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01K10D00E(
+ BuiltInId::imageAtomicMaxExt_IImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01K10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01V10D00E(
+ BuiltInId::imageAtomicMaxExt_UImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01V10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01A20D00E(
+ BuiltInId::imageAtomicMaxExt_Image3D1_Int3_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01A20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01L20D00E(
+ BuiltInId::imageAtomicMaxExt_IImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01L20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01W20D00E(
+ BuiltInId::imageAtomicMaxExt_UImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01W20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01C20D00E(
+ BuiltInId::imageAtomicMaxExt_ImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01C20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01N20D00E(
+ BuiltInId::imageAtomicMaxExt_IImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01N20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01Y20D00E(
+ BuiltInId::imageAtomicMaxExt_UImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Y20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01J00D00E(
+ BuiltInId::imageAtomicMaxExt_ImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01J00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01U00D00E(
+ BuiltInId::imageAtomicMaxExt_IImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01U00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01f00D00E(
+ BuiltInId::imageAtomicMaxExt_UImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01f00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01B20D00E(
+ BuiltInId::imageAtomicMaxExt_Image2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01B20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01M20D00E(
+ BuiltInId::imageAtomicMaxExt_IImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01M20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01X20D00E(
+ BuiltInId::imageAtomicMaxExt_UImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01X20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01H20D00E(
+ BuiltInId::imageAtomicMaxExt_ImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01H20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01S20D00E(
+ BuiltInId::imageAtomicMaxExt_IImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01S20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01d20D00E(
+ BuiltInId::imageAtomicMaxExt_UImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01d20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01D00D00E(
+ BuiltInId::imageAtomicMaxExt_Image1D1_Int1_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01D00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01O00D00E(
+ BuiltInId::imageAtomicMaxExt_IImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01O00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01Z00D00E(
+ BuiltInId::imageAtomicMaxExt_UImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Z00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01E10D00E(
+ BuiltInId::imageAtomicMaxExt_Image1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01E10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01P10D00E(
+ BuiltInId::imageAtomicMaxExt_IImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01P10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01a10D00E(
+ BuiltInId::imageAtomicMaxExt_UImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01a10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01I10D00E(
+ BuiltInId::imageAtomicMaxExt_ImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01I10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01T10D00E(
+ BuiltInId::imageAtomicMaxExt_IImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01T10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01e10D00E(
+ BuiltInId::imageAtomicMaxExt_UImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01e10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01F10D00D00E(
+ BuiltInId::imageAtomicMaxExt_Image2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01F10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01Q10D00D00E(
+ BuiltInId::imageAtomicMaxExt_IImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Q10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01b10D00D00E(
+ BuiltInId::imageAtomicMaxExt_UImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01b10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01G20D00D00E(
+ BuiltInId::imageAtomicMaxExt_Image2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01G20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01R20D00D00E(
+ BuiltInId::imageAtomicMaxExt_IImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01R20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01c20D00D00E(
+ BuiltInId::imageAtomicMaxExt_UImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01c20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_00z10D00D(
+ BuiltInId::imageAtomicMaxExt_Image2D1_Int2_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p00z10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01K10D00D(
+ BuiltInId::imageAtomicMaxExt_IImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01K10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01V10D00D(
+ BuiltInId::imageAtomicMaxExt_UImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01V10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01A20D00D(
+ BuiltInId::imageAtomicMaxExt_Image3D1_Int3_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01A20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01L20D00D(
+ BuiltInId::imageAtomicMaxExt_IImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01L20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01W20D00D(
+ BuiltInId::imageAtomicMaxExt_UImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01W20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01C20D00D(
+ BuiltInId::imageAtomicMaxExt_ImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01C20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01N20D00D(
+ BuiltInId::imageAtomicMaxExt_IImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01N20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01Y20D00D(
+ BuiltInId::imageAtomicMaxExt_UImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Y20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01J00D00D(
+ BuiltInId::imageAtomicMaxExt_ImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01J00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01U00D00D(
+ BuiltInId::imageAtomicMaxExt_IImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01U00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01f00D00D(
+ BuiltInId::imageAtomicMaxExt_UImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01f00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01B20D00D(
+ BuiltInId::imageAtomicMaxExt_Image2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01B20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01M20D00D(
+ BuiltInId::imageAtomicMaxExt_IImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01M20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01X20D00D(
+ BuiltInId::imageAtomicMaxExt_UImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01X20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01H20D00D(
+ BuiltInId::imageAtomicMaxExt_ImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01H20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01S20D00D(
+ BuiltInId::imageAtomicMaxExt_IImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01S20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01d20D00D(
+ BuiltInId::imageAtomicMaxExt_UImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01d20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01D00D00D(
+ BuiltInId::imageAtomicMaxExt_Image1D1_Int1_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01D00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01O00D00D(
+ BuiltInId::imageAtomicMaxExt_IImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01O00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01Z00D00D(
+ BuiltInId::imageAtomicMaxExt_UImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Z00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01E10D00D(
+ BuiltInId::imageAtomicMaxExt_Image1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01E10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01P10D00D(
+ BuiltInId::imageAtomicMaxExt_IImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01P10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01a10D00D(
+ BuiltInId::imageAtomicMaxExt_UImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01a10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01I10D00D(
+ BuiltInId::imageAtomicMaxExt_ImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01I10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01T10D00D(
+ BuiltInId::imageAtomicMaxExt_IImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01T10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01e10D00D(
+ BuiltInId::imageAtomicMaxExt_UImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01e10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01F10D00D00D(
+ BuiltInId::imageAtomicMaxExt_Image2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01F10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01Q10D00D00D(
+ BuiltInId::imageAtomicMaxExt_IImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Q10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01b10D00D00D(
+ BuiltInId::imageAtomicMaxExt_UImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01b10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01G20D00D00D(
+ BuiltInId::imageAtomicMaxExt_Image2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01G20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01R20D00D00D(
+ BuiltInId::imageAtomicMaxExt_IImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01R20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicMaxExt_01c20D00D00D(
+ BuiltInId::imageAtomicMaxExt_UImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicMaxExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01c20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicMax,
+ false);
+constexpr const TFunction imageAtomicAndExt_00z10D00E(
+ BuiltInId::imageAtomicAndExt_Image2D1_Int2_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p00z10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01K10D00E(
+ BuiltInId::imageAtomicAndExt_IImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01K10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01V10D00E(
+ BuiltInId::imageAtomicAndExt_UImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01V10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01A20D00E(
+ BuiltInId::imageAtomicAndExt_Image3D1_Int3_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01A20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01L20D00E(
+ BuiltInId::imageAtomicAndExt_IImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01L20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01W20D00E(
+ BuiltInId::imageAtomicAndExt_UImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01W20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01C20D00E(
+ BuiltInId::imageAtomicAndExt_ImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01C20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01N20D00E(
+ BuiltInId::imageAtomicAndExt_IImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01N20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01Y20D00E(
+ BuiltInId::imageAtomicAndExt_UImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Y20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01J00D00E(
+ BuiltInId::imageAtomicAndExt_ImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01J00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01U00D00E(
+ BuiltInId::imageAtomicAndExt_IImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01U00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01f00D00E(
+ BuiltInId::imageAtomicAndExt_UImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01f00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01B20D00E(
+ BuiltInId::imageAtomicAndExt_Image2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01B20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01M20D00E(
+ BuiltInId::imageAtomicAndExt_IImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01M20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01X20D00E(
+ BuiltInId::imageAtomicAndExt_UImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01X20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01H20D00E(
+ BuiltInId::imageAtomicAndExt_ImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01H20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01S20D00E(
+ BuiltInId::imageAtomicAndExt_IImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01S20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01d20D00E(
+ BuiltInId::imageAtomicAndExt_UImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01d20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01D00D00E(
+ BuiltInId::imageAtomicAndExt_Image1D1_Int1_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01D00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01O00D00E(
+ BuiltInId::imageAtomicAndExt_IImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01O00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01Z00D00E(
+ BuiltInId::imageAtomicAndExt_UImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Z00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01E10D00E(
+ BuiltInId::imageAtomicAndExt_Image1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01E10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01P10D00E(
+ BuiltInId::imageAtomicAndExt_IImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01P10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01a10D00E(
+ BuiltInId::imageAtomicAndExt_UImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01a10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01I10D00E(
+ BuiltInId::imageAtomicAndExt_ImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01I10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01T10D00E(
+ BuiltInId::imageAtomicAndExt_IImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01T10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01e10D00E(
+ BuiltInId::imageAtomicAndExt_UImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01e10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01F10D00D00E(
+ BuiltInId::imageAtomicAndExt_Image2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01F10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01Q10D00D00E(
+ BuiltInId::imageAtomicAndExt_IImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Q10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01b10D00D00E(
+ BuiltInId::imageAtomicAndExt_UImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01b10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01G20D00D00E(
+ BuiltInId::imageAtomicAndExt_Image2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01G20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01R20D00D00E(
+ BuiltInId::imageAtomicAndExt_IImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01R20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01c20D00D00E(
+ BuiltInId::imageAtomicAndExt_UImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01c20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_00z10D00D(
+ BuiltInId::imageAtomicAndExt_Image2D1_Int2_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p00z10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01K10D00D(
+ BuiltInId::imageAtomicAndExt_IImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01K10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01V10D00D(
+ BuiltInId::imageAtomicAndExt_UImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01V10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01A20D00D(
+ BuiltInId::imageAtomicAndExt_Image3D1_Int3_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01A20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01L20D00D(
+ BuiltInId::imageAtomicAndExt_IImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01L20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01W20D00D(
+ BuiltInId::imageAtomicAndExt_UImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01W20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01C20D00D(
+ BuiltInId::imageAtomicAndExt_ImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01C20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01N20D00D(
+ BuiltInId::imageAtomicAndExt_IImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01N20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01Y20D00D(
+ BuiltInId::imageAtomicAndExt_UImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Y20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01J00D00D(
+ BuiltInId::imageAtomicAndExt_ImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01J00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01U00D00D(
+ BuiltInId::imageAtomicAndExt_IImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01U00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01f00D00D(
+ BuiltInId::imageAtomicAndExt_UImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01f00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01B20D00D(
+ BuiltInId::imageAtomicAndExt_Image2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01B20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01M20D00D(
+ BuiltInId::imageAtomicAndExt_IImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01M20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01X20D00D(
+ BuiltInId::imageAtomicAndExt_UImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01X20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01H20D00D(
+ BuiltInId::imageAtomicAndExt_ImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01H20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01S20D00D(
+ BuiltInId::imageAtomicAndExt_IImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01S20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01d20D00D(
+ BuiltInId::imageAtomicAndExt_UImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01d20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01D00D00D(
+ BuiltInId::imageAtomicAndExt_Image1D1_Int1_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01D00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01O00D00D(
+ BuiltInId::imageAtomicAndExt_IImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01O00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01Z00D00D(
+ BuiltInId::imageAtomicAndExt_UImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Z00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01E10D00D(
+ BuiltInId::imageAtomicAndExt_Image1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01E10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01P10D00D(
+ BuiltInId::imageAtomicAndExt_IImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01P10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01a10D00D(
+ BuiltInId::imageAtomicAndExt_UImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01a10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01I10D00D(
+ BuiltInId::imageAtomicAndExt_ImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01I10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01T10D00D(
+ BuiltInId::imageAtomicAndExt_IImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01T10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01e10D00D(
+ BuiltInId::imageAtomicAndExt_UImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01e10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01F10D00D00D(
+ BuiltInId::imageAtomicAndExt_Image2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01F10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01Q10D00D00D(
+ BuiltInId::imageAtomicAndExt_IImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Q10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01b10D00D00D(
+ BuiltInId::imageAtomicAndExt_UImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01b10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01G20D00D00D(
+ BuiltInId::imageAtomicAndExt_Image2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01G20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01R20D00D00D(
+ BuiltInId::imageAtomicAndExt_IImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01R20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicAndExt_01c20D00D00D(
+ BuiltInId::imageAtomicAndExt_UImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicAndExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01c20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicAnd,
+ false);
+constexpr const TFunction imageAtomicOrExt_00z10D00E(
+ BuiltInId::imageAtomicOrExt_Image2D1_Int2_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p00z10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01K10D00E(
+ BuiltInId::imageAtomicOrExt_IImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01K10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01V10D00E(
+ BuiltInId::imageAtomicOrExt_UImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01V10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01A20D00E(
+ BuiltInId::imageAtomicOrExt_Image3D1_Int3_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01A20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01L20D00E(
+ BuiltInId::imageAtomicOrExt_IImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01L20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01W20D00E(
+ BuiltInId::imageAtomicOrExt_UImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01W20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01C20D00E(
+ BuiltInId::imageAtomicOrExt_ImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01C20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01N20D00E(
+ BuiltInId::imageAtomicOrExt_IImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01N20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01Y20D00E(
+ BuiltInId::imageAtomicOrExt_UImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Y20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01J00D00E(
+ BuiltInId::imageAtomicOrExt_ImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01J00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01U00D00E(
+ BuiltInId::imageAtomicOrExt_IImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01U00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01f00D00E(
+ BuiltInId::imageAtomicOrExt_UImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01f00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01B20D00E(
+ BuiltInId::imageAtomicOrExt_Image2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01B20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01M20D00E(
+ BuiltInId::imageAtomicOrExt_IImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01M20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01X20D00E(
+ BuiltInId::imageAtomicOrExt_UImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01X20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01H20D00E(
+ BuiltInId::imageAtomicOrExt_ImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01H20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01S20D00E(
+ BuiltInId::imageAtomicOrExt_IImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01S20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01d20D00E(
+ BuiltInId::imageAtomicOrExt_UImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01d20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01D00D00E(
+ BuiltInId::imageAtomicOrExt_Image1D1_Int1_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01D00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01O00D00E(
+ BuiltInId::imageAtomicOrExt_IImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01O00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01Z00D00E(
+ BuiltInId::imageAtomicOrExt_UImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Z00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01E10D00E(
+ BuiltInId::imageAtomicOrExt_Image1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01E10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01P10D00E(
+ BuiltInId::imageAtomicOrExt_IImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01P10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01a10D00E(
+ BuiltInId::imageAtomicOrExt_UImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01a10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01I10D00E(
+ BuiltInId::imageAtomicOrExt_ImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01I10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01T10D00E(
+ BuiltInId::imageAtomicOrExt_IImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01T10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01e10D00E(
+ BuiltInId::imageAtomicOrExt_UImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01e10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01F10D00D00E(
+ BuiltInId::imageAtomicOrExt_Image2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01F10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01Q10D00D00E(
+ BuiltInId::imageAtomicOrExt_IImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Q10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01b10D00D00E(
+ BuiltInId::imageAtomicOrExt_UImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01b10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01G20D00D00E(
+ BuiltInId::imageAtomicOrExt_Image2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01G20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01R20D00D00E(
+ BuiltInId::imageAtomicOrExt_IImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01R20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01c20D00D00E(
+ BuiltInId::imageAtomicOrExt_UImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01c20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_00z10D00D(
+ BuiltInId::imageAtomicOrExt_Image2D1_Int2_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p00z10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01K10D00D(
+ BuiltInId::imageAtomicOrExt_IImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01K10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01V10D00D(
+ BuiltInId::imageAtomicOrExt_UImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01V10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01A20D00D(
+ BuiltInId::imageAtomicOrExt_Image3D1_Int3_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01A20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01L20D00D(
+ BuiltInId::imageAtomicOrExt_IImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01L20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01W20D00D(
+ BuiltInId::imageAtomicOrExt_UImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01W20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01C20D00D(
+ BuiltInId::imageAtomicOrExt_ImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01C20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01N20D00D(
+ BuiltInId::imageAtomicOrExt_IImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01N20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01Y20D00D(
+ BuiltInId::imageAtomicOrExt_UImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Y20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01J00D00D(
+ BuiltInId::imageAtomicOrExt_ImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01J00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01U00D00D(
+ BuiltInId::imageAtomicOrExt_IImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01U00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01f00D00D(
+ BuiltInId::imageAtomicOrExt_UImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01f00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01B20D00D(
+ BuiltInId::imageAtomicOrExt_Image2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01B20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01M20D00D(
+ BuiltInId::imageAtomicOrExt_IImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01M20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01X20D00D(
+ BuiltInId::imageAtomicOrExt_UImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01X20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01H20D00D(
+ BuiltInId::imageAtomicOrExt_ImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01H20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01S20D00D(
+ BuiltInId::imageAtomicOrExt_IImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01S20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01d20D00D(
+ BuiltInId::imageAtomicOrExt_UImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01d20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01D00D00D(
+ BuiltInId::imageAtomicOrExt_Image1D1_Int1_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01D00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01O00D00D(
+ BuiltInId::imageAtomicOrExt_IImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01O00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01Z00D00D(
+ BuiltInId::imageAtomicOrExt_UImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Z00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01E10D00D(
+ BuiltInId::imageAtomicOrExt_Image1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01E10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01P10D00D(
+ BuiltInId::imageAtomicOrExt_IImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01P10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01a10D00D(
+ BuiltInId::imageAtomicOrExt_UImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01a10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01I10D00D(
+ BuiltInId::imageAtomicOrExt_ImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01I10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01T10D00D(
+ BuiltInId::imageAtomicOrExt_IImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01T10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01e10D00D(
+ BuiltInId::imageAtomicOrExt_UImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01e10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01F10D00D00D(
+ BuiltInId::imageAtomicOrExt_Image2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01F10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01Q10D00D00D(
+ BuiltInId::imageAtomicOrExt_IImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Q10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01b10D00D00D(
+ BuiltInId::imageAtomicOrExt_UImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01b10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01G20D00D00D(
+ BuiltInId::imageAtomicOrExt_Image2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01G20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01R20D00D00D(
+ BuiltInId::imageAtomicOrExt_IImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01R20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicOrExt_01c20D00D00D(
+ BuiltInId::imageAtomicOrExt_UImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicOrExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01c20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicOr,
+ false);
+constexpr const TFunction imageAtomicXorExt_00z10D00E(
+ BuiltInId::imageAtomicXorExt_Image2D1_Int2_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p00z10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01K10D00E(
+ BuiltInId::imageAtomicXorExt_IImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01K10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01V10D00E(
+ BuiltInId::imageAtomicXorExt_UImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01V10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01A20D00E(
+ BuiltInId::imageAtomicXorExt_Image3D1_Int3_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01A20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01L20D00E(
+ BuiltInId::imageAtomicXorExt_IImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01L20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01W20D00E(
+ BuiltInId::imageAtomicXorExt_UImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01W20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01C20D00E(
+ BuiltInId::imageAtomicXorExt_ImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01C20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01N20D00E(
+ BuiltInId::imageAtomicXorExt_IImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01N20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01Y20D00E(
+ BuiltInId::imageAtomicXorExt_UImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Y20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01J00D00E(
+ BuiltInId::imageAtomicXorExt_ImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01J00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01U00D00E(
+ BuiltInId::imageAtomicXorExt_IImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01U00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01f00D00E(
+ BuiltInId::imageAtomicXorExt_UImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01f00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01B20D00E(
+ BuiltInId::imageAtomicXorExt_Image2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01B20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01M20D00E(
+ BuiltInId::imageAtomicXorExt_IImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01M20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01X20D00E(
+ BuiltInId::imageAtomicXorExt_UImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01X20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01H20D00E(
+ BuiltInId::imageAtomicXorExt_ImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01H20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01S20D00E(
+ BuiltInId::imageAtomicXorExt_IImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01S20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01d20D00E(
+ BuiltInId::imageAtomicXorExt_UImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01d20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01D00D00E(
+ BuiltInId::imageAtomicXorExt_Image1D1_Int1_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01D00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01O00D00E(
+ BuiltInId::imageAtomicXorExt_IImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01O00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01Z00D00E(
+ BuiltInId::imageAtomicXorExt_UImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Z00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01E10D00E(
+ BuiltInId::imageAtomicXorExt_Image1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01E10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01P10D00E(
+ BuiltInId::imageAtomicXorExt_IImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01P10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01a10D00E(
+ BuiltInId::imageAtomicXorExt_UImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01a10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01I10D00E(
+ BuiltInId::imageAtomicXorExt_ImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01I10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01T10D00E(
+ BuiltInId::imageAtomicXorExt_IImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01T10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01e10D00E(
+ BuiltInId::imageAtomicXorExt_UImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01e10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01F10D00D00E(
+ BuiltInId::imageAtomicXorExt_Image2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01F10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01Q10D00D00E(
+ BuiltInId::imageAtomicXorExt_IImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Q10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01b10D00D00E(
+ BuiltInId::imageAtomicXorExt_UImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01b10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01G20D00D00E(
+ BuiltInId::imageAtomicXorExt_Image2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01G20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01R20D00D00E(
+ BuiltInId::imageAtomicXorExt_IImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01R20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01c20D00D00E(
+ BuiltInId::imageAtomicXorExt_UImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01c20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_00z10D00D(
+ BuiltInId::imageAtomicXorExt_Image2D1_Int2_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p00z10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01K10D00D(
+ BuiltInId::imageAtomicXorExt_IImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01K10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01V10D00D(
+ BuiltInId::imageAtomicXorExt_UImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01V10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01A20D00D(
+ BuiltInId::imageAtomicXorExt_Image3D1_Int3_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01A20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01L20D00D(
+ BuiltInId::imageAtomicXorExt_IImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01L20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01W20D00D(
+ BuiltInId::imageAtomicXorExt_UImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01W20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01C20D00D(
+ BuiltInId::imageAtomicXorExt_ImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01C20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01N20D00D(
+ BuiltInId::imageAtomicXorExt_IImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01N20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01Y20D00D(
+ BuiltInId::imageAtomicXorExt_UImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Y20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01J00D00D(
+ BuiltInId::imageAtomicXorExt_ImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01J00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01U00D00D(
+ BuiltInId::imageAtomicXorExt_IImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01U00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01f00D00D(
+ BuiltInId::imageAtomicXorExt_UImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01f00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01B20D00D(
+ BuiltInId::imageAtomicXorExt_Image2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01B20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01M20D00D(
+ BuiltInId::imageAtomicXorExt_IImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01M20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01X20D00D(
+ BuiltInId::imageAtomicXorExt_UImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01X20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01H20D00D(
+ BuiltInId::imageAtomicXorExt_ImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01H20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01S20D00D(
+ BuiltInId::imageAtomicXorExt_IImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01S20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01d20D00D(
+ BuiltInId::imageAtomicXorExt_UImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01d20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01D00D00D(
+ BuiltInId::imageAtomicXorExt_Image1D1_Int1_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01D00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01O00D00D(
+ BuiltInId::imageAtomicXorExt_IImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01O00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01Z00D00D(
+ BuiltInId::imageAtomicXorExt_UImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Z00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01E10D00D(
+ BuiltInId::imageAtomicXorExt_Image1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01E10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01P10D00D(
+ BuiltInId::imageAtomicXorExt_IImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01P10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01a10D00D(
+ BuiltInId::imageAtomicXorExt_UImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01a10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01I10D00D(
+ BuiltInId::imageAtomicXorExt_ImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01I10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01T10D00D(
+ BuiltInId::imageAtomicXorExt_IImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01T10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01e10D00D(
+ BuiltInId::imageAtomicXorExt_UImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01e10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01F10D00D00D(
+ BuiltInId::imageAtomicXorExt_Image2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01F10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01Q10D00D00D(
+ BuiltInId::imageAtomicXorExt_IImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Q10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01b10D00D00D(
+ BuiltInId::imageAtomicXorExt_UImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01b10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01G20D00D00D(
+ BuiltInId::imageAtomicXorExt_Image2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01G20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01R20D00D00D(
+ BuiltInId::imageAtomicXorExt_IImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01R20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicXorExt_01c20D00D00D(
+ BuiltInId::imageAtomicXorExt_UImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicXorExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01c20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicXor,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_00z10D00E(
+ BuiltInId::imageAtomicExchangeExt_Image2D1_Int2_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p00z10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01K10D00E(
+ BuiltInId::imageAtomicExchangeExt_IImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01K10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01V10D00E(
+ BuiltInId::imageAtomicExchangeExt_UImage2D1_Int2_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01V10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01A20D00E(
+ BuiltInId::imageAtomicExchangeExt_Image3D1_Int3_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01A20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01L20D00E(
+ BuiltInId::imageAtomicExchangeExt_IImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01L20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01W20D00E(
+ BuiltInId::imageAtomicExchangeExt_UImage3D1_Int3_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01W20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01C20D00E(
+ BuiltInId::imageAtomicExchangeExt_ImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01C20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01N20D00E(
+ BuiltInId::imageAtomicExchangeExt_IImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01N20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01Y20D00E(
+ BuiltInId::imageAtomicExchangeExt_UImageCube1_Int3_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Y20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01J00D00E(
+ BuiltInId::imageAtomicExchangeExt_ImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01J00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01U00D00E(
+ BuiltInId::imageAtomicExchangeExt_IImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01U00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01f00D00E(
+ BuiltInId::imageAtomicExchangeExt_UImageBuffer1_Int1_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01f00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01B20D00E(
+ BuiltInId::imageAtomicExchangeExt_Image2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01B20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01M20D00E(
+ BuiltInId::imageAtomicExchangeExt_IImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01M20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01X20D00E(
+ BuiltInId::imageAtomicExchangeExt_UImage2DArray1_Int3_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01X20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01H20D00E(
+ BuiltInId::imageAtomicExchangeExt_ImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01H20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01S20D00E(
+ BuiltInId::imageAtomicExchangeExt_IImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01S20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01d20D00E(
+ BuiltInId::imageAtomicExchangeExt_UImageCubeArray1_Int3_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01d20D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01D00D00E(
+ BuiltInId::imageAtomicExchangeExt_Image1D1_Int1_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01D00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01O00D00E(
+ BuiltInId::imageAtomicExchangeExt_IImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01O00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01Z00D00E(
+ BuiltInId::imageAtomicExchangeExt_UImage1D1_Int1_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Z00D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01E10D00E(
+ BuiltInId::imageAtomicExchangeExt_Image1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01E10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01P10D00E(
+ BuiltInId::imageAtomicExchangeExt_IImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01P10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01a10D00E(
+ BuiltInId::imageAtomicExchangeExt_UImage1DArray1_Int2_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01a10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01I10D00E(
+ BuiltInId::imageAtomicExchangeExt_ImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01I10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01T10D00E(
+ BuiltInId::imageAtomicExchangeExt_IImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01T10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01e10D00E(
+ BuiltInId::imageAtomicExchangeExt_UImageRect1_Int2_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01e10D00E00E,
+ 3,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01F10D00D00E(
+ BuiltInId::imageAtomicExchangeExt_Image2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01F10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01Q10D00D00E(
+ BuiltInId::imageAtomicExchangeExt_IImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Q10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01b10D00D00E(
+ BuiltInId::imageAtomicExchangeExt_UImage2DMS1_Int2_Int1_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01b10D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01G20D00D00E(
+ BuiltInId::imageAtomicExchangeExt_Image2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01G20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01R20D00D00E(
+ BuiltInId::imageAtomicExchangeExt_IImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01R20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01c20D00D00E(
+ BuiltInId::imageAtomicExchangeExt_UImage2DMSArray1_Int3_Int1_UInt1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01c20D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_00z10D00D(
+ BuiltInId::imageAtomicExchangeExt_Image2D1_Int2_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p00z10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01K10D00D(
+ BuiltInId::imageAtomicExchangeExt_IImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01K10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01V10D00D(
+ BuiltInId::imageAtomicExchangeExt_UImage2D1_Int2_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01V10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01A20D00D(
+ BuiltInId::imageAtomicExchangeExt_Image3D1_Int3_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01A20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01L20D00D(
+ BuiltInId::imageAtomicExchangeExt_IImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01L20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01W20D00D(
+ BuiltInId::imageAtomicExchangeExt_UImage3D1_Int3_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01W20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01C20D00D(
+ BuiltInId::imageAtomicExchangeExt_ImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01C20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01N20D00D(
+ BuiltInId::imageAtomicExchangeExt_IImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01N20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01Y20D00D(
+ BuiltInId::imageAtomicExchangeExt_UImageCube1_Int3_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Y20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01J00D00D(
+ BuiltInId::imageAtomicExchangeExt_ImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01J00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01U00D00D(
+ BuiltInId::imageAtomicExchangeExt_IImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01U00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01f00D00D(
+ BuiltInId::imageAtomicExchangeExt_UImageBuffer1_Int1_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01f00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01B20D00D(
+ BuiltInId::imageAtomicExchangeExt_Image2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01B20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01M20D00D(
+ BuiltInId::imageAtomicExchangeExt_IImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01M20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01X20D00D(
+ BuiltInId::imageAtomicExchangeExt_UImage2DArray1_Int3_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01X20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01H20D00D(
+ BuiltInId::imageAtomicExchangeExt_ImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01H20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01S20D00D(
+ BuiltInId::imageAtomicExchangeExt_IImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01S20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01d20D00D(
+ BuiltInId::imageAtomicExchangeExt_UImageCubeArray1_Int3_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01d20D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01D00D00D(
+ BuiltInId::imageAtomicExchangeExt_Image1D1_Int1_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01D00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01O00D00D(
+ BuiltInId::imageAtomicExchangeExt_IImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01O00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01Z00D00D(
+ BuiltInId::imageAtomicExchangeExt_UImage1D1_Int1_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Z00D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01E10D00D(
+ BuiltInId::imageAtomicExchangeExt_Image1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01E10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01P10D00D(
+ BuiltInId::imageAtomicExchangeExt_IImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01P10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01a10D00D(
+ BuiltInId::imageAtomicExchangeExt_UImage1DArray1_Int2_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01a10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01I10D00D(
+ BuiltInId::imageAtomicExchangeExt_ImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01I10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01T10D00D(
+ BuiltInId::imageAtomicExchangeExt_IImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01T10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01e10D00D(
+ BuiltInId::imageAtomicExchangeExt_UImageRect1_Int2_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01e10D00D00D,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01F10D00D00D(
+ BuiltInId::imageAtomicExchangeExt_Image2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01F10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01Q10D00D00D(
+ BuiltInId::imageAtomicExchangeExt_IImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Q10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01b10D00D00D(
+ BuiltInId::imageAtomicExchangeExt_UImage2DMS1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01b10D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01G20D00D00D(
+ BuiltInId::imageAtomicExchangeExt_Image2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01G20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01R20D00D00D(
+ BuiltInId::imageAtomicExchangeExt_IImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01R20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01c20D00D00D(
+ BuiltInId::imageAtomicExchangeExt_UImage2DMSArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01c20D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_00z10D00B(
+ BuiltInId::imageAtomicExchangeExt_Image2D1_Int2_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p00z10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01K10D00B(
+ BuiltInId::imageAtomicExchangeExt_IImage2D1_Int2_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01K10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01V10D00B(
+ BuiltInId::imageAtomicExchangeExt_UImage2D1_Int2_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01V10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01A20D00B(
+ BuiltInId::imageAtomicExchangeExt_Image3D1_Int3_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01A20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01L20D00B(
+ BuiltInId::imageAtomicExchangeExt_IImage3D1_Int3_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01L20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01W20D00B(
+ BuiltInId::imageAtomicExchangeExt_UImage3D1_Int3_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01W20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01C20D00B(
+ BuiltInId::imageAtomicExchangeExt_ImageCube1_Int3_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01C20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01N20D00B(
+ BuiltInId::imageAtomicExchangeExt_IImageCube1_Int3_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01N20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01Y20D00B(
+ BuiltInId::imageAtomicExchangeExt_UImageCube1_Int3_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Y20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01J00D00B(
+ BuiltInId::imageAtomicExchangeExt_ImageBuffer1_Int1_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01J00D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01U00D00B(
+ BuiltInId::imageAtomicExchangeExt_IImageBuffer1_Int1_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01U00D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01f00D00B(
+ BuiltInId::imageAtomicExchangeExt_UImageBuffer1_Int1_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01f00D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01B20D00B(
+ BuiltInId::imageAtomicExchangeExt_Image2DArray1_Int3_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01B20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01M20D00B(
+ BuiltInId::imageAtomicExchangeExt_IImage2DArray1_Int3_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01M20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01X20D00B(
+ BuiltInId::imageAtomicExchangeExt_UImage2DArray1_Int3_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01X20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01H20D00B(
+ BuiltInId::imageAtomicExchangeExt_ImageCubeArray1_Int3_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01H20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01S20D00B(
+ BuiltInId::imageAtomicExchangeExt_IImageCubeArray1_Int3_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01S20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01d20D00B(
+ BuiltInId::imageAtomicExchangeExt_UImageCubeArray1_Int3_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01d20D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01D00D00B(
+ BuiltInId::imageAtomicExchangeExt_Image1D1_Int1_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01D00D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01O00D00B(
+ BuiltInId::imageAtomicExchangeExt_IImage1D1_Int1_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01O00D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01Z00D00B(
+ BuiltInId::imageAtomicExchangeExt_UImage1D1_Int1_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Z00D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01E10D00B(
+ BuiltInId::imageAtomicExchangeExt_Image1DArray1_Int2_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01E10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01P10D00B(
+ BuiltInId::imageAtomicExchangeExt_IImage1DArray1_Int2_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01P10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01a10D00B(
+ BuiltInId::imageAtomicExchangeExt_UImage1DArray1_Int2_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01a10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01I10D00B(
+ BuiltInId::imageAtomicExchangeExt_ImageRect1_Int2_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01I10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01T10D00B(
+ BuiltInId::imageAtomicExchangeExt_IImageRect1_Int2_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01T10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01e10D00B(
+ BuiltInId::imageAtomicExchangeExt_UImageRect1_Int2_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01e10D00B,
+ 3,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01F10D00D00B(
+ BuiltInId::imageAtomicExchangeExt_Image2DMS1_Int2_Int1_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01F10D00D00B,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01Q10D00D00B(
+ BuiltInId::imageAtomicExchangeExt_IImage2DMS1_Int2_Int1_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Q10D00D00B,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01b10D00D00B(
+ BuiltInId::imageAtomicExchangeExt_UImage2DMS1_Int2_Int1_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01b10D00D00B,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01G20D00D00B(
+ BuiltInId::imageAtomicExchangeExt_Image2DMSArray1_Int3_Int1_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01G20D00D00B,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01R20D00D00B(
+ BuiltInId::imageAtomicExchangeExt_IImage2DMSArray1_Int3_Int1_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01R20D00D00B,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicExchangeExt_01c20D00D00B(
+ BuiltInId::imageAtomicExchangeExt_UImage2DMSArray1_Int3_Int1_Float1,
+ BuiltInName::imageAtomicExchangeExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01c20D00D00B,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicExchange,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_00z10D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_Image2D1_Int2_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p00z10D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01K10D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_IImage2D1_Int2_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01K10D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01V10D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_UImage2D1_Int2_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01V10D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01A20D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_Image3D1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01A20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01L20D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_IImage3D1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01L20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01W20D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_UImage3D1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01W20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01C20D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_ImageCube1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01C20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01N20D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_IImageCube1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01N20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01Y20D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_UImageCube1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Y20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01J00D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_ImageBuffer1_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01J00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01U00D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_IImageBuffer1_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01U00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01f00D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_UImageBuffer1_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01f00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01B20D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_Image2DArray1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01B20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01M20D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_IImage2DArray1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01M20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01X20D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_UImage2DArray1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01X20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01H20D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_ImageCubeArray1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01H20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01S20D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_IImageCubeArray1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01S20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01d20D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_UImageCubeArray1_Int3_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01d20D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01D00D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_Image1D1_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01D00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01O00D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_IImage1D1_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01O00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01Z00D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_UImage1D1_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Z00D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01E10D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_Image1DArray1_Int2_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01E10D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01P10D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_IImage1DArray1_Int2_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01P10D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01a10D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_UImage1DArray1_Int2_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01a10D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01I10D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_ImageRect1_Int2_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01I10D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01T10D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_IImageRect1_Int2_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01T10D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01e10D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_UImageRect1_Int2_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01e10D00E00E,
+ 4,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01F10D00D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_Image2DMS1_Int2_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01F10D00D00E00E,
+ 5,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01Q10D00D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_IImage2DMS1_Int2_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Q10D00D00E00E,
+ 5,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01b10D00D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_UImage2DMS1_Int2_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01b10D00D00E00E,
+ 5,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01G20D00D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_Image2DMSArray1_Int3_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01G20D00D00E00E,
+ 5,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01R20D00D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_IImage2DMSArray1_Int3_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01R20D00D00E00E,
+ 5,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01c20D00D00E00E(
+ BuiltInId::imageAtomicCompSwapExt_UImage2DMSArray1_Int3_Int1_UInt1_UInt1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01c20D00D00E00E,
+ 5,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_00z10D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_Image2D1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p00z10D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01K10D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_IImage2D1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01K10D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01V10D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_UImage2D1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01V10D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01A20D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_Image3D1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01A20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01L20D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_IImage3D1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01L20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01W20D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_UImage3D1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01W20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01C20D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_ImageCube1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01C20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01N20D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_IImageCube1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01N20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01Y20D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_UImageCube1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Y20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01J00D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_ImageBuffer1_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01J00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01U00D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_IImageBuffer1_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01U00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01f00D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_UImageBuffer1_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01f00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01B20D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_Image2DArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01B20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01M20D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_IImage2DArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01M20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01X20D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_UImage2DArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01X20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01H20D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_ImageCubeArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01H20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01S20D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_IImageCubeArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01S20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01d20D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_UImageCubeArray1_Int3_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01d20D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01D00D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_Image1D1_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01D00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01O00D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_IImage1D1_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01O00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01Z00D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_UImage1D1_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Z00D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01E10D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_Image1DArray1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01E10D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01P10D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_IImage1DArray1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01P10D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01a10D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_UImage1DArray1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01a10D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01I10D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_ImageRect1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01I10D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01T10D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_IImageRect1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01T10D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01e10D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_UImageRect1_Int2_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01e10D00D00D,
+ 4,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01F10D00D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_Image2DMS1_Int2_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01F10D00D00D00D,
+ 5,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01Q10D00D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_IImage2DMS1_Int2_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01Q10D00D00D00D,
+ 5,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01b10D00D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_UImage2DMS1_Int2_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01b10D00D00D00D,
+ 5,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01G20D00D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_Image2DMSArray1_Int3_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01G20D00D00D00D,
+ 5,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01R20D00D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_IImage2DMSArray1_Int3_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01R20D00D00D00D,
+ 5,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction imageAtomicCompSwapExt_01c20D00D00D00D(
+ BuiltInId::imageAtomicCompSwapExt_UImage2DMSArray1_Int3_Int1_Int1_Int1,
+ BuiltInName::imageAtomicCompSwapExt,
+ std::array<TExtension, 1u>{{TExtension::OES_shader_image_atomic}},
+ BuiltInParameters::p01c20D00D00D00D,
+ 5,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpImageAtomicCompSwap,
+ false);
+constexpr const TFunction pixelLocalLoadANGLE_01g(
+ BuiltInId::pixelLocalLoadANGLE_PixelLocalANGLE1,
+ BuiltInName::pixelLocalLoadANGLE,
+ std::array<TExtension, 1u>{{TExtension::ANGLE_shader_pixel_local_storage}},
+ BuiltInParameters::p01g30B,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpPixelLocalLoadANGLE,
+ false);
+constexpr const TFunction pixelLocalLoadANGLE_01h(
+ BuiltInId::pixelLocalLoadANGLE_IPixelLocalANGLE1,
+ BuiltInName::pixelLocalLoadANGLE,
+ std::array<TExtension, 1u>{{TExtension::ANGLE_shader_pixel_local_storage}},
+ BuiltInParameters::p01h30D,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpPixelLocalLoadANGLE,
+ false);
+constexpr const TFunction pixelLocalLoadANGLE_01i(
+ BuiltInId::pixelLocalLoadANGLE_UPixelLocalANGLE1,
+ BuiltInName::pixelLocalLoadANGLE,
+ std::array<TExtension, 1u>{{TExtension::ANGLE_shader_pixel_local_storage}},
+ BuiltInParameters::p01i30E,
+ 1,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpPixelLocalLoadANGLE,
+ false);
+constexpr const TFunction pixelLocalStoreANGLE_01g30B(
+ BuiltInId::pixelLocalStoreANGLE_PixelLocalANGLE1_Float4,
+ BuiltInName::pixelLocalStoreANGLE,
+ std::array<TExtension, 1u>{{TExtension::ANGLE_shader_pixel_local_storage}},
+ BuiltInParameters::p01g30B,
+ 2,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpPixelLocalStoreANGLE,
+ false);
+constexpr const TFunction pixelLocalStoreANGLE_01h30D(
+ BuiltInId::pixelLocalStoreANGLE_IPixelLocalANGLE1_Int4,
+ BuiltInName::pixelLocalStoreANGLE,
+ std::array<TExtension, 1u>{{TExtension::ANGLE_shader_pixel_local_storage}},
+ BuiltInParameters::p01h30D,
+ 2,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpPixelLocalStoreANGLE,
+ false);
+constexpr const TFunction pixelLocalStoreANGLE_01i30E(
+ BuiltInId::pixelLocalStoreANGLE_UPixelLocalANGLE1_UInt4,
+ BuiltInName::pixelLocalStoreANGLE,
+ std::array<TExtension, 1u>{{TExtension::ANGLE_shader_pixel_local_storage}},
+ BuiltInParameters::p01i30E,
+ 2,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpPixelLocalStoreANGLE,
+ false);
+constexpr const TFunction beginInvocationInterlockNV_(
+ BuiltInId::beginInvocationInterlockNV,
+ BuiltInName::beginInvocationInterlockNV,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::empty,
+ 0,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpBeginInvocationInterlockNV,
+ false);
+constexpr const TFunction endInvocationInterlockNV_(
+ BuiltInId::endInvocationInterlockNV,
+ BuiltInName::endInvocationInterlockNV,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::empty,
+ 0,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpEndInvocationInterlockNV,
+ false);
+constexpr const TFunction beginFragmentShaderOrderingINTEL_(
+ BuiltInId::beginFragmentShaderOrderingINTEL,
+ BuiltInName::beginFragmentShaderOrderingINTEL,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::empty,
+ 0,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpBeginFragmentShaderOrderingINTEL,
+ false);
+constexpr const TFunction beginInvocationInterlockARB_(
+ BuiltInId::beginInvocationInterlockARB,
+ BuiltInName::beginInvocationInterlockARB,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::empty,
+ 0,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpBeginInvocationInterlockARB,
+ false);
+constexpr const TFunction endInvocationInterlockARB_(
+ BuiltInId::endInvocationInterlockARB,
+ BuiltInName::endInvocationInterlockARB,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::empty,
+ 0,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpEndInvocationInterlockARB,
+ false);
+constexpr const TFunction memoryBarrier_(BuiltInId::memoryBarrier,
+ BuiltInName::memoryBarrier,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::empty,
+ 0,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpMemoryBarrier,
+ false);
+constexpr const TFunction memoryBarrierAtomicCounter_(
+ BuiltInId::memoryBarrierAtomicCounter,
+ BuiltInName::memoryBarrierAtomicCounter,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::empty,
+ 0,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpMemoryBarrierAtomicCounter,
+ false);
+constexpr const TFunction memoryBarrierBuffer_(
+ BuiltInId::memoryBarrierBuffer,
+ BuiltInName::memoryBarrierBuffer,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::empty,
+ 0,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpMemoryBarrierBuffer,
+ false);
+constexpr const TFunction memoryBarrierImage_(
+ BuiltInId::memoryBarrierImage,
+ BuiltInName::memoryBarrierImage,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::empty,
+ 0,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpMemoryBarrierImage,
+ false);
+constexpr const TFunction barrier_(BuiltInId::barrier,
+ BuiltInName::barrier,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::empty,
+ 0,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpBarrier,
+ false);
+constexpr const TFunction memoryBarrierShared_(
+ BuiltInId::memoryBarrierShared,
+ BuiltInName::memoryBarrierShared,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::empty,
+ 0,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpMemoryBarrierShared,
+ false);
+constexpr const TFunction groupMemoryBarrier_(
+ BuiltInId::groupMemoryBarrier,
+ BuiltInName::groupMemoryBarrier,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::empty,
+ 0,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpGroupMemoryBarrier,
+ false);
+constexpr const TFunction barrierTCS_(BuiltInId::barrierTCS,
+ BuiltInName::barrierTCS,
+ std::array<TExtension, 1u>{
+ {TExtension::EXT_tessellation_shader}},
+ BuiltInParameters::empty,
+ 0,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpBarrierTCS,
+ false);
+constexpr const TFunction barrierTCSES3_2_(
+ BuiltInId::barrierTCSES3_2,
+ BuiltInName::barrierTCSES3_2,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::empty,
+ 0,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpBarrierTCS,
+ false);
+constexpr const TFunction EmitVertex_(BuiltInId::EmitVertex,
+ BuiltInName::EmitVertex,
+ std::array<TExtension, 2u>{{TExtension::EXT_geometry_shader,
+ TExtension::OES_geometry_shader}},
+ BuiltInParameters::empty,
+ 0,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpEmitVertex,
+ false);
+constexpr const TFunction EmitVertexES3_2_(
+ BuiltInId::EmitVertexES3_2,
+ BuiltInName::EmitVertexES3_2,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::empty,
+ 0,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpEmitVertex,
+ false);
+constexpr const TFunction EndPrimitive_(
+ BuiltInId::EndPrimitive,
+ BuiltInName::EndPrimitive,
+ std::array<TExtension, 2u>{{TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}},
+ BuiltInParameters::empty,
+ 0,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpEndPrimitive,
+ false);
+constexpr const TFunction EndPrimitiveES3_2_(
+ BuiltInId::EndPrimitiveES3_2,
+ BuiltInName::EndPrimitiveES3_2,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::empty,
+ 0,
+ StaticType::Get<EbtVoid, EbpUndefined, EvqGlobal, 1, 1>(),
+ EOpEndPrimitive,
+ false);
+constexpr const TFunction subpassLoad_01j(
+ BuiltInId::subpassLoad_SubpassInput1,
+ BuiltInName::subpassLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01j,
+ 1,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpSubpassLoad,
+ false);
+constexpr const TFunction subpassLoad_01k(BuiltInId::subpassLoad_ISubpassInput1,
+ BuiltInName::subpassLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01k,
+ 1,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpSubpassLoad,
+ false);
+constexpr const TFunction subpassLoad_01l(BuiltInId::subpassLoad_USubpassInput1,
+ BuiltInName::subpassLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01l,
+ 1,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpSubpassLoad,
+ false);
+constexpr const TFunction subpassLoad_01m00D(
+ BuiltInId::subpassLoad_SubpassInputMS1_Int1,
+ BuiltInName::subpassLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01m00D,
+ 2,
+ StaticType::Get<EbtFloat, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpSubpassLoad,
+ false);
+constexpr const TFunction subpassLoad_01n00D(
+ BuiltInId::subpassLoad_ISubpassInputMS1_Int1,
+ BuiltInName::subpassLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01n00D,
+ 2,
+ StaticType::Get<EbtInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpSubpassLoad,
+ false);
+constexpr const TFunction subpassLoad_01o00D(
+ BuiltInId::subpassLoad_USubpassInputMS1_Int1,
+ BuiltInName::subpassLoad,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ BuiltInParameters::p01o00D,
+ 2,
+ StaticType::Get<EbtUInt, EbpUndefined, EvqGlobal, 4, 1>(),
+ EOpSubpassLoad,
+ false);
+
+} // namespace Func
+
+namespace BuiltInArray
+{
+using namespace Func;
+using Rule = SymbolRule;
+
+// Rules used to initialize the mangled name array.
+constexpr SymbolRule kRules[] = {
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&radians_00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&radians_10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&radians_20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&radians_30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&degrees_00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&degrees_10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&degrees_20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&degrees_30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&sin_00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&sin_10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&sin_20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&sin_30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&cos_00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&cos_10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&cos_20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&cos_30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&tan_00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&tan_10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&tan_20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&tan_30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&asin_00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&asin_10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&asin_20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&asin_30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&acos_00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&acos_10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&acos_20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&acos_30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&atan_00B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&atan_10B10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&atan_20B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&atan_30B30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&atan_00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&atan_10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&atan_20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&atan_30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&sinh_00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&sinh_10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&sinh_20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&sinh_30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&cosh_00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&cosh_10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&cosh_20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&cosh_30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&tanh_00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&tanh_10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&tanh_20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&tanh_30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&asinh_00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&asinh_10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&asinh_20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&asinh_30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&acosh_00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&acosh_10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&acosh_20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&acosh_30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&atanh_00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&atanh_10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&atanh_20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&atanh_30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&pow_00B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&pow_10B10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&pow_20B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&pow_30B30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&exp_00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&exp_10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&exp_20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&exp_30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&log_00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&log_10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&log_20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&log_30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&exp2_00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&exp2_10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&exp2_20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&exp2_30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&log2_00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&log2_10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&log2_20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&log2_30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&sqrt_00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&sqrt_10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&sqrt_20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&sqrt_30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&inversesqrt_00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&inversesqrt_10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&inversesqrt_20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&inversesqrt_30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&abs_00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&abs_10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&abs_20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&abs_30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&abs_00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&abs_10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&abs_20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&abs_30D),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&sign_00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&sign_10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&sign_20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&sign_30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&sign_00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&sign_10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&sign_20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&sign_30D),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&floor_00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&floor_10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&floor_20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&floor_30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&trunc_00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&trunc_10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&trunc_20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&trunc_30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&round_00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&round_10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&round_20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&round_30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&roundEven_00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&roundEven_10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&roundEven_20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&roundEven_30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&ceil_00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&ceil_10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&ceil_20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&ceil_30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&fract_00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&fract_10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&fract_20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&fract_30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&mod_00B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&mod_10B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&mod_20B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&mod_30B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&mod_10B10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&mod_20B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&mod_30B30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&min_00B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&min_10B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&min_20B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&min_30B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&min_10B10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&min_20B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&min_30B30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&min_00D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&min_10D10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&min_20D20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&min_30D30D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&min_10D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&min_20D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&min_30D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&min_00E00E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&min_10E10E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&min_20E20E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&min_30E30E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&min_10E00E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&min_20E00E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&min_30E00E),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&max_00B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&max_10B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&max_20B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&max_30B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&max_10B10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&max_20B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&max_30B30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&max_00D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&max_10D10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&max_20D20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&max_30D30D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&max_10D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&max_20D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&max_30D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&max_00E00E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&max_10E10E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&max_20E20E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&max_30E30E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&max_10E00E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&max_20E00E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&max_30E00E),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&clamp_00B00B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&clamp_10B00B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&clamp_20B00B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&clamp_30B00B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&clamp_10B10B10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&clamp_20B20B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&clamp_30B30B30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&clamp_00D00D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&clamp_10D00D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&clamp_20D00D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&clamp_30D00D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&clamp_10D10D10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&clamp_20D20D20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&clamp_30D30D30D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&clamp_00E00E00E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&clamp_10E00E00E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&clamp_20E00E00E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&clamp_30E00E00E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&clamp_10E10E10E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&clamp_20E20E20E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&clamp_30E30E30E),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&mix_00B00B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&mix_10B10B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&mix_20B20B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&mix_30B30B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&mix_10B10B10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&mix_20B20B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&mix_30B30B30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&mix_00B00B00F),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&mix_10B10B10F),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&mix_20B20B20F),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&mix_30B30B30F),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&mix_00D00D00F),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&mix_10D10D10F),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&mix_20D20D20F),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&mix_30D30D30F),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&mix_00E00E00F),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&mix_10E10E10F),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&mix_20E20E20F),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&mix_30E30E30F),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&mix_00F00F00F),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&mix_10F10F10F),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&mix_20F20F20F),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&mix_30F30F30F),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&step_00B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&step_10B10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&step_20B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&step_30B30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&step_00B10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&step_00B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&step_00B30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&smoothstep_00B00B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&smoothstep_10B10B10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&smoothstep_20B20B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&smoothstep_30B30B30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&smoothstep_00B00B10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&smoothstep_00B00B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&smoothstep_00B00B30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&modf_00B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&modf_10B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&modf_20B20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&modf_30B30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&isnan_00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&isnan_10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&isnan_20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&isnan_30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&isinf_00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&isinf_10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&isinf_20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&isinf_30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&floatBitsToInt_00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&floatBitsToInt_10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&floatBitsToInt_20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&floatBitsToInt_30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&floatBitsToUint_00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&floatBitsToUint_10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&floatBitsToUint_20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&floatBitsToUint_30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&intBitsToFloat_00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&intBitsToFloat_10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&intBitsToFloat_20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&intBitsToFloat_30D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&uintBitsToFloat_00E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&uintBitsToFloat_10E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&uintBitsToFloat_20E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&uintBitsToFloat_30E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&fma_00B00B00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_gpu_shader5)>(&fmaExt_00B00B00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&fma_10B10B10B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_gpu_shader5)>(&fmaExt_10B10B10B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&fma_20B20B20B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_gpu_shader5)>(&fmaExt_20B20B20B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&fma_30B30B30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_gpu_shader5)>(&fmaExt_30B30B30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&frexp_00B00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&frexp_10B10D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&frexp_20B20D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&frexp_30B30D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&ldexp_00B00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&ldexp_10B10D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&ldexp_20B20D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&ldexp_30B30D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&packSnorm2x16_10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&packHalf2x16_10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&unpackSnorm2x16_00E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&unpackHalf2x16_00E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&packUnorm2x16_10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&unpackUnorm2x16_00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&packUnorm4x8_30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&packSnorm4x8_30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&unpackUnorm4x8_00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&unpackSnorm4x8_00E),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&length_00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&length_10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&length_20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&length_30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&distance_00B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&distance_10B10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&distance_20B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&distance_30B30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&dot_00B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&dot_10B10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&dot_20B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&dot_30B30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&cross_20B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&normalize_00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&normalize_10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&normalize_20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&normalize_30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&faceforward_00B00B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&faceforward_10B10B10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&faceforward_20B20B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&faceforward_30B30B30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&reflect_00B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&reflect_10B10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&reflect_20B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&reflect_30B30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&refract_00B00B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&refract_10B10B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&refract_20B20B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&refract_30B30B00B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&matrixCompMult_50B50B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&matrixCompMult_A0BA0B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&matrixCompMult_F0BF0B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&matrixCompMult_90B90B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&matrixCompMult_60B60B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&matrixCompMult_D0BD0B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&matrixCompMult_70B70B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&matrixCompMult_E0BE0B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&matrixCompMult_B0BB0B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&outerProduct_10B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&outerProduct_20B20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&outerProduct_30B30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&outerProduct_20B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&outerProduct_10B20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&outerProduct_30B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&outerProduct_10B30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&outerProduct_30B20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&outerProduct_20B30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&transpose_50B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&transpose_A0B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&transpose_F0B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&transpose_60B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&transpose_90B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&transpose_70B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&transpose_D0B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&transpose_B0B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&transpose_E0B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&determinant_50B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&determinant_A0B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&determinant_F0B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&inverse_50B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&inverse_A0B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&inverse_F0B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&lessThan_10B10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&lessThan_20B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&lessThan_30B30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&lessThan_10D10D),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&lessThan_20D20D),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&lessThan_30D30D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&lessThan_10E10E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&lessThan_20E20E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&lessThan_30E30E),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&lessThanEqual_10B10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&lessThanEqual_20B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&lessThanEqual_30B30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&lessThanEqual_10D10D),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&lessThanEqual_20D20D),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&lessThanEqual_30D30D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&lessThanEqual_10E10E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&lessThanEqual_20E20E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&lessThanEqual_30E30E),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&greaterThan_10B10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&greaterThan_20B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&greaterThan_30B30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&greaterThan_10D10D),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&greaterThan_20D20D),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&greaterThan_30D30D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&greaterThan_10E10E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&greaterThan_20E20E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&greaterThan_30E30E),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&greaterThanEqual_10B10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&greaterThanEqual_20B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&greaterThanEqual_30B30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&greaterThanEqual_10D10D),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&greaterThanEqual_20D20D),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&greaterThanEqual_30D30D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&greaterThanEqual_10E10E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&greaterThanEqual_20E20E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&greaterThanEqual_30E30E),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&equal_10B10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&equal_20B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&equal_30B30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&equal_10D10D),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&equal_20D20D),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&equal_30D30D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&equal_10E10E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&equal_20E20E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&equal_30E30E),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&equal_10F10F),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&equal_20F20F),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&equal_30F30F),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&notEqual_10B10B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&notEqual_20B20B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&notEqual_30B30B),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&notEqual_10D10D),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&notEqual_20D20D),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&notEqual_30D30D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&notEqual_10E10E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&notEqual_20E20E),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&notEqual_30E30E),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&notEqual_10F10F),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&notEqual_20F20F),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&notEqual_30F30F),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&any_10F),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&any_20F),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&any_30F),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&all_10F),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&all_20F),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&all_30F),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&notFunc_10F),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&notFunc_20F),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&notFunc_30F),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldExtract_00D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldExtract_10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldExtract_20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldExtract_30D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldExtract_00E00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldExtract_10E00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldExtract_20E00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldExtract_30E00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldInsert_00D00D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldInsert_10D10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldInsert_20D20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldInsert_30D30D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldInsert_00E00E00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldInsert_10E10E00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldInsert_20E20E00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldInsert_30E30E00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldReverse_00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldReverse_10D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldReverse_20D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldReverse_30D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldReverse_00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldReverse_10E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldReverse_20E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitfieldReverse_30E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitCount_00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitCount_10D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitCount_20D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitCount_30D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitCount_00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitCount_10E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitCount_20E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&bitCount_30E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&findLSB_00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&findLSB_10D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&findLSB_20D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&findLSB_30D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&findLSB_00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&findLSB_10E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&findLSB_20E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&findLSB_30E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&findMSB_00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&findMSB_10D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&findMSB_20D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&findMSB_30D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&findMSB_00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&findMSB_10E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&findMSB_20E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&findMSB_30E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&uaddCarry_00E00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&uaddCarry_10E10E10E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&uaddCarry_20E20E20E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&uaddCarry_30E30E30E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&usubBorrow_00E00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&usubBorrow_10E10E10E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&usubBorrow_20E20E20E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&usubBorrow_30E30E30E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&umulExtended_00E00E00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&umulExtended_10E10E10E10E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&umulExtended_20E20E20E20E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&umulExtended_30E30E30E30E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imulExtended_00D00D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imulExtended_10D10D10D10D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imulExtended_20D20D20D20D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imulExtended_30D30D30D30D),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, 0>(&texture2D_00I10B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, 0>(&texture2DProj_00I20B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, 0>(&texture2DProj_00I30B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, 0>(&textureCube_00K20B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, EXT_INDEX(OES_texture_3D)>(&texture3D_00J20B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, EXT_INDEX(OES_texture_3D)>(&texture3DProj_00J30B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, EXT_INDEX(EXT_shadow_samplers)>(&shadow2DEXT_00d20B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, EXT_INDEX(EXT_shadow_samplers)>(
+ &shadow2DProjEXT_00d30B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, EXT_INDEX(OES_EGL_image_external)>(&texture2D_00M10B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, EXT_INDEX(NV_EGL_stream_consumer_external)>(
+ &texture2D_00M10B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, EXT_INDEX(OES_EGL_image_external)>(
+ &texture2DProj_00M20B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, EXT_INDEX(NV_EGL_stream_consumer_external)>(
+ &texture2DProj_00M20B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, EXT_INDEX(OES_EGL_image_external)>(
+ &texture2DProj_00M30B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, EXT_INDEX(NV_EGL_stream_consumer_external)>(
+ &texture2DProj_00M30B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, EXT_INDEX(ARB_texture_rectangle)>(
+ &texture2DRect_00O10B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, EXT_INDEX(ARB_texture_rectangle)>(
+ &texture2DRectProj_00O20B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, EXT_INDEX(ARB_texture_rectangle)>(
+ &texture2DRectProj_00O30B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, EXT_INDEX(EXT_shader_texture_lod)>(
+ &texture2DGradEXT_00I10B10B10B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, EXT_INDEX(EXT_shader_texture_lod)>(
+ &texture2DProjGradEXT_00I20B10B10B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, EXT_INDEX(EXT_shader_texture_lod)>(
+ &texture2DProjGradEXT_00I30B10B10B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, EXT_INDEX(EXT_shader_texture_lod)>(
+ &textureCubeGradEXT_00K20B20B20B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, 0>(&textureVideoWEBGL_00y10B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, 0>(&texture2D_00I10B00B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, 0>(&texture2DProj_00I20B00B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, 0>(&texture2DProj_00I30B00B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, 0>(&textureCube_00K20B00B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(OES_texture_3D)>(&texture3D_00J20B00B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(OES_texture_3D)>(
+ &texture3DProj_00J30B00B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, EXT_INDEX(OES_texture_3D)>(&texture3DLod_00J20B00B),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, EXT_INDEX(OES_texture_3D)>(&texture3DProjLod_00J30B00B),
+ Rule::Get<Spec::ESSL, 100, Shader::VERTEX, 0>(&texture2DLod_00I10B00B),
+ Rule::Get<Spec::ESSL, 100, Shader::VERTEX, 0>(&texture2DProjLod_00I20B00B),
+ Rule::Get<Spec::ESSL, 100, Shader::VERTEX, 0>(&texture2DProjLod_00I30B00B),
+ Rule::Get<Spec::ESSL, 100, Shader::VERTEX, 0>(&textureCubeLod_00K20B00B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(EXT_shader_texture_lod)>(
+ &texture2DLodEXT_00I10B00B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(EXT_shader_texture_lod)>(
+ &texture2DProjLodEXT_00I20B00B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(EXT_shader_texture_lod)>(
+ &texture2DProjLodEXT_00I30B00B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(EXT_shader_texture_lod)>(
+ &textureCubeLodEXT_00K20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texture_00I10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texture_00R10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texture_00X10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texture_00J20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texture_00S20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texture_00Y20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texture_00K20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texture_00T20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texture_00Z20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texture_00L20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texture_00U20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texture_00a20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texture_00d20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texture_00e30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texture_00f30B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&texture_00k30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureExt_00k30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureExt_00k30B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&texture_00s30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureExt_00s30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureExt_00s30B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&texture_00x30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureExt_00x30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureExt_00x30B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&texture_00l30B00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureExt_00l30B00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureExt_00l30B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(OES_EGL_image_external_essl3)>(
+ &texture_00M10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(EXT_YUV_target)>(&texture_00N10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(ARB_texture_rectangle)>(&texture_00O10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texture_00y10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProj_00I20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProj_00R20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProj_00X20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProj_00I30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProj_00R30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProj_00X30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProj_00J30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProj_00S30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProj_00Y30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProj_00d30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(OES_EGL_image_external_essl3)>(
+ &textureProj_00M20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(OES_EGL_image_external_essl3)>(
+ &textureProj_00M30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(EXT_YUV_target)>(&textureProj_00N20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(EXT_YUV_target)>(&textureProj_00N30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(ARB_texture_rectangle)>(&textureProj_00O20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(ARB_texture_rectangle)>(&textureProj_00O30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLod_00I10B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLod_00R10B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLod_00X10B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLod_00J20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLod_00S20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLod_00Y20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLod_00K20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLod_00T20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLod_00Z20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLod_00L20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLod_00U20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLod_00a20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLod_00d20B00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureLod_00k30B00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureLodExt_00k30B00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureLodExt_00k30B00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureLod_00s30B00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureLodExt_00s30B00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureLodExt_00s30B00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureLod_00x30B00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureLodExt_00x30B00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureLodExt_00x30B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureSize_00I00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureSize_00R00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureSize_00X00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureSize_00J00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureSize_00S00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureSize_00Y00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureSize_00K00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureSize_00T00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureSize_00Z00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureSize_00L00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureSize_00U00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureSize_00a00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureSize_00d00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureSize_00e00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureSize_00f00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureSize_00k00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureSizeExt_00k00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureSizeExt_00k00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureSize_00s00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureSizeExt_00s00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureSizeExt_00s00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureSize_00x00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureSizeExt_00x00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureSizeExt_00x00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureSize_00l00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureSizeExt_00l00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureSizeExt_00l00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureSize_00j),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_buffer)>(&textureSizeExt_00j),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_buffer)>(&textureSizeExt_00j),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureSize_00r),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_buffer)>(&textureSizeExt_00r),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_buffer)>(&textureSizeExt_00r),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureSize_00w),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_buffer)>(&textureSizeExt_00w),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_buffer)>(&textureSizeExt_00w),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureSize_00P),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(ANGLE_texture_multisample)>(
+ &textureSizeExt_00P),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureSize_00V),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(ANGLE_texture_multisample)>(
+ &textureSizeExt_00V),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureSize_00b),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(ANGLE_texture_multisample)>(
+ &textureSizeExt_00b),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureSize_00Q),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_storage_multisample_2d_array)>(
+ &textureSizeExt_00Q),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureSize_00W),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_storage_multisample_2d_array)>(
+ &textureSizeExt_00W),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureSize_00c),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_storage_multisample_2d_array)>(
+ &textureSizeExt_00c),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(OES_EGL_image_external_essl3)>(
+ &textureSize_00M00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(EXT_YUV_target)>(&textureSize_00N00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjLod_00I20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjLod_00R20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjLod_00X20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjLod_00I30B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjLod_00R30B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjLod_00X30B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjLod_00J30B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjLod_00S30B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjLod_00Y30B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjLod_00d30B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texelFetch_00I10D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texelFetch_00R10D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texelFetch_00X10D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texelFetch_00J20D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texelFetch_00S20D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texelFetch_00Y20D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texelFetch_00L20D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texelFetch_00U20D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texelFetch_00a20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&texelFetch_00j00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_buffer)>(&texelFetchExt_00j00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_buffer)>(&texelFetchExt_00j00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&texelFetch_00r00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_buffer)>(&texelFetchExt_00r00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_buffer)>(&texelFetchExt_00r00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&texelFetch_00w00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_buffer)>(&texelFetchExt_00w00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_buffer)>(&texelFetchExt_00w00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&texelFetch_00P10D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(ANGLE_texture_multisample)>(
+ &texelFetchExt_00P10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&texelFetch_00V10D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(ANGLE_texture_multisample)>(
+ &texelFetchExt_00V10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&texelFetch_00b10D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(ANGLE_texture_multisample)>(
+ &texelFetchExt_00b10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&texelFetch_00Q20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_storage_multisample_2d_array)>(
+ &texelFetchExt_00Q20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&texelFetch_00W20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_storage_multisample_2d_array)>(
+ &texelFetchExt_00W20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&texelFetch_00c20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_storage_multisample_2d_array)>(
+ &texelFetchExt_00c20D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(OES_EGL_image_external_essl3)>(
+ &texelFetch_00M10D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(EXT_YUV_target)>(&texelFetch_00N10D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGrad_00I10B10B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGrad_00R10B10B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGrad_00X10B10B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGrad_00J20B20B20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGrad_00S20B20B20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGrad_00Y20B20B20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGrad_00K20B20B20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGrad_00T20B20B20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGrad_00Z20B20B20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGrad_00d20B10B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGrad_00e30B20B20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGrad_00L20B10B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGrad_00U20B10B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGrad_00a20B10B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGrad_00f30B10B10B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGrad_00k30B20B20B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureGradExt_00k30B20B20B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureGradExt_00k30B20B20B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGrad_00s30B20B20B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureGradExt_00s30B20B20B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureGradExt_00s30B20B20B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGrad_00x30B20B20B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureGradExt_00x30B20B20B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureGradExt_00x30B20B20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjGrad_00I20B10B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjGrad_00R20B10B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjGrad_00X20B10B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjGrad_00I30B10B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjGrad_00R30B10B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjGrad_00X30B10B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjGrad_00J30B20B20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjGrad_00S30B20B20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjGrad_00Y30B20B20B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjGrad_00d30B10B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&texture_00I10B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&texture_00R10B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&texture_00X10B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&texture_00J20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&texture_00S20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&texture_00Y20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&texture_00K20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&texture_00T20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&texture_00Z20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&texture_00L20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&texture_00U20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&texture_00a20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureProj_00I20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureProj_00R20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureProj_00X20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureProj_00I30B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureProj_00R30B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureProj_00X30B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureProj_00J30B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureProj_00S30B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureProj_00Y30B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&texture_00d20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&texture_00e30B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureProj_00d30B00B),
+ Rule::Get<Spec::ESSL, 320, Shader::FRAGMENT, 0>(&texture_00k30B00B),
+ Rule::Get<Spec::ESSL, 310, Shader::FRAGMENT, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureExt_00k30B00B),
+ Rule::Get<Spec::ESSL, 310, Shader::FRAGMENT, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureExt_00k30B00B),
+ Rule::Get<Spec::ESSL, 320, Shader::FRAGMENT, 0>(&texture_00s30B00B),
+ Rule::Get<Spec::ESSL, 310, Shader::FRAGMENT, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureExt_00s30B00B),
+ Rule::Get<Spec::ESSL, 310, Shader::FRAGMENT, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureExt_00s30B00B),
+ Rule::Get<Spec::ESSL, 320, Shader::FRAGMENT, 0>(&texture_00x30B00B),
+ Rule::Get<Spec::ESSL, 310, Shader::FRAGMENT, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureExt_00x30B00B),
+ Rule::Get<Spec::ESSL, 310, Shader::FRAGMENT, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureExt_00x30B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(OES_EGL_image_external_essl3)>(
+ &texture_00M10B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(OES_EGL_image_external_essl3)>(
+ &textureProj_00M20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(OES_EGL_image_external_essl3)>(
+ &textureProj_00M30B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(EXT_YUV_target)>(&texture_00N10B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(EXT_YUV_target)>(&textureProj_00N20B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(EXT_YUV_target)>(&textureProj_00N30B00B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureOffset_00I10B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureOffset_00R10B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureOffset_00X10B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureOffset_00J20B20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureOffset_00S20B20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureOffset_00Y20B20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureOffset_00d20B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureOffset_00L20B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureOffset_00U20B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureOffset_00a20B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjOffset_00I20B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjOffset_00R20B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjOffset_00X20B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjOffset_00I30B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjOffset_00R30B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjOffset_00X30B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjOffset_00J30B20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjOffset_00S30B20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjOffset_00Y30B20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjOffset_00d30B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLodOffset_00I10B00B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLodOffset_00R10B00B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLodOffset_00X10B00B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLodOffset_00J20B00B20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLodOffset_00S20B00B20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLodOffset_00Y20B00B20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLodOffset_00d20B00B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLodOffset_00L20B00B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLodOffset_00U20B00B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureLodOffset_00a20B00B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjLodOffset_00I20B00B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjLodOffset_00R20B00B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjLodOffset_00X20B00B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjLodOffset_00I30B00B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjLodOffset_00R30B00B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjLodOffset_00X30B00B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjLodOffset_00J30B00B20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjLodOffset_00S30B00B20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjLodOffset_00Y30B00B20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjLodOffset_00d30B00B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texelFetchOffset_00I10D00D10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texelFetchOffset_00R10D00D10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texelFetchOffset_00X10D00D10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texelFetchOffset_00J20D00D20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texelFetchOffset_00S20D00D20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texelFetchOffset_00Y20D00D20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texelFetchOffset_00L20D00D10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texelFetchOffset_00U20D00D10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&texelFetchOffset_00a20D00D10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGradOffset_00I10B10B10B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGradOffset_00R10B10B10B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGradOffset_00X10B10B10B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGradOffset_00J20B20B20B20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGradOffset_00S20B20B20B20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGradOffset_00Y20B20B20B20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGradOffset_00d20B10B10B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGradOffset_00L20B10B10B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGradOffset_00U20B10B10B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGradOffset_00a20B10B10B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureGradOffset_00f30B10B10B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjGradOffset_00I20B10B10B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjGradOffset_00R20B10B10B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjGradOffset_00X20B10B10B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjGradOffset_00I30B10B10B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjGradOffset_00R30B10B10B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjGradOffset_00X30B10B10B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjGradOffset_00J30B20B20B20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjGradOffset_00S30B20B20B20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjGradOffset_00Y30B20B20B20D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&textureProjGradOffset_00d30B10B10B10D),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureOffset_00I10B10D00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureOffset_00R10B10D00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureOffset_00X10B10D00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureOffset_00J20B20D00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureOffset_00S20B20D00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureOffset_00Y20B20D00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureOffset_00d20B10D00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureOffset_00L20B10D00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureOffset_00U20B10D00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureOffset_00a20B10D00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureProjOffset_00I20B10D00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureProjOffset_00R20B10D00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureProjOffset_00X20B10D00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureProjOffset_00I30B10D00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureProjOffset_00R30B10D00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureProjOffset_00X30B10D00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureProjOffset_00J30B20D00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureProjOffset_00S30B20D00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureProjOffset_00Y30B20D00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&textureProjOffset_00d30B10D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00I10B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00R10B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00X10B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00I10B00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00R10B00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00X10B00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00L20B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00U20B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00a20B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00L20B00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00U20B00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00a20B00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00K20B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00T20B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00Z20B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00K20B00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00T20B00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00Z20B00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGather_00k30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureGatherExt_00k30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureGatherExt_00k30B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGather_00s30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureGatherExt_00s30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureGatherExt_00s30B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGather_00x30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureGatherExt_00x30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureGatherExt_00x30B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGather_00k30B00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureGatherExt_00k30B00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureGatherExt_00k30B00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGather_00s30B00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureGatherExt_00s30B00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureGatherExt_00s30B00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGather_00x30B00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureGatherExt_00x30B00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureGatherExt_00x30B00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGather_00l30B00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &textureGatherExt_00l30B00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &textureGatherExt_00l30B00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00d10B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00d10B00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00f20B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00f20B00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00e20B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGather_00e20B00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGatherOffset_00I10B10D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGatherOffset_00R10B10D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGatherOffset_00X10B10D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGatherOffset_00L20B10D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGatherOffset_00U20B10D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGatherOffset_00a20B10D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGatherOffset_00d10B00B10D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGatherOffset_00f20B00B10D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGatherOffset_00I10B10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGatherOffset_00R10B10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGatherOffset_00X10B10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGatherOffset_00L20B10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGatherOffset_00U20B10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&textureGatherOffset_00a20B10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGatherOffsets_00I10B10Dx4),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_gpu_shader5)>(
+ &textureGatherOffsetsExt_00I10B10Dx4),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGatherOffsets_00R10B10Dx4),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_gpu_shader5)>(
+ &textureGatherOffsetsExt_00R10B10Dx4),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGatherOffsets_00X10B10Dx4),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_gpu_shader5)>(
+ &textureGatherOffsetsExt_00X10B10Dx4),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGatherOffsets_00L20B10Dx4),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_gpu_shader5)>(
+ &textureGatherOffsetsExt_00L20B10Dx4),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGatherOffsets_00U20B10Dx4),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_gpu_shader5)>(
+ &textureGatherOffsetsExt_00U20B10Dx4),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGatherOffsets_00a20B10Dx4),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_gpu_shader5)>(
+ &textureGatherOffsetsExt_00a20B10Dx4),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGatherOffsets_00d10B00B10Dx4),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_gpu_shader5)>(
+ &textureGatherOffsetsExt_00d10B00B10Dx4),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGatherOffsets_00f20B00B10Dx4),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_gpu_shader5)>(
+ &textureGatherOffsetsExt_00f20B00B10Dx4),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGatherOffsets_00I10B10Dx400D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_gpu_shader5)>(
+ &textureGatherOffsetsExt_00I10B10Dx400D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGatherOffsets_00R10B10Dx400D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_gpu_shader5)>(
+ &textureGatherOffsetsExt_00R10B10Dx400D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGatherOffsets_00X10B10Dx400D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_gpu_shader5)>(
+ &textureGatherOffsetsExt_00X10B10Dx400D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGatherOffsets_00L20B10Dx400D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_gpu_shader5)>(
+ &textureGatherOffsetsExt_00L20B10Dx400D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGatherOffsets_00U20B10Dx400D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_gpu_shader5)>(
+ &textureGatherOffsetsExt_00U20B10Dx400D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&textureGatherOffsets_00a20B10Dx400D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_gpu_shader5)>(
+ &textureGatherOffsetsExt_00a20B10Dx400D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(EXT_YUV_target)>(&rgb_2_yuv_20B00H),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(EXT_YUV_target)>(&yuv_2_rgb_20B00H),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&dFdx_00B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(OES_standard_derivatives)>(&dFdxExt_00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&dFdx_10B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(OES_standard_derivatives)>(&dFdxExt_10B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&dFdx_20B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(OES_standard_derivatives)>(&dFdxExt_20B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&dFdx_30B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(OES_standard_derivatives)>(&dFdxExt_30B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&dFdy_00B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(OES_standard_derivatives)>(&dFdyExt_00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&dFdy_10B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(OES_standard_derivatives)>(&dFdyExt_10B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&dFdy_20B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(OES_standard_derivatives)>(&dFdyExt_20B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&dFdy_30B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(OES_standard_derivatives)>(&dFdyExt_30B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&fwidth_00B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(OES_standard_derivatives)>(
+ &fwidthExt_00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&fwidth_10B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(OES_standard_derivatives)>(
+ &fwidthExt_10B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&fwidth_20B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(OES_standard_derivatives)>(
+ &fwidthExt_20B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&fwidth_30B),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(OES_standard_derivatives)>(
+ &fwidthExt_30B),
+ Rule::Get<Spec::ESSL, 320, Shader::FRAGMENT, 0>(&interpolateAtCentroid_00B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(OES_shader_multisample_interpolation)>(
+ &interpolateAtCentroidExt_00B),
+ Rule::Get<Spec::ESSL, 320, Shader::FRAGMENT, 0>(&interpolateAtCentroid_10B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(OES_shader_multisample_interpolation)>(
+ &interpolateAtCentroidExt_10B),
+ Rule::Get<Spec::ESSL, 320, Shader::FRAGMENT, 0>(&interpolateAtCentroid_20B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(OES_shader_multisample_interpolation)>(
+ &interpolateAtCentroidExt_20B),
+ Rule::Get<Spec::ESSL, 320, Shader::FRAGMENT, 0>(&interpolateAtCentroid_30B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(OES_shader_multisample_interpolation)>(
+ &interpolateAtCentroidExt_30B),
+ Rule::Get<Spec::ESSL, 320, Shader::FRAGMENT, 0>(&interpolateAtSample_00B00D),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(OES_shader_multisample_interpolation)>(
+ &interpolateAtSampleExt_00B00D),
+ Rule::Get<Spec::ESSL, 320, Shader::FRAGMENT, 0>(&interpolateAtSample_10B00D),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(OES_shader_multisample_interpolation)>(
+ &interpolateAtSampleExt_10B00D),
+ Rule::Get<Spec::ESSL, 320, Shader::FRAGMENT, 0>(&interpolateAtSample_20B00D),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(OES_shader_multisample_interpolation)>(
+ &interpolateAtSampleExt_20B00D),
+ Rule::Get<Spec::ESSL, 320, Shader::FRAGMENT, 0>(&interpolateAtSample_30B00D),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(OES_shader_multisample_interpolation)>(
+ &interpolateAtSampleExt_30B00D),
+ Rule::Get<Spec::ESSL, 320, Shader::FRAGMENT, 0>(&interpolateAtOffset_00B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(OES_shader_multisample_interpolation)>(
+ &interpolateAtOffsetExt_00B10B),
+ Rule::Get<Spec::ESSL, 320, Shader::FRAGMENT, 0>(&interpolateAtOffset_10B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(OES_shader_multisample_interpolation)>(
+ &interpolateAtOffsetExt_10B10B),
+ Rule::Get<Spec::ESSL, 320, Shader::FRAGMENT, 0>(&interpolateAtOffset_20B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(OES_shader_multisample_interpolation)>(
+ &interpolateAtOffsetExt_20B10B),
+ Rule::Get<Spec::ESSL, 320, Shader::FRAGMENT, 0>(&interpolateAtOffset_30B10B),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(OES_shader_multisample_interpolation)>(
+ &interpolateAtOffsetExt_30B10B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&atomicCounter_00G),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&atomicCounterIncrement_00G),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&atomicCounterDecrement_00G),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&atomicAdd_00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&atomicAdd_00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&atomicMin_00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&atomicMin_00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&atomicMax_00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&atomicMax_00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&atomicAnd_00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&atomicAnd_00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&atomicOr_00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&atomicOr_00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&atomicXor_00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&atomicXor_00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&atomicExchange_00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&atomicExchange_00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&atomicCompSwap_00E00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&atomicCompSwap_00D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageSize_00z),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageSize_01K),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageSize_01V),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageSize_01A),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageSize_01L),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageSize_01W),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageSize_01B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageSize_01M),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageSize_01X),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageSize_01C),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageSize_01N),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageSize_01Y),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageSize_01H),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &imageSizeExt_01H),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &imageSizeExt_01H),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageSize_01S),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &imageSizeExt_01S),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &imageSizeExt_01S),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageSize_01d),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &imageSizeExt_01d),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &imageSizeExt_01d),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageSize_01J),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_buffer)>(&imageSizeExt_01J),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_buffer)>(&imageSizeExt_01J),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageSize_01U),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_buffer)>(&imageSizeExt_01U),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_buffer)>(&imageSizeExt_01U),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageSize_01f),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_buffer)>(&imageSizeExt_01f),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_buffer)>(&imageSizeExt_01f),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageStore_00z10D30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageStore_01K10D30D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageStore_01V10D30E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageStore_01A20D30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageStore_01L20D30D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageStore_01W20D30E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageStore_01B20D30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageStore_01M20D30D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageStore_01X20D30E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageStore_01C20D30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageStore_01N20D30D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageStore_01Y20D30E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageStore_01H20D30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &imageStoreExt_01H20D30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &imageStoreExt_01H20D30B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageStore_01S20D30D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &imageStoreExt_01S20D30D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &imageStoreExt_01S20D30D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageStore_01d20D30E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &imageStoreExt_01d20D30E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &imageStoreExt_01d20D30E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageStore_01J00D30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_buffer)>(
+ &imageStoreExt_01J00D30B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_buffer)>(
+ &imageStoreExt_01J00D30B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageStore_01U00D30D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_buffer)>(
+ &imageStoreExt_01U00D30D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_buffer)>(
+ &imageStoreExt_01U00D30D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageStore_01f00D30E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_buffer)>(
+ &imageStoreExt_01f00D30E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_buffer)>(
+ &imageStoreExt_01f00D30E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageLoad_00z10D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageLoad_01K10D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageLoad_01V10D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageLoad_01A20D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageLoad_01L20D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageLoad_01W20D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageLoad_01B20D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageLoad_01M20D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageLoad_01X20D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageLoad_01C20D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageLoad_01N20D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&imageLoad_01Y20D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageLoad_01H20D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &imageLoadExt_01H20D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &imageLoadExt_01H20D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageLoad_01S20D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &imageLoadExt_01S20D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &imageLoadExt_01S20D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageLoad_01d20D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_cube_map_array)>(
+ &imageLoadExt_01d20D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_cube_map_array)>(
+ &imageLoadExt_01d20D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageLoad_01J00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_buffer)>(&imageLoadExt_01J00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_buffer)>(&imageLoadExt_01J00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageLoad_01U00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_buffer)>(&imageLoadExt_01U00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_buffer)>(&imageLoadExt_01U00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageLoad_01f00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_texture_buffer)>(&imageLoadExt_01f00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_texture_buffer)>(&imageLoadExt_01f00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_00z10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_00z10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01K10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01K10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01V10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01V10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01A20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01A20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01L20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01L20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01W20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01W20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01C20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01C20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01N20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01N20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01Y20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01Y20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01J00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01J00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01U00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01U00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01f00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01f00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01B20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01B20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01M20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01M20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01X20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01X20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01H20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01H20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01S20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01S20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01d20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01d20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01O00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01O00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01Z00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01Z00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01E10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01E10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01P10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01P10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01a10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01a10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01I10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01I10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01T10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01T10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01e10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01e10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01F10D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01F10D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01Q10D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01Q10D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01b10D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01b10D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01G20D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01G20D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01R20D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01R20D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01c20D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01c20D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_00z10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_00z10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01K10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01K10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01V10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01V10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01A20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01A20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01L20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01L20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01W20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01W20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01C20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01C20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01N20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01N20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01Y20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01Y20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01J00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01J00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01U00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01U00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01f00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01f00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01B20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01B20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01M20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01M20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01X20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01X20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01H20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01H20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01S20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01S20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01d20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01d20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01O00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01O00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01Z00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01Z00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01E10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01E10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01P10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01P10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01a10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01a10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01I10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01I10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01T10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01T10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01e10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01e10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01F10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01F10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01Q10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01Q10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01b10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01b10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01G20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01G20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01R20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01R20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAdd_01c20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAddExt_01c20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_00z10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_00z10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01K10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01K10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01V10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01V10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01A20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01A20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01L20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01L20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01W20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01W20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01C20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01C20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01N20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01N20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01Y20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01Y20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01J00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01J00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01U00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01U00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01f00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01f00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01B20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01B20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01M20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01M20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01X20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01X20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01H20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01H20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01S20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01S20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01d20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01d20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01O00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01O00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01Z00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01Z00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01E10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01E10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01P10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01P10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01a10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01a10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01I10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01I10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01T10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01T10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01e10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01e10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01F10D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01F10D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01Q10D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01Q10D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01b10D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01b10D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01G20D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01G20D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01R20D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01R20D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01c20D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01c20D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_00z10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_00z10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01K10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01K10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01V10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01V10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01A20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01A20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01L20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01L20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01W20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01W20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01C20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01C20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01N20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01N20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01Y20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01Y20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01J00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01J00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01U00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01U00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01f00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01f00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01B20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01B20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01M20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01M20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01X20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01X20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01H20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01H20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01S20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01S20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01d20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01d20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01O00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01O00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01Z00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01Z00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01E10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01E10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01P10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01P10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01a10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01a10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01I10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01I10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01T10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01T10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01e10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01e10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01F10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01F10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01Q10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01Q10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01b10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01b10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01G20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01G20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01R20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01R20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMin_01c20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMinExt_01c20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_00z10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_00z10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01K10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01K10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01V10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01V10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01A20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01A20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01L20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01L20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01W20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01W20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01C20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01C20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01N20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01N20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01Y20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01Y20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01J00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01J00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01U00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01U00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01f00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01f00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01B20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01B20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01M20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01M20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01X20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01X20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01H20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01H20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01S20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01S20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01d20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01d20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01O00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01O00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01Z00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01Z00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01E10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01E10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01P10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01P10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01a10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01a10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01I10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01I10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01T10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01T10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01e10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01e10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01F10D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01F10D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01Q10D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01Q10D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01b10D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01b10D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01G20D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01G20D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01R20D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01R20D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01c20D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01c20D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_00z10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_00z10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01K10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01K10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01V10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01V10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01A20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01A20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01L20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01L20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01W20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01W20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01C20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01C20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01N20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01N20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01Y20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01Y20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01J00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01J00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01U00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01U00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01f00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01f00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01B20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01B20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01M20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01M20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01X20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01X20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01H20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01H20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01S20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01S20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01d20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01d20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01O00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01O00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01Z00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01Z00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01E10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01E10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01P10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01P10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01a10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01a10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01I10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01I10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01T10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01T10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01e10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01e10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01F10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01F10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01Q10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01Q10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01b10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01b10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01G20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01G20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01R20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01R20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicMax_01c20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicMaxExt_01c20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_00z10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_00z10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01K10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01K10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01V10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01V10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01A20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01A20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01L20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01L20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01W20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01W20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01C20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01C20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01N20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01N20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01Y20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01Y20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01J00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01J00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01U00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01U00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01f00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01f00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01B20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01B20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01M20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01M20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01X20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01X20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01H20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01H20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01S20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01S20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01d20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01d20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01O00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01O00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01Z00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01Z00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01E10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01E10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01P10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01P10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01a10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01a10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01I10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01I10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01T10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01T10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01e10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01e10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01F10D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01F10D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01Q10D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01Q10D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01b10D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01b10D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01G20D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01G20D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01R20D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01R20D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01c20D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01c20D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_00z10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_00z10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01K10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01K10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01V10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01V10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01A20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01A20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01L20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01L20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01W20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01W20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01C20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01C20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01N20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01N20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01Y20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01Y20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01J00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01J00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01U00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01U00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01f00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01f00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01B20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01B20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01M20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01M20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01X20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01X20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01H20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01H20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01S20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01S20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01d20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01d20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01O00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01O00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01Z00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01Z00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01E10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01E10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01P10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01P10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01a10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01a10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01I10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01I10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01T10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01T10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01e10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01e10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01F10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01F10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01Q10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01Q10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01b10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01b10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01G20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01G20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01R20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01R20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicAnd_01c20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicAndExt_01c20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_00z10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_00z10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01K10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01K10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01V10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01V10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01A20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01A20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01L20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01L20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01W20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01W20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01C20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01C20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01N20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01N20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01Y20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01Y20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01J00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01J00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01U00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01U00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01f00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01f00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01B20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01B20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01M20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01M20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01X20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01X20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01H20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01H20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01S20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01S20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01d20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01d20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01O00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01O00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01Z00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01Z00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01E10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01E10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01P10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01P10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01a10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01a10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01I10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01I10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01T10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01T10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01e10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01e10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01F10D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01F10D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01Q10D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01Q10D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01b10D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01b10D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01G20D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01G20D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01R20D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01R20D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01c20D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01c20D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_00z10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_00z10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01K10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01K10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01V10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01V10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01A20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01A20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01L20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01L20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01W20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01W20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01C20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01C20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01N20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01N20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01Y20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01Y20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01J00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01J00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01U00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01U00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01f00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01f00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01B20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01B20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01M20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01M20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01X20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01X20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01H20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01H20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01S20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01S20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01d20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01d20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01O00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01O00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01Z00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01Z00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01E10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01E10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01P10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01P10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01a10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01a10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01I10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01I10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01T10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01T10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01e10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01e10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01F10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01F10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01Q10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01Q10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01b10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01b10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01G20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01G20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01R20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01R20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicOr_01c20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicOrExt_01c20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_00z10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_00z10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01K10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01K10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01V10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01V10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01A20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01A20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01L20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01L20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01W20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01W20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01C20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01C20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01N20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01N20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01Y20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01Y20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01J00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01J00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01U00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01U00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01f00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01f00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01B20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01B20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01M20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01M20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01X20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01X20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01H20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01H20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01S20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01S20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01d20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01d20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01O00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01O00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01Z00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01Z00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01E10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01E10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01P10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01P10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01a10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01a10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01I10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01I10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01T10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01T10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01e10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01e10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01F10D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01F10D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01Q10D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01Q10D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01b10D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01b10D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01G20D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01G20D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01R20D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01R20D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01c20D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01c20D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_00z10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_00z10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01K10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01K10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01V10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01V10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01A20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01A20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01L20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01L20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01W20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01W20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01C20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01C20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01N20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01N20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01Y20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01Y20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01J00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01J00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01U00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01U00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01f00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01f00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01B20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01B20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01M20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01M20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01X20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01X20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01H20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01H20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01S20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01S20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01d20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01d20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01O00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01O00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01Z00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01Z00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01E10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01E10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01P10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01P10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01a10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01a10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01I10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01I10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01T10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01T10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01e10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01e10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01F10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01F10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01Q10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01Q10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01b10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01b10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01G20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01G20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01R20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01R20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicXor_01c20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicXorExt_01c20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_00z10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_00z10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01K10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01K10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01V10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01V10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01A20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01A20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01L20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01L20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01W20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01W20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01C20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01C20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01N20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01N20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01Y20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01Y20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01J00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01J00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01U00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01U00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01f00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01f00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01B20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01B20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01M20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01M20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01X20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01X20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01H20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01H20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01S20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01S20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01d20D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01d20D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01O00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01O00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01Z00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01Z00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01E10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01E10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01P10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01P10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01a10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01a10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01I10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01I10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01T10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01T10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01e10D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01e10D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01F10D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01F10D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01Q10D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01Q10D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01b10D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01b10D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01G20D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01G20D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01R20D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01R20D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01c20D00D00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01c20D00D00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_00z10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_00z10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01K10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01K10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01V10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01V10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01A20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01A20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01L20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01L20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01W20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01W20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01C20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01C20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01N20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01N20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01Y20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01Y20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01J00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01J00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01U00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01U00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01f00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01f00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01B20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01B20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01M20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01M20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01X20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01X20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01H20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01H20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01S20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01S20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01d20D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01d20D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01O00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01O00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01Z00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01Z00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01E10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01E10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01P10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01P10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01a10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01a10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01I10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01I10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01T10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01T10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01e10D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01e10D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01F10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01F10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01Q10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01Q10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01b10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01b10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01G20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01G20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01R20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01R20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01c20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01c20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_00z10D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_00z10D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01K10D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01K10D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01V10D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01V10D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01A20D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01A20D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01L20D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01L20D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01W20D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01W20D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01C20D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01C20D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01N20D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01N20D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01Y20D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01Y20D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01J00D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01J00D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01U00D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01U00D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01f00D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01f00D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01B20D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01B20D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01M20D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01M20D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01X20D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01X20D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01H20D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01H20D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01S20D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01S20D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01d20D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01d20D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01D00D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01D00D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01O00D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01O00D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01Z00D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01Z00D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01E10D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01E10D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01P10D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01P10D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01a10D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01a10D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01I10D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01I10D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01T10D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01T10D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01e10D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01e10D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01F10D00D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01F10D00D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01Q10D00D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01Q10D00D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01b10D00D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01b10D00D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01G20D00D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01G20D00D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01R20D00D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01R20D00D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicExchange_01c20D00D00B),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicExchangeExt_01c20D00D00B),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_00z10D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_00z10D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01K10D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01K10D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01V10D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01V10D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01A20D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01A20D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01L20D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01L20D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01W20D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01W20D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01C20D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01C20D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01N20D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01N20D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01Y20D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01Y20D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01J00D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01J00D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01U00D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01U00D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01f00D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01f00D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01B20D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01B20D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01M20D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01M20D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01X20D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01X20D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01H20D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01H20D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01S20D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01S20D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01d20D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01d20D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01D00D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01D00D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01O00D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01O00D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01Z00D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01Z00D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01E10D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01E10D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01P10D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01P10D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01a10D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01a10D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01I10D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01I10D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01T10D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01T10D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01e10D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01e10D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01F10D00D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01F10D00D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01Q10D00D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01Q10D00D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01b10D00D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01b10D00D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01G20D00D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01G20D00D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01R20D00D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01R20D00D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01c20D00D00E00E),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01c20D00D00E00E),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_00z10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_00z10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01K10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01K10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01V10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01V10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01A20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01A20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01L20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01L20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01W20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01W20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01C20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01C20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01N20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01N20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01Y20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01Y20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01J00D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01J00D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01U00D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01U00D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01f00D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01f00D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01B20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01B20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01M20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01M20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01X20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01X20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01H20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01H20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01S20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01S20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01d20D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01d20D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01D00D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01D00D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01O00D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01O00D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01Z00D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01Z00D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01E10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01E10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01P10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01P10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01a10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01a10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01I10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01I10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01T10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01T10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01e10D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01e10D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01F10D00D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01F10D00D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01Q10D00D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01Q10D00D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01b10D00D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01b10D00D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01G20D00D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01G20D00D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01R20D00D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01R20D00D00D00D),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&imageAtomicCompSwap_01c20D00D00D00D),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_shader_image_atomic)>(
+ &imageAtomicCompSwapExt_01c20D00D00D00D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(ANGLE_shader_pixel_local_storage)>(
+ &pixelLocalLoadANGLE_01g),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(ANGLE_shader_pixel_local_storage)>(
+ &pixelLocalLoadANGLE_01h),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(ANGLE_shader_pixel_local_storage)>(
+ &pixelLocalLoadANGLE_01i),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(ANGLE_shader_pixel_local_storage)>(
+ &pixelLocalStoreANGLE_01g30B),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(ANGLE_shader_pixel_local_storage)>(
+ &pixelLocalStoreANGLE_01h30D),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(ANGLE_shader_pixel_local_storage)>(
+ &pixelLocalStoreANGLE_01i30E),
+ Rule::Get<Spec::ESSL, kESSLInternalBackendBuiltIns, Shader::ALL, 0>(
+ &beginInvocationInterlockNV_),
+ Rule::Get<Spec::ESSL, kESSLInternalBackendBuiltIns, Shader::ALL, 0>(&endInvocationInterlockNV_),
+ Rule::Get<Spec::ESSL, kESSLInternalBackendBuiltIns, Shader::ALL, 0>(
+ &beginFragmentShaderOrderingINTEL_),
+ Rule::Get<Spec::ESSL, kESSLInternalBackendBuiltIns, Shader::ALL, 0>(
+ &beginInvocationInterlockARB_),
+ Rule::Get<Spec::ESSL, kESSLInternalBackendBuiltIns, Shader::ALL, 0>(
+ &endInvocationInterlockARB_),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&memoryBarrier_),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&memoryBarrierAtomicCounter_),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&memoryBarrierBuffer_),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&memoryBarrierImage_),
+ Rule::Get<Spec::ESSL, 310, Shader::COMPUTE, 0>(&barrier_),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_CONTROL_EXT, 0>(&barrierTCSES3_2_),
+ Rule::Get<Spec::ESSL, 310, Shader::TESS_CONTROL_EXT, EXT_INDEX(EXT_tessellation_shader)>(
+ &barrierTCS_),
+ Rule::Get<Spec::ESSL, 310, Shader::COMPUTE, 0>(&memoryBarrierShared_),
+ Rule::Get<Spec::ESSL, 310, Shader::COMPUTE, 0>(&groupMemoryBarrier_),
+ Rule::Get<Spec::ESSL, 320, Shader::GEOMETRY, 0>(&EmitVertexES3_2_),
+ Rule::Get<Spec::ESSL, 310, Shader::GEOMETRY, EXT_INDEX(EXT_geometry_shader)>(&EmitVertex_),
+ Rule::Get<Spec::ESSL, 310, Shader::GEOMETRY, EXT_INDEX(OES_geometry_shader)>(&EmitVertex_),
+ Rule::Get<Spec::ESSL, 320, Shader::GEOMETRY, 0>(&EndPrimitiveES3_2_),
+ Rule::Get<Spec::ESSL, 310, Shader::GEOMETRY, EXT_INDEX(EXT_geometry_shader)>(&EndPrimitive_),
+ Rule::Get<Spec::ESSL, 310, Shader::GEOMETRY, EXT_INDEX(OES_geometry_shader)>(&EndPrimitive_),
+ Rule::Get<Spec::ESSL, kESSLInternalBackendBuiltIns, Shader::ALL, 0>(&subpassLoad_01j),
+ Rule::Get<Spec::ESSL, kESSLInternalBackendBuiltIns, Shader::ALL, 0>(&subpassLoad_01k),
+ Rule::Get<Spec::ESSL, kESSLInternalBackendBuiltIns, Shader::ALL, 0>(&subpassLoad_01l),
+ Rule::Get<Spec::ESSL, kESSLInternalBackendBuiltIns, Shader::ALL, 0>(&subpassLoad_01m00D),
+ Rule::Get<Spec::ESSL, kESSLInternalBackendBuiltIns, Shader::ALL, 0>(&subpassLoad_01n00D),
+ Rule::Get<Spec::ESSL, kESSLInternalBackendBuiltIns, Shader::ALL, 0>(&subpassLoad_01o00D),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&TableBase::m_gl_DepthRangeParameters),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&TableBase::m_gl_DepthRange),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&BuiltInVariable::kgl_NumSamplesES3_2),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(OES_sample_variables)>(
+ &BuiltInVariable::kgl_NumSamples),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&TableBase::m_gl_MaxVertexAttribs),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&TableBase::m_gl_MaxVertexUniformVectors),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&TableBase::m_gl_MaxVertexTextureImageUnits),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&TableBase::m_gl_MaxCombinedTextureImageUnits),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&TableBase::m_gl_MaxTextureImageUnits),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&TableBase::m_gl_MaxFragmentUniformVectors),
+ Rule::Get<Spec::ESSL, 100, Shader::ALL, 0>(&TableBase::m_gl_MaxVaryingVectors),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, 0>(&TableBase::m_gl_MaxDrawBuffers),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, EXT_INDEX(EXT_blend_func_extended)>(
+ &TableBase::m_gl_MaxDualSourceDrawBuffersEXT),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&TableBase::m_gl_MaxVertexOutputVectors),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&TableBase::m_gl_MaxFragmentInputVectors),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&TableBase::m_gl_MinProgramTexelOffset),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, 0>(&TableBase::m_gl_MaxProgramTexelOffset),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&TableBase::m_gl_MaxImageUnits),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&TableBase::m_gl_MaxVertexImageUniforms),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&TableBase::m_gl_MaxFragmentImageUniforms),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&TableBase::m_gl_MaxComputeImageUniforms),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&TableBase::m_gl_MaxCombinedImageUniforms),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&TableBase::m_gl_MaxCombinedShaderOutputResources),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&TableBase::m_gl_MaxComputeWorkGroupCount),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&TableBase::m_gl_MaxComputeWorkGroupSize),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&TableBase::m_gl_MaxComputeUniformComponents),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&TableBase::m_gl_MaxComputeTextureImageUnits),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&TableBase::m_gl_MaxComputeAtomicCounters),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&TableBase::m_gl_MaxComputeAtomicCounterBuffers),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&TableBase::m_gl_MaxVertexAtomicCounters),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&TableBase::m_gl_MaxFragmentAtomicCounters),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&TableBase::m_gl_MaxCombinedAtomicCounters),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&TableBase::m_gl_MaxAtomicCounterBindings),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&TableBase::m_gl_MaxVertexAtomicCounterBuffers),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&TableBase::m_gl_MaxFragmentAtomicCounterBuffers),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&TableBase::m_gl_MaxCombinedAtomicCounterBuffers),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, 0>(&TableBase::m_gl_MaxAtomicCounterBufferSize),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&TableBase::m_gl_MaxGeometryInputComponentsES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_geometry_shader)>(
+ &TableBase::m_gl_MaxGeometryInputComponents),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_geometry_shader)>(
+ &TableBase::m_gl_MaxGeometryInputComponents),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&TableBase::m_gl_MaxGeometryOutputComponentsES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_geometry_shader)>(
+ &TableBase::m_gl_MaxGeometryOutputComponents),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_geometry_shader)>(
+ &TableBase::m_gl_MaxGeometryOutputComponents),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&TableBase::m_gl_MaxGeometryImageUniformsES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_geometry_shader)>(
+ &TableBase::m_gl_MaxGeometryImageUniforms),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_geometry_shader)>(
+ &TableBase::m_gl_MaxGeometryImageUniforms),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&TableBase::m_gl_MaxGeometryTextureImageUnitsES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_geometry_shader)>(
+ &TableBase::m_gl_MaxGeometryTextureImageUnits),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_geometry_shader)>(
+ &TableBase::m_gl_MaxGeometryTextureImageUnits),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&TableBase::m_gl_MaxGeometryOutputVerticesES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_geometry_shader)>(
+ &TableBase::m_gl_MaxGeometryOutputVertices),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_geometry_shader)>(
+ &TableBase::m_gl_MaxGeometryOutputVertices),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(
+ &TableBase::m_gl_MaxGeometryTotalOutputComponentsES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_geometry_shader)>(
+ &TableBase::m_gl_MaxGeometryTotalOutputComponents),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_geometry_shader)>(
+ &TableBase::m_gl_MaxGeometryTotalOutputComponents),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&TableBase::m_gl_MaxGeometryUniformComponentsES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_geometry_shader)>(
+ &TableBase::m_gl_MaxGeometryUniformComponents),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_geometry_shader)>(
+ &TableBase::m_gl_MaxGeometryUniformComponents),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&TableBase::m_gl_MaxGeometryAtomicCountersES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_geometry_shader)>(
+ &TableBase::m_gl_MaxGeometryAtomicCounters),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_geometry_shader)>(
+ &TableBase::m_gl_MaxGeometryAtomicCounters),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(
+ &TableBase::m_gl_MaxGeometryAtomicCounterBuffersES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_geometry_shader)>(
+ &TableBase::m_gl_MaxGeometryAtomicCounterBuffers),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(OES_geometry_shader)>(
+ &TableBase::m_gl_MaxGeometryAtomicCounterBuffers),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&TableBase::m_gl_MaxTessControlInputComponentsES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_MaxTessControlInputComponents),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(
+ &TableBase::m_gl_MaxTessControlOutputComponentsES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_MaxTessControlOutputComponents),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(
+ &TableBase::m_gl_MaxTessControlTextureImageUnitsES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_MaxTessControlTextureImageUnits),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(
+ &TableBase::m_gl_MaxTessControlUniformComponentsES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_MaxTessControlUniformComponents),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(
+ &TableBase::m_gl_MaxTessControlTotalOutputComponentsES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_MaxTessControlTotalOutputComponents),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&TableBase::m_gl_MaxTessControlImageUniformsES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_MaxTessControlImageUniforms),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&TableBase::m_gl_MaxTessControlAtomicCountersES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_MaxTessControlAtomicCounters),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(
+ &TableBase::m_gl_MaxTessControlAtomicCounterBuffersES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_MaxTessControlAtomicCounterBuffers),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&TableBase::m_gl_MaxTessPatchComponentsES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_MaxTessPatchComponents),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&TableBase::m_gl_MaxPatchVerticesES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_MaxPatchVertices),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&TableBase::m_gl_MaxTessGenLevelES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_MaxTessGenLevel),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(
+ &TableBase::m_gl_MaxTessEvaluationInputComponentsES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_MaxTessEvaluationInputComponents),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(
+ &TableBase::m_gl_MaxTessEvaluationOutputComponentsES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_MaxTessEvaluationOutputComponents),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(
+ &TableBase::m_gl_MaxTessEvaluationTextureImageUnitsES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_MaxTessEvaluationTextureImageUnits),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(
+ &TableBase::m_gl_MaxTessEvaluationUniformComponentsES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_MaxTessEvaluationUniformComponents),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(
+ &TableBase::m_gl_MaxTessEvaluationImageUniformsES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_MaxTessEvaluationImageUniforms),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(
+ &TableBase::m_gl_MaxTessEvaluationAtomicCountersES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_MaxTessEvaluationAtomicCounters),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(
+ &TableBase::m_gl_MaxTessEvaluationAtomicCounterBuffersES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::ALL, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_MaxTessEvaluationAtomicCounterBuffers),
+ Rule::Get<Spec::ESSL, 320, Shader::ALL, 0>(&TableBase::m_gl_MaxSamplesES3_2),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(OES_sample_variables)>(
+ &TableBase::m_gl_MaxSamples),
+ Rule::Get<Spec::ESSL, 0, Shader::ALL, EXT_INDEX(APPLE_clip_distance)>(
+ &TableBase::m_gl_MaxClipDistancesAPPLE),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(EXT_clip_cull_distance)>(
+ &TableBase::m_gl_MaxCullDistancesEXT),
+ Rule::Get<Spec::ESSL, 300, Shader::ALL, EXT_INDEX(EXT_clip_cull_distance)>(
+ &TableBase::m_gl_MaxCombinedClipAndCullDistancesEXT),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, 0>(&BuiltInVariable::kgl_FragCoord),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&BuiltInVariable::kgl_FragCoord300),
+ Rule::Get<Spec::ESSL, 0, Shader::FRAGMENT, 0>(&BuiltInVariable::kgl_FrontFacing),
+ Rule::Get<Spec::ESSL, 0, Shader::FRAGMENT, 0>(&BuiltInVariable::kgl_PointCoord),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, 0>(&BuiltInVariable::kgl_FragColor),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, 0>(&TableBase::m_gl_FragData),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, 0>(&BuiltInVariable::kgl_FragDepth),
+ Rule::Get<Spec::ESSL, 310, Shader::FRAGMENT, 0>(&BuiltInVariable::kgl_HelperInvocation),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(EXT_blend_func_extended)>(
+ &BuiltInVariable::kgl_SecondaryFragColorEXT),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(EXT_blend_func_extended)>(
+ &TableBase::m_gl_SecondaryFragDataEXT),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(EXT_frag_depth)>(
+ &TableBase::m_gl_FragDepthEXT),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(EXT_shader_framebuffer_fetch)>(
+ &TableBase::m_gl_LastFragData),
+ Rule::Get<Spec::ESSL,
+ 100,
+ Shader::FRAGMENT,
+ EXT_INDEX(EXT_shader_framebuffer_fetch_non_coherent)>(&TableBase::m_gl_LastFragData),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(NV_shader_framebuffer_fetch)>(
+ &TableBase::m_gl_LastFragDataNV),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(NV_shader_framebuffer_fetch)>(
+ &BuiltInVariable::kgl_LastFragColor),
+ Rule::Get<Spec::ESSL, 100, Shader::FRAGMENT, EXT_INDEX(ARM_shader_framebuffer_fetch)>(
+ &BuiltInVariable::kgl_LastFragColorARM),
+ Rule::Get<Spec::ESSL, 320, Shader::FRAGMENT, 0>(&BuiltInVariable::kgl_PrimitiveIDES3_2),
+ Rule::Get<Spec::ESSL, 320, Shader::GEOMETRY_EXT, 0>(&BuiltInVariable::kgl_PrimitiveIDGSES3_2),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_CONTROL_EXT, 0>(
+ &BuiltInVariable::kgl_PrimitiveIDTCSES3_2),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_EVALUATION_EXT, 0>(
+ &BuiltInVariable::kgl_PrimitiveIDTESES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::FRAGMENT, EXT_INDEX(EXT_geometry_shader)>(
+ &BuiltInVariable::kgl_PrimitiveID),
+ Rule::Get<Spec::ESSL, 310, Shader::FRAGMENT, EXT_INDEX(OES_geometry_shader)>(
+ &BuiltInVariable::kgl_PrimitiveID),
+ Rule::Get<Spec::ESSL, 310, Shader::GEOMETRY_EXT, EXT_INDEX(EXT_geometry_shader)>(
+ &BuiltInVariable::kgl_PrimitiveIDGS),
+ Rule::Get<Spec::ESSL, 310, Shader::GEOMETRY_EXT, EXT_INDEX(OES_geometry_shader)>(
+ &BuiltInVariable::kgl_PrimitiveIDGS),
+ Rule::Get<Spec::ESSL, 310, Shader::TESS_CONTROL_EXT, EXT_INDEX(EXT_tessellation_shader)>(
+ &BuiltInVariable::kgl_PrimitiveIDTCS),
+ Rule::Get<Spec::ESSL, 310, Shader::TESS_EVALUATION_EXT, EXT_INDEX(EXT_tessellation_shader)>(
+ &BuiltInVariable::kgl_PrimitiveIDTES),
+ Rule::Get<Spec::ESSL, 320, Shader::FRAGMENT, 0>(&BuiltInVariable::kgl_LayerES3_2),
+ Rule::Get<Spec::ESSL, 320, Shader::GEOMETRY_EXT, 0>(&BuiltInVariable::kgl_LayerGSES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::FRAGMENT, EXT_INDEX(EXT_geometry_shader)>(
+ &BuiltInVariable::kgl_Layer),
+ Rule::Get<Spec::ESSL, 310, Shader::FRAGMENT, EXT_INDEX(OES_geometry_shader)>(
+ &BuiltInVariable::kgl_Layer),
+ Rule::Get<Spec::ESSL, 310, Shader::GEOMETRY_EXT, EXT_INDEX(EXT_geometry_shader)>(
+ &BuiltInVariable::kgl_LayerGS),
+ Rule::Get<Spec::ESSL, 310, Shader::GEOMETRY_EXT, EXT_INDEX(OES_geometry_shader)>(
+ &BuiltInVariable::kgl_LayerGS),
+ Rule::Get<Spec::ESSL, 320, Shader::FRAGMENT, 0>(&BuiltInVariable::kgl_SampleIDES3_2),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(OES_sample_variables)>(
+ &BuiltInVariable::kgl_SampleID),
+ Rule::Get<Spec::ESSL, 320, Shader::FRAGMENT, 0>(&BuiltInVariable::kgl_SamplePositionES3_2),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(OES_sample_variables)>(
+ &BuiltInVariable::kgl_SamplePosition),
+ Rule::Get<Spec::ESSL, 320, Shader::FRAGMENT, 0>(&TableBase::m_gl_SampleMaskInES3_2),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(OES_sample_variables)>(
+ &TableBase::m_gl_SampleMaskIn),
+ Rule::Get<Spec::ESSL, 320, Shader::FRAGMENT, 0>(&TableBase::m_gl_SampleMaskES3_2),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(OES_sample_variables)>(
+ &TableBase::m_gl_SampleMask),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(EXT_clip_cull_distance)>(
+ &TableBase::m_gl_CullDistance),
+ Rule::Get<Spec::ESSL, 300, Shader::VERTEX, EXT_INDEX(EXT_clip_cull_distance)>(
+ &TableBase::m_gl_CullDistanceEXT),
+ Rule::Get<Spec::ESSL, 300, Shader::FRAGMENT, EXT_INDEX(EXT_clip_cull_distance)>(
+ &TableBase::m_gl_ClipDistance),
+ Rule::Get<Spec::ESSL, 0, Shader::VERTEX, EXT_INDEX(APPLE_clip_distance)>(
+ &TableBase::m_gl_ClipDistanceAPPLE),
+ Rule::Get<Spec::ESSL, 0, Shader::VERTEX, 0>(&BuiltInVariable::kgl_Position),
+ Rule::Get<Spec::ESSL, 320, Shader::GEOMETRY_EXT, 0>(&TableBase::m_gl_PositionGSES3_2),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_CONTROL_EXT, 0>(&TableBase::m_gl_PositionTCSES3_2),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_EVALUATION_EXT, 0>(&TableBase::m_gl_PositionTESES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::GEOMETRY_EXT, EXT_INDEX(EXT_geometry_shader)>(
+ &TableBase::m_gl_PositionGS),
+ Rule::Get<Spec::ESSL, 310, Shader::GEOMETRY_EXT, EXT_INDEX(OES_geometry_shader)>(
+ &TableBase::m_gl_PositionGS),
+ Rule::Get<Spec::ESSL, 310, Shader::TESS_CONTROL_EXT, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_PositionTCS),
+ Rule::Get<Spec::ESSL, 310, Shader::TESS_EVALUATION_EXT, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_PositionTES),
+ Rule::Get<Spec::ESSL, 100, Shader::VERTEX, 0>(&BuiltInVariable::kgl_PointSize),
+ Rule::Get<Spec::ESSL, 300, Shader::VERTEX, 0>(&BuiltInVariable::kgl_PointSize300),
+ Rule::Get<Spec::ESSL, 300, Shader::VERTEX, 0>(&BuiltInVariable::kgl_InstanceID),
+ Rule::Get<Spec::ESSL, 300, Shader::VERTEX, 0>(&BuiltInVariable::kgl_VertexID),
+ Rule::Get<Spec::ESSL, 0, Shader::VERTEX, EXT_INDEX(ANGLE_multi_draw)>(
+ &BuiltInVariable::kgl_DrawID),
+ Rule::Get<Spec::ESSL,
+ 300,
+ Shader::VERTEX,
+ EXT_INDEX(ANGLE_base_vertex_base_instance_shader_builtin)>(
+ &BuiltInVariable::kgl_BaseVertex),
+ Rule::Get<Spec::ESSL,
+ 300,
+ Shader::VERTEX,
+ EXT_INDEX(ANGLE_base_vertex_base_instance_shader_builtin)>(
+ &BuiltInVariable::kgl_BaseInstance),
+ Rule::Get<Spec::ESSL,
+ 0,
+ Shader::VERTEX,
+ EXT_INDEX(ANGLE_base_vertex_base_instance_shader_builtin)>(
+ &BuiltInVariable::kangle_BaseVertex),
+ Rule::Get<Spec::ESSL,
+ 0,
+ Shader::VERTEX,
+ EXT_INDEX(ANGLE_base_vertex_base_instance_shader_builtin)>(
+ &BuiltInVariable::kangle_BaseInstance),
+ Rule::Get<Spec::ESSL, 310, Shader::COMPUTE, 0>(&BuiltInVariable::kgl_NumWorkGroups),
+ Rule::Get<Spec::ESSL, 310, Shader::COMPUTE, 0>(&BuiltInVariable::kgl_WorkGroupSize),
+ Rule::Get<Spec::ESSL, 310, Shader::COMPUTE, 0>(&BuiltInVariable::kgl_WorkGroupID),
+ Rule::Get<Spec::ESSL, 310, Shader::COMPUTE, 0>(&BuiltInVariable::kgl_LocalInvocationID),
+ Rule::Get<Spec::ESSL, 310, Shader::COMPUTE, 0>(&BuiltInVariable::kgl_GlobalInvocationID),
+ Rule::Get<Spec::ESSL, 310, Shader::COMPUTE, 0>(&BuiltInVariable::kgl_LocalInvocationIndex),
+ Rule::Get<Spec::ESSL, 320, Shader::GEOMETRY_EXT, 0>(&BuiltInVariable::kgl_PrimitiveIDInES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::GEOMETRY_EXT, EXT_INDEX(EXT_geometry_shader)>(
+ &BuiltInVariable::kgl_PrimitiveIDIn),
+ Rule::Get<Spec::ESSL, 310, Shader::GEOMETRY_EXT, EXT_INDEX(OES_geometry_shader)>(
+ &BuiltInVariable::kgl_PrimitiveIDIn),
+ Rule::Get<Spec::ESSL, 320, Shader::GEOMETRY_EXT, 0>(&BuiltInVariable::kgl_InvocationIDES3_2),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_CONTROL_EXT, 0>(
+ &BuiltInVariable::kgl_InvocationIDTCSES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::GEOMETRY_EXT, EXT_INDEX(EXT_geometry_shader)>(
+ &BuiltInVariable::kgl_InvocationID),
+ Rule::Get<Spec::ESSL, 310, Shader::GEOMETRY_EXT, EXT_INDEX(OES_geometry_shader)>(
+ &BuiltInVariable::kgl_InvocationID),
+ Rule::Get<Spec::ESSL, 310, Shader::TESS_CONTROL_EXT, EXT_INDEX(EXT_tessellation_shader)>(
+ &BuiltInVariable::kgl_InvocationIDTCS),
+ Rule::Get<Spec::ESSL, 320, Shader::GEOMETRY_EXT, 0>(&TableBase::m_gl_PerVertexES3_2),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_CONTROL_EXT, 0>(&TableBase::m_gl_PerVertexTCSES3_2),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_EVALUATION_EXT, 0>(&TableBase::m_gl_PerVertexTESES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::GEOMETRY_EXT, EXT_INDEX(EXT_geometry_shader)>(
+ &TableBase::m_gl_PerVertex),
+ Rule::Get<Spec::ESSL, 310, Shader::GEOMETRY_EXT, EXT_INDEX(OES_geometry_shader)>(
+ &TableBase::m_gl_PerVertex),
+ Rule::Get<Spec::ESSL, 310, Shader::TESS_CONTROL_EXT, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_PerVertexTCS),
+ Rule::Get<Spec::ESSL, 310, Shader::TESS_EVALUATION_EXT, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_PerVertexTES),
+ Rule::Get<Spec::ESSL, 320, Shader::GEOMETRY_EXT, 0>(&TableBase::m_gl_inES3_2),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_CONTROL_EXT, 0>(&TableBase::m_gl_inTCSES3_2),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_EVALUATION_EXT, 0>(&TableBase::m_gl_inTESES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::GEOMETRY_EXT, EXT_INDEX(EXT_geometry_shader)>(
+ &TableBase::m_gl_in),
+ Rule::Get<Spec::ESSL, 310, Shader::GEOMETRY_EXT, EXT_INDEX(OES_geometry_shader)>(
+ &TableBase::m_gl_in),
+ Rule::Get<Spec::ESSL, 310, Shader::TESS_CONTROL_EXT, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_inTCS),
+ Rule::Get<Spec::ESSL, 310, Shader::TESS_EVALUATION_EXT, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_inTES),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_CONTROL_EXT, 0>(
+ &BuiltInVariable::kgl_PatchVerticesInTCSES3_2),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_EVALUATION_EXT, 0>(
+ &BuiltInVariable::kgl_PatchVerticesInTESES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::TESS_CONTROL_EXT, EXT_INDEX(EXT_tessellation_shader)>(
+ &BuiltInVariable::kgl_PatchVerticesInTCS),
+ Rule::Get<Spec::ESSL, 310, Shader::TESS_EVALUATION_EXT, EXT_INDEX(EXT_tessellation_shader)>(
+ &BuiltInVariable::kgl_PatchVerticesInTES),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_CONTROL_EXT, 0>(
+ &TableBase::m_gl_TessLevelOuterTCSES3_2),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_EVALUATION_EXT, 0>(
+ &TableBase::m_gl_TessLevelOuterTESES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::TESS_CONTROL_EXT, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_TessLevelOuterTCS),
+ Rule::Get<Spec::ESSL, 310, Shader::TESS_EVALUATION_EXT, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_TessLevelOuterTES),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_CONTROL_EXT, 0>(
+ &TableBase::m_gl_TessLevelInnerTCSES3_2),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_EVALUATION_EXT, 0>(
+ &TableBase::m_gl_TessLevelInnerTESES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::TESS_CONTROL_EXT, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_TessLevelInnerTCS),
+ Rule::Get<Spec::ESSL, 310, Shader::TESS_EVALUATION_EXT, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_TessLevelInnerTES),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_CONTROL_EXT, 0>(&TableBase::m_gl_outTCSES3_2),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_EVALUATION_EXT, 0>(&TableBase::m_gl_outTESES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::TESS_CONTROL_EXT, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_outTCS),
+ Rule::Get<Spec::ESSL, 310, Shader::TESS_EVALUATION_EXT, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_outTES),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_CONTROL_EXT, 0>(&TableBase::m_gl_BoundingBoxTCSES3_2),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_CONTROL_EXT, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_BoundingBoxTCS),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_CONTROL_EXT, 0>(
+ &TableBase::m_gl_BoundingBoxEXTTCSES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::TESS_CONTROL_EXT, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_BoundingBoxEXTTCS),
+ Rule::Get<Spec::ESSL, 320, Shader::TESS_CONTROL_EXT, 0>(
+ &TableBase::m_gl_BoundingBoxOESTCSES3_2),
+ Rule::Get<Spec::ESSL, 310, Shader::TESS_CONTROL_EXT, EXT_INDEX(EXT_tessellation_shader)>(
+ &TableBase::m_gl_BoundingBoxOESTCS),
+ Rule::Get<Spec::ESSL, 310, Shader::TESS_EVALUATION_EXT, 0>(&BuiltInVariable::kgl_TessCoord),
+ Rule::Get<Spec::ESSL, 300, Shader::NOT_COMPUTE, EXT_INDEX(OVR_multiview)>(
+ &BuiltInVariable::kgl_ViewID_OVR)};
+
+// Flat array of all mangled names.
+constexpr const char *kMangledNames[] = {"radians(00B",
+ "radians(10B",
+ "radians(20B",
+ "radians(30B",
+ "degrees(00B",
+ "degrees(10B",
+ "degrees(20B",
+ "degrees(30B",
+ "sin(00B",
+ "sin(10B",
+ "sin(20B",
+ "sin(30B",
+ "cos(00B",
+ "cos(10B",
+ "cos(20B",
+ "cos(30B",
+ "tan(00B",
+ "tan(10B",
+ "tan(20B",
+ "tan(30B",
+ "asin(00B",
+ "asin(10B",
+ "asin(20B",
+ "asin(30B",
+ "acos(00B",
+ "acos(10B",
+ "acos(20B",
+ "acos(30B",
+ "atan(00B00B",
+ "atan(10B10B",
+ "atan(20B20B",
+ "atan(30B30B",
+ "atan(00B",
+ "atan(10B",
+ "atan(20B",
+ "atan(30B",
+ "sinh(00B",
+ "sinh(10B",
+ "sinh(20B",
+ "sinh(30B",
+ "cosh(00B",
+ "cosh(10B",
+ "cosh(20B",
+ "cosh(30B",
+ "tanh(00B",
+ "tanh(10B",
+ "tanh(20B",
+ "tanh(30B",
+ "asinh(00B",
+ "asinh(10B",
+ "asinh(20B",
+ "asinh(30B",
+ "acosh(00B",
+ "acosh(10B",
+ "acosh(20B",
+ "acosh(30B",
+ "atanh(00B",
+ "atanh(10B",
+ "atanh(20B",
+ "atanh(30B",
+ "pow(00B00B",
+ "pow(10B10B",
+ "pow(20B20B",
+ "pow(30B30B",
+ "exp(00B",
+ "exp(10B",
+ "exp(20B",
+ "exp(30B",
+ "log(00B",
+ "log(10B",
+ "log(20B",
+ "log(30B",
+ "exp2(00B",
+ "exp2(10B",
+ "exp2(20B",
+ "exp2(30B",
+ "log2(00B",
+ "log2(10B",
+ "log2(20B",
+ "log2(30B",
+ "sqrt(00B",
+ "sqrt(10B",
+ "sqrt(20B",
+ "sqrt(30B",
+ "inversesqrt(00B",
+ "inversesqrt(10B",
+ "inversesqrt(20B",
+ "inversesqrt(30B",
+ "abs(00B",
+ "abs(10B",
+ "abs(20B",
+ "abs(30B",
+ "abs(00D",
+ "abs(10D",
+ "abs(20D",
+ "abs(30D",
+ "sign(00B",
+ "sign(10B",
+ "sign(20B",
+ "sign(30B",
+ "sign(00D",
+ "sign(10D",
+ "sign(20D",
+ "sign(30D",
+ "floor(00B",
+ "floor(10B",
+ "floor(20B",
+ "floor(30B",
+ "trunc(00B",
+ "trunc(10B",
+ "trunc(20B",
+ "trunc(30B",
+ "round(00B",
+ "round(10B",
+ "round(20B",
+ "round(30B",
+ "roundEven(00B",
+ "roundEven(10B",
+ "roundEven(20B",
+ "roundEven(30B",
+ "ceil(00B",
+ "ceil(10B",
+ "ceil(20B",
+ "ceil(30B",
+ "fract(00B",
+ "fract(10B",
+ "fract(20B",
+ "fract(30B",
+ "mod(00B00B",
+ "mod(10B00B",
+ "mod(20B00B",
+ "mod(30B00B",
+ "mod(10B10B",
+ "mod(20B20B",
+ "mod(30B30B",
+ "min(00B00B",
+ "min(10B00B",
+ "min(20B00B",
+ "min(30B00B",
+ "min(10B10B",
+ "min(20B20B",
+ "min(30B30B",
+ "min(00D00D",
+ "min(10D10D",
+ "min(20D20D",
+ "min(30D30D",
+ "min(10D00D",
+ "min(20D00D",
+ "min(30D00D",
+ "min(00E00E",
+ "min(10E10E",
+ "min(20E20E",
+ "min(30E30E",
+ "min(10E00E",
+ "min(20E00E",
+ "min(30E00E",
+ "max(00B00B",
+ "max(10B00B",
+ "max(20B00B",
+ "max(30B00B",
+ "max(10B10B",
+ "max(20B20B",
+ "max(30B30B",
+ "max(00D00D",
+ "max(10D10D",
+ "max(20D20D",
+ "max(30D30D",
+ "max(10D00D",
+ "max(20D00D",
+ "max(30D00D",
+ "max(00E00E",
+ "max(10E10E",
+ "max(20E20E",
+ "max(30E30E",
+ "max(10E00E",
+ "max(20E00E",
+ "max(30E00E",
+ "clamp(00B00B00B",
+ "clamp(10B00B00B",
+ "clamp(20B00B00B",
+ "clamp(30B00B00B",
+ "clamp(10B10B10B",
+ "clamp(20B20B20B",
+ "clamp(30B30B30B",
+ "clamp(00D00D00D",
+ "clamp(10D00D00D",
+ "clamp(20D00D00D",
+ "clamp(30D00D00D",
+ "clamp(10D10D10D",
+ "clamp(20D20D20D",
+ "clamp(30D30D30D",
+ "clamp(00E00E00E",
+ "clamp(10E00E00E",
+ "clamp(20E00E00E",
+ "clamp(30E00E00E",
+ "clamp(10E10E10E",
+ "clamp(20E20E20E",
+ "clamp(30E30E30E",
+ "mix(00B00B00B",
+ "mix(10B10B00B",
+ "mix(20B20B00B",
+ "mix(30B30B00B",
+ "mix(10B10B10B",
+ "mix(20B20B20B",
+ "mix(30B30B30B",
+ "mix(00B00B00F",
+ "mix(10B10B10F",
+ "mix(20B20B20F",
+ "mix(30B30B30F",
+ "mix(00D00D00F",
+ "mix(10D10D10F",
+ "mix(20D20D20F",
+ "mix(30D30D30F",
+ "mix(00E00E00F",
+ "mix(10E10E10F",
+ "mix(20E20E20F",
+ "mix(30E30E30F",
+ "mix(00F00F00F",
+ "mix(10F10F10F",
+ "mix(20F20F20F",
+ "mix(30F30F30F",
+ "step(00B00B",
+ "step(10B10B",
+ "step(20B20B",
+ "step(30B30B",
+ "step(00B10B",
+ "step(00B20B",
+ "step(00B30B",
+ "smoothstep(00B00B00B",
+ "smoothstep(10B10B10B",
+ "smoothstep(20B20B20B",
+ "smoothstep(30B30B30B",
+ "smoothstep(00B00B10B",
+ "smoothstep(00B00B20B",
+ "smoothstep(00B00B30B",
+ "modf(00B00B",
+ "modf(10B10B",
+ "modf(20B20B",
+ "modf(30B30B",
+ "isnan(00B",
+ "isnan(10B",
+ "isnan(20B",
+ "isnan(30B",
+ "isinf(00B",
+ "isinf(10B",
+ "isinf(20B",
+ "isinf(30B",
+ "floatBitsToInt(00B",
+ "floatBitsToInt(10B",
+ "floatBitsToInt(20B",
+ "floatBitsToInt(30B",
+ "floatBitsToUint(00B",
+ "floatBitsToUint(10B",
+ "floatBitsToUint(20B",
+ "floatBitsToUint(30B",
+ "intBitsToFloat(00D",
+ "intBitsToFloat(10D",
+ "intBitsToFloat(20D",
+ "intBitsToFloat(30D",
+ "uintBitsToFloat(00E",
+ "uintBitsToFloat(10E",
+ "uintBitsToFloat(20E",
+ "uintBitsToFloat(30E",
+ "fma(00B00B00B",
+ "fma(10B10B10B",
+ "fma(20B20B20B",
+ "fma(30B30B30B",
+ "frexp(00B00D",
+ "frexp(10B10D",
+ "frexp(20B20D",
+ "frexp(30B30D",
+ "ldexp(00B00D",
+ "ldexp(10B10D",
+ "ldexp(20B20D",
+ "ldexp(30B30D",
+ "packSnorm2x16(10B",
+ "packHalf2x16(10B",
+ "unpackSnorm2x16(00E",
+ "unpackHalf2x16(00E",
+ "packUnorm2x16(10B",
+ "unpackUnorm2x16(00E",
+ "packUnorm4x8(30B",
+ "packSnorm4x8(30B",
+ "unpackUnorm4x8(00E",
+ "unpackSnorm4x8(00E",
+ "length(00B",
+ "length(10B",
+ "length(20B",
+ "length(30B",
+ "distance(00B00B",
+ "distance(10B10B",
+ "distance(20B20B",
+ "distance(30B30B",
+ "dot(00B00B",
+ "dot(10B10B",
+ "dot(20B20B",
+ "dot(30B30B",
+ "cross(20B20B",
+ "normalize(00B",
+ "normalize(10B",
+ "normalize(20B",
+ "normalize(30B",
+ "faceforward(00B00B00B",
+ "faceforward(10B10B10B",
+ "faceforward(20B20B20B",
+ "faceforward(30B30B30B",
+ "reflect(00B00B",
+ "reflect(10B10B",
+ "reflect(20B20B",
+ "reflect(30B30B",
+ "refract(00B00B00B",
+ "refract(10B10B00B",
+ "refract(20B20B00B",
+ "refract(30B30B00B",
+ "matrixCompMult(50B50B",
+ "matrixCompMult(A0BA0B",
+ "matrixCompMult(F0BF0B",
+ "matrixCompMult(90B90B",
+ "matrixCompMult(60B60B",
+ "matrixCompMult(D0BD0B",
+ "matrixCompMult(70B70B",
+ "matrixCompMult(E0BE0B",
+ "matrixCompMult(B0BB0B",
+ "outerProduct(10B10B",
+ "outerProduct(20B20B",
+ "outerProduct(30B30B",
+ "outerProduct(20B10B",
+ "outerProduct(10B20B",
+ "outerProduct(30B10B",
+ "outerProduct(10B30B",
+ "outerProduct(30B20B",
+ "outerProduct(20B30B",
+ "transpose(50B",
+ "transpose(A0B",
+ "transpose(F0B",
+ "transpose(60B",
+ "transpose(90B",
+ "transpose(70B",
+ "transpose(D0B",
+ "transpose(B0B",
+ "transpose(E0B",
+ "determinant(50B",
+ "determinant(A0B",
+ "determinant(F0B",
+ "inverse(50B",
+ "inverse(A0B",
+ "inverse(F0B",
+ "lessThan(10B10B",
+ "lessThan(20B20B",
+ "lessThan(30B30B",
+ "lessThan(10D10D",
+ "lessThan(20D20D",
+ "lessThan(30D30D",
+ "lessThan(10E10E",
+ "lessThan(20E20E",
+ "lessThan(30E30E",
+ "lessThanEqual(10B10B",
+ "lessThanEqual(20B20B",
+ "lessThanEqual(30B30B",
+ "lessThanEqual(10D10D",
+ "lessThanEqual(20D20D",
+ "lessThanEqual(30D30D",
+ "lessThanEqual(10E10E",
+ "lessThanEqual(20E20E",
+ "lessThanEqual(30E30E",
+ "greaterThan(10B10B",
+ "greaterThan(20B20B",
+ "greaterThan(30B30B",
+ "greaterThan(10D10D",
+ "greaterThan(20D20D",
+ "greaterThan(30D30D",
+ "greaterThan(10E10E",
+ "greaterThan(20E20E",
+ "greaterThan(30E30E",
+ "greaterThanEqual(10B10B",
+ "greaterThanEqual(20B20B",
+ "greaterThanEqual(30B30B",
+ "greaterThanEqual(10D10D",
+ "greaterThanEqual(20D20D",
+ "greaterThanEqual(30D30D",
+ "greaterThanEqual(10E10E",
+ "greaterThanEqual(20E20E",
+ "greaterThanEqual(30E30E",
+ "equal(10B10B",
+ "equal(20B20B",
+ "equal(30B30B",
+ "equal(10D10D",
+ "equal(20D20D",
+ "equal(30D30D",
+ "equal(10E10E",
+ "equal(20E20E",
+ "equal(30E30E",
+ "equal(10F10F",
+ "equal(20F20F",
+ "equal(30F30F",
+ "notEqual(10B10B",
+ "notEqual(20B20B",
+ "notEqual(30B30B",
+ "notEqual(10D10D",
+ "notEqual(20D20D",
+ "notEqual(30D30D",
+ "notEqual(10E10E",
+ "notEqual(20E20E",
+ "notEqual(30E30E",
+ "notEqual(10F10F",
+ "notEqual(20F20F",
+ "notEqual(30F30F",
+ "any(10F",
+ "any(20F",
+ "any(30F",
+ "all(10F",
+ "all(20F",
+ "all(30F",
+ "not(10F",
+ "not(20F",
+ "not(30F",
+ "bitfieldExtract(00D00D00D",
+ "bitfieldExtract(10D00D00D",
+ "bitfieldExtract(20D00D00D",
+ "bitfieldExtract(30D00D00D",
+ "bitfieldExtract(00E00D00D",
+ "bitfieldExtract(10E00D00D",
+ "bitfieldExtract(20E00D00D",
+ "bitfieldExtract(30E00D00D",
+ "bitfieldInsert(00D00D00D00D",
+ "bitfieldInsert(10D10D00D00D",
+ "bitfieldInsert(20D20D00D00D",
+ "bitfieldInsert(30D30D00D00D",
+ "bitfieldInsert(00E00E00D00D",
+ "bitfieldInsert(10E10E00D00D",
+ "bitfieldInsert(20E20E00D00D",
+ "bitfieldInsert(30E30E00D00D",
+ "bitfieldReverse(00D",
+ "bitfieldReverse(10D",
+ "bitfieldReverse(20D",
+ "bitfieldReverse(30D",
+ "bitfieldReverse(00E",
+ "bitfieldReverse(10E",
+ "bitfieldReverse(20E",
+ "bitfieldReverse(30E",
+ "bitCount(00D",
+ "bitCount(10D",
+ "bitCount(20D",
+ "bitCount(30D",
+ "bitCount(00E",
+ "bitCount(10E",
+ "bitCount(20E",
+ "bitCount(30E",
+ "findLSB(00D",
+ "findLSB(10D",
+ "findLSB(20D",
+ "findLSB(30D",
+ "findLSB(00E",
+ "findLSB(10E",
+ "findLSB(20E",
+ "findLSB(30E",
+ "findMSB(00D",
+ "findMSB(10D",
+ "findMSB(20D",
+ "findMSB(30D",
+ "findMSB(00E",
+ "findMSB(10E",
+ "findMSB(20E",
+ "findMSB(30E",
+ "uaddCarry(00E00E00E",
+ "uaddCarry(10E10E10E",
+ "uaddCarry(20E20E20E",
+ "uaddCarry(30E30E30E",
+ "usubBorrow(00E00E00E",
+ "usubBorrow(10E10E10E",
+ "usubBorrow(20E20E20E",
+ "usubBorrow(30E30E30E",
+ "umulExtended(00E00E00E00E",
+ "umulExtended(10E10E10E10E",
+ "umulExtended(20E20E20E20E",
+ "umulExtended(30E30E30E30E",
+ "imulExtended(00D00D00D00D",
+ "imulExtended(10D10D10D10D",
+ "imulExtended(20D20D20D20D",
+ "imulExtended(30D30D30D30D",
+ "texture2D(00I10B",
+ "texture2DProj(00I20B",
+ "texture2DProj(00I30B",
+ "textureCube(00K20B",
+ "texture3D(00J20B",
+ "texture3DProj(00J30B",
+ "shadow2DEXT(00d20B",
+ "shadow2DProjEXT(00d30B",
+ "texture2D(00M10B",
+ "texture2DProj(00M20B",
+ "texture2DProj(00M30B",
+ "texture2DRect(00O10B",
+ "texture2DRectProj(00O20B",
+ "texture2DRectProj(00O30B",
+ "texture2DGradEXT(00I10B10B10B",
+ "texture2DProjGradEXT(00I20B10B10B",
+ "texture2DProjGradEXT(00I30B10B10B",
+ "textureCubeGradEXT(00K20B20B20B",
+ "textureVideoWEBGL(00y10B",
+ "texture2D(00I10B00B",
+ "texture2DProj(00I20B00B",
+ "texture2DProj(00I30B00B",
+ "textureCube(00K20B00B",
+ "texture3D(00J20B00B",
+ "texture3DProj(00J30B00B",
+ "texture3DLod(00J20B00B",
+ "texture3DProjLod(00J30B00B",
+ "texture2DLod(00I10B00B",
+ "texture2DProjLod(00I20B00B",
+ "texture2DProjLod(00I30B00B",
+ "textureCubeLod(00K20B00B",
+ "texture2DLodEXT(00I10B00B",
+ "texture2DProjLodEXT(00I20B00B",
+ "texture2DProjLodEXT(00I30B00B",
+ "textureCubeLodEXT(00K20B00B",
+ "texture(00I10B",
+ "texture(00R10B",
+ "texture(00X10B",
+ "texture(00J20B",
+ "texture(00S20B",
+ "texture(00Y20B",
+ "texture(00K20B",
+ "texture(00T20B",
+ "texture(00Z20B",
+ "texture(00L20B",
+ "texture(00U20B",
+ "texture(00a20B",
+ "texture(00d20B",
+ "texture(00e30B",
+ "texture(00f30B",
+ "texture(00k30B",
+ "texture(00s30B",
+ "texture(00x30B",
+ "texture(00l30B00B",
+ "texture(00M10B",
+ "texture(00N10B",
+ "texture(00O10B",
+ "texture(00y10B",
+ "textureProj(00I20B",
+ "textureProj(00R20B",
+ "textureProj(00X20B",
+ "textureProj(00I30B",
+ "textureProj(00R30B",
+ "textureProj(00X30B",
+ "textureProj(00J30B",
+ "textureProj(00S30B",
+ "textureProj(00Y30B",
+ "textureProj(00d30B",
+ "textureProj(00M20B",
+ "textureProj(00M30B",
+ "textureProj(00N20B",
+ "textureProj(00N30B",
+ "textureProj(00O20B",
+ "textureProj(00O30B",
+ "textureLod(00I10B00B",
+ "textureLod(00R10B00B",
+ "textureLod(00X10B00B",
+ "textureLod(00J20B00B",
+ "textureLod(00S20B00B",
+ "textureLod(00Y20B00B",
+ "textureLod(00K20B00B",
+ "textureLod(00T20B00B",
+ "textureLod(00Z20B00B",
+ "textureLod(00L20B00B",
+ "textureLod(00U20B00B",
+ "textureLod(00a20B00B",
+ "textureLod(00d20B00B",
+ "textureLod(00k30B00B",
+ "textureLod(00s30B00B",
+ "textureLod(00x30B00B",
+ "textureSize(00I00D",
+ "textureSize(00R00D",
+ "textureSize(00X00D",
+ "textureSize(00J00D",
+ "textureSize(00S00D",
+ "textureSize(00Y00D",
+ "textureSize(00K00D",
+ "textureSize(00T00D",
+ "textureSize(00Z00D",
+ "textureSize(00L00D",
+ "textureSize(00U00D",
+ "textureSize(00a00D",
+ "textureSize(00d00D",
+ "textureSize(00e00D",
+ "textureSize(00f00D",
+ "textureSize(00k00D",
+ "textureSize(00s00D",
+ "textureSize(00x00D",
+ "textureSize(00l00D",
+ "textureSize(00j",
+ "textureSize(00r",
+ "textureSize(00w",
+ "textureSize(00P",
+ "textureSize(00V",
+ "textureSize(00b",
+ "textureSize(00Q",
+ "textureSize(00W",
+ "textureSize(00c",
+ "textureSize(00M00D",
+ "textureSize(00N00D",
+ "textureProjLod(00I20B00B",
+ "textureProjLod(00R20B00B",
+ "textureProjLod(00X20B00B",
+ "textureProjLod(00I30B00B",
+ "textureProjLod(00R30B00B",
+ "textureProjLod(00X30B00B",
+ "textureProjLod(00J30B00B",
+ "textureProjLod(00S30B00B",
+ "textureProjLod(00Y30B00B",
+ "textureProjLod(00d30B00B",
+ "texelFetch(00I10D00D",
+ "texelFetch(00R10D00D",
+ "texelFetch(00X10D00D",
+ "texelFetch(00J20D00D",
+ "texelFetch(00S20D00D",
+ "texelFetch(00Y20D00D",
+ "texelFetch(00L20D00D",
+ "texelFetch(00U20D00D",
+ "texelFetch(00a20D00D",
+ "texelFetch(00j00D",
+ "texelFetch(00r00D",
+ "texelFetch(00w00D",
+ "texelFetch(00P10D00D",
+ "texelFetch(00V10D00D",
+ "texelFetch(00b10D00D",
+ "texelFetch(00Q20D00D",
+ "texelFetch(00W20D00D",
+ "texelFetch(00c20D00D",
+ "texelFetch(00M10D00D",
+ "texelFetch(00N10D00D",
+ "textureGrad(00I10B10B10B",
+ "textureGrad(00R10B10B10B",
+ "textureGrad(00X10B10B10B",
+ "textureGrad(00J20B20B20B",
+ "textureGrad(00S20B20B20B",
+ "textureGrad(00Y20B20B20B",
+ "textureGrad(00K20B20B20B",
+ "textureGrad(00T20B20B20B",
+ "textureGrad(00Z20B20B20B",
+ "textureGrad(00d20B10B10B",
+ "textureGrad(00e30B20B20B",
+ "textureGrad(00L20B10B10B",
+ "textureGrad(00U20B10B10B",
+ "textureGrad(00a20B10B10B",
+ "textureGrad(00f30B10B10B",
+ "textureGrad(00k30B20B20B",
+ "textureGrad(00s30B20B20B",
+ "textureGrad(00x30B20B20B",
+ "textureProjGrad(00I20B10B10B",
+ "textureProjGrad(00R20B10B10B",
+ "textureProjGrad(00X20B10B10B",
+ "textureProjGrad(00I30B10B10B",
+ "textureProjGrad(00R30B10B10B",
+ "textureProjGrad(00X30B10B10B",
+ "textureProjGrad(00J30B20B20B",
+ "textureProjGrad(00S30B20B20B",
+ "textureProjGrad(00Y30B20B20B",
+ "textureProjGrad(00d30B10B10B",
+ "texture(00I10B00B",
+ "texture(00R10B00B",
+ "texture(00X10B00B",
+ "texture(00J20B00B",
+ "texture(00S20B00B",
+ "texture(00Y20B00B",
+ "texture(00K20B00B",
+ "texture(00T20B00B",
+ "texture(00Z20B00B",
+ "texture(00L20B00B",
+ "texture(00U20B00B",
+ "texture(00a20B00B",
+ "textureProj(00I20B00B",
+ "textureProj(00R20B00B",
+ "textureProj(00X20B00B",
+ "textureProj(00I30B00B",
+ "textureProj(00R30B00B",
+ "textureProj(00X30B00B",
+ "textureProj(00J30B00B",
+ "textureProj(00S30B00B",
+ "textureProj(00Y30B00B",
+ "texture(00d20B00B",
+ "texture(00e30B00B",
+ "textureProj(00d30B00B",
+ "texture(00k30B00B",
+ "texture(00s30B00B",
+ "texture(00x30B00B",
+ "texture(00M10B00B",
+ "textureProj(00M20B00B",
+ "textureProj(00M30B00B",
+ "texture(00N10B00B",
+ "textureProj(00N20B00B",
+ "textureProj(00N30B00B",
+ "textureOffset(00I10B10D",
+ "textureOffset(00R10B10D",
+ "textureOffset(00X10B10D",
+ "textureOffset(00J20B20D",
+ "textureOffset(00S20B20D",
+ "textureOffset(00Y20B20D",
+ "textureOffset(00d20B10D",
+ "textureOffset(00L20B10D",
+ "textureOffset(00U20B10D",
+ "textureOffset(00a20B10D",
+ "textureProjOffset(00I20B10D",
+ "textureProjOffset(00R20B10D",
+ "textureProjOffset(00X20B10D",
+ "textureProjOffset(00I30B10D",
+ "textureProjOffset(00R30B10D",
+ "textureProjOffset(00X30B10D",
+ "textureProjOffset(00J30B20D",
+ "textureProjOffset(00S30B20D",
+ "textureProjOffset(00Y30B20D",
+ "textureProjOffset(00d30B10D",
+ "textureLodOffset(00I10B00B10D",
+ "textureLodOffset(00R10B00B10D",
+ "textureLodOffset(00X10B00B10D",
+ "textureLodOffset(00J20B00B20D",
+ "textureLodOffset(00S20B00B20D",
+ "textureLodOffset(00Y20B00B20D",
+ "textureLodOffset(00d20B00B10D",
+ "textureLodOffset(00L20B00B10D",
+ "textureLodOffset(00U20B00B10D",
+ "textureLodOffset(00a20B00B10D",
+ "textureProjLodOffset(00I20B00B10D",
+ "textureProjLodOffset(00R20B00B10D",
+ "textureProjLodOffset(00X20B00B10D",
+ "textureProjLodOffset(00I30B00B10D",
+ "textureProjLodOffset(00R30B00B10D",
+ "textureProjLodOffset(00X30B00B10D",
+ "textureProjLodOffset(00J30B00B20D",
+ "textureProjLodOffset(00S30B00B20D",
+ "textureProjLodOffset(00Y30B00B20D",
+ "textureProjLodOffset(00d30B00B10D",
+ "texelFetchOffset(00I10D00D10D",
+ "texelFetchOffset(00R10D00D10D",
+ "texelFetchOffset(00X10D00D10D",
+ "texelFetchOffset(00J20D00D20D",
+ "texelFetchOffset(00S20D00D20D",
+ "texelFetchOffset(00Y20D00D20D",
+ "texelFetchOffset(00L20D00D10D",
+ "texelFetchOffset(00U20D00D10D",
+ "texelFetchOffset(00a20D00D10D",
+ "textureGradOffset(00I10B10B10B10D",
+ "textureGradOffset(00R10B10B10B10D",
+ "textureGradOffset(00X10B10B10B10D",
+ "textureGradOffset(00J20B20B20B20D",
+ "textureGradOffset(00S20B20B20B20D",
+ "textureGradOffset(00Y20B20B20B20D",
+ "textureGradOffset(00d20B10B10B10D",
+ "textureGradOffset(00L20B10B10B10D",
+ "textureGradOffset(00U20B10B10B10D",
+ "textureGradOffset(00a20B10B10B10D",
+ "textureGradOffset(00f30B10B10B10D",
+ "textureProjGradOffset(00I20B10B10B10D",
+ "textureProjGradOffset(00R20B10B10B10D",
+ "textureProjGradOffset(00X20B10B10B10D",
+ "textureProjGradOffset(00I30B10B10B10D",
+ "textureProjGradOffset(00R30B10B10B10D",
+ "textureProjGradOffset(00X30B10B10B10D",
+ "textureProjGradOffset(00J30B20B20B20D",
+ "textureProjGradOffset(00S30B20B20B20D",
+ "textureProjGradOffset(00Y30B20B20B20D",
+ "textureProjGradOffset(00d30B10B10B10D",
+ "textureOffset(00I10B10D00B",
+ "textureOffset(00R10B10D00B",
+ "textureOffset(00X10B10D00B",
+ "textureOffset(00J20B20D00B",
+ "textureOffset(00S20B20D00B",
+ "textureOffset(00Y20B20D00B",
+ "textureOffset(00d20B10D00B",
+ "textureOffset(00L20B10D00B",
+ "textureOffset(00U20B10D00B",
+ "textureOffset(00a20B10D00B",
+ "textureProjOffset(00I20B10D00B",
+ "textureProjOffset(00R20B10D00B",
+ "textureProjOffset(00X20B10D00B",
+ "textureProjOffset(00I30B10D00B",
+ "textureProjOffset(00R30B10D00B",
+ "textureProjOffset(00X30B10D00B",
+ "textureProjOffset(00J30B20D00B",
+ "textureProjOffset(00S30B20D00B",
+ "textureProjOffset(00Y30B20D00B",
+ "textureProjOffset(00d30B10D00B",
+ "textureGather(00I10B",
+ "textureGather(00R10B",
+ "textureGather(00X10B",
+ "textureGather(00I10B00D",
+ "textureGather(00R10B00D",
+ "textureGather(00X10B00D",
+ "textureGather(00L20B",
+ "textureGather(00U20B",
+ "textureGather(00a20B",
+ "textureGather(00L20B00D",
+ "textureGather(00U20B00D",
+ "textureGather(00a20B00D",
+ "textureGather(00K20B",
+ "textureGather(00T20B",
+ "textureGather(00Z20B",
+ "textureGather(00K20B00D",
+ "textureGather(00T20B00D",
+ "textureGather(00Z20B00D",
+ "textureGather(00k30B",
+ "textureGather(00s30B",
+ "textureGather(00x30B",
+ "textureGather(00k30B00D",
+ "textureGather(00s30B00D",
+ "textureGather(00x30B00D",
+ "textureGather(00l30B00B",
+ "textureGather(00d10B",
+ "textureGather(00d10B00B",
+ "textureGather(00f20B",
+ "textureGather(00f20B00B",
+ "textureGather(00e20B",
+ "textureGather(00e20B00B",
+ "textureGatherOffset(00I10B10D",
+ "textureGatherOffset(00R10B10D",
+ "textureGatherOffset(00X10B10D",
+ "textureGatherOffset(00L20B10D",
+ "textureGatherOffset(00U20B10D",
+ "textureGatherOffset(00a20B10D",
+ "textureGatherOffset(00d10B00B10D",
+ "textureGatherOffset(00f20B00B10D",
+ "textureGatherOffset(00I10B10D00D",
+ "textureGatherOffset(00R10B10D00D",
+ "textureGatherOffset(00X10B10D00D",
+ "textureGatherOffset(00L20B10D00D",
+ "textureGatherOffset(00U20B10D00D",
+ "textureGatherOffset(00a20B10D00D",
+ "textureGatherOffsets(00I10B10Dx4",
+ "textureGatherOffsets(00R10B10Dx4",
+ "textureGatherOffsets(00X10B10Dx4",
+ "textureGatherOffsets(00L20B10Dx4",
+ "textureGatherOffsets(00U20B10Dx4",
+ "textureGatherOffsets(00a20B10Dx4",
+ "textureGatherOffsets(00d10B00B10Dx4",
+ "textureGatherOffsets(00f20B00B10Dx4",
+ "textureGatherOffsets(00I10B10Dx400D",
+ "textureGatherOffsets(00R10B10Dx400D",
+ "textureGatherOffsets(00X10B10Dx400D",
+ "textureGatherOffsets(00L20B10Dx400D",
+ "textureGatherOffsets(00U20B10Dx400D",
+ "textureGatherOffsets(00a20B10Dx400D",
+ "rgb_2_yuv(20B00H",
+ "yuv_2_rgb(20B00H",
+ "dFdx(00B",
+ "dFdx(10B",
+ "dFdx(20B",
+ "dFdx(30B",
+ "dFdy(00B",
+ "dFdy(10B",
+ "dFdy(20B",
+ "dFdy(30B",
+ "fwidth(00B",
+ "fwidth(10B",
+ "fwidth(20B",
+ "fwidth(30B",
+ "interpolateAtCentroid(00B",
+ "interpolateAtCentroid(10B",
+ "interpolateAtCentroid(20B",
+ "interpolateAtCentroid(30B",
+ "interpolateAtSample(00B00D",
+ "interpolateAtSample(10B00D",
+ "interpolateAtSample(20B00D",
+ "interpolateAtSample(30B00D",
+ "interpolateAtOffset(00B10B",
+ "interpolateAtOffset(10B10B",
+ "interpolateAtOffset(20B10B",
+ "interpolateAtOffset(30B10B",
+ "atomicCounter(00G",
+ "atomicCounterIncrement(00G",
+ "atomicCounterDecrement(00G",
+ "atomicAdd(00E00E",
+ "atomicAdd(00D00D",
+ "atomicMin(00E00E",
+ "atomicMin(00D00D",
+ "atomicMax(00E00E",
+ "atomicMax(00D00D",
+ "atomicAnd(00E00E",
+ "atomicAnd(00D00D",
+ "atomicOr(00E00E",
+ "atomicOr(00D00D",
+ "atomicXor(00E00E",
+ "atomicXor(00D00D",
+ "atomicExchange(00E00E",
+ "atomicExchange(00D00D",
+ "atomicCompSwap(00E00E00E",
+ "atomicCompSwap(00D00D00D",
+ "imageSize(00z",
+ "imageSize(01K",
+ "imageSize(01V",
+ "imageSize(01A",
+ "imageSize(01L",
+ "imageSize(01W",
+ "imageSize(01B",
+ "imageSize(01M",
+ "imageSize(01X",
+ "imageSize(01C",
+ "imageSize(01N",
+ "imageSize(01Y",
+ "imageSize(01H",
+ "imageSize(01S",
+ "imageSize(01d",
+ "imageSize(01J",
+ "imageSize(01U",
+ "imageSize(01f",
+ "imageStore(00z10D30B",
+ "imageStore(01K10D30D",
+ "imageStore(01V10D30E",
+ "imageStore(01A20D30B",
+ "imageStore(01L20D30D",
+ "imageStore(01W20D30E",
+ "imageStore(01B20D30B",
+ "imageStore(01M20D30D",
+ "imageStore(01X20D30E",
+ "imageStore(01C20D30B",
+ "imageStore(01N20D30D",
+ "imageStore(01Y20D30E",
+ "imageStore(01H20D30B",
+ "imageStore(01S20D30D",
+ "imageStore(01d20D30E",
+ "imageStore(01J00D30B",
+ "imageStore(01U00D30D",
+ "imageStore(01f00D30E",
+ "imageLoad(00z10D",
+ "imageLoad(01K10D",
+ "imageLoad(01V10D",
+ "imageLoad(01A20D",
+ "imageLoad(01L20D",
+ "imageLoad(01W20D",
+ "imageLoad(01B20D",
+ "imageLoad(01M20D",
+ "imageLoad(01X20D",
+ "imageLoad(01C20D",
+ "imageLoad(01N20D",
+ "imageLoad(01Y20D",
+ "imageLoad(01H20D",
+ "imageLoad(01S20D",
+ "imageLoad(01d20D",
+ "imageLoad(01J00D",
+ "imageLoad(01U00D",
+ "imageLoad(01f00D",
+ "imageAtomicAdd(00z10D00E",
+ "imageAtomicAdd(01K10D00E",
+ "imageAtomicAdd(01V10D00E",
+ "imageAtomicAdd(01A20D00E",
+ "imageAtomicAdd(01L20D00E",
+ "imageAtomicAdd(01W20D00E",
+ "imageAtomicAdd(01C20D00E",
+ "imageAtomicAdd(01N20D00E",
+ "imageAtomicAdd(01Y20D00E",
+ "imageAtomicAdd(01J00D00E",
+ "imageAtomicAdd(01U00D00E",
+ "imageAtomicAdd(01f00D00E",
+ "imageAtomicAdd(01B20D00E",
+ "imageAtomicAdd(01M20D00E",
+ "imageAtomicAdd(01X20D00E",
+ "imageAtomicAdd(01H20D00E",
+ "imageAtomicAdd(01S20D00E",
+ "imageAtomicAdd(01d20D00E",
+ "imageAtomicAdd(01D00D00E",
+ "imageAtomicAdd(01O00D00E",
+ "imageAtomicAdd(01Z00D00E",
+ "imageAtomicAdd(01E10D00E",
+ "imageAtomicAdd(01P10D00E",
+ "imageAtomicAdd(01a10D00E",
+ "imageAtomicAdd(01I10D00E",
+ "imageAtomicAdd(01T10D00E",
+ "imageAtomicAdd(01e10D00E",
+ "imageAtomicAdd(01F10D00D00E",
+ "imageAtomicAdd(01Q10D00D00E",
+ "imageAtomicAdd(01b10D00D00E",
+ "imageAtomicAdd(01G20D00D00E",
+ "imageAtomicAdd(01R20D00D00E",
+ "imageAtomicAdd(01c20D00D00E",
+ "imageAtomicAdd(00z10D00D",
+ "imageAtomicAdd(01K10D00D",
+ "imageAtomicAdd(01V10D00D",
+ "imageAtomicAdd(01A20D00D",
+ "imageAtomicAdd(01L20D00D",
+ "imageAtomicAdd(01W20D00D",
+ "imageAtomicAdd(01C20D00D",
+ "imageAtomicAdd(01N20D00D",
+ "imageAtomicAdd(01Y20D00D",
+ "imageAtomicAdd(01J00D00D",
+ "imageAtomicAdd(01U00D00D",
+ "imageAtomicAdd(01f00D00D",
+ "imageAtomicAdd(01B20D00D",
+ "imageAtomicAdd(01M20D00D",
+ "imageAtomicAdd(01X20D00D",
+ "imageAtomicAdd(01H20D00D",
+ "imageAtomicAdd(01S20D00D",
+ "imageAtomicAdd(01d20D00D",
+ "imageAtomicAdd(01D00D00D",
+ "imageAtomicAdd(01O00D00D",
+ "imageAtomicAdd(01Z00D00D",
+ "imageAtomicAdd(01E10D00D",
+ "imageAtomicAdd(01P10D00D",
+ "imageAtomicAdd(01a10D00D",
+ "imageAtomicAdd(01I10D00D",
+ "imageAtomicAdd(01T10D00D",
+ "imageAtomicAdd(01e10D00D",
+ "imageAtomicAdd(01F10D00D00D",
+ "imageAtomicAdd(01Q10D00D00D",
+ "imageAtomicAdd(01b10D00D00D",
+ "imageAtomicAdd(01G20D00D00D",
+ "imageAtomicAdd(01R20D00D00D",
+ "imageAtomicAdd(01c20D00D00D",
+ "imageAtomicMin(00z10D00E",
+ "imageAtomicMin(01K10D00E",
+ "imageAtomicMin(01V10D00E",
+ "imageAtomicMin(01A20D00E",
+ "imageAtomicMin(01L20D00E",
+ "imageAtomicMin(01W20D00E",
+ "imageAtomicMin(01C20D00E",
+ "imageAtomicMin(01N20D00E",
+ "imageAtomicMin(01Y20D00E",
+ "imageAtomicMin(01J00D00E",
+ "imageAtomicMin(01U00D00E",
+ "imageAtomicMin(01f00D00E",
+ "imageAtomicMin(01B20D00E",
+ "imageAtomicMin(01M20D00E",
+ "imageAtomicMin(01X20D00E",
+ "imageAtomicMin(01H20D00E",
+ "imageAtomicMin(01S20D00E",
+ "imageAtomicMin(01d20D00E",
+ "imageAtomicMin(01D00D00E",
+ "imageAtomicMin(01O00D00E",
+ "imageAtomicMin(01Z00D00E",
+ "imageAtomicMin(01E10D00E",
+ "imageAtomicMin(01P10D00E",
+ "imageAtomicMin(01a10D00E",
+ "imageAtomicMin(01I10D00E",
+ "imageAtomicMin(01T10D00E",
+ "imageAtomicMin(01e10D00E",
+ "imageAtomicMin(01F10D00D00E",
+ "imageAtomicMin(01Q10D00D00E",
+ "imageAtomicMin(01b10D00D00E",
+ "imageAtomicMin(01G20D00D00E",
+ "imageAtomicMin(01R20D00D00E",
+ "imageAtomicMin(01c20D00D00E",
+ "imageAtomicMin(00z10D00D",
+ "imageAtomicMin(01K10D00D",
+ "imageAtomicMin(01V10D00D",
+ "imageAtomicMin(01A20D00D",
+ "imageAtomicMin(01L20D00D",
+ "imageAtomicMin(01W20D00D",
+ "imageAtomicMin(01C20D00D",
+ "imageAtomicMin(01N20D00D",
+ "imageAtomicMin(01Y20D00D",
+ "imageAtomicMin(01J00D00D",
+ "imageAtomicMin(01U00D00D",
+ "imageAtomicMin(01f00D00D",
+ "imageAtomicMin(01B20D00D",
+ "imageAtomicMin(01M20D00D",
+ "imageAtomicMin(01X20D00D",
+ "imageAtomicMin(01H20D00D",
+ "imageAtomicMin(01S20D00D",
+ "imageAtomicMin(01d20D00D",
+ "imageAtomicMin(01D00D00D",
+ "imageAtomicMin(01O00D00D",
+ "imageAtomicMin(01Z00D00D",
+ "imageAtomicMin(01E10D00D",
+ "imageAtomicMin(01P10D00D",
+ "imageAtomicMin(01a10D00D",
+ "imageAtomicMin(01I10D00D",
+ "imageAtomicMin(01T10D00D",
+ "imageAtomicMin(01e10D00D",
+ "imageAtomicMin(01F10D00D00D",
+ "imageAtomicMin(01Q10D00D00D",
+ "imageAtomicMin(01b10D00D00D",
+ "imageAtomicMin(01G20D00D00D",
+ "imageAtomicMin(01R20D00D00D",
+ "imageAtomicMin(01c20D00D00D",
+ "imageAtomicMax(00z10D00E",
+ "imageAtomicMax(01K10D00E",
+ "imageAtomicMax(01V10D00E",
+ "imageAtomicMax(01A20D00E",
+ "imageAtomicMax(01L20D00E",
+ "imageAtomicMax(01W20D00E",
+ "imageAtomicMax(01C20D00E",
+ "imageAtomicMax(01N20D00E",
+ "imageAtomicMax(01Y20D00E",
+ "imageAtomicMax(01J00D00E",
+ "imageAtomicMax(01U00D00E",
+ "imageAtomicMax(01f00D00E",
+ "imageAtomicMax(01B20D00E",
+ "imageAtomicMax(01M20D00E",
+ "imageAtomicMax(01X20D00E",
+ "imageAtomicMax(01H20D00E",
+ "imageAtomicMax(01S20D00E",
+ "imageAtomicMax(01d20D00E",
+ "imageAtomicMax(01D00D00E",
+ "imageAtomicMax(01O00D00E",
+ "imageAtomicMax(01Z00D00E",
+ "imageAtomicMax(01E10D00E",
+ "imageAtomicMax(01P10D00E",
+ "imageAtomicMax(01a10D00E",
+ "imageAtomicMax(01I10D00E",
+ "imageAtomicMax(01T10D00E",
+ "imageAtomicMax(01e10D00E",
+ "imageAtomicMax(01F10D00D00E",
+ "imageAtomicMax(01Q10D00D00E",
+ "imageAtomicMax(01b10D00D00E",
+ "imageAtomicMax(01G20D00D00E",
+ "imageAtomicMax(01R20D00D00E",
+ "imageAtomicMax(01c20D00D00E",
+ "imageAtomicMax(00z10D00D",
+ "imageAtomicMax(01K10D00D",
+ "imageAtomicMax(01V10D00D",
+ "imageAtomicMax(01A20D00D",
+ "imageAtomicMax(01L20D00D",
+ "imageAtomicMax(01W20D00D",
+ "imageAtomicMax(01C20D00D",
+ "imageAtomicMax(01N20D00D",
+ "imageAtomicMax(01Y20D00D",
+ "imageAtomicMax(01J00D00D",
+ "imageAtomicMax(01U00D00D",
+ "imageAtomicMax(01f00D00D",
+ "imageAtomicMax(01B20D00D",
+ "imageAtomicMax(01M20D00D",
+ "imageAtomicMax(01X20D00D",
+ "imageAtomicMax(01H20D00D",
+ "imageAtomicMax(01S20D00D",
+ "imageAtomicMax(01d20D00D",
+ "imageAtomicMax(01D00D00D",
+ "imageAtomicMax(01O00D00D",
+ "imageAtomicMax(01Z00D00D",
+ "imageAtomicMax(01E10D00D",
+ "imageAtomicMax(01P10D00D",
+ "imageAtomicMax(01a10D00D",
+ "imageAtomicMax(01I10D00D",
+ "imageAtomicMax(01T10D00D",
+ "imageAtomicMax(01e10D00D",
+ "imageAtomicMax(01F10D00D00D",
+ "imageAtomicMax(01Q10D00D00D",
+ "imageAtomicMax(01b10D00D00D",
+ "imageAtomicMax(01G20D00D00D",
+ "imageAtomicMax(01R20D00D00D",
+ "imageAtomicMax(01c20D00D00D",
+ "imageAtomicAnd(00z10D00E",
+ "imageAtomicAnd(01K10D00E",
+ "imageAtomicAnd(01V10D00E",
+ "imageAtomicAnd(01A20D00E",
+ "imageAtomicAnd(01L20D00E",
+ "imageAtomicAnd(01W20D00E",
+ "imageAtomicAnd(01C20D00E",
+ "imageAtomicAnd(01N20D00E",
+ "imageAtomicAnd(01Y20D00E",
+ "imageAtomicAnd(01J00D00E",
+ "imageAtomicAnd(01U00D00E",
+ "imageAtomicAnd(01f00D00E",
+ "imageAtomicAnd(01B20D00E",
+ "imageAtomicAnd(01M20D00E",
+ "imageAtomicAnd(01X20D00E",
+ "imageAtomicAnd(01H20D00E",
+ "imageAtomicAnd(01S20D00E",
+ "imageAtomicAnd(01d20D00E",
+ "imageAtomicAnd(01D00D00E",
+ "imageAtomicAnd(01O00D00E",
+ "imageAtomicAnd(01Z00D00E",
+ "imageAtomicAnd(01E10D00E",
+ "imageAtomicAnd(01P10D00E",
+ "imageAtomicAnd(01a10D00E",
+ "imageAtomicAnd(01I10D00E",
+ "imageAtomicAnd(01T10D00E",
+ "imageAtomicAnd(01e10D00E",
+ "imageAtomicAnd(01F10D00D00E",
+ "imageAtomicAnd(01Q10D00D00E",
+ "imageAtomicAnd(01b10D00D00E",
+ "imageAtomicAnd(01G20D00D00E",
+ "imageAtomicAnd(01R20D00D00E",
+ "imageAtomicAnd(01c20D00D00E",
+ "imageAtomicAnd(00z10D00D",
+ "imageAtomicAnd(01K10D00D",
+ "imageAtomicAnd(01V10D00D",
+ "imageAtomicAnd(01A20D00D",
+ "imageAtomicAnd(01L20D00D",
+ "imageAtomicAnd(01W20D00D",
+ "imageAtomicAnd(01C20D00D",
+ "imageAtomicAnd(01N20D00D",
+ "imageAtomicAnd(01Y20D00D",
+ "imageAtomicAnd(01J00D00D",
+ "imageAtomicAnd(01U00D00D",
+ "imageAtomicAnd(01f00D00D",
+ "imageAtomicAnd(01B20D00D",
+ "imageAtomicAnd(01M20D00D",
+ "imageAtomicAnd(01X20D00D",
+ "imageAtomicAnd(01H20D00D",
+ "imageAtomicAnd(01S20D00D",
+ "imageAtomicAnd(01d20D00D",
+ "imageAtomicAnd(01D00D00D",
+ "imageAtomicAnd(01O00D00D",
+ "imageAtomicAnd(01Z00D00D",
+ "imageAtomicAnd(01E10D00D",
+ "imageAtomicAnd(01P10D00D",
+ "imageAtomicAnd(01a10D00D",
+ "imageAtomicAnd(01I10D00D",
+ "imageAtomicAnd(01T10D00D",
+ "imageAtomicAnd(01e10D00D",
+ "imageAtomicAnd(01F10D00D00D",
+ "imageAtomicAnd(01Q10D00D00D",
+ "imageAtomicAnd(01b10D00D00D",
+ "imageAtomicAnd(01G20D00D00D",
+ "imageAtomicAnd(01R20D00D00D",
+ "imageAtomicAnd(01c20D00D00D",
+ "imageAtomicOr(00z10D00E",
+ "imageAtomicOr(01K10D00E",
+ "imageAtomicOr(01V10D00E",
+ "imageAtomicOr(01A20D00E",
+ "imageAtomicOr(01L20D00E",
+ "imageAtomicOr(01W20D00E",
+ "imageAtomicOr(01C20D00E",
+ "imageAtomicOr(01N20D00E",
+ "imageAtomicOr(01Y20D00E",
+ "imageAtomicOr(01J00D00E",
+ "imageAtomicOr(01U00D00E",
+ "imageAtomicOr(01f00D00E",
+ "imageAtomicOr(01B20D00E",
+ "imageAtomicOr(01M20D00E",
+ "imageAtomicOr(01X20D00E",
+ "imageAtomicOr(01H20D00E",
+ "imageAtomicOr(01S20D00E",
+ "imageAtomicOr(01d20D00E",
+ "imageAtomicOr(01D00D00E",
+ "imageAtomicOr(01O00D00E",
+ "imageAtomicOr(01Z00D00E",
+ "imageAtomicOr(01E10D00E",
+ "imageAtomicOr(01P10D00E",
+ "imageAtomicOr(01a10D00E",
+ "imageAtomicOr(01I10D00E",
+ "imageAtomicOr(01T10D00E",
+ "imageAtomicOr(01e10D00E",
+ "imageAtomicOr(01F10D00D00E",
+ "imageAtomicOr(01Q10D00D00E",
+ "imageAtomicOr(01b10D00D00E",
+ "imageAtomicOr(01G20D00D00E",
+ "imageAtomicOr(01R20D00D00E",
+ "imageAtomicOr(01c20D00D00E",
+ "imageAtomicOr(00z10D00D",
+ "imageAtomicOr(01K10D00D",
+ "imageAtomicOr(01V10D00D",
+ "imageAtomicOr(01A20D00D",
+ "imageAtomicOr(01L20D00D",
+ "imageAtomicOr(01W20D00D",
+ "imageAtomicOr(01C20D00D",
+ "imageAtomicOr(01N20D00D",
+ "imageAtomicOr(01Y20D00D",
+ "imageAtomicOr(01J00D00D",
+ "imageAtomicOr(01U00D00D",
+ "imageAtomicOr(01f00D00D",
+ "imageAtomicOr(01B20D00D",
+ "imageAtomicOr(01M20D00D",
+ "imageAtomicOr(01X20D00D",
+ "imageAtomicOr(01H20D00D",
+ "imageAtomicOr(01S20D00D",
+ "imageAtomicOr(01d20D00D",
+ "imageAtomicOr(01D00D00D",
+ "imageAtomicOr(01O00D00D",
+ "imageAtomicOr(01Z00D00D",
+ "imageAtomicOr(01E10D00D",
+ "imageAtomicOr(01P10D00D",
+ "imageAtomicOr(01a10D00D",
+ "imageAtomicOr(01I10D00D",
+ "imageAtomicOr(01T10D00D",
+ "imageAtomicOr(01e10D00D",
+ "imageAtomicOr(01F10D00D00D",
+ "imageAtomicOr(01Q10D00D00D",
+ "imageAtomicOr(01b10D00D00D",
+ "imageAtomicOr(01G20D00D00D",
+ "imageAtomicOr(01R20D00D00D",
+ "imageAtomicOr(01c20D00D00D",
+ "imageAtomicXor(00z10D00E",
+ "imageAtomicXor(01K10D00E",
+ "imageAtomicXor(01V10D00E",
+ "imageAtomicXor(01A20D00E",
+ "imageAtomicXor(01L20D00E",
+ "imageAtomicXor(01W20D00E",
+ "imageAtomicXor(01C20D00E",
+ "imageAtomicXor(01N20D00E",
+ "imageAtomicXor(01Y20D00E",
+ "imageAtomicXor(01J00D00E",
+ "imageAtomicXor(01U00D00E",
+ "imageAtomicXor(01f00D00E",
+ "imageAtomicXor(01B20D00E",
+ "imageAtomicXor(01M20D00E",
+ "imageAtomicXor(01X20D00E",
+ "imageAtomicXor(01H20D00E",
+ "imageAtomicXor(01S20D00E",
+ "imageAtomicXor(01d20D00E",
+ "imageAtomicXor(01D00D00E",
+ "imageAtomicXor(01O00D00E",
+ "imageAtomicXor(01Z00D00E",
+ "imageAtomicXor(01E10D00E",
+ "imageAtomicXor(01P10D00E",
+ "imageAtomicXor(01a10D00E",
+ "imageAtomicXor(01I10D00E",
+ "imageAtomicXor(01T10D00E",
+ "imageAtomicXor(01e10D00E",
+ "imageAtomicXor(01F10D00D00E",
+ "imageAtomicXor(01Q10D00D00E",
+ "imageAtomicXor(01b10D00D00E",
+ "imageAtomicXor(01G20D00D00E",
+ "imageAtomicXor(01R20D00D00E",
+ "imageAtomicXor(01c20D00D00E",
+ "imageAtomicXor(00z10D00D",
+ "imageAtomicXor(01K10D00D",
+ "imageAtomicXor(01V10D00D",
+ "imageAtomicXor(01A20D00D",
+ "imageAtomicXor(01L20D00D",
+ "imageAtomicXor(01W20D00D",
+ "imageAtomicXor(01C20D00D",
+ "imageAtomicXor(01N20D00D",
+ "imageAtomicXor(01Y20D00D",
+ "imageAtomicXor(01J00D00D",
+ "imageAtomicXor(01U00D00D",
+ "imageAtomicXor(01f00D00D",
+ "imageAtomicXor(01B20D00D",
+ "imageAtomicXor(01M20D00D",
+ "imageAtomicXor(01X20D00D",
+ "imageAtomicXor(01H20D00D",
+ "imageAtomicXor(01S20D00D",
+ "imageAtomicXor(01d20D00D",
+ "imageAtomicXor(01D00D00D",
+ "imageAtomicXor(01O00D00D",
+ "imageAtomicXor(01Z00D00D",
+ "imageAtomicXor(01E10D00D",
+ "imageAtomicXor(01P10D00D",
+ "imageAtomicXor(01a10D00D",
+ "imageAtomicXor(01I10D00D",
+ "imageAtomicXor(01T10D00D",
+ "imageAtomicXor(01e10D00D",
+ "imageAtomicXor(01F10D00D00D",
+ "imageAtomicXor(01Q10D00D00D",
+ "imageAtomicXor(01b10D00D00D",
+ "imageAtomicXor(01G20D00D00D",
+ "imageAtomicXor(01R20D00D00D",
+ "imageAtomicXor(01c20D00D00D",
+ "imageAtomicExchange(00z10D00E",
+ "imageAtomicExchange(01K10D00E",
+ "imageAtomicExchange(01V10D00E",
+ "imageAtomicExchange(01A20D00E",
+ "imageAtomicExchange(01L20D00E",
+ "imageAtomicExchange(01W20D00E",
+ "imageAtomicExchange(01C20D00E",
+ "imageAtomicExchange(01N20D00E",
+ "imageAtomicExchange(01Y20D00E",
+ "imageAtomicExchange(01J00D00E",
+ "imageAtomicExchange(01U00D00E",
+ "imageAtomicExchange(01f00D00E",
+ "imageAtomicExchange(01B20D00E",
+ "imageAtomicExchange(01M20D00E",
+ "imageAtomicExchange(01X20D00E",
+ "imageAtomicExchange(01H20D00E",
+ "imageAtomicExchange(01S20D00E",
+ "imageAtomicExchange(01d20D00E",
+ "imageAtomicExchange(01D00D00E",
+ "imageAtomicExchange(01O00D00E",
+ "imageAtomicExchange(01Z00D00E",
+ "imageAtomicExchange(01E10D00E",
+ "imageAtomicExchange(01P10D00E",
+ "imageAtomicExchange(01a10D00E",
+ "imageAtomicExchange(01I10D00E",
+ "imageAtomicExchange(01T10D00E",
+ "imageAtomicExchange(01e10D00E",
+ "imageAtomicExchange(01F10D00D00E",
+ "imageAtomicExchange(01Q10D00D00E",
+ "imageAtomicExchange(01b10D00D00E",
+ "imageAtomicExchange(01G20D00D00E",
+ "imageAtomicExchange(01R20D00D00E",
+ "imageAtomicExchange(01c20D00D00E",
+ "imageAtomicExchange(00z10D00D",
+ "imageAtomicExchange(01K10D00D",
+ "imageAtomicExchange(01V10D00D",
+ "imageAtomicExchange(01A20D00D",
+ "imageAtomicExchange(01L20D00D",
+ "imageAtomicExchange(01W20D00D",
+ "imageAtomicExchange(01C20D00D",
+ "imageAtomicExchange(01N20D00D",
+ "imageAtomicExchange(01Y20D00D",
+ "imageAtomicExchange(01J00D00D",
+ "imageAtomicExchange(01U00D00D",
+ "imageAtomicExchange(01f00D00D",
+ "imageAtomicExchange(01B20D00D",
+ "imageAtomicExchange(01M20D00D",
+ "imageAtomicExchange(01X20D00D",
+ "imageAtomicExchange(01H20D00D",
+ "imageAtomicExchange(01S20D00D",
+ "imageAtomicExchange(01d20D00D",
+ "imageAtomicExchange(01D00D00D",
+ "imageAtomicExchange(01O00D00D",
+ "imageAtomicExchange(01Z00D00D",
+ "imageAtomicExchange(01E10D00D",
+ "imageAtomicExchange(01P10D00D",
+ "imageAtomicExchange(01a10D00D",
+ "imageAtomicExchange(01I10D00D",
+ "imageAtomicExchange(01T10D00D",
+ "imageAtomicExchange(01e10D00D",
+ "imageAtomicExchange(01F10D00D00D",
+ "imageAtomicExchange(01Q10D00D00D",
+ "imageAtomicExchange(01b10D00D00D",
+ "imageAtomicExchange(01G20D00D00D",
+ "imageAtomicExchange(01R20D00D00D",
+ "imageAtomicExchange(01c20D00D00D",
+ "imageAtomicExchange(00z10D00B",
+ "imageAtomicExchange(01K10D00B",
+ "imageAtomicExchange(01V10D00B",
+ "imageAtomicExchange(01A20D00B",
+ "imageAtomicExchange(01L20D00B",
+ "imageAtomicExchange(01W20D00B",
+ "imageAtomicExchange(01C20D00B",
+ "imageAtomicExchange(01N20D00B",
+ "imageAtomicExchange(01Y20D00B",
+ "imageAtomicExchange(01J00D00B",
+ "imageAtomicExchange(01U00D00B",
+ "imageAtomicExchange(01f00D00B",
+ "imageAtomicExchange(01B20D00B",
+ "imageAtomicExchange(01M20D00B",
+ "imageAtomicExchange(01X20D00B",
+ "imageAtomicExchange(01H20D00B",
+ "imageAtomicExchange(01S20D00B",
+ "imageAtomicExchange(01d20D00B",
+ "imageAtomicExchange(01D00D00B",
+ "imageAtomicExchange(01O00D00B",
+ "imageAtomicExchange(01Z00D00B",
+ "imageAtomicExchange(01E10D00B",
+ "imageAtomicExchange(01P10D00B",
+ "imageAtomicExchange(01a10D00B",
+ "imageAtomicExchange(01I10D00B",
+ "imageAtomicExchange(01T10D00B",
+ "imageAtomicExchange(01e10D00B",
+ "imageAtomicExchange(01F10D00D00B",
+ "imageAtomicExchange(01Q10D00D00B",
+ "imageAtomicExchange(01b10D00D00B",
+ "imageAtomicExchange(01G20D00D00B",
+ "imageAtomicExchange(01R20D00D00B",
+ "imageAtomicExchange(01c20D00D00B",
+ "imageAtomicCompSwap(00z10D00E00E",
+ "imageAtomicCompSwap(01K10D00E00E",
+ "imageAtomicCompSwap(01V10D00E00E",
+ "imageAtomicCompSwap(01A20D00E00E",
+ "imageAtomicCompSwap(01L20D00E00E",
+ "imageAtomicCompSwap(01W20D00E00E",
+ "imageAtomicCompSwap(01C20D00E00E",
+ "imageAtomicCompSwap(01N20D00E00E",
+ "imageAtomicCompSwap(01Y20D00E00E",
+ "imageAtomicCompSwap(01J00D00E00E",
+ "imageAtomicCompSwap(01U00D00E00E",
+ "imageAtomicCompSwap(01f00D00E00E",
+ "imageAtomicCompSwap(01B20D00E00E",
+ "imageAtomicCompSwap(01M20D00E00E",
+ "imageAtomicCompSwap(01X20D00E00E",
+ "imageAtomicCompSwap(01H20D00E00E",
+ "imageAtomicCompSwap(01S20D00E00E",
+ "imageAtomicCompSwap(01d20D00E00E",
+ "imageAtomicCompSwap(01D00D00E00E",
+ "imageAtomicCompSwap(01O00D00E00E",
+ "imageAtomicCompSwap(01Z00D00E00E",
+ "imageAtomicCompSwap(01E10D00E00E",
+ "imageAtomicCompSwap(01P10D00E00E",
+ "imageAtomicCompSwap(01a10D00E00E",
+ "imageAtomicCompSwap(01I10D00E00E",
+ "imageAtomicCompSwap(01T10D00E00E",
+ "imageAtomicCompSwap(01e10D00E00E",
+ "imageAtomicCompSwap(01F10D00D00E00E",
+ "imageAtomicCompSwap(01Q10D00D00E00E",
+ "imageAtomicCompSwap(01b10D00D00E00E",
+ "imageAtomicCompSwap(01G20D00D00E00E",
+ "imageAtomicCompSwap(01R20D00D00E00E",
+ "imageAtomicCompSwap(01c20D00D00E00E",
+ "imageAtomicCompSwap(00z10D00D00D",
+ "imageAtomicCompSwap(01K10D00D00D",
+ "imageAtomicCompSwap(01V10D00D00D",
+ "imageAtomicCompSwap(01A20D00D00D",
+ "imageAtomicCompSwap(01L20D00D00D",
+ "imageAtomicCompSwap(01W20D00D00D",
+ "imageAtomicCompSwap(01C20D00D00D",
+ "imageAtomicCompSwap(01N20D00D00D",
+ "imageAtomicCompSwap(01Y20D00D00D",
+ "imageAtomicCompSwap(01J00D00D00D",
+ "imageAtomicCompSwap(01U00D00D00D",
+ "imageAtomicCompSwap(01f00D00D00D",
+ "imageAtomicCompSwap(01B20D00D00D",
+ "imageAtomicCompSwap(01M20D00D00D",
+ "imageAtomicCompSwap(01X20D00D00D",
+ "imageAtomicCompSwap(01H20D00D00D",
+ "imageAtomicCompSwap(01S20D00D00D",
+ "imageAtomicCompSwap(01d20D00D00D",
+ "imageAtomicCompSwap(01D00D00D00D",
+ "imageAtomicCompSwap(01O00D00D00D",
+ "imageAtomicCompSwap(01Z00D00D00D",
+ "imageAtomicCompSwap(01E10D00D00D",
+ "imageAtomicCompSwap(01P10D00D00D",
+ "imageAtomicCompSwap(01a10D00D00D",
+ "imageAtomicCompSwap(01I10D00D00D",
+ "imageAtomicCompSwap(01T10D00D00D",
+ "imageAtomicCompSwap(01e10D00D00D",
+ "imageAtomicCompSwap(01F10D00D00D00D",
+ "imageAtomicCompSwap(01Q10D00D00D00D",
+ "imageAtomicCompSwap(01b10D00D00D00D",
+ "imageAtomicCompSwap(01G20D00D00D00D",
+ "imageAtomicCompSwap(01R20D00D00D00D",
+ "imageAtomicCompSwap(01c20D00D00D00D",
+ "pixelLocalLoadANGLE(01g",
+ "pixelLocalLoadANGLE(01h",
+ "pixelLocalLoadANGLE(01i",
+ "pixelLocalStoreANGLE(01g30B",
+ "pixelLocalStoreANGLE(01h30D",
+ "pixelLocalStoreANGLE(01i30E",
+ "beginInvocationInterlockNV(",
+ "endInvocationInterlockNV(",
+ "beginFragmentShaderOrderingINTEL(",
+ "beginInvocationInterlockARB(",
+ "endInvocationInterlockARB(",
+ "memoryBarrier(",
+ "memoryBarrierAtomicCounter(",
+ "memoryBarrierBuffer(",
+ "memoryBarrierImage(",
+ "barrier(",
+ "memoryBarrierShared(",
+ "groupMemoryBarrier(",
+ "EmitVertex(",
+ "EndPrimitive(",
+ "subpassLoad(01j",
+ "subpassLoad(01k",
+ "subpassLoad(01l",
+ "subpassLoad(01m00D",
+ "subpassLoad(01n00D",
+ "subpassLoad(01o00D",
+ "gl_DepthRangeParameters",
+ "gl_DepthRange",
+ "gl_NumSamples",
+ "gl_MaxVertexAttribs",
+ "gl_MaxVertexUniformVectors",
+ "gl_MaxVertexTextureImageUnits",
+ "gl_MaxCombinedTextureImageUnits",
+ "gl_MaxTextureImageUnits",
+ "gl_MaxFragmentUniformVectors",
+ "gl_MaxVaryingVectors",
+ "gl_MaxDrawBuffers",
+ "gl_MaxDualSourceDrawBuffersEXT",
+ "gl_MaxVertexOutputVectors",
+ "gl_MaxFragmentInputVectors",
+ "gl_MinProgramTexelOffset",
+ "gl_MaxProgramTexelOffset",
+ "gl_MaxImageUnits",
+ "gl_MaxVertexImageUniforms",
+ "gl_MaxFragmentImageUniforms",
+ "gl_MaxComputeImageUniforms",
+ "gl_MaxCombinedImageUniforms",
+ "gl_MaxCombinedShaderOutputResources",
+ "gl_MaxComputeWorkGroupCount",
+ "gl_MaxComputeWorkGroupSize",
+ "gl_MaxComputeUniformComponents",
+ "gl_MaxComputeTextureImageUnits",
+ "gl_MaxComputeAtomicCounters",
+ "gl_MaxComputeAtomicCounterBuffers",
+ "gl_MaxVertexAtomicCounters",
+ "gl_MaxFragmentAtomicCounters",
+ "gl_MaxCombinedAtomicCounters",
+ "gl_MaxAtomicCounterBindings",
+ "gl_MaxVertexAtomicCounterBuffers",
+ "gl_MaxFragmentAtomicCounterBuffers",
+ "gl_MaxCombinedAtomicCounterBuffers",
+ "gl_MaxAtomicCounterBufferSize",
+ "gl_MaxGeometryInputComponents",
+ "gl_MaxGeometryOutputComponents",
+ "gl_MaxGeometryImageUniforms",
+ "gl_MaxGeometryTextureImageUnits",
+ "gl_MaxGeometryOutputVertices",
+ "gl_MaxGeometryTotalOutputComponents",
+ "gl_MaxGeometryUniformComponents",
+ "gl_MaxGeometryAtomicCounters",
+ "gl_MaxGeometryAtomicCounterBuffers",
+ "gl_MaxTessControlInputComponents",
+ "gl_MaxTessControlOutputComponents",
+ "gl_MaxTessControlTextureImageUnits",
+ "gl_MaxTessControlUniformComponents",
+ "gl_MaxTessControlTotalOutputComponents",
+ "gl_MaxTessControlImageUniforms",
+ "gl_MaxTessControlAtomicCounters",
+ "gl_MaxTessControlAtomicCounterBuffers",
+ "gl_MaxTessPatchComponents",
+ "gl_MaxPatchVertices",
+ "gl_MaxTessGenLevel",
+ "gl_MaxTessEvaluationInputComponents",
+ "gl_MaxTessEvaluationOutputComponents",
+ "gl_MaxTessEvaluationTextureImageUnits",
+ "gl_MaxTessEvaluationUniformComponents",
+ "gl_MaxTessEvaluationImageUniforms",
+ "gl_MaxTessEvaluationAtomicCounters",
+ "gl_MaxTessEvaluationAtomicCounterBuffers",
+ "gl_MaxSamples",
+ "gl_MaxClipDistances",
+ "gl_MaxCullDistances",
+ "gl_MaxCombinedClipAndCullDistances",
+ "gl_FragCoord",
+ "gl_FrontFacing",
+ "gl_PointCoord",
+ "gl_FragColor",
+ "gl_FragData",
+ "gl_FragDepth",
+ "gl_HelperInvocation",
+ "gl_SecondaryFragColorEXT",
+ "gl_SecondaryFragDataEXT",
+ "gl_FragDepthEXT",
+ "gl_LastFragData",
+ "gl_LastFragColor",
+ "gl_LastFragColorARM",
+ "gl_PrimitiveID",
+ "gl_Layer",
+ "gl_SampleID",
+ "gl_SamplePosition",
+ "gl_SampleMaskIn",
+ "gl_SampleMask",
+ "gl_CullDistance",
+ "gl_ClipDistance",
+ "gl_Position",
+ "gl_PointSize",
+ "gl_InstanceID",
+ "",
+ "gl_VertexID",
+ "",
+ "",
+ "gl_DrawID",
+ "gl_BaseVertex",
+ "gl_BaseInstance",
+ "angle_BaseVertex",
+ "angle_BaseInstance",
+ "gl_NumWorkGroups",
+ "gl_WorkGroupSize",
+ "gl_WorkGroupID",
+ "gl_LocalInvocationID",
+ "gl_GlobalInvocationID",
+ "gl_LocalInvocationIndex",
+ "gl_PrimitiveIDIn",
+ "gl_InvocationID",
+ "gl_PerVertex",
+ "gl_in",
+ "gl_PatchVerticesIn",
+ "gl_TessLevelOuter",
+ "gl_TessLevelInner",
+ "gl_out",
+ "gl_BoundingBox",
+ "gl_BoundingBoxEXT",
+ "gl_BoundingBoxOES",
+ "gl_TessCoord",
+ "gl_ViewID_OVR"};
+
+// Flat array of offsets from a symbol into the rules table.
+constexpr uint16_t kMangledOffsets[] = {
+ 0, // radians_00B
+ 1, // radians_10B
+ 2, // radians_20B
+ 3, // radians_30B
+ 4, // degrees_00B
+ 5, // degrees_10B
+ 6, // degrees_20B
+ 7, // degrees_30B
+ 8, // sin_00B
+ 9, // sin_10B
+ 10, // sin_20B
+ 11, // sin_30B
+ 12, // cos_00B
+ 13, // cos_10B
+ 14, // cos_20B
+ 15, // cos_30B
+ 16, // tan_00B
+ 17, // tan_10B
+ 18, // tan_20B
+ 19, // tan_30B
+ 20, // asin_00B
+ 21, // asin_10B
+ 22, // asin_20B
+ 23, // asin_30B
+ 24, // acos_00B
+ 25, // acos_10B
+ 26, // acos_20B
+ 27, // acos_30B
+ 28, // atan_00B00B
+ 29, // atan_10B10B
+ 30, // atan_20B20B
+ 31, // atan_30B30B
+ 32, // atan_00B
+ 33, // atan_10B
+ 34, // atan_20B
+ 35, // atan_30B
+ 36, // sinh_00B
+ 37, // sinh_10B
+ 38, // sinh_20B
+ 39, // sinh_30B
+ 40, // cosh_00B
+ 41, // cosh_10B
+ 42, // cosh_20B
+ 43, // cosh_30B
+ 44, // tanh_00B
+ 45, // tanh_10B
+ 46, // tanh_20B
+ 47, // tanh_30B
+ 48, // asinh_00B
+ 49, // asinh_10B
+ 50, // asinh_20B
+ 51, // asinh_30B
+ 52, // acosh_00B
+ 53, // acosh_10B
+ 54, // acosh_20B
+ 55, // acosh_30B
+ 56, // atanh_00B
+ 57, // atanh_10B
+ 58, // atanh_20B
+ 59, // atanh_30B
+ 60, // pow_00B00B
+ 61, // pow_10B10B
+ 62, // pow_20B20B
+ 63, // pow_30B30B
+ 64, // exp_00B
+ 65, // exp_10B
+ 66, // exp_20B
+ 67, // exp_30B
+ 68, // log_00B
+ 69, // log_10B
+ 70, // log_20B
+ 71, // log_30B
+ 72, // exp2_00B
+ 73, // exp2_10B
+ 74, // exp2_20B
+ 75, // exp2_30B
+ 76, // log2_00B
+ 77, // log2_10B
+ 78, // log2_20B
+ 79, // log2_30B
+ 80, // sqrt_00B
+ 81, // sqrt_10B
+ 82, // sqrt_20B
+ 83, // sqrt_30B
+ 84, // inversesqrt_00B
+ 85, // inversesqrt_10B
+ 86, // inversesqrt_20B
+ 87, // inversesqrt_30B
+ 88, // abs_00B
+ 89, // abs_10B
+ 90, // abs_20B
+ 91, // abs_30B
+ 92, // abs_00D
+ 93, // abs_10D
+ 94, // abs_20D
+ 95, // abs_30D
+ 96, // sign_00B
+ 97, // sign_10B
+ 98, // sign_20B
+ 99, // sign_30B
+ 100, // sign_00D
+ 101, // sign_10D
+ 102, // sign_20D
+ 103, // sign_30D
+ 104, // floor_00B
+ 105, // floor_10B
+ 106, // floor_20B
+ 107, // floor_30B
+ 108, // trunc_00B
+ 109, // trunc_10B
+ 110, // trunc_20B
+ 111, // trunc_30B
+ 112, // round_00B
+ 113, // round_10B
+ 114, // round_20B
+ 115, // round_30B
+ 116, // roundEven_00B
+ 117, // roundEven_10B
+ 118, // roundEven_20B
+ 119, // roundEven_30B
+ 120, // ceil_00B
+ 121, // ceil_10B
+ 122, // ceil_20B
+ 123, // ceil_30B
+ 124, // fract_00B
+ 125, // fract_10B
+ 126, // fract_20B
+ 127, // fract_30B
+ 128, // mod_00B00B
+ 129, // mod_10B00B
+ 130, // mod_20B00B
+ 131, // mod_30B00B
+ 132, // mod_10B10B
+ 133, // mod_20B20B
+ 134, // mod_30B30B
+ 135, // min_00B00B
+ 136, // min_10B00B
+ 137, // min_20B00B
+ 138, // min_30B00B
+ 139, // min_10B10B
+ 140, // min_20B20B
+ 141, // min_30B30B
+ 142, // min_00D00D
+ 143, // min_10D10D
+ 144, // min_20D20D
+ 145, // min_30D30D
+ 146, // min_10D00D
+ 147, // min_20D00D
+ 148, // min_30D00D
+ 149, // min_00E00E
+ 150, // min_10E10E
+ 151, // min_20E20E
+ 152, // min_30E30E
+ 153, // min_10E00E
+ 154, // min_20E00E
+ 155, // min_30E00E
+ 156, // max_00B00B
+ 157, // max_10B00B
+ 158, // max_20B00B
+ 159, // max_30B00B
+ 160, // max_10B10B
+ 161, // max_20B20B
+ 162, // max_30B30B
+ 163, // max_00D00D
+ 164, // max_10D10D
+ 165, // max_20D20D
+ 166, // max_30D30D
+ 167, // max_10D00D
+ 168, // max_20D00D
+ 169, // max_30D00D
+ 170, // max_00E00E
+ 171, // max_10E10E
+ 172, // max_20E20E
+ 173, // max_30E30E
+ 174, // max_10E00E
+ 175, // max_20E00E
+ 176, // max_30E00E
+ 177, // clamp_00B00B00B
+ 178, // clamp_10B00B00B
+ 179, // clamp_20B00B00B
+ 180, // clamp_30B00B00B
+ 181, // clamp_10B10B10B
+ 182, // clamp_20B20B20B
+ 183, // clamp_30B30B30B
+ 184, // clamp_00D00D00D
+ 185, // clamp_10D00D00D
+ 186, // clamp_20D00D00D
+ 187, // clamp_30D00D00D
+ 188, // clamp_10D10D10D
+ 189, // clamp_20D20D20D
+ 190, // clamp_30D30D30D
+ 191, // clamp_00E00E00E
+ 192, // clamp_10E00E00E
+ 193, // clamp_20E00E00E
+ 194, // clamp_30E00E00E
+ 195, // clamp_10E10E10E
+ 196, // clamp_20E20E20E
+ 197, // clamp_30E30E30E
+ 198, // mix_00B00B00B
+ 199, // mix_10B10B00B
+ 200, // mix_20B20B00B
+ 201, // mix_30B30B00B
+ 202, // mix_10B10B10B
+ 203, // mix_20B20B20B
+ 204, // mix_30B30B30B
+ 205, // mix_00B00B00F
+ 206, // mix_10B10B10F
+ 207, // mix_20B20B20F
+ 208, // mix_30B30B30F
+ 209, // mix_00D00D00F
+ 210, // mix_10D10D10F
+ 211, // mix_20D20D20F
+ 212, // mix_30D30D30F
+ 213, // mix_00E00E00F
+ 214, // mix_10E10E10F
+ 215, // mix_20E20E20F
+ 216, // mix_30E30E30F
+ 217, // mix_00F00F00F
+ 218, // mix_10F10F10F
+ 219, // mix_20F20F20F
+ 220, // mix_30F30F30F
+ 221, // step_00B00B
+ 222, // step_10B10B
+ 223, // step_20B20B
+ 224, // step_30B30B
+ 225, // step_00B10B
+ 226, // step_00B20B
+ 227, // step_00B30B
+ 228, // smoothstep_00B00B00B
+ 229, // smoothstep_10B10B10B
+ 230, // smoothstep_20B20B20B
+ 231, // smoothstep_30B30B30B
+ 232, // smoothstep_00B00B10B
+ 233, // smoothstep_00B00B20B
+ 234, // smoothstep_00B00B30B
+ 235, // modf_00B00B
+ 236, // modf_10B10B
+ 237, // modf_20B20B
+ 238, // modf_30B30B
+ 239, // isnan_00B
+ 240, // isnan_10B
+ 241, // isnan_20B
+ 242, // isnan_30B
+ 243, // isinf_00B
+ 244, // isinf_10B
+ 245, // isinf_20B
+ 246, // isinf_30B
+ 247, // floatBitsToInt_00B
+ 248, // floatBitsToInt_10B
+ 249, // floatBitsToInt_20B
+ 250, // floatBitsToInt_30B
+ 251, // floatBitsToUint_00B
+ 252, // floatBitsToUint_10B
+ 253, // floatBitsToUint_20B
+ 254, // floatBitsToUint_30B
+ 255, // intBitsToFloat_00D
+ 256, // intBitsToFloat_10D
+ 257, // intBitsToFloat_20D
+ 258, // intBitsToFloat_30D
+ 259, // uintBitsToFloat_00E
+ 260, // uintBitsToFloat_10E
+ 261, // uintBitsToFloat_20E
+ 262, // uintBitsToFloat_30E
+ 263, // fma_00B00B00B
+ 265, // fma_10B10B10B
+ 267, // fma_20B20B20B
+ 269, // fma_30B30B30B
+ 271, // frexp_00B00D
+ 272, // frexp_10B10D
+ 273, // frexp_20B20D
+ 274, // frexp_30B30D
+ 275, // ldexp_00B00D
+ 276, // ldexp_10B10D
+ 277, // ldexp_20B20D
+ 278, // ldexp_30B30D
+ 279, // packSnorm2x16_10B
+ 280, // packHalf2x16_10B
+ 281, // unpackSnorm2x16_00E
+ 282, // unpackHalf2x16_00E
+ 283, // packUnorm2x16_10B
+ 284, // unpackUnorm2x16_00E
+ 285, // packUnorm4x8_30B
+ 286, // packSnorm4x8_30B
+ 287, // unpackUnorm4x8_00E
+ 288, // unpackSnorm4x8_00E
+ 289, // length_00B
+ 290, // length_10B
+ 291, // length_20B
+ 292, // length_30B
+ 293, // distance_00B00B
+ 294, // distance_10B10B
+ 295, // distance_20B20B
+ 296, // distance_30B30B
+ 297, // dot_00B00B
+ 298, // dot_10B10B
+ 299, // dot_20B20B
+ 300, // dot_30B30B
+ 301, // cross_20B20B
+ 302, // normalize_00B
+ 303, // normalize_10B
+ 304, // normalize_20B
+ 305, // normalize_30B
+ 306, // faceforward_00B00B00B
+ 307, // faceforward_10B10B10B
+ 308, // faceforward_20B20B20B
+ 309, // faceforward_30B30B30B
+ 310, // reflect_00B00B
+ 311, // reflect_10B10B
+ 312, // reflect_20B20B
+ 313, // reflect_30B30B
+ 314, // refract_00B00B00B
+ 315, // refract_10B10B00B
+ 316, // refract_20B20B00B
+ 317, // refract_30B30B00B
+ 318, // matrixCompMult_50B50B
+ 319, // matrixCompMult_A0BA0B
+ 320, // matrixCompMult_F0BF0B
+ 321, // matrixCompMult_90B90B
+ 322, // matrixCompMult_60B60B
+ 323, // matrixCompMult_D0BD0B
+ 324, // matrixCompMult_70B70B
+ 325, // matrixCompMult_E0BE0B
+ 326, // matrixCompMult_B0BB0B
+ 327, // outerProduct_10B10B
+ 328, // outerProduct_20B20B
+ 329, // outerProduct_30B30B
+ 330, // outerProduct_20B10B
+ 331, // outerProduct_10B20B
+ 332, // outerProduct_30B10B
+ 333, // outerProduct_10B30B
+ 334, // outerProduct_30B20B
+ 335, // outerProduct_20B30B
+ 336, // transpose_50B
+ 337, // transpose_A0B
+ 338, // transpose_F0B
+ 339, // transpose_60B
+ 340, // transpose_90B
+ 341, // transpose_70B
+ 342, // transpose_D0B
+ 343, // transpose_B0B
+ 344, // transpose_E0B
+ 345, // determinant_50B
+ 346, // determinant_A0B
+ 347, // determinant_F0B
+ 348, // inverse_50B
+ 349, // inverse_A0B
+ 350, // inverse_F0B
+ 351, // lessThan_10B10B
+ 352, // lessThan_20B20B
+ 353, // lessThan_30B30B
+ 354, // lessThan_10D10D
+ 355, // lessThan_20D20D
+ 356, // lessThan_30D30D
+ 357, // lessThan_10E10E
+ 358, // lessThan_20E20E
+ 359, // lessThan_30E30E
+ 360, // lessThanEqual_10B10B
+ 361, // lessThanEqual_20B20B
+ 362, // lessThanEqual_30B30B
+ 363, // lessThanEqual_10D10D
+ 364, // lessThanEqual_20D20D
+ 365, // lessThanEqual_30D30D
+ 366, // lessThanEqual_10E10E
+ 367, // lessThanEqual_20E20E
+ 368, // lessThanEqual_30E30E
+ 369, // greaterThan_10B10B
+ 370, // greaterThan_20B20B
+ 371, // greaterThan_30B30B
+ 372, // greaterThan_10D10D
+ 373, // greaterThan_20D20D
+ 374, // greaterThan_30D30D
+ 375, // greaterThan_10E10E
+ 376, // greaterThan_20E20E
+ 377, // greaterThan_30E30E
+ 378, // greaterThanEqual_10B10B
+ 379, // greaterThanEqual_20B20B
+ 380, // greaterThanEqual_30B30B
+ 381, // greaterThanEqual_10D10D
+ 382, // greaterThanEqual_20D20D
+ 383, // greaterThanEqual_30D30D
+ 384, // greaterThanEqual_10E10E
+ 385, // greaterThanEqual_20E20E
+ 386, // greaterThanEqual_30E30E
+ 387, // equal_10B10B
+ 388, // equal_20B20B
+ 389, // equal_30B30B
+ 390, // equal_10D10D
+ 391, // equal_20D20D
+ 392, // equal_30D30D
+ 393, // equal_10E10E
+ 394, // equal_20E20E
+ 395, // equal_30E30E
+ 396, // equal_10F10F
+ 397, // equal_20F20F
+ 398, // equal_30F30F
+ 399, // notEqual_10B10B
+ 400, // notEqual_20B20B
+ 401, // notEqual_30B30B
+ 402, // notEqual_10D10D
+ 403, // notEqual_20D20D
+ 404, // notEqual_30D30D
+ 405, // notEqual_10E10E
+ 406, // notEqual_20E20E
+ 407, // notEqual_30E30E
+ 408, // notEqual_10F10F
+ 409, // notEqual_20F20F
+ 410, // notEqual_30F30F
+ 411, // any_10F
+ 412, // any_20F
+ 413, // any_30F
+ 414, // all_10F
+ 415, // all_20F
+ 416, // all_30F
+ 417, // not_10F
+ 418, // not_20F
+ 419, // not_30F
+ 420, // bitfieldExtract_00D00D00D
+ 421, // bitfieldExtract_10D00D00D
+ 422, // bitfieldExtract_20D00D00D
+ 423, // bitfieldExtract_30D00D00D
+ 424, // bitfieldExtract_00E00D00D
+ 425, // bitfieldExtract_10E00D00D
+ 426, // bitfieldExtract_20E00D00D
+ 427, // bitfieldExtract_30E00D00D
+ 428, // bitfieldInsert_00D00D00D00D
+ 429, // bitfieldInsert_10D10D00D00D
+ 430, // bitfieldInsert_20D20D00D00D
+ 431, // bitfieldInsert_30D30D00D00D
+ 432, // bitfieldInsert_00E00E00D00D
+ 433, // bitfieldInsert_10E10E00D00D
+ 434, // bitfieldInsert_20E20E00D00D
+ 435, // bitfieldInsert_30E30E00D00D
+ 436, // bitfieldReverse_00D
+ 437, // bitfieldReverse_10D
+ 438, // bitfieldReverse_20D
+ 439, // bitfieldReverse_30D
+ 440, // bitfieldReverse_00E
+ 441, // bitfieldReverse_10E
+ 442, // bitfieldReverse_20E
+ 443, // bitfieldReverse_30E
+ 444, // bitCount_00D
+ 445, // bitCount_10D
+ 446, // bitCount_20D
+ 447, // bitCount_30D
+ 448, // bitCount_00E
+ 449, // bitCount_10E
+ 450, // bitCount_20E
+ 451, // bitCount_30E
+ 452, // findLSB_00D
+ 453, // findLSB_10D
+ 454, // findLSB_20D
+ 455, // findLSB_30D
+ 456, // findLSB_00E
+ 457, // findLSB_10E
+ 458, // findLSB_20E
+ 459, // findLSB_30E
+ 460, // findMSB_00D
+ 461, // findMSB_10D
+ 462, // findMSB_20D
+ 463, // findMSB_30D
+ 464, // findMSB_00E
+ 465, // findMSB_10E
+ 466, // findMSB_20E
+ 467, // findMSB_30E
+ 468, // uaddCarry_00E00E00E
+ 469, // uaddCarry_10E10E10E
+ 470, // uaddCarry_20E20E20E
+ 471, // uaddCarry_30E30E30E
+ 472, // usubBorrow_00E00E00E
+ 473, // usubBorrow_10E10E10E
+ 474, // usubBorrow_20E20E20E
+ 475, // usubBorrow_30E30E30E
+ 476, // umulExtended_00E00E00E00E
+ 477, // umulExtended_10E10E10E10E
+ 478, // umulExtended_20E20E20E20E
+ 479, // umulExtended_30E30E30E30E
+ 480, // imulExtended_00D00D00D00D
+ 481, // imulExtended_10D10D10D10D
+ 482, // imulExtended_20D20D20D20D
+ 483, // imulExtended_30D30D30D30D
+ 484, // texture2D_00I10B
+ 485, // texture2DProj_00I20B
+ 486, // texture2DProj_00I30B
+ 487, // textureCube_00K20B
+ 488, // texture3D_00J20B
+ 489, // texture3DProj_00J30B
+ 490, // shadow2DEXT_00d20B
+ 491, // shadow2DProjEXT_00d30B
+ 492, // texture2D_00M10B
+ 494, // texture2DProj_00M20B
+ 496, // texture2DProj_00M30B
+ 498, // texture2DRect_00O10B
+ 499, // texture2DRectProj_00O20B
+ 500, // texture2DRectProj_00O30B
+ 501, // texture2DGradEXT_00I10B10B10B
+ 502, // texture2DProjGradEXT_00I20B10B10B
+ 503, // texture2DProjGradEXT_00I30B10B10B
+ 504, // textureCubeGradEXT_00K20B20B20B
+ 505, // textureVideoWEBGL_00y10B
+ 506, // texture2D_00I10B00B
+ 507, // texture2DProj_00I20B00B
+ 508, // texture2DProj_00I30B00B
+ 509, // textureCube_00K20B00B
+ 510, // texture3D_00J20B00B
+ 511, // texture3DProj_00J30B00B
+ 512, // texture3DLod_00J20B00B
+ 513, // texture3DProjLod_00J30B00B
+ 514, // texture2DLod_00I10B00B
+ 515, // texture2DProjLod_00I20B00B
+ 516, // texture2DProjLod_00I30B00B
+ 517, // textureCubeLod_00K20B00B
+ 518, // texture2DLodEXT_00I10B00B
+ 519, // texture2DProjLodEXT_00I20B00B
+ 520, // texture2DProjLodEXT_00I30B00B
+ 521, // textureCubeLodEXT_00K20B00B
+ 522, // texture_00I10B
+ 523, // texture_00R10B
+ 524, // texture_00X10B
+ 525, // texture_00J20B
+ 526, // texture_00S20B
+ 527, // texture_00Y20B
+ 528, // texture_00K20B
+ 529, // texture_00T20B
+ 530, // texture_00Z20B
+ 531, // texture_00L20B
+ 532, // texture_00U20B
+ 533, // texture_00a20B
+ 534, // texture_00d20B
+ 535, // texture_00e30B
+ 536, // texture_00f30B
+ 537, // texture_00k30B
+ 540, // texture_00s30B
+ 543, // texture_00x30B
+ 546, // texture_00l30B00B
+ 549, // texture_00M10B
+ 550, // texture_00N10B
+ 551, // texture_00O10B
+ 552, // texture_00y10B
+ 553, // textureProj_00I20B
+ 554, // textureProj_00R20B
+ 555, // textureProj_00X20B
+ 556, // textureProj_00I30B
+ 557, // textureProj_00R30B
+ 558, // textureProj_00X30B
+ 559, // textureProj_00J30B
+ 560, // textureProj_00S30B
+ 561, // textureProj_00Y30B
+ 562, // textureProj_00d30B
+ 563, // textureProj_00M20B
+ 564, // textureProj_00M30B
+ 565, // textureProj_00N20B
+ 566, // textureProj_00N30B
+ 567, // textureProj_00O20B
+ 568, // textureProj_00O30B
+ 569, // textureLod_00I10B00B
+ 570, // textureLod_00R10B00B
+ 571, // textureLod_00X10B00B
+ 572, // textureLod_00J20B00B
+ 573, // textureLod_00S20B00B
+ 574, // textureLod_00Y20B00B
+ 575, // textureLod_00K20B00B
+ 576, // textureLod_00T20B00B
+ 577, // textureLod_00Z20B00B
+ 578, // textureLod_00L20B00B
+ 579, // textureLod_00U20B00B
+ 580, // textureLod_00a20B00B
+ 581, // textureLod_00d20B00B
+ 582, // textureLod_00k30B00B
+ 585, // textureLod_00s30B00B
+ 588, // textureLod_00x30B00B
+ 591, // textureSize_00I00D
+ 592, // textureSize_00R00D
+ 593, // textureSize_00X00D
+ 594, // textureSize_00J00D
+ 595, // textureSize_00S00D
+ 596, // textureSize_00Y00D
+ 597, // textureSize_00K00D
+ 598, // textureSize_00T00D
+ 599, // textureSize_00Z00D
+ 600, // textureSize_00L00D
+ 601, // textureSize_00U00D
+ 602, // textureSize_00a00D
+ 603, // textureSize_00d00D
+ 604, // textureSize_00e00D
+ 605, // textureSize_00f00D
+ 606, // textureSize_00k00D
+ 609, // textureSize_00s00D
+ 612, // textureSize_00x00D
+ 615, // textureSize_00l00D
+ 618, // textureSize_00j
+ 621, // textureSize_00r
+ 624, // textureSize_00w
+ 627, // textureSize_00P
+ 629, // textureSize_00V
+ 631, // textureSize_00b
+ 633, // textureSize_00Q
+ 635, // textureSize_00W
+ 637, // textureSize_00c
+ 639, // textureSize_00M00D
+ 640, // textureSize_00N00D
+ 641, // textureProjLod_00I20B00B
+ 642, // textureProjLod_00R20B00B
+ 643, // textureProjLod_00X20B00B
+ 644, // textureProjLod_00I30B00B
+ 645, // textureProjLod_00R30B00B
+ 646, // textureProjLod_00X30B00B
+ 647, // textureProjLod_00J30B00B
+ 648, // textureProjLod_00S30B00B
+ 649, // textureProjLod_00Y30B00B
+ 650, // textureProjLod_00d30B00B
+ 651, // texelFetch_00I10D00D
+ 652, // texelFetch_00R10D00D
+ 653, // texelFetch_00X10D00D
+ 654, // texelFetch_00J20D00D
+ 655, // texelFetch_00S20D00D
+ 656, // texelFetch_00Y20D00D
+ 657, // texelFetch_00L20D00D
+ 658, // texelFetch_00U20D00D
+ 659, // texelFetch_00a20D00D
+ 660, // texelFetch_00j00D
+ 663, // texelFetch_00r00D
+ 666, // texelFetch_00w00D
+ 669, // texelFetch_00P10D00D
+ 671, // texelFetch_00V10D00D
+ 673, // texelFetch_00b10D00D
+ 675, // texelFetch_00Q20D00D
+ 677, // texelFetch_00W20D00D
+ 679, // texelFetch_00c20D00D
+ 681, // texelFetch_00M10D00D
+ 682, // texelFetch_00N10D00D
+ 683, // textureGrad_00I10B10B10B
+ 684, // textureGrad_00R10B10B10B
+ 685, // textureGrad_00X10B10B10B
+ 686, // textureGrad_00J20B20B20B
+ 687, // textureGrad_00S20B20B20B
+ 688, // textureGrad_00Y20B20B20B
+ 689, // textureGrad_00K20B20B20B
+ 690, // textureGrad_00T20B20B20B
+ 691, // textureGrad_00Z20B20B20B
+ 692, // textureGrad_00d20B10B10B
+ 693, // textureGrad_00e30B20B20B
+ 694, // textureGrad_00L20B10B10B
+ 695, // textureGrad_00U20B10B10B
+ 696, // textureGrad_00a20B10B10B
+ 697, // textureGrad_00f30B10B10B
+ 698, // textureGrad_00k30B20B20B
+ 701, // textureGrad_00s30B20B20B
+ 704, // textureGrad_00x30B20B20B
+ 707, // textureProjGrad_00I20B10B10B
+ 708, // textureProjGrad_00R20B10B10B
+ 709, // textureProjGrad_00X20B10B10B
+ 710, // textureProjGrad_00I30B10B10B
+ 711, // textureProjGrad_00R30B10B10B
+ 712, // textureProjGrad_00X30B10B10B
+ 713, // textureProjGrad_00J30B20B20B
+ 714, // textureProjGrad_00S30B20B20B
+ 715, // textureProjGrad_00Y30B20B20B
+ 716, // textureProjGrad_00d30B10B10B
+ 717, // texture_00I10B00B
+ 718, // texture_00R10B00B
+ 719, // texture_00X10B00B
+ 720, // texture_00J20B00B
+ 721, // texture_00S20B00B
+ 722, // texture_00Y20B00B
+ 723, // texture_00K20B00B
+ 724, // texture_00T20B00B
+ 725, // texture_00Z20B00B
+ 726, // texture_00L20B00B
+ 727, // texture_00U20B00B
+ 728, // texture_00a20B00B
+ 729, // textureProj_00I20B00B
+ 730, // textureProj_00R20B00B
+ 731, // textureProj_00X20B00B
+ 732, // textureProj_00I30B00B
+ 733, // textureProj_00R30B00B
+ 734, // textureProj_00X30B00B
+ 735, // textureProj_00J30B00B
+ 736, // textureProj_00S30B00B
+ 737, // textureProj_00Y30B00B
+ 738, // texture_00d20B00B
+ 739, // texture_00e30B00B
+ 740, // textureProj_00d30B00B
+ 741, // texture_00k30B00B
+ 744, // texture_00s30B00B
+ 747, // texture_00x30B00B
+ 750, // texture_00M10B00B
+ 751, // textureProj_00M20B00B
+ 752, // textureProj_00M30B00B
+ 753, // texture_00N10B00B
+ 754, // textureProj_00N20B00B
+ 755, // textureProj_00N30B00B
+ 756, // textureOffset_00I10B10D
+ 757, // textureOffset_00R10B10D
+ 758, // textureOffset_00X10B10D
+ 759, // textureOffset_00J20B20D
+ 760, // textureOffset_00S20B20D
+ 761, // textureOffset_00Y20B20D
+ 762, // textureOffset_00d20B10D
+ 763, // textureOffset_00L20B10D
+ 764, // textureOffset_00U20B10D
+ 765, // textureOffset_00a20B10D
+ 766, // textureProjOffset_00I20B10D
+ 767, // textureProjOffset_00R20B10D
+ 768, // textureProjOffset_00X20B10D
+ 769, // textureProjOffset_00I30B10D
+ 770, // textureProjOffset_00R30B10D
+ 771, // textureProjOffset_00X30B10D
+ 772, // textureProjOffset_00J30B20D
+ 773, // textureProjOffset_00S30B20D
+ 774, // textureProjOffset_00Y30B20D
+ 775, // textureProjOffset_00d30B10D
+ 776, // textureLodOffset_00I10B00B10D
+ 777, // textureLodOffset_00R10B00B10D
+ 778, // textureLodOffset_00X10B00B10D
+ 779, // textureLodOffset_00J20B00B20D
+ 780, // textureLodOffset_00S20B00B20D
+ 781, // textureLodOffset_00Y20B00B20D
+ 782, // textureLodOffset_00d20B00B10D
+ 783, // textureLodOffset_00L20B00B10D
+ 784, // textureLodOffset_00U20B00B10D
+ 785, // textureLodOffset_00a20B00B10D
+ 786, // textureProjLodOffset_00I20B00B10D
+ 787, // textureProjLodOffset_00R20B00B10D
+ 788, // textureProjLodOffset_00X20B00B10D
+ 789, // textureProjLodOffset_00I30B00B10D
+ 790, // textureProjLodOffset_00R30B00B10D
+ 791, // textureProjLodOffset_00X30B00B10D
+ 792, // textureProjLodOffset_00J30B00B20D
+ 793, // textureProjLodOffset_00S30B00B20D
+ 794, // textureProjLodOffset_00Y30B00B20D
+ 795, // textureProjLodOffset_00d30B00B10D
+ 796, // texelFetchOffset_00I10D00D10D
+ 797, // texelFetchOffset_00R10D00D10D
+ 798, // texelFetchOffset_00X10D00D10D
+ 799, // texelFetchOffset_00J20D00D20D
+ 800, // texelFetchOffset_00S20D00D20D
+ 801, // texelFetchOffset_00Y20D00D20D
+ 802, // texelFetchOffset_00L20D00D10D
+ 803, // texelFetchOffset_00U20D00D10D
+ 804, // texelFetchOffset_00a20D00D10D
+ 805, // textureGradOffset_00I10B10B10B10D
+ 806, // textureGradOffset_00R10B10B10B10D
+ 807, // textureGradOffset_00X10B10B10B10D
+ 808, // textureGradOffset_00J20B20B20B20D
+ 809, // textureGradOffset_00S20B20B20B20D
+ 810, // textureGradOffset_00Y20B20B20B20D
+ 811, // textureGradOffset_00d20B10B10B10D
+ 812, // textureGradOffset_00L20B10B10B10D
+ 813, // textureGradOffset_00U20B10B10B10D
+ 814, // textureGradOffset_00a20B10B10B10D
+ 815, // textureGradOffset_00f30B10B10B10D
+ 816, // textureProjGradOffset_00I20B10B10B10D
+ 817, // textureProjGradOffset_00R20B10B10B10D
+ 818, // textureProjGradOffset_00X20B10B10B10D
+ 819, // textureProjGradOffset_00I30B10B10B10D
+ 820, // textureProjGradOffset_00R30B10B10B10D
+ 821, // textureProjGradOffset_00X30B10B10B10D
+ 822, // textureProjGradOffset_00J30B20B20B20D
+ 823, // textureProjGradOffset_00S30B20B20B20D
+ 824, // textureProjGradOffset_00Y30B20B20B20D
+ 825, // textureProjGradOffset_00d30B10B10B10D
+ 826, // textureOffset_00I10B10D00B
+ 827, // textureOffset_00R10B10D00B
+ 828, // textureOffset_00X10B10D00B
+ 829, // textureOffset_00J20B20D00B
+ 830, // textureOffset_00S20B20D00B
+ 831, // textureOffset_00Y20B20D00B
+ 832, // textureOffset_00d20B10D00B
+ 833, // textureOffset_00L20B10D00B
+ 834, // textureOffset_00U20B10D00B
+ 835, // textureOffset_00a20B10D00B
+ 836, // textureProjOffset_00I20B10D00B
+ 837, // textureProjOffset_00R20B10D00B
+ 838, // textureProjOffset_00X20B10D00B
+ 839, // textureProjOffset_00I30B10D00B
+ 840, // textureProjOffset_00R30B10D00B
+ 841, // textureProjOffset_00X30B10D00B
+ 842, // textureProjOffset_00J30B20D00B
+ 843, // textureProjOffset_00S30B20D00B
+ 844, // textureProjOffset_00Y30B20D00B
+ 845, // textureProjOffset_00d30B10D00B
+ 846, // textureGather_00I10B
+ 847, // textureGather_00R10B
+ 848, // textureGather_00X10B
+ 849, // textureGather_00I10B00D
+ 850, // textureGather_00R10B00D
+ 851, // textureGather_00X10B00D
+ 852, // textureGather_00L20B
+ 853, // textureGather_00U20B
+ 854, // textureGather_00a20B
+ 855, // textureGather_00L20B00D
+ 856, // textureGather_00U20B00D
+ 857, // textureGather_00a20B00D
+ 858, // textureGather_00K20B
+ 859, // textureGather_00T20B
+ 860, // textureGather_00Z20B
+ 861, // textureGather_00K20B00D
+ 862, // textureGather_00T20B00D
+ 863, // textureGather_00Z20B00D
+ 864, // textureGather_00k30B
+ 867, // textureGather_00s30B
+ 870, // textureGather_00x30B
+ 873, // textureGather_00k30B00D
+ 876, // textureGather_00s30B00D
+ 879, // textureGather_00x30B00D
+ 882, // textureGather_00l30B00B
+ 885, // textureGather_00d10B
+ 886, // textureGather_00d10B00B
+ 887, // textureGather_00f20B
+ 888, // textureGather_00f20B00B
+ 889, // textureGather_00e20B
+ 890, // textureGather_00e20B00B
+ 891, // textureGatherOffset_00I10B10D
+ 892, // textureGatherOffset_00R10B10D
+ 893, // textureGatherOffset_00X10B10D
+ 894, // textureGatherOffset_00L20B10D
+ 895, // textureGatherOffset_00U20B10D
+ 896, // textureGatherOffset_00a20B10D
+ 897, // textureGatherOffset_00d10B00B10D
+ 898, // textureGatherOffset_00f20B00B10D
+ 899, // textureGatherOffset_00I10B10D00D
+ 900, // textureGatherOffset_00R10B10D00D
+ 901, // textureGatherOffset_00X10B10D00D
+ 902, // textureGatherOffset_00L20B10D00D
+ 903, // textureGatherOffset_00U20B10D00D
+ 904, // textureGatherOffset_00a20B10D00D
+ 905, // textureGatherOffsets_00I10B10Dx4
+ 907, // textureGatherOffsets_00R10B10Dx4
+ 909, // textureGatherOffsets_00X10B10Dx4
+ 911, // textureGatherOffsets_00L20B10Dx4
+ 913, // textureGatherOffsets_00U20B10Dx4
+ 915, // textureGatherOffsets_00a20B10Dx4
+ 917, // textureGatherOffsets_00d10B00B10Dx4
+ 919, // textureGatherOffsets_00f20B00B10Dx4
+ 921, // textureGatherOffsets_00I10B10Dx400D
+ 923, // textureGatherOffsets_00R10B10Dx400D
+ 925, // textureGatherOffsets_00X10B10Dx400D
+ 927, // textureGatherOffsets_00L20B10Dx400D
+ 929, // textureGatherOffsets_00U20B10Dx400D
+ 931, // textureGatherOffsets_00a20B10Dx400D
+ 933, // rgb_2_yuv_20B00H
+ 934, // yuv_2_rgb_20B00H
+ 935, // dFdx_00B
+ 937, // dFdx_10B
+ 939, // dFdx_20B
+ 941, // dFdx_30B
+ 943, // dFdy_00B
+ 945, // dFdy_10B
+ 947, // dFdy_20B
+ 949, // dFdy_30B
+ 951, // fwidth_00B
+ 953, // fwidth_10B
+ 955, // fwidth_20B
+ 957, // fwidth_30B
+ 959, // interpolateAtCentroid_00B
+ 961, // interpolateAtCentroid_10B
+ 963, // interpolateAtCentroid_20B
+ 965, // interpolateAtCentroid_30B
+ 967, // interpolateAtSample_00B00D
+ 969, // interpolateAtSample_10B00D
+ 971, // interpolateAtSample_20B00D
+ 973, // interpolateAtSample_30B00D
+ 975, // interpolateAtOffset_00B10B
+ 977, // interpolateAtOffset_10B10B
+ 979, // interpolateAtOffset_20B10B
+ 981, // interpolateAtOffset_30B10B
+ 983, // atomicCounter_00G
+ 984, // atomicCounterIncrement_00G
+ 985, // atomicCounterDecrement_00G
+ 986, // atomicAdd_00E00E
+ 987, // atomicAdd_00D00D
+ 988, // atomicMin_00E00E
+ 989, // atomicMin_00D00D
+ 990, // atomicMax_00E00E
+ 991, // atomicMax_00D00D
+ 992, // atomicAnd_00E00E
+ 993, // atomicAnd_00D00D
+ 994, // atomicOr_00E00E
+ 995, // atomicOr_00D00D
+ 996, // atomicXor_00E00E
+ 997, // atomicXor_00D00D
+ 998, // atomicExchange_00E00E
+ 999, // atomicExchange_00D00D
+ 1000, // atomicCompSwap_00E00E00E
+ 1001, // atomicCompSwap_00D00D00D
+ 1002, // imageSize_00z
+ 1003, // imageSize_01K
+ 1004, // imageSize_01V
+ 1005, // imageSize_01A
+ 1006, // imageSize_01L
+ 1007, // imageSize_01W
+ 1008, // imageSize_01B
+ 1009, // imageSize_01M
+ 1010, // imageSize_01X
+ 1011, // imageSize_01C
+ 1012, // imageSize_01N
+ 1013, // imageSize_01Y
+ 1014, // imageSize_01H
+ 1017, // imageSize_01S
+ 1020, // imageSize_01d
+ 1023, // imageSize_01J
+ 1026, // imageSize_01U
+ 1029, // imageSize_01f
+ 1032, // imageStore_00z10D30B
+ 1033, // imageStore_01K10D30D
+ 1034, // imageStore_01V10D30E
+ 1035, // imageStore_01A20D30B
+ 1036, // imageStore_01L20D30D
+ 1037, // imageStore_01W20D30E
+ 1038, // imageStore_01B20D30B
+ 1039, // imageStore_01M20D30D
+ 1040, // imageStore_01X20D30E
+ 1041, // imageStore_01C20D30B
+ 1042, // imageStore_01N20D30D
+ 1043, // imageStore_01Y20D30E
+ 1044, // imageStore_01H20D30B
+ 1047, // imageStore_01S20D30D
+ 1050, // imageStore_01d20D30E
+ 1053, // imageStore_01J00D30B
+ 1056, // imageStore_01U00D30D
+ 1059, // imageStore_01f00D30E
+ 1062, // imageLoad_00z10D
+ 1063, // imageLoad_01K10D
+ 1064, // imageLoad_01V10D
+ 1065, // imageLoad_01A20D
+ 1066, // imageLoad_01L20D
+ 1067, // imageLoad_01W20D
+ 1068, // imageLoad_01B20D
+ 1069, // imageLoad_01M20D
+ 1070, // imageLoad_01X20D
+ 1071, // imageLoad_01C20D
+ 1072, // imageLoad_01N20D
+ 1073, // imageLoad_01Y20D
+ 1074, // imageLoad_01H20D
+ 1077, // imageLoad_01S20D
+ 1080, // imageLoad_01d20D
+ 1083, // imageLoad_01J00D
+ 1086, // imageLoad_01U00D
+ 1089, // imageLoad_01f00D
+ 1092, // imageAtomicAdd_00z10D00E
+ 1094, // imageAtomicAdd_01K10D00E
+ 1096, // imageAtomicAdd_01V10D00E
+ 1098, // imageAtomicAdd_01A20D00E
+ 1100, // imageAtomicAdd_01L20D00E
+ 1102, // imageAtomicAdd_01W20D00E
+ 1104, // imageAtomicAdd_01C20D00E
+ 1106, // imageAtomicAdd_01N20D00E
+ 1108, // imageAtomicAdd_01Y20D00E
+ 1110, // imageAtomicAdd_01J00D00E
+ 1112, // imageAtomicAdd_01U00D00E
+ 1114, // imageAtomicAdd_01f00D00E
+ 1116, // imageAtomicAdd_01B20D00E
+ 1118, // imageAtomicAdd_01M20D00E
+ 1120, // imageAtomicAdd_01X20D00E
+ 1122, // imageAtomicAdd_01H20D00E
+ 1124, // imageAtomicAdd_01S20D00E
+ 1126, // imageAtomicAdd_01d20D00E
+ 1128, // imageAtomicAdd_01D00D00E
+ 1130, // imageAtomicAdd_01O00D00E
+ 1132, // imageAtomicAdd_01Z00D00E
+ 1134, // imageAtomicAdd_01E10D00E
+ 1136, // imageAtomicAdd_01P10D00E
+ 1138, // imageAtomicAdd_01a10D00E
+ 1140, // imageAtomicAdd_01I10D00E
+ 1142, // imageAtomicAdd_01T10D00E
+ 1144, // imageAtomicAdd_01e10D00E
+ 1146, // imageAtomicAdd_01F10D00D00E
+ 1148, // imageAtomicAdd_01Q10D00D00E
+ 1150, // imageAtomicAdd_01b10D00D00E
+ 1152, // imageAtomicAdd_01G20D00D00E
+ 1154, // imageAtomicAdd_01R20D00D00E
+ 1156, // imageAtomicAdd_01c20D00D00E
+ 1158, // imageAtomicAdd_00z10D00D
+ 1160, // imageAtomicAdd_01K10D00D
+ 1162, // imageAtomicAdd_01V10D00D
+ 1164, // imageAtomicAdd_01A20D00D
+ 1166, // imageAtomicAdd_01L20D00D
+ 1168, // imageAtomicAdd_01W20D00D
+ 1170, // imageAtomicAdd_01C20D00D
+ 1172, // imageAtomicAdd_01N20D00D
+ 1174, // imageAtomicAdd_01Y20D00D
+ 1176, // imageAtomicAdd_01J00D00D
+ 1178, // imageAtomicAdd_01U00D00D
+ 1180, // imageAtomicAdd_01f00D00D
+ 1182, // imageAtomicAdd_01B20D00D
+ 1184, // imageAtomicAdd_01M20D00D
+ 1186, // imageAtomicAdd_01X20D00D
+ 1188, // imageAtomicAdd_01H20D00D
+ 1190, // imageAtomicAdd_01S20D00D
+ 1192, // imageAtomicAdd_01d20D00D
+ 1194, // imageAtomicAdd_01D00D00D
+ 1196, // imageAtomicAdd_01O00D00D
+ 1198, // imageAtomicAdd_01Z00D00D
+ 1200, // imageAtomicAdd_01E10D00D
+ 1202, // imageAtomicAdd_01P10D00D
+ 1204, // imageAtomicAdd_01a10D00D
+ 1206, // imageAtomicAdd_01I10D00D
+ 1208, // imageAtomicAdd_01T10D00D
+ 1210, // imageAtomicAdd_01e10D00D
+ 1212, // imageAtomicAdd_01F10D00D00D
+ 1214, // imageAtomicAdd_01Q10D00D00D
+ 1216, // imageAtomicAdd_01b10D00D00D
+ 1218, // imageAtomicAdd_01G20D00D00D
+ 1220, // imageAtomicAdd_01R20D00D00D
+ 1222, // imageAtomicAdd_01c20D00D00D
+ 1224, // imageAtomicMin_00z10D00E
+ 1226, // imageAtomicMin_01K10D00E
+ 1228, // imageAtomicMin_01V10D00E
+ 1230, // imageAtomicMin_01A20D00E
+ 1232, // imageAtomicMin_01L20D00E
+ 1234, // imageAtomicMin_01W20D00E
+ 1236, // imageAtomicMin_01C20D00E
+ 1238, // imageAtomicMin_01N20D00E
+ 1240, // imageAtomicMin_01Y20D00E
+ 1242, // imageAtomicMin_01J00D00E
+ 1244, // imageAtomicMin_01U00D00E
+ 1246, // imageAtomicMin_01f00D00E
+ 1248, // imageAtomicMin_01B20D00E
+ 1250, // imageAtomicMin_01M20D00E
+ 1252, // imageAtomicMin_01X20D00E
+ 1254, // imageAtomicMin_01H20D00E
+ 1256, // imageAtomicMin_01S20D00E
+ 1258, // imageAtomicMin_01d20D00E
+ 1260, // imageAtomicMin_01D00D00E
+ 1262, // imageAtomicMin_01O00D00E
+ 1264, // imageAtomicMin_01Z00D00E
+ 1266, // imageAtomicMin_01E10D00E
+ 1268, // imageAtomicMin_01P10D00E
+ 1270, // imageAtomicMin_01a10D00E
+ 1272, // imageAtomicMin_01I10D00E
+ 1274, // imageAtomicMin_01T10D00E
+ 1276, // imageAtomicMin_01e10D00E
+ 1278, // imageAtomicMin_01F10D00D00E
+ 1280, // imageAtomicMin_01Q10D00D00E
+ 1282, // imageAtomicMin_01b10D00D00E
+ 1284, // imageAtomicMin_01G20D00D00E
+ 1286, // imageAtomicMin_01R20D00D00E
+ 1288, // imageAtomicMin_01c20D00D00E
+ 1290, // imageAtomicMin_00z10D00D
+ 1292, // imageAtomicMin_01K10D00D
+ 1294, // imageAtomicMin_01V10D00D
+ 1296, // imageAtomicMin_01A20D00D
+ 1298, // imageAtomicMin_01L20D00D
+ 1300, // imageAtomicMin_01W20D00D
+ 1302, // imageAtomicMin_01C20D00D
+ 1304, // imageAtomicMin_01N20D00D
+ 1306, // imageAtomicMin_01Y20D00D
+ 1308, // imageAtomicMin_01J00D00D
+ 1310, // imageAtomicMin_01U00D00D
+ 1312, // imageAtomicMin_01f00D00D
+ 1314, // imageAtomicMin_01B20D00D
+ 1316, // imageAtomicMin_01M20D00D
+ 1318, // imageAtomicMin_01X20D00D
+ 1320, // imageAtomicMin_01H20D00D
+ 1322, // imageAtomicMin_01S20D00D
+ 1324, // imageAtomicMin_01d20D00D
+ 1326, // imageAtomicMin_01D00D00D
+ 1328, // imageAtomicMin_01O00D00D
+ 1330, // imageAtomicMin_01Z00D00D
+ 1332, // imageAtomicMin_01E10D00D
+ 1334, // imageAtomicMin_01P10D00D
+ 1336, // imageAtomicMin_01a10D00D
+ 1338, // imageAtomicMin_01I10D00D
+ 1340, // imageAtomicMin_01T10D00D
+ 1342, // imageAtomicMin_01e10D00D
+ 1344, // imageAtomicMin_01F10D00D00D
+ 1346, // imageAtomicMin_01Q10D00D00D
+ 1348, // imageAtomicMin_01b10D00D00D
+ 1350, // imageAtomicMin_01G20D00D00D
+ 1352, // imageAtomicMin_01R20D00D00D
+ 1354, // imageAtomicMin_01c20D00D00D
+ 1356, // imageAtomicMax_00z10D00E
+ 1358, // imageAtomicMax_01K10D00E
+ 1360, // imageAtomicMax_01V10D00E
+ 1362, // imageAtomicMax_01A20D00E
+ 1364, // imageAtomicMax_01L20D00E
+ 1366, // imageAtomicMax_01W20D00E
+ 1368, // imageAtomicMax_01C20D00E
+ 1370, // imageAtomicMax_01N20D00E
+ 1372, // imageAtomicMax_01Y20D00E
+ 1374, // imageAtomicMax_01J00D00E
+ 1376, // imageAtomicMax_01U00D00E
+ 1378, // imageAtomicMax_01f00D00E
+ 1380, // imageAtomicMax_01B20D00E
+ 1382, // imageAtomicMax_01M20D00E
+ 1384, // imageAtomicMax_01X20D00E
+ 1386, // imageAtomicMax_01H20D00E
+ 1388, // imageAtomicMax_01S20D00E
+ 1390, // imageAtomicMax_01d20D00E
+ 1392, // imageAtomicMax_01D00D00E
+ 1394, // imageAtomicMax_01O00D00E
+ 1396, // imageAtomicMax_01Z00D00E
+ 1398, // imageAtomicMax_01E10D00E
+ 1400, // imageAtomicMax_01P10D00E
+ 1402, // imageAtomicMax_01a10D00E
+ 1404, // imageAtomicMax_01I10D00E
+ 1406, // imageAtomicMax_01T10D00E
+ 1408, // imageAtomicMax_01e10D00E
+ 1410, // imageAtomicMax_01F10D00D00E
+ 1412, // imageAtomicMax_01Q10D00D00E
+ 1414, // imageAtomicMax_01b10D00D00E
+ 1416, // imageAtomicMax_01G20D00D00E
+ 1418, // imageAtomicMax_01R20D00D00E
+ 1420, // imageAtomicMax_01c20D00D00E
+ 1422, // imageAtomicMax_00z10D00D
+ 1424, // imageAtomicMax_01K10D00D
+ 1426, // imageAtomicMax_01V10D00D
+ 1428, // imageAtomicMax_01A20D00D
+ 1430, // imageAtomicMax_01L20D00D
+ 1432, // imageAtomicMax_01W20D00D
+ 1434, // imageAtomicMax_01C20D00D
+ 1436, // imageAtomicMax_01N20D00D
+ 1438, // imageAtomicMax_01Y20D00D
+ 1440, // imageAtomicMax_01J00D00D
+ 1442, // imageAtomicMax_01U00D00D
+ 1444, // imageAtomicMax_01f00D00D
+ 1446, // imageAtomicMax_01B20D00D
+ 1448, // imageAtomicMax_01M20D00D
+ 1450, // imageAtomicMax_01X20D00D
+ 1452, // imageAtomicMax_01H20D00D
+ 1454, // imageAtomicMax_01S20D00D
+ 1456, // imageAtomicMax_01d20D00D
+ 1458, // imageAtomicMax_01D00D00D
+ 1460, // imageAtomicMax_01O00D00D
+ 1462, // imageAtomicMax_01Z00D00D
+ 1464, // imageAtomicMax_01E10D00D
+ 1466, // imageAtomicMax_01P10D00D
+ 1468, // imageAtomicMax_01a10D00D
+ 1470, // imageAtomicMax_01I10D00D
+ 1472, // imageAtomicMax_01T10D00D
+ 1474, // imageAtomicMax_01e10D00D
+ 1476, // imageAtomicMax_01F10D00D00D
+ 1478, // imageAtomicMax_01Q10D00D00D
+ 1480, // imageAtomicMax_01b10D00D00D
+ 1482, // imageAtomicMax_01G20D00D00D
+ 1484, // imageAtomicMax_01R20D00D00D
+ 1486, // imageAtomicMax_01c20D00D00D
+ 1488, // imageAtomicAnd_00z10D00E
+ 1490, // imageAtomicAnd_01K10D00E
+ 1492, // imageAtomicAnd_01V10D00E
+ 1494, // imageAtomicAnd_01A20D00E
+ 1496, // imageAtomicAnd_01L20D00E
+ 1498, // imageAtomicAnd_01W20D00E
+ 1500, // imageAtomicAnd_01C20D00E
+ 1502, // imageAtomicAnd_01N20D00E
+ 1504, // imageAtomicAnd_01Y20D00E
+ 1506, // imageAtomicAnd_01J00D00E
+ 1508, // imageAtomicAnd_01U00D00E
+ 1510, // imageAtomicAnd_01f00D00E
+ 1512, // imageAtomicAnd_01B20D00E
+ 1514, // imageAtomicAnd_01M20D00E
+ 1516, // imageAtomicAnd_01X20D00E
+ 1518, // imageAtomicAnd_01H20D00E
+ 1520, // imageAtomicAnd_01S20D00E
+ 1522, // imageAtomicAnd_01d20D00E
+ 1524, // imageAtomicAnd_01D00D00E
+ 1526, // imageAtomicAnd_01O00D00E
+ 1528, // imageAtomicAnd_01Z00D00E
+ 1530, // imageAtomicAnd_01E10D00E
+ 1532, // imageAtomicAnd_01P10D00E
+ 1534, // imageAtomicAnd_01a10D00E
+ 1536, // imageAtomicAnd_01I10D00E
+ 1538, // imageAtomicAnd_01T10D00E
+ 1540, // imageAtomicAnd_01e10D00E
+ 1542, // imageAtomicAnd_01F10D00D00E
+ 1544, // imageAtomicAnd_01Q10D00D00E
+ 1546, // imageAtomicAnd_01b10D00D00E
+ 1548, // imageAtomicAnd_01G20D00D00E
+ 1550, // imageAtomicAnd_01R20D00D00E
+ 1552, // imageAtomicAnd_01c20D00D00E
+ 1554, // imageAtomicAnd_00z10D00D
+ 1556, // imageAtomicAnd_01K10D00D
+ 1558, // imageAtomicAnd_01V10D00D
+ 1560, // imageAtomicAnd_01A20D00D
+ 1562, // imageAtomicAnd_01L20D00D
+ 1564, // imageAtomicAnd_01W20D00D
+ 1566, // imageAtomicAnd_01C20D00D
+ 1568, // imageAtomicAnd_01N20D00D
+ 1570, // imageAtomicAnd_01Y20D00D
+ 1572, // imageAtomicAnd_01J00D00D
+ 1574, // imageAtomicAnd_01U00D00D
+ 1576, // imageAtomicAnd_01f00D00D
+ 1578, // imageAtomicAnd_01B20D00D
+ 1580, // imageAtomicAnd_01M20D00D
+ 1582, // imageAtomicAnd_01X20D00D
+ 1584, // imageAtomicAnd_01H20D00D
+ 1586, // imageAtomicAnd_01S20D00D
+ 1588, // imageAtomicAnd_01d20D00D
+ 1590, // imageAtomicAnd_01D00D00D
+ 1592, // imageAtomicAnd_01O00D00D
+ 1594, // imageAtomicAnd_01Z00D00D
+ 1596, // imageAtomicAnd_01E10D00D
+ 1598, // imageAtomicAnd_01P10D00D
+ 1600, // imageAtomicAnd_01a10D00D
+ 1602, // imageAtomicAnd_01I10D00D
+ 1604, // imageAtomicAnd_01T10D00D
+ 1606, // imageAtomicAnd_01e10D00D
+ 1608, // imageAtomicAnd_01F10D00D00D
+ 1610, // imageAtomicAnd_01Q10D00D00D
+ 1612, // imageAtomicAnd_01b10D00D00D
+ 1614, // imageAtomicAnd_01G20D00D00D
+ 1616, // imageAtomicAnd_01R20D00D00D
+ 1618, // imageAtomicAnd_01c20D00D00D
+ 1620, // imageAtomicOr_00z10D00E
+ 1622, // imageAtomicOr_01K10D00E
+ 1624, // imageAtomicOr_01V10D00E
+ 1626, // imageAtomicOr_01A20D00E
+ 1628, // imageAtomicOr_01L20D00E
+ 1630, // imageAtomicOr_01W20D00E
+ 1632, // imageAtomicOr_01C20D00E
+ 1634, // imageAtomicOr_01N20D00E
+ 1636, // imageAtomicOr_01Y20D00E
+ 1638, // imageAtomicOr_01J00D00E
+ 1640, // imageAtomicOr_01U00D00E
+ 1642, // imageAtomicOr_01f00D00E
+ 1644, // imageAtomicOr_01B20D00E
+ 1646, // imageAtomicOr_01M20D00E
+ 1648, // imageAtomicOr_01X20D00E
+ 1650, // imageAtomicOr_01H20D00E
+ 1652, // imageAtomicOr_01S20D00E
+ 1654, // imageAtomicOr_01d20D00E
+ 1656, // imageAtomicOr_01D00D00E
+ 1658, // imageAtomicOr_01O00D00E
+ 1660, // imageAtomicOr_01Z00D00E
+ 1662, // imageAtomicOr_01E10D00E
+ 1664, // imageAtomicOr_01P10D00E
+ 1666, // imageAtomicOr_01a10D00E
+ 1668, // imageAtomicOr_01I10D00E
+ 1670, // imageAtomicOr_01T10D00E
+ 1672, // imageAtomicOr_01e10D00E
+ 1674, // imageAtomicOr_01F10D00D00E
+ 1676, // imageAtomicOr_01Q10D00D00E
+ 1678, // imageAtomicOr_01b10D00D00E
+ 1680, // imageAtomicOr_01G20D00D00E
+ 1682, // imageAtomicOr_01R20D00D00E
+ 1684, // imageAtomicOr_01c20D00D00E
+ 1686, // imageAtomicOr_00z10D00D
+ 1688, // imageAtomicOr_01K10D00D
+ 1690, // imageAtomicOr_01V10D00D
+ 1692, // imageAtomicOr_01A20D00D
+ 1694, // imageAtomicOr_01L20D00D
+ 1696, // imageAtomicOr_01W20D00D
+ 1698, // imageAtomicOr_01C20D00D
+ 1700, // imageAtomicOr_01N20D00D
+ 1702, // imageAtomicOr_01Y20D00D
+ 1704, // imageAtomicOr_01J00D00D
+ 1706, // imageAtomicOr_01U00D00D
+ 1708, // imageAtomicOr_01f00D00D
+ 1710, // imageAtomicOr_01B20D00D
+ 1712, // imageAtomicOr_01M20D00D
+ 1714, // imageAtomicOr_01X20D00D
+ 1716, // imageAtomicOr_01H20D00D
+ 1718, // imageAtomicOr_01S20D00D
+ 1720, // imageAtomicOr_01d20D00D
+ 1722, // imageAtomicOr_01D00D00D
+ 1724, // imageAtomicOr_01O00D00D
+ 1726, // imageAtomicOr_01Z00D00D
+ 1728, // imageAtomicOr_01E10D00D
+ 1730, // imageAtomicOr_01P10D00D
+ 1732, // imageAtomicOr_01a10D00D
+ 1734, // imageAtomicOr_01I10D00D
+ 1736, // imageAtomicOr_01T10D00D
+ 1738, // imageAtomicOr_01e10D00D
+ 1740, // imageAtomicOr_01F10D00D00D
+ 1742, // imageAtomicOr_01Q10D00D00D
+ 1744, // imageAtomicOr_01b10D00D00D
+ 1746, // imageAtomicOr_01G20D00D00D
+ 1748, // imageAtomicOr_01R20D00D00D
+ 1750, // imageAtomicOr_01c20D00D00D
+ 1752, // imageAtomicXor_00z10D00E
+ 1754, // imageAtomicXor_01K10D00E
+ 1756, // imageAtomicXor_01V10D00E
+ 1758, // imageAtomicXor_01A20D00E
+ 1760, // imageAtomicXor_01L20D00E
+ 1762, // imageAtomicXor_01W20D00E
+ 1764, // imageAtomicXor_01C20D00E
+ 1766, // imageAtomicXor_01N20D00E
+ 1768, // imageAtomicXor_01Y20D00E
+ 1770, // imageAtomicXor_01J00D00E
+ 1772, // imageAtomicXor_01U00D00E
+ 1774, // imageAtomicXor_01f00D00E
+ 1776, // imageAtomicXor_01B20D00E
+ 1778, // imageAtomicXor_01M20D00E
+ 1780, // imageAtomicXor_01X20D00E
+ 1782, // imageAtomicXor_01H20D00E
+ 1784, // imageAtomicXor_01S20D00E
+ 1786, // imageAtomicXor_01d20D00E
+ 1788, // imageAtomicXor_01D00D00E
+ 1790, // imageAtomicXor_01O00D00E
+ 1792, // imageAtomicXor_01Z00D00E
+ 1794, // imageAtomicXor_01E10D00E
+ 1796, // imageAtomicXor_01P10D00E
+ 1798, // imageAtomicXor_01a10D00E
+ 1800, // imageAtomicXor_01I10D00E
+ 1802, // imageAtomicXor_01T10D00E
+ 1804, // imageAtomicXor_01e10D00E
+ 1806, // imageAtomicXor_01F10D00D00E
+ 1808, // imageAtomicXor_01Q10D00D00E
+ 1810, // imageAtomicXor_01b10D00D00E
+ 1812, // imageAtomicXor_01G20D00D00E
+ 1814, // imageAtomicXor_01R20D00D00E
+ 1816, // imageAtomicXor_01c20D00D00E
+ 1818, // imageAtomicXor_00z10D00D
+ 1820, // imageAtomicXor_01K10D00D
+ 1822, // imageAtomicXor_01V10D00D
+ 1824, // imageAtomicXor_01A20D00D
+ 1826, // imageAtomicXor_01L20D00D
+ 1828, // imageAtomicXor_01W20D00D
+ 1830, // imageAtomicXor_01C20D00D
+ 1832, // imageAtomicXor_01N20D00D
+ 1834, // imageAtomicXor_01Y20D00D
+ 1836, // imageAtomicXor_01J00D00D
+ 1838, // imageAtomicXor_01U00D00D
+ 1840, // imageAtomicXor_01f00D00D
+ 1842, // imageAtomicXor_01B20D00D
+ 1844, // imageAtomicXor_01M20D00D
+ 1846, // imageAtomicXor_01X20D00D
+ 1848, // imageAtomicXor_01H20D00D
+ 1850, // imageAtomicXor_01S20D00D
+ 1852, // imageAtomicXor_01d20D00D
+ 1854, // imageAtomicXor_01D00D00D
+ 1856, // imageAtomicXor_01O00D00D
+ 1858, // imageAtomicXor_01Z00D00D
+ 1860, // imageAtomicXor_01E10D00D
+ 1862, // imageAtomicXor_01P10D00D
+ 1864, // imageAtomicXor_01a10D00D
+ 1866, // imageAtomicXor_01I10D00D
+ 1868, // imageAtomicXor_01T10D00D
+ 1870, // imageAtomicXor_01e10D00D
+ 1872, // imageAtomicXor_01F10D00D00D
+ 1874, // imageAtomicXor_01Q10D00D00D
+ 1876, // imageAtomicXor_01b10D00D00D
+ 1878, // imageAtomicXor_01G20D00D00D
+ 1880, // imageAtomicXor_01R20D00D00D
+ 1882, // imageAtomicXor_01c20D00D00D
+ 1884, // imageAtomicExchange_00z10D00E
+ 1886, // imageAtomicExchange_01K10D00E
+ 1888, // imageAtomicExchange_01V10D00E
+ 1890, // imageAtomicExchange_01A20D00E
+ 1892, // imageAtomicExchange_01L20D00E
+ 1894, // imageAtomicExchange_01W20D00E
+ 1896, // imageAtomicExchange_01C20D00E
+ 1898, // imageAtomicExchange_01N20D00E
+ 1900, // imageAtomicExchange_01Y20D00E
+ 1902, // imageAtomicExchange_01J00D00E
+ 1904, // imageAtomicExchange_01U00D00E
+ 1906, // imageAtomicExchange_01f00D00E
+ 1908, // imageAtomicExchange_01B20D00E
+ 1910, // imageAtomicExchange_01M20D00E
+ 1912, // imageAtomicExchange_01X20D00E
+ 1914, // imageAtomicExchange_01H20D00E
+ 1916, // imageAtomicExchange_01S20D00E
+ 1918, // imageAtomicExchange_01d20D00E
+ 1920, // imageAtomicExchange_01D00D00E
+ 1922, // imageAtomicExchange_01O00D00E
+ 1924, // imageAtomicExchange_01Z00D00E
+ 1926, // imageAtomicExchange_01E10D00E
+ 1928, // imageAtomicExchange_01P10D00E
+ 1930, // imageAtomicExchange_01a10D00E
+ 1932, // imageAtomicExchange_01I10D00E
+ 1934, // imageAtomicExchange_01T10D00E
+ 1936, // imageAtomicExchange_01e10D00E
+ 1938, // imageAtomicExchange_01F10D00D00E
+ 1940, // imageAtomicExchange_01Q10D00D00E
+ 1942, // imageAtomicExchange_01b10D00D00E
+ 1944, // imageAtomicExchange_01G20D00D00E
+ 1946, // imageAtomicExchange_01R20D00D00E
+ 1948, // imageAtomicExchange_01c20D00D00E
+ 1950, // imageAtomicExchange_00z10D00D
+ 1952, // imageAtomicExchange_01K10D00D
+ 1954, // imageAtomicExchange_01V10D00D
+ 1956, // imageAtomicExchange_01A20D00D
+ 1958, // imageAtomicExchange_01L20D00D
+ 1960, // imageAtomicExchange_01W20D00D
+ 1962, // imageAtomicExchange_01C20D00D
+ 1964, // imageAtomicExchange_01N20D00D
+ 1966, // imageAtomicExchange_01Y20D00D
+ 1968, // imageAtomicExchange_01J00D00D
+ 1970, // imageAtomicExchange_01U00D00D
+ 1972, // imageAtomicExchange_01f00D00D
+ 1974, // imageAtomicExchange_01B20D00D
+ 1976, // imageAtomicExchange_01M20D00D
+ 1978, // imageAtomicExchange_01X20D00D
+ 1980, // imageAtomicExchange_01H20D00D
+ 1982, // imageAtomicExchange_01S20D00D
+ 1984, // imageAtomicExchange_01d20D00D
+ 1986, // imageAtomicExchange_01D00D00D
+ 1988, // imageAtomicExchange_01O00D00D
+ 1990, // imageAtomicExchange_01Z00D00D
+ 1992, // imageAtomicExchange_01E10D00D
+ 1994, // imageAtomicExchange_01P10D00D
+ 1996, // imageAtomicExchange_01a10D00D
+ 1998, // imageAtomicExchange_01I10D00D
+ 2000, // imageAtomicExchange_01T10D00D
+ 2002, // imageAtomicExchange_01e10D00D
+ 2004, // imageAtomicExchange_01F10D00D00D
+ 2006, // imageAtomicExchange_01Q10D00D00D
+ 2008, // imageAtomicExchange_01b10D00D00D
+ 2010, // imageAtomicExchange_01G20D00D00D
+ 2012, // imageAtomicExchange_01R20D00D00D
+ 2014, // imageAtomicExchange_01c20D00D00D
+ 2016, // imageAtomicExchange_00z10D00B
+ 2018, // imageAtomicExchange_01K10D00B
+ 2020, // imageAtomicExchange_01V10D00B
+ 2022, // imageAtomicExchange_01A20D00B
+ 2024, // imageAtomicExchange_01L20D00B
+ 2026, // imageAtomicExchange_01W20D00B
+ 2028, // imageAtomicExchange_01C20D00B
+ 2030, // imageAtomicExchange_01N20D00B
+ 2032, // imageAtomicExchange_01Y20D00B
+ 2034, // imageAtomicExchange_01J00D00B
+ 2036, // imageAtomicExchange_01U00D00B
+ 2038, // imageAtomicExchange_01f00D00B
+ 2040, // imageAtomicExchange_01B20D00B
+ 2042, // imageAtomicExchange_01M20D00B
+ 2044, // imageAtomicExchange_01X20D00B
+ 2046, // imageAtomicExchange_01H20D00B
+ 2048, // imageAtomicExchange_01S20D00B
+ 2050, // imageAtomicExchange_01d20D00B
+ 2052, // imageAtomicExchange_01D00D00B
+ 2054, // imageAtomicExchange_01O00D00B
+ 2056, // imageAtomicExchange_01Z00D00B
+ 2058, // imageAtomicExchange_01E10D00B
+ 2060, // imageAtomicExchange_01P10D00B
+ 2062, // imageAtomicExchange_01a10D00B
+ 2064, // imageAtomicExchange_01I10D00B
+ 2066, // imageAtomicExchange_01T10D00B
+ 2068, // imageAtomicExchange_01e10D00B
+ 2070, // imageAtomicExchange_01F10D00D00B
+ 2072, // imageAtomicExchange_01Q10D00D00B
+ 2074, // imageAtomicExchange_01b10D00D00B
+ 2076, // imageAtomicExchange_01G20D00D00B
+ 2078, // imageAtomicExchange_01R20D00D00B
+ 2080, // imageAtomicExchange_01c20D00D00B
+ 2082, // imageAtomicCompSwap_00z10D00E00E
+ 2084, // imageAtomicCompSwap_01K10D00E00E
+ 2086, // imageAtomicCompSwap_01V10D00E00E
+ 2088, // imageAtomicCompSwap_01A20D00E00E
+ 2090, // imageAtomicCompSwap_01L20D00E00E
+ 2092, // imageAtomicCompSwap_01W20D00E00E
+ 2094, // imageAtomicCompSwap_01C20D00E00E
+ 2096, // imageAtomicCompSwap_01N20D00E00E
+ 2098, // imageAtomicCompSwap_01Y20D00E00E
+ 2100, // imageAtomicCompSwap_01J00D00E00E
+ 2102, // imageAtomicCompSwap_01U00D00E00E
+ 2104, // imageAtomicCompSwap_01f00D00E00E
+ 2106, // imageAtomicCompSwap_01B20D00E00E
+ 2108, // imageAtomicCompSwap_01M20D00E00E
+ 2110, // imageAtomicCompSwap_01X20D00E00E
+ 2112, // imageAtomicCompSwap_01H20D00E00E
+ 2114, // imageAtomicCompSwap_01S20D00E00E
+ 2116, // imageAtomicCompSwap_01d20D00E00E
+ 2118, // imageAtomicCompSwap_01D00D00E00E
+ 2120, // imageAtomicCompSwap_01O00D00E00E
+ 2122, // imageAtomicCompSwap_01Z00D00E00E
+ 2124, // imageAtomicCompSwap_01E10D00E00E
+ 2126, // imageAtomicCompSwap_01P10D00E00E
+ 2128, // imageAtomicCompSwap_01a10D00E00E
+ 2130, // imageAtomicCompSwap_01I10D00E00E
+ 2132, // imageAtomicCompSwap_01T10D00E00E
+ 2134, // imageAtomicCompSwap_01e10D00E00E
+ 2136, // imageAtomicCompSwap_01F10D00D00E00E
+ 2138, // imageAtomicCompSwap_01Q10D00D00E00E
+ 2140, // imageAtomicCompSwap_01b10D00D00E00E
+ 2142, // imageAtomicCompSwap_01G20D00D00E00E
+ 2144, // imageAtomicCompSwap_01R20D00D00E00E
+ 2146, // imageAtomicCompSwap_01c20D00D00E00E
+ 2148, // imageAtomicCompSwap_00z10D00D00D
+ 2150, // imageAtomicCompSwap_01K10D00D00D
+ 2152, // imageAtomicCompSwap_01V10D00D00D
+ 2154, // imageAtomicCompSwap_01A20D00D00D
+ 2156, // imageAtomicCompSwap_01L20D00D00D
+ 2158, // imageAtomicCompSwap_01W20D00D00D
+ 2160, // imageAtomicCompSwap_01C20D00D00D
+ 2162, // imageAtomicCompSwap_01N20D00D00D
+ 2164, // imageAtomicCompSwap_01Y20D00D00D
+ 2166, // imageAtomicCompSwap_01J00D00D00D
+ 2168, // imageAtomicCompSwap_01U00D00D00D
+ 2170, // imageAtomicCompSwap_01f00D00D00D
+ 2172, // imageAtomicCompSwap_01B20D00D00D
+ 2174, // imageAtomicCompSwap_01M20D00D00D
+ 2176, // imageAtomicCompSwap_01X20D00D00D
+ 2178, // imageAtomicCompSwap_01H20D00D00D
+ 2180, // imageAtomicCompSwap_01S20D00D00D
+ 2182, // imageAtomicCompSwap_01d20D00D00D
+ 2184, // imageAtomicCompSwap_01D00D00D00D
+ 2186, // imageAtomicCompSwap_01O00D00D00D
+ 2188, // imageAtomicCompSwap_01Z00D00D00D
+ 2190, // imageAtomicCompSwap_01E10D00D00D
+ 2192, // imageAtomicCompSwap_01P10D00D00D
+ 2194, // imageAtomicCompSwap_01a10D00D00D
+ 2196, // imageAtomicCompSwap_01I10D00D00D
+ 2198, // imageAtomicCompSwap_01T10D00D00D
+ 2200, // imageAtomicCompSwap_01e10D00D00D
+ 2202, // imageAtomicCompSwap_01F10D00D00D00D
+ 2204, // imageAtomicCompSwap_01Q10D00D00D00D
+ 2206, // imageAtomicCompSwap_01b10D00D00D00D
+ 2208, // imageAtomicCompSwap_01G20D00D00D00D
+ 2210, // imageAtomicCompSwap_01R20D00D00D00D
+ 2212, // imageAtomicCompSwap_01c20D00D00D00D
+ 2214, // pixelLocalLoadANGLE_01g
+ 2215, // pixelLocalLoadANGLE_01h
+ 2216, // pixelLocalLoadANGLE_01i
+ 2217, // pixelLocalStoreANGLE_01g30B
+ 2218, // pixelLocalStoreANGLE_01h30D
+ 2219, // pixelLocalStoreANGLE_01i30E
+ 2220, // beginInvocationInterlockNV_
+ 2221, // endInvocationInterlockNV_
+ 2222, // beginFragmentShaderOrderingINTEL_
+ 2223, // beginInvocationInterlockARB_
+ 2224, // endInvocationInterlockARB_
+ 2225, // memoryBarrier_
+ 2226, // memoryBarrierAtomicCounter_
+ 2227, // memoryBarrierBuffer_
+ 2228, // memoryBarrierImage_
+ 2229, // barrier_
+ 2232, // memoryBarrierShared_
+ 2233, // groupMemoryBarrier_
+ 2234, // EmitVertex_
+ 2237, // EndPrimitive_
+ 2240, // subpassLoad_01j
+ 2241, // subpassLoad_01k
+ 2242, // subpassLoad_01l
+ 2243, // subpassLoad_01m00D
+ 2244, // subpassLoad_01n00D
+ 2245, // subpassLoad_01o00D
+ 2246, // gl_DepthRangeParameters
+ 2247, // gl_DepthRange
+ 2248, // gl_NumSamples
+ 2250, // gl_MaxVertexAttribs
+ 2251, // gl_MaxVertexUniformVectors
+ 2252, // gl_MaxVertexTextureImageUnits
+ 2253, // gl_MaxCombinedTextureImageUnits
+ 2254, // gl_MaxTextureImageUnits
+ 2255, // gl_MaxFragmentUniformVectors
+ 2256, // gl_MaxVaryingVectors
+ 2257, // gl_MaxDrawBuffers
+ 2258, // gl_MaxDualSourceDrawBuffersEXT
+ 2259, // gl_MaxVertexOutputVectors
+ 2260, // gl_MaxFragmentInputVectors
+ 2261, // gl_MinProgramTexelOffset
+ 2262, // gl_MaxProgramTexelOffset
+ 2263, // gl_MaxImageUnits
+ 2264, // gl_MaxVertexImageUniforms
+ 2265, // gl_MaxFragmentImageUniforms
+ 2266, // gl_MaxComputeImageUniforms
+ 2267, // gl_MaxCombinedImageUniforms
+ 2268, // gl_MaxCombinedShaderOutputResources
+ 2269, // gl_MaxComputeWorkGroupCount
+ 2270, // gl_MaxComputeWorkGroupSize
+ 2271, // gl_MaxComputeUniformComponents
+ 2272, // gl_MaxComputeTextureImageUnits
+ 2273, // gl_MaxComputeAtomicCounters
+ 2274, // gl_MaxComputeAtomicCounterBuffers
+ 2275, // gl_MaxVertexAtomicCounters
+ 2276, // gl_MaxFragmentAtomicCounters
+ 2277, // gl_MaxCombinedAtomicCounters
+ 2278, // gl_MaxAtomicCounterBindings
+ 2279, // gl_MaxVertexAtomicCounterBuffers
+ 2280, // gl_MaxFragmentAtomicCounterBuffers
+ 2281, // gl_MaxCombinedAtomicCounterBuffers
+ 2282, // gl_MaxAtomicCounterBufferSize
+ 2283, // gl_MaxGeometryInputComponents
+ 2286, // gl_MaxGeometryOutputComponents
+ 2289, // gl_MaxGeometryImageUniforms
+ 2292, // gl_MaxGeometryTextureImageUnits
+ 2295, // gl_MaxGeometryOutputVertices
+ 2298, // gl_MaxGeometryTotalOutputComponents
+ 2301, // gl_MaxGeometryUniformComponents
+ 2304, // gl_MaxGeometryAtomicCounters
+ 2307, // gl_MaxGeometryAtomicCounterBuffers
+ 2310, // gl_MaxTessControlInputComponents
+ 2312, // gl_MaxTessControlOutputComponents
+ 2314, // gl_MaxTessControlTextureImageUnits
+ 2316, // gl_MaxTessControlUniformComponents
+ 2318, // gl_MaxTessControlTotalOutputComponents
+ 2320, // gl_MaxTessControlImageUniforms
+ 2322, // gl_MaxTessControlAtomicCounters
+ 2324, // gl_MaxTessControlAtomicCounterBuffers
+ 2326, // gl_MaxTessPatchComponents
+ 2328, // gl_MaxPatchVertices
+ 2330, // gl_MaxTessGenLevel
+ 2332, // gl_MaxTessEvaluationInputComponents
+ 2334, // gl_MaxTessEvaluationOutputComponents
+ 2336, // gl_MaxTessEvaluationTextureImageUnits
+ 2338, // gl_MaxTessEvaluationUniformComponents
+ 2340, // gl_MaxTessEvaluationImageUniforms
+ 2342, // gl_MaxTessEvaluationAtomicCounters
+ 2344, // gl_MaxTessEvaluationAtomicCounterBuffers
+ 2346, // gl_MaxSamples
+ 2348, // gl_MaxClipDistances
+ 2349, // gl_MaxCullDistances
+ 2350, // gl_MaxCombinedClipAndCullDistances
+ 2351, // gl_FragCoord
+ 2353, // gl_FrontFacing
+ 2354, // gl_PointCoord
+ 2355, // gl_FragColor
+ 2356, // gl_FragData
+ 2357, // gl_FragDepth
+ 2358, // gl_HelperInvocation
+ 2359, // gl_SecondaryFragColorEXT
+ 2360, // gl_SecondaryFragDataEXT
+ 2361, // gl_FragDepthEXT
+ 2362, // gl_LastFragData
+ 2365, // gl_LastFragColor
+ 2366, // gl_LastFragColorARM
+ 2367, // gl_PrimitiveID
+ 2377, // gl_Layer
+ 2383, // gl_SampleID
+ 2385, // gl_SamplePosition
+ 2387, // gl_SampleMaskIn
+ 2389, // gl_SampleMask
+ 2391, // gl_CullDistance
+ 2393, // gl_ClipDistance
+ 2395, // gl_Position
+ 2403, // gl_PointSize
+ 2405, // gl_InstanceID
+ 2406, // Empty
+ 2406, // gl_VertexID
+ 2407, // Empty
+ 2407, // Empty
+ 2407, // gl_DrawID
+ 2408, // gl_BaseVertex
+ 2409, // gl_BaseInstance
+ 2410, // angle_BaseVertex
+ 2411, // angle_BaseInstance
+ 2412, // gl_NumWorkGroups
+ 2413, // gl_WorkGroupSize
+ 2414, // gl_WorkGroupID
+ 2415, // gl_LocalInvocationID
+ 2416, // gl_GlobalInvocationID
+ 2417, // gl_LocalInvocationIndex
+ 2418, // gl_PrimitiveIDIn
+ 2421, // gl_InvocationID
+ 2426, // gl_PerVertex
+ 2433, // gl_in
+ 2440, // gl_PatchVerticesIn
+ 2444, // gl_TessLevelOuter
+ 2448, // gl_TessLevelInner
+ 2452, // gl_out
+ 2456, // gl_BoundingBox
+ 2458, // gl_BoundingBoxEXT
+ 2460, // gl_BoundingBoxOES
+ 2462, // gl_TessCoord
+ 2463, // gl_ViewID_OVR
+};
+
+using Ext = TExtension;
+
+// Flat array of all unmangled name identifiers.
+constexpr UnmangledEntry unmangled[] = {
+ {"radians", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"degrees", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"sin", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"cos", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"tan", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"asin", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"acos", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"atan", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"sinh", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130, Shader::ALL},
+ {"cosh", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130, Shader::ALL},
+ {"tanh", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130, Shader::ALL},
+ {"asinh", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130, Shader::ALL},
+ {"acosh", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130, Shader::ALL},
+ {"atanh", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130, Shader::ALL},
+ {"pow", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"exp", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"log", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"exp2", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"log2", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"sqrt", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"inversesqrt", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"abs", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130, Shader::ALL},
+ {"sign", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130, Shader::ALL},
+ {"floor", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"trunc", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130, Shader::ALL},
+ {"round", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130, Shader::ALL},
+ {"roundEven", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130,
+ Shader::ALL},
+ {"ceil", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"fract", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"mod", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"min", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130, Shader::ALL},
+ {"max", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130, Shader::ALL},
+ {"clamp", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130, Shader::ALL},
+ {"mix", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 450, Shader::ALL},
+ {"step", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"smoothstep", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"modf", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130, Shader::ALL},
+ {"isnan", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130, Shader::ALL},
+ {"isinf", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130, Shader::ALL},
+ {"floatBitsToInt", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 330,
+ Shader::ALL},
+ {"floatBitsToUint", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 330,
+ Shader::ALL},
+ {"intBitsToFloat", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 330,
+ Shader::ALL},
+ {"uintBitsToFloat", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 330,
+ Shader::ALL},
+ {"fma", std::array<TExtension, 1>{{Ext::EXT_gpu_shader5}}, Ext::UNDEFINED, 310, -1,
+ Shader::ALL},
+ {"frexp", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 400, Shader::ALL},
+ {"ldexp", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 400, Shader::ALL},
+ {"packSnorm2x16", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 420,
+ Shader::ALL},
+ {"packHalf2x16", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 420,
+ Shader::ALL},
+ {"unpackSnorm2x16", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 420,
+ Shader::ALL},
+ {"unpackHalf2x16", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 420,
+ Shader::ALL},
+ {"packUnorm2x16", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 400,
+ Shader::ALL},
+ {"unpackUnorm2x16", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 400,
+ Shader::ALL},
+ {"packUnorm4x8", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 400,
+ Shader::ALL},
+ {"packSnorm4x8", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 400,
+ Shader::ALL},
+ {"unpackUnorm4x8", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 400,
+ Shader::ALL},
+ {"unpackSnorm4x8", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 400,
+ Shader::ALL},
+ {"length", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"distance", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"dot", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"cross", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"normalize", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"faceforward", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"reflect", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"refract", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"matrixCompMult", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, -1,
+ Shader::ALL},
+ {"outerProduct", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 120,
+ Shader::ALL},
+ {"transpose", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 120,
+ Shader::ALL},
+ {"determinant", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, -1,
+ Shader::ALL},
+ {"inverse", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 140, Shader::ALL},
+ {"lessThan", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130,
+ Shader::ALL},
+ {"lessThanEqual", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130,
+ Shader::ALL},
+ {"greaterThan", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130,
+ Shader::ALL},
+ {"greaterThanEqual", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130,
+ Shader::ALL},
+ {"equal", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"notEqual", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"any", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"all", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"not", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 0, 0, Shader::ALL},
+ {"bitfieldExtract", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 400,
+ Shader::ALL},
+ {"bitfieldInsert", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 400,
+ Shader::ALL},
+ {"bitfieldReverse", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 400,
+ Shader::ALL},
+ {"bitCount", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 400,
+ Shader::ALL},
+ {"findLSB", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 400, Shader::ALL},
+ {"findMSB", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 400, Shader::ALL},
+ {"uaddCarry", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 400,
+ Shader::ALL},
+ {"usubBorrow", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 400,
+ Shader::ALL},
+ {"umulExtended", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 400,
+ Shader::ALL},
+ {"imulExtended", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 400,
+ Shader::ALL},
+ {"texture2D", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 100, 0,
+ Shader::FRAGMENT},
+ {"texture2DProj", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 100, 0,
+ Shader::FRAGMENT},
+ {"textureCube", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 100, 0,
+ Shader::ALL},
+ {"texture3D", std::array<TExtension, 1>{{Ext::OES_texture_3D}}, Ext::UNDEFINED, 100, -1,
+ Shader::FRAGMENT},
+ {"texture3DProj", std::array<TExtension, 1>{{Ext::OES_texture_3D}}, Ext::UNDEFINED, 100, -1,
+ Shader::FRAGMENT},
+ {"shadow2DEXT", std::array<TExtension, 1>{{Ext::EXT_shadow_samplers}}, Ext::UNDEFINED, 100, -1,
+ Shader::ALL},
+ {"shadow2DProjEXT", std::array<TExtension, 1>{{Ext::EXT_shadow_samplers}}, Ext::UNDEFINED, 100,
+ -1, Shader::ALL},
+ {"texture2DRect", std::array<TExtension, 1>{{Ext::ARB_texture_rectangle}}, Ext::UNDEFINED, 100,
+ -1, Shader::ALL},
+ {"texture2DRectProj", std::array<TExtension, 1>{{Ext::ARB_texture_rectangle}}, Ext::UNDEFINED,
+ 100, -1, Shader::ALL},
+ {"texture2DGradEXT", std::array<TExtension, 1>{{Ext::EXT_shader_texture_lod}}, Ext::UNDEFINED,
+ 100, -1, Shader::ALL},
+ {"texture2DProjGradEXT", std::array<TExtension, 1>{{Ext::EXT_shader_texture_lod}},
+ Ext::UNDEFINED, 100, -1, Shader::ALL},
+ {"textureCubeGradEXT", std::array<TExtension, 1>{{Ext::EXT_shader_texture_lod}}, Ext::UNDEFINED,
+ 100, -1, Shader::ALL},
+ {"textureVideoWEBGL", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 100, 0,
+ Shader::ALL},
+ {"texture3DLod", std::array<TExtension, 1>{{Ext::OES_texture_3D}}, Ext::UNDEFINED, 100, -1,
+ Shader::ALL},
+ {"texture3DProjLod", std::array<TExtension, 1>{{Ext::OES_texture_3D}}, Ext::UNDEFINED, 100, -1,
+ Shader::ALL},
+ {"texture2DLod", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 100, -1,
+ Shader::VERTEX},
+ {"texture2DProjLod", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 100, -1,
+ Shader::VERTEX},
+ {"textureCubeLod", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 100, -1,
+ Shader::VERTEX},
+ {"texture2DLodEXT", std::array<TExtension, 1>{{Ext::EXT_shader_texture_lod}}, Ext::UNDEFINED,
+ 100, -1, Shader::FRAGMENT},
+ {"texture2DProjLodEXT", std::array<TExtension, 1>{{Ext::EXT_shader_texture_lod}},
+ Ext::UNDEFINED, 100, -1, Shader::FRAGMENT},
+ {"textureCubeLodEXT", std::array<TExtension, 1>{{Ext::EXT_shader_texture_lod}}, Ext::UNDEFINED,
+ 100, -1, Shader::FRAGMENT},
+ {"texture", std::array<TExtension, 1>{{Ext::OES_EGL_image_external_essl3}}, Ext::UNDEFINED, 300,
+ -1, Shader::FRAGMENT},
+ {"textureProj", std::array<TExtension, 1>{{Ext::OES_EGL_image_external_essl3}}, Ext::UNDEFINED,
+ 300, -1, Shader::FRAGMENT},
+ {"textureLod",
+ std::array<TExtension, 2>{{Ext::OES_texture_cube_map_array, Ext::EXT_texture_cube_map_array}},
+ Ext::UNDEFINED, 310, -1, Shader::ALL},
+ {"textureSize", std::array<TExtension, 1>{{Ext::OES_EGL_image_external_essl3}}, Ext::UNDEFINED,
+ 300, -1, Shader::ALL},
+ {"textureProjLod", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130,
+ Shader::ALL},
+ {"texelFetch", std::array<TExtension, 1>{{Ext::OES_EGL_image_external_essl3}}, Ext::UNDEFINED,
+ 300, -1, Shader::ALL},
+ {"textureGrad",
+ std::array<TExtension, 2>{{Ext::OES_texture_cube_map_array, Ext::EXT_texture_cube_map_array}},
+ Ext::UNDEFINED, 310, -1, Shader::ALL},
+ {"textureProjGrad", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130,
+ Shader::ALL},
+ {"textureOffset", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130,
+ Shader::ALL},
+ {"textureProjOffset", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130,
+ Shader::ALL},
+ {"textureLodOffset", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130,
+ Shader::ALL},
+ {"textureProjLodOffset", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130,
+ Shader::ALL},
+ {"texelFetchOffset", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130,
+ Shader::ALL},
+ {"textureGradOffset", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130,
+ Shader::ALL},
+ {"textureProjGradOffset", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 130,
+ Shader::ALL},
+ {"textureGather", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 400,
+ Shader::ALL},
+ {"textureGatherOffset", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 400,
+ Shader::ALL},
+ {"textureGatherOffsets", std::array<TExtension, 1>{{Ext::EXT_gpu_shader5}}, Ext::UNDEFINED, 310,
+ -1, Shader::ALL},
+ {"rgb_2_yuv", std::array<TExtension, 1>{{Ext::EXT_YUV_target}}, Ext::UNDEFINED, 300, -1,
+ Shader::ALL},
+ {"yuv_2_rgb", std::array<TExtension, 1>{{Ext::EXT_YUV_target}}, Ext::UNDEFINED, 300, -1,
+ Shader::ALL},
+ {"dFdx", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 0, Shader::FRAGMENT},
+ {"dFdy", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 0, Shader::FRAGMENT},
+ {"fwidth", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 300, 0,
+ Shader::FRAGMENT},
+ {"interpolateAtCentroid",
+ std::array<TExtension, 1>{{Ext::OES_shader_multisample_interpolation}}, Ext::UNDEFINED, 300,
+ -1, Shader::FRAGMENT},
+ {"interpolateAtSample", std::array<TExtension, 1>{{Ext::OES_shader_multisample_interpolation}},
+ Ext::UNDEFINED, 300, -1, Shader::FRAGMENT},
+ {"interpolateAtOffset", std::array<TExtension, 1>{{Ext::OES_shader_multisample_interpolation}},
+ Ext::UNDEFINED, 300, -1, Shader::FRAGMENT},
+ {"atomicCounter", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 420,
+ Shader::ALL},
+ {"atomicCounterIncrement", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310,
+ 420, Shader::ALL},
+ {"atomicCounterDecrement", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310,
+ 420, Shader::ALL},
+ {"atomicAdd", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 430,
+ Shader::ALL},
+ {"atomicMin", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 430,
+ Shader::ALL},
+ {"atomicMax", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 430,
+ Shader::ALL},
+ {"atomicAnd", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 430,
+ Shader::ALL},
+ {"atomicOr", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 430,
+ Shader::ALL},
+ {"atomicXor", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 430,
+ Shader::ALL},
+ {"atomicExchange", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 430,
+ Shader::ALL},
+ {"atomicCompSwap", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 430,
+ Shader::ALL},
+ {"imageSize", std::array<TExtension, 2>{{Ext::OES_texture_buffer, Ext::EXT_texture_buffer}},
+ Ext::UNDEFINED, 310, -1, Shader::ALL},
+ {"imageStore", std::array<TExtension, 2>{{Ext::OES_texture_buffer, Ext::EXT_texture_buffer}},
+ Ext::UNDEFINED, 310, -1, Shader::ALL},
+ {"imageLoad", std::array<TExtension, 2>{{Ext::OES_texture_buffer, Ext::EXT_texture_buffer}},
+ Ext::UNDEFINED, 310, -1, Shader::ALL},
+ {"imageAtomicAdd", std::array<TExtension, 1>{{Ext::OES_shader_image_atomic}}, Ext::UNDEFINED,
+ 310, -1, Shader::ALL},
+ {"imageAtomicMin", std::array<TExtension, 1>{{Ext::OES_shader_image_atomic}}, Ext::UNDEFINED,
+ 310, -1, Shader::ALL},
+ {"imageAtomicMax", std::array<TExtension, 1>{{Ext::OES_shader_image_atomic}}, Ext::UNDEFINED,
+ 310, -1, Shader::ALL},
+ {"imageAtomicAnd", std::array<TExtension, 1>{{Ext::OES_shader_image_atomic}}, Ext::UNDEFINED,
+ 310, -1, Shader::ALL},
+ {"imageAtomicOr", std::array<TExtension, 1>{{Ext::OES_shader_image_atomic}}, Ext::UNDEFINED,
+ 310, -1, Shader::ALL},
+ {"imageAtomicXor", std::array<TExtension, 1>{{Ext::OES_shader_image_atomic}}, Ext::UNDEFINED,
+ 310, -1, Shader::ALL},
+ {"imageAtomicExchange", std::array<TExtension, 1>{{Ext::OES_shader_image_atomic}},
+ Ext::UNDEFINED, 310, -1, Shader::ALL},
+ {"imageAtomicCompSwap", std::array<TExtension, 1>{{Ext::OES_shader_image_atomic}},
+ Ext::UNDEFINED, 310, -1, Shader::ALL},
+ {"pixelLocalLoadANGLE", std::array<TExtension, 1>{{Ext::ANGLE_shader_pixel_local_storage}},
+ Ext::UNDEFINED, 300, -1, Shader::ALL},
+ {"pixelLocalStoreANGLE", std::array<TExtension, 1>{{Ext::ANGLE_shader_pixel_local_storage}},
+ Ext::UNDEFINED, 300, -1, Shader::ALL},
+ {"beginInvocationInterlockNV", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED,
+ kESSLInternalBackendBuiltIns, -1, Shader::ALL},
+ {"endInvocationInterlockNV", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED,
+ kESSLInternalBackendBuiltIns, -1, Shader::ALL},
+ {"beginFragmentShaderOrderingINTEL", std::array<TExtension, 1>{{Ext::UNDEFINED}},
+ Ext::UNDEFINED, kESSLInternalBackendBuiltIns, -1, Shader::ALL},
+ {"beginInvocationInterlockARB", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED,
+ kESSLInternalBackendBuiltIns, -1, Shader::ALL},
+ {"endInvocationInterlockARB", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED,
+ kESSLInternalBackendBuiltIns, -1, Shader::ALL},
+ {"memoryBarrier", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 420,
+ Shader::ALL},
+ {"memoryBarrierAtomicCounter", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310,
+ 430, Shader::ALL},
+ {"memoryBarrierBuffer", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 430,
+ Shader::ALL},
+ {"memoryBarrierImage", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 430,
+ Shader::ALL},
+ {"barrier", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 320, -1,
+ Shader::TESS_CONTROL_EXT},
+ {"memoryBarrierShared", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 430,
+ Shader::COMPUTE},
+ {"groupMemoryBarrier", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 310, 430,
+ Shader::COMPUTE},
+ {"EmitVertex", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 320, -1,
+ Shader::GEOMETRY},
+ {"EndPrimitive", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED, 320, -1,
+ Shader::GEOMETRY},
+ {"subpassLoad", std::array<TExtension, 1>{{Ext::UNDEFINED}}, Ext::UNDEFINED,
+ kESSLInternalBackendBuiltIns, 460, Shader::ALL}};
+
+} // namespace BuiltInArray
+
+void TSymbolTable::initializeBuiltInVariables(sh::GLenum shaderType,
+ ShShaderSpec spec,
+ const ShBuiltInResources &resources)
+{
+ const TSourceLoc zeroSourceLoc = {0, 0, 0, 0};
+ TFieldList *fields_gl_DepthRangeParameters = new TFieldList();
+ fields_gl_DepthRangeParameters->push_back(
+ new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1, 1), BuiltInName::near, zeroSourceLoc,
+ SymbolType::BuiltIn));
+ fields_gl_DepthRangeParameters->push_back(
+ new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1, 1), BuiltInName::far, zeroSourceLoc,
+ SymbolType::BuiltIn));
+ fields_gl_DepthRangeParameters->push_back(
+ new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1, 1), BuiltInName::diff, zeroSourceLoc,
+ SymbolType::BuiltIn));
+ TStructure *gl_DepthRangeParameters = new TStructure(
+ BuiltInId::gl_DepthRangeParameters, BuiltInName::gl_DepthRangeParameters,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, fields_gl_DepthRangeParameters);
+ m_gl_DepthRangeParameters = gl_DepthRangeParameters;
+ TType *type_gl_DepthRange = new TType(gl_DepthRangeParameters, false);
+ type_gl_DepthRange->setQualifier(EvqUniform);
+ type_gl_DepthRange->realize();
+ m_gl_DepthRange =
+ new TVariable(BuiltInId::gl_DepthRange, BuiltInName::gl_DepthRange, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, type_gl_DepthRange);
+ m_gl_MaxVertexAttribs =
+ new TVariable(BuiltInId::gl_MaxVertexAttribs, BuiltInName::gl_MaxVertexAttribs,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxVertexAttribs);
+ static_cast<TVariable *>(m_gl_MaxVertexAttribs)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxVertexUniformVectors = new TVariable(
+ BuiltInId::gl_MaxVertexUniformVectors, BuiltInName::gl_MaxVertexUniformVectors,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxVertexUniformVectors);
+ static_cast<TVariable *>(m_gl_MaxVertexUniformVectors)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxVertexTextureImageUnits = new TVariable(
+ BuiltInId::gl_MaxVertexTextureImageUnits, BuiltInName::gl_MaxVertexTextureImageUnits,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxVertexTextureImageUnits);
+ static_cast<TVariable *>(m_gl_MaxVertexTextureImageUnits)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxCombinedTextureImageUnits = new TVariable(
+ BuiltInId::gl_MaxCombinedTextureImageUnits, BuiltInName::gl_MaxCombinedTextureImageUnits,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxCombinedTextureImageUnits);
+ static_cast<TVariable *>(m_gl_MaxCombinedTextureImageUnits)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTextureImageUnits =
+ new TVariable(BuiltInId::gl_MaxTextureImageUnits, BuiltInName::gl_MaxTextureImageUnits,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTextureImageUnits);
+ static_cast<TVariable *>(m_gl_MaxTextureImageUnits)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxFragmentUniformVectors = new TVariable(
+ BuiltInId::gl_MaxFragmentUniformVectors, BuiltInName::gl_MaxFragmentUniformVectors,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxFragmentUniformVectors);
+ static_cast<TVariable *>(m_gl_MaxFragmentUniformVectors)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxVaryingVectors =
+ new TVariable(BuiltInId::gl_MaxVaryingVectors, BuiltInName::gl_MaxVaryingVectors,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxVaryingVectors);
+ static_cast<TVariable *>(m_gl_MaxVaryingVectors)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxDrawBuffers =
+ new TVariable(BuiltInId::gl_MaxDrawBuffers, BuiltInName::gl_MaxDrawBuffers,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxDrawBuffers);
+ static_cast<TVariable *>(m_gl_MaxDrawBuffers)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxDualSourceDrawBuffersEXT = new TVariable(
+ BuiltInId::gl_MaxDualSourceDrawBuffersEXT, BuiltInName::gl_MaxDualSourceDrawBuffersEXT,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::EXT_blend_func_extended}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxDualSourceDrawBuffers);
+ static_cast<TVariable *>(m_gl_MaxDualSourceDrawBuffersEXT)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxVertexOutputVectors =
+ new TVariable(BuiltInId::gl_MaxVertexOutputVectors, BuiltInName::gl_MaxVertexOutputVectors,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxVertexOutputVectors);
+ static_cast<TVariable *>(m_gl_MaxVertexOutputVectors)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxFragmentInputVectors = new TVariable(
+ BuiltInId::gl_MaxFragmentInputVectors, BuiltInName::gl_MaxFragmentInputVectors,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxFragmentInputVectors);
+ static_cast<TVariable *>(m_gl_MaxFragmentInputVectors)->shareConstPointer(unionArray);
+ }
+ m_gl_MinProgramTexelOffset =
+ new TVariable(BuiltInId::gl_MinProgramTexelOffset, BuiltInName::gl_MinProgramTexelOffset,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MinProgramTexelOffset);
+ static_cast<TVariable *>(m_gl_MinProgramTexelOffset)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxProgramTexelOffset =
+ new TVariable(BuiltInId::gl_MaxProgramTexelOffset, BuiltInName::gl_MaxProgramTexelOffset,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxProgramTexelOffset);
+ static_cast<TVariable *>(m_gl_MaxProgramTexelOffset)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxImageUnits =
+ new TVariable(BuiltInId::gl_MaxImageUnits, BuiltInName::gl_MaxImageUnits,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxImageUnits);
+ static_cast<TVariable *>(m_gl_MaxImageUnits)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxVertexImageUniforms =
+ new TVariable(BuiltInId::gl_MaxVertexImageUniforms, BuiltInName::gl_MaxVertexImageUniforms,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxVertexImageUniforms);
+ static_cast<TVariable *>(m_gl_MaxVertexImageUniforms)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxFragmentImageUniforms = new TVariable(
+ BuiltInId::gl_MaxFragmentImageUniforms, BuiltInName::gl_MaxFragmentImageUniforms,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxFragmentImageUniforms);
+ static_cast<TVariable *>(m_gl_MaxFragmentImageUniforms)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxComputeImageUniforms = new TVariable(
+ BuiltInId::gl_MaxComputeImageUniforms, BuiltInName::gl_MaxComputeImageUniforms,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxComputeImageUniforms);
+ static_cast<TVariable *>(m_gl_MaxComputeImageUniforms)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxCombinedImageUniforms = new TVariable(
+ BuiltInId::gl_MaxCombinedImageUniforms, BuiltInName::gl_MaxCombinedImageUniforms,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxCombinedImageUniforms);
+ static_cast<TVariable *>(m_gl_MaxCombinedImageUniforms)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxCombinedShaderOutputResources =
+ new TVariable(BuiltInId::gl_MaxCombinedShaderOutputResources,
+ BuiltInName::gl_MaxCombinedShaderOutputResources, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxCombinedShaderOutputResources);
+ static_cast<TVariable *>(m_gl_MaxCombinedShaderOutputResources)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxComputeWorkGroupCount = new TVariable(
+ BuiltInId::gl_MaxComputeWorkGroupCount, BuiltInName::gl_MaxComputeWorkGroupCount,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpHigh, EvqConst, 3, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[3];
+ for (size_t index = 0u; index < 3; ++index)
+ {
+ unionArray[index].setIConst(resources.MaxComputeWorkGroupCount[index]);
+ }
+ static_cast<TVariable *>(m_gl_MaxComputeWorkGroupCount)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxComputeWorkGroupSize = new TVariable(
+ BuiltInId::gl_MaxComputeWorkGroupSize, BuiltInName::gl_MaxComputeWorkGroupSize,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpHigh, EvqConst, 3, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[3];
+ for (size_t index = 0u; index < 3; ++index)
+ {
+ unionArray[index].setIConst(resources.MaxComputeWorkGroupSize[index]);
+ }
+ static_cast<TVariable *>(m_gl_MaxComputeWorkGroupSize)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxComputeUniformComponents = new TVariable(
+ BuiltInId::gl_MaxComputeUniformComponents, BuiltInName::gl_MaxComputeUniformComponents,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxComputeUniformComponents);
+ static_cast<TVariable *>(m_gl_MaxComputeUniformComponents)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxComputeTextureImageUnits = new TVariable(
+ BuiltInId::gl_MaxComputeTextureImageUnits, BuiltInName::gl_MaxComputeTextureImageUnits,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxComputeTextureImageUnits);
+ static_cast<TVariable *>(m_gl_MaxComputeTextureImageUnits)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxComputeAtomicCounters = new TVariable(
+ BuiltInId::gl_MaxComputeAtomicCounters, BuiltInName::gl_MaxComputeAtomicCounters,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxComputeAtomicCounters);
+ static_cast<TVariable *>(m_gl_MaxComputeAtomicCounters)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxComputeAtomicCounterBuffers =
+ new TVariable(BuiltInId::gl_MaxComputeAtomicCounterBuffers,
+ BuiltInName::gl_MaxComputeAtomicCounterBuffers, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxComputeAtomicCounterBuffers);
+ static_cast<TVariable *>(m_gl_MaxComputeAtomicCounterBuffers)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxVertexAtomicCounters = new TVariable(
+ BuiltInId::gl_MaxVertexAtomicCounters, BuiltInName::gl_MaxVertexAtomicCounters,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxVertexAtomicCounters);
+ static_cast<TVariable *>(m_gl_MaxVertexAtomicCounters)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxFragmentAtomicCounters = new TVariable(
+ BuiltInId::gl_MaxFragmentAtomicCounters, BuiltInName::gl_MaxFragmentAtomicCounters,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxFragmentAtomicCounters);
+ static_cast<TVariable *>(m_gl_MaxFragmentAtomicCounters)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxCombinedAtomicCounters = new TVariable(
+ BuiltInId::gl_MaxCombinedAtomicCounters, BuiltInName::gl_MaxCombinedAtomicCounters,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxCombinedAtomicCounters);
+ static_cast<TVariable *>(m_gl_MaxCombinedAtomicCounters)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxAtomicCounterBindings = new TVariable(
+ BuiltInId::gl_MaxAtomicCounterBindings, BuiltInName::gl_MaxAtomicCounterBindings,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxAtomicCounterBindings);
+ static_cast<TVariable *>(m_gl_MaxAtomicCounterBindings)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxVertexAtomicCounterBuffers = new TVariable(
+ BuiltInId::gl_MaxVertexAtomicCounterBuffers, BuiltInName::gl_MaxVertexAtomicCounterBuffers,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxVertexAtomicCounterBuffers);
+ static_cast<TVariable *>(m_gl_MaxVertexAtomicCounterBuffers)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxFragmentAtomicCounterBuffers =
+ new TVariable(BuiltInId::gl_MaxFragmentAtomicCounterBuffers,
+ BuiltInName::gl_MaxFragmentAtomicCounterBuffers, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxFragmentAtomicCounterBuffers);
+ static_cast<TVariable *>(m_gl_MaxFragmentAtomicCounterBuffers)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxCombinedAtomicCounterBuffers =
+ new TVariable(BuiltInId::gl_MaxCombinedAtomicCounterBuffers,
+ BuiltInName::gl_MaxCombinedAtomicCounterBuffers, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxCombinedAtomicCounterBuffers);
+ static_cast<TVariable *>(m_gl_MaxCombinedAtomicCounterBuffers)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxAtomicCounterBufferSize = new TVariable(
+ BuiltInId::gl_MaxAtomicCounterBufferSize, BuiltInName::gl_MaxAtomicCounterBufferSize,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxAtomicCounterBufferSize);
+ static_cast<TVariable *>(m_gl_MaxAtomicCounterBufferSize)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxGeometryInputComponents =
+ new TVariable(BuiltInId::gl_MaxGeometryInputComponents,
+ BuiltInName::gl_MaxGeometryInputComponents, SymbolType::BuiltIn,
+ std::array<TExtension, 2u>{
+ {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxGeometryInputComponents);
+ static_cast<TVariable *>(m_gl_MaxGeometryInputComponents)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxGeometryInputComponentsES3_2 = new TVariable(
+ BuiltInId::gl_MaxGeometryInputComponentsES3_2, BuiltInName::gl_MaxGeometryInputComponents,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxGeometryInputComponents);
+ static_cast<TVariable *>(m_gl_MaxGeometryInputComponentsES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxGeometryOutputComponents =
+ new TVariable(BuiltInId::gl_MaxGeometryOutputComponents,
+ BuiltInName::gl_MaxGeometryOutputComponents, SymbolType::BuiltIn,
+ std::array<TExtension, 2u>{
+ {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxGeometryOutputComponents);
+ static_cast<TVariable *>(m_gl_MaxGeometryOutputComponents)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxGeometryOutputComponentsES3_2 = new TVariable(
+ BuiltInId::gl_MaxGeometryOutputComponentsES3_2, BuiltInName::gl_MaxGeometryOutputComponents,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxGeometryOutputComponents);
+ static_cast<TVariable *>(m_gl_MaxGeometryOutputComponentsES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxGeometryImageUniforms =
+ new TVariable(BuiltInId::gl_MaxGeometryImageUniforms,
+ BuiltInName::gl_MaxGeometryImageUniforms, SymbolType::BuiltIn,
+ std::array<TExtension, 2u>{
+ {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxGeometryImageUniforms);
+ static_cast<TVariable *>(m_gl_MaxGeometryImageUniforms)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxGeometryImageUniformsES3_2 = new TVariable(
+ BuiltInId::gl_MaxGeometryImageUniformsES3_2, BuiltInName::gl_MaxGeometryImageUniforms,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxGeometryImageUniforms);
+ static_cast<TVariable *>(m_gl_MaxGeometryImageUniformsES3_2)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxGeometryTextureImageUnits =
+ new TVariable(BuiltInId::gl_MaxGeometryTextureImageUnits,
+ BuiltInName::gl_MaxGeometryTextureImageUnits, SymbolType::BuiltIn,
+ std::array<TExtension, 2u>{
+ {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxGeometryTextureImageUnits);
+ static_cast<TVariable *>(m_gl_MaxGeometryTextureImageUnits)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxGeometryTextureImageUnitsES3_2 =
+ new TVariable(BuiltInId::gl_MaxGeometryTextureImageUnitsES3_2,
+ BuiltInName::gl_MaxGeometryTextureImageUnits, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxGeometryTextureImageUnits);
+ static_cast<TVariable *>(m_gl_MaxGeometryTextureImageUnitsES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxGeometryOutputVertices =
+ new TVariable(BuiltInId::gl_MaxGeometryOutputVertices,
+ BuiltInName::gl_MaxGeometryOutputVertices, SymbolType::BuiltIn,
+ std::array<TExtension, 2u>{
+ {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxGeometryOutputVertices);
+ static_cast<TVariable *>(m_gl_MaxGeometryOutputVertices)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxGeometryOutputVerticesES3_2 = new TVariable(
+ BuiltInId::gl_MaxGeometryOutputVerticesES3_2, BuiltInName::gl_MaxGeometryOutputVertices,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxGeometryOutputVertices);
+ static_cast<TVariable *>(m_gl_MaxGeometryOutputVerticesES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxGeometryTotalOutputComponents =
+ new TVariable(BuiltInId::gl_MaxGeometryTotalOutputComponents,
+ BuiltInName::gl_MaxGeometryTotalOutputComponents, SymbolType::BuiltIn,
+ std::array<TExtension, 2u>{
+ {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxGeometryTotalOutputComponents);
+ static_cast<TVariable *>(m_gl_MaxGeometryTotalOutputComponents)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxGeometryTotalOutputComponentsES3_2 =
+ new TVariable(BuiltInId::gl_MaxGeometryTotalOutputComponentsES3_2,
+ BuiltInName::gl_MaxGeometryTotalOutputComponents, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxGeometryTotalOutputComponents);
+ static_cast<TVariable *>(m_gl_MaxGeometryTotalOutputComponentsES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxGeometryUniformComponents =
+ new TVariable(BuiltInId::gl_MaxGeometryUniformComponents,
+ BuiltInName::gl_MaxGeometryUniformComponents, SymbolType::BuiltIn,
+ std::array<TExtension, 2u>{
+ {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxGeometryUniformComponents);
+ static_cast<TVariable *>(m_gl_MaxGeometryUniformComponents)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxGeometryUniformComponentsES3_2 =
+ new TVariable(BuiltInId::gl_MaxGeometryUniformComponentsES3_2,
+ BuiltInName::gl_MaxGeometryUniformComponents, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxGeometryUniformComponents);
+ static_cast<TVariable *>(m_gl_MaxGeometryUniformComponentsES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxGeometryAtomicCounters =
+ new TVariable(BuiltInId::gl_MaxGeometryAtomicCounters,
+ BuiltInName::gl_MaxGeometryAtomicCounters, SymbolType::BuiltIn,
+ std::array<TExtension, 2u>{
+ {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxGeometryAtomicCounters);
+ static_cast<TVariable *>(m_gl_MaxGeometryAtomicCounters)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxGeometryAtomicCountersES3_2 = new TVariable(
+ BuiltInId::gl_MaxGeometryAtomicCountersES3_2, BuiltInName::gl_MaxGeometryAtomicCounters,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxGeometryAtomicCounters);
+ static_cast<TVariable *>(m_gl_MaxGeometryAtomicCountersES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxGeometryAtomicCounterBuffers =
+ new TVariable(BuiltInId::gl_MaxGeometryAtomicCounterBuffers,
+ BuiltInName::gl_MaxGeometryAtomicCounterBuffers, SymbolType::BuiltIn,
+ std::array<TExtension, 2u>{
+ {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxGeometryAtomicCounterBuffers);
+ static_cast<TVariable *>(m_gl_MaxGeometryAtomicCounterBuffers)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxGeometryAtomicCounterBuffersES3_2 =
+ new TVariable(BuiltInId::gl_MaxGeometryAtomicCounterBuffersES3_2,
+ BuiltInName::gl_MaxGeometryAtomicCounterBuffers, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxGeometryAtomicCounterBuffers);
+ static_cast<TVariable *>(m_gl_MaxGeometryAtomicCounterBuffersES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessControlInputComponents = new TVariable(
+ BuiltInId::gl_MaxTessControlInputComponents, BuiltInName::gl_MaxTessControlInputComponents,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessControlInputComponents);
+ static_cast<TVariable *>(m_gl_MaxTessControlInputComponents)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessControlInputComponentsES3_2 =
+ new TVariable(BuiltInId::gl_MaxTessControlInputComponentsES3_2,
+ BuiltInName::gl_MaxTessControlInputComponents, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessControlInputComponents);
+ static_cast<TVariable *>(m_gl_MaxTessControlInputComponentsES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessControlOutputComponents =
+ new TVariable(BuiltInId::gl_MaxTessControlOutputComponents,
+ BuiltInName::gl_MaxTessControlOutputComponents, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessControlOutputComponents);
+ static_cast<TVariable *>(m_gl_MaxTessControlOutputComponents)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessControlOutputComponentsES3_2 =
+ new TVariable(BuiltInId::gl_MaxTessControlOutputComponentsES3_2,
+ BuiltInName::gl_MaxTessControlOutputComponents, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessControlOutputComponents);
+ static_cast<TVariable *>(m_gl_MaxTessControlOutputComponentsES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessControlTextureImageUnits =
+ new TVariable(BuiltInId::gl_MaxTessControlTextureImageUnits,
+ BuiltInName::gl_MaxTessControlTextureImageUnits, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessControlTextureImageUnits);
+ static_cast<TVariable *>(m_gl_MaxTessControlTextureImageUnits)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessControlTextureImageUnitsES3_2 =
+ new TVariable(BuiltInId::gl_MaxTessControlTextureImageUnitsES3_2,
+ BuiltInName::gl_MaxTessControlTextureImageUnits, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessControlTextureImageUnits);
+ static_cast<TVariable *>(m_gl_MaxTessControlTextureImageUnitsES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessControlUniformComponents =
+ new TVariable(BuiltInId::gl_MaxTessControlUniformComponents,
+ BuiltInName::gl_MaxTessControlUniformComponents, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessControlUniformComponents);
+ static_cast<TVariable *>(m_gl_MaxTessControlUniformComponents)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessControlUniformComponentsES3_2 =
+ new TVariable(BuiltInId::gl_MaxTessControlUniformComponentsES3_2,
+ BuiltInName::gl_MaxTessControlUniformComponents, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessControlUniformComponents);
+ static_cast<TVariable *>(m_gl_MaxTessControlUniformComponentsES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessControlTotalOutputComponents =
+ new TVariable(BuiltInId::gl_MaxTessControlTotalOutputComponents,
+ BuiltInName::gl_MaxTessControlTotalOutputComponents, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessControlTotalOutputComponents);
+ static_cast<TVariable *>(m_gl_MaxTessControlTotalOutputComponents)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessControlTotalOutputComponentsES3_2 =
+ new TVariable(BuiltInId::gl_MaxTessControlTotalOutputComponentsES3_2,
+ BuiltInName::gl_MaxTessControlTotalOutputComponents, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessControlTotalOutputComponents);
+ static_cast<TVariable *>(m_gl_MaxTessControlTotalOutputComponentsES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessControlImageUniforms = new TVariable(
+ BuiltInId::gl_MaxTessControlImageUniforms, BuiltInName::gl_MaxTessControlImageUniforms,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessControlImageUniforms);
+ static_cast<TVariable *>(m_gl_MaxTessControlImageUniforms)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessControlImageUniformsES3_2 = new TVariable(
+ BuiltInId::gl_MaxTessControlImageUniformsES3_2, BuiltInName::gl_MaxTessControlImageUniforms,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessControlImageUniforms);
+ static_cast<TVariable *>(m_gl_MaxTessControlImageUniformsES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessControlAtomicCounters = new TVariable(
+ BuiltInId::gl_MaxTessControlAtomicCounters, BuiltInName::gl_MaxTessControlAtomicCounters,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessControlAtomicCounters);
+ static_cast<TVariable *>(m_gl_MaxTessControlAtomicCounters)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessControlAtomicCountersES3_2 =
+ new TVariable(BuiltInId::gl_MaxTessControlAtomicCountersES3_2,
+ BuiltInName::gl_MaxTessControlAtomicCounters, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessControlAtomicCounters);
+ static_cast<TVariable *>(m_gl_MaxTessControlAtomicCountersES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessControlAtomicCounterBuffers =
+ new TVariable(BuiltInId::gl_MaxTessControlAtomicCounterBuffers,
+ BuiltInName::gl_MaxTessControlAtomicCounterBuffers, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessControlAtomicCounterBuffers);
+ static_cast<TVariable *>(m_gl_MaxTessControlAtomicCounterBuffers)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessControlAtomicCounterBuffersES3_2 =
+ new TVariable(BuiltInId::gl_MaxTessControlAtomicCounterBuffersES3_2,
+ BuiltInName::gl_MaxTessControlAtomicCounterBuffers, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessControlAtomicCounterBuffers);
+ static_cast<TVariable *>(m_gl_MaxTessControlAtomicCounterBuffersES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessPatchComponents = new TVariable(
+ BuiltInId::gl_MaxTessPatchComponents, BuiltInName::gl_MaxTessPatchComponents,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessPatchComponents);
+ static_cast<TVariable *>(m_gl_MaxTessPatchComponents)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessPatchComponentsES3_2 = new TVariable(
+ BuiltInId::gl_MaxTessPatchComponentsES3_2, BuiltInName::gl_MaxTessPatchComponents,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessPatchComponents);
+ static_cast<TVariable *>(m_gl_MaxTessPatchComponentsES3_2)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxPatchVertices = new TVariable(
+ BuiltInId::gl_MaxPatchVertices, BuiltInName::gl_MaxPatchVertices, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxPatchVertices);
+ static_cast<TVariable *>(m_gl_MaxPatchVertices)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxPatchVerticesES3_2 =
+ new TVariable(BuiltInId::gl_MaxPatchVerticesES3_2, BuiltInName::gl_MaxPatchVertices,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxPatchVertices);
+ static_cast<TVariable *>(m_gl_MaxPatchVerticesES3_2)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessGenLevel = new TVariable(
+ BuiltInId::gl_MaxTessGenLevel, BuiltInName::gl_MaxTessGenLevel, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessGenLevel);
+ static_cast<TVariable *>(m_gl_MaxTessGenLevel)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessGenLevelES3_2 =
+ new TVariable(BuiltInId::gl_MaxTessGenLevelES3_2, BuiltInName::gl_MaxTessGenLevel,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessGenLevel);
+ static_cast<TVariable *>(m_gl_MaxTessGenLevelES3_2)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessEvaluationInputComponents =
+ new TVariable(BuiltInId::gl_MaxTessEvaluationInputComponents,
+ BuiltInName::gl_MaxTessEvaluationInputComponents, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessEvaluationInputComponents);
+ static_cast<TVariable *>(m_gl_MaxTessEvaluationInputComponents)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessEvaluationInputComponentsES3_2 =
+ new TVariable(BuiltInId::gl_MaxTessEvaluationInputComponentsES3_2,
+ BuiltInName::gl_MaxTessEvaluationInputComponents, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessEvaluationInputComponents);
+ static_cast<TVariable *>(m_gl_MaxTessEvaluationInputComponentsES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessEvaluationOutputComponents =
+ new TVariable(BuiltInId::gl_MaxTessEvaluationOutputComponents,
+ BuiltInName::gl_MaxTessEvaluationOutputComponents, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessEvaluationOutputComponents);
+ static_cast<TVariable *>(m_gl_MaxTessEvaluationOutputComponents)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessEvaluationOutputComponentsES3_2 =
+ new TVariable(BuiltInId::gl_MaxTessEvaluationOutputComponentsES3_2,
+ BuiltInName::gl_MaxTessEvaluationOutputComponents, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessEvaluationOutputComponents);
+ static_cast<TVariable *>(m_gl_MaxTessEvaluationOutputComponentsES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessEvaluationTextureImageUnits =
+ new TVariable(BuiltInId::gl_MaxTessEvaluationTextureImageUnits,
+ BuiltInName::gl_MaxTessEvaluationTextureImageUnits, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessEvaluationTextureImageUnits);
+ static_cast<TVariable *>(m_gl_MaxTessEvaluationTextureImageUnits)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessEvaluationTextureImageUnitsES3_2 =
+ new TVariable(BuiltInId::gl_MaxTessEvaluationTextureImageUnitsES3_2,
+ BuiltInName::gl_MaxTessEvaluationTextureImageUnits, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessEvaluationTextureImageUnits);
+ static_cast<TVariable *>(m_gl_MaxTessEvaluationTextureImageUnitsES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessEvaluationUniformComponents =
+ new TVariable(BuiltInId::gl_MaxTessEvaluationUniformComponents,
+ BuiltInName::gl_MaxTessEvaluationUniformComponents, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessEvaluationUniformComponents);
+ static_cast<TVariable *>(m_gl_MaxTessEvaluationUniformComponents)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessEvaluationUniformComponentsES3_2 =
+ new TVariable(BuiltInId::gl_MaxTessEvaluationUniformComponentsES3_2,
+ BuiltInName::gl_MaxTessEvaluationUniformComponents, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessEvaluationUniformComponents);
+ static_cast<TVariable *>(m_gl_MaxTessEvaluationUniformComponentsES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessEvaluationImageUniforms =
+ new TVariable(BuiltInId::gl_MaxTessEvaluationImageUniforms,
+ BuiltInName::gl_MaxTessEvaluationImageUniforms, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessEvaluationImageUniforms);
+ static_cast<TVariable *>(m_gl_MaxTessEvaluationImageUniforms)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessEvaluationImageUniformsES3_2 =
+ new TVariable(BuiltInId::gl_MaxTessEvaluationImageUniformsES3_2,
+ BuiltInName::gl_MaxTessEvaluationImageUniforms, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessEvaluationImageUniforms);
+ static_cast<TVariable *>(m_gl_MaxTessEvaluationImageUniformsES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessEvaluationAtomicCounters =
+ new TVariable(BuiltInId::gl_MaxTessEvaluationAtomicCounters,
+ BuiltInName::gl_MaxTessEvaluationAtomicCounters, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessEvaluationAtomicCounters);
+ static_cast<TVariable *>(m_gl_MaxTessEvaluationAtomicCounters)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessEvaluationAtomicCountersES3_2 =
+ new TVariable(BuiltInId::gl_MaxTessEvaluationAtomicCountersES3_2,
+ BuiltInName::gl_MaxTessEvaluationAtomicCounters, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessEvaluationAtomicCounters);
+ static_cast<TVariable *>(m_gl_MaxTessEvaluationAtomicCountersES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessEvaluationAtomicCounterBuffers =
+ new TVariable(BuiltInId::gl_MaxTessEvaluationAtomicCounterBuffers,
+ BuiltInName::gl_MaxTessEvaluationAtomicCounterBuffers, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessEvaluationAtomicCounterBuffers);
+ static_cast<TVariable *>(m_gl_MaxTessEvaluationAtomicCounterBuffers)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxTessEvaluationAtomicCounterBuffersES3_2 =
+ new TVariable(BuiltInId::gl_MaxTessEvaluationAtomicCounterBuffersES3_2,
+ BuiltInName::gl_MaxTessEvaluationAtomicCounterBuffers, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxTessEvaluationAtomicCounterBuffers);
+ static_cast<TVariable *>(m_gl_MaxTessEvaluationAtomicCounterBuffersES3_2)
+ ->shareConstPointer(unionArray);
+ }
+ m_gl_MaxSamples =
+ new TVariable(BuiltInId::gl_MaxSamples, BuiltInName::gl_MaxSamples, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::OES_sample_variables}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxSamples);
+ static_cast<TVariable *>(m_gl_MaxSamples)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxSamplesES3_2 =
+ new TVariable(BuiltInId::gl_MaxSamplesES3_2, BuiltInName::gl_MaxSamples,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::UNDEFINED}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxSamples);
+ static_cast<TVariable *>(m_gl_MaxSamplesES3_2)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxClipDistancesAPPLE = new TVariable(
+ BuiltInId::gl_MaxClipDistancesAPPLE, BuiltInName::gl_MaxClipDistances, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::APPLE_clip_distance}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxClipDistances);
+ static_cast<TVariable *>(m_gl_MaxClipDistancesAPPLE)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxCullDistancesEXT = new TVariable(
+ BuiltInId::gl_MaxCullDistancesEXT, BuiltInName::gl_MaxCullDistances, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_clip_cull_distance}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxCullDistances);
+ static_cast<TVariable *>(m_gl_MaxCullDistancesEXT)->shareConstPointer(unionArray);
+ }
+ m_gl_MaxCombinedClipAndCullDistancesEXT =
+ new TVariable(BuiltInId::gl_MaxCombinedClipAndCullDistancesEXT,
+ BuiltInName::gl_MaxCombinedClipAndCullDistances, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_clip_cull_distance}},
+ StaticType::Get<EbtInt, EbpMedium, EvqConst, 1, 1>());
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray[0].setIConst(resources.MaxCombinedClipAndCullDistances);
+ static_cast<TVariable *>(m_gl_MaxCombinedClipAndCullDistancesEXT)
+ ->shareConstPointer(unionArray);
+ }
+ TType *type_gl_FragData = new TType(EbtFloat, EbpMedium, EvqFragData, 4);
+ if (spec != SH_WEBGL2_SPEC && spec != SH_WEBGL3_SPEC)
+ {
+ type_gl_FragData->makeArray(resources.MaxDrawBuffers);
+ }
+ else
+ {
+ type_gl_FragData->makeArray(1u);
+ }
+ type_gl_FragData->realize();
+ m_gl_FragData =
+ new TVariable(BuiltInId::gl_FragData, BuiltInName::gl_FragData, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, type_gl_FragData);
+ TType *type_gl_SecondaryFragDataEXT =
+ new TType(EbtFloat, EbpMedium, EvqSecondaryFragDataEXT, 4, 1);
+ type_gl_SecondaryFragDataEXT->makeArray(resources.MaxDualSourceDrawBuffers);
+ type_gl_SecondaryFragDataEXT->realize();
+ m_gl_SecondaryFragDataEXT = new TVariable(
+ BuiltInId::gl_SecondaryFragDataEXT, BuiltInName::gl_SecondaryFragDataEXT,
+ SymbolType::BuiltIn, std::array<TExtension, 1u>{{TExtension::EXT_blend_func_extended}},
+ type_gl_SecondaryFragDataEXT);
+ TType *type_gl_FragDepthEXT =
+ new TType(EbtFloat, resources.FragmentPrecisionHigh ? EbpHigh : EbpMedium, EvqFragDepth, 1);
+ type_gl_FragDepthEXT->realize();
+ m_gl_FragDepthEXT = new TVariable(
+ BuiltInId::gl_FragDepthEXT, BuiltInName::gl_FragDepthEXT, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_frag_depth}}, type_gl_FragDepthEXT);
+ TType *type_gl_LastFragData = new TType(EbtFloat, EbpMedium, EvqLastFragData, 4, 1);
+ type_gl_LastFragData->makeArray(resources.MaxDrawBuffers);
+ type_gl_LastFragData->realize();
+ m_gl_LastFragData = new TVariable(
+ BuiltInId::gl_LastFragData, BuiltInName::gl_LastFragData, SymbolType::BuiltIn,
+ std::array<TExtension, 2u>{{TExtension::EXT_shader_framebuffer_fetch,
+ TExtension::EXT_shader_framebuffer_fetch_non_coherent}},
+ type_gl_LastFragData);
+ TType *type_gl_LastFragDataNV = new TType(EbtFloat, EbpMedium, EvqLastFragData, 4, 1);
+ type_gl_LastFragDataNV->makeArray(resources.MaxDrawBuffers);
+ type_gl_LastFragDataNV->realize();
+ m_gl_LastFragDataNV = new TVariable(
+ BuiltInId::gl_LastFragDataNV, BuiltInName::gl_LastFragData, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::NV_shader_framebuffer_fetch}},
+ type_gl_LastFragDataNV);
+ TType *type_gl_SampleMaskIn = new TType(EbtInt, EbpHigh, EvqSampleMaskIn, 1);
+ type_gl_SampleMaskIn->makeArray((resources.MaxSamples + 31) / 32);
+ type_gl_SampleMaskIn->realize();
+ m_gl_SampleMaskIn = new TVariable(
+ BuiltInId::gl_SampleMaskIn, BuiltInName::gl_SampleMaskIn, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::OES_sample_variables}}, type_gl_SampleMaskIn);
+ TType *type_gl_SampleMaskInES3_2 = new TType(EbtInt, EbpHigh, EvqSampleMaskIn, 1);
+ type_gl_SampleMaskInES3_2->makeArray((resources.MaxSamples + 31) / 32);
+ type_gl_SampleMaskInES3_2->realize();
+ m_gl_SampleMaskInES3_2 = new TVariable(
+ BuiltInId::gl_SampleMaskInES3_2, BuiltInName::gl_SampleMaskIn, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, type_gl_SampleMaskInES3_2);
+ TType *type_gl_SampleMask = new TType(EbtInt, EbpHigh, EvqSampleMask, 1);
+ type_gl_SampleMask->makeArray((resources.MaxSamples + 31) / 32);
+ type_gl_SampleMask->realize();
+ m_gl_SampleMask = new TVariable(
+ BuiltInId::gl_SampleMask, BuiltInName::gl_SampleMask, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::OES_sample_variables}}, type_gl_SampleMask);
+ TType *type_gl_SampleMaskES3_2 = new TType(EbtInt, EbpHigh, EvqSampleMask, 1);
+ type_gl_SampleMaskES3_2->makeArray((resources.MaxSamples + 31) / 32);
+ type_gl_SampleMaskES3_2->realize();
+ m_gl_SampleMaskES3_2 = new TVariable(
+ BuiltInId::gl_SampleMaskES3_2, BuiltInName::gl_SampleMask, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, type_gl_SampleMaskES3_2);
+ TType *type_gl_CullDistance = new TType(EbtFloat, EbpHigh, EvqCullDistance, 1);
+ type_gl_CullDistance->makeArray(resources.MaxCullDistances);
+ type_gl_CullDistance->realize();
+ m_gl_CullDistance = new TVariable(
+ BuiltInId::gl_CullDistance, BuiltInName::gl_CullDistance, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_clip_cull_distance}}, type_gl_CullDistance);
+ TType *type_gl_ClipDistance = new TType(EbtFloat, EbpHigh, EvqClipDistance, 1);
+ type_gl_ClipDistance->makeArray(resources.MaxClipDistances);
+ type_gl_ClipDistance->realize();
+ m_gl_ClipDistance = new TVariable(
+ BuiltInId::gl_ClipDistance, BuiltInName::gl_ClipDistance, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_clip_cull_distance}}, type_gl_ClipDistance);
+ TType *type_gl_ClipDistanceAPPLE = new TType(EbtFloat, EbpHigh, EvqClipDistance, 1);
+ type_gl_ClipDistanceAPPLE->makeArray(resources.MaxClipDistances);
+ type_gl_ClipDistanceAPPLE->realize();
+ m_gl_ClipDistanceAPPLE = new TVariable(
+ BuiltInId::gl_ClipDistanceAPPLE, BuiltInName::gl_ClipDistance, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::APPLE_clip_distance}}, type_gl_ClipDistanceAPPLE);
+ TType *type_gl_CullDistanceEXT = new TType(EbtFloat, EbpHigh, EvqCullDistance, 1);
+ type_gl_CullDistanceEXT->makeArray(resources.MaxCullDistances);
+ type_gl_CullDistanceEXT->realize();
+ m_gl_CullDistanceEXT = new TVariable(
+ BuiltInId::gl_CullDistanceEXT, BuiltInName::gl_CullDistance, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_clip_cull_distance}}, type_gl_CullDistanceEXT);
+ TFieldList *fields_gl_PerVertex = new TFieldList();
+ fields_gl_PerVertex->push_back(new TField(new TType(EbtFloat, EbpHigh, EvqPosition, 4, 1),
+ BuiltInName::gl_Position, zeroSourceLoc,
+ SymbolType::BuiltIn));
+ TInterfaceBlock *gl_PerVertex =
+ new TInterfaceBlock(BuiltInId::gl_PerVertex, BuiltInName::gl_PerVertex,
+ std::array<TExtension, 2u>{
+ {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}},
+ fields_gl_PerVertex);
+ m_gl_PerVertex = gl_PerVertex;
+ TFieldList *fields_gl_PerVertexES3_2 = new TFieldList();
+ fields_gl_PerVertexES3_2->push_back(new TField(new TType(EbtFloat, EbpHigh, EvqPosition, 4, 1),
+ BuiltInName::gl_Position, zeroSourceLoc,
+ SymbolType::BuiltIn));
+ TInterfaceBlock *gl_PerVertexES3_2 = new TInterfaceBlock(
+ BuiltInId::gl_PerVertexES3_2, BuiltInName::gl_PerVertex,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, fields_gl_PerVertexES3_2);
+ m_gl_PerVertexES3_2 = gl_PerVertexES3_2;
+ TType *type_gl_in = new TType(gl_PerVertex, EvqPerVertexIn, TLayoutQualifier::Create());
+ type_gl_in->makeArray(0u);
+ type_gl_in->realize();
+ m_gl_in = new TVariable(BuiltInId::gl_in, BuiltInName::gl_in, SymbolType::BuiltIn,
+ std::array<TExtension, 2u>{
+ {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}},
+ type_gl_in);
+ TType *type_gl_inES3_2 = new TType(gl_PerVertex, EvqPerVertexIn, TLayoutQualifier::Create());
+ type_gl_inES3_2->makeArray(0u);
+ type_gl_inES3_2->realize();
+ m_gl_inES3_2 =
+ new TVariable(BuiltInId::gl_inES3_2, BuiltInName::gl_in, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, type_gl_inES3_2);
+ TFieldList *fields_gl_PerVertexOutBlock = new TFieldList();
+ fields_gl_PerVertexOutBlock->push_back(
+ new TField(new TType(EbtFloat, EbpHigh, EvqPosition, 4, 1), BuiltInName::gl_Position,
+ zeroSourceLoc, SymbolType::BuiltIn));
+ TInterfaceBlock *gl_PerVertexOutBlock =
+ new TInterfaceBlock(BuiltInId::gl_PerVertexOutBlock, BuiltInName::gl_PerVertex,
+ std::array<TExtension, 2u>{
+ {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}},
+ fields_gl_PerVertexOutBlock);
+ TFieldList *fields_gl_PerVertexOutBlockES3_2 = new TFieldList();
+ fields_gl_PerVertexOutBlockES3_2->push_back(
+ new TField(new TType(EbtFloat, EbpHigh, EvqPosition, 4, 1), BuiltInName::gl_Position,
+ zeroSourceLoc, SymbolType::BuiltIn));
+ TInterfaceBlock *gl_PerVertexOutBlockES3_2 = new TInterfaceBlock(
+ BuiltInId::gl_PerVertexOutBlockES3_2, BuiltInName::gl_PerVertex,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, fields_gl_PerVertexOutBlockES3_2);
+ TType *type_gl_PositionGS = new TType(EbtFloat, EbpHigh, EvqPosition, 4);
+ type_gl_PositionGS->setInterfaceBlock(gl_PerVertexOutBlock);
+ type_gl_PositionGS->realize();
+ m_gl_PositionGS =
+ new TVariable(BuiltInId::gl_PositionGS, BuiltInName::gl_Position, SymbolType::BuiltIn,
+ std::array<TExtension, 2u>{
+ {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}},
+ type_gl_PositionGS);
+ TType *type_gl_PositionGSES3_2 = new TType(EbtFloat, EbpHigh, EvqPosition, 4);
+ type_gl_PositionGSES3_2->setInterfaceBlock(gl_PerVertexOutBlockES3_2);
+ type_gl_PositionGSES3_2->realize();
+ m_gl_PositionGSES3_2 =
+ new TVariable(BuiltInId::gl_PositionGSES3_2, BuiltInName::gl_Position, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, type_gl_PositionGSES3_2);
+ TType *type_gl_TessLevelOuterTCS = new TType(EbtFloat, EbpHigh, EvqTessLevelOuter, 1);
+ type_gl_TessLevelOuterTCS->makeArray(4u);
+ type_gl_TessLevelOuterTCS->realize();
+ m_gl_TessLevelOuterTCS = new TVariable(
+ BuiltInId::gl_TessLevelOuterTCS, BuiltInName::gl_TessLevelOuter, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ type_gl_TessLevelOuterTCS);
+ TType *type_gl_TessLevelOuterTCSES3_2 = new TType(EbtFloat, EbpHigh, EvqTessLevelOuter, 1);
+ type_gl_TessLevelOuterTCSES3_2->makeArray(4u);
+ type_gl_TessLevelOuterTCSES3_2->realize();
+ m_gl_TessLevelOuterTCSES3_2 = new TVariable(
+ BuiltInId::gl_TessLevelOuterTCSES3_2, BuiltInName::gl_TessLevelOuter, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, type_gl_TessLevelOuterTCSES3_2);
+ TType *type_gl_TessLevelInnerTCS = new TType(EbtFloat, EbpHigh, EvqTessLevelInner, 1);
+ type_gl_TessLevelInnerTCS->makeArray(2u);
+ type_gl_TessLevelInnerTCS->realize();
+ m_gl_TessLevelInnerTCS = new TVariable(
+ BuiltInId::gl_TessLevelInnerTCS, BuiltInName::gl_TessLevelInner, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ type_gl_TessLevelInnerTCS);
+ TType *type_gl_TessLevelInnerTCSES3_2 = new TType(EbtFloat, EbpHigh, EvqTessLevelInner, 1);
+ type_gl_TessLevelInnerTCSES3_2->makeArray(2u);
+ type_gl_TessLevelInnerTCSES3_2->realize();
+ m_gl_TessLevelInnerTCSES3_2 = new TVariable(
+ BuiltInId::gl_TessLevelInnerTCSES3_2, BuiltInName::gl_TessLevelInner, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, type_gl_TessLevelInnerTCSES3_2);
+ TFieldList *fields_gl_PerVertexTCS = new TFieldList();
+ fields_gl_PerVertexTCS->push_back(new TField(new TType(EbtFloat, EbpHigh, EvqPosition, 4, 1),
+ BuiltInName::gl_Position, zeroSourceLoc,
+ SymbolType::BuiltIn));
+ TInterfaceBlock *gl_PerVertexTCS = new TInterfaceBlock(
+ BuiltInId::gl_PerVertexTCS, BuiltInName::gl_PerVertex,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}}, fields_gl_PerVertexTCS);
+ m_gl_PerVertexTCS = gl_PerVertexTCS;
+ TFieldList *fields_gl_PerVertexTCSES3_2 = new TFieldList();
+ fields_gl_PerVertexTCSES3_2->push_back(
+ new TField(new TType(EbtFloat, EbpHigh, EvqPosition, 4, 1), BuiltInName::gl_Position,
+ zeroSourceLoc, SymbolType::BuiltIn));
+ TInterfaceBlock *gl_PerVertexTCSES3_2 = new TInterfaceBlock(
+ BuiltInId::gl_PerVertexTCSES3_2, BuiltInName::gl_PerVertex,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, fields_gl_PerVertexTCSES3_2);
+ m_gl_PerVertexTCSES3_2 = gl_PerVertexTCSES3_2;
+ TType *type_gl_inTCS = new TType(gl_PerVertex, EvqPerVertexIn, TLayoutQualifier::Create());
+ type_gl_inTCS->makeArray(resources.MaxPatchVertices);
+ type_gl_inTCS->realize();
+ m_gl_inTCS = new TVariable(BuiltInId::gl_inTCS, BuiltInName::gl_in, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ type_gl_inTCS);
+ TType *type_gl_inTCSES3_2 = new TType(gl_PerVertex, EvqPerVertexIn, TLayoutQualifier::Create());
+ type_gl_inTCSES3_2->makeArray(resources.MaxPatchVertices);
+ type_gl_inTCSES3_2->realize();
+ m_gl_inTCSES3_2 =
+ new TVariable(BuiltInId::gl_inTCSES3_2, BuiltInName::gl_in, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, type_gl_inTCSES3_2);
+ TType *type_gl_outTCS = new TType(gl_PerVertex, EvqPerVertexOut, TLayoutQualifier::Create());
+ type_gl_outTCS->makeArray(resources.MaxPatchVertices);
+ type_gl_outTCS->realize();
+ m_gl_outTCS = new TVariable(BuiltInId::gl_outTCS, BuiltInName::gl_out, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ type_gl_outTCS);
+ TType *type_gl_outTCSES3_2 =
+ new TType(gl_PerVertex, EvqPerVertexOut, TLayoutQualifier::Create());
+ type_gl_outTCSES3_2->makeArray(resources.MaxPatchVertices);
+ type_gl_outTCSES3_2->realize();
+ m_gl_outTCSES3_2 =
+ new TVariable(BuiltInId::gl_outTCSES3_2, BuiltInName::gl_out, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, type_gl_outTCSES3_2);
+ TType *type_gl_BoundingBoxTCS = new TType(EbtFloat, EbpHigh, EvqBoundingBox, 4);
+ type_gl_BoundingBoxTCS->makeArray(2u);
+ type_gl_BoundingBoxTCS->realize();
+ m_gl_BoundingBoxTCS = new TVariable(
+ BuiltInId::gl_BoundingBoxTCS, BuiltInName::gl_BoundingBox, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}}, type_gl_BoundingBoxTCS);
+ TType *type_gl_BoundingBoxTCSES3_2 = new TType(EbtFloat, EbpHigh, EvqBoundingBox, 4);
+ type_gl_BoundingBoxTCSES3_2->makeArray(2u);
+ type_gl_BoundingBoxTCSES3_2->realize();
+ m_gl_BoundingBoxTCSES3_2 = new TVariable(
+ BuiltInId::gl_BoundingBoxTCSES3_2, BuiltInName::gl_BoundingBox, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, type_gl_BoundingBoxTCSES3_2);
+ TFieldList *fields_gl_PerVertexOutTcsBlock = new TFieldList();
+ fields_gl_PerVertexOutTcsBlock->push_back(
+ new TField(new TType(EbtFloat, EbpHigh, EvqPosition, 4, 1), BuiltInName::gl_Position,
+ zeroSourceLoc, SymbolType::BuiltIn));
+ TInterfaceBlock *gl_PerVertexOutTcsBlock =
+ new TInterfaceBlock(BuiltInId::gl_PerVertexOutTcsBlock, BuiltInName::gl_PerVertex,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ fields_gl_PerVertexOutTcsBlock);
+ TFieldList *fields_gl_PerVertexOutTcsBlockES3_2 = new TFieldList();
+ fields_gl_PerVertexOutTcsBlockES3_2->push_back(
+ new TField(new TType(EbtFloat, EbpHigh, EvqPosition, 4, 1), BuiltInName::gl_Position,
+ zeroSourceLoc, SymbolType::BuiltIn));
+ TInterfaceBlock *gl_PerVertexOutTcsBlockES3_2 = new TInterfaceBlock(
+ BuiltInId::gl_PerVertexOutTcsBlockES3_2, BuiltInName::gl_PerVertex,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, fields_gl_PerVertexOutTcsBlockES3_2);
+ TType *type_gl_PositionTCS = new TType(EbtFloat, EbpHigh, EvqPosition, 4);
+ type_gl_PositionTCS->setInterfaceBlock(gl_PerVertexOutTcsBlock);
+ type_gl_PositionTCS->realize();
+ m_gl_PositionTCS = new TVariable(
+ BuiltInId::gl_PositionTCS, BuiltInName::gl_Position, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}}, type_gl_PositionTCS);
+ TType *type_gl_PositionTCSES3_2 = new TType(EbtFloat, EbpHigh, EvqPosition, 4);
+ type_gl_PositionTCSES3_2->setInterfaceBlock(gl_PerVertexOutTcsBlockES3_2);
+ type_gl_PositionTCSES3_2->realize();
+ m_gl_PositionTCSES3_2 = new TVariable(
+ BuiltInId::gl_PositionTCSES3_2, BuiltInName::gl_Position, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, type_gl_PositionTCSES3_2);
+ TType *type_gl_BoundingBoxEXTTCS = new TType(EbtFloat, EbpHigh, EvqBoundingBox, 4);
+ type_gl_BoundingBoxEXTTCS->makeArray(2u);
+ type_gl_BoundingBoxEXTTCS->realize();
+ m_gl_BoundingBoxEXTTCS = new TVariable(
+ BuiltInId::gl_BoundingBoxEXTTCS, BuiltInName::gl_BoundingBoxEXT, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ type_gl_BoundingBoxEXTTCS);
+ TType *type_gl_BoundingBoxEXTTCSES3_2 = new TType(EbtFloat, EbpHigh, EvqBoundingBox, 4);
+ type_gl_BoundingBoxEXTTCSES3_2->makeArray(2u);
+ type_gl_BoundingBoxEXTTCSES3_2->realize();
+ m_gl_BoundingBoxEXTTCSES3_2 = new TVariable(
+ BuiltInId::gl_BoundingBoxEXTTCSES3_2, BuiltInName::gl_BoundingBoxEXT, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, type_gl_BoundingBoxEXTTCSES3_2);
+ TType *type_gl_BoundingBoxOESTCS = new TType(EbtFloat, EbpHigh, EvqBoundingBox, 4);
+ type_gl_BoundingBoxOESTCS->makeArray(2u);
+ type_gl_BoundingBoxOESTCS->realize();
+ m_gl_BoundingBoxOESTCS = new TVariable(
+ BuiltInId::gl_BoundingBoxOESTCS, BuiltInName::gl_BoundingBoxOES, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ type_gl_BoundingBoxOESTCS);
+ TType *type_gl_BoundingBoxOESTCSES3_2 = new TType(EbtFloat, EbpHigh, EvqBoundingBox, 4);
+ type_gl_BoundingBoxOESTCSES3_2->makeArray(2u);
+ type_gl_BoundingBoxOESTCSES3_2->realize();
+ m_gl_BoundingBoxOESTCSES3_2 = new TVariable(
+ BuiltInId::gl_BoundingBoxOESTCSES3_2, BuiltInName::gl_BoundingBoxOES, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, type_gl_BoundingBoxOESTCSES3_2);
+ TType *type_gl_TessLevelOuterTES = new TType(EbtFloat, EbpHigh, EvqTessLevelOuter, 1);
+ type_gl_TessLevelOuterTES->makeArray(4u);
+ type_gl_TessLevelOuterTES->realize();
+ m_gl_TessLevelOuterTES = new TVariable(
+ BuiltInId::gl_TessLevelOuterTES, BuiltInName::gl_TessLevelOuter, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ type_gl_TessLevelOuterTES);
+ TType *type_gl_TessLevelOuterTESES3_2 = new TType(EbtFloat, EbpHigh, EvqTessLevelOuter, 1);
+ type_gl_TessLevelOuterTESES3_2->makeArray(4u);
+ type_gl_TessLevelOuterTESES3_2->realize();
+ m_gl_TessLevelOuterTESES3_2 = new TVariable(
+ BuiltInId::gl_TessLevelOuterTESES3_2, BuiltInName::gl_TessLevelOuter, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, type_gl_TessLevelOuterTESES3_2);
+ TType *type_gl_TessLevelInnerTES = new TType(EbtFloat, EbpHigh, EvqTessLevelInner, 1);
+ type_gl_TessLevelInnerTES->makeArray(2u);
+ type_gl_TessLevelInnerTES->realize();
+ m_gl_TessLevelInnerTES = new TVariable(
+ BuiltInId::gl_TessLevelInnerTES, BuiltInName::gl_TessLevelInner, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ type_gl_TessLevelInnerTES);
+ TType *type_gl_TessLevelInnerTESES3_2 = new TType(EbtFloat, EbpHigh, EvqTessLevelInner, 1);
+ type_gl_TessLevelInnerTESES3_2->makeArray(2u);
+ type_gl_TessLevelInnerTESES3_2->realize();
+ m_gl_TessLevelInnerTESES3_2 = new TVariable(
+ BuiltInId::gl_TessLevelInnerTESES3_2, BuiltInName::gl_TessLevelInner, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, type_gl_TessLevelInnerTESES3_2);
+ TFieldList *fields_gl_PerVertexTES = new TFieldList();
+ fields_gl_PerVertexTES->push_back(new TField(new TType(EbtFloat, EbpHigh, EvqPosition, 4, 1),
+ BuiltInName::gl_Position, zeroSourceLoc,
+ SymbolType::BuiltIn));
+ TInterfaceBlock *gl_PerVertexTES = new TInterfaceBlock(
+ BuiltInId::gl_PerVertexTES, BuiltInName::gl_PerVertex,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}}, fields_gl_PerVertexTES);
+ m_gl_PerVertexTES = gl_PerVertexTES;
+ TFieldList *fields_gl_PerVertexTESES3_2 = new TFieldList();
+ fields_gl_PerVertexTESES3_2->push_back(
+ new TField(new TType(EbtFloat, EbpHigh, EvqPosition, 4, 1), BuiltInName::gl_Position,
+ zeroSourceLoc, SymbolType::BuiltIn));
+ TInterfaceBlock *gl_PerVertexTESES3_2 = new TInterfaceBlock(
+ BuiltInId::gl_PerVertexTESES3_2, BuiltInName::gl_PerVertex,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, fields_gl_PerVertexTESES3_2);
+ m_gl_PerVertexTESES3_2 = gl_PerVertexTESES3_2;
+ TType *type_gl_inTES = new TType(gl_PerVertex, EvqPerVertexIn, TLayoutQualifier::Create());
+ type_gl_inTES->makeArray(resources.MaxPatchVertices);
+ type_gl_inTES->realize();
+ m_gl_inTES = new TVariable(BuiltInId::gl_inTES, BuiltInName::gl_in, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ type_gl_inTES);
+ TType *type_gl_inTESES3_2 = new TType(gl_PerVertex, EvqPerVertexIn, TLayoutQualifier::Create());
+ type_gl_inTESES3_2->makeArray(resources.MaxPatchVertices);
+ type_gl_inTESES3_2->realize();
+ m_gl_inTESES3_2 =
+ new TVariable(BuiltInId::gl_inTESES3_2, BuiltInName::gl_in, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, type_gl_inTESES3_2);
+ TType *type_gl_outTES = new TType(gl_PerVertex, EvqPerVertexOut, TLayoutQualifier::Create());
+ type_gl_outTES->makeArray(resources.MaxPatchVertices);
+ type_gl_outTES->realize();
+ m_gl_outTES = new TVariable(BuiltInId::gl_outTES, BuiltInName::gl_out, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ type_gl_outTES);
+ TType *type_gl_outTESES3_2 =
+ new TType(gl_PerVertex, EvqPerVertexOut, TLayoutQualifier::Create());
+ type_gl_outTESES3_2->makeArray(resources.MaxPatchVertices);
+ type_gl_outTESES3_2->realize();
+ m_gl_outTESES3_2 =
+ new TVariable(BuiltInId::gl_outTESES3_2, BuiltInName::gl_out, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, type_gl_outTESES3_2);
+ TFieldList *fields_gl_PerVertexOutTesBlock = new TFieldList();
+ fields_gl_PerVertexOutTesBlock->push_back(
+ new TField(new TType(EbtFloat, EbpHigh, EvqPosition, 4, 1), BuiltInName::gl_Position,
+ zeroSourceLoc, SymbolType::BuiltIn));
+ TInterfaceBlock *gl_PerVertexOutTesBlock =
+ new TInterfaceBlock(BuiltInId::gl_PerVertexOutTesBlock, BuiltInName::gl_PerVertex,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}},
+ fields_gl_PerVertexOutTesBlock);
+ TFieldList *fields_gl_PerVertexOutTesBlockES3_2 = new TFieldList();
+ fields_gl_PerVertexOutTesBlockES3_2->push_back(
+ new TField(new TType(EbtFloat, EbpHigh, EvqPosition, 4, 1), BuiltInName::gl_Position,
+ zeroSourceLoc, SymbolType::BuiltIn));
+ TInterfaceBlock *gl_PerVertexOutTesBlockES3_2 = new TInterfaceBlock(
+ BuiltInId::gl_PerVertexOutTesBlockES3_2, BuiltInName::gl_PerVertex,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, fields_gl_PerVertexOutTesBlockES3_2);
+ TType *type_gl_PositionTES = new TType(EbtFloat, EbpHigh, EvqPosition, 4);
+ type_gl_PositionTES->setInterfaceBlock(gl_PerVertexOutTesBlock);
+ type_gl_PositionTES->realize();
+ m_gl_PositionTES = new TVariable(
+ BuiltInId::gl_PositionTES, BuiltInName::gl_Position, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::EXT_tessellation_shader}}, type_gl_PositionTES);
+ TType *type_gl_PositionTESES3_2 = new TType(EbtFloat, EbpHigh, EvqPosition, 4);
+ type_gl_PositionTESES3_2->setInterfaceBlock(gl_PerVertexOutTesBlockES3_2);
+ type_gl_PositionTESES3_2->realize();
+ m_gl_PositionTESES3_2 = new TVariable(
+ BuiltInId::gl_PositionTESES3_2, BuiltInName::gl_Position, SymbolType::BuiltIn,
+ std::array<TExtension, 1u>{{TExtension::UNDEFINED}}, type_gl_PositionTESES3_2);
+}
+
+namespace
+{
+uint16_t GetNextRuleIndex(uint32_t nameHash)
+{
+ if (nameHash == 1645 - 1)
+ return ArraySize(BuiltInArray::kRules);
+ return BuiltInArray::kMangledOffsets[nameHash + 1];
+}
+} // namespace
+
+const TSymbol *TSymbolTable::findBuiltIn(const ImmutableString &name, int shaderVersion) const
+{
+ if (name.length() > 40)
+ return nullptr;
+
+ uint32_t nameHash = name.mangledNameHash();
+ if (nameHash >= 1645)
+ return nullptr;
+
+ const char *actualName = BuiltInArray::kMangledNames[nameHash];
+ if (name != actualName)
+ return nullptr;
+
+ uint16_t startIndex = BuiltInArray::kMangledOffsets[nameHash];
+ uint16_t nextIndex = GetNextRuleIndex(nameHash);
+
+ return FindMangledBuiltIn(mShaderSpec, shaderVersion, mShaderType, mResources, *this,
+ BuiltInArray::kRules, startIndex, nextIndex);
+}
+
+bool TSymbolTable::isUnmangledBuiltInName(const ImmutableString &name,
+ int shaderVersion,
+ const TExtensionBehavior &extensions) const
+{
+ if (name.length() > 32)
+ return false;
+
+ uint32_t nameHash = name.unmangledNameHash();
+ if (nameHash >= 174)
+ return false;
+
+ return BuiltInArray::unmangled[nameHash].matches(name, mShaderSpec, shaderVersion, mShaderType,
+ extensions);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/SymbolTable_autogen.h b/gfx/angle/checkout/src/compiler/translator/SymbolTable_autogen.h
new file mode 100644
index 0000000000..37c3c46462
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/SymbolTable_autogen.h
@@ -0,0 +1,169 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_builtin_symbols.py using data from builtin_variables.json and
+// builtin_function_declarations.txt.
+//
+// Copyright 2020 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.
+//
+// SymbolTable_autogen.h:
+// Autogenerated member variables of TSymbolTable.
+
+#ifndef COMPILER_TRANSLATOR_SYMBOLTABLE_AUTOGEN_H_
+#define COMPILER_TRANSLATOR_SYMBOLTABLE_AUTOGEN_H_
+
+namespace sh
+{
+
+class TSymbolTableBase
+{
+ public:
+ TSymbolTableBase() = default;
+ TSymbol *m_gl_DepthRangeParameters = nullptr;
+ TSymbol *m_gl_DepthRange = nullptr;
+ TSymbol *m_gl_MaxVertexAttribs = nullptr;
+ TSymbol *m_gl_MaxVertexUniformVectors = nullptr;
+ TSymbol *m_gl_MaxVertexTextureImageUnits = nullptr;
+ TSymbol *m_gl_MaxCombinedTextureImageUnits = nullptr;
+ TSymbol *m_gl_MaxTextureImageUnits = nullptr;
+ TSymbol *m_gl_MaxFragmentUniformVectors = nullptr;
+ TSymbol *m_gl_MaxVaryingVectors = nullptr;
+ TSymbol *m_gl_MaxDrawBuffers = nullptr;
+ TSymbol *m_gl_MaxDualSourceDrawBuffersEXT = nullptr;
+ TSymbol *m_gl_MaxVertexOutputVectors = nullptr;
+ TSymbol *m_gl_MaxFragmentInputVectors = nullptr;
+ TSymbol *m_gl_MinProgramTexelOffset = nullptr;
+ TSymbol *m_gl_MaxProgramTexelOffset = nullptr;
+ TSymbol *m_gl_MaxImageUnits = nullptr;
+ TSymbol *m_gl_MaxVertexImageUniforms = nullptr;
+ TSymbol *m_gl_MaxFragmentImageUniforms = nullptr;
+ TSymbol *m_gl_MaxComputeImageUniforms = nullptr;
+ TSymbol *m_gl_MaxCombinedImageUniforms = nullptr;
+ TSymbol *m_gl_MaxCombinedShaderOutputResources = nullptr;
+ TSymbol *m_gl_MaxComputeWorkGroupCount = nullptr;
+ TSymbol *m_gl_MaxComputeWorkGroupSize = nullptr;
+ TSymbol *m_gl_MaxComputeUniformComponents = nullptr;
+ TSymbol *m_gl_MaxComputeTextureImageUnits = nullptr;
+ TSymbol *m_gl_MaxComputeAtomicCounters = nullptr;
+ TSymbol *m_gl_MaxComputeAtomicCounterBuffers = nullptr;
+ TSymbol *m_gl_MaxVertexAtomicCounters = nullptr;
+ TSymbol *m_gl_MaxFragmentAtomicCounters = nullptr;
+ TSymbol *m_gl_MaxCombinedAtomicCounters = nullptr;
+ TSymbol *m_gl_MaxAtomicCounterBindings = nullptr;
+ TSymbol *m_gl_MaxVertexAtomicCounterBuffers = nullptr;
+ TSymbol *m_gl_MaxFragmentAtomicCounterBuffers = nullptr;
+ TSymbol *m_gl_MaxCombinedAtomicCounterBuffers = nullptr;
+ TSymbol *m_gl_MaxAtomicCounterBufferSize = nullptr;
+ TSymbol *m_gl_MaxGeometryInputComponents = nullptr;
+ TSymbol *m_gl_MaxGeometryInputComponentsES3_2 = nullptr;
+ TSymbol *m_gl_MaxGeometryOutputComponents = nullptr;
+ TSymbol *m_gl_MaxGeometryOutputComponentsES3_2 = nullptr;
+ TSymbol *m_gl_MaxGeometryImageUniforms = nullptr;
+ TSymbol *m_gl_MaxGeometryImageUniformsES3_2 = nullptr;
+ TSymbol *m_gl_MaxGeometryTextureImageUnits = nullptr;
+ TSymbol *m_gl_MaxGeometryTextureImageUnitsES3_2 = nullptr;
+ TSymbol *m_gl_MaxGeometryOutputVertices = nullptr;
+ TSymbol *m_gl_MaxGeometryOutputVerticesES3_2 = nullptr;
+ TSymbol *m_gl_MaxGeometryTotalOutputComponents = nullptr;
+ TSymbol *m_gl_MaxGeometryTotalOutputComponentsES3_2 = nullptr;
+ TSymbol *m_gl_MaxGeometryUniformComponents = nullptr;
+ TSymbol *m_gl_MaxGeometryUniformComponentsES3_2 = nullptr;
+ TSymbol *m_gl_MaxGeometryAtomicCounters = nullptr;
+ TSymbol *m_gl_MaxGeometryAtomicCountersES3_2 = nullptr;
+ TSymbol *m_gl_MaxGeometryAtomicCounterBuffers = nullptr;
+ TSymbol *m_gl_MaxGeometryAtomicCounterBuffersES3_2 = nullptr;
+ TSymbol *m_gl_MaxTessControlInputComponents = nullptr;
+ TSymbol *m_gl_MaxTessControlInputComponentsES3_2 = nullptr;
+ TSymbol *m_gl_MaxTessControlOutputComponents = nullptr;
+ TSymbol *m_gl_MaxTessControlOutputComponentsES3_2 = nullptr;
+ TSymbol *m_gl_MaxTessControlTextureImageUnits = nullptr;
+ TSymbol *m_gl_MaxTessControlTextureImageUnitsES3_2 = nullptr;
+ TSymbol *m_gl_MaxTessControlUniformComponents = nullptr;
+ TSymbol *m_gl_MaxTessControlUniformComponentsES3_2 = nullptr;
+ TSymbol *m_gl_MaxTessControlTotalOutputComponents = nullptr;
+ TSymbol *m_gl_MaxTessControlTotalOutputComponentsES3_2 = nullptr;
+ TSymbol *m_gl_MaxTessControlImageUniforms = nullptr;
+ TSymbol *m_gl_MaxTessControlImageUniformsES3_2 = nullptr;
+ TSymbol *m_gl_MaxTessControlAtomicCounters = nullptr;
+ TSymbol *m_gl_MaxTessControlAtomicCountersES3_2 = nullptr;
+ TSymbol *m_gl_MaxTessControlAtomicCounterBuffers = nullptr;
+ TSymbol *m_gl_MaxTessControlAtomicCounterBuffersES3_2 = nullptr;
+ TSymbol *m_gl_MaxTessPatchComponents = nullptr;
+ TSymbol *m_gl_MaxTessPatchComponentsES3_2 = nullptr;
+ TSymbol *m_gl_MaxPatchVertices = nullptr;
+ TSymbol *m_gl_MaxPatchVerticesES3_2 = nullptr;
+ TSymbol *m_gl_MaxTessGenLevel = nullptr;
+ TSymbol *m_gl_MaxTessGenLevelES3_2 = nullptr;
+ TSymbol *m_gl_MaxTessEvaluationInputComponents = nullptr;
+ TSymbol *m_gl_MaxTessEvaluationInputComponentsES3_2 = nullptr;
+ TSymbol *m_gl_MaxTessEvaluationOutputComponents = nullptr;
+ TSymbol *m_gl_MaxTessEvaluationOutputComponentsES3_2 = nullptr;
+ TSymbol *m_gl_MaxTessEvaluationTextureImageUnits = nullptr;
+ TSymbol *m_gl_MaxTessEvaluationTextureImageUnitsES3_2 = nullptr;
+ TSymbol *m_gl_MaxTessEvaluationUniformComponents = nullptr;
+ TSymbol *m_gl_MaxTessEvaluationUniformComponentsES3_2 = nullptr;
+ TSymbol *m_gl_MaxTessEvaluationImageUniforms = nullptr;
+ TSymbol *m_gl_MaxTessEvaluationImageUniformsES3_2 = nullptr;
+ TSymbol *m_gl_MaxTessEvaluationAtomicCounters = nullptr;
+ TSymbol *m_gl_MaxTessEvaluationAtomicCountersES3_2 = nullptr;
+ TSymbol *m_gl_MaxTessEvaluationAtomicCounterBuffers = nullptr;
+ TSymbol *m_gl_MaxTessEvaluationAtomicCounterBuffersES3_2 = nullptr;
+ TSymbol *m_gl_MaxSamples = nullptr;
+ TSymbol *m_gl_MaxSamplesES3_2 = nullptr;
+ TSymbol *m_gl_MaxClipDistancesAPPLE = nullptr;
+ TSymbol *m_gl_MaxCullDistancesEXT = nullptr;
+ TSymbol *m_gl_MaxCombinedClipAndCullDistancesEXT = nullptr;
+ TSymbol *m_gl_FragData = nullptr;
+ TSymbol *m_gl_SecondaryFragDataEXT = nullptr;
+ TSymbol *m_gl_FragDepthEXT = nullptr;
+ TSymbol *m_gl_LastFragData = nullptr;
+ TSymbol *m_gl_LastFragDataNV = nullptr;
+ TSymbol *m_gl_SampleMaskIn = nullptr;
+ TSymbol *m_gl_SampleMaskInES3_2 = nullptr;
+ TSymbol *m_gl_SampleMask = nullptr;
+ TSymbol *m_gl_SampleMaskES3_2 = nullptr;
+ TSymbol *m_gl_CullDistance = nullptr;
+ TSymbol *m_gl_ClipDistance = nullptr;
+ TSymbol *m_gl_ClipDistanceAPPLE = nullptr;
+ TSymbol *m_gl_CullDistanceEXT = nullptr;
+ TSymbol *m_gl_PerVertex = nullptr;
+ TSymbol *m_gl_PerVertexES3_2 = nullptr;
+ TSymbol *m_gl_in = nullptr;
+ TSymbol *m_gl_inES3_2 = nullptr;
+ TSymbol *m_gl_PositionGS = nullptr;
+ TSymbol *m_gl_PositionGSES3_2 = nullptr;
+ TSymbol *m_gl_TessLevelOuterTCS = nullptr;
+ TSymbol *m_gl_TessLevelOuterTCSES3_2 = nullptr;
+ TSymbol *m_gl_TessLevelInnerTCS = nullptr;
+ TSymbol *m_gl_TessLevelInnerTCSES3_2 = nullptr;
+ TSymbol *m_gl_PerVertexTCS = nullptr;
+ TSymbol *m_gl_PerVertexTCSES3_2 = nullptr;
+ TSymbol *m_gl_inTCS = nullptr;
+ TSymbol *m_gl_inTCSES3_2 = nullptr;
+ TSymbol *m_gl_outTCS = nullptr;
+ TSymbol *m_gl_outTCSES3_2 = nullptr;
+ TSymbol *m_gl_BoundingBoxTCS = nullptr;
+ TSymbol *m_gl_BoundingBoxTCSES3_2 = nullptr;
+ TSymbol *m_gl_PositionTCS = nullptr;
+ TSymbol *m_gl_PositionTCSES3_2 = nullptr;
+ TSymbol *m_gl_BoundingBoxEXTTCS = nullptr;
+ TSymbol *m_gl_BoundingBoxEXTTCSES3_2 = nullptr;
+ TSymbol *m_gl_BoundingBoxOESTCS = nullptr;
+ TSymbol *m_gl_BoundingBoxOESTCSES3_2 = nullptr;
+ TSymbol *m_gl_TessLevelOuterTES = nullptr;
+ TSymbol *m_gl_TessLevelOuterTESES3_2 = nullptr;
+ TSymbol *m_gl_TessLevelInnerTES = nullptr;
+ TSymbol *m_gl_TessLevelInnerTESES3_2 = nullptr;
+ TSymbol *m_gl_PerVertexTES = nullptr;
+ TSymbol *m_gl_PerVertexTESES3_2 = nullptr;
+ TSymbol *m_gl_inTES = nullptr;
+ TSymbol *m_gl_inTESES3_2 = nullptr;
+ TSymbol *m_gl_outTES = nullptr;
+ TSymbol *m_gl_outTESES3_2 = nullptr;
+ TSymbol *m_gl_PositionTES = nullptr;
+ TSymbol *m_gl_PositionTESES3_2 = nullptr;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_SYMBOLTABLE_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/SymbolUniqueId.cpp b/gfx/angle/checkout/src/compiler/translator/SymbolUniqueId.cpp
new file mode 100644
index 0000000000..2bdf08fa5f
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/SymbolUniqueId.cpp
@@ -0,0 +1,27 @@
+//
+// Copyright 2017 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.
+//
+// SymbolUniqueId.cpp: Encapsulates a unique id for a symbol.
+
+#include "compiler/translator/SymbolUniqueId.h"
+
+#include "compiler/translator/SymbolTable.h"
+
+namespace sh
+{
+
+TSymbolUniqueId::TSymbolUniqueId(TSymbolTable *symbolTable) : mId(symbolTable->nextUniqueIdValue())
+{}
+
+TSymbolUniqueId::TSymbolUniqueId(const TSymbol &symbol) : mId(symbol.uniqueId().get()) {}
+
+TSymbolUniqueId &TSymbolUniqueId::operator=(const TSymbolUniqueId &) = default;
+
+bool TSymbolUniqueId::operator==(const TSymbolUniqueId &other) const
+{
+ return mId == other.mId;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/SymbolUniqueId.h b/gfx/angle/checkout/src/compiler/translator/SymbolUniqueId.h
new file mode 100644
index 0000000000..7e0312d054
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/SymbolUniqueId.h
@@ -0,0 +1,58 @@
+//
+// Copyright 2017 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.
+//
+// SymbolUniqueId.h: Encapsulates a unique id for a symbol.
+
+#ifndef COMPILER_TRANSLATOR_SYMBOLUNIQUEID_H_
+#define COMPILER_TRANSLATOR_SYMBOLUNIQUEID_H_
+
+#include "compiler/translator/Common.h"
+
+namespace sh
+{
+
+class TSymbolTable;
+class TSymbol;
+
+class TSymbolUniqueId
+{
+ public:
+ POOL_ALLOCATOR_NEW_DELETE
+ explicit TSymbolUniqueId(const TSymbol &symbol);
+ constexpr TSymbolUniqueId(const TSymbolUniqueId &) = default;
+ TSymbolUniqueId &operator =(const TSymbolUniqueId &);
+ bool operator==(const TSymbolUniqueId &) const;
+
+ constexpr int get() const { return mId; }
+
+ private:
+ friend class TSymbolTable;
+ explicit TSymbolUniqueId(TSymbolTable *symbolTable);
+
+ friend class BuiltInId;
+ constexpr TSymbolUniqueId(int staticId) : mId(staticId) {}
+
+ int mId;
+};
+
+enum class SymbolType : uint8_t
+{
+ BuiltIn,
+ UserDefined,
+ AngleInternal,
+ Empty // Meaning symbol without a name.
+};
+
+enum class SymbolClass : uint8_t
+{
+ Function,
+ Variable,
+ Struct,
+ InterfaceBlock
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_SYMBOLUNIQUEID_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/TextureFunctionHLSL.cpp b/gfx/angle/checkout/src/compiler/translator/TextureFunctionHLSL.cpp
new file mode 100644
index 0000000000..b88e6c9ce4
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/TextureFunctionHLSL.cpp
@@ -0,0 +1,1614 @@
+//
+// 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.
+//
+// TextureFunctionHLSL: Class for writing implementations of ESSL texture functions into HLSL
+// output. Some of the implementations are straightforward and just call the HLSL equivalent of the
+// ESSL texture function, others do more work to emulate ESSL texture sampling or size query
+// behavior.
+//
+
+#include "compiler/translator/TextureFunctionHLSL.h"
+
+#include "compiler/translator/ImmutableStringBuilder.h"
+#include "compiler/translator/UtilsHLSL.h"
+
+namespace sh
+{
+
+namespace
+{
+
+void OutputIntTexCoordWrap(TInfoSinkBase &out,
+ const char *wrapMode,
+ const char *size,
+ const ImmutableString &texCoord,
+ const char *texCoordOffset,
+ const char *texCoordOutName)
+{
+ // GLES 3.0.4 table 3.22 specifies how the wrap modes work. We don't use the formulas verbatim
+ // but rather use equivalent formulas that map better to HLSL.
+ out << "int " << texCoordOutName << ";\n";
+ out << "float " << texCoordOutName << "Offset = " << texCoord << " + float(" << texCoordOffset
+ << ") / " << size << ";\n";
+ out << "bool " << texCoordOutName << "UseBorderColor = false;\n";
+
+ // CLAMP_TO_EDGE
+ out << "if (" << wrapMode << " == 0)\n";
+ out << "{\n";
+ out << " " << texCoordOutName << " = clamp(int(floor(" << size << " * " << texCoordOutName
+ << "Offset)), 0, int(" << size << ") - 1);\n";
+ out << "}\n";
+
+ // CLAMP_TO_BORDER
+ out << "else if (" << wrapMode << " == 3)\n";
+ out << "{\n";
+ out << " int texCoordInt = int(floor(" << size << " * " << texCoordOutName << "Offset));\n";
+ out << " " << texCoordOutName << " = clamp(texCoordInt, 0, int(" << size << ") - 1);\n";
+ out << " " << texCoordOutName << "UseBorderColor = (texCoordInt != " << texCoordOutName
+ << ");\n";
+ out << "}\n";
+
+ // MIRRORED_REPEAT
+ out << "else if (" << wrapMode << " == 2)\n";
+ out << "{\n";
+ out << " float coordWrapped = 1.0 - abs(frac(abs(" << texCoordOutName
+ << "Offset) * 0.5) * 2.0 - 1.0);\n";
+ out << " " << texCoordOutName << " = int(floor(" << size << " * coordWrapped));\n";
+ out << "}\n";
+
+ // REPEAT
+ out << "else\n";
+ out << "{\n";
+ out << " " << texCoordOutName << " = int(floor(" << size << " * frac(" << texCoordOutName
+ << "Offset)));\n";
+ out << "}\n";
+}
+
+void OutputIntTexCoordWraps(TInfoSinkBase &out,
+ const TextureFunctionHLSL::TextureFunction &textureFunction,
+ ImmutableString *texCoordX,
+ ImmutableString *texCoordY,
+ ImmutableString *texCoordZ)
+{
+ // Convert from normalized floating-point to integer
+ out << "int wrapS = samplerMetadata[samplerIndex].wrapModes & 0x3;\n";
+ if (textureFunction.offset)
+ {
+ OutputIntTexCoordWrap(out, "wrapS", "width", *texCoordX, "offset.x", "tix");
+ }
+ else
+ {
+ OutputIntTexCoordWrap(out, "wrapS", "width", *texCoordX, "0", "tix");
+ }
+ *texCoordX = ImmutableString("tix");
+ out << "int wrapT = (samplerMetadata[samplerIndex].wrapModes >> 2) & 0x3;\n";
+ if (textureFunction.offset)
+ {
+ OutputIntTexCoordWrap(out, "wrapT", "height", *texCoordY, "offset.y", "tiy");
+ }
+ else
+ {
+ OutputIntTexCoordWrap(out, "wrapT", "height", *texCoordY, "0", "tiy");
+ }
+ *texCoordY = ImmutableString("tiy");
+
+ bool tizAvailable = false;
+
+ if (IsSamplerArray(textureFunction.sampler))
+ {
+ *texCoordZ = ImmutableString("int(max(0, min(layers - 1, floor(0.5 + t.z))))");
+ }
+ else if (!IsSamplerCube(textureFunction.sampler) && !IsSampler2D(textureFunction.sampler))
+ {
+ out << "int wrapR = (samplerMetadata[samplerIndex].wrapModes >> 4) & 0x3;\n";
+ if (textureFunction.offset)
+ {
+ OutputIntTexCoordWrap(out, "wrapR", "depth", *texCoordZ, "offset.z", "tiz");
+ }
+ else
+ {
+ OutputIntTexCoordWrap(out, "wrapR", "depth", *texCoordZ, "0", "tiz");
+ }
+ *texCoordZ = ImmutableString("tiz");
+ tizAvailable = true;
+ }
+
+ out << "bool useBorderColor = tixUseBorderColor || tiyUseBorderColor"
+ << (tizAvailable ? " || tizUseBorderColor" : "") << ";\n";
+}
+
+void OutputHLSL4SampleFunctionPrefix(TInfoSinkBase &out,
+ const TextureFunctionHLSL::TextureFunction &textureFunction,
+ const ImmutableString &textureReference,
+ const ImmutableString &samplerReference)
+{
+ out << textureReference;
+ if (IsIntegerSampler(textureFunction.sampler) ||
+ textureFunction.method == TextureFunctionHLSL::TextureFunction::FETCH)
+ {
+ out << ".Load(";
+ return;
+ }
+
+ if (IsShadowSampler(textureFunction.sampler))
+ {
+ switch (textureFunction.method)
+ {
+ case TextureFunctionHLSL::TextureFunction::IMPLICIT:
+ case TextureFunctionHLSL::TextureFunction::BIAS:
+ case TextureFunctionHLSL::TextureFunction::LOD:
+ out << ".SampleCmp(";
+ break;
+ case TextureFunctionHLSL::TextureFunction::LOD0:
+ case TextureFunctionHLSL::TextureFunction::LOD0BIAS:
+ case TextureFunctionHLSL::TextureFunction::GRAD:
+ out << ".SampleCmpLevelZero(";
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+ else
+ {
+ switch (textureFunction.method)
+ {
+ case TextureFunctionHLSL::TextureFunction::IMPLICIT:
+ out << ".Sample(";
+ break;
+ case TextureFunctionHLSL::TextureFunction::BIAS:
+ out << ".SampleBias(";
+ break;
+ case TextureFunctionHLSL::TextureFunction::LOD:
+ case TextureFunctionHLSL::TextureFunction::LOD0:
+ case TextureFunctionHLSL::TextureFunction::LOD0BIAS:
+ out << ".SampleLevel(";
+ break;
+ case TextureFunctionHLSL::TextureFunction::GRAD:
+ out << ".SampleGrad(";
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+ out << samplerReference << ", ";
+}
+
+const char *GetSamplerCoordinateTypeString(
+ const TextureFunctionHLSL::TextureFunction &textureFunction,
+ int hlslCoords)
+{
+ // Gather[Red|Green|Blue|Alpha] accepts float texture coordinates on textures in integer or
+ // unsigned integer formats.
+ // https://docs.microsoft.com/en-us/windows/desktop/direct3dhlsl/dx-graphics-hlsl-to-gather
+ if ((IsIntegerSampler(textureFunction.sampler) &&
+ textureFunction.method != TextureFunctionHLSL::TextureFunction::GATHER) ||
+ textureFunction.method == TextureFunctionHLSL::TextureFunction::FETCH)
+ {
+ switch (hlslCoords)
+ {
+ case 1:
+ return "int";
+ case 2:
+ if (IsSampler2DMS(textureFunction.sampler))
+ {
+ return "int2";
+ }
+ else
+ {
+ return "int3";
+ }
+ case 3:
+ if (IsSampler2DMSArray(textureFunction.sampler))
+ {
+ return "int3";
+ }
+ else
+ {
+ return "int4";
+ }
+ default:
+ UNREACHABLE();
+ }
+ }
+ else
+ {
+ switch (hlslCoords)
+ {
+ case 1:
+ return "float";
+ case 2:
+ return "float2";
+ case 3:
+ return "float3";
+ case 4:
+ return "float4";
+ default:
+ UNREACHABLE();
+ }
+ }
+ return "";
+}
+
+int GetHLSLCoordCount(const TextureFunctionHLSL::TextureFunction &textureFunction,
+ ShShaderOutput outputType)
+{
+ if (outputType == SH_HLSL_3_0_OUTPUT)
+ {
+ int hlslCoords = 2;
+ switch (textureFunction.sampler)
+ {
+ case EbtSamplerBuffer:
+ hlslCoords = 1;
+ break;
+ case EbtSampler2D:
+ case EbtSamplerExternalOES:
+ case EbtSampler2DMS:
+ case EbtSamplerVideoWEBGL:
+ hlslCoords = 2;
+ break;
+ case EbtSamplerCube:
+ hlslCoords = 3;
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ switch (textureFunction.method)
+ {
+ case TextureFunctionHLSL::TextureFunction::IMPLICIT:
+ case TextureFunctionHLSL::TextureFunction::GRAD:
+ return hlslCoords;
+ case TextureFunctionHLSL::TextureFunction::BIAS:
+ case TextureFunctionHLSL::TextureFunction::LOD:
+ case TextureFunctionHLSL::TextureFunction::LOD0:
+ case TextureFunctionHLSL::TextureFunction::LOD0BIAS:
+ return 4;
+ default:
+ UNREACHABLE();
+ }
+ }
+ else
+ {
+ if (IsSamplerBuffer(textureFunction.sampler))
+ {
+ return 1;
+ }
+ else if (IsSampler3D(textureFunction.sampler) || IsSamplerArray(textureFunction.sampler) ||
+ IsSamplerCube(textureFunction.sampler))
+ {
+ return 3;
+ }
+ ASSERT(IsSampler2D(textureFunction.sampler));
+ return 2;
+ }
+ return 0;
+}
+
+void OutputTextureFunctionArgumentList(TInfoSinkBase &out,
+ const TextureFunctionHLSL::TextureFunction &textureFunction,
+ const ShShaderOutput outputType)
+{
+ if (outputType == SH_HLSL_3_0_OUTPUT)
+ {
+ switch (textureFunction.sampler)
+ {
+ case EbtSampler2D:
+ case EbtSamplerVideoWEBGL:
+ case EbtSamplerExternalOES:
+ out << "sampler2D s";
+ break;
+ case EbtSamplerCube:
+ out << "samplerCUBE s";
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+ else
+ {
+ if (outputType == SH_HLSL_4_0_FL9_3_OUTPUT)
+ {
+ out << TextureString(textureFunction.sampler) << " x, "
+ << SamplerString(textureFunction.sampler) << " s";
+ }
+ else
+ {
+ ASSERT(outputType == SH_HLSL_4_1_OUTPUT);
+ // A bug in the D3D compiler causes some nested sampling operations to fail.
+ // See http://anglebug.com/1923
+ // TODO(jmadill): Reinstate the const keyword when possible.
+ out << /*"const"*/ "uint samplerIndex";
+ }
+ }
+
+ if (textureFunction.method ==
+ TextureFunctionHLSL::TextureFunction::FETCH) // Integer coordinates
+ {
+ switch (textureFunction.coords)
+ {
+ case 1:
+ out << ", int t";
+ break;
+ case 2:
+ out << ", int2 t";
+ break;
+ case 3:
+ out << ", int3 t";
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+ else // Floating-point coordinates (except textureSize)
+ {
+ switch (textureFunction.coords)
+ {
+ case 0:
+ break; // textureSize(gSampler2DMS sampler)
+ case 1:
+ out << ", int lod";
+ break; // textureSize()
+ case 2:
+ out << ", float2 t";
+ break;
+ case 3:
+ out << ", float3 t";
+ break;
+ case 4:
+ out << ", float4 t";
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ if (textureFunction.method == TextureFunctionHLSL::TextureFunction::GRAD)
+ {
+ switch (textureFunction.sampler)
+ {
+ case EbtSampler2D:
+ case EbtISampler2D:
+ case EbtUSampler2D:
+ case EbtSampler2DArray:
+ case EbtISampler2DArray:
+ case EbtUSampler2DArray:
+ case EbtSampler2DShadow:
+ case EbtSampler2DArrayShadow:
+ case EbtSamplerExternalOES:
+ case EbtSamplerVideoWEBGL:
+ out << ", float2 ddx, float2 ddy";
+ break;
+ case EbtSampler3D:
+ case EbtISampler3D:
+ case EbtUSampler3D:
+ case EbtSamplerCube:
+ case EbtISamplerCube:
+ case EbtUSamplerCube:
+ case EbtSamplerCubeShadow:
+ out << ", float3 ddx, float3 ddy";
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ switch (textureFunction.method)
+ {
+ case TextureFunctionHLSL::TextureFunction::IMPLICIT:
+ break;
+ case TextureFunctionHLSL::TextureFunction::BIAS:
+ break; // Comes after the offset parameter
+ case TextureFunctionHLSL::TextureFunction::LOD:
+ out << ", float lod";
+ break;
+ case TextureFunctionHLSL::TextureFunction::LOD0:
+ break;
+ case TextureFunctionHLSL::TextureFunction::LOD0BIAS:
+ break; // Comes after the offset parameter
+ case TextureFunctionHLSL::TextureFunction::SIZE:
+ break;
+ case TextureFunctionHLSL::TextureFunction::FETCH:
+ if (IsSampler2DMS(textureFunction.sampler) ||
+ IsSampler2DMSArray(textureFunction.sampler))
+ out << ", int index";
+ else if (!IsSamplerBuffer(textureFunction.sampler))
+ out << ", int mip";
+ break;
+ case TextureFunctionHLSL::TextureFunction::GRAD:
+ break;
+ case TextureFunctionHLSL::TextureFunction::GATHER:
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ if (textureFunction.method == TextureFunctionHLSL::TextureFunction::GATHER &&
+ IsShadowSampler(textureFunction.sampler))
+ {
+ out << ", float refZ";
+ }
+
+ if (textureFunction.offset)
+ {
+ switch (textureFunction.sampler)
+ {
+ case EbtSampler3D:
+ case EbtISampler3D:
+ case EbtUSampler3D:
+ out << ", int3 offset";
+ break;
+ case EbtSampler2D:
+ case EbtSampler2DArray:
+ case EbtISampler2D:
+ case EbtISampler2DArray:
+ case EbtUSampler2D:
+ case EbtUSampler2DArray:
+ case EbtSampler2DShadow:
+ case EbtSampler2DArrayShadow:
+ case EbtSamplerExternalOES:
+ case EbtSamplerVideoWEBGL:
+ out << ", int2 offset";
+ break;
+ default:
+ // Offset is not supported for multisampled textures.
+ UNREACHABLE();
+ }
+ }
+
+ if (textureFunction.method == TextureFunctionHLSL::TextureFunction::BIAS ||
+ textureFunction.method == TextureFunctionHLSL::TextureFunction::LOD0BIAS)
+ {
+ out << ", float bias";
+ }
+ else if (textureFunction.method == TextureFunctionHLSL::TextureFunction::GATHER &&
+ !IsShadowSampler(textureFunction.sampler))
+ {
+ out << ", int comp = 0";
+ }
+}
+
+void GetTextureReference(TInfoSinkBase &out,
+ const TextureFunctionHLSL::TextureFunction &textureFunction,
+ const ShShaderOutput outputType,
+ ImmutableString *textureReference,
+ ImmutableString *samplerReference)
+{
+ if (outputType == SH_HLSL_4_1_OUTPUT)
+ {
+ static const ImmutableString kTexturesStr("textures");
+ static const ImmutableString kSamplersStr("samplers");
+ static const ImmutableString kSamplerIndexStr("[samplerIndex]");
+ static const ImmutableString kTextureIndexStr("[textureIndex]");
+ static const ImmutableString kSamplerArrayIndexStr("[samplerArrayIndex]");
+ ImmutableString suffix(TextureGroupSuffix(textureFunction.sampler));
+
+ if (TextureGroup(textureFunction.sampler) == HLSL_TEXTURE_2D)
+ {
+ ImmutableStringBuilder textureRefBuilder(kTexturesStr.length() + suffix.length() +
+ kSamplerIndexStr.length());
+ textureRefBuilder << kTexturesStr << suffix << kSamplerIndexStr;
+ *textureReference = textureRefBuilder;
+ ImmutableStringBuilder samplerRefBuilder(kSamplersStr.length() + suffix.length() +
+ kSamplerIndexStr.length());
+ samplerRefBuilder << kSamplersStr << suffix << kSamplerIndexStr;
+ *samplerReference = samplerRefBuilder;
+ }
+ else
+ {
+ out << " const uint textureIndex = samplerIndex - textureIndexOffset"
+ << suffix.data() << ";\n";
+ ImmutableStringBuilder textureRefBuilder(kTexturesStr.length() + suffix.length() +
+ kTextureIndexStr.length());
+ textureRefBuilder << kTexturesStr << suffix << kTextureIndexStr;
+ *textureReference = textureRefBuilder;
+
+ out << " const uint samplerArrayIndex = samplerIndex - samplerIndexOffset"
+ << suffix.data() << ";\n";
+ ImmutableStringBuilder samplerRefBuilder(kSamplersStr.length() + suffix.length() +
+ kSamplerArrayIndexStr.length());
+ samplerRefBuilder << kSamplersStr << suffix << kSamplerArrayIndexStr;
+ *samplerReference = samplerRefBuilder;
+ }
+ }
+ else
+ {
+ *textureReference = ImmutableString("x");
+ *samplerReference = ImmutableString("s");
+ }
+}
+
+void OutputTextureSizeFunctionBody(TInfoSinkBase &out,
+ const TextureFunctionHLSL::TextureFunction &textureFunction,
+ const ImmutableString &textureReference,
+ bool getDimensionsIgnoresBaseLevel)
+{
+ if (IsSampler2DMS(textureFunction.sampler))
+ {
+ out << " uint width; uint height; uint samples;\n"
+ << " " << textureReference << ".GetDimensions(width, height, samples);\n";
+ }
+ else if (IsSampler2DMSArray(textureFunction.sampler))
+ {
+ out << " uint width; uint height; uint depth; uint samples;\n"
+ << " " << textureReference << ".GetDimensions(width, height, depth, samples);\n";
+ }
+ else if (IsSamplerBuffer(textureFunction.sampler))
+ {
+ out << " uint width;\n"
+ << " " << textureReference << ".GetDimensions(width);\n";
+ }
+ else
+ {
+ 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, 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, width, height, numberOfLevels);\n"
+ << " width = max(width >> lod, 1);\n"
+ << " height = max(height >> lod, 1);\n";
+ }
+ else
+ UNREACHABLE();
+ }
+
+ const char *returnType = textureFunction.getReturnType();
+ if (strcmp(returnType, "int3") == 0)
+ {
+ out << " return int3(width, height, depth);\n";
+ }
+ else if (strcmp(returnType, "int2") == 0)
+ {
+ out << " return int2(width, height);\n";
+ }
+ else
+ {
+ out << " return int(width);\n";
+ }
+}
+
+void ProjectTextureCoordinates(const TextureFunctionHLSL::TextureFunction &textureFunction,
+ ImmutableString *texCoordX,
+ ImmutableString *texCoordY,
+ ImmutableString *texCoordZ)
+{
+ if (textureFunction.proj)
+ {
+ ImmutableString proj("");
+ switch (textureFunction.coords)
+ {
+ case 3:
+ proj = ImmutableString(" / t.z");
+ break;
+ case 4:
+ proj = ImmutableString(" / t.w");
+ break;
+ default:
+ UNREACHABLE();
+ }
+ ImmutableStringBuilder texCoordXBuilder(texCoordX->length() + proj.length() + 2u);
+ texCoordXBuilder << '(' << *texCoordX << proj << ')';
+ *texCoordX = texCoordXBuilder;
+ ImmutableStringBuilder texCoordYBuilder(texCoordY->length() + proj.length() + 2u);
+ texCoordYBuilder << '(' << *texCoordY << proj << ')';
+ *texCoordY = texCoordYBuilder;
+ ImmutableStringBuilder texCoordZBuilder(texCoordZ->length() + proj.length() + 2u);
+ texCoordZBuilder << '(' << *texCoordZ << proj << ')';
+ *texCoordZ = texCoordZBuilder;
+ }
+}
+
+void OutputIntegerTextureSampleFunctionComputations(
+ TInfoSinkBase &out,
+ const TextureFunctionHLSL::TextureFunction &textureFunction,
+ const ShShaderOutput outputType,
+ const ImmutableString &textureReference,
+ ImmutableString *texCoordX,
+ ImmutableString *texCoordY,
+ ImmutableString *texCoordZ,
+ bool getDimensionsIgnoresBaseLevel)
+{
+ if (!IsIntegerSampler(textureFunction.sampler))
+ {
+ return;
+ }
+
+ if (getDimensionsIgnoresBaseLevel)
+ {
+ out << " int baseLevel = samplerMetadata[samplerIndex].baseLevel;\n";
+ }
+ else
+ {
+ out << " int baseLevel = 0;\n";
+ }
+
+ if (IsSamplerCube(textureFunction.sampler))
+ {
+ out << " float width; float height; float layers; float levels;\n";
+
+ out << " uint mip = 0;\n";
+
+ out << " " << textureReference
+ << ".GetDimensions(baseLevel + mip, width, height, layers, levels);\n";
+
+ out << " bool xMajor = abs(t.x) >= abs(t.y) && abs(t.x) >= abs(t.z);\n";
+ out << " bool yMajor = abs(t.y) >= abs(t.z) && abs(t.y) > abs(t.x);\n";
+ out << " bool zMajor = abs(t.z) > abs(t.x) && abs(t.z) > abs(t.y);\n";
+ out << " bool negative = (xMajor && t.x < 0.0f) || (yMajor && t.y < 0.0f) || "
+ "(zMajor && t.z < 0.0f);\n";
+
+ // FACE_POSITIVE_X = 000b
+ // FACE_NEGATIVE_X = 001b
+ // FACE_POSITIVE_Y = 010b
+ // FACE_NEGATIVE_Y = 011b
+ // FACE_POSITIVE_Z = 100b
+ // FACE_NEGATIVE_Z = 101b
+ out << " int face = (int)negative + (int)yMajor * 2 + (int)zMajor * 4;\n";
+
+ out << " float u = xMajor ? -t.z : (yMajor && t.y < 0.0f ? -t.x : t.x);\n";
+ out << " float v = yMajor ? t.z : (negative ? t.y : -t.y);\n";
+ out << " float m = xMajor ? t.x : (yMajor ? t.y : t.z);\n";
+
+ out << " float3 r = any(t) ? t : float3(1, 0, 0);\n";
+ out << " t.x = (u * 0.5f / m) + 0.5f;\n";
+ out << " t.y = (v * 0.5f / m) + 0.5f;\n";
+
+ // Mip level computation.
+ if (textureFunction.method == TextureFunctionHLSL::TextureFunction::IMPLICIT ||
+ textureFunction.method == TextureFunctionHLSL::TextureFunction::LOD ||
+ textureFunction.method == TextureFunctionHLSL::TextureFunction::GRAD)
+ {
+ if (textureFunction.method == TextureFunctionHLSL::TextureFunction::IMPLICIT)
+ {
+ // We would like to calculate tha maximum of how many texels we move in the major
+ // face's texture as we move across the screen in any direction. Namely, we want the
+ // length of the directional derivative of the function p (defined below), maximized
+ // over screen space directions. (For short: we want the norm of Dp.) For
+ // simplicity, assume that z-axis is the major axis. By symmetry, we can assume that
+ // the positive z direction is major. (The calculated value will be the same even if
+ // this is false.) Let r denote the function from screen position to cube texture
+ // coordinates. Then p can be written as p = s . P . r, where P(r) = (r.x, r.y)/r.z
+ // is the projection onto the major cube face, and s = diag(width, height)/2. (s
+ // linearly maps from the cube face into texture space, so that p(r) is in units of
+ // texels.) The derivative is
+ // Dp(r) = s |1 0 -r.x/r.z|
+ // |0 1 -r.y/r.z| |ddx(r) ddy(r)| / r.z
+ // = |dot(a, ddx(r)) dot(a, ddy(r))|
+ // |dot(b, ddx(r)) dot(b, ddy(r))| / (2 r.z)
+ // where a = w * vec3(1, 0, -r.x/r.z)
+ // b = h * vec3(0, 1, -r.y/r.z)
+ // We would like to know max(L(x)) over unit vectors x, where L(x) = |Dp(r) x|^2.
+ // Since ddx(r) and ddy(r) are unknown, the best we can do is to sample L in some
+ // directions and take the maximum across the samples.
+ //
+ // Some implementations use max(L(n1), L(n2)) where n1 = vec2(1,0) and n2 =
+ // vec2(0,1).
+ //
+ // Some implementations use max(L(n1), L(n2), L(n3), L(n4)),
+ // where n3 = (n1 + n2) / |n1 + n2| = (n1 + n2)/sqrt(2)
+ // n4 = (n1 - n2) / |n1 - n2| = (n1 - n2)/sqrt(2).
+ // In other words, two samples along the diagonal screen space directions have been
+ // added, giving a strictly better estimate of the true maximum.
+ //
+ // It turns out we can get twice the sample count very cheaply.
+ // We can use the linearity of Dp(r) to get these extra samples of L cheaply in
+ // terms of the already taken samples, L(n1) and L(n2):
+ // Denoting
+ // dpx = Dp(r)n1
+ // dpy = Dp(r)n2
+ // dpxx = dot(dpx, dpx)
+ // dpyy = dot(dpy, dpy)
+ // dpxy = dot(dpx, dpy)
+ // we obtain
+ // L(n3) = |Dp(r)n1 + Dp(r)n2|^2/2 = (dpxx + dpyy)/2 + dpxy
+ // L(n4) = |Dp(r)n1 - Dp(r)n2|^2/2 = (dpxx + dpyy)/2 - dpxy
+ // max(L(n1), L(n2), L(n3), L(n4))
+ // = max(max(L(n1), L(n2)), max(L(n3), L(n4)))
+ // = max(max(dpxx, dpyy), (dpxx + dpyy)/2 + abs(dpxy))
+ // So the extra cost is: one dot, one abs, one add, one multiply-add and one max.
+ // (All scalar.)
+ //
+ // In section 3.8.10.1, the OpenGL ES 3 specification defines the "scale factor",
+ // rho. In our terminology, this definition works out to taking sqrt(max(L(n1),
+ // L(n2))). Some implementations will use this estimate, here we use the strictly
+ // better sqrt(max(L(n1), L(n2), L(n3), L(n4))), since it's not much more expensive
+ // to calculate.
+
+ // Swap coordinates such that we can assume that the positive z-axis is major, in
+ // what follows.
+ out << " float3 ddxr = xMajor ? ddx(r).yzx : yMajor ? ddx(r).zxy : ddx(r).xyz;\n"
+ " float3 ddyr = xMajor ? ddy(r).yzx : yMajor ? ddy(r).zxy : ddy(r).xyz;\n"
+ " r = xMajor ? r.yzx : yMajor ? r.zxy : r.xyz;\n";
+
+ out << " float2 s = 0.5*float2(width, height);\n"
+ " float2 dpx = s * (ddxr.xy - ddxr.z*r.xy/r.z)/r.z;\n"
+ " float2 dpy = s * (ddyr.xy - ddyr.z*r.xy/r.z)/r.z;\n"
+ " float dpxx = dot(dpx, dpx);\n;"
+ " float dpyy = dot(dpy, dpy);\n;"
+ " float dpxy = dot(dpx, dpy);\n"
+ " float ma = max(dpxx, dpyy);\n"
+ " float mb = 0.5 * (dpxx + dpyy) + abs(dpxy);\n"
+ " float mab = max(ma, mb);\n"
+ " float lod = 0.5f * log2(mab);\n";
+ }
+ else if (textureFunction.method == TextureFunctionHLSL::TextureFunction::GRAD)
+ {
+ // ESSL 3.00.6 spec section 8.8: "For the cube version, the partial
+ // derivatives of P are assumed to be in the coordinate system used before
+ // texture coordinates are projected onto the appropriate cube face."
+ // ddx[0] and ddy[0] are the derivatives of t.x passed into the function
+ // ddx[1] and ddy[1] are the derivatives of t.y passed into the function
+ // ddx[2] and ddy[2] are the derivatives of t.z passed into the function
+ // Determine the derivatives of u, v and m
+ out << " float dudx = xMajor ? ddx[2] : (yMajor && t.y < 0.0f ? -ddx[0] "
+ ": ddx[0]);\n"
+ " float dudy = xMajor ? ddy[2] : (yMajor && t.y < 0.0f ? -ddy[0] "
+ ": ddy[0]);\n"
+ " float dvdx = yMajor ? ddx[2] : (negative ? ddx[1] : -ddx[1]);\n"
+ " float dvdy = yMajor ? ddy[2] : (negative ? ddy[1] : -ddy[1]);\n"
+ " float dmdx = xMajor ? ddx[0] : (yMajor ? ddx[1] : ddx[2]);\n"
+ " float dmdy = xMajor ? ddy[0] : (yMajor ? ddy[1] : ddy[2]);\n";
+ // Now determine the derivatives of the face coordinates, using the
+ // derivatives calculated above.
+ // d / dx (u(x) * 0.5 / m(x) + 0.5)
+ // = 0.5 * (m(x) * u'(x) - u(x) * m'(x)) / m(x)^2
+ out << " float dfacexdx = 0.5f * (m * dudx - u * dmdx) / (m * m);\n"
+ " float dfaceydx = 0.5f * (m * dvdx - v * dmdx) / (m * m);\n"
+ " float dfacexdy = 0.5f * (m * dudy - u * dmdy) / (m * m);\n"
+ " float dfaceydy = 0.5f * (m * dvdy - v * dmdy) / (m * m);\n"
+ " float2 sizeVec = float2(width, height);\n"
+ " float2 faceddx = float2(dfacexdx, dfaceydx) * sizeVec;\n"
+ " float2 faceddy = float2(dfacexdy, dfaceydy) * sizeVec;\n";
+ // Optimization: instead of: log2(max(length(faceddx), length(faceddy)))
+ // we compute: log2(max(length(faceddx)^2, length(faceddy)^2)) / 2
+ out << " float lengthfaceddx2 = dot(faceddx, faceddx);\n"
+ " float lengthfaceddy2 = dot(faceddy, faceddy);\n"
+ " float lod = log2(max(lengthfaceddx2, lengthfaceddy2)) * 0.5f;\n";
+ }
+ out << " mip = uint(min(max(round(lod), 0), levels - 1));\n"
+ << " " << textureReference
+ << ".GetDimensions(baseLevel + mip, width, height, layers, levels);\n";
+ }
+
+ // Convert from normalized floating-point to integer
+ static const ImmutableString kXPrefix("int(floor(width * frac(");
+ static const ImmutableString kYPrefix("int(floor(height * frac(");
+ static const ImmutableString kSuffix(")))");
+ ImmutableStringBuilder texCoordXBuilder(kXPrefix.length() + texCoordX->length() +
+ kSuffix.length());
+ texCoordXBuilder << kXPrefix << *texCoordX << kSuffix;
+ *texCoordX = texCoordXBuilder;
+ ImmutableStringBuilder texCoordYBuilder(kYPrefix.length() + texCoordX->length() +
+ kSuffix.length());
+ texCoordYBuilder << kYPrefix << *texCoordY << kSuffix;
+ *texCoordY = texCoordYBuilder;
+ *texCoordZ = ImmutableString("face");
+ }
+ else if (textureFunction.method != TextureFunctionHLSL::TextureFunction::FETCH)
+ {
+ if (IsSamplerArray(textureFunction.sampler))
+ {
+ out << " float width; float height; float layers; float levels;\n";
+ if (textureFunction.method == TextureFunctionHLSL::TextureFunction::LOD0)
+ {
+ out << " uint mip = 0;\n";
+ }
+ else if (textureFunction.method == TextureFunctionHLSL::TextureFunction::LOD0BIAS)
+ {
+ out << " uint mip = bias;\n";
+ }
+ else
+ {
+
+ out << " " << textureReference
+ << ".GetDimensions(baseLevel, width, height, layers, levels);\n";
+ if (textureFunction.method == TextureFunctionHLSL::TextureFunction::IMPLICIT ||
+ textureFunction.method == TextureFunctionHLSL::TextureFunction::BIAS)
+ {
+ out << " float2 tSized = float2(t.x * width, t.y * height);\n"
+ " float dx = length(ddx(tSized));\n"
+ " float dy = length(ddy(tSized));\n"
+ " float lod = log2(max(dx, dy));\n";
+
+ if (textureFunction.method == TextureFunctionHLSL::TextureFunction::BIAS)
+ {
+ out << " lod += bias;\n";
+ }
+ }
+ else if (textureFunction.method == TextureFunctionHLSL::TextureFunction::GRAD)
+ {
+ out << " float2 sizeVec = float2(width, height);\n"
+ " float2 sizeDdx = ddx * sizeVec;\n"
+ " float2 sizeDdy = ddy * sizeVec;\n"
+ " float lod = log2(max(dot(sizeDdx, sizeDdx), "
+ "dot(sizeDdy, sizeDdy))) * 0.5f;\n";
+ }
+
+ out << " uint mip = uint(min(max(round(lod), 0), levels - 1));\n";
+ }
+
+ out << " " << textureReference
+ << ".GetDimensions(baseLevel + mip, width, height, layers, levels);\n";
+ }
+ else if (IsSampler2D(textureFunction.sampler))
+ {
+ out << " float width; float height; float levels;\n";
+
+ if (textureFunction.method == TextureFunctionHLSL::TextureFunction::LOD0)
+ {
+ out << " uint mip = 0;\n";
+ }
+ else if (textureFunction.method == TextureFunctionHLSL::TextureFunction::LOD0BIAS)
+ {
+ out << " uint mip = bias;\n";
+ }
+ else
+ {
+ out << " " << textureReference
+ << ".GetDimensions(baseLevel, width, height, levels);\n";
+
+ if (textureFunction.method == TextureFunctionHLSL::TextureFunction::IMPLICIT ||
+ textureFunction.method == TextureFunctionHLSL::TextureFunction::BIAS)
+ {
+ out << " float2 tSized = float2(t.x * width, t.y * height);\n"
+ " float dx = length(ddx(tSized));\n"
+ " float dy = length(ddy(tSized));\n"
+ " float lod = log2(max(dx, dy));\n";
+
+ if (textureFunction.method == TextureFunctionHLSL::TextureFunction::BIAS)
+ {
+ out << " lod += bias;\n";
+ }
+ }
+ else if (textureFunction.method == TextureFunctionHLSL::TextureFunction::GRAD)
+ {
+ out << " float2 sizeVec = float2(width, height);\n"
+ " float2 sizeDdx = ddx * sizeVec;\n"
+ " float2 sizeDdy = ddy * sizeVec;\n"
+ " float lod = log2(max(dot(sizeDdx, sizeDdx), "
+ "dot(sizeDdy, sizeDdy))) * 0.5f;\n";
+ }
+
+ out << " uint mip = uint(min(max(round(lod), 0), levels - 1));\n";
+ }
+
+ out << " " << textureReference
+ << ".GetDimensions(baseLevel + mip, width, height, levels);\n";
+ }
+ else if (IsSampler3D(textureFunction.sampler))
+ {
+ out << " float width; float height; float depth; float levels;\n";
+
+ if (textureFunction.method == TextureFunctionHLSL::TextureFunction::LOD0)
+ {
+ out << " uint mip = 0;\n";
+ }
+ else if (textureFunction.method == TextureFunctionHLSL::TextureFunction::LOD0BIAS)
+ {
+ out << " uint mip = bias;\n";
+ }
+ else
+ {
+ out << " " << textureReference
+ << ".GetDimensions(baseLevel, width, height, depth, levels);\n";
+
+ if (textureFunction.method == TextureFunctionHLSL::TextureFunction::IMPLICIT ||
+ textureFunction.method == TextureFunctionHLSL::TextureFunction::BIAS)
+ {
+ out << " float3 tSized = float3(t.x * width, t.y * height, t.z * depth);\n"
+ " float dx = length(ddx(tSized));\n"
+ " float dy = length(ddy(tSized));\n"
+ " float lod = log2(max(dx, dy));\n";
+
+ if (textureFunction.method == TextureFunctionHLSL::TextureFunction::BIAS)
+ {
+ out << " lod += bias;\n";
+ }
+ }
+ else if (textureFunction.method == TextureFunctionHLSL::TextureFunction::GRAD)
+ {
+ out << " float3 sizeVec = float3(width, height, depth);\n"
+ " float3 sizeDdx = ddx * sizeVec;\n"
+ " float3 sizeDdy = ddy * sizeVec;\n"
+ " float lod = log2(max(dot(sizeDdx, sizeDdx), dot(sizeDdy, "
+ "sizeDdy))) * 0.5f;\n";
+ }
+
+ out << " uint mip = uint(min(max(round(lod), 0), levels - 1));\n";
+ }
+
+ out << " " << textureReference
+ << ".GetDimensions(baseLevel + mip, width, height, depth, levels);\n";
+ }
+ else
+ UNREACHABLE();
+
+ OutputIntTexCoordWraps(out, textureFunction, texCoordX, texCoordY, texCoordZ);
+ }
+}
+
+void OutputTextureGatherFunctionBody(TInfoSinkBase &out,
+ const TextureFunctionHLSL::TextureFunction &textureFunction,
+ ShShaderOutput outputType,
+ const ImmutableString &textureReference,
+ const ImmutableString &samplerReference,
+ const ImmutableString &texCoordX,
+ const ImmutableString &texCoordY,
+ const ImmutableString &texCoordZ)
+{
+ const int hlslCoords = GetHLSLCoordCount(textureFunction, outputType);
+ ImmutableString samplerCoordTypeString(
+ GetSamplerCoordinateTypeString(textureFunction, hlslCoords));
+ ImmutableStringBuilder samplerCoordBuilder(
+ samplerCoordTypeString.length() + strlen("(") + texCoordX.length() + strlen(", ") +
+ texCoordY.length() + strlen(", ") + texCoordZ.length() + strlen(")"));
+
+ samplerCoordBuilder << samplerCoordTypeString << "(" << texCoordX << ", " << texCoordY;
+ if (hlslCoords >= 3)
+ {
+ if (textureFunction.coords < 3)
+ {
+ samplerCoordBuilder << ", 0";
+ }
+ else
+ {
+ samplerCoordBuilder << ", " << texCoordZ;
+ }
+ }
+ samplerCoordBuilder << ")";
+
+ ImmutableString samplerCoordString(samplerCoordBuilder);
+
+ if (IsShadowSampler(textureFunction.sampler))
+ {
+ out << "return " << textureReference << ".GatherCmp(" << samplerReference << ", "
+ << samplerCoordString << ", refZ";
+ if (textureFunction.offset)
+ {
+ out << ", offset";
+ }
+ out << ");\n";
+ return;
+ }
+
+ constexpr std::array<const char *, 4> kHLSLGatherFunctions = {
+ {"GatherRed", "GatherGreen", "GatherBlue", "GatherAlpha"}};
+
+ out << " switch(comp)\n"
+ " {\n";
+ for (size_t component = 0; component < kHLSLGatherFunctions.size(); ++component)
+ {
+ out << " case " << component << ":\n"
+ << " return " << textureReference << "." << kHLSLGatherFunctions[component]
+ << "(" << samplerReference << ", " << samplerCoordString;
+ if (textureFunction.offset)
+ {
+ out << ", offset";
+ }
+ out << ");\n";
+ }
+
+ out << " default:\n"
+ " return float4(0.0, 0.0, 0.0, 1.0);\n"
+ " }\n";
+}
+
+void OutputTextureSampleFunctionReturnStatement(
+ TInfoSinkBase &out,
+ const TextureFunctionHLSL::TextureFunction &textureFunction,
+ const ShShaderOutput outputType,
+ const ImmutableString &textureReference,
+ const ImmutableString &samplerReference,
+ const ImmutableString &texCoordX,
+ const ImmutableString &texCoordY,
+ const ImmutableString &texCoordZ)
+{
+ out << " return ";
+
+ if (IsIntegerSampler(textureFunction.sampler) && !IsSamplerCube(textureFunction.sampler) &&
+ textureFunction.method != TextureFunctionHLSL::TextureFunction::FETCH)
+ {
+ out << " useBorderColor ? ";
+ if (IsIntegerSamplerUnsigned(textureFunction.sampler))
+ {
+ out << "asuint";
+ }
+ out << "(samplerMetadata[samplerIndex].intBorderColor) : ";
+ }
+
+ // HLSL intrinsic
+ if (outputType == SH_HLSL_3_0_OUTPUT)
+ {
+ switch (textureFunction.sampler)
+ {
+ case EbtSampler2D:
+ case EbtSamplerVideoWEBGL:
+ case EbtSamplerExternalOES:
+ out << "tex2D";
+ break;
+ case EbtSamplerCube:
+ out << "texCUBE";
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ switch (textureFunction.method)
+ {
+ case TextureFunctionHLSL::TextureFunction::IMPLICIT:
+ out << "(" << samplerReference << ", ";
+ break;
+ case TextureFunctionHLSL::TextureFunction::BIAS:
+ out << "bias(" << samplerReference << ", ";
+ break;
+ case TextureFunctionHLSL::TextureFunction::LOD:
+ out << "lod(" << samplerReference << ", ";
+ break;
+ case TextureFunctionHLSL::TextureFunction::LOD0:
+ out << "lod(" << samplerReference << ", ";
+ break;
+ case TextureFunctionHLSL::TextureFunction::LOD0BIAS:
+ out << "lod(" << samplerReference << ", ";
+ break;
+ case TextureFunctionHLSL::TextureFunction::GRAD:
+ out << "grad(" << samplerReference << ", ";
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+ else if (outputType == SH_HLSL_4_1_OUTPUT || outputType == SH_HLSL_4_0_FL9_3_OUTPUT)
+ {
+ OutputHLSL4SampleFunctionPrefix(out, textureFunction, textureReference, samplerReference);
+ }
+ else
+ UNREACHABLE();
+
+ const int hlslCoords = GetHLSLCoordCount(textureFunction, outputType);
+ out << GetSamplerCoordinateTypeString(textureFunction, hlslCoords);
+
+ if (hlslCoords >= 2)
+ {
+ out << "(" << texCoordX << ", " << texCoordY;
+ }
+ else if (hlslCoords == 1)
+ {
+ std::string varName(texCoordX.data());
+ if (size_t pos = varName.find_last_of('.') != std::string::npos)
+ {
+ varName = varName.substr(0, pos);
+ }
+ out << "(" << varName;
+ }
+ else
+ {
+ out << "(";
+ }
+
+ if (outputType == SH_HLSL_3_0_OUTPUT)
+ {
+ if (hlslCoords >= 3)
+ {
+ if (textureFunction.coords < 3)
+ {
+ out << ", 0";
+ }
+ else
+ {
+ out << ", " << texCoordZ;
+ }
+ }
+
+ if (hlslCoords == 4)
+ {
+ switch (textureFunction.method)
+ {
+ case TextureFunctionHLSL::TextureFunction::BIAS:
+ out << ", bias";
+ break;
+ case TextureFunctionHLSL::TextureFunction::LOD:
+ out << ", lod";
+ break;
+ case TextureFunctionHLSL::TextureFunction::LOD0:
+ out << ", 0";
+ break;
+ case TextureFunctionHLSL::TextureFunction::LOD0BIAS:
+ out << ", bias";
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ out << ")";
+ }
+ else if (outputType == SH_HLSL_4_1_OUTPUT || outputType == SH_HLSL_4_0_FL9_3_OUTPUT)
+ {
+ if (hlslCoords >= 3)
+ {
+ ASSERT(!IsIntegerSampler(textureFunction.sampler) ||
+ !IsSamplerCube(textureFunction.sampler) || texCoordZ == "face");
+ out << ", " << texCoordZ;
+ }
+
+ if (textureFunction.method == TextureFunctionHLSL::TextureFunction::GRAD)
+ {
+ if (IsIntegerSampler(textureFunction.sampler))
+ {
+ out << ", mip)";
+ }
+ else if (IsShadowSampler(textureFunction.sampler))
+ {
+ // Compare value
+ if (textureFunction.proj)
+ {
+ // According to ESSL 3.00.4 sec 8.8 p95 on textureProj:
+ // The resulting third component of P' in the shadow forms is used as
+ // Dref
+ out << "), " << texCoordZ;
+ }
+ else
+ {
+ switch (textureFunction.coords)
+ {
+ case 3:
+ out << "), t.z";
+ break;
+ case 4:
+ out << "), t.w";
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+ }
+ else
+ {
+ out << "), ddx, ddy";
+ }
+ }
+ else if (IsIntegerSampler(textureFunction.sampler) ||
+ textureFunction.method == TextureFunctionHLSL::TextureFunction::FETCH)
+ {
+ if (IsSampler2DMS(textureFunction.sampler) ||
+ IsSampler2DMSArray(textureFunction.sampler))
+ out << "), index";
+ else if (IsSamplerBuffer(textureFunction.sampler))
+ out << ")";
+ else
+ out << ", mip)";
+ }
+ else if (IsShadowSampler(textureFunction.sampler))
+ {
+ // Compare value
+ if (textureFunction.proj)
+ {
+ // According to ESSL 3.00.4 sec 8.8 p95 on textureProj:
+ // The resulting third component of P' in the shadow forms is used as Dref
+ out << "), " << texCoordZ;
+ }
+ else
+ {
+ switch (textureFunction.coords)
+ {
+ case 3:
+ out << "), t.z";
+ break;
+ case 4:
+ out << "), t.w";
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+ }
+ else
+ {
+ switch (textureFunction.method)
+ {
+ case TextureFunctionHLSL::TextureFunction::IMPLICIT:
+ out << ")";
+ break;
+ case TextureFunctionHLSL::TextureFunction::BIAS:
+ out << "), bias";
+ break;
+ case TextureFunctionHLSL::TextureFunction::LOD:
+ out << "), lod";
+ break;
+ case TextureFunctionHLSL::TextureFunction::LOD0:
+ out << "), 0";
+ break;
+ case TextureFunctionHLSL::TextureFunction::LOD0BIAS:
+ out << "), bias";
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ if (textureFunction.offset &&
+ (!IsIntegerSampler(textureFunction.sampler) ||
+ textureFunction.method == TextureFunctionHLSL::TextureFunction::FETCH))
+ {
+ out << ", offset";
+ }
+ }
+ else
+ UNREACHABLE();
+
+ out << ");\n"; // Close the sample function call and return statement
+}
+
+} // Anonymous namespace
+
+ImmutableString TextureFunctionHLSL::TextureFunction::name() const
+{
+ static const ImmutableString kGlTextureName("gl_texture");
+
+ ImmutableString suffix(TextureTypeSuffix(this->sampler));
+
+ ImmutableStringBuilder name(kGlTextureName.length() + suffix.length() + 4u + 6u + 5u);
+
+ name << kGlTextureName;
+
+ // We need to include full the sampler type in the function name to make the signature unique
+ // on D3D11, where samplers are passed to texture functions as indices.
+ name << suffix;
+
+ if (proj)
+ {
+ name << "Proj";
+ }
+
+ if (offset)
+ {
+ name << "Offset";
+ }
+
+ switch (method)
+ {
+ case IMPLICIT:
+ break;
+ case BIAS:
+ break; // Extra parameter makes the signature unique
+ case LOD:
+ name << "Lod";
+ break;
+ case LOD0:
+ name << "Lod0";
+ break;
+ case LOD0BIAS:
+ name << "Lod0";
+ break; // Extra parameter makes the signature unique
+ case SIZE:
+ name << "Size";
+ break;
+ case FETCH:
+ name << "Fetch";
+ break;
+ case GRAD:
+ name << "Grad";
+ break;
+ case GATHER:
+ name << "Gather";
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ return name;
+}
+
+const char *TextureFunctionHLSL::TextureFunction::getReturnType() const
+{
+ if (method == TextureFunction::SIZE)
+ {
+ switch (sampler)
+ {
+ case EbtSampler2D:
+ case EbtISampler2D:
+ case EbtUSampler2D:
+ case EbtSampler2DShadow:
+ case EbtSamplerCube:
+ case EbtISamplerCube:
+ case EbtUSamplerCube:
+ case EbtSamplerCubeShadow:
+ case EbtSamplerExternalOES:
+ case EbtSampler2DMS:
+ case EbtISampler2DMS:
+ case EbtUSampler2DMS:
+ case EbtSamplerVideoWEBGL:
+ return "int2";
+ case EbtSampler3D:
+ case EbtISampler3D:
+ case EbtUSampler3D:
+ case EbtSampler2DArray:
+ case EbtISampler2DArray:
+ case EbtUSampler2DArray:
+ case EbtSampler2DMSArray:
+ case EbtISampler2DMSArray:
+ case EbtUSampler2DMSArray:
+ case EbtSampler2DArrayShadow:
+ return "int3";
+ case EbtISamplerBuffer:
+ case EbtUSamplerBuffer:
+ case EbtSamplerBuffer:
+ return "int";
+ default:
+ UNREACHABLE();
+ }
+ }
+ else // Sampling function
+ {
+ switch (sampler)
+ {
+ case EbtSampler2D:
+ case EbtSampler2DMS:
+ case EbtSampler2DMSArray:
+ case EbtSampler3D:
+ case EbtSamplerCube:
+ case EbtSampler2DArray:
+ case EbtSamplerExternalOES:
+ case EbtSamplerVideoWEBGL:
+ case EbtSamplerBuffer:
+ return "float4";
+ case EbtISampler2D:
+ case EbtISampler2DMS:
+ case EbtISampler2DMSArray:
+ case EbtISampler3D:
+ case EbtISamplerCube:
+ case EbtISampler2DArray:
+ case EbtISamplerBuffer:
+ return "int4";
+ case EbtUSampler2D:
+ case EbtUSampler2DMS:
+ case EbtUSampler2DMSArray:
+ case EbtUSampler3D:
+ case EbtUSamplerCube:
+ case EbtUSampler2DArray:
+ case EbtUSamplerBuffer:
+ return "uint4";
+ case EbtSampler2DShadow:
+ case EbtSamplerCubeShadow:
+ case EbtSampler2DArrayShadow:
+ if (method == TextureFunctionHLSL::TextureFunction::GATHER)
+ {
+ return "float4";
+ }
+ else
+ {
+ return "float";
+ }
+ default:
+ UNREACHABLE();
+ }
+ }
+ return "";
+}
+
+bool TextureFunctionHLSL::TextureFunction::operator<(const TextureFunction &rhs) const
+{
+ return std::tie(sampler, coords, proj, offset, method) <
+ std::tie(rhs.sampler, rhs.coords, rhs.proj, rhs.offset, rhs.method);
+}
+
+ImmutableString TextureFunctionHLSL::useTextureFunction(const ImmutableString &name,
+ TBasicType samplerType,
+ int coords,
+ size_t argumentCount,
+ bool lod0,
+ sh::GLenum shaderType)
+{
+ TextureFunction textureFunction;
+ textureFunction.sampler = samplerType;
+ textureFunction.coords = coords;
+ textureFunction.method = TextureFunction::IMPLICIT;
+ textureFunction.proj = false;
+ textureFunction.offset = false;
+
+ if (name == "texture2D" || name == "textureCube" || name == "texture")
+ {
+ textureFunction.method = TextureFunction::IMPLICIT;
+ }
+ else if (name == "texture2DProj" || name == "textureProj")
+ {
+ textureFunction.method = TextureFunction::IMPLICIT;
+ textureFunction.proj = true;
+ }
+ else if (name == "texture2DLod" || name == "textureCubeLod" || name == "textureLod" ||
+ name == "texture2DLodEXT" || name == "textureCubeLodEXT")
+ {
+ textureFunction.method = TextureFunction::LOD;
+ }
+ else if (name == "texture2DProjLod" || name == "textureProjLod" ||
+ name == "texture2DProjLodEXT")
+ {
+ textureFunction.method = TextureFunction::LOD;
+ textureFunction.proj = true;
+ }
+ else if (name == "textureSize")
+ {
+ textureFunction.method = TextureFunction::SIZE;
+ }
+ else if (name == "textureOffset")
+ {
+ textureFunction.method = TextureFunction::IMPLICIT;
+ textureFunction.offset = true;
+ }
+ else if (name == "textureProjOffset")
+ {
+ textureFunction.method = TextureFunction::IMPLICIT;
+ textureFunction.offset = true;
+ textureFunction.proj = true;
+ }
+ else if (name == "textureLodOffset")
+ {
+ textureFunction.method = TextureFunction::LOD;
+ textureFunction.offset = true;
+ }
+ else if (name == "textureProjLodOffset")
+ {
+ textureFunction.method = TextureFunction::LOD;
+ textureFunction.proj = true;
+ textureFunction.offset = true;
+ }
+ else if (name == "texelFetch")
+ {
+ textureFunction.method = TextureFunction::FETCH;
+ }
+ else if (name == "texelFetchOffset")
+ {
+ textureFunction.method = TextureFunction::FETCH;
+ textureFunction.offset = true;
+ }
+ else if (name == "textureGrad" || name == "texture2DGradEXT")
+ {
+ textureFunction.method = TextureFunction::GRAD;
+ }
+ else if (name == "textureGradOffset")
+ {
+ textureFunction.method = TextureFunction::GRAD;
+ textureFunction.offset = true;
+ }
+ else if (name == "textureProjGrad" || name == "texture2DProjGradEXT" ||
+ name == "textureCubeGradEXT")
+ {
+ textureFunction.method = TextureFunction::GRAD;
+ textureFunction.proj = true;
+ }
+ else if (name == "textureProjGradOffset")
+ {
+ textureFunction.method = TextureFunction::GRAD;
+ textureFunction.proj = true;
+ textureFunction.offset = true;
+ }
+ else if (name == "textureGather")
+ {
+ textureFunction.method = TextureFunction::GATHER;
+ }
+ else if (name == "textureGatherOffset")
+ {
+ textureFunction.method = TextureFunction::GATHER;
+ textureFunction.offset = true;
+ }
+ else if (name == "textureVideoWEBGL")
+ {
+ textureFunction.method = TextureFunction::IMPLICIT;
+ }
+ else
+ UNREACHABLE();
+
+ if (textureFunction.method ==
+ TextureFunction::IMPLICIT) // Could require lod 0 or have a bias argument
+ {
+ size_t mandatoryArgumentCount = 2; // All functions have sampler and coordinate arguments
+
+ if (textureFunction.offset)
+ {
+ mandatoryArgumentCount++;
+ }
+
+ bool bias = (argumentCount > mandatoryArgumentCount); // Bias argument is optional
+
+ if (lod0 || shaderType == GL_VERTEX_SHADER || shaderType == GL_COMPUTE_SHADER)
+ {
+ if (bias)
+ {
+ textureFunction.method = TextureFunction::LOD0BIAS;
+ }
+ else
+ {
+ textureFunction.method = TextureFunction::LOD0;
+ }
+ }
+ else if (bias)
+ {
+ textureFunction.method = TextureFunction::BIAS;
+ }
+ }
+
+ mUsesTexture.insert(textureFunction);
+ return textureFunction.name();
+}
+
+void TextureFunctionHLSL::textureFunctionHeader(TInfoSinkBase &out,
+ const ShShaderOutput outputType,
+ bool getDimensionsIgnoresBaseLevel)
+{
+ for (const TextureFunction &textureFunction : mUsesTexture)
+ {
+ // Function header
+ out << textureFunction.getReturnType() << " " << textureFunction.name() << "(";
+
+ OutputTextureFunctionArgumentList(out, textureFunction, outputType);
+
+ out << ")\n"
+ "{\n";
+
+ // In some cases we use a variable to store the texture/sampler objects, but to work around
+ // a D3D11 compiler bug related to discard inside a loop that is conditional on texture
+ // sampling we need to call the function directly on references to the texture and sampler
+ // arrays. The bug was found using dEQP-GLES3.functional.shaders.discard*loop_texture*
+ // tests.
+ ImmutableString textureReference("");
+ ImmutableString samplerReference("");
+ GetTextureReference(out, textureFunction, outputType, &textureReference, &samplerReference);
+
+ if (textureFunction.method == TextureFunction::SIZE)
+ {
+ OutputTextureSizeFunctionBody(out, textureFunction, textureReference,
+ getDimensionsIgnoresBaseLevel);
+ }
+ else
+ {
+ ImmutableString texCoordX("t.x");
+ ImmutableString texCoordY("t.y");
+ ImmutableString texCoordZ("t.z");
+ if (textureFunction.method == TextureFunction::GATHER)
+ {
+ OutputTextureGatherFunctionBody(out, textureFunction, outputType, textureReference,
+ samplerReference, texCoordX, texCoordY, texCoordZ);
+ }
+ else
+ {
+ ProjectTextureCoordinates(textureFunction, &texCoordX, &texCoordY, &texCoordZ);
+ OutputIntegerTextureSampleFunctionComputations(
+ out, textureFunction, outputType, textureReference, &texCoordX, &texCoordY,
+ &texCoordZ, getDimensionsIgnoresBaseLevel);
+ OutputTextureSampleFunctionReturnStatement(out, textureFunction, outputType,
+ textureReference, samplerReference,
+ texCoordX, texCoordY, texCoordZ);
+ }
+ }
+
+ out << "}\n"
+ "\n";
+ }
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/TextureFunctionHLSL.h b/gfx/angle/checkout/src/compiler/translator/TextureFunctionHLSL.h
new file mode 100644
index 0000000000..6e81ad00c6
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/TextureFunctionHLSL.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.
+//
+// TextureFunctionHLSL: Class for writing implementations of ESSL texture functions into HLSL
+// output. Some of the implementations are straightforward and just call the HLSL equivalent of the
+// ESSL texture function, others do more work to emulate ESSL texture sampling or size query
+// behavior.
+//
+
+#ifndef COMPILER_TRANSLATOR_TEXTUREFUNCTIONHLSL_H_
+#define COMPILER_TRANSLATOR_TEXTUREFUNCTIONHLSL_H_
+
+#include <set>
+
+#include "GLSLANG/ShaderLang.h"
+#include "compiler/translator/BaseTypes.h"
+#include "compiler/translator/Common.h"
+#include "compiler/translator/InfoSink.h"
+
+namespace sh
+{
+
+class TextureFunctionHLSL final : angle::NonCopyable
+{
+ public:
+ struct TextureFunction
+ {
+ // See ESSL 3.00.6 section 8.8 for reference about what the different methods below do.
+ enum Method
+ {
+ IMPLICIT, // Mipmap LOD determined implicitly (standard lookup)
+ BIAS,
+ LOD,
+ LOD0,
+ LOD0BIAS,
+ SIZE, // textureSize()
+ FETCH,
+ GRAD,
+ GATHER
+ };
+
+ ImmutableString name() const;
+
+ bool operator<(const TextureFunction &rhs) const;
+
+ const char *getReturnType() const;
+
+ TBasicType sampler;
+ int coords;
+ bool proj;
+ bool offset;
+ Method method;
+ };
+
+ // Returns the name of the texture function implementation to call.
+ // The name that's passed in is the name of the GLSL texture function that it should implement.
+ ImmutableString useTextureFunction(const ImmutableString &name,
+ TBasicType samplerType,
+ int coords,
+ size_t argumentCount,
+ bool lod0,
+ sh::GLenum shaderType);
+
+ void textureFunctionHeader(TInfoSinkBase &out,
+ const ShShaderOutput outputType,
+ bool getDimensionsIgnoresBaseLevel);
+
+ private:
+ typedef std::set<TextureFunction> TextureFunctionSet;
+ TextureFunctionSet mUsesTexture;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TEXTUREFUNCTIONHLSL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/TranslatorESSL.cpp b/gfx/angle/checkout/src/compiler/translator/TranslatorESSL.cpp
new file mode 100644
index 0000000000..5179b8c9b3
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/TranslatorESSL.cpp
@@ -0,0 +1,219 @@
+//
+// Copyright 2002 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/TranslatorESSL.h"
+
+#include "angle_gl.h"
+#include "common/utilities.h"
+#include "compiler/translator/BuiltInFunctionEmulatorGLSL.h"
+#include "compiler/translator/OutputESSL.h"
+#include "compiler/translator/tree_ops/RecordConstantPrecision.h"
+
+namespace sh
+{
+
+TranslatorESSL::TranslatorESSL(sh::GLenum type, ShShaderSpec spec)
+ : TCompiler(type, spec, SH_ESSL_OUTPUT)
+{}
+
+void TranslatorESSL::initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu,
+ const ShCompileOptions &compileOptions)
+{
+ if (compileOptions.emulateAtan2FloatFunction)
+ {
+ InitBuiltInAtanFunctionEmulatorForGLSLWorkarounds(emu);
+ }
+}
+
+bool TranslatorESSL::translate(TIntermBlock *root,
+ const ShCompileOptions &compileOptions,
+ PerformanceDiagnostics * /*perfDiagnostics*/)
+{
+ TInfoSinkBase &sink = getInfoSink().obj;
+
+ int shaderVer = getShaderVersion(); // Frontend shader version.
+ if (hasPixelLocalStorageUniforms() &&
+ ShPixelLocalStorageTypeUsesImages(compileOptions.pls.type))
+ {
+ // The backend translator emits shader image code. Use a minimum version of 310.
+ shaderVer = std::max(shaderVer, 310);
+ }
+ if (shaderVer > 100)
+ {
+ sink << "#version " << shaderVer << " es\n";
+ }
+
+ // Write built-in extension behaviors.
+ writeExtensionBehavior(compileOptions);
+
+ // Write pragmas after extensions because some drivers consider pragmas
+ // like non-preprocessor tokens.
+ WritePragma(sink, compileOptions, getPragma());
+
+ if (!RecordConstantPrecision(this, root, &getSymbolTable()))
+ {
+ return false;
+ }
+
+ // Write emulated built-in functions if needed.
+ if (!getBuiltInFunctionEmulator().isOutputEmpty())
+ {
+ sink << "// BEGIN: Generated code for built-in function emulation\n\n";
+ if (getShaderType() == GL_FRAGMENT_SHADER)
+ {
+ sink << "#if defined(GL_FRAGMENT_PRECISION_HIGH)\n"
+ << "#define emu_precision highp\n"
+ << "#else\n"
+ << "#define emu_precision mediump\n"
+ << "#endif\n\n";
+ }
+ else
+ {
+ sink << "#define emu_precision highp\n";
+ }
+
+ getBuiltInFunctionEmulator().outputEmulatedFunctions(sink);
+ sink << "// END: Generated code for built-in function emulation\n\n";
+ }
+
+ if (getShaderType() == GL_FRAGMENT_SHADER)
+ {
+ EmitEarlyFragmentTestsGLSL(*this, sink);
+ }
+
+ if (getShaderType() == GL_COMPUTE_SHADER)
+ {
+ EmitWorkGroupSizeGLSL(*this, sink);
+ }
+
+ if (getShaderType() == GL_GEOMETRY_SHADER_EXT)
+ {
+ WriteGeometryShaderLayoutQualifiers(
+ sink, getGeometryShaderInputPrimitiveType(), getGeometryShaderInvocations(),
+ getGeometryShaderOutputPrimitiveType(), getGeometryShaderMaxVertices());
+ }
+
+ // Write translated shader.
+ TOutputESSL outputESSL(this, sink, compileOptions);
+
+ root->traverse(&outputESSL);
+
+ return true;
+}
+
+bool TranslatorESSL::shouldFlattenPragmaStdglInvariantAll()
+{
+ // If following the spec to the letter, we should not flatten this pragma.
+ // However, the spec's wording means that the pragma applies only to outputs.
+ // This contradicts the spirit of using the pragma,
+ // because if the pragma is used in a vertex shader,
+ // the only way to be able to link it to a fragment shader
+ // is to manually qualify each of fragment shader's inputs as invariant.
+ // Which defeats the purpose of this pragma - temporarily make all varyings
+ // invariant for debugging.
+ // Thus, we should be non-conformant to spec's letter here and flatten.
+ return true;
+}
+
+void TranslatorESSL::writeExtensionBehavior(const ShCompileOptions &compileOptions)
+{
+ TInfoSinkBase &sink = getInfoSink().obj;
+ const TExtensionBehavior &extBehavior = getExtensionBehavior();
+ for (TExtensionBehavior::const_iterator iter = extBehavior.begin(); iter != extBehavior.end();
+ ++iter)
+ {
+ if (iter->second != EBhUndefined)
+ {
+ const bool isMultiview = (iter->first == TExtension::OVR_multiview) ||
+ (iter->first == TExtension::OVR_multiview2);
+ if (getResources().NV_shader_framebuffer_fetch &&
+ iter->first == TExtension::EXT_shader_framebuffer_fetch)
+ {
+ sink << "#extension GL_NV_shader_framebuffer_fetch : "
+ << GetBehaviorString(iter->second) << "\n";
+ }
+ else if (getResources().NV_draw_buffers && iter->first == TExtension::EXT_draw_buffers)
+ {
+ sink << "#extension GL_NV_draw_buffers : " << GetBehaviorString(iter->second)
+ << "\n";
+ }
+ else if (isMultiview)
+ {
+ // Only either OVR_multiview OR OVR_multiview2 should be emitted.
+ if ((iter->first != TExtension::OVR_multiview) ||
+ !IsExtensionEnabled(extBehavior, TExtension::OVR_multiview2))
+ {
+ EmitMultiviewGLSL(*this, compileOptions, iter->first, iter->second, sink);
+ }
+ }
+ else if (iter->first == TExtension::EXT_geometry_shader ||
+ iter->first == TExtension::OES_geometry_shader)
+ {
+ sink << "#ifdef GL_EXT_geometry_shader\n"
+ << "#extension GL_EXT_geometry_shader : " << GetBehaviorString(iter->second)
+ << "\n"
+ << "#elif defined GL_OES_geometry_shader\n"
+ << "#extension GL_OES_geometry_shader : " << GetBehaviorString(iter->second)
+ << "\n";
+ if (iter->second == EBhRequire)
+ {
+ sink << "#else\n"
+ << "#error \"No geometry shader extensions available.\" // Only generate "
+ "this if the extension is \"required\"\n";
+ }
+ sink << "#endif\n";
+ }
+ else if (iter->first == TExtension::ANGLE_multi_draw)
+ {
+ // Don't emit anything. This extension is emulated
+ ASSERT(compileOptions.emulateGLDrawID);
+ continue;
+ }
+ else if (iter->first == TExtension::ANGLE_base_vertex_base_instance_shader_builtin)
+ {
+ // Don't emit anything. This extension is emulated
+ ASSERT(compileOptions.emulateGLBaseVertexBaseInstance);
+ continue;
+ }
+ else if (iter->first == TExtension::ANGLE_shader_pixel_local_storage)
+ {
+ // TODO(anglebug.com/7279): future impl that uses EXT_shader_pixel_local_storage.
+ if (compileOptions.pls.type == ShPixelLocalStorageType::FramebufferFetch)
+ {
+ // Just enable the extension. Appropriate warnings will be generated by the
+ // frontend compiler for GL_ANGLE_shader_pixel_local_storage, if desired.
+ sink << "#extension GL_EXT_shader_framebuffer_fetch : enable\n";
+ }
+ continue;
+ }
+ else if (iter->first == TExtension::EXT_shader_framebuffer_fetch)
+ {
+ sink << "#extension GL_EXT_shader_framebuffer_fetch : "
+ << GetBehaviorString(iter->second) << "\n";
+ continue;
+ }
+ else if (iter->first == TExtension::EXT_shader_framebuffer_fetch_non_coherent)
+ {
+ sink << "#extension GL_EXT_shader_framebuffer_fetch_non_coherent : "
+ << GetBehaviorString(iter->second) << "\n";
+ continue;
+ }
+ else if (iter->first == TExtension::WEBGL_video_texture)
+ {
+ // Don't emit anything. This extension is emulated
+ // TODO(crbug.com/776222): support external image.
+ continue;
+ }
+ else
+ {
+ sink << "#extension " << GetExtensionNameString(iter->first) << " : "
+ << GetBehaviorString(iter->second) << "\n";
+ }
+ }
+ }
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/TranslatorESSL.h b/gfx/angle/checkout/src/compiler/translator/TranslatorESSL.h
new file mode 100644
index 0000000000..913d441364
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/TranslatorESSL.h
@@ -0,0 +1,35 @@
+//
+// Copyright 2002 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_TRANSLATORESSL_H_
+#define COMPILER_TRANSLATOR_TRANSLATORESSL_H_
+
+#include "compiler/translator/Compiler.h"
+
+namespace sh
+{
+
+class TranslatorESSL : public TCompiler
+{
+ public:
+ TranslatorESSL(sh::GLenum type, ShShaderSpec spec);
+
+ protected:
+ void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu,
+ const ShCompileOptions &compileOptions) override;
+
+ [[nodiscard]] bool translate(TIntermBlock *root,
+ const ShCompileOptions &compileOptions,
+ PerformanceDiagnostics *perfDiagnostics) override;
+ bool shouldFlattenPragmaStdglInvariantAll() override;
+
+ private:
+ void writeExtensionBehavior(const ShCompileOptions &compileOptions);
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TRANSLATORESSL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/TranslatorGLSL.cpp b/gfx/angle/checkout/src/compiler/translator/TranslatorGLSL.cpp
new file mode 100644
index 0000000000..76e0130e77
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/TranslatorGLSL.cpp
@@ -0,0 +1,388 @@
+//
+// Copyright 2002 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/TranslatorGLSL.h"
+
+#include "angle_gl.h"
+#include "compiler/translator/BuiltInFunctionEmulatorGLSL.h"
+#include "compiler/translator/ExtensionGLSL.h"
+#include "compiler/translator/OutputGLSL.h"
+#include "compiler/translator/VersionGLSL.h"
+#include "compiler/translator/tree_ops/RewriteTexelFetchOffset.h"
+#include "compiler/translator/tree_ops/apple/RewriteRowMajorMatrices.h"
+#include "compiler/translator/tree_ops/apple/RewriteUnaryMinusOperatorFloat.h"
+
+namespace sh
+{
+
+TranslatorGLSL::TranslatorGLSL(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output)
+ : TCompiler(type, spec, output)
+{}
+
+void TranslatorGLSL::initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu,
+ const ShCompileOptions &compileOptions)
+{
+ if (compileOptions.emulateAbsIntFunction)
+ {
+ InitBuiltInAbsFunctionEmulatorForGLSLWorkarounds(emu, getShaderType());
+ }
+
+ if (compileOptions.emulateIsnanFloatFunction)
+ {
+ InitBuiltInIsnanFunctionEmulatorForGLSLWorkarounds(emu, getShaderVersion());
+ }
+
+ if (compileOptions.emulateAtan2FloatFunction)
+ {
+ InitBuiltInAtanFunctionEmulatorForGLSLWorkarounds(emu);
+ }
+
+ int targetGLSLVersion = ShaderOutputTypeToGLSLVersion(getOutputType());
+ InitBuiltInFunctionEmulatorForGLSLMissingFunctions(emu, getShaderType(), targetGLSLVersion);
+}
+
+bool TranslatorGLSL::translate(TIntermBlock *root,
+ const ShCompileOptions &compileOptions,
+ PerformanceDiagnostics * /*perfDiagnostics*/)
+{
+ TInfoSinkBase &sink = getInfoSink().obj;
+
+ // Write GLSL version.
+ writeVersion(root);
+
+ // Write extension behaviour as needed
+ writeExtensionBehavior(root, compileOptions);
+
+ // Write pragmas after extensions because some drivers consider pragmas
+ // like non-preprocessor tokens.
+ WritePragma(sink, compileOptions, getPragma());
+
+ // 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.flattenPragmaSTDGLInvariantAll && getPragma().stdgl.invariantAll &&
+ !sh::RemoveInvariant(getShaderType(), getShaderVersion(), getOutputType(), compileOptions))
+ {
+ ASSERT(wereVariablesCollected());
+
+ 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.rewriteTexelFetchOffsetToTexelFetch)
+ {
+ if (!sh::RewriteTexelFetchOffset(this, root, getSymbolTable(), getShaderVersion()))
+ {
+ return false;
+ }
+ }
+
+ if (compileOptions.rewriteFloatUnaryMinusOperator)
+ {
+ if (!sh::RewriteUnaryMinusOperatorFloat(this, root))
+ {
+ return false;
+ }
+ }
+
+ if (compileOptions.rewriteRowMajorMatrices && getShaderVersion() >= 300)
+ {
+ if (!RewriteRowMajorMatrices(this, root, &getSymbolTable()))
+ {
+ return false;
+ }
+ }
+
+ // Write emulated built-in functions if needed.
+ if (!getBuiltInFunctionEmulator().isOutputEmpty())
+ {
+ sink << "// BEGIN: Generated code for built-in function emulation\n\n";
+ sink << "#define emu_precision\n\n";
+ getBuiltInFunctionEmulator().outputEmulatedFunctions(sink);
+ sink << "// END: Generated code for built-in function emulation\n\n";
+ }
+
+ // Declare gl_FragColor and glFragData as webgl_FragColor and webgl_FragData
+ // if it's core profile shaders and they are used.
+ if (getShaderType() == GL_FRAGMENT_SHADER)
+ {
+ const bool mayHaveESSL1SecondaryOutputs =
+ IsExtensionEnabled(getExtensionBehavior(), TExtension::EXT_blend_func_extended) &&
+ getShaderVersion() == 100;
+ const bool declareGLFragmentOutputs = IsGLSL130OrNewer(getOutputType());
+
+ bool hasGLFragColor = false;
+ bool hasGLFragData = false;
+ bool hasGLSecondaryFragColor = false;
+ bool hasGLSecondaryFragData = false;
+
+ for (const auto &outputVar : mOutputVariables)
+ {
+ if (declareGLFragmentOutputs)
+ {
+ if (outputVar.name == "gl_FragColor")
+ {
+ ASSERT(!hasGLFragColor);
+ hasGLFragColor = true;
+ continue;
+ }
+ else if (outputVar.name == "gl_FragData")
+ {
+ ASSERT(!hasGLFragData);
+ hasGLFragData = true;
+ continue;
+ }
+ }
+ if (mayHaveESSL1SecondaryOutputs)
+ {
+ if (outputVar.name == "gl_SecondaryFragColorEXT")
+ {
+ ASSERT(!hasGLSecondaryFragColor);
+ hasGLSecondaryFragColor = true;
+ continue;
+ }
+ else if (outputVar.name == "gl_SecondaryFragDataEXT")
+ {
+ ASSERT(!hasGLSecondaryFragData);
+ hasGLSecondaryFragData = true;
+ continue;
+ }
+ }
+ }
+ ASSERT(!((hasGLFragColor || hasGLSecondaryFragColor) &&
+ (hasGLFragData || hasGLSecondaryFragData)));
+ if (hasGLFragColor)
+ {
+ sink << "out vec4 webgl_FragColor;\n";
+ }
+ if (hasGLFragData)
+ {
+ sink << "out vec4 webgl_FragData[gl_MaxDrawBuffers];\n";
+ }
+ if (hasGLSecondaryFragColor)
+ {
+ sink << "out vec4 webgl_SecondaryFragColor;\n";
+ }
+ if (hasGLSecondaryFragData)
+ {
+ sink << "out vec4 webgl_SecondaryFragData[" << getResources().MaxDualSourceDrawBuffers
+ << "];\n";
+ }
+
+ EmitEarlyFragmentTestsGLSL(*this, sink);
+ }
+
+ if (getShaderType() == GL_COMPUTE_SHADER)
+ {
+ EmitWorkGroupSizeGLSL(*this, sink);
+ }
+
+ if (getShaderType() == GL_GEOMETRY_SHADER_EXT)
+ {
+ WriteGeometryShaderLayoutQualifiers(
+ sink, getGeometryShaderInputPrimitiveType(), getGeometryShaderInvocations(),
+ getGeometryShaderOutputPrimitiveType(), getGeometryShaderMaxVertices());
+ }
+
+ // Write translated shader.
+ TOutputGLSL outputGLSL(this, sink, compileOptions);
+
+ root->traverse(&outputGLSL);
+
+ return true;
+}
+
+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());
+}
+
+bool TranslatorGLSL::shouldCollectVariables(const ShCompileOptions &compileOptions)
+{
+ return compileOptions.flattenPragmaSTDGLInvariantAll ||
+ TCompiler::shouldCollectVariables(compileOptions);
+}
+
+void TranslatorGLSL::writeVersion(TIntermNode *root)
+{
+ TVersionGLSL versionGLSL(getShaderType(), getPragma(), getOutputType());
+ root->traverse(&versionGLSL);
+ int version = versionGLSL.getVersion();
+ // We need to write version directive only if it is greater than 110.
+ // If there is no version directive in the shader, 110 is implied.
+ if (version > 110)
+ {
+ TInfoSinkBase &sink = getInfoSink().obj;
+ sink << "#version " << version << "\n";
+ }
+}
+
+void TranslatorGLSL::writeExtensionBehavior(TIntermNode *root,
+ const ShCompileOptions &compileOptions)
+{
+ bool usesTextureCubeMapArray = false;
+ bool usesTextureBuffer = false;
+
+ TInfoSinkBase &sink = getInfoSink().obj;
+ const TExtensionBehavior &extBehavior = getExtensionBehavior();
+ for (const auto &iter : extBehavior)
+ {
+ if (iter.second == EBhUndefined)
+ {
+ continue;
+ }
+
+ if (getOutputType() == SH_GLSL_COMPATIBILITY_OUTPUT)
+ {
+ // For GLSL output, we don't need to emit most extensions explicitly,
+ // but some we need to translate in GL compatibility profile.
+ if (iter.first == TExtension::EXT_shader_texture_lod)
+ {
+ sink << "#extension GL_ARB_shader_texture_lod : " << GetBehaviorString(iter.second)
+ << "\n";
+ }
+
+ if (iter.first == TExtension::EXT_draw_buffers)
+ {
+ sink << "#extension GL_ARB_draw_buffers : " << GetBehaviorString(iter.second)
+ << "\n";
+ }
+
+ if (iter.first == TExtension::EXT_geometry_shader ||
+ iter.first == TExtension::OES_geometry_shader)
+ {
+ sink << "#extension GL_ARB_geometry_shader4 : " << GetBehaviorString(iter.second)
+ << "\n";
+ }
+ }
+
+ const bool isMultiview =
+ (iter.first == TExtension::OVR_multiview) || (iter.first == TExtension::OVR_multiview2);
+ if (isMultiview)
+ {
+ // Only either OVR_multiview or OVR_multiview2 should be emitted.
+ if ((iter.first != TExtension::OVR_multiview) ||
+ !IsExtensionEnabled(extBehavior, TExtension::OVR_multiview2))
+ {
+ EmitMultiviewGLSL(*this, compileOptions, iter.first, iter.second, sink);
+ }
+ }
+
+ // Support ANGLE_texture_multisample extension on GLSL300
+ if (getShaderVersion() >= 300 && iter.first == TExtension::ANGLE_texture_multisample &&
+ getOutputType() < SH_GLSL_330_CORE_OUTPUT)
+ {
+ sink << "#extension GL_ARB_texture_multisample : " << GetBehaviorString(iter.second)
+ << "\n";
+ }
+
+ if ((iter.first == TExtension::OES_texture_cube_map_array ||
+ iter.first == TExtension::EXT_texture_cube_map_array) &&
+ (iter.second == EBhRequire || iter.second == EBhEnable))
+ {
+ usesTextureCubeMapArray = true;
+ }
+
+ if ((iter.first == TExtension::OES_texture_buffer ||
+ iter.first == TExtension::EXT_texture_buffer) &&
+ (iter.second == EBhRequire || iter.second == EBhEnable))
+ {
+ usesTextureBuffer = true;
+ }
+ }
+
+ // GLSL ES 3 explicit location qualifiers need to use an extension before GLSL 330
+ if (getShaderVersion() >= 300 && getOutputType() < SH_GLSL_330_CORE_OUTPUT &&
+ getShaderType() != GL_COMPUTE_SHADER)
+ {
+ sink << "#extension GL_ARB_explicit_attrib_location : require\n";
+ }
+
+ // Need to enable gpu_shader5 to have index constant sampler array indexing
+ if (getOutputType() != SH_ESSL_OUTPUT && getOutputType() < SH_GLSL_400_CORE_OUTPUT &&
+ getShaderVersion() == 100)
+ {
+ // Don't use "require" on to avoid breaking WebGL 1 on drivers that silently
+ // support index constant sampler array indexing, but don't have the extension or
+ // on drivers that don't have the extension at all as it would break WebGL 1 for
+ // some users.
+ sink << "#extension GL_ARB_gpu_shader5 : enable\n";
+ sink << "#extension GL_EXT_gpu_shader5 : enable\n";
+ }
+
+ if (usesTextureCubeMapArray)
+ {
+ if (getOutputType() >= SH_GLSL_COMPATIBILITY_OUTPUT &&
+ getOutputType() < SH_GLSL_400_CORE_OUTPUT)
+ {
+ sink << "#extension GL_ARB_texture_cube_map_array : enable\n";
+ }
+ else if (getOutputType() == SH_ESSL_OUTPUT && getShaderVersion() < 320)
+ {
+ sink << "#extension GL_OES_texture_cube_map_array : enable\n";
+ sink << "#extension GL_EXT_texture_cube_map_array : enable\n";
+ }
+ }
+
+ if (usesTextureBuffer)
+ {
+ if (getOutputType() >= SH_GLSL_COMPATIBILITY_OUTPUT &&
+ getOutputType() < SH_GLSL_400_CORE_OUTPUT)
+ {
+ sink << "#extension GL_ARB_texture_buffer_objects : enable\n";
+ }
+ else if (getOutputType() == SH_ESSL_OUTPUT && getShaderVersion() < 320)
+ {
+ sink << "#extension GL_OES_texture_buffer : enable\n";
+ sink << "#extension GL_EXT_texture_buffer : enable\n";
+ }
+ }
+
+ TExtensionGLSL extensionGLSL(getOutputType());
+ root->traverse(&extensionGLSL);
+
+ for (const auto &ext : extensionGLSL.getEnabledExtensions())
+ {
+ sink << "#extension " << ext << " : enable\n";
+ }
+ for (const auto &ext : extensionGLSL.getRequiredExtensions())
+ {
+ sink << "#extension " << ext << " : require\n";
+ }
+}
+
+void TranslatorGLSL::conditionallyOutputInvariantDeclaration(const char *builtinVaryingName)
+{
+ if (isVaryingDefined(builtinVaryingName))
+ {
+ TInfoSinkBase &sink = getInfoSink().obj;
+ sink << "invariant " << builtinVaryingName << ";\n";
+ }
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/TranslatorGLSL.h b/gfx/angle/checkout/src/compiler/translator/TranslatorGLSL.h
new file mode 100644
index 0000000000..0e0c65f09a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/TranslatorGLSL.h
@@ -0,0 +1,38 @@
+//
+// Copyright 2002 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_TRANSLATORGLSL_H_
+#define COMPILER_TRANSLATOR_TRANSLATORGLSL_H_
+
+#include "compiler/translator/Compiler.h"
+
+namespace sh
+{
+
+class TranslatorGLSL : public TCompiler
+{
+ public:
+ TranslatorGLSL(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output);
+
+ protected:
+ void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu,
+ const ShCompileOptions &compileOptions) override;
+
+ [[nodiscard]] bool translate(TIntermBlock *root,
+ const ShCompileOptions &compileOptions,
+ PerformanceDiagnostics *perfDiagnostics) override;
+ bool shouldFlattenPragmaStdglInvariantAll() override;
+ bool shouldCollectVariables(const ShCompileOptions &compileOptions) override;
+
+ private:
+ void writeVersion(TIntermNode *root);
+ void writeExtensionBehavior(TIntermNode *root, const ShCompileOptions &compileOptions);
+ void conditionallyOutputInvariantDeclaration(const char *builtinVaryingName);
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TRANSLATORGLSL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/TranslatorHLSL.cpp b/gfx/angle/checkout/src/compiler/translator/TranslatorHLSL.cpp
new file mode 100644
index 0000000000..d07ed2975e
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/TranslatorHLSL.cpp
@@ -0,0 +1,311 @@
+//
+// Copyright 2002 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/TranslatorHLSL.h"
+
+#include "compiler/translator/OutputHLSL.h"
+#include "compiler/translator/tree_ops/RemoveDynamicIndexing.h"
+#include "compiler/translator/tree_ops/RewriteTexelFetchOffset.h"
+#include "compiler/translator/tree_ops/SimplifyLoopConditions.h"
+#include "compiler/translator/tree_ops/SplitSequenceOperator.h"
+#include "compiler/translator/tree_ops/d3d/AddDefaultReturnStatements.h"
+#include "compiler/translator/tree_ops/d3d/AggregateAssignArraysInSSBOs.h"
+#include "compiler/translator/tree_ops/d3d/AggregateAssignStructsInSSBOs.h"
+#include "compiler/translator/tree_ops/d3d/ArrayReturnValueToOutParameter.h"
+#include "compiler/translator/tree_ops/d3d/BreakVariableAliasingInInnerLoops.h"
+#include "compiler/translator/tree_ops/d3d/ExpandIntegerPowExpressions.h"
+#include "compiler/translator/tree_ops/d3d/RecordUniformBlocksWithLargeArrayMember.h"
+#include "compiler/translator/tree_ops/d3d/RewriteAtomicFunctionExpressions.h"
+#include "compiler/translator/tree_ops/d3d/RewriteElseBlocks.h"
+#include "compiler/translator/tree_ops/d3d/RewriteExpressionsWithShaderStorageBlock.h"
+#include "compiler/translator/tree_ops/d3d/RewriteUnaryMinusOperatorInt.h"
+#include "compiler/translator/tree_ops/d3d/SeparateArrayConstructorStatements.h"
+#include "compiler/translator/tree_ops/d3d/SeparateArrayInitialization.h"
+#include "compiler/translator/tree_ops/d3d/SeparateExpressionsReturningArrays.h"
+#include "compiler/translator/tree_ops/d3d/UnfoldShortCircuitToIf.h"
+#include "compiler/translator/tree_ops/d3d/WrapSwitchStatementsInBlocks.h"
+#include "compiler/translator/tree_util/IntermNodePatternMatcher.h"
+
+namespace sh
+{
+
+TranslatorHLSL::TranslatorHLSL(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output)
+ : TCompiler(type, spec, output)
+{}
+
+bool TranslatorHLSL::translate(TIntermBlock *root,
+ const ShCompileOptions &compileOptions,
+ PerformanceDiagnostics *perfDiagnostics)
+{
+ // A few transformations leave the tree in an inconsistent state. For example, when unfolding
+ // the short-circuit in the following function:
+ //
+ // mediump float f(float a) { return a > 0 ? 0.0 : 1.0; }
+ //
+ // a temp variable is created to hold the result of the expression. Currently the precision of
+ // the return value of the function is not propagated to its return expressions. Additionally,
+ // an expression such as
+ //
+ // cond ? gl_NumWorkGroups.x : gl_NumWorkGroups.y
+ //
+ // does not have a precision as the built-in does not specify a precision.
+ //
+ // Precision is not applicable to HLSL so fixing these issues are deferred.
+ mValidateASTOptions.validatePrecision = false;
+
+ const ShBuiltInResources &resources = getResources();
+ int numRenderTargets = resources.EXT_draw_buffers ? resources.MaxDrawBuffers : 1;
+ int maxDualSourceDrawBuffers =
+ resources.EXT_blend_func_extended ? resources.MaxDualSourceDrawBuffers : 0;
+
+ if (!sh::AddDefaultReturnStatements(this, root))
+ {
+ return false;
+ }
+
+ // 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.
+ // Note that SeparateDeclarations has already been run in TCompiler::compileTreeImpl().
+ if (!SimplifyLoopConditions(
+ this, root,
+ IntermNodePatternMatcher::kExpressionReturningArray |
+ IntermNodePatternMatcher::kUnfoldedShortCircuitExpression |
+ IntermNodePatternMatcher::kDynamicIndexingOfVectorOrMatrixInLValue,
+ &getSymbolTable()))
+ {
+ return false;
+ }
+
+ if (!SplitSequenceOperator(
+ this, root,
+ IntermNodePatternMatcher::kExpressionReturningArray |
+ IntermNodePatternMatcher::kUnfoldedShortCircuitExpression |
+ IntermNodePatternMatcher::kDynamicIndexingOfVectorOrMatrixInLValue,
+ &getSymbolTable()))
+ {
+ return false;
+ }
+
+ // Note that SeparateDeclarations needs to be run before UnfoldShortCircuitToIf.
+ if (!UnfoldShortCircuitToIf(this, root, &getSymbolTable()))
+ {
+ return false;
+ }
+
+ if (!SeparateArrayConstructorStatements(this, root))
+ {
+ return false;
+ }
+
+ if (getShaderVersion() >= 310)
+ {
+ // Do element-by-element assignments of arrays in SSBOs. This allows the D3D backend to use
+ // RWByteAddressBuffer.Load() and .Store(), which only operate on values up to 16 bytes in
+ // size. Note that this must be done before SeparateExpressionsReturningArrays.
+ if (!sh::AggregateAssignArraysInSSBOs(this, root, &getSymbolTable()))
+ {
+ return false;
+ }
+ // Do field-by-field assignment of structs in SSBOs. This allows the D3D backend to use
+ // RWByteAddressBuffer.Load() and .Store(), which only operate on values up to 16 bytes in
+ // size.
+ if (!sh::AggregateAssignStructsInSSBOs(this, root, &getSymbolTable()))
+ {
+ return false;
+ }
+ }
+
+ if (!SeparateExpressionsReturningArrays(this, root, &getSymbolTable()))
+ {
+ return false;
+ }
+
+ // Note that SeparateDeclarations needs to be run before SeparateArrayInitialization.
+ if (!SeparateArrayInitialization(this, root))
+ {
+ return false;
+ }
+
+ // HLSL doesn't support arrays as return values, we'll need to make functions that have an array
+ // as a return value to use an out parameter to transfer the array data instead.
+ if (!ArrayReturnValueToOutParameter(this, root, &getSymbolTable()))
+ {
+ return false;
+ }
+
+ if (!shouldRunLoopAndIndexingValidation(compileOptions))
+ {
+ // HLSL doesn't support dynamic indexing of vectors and matrices.
+ if (!RemoveDynamicIndexingOfNonSSBOVectorOrMatrix(this, root, &getSymbolTable(),
+ perfDiagnostics))
+ {
+ return false;
+ }
+ }
+
+ // Work around D3D9 bug that would manifest in vertex shaders with selection blocks which
+ // use a vertex attribute as a condition, and some related computation in the else block.
+ if (getOutputType() == SH_HLSL_3_0_OUTPUT && getShaderType() == GL_VERTEX_SHADER)
+ {
+ if (!sh::RewriteElseBlocks(this, root, &getSymbolTable()))
+ {
+ return false;
+ }
+ }
+
+ // 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.
+ if (!sh::BreakVariableAliasingInInnerLoops(this, root))
+ {
+ return false;
+ }
+
+ // WrapSwitchStatementsInBlocks should be called after any AST transformations that might
+ // introduce variable declarations inside the main scope of any switch statement. It cannot
+ // result in no-op cases at the end of switch statements, because unreferenced variables
+ // have already been pruned.
+ if (!WrapSwitchStatementsInBlocks(this, root))
+ {
+ return false;
+ }
+
+ if (compileOptions.expandSelectHLSLIntegerPowExpressions)
+ {
+ if (!sh::ExpandIntegerPowExpressions(this, root, &getSymbolTable()))
+ {
+ return false;
+ }
+ }
+
+ if (compileOptions.rewriteTexelFetchOffsetToTexelFetch)
+ {
+ if (!sh::RewriteTexelFetchOffset(this, root, getSymbolTable(), getShaderVersion()))
+ {
+ return false;
+ }
+ }
+
+ if (compileOptions.rewriteIntegerUnaryMinusOperator && getShaderType() == GL_VERTEX_SHADER)
+ {
+ if (!sh::RewriteUnaryMinusOperatorInt(this, root))
+ {
+ return false;
+ }
+ }
+
+ if (getShaderVersion() >= 310)
+ {
+ // Due to ssbo also can be used as the argument of atomic memory functions, we should put
+ // RewriteExpressionsWithShaderStorageBlock before RewriteAtomicFunctionExpressions.
+ if (!sh::RewriteExpressionsWithShaderStorageBlock(this, root, &getSymbolTable()))
+ {
+ return false;
+ }
+ if (!sh::RewriteAtomicFunctionExpressions(this, root, &getSymbolTable(),
+ getShaderVersion()))
+ {
+ return false;
+ }
+ }
+
+ mUniformBlockOptimizedMap.clear();
+ mSlowCompilingUniformBlockSet.clear();
+ // In order to get the exact maximum of slots are available for shader resources, which would
+ // been bound with StructuredBuffer, we only translate uniform block with a large array member
+ // into StructuredBuffer when shader version is 300.
+ if (getShaderVersion() == 300 && compileOptions.allowTranslateUniformBlockToStructuredBuffer)
+ {
+ if (!sh::RecordUniformBlocksWithLargeArrayMember(root, mUniformBlockOptimizedMap,
+ mSlowCompilingUniformBlockSet))
+ {
+ return false;
+ }
+ }
+
+ sh::OutputHLSL outputHLSL(
+ getShaderType(), getShaderSpec(), getShaderVersion(), getExtensionBehavior(),
+ getSourcePath(), getOutputType(), numRenderTargets, maxDualSourceDrawBuffers, getUniforms(),
+ compileOptions, getComputeShaderLocalSize(), &getSymbolTable(), perfDiagnostics,
+ mUniformBlockOptimizedMap, mShaderStorageBlocks, isEarlyFragmentTestsSpecified());
+
+ outputHLSL.output(root, getInfoSink().obj);
+
+ mShaderStorageBlockRegisterMap = outputHLSL.getShaderStorageBlockRegisterMap();
+ mUniformBlockRegisterMap = outputHLSL.getUniformBlockRegisterMap();
+ mUniformBlockUseStructuredBufferMap = outputHLSL.getUniformBlockUseStructuredBufferMap();
+ mUniformRegisterMap = outputHLSL.getUniformRegisterMap();
+ mReadonlyImage2DRegisterIndex = outputHLSL.getReadonlyImage2DRegisterIndex();
+ mImage2DRegisterIndex = outputHLSL.getImage2DRegisterIndex();
+ mUsedImage2DFunctionNames = outputHLSL.getUsedImage2DFunctionNames();
+
+ return true;
+}
+
+bool TranslatorHLSL::shouldFlattenPragmaStdglInvariantAll()
+{
+ // Not necessary when translating to HLSL.
+ return false;
+}
+
+bool TranslatorHLSL::hasShaderStorageBlock(const std::string &uniformBlockName) const
+{
+ return (mShaderStorageBlockRegisterMap.count(uniformBlockName) > 0);
+}
+
+unsigned int TranslatorHLSL::getShaderStorageBlockRegister(
+ const std::string &shaderStorageBlockName) const
+{
+ ASSERT(hasShaderStorageBlock(shaderStorageBlockName));
+ return mShaderStorageBlockRegisterMap.find(shaderStorageBlockName)->second;
+}
+
+bool TranslatorHLSL::hasUniformBlock(const std::string &uniformBlockName) const
+{
+ return (mUniformBlockRegisterMap.count(uniformBlockName) > 0);
+}
+
+unsigned int TranslatorHLSL::getUniformBlockRegister(const std::string &uniformBlockName) const
+{
+ ASSERT(hasUniformBlock(uniformBlockName));
+ return mUniformBlockRegisterMap.find(uniformBlockName)->second;
+}
+
+const std::map<std::string, unsigned int> *TranslatorHLSL::getUniformRegisterMap() const
+{
+ return &mUniformRegisterMap;
+}
+
+const std::set<std::string> *TranslatorHLSL::getSlowCompilingUniformBlockSet() const
+{
+ return &mSlowCompilingUniformBlockSet;
+}
+
+unsigned int TranslatorHLSL::getReadonlyImage2DRegisterIndex() const
+{
+ return mReadonlyImage2DRegisterIndex;
+}
+
+unsigned int TranslatorHLSL::getImage2DRegisterIndex() const
+{
+ return mImage2DRegisterIndex;
+}
+
+const std::set<std::string> *TranslatorHLSL::getUsedImage2DFunctionNames() const
+{
+ return &mUsedImage2DFunctionNames;
+}
+
+bool TranslatorHLSL::shouldUniformBlockUseStructuredBuffer(
+ const std::string &uniformBlockName) const
+{
+ auto uniformBlockIter = mUniformBlockUseStructuredBufferMap.find(uniformBlockName);
+ return uniformBlockIter != mUniformBlockUseStructuredBufferMap.end() &&
+ uniformBlockIter->second;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/TranslatorHLSL.h b/gfx/angle/checkout/src/compiler/translator/TranslatorHLSL.h
new file mode 100644
index 0000000000..309176bed8
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/TranslatorHLSL.h
@@ -0,0 +1,56 @@
+//
+// Copyright 2002 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_TRANSLATORHLSL_H_
+#define COMPILER_TRANSLATOR_TRANSLATORHLSL_H_
+
+#include "compiler/translator/Compiler.h"
+
+namespace sh
+{
+
+class TranslatorHLSL : public TCompiler
+{
+ public:
+ TranslatorHLSL(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output);
+ TranslatorHLSL *getAsTranslatorHLSL() override { return this; }
+
+ bool hasShaderStorageBlock(const std::string &interfaceBlockName) const;
+ unsigned int getShaderStorageBlockRegister(const std::string &interfaceBlockName) const;
+
+ bool hasUniformBlock(const std::string &interfaceBlockName) const;
+ unsigned int getUniformBlockRegister(const std::string &interfaceBlockName) const;
+ bool shouldUniformBlockUseStructuredBuffer(const std::string &uniformBlockName) const;
+ const std::set<std::string> *getSlowCompilingUniformBlockSet() const;
+
+ const std::map<std::string, unsigned int> *getUniformRegisterMap() const;
+ unsigned int getReadonlyImage2DRegisterIndex() const;
+ unsigned int getImage2DRegisterIndex() const;
+ const std::set<std::string> *getUsedImage2DFunctionNames() const;
+
+ protected:
+ [[nodiscard]] bool translate(TIntermBlock *root,
+ const ShCompileOptions &compileOptions,
+ PerformanceDiagnostics *perfDiagnostics) override;
+ bool shouldFlattenPragmaStdglInvariantAll() override;
+
+ // collectVariables needs to be run always so registers can be assigned.
+ bool shouldCollectVariables(const ShCompileOptions &compileOptions) override { return true; }
+
+ std::map<std::string, unsigned int> mShaderStorageBlockRegisterMap;
+ std::map<std::string, unsigned int> mUniformBlockRegisterMap;
+ std::map<std::string, bool> mUniformBlockUseStructuredBufferMap;
+ std::map<std::string, unsigned int> mUniformRegisterMap;
+ unsigned int mReadonlyImage2DRegisterIndex;
+ unsigned int mImage2DRegisterIndex;
+ std::set<std::string> mUsedImage2DFunctionNames;
+ std::map<int, const TInterfaceBlock *> mUniformBlockOptimizedMap;
+ std::set<std::string> mSlowCompilingUniformBlockSet;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TRANSLATORHLSL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/TranslatorMetal.h b/gfx/angle/checkout/src/compiler/translator/TranslatorMetal.h
new file mode 100644
index 0000000000..32b7564f34
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/TranslatorMetal.h
@@ -0,0 +1,62 @@
+//
+// Copyright 2019 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.
+//
+// TranslatorMetal:
+// A GLSL-based translator that outputs shaders that fit GL_KHR_vulkan_glsl.
+// It takes into account some considerations for Metal backend also.
+// The shaders are then fed into glslang to spit out SPIR-V.
+// See: https://www.khronos.org/registry/vulkan/specs/misc/GL_KHR_vulkan_glsl.txt
+//
+// The SPIR-V will then be translated to Metal Shading Language later in Metal backend.
+//
+
+#ifndef LIBANGLE_RENDERER_METAL_TRANSLATORMETAL_H_
+#define LIBANGLE_RENDERER_METAL_TRANSLATORMETAL_H_
+
+#include "compiler/translator/DriverUniformMetal.h"
+#include "compiler/translator/TranslatorVulkan.h"
+#include "compiler/translator/tree_util/DriverUniform.h"
+#include "compiler/translator/tree_util/SpecializationConstant.h"
+
+namespace sh
+{
+
+// TODO: http://anglebug.com/5339 Implement it using actual specialization constant. For now we are
+// redirecting to driver uniforms
+class SpecConstMetal : public SpecConst
+{
+ public:
+ SpecConstMetal(TSymbolTable *symbolTable,
+ const ShCompileOptions &compileOptions,
+ GLenum shaderType)
+ : SpecConst(symbolTable, compileOptions, shaderType)
+ {}
+ ~SpecConstMetal() override {}
+
+ private:
+};
+
+class TranslatorMetal : public TranslatorVulkan
+{
+ public:
+ TranslatorMetal(sh::GLenum type, ShShaderSpec spec);
+
+ protected:
+ [[nodiscard]] bool translate(TIntermBlock *root,
+ const ShCompileOptions &compileOptions,
+ PerformanceDiagnostics *perfDiagnostics) override;
+
+ [[nodiscard]] bool transformDepthBeforeCorrection(TIntermBlock *root,
+ const DriverUniform *driverUniforms) override;
+
+ [[nodiscard]] bool insertSampleMaskWritingLogic(TInfoSinkBase &sink,
+ TIntermBlock *root,
+ const DriverUniformMetal *driverUniforms);
+ [[nodiscard]] bool insertRasterizerDiscardLogic(TInfoSinkBase &sink, TIntermBlock *root);
+};
+
+} // namespace sh
+
+#endif /* LIBANGLE_RENDERER_METAL_TRANSLATORMETAL_H_ */
diff --git a/gfx/angle/checkout/src/compiler/translator/TranslatorMetalDirect.h b/gfx/angle/checkout/src/compiler/translator/TranslatorMetalDirect.h
new file mode 100644
index 0000000000..679687df07
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/TranslatorMetalDirect.h
@@ -0,0 +1,195 @@
+//
+// Copyright 2020 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_TRANSLATORMETALDIRECT_H_
+#define COMPILER_TRANSLATOR_TRANSLATORMETALDIRECT_H_
+
+#include "compiler/translator/Compiler.h"
+
+namespace sh
+{
+
+constexpr const char kUniformsVar[] = "angleUniforms";
+constexpr const char kUnassignedAttributeString[] = " __unassigned_attribute__";
+
+class DriverUniform;
+class DriverUniformMetal;
+class SpecConst;
+class TOutputMSL;
+class TranslatorMetalReflection;
+typedef std::unordered_map<size_t, std::string> originalNamesMap;
+typedef std::unordered_map<std::string, size_t> samplerBindingMap;
+typedef std::unordered_map<std::string, size_t> textureBindingMap;
+typedef std::unordered_map<std::string, size_t> userUniformBufferBindingMap;
+typedef std::pair<size_t, size_t> uboBindingInfo;
+struct UBOBindingInfo
+{
+ size_t bindIndex = 0;
+ size_t arraySize = 0;
+};
+typedef std::unordered_map<std::string, UBOBindingInfo> uniformBufferBindingMap;
+
+namespace mtl
+{
+TranslatorMetalReflection *getTranslatorMetalReflection(const TCompiler *compiler);
+}
+
+class TranslatorMetalReflection
+{
+ public:
+ TranslatorMetalReflection() : hasUBOs(false), hasFlatInput(false) {}
+ ~TranslatorMetalReflection() {}
+
+ void addOriginalName(const size_t id, const std::string &name)
+ {
+ originalNames.insert({id, name});
+ }
+ void addSamplerBinding(const std::string &name, size_t samplerBinding)
+ {
+ samplerBindings.insert({name, samplerBinding});
+ }
+ void addTextureBinding(const std::string &name, size_t textureBinding)
+ {
+ textureBindings.insert({name, textureBinding});
+ }
+ void addUserUniformBufferBinding(const std::string &name, size_t userUniformBufferBinding)
+ {
+ userUniformBufferBindings.insert({name, userUniformBufferBinding});
+ }
+ void addUniformBufferBinding(const std::string &name, UBOBindingInfo bindingInfo)
+ {
+ uniformBufferBindings.insert({name, bindingInfo});
+ }
+ std::string getOriginalName(const size_t id) { return originalNames.at(id); }
+ samplerBindingMap getSamplerBindings() const { return samplerBindings; }
+ textureBindingMap getTextureBindings() const { return textureBindings; }
+ userUniformBufferBindingMap getUserUniformBufferBindings() const
+ {
+ return userUniformBufferBindings;
+ }
+ uniformBufferBindingMap getUniformBufferBindings() const { return uniformBufferBindings; }
+ size_t getSamplerBinding(const std::string &name) const
+ {
+ auto it = samplerBindings.find(name);
+ if (it != samplerBindings.end())
+ {
+ return it->second;
+ }
+ // If we can't find a matching sampler, assert out on Debug, and return an invalid value on
+ // release.
+ ASSERT(0);
+ return std::numeric_limits<size_t>::max();
+ }
+ size_t getTextureBinding(const std::string &name) const
+ {
+ auto it = textureBindings.find(name);
+ if (it != textureBindings.end())
+ {
+ return it->second;
+ }
+ // If we can't find a matching texture, assert out on Debug, and return an invalid value on
+ // release.
+ ASSERT(0);
+ return std::numeric_limits<size_t>::max();
+ }
+ size_t getUserUniformBufferBinding(const std::string &name) const
+ {
+ auto it = userUniformBufferBindings.find(name);
+ if (it != userUniformBufferBindings.end())
+ {
+ return it->second;
+ }
+ // If we can't find a matching Uniform binding, assert out on Debug, and return an invalid
+ // value.
+ ASSERT(0);
+ return std::numeric_limits<size_t>::max();
+ }
+ UBOBindingInfo getUniformBufferBinding(const std::string &name) const
+ {
+ auto it = uniformBufferBindings.find(name);
+ if (it != uniformBufferBindings.end())
+ {
+ return it->second;
+ }
+ // If we can't find a matching UBO binding by name, assert out on Debug, and return an
+ // invalid value.
+ ASSERT(0);
+ return {.bindIndex = std::numeric_limits<size_t>::max(),
+ .arraySize = std::numeric_limits<size_t>::max()};
+ }
+ void reset()
+ {
+ hasUBOs = false;
+ hasFlatInput = false;
+ hasAtan = false;
+ hasInvariance = false;
+ originalNames.clear();
+ samplerBindings.clear();
+ textureBindings.clear();
+ userUniformBufferBindings.clear();
+ uniformBufferBindings.clear();
+ }
+
+ bool hasUBOs = false;
+ bool hasFlatInput = false;
+ bool hasAtan = false;
+ bool hasInvariance = false;
+
+ private:
+ originalNamesMap originalNames;
+ samplerBindingMap samplerBindings;
+ textureBindingMap textureBindings;
+ userUniformBufferBindingMap userUniformBufferBindings;
+ uniformBufferBindingMap uniformBufferBindings;
+};
+
+class TranslatorMetalDirect : public TCompiler
+{
+ public:
+ TranslatorMetalDirect(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output);
+
+#ifdef ANGLE_ENABLE_METAL
+ TranslatorMetalDirect *getAsTranslatorMetalDirect() override { return this; }
+#endif
+
+ TranslatorMetalReflection *getTranslatorMetalReflection() { return &translatorMetalReflection; }
+
+ protected:
+ bool translate(TIntermBlock *root,
+ const ShCompileOptions &compileOptions,
+ PerformanceDiagnostics *perfDiagnostics) override;
+
+ // The sample mask can't be in our fragment output struct if we read the framebuffer. Luckily,
+ // pixel local storage bans gl_SampleMask, so we can just not use it when PLS is active.
+ bool usesSampleMask() const { return !hasPixelLocalStorageUniforms(); }
+
+ // Need to collect variables so that RemoveInactiveInterfaceVariables works.
+ bool shouldCollectVariables(const ShCompileOptions &compileOptions) override { return true; }
+
+ [[nodiscard]] bool translateImpl(TInfoSinkBase &sink,
+ TIntermBlock *root,
+ const ShCompileOptions &compileOptions,
+ PerformanceDiagnostics *perfDiagnostics,
+ SpecConst *specConst,
+ DriverUniformMetal *driverUniforms);
+
+ [[nodiscard]] bool shouldFlattenPragmaStdglInvariantAll() override;
+
+ [[nodiscard]] bool transformDepthBeforeCorrection(TIntermBlock *root,
+ const DriverUniformMetal *driverUniforms);
+
+ [[nodiscard]] bool appendVertexShaderDepthCorrectionToMain(TIntermBlock *root);
+
+ [[nodiscard]] bool insertSampleMaskWritingLogic(TIntermBlock &root,
+ DriverUniformMetal &driverUniforms);
+ [[nodiscard]] bool insertRasterizationDiscardLogic(TIntermBlock &root);
+
+ TranslatorMetalReflection translatorMetalReflection = {};
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TRANSLATORMETALDIRECT_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/TranslatorVulkan.h b/gfx/angle/checkout/src/compiler/translator/TranslatorVulkan.h
new file mode 100644
index 0000000000..db80f499e8
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/TranslatorVulkan.h
@@ -0,0 +1,60 @@
+//
+// 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.
+//
+// TranslatorVulkan:
+// A GLSL-based translator that outputs shaders that fit GL_KHR_vulkan_glsl and feeds them into
+// glslang to spit out SPIR-V.
+// See: https://www.khronos.org/registry/vulkan/specs/misc/GL_KHR_vulkan_glsl.txt
+//
+
+#ifndef COMPILER_TRANSLATOR_TRANSLATORVULKAN_H_
+#define COMPILER_TRANSLATOR_TRANSLATORVULKAN_H_
+
+#include "compiler/translator/Compiler.h"
+
+namespace sh
+{
+
+class TOutputVulkanGLSL;
+class SpecConst;
+class DriverUniform;
+
+class TranslatorVulkan : public TCompiler
+{
+ public:
+ TranslatorVulkan(sh::GLenum type, ShShaderSpec spec);
+
+ protected:
+ [[nodiscard]] bool translate(TIntermBlock *root,
+ const ShCompileOptions &compileOptions,
+ PerformanceDiagnostics *perfDiagnostics) override;
+ bool shouldFlattenPragmaStdglInvariantAll() override;
+
+ // Subclass can call this method to transform the AST before writing the final output.
+ // See TranslatorMetal.cpp.
+ [[nodiscard]] bool translateImpl(TInfoSinkBase &sink,
+ TIntermBlock *root,
+ const ShCompileOptions &compileOptions,
+ PerformanceDiagnostics *perfDiagnostics,
+ SpecConst *specConst,
+ DriverUniform *driverUniforms);
+
+ void writeExtensionBehavior(const ShCompileOptions &compileOptions, TInfoSinkBase &sink);
+
+ // Give subclass such as TranslatorMetal a chance to do depth transform before
+ // TranslatorVulkan apply its own transform.
+ [[nodiscard]] virtual bool transformDepthBeforeCorrection(TIntermBlock *root,
+ const DriverUniform *driverUniforms)
+ {
+ return true;
+ }
+
+ // Generate SPIR-V out of intermediate GLSL through glslang.
+ [[nodiscard]] bool compileToSpirv(const TInfoSinkBase &glsl);
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TRANSLATORVULKAN_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/Types.cpp b/gfx/angle/checkout/src/compiler/translator/Types.cpp
new file mode 100644
index 0000000000..c1d57fdaef
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/Types.cpp
@@ -0,0 +1,984 @@
+//
+// Copyright 2002 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.
+//
+
+#if defined(_MSC_VER)
+# pragma warning(disable : 4718)
+#endif
+
+#include "compiler/translator/Types.h"
+#include "compiler/translator/ImmutableString.h"
+#include "compiler/translator/InfoSink.h"
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/SymbolTable.h"
+
+#include <algorithm>
+#include <climits>
+
+namespace sh
+{
+
+const char *getBasicString(TBasicType t)
+{
+ switch (t)
+ {
+ case EbtVoid:
+ return "void";
+ case EbtFloat:
+ return "float";
+ case EbtInt:
+ return "int";
+ case EbtUInt:
+ return "uint";
+ case EbtBool:
+ return "bool";
+ case EbtYuvCscStandardEXT:
+ return "yuvCscStandardEXT";
+ case EbtSampler2D:
+ return "sampler2D";
+ case EbtSampler3D:
+ return "sampler3D";
+ case EbtSamplerCube:
+ return "samplerCube";
+ case EbtSamplerExternalOES:
+ return "samplerExternalOES";
+ case EbtSamplerExternal2DY2YEXT:
+ return "__samplerExternal2DY2YEXT";
+ case EbtSampler2DRect:
+ return "sampler2DRect";
+ case EbtSampler2DArray:
+ return "sampler2DArray";
+ case EbtSampler2DMS:
+ return "sampler2DMS";
+ case EbtSampler2DMSArray:
+ return "sampler2DMSArray";
+ case EbtSamplerCubeArray:
+ return "samplerCubeArray";
+ case EbtSamplerBuffer:
+ return "samplerBuffer";
+ case EbtISampler2D:
+ return "isampler2D";
+ case EbtISampler3D:
+ return "isampler3D";
+ case EbtISamplerCube:
+ return "isamplerCube";
+ case EbtISampler2DArray:
+ return "isampler2DArray";
+ case EbtISampler2DMS:
+ return "isampler2DMS";
+ case EbtISampler2DMSArray:
+ return "isampler2DMSArray";
+ case EbtISamplerCubeArray:
+ return "isamplerCubeArray";
+ case EbtISamplerBuffer:
+ return "isamplerBuffer";
+ case EbtUSampler2D:
+ return "usampler2D";
+ case EbtUSampler3D:
+ return "usampler3D";
+ case EbtUSamplerCube:
+ return "usamplerCube";
+ case EbtUSampler2DArray:
+ return "usampler2DArray";
+ case EbtUSampler2DMS:
+ return "usampler2DMS";
+ case EbtUSampler2DMSArray:
+ return "usampler2DMSArray";
+ case EbtUSamplerCubeArray:
+ return "usamplerCubeArray";
+ case EbtUSamplerBuffer:
+ return "usamplerBuffer";
+ case EbtSampler2DShadow:
+ return "sampler2DShadow";
+ case EbtSamplerCubeShadow:
+ return "samplerCubeShadow";
+ case EbtSampler2DArrayShadow:
+ return "sampler2DArrayShadow";
+ case EbtSamplerCubeArrayShadow:
+ return "samplerCubeArrayShadow";
+ case EbtStruct:
+ return "structure";
+ case EbtInterfaceBlock:
+ return "interface block";
+ case EbtImage2D:
+ return "image2D";
+ case EbtIImage2D:
+ return "iimage2D";
+ case EbtUImage2D:
+ return "uimage2D";
+ case EbtImage3D:
+ return "image3D";
+ case EbtIImage3D:
+ return "iimage3D";
+ case EbtUImage3D:
+ return "uimage3D";
+ case EbtImage2DArray:
+ return "image2DArray";
+ case EbtIImage2DArray:
+ return "iimage2DArray";
+ case EbtUImage2DArray:
+ return "uimage2DArray";
+ case EbtImageCube:
+ return "imageCube";
+ case EbtIImageCube:
+ return "iimageCube";
+ case EbtUImageCube:
+ return "uimageCube";
+ case EbtImageCubeArray:
+ return "imageCubeArray";
+ case EbtIImageCubeArray:
+ return "iimageCubeArray";
+ case EbtUImageCubeArray:
+ return "uimageCubeArray";
+ case EbtImageBuffer:
+ return "imageBuffer";
+ case EbtIImageBuffer:
+ return "iimageBuffer";
+ case EbtUImageBuffer:
+ return "uimageBuffer";
+ case EbtAtomicCounter:
+ return "atomic_uint";
+ case EbtSamplerVideoWEBGL:
+ return "samplerVideoWEBGL";
+ case EbtPixelLocalANGLE:
+ return "pixelLocalANGLE";
+ case EbtIPixelLocalANGLE:
+ return "ipixelLocalANGLE";
+ case EbtUPixelLocalANGLE:
+ return "upixelLocalANGLE";
+ case EbtSubpassInput:
+ return "subpassInput";
+ case EbtISubpassInput:
+ return "isubpassInput";
+ case EbtUSubpassInput:
+ return "usubpassInput";
+ case EbtSubpassInputMS:
+ return "subpassInputMS";
+ case EbtISubpassInputMS:
+ return "isubpassInputMS";
+ case EbtUSubpassInputMS:
+ return "usubpassInputMS";
+ default:
+ UNREACHABLE();
+ return "unknown type";
+ }
+}
+
+// TType implementation.
+TType::TType() : TType(EbtVoid, 0, 0) {}
+
+TType::TType(TBasicType t, uint8_t ps, uint8_t ss) : TType(t, EbpUndefined, EvqGlobal, ps, ss) {}
+
+TType::TType(TBasicType t, TPrecision p, TQualifier q, uint8_t ps, uint8_t ss)
+ : TType(t, p, q, ps, ss, TSpan<const unsigned int>(), nullptr)
+{}
+
+TType::TType(const TPublicType &p)
+ : type(p.getBasicType()),
+ precision(p.precision),
+ qualifier(p.qualifier),
+ invariant(p.invariant),
+ precise(p.precise),
+ memoryQualifier(p.memoryQualifier),
+ layoutQualifier(p.layoutQualifier),
+ primarySize(p.getPrimarySize()),
+ secondarySize(p.getSecondarySize()),
+ mArraySizesStorage(nullptr),
+ mInterfaceBlock(nullptr),
+ mStructure(nullptr),
+ mIsStructSpecifier(false),
+ mInterfaceBlockFieldIndex(0),
+ mMangledName(nullptr)
+{
+ ASSERT(primarySize <= 4);
+ ASSERT(secondarySize <= 4);
+ if (p.isArray())
+ {
+ makeArrays(*p.arraySizes);
+ }
+ if (p.getUserDef())
+ {
+ mStructure = p.getUserDef();
+ mIsStructSpecifier = p.isStructSpecifier();
+ }
+}
+
+TType::TType(const TStructure *userDef, bool isStructSpecifier)
+ : TType(EbtStruct, EbpUndefined, EvqTemporary, 1, 1)
+{
+ mStructure = userDef;
+ mIsStructSpecifier = isStructSpecifier;
+}
+
+TType::TType(const TInterfaceBlock *interfaceBlockIn,
+ TQualifier qualifierIn,
+ TLayoutQualifier layoutQualifierIn)
+ : TType(EbtInterfaceBlock, EbpUndefined, qualifierIn, 1, 1)
+{
+ layoutQualifier = layoutQualifierIn;
+ mInterfaceBlock = interfaceBlockIn;
+}
+
+TType::TType(const TType &t)
+{
+ *this = t;
+}
+
+TType &TType::operator=(const TType &t)
+{
+ type = t.type;
+ precision = t.precision;
+ qualifier = t.qualifier;
+ invariant = t.invariant;
+ precise = t.precise;
+ memoryQualifier = t.memoryQualifier;
+ layoutQualifier = t.layoutQualifier;
+ primarySize = t.primarySize;
+ secondarySize = t.secondarySize;
+ mArraySizesStorage = nullptr;
+ mInterfaceBlock = t.mInterfaceBlock;
+ mStructure = t.mStructure;
+ mIsStructSpecifier = t.mIsStructSpecifier;
+ mInterfaceBlockFieldIndex = t.mInterfaceBlockFieldIndex;
+ mMangledName = t.mMangledName;
+
+ if (t.mArraySizesStorage)
+ {
+ // If other type has storage, duplicate the storage and set the view to our own storage.
+ mArraySizesStorage = new TVector<unsigned int>(*t.mArraySizesStorage);
+ mArraySizes = *mArraySizesStorage;
+ }
+ else
+ {
+ // Otherwise reference the same (constexpr) array sizes as the other type.
+ mArraySizes = t.mArraySizes;
+ }
+
+ return *this;
+}
+
+bool TType::canBeConstructed() const
+{
+ switch (type)
+ {
+ case EbtFloat:
+ case EbtInt:
+ case EbtUInt:
+ case EbtBool:
+ case EbtStruct:
+ return true;
+ default:
+ return false;
+ }
+}
+
+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();
+}
+
+int TType::getDeepestStructNesting() const
+{
+ return mStructure ? mStructure->deepestNesting() : 0;
+}
+
+bool TType::isNamelessStruct() const
+{
+ return mStructure && mStructure->symbolType() == SymbolType::Empty;
+}
+
+bool TType::isStructureContainingArrays() const
+{
+ return mStructure ? mStructure->containsArrays() : false;
+}
+
+bool TType::isStructureContainingMatrices() const
+{
+ return mStructure ? mStructure->containsMatrices() : false;
+}
+
+bool TType::isStructureContainingType(TBasicType t) const
+{
+ return mStructure ? mStructure->containsType(t) : false;
+}
+
+bool TType::isStructureContainingSamplers() const
+{
+ return mStructure ? mStructure->containsSamplers() : false;
+}
+
+bool TType::isInterfaceBlockContainingType(TBasicType t) const
+{
+ return isInterfaceBlock() ? mInterfaceBlock->containsType(t) : false;
+}
+
+bool TType::canReplaceWithConstantUnion() const
+{
+ if (isArray())
+ {
+ return false;
+ }
+ if (!mStructure)
+ {
+ return true;
+ }
+ if (isStructureContainingArrays())
+ {
+ return false;
+ }
+ if (getObjectSize() > 16)
+ {
+ return false;
+ }
+ return true;
+}
+
+//
+// Recursively generate mangled names.
+//
+const char *TType::buildMangledName() const
+{
+ TString mangledName(1, GetSizeMangledName(primarySize, secondarySize));
+
+ TBasicMangledName typeName(type);
+ char *basicMangledName = typeName.getName();
+ static_assert(TBasicMangledName::mangledNameSize == 2, "Mangled name size is not 2");
+ if (basicMangledName[0] != '{')
+ {
+ mangledName += basicMangledName[0];
+ mangledName += basicMangledName[1];
+ }
+ else
+ {
+ ASSERT(type == EbtStruct || type == EbtInterfaceBlock);
+ switch (type)
+ {
+ case EbtStruct:
+ mangledName += "{s";
+ if (mStructure->symbolType() != SymbolType::Empty)
+ {
+ mangledName += mStructure->name().data();
+ }
+ mangledName += mStructure->mangledFieldList();
+ mangledName += '}';
+ break;
+ case EbtInterfaceBlock:
+ mangledName += "{i";
+ mangledName += mInterfaceBlock->name().data();
+ mangledName += mInterfaceBlock->mangledFieldList();
+ mangledName += '}';
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ }
+
+ for (unsigned int arraySize : mArraySizes)
+ {
+ char buf[20];
+ snprintf(buf, sizeof(buf), "%d", arraySize);
+ mangledName += 'x';
+ mangledName += buf;
+ }
+
+ // Copy string contents into a pool-allocated buffer, so we never need to call delete.
+ return AllocatePoolCharArray(mangledName.c_str(), mangledName.size());
+}
+
+size_t TType::getObjectSize() const
+{
+ size_t totalSize;
+
+ if (getBasicType() == EbtStruct)
+ totalSize = mStructure->objectSize();
+ else
+ totalSize = primarySize * secondarySize;
+
+ if (totalSize == 0)
+ return 0;
+
+ for (size_t arraySize : mArraySizes)
+ {
+ if (arraySize > INT_MAX / totalSize)
+ totalSize = INT_MAX;
+ else
+ totalSize *= arraySize;
+ }
+
+ return totalSize;
+}
+
+int TType::getLocationCount() const
+{
+ int count = 1;
+
+ if (getBasicType() == EbtStruct)
+ {
+ count = mStructure->getLocationCount();
+ }
+
+ if (count == 0)
+ {
+ return 0;
+ }
+
+ for (unsigned int arraySize : mArraySizes)
+ {
+ if (arraySize > static_cast<unsigned int>(std::numeric_limits<int>::max() / count))
+ {
+ count = std::numeric_limits<int>::max();
+ }
+ else
+ {
+ count *= static_cast<int>(arraySize);
+ }
+ }
+
+ return count;
+}
+
+unsigned int TType::getArraySizeProduct() const
+{
+ unsigned int product = 1u;
+
+ for (unsigned int arraySize : mArraySizes)
+ {
+ product *= arraySize;
+ }
+ return product;
+}
+
+bool TType::isUnsizedArray() const
+{
+ for (unsigned int arraySize : mArraySizes)
+ {
+ if (arraySize == 0u)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool TType::sameNonArrayType(const TType &right) const
+{
+ return (type == right.type && primarySize == right.primarySize &&
+ secondarySize == right.secondarySize && mStructure == right.mStructure);
+}
+
+bool TType::isElementTypeOf(const TType &arrayType) const
+{
+ if (!sameNonArrayType(arrayType))
+ {
+ return false;
+ }
+ if (arrayType.getNumArraySizes() != getNumArraySizes() + 1u)
+ {
+ return false;
+ }
+ for (size_t i = 0; i < mArraySizes.size(); ++i)
+ {
+ if (mArraySizes[i] != arrayType.mArraySizes[i])
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+void TType::sizeUnsizedArrays(const TSpan<const unsigned int> &newArraySizes)
+{
+ ASSERT(!isArray() || mArraySizesStorage != nullptr);
+ for (size_t i = 0u; i < getNumArraySizes(); ++i)
+ {
+ if (mArraySizes[i] == 0)
+ {
+ if (i < newArraySizes.size())
+ {
+ (*mArraySizesStorage)[i] = newArraySizes[i];
+ }
+ else
+ {
+ (*mArraySizesStorage)[i] = 1u;
+ }
+ }
+ }
+ invalidateMangledName();
+}
+
+void TType::sizeOutermostUnsizedArray(unsigned int arraySize)
+{
+ ASSERT(isArray() && mArraySizesStorage != nullptr);
+ ASSERT((*mArraySizesStorage).back() == 0u);
+ (*mArraySizesStorage).back() = arraySize;
+}
+
+void TType::setBasicType(TBasicType t)
+{
+ if (type != t)
+ {
+ type = t;
+ invalidateMangledName();
+ }
+}
+
+void TType::setPrimarySize(uint8_t ps)
+{
+ if (primarySize != ps)
+ {
+ ASSERT(ps <= 4);
+ primarySize = ps;
+ invalidateMangledName();
+ }
+}
+
+void TType::setSecondarySize(uint8_t ss)
+{
+ if (secondarySize != ss)
+ {
+ ASSERT(ss <= 4);
+ secondarySize = ss;
+ invalidateMangledName();
+ }
+}
+
+void TType::makeArray(unsigned int s)
+{
+ if (mArraySizesStorage == nullptr)
+ {
+ mArraySizesStorage = new TVector<unsigned int>();
+ }
+ // Add a dimension to the current ones.
+ mArraySizesStorage->push_back(s);
+ onArrayDimensionsChange(*mArraySizesStorage);
+}
+
+void TType::makeArrays(const TSpan<const unsigned int> &sizes)
+{
+ if (mArraySizesStorage == nullptr)
+ {
+ mArraySizesStorage = new TVector<unsigned int>();
+ }
+ // Add dimensions to the current ones.
+ mArraySizesStorage->insert(mArraySizesStorage->end(), sizes.begin(), sizes.end());
+ onArrayDimensionsChange(*mArraySizesStorage);
+}
+
+void TType::setArraySize(size_t arrayDimension, unsigned int s)
+{
+ ASSERT(isArray() && mArraySizesStorage != nullptr);
+ ASSERT(arrayDimension < mArraySizesStorage->size());
+ if (mArraySizes[arrayDimension] != s)
+ {
+ (*mArraySizesStorage)[arrayDimension] = s;
+ invalidateMangledName();
+ }
+}
+
+void TType::toArrayElementType()
+{
+ ASSERT(isArray() && mArraySizesStorage != nullptr);
+ mArraySizesStorage->pop_back();
+ onArrayDimensionsChange(*mArraySizesStorage);
+}
+
+void TType::toArrayBaseType()
+{
+ if (!isArray())
+ {
+ return;
+ }
+ if (mArraySizesStorage)
+ {
+ mArraySizesStorage->clear();
+ }
+ onArrayDimensionsChange(TSpan<const unsigned int>());
+}
+
+void TType::toMatrixColumnType()
+{
+ ASSERT(isMatrix());
+ primarySize = secondarySize;
+ secondarySize = 1;
+ invalidateMangledName();
+}
+
+void TType::toComponentType()
+{
+ primarySize = 1;
+ secondarySize = 1;
+ invalidateMangledName();
+}
+
+void TType::setInterfaceBlock(const TInterfaceBlock *interfaceBlockIn)
+{
+ if (mInterfaceBlock != interfaceBlockIn)
+ {
+ mInterfaceBlock = interfaceBlockIn;
+ invalidateMangledName();
+ }
+}
+
+void TType::setInterfaceBlockField(const TInterfaceBlock *interfaceBlockIn, size_t fieldIndex)
+{
+ setInterfaceBlock(interfaceBlockIn);
+ mInterfaceBlockFieldIndex = fieldIndex;
+}
+
+const char *TType::getMangledName() const
+{
+ if (mMangledName == nullptr)
+ {
+ mMangledName = buildMangledName();
+ }
+
+ return mMangledName;
+}
+
+void TType::realize()
+{
+ getMangledName();
+}
+
+void TType::createSamplerSymbols(const ImmutableString &namePrefix,
+ const TString &apiNamePrefix,
+ TVector<const TVariable *> *outputSymbols,
+ TMap<const TVariable *, TString> *outputSymbolsToAPINames,
+ TSymbolTable *symbolTable) const
+{
+ if (isStructureContainingSamplers())
+ {
+ if (isArray())
+ {
+ TType elementType(*this);
+ elementType.toArrayElementType();
+ for (unsigned int arrayIndex = 0u; arrayIndex < getOutermostArraySize(); ++arrayIndex)
+ {
+ std::stringstream elementName = sh::InitializeStream<std::stringstream>();
+ elementName << namePrefix << "_" << arrayIndex;
+ TStringStream elementApiName;
+ elementApiName << apiNamePrefix << "[" << arrayIndex << "]";
+ elementType.createSamplerSymbols(ImmutableString(elementName.str()),
+ elementApiName.str(), outputSymbols,
+ outputSymbolsToAPINames, symbolTable);
+ }
+ }
+ else
+ {
+ mStructure->createSamplerSymbols(namePrefix.data(), apiNamePrefix, outputSymbols,
+ outputSymbolsToAPINames, symbolTable);
+ }
+ return;
+ }
+
+ ASSERT(IsSampler(type));
+ TVariable *variable =
+ new TVariable(symbolTable, namePrefix, new TType(*this), SymbolType::AngleInternal);
+ outputSymbols->push_back(variable);
+ if (outputSymbolsToAPINames)
+ {
+ (*outputSymbolsToAPINames)[variable] = apiNamePrefix;
+ }
+}
+
+TFieldListCollection::TFieldListCollection(const TFieldList *fields)
+ : mFields(fields), mObjectSize(0), mDeepestNesting(0)
+{}
+
+bool TFieldListCollection::containsArrays() const
+{
+ for (const auto *field : *mFields)
+ {
+ const TType *fieldType = field->type();
+ if (fieldType->isArray() || fieldType->isStructureContainingArrays())
+ return true;
+ }
+ return false;
+}
+
+bool TFieldListCollection::containsMatrices() const
+{
+ for (const auto *field : *mFields)
+ {
+ const TType *fieldType = field->type();
+ if (fieldType->isMatrix() || fieldType->isStructureContainingMatrices())
+ return true;
+ }
+ return false;
+}
+
+bool TFieldListCollection::containsType(TBasicType type) const
+{
+ for (const auto *field : *mFields)
+ {
+ const TType *fieldType = field->type();
+ if (fieldType->getBasicType() == type || fieldType->isStructureContainingType(type))
+ return true;
+ }
+ return false;
+}
+
+bool TFieldListCollection::containsSamplers() const
+{
+ for (const auto *field : *mFields)
+ {
+ const TType *fieldType = field->type();
+ if (IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers())
+ return true;
+ }
+ return false;
+}
+
+TString TFieldListCollection::buildMangledFieldList() const
+{
+ TString mangledName;
+ for (const auto *field : *mFields)
+ {
+ mangledName += field->type()->getMangledName();
+ }
+ return mangledName;
+}
+
+size_t TFieldListCollection::calculateObjectSize() const
+{
+ size_t size = 0;
+ for (const TField *field : *mFields)
+ {
+ size_t fieldSize = field->type()->getObjectSize();
+ if (fieldSize > INT_MAX - size)
+ size = INT_MAX;
+ else
+ size += fieldSize;
+ }
+ return size;
+}
+
+size_t TFieldListCollection::objectSize() const
+{
+ if (mObjectSize == 0)
+ mObjectSize = calculateObjectSize();
+ return mObjectSize;
+}
+
+int TFieldListCollection::getLocationCount() const
+{
+ int count = 0;
+ for (const TField *field : *mFields)
+ {
+ int fieldCount = field->type()->getLocationCount();
+ if (fieldCount > std::numeric_limits<int>::max() - count)
+ {
+ count = std::numeric_limits<int>::max();
+ }
+ else
+ {
+ count += fieldCount;
+ }
+ }
+ return count;
+}
+
+int TFieldListCollection::deepestNesting() const
+{
+ if (mDeepestNesting == 0)
+ mDeepestNesting = calculateDeepestNesting();
+ return mDeepestNesting;
+}
+
+const TString &TFieldListCollection::mangledFieldList() const
+{
+ if (mMangledFieldList.empty())
+ mMangledFieldList = buildMangledFieldList();
+ return mMangledFieldList;
+}
+
+int TFieldListCollection::calculateDeepestNesting() const
+{
+ int maxNesting = 0;
+ for (size_t i = 0; i < mFields->size(); ++i)
+ maxNesting = std::max(maxNesting, (*mFields)[i]->type()->getDeepestStructNesting());
+ return 1 + maxNesting;
+}
+
+// TPublicType implementation.
+void TPublicType::initialize(const TTypeSpecifierNonArray &typeSpecifier, TQualifier q)
+{
+ typeSpecifierNonArray = typeSpecifier;
+ layoutQualifier = TLayoutQualifier::Create();
+ memoryQualifier = TMemoryQualifier::Create();
+ qualifier = q;
+ invariant = false;
+ precise = false;
+ precision = EbpUndefined;
+ arraySizes = nullptr;
+}
+
+void TPublicType::initializeBasicType(TBasicType basicType)
+{
+ typeSpecifierNonArray.type = basicType;
+ typeSpecifierNonArray.primarySize = 1;
+ typeSpecifierNonArray.secondarySize = 1;
+ layoutQualifier = TLayoutQualifier::Create();
+ memoryQualifier = TMemoryQualifier::Create();
+ qualifier = EvqTemporary;
+ invariant = false;
+ precise = false;
+ precision = EbpUndefined;
+ arraySizes = nullptr;
+}
+
+bool TPublicType::isStructureContainingArrays() const
+{
+ if (!typeSpecifierNonArray.userDef)
+ {
+ return false;
+ }
+
+ return typeSpecifierNonArray.userDef->containsArrays();
+}
+
+bool TPublicType::isStructureContainingType(TBasicType t) const
+{
+ if (!typeSpecifierNonArray.userDef)
+ {
+ return false;
+ }
+
+ return typeSpecifierNonArray.userDef->containsType(t);
+}
+
+void TPublicType::setArraySizes(TVector<unsigned int> *sizes)
+{
+ arraySizes = sizes;
+}
+
+bool TPublicType::isArray() const
+{
+ return arraySizes && !arraySizes->empty();
+}
+
+void TPublicType::clearArrayness()
+{
+ arraySizes = nullptr;
+}
+
+bool TPublicType::isAggregate() const
+{
+ return isArray() || typeSpecifierNonArray.isMatrix() || typeSpecifierNonArray.isVector();
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/Types.h b/gfx/angle/checkout/src/compiler/translator/Types.h
new file mode 100644
index 0000000000..623a3b335b
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/Types.h
@@ -0,0 +1,508 @@
+//
+// Copyright 2002 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_TYPES_H_
+#define COMPILER_TRANSLATOR_TYPES_H_
+
+#include "common/angleutils.h"
+#include "common/debug.h"
+
+#include "compiler/translator/BaseTypes.h"
+#include "compiler/translator/Common.h"
+#include "compiler/translator/ImmutableString.h"
+#include "compiler/translator/SymbolUniqueId.h"
+
+namespace sh
+{
+
+struct TPublicType;
+class TType;
+class TInterfaceBlock;
+class TStructure;
+class TSymbol;
+class TVariable;
+class TIntermSymbol;
+class TSymbolTable;
+
+class TField : angle::NonCopyable
+{
+ public:
+ POOL_ALLOCATOR_NEW_DELETE
+ TField(TType *type, const ImmutableString &name, const TSourceLoc &line, SymbolType symbolType)
+ : mType(type), mName(name), mLine(line), mSymbolType(symbolType)
+ {
+ ASSERT(mSymbolType != SymbolType::Empty);
+ }
+
+ // TODO(alokp): We should only return const type.
+ // Fix it by tweaking grammar.
+ TType *type() { return mType; }
+ const TType *type() const { return mType; }
+ const ImmutableString &name() const { return mName; }
+ const TSourceLoc &line() const { return mLine; }
+ SymbolType symbolType() const { return mSymbolType; }
+
+ private:
+ TType *mType;
+ const ImmutableString mName;
+ const TSourceLoc mLine;
+ const SymbolType mSymbolType;
+};
+
+typedef TVector<TField *> TFieldList;
+
+class TFieldListCollection : angle::NonCopyable
+{
+ public:
+ const TFieldList &fields() const { return *mFields; }
+
+ bool containsArrays() const;
+ bool containsMatrices() const;
+ bool containsType(TBasicType t) const;
+ bool containsSamplers() const;
+
+ size_t objectSize() const;
+ // How many locations the field list consumes as a uniform.
+ int getLocationCount() const;
+ int deepestNesting() const;
+ const TString &mangledFieldList() const;
+
+ protected:
+ TFieldListCollection(const TFieldList *fields);
+
+ const TFieldList *mFields;
+
+ private:
+ size_t calculateObjectSize() const;
+ int calculateDeepestNesting() const;
+ TString buildMangledFieldList() const;
+
+ mutable size_t mObjectSize;
+ mutable int mDeepestNesting;
+ mutable TString mMangledFieldList;
+};
+
+//
+// Base class for things that have a type.
+//
+class TType
+{
+ public:
+ POOL_ALLOCATOR_NEW_DELETE
+ TType();
+ explicit TType(TBasicType t, uint8_t ps = 1, uint8_t ss = 1);
+ TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, uint8_t ps = 1, uint8_t ss = 1);
+ explicit TType(const TPublicType &p);
+ TType(const TStructure *userDef, bool isStructSpecifier);
+ TType(const TInterfaceBlock *interfaceBlockIn,
+ TQualifier qualifierIn,
+ TLayoutQualifier layoutQualifierIn);
+ TType(const TType &t);
+ TType &operator=(const TType &t);
+
+ constexpr TType(TBasicType t,
+ TPrecision p,
+ TQualifier q,
+ uint8_t ps,
+ uint8_t ss,
+ const TSpan<const unsigned int> arraySizes,
+ const char *mangledName)
+ : type(t),
+ precision(p),
+ qualifier(q),
+ invariant(false),
+ precise(false),
+ memoryQualifier(TMemoryQualifier::Create()),
+ layoutQualifier(TLayoutQualifier::Create()),
+ primarySize(ps),
+ secondarySize(ss),
+ mArraySizes(arraySizes),
+ mArraySizesStorage(nullptr),
+ mInterfaceBlock(nullptr),
+ mStructure(nullptr),
+ mIsStructSpecifier(false),
+ mInterfaceBlockFieldIndex(0),
+ mMangledName(mangledName)
+ {}
+
+ constexpr TType(TType &&t)
+ : type(t.type),
+ precision(t.precision),
+ qualifier(t.qualifier),
+ invariant(t.invariant),
+ precise(t.precise),
+ memoryQualifier(t.memoryQualifier),
+ layoutQualifier(t.layoutQualifier),
+ primarySize(t.primarySize),
+ secondarySize(t.secondarySize),
+ mArraySizes(t.mArraySizes),
+ mArraySizesStorage(t.mArraySizesStorage),
+ mInterfaceBlock(t.mInterfaceBlock),
+ mStructure(t.mStructure),
+ mIsStructSpecifier(t.mIsStructSpecifier),
+ mInterfaceBlockFieldIndex(0),
+ mMangledName(t.mMangledName)
+ {
+ t.mArraySizesStorage = nullptr;
+ }
+
+ constexpr TBasicType getBasicType() const { return type; }
+ void setBasicType(TBasicType t);
+
+ TPrecision getPrecision() const { return precision; }
+ void setPrecision(TPrecision p) { precision = p; }
+
+ constexpr TQualifier getQualifier() const { return qualifier; }
+ void setQualifier(TQualifier q) { qualifier = q; }
+
+ bool isInvariant() const { return invariant; }
+ void setInvariant(bool i) { invariant = i; }
+
+ bool isPrecise() const { return precise; }
+ void setPrecise(bool i) { precise = i; }
+
+ TMemoryQualifier getMemoryQualifier() const { return memoryQualifier; }
+ void setMemoryQualifier(const TMemoryQualifier &mq) { memoryQualifier = mq; }
+
+ TLayoutQualifier getLayoutQualifier() const { return layoutQualifier; }
+ void setLayoutQualifier(TLayoutQualifier lq) { layoutQualifier = lq; }
+
+ uint8_t getNominalSize() const { return primarySize; }
+ uint8_t getSecondarySize() const { return secondarySize; }
+ uint8_t getCols() const
+ {
+ ASSERT(isMatrix());
+ return primarySize;
+ }
+ uint8_t getRows() const
+ {
+ ASSERT(isMatrix());
+ return secondarySize;
+ }
+ void setPrimarySize(uint8_t ps);
+ void setSecondarySize(uint8_t ss);
+
+ // Full size of single instance of type
+ size_t getObjectSize() const;
+
+ // Get how many locations this type consumes as a uniform.
+ int getLocationCount() const;
+
+ bool isMatrix() const { return primarySize > 1 && secondarySize > 1; }
+ bool isNonSquareMatrix() const { return isMatrix() && primarySize != secondarySize; }
+ bool isArray() const { return !mArraySizes.empty(); }
+ bool isArrayOfArrays() const { return mArraySizes.size() > 1u; }
+ size_t getNumArraySizes() const { return mArraySizes.size(); }
+ const TSpan<const unsigned int> &getArraySizes() const { return mArraySizes; }
+ unsigned int getArraySizeProduct() const;
+ bool isUnsizedArray() const;
+ unsigned int getOutermostArraySize() const
+ {
+ ASSERT(isArray());
+ return mArraySizes.back();
+ }
+ void makeArray(unsigned int s);
+
+ // sizes contain new outermost array sizes.
+ void makeArrays(const TSpan<const unsigned int> &sizes);
+ // Here, the array dimension value 0 corresponds to the innermost array.
+ void setArraySize(size_t arrayDimension, unsigned int s);
+
+ // Will set unsized array sizes according to newArraySizes. In case there are more
+ // unsized arrays than there are sizes in newArraySizes, defaults to setting any
+ // remaining array sizes to 1.
+ void sizeUnsizedArrays(const TSpan<const unsigned int> &newArraySizes);
+
+ // Will size the outermost array according to arraySize.
+ void sizeOutermostUnsizedArray(unsigned int arraySize);
+
+ // Note that the array element type might still be an array type in GLSL ES version >= 3.10.
+ void toArrayElementType();
+ // Removes all array sizes.
+ void toArrayBaseType();
+ // Turns a matrix into a column of it.
+ void toMatrixColumnType();
+ // Turns a matrix or vector into a component of it.
+ void toComponentType();
+
+ const TInterfaceBlock *getInterfaceBlock() const { return mInterfaceBlock; }
+ void setInterfaceBlock(const TInterfaceBlock *interfaceBlockIn);
+ bool isInterfaceBlock() const { return type == EbtInterfaceBlock; }
+
+ void setInterfaceBlockField(const TInterfaceBlock *interfaceBlockIn, size_t fieldIndex);
+ size_t getInterfaceBlockFieldIndex() const { return mInterfaceBlockFieldIndex; }
+
+ bool isVector() const { return primarySize > 1 && secondarySize == 1; }
+ bool isVectorArray() const { return primarySize > 1 && secondarySize == 1 && isArray(); }
+ bool isRank0() const { return primarySize == 1 && secondarySize == 1; }
+ bool isScalar() const
+ {
+ return primarySize == 1 && secondarySize == 1 && !mStructure && !isArray();
+ }
+ bool isScalarArray() const
+ {
+ return primarySize == 1 && secondarySize == 1 && !mStructure && isArray();
+ }
+ bool isScalarFloat() const { return isScalar() && type == EbtFloat; }
+ bool isScalarInt() const { return isScalar() && (type == EbtInt || type == EbtUInt); }
+
+ bool canBeConstructed() const;
+
+ const TStructure *getStruct() const { return mStructure; }
+
+ static constexpr char GetSizeMangledName(uint8_t primarySize, uint8_t secondarySize)
+ {
+ unsigned int sizeKey = (secondarySize - 1u) * 4u + primarySize - 1u;
+ if (sizeKey < 10u)
+ {
+ return static_cast<char>('0' + sizeKey);
+ }
+ return static_cast<char>('A' + sizeKey - 10);
+ }
+ const char *getMangledName() const;
+
+ bool sameNonArrayType(const TType &right) const;
+
+ // Returns true if arrayType is an array made of this type.
+ bool isElementTypeOf(const TType &arrayType) const;
+
+ bool operator==(const TType &right) const
+ {
+ size_t numArraySizesL = getNumArraySizes();
+ size_t numArraySizesR = right.getNumArraySizes();
+ bool arraySizesEqual = numArraySizesL == numArraySizesR &&
+ (numArraySizesL == 0 || mArraySizes == right.mArraySizes);
+ return type == right.type && primarySize == right.primarySize &&
+ secondarySize == right.secondarySize && arraySizesEqual &&
+ mStructure == right.mStructure;
+ // don't check the qualifier, it's not ever what's being sought after
+ }
+ bool operator!=(const TType &right) const { return !operator==(right); }
+ bool operator<(const TType &right) const
+ {
+ if (type != right.type)
+ return type < right.type;
+ if (primarySize != right.primarySize)
+ return primarySize < right.primarySize;
+ if (secondarySize != right.secondarySize)
+ return secondarySize < right.secondarySize;
+ size_t numArraySizesL = getNumArraySizes();
+ size_t numArraySizesR = right.getNumArraySizes();
+ if (numArraySizesL != numArraySizesR)
+ return numArraySizesL < numArraySizesR;
+ for (size_t i = 0; i < numArraySizesL; ++i)
+ {
+ if (mArraySizes[i] != right.mArraySizes[i])
+ return mArraySizes[i] < right.mArraySizes[i];
+ }
+ if (mStructure != right.mStructure)
+ return mStructure < right.mStructure;
+
+ return false;
+ }
+
+ const char *getBasicString() const { return sh::getBasicString(type); }
+
+ const char *getPrecisionString() const { return sh::getPrecisionString(precision); }
+ const char *getQualifierString() const { return sh::getQualifierString(qualifier); }
+
+ const char *getBuiltInTypeNameString() const;
+
+ // If this type is a struct, returns the deepest struct nesting of
+ // any field in the struct. For example:
+ // struct nesting1 {
+ // vec4 position;
+ // };
+ // struct nesting2 {
+ // nesting1 field1;
+ // vec4 field2;
+ // };
+ // For type "nesting2", this method would return 2 -- the number
+ // of structures through which indirection must occur to reach the
+ // deepest field (nesting2.field1.position).
+ int getDeepestStructNesting() const;
+
+ bool isNamelessStruct() const;
+
+ bool isStructureContainingArrays() const;
+ bool isStructureContainingMatrices() const;
+ bool isStructureContainingType(TBasicType t) const;
+ bool isStructureContainingSamplers() const;
+ bool isInterfaceBlockContainingType(TBasicType t) const;
+
+ bool isStructSpecifier() const { return mIsStructSpecifier; }
+
+ // Return true if variables of this type should be replaced with an inline constant value if
+ // such is available. False will be returned in cases where output doesn't support
+ // TIntermConstantUnion nodes of the type, or if the type contains a lot of fields and creating
+ // several copies of it in the output code is undesirable for performance.
+ bool canReplaceWithConstantUnion() const;
+
+ // The char arrays passed in must be pool allocated or static.
+ void createSamplerSymbols(const ImmutableString &namePrefix,
+ const TString &apiNamePrefix,
+ TVector<const TVariable *> *outputSymbols,
+ TMap<const TVariable *, TString> *outputSymbolsToAPINames,
+ TSymbolTable *symbolTable) const;
+
+ // Initializes all lazily-initialized members.
+ void realize();
+
+ bool isSampler() const { return IsSampler(type); }
+ bool isSamplerCube() const { return type == EbtSamplerCube; }
+ bool isAtomicCounter() const { return IsAtomicCounter(type); }
+ bool isSamplerVideoWEBGL() const { return type == EbtSamplerVideoWEBGL; }
+ bool isImage() const { return IsImage(type); }
+ bool isPixelLocal() const { return IsPixelLocal(type); }
+
+ private:
+ constexpr void invalidateMangledName() { mMangledName = nullptr; }
+ const char *buildMangledName() const;
+ constexpr void onArrayDimensionsChange(const TSpan<const unsigned int> &sizes)
+ {
+ mArraySizes = sizes;
+ invalidateMangledName();
+ }
+
+ TBasicType type;
+ TPrecision precision;
+ TQualifier qualifier;
+ bool invariant;
+ bool precise;
+
+ TMemoryQualifier memoryQualifier;
+ TLayoutQualifier layoutQualifier;
+ uint8_t primarySize; // size of vector or cols matrix
+ uint8_t secondarySize; // rows of a matrix
+
+ // Used to make an array type. Outermost array size is stored at the end of the vector. Having 0
+ // in this vector means an unsized array.
+ TSpan<const unsigned int> mArraySizes;
+ // Storage for mArraySizes, if any. This is usually the case, except for constexpr TTypes which
+ // only have a valid mArraySizes (with mArraySizesStorage being nullptr). Therefore, all
+ // modifications to array sizes happen on the storage (and if dimensions change, mArraySizes is
+ // also updated) and all reads are from mArraySizes.
+ TVector<unsigned int> *mArraySizesStorage;
+
+ // This is set only in the following two cases:
+ // 1) Represents an interface block.
+ // 2) Represents the member variable of an unnamed interface block.
+ // It's nullptr also for members of named interface blocks.
+ const TInterfaceBlock *mInterfaceBlock;
+
+ // nullptr unless this is a struct
+ const TStructure *mStructure;
+ bool mIsStructSpecifier;
+
+ // If this is a field of a nameless interface block, this would indicate which member it's
+ // refering to.
+ size_t mInterfaceBlockFieldIndex;
+
+ mutable const char *mMangledName;
+};
+
+// TTypeSpecifierNonArray stores all of the necessary fields for type_specifier_nonarray from the
+// grammar
+struct TTypeSpecifierNonArray
+{
+ TBasicType type;
+ uint8_t primarySize; // size of vector or cols of matrix
+ uint8_t secondarySize; // rows of matrix
+ const TStructure *userDef;
+ TSourceLoc line;
+
+ // true if the type was defined by a struct specifier rather than a reference to a type name.
+ bool isStructSpecifier;
+
+ void initialize(TBasicType aType, const TSourceLoc &aLine)
+ {
+ ASSERT(aType != EbtStruct);
+ type = aType;
+ primarySize = 1;
+ secondarySize = 1;
+ userDef = nullptr;
+ line = aLine;
+ isStructSpecifier = false;
+ }
+
+ void initializeStruct(const TStructure *aUserDef,
+ bool aIsStructSpecifier,
+ const TSourceLoc &aLine)
+ {
+ type = EbtStruct;
+ primarySize = 1;
+ secondarySize = 1;
+ userDef = aUserDef;
+ line = aLine;
+ isStructSpecifier = aIsStructSpecifier;
+ }
+
+ void setAggregate(uint8_t size) { primarySize = size; }
+
+ void setMatrix(uint8_t columns, uint8_t rows)
+ {
+ ASSERT(columns > 1 && rows > 1 && columns <= 4 && rows <= 4);
+ primarySize = columns;
+ secondarySize = rows;
+ }
+
+ 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
+{
+ // Must have a trivial default constructor since it is used in YYSTYPE.
+ TPublicType() = default;
+
+ void initialize(const TTypeSpecifierNonArray &typeSpecifier, TQualifier q);
+ void initializeBasicType(TBasicType basicType);
+
+ TBasicType getBasicType() const { return typeSpecifierNonArray.type; }
+ void setBasicType(TBasicType basicType) { typeSpecifierNonArray.type = basicType; }
+
+ uint8_t getPrimarySize() const { return typeSpecifierNonArray.primarySize; }
+ uint8_t getSecondarySize() const { return typeSpecifierNonArray.secondarySize; }
+
+ const TStructure *getUserDef() const { return typeSpecifierNonArray.userDef; }
+ const TSourceLoc &getLine() const { return typeSpecifierNonArray.line; }
+
+ bool isStructSpecifier() const { return typeSpecifierNonArray.isStructSpecifier; }
+
+ bool isStructureContainingArrays() const;
+ bool isStructureContainingType(TBasicType t) const;
+ void setArraySizes(TVector<unsigned int> *sizes);
+ bool isArray() const;
+ void clearArrayness();
+ bool isAggregate() const;
+
+ TTypeSpecifierNonArray typeSpecifierNonArray;
+ TLayoutQualifier layoutQualifier;
+ TMemoryQualifier memoryQualifier;
+ TQualifier qualifier;
+ bool invariant;
+ bool precise;
+ TPrecision precision;
+
+ // Either nullptr or empty in case the type is not an array. The last element is the outermost
+ // array size. Note that due to bison restrictions, copies of the public type created by the
+ // copy constructor share the same arraySizes pointer.
+ const TVector<unsigned int> *arraySizes;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TYPES_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/UtilsHLSL.cpp b/gfx/angle/checkout/src/compiler/translator/UtilsHLSL.cpp
new file mode 100644
index 0000000000..5d9a573d7b
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/UtilsHLSL.cpp
@@ -0,0 +1,1223 @@
+//
+// 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.
+//
+// UtilsHLSL.cpp:
+// Utility methods for GLSL to HLSL translation.
+//
+
+#include "compiler/translator/UtilsHLSL.h"
+
+#include "common/utilities.h"
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/StructureHLSL.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+// Parameter types are only added to function names if they are ambiguous according to the
+// native HLSL compiler. Other parameter types are not added to function names to avoid
+// making function names longer.
+bool FunctionParameterNeedsDisambiguation(const TType &paramType)
+{
+ if (paramType.getObjectSize() == 4 && paramType.getBasicType() == EbtFloat)
+ {
+ // Disambiguation is needed for float2x2 and float4 parameters. These are the only
+ // built-in types that HLSL thinks are identical. float2x3 and float3x2 are different
+ // types, for example.
+ return true;
+ }
+
+ if (paramType.getBasicType() == EbtUInt || paramType.getBasicType() == EbtInt)
+ {
+ // The HLSL compiler can't always tell the difference between int and uint types when an
+ // expression is passed as a function parameter
+ return true;
+ }
+
+ if (paramType.getBasicType() == EbtStruct)
+ {
+ // Disambiguation is needed for struct parameters, since HLSL thinks that structs with
+ // the same fields but a different name are identical.
+ ASSERT(paramType.getStruct()->symbolType() != SymbolType::Empty);
+ return true;
+ }
+
+ return false;
+}
+
+void DisambiguateFunctionNameForParameterType(const TType &paramType,
+ TString *disambiguatingStringOut)
+{
+ if (FunctionParameterNeedsDisambiguation(paramType))
+ {
+ *disambiguatingStringOut += "_" + TypeString(paramType);
+ }
+}
+
+} // anonymous namespace
+
+const char *SamplerString(const TBasicType type)
+{
+ if (IsShadowSampler(type))
+ {
+ return "SamplerComparisonState";
+ }
+ else
+ {
+ return "SamplerState";
+ }
+}
+
+const char *SamplerString(HLSLTextureGroup type)
+{
+ if (type >= HLSL_COMPARISON_SAMPLER_GROUP_BEGIN && type <= HLSL_COMPARISON_SAMPLER_GROUP_END)
+ {
+ return "SamplerComparisonState";
+ }
+ else
+ {
+ return "SamplerState";
+ }
+}
+
+HLSLTextureGroup TextureGroup(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat)
+
+{
+ switch (type)
+ {
+ case EbtSampler2D:
+ case EbtSamplerVideoWEBGL:
+ return HLSL_TEXTURE_2D;
+ case EbtSamplerCube:
+ return HLSL_TEXTURE_CUBE;
+ case EbtSamplerExternalOES:
+ return HLSL_TEXTURE_2D;
+ case EbtSampler2DArray:
+ return HLSL_TEXTURE_2D_ARRAY;
+ case EbtSampler3D:
+ return HLSL_TEXTURE_3D;
+ case EbtSampler2DMS:
+ return HLSL_TEXTURE_2D_MS;
+ case EbtSampler2DMSArray:
+ return HLSL_TEXTURE_2D_MS_ARRAY;
+ case EbtSamplerBuffer:
+ return HLSL_TEXTURE_BUFFER;
+ case EbtISampler2D:
+ return HLSL_TEXTURE_2D_INT4;
+ case EbtISamplerBuffer:
+ return HLSL_TEXTURE_BUFFER_INT4;
+ case EbtISampler3D:
+ return HLSL_TEXTURE_3D_INT4;
+ case EbtISamplerCube:
+ return HLSL_TEXTURE_2D_ARRAY_INT4;
+ case EbtISampler2DArray:
+ return HLSL_TEXTURE_2D_ARRAY_INT4;
+ case EbtISampler2DMS:
+ return HLSL_TEXTURE_2D_MS_INT4;
+ case EbtISampler2DMSArray:
+ return HLSL_TEXTURE_2D_MS_ARRAY_INT4;
+ case EbtUSampler2D:
+ return HLSL_TEXTURE_2D_UINT4;
+ case EbtUSampler3D:
+ return HLSL_TEXTURE_3D_UINT4;
+ case EbtUSamplerCube:
+ return HLSL_TEXTURE_2D_ARRAY_UINT4;
+ case EbtUSamplerBuffer:
+ return HLSL_TEXTURE_BUFFER_UINT4;
+ case EbtUSampler2DArray:
+ return HLSL_TEXTURE_2D_ARRAY_UINT4;
+ case EbtUSampler2DMS:
+ return HLSL_TEXTURE_2D_MS_UINT4;
+ case EbtUSampler2DMSArray:
+ return HLSL_TEXTURE_2D_MS_ARRAY_UINT4;
+ case EbtSampler2DShadow:
+ return HLSL_TEXTURE_2D_COMPARISON;
+ case EbtSamplerCubeShadow:
+ return HLSL_TEXTURE_CUBE_COMPARISON;
+ case EbtSampler2DArrayShadow:
+ return HLSL_TEXTURE_2D_ARRAY_COMPARISON;
+ case EbtImage2D:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32F:
+ case EiifRGBA16F:
+ case EiifR32F:
+ return HLSL_TEXTURE_2D;
+ case EiifRGBA8:
+ return HLSL_TEXTURE_2D_UNORM;
+ case EiifRGBA8_SNORM:
+ return HLSL_TEXTURE_2D_SNORM;
+ default:
+ UNREACHABLE();
+ return HLSL_TEXTURE_UNKNOWN;
+ }
+ }
+ case EbtIImage2D:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32I:
+ case EiifRGBA16I:
+ case EiifRGBA8I:
+ case EiifR32I:
+ return HLSL_TEXTURE_2D_INT4;
+ default:
+ UNREACHABLE();
+ return HLSL_TEXTURE_UNKNOWN;
+ }
+ }
+ case EbtUImage2D:
+ {
+ switch (imageInternalFormat)
+ {
+
+ case EiifRGBA32UI:
+ case EiifRGBA16UI:
+ case EiifRGBA8UI:
+ case EiifR32UI:
+ return HLSL_TEXTURE_2D_UINT4;
+ default:
+ UNREACHABLE();
+ return HLSL_TEXTURE_UNKNOWN;
+ }
+ }
+ case EbtImage3D:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32F:
+ case EiifRGBA16F:
+ case EiifR32F:
+ return HLSL_TEXTURE_3D;
+ case EiifRGBA8:
+ return HLSL_TEXTURE_3D_UNORM;
+ case EiifRGBA8_SNORM:
+ return HLSL_TEXTURE_3D_SNORM;
+ default:
+ UNREACHABLE();
+ return HLSL_TEXTURE_UNKNOWN;
+ }
+ }
+ case EbtIImage3D:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32I:
+ case EiifRGBA16I:
+ case EiifRGBA8I:
+ case EiifR32I:
+ return HLSL_TEXTURE_3D_INT4;
+ default:
+ UNREACHABLE();
+ return HLSL_TEXTURE_UNKNOWN;
+ }
+ }
+ case EbtUImage3D:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32UI:
+ case EiifRGBA16UI:
+ case EiifRGBA8UI:
+ case EiifR32UI:
+ return HLSL_TEXTURE_3D_UINT4;
+ default:
+ UNREACHABLE();
+ return HLSL_TEXTURE_UNKNOWN;
+ }
+ }
+ case EbtImage2DArray:
+ case EbtImageCube:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32F:
+ case EiifRGBA16F:
+ case EiifR32F:
+ return HLSL_TEXTURE_2D_ARRAY;
+ case EiifRGBA8:
+ return HLSL_TEXTURE_2D_ARRAY_UNORN;
+ case EiifRGBA8_SNORM:
+ return HLSL_TEXTURE_2D_ARRAY_SNORM;
+ default:
+ UNREACHABLE();
+ return HLSL_TEXTURE_UNKNOWN;
+ }
+ }
+ case EbtIImage2DArray:
+ case EbtIImageCube:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32I:
+ case EiifRGBA16I:
+ case EiifRGBA8I:
+ case EiifR32I:
+ return HLSL_TEXTURE_2D_ARRAY_INT4;
+ default:
+ UNREACHABLE();
+ return HLSL_TEXTURE_UNKNOWN;
+ }
+ }
+ case EbtUImage2DArray:
+ case EbtUImageCube:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32UI:
+ case EiifRGBA16UI:
+ case EiifRGBA8UI:
+ case EiifR32UI:
+ return HLSL_TEXTURE_2D_ARRAY_UINT4;
+ default:
+ UNREACHABLE();
+ return HLSL_TEXTURE_UNKNOWN;
+ }
+ }
+ case EbtImageBuffer:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32F:
+ case EiifRGBA16F:
+ case EiifR32F:
+ return HLSL_TEXTURE_BUFFER;
+ case EiifRGBA8:
+ return HLSL_TEXTURE_BUFFER_UNORM;
+ case EiifRGBA8_SNORM:
+ return HLSL_TEXTURE_BUFFER_SNORM;
+ default:
+ UNREACHABLE();
+ return HLSL_TEXTURE_UNKNOWN;
+ }
+ }
+ case EbtUImageBuffer:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32UI:
+ case EiifRGBA16UI:
+ case EiifRGBA8UI:
+ case EiifR32UI:
+ return HLSL_TEXTURE_BUFFER_UINT4;
+ default:
+ UNREACHABLE();
+ return HLSL_TEXTURE_UNKNOWN;
+ }
+ }
+ case EbtIImageBuffer:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32I:
+ case EiifRGBA16I:
+ case EiifRGBA8I:
+ case EiifR32I:
+ return HLSL_TEXTURE_BUFFER_INT4;
+ default:
+ UNREACHABLE();
+ return HLSL_TEXTURE_UNKNOWN;
+ }
+ }
+ default:
+ UNREACHABLE();
+ return HLSL_TEXTURE_UNKNOWN;
+ }
+}
+
+const char *TextureString(const HLSLTextureGroup textureGroup)
+{
+ switch (textureGroup)
+ {
+ case HLSL_TEXTURE_2D:
+ return "Texture2D<float4>";
+ case HLSL_TEXTURE_CUBE:
+ return "TextureCube<float4>";
+ case HLSL_TEXTURE_2D_ARRAY:
+ return "Texture2DArray<float4>";
+ case HLSL_TEXTURE_3D:
+ return "Texture3D<float4>";
+ case HLSL_TEXTURE_2D_UNORM:
+ return "Texture2D<unorm float4>";
+ case HLSL_TEXTURE_CUBE_UNORM:
+ return "TextureCube<unorm float4>";
+ case HLSL_TEXTURE_2D_ARRAY_UNORN:
+ return "Texture2DArray<unorm float4>";
+ case HLSL_TEXTURE_3D_UNORM:
+ return "Texture3D<unorm float4>";
+ case HLSL_TEXTURE_2D_SNORM:
+ return "Texture2D<snorm float4>";
+ case HLSL_TEXTURE_CUBE_SNORM:
+ return "TextureCube<snorm float4>";
+ case HLSL_TEXTURE_2D_ARRAY_SNORM:
+ return "Texture2DArray<snorm float4>";
+ case HLSL_TEXTURE_3D_SNORM:
+ return "Texture3D<snorm float4>";
+ case HLSL_TEXTURE_2D_MS:
+ return "Texture2DMS<float4>";
+ case HLSL_TEXTURE_2D_MS_ARRAY:
+ return "Texture2DMSArray<float4>";
+ case HLSL_TEXTURE_2D_INT4:
+ return "Texture2D<int4>";
+ case HLSL_TEXTURE_3D_INT4:
+ return "Texture3D<int4>";
+ case HLSL_TEXTURE_2D_ARRAY_INT4:
+ return "Texture2DArray<int4>";
+ case HLSL_TEXTURE_2D_MS_INT4:
+ return "Texture2DMS<int4>";
+ case HLSL_TEXTURE_2D_MS_ARRAY_INT4:
+ return "Texture2DMSArray<int4>";
+ case HLSL_TEXTURE_2D_UINT4:
+ return "Texture2D<uint4>";
+ case HLSL_TEXTURE_3D_UINT4:
+ return "Texture3D<uint4>";
+ case HLSL_TEXTURE_2D_ARRAY_UINT4:
+ return "Texture2DArray<uint4>";
+ case HLSL_TEXTURE_2D_MS_UINT4:
+ return "Texture2DMS<uint4>";
+ case HLSL_TEXTURE_2D_MS_ARRAY_UINT4:
+ return "Texture2DMSArray<uint4>";
+ case HLSL_TEXTURE_2D_COMPARISON:
+ return "Texture2D";
+ case HLSL_TEXTURE_CUBE_COMPARISON:
+ return "TextureCube";
+ case HLSL_TEXTURE_2D_ARRAY_COMPARISON:
+ return "Texture2DArray";
+ case HLSL_TEXTURE_BUFFER:
+ return "Buffer<float4>";
+ case HLSL_TEXTURE_BUFFER_INT4:
+ return "Buffer<int4>";
+ case HLSL_TEXTURE_BUFFER_UINT4:
+ return "Buffer<uint4>";
+ case HLSL_TEXTURE_BUFFER_UNORM:
+ return "Buffer<unorm float4>";
+ case HLSL_TEXTURE_BUFFER_SNORM:
+ return "Buffer<snorm float4>";
+ default:
+ UNREACHABLE();
+ }
+
+ return "<unknown read texture type>";
+}
+
+const char *TextureString(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat)
+{
+ return TextureString(TextureGroup(type, imageInternalFormat));
+}
+
+const char *TextureGroupSuffix(const HLSLTextureGroup type)
+{
+ switch (type)
+ {
+ case HLSL_TEXTURE_2D:
+ return "2D";
+ case HLSL_TEXTURE_CUBE:
+ return "Cube";
+ case HLSL_TEXTURE_2D_ARRAY:
+ return "2DArray";
+ case HLSL_TEXTURE_3D:
+ return "3D";
+ case HLSL_TEXTURE_2D_UNORM:
+ return "2D_unorm_float4_";
+ case HLSL_TEXTURE_CUBE_UNORM:
+ return "Cube_unorm_float4_";
+ case HLSL_TEXTURE_2D_ARRAY_UNORN:
+ return "2DArray_unorm_float4_";
+ case HLSL_TEXTURE_3D_UNORM:
+ return "3D_unorm_float4_";
+ case HLSL_TEXTURE_2D_SNORM:
+ return "2D_snorm_float4_";
+ case HLSL_TEXTURE_CUBE_SNORM:
+ return "Cube_snorm_float4_";
+ case HLSL_TEXTURE_2D_ARRAY_SNORM:
+ return "2DArray_snorm_float4_";
+ case HLSL_TEXTURE_3D_SNORM:
+ return "3D_snorm_float4_";
+ case HLSL_TEXTURE_2D_MS:
+ return "2DMS";
+ case HLSL_TEXTURE_2D_MS_ARRAY:
+ return "2DMSArray";
+ case HLSL_TEXTURE_2D_INT4:
+ return "2D_int4_";
+ case HLSL_TEXTURE_3D_INT4:
+ return "3D_int4_";
+ case HLSL_TEXTURE_2D_ARRAY_INT4:
+ return "2DArray_int4_";
+ case HLSL_TEXTURE_2D_MS_INT4:
+ return "2DMS_int4_";
+ case HLSL_TEXTURE_2D_MS_ARRAY_INT4:
+ return "2DMSArray_int4_";
+ case HLSL_TEXTURE_2D_UINT4:
+ return "2D_uint4_";
+ case HLSL_TEXTURE_3D_UINT4:
+ return "3D_uint4_";
+ case HLSL_TEXTURE_2D_ARRAY_UINT4:
+ return "2DArray_uint4_";
+ case HLSL_TEXTURE_2D_MS_UINT4:
+ return "2DMS_uint4_";
+ case HLSL_TEXTURE_2D_MS_ARRAY_UINT4:
+ return "2DMSArray_uint4_";
+ case HLSL_TEXTURE_2D_COMPARISON:
+ return "2D_comparison";
+ case HLSL_TEXTURE_CUBE_COMPARISON:
+ return "Cube_comparison";
+ case HLSL_TEXTURE_2D_ARRAY_COMPARISON:
+ return "2DArray_comparison";
+ case HLSL_TEXTURE_BUFFER:
+ return "Buffer";
+ case HLSL_TEXTURE_BUFFER_INT4:
+ return "Buffer_int4_";
+ case HLSL_TEXTURE_BUFFER_UINT4:
+ return "Buffer_uint4_";
+ case HLSL_TEXTURE_BUFFER_UNORM:
+ return "Buffer_unorm_float4_";
+ case HLSL_TEXTURE_BUFFER_SNORM:
+ return "Buffer_snorm_float4_";
+ default:
+ UNREACHABLE();
+ }
+
+ return "<unknown texture type>";
+}
+
+const char *TextureGroupSuffix(const TBasicType type,
+ TLayoutImageInternalFormat imageInternalFormat)
+{
+ return TextureGroupSuffix(TextureGroup(type, imageInternalFormat));
+}
+
+const char *TextureTypeSuffix(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat)
+{
+ switch (type)
+ {
+ case EbtISamplerCube:
+ return "Cube_int4_";
+ case EbtUSamplerCube:
+ return "Cube_uint4_";
+ case EbtSamplerExternalOES:
+ return "_External";
+ case EbtImageCube:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32F:
+ case EiifRGBA16F:
+ case EiifR32F:
+ return "Cube_float4_";
+ case EiifRGBA8:
+ return "Cube_unorm_float4_";
+ case EiifRGBA8_SNORM:
+ return "Cube_snorm_float4_";
+ default:
+ UNREACHABLE();
+ }
+ break;
+ }
+ case EbtIImageCube:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32I:
+ case EiifRGBA16I:
+ case EiifRGBA8I:
+ case EiifR32I:
+ return "Cube_int4_";
+ default:
+ UNREACHABLE();
+ }
+ break;
+ }
+ case EbtUImageCube:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32UI:
+ case EiifRGBA16UI:
+ case EiifRGBA8UI:
+ case EiifR32UI:
+ return "Cube_uint4_";
+ default:
+ UNREACHABLE();
+ }
+ break;
+ }
+ default:
+ // All other types are identified by their group suffix
+ return TextureGroupSuffix(type, imageInternalFormat);
+ }
+ UNREACHABLE();
+ return "_TTS_invalid_";
+}
+
+HLSLRWTextureGroup RWTextureGroup(const TBasicType type,
+ TLayoutImageInternalFormat imageInternalFormat)
+
+{
+ switch (type)
+ {
+ case EbtImage2D:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32F:
+ case EiifRGBA16F:
+ case EiifR32F:
+ return HLSL_RWTEXTURE_2D_FLOAT4;
+ case EiifRGBA8:
+ return HLSL_RWTEXTURE_2D_UNORM;
+ case EiifRGBA8_SNORM:
+ return HLSL_RWTEXTURE_2D_SNORM;
+ default:
+ UNREACHABLE();
+ }
+ break;
+ }
+ case EbtIImage2D:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32I:
+ case EiifRGBA16I:
+ case EiifRGBA8I:
+ case EiifR32I:
+ return HLSL_RWTEXTURE_2D_INT4;
+ default:
+ UNREACHABLE();
+ }
+ break;
+ }
+ case EbtUImage2D:
+ {
+ switch (imageInternalFormat)
+ {
+
+ case EiifRGBA32UI:
+ case EiifRGBA16UI:
+ case EiifRGBA8UI:
+ case EiifR32UI:
+ return HLSL_RWTEXTURE_2D_UINT4;
+ default:
+ UNREACHABLE();
+ }
+ break;
+ }
+ case EbtImage3D:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32F:
+ case EiifRGBA16F:
+ case EiifR32F:
+ return HLSL_RWTEXTURE_3D_FLOAT4;
+ case EiifRGBA8:
+ return HLSL_RWTEXTURE_3D_UNORM;
+ case EiifRGBA8_SNORM:
+ return HLSL_RWTEXTURE_3D_SNORM;
+ default:
+ UNREACHABLE();
+ }
+ break;
+ }
+ case EbtIImage3D:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32I:
+ case EiifRGBA16I:
+ case EiifRGBA8I:
+ case EiifR32I:
+ return HLSL_RWTEXTURE_3D_INT4;
+ default:
+ UNREACHABLE();
+ }
+ break;
+ }
+ case EbtUImage3D:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32UI:
+ case EiifRGBA16UI:
+ case EiifRGBA8UI:
+ case EiifR32UI:
+ return HLSL_RWTEXTURE_3D_UINT4;
+ default:
+ UNREACHABLE();
+ }
+ break;
+ }
+ case EbtImage2DArray:
+ case EbtImageCube:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32F:
+ case EiifRGBA16F:
+ case EiifR32F:
+ return HLSL_RWTEXTURE_2D_ARRAY_FLOAT4;
+ case EiifRGBA8:
+ return HLSL_RWTEXTURE_2D_ARRAY_UNORN;
+ case EiifRGBA8_SNORM:
+ return HLSL_RWTEXTURE_2D_ARRAY_SNORM;
+ default:
+ UNREACHABLE();
+ }
+ break;
+ }
+ case EbtIImage2DArray:
+ case EbtIImageCube:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32I:
+ case EiifRGBA16I:
+ case EiifRGBA8I:
+ case EiifR32I:
+ return HLSL_RWTEXTURE_2D_ARRAY_INT4;
+ default:
+ UNREACHABLE();
+ }
+ break;
+ }
+ case EbtUImage2DArray:
+ case EbtUImageCube:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32UI:
+ case EiifRGBA16UI:
+ case EiifRGBA8UI:
+ case EiifR32UI:
+ return HLSL_RWTEXTURE_2D_ARRAY_UINT4;
+ default:
+ UNREACHABLE();
+ }
+ break;
+ }
+ case EbtImageBuffer:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32F:
+ case EiifRGBA16F:
+ case EiifR32F:
+ return HLSL_RWTEXTURE_BUFFER_FLOAT4;
+ case EiifRGBA8:
+ return HLSL_RWTEXTURE_BUFFER_UNORM;
+ case EiifRGBA8_SNORM:
+ return HLSL_RWTEXTURE_BUFFER_SNORM;
+ default:
+ UNREACHABLE();
+ }
+ break;
+ }
+ case EbtIImageBuffer:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32I:
+ case EiifRGBA16I:
+ case EiifRGBA8I:
+ case EiifR32I:
+ return HLSL_RWTEXTURE_BUFFER_INT4;
+ default:
+ UNREACHABLE();
+ }
+ break;
+ }
+ case EbtUImageBuffer:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32UI:
+ case EiifRGBA16UI:
+ case EiifRGBA8UI:
+ case EiifR32UI:
+ return HLSL_RWTEXTURE_BUFFER_UINT4;
+ default:
+ UNREACHABLE();
+ }
+ break;
+ }
+ default:
+ UNREACHABLE();
+ }
+ return HLSL_RWTEXTURE_UNKNOWN;
+}
+
+const char *RWTextureString(const HLSLRWTextureGroup RWTextureGroup)
+{
+ switch (RWTextureGroup)
+ {
+ case HLSL_RWTEXTURE_2D_FLOAT4:
+ return "RWTexture2D<float4>";
+ case HLSL_RWTEXTURE_2D_ARRAY_FLOAT4:
+ return "RWTexture2DArray<float4>";
+ case HLSL_RWTEXTURE_3D_FLOAT4:
+ return "RWTexture3D<float4>";
+ case HLSL_RWTEXTURE_2D_UNORM:
+ return "RWTexture2D<unorm float4>";
+ case HLSL_RWTEXTURE_2D_ARRAY_UNORN:
+ return "RWTexture2DArray<unorm float4>";
+ case HLSL_RWTEXTURE_3D_UNORM:
+ return "RWTexture3D<unorm float4>";
+ case HLSL_RWTEXTURE_2D_SNORM:
+ return "RWTexture2D<snorm float4>";
+ case HLSL_RWTEXTURE_2D_ARRAY_SNORM:
+ return "RWTexture2DArray<snorm float4>";
+ case HLSL_RWTEXTURE_3D_SNORM:
+ return "RWTexture3D<snorm float4>";
+ case HLSL_RWTEXTURE_2D_UINT4:
+ return "RWTexture2D<uint4>";
+ case HLSL_RWTEXTURE_2D_ARRAY_UINT4:
+ return "RWTexture2DArray<uint4>";
+ case HLSL_RWTEXTURE_3D_UINT4:
+ return "RWTexture3D<uint4>";
+ case HLSL_RWTEXTURE_2D_INT4:
+ return "RWTexture2D<int4>";
+ case HLSL_RWTEXTURE_2D_ARRAY_INT4:
+ return "RWTexture2DArray<int4>";
+ case HLSL_RWTEXTURE_3D_INT4:
+ return "RWTexture3D<int4>";
+ case HLSL_RWTEXTURE_BUFFER_FLOAT4:
+ return "RWBuffer<float4>";
+ case HLSL_RWTEXTURE_BUFFER_UNORM:
+ return "RWBuffer<unorm float4>";
+ case HLSL_RWTEXTURE_BUFFER_SNORM:
+ return "RWBuffer<snorm float4>";
+ case HLSL_RWTEXTURE_BUFFER_UINT4:
+ return "RWBuffer<uint4>";
+ case HLSL_RWTEXTURE_BUFFER_INT4:
+ return "RWBuffer<int4>";
+ default:
+ UNREACHABLE();
+ }
+
+ return "<unknown read and write texture type>";
+}
+
+const char *RWTextureString(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat)
+{
+ return RWTextureString(RWTextureGroup(type, imageInternalFormat));
+}
+
+const char *RWTextureGroupSuffix(const HLSLRWTextureGroup type)
+{
+ switch (type)
+ {
+ case HLSL_RWTEXTURE_2D_FLOAT4:
+ return "RW2D_float4_";
+ case HLSL_RWTEXTURE_2D_ARRAY_FLOAT4:
+ return "RW2DArray_float4_";
+ case HLSL_RWTEXTURE_3D_FLOAT4:
+ return "RW3D_float4_";
+ case HLSL_RWTEXTURE_2D_UNORM:
+ return "RW2D_unorm_float4_";
+ case HLSL_RWTEXTURE_2D_ARRAY_UNORN:
+ return "RW2DArray_unorm_float4_";
+ case HLSL_RWTEXTURE_3D_UNORM:
+ return "RW3D_unorm_float4_";
+ case HLSL_RWTEXTURE_2D_SNORM:
+ return "RW2D_snorm_float4_";
+ case HLSL_RWTEXTURE_2D_ARRAY_SNORM:
+ return "RW2DArray_snorm_float4_";
+ case HLSL_RWTEXTURE_3D_SNORM:
+ return "RW3D_snorm_float4_";
+ case HLSL_RWTEXTURE_2D_UINT4:
+ return "RW2D_uint4_";
+ case HLSL_RWTEXTURE_2D_ARRAY_UINT4:
+ return "RW2DArray_uint4_";
+ case HLSL_RWTEXTURE_3D_UINT4:
+ return "RW3D_uint4_";
+ case HLSL_RWTEXTURE_2D_INT4:
+ return "RW2D_int4_";
+ case HLSL_RWTEXTURE_2D_ARRAY_INT4:
+ return "RW2DArray_int4_";
+ case HLSL_RWTEXTURE_3D_INT4:
+ return "RW3D_int4_";
+ case HLSL_RWTEXTURE_BUFFER_FLOAT4:
+ return "RWBuffer_float4_";
+ case HLSL_RWTEXTURE_BUFFER_UNORM:
+ return "RWBuffer_unorm_float4_";
+ case HLSL_RWTEXTURE_BUFFER_SNORM:
+ return "RWBuffer_snorm_float4_";
+ case HLSL_RWTEXTURE_BUFFER_UINT4:
+ return "RWBuffer_uint4_";
+ case HLSL_RWTEXTURE_BUFFER_INT4:
+ return "RWBuffer_int4_";
+ default:
+ UNREACHABLE();
+ }
+
+ return "<unknown read and write resource>";
+}
+
+const char *RWTextureGroupSuffix(const TBasicType type,
+ TLayoutImageInternalFormat imageInternalFormat)
+{
+ return RWTextureGroupSuffix(RWTextureGroup(type, imageInternalFormat));
+}
+
+const char *RWTextureTypeSuffix(const TBasicType type,
+ TLayoutImageInternalFormat imageInternalFormat)
+{
+ switch (type)
+ {
+ case EbtImageCube:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32F:
+ case EiifRGBA16F:
+ case EiifR32F:
+ return "RWCube_float4_";
+ case EiifRGBA8:
+ return "RWCube_unorm_float4_";
+ case EiifRGBA8_SNORM:
+ return "RWCube_unorm_float4_";
+ default:
+ UNREACHABLE();
+ }
+ break;
+ }
+ case EbtIImageCube:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32I:
+ case EiifRGBA16I:
+ case EiifRGBA8I:
+ case EiifR32I:
+ return "RWCube_int4_";
+ default:
+ UNREACHABLE();
+ }
+ break;
+ }
+ case EbtUImageCube:
+ {
+ switch (imageInternalFormat)
+ {
+ case EiifRGBA32UI:
+ case EiifRGBA16UI:
+ case EiifRGBA8UI:
+ case EiifR32UI:
+ return "RWCube_uint4_";
+ default:
+ UNREACHABLE();
+ }
+ break;
+ }
+ default:
+ // All other types are identified by their group suffix
+ return RWTextureGroupSuffix(type, imageInternalFormat);
+ }
+ UNREACHABLE();
+ return "_RWTS_invalid_";
+}
+
+TString DecorateField(const ImmutableString &string, const TStructure &structure)
+{
+ if (structure.symbolType() != SymbolType::BuiltIn)
+ {
+ return Decorate(string);
+ }
+
+ return TString(string.data());
+}
+
+TString DecoratePrivate(const ImmutableString &privateText)
+{
+ return "dx_" + TString(privateText.data());
+}
+
+TString Decorate(const ImmutableString &string)
+{
+ if (!gl::IsBuiltInName(string.data()))
+ {
+ return "_" + TString(string.data());
+ }
+
+ return TString(string.data());
+}
+
+TString DecorateVariableIfNeeded(const TVariable &variable)
+{
+ if (variable.symbolType() == SymbolType::AngleInternal ||
+ variable.symbolType() == SymbolType::BuiltIn || variable.symbolType() == SymbolType::Empty)
+ {
+ // Besides handling internal variables, we generate names for nameless parameters here.
+ const ImmutableString &name = variable.name();
+ // The name should not have a prefix reserved for user-defined variables or functions.
+ ASSERT(!name.beginsWith("f_"));
+ ASSERT(!name.beginsWith("_"));
+ return TString(name.data());
+ }
+ // For user defined variables, combine variable name with unique id
+ // so variables of the same name in different scopes do not get overwritten.
+ else if (variable.symbolType() == SymbolType::UserDefined &&
+ variable.getType().getQualifier() == EvqTemporary)
+ {
+ return Decorate(variable.name()) + str(variable.uniqueId().get());
+ }
+ else
+ {
+ return Decorate(variable.name());
+ }
+}
+
+TString DecorateFunctionIfNeeded(const TFunction *func)
+{
+ if (func->symbolType() == SymbolType::AngleInternal)
+ {
+ // The name should not have a prefix reserved for user-defined variables or functions.
+ ASSERT(!func->name().beginsWith("f_"));
+ ASSERT(!func->name().beginsWith("_"));
+ return TString(func->name().data());
+ }
+ ASSERT(!gl::IsBuiltInName(func->name().data()));
+ // Add an additional f prefix to functions so that they're always disambiguated from variables.
+ // This is necessary in the corner case where a variable declaration hides a function that it
+ // uses in its initializer.
+ return "f_" + TString(func->name().data());
+}
+
+TString TypeString(const TType &type)
+{
+ const TStructure *structure = type.getStruct();
+ if (structure)
+ {
+ if (structure->symbolType() != SymbolType::Empty)
+ {
+ return StructNameString(*structure);
+ }
+ else // Nameless structure, define in place
+ {
+ return StructureHLSL::defineNameless(*structure);
+ }
+ }
+ else if (type.isMatrix())
+ {
+ uint8_t cols = type.getCols();
+ uint8_t rows = type.getRows();
+ return "float" + str(cols) + "x" + str(rows);
+ }
+ else
+ {
+ switch (type.getBasicType())
+ {
+ case EbtFloat:
+ switch (type.getNominalSize())
+ {
+ case 1:
+ return "float";
+ case 2:
+ return "float2";
+ case 3:
+ return "float3";
+ case 4:
+ return "float4";
+ }
+ case EbtInt:
+ switch (type.getNominalSize())
+ {
+ case 1:
+ return "int";
+ case 2:
+ return "int2";
+ case 3:
+ return "int3";
+ case 4:
+ return "int4";
+ }
+ case EbtUInt:
+ switch (type.getNominalSize())
+ {
+ case 1:
+ return "uint";
+ case 2:
+ return "uint2";
+ case 3:
+ return "uint3";
+ case 4:
+ return "uint4";
+ }
+ case EbtBool:
+ switch (type.getNominalSize())
+ {
+ case 1:
+ return "bool";
+ case 2:
+ return "bool2";
+ case 3:
+ return "bool3";
+ case 4:
+ return "bool4";
+ }
+ case EbtVoid:
+ return "void";
+ case EbtSampler2D:
+ case EbtISampler2D:
+ case EbtUSampler2D:
+ case EbtSampler2DArray:
+ case EbtISampler2DArray:
+ case EbtUSampler2DArray:
+ return "sampler2D";
+ case EbtSamplerCube:
+ case EbtISamplerCube:
+ case EbtUSamplerCube:
+ return "samplerCUBE";
+ case EbtSamplerExternalOES:
+ return "sampler2D";
+ case EbtSamplerVideoWEBGL:
+ return "sampler2D";
+ case EbtAtomicCounter:
+ // Multiple atomic_uints will be implemented as a single RWByteAddressBuffer
+ return "RWByteAddressBuffer";
+ default:
+ break;
+ }
+ }
+
+ UNREACHABLE();
+ return "<unknown type>";
+}
+
+TString StructNameString(const TStructure &structure)
+{
+ if (structure.symbolType() == SymbolType::Empty)
+ {
+ return "";
+ }
+
+ // For structures at global scope we use a consistent
+ // translation so that we can link between shader stages.
+ if (structure.atGlobalScope())
+ {
+ return Decorate(structure.name());
+ }
+
+ return "ss" + str(structure.uniqueId().get()) + "_" + TString(structure.name().data());
+}
+
+TString QualifiedStructNameString(const TStructure &structure,
+ bool useHLSLRowMajorPacking,
+ bool useStd140Packing,
+ bool forcePadding)
+{
+ if (structure.symbolType() == SymbolType::Empty)
+ {
+ return "";
+ }
+
+ TString prefix = "";
+
+ // Structs packed with row-major matrices in HLSL are prefixed with "rm"
+ // GLSL column-major maps to HLSL row-major, and the converse is true
+
+ if (useStd140Packing)
+ {
+ prefix += "std_";
+ }
+
+ if (useHLSLRowMajorPacking)
+ {
+ prefix += "rm_";
+ }
+
+ if (forcePadding)
+ {
+ prefix += "fp_";
+ }
+
+ return prefix + StructNameString(structure);
+}
+
+const char *InterpolationString(TQualifier qualifier)
+{
+ switch (qualifier)
+ {
+ case EvqVaryingIn:
+ return "";
+ case EvqFragmentIn:
+ return "";
+ case EvqSmoothIn:
+ return "linear";
+ case EvqFlatIn:
+ return "nointerpolation";
+ case EvqCentroidIn:
+ return "centroid";
+ case EvqVaryingOut:
+ return "";
+ case EvqVertexOut:
+ return "";
+ case EvqSmoothOut:
+ return "linear";
+ case EvqFlatOut:
+ return "nointerpolation";
+ case EvqCentroidOut:
+ return "centroid";
+ case EvqSampleIn:
+ return "sample";
+ default:
+ UNREACHABLE();
+ }
+
+ return "";
+}
+
+const char *QualifierString(TQualifier qualifier)
+{
+ switch (qualifier)
+ {
+ case EvqParamIn:
+ return "in";
+ case EvqParamOut:
+ return "inout"; // 'out' results in an HLSL error if not all fields are written, for
+ // GLSL it's undefined
+ case EvqParamInOut:
+ return "inout";
+ case EvqParamConst:
+ return "const";
+ case EvqSampleOut:
+ return "sample";
+ default:
+ UNREACHABLE();
+ }
+
+ return "";
+}
+
+TString DisambiguateFunctionName(const TFunction *func)
+{
+ TString disambiguatingString;
+ size_t paramCount = func->getParamCount();
+ for (size_t i = 0; i < paramCount; ++i)
+ {
+ DisambiguateFunctionNameForParameterType(func->getParam(i)->getType(),
+ &disambiguatingString);
+ }
+ return disambiguatingString;
+}
+
+TString DisambiguateFunctionName(const TIntermSequence *args)
+{
+ TString disambiguatingString;
+ for (TIntermNode *arg : *args)
+ {
+ ASSERT(arg->getAsTyped());
+ DisambiguateFunctionNameForParameterType(arg->getAsTyped()->getType(),
+ &disambiguatingString);
+ }
+ return disambiguatingString;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/UtilsHLSL.h b/gfx/angle/checkout/src/compiler/translator/UtilsHLSL.h
new file mode 100644
index 0000000000..722b61f3ca
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/UtilsHLSL.h
@@ -0,0 +1,148 @@
+//
+// 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.
+//
+// UtilsHLSL.h:
+// Utility methods for GLSL to HLSL translation.
+//
+
+#ifndef COMPILER_TRANSLATOR_UTILSHLSL_H_
+#define COMPILER_TRANSLATOR_UTILSHLSL_H_
+
+#include <vector>
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/Types.h"
+
+#include "angle_gl.h"
+
+namespace sh
+{
+
+class TFunction;
+
+// HLSL Texture type for GLSL sampler type and readonly image type.
+enum HLSLTextureGroup
+{
+ // read resources
+ HLSL_TEXTURE_2D,
+ HLSL_TEXTURE_MIN = HLSL_TEXTURE_2D,
+
+ HLSL_TEXTURE_CUBE,
+ HLSL_TEXTURE_2D_ARRAY,
+ HLSL_TEXTURE_3D,
+ HLSL_TEXTURE_2D_UNORM,
+ HLSL_TEXTURE_CUBE_UNORM,
+ HLSL_TEXTURE_2D_ARRAY_UNORN,
+ HLSL_TEXTURE_3D_UNORM,
+ HLSL_TEXTURE_2D_SNORM,
+ HLSL_TEXTURE_CUBE_SNORM,
+ HLSL_TEXTURE_2D_ARRAY_SNORM,
+ HLSL_TEXTURE_3D_SNORM,
+ HLSL_TEXTURE_2D_MS,
+ HLSL_TEXTURE_2D_MS_ARRAY,
+ HLSL_TEXTURE_2D_INT4,
+ HLSL_TEXTURE_3D_INT4,
+ HLSL_TEXTURE_2D_ARRAY_INT4,
+ HLSL_TEXTURE_2D_MS_INT4,
+ HLSL_TEXTURE_2D_MS_ARRAY_INT4,
+ HLSL_TEXTURE_2D_UINT4,
+ HLSL_TEXTURE_3D_UINT4,
+ HLSL_TEXTURE_2D_ARRAY_UINT4,
+ HLSL_TEXTURE_2D_MS_UINT4,
+ HLSL_TEXTURE_2D_MS_ARRAY_UINT4,
+
+ HLSL_TEXTURE_BUFFER,
+ HLSL_TEXTURE_BUFFER_UNORM,
+ HLSL_TEXTURE_BUFFER_SNORM,
+ HLSL_TEXTURE_BUFFER_UINT4,
+ HLSL_TEXTURE_BUFFER_INT4,
+
+ // Comparison samplers
+
+ HLSL_TEXTURE_2D_COMPARISON,
+ HLSL_TEXTURE_CUBE_COMPARISON,
+ HLSL_TEXTURE_2D_ARRAY_COMPARISON,
+
+ HLSL_COMPARISON_SAMPLER_GROUP_BEGIN = HLSL_TEXTURE_2D_COMPARISON,
+ HLSL_COMPARISON_SAMPLER_GROUP_END = HLSL_TEXTURE_2D_ARRAY_COMPARISON,
+
+ HLSL_TEXTURE_UNKNOWN,
+ HLSL_TEXTURE_MAX = HLSL_TEXTURE_UNKNOWN
+};
+
+// HLSL RWTexture type for GLSL read and write image type.
+enum HLSLRWTextureGroup
+{
+ // read/write resource
+ HLSL_RWTEXTURE_2D_FLOAT4,
+ HLSL_RWTEXTURE_MIN = HLSL_RWTEXTURE_2D_FLOAT4,
+ HLSL_RWTEXTURE_2D_ARRAY_FLOAT4,
+ HLSL_RWTEXTURE_3D_FLOAT4,
+ HLSL_RWTEXTURE_2D_UNORM,
+ HLSL_RWTEXTURE_2D_ARRAY_UNORN,
+ HLSL_RWTEXTURE_3D_UNORM,
+ HLSL_RWTEXTURE_2D_SNORM,
+ HLSL_RWTEXTURE_2D_ARRAY_SNORM,
+ HLSL_RWTEXTURE_3D_SNORM,
+ HLSL_RWTEXTURE_2D_UINT4,
+ HLSL_RWTEXTURE_2D_ARRAY_UINT4,
+ HLSL_RWTEXTURE_3D_UINT4,
+ HLSL_RWTEXTURE_2D_INT4,
+ HLSL_RWTEXTURE_2D_ARRAY_INT4,
+ HLSL_RWTEXTURE_3D_INT4,
+
+ HLSL_RWTEXTURE_BUFFER_FLOAT4,
+ HLSL_RWTEXTURE_BUFFER_UNORM,
+ HLSL_RWTEXTURE_BUFFER_SNORM,
+ HLSL_RWTEXTURE_BUFFER_UINT4,
+ HLSL_RWTEXTURE_BUFFER_INT4,
+
+ HLSL_RWTEXTURE_UNKNOWN,
+ HLSL_RWTEXTURE_MAX = HLSL_RWTEXTURE_UNKNOWN
+};
+
+HLSLTextureGroup TextureGroup(const TBasicType type,
+ TLayoutImageInternalFormat imageInternalFormat = EiifUnspecified);
+const char *TextureString(const HLSLTextureGroup textureGroup);
+const char *TextureString(const TBasicType type,
+ TLayoutImageInternalFormat imageInternalFormat = EiifUnspecified);
+const char *TextureGroupSuffix(const HLSLTextureGroup type);
+const char *TextureGroupSuffix(const TBasicType type,
+ TLayoutImageInternalFormat imageInternalFormat = EiifUnspecified);
+const char *TextureTypeSuffix(const TBasicType type,
+ TLayoutImageInternalFormat imageInternalFormat = EiifUnspecified);
+HLSLRWTextureGroup RWTextureGroup(const TBasicType type,
+ TLayoutImageInternalFormat imageInternalFormat);
+const char *RWTextureString(const HLSLRWTextureGroup textureGroup);
+const char *RWTextureString(const TBasicType type, TLayoutImageInternalFormat imageInternalFormat);
+const char *RWTextureGroupSuffix(const HLSLRWTextureGroup type);
+const char *RWTextureGroupSuffix(const TBasicType type,
+ TLayoutImageInternalFormat imageInternalFormat);
+const char *RWTextureTypeSuffix(const TBasicType type,
+ TLayoutImageInternalFormat imageInternalFormat);
+
+const char *SamplerString(const TBasicType type);
+const char *SamplerString(HLSLTextureGroup type);
+
+// Adds a prefix to user-defined names to avoid naming clashes.
+TString Decorate(const ImmutableString &string);
+TString DecorateVariableIfNeeded(const TVariable &variable);
+TString DecorateFunctionIfNeeded(const TFunction *func);
+TString DecorateField(const ImmutableString &string, const TStructure &structure);
+TString DecoratePrivate(const ImmutableString &privateText);
+TString TypeString(const TType &type);
+TString StructNameString(const TStructure &structure);
+TString QualifiedStructNameString(const TStructure &structure,
+ bool useHLSLRowMajorPacking,
+ bool useStd140Packing,
+ bool forcePackingEnd);
+const char *InterpolationString(TQualifier qualifier);
+const char *QualifierString(TQualifier qualifier);
+// Parameters may need to be included in function names to disambiguate between overloaded
+// functions.
+TString DisambiguateFunctionName(const TFunction *func);
+TString DisambiguateFunctionName(const TIntermSequence *args);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_UTILSHLSL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/ValidateAST.cpp b/gfx/angle/checkout/src/compiler/translator/ValidateAST.cpp
new file mode 100644
index 0000000000..faba9a9a82
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateAST.cpp
@@ -0,0 +1,1133 @@
+//
+// Copyright 2019 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/ValidateAST.h"
+
+#include "common/utilities.h"
+#include "compiler/translator/Diagnostics.h"
+#include "compiler/translator/ImmutableStringBuilder.h"
+#include "compiler/translator/Symbol.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/tree_util/SpecializationConstant.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class ValidateAST : public TIntermTraverser
+{
+ public:
+ static bool validate(TIntermNode *root,
+ TDiagnostics *diagnostics,
+ const ValidateASTOptions &options);
+
+ 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 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;
+ void visitFunctionPrototype(TIntermFunctionPrototype *node) override;
+ bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override;
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override;
+ bool visitBlock(Visit visit, TIntermBlock *node) override;
+ bool visitGlobalQualifierDeclaration(Visit visit,
+ TIntermGlobalQualifierDeclaration *node) override;
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
+ bool visitLoop(Visit visit, TIntermLoop *node) override;
+ bool visitBranch(Visit visit, TIntermBranch *node) override;
+ void visitPreprocessorDirective(TIntermPreprocessorDirective *node) override;
+
+ private:
+ ValidateAST(TIntermNode *root, TDiagnostics *diagnostics, const ValidateASTOptions &options);
+
+ // Visit as a generic node
+ void visitNode(Visit visit, TIntermNode *node);
+ // Visit a structure or interface block, and recursively visit its fields of structure type.
+ void visitStructOrInterfaceBlockDeclaration(const TType &type, const TSourceLoc &location);
+ void visitStructUsage(const TType &type, const TSourceLoc &location);
+ // Visit a unary or aggregate node and validate its built-in op against its built-in function.
+ void visitBuiltInFunction(TIntermOperator *op, const TFunction *function);
+ // Visit an aggregate node and validate its function call is to one that's already defined.
+ void visitFunctionCall(TIntermAggregate *node);
+ // Visit a binary node and validate its type against its operands.
+ void validateExpressionTypeBinary(TIntermBinary *node);
+ // Visit a switch node and validate its selector type is integer.
+ void validateExpressionTypeSwitch(TIntermSwitch *node);
+ // Visit a symbol node and validate it's declared previously.
+ void visitVariableNeedingDeclaration(TIntermSymbol *node);
+ // Visit a built-in symbol node and validate it's consistently used across the tree.
+ void visitBuiltInVariable(TIntermSymbol *node);
+
+ void scope(Visit visit);
+ bool isVariableDeclared(const TVariable *variable);
+ bool variableNeedsDeclaration(const TVariable *variable);
+ const TFieldListCollection *getStructOrInterfaceBlock(const TType &type,
+ ImmutableString *typeNameOut);
+
+ void expectNonNullChildren(Visit visit, TIntermNode *node, size_t least_count);
+
+ bool validateInternal();
+
+ ValidateASTOptions mOptions;
+ TDiagnostics *mDiagnostics;
+
+ // For validateSingleParent:
+ std::map<TIntermNode *, TIntermNode *> mParent;
+ bool mSingleParentFailed = false;
+
+ // For validateVariableReferences:
+ std::vector<std::set<const TVariable *>> mDeclaredVariables;
+ std::set<const TInterfaceBlock *> mNamelessInterfaceBlocks;
+ std::map<ImmutableString, const TVariable *> mReferencedBuiltIns;
+ bool mVariableReferencesFailed = false;
+
+ // For validateBuiltInOps:
+ bool mBuiltInOpsFailed = false;
+
+ // For validateFunctionCall:
+ std::set<const TFunction *> mDeclaredFunctions;
+ bool mFunctionCallFailed = false;
+
+ // For validateNoRawFunctionCalls:
+ bool mNoRawFunctionCallsFailed = false;
+
+ // For validateNullNodes:
+ bool mNullNodesFailed = false;
+
+ // For validateQualifiers:
+ bool mQualifiersFailed = false;
+
+ // For validatePrecision:
+ bool mPrecisionFailed = false;
+
+ // For validateStructUsage:
+ std::vector<std::map<ImmutableString, const TFieldListCollection *>> mStructsAndBlocksByName;
+ bool mStructUsageFailed = false;
+
+ // For validateExpressionTypes:
+ bool mExpressionTypesFailed = false;
+
+ // For validateMultiDeclarations:
+ bool mMultiDeclarationsFailed = false;
+
+ // For validateNoSwizzleOfSwizzle:
+ bool mNoSwizzleOfSwizzleFailed = false;
+
+ // For validateNoStatementsAfterBranch:
+ bool mIsBranchVisitedInBlock = false;
+ bool mNoStatementsAfterBranchFailed = false;
+};
+
+bool IsSameType(const TType &a, const TType &b)
+{
+ return a.getBasicType() == b.getBasicType() && a.getNominalSize() == b.getNominalSize() &&
+ a.getSecondarySize() == b.getSecondarySize() && a.getArraySizes() == b.getArraySizes() &&
+ a.getStruct() == b.getStruct() &&
+ (!a.isInterfaceBlock() || a.getInterfaceBlock() == b.getInterfaceBlock());
+}
+
+bool ValidateAST::validate(TIntermNode *root,
+ TDiagnostics *diagnostics,
+ const ValidateASTOptions &options)
+{
+ ValidateAST validate(root, diagnostics, options);
+ root->traverse(&validate);
+ return validate.validateInternal();
+}
+
+ValidateAST::ValidateAST(TIntermNode *root,
+ TDiagnostics *diagnostics,
+ const ValidateASTOptions &options)
+ : TIntermTraverser(true, false, true, nullptr), mOptions(options), mDiagnostics(diagnostics)
+{
+ bool isTreeRoot = root->getAsBlock() && root->getAsBlock()->isTreeRoot();
+
+ // Some validations are not applicable unless run on the entire tree.
+ if (!isTreeRoot)
+ {
+ mOptions.validateVariableReferences = false;
+ mOptions.validateFunctionCall = false;
+ mOptions.validateStructUsage = false;
+ }
+
+ if (mOptions.validateSingleParent)
+ {
+ mParent[root] = nullptr;
+ }
+}
+
+void ValidateAST::visitNode(Visit visit, TIntermNode *node)
+{
+ if (visit == PreVisit && mOptions.validateSingleParent)
+ {
+ size_t childCount = node->getChildCount();
+ for (size_t i = 0; i < childCount; ++i)
+ {
+ TIntermNode *child = node->getChildNode(i);
+ if (mParent.find(child) != mParent.end())
+ {
+ // If child is visited twice but through the same parent, the problem is in one of
+ // the ancestors.
+ if (mParent[child] != node)
+ {
+ mDiagnostics->error(node->getLine(), "Found child with two parents",
+ "<validateSingleParent>");
+ mSingleParentFailed = true;
+ }
+ }
+
+ mParent[child] = node;
+ }
+ }
+
+ if (visit == PreVisit && mOptions.validateNoStatementsAfterBranch)
+ {
+ // If a branch has already been visited in this block, there should be no statements that
+ // follow. Only expected node visit should be PostVisit of the block.
+ if (mIsBranchVisitedInBlock)
+ {
+ mDiagnostics->error(node->getLine(), "Found dead code after branch",
+ "<validateNoStatementsAfterBranch>");
+ mNoStatementsAfterBranchFailed = true;
+ }
+ }
+}
+
+void ValidateAST::visitStructOrInterfaceBlockDeclaration(const TType &type,
+ const TSourceLoc &location)
+{
+ if (type.getStruct() == nullptr && type.getInterfaceBlock() == nullptr)
+ {
+ return;
+ }
+
+ // Make sure the structure or interface block is not doubly defined.
+ ImmutableString typeName("");
+ const TFieldListCollection *namedStructOrBlock = getStructOrInterfaceBlock(type, &typeName);
+
+ // Recurse the fields of the structure or interface block and check members of structure type.
+ // This is done before visiting the struct itself, because if the fields refer to a struct with
+ // the same name, they would be referencing the struct declared in an outer scope.
+ {
+ // Note that structOrBlock was previously only set for named structures, so make sure
+ // nameless structs are also recursed.
+ const TFieldListCollection *structOrBlock = namedStructOrBlock;
+ if (structOrBlock == nullptr)
+ {
+ structOrBlock = type.getStruct();
+ }
+ ASSERT(structOrBlock != nullptr);
+
+ for (const TField *field : structOrBlock->fields())
+ {
+ visitStructUsage(*field->type(), field->line());
+ }
+ }
+
+ if (namedStructOrBlock)
+ {
+ ASSERT(!typeName.empty());
+ // Structures are not allowed to be doubly defined
+ if (type.getStruct() == nullptr)
+ {
+ // Allow interfaces to be doubly-defined.
+ std::string name(typeName.data());
+
+ if (IsShaderIn(type.getQualifier()))
+ {
+ typeName = ImmutableString(name + "<input>");
+ }
+ else if (IsShaderOut(type.getQualifier()))
+ {
+ typeName = ImmutableString(name + "<output>");
+ }
+ else if (IsStorageBuffer(type.getQualifier()))
+ {
+ typeName = ImmutableString(name + "<buffer>");
+ }
+ else if (type.getQualifier() == EvqUniform)
+ {
+ typeName = ImmutableString(name + "<uniform>");
+ }
+ }
+
+ if (mStructsAndBlocksByName.back().find(typeName) != mStructsAndBlocksByName.back().end())
+ {
+ mDiagnostics->error(location,
+ "Found redeclaration of struct or interface block with the same "
+ "name in the same scope <validateStructUsage>",
+ typeName.data());
+ mStructUsageFailed = true;
+ }
+ else
+ {
+ // First encounter.
+ mStructsAndBlocksByName.back()[typeName] = namedStructOrBlock;
+ }
+ }
+}
+
+void ValidateAST::visitStructUsage(const TType &type, const TSourceLoc &location)
+{
+ if (type.getStruct() == nullptr)
+ {
+ return;
+ }
+
+ // Make sure the structure being referenced has the same pointer as the closest (in scope)
+ // definition.
+ const TStructure *structure = type.getStruct();
+ const ImmutableString &typeName = structure->name();
+
+ bool foundDeclaration = false;
+ for (size_t scopeIndex = mStructsAndBlocksByName.size(); scopeIndex > 0; --scopeIndex)
+ {
+ const std::map<ImmutableString, const TFieldListCollection *> &scopeDecls =
+ mStructsAndBlocksByName[scopeIndex - 1];
+
+ auto iter = scopeDecls.find(typeName);
+ if (iter != scopeDecls.end())
+ {
+ foundDeclaration = true;
+
+ if (iter->second != structure)
+ {
+ mDiagnostics->error(location,
+ "Found reference to struct or interface block with doubly "
+ "created type <validateStructUsage>",
+ typeName.data());
+ mStructUsageFailed = true;
+ }
+
+ break;
+ }
+ }
+
+ if (!foundDeclaration)
+ {
+ mDiagnostics->error(location,
+ "Found reference to struct or interface block with no declaration "
+ "<validateStructUsage>",
+ typeName.data());
+ mStructUsageFailed = true;
+ }
+}
+
+void ValidateAST::visitBuiltInFunction(TIntermOperator *node, const TFunction *function)
+{
+ const TOperator op = node->getOp();
+ if (!BuiltInGroup::IsBuiltIn(op))
+ {
+ return;
+ }
+
+ ImmutableStringBuilder opValueBuilder(16);
+ opValueBuilder << "op: ";
+ opValueBuilder.appendDecimal(op);
+
+ ImmutableString opValue = opValueBuilder;
+
+ if (function == nullptr)
+ {
+ mDiagnostics->error(node->getLine(),
+ "Found node calling built-in without a reference to the built-in "
+ "function <validateBuiltInOps>",
+ opValue.data());
+ mVariableReferencesFailed = true;
+ }
+ else if (function->getBuiltInOp() != op)
+ {
+ mDiagnostics->error(node->getLine(),
+ "Found node calling built-in with a reference to a different function "
+ "<validateBuiltInOps>",
+ opValue.data());
+ mVariableReferencesFailed = true;
+ }
+}
+
+void ValidateAST::visitFunctionCall(TIntermAggregate *node)
+{
+ if (node->getOp() != EOpCallFunctionInAST)
+ {
+ return;
+ }
+
+ const TFunction *function = node->getFunction();
+
+ if (function == nullptr)
+ {
+ mDiagnostics->error(node->getLine(),
+ "Found node calling function without a reference to it",
+ "<validateFunctionCall>");
+ mFunctionCallFailed = true;
+ }
+ else if (mDeclaredFunctions.find(function) == mDeclaredFunctions.end())
+ {
+ mDiagnostics->error(node->getLine(),
+ "Found node calling previously undeclared function "
+ "<validateFunctionCall>",
+ function->name().data());
+ mFunctionCallFailed = true;
+ }
+}
+
+void ValidateAST::validateExpressionTypeBinary(TIntermBinary *node)
+{
+ switch (node->getOp())
+ {
+ case EOpIndexDirect:
+ case EOpIndexIndirect:
+ {
+ TType expectedType(node->getLeft()->getType());
+ if (!expectedType.isArray())
+ {
+ // TODO: Validate matrix column selection and vector component selection.
+ // http://anglebug.com/2733
+ break;
+ }
+
+ expectedType.toArrayElementType();
+
+ if (!IsSameType(node->getType(), expectedType))
+ {
+ const TSymbol *symbol = expectedType.getStruct();
+ if (symbol == nullptr)
+ {
+ symbol = expectedType.getInterfaceBlock();
+ }
+ const char *name = nullptr;
+ if (symbol)
+ {
+ name = symbol->name().data();
+ }
+ else if (expectedType.isScalar())
+ {
+ name = "<scalar array>";
+ }
+ else if (expectedType.isVector())
+ {
+ name = "<vector array>";
+ }
+ else
+ {
+ ASSERT(expectedType.isMatrix());
+ name = "<matrix array>";
+ }
+
+ mDiagnostics->error(
+ node->getLine(),
+ "Found index node with type that is inconsistent with the array being indexed "
+ "<validateExpressionTypes>",
+ name);
+ mExpressionTypesFailed = true;
+ }
+ }
+ break;
+ default:
+ // TODO: Validate other expressions. http://anglebug.com/2733
+ break;
+ }
+
+ switch (node->getOp())
+ {
+ case EOpIndexDirect:
+ case EOpIndexDirectStruct:
+ case EOpIndexDirectInterfaceBlock:
+ if (node->getRight()->getAsConstantUnion() == nullptr)
+ {
+ mDiagnostics->error(node->getLine(),
+ "Found direct index node with a non-constant index",
+ "<validateExpressionTypes>");
+ mExpressionTypesFailed = true;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void ValidateAST::validateExpressionTypeSwitch(TIntermSwitch *node)
+{
+ const TType &selectorType = node->getInit()->getType();
+
+ if (selectorType.getBasicType() != EbtYuvCscStandardEXT &&
+ selectorType.getBasicType() != EbtInt && selectorType.getBasicType() != EbtUInt)
+ {
+ mDiagnostics->error(node->getLine(), "Found switch selector expression that is not integer",
+ "<validateExpressionTypes>");
+ mExpressionTypesFailed = true;
+ }
+ else if (!selectorType.isScalar())
+ {
+ mDiagnostics->error(node->getLine(), "Found switch selector expression that is not scalar",
+ "<validateExpressionTypes>");
+ mExpressionTypesFailed = true;
+ }
+}
+
+void ValidateAST::visitVariableNeedingDeclaration(TIntermSymbol *node)
+{
+ const TVariable *variable = &node->variable();
+ const TType &type = node->getType();
+
+ // If it's a reference to a field of a nameless interface block, match it by index and name.
+ if (type.getInterfaceBlock() && !type.isInterfaceBlock())
+ {
+ const TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
+ const TFieldList &fieldList = interfaceBlock->fields();
+ const size_t fieldIndex = type.getInterfaceBlockFieldIndex();
+
+ if (mNamelessInterfaceBlocks.count(interfaceBlock) == 0)
+ {
+ mDiagnostics->error(node->getLine(),
+ "Found reference to undeclared or inconsistenly transformed "
+ "nameless interface block <validateVariableReferences>",
+ node->getName().data());
+ mVariableReferencesFailed = true;
+ }
+ else if (fieldIndex >= fieldList.size() || node->getName() != fieldList[fieldIndex]->name())
+ {
+ mDiagnostics->error(node->getLine(),
+ "Found reference to inconsistenly transformed nameless "
+ "interface block field <validateVariableReferences>",
+ node->getName().data());
+ mVariableReferencesFailed = true;
+ }
+ return;
+ }
+
+ const bool isStructDeclaration =
+ type.isStructSpecifier() && variable->symbolType() == SymbolType::Empty;
+
+ if (!isStructDeclaration && !isVariableDeclared(variable))
+ {
+ mDiagnostics->error(node->getLine(),
+ "Found reference to undeclared or inconsistently transformed "
+ "variable <validateVariableReferences>",
+ node->getName().data());
+ mVariableReferencesFailed = true;
+ }
+}
+
+void ValidateAST::visitBuiltInVariable(TIntermSymbol *node)
+{
+ const TVariable *variable = &node->variable();
+ ImmutableString name = variable->name();
+
+ if (mOptions.validateVariableReferences)
+ {
+ auto iter = mReferencedBuiltIns.find(name);
+ if (iter == mReferencedBuiltIns.end())
+ {
+ mReferencedBuiltIns[name] = variable;
+ return;
+ }
+
+ if (variable != iter->second)
+ {
+ mDiagnostics->error(
+ node->getLine(),
+ "Found inconsistent references to built-in variable <validateVariableReferences>",
+ name.data());
+ mVariableReferencesFailed = true;
+ }
+ }
+
+ if (mOptions.validateQualifiers)
+ {
+ TQualifier qualifier = variable->getType().getQualifier();
+
+ if ((name == "gl_ClipDistance" && qualifier != EvqClipDistance) ||
+ (name == "gl_CullDistance" && qualifier != EvqCullDistance) ||
+ (name == "gl_LastFragData" && qualifier != EvqLastFragData))
+ {
+ mDiagnostics->error(
+ node->getLine(),
+ "Incorrect qualifier applied to redeclared built-in <validateQualifiers>",
+ name.data());
+ mQualifiersFailed = true;
+ }
+ }
+}
+
+void ValidateAST::scope(Visit visit)
+{
+ if (mOptions.validateVariableReferences)
+ {
+ if (visit == PreVisit)
+ {
+ mDeclaredVariables.push_back({});
+ }
+ else if (visit == PostVisit)
+ {
+ mDeclaredVariables.pop_back();
+ }
+ }
+
+ if (mOptions.validateStructUsage)
+ {
+ if (visit == PreVisit)
+ {
+ mStructsAndBlocksByName.push_back({});
+ }
+ else if (visit == PostVisit)
+ {
+ mStructsAndBlocksByName.pop_back();
+ }
+ }
+}
+
+bool ValidateAST::isVariableDeclared(const TVariable *variable)
+{
+ ASSERT(mOptions.validateVariableReferences);
+
+ for (const std::set<const TVariable *> &scopeVariables : mDeclaredVariables)
+ {
+ if (scopeVariables.count(variable) > 0)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool ValidateAST::variableNeedsDeclaration(const TVariable *variable)
+{
+ // Don't expect declaration for built-in variables.
+ if (gl::IsBuiltInName(variable->name().data()))
+ {
+ return false;
+ }
+
+ // Additionally, don't expect declaration for Vulkan specialization constants if not enabled.
+ // The declaration of these variables is deferred.
+ if (variable->getType().getQualifier() == EvqSpecConst)
+ {
+ return mOptions.validateSpecConstReferences;
+ }
+
+ return true;
+}
+
+const TFieldListCollection *ValidateAST::getStructOrInterfaceBlock(const TType &type,
+ ImmutableString *typeNameOut)
+{
+ const TStructure *structure = type.getStruct();
+ const TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
+
+ ASSERT(structure != nullptr || interfaceBlock != nullptr);
+
+ // Make sure the structure or interface block is not doubly defined.
+ const TFieldListCollection *structOrBlock = nullptr;
+ if (structure != nullptr && structure->symbolType() != SymbolType::Empty)
+ {
+ structOrBlock = structure;
+ *typeNameOut = structure->name();
+ }
+ else if (interfaceBlock != nullptr)
+ {
+ structOrBlock = interfaceBlock;
+ *typeNameOut = interfaceBlock->name();
+ }
+
+ return structOrBlock;
+}
+
+void ValidateAST::expectNonNullChildren(Visit visit, TIntermNode *node, size_t least_count)
+{
+ if (visit == PreVisit && mOptions.validateNullNodes)
+ {
+ size_t childCount = node->getChildCount();
+ if (childCount < least_count)
+ {
+ mDiagnostics->error(node->getLine(), "Too few children", "<validateNullNodes>");
+ mNullNodesFailed = true;
+ }
+
+ for (size_t i = 0; i < childCount; ++i)
+ {
+ if (node->getChildNode(i) == nullptr)
+ {
+ mDiagnostics->error(node->getLine(), "Found nullptr child", "<validateNullNodes>");
+ mNullNodesFailed = true;
+ }
+ }
+ }
+}
+
+void ValidateAST::visitSymbol(TIntermSymbol *node)
+{
+ visitNode(PreVisit, node);
+
+ const TVariable *variable = &node->variable();
+
+ if (mOptions.validateVariableReferences)
+ {
+ if (variableNeedsDeclaration(variable))
+ {
+ visitVariableNeedingDeclaration(node);
+ }
+ }
+
+ const bool isBuiltIn = gl::IsBuiltInName(variable->name().data());
+ if (isBuiltIn)
+ {
+ visitBuiltInVariable(node);
+ }
+
+ if (mOptions.validatePrecision)
+ {
+ if (!isBuiltIn && IsPrecisionApplicableToType(node->getBasicType()) &&
+ node->getType().getPrecision() == EbpUndefined)
+ {
+ // Note that some built-ins don't have a precision.
+ mDiagnostics->error(node->getLine(),
+ "Found symbol with undefined precision <validatePrecision>",
+ variable->name().data());
+ mPrecisionFailed = true;
+ }
+ }
+}
+
+void ValidateAST::visitConstantUnion(TIntermConstantUnion *node)
+{
+ visitNode(PreVisit, node);
+}
+
+bool ValidateAST::visitSwizzle(Visit visit, TIntermSwizzle *node)
+{
+ visitNode(visit, node);
+
+ if (mOptions.validateNoSwizzleOfSwizzle)
+ {
+ if (node->getOperand()->getAsSwizzleNode() != nullptr)
+ {
+ mDiagnostics->error(node->getLine(), "Found swizzle applied to swizzle",
+ "<validateNoSwizzleOfSwizzle>");
+ mNoSwizzleOfSwizzleFailed = true;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateAST::visitBinary(Visit visit, TIntermBinary *node)
+{
+ visitNode(visit, node);
+
+ if (mOptions.validateExpressionTypes && visit == PreVisit)
+ {
+ validateExpressionTypeBinary(node);
+ }
+
+ return true;
+}
+
+bool ValidateAST::visitUnary(Visit visit, TIntermUnary *node)
+{
+ visitNode(visit, node);
+
+ if (visit == PreVisit && mOptions.validateBuiltInOps)
+ {
+ visitBuiltInFunction(node, node->getFunction());
+ }
+
+ return true;
+}
+
+bool ValidateAST::visitTernary(Visit visit, TIntermTernary *node)
+{
+ visitNode(visit, node);
+ return true;
+}
+
+bool ValidateAST::visitIfElse(Visit visit, TIntermIfElse *node)
+{
+ visitNode(visit, node);
+ return true;
+}
+
+bool ValidateAST::visitSwitch(Visit visit, TIntermSwitch *node)
+{
+ visitNode(visit, node);
+
+ if (mOptions.validateExpressionTypes && visit == PreVisit)
+ {
+ validateExpressionTypeSwitch(node);
+ }
+
+ return true;
+}
+
+bool ValidateAST::visitCase(Visit visit, TIntermCase *node)
+{
+ // Case is allowed to come after a branch, and for dead-code-elimination purposes acts as if a
+ // new block is started.
+ mIsBranchVisitedInBlock = false;
+
+ visitNode(visit, node);
+
+ return true;
+}
+
+void ValidateAST::visitFunctionPrototype(TIntermFunctionPrototype *node)
+{
+ visitNode(PreVisit, node);
+
+ if (mOptions.validateFunctionCall)
+ {
+ const TFunction *function = node->getFunction();
+ mDeclaredFunctions.insert(function);
+ }
+
+ const TFunction *function = node->getFunction();
+ const TType &returnType = function->getReturnType();
+ if (mOptions.validatePrecision && IsPrecisionApplicableToType(returnType.getBasicType()) &&
+ returnType.getPrecision() == EbpUndefined)
+ {
+ mDiagnostics->error(
+ node->getLine(),
+ "Found function with undefined precision on return value <validatePrecision>",
+ function->name().data());
+ mPrecisionFailed = true;
+ }
+
+ if (mOptions.validateStructUsage)
+ {
+ if (returnType.isStructSpecifier())
+ {
+ visitStructOrInterfaceBlockDeclaration(returnType, node->getLine());
+ }
+ else
+ {
+ visitStructUsage(returnType, node->getLine());
+ }
+ }
+
+ for (size_t paramIndex = 0; paramIndex < function->getParamCount(); ++paramIndex)
+ {
+ const TVariable *param = function->getParam(paramIndex);
+ const TType &paramType = param->getType();
+
+ if (mOptions.validateStructUsage)
+ {
+ visitStructUsage(paramType, node->getLine());
+ }
+
+ if (mOptions.validateQualifiers)
+ {
+ TQualifier qualifier = paramType.getQualifier();
+ if (qualifier != EvqParamIn && qualifier != EvqParamOut && qualifier != EvqParamInOut &&
+ qualifier != EvqParamConst)
+ {
+ mDiagnostics->error(node->getLine(),
+ "Found function prototype with an invalid qualifier "
+ "<validateQualifiers>",
+ param->name().data());
+ mQualifiersFailed = true;
+ }
+
+ if (IsOpaqueType(paramType.getBasicType()) && qualifier != EvqParamIn)
+ {
+ mDiagnostics->error(
+ node->getLine(),
+ "Found function prototype with an invalid qualifier on opaque parameter "
+ "<validateQualifiers>",
+ param->name().data());
+ mQualifiersFailed = true;
+ }
+ }
+
+ if (mOptions.validatePrecision && IsPrecisionApplicableToType(paramType.getBasicType()) &&
+ paramType.getPrecision() == EbpUndefined)
+ {
+ mDiagnostics->error(
+ node->getLine(),
+ "Found function parameter with undefined precision <validatePrecision>",
+ param->name().data());
+ mPrecisionFailed = true;
+ }
+ }
+}
+
+bool ValidateAST::visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node)
+{
+ visitNode(visit, node);
+ scope(visit);
+
+ if (mOptions.validateVariableReferences && visit == PreVisit)
+ {
+ const TFunction *function = node->getFunction();
+
+ size_t paramCount = function->getParamCount();
+ for (size_t paramIndex = 0; paramIndex < paramCount; ++paramIndex)
+ {
+ const TVariable *variable = function->getParam(paramIndex);
+
+ if (isVariableDeclared(variable))
+ {
+ mDiagnostics->error(node->getLine(),
+ "Found two declarations of the same function argument "
+ "<validateVariableReferences>",
+ variable->name().data());
+ mVariableReferencesFailed = true;
+ break;
+ }
+
+ mDeclaredVariables.back().insert(variable);
+ }
+ }
+
+ return true;
+}
+
+bool ValidateAST::visitAggregate(Visit visit, TIntermAggregate *node)
+{
+ visitNode(visit, node);
+ expectNonNullChildren(visit, node, 0);
+
+ if (visit == PreVisit && mOptions.validateBuiltInOps)
+ {
+ visitBuiltInFunction(node, node->getFunction());
+ }
+
+ if (visit == PreVisit && mOptions.validateFunctionCall)
+ {
+ visitFunctionCall(node);
+ }
+
+ if (visit == PreVisit && mOptions.validateNoRawFunctionCalls)
+ {
+ if (node->getOp() == EOpCallInternalRawFunction)
+ {
+ mDiagnostics->error(node->getLine(),
+ "Found node calling a raw function (deprecated) "
+ "<validateNoRawFunctionCalls>",
+ node->getFunction()->name().data());
+ mNoRawFunctionCallsFailed = true;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateAST::visitBlock(Visit visit, TIntermBlock *node)
+{
+ visitNode(visit, node);
+ scope(visit);
+ expectNonNullChildren(visit, node, 0);
+
+ if (visit == PostVisit)
+ {
+ // If the parent is a block and mIsBranchVisitedInBlock is set, this is a nested block
+ // without any condition (like if, loop or switch), so the rest of the parent block is also
+ // dead code. Otherwise the parent block can contain code after this.
+ if (getParentNode() == nullptr || getParentNode()->getAsBlock() == nullptr)
+ {
+ mIsBranchVisitedInBlock = false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateAST::visitGlobalQualifierDeclaration(Visit visit,
+ TIntermGlobalQualifierDeclaration *node)
+{
+ visitNode(visit, node);
+
+ const TVariable *variable = &node->getSymbol()->variable();
+
+ if (mOptions.validateVariableReferences && variableNeedsDeclaration(variable))
+ {
+ if (!isVariableDeclared(variable))
+ {
+ mDiagnostics->error(node->getLine(),
+ "Found reference to undeclared or inconsistently transformed "
+ "variable <validateVariableReferences>",
+ variable->name().data());
+ mVariableReferencesFailed = true;
+ }
+ }
+ return true;
+}
+
+bool ValidateAST::visitDeclaration(Visit visit, TIntermDeclaration *node)
+{
+ visitNode(visit, node);
+ expectNonNullChildren(visit, node, 0);
+
+ const TIntermSequence &sequence = *(node->getSequence());
+
+ if (mOptions.validateMultiDeclarations && sequence.size() > 1)
+ {
+ TIntermSymbol *symbol = sequence[1]->getAsSymbolNode();
+ if (symbol == nullptr)
+ {
+ TIntermBinary *init = sequence[1]->getAsBinaryNode();
+ ASSERT(init && init->getOp() == EOpInitialize);
+ symbol = init->getLeft()->getAsSymbolNode();
+ }
+ ASSERT(symbol);
+
+ mDiagnostics->error(node->getLine(),
+ "Found multiple declarations where SeparateDeclarations should have "
+ "separated them <validateMultiDeclarations>",
+ symbol->variable().name().data());
+ mMultiDeclarationsFailed = true;
+ }
+
+ if (visit == PreVisit)
+ {
+ bool validateStructUsage = mOptions.validateStructUsage;
+
+ for (TIntermNode *instance : sequence)
+ {
+ TIntermSymbol *symbol = instance->getAsSymbolNode();
+ if (symbol == nullptr)
+ {
+ TIntermBinary *init = instance->getAsBinaryNode();
+ ASSERT(init && init->getOp() == EOpInitialize);
+ symbol = init->getLeft()->getAsSymbolNode();
+ }
+ ASSERT(symbol);
+
+ const TVariable *variable = &symbol->variable();
+ const TType &type = variable->getType();
+
+ if (mOptions.validateVariableReferences)
+ {
+ if (isVariableDeclared(variable))
+ {
+ mDiagnostics->error(
+ node->getLine(),
+ "Found two declarations of the same variable <validateVariableReferences>",
+ variable->name().data());
+ mVariableReferencesFailed = true;
+ break;
+ }
+
+ mDeclaredVariables.back().insert(variable);
+
+ const TInterfaceBlock *interfaceBlock = variable->getType().getInterfaceBlock();
+
+ if (variable->symbolType() == SymbolType::Empty && interfaceBlock != nullptr)
+ {
+ // Nameless interface blocks can only be declared at the top level. Their
+ // fields are matched by field index, and then verified to match by name.
+ // Conflict in names should have already generated a compile error.
+ ASSERT(mDeclaredVariables.size() == 1);
+ ASSERT(mNamelessInterfaceBlocks.count(interfaceBlock) == 0);
+
+ mNamelessInterfaceBlocks.insert(interfaceBlock);
+ }
+ }
+
+ if (validateStructUsage)
+ {
+ // Only declare and/or validate the struct once.
+ validateStructUsage = false;
+
+ if (type.isStructSpecifier() || type.isInterfaceBlock())
+ {
+ visitStructOrInterfaceBlockDeclaration(type, node->getLine());
+ }
+ else
+ {
+ visitStructUsage(type, node->getLine());
+ }
+ }
+
+ if (gl::IsBuiltInName(variable->name().data()))
+ {
+ visitBuiltInVariable(symbol);
+ }
+
+ if (mOptions.validatePrecision && (type.isStructSpecifier() || type.isInterfaceBlock()))
+ {
+ const TFieldListCollection *structOrBlock = type.getStruct();
+ if (structOrBlock == nullptr)
+ {
+ structOrBlock = type.getInterfaceBlock();
+ }
+
+ for (const TField *field : structOrBlock->fields())
+ {
+ const TType *fieldType = field->type();
+ if (IsPrecisionApplicableToType(fieldType->getBasicType()) &&
+ fieldType->getPrecision() == EbpUndefined)
+ {
+ mDiagnostics->error(
+ node->getLine(),
+ "Found block field with undefined precision <validatePrecision>",
+ field->name().data());
+ mPrecisionFailed = true;
+ }
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+bool ValidateAST::visitLoop(Visit visit, TIntermLoop *node)
+{
+ visitNode(visit, node);
+ return true;
+}
+
+bool ValidateAST::visitBranch(Visit visit, TIntermBranch *node)
+{
+ visitNode(visit, node);
+
+ if (visit == PostVisit)
+ {
+ mIsBranchVisitedInBlock = true;
+ }
+
+ return true;
+}
+
+void ValidateAST::visitPreprocessorDirective(TIntermPreprocessorDirective *node)
+{
+ visitNode(PreVisit, node);
+}
+
+bool ValidateAST::validateInternal()
+{
+ return !mSingleParentFailed && !mVariableReferencesFailed && !mBuiltInOpsFailed &&
+ !mFunctionCallFailed && !mNoRawFunctionCallsFailed && !mNullNodesFailed &&
+ !mQualifiersFailed && !mPrecisionFailed && !mStructUsageFailed &&
+ !mExpressionTypesFailed && !mMultiDeclarationsFailed && !mNoSwizzleOfSwizzleFailed &&
+ !mNoStatementsAfterBranchFailed;
+}
+
+} // anonymous namespace
+
+bool ValidateAST(TIntermNode *root, TDiagnostics *diagnostics, const ValidateASTOptions &options)
+{
+ // ValidateAST is called after transformations, so if |validateNoMoreTransformations| is set,
+ // it's immediately an error.
+ if (options.validateNoMoreTransformations)
+ {
+ diagnostics->error(kNoSourceLoc, "Unexpected transformation after AST post-processing",
+ "<validateNoMoreTransformations>");
+ return false;
+ }
+
+ return ValidateAST::validate(root, diagnostics, options);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/ValidateAST.h b/gfx/angle/checkout/src/compiler/translator/ValidateAST.h
new file mode 100644
index 0000000000..2fa73db9fb
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateAST.h
@@ -0,0 +1,108 @@
+//
+// Copyright 2019 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_VALIDATEAST_H_
+#define COMPILER_TRANSLATOR_VALIDATEAST_H_
+
+#include "compiler/translator/BaseTypes.h"
+#include "compiler/translator/Common.h"
+
+namespace sh
+{
+class TDiagnostics;
+class TIntermNode;
+
+// The following options (stored in Compiler) tell the validator what to validate. Some validations
+// are conditional to certain passes.
+struct ValidateASTOptions
+{
+ // TODO: add support for the flags marked with TODO. http://anglebug.com/2733
+
+ // Check that every node always has only one parent,
+ bool validateSingleParent = true;
+ // Check that all symbols reference TVariables that have been declared. For built-ins, this
+ // makes sure that the same GLSL built-in uses the same TVariable consistently.
+ bool validateVariableReferences = true;
+ // Whether validateVariableReferences should also include specialization constants. Their
+ // declaration is output after their usage is discovered, so this is disabled until then.
+ bool validateSpecConstReferences = false;
+ // Check that TIntermUnary and TIntermAggregate nodes with a built-in op reference a function
+ // with said op.
+ bool validateBuiltInOps = true;
+ // Check that all EOpCallFunctionInAST have their corresponding function definitions in the AST,
+ // with matching symbol ids. There should also be at least a prototype declaration before the
+ // function is called.
+ bool validateFunctionCall = true;
+ // Check that EOpCallInternalRawFunction is not used. This OP is deprecated and needs to be
+ // removed. http://anglebug.com/6059
+ bool validateNoRawFunctionCalls = true;
+ // Check that there are no null nodes where they are not allowed, for example as children of
+ // TIntermDeclaration or TIntermBlock.
+ bool validateNullNodes = true;
+ // Check that symbols that reference variables have consistent qualifiers and symbol ids with
+ // the variable declaration. The following needs to be validated:
+ //
+ // Implemented:
+ //
+ // - Function parameters having one of EvqParam* qualifiers.
+ // - No const qualifier on opaque function parameters.
+ // - gl_ClipDistance, gl_CullDistance and gl_LastFragData are correctly qualified even when
+ // redeclared in the shader.
+ //
+ // TODO:
+ //
+ // - Function-local variables must have the EvqTemporary qualifier.
+ // - Symbol references and declarations have identical qualifiers.
+ bool validateQualifiers = true;
+ // Check that every symbol has its precision specified. That includes variables, block members,
+ // function parameters and return values.
+ bool validatePrecision = true;
+ // Check that variable declarations that can't have initializers don't have initializers
+ // (varyings, uniforms for example).
+ bool validateInitializers = true; // TODO
+ // Check that there is only one TFunction with each function name referenced in the nodes (no
+ // two TFunctions with the same name, taking internal/non-internal namespaces into account).
+ bool validateUniqueFunctions = true; // TODO
+ // Check that references to structs are matched with the corresponding struct declaration.
+ bool validateStructUsage = true;
+ // Check that expression nodes have the correct type considering their operand(s). The
+ // following validation is possible:
+ //
+ // Implemented:
+ //
+ // - Binary node that indexes T[] should have type T
+ // - Binary nodes with EOpIndexDirect* should have a constant as the right node
+ // - Switch nodes should have an integer type in the selector
+ //
+ // TODO:
+ //
+ // - Function calls (including built-ins) have the same return type in the node and function.
+ // - Unary and binary operators have the correct type based on operands
+ // - Swizzle result has same type as the operand except for vector size
+ // - Ternary operator has the same type as the operands
+ // - Case expressions have the same type as the switch selector
+ bool validateExpressionTypes = true;
+ // If SeparateDeclarations has been run, check for the absence of multi declarations as well.
+ bool validateMultiDeclarations = false;
+ // If PruneNoOps has been run, check that no statements are ever added after branches in the
+ // same block. Those statements would be dead code.
+ bool validateNoStatementsAfterBranch = false;
+ // Check that swizzle is not applied to swizzle. Swizzles of swizzles are folded in
+ // TIntermSwizzle::fold.
+ bool validateNoSwizzleOfSwizzle = true;
+
+ // Once set, disallows any further transformations on the tree. Used before AST post-processing
+ // which requires that the tree remains unmodified.
+ bool validateNoMoreTransformations = false;
+};
+
+// Check for errors and output error messages on the context.
+// Returns true if there are no errors.
+bool ValidateAST(TIntermNode *root, TDiagnostics *diagnostics, const ValidateASTOptions &options);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_VALIDATESWITCH_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/ValidateBarrierFunctionCall.cpp b/gfx/angle/checkout/src/compiler/translator/ValidateBarrierFunctionCall.cpp
new file mode 100644
index 0000000000..c36406ea59
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateBarrierFunctionCall.cpp
@@ -0,0 +1,100 @@
+//
+// Copyright 2020 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.
+//
+// ValidateBarrierFunctionCalls:
+// Runs compilation checks related to the "barrier built-in function.
+
+#include "compiler/translator/ValidateBarrierFunctionCall.h"
+
+#include "compiler/translator/Diagnostics.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+namespace
+{
+class Traverser : public TIntermTraverser
+{
+ public:
+ Traverser(TDiagnostics *diagnostics)
+ : TIntermTraverser(true, false, true), mDiagnostics(diagnostics)
+ {}
+
+ bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override
+ {
+ if (!node->getFunction()->isMain())
+ {
+ return false;
+ }
+
+ mInMain = visit == PreVisit;
+ return true;
+ }
+
+ bool visitBranch(Visit visit, TIntermBranch *branch) override
+ {
+ if (branch->getFlowOp() == EOpReturn)
+ {
+ mSeenReturn = true;
+ }
+
+ return true;
+ }
+
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override
+ {
+ if (node->getOp() != EOpBarrierTCS)
+ {
+ return true;
+ }
+
+ if (mSeenReturn)
+ {
+ mDiagnostics->error(node->getLine(),
+ "barrier() may not be called at any point after a return statement "
+ "in the function main().",
+ "barrier");
+ mValid = false;
+ return false;
+ }
+
+ // TODO(anglebug.com/5557): Determine if we should check loops as well.
+ if (mBranchCount > 0)
+ {
+ mDiagnostics->error(
+ node->getLine(),
+ "barrier() may not be called in potentially divergent flow control.", "barrier");
+ mValid = false;
+ return false;
+ }
+
+ return true;
+ }
+
+ bool visitIfElse(Visit visit, TIntermIfElse *node) override
+ {
+ mBranchCount += ((visit == PreVisit) ? 1 : -1);
+ return true;
+ }
+
+ bool valid() const { return mValid; }
+
+ private:
+ TDiagnostics *mDiagnostics = nullptr;
+ bool mInMain = false;
+ bool mSeenReturn = false;
+ bool mValid = true;
+ uint32_t mBranchCount = 0;
+};
+} // anonymous namespace
+
+bool ValidateBarrierFunctionCall(TIntermBlock *root, TDiagnostics *diagnostics)
+{
+ Traverser traverser(diagnostics);
+ root->traverse(&traverser);
+ return traverser.valid();
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/ValidateBarrierFunctionCall.h b/gfx/angle/checkout/src/compiler/translator/ValidateBarrierFunctionCall.h
new file mode 100644
index 0000000000..6b91eb456a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateBarrierFunctionCall.h
@@ -0,0 +1,22 @@
+//
+// Copyright 2020 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.
+//
+// ValidateBarrierFunctionCalls:
+// Runs compilation checks related to the "barrier built-in function.
+
+#ifndef COMPILER_TRANSLATOR_VALIDATEBARRIERFUNCTIONCALL_H_
+#define COMPILER_TRANSLATOR_VALIDATEBARRIERFUNCTIONCALL_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TDiagnostics;
+class TIntermBlock;
+
+[[nodiscard]] bool ValidateBarrierFunctionCall(TIntermBlock *root, TDiagnostics *diagnostics);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_VALIDATEBARRIERFUNCTIONCALL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/ValidateClipCullDistance.cpp b/gfx/angle/checkout/src/compiler/translator/ValidateClipCullDistance.cpp
new file mode 100644
index 0000000000..3ecd8b4295
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateClipCullDistance.cpp
@@ -0,0 +1,200 @@
+//
+// Copyright 2020 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.
+//
+// The ValidateClipCullDistance function checks if the sum of array sizes for gl_ClipDistance and
+// gl_CullDistance exceeds gl_MaxCombinedClipAndCullDistances
+//
+
+#include "ValidateClipCullDistance.h"
+
+#include "compiler/translator/Diagnostics.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+void error(const TIntermSymbol &symbol, const char *reason, TDiagnostics *diagnostics)
+{
+ diagnostics->error(symbol.getLine(), reason, symbol.getName().data());
+}
+
+class ValidateClipCullDistanceTraverser : public TIntermTraverser
+{
+ public:
+ ValidateClipCullDistanceTraverser();
+ void validate(TDiagnostics *diagnostics, const unsigned int maxCombinedClipAndCullDistances);
+
+ private:
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
+ bool visitBinary(Visit visit, TIntermBinary *node) override;
+
+ unsigned int mClipDistanceSize;
+ unsigned int mCullDistanceSize;
+
+ unsigned int mMaxClipDistanceIndex;
+ unsigned int mMaxCullDistanceIndex;
+
+ const TIntermSymbol *mClipDistance;
+ const TIntermSymbol *mCullDistance;
+};
+
+ValidateClipCullDistanceTraverser::ValidateClipCullDistanceTraverser()
+ : TIntermTraverser(true, false, false),
+ mClipDistanceSize(0),
+ mCullDistanceSize(0),
+ mMaxClipDistanceIndex(0),
+ mMaxCullDistanceIndex(0),
+ mClipDistance(nullptr),
+ mCullDistance(nullptr)
+{}
+
+bool ValidateClipCullDistanceTraverser::visitDeclaration(Visit visit, TIntermDeclaration *node)
+{
+ const TIntermSequence &sequence = *(node->getSequence());
+
+ if (sequence.size() != 1)
+ {
+ return true;
+ }
+
+ const TIntermSymbol *symbol = sequence.front()->getAsSymbolNode();
+ if (symbol == nullptr)
+ {
+ return true;
+ }
+
+ if (symbol->getName() == "gl_ClipDistance")
+ {
+ mClipDistanceSize = symbol->getOutermostArraySize();
+ mClipDistance = symbol;
+ }
+ else if (symbol->getName() == "gl_CullDistance")
+ {
+ mCullDistanceSize = symbol->getOutermostArraySize();
+ mCullDistance = symbol;
+ }
+
+ return true;
+}
+
+bool ValidateClipCullDistanceTraverser::visitBinary(Visit visit, TIntermBinary *node)
+{
+ TOperator op = node->getOp();
+ if (op != EOpIndexDirect && op != EOpIndexIndirect)
+ {
+ return true;
+ }
+
+ TIntermSymbol *left = node->getLeft()->getAsSymbolNode();
+ if (!left)
+ {
+ return true;
+ }
+
+ ImmutableString varName(left->getName());
+ if (varName != "gl_ClipDistance" && varName != "gl_CullDistance")
+ {
+ return true;
+ }
+
+ const TConstantUnion *constIdx = node->getRight()->getConstantValue();
+ if (constIdx)
+ {
+ unsigned int idx = 0;
+ switch (constIdx->getType())
+ {
+ case EbtInt:
+ idx = constIdx->getIConst();
+ break;
+ case EbtUInt:
+ idx = constIdx->getUConst();
+ break;
+ case EbtFloat:
+ idx = static_cast<unsigned int>(constIdx->getFConst());
+ break;
+ case EbtBool:
+ idx = constIdx->getBConst() ? 1 : 0;
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ if (varName == "gl_ClipDistance")
+ {
+ if (idx > mMaxClipDistanceIndex)
+ {
+ mMaxClipDistanceIndex = idx;
+ if (!mClipDistance)
+ {
+ mClipDistance = left;
+ }
+ }
+ }
+ else
+ {
+ ASSERT(varName == "gl_CullDistance");
+ if (idx > mMaxCullDistanceIndex)
+ {
+ mMaxCullDistanceIndex = idx;
+ if (!mCullDistance)
+ {
+ mCullDistance = left;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+void ValidateClipCullDistanceTraverser::validate(TDiagnostics *diagnostics,
+ const unsigned int maxCombinedClipAndCullDistances)
+{
+ ASSERT(diagnostics);
+
+ unsigned int enabledClipDistances =
+ (mClipDistanceSize > 0 ? mClipDistanceSize
+ : (mClipDistance ? mMaxClipDistanceIndex + 1 : 0));
+ unsigned int enabledCullDistances =
+ (mCullDistanceSize > 0 ? mCullDistanceSize
+ : (mCullDistance ? mMaxCullDistanceIndex + 1 : 0));
+ unsigned int combinedClipAndCullDistances =
+ (enabledClipDistances > 0 && enabledCullDistances > 0
+ ? enabledClipDistances + enabledCullDistances
+ : 0);
+
+ if (combinedClipAndCullDistances > maxCombinedClipAndCullDistances)
+ {
+ const TIntermSymbol *greaterSymbol =
+ (enabledClipDistances >= enabledCullDistances ? mClipDistance : mCullDistance);
+
+ std::stringstream strstr = sh::InitializeStream<std::stringstream>();
+ strstr << "The sum of 'gl_ClipDistance' and 'gl_CullDistance' size is greater than "
+ "gl_MaxCombinedClipAndCullDistances ("
+ << combinedClipAndCullDistances << " > " << maxCombinedClipAndCullDistances << ")";
+ error(*greaterSymbol, strstr.str().c_str(), diagnostics);
+ }
+}
+
+} // anonymous namespace
+
+bool ValidateClipCullDistance(TIntermBlock *root,
+ TDiagnostics *diagnostics,
+ const unsigned int maxCombinedClipAndCullDistances)
+{
+ ValidateClipCullDistanceTraverser varyingValidator;
+ root->traverse(&varyingValidator);
+ int numErrorsBefore = diagnostics->numErrors();
+ varyingValidator.validate(diagnostics, maxCombinedClipAndCullDistances);
+ return (diagnostics->numErrors() == numErrorsBefore);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/ValidateClipCullDistance.h b/gfx/angle/checkout/src/compiler/translator/ValidateClipCullDistance.h
new file mode 100644
index 0000000000..31ea890cd7
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateClipCullDistance.h
@@ -0,0 +1,27 @@
+//
+// Copyright 2020 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.
+//
+// The ValidateClipCullDistance function checks if the sum of array sizes for gl_ClipDistance and
+// gl_CullDistance exceeds gl_MaxCombinedClipAndCullDistances
+//
+
+#ifndef COMPILER_TRANSLATOR_VALIDATECLIPCULLDISTANCE_H_
+#define COMPILER_TRANSLATOR_VALIDATECLIPCULLDISTANCE_H_
+
+#include "GLSLANG/ShaderVars.h"
+
+namespace sh
+{
+
+class TIntermBlock;
+class TDiagnostics;
+
+bool ValidateClipCullDistance(TIntermBlock *root,
+ TDiagnostics *diagnostics,
+ const unsigned int maxCombinedClipAndCullDistances);
+
+} // namespace sh
+
+#endif
diff --git a/gfx/angle/checkout/src/compiler/translator/ValidateGlobalInitializer.cpp b/gfx/angle/checkout/src/compiler/translator/ValidateGlobalInitializer.cpp
new file mode 100644
index 0000000000..126e8d7854
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateGlobalInitializer.cpp
@@ -0,0 +1,157 @@
+//
+// Copyright 2002 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/ValidateGlobalInitializer.h"
+
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+const int kMaxAllowedTraversalDepth = 256;
+
+class ValidateGlobalInitializerTraverser : public TIntermTraverser
+{
+ public:
+ ValidateGlobalInitializerTraverser(int shaderVersion,
+ bool isWebGL,
+ bool hasExtNonConstGlobalInitializers);
+
+ void visitSymbol(TIntermSymbol *node) override;
+ void visitConstantUnion(TIntermConstantUnion *node) override;
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override;
+ bool visitBinary(Visit visit, TIntermBinary *node) override;
+ bool visitUnary(Visit visit, TIntermUnary *node) override;
+
+ bool isValid() const { return mIsValid && mMaxDepth < mMaxAllowedDepth; }
+ bool issueWarning() const { return mIssueWarning; }
+
+ private:
+ ANGLE_INLINE void onNonConstInitializerVisit(bool accept)
+ {
+ if (accept)
+ {
+ if (!mExtNonConstGlobalInitializers)
+ {
+ mIssueWarning = true;
+ }
+ }
+ else
+ {
+ mIsValid = false;
+ }
+ }
+
+ int mShaderVersion;
+ bool mIsWebGL;
+ bool mExtNonConstGlobalInitializers;
+ bool mIsValid;
+ bool mIssueWarning;
+};
+
+void ValidateGlobalInitializerTraverser::visitSymbol(TIntermSymbol *node)
+{
+ // ESSL 1.00 section 4.3 (or ESSL 3.00 section 4.3):
+ // Global initializers must be constant expressions.
+ switch (node->getType().getQualifier())
+ {
+ case EvqConst:
+ break;
+ case EvqGlobal:
+ case EvqTemporary:
+ case EvqUniform:
+ // We allow these cases to be compatible with legacy ESSL 1.00 content.
+ // Implement stricter rules for ESSL 3.00 since there's no legacy content to deal
+ // with.
+ onNonConstInitializerVisit(mExtNonConstGlobalInitializers ||
+ ((mShaderVersion < 300) && mIsWebGL));
+ break;
+ default:
+ mIsValid = false;
+ }
+}
+
+void ValidateGlobalInitializerTraverser::visitConstantUnion(TIntermConstantUnion *node)
+{
+ // Constant unions that are not constant expressions may result from folding a ternary
+ // expression.
+ switch (node->getType().getQualifier())
+ {
+ case EvqConst:
+ break;
+ case EvqTemporary:
+ onNonConstInitializerVisit(mExtNonConstGlobalInitializers ||
+ ((mShaderVersion < 300) && mIsWebGL));
+ break;
+ default:
+ UNREACHABLE();
+ }
+}
+
+bool ValidateGlobalInitializerTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
+{
+ // Disallow calls to user-defined functions and texture lookup functions in global variable
+ // initializers. For simplicity, all non-math built-in calls are disallowed.
+ if (node->isFunctionCall() ||
+ (BuiltInGroup::IsBuiltIn(node->getOp()) && !BuiltInGroup::IsMath(node->getOp())))
+ {
+ onNonConstInitializerVisit(mExtNonConstGlobalInitializers);
+ }
+ return true;
+}
+
+bool ValidateGlobalInitializerTraverser::visitBinary(Visit visit, TIntermBinary *node)
+{
+ if (node->isAssignment())
+ {
+ onNonConstInitializerVisit(mExtNonConstGlobalInitializers);
+ }
+ return true;
+}
+
+bool ValidateGlobalInitializerTraverser::visitUnary(Visit visit, TIntermUnary *node)
+{
+ if (node->isAssignment())
+ {
+ onNonConstInitializerVisit(mExtNonConstGlobalInitializers);
+ }
+ return true;
+}
+
+ValidateGlobalInitializerTraverser::ValidateGlobalInitializerTraverser(
+ int shaderVersion,
+ bool isWebGL,
+ bool hasExtNonConstGlobalInitializers)
+ : TIntermTraverser(true, false, false, nullptr),
+ mShaderVersion(shaderVersion),
+ mIsWebGL(isWebGL),
+ mExtNonConstGlobalInitializers(hasExtNonConstGlobalInitializers),
+ mIsValid(true),
+ mIssueWarning(false)
+{
+ setMaxAllowedDepth(kMaxAllowedTraversalDepth);
+}
+
+} // namespace
+
+bool ValidateGlobalInitializer(TIntermTyped *initializer,
+ int shaderVersion,
+ bool isWebGL,
+ bool hasExtNonConstGlobalInitializers,
+ bool *warning)
+{
+ ValidateGlobalInitializerTraverser validate(shaderVersion, isWebGL,
+ hasExtNonConstGlobalInitializers);
+ initializer->traverse(&validate);
+ ASSERT(warning != nullptr);
+ *warning = validate.issueWarning();
+ return validate.isValid();
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/ValidateGlobalInitializer.h b/gfx/angle/checkout/src/compiler/translator/ValidateGlobalInitializer.h
new file mode 100644
index 0000000000..cb4b652b18
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateGlobalInitializer.h
@@ -0,0 +1,24 @@
+//
+// Copyright 2002 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_VALIDATEGLOBALINITIALIZER_H_
+#define COMPILER_TRANSLATOR_VALIDATEGLOBALINITIALIZER_H_
+
+namespace sh
+{
+
+class TIntermTyped;
+
+// Returns true if the initializer is valid.
+bool ValidateGlobalInitializer(TIntermTyped *initializer,
+ int shaderVersion,
+ bool isWebGL,
+ bool hasExtNonConstGlobalInitializers,
+ bool *warning);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_VALIDATEGLOBALINITIALIZER_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/ValidateLimitations.cpp b/gfx/angle/checkout/src/compiler/translator/ValidateLimitations.cpp
new file mode 100644
index 0000000000..5ca3daca0f
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateLimitations.cpp
@@ -0,0 +1,452 @@
+//
+// Copyright 2002 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/ValidateLimitations.h"
+
+#include "angle_gl.h"
+#include "compiler/translator/Diagnostics.h"
+#include "compiler/translator/ParseContext.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+int GetLoopSymbolId(TIntermLoop *loop)
+{
+ // Here we assume all the operations are valid, because the loop node is
+ // already validated before this call.
+ TIntermSequence *declSeq = loop->getInit()->getAsDeclarationNode()->getSequence();
+ TIntermBinary *declInit = (*declSeq)[0]->getAsBinaryNode();
+ TIntermSymbol *symbol = declInit->getLeft()->getAsSymbolNode();
+
+ return symbol->uniqueId().get();
+}
+
+// Traverses a node to check if it represents a constant index expression.
+// Definition:
+// constant-index-expressions are a superset of constant-expressions.
+// Constant-index-expressions can include loop indices as defined in
+// GLSL ES 1.0 spec, Appendix A, section 4.
+// The following are constant-index-expressions:
+// - Constant expressions
+// - Loop indices as defined in section 4
+// - Expressions composed of both of the above
+class ValidateConstIndexExpr : public TIntermTraverser
+{
+ public:
+ ValidateConstIndexExpr(const std::vector<int> &loopSymbols)
+ : TIntermTraverser(true, false, false), mValid(true), mLoopSymbolIds(loopSymbols)
+ {}
+
+ // Returns true if the parsed node represents a constant index expression.
+ bool isValid() const { return mValid; }
+
+ void visitSymbol(TIntermSymbol *symbol) override
+ {
+ // Only constants and loop indices are allowed in a
+ // constant index expression.
+ if (mValid)
+ {
+ bool isLoopSymbol = std::find(mLoopSymbolIds.begin(), mLoopSymbolIds.end(),
+ symbol->uniqueId().get()) != mLoopSymbolIds.end();
+ mValid = (symbol->getQualifier() == EvqConst) || isLoopSymbol;
+ }
+ }
+
+ private:
+ bool mValid;
+ const std::vector<int> mLoopSymbolIds;
+};
+
+// Traverses intermediate tree to ensure that the shader does not exceed the
+// minimum functionality mandated in GLSL 1.0 spec, Appendix A.
+class ValidateLimitationsTraverser : public TLValueTrackingTraverser
+{
+ public:
+ ValidateLimitationsTraverser(sh::GLenum shaderType,
+ TSymbolTable *symbolTable,
+ TDiagnostics *diagnostics);
+
+ void visitSymbol(TIntermSymbol *node) override;
+ bool visitBinary(Visit, TIntermBinary *) override;
+ bool visitLoop(Visit, TIntermLoop *) override;
+
+ private:
+ void error(TSourceLoc loc, const char *reason, const char *token);
+ void error(TSourceLoc loc, const char *reason, const ImmutableString &token);
+
+ bool isLoopIndex(TIntermSymbol *symbol);
+ bool validateLoopType(TIntermLoop *node);
+
+ bool validateForLoopHeader(TIntermLoop *node);
+ // If valid, return the index symbol id; Otherwise, return -1.
+ int validateForLoopInit(TIntermLoop *node);
+ bool validateForLoopCond(TIntermLoop *node, int indexSymbolId);
+ bool validateForLoopExpr(TIntermLoop *node, int indexSymbolId);
+
+ // Returns true if indexing does not exceed the minimum functionality
+ // mandated in GLSL 1.0 spec, Appendix A, Section 5.
+ bool isConstExpr(TIntermNode *node);
+ bool isConstIndexExpr(TIntermNode *node);
+ bool validateIndexing(TIntermBinary *node);
+
+ sh::GLenum mShaderType;
+ TDiagnostics *mDiagnostics;
+ std::vector<int> mLoopSymbolIds;
+};
+
+ValidateLimitationsTraverser::ValidateLimitationsTraverser(sh::GLenum shaderType,
+ TSymbolTable *symbolTable,
+ TDiagnostics *diagnostics)
+ : TLValueTrackingTraverser(true, false, false, symbolTable),
+ mShaderType(shaderType),
+ mDiagnostics(diagnostics)
+{
+ ASSERT(diagnostics);
+}
+
+void ValidateLimitationsTraverser::visitSymbol(TIntermSymbol *node)
+{
+ if (isLoopIndex(node) && isLValueRequiredHere())
+ {
+ error(node->getLine(),
+ "Loop index cannot be statically assigned to within the body of the loop",
+ node->getName());
+ }
+}
+
+bool ValidateLimitationsTraverser::visitBinary(Visit, TIntermBinary *node)
+{
+ // Check indexing.
+ switch (node->getOp())
+ {
+ case EOpIndexDirect:
+ case EOpIndexIndirect:
+ validateIndexing(node);
+ break;
+ default:
+ break;
+ }
+ return true;
+}
+
+bool ValidateLimitationsTraverser::visitLoop(Visit, TIntermLoop *node)
+{
+ if (!validateLoopType(node))
+ return false;
+
+ if (!validateForLoopHeader(node))
+ return false;
+
+ TIntermNode *body = node->getBody();
+ if (body != nullptr)
+ {
+ mLoopSymbolIds.push_back(GetLoopSymbolId(node));
+ body->traverse(this);
+ mLoopSymbolIds.pop_back();
+ }
+
+ // The loop is fully processed - no need to visit children.
+ return false;
+}
+
+void ValidateLimitationsTraverser::error(TSourceLoc loc, const char *reason, const char *token)
+{
+ mDiagnostics->error(loc, reason, token);
+}
+
+void ValidateLimitationsTraverser::error(TSourceLoc loc,
+ const char *reason,
+ const ImmutableString &token)
+{
+ error(loc, reason, token.data());
+}
+
+bool ValidateLimitationsTraverser::isLoopIndex(TIntermSymbol *symbol)
+{
+ return std::find(mLoopSymbolIds.begin(), mLoopSymbolIds.end(), symbol->uniqueId().get()) !=
+ mLoopSymbolIds.end();
+}
+
+bool ValidateLimitationsTraverser::validateLoopType(TIntermLoop *node)
+{
+ TLoopType type = node->getType();
+ if (type == ELoopFor)
+ return true;
+
+ // Reject while and do-while loops.
+ error(node->getLine(), "This type of loop is not allowed", type == ELoopWhile ? "while" : "do");
+ return false;
+}
+
+bool ValidateLimitationsTraverser::validateForLoopHeader(TIntermLoop *node)
+{
+ ASSERT(node->getType() == ELoopFor);
+
+ //
+ // The for statement has the form:
+ // for ( init-declaration ; condition ; expression ) statement
+ //
+ int indexSymbolId = validateForLoopInit(node);
+ if (indexSymbolId < 0)
+ return false;
+ if (!validateForLoopCond(node, indexSymbolId))
+ return false;
+ if (!validateForLoopExpr(node, indexSymbolId))
+ return false;
+
+ return true;
+}
+
+int ValidateLimitationsTraverser::validateForLoopInit(TIntermLoop *node)
+{
+ TIntermNode *init = node->getInit();
+ if (init == nullptr)
+ {
+ error(node->getLine(), "Missing init declaration", "for");
+ return -1;
+ }
+
+ //
+ // init-declaration has the form:
+ // type-specifier identifier = constant-expression
+ //
+ TIntermDeclaration *decl = init->getAsDeclarationNode();
+ if (decl == nullptr)
+ {
+ error(init->getLine(), "Invalid init declaration", "for");
+ return -1;
+ }
+ // To keep things simple do not allow declaration list.
+ TIntermSequence *declSeq = decl->getSequence();
+ if (declSeq->size() != 1)
+ {
+ error(decl->getLine(), "Invalid init declaration", "for");
+ return -1;
+ }
+ TIntermBinary *declInit = (*declSeq)[0]->getAsBinaryNode();
+ if ((declInit == nullptr) || (declInit->getOp() != EOpInitialize))
+ {
+ error(decl->getLine(), "Invalid init declaration", "for");
+ return -1;
+ }
+ TIntermSymbol *symbol = declInit->getLeft()->getAsSymbolNode();
+ if (symbol == nullptr)
+ {
+ error(declInit->getLine(), "Invalid init declaration", "for");
+ return -1;
+ }
+ // The loop index has type int or float.
+ TBasicType type = symbol->getBasicType();
+ if ((type != EbtInt) && (type != EbtUInt) && (type != EbtFloat))
+ {
+ error(symbol->getLine(), "Invalid type for loop index", getBasicString(type));
+ return -1;
+ }
+ // The loop index is initialized with constant expression.
+ if (!isConstExpr(declInit->getRight()))
+ {
+ error(declInit->getLine(), "Loop index cannot be initialized with non-constant expression",
+ symbol->getName());
+ return -1;
+ }
+
+ return symbol->uniqueId().get();
+}
+
+bool ValidateLimitationsTraverser::validateForLoopCond(TIntermLoop *node, int indexSymbolId)
+{
+ TIntermNode *cond = node->getCondition();
+ if (cond == nullptr)
+ {
+ error(node->getLine(), "Missing condition", "for");
+ return false;
+ }
+ //
+ // condition has the form:
+ // loop_index relational_operator constant_expression
+ //
+ TIntermBinary *binOp = cond->getAsBinaryNode();
+ if (binOp == nullptr)
+ {
+ error(node->getLine(), "Invalid condition", "for");
+ return false;
+ }
+ // Loop index should be to the left of relational operator.
+ TIntermSymbol *symbol = binOp->getLeft()->getAsSymbolNode();
+ if (symbol == nullptr)
+ {
+ error(binOp->getLine(), "Invalid condition", "for");
+ return false;
+ }
+ if (symbol->uniqueId().get() != indexSymbolId)
+ {
+ error(symbol->getLine(), "Expected loop index", symbol->getName());
+ return false;
+ }
+ // Relational operator is one of: > >= < <= == or !=.
+ switch (binOp->getOp())
+ {
+ case EOpEqual:
+ case EOpNotEqual:
+ case EOpLessThan:
+ case EOpGreaterThan:
+ case EOpLessThanEqual:
+ case EOpGreaterThanEqual:
+ break;
+ default:
+ error(binOp->getLine(), "Invalid relational operator",
+ GetOperatorString(binOp->getOp()));
+ break;
+ }
+ // Loop index must be compared with a constant.
+ if (!isConstExpr(binOp->getRight()))
+ {
+ error(binOp->getLine(), "Loop index cannot be compared with non-constant expression",
+ symbol->getName());
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateLimitationsTraverser::validateForLoopExpr(TIntermLoop *node, int indexSymbolId)
+{
+ TIntermNode *expr = node->getExpression();
+ if (expr == nullptr)
+ {
+ error(node->getLine(), "Missing expression", "for");
+ return false;
+ }
+
+ // for expression has one of the following forms:
+ // loop_index++
+ // loop_index--
+ // loop_index += constant_expression
+ // loop_index -= constant_expression
+ // ++loop_index
+ // --loop_index
+ // The last two forms are not specified in the spec, but I am assuming
+ // its an oversight.
+ TIntermUnary *unOp = expr->getAsUnaryNode();
+ TIntermBinary *binOp = unOp ? nullptr : expr->getAsBinaryNode();
+
+ TOperator op = EOpNull;
+ const TFunction *opFunc = nullptr;
+ TIntermSymbol *symbol = nullptr;
+ if (unOp != nullptr)
+ {
+ op = unOp->getOp();
+ opFunc = unOp->getFunction();
+ symbol = unOp->getOperand()->getAsSymbolNode();
+ }
+ else if (binOp != nullptr)
+ {
+ op = binOp->getOp();
+ symbol = binOp->getLeft()->getAsSymbolNode();
+ }
+
+ // The operand must be loop index.
+ if (symbol == nullptr)
+ {
+ error(expr->getLine(), "Invalid expression", "for");
+ return false;
+ }
+ if (symbol->uniqueId().get() != indexSymbolId)
+ {
+ error(symbol->getLine(), "Expected loop index", symbol->getName());
+ return false;
+ }
+
+ // The operator is one of: ++ -- += -=.
+ switch (op)
+ {
+ case EOpPostIncrement:
+ case EOpPostDecrement:
+ case EOpPreIncrement:
+ case EOpPreDecrement:
+ ASSERT((unOp != nullptr) && (binOp == nullptr));
+ break;
+ case EOpAddAssign:
+ case EOpSubAssign:
+ ASSERT((unOp == nullptr) && (binOp != nullptr));
+ break;
+ default:
+ if (BuiltInGroup::IsBuiltIn(op))
+ {
+ ASSERT(opFunc != nullptr);
+ error(expr->getLine(), "Invalid built-in call", opFunc->name().data());
+ }
+ else
+ {
+ error(expr->getLine(), "Invalid operator", GetOperatorString(op));
+ }
+ return false;
+ }
+
+ // Loop index must be incremented/decremented with a constant.
+ if (binOp != nullptr)
+ {
+ if (!isConstExpr(binOp->getRight()))
+ {
+ error(binOp->getLine(), "Loop index cannot be modified by non-constant expression",
+ symbol->getName());
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateLimitationsTraverser::isConstExpr(TIntermNode *node)
+{
+ ASSERT(node != nullptr);
+ return node->getAsConstantUnion() != nullptr && node->getAsTyped()->getQualifier() == EvqConst;
+}
+
+bool ValidateLimitationsTraverser::isConstIndexExpr(TIntermNode *node)
+{
+ ASSERT(node != nullptr);
+
+ ValidateConstIndexExpr validate(mLoopSymbolIds);
+ node->traverse(&validate);
+ return validate.isValid();
+}
+
+bool ValidateLimitationsTraverser::validateIndexing(TIntermBinary *node)
+{
+ ASSERT((node->getOp() == EOpIndexDirect) || (node->getOp() == EOpIndexIndirect));
+
+ bool valid = true;
+ TIntermTyped *index = node->getRight();
+ // The index expession must be a constant-index-expression unless
+ // the operand is a uniform in a vertex shader.
+ TIntermTyped *operand = node->getLeft();
+ bool skip = (mShaderType == GL_VERTEX_SHADER) && (operand->getQualifier() == EvqUniform);
+ if (!skip && !isConstIndexExpr(index))
+ {
+ error(index->getLine(), "Index expression must be constant", "[]");
+ valid = false;
+ }
+ return valid;
+}
+
+} // namespace
+
+bool ValidateLimitations(TIntermNode *root,
+ GLenum shaderType,
+ TSymbolTable *symbolTable,
+ TDiagnostics *diagnostics)
+{
+ ValidateLimitationsTraverser validate(shaderType, symbolTable, diagnostics);
+ root->traverse(&validate);
+ return diagnostics->numErrors() == 0;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/ValidateLimitations.h b/gfx/angle/checkout/src/compiler/translator/ValidateLimitations.h
new file mode 100644
index 0000000000..00f26b53f5
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateLimitations.h
@@ -0,0 +1,26 @@
+//
+// Copyright 2010 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_VALIDATELIMITATIONS_H_
+#define COMPILER_TRANSLATOR_VALIDATELIMITATIONS_H_
+
+#include "compiler/translator/IntermNode.h"
+
+namespace sh
+{
+
+class TDiagnostics;
+
+// Returns true if the given shader does not exceed the minimum functionality mandated in GLSL ES
+// 1.00 spec Appendix A.
+bool ValidateLimitations(TIntermNode *root,
+ GLenum shaderType,
+ TSymbolTable *symbolTable,
+ TDiagnostics *diagnostics);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_VALIDATELIMITATIONS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/ValidateMaxParameters.cpp b/gfx/angle/checkout/src/compiler/translator/ValidateMaxParameters.cpp
new file mode 100644
index 0000000000..b3f53e27fa
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateMaxParameters.cpp
@@ -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.
+//
+// ValidateMaxParameters checks if function definitions have more than a set number of parameters.
+
+#include "compiler/translator/ValidateMaxParameters.h"
+
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/Symbol.h"
+
+namespace sh
+{
+
+bool ValidateMaxParameters(TIntermBlock *root, unsigned int maxParameters)
+{
+ for (TIntermNode *node : *root->getSequence())
+ {
+ TIntermFunctionDefinition *definition = node->getAsFunctionDefinition();
+ if (definition != nullptr &&
+ definition->getFunctionPrototype()->getFunction()->getParamCount() > maxParameters)
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/ValidateMaxParameters.h b/gfx/angle/checkout/src/compiler/translator/ValidateMaxParameters.h
new file mode 100644
index 0000000000..73cdb992d3
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateMaxParameters.h
@@ -0,0 +1,21 @@
+//
+// 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.
+//
+// ValidateMaxParameters checks if function definitions have more than a set number of parameters.
+
+#ifndef COMPILER_TRANSLATOR_VALIDATEMAXPARAMETERS_H_
+#define COMPILER_TRANSLATOR_VALIDATEMAXPARAMETERS_H_
+
+namespace sh
+{
+
+class TIntermBlock;
+
+// Return true if valid.
+bool ValidateMaxParameters(TIntermBlock *root, unsigned int maxParameters);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_VALIDATEMAXPARAMETERS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/ValidateOutputs.cpp b/gfx/angle/checkout/src/compiler/translator/ValidateOutputs.cpp
new file mode 100644
index 0000000000..5ba70c4de1
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateOutputs.cpp
@@ -0,0 +1,184 @@
+//
+// Copyright 2013 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.
+//
+// ValidateOutputs validates fragment shader outputs. It checks for conflicting locations,
+// out-of-range locations, that locations are specified when using multiple outputs, and YUV output
+// validity.
+
+#include "compiler/translator/ValidateOutputs.h"
+
+#include <set>
+
+#include "compiler/translator/InfoSink.h"
+#include "compiler/translator/ParseContext.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+void error(const TIntermSymbol &symbol, const char *reason, TDiagnostics *diagnostics)
+{
+ diagnostics->error(symbol.getLine(), reason, symbol.getName().data());
+}
+
+class ValidateOutputsTraverser : public TIntermTraverser
+{
+ public:
+ ValidateOutputsTraverser(const TExtensionBehavior &extBehavior, int maxDrawBuffers);
+
+ void validate(TDiagnostics *diagnostics) const;
+
+ void visitSymbol(TIntermSymbol *) override;
+
+ private:
+ int mMaxDrawBuffers;
+ bool mAllowUnspecifiedOutputLocationResolution;
+ bool mUsesFragDepth;
+
+ typedef std::vector<TIntermSymbol *> OutputVector;
+ OutputVector mOutputs;
+ OutputVector mUnspecifiedLocationOutputs;
+ OutputVector mYuvOutputs;
+ std::set<int> mVisitedSymbols; // Visited symbol ids.
+};
+
+ValidateOutputsTraverser::ValidateOutputsTraverser(const TExtensionBehavior &extBehavior,
+ int maxDrawBuffers)
+ : TIntermTraverser(true, false, false),
+ mMaxDrawBuffers(maxDrawBuffers),
+ mAllowUnspecifiedOutputLocationResolution(
+ IsExtensionEnabled(extBehavior, TExtension::EXT_blend_func_extended)),
+ mUsesFragDepth(false)
+{}
+
+void ValidateOutputsTraverser::visitSymbol(TIntermSymbol *symbol)
+{
+ if (symbol->variable().symbolType() == SymbolType::Empty)
+ return;
+
+ if (mVisitedSymbols.count(symbol->uniqueId().get()) == 1)
+ return;
+
+ mVisitedSymbols.insert(symbol->uniqueId().get());
+
+ TQualifier qualifier = symbol->getQualifier();
+ if (qualifier == EvqFragmentOut)
+ {
+ if (symbol->getType().getLayoutQualifier().location != -1)
+ {
+ mOutputs.push_back(symbol);
+ }
+ else if (symbol->getType().getLayoutQualifier().yuv == true)
+ {
+ mYuvOutputs.push_back(symbol);
+ }
+ else
+ {
+ mUnspecifiedLocationOutputs.push_back(symbol);
+ }
+ }
+ else if (qualifier == EvqFragDepth)
+ {
+ mUsesFragDepth = true;
+ }
+}
+
+void ValidateOutputsTraverser::validate(TDiagnostics *diagnostics) const
+{
+ ASSERT(diagnostics);
+ OutputVector validOutputs(mMaxDrawBuffers, nullptr);
+ OutputVector validSecondaryOutputs(mMaxDrawBuffers, nullptr);
+
+ for (const auto &symbol : mOutputs)
+ {
+ const TType &type = symbol->getType();
+ ASSERT(!type.isArrayOfArrays()); // Disallowed in GLSL ES 3.10 section 4.3.6.
+ const size_t elementCount =
+ static_cast<size_t>(type.isArray() ? type.getOutermostArraySize() : 1u);
+ const size_t location = static_cast<size_t>(type.getLayoutQualifier().location);
+
+ ASSERT(type.getLayoutQualifier().location != -1);
+
+ OutputVector *validOutputsToUse = &validOutputs;
+ // The default index is 0, so we only assign the output to secondary outputs in case the
+ // index is explicitly set to 1.
+ if (type.getLayoutQualifier().index == 1)
+ {
+ validOutputsToUse = &validSecondaryOutputs;
+ }
+
+ if (location + elementCount <= validOutputsToUse->size())
+ {
+ for (size_t elementIndex = 0; elementIndex < elementCount; elementIndex++)
+ {
+ const size_t offsetLocation = location + elementIndex;
+ if ((*validOutputsToUse)[offsetLocation])
+ {
+ std::stringstream strstr = sh::InitializeStream<std::stringstream>();
+ strstr << "conflicting output locations with previously defined output '"
+ << (*validOutputsToUse)[offsetLocation]->getName() << "'";
+ error(*symbol, strstr.str().c_str(), diagnostics);
+ }
+ else
+ {
+ (*validOutputsToUse)[offsetLocation] = symbol;
+ }
+ }
+ }
+ else
+ {
+ if (elementCount > 0)
+ {
+ error(*symbol,
+ elementCount > 1 ? "output array locations would exceed MAX_DRAW_BUFFERS"
+ : "output location must be < MAX_DRAW_BUFFERS",
+ diagnostics);
+ }
+ }
+ }
+
+ if (!mAllowUnspecifiedOutputLocationResolution &&
+ ((!mOutputs.empty() && !mUnspecifiedLocationOutputs.empty()) ||
+ mUnspecifiedLocationOutputs.size() > 1))
+ {
+ for (const auto &symbol : mUnspecifiedLocationOutputs)
+ {
+ error(*symbol,
+ "must explicitly specify all locations when using multiple fragment outputs",
+ diagnostics);
+ }
+ }
+
+ if (!mYuvOutputs.empty() && (mYuvOutputs.size() > 1 || mUsesFragDepth || !mOutputs.empty() ||
+ !mUnspecifiedLocationOutputs.empty()))
+ {
+ for (const auto &symbol : mYuvOutputs)
+ {
+ error(*symbol,
+ "not allowed to specify yuv qualifier when using depth or multiple color "
+ "fragment outputs",
+ diagnostics);
+ }
+ }
+}
+
+} // anonymous namespace
+
+bool ValidateOutputs(TIntermBlock *root,
+ const TExtensionBehavior &extBehavior,
+ int maxDrawBuffers,
+ TDiagnostics *diagnostics)
+{
+ ValidateOutputsTraverser validateOutputs(extBehavior, maxDrawBuffers);
+ root->traverse(&validateOutputs);
+ int numErrorsBefore = diagnostics->numErrors();
+ validateOutputs.validate(diagnostics);
+ return (diagnostics->numErrors() == numErrorsBefore);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/ValidateOutputs.h b/gfx/angle/checkout/src/compiler/translator/ValidateOutputs.h
new file mode 100644
index 0000000000..136288bb50
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateOutputs.h
@@ -0,0 +1,30 @@
+//
+// Copyright 2013 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.
+//
+// ValidateOutputs validates fragment shader outputs. It checks for conflicting locations,
+// out-of-range locations, that locations are specified when using multiple outputs, and YUV output
+// validity.
+//
+
+#ifndef COMPILER_TRANSLATOR_VALIDATEOUTPUTS_H_
+#define COMPILER_TRANSLATOR_VALIDATEOUTPUTS_H_
+
+#include "compiler/translator/ExtensionBehavior.h"
+
+namespace sh
+{
+
+class TIntermBlock;
+class TDiagnostics;
+
+// Returns true if the shader has no conflicting or otherwise erroneous fragment outputs.
+bool ValidateOutputs(TIntermBlock *root,
+ const TExtensionBehavior &extBehavior,
+ int maxDrawBuffers,
+ TDiagnostics *diagnostics);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_VALIDATEOUTPUTS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/ValidateSwitch.cpp b/gfx/angle/checkout/src/compiler/translator/ValidateSwitch.cpp
new file mode 100644
index 0000000000..8a9e7b22a1
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateSwitch.cpp
@@ -0,0 +1,315 @@
+//
+// Copyright 2002 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/ValidateSwitch.h"
+
+#include "compiler/translator/Diagnostics.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+const int kMaxAllowedTraversalDepth = 256;
+
+class ValidateSwitch : public TIntermTraverser
+{
+ public:
+ static bool validate(TBasicType switchType,
+ TDiagnostics *diagnostics,
+ TIntermBlock *statementList,
+ const TSourceLoc &loc);
+
+ void visitSymbol(TIntermSymbol *) override;
+ void visitConstantUnion(TIntermConstantUnion *) override;
+ bool visitDeclaration(Visit, TIntermDeclaration *) override;
+ bool visitBlock(Visit visit, TIntermBlock *) override;
+ bool visitBinary(Visit, TIntermBinary *) override;
+ bool visitUnary(Visit, TIntermUnary *) override;
+ bool visitTernary(Visit, TIntermTernary *) override;
+ bool visitSwizzle(Visit, TIntermSwizzle *) override;
+ bool visitIfElse(Visit visit, TIntermIfElse *) override;
+ bool visitSwitch(Visit, TIntermSwitch *) override;
+ bool visitCase(Visit, TIntermCase *node) override;
+ bool visitAggregate(Visit, TIntermAggregate *) override;
+ bool visitLoop(Visit visit, TIntermLoop *) override;
+ bool visitBranch(Visit, TIntermBranch *) override;
+
+ private:
+ ValidateSwitch(TBasicType switchType, TDiagnostics *context);
+
+ bool validateInternal(const TSourceLoc &loc);
+
+ TBasicType mSwitchType;
+ TDiagnostics *mDiagnostics;
+ bool mCaseTypeMismatch;
+ bool mFirstCaseFound;
+ bool mStatementBeforeCase;
+ bool mLastStatementWasCase;
+ int mControlFlowDepth;
+ bool mCaseInsideControlFlow;
+ int mDefaultCount;
+ std::set<int> mCasesSigned;
+ std::set<unsigned int> mCasesUnsigned;
+ bool mDuplicateCases;
+};
+
+bool ValidateSwitch::validate(TBasicType switchType,
+ TDiagnostics *diagnostics,
+ TIntermBlock *statementList,
+ const TSourceLoc &loc)
+{
+ ValidateSwitch validate(switchType, diagnostics);
+ ASSERT(statementList);
+ statementList->traverse(&validate);
+ return validate.validateInternal(loc);
+}
+
+ValidateSwitch::ValidateSwitch(TBasicType switchType, TDiagnostics *diagnostics)
+ : TIntermTraverser(true, false, true, nullptr),
+ mSwitchType(switchType),
+ mDiagnostics(diagnostics),
+ mCaseTypeMismatch(false),
+ mFirstCaseFound(false),
+ mStatementBeforeCase(false),
+ mLastStatementWasCase(false),
+ mControlFlowDepth(0),
+ mCaseInsideControlFlow(false),
+ mDefaultCount(0),
+ mDuplicateCases(false)
+{
+ setMaxAllowedDepth(kMaxAllowedTraversalDepth);
+}
+
+void ValidateSwitch::visitSymbol(TIntermSymbol *)
+{
+ if (!mFirstCaseFound)
+ mStatementBeforeCase = true;
+ mLastStatementWasCase = false;
+}
+
+void ValidateSwitch::visitConstantUnion(TIntermConstantUnion *)
+{
+ // Conditions of case labels are not traversed, so this is some other constant
+ // Could be just a statement like "0;"
+ if (!mFirstCaseFound)
+ mStatementBeforeCase = true;
+ mLastStatementWasCase = false;
+}
+
+bool ValidateSwitch::visitDeclaration(Visit, TIntermDeclaration *)
+{
+ if (!mFirstCaseFound)
+ mStatementBeforeCase = true;
+ mLastStatementWasCase = false;
+ return true;
+}
+
+bool ValidateSwitch::visitBlock(Visit visit, TIntermBlock *)
+{
+ if (getParentNode() != nullptr)
+ {
+ if (!mFirstCaseFound)
+ mStatementBeforeCase = true;
+ mLastStatementWasCase = false;
+ if (visit == PreVisit)
+ ++mControlFlowDepth;
+ if (visit == PostVisit)
+ --mControlFlowDepth;
+ }
+ return true;
+}
+
+bool ValidateSwitch::visitBinary(Visit, TIntermBinary *)
+{
+ if (!mFirstCaseFound)
+ mStatementBeforeCase = true;
+ mLastStatementWasCase = false;
+ return true;
+}
+
+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::visitSwizzle(Visit, TIntermSwizzle *)
+{
+ if (!mFirstCaseFound)
+ mStatementBeforeCase = true;
+ mLastStatementWasCase = false;
+ return true;
+}
+
+bool ValidateSwitch::visitIfElse(Visit visit, TIntermIfElse *)
+{
+ if (visit == PreVisit)
+ ++mControlFlowDepth;
+ if (visit == PostVisit)
+ --mControlFlowDepth;
+ if (!mFirstCaseFound)
+ mStatementBeforeCase = true;
+ mLastStatementWasCase = false;
+ return true;
+}
+
+bool ValidateSwitch::visitSwitch(Visit, TIntermSwitch *)
+{
+ if (!mFirstCaseFound)
+ mStatementBeforeCase = true;
+ mLastStatementWasCase = false;
+ // Don't go into nested switch statements
+ return false;
+}
+
+bool ValidateSwitch::visitCase(Visit, TIntermCase *node)
+{
+ const char *nodeStr = node->hasCondition() ? "case" : "default";
+ if (mControlFlowDepth > 0)
+ {
+ mDiagnostics->error(node->getLine(), "label statement nested inside control flow", nodeStr);
+ mCaseInsideControlFlow = true;
+ }
+ mFirstCaseFound = true;
+ mLastStatementWasCase = true;
+ if (!node->hasCondition())
+ {
+ ++mDefaultCount;
+ if (mDefaultCount > 1)
+ {
+ mDiagnostics->error(node->getLine(), "duplicate default label", nodeStr);
+ }
+ }
+ else
+ {
+ TIntermConstantUnion *condition = node->getCondition()->getAsConstantUnion();
+ if (condition == nullptr)
+ {
+ // This can happen in error cases.
+ return false;
+ }
+ TBasicType conditionType = condition->getBasicType();
+ if (conditionType != mSwitchType)
+ {
+ mDiagnostics->error(condition->getLine(),
+ "case label type does not match switch init-expression type",
+ nodeStr);
+ mCaseTypeMismatch = true;
+ }
+
+ if (conditionType == EbtInt)
+ {
+ int iConst = condition->getIConst(0);
+ if (mCasesSigned.find(iConst) != mCasesSigned.end())
+ {
+ mDiagnostics->error(condition->getLine(), "duplicate case label", nodeStr);
+ mDuplicateCases = true;
+ }
+ else
+ {
+ mCasesSigned.insert(iConst);
+ }
+ }
+ else if (conditionType == EbtUInt)
+ {
+ unsigned int uConst = condition->getUConst(0);
+ if (mCasesUnsigned.find(uConst) != mCasesUnsigned.end())
+ {
+ mDiagnostics->error(condition->getLine(), "duplicate case label", nodeStr);
+ mDuplicateCases = true;
+ }
+ else
+ {
+ mCasesUnsigned.insert(uConst);
+ }
+ }
+ // Other types are possible only in error cases, where the error has already been generated
+ // when parsing the case statement.
+ }
+ // Don't traverse the condition of the case statement
+ return false;
+}
+
+bool ValidateSwitch::visitAggregate(Visit visit, TIntermAggregate *)
+{
+ if (getParentNode() != nullptr)
+ {
+ // This is not the statementList node, but some other node.
+ if (!mFirstCaseFound)
+ mStatementBeforeCase = true;
+ mLastStatementWasCase = false;
+ }
+ return true;
+}
+
+bool ValidateSwitch::visitLoop(Visit visit, TIntermLoop *)
+{
+ if (visit == PreVisit)
+ ++mControlFlowDepth;
+ if (visit == PostVisit)
+ --mControlFlowDepth;
+ if (!mFirstCaseFound)
+ mStatementBeforeCase = true;
+ mLastStatementWasCase = false;
+ return true;
+}
+
+bool ValidateSwitch::visitBranch(Visit, TIntermBranch *)
+{
+ if (!mFirstCaseFound)
+ mStatementBeforeCase = true;
+ mLastStatementWasCase = false;
+ return true;
+}
+
+bool ValidateSwitch::validateInternal(const TSourceLoc &loc)
+{
+ if (mStatementBeforeCase)
+ {
+ mDiagnostics->error(loc, "statement before the first label", "switch");
+ }
+ if (mLastStatementWasCase)
+ {
+ // There have been some differences between versions of GLSL ES specs on whether this should
+ // be an error or not, but as of early 2018 the latest discussion is that this is an error
+ // also on GLSL ES versions newer than 3.00.
+ mDiagnostics->error(
+ loc, "no statement between the last label and the end of the switch statement",
+ "switch");
+ }
+ if (getMaxDepth() >= kMaxAllowedTraversalDepth)
+ {
+ mDiagnostics->error(loc, "too complex expressions inside a switch statement", "switch");
+ }
+ return !mStatementBeforeCase && !mLastStatementWasCase && !mCaseInsideControlFlow &&
+ !mCaseTypeMismatch && mDefaultCount <= 1 && !mDuplicateCases &&
+ getMaxDepth() < kMaxAllowedTraversalDepth;
+}
+
+} // anonymous namespace
+
+bool ValidateSwitchStatementList(TBasicType switchType,
+ TDiagnostics *diagnostics,
+ TIntermBlock *statementList,
+ const TSourceLoc &loc)
+{
+ return ValidateSwitch::validate(switchType, diagnostics, statementList, loc);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/ValidateSwitch.h b/gfx/angle/checkout/src/compiler/translator/ValidateSwitch.h
new file mode 100644
index 0000000000..828faac98a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateSwitch.h
@@ -0,0 +1,27 @@
+//
+// Copyright 2002 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_VALIDATESWITCH_H_
+#define COMPILER_TRANSLATOR_VALIDATESWITCH_H_
+
+#include "compiler/translator/BaseTypes.h"
+#include "compiler/translator/Common.h"
+
+namespace sh
+{
+class TDiagnostics;
+class TIntermBlock;
+
+// Check for errors and output error messages on the context.
+// Returns true if there are no errors.
+bool ValidateSwitchStatementList(TBasicType switchType,
+ TDiagnostics *diagnostics,
+ TIntermBlock *statementList,
+ const TSourceLoc &loc);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_VALIDATESWITCH_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/ValidateTypeSizeLimitations.cpp b/gfx/angle/checkout/src/compiler/translator/ValidateTypeSizeLimitations.cpp
new file mode 100644
index 0000000000..6097b6d236
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateTypeSizeLimitations.cpp
@@ -0,0 +1,229 @@
+//
+// Copyright 2021 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/ValidateTypeSizeLimitations.h"
+
+#include "angle_gl.h"
+#include "compiler/translator/Diagnostics.h"
+#include "compiler/translator/Symbol.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/blocklayout.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+// Arbitrarily enforce that all types declared with a size in bytes of over 2 GB will cause
+// compilation failure.
+//
+// For local and global variables, the limit is much lower (1MB) as that much memory won't fit in
+// the GPU registers anyway.
+constexpr size_t kMaxVariableSizeInBytes = static_cast<size_t>(2) * 1024 * 1024 * 1024;
+constexpr size_t kMaxPrivateVariableSizeInBytes = static_cast<size_t>(1) * 1024 * 1024;
+
+// Traverses intermediate tree to ensure that the shader does not
+// exceed certain implementation-defined limits on the sizes of types.
+// Some code was copied from the CollectVariables pass.
+class ValidateTypeSizeLimitationsTraverser : public TIntermTraverser
+{
+ public:
+ ValidateTypeSizeLimitationsTraverser(TSymbolTable *symbolTable, TDiagnostics *diagnostics)
+ : TIntermTraverser(true, false, false, symbolTable), mDiagnostics(diagnostics)
+ {
+ ASSERT(diagnostics);
+ }
+
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override
+ {
+ const TIntermSequence &sequence = *(node->getSequence());
+
+ for (TIntermNode *variableNode : sequence)
+ {
+ // See CollectVariablesTraverser::visitDeclaration for a
+ // deeper analysis of the AST structures that might be
+ // encountered.
+ TIntermSymbol *asSymbol = variableNode->getAsSymbolNode();
+ TIntermBinary *asBinary = variableNode->getAsBinaryNode();
+
+ if (asBinary != nullptr)
+ {
+ ASSERT(asBinary->getOp() == EOpInitialize);
+ asSymbol = asBinary->getLeft()->getAsSymbolNode();
+ }
+
+ ASSERT(asSymbol);
+
+ const TVariable &variable = asSymbol->variable();
+ if (variable.symbolType() == SymbolType::AngleInternal)
+ {
+ // Ignore internal variables.
+ continue;
+ }
+
+ const TType &variableType = asSymbol->getType();
+
+ // Create a ShaderVariable from which to compute
+ // (conservative) sizing information.
+ ShaderVariable shaderVar;
+ setCommonVariableProperties(variableType, variable, &shaderVar);
+
+ // Compute the std140 layout of this variable, assuming
+ // it's a member of a block (which it might not be).
+ Std140BlockEncoder layoutEncoder;
+ BlockEncoderVisitor visitor("", "", &layoutEncoder);
+ // Since the size limit's arbitrary, it doesn't matter
+ // whether the row-major layout is correctly determined.
+ bool isRowMajorLayout = false;
+ TraverseShaderVariable(shaderVar, isRowMajorLayout, &visitor);
+ if (layoutEncoder.getCurrentOffset() > kMaxVariableSizeInBytes)
+ {
+ error(asSymbol->getLine(),
+ "Size of declared variable exceeds implementation-defined limit",
+ asSymbol->getName());
+ return false;
+ }
+
+ const bool isPrivate = variableType.getQualifier() == EvqTemporary ||
+ variableType.getQualifier() == EvqGlobal ||
+ variableType.getQualifier() == EvqConst;
+ if (layoutEncoder.getCurrentOffset() > kMaxPrivateVariableSizeInBytes && isPrivate)
+ {
+ error(asSymbol->getLine(),
+ "Size of declared private variable exceeds implementation-defined limit",
+ asSymbol->getName());
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private:
+ void error(TSourceLoc loc, const char *reason, const ImmutableString &token)
+ {
+ mDiagnostics->error(loc, reason, token.data());
+ }
+
+ void setFieldOrVariableProperties(const TType &type,
+ bool staticUse,
+ bool isShaderIOBlock,
+ bool isPatch,
+ ShaderVariable *variableOut) const
+ {
+ ASSERT(variableOut);
+
+ variableOut->staticUse = staticUse;
+ variableOut->isShaderIOBlock = isShaderIOBlock;
+ variableOut->isPatch = isPatch;
+
+ const TStructure *structure = type.getStruct();
+ const TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
+ if (structure)
+ {
+ // Structures use a NONE type that isn't exposed outside ANGLE.
+ variableOut->type = GL_NONE;
+ if (structure->symbolType() != SymbolType::Empty)
+ {
+ variableOut->structOrBlockName = structure->name().data();
+ }
+
+ const TFieldList &fields = structure->fields();
+
+ for (const TField *field : fields)
+ {
+ // Regardless of the variable type (uniform, in/out etc.) its fields are always
+ // plain ShaderVariable objects.
+ ShaderVariable fieldVariable;
+ setFieldProperties(*field->type(), field->name(), staticUse, isShaderIOBlock,
+ isPatch, &fieldVariable);
+ variableOut->fields.push_back(fieldVariable);
+ }
+ }
+ else if (interfaceBlock && isShaderIOBlock)
+ {
+ variableOut->type = GL_NONE;
+ if (interfaceBlock->symbolType() != SymbolType::Empty)
+ {
+ variableOut->structOrBlockName = interfaceBlock->name().data();
+ }
+ const TFieldList &fields = interfaceBlock->fields();
+ for (const TField *field : fields)
+ {
+ ShaderVariable fieldVariable;
+ setFieldProperties(*field->type(), field->name(), staticUse, true, isPatch,
+ &fieldVariable);
+ fieldVariable.isShaderIOBlock = true;
+ variableOut->fields.push_back(fieldVariable);
+ }
+ }
+ else
+ {
+ variableOut->type = GLVariableType(type);
+ variableOut->precision = GLVariablePrecision(type);
+ }
+
+ const TSpan<const unsigned int> &arraySizes = type.getArraySizes();
+ if (!arraySizes.empty())
+ {
+ variableOut->arraySizes.assign(arraySizes.begin(), arraySizes.end());
+ // WebGL does not support tessellation shaders; removed
+ // code specific to that shader type.
+ }
+ }
+
+ void setFieldProperties(const TType &type,
+ const ImmutableString &name,
+ bool staticUse,
+ bool isShaderIOBlock,
+ bool isPatch,
+ ShaderVariable *variableOut) const
+ {
+ ASSERT(variableOut);
+ setFieldOrVariableProperties(type, staticUse, isShaderIOBlock, isPatch, variableOut);
+ variableOut->name.assign(name.data(), name.length());
+ }
+
+ void setCommonVariableProperties(const TType &type,
+ const TVariable &variable,
+ ShaderVariable *variableOut) const
+ {
+ ASSERT(variableOut);
+
+ // Shortcut some processing that's unnecessary for this analysis.
+ const bool staticUse = true;
+ const bool isShaderIOBlock = type.getInterfaceBlock() != nullptr;
+ const bool isPatch = false;
+
+ setFieldOrVariableProperties(type, staticUse, isShaderIOBlock, isPatch, variableOut);
+
+ const bool isNamed = variable.symbolType() != SymbolType::Empty;
+
+ if (isNamed)
+ {
+ variableOut->name.assign(variable.name().data(), variable.name().length());
+ }
+ }
+
+ TDiagnostics *mDiagnostics;
+ std::vector<int> mLoopSymbolIds;
+};
+
+} // namespace
+
+bool ValidateTypeSizeLimitations(TIntermNode *root,
+ TSymbolTable *symbolTable,
+ TDiagnostics *diagnostics)
+{
+ ValidateTypeSizeLimitationsTraverser validate(symbolTable, diagnostics);
+ root->traverse(&validate);
+ return diagnostics->numErrors() == 0;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/ValidateTypeSizeLimitations.h b/gfx/angle/checkout/src/compiler/translator/ValidateTypeSizeLimitations.h
new file mode 100644
index 0000000000..defa39876d
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateTypeSizeLimitations.h
@@ -0,0 +1,25 @@
+//
+// Copyright 2021 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_VALIDATETYPESIZELIMITATIONS_H_
+#define COMPILER_TRANSLATOR_VALIDATETYPESIZELIMITATIONS_H_
+
+#include "compiler/translator/IntermNode.h"
+
+namespace sh
+{
+
+class TDiagnostics;
+
+// Returns true if the given shader does not violate certain
+// implementation-defined limits on the size of variables' types.
+bool ValidateTypeSizeLimitations(TIntermNode *root,
+ TSymbolTable *symbolTable,
+ TDiagnostics *diagnostics);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_VALIDATETYPESIZELIMITATIONS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/ValidateVaryingLocations.cpp b/gfx/angle/checkout/src/compiler/translator/ValidateVaryingLocations.cpp
new file mode 100644
index 0000000000..3c2eeeb5bc
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateVaryingLocations.cpp
@@ -0,0 +1,368 @@
+//
+// Copyright 2002 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.
+//
+// The ValidateVaryingLocations function checks if there exists location conflicts on shader
+// varyings.
+//
+
+#include "ValidateVaryingLocations.h"
+
+#include "compiler/translator/Diagnostics.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+void error(const TIntermSymbol &symbol, const char *reason, TDiagnostics *diagnostics)
+{
+ diagnostics->error(symbol.getLine(), reason, symbol.getName().data());
+}
+
+int GetStructLocationCount(const TStructure *structure);
+
+int GetFieldLocationCount(const TField *field)
+{
+ int field_size = 0;
+ const TType *fieldType = field->type();
+
+ if (fieldType->getStruct() != nullptr)
+ {
+ field_size = GetStructLocationCount(fieldType->getStruct());
+ }
+ else if (fieldType->isMatrix())
+ {
+ field_size = fieldType->getNominalSize();
+ }
+ else
+ {
+ ASSERT(fieldType->getSecondarySize() == 1);
+ field_size = 1;
+ }
+
+ if (fieldType->isArray())
+ {
+ field_size *= fieldType->getArraySizeProduct();
+ }
+
+ return field_size;
+}
+
+int GetStructLocationCount(const TStructure *structure)
+{
+ int totalLocation = 0;
+ for (const TField *field : structure->fields())
+ {
+ totalLocation += GetFieldLocationCount(field);
+ }
+ return totalLocation;
+}
+
+int GetInterfaceBlockLocationCount(const TType &varyingType, bool ignoreVaryingArraySize)
+{
+ int totalLocation = 0;
+ for (const TField *field : varyingType.getInterfaceBlock()->fields())
+ {
+ totalLocation += GetFieldLocationCount(field);
+ }
+
+ if (!ignoreVaryingArraySize && varyingType.isArray())
+ {
+ totalLocation *= varyingType.getArraySizeProduct();
+ }
+ return totalLocation;
+}
+
+int GetLocationCount(const TType &varyingType, bool ignoreVaryingArraySize)
+{
+ ASSERT(!varyingType.isInterfaceBlock());
+
+ if (varyingType.getStruct() != nullptr)
+ {
+ int totalLocation = 0;
+ for (const TField *field : varyingType.getStruct()->fields())
+ {
+ const TType *fieldType = field->type();
+ ASSERT(fieldType->getStruct() == nullptr && !fieldType->isArray());
+
+ totalLocation += GetFieldLocationCount(field);
+ }
+ return totalLocation;
+ }
+
+ ASSERT(varyingType.isMatrix() || varyingType.getSecondarySize() == 1);
+ int elementLocationCount = varyingType.isMatrix() ? varyingType.getNominalSize() : 1;
+
+ // [GL_EXT_shader_io_blocks SPEC Chapter 4.4.1]
+ // Geometry shader inputs, tessellation control shader inputs and outputs, and tessellation
+ // evaluation inputs all have an additional level of arrayness relative to other shader inputs
+ // and outputs. This outer array level is removed from the type before considering how many
+ // locations the type consumes.
+ if (ignoreVaryingArraySize)
+ {
+ // Array-of-arrays cannot be inputs or outputs of a geometry shader.
+ // (GL_EXT_geometry_shader SPEC issues(5))
+ ASSERT(!varyingType.isArrayOfArrays());
+ return elementLocationCount;
+ }
+
+ return elementLocationCount * varyingType.getArraySizeProduct();
+}
+
+bool ShouldIgnoreVaryingArraySize(TQualifier qualifier, GLenum shaderType)
+{
+ bool isVaryingIn = IsShaderIn(qualifier) && qualifier != EvqPatchIn;
+
+ switch (shaderType)
+ {
+ case GL_GEOMETRY_SHADER:
+ case GL_TESS_EVALUATION_SHADER:
+ return isVaryingIn;
+ case GL_TESS_CONTROL_SHADER:
+ return (IsShaderOut(qualifier) && qualifier != EvqPatchOut) || isVaryingIn;
+ default:
+ return false;
+ }
+}
+
+struct SymbolAndField
+{
+ const TIntermSymbol *symbol;
+ const TField *field;
+};
+using LocationMap = std::map<int, SymbolAndField>;
+
+void MarkVaryingLocations(TDiagnostics *diagnostics,
+ const TIntermSymbol *varying,
+ const TField *field,
+ int location,
+ int elementCount,
+ LocationMap *locationMap)
+{
+ for (int elementIndex = 0; elementIndex < elementCount; ++elementIndex)
+ {
+ const int offsetLocation = location + elementIndex;
+ auto conflict = locationMap->find(offsetLocation);
+ if (conflict != locationMap->end())
+ {
+ std::stringstream strstr = sh::InitializeStream<std::stringstream>();
+ strstr << "'" << varying->getName();
+ if (field)
+ {
+ strstr << "." << field->name();
+ }
+ strstr << "' conflicting location with '" << conflict->second.symbol->getName();
+ if (conflict->second.field)
+ {
+ strstr << "." << conflict->second.field->name();
+ }
+ strstr << "'";
+ error(*varying, strstr.str().c_str(), diagnostics);
+ }
+ else
+ {
+ (*locationMap)[offsetLocation] = {varying, field};
+ }
+ }
+}
+
+using VaryingVector = std::vector<const TIntermSymbol *>;
+
+void ValidateShaderInterfaceAndAssignLocations(TDiagnostics *diagnostics,
+ const VaryingVector &varyingVector,
+ GLenum shaderType)
+{
+ // Location conflicts can only happen when there are two or more varyings in varyingVector.
+ if (varyingVector.size() <= 1)
+ {
+ return;
+ }
+
+ LocationMap locationMap;
+ for (const TIntermSymbol *varying : varyingVector)
+ {
+ const TType &varyingType = varying->getType();
+ const int location = varyingType.getLayoutQualifier().location;
+ ASSERT(location >= 0);
+
+ bool ignoreVaryingArraySize =
+ ShouldIgnoreVaryingArraySize(varying->getQualifier(), shaderType);
+
+ // A varying is either:
+ //
+ // - A vector or matrix, which can take a number of contiguous locations
+ // - A struct, which also takes a number of contiguous locations
+ // - An interface block.
+ //
+ // Interface blocks can assign arbitrary locations to their fields, for example:
+ //
+ // layout(location = 4) in block {
+ // vec4 a; // gets location 4
+ // vec4 b; // gets location 5
+ // layout(location = 7) vec4 c; // gets location 7
+ // vec4 d; // gets location 8
+ // layout (location = 1) vec4 e; // gets location 1
+ // vec4 f; // gets location 2
+ // };
+ //
+ // The following code therefore takes two paths. For non-interface-block types, the number
+ // of locations for the varying is calculated (elementCount), and all locations in
+ // [location, location + elementCount) are marked as occupied.
+ //
+ // For interface blocks, a similar algorithm is implemented except each field is
+ // individually marked with the location either advancing automatically or taking its value
+ // from the field's layout qualifier.
+
+ if (varyingType.isInterfaceBlock())
+ {
+ int currentLocation = location;
+ bool anyFieldWithLocation = false;
+
+ for (const TField *field : varyingType.getInterfaceBlock()->fields())
+ {
+ const int fieldLocation = field->type()->getLayoutQualifier().location;
+ if (fieldLocation >= 0)
+ {
+ currentLocation = fieldLocation;
+ anyFieldWithLocation = true;
+ }
+
+ const int fieldLocationCount = GetFieldLocationCount(field);
+ MarkVaryingLocations(diagnostics, varying, field, currentLocation,
+ fieldLocationCount, &locationMap);
+
+ currentLocation += fieldLocationCount;
+ }
+
+ // Array interface blocks can't have location qualifiers on fields.
+ ASSERT(ignoreVaryingArraySize || !anyFieldWithLocation || !varyingType.isArray());
+
+ if (!ignoreVaryingArraySize && varyingType.isArray())
+ {
+ // This is only reached if the varying is an array of interface blocks, with only a
+ // layout qualifier on the block itself, for example:
+ //
+ // layout(location = 4) in block {
+ // vec4 a;
+ // vec4 b;
+ // vec4 c;
+ // vec4 d;
+ // } instance[N];
+ //
+ // The locations for instance[0] are already marked by the above code, so we need to
+ // further mark locations occupied by instances [1, N). |currentLocation| is
+ // already just past the end of instance[0], which is the beginning of instance[1].
+ //
+ int remainingLocations = currentLocation * (varyingType.getArraySizeProduct() - 1);
+ MarkVaryingLocations(diagnostics, varying, nullptr, currentLocation,
+ remainingLocations, &locationMap);
+ }
+ }
+ else
+ {
+ const int elementCount = GetLocationCount(varying->getType(), ignoreVaryingArraySize);
+ MarkVaryingLocations(diagnostics, varying, nullptr, location, elementCount,
+ &locationMap);
+ }
+ }
+}
+
+class ValidateVaryingLocationsTraverser : public TIntermTraverser
+{
+ public:
+ ValidateVaryingLocationsTraverser(GLenum shaderType);
+ void validate(TDiagnostics *diagnostics);
+
+ private:
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
+ bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override;
+
+ VaryingVector mInputVaryingsWithLocation;
+ VaryingVector mOutputVaryingsWithLocation;
+ GLenum mShaderType;
+};
+
+ValidateVaryingLocationsTraverser::ValidateVaryingLocationsTraverser(GLenum shaderType)
+ : TIntermTraverser(true, false, false), mShaderType(shaderType)
+{}
+
+bool ValidateVaryingLocationsTraverser::visitDeclaration(Visit visit, TIntermDeclaration *node)
+{
+ const TIntermSequence &sequence = *(node->getSequence());
+ ASSERT(!sequence.empty());
+
+ const TIntermSymbol *symbol = sequence.front()->getAsSymbolNode();
+ if (symbol == nullptr)
+ {
+ return false;
+ }
+
+ if (symbol->variable().symbolType() == SymbolType::Empty)
+ {
+ return false;
+ }
+
+ // Collect varyings that have explicit 'location' qualifiers.
+ const TQualifier qualifier = symbol->getQualifier();
+ if (symbol->getType().getLayoutQualifier().location != -1)
+ {
+ if (IsVaryingIn(qualifier))
+ {
+ mInputVaryingsWithLocation.push_back(symbol);
+ }
+ else if (IsVaryingOut(qualifier))
+ {
+ mOutputVaryingsWithLocation.push_back(symbol);
+ }
+ }
+
+ return false;
+}
+
+bool ValidateVaryingLocationsTraverser::visitFunctionDefinition(Visit visit,
+ TIntermFunctionDefinition *node)
+{
+ // We stop traversing function definitions because varyings cannot be defined in a function.
+ return false;
+}
+
+void ValidateVaryingLocationsTraverser::validate(TDiagnostics *diagnostics)
+{
+ ASSERT(diagnostics);
+
+ ValidateShaderInterfaceAndAssignLocations(diagnostics, mInputVaryingsWithLocation, mShaderType);
+ ValidateShaderInterfaceAndAssignLocations(diagnostics, mOutputVaryingsWithLocation,
+ mShaderType);
+}
+
+} // anonymous namespace
+
+unsigned int CalculateVaryingLocationCount(const TType &varyingType, GLenum shaderType)
+{
+ const TQualifier qualifier = varyingType.getQualifier();
+ const bool ignoreVaryingArraySize = ShouldIgnoreVaryingArraySize(qualifier, shaderType);
+
+ if (varyingType.isInterfaceBlock())
+ {
+ return GetInterfaceBlockLocationCount(varyingType, ignoreVaryingArraySize);
+ }
+
+ return GetLocationCount(varyingType, ignoreVaryingArraySize);
+}
+
+bool ValidateVaryingLocations(TIntermBlock *root, TDiagnostics *diagnostics, GLenum shaderType)
+{
+ ValidateVaryingLocationsTraverser varyingValidator(shaderType);
+ root->traverse(&varyingValidator);
+ int numErrorsBefore = diagnostics->numErrors();
+ varyingValidator.validate(diagnostics);
+ return (diagnostics->numErrors() == numErrorsBefore);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/ValidateVaryingLocations.h b/gfx/angle/checkout/src/compiler/translator/ValidateVaryingLocations.h
new file mode 100644
index 0000000000..5ce43c91c4
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/ValidateVaryingLocations.h
@@ -0,0 +1,28 @@
+//
+// Copyright 2002 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.
+//
+// The ValidateVaryingLocations function checks if there exists location conflicts on shader
+// varyings.
+//
+
+#ifndef COMPILER_TRANSLATOR_VALIDATEVARYINGLOCATIONS_H_
+#define COMPILER_TRANSLATOR_VALIDATEVARYINGLOCATIONS_H_
+
+#include "GLSLANG/ShaderVars.h"
+
+namespace sh
+{
+
+class TIntermBlock;
+class TIntermSymbol;
+class TDiagnostics;
+class TType;
+
+unsigned int CalculateVaryingLocationCount(const TType &varyingType, GLenum shaderType);
+bool ValidateVaryingLocations(TIntermBlock *root, TDiagnostics *diagnostics, GLenum shaderType);
+
+} // namespace sh
+
+#endif
diff --git a/gfx/angle/checkout/src/compiler/translator/VariablePacker.cpp b/gfx/angle/checkout/src/compiler/translator/VariablePacker.cpp
new file mode 100644
index 0000000000..347395d382
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/VariablePacker.cpp
@@ -0,0 +1,409 @@
+//
+// Copyright 2002 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.
+//
+// Check whether variables fit within packing limits according to the packing rules from the GLSL ES
+// 1.00.17 spec, Appendix A, section 7.
+
+#include <algorithm>
+
+#include "angle_gl.h"
+
+#include "common/utilities.h"
+#include "compiler/translator/VariablePacker.h"
+
+namespace sh
+{
+
+namespace
+{
+
+// Expand the variable so that struct variables are split into their individual fields.
+// Will not set the mappedName or staticUse fields on the expanded variables.
+void ExpandVariable(const ShaderVariable &variable,
+ const std::string &name,
+ std::vector<ShaderVariable> *expanded);
+
+void ExpandStructVariable(const ShaderVariable &variable,
+ const std::string &name,
+ std::vector<ShaderVariable> *expanded)
+{
+ ASSERT(variable.isStruct());
+
+ const std::vector<ShaderVariable> &fields = variable.fields;
+
+ for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
+ {
+ const ShaderVariable &field = fields[fieldIndex];
+ ExpandVariable(field, name + "." + field.name, expanded);
+ }
+}
+
+void ExpandStructArrayVariable(const ShaderVariable &variable,
+ unsigned int arrayNestingIndex,
+ const std::string &name,
+ std::vector<ShaderVariable> *expanded)
+{
+ // Nested arrays are processed starting from outermost (arrayNestingIndex 0u) and ending at the
+ // innermost.
+ const unsigned int currentArraySize = variable.getNestedArraySize(arrayNestingIndex);
+ for (unsigned int arrayElement = 0u; arrayElement < currentArraySize; ++arrayElement)
+ {
+ const std::string elementName = name + ArrayString(arrayElement);
+ if (arrayNestingIndex + 1u < variable.arraySizes.size())
+ {
+ ExpandStructArrayVariable(variable, arrayNestingIndex + 1u, elementName, expanded);
+ }
+ else
+ {
+ ExpandStructVariable(variable, elementName, expanded);
+ }
+ }
+}
+
+void ExpandVariable(const ShaderVariable &variable,
+ const std::string &name,
+ std::vector<ShaderVariable> *expanded)
+{
+ if (variable.isStruct())
+ {
+ if (variable.isArray())
+ {
+ ExpandStructArrayVariable(variable, 0u, name, expanded);
+ }
+ else
+ {
+ ExpandStructVariable(variable, name, expanded);
+ }
+ }
+ else
+ {
+ ShaderVariable expandedVar = variable;
+ expandedVar.name = name;
+
+ expanded->push_back(expandedVar);
+ }
+}
+
+int GetVariablePackingRows(const ShaderVariable &variable)
+{
+ return GetTypePackingRows(variable.type) * variable.getArraySizeProduct();
+}
+
+class VariablePacker
+{
+ public:
+ bool checkExpandedVariablesWithinPackingLimits(unsigned int maxVectors,
+ std::vector<sh::ShaderVariable> *variables);
+
+ 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_;
+};
+
+struct TVariableInfoComparer
+{
+ bool operator()(const sh::ShaderVariable &lhs, const sh::ShaderVariable &rhs) const
+ {
+ int lhsSortOrder = gl::VariableSortOrder(lhs.type);
+ int rhsSortOrder = gl::VariableSortOrder(rhs.type);
+ if (lhsSortOrder != rhsSortOrder)
+ {
+ return lhsSortOrder < rhsSortOrder;
+ }
+ // Sort by largest first.
+ return lhs.getArraySizeProduct() > rhs.getArraySizeProduct();
+ }
+};
+
+unsigned VariablePacker::makeColumnFlags(int column, int numComponentsPerRow)
+{
+ return ((kColumnMask << (kNumColumns - numComponentsPerRow)) & kColumnMask) >> column;
+}
+
+void VariablePacker::fillColumns(int topRow, int numRows, int column, int numComponentsPerRow)
+{
+ unsigned columnFlags = makeColumnFlags(column, numComponentsPerRow);
+ for (int r = 0; r < numRows; ++r)
+ {
+ int row = topRow + r;
+ ASSERT((rows_[row] & columnFlags) == 0);
+ rows_[row] |= columnFlags;
+ }
+}
+
+bool VariablePacker::searchColumn(int column, int numRows, int *destRow, int *destSize)
+{
+ ASSERT(destRow);
+
+ for (; topNonFullRow_ < maxRows_ && rows_[topNonFullRow_] == kColumnMask; ++topNonFullRow_)
+ {
+ }
+
+ for (; bottomNonFullRow_ >= 0 && rows_[bottomNonFullRow_] == kColumnMask; --bottomNonFullRow_)
+ {
+ }
+
+ if (bottomNonFullRow_ - topNonFullRow_ + 1 < numRows)
+ {
+ return false;
+ }
+
+ unsigned columnFlags = makeColumnFlags(column, 1);
+ int topGoodRow = 0;
+ int smallestGoodTop = -1;
+ int smallestGoodSize = maxRows_ + 1;
+ int bottomRow = bottomNonFullRow_ + 1;
+ bool found = false;
+ for (int row = topNonFullRow_; row <= bottomRow; ++row)
+ {
+ bool rowEmpty = row < bottomRow ? ((rows_[row] & columnFlags) == 0) : false;
+ if (rowEmpty)
+ {
+ if (!found)
+ {
+ topGoodRow = row;
+ found = true;
+ }
+ }
+ else
+ {
+ if (found)
+ {
+ int size = row - topGoodRow;
+ if (size >= numRows && size < smallestGoodSize)
+ {
+ smallestGoodSize = size;
+ smallestGoodTop = topGoodRow;
+ }
+ }
+ found = false;
+ }
+ }
+ if (smallestGoodTop < 0)
+ {
+ return false;
+ }
+
+ *destRow = smallestGoodTop;
+ if (destSize)
+ {
+ *destSize = smallestGoodSize;
+ }
+ return true;
+}
+
+bool VariablePacker::checkExpandedVariablesWithinPackingLimits(
+ unsigned int maxVectors,
+ std::vector<sh::ShaderVariable> *variables)
+{
+ ASSERT(maxVectors > 0);
+ maxRows_ = maxVectors;
+ topNonFullRow_ = 0;
+ bottomNonFullRow_ = maxRows_ - 1;
+
+ // Check whether each variable fits in the available vectors.
+ for (const sh::ShaderVariable &variable : *variables)
+ {
+ // Structs should have been expanded before reaching here.
+ ASSERT(!variable.isStruct());
+ if (variable.getArraySizeProduct() > maxVectors / GetTypePackingRows(variable.type))
+ {
+ return false;
+ }
+ }
+
+ // As per GLSL 1.017 Appendix A, Section 7 variables are packed in specific
+ // order by type, then by size of array, largest first.
+ std::sort(variables->begin(), variables->end(), TVariableInfoComparer());
+ rows_.clear();
+ rows_.resize(maxVectors, 0);
+
+ // Packs the 4 column variables.
+ size_t ii = 0;
+ for (; ii < variables->size(); ++ii)
+ {
+ const sh::ShaderVariable &variable = (*variables)[ii];
+ if (GetTypePackingComponentsPerRow(variable.type) != 4)
+ {
+ break;
+ }
+ topNonFullRow_ += GetVariablePackingRows(variable);
+ if (topNonFullRow_ > maxRows_)
+ {
+ return false;
+ }
+ }
+
+ // Packs the 3 column variables.
+ int num3ColumnRows = 0;
+ for (; ii < variables->size(); ++ii)
+ {
+ const sh::ShaderVariable &variable = (*variables)[ii];
+ if (GetTypePackingComponentsPerRow(variable.type) != 3)
+ {
+ break;
+ }
+
+ num3ColumnRows += GetVariablePackingRows(variable);
+ if (topNonFullRow_ + num3ColumnRows > maxRows_)
+ {
+ return false;
+ }
+ }
+
+ fillColumns(topNonFullRow_, num3ColumnRows, 0, 3);
+
+ // Packs the 2 column variables.
+ int top2ColumnRow = topNonFullRow_ + num3ColumnRows;
+ int twoColumnRowsAvailable = maxRows_ - top2ColumnRow;
+ int rowsAvailableInColumns01 = twoColumnRowsAvailable;
+ int rowsAvailableInColumns23 = twoColumnRowsAvailable;
+ for (; ii < variables->size(); ++ii)
+ {
+ const sh::ShaderVariable &variable = (*variables)[ii];
+ if (GetTypePackingComponentsPerRow(variable.type) != 2)
+ {
+ break;
+ }
+ int numRows = GetVariablePackingRows(variable);
+ if (numRows <= rowsAvailableInColumns01)
+ {
+ rowsAvailableInColumns01 -= numRows;
+ }
+ else if (numRows <= rowsAvailableInColumns23)
+ {
+ rowsAvailableInColumns23 -= numRows;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ int numRowsUsedInColumns01 = twoColumnRowsAvailable - rowsAvailableInColumns01;
+ int numRowsUsedInColumns23 = twoColumnRowsAvailable - rowsAvailableInColumns23;
+ fillColumns(top2ColumnRow, numRowsUsedInColumns01, 0, 2);
+ fillColumns(maxRows_ - numRowsUsedInColumns23, numRowsUsedInColumns23, 2, 2);
+
+ // Packs the 1 column variables.
+ for (; ii < variables->size(); ++ii)
+ {
+ const sh::ShaderVariable &variable = (*variables)[ii];
+ ASSERT(1 == GetTypePackingComponentsPerRow(variable.type));
+ int numRows = GetVariablePackingRows(variable);
+ int smallestColumn = -1;
+ int smallestSize = maxRows_ + 1;
+ int topRow = -1;
+ for (int column = 0; column < kNumColumns; ++column)
+ {
+ int row = 0;
+ int size = 0;
+ if (searchColumn(column, numRows, &row, &size))
+ {
+ if (size < smallestSize)
+ {
+ smallestSize = size;
+ smallestColumn = column;
+ topRow = row;
+ }
+ }
+ }
+
+ if (smallestColumn < 0)
+ {
+ return false;
+ }
+
+ fillColumns(topRow, numRows, smallestColumn, 1);
+ }
+
+ ASSERT(variables->size() == ii);
+
+ return true;
+}
+
+} // anonymous namespace
+
+int GetTypePackingComponentsPerRow(sh::GLenum type)
+{
+ switch (type)
+ {
+ case GL_FLOAT_MAT4:
+ case GL_FLOAT_MAT2:
+ case GL_FLOAT_MAT2x4:
+ case GL_FLOAT_MAT3x4:
+ case GL_FLOAT_MAT4x2:
+ case GL_FLOAT_MAT4x3:
+ case GL_FLOAT_VEC4:
+ case GL_INT_VEC4:
+ case GL_BOOL_VEC4:
+ case GL_UNSIGNED_INT_VEC4:
+ return 4;
+ case GL_FLOAT_MAT3:
+ case GL_FLOAT_MAT2x3:
+ case GL_FLOAT_MAT3x2:
+ case GL_FLOAT_VEC3:
+ case GL_INT_VEC3:
+ case GL_BOOL_VEC3:
+ case GL_UNSIGNED_INT_VEC3:
+ return 3;
+ case GL_FLOAT_VEC2:
+ case GL_INT_VEC2:
+ case GL_BOOL_VEC2:
+ case GL_UNSIGNED_INT_VEC2:
+ return 2;
+ default:
+ ASSERT(gl::VariableComponentCount(type) == 1);
+ return 1;
+ }
+}
+
+int GetTypePackingRows(sh::GLenum type)
+{
+ switch (type)
+ {
+ case GL_FLOAT_MAT4:
+ case GL_FLOAT_MAT2x4:
+ case GL_FLOAT_MAT3x4:
+ case GL_FLOAT_MAT4x3:
+ case GL_FLOAT_MAT4x2:
+ return 4;
+ case GL_FLOAT_MAT3:
+ case GL_FLOAT_MAT2x3:
+ case GL_FLOAT_MAT3x2:
+ return 3;
+ case GL_FLOAT_MAT2:
+ return 2;
+ default:
+ ASSERT(gl::VariableRowCount(type) == 1);
+ return 1;
+ }
+}
+
+bool CheckVariablesInPackingLimits(unsigned int maxVectors,
+ const std::vector<ShaderVariable> &variables)
+{
+ VariablePacker packer;
+ std::vector<sh::ShaderVariable> expandedVariables;
+ for (const ShaderVariable &variable : variables)
+ {
+ ExpandVariable(variable, variable.name, &expandedVariables);
+ }
+ return packer.checkExpandedVariablesWithinPackingLimits(maxVectors, &expandedVariables);
+}
+
+bool CheckVariablesInPackingLimits(unsigned int maxVectors,
+ const std::vector<ShaderVariable> &variables);
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/VariablePacker.h b/gfx/angle/checkout/src/compiler/translator/VariablePacker.h
new file mode 100644
index 0000000000..8cf621f168
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/VariablePacker.h
@@ -0,0 +1,32 @@
+//
+// Copyright 2002 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.
+//
+// Check whether variables fit within packing limits according to the packing rules from the GLSL ES
+// 1.00.17 spec, Appendix A, section 7.
+
+#ifndef COMPILER_TRANSLATOR_VARIABLEPACKER_H_
+#define COMPILER_TRANSLATOR_VARIABLEPACKER_H_
+
+#include <vector>
+
+#include <GLSLANG/ShaderLang.h>
+
+namespace sh
+{
+
+// Gets how many components in a row a data type takes.
+int GetTypePackingComponentsPerRow(sh::GLenum type);
+
+// Gets how many rows a data type takes.
+int GetTypePackingRows(sh::GLenum type);
+
+// Returns true if the passed in variables pack in maxVectors.
+// T should be ShaderVariable or one of the subclasses of ShaderVariable.
+bool CheckVariablesInPackingLimits(unsigned int maxVectors,
+ const std::vector<ShaderVariable> &variables);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_VARIABLEPACKER_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/VersionGLSL.cpp b/gfx/angle/checkout/src/compiler/translator/VersionGLSL.cpp
new file mode 100644
index 0000000000..3ff4216a0d
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/VersionGLSL.cpp
@@ -0,0 +1,156 @@
+//
+// Copyright 2002 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/VersionGLSL.h"
+
+#include "angle_gl.h"
+#include "compiler/translator/Symbol.h"
+
+namespace sh
+{
+
+namespace
+{
+constexpr const ImmutableString kGlPointCoordString("gl_PointCoord");
+} // anonymous namespace
+
+int ShaderOutputTypeToGLSLVersion(ShShaderOutput output)
+{
+ switch (output)
+ {
+ case SH_GLSL_130_OUTPUT:
+ return GLSL_VERSION_130;
+ case SH_GLSL_140_OUTPUT:
+ return GLSL_VERSION_140;
+ case SH_GLSL_150_CORE_OUTPUT:
+ return GLSL_VERSION_150;
+ case SH_GLSL_330_CORE_OUTPUT:
+ return GLSL_VERSION_330;
+ case SH_GLSL_400_CORE_OUTPUT:
+ return GLSL_VERSION_400;
+ case SH_GLSL_410_CORE_OUTPUT:
+ return GLSL_VERSION_410;
+ case SH_GLSL_420_CORE_OUTPUT:
+ return GLSL_VERSION_420;
+ case SH_GLSL_430_CORE_OUTPUT:
+ return GLSL_VERSION_430;
+ case SH_GLSL_440_CORE_OUTPUT:
+ return GLSL_VERSION_440;
+ case SH_GLSL_450_CORE_OUTPUT:
+ return GLSL_VERSION_450;
+ case SH_GLSL_COMPATIBILITY_OUTPUT:
+ return GLSL_VERSION_110;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+// We need to scan for the following:
+// 1. "invariant" keyword: This can occur in both - vertex and fragment shaders
+// but only at the global scope.
+// 2. "gl_PointCoord" built-in variable: This can only occur in fragment shader
+// but inside any scope.
+// 3. Call to a matrix constructor with another matrix as argument.
+// (These constructors were reserved in GLSL version 1.10.)
+// 4. Arrays as "out" function parameters.
+// GLSL spec section 6.1.1: "When calling a function, expressions that do
+// not evaluate to l-values cannot be passed to parameters declared as
+// out or inout."
+// GLSL 1.1 section 5.8: "Other binary or unary expressions,
+// non-dereferenced arrays, function names, swizzles with repeated fields,
+// and constants cannot be l-values."
+// GLSL 1.2 relaxed the restriction on arrays, section 5.8: "Variables that
+// are built-in types, entire structures or arrays... are all l-values."
+//
+TVersionGLSL::TVersionGLSL(sh::GLenum type, const TPragma &pragma, ShShaderOutput output)
+ : TIntermTraverser(true, false, false)
+{
+ mVersion = ShaderOutputTypeToGLSLVersion(output);
+ if (pragma.stdgl.invariantAll)
+ {
+ ensureVersionIsAtLeast(GLSL_VERSION_120);
+ }
+ if (type == GL_COMPUTE_SHADER)
+ {
+ ensureVersionIsAtLeast(GLSL_VERSION_430);
+ }
+}
+
+void TVersionGLSL::visitSymbol(TIntermSymbol *node)
+{
+ if (node->variable().symbolType() == SymbolType::BuiltIn &&
+ node->getName() == kGlPointCoordString)
+ {
+ ensureVersionIsAtLeast(GLSL_VERSION_120);
+ }
+}
+
+bool TVersionGLSL::visitDeclaration(Visit, TIntermDeclaration *node)
+{
+ const TIntermSequence &sequence = *(node->getSequence());
+ if (sequence.front()->getAsTyped()->getType().isInvariant())
+ {
+ ensureVersionIsAtLeast(GLSL_VERSION_120);
+ }
+ return true;
+}
+
+bool TVersionGLSL::visitGlobalQualifierDeclaration(Visit, TIntermGlobalQualifierDeclaration *node)
+{
+ if (node->isPrecise())
+ {
+ ensureVersionIsAtLeast(GLSL_VERSION_420);
+ }
+ else
+ {
+ ensureVersionIsAtLeast(GLSL_VERSION_120);
+ }
+ return true;
+}
+
+void TVersionGLSL::visitFunctionPrototype(TIntermFunctionPrototype *node)
+{
+ size_t paramCount = node->getFunction()->getParamCount();
+ for (size_t i = 0; i < paramCount; ++i)
+ {
+ const TVariable *param = node->getFunction()->getParam(i);
+ const TType &type = param->getType();
+ if (type.isArray())
+ {
+ TQualifier qualifier = type.getQualifier();
+ if ((qualifier == EvqParamOut) || (qualifier == EvqParamInOut))
+ {
+ ensureVersionIsAtLeast(GLSL_VERSION_120);
+ break;
+ }
+ }
+ }
+}
+
+bool TVersionGLSL::visitAggregate(Visit, TIntermAggregate *node)
+{
+ if (node->getOp() == EOpConstruct && node->getType().isMatrix())
+ {
+ const TIntermSequence &sequence = *(node->getSequence());
+ if (sequence.size() == 1)
+ {
+ TIntermTyped *typed = sequence.front()->getAsTyped();
+ if (typed && typed->isMatrix())
+ {
+ ensureVersionIsAtLeast(GLSL_VERSION_120);
+ }
+ }
+ }
+ return true;
+}
+
+void TVersionGLSL::ensureVersionIsAtLeast(int version)
+{
+ mVersion = std::max(version, mVersion);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/VersionGLSL.h b/gfx/angle/checkout/src/compiler/translator/VersionGLSL.h
new file mode 100644
index 0000000000..706e9125e1
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/VersionGLSL.h
@@ -0,0 +1,76 @@
+//
+// Copyright 2002 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_VERSIONGLSL_H_
+#define COMPILER_TRANSLATOR_VERSIONGLSL_H_
+
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+#include "compiler/translator/Pragma.h"
+
+namespace sh
+{
+
+static const int GLSL_VERSION_110 = 110;
+static const int GLSL_VERSION_120 = 120;
+static const int GLSL_VERSION_130 = 130;
+static const int GLSL_VERSION_140 = 140;
+static const int GLSL_VERSION_150 = 150;
+static const int GLSL_VERSION_330 = 330;
+static const int GLSL_VERSION_400 = 400;
+static const int GLSL_VERSION_410 = 410;
+static const int GLSL_VERSION_420 = 420;
+static const int GLSL_VERSION_430 = 430;
+static const int GLSL_VERSION_440 = 440;
+static const int GLSL_VERSION_450 = 450;
+
+int ShaderOutputTypeToGLSLVersion(ShShaderOutput output);
+
+// Traverses the intermediate tree to return the minimum GLSL version
+// required to legally access all built-in features used in the shader.
+// GLSL 1.1 which is mandated by OpenGL 2.0 provides:
+// - #version and #extension to declare version and extensions.
+// - built-in functions refract, exp, and log.
+// - updated step() to compare x < edge instead of x <= edge.
+// GLSL 1.2 which is mandated by OpenGL 2.1 provides:
+// - many changes to reduce differences when compared to the ES specification.
+// - invariant keyword and its support.
+// - c++ style name hiding rules.
+// - built-in variable gl_PointCoord for fragment shaders.
+// - matrix constructors taking matrix as argument.
+// - array as "out" function parameters
+//
+// TODO: ES3 equivalent versions of GLSL
+class TVersionGLSL : public TIntermTraverser
+{
+ public:
+ TVersionGLSL(sh::GLenum type, const TPragma &pragma, ShShaderOutput output);
+
+ // If output is core profile, returns 150.
+ // If output is legacy profile,
+ // Returns 120 if the following is used the shader:
+ // - "invariant",
+ // - "gl_PointCoord",
+ // - matrix/matrix constructors
+ // - array "out" parameters
+ // Else 110 is returned.
+ int getVersion() const { return mVersion; }
+
+ void visitSymbol(TIntermSymbol *node) override;
+ bool visitAggregate(Visit, TIntermAggregate *node) override;
+ bool visitGlobalQualifierDeclaration(Visit, TIntermGlobalQualifierDeclaration *node) override;
+ void visitFunctionPrototype(TIntermFunctionPrototype *node) override;
+ bool visitDeclaration(Visit, TIntermDeclaration *node) override;
+
+ private:
+ void ensureVersionIsAtLeast(int version);
+
+ int mVersion;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_VERSIONGLSL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/blocklayout.cpp b/gfx/angle/checkout/src/compiler/translator/blocklayout.cpp
new file mode 100644
index 0000000000..24a2640dca
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/blocklayout.cpp
@@ -0,0 +1,666 @@
+//
+// Copyright 2013 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.
+//
+// blocklayout.cpp:
+// Implementation for block layout classes and methods.
+//
+
+#include "compiler/translator/blocklayout.h"
+
+#include "common/mathutil.h"
+#include "common/utilities.h"
+#include "compiler/translator/Common.h"
+
+namespace sh
+{
+
+namespace
+{
+class BlockLayoutMapVisitor : public BlockEncoderVisitor
+{
+ public:
+ BlockLayoutMapVisitor(BlockLayoutMap *blockInfoOut,
+ const std::string &instanceName,
+ BlockLayoutEncoder *encoder)
+ : BlockEncoderVisitor(instanceName, instanceName, encoder), mInfoOut(blockInfoOut)
+ {}
+
+ void encodeVariable(const ShaderVariable &variable,
+ const BlockMemberInfo &variableInfo,
+ const std::string &name,
+ const std::string &mappedName) override
+ {
+ ASSERT(!gl::IsSamplerType(variable.type));
+ if (!gl::IsOpaqueType(variable.type))
+ {
+ (*mInfoOut)[name] = variableInfo;
+ }
+ }
+
+ private:
+ BlockLayoutMap *mInfoOut;
+};
+
+template <typename VarT>
+void GetInterfaceBlockInfo(const std::vector<VarT> &fields,
+ const std::string &prefix,
+ BlockLayoutEncoder *encoder,
+ bool inRowMajorLayout,
+ bool onlyActiveVariables,
+ BlockLayoutMap *blockInfoOut)
+{
+ BlockLayoutMapVisitor visitor(blockInfoOut, prefix, encoder);
+ if (onlyActiveVariables)
+ {
+ TraverseActiveShaderVariables(fields, inRowMajorLayout, &visitor);
+ }
+ else
+ {
+ TraverseShaderVariables(fields, inRowMajorLayout, &visitor);
+ }
+}
+
+void TraverseStructVariable(const ShaderVariable &variable,
+ bool isRowMajorLayout,
+ ShaderVariableVisitor *visitor)
+{
+ const std::vector<ShaderVariable> &fields = variable.fields;
+
+ visitor->enterStructAccess(variable, isRowMajorLayout);
+ TraverseShaderVariables(fields, isRowMajorLayout, visitor);
+ visitor->exitStructAccess(variable, isRowMajorLayout);
+}
+
+void TraverseStructArrayVariable(const ShaderVariable &variable,
+ bool inRowMajorLayout,
+ ShaderVariableVisitor *visitor)
+{
+ visitor->enterArray(variable);
+
+ // Nested arrays are processed starting from outermost (arrayNestingIndex 0u) and ending at the
+ // innermost. We make a special case for unsized arrays.
+ const unsigned int currentArraySize = variable.getNestedArraySize(0);
+ for (unsigned int arrayElement = 0u; arrayElement < currentArraySize; ++arrayElement)
+ {
+ visitor->enterArrayElement(variable, arrayElement);
+ ShaderVariable elementVar = variable;
+ elementVar.indexIntoArray(arrayElement);
+
+ if (variable.arraySizes.size() > 1u)
+ {
+ TraverseStructArrayVariable(elementVar, inRowMajorLayout, visitor);
+ }
+ else
+ {
+ TraverseStructVariable(elementVar, inRowMajorLayout, visitor);
+ }
+
+ visitor->exitArrayElement(variable, arrayElement);
+ }
+
+ visitor->exitArray(variable);
+}
+
+void TraverseArrayOfArraysVariable(const ShaderVariable &variable,
+ unsigned int arrayNestingIndex,
+ bool isRowMajorMatrix,
+ ShaderVariableVisitor *visitor)
+{
+ visitor->enterArray(variable);
+
+ const unsigned int currentArraySize = variable.getNestedArraySize(arrayNestingIndex);
+ unsigned int count = std::max(currentArraySize, 1u);
+ for (unsigned int arrayElement = 0u; arrayElement < count; ++arrayElement)
+ {
+ visitor->enterArrayElement(variable, arrayElement);
+
+ ShaderVariable elementVar = variable;
+ elementVar.indexIntoArray(arrayElement);
+
+ if (arrayNestingIndex + 2u < variable.arraySizes.size())
+ {
+ TraverseArrayOfArraysVariable(elementVar, arrayNestingIndex, isRowMajorMatrix, visitor);
+ }
+ else
+ {
+ if (gl::IsSamplerType(variable.type) || gl::IsImageType(variable.type) ||
+ variable.isFragmentInOut)
+ {
+ visitor->visitOpaqueObject(elementVar);
+ }
+ else
+ {
+ visitor->visitVariable(elementVar, isRowMajorMatrix);
+ }
+ }
+
+ visitor->exitArrayElement(variable, arrayElement);
+ }
+
+ visitor->exitArray(variable);
+}
+
+std::string CollapseNameStack(const std::vector<std::string> &nameStack)
+{
+ std::stringstream strstr = sh::InitializeStream<std::stringstream>();
+ for (const std::string &part : nameStack)
+ {
+ strstr << part;
+ }
+ return strstr.str();
+}
+
+size_t GetStd430BaseAlignment(GLenum variableType, bool isRowMajor)
+{
+ GLenum flippedType = isRowMajor ? variableType : gl::TransposeMatrixType(variableType);
+ size_t numComponents = static_cast<size_t>(gl::VariableColumnCount(flippedType));
+ return ComponentAlignment(numComponents);
+}
+
+class BaseAlignmentVisitor : public ShaderVariableVisitor
+{
+ public:
+ BaseAlignmentVisitor() = default;
+ void visitVariable(const ShaderVariable &variable, bool isRowMajor) override
+ {
+ size_t baseAlignment = GetStd430BaseAlignment(variable.type, isRowMajor);
+ mCurrentAlignment = std::max(mCurrentAlignment, baseAlignment);
+ }
+
+ // This is in components rather than bytes.
+ size_t getBaseAlignment() const { return mCurrentAlignment; }
+
+ private:
+ size_t mCurrentAlignment = 0;
+};
+} // anonymous namespace
+
+// BlockLayoutEncoder implementation.
+BlockLayoutEncoder::BlockLayoutEncoder() : mCurrentOffset(0) {}
+
+BlockMemberInfo BlockLayoutEncoder::encodeType(GLenum type,
+ const std::vector<unsigned int> &arraySizes,
+ bool isRowMajorMatrix)
+{
+ int arrayStride;
+ int matrixStride;
+
+ getBlockLayoutInfo(type, arraySizes, isRowMajorMatrix, &arrayStride, &matrixStride);
+
+ const BlockMemberInfo memberInfo(static_cast<int>(mCurrentOffset * kBytesPerComponent),
+ static_cast<int>(arrayStride * kBytesPerComponent),
+ static_cast<int>(matrixStride * kBytesPerComponent),
+ isRowMajorMatrix);
+
+ advanceOffset(type, arraySizes, isRowMajorMatrix, arrayStride, matrixStride);
+
+ return memberInfo;
+}
+
+BlockMemberInfo BlockLayoutEncoder::encodeArrayOfPreEncodedStructs(
+ size_t size,
+ const std::vector<unsigned int> &arraySizes)
+{
+ const unsigned int innerArraySizeProduct = gl::InnerArraySizeProduct(arraySizes);
+ const unsigned int outermostArraySize = gl::OutermostArraySize(arraySizes);
+
+ // The size of struct is expected to be already aligned appropriately.
+ const size_t arrayStride = size * innerArraySizeProduct;
+
+ const BlockMemberInfo memberInfo(static_cast<int>(mCurrentOffset * kBytesPerComponent),
+ static_cast<int>(arrayStride), -1, false);
+
+ angle::base::CheckedNumeric<size_t> checkedOffset(arrayStride);
+ checkedOffset *= outermostArraySize;
+ checkedOffset /= kBytesPerComponent;
+ checkedOffset += mCurrentOffset;
+ mCurrentOffset = checkedOffset.ValueOrDefault(std::numeric_limits<size_t>::max());
+
+ return memberInfo;
+}
+
+size_t BlockLayoutEncoder::getCurrentOffset() const
+{
+ angle::base::CheckedNumeric<size_t> checkedOffset(mCurrentOffset);
+ checkedOffset *= kBytesPerComponent;
+ return checkedOffset.ValueOrDefault(std::numeric_limits<size_t>::max());
+}
+
+size_t BlockLayoutEncoder::getShaderVariableSize(const ShaderVariable &structVar, bool isRowMajor)
+{
+ size_t currentOffset = mCurrentOffset;
+ mCurrentOffset = 0;
+ BlockEncoderVisitor visitor("", "", this);
+ enterAggregateType(structVar);
+ TraverseShaderVariables(structVar.fields, isRowMajor, &visitor);
+ exitAggregateType(structVar);
+ size_t structVarSize = getCurrentOffset();
+ mCurrentOffset = currentOffset;
+ return structVarSize;
+}
+
+// static
+size_t BlockLayoutEncoder::GetBlockRegister(const BlockMemberInfo &info)
+{
+ return (info.offset / kBytesPerComponent) / kComponentsPerRegister;
+}
+
+// static
+size_t BlockLayoutEncoder::GetBlockRegisterElement(const BlockMemberInfo &info)
+{
+ return (info.offset / kBytesPerComponent) % kComponentsPerRegister;
+}
+
+void BlockLayoutEncoder::align(size_t baseAlignment)
+{
+ angle::base::CheckedNumeric<size_t> checkedOffset(mCurrentOffset);
+ checkedOffset += baseAlignment;
+ checkedOffset -= 1;
+ angle::base::CheckedNumeric<size_t> checkedAlignmentOffset = checkedOffset;
+ checkedAlignmentOffset %= baseAlignment;
+ checkedOffset -= checkedAlignmentOffset.ValueOrDefault(std::numeric_limits<size_t>::max());
+ mCurrentOffset = checkedOffset.ValueOrDefault(std::numeric_limits<size_t>::max());
+}
+
+// StubBlockEncoder implementation.
+void StubBlockEncoder::getBlockLayoutInfo(GLenum type,
+ const std::vector<unsigned int> &arraySizes,
+ bool isRowMajorMatrix,
+ int *arrayStrideOut,
+ int *matrixStrideOut)
+{
+ *arrayStrideOut = 0;
+ *matrixStrideOut = 0;
+}
+
+// Std140BlockEncoder implementation.
+Std140BlockEncoder::Std140BlockEncoder() {}
+
+void Std140BlockEncoder::enterAggregateType(const ShaderVariable &structVar)
+{
+ align(getBaseAlignment(structVar));
+}
+
+void Std140BlockEncoder::exitAggregateType(const ShaderVariable &structVar)
+{
+ align(getBaseAlignment(structVar));
+}
+
+void Std140BlockEncoder::getBlockLayoutInfo(GLenum type,
+ const std::vector<unsigned int> &arraySizes,
+ bool isRowMajorMatrix,
+ int *arrayStrideOut,
+ int *matrixStrideOut)
+{
+ // We assume we are only dealing with 4 byte components (no doubles or half-words currently)
+ ASSERT(gl::VariableComponentSize(gl::VariableComponentType(type)) == kBytesPerComponent);
+
+ size_t baseAlignment = 0;
+ int matrixStride = 0;
+ int arrayStride = 0;
+
+ if (gl::IsMatrixType(type))
+ {
+ baseAlignment = getTypeBaseAlignment(type, isRowMajorMatrix);
+ matrixStride = static_cast<int>(getTypeBaseAlignment(type, isRowMajorMatrix));
+
+ if (!arraySizes.empty())
+ {
+ const int numRegisters = gl::MatrixRegisterCount(type, isRowMajorMatrix);
+ arrayStride =
+ static_cast<int>(getTypeBaseAlignment(type, isRowMajorMatrix) * numRegisters);
+ }
+ }
+ else if (!arraySizes.empty())
+ {
+ baseAlignment = static_cast<int>(getTypeBaseAlignment(type, false));
+ arrayStride = static_cast<int>(getTypeBaseAlignment(type, false));
+ }
+ else
+ {
+ const size_t numComponents = static_cast<size_t>(gl::VariableComponentCount(type));
+ baseAlignment = ComponentAlignment(numComponents);
+ }
+
+ align(baseAlignment);
+
+ *matrixStrideOut = matrixStride;
+ *arrayStrideOut = arrayStride;
+}
+
+void Std140BlockEncoder::advanceOffset(GLenum type,
+ const std::vector<unsigned int> &arraySizes,
+ bool isRowMajorMatrix,
+ int arrayStride,
+ int matrixStride)
+{
+ if (!arraySizes.empty())
+ {
+ angle::base::CheckedNumeric<size_t> checkedOffset(arrayStride);
+ checkedOffset *= gl::ArraySizeProduct(arraySizes);
+ checkedOffset += mCurrentOffset;
+ mCurrentOffset = checkedOffset.ValueOrDefault(std::numeric_limits<size_t>::max());
+ }
+ else if (gl::IsMatrixType(type))
+ {
+ angle::base::CheckedNumeric<size_t> checkedOffset(matrixStride);
+ checkedOffset *= gl::MatrixRegisterCount(type, isRowMajorMatrix);
+ checkedOffset += mCurrentOffset;
+ mCurrentOffset = checkedOffset.ValueOrDefault(std::numeric_limits<size_t>::max());
+ }
+ else
+ {
+ angle::base::CheckedNumeric<size_t> checkedOffset(mCurrentOffset);
+ checkedOffset += gl::VariableComponentCount(type);
+ mCurrentOffset = checkedOffset.ValueOrDefault(std::numeric_limits<size_t>::max());
+ }
+}
+
+size_t Std140BlockEncoder::getBaseAlignment(const ShaderVariable &variable) const
+{
+ return kComponentsPerRegister;
+}
+
+size_t Std140BlockEncoder::getTypeBaseAlignment(GLenum type, bool isRowMajorMatrix) const
+{
+ return kComponentsPerRegister;
+}
+
+// Std430BlockEncoder implementation.
+Std430BlockEncoder::Std430BlockEncoder() {}
+
+size_t Std430BlockEncoder::getBaseAlignment(const ShaderVariable &shaderVar) const
+{
+ if (shaderVar.isStruct())
+ {
+ BaseAlignmentVisitor visitor;
+ TraverseShaderVariables(shaderVar.fields, false, &visitor);
+ return visitor.getBaseAlignment();
+ }
+
+ return GetStd430BaseAlignment(shaderVar.type, shaderVar.isRowMajorLayout);
+}
+
+size_t Std430BlockEncoder::getTypeBaseAlignment(GLenum type, bool isRowMajorMatrix) const
+{
+ return GetStd430BaseAlignment(type, isRowMajorMatrix);
+}
+
+void GetInterfaceBlockInfo(const std::vector<ShaderVariable> &fields,
+ const std::string &prefix,
+ BlockLayoutEncoder *encoder,
+ BlockLayoutMap *blockInfoOut)
+{
+ // Matrix packing is always recorded in individual fields, so they'll set the row major layout
+ // flag to true if needed.
+ // Iterates over all variables.
+ GetInterfaceBlockInfo(fields, prefix, encoder, false, false, blockInfoOut);
+}
+
+void GetActiveUniformBlockInfo(const std::vector<ShaderVariable> &uniforms,
+ const std::string &prefix,
+ BlockLayoutEncoder *encoder,
+ BlockLayoutMap *blockInfoOut)
+{
+ // Matrix packing is always recorded in individual fields, so they'll set the row major layout
+ // flag to true if needed.
+ // Iterates only over the active variables.
+ GetInterfaceBlockInfo(uniforms, prefix, encoder, false, true, blockInfoOut);
+}
+
+// VariableNameVisitor implementation.
+VariableNameVisitor::VariableNameVisitor(const std::string &namePrefix,
+ const std::string &mappedNamePrefix)
+{
+ if (!namePrefix.empty())
+ {
+ mNameStack.push_back(namePrefix + ".");
+ }
+
+ if (!mappedNamePrefix.empty())
+ {
+ mMappedNameStack.push_back(mappedNamePrefix + ".");
+ }
+}
+
+VariableNameVisitor::~VariableNameVisitor() = default;
+
+void VariableNameVisitor::enterStruct(const ShaderVariable &structVar)
+{
+ mNameStack.push_back(structVar.name);
+ mMappedNameStack.push_back(structVar.mappedName);
+}
+
+void VariableNameVisitor::exitStruct(const ShaderVariable &structVar)
+{
+ mNameStack.pop_back();
+ mMappedNameStack.pop_back();
+}
+
+void VariableNameVisitor::enterStructAccess(const ShaderVariable &structVar, bool isRowMajor)
+{
+ mNameStack.push_back(".");
+ mMappedNameStack.push_back(".");
+}
+
+void VariableNameVisitor::exitStructAccess(const ShaderVariable &structVar, bool isRowMajor)
+{
+ mNameStack.pop_back();
+ mMappedNameStack.pop_back();
+}
+
+void VariableNameVisitor::enterArray(const ShaderVariable &arrayVar)
+{
+ if (!arrayVar.hasParentArrayIndex() && !arrayVar.isStruct())
+ {
+ mNameStack.push_back(arrayVar.name);
+ mMappedNameStack.push_back(arrayVar.mappedName);
+ }
+ mArraySizeStack.push_back(arrayVar.getOutermostArraySize());
+}
+
+void VariableNameVisitor::exitArray(const ShaderVariable &arrayVar)
+{
+ if (!arrayVar.hasParentArrayIndex() && !arrayVar.isStruct())
+ {
+ mNameStack.pop_back();
+ mMappedNameStack.pop_back();
+ }
+ mArraySizeStack.pop_back();
+}
+
+void VariableNameVisitor::enterArrayElement(const ShaderVariable &arrayVar,
+ unsigned int arrayElement)
+{
+ std::stringstream strstr = sh::InitializeStream<std::stringstream>();
+ strstr << "[" << arrayElement << "]";
+ std::string elementString = strstr.str();
+ mNameStack.push_back(elementString);
+ mMappedNameStack.push_back(elementString);
+}
+
+void VariableNameVisitor::exitArrayElement(const ShaderVariable &arrayVar,
+ unsigned int arrayElement)
+{
+ mNameStack.pop_back();
+ mMappedNameStack.pop_back();
+}
+
+std::string VariableNameVisitor::collapseNameStack() const
+{
+ return CollapseNameStack(mNameStack);
+}
+
+std::string VariableNameVisitor::collapseMappedNameStack() const
+{
+ return CollapseNameStack(mMappedNameStack);
+}
+
+void VariableNameVisitor::visitOpaqueObject(const sh::ShaderVariable &variable)
+{
+ if (!variable.hasParentArrayIndex())
+ {
+ mNameStack.push_back(variable.name);
+ mMappedNameStack.push_back(variable.mappedName);
+ }
+
+ std::string name = collapseNameStack();
+ std::string mappedName = collapseMappedNameStack();
+
+ if (!variable.hasParentArrayIndex())
+ {
+ mNameStack.pop_back();
+ mMappedNameStack.pop_back();
+ }
+
+ visitNamedOpaqueObject(variable, name, mappedName, mArraySizeStack);
+}
+
+void VariableNameVisitor::visitVariable(const ShaderVariable &variable, bool isRowMajor)
+{
+ if (!variable.hasParentArrayIndex())
+ {
+ mNameStack.push_back(variable.name);
+ mMappedNameStack.push_back(variable.mappedName);
+ }
+
+ std::string name = collapseNameStack();
+ std::string mappedName = collapseMappedNameStack();
+
+ if (!variable.hasParentArrayIndex())
+ {
+ mNameStack.pop_back();
+ mMappedNameStack.pop_back();
+ }
+
+ visitNamedVariable(variable, isRowMajor, name, mappedName, mArraySizeStack);
+}
+
+// BlockEncoderVisitor implementation.
+BlockEncoderVisitor::BlockEncoderVisitor(const std::string &namePrefix,
+ const std::string &mappedNamePrefix,
+ BlockLayoutEncoder *encoder)
+ : VariableNameVisitor(namePrefix, mappedNamePrefix), mEncoder(encoder)
+{}
+
+BlockEncoderVisitor::~BlockEncoderVisitor() = default;
+
+void BlockEncoderVisitor::enterStructAccess(const ShaderVariable &structVar, bool isRowMajor)
+{
+ mStructStackSize++;
+ if (!mIsTopLevelArrayStrideReady)
+ {
+ size_t structSize = mEncoder->getShaderVariableSize(structVar, isRowMajor);
+ mTopLevelArrayStride *= structSize;
+ mIsTopLevelArrayStrideReady = true;
+ }
+
+ VariableNameVisitor::enterStructAccess(structVar, isRowMajor);
+ mEncoder->enterAggregateType(structVar);
+}
+
+void BlockEncoderVisitor::exitStructAccess(const ShaderVariable &structVar, bool isRowMajor)
+{
+ mStructStackSize--;
+ mEncoder->exitAggregateType(structVar);
+ VariableNameVisitor::exitStructAccess(structVar, isRowMajor);
+}
+
+void BlockEncoderVisitor::enterArrayElement(const sh::ShaderVariable &arrayVar,
+ unsigned int arrayElement)
+{
+ if (mStructStackSize == 0 && !arrayVar.hasParentArrayIndex())
+ {
+ // From the ES 3.1 spec "7.3.1.1 Naming Active Resources":
+ // For an active shader storage block member declared as an array of an aggregate type,
+ // an entry will be generated only for the first array element, regardless of its type.
+ // Such block members are referred to as top-level arrays. If the block member is an
+ // aggregate type, the enumeration rules are then applied recursively.
+ if (arrayElement == 0)
+ {
+ mTopLevelArraySize = arrayVar.getOutermostArraySize();
+ mTopLevelArrayStride = arrayVar.getInnerArraySizeProduct();
+ mIsTopLevelArrayStrideReady = false;
+ }
+ else
+ {
+ mSkipEnabled = true;
+ }
+ }
+ VariableNameVisitor::enterArrayElement(arrayVar, arrayElement);
+}
+
+void BlockEncoderVisitor::exitArrayElement(const sh::ShaderVariable &arrayVar,
+ unsigned int arrayElement)
+{
+ if (mStructStackSize == 0 && !arrayVar.hasParentArrayIndex())
+ {
+ mTopLevelArraySize = 1;
+ mTopLevelArrayStride = 0;
+ mIsTopLevelArrayStrideReady = true;
+ mSkipEnabled = false;
+ }
+ VariableNameVisitor::exitArrayElement(arrayVar, arrayElement);
+}
+
+void BlockEncoderVisitor::visitNamedVariable(const ShaderVariable &variable,
+ bool isRowMajor,
+ const std::string &name,
+ const std::string &mappedName,
+ const std::vector<unsigned int> &arraySizes)
+{
+ std::vector<unsigned int> innermostArraySize;
+
+ if (variable.isArray())
+ {
+ innermostArraySize.push_back(variable.getNestedArraySize(0));
+ }
+ BlockMemberInfo variableInfo =
+ mEncoder->encodeType(variable.type, innermostArraySize, isRowMajor);
+ if (!mIsTopLevelArrayStrideReady)
+ {
+ ASSERT(mTopLevelArrayStride);
+ mTopLevelArrayStride *= variableInfo.arrayStride;
+ mIsTopLevelArrayStrideReady = true;
+ }
+ variableInfo.topLevelArrayStride = mTopLevelArrayStride;
+ encodeVariable(variable, variableInfo, name, mappedName);
+}
+
+void TraverseShaderVariable(const ShaderVariable &variable,
+ bool isRowMajorLayout,
+ ShaderVariableVisitor *visitor)
+{
+ bool rowMajorLayout = (isRowMajorLayout || variable.isRowMajorLayout);
+ bool isRowMajor = rowMajorLayout && gl::IsMatrixType(variable.type);
+
+ if (variable.isStruct())
+ {
+ visitor->enterStruct(variable);
+ if (variable.isArray())
+ {
+ TraverseStructArrayVariable(variable, rowMajorLayout, visitor);
+ }
+ else
+ {
+ TraverseStructVariable(variable, rowMajorLayout, visitor);
+ }
+ visitor->exitStruct(variable);
+ }
+ else if (variable.isArrayOfArrays())
+ {
+ TraverseArrayOfArraysVariable(variable, 0u, isRowMajor, visitor);
+ }
+ else if (gl::IsSamplerType(variable.type) || gl::IsImageType(variable.type) ||
+ variable.isFragmentInOut)
+ {
+ visitor->visitOpaqueObject(variable);
+ }
+ else
+ {
+ visitor->visitVariable(variable, isRowMajor);
+ }
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/blocklayout.h b/gfx/angle/checkout/src/compiler/translator/blocklayout.h
new file mode 100644
index 0000000000..97f9daa251
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/blocklayout.h
@@ -0,0 +1,322 @@
+//
+// Copyright 2013 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.
+//
+// blocklayout.h:
+// Methods and classes related to uniform layout and packing in GLSL and HLSL.
+//
+
+#ifndef COMMON_BLOCKLAYOUT_H_
+#define COMMON_BLOCKLAYOUT_H_
+
+#include <cstddef>
+#include <map>
+#include <vector>
+
+#include <GLSLANG/ShaderLang.h>
+#include "angle_gl.h"
+
+namespace sh
+{
+struct ShaderVariable;
+struct InterfaceBlock;
+
+struct BlockMemberInfo
+{
+ constexpr BlockMemberInfo() = default;
+
+ constexpr BlockMemberInfo(int offset, int arrayStride, int matrixStride, bool isRowMajorMatrix)
+ : offset(offset),
+ arrayStride(arrayStride),
+ matrixStride(matrixStride),
+ isRowMajorMatrix(isRowMajorMatrix)
+ {}
+
+ constexpr BlockMemberInfo(int offset,
+ int arrayStride,
+ int matrixStride,
+ bool isRowMajorMatrix,
+ int topLevelArrayStride)
+ : offset(offset),
+ arrayStride(arrayStride),
+ matrixStride(matrixStride),
+ isRowMajorMatrix(isRowMajorMatrix),
+ topLevelArrayStride(topLevelArrayStride)
+ {}
+
+ // A single integer identifying the offset of an active variable.
+ int offset = -1;
+
+ // A single integer identifying the stride between array elements in an active variable.
+ int arrayStride = -1;
+
+ // A single integer identifying the stride between columns of a column-major matrix or rows of a
+ // row-major matrix.
+ int matrixStride = -1;
+
+ // A single integer identifying whether an active variable is a row-major matrix.
+ bool isRowMajorMatrix = false;
+
+ // A single integer identifying the number of active array elements of the top-level shader
+ // storage block member containing the active variable.
+ int topLevelArrayStride = -1;
+};
+
+constexpr size_t ComponentAlignment(size_t numComponents)
+{
+ return (numComponents == 3u ? 4u : numComponents);
+}
+
+constexpr BlockMemberInfo kDefaultBlockMemberInfo;
+
+class BlockLayoutEncoder
+{
+ public:
+ BlockLayoutEncoder();
+ virtual ~BlockLayoutEncoder() {}
+
+ BlockMemberInfo encodeType(GLenum type,
+ const std::vector<unsigned int> &arraySizes,
+ bool isRowMajorMatrix);
+ // Advance the offset based on struct size and array dimensions. Size can be calculated with
+ // getShaderVariableSize() or equivalent. |enterAggregateType|/|exitAggregateType| is necessary
+ // around this call.
+ BlockMemberInfo encodeArrayOfPreEncodedStructs(size_t size,
+ const std::vector<unsigned int> &arraySizes);
+
+ size_t getCurrentOffset() const;
+ size_t getShaderVariableSize(const ShaderVariable &structVar, bool isRowMajor);
+
+ // Called when entering/exiting a structure variable.
+ virtual void enterAggregateType(const ShaderVariable &structVar) = 0;
+ virtual void exitAggregateType(const ShaderVariable &structVar) = 0;
+
+ static constexpr size_t kBytesPerComponent = 4u;
+ static constexpr unsigned int kComponentsPerRegister = 4u;
+
+ static size_t GetBlockRegister(const BlockMemberInfo &info);
+ static size_t GetBlockRegisterElement(const BlockMemberInfo &info);
+
+ protected:
+ void align(size_t baseAlignment);
+
+ virtual void getBlockLayoutInfo(GLenum type,
+ const std::vector<unsigned int> &arraySizes,
+ bool isRowMajorMatrix,
+ int *arrayStrideOut,
+ int *matrixStrideOut) = 0;
+ virtual void advanceOffset(GLenum type,
+ const std::vector<unsigned int> &arraySizes,
+ bool isRowMajorMatrix,
+ int arrayStride,
+ int matrixStride) = 0;
+
+ size_t mCurrentOffset;
+};
+
+// Will return default values for everything.
+class StubBlockEncoder : public BlockLayoutEncoder
+{
+ public:
+ StubBlockEncoder() = default;
+
+ void enterAggregateType(const ShaderVariable &structVar) override {}
+ void exitAggregateType(const ShaderVariable &structVar) override {}
+
+ protected:
+ void getBlockLayoutInfo(GLenum type,
+ const std::vector<unsigned int> &arraySizes,
+ bool isRowMajorMatrix,
+ int *arrayStrideOut,
+ int *matrixStrideOut) override;
+
+ void advanceOffset(GLenum type,
+ const std::vector<unsigned int> &arraySizes,
+ bool isRowMajorMatrix,
+ int arrayStride,
+ int matrixStride) override
+ {}
+};
+
+// Block layout according to the std140 block layout
+// See "Standard Uniform Block Layout" in Section 2.11.6 of the OpenGL ES 3.0 specification
+
+class Std140BlockEncoder : public BlockLayoutEncoder
+{
+ public:
+ Std140BlockEncoder();
+
+ void enterAggregateType(const ShaderVariable &structVar) override;
+ void exitAggregateType(const ShaderVariable &structVar) override;
+
+ protected:
+ void getBlockLayoutInfo(GLenum type,
+ const std::vector<unsigned int> &arraySizes,
+ bool isRowMajorMatrix,
+ int *arrayStrideOut,
+ int *matrixStrideOut) override;
+ void advanceOffset(GLenum type,
+ const std::vector<unsigned int> &arraySizes,
+ bool isRowMajorMatrix,
+ int arrayStride,
+ int matrixStride) override;
+
+ virtual size_t getBaseAlignment(const ShaderVariable &variable) const;
+ virtual size_t getTypeBaseAlignment(GLenum type, bool isRowMajorMatrix) const;
+};
+
+class Std430BlockEncoder : public Std140BlockEncoder
+{
+ public:
+ Std430BlockEncoder();
+
+ protected:
+ size_t getBaseAlignment(const ShaderVariable &variable) const override;
+ size_t getTypeBaseAlignment(GLenum type, bool isRowMajorMatrix) const override;
+};
+
+using BlockLayoutMap = std::map<std::string, BlockMemberInfo>;
+
+void GetInterfaceBlockInfo(const std::vector<ShaderVariable> &fields,
+ const std::string &prefix,
+ BlockLayoutEncoder *encoder,
+ BlockLayoutMap *blockInfoOut);
+
+// Used for laying out the default uniform block on the Vulkan backend.
+void GetActiveUniformBlockInfo(const std::vector<ShaderVariable> &uniforms,
+ const std::string &prefix,
+ BlockLayoutEncoder *encoder,
+ BlockLayoutMap *blockInfoOut);
+
+class ShaderVariableVisitor
+{
+ public:
+ virtual ~ShaderVariableVisitor() {}
+
+ virtual void enterStruct(const ShaderVariable &structVar) {}
+ virtual void exitStruct(const ShaderVariable &structVar) {}
+
+ virtual void enterStructAccess(const ShaderVariable &structVar, bool isRowMajor) {}
+ virtual void exitStructAccess(const ShaderVariable &structVar, bool isRowMajor) {}
+
+ virtual void enterArray(const ShaderVariable &arrayVar) {}
+ virtual void exitArray(const ShaderVariable &arrayVar) {}
+
+ virtual void enterArrayElement(const ShaderVariable &arrayVar, unsigned int arrayElement) {}
+ virtual void exitArrayElement(const ShaderVariable &arrayVar, unsigned int arrayElement) {}
+
+ virtual void visitOpaqueObject(const sh::ShaderVariable &variable) {}
+
+ virtual void visitVariable(const ShaderVariable &variable, bool isRowMajor) = 0;
+
+ protected:
+ ShaderVariableVisitor() {}
+};
+
+class VariableNameVisitor : public ShaderVariableVisitor
+{
+ public:
+ VariableNameVisitor(const std::string &namePrefix, const std::string &mappedNamePrefix);
+ ~VariableNameVisitor() override;
+
+ void enterStruct(const ShaderVariable &structVar) override;
+ void exitStruct(const ShaderVariable &structVar) override;
+ void enterStructAccess(const ShaderVariable &structVar, bool isRowMajor) override;
+ void exitStructAccess(const ShaderVariable &structVar, bool isRowMajor) override;
+ void enterArray(const ShaderVariable &arrayVar) override;
+ void exitArray(const ShaderVariable &arrayVar) override;
+ void enterArrayElement(const ShaderVariable &arrayVar, unsigned int arrayElement) override;
+ void exitArrayElement(const ShaderVariable &arrayVar, unsigned int arrayElement) override;
+
+ protected:
+ virtual void visitNamedOpaqueObject(const sh::ShaderVariable &variable,
+ const std::string &name,
+ const std::string &mappedName,
+ const std::vector<unsigned int> &arraySizes)
+ {}
+ virtual void visitNamedVariable(const ShaderVariable &variable,
+ bool isRowMajor,
+ const std::string &name,
+ const std::string &mappedName,
+ const std::vector<unsigned int> &arraySizes) = 0;
+
+ std::string collapseNameStack() const;
+ std::string collapseMappedNameStack() const;
+
+ private:
+ void visitOpaqueObject(const sh::ShaderVariable &variable) final;
+ void visitVariable(const ShaderVariable &variable, bool isRowMajor) final;
+
+ std::vector<std::string> mNameStack;
+ std::vector<std::string> mMappedNameStack;
+ std::vector<unsigned int> mArraySizeStack;
+};
+
+class BlockEncoderVisitor : public VariableNameVisitor
+{
+ public:
+ BlockEncoderVisitor(const std::string &namePrefix,
+ const std::string &mappedNamePrefix,
+ BlockLayoutEncoder *encoder);
+ ~BlockEncoderVisitor() override;
+
+ void enterStructAccess(const ShaderVariable &structVar, bool isRowMajor) override;
+ void exitStructAccess(const ShaderVariable &structVar, bool isRowMajor) override;
+ void enterArrayElement(const ShaderVariable &arrayVar, unsigned int arrayElement) override;
+ void exitArrayElement(const ShaderVariable &arrayVar, unsigned int arrayElement) override;
+
+ void visitNamedVariable(const ShaderVariable &variable,
+ bool isRowMajor,
+ const std::string &name,
+ const std::string &mappedName,
+ const std::vector<unsigned int> &arraySizes) override;
+
+ virtual void encodeVariable(const ShaderVariable &variable,
+ const BlockMemberInfo &variableInfo,
+ const std::string &name,
+ const std::string &mappedName)
+ {}
+
+ protected:
+ int mTopLevelArraySize = 1;
+ int mTopLevelArrayStride = 0;
+ bool mIsTopLevelArrayStrideReady = true;
+ bool mSkipEnabled = false;
+
+ private:
+ BlockLayoutEncoder *mEncoder;
+ unsigned int mStructStackSize = 0;
+};
+
+void TraverseShaderVariable(const ShaderVariable &variable,
+ bool isRowMajorLayout,
+ ShaderVariableVisitor *visitor);
+
+template <typename T>
+void TraverseShaderVariables(const std::vector<T> &vars,
+ bool isRowMajorLayout,
+ ShaderVariableVisitor *visitor)
+{
+ for (const T &var : vars)
+ {
+ TraverseShaderVariable(var, isRowMajorLayout, visitor);
+ }
+}
+
+template <typename T>
+void TraverseActiveShaderVariables(const std::vector<T> &vars,
+ bool isRowMajorLayout,
+ ShaderVariableVisitor *visitor)
+{
+ for (const T &var : vars)
+ {
+ if (var.active)
+ {
+ TraverseShaderVariable(var, isRowMajorLayout, visitor);
+ }
+ }
+}
+} // namespace sh
+
+#endif // COMMON_BLOCKLAYOUT_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/blocklayoutHLSL.cpp b/gfx/angle/checkout/src/compiler/translator/blocklayoutHLSL.cpp
new file mode 100644
index 0000000000..9030c7f370
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/blocklayoutHLSL.cpp
@@ -0,0 +1,167 @@
+//
+// Copyright 2013 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.
+//
+// blocklayout.cpp:
+// Implementation for block layout classes and methods.
+//
+
+#include "compiler/translator/blocklayoutHLSL.h"
+
+#include "common/mathutil.h"
+#include "common/utilities.h"
+
+namespace sh
+{
+
+HLSLBlockEncoder::HLSLBlockEncoder(HLSLBlockEncoderStrategy strategy, bool transposeMatrices)
+ : mEncoderStrategy(strategy), mTransposeMatrices(transposeMatrices)
+{}
+
+void HLSLBlockEncoder::enterAggregateType(const ShaderVariable &structVar)
+{
+ align(kComponentsPerRegister);
+}
+
+void HLSLBlockEncoder::exitAggregateType(const ShaderVariable &structVar) {}
+
+void HLSLBlockEncoder::getBlockLayoutInfo(GLenum typeIn,
+ const std::vector<unsigned int> &arraySizes,
+ bool isRowMajorMatrix,
+ int *arrayStrideOut,
+ int *matrixStrideOut)
+{
+ GLenum type = (mTransposeMatrices ? gl::TransposeMatrixType(typeIn) : typeIn);
+
+ // We assume we are only dealing with 4 byte components (no doubles or half-words currently)
+ ASSERT(gl::VariableComponentSize(gl::VariableComponentType(type)) == kBytesPerComponent);
+
+ int matrixStride = 0;
+ int arrayStride = 0;
+
+ // if variables are not to be packed, or we're about to
+ // pack a matrix or array, skip to the start of the next
+ // register
+ if (!isPacked() || gl::IsMatrixType(type) || !arraySizes.empty())
+ {
+ align(kComponentsPerRegister);
+ }
+
+ if (gl::IsMatrixType(type))
+ {
+ matrixStride = kComponentsPerRegister;
+
+ if (!arraySizes.empty())
+ {
+ const int numRegisters = gl::MatrixRegisterCount(type, isRowMajorMatrix);
+ arrayStride = kComponentsPerRegister * numRegisters;
+ }
+ }
+ else if (!arraySizes.empty())
+ {
+ arrayStride = kComponentsPerRegister;
+ }
+ else if (isPacked())
+ {
+ int numComponents = gl::VariableComponentCount(type);
+ if ((numComponents + (mCurrentOffset % kComponentsPerRegister)) > kComponentsPerRegister)
+ {
+ align(kComponentsPerRegister);
+ }
+ }
+
+ *matrixStrideOut = matrixStride;
+ *arrayStrideOut = arrayStride;
+}
+
+void HLSLBlockEncoder::advanceOffset(GLenum typeIn,
+ const std::vector<unsigned int> &arraySizes,
+ bool isRowMajorMatrix,
+ int arrayStride,
+ int matrixStride)
+{
+ GLenum type = (mTransposeMatrices ? gl::TransposeMatrixType(typeIn) : typeIn);
+
+ if (!arraySizes.empty())
+ {
+ unsigned int arraySize = gl::ArraySizeProduct(arraySizes);
+ if (arraySize > 0)
+ {
+ mCurrentOffset += arrayStride * (arraySize - 1);
+ }
+ }
+
+ if (gl::IsMatrixType(type))
+ {
+ ASSERT(matrixStride == kComponentsPerRegister);
+ const int numRegisters = gl::MatrixRegisterCount(type, isRowMajorMatrix);
+ const int numComponents = gl::MatrixComponentCount(type, isRowMajorMatrix);
+ mCurrentOffset += kComponentsPerRegister * (numRegisters - 1);
+ mCurrentOffset += numComponents;
+ }
+ else if (isPacked())
+ {
+ mCurrentOffset += gl::VariableComponentCount(type);
+ }
+ else
+ {
+ mCurrentOffset += kComponentsPerRegister;
+ }
+}
+
+void HLSLBlockEncoder::skipRegisters(unsigned int numRegisters)
+{
+ mCurrentOffset += (numRegisters * kComponentsPerRegister);
+}
+
+HLSLBlockEncoder::HLSLBlockEncoderStrategy HLSLBlockEncoder::GetStrategyFor(
+ ShShaderOutput outputType)
+{
+ switch (outputType)
+ {
+ case SH_HLSL_3_0_OUTPUT:
+ return ENCODE_LOOSE;
+ case SH_HLSL_4_1_OUTPUT:
+ case SH_HLSL_4_0_FL9_3_OUTPUT:
+ return ENCODE_PACKED;
+ default:
+ UNREACHABLE();
+ return ENCODE_PACKED;
+ }
+}
+
+template <class ShaderVarType>
+void HLSLVariableRegisterCount(const ShaderVarType &variable, HLSLBlockEncoder *encoder)
+{
+ if (variable.isStruct())
+ {
+ for (size_t arrayElement = 0; arrayElement < variable.getArraySizeProduct(); arrayElement++)
+ {
+ encoder->enterAggregateType(variable);
+
+ for (const ShaderVariable &field : variable.fields)
+ {
+ HLSLVariableRegisterCount(field, encoder);
+ }
+
+ encoder->exitAggregateType(variable);
+ }
+ }
+ else
+ {
+ // We operate only on varyings and uniforms, which do not have matrix layout qualifiers
+ encoder->encodeType(variable.type, variable.arraySizes, false);
+ }
+}
+
+unsigned int HLSLVariableRegisterCount(const ShaderVariable &variable, ShShaderOutput outputType)
+{
+ HLSLBlockEncoder encoder(HLSLBlockEncoder::GetStrategyFor(outputType), true);
+ HLSLVariableRegisterCount(variable, &encoder);
+
+ const size_t registerBytes = (encoder.kBytesPerComponent * encoder.kComponentsPerRegister);
+ return static_cast<unsigned int>(
+ rx::roundUp<size_t>(encoder.getCurrentOffset(), registerBytes) / registerBytes);
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/blocklayoutHLSL.h b/gfx/angle/checkout/src/compiler/translator/blocklayoutHLSL.h
new file mode 100644
index 0000000000..8ed46b7728
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/blocklayoutHLSL.h
@@ -0,0 +1,68 @@
+//
+// Copyright 2013 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.
+//
+// blocklayout.h:
+// Methods and classes related to uniform layout and packing in GLSL and HLSL.
+//
+
+#ifndef COMMON_BLOCKLAYOUTHLSL_H_
+#define COMMON_BLOCKLAYOUTHLSL_H_
+
+#include <cstddef>
+#include <vector>
+
+#include <GLSLANG/ShaderLang.h>
+#include "angle_gl.h"
+#include "blocklayout.h"
+
+namespace sh
+{
+// Block layout packed according to the D3D9 or default D3D10+ register packing rules
+// See http://msdn.microsoft.com/en-us/library/windows/desktop/bb509632(v=vs.85).aspx
+// The strategy should be ENCODE_LOOSE for D3D9 constant blocks, and ENCODE_PACKED
+// for everything else (D3D10+ constant blocks and all attributes/varyings).
+
+class HLSLBlockEncoder : public BlockLayoutEncoder
+{
+ public:
+ enum HLSLBlockEncoderStrategy
+ {
+ ENCODE_PACKED,
+ ENCODE_LOOSE
+ };
+
+ HLSLBlockEncoder(HLSLBlockEncoderStrategy strategy, bool transposeMatrices);
+
+ void enterAggregateType(const ShaderVariable &structVar) override;
+ void exitAggregateType(const ShaderVariable &structVar) override;
+ void skipRegisters(unsigned int numRegisters);
+
+ bool isPacked() const { return mEncoderStrategy == ENCODE_PACKED; }
+
+ static HLSLBlockEncoderStrategy GetStrategyFor(ShShaderOutput outputType);
+
+ protected:
+ void getBlockLayoutInfo(GLenum type,
+ const std::vector<unsigned int> &arraySizes,
+ bool isRowMajorMatrix,
+ int *arrayStrideOut,
+ int *matrixStrideOut) override;
+ void advanceOffset(GLenum type,
+ const std::vector<unsigned int> &arraySizes,
+ bool isRowMajorMatrix,
+ int arrayStride,
+ int matrixStride) override;
+
+ HLSLBlockEncoderStrategy mEncoderStrategy;
+ bool mTransposeMatrices;
+};
+
+// This method returns the number of used registers for a ShaderVariable. It is dependent on the
+// HLSLBlockEncoder class to count the number of used registers in a struct (which are individually
+// packed according to the same rules).
+unsigned int HLSLVariableRegisterCount(const ShaderVariable &variable, ShShaderOutput outputType);
+} // namespace sh
+
+#endif // COMMON_BLOCKLAYOUTHLSL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/emulated_builtin_functions_hlsl_autogen.cpp b/gfx/angle/checkout/src/compiler/translator/emulated_builtin_functions_hlsl_autogen.cpp
new file mode 100644
index 0000000000..5b81f13869
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/emulated_builtin_functions_hlsl_autogen.cpp
@@ -0,0 +1,881 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_emulated_builtin_function_tables.py using data from
+// emulated_builtin_function_data_hlsl.json.
+//
+// Copyright 2017 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.
+//
+// emulated_builtin_functions_hlsl:
+// HLSL code for emulating GLSL builtin functions not present in HLSL.
+
+#include "compiler/translator/BuiltInFunctionEmulator.h"
+#include "compiler/translator/tree_util/BuiltIn.h"
+
+namespace sh
+{
+
+namespace
+{
+
+struct FunctionPair
+{
+ constexpr FunctionPair(const TSymbolUniqueId &idIn, const char *bodyIn)
+ : id(idIn.get()), body(bodyIn)
+ {}
+
+ int id;
+ const char *body;
+};
+
+constexpr FunctionPair g_hlslFunctions[] = {
+ {BuiltInId::mod_Float1_Float1,
+ "float mod_emu(float x, float y)\n"
+ "{\n"
+ " return x - y * floor(x / y);\n"
+ "}\n"},
+ {BuiltInId::mod_Float2_Float2,
+ "float2 mod_emu(float2 x, float2 y)\n"
+ "{\n"
+ " return x - y * floor(x / y);\n"
+ "}\n"},
+ {BuiltInId::mod_Float2_Float1,
+ "float2 mod_emu(float2 x, float y)\n"
+ "{\n"
+ " return x - y * floor(x / y);\n"
+ "}\n"},
+ {BuiltInId::mod_Float3_Float3,
+ "float3 mod_emu(float3 x, float3 y)\n"
+ "{\n"
+ " return x - y * floor(x / y);\n"
+ "}\n"},
+ {BuiltInId::mod_Float3_Float1,
+ "float3 mod_emu(float3 x, float y)\n"
+ "{\n"
+ " return x - y * floor(x / y);\n"
+ "}\n"},
+ {BuiltInId::mod_Float4_Float4,
+ "float4 mod_emu(float4 x, float4 y)\n"
+ "{\n"
+ " return x - y * floor(x / y);\n"
+ "}\n"},
+ {BuiltInId::mod_Float4_Float1,
+ "float4 mod_emu(float4 x, float y)\n"
+ "{\n"
+ " return x - y * floor(x / y);\n"
+ "}\n"},
+ {BuiltInId::frexp_Float1_Int1,
+ "float frexp_emu(float x, out int exp)\n"
+ "{\n"
+ " float fexp;\n"
+ " float mantissa = frexp(abs(x), fexp) * sign(x);\n"
+ " exp = int(fexp);\n"
+ " return mantissa;\n"
+ "}\n"},
+ {BuiltInId::frexp_Float2_Int2,
+ "float2 frexp_emu(float2 x, out int2 exp)\n"
+ "{\n"
+ " float2 fexp;\n"
+ " float2 mantissa = frexp(abs(x), fexp) * sign(x);\n"
+ " exp = int2(fexp);\n"
+ " return mantissa;\n"
+ "}\n"},
+ {BuiltInId::frexp_Float3_Int3,
+ "float3 frexp_emu(float3 x, out int3 exp)\n"
+ "{\n"
+ " float3 fexp;\n"
+ " float3 mantissa = frexp(abs(x), fexp) * sign(x);\n"
+ " exp = int3(fexp);\n"
+ " return mantissa;\n"
+ "}\n"},
+ {BuiltInId::frexp_Float4_Int4,
+ "float4 frexp_emu(float4 x, out int4 exp)\n"
+ "{\n"
+ " float4 fexp;\n"
+ " float4 mantissa = frexp(abs(x), fexp) * sign(x);\n"
+ " exp = int4(fexp);\n"
+ " return mantissa;\n"
+ "}\n"},
+ {BuiltInId::ldexp_Float1_Int1,
+ "float ldexp_emu(float x, int exp)\n"
+ "{\n"
+ " return ldexp(x, float(exp));\n"
+ "}\n"},
+ {BuiltInId::ldexp_Float2_Int2,
+ "float2 ldexp_emu(float2 x, int2 exp)\n"
+ "{\n"
+ " return ldexp(x, float2(exp));\n"
+ "}\n"},
+ {BuiltInId::ldexp_Float3_Int3,
+ "float3 ldexp_emu(float3 x, int3 exp)\n"
+ "{\n"
+ " return ldexp(x, float3(exp));\n"
+ "}\n"},
+ {BuiltInId::ldexp_Float4_Int4,
+ "float4 ldexp_emu(float4 x, int4 exp)\n"
+ "{\n"
+ " return ldexp(x, float4(exp));\n"
+ "}\n"},
+ {BuiltInId::faceforward_Float1_Float1_Float1,
+ "float faceforward_emu(float N, float I, float Nref)\n"
+ "{\n"
+ " if(dot(Nref, I) >= 0)\n"
+ " {\n"
+ " return -N;\n"
+ " }\n"
+ " else\n"
+ " {\n"
+ " return N;\n"
+ " }\n"
+ "}\n"},
+ {BuiltInId::faceforward_Float2_Float2_Float2,
+ "float2 faceforward_emu(float2 N, float2 I, float2 Nref)\n"
+ "{\n"
+ " if(dot(Nref, I) >= 0)\n"
+ " {\n"
+ " return -N;\n"
+ " }\n"
+ " else\n"
+ " {\n"
+ " return N;\n"
+ " }\n"
+ "}\n"},
+ {BuiltInId::faceforward_Float3_Float3_Float3,
+ "float3 faceforward_emu(float3 N, float3 I, float3 Nref)\n"
+ "{\n"
+ " if(dot(Nref, I) >= 0)\n"
+ " {\n"
+ " return -N;\n"
+ " }\n"
+ " else\n"
+ " {\n"
+ " return N;\n"
+ " }\n"
+ "}\n"},
+ {BuiltInId::faceforward_Float4_Float4_Float4,
+ "float4 faceforward_emu(float4 N, float4 I, float4 Nref)\n"
+ "{\n"
+ " if(dot(Nref, I) >= 0)\n"
+ " {\n"
+ " return -N;\n"
+ " }\n"
+ " else\n"
+ " {\n"
+ " return N;\n"
+ " }\n"
+ "}\n"},
+ {BuiltInId::atan_Float1_Float1,
+ "float atan_emu(float y, float x)\n"
+ "{\n"
+ " if(x == 0 && y == 0) x = 1;\n"
+ " return atan2(y, x);\n"
+ "}\n"},
+ {BuiltInId::atan_Float2_Float2,
+ "float2 atan_emu(float2 y, float2 x)\n"
+ "{\n"
+ " if(x[0] == 0 && y[0] == 0) x[0] = 1;\n"
+ " if(x[1] == 0 && y[1] == 0) x[1] = 1;\n"
+ " return float2(atan2(y[0], x[0]), atan2(y[1], x[1]));\n"
+ "}\n"},
+ {BuiltInId::atan_Float3_Float3,
+ "float3 atan_emu(float3 y, float3 x)\n"
+ "{\n"
+ " if(x[0] == 0 && y[0] == 0) x[0] = 1;\n"
+ " if(x[1] == 0 && y[1] == 0) x[1] = 1;\n"
+ " if(x[2] == 0 && y[2] == 0) x[2] = 1;\n"
+ " return float3(atan2(y[0], x[0]), atan2(y[1], x[1]), atan2(y[2], x[2]));\n"
+ "}\n"},
+ {BuiltInId::atan_Float4_Float4,
+ "float4 atan_emu(float4 y, float4 x)\n"
+ "{\n"
+ " if(x[0] == 0 && y[0] == 0) x[0] = 1;\n"
+ " if(x[1] == 0 && y[1] == 0) x[1] = 1;\n"
+ " if(x[2] == 0 && y[2] == 0) x[2] = 1;\n"
+ " if(x[3] == 0 && y[3] == 0) x[3] = 1;\n"
+ " return float4(atan2(y[0], x[0]), atan2(y[1], x[1]), atan2(y[2], \n"
+ " x[2]), atan2(y[3], x[3]));\n"
+ "}\n"},
+ {BuiltInId::asinh_Float1,
+ "float asinh_emu(in float x)\n"
+ "{\n"
+ " return log(x + sqrt(pow(x, 2.0) + 1.0));\n"
+ "}\n"},
+ {BuiltInId::asinh_Float2,
+ "float2 asinh_emu(in float2 x)\n"
+ "{\n"
+ " return log(x + sqrt(pow(x, 2.0) + 1.0));\n"
+ "}\n"},
+ {BuiltInId::asinh_Float3,
+ "float3 asinh_emu(in float3 x)\n"
+ "{\n"
+ " return log(x + sqrt(pow(x, 2.0) + 1.0));\n"
+ "}\n"},
+ {BuiltInId::asinh_Float4,
+ "float4 asinh_emu(in float4 x)\n"
+ "{\n"
+ " return log(x + sqrt(pow(x, 2.0) + 1.0));\n"
+ "}\n"},
+ {BuiltInId::acosh_Float1,
+ "float acosh_emu(in float x)\n"
+ "{\n"
+ " return log(x + sqrt(x + 1.0) * sqrt(x - 1.0));\n"
+ "}\n"},
+ {BuiltInId::acosh_Float2,
+ "float2 acosh_emu(in float2 x)\n"
+ "{\n"
+ " return log(x + sqrt(x + 1.0) * sqrt(x - 1.0));\n"
+ "}\n"},
+ {BuiltInId::acosh_Float3,
+ "float3 acosh_emu(in float3 x)\n"
+ "{\n"
+ " return log(x + sqrt(x + 1.0) * sqrt(x - 1.0));\n"
+ "}\n"},
+ {BuiltInId::acosh_Float4,
+ "float4 acosh_emu(in float4 x)\n"
+ "{\n"
+ " return log(x + sqrt(x + 1.0) * sqrt(x - 1.0));\n"
+ "}\n"},
+ {BuiltInId::atanh_Float1,
+ "float atanh_emu(in float x)\n"
+ "{\n"
+ " return 0.5 * log((1.0 + x) / (1.0 - x));\n"
+ "}\n"},
+ {BuiltInId::atanh_Float2,
+ "float2 atanh_emu(in float2 x)\n"
+ "{\n"
+ " return 0.5 * log((1.0 + x) / (1.0 - x));\n"
+ "}\n"},
+ {BuiltInId::atanh_Float3,
+ "float3 atanh_emu(in float3 x)\n"
+ "{\n"
+ " return 0.5 * log((1.0 + x) / (1.0 - x));\n"
+ "}\n"},
+ {BuiltInId::atanh_Float4,
+ "float4 atanh_emu(in float4 x)\n"
+ "{\n"
+ " return 0.5 * log((1.0 + x) / (1.0 - x));\n"
+ "}\n"},
+ {BuiltInId::roundEven_Float1,
+ "float roundEven_emu(in float x)\n"
+ "{\n"
+ " return (frac(x) == 0.5 && trunc(x) % 2.0 == 0.0) ? trunc(x) : round(x);\n"
+ "}\n"},
+ {BuiltInId::roundEven_Float2,
+ "float2 roundEven_emu(in float2 x)\n"
+ "{\n"
+ " float2 v;\n"
+ " v[0] = (frac(x[0]) == 0.5 && trunc(x[0]) % 2.0 == 0.0) ? trunc(x[0]) : round(x[0]);\n"
+ " v[1] = (frac(x[1]) == 0.5 && trunc(x[1]) % 2.0 == 0.0) ? trunc(x[1]) : round(x[1]);\n"
+ " return v;\n"
+ "}\n"},
+ {BuiltInId::roundEven_Float3,
+ "float3 roundEven_emu(in float3 x)\n"
+ "{\n"
+ " float3 v;\n"
+ " v[0] = (frac(x[0]) == 0.5 && trunc(x[0]) % 2.0 == 0.0) ? trunc(x[0]) : round(x[0]);\n"
+ " v[1] = (frac(x[1]) == 0.5 && trunc(x[1]) % 2.0 == 0.0) ? trunc(x[1]) : round(x[1]);\n"
+ " v[2] = (frac(x[2]) == 0.5 && trunc(x[2]) % 2.0 == 0.0) ? trunc(x[2]) : round(x[2]);\n"
+ " return v;\n"
+ "}\n"},
+ {BuiltInId::roundEven_Float4,
+ "float4 roundEven_emu(in float4 x)\n"
+ "{\n"
+ " float4 v;\n"
+ " v[0] = (frac(x[0]) == 0.5 && trunc(x[0]) % 2.0 == 0.0) ? trunc(x[0]) : round(x[0]);\n"
+ " v[1] = (frac(x[1]) == 0.5 && trunc(x[1]) % 2.0 == 0.0) ? trunc(x[1]) : round(x[1]);\n"
+ " v[2] = (frac(x[2]) == 0.5 && trunc(x[2]) % 2.0 == 0.0) ? trunc(x[2]) : round(x[2]);\n"
+ " v[3] = (frac(x[3]) == 0.5 && trunc(x[3]) % 2.0 == 0.0) ? trunc(x[3]) : round(x[3]);\n"
+ " return v;\n"
+ "}\n"},
+ {BuiltInId::packSnorm2x16_Float2,
+ "int webgl_toSnorm16(in float x) {\n"
+ " return int(round(clamp(x, -1.0, 1.0) * 32767.0));\n"
+ "}\n"
+ "uint packSnorm2x16_emu(in float2 v)\n"
+ "{\n"
+ " int x = webgl_toSnorm16(v.x);\n"
+ " int y = webgl_toSnorm16(v.y);\n"
+ " return (asuint(y) << 16) | (asuint(x) & 0xffffu);\n"
+ "}\n"},
+ {BuiltInId::packUnorm2x16_Float2,
+ "uint webgl_toUnorm16(in float x) {\n"
+ " return uint(round(clamp(x, 0.0, 1.0) * 65535.0));\n"
+ "}\n"
+ "uint packUnorm2x16_emu(in float2 v)\n"
+ "{\n"
+ " uint x = webgl_toUnorm16(v.x);\n"
+ " uint y = webgl_toUnorm16(v.y);\n"
+ " return (y << 16) | x;\n"
+ "}\n"},
+ {BuiltInId::packHalf2x16_Float2,
+ "uint packHalf2x16_emu(in float2 v)\n"
+ "{\n"
+ " uint x = f32tof16(v.x);\n"
+ " uint y = f32tof16(v.y);\n"
+ " return (y << 16) | x;\n"
+ "}\n"},
+ {BuiltInId::unpackSnorm2x16_UInt1,
+ "float webgl_fromSnorm16(in uint x) {\n"
+ " int xi = asint(x & 0x7fffu) - asint(x & 0x8000u);\n"
+ " return clamp(float(xi) / 32767.0, -1.0, 1.0);\n"
+ "}\n"
+ "float2 unpackSnorm2x16_emu(in uint u)\n"
+ "{\n"
+ " uint y = (u >> 16);\n"
+ " uint x = u;\n"
+ " return float2(webgl_fromSnorm16(x), webgl_fromSnorm16(y));\n"
+ "}\n"},
+ {BuiltInId::unpackUnorm2x16_UInt1,
+ "float webgl_fromUnorm16(in uint x) {\n"
+ " return float(x) / 65535.0;\n"
+ "}\n"
+ "float2 unpackUnorm2x16_emu(in uint u)\n"
+ "{\n"
+ " uint y = (u >> 16);\n"
+ " uint x = u & 0xffffu;\n"
+ " return float2(webgl_fromUnorm16(x), webgl_fromUnorm16(y));\n"
+ "}\n"},
+ {BuiltInId::unpackHalf2x16_UInt1,
+ "float2 unpackHalf2x16_emu(in uint u)\n"
+ "{\n"
+ " uint y = (u >> 16);\n"
+ " uint x = u & 0xffffu;\n"
+ " return float2(f16tof32(x), f16tof32(y));\n"
+ "}\n"},
+ {BuiltInId::packSnorm4x8_Float4,
+ "int webgl_toSnorm8(in float x) {\n"
+ " return int(round(clamp(x, -1.0, 1.0) * 127.0));\n"
+ "}\n"
+ "uint packSnorm4x8_emu(in float4 v)\n"
+ "{\n"
+ " int x = webgl_toSnorm8(v.x);\n"
+ " int y = webgl_toSnorm8(v.y);\n"
+ " int z = webgl_toSnorm8(v.z);\n"
+ " int w = webgl_toSnorm8(v.w);\n"
+ " return ((asuint(w) & 0xffu) << 24) | ((asuint(z) & 0xffu) << 16) \n"
+ " | ((asuint(y) & 0xffu) << 8) | (asuint(x) & 0xffu);\n"
+ "}\n"},
+ {BuiltInId::packUnorm4x8_Float4,
+ "uint webgl_toUnorm8(in float x) {\n"
+ " return uint(round(clamp(x, 0.0, 1.0) * 255.0));\n"
+ "}\n"
+ "uint packUnorm4x8_emu(in float4 v)\n"
+ "{\n"
+ " uint x = webgl_toUnorm8(v.x);\n"
+ " uint y = webgl_toUnorm8(v.y);\n"
+ " uint z = webgl_toUnorm8(v.z);\n"
+ " uint w = webgl_toUnorm8(v.w);\n"
+ " return (w << 24) | (z << 16) | (y << 8) | x;\n"
+ "}\n"},
+ {BuiltInId::unpackSnorm4x8_UInt1,
+ "float webgl_fromSnorm8(in uint x) {\n"
+ " int xi = asint(x & 0x7fu) - asint(x & 0x80u);\n"
+ " return clamp(float(xi) / 127.0, -1.0, 1.0);\n"
+ "}\n"
+ "float4 unpackSnorm4x8_emu(in uint u)\n"
+ "{\n"
+ " uint w = (u >> 24);\n"
+ " uint z = (u >> 16);\n"
+ " uint y = (u >> 8);\n"
+ " uint x = u;\n"
+ " return float4(webgl_fromSnorm8(x), webgl_fromSnorm8(y), \n"
+ " webgl_fromSnorm8(z), webgl_fromSnorm8(w));\n"
+ "}\n"},
+ {BuiltInId::unpackUnorm4x8_UInt1,
+ "float webgl_fromUnorm8(in uint x) {\n"
+ " return float(x) / 255.0;\n"
+ "}\n"
+ "float4 unpackUnorm4x8_emu(in uint u)\n"
+ "{\n"
+ " uint w = (u >> 24) & 0xffu;\n"
+ " uint z = (u >> 16) & 0xffu;\n"
+ " uint y = (u >> 8) & 0xffu;\n"
+ " uint x = u & 0xffu;\n"
+ " return float4(webgl_fromUnorm8(x), webgl_fromUnorm8(y), \n"
+ " webgl_fromUnorm8(z), webgl_fromUnorm8(w));\n"
+ "}\n"},
+ // The matrix resulting from outer product needs to be transposed
+ // (matrices are stored as transposed to simplify element access in HLSL).
+ // So the function should return transpose(c * r) where c is a column vector
+ // and r is a row vector. This can be simplified by using the following
+ // formula:
+ // transpose(c * r) = transpose(r) * transpose(c)
+ // transpose(r) and transpose(c) are in a sense free, since to get the
+ // transpose of r, we simply can build a column matrix out of the original
+ // vector instead of a row matrix.
+ {BuiltInId::outerProduct_Float2_Float2,
+ "float2x2 outerProduct_emu(in float2 c, in float2 r)\n"
+ "{\n"
+ " return mul(float2x1(r), float1x2(c));\n"
+ "}\n"},
+ {BuiltInId::outerProduct_Float3_Float3,
+ "float3x3 outerProduct_emu(in float3 c, in float3 r)\n"
+ "{\n"
+ " return mul(float3x1(r), float1x3(c));\n"
+ "}\n"},
+ {BuiltInId::outerProduct_Float4_Float4,
+ "float4x4 outerProduct_emu(in float4 c, in float4 r)\n"
+ "{\n"
+ " return mul(float4x1(r), float1x4(c));\n"
+ "}\n"},
+ {BuiltInId::outerProduct_Float3_Float2,
+ "float2x3 outerProduct_emu(in float3 c, in float2 r)\n"
+ "{\n"
+ " return mul(float2x1(r), float1x3(c));\n"
+ "}\n"},
+ {BuiltInId::outerProduct_Float2_Float3,
+ "float3x2 outerProduct_emu(in float2 c, in float3 r)\n"
+ "{\n"
+ " return mul(float3x1(r), float1x2(c));\n"
+ "}\n"},
+ {BuiltInId::outerProduct_Float4_Float2,
+ "float2x4 outerProduct_emu(in float4 c, in float2 r)\n"
+ "{\n"
+ " return mul(float2x1(r), float1x4(c));\n"
+ "}\n"},
+ {BuiltInId::outerProduct_Float2_Float4,
+ "float4x2 outerProduct_emu(in float2 c, in float4 r)\n"
+ "{\n"
+ " return mul(float4x1(r), float1x2(c));\n"
+ "}\n"},
+ {BuiltInId::outerProduct_Float4_Float3,
+ "float3x4 outerProduct_emu(in float4 c, in float3 r)\n"
+ "{\n"
+ " return mul(float3x1(r), float1x4(c));\n"
+ "}\n"},
+ {BuiltInId::outerProduct_Float3_Float4,
+ "float4x3 outerProduct_emu(in float3 c, in float4 r)\n"
+ "{\n"
+ " return mul(float4x1(r), float1x3(c));\n"
+ "}\n"},
+ // Remember here that the parameter matrix is actually the transpose
+ // of the matrix that we're trying to invert, and the resulting matrix
+ // should also be the transpose of the inverse.
+ // When accessing the parameter matrix with m[a][b] it can be thought of so
+ // that a is the column and b is the row of the matrix that we're inverting.
+ // We calculate the inverse as the adjugate matrix divided by the
+ // determinant of the matrix being inverted. However, as the result needs
+ // to be transposed, we actually use of the transpose of the adjugate matrix
+ // which happens to be the cofactor matrix. That's stored in 'cof'.
+ // We don't need to care about divide-by-zero since results are undefined
+ // for singular or poorly-conditioned matrices.
+ {BuiltInId::inverse_Float2x2,
+ "float2x2 inverse_emu(in float2x2 m)\n"
+ "{\n"
+ " float2x2 cof = { m[1][1], -m[0][1], -m[1][0], m[0][0] };\n"
+ " return cof / determinant(transpose(m));\n"
+ "}\n"},
+ // cofAB is the cofactor for column A and row B.
+ {BuiltInId::inverse_Float3x3,
+ "float3x3 inverse_emu(in float3x3 m)\n"
+ "{\n"
+ " float cof00 = m[1][1] * m[2][2] - m[2][1] * m[1][2];\n"
+ " float cof01 = -(m[1][0] * m[2][2] - m[2][0] * m[1][2]);\n"
+ " float cof02 = m[1][0] * m[2][1] - m[2][0] * m[1][1];\n"
+ " float cof10 = -(m[0][1] * m[2][2] - m[2][1] * m[0][2]);\n"
+ " float cof11 = m[0][0] * m[2][2] - m[2][0] * m[0][2];\n"
+ " float cof12 = -(m[0][0] * m[2][1] - m[2][0] * m[0][1]);\n"
+ " float cof20 = m[0][1] * m[1][2] - m[1][1] * m[0][2];\n"
+ " float cof21 = -(m[0][0] * m[1][2] - m[1][0] * m[0][2]);\n"
+ " float cof22 = m[0][0] * m[1][1] - m[1][0] * m[0][1];\n"
+ " float3x3 cof = { cof00, cof10, cof20, cof01, cof11, cof21, cof02, cof12, cof22 };\n"
+ " return cof / determinant(transpose(m));\n"
+ "}\n"},
+ {BuiltInId::inverse_Float4x4,
+ "float4x4 inverse_emu(in float4x4 m)\n"
+ "{\n"
+ " float cof00 = m[1][1] * m[2][2] * m[3][3] + m[2][1] * m[3][2] * m[1][3] + m[3][1] * \n"
+ " m[1][2] * m[2][3]\n"
+ " - m[1][1] * m[3][2] * m[2][3] - m[2][1] * m[1][2] * m[3][3] - m[3][1] * m[2][2] * \n"
+ " m[1][3];\n"
+ " float cof01 = -(m[1][0] * m[2][2] * m[3][3] + m[2][0] * m[3][2] * m[1][3] + m[3][0] * \n"
+ " m[1][2] * m[2][3]\n"
+ " - m[1][0] * m[3][2] * m[2][3] - m[2][0] * m[1][2] * m[3][3] - m[3][0] * m[2][2] * \n"
+ " m[1][3]);\n"
+ " float cof02 = m[1][0] * m[2][1] * m[3][3] + m[2][0] * m[3][1] * m[1][3] + m[3][0] * \n"
+ " m[1][1] * m[2][3]\n"
+ " - m[1][0] * m[3][1] * m[2][3] - m[2][0] * m[1][1] * m[3][3] - m[3][0] * m[2][1] * \n"
+ " m[1][3];\n"
+ " float cof03 = -(m[1][0] * m[2][1] * m[3][2] + m[2][0] * m[3][1] * m[1][2] + m[3][0] * \n"
+ " m[1][1] * m[2][2]\n"
+ " - m[1][0] * m[3][1] * m[2][2] - m[2][0] * m[1][1] * m[3][2] - m[3][0] * m[2][1] * \n"
+ " m[1][2]);\n"
+ " float cof10 = -(m[0][1] * m[2][2] * m[3][3] + m[2][1] * m[3][2] * m[0][3] + m[3][1] * \n"
+ " m[0][2] * m[2][3]\n"
+ " - m[0][1] * m[3][2] * m[2][3] - m[2][1] * m[0][2] * m[3][3] - m[3][1] * m[2][2] * \n"
+ " m[0][3]);\n"
+ " float cof11 = m[0][0] * m[2][2] * m[3][3] + m[2][0] * m[3][2] * m[0][3] + m[3][0] * \n"
+ " m[0][2] * m[2][3]\n"
+ " - m[0][0] * m[3][2] * m[2][3] - m[2][0] * m[0][2] * m[3][3] - m[3][0] * m[2][2] * \n"
+ " m[0][3];\n"
+ " float cof12 = -(m[0][0] * m[2][1] * m[3][3] + m[2][0] * m[3][1] * m[0][3] + m[3][0] * \n"
+ " m[0][1] * m[2][3]\n"
+ " - m[0][0] * m[3][1] * m[2][3] - m[2][0] * m[0][1] * m[3][3] - m[3][0] * m[2][1] * \n"
+ " m[0][3]);\n"
+ " float cof13 = m[0][0] * m[2][1] * m[3][2] + m[2][0] * m[3][1] * m[0][2] + m[3][0] * \n"
+ " m[0][1] * m[2][2]\n"
+ " - m[0][0] * m[3][1] * m[2][2] - m[2][0] * m[0][1] * m[3][2] - m[3][0] * m[2][1] * \n"
+ " m[0][2];\n"
+ " float cof20 = m[0][1] * m[1][2] * m[3][3] + m[1][1] * m[3][2] * m[0][3] + m[3][1] * \n"
+ " m[0][2] * m[1][3]\n"
+ " - m[0][1] * m[3][2] * m[1][3] - m[1][1] * m[0][2] * m[3][3] - m[3][1] * m[1][2] * \n"
+ " m[0][3];\n"
+ " float cof21 = -(m[0][0] * m[1][2] * m[3][3] + m[1][0] * m[3][2] * m[0][3] + m[3][0] * \n"
+ " m[0][2] * m[1][3]\n"
+ " - m[0][0] * m[3][2] * m[1][3] - m[1][0] * m[0][2] * m[3][3] - m[3][0] * m[1][2] * \n"
+ " m[0][3]);\n"
+ " float cof22 = m[0][0] * m[1][1] * m[3][3] + m[1][0] * m[3][1] * m[0][3] + m[3][0] * \n"
+ " m[0][1] * m[1][3]\n"
+ " - m[0][0] * m[3][1] * m[1][3] - m[1][0] * m[0][1] * m[3][3] - m[3][0] * m[1][1] * \n"
+ " m[0][3];\n"
+ " float cof23 = -(m[0][0] * m[1][1] * m[3][2] + m[1][0] * m[3][1] * m[0][2] + m[3][0] * \n"
+ " m[0][1] * m[1][2]\n"
+ " - m[0][0] * m[3][1] * m[1][2] - m[1][0] * m[0][1] * m[3][2] - m[3][0] * m[1][1] * \n"
+ " m[0][2]);\n"
+ " float cof30 = -(m[0][1] * m[1][2] * m[2][3] + m[1][1] * m[2][2] * m[0][3] + m[2][1] * \n"
+ " m[0][2] * m[1][3]\n"
+ " - m[0][1] * m[2][2] * m[1][3] - m[1][1] * m[0][2] * m[2][3] - m[2][1] * m[1][2] * \n"
+ " m[0][3]);\n"
+ " float cof31 = m[0][0] * m[1][2] * m[2][3] + m[1][0] * m[2][2] * m[0][3] + m[2][0] * \n"
+ " m[0][2] * m[1][3]\n"
+ " - m[0][0] * m[2][2] * m[1][3] - m[1][0] * m[0][2] * m[2][3] - m[2][0] * m[1][2] * \n"
+ " m[0][3];\n"
+ " float cof32 = -(m[0][0] * m[1][1] * m[2][3] + m[1][0] * m[2][1] * m[0][3] + m[2][0] * \n"
+ " m[0][1] * m[1][3]\n"
+ " - m[0][0] * m[2][1] * m[1][3] - m[1][0] * m[0][1] * m[2][3] - m[2][0] * m[1][1] * \n"
+ " m[0][3]);\n"
+ " float cof33 = m[0][0] * m[1][1] * m[2][2] + m[1][0] * m[2][1] * m[0][2] + m[2][0] * \n"
+ " m[0][1] * m[1][2]\n"
+ " - m[0][0] * m[2][1] * m[1][2] - m[1][0] * m[0][1] * m[2][2] - m[2][0] * m[1][1] * \n"
+ " m[0][2];\n"
+ " float4x4 cof = { cof00, cof10, cof20, cof30, cof01, cof11, cof21, cof31,\n"
+ " cof02, cof12, cof22, cof32, cof03, cof13, cof23, cof33 };\n"
+ " return cof / determinant(transpose(m));\n"
+ "}\n"},
+ // Emulate ESSL3 variant of mix that takes last argument as boolean vector.
+ // genType mix(genType x, genType y, genBType a): 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.
+ {BuiltInId::mix_Float1_Float1_Bool1,
+ "float mix_emu(float x, float y, bool a)\n"
+ "{\n"
+ " return a ? y : x;\n"
+ "}\n"},
+ {BuiltInId::mix_Float2_Float2_Bool2,
+ "float2 mix_emu(float2 x, float2 y, bool2 a)\n"
+ "{\n"
+ " return a ? y : x;\n"
+ "}\n"},
+ {BuiltInId::mix_Float3_Float3_Bool3,
+ "float3 mix_emu(float3 x, float3 y, bool3 a)\n"
+ "{\n"
+ " return a ? y : x;\n"
+ "}\n"},
+ {BuiltInId::mix_Float4_Float4_Bool4,
+ "float4 mix_emu(float4 x, float4 y, bool4 a)\n"
+ "{\n"
+ " return a ? y : x;\n"
+ "}\n"},
+ {BuiltInId::bitfieldExtract_UInt1_Int1_Int1,
+ "uint bitfieldExtract_emu(uint value, int offset, int bits)\n"
+ "{\n"
+ " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
+ " {\n"
+ " return 0u;\n"
+ " }\n"
+ " uint maskMsb = (1u << (bits - 1));\n"
+ " uint mask = ((maskMsb - 1u) | maskMsb) << offset;\n"
+ " return (value & mask) >> offset;\n"
+ "}\n"},
+ {BuiltInId::bitfieldExtract_UInt2_Int1_Int1,
+ "uint2 bitfieldExtract_emu(uint2 value, int offset, int bits)\n"
+ "{\n"
+ " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
+ " {\n"
+ " return uint2(0u, 0u);\n"
+ " }\n"
+ " uint maskMsb = (1u << (bits - 1));\n"
+ " uint mask = ((maskMsb - 1u) | maskMsb) << offset;\n"
+ " return (value & mask) >> offset;\n"
+ "}\n"},
+ {BuiltInId::bitfieldExtract_UInt3_Int1_Int1,
+ "uint3 bitfieldExtract_emu(uint3 value, int offset, int bits)\n"
+ "{\n"
+ " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
+ " {\n"
+ " return uint3(0u, 0u, 0u);\n"
+ " }\n"
+ " uint maskMsb = (1u << (bits - 1));\n"
+ " uint mask = ((maskMsb - 1u) | maskMsb) << offset;\n"
+ " return (value & mask) >> offset;\n"
+ "}\n"},
+ {BuiltInId::bitfieldExtract_UInt4_Int1_Int1,
+ "uint4 bitfieldExtract_emu(uint4 value, int offset, int bits)\n"
+ "{\n"
+ " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
+ " {\n"
+ " return uint4(0u, 0u, 0u, 0u);\n"
+ " }\n"
+ " uint maskMsb = (1u << (bits - 1));\n"
+ " uint mask = ((maskMsb - 1u) | maskMsb) << offset;\n"
+ " return (value & mask) >> offset;\n"
+ "}\n"},
+ {BuiltInId::bitfieldExtract_Int1_Int1_Int1,
+ "int bitfieldExtract_emu(int value, int offset, int bits)\n"
+ "{\n"
+ " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
+ " {\n"
+ " return 0;\n"
+ " }\n"
+ " uint maskMsb = (1u << (bits - 1));\n"
+ " uint mask = ((maskMsb - 1u) | maskMsb) << offset;\n"
+ " uint resultUnsigned = (asuint(value) & mask) >> offset;\n"
+ " if (bits != 32 && (resultUnsigned & maskMsb) != 0)\n"
+ " {\n"
+ " uint higherBitsMask = ((1u << (32 - bits)) - 1u) << bits;\n"
+ " resultUnsigned |= higherBitsMask;\n"
+ " }\n"
+ " return asint(resultUnsigned);\n"
+ "}\n"},
+ {BuiltInId::bitfieldExtract_Int2_Int1_Int1,
+ "int2 bitfieldExtract_emu(int2 value, int offset, int bits)\n"
+ "{\n"
+ " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
+ " {\n"
+ " return int2(0, 0);\n"
+ " }\n"
+ " uint maskMsb = (1u << (bits - 1));\n"
+ " uint mask = ((maskMsb - 1u) | maskMsb) << offset;\n"
+ " uint2 resultUnsigned = (asuint(value) & mask) >> offset;\n"
+ " if (bits != 32)\n"
+ " {\n"
+ " uint higherBitsMask = ((1u << (32 - bits)) - 1u) << bits;\n"
+ " resultUnsigned |= ((resultUnsigned & maskMsb) >> (bits - 1)) * higherBitsMask;\n"
+ " }\n"
+ " return asint(resultUnsigned);\n"
+ "}\n"},
+ {BuiltInId::bitfieldExtract_Int3_Int1_Int1,
+ "int3 bitfieldExtract_emu(int3 value, int offset, int bits)\n"
+ "{\n"
+ " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
+ " {\n"
+ " return int3(0, 0, 0);\n"
+ " }\n"
+ " uint maskMsb = (1u << (bits - 1));\n"
+ " uint mask = ((maskMsb - 1u) | maskMsb) << offset;\n"
+ " uint3 resultUnsigned = (asuint(value) & mask) >> offset;\n"
+ " if (bits != 32)\n"
+ " {\n"
+ " uint higherBitsMask = ((1u << (32 - bits)) - 1u) << bits;\n"
+ " resultUnsigned |= ((resultUnsigned & maskMsb) >> (bits - 1)) * higherBitsMask;\n"
+ " }\n"
+ " return asint(resultUnsigned);\n"
+ "}\n"},
+ {BuiltInId::bitfieldExtract_Int4_Int1_Int1,
+ "int4 bitfieldExtract_emu(int4 value, int offset, int bits)\n"
+ "{\n"
+ " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
+ " {\n"
+ " return int4(0, 0, 0, 0);\n"
+ " }\n"
+ " uint maskMsb = (1u << (bits - 1));\n"
+ " uint mask = ((maskMsb - 1u) | maskMsb) << offset;\n"
+ " uint4 resultUnsigned = (asuint(value) & mask) >> offset;\n"
+ " if (bits != 32)\n"
+ " {\n"
+ " uint higherBitsMask = ((1u << (32 - bits)) - 1u) << bits;\n"
+ " resultUnsigned |= ((resultUnsigned & maskMsb) >> (bits - 1)) * higherBitsMask;\n"
+ " }\n"
+ " return asint(resultUnsigned);\n"
+ "}\n"},
+ {BuiltInId::bitfieldInsert_UInt1_UInt1_Int1_Int1,
+ "uint bitfieldInsert_emu(uint base, uint insert, int offset, int bits)\n"
+ "{\n"
+ " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
+ " {\n"
+ " return base;\n"
+ " }\n"
+ " uint maskMsb = (1u << (bits - 1));\n"
+ " uint insertMask = ((maskMsb - 1u) | maskMsb) << offset;\n"
+ " uint baseMask = ~insertMask;\n"
+ " return (base & baseMask) | ((insert << offset) & insertMask);\n"
+ "}\n"},
+ {BuiltInId::bitfieldInsert_UInt2_UInt2_Int1_Int1,
+ "uint2 bitfieldInsert_emu(uint2 base, uint2 insert, int offset, int bits)\n"
+ "{\n"
+ " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
+ " {\n"
+ " return base;\n"
+ " }\n"
+ " uint maskMsb = (1u << (bits - 1));\n"
+ " uint insertMask = ((maskMsb - 1u) | maskMsb) << offset;\n"
+ " uint baseMask = ~insertMask;\n"
+ " return (base & baseMask) | ((insert << offset) & insertMask);\n"
+ "}\n"},
+ {BuiltInId::bitfieldInsert_UInt3_UInt3_Int1_Int1,
+ "uint3 bitfieldInsert_emu(uint3 base, uint3 insert, int offset, int bits)\n"
+ "{\n"
+ " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
+ " {\n"
+ " return base;\n"
+ " }\n"
+ " uint maskMsb = (1u << (bits - 1));\n"
+ " uint insertMask = ((maskMsb - 1u) | maskMsb) << offset;\n"
+ " uint baseMask = ~insertMask;\n"
+ " return (base & baseMask) | ((insert << offset) & insertMask);\n"
+ "}\n"},
+ {BuiltInId::bitfieldInsert_UInt4_UInt4_Int1_Int1,
+ "uint4 bitfieldInsert_emu(uint4 base, uint4 insert, int offset, int bits)\n"
+ "{\n"
+ " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
+ " {\n"
+ " return base;\n"
+ " }\n"
+ " uint maskMsb = (1u << (bits - 1));\n"
+ " uint insertMask = ((maskMsb - 1u) | maskMsb) << offset;\n"
+ " uint baseMask = ~insertMask;\n"
+ " return (base & baseMask) | ((insert << offset) & insertMask);\n"
+ "}\n"},
+ {BuiltInId::bitfieldInsert_Int1_Int1_Int1_Int1,
+ "int bitfieldInsert_emu(int base, int insert, int offset, int bits)\n"
+ "{\n"
+ " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
+ " {\n"
+ " return base;\n"
+ " }\n"
+ " uint maskMsb = (1u << (bits - 1));\n"
+ " uint insertMask = ((maskMsb - 1u) | maskMsb) << offset;\n"
+ " uint baseMask = ~insertMask;\n"
+ " uint resultUnsigned = (asuint(base) & baseMask) | ((asuint(insert) << offset) & \n"
+ " insertMask);\n"
+ " return asint(resultUnsigned);\n"
+ "}\n"},
+ {BuiltInId::bitfieldInsert_Int2_Int2_Int1_Int1,
+ "int2 bitfieldInsert_emu(int2 base, int2 insert, int offset, int bits)\n"
+ "{\n"
+ " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
+ " {\n"
+ " return base;\n"
+ " }\n"
+ " uint maskMsb = (1u << (bits - 1));\n"
+ " uint insertMask = ((maskMsb - 1u) | maskMsb) << offset;\n"
+ " uint baseMask = ~insertMask;\n"
+ " uint2 resultUnsigned = (asuint(base) & baseMask) | ((asuint(insert) << offset) & \n"
+ " insertMask);\n"
+ " return asint(resultUnsigned);\n"
+ "}\n"},
+ {BuiltInId::bitfieldInsert_Int3_Int3_Int1_Int1,
+ "int3 bitfieldInsert_emu(int3 base, int3 insert, int offset, int bits)\n"
+ "{\n"
+ " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
+ " {\n"
+ " return base;\n"
+ " }\n"
+ " uint maskMsb = (1u << (bits - 1));\n"
+ " uint insertMask = ((maskMsb - 1u) | maskMsb) << offset;\n"
+ " uint baseMask = ~insertMask;\n"
+ " uint3 resultUnsigned = (asuint(base) & baseMask) | ((asuint(insert) << offset) & \n"
+ " insertMask);\n"
+ " return asint(resultUnsigned);\n"
+ "}\n"},
+ {BuiltInId::bitfieldInsert_Int4_Int4_Int1_Int1,
+ "int4 bitfieldInsert_emu(int4 base, int4 insert, int offset, int bits)\n"
+ "{\n"
+ " if (offset < 0 || bits <= 0 || offset >= 32 || bits > 32 || offset + bits > 32)\n"
+ " {\n"
+ " return base;\n"
+ " }\n"
+ " uint maskMsb = (1u << (bits - 1));\n"
+ " uint insertMask = ((maskMsb - 1u) | maskMsb) << offset;\n"
+ " uint baseMask = ~insertMask;\n"
+ " uint4 resultUnsigned = (asuint(base) & baseMask) | ((asuint(insert) << offset) & \n"
+ " insertMask);\n"
+ " return asint(resultUnsigned);\n"
+ "}\n"},
+ {BuiltInId::uaddCarry_UInt1_UInt1_UInt1,
+ "uint uaddCarry_emu(uint x, uint y, out uint carry)\n"
+ "{\n"
+ " carry = uint(x > (0xffffffffu - y));\n"
+ " return x + y;\n"
+ "}\n"},
+ {BuiltInId::uaddCarry_UInt2_UInt2_UInt2,
+ "uint2 uaddCarry_emu(uint2 x, uint2 y, out uint2 carry)\n"
+ "{\n"
+ " carry = uint2(x > (0xffffffffu - y));\n"
+ " return x + y;\n"
+ "}\n"},
+ {BuiltInId::uaddCarry_UInt3_UInt3_UInt3,
+ "uint3 uaddCarry_emu(uint3 x, uint3 y, out uint3 carry)\n"
+ "{\n"
+ " carry = uint3(x > (0xffffffffu - y));\n"
+ " return x + y;\n"
+ "}\n"},
+ {BuiltInId::uaddCarry_UInt4_UInt4_UInt4,
+ "uint4 uaddCarry_emu(uint4 x, uint4 y, out uint4 carry)\n"
+ "{\n"
+ " carry = uint4(x > (0xffffffffu - y));\n"
+ " return x + y;\n"
+ "}\n"},
+ {BuiltInId::usubBorrow_UInt1_UInt1_UInt1,
+ "uint usubBorrow_emu(uint x, uint y, out uint borrow)\n"
+ "{\n"
+ " borrow = uint(x < y);\n"
+ " return x - y;\n"
+ "}\n"},
+ {BuiltInId::usubBorrow_UInt2_UInt2_UInt2,
+ "uint2 usubBorrow_emu(uint2 x, uint2 y, out uint2 borrow)\n"
+ "{\n"
+ " borrow = uint2(x < y);\n"
+ " return x - y;\n"
+ "}\n"},
+ {BuiltInId::usubBorrow_UInt3_UInt3_UInt3,
+ "uint3 usubBorrow_emu(uint3 x, uint3 y, out uint3 borrow)\n"
+ "{\n"
+ " borrow = uint3(x < y);\n"
+ " return x - y;\n"
+ "}\n"},
+ {BuiltInId::usubBorrow_UInt4_UInt4_UInt4,
+ "uint4 usubBorrow_emu(uint4 x, uint4 y, out uint4 borrow)\n"
+ "{\n"
+ " borrow = uint4(x < y);\n"
+ " return x - y;\n"
+ "}\n"},
+ // We emulate tanh just to avoid overflow on large arguments.
+ {BuiltInId::tanh_Float1,
+ "float tanh_emu(float x)\n"
+ "{\n"
+ " return (abs(x) > 15.0) ? sign(x) : tanh(x);\n"
+ "}\n"},
+ {BuiltInId::tanh_Float2,
+ "float2 tanh_emu(float2 x)\n"
+ "{\n"
+ " return (abs(x) > 15.0) ? sign(x) : tanh(x);\n"
+ "}\n"},
+ {BuiltInId::tanh_Float3,
+ "float3 tanh_emu(float3 x)\n"
+ "{\n"
+ " return (abs(x) > 15.0) ? sign(x) : tanh(x);\n"
+ "}\n"},
+ {BuiltInId::tanh_Float4,
+ "float4 tanh_emu(float4 x)\n"
+ "{\n"
+ " return (abs(x) > 15.0) ? sign(x) : tanh(x);\n"
+ "}\n"},
+};
+} // anonymous namespace
+
+const char *FindHLSLFunction(int uniqueId)
+{
+ for (size_t index = 0; index < ArraySize(g_hlslFunctions); ++index)
+ {
+ const auto &function = g_hlslFunctions[index];
+ if (function.id == uniqueId)
+ {
+ return function.body;
+ }
+ }
+
+ return nullptr;
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/glslang.h b/gfx/angle/checkout/src/compiler/translator/glslang.h
new file mode 100644
index 0000000000..301da81cca
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/glslang.h
@@ -0,0 +1,24 @@
+//
+// Copyright 2010 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_GLSLANG_H_
+#define COMPILER_TRANSLATOR_GLSLANG_H_
+
+namespace sh
+{
+class TParseContext;
+}
+
+extern int glslang_initialize(sh::TParseContext *context);
+extern int glslang_finalize(sh::TParseContext *context);
+
+extern int glslang_scan(size_t count,
+ const char *const string[],
+ const int length[],
+ sh::TParseContext *context);
+extern int glslang_parse(sh::TParseContext *context);
+
+#endif // COMPILER_TRANSLATOR_GLSLANG_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/glslang_lex_autogen.cpp b/gfx/angle/checkout/src/compiler/translator/glslang_lex_autogen.cpp
new file mode 100644
index 0000000000..c806fd8e3a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/glslang_lex_autogen.cpp
@@ -0,0 +1,4326 @@
+#line 17 "glslang.l"
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_parser.py from glslang.l
+//
+// Copyright 2019 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.
+//
+// glslang.l:
+// Lexer for the OpenGL shading language.
+
+// Ignore errors in auto-generated code.
+#if defined(__GNUC__)
+# pragma GCC diagnostic ignored "-Wswitch-enum"
+# pragma GCC diagnostic ignored "-Wunused-function"
+# pragma GCC diagnostic ignored "-Wunused-variable"
+#elif defined(_MSC_VER)
+# pragma warning(disable : 4005)
+# pragma warning(disable : 4065)
+# pragma warning(disable : 4189)
+# pragma warning(disable : 4244)
+# pragma warning(disable : 4505)
+# pragma warning(disable : 4701)
+# pragma warning(disable : 4702)
+#endif
+#if defined(__clang__)
+# pragma clang diagnostic ignored "-Wimplicit-fallthrough"
+# if defined(__APPLE__)
+// Older clang versions don't have -Wextra-semi-stmt, and detecting Apple clang versions is
+// difficult because they use different yet overlapping version numbers vs. regular clang.
+# pragma clang diagnostic ignored "-Wunknown-warning-option"
+# endif
+// Flex isn't semi-colon clean.
+# pragma clang diagnostic ignored "-Wextra-semi-stmt"
+# pragma clang diagnostic ignored "-Wunreachable-code"
+#endif
+
+#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 6
+#define YY_FLEX_SUBMINOR_VERSION 4
+#if YY_FLEX_SUBMINOR_VERSION > 0
+# define FLEX_BETA
+#endif
+
+#ifdef yyget_lval
+# define yyget_lval_ALREADY_DEFINED
+#else
+# define yyget_lval yyget_lval
+#endif
+
+#ifdef yyset_lval
+# define yyset_lval_ALREADY_DEFINED
+#else
+# define yyset_lval yyset_lval
+#endif
+
+#ifdef yyget_lloc
+# define yyget_lloc_ALREADY_DEFINED
+#else
+# define yyget_lloc yyget_lloc
+#endif
+
+#ifdef yyset_lloc
+# define yyset_lloc_ALREADY_DEFINED
+#else
+# define yyset_lloc yyset_lloc
+#endif
+
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+# define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+# if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+# ifndef __STDC_LIMIT_MACROS
+# define __STDC_LIMIT_MACROS 1
+# endif
+
+# include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+# else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+
+/* Limits of integral types. */
+# ifndef INT8_MIN
+# define INT8_MIN (-128)
+# endif
+# ifndef INT16_MIN
+# define INT16_MIN (-32767 - 1)
+# endif
+# ifndef INT32_MIN
+# define INT32_MIN (-2147483647 - 1)
+# endif
+# ifndef INT8_MAX
+# define INT8_MAX (127)
+# endif
+# ifndef INT16_MAX
+# define INT16_MAX (32767)
+# endif
+# ifndef INT32_MAX
+# define INT32_MAX (2147483647)
+# endif
+# ifndef UINT8_MAX
+# define UINT8_MAX (255U)
+# endif
+# ifndef UINT16_MAX
+# define UINT16_MAX (65535U)
+# endif
+# ifndef UINT32_MAX
+# define UINT32_MAX (4294967295U)
+# endif
+
+# ifndef SIZE_MAX
+# define SIZE_MAX (~(size_t)0)
+# endif
+
+# endif /* ! C99 */
+
+#endif /* ! FLEXINT_H */
+
+/* begin standard C++ headers. */
+
+/* TODO: this is always defined, so inline it */
+#define yyconst const
+
+#if defined(__GNUC__) && __GNUC__ >= 3
+# define yynoreturn __attribute__((__noreturn__))
+#else
+# define yynoreturn
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an
+ * integer in range [0..255] for use as an array index.
+ */
+#define YY_SC_TO_UI(c) ((YY_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
+#define yyout yyg->yyout_r
+#define yyextra yyg->yyextra_r
+#define yyleng yyg->yyleng_r
+#define yytext yyg->yytext_r
+#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
+#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.
+ */
+#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 yyrestart(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;
+#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
+
+/* Note: We specifically omit the test for yy_rule_can_match_eol because it requires
+ * access to the local variable yy_act. Since yyless() is a macro, it would break
+ * existing scanners that call yyless() from OUTSIDE yylex.
+ * One obvious solution it to make yy_act a global. I tried that, and saw
+ * a 5% performance hit in a non-yylineno scanner, because yy_act is
+ * normally declared as a register variable-- so it is not worth it.
+ */
+#define YY_LESS_LINENO(n) \
+ do \
+ { \
+ int yyl; \
+ for (yyl = n; yyl < yyleng; ++yyl) \
+ if (yytext[yyl] == '\n') \
+ --yylineno; \
+ } while (0)
+#define YY_LINENO_REWIND_TO(dst) \
+ do \
+ { \
+ const char *p; \
+ for (p = yy_cp - 1; p >= (dst); --p) \
+ if (*p == '\n') \
+ --yylineno; \
+ } while (0)
+
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg); \
+ *yy_cp = yyg->yy_hold_char; \
+ YY_RESTORE_YY_MORE_OFFSET \
+ yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } 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.
+ */
+ int yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ 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
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ 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.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+
+# define YY_BUFFER_NEW 0
+# define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via yyrestart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+# define YY_BUFFER_EOF_PENDING 2
+};
+#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".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER \
+ (yyg->yy_buffer_stack ? 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 yyrestart(FILE *input_file, yyscan_t yyscanner);
+void yy_switch_to_buffer(YY_BUFFER_STATE new_buffer, yyscan_t yyscanner);
+YY_BUFFER_STATE yy_create_buffer(FILE *file, int size, yyscan_t yyscanner);
+void yy_delete_buffer(YY_BUFFER_STATE b, yyscan_t yyscanner);
+void yy_flush_buffer(YY_BUFFER_STATE b, yyscan_t yyscanner);
+void yypush_buffer_state(YY_BUFFER_STATE new_buffer, yyscan_t yyscanner);
+void yypop_buffer_state(yyscan_t yyscanner);
+
+static void yyensure_buffer_stack(yyscan_t yyscanner);
+static void yy_load_buffer_state(yyscan_t yyscanner);
+static void yy_init_buffer(YY_BUFFER_STATE b, FILE *file, yyscan_t yyscanner);
+#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER, yyscanner)
+
+YY_BUFFER_STATE yy_scan_buffer(char *base, yy_size_t size, yyscan_t yyscanner);
+YY_BUFFER_STATE yy_scan_string(const char *yy_str, yyscan_t yyscanner);
+YY_BUFFER_STATE yy_scan_bytes(const char *bytes, int len, yyscan_t yyscanner);
+
+void *yyalloc(yy_size_t, yyscan_t yyscanner);
+void *yyrealloc(void *, yy_size_t, yyscan_t yyscanner);
+void yyfree(void *, yyscan_t yyscanner);
+
+#define yy_new_buffer yy_create_buffer
+#define yy_set_interactive(is_interactive) \
+ { \
+ if (!YY_CURRENT_BUFFER) \
+ { \
+ yyensure_buffer_stack(yyscanner); \
+ YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin, YY_BUF_SIZE, yyscanner); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+ }
+#define yy_set_bol(at_bol) \
+ { \
+ if (!YY_CURRENT_BUFFER) \
+ { \
+ yyensure_buffer_stack(yyscanner); \
+ YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin, YY_BUF_SIZE, 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 yywrap(yyscanner) (/*CONSTCOND*/ 1)
+#define YY_SKIP_YYWRAP
+typedef flex_uint8_t 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 yynoreturn yy_fatal_error(const 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 = (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 259
+#define YY_END_OF_BUFFER 260
+/* This struct is not used in this scanner,
+ but its presence is necessary. */
+struct yy_trans_info
+{
+ flex_int32_t yy_verify;
+ flex_int32_t yy_nxt;
+};
+static const flex_int16_t yy_accept[982] = {
+ 0, 0, 0, 0, 0, 260, 258, 257, 257, 241, 247, 252, 236, 237, 245, 244, 233,
+ 242, 240, 246, 199, 199, 234, 230, 248, 235, 249, 253, 196, 238, 239, 251, 196, 196,
+ 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+ 196, 196, 196, 231, 250, 232, 243, 256, 255, 259, 254, 227, 213, 232, 221, 216, 211,
+ 219, 209, 220, 210, 205, 212, 204, 198, 199, 0, 202, 0, 239, 231, 238, 228, 224,
+ 226, 225, 229, 196, 217, 223, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+
+ 196, 196, 196, 196, 13, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+ 196, 16, 196, 196, 26, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+ 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+ 196, 196, 196, 196, 196, 196, 196, 196, 196, 218, 222, 254, 0, 208, 204, 0, 207,
+ 201, 0, 203, 197, 214, 215, 196, 196, 156, 196, 196, 196, 196, 196, 196, 196, 196,
+ 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+
+ 196, 14, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 31, 196, 196, 196, 196,
+ 196, 196, 196, 196, 196, 196, 196, 196, 196, 27, 196, 196, 196, 196, 196, 196, 196,
+ 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+ 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 0, 205, 0,
+ 204, 206, 200, 196, 196, 196, 196, 34, 196, 196, 196, 19, 193, 196, 196, 196, 196,
+ 196, 196, 196, 196, 196, 196, 17, 159, 196, 196, 196, 196, 22, 196, 196,
+
+ 163, 174, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 171,
+ 4, 39, 40, 41, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+ 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 162, 35, 196, 196,
+ 32, 196, 196, 196, 196, 196, 196, 196, 196, 51, 52, 53, 33, 196, 196, 196, 196,
+ 196, 196, 196, 196, 11, 196, 57, 58, 59, 196, 157, 196, 196, 7, 196, 196, 196,
+ 196, 183, 184, 185, 196, 36, 196, 175, 30, 186, 187, 188, 2, 180, 181,
+
+ 182, 196, 196, 196, 28, 178, 196, 196, 196, 196, 196, 196, 54, 55, 56, 196, 196,
+ 196, 196, 196, 196, 196, 196, 196, 196, 196, 25, 196, 196, 196, 196, 196, 196, 196,
+ 196, 196, 172, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 158, 196, 196,
+ 196, 195, 60, 61, 62, 196, 196, 15, 196, 196, 196, 135, 196, 196, 9, 196, 196,
+ 133, 196, 196, 196, 173, 168, 136, 196, 196, 196, 196, 196, 196, 164, 196, 196, 196,
+ 196, 196, 196, 97, 42, 45, 47, 46, 43, 49, 48, 50, 44, 196, 196,
+
+ 196, 196, 179, 155, 196, 196, 196, 166, 196, 196, 196, 38, 126, 29, 192, 23, 167,
+ 96, 196, 177, 18, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+ 196, 196, 196, 196, 20, 37, 196, 196, 196, 196, 196, 196, 137, 102, 108, 196, 196,
+ 196, 196, 196, 196, 99, 101, 3, 196, 196, 196, 196, 196, 127, 196, 196, 196, 196,
+ 196, 196, 196, 160, 196, 196, 196, 196, 196, 8, 196, 196, 196, 10, 196, 196, 196,
+ 196, 196, 196, 21, 122, 12, 169, 138, 103, 110, 196, 196, 196, 196, 196,
+
+ 196, 196, 196, 196, 196, 196, 196, 196, 196, 165, 196, 196, 196, 196, 120, 131, 123,
+ 196, 196, 196, 196, 196, 196, 196, 196, 161, 139, 104, 109, 196, 196, 176, 196, 196,
+ 124, 196, 196, 196, 196, 6, 196, 196, 196, 196, 196, 196, 196, 196, 196, 113, 170,
+ 1, 196, 196, 196, 196, 196, 196, 196, 194, 196, 134, 196, 5, 189, 63, 66, 196,
+ 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 121, 196, 196,
+ 196, 196, 196, 196, 111, 196, 196, 196, 196, 196, 196, 196, 149, 71, 72,
+
+ 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 132,
+ 196, 196, 196, 112, 196, 151, 76, 77, 196, 196, 196, 196, 125, 196, 196, 196, 196,
+ 196, 196, 196, 196, 117, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+ 196, 196, 70, 196, 196, 196, 196, 64, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+ 196, 196, 196, 196, 196, 196, 196, 196, 118, 196, 140, 196, 105, 196, 196, 196, 196,
+ 196, 75, 196, 196, 73, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+
+ 196, 196, 196, 196, 196, 196, 196, 119, 196, 196, 196, 196, 80, 196, 196, 78, 196,
+ 196, 141, 106, 196, 196, 143, 196, 144, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+ 24, 196, 196, 196, 196, 196, 68, 196, 67, 89, 196, 196, 196, 196, 142, 107, 196,
+ 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 114, 196, 196, 196, 196,
+ 153, 92, 196, 196, 196, 147, 196, 69, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+ 196, 196, 196, 154, 94, 196, 196, 196, 115, 196, 196, 196, 150, 74, 196,
+
+ 196, 196, 128, 196, 190, 196, 196, 196, 81, 196, 196, 196, 196, 116, 196, 152, 79,
+ 196, 196, 196, 196, 196, 196, 129, 196, 196, 196, 196, 196, 85, 196, 88, 196, 196,
+ 196, 130, 196, 196, 196, 196, 196, 196, 86, 91, 196, 196, 196, 196, 196, 82, 196,
+ 95, 87, 93, 98, 196, 145, 146, 100, 196, 196, 196, 196, 65, 196, 196, 196, 191,
+ 196, 196, 148, 83, 196, 196, 196, 196, 90, 196, 196, 84, 0};
+
+static const YY_CHAR yy_ec[256] = {
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 1, 1, 1, 5, 6, 1, 7, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 1, 31, 32, 33, 34, 35, 36, 37, 38, 38, 38, 38, 39, 40, 41, 42, 38, 38, 43, 44,
+ 45, 46, 47, 48, 49, 50, 38, 51, 1, 52, 53, 54, 1, 55, 56, 57, 58,
+
+ 59, 60, 61, 62, 63, 38, 64, 65, 66, 67, 68, 69, 38, 70, 71, 72, 73, 74, 75, 76, 77,
+ 78, 79, 80, 81, 82, 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, 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, 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, 1, 1, 1, 1, 1, 1};
+
+static const YY_CHAR yy_meta[83] = {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 4, 4, 4, 4, 3, 5, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 7, 6, 6, 6, 6, 1, 1, 1, 6, 4, 4, 4, 4, 3, 5, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 6, 6, 6, 6, 6, 1, 1, 1, 1};
+
+static const flex_int16_t yy_base[988] = {
+ 0, 0, 0, 82, 0, 1237, 1238, 1238, 1238, 1208, 137, 161, 1238, 1238, 1207,
+ 158, 1238, 157, 155, 1206, 177, 168, 1204, 1238, 177, 1204, 155, 1238, 0, 1238,
+ 1238, 160, 1177, 149, 160, 170, 148, 143, 177, 1162, 184, 194, 163, 132, 169,
+ 1156, 189, 1169, 209, 208, 220, 218, 147, 1154, 1238, 215, 1238, 1238, 1238, 1238,
+ 1238, 0, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 220, 1238, 257,
+ 250, 263, 322, 1238, 0, 1238, 1238, 1238, 1198, 1238, 1238, 1238, 1197, 0, 1238,
+ 1238, 1153, 1151, 1156, 229, 1153, 1161, 1159, 1159, 1146, 1149,
+
+ 1160, 238, 1154, 1142, 1139, 1152, 1139, 1136, 1136, 1142, 237, 235, 1136, 1146, 1132,
+ 1138, 1141, 1142, 0, 1134, 1144, 246, 1135, 1142, 1123, 1136, 1117, 252, 1121, 1134,
+ 1125, 243, 1118, 278, 1113, 1129, 1131, 253, 1120, 292, 1107, 1116, 294, 296, 1120,
+ 1116, 1118, 1107, 1110, 182, 258, 1115, 296, 1118, 1106, 1118, 265, 1111, 1110, 1098,
+ 1238, 1238, 0, 351, 1238, 318, 369, 1238, 1238, 379, 389, 285, 1238, 1238, 1116,
+ 1107, 0, 1103, 1098, 1102, 1111, 1105, 1107, 355, 1091, 1091, 1102, 1094, 284, 1104,
+ 1101, 1101, 1099, 1096, 1088, 1094, 1081, 1079, 1091, 1077,
+
+ 1093, 0, 1090, 1078, 1085, 1082, 1086, 1087, 1080, 1077, 1066, 1065, 1078, 1081, 1059,
+ 1068, 1079, 1075, 1063, 1069, 1060, 398, 1065, 1068, 1059, 1066, 1055, 1059, 1050, 1064,
+ 1061, 1062, 1053, 1059, 308, 1043, 1046, 1044, 1043, 1053, 1043, 1038, 1036, 1038, 1048,
+ 1034, 1036, 1033, 1044, 1043, 1046, 1028, 358, 1036, 1022, 1031, 1029, 1038, 1017, 402,
+ 1035, 1037, 1026, 1018, 1056, 413, 423, 445, 455, 1238, 1238, 1022, 1013, 1023, 1022,
+ 0, 1020, 1024, 405, 0, 0, 1012, 1010, 1010, 1011, 1006, 1014, 1003, 1020, 1009,
+ 433, 0, 0, 1003, 1013, 1012, 1012, 0, 997, 436,
+
+ 0, 0, 999, 439, 1006, 1007, 998, 992, 991, 992, 991, 1001, 990, 361, 463,
+ 985, 0, 0, 981, 980, 979, 981, 982, 987, 981, 977, 990, 985, 985, 981,
+ 982, 981, 975, 969, 971, 970, 974, 979, 965, 968, 963, 971, 976, 964, 961,
+ 973, 964, 0, 0, 970, 966, 0, 958, 958, 963, 964, 953, 960, 467, 957,
+ 0, 0, 0, 0, 947, 959, 958, 945, 946, 955, 956, 956, 0, 941, 0,
+ 0, 0, 942, 0, 950, 941, 0, 940, 941, 935, 945, 0, 0, 0, 936,
+ 0, 932, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 942, 471, 941, 0, 0, 939, 935, 932, 931, 980, 979, 0, 0, 0,
+ 921, 475, 478, 481, 926, 922, 927, 918, 916, 929, 914, 0, 946, 913, 926,
+ 915, 911, 917, 912, 919, 919, 0, 916, 913, 917, 901, 899, 902, 908, 914,
+ 909, 908, 896, 0, 898, 899, 898, 0, 0, 0, 0, 895, 898, 0, 892,
+ 902, 893, 0, 903, 883, 0, 892, 887, 0, 880, 880, 893, 0, 895, 0,
+ 489, 915, 914, 913, 873, 872, 0, 889, 888, 903, 882, 924, 915, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 869, 882,
+
+ 869, 866, 0, 0, 871, 865, 449, 0, 867, 874, 873, 0, 859, 0, 0,
+ 0, 0, 0, 856, 0, 0, 855, 866, 493, 859, 865, 884, 863, 860, 855,
+ 852, 874, 858, 843, 843, 856, 841, 853, 0, 0, 846, 876, 875, 874, 834,
+ 833, 470, 485, 0, 845, 848, 846, 835, 833, 830, 845, 0, 0, 841, 838,
+ 837, 827, 837, 0, 825, 815, 832, 818, 501, 826, 829, 0, 853, 852, 851,
+ 811, 810, 0, 824, 813, 810, 0, 820, 813, 805, 806, 812, 815, 0, 0,
+ 0, 0, 842, 841, 0, 811, 814, 799, 806, 797,
+
+ 804, 805, 805, 804, 790, 804, 514, 800, 800, 0, 801, 790, 801, 788, 0,
+ 0, 0, 820, 819, 818, 778, 777, 773, 785, 780, 0, 815, 814, 0, 784,
+ 787, 0, 785, 521, 0, 764, 785, 804, 771, 0, 767, 766, 775, 775, 763,
+ 777, 761, 775, 770, 797, 0, 0, 772, 792, 791, 790, 750, 749, 748, 0,
+ 748, 0, 754, 0, 496, 512, 775, 757, 760, 743, 756, 754, 742, 741, 750,
+ 750, 753, 773, 772, 771, 731, 730, 0, 735, 725, 728, 729, 728, 738, 765,
+ 740, 736, 738, 734, 721, 720, 724, 757, 518, 0,
+
+ 727, 730, 720, 721, 752, 712, 719, 710, 735, 719, 715, 717, 715, 715, 714,
+ 713, 0, 701, 700, 710, 737, 702, 735, 519, 0, 705, 708, 705, 690, 0,
+ 706, 705, 689, 688, 680, 688, 678, 686, 0, 683, 721, 681, 680, 705, 689,
+ 687, 687, 680, 670, 698, 666, 668, 652, 690, 123, 160, 189, 210, 497, 204,
+ 220, 252, 255, 263, 287, 331, 378, 420, 458, 454, 460, 464, 469, 476, 465,
+ 467, 0, 475, 507, 482, 516, 488, 509, 524, 496, 497, 537, 512, 511, 540,
+ 518, 514, 537, 520, 518, 522, 508, 507, 522, 509,
+
+ 512, 513, 522, 518, 538, 510, 511, 0, 519, 549, 521, 522, 562, 537, 536,
+ 565, 527, 528, 0, 0, 544, 538, 0, 539, 0, 525, 566, 549, 550, 536,
+ 535, 538, 539, 540, 0, 572, 535, 545, 537, 545, 572, 549, 0, 0, 548,
+ 564, 565, 586, 0, 0, 567, 586, 569, 570, 556, 555, 558, 559, 572, 564,
+ 555, 578, 579, 0, 596, 559, 560, 568, 0, 0, 569, 585, 606, 598, 568,
+ 600, 590, 584, 572, 593, 591, 585, 619, 575, 614, 577, 578, 586, 0, 0,
+ 587, 623, 604, 0, 602, 603, 627, 0, 0, 608,
+
+ 609, 598, 0, 604, 0, 605, 591, 614, 0, 593, 603, 630, 636, 0, 639,
+ 0, 0, 620, 621, 628, 613, 611, 612, 0, 604, 605, 622, 629, 630, 0,
+ 628, 643, 613, 654, 651, 0, 614, 615, 648, 677, 620, 621, 0, 0, 638,
+ 640, 641, 632, 639, 0, 658, 0, 0, 0, 0, 669, 0, 0, 0, 636,
+ 637, 631, 652, 0, 658, 634, 635, 0, 653, 695, 0, 0, 645, 664, 640,
+ 681, 0, 668, 673, 0, 1238, 717, 722, 727, 732, 735, 738};
+
+static const flex_int16_t yy_def[988] = {
+ 0, 981, 1, 981, 3, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981,
+ 981, 981, 981, 982, 981, 981, 981, 981, 981, 981, 983, 981, 981, 981, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 981, 981, 981, 981, 981, 981, 981, 984, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981,
+ 985, 981, 986, 20, 982, 981, 981, 987, 981, 981, 981, 981, 981, 981, 981, 981, 983, 981,
+ 981, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 981, 981, 984, 981, 981, 986, 981, 981, 981, 981, 981, 987,
+ 981, 981, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 981, 981, 981, 981, 981, 981, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983, 983,
+ 983, 983, 983, 983, 983, 983, 983, 983, 0, 981, 981, 981, 981, 981, 981};
+
+static const flex_int16_t yy_nxt[1321] = {
+ 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 22, 23, 24, 25, 26, 27, 28, 28, 28,
+ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+ 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 28, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 28, 53, 28, 54, 55, 56, 57, 58, 59,
+ 60, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
+
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 61, 61, 61, 61, 61,
+ 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 58, 58,
+ 58, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
+ 61, 61, 61, 61, 61, 61, 61, 61, 61, 58, 58, 58, 58, 63, 64, 65, 68,
+ 70, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 798, 74, 81, 86, 87, 71,
+ 69, 129, 89, 66, 74, 130, 75, 75, 75, 75, 75, 75, 75, 75, 76,
+
+ 76, 82, 77, 83, 84, 92, 103, 107, 158, 108, 104, 77, 90, 78, 799, 105, 159,
+ 127, 109, 93, 94, 106, 78, 131, 99, 79, 77, 95, 100, 96, 128, 110, 97, 98,
+ 101, 77, 132, 102, 116, 111, 78, 112, 161, 134, 113, 800, 117, 251, 252, 78, 114,
+ 135, 79, 119, 164, 165, 120, 118, 136, 121, 122, 137, 123, 139, 124, 125, 146, 126,
+ 801, 147, 140, 141, 155, 804, 142, 74, 156, 148, 164, 165, 143, 144, 150, 145, 149,
+ 157, 151, 805, 152, 200, 153, 167, 168, 154, 162, 169, 178, 77, 981, 187,
+
+ 179, 198, 201, 188, 189, 225, 806, 234, 78, 807, 210, 226, 199, 211, 212, 167, 168,
+ 213, 220, 214, 253, 77, 169, 235, 236, 981, 221, 261, 254, 262, 271, 170, 808, 170,
+ 228, 78, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 238, 229, 242, 230, 256,
+ 244, 167, 168, 286, 287, 809, 271, 257, 239, 266, 810, 266, 243, 245, 267, 267, 267,
+ 267, 267, 267, 267, 267, 267, 267, 334, 167, 168, 268, 335, 268, 411, 412, 269, 269,
+ 269, 269, 269, 269, 269, 269, 269, 269, 171, 171, 171, 171, 171, 171, 171,
+
+ 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 280, 319, 320, 321,
+ 353, 361, 362, 363, 375, 376, 377, 270, 354, 281, 267, 267, 267, 267, 267, 267, 267,
+ 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 811, 270, 387, 388,
+ 389, 395, 396, 397, 399, 400, 401, 165, 269, 269, 269, 269, 269, 269, 269, 269, 269,
+ 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 413, 414, 415, 165, 454, 455,
+ 456, 477, 478, 479, 812, 168, 490, 491, 492, 493, 494, 495, 496, 497, 498,
+
+ 598, 813, 480, 481, 542, 543, 544, 564, 573, 574, 575, 565, 814, 599, 168, 600, 618,
+ 619, 620, 815, 545, 546, 816, 817, 576, 577, 706, 802, 601, 654, 655, 656, 621, 622,
+ 818, 623, 678, 679, 680, 707, 803, 819, 708, 820, 821, 657, 658, 624, 743, 768, 822,
+ 709, 681, 682, 710, 711, 823, 744, 769, 824, 745, 770, 825, 826, 827, 828, 829, 830,
+ 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847,
+ 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862,
+
+ 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879,
+ 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896,
+ 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913,
+ 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930,
+ 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947,
+ 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962,
+
+ 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979,
+ 980, 76, 76, 797, 796, 795, 76, 88, 88, 88, 88, 88, 163, 163, 163, 163, 163,
+ 72, 794, 72, 166, 793, 166, 172, 172, 172, 792, 791, 790, 789, 788, 787, 786, 785,
+ 784, 783, 782, 781, 780, 779, 778, 777, 776, 775, 774, 773, 772, 771, 767, 766, 765,
+ 764, 763, 762, 761, 760, 759, 758, 757, 756, 755, 754, 753, 752, 751, 750, 749, 748,
+ 747, 746, 742, 741, 740, 739, 738, 737, 736, 735, 734, 733, 732, 731, 730,
+
+ 729, 728, 727, 726, 725, 724, 723, 722, 721, 720, 719, 718, 717, 716, 715, 714, 713,
+ 712, 705, 704, 703, 702, 701, 700, 699, 698, 697, 696, 695, 694, 693, 692, 691, 690,
+ 689, 688, 687, 686, 685, 684, 683, 677, 676, 675, 674, 673, 672, 671, 670, 669, 668,
+ 667, 666, 665, 664, 663, 662, 661, 660, 659, 653, 652, 651, 650, 649, 648, 647, 646,
+ 645, 644, 643, 642, 641, 640, 639, 638, 637, 636, 635, 634, 633, 632, 631, 630, 629,
+ 628, 627, 626, 625, 617, 616, 615, 614, 613, 612, 611, 610, 609, 608, 607,
+
+ 606, 605, 604, 603, 602, 597, 596, 595, 594, 593, 592, 591, 590, 589, 588, 587, 586,
+ 585, 584, 583, 582, 581, 580, 579, 578, 572, 571, 570, 569, 568, 567, 566, 563, 562,
+ 561, 560, 559, 558, 557, 556, 555, 554, 553, 552, 551, 550, 549, 548, 547, 541, 540,
+ 539, 538, 537, 536, 535, 534, 533, 532, 531, 530, 529, 528, 527, 526, 525, 524, 523,
+ 522, 521, 520, 519, 518, 517, 516, 515, 514, 513, 512, 511, 510, 509, 508, 507, 506,
+ 505, 504, 503, 502, 501, 500, 499, 489, 488, 487, 486, 485, 484, 483, 482,
+
+ 476, 475, 474, 473, 472, 471, 470, 469, 468, 467, 466, 465, 464, 463, 462, 461, 460,
+ 459, 458, 457, 453, 452, 451, 450, 449, 448, 447, 446, 445, 444, 443, 442, 441, 440,
+ 439, 438, 437, 436, 435, 434, 433, 432, 431, 430, 429, 428, 427, 426, 425, 424, 423,
+ 422, 421, 420, 419, 418, 417, 416, 410, 409, 408, 407, 406, 405, 404, 403, 402, 398,
+ 394, 393, 392, 391, 390, 386, 385, 384, 383, 382, 381, 380, 379, 378, 374, 373, 372,
+ 371, 370, 369, 368, 367, 366, 365, 364, 360, 359, 358, 357, 356, 355, 352,
+
+ 351, 350, 349, 348, 347, 346, 345, 344, 343, 342, 341, 340, 339, 338, 337, 336, 333,
+ 332, 331, 330, 329, 328, 327, 326, 325, 324, 323, 322, 318, 317, 316, 315, 314, 313,
+ 312, 311, 310, 309, 308, 307, 306, 305, 304, 303, 302, 301, 300, 299, 298, 297, 296,
+ 295, 294, 293, 292, 291, 290, 289, 288, 285, 284, 283, 282, 279, 278, 277, 276, 275,
+ 274, 273, 272, 265, 264, 263, 260, 259, 258, 255, 250, 249, 248, 247, 246, 241, 240,
+ 237, 233, 232, 231, 227, 224, 223, 222, 219, 218, 217, 216, 215, 209, 208,
+
+ 207, 206, 205, 204, 203, 202, 197, 196, 195, 194, 193, 192, 191, 190, 186, 185, 184,
+ 183, 182, 181, 180, 177, 176, 175, 174, 173, 160, 138, 133, 115, 91, 85, 80, 73,
+ 67, 62, 981, 5, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981,
+ 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981,
+ 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981,
+ 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981,
+
+ 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981,
+ 981, 981, 981};
+
+static const flex_int16_t yy_chk[1321] = {
+ 0, 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, 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, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 10, 10, 11, 15,
+ 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 755, 21, 24, 26, 26, 17,
+ 15, 43, 31, 11, 20, 43, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+
+ 20, 24, 21, 24, 24, 33, 36, 37, 52, 37, 36, 20, 31, 21, 756, 36, 52,
+ 42, 37, 33, 33, 36, 20, 44, 35, 20, 21, 34, 35, 34, 42, 38, 34, 34,
+ 35, 20, 44, 35, 40, 38, 21, 38, 55, 46, 38, 757, 40, 150, 150, 20, 38,
+ 46, 20, 41, 72, 72, 41, 40, 46, 41, 41, 46, 41, 48, 41, 41, 49, 41,
+ 758, 49, 48, 48, 51, 760, 48, 76, 51, 49, 72, 72, 48, 48, 50, 48, 49,
+ 51, 50, 761, 50, 112, 50, 74, 74, 50, 55, 75, 94, 76, 75, 102,
+
+ 94, 111, 112, 102, 102, 132, 762, 138, 76, 763, 122, 132, 111, 122, 122, 74, 74,
+ 122, 128, 122, 151, 76, 75, 138, 138, 75, 128, 157, 151, 157, 172, 77, 764, 77,
+ 134, 76, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 140, 134, 143, 134, 153,
+ 144, 166, 166, 189, 189, 765, 172, 153, 140, 164, 766, 164, 143, 144, 164, 164, 164,
+ 164, 164, 164, 164, 164, 164, 164, 235, 166, 166, 167, 235, 167, 314, 314, 167, 167,
+ 167, 167, 167, 167, 167, 167, 167, 167, 170, 170, 170, 170, 170, 170, 170,
+
+ 170, 170, 170, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 184, 222, 222, 222,
+ 253, 260, 260, 260, 279, 279, 279, 171, 253, 184, 266, 266, 266, 266, 266, 266, 266,
+ 266, 266, 266, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 767, 171, 291, 291,
+ 291, 300, 300, 300, 304, 304, 304, 267, 268, 268, 268, 268, 268, 268, 268, 268, 268,
+ 268, 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, 315, 315, 315, 267, 359, 359,
+ 359, 403, 403, 403, 768, 269, 417, 417, 417, 418, 418, 418, 419, 419, 419,
+
+ 547, 769, 403, 403, 476, 476, 476, 507, 524, 524, 524, 507, 770, 547, 269, 548, 569,
+ 569, 569, 771, 476, 476, 772, 773, 524, 524, 665, 759, 548, 607, 607, 607, 569, 569,
+ 774, 569, 634, 634, 634, 665, 759, 775, 666, 776, 778, 607, 607, 569, 699, 724, 779,
+ 666, 634, 634, 666, 666, 780, 699, 724, 781, 699, 724, 782, 783, 784, 785, 786, 787,
+ 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804,
+ 805, 806, 807, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 821, 822,
+
+ 824, 826, 827, 828, 829, 830, 831, 832, 833, 834, 836, 837, 838, 839, 840, 841, 842,
+ 845, 846, 847, 848, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863,
+ 865, 866, 867, 868, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883,
+ 884, 885, 886, 887, 888, 891, 892, 893, 895, 896, 897, 900, 901, 902, 904, 906, 907,
+ 908, 910, 911, 912, 913, 915, 918, 919, 920, 921, 922, 923, 925, 926, 927, 928, 929,
+ 931, 932, 933, 934, 935, 937, 938, 939, 940, 941, 942, 945, 946, 947, 948,
+
+ 949, 951, 956, 960, 961, 962, 963, 965, 966, 967, 969, 970, 973, 974, 975, 976, 978,
+ 979, 982, 982, 754, 753, 752, 982, 983, 983, 983, 983, 983, 984, 984, 984, 984, 984,
+ 985, 751, 985, 986, 750, 986, 987, 987, 987, 749, 748, 747, 746, 745, 744, 743, 742,
+ 741, 740, 738, 737, 736, 735, 734, 733, 732, 731, 729, 728, 727, 726, 723, 722, 721,
+ 720, 719, 718, 716, 715, 714, 713, 712, 711, 710, 709, 708, 707, 706, 705, 704, 703,
+ 702, 701, 698, 697, 696, 695, 694, 693, 692, 691, 690, 689, 688, 687, 686,
+
+ 685, 684, 682, 681, 680, 679, 678, 677, 676, 675, 674, 673, 672, 671, 670, 669, 668,
+ 667, 663, 661, 659, 658, 657, 656, 655, 654, 653, 650, 649, 648, 647, 646, 645, 644,
+ 643, 642, 641, 639, 638, 637, 636, 633, 631, 630, 628, 627, 625, 624, 623, 622, 621,
+ 620, 619, 618, 614, 613, 612, 611, 609, 608, 606, 605, 604, 603, 602, 601, 600, 599,
+ 598, 597, 596, 594, 593, 588, 587, 586, 585, 584, 583, 581, 580, 579, 577, 576, 575,
+ 574, 573, 571, 570, 568, 567, 566, 565, 563, 562, 561, 560, 559, 556, 555,
+
+ 554, 553, 552, 551, 550, 546, 545, 544, 543, 542, 541, 538, 537, 536, 535, 534, 533,
+ 532, 531, 530, 529, 528, 527, 526, 525, 523, 522, 519, 513, 511, 510, 509, 506, 505,
+ 502, 501, 500, 499, 488, 487, 486, 485, 484, 483, 481, 480, 479, 478, 477, 474, 472,
+ 471, 470, 468, 467, 465, 464, 462, 461, 460, 458, 457, 452, 451, 450, 448, 447, 446,
+ 445, 444, 443, 442, 441, 440, 439, 438, 436, 435, 434, 433, 432, 431, 430, 429, 428,
+ 426, 425, 424, 423, 422, 421, 420, 416, 412, 411, 410, 409, 408, 407, 404,
+
+ 402, 392, 390, 386, 385, 384, 383, 381, 380, 378, 374, 372, 371, 370, 369, 368, 367,
+ 366, 365, 360, 358, 357, 356, 355, 354, 353, 351, 350, 347, 346, 345, 344, 343, 342,
+ 341, 340, 339, 338, 337, 336, 335, 334, 333, 332, 331, 330, 329, 328, 327, 326, 325,
+ 324, 323, 322, 321, 320, 319, 316, 313, 312, 311, 310, 309, 308, 307, 306, 305, 303,
+ 299, 297, 296, 295, 294, 290, 289, 288, 287, 286, 285, 284, 283, 282, 278, 277, 275,
+ 274, 273, 272, 265, 264, 263, 262, 261, 259, 258, 257, 256, 255, 254, 252,
+
+ 251, 250, 249, 248, 247, 246, 245, 244, 243, 242, 241, 240, 239, 238, 237, 236, 234,
+ 233, 232, 231, 230, 229, 228, 227, 226, 225, 224, 223, 221, 220, 219, 218, 217, 216,
+ 215, 214, 213, 212, 211, 210, 209, 208, 207, 206, 205, 204, 203, 201, 200, 199, 198,
+ 197, 196, 195, 194, 193, 192, 191, 190, 188, 187, 186, 185, 183, 182, 181, 180, 179,
+ 178, 176, 175, 160, 159, 158, 156, 155, 154, 152, 149, 148, 147, 146, 145, 142, 141,
+ 139, 137, 136, 135, 133, 131, 130, 129, 127, 126, 125, 124, 123, 121, 120,
+
+ 118, 117, 116, 115, 114, 113, 110, 109, 108, 107, 106, 105, 104, 103, 101, 100, 99,
+ 98, 97, 96, 95, 93, 92, 91, 87, 83, 53, 47, 45, 39, 32, 25, 22, 19,
+ 14, 9, 5, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981,
+ 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981,
+ 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981,
+ 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981,
+
+ 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981, 981,
+ 981, 981, 981};
+
+/* Table of booleans, true if rule could match eol. */
+static const flex_int32_t yy_rule_can_match_eol[260] = {
+ 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, 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, 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, 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, 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, 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,
+};
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+/*
+//
+// Copyright 2002 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 file contains the Lex specification for GLSL ES.
+Based on ANSI C grammar, Lex specification:
+http://www.lysator.liu.se/c/ANSI-C-grammar-l.html
+
+IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN scripts/run_code_generation.py
+WHICH GENERATES THE GLSL ES LEXER (glslang_lex_autogen.cpp).
+*/
+
+#include "compiler/preprocessor/Token.h"
+#include "compiler/translator/ParseContext.h"
+#include "compiler/translator/glslang.h"
+#include "compiler/translator/length_limits.h"
+#include "compiler/translator/util.h"
+
+using namespace sh;
+
+#include "glslang_tab_autogen.h"
+
+/* windows only pragma */
+#ifdef _MSC_VER
+# pragma warning(disable : 4102)
+#endif
+
+// Workaround for flex using the register keyword, deprecated in C++11.
+#ifdef __cplusplus
+# if __cplusplus > 199711L
+# define register
+# endif
+#endif
+
+#define YY_NO_INPUT
+#define YY_USER_ACTION \
+ yylloc->first_file = yylloc->last_file = yycolumn; \
+ yylloc->first_line = yylloc->last_line = yylineno;
+
+#define YY_INPUT(buf, result, max_size) result = string_input(buf, max_size, yyscanner);
+
+static yy_size_t string_input(char *buf, yy_size_t max_size, yyscan_t yyscanner);
+static int check_type(yyscan_t yyscanner);
+static int reserved_word(yyscan_t yyscanner);
+// Tests if an extension is enabled. If the extension is promoted to core, this function returns
+// true.
+static bool is_extension_enabled_or_is_core(TParseContext *context,
+ int extension_version,
+ TExtension extension,
+ int promotion_version);
+// Helpers to determine if a symbol is reserved, keyword in extension or core, or identifier.
+// Formatted as:
+//
+// [V1_reserved_][V2_extension_][V3_keyword]
+//
+// which means in version V1, the symbol is reserved, and remains reserved until V3. From versions
+// V2 until V3, it's a keyword if the extension is enabled. From version V3 on, it's a keyword in
+// the spec itself. Prior to V1, the symbol can be used as identifier.
+static int ES2_extensions_ES3_keyword(TParseContext *context,
+ TExtension extension1,
+ TExtension extension2,
+ TExtension extension3,
+ int token);
+static int ES2_reserved_ES3_keyword(TParseContext *context, int token);
+static int ES2_keyword_ES3_reserved(TParseContext *context, int token);
+static int ES3_keyword(TParseContext *context, int token);
+static int ES3_reserved_ES3_1_keyword(TParseContext *context, int token);
+static int ES2_reserved_ES3_1_keyword(TParseContext *context, int token);
+static int ES3_1_keyword(TParseContext *context, int token);
+static int ES2_reserved_ES2_extension_ES3_keyword(TParseContext *context,
+ TExtension extension,
+ int token);
+static int ES3_extension(TParseContext *context, TExtension extension, int token);
+static int ES3_reserved_ES3_1_extension_ES3_2_keyword(TParseContext *context,
+ TExtension extension,
+ int token);
+static int ES3_reserved_ES3_extension(TParseContext *context, TExtension extension, int token);
+static int ES3_reserved_ES3_extension_ES3_1_keyword(TParseContext *context,
+ TExtension extension,
+ int token);
+static int ES3_reserved_ES3_extension_ES3_2_keyword(TParseContext *context,
+ TExtension extension,
+ int token);
+static int ES3_1_reserved_ES3_1_extension_ES3_2_keyword(TParseContext *context,
+ TExtension extension,
+ int token);
+static int ES3_1_reserved_ES3_1_extension_ES3_2_keyword_2(TParseContext *context,
+ TExtension extension1,
+ TExtension extension2,
+ int token1,
+ int token2);
+static int ES3_and_3_1_reserved_ES3_1_extension_ES3_2_keyword_2(TParseContext *context,
+ TExtension extension1,
+ TExtension extension2,
+ int token1,
+ int token2);
+static int WEBGL_video_texture_extension(TParseContext *context, int token);
+static int uint_constant(TParseContext *context);
+static int int_constant(TParseContext *context);
+static int float_constant(yyscan_t yyscanner);
+static int floatsuffix_check(TParseContext *context);
+static int yuvcscstandardext_constant(TParseContext *context);
+
+#define INITIAL 0
+#define FIELDS 1
+
+#define YY_EXTRA_TYPE TParseContext *
+
+/* Holds the entire state of the reentrant scanner. */
+struct yyguts_t
+{
+
+ /* User-defined. Not touched by flex. */
+ YY_EXTRA_TYPE yyextra_r;
+
+ /* The rest are the same as the globals declared in the non-reentrant scanner. */
+ FILE *yyin_r, *yyout_r;
+ size_t yy_buffer_stack_top; /**< index of top of stack. */
+ size_t yy_buffer_stack_max; /**< capacity of stack. */
+ YY_BUFFER_STATE *yy_buffer_stack; /**< Stack as an array. */
+ char yy_hold_char;
+ int yy_n_chars;
+ int yyleng_r;
+ char *yy_c_buf_p;
+ int yy_init;
+ int yy_start;
+ int yy_did_buffer_switch_on_eof;
+ int yy_start_stack_ptr;
+ int yy_start_stack_depth;
+ int *yy_start_stack;
+ yy_state_type yy_last_accepting_state;
+ char *yy_last_accepting_cpos;
+
+ 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 yylex_init(yyscan_t *scanner);
+
+int yylex_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 yylex_destroy(yyscan_t yyscanner);
+
+int yyget_debug(yyscan_t yyscanner);
+
+void yyset_debug(int debug_flag, yyscan_t yyscanner);
+
+YY_EXTRA_TYPE yyget_extra(yyscan_t yyscanner);
+
+void yyset_extra(YY_EXTRA_TYPE user_defined, yyscan_t yyscanner);
+
+FILE *yyget_in(yyscan_t yyscanner);
+
+void yyset_in(FILE *_in_str, yyscan_t yyscanner);
+
+FILE *yyget_out(yyscan_t yyscanner);
+
+void yyset_out(FILE *_out_str, yyscan_t yyscanner);
+
+int yyget_leng(yyscan_t yyscanner);
+
+char *yyget_text(yyscan_t yyscanner);
+
+int yyget_lineno(yyscan_t yyscanner);
+
+void yyset_lineno(int _line_number, yyscan_t yyscanner);
+
+int yyget_column(yyscan_t yyscanner);
+
+void yyset_column(int _column_no, yyscan_t yyscanner);
+
+YYSTYPE *yyget_lval(yyscan_t yyscanner);
+
+void yyset_lval(YYSTYPE *yylval_param, yyscan_t yyscanner);
+
+YYLTYPE *yyget_lloc(yyscan_t yyscanner);
+
+void yyset_lloc(YYLTYPE *yylloc_param, yyscan_t yyscanner);
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+# ifdef __cplusplus
+extern "C" int yywrap(yyscan_t yyscanner);
+# else
+extern int yywrap(yyscan_t yyscanner);
+# endif
+#endif
+
+#ifndef YY_NO_UNPUT
+
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy(char *, const char *, int, yyscan_t yyscanner);
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen(const char *, yyscan_t yyscanner);
+#endif
+
+#ifndef YY_NO_INPUT
+# ifdef __cplusplus
+static int yyinput(yyscan_t yyscanner);
+# else
+static int input(yyscan_t yyscanner);
+# endif
+
+#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, (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".
+ */
+#ifndef YY_INPUT
+# define YY_INPUT(buf, result, max_size) \
+ if (YY_CURRENT_BUFFER_LVALUE->yy_is_interactive) \
+ { \
+ int c = '*'; \
+ int n; \
+ for (n = 0; n < max_size && (c = getc(yyin)) != EOF && c != '\n'; ++n) \
+ buf[n] = (char)c; \
+ if (c == '\n') \
+ buf[n++] = (char)c; \
+ if (c == EOF && ferror(yyin)) \
+ YY_FATAL_ERROR("input in flex scanner failed"); \
+ result = n; \
+ } \
+ else \
+ { \
+ errno = 0; \
+ while ((result = (int)fread(buf, 1, (yy_size_t)max_size, yyin)) == 0 && ferror(yyin)) \
+ { \
+ if (errno != EINTR) \
+ { \
+ YY_FATAL_ERROR("input in flex scanner failed"); \
+ break; \
+ } \
+ errno = 0; \
+ clearerr(yyin); \
+ } \
+ }
+
+#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.
+ */
+#ifndef yyterminate
+# 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 yylex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param, yyscan_t yyscanner);
+
+# define YY_DECL int yylex(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.
+ */
+#ifndef YY_USER_ACTION
+# define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_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
+{
+ 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;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if (!yyg->yy_start)
+ yyg->yy_start = 1; /* first start state */
+
+ if (!yyin)
+ yyin = stdin;
+
+ if (!yyout)
+ yyout = stdout;
+
+ if (!YY_CURRENT_BUFFER)
+ {
+ yyensure_buffer_stack(yyscanner);
+ YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin, YY_BUF_SIZE, yyscanner);
+ }
+
+ yy_load_buffer_state(yyscanner);
+ }
+
+ {
+
+ TParseContext *context = yyextra;
+
+ while (/*CONSTCOND*/ 1) /* loops until end-of-file is reached */
+ {
+ yy_cp = yyg->yy_c_buf_p;
+
+ /* Support of yytext. */
+ *yy_cp = yyg->yy_hold_char;
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = yyg->yy_start;
+ yy_match:
+ do
+ {
+ 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;
+ yyg->yy_last_accepting_cpos = yy_cp;
+ }
+ while (yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state)
+ {
+ yy_current_state = (int)yy_def[yy_current_state];
+ if (yy_current_state >= 982)
+ yy_c = yy_meta[yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
+ ++yy_cp;
+ } while (yy_current_state != 981);
+ yy_cp = yyg->yy_last_accepting_cpos;
+ yy_current_state = yyg->yy_last_accepting_state;
+
+ yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+
+ YY_DO_BEFORE_ACTION;
+
+ if (yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act])
+ {
+ int yyl;
+ for (yyl = 0; yyl < yyleng; ++yyl)
+ if (yytext[yyl] == '\n')
+
+ do
+ {
+ yylineno++;
+ yycolumn = 0;
+ } while (0);
+ }
+
+ do_action: /* This label is used only to access EOF actions. */
+
+ switch (yy_act)
+ { /* beginning of action switch */
+ case 0: /* must back up */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = yyg->yy_hold_char;
+ yy_cp = yyg->yy_last_accepting_cpos;
+ yy_current_state = yyg->yy_last_accepting_state;
+ goto yy_find_action;
+
+ case 1:
+ YY_RULE_SETUP
+ {
+ return INVARIANT;
+ }
+ YY_BREAK
+ case 2:
+ YY_RULE_SETUP
+ {
+ return HIGH_PRECISION;
+ }
+ YY_BREAK
+ case 3:
+ YY_RULE_SETUP
+ {
+ return MEDIUM_PRECISION;
+ }
+ YY_BREAK
+ case 4:
+ YY_RULE_SETUP
+ {
+ return LOW_PRECISION;
+ }
+ YY_BREAK
+ case 5:
+ YY_RULE_SETUP
+ {
+ return PRECISION;
+ }
+ YY_BREAK
+ case 6:
+ YY_RULE_SETUP
+ {
+ return ES2_keyword_ES3_reserved(context, ATTRIBUTE);
+ }
+ YY_BREAK
+ case 7:
+ YY_RULE_SETUP
+ {
+ return CONST_QUAL;
+ }
+ YY_BREAK
+ case 8:
+ YY_RULE_SETUP
+ {
+ return UNIFORM;
+ }
+ YY_BREAK
+ case 9:
+ YY_RULE_SETUP
+ {
+ return ES3_1_keyword(context, BUFFER);
+ }
+ YY_BREAK
+ case 10:
+ YY_RULE_SETUP
+ {
+ return ES2_keyword_ES3_reserved(context, VARYING);
+ }
+ YY_BREAK
+ case 11:
+ YY_RULE_SETUP
+ {
+ return BREAK;
+ }
+ YY_BREAK
+ case 12:
+ YY_RULE_SETUP
+ {
+ return CONTINUE;
+ }
+ YY_BREAK
+ case 13:
+ YY_RULE_SETUP
+ {
+ return DO;
+ }
+ YY_BREAK
+ case 14:
+ YY_RULE_SETUP
+ {
+ return FOR;
+ }
+ YY_BREAK
+ case 15:
+ YY_RULE_SETUP
+ {
+ return WHILE;
+ }
+ YY_BREAK
+ case 16:
+ YY_RULE_SETUP
+ {
+ return IF;
+ }
+ YY_BREAK
+ case 17:
+ YY_RULE_SETUP
+ {
+ return ELSE;
+ }
+ YY_BREAK
+ case 18:
+ YY_RULE_SETUP
+ {
+ return ES2_reserved_ES3_keyword(context, SWITCH);
+ }
+ YY_BREAK
+ case 19:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, CASE);
+ }
+ YY_BREAK
+ case 20:
+ YY_RULE_SETUP
+ {
+ return ES2_reserved_ES3_keyword(context, DEFAULT);
+ }
+ YY_BREAK
+ case 21:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, CENTROID);
+ }
+ YY_BREAK
+ case 22:
+ YY_RULE_SETUP
+ {
+ return ES2_reserved_ES3_keyword(context, FLAT);
+ }
+ YY_BREAK
+ case 23:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, SMOOTH);
+ }
+ YY_BREAK
+ case 24:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_extension(
+ context, TExtension::NV_shader_noperspective_interpolation,
+ NOPERSPECTIVE);
+ }
+ YY_BREAK
+ case 25:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_1_extension_ES3_2_keyword(
+ context, TExtension::EXT_tessellation_shader, PATCH);
+ }
+ YY_BREAK
+ case 26:
+ YY_RULE_SETUP
+ {
+ return IN_QUAL;
+ }
+ YY_BREAK
+ case 27:
+ YY_RULE_SETUP
+ {
+ return OUT_QUAL;
+ }
+ YY_BREAK
+ case 28:
+ YY_RULE_SETUP
+ {
+ return INOUT_QUAL;
+ }
+ YY_BREAK
+ case 29:
+ YY_RULE_SETUP
+ {
+ return ES3_1_keyword(context, SHARED);
+ }
+ YY_BREAK
+ case 30:
+ YY_RULE_SETUP
+ {
+ return FLOAT_TYPE;
+ }
+ YY_BREAK
+ case 31:
+ YY_RULE_SETUP
+ {
+ return INT_TYPE;
+ }
+ YY_BREAK
+ case 32:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, UINT_TYPE);
+ }
+ YY_BREAK
+ case 33:
+ YY_RULE_SETUP
+ {
+ return VOID_TYPE;
+ }
+ YY_BREAK
+ case 34:
+ YY_RULE_SETUP
+ {
+ return BOOL_TYPE;
+ }
+ YY_BREAK
+ case 35:
+ YY_RULE_SETUP
+ {
+ yylval->lex.b = true;
+ return BOOLCONSTANT;
+ }
+ YY_BREAK
+ case 36:
+ YY_RULE_SETUP
+ {
+ yylval->lex.b = false;
+ return BOOLCONSTANT;
+ }
+ YY_BREAK
+ case 37:
+ YY_RULE_SETUP
+ {
+ return DISCARD;
+ }
+ YY_BREAK
+ case 38:
+ YY_RULE_SETUP
+ {
+ return RETURN;
+ }
+ YY_BREAK
+ case 39:
+ YY_RULE_SETUP
+ {
+ return MATRIX2;
+ }
+ YY_BREAK
+ case 40:
+ YY_RULE_SETUP
+ {
+ return MATRIX3;
+ }
+ YY_BREAK
+ case 41:
+ YY_RULE_SETUP
+ {
+ return MATRIX4;
+ }
+ YY_BREAK
+ case 42:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, MATRIX2);
+ }
+ YY_BREAK
+ case 43:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, MATRIX3);
+ }
+ YY_BREAK
+ case 44:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, MATRIX4);
+ }
+ YY_BREAK
+ case 45:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, MATRIX2x3);
+ }
+ YY_BREAK
+ case 46:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, MATRIX3x2);
+ }
+ YY_BREAK
+ case 47:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, MATRIX2x4);
+ }
+ YY_BREAK
+ case 48:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, MATRIX4x2);
+ }
+ YY_BREAK
+ case 49:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, MATRIX3x4);
+ }
+ YY_BREAK
+ case 50:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, MATRIX4x3);
+ }
+ YY_BREAK
+ case 51:
+ YY_RULE_SETUP
+ {
+ return VEC2;
+ }
+ YY_BREAK
+ case 52:
+ YY_RULE_SETUP
+ {
+ return VEC3;
+ }
+ YY_BREAK
+ case 53:
+ YY_RULE_SETUP
+ {
+ return VEC4;
+ }
+ YY_BREAK
+ case 54:
+ YY_RULE_SETUP
+ {
+ return IVEC2;
+ }
+ YY_BREAK
+ case 55:
+ YY_RULE_SETUP
+ {
+ return IVEC3;
+ }
+ YY_BREAK
+ case 56:
+ YY_RULE_SETUP
+ {
+ return IVEC4;
+ }
+ YY_BREAK
+ case 57:
+ YY_RULE_SETUP
+ {
+ return BVEC2;
+ }
+ YY_BREAK
+ case 58:
+ YY_RULE_SETUP
+ {
+ return BVEC3;
+ }
+ YY_BREAK
+ case 59:
+ YY_RULE_SETUP
+ {
+ return BVEC4;
+ }
+ YY_BREAK
+ case 60:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, UVEC2);
+ }
+ YY_BREAK
+ case 61:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, UVEC3);
+ }
+ YY_BREAK
+ case 62:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, UVEC4);
+ }
+ YY_BREAK
+ case 63:
+ YY_RULE_SETUP
+ {
+ return SAMPLER2D;
+ }
+ YY_BREAK
+ case 64:
+ YY_RULE_SETUP
+ {
+ return SAMPLERCUBE;
+ }
+ YY_BREAK
+ case 65:
+ YY_RULE_SETUP
+ {
+ return SAMPLER_EXTERNAL_OES;
+ }
+ YY_BREAK
+ case 66:
+ YY_RULE_SETUP
+ {
+ return ES2_reserved_ES2_extension_ES3_keyword(
+ context, TExtension::OES_texture_3D, SAMPLER3D);
+ }
+ YY_BREAK
+ case 67:
+ YY_RULE_SETUP
+ {
+ return ES2_reserved_ES3_keyword(context, SAMPLER3DRECT);
+ }
+ YY_BREAK
+ case 68:
+ YY_RULE_SETUP
+ {
+ return SAMPLER2DRECT;
+ }
+ YY_BREAK
+ case 69:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, SAMPLER2DARRAY);
+ }
+ YY_BREAK
+ case 70:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_extension_ES3_1_keyword(
+ context, TExtension::ANGLE_texture_multisample, SAMPLER2DMS);
+ }
+ YY_BREAK
+ case 71:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, ISAMPLER2D);
+ }
+ YY_BREAK
+ case 72:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, ISAMPLER3D);
+ }
+ YY_BREAK
+ case 73:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, ISAMPLERCUBE);
+ }
+ YY_BREAK
+ case 74:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, ISAMPLER2DARRAY);
+ }
+ YY_BREAK
+ case 75:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_extension_ES3_1_keyword(
+ context, TExtension::ANGLE_texture_multisample, ISAMPLER2DMS);
+ }
+ YY_BREAK
+ case 76:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, USAMPLER2D);
+ }
+ YY_BREAK
+ case 77:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, USAMPLER3D);
+ }
+ YY_BREAK
+ case 78:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, USAMPLERCUBE);
+ }
+ YY_BREAK
+ case 79:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, USAMPLER2DARRAY);
+ }
+ YY_BREAK
+ case 80:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_extension_ES3_1_keyword(
+ context, TExtension::ANGLE_texture_multisample, USAMPLER2DMS);
+ }
+ YY_BREAK
+ case 81:
+ YY_RULE_SETUP
+ {
+ return ES2_reserved_ES2_extension_ES3_keyword(
+ context, TExtension::EXT_shadow_samplers, SAMPLER2DSHADOW);
+ }
+ YY_BREAK
+ case 82:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, SAMPLERCUBESHADOW);
+ }
+ YY_BREAK
+ case 83:
+ YY_RULE_SETUP
+ {
+ return ES3_keyword(context, SAMPLER2DARRAYSHADOW);
+ }
+ YY_BREAK
+ case 84:
+ YY_RULE_SETUP
+ {
+ return ES3_extension(context, TExtension::EXT_YUV_target,
+ SAMPLEREXTERNAL2DY2YEXT);
+ }
+ YY_BREAK
+ case 85:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_1_extension_ES3_2_keyword(
+ context, TExtension::OES_texture_storage_multisample_2d_array,
+ SAMPLER2DMSARRAY);
+ }
+ YY_BREAK
+ case 86:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_1_extension_ES3_2_keyword(
+ context, TExtension::OES_texture_storage_multisample_2d_array,
+ ISAMPLER2DMSARRAY);
+ }
+ YY_BREAK
+ case 87:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_1_extension_ES3_2_keyword(
+ context, TExtension::OES_texture_storage_multisample_2d_array,
+ USAMPLER2DMSARRAY);
+ }
+ YY_BREAK
+ case 88:
+ YY_RULE_SETUP
+ {
+ return ES3_1_reserved_ES3_1_extension_ES3_2_keyword_2(
+ context, TExtension::OES_texture_cube_map_array,
+ TExtension::EXT_texture_cube_map_array, SAMPLERCUBEARRAYOES,
+ SAMPLERCUBEARRAYEXT);
+ }
+ YY_BREAK
+ case 89:
+ YY_RULE_SETUP
+ {
+ return ES3_and_3_1_reserved_ES3_1_extension_ES3_2_keyword_2(
+ context, TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer,
+ SAMPLERBUFFER, SAMPLERBUFFER);
+ }
+ YY_BREAK
+ case 90:
+ YY_RULE_SETUP
+ {
+ return ES3_1_reserved_ES3_1_extension_ES3_2_keyword_2(
+ context, TExtension::OES_texture_cube_map_array,
+ TExtension::EXT_texture_cube_map_array, SAMPLERCUBEARRAYSHADOWOES,
+ SAMPLERCUBEARRAYSHADOWEXT);
+ }
+ YY_BREAK
+ case 91:
+ YY_RULE_SETUP
+ {
+ return ES3_1_reserved_ES3_1_extension_ES3_2_keyword_2(
+ context, TExtension::OES_texture_cube_map_array,
+ TExtension::EXT_texture_cube_map_array, ISAMPLERCUBEARRAYOES,
+ ISAMPLERCUBEARRAYEXT);
+ }
+ YY_BREAK
+ case 92:
+ YY_RULE_SETUP
+ {
+ return ES3_and_3_1_reserved_ES3_1_extension_ES3_2_keyword_2(
+ context, TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer,
+ ISAMPLERBUFFER, ISAMPLERBUFFER);
+ }
+ YY_BREAK
+ case 93:
+ YY_RULE_SETUP
+ {
+ return ES3_1_reserved_ES3_1_extension_ES3_2_keyword_2(
+ context, TExtension::OES_texture_cube_map_array,
+ TExtension::EXT_texture_cube_map_array, USAMPLERCUBEARRAYOES,
+ USAMPLERCUBEARRAYEXT);
+ }
+ YY_BREAK
+ case 94:
+ YY_RULE_SETUP
+ {
+ return ES3_and_3_1_reserved_ES3_1_extension_ES3_2_keyword_2(
+ context, TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer,
+ USAMPLERBUFFER, USAMPLERBUFFER);
+ }
+ YY_BREAK
+ case 95:
+ YY_RULE_SETUP
+ {
+ return WEBGL_video_texture_extension(context, SAMPLERVIDEOWEBGL);
+ }
+ YY_BREAK
+ case 96:
+ YY_RULE_SETUP
+ {
+ return STRUCT;
+ }
+ YY_BREAK
+ case 97:
+ YY_RULE_SETUP
+ {
+ return ES2_extensions_ES3_keyword(
+ context, TExtension::EXT_shader_framebuffer_fetch,
+ TExtension::EXT_shader_framebuffer_fetch_non_coherent,
+ TExtension::KHR_blend_equation_advanced, LAYOUT);
+ }
+ YY_BREAK
+ case 98:
+ YY_RULE_SETUP
+ {
+ return ES3_extension(context, TExtension::EXT_YUV_target,
+ YUVCSCSTANDARDEXT);
+ }
+ YY_BREAK
+ case 99:
+ YY_RULE_SETUP
+ {
+ return yuvcscstandardext_constant(context);
+ }
+ YY_BREAK
+ case 100:
+ YY_RULE_SETUP
+ {
+ return yuvcscstandardext_constant(context);
+ }
+ YY_BREAK
+ case 101:
+ YY_RULE_SETUP
+ {
+ return yuvcscstandardext_constant(context);
+ }
+ YY_BREAK
+ case 102:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_1_keyword(context, IMAGE2D);
+ }
+ YY_BREAK
+ case 103:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_1_keyword(context, IIMAGE2D);
+ }
+ YY_BREAK
+ case 104:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_1_keyword(context, UIMAGE2D);
+ }
+ YY_BREAK
+ case 105:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_1_keyword(context, IMAGE2DARRAY);
+ }
+ YY_BREAK
+ case 106:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_1_keyword(context, IIMAGE2DARRAY);
+ }
+ YY_BREAK
+ case 107:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_1_keyword(context, UIMAGE2DARRAY);
+ }
+ YY_BREAK
+ case 108:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_1_keyword(context, IMAGE3D);
+ }
+ YY_BREAK
+ case 109:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_1_keyword(context, UIMAGE3D);
+ }
+ YY_BREAK
+ case 110:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_1_keyword(context, IIMAGE3D);
+ }
+ YY_BREAK
+ case 111:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_1_keyword(context, IIMAGECUBE);
+ }
+ YY_BREAK
+ case 112:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_1_keyword(context, UIMAGECUBE);
+ }
+ YY_BREAK
+ case 113:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_1_keyword(context, IMAGECUBE);
+ }
+ YY_BREAK
+ case 114:
+ YY_RULE_SETUP
+ {
+ return ES3_1_reserved_ES3_1_extension_ES3_2_keyword_2(
+ context, TExtension::OES_texture_cube_map_array,
+ TExtension::EXT_texture_cube_map_array, IMAGECUBEARRAYOES,
+ IMAGECUBEARRAYEXT);
+ }
+ YY_BREAK
+ case 115:
+ YY_RULE_SETUP
+ {
+ return ES3_1_reserved_ES3_1_extension_ES3_2_keyword_2(
+ context, TExtension::OES_texture_cube_map_array,
+ TExtension::EXT_texture_cube_map_array, IIMAGECUBEARRAYOES,
+ IIMAGECUBEARRAYEXT);
+ }
+ YY_BREAK
+ case 116:
+ YY_RULE_SETUP
+ {
+ return ES3_1_reserved_ES3_1_extension_ES3_2_keyword_2(
+ context, TExtension::OES_texture_cube_map_array,
+ TExtension::EXT_texture_cube_map_array, UIMAGECUBEARRAYOES,
+ UIMAGECUBEARRAYEXT);
+ }
+ YY_BREAK
+ case 117:
+ YY_RULE_SETUP
+ {
+ return ES3_and_3_1_reserved_ES3_1_extension_ES3_2_keyword_2(
+ context, TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer,
+ IMAGEBUFFER, IMAGEBUFFER);
+ }
+ YY_BREAK
+ case 118:
+ YY_RULE_SETUP
+ {
+ return ES3_and_3_1_reserved_ES3_1_extension_ES3_2_keyword_2(
+ context, TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer,
+ IIMAGEBUFFER, IIMAGEBUFFER);
+ }
+ YY_BREAK
+ case 119:
+ YY_RULE_SETUP
+ {
+ return ES3_and_3_1_reserved_ES3_1_extension_ES3_2_keyword_2(
+ context, TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer,
+ UIMAGEBUFFER, UIMAGEBUFFER);
+ }
+ YY_BREAK
+ case 120:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_1_keyword(context, READONLY);
+ }
+ YY_BREAK
+ case 121:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_1_keyword(context, WRITEONLY);
+ }
+ YY_BREAK
+ case 122:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_1_keyword(context, COHERENT);
+ }
+ YY_BREAK
+ case 123:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_1_keyword(context, RESTRICT);
+ }
+ YY_BREAK
+ case 124:
+ YY_RULE_SETUP
+ {
+ return ES2_reserved_ES3_1_keyword(context, VOLATILE);
+ }
+ YY_BREAK
+ case 125:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_1_keyword(context, ATOMICUINT);
+ }
+ YY_BREAK
+ case 126:
+ YY_RULE_SETUP
+ {
+ return ES3_reserved_ES3_extension_ES3_2_keyword(
+ context, TExtension::OES_shader_multisample_interpolation, SAMPLE);
+ }
+ YY_BREAK
+ case 127:
+ YY_RULE_SETUP
+ {
+ return ES3_1_reserved_ES3_1_extension_ES3_2_keyword(
+ context, TExtension::EXT_gpu_shader5, PRECISE);
+ }
+ YY_BREAK
+ /* ANGLE_shader_pixel_local_storage */
+ case 128:
+ YY_RULE_SETUP
+ {
+ return ES3_extension(context, TExtension::ANGLE_shader_pixel_local_storage,
+ PIXELLOCALANGLE);
+ }
+ YY_BREAK
+ case 129:
+ YY_RULE_SETUP
+ {
+ return ES3_extension(context, TExtension::ANGLE_shader_pixel_local_storage,
+ IPIXELLOCALANGLE);
+ }
+ YY_BREAK
+ case 130:
+ YY_RULE_SETUP
+ {
+ return ES3_extension(context, TExtension::ANGLE_shader_pixel_local_storage,
+ UPIXELLOCALANGLE);
+ }
+ YY_BREAK
+ /* Reserved keywords for GLSL ES 3.00 that are not reserved for GLSL ES 1.00 */
+ case 131:
+ case 132:
+ case 133:
+ case 134:
+ case 135:
+ case 136:
+ case 137:
+ case 138:
+ case 139:
+ case 140:
+ case 141:
+ case 142:
+ case 143:
+ case 144:
+ case 145:
+ case 146:
+ case 147:
+ case 148:
+ case 149:
+ case 150:
+ case 151:
+ case 152:
+ case 153:
+ case 154:
+ YY_RULE_SETUP
+ {
+ if (context->getShaderVersion() < 300)
+ {
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
+ return check_type(yyscanner);
+ }
+ return reserved_word(yyscanner);
+ }
+ YY_BREAK
+ /* Reserved keywords in GLSL ES 1.00 that are not reserved in GLSL ES 3.00 */
+ case 155:
+ YY_RULE_SETUP
+ {
+ if (context->getShaderVersion() >= 300)
+ {
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
+ return check_type(yyscanner);
+ }
+
+ return reserved_word(yyscanner);
+ }
+ YY_BREAK
+ /* Reserved keywords */
+ case 156:
+ case 157:
+ case 158:
+ case 159:
+ case 160:
+ case 161:
+ case 162:
+ case 163:
+ case 164:
+ case 165:
+ case 166:
+ case 167:
+ case 168:
+ case 169:
+ case 170:
+ case 171:
+ case 172:
+ case 173:
+ case 174:
+ case 175:
+ case 176:
+ case 177:
+ case 178:
+ case 179:
+ case 180:
+ case 181:
+ case 182:
+ case 183:
+ case 184:
+ case 185:
+ case 186:
+ case 187:
+ case 188:
+ case 189:
+ case 190:
+ case 191:
+ case 192:
+ case 193:
+ case 194:
+ case 195:
+ YY_RULE_SETUP
+ {
+ return reserved_word(yyscanner);
+ }
+ YY_BREAK
+ case 196:
+ YY_RULE_SETUP
+ {
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
+ return check_type(yyscanner);
+ }
+ YY_BREAK
+ case 197:
+ YY_RULE_SETUP
+ {
+ return int_constant(context);
+ }
+ YY_BREAK
+ case 198:
+ YY_RULE_SETUP
+ {
+ return int_constant(context);
+ }
+ YY_BREAK
+ case 199:
+ YY_RULE_SETUP
+ {
+ return int_constant(context);
+ }
+ YY_BREAK
+ case 200:
+ YY_RULE_SETUP
+ {
+ return uint_constant(context);
+ }
+ YY_BREAK
+ case 201:
+ YY_RULE_SETUP
+ {
+ return uint_constant(context);
+ }
+ YY_BREAK
+ case 202:
+ YY_RULE_SETUP
+ {
+ return uint_constant(context);
+ }
+ YY_BREAK
+ case 203:
+ YY_RULE_SETUP
+ {
+ return float_constant(yyscanner);
+ }
+ YY_BREAK
+ case 204:
+ YY_RULE_SETUP
+ {
+ return float_constant(yyscanner);
+ }
+ YY_BREAK
+ case 205:
+ YY_RULE_SETUP
+ {
+ return float_constant(yyscanner);
+ }
+ YY_BREAK
+ case 206:
+ YY_RULE_SETUP
+ {
+ return floatsuffix_check(context);
+ }
+ YY_BREAK
+ case 207:
+ YY_RULE_SETUP
+ {
+ return floatsuffix_check(context);
+ }
+ YY_BREAK
+ case 208:
+ YY_RULE_SETUP
+ {
+ return floatsuffix_check(context);
+ }
+ YY_BREAK
+ case 209:
+ YY_RULE_SETUP
+ {
+ return ADD_ASSIGN;
+ }
+ YY_BREAK
+ case 210:
+ YY_RULE_SETUP
+ {
+ return SUB_ASSIGN;
+ }
+ YY_BREAK
+ case 211:
+ YY_RULE_SETUP
+ {
+ return MUL_ASSIGN;
+ }
+ YY_BREAK
+ case 212:
+ YY_RULE_SETUP
+ {
+ return DIV_ASSIGN;
+ }
+ YY_BREAK
+ case 213:
+ YY_RULE_SETUP
+ {
+ return MOD_ASSIGN;
+ }
+ YY_BREAK
+ case 214:
+ YY_RULE_SETUP
+ {
+ return LEFT_ASSIGN;
+ }
+ YY_BREAK
+ case 215:
+ YY_RULE_SETUP
+ {
+ return RIGHT_ASSIGN;
+ }
+ YY_BREAK
+ case 216:
+ YY_RULE_SETUP
+ {
+ return AND_ASSIGN;
+ }
+ YY_BREAK
+ case 217:
+ YY_RULE_SETUP
+ {
+ return XOR_ASSIGN;
+ }
+ YY_BREAK
+ case 218:
+ YY_RULE_SETUP
+ {
+ return OR_ASSIGN;
+ }
+ YY_BREAK
+ case 219:
+ YY_RULE_SETUP
+ {
+ return INC_OP;
+ }
+ YY_BREAK
+ case 220:
+ YY_RULE_SETUP
+ {
+ return DEC_OP;
+ }
+ YY_BREAK
+ case 221:
+ YY_RULE_SETUP
+ {
+ return AND_OP;
+ }
+ YY_BREAK
+ case 222:
+ YY_RULE_SETUP
+ {
+ return OR_OP;
+ }
+ YY_BREAK
+ case 223:
+ YY_RULE_SETUP
+ {
+ return XOR_OP;
+ }
+ YY_BREAK
+ case 224:
+ YY_RULE_SETUP
+ {
+ return LE_OP;
+ }
+ YY_BREAK
+ case 225:
+ YY_RULE_SETUP
+ {
+ return GE_OP;
+ }
+ YY_BREAK
+ case 226:
+ YY_RULE_SETUP
+ {
+ return EQ_OP;
+ }
+ YY_BREAK
+ case 227:
+ YY_RULE_SETUP
+ {
+ return NE_OP;
+ }
+ YY_BREAK
+ case 228:
+ YY_RULE_SETUP
+ {
+ return LEFT_OP;
+ }
+ YY_BREAK
+ case 229:
+ YY_RULE_SETUP
+ {
+ return RIGHT_OP;
+ }
+ YY_BREAK
+ case 230:
+ YY_RULE_SETUP
+ {
+ return SEMICOLON;
+ }
+ YY_BREAK
+ case 231:
+ YY_RULE_SETUP
+ {
+ return LEFT_BRACE;
+ }
+ YY_BREAK
+ case 232:
+ YY_RULE_SETUP
+ {
+ return RIGHT_BRACE;
+ }
+ YY_BREAK
+ case 233:
+ YY_RULE_SETUP
+ {
+ return COMMA;
+ }
+ YY_BREAK
+ case 234:
+ YY_RULE_SETUP
+ {
+ return COLON;
+ }
+ YY_BREAK
+ case 235:
+ YY_RULE_SETUP
+ {
+ return EQUAL;
+ }
+ YY_BREAK
+ case 236:
+ YY_RULE_SETUP
+ {
+ return LEFT_PAREN;
+ }
+ YY_BREAK
+ case 237:
+ YY_RULE_SETUP
+ {
+ return RIGHT_PAREN;
+ }
+ YY_BREAK
+ case 238:
+ YY_RULE_SETUP
+ {
+ return LEFT_BRACKET;
+ }
+ YY_BREAK
+ case 239:
+ YY_RULE_SETUP
+ {
+ return RIGHT_BRACKET;
+ }
+ YY_BREAK
+ case 240:
+ YY_RULE_SETUP
+ {
+ BEGIN(FIELDS);
+ return DOT;
+ }
+ YY_BREAK
+ case 241:
+ YY_RULE_SETUP
+ {
+ return BANG;
+ }
+ YY_BREAK
+ case 242:
+ YY_RULE_SETUP
+ {
+ return DASH;
+ }
+ YY_BREAK
+ case 243:
+ YY_RULE_SETUP
+ {
+ return TILDE;
+ }
+ YY_BREAK
+ case 244:
+ YY_RULE_SETUP
+ {
+ return PLUS;
+ }
+ YY_BREAK
+ case 245:
+ YY_RULE_SETUP
+ {
+ return STAR;
+ }
+ YY_BREAK
+ case 246:
+ YY_RULE_SETUP
+ {
+ return SLASH;
+ }
+ YY_BREAK
+ case 247:
+ YY_RULE_SETUP
+ {
+ return PERCENT;
+ }
+ YY_BREAK
+ case 248:
+ YY_RULE_SETUP
+ {
+ return LEFT_ANGLE;
+ }
+ YY_BREAK
+ case 249:
+ YY_RULE_SETUP
+ {
+ return RIGHT_ANGLE;
+ }
+ YY_BREAK
+ case 250:
+ YY_RULE_SETUP
+ {
+ return VERTICAL_BAR;
+ }
+ YY_BREAK
+ case 251:
+ YY_RULE_SETUP
+ {
+ return CARET;
+ }
+ YY_BREAK
+ case 252:
+ YY_RULE_SETUP
+ {
+ return AMPERSAND;
+ }
+ YY_BREAK
+ case 253:
+ YY_RULE_SETUP
+ {
+ return QUESTION;
+ }
+ YY_BREAK
+ case 254:
+ YY_RULE_SETUP
+ {
+ BEGIN(INITIAL);
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
+ return FIELD_SELECTION;
+ }
+ YY_BREAK
+ case 255:
+ YY_RULE_SETUP {}
+ YY_BREAK
+ case 256:
+ YY_RULE_SETUP
+ {
+ yyextra->error(*yylloc, "Illegal character at fieldname start", yytext);
+ return 0;
+ }
+ YY_BREAK
+ case 257:
+ /* rule 257 can match eol */
+ YY_RULE_SETUP {}
+ YY_BREAK
+ case YY_STATE_EOF(INITIAL):
+ case YY_STATE_EOF(FIELDS):
+ {
+ yyterminate();
+ }
+ YY_BREAK
+ case 258:
+ YY_RULE_SETUP
+ {
+ assert(false);
+ return 0;
+ }
+ YY_BREAK
+ case 259:
+ YY_RULE_SETUP
+ ECHO;
+ YY_BREAK
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int)(yy_cp - yyg->yytext_ptr) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = yyg->yy_hold_char;
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if (YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW)
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * yylex(). If so, then we have to assure
+ * consistency between YY_CURRENT_BUFFER and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if (yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars])
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state(yyscanner);
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans(yy_current_state, yyscanner);
+
+ yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+
+ if (yy_next_state)
+ {
+ /* Consume the NUL. */
+ yy_cp = ++yyg->yy_c_buf_p;
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = yyg->yy_last_accepting_cpos;
+ yy_current_state = yyg->yy_last_accepting_state;
+ goto yy_find_action;
+ }
+ }
+
+ else
+ switch (yy_get_next_buffer(yyscanner))
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ yyg->yy_did_buffer_switch_on_eof = 0;
+
+ if (yywrap(yyscanner))
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if (!yyg->yy_did_buffer_switch_on_eof)
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state(yyscanner);
+
+ yy_cp = yyg->yy_c_buf_p;
+ yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ yyg->yy_c_buf_p =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars];
+
+ yy_current_state = yy_get_previous_state(yyscanner);
+
+ yy_cp = yyg->yy_c_buf_p;
+ yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR("fatal flex scanner internal error--no action found");
+ } /* end of action switch */
+ } /* end of scanning one token */
+ } /* end of user's declarations */
+} /* end of yylex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ char *source = yyg->yytext_ptr;
+ int 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])
+ YY_FATAL_ERROR("fatal flex scanner internal error--end of buffer missed");
+
+ if (YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0)
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if (yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1)
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* 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);
+
+ for (i = 0; i < number_to_move; ++i)
+ *(dest++) = *(source++);
+
+ if (YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING)
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0;
+
+ else
+ {
+ int num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+ while (num_to_read <= 0)
+ { /* Not enough room in the buffer - grow it. */
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;
+
+ int yy_c_buf_p_offset = (int)(yyg->yy_c_buf_p - b->yy_ch_buf);
+
+ if (b->yy_is_our_buffer)
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if (new_size <= 0)
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ yyrealloc((void *)b->yy_ch_buf, (yy_size_t)(b->yy_buf_size + 2), yyscanner);
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = NULL;
+
+ if (!b->yy_ch_buf)
+ YY_FATAL_ERROR("fatal error - scanner input buffer overflow");
+
+ 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;
+ }
+
+ if (num_to_read > YY_READ_BUF_SIZE)
+ 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]), ret, num_to_read);
+ yyg->yy_n_chars = static_cast<int>(ret);
+
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+ }
+
+ if (yyg->yy_n_chars == 0)
+ {
+ if (number_to_move == YY_MORE_ADJ)
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ yyrestart(yyin, yyscanner);
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ if ((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_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *)yyrealloc(
+ (void *)YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t)new_size, yyscanner);
+ if (!YY_CURRENT_BUFFER_LVALUE->yy_ch_buf)
+ YY_FATAL_ERROR("out of dynamic memory in yy_get_next_buffer()");
+ /* "- 2" to take care of EOB's */
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int)(new_size - 2);
+ }
+
+ yyg->yy_n_chars += 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;
+
+ yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+ 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)
+{
+ 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)
+ {
+ 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;
+ yyg->yy_last_accepting_cpos = yy_cp;
+ }
+ while (yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state)
+ {
+ yy_current_state = (int)yy_def[yy_current_state];
+ if (yy_current_state >= 982)
+ yy_c = yy_meta[yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
+ }
+
+ return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+static yy_state_type yy_try_NUL_trans(yy_state_type yy_current_state, yyscan_t yyscanner)
+{
+ int yy_is_jam;
+ struct yyguts_t *yyg =
+ (struct yyguts_t *)yyscanner; /* This var may be unused depending upon options. */
+ char *yy_cp = yyg->yy_c_buf_p;
+
+ YY_CHAR yy_c = 1;
+ if (yy_accept[yy_current_state])
+ {
+ yyg->yy_last_accepting_state = yy_current_state;
+ yyg->yy_last_accepting_cpos = yy_cp;
+ }
+ while (yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state)
+ {
+ yy_current_state = (int)yy_def[yy_current_state];
+ if (yy_current_state >= 982)
+ yy_c = yy_meta[yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
+ yy_is_jam = (yy_current_state == 981);
+
+ (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)
+# else
+static int input(yyscan_t yyscanner)
+# endif
+
+{
+ int c;
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+
+ *yyg->yy_c_buf_p = yyg->yy_hold_char;
+
+ if (*yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR)
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if (yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars])
+ /* This was really a NUL. */
+ *yyg->yy_c_buf_p = '\0';
+
+ else
+ { /* need more input */
+ int offset = (int)(yyg->yy_c_buf_p - yyg->yytext_ptr);
+ ++yyg->yy_c_buf_p;
+
+ switch (yy_get_next_buffer(yyscanner))
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ yyrestart(yyin, yyscanner);
+
+ /*FALLTHROUGH*/
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if (yywrap(yyscanner))
+ return 0;
+
+ if (!yyg->yy_did_buffer_switch_on_eof)
+ YY_NEW_FILE;
+# ifdef __cplusplus
+ return yyinput(yyscanner);
+# else
+ return input(yyscanner);
+# endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yyg->yy_c_buf_p = yyg->yytext_ptr + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *)yyg->yy_c_buf_p; /* cast for 8-bit char's */
+ *yyg->yy_c_buf_p = '\0'; /* preserve yytext */
+ yyg->yy_hold_char = *++yyg->yy_c_buf_p;
+
+ if (c == '\n')
+
+ do
+ {
+ yylineno++;
+ yycolumn = 0;
+ } while (0);
+
+ return c;
+}
+#endif /* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ * @param yyscanner The scanner object.
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+void yyrestart(FILE *input_file, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+
+ if (!YY_CURRENT_BUFFER)
+ {
+ yyensure_buffer_stack(yyscanner);
+ YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin, YY_BUF_SIZE, yyscanner);
+ }
+
+ yy_init_buffer(YY_CURRENT_BUFFER, input_file, yyscanner);
+ yy_load_buffer_state(yyscanner);
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ * @param yyscanner The scanner object.
+ */
+void yy_switch_to_buffer(YY_BUFFER_STATE new_buffer, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+
+ /* TODO. We should be able to replace this entire function body
+ * with
+ * yypop_buffer_state();
+ * yypush_buffer_state(new_buffer);
+ */
+ yyensure_buffer_stack(yyscanner);
+ if (YY_CURRENT_BUFFER == new_buffer)
+ return;
+
+ if (YY_CURRENT_BUFFER)
+ {
+ /* Flush out information for old buffer. */
+ *yyg->yy_c_buf_p = yyg->yy_hold_char;
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+ }
+
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+ yy_load_buffer_state(yyscanner);
+
+ /* We don't actually know whether we did this switch during
+ * EOF (yywrap()) processing, but the only time this flag
+ * is looked at is after yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ yyg->yy_did_buffer_switch_on_eof = 1;
+}
+
+static void yy_load_buffer_state(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+ yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+ yyg->yy_hold_char = *yyg->yy_c_buf_p;
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ * @param yyscanner The scanner object.
+ * @return the allocated buffer state.
+ */
+YY_BUFFER_STATE yy_create_buffer(FILE *file, int size, yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE)yyalloc(sizeof(struct yy_buffer_state), yyscanner);
+ if (!b)
+ YY_FATAL_ERROR("out of dynamic memory in yy_create_buffer()");
+
+ b->yy_buf_size = 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.
+ */
+ b->yy_ch_buf = (char *)yyalloc((yy_size_t)(b->yy_buf_size + 2), yyscanner);
+ if (!b->yy_ch_buf)
+ YY_FATAL_ERROR("out of dynamic memory in yy_create_buffer()");
+
+ b->yy_is_our_buffer = 1;
+
+ yy_init_buffer(b, file, yyscanner);
+
+ return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with yy_create_buffer()
+ * @param yyscanner The scanner object.
+ */
+void yy_delete_buffer(YY_BUFFER_STATE b, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+
+ if (!b)
+ return;
+
+ if (b == YY_CURRENT_BUFFER) /* Not sure if we should pop here. */
+ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE)0;
+
+ if (b->yy_is_our_buffer)
+ yyfree((void *)b->yy_ch_buf, yyscanner);
+
+ yyfree((void *)b, yyscanner);
+}
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a yyrestart() or at EOF.
+ */
+static void yy_init_buffer(YY_BUFFER_STATE b, FILE *file, yyscan_t yyscanner)
+
+{
+ int oerrno = errno;
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+
+ yy_flush_buffer(b, yyscanner);
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+ /* If b is the current buffer, then yy_init_buffer was _probably_
+ * called from yyrestart() or through yy_get_next_buffer.
+ * In that case, we don't want to reset the lineno or column.
+ */
+ if (b != YY_CURRENT_BUFFER)
+ {
+ b->yy_bs_lineno = 1;
+ b->yy_bs_column = 0;
+ }
+
+ b->yy_is_interactive = 0;
+
+ errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ * @param yyscanner The scanner object.
+ */
+void yy_flush_buffer(YY_BUFFER_STATE b, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ if (!b)
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if (b == YY_CURRENT_BUFFER)
+ yy_load_buffer_state(yyscanner);
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ * the current state. This function will allocate the stack
+ * if necessary.
+ * @param new_buffer The new state.
+ * @param yyscanner The scanner object.
+ */
+void yypush_buffer_state(YY_BUFFER_STATE new_buffer, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ if (new_buffer == NULL)
+ return;
+
+ yyensure_buffer_stack(yyscanner);
+
+ /* This block is copied from yy_switch_to_buffer. */
+ if (YY_CURRENT_BUFFER)
+ {
+ /* Flush out information for old buffer. */
+ *yyg->yy_c_buf_p = yyg->yy_hold_char;
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+ }
+
+ /* Only push if top exists. Otherwise, replace top. */
+ if (YY_CURRENT_BUFFER)
+ yyg->yy_buffer_stack_top++;
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+ /* copied from yy_switch_to_buffer. */
+ yy_load_buffer_state(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.
+ */
+void yypop_buffer_state(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ yy_delete_buffer(YY_CURRENT_BUFFER, yyscanner);
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ if (yyg->yy_buffer_stack_top > 0)
+ --yyg->yy_buffer_stack_top;
+
+ if (YY_CURRENT_BUFFER)
+ {
+ yy_load_buffer_state(yyscanner);
+ yyg->yy_did_buffer_switch_on_eof = 1;
+ }
+}
+
+/* Allocates the stack if it does not exist.
+ * Guarantees space for at least one push.
+ */
+static void yyensure_buffer_stack(yyscan_t yyscanner)
+{
+ yy_size_t num_to_alloc;
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+
+ if (!yyg->yy_buffer_stack)
+ {
+
+ /* First allocation is just for 2 elements, since we don't know if this
+ * 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; /* After all that talk, this was set to 1 anyways... */
+ yyg->yy_buffer_stack = (struct yy_buffer_state **)yyalloc(
+ num_to_alloc * sizeof(struct yy_buffer_state *), yyscanner);
+ if (!yyg->yy_buffer_stack)
+ YY_FATAL_ERROR("out of dynamic memory in yyensure_buffer_stack()");
+
+ memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state *));
+
+ yyg->yy_buffer_stack_max = num_to_alloc;
+ yyg->yy_buffer_stack_top = 0;
+ return;
+ }
+
+ if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1)
+ {
+
+ /* Increase the buffer to prepare for a possible push. */
+ 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 **)yyrealloc(
+ yyg->yy_buffer_stack, num_to_alloc * sizeof(struct yy_buffer_state *), yyscanner);
+ if (!yyg->yy_buffer_stack)
+ YY_FATAL_ERROR("out of dynamic memory in yyensure_buffer_stack()");
+
+ /* zero only the new slots.*/
+ memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0,
+ grow_size * sizeof(struct yy_buffer_state *));
+ yyg->yy_buffer_stack_max = num_to_alloc;
+ }
+}
+
+/** 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
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_buffer(char *base, yy_size_t size, yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+
+ if (size < 2 || 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 NULL;
+
+ b = (YY_BUFFER_STATE)yyalloc(sizeof(struct yy_buffer_state), yyscanner);
+ if (!b)
+ YY_FATAL_ERROR("out of dynamic memory in yy_scan_buffer()");
+
+ b->yy_buf_size = (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;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ yy_switch_to_buffer(b, yyscanner);
+
+ return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to yylex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ * yy_scan_bytes() instead.
+ */
+YY_BUFFER_STATE yy_scan_string(const char *yystr, yyscan_t yyscanner)
+{
+
+ return yy_scan_bytes(yystr, (int)strlen(yystr), yyscanner);
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
+ * scan from a @e copy of @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_bytes(const char *yybytes, int _yybytes_len, yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = (yy_size_t)(_yybytes_len + 2);
+ buf = (char *)yyalloc(n, yyscanner);
+ if (!buf)
+ YY_FATAL_ERROR("out of dynamic memory in yy_scan_bytes()");
+
+ for (i = 0; i < _yybytes_len; ++i)
+ buf[i] = yybytes[i];
+
+ buf[_yybytes_len] = buf[_yybytes_len + 1] = YY_END_OF_BUFFER_CHAR;
+
+ b = yy_scan_buffer(buf, n, yyscanner);
+ if (!b)
+ YY_FATAL_ERROR("bad buffer in yy_scan_bytes()");
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+# define YY_EXIT_FAILURE 2
+#endif
+
+static void yynoreturn yy_fatal_error(const char *msg, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ (void)yyg;
+ fprintf(stderr, "%s\n", msg);
+ exit(YY_EXIT_FAILURE);
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg); \
+ yytext[yyleng] = yyg->yy_hold_char; \
+ yyg->yy_c_buf_p = yytext + yyless_macro_arg; \
+ yyg->yy_hold_char = *yyg->yy_c_buf_p; \
+ *yyg->yy_c_buf_p = '\0'; \
+ yyleng = yyless_macro_arg; \
+ } while (0)
+
+/* Accessor methods (get/set functions) to struct members. */
+
+/** Get the user-defined data for this scanner.
+ * @param yyscanner The scanner object.
+ */
+YY_EXTRA_TYPE yyget_extra(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ return yyextra;
+}
+
+/** Get the current line number.
+ * @param yyscanner The scanner object.
+ */
+int yyget_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.
+ */
+int yyget_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.
+ */
+FILE *yyget_in(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ return yyin;
+}
+
+/** Get the output stream.
+ * @param yyscanner The scanner object.
+ */
+FILE *yyget_out(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ return yyout;
+}
+
+/** Get the length of the current token.
+ * @param yyscanner The scanner object.
+ */
+int yyget_leng(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ return yyleng;
+}
+
+/** Get the current token.
+ * @param yyscanner The scanner object.
+ */
+
+char *yyget_text(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_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.
+ */
+void yyset_extra(YY_EXTRA_TYPE user_defined, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ yyextra = user_defined;
+}
+
+/** Set the current line number.
+ * @param _line_number line number
+ * @param yyscanner The scanner object.
+ */
+void yyset_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("yyset_lineno called with no buffer");
+
+ yylineno = _line_number;
+}
+
+/** Set the current column.
+ * @param _column_no column number
+ * @param yyscanner The scanner object.
+ */
+void yyset_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("yyset_column called with no buffer");
+
+ yycolumn = _column_no;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param _in_str A readable stream.
+ * @param yyscanner The scanner object.
+ * @see yy_switch_to_buffer
+ */
+void yyset_in(FILE *_in_str, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ yyin = _in_str;
+}
+
+void yyset_out(FILE *_out_str, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ yyout = _out_str;
+}
+
+int yyget_debug(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ return yy_flex_debug;
+}
+
+void yyset_debug(int _bdebug, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ yy_flex_debug = _bdebug;
+}
+
+/* Accessor methods for yylval and yylloc */
+
+YYSTYPE *yyget_lval(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ return yylval;
+}
+
+void yyset_lval(YYSTYPE *yylval_param, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ yylval = yylval_param;
+}
+
+YYLTYPE *yyget_lloc(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ return yylloc;
+}
+
+void yyset_lloc(YYLTYPE *yylloc_param, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ yylloc = yylloc_param;
+}
+
+/* User-visible API */
+
+/* yylex_init is special because it creates the scanner itself, so it is
+ * the ONLY reentrant function that doesn't take the scanner as the last argument.
+ * That's why we explicitly handle the declaration, instead of using our macros.
+ */
+int yylex_init(yyscan_t *ptr_yy_globals)
+{
+ if (ptr_yy_globals == NULL)
+ {
+ errno = EINVAL;
+ return 1;
+ }
+
+ *ptr_yy_globals = (yyscan_t)yyalloc(sizeof(struct yyguts_t), NULL);
+
+ if (*ptr_yy_globals == NULL)
+ {
+ errno = ENOMEM;
+ return 1;
+ }
+
+ /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */
+ memset(*ptr_yy_globals, 0x00, sizeof(struct yyguts_t));
+
+ return yy_init_globals(*ptr_yy_globals);
+}
+
+/* yylex_init_extra has the same functionality as yylex_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
+ * is the reason, too, why this function also must handle its own declaration).
+ * The user defined value in the first argument will be available to yyalloc in
+ * the yyextra field.
+ */
+int yylex_init_extra(YY_EXTRA_TYPE yy_user_defined, yyscan_t *ptr_yy_globals)
+{
+ struct yyguts_t dummy_yyguts;
+
+ yyset_extra(yy_user_defined, &dummy_yyguts);
+
+ if (ptr_yy_globals == NULL)
+ {
+ errno = EINVAL;
+ return 1;
+ }
+
+ *ptr_yy_globals = (yyscan_t)yyalloc(sizeof(struct yyguts_t), &dummy_yyguts);
+
+ if (*ptr_yy_globals == NULL)
+ {
+ errno = ENOMEM;
+ return 1;
+ }
+
+ /* By setting to 0xAA, we expose bugs in
+ yy_init_globals. Leave at 0x00 for releases. */
+ memset(*ptr_yy_globals, 0x00, sizeof(struct yyguts_t));
+
+ yyset_extra(yy_user_defined, *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;
+ /* Initialization is the same as for the non-reentrant scanner.
+ * This function is called from yylex_destroy(), so don't allocate here.
+ */
+
+ yyg->yy_buffer_stack = NULL;
+ yyg->yy_buffer_stack_top = 0;
+ yyg->yy_buffer_stack_max = 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 = NULL;
+ yyout = NULL;
+#endif
+
+ /* For future reference: Set errno on error, since we are called by
+ * yylex_init()
+ */
+ return 0;
+}
+
+/* yylex_destroy is for both reentrant and non-reentrant scanners. */
+int yylex_destroy(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+
+ /* Pop the buffer stack, destroying each element. */
+ while (YY_CURRENT_BUFFER)
+ {
+ yy_delete_buffer(YY_CURRENT_BUFFER, yyscanner);
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ yypop_buffer_state(yyscanner);
+ }
+
+ /* Destroy the stack itself. */
+ yyfree(yyg->yy_buffer_stack, yyscanner);
+ yyg->yy_buffer_stack = NULL;
+
+ /* Destroy the start condition stack. */
+ yyfree(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
+ * yylex() is called, initialization will occur. */
+ yy_init_globals(yyscanner);
+
+ /* Destroy the main struct (reentrant only). */
+ yyfree(yyscanner, yyscanner);
+ yyscanner = NULL;
+ return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy(char *s1, const char *s2, int n, yyscan_t yyscanner)
+{
+ 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(const char *s, yyscan_t yyscanner)
+{
+ int n;
+ for (n = 0; s[n]; ++n)
+ ;
+
+ return n;
+}
+#endif
+
+void *yyalloc(yy_size_t size, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ (void)yyg;
+ return malloc(size);
+}
+
+void *yyrealloc(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
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return realloc(ptr, size);
+}
+
+void yyfree(void *ptr, yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+ (void)yyg;
+ free((char *)ptr); /* see yyrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+yy_size_t string_input(char *buf, yy_size_t max_size, yyscan_t yyscanner)
+{
+ angle::pp::Token token;
+ yyget_extra(yyscanner)->getPreprocessor().lex(&token);
+ yy_size_t len = token.type == angle::pp::Token::LAST ? 0 : token.text.size();
+ if (len < max_size)
+ memcpy(buf, token.text.c_str(), len);
+ yyset_column(token.location.file, yyscanner);
+ yyset_lineno(token.location.line, yyscanner);
+
+ if (len >= max_size)
+ YY_FATAL_ERROR("Input buffer overflow");
+ else if (len > 0)
+ buf[len++] = ' ';
+ return len;
+}
+
+int check_type(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+
+ int token = IDENTIFIER;
+ // Note that the ImmutableString used here isn't static or pool allocated - but it's fine since
+ // yytext is valid for the duration of its use.
+ const TSymbol *symbol =
+ yyextra->symbolTable.find(ImmutableString(yytext, yyleng), yyextra->getShaderVersion());
+ if (symbol && symbol->isStruct())
+ {
+ token = TYPE_NAME;
+ }
+ yylval->lex.symbol = symbol;
+ return token;
+}
+
+int reserved_word(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+
+ yyextra->error(*yylloc, "Illegal use of reserved word", yytext);
+ return 0;
+}
+
+static bool is_extension_enabled_or_is_core(TParseContext *context,
+ int extension_version,
+ TExtension extension,
+ int promotion_version)
+{
+ int version = context->getShaderVersion();
+
+ // If version is at least promotion_version, symbol is definitely keyword. Otherwise it's a
+ // keyword if version is at least extension_version (where the extension was introduced) and
+ // the extension is enabled.
+ return version >= promotion_version ||
+ (version >= extension_version && context->isExtensionEnabled(extension));
+}
+
+int ES2_reserved_ES3_keyword(TParseContext *context, int token)
+{
+ yyscan_t yyscanner = (yyscan_t)context->getScanner();
+
+ if (context->getShaderVersion() < 300)
+ {
+ return reserved_word(yyscanner);
+ }
+
+ return token;
+}
+
+int ES2_keyword_ES3_reserved(TParseContext *context, int token)
+{
+ yyscan_t yyscanner = (yyscan_t)context->getScanner();
+
+ if (context->getShaderVersion() >= 300)
+ {
+ return reserved_word(yyscanner);
+ }
+
+ return token;
+}
+
+int ES3_reserved_ES3_1_keyword(TParseContext *context, int token)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)context->getScanner();
+ yyscan_t yyscanner = (yyscan_t)context->getScanner();
+
+ if (context->getShaderVersion() < 300)
+ {
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
+ return check_type(yyscanner);
+ }
+ else if (context->getShaderVersion() == 300)
+ {
+ return reserved_word(yyscanner);
+ }
+
+ return token;
+}
+
+int ES3_keyword(TParseContext *context, int token)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)context->getScanner();
+ yyscan_t yyscanner = (yyscan_t)context->getScanner();
+
+ // not a reserved word in GLSL ES 1.00, so could be used as an identifier/type name
+ if (context->getShaderVersion() < 300)
+ {
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
+ return check_type(yyscanner);
+ }
+
+ return token;
+}
+
+int ES2_reserved_ES3_1_keyword(TParseContext *context, int token)
+{
+ yyscan_t yyscanner = (yyscan_t)context->getScanner();
+
+ if (context->getShaderVersion() < 310)
+ {
+ return reserved_word(yyscanner);
+ }
+
+ return token;
+}
+
+int ES3_1_keyword(TParseContext *context, int token)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)context->getScanner();
+ yyscan_t yyscanner = (yyscan_t)context->getScanner();
+
+ // A keyword in GLSL ES 3.10.
+ if (context->getShaderVersion() >= 310)
+ {
+ return token;
+ }
+
+ // Otherwise can be used as an identifier/type name
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
+ return check_type(yyscanner);
+}
+
+int WEBGL_video_texture_extension(TParseContext *context, int token)
+{
+ // Available with WEBGL_video_texture_extension
+ if (context->isExtensionEnabled(TExtension::WEBGL_video_texture))
+ {
+ return token;
+ }
+
+ // Otherwise can be used as an identifier/type name
+ struct yyguts_t *yyg = (struct yyguts_t *)context->getScanner();
+ yyscan_t yyscanner = (yyscan_t)context->getScanner();
+
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
+ return check_type(yyscanner);
+}
+
+int ES2_extensions_ES3_keyword(TParseContext *context,
+ TExtension extension1,
+ TExtension extension2,
+ TExtension extension3,
+ int token)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)context->getScanner();
+ yyscan_t yyscanner = (yyscan_t)context->getScanner();
+
+ // A keyword in GLSL ES 3.00 or GLSL ES 1.00 with enabled extension.
+ if (is_extension_enabled_or_is_core(context, 100, extension1, 300))
+ {
+ return token;
+ }
+ else if (is_extension_enabled_or_is_core(context, 100, extension2, 300))
+ {
+ return token;
+ }
+ else if (is_extension_enabled_or_is_core(context, 100, extension3, 300))
+ {
+ return token;
+ }
+
+ // not a reserved word in GLSL ES 1.00, so could be used as an identifier/type name
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
+ return check_type(yyscanner);
+}
+
+int ES2_reserved_ES2_extension_ES3_keyword(TParseContext *context, TExtension extension, int token)
+{
+ yyscan_t yyscanner = (yyscan_t)context->getScanner();
+
+ // A keyword in GLSL ES 3.00 or GLSL ES 1.00 with enabled extension.
+ if (is_extension_enabled_or_is_core(context, 100, extension, 300))
+ {
+ return token;
+ }
+
+ // Reserved otherwise.
+ return reserved_word(yyscanner);
+}
+
+int ES3_extension(TParseContext *context, TExtension extension, int token)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)context->getScanner();
+ yyscan_t yyscanner = (yyscan_t)context->getScanner();
+
+ // a keyword word in GLSL ES 3.00 with enabled extension.
+ if (context->getShaderVersion() >= 300 && context->isExtensionEnabled(extension))
+ {
+ return token;
+ }
+
+ // Otherwise can be used as an identifier/type name
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
+ return check_type(yyscanner);
+}
+
+int ES3_reserved_ES3_1_extension_ES3_2_keyword(TParseContext *context,
+ TExtension extension,
+ int token)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)context->getScanner();
+ yyscan_t yyscanner = (yyscan_t)context->getScanner();
+
+ // a keyword in GLSL ES 3.10 with enabled extension
+ if (is_extension_enabled_or_is_core(context, 310, extension, 320))
+ {
+ return token;
+ }
+ // a reserved word in GLSL ES 3.00+
+ if (context->getShaderVersion() >= 300)
+ {
+ return reserved_word(yyscanner);
+ }
+
+ // Otherwise can be used as an identifier/type name
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
+ return check_type(yyscanner);
+}
+
+int ES3_reserved_ES3_extension(TParseContext *context, TExtension extension, int token)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)context->getScanner();
+ yyscan_t yyscanner = (yyscan_t)context->getScanner();
+
+ if (context->getShaderVersion() >= 300)
+ {
+ if (context->isExtensionEnabled(extension))
+ {
+ return token;
+ }
+ else
+ {
+ return reserved_word(yyscanner);
+ }
+ }
+
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
+ return check_type(yyscanner);
+}
+
+int ES3_reserved_ES3_extension_ES3_1_keyword(TParseContext *context,
+ TExtension extension,
+ int token)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)context->getScanner();
+ yyscan_t yyscanner = (yyscan_t)context->getScanner();
+
+ // A keyword in GLSL ES 3.00 with enabled extension or in GLSL ES 3.10
+ if (is_extension_enabled_or_is_core(context, 300, extension, 310))
+ {
+ return token;
+ }
+
+ if (context->getShaderVersion() == 300)
+ {
+ return reserved_word(yyscanner);
+ }
+
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
+ return check_type(yyscanner);
+}
+
+int ES3_reserved_ES3_extension_ES3_2_keyword(TParseContext *context,
+ TExtension extension,
+ int token)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)context->getScanner();
+ yyscan_t yyscanner = (yyscan_t)context->getScanner();
+
+ // A keyword in GLSL ES 3.00 with enabled extension or in GLSL ES 3.20
+ if (is_extension_enabled_or_is_core(context, 300, extension, 320))
+ {
+ return token;
+ }
+
+ if (context->getShaderVersion() == 300 || context->getShaderVersion() == 310)
+ {
+ return reserved_word(yyscanner);
+ }
+
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
+ return check_type(yyscanner);
+}
+
+static int ES3_1_reserved_ES3_1_extension_ES3_2_keyword(TParseContext *context,
+ TExtension extension,
+ int token)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)context->getScanner();
+ yyscan_t yyscanner = (yyscan_t)context->getScanner();
+
+ // A keyword in GLSL ES 3.20 or GLSL ES 3.10 with enabled extension.
+ if (is_extension_enabled_or_is_core(context, 310, extension, 320))
+ {
+ return token;
+ }
+
+ // A reserved word in GLSL ES 3.10
+ if (context->getShaderVersion() == 310)
+ {
+ return reserved_word(yyscanner);
+ }
+
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
+ return check_type(yyscanner);
+}
+
+static int ES3_1_reserved_ES3_1_extension_ES3_2_keyword_2(TParseContext *context,
+ TExtension extension1,
+ TExtension extension2,
+ int token1,
+ int token2)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)context->getScanner();
+ yyscan_t yyscanner = (yyscan_t)context->getScanner();
+
+ // A keyword in GLSL ES 3.20 or GLSL ES 3.10 with enabled extension.
+ if (is_extension_enabled_or_is_core(context, 310, extension1, 320))
+ {
+ return token1;
+ }
+ else if (is_extension_enabled_or_is_core(context, 310, extension2, 320))
+ {
+ return token2;
+ }
+
+ // A reserved word in GLSL ES 3.10
+ if (context->getShaderVersion() == 310)
+ {
+ return reserved_word(yyscanner);
+ }
+
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
+ return check_type(yyscanner);
+}
+
+static int ES3_and_3_1_reserved_ES3_1_extension_ES3_2_keyword_2(TParseContext *context,
+ TExtension extension1,
+ TExtension extension2,
+ int token1,
+ int token2)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)context->getScanner();
+ yyscan_t yyscanner = (yyscan_t)context->getScanner();
+
+ // A keyword in GLSL ES 3.20 or GLSL ES 3.10 with enabled extension.
+ if (is_extension_enabled_or_is_core(context, 310, extension1, 320))
+ {
+ return token1;
+ }
+ else if (is_extension_enabled_or_is_core(context, 310, extension2, 320))
+ {
+ return token2;
+ }
+
+ // A reserved word in GLSL ES 3.00 and 3.10
+ if (context->getShaderVersion() >= 300)
+ {
+ return reserved_word(yyscanner);
+ }
+
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
+ return check_type(yyscanner);
+}
+
+int uint_constant(TParseContext *context)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)context->getScanner();
+
+ if (context->getShaderVersion() < 300)
+ {
+ context->error(*yylloc, "Unsigned integers are unsupported prior to GLSL ES 3.00", yytext);
+ return 0;
+ }
+
+ if (!atoi_clamp(yytext, &(yylval->lex.u)))
+ yyextra->error(*yylloc, "Integer overflow", yytext);
+
+ return UINTCONSTANT;
+}
+
+int floatsuffix_check(TParseContext *context)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)context->getScanner();
+
+ if (context->getShaderVersion() < 300)
+ {
+ context->error(*yylloc, "Floating-point suffix unsupported prior to GLSL ES 3.00", yytext);
+ return 0;
+ }
+
+ std::string text = yytext;
+ text.resize(text.size() - 1);
+ if (!strtof_clamp(text, &(yylval->lex.f)))
+ yyextra->warning(*yylloc, "Float overflow", yytext);
+
+ return (FLOATCONSTANT);
+}
+
+void yyerror(YYLTYPE *lloc, TParseContext *context, void *scanner, const char *reason)
+{
+ context->error(*lloc, reason, yyget_text(scanner));
+}
+
+int int_constant(TParseContext *context)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)context->getScanner();
+
+ unsigned int u;
+ if (!atoi_clamp(yytext, &u))
+ {
+ if (context->getShaderVersion() >= 300)
+ yyextra->error(*yylloc, "Integer overflow", yytext);
+ else
+ yyextra->warning(*yylloc, "Integer overflow", yytext);
+ }
+ yylval->lex.i = static_cast<int>(u);
+ return INTCONSTANT;
+}
+
+int float_constant(yyscan_t yyscanner)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)yyscanner;
+
+ if (!strtof_clamp(yytext, &(yylval->lex.f)))
+ yyextra->warning(*yylloc, "Float overflow", yytext);
+ return FLOATCONSTANT;
+}
+
+int yuvcscstandardext_constant(TParseContext *context)
+{
+ struct yyguts_t *yyg = (struct yyguts_t *)context->getScanner();
+ yyscan_t yyscanner = (yyscan_t)context->getScanner();
+
+ // a reserved word in GLSL ES 3.00 with enabled extension, otherwise could be used as an
+ // identifier/type name
+ if (context->getShaderVersion() >= 300 &&
+ context->isExtensionEnabled(TExtension::EXT_YUV_target))
+ {
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
+ return YUVCSCSTANDARDEXTCONSTANT;
+ }
+
+ yylval->lex.string = AllocatePoolCharArray(yytext, yyleng);
+ return check_type(yyscanner);
+}
+
+int glslang_initialize(TParseContext *context)
+{
+ yyscan_t scanner = NULL;
+ if (yylex_init_extra(context, &scanner))
+ return 1;
+
+ context->setScanner(scanner);
+ return 0;
+}
+
+int glslang_finalize(TParseContext *context)
+{
+ yyscan_t scanner = context->getScanner();
+ if (scanner == NULL)
+ return 0;
+
+ context->setScanner(NULL);
+ yylex_destroy(scanner);
+
+ return 0;
+}
+
+int glslang_scan(size_t count,
+ const char *const string[],
+ const int length[],
+ TParseContext *context)
+{
+ yyrestart(NULL, context->getScanner());
+ yyset_column(0, context->getScanner());
+ yyset_lineno(1, context->getScanner());
+
+ // Initialize preprocessor.
+ angle::pp::Preprocessor *preprocessor = &context->getPreprocessor();
+
+ if (!preprocessor->init(count, string, length))
+ return 1;
+
+ // Define extension macros.
+ const TExtensionBehavior &extBehavior = context->extensionBehavior();
+ for (TExtensionBehavior::const_iterator iter = extBehavior.begin(); iter != extBehavior.end();
+ ++iter)
+ {
+ // OVR_multiview should not be defined for WebGL spec'ed shaders.
+ if (sh::IsWebGLBasedSpec(context->getShaderSpec()) &&
+ iter->first == TExtension::OVR_multiview)
+ {
+ continue;
+ }
+ preprocessor->predefineMacro(GetExtensionNameString(iter->first), 1);
+ }
+ if (context->getFragmentPrecisionHigh())
+ preprocessor->predefineMacro("GL_FRAGMENT_PRECISION_HIGH", 1);
+
+ preprocessor->setMaxTokenSize(sh::GetGlobalMaxTokenSize(context->getShaderSpec()));
+
+ return 0;
+}
diff --git a/gfx/angle/checkout/src/compiler/translator/glslang_tab_autogen.cpp b/gfx/angle/checkout/src/compiler/translator/glslang_tab_autogen.cpp
new file mode 100644
index 0000000000..233b571b79
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/glslang_tab_autogen.cpp
@@ -0,0 +1,4909 @@
+/* A Bison parser, made by GNU Bison 3.8.2. */
+
+/* Bison implementation for Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
+ Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+ simplifying the original so-called "semantic" parser. */
+
+/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
+ especially those whose name start with YY_ or yy_. They are
+ private implementation details that can be changed or removed. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+/* Identify Bison output, and Bison version. */
+#define YYBISON 30802
+
+/* Bison version string. */
+#define YYBISON_VERSION "3.8.2"
+
+/* Skeleton name. */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers. */
+#define YYPURE 2
+
+/* Push parsers. */
+#define YYPUSH 0
+
+/* Pull parsers. */
+#define YYPULL 1
+
+/* First part of user prologue. */
+
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_parser.py from glslang.y
+//
+// Copyright 2019 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.
+//
+// glslang.y:
+// Parser for the OpenGL shading language.
+
+// Ignore errors in auto-generated code.
+#if defined(__GNUC__)
+# pragma GCC diagnostic ignored "-Wunused-function"
+# pragma GCC diagnostic ignored "-Wunused-variable"
+# pragma GCC diagnostic ignored "-Wswitch-enum"
+#elif defined(_MSC_VER)
+# pragma warning(disable : 4065)
+# pragma warning(disable : 4189)
+# pragma warning(disable : 4244)
+# pragma warning(disable : 4505)
+# pragma warning(disable : 4701)
+# pragma warning(disable : 4702)
+#endif
+#if defined(__clang__)
+# pragma clang diagnostic ignored "-Wunreachable-code"
+# pragma clang diagnostic ignored "-Wunused-but-set-variable"
+#endif
+
+#include "GLSLANG/ShaderLang.h"
+#include "angle_gl.h"
+#include "compiler/translator/Declarator.h"
+#include "compiler/translator/ParseContext.h"
+#include "compiler/translator/SymbolTable.h"
+
+#define YYENABLE_NLS 0
+
+using namespace sh;
+
+#ifndef YY_CAST
+# ifdef __cplusplus
+# define YY_CAST(Type, Val) static_cast<Type>(Val)
+# define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast<Type>(Val)
+# else
+# define YY_CAST(Type, Val) ((Type)(Val))
+# define YY_REINTERPRET_CAST(Type, Val) ((Type)(Val))
+# endif
+#endif
+#ifndef YY_NULLPTR
+# if defined __cplusplus
+# if 201103L <= __cplusplus
+# define YY_NULLPTR nullptr
+# else
+# define YY_NULLPTR 0
+# endif
+# else
+# define YY_NULLPTR ((void *)0)
+# endif
+#endif
+
+#include "glslang_tab_autogen.h"
+/* Symbol kind. */
+enum yysymbol_kind_t
+{
+ YYSYMBOL_YYEMPTY = -2,
+ YYSYMBOL_YYEOF = 0, /* "end of file" */
+ YYSYMBOL_YYerror = 1, /* error */
+ YYSYMBOL_YYUNDEF = 2, /* "invalid token" */
+ YYSYMBOL_INVARIANT = 3, /* INVARIANT */
+ YYSYMBOL_PRECISE = 4, /* PRECISE */
+ YYSYMBOL_HIGH_PRECISION = 5, /* HIGH_PRECISION */
+ YYSYMBOL_MEDIUM_PRECISION = 6, /* MEDIUM_PRECISION */
+ YYSYMBOL_LOW_PRECISION = 7, /* LOW_PRECISION */
+ YYSYMBOL_PRECISION = 8, /* PRECISION */
+ YYSYMBOL_ATTRIBUTE = 9, /* ATTRIBUTE */
+ YYSYMBOL_CONST_QUAL = 10, /* CONST_QUAL */
+ YYSYMBOL_BOOL_TYPE = 11, /* BOOL_TYPE */
+ YYSYMBOL_FLOAT_TYPE = 12, /* FLOAT_TYPE */
+ YYSYMBOL_INT_TYPE = 13, /* INT_TYPE */
+ YYSYMBOL_UINT_TYPE = 14, /* UINT_TYPE */
+ YYSYMBOL_BREAK = 15, /* BREAK */
+ YYSYMBOL_CONTINUE = 16, /* CONTINUE */
+ YYSYMBOL_DO = 17, /* DO */
+ YYSYMBOL_ELSE = 18, /* ELSE */
+ YYSYMBOL_FOR = 19, /* FOR */
+ YYSYMBOL_IF = 20, /* IF */
+ YYSYMBOL_DISCARD = 21, /* DISCARD */
+ YYSYMBOL_RETURN = 22, /* RETURN */
+ YYSYMBOL_SWITCH = 23, /* SWITCH */
+ YYSYMBOL_CASE = 24, /* CASE */
+ YYSYMBOL_DEFAULT = 25, /* DEFAULT */
+ YYSYMBOL_BVEC2 = 26, /* BVEC2 */
+ YYSYMBOL_BVEC3 = 27, /* BVEC3 */
+ YYSYMBOL_BVEC4 = 28, /* BVEC4 */
+ YYSYMBOL_IVEC2 = 29, /* IVEC2 */
+ YYSYMBOL_IVEC3 = 30, /* IVEC3 */
+ YYSYMBOL_IVEC4 = 31, /* IVEC4 */
+ YYSYMBOL_VEC2 = 32, /* VEC2 */
+ YYSYMBOL_VEC3 = 33, /* VEC3 */
+ YYSYMBOL_VEC4 = 34, /* VEC4 */
+ YYSYMBOL_UVEC2 = 35, /* UVEC2 */
+ YYSYMBOL_UVEC3 = 36, /* UVEC3 */
+ YYSYMBOL_UVEC4 = 37, /* UVEC4 */
+ YYSYMBOL_MATRIX2 = 38, /* MATRIX2 */
+ YYSYMBOL_MATRIX3 = 39, /* MATRIX3 */
+ YYSYMBOL_MATRIX4 = 40, /* MATRIX4 */
+ YYSYMBOL_IN_QUAL = 41, /* IN_QUAL */
+ YYSYMBOL_OUT_QUAL = 42, /* OUT_QUAL */
+ YYSYMBOL_INOUT_QUAL = 43, /* INOUT_QUAL */
+ YYSYMBOL_UNIFORM = 44, /* UNIFORM */
+ YYSYMBOL_BUFFER = 45, /* BUFFER */
+ YYSYMBOL_VARYING = 46, /* VARYING */
+ YYSYMBOL_MATRIX2x3 = 47, /* MATRIX2x3 */
+ YYSYMBOL_MATRIX3x2 = 48, /* MATRIX3x2 */
+ YYSYMBOL_MATRIX2x4 = 49, /* MATRIX2x4 */
+ YYSYMBOL_MATRIX4x2 = 50, /* MATRIX4x2 */
+ YYSYMBOL_MATRIX3x4 = 51, /* MATRIX3x4 */
+ YYSYMBOL_MATRIX4x3 = 52, /* MATRIX4x3 */
+ YYSYMBOL_SAMPLE = 53, /* SAMPLE */
+ YYSYMBOL_CENTROID = 54, /* CENTROID */
+ YYSYMBOL_FLAT = 55, /* FLAT */
+ YYSYMBOL_SMOOTH = 56, /* SMOOTH */
+ YYSYMBOL_NOPERSPECTIVE = 57, /* NOPERSPECTIVE */
+ YYSYMBOL_PATCH = 58, /* PATCH */
+ YYSYMBOL_READONLY = 59, /* READONLY */
+ YYSYMBOL_WRITEONLY = 60, /* WRITEONLY */
+ YYSYMBOL_COHERENT = 61, /* COHERENT */
+ YYSYMBOL_RESTRICT = 62, /* RESTRICT */
+ YYSYMBOL_VOLATILE = 63, /* VOLATILE */
+ YYSYMBOL_SHARED = 64, /* SHARED */
+ YYSYMBOL_STRUCT = 65, /* STRUCT */
+ YYSYMBOL_VOID_TYPE = 66, /* VOID_TYPE */
+ YYSYMBOL_WHILE = 67, /* WHILE */
+ YYSYMBOL_SAMPLER2D = 68, /* SAMPLER2D */
+ YYSYMBOL_SAMPLERCUBE = 69, /* SAMPLERCUBE */
+ YYSYMBOL_SAMPLER_EXTERNAL_OES = 70, /* SAMPLER_EXTERNAL_OES */
+ YYSYMBOL_SAMPLER2DRECT = 71, /* SAMPLER2DRECT */
+ YYSYMBOL_SAMPLER2DARRAY = 72, /* SAMPLER2DARRAY */
+ YYSYMBOL_ISAMPLER2D = 73, /* ISAMPLER2D */
+ YYSYMBOL_ISAMPLER3D = 74, /* ISAMPLER3D */
+ YYSYMBOL_ISAMPLERCUBE = 75, /* ISAMPLERCUBE */
+ YYSYMBOL_ISAMPLER2DARRAY = 76, /* ISAMPLER2DARRAY */
+ YYSYMBOL_USAMPLER2D = 77, /* USAMPLER2D */
+ YYSYMBOL_USAMPLER3D = 78, /* USAMPLER3D */
+ YYSYMBOL_USAMPLERCUBE = 79, /* USAMPLERCUBE */
+ YYSYMBOL_USAMPLER2DARRAY = 80, /* USAMPLER2DARRAY */
+ YYSYMBOL_SAMPLER2DMS = 81, /* SAMPLER2DMS */
+ YYSYMBOL_ISAMPLER2DMS = 82, /* ISAMPLER2DMS */
+ YYSYMBOL_USAMPLER2DMS = 83, /* USAMPLER2DMS */
+ YYSYMBOL_SAMPLER2DMSARRAY = 84, /* SAMPLER2DMSARRAY */
+ YYSYMBOL_ISAMPLER2DMSARRAY = 85, /* ISAMPLER2DMSARRAY */
+ YYSYMBOL_USAMPLER2DMSARRAY = 86, /* USAMPLER2DMSARRAY */
+ YYSYMBOL_SAMPLER3D = 87, /* SAMPLER3D */
+ YYSYMBOL_SAMPLER3DRECT = 88, /* SAMPLER3DRECT */
+ YYSYMBOL_SAMPLER2DSHADOW = 89, /* SAMPLER2DSHADOW */
+ YYSYMBOL_SAMPLERCUBESHADOW = 90, /* SAMPLERCUBESHADOW */
+ YYSYMBOL_SAMPLER2DARRAYSHADOW = 91, /* SAMPLER2DARRAYSHADOW */
+ YYSYMBOL_SAMPLERVIDEOWEBGL = 92, /* SAMPLERVIDEOWEBGL */
+ YYSYMBOL_SAMPLERCUBEARRAYOES = 93, /* SAMPLERCUBEARRAYOES */
+ YYSYMBOL_SAMPLERCUBEARRAYSHADOWOES = 94, /* SAMPLERCUBEARRAYSHADOWOES */
+ YYSYMBOL_ISAMPLERCUBEARRAYOES = 95, /* ISAMPLERCUBEARRAYOES */
+ YYSYMBOL_USAMPLERCUBEARRAYOES = 96, /* USAMPLERCUBEARRAYOES */
+ YYSYMBOL_SAMPLERCUBEARRAYEXT = 97, /* SAMPLERCUBEARRAYEXT */
+ YYSYMBOL_SAMPLERCUBEARRAYSHADOWEXT = 98, /* SAMPLERCUBEARRAYSHADOWEXT */
+ YYSYMBOL_ISAMPLERCUBEARRAYEXT = 99, /* ISAMPLERCUBEARRAYEXT */
+ YYSYMBOL_USAMPLERCUBEARRAYEXT = 100, /* USAMPLERCUBEARRAYEXT */
+ YYSYMBOL_SAMPLERBUFFER = 101, /* SAMPLERBUFFER */
+ YYSYMBOL_ISAMPLERBUFFER = 102, /* ISAMPLERBUFFER */
+ YYSYMBOL_USAMPLERBUFFER = 103, /* USAMPLERBUFFER */
+ YYSYMBOL_SAMPLEREXTERNAL2DY2YEXT = 104, /* SAMPLEREXTERNAL2DY2YEXT */
+ YYSYMBOL_IMAGE2D = 105, /* IMAGE2D */
+ YYSYMBOL_IIMAGE2D = 106, /* IIMAGE2D */
+ YYSYMBOL_UIMAGE2D = 107, /* UIMAGE2D */
+ YYSYMBOL_IMAGE3D = 108, /* IMAGE3D */
+ YYSYMBOL_IIMAGE3D = 109, /* IIMAGE3D */
+ YYSYMBOL_UIMAGE3D = 110, /* UIMAGE3D */
+ YYSYMBOL_IMAGE2DARRAY = 111, /* IMAGE2DARRAY */
+ YYSYMBOL_IIMAGE2DARRAY = 112, /* IIMAGE2DARRAY */
+ YYSYMBOL_UIMAGE2DARRAY = 113, /* UIMAGE2DARRAY */
+ YYSYMBOL_IMAGECUBE = 114, /* IMAGECUBE */
+ YYSYMBOL_IIMAGECUBE = 115, /* IIMAGECUBE */
+ YYSYMBOL_UIMAGECUBE = 116, /* UIMAGECUBE */
+ YYSYMBOL_IMAGECUBEARRAYOES = 117, /* IMAGECUBEARRAYOES */
+ YYSYMBOL_IIMAGECUBEARRAYOES = 118, /* IIMAGECUBEARRAYOES */
+ YYSYMBOL_UIMAGECUBEARRAYOES = 119, /* UIMAGECUBEARRAYOES */
+ YYSYMBOL_IMAGECUBEARRAYEXT = 120, /* IMAGECUBEARRAYEXT */
+ YYSYMBOL_IIMAGECUBEARRAYEXT = 121, /* IIMAGECUBEARRAYEXT */
+ YYSYMBOL_UIMAGECUBEARRAYEXT = 122, /* UIMAGECUBEARRAYEXT */
+ YYSYMBOL_IMAGEBUFFER = 123, /* IMAGEBUFFER */
+ YYSYMBOL_IIMAGEBUFFER = 124, /* IIMAGEBUFFER */
+ YYSYMBOL_UIMAGEBUFFER = 125, /* UIMAGEBUFFER */
+ YYSYMBOL_ATOMICUINT = 126, /* ATOMICUINT */
+ YYSYMBOL_PIXELLOCALANGLE = 127, /* PIXELLOCALANGLE */
+ YYSYMBOL_IPIXELLOCALANGLE = 128, /* IPIXELLOCALANGLE */
+ YYSYMBOL_UPIXELLOCALANGLE = 129, /* UPIXELLOCALANGLE */
+ YYSYMBOL_LAYOUT = 130, /* LAYOUT */
+ YYSYMBOL_YUVCSCSTANDARDEXT = 131, /* YUVCSCSTANDARDEXT */
+ YYSYMBOL_YUVCSCSTANDARDEXTCONSTANT = 132, /* YUVCSCSTANDARDEXTCONSTANT */
+ YYSYMBOL_IDENTIFIER = 133, /* IDENTIFIER */
+ YYSYMBOL_TYPE_NAME = 134, /* TYPE_NAME */
+ YYSYMBOL_FLOATCONSTANT = 135, /* FLOATCONSTANT */
+ YYSYMBOL_INTCONSTANT = 136, /* INTCONSTANT */
+ YYSYMBOL_UINTCONSTANT = 137, /* UINTCONSTANT */
+ YYSYMBOL_BOOLCONSTANT = 138, /* BOOLCONSTANT */
+ YYSYMBOL_FIELD_SELECTION = 139, /* FIELD_SELECTION */
+ YYSYMBOL_LEFT_OP = 140, /* LEFT_OP */
+ YYSYMBOL_RIGHT_OP = 141, /* RIGHT_OP */
+ YYSYMBOL_INC_OP = 142, /* INC_OP */
+ YYSYMBOL_DEC_OP = 143, /* DEC_OP */
+ YYSYMBOL_LE_OP = 144, /* LE_OP */
+ YYSYMBOL_GE_OP = 145, /* GE_OP */
+ YYSYMBOL_EQ_OP = 146, /* EQ_OP */
+ YYSYMBOL_NE_OP = 147, /* NE_OP */
+ YYSYMBOL_AND_OP = 148, /* AND_OP */
+ YYSYMBOL_OR_OP = 149, /* OR_OP */
+ YYSYMBOL_XOR_OP = 150, /* XOR_OP */
+ YYSYMBOL_MUL_ASSIGN = 151, /* MUL_ASSIGN */
+ YYSYMBOL_DIV_ASSIGN = 152, /* DIV_ASSIGN */
+ YYSYMBOL_ADD_ASSIGN = 153, /* ADD_ASSIGN */
+ YYSYMBOL_MOD_ASSIGN = 154, /* MOD_ASSIGN */
+ YYSYMBOL_LEFT_ASSIGN = 155, /* LEFT_ASSIGN */
+ YYSYMBOL_RIGHT_ASSIGN = 156, /* RIGHT_ASSIGN */
+ YYSYMBOL_AND_ASSIGN = 157, /* AND_ASSIGN */
+ YYSYMBOL_XOR_ASSIGN = 158, /* XOR_ASSIGN */
+ YYSYMBOL_OR_ASSIGN = 159, /* OR_ASSIGN */
+ YYSYMBOL_SUB_ASSIGN = 160, /* SUB_ASSIGN */
+ YYSYMBOL_LEFT_PAREN = 161, /* LEFT_PAREN */
+ YYSYMBOL_RIGHT_PAREN = 162, /* RIGHT_PAREN */
+ YYSYMBOL_LEFT_BRACKET = 163, /* LEFT_BRACKET */
+ YYSYMBOL_RIGHT_BRACKET = 164, /* RIGHT_BRACKET */
+ YYSYMBOL_LEFT_BRACE = 165, /* LEFT_BRACE */
+ YYSYMBOL_RIGHT_BRACE = 166, /* RIGHT_BRACE */
+ YYSYMBOL_DOT = 167, /* DOT */
+ YYSYMBOL_COMMA = 168, /* COMMA */
+ YYSYMBOL_COLON = 169, /* COLON */
+ YYSYMBOL_EQUAL = 170, /* EQUAL */
+ YYSYMBOL_SEMICOLON = 171, /* SEMICOLON */
+ YYSYMBOL_BANG = 172, /* BANG */
+ YYSYMBOL_DASH = 173, /* DASH */
+ YYSYMBOL_TILDE = 174, /* TILDE */
+ YYSYMBOL_PLUS = 175, /* PLUS */
+ YYSYMBOL_STAR = 176, /* STAR */
+ YYSYMBOL_SLASH = 177, /* SLASH */
+ YYSYMBOL_PERCENT = 178, /* PERCENT */
+ YYSYMBOL_LEFT_ANGLE = 179, /* LEFT_ANGLE */
+ YYSYMBOL_RIGHT_ANGLE = 180, /* RIGHT_ANGLE */
+ YYSYMBOL_VERTICAL_BAR = 181, /* VERTICAL_BAR */
+ YYSYMBOL_CARET = 182, /* CARET */
+ YYSYMBOL_AMPERSAND = 183, /* AMPERSAND */
+ YYSYMBOL_QUESTION = 184, /* QUESTION */
+ YYSYMBOL_YYACCEPT = 185, /* $accept */
+ YYSYMBOL_identifier = 186, /* identifier */
+ YYSYMBOL_variable_identifier = 187, /* variable_identifier */
+ YYSYMBOL_primary_expression = 188, /* primary_expression */
+ YYSYMBOL_postfix_expression = 189, /* postfix_expression */
+ YYSYMBOL_integer_expression = 190, /* integer_expression */
+ YYSYMBOL_function_call = 191, /* function_call */
+ YYSYMBOL_function_call_or_method = 192, /* function_call_or_method */
+ YYSYMBOL_function_call_generic = 193, /* function_call_generic */
+ YYSYMBOL_function_call_header_no_parameters = 194, /* function_call_header_no_parameters */
+ YYSYMBOL_function_call_header_with_parameters = 195, /* function_call_header_with_parameters */
+ YYSYMBOL_function_call_header = 196, /* function_call_header */
+ YYSYMBOL_function_identifier = 197, /* function_identifier */
+ YYSYMBOL_unary_expression = 198, /* unary_expression */
+ YYSYMBOL_unary_operator = 199, /* unary_operator */
+ YYSYMBOL_multiplicative_expression = 200, /* multiplicative_expression */
+ YYSYMBOL_additive_expression = 201, /* additive_expression */
+ YYSYMBOL_shift_expression = 202, /* shift_expression */
+ YYSYMBOL_relational_expression = 203, /* relational_expression */
+ YYSYMBOL_equality_expression = 204, /* equality_expression */
+ YYSYMBOL_and_expression = 205, /* and_expression */
+ YYSYMBOL_exclusive_or_expression = 206, /* exclusive_or_expression */
+ YYSYMBOL_inclusive_or_expression = 207, /* inclusive_or_expression */
+ YYSYMBOL_logical_and_expression = 208, /* logical_and_expression */
+ YYSYMBOL_logical_xor_expression = 209, /* logical_xor_expression */
+ YYSYMBOL_logical_or_expression = 210, /* logical_or_expression */
+ YYSYMBOL_conditional_expression = 211, /* conditional_expression */
+ YYSYMBOL_assignment_expression = 212, /* assignment_expression */
+ YYSYMBOL_assignment_operator = 213, /* assignment_operator */
+ YYSYMBOL_expression = 214, /* expression */
+ YYSYMBOL_constant_expression = 215, /* constant_expression */
+ YYSYMBOL_enter_struct = 216, /* enter_struct */
+ YYSYMBOL_declaration = 217, /* declaration */
+ YYSYMBOL_function_prototype = 218, /* function_prototype */
+ YYSYMBOL_function_declarator = 219, /* function_declarator */
+ YYSYMBOL_function_header_with_parameters = 220, /* function_header_with_parameters */
+ YYSYMBOL_function_header = 221, /* function_header */
+ YYSYMBOL_parameter_declarator = 222, /* parameter_declarator */
+ YYSYMBOL_parameter_declaration = 223, /* parameter_declaration */
+ YYSYMBOL_parameter_type_specifier = 224, /* parameter_type_specifier */
+ YYSYMBOL_init_declarator_list = 225, /* init_declarator_list */
+ YYSYMBOL_single_declaration = 226, /* single_declaration */
+ YYSYMBOL_fully_specified_type = 227, /* fully_specified_type */
+ YYSYMBOL_interpolation_qualifier = 228, /* interpolation_qualifier */
+ YYSYMBOL_type_qualifier = 229, /* type_qualifier */
+ YYSYMBOL_invariant_qualifier = 230, /* invariant_qualifier */
+ YYSYMBOL_precise_qualifier = 231, /* precise_qualifier */
+ YYSYMBOL_single_type_qualifier = 232, /* single_type_qualifier */
+ YYSYMBOL_storage_qualifier = 233, /* storage_qualifier */
+ YYSYMBOL_type_specifier = 234, /* type_specifier */
+ YYSYMBOL_precision_qualifier = 235, /* precision_qualifier */
+ YYSYMBOL_layout_qualifier = 236, /* layout_qualifier */
+ YYSYMBOL_layout_qualifier_id_list = 237, /* layout_qualifier_id_list */
+ YYSYMBOL_layout_qualifier_id = 238, /* layout_qualifier_id */
+ YYSYMBOL_type_specifier_no_prec = 239, /* type_specifier_no_prec */
+ YYSYMBOL_array_specifier = 240, /* array_specifier */
+ YYSYMBOL_type_specifier_nonarray = 241, /* type_specifier_nonarray */
+ YYSYMBOL_struct_specifier = 242, /* struct_specifier */
+ YYSYMBOL_243_1 = 243, /* $@1 */
+ YYSYMBOL_244_2 = 244, /* $@2 */
+ YYSYMBOL_struct_declaration_list = 245, /* struct_declaration_list */
+ YYSYMBOL_struct_declaration = 246, /* struct_declaration */
+ YYSYMBOL_struct_declarator_list = 247, /* struct_declarator_list */
+ YYSYMBOL_struct_declarator = 248, /* struct_declarator */
+ YYSYMBOL_initializer = 249, /* initializer */
+ YYSYMBOL_declaration_statement = 250, /* declaration_statement */
+ YYSYMBOL_statement = 251, /* statement */
+ YYSYMBOL_simple_statement = 252, /* simple_statement */
+ YYSYMBOL_compound_statement_with_scope = 253, /* compound_statement_with_scope */
+ YYSYMBOL_254_3 = 254, /* $@3 */
+ YYSYMBOL_255_4 = 255, /* $@4 */
+ YYSYMBOL_statement_no_new_scope = 256, /* statement_no_new_scope */
+ YYSYMBOL_statement_with_scope = 257, /* statement_with_scope */
+ YYSYMBOL_258_5 = 258, /* $@5 */
+ YYSYMBOL_259_6 = 259, /* $@6 */
+ YYSYMBOL_compound_statement_no_new_scope = 260, /* compound_statement_no_new_scope */
+ YYSYMBOL_statement_list = 261, /* statement_list */
+ YYSYMBOL_expression_statement = 262, /* expression_statement */
+ YYSYMBOL_selection_statement = 263, /* selection_statement */
+ YYSYMBOL_selection_rest_statement = 264, /* selection_rest_statement */
+ YYSYMBOL_switch_statement = 265, /* switch_statement */
+ YYSYMBOL_266_7 = 266, /* $@7 */
+ YYSYMBOL_case_label = 267, /* case_label */
+ YYSYMBOL_condition = 268, /* condition */
+ YYSYMBOL_iteration_statement = 269, /* iteration_statement */
+ YYSYMBOL_270_8 = 270, /* $@8 */
+ YYSYMBOL_271_9 = 271, /* $@9 */
+ YYSYMBOL_272_10 = 272, /* $@10 */
+ YYSYMBOL_for_init_statement = 273, /* for_init_statement */
+ YYSYMBOL_conditionopt = 274, /* conditionopt */
+ YYSYMBOL_for_rest_statement = 275, /* for_rest_statement */
+ YYSYMBOL_jump_statement = 276, /* jump_statement */
+ YYSYMBOL_translation_unit = 277, /* translation_unit */
+ YYSYMBOL_external_declaration = 278, /* external_declaration */
+ YYSYMBOL_function_definition = 279, /* function_definition */
+ YYSYMBOL_280_11 = 280 /* $@11 */
+};
+typedef enum yysymbol_kind_t yysymbol_kind_t;
+
+/* Second part of user prologue. */
+
+extern int yylex(YYSTYPE *yylval, YYLTYPE *yylloc, void *yyscanner);
+extern void yyerror(YYLTYPE *yylloc, TParseContext *context, void *scanner, const char *reason);
+
+#define YYLLOC_DEFAULT(Current, Rhs, N) \
+ do \
+ { \
+ if (N) \
+ { \
+ (Current).first_file = YYRHSLOC(Rhs, 1).first_file; \
+ (Current).first_line = YYRHSLOC(Rhs, 1).first_line; \
+ (Current).last_file = YYRHSLOC(Rhs, N).last_file; \
+ (Current).last_line = YYRHSLOC(Rhs, N).last_line; \
+ } \
+ else \
+ { \
+ (Current).first_file = YYRHSLOC(Rhs, 0).last_file; \
+ (Current).first_line = YYRHSLOC(Rhs, 0).last_line; \
+ (Current).last_file = YYRHSLOC(Rhs, 0).last_file; \
+ (Current).last_line = YYRHSLOC(Rhs, 0).last_line; \
+ } \
+ } while (0)
+
+#define VERTEX_ONLY(S, L) \
+ do \
+ { \
+ if (context->getShaderType() != GL_VERTEX_SHADER) \
+ { \
+ context->error(L, " supported in vertex shaders only", S); \
+ } \
+ } while (0)
+
+#define COMPUTE_ONLY(S, L) \
+ do \
+ { \
+ if (context->getShaderType() != GL_COMPUTE_SHADER) \
+ { \
+ context->error(L, " supported in compute shaders only", S); \
+ } \
+ } while (0)
+
+#define ES2_ONLY(S, L) \
+ do \
+ { \
+ if (context->getShaderVersion() != 100) \
+ { \
+ context->error(L, " supported in GLSL ES 1.00 only", S); \
+ } \
+ } while (0)
+
+#define ES3_OR_NEWER(TOKEN, LINE, REASON) \
+ do \
+ { \
+ if (context->getShaderVersion() < 300) \
+ { \
+ context->error(LINE, REASON " supported in GLSL ES 3.00 and above only", TOKEN); \
+ } \
+ } while (0)
+
+#define ES3_1_OR_NEWER(TOKEN, LINE, REASON) \
+ do \
+ { \
+ if (context->getShaderVersion() < 310) \
+ { \
+ context->error(LINE, REASON " supported in GLSL ES 3.10 and above only", TOKEN); \
+ } \
+ } while (0)
+
+#ifdef short
+# undef short
+#endif
+
+/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure
+ <limits.h> and (if available) <stdint.h> are included
+ so that the code can choose integer types of a good width. */
+
+#ifndef __PTRDIFF_MAX__
+# include <limits.h> /* INFRINGES ON USER NAME SPACE */
+# if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
+# include <stdint.h> /* INFRINGES ON USER NAME SPACE */
+# define YY_STDINT_H
+# endif
+#endif
+
+/* Narrow types that promote to a signed type and that can represent a
+ signed or unsigned integer of at least N bits. In tables they can
+ save space and decrease cache pressure. Promoting to a signed type
+ helps avoid bugs in integer arithmetic. */
+
+#ifdef __INT_LEAST8_MAX__
+typedef __INT_LEAST8_TYPE__ yytype_int8;
+#elif defined YY_STDINT_H
+typedef int_least8_t yytype_int8;
+#else
+typedef signed char yytype_int8;
+#endif
+
+#ifdef __INT_LEAST16_MAX__
+typedef __INT_LEAST16_TYPE__ yytype_int16;
+#elif defined YY_STDINT_H
+typedef int_least16_t yytype_int16;
+#else
+typedef short yytype_int16;
+#endif
+
+/* Work around bug in HP-UX 11.23, which defines these macros
+ incorrectly for preprocessor constants. This workaround can likely
+ be removed in 2023, as HPE has promised support for HP-UX 11.23
+ (aka HP-UX 11i v2) only through the end of 2022; see Table 2 of
+ <https://h20195.www2.hpe.com/V2/getpdf.aspx/4AA4-7673ENW.pdf>. */
+#ifdef __hpux
+# undef UINT_LEAST8_MAX
+# undef UINT_LEAST16_MAX
+# define UINT_LEAST8_MAX 255
+# define UINT_LEAST16_MAX 65535
+#endif
+
+#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__
+typedef __UINT_LEAST8_TYPE__ yytype_uint8;
+#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H && UINT_LEAST8_MAX <= INT_MAX)
+typedef uint_least8_t yytype_uint8;
+#elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX
+typedef unsigned char yytype_uint8;
+#else
+typedef short yytype_uint8;
+#endif
+
+#if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__
+typedef __UINT_LEAST16_TYPE__ yytype_uint16;
+#elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H && UINT_LEAST16_MAX <= INT_MAX)
+typedef uint_least16_t yytype_uint16;
+#elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX
+typedef unsigned short yytype_uint16;
+#else
+typedef int yytype_uint16;
+#endif
+
+#ifndef YYPTRDIFF_T
+# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__
+# define YYPTRDIFF_T __PTRDIFF_TYPE__
+# define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__
+# elif defined PTRDIFF_MAX
+# ifndef ptrdiff_t
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# endif
+# define YYPTRDIFF_T ptrdiff_t
+# define YYPTRDIFF_MAXIMUM PTRDIFF_MAX
+# else
+# define YYPTRDIFF_T long
+# define YYPTRDIFF_MAXIMUM LONG_MAX
+# endif
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+# define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+# define YYSIZE_T size_t
+# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# else
+# define YYSIZE_T unsigned
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM \
+ YY_CAST(YYPTRDIFF_T, (YYPTRDIFF_MAXIMUM < YY_CAST(YYSIZE_T, -1) ? YYPTRDIFF_MAXIMUM \
+ : YY_CAST(YYSIZE_T, -1)))
+
+#define YYSIZEOF(X) YY_CAST(YYPTRDIFF_T, sizeof(X))
+
+/* Stored state numbers (used for stacks). */
+typedef yytype_int16 yy_state_t;
+
+/* State numbers in computations. */
+typedef int yy_state_fast_t;
+
+#ifndef YY_
+# if defined YYENABLE_NLS && YYENABLE_NLS
+# if ENABLE_NLS
+# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+# define YY_(Msgid) dgettext("bison-runtime", Msgid)
+# endif
+# endif
+# ifndef YY_
+# define YY_(Msgid) Msgid
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE_PURE
+# if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__)
+# define YY_ATTRIBUTE_PURE __attribute__((__pure__))
+# else
+# define YY_ATTRIBUTE_PURE
+# endif
+#endif
+
+#ifndef YY_ATTRIBUTE_UNUSED
+# if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__)
+# define YY_ATTRIBUTE_UNUSED __attribute__((__unused__))
+# else
+# define YY_ATTRIBUTE_UNUSED
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E. */
+#if !defined lint || defined __GNUC__
+# define YY_USE(E) ((void)(E))
+#else
+# define YY_USE(E) /* empty */
+#endif
+
+/* Suppress an incorrect diagnostic about yylval being uninitialized. */
+#if defined __GNUC__ && !defined __ICC && 406 <= __GNUC__ * 100 + __GNUC_MINOR__
+# if __GNUC__ * 100 + __GNUC_MINOR__ < 407
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+ _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wuninitialized\"")
+# else
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+ _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wuninitialized\"") \
+ _Pragma("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
+# endif
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END _Pragma("GCC diagnostic pop")
+#else
+# define YY_INITIAL_VALUE(Value) Value
+#endif
+#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END
+#endif
+#ifndef YY_INITIAL_VALUE
+# define YY_INITIAL_VALUE(Value) /* Nothing. */
+#endif
+
+#if defined __cplusplus && defined __GNUC__ && !defined __ICC && 6 <= __GNUC__
+# define YY_IGNORE_USELESS_CAST_BEGIN \
+ _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wuseless-cast\"")
+# define YY_IGNORE_USELESS_CAST_END _Pragma("GCC diagnostic pop")
+#endif
+#ifndef YY_IGNORE_USELESS_CAST_BEGIN
+# define YY_IGNORE_USELESS_CAST_BEGIN
+# define YY_IGNORE_USELESS_CAST_END
+#endif
+
+#define YY_ASSERT(E) ((void)(0 && (E)))
+
+#if !defined yyoverflow
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# ifdef YYSTACK_USE_ALLOCA
+# if YYSTACK_USE_ALLOCA
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# elif defined __BUILTIN_VA_ARG_INCR
+# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+# elif defined _AIX
+# define YYSTACK_ALLOC __alloca
+# elif defined _MSC_VER
+# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+# define alloca _alloca
+# else
+# define YYSTACK_ALLOC alloca
+# if !defined _ALLOCA_H && !defined EXIT_SUCCESS
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+/* Use EXIT_SUCCESS as a witness for stdlib.h. */
+# ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
+# endif
+# endif
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+/* Pacify GCC's 'empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) \
+ do \
+ { /* empty */ \
+ ; \
+ } while (0)
+# ifndef YYSTACK_ALLOC_MAXIMUM
+/* The OS might guarantee only one guard page at the bottom of the stack,
+ and a page size can be as small as 4096 bytes. So we cannot safely
+ invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
+ to allow for a few compiler-allocated temporary stack slots. */
+# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+# endif
+# else
+# define YYSTACK_ALLOC YYMALLOC
+# define YYSTACK_FREE YYFREE
+# ifndef YYSTACK_ALLOC_MAXIMUM
+# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+# endif
+# if (defined __cplusplus && !defined EXIT_SUCCESS && \
+ !((defined YYMALLOC || defined malloc) && (defined YYFREE || defined free)))
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
+# endif
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# if !defined malloc && !defined EXIT_SUCCESS
+void *malloc(YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# ifndef YYFREE
+# define YYFREE free
+# if !defined free && !defined EXIT_SUCCESS
+void free(void *); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# endif
+#endif /* !defined yyoverflow */
+
+#if (!defined yyoverflow && \
+ (!defined __cplusplus || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL && \
+ defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ yy_state_t yyss_alloc;
+ YYSTYPE yyvs_alloc;
+ YYLTYPE yyls_alloc;
+};
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAXIMUM (YYSIZEOF(union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# define YYSTACK_BYTES(N) \
+ ((N) * (YYSIZEOF(yy_state_t) + YYSIZEOF(YYSTYPE) + YYSIZEOF(YYLTYPE)) + \
+ 2 * YYSTACK_GAP_MAXIMUM)
+
+# define YYCOPY_NEEDED 1
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
+ do \
+ { \
+ YYPTRDIFF_T yynewbytes; \
+ YYCOPY(&yyptr->Stack_alloc, Stack, yysize); \
+ Stack = &yyptr->Stack_alloc; \
+ yynewbytes = yystacksize * YYSIZEOF(*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / YYSIZEOF(*yyptr); \
+ } while (0)
+
+#endif
+
+#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
+/* Copy COUNT objects from SRC to DST. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if defined __GNUC__ && 1 < __GNUC__
+# define YYCOPY(Dst, Src, Count) \
+ __builtin_memcpy(Dst, Src, YY_CAST(YYSIZE_T, (Count)) * sizeof(*(Src)))
+# else
+# define YYCOPY(Dst, Src, Count) \
+ do \
+ { \
+ YYPTRDIFF_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (Dst)[yyi] = (Src)[yyi]; \
+ } while (0)
+# endif
+# endif
+#endif /* !YYCOPY_NEEDED */
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 167
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST 3566
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 185
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 96
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 329
+/* YYNSTATES -- Number of states. */
+#define YYNSTATES 453
+
+/* YYMAXUTOK -- Last valid token kind. */
+#define YYMAXUTOK 439
+
+/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
+ as returned by yylex, with out-of-bounds checking. */
+#define YYTRANSLATE(YYX) \
+ (0 <= (YYX) && (YYX) <= YYMAXUTOK ? YY_CAST(yysymbol_kind_t, yytranslate[YYX]) \
+ : YYSYMBOL_YYUNDEF)
+
+/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
+ as returned by yylex. */
+static const yytype_uint8 yytranslate[] = {
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 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, 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, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
+ 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
+ 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
+ 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
+ 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162,
+ 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181,
+ 182, 183, 184};
+
+#if YYDEBUG
+/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
+static const yytype_int16 yyrline[] = {
+ 0, 259, 259, 260, 263, 270, 273, 278, 283, 288, 293, 302, 308, 311, 314, 317,
+ 320, 323, 329, 336, 342, 345, 353, 356, 362, 365, 371, 375, 382, 390, 393, 396,
+ 402, 405, 408, 411, 418, 419, 420, 421, 429, 430, 433, 436, 443, 444, 447, 453,
+ 454, 458, 465, 466, 469, 472, 475, 481, 482, 485, 491, 492, 499, 500, 507, 508,
+ 515, 516, 522, 523, 529, 530, 536, 537, 543, 544, 550, 551, 552, 553, 557, 558,
+ 559, 563, 567, 571, 575, 582, 585, 591, 598, 605, 608, 611, 615, 619, 623, 627,
+ 631, 638, 645, 648, 655, 668, 691, 701, 704, 710, 714, 718, 722, 729, 736, 739,
+ 743, 747, 752, 759, 763, 767, 771, 776, 783, 787, 793, 796, 799, 809, 813, 820,
+ 826, 832, 836, 840, 843, 846, 850, 858, 863, 867, 870, 873, 876, 879, 883, 891,
+ 894, 898, 901, 904, 907, 910, 913, 917, 924, 931, 934, 937, 943, 950, 953, 959,
+ 962, 965, 968, 974, 977, 984, 989, 996, 1001, 1012, 1015, 1018, 1021, 1024, 1027, 1031,
+ 1035, 1039, 1043, 1047, 1051, 1055, 1059, 1063, 1067, 1071, 1075, 1079, 1083, 1087, 1091, 1095,
+ 1099, 1103, 1107, 1111, 1118, 1121, 1124, 1127, 1130, 1133, 1136, 1144, 1152, 1162, 1165, 1168,
+ 1171, 1174, 1177, 1180, 1188, 1196, 1206, 1209, 1212, 1215, 1218, 1221, 1224, 1232, 1240, 1250,
+ 1253, 1256, 1259, 1267, 1275, 1282, 1292, 1299, 1306, 1309, 1312, 1315, 1318, 1321, 1324, 1327,
+ 1330, 1333, 1336, 1339, 1342, 1350, 1358, 1366, 1374, 1382, 1390, 1400, 1410, 1420, 1423, 1430,
+ 1437, 1444, 1447, 1455, 1455, 1458, 1458, 1464, 1467, 1473, 1476, 1483, 1487, 1493, 1496, 1502,
+ 1506, 1510, 1511, 1517, 1518, 1519, 1520, 1521, 1522, 1523, 1527, 1531, 1531, 1531, 1538, 1539,
+ 1543, 1543, 1544, 1544, 1549, 1553, 1560, 1564, 1571, 1572, 1576, 1582, 1586, 1595, 1595, 1602,
+ 1605, 1611, 1615, 1621, 1621, 1626, 1626, 1630, 1630, 1638, 1641, 1647, 1650, 1656, 1660, 1667,
+ 1670, 1673, 1676, 1679, 1687, 1693, 1699, 1702, 1708, 1708};
+#endif
+
+/** Accessing symbol of state STATE. */
+#define YY_ACCESSING_SYMBOL(State) YY_CAST(yysymbol_kind_t, yystos[State])
+
+#if YYDEBUG || 0
+/* The user-facing name of the symbol whose (internal) number is
+ YYSYMBOL. No bounds checking. */
+static const char *yysymbol_name(yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED;
+
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] = {"\"end of file\"",
+ "error",
+ "\"invalid token\"",
+ "INVARIANT",
+ "PRECISE",
+ "HIGH_PRECISION",
+ "MEDIUM_PRECISION",
+ "LOW_PRECISION",
+ "PRECISION",
+ "ATTRIBUTE",
+ "CONST_QUAL",
+ "BOOL_TYPE",
+ "FLOAT_TYPE",
+ "INT_TYPE",
+ "UINT_TYPE",
+ "BREAK",
+ "CONTINUE",
+ "DO",
+ "ELSE",
+ "FOR",
+ "IF",
+ "DISCARD",
+ "RETURN",
+ "SWITCH",
+ "CASE",
+ "DEFAULT",
+ "BVEC2",
+ "BVEC3",
+ "BVEC4",
+ "IVEC2",
+ "IVEC3",
+ "IVEC4",
+ "VEC2",
+ "VEC3",
+ "VEC4",
+ "UVEC2",
+ "UVEC3",
+ "UVEC4",
+ "MATRIX2",
+ "MATRIX3",
+ "MATRIX4",
+ "IN_QUAL",
+ "OUT_QUAL",
+ "INOUT_QUAL",
+ "UNIFORM",
+ "BUFFER",
+ "VARYING",
+ "MATRIX2x3",
+ "MATRIX3x2",
+ "MATRIX2x4",
+ "MATRIX4x2",
+ "MATRIX3x4",
+ "MATRIX4x3",
+ "SAMPLE",
+ "CENTROID",
+ "FLAT",
+ "SMOOTH",
+ "NOPERSPECTIVE",
+ "PATCH",
+ "READONLY",
+ "WRITEONLY",
+ "COHERENT",
+ "RESTRICT",
+ "VOLATILE",
+ "SHARED",
+ "STRUCT",
+ "VOID_TYPE",
+ "WHILE",
+ "SAMPLER2D",
+ "SAMPLERCUBE",
+ "SAMPLER_EXTERNAL_OES",
+ "SAMPLER2DRECT",
+ "SAMPLER2DARRAY",
+ "ISAMPLER2D",
+ "ISAMPLER3D",
+ "ISAMPLERCUBE",
+ "ISAMPLER2DARRAY",
+ "USAMPLER2D",
+ "USAMPLER3D",
+ "USAMPLERCUBE",
+ "USAMPLER2DARRAY",
+ "SAMPLER2DMS",
+ "ISAMPLER2DMS",
+ "USAMPLER2DMS",
+ "SAMPLER2DMSARRAY",
+ "ISAMPLER2DMSARRAY",
+ "USAMPLER2DMSARRAY",
+ "SAMPLER3D",
+ "SAMPLER3DRECT",
+ "SAMPLER2DSHADOW",
+ "SAMPLERCUBESHADOW",
+ "SAMPLER2DARRAYSHADOW",
+ "SAMPLERVIDEOWEBGL",
+ "SAMPLERCUBEARRAYOES",
+ "SAMPLERCUBEARRAYSHADOWOES",
+ "ISAMPLERCUBEARRAYOES",
+ "USAMPLERCUBEARRAYOES",
+ "SAMPLERCUBEARRAYEXT",
+ "SAMPLERCUBEARRAYSHADOWEXT",
+ "ISAMPLERCUBEARRAYEXT",
+ "USAMPLERCUBEARRAYEXT",
+ "SAMPLERBUFFER",
+ "ISAMPLERBUFFER",
+ "USAMPLERBUFFER",
+ "SAMPLEREXTERNAL2DY2YEXT",
+ "IMAGE2D",
+ "IIMAGE2D",
+ "UIMAGE2D",
+ "IMAGE3D",
+ "IIMAGE3D",
+ "UIMAGE3D",
+ "IMAGE2DARRAY",
+ "IIMAGE2DARRAY",
+ "UIMAGE2DARRAY",
+ "IMAGECUBE",
+ "IIMAGECUBE",
+ "UIMAGECUBE",
+ "IMAGECUBEARRAYOES",
+ "IIMAGECUBEARRAYOES",
+ "UIMAGECUBEARRAYOES",
+ "IMAGECUBEARRAYEXT",
+ "IIMAGECUBEARRAYEXT",
+ "UIMAGECUBEARRAYEXT",
+ "IMAGEBUFFER",
+ "IIMAGEBUFFER",
+ "UIMAGEBUFFER",
+ "ATOMICUINT",
+ "PIXELLOCALANGLE",
+ "IPIXELLOCALANGLE",
+ "UPIXELLOCALANGLE",
+ "LAYOUT",
+ "YUVCSCSTANDARDEXT",
+ "YUVCSCSTANDARDEXTCONSTANT",
+ "IDENTIFIER",
+ "TYPE_NAME",
+ "FLOATCONSTANT",
+ "INTCONSTANT",
+ "UINTCONSTANT",
+ "BOOLCONSTANT",
+ "FIELD_SELECTION",
+ "LEFT_OP",
+ "RIGHT_OP",
+ "INC_OP",
+ "DEC_OP",
+ "LE_OP",
+ "GE_OP",
+ "EQ_OP",
+ "NE_OP",
+ "AND_OP",
+ "OR_OP",
+ "XOR_OP",
+ "MUL_ASSIGN",
+ "DIV_ASSIGN",
+ "ADD_ASSIGN",
+ "MOD_ASSIGN",
+ "LEFT_ASSIGN",
+ "RIGHT_ASSIGN",
+ "AND_ASSIGN",
+ "XOR_ASSIGN",
+ "OR_ASSIGN",
+ "SUB_ASSIGN",
+ "LEFT_PAREN",
+ "RIGHT_PAREN",
+ "LEFT_BRACKET",
+ "RIGHT_BRACKET",
+ "LEFT_BRACE",
+ "RIGHT_BRACE",
+ "DOT",
+ "COMMA",
+ "COLON",
+ "EQUAL",
+ "SEMICOLON",
+ "BANG",
+ "DASH",
+ "TILDE",
+ "PLUS",
+ "STAR",
+ "SLASH",
+ "PERCENT",
+ "LEFT_ANGLE",
+ "RIGHT_ANGLE",
+ "VERTICAL_BAR",
+ "CARET",
+ "AMPERSAND",
+ "QUESTION",
+ "$accept",
+ "identifier",
+ "variable_identifier",
+ "primary_expression",
+ "postfix_expression",
+ "integer_expression",
+ "function_call",
+ "function_call_or_method",
+ "function_call_generic",
+ "function_call_header_no_parameters",
+ "function_call_header_with_parameters",
+ "function_call_header",
+ "function_identifier",
+ "unary_expression",
+ "unary_operator",
+ "multiplicative_expression",
+ "additive_expression",
+ "shift_expression",
+ "relational_expression",
+ "equality_expression",
+ "and_expression",
+ "exclusive_or_expression",
+ "inclusive_or_expression",
+ "logical_and_expression",
+ "logical_xor_expression",
+ "logical_or_expression",
+ "conditional_expression",
+ "assignment_expression",
+ "assignment_operator",
+ "expression",
+ "constant_expression",
+ "enter_struct",
+ "declaration",
+ "function_prototype",
+ "function_declarator",
+ "function_header_with_parameters",
+ "function_header",
+ "parameter_declarator",
+ "parameter_declaration",
+ "parameter_type_specifier",
+ "init_declarator_list",
+ "single_declaration",
+ "fully_specified_type",
+ "interpolation_qualifier",
+ "type_qualifier",
+ "invariant_qualifier",
+ "precise_qualifier",
+ "single_type_qualifier",
+ "storage_qualifier",
+ "type_specifier",
+ "precision_qualifier",
+ "layout_qualifier",
+ "layout_qualifier_id_list",
+ "layout_qualifier_id",
+ "type_specifier_no_prec",
+ "array_specifier",
+ "type_specifier_nonarray",
+ "struct_specifier",
+ "$@1",
+ "$@2",
+ "struct_declaration_list",
+ "struct_declaration",
+ "struct_declarator_list",
+ "struct_declarator",
+ "initializer",
+ "declaration_statement",
+ "statement",
+ "simple_statement",
+ "compound_statement_with_scope",
+ "$@3",
+ "$@4",
+ "statement_no_new_scope",
+ "statement_with_scope",
+ "$@5",
+ "$@6",
+ "compound_statement_no_new_scope",
+ "statement_list",
+ "expression_statement",
+ "selection_statement",
+ "selection_rest_statement",
+ "switch_statement",
+ "$@7",
+ "case_label",
+ "condition",
+ "iteration_statement",
+ "$@8",
+ "$@9",
+ "$@10",
+ "for_init_statement",
+ "conditionopt",
+ "for_rest_statement",
+ "jump_statement",
+ "translation_unit",
+ "external_declaration",
+ "function_definition",
+ "$@11",
+ YY_NULLPTR};
+
+static const char *yysymbol_name(yysymbol_kind_t yysymbol)
+{
+ return yytname[yysymbol];
+}
+#endif
+
+#define YYPACT_NINF (-397)
+
+#define yypact_value_is_default(Yyn) ((Yyn) == YYPACT_NINF)
+
+#define YYTABLE_NINF (-289)
+
+#define yytable_value_is_error(Yyn) 0
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+static const yytype_int16 yypact[] = {
+ 3052, -397, -397, -397, -397, -397, 105, -397, -397, -397, -397, -397, -397, -397, -397, -397,
+ -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397,
+ -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397,
+ -397, -397, -397, -397, -94, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397,
+ -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397,
+ -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397,
+ -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397,
+ -397, -397, -397, -132, -397, -397, -397, -81, -41, -49, 3184, -90, -397, -86, -397, 1609,
+ -397, -397, -397, -397, -397, -397, -397, -397, -39, -397, 2920, -397, -397, 3432, -397, -397,
+ -397, -31, -47, -397, -26, -397, 3184, -397, -397, -397, 3184, 3, 3, -397, -35, -135,
+ -114, -397, 3184, -397, -397, 1734, -10, -397, -397, -6, 3184, -397, -397, -9, -93, -397,
+ 438, -397, -397, -397, -397, -39, -97, -397, 2193, -87, -397, -397, 3184, 3, 2497, -397,
+ -397, 7, -397, -397, -397, -397, -397, 2193, 2193, 2193, -397, -397, -397, -397, -397, -397,
+ -397, -78, -397, -397, -397, 12, -69, 2344, 8, -397, 2193, -33, -96, -116, -124, 5,
+ -12, -7, -4, 31, 30, -123, -397, 17, -397, 1888, -397, 2638, 3184, 19, -397, -47,
+ 13, 14, -397, 22, 25, 16, 2042, 28, 2193, 32, 44, 37, -397, -397, 40, -397,
+ -397, -80, -397, -81, 45, -397, -397, -397, -397, 611, -397, -397, -397, -397, -397, -397,
+ -10, 2193, -83, -397, -397, 2193, 3, -39, -76, -397, -111, -397, -397, -397, -62, -397,
+ -397, 2193, 3308, -397, -397, 2193, 46, -397, -397, -397, 2193, 2193, 2193, 2193, 2193, 2193,
+ 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, 2193, -397, -397,
+ 47, -397, 2779, -397, -397, -397, -397, -397, 48, -397, 2193, -397, -397, -48, 2193, 43,
+ -397, -397, -397, 784, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, -397, 2193,
+ 2193, -397, -397, -397, -397, 2193, -397, -43, -10, 3, -397, -122, -397, -397, 51, 41,
+ -397, 55, -397, -397, -397, -397, -397, -33, -33, -96, -96, -116, -116, -116, -116, -124,
+ -124, 5, -12, -7, -4, 31, 30, -11, -397, -397, 150, -26, 1130, 1303, -60, -397,
+ -59, -397, 1456, 784, -397, -397, -397, -397, -397, -397, -109, -397, 2193, 57, -397, -397,
+ -397, -397, 1456, 48, -397, 41, 3, 3184, 58, 56, -397, -397, 2193, -397, 50, 61,
+ 206, -397, 60, 59, 957, -397, -55, 2193, 957, 48, -397, 2193, -397, -397, -397, 63,
+ 41, -397, -397, -397, -397};
+
+/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
+ Performed when YYTABLE does not specify something else to do. Zero
+ means the default is an error. */
+static const yytype_int16 yydefact[] = {
+ 0, 127, 128, 153, 154, 155, 0, 135, 137, 173, 170, 171, 172, 177, 178, 179, 180, 181, 182,
+ 174, 175, 176, 183, 184, 185, 186, 187, 188, 138, 139, 140, 143, 144, 136, 189, 190, 191, 192,
+ 193, 194, 151, 141, 123, 122, 124, 142, 145, 146, 147, 148, 149, 150, 0, 169, 196, 198, 229,
+ 231, 199, 205, 206, 207, 208, 214, 215, 216, 217, 200, 209, 218, 201, 210, 219, 197, 223, 224,
+ 225, 228, 202, 226, 211, 220, 203, 227, 212, 221, 204, 213, 222, 230, 232, 233, 234, 235, 236,
+ 237, 238, 239, 240, 241, 242, 243, 244, 246, 248, 245, 247, 249, 250, 251, 252, 253, 254, 255,
+ 256, 0, 195, 258, 327, 328, 0, 99, 98, 0, 110, 115, 132, 0, 133, 134, 125, 129, 120,
+ 131, 130, 152, 163, 257, 0, 324, 326, 0, 2, 3, 261, 0, 0, 89, 0, 97, 0, 106,
+ 100, 108, 0, 109, 0, 90, 2, 116, 0, 95, 0, 126, 121, 0, 164, 1, 325, 0, 0,
+ 259, 162, 159, 0, 157, 0, 329, 101, 105, 107, 103, 111, 102, 0, 117, 88, 96, 0, 0,
+ 0, 263, 10, 4, 8, 6, 7, 9, 31, 0, 0, 0, 165, 38, 37, 39, 36, 5, 12,
+ 32, 14, 19, 20, 0, 0, 25, 0, 40, 0, 44, 47, 50, 55, 58, 60, 62, 64, 66,
+ 68, 70, 87, 0, 29, 0, 91, 0, 0, 0, 156, 0, 0, 0, 309, 0, 0, 0, 0,
+ 0, 0, 0, 0, 283, 292, 296, 40, 72, 85, 0, 272, 0, 152, 275, 294, 274, 273, 0,
+ 276, 277, 278, 279, 280, 281, 104, 0, 112, 271, 119, 0, 0, 269, 0, 267, 0, 264, 33,
+ 34, 0, 16, 17, 0, 0, 23, 22, 0, 169, 26, 28, 35, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 167, 0, 262, 0,
+ 160, 161, 158, 320, 319, 290, 311, 0, 323, 321, 0, 0, 0, 304, 307, 282, 0, 75, 76,
+ 78, 77, 80, 81, 82, 83, 84, 79, 74, 0, 0, 297, 293, 295, 114, 0, 118, 0, 270,
+ 0, 265, 0, 92, 11, 0, 18, 30, 15, 21, 27, 41, 42, 43, 46, 45, 48, 49, 53,
+ 54, 51, 52, 56, 57, 59, 61, 63, 65, 67, 69, 0, 168, 260, 0, 0, 0, 0, 0,
+ 322, 0, 303, 0, 284, 73, 86, 113, 266, 268, 93, 0, 13, 0, 0, 289, 291, 314, 313,
+ 316, 290, 301, 305, 0, 0, 0, 0, 94, 71, 0, 315, 0, 0, 300, 298, 0, 0, 0,
+ 285, 0, 317, 0, 290, 302, 0, 287, 308, 286, 0, 318, 312, 299, 306, 310};
+
+/* YYPGOTO[NTERM-NUM]. */
+static const yytype_int16 yypgoto[] = {
+ -397, -51, -397, -397, -397, -397, -397, -397, -64, -397, -397, -397, -397, 42, -397, -142,
+ -140, -175, -143, -84, -75, -85, -82, -77, -73, -397, -151, -179, -397, -188, -202, -397,
+ 9, 10, -397, -397, -397, 77, 89, 90, -397, -397, -375, -397, -118, -397, -397, -121,
+ -397, -120, 239, -397, -397, 15, 0, -144, -397, -397, -397, -397, -152, -182, -32, -113,
+ -261, -150, -254, -377, -185, -397, -397, -187, -396, -397, -397, -145, -72, -141, -397, -397,
+ -397, -397, -397, -166, -397, -397, -397, -397, -397, -397, -397, -397, -397, 117, -397, -397};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const yytype_int16 yydefgoto[] = {
+ 0, 279, 207, 208, 209, 366, 210, 211, 212, 213, 214, 215, 216, 254, 218, 219,
+ 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 255, 256, 351, 257, 231, 162,
+ 258, 259, 120, 121, 122, 151, 152, 153, 123, 124, 125, 126, 127, 128, 129, 130,
+ 131, 132, 133, 134, 174, 175, 232, 166, 136, 137, 236, 170, 190, 191, 280, 281,
+ 276, 261, 262, 263, 264, 339, 425, 445, 394, 395, 396, 446, 265, 266, 267, 433,
+ 268, 434, 269, 424, 270, 402, 328, 397, 418, 430, 431, 271, 138, 139, 140, 148};
+
+/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule whose
+ number is the opposite. If YYTABLE_NINF, syntax error. */
+static const yytype_int16 yytable[] = {
+ 135, 145, 155, 177, 154, 275, 163, 164, 283, 118, 119, 355, 356, 286, 230, 185, 358, 172, 235,
+ 415, 305, 306, 363, 432, 303, 304, 316, 422, 165, 146, 155, 320, 154, 163, 155, 184, 295, 272,
+ 274, 142, 143, 165, 189, 422, 188, 450, 335, 158, 143, 409, 189, 186, 188, 283, 233, 307, 308,
+ 187, 333, 444, 364, 317, 426, 444, 287, 288, 165, 163, 278, 238, 189, 144, 188, 273, 159, 239,
+ 233, 301, 156, 302, 233, 157, 230, 277, 322, 289, 173, 357, 352, 290, 147, 353, 361, 292, 275,
+ 362, 406, 230, 275, 293, 365, 367, 419, 420, 181, 182, 352, 447, 352, 352, 3, 4, 5, 352,
+ 371, 189, 189, 188, 188, 150, 352, 149, 135, 399, 165, 361, 183, 135, 407, 391, 379, 380, 381,
+ 382, 171, 360, 142, 143, 135, 176, 283, 169, 398, 298, 299, 300, 400, 118, 119, 355, 135, 309,
+ 310, 233, 135, 323, 324, 352, 412, 375, 376, 237, 135, 377, 378, 234, 383, 384, -30, 296, 135,
+ 311, 404, 405, 291, 312, 260, 313, 275, 314, 315, 318, 451, 329, 326, 327, 330, 331, 135, 334,
+ 135, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 336, 189, 338, 188, 337, -29, 217, -24,
+ 352, 350, 392, 401, -288, 421, 411, -31, 413, 428, 410, 436, 439, 437, 440, 441, 251, 370, 385,
+ 387, 443, 421, 179, 388, 427, 452, 135, 135, 386, 389, 178, 438, 284, 285, 390, 180, 141, 359,
+ 416, 408, 442, 414, 448, 429, 449, 325, 168, 417, 0, 0, 0, 297, 0, 0, 0, 275, 260,
+ 0, 403, 0, 0, 0, 0, 0, 0, 0, 217, 0, 0, 0, 0, 0, 0, 0, 0, 423,
+ 0, 0, 0, 0, 0, 217, 0, 0, 0, 0, 0, 0, 0, 0, 0, 423, 0, 163, 164,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 260, 372, 373,
+ 374, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 435, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 260, 260, 0,
+ 0, 0, 0, 260, 260, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 260, 0, 0, 0, 0, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 260,
+ 0, 0, 0, 260, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 240, 241, 242,
+ 0, 243, 244, 245, 246, 247, 248, 249, 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,
+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 250, 54, 55, 56, 57, 58, 59, 60,
+ 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 0, 74, 75, 76, 77, 78,
+ 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
+ 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
+ 192, 193, 117, 194, 195, 196, 197, 198, 0, 0, 199, 200, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 251, 252, 0, 0, 0,
+ 0, 253, 203, 204, 205, 206, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 240,
+ 241, 242, 0, 243, 244, 245, 246, 247, 248, 249, 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, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 250, 54, 55, 56, 57, 58,
+ 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 0, 74, 75, 76,
+ 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+ 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
+ 115, 116, 192, 193, 117, 194, 195, 196, 197, 198, 0, 0, 199, 200, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 251, 354, 0,
+ 0, 0, 0, 253, 203, 204, 205, 206, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
+ 12, 240, 241, 242, 0, 243, 244, 245, 246, 247, 248, 249, 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, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 250, 54, 55, 56,
+ 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 0, 74,
+ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
+ 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
+ 113, 114, 115, 116, 192, 193, 117, 194, 195, 196, 197, 198, 0, 0, 199, 200, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 251,
+ 0, 0, 0, 0, 0, 253, 203, 204, 205, 206, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 240, 241, 242, 0, 243, 244, 245, 246, 247, 248, 249, 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, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 250, 54,
+ 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
+ 0, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
+ 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
+ 111, 112, 113, 114, 115, 116, 192, 193, 117, 194, 195, 196, 197, 198, 0, 0, 199, 200, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 201, 0, 0,
+ 0, 176, 0, 0, 0, 0, 0, 253, 203, 204, 205, 206, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 240, 241, 242, 0, 243, 244, 245, 246, 247, 248, 249, 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, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ 250, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
+ 72, 73, 0, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
+ 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
+ 109, 110, 111, 112, 113, 114, 115, 116, 192, 193, 117, 194, 195, 196, 197, 198, 0, 0, 199,
+ 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 201,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 253, 203, 204, 205, 206, 1, 2, 3, 4, 5,
+ 6, 7, 8, 9, 10, 11, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 0, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+ 70, 71, 72, 73, 0, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87,
+ 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106,
+ 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 192, 193, 117, 194, 195, 196, 197, 198, 0,
+ 0, 199, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4,
+ 5, 201, 7, 8, 9, 10, 11, 12, 0, 0, 0, 253, 203, 204, 205, 206, 0, 0, 0,
+ 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, 43, 44, 45, 46, 47, 48, 49, 50,
+ 51, 52, 53, 0, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
+ 69, 70, 71, 72, 73, 0, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
+ 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
+ 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 192, 193, 117, 194, 195, 196, 197, 198,
+ 0, 0, 199, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3,
+ 4, 5, 201, 7, 8, 9, 10, 11, 12, 0, 0, 0, 0, 203, 204, 205, 206, 0, 0,
+ 0, 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, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 0, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
+ 68, 69, 70, 71, 72, 73, 0, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85,
+ 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
+ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 0, 160, 117, 0, 9, 10, 11,
+ 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, 0, 0, 0, 0, 0, 161, 34, 35, 36, 37, 38,
+ 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 53, 0, 54, 55, 56,
+ 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 0, 74,
+ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
+ 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
+ 113, 114, 0, 116, 192, 193, 117, 194, 195, 196, 197, 198, 0, 0, 199, 200, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 201, 0, 0, 202, 9,
+ 10, 11, 12, 0, 0, 0, 203, 204, 205, 206, 0, 0, 0, 0, 13, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 0, 0, 0, 0, 0, 0, 34, 35, 36,
+ 37, 38, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 53, 0, 54,
+ 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
+ 0, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
+ 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
+ 111, 112, 113, 114, 0, 116, 192, 193, 117, 194, 195, 196, 197, 198, 0, 0, 199, 200, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 201, 0, 0,
+ 319, 9, 10, 11, 12, 0, 0, 0, 203, 204, 205, 206, 0, 0, 0, 0, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 0, 0, 0, 0, 0, 0, 34,
+ 35, 36, 37, 38, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 53,
+ 0, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
+ 72, 73, 0, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
+ 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
+ 109, 110, 111, 112, 113, 114, 0, 116, 192, 193, 117, 194, 195, 196, 197, 198, 0, 0, 199,
+ 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 201,
+ 9, 10, 11, 12, 0, 0, 0, 0, 0, 332, 203, 204, 205, 206, 0, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 0, 0, 0, 0, 0, 0, 34, 35,
+ 36, 37, 38, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 53, 0,
+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
+ 73, 0, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
+ 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
+ 110, 111, 112, 113, 114, 0, 116, 192, 193, 117, 194, 195, 196, 197, 198, 0, 0, 199, 200,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 201, 9,
+ 10, 11, 12, 0, 0, 0, 0, 0, 0, 203, 204, 205, 206, 0, 13, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 0, 0, 0, 0, 0, 0, 34, 35, 36,
+ 37, 38, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 294, 0, 54,
+ 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
+ 0, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
+ 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
+ 111, 112, 113, 114, 0, 116, 192, 193, 117, 194, 195, 196, 197, 198, 0, 0, 199, 200, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 201, 7, 8,
+ 9, 10, 11, 12, 0, 0, 0, 0, 203, 204, 205, 206, 0, 0, 0, 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, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 0,
+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
+ 73, 0, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
+ 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
+ 110, 111, 112, 113, 114, 115, 116, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 2, 3, 4, 5, 0, 7, 8, 9, 10, 11, 12, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 282, 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, 43, 44, 45, 46,
+ 47, 48, 49, 50, 51, 52, 53, 0, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
+ 65, 66, 67, 68, 69, 70, 71, 72, 73, 0, 74, 75, 76, 77, 78, 79, 80, 81, 82,
+ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101,
+ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 0, 0, 117, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 0, 7, 8, 9, 10, 11,
+ 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, 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, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 0, 54, 55, 56,
+ 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 0, 74,
+ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
+ 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
+ 113, 114, 115, 116, 0, 0, 117, 0, 0, 0, 0, 0, 0, 167, 0, 0, 1, 2, 3,
+ 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 393, 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, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 0, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
+ 68, 69, 70, 71, 72, 73, 0, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85,
+ 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
+ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 0, 0, 117, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 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, 43, 44, 45, 46, 47, 48, 49, 50,
+ 51, 52, 53, 0, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
+ 69, 70, 71, 72, 73, 0, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
+ 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
+ 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 0, 0, 117, 1, 2, 3, 4, 5,
+ 0, 7, 8, 9, 10, 11, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 0, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+ 70, 71, 72, 73, 0, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87,
+ 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106,
+ 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 0, 0, 117, 9, 10, 11, 12, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 0, 0, 0, 0, 0, 0, 34, 35, 36, 37, 38, 39, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 53, 0, 54, 55, 56, 57, 58, 59,
+ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 0, 74, 75, 76, 77,
+ 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96,
+ 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 0,
+ 116, 0, 368, 117, 9, 10, 11, 12, 369, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 0, 0, 0, 0,
+ 0, 0, 34, 35, 36, 37, 38, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 52, 53, 0, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
+ 69, 70, 71, 72, 73, 0, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
+ 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
+ 106, 107, 108, 109, 110, 111, 112, 113, 114, 0, 116, 0, 0, 117};
+
+static const yytype_int16 yycheck[] = {
+ 0, 52, 122, 148, 122, 184, 127, 127, 190, 0, 0, 265, 273, 201, 165, 159, 277, 64, 170,
+ 396, 144, 145, 133, 419, 140, 141, 149, 402, 163, 161, 150, 233, 150, 154, 154, 170, 215, 181,
+ 182, 133, 134, 163, 162, 418, 162, 441, 248, 133, 134, 171, 170, 165, 170, 235, 163, 179, 180,
+ 171, 246, 436, 171, 184, 171, 440, 142, 143, 163, 188, 188, 162, 190, 165, 190, 170, 125, 168,
+ 163, 173, 168, 175, 163, 171, 233, 170, 236, 163, 133, 170, 168, 167, 171, 171, 168, 162, 273,
+ 171, 357, 248, 277, 168, 162, 289, 162, 162, 155, 156, 168, 162, 168, 168, 5, 6, 7, 168,
+ 293, 235, 236, 235, 236, 168, 168, 162, 122, 171, 163, 168, 161, 127, 171, 317, 305, 306, 307,
+ 308, 165, 279, 133, 134, 138, 165, 322, 141, 330, 176, 177, 178, 334, 138, 138, 403, 150, 146,
+ 147, 163, 154, 136, 137, 168, 169, 301, 302, 170, 162, 303, 304, 171, 309, 310, 161, 161, 170,
+ 183, 351, 352, 162, 182, 176, 181, 357, 148, 150, 164, 443, 161, 171, 171, 161, 171, 188, 161,
+ 190, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 169, 322, 166, 322, 161, 161, 165, 162,
+ 168, 170, 164, 169, 165, 402, 164, 161, 67, 161, 363, 162, 171, 166, 162, 18, 165, 290, 311,
+ 313, 170, 418, 154, 314, 412, 171, 235, 236, 312, 315, 150, 428, 199, 200, 316, 154, 6, 278,
+ 397, 361, 434, 395, 439, 418, 440, 239, 138, 397, -1, -1, -1, 218, -1, -1, -1, 443, 265,
+ -1, 339, -1, -1, -1, -1, -1, -1, -1, 233, -1, -1, -1, -1, -1, -1, -1, -1, 402,
+ -1, -1, -1, -1, -1, 248, -1, -1, -1, -1, -1, -1, -1, -1, -1, 418, -1, 423, 423,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 322,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 339, 298, 299,
+ 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 422, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 396, 397, -1,
+ -1, -1, -1, 402, 403, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 418, -1, -1, -1, -1, 423, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 436,
+ -1, -1, -1, 440, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
+ -1, 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, 71, 72, 73, 74,
+ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, -1, 89, 90, 91, 92, 93,
+ 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
+ 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131,
+ 132, 133, 134, 135, 136, 137, 138, 139, -1, -1, 142, 143, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 161, -1, -1, -1, 165, 166, -1, -1, -1,
+ -1, 171, 172, 173, 174, 175, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, -1, 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, 71, 72,
+ 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, -1, 89, 90, 91,
+ 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
+ 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129,
+ 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, -1, -1, 142, 143, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 161, -1, -1, -1, 165, 166, -1,
+ -1, -1, -1, 171, 172, 173, 174, 175, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
+ 14, 15, 16, 17, -1, 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,
+ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, -1, 89,
+ 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
+ 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
+ 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, -1, -1, 142, 143, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 161, -1, -1, -1, 165,
+ -1, -1, -1, -1, -1, 171, 172, 173, 174, 175, 3, 4, 5, 6, 7, 8, 9, 10, 11,
+ 12, 13, 14, 15, 16, 17, -1, 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, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87,
+ -1, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106,
+ 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125,
+ 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, -1, -1, 142, 143, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 161, -1, -1,
+ -1, 165, -1, -1, -1, -1, -1, 171, 172, 173, 174, 175, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, 15, 16, 17, -1, 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, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85,
+ 86, 87, -1, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
+ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123,
+ 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, -1, -1, 142,
+ 143, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 161,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 171, 172, 173, 174, 175, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 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, -1, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
+ 84, 85, 86, 87, -1, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102,
+ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121,
+ 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, -1,
+ -1, 142, 143, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, 4, 5, 6,
+ 7, 161, 9, 10, 11, 12, 13, 14, -1, -1, -1, 171, 172, 173, 174, 175, -1, -1, -1,
+ 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, -1, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
+ 83, 84, 85, 86, 87, -1, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101,
+ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120,
+ 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139,
+ -1, -1, 142, 143, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, 4, 5,
+ 6, 7, 161, 9, 10, 11, 12, 13, 14, -1, -1, -1, -1, 172, 173, 174, 175, -1, -1,
+ -1, 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, -1, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
+ 82, 83, 84, 85, 86, 87, -1, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,
+ 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
+ 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, -1, 133, 134, -1, 11, 12, 13,
+ 14, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 36, 37, 38, 39, 40, -1, -1, -1, -1, -1, 171, 47, 48, 49, 50, 51,
+ 52, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65, 66, -1, 68, 69, 70,
+ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, -1, 89,
+ 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
+ 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
+ 128, 129, -1, 131, 132, 133, 134, 135, 136, 137, 138, 139, -1, -1, 142, 143, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 161, -1, -1, 164, 11,
+ 12, 13, 14, -1, -1, -1, 172, 173, 174, 175, -1, -1, -1, -1, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, -1, -1, -1, -1, -1, -1, 47, 48, 49,
+ 50, 51, 52, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65, 66, -1, 68,
+ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87,
+ -1, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106,
+ 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125,
+ 126, 127, 128, 129, -1, 131, 132, 133, 134, 135, 136, 137, 138, 139, -1, -1, 142, 143, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 161, -1, -1,
+ 164, 11, 12, 13, 14, -1, -1, -1, 172, 173, 174, 175, -1, -1, -1, -1, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, -1, -1, -1, -1, -1, -1, 47,
+ 48, 49, 50, 51, 52, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65, 66,
+ -1, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85,
+ 86, 87, -1, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
+ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123,
+ 124, 125, 126, 127, 128, 129, -1, 131, 132, 133, 134, 135, 136, 137, 138, 139, -1, -1, 142,
+ 143, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 161,
+ 11, 12, 13, 14, -1, -1, -1, -1, -1, 171, 172, 173, 174, 175, -1, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, -1, -1, -1, -1, -1, -1, 47, 48,
+ 49, 50, 51, 52, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65, 66, -1,
+ 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
+ 87, -1, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
+ 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
+ 125, 126, 127, 128, 129, -1, 131, 132, 133, 134, 135, 136, 137, 138, 139, -1, -1, 142, 143,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 161, 11,
+ 12, 13, 14, -1, -1, -1, -1, -1, -1, 172, 173, 174, 175, -1, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, -1, -1, -1, -1, -1, -1, 47, 48, 49,
+ 50, 51, 52, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65, 66, -1, 68,
+ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87,
+ -1, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106,
+ 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125,
+ 126, 127, 128, 129, -1, 131, 132, 133, 134, 135, 136, 137, 138, 139, -1, -1, 142, 143, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, 4, 5, 6, 7, 161, 9, 10,
+ 11, 12, 13, 14, -1, -1, -1, -1, 172, 173, 174, 175, -1, -1, -1, 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, -1,
+ 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
+ 87, -1, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
+ 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
+ 125, 126, 127, 128, 129, 130, 131, -1, -1, 134, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 3, 4, 5, 6, 7, -1, 9, 10, 11, 12, 13, 14, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 166, 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, -1, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
+ 79, 80, 81, 82, 83, 84, 85, 86, 87, -1, 89, 90, 91, 92, 93, 94, 95, 96, 97,
+ 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
+ 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, -1, -1, 134, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 3, 4, 5, 6, 7, -1, 9, 10, 11, 12, 13,
+ 14, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 166, 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, -1, 68, 69, 70,
+ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, -1, 89,
+ 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
+ 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
+ 128, 129, 130, 131, -1, -1, 134, -1, -1, -1, -1, -1, -1, 0, -1, -1, 3, 4, 5,
+ 6, 7, 8, 9, 10, 11, 12, 13, 14, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 166, 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, -1, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
+ 82, 83, 84, 85, 86, 87, -1, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,
+ 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
+ 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, -1, -1, 134, 3, 4, 5, 6,
+ 7, 8, 9, 10, 11, 12, 13, 14, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 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, -1, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
+ 83, 84, 85, 86, 87, -1, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101,
+ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120,
+ 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, -1, -1, 134, 3, 4, 5, 6, 7,
+ -1, 9, 10, 11, 12, 13, 14, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 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, -1, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
+ 84, 85, 86, 87, -1, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102,
+ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121,
+ 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, -1, -1, 134, 11, 12, 13, 14, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+ 36, 37, 38, 39, 40, -1, -1, -1, -1, -1, -1, 47, 48, 49, 50, 51, 52, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65, 66, -1, 68, 69, 70, 71, 72, 73,
+ 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, -1, 89, 90, 91, 92,
+ 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, -1,
+ 131, -1, 133, 134, 11, 12, 13, 14, 139, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, -1, -1, -1, -1,
+ -1, -1, 47, 48, 49, 50, 51, 52, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 65, 66, -1, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
+ 83, 84, 85, 86, 87, -1, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101,
+ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120,
+ 121, 122, 123, 124, 125, 126, 127, 128, 129, -1, 131, -1, -1, 134};
+
+/* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of
+ state STATE-NUM. */
+static const yytype_int16 yystos[] = {
+ 0, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 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, 68, 69, 70,
+ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 89, 90,
+ 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
+ 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128,
+ 129, 130, 131, 134, 217, 218, 219, 220, 221, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234,
+ 235, 236, 239, 241, 242, 277, 278, 279, 235, 133, 134, 165, 186, 161, 171, 280, 162, 168, 222,
+ 223, 224, 229, 234, 168, 171, 133, 186, 133, 171, 216, 232, 234, 163, 240, 0, 278, 239, 244,
+ 165, 64, 133, 237, 238, 165, 260, 223, 222, 224, 186, 186, 161, 170, 240, 165, 171, 229, 234,
+ 245, 246, 132, 133, 135, 136, 137, 138, 139, 142, 143, 161, 164, 172, 173, 174, 175, 187, 188,
+ 189, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208,
+ 209, 210, 211, 215, 239, 163, 171, 245, 243, 170, 162, 168, 15, 16, 17, 19, 20, 21, 22,
+ 23, 24, 25, 67, 165, 166, 171, 198, 211, 212, 214, 217, 218, 239, 250, 251, 252, 253, 261,
+ 262, 263, 265, 267, 269, 276, 240, 170, 240, 212, 249, 170, 234, 186, 247, 248, 166, 246, 198,
+ 198, 214, 142, 143, 163, 167, 162, 162, 168, 66, 212, 161, 198, 176, 177, 178, 173, 175, 140,
+ 141, 144, 145, 179, 180, 146, 147, 183, 182, 181, 148, 150, 149, 184, 164, 164, 215, 166, 245,
+ 136, 137, 238, 171, 171, 271, 161, 161, 171, 171, 214, 161, 215, 169, 161, 166, 254, 151, 152,
+ 153, 154, 155, 156, 157, 158, 159, 160, 170, 213, 168, 171, 166, 251, 249, 170, 249, 247, 240,
+ 168, 171, 133, 171, 162, 190, 214, 133, 139, 193, 212, 198, 198, 198, 200, 200, 201, 201, 202,
+ 202, 202, 202, 203, 203, 204, 205, 206, 207, 208, 209, 214, 164, 166, 257, 258, 259, 272, 214,
+ 171, 214, 169, 270, 261, 212, 212, 249, 171, 248, 171, 240, 164, 169, 67, 260, 252, 250, 262,
+ 273, 162, 162, 214, 227, 229, 268, 255, 171, 212, 161, 268, 274, 275, 257, 264, 266, 186, 162,
+ 166, 214, 171, 162, 18, 253, 170, 252, 256, 260, 162, 214, 256, 257, 249, 171};
+
+/* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */
+static const yytype_int16 yyr1[] = {
+ 0, 185, 186, 186, 187, 188, 188, 188, 188, 188, 188, 188, 189, 189, 189, 189, 189, 189, 190,
+ 191, 192, 192, 193, 193, 194, 194, 195, 195, 196, 197, 197, 197, 198, 198, 198, 198, 199, 199,
+ 199, 199, 200, 200, 200, 200, 201, 201, 201, 202, 202, 202, 203, 203, 203, 203, 203, 204, 204,
+ 204, 205, 205, 206, 206, 207, 207, 208, 208, 209, 209, 210, 210, 211, 211, 212, 212, 213, 213,
+ 213, 213, 213, 213, 213, 213, 213, 213, 213, 214, 214, 215, 216, 217, 217, 217, 217, 217, 217,
+ 217, 217, 218, 219, 219, 220, 220, 221, 222, 222, 223, 223, 223, 223, 224, 225, 225, 225, 225,
+ 225, 226, 226, 226, 226, 226, 227, 227, 228, 228, 228, 229, 229, 230, 231, 232, 232, 232, 232,
+ 232, 232, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233,
+ 234, 235, 235, 235, 236, 237, 237, 238, 238, 238, 238, 239, 239, 240, 240, 240, 240, 241, 241,
+ 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241,
+ 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241,
+ 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241,
+ 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241,
+ 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 243, 242, 244, 242, 245, 245, 246,
+ 246, 247, 247, 248, 248, 249, 250, 251, 251, 252, 252, 252, 252, 252, 252, 252, 253, 254, 255,
+ 253, 256, 256, 258, 257, 259, 257, 260, 260, 261, 261, 262, 262, 263, 264, 264, 266, 265, 267,
+ 267, 268, 268, 270, 269, 271, 269, 272, 269, 273, 273, 274, 274, 275, 275, 276, 276, 276, 276,
+ 276, 277, 277, 278, 278, 280, 279};
+
+/* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */
+static const yytype_int8 yyr2[] = {
+ 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 4, 1, 3, 2, 2, 1, 1, 1, 3, 2, 2, 2, 1, 2, 3, 2, 1,
+ 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 3, 3, 3, 1, 3, 3, 1, 3, 3, 1, 3, 3, 3, 3, 1, 3, 3, 1, 3,
+ 1, 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, 7, 2, 3, 2, 1, 1, 2, 3, 3, 2, 3, 2, 1, 2, 1, 1, 1, 3, 4, 6, 5, 1, 2, 3, 5, 4,
+ 1, 2, 1, 1, 1, 1, 2, 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, 4, 1, 3, 1, 3, 3, 1, 1, 2, 2, 3, 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,
+ 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, 1, 1, 1, 1, 1, 1, 1, 1, 0, 6, 0, 5, 1, 2, 3, 4, 1, 3, 1,
+ 2, 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};
+
+enum
+{
+ YYENOMEM = -2
+};
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrorlab
+#define YYNOMEM goto yyexhaustedlab
+
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+ do \
+ if (yychar == YYEMPTY) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ YYPOPSTACK(yylen); \
+ yystate = *yyssp; \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror(&yylloc, context, scanner, YY_("syntax error: cannot back up")); \
+ YYERROR; \
+ } \
+ while (0)
+
+/* Backward compatibility with an undocumented macro.
+ Use YYerror or YYUNDEF. */
+#define YYERRCODE YYUNDEF
+
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+ If N is 0, then set CURRENT to the empty location which ends
+ the previous symbol: RHS[0] (always defined). */
+
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ do \
+ if (N) \
+ { \
+ (Current).first_line = YYRHSLOC(Rhs, 1).first_line; \
+ (Current).first_column = YYRHSLOC(Rhs, 1).first_column; \
+ (Current).last_line = YYRHSLOC(Rhs, N).last_line; \
+ (Current).last_column = YYRHSLOC(Rhs, N).last_column; \
+ } \
+ else \
+ { \
+ (Current).first_line = (Current).last_line = YYRHSLOC(Rhs, 0).last_line; \
+ (Current).first_column = (Current).last_column = YYRHSLOC(Rhs, 0).last_column; \
+ } \
+ while (0)
+#endif
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+
+/* Enable debugging if requested. */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+ do \
+ { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+ } while (0)
+
+/* YYLOCATION_PRINT -- Print the location on the stream.
+ This macro was not mandated originally: define only if we know
+ we won't break user code: when these are the locations we know. */
+
+# ifndef YYLOCATION_PRINT
+
+# if defined YY_LOCATION_PRINT
+
+/* Temporary convenience wrapper in case some people defined the
+ undocumented and private YY_LOCATION_PRINT macros. */
+# define YYLOCATION_PRINT(File, Loc) YY_LOCATION_PRINT(File, *(Loc))
+
+# elif defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
+
+/* Print *YYLOCP on YYO. Private, do not rely on its existence. */
+
+YY_ATTRIBUTE_UNUSED
+static int yy_location_print_(FILE *yyo, YYLTYPE const *const yylocp)
+{
+ int res = 0;
+ int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0;
+ if (0 <= yylocp->first_line)
+ {
+ res += YYFPRINTF(yyo, "%d", yylocp->first_line);
+ if (0 <= yylocp->first_column)
+ res += YYFPRINTF(yyo, ".%d", yylocp->first_column);
+ }
+ if (0 <= yylocp->last_line)
+ {
+ if (yylocp->first_line < yylocp->last_line)
+ {
+ res += YYFPRINTF(yyo, "-%d", yylocp->last_line);
+ if (0 <= end_col)
+ res += YYFPRINTF(yyo, ".%d", end_col);
+ }
+ else if (0 <= end_col && yylocp->first_column < end_col)
+ res += YYFPRINTF(yyo, "-%d", end_col);
+ }
+ return res;
+}
+
+# define YYLOCATION_PRINT yy_location_print_
+
+/* Temporary convenience wrapper in case some people defined the
+ undocumented and private YY_LOCATION_PRINT macros. */
+# define YY_LOCATION_PRINT(File, Loc) YYLOCATION_PRINT(File, &(Loc))
+
+# else
+
+# define YYLOCATION_PRINT(File, Loc) ((void)0)
+/* Temporary convenience wrapper in case some people defined the
+ undocumented and private YY_LOCATION_PRINT macros. */
+# define YY_LOCATION_PRINT YYLOCATION_PRINT
+
+# endif
+# endif /* !defined YYLOCATION_PRINT */
+
+# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \
+ do \
+ { \
+ if (yydebug) \
+ { \
+ YYFPRINTF(stderr, "%s ", Title); \
+ yy_symbol_print(stderr, Kind, Value, Location, context, scanner); \
+ YYFPRINTF(stderr, "\n"); \
+ } \
+ } while (0)
+
+/*-----------------------------------.
+| Print this symbol's value on YYO. |
+`-----------------------------------*/
+
+static void yy_symbol_value_print(FILE *yyo,
+ yysymbol_kind_t yykind,
+ YYSTYPE const *const yyvaluep,
+ YYLTYPE const *const yylocationp,
+ TParseContext *context,
+ void *scanner)
+{
+ FILE *yyoutput = yyo;
+ YY_USE(yyoutput);
+ YY_USE(yylocationp);
+ YY_USE(context);
+ YY_USE(scanner);
+ if (!yyvaluep)
+ return;
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ YY_USE(yykind);
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+}
+
+/*---------------------------.
+| Print this symbol on YYO. |
+`---------------------------*/
+
+static void yy_symbol_print(FILE *yyo,
+ yysymbol_kind_t yykind,
+ YYSTYPE const *const yyvaluep,
+ YYLTYPE const *const yylocationp,
+ TParseContext *context,
+ void *scanner)
+{
+ YYFPRINTF(yyo, "%s %s (", yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name(yykind));
+
+ YYLOCATION_PRINT(yyo, yylocationp);
+ YYFPRINTF(yyo, ": ");
+ yy_symbol_value_print(yyo, yykind, yyvaluep, yylocationp, context, scanner);
+ YYFPRINTF(yyo, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included). |
+`------------------------------------------------------------------*/
+
+static void yy_stack_print(yy_state_t *yybottom, yy_state_t *yytop)
+{
+ YYFPRINTF(stderr, "Stack now");
+ for (; yybottom <= yytop; yybottom++)
+ {
+ int yybot = *yybottom;
+ YYFPRINTF(stderr, " %d", yybot);
+ }
+ YYFPRINTF(stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top) \
+ do \
+ { \
+ if (yydebug) \
+ yy_stack_print((Bottom), (Top)); \
+ } while (0)
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced. |
+`------------------------------------------------*/
+
+static void yy_reduce_print(yy_state_t *yyssp,
+ YYSTYPE *yyvsp,
+ YYLTYPE *yylsp,
+ int yyrule,
+ TParseContext *context,
+ void *scanner)
+{
+ int yylno = yyrline[yyrule];
+ int yynrhs = yyr2[yyrule];
+ int yyi;
+ YYFPRINTF(stderr, "Reducing stack by rule %d (line %d):\n", yyrule - 1, yylno);
+ /* The symbols being reduced. */
+ for (yyi = 0; yyi < yynrhs; yyi++)
+ {
+ YYFPRINTF(stderr, " $%d = ", yyi + 1);
+ yy_symbol_print(stderr, YY_ACCESSING_SYMBOL(+yyssp[yyi + 1 - yynrhs]),
+ &yyvsp[(yyi + 1) - (yynrhs)], &(yylsp[(yyi + 1) - (yynrhs)]), context,
+ scanner);
+ YYFPRINTF(stderr, "\n");
+ }
+}
+
+# define YY_REDUCE_PRINT(Rule) \
+ do \
+ { \
+ if (yydebug) \
+ yy_reduce_print(yyssp, yyvsp, yylsp, Rule, context, scanner); \
+ } while (0)
+
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args) ((void)0)
+# define YY_SYMBOL_PRINT(Title, Kind, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+static void yydestruct(const char *yymsg,
+ yysymbol_kind_t yykind,
+ YYSTYPE *yyvaluep,
+ YYLTYPE *yylocationp,
+ TParseContext *context,
+ void *scanner)
+{
+ YY_USE(yyvaluep);
+ YY_USE(yylocationp);
+ YY_USE(context);
+ YY_USE(scanner);
+ if (!yymsg)
+ yymsg = "Deleting";
+ YY_SYMBOL_PRINT(yymsg, yykind, yyvaluep, yylocationp);
+
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ YY_USE(yykind);
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+}
+
+/*----------.
+| yyparse. |
+`----------*/
+
+int yyparse(TParseContext *context, void *scanner)
+{
+ /* Lookahead token kind. */
+ int yychar;
+
+ /* The semantic value of the lookahead symbol. */
+ /* Default value used for initialization, for pacifying older GCCs
+ or non-GCC compilers. */
+ YY_INITIAL_VALUE(static YYSTYPE yyval_default;)
+ YYSTYPE yylval YY_INITIAL_VALUE(= yyval_default);
+
+ /* Location data for the lookahead symbol. */
+ static YYLTYPE yyloc_default
+#if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
+ = {1, 1, 1, 1}
+#endif
+ ;
+ YYLTYPE yylloc = yyloc_default;
+
+ /* Number of syntax errors so far. */
+ int yynerrs = 0;
+
+ yy_state_fast_t yystate = 0;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus = 0;
+
+ /* Refer to the stacks through separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* Their size. */
+ YYPTRDIFF_T yystacksize = YYINITDEPTH;
+
+ /* The state stack: array, bottom, top. */
+ yy_state_t yyssa[YYINITDEPTH];
+ yy_state_t *yyss = yyssa;
+ yy_state_t *yyssp = yyss;
+
+ /* The semantic value stack: array, bottom, top. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs = yyvsa;
+ YYSTYPE *yyvsp = yyvs;
+
+ /* The location stack: array, bottom, top. */
+ YYLTYPE yylsa[YYINITDEPTH];
+ YYLTYPE *yyls = yylsa;
+ YYLTYPE *yylsp = yyls;
+
+ int yyn;
+ /* The return value of yyparse. */
+ int yyresult;
+ /* Lookahead symbol kind. */
+ yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY;
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+ YYLTYPE yyloc;
+
+ /* The locations where the error started and ended. */
+ YYLTYPE yyerror_range[3];
+
+#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N))
+
+ /* The number of symbols on the RHS of the reduced rule.
+ Keep to zero when no symbol should be popped. */
+ int yylen = 0;
+
+ YYDPRINTF((stderr, "Starting parse\n"));
+
+ yychar = YYEMPTY; /* Cause a token to be read. */
+
+ yylsp[0] = yylloc;
+ goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. So pushing a state here evens the stacks. */
+ yyssp++;
+
+/*--------------------------------------------------------------------.
+| yysetstate -- set current state (the top of the stack) to yystate. |
+`--------------------------------------------------------------------*/
+yysetstate:
+ YYDPRINTF((stderr, "Entering state %d\n", yystate));
+ YY_ASSERT(0 <= yystate && yystate < YYNSTATES);
+ YY_IGNORE_USELESS_CAST_BEGIN
+ *yyssp = YY_CAST(yy_state_t, yystate);
+ YY_IGNORE_USELESS_CAST_END
+ YY_STACK_PRINT(yyss, yyssp);
+
+ if (yyss + yystacksize - 1 <= yyssp)
+#if !defined yyoverflow && !defined YYSTACK_RELOCATE
+ YYNOMEM;
+#else
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYPTRDIFF_T yysize = yyssp - yyss + 1;
+
+# if defined yyoverflow
+ {
+ /* Give user a chance to reallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ yy_state_t *yyss1 = yyss;
+ YYSTYPE *yyvs1 = yyvs;
+ YYLTYPE *yyls1 = yyls;
+
+ /* Each stack pointer address is followed by the size of the
+ data in use in that stack, in bytes. This used to be a
+ conditional around just the two extra args, but that might
+ be undefined if yyoverflow is a macro. */
+ yyoverflow(YY_("memory exhausted"), &yyss1, yysize * YYSIZEOF(*yyssp), &yyvs1,
+ yysize * YYSIZEOF(*yyvsp), &yyls1, yysize * YYSIZEOF(*yylsp), &yystacksize);
+ yyss = yyss1;
+ yyvs = yyvs1;
+ yyls = yyls1;
+ }
+# else /* defined YYSTACK_RELOCATE */
+ /* Extend the stack our own way. */
+ if (YYMAXDEPTH <= yystacksize)
+ YYNOMEM;
+ yystacksize *= 2;
+ if (YYMAXDEPTH < yystacksize)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ yy_state_t *yyss1 = yyss;
+ union yyalloc *yyptr = YY_CAST(
+ union yyalloc *, YYSTACK_ALLOC(YY_CAST(YYSIZE_T, YYSTACK_BYTES(yystacksize))));
+ if (!yyptr)
+ YYNOMEM;
+ YYSTACK_RELOCATE(yyss_alloc, yyss);
+ YYSTACK_RELOCATE(yyvs_alloc, yyvs);
+ YYSTACK_RELOCATE(yyls_alloc, yyls);
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE(yyss1);
+ }
+# endif
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;
+ yylsp = yyls + yysize - 1;
+
+ YY_IGNORE_USELESS_CAST_BEGIN
+ YYDPRINTF((stderr, "Stack size increased to %ld\n", YY_CAST(long, yystacksize)));
+ YY_IGNORE_USELESS_CAST_END
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ YYABORT;
+ }
+#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
+
+ if (yystate == YYFINAL)
+ YYACCEPT;
+
+ goto yybackup;
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+ /* Do appropriate processing given the current state. Read a
+ lookahead token if we need one and don't already have one. */
+
+ /* First try to decide what to do without reference to lookahead token. */
+ yyn = yypact[yystate];
+ if (yypact_value_is_default(yyn))
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* YYCHAR is either empty, or end-of-input, or a valid lookahead. */
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF((stderr, "Reading a token\n"));
+ yychar = yylex(&yylval, &yylloc, scanner);
+ }
+
+ if (yychar <= YYEOF)
+ {
+ yychar = YYEOF;
+ yytoken = YYSYMBOL_YYEOF;
+ YYDPRINTF((stderr, "Now at end of input.\n"));
+ }
+ else if (yychar == YYerror)
+ {
+ /* The scanner already issued an error message, process directly
+ to error recovery. But do not keep the error token as
+ lookahead, it is too special and may lead us to an endless
+ loop in error recovery. */
+ yychar = YYUNDEF;
+ yytoken = YYSYMBOL_YYerror;
+ yyerror_range[1] = yylloc;
+ goto yyerrlab1;
+ }
+ else
+ {
+ yytoken = YYTRANSLATE(yychar);
+ YY_SYMBOL_PRINT("Next token is", yytoken, &yylval, &yylloc);
+ }
+
+ /* If the proper action on seeing token YYTOKEN is to reduce or to
+ detect an error, take that action. */
+ yyn += yytoken;
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+ goto yydefault;
+ yyn = yytable[yyn];
+ if (yyn <= 0)
+ {
+ if (yytable_value_is_error(yyn))
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ /* Shift the lookahead token. */
+ YY_SYMBOL_PRINT("Shifting", yytoken, &yylval, &yylloc);
+ yystate = yyn;
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ *++yyvsp = yylval;
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+ *++yylsp = yylloc;
+
+ /* Discard the shifted token. */
+ yychar = YYEMPTY;
+ goto yynewstate;
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state. |
+`-----------------------------------------------------------*/
+yydefault:
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+/*-----------------------------.
+| yyreduce -- do a reduction. |
+`-----------------------------*/
+yyreduce:
+ /* yyn is the number of a rule to reduce with. */
+ yylen = yyr2[yyn];
+
+ /* If YYLEN is nonzero, implement the default value of the action:
+ '$$ = $1'.
+
+ Otherwise, the following line sets YYVAL to garbage.
+ This behavior is undocumented and Bison
+ users should not rely upon it. Assigning to YYVAL
+ unconditionally makes the parser a bit smaller, and it avoids a
+ GCC warning that YYVAL may be used uninitialized. */
+ yyval = yyvsp[1 - yylen];
+
+ /* Default location. */
+ YYLLOC_DEFAULT(yyloc, (yylsp - yylen), yylen);
+ yyerror_range[1] = yyloc;
+ YY_REDUCE_PRINT(yyn);
+ switch (yyn)
+ {
+ case 4: /* variable_identifier: IDENTIFIER */
+ {
+ // The symbol table search was done in the lexical phase
+ (yyval.interm.intermTypedNode) = context->parseVariableIdentifier(
+ (yylsp[0]), ImmutableString((yyvsp[0].lex).string), (yyvsp[0].lex).symbol);
+ }
+ break;
+
+ case 5: /* primary_expression: variable_identifier */
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 6: /* primary_expression: INTCONSTANT */
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray->setIConst((yyvsp[0].lex).i);
+ (yyval.interm.intermTypedNode) = context->addScalarLiteral(unionArray, (yylsp[0]));
+ }
+ break;
+
+ case 7: /* primary_expression: UINTCONSTANT */
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray->setUConst((yyvsp[0].lex).u);
+ (yyval.interm.intermTypedNode) = context->addScalarLiteral(unionArray, (yylsp[0]));
+ }
+ break;
+
+ case 8: /* primary_expression: FLOATCONSTANT */
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray->setFConst((yyvsp[0].lex).f);
+ (yyval.interm.intermTypedNode) = context->addScalarLiteral(unionArray, (yylsp[0]));
+ }
+ break;
+
+ case 9: /* primary_expression: BOOLCONSTANT */
+ {
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray->setBConst((yyvsp[0].lex).b);
+ (yyval.interm.intermTypedNode) = context->addScalarLiteral(unionArray, (yylsp[0]));
+ }
+ break;
+
+ case 10: /* primary_expression: YUVCSCSTANDARDEXTCONSTANT */
+ {
+ if (!context->checkCanUseExtension((yylsp[0]), TExtension::EXT_YUV_target))
+ {
+ context->error((yylsp[0]), "unsupported value",
+ ImmutableString((yyvsp[0].lex).string));
+ }
+ TConstantUnion *unionArray = new TConstantUnion[1];
+ unionArray->setYuvCscStandardEXTConst(
+ getYuvCscStandardEXT(ImmutableString((yyvsp[0].lex).string)));
+ (yyval.interm.intermTypedNode) = context->addScalarLiteral(unionArray, (yylsp[0]));
+ }
+ break;
+
+ case 11: /* primary_expression: LEFT_PAREN expression RIGHT_PAREN */
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[-1].interm.intermTypedNode);
+ }
+ break;
+
+ case 12: /* postfix_expression: primary_expression */
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 13: /* postfix_expression: postfix_expression LEFT_BRACKET integer_expression
+ RIGHT_BRACKET */
+ {
+ (yyval.interm.intermTypedNode) =
+ context->addIndexExpression((yyvsp[-3].interm.intermTypedNode), (yylsp[-2]),
+ (yyvsp[-1].interm.intermTypedNode));
+ }
+ break;
+
+ case 14: /* postfix_expression: function_call */
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 15: /* postfix_expression: postfix_expression DOT FIELD_SELECTION */
+ {
+ (yyval.interm.intermTypedNode) = context->addFieldSelectionExpression(
+ (yyvsp[-2].interm.intermTypedNode), (yylsp[-1]),
+ ImmutableString((yyvsp[0].lex).string), (yylsp[0]));
+ }
+ break;
+
+ case 16: /* postfix_expression: postfix_expression INC_OP */
+ {
+ (yyval.interm.intermTypedNode) = context->addUnaryMathLValue(
+ EOpPostIncrement, (yyvsp[-1].interm.intermTypedNode), (yylsp[0]));
+ }
+ break;
+
+ case 17: /* postfix_expression: postfix_expression DEC_OP */
+ {
+ (yyval.interm.intermTypedNode) = context->addUnaryMathLValue(
+ EOpPostDecrement, (yyvsp[-1].interm.intermTypedNode), (yylsp[0]));
+ }
+ break;
+
+ case 18: /* integer_expression: expression */
+ {
+ context->checkIsScalarInteger((yyvsp[0].interm.intermTypedNode), "[]");
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 19: /* function_call: function_call_or_method */
+ {
+ (yyval.interm.intermTypedNode) =
+ context->addFunctionCallOrMethod((yyvsp[0].interm.functionLookup), (yylsp[0]));
+ }
+ break;
+
+ case 20: /* function_call_or_method: function_call_generic */
+ {
+ (yyval.interm.functionLookup) = (yyvsp[0].interm.functionLookup);
+ }
+ break;
+
+ case 21: /* function_call_or_method: postfix_expression DOT function_call_generic */
+ {
+ ES3_OR_NEWER("", (yylsp[0]), "methods");
+ (yyval.interm.functionLookup) = (yyvsp[0].interm.functionLookup);
+ (yyval.interm.functionLookup)->setThisNode((yyvsp[-2].interm.intermTypedNode));
+ }
+ break;
+
+ case 22: /* function_call_generic: function_call_header_with_parameters RIGHT_PAREN */
+ {
+ (yyval.interm.functionLookup) = (yyvsp[-1].interm.functionLookup);
+ }
+ break;
+
+ case 23: /* function_call_generic: function_call_header_no_parameters RIGHT_PAREN */
+ {
+ (yyval.interm.functionLookup) = (yyvsp[-1].interm.functionLookup);
+ }
+ break;
+
+ case 24: /* function_call_header_no_parameters: function_call_header VOID_TYPE */
+ {
+ (yyval.interm.functionLookup) = (yyvsp[-1].interm.functionLookup);
+ }
+ break;
+
+ case 25: /* function_call_header_no_parameters: function_call_header */
+ {
+ (yyval.interm.functionLookup) = (yyvsp[0].interm.functionLookup);
+ }
+ break;
+
+ case 26: /* function_call_header_with_parameters: function_call_header assignment_expression
+ */
+ {
+ (yyval.interm.functionLookup) = (yyvsp[-1].interm.functionLookup);
+ (yyval.interm.functionLookup)->addArgument((yyvsp[0].interm.intermTypedNode));
+ }
+ break;
+
+ case 27: /* function_call_header_with_parameters: function_call_header_with_parameters COMMA
+ assignment_expression */
+ {
+ (yyval.interm.functionLookup) = (yyvsp[-2].interm.functionLookup);
+ (yyval.interm.functionLookup)->addArgument((yyvsp[0].interm.intermTypedNode));
+ }
+ break;
+
+ case 28: /* function_call_header: function_identifier LEFT_PAREN */
+ {
+ (yyval.interm.functionLookup) = (yyvsp[-1].interm.functionLookup);
+ }
+ break;
+
+ case 29: /* function_identifier: type_specifier_no_prec */
+ {
+ (yyval.interm.functionLookup) = context->addConstructorFunc((yyvsp[0].interm.type));
+ }
+ break;
+
+ case 30: /* function_identifier: IDENTIFIER */
+ {
+ (yyval.interm.functionLookup) = context->addNonConstructorFunc(
+ ImmutableString((yyvsp[0].lex).string), (yyvsp[0].lex).symbol);
+ }
+ break;
+
+ case 31: /* function_identifier: FIELD_SELECTION */
+ {
+ (yyval.interm.functionLookup) = context->addNonConstructorFunc(
+ ImmutableString((yyvsp[0].lex).string), (yyvsp[0].lex).symbol);
+ }
+ break;
+
+ case 32: /* unary_expression: postfix_expression */
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 33: /* unary_expression: INC_OP unary_expression */
+ {
+ (yyval.interm.intermTypedNode) = context->addUnaryMathLValue(
+ EOpPreIncrement, (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 34: /* unary_expression: DEC_OP unary_expression */
+ {
+ (yyval.interm.intermTypedNode) = context->addUnaryMathLValue(
+ EOpPreDecrement, (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 35: /* unary_expression: unary_operator unary_expression */
+ {
+ (yyval.interm.intermTypedNode) = context->addUnaryMath(
+ (yyvsp[-1].interm.op), (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 36: /* unary_operator: PLUS */
+ {
+ (yyval.interm.op) = EOpPositive;
+ }
+ break;
+
+ case 37: /* unary_operator: DASH */
+ {
+ (yyval.interm.op) = EOpNegative;
+ }
+ break;
+
+ case 38: /* unary_operator: BANG */
+ {
+ (yyval.interm.op) = EOpLogicalNot;
+ }
+ break;
+
+ case 39: /* unary_operator: TILDE */
+ {
+ ES3_OR_NEWER("~", (yyloc), "bit-wise operator");
+ (yyval.interm.op) = EOpBitwiseNot;
+ }
+ break;
+
+ case 40: /* multiplicative_expression: unary_expression */
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 41: /* multiplicative_expression: multiplicative_expression STAR unary_expression */
+ {
+ (yyval.interm.intermTypedNode) =
+ context->addBinaryMath(EOpMul, (yyvsp[-2].interm.intermTypedNode),
+ (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 42: /* multiplicative_expression: multiplicative_expression SLASH unary_expression */
+ {
+ (yyval.interm.intermTypedNode) =
+ context->addBinaryMath(EOpDiv, (yyvsp[-2].interm.intermTypedNode),
+ (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 43: /* multiplicative_expression: multiplicative_expression PERCENT unary_expression */
+ {
+ ES3_OR_NEWER("%", (yylsp[-1]), "integer modulus operator");
+ (yyval.interm.intermTypedNode) =
+ context->addBinaryMath(EOpIMod, (yyvsp[-2].interm.intermTypedNode),
+ (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 44: /* additive_expression: multiplicative_expression */
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 45: /* additive_expression: additive_expression PLUS multiplicative_expression */
+ {
+ (yyval.interm.intermTypedNode) =
+ context->addBinaryMath(EOpAdd, (yyvsp[-2].interm.intermTypedNode),
+ (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 46: /* additive_expression: additive_expression DASH multiplicative_expression */
+ {
+ (yyval.interm.intermTypedNode) =
+ context->addBinaryMath(EOpSub, (yyvsp[-2].interm.intermTypedNode),
+ (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 47: /* shift_expression: additive_expression */
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 48: /* shift_expression: shift_expression LEFT_OP additive_expression */
+ {
+ ES3_OR_NEWER("<<", (yylsp[-1]), "bit-wise operator");
+ (yyval.interm.intermTypedNode) =
+ context->addBinaryMath(EOpBitShiftLeft, (yyvsp[-2].interm.intermTypedNode),
+ (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 49: /* shift_expression: shift_expression RIGHT_OP additive_expression */
+ {
+ ES3_OR_NEWER(">>", (yylsp[-1]), "bit-wise operator");
+ (yyval.interm.intermTypedNode) =
+ context->addBinaryMath(EOpBitShiftRight, (yyvsp[-2].interm.intermTypedNode),
+ (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 50: /* relational_expression: shift_expression */
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 51: /* relational_expression: relational_expression LEFT_ANGLE shift_expression */
+ {
+ (yyval.interm.intermTypedNode) =
+ context->addBinaryMathBooleanResult(EOpLessThan, (yyvsp[-2].interm.intermTypedNode),
+ (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 52: /* relational_expression: relational_expression RIGHT_ANGLE shift_expression */
+ {
+ (yyval.interm.intermTypedNode) = context->addBinaryMathBooleanResult(
+ EOpGreaterThan, (yyvsp[-2].interm.intermTypedNode),
+ (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 53: /* relational_expression: relational_expression LE_OP shift_expression */
+ {
+ (yyval.interm.intermTypedNode) = context->addBinaryMathBooleanResult(
+ EOpLessThanEqual, (yyvsp[-2].interm.intermTypedNode),
+ (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 54: /* relational_expression: relational_expression GE_OP shift_expression */
+ {
+ (yyval.interm.intermTypedNode) = context->addBinaryMathBooleanResult(
+ EOpGreaterThanEqual, (yyvsp[-2].interm.intermTypedNode),
+ (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 55: /* equality_expression: relational_expression */
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 56: /* equality_expression: equality_expression EQ_OP relational_expression */
+ {
+ (yyval.interm.intermTypedNode) =
+ context->addBinaryMathBooleanResult(EOpEqual, (yyvsp[-2].interm.intermTypedNode),
+ (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 57: /* equality_expression: equality_expression NE_OP relational_expression */
+ {
+ (yyval.interm.intermTypedNode) =
+ context->addBinaryMathBooleanResult(EOpNotEqual, (yyvsp[-2].interm.intermTypedNode),
+ (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 58: /* and_expression: equality_expression */
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 59: /* and_expression: and_expression AMPERSAND equality_expression */
+ {
+ ES3_OR_NEWER("&", (yylsp[-1]), "bit-wise operator");
+ (yyval.interm.intermTypedNode) =
+ context->addBinaryMath(EOpBitwiseAnd, (yyvsp[-2].interm.intermTypedNode),
+ (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 60: /* exclusive_or_expression: and_expression */
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 61: /* exclusive_or_expression: exclusive_or_expression CARET and_expression */
+ {
+ ES3_OR_NEWER("^", (yylsp[-1]), "bit-wise operator");
+ (yyval.interm.intermTypedNode) =
+ context->addBinaryMath(EOpBitwiseXor, (yyvsp[-2].interm.intermTypedNode),
+ (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 62: /* inclusive_or_expression: exclusive_or_expression */
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 63: /* inclusive_or_expression: inclusive_or_expression VERTICAL_BAR
+ exclusive_or_expression */
+ {
+ ES3_OR_NEWER("|", (yylsp[-1]), "bit-wise operator");
+ (yyval.interm.intermTypedNode) =
+ context->addBinaryMath(EOpBitwiseOr, (yyvsp[-2].interm.intermTypedNode),
+ (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 64: /* logical_and_expression: inclusive_or_expression */
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 65: /* logical_and_expression: logical_and_expression AND_OP inclusive_or_expression */
+ {
+ (yyval.interm.intermTypedNode) = context->addBinaryMathBooleanResult(
+ EOpLogicalAnd, (yyvsp[-2].interm.intermTypedNode),
+ (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 66: /* logical_xor_expression: logical_and_expression */
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 67: /* logical_xor_expression: logical_xor_expression XOR_OP logical_and_expression */
+ {
+ (yyval.interm.intermTypedNode) = context->addBinaryMathBooleanResult(
+ EOpLogicalXor, (yyvsp[-2].interm.intermTypedNode),
+ (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 68: /* logical_or_expression: logical_xor_expression */
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 69: /* logical_or_expression: logical_or_expression OR_OP logical_xor_expression */
+ {
+ (yyval.interm.intermTypedNode) = context->addBinaryMathBooleanResult(
+ EOpLogicalOr, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode),
+ (yylsp[-1]));
+ }
+ break;
+
+ case 70: /* conditional_expression: logical_or_expression */
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 71: /* conditional_expression: logical_or_expression QUESTION expression COLON
+ assignment_expression */
+ {
+ (yyval.interm.intermTypedNode) = context->addTernarySelection(
+ (yyvsp[-4].interm.intermTypedNode), (yyvsp[-2].interm.intermTypedNode),
+ (yyvsp[0].interm.intermTypedNode), (yylsp[-3]));
+ }
+ break;
+
+ case 72: /* assignment_expression: conditional_expression */
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 73: /* assignment_expression: unary_expression assignment_operator
+ assignment_expression */
+ {
+ (yyval.interm.intermTypedNode) =
+ context->addAssign((yyvsp[-1].interm.op), (yyvsp[-2].interm.intermTypedNode),
+ (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 74: /* assignment_operator: EQUAL */
+ {
+ (yyval.interm.op) = EOpAssign;
+ }
+ break;
+
+ case 75: /* assignment_operator: MUL_ASSIGN */
+ {
+ (yyval.interm.op) = EOpMulAssign;
+ }
+ break;
+
+ case 76: /* assignment_operator: DIV_ASSIGN */
+ {
+ (yyval.interm.op) = EOpDivAssign;
+ }
+ break;
+
+ case 77: /* assignment_operator: MOD_ASSIGN */
+ {
+ ES3_OR_NEWER("%=", (yyloc), "integer modulus operator");
+ (yyval.interm.op) = EOpIModAssign;
+ }
+ break;
+
+ case 78: /* assignment_operator: ADD_ASSIGN */
+ {
+ (yyval.interm.op) = EOpAddAssign;
+ }
+ break;
+
+ case 79: /* assignment_operator: SUB_ASSIGN */
+ {
+ (yyval.interm.op) = EOpSubAssign;
+ }
+ break;
+
+ case 80: /* assignment_operator: LEFT_ASSIGN */
+ {
+ ES3_OR_NEWER("<<=", (yyloc), "bit-wise operator");
+ (yyval.interm.op) = EOpBitShiftLeftAssign;
+ }
+ break;
+
+ case 81: /* assignment_operator: RIGHT_ASSIGN */
+ {
+ ES3_OR_NEWER(">>=", (yyloc), "bit-wise operator");
+ (yyval.interm.op) = EOpBitShiftRightAssign;
+ }
+ break;
+
+ case 82: /* assignment_operator: AND_ASSIGN */
+ {
+ ES3_OR_NEWER("&=", (yyloc), "bit-wise operator");
+ (yyval.interm.op) = EOpBitwiseAndAssign;
+ }
+ break;
+
+ case 83: /* assignment_operator: XOR_ASSIGN */
+ {
+ ES3_OR_NEWER("^=", (yyloc), "bit-wise operator");
+ (yyval.interm.op) = EOpBitwiseXorAssign;
+ }
+ break;
+
+ case 84: /* assignment_operator: OR_ASSIGN */
+ {
+ ES3_OR_NEWER("|=", (yyloc), "bit-wise operator");
+ (yyval.interm.op) = EOpBitwiseOrAssign;
+ }
+ break;
+
+ case 85: /* expression: assignment_expression */
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 86: /* expression: expression COMMA assignment_expression */
+ {
+ (yyval.interm.intermTypedNode) = context->addComma(
+ (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
+ }
+ break;
+
+ case 87: /* constant_expression: conditional_expression */
+ {
+ context->checkIsConst((yyvsp[0].interm.intermTypedNode));
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 88: /* enter_struct: IDENTIFIER LEFT_BRACE */
+ {
+ context->enterStructDeclaration((yylsp[-1]), ImmutableString((yyvsp[-1].lex).string));
+ (yyval.lex) = (yyvsp[-1].lex);
+ }
+ break;
+
+ case 89: /* declaration: function_prototype SEMICOLON */
+ {
+ (yyval.interm.intermNode) = context->addFunctionPrototypeDeclaration(
+ *((yyvsp[-1].interm).function), (yylsp[-1]));
+ }
+ break;
+
+ case 90: /* declaration: init_declarator_list SEMICOLON */
+ {
+ (yyval.interm.intermNode) = (yyvsp[-1].interm).intermDeclaration;
+ }
+ break;
+
+ case 91: /* declaration: PRECISION precision_qualifier type_specifier_no_prec SEMICOLON */
+ {
+ context->parseDefaultPrecisionQualifier((yyvsp[-2].interm.precision),
+ (yyvsp[-1].interm.type), (yylsp[-3]));
+ (yyval.interm.intermNode) = nullptr;
+ }
+ break;
+
+ case 92: /* declaration: type_qualifier enter_struct struct_declaration_list RIGHT_BRACE
+ SEMICOLON */
+ {
+ ES3_OR_NEWER(ImmutableString((yyvsp[-3].lex).string), (yylsp[-4]), "interface blocks");
+ (yyval.interm.intermNode) = context->addInterfaceBlock(
+ *(yyvsp[-4].interm.typeQualifierBuilder), (yylsp[-3]),
+ ImmutableString((yyvsp[-3].lex).string), (yyvsp[-2].interm.fieldList),
+ kEmptyImmutableString, (yyloc), NULL, (yyloc));
+ }
+ break;
+
+ case 93: /* declaration: type_qualifier enter_struct struct_declaration_list RIGHT_BRACE
+ IDENTIFIER SEMICOLON */
+ {
+ ES3_OR_NEWER(ImmutableString((yyvsp[-4].lex).string), (yylsp[-5]), "interface blocks");
+ (yyval.interm.intermNode) = context->addInterfaceBlock(
+ *(yyvsp[-5].interm.typeQualifierBuilder), (yylsp[-4]),
+ ImmutableString((yyvsp[-4].lex).string), (yyvsp[-3].interm.fieldList),
+ ImmutableString((yyvsp[-1].lex).string), (yylsp[-1]), NULL, (yyloc));
+ }
+ break;
+
+ case 94: /* declaration: type_qualifier enter_struct struct_declaration_list RIGHT_BRACE
+ IDENTIFIER array_specifier SEMICOLON */
+ {
+ ES3_OR_NEWER(ImmutableString((yyvsp[-5].lex).string), (yylsp[-6]), "interface blocks");
+ (yyval.interm.intermNode) = context->addInterfaceBlock(
+ *(yyvsp[-6].interm.typeQualifierBuilder), (yylsp[-5]),
+ ImmutableString((yyvsp[-5].lex).string), (yyvsp[-4].interm.fieldList),
+ ImmutableString((yyvsp[-2].lex).string), (yylsp[-2]), (yyvsp[-1].interm.arraySizes),
+ (yylsp[-1]));
+ }
+ break;
+
+ case 95: /* declaration: type_qualifier SEMICOLON */
+ {
+ context->parseGlobalLayoutQualifier(*(yyvsp[-1].interm.typeQualifierBuilder));
+ (yyval.interm.intermNode) = nullptr;
+ }
+ break;
+
+ case 96: /* declaration: type_qualifier IDENTIFIER SEMICOLON */
+ {
+ (yyval.interm.intermNode) = context->parseGlobalQualifierDeclaration(
+ *(yyvsp[-2].interm.typeQualifierBuilder), (yylsp[-1]),
+ ImmutableString((yyvsp[-1].lex).string), (yyvsp[-1].lex).symbol);
+ }
+ break;
+
+ case 97: /* function_prototype: function_declarator RIGHT_PAREN */
+ {
+ (yyval.interm).function =
+ context->parseFunctionDeclarator((yylsp[0]), (yyvsp[-1].interm.function));
+ context->exitFunctionDeclaration();
+ }
+ break;
+
+ case 98: /* function_declarator: function_header */
+ {
+ (yyval.interm.function) = (yyvsp[0].interm.function);
+ }
+ break;
+
+ case 99: /* function_declarator: function_header_with_parameters */
+ {
+ (yyval.interm.function) = (yyvsp[0].interm.function);
+ }
+ break;
+
+ case 100: /* function_header_with_parameters: function_header parameter_declaration */
+ {
+ // Add the parameter
+ (yyval.interm.function) = (yyvsp[-1].interm.function);
+ if ((yyvsp[0].interm.param).type->getBasicType() != EbtVoid)
+ {
+ (yyvsp[-1].interm.function)
+ ->addParameter((yyvsp[0].interm.param).createVariable(&context->symbolTable));
+ }
+ else
+ {
+ // Remember that void was seen, so error can be generated if another parameter is
+ // seen.
+ (yyvsp[-1].interm.function)->setHasVoidParameter();
+ }
+ }
+ break;
+
+ case 101: /* function_header_with_parameters: function_header_with_parameters COMMA
+ parameter_declaration */
+ {
+ (yyval.interm.function) = (yyvsp[-2].interm.function);
+ // Only first parameter of one-parameter functions can be void
+ // The check for named parameters not being void is done in parameter_declarator
+ if ((yyvsp[0].interm.param).type->getBasicType() == EbtVoid)
+ {
+ // This parameter > first is void
+ context->error((yylsp[-1]), "cannot be a parameter type except for '(void)'",
+ "void");
+ }
+ else
+ {
+ if ((yyvsp[-2].interm.function)->hasVoidParameter())
+ {
+ // Only first parameter of one-parameter functions can be void. This check
+ // prevents (void, non_void) parameters.
+ context->error((yylsp[-1]), "cannot be a parameter type except for '(void)'",
+ "void");
+ }
+ (yyvsp[-2].interm.function)
+ ->addParameter((yyvsp[0].interm.param).createVariable(&context->symbolTable));
+ }
+ }
+ break;
+
+ case 102: /* function_header: fully_specified_type IDENTIFIER LEFT_PAREN */
+ {
+ (yyval.interm.function) = context->parseFunctionHeader(
+ (yyvsp[-2].interm.type), ImmutableString((yyvsp[-1].lex).string), (yylsp[-1]));
+
+ context->symbolTable.push();
+ context->enterFunctionDeclaration();
+ }
+ break;
+
+ case 103: /* parameter_declarator: type_specifier identifier */
+ {
+ (yyval.interm.param) = context->parseParameterDeclarator(
+ (yyvsp[-1].interm.type), ImmutableString((yyvsp[0].lex).string), (yylsp[0]));
+ }
+ break;
+
+ case 104: /* parameter_declarator: type_specifier identifier array_specifier */
+ {
+ (yyval.interm.param) = context->parseParameterArrayDeclarator(
+ ImmutableString((yyvsp[-1].lex).string), (yylsp[-1]),
+ *((yyvsp[0].interm.arraySizes)), (yylsp[0]), &(yyvsp[-2].interm.type));
+ }
+ break;
+
+ case 105: /* parameter_declaration: type_qualifier parameter_declarator */
+ {
+ (yyval.interm.param) = (yyvsp[0].interm.param);
+ context->checkIsParameterQualifierValid(
+ (yylsp[0]), *(yyvsp[-1].interm.typeQualifierBuilder), (yyvsp[0].interm.param).type);
+ }
+ break;
+
+ case 106: /* parameter_declaration: parameter_declarator */
+ {
+ (yyval.interm.param) = (yyvsp[0].interm.param);
+ (yyval.interm.param).type->setQualifier(EvqParamIn);
+ }
+ break;
+
+ case 107: /* parameter_declaration: type_qualifier parameter_type_specifier */
+ {
+ (yyval.interm.param) = (yyvsp[0].interm.param);
+ context->checkIsParameterQualifierValid(
+ (yylsp[0]), *(yyvsp[-1].interm.typeQualifierBuilder), (yyvsp[0].interm.param).type);
+ }
+ break;
+
+ case 108: /* parameter_declaration: parameter_type_specifier */
+ {
+ (yyval.interm.param) = (yyvsp[0].interm.param);
+ (yyval.interm.param).type->setQualifier(EvqParamIn);
+ }
+ break;
+
+ case 109: /* parameter_type_specifier: type_specifier */
+ {
+ TParameter param = {0, new TType((yyvsp[0].interm.type))};
+ (yyval.interm.param) = param;
+ }
+ break;
+
+ case 110: /* init_declarator_list: single_declaration */
+ {
+ (yyval.interm) = (yyvsp[0].interm);
+ }
+ break;
+
+ case 111: /* init_declarator_list: init_declarator_list COMMA identifier */
+ {
+ (yyval.interm) = (yyvsp[-2].interm);
+ context->parseDeclarator((yyval.interm).type, (yylsp[0]),
+ ImmutableString((yyvsp[0].lex).string),
+ (yyval.interm).intermDeclaration);
+ }
+ break;
+
+ case 112: /* init_declarator_list: init_declarator_list COMMA identifier array_specifier */
+ {
+ (yyval.interm) = (yyvsp[-3].interm);
+ context->parseArrayDeclarator(
+ (yyval.interm).type, (yylsp[-1]), ImmutableString((yyvsp[-1].lex).string),
+ (yylsp[0]), *((yyvsp[0].interm.arraySizes)), (yyval.interm).intermDeclaration);
+ }
+ break;
+
+ case 113: /* init_declarator_list: init_declarator_list COMMA identifier array_specifier
+ EQUAL initializer */
+ {
+ ES3_OR_NEWER("=", (yylsp[-1]), "first-class arrays (array initializer)");
+ (yyval.interm) = (yyvsp[-5].interm);
+ context->parseArrayInitDeclarator(
+ (yyval.interm).type, (yylsp[-3]), ImmutableString((yyvsp[-3].lex).string),
+ (yylsp[-2]), *((yyvsp[-2].interm.arraySizes)), (yylsp[-1]),
+ (yyvsp[0].interm.intermTypedNode), (yyval.interm).intermDeclaration);
+ }
+ break;
+
+ case 114: /* init_declarator_list: init_declarator_list COMMA identifier EQUAL initializer
+ */
+ {
+ (yyval.interm) = (yyvsp[-4].interm);
+ context->parseInitDeclarator(
+ (yyval.interm).type, (yylsp[-2]), ImmutableString((yyvsp[-2].lex).string),
+ (yylsp[-1]), (yyvsp[0].interm.intermTypedNode), (yyval.interm).intermDeclaration);
+ }
+ break;
+
+ case 115: /* single_declaration: fully_specified_type */
+ {
+ (yyval.interm).type = (yyvsp[0].interm.type);
+ (yyval.interm).intermDeclaration = context->parseSingleDeclaration(
+ (yyval.interm).type, (yylsp[0]), kEmptyImmutableString);
+ }
+ break;
+
+ case 116: /* single_declaration: fully_specified_type identifier */
+ {
+ (yyval.interm).type = (yyvsp[-1].interm.type);
+ (yyval.interm).intermDeclaration = context->parseSingleDeclaration(
+ (yyval.interm).type, (yylsp[0]), ImmutableString((yyvsp[0].lex).string));
+ }
+ break;
+
+ case 117: /* single_declaration: fully_specified_type identifier array_specifier */
+ {
+ (yyval.interm).type = (yyvsp[-2].interm.type);
+ (yyval.interm).intermDeclaration = context->parseSingleArrayDeclaration(
+ (yyval.interm).type, (yylsp[-1]), ImmutableString((yyvsp[-1].lex).string),
+ (yylsp[0]), *((yyvsp[0].interm.arraySizes)));
+ }
+ break;
+
+ case 118: /* single_declaration: fully_specified_type identifier array_specifier EQUAL
+ initializer */
+ {
+ ES3_OR_NEWER("[]", (yylsp[-2]), "first-class arrays (array initializer)");
+ (yyval.interm).type = (yyvsp[-4].interm.type);
+ (yyval.interm).intermDeclaration = context->parseSingleArrayInitDeclaration(
+ (yyval.interm).type, (yylsp[-3]), ImmutableString((yyvsp[-3].lex).string),
+ (yylsp[-2]), *((yyvsp[-2].interm.arraySizes)), (yylsp[-1]),
+ (yyvsp[0].interm.intermTypedNode));
+ }
+ break;
+
+ case 119: /* single_declaration: fully_specified_type identifier EQUAL initializer */
+ {
+ (yyval.interm).type = (yyvsp[-3].interm.type);
+ (yyval.interm).intermDeclaration = context->parseSingleInitDeclaration(
+ (yyval.interm).type, (yylsp[-2]), ImmutableString((yyvsp[-2].lex).string),
+ (yylsp[-1]), (yyvsp[0].interm.intermTypedNode));
+ }
+ break;
+
+ case 120: /* fully_specified_type: type_specifier */
+ {
+ context->addFullySpecifiedType(&(yyvsp[0].interm.type));
+ (yyval.interm.type) = (yyvsp[0].interm.type);
+ }
+ break;
+
+ case 121: /* fully_specified_type: type_qualifier type_specifier */
+ {
+ (yyval.interm.type) = context->addFullySpecifiedType(
+ *(yyvsp[-1].interm.typeQualifierBuilder), (yyvsp[0].interm.type));
+ }
+ break;
+
+ case 122: /* interpolation_qualifier: SMOOTH */
+ {
+ (yyval.interm.qualifier) = EvqSmooth;
+ }
+ break;
+
+ case 123: /* interpolation_qualifier: FLAT */
+ {
+ (yyval.interm.qualifier) = EvqFlat;
+ }
+ break;
+
+ case 124: /* interpolation_qualifier: NOPERSPECTIVE */
+ {
+ if (!context->checkCanUseExtension((yylsp[0]),
+ TExtension::NV_shader_noperspective_interpolation))
+ {
+ context->error((yylsp[0]), "unsupported interpolation qualifier", "noperspective");
+ }
+ (yyval.interm.qualifier) = EvqNoPerspective;
+ }
+ break;
+
+ case 125: /* type_qualifier: single_type_qualifier */
+ {
+ (yyval.interm.typeQualifierBuilder) = context->createTypeQualifierBuilder((yylsp[0]));
+ (yyval.interm.typeQualifierBuilder)
+ ->appendQualifier((yyvsp[0].interm.qualifierWrapper));
+ }
+ break;
+
+ case 126: /* type_qualifier: type_qualifier single_type_qualifier */
+ {
+ (yyval.interm.typeQualifierBuilder) = (yyvsp[-1].interm.typeQualifierBuilder);
+ (yyval.interm.typeQualifierBuilder)
+ ->appendQualifier((yyvsp[0].interm.qualifierWrapper));
+ }
+ break;
+
+ case 127: /* invariant_qualifier: INVARIANT */
+ {
+ // empty
+ }
+ break;
+
+ case 128: /* precise_qualifier: PRECISE */
+ {
+ context->markShaderHasPrecise();
+ }
+ break;
+
+ case 129: /* single_type_qualifier: storage_qualifier */
+ {
+ context->checkLocalVariableConstStorageQualifier(*(yyvsp[0].interm.qualifierWrapper));
+ (yyval.interm.qualifierWrapper) = (yyvsp[0].interm.qualifierWrapper);
+ }
+ break;
+
+ case 130: /* single_type_qualifier: layout_qualifier */
+ {
+ context->checkIsAtGlobalLevel((yylsp[0]), "layout");
+ (yyval.interm.qualifierWrapper) =
+ new TLayoutQualifierWrapper((yyvsp[0].interm.layoutQualifier), (yylsp[0]));
+ }
+ break;
+
+ case 131: /* single_type_qualifier: precision_qualifier */
+ {
+ (yyval.interm.qualifierWrapper) =
+ new TPrecisionQualifierWrapper((yyvsp[0].interm.precision), (yylsp[0]));
+ }
+ break;
+
+ case 132: /* single_type_qualifier: interpolation_qualifier */
+ {
+ (yyval.interm.qualifierWrapper) =
+ new TInterpolationQualifierWrapper((yyvsp[0].interm.qualifier), (yylsp[0]));
+ }
+ break;
+
+ case 133: /* single_type_qualifier: invariant_qualifier */
+ {
+ context->checkIsAtGlobalLevel((yylsp[0]), "invariant");
+ (yyval.interm.qualifierWrapper) = new TInvariantQualifierWrapper((yylsp[0]));
+ }
+ break;
+
+ case 134: /* single_type_qualifier: precise_qualifier */
+ {
+ (yyval.interm.qualifierWrapper) = new TPreciseQualifierWrapper((yylsp[0]));
+ }
+ break;
+
+ case 135: /* storage_qualifier: ATTRIBUTE */
+ {
+ VERTEX_ONLY("attribute", (yylsp[0]));
+ ES2_ONLY("attribute", (yylsp[0]));
+ (yyval.interm.qualifierWrapper) =
+ context->parseGlobalStorageQualifier(EvqAttribute, (yylsp[0]));
+ }
+ break;
+
+ case 136: /* storage_qualifier: VARYING */
+ {
+ ES2_ONLY("varying", (yylsp[0]));
+ (yyval.interm.qualifierWrapper) = context->parseVaryingQualifier((yylsp[0]));
+ }
+ break;
+
+ case 137: /* storage_qualifier: CONST_QUAL */
+ {
+ (yyval.interm.qualifierWrapper) = new TStorageQualifierWrapper(EvqConst, (yylsp[0]));
+ }
+ break;
+
+ case 138: /* storage_qualifier: IN_QUAL */
+ {
+ (yyval.interm.qualifierWrapper) = context->parseInQualifier((yylsp[0]));
+ }
+ break;
+
+ case 139: /* storage_qualifier: OUT_QUAL */
+ {
+ (yyval.interm.qualifierWrapper) = context->parseOutQualifier((yylsp[0]));
+ }
+ break;
+
+ case 140: /* storage_qualifier: INOUT_QUAL */
+ {
+ (yyval.interm.qualifierWrapper) = context->parseInOutQualifier((yylsp[0]));
+ }
+ break;
+
+ case 141: /* storage_qualifier: CENTROID */
+ {
+ ES3_OR_NEWER("centroid", (yylsp[0]), "storage qualifier");
+ (yyval.interm.qualifierWrapper) = new TStorageQualifierWrapper(EvqCentroid, (yylsp[0]));
+ }
+ break;
+
+ case 142: /* storage_qualifier: PATCH */
+ {
+ if (context->getShaderVersion() < 320 &&
+ !context->checkCanUseExtension((yylsp[0]), TExtension::EXT_tessellation_shader))
+ {
+ context->error((yylsp[0]), "unsupported storage qualifier", "patch");
+ }
+ (yyval.interm.qualifierWrapper) = new TStorageQualifierWrapper(EvqPatch, (yylsp[0]));
+ }
+ break;
+
+ case 143: /* storage_qualifier: UNIFORM */
+ {
+ (yyval.interm.qualifierWrapper) =
+ context->parseGlobalStorageQualifier(EvqUniform, (yylsp[0]));
+ }
+ break;
+
+ case 144: /* storage_qualifier: BUFFER */
+ {
+ ES3_1_OR_NEWER("buffer", (yylsp[0]), "storage qualifier");
+ (yyval.interm.qualifierWrapper) =
+ context->parseGlobalStorageQualifier(EvqBuffer, (yylsp[0]));
+ }
+ break;
+
+ case 145: /* storage_qualifier: READONLY */
+ {
+ (yyval.interm.qualifierWrapper) = new TMemoryQualifierWrapper(EvqReadOnly, (yylsp[0]));
+ }
+ break;
+
+ case 146: /* storage_qualifier: WRITEONLY */
+ {
+ (yyval.interm.qualifierWrapper) = new TMemoryQualifierWrapper(EvqWriteOnly, (yylsp[0]));
+ }
+ break;
+
+ case 147: /* storage_qualifier: COHERENT */
+ {
+ (yyval.interm.qualifierWrapper) = new TMemoryQualifierWrapper(EvqCoherent, (yylsp[0]));
+ }
+ break;
+
+ case 148: /* storage_qualifier: RESTRICT */
+ {
+ (yyval.interm.qualifierWrapper) = new TMemoryQualifierWrapper(EvqRestrict, (yylsp[0]));
+ }
+ break;
+
+ case 149: /* storage_qualifier: VOLATILE */
+ {
+ (yyval.interm.qualifierWrapper) = new TMemoryQualifierWrapper(EvqVolatile, (yylsp[0]));
+ }
+ break;
+
+ case 150: /* storage_qualifier: SHARED */
+ {
+ COMPUTE_ONLY("shared", (yylsp[0]));
+ (yyval.interm.qualifierWrapper) =
+ context->parseGlobalStorageQualifier(EvqShared, (yylsp[0]));
+ }
+ break;
+
+ case 151: /* storage_qualifier: SAMPLE */
+ {
+ ES3_OR_NEWER("sample", (yylsp[0]), "storage qualifier");
+ (yyval.interm.qualifierWrapper) = new TStorageQualifierWrapper(EvqSample, (yylsp[0]));
+ }
+ break;
+
+ case 152: /* type_specifier: type_specifier_no_prec */
+ {
+ (yyval.interm.type) = (yyvsp[0].interm.type);
+ (yyval.interm.type).precision =
+ context->symbolTable.getDefaultPrecision((yyvsp[0].interm.type).getBasicType());
+ }
+ break;
+
+ case 153: /* precision_qualifier: HIGH_PRECISION */
+ {
+ (yyval.interm.precision) = EbpHigh;
+ }
+ break;
+
+ case 154: /* precision_qualifier: MEDIUM_PRECISION */
+ {
+ (yyval.interm.precision) = EbpMedium;
+ }
+ break;
+
+ case 155: /* precision_qualifier: LOW_PRECISION */
+ {
+ (yyval.interm.precision) = EbpLow;
+ }
+ break;
+
+ case 156: /* layout_qualifier: LAYOUT LEFT_PAREN layout_qualifier_id_list RIGHT_PAREN */
+ {
+ context->checkCanUseLayoutQualifier((yylsp[-3]));
+ (yyval.interm.layoutQualifier) = (yyvsp[-1].interm.layoutQualifier);
+ }
+ break;
+
+ case 157: /* layout_qualifier_id_list: layout_qualifier_id */
+ {
+ (yyval.interm.layoutQualifier) = (yyvsp[0].interm.layoutQualifier);
+ }
+ break;
+
+ case 158: /* layout_qualifier_id_list: layout_qualifier_id_list COMMA layout_qualifier_id */
+ {
+ (yyval.interm.layoutQualifier) = context->joinLayoutQualifiers(
+ (yyvsp[-2].interm.layoutQualifier), (yyvsp[0].interm.layoutQualifier), (yylsp[0]));
+ }
+ break;
+
+ case 159: /* layout_qualifier_id: IDENTIFIER */
+ {
+ (yyval.interm.layoutQualifier) =
+ context->parseLayoutQualifier(ImmutableString((yyvsp[0].lex).string), (yylsp[0]));
+ }
+ break;
+
+ case 160: /* layout_qualifier_id: IDENTIFIER EQUAL INTCONSTANT */
+ {
+ (yyval.interm.layoutQualifier) = context->parseLayoutQualifier(
+ ImmutableString((yyvsp[-2].lex).string), (yylsp[-2]), (yyvsp[0].lex).i, (yylsp[0]));
+ }
+ break;
+
+ case 161: /* layout_qualifier_id: IDENTIFIER EQUAL UINTCONSTANT */
+ {
+ (yyval.interm.layoutQualifier) = context->parseLayoutQualifier(
+ ImmutableString((yyvsp[-2].lex).string), (yylsp[-2]), (yyvsp[0].lex).i, (yylsp[0]));
+ }
+ break;
+
+ case 162: /* layout_qualifier_id: SHARED */
+ {
+ (yyval.interm.layoutQualifier) =
+ context->parseLayoutQualifier(ImmutableString("shared"), (yylsp[0]));
+ }
+ break;
+
+ case 163: /* type_specifier_no_prec: type_specifier_nonarray */
+ {
+ (yyval.interm.type)
+ .initialize((yyvsp[0].interm.typeSpecifierNonArray),
+ (context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary));
+ }
+ break;
+
+ case 164: /* type_specifier_no_prec: type_specifier_nonarray array_specifier */
+ {
+ (yyval.interm.type)
+ .initialize((yyvsp[-1].interm.typeSpecifierNonArray),
+ (context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary));
+ (yyval.interm.type).setArraySizes((yyvsp[0].interm.arraySizes));
+ }
+ break;
+
+ case 165: /* array_specifier: LEFT_BRACKET RIGHT_BRACKET */
+ {
+ ES3_OR_NEWER("[]", (yylsp[-1]), "implicitly sized array");
+ (yyval.interm.arraySizes) = new TVector<unsigned int>();
+ (yyval.interm.arraySizes)->push_back(0u);
+ }
+ break;
+
+ case 166: /* array_specifier: LEFT_BRACKET constant_expression RIGHT_BRACKET */
+ {
+ (yyval.interm.arraySizes) = new TVector<unsigned int>();
+ unsigned int size =
+ context->checkIsValidArraySize((yylsp[-2]), (yyvsp[-1].interm.intermTypedNode));
+ // Make the type an array even if size check failed.
+ // This ensures useless error messages regarding a variable's non-arrayness won't
+ // follow.
+ (yyval.interm.arraySizes)->push_back(size);
+ }
+ break;
+
+ case 167: /* array_specifier: array_specifier LEFT_BRACKET RIGHT_BRACKET */
+ {
+ ES3_1_OR_NEWER("[]", (yylsp[-1]), "arrays of arrays");
+ (yyval.interm.arraySizes) = (yyvsp[-2].interm.arraySizes);
+ (yyval.interm.arraySizes)->insert((yyval.interm.arraySizes)->begin(), 0u);
+ }
+ break;
+
+ case 168: /* array_specifier: array_specifier LEFT_BRACKET constant_expression RIGHT_BRACKET
+ */
+ {
+ ES3_1_OR_NEWER("[]", (yylsp[-2]), "arrays of arrays");
+ (yyval.interm.arraySizes) = (yyvsp[-3].interm.arraySizes);
+ unsigned int size =
+ context->checkIsValidArraySize((yylsp[-2]), (yyvsp[-1].interm.intermTypedNode));
+ // Make the type an array even if size check failed.
+ // This ensures useless error messages regarding a variable's non-arrayness won't
+ // follow.
+ (yyval.interm.arraySizes)->insert((yyval.interm.arraySizes)->begin(), size);
+ }
+ break;
+
+ case 169: /* type_specifier_nonarray: VOID_TYPE */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtVoid, (yylsp[0]));
+ }
+ break;
+
+ case 170: /* type_specifier_nonarray: FLOAT_TYPE */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
+ }
+ break;
+
+ case 171: /* type_specifier_nonarray: INT_TYPE */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtInt, (yylsp[0]));
+ }
+ break;
+
+ case 172: /* type_specifier_nonarray: UINT_TYPE */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtUInt, (yylsp[0]));
+ }
+ break;
+
+ case 173: /* type_specifier_nonarray: BOOL_TYPE */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtBool, (yylsp[0]));
+ }
+ break;
+
+ case 174: /* type_specifier_nonarray: VEC2 */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
+ (yyval.interm.typeSpecifierNonArray).setAggregate(2);
+ }
+ break;
+
+ case 175: /* type_specifier_nonarray: VEC3 */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
+ (yyval.interm.typeSpecifierNonArray).setAggregate(3);
+ }
+ break;
+
+ case 176: /* type_specifier_nonarray: VEC4 */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
+ (yyval.interm.typeSpecifierNonArray).setAggregate(4);
+ }
+ break;
+
+ case 177: /* type_specifier_nonarray: BVEC2 */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtBool, (yylsp[0]));
+ (yyval.interm.typeSpecifierNonArray).setAggregate(2);
+ }
+ break;
+
+ case 178: /* type_specifier_nonarray: BVEC3 */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtBool, (yylsp[0]));
+ (yyval.interm.typeSpecifierNonArray).setAggregate(3);
+ }
+ break;
+
+ case 179: /* type_specifier_nonarray: BVEC4 */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtBool, (yylsp[0]));
+ (yyval.interm.typeSpecifierNonArray).setAggregate(4);
+ }
+ break;
+
+ case 180: /* type_specifier_nonarray: IVEC2 */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtInt, (yylsp[0]));
+ (yyval.interm.typeSpecifierNonArray).setAggregate(2);
+ }
+ break;
+
+ case 181: /* type_specifier_nonarray: IVEC3 */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtInt, (yylsp[0]));
+ (yyval.interm.typeSpecifierNonArray).setAggregate(3);
+ }
+ break;
+
+ case 182: /* type_specifier_nonarray: IVEC4 */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtInt, (yylsp[0]));
+ (yyval.interm.typeSpecifierNonArray).setAggregate(4);
+ }
+ break;
+
+ case 183: /* type_specifier_nonarray: UVEC2 */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtUInt, (yylsp[0]));
+ (yyval.interm.typeSpecifierNonArray).setAggregate(2);
+ }
+ break;
+
+ case 184: /* type_specifier_nonarray: UVEC3 */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtUInt, (yylsp[0]));
+ (yyval.interm.typeSpecifierNonArray).setAggregate(3);
+ }
+ break;
+
+ case 185: /* type_specifier_nonarray: UVEC4 */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtUInt, (yylsp[0]));
+ (yyval.interm.typeSpecifierNonArray).setAggregate(4);
+ }
+ break;
+
+ case 186: /* type_specifier_nonarray: MATRIX2 */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
+ (yyval.interm.typeSpecifierNonArray).setMatrix(2, 2);
+ }
+ break;
+
+ case 187: /* type_specifier_nonarray: MATRIX3 */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
+ (yyval.interm.typeSpecifierNonArray).setMatrix(3, 3);
+ }
+ break;
+
+ case 188: /* type_specifier_nonarray: MATRIX4 */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
+ (yyval.interm.typeSpecifierNonArray).setMatrix(4, 4);
+ }
+ break;
+
+ case 189: /* type_specifier_nonarray: MATRIX2x3 */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
+ (yyval.interm.typeSpecifierNonArray).setMatrix(2, 3);
+ }
+ break;
+
+ case 190: /* type_specifier_nonarray: MATRIX3x2 */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
+ (yyval.interm.typeSpecifierNonArray).setMatrix(3, 2);
+ }
+ break;
+
+ case 191: /* type_specifier_nonarray: MATRIX2x4 */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
+ (yyval.interm.typeSpecifierNonArray).setMatrix(2, 4);
+ }
+ break;
+
+ case 192: /* type_specifier_nonarray: MATRIX4x2 */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
+ (yyval.interm.typeSpecifierNonArray).setMatrix(4, 2);
+ }
+ break;
+
+ case 193: /* type_specifier_nonarray: MATRIX3x4 */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
+ (yyval.interm.typeSpecifierNonArray).setMatrix(3, 4);
+ }
+ break;
+
+ case 194: /* type_specifier_nonarray: MATRIX4x3 */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtFloat, (yylsp[0]));
+ (yyval.interm.typeSpecifierNonArray).setMatrix(4, 3);
+ }
+ break;
+
+ case 195: /* type_specifier_nonarray: YUVCSCSTANDARDEXT */
+ {
+ if (!context->checkCanUseExtension((yylsp[0]), TExtension::EXT_YUV_target))
+ {
+ context->error((yylsp[0]), "unsupported type", "yuvCscStandardEXT");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtYuvCscStandardEXT, (yylsp[0]));
+ }
+ break;
+
+ case 196: /* type_specifier_nonarray: SAMPLER2D */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtSampler2D, (yylsp[0]));
+ }
+ break;
+
+ case 197: /* type_specifier_nonarray: SAMPLER3D */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtSampler3D, (yylsp[0]));
+ }
+ break;
+
+ case 198: /* type_specifier_nonarray: SAMPLERCUBE */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtSamplerCube, (yylsp[0]));
+ }
+ break;
+
+ case 199: /* type_specifier_nonarray: SAMPLER2DARRAY */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtSampler2DArray, (yylsp[0]));
+ }
+ break;
+
+ case 200: /* type_specifier_nonarray: SAMPLER2DMS */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtSampler2DMS, (yylsp[0]));
+ }
+ break;
+
+ case 201: /* type_specifier_nonarray: SAMPLER2DMSARRAY */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtSampler2DMSArray, (yylsp[0]));
+ }
+ break;
+
+ case 202: /* type_specifier_nonarray: SAMPLERCUBEARRAYOES */
+ {
+ if (context->getShaderVersion() < 320 &&
+ !context->checkCanUseExtension((yylsp[0]), TExtension::OES_texture_cube_map_array))
+ {
+ context->error((yylsp[0]), "unsupported type", "__samplerCubeArray");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtSamplerCubeArray, (yylsp[0]));
+ }
+ break;
+
+ case 203: /* type_specifier_nonarray: SAMPLERCUBEARRAYEXT */
+ {
+ if (context->getShaderVersion() < 320 &&
+ !context->checkCanUseExtension((yylsp[0]), TExtension::EXT_texture_cube_map_array))
+ {
+ context->error((yylsp[0]), "unsupported type", "__samplerCubeArray");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtSamplerCubeArray, (yylsp[0]));
+ }
+ break;
+
+ case 204: /* type_specifier_nonarray: SAMPLERBUFFER */
+ {
+ constexpr std::array<TExtension, 2u> extensions{
+ {TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer}};
+ if (context->getShaderVersion() < 320 &&
+ !context->checkCanUseOneOfExtensions((yylsp[0]), extensions))
+ {
+ context->error((yylsp[0]), "unsupported type", "__samplerBuffer");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtSamplerBuffer, (yylsp[0]));
+ }
+ break;
+
+ case 205: /* type_specifier_nonarray: ISAMPLER2D */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtISampler2D, (yylsp[0]));
+ }
+ break;
+
+ case 206: /* type_specifier_nonarray: ISAMPLER3D */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtISampler3D, (yylsp[0]));
+ }
+ break;
+
+ case 207: /* type_specifier_nonarray: ISAMPLERCUBE */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtISamplerCube, (yylsp[0]));
+ }
+ break;
+
+ case 208: /* type_specifier_nonarray: ISAMPLER2DARRAY */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtISampler2DArray, (yylsp[0]));
+ }
+ break;
+
+ case 209: /* type_specifier_nonarray: ISAMPLER2DMS */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtISampler2DMS, (yylsp[0]));
+ }
+ break;
+
+ case 210: /* type_specifier_nonarray: ISAMPLER2DMSARRAY */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtISampler2DMSArray, (yylsp[0]));
+ }
+ break;
+
+ case 211: /* type_specifier_nonarray: ISAMPLERCUBEARRAYOES */
+ {
+ if (context->getShaderVersion() < 320 &&
+ !context->checkCanUseExtension((yylsp[0]), TExtension::OES_texture_cube_map_array))
+ {
+ context->error((yylsp[0]), "unsupported type", "__isamplerCubeArray");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtISamplerCubeArray, (yylsp[0]));
+ }
+ break;
+
+ case 212: /* type_specifier_nonarray: ISAMPLERCUBEARRAYEXT */
+ {
+ if (context->getShaderVersion() < 320 &&
+ !context->checkCanUseExtension((yylsp[0]), TExtension::EXT_texture_cube_map_array))
+ {
+ context->error((yylsp[0]), "unsupported type", "__isamplerCubeArray");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtISamplerCubeArray, (yylsp[0]));
+ }
+ break;
+
+ case 213: /* type_specifier_nonarray: ISAMPLERBUFFER */
+ {
+ constexpr std::array<TExtension, 2u> extensions{
+ {TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer}};
+ if (context->getShaderVersion() < 320 &&
+ !context->checkCanUseOneOfExtensions((yylsp[0]), extensions))
+ {
+ context->error((yylsp[0]), "unsupported type", "__isamplerBuffer");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtISamplerBuffer, (yylsp[0]));
+ }
+ break;
+
+ case 214: /* type_specifier_nonarray: USAMPLER2D */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtUSampler2D, (yylsp[0]));
+ }
+ break;
+
+ case 215: /* type_specifier_nonarray: USAMPLER3D */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtUSampler3D, (yylsp[0]));
+ }
+ break;
+
+ case 216: /* type_specifier_nonarray: USAMPLERCUBE */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtUSamplerCube, (yylsp[0]));
+ }
+ break;
+
+ case 217: /* type_specifier_nonarray: USAMPLER2DARRAY */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtUSampler2DArray, (yylsp[0]));
+ }
+ break;
+
+ case 218: /* type_specifier_nonarray: USAMPLER2DMS */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtUSampler2DMS, (yylsp[0]));
+ }
+ break;
+
+ case 219: /* type_specifier_nonarray: USAMPLER2DMSARRAY */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtUSampler2DMSArray, (yylsp[0]));
+ }
+ break;
+
+ case 220: /* type_specifier_nonarray: USAMPLERCUBEARRAYOES */
+ {
+ if (context->getShaderVersion() < 320 &&
+ !context->checkCanUseExtension((yylsp[0]), TExtension::OES_texture_cube_map_array))
+ {
+ context->error((yylsp[0]), "unsupported type", "__usamplerCubeArray");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtUSamplerCubeArray, (yylsp[0]));
+ }
+ break;
+
+ case 221: /* type_specifier_nonarray: USAMPLERCUBEARRAYEXT */
+ {
+ if (context->getShaderVersion() < 320 &&
+ !context->checkCanUseExtension((yylsp[0]), TExtension::EXT_texture_cube_map_array))
+ {
+ context->error((yylsp[0]), "unsupported type", "__usamplerCubeArray");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtUSamplerCubeArray, (yylsp[0]));
+ }
+ break;
+
+ case 222: /* type_specifier_nonarray: USAMPLERBUFFER */
+ {
+ constexpr std::array<TExtension, 2u> extensions{
+ {TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer}};
+ if (context->getShaderVersion() < 320 &&
+ !context->checkCanUseOneOfExtensions((yylsp[0]), extensions))
+ {
+ context->error((yylsp[0]), "unsupported type", "__usamplerBuffer");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtUSamplerBuffer, (yylsp[0]));
+ }
+ break;
+
+ case 223: /* type_specifier_nonarray: SAMPLER2DSHADOW */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtSampler2DShadow, (yylsp[0]));
+ }
+ break;
+
+ case 224: /* type_specifier_nonarray: SAMPLERCUBESHADOW */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtSamplerCubeShadow, (yylsp[0]));
+ }
+ break;
+
+ case 225: /* type_specifier_nonarray: SAMPLER2DARRAYSHADOW */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtSampler2DArrayShadow, (yylsp[0]));
+ }
+ break;
+
+ case 226: /* type_specifier_nonarray: SAMPLERCUBEARRAYSHADOWOES */
+ {
+ if (context->getShaderVersion() < 320 &&
+ !context->checkCanUseExtension((yylsp[0]), TExtension::OES_texture_cube_map_array))
+ {
+ context->error((yylsp[0]), "unsupported type", "__samplerCubeArrayShadow");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtSamplerCubeArrayShadow, (yylsp[0]));
+ }
+ break;
+
+ case 227: /* type_specifier_nonarray: SAMPLERCUBEARRAYSHADOWEXT */
+ {
+ if (context->getShaderVersion() < 320 &&
+ !context->checkCanUseExtension((yylsp[0]), TExtension::EXT_texture_cube_map_array))
+ {
+ context->error((yylsp[0]), "unsupported type", "__samplerCubeArrayShadow");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtSamplerCubeArrayShadow, (yylsp[0]));
+ }
+ break;
+
+ case 228: /* type_specifier_nonarray: SAMPLERVIDEOWEBGL */
+ {
+ if (!context->checkCanUseExtension((yylsp[0]), TExtension::WEBGL_video_texture))
+ {
+ context->error((yylsp[0]), "unsupported type", "samplerVideoWEBGL");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtSamplerVideoWEBGL, (yylsp[0]));
+ }
+ break;
+
+ case 229: /* type_specifier_nonarray: SAMPLER_EXTERNAL_OES */
+ {
+ constexpr std::array<TExtension, 3u> extensions{
+ {TExtension::NV_EGL_stream_consumer_external,
+ TExtension::OES_EGL_image_external_essl3, TExtension::OES_EGL_image_external}};
+ if (!context->checkCanUseOneOfExtensions((yylsp[0]), extensions))
+ {
+ context->error((yylsp[0]), "unsupported type", "samplerExternalOES");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtSamplerExternalOES, (yylsp[0]));
+ }
+ break;
+
+ case 230: /* type_specifier_nonarray: SAMPLEREXTERNAL2DY2YEXT */
+ {
+ if (!context->checkCanUseExtension((yylsp[0]), TExtension::EXT_YUV_target))
+ {
+ context->error((yylsp[0]), "unsupported type", "__samplerExternal2DY2YEXT");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtSamplerExternal2DY2YEXT, (yylsp[0]));
+ }
+ break;
+
+ case 231: /* type_specifier_nonarray: SAMPLER2DRECT */
+ {
+ if (!context->checkCanUseExtension((yylsp[0]), TExtension::ARB_texture_rectangle))
+ {
+ context->error((yylsp[0]), "unsupported type", "sampler2DRect");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtSampler2DRect, (yylsp[0]));
+ }
+ break;
+
+ case 232: /* type_specifier_nonarray: IMAGE2D */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtImage2D, (yylsp[0]));
+ }
+ break;
+
+ case 233: /* type_specifier_nonarray: IIMAGE2D */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtIImage2D, (yylsp[0]));
+ }
+ break;
+
+ case 234: /* type_specifier_nonarray: UIMAGE2D */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtUImage2D, (yylsp[0]));
+ }
+ break;
+
+ case 235: /* type_specifier_nonarray: IMAGE3D */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtImage3D, (yylsp[0]));
+ }
+ break;
+
+ case 236: /* type_specifier_nonarray: IIMAGE3D */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtIImage3D, (yylsp[0]));
+ }
+ break;
+
+ case 237: /* type_specifier_nonarray: UIMAGE3D */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtUImage3D, (yylsp[0]));
+ }
+ break;
+
+ case 238: /* type_specifier_nonarray: IMAGE2DARRAY */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtImage2DArray, (yylsp[0]));
+ }
+ break;
+
+ case 239: /* type_specifier_nonarray: IIMAGE2DARRAY */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtIImage2DArray, (yylsp[0]));
+ }
+ break;
+
+ case 240: /* type_specifier_nonarray: UIMAGE2DARRAY */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtUImage2DArray, (yylsp[0]));
+ }
+ break;
+
+ case 241: /* type_specifier_nonarray: IMAGECUBE */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtImageCube, (yylsp[0]));
+ }
+ break;
+
+ case 242: /* type_specifier_nonarray: IIMAGECUBE */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtIImageCube, (yylsp[0]));
+ }
+ break;
+
+ case 243: /* type_specifier_nonarray: UIMAGECUBE */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtUImageCube, (yylsp[0]));
+ }
+ break;
+
+ case 244: /* type_specifier_nonarray: IMAGECUBEARRAYOES */
+ {
+ if (context->getShaderVersion() < 320 &&
+ !context->checkCanUseExtension((yylsp[0]), TExtension::OES_texture_cube_map_array))
+ {
+ context->error((yylsp[0]), "unsupported type", "__imageCubeArray");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtImageCubeArray, (yylsp[0]));
+ }
+ break;
+
+ case 245: /* type_specifier_nonarray: IMAGECUBEARRAYEXT */
+ {
+ if (context->getShaderVersion() < 320 &&
+ !context->checkCanUseExtension((yylsp[0]), TExtension::EXT_texture_cube_map_array))
+ {
+ context->error((yylsp[0]), "unsupported type", "__imageCubeArray");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtImageCubeArray, (yylsp[0]));
+ }
+ break;
+
+ case 246: /* type_specifier_nonarray: IIMAGECUBEARRAYOES */
+ {
+ if (context->getShaderVersion() < 320 &&
+ !context->checkCanUseExtension((yylsp[0]), TExtension::OES_texture_cube_map_array))
+ {
+ context->error((yylsp[0]), "unsupported type", "__iimageCubeArray");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtIImageCubeArray, (yylsp[0]));
+ }
+ break;
+
+ case 247: /* type_specifier_nonarray: IIMAGECUBEARRAYEXT */
+ {
+ if (context->getShaderVersion() < 320 &&
+ !context->checkCanUseExtension((yylsp[0]), TExtension::EXT_texture_cube_map_array))
+ {
+ context->error((yylsp[0]), "unsupported type", "__iimageCubeArray");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtIImageCubeArray, (yylsp[0]));
+ }
+ break;
+
+ case 248: /* type_specifier_nonarray: UIMAGECUBEARRAYOES */
+ {
+ if (context->getShaderVersion() < 320 &&
+ !context->checkCanUseExtension((yylsp[0]), TExtension::OES_texture_cube_map_array))
+ {
+ context->error((yylsp[0]), "unsupported type", "__uimageCubeArray");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtUImageCubeArray, (yylsp[0]));
+ }
+ break;
+
+ case 249: /* type_specifier_nonarray: UIMAGECUBEARRAYEXT */
+ {
+ if (context->getShaderVersion() < 320 &&
+ !context->checkCanUseExtension((yylsp[0]), TExtension::EXT_texture_cube_map_array))
+ {
+ context->error((yylsp[0]), "unsupported type", "__uimageCubeArray");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtUImageCubeArray, (yylsp[0]));
+ }
+ break;
+
+ case 250: /* type_specifier_nonarray: IMAGEBUFFER */
+ {
+ constexpr std::array<TExtension, 2u> extensions{
+ {TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer}};
+ if (context->getShaderVersion() < 320 &&
+ !context->checkCanUseOneOfExtensions((yylsp[0]), extensions))
+ {
+ context->error((yylsp[0]), "unsupported type", "__imageBuffer");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtImageBuffer, (yylsp[0]));
+ }
+ break;
+
+ case 251: /* type_specifier_nonarray: IIMAGEBUFFER */
+ {
+ constexpr std::array<TExtension, 2u> extensions{
+ {TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer}};
+ if (context->getShaderVersion() < 320 &&
+ !context->checkCanUseOneOfExtensions((yylsp[0]), extensions))
+ {
+ context->error((yylsp[0]), "unsupported type", "__iimageBuffer");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtIImageBuffer, (yylsp[0]));
+ }
+ break;
+
+ case 252: /* type_specifier_nonarray: UIMAGEBUFFER */
+ {
+ constexpr std::array<TExtension, 2u> extensions{
+ {TExtension::OES_texture_buffer, TExtension::EXT_texture_buffer}};
+ if (context->getShaderVersion() < 320 &&
+ !context->checkCanUseOneOfExtensions((yylsp[0]), extensions))
+ {
+ context->error((yylsp[0]), "unsupported type", "__uimageBuffer");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtUImageBuffer, (yylsp[0]));
+ }
+ break;
+
+ case 253: /* type_specifier_nonarray: ATOMICUINT */
+ {
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtAtomicCounter, (yylsp[0]));
+ }
+ break;
+
+ case 254: /* type_specifier_nonarray: PIXELLOCALANGLE */
+ {
+ if (!context->checkCanUseExtension((yylsp[0]),
+ TExtension::ANGLE_shader_pixel_local_storage))
+ {
+ context->error((yylsp[0]), "unsupported type", "__pixelLocalANGLE");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtPixelLocalANGLE, (yylsp[0]));
+ }
+ break;
+
+ case 255: /* type_specifier_nonarray: IPIXELLOCALANGLE */
+ {
+ if (!context->checkCanUseExtension((yylsp[0]),
+ TExtension::ANGLE_shader_pixel_local_storage))
+ {
+ context->error((yylsp[0]), "unsupported type", "__ipixelLocalANGLE");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtIPixelLocalANGLE, (yylsp[0]));
+ }
+ break;
+
+ case 256: /* type_specifier_nonarray: UPIXELLOCALANGLE */
+ {
+ if (!context->checkCanUseExtension((yylsp[0]),
+ TExtension::ANGLE_shader_pixel_local_storage))
+ {
+ context->error((yylsp[0]), "unsupported type", "__upixelLocalANGLE");
+ }
+ (yyval.interm.typeSpecifierNonArray).initialize(EbtUPixelLocalANGLE, (yylsp[0]));
+ }
+ break;
+
+ case 257: /* type_specifier_nonarray: struct_specifier */
+ {
+ (yyval.interm.typeSpecifierNonArray) = (yyvsp[0].interm.typeSpecifierNonArray);
+ }
+ break;
+
+ case 258: /* type_specifier_nonarray: TYPE_NAME */
+ {
+ // This is for user defined type names. The lexical phase looked up the type.
+ const TStructure *structure = static_cast<const TStructure *>((yyvsp[0].lex).symbol);
+ (yyval.interm.typeSpecifierNonArray).initializeStruct(structure, false, (yylsp[0]));
+ }
+ break;
+
+ case 259: /* $@1: %empty */
+ {
+ context->enterStructDeclaration((yylsp[-1]), ImmutableString((yyvsp[-1].lex).string));
+ }
+ break;
+
+ case 260: /* struct_specifier: STRUCT identifier LEFT_BRACE $@1 struct_declaration_list
+ RIGHT_BRACE */
+ {
+ (yyval.interm.typeSpecifierNonArray) = context->addStructure(
+ (yylsp[-5]), (yylsp[-4]), ImmutableString((yyvsp[-4].lex).string),
+ (yyvsp[-1].interm.fieldList));
+ }
+ break;
+
+ case 261: /* $@2: %empty */
+ {
+ context->enterStructDeclaration((yylsp[0]), kEmptyImmutableString);
+ }
+ break;
+
+ case 262: /* struct_specifier: STRUCT LEFT_BRACE $@2 struct_declaration_list RIGHT_BRACE */
+ {
+ (yyval.interm.typeSpecifierNonArray) = context->addStructure(
+ (yylsp[-4]), (yyloc), kEmptyImmutableString, (yyvsp[-1].interm.fieldList));
+ }
+ break;
+
+ case 263: /* struct_declaration_list: struct_declaration */
+ {
+ (yyval.interm.fieldList) =
+ context->addStructFieldList((yyvsp[0].interm.fieldList), (yylsp[0]));
+ }
+ break;
+
+ case 264: /* struct_declaration_list: struct_declaration_list struct_declaration */
+ {
+ (yyval.interm.fieldList) = context->combineStructFieldLists(
+ (yyvsp[-1].interm.fieldList), (yyvsp[0].interm.fieldList), (yylsp[0]));
+ }
+ break;
+
+ case 265: /* struct_declaration: type_specifier struct_declarator_list SEMICOLON */
+ {
+ (yyval.interm.fieldList) = context->addStructDeclaratorList(
+ (yyvsp[-2].interm.type), (yyvsp[-1].interm.declaratorList));
+ }
+ break;
+
+ case 266: /* struct_declaration: type_qualifier type_specifier struct_declarator_list
+ SEMICOLON */
+ {
+ // ES3 Only, but errors should be handled elsewhere
+ (yyval.interm.fieldList) = context->addStructDeclaratorListWithQualifiers(
+ *(yyvsp[-3].interm.typeQualifierBuilder), &(yyvsp[-2].interm.type),
+ (yyvsp[-1].interm.declaratorList));
+ }
+ break;
+
+ case 267: /* struct_declarator_list: struct_declarator */
+ {
+ (yyval.interm.declaratorList) = new TDeclaratorList();
+ (yyval.interm.declaratorList)->push_back((yyvsp[0].interm.declarator));
+ }
+ break;
+
+ case 268: /* struct_declarator_list: struct_declarator_list COMMA struct_declarator */
+ {
+ (yyval.interm.declaratorList)->push_back((yyvsp[0].interm.declarator));
+ }
+ break;
+
+ case 269: /* struct_declarator: identifier */
+ {
+ (yyval.interm.declarator) =
+ context->parseStructDeclarator(ImmutableString((yyvsp[0].lex).string), (yylsp[0]));
+ }
+ break;
+
+ case 270: /* struct_declarator: identifier array_specifier */
+ {
+ (yyval.interm.declarator) = context->parseStructArrayDeclarator(
+ ImmutableString((yyvsp[-1].lex).string), (yylsp[-1]), (yyvsp[0].interm.arraySizes));
+ }
+ break;
+
+ case 271: /* initializer: assignment_expression */
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 272: /* declaration_statement: declaration */
+ {
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
+ }
+ break;
+
+ case 273: /* statement: compound_statement_with_scope */
+ {
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermBlock);
+ }
+ break;
+
+ case 274: /* statement: simple_statement */
+ {
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
+ }
+ break;
+
+ case 275: /* simple_statement: declaration_statement */
+ {
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
+ }
+ break;
+
+ case 276: /* simple_statement: expression_statement */
+ {
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
+ }
+ break;
+
+ case 277: /* simple_statement: selection_statement */
+ {
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
+ }
+ break;
+
+ case 278: /* simple_statement: switch_statement */
+ {
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermSwitch);
+ }
+ break;
+
+ case 279: /* simple_statement: case_label */
+ {
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermCase);
+ }
+ break;
+
+ case 280: /* simple_statement: iteration_statement */
+ {
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
+ }
+ break;
+
+ case 281: /* simple_statement: jump_statement */
+ {
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
+ }
+ break;
+
+ case 282: /* compound_statement_with_scope: LEFT_BRACE RIGHT_BRACE */
+ {
+ (yyval.interm.intermBlock) = new TIntermBlock();
+ (yyval.interm.intermBlock)->setLine((yyloc));
+ }
+ break;
+
+ case 283: /* $@3: %empty */
+ {
+ context->symbolTable.push();
+ }
+ break;
+
+ case 284: /* $@4: %empty */
+ {
+ context->symbolTable.pop();
+ }
+ break;
+
+ case 285: /* compound_statement_with_scope: LEFT_BRACE $@3 statement_list $@4 RIGHT_BRACE */
+ {
+ (yyvsp[-2].interm.intermBlock)->setLine((yyloc));
+ (yyval.interm.intermBlock) = (yyvsp[-2].interm.intermBlock);
+ }
+ break;
+
+ case 286: /* statement_no_new_scope: compound_statement_no_new_scope */
+ {
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermBlock);
+ }
+ break;
+
+ case 287: /* statement_no_new_scope: simple_statement */
+ {
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
+ }
+ break;
+
+ case 288: /* $@5: %empty */
+ {
+ context->symbolTable.push();
+ }
+ break;
+
+ case 289: /* statement_with_scope: $@5 compound_statement_no_new_scope */
+ {
+ context->symbolTable.pop();
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermBlock);
+ }
+ break;
+
+ case 290: /* $@6: %empty */
+ {
+ context->symbolTable.push();
+ }
+ break;
+
+ case 291: /* statement_with_scope: $@6 simple_statement */
+ {
+ context->symbolTable.pop();
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
+ }
+ break;
+
+ case 292: /* compound_statement_no_new_scope: LEFT_BRACE RIGHT_BRACE */
+ {
+ (yyval.interm.intermBlock) = new TIntermBlock();
+ (yyval.interm.intermBlock)->setLine((yyloc));
+ }
+ break;
+
+ case 293: /* compound_statement_no_new_scope: LEFT_BRACE statement_list RIGHT_BRACE */
+ {
+ (yyvsp[-1].interm.intermBlock)->setLine((yyloc));
+ (yyval.interm.intermBlock) = (yyvsp[-1].interm.intermBlock);
+ }
+ break;
+
+ case 294: /* statement_list: statement */
+ {
+ (yyval.interm.intermBlock) = new TIntermBlock();
+ context->appendStatement((yyval.interm.intermBlock), (yyvsp[0].interm.intermNode));
+ }
+ break;
+
+ case 295: /* statement_list: statement_list statement */
+ {
+ (yyval.interm.intermBlock) = (yyvsp[-1].interm.intermBlock);
+ context->appendStatement((yyval.interm.intermBlock), (yyvsp[0].interm.intermNode));
+ }
+ break;
+
+ case 296: /* expression_statement: SEMICOLON */
+ {
+ (yyval.interm.intermNode) = context->addEmptyStatement((yyloc));
+ }
+ break;
+
+ case 297: /* expression_statement: expression SEMICOLON */
+ {
+ (yyval.interm.intermNode) = (yyvsp[-1].interm.intermTypedNode);
+ }
+ break;
+
+ case 298: /* selection_statement: IF LEFT_PAREN expression RIGHT_PAREN
+ selection_rest_statement */
+ {
+ (yyval.interm.intermNode) = context->addIfElse((yyvsp[-2].interm.intermTypedNode),
+ (yyvsp[0].interm.nodePair), (yylsp[-4]));
+ }
+ break;
+
+ case 299: /* selection_rest_statement: statement_with_scope ELSE statement_with_scope */
+ {
+ (yyval.interm.nodePair).node1 = (yyvsp[-2].interm.intermNode);
+ (yyval.interm.nodePair).node2 = (yyvsp[0].interm.intermNode);
+ }
+ break;
+
+ case 300: /* selection_rest_statement: statement_with_scope */
+ {
+ (yyval.interm.nodePair).node1 = (yyvsp[0].interm.intermNode);
+ (yyval.interm.nodePair).node2 = nullptr;
+ }
+ break;
+
+ case 301: /* $@7: %empty */
+ {
+ context->incrSwitchNestingLevel();
+ }
+ break;
+
+ case 302: /* switch_statement: SWITCH LEFT_PAREN expression RIGHT_PAREN $@7
+ compound_statement_with_scope */
+ {
+ (yyval.interm.intermSwitch) = context->addSwitch(
+ (yyvsp[-3].interm.intermTypedNode), (yyvsp[0].interm.intermBlock), (yylsp[-5]));
+ context->decrSwitchNestingLevel();
+ }
+ break;
+
+ case 303: /* case_label: CASE constant_expression COLON */
+ {
+ (yyval.interm.intermCase) =
+ context->addCase((yyvsp[-1].interm.intermTypedNode), (yylsp[-2]));
+ }
+ break;
+
+ case 304: /* case_label: DEFAULT COLON */
+ {
+ (yyval.interm.intermCase) = context->addDefault((yylsp[-1]));
+ }
+ break;
+
+ case 305: /* condition: expression */
+ {
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermTypedNode);
+ context->checkIsScalarBool((yyvsp[0].interm.intermTypedNode)->getLine(),
+ (yyvsp[0].interm.intermTypedNode));
+ }
+ break;
+
+ case 306: /* condition: fully_specified_type identifier EQUAL initializer */
+ {
+ (yyval.interm.intermNode) = context->addConditionInitializer(
+ (yyvsp[-3].interm.type), ImmutableString((yyvsp[-2].lex).string),
+ (yyvsp[0].interm.intermTypedNode), (yylsp[-2]));
+ }
+ break;
+
+ case 307: /* $@8: %empty */
+ {
+ context->symbolTable.push();
+ context->incrLoopNestingLevel();
+ }
+ break;
+
+ case 308: /* iteration_statement: WHILE LEFT_PAREN $@8 condition RIGHT_PAREN
+ statement_no_new_scope */
+ {
+ context->symbolTable.pop();
+ (yyval.interm.intermNode) =
+ context->addLoop(ELoopWhile, 0, (yyvsp[-2].interm.intermNode), 0,
+ (yyvsp[0].interm.intermNode), (yylsp[-5]));
+ context->decrLoopNestingLevel();
+ }
+ break;
+
+ case 309: /* $@9: %empty */
+ {
+ context->incrLoopNestingLevel();
+ }
+ break;
+
+ case 310: /* iteration_statement: DO $@9 statement_with_scope WHILE LEFT_PAREN expression
+ RIGHT_PAREN SEMICOLON */
+ {
+ (yyval.interm.intermNode) =
+ context->addLoop(ELoopDoWhile, 0, (yyvsp[-2].interm.intermTypedNode), 0,
+ (yyvsp[-5].interm.intermNode), (yylsp[-4]));
+ context->decrLoopNestingLevel();
+ }
+ break;
+
+ case 311: /* $@10: %empty */
+ {
+ context->symbolTable.push();
+ context->incrLoopNestingLevel();
+ }
+ break;
+
+ case 312: /* iteration_statement: FOR LEFT_PAREN $@10 for_init_statement for_rest_statement
+ RIGHT_PAREN statement_no_new_scope */
+ {
+ context->symbolTable.pop();
+ (yyval.interm.intermNode) = context->addLoop(
+ ELoopFor, (yyvsp[-3].interm.intermNode), (yyvsp[-2].interm.nodePair).node1,
+ reinterpret_cast<TIntermTyped *>((yyvsp[-2].interm.nodePair).node2),
+ (yyvsp[0].interm.intermNode), (yylsp[-6]));
+ context->decrLoopNestingLevel();
+ }
+ break;
+
+ case 313: /* for_init_statement: expression_statement */
+ {
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
+ }
+ break;
+
+ case 314: /* for_init_statement: declaration_statement */
+ {
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
+ }
+ break;
+
+ case 315: /* conditionopt: condition */
+ {
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
+ }
+ break;
+
+ case 316: /* conditionopt: %empty */
+ {
+ (yyval.interm.intermNode) = nullptr;
+ }
+ break;
+
+ case 317: /* for_rest_statement: conditionopt SEMICOLON */
+ {
+ (yyval.interm.nodePair).node1 = (yyvsp[-1].interm.intermNode);
+ (yyval.interm.nodePair).node2 = 0;
+ }
+ break;
+
+ case 318: /* for_rest_statement: conditionopt SEMICOLON expression */
+ {
+ (yyval.interm.nodePair).node1 = (yyvsp[-2].interm.intermNode);
+ (yyval.interm.nodePair).node2 = (yyvsp[0].interm.intermTypedNode);
+ }
+ break;
+
+ case 319: /* jump_statement: CONTINUE SEMICOLON */
+ {
+ (yyval.interm.intermNode) = context->addBranch(EOpContinue, (yylsp[-1]));
+ }
+ break;
+
+ case 320: /* jump_statement: BREAK SEMICOLON */
+ {
+ (yyval.interm.intermNode) = context->addBranch(EOpBreak, (yylsp[-1]));
+ }
+ break;
+
+ case 321: /* jump_statement: RETURN SEMICOLON */
+ {
+ (yyval.interm.intermNode) = context->addBranch(EOpReturn, (yylsp[-1]));
+ }
+ break;
+
+ case 322: /* jump_statement: RETURN expression SEMICOLON */
+ {
+ (yyval.interm.intermNode) =
+ context->addBranch(EOpReturn, (yyvsp[-1].interm.intermTypedNode), (yylsp[-2]));
+ }
+ break;
+
+ case 323: /* jump_statement: DISCARD SEMICOLON */
+ {
+ (yyval.interm.intermNode) = context->addBranch(EOpKill, (yylsp[-1]));
+ }
+ break;
+
+ case 324: /* translation_unit: external_declaration */
+ {
+ (yyval.interm.intermBlock) = new TIntermBlock();
+ (yyval.interm.intermBlock)->setLine((yyloc));
+ (yyval.interm.intermBlock)->appendStatement((yyvsp[0].interm.intermNode));
+ context->setTreeRoot((yyval.interm.intermBlock));
+ }
+ break;
+
+ case 325: /* translation_unit: translation_unit external_declaration */
+ {
+ (yyval.interm.intermBlock)->appendStatement((yyvsp[0].interm.intermNode));
+ }
+ break;
+
+ case 326: /* external_declaration: function_definition */
+ {
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
+ }
+ break;
+
+ case 327: /* external_declaration: declaration */
+ {
+ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
+ }
+ break;
+
+ case 328: /* $@11: %empty */
+ {
+ context->parseFunctionDefinitionHeader((yylsp[0]), (yyvsp[0].interm).function,
+ &((yyvsp[0].interm).intermFunctionPrototype));
+ }
+ break;
+
+ case 329: /* function_definition: function_prototype $@11 compound_statement_no_new_scope */
+ {
+ (yyval.interm.intermNode) =
+ context->addFunctionDefinition((yyvsp[-2].interm).intermFunctionPrototype,
+ (yyvsp[0].interm.intermBlock), (yylsp[-2]));
+ }
+ break;
+
+ default:
+ break;
+ }
+ /* User semantic actions sometimes alter yychar, and that requires
+ that yytoken be updated with the new translation. We take the
+ approach of translating immediately before every use of yytoken.
+ One alternative is translating here after every semantic action,
+ but that translation would be missed if the semantic action invokes
+ YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
+ if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an
+ incorrect destructor might then be invoked immediately. In the
+ case of YYERROR or YYBACKUP, subsequent parser actions might lead
+ to an incorrect destructor call or verbose syntax error message
+ before the lookahead is translated. */
+ YY_SYMBOL_PRINT("-> $$ =", YY_CAST(yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc);
+
+ YYPOPSTACK(yylen);
+ yylen = 0;
+
+ *++yyvsp = yyval;
+ *++yylsp = yyloc;
+
+ /* Now 'shift' the result of the reduction. Determine what state
+ that goes to, based on the state we popped back to and the rule
+ number reduced by. */
+ {
+ const int yylhs = yyr1[yyn] - YYNTOKENS;
+ const int yyi = yypgoto[yylhs] + *yyssp;
+ yystate =
+ (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp ? yytable[yyi] : yydefgoto[yylhs]);
+ }
+
+ goto yynewstate;
+
+/*--------------------------------------.
+| yyerrlab -- here on detecting error. |
+`--------------------------------------*/
+yyerrlab:
+ /* Make sure we have latest lookahead translation. See comments at
+ user semantic actions for why this is necessary. */
+ yytoken = yychar == YYEMPTY ? YYSYMBOL_YYEMPTY : YYTRANSLATE(yychar);
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+ yyerror(&yylloc, context, scanner, YY_("syntax error"));
+ }
+
+ yyerror_range[1] = yylloc;
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse lookahead token after an
+ error, discard it. */
+
+ if (yychar <= YYEOF)
+ {
+ /* Return failure if at end of input. */
+ if (yychar == YYEOF)
+ YYABORT;
+ }
+ else
+ {
+ yydestruct("Error: discarding", yytoken, &yylval, &yylloc, context, scanner);
+ yychar = YYEMPTY;
+ }
+ }
+
+ /* Else will try to reuse lookahead token after shifting the error
+ token. */
+ goto yyerrlab1;
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR. |
+`---------------------------------------------------*/
+yyerrorlab:
+ /* Pacify compilers when the user code never invokes YYERROR and the
+ label yyerrorlab therefore never appears in user code. */
+ if (0)
+ YYERROR;
+ ++yynerrs;
+
+ /* Do not reclaim the symbols of the rule whose action triggered
+ this YYERROR. */
+ YYPOPSTACK(yylen);
+ yylen = 0;
+ YY_STACK_PRINT(yyss, yyssp);
+ yystate = *yyssp;
+ goto yyerrlab1;
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR. |
+`-------------------------------------------------------------*/
+yyerrlab1:
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
+
+ /* Pop stack until we find a state that shifts the error token. */
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (!yypact_value_is_default(yyn))
+ {
+ yyn += YYSYMBOL_YYerror;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror)
+ {
+ yyn = yytable[yyn];
+ if (0 < yyn)
+ break;
+ }
+ }
+
+ /* Pop the current state because it cannot handle the error token. */
+ if (yyssp == yyss)
+ YYABORT;
+
+ yyerror_range[1] = *yylsp;
+ yydestruct("Error: popping", YY_ACCESSING_SYMBOL(yystate), yyvsp, yylsp, context, scanner);
+ YYPOPSTACK(1);
+ yystate = *yyssp;
+ YY_STACK_PRINT(yyss, yyssp);
+ }
+
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+ *++yyvsp = yylval;
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
+
+ yyerror_range[2] = yylloc;
+ ++yylsp;
+ YYLLOC_DEFAULT(*yylsp, yyerror_range, 2);
+
+ /* Shift the error token. */
+ YY_SYMBOL_PRINT("Shifting", YY_ACCESSING_SYMBOL(yyn), yyvsp, yylsp);
+
+ yystate = yyn;
+ goto yynewstate;
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturnlab;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yyresult = 1;
+ goto yyreturnlab;
+
+/*-----------------------------------------------------------.
+| yyexhaustedlab -- YYNOMEM (memory exhaustion) comes here. |
+`-----------------------------------------------------------*/
+yyexhaustedlab:
+ yyerror(&yylloc, context, scanner, YY_("memory exhausted"));
+ yyresult = 2;
+ goto yyreturnlab;
+
+/*----------------------------------------------------------.
+| yyreturnlab -- parsing is finished, clean up and return. |
+`----------------------------------------------------------*/
+yyreturnlab:
+ if (yychar != YYEMPTY)
+ {
+ /* Make sure we have latest lookahead translation. See comments at
+ user semantic actions for why this is necessary. */
+ yytoken = YYTRANSLATE(yychar);
+ yydestruct("Cleanup: discarding lookahead", yytoken, &yylval, &yylloc, context, scanner);
+ }
+ /* Do not reclaim the symbols of the rule whose action triggered
+ this YYABORT or YYACCEPT. */
+ YYPOPSTACK(yylen);
+ YY_STACK_PRINT(yyss, yyssp);
+ while (yyssp != yyss)
+ {
+ yydestruct("Cleanup: popping", YY_ACCESSING_SYMBOL(+*yyssp), yyvsp, yylsp, context,
+ scanner);
+ YYPOPSTACK(1);
+ }
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE(yyss);
+#endif
+
+ return yyresult;
+}
+
+int glslang_parse(TParseContext *context)
+{
+ return yyparse(context, context->getScanner());
+}
diff --git a/gfx/angle/checkout/src/compiler/translator/glslang_tab_autogen.h b/gfx/angle/checkout/src/compiler/translator/glslang_tab_autogen.h
new file mode 100644
index 0000000000..d5a48edd40
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/glslang_tab_autogen.h
@@ -0,0 +1,320 @@
+/* A Bison parser, made by GNU Bison 3.8.2. */
+
+/* Bison interface for Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
+ Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
+ especially those whose name start with YY_ or yy_. They are
+ private implementation details that can be changed or removed. */
+
+#ifndef YY_YY_GLSLANG_TAB_AUTOGEN_H_INCLUDED
+#define YY_YY_GLSLANG_TAB_AUTOGEN_H_INCLUDED
+/* Debug traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+#if YYDEBUG
+extern int yydebug;
+#endif
+/* "%code requires" blocks. */
+
+#define YYLTYPE TSourceLoc
+#define YYLTYPE_IS_DECLARED 1
+#define YYLTYPE_IS_TRIVIAL 1
+
+/* Token kinds. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+enum yytokentype
+{
+ YYEMPTY = -2,
+ YYEOF = 0, /* "end of file" */
+ YYerror = 256, /* error */
+ YYUNDEF = 257, /* "invalid token" */
+ INVARIANT = 258, /* INVARIANT */
+ PRECISE = 259, /* PRECISE */
+ HIGH_PRECISION = 260, /* HIGH_PRECISION */
+ MEDIUM_PRECISION = 261, /* MEDIUM_PRECISION */
+ LOW_PRECISION = 262, /* LOW_PRECISION */
+ PRECISION = 263, /* PRECISION */
+ ATTRIBUTE = 264, /* ATTRIBUTE */
+ CONST_QUAL = 265, /* CONST_QUAL */
+ BOOL_TYPE = 266, /* BOOL_TYPE */
+ FLOAT_TYPE = 267, /* FLOAT_TYPE */
+ INT_TYPE = 268, /* INT_TYPE */
+ UINT_TYPE = 269, /* UINT_TYPE */
+ BREAK = 270, /* BREAK */
+ CONTINUE = 271, /* CONTINUE */
+ DO = 272, /* DO */
+ ELSE = 273, /* ELSE */
+ FOR = 274, /* FOR */
+ IF = 275, /* IF */
+ DISCARD = 276, /* DISCARD */
+ RETURN = 277, /* RETURN */
+ SWITCH = 278, /* SWITCH */
+ CASE = 279, /* CASE */
+ DEFAULT = 280, /* DEFAULT */
+ BVEC2 = 281, /* BVEC2 */
+ BVEC3 = 282, /* BVEC3 */
+ BVEC4 = 283, /* BVEC4 */
+ IVEC2 = 284, /* IVEC2 */
+ IVEC3 = 285, /* IVEC3 */
+ IVEC4 = 286, /* IVEC4 */
+ VEC2 = 287, /* VEC2 */
+ VEC3 = 288, /* VEC3 */
+ VEC4 = 289, /* VEC4 */
+ UVEC2 = 290, /* UVEC2 */
+ UVEC3 = 291, /* UVEC3 */
+ UVEC4 = 292, /* UVEC4 */
+ MATRIX2 = 293, /* MATRIX2 */
+ MATRIX3 = 294, /* MATRIX3 */
+ MATRIX4 = 295, /* MATRIX4 */
+ IN_QUAL = 296, /* IN_QUAL */
+ OUT_QUAL = 297, /* OUT_QUAL */
+ INOUT_QUAL = 298, /* INOUT_QUAL */
+ UNIFORM = 299, /* UNIFORM */
+ BUFFER = 300, /* BUFFER */
+ VARYING = 301, /* VARYING */
+ MATRIX2x3 = 302, /* MATRIX2x3 */
+ MATRIX3x2 = 303, /* MATRIX3x2 */
+ MATRIX2x4 = 304, /* MATRIX2x4 */
+ MATRIX4x2 = 305, /* MATRIX4x2 */
+ MATRIX3x4 = 306, /* MATRIX3x4 */
+ MATRIX4x3 = 307, /* MATRIX4x3 */
+ SAMPLE = 308, /* SAMPLE */
+ CENTROID = 309, /* CENTROID */
+ FLAT = 310, /* FLAT */
+ SMOOTH = 311, /* SMOOTH */
+ NOPERSPECTIVE = 312, /* NOPERSPECTIVE */
+ PATCH = 313, /* PATCH */
+ READONLY = 314, /* READONLY */
+ WRITEONLY = 315, /* WRITEONLY */
+ COHERENT = 316, /* COHERENT */
+ RESTRICT = 317, /* RESTRICT */
+ VOLATILE = 318, /* VOLATILE */
+ SHARED = 319, /* SHARED */
+ STRUCT = 320, /* STRUCT */
+ VOID_TYPE = 321, /* VOID_TYPE */
+ WHILE = 322, /* WHILE */
+ SAMPLER2D = 323, /* SAMPLER2D */
+ SAMPLERCUBE = 324, /* SAMPLERCUBE */
+ SAMPLER_EXTERNAL_OES = 325, /* SAMPLER_EXTERNAL_OES */
+ SAMPLER2DRECT = 326, /* SAMPLER2DRECT */
+ SAMPLER2DARRAY = 327, /* SAMPLER2DARRAY */
+ ISAMPLER2D = 328, /* ISAMPLER2D */
+ ISAMPLER3D = 329, /* ISAMPLER3D */
+ ISAMPLERCUBE = 330, /* ISAMPLERCUBE */
+ ISAMPLER2DARRAY = 331, /* ISAMPLER2DARRAY */
+ USAMPLER2D = 332, /* USAMPLER2D */
+ USAMPLER3D = 333, /* USAMPLER3D */
+ USAMPLERCUBE = 334, /* USAMPLERCUBE */
+ USAMPLER2DARRAY = 335, /* USAMPLER2DARRAY */
+ SAMPLER2DMS = 336, /* SAMPLER2DMS */
+ ISAMPLER2DMS = 337, /* ISAMPLER2DMS */
+ USAMPLER2DMS = 338, /* USAMPLER2DMS */
+ SAMPLER2DMSARRAY = 339, /* SAMPLER2DMSARRAY */
+ ISAMPLER2DMSARRAY = 340, /* ISAMPLER2DMSARRAY */
+ USAMPLER2DMSARRAY = 341, /* USAMPLER2DMSARRAY */
+ SAMPLER3D = 342, /* SAMPLER3D */
+ SAMPLER3DRECT = 343, /* SAMPLER3DRECT */
+ SAMPLER2DSHADOW = 344, /* SAMPLER2DSHADOW */
+ SAMPLERCUBESHADOW = 345, /* SAMPLERCUBESHADOW */
+ SAMPLER2DARRAYSHADOW = 346, /* SAMPLER2DARRAYSHADOW */
+ SAMPLERVIDEOWEBGL = 347, /* SAMPLERVIDEOWEBGL */
+ SAMPLERCUBEARRAYOES = 348, /* SAMPLERCUBEARRAYOES */
+ SAMPLERCUBEARRAYSHADOWOES = 349, /* SAMPLERCUBEARRAYSHADOWOES */
+ ISAMPLERCUBEARRAYOES = 350, /* ISAMPLERCUBEARRAYOES */
+ USAMPLERCUBEARRAYOES = 351, /* USAMPLERCUBEARRAYOES */
+ SAMPLERCUBEARRAYEXT = 352, /* SAMPLERCUBEARRAYEXT */
+ SAMPLERCUBEARRAYSHADOWEXT = 353, /* SAMPLERCUBEARRAYSHADOWEXT */
+ ISAMPLERCUBEARRAYEXT = 354, /* ISAMPLERCUBEARRAYEXT */
+ USAMPLERCUBEARRAYEXT = 355, /* USAMPLERCUBEARRAYEXT */
+ SAMPLERBUFFER = 356, /* SAMPLERBUFFER */
+ ISAMPLERBUFFER = 357, /* ISAMPLERBUFFER */
+ USAMPLERBUFFER = 358, /* USAMPLERBUFFER */
+ SAMPLEREXTERNAL2DY2YEXT = 359, /* SAMPLEREXTERNAL2DY2YEXT */
+ IMAGE2D = 360, /* IMAGE2D */
+ IIMAGE2D = 361, /* IIMAGE2D */
+ UIMAGE2D = 362, /* UIMAGE2D */
+ IMAGE3D = 363, /* IMAGE3D */
+ IIMAGE3D = 364, /* IIMAGE3D */
+ UIMAGE3D = 365, /* UIMAGE3D */
+ IMAGE2DARRAY = 366, /* IMAGE2DARRAY */
+ IIMAGE2DARRAY = 367, /* IIMAGE2DARRAY */
+ UIMAGE2DARRAY = 368, /* UIMAGE2DARRAY */
+ IMAGECUBE = 369, /* IMAGECUBE */
+ IIMAGECUBE = 370, /* IIMAGECUBE */
+ UIMAGECUBE = 371, /* UIMAGECUBE */
+ IMAGECUBEARRAYOES = 372, /* IMAGECUBEARRAYOES */
+ IIMAGECUBEARRAYOES = 373, /* IIMAGECUBEARRAYOES */
+ UIMAGECUBEARRAYOES = 374, /* UIMAGECUBEARRAYOES */
+ IMAGECUBEARRAYEXT = 375, /* IMAGECUBEARRAYEXT */
+ IIMAGECUBEARRAYEXT = 376, /* IIMAGECUBEARRAYEXT */
+ UIMAGECUBEARRAYEXT = 377, /* UIMAGECUBEARRAYEXT */
+ IMAGEBUFFER = 378, /* IMAGEBUFFER */
+ IIMAGEBUFFER = 379, /* IIMAGEBUFFER */
+ UIMAGEBUFFER = 380, /* UIMAGEBUFFER */
+ ATOMICUINT = 381, /* ATOMICUINT */
+ PIXELLOCALANGLE = 382, /* PIXELLOCALANGLE */
+ IPIXELLOCALANGLE = 383, /* IPIXELLOCALANGLE */
+ UPIXELLOCALANGLE = 384, /* UPIXELLOCALANGLE */
+ LAYOUT = 385, /* LAYOUT */
+ YUVCSCSTANDARDEXT = 386, /* YUVCSCSTANDARDEXT */
+ YUVCSCSTANDARDEXTCONSTANT = 387, /* YUVCSCSTANDARDEXTCONSTANT */
+ IDENTIFIER = 388, /* IDENTIFIER */
+ TYPE_NAME = 389, /* TYPE_NAME */
+ FLOATCONSTANT = 390, /* FLOATCONSTANT */
+ INTCONSTANT = 391, /* INTCONSTANT */
+ UINTCONSTANT = 392, /* UINTCONSTANT */
+ BOOLCONSTANT = 393, /* BOOLCONSTANT */
+ FIELD_SELECTION = 394, /* FIELD_SELECTION */
+ LEFT_OP = 395, /* LEFT_OP */
+ RIGHT_OP = 396, /* RIGHT_OP */
+ INC_OP = 397, /* INC_OP */
+ DEC_OP = 398, /* DEC_OP */
+ LE_OP = 399, /* LE_OP */
+ GE_OP = 400, /* GE_OP */
+ EQ_OP = 401, /* EQ_OP */
+ NE_OP = 402, /* NE_OP */
+ AND_OP = 403, /* AND_OP */
+ OR_OP = 404, /* OR_OP */
+ XOR_OP = 405, /* XOR_OP */
+ MUL_ASSIGN = 406, /* MUL_ASSIGN */
+ DIV_ASSIGN = 407, /* DIV_ASSIGN */
+ ADD_ASSIGN = 408, /* ADD_ASSIGN */
+ MOD_ASSIGN = 409, /* MOD_ASSIGN */
+ LEFT_ASSIGN = 410, /* LEFT_ASSIGN */
+ RIGHT_ASSIGN = 411, /* RIGHT_ASSIGN */
+ AND_ASSIGN = 412, /* AND_ASSIGN */
+ XOR_ASSIGN = 413, /* XOR_ASSIGN */
+ OR_ASSIGN = 414, /* OR_ASSIGN */
+ SUB_ASSIGN = 415, /* SUB_ASSIGN */
+ LEFT_PAREN = 416, /* LEFT_PAREN */
+ RIGHT_PAREN = 417, /* RIGHT_PAREN */
+ LEFT_BRACKET = 418, /* LEFT_BRACKET */
+ RIGHT_BRACKET = 419, /* RIGHT_BRACKET */
+ LEFT_BRACE = 420, /* LEFT_BRACE */
+ RIGHT_BRACE = 421, /* RIGHT_BRACE */
+ DOT = 422, /* DOT */
+ COMMA = 423, /* COMMA */
+ COLON = 424, /* COLON */
+ EQUAL = 425, /* EQUAL */
+ SEMICOLON = 426, /* SEMICOLON */
+ BANG = 427, /* BANG */
+ DASH = 428, /* DASH */
+ TILDE = 429, /* TILDE */
+ PLUS = 430, /* PLUS */
+ STAR = 431, /* STAR */
+ SLASH = 432, /* SLASH */
+ PERCENT = 433, /* PERCENT */
+ LEFT_ANGLE = 434, /* LEFT_ANGLE */
+ RIGHT_ANGLE = 435, /* RIGHT_ANGLE */
+ VERTICAL_BAR = 436, /* VERTICAL_BAR */
+ CARET = 437, /* CARET */
+ AMPERSAND = 438, /* AMPERSAND */
+ QUESTION = 439 /* QUESTION */
+};
+typedef enum yytokentype yytoken_kind_t;
+#endif
+
+/* Value type. */
+#if !defined YYSTYPE && !defined YYSTYPE_IS_DECLARED
+union YYSTYPE
+{
+
+ struct
+ {
+ union
+ {
+ const char *string; // pool allocated.
+ float f;
+ int i;
+ unsigned int u;
+ bool b;
+ };
+ const TSymbol *symbol;
+ } lex;
+ struct
+ {
+ TOperator op;
+ union
+ {
+ TIntermNode *intermNode;
+ TIntermNodePair nodePair;
+ TIntermTyped *intermTypedNode;
+ TIntermAggregate *intermAggregate;
+ TIntermBlock *intermBlock;
+ TIntermDeclaration *intermDeclaration;
+ TIntermFunctionPrototype *intermFunctionPrototype;
+ TIntermSwitch *intermSwitch;
+ TIntermCase *intermCase;
+ };
+ union
+ {
+ TVector<unsigned int> *arraySizes;
+ TTypeSpecifierNonArray typeSpecifierNonArray;
+ TPublicType type;
+ TPrecision precision;
+ TLayoutQualifier layoutQualifier;
+ TQualifier qualifier;
+ TFunction *function;
+ TFunctionLookup *functionLookup;
+ TParameter param;
+ TDeclarator *declarator;
+ TDeclaratorList *declaratorList;
+ TFieldList *fieldList;
+ TQualifierWrapperBase *qualifierWrapper;
+ TTypeQualifierBuilder *typeQualifierBuilder;
+ };
+ } interm;
+};
+typedef union YYSTYPE YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+/* Location type. */
+#if !defined YYLTYPE && !defined YYLTYPE_IS_DECLARED
+typedef struct YYLTYPE YYLTYPE;
+struct YYLTYPE
+{
+ int first_line;
+ int first_column;
+ int last_line;
+ int last_column;
+};
+# define YYLTYPE_IS_DECLARED 1
+# define YYLTYPE_IS_TRIVIAL 1
+#endif
+
+int yyparse(TParseContext *context, void *scanner);
+
+#endif /* !YY_YY_GLSLANG_TAB_AUTOGEN_H_INCLUDED */
diff --git a/gfx/angle/checkout/src/compiler/translator/glslang_wrapper.h b/gfx/angle/checkout/src/compiler/translator/glslang_wrapper.h
new file mode 100644
index 0000000000..a5cd49bcbb
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/glslang_wrapper.h
@@ -0,0 +1,46 @@
+//
+// Copyright 2021 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.
+//
+// glslang_wrapper:
+// A wrapper to compile GLSL strings to SPIR-V blobs. glslang here refers to the Khronos
+// compiler.
+//
+
+#ifndef COMPILER_TRANSLATOR_GLSLANG_WRAPPER_H_
+#define COMPILER_TRANSLATOR_GLSLANG_WRAPPER_H_
+
+#include "GLSLANG/ShaderLang.h"
+#include "common/PackedEnums.h"
+#include "common/spirv/spirv_types.h"
+
+#include <string>
+#include <vector>
+
+namespace sh
+{
+#if defined(ANGLE_ENABLE_SPIRV_GENERATION_THROUGH_GLSLANG)
+void GlslangInitialize();
+void GlslangFinalize();
+
+// Generate SPIR-V out of intermediate GLSL through glslang.
+[[nodiscard]] bool GlslangCompileToSpirv(const ShBuiltInResources &resources,
+ sh::GLenum shaderType,
+ const std::string &shaderSource,
+ angle::spirv::Blob *spirvBlobOut);
+#else
+ANGLE_INLINE void GlslangInitialize() {}
+ANGLE_INLINE void GlslangFinalize() {}
+ANGLE_INLINE bool GlslangCompileToSpirv(const ShBuiltInResources &resources,
+ sh::GLenum shaderType,
+ const std::string &shaderSource,
+ angle::spirv::Blob *spirvBlobOut)
+{
+ UNREACHABLE();
+ return false;
+}
+#endif // defined(ANGLE_ENABLE_VULKAN) || defined(ANGLE_ENABLE_METAL)
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_GLSLANG_WRAPPER_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/length_limits.h b/gfx/angle/checkout/src/compiler/translator/length_limits.h
new file mode 100644
index 0000000000..a7d95db135
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/length_limits.h
@@ -0,0 +1,26 @@
+//
+// Copyright 2011 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.
+//
+
+//
+// length_limits.h
+//
+
+#ifndef COMPILER_TRANSLATOR_LENGTHLIMITS_H_
+#define COMPILER_TRANSLATOR_LENGTHLIMITS_H_
+
+#include "GLSLANG/ShaderLang.h"
+
+// These constants are factored out from the rest of the headers to
+// make it easier to reference them from the compiler sources.
+
+namespace sh
+{
+
+size_t GetGlobalMaxTokenSize(ShShaderSpec spec);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_LENGTHLIMITS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/ClampIndirectIndices.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/ClampIndirectIndices.cpp
new file mode 100644
index 0000000000..bd1997a21d
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/ClampIndirectIndices.cpp
@@ -0,0 +1,136 @@
+//
+// Copyright 2021 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.
+//
+// ClampIndirectIndices.h: Add clamp to the indirect indices used on arrays.
+//
+
+#include "compiler/translator/tree_ops/ClampIndirectIndices.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/StaticType.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+namespace
+{
+// Traverser that finds EOpIndexIndirect nodes and applies a clamp to their right-hand side
+// expression.
+class ClampIndirectIndicesTraverser : public TIntermTraverser
+{
+ public:
+ ClampIndirectIndicesTraverser(TCompiler *compiler, TSymbolTable *symbolTable)
+ : TIntermTraverser(true, false, false, symbolTable), mCompiler(compiler)
+ {}
+
+ bool visitBinary(Visit visit, TIntermBinary *node) override
+ {
+ ASSERT(visit == PreVisit);
+
+ // Only interested in EOpIndexIndirect nodes.
+ if (node->getOp() != EOpIndexIndirect)
+ {
+ return true;
+ }
+
+ // Apply the transformation to the left and right nodes
+ bool valid = ClampIndirectIndices(mCompiler, node->getLeft(), mSymbolTable);
+ ASSERT(valid);
+ valid = ClampIndirectIndices(mCompiler, node->getRight(), mSymbolTable);
+ ASSERT(valid);
+
+ // Generate clamp(right, 0, N), where N is the size of the array being indexed minus 1. If
+ // the array is runtime-sized, the length() method is called on it.
+ const TType &leftType = node->getLeft()->getType();
+ const TType &rightType = node->getRight()->getType();
+
+ // Don't clamp indirect indices on unsized arrays in buffer blocks. They are covered by the
+ // relevant robust access behavior of the backend.
+ if (leftType.isUnsizedArray())
+ {
+ return true;
+ }
+
+ // On GLSL es 100, clamp is only defined for float, so float arguments are used.
+ //
+ // However, float clamp is unconditionally emitted to workaround driver bugs with integer
+ // clamp on Qualcomm. http://crbug.com/1217167
+ //
+ // const bool useFloatClamp = mCompiler->getShaderVersion() == 100;
+ const bool useFloatClamp = true;
+
+ TIntermConstantUnion *zero = createClampValue(0, useFloatClamp);
+ TIntermTyped *max;
+
+ if (leftType.isArray())
+ {
+ max = createClampValue(static_cast<int>(leftType.getOutermostArraySize()) - 1,
+ useFloatClamp);
+ }
+ else
+ {
+ ASSERT(leftType.isVector() || leftType.isMatrix());
+ max = createClampValue(leftType.getNominalSize() - 1, useFloatClamp);
+ }
+
+ TIntermTyped *index = node->getRight();
+ // If the index node is not an int (i.e. it's a uint), or a float (if using float clamp),
+ // cast it.
+ const TBasicType requiredBasicType = useFloatClamp ? EbtFloat : EbtInt;
+ if (rightType.getBasicType() != requiredBasicType)
+ {
+ const TType *clampType = useFloatClamp ? StaticType::GetBasic<EbtFloat, EbpHigh>()
+ : StaticType::GetBasic<EbtInt, EbpHigh>();
+ TIntermSequence constructorArgs = {index};
+ index = TIntermAggregate::CreateConstructor(*clampType, &constructorArgs);
+ }
+
+ // min(gl_PointSize, maxPointSize)
+ TIntermSequence args;
+ args.push_back(index);
+ args.push_back(zero);
+ args.push_back(max);
+ TIntermTyped *clamped =
+ CreateBuiltInFunctionCallNode("clamp", &args, *mSymbolTable, useFloatClamp ? 100 : 300);
+
+ // Cast back to int if float clamp was used.
+ if (useFloatClamp)
+ {
+ TIntermSequence constructorArgs = {clamped};
+ clamped = TIntermAggregate::CreateConstructor(*StaticType::GetBasic<EbtInt, EbpHigh>(),
+ &constructorArgs);
+ }
+
+ // Replace the right node (the index) with the clamped result.
+ queueReplacementWithParent(node, node->getRight(), clamped, OriginalNode::IS_DROPPED);
+
+ // Don't recurse as left and right nodes are already processed.
+ return false;
+ }
+
+ private:
+ TIntermConstantUnion *createClampValue(int value, bool useFloat)
+ {
+ if (useFloat)
+ {
+ return CreateFloatNode(static_cast<float>(value), EbpHigh);
+ }
+ return CreateIndexNode(value);
+ }
+
+ TCompiler *mCompiler;
+};
+} // anonymous namespace
+
+bool ClampIndirectIndices(TCompiler *compiler, TIntermNode *root, TSymbolTable *symbolTable)
+{
+ ClampIndirectIndicesTraverser traverser(compiler, symbolTable);
+ root->traverse(&traverser);
+ return traverser.updateTree(compiler, root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/ClampIndirectIndices.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/ClampIndirectIndices.h
new file mode 100644
index 0000000000..eebbab02e6
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/ClampIndirectIndices.h
@@ -0,0 +1,27 @@
+//
+// Copyright 2021 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.
+//
+// ClampIndirectIndices.h: Add clamp to the indirect indices used on arrays.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_CLAMPINDIRECTINDICES_H_
+#define COMPILER_TRANSLATOR_TREEOPS_CLAMPINDIRECTINDICES_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermNode;
+class TSymbolTable;
+
+[[nodiscard]] bool ClampIndirectIndices(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_CLAMPINDIRECTINDICES_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/ClampPointSize.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/ClampPointSize.cpp
new file mode 100644
index 0000000000..db006989e9
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/ClampPointSize.cpp
@@ -0,0 +1,52 @@
+//
+// Copyright 2017 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.
+//
+// ClampPointSize.cpp: Limit the value that is written to gl_PointSize.
+//
+
+#include "compiler/translator/tree_ops/ClampPointSize.h"
+
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/BuiltIn.h"
+#include "compiler/translator/tree_util/FindSymbolNode.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/RunAtTheEndOfShader.h"
+
+namespace sh
+{
+
+bool ClampPointSize(TCompiler *compiler,
+ TIntermBlock *root,
+ float maxPointSize,
+ TSymbolTable *symbolTable)
+{
+ // Only clamp gl_PointSize if it's used in the shader.
+ const TIntermSymbol *glPointSize = FindSymbolNode(root, ImmutableString("gl_PointSize"));
+ if (glPointSize == nullptr)
+ {
+ return true;
+ }
+
+ TIntermTyped *pointSizeNode = glPointSize->deepCopy();
+
+ TConstantUnion *maxPointSizeConstant = new TConstantUnion();
+ maxPointSizeConstant->setFConst(maxPointSize);
+ TIntermConstantUnion *maxPointSizeNode =
+ new TIntermConstantUnion(maxPointSizeConstant, TType(EbtFloat, EbpHigh, EvqConst));
+
+ // min(gl_PointSize, maxPointSize)
+ TIntermSequence minArguments;
+ minArguments.push_back(pointSizeNode->deepCopy());
+ minArguments.push_back(maxPointSizeNode);
+ TIntermTyped *clampedPointSize =
+ CreateBuiltInFunctionCallNode("min", &minArguments, *symbolTable, 100);
+
+ // gl_PointSize = min(gl_PointSize, maxPointSize)
+ TIntermBinary *assignPointSize = new TIntermBinary(EOpAssign, pointSizeNode, clampedPointSize);
+
+ return RunAtTheEndOfShader(compiler, root, assignPointSize, symbolTable);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/ClampPointSize.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/ClampPointSize.h
new file mode 100644
index 0000000000..c42f32bde2
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/ClampPointSize.h
@@ -0,0 +1,28 @@
+//
+// Copyright 2017 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.
+//
+// ClampPointSize.h: Limit the value that is written to gl_PointSize.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_CLAMPPOINTSIZE_H_
+#define COMPILER_TRANSLATOR_TREEOPS_CLAMPPOINTSIZE_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+[[nodiscard]] bool ClampPointSize(TCompiler *compiler,
+ TIntermBlock *root,
+ float maxPointSize,
+ TSymbolTable *symbolTable);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_CLAMPPOINTSIZE_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/ConvertUnsupportedConstructorsToFunctionCalls.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/ConvertUnsupportedConstructorsToFunctionCalls.cpp
new file mode 100644
index 0000000000..5c45e1fb59
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/ConvertUnsupportedConstructorsToFunctionCalls.cpp
@@ -0,0 +1,335 @@
+//
+// Copyright 2020 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/tree_ops/ConvertUnsupportedConstructorsToFunctionCalls.h"
+#include "compiler/translator/ImmutableString.h"
+#include "compiler/translator/Symbol.h"
+#include "compiler/translator/tree_util/FindFunction.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermRebuild.h"
+
+using namespace sh;
+
+namespace
+{
+
+void AppendMatrixElementArgument(TIntermSymbol *parameter,
+ int colIndex,
+ int rowIndex,
+ TIntermSequence *returnCtorArgs)
+{
+ TIntermBinary *matColN =
+ new TIntermBinary(EOpIndexDirect, parameter->deepCopy(), CreateIndexNode(colIndex));
+ TIntermSwizzle *matElem = new TIntermSwizzle(matColN, {rowIndex});
+ returnCtorArgs->push_back(matElem);
+}
+
+// Adds the argument to sequence for a scalar constructor.
+// Given scalar(scalarA) appends scalarA
+// Given scalar(vecA) appends vecA.x
+// Given scalar(matA) appends matA[0].x
+void AppendScalarFromNonScalarArguments(TFunction &function, TIntermSequence *returnCtorArgs)
+{
+ const TVariable *var = function.getParam(0);
+ TIntermSymbol *arg0 = new TIntermSymbol(var);
+
+ const TType &type = arg0->getType();
+
+ if (type.isScalar())
+ {
+ returnCtorArgs->push_back(arg0);
+ }
+ else if (type.isVector())
+ {
+ TIntermSwizzle *vecX = new TIntermSwizzle(arg0, {0});
+ returnCtorArgs->push_back(vecX);
+ }
+ else if (type.isMatrix())
+ {
+ AppendMatrixElementArgument(arg0, 0, 0, returnCtorArgs);
+ }
+}
+
+// Adds the arguments to sequence for a vector constructor from a scalar.
+// Given vecN(scalarA) appends scalarA, scalarA, ... n times
+void AppendVectorFromScalarArgument(const TType &type,
+ TFunction &function,
+ TIntermSequence *returnCtorArgs)
+{
+ const uint8_t vectorSize = type.getNominalSize();
+ const TVariable *var = function.getParam(0);
+ TIntermSymbol *v = new TIntermSymbol(var);
+ for (uint8_t i = 0; i < vectorSize; ++i)
+ {
+ returnCtorArgs->push_back(v->deepCopy());
+ }
+}
+
+// Adds the arguments to sequence for a vector or matrix constructor from the available arguments
+// applying arguments in order until the requested number of values have been extracted from the
+// given arguments or until there are no more arguments.
+void AppendValuesFromMultipleArguments(int numValuesNeeded,
+ TFunction &function,
+ TIntermSequence *returnCtorArgs)
+{
+ size_t numParameters = function.getParamCount();
+ size_t paramIndex = 0;
+ uint8_t colIndex = 0;
+ uint8_t rowIndex = 0;
+
+ for (int i = 0; i < numValuesNeeded && paramIndex < numParameters; ++i)
+ {
+ const TVariable *p = function.getParam(paramIndex);
+ TIntermSymbol *parameter = new TIntermSymbol(p);
+ if (parameter->isScalar())
+ {
+ returnCtorArgs->push_back(parameter);
+ ++paramIndex;
+ }
+ else if (parameter->isVector())
+ {
+ TIntermSwizzle *vecS = new TIntermSwizzle(parameter->deepCopy(), {rowIndex++});
+ returnCtorArgs->push_back(vecS);
+ if (rowIndex == parameter->getNominalSize())
+ {
+ ++paramIndex;
+ rowIndex = 0;
+ }
+ }
+ else if (parameter->isMatrix())
+ {
+ AppendMatrixElementArgument(parameter, colIndex, rowIndex++, returnCtorArgs);
+ if (rowIndex == parameter->getSecondarySize())
+ {
+ rowIndex = 0;
+ ++colIndex;
+ if (colIndex == parameter->getNominalSize())
+ {
+ colIndex = 0;
+ ++paramIndex;
+ }
+ }
+ }
+ }
+}
+
+// Adds the arguments for a matrix constructor from a scalar
+// putting the scalar along the diagonal and 0 everywhere else.
+void AppendMatrixFromScalarArgument(const TType &type,
+ TFunction &function,
+ TIntermSequence *returnCtorArgs)
+{
+ const TVariable *var = function.getParam(0);
+ TIntermSymbol *v = new TIntermSymbol(var);
+ const uint8_t numCols = type.getNominalSize();
+ const uint8_t numRows = type.getSecondarySize();
+ for (uint8_t col = 0; col < numCols; ++col)
+ {
+ for (uint8_t row = 0; row < numRows; ++row)
+ {
+ if (col == row)
+ {
+ returnCtorArgs->push_back(v->deepCopy());
+ }
+ else
+ {
+ returnCtorArgs->push_back(CreateFloatNode(0.0f, sh::EbpUndefined));
+ }
+ }
+ }
+}
+
+// Add the argument for a matrix constructor from a matrix
+// copying elements from the same column/row and otherwise
+// initialize to the identity matrix.
+void AppendMatrixFromMatrixArgument(const TType &type,
+ TFunction &function,
+ TIntermSequence *returnCtorArgs)
+{
+ const TVariable *var = function.getParam(0);
+ TIntermSymbol *v = new TIntermSymbol(var);
+ const uint8_t dstCols = type.getNominalSize();
+ const uint8_t dstRows = type.getSecondarySize();
+ const uint8_t srcCols = v->getNominalSize();
+ const uint8_t srcRows = v->getSecondarySize();
+ for (uint8_t dstCol = 0; dstCol < dstCols; ++dstCol)
+ {
+ for (uint8_t dstRow = 0; dstRow < dstRows; ++dstRow)
+ {
+ if (dstRow < srcRows && dstCol < srcCols)
+ {
+ AppendMatrixElementArgument(v, dstCol, dstRow, returnCtorArgs);
+ }
+ else
+ {
+ returnCtorArgs->push_back(
+ CreateFloatNode(dstRow == dstCol ? 1.0f : 0.0f, sh::EbpUndefined));
+ }
+ }
+ }
+}
+
+class Rebuild : public TIntermRebuild
+{
+ public:
+ explicit Rebuild(TCompiler &compiler) : TIntermRebuild(compiler, false, true) {}
+ PostResult visitAggregatePost(TIntermAggregate &node) override
+ {
+ if (!node.isConstructor())
+ {
+ return node;
+ }
+
+ TIntermSequence &arguments = *node.getSequence();
+ if (arguments.empty())
+ {
+ return node;
+ }
+
+ const TType &type = node.getType();
+ const TType &arg0Type = arguments[0]->getAsTyped()->getType();
+
+ if (!type.isScalar() && !type.isVector() && !type.isMatrix())
+ {
+ return node;
+ }
+
+ if (type.isArray())
+ {
+ return node;
+ }
+
+ // check for type_ctor(sameType)
+ // scalar(scalar) -> passthrough
+ // vecN(vecN) -> passthrough
+ // matN(matN) -> passthrough
+ if (arguments.size() == 1 && arg0Type == type)
+ {
+ return node;
+ }
+
+ // The following are simple casts:
+ //
+ // - basic(s) (where basic is int, uint, float or bool, and s is scalar).
+ // - gvecN(vN) (where the argument is a single vector with the same number of components).
+ // - matNxM(mNxM) (where the argument is a single matrix with the same dimensions). Note
+ // that
+ // matrices are always float, so there's no actual cast and this would be a no-op.
+ //
+ const bool isSingleScalarCast =
+ arguments.size() == 1 && type.isScalar() && arg0Type.isScalar();
+ const bool isSingleVectorCast = arguments.size() == 1 && type.isVector() &&
+ arg0Type.isVector() &&
+ type.getNominalSize() == arg0Type.getNominalSize();
+ const bool isSingleMatrixCast =
+ arguments.size() == 1 && type.isMatrix() && arg0Type.isMatrix() &&
+ type.getCols() == arg0Type.getCols() && type.getRows() == arg0Type.getRows();
+ if (isSingleScalarCast || isSingleVectorCast || isSingleMatrixCast)
+ {
+ return node;
+ }
+
+ // Cases we need to handle:
+ // scalar(vec)
+ // scalar(mat)
+ // vecN(scalar)
+ // vecN(vecM)
+ // vecN(a,...)
+ // matN(scalar) -> diag
+ // matN(vec) -> fail!
+ // manN(matM) -> corner + ident
+ // matN(a, ...)
+
+ // Build a function and pass all the constructor's arguments to it.
+ TIntermBlock *body = new TIntermBlock;
+ TFunction *function = new TFunction(&mSymbolTable, ImmutableString(""),
+ SymbolType::AngleInternal, &type, true);
+
+ for (size_t i = 0; i < arguments.size(); ++i)
+ {
+ TIntermTyped &arg = *arguments[i]->getAsTyped();
+ TType *argType = new TType(arg.getBasicType(), arg.getPrecision(), EvqParamIn,
+ arg.getNominalSize(), arg.getSecondarySize());
+ TVariable *var = CreateTempVariable(&mSymbolTable, argType);
+ function->addParameter(var);
+ }
+
+ // Build a return statement for the function that
+ // converts the arguments into the required type.
+ TIntermSequence *returnCtorArgs = new TIntermSequence();
+
+ if (type.isScalar())
+ {
+ AppendScalarFromNonScalarArguments(*function, returnCtorArgs);
+ }
+ else if (type.isVector())
+ {
+ if (arguments.size() == 1 && arg0Type.isScalar())
+ {
+ AppendVectorFromScalarArgument(type, *function, returnCtorArgs);
+ }
+ else
+ {
+ AppendValuesFromMultipleArguments(type.getNominalSize(), *function, returnCtorArgs);
+ }
+ }
+ else if (type.isMatrix())
+ {
+ if (arguments.size() == 1 && arg0Type.isScalar())
+ {
+ // MSL already handles this case
+ AppendMatrixFromScalarArgument(type, *function, returnCtorArgs);
+ }
+ else if (arg0Type.isMatrix())
+ {
+ AppendMatrixFromMatrixArgument(type, *function, returnCtorArgs);
+ }
+ else
+ {
+ AppendValuesFromMultipleArguments(type.getNominalSize() * type.getSecondarySize(),
+ *function, returnCtorArgs);
+ }
+ }
+
+ TIntermBranch *returnStatement =
+ new TIntermBranch(EOpReturn, TIntermAggregate::CreateConstructor(type, returnCtorArgs));
+ body->appendStatement(returnStatement);
+
+ TIntermFunctionDefinition *functionDefinition =
+ CreateInternalFunctionDefinitionNode(*function, body);
+ mFunctionDefs.push_back(functionDefinition);
+
+ TIntermTyped *functionCall = TIntermAggregate::CreateFunctionCall(*function, &arguments);
+
+ return *functionCall;
+ }
+
+ bool rewrite(TIntermBlock &root)
+ {
+ if (!rebuildInPlace(root))
+ {
+ return true;
+ }
+
+ size_t firstFunctionIndex = FindFirstFunctionDefinitionIndex(&root);
+ for (TIntermFunctionDefinition *functionDefinition : mFunctionDefs)
+ {
+ root.insertChildNodes(firstFunctionIndex, TIntermSequence({functionDefinition}));
+ }
+
+ return mCompiler.validateAST(&root);
+ }
+
+ private:
+ TVector<TIntermFunctionDefinition *> mFunctionDefs;
+};
+
+} // anonymous namespace
+
+bool sh::ConvertUnsupportedConstructorsToFunctionCalls(TCompiler &compiler, TIntermBlock &root)
+{
+ return Rebuild(compiler).rewrite(root);
+}
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/ConvertUnsupportedConstructorsToFunctionCalls.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/ConvertUnsupportedConstructorsToFunctionCalls.h
new file mode 100644
index 0000000000..720a02c9a6
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/ConvertUnsupportedConstructorsToFunctionCalls.h
@@ -0,0 +1,25 @@
+//
+// Copyright 2020 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_TREE_OPS_CONVERTUNSUPPORTEDCONSTRUCTORSTOFUNCTIONCALLS_H_
+#define COMPILER_TRANSLATOR_TREE_OPS_CONVERTUNSUPPORTEDCONSTRUCTORSTOFUNCTIONCALLS_H_
+
+#include "compiler/translator/Compiler.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TInterBlock;
+class SymbolEnv;
+
+// Adds explicit type casts into the AST where casting is done implicitly.
+[[nodiscard]] bool ConvertUnsupportedConstructorsToFunctionCalls(TCompiler &compiler,
+ TIntermBlock &root);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREE_OPS_CONVERTUNSUPPORTEDCONSTRUCTORSTOFUNCTIONCALLS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/DeclareAndInitBuiltinsForInstancedMultiview.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/DeclareAndInitBuiltinsForInstancedMultiview.cpp
new file mode 100644
index 0000000000..8c2925949d
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/DeclareAndInitBuiltinsForInstancedMultiview.cpp
@@ -0,0 +1,196 @@
+//
+// Copyright 2017 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.
+//
+// Applies the necessary AST transformations to support multiview rendering through instancing.
+// Check the header file For more information.
+//
+
+#include "compiler/translator/tree_ops/DeclareAndInitBuiltinsForInstancedMultiview.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/StaticType.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_ops/InitializeVariables.h"
+#include "compiler/translator/tree_util/BuiltIn.h"
+#include "compiler/translator/tree_util/FindMain.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/tree_util/ReplaceVariable.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+constexpr const ImmutableString kViewIDVariableName("ViewID_OVR");
+constexpr const ImmutableString kInstanceIDVariableName("InstanceID");
+constexpr const ImmutableString kMultiviewBaseViewLayerIndexVariableName(
+ "multiviewBaseViewLayerIndex");
+
+// Adds the InstanceID and ViewID_OVR initializers to the end of the initializers' sequence.
+void InitializeViewIDAndInstanceID(const TVariable *viewID,
+ const TVariable *instanceID,
+ unsigned numberOfViews,
+ const TSymbolTable &symbolTable,
+ TIntermSequence *initializers)
+{
+ // Create an unsigned numberOfViews node.
+ TConstantUnion *numberOfViewsUnsignedConstant = new TConstantUnion();
+ numberOfViewsUnsignedConstant->setUConst(numberOfViews);
+ TIntermConstantUnion *numberOfViewsUint =
+ new TIntermConstantUnion(numberOfViewsUnsignedConstant, TType(EbtUInt, EbpLow, EvqConst));
+
+ // Create a uint(gl_InstanceID) node.
+ TIntermSequence glInstanceIDSymbolCastArguments;
+ glInstanceIDSymbolCastArguments.push_back(new TIntermSymbol(BuiltInVariable::gl_InstanceID()));
+ TIntermAggregate *glInstanceIDAsUint = TIntermAggregate::CreateConstructor(
+ TType(EbtUInt, EbpHigh, EvqTemporary), &glInstanceIDSymbolCastArguments);
+
+ // Create a uint(gl_InstanceID) / numberOfViews node.
+ TIntermBinary *normalizedInstanceID =
+ new TIntermBinary(EOpDiv, glInstanceIDAsUint, numberOfViewsUint);
+
+ // Create an int(uint(gl_InstanceID) / numberOfViews) node.
+ TIntermSequence normalizedInstanceIDCastArguments;
+ normalizedInstanceIDCastArguments.push_back(normalizedInstanceID);
+ TIntermAggregate *normalizedInstanceIDAsInt = TIntermAggregate::CreateConstructor(
+ TType(EbtInt, EbpHigh, EvqTemporary), &normalizedInstanceIDCastArguments);
+
+ // Create an InstanceID = int(uint(gl_InstanceID) / numberOfViews) node.
+ TIntermBinary *instanceIDInitializer =
+ new TIntermBinary(EOpAssign, new TIntermSymbol(instanceID), normalizedInstanceIDAsInt);
+ initializers->push_back(instanceIDInitializer);
+
+ // Create a uint(gl_InstanceID) % numberOfViews node.
+ TIntermBinary *normalizedViewID =
+ new TIntermBinary(EOpIMod, glInstanceIDAsUint->deepCopy(), numberOfViewsUint->deepCopy());
+
+ // Create a ViewID_OVR = uint(gl_InstanceID) % numberOfViews node.
+ TIntermBinary *viewIDInitializer =
+ new TIntermBinary(EOpAssign, new TIntermSymbol(viewID), normalizedViewID);
+ initializers->push_back(viewIDInitializer);
+}
+
+// Adds a branch to write int(ViewID_OVR) to either gl_ViewportIndex or gl_Layer. The branch is
+// added to the end of the initializers' sequence.
+void SelectViewIndexInVertexShader(const TVariable *viewID,
+ const TVariable *multiviewBaseViewLayerIndex,
+ TIntermSequence *initializers,
+ const TSymbolTable &symbolTable)
+{
+ // Create an int(ViewID_OVR) node.
+ TIntermSequence viewIDSymbolCastArguments;
+ viewIDSymbolCastArguments.push_back(new TIntermSymbol(viewID));
+ TIntermAggregate *viewIDAsInt = TIntermAggregate::CreateConstructor(
+ TType(EbtInt, EbpHigh, EvqTemporary), &viewIDSymbolCastArguments);
+
+ // Create a gl_ViewportIndex node.
+ TIntermSymbol *viewportIndexSymbol = new TIntermSymbol(BuiltInVariable::gl_ViewportIndex());
+
+ // Create a { gl_ViewportIndex = int(ViewID_OVR) } node.
+ TIntermBlock *viewportIndexInitializerInBlock = new TIntermBlock();
+ viewportIndexInitializerInBlock->appendStatement(
+ new TIntermBinary(EOpAssign, viewportIndexSymbol, viewIDAsInt));
+
+ // Create a gl_Layer node.
+ TIntermSymbol *layerSymbol = new TIntermSymbol(BuiltInVariable::gl_LayerVS());
+
+ // Create an int(ViewID_OVR) + multiviewBaseViewLayerIndex node
+ TIntermBinary *sumOfViewIDAndBaseViewIndex = new TIntermBinary(
+ EOpAdd, viewIDAsInt->deepCopy(), new TIntermSymbol(multiviewBaseViewLayerIndex));
+
+ // Create a { gl_Layer = int(ViewID_OVR) + multiviewBaseViewLayerIndex } node.
+ TIntermBlock *layerInitializerInBlock = new TIntermBlock();
+ layerInitializerInBlock->appendStatement(
+ new TIntermBinary(EOpAssign, layerSymbol, sumOfViewIDAndBaseViewIndex));
+
+ // Create a node to compare whether the base view index uniform is less than zero.
+ TIntermBinary *multiviewBaseViewLayerIndexZeroComparison =
+ new TIntermBinary(EOpLessThan, new TIntermSymbol(multiviewBaseViewLayerIndex),
+ CreateZeroNode(TType(EbtInt, EbpHigh, EvqConst)));
+
+ // Create an if-else statement to select the code path.
+ TIntermIfElse *multiviewBranch =
+ new TIntermIfElse(multiviewBaseViewLayerIndexZeroComparison,
+ viewportIndexInitializerInBlock, layerInitializerInBlock);
+
+ initializers->push_back(multiviewBranch);
+}
+
+} // namespace
+
+bool DeclareAndInitBuiltinsForInstancedMultiview(TCompiler *compiler,
+ TIntermBlock *root,
+ unsigned numberOfViews,
+ GLenum shaderType,
+ const ShCompileOptions &compileOptions,
+ ShShaderOutput shaderOutput,
+ TSymbolTable *symbolTable)
+{
+ ASSERT(shaderType == GL_VERTEX_SHADER || shaderType == GL_FRAGMENT_SHADER);
+
+ TQualifier viewIDQualifier = (shaderType == GL_VERTEX_SHADER) ? EvqFlatOut : EvqFlatIn;
+ const TVariable *viewID =
+ new TVariable(symbolTable, kViewIDVariableName,
+ new TType(EbtUInt, EbpHigh, viewIDQualifier), SymbolType::AngleInternal);
+
+ DeclareGlobalVariable(root, viewID);
+ if (!ReplaceVariable(compiler, root, BuiltInVariable::gl_ViewID_OVR(), viewID))
+ {
+ return false;
+ }
+ if (shaderType == GL_VERTEX_SHADER)
+ {
+ // Replacing gl_InstanceID with InstanceID should happen before adding the initializers of
+ // InstanceID and ViewID.
+ const TType *instanceIDVariableType = StaticType::Get<EbtInt, EbpHigh, EvqGlobal, 1, 1>();
+ const TVariable *instanceID =
+ new TVariable(symbolTable, kInstanceIDVariableName, instanceIDVariableType,
+ SymbolType::AngleInternal);
+ DeclareGlobalVariable(root, instanceID);
+ if (!ReplaceVariable(compiler, root, BuiltInVariable::gl_InstanceID(), instanceID))
+ {
+ return false;
+ }
+
+ TIntermSequence initializers;
+ InitializeViewIDAndInstanceID(viewID, instanceID, numberOfViews, *symbolTable,
+ &initializers);
+
+ // The AST transformation which adds the expression to select the viewport index should
+ // be done only for the GLSL and ESSL output.
+ const bool selectView = compileOptions.selectViewInNvGLSLVertexShader;
+ // Assert that if the view is selected in the vertex shader, then the output is
+ // either GLSL or ESSL.
+ ASSERT(!selectView || IsOutputGLSL(shaderOutput) || IsOutputESSL(shaderOutput));
+ if (selectView)
+ {
+ // Add a uniform to switch between side-by-side and layered rendering.
+ const TType *baseLayerIndexVariableType =
+ StaticType::Get<EbtInt, EbpHigh, EvqUniform, 1, 1>();
+ const TVariable *multiviewBaseViewLayerIndex =
+ new TVariable(symbolTable, kMultiviewBaseViewLayerIndexVariableName,
+ baseLayerIndexVariableType, SymbolType::AngleInternal);
+ DeclareGlobalVariable(root, multiviewBaseViewLayerIndex);
+
+ // Setting a value to gl_ViewportIndex or gl_Layer should happen after ViewID_OVR's
+ // initialization.
+ SelectViewIndexInVertexShader(viewID, multiviewBaseViewLayerIndex, &initializers,
+ *symbolTable);
+ }
+
+ // Insert initializers at the beginning of main().
+ TIntermBlock *initializersBlock = new TIntermBlock();
+ initializersBlock->getSequence()->swap(initializers);
+ TIntermBlock *mainBody = FindMainBody(root);
+ mainBody->getSequence()->insert(mainBody->getSequence()->begin(), initializersBlock);
+ }
+
+ return compiler->validateAST(root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/DeclareAndInitBuiltinsForInstancedMultiview.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/DeclareAndInitBuiltinsForInstancedMultiview.h
new file mode 100644
index 0000000000..49a964d234
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/DeclareAndInitBuiltinsForInstancedMultiview.h
@@ -0,0 +1,52 @@
+//
+// Copyright 2017 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.
+//
+// Regardless of the shader type, the following AST transformations are applied:
+// - Add declaration of View_ID_OVR.
+// - Replace every occurrence of gl_ViewID_OVR with ViewID_OVR, mark ViewID_OVR as internal and
+// declare it as a flat varying.
+//
+// If the shader type is a vertex shader, the following AST transformations are applied:
+// - Replace every occurrence of gl_InstanceID with InstanceID, mark InstanceID as internal and set
+// its qualifier to EvqTemporary.
+// - Add initializers of ViewID_OVR and InstanceID to the beginning of the body of main. The pass
+// should be executed before any variables get collected so that usage of gl_InstanceID is recorded.
+// - If the output is ESSL or GLSL and the selectViewInNvGLSLVertexShader option is
+// enabled, the expression
+// "if (multiviewBaseViewLayerIndex < 0) {
+// gl_ViewportIndex = int(ViewID_OVR);
+// } else {
+// gl_Layer = int(ViewID_OVR) + multiviewBaseViewLayerIndex;
+// }"
+// is added after ViewID and InstanceID are initialized. Also, MultiviewRenderPath is added as a
+// uniform.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_DECLAREANDINITBUILTINSFORINSTANCEDMULTIVIEW_H_
+#define COMPILER_TRANSLATOR_TREEOPS_DECLAREANDINITBUILTINSFORINSTANCEDMULTIVIEW_H_
+
+#include "GLSLANG/ShaderLang.h"
+#include "angle_gl.h"
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+[[nodiscard]] bool DeclareAndInitBuiltinsForInstancedMultiview(
+ TCompiler *compiler,
+ TIntermBlock *root,
+ unsigned numberOfViews,
+ GLenum shaderType,
+ const ShCompileOptions &compileOptions,
+ ShShaderOutput shaderOutput,
+ TSymbolTable *symbolTable);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_DECLAREANDINITBUILTINSFORINSTANCEDMULTIVIEW_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/DeferGlobalInitializers.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/DeferGlobalInitializers.cpp
new file mode 100644
index 0000000000..035de73431
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/DeferGlobalInitializers.cpp
@@ -0,0 +1,180 @@
+//
+// 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.
+//
+// DeferGlobalInitializers is an AST traverser that moves global initializers into a separate
+// function that is called in the beginning of main(). This enables initialization of globals with
+// uniforms or non-constant globals, as allowed by the WebGL spec. Some initializers referencing
+// non-constants may need to be unfolded into if statements in HLSL - this kind of steps should be
+// done after DeferGlobalInitializers is run. Note that it's important that the function definition
+// is at the end of the shader, as some globals may be declared after main().
+//
+// It can also initialize all uninitialized globals.
+//
+
+#include "compiler/translator/tree_ops/DeferGlobalInitializers.h"
+
+#include <vector>
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/StaticType.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_ops/InitializeVariables.h"
+#include "compiler/translator/tree_util/FindMain.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/ReplaceVariable.h"
+
+namespace sh
+{
+
+namespace
+{
+
+constexpr const ImmutableString kInitGlobalsString("initGlobals");
+
+void GetDeferredInitializers(TIntermDeclaration *declaration,
+ bool initializeUninitializedGlobals,
+ bool canUseLoopsToInitialize,
+ bool highPrecisionSupported,
+ bool forceDeferGlobalInitializers,
+ TIntermSequence *deferredInitializersOut,
+ std::vector<const TVariable *> *variablesToReplaceOut,
+ TSymbolTable *symbolTable)
+{
+ // SeparateDeclarations should have already been run.
+ ASSERT(declaration->getSequence()->size() == 1);
+
+ TIntermNode *declarator = declaration->getSequence()->back();
+ TIntermBinary *init = declarator->getAsBinaryNode();
+ if (init)
+ {
+ TIntermSymbol *symbolNode = init->getLeft()->getAsSymbolNode();
+ ASSERT(symbolNode);
+ TIntermTyped *expression = init->getRight();
+
+ if (expression->getQualifier() != EvqConst || !expression->hasConstantValue() ||
+ forceDeferGlobalInitializers)
+ {
+ // For variables which are not constant, defer their real initialization until
+ // after we initialize uniforms.
+ // Deferral is done also in any cases where the variable can not be converted to a
+ // constant union, since otherwise there's a chance that HLSL output will generate extra
+ // statements from the initializer expression.
+
+ // Change const global to a regular global if its initialization is deferred.
+ // This can happen if ANGLE has not been able to fold the constant expression used
+ // as an initializer.
+ ASSERT(symbolNode->getQualifier() == EvqConst ||
+ symbolNode->getQualifier() == EvqGlobal);
+ if (symbolNode->getQualifier() == EvqConst)
+ {
+ variablesToReplaceOut->push_back(&symbolNode->variable());
+ }
+
+ TIntermBinary *deferredInit =
+ new TIntermBinary(EOpAssign, symbolNode->deepCopy(), init->getRight());
+ deferredInitializersOut->push_back(deferredInit);
+
+ // Remove the initializer from the global scope and just declare the global instead.
+ declaration->replaceChildNode(init, symbolNode);
+ }
+ }
+ else if (initializeUninitializedGlobals)
+ {
+ TIntermSymbol *symbolNode = declarator->getAsSymbolNode();
+ ASSERT(symbolNode);
+
+ // Ignore ANGLE internal variables and nameless declarations.
+ if (symbolNode->variable().symbolType() == SymbolType::AngleInternal ||
+ symbolNode->variable().symbolType() == SymbolType::Empty)
+ return;
+
+ if (symbolNode->getQualifier() == EvqGlobal)
+ {
+ TIntermSequence initCode;
+ CreateInitCode(symbolNode, canUseLoopsToInitialize, highPrecisionSupported, &initCode,
+ symbolTable);
+ deferredInitializersOut->insert(deferredInitializersOut->end(), initCode.begin(),
+ initCode.end());
+ }
+ }
+}
+
+void InsertInitCallToMain(TIntermBlock *root,
+ TIntermSequence *deferredInitializers,
+ TSymbolTable *symbolTable)
+{
+ TIntermBlock *initGlobalsBlock = new TIntermBlock();
+ initGlobalsBlock->getSequence()->swap(*deferredInitializers);
+
+ TFunction *initGlobalsFunction =
+ new TFunction(symbolTable, kInitGlobalsString, SymbolType::AngleInternal,
+ StaticType::GetBasic<EbtVoid, EbpUndefined>(), false);
+
+ TIntermFunctionPrototype *initGlobalsFunctionPrototype =
+ CreateInternalFunctionPrototypeNode(*initGlobalsFunction);
+ root->getSequence()->insert(root->getSequence()->begin(), initGlobalsFunctionPrototype);
+ TIntermFunctionDefinition *initGlobalsFunctionDefinition =
+ CreateInternalFunctionDefinitionNode(*initGlobalsFunction, initGlobalsBlock);
+ root->appendStatement(initGlobalsFunctionDefinition);
+
+ TIntermSequence emptySequence;
+ TIntermAggregate *initGlobalsCall =
+ TIntermAggregate::CreateFunctionCall(*initGlobalsFunction, &emptySequence);
+
+ TIntermBlock *mainBody = FindMainBody(root);
+ mainBody->getSequence()->insert(mainBody->getSequence()->begin(), initGlobalsCall);
+}
+
+} // namespace
+
+bool DeferGlobalInitializers(TCompiler *compiler,
+ TIntermBlock *root,
+ bool initializeUninitializedGlobals,
+ bool canUseLoopsToInitialize,
+ bool highPrecisionSupported,
+ bool forceDeferGlobalInitializers,
+ TSymbolTable *symbolTable)
+{
+ TIntermSequence deferredInitializers;
+ std::vector<const TVariable *> variablesToReplace;
+
+ // Loop over all global statements and process the declarations. This is simpler than using a
+ // traverser.
+ for (TIntermNode *statement : *root->getSequence())
+ {
+ TIntermDeclaration *declaration = statement->getAsDeclarationNode();
+ if (declaration)
+ {
+ GetDeferredInitializers(declaration, initializeUninitializedGlobals,
+ canUseLoopsToInitialize, highPrecisionSupported,
+ forceDeferGlobalInitializers, &deferredInitializers,
+ &variablesToReplace, symbolTable);
+ }
+ }
+
+ // Add the function with initialization and the call to that.
+ if (!deferredInitializers.empty())
+ {
+ InsertInitCallToMain(root, &deferredInitializers, symbolTable);
+ }
+
+ // Replace constant variables with non-constant global variables.
+ for (const TVariable *var : variablesToReplace)
+ {
+ TType *replacementType = new TType(var->getType());
+ replacementType->setQualifier(EvqGlobal);
+ TVariable *replacement =
+ new TVariable(symbolTable, var->name(), replacementType, var->symbolType());
+ if (!ReplaceVariable(compiler, root, var, replacement))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/DeferGlobalInitializers.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/DeferGlobalInitializers.h
new file mode 100644
index 0000000000..58a38a982b
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/DeferGlobalInitializers.h
@@ -0,0 +1,38 @@
+//
+// 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.
+//
+// DeferGlobalInitializers is an AST traverser that moves global initializers into a separate
+// function that is called in the beginning of main(). This enables initialization of globals with
+// uniforms or non-constant globals, as allowed by the WebGL spec. Some initializers referencing
+// non-constants may need to be unfolded into if statements in HLSL - this kind of steps should be
+// done after DeferGlobalInitializers is run. Note that it's important that the function definition
+// is at the end of the shader, as some globals may be declared after main().
+//
+// It can also initialize all uninitialized globals.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_DEFERGLOBALINITIALIZERS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_DEFERGLOBALINITIALIZERS_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+[[nodiscard]] bool DeferGlobalInitializers(TCompiler *compiler,
+ TIntermBlock *root,
+ bool initializeUninitializedGlobals,
+ bool canUseLoopsToInitialize,
+ bool highPrecisionSupported,
+ bool forceDeferGlobalInitializers,
+ TSymbolTable *symbolTable);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_DEFERGLOBALINITIALIZERS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateGLFragColorBroadcast.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateGLFragColorBroadcast.cpp
new file mode 100644
index 0000000000..25e1fde29a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateGLFragColorBroadcast.cpp
@@ -0,0 +1,142 @@
+//
+// Copyright 2002 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/tree_ops/EmulateGLFragColorBroadcast.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/Symbol.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/tree_util/RunAtTheEndOfShader.h"
+
+namespace sh
+{
+
+namespace
+{
+
+constexpr const ImmutableString kGlFragDataString("gl_FragData");
+
+class GLFragColorBroadcastTraverser : public TIntermTraverser
+{
+ public:
+ GLFragColorBroadcastTraverser(int maxDrawBuffers, TSymbolTable *symbolTable, int shaderVersion)
+ : TIntermTraverser(true, false, false, symbolTable),
+ mGLFragColorUsed(false),
+ mMaxDrawBuffers(maxDrawBuffers),
+ mShaderVersion(shaderVersion)
+ {}
+
+ [[nodiscard]] bool broadcastGLFragColor(TCompiler *compiler, TIntermBlock *root);
+
+ bool isGLFragColorUsed() const { return mGLFragColorUsed; }
+
+ protected:
+ void visitSymbol(TIntermSymbol *node) override;
+
+ TIntermBinary *constructGLFragDataNode(int index) const;
+ TIntermBinary *constructGLFragDataAssignNode(int index) const;
+
+ private:
+ bool mGLFragColorUsed;
+ int mMaxDrawBuffers;
+ const int mShaderVersion;
+};
+
+TIntermBinary *GLFragColorBroadcastTraverser::constructGLFragDataNode(int index) const
+{
+ TIntermSymbol *symbol =
+ ReferenceBuiltInVariable(kGlFragDataString, *mSymbolTable, mShaderVersion);
+ TIntermTyped *indexNode = 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->variable().symbolType() == SymbolType::BuiltIn && node->getName() == "gl_FragColor")
+ {
+ queueReplacement(constructGLFragDataNode(0), OriginalNode::IS_DROPPED);
+ mGLFragColorUsed = true;
+ }
+}
+
+bool GLFragColorBroadcastTraverser::broadcastGLFragColor(TCompiler *compiler, TIntermBlock *root)
+{
+ ASSERT(mMaxDrawBuffers > 1);
+ if (!mGLFragColorUsed)
+ {
+ return true;
+ }
+
+ TIntermBlock *broadcastBlock = new TIntermBlock();
+ // Now insert statements
+ // gl_FragData[1] = gl_FragData[0];
+ // ...
+ // gl_FragData[maxDrawBuffers - 1] = gl_FragData[0];
+ for (int colorIndex = 1; colorIndex < mMaxDrawBuffers; ++colorIndex)
+ {
+ broadcastBlock->appendStatement(constructGLFragDataAssignNode(colorIndex));
+ }
+ return RunAtTheEndOfShader(compiler, root, broadcastBlock, mSymbolTable);
+}
+
+} // namespace
+
+bool EmulateGLFragColorBroadcast(TCompiler *compiler,
+ TIntermBlock *root,
+ int maxDrawBuffers,
+ std::vector<sh::ShaderVariable> *outputVariables,
+ TSymbolTable *symbolTable,
+ int shaderVersion)
+{
+ ASSERT(maxDrawBuffers > 1);
+ GLFragColorBroadcastTraverser traverser(maxDrawBuffers, symbolTable, shaderVersion);
+ root->traverse(&traverser);
+ if (traverser.isGLFragColorUsed())
+ {
+ if (!traverser.updateTree(compiler, root))
+ {
+ return false;
+ }
+ if (!traverser.broadcastGLFragColor(compiler, root))
+ {
+ return false;
+ }
+
+ 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.arraySizes.push_back(maxDrawBuffers);
+ ASSERT(var.arraySizes.size() == 1u);
+ }
+ }
+ }
+
+ return true;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateGLFragColorBroadcast.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateGLFragColorBroadcast.h
new file mode 100644
index 0000000000..c71ba7c2be
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateGLFragColorBroadcast.h
@@ -0,0 +1,35 @@
+//
+// Copyright 2002 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_TREEOPS_EMULATEGLFRAGCOLORBROADCAST_H_
+#define COMPILER_TRANSLATOR_TREEOPS_EMULATEGLFRAGCOLORBROADCAST_H_
+
+#include <vector>
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+struct ShaderVariable;
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+// 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.
+[[nodiscard]] bool EmulateGLFragColorBroadcast(TCompiler *compiler,
+ TIntermBlock *root,
+ int maxDrawBuffers,
+ std::vector<ShaderVariable> *outputVariables,
+ TSymbolTable *symbolTable,
+ int shaderVersion);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_EMULATEGLFRAGCOLORBROADCAST_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateMultiDrawShaderBuiltins.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateMultiDrawShaderBuiltins.cpp
new file mode 100644
index 0000000000..dfa36ad145
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateMultiDrawShaderBuiltins.cpp
@@ -0,0 +1,274 @@
+//
+// Copyright 2019 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.
+//
+// EmulateGLDrawID is an AST traverser to convert the gl_DrawID builtin
+// to a uniform int
+//
+// EmulateGLBaseVertex is an AST traverser to convert the gl_BaseVertex builtin
+// to a uniform int
+//
+// EmulateGLBaseInstance is an AST traverser to convert the gl_BaseInstance builtin
+// to a uniform int
+//
+
+#include "compiler/translator/tree_ops/EmulateMultiDrawShaderBuiltins.h"
+
+#include "angle_gl.h"
+#include "compiler/translator/StaticType.h"
+#include "compiler/translator/Symbol.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/BuiltIn.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/tree_util/ReplaceVariable.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+constexpr const ImmutableString kEmulatedGLDrawIDName("angle_DrawID");
+
+class FindGLDrawIDTraverser : public TIntermTraverser
+{
+ public:
+ FindGLDrawIDTraverser() : TIntermTraverser(true, false, false), mVariable(nullptr) {}
+
+ const TVariable *getGLDrawIDBuiltinVariable() { return mVariable; }
+
+ protected:
+ void visitSymbol(TIntermSymbol *node) override
+ {
+ if (&node->variable() == BuiltInVariable::gl_DrawID())
+ {
+ mVariable = &node->variable();
+ }
+ }
+
+ private:
+ const TVariable *mVariable;
+};
+
+class AddBaseVertexToGLVertexIDTraverser : public TIntermTraverser
+{
+ public:
+ AddBaseVertexToGLVertexIDTraverser() : TIntermTraverser(true, false, false) {}
+
+ protected:
+ void visitSymbol(TIntermSymbol *node) override
+ {
+ if (&node->variable() == BuiltInVariable::gl_VertexID())
+ {
+
+ TIntermSymbol *baseVertexRef = new TIntermSymbol(BuiltInVariable::gl_BaseVertex());
+
+ TIntermBinary *addBaseVertex = new TIntermBinary(EOpAdd, node, baseVertexRef);
+ queueReplacement(addBaseVertex, OriginalNode::BECOMES_CHILD);
+ }
+ }
+};
+
+constexpr const ImmutableString kEmulatedGLBaseVertexName("angle_BaseVertex");
+
+class FindGLBaseVertexTraverser : public TIntermTraverser
+{
+ public:
+ FindGLBaseVertexTraverser() : TIntermTraverser(true, false, false), mVariable(nullptr) {}
+
+ const TVariable *getGLBaseVertexBuiltinVariable() { return mVariable; }
+
+ protected:
+ void visitSymbol(TIntermSymbol *node) override
+ {
+ if (&node->variable() == BuiltInVariable::gl_BaseVertex())
+ {
+ mVariable = &node->variable();
+ }
+ }
+
+ private:
+ const TVariable *mVariable;
+};
+
+constexpr const ImmutableString kEmulatedGLBaseInstanceName("angle_BaseInstance");
+
+class FindGLBaseInstanceTraverser : public TIntermTraverser
+{
+ public:
+ FindGLBaseInstanceTraverser() : TIntermTraverser(true, false, false), mVariable(nullptr) {}
+
+ const TVariable *getGLBaseInstanceBuiltinVariable() { return mVariable; }
+
+ protected:
+ void visitSymbol(TIntermSymbol *node) override
+ {
+ if (&node->variable() == BuiltInVariable::gl_BaseInstance())
+ {
+ mVariable = &node->variable();
+ }
+ }
+
+ private:
+ const TVariable *mVariable;
+};
+
+} // namespace
+
+bool EmulateGLDrawID(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ std::vector<sh::ShaderVariable> *uniforms,
+ bool shouldCollect)
+{
+ FindGLDrawIDTraverser traverser;
+ root->traverse(&traverser);
+ const TVariable *builtInVariable = traverser.getGLDrawIDBuiltinVariable();
+ if (builtInVariable)
+ {
+ const TType *type = StaticType::Get<EbtInt, EbpHigh, EvqUniform, 1, 1>();
+ const TVariable *drawID =
+ new TVariable(symbolTable, kEmulatedGLDrawIDName, type, SymbolType::AngleInternal);
+ const TIntermSymbol *drawIDSymbol = new TIntermSymbol(drawID);
+
+ // AngleInternal variables don't get collected
+ if (shouldCollect)
+ {
+ ShaderVariable uniform;
+ uniform.name = kEmulatedGLDrawIDName.data();
+ uniform.mappedName = kEmulatedGLDrawIDName.data();
+ uniform.type = GLVariableType(*type);
+ uniform.precision = GLVariablePrecision(*type);
+ uniform.staticUse = symbolTable->isStaticallyUsed(*builtInVariable);
+ uniform.active = true;
+ uniform.binding = type->getLayoutQualifier().binding;
+ uniform.location = type->getLayoutQualifier().location;
+ uniform.offset = type->getLayoutQualifier().offset;
+ uniform.rasterOrdered = type->getLayoutQualifier().rasterOrdered;
+ uniform.readonly = type->getMemoryQualifier().readonly;
+ uniform.writeonly = type->getMemoryQualifier().writeonly;
+ uniforms->push_back(uniform);
+ }
+
+ DeclareGlobalVariable(root, drawID);
+ if (!ReplaceVariableWithTyped(compiler, root, builtInVariable, drawIDSymbol))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool EmulateGLBaseVertexBaseInstance(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ std::vector<sh::ShaderVariable> *uniforms,
+ bool shouldCollect,
+ bool addBaseVertexToVertexID)
+{
+ bool addBaseVertex = false, addBaseInstance = false;
+ ShaderVariable uniformBaseVertex, uniformBaseInstance;
+
+ if (addBaseVertexToVertexID)
+ {
+ // This is a workaround for Mac AMD GPU
+ // Replace gl_VertexID with (gl_VertexID + gl_BaseVertex)
+ AddBaseVertexToGLVertexIDTraverser traverserVertexID;
+ root->traverse(&traverserVertexID);
+ if (!traverserVertexID.updateTree(compiler, root))
+ {
+ return false;
+ }
+ }
+
+ FindGLBaseVertexTraverser traverserBaseVertex;
+ root->traverse(&traverserBaseVertex);
+ const TVariable *builtInVariableBaseVertex =
+ traverserBaseVertex.getGLBaseVertexBuiltinVariable();
+
+ if (builtInVariableBaseVertex)
+ {
+ const TVariable *baseVertex = BuiltInVariable::angle_BaseVertex();
+ const TType &type = baseVertex->getType();
+ const TIntermSymbol *baseVertexSymbol = new TIntermSymbol(baseVertex);
+
+ // AngleInternal variables don't get collected
+ if (shouldCollect)
+ {
+ uniformBaseVertex.name = kEmulatedGLBaseVertexName.data();
+ uniformBaseVertex.mappedName = kEmulatedGLBaseVertexName.data();
+ uniformBaseVertex.type = GLVariableType(type);
+ uniformBaseVertex.precision = GLVariablePrecision(type);
+ uniformBaseVertex.staticUse = symbolTable->isStaticallyUsed(*builtInVariableBaseVertex);
+ uniformBaseVertex.active = true;
+ uniformBaseVertex.binding = type.getLayoutQualifier().binding;
+ uniformBaseVertex.location = type.getLayoutQualifier().location;
+ uniformBaseVertex.offset = type.getLayoutQualifier().offset;
+ uniformBaseVertex.rasterOrdered = type.getLayoutQualifier().rasterOrdered;
+ uniformBaseVertex.readonly = type.getMemoryQualifier().readonly;
+ uniformBaseVertex.writeonly = type.getMemoryQualifier().writeonly;
+ addBaseVertex = true;
+ }
+
+ DeclareGlobalVariable(root, baseVertex);
+ if (!ReplaceVariableWithTyped(compiler, root, builtInVariableBaseVertex, baseVertexSymbol))
+ {
+ return false;
+ }
+ }
+
+ FindGLBaseInstanceTraverser traverserInstance;
+ root->traverse(&traverserInstance);
+ const TVariable *builtInVariableBaseInstance =
+ traverserInstance.getGLBaseInstanceBuiltinVariable();
+
+ if (builtInVariableBaseInstance)
+ {
+ const TVariable *baseInstance = BuiltInVariable::angle_BaseInstance();
+ const TType &type = baseInstance->getType();
+ const TIntermSymbol *baseInstanceSymbol = new TIntermSymbol(baseInstance);
+
+ // AngleInternal variables don't get collected
+ if (shouldCollect)
+ {
+ uniformBaseInstance.name = kEmulatedGLBaseInstanceName.data();
+ uniformBaseInstance.mappedName = kEmulatedGLBaseInstanceName.data();
+ uniformBaseInstance.type = GLVariableType(type);
+ uniformBaseInstance.precision = GLVariablePrecision(type);
+ uniformBaseInstance.staticUse =
+ symbolTable->isStaticallyUsed(*builtInVariableBaseInstance);
+ uniformBaseInstance.active = true;
+ uniformBaseInstance.binding = type.getLayoutQualifier().binding;
+ uniformBaseInstance.location = type.getLayoutQualifier().location;
+ uniformBaseInstance.offset = type.getLayoutQualifier().offset;
+ uniformBaseInstance.rasterOrdered = type.getLayoutQualifier().rasterOrdered;
+ uniformBaseInstance.readonly = type.getMemoryQualifier().readonly;
+ uniformBaseInstance.writeonly = type.getMemoryQualifier().writeonly;
+ addBaseInstance = true;
+ }
+
+ DeclareGlobalVariable(root, baseInstance);
+ if (!ReplaceVariableWithTyped(compiler, root, builtInVariableBaseInstance,
+ baseInstanceSymbol))
+ {
+ return false;
+ }
+ }
+
+ // Make sure the order in uniforms is the same as the traverse order
+ if (addBaseInstance)
+ {
+ uniforms->push_back(uniformBaseInstance);
+ }
+ if (addBaseVertex)
+ {
+ uniforms->push_back(uniformBaseVertex);
+ }
+
+ return true;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateMultiDrawShaderBuiltins.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateMultiDrawShaderBuiltins.h
new file mode 100644
index 0000000000..792a7c96b2
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/EmulateMultiDrawShaderBuiltins.h
@@ -0,0 +1,47 @@
+//
+// Copyright 2019 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.
+//
+// EmulateGLDrawID is an AST traverser to convert the gl_DrawID builtin
+// to a uniform int
+//
+// EmulateGLBaseVertexBaseInstance is an AST traverser to convert the gl_BaseVertex and
+// gl_BaseInstance builtin to uniform ints
+//
+// EmulateGLBaseInstance is an AST traverser to convert the gl_BaseInstance builtin
+// to a uniform int
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_EMULATEMULTIDRAWSHADERBUILTINS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_EMULATEMULTIDRAWSHADERBUILTINS_H_
+
+#include <GLSLANG/ShaderLang.h>
+#include <vector>
+
+#include "common/angleutils.h"
+#include "compiler/translator/HashNames.h"
+
+namespace sh
+{
+struct ShaderVariable;
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+[[nodiscard]] bool EmulateGLDrawID(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ std::vector<sh::ShaderVariable> *uniforms,
+ bool shouldCollect);
+
+[[nodiscard]] bool EmulateGLBaseVertexBaseInstance(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ std::vector<sh::ShaderVariable> *uniforms,
+ bool shouldCollect,
+ bool addBaseVertexToVertexID);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_EMULATEMULTIDRAWSHADERBUILTINS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/FoldExpressions.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/FoldExpressions.cpp
new file mode 100644
index 0000000000..1ede8c1a46
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/FoldExpressions.cpp
@@ -0,0 +1,120 @@
+//
+// Copyright 2018 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.
+//
+// FoldExpressions.cpp: Fold expressions. This may fold expressions so that the qualifier of the
+// folded node differs from the qualifier of the original expression, so it needs to be done after
+// parsing and validation of qualifiers is complete. Expressions that are folded:
+// 1. Ternary ops with a constant condition.
+// 2. Sequence aka comma ops where the left side has no side effects.
+// 3. Any expressions containing any of the above.
+
+#include "compiler/translator/tree_ops/FoldExpressions.h"
+
+#include "compiler/translator/Diagnostics.h"
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class FoldExpressionsTraverser : public TIntermTraverser
+{
+ public:
+ FoldExpressionsTraverser(TDiagnostics *diagnostics)
+ : TIntermTraverser(true, false, false), mDiagnostics(diagnostics), mDidReplace(false)
+ {}
+
+ bool didReplace() { return mDidReplace; }
+
+ void nextIteration() { mDidReplace = false; }
+
+ protected:
+ bool visitTernary(Visit visit, TIntermTernary *node) override
+ {
+ TIntermTyped *folded = node->fold(mDiagnostics);
+ if (folded != node)
+ {
+ queueReplacement(folded, OriginalNode::IS_DROPPED);
+ mDidReplace = true;
+ return false;
+ }
+ return true;
+ }
+
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override
+ {
+ TIntermTyped *folded = node->fold(mDiagnostics);
+ if (folded != node)
+ {
+ queueReplacement(folded, OriginalNode::IS_DROPPED);
+ mDidReplace = true;
+ return false;
+ }
+ return true;
+ }
+
+ bool visitBinary(Visit visit, TIntermBinary *node) override
+ {
+ TIntermTyped *folded = node->fold(mDiagnostics);
+ if (folded != node)
+ {
+ queueReplacement(folded, OriginalNode::IS_DROPPED);
+ mDidReplace = true;
+ return false;
+ }
+ return true;
+ }
+
+ bool visitUnary(Visit visit, TIntermUnary *node) override
+ {
+ TIntermTyped *folded = node->fold(mDiagnostics);
+ if (folded != node)
+ {
+ queueReplacement(folded, OriginalNode::IS_DROPPED);
+ mDidReplace = true;
+ return false;
+ }
+ return true;
+ }
+
+ bool visitSwizzle(Visit visit, TIntermSwizzle *node) override
+ {
+ TIntermTyped *folded = node->fold(mDiagnostics);
+ if (folded != node)
+ {
+ queueReplacement(folded, OriginalNode::IS_DROPPED);
+ mDidReplace = true;
+ return false;
+ }
+ return true;
+ }
+
+ private:
+ TDiagnostics *mDiagnostics;
+ bool mDidReplace;
+};
+
+} // anonymous namespace
+
+bool FoldExpressions(TCompiler *compiler, TIntermBlock *root, TDiagnostics *diagnostics)
+{
+ FoldExpressionsTraverser traverser(diagnostics);
+ do
+ {
+ traverser.nextIteration();
+ root->traverse(&traverser);
+ if (!traverser.updateTree(compiler, root))
+ {
+ return false;
+ }
+ } while (traverser.didReplace());
+
+ return true;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/FoldExpressions.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/FoldExpressions.h
new file mode 100644
index 0000000000..1592444c50
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/FoldExpressions.h
@@ -0,0 +1,29 @@
+//
+// Copyright 2018 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.
+//
+// FoldExpressions.h: Fold expressions. This may fold expressions so that the qualifier of the
+// folded node differs from the qualifier of the original expression, so it needs to be done after
+// parsing and validation of qualifiers is complete. Expressions that are folded: 1. Ternary ops
+// with a constant condition.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_FOLDEXPRESSIONS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_FOLDEXPRESSIONS_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermBlock;
+class TDiagnostics;
+
+[[nodiscard]] bool FoldExpressions(TCompiler *compiler,
+ TIntermBlock *root,
+ TDiagnostics *diagnostics);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_FOLDEXPRESSIONS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/ForcePrecisionQualifier.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/ForcePrecisionQualifier.cpp
new file mode 100644
index 0000000000..00dd0131c6
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/ForcePrecisionQualifier.cpp
@@ -0,0 +1,101 @@
+//
+// Copyright 2020 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/tree_ops/ForcePrecisionQualifier.h"
+#include "angle_gl.h"
+#include "common/debug.h"
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+class TPrecisionTraverser : public TIntermTraverser
+{
+ public:
+ TPrecisionTraverser(TSymbolTable *symbolTable);
+
+ protected:
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
+
+ void overwriteVariablePrecision(TType *type) const;
+};
+
+TPrecisionTraverser::TPrecisionTraverser(TSymbolTable *symbolTable)
+ : TIntermTraverser(true, true, true, symbolTable)
+{}
+
+void TPrecisionTraverser::overwriteVariablePrecision(TType *type) const
+{
+ if (type->getPrecision() == EbpHigh)
+ {
+ type->setPrecision(EbpMedium);
+ }
+}
+
+bool TPrecisionTraverser::visitDeclaration(Visit visit, TIntermDeclaration *node)
+{
+ // Variable declaration.
+ if (visit == PreVisit)
+ {
+ const TIntermSequence &sequence = *(node->getSequence());
+ TIntermTyped *variable = sequence.front()->getAsTyped();
+ const TType &type = variable->getType();
+ TQualifier qualifier = variable->getQualifier();
+
+ // Don't modify uniform since it might be shared between vertex and fragment shader
+ if (qualifier == EvqUniform)
+ {
+ return true;
+ }
+
+ // Visit the struct.
+ if (type.isStructSpecifier())
+ {
+ const TStructure *structure = type.getStruct();
+ const TFieldList &fields = structure->fields();
+ for (size_t i = 0; i < fields.size(); ++i)
+ {
+ const TField *field = fields[i];
+ const TType *fieldType = field->type();
+ overwriteVariablePrecision((TType *)fieldType);
+ }
+ }
+ else if (type.getBasicType() == EbtInterfaceBlock)
+ {
+ const TInterfaceBlock *interfaceBlock = type.getInterfaceBlock();
+ const TFieldList &fields = interfaceBlock->fields();
+ for (const TField *field : fields)
+ {
+ const TType *fieldType = field->type();
+ overwriteVariablePrecision((TType *)fieldType);
+ }
+ }
+ else
+ {
+ overwriteVariablePrecision((TType *)&type);
+ }
+ }
+ return true;
+}
+} // namespace
+
+bool ForceShaderPrecisionToMediump(TIntermNode *root, TSymbolTable *symbolTable, GLenum shaderType)
+{
+ if (shaderType != GL_FRAGMENT_SHADER)
+ {
+ return true;
+ }
+
+ TPrecisionTraverser traverser(symbolTable);
+ root->traverse(&traverser);
+ return true;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/ForcePrecisionQualifier.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/ForcePrecisionQualifier.h
new file mode 100644
index 0000000000..c4cde25415
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/ForcePrecisionQualifier.h
@@ -0,0 +1,17 @@
+//
+// Copyright 2020 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_TREEOPS_FORCEPRECISIONQUALIFIER_H_
+#define COMPILER_TRANSLATOR_TREEOPS_FORCEPRECISIONQUALIFIER_H_
+
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+bool ForceShaderPrecisionToMediump(TIntermNode *root, TSymbolTable *symbolTable, GLenum shaderType);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_FORCEPRECISIONQUALIFIER_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/InitializeVariables.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/InitializeVariables.cpp
new file mode 100644
index 0000000000..789610ecc0
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/InitializeVariables.cpp
@@ -0,0 +1,359 @@
+//
+// Copyright 2002 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/tree_ops/InitializeVariables.h"
+
+#include "angle_gl.h"
+#include "common/debug.h"
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/StaticType.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/FindMain.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+void AddArrayZeroInitSequence(const TIntermTyped *initializedNode,
+ bool canUseLoopsToInitialize,
+ bool highPrecisionSupported,
+ TIntermSequence *initSequenceOut,
+ TSymbolTable *symbolTable);
+
+void AddStructZeroInitSequence(const TIntermTyped *initializedNode,
+ bool canUseLoopsToInitialize,
+ bool highPrecisionSupported,
+ TIntermSequence *initSequenceOut,
+ TSymbolTable *symbolTable);
+
+TIntermBinary *CreateZeroInitAssignment(const TIntermTyped *initializedNode)
+{
+ TIntermTyped *zero = CreateZeroNode(initializedNode->getType());
+ return new TIntermBinary(EOpAssign, initializedNode->deepCopy(), zero);
+}
+
+void AddZeroInitSequence(const TIntermTyped *initializedNode,
+ bool canUseLoopsToInitialize,
+ bool highPrecisionSupported,
+ TIntermSequence *initSequenceOut,
+ TSymbolTable *symbolTable)
+{
+ if (initializedNode->isArray())
+ {
+ AddArrayZeroInitSequence(initializedNode, canUseLoopsToInitialize, highPrecisionSupported,
+ initSequenceOut, symbolTable);
+ }
+ else if (initializedNode->getType().isStructureContainingArrays() ||
+ initializedNode->getType().isNamelessStruct())
+ {
+ AddStructZeroInitSequence(initializedNode, canUseLoopsToInitialize, highPrecisionSupported,
+ initSequenceOut, symbolTable);
+ }
+ else if (initializedNode->getType().isInterfaceBlock())
+ {
+ const TType &type = initializedNode->getType();
+ const TInterfaceBlock &interfaceBlock = *type.getInterfaceBlock();
+ const TFieldList &fieldList = interfaceBlock.fields();
+ for (size_t fieldIndex = 0; fieldIndex < fieldList.size(); ++fieldIndex)
+ {
+ const TField &field = *fieldList[fieldIndex];
+ TIntermTyped *fieldIndexRef = CreateIndexNode(static_cast<int>(fieldIndex));
+ TIntermTyped *fieldReference =
+ new TIntermBinary(TOperator::EOpIndexDirectInterfaceBlock,
+ initializedNode->deepCopy(), fieldIndexRef);
+ TIntermTyped *fieldZero = CreateZeroNode(*field.type());
+ TIntermTyped *assignment =
+ new TIntermBinary(TOperator::EOpAssign, fieldReference, fieldZero);
+ initSequenceOut->push_back(assignment);
+ }
+ }
+ else
+ {
+ initSequenceOut->push_back(CreateZeroInitAssignment(initializedNode));
+ }
+}
+
+void AddStructZeroInitSequence(const TIntermTyped *initializedNode,
+ bool canUseLoopsToInitialize,
+ bool highPrecisionSupported,
+ TIntermSequence *initSequenceOut,
+ TSymbolTable *symbolTable)
+{
+ ASSERT(initializedNode->getBasicType() == EbtStruct);
+ const TStructure *structType = initializedNode->getType().getStruct();
+ for (int i = 0; i < static_cast<int>(structType->fields().size()); ++i)
+ {
+ TIntermBinary *element = new TIntermBinary(EOpIndexDirectStruct,
+ initializedNode->deepCopy(), CreateIndexNode(i));
+ // Structs can't be defined inside structs, so the type of a struct field can't be a
+ // nameless struct.
+ ASSERT(!element->getType().isNamelessStruct());
+ AddZeroInitSequence(element, canUseLoopsToInitialize, highPrecisionSupported,
+ initSequenceOut, symbolTable);
+ }
+}
+
+void AddArrayZeroInitStatementList(const TIntermTyped *initializedNode,
+ bool canUseLoopsToInitialize,
+ bool highPrecisionSupported,
+ TIntermSequence *initSequenceOut,
+ TSymbolTable *symbolTable)
+{
+ for (unsigned int i = 0; i < initializedNode->getOutermostArraySize(); ++i)
+ {
+ TIntermBinary *element =
+ new TIntermBinary(EOpIndexDirect, initializedNode->deepCopy(), CreateIndexNode(i));
+ AddZeroInitSequence(element, canUseLoopsToInitialize, highPrecisionSupported,
+ initSequenceOut, symbolTable);
+ }
+}
+
+void AddArrayZeroInitForLoop(const TIntermTyped *initializedNode,
+ bool highPrecisionSupported,
+ TIntermSequence *initSequenceOut,
+ TSymbolTable *symbolTable)
+{
+ ASSERT(initializedNode->isArray());
+ const TType *mediumpIndexType = StaticType::Get<EbtInt, EbpMedium, EvqTemporary, 1, 1>();
+ const TType *highpIndexType = StaticType::Get<EbtInt, EbpHigh, EvqTemporary, 1, 1>();
+ TVariable *indexVariable =
+ CreateTempVariable(symbolTable, highPrecisionSupported ? highpIndexType : mediumpIndexType);
+
+ TIntermSymbol *indexSymbolNode = CreateTempSymbolNode(indexVariable);
+ TIntermDeclaration *indexInit =
+ CreateTempInitDeclarationNode(indexVariable, CreateZeroNode(indexVariable->getType()));
+ TIntermConstantUnion *arraySizeNode = CreateIndexNode(initializedNode->getOutermostArraySize());
+ TIntermBinary *indexSmallerThanSize =
+ new TIntermBinary(EOpLessThan, indexSymbolNode->deepCopy(), arraySizeNode);
+ TIntermUnary *indexIncrement =
+ new TIntermUnary(EOpPreIncrement, indexSymbolNode->deepCopy(), nullptr);
+
+ TIntermBlock *forLoopBody = new TIntermBlock();
+ TIntermSequence *forLoopBodySeq = forLoopBody->getSequence();
+
+ TIntermBinary *element = new TIntermBinary(EOpIndexIndirect, initializedNode->deepCopy(),
+ indexSymbolNode->deepCopy());
+ AddZeroInitSequence(element, true, highPrecisionSupported, forLoopBodySeq, symbolTable);
+
+ TIntermLoop *forLoop =
+ new TIntermLoop(ELoopFor, indexInit, indexSmallerThanSize, indexIncrement, forLoopBody);
+ initSequenceOut->push_back(forLoop);
+}
+
+void AddArrayZeroInitSequence(const TIntermTyped *initializedNode,
+ bool canUseLoopsToInitialize,
+ bool highPrecisionSupported,
+ TIntermSequence *initSequenceOut,
+ TSymbolTable *symbolTable)
+{
+ // The array elements are assigned one by one to keep the AST compatible with ESSL 1.00 which
+ // doesn't have array assignment. We'll do this either with a for loop or just a list of
+ // statements assigning to each array index. Note that it is important to have the array init in
+ // the right order to workaround http://crbug.com/709317
+ bool isSmallArray = initializedNode->getOutermostArraySize() <= 1u ||
+ (initializedNode->getBasicType() != EbtStruct &&
+ !initializedNode->getType().isArrayOfArrays() &&
+ initializedNode->getOutermostArraySize() <= 3u);
+ if (initializedNode->getQualifier() == EvqFragData ||
+ initializedNode->getQualifier() == EvqFragmentOut || isSmallArray ||
+ !canUseLoopsToInitialize)
+ {
+ // Fragment outputs should not be indexed by non-constant indices.
+ // Also it doesn't make sense to use loops to initialize very small arrays.
+ AddArrayZeroInitStatementList(initializedNode, canUseLoopsToInitialize,
+ highPrecisionSupported, initSequenceOut, symbolTable);
+ }
+ else
+ {
+ AddArrayZeroInitForLoop(initializedNode, highPrecisionSupported, initSequenceOut,
+ symbolTable);
+ }
+}
+
+void InsertInitCode(TCompiler *compiler,
+ TIntermSequence *mainBody,
+ const InitVariableList &variables,
+ TSymbolTable *symbolTable,
+ int shaderVersion,
+ const TExtensionBehavior &extensionBehavior,
+ bool canUseLoopsToInitialize,
+ bool highPrecisionSupported)
+{
+ for (const ShaderVariable &var : variables)
+ {
+ // Note that tempVariableName will reference a short-lived char array here - that's fine
+ // since we're only using it to find symbols.
+ ImmutableString tempVariableName(var.name.c_str(), var.name.length());
+
+ TIntermTyped *initializedSymbol = nullptr;
+ if (var.isBuiltIn() && !symbolTable->findUserDefined(tempVariableName))
+ {
+ initializedSymbol =
+ ReferenceBuiltInVariable(tempVariableName, *symbolTable, shaderVersion);
+ if (initializedSymbol->getQualifier() == EvqFragData &&
+ !IsExtensionEnabled(extensionBehavior, TExtension::EXT_draw_buffers))
+ {
+ // If GL_EXT_draw_buffers is disabled, only the 0th index of gl_FragData can be
+ // written to.
+ // TODO(oetuaho): This is a bit hacky and would be better to remove, if we came up
+ // with a good way to do it. Right now "gl_FragData" in symbol table is initialized
+ // to have the array size of MaxDrawBuffers, and the initialization happens before
+ // the shader sets the extensions it is using.
+ initializedSymbol =
+ new TIntermBinary(EOpIndexDirect, initializedSymbol, CreateIndexNode(0));
+ }
+ }
+ else
+ {
+ if (tempVariableName != "")
+ {
+ initializedSymbol = ReferenceGlobalVariable(tempVariableName, *symbolTable);
+ }
+ else
+ {
+ // Must be a nameless interface block.
+ ASSERT(var.structOrBlockName != "");
+ const TSymbol *symbol = symbolTable->findGlobal(var.structOrBlockName);
+ ASSERT(symbol && symbol->isInterfaceBlock());
+ const TInterfaceBlock *block = static_cast<const TInterfaceBlock *>(symbol);
+
+ for (const TField *field : block->fields())
+ {
+ initializedSymbol = ReferenceGlobalVariable(field->name(), *symbolTable);
+
+ TIntermSequence initCode;
+ CreateInitCode(initializedSymbol, canUseLoopsToInitialize,
+ highPrecisionSupported, &initCode, symbolTable);
+ mainBody->insert(mainBody->begin(), initCode.begin(), initCode.end());
+ }
+ // Already inserted init code in this case
+ continue;
+ }
+ }
+ ASSERT(initializedSymbol != nullptr);
+
+ TIntermSequence initCode;
+ CreateInitCode(initializedSymbol, canUseLoopsToInitialize, highPrecisionSupported,
+ &initCode, symbolTable);
+ mainBody->insert(mainBody->begin(), initCode.begin(), initCode.end());
+ }
+}
+
+class InitializeLocalsTraverser : public TIntermTraverser
+{
+ public:
+ InitializeLocalsTraverser(int shaderVersion,
+ TSymbolTable *symbolTable,
+ bool canUseLoopsToInitialize,
+ bool highPrecisionSupported)
+ : TIntermTraverser(true, false, false, symbolTable),
+ mShaderVersion(shaderVersion),
+ mCanUseLoopsToInitialize(canUseLoopsToInitialize),
+ mHighPrecisionSupported(highPrecisionSupported)
+ {}
+
+ protected:
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override
+ {
+ for (TIntermNode *declarator : *node->getSequence())
+ {
+ if (!mInGlobalScope && !declarator->getAsBinaryNode())
+ {
+ TIntermSymbol *symbol = declarator->getAsSymbolNode();
+ ASSERT(symbol);
+ if (symbol->variable().symbolType() == SymbolType::Empty)
+ {
+ continue;
+ }
+
+ // Arrays may need to be initialized one element at a time, since ESSL 1.00 does not
+ // support array constructors or assigning arrays.
+ bool arrayConstructorUnavailable =
+ (symbol->isArray() || symbol->getType().isStructureContainingArrays()) &&
+ mShaderVersion == 100;
+ // Nameless struct constructors can't be referred to, so they also need to be
+ // initialized one element at a time.
+ // TODO(oetuaho): Check if it makes sense to initialize using a loop, even if we
+ // could use an initializer. It could at least reduce code size for very large
+ // arrays, but could hurt runtime performance.
+ if (arrayConstructorUnavailable || symbol->getType().isNamelessStruct())
+ {
+ // SimplifyLoopConditions should have been run so the parent node of this node
+ // should not be a loop.
+ ASSERT(getParentNode()->getAsLoopNode() == nullptr);
+ // SeparateDeclarations should have already been run, so we don't need to worry
+ // about further declarators in this declaration depending on the effects of
+ // this declarator.
+ ASSERT(node->getSequence()->size() == 1);
+ TIntermSequence initCode;
+ CreateInitCode(symbol, mCanUseLoopsToInitialize, mHighPrecisionSupported,
+ &initCode, mSymbolTable);
+ insertStatementsInParentBlock(TIntermSequence(), initCode);
+ }
+ else
+ {
+ TIntermBinary *init =
+ new TIntermBinary(EOpInitialize, symbol, CreateZeroNode(symbol->getType()));
+ queueReplacementWithParent(node, symbol, init, OriginalNode::BECOMES_CHILD);
+ }
+ }
+ }
+ return false;
+ }
+
+ private:
+ int mShaderVersion;
+ bool mCanUseLoopsToInitialize;
+ bool mHighPrecisionSupported;
+};
+
+} // namespace
+
+void CreateInitCode(const TIntermTyped *initializedSymbol,
+ bool canUseLoopsToInitialize,
+ bool highPrecisionSupported,
+ TIntermSequence *initCode,
+ TSymbolTable *symbolTable)
+{
+ AddZeroInitSequence(initializedSymbol, canUseLoopsToInitialize, highPrecisionSupported,
+ initCode, symbolTable);
+}
+
+bool InitializeUninitializedLocals(TCompiler *compiler,
+ TIntermBlock *root,
+ int shaderVersion,
+ bool canUseLoopsToInitialize,
+ bool highPrecisionSupported,
+ TSymbolTable *symbolTable)
+{
+ InitializeLocalsTraverser traverser(shaderVersion, symbolTable, canUseLoopsToInitialize,
+ highPrecisionSupported);
+ root->traverse(&traverser);
+ return traverser.updateTree(compiler, root);
+}
+
+bool InitializeVariables(TCompiler *compiler,
+ TIntermBlock *root,
+ const InitVariableList &vars,
+ TSymbolTable *symbolTable,
+ int shaderVersion,
+ const TExtensionBehavior &extensionBehavior,
+ bool canUseLoopsToInitialize,
+ bool highPrecisionSupported)
+{
+ TIntermBlock *body = FindMainBody(root);
+ InsertInitCode(compiler, body->getSequence(), vars, symbolTable, shaderVersion,
+ extensionBehavior, canUseLoopsToInitialize, highPrecisionSupported);
+
+ return compiler->validateAST(root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/InitializeVariables.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/InitializeVariables.h
new file mode 100644
index 0000000000..755b8d72eb
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/InitializeVariables.h
@@ -0,0 +1,60 @@
+//
+// Copyright 2002 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_TREEOPS_INITIALIZEVARIABLES_H_
+#define COMPILER_TRANSLATOR_TREEOPS_INITIALIZEVARIABLES_H_
+
+#include <GLSLANG/ShaderLang.h>
+
+#include "compiler/translator/ExtensionBehavior.h"
+#include "compiler/translator/IntermNode.h"
+
+namespace sh
+{
+class TCompiler;
+class TSymbolTable;
+
+typedef std::vector<sh::ShaderVariable> InitVariableList;
+
+// For all of the functions below: If canUseLoopsToInitialize is set, for loops are used instead of
+// a large number of initializers where it can make sense, such as for initializing large arrays.
+
+// Populate a sequence of assignment operations to initialize "initializedSymbol". initializedSymbol
+// may be an array, struct or any combination of these, as long as it contains only basic types.
+void CreateInitCode(const TIntermTyped *initializedSymbol,
+ bool canUseLoopsToInitialize,
+ bool highPrecisionSupported,
+ TIntermSequence *initCode,
+ TSymbolTable *symbolTable);
+
+// Initialize all uninitialized local variables, so that undefined behavior is avoided.
+[[nodiscard]] bool InitializeUninitializedLocals(TCompiler *compiler,
+ TIntermBlock *root,
+ int shaderVersion,
+ bool canUseLoopsToInitialize,
+ bool highPrecisionSupported,
+ TSymbolTable *symbolTable);
+
+// This function can initialize all the types that CreateInitCode is able to initialize. All
+// variables must be globals which can be found in the symbol table. For now it is used for the
+// following two scenarios:
+// 1. Initializing gl_Position;
+// 2. Initializing output variables referred to in the shader source.
+// Note: The type of each lvalue in an initializer is retrieved from the symbol table. gl_FragData
+// requires special handling because the number of indices which can be initialized is determined by
+// enabled extensions.
+[[nodiscard]] bool InitializeVariables(TCompiler *compiler,
+ TIntermBlock *root,
+ const InitVariableList &vars,
+ TSymbolTable *symbolTable,
+ int shaderVersion,
+ const TExtensionBehavior &extensionBehavior,
+ bool canUseLoopsToInitialize,
+ bool highPrecisionSupported);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_INITIALIZEVARIABLES_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/MonomorphizeUnsupportedFunctions.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/MonomorphizeUnsupportedFunctions.cpp
new file mode 100644
index 0000000000..11c8b72002
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/MonomorphizeUnsupportedFunctions.cpp
@@ -0,0 +1,613 @@
+//
+// Copyright 2021 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.
+//
+// MonomorphizeUnsupportedFunctions: Monomorphize functions that are called with
+// parameters that are incompatible with both Vulkan GLSL and Metal.
+//
+
+#include "compiler/translator/tree_ops/MonomorphizeUnsupportedFunctions.h"
+
+#include "compiler/translator/ImmutableStringBuilder.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/tree_util/ReplaceVariable.h"
+
+namespace sh
+{
+namespace
+{
+struct Argument
+{
+ size_t argumentIndex;
+ TIntermTyped *argument;
+};
+
+struct FunctionData
+{
+ // Whether the original function is used. If this is false, the function can be removed because
+ // all callers have been modified.
+ bool isOriginalUsed;
+ // The original definition of the function, used to create the monomorphized version.
+ TIntermFunctionDefinition *originalDefinition;
+ // List of monomorphized versions of this function. They will be added next to the original
+ // version (or replace it).
+ TVector<TIntermFunctionDefinition *> monomorphizedDefinitions;
+};
+
+using FunctionMap = angle::HashMap<const TFunction *, FunctionData>;
+
+// Traverse the function definitions and initialize the map. Allows visitAggregate to have access
+// to TIntermFunctionDefinition even when the function is only forward declared at that point.
+void InitializeFunctionMap(TIntermBlock *root, FunctionMap *functionMapOut)
+{
+ TIntermSequence &sequence = *root->getSequence();
+
+ for (TIntermNode *node : sequence)
+ {
+ TIntermFunctionDefinition *asFuncDef = node->getAsFunctionDefinition();
+ if (asFuncDef != nullptr)
+ {
+ const TFunction *function = asFuncDef->getFunction();
+ ASSERT(function && functionMapOut->find(function) == functionMapOut->end());
+ (*functionMapOut)[function] = FunctionData{false, asFuncDef, {}};
+ }
+ }
+}
+
+const TVariable *GetBaseUniform(TIntermTyped *node, bool *isSamplerInStructOut)
+{
+ *isSamplerInStructOut = false;
+
+ while (node->getAsBinaryNode())
+ {
+ TIntermBinary *asBinary = node->getAsBinaryNode();
+
+ TOperator op = asBinary->getOp();
+
+ // No opaque uniform can be inside an interface block.
+ if (op == EOpIndexDirectInterfaceBlock)
+ {
+ return nullptr;
+ }
+
+ if (op == EOpIndexDirectStruct)
+ {
+ *isSamplerInStructOut = true;
+ }
+
+ node = asBinary->getLeft();
+ }
+
+ // Only interested in uniform opaque types. If a function call within another function uses
+ // opaque uniforms in an unsupported way, it will be replaced in a follow up pass after the
+ // calling function is monomorphized.
+ if (node->getType().getQualifier() != EvqUniform)
+ {
+ return nullptr;
+ }
+
+ ASSERT(IsOpaqueType(node->getType().getBasicType()) ||
+ node->getType().isStructureContainingSamplers());
+
+ TIntermSymbol *asSymbol = node->getAsSymbolNode();
+ ASSERT(asSymbol);
+
+ return &asSymbol->variable();
+}
+
+TIntermTyped *ExtractSideEffects(TSymbolTable *symbolTable,
+ TIntermTyped *node,
+ TIntermSequence *replacementIndices)
+{
+ TIntermTyped *withoutSideEffects = node->deepCopy();
+
+ for (TIntermBinary *asBinary = withoutSideEffects->getAsBinaryNode(); asBinary;
+ asBinary = asBinary->getLeft()->getAsBinaryNode())
+ {
+ TOperator op = asBinary->getOp();
+ TIntermTyped *index = asBinary->getRight();
+
+ if (op == EOpIndexDirectStruct)
+ {
+ break;
+ }
+
+ // No side effects with constant expressions.
+ if (op == EOpIndexDirect)
+ {
+ ASSERT(index->getAsConstantUnion());
+ continue;
+ }
+
+ ASSERT(op == EOpIndexIndirect);
+
+ // If the index is a symbol, there's no side effect, so leave it as-is.
+ if (index->getAsSymbolNode())
+ {
+ continue;
+ }
+
+ // Otherwise create a temp variable initialized with the index and use that temp variable as
+ // the index.
+ TIntermDeclaration *tempDecl = nullptr;
+ TVariable *tempVar = DeclareTempVariable(symbolTable, index, EvqTemporary, &tempDecl);
+
+ replacementIndices->push_back(tempDecl);
+ asBinary->replaceChildNode(index, new TIntermSymbol(tempVar));
+ }
+
+ return withoutSideEffects;
+}
+
+void CreateMonomorphizedFunctionCallArgs(const TIntermSequence &originalCallArguments,
+ const TVector<Argument> &replacedArguments,
+ TIntermSequence *substituteArgsOut)
+{
+ size_t nextReplacedArg = 0;
+ for (size_t argIndex = 0; argIndex < originalCallArguments.size(); ++argIndex)
+ {
+ if (nextReplacedArg >= replacedArguments.size() ||
+ argIndex != replacedArguments[nextReplacedArg].argumentIndex)
+ {
+ // Not replaced, keep argument as is.
+ substituteArgsOut->push_back(originalCallArguments[argIndex]);
+ }
+ else
+ {
+ TIntermTyped *argument = replacedArguments[nextReplacedArg].argument;
+
+ // Iterate over indices of the argument and create a new arg for every non-const
+ // index. Note that the index itself may be an expression, and it may require further
+ // substitution in the next pass.
+ while (argument->getAsBinaryNode())
+ {
+ TIntermBinary *asBinary = argument->getAsBinaryNode();
+ if (asBinary->getOp() == EOpIndexIndirect)
+ {
+ TIntermTyped *index = asBinary->getRight();
+ substituteArgsOut->push_back(index->deepCopy());
+ }
+ argument = asBinary->getLeft();
+ }
+
+ ++nextReplacedArg;
+ }
+ }
+}
+
+const TFunction *MonomorphizeFunction(TSymbolTable *symbolTable,
+ const TFunction *original,
+ TVector<Argument> *replacedArguments,
+ VariableReplacementMap *argumentMapOut)
+{
+ TFunction *substituteFunction =
+ new TFunction(symbolTable, kEmptyImmutableString, SymbolType::AngleInternal,
+ &original->getReturnType(), original->isKnownToNotHaveSideEffects());
+
+ size_t nextReplacedArg = 0;
+ for (size_t paramIndex = 0; paramIndex < original->getParamCount(); ++paramIndex)
+ {
+ const TVariable *originalParam = original->getParam(paramIndex);
+
+ if (nextReplacedArg >= replacedArguments->size() ||
+ paramIndex != (*replacedArguments)[nextReplacedArg].argumentIndex)
+ {
+ TVariable *substituteArgument =
+ new TVariable(symbolTable, originalParam->name(), &originalParam->getType(),
+ originalParam->symbolType());
+ // Not replaced, add an identical parameter.
+ substituteFunction->addParameter(substituteArgument);
+ (*argumentMapOut)[originalParam] = new TIntermSymbol(substituteArgument);
+ }
+ else
+ {
+ TIntermTyped *substituteArgument = (*replacedArguments)[nextReplacedArg].argument;
+ (*argumentMapOut)[originalParam] = substituteArgument;
+
+ // Iterate over indices of the argument and create a new parameter for every non-const
+ // index (which may be an expression). Replace the symbol in the argument with a
+ // variable of the index type. This is later used to replace the parameter in the
+ // function body.
+ while (substituteArgument->getAsBinaryNode())
+ {
+ TIntermBinary *asBinary = substituteArgument->getAsBinaryNode();
+ if (asBinary->getOp() == EOpIndexIndirect)
+ {
+ TIntermTyped *index = asBinary->getRight();
+ TType *indexType = new TType(index->getType());
+ indexType->setQualifier(EvqParamIn);
+
+ TVariable *param = new TVariable(symbolTable, kEmptyImmutableString, indexType,
+ SymbolType::AngleInternal);
+ substituteFunction->addParameter(param);
+
+ // The argument now uses the function parameters as indices.
+ asBinary->replaceChildNode(asBinary->getRight(), new TIntermSymbol(param));
+ }
+ substituteArgument = asBinary->getLeft();
+ }
+
+ ++nextReplacedArg;
+ }
+ }
+
+ return substituteFunction;
+}
+
+class MonomorphizeTraverser final : public TIntermTraverser
+{
+ public:
+ explicit MonomorphizeTraverser(TCompiler *compiler,
+ TSymbolTable *symbolTable,
+ const ShCompileOptions &compileOptions,
+ UnsupportedFunctionArgsBitSet unsupportedFunctionArgs,
+ FunctionMap *functionMap)
+ : TIntermTraverser(true, false, false, symbolTable),
+ mCompiler(compiler),
+ mCompileOptions(compileOptions),
+ mUnsupportedFunctionArgs(unsupportedFunctionArgs),
+ mFunctionMap(functionMap)
+ {}
+
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override
+ {
+ if (node->getOp() != EOpCallFunctionInAST)
+ {
+ return true;
+ }
+
+ const TFunction *function = node->getFunction();
+ ASSERT(function && mFunctionMap->find(function) != mFunctionMap->end());
+
+ FunctionData &data = (*mFunctionMap)[function];
+
+ TIntermFunctionDefinition *monomorphized =
+ processFunctionCall(node, data.originalDefinition, &data.isOriginalUsed);
+ if (monomorphized)
+ {
+ data.monomorphizedDefinitions.push_back(monomorphized);
+ }
+
+ return true;
+ }
+
+ bool getAnyMonomorphized() const { return mAnyMonomorphized; }
+
+ private:
+ bool isUnsupportedArgument(TIntermTyped *callArgument, const TVariable *funcArgument) const
+ {
+ // Only interested in opaque uniforms and structs that contain samplers.
+ const bool isOpaqueType = IsOpaqueType(funcArgument->getType().getBasicType());
+ const bool isStructContainingSamplers =
+ funcArgument->getType().isStructureContainingSamplers();
+ if (!isOpaqueType && !isStructContainingSamplers)
+ {
+ return false;
+ }
+
+ // If not uniform (the variable was itself a function parameter), don't process it in
+ // this pass, as we don't know which actual uniform it corresponds to.
+ bool isSamplerInStruct = false;
+ const TVariable *uniform = GetBaseUniform(callArgument, &isSamplerInStruct);
+ if (uniform == nullptr)
+ {
+ return false;
+ }
+
+ const TType &type = uniform->getType();
+
+ if (mUnsupportedFunctionArgs[UnsupportedFunctionArgs::StructContainingSamplers])
+ {
+ // Monomorphize if the parameter is a structure that contains samplers (so in
+ // RewriteStructSamplers we don't need to rewrite the functions to accept multiple
+ // parameters split from the struct).
+ if (isStructContainingSamplers)
+ {
+ return true;
+ }
+ }
+
+ if (mUnsupportedFunctionArgs[UnsupportedFunctionArgs::ArrayOfArrayOfSamplerOrImage])
+ {
+ // Monomorphize if:
+ //
+ // - The opaque uniform is a sampler in a struct (which can create an array-of-array
+ // situation), and the function expects an array of samplers, or
+ //
+ // - The opaque uniform is an array of array of sampler or image, and it's partially
+ // subscripted (i.e. the function itself expects an array)
+ //
+ const bool isParameterArrayOfOpaqueType = funcArgument->getType().isArray();
+ const bool isArrayOfArrayOfSamplerOrImage =
+ (type.isSampler() || type.isImage()) && type.isArrayOfArrays();
+ if (isSamplerInStruct && isParameterArrayOfOpaqueType)
+ {
+ return true;
+ }
+ if (isArrayOfArrayOfSamplerOrImage && isParameterArrayOfOpaqueType)
+ {
+ return true;
+ }
+ }
+
+ if (mUnsupportedFunctionArgs[UnsupportedFunctionArgs::AtomicCounter])
+ {
+ if (type.isAtomicCounter())
+ {
+ return true;
+ }
+ }
+
+ if (mUnsupportedFunctionArgs[UnsupportedFunctionArgs::SamplerCubeEmulation])
+ {
+ // Monomorphize if the opaque uniform is a samplerCube and ES2's cube sampling emulation
+ // is requested.
+ if (type.isSamplerCube() && mCompileOptions.emulateSeamfulCubeMapSampling)
+ {
+ return true;
+ }
+ }
+
+ if (mUnsupportedFunctionArgs[UnsupportedFunctionArgs::Image])
+ {
+ if (type.isImage())
+ {
+ return true;
+ }
+ }
+
+ if (mUnsupportedFunctionArgs[UnsupportedFunctionArgs::PixelLocalStorage])
+ {
+ if (type.isPixelLocal())
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ TIntermFunctionDefinition *processFunctionCall(TIntermAggregate *functionCall,
+ TIntermFunctionDefinition *originalDefinition,
+ bool *isOriginalUsedOut)
+ {
+ const TFunction *function = functionCall->getFunction();
+ const TIntermSequence &callArguments = *functionCall->getSequence();
+
+ TVector<Argument> replacedArguments;
+ TIntermSequence replacementIndices;
+
+ // Go through function call arguments, and see if any is used in an unsupported way.
+ for (size_t argIndex = 0; argIndex < callArguments.size(); ++argIndex)
+ {
+ TIntermTyped *callArgument = callArguments[argIndex]->getAsTyped();
+ const TVariable *funcArgument = function->getParam(argIndex);
+ if (isUnsupportedArgument(callArgument, funcArgument))
+ {
+ // Copy the argument and extract the side effects.
+ TIntermTyped *argument =
+ ExtractSideEffects(mSymbolTable, callArgument, &replacementIndices);
+
+ replacedArguments.push_back({argIndex, argument});
+ }
+ }
+
+ if (replacedArguments.empty())
+ {
+ *isOriginalUsedOut = true;
+ return nullptr;
+ }
+
+ mAnyMonomorphized = true;
+
+ insertStatementsInParentBlock(replacementIndices);
+
+ // Create the arguments for the substitute function call. Done before monomorphizing the
+ // function, which transforms the arguments to what needs to be replaced in the function
+ // body.
+ TIntermSequence newCallArgs;
+ CreateMonomorphizedFunctionCallArgs(callArguments, replacedArguments, &newCallArgs);
+
+ // Duplicate the function and substitute the replaced arguments with only the non-const
+ // indices. Additionally, substitute the non-const indices of arguments with the new
+ // function parameters.
+ VariableReplacementMap argumentMap;
+ const TFunction *monomorphized =
+ MonomorphizeFunction(mSymbolTable, function, &replacedArguments, &argumentMap);
+
+ // Replace this function call with a call to the new one.
+ queueReplacement(TIntermAggregate::CreateFunctionCall(*monomorphized, &newCallArgs),
+ OriginalNode::IS_DROPPED);
+
+ // Create a new function definition, with the body of the old function but with the replaced
+ // parameters substituted with the calling expressions.
+ TIntermFunctionPrototype *substitutePrototype = new TIntermFunctionPrototype(monomorphized);
+ TIntermBlock *substituteBlock = originalDefinition->getBody()->deepCopy();
+ GetDeclaratorReplacements(mSymbolTable, substituteBlock, &argumentMap);
+ bool valid = ReplaceVariables(mCompiler, substituteBlock, argumentMap);
+ ASSERT(valid);
+
+ return new TIntermFunctionDefinition(substitutePrototype, substituteBlock);
+ }
+
+ TCompiler *mCompiler;
+ const ShCompileOptions &mCompileOptions;
+ UnsupportedFunctionArgsBitSet mUnsupportedFunctionArgs;
+ bool mAnyMonomorphized = false;
+
+ // Map of original to monomorphized functions.
+ FunctionMap *mFunctionMap;
+};
+
+class UpdateFunctionsDefinitionsTraverser final : public TIntermTraverser
+{
+ public:
+ explicit UpdateFunctionsDefinitionsTraverser(TSymbolTable *symbolTable,
+ const FunctionMap &functionMap)
+ : TIntermTraverser(true, false, false, symbolTable), mFunctionMap(functionMap)
+ {}
+
+ void visitFunctionPrototype(TIntermFunctionPrototype *node) override
+ {
+ const bool isInFunctionDefinition = getParentNode()->getAsFunctionDefinition() != nullptr;
+ if (isInFunctionDefinition)
+ {
+ return;
+ }
+
+ // Add to and possibly replace the function prototype with replacement prototypes.
+ const TFunction *function = node->getFunction();
+ ASSERT(function && mFunctionMap.find(function) != mFunctionMap.end());
+
+ const FunctionData &data = mFunctionMap.at(function);
+
+ // If nothing to do, leave it be.
+ if (data.monomorphizedDefinitions.empty())
+ {
+ ASSERT(data.isOriginalUsed);
+ return;
+ }
+
+ // Replace the prototype with itself (if function is still used) as well as any
+ // monomorphized versions.
+ TIntermSequence replacement;
+ if (data.isOriginalUsed)
+ {
+ replacement.push_back(node);
+ }
+ for (TIntermFunctionDefinition *monomorphizedDefinition : data.monomorphizedDefinitions)
+ {
+ replacement.push_back(new TIntermFunctionPrototype(
+ monomorphizedDefinition->getFunctionPrototype()->getFunction()));
+ }
+ mMultiReplacements.emplace_back(getParentNode()->getAsBlock(), node,
+ std::move(replacement));
+ }
+
+ bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override
+ {
+ // Add to and possibly replace the function definition with replacement definitions.
+ const TFunction *function = node->getFunction();
+ ASSERT(function && mFunctionMap.find(function) != mFunctionMap.end());
+
+ const FunctionData &data = mFunctionMap.at(function);
+
+ // If nothing to do, leave it be.
+ if (data.monomorphizedDefinitions.empty())
+ {
+ ASSERT(data.isOriginalUsed || function->name() == "main");
+ return false;
+ }
+
+ // Replace the definition with itself (if function is still used) as well as any
+ // monomorphized versions.
+ TIntermSequence replacement;
+ if (data.isOriginalUsed)
+ {
+ replacement.push_back(node);
+ }
+ for (TIntermFunctionDefinition *monomorphizedDefinition : data.monomorphizedDefinitions)
+ {
+ replacement.push_back(monomorphizedDefinition);
+ }
+ mMultiReplacements.emplace_back(getParentNode()->getAsBlock(), node,
+ std::move(replacement));
+
+ return false;
+ }
+
+ private:
+ const FunctionMap &mFunctionMap;
+};
+
+void SortDeclarations(TIntermBlock *root)
+{
+ TIntermSequence *original = root->getSequence();
+
+ TIntermSequence replacement;
+ TIntermSequence functionDefs;
+
+ // Accumulate non-function-definition declarations in |replacement| and function definitions in
+ // |functionDefs|.
+ for (TIntermNode *node : *original)
+ {
+ if (node->getAsFunctionDefinition() || node->getAsFunctionPrototypeNode())
+ {
+ functionDefs.push_back(node);
+ }
+ else
+ {
+ replacement.push_back(node);
+ }
+ }
+
+ // Append function definitions to |replacement|.
+ replacement.insert(replacement.end(), functionDefs.begin(), functionDefs.end());
+
+ // Replace root's sequence with |replacement|.
+ root->replaceAllChildren(replacement);
+}
+
+bool MonomorphizeUnsupportedFunctionsImpl(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ const ShCompileOptions &compileOptions,
+ UnsupportedFunctionArgsBitSet unsupportedFunctionArgs)
+{
+ // First, sort out the declarations such that all non-function declarations are placed before
+ // function definitions. This way when the function is replaced with one that references said
+ // declarations (i.e. uniforms), the uniform declaration is already present above it.
+ SortDeclarations(root);
+
+ while (true)
+ {
+ FunctionMap functionMap;
+ InitializeFunctionMap(root, &functionMap);
+
+ MonomorphizeTraverser monomorphizer(compiler, symbolTable, compileOptions,
+ unsupportedFunctionArgs, &functionMap);
+ root->traverse(&monomorphizer);
+
+ if (!monomorphizer.getAnyMonomorphized())
+ {
+ break;
+ }
+
+ if (!monomorphizer.updateTree(compiler, root))
+ {
+ return false;
+ }
+
+ UpdateFunctionsDefinitionsTraverser functionUpdater(symbolTable, functionMap);
+ root->traverse(&functionUpdater);
+
+ if (!functionUpdater.updateTree(compiler, root))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+} // anonymous namespace
+
+bool MonomorphizeUnsupportedFunctions(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ const ShCompileOptions &compileOptions,
+ UnsupportedFunctionArgsBitSet unsupportedFunctionArgs)
+{
+ // This function actually applies multiple transformation, and the AST may not be valid until
+ // the transformations are entirely done. Some validation is momentarily disabled.
+ bool enableValidateFunctionCall = compiler->disableValidateFunctionCall();
+
+ bool result = MonomorphizeUnsupportedFunctionsImpl(compiler, root, symbolTable, compileOptions,
+ unsupportedFunctionArgs);
+
+ compiler->restoreValidateFunctionCall(enableValidateFunctionCall);
+ return result && compiler->validateAST(root);
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/MonomorphizeUnsupportedFunctions.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/MonomorphizeUnsupportedFunctions.h
new file mode 100644
index 0000000000..a9a212704b
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/MonomorphizeUnsupportedFunctions.h
@@ -0,0 +1,54 @@
+//
+// Copyright 2021 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.
+//
+// MonomorphizeUnsupportedFunctions: Monomorphize functions that are called with
+// parameters that are incompatible with both Vulkan GLSL and Metal:
+//
+// - Samplers in structs
+// - Structs that have samplers
+// - Partially subscripted array of array of samplers
+// - Partially subscripted array of array of images
+// - Atomic counters
+// - samplerCube variables when emulating ES2's cube map sampling
+// - image* variables with r32f formats (to emulate imageAtomicExchange)
+//
+// This transformation basically duplicates such functions, removes the
+// sampler/image/atomic_counter parameters and uses the opaque uniforms used by the caller.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_VULKAN_MONOMORPHIZEUNSUPPORTEDFUNCTIONS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_VULKAN_MONOMORPHIZEUNSUPPORTEDFUNCTIONS_H_
+
+#include "common/angleutils.h"
+#include "compiler/translator/Compiler.h"
+
+namespace sh
+{
+class TIntermBlock;
+class TSymbolTable;
+
+// Types of function prameters that should trigger monomorphization.
+enum class UnsupportedFunctionArgs
+{
+ StructContainingSamplers = 0,
+ ArrayOfArrayOfSamplerOrImage = 1,
+ AtomicCounter = 2,
+ SamplerCubeEmulation = 3,
+ Image = 4,
+ PixelLocalStorage = 5,
+
+ InvalidEnum = 6,
+ EnumCount = 6,
+};
+
+using UnsupportedFunctionArgsBitSet = angle::PackedEnumBitSet<UnsupportedFunctionArgs>;
+
+[[nodiscard]] bool MonomorphizeUnsupportedFunctions(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ const ShCompileOptions &compileOptions,
+ UnsupportedFunctionArgsBitSet);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_VULKAN_MONOMORPHIZEUNSUPPORTEDFUNCTIONS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/NameNamelessUniformBuffers.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/NameNamelessUniformBuffers.cpp
new file mode 100644
index 0000000000..a23d0770ef
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/NameNamelessUniformBuffers.cpp
@@ -0,0 +1,127 @@
+//
+// Copyright 2019 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.
+//
+// NameNamelessUniformBuffers: Gives nameless uniform buffer variables internal names.
+//
+
+#include "compiler/translator/tree_ops/NameNamelessUniformBuffers.h"
+
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+namespace
+{
+// Traverse uniform buffer declarations and give name to nameless declarations. Keeps track of
+// the interface fields which will be used in the source without the interface block variable name
+// and replaces them with name.field.
+class NameUniformBufferVariablesTraverser : public TIntermTraverser
+{
+ public:
+ explicit NameUniformBufferVariablesTraverser(TSymbolTable *symbolTable)
+ : TIntermTraverser(true, false, false, symbolTable)
+ {}
+
+ bool visitDeclaration(Visit visit, TIntermDeclaration *decl) override
+ {
+ ASSERT(visit == PreVisit);
+
+ const TIntermSequence &sequence = *(decl->getSequence());
+
+ TIntermTyped *variableNode = sequence.front()->getAsTyped();
+ const TType &type = variableNode->getType();
+
+ // If it's an interface block, it may have to be converted if it contains any row-major
+ // fields.
+ if (!type.isInterfaceBlock())
+ {
+ return true;
+ }
+
+ // Multi declaration statements are already separated, so there can only be one variable
+ // here.
+ ASSERT(sequence.size() == 1);
+ const TVariable *variable = &variableNode->getAsSymbolNode()->variable();
+ if (variable->symbolType() != SymbolType::Empty)
+ {
+ return false;
+ }
+
+ TIntermDeclaration *newDeclaration = new TIntermDeclaration;
+ TVariable *newVariable = new TVariable(mSymbolTable, kEmptyImmutableString, &type,
+ SymbolType::AngleInternal, variable->extensions());
+ newDeclaration->appendDeclarator(new TIntermSymbol(newVariable));
+
+ queueReplacement(newDeclaration, OriginalNode::IS_DROPPED);
+
+ // It's safe to key the map with the interface block, as there couldn't have been multiple
+ // declarations with this interface block (as the variable is nameless), so for nameless
+ // uniform buffers, the interface block is unique.
+ mNamelessUniformBuffersMap[type.getInterfaceBlock()] = newVariable;
+
+ return false;
+ }
+
+ void visitSymbol(TIntermSymbol *symbol) override
+ {
+ const TType &type = symbol->getType();
+
+ // The symbols we are looking for have the interface block pointer set, but are not
+ // interface blocks. These are references to fields of nameless uniform buffers.
+ if (type.isInterfaceBlock() || type.getInterfaceBlock() == nullptr)
+ {
+ return;
+ }
+
+ const TInterfaceBlock *block = type.getInterfaceBlock();
+
+ // If block variable is not nameless, there's nothing to do.
+ if (mNamelessUniformBuffersMap.count(block) == 0)
+ {
+ return;
+ }
+
+ const ImmutableString symbolName = symbol->getName();
+
+ // Find which field it is
+ const TVector<TField *> fields = block->fields();
+ for (size_t fieldIndex = 0; fieldIndex < fields.size(); ++fieldIndex)
+ {
+ const TField *field = fields[fieldIndex];
+ if (field->name() != symbolName)
+ {
+ continue;
+ }
+
+ // Replace this node with a binary node that indexes the named uniform buffer.
+ TIntermSymbol *namedUniformBuffer =
+ new TIntermSymbol(mNamelessUniformBuffersMap[block]);
+ TIntermBinary *replacement =
+ new TIntermBinary(EOpIndexDirectInterfaceBlock, namedUniformBuffer,
+ CreateIndexNode(static_cast<uint32_t>(fieldIndex)));
+
+ queueReplacement(replacement, OriginalNode::IS_DROPPED);
+
+ return;
+ }
+
+ UNREACHABLE();
+ }
+
+ private:
+ // A map from nameless uniform buffers to their named replacements.
+ std::unordered_map<const TInterfaceBlock *, const TVariable *> mNamelessUniformBuffersMap;
+};
+} // anonymous namespace
+
+bool NameNamelessUniformBuffers(TCompiler *compiler, TIntermBlock *root, TSymbolTable *symbolTable)
+{
+ NameUniformBufferVariablesTraverser nameUniformBufferVariables(symbolTable);
+ root->traverse(&nameUniformBufferVariables);
+ return nameUniformBufferVariables.updateTree(compiler, root);
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/NameNamelessUniformBuffers.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/NameNamelessUniformBuffers.h
new file mode 100644
index 0000000000..23964a5846
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/NameNamelessUniformBuffers.h
@@ -0,0 +1,32 @@
+//
+// Copyright 2019 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.
+//
+// NameNamelessUniformBuffers: Gives nameless uniform buffer variables internal names.
+//
+// For example:
+// uniform UniformBuffer { int a; };
+// x = a;
+// becomes:
+// uniform UniformBuffer { int a; } s123;
+// x = s123.a;
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_NAMENAMELESSUNIFORMBUFFERS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_NAMENAMELESSUNIFORMBUFFERS_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+[[nodiscard]] bool NameNamelessUniformBuffers(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_NAMENAMELESSUNIFORMBUFFERS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/PruneEmptyCases.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/PruneEmptyCases.cpp
new file mode 100644
index 0000000000..276c8c98ed
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/PruneEmptyCases.cpp
@@ -0,0 +1,127 @@
+//
+// Copyright 2018 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.
+//
+// PruneEmptyCases.cpp: The PruneEmptyCases function prunes cases that are followed by nothing from
+// the AST.
+
+#include "compiler/translator/tree_ops/PruneEmptyCases.h"
+
+#include "compiler/translator/Symbol.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+bool AreEmptyBlocks(const TIntermSequence *statements);
+
+bool IsEmptyBlock(TIntermNode *node)
+{
+ TIntermBlock *asBlock = node->getAsBlock();
+ if (asBlock)
+ {
+ return AreEmptyBlocks(asBlock->getSequence());
+ }
+ // Empty declarations should have already been pruned, otherwise they would need to be handled
+ // here. Note that declarations for struct types do contain a nameless child node.
+ ASSERT(node->getAsDeclarationNode() == nullptr ||
+ !node->getAsDeclarationNode()->getSequence()->empty());
+ // Pure literal statements should also already be pruned.
+ ASSERT(node->getAsConstantUnion() == nullptr);
+ return false;
+}
+
+// Return true if all statements in "statements" consist only of empty blocks and no-op statements.
+// Returns true also if there are no statements.
+bool AreEmptyBlocks(const TIntermSequence *statements)
+{
+ for (size_t i = 0u; i < statements->size(); ++i)
+ {
+ if (!IsEmptyBlock(statements->at(i)))
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+class PruneEmptyCasesTraverser : private TIntermTraverser
+{
+ public:
+ [[nodiscard]] static bool apply(TCompiler *compiler, TIntermBlock *root);
+
+ private:
+ PruneEmptyCasesTraverser();
+ bool visitSwitch(Visit visit, TIntermSwitch *node) override;
+};
+
+bool PruneEmptyCasesTraverser::apply(TCompiler *compiler, TIntermBlock *root)
+{
+ PruneEmptyCasesTraverser prune;
+ root->traverse(&prune);
+ return prune.updateTree(compiler, root);
+}
+
+PruneEmptyCasesTraverser::PruneEmptyCasesTraverser() : TIntermTraverser(true, false, false) {}
+
+bool PruneEmptyCasesTraverser::visitSwitch(Visit visit, TIntermSwitch *node)
+{
+ // This may mutate the statementList, but that's okay, since traversal has not yet reached
+ // there.
+ TIntermBlock *statementList = node->getStatementList();
+ TIntermSequence *statements = statementList->getSequence();
+
+ // Iterate block children in reverse order. Cases that are only followed by other cases or empty
+ // blocks are marked for pruning.
+ size_t i = statements->size();
+ size_t lastNoOpInStatementList = i;
+ while (i > 0)
+ {
+ --i;
+ TIntermNode *statement = statements->at(i);
+ if (statement->getAsCaseNode() || IsEmptyBlock(statement))
+ {
+ lastNoOpInStatementList = i;
+ }
+ else
+ {
+ break;
+ }
+ }
+ if (lastNoOpInStatementList == 0)
+ {
+ // Remove the entire switch statement, extracting the init expression if needed.
+ TIntermTyped *init = node->getInit();
+ if (init->hasSideEffects())
+ {
+ queueReplacement(init, OriginalNode::IS_DROPPED);
+ }
+ else
+ {
+ TIntermSequence emptyReplacement;
+ ASSERT(getParentNode()->getAsBlock());
+ mMultiReplacements.emplace_back(getParentNode()->getAsBlock(), node,
+ std::move(emptyReplacement));
+ }
+ return false;
+ }
+ if (lastNoOpInStatementList < statements->size())
+ {
+ statements->erase(statements->begin() + lastNoOpInStatementList, statements->end());
+ }
+
+ return true;
+}
+
+} // namespace
+
+bool PruneEmptyCases(TCompiler *compiler, TIntermBlock *root)
+{
+ return PruneEmptyCasesTraverser::apply(compiler, root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/PruneEmptyCases.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/PruneEmptyCases.h
new file mode 100644
index 0000000000..5098fec9b7
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/PruneEmptyCases.h
@@ -0,0 +1,22 @@
+//
+// Copyright 2018 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.
+//
+// PruneEmptyCases.h: The PruneEmptyCases function prunes cases that are followed by nothing from
+// the AST.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_PRUNEEMPTYCASES_H_
+#define COMPILER_TRANSLATOR_TREEOPS_PRUNEEMPTYCASES_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermBlock;
+
+[[nodiscard]] bool PruneEmptyCases(TCompiler *compiler, TIntermBlock *root);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_PRUNEEMPTYCASES_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/PruneNoOps.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/PruneNoOps.cpp
new file mode 100644
index 0000000000..fdc6070660
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/PruneNoOps.cpp
@@ -0,0 +1,215 @@
+//
+// Copyright 2002 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.
+//
+// PruneNoOps.cpp: The PruneNoOps function prunes:
+// 1. Empty declarations "int;". Empty declarators will be pruned as well, so for example:
+// int , a;
+// is turned into
+// int a;
+// 2. Literal statements: "1.0;". The ESSL output doesn't define a default precision for float,
+// so float literal statements would end up with no precision which is invalid ESSL.
+// 3. Statements after discard, return, break and continue.
+
+#include "compiler/translator/tree_ops/PruneNoOps.h"
+
+#include "compiler/translator/Symbol.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+bool IsNoOp(TIntermNode *node)
+{
+ if (node->getAsConstantUnion() != nullptr)
+ {
+ return true;
+ }
+ bool isEmptyDeclaration = node->getAsDeclarationNode() != nullptr &&
+ node->getAsDeclarationNode()->getSequence()->empty();
+ if (isEmptyDeclaration)
+ {
+ return true;
+ }
+ return false;
+}
+
+class PruneNoOpsTraverser : private TIntermTraverser
+{
+ public:
+ [[nodiscard]] static bool apply(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable);
+
+ private:
+ PruneNoOpsTraverser(TSymbolTable *symbolTable);
+ bool visitDeclaration(Visit, TIntermDeclaration *node) override;
+ bool visitBlock(Visit visit, TIntermBlock *node) override;
+ bool visitLoop(Visit visit, TIntermLoop *loop) override;
+ bool visitBranch(Visit visit, TIntermBranch *node) override;
+
+ bool mIsBranchVisited = false;
+};
+
+bool PruneNoOpsTraverser::apply(TCompiler *compiler, TIntermBlock *root, TSymbolTable *symbolTable)
+{
+ PruneNoOpsTraverser prune(symbolTable);
+ root->traverse(&prune);
+ return prune.updateTree(compiler, root);
+}
+
+PruneNoOpsTraverser::PruneNoOpsTraverser(TSymbolTable *symbolTable)
+ : TIntermTraverser(true, true, true, symbolTable)
+{}
+
+bool PruneNoOpsTraverser::visitDeclaration(Visit visit, TIntermDeclaration *node)
+{
+ if (visit != PreVisit)
+ {
+ return true;
+ }
+
+ TIntermSequence *sequence = node->getSequence();
+ if (sequence->size() >= 1)
+ {
+ TIntermSymbol *declaratorSymbol = sequence->front()->getAsSymbolNode();
+ // Prune declarations without a variable name, unless it's an interface block declaration.
+ if (declaratorSymbol != nullptr &&
+ declaratorSymbol->variable().symbolType() == SymbolType::Empty &&
+ !declaratorSymbol->isInterfaceBlock())
+ {
+ if (sequence->size() > 1)
+ {
+ // Generate a replacement that will remove the empty declarator in the beginning of
+ // a declarator list. Example of a declaration that will be changed:
+ // float, a;
+ // will be changed to
+ // float a;
+ // This applies also to struct declarations.
+ TIntermSequence emptyReplacement;
+ mMultiReplacements.emplace_back(node, declaratorSymbol,
+ std::move(emptyReplacement));
+ }
+ else if (declaratorSymbol->getBasicType() != EbtStruct)
+ {
+ // If there are entirely empty non-struct declarations, they result in
+ // TIntermDeclaration nodes without any children in the parsing stage. These are
+ // handled in visitBlock and visitLoop.
+ UNREACHABLE();
+ }
+ else if (declaratorSymbol->getQualifier() != EvqGlobal &&
+ declaratorSymbol->getQualifier() != EvqTemporary)
+ {
+ // Single struct declarations may just declare the struct type and no variables, so
+ // they should not be pruned. Here we handle 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."
+
+ // Create a new variable to use in the declarator so that the variable and node
+ // types are kept consistent.
+ TType *type = new TType(declaratorSymbol->getType());
+ if (mInGlobalScope)
+ {
+ type->setQualifier(EvqGlobal);
+ }
+ else
+ {
+ type->setQualifier(EvqTemporary);
+ }
+ TVariable *variable =
+ new TVariable(mSymbolTable, kEmptyImmutableString, type, SymbolType::Empty);
+ queueReplacementWithParent(node, declaratorSymbol, new TIntermSymbol(variable),
+ OriginalNode::IS_DROPPED);
+ }
+ }
+ }
+ return false;
+}
+
+bool PruneNoOpsTraverser::visitBlock(Visit visit, TIntermBlock *node)
+{
+ ASSERT(visit == PreVisit);
+
+ TIntermSequence &statements = *node->getSequence();
+
+ // Visit each statement in the block one by one. Once a branch is visited (break, continue,
+ // return or discard), drop the rest of the statements.
+ for (size_t statementIndex = 0; statementIndex < statements.size(); ++statementIndex)
+ {
+ TIntermNode *statement = statements[statementIndex];
+
+ // If the statement is a switch case label, stop pruning and continue visiting the children.
+ if (statement->getAsCaseNode() != nullptr)
+ {
+ mIsBranchVisited = false;
+ }
+
+ // If a branch is visited, prune the statement. If the statement is a no-op, also prune it.
+ if (mIsBranchVisited || IsNoOp(statement))
+ {
+ TIntermSequence emptyReplacement;
+ mMultiReplacements.emplace_back(node, statement, std::move(emptyReplacement));
+ continue;
+ }
+
+ // Visit the statement if not pruned.
+ statement->traverse(this);
+ }
+
+ // If the parent is a block and mIsBranchVisited is set, this is a nested block without any
+ // condition (like if, loop or switch), so the rest of the parent block should also be pruned.
+ // Otherwise the parent block should be unaffected.
+ if (mIsBranchVisited && getParentNode()->getAsBlock() == nullptr)
+ {
+ mIsBranchVisited = false;
+ }
+
+ return false;
+}
+
+bool PruneNoOpsTraverser::visitLoop(Visit visit, TIntermLoop *loop)
+{
+ if (visit != PreVisit)
+ {
+ return true;
+ }
+
+ TIntermTyped *expr = loop->getExpression();
+ if (expr != nullptr && IsNoOp(expr))
+ {
+ loop->setExpression(nullptr);
+ }
+ TIntermNode *init = loop->getInit();
+ if (init != nullptr && IsNoOp(init))
+ {
+ loop->setInit(nullptr);
+ }
+
+ return true;
+}
+
+bool PruneNoOpsTraverser::visitBranch(Visit visit, TIntermBranch *node)
+{
+ ASSERT(visit == PreVisit);
+
+ mIsBranchVisited = true;
+
+ // Only possible child is the value of a return statement, which has nothing to prune.
+ return false;
+}
+} // namespace
+
+bool PruneNoOps(TCompiler *compiler, TIntermBlock *root, TSymbolTable *symbolTable)
+{
+ return PruneNoOpsTraverser::apply(compiler, root, symbolTable);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/PruneNoOps.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/PruneNoOps.h
new file mode 100644
index 0000000000..a73cb71d08
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/PruneNoOps.h
@@ -0,0 +1,29 @@
+//
+// Copyright 2002 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.
+//
+// PruneNoOps.h: The PruneNoOps function prunes:
+// 1. Empty declarations "int;". Empty declarators will be pruned as well, so for example:
+// int , a;
+// is turned into
+// int a;
+// 2. Literal statements: "1.0;". The ESSL output doesn't define a default precision for float,
+// so float literal statements would end up with no precision which is invalid ESSL.
+// 3. Statements after discard, return, break and continue.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_PRUNENOOPS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_PRUNENOOPS_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+[[nodiscard]] bool PruneNoOps(TCompiler *compiler, TIntermBlock *root, TSymbolTable *symbolTable);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_PRUNENOOPS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RecordConstantPrecision.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/RecordConstantPrecision.cpp
new file mode 100644
index 0000000000..ea15ab7844
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RecordConstantPrecision.cpp
@@ -0,0 +1,119 @@
+//
+// Copyright 2002 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.
+//
+// During parsing, all constant expressions are folded to constant union nodes. The expressions that
+// have been folded may have had precision qualifiers, which should affect the precision of the
+// consuming operation. If the folded constant union nodes are written to output as such they won't
+// have any precision qualifiers, and their effect on the precision of the consuming operation is
+// lost.
+//
+// RecordConstantPrecision is an AST traverser that inspects the precision qualifiers of constants
+// and hoists the constants outside the containing expression as precision qualified named variables
+// in case that is required for correct precision propagation.
+//
+
+#include "compiler/translator/tree_ops/RecordConstantPrecision.h"
+
+#include "compiler/translator/InfoSink.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class RecordConstantPrecisionTraverser : public TIntermTraverser
+{
+ public:
+ RecordConstantPrecisionTraverser(TSymbolTable *symbolTable);
+
+ void visitConstantUnion(TIntermConstantUnion *node) override;
+
+ protected:
+ bool operandAffectsParentOperationPrecision(TIntermTyped *operand);
+};
+
+RecordConstantPrecisionTraverser::RecordConstantPrecisionTraverser(TSymbolTable *symbolTable)
+ : TIntermTraverser(true, false, true, symbolTable)
+{}
+
+bool RecordConstantPrecisionTraverser::operandAffectsParentOperationPrecision(TIntermTyped *operand)
+{
+ if (getParentNode()->getAsCaseNode() || getParentNode()->getAsBlock())
+ {
+ return false;
+ }
+
+ if (operand->getBasicType() == EbtBool || operand->getBasicType() == EbtStruct)
+ {
+ return false;
+ }
+
+ const TIntermBinary *parentAsBinary = getParentNode()->getAsBinaryNode();
+ if (parentAsBinary != nullptr)
+ {
+ // If the constant is assigned or is used to initialize a variable, or if it's an index,
+ // its precision has no effect.
+ switch (parentAsBinary->getOp())
+ {
+ case EOpInitialize:
+ case EOpAssign:
+ case EOpIndexDirect:
+ case EOpIndexDirectStruct:
+ case EOpIndexDirectInterfaceBlock:
+ case EOpIndexIndirect:
+ return false;
+ default:
+ return true;
+ }
+ }
+
+ TIntermAggregate *parentAsAggregate = getParentNode()->getAsAggregate();
+ if (parentAsAggregate != nullptr)
+ {
+ // The precision of an aggregate is derived from children only in the following conditions:
+ //
+ // - Built-in math operations
+ // - Constructors
+ //
+ return parentAsAggregate->isConstructor() ||
+ BuiltInGroup::IsMath(parentAsAggregate->getOp());
+ }
+
+ return true;
+}
+
+void RecordConstantPrecisionTraverser::visitConstantUnion(TIntermConstantUnion *node)
+{
+ // If the constant has lowp or undefined precision, it can't increase the precision of consuming
+ // operations.
+ if (node->getPrecision() < EbpMedium)
+ return;
+
+ // It's possible the node has no effect on the precision of the consuming expression, depending
+ // on the consuming expression, and the precision of the other parameters of the expression.
+ if (!operandAffectsParentOperationPrecision(node))
+ return;
+
+ // Make the constant a precision-qualified named variable to make sure it affects the precision
+ // of the consuming expression.
+ TIntermDeclaration *variableDeclaration = nullptr;
+ TVariable *variable = DeclareTempVariable(mSymbolTable, node, EvqConst, &variableDeclaration);
+ insertStatementInParentBlock(variableDeclaration);
+ queueReplacement(CreateTempSymbolNode(variable), OriginalNode::IS_DROPPED);
+}
+
+} // namespace
+
+bool RecordConstantPrecision(TCompiler *compiler, TIntermNode *root, TSymbolTable *symbolTable)
+{
+ RecordConstantPrecisionTraverser traverser(symbolTable);
+ root->traverse(&traverser);
+ return traverser.updateTree(compiler, root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RecordConstantPrecision.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/RecordConstantPrecision.h
new file mode 100644
index 0000000000..f615b11221
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RecordConstantPrecision.h
@@ -0,0 +1,33 @@
+//
+// Copyright 2002 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.
+//
+// During parsing, all constant expressions are folded to constant union nodes. The expressions that
+// have been folded may have had precision qualifiers, which should affect the precision of the
+// consuming operation. If the folded constant union nodes are written to output as such they won't
+// have any precision qualifiers, and their effect on the precision of the consuming operation is
+// lost.
+//
+// RecordConstantPrecision is an AST traverser that inspects the precision qualifiers of constants
+// and hoists the constants outside the containing expression as precision qualified named variables
+// in case that is required for correct precision propagation.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_RECORDCONSTANTPRECISION_H_
+#define COMPILER_TRANSLATOR_TREEOPS_RECORDCONSTANTPRECISION_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermNode;
+class TSymbolTable;
+
+[[nodiscard]] bool RecordConstantPrecision(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_RECORDCONSTANTPRECISION_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveArrayLengthMethod.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveArrayLengthMethod.cpp
new file mode 100644
index 0000000000..85ecb9346b
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveArrayLengthMethod.cpp
@@ -0,0 +1,109 @@
+//
+// Copyright 2017 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.
+//
+// RemoveArrayLengthMethod.cpp:
+// Fold array length expressions, including cases where the "this" node has side effects.
+// Example:
+// int i = (a = b).length();
+// int j = (func()).length();
+// becomes:
+// (a = b);
+// int i = <constant array length>;
+// func();
+// int j = <constant array length>;
+//
+// Must be run after SplitSequenceOperator, SimplifyLoopConditions and SeparateDeclarations steps
+// have been done to expressions containing calls of the array length method.
+//
+// Does nothing to length method calls done on runtime-sized arrays.
+
+#include "compiler/translator/tree_ops/RemoveArrayLengthMethod.h"
+
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class RemoveArrayLengthTraverser : public TIntermTraverser
+{
+ public:
+ RemoveArrayLengthTraverser() : TIntermTraverser(true, false, false), mFoundArrayLength(false) {}
+
+ bool visitUnary(Visit visit, TIntermUnary *node) override;
+
+ void nextIteration() { mFoundArrayLength = false; }
+
+ bool foundArrayLength() const { return mFoundArrayLength; }
+
+ private:
+ void insertSideEffectsInParentBlock(TIntermTyped *node);
+
+ bool mFoundArrayLength;
+};
+
+bool RemoveArrayLengthTraverser::visitUnary(Visit visit, TIntermUnary *node)
+{
+ // The only case where we leave array length() in place is for runtime-sized arrays.
+ if (node->getOp() == EOpArrayLength && !node->getOperand()->getType().isUnsizedArray())
+ {
+ mFoundArrayLength = true;
+ insertSideEffectsInParentBlock(node->getOperand());
+ TConstantUnion *constArray = new TConstantUnion[1];
+ constArray->setIConst(node->getOperand()->getOutermostArraySize());
+ queueReplacement(new TIntermConstantUnion(constArray, node->getType()),
+ OriginalNode::IS_DROPPED);
+ return false;
+ }
+ return true;
+}
+
+void RemoveArrayLengthTraverser::insertSideEffectsInParentBlock(TIntermTyped *node)
+{
+ // If the node is an index type, traverse it and add the indices as side effects. If at the end
+ // an expression without side effect is encountered, such as an opaque uniform or a lone symbol,
+ // don't generate a statement for it.
+ if (!node->hasSideEffects())
+ {
+ return;
+ }
+
+ TIntermBinary *asBinary = node->getAsBinaryNode();
+ if (asBinary && !asBinary->isAssignment())
+ {
+ insertSideEffectsInParentBlock(asBinary->getLeft());
+ insertSideEffectsInParentBlock(asBinary->getRight());
+ }
+ else
+ {
+ insertStatementInParentBlock(node);
+ }
+}
+
+} // anonymous namespace
+
+bool RemoveArrayLengthMethod(TCompiler *compiler, TIntermBlock *root)
+{
+ RemoveArrayLengthTraverser traverser;
+ do
+ {
+ traverser.nextIteration();
+ root->traverse(&traverser);
+ if (traverser.foundArrayLength())
+ {
+ if (!traverser.updateTree(compiler, root))
+ {
+ return false;
+ }
+ }
+ } while (traverser.foundArrayLength());
+
+ return true;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveArrayLengthMethod.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveArrayLengthMethod.h
new file mode 100644
index 0000000000..8468e1e635
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveArrayLengthMethod.h
@@ -0,0 +1,37 @@
+//
+// Copyright 2017 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.
+//
+// RemoveArrayLengthMethod.h:
+// Fold array length expressions, including cases where the "this" node has side effects.
+// Example:
+// int i = (a = b).length();
+// int j = (func()).length();
+// becomes:
+// (a = b);
+// int i = <constant array length>;
+// func();
+// int j = <constant array length>;
+//
+// Must be run after SplitSequenceOperator, SimplifyLoopConditions and SeparateDeclarations steps
+// have been done to expressions containing calls of the array length method.
+//
+// Does nothing to length method calls done on runtime-sized arrays.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_REMOVEARRAYLENGTHMETHOD_H_
+#define COMPILER_TRANSLATOR_TREEOPS_REMOVEARRAYLENGTHMETHOD_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermBlock;
+
+[[nodiscard]] bool RemoveArrayLengthMethod(TCompiler *compiler, TIntermBlock *root);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_REMOVEARRAYLENGTHMETHOD_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveAtomicCounterBuiltins.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveAtomicCounterBuiltins.cpp
new file mode 100644
index 0000000000..ed0ba3fed8
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveAtomicCounterBuiltins.cpp
@@ -0,0 +1,74 @@
+//
+// Copyright 2020 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.
+//
+// RemoveAtomicCounterBuiltins: Remove atomic counter builtins.
+//
+
+#include "compiler/translator/tree_ops/RemoveAtomicCounterBuiltins.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+namespace
+{
+
+bool IsAtomicCounterDecl(const TIntermDeclaration *node)
+{
+ const TIntermSequence &sequence = *(node->getSequence());
+ TIntermTyped *variable = sequence.front()->getAsTyped();
+ const TType &type = variable->getType();
+ return type.getQualifier() == EvqUniform && type.isAtomicCounter();
+}
+
+// Traverser that removes all GLSL built-ins that use AtomicCounters
+// Only called when the builtins are in use, but no atomic counters have been declared
+class RemoveAtomicCounterBuiltinsTraverser : public TIntermTraverser
+{
+ public:
+ RemoveAtomicCounterBuiltinsTraverser() : TIntermTraverser(true, false, false) {}
+
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override
+ {
+ ASSERT(visit == PreVisit);
+
+ // Active atomic counters should have been removed by RewriteAtomicCounters, and this
+ // traversal should not have been invoked
+ ASSERT(!IsAtomicCounterDecl(node));
+ return false;
+ }
+
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override
+ {
+ if (node->getOp() == EOpMemoryBarrierAtomicCounter)
+ {
+ // Vulkan does not support atomic counters, so if this builtin finds its way here,
+ // we need to remove it.
+ TIntermSequence emptySequence;
+ mMultiReplacements.emplace_back(getParentNode()->getAsBlock(), node,
+ std::move(emptySequence));
+ return true;
+ }
+
+ // We shouldn't see any other builtins because they cannot be present without an active
+ // atomic counter, and should have been removed by RewriteAtomicCounters. If this fires,
+ // this traversal should not have been called.
+ ASSERT(!(BuiltInGroup::IsBuiltIn(node->getOp()) &&
+ node->getFunction()->isAtomicCounterFunction()));
+
+ return false;
+ }
+};
+
+} // anonymous namespace
+
+bool RemoveAtomicCounterBuiltins(TCompiler *compiler, TIntermBlock *root)
+{
+ RemoveAtomicCounterBuiltinsTraverser traverser;
+ root->traverse(&traverser);
+ return traverser.updateTree(compiler, root);
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveAtomicCounterBuiltins.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveAtomicCounterBuiltins.h
new file mode 100644
index 0000000000..efe8a53595
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveAtomicCounterBuiltins.h
@@ -0,0 +1,24 @@
+//
+// Copyright 2020 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.
+//
+// RemoveAtomicCounterBuiltins: Remove atomic counter builtins.
+// Normally handled by RewriteAtomicCounters, but that is only invoked when
+// atomic counters are actually in use. This pass removes the builtins and
+// asserts no atomic counters are declared.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_REMOVEATOMICCOUNTERBUILTINS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_REMOVEATOMICCOUNTERBUILTINS_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermBlock;
+
+[[nodiscard]] bool RemoveAtomicCounterBuiltins(TCompiler *compiler, TIntermBlock *root);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_REMOVEATOMICCOUNTERBUILTINS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveDynamicIndexing.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveDynamicIndexing.cpp
new file mode 100644
index 0000000000..fda6de6f48
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveDynamicIndexing.cpp
@@ -0,0 +1,597 @@
+//
+// Copyright 2002 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.
+//
+// RemoveDynamicIndexing is an AST traverser to remove dynamic indexing of non-SSBO vectors and
+// matrices, replacing them with calls to functions that choose which component to return or write.
+// We don't need to consider dynamic indexing in SSBO since it can be directly as part of the offset
+// of RWByteAddressBuffer.
+//
+
+#include "compiler/translator/tree_ops/RemoveDynamicIndexing.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/Diagnostics.h"
+#include "compiler/translator/InfoSink.h"
+#include "compiler/translator/StaticType.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermNodePatternMatcher.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+using DynamicIndexingNodeMatcher = std::function<bool(TIntermBinary *)>;
+
+const TType *kIndexType = StaticType::Get<EbtInt, EbpHigh, EvqParamIn, 1, 1>();
+
+constexpr const ImmutableString kBaseName("base");
+constexpr const ImmutableString kIndexName("index");
+constexpr const ImmutableString kValueName("value");
+
+std::string GetIndexFunctionName(const TType &type, bool write)
+{
+ TInfoSinkBase nameSink;
+ nameSink << "dyn_index_";
+ if (write)
+ {
+ nameSink << "write_";
+ }
+ if (type.isMatrix())
+ {
+ nameSink << "mat" << static_cast<uint32_t>(type.getCols()) << "x"
+ << static_cast<uint32_t>(type.getRows());
+ }
+ else
+ {
+ switch (type.getBasicType())
+ {
+ case EbtInt:
+ nameSink << "ivec";
+ break;
+ case EbtBool:
+ nameSink << "bvec";
+ break;
+ case EbtUInt:
+ nameSink << "uvec";
+ break;
+ case EbtFloat:
+ nameSink << "vec";
+ break;
+ default:
+ UNREACHABLE();
+ }
+ nameSink << static_cast<uint32_t>(type.getNominalSize());
+ }
+ return nameSink.str();
+}
+
+TIntermConstantUnion *CreateIntConstantNode(int i)
+{
+ TConstantUnion *constant = new TConstantUnion();
+ constant->setIConst(i);
+ return new TIntermConstantUnion(constant, TType(EbtInt, EbpHigh));
+}
+
+TIntermTyped *EnsureSignedInt(TIntermTyped *node)
+{
+ if (node->getBasicType() == EbtInt)
+ return node;
+
+ TIntermSequence arguments;
+ arguments.push_back(node);
+ return TIntermAggregate::CreateConstructor(TType(EbtInt), &arguments);
+}
+
+TType *GetFieldType(const TType &indexedType)
+{
+ TType *fieldType = new TType(indexedType);
+ if (indexedType.isMatrix())
+ {
+ fieldType->toMatrixColumnType();
+ }
+ else
+ {
+ ASSERT(indexedType.isVector());
+ fieldType->toComponentType();
+ }
+ // Default precision to highp if not specified. For example in |vec3(0)[i], i < 0|, there is no
+ // precision assigned to vec3(0).
+ if (fieldType->getPrecision() == EbpUndefined)
+ {
+ fieldType->setPrecision(EbpHigh);
+ }
+ return fieldType;
+}
+
+const TType *GetBaseType(const TType &type, bool write)
+{
+ TType *baseType = new TType(type);
+ // Conservatively use highp here, even if the indexed type is not highp. That way the code can't
+ // end up using mediump version of an indexing function for a highp value, if both mediump and
+ // highp values are being indexed in the shader. For HLSL precision doesn't matter, but in
+ // principle this code could be used with multiple backends.
+ baseType->setPrecision(EbpHigh);
+ baseType->setQualifier(EvqParamInOut);
+ if (!write)
+ baseType->setQualifier(EvqParamIn);
+ return baseType;
+}
+
+// Generate a read or write function for one field in a vector/matrix.
+// Out-of-range indices are clamped. This is consistent with how ANGLE handles out-of-range
+// indices in other places.
+// Note that indices can be either int or uint. We create only int versions of the functions,
+// and convert uint indices to int at the call site.
+// read function example:
+// float dyn_index_vec2(in vec2 base, in int index)
+// {
+// switch(index)
+// {
+// case (0):
+// return base[0];
+// case (1):
+// return base[1];
+// default:
+// break;
+// }
+// if (index < 0)
+// return base[0];
+// return base[1];
+// }
+// write function example:
+// void dyn_index_write_vec2(inout vec2 base, in int index, in float value)
+// {
+// switch(index)
+// {
+// case (0):
+// base[0] = value;
+// return;
+// case (1):
+// base[1] = value;
+// return;
+// default:
+// break;
+// }
+// if (index < 0)
+// {
+// base[0] = value;
+// return;
+// }
+// base[1] = value;
+// }
+// Note that else is not used in above functions to avoid the RewriteElseBlocks transformation.
+TIntermFunctionDefinition *GetIndexFunctionDefinition(const TType &type,
+ bool write,
+ const TFunction &func,
+ TSymbolTable *symbolTable)
+{
+ ASSERT(!type.isArray());
+
+ uint8_t numCases = 0;
+ if (type.isMatrix())
+ {
+ numCases = type.getCols();
+ }
+ else
+ {
+ numCases = type.getNominalSize();
+ }
+
+ std::string functionName = GetIndexFunctionName(type, write);
+ TIntermFunctionPrototype *prototypeNode = CreateInternalFunctionPrototypeNode(func);
+
+ TIntermSymbol *baseParam = new TIntermSymbol(func.getParam(0));
+ TIntermSymbol *indexParam = new TIntermSymbol(func.getParam(1));
+ TIntermSymbol *valueParam = nullptr;
+ if (write)
+ {
+ valueParam = new TIntermSymbol(func.getParam(2));
+ }
+
+ TIntermBlock *statementList = new TIntermBlock();
+ for (uint8_t i = 0; i < numCases; ++i)
+ {
+ TIntermCase *caseNode = new TIntermCase(CreateIntConstantNode(i));
+ statementList->getSequence()->push_back(caseNode);
+
+ TIntermBinary *indexNode =
+ new TIntermBinary(EOpIndexDirect, baseParam->deepCopy(), CreateIndexNode(i));
+ if (write)
+ {
+ TIntermBinary *assignNode =
+ new TIntermBinary(EOpAssign, indexNode, valueParam->deepCopy());
+ statementList->getSequence()->push_back(assignNode);
+ TIntermBranch *returnNode = new TIntermBranch(EOpReturn, nullptr);
+ statementList->getSequence()->push_back(returnNode);
+ }
+ else
+ {
+ TIntermBranch *returnNode = new TIntermBranch(EOpReturn, indexNode);
+ statementList->getSequence()->push_back(returnNode);
+ }
+ }
+
+ // Default case
+ TIntermCase *defaultNode = new TIntermCase(nullptr);
+ statementList->getSequence()->push_back(defaultNode);
+ TIntermBranch *breakNode = new TIntermBranch(EOpBreak, nullptr);
+ statementList->getSequence()->push_back(breakNode);
+
+ TIntermSwitch *switchNode = new TIntermSwitch(indexParam->deepCopy(), statementList);
+
+ TIntermBlock *bodyNode = new TIntermBlock();
+ bodyNode->getSequence()->push_back(switchNode);
+
+ TIntermBinary *cond =
+ new TIntermBinary(EOpLessThan, indexParam->deepCopy(), CreateIntConstantNode(0));
+
+ // Two blocks: one accesses (either reads or writes) the first element and returns,
+ // the other accesses the last element.
+ TIntermBlock *useFirstBlock = new TIntermBlock();
+ TIntermBlock *useLastBlock = new TIntermBlock();
+ TIntermBinary *indexFirstNode =
+ new TIntermBinary(EOpIndexDirect, baseParam->deepCopy(), CreateIndexNode(0));
+ TIntermBinary *indexLastNode =
+ new TIntermBinary(EOpIndexDirect, baseParam->deepCopy(), CreateIndexNode(numCases - 1));
+ if (write)
+ {
+ TIntermBinary *assignFirstNode =
+ new TIntermBinary(EOpAssign, indexFirstNode, valueParam->deepCopy());
+ useFirstBlock->getSequence()->push_back(assignFirstNode);
+ TIntermBranch *returnNode = new TIntermBranch(EOpReturn, nullptr);
+ useFirstBlock->getSequence()->push_back(returnNode);
+
+ TIntermBinary *assignLastNode =
+ new TIntermBinary(EOpAssign, indexLastNode, valueParam->deepCopy());
+ useLastBlock->getSequence()->push_back(assignLastNode);
+ }
+ else
+ {
+ TIntermBranch *returnFirstNode = new TIntermBranch(EOpReturn, indexFirstNode);
+ useFirstBlock->getSequence()->push_back(returnFirstNode);
+
+ TIntermBranch *returnLastNode = new TIntermBranch(EOpReturn, indexLastNode);
+ useLastBlock->getSequence()->push_back(returnLastNode);
+ }
+ TIntermIfElse *ifNode = new TIntermIfElse(cond, useFirstBlock, nullptr);
+ bodyNode->getSequence()->push_back(ifNode);
+ bodyNode->getSequence()->push_back(useLastBlock);
+
+ TIntermFunctionDefinition *indexingFunction =
+ new TIntermFunctionDefinition(prototypeNode, bodyNode);
+ return indexingFunction;
+}
+
+class RemoveDynamicIndexingTraverser : public TLValueTrackingTraverser
+{
+ public:
+ RemoveDynamicIndexingTraverser(DynamicIndexingNodeMatcher &&matcher,
+ TSymbolTable *symbolTable,
+ PerformanceDiagnostics *perfDiagnostics);
+
+ bool visitBinary(Visit visit, TIntermBinary *node) override;
+
+ void insertHelperDefinitions(TIntermNode *root);
+
+ void nextIteration();
+
+ bool usedTreeInsertion() const { return mUsedTreeInsertion; }
+
+ protected:
+ // Maps of types that are indexed to the indexing function ids used for them. Note that these
+ // can not store multiple variants of the same type with different precisions - only one
+ // precision gets stored.
+ std::map<TType, TFunction *> mIndexedVecAndMatrixTypes;
+ std::map<TType, TFunction *> mWrittenVecAndMatrixTypes;
+
+ bool mUsedTreeInsertion;
+
+ // When true, the traverser will remove side effects from any indexing expression.
+ // This is done so that in code like
+ // V[j++][i]++.
+ // where V is an array of vectors, j++ will only be evaluated once.
+ bool mRemoveIndexSideEffectsInSubtree;
+
+ DynamicIndexingNodeMatcher mMatcher;
+ PerformanceDiagnostics *mPerfDiagnostics;
+};
+
+RemoveDynamicIndexingTraverser::RemoveDynamicIndexingTraverser(
+ DynamicIndexingNodeMatcher &&matcher,
+ TSymbolTable *symbolTable,
+ PerformanceDiagnostics *perfDiagnostics)
+ : TLValueTrackingTraverser(true, false, false, symbolTable),
+ mUsedTreeInsertion(false),
+ mRemoveIndexSideEffectsInSubtree(false),
+ mMatcher(matcher),
+ mPerfDiagnostics(perfDiagnostics)
+{}
+
+void RemoveDynamicIndexingTraverser::insertHelperDefinitions(TIntermNode *root)
+{
+ TIntermBlock *rootBlock = root->getAsBlock();
+ ASSERT(rootBlock != nullptr);
+ TIntermSequence insertions;
+ for (auto &type : mIndexedVecAndMatrixTypes)
+ {
+ insertions.push_back(
+ GetIndexFunctionDefinition(type.first, false, *type.second, mSymbolTable));
+ }
+ for (auto &type : mWrittenVecAndMatrixTypes)
+ {
+ insertions.push_back(
+ GetIndexFunctionDefinition(type.first, true, *type.second, mSymbolTable));
+ }
+ rootBlock->insertChildNodes(0, insertions);
+}
+
+// Create a call to dyn_index_*() based on an indirect indexing op node
+TIntermAggregate *CreateIndexFunctionCall(TIntermBinary *node,
+ TIntermTyped *index,
+ TFunction *indexingFunction)
+{
+ ASSERT(node->getOp() == EOpIndexIndirect);
+ TIntermSequence arguments;
+ arguments.push_back(node->getLeft());
+ arguments.push_back(index);
+
+ TIntermAggregate *indexingCall =
+ TIntermAggregate::CreateFunctionCall(*indexingFunction, &arguments);
+ indexingCall->setLine(node->getLine());
+ return indexingCall;
+}
+
+TIntermAggregate *CreateIndexedWriteFunctionCall(TIntermBinary *node,
+ TVariable *index,
+ TVariable *writtenValue,
+ TFunction *indexedWriteFunction)
+{
+ ASSERT(node->getOp() == EOpIndexIndirect);
+ TIntermSequence arguments;
+ // Deep copy the child nodes so that two pointers to the same node don't end up in the tree.
+ arguments.push_back(node->getLeft()->deepCopy());
+ arguments.push_back(CreateTempSymbolNode(index));
+ arguments.push_back(CreateTempSymbolNode(writtenValue));
+
+ TIntermAggregate *indexedWriteCall =
+ TIntermAggregate::CreateFunctionCall(*indexedWriteFunction, &arguments);
+ indexedWriteCall->setLine(node->getLine());
+ return indexedWriteCall;
+}
+
+bool RemoveDynamicIndexingTraverser::visitBinary(Visit visit, TIntermBinary *node)
+{
+ if (mUsedTreeInsertion)
+ return false;
+
+ if (node->getOp() == EOpIndexIndirect)
+ {
+ if (mRemoveIndexSideEffectsInSubtree)
+ {
+ ASSERT(node->getRight()->hasSideEffects());
+ // In case we're just removing index side effects, convert
+ // v_expr[index_expr]
+ // to this:
+ // int s0 = index_expr; v_expr[s0];
+ // Now v_expr[s0] can be safely executed several times without unintended side effects.
+ TIntermDeclaration *indexVariableDeclaration = nullptr;
+ TVariable *indexVariable = DeclareTempVariable(mSymbolTable, node->getRight(),
+ EvqTemporary, &indexVariableDeclaration);
+ insertStatementInParentBlock(indexVariableDeclaration);
+ mUsedTreeInsertion = true;
+
+ // Replace the index with the temp variable
+ TIntermSymbol *tempIndex = CreateTempSymbolNode(indexVariable);
+ queueReplacementWithParent(node, node->getRight(), tempIndex, OriginalNode::IS_DROPPED);
+ }
+ else if (mMatcher(node))
+ {
+ if (mPerfDiagnostics)
+ {
+ mPerfDiagnostics->warning(node->getLine(),
+ "Performance: dynamic indexing of vectors and "
+ "matrices is emulated and can be slow.",
+ "[]");
+ }
+ 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
+
+ const TType &type = node->getLeft()->getType();
+ ImmutableString indexingFunctionName(GetIndexFunctionName(type, false));
+ TFunction *indexingFunction = nullptr;
+ if (mIndexedVecAndMatrixTypes.find(type) == mIndexedVecAndMatrixTypes.end())
+ {
+ indexingFunction =
+ new TFunction(mSymbolTable, indexingFunctionName, SymbolType::AngleInternal,
+ GetFieldType(type), true);
+ indexingFunction->addParameter(new TVariable(
+ mSymbolTable, kBaseName, GetBaseType(type, false), SymbolType::AngleInternal));
+ indexingFunction->addParameter(
+ new TVariable(mSymbolTable, kIndexName, kIndexType, SymbolType::AngleInternal));
+ mIndexedVecAndMatrixTypes[type] = indexingFunction;
+ }
+ else
+ {
+ indexingFunction = mIndexedVecAndMatrixTypes[type];
+ }
+
+ if (write)
+ {
+ // Convert:
+ // v_expr[index_expr]++;
+ // to this:
+ // int s0 = index_expr; float s1 = dyn_index(v_expr, s0); s1++;
+ // dyn_index_write(v_expr, s0, s1);
+ // This works even if index_expr has some side effects.
+ if (node->getLeft()->hasSideEffects())
+ {
+ // If v_expr has side effects, those need to be removed before proceeding.
+ // Otherwise the side effects of v_expr would be evaluated twice.
+ // The only case where an l-value can have side effects is when it is
+ // indexing. For example, it can be V[j++] where V is an array of vectors.
+ mRemoveIndexSideEffectsInSubtree = true;
+ return true;
+ }
+
+ TIntermBinary *leftBinary = node->getLeft()->getAsBinaryNode();
+ if (leftBinary != nullptr && mMatcher(leftBinary))
+ {
+ // This is a case like:
+ // mat2 m;
+ // m[a][b]++;
+ // Process the child node m[a] first.
+ return true;
+ }
+
+ // TODO(oetuaho@nvidia.com): This is not optimal if the expression using the value
+ // only writes it and doesn't need the previous value. http://anglebug.com/1116
+
+ TFunction *indexedWriteFunction = nullptr;
+ if (mWrittenVecAndMatrixTypes.find(type) == mWrittenVecAndMatrixTypes.end())
+ {
+ ImmutableString functionName(
+ GetIndexFunctionName(node->getLeft()->getType(), true));
+ indexedWriteFunction =
+ new TFunction(mSymbolTable, functionName, SymbolType::AngleInternal,
+ StaticType::GetBasic<EbtVoid, EbpUndefined>(), false);
+ indexedWriteFunction->addParameter(new TVariable(mSymbolTable, kBaseName,
+ GetBaseType(type, true),
+ SymbolType::AngleInternal));
+ indexedWriteFunction->addParameter(new TVariable(
+ mSymbolTable, kIndexName, kIndexType, SymbolType::AngleInternal));
+ TType *valueType = GetFieldType(type);
+ valueType->setQualifier(EvqParamIn);
+ indexedWriteFunction->addParameter(new TVariable(
+ mSymbolTable, kValueName, static_cast<const TType *>(valueType),
+ SymbolType::AngleInternal));
+ mWrittenVecAndMatrixTypes[type] = indexedWriteFunction;
+ }
+ else
+ {
+ indexedWriteFunction = mWrittenVecAndMatrixTypes[type];
+ }
+
+ TIntermSequence insertionsBefore;
+ TIntermSequence insertionsAfter;
+
+ // Store the index in a temporary signed int variable.
+ // s0 = index_expr;
+ TIntermTyped *indexInitializer = EnsureSignedInt(node->getRight());
+ TIntermDeclaration *indexVariableDeclaration = nullptr;
+ TVariable *indexVariable = DeclareTempVariable(
+ mSymbolTable, indexInitializer, EvqTemporary, &indexVariableDeclaration);
+ insertionsBefore.push_back(indexVariableDeclaration);
+
+ // s1 = dyn_index(v_expr, s0);
+ TIntermAggregate *indexingCall = CreateIndexFunctionCall(
+ node, CreateTempSymbolNode(indexVariable), indexingFunction);
+ TIntermDeclaration *fieldVariableDeclaration = nullptr;
+ TVariable *fieldVariable = DeclareTempVariable(
+ mSymbolTable, indexingCall, EvqTemporary, &fieldVariableDeclaration);
+ insertionsBefore.push_back(fieldVariableDeclaration);
+
+ // dyn_index_write(v_expr, s0, s1);
+ TIntermAggregate *indexedWriteCall = CreateIndexedWriteFunctionCall(
+ node, indexVariable, fieldVariable, indexedWriteFunction);
+ insertionsAfter.push_back(indexedWriteCall);
+ insertStatementsInParentBlock(insertionsBefore, insertionsAfter);
+
+ // replace the node with s1
+ queueReplacement(CreateTempSymbolNode(fieldVariable), OriginalNode::IS_DROPPED);
+ mUsedTreeInsertion = true;
+ }
+ else
+ {
+ // The indexed value is not being written, so we can simply convert
+ // v_expr[index_expr]
+ // into
+ // dyn_index(v_expr, index_expr)
+ // If the index_expr is unsigned, we'll convert it to signed.
+ ASSERT(!mRemoveIndexSideEffectsInSubtree);
+ TIntermAggregate *indexingCall = CreateIndexFunctionCall(
+ node, EnsureSignedInt(node->getRight()), indexingFunction);
+ queueReplacement(indexingCall, OriginalNode::IS_DROPPED);
+ }
+ }
+ }
+ return !mUsedTreeInsertion;
+}
+
+void RemoveDynamicIndexingTraverser::nextIteration()
+{
+ mUsedTreeInsertion = false;
+ mRemoveIndexSideEffectsInSubtree = false;
+}
+
+bool RemoveDynamicIndexingIf(DynamicIndexingNodeMatcher &&matcher,
+ TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable,
+ PerformanceDiagnostics *perfDiagnostics)
+{
+ // This transformation adds function declarations after the fact and so some validation is
+ // momentarily disabled.
+ bool enableValidateFunctionCall = compiler->disableValidateFunctionCall();
+
+ RemoveDynamicIndexingTraverser traverser(std::move(matcher), symbolTable, perfDiagnostics);
+ do
+ {
+ traverser.nextIteration();
+ root->traverse(&traverser);
+ if (!traverser.updateTree(compiler, root))
+ {
+ return false;
+ }
+ } while (traverser.usedTreeInsertion());
+ // TODO(oetuaho@nvidia.com): It might be nicer to add the helper definitions also in the middle
+ // of traversal. Now the tree ends up in an inconsistent state in the middle, since there are
+ // function call nodes with no corresponding definition nodes. This needs special handling in
+ // TIntermLValueTrackingTraverser, and creates intricacies that are not easily apparent from a
+ // superficial reading of the code.
+ traverser.insertHelperDefinitions(root);
+
+ compiler->restoreValidateFunctionCall(enableValidateFunctionCall);
+ return compiler->validateAST(root);
+}
+
+} // namespace
+
+[[nodiscard]] bool RemoveDynamicIndexingOfNonSSBOVectorOrMatrix(
+ TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable,
+ PerformanceDiagnostics *perfDiagnostics)
+{
+ DynamicIndexingNodeMatcher matcher = [](TIntermBinary *node) {
+ return IntermNodePatternMatcher::IsDynamicIndexingOfNonSSBOVectorOrMatrix(node);
+ };
+ return RemoveDynamicIndexingIf(std::move(matcher), compiler, root, symbolTable,
+ perfDiagnostics);
+}
+
+[[nodiscard]] bool RemoveDynamicIndexingOfSwizzledVector(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable,
+ PerformanceDiagnostics *perfDiagnostics)
+{
+ DynamicIndexingNodeMatcher matcher = [](TIntermBinary *node) {
+ return IntermNodePatternMatcher::IsDynamicIndexingOfSwizzledVector(node);
+ };
+ return RemoveDynamicIndexingIf(std::move(matcher), compiler, root, symbolTable,
+ perfDiagnostics);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveDynamicIndexing.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveDynamicIndexing.h
new file mode 100644
index 0000000000..9693f55c40
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveDynamicIndexing.h
@@ -0,0 +1,41 @@
+//
+// Copyright 2002 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.
+//
+// RemoveDynamicIndexing is an AST traverser to remove dynamic indexing of non-SSBO vectors and
+// matrices, replacing them with calls to functions that choose which component to return or write.
+// We don't need to consider dynamic indexing in SSBO since it can be directly as part of the offset
+// of RWByteAddressBuffer.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_REMOVEDYNAMICINDEXING_H_
+#define COMPILER_TRANSLATOR_TREEOPS_REMOVEDYNAMICINDEXING_H_
+
+#include "common/angleutils.h"
+
+#include <functional>
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermNode;
+class TIntermBinary;
+class TSymbolTable;
+class PerformanceDiagnostics;
+
+[[nodiscard]] bool RemoveDynamicIndexingOfNonSSBOVectorOrMatrix(
+ TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable,
+ PerformanceDiagnostics *perfDiagnostics);
+
+[[nodiscard]] bool RemoveDynamicIndexingOfSwizzledVector(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable,
+ PerformanceDiagnostics *perfDiagnostics);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_REMOVEDYNAMICINDEXING_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveInactiveInterfaceVariables.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveInactiveInterfaceVariables.cpp
new file mode 100644
index 0000000000..a5e20ebcb0
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveInactiveInterfaceVariables.cpp
@@ -0,0 +1,209 @@
+//
+// Copyright 2019 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.
+//
+// RemoveInactiveInterfaceVariables.h:
+// Drop shader interface variable declarations for those that are inactive.
+//
+
+#include "compiler/translator/tree_ops/RemoveInactiveInterfaceVariables.h"
+
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+// Traverser that removes all declarations that correspond to inactive variables.
+class RemoveInactiveInterfaceVariablesTraverser : public TIntermTraverser
+{
+ public:
+ RemoveInactiveInterfaceVariablesTraverser(
+ TSymbolTable *symbolTable,
+ const std::vector<sh::ShaderVariable> &attributes,
+ const std::vector<sh::ShaderVariable> &inputVaryings,
+ const std::vector<sh::ShaderVariable> &outputVariables,
+ const std::vector<sh::ShaderVariable> &uniforms,
+ const std::vector<sh::InterfaceBlock> &interfaceBlocks,
+ bool removeFragmentOutputs);
+
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
+ bool visitBinary(Visit visit, TIntermBinary *node) override;
+
+ private:
+ const std::vector<sh::ShaderVariable> &mAttributes;
+ const std::vector<sh::ShaderVariable> &mInputVaryings;
+ const std::vector<sh::ShaderVariable> &mOutputVariables;
+ const std::vector<sh::ShaderVariable> &mUniforms;
+ const std::vector<sh::InterfaceBlock> &mInterfaceBlocks;
+ bool mRemoveFragmentOutputs;
+};
+
+RemoveInactiveInterfaceVariablesTraverser::RemoveInactiveInterfaceVariablesTraverser(
+ TSymbolTable *symbolTable,
+ const std::vector<sh::ShaderVariable> &attributes,
+ const std::vector<sh::ShaderVariable> &inputVaryings,
+ const std::vector<sh::ShaderVariable> &outputVariables,
+ const std::vector<sh::ShaderVariable> &uniforms,
+ const std::vector<sh::InterfaceBlock> &interfaceBlocks,
+ bool removeFragmentOutputs)
+ : TIntermTraverser(true, false, false, symbolTable),
+ mAttributes(attributes),
+ mInputVaryings(inputVaryings),
+ mOutputVariables(outputVariables),
+ mUniforms(uniforms),
+ mInterfaceBlocks(interfaceBlocks),
+ mRemoveFragmentOutputs(removeFragmentOutputs)
+{}
+
+template <typename Variable>
+bool IsVariableActive(const std::vector<Variable> &mVars, const ImmutableString &name)
+{
+ for (const Variable &var : mVars)
+ {
+ if (name == var.name)
+ {
+ return var.active;
+ }
+ }
+ UNREACHABLE();
+ return true;
+}
+
+bool RemoveInactiveInterfaceVariablesTraverser::visitDeclaration(Visit visit,
+ TIntermDeclaration *node)
+{
+ // SeparateDeclarations should have already been run.
+ ASSERT(node->getSequence()->size() == 1u);
+
+ TIntermTyped *declarator = node->getSequence()->front()->getAsTyped();
+ ASSERT(declarator);
+
+ TIntermSymbol *asSymbol = declarator->getAsSymbolNode();
+ if (!asSymbol)
+ {
+ return false;
+ }
+
+ const TType &type = declarator->getType();
+
+ // Remove all shader interface variables except outputs, i.e. uniforms, interface blocks and
+ // inputs.
+ //
+ // Imagine a situation where the VS doesn't write to a varying but the FS reads from it. This
+ // is allowed, though the value of the varying is undefined. If the varying is removed here,
+ // the situation is changed to VS not declaring the varying, but the FS reading from it, which
+ // is not allowed. That's why inactive shader outputs are not removed.
+ //
+ // Inactive fragment shader outputs can be removed though, as there is no next stage.
+ bool removeDeclaration = false;
+ const TQualifier qualifier = type.getQualifier();
+
+ if (type.isInterfaceBlock())
+ {
+ // When a member has an explicit location, interface block should not be removed.
+ // If the member or interface would be removed, GetProgramResource could not return the
+ // location.
+ if (!IsShaderIoBlock(type.getQualifier()) && type.getQualifier() != EvqPatchIn &&
+ type.getQualifier() != EvqPatchOut)
+ {
+ removeDeclaration =
+ !IsVariableActive(mInterfaceBlocks, type.getInterfaceBlock()->name());
+ }
+ }
+ else if (qualifier == EvqUniform)
+ {
+ removeDeclaration = !IsVariableActive(mUniforms, asSymbol->getName());
+ }
+ else if (qualifier == EvqAttribute || qualifier == EvqVertexIn)
+ {
+ removeDeclaration = !IsVariableActive(mAttributes, asSymbol->getName());
+ }
+ else if (IsShaderIn(qualifier))
+ {
+ removeDeclaration = !IsVariableActive(mInputVaryings, asSymbol->getName());
+ }
+ else if (qualifier == EvqFragmentOut)
+ {
+ removeDeclaration =
+ !IsVariableActive(mOutputVariables, asSymbol->getName()) && mRemoveFragmentOutputs;
+ }
+
+ if (removeDeclaration)
+ {
+ TIntermSequence replacement;
+
+ // If the declaration was of a struct, keep the struct declaration itself.
+ if (type.isStructSpecifier())
+ {
+ TType *structSpecifierType = new TType(type.getStruct(), true);
+ TVariable *emptyVariable = new TVariable(mSymbolTable, kEmptyImmutableString,
+ structSpecifierType, SymbolType::Empty);
+ TIntermDeclaration *declaration = new TIntermDeclaration();
+ declaration->appendDeclarator(new TIntermSymbol(emptyVariable));
+ replacement.push_back(declaration);
+ }
+
+ mMultiReplacements.emplace_back(getParentNode()->getAsBlock(), node,
+ std::move(replacement));
+ }
+
+ return false;
+}
+
+bool RemoveInactiveInterfaceVariablesTraverser::visitBinary(Visit visit, TIntermBinary *node)
+{
+ // Remove any code that initOutputVariables might have added corresponding to inactive
+ // output variables. This code is always in the form of `variable = ...;`.
+ if (node->getOp() != EOpAssign)
+ {
+ // Don't recurse, won't find the initialization nested in another expression.
+ return false;
+ }
+
+ // Get the symbol being initialized, and check if it's an inactive output. If it is, this must
+ // necessarily be initialization code that ANGLE has added (and wasn't there in the original
+ // shader; if it was, the symbol wouldn't have been inactive).
+ TIntermSymbol *symbol = node->getLeft()->getAsSymbolNode();
+ if (symbol == nullptr)
+ {
+ return false;
+ }
+
+ const TQualifier qualifier = symbol->getType().getQualifier();
+ if (qualifier != EvqFragmentOut || IsVariableActive(mOutputVariables, symbol->getName()))
+ {
+ return false;
+ }
+
+ // Drop the initialization code.
+ TIntermSequence replacement;
+ mMultiReplacements.emplace_back(getParentNode()->getAsBlock(), node, std::move(replacement));
+ return false;
+}
+
+} // namespace
+
+bool RemoveInactiveInterfaceVariables(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ const std::vector<sh::ShaderVariable> &attributes,
+ const std::vector<sh::ShaderVariable> &inputVaryings,
+ const std::vector<sh::ShaderVariable> &outputVariables,
+ const std::vector<sh::ShaderVariable> &uniforms,
+ const std::vector<sh::InterfaceBlock> &interfaceBlocks,
+ bool removeFragmentOutputs)
+{
+ RemoveInactiveInterfaceVariablesTraverser traverser(symbolTable, attributes, inputVaryings,
+ outputVariables, uniforms, interfaceBlocks,
+ removeFragmentOutputs);
+ root->traverse(&traverser);
+ return traverser.updateTree(compiler, root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveInactiveInterfaceVariables.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveInactiveInterfaceVariables.h
new file mode 100644
index 0000000000..ddbdea2ced
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveInactiveInterfaceVariables.h
@@ -0,0 +1,42 @@
+//
+// Copyright 2019 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.
+//
+// RemoveInactiveInterfaceVariables.h:
+// Drop shader interface variable declarations for those that are inactive. This step needs to be
+// done after CollectVariables. This avoids having to emulate them (e.g. atomic counters for
+// Vulkan) or remove them in glslang wrapper (again, for Vulkan).
+//
+// Shouldn't be run for the GL backend, as it queries shader interface variables from GL itself,
+// instead of relying on what was gathered during CollectVariables.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_REMOVEINACTIVEVARIABLES_H_
+#define COMPILER_TRANSLATOR_TREEOPS_REMOVEINACTIVEVARIABLES_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+struct InterfaceBlock;
+struct ShaderVariable;
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+[[nodiscard]] bool RemoveInactiveInterfaceVariables(
+ TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ const std::vector<sh::ShaderVariable> &attributes,
+ const std::vector<sh::ShaderVariable> &inputVaryings,
+ const std::vector<sh::ShaderVariable> &outputVariables,
+ const std::vector<sh::ShaderVariable> &uniforms,
+ const std::vector<sh::InterfaceBlock> &interfaceBlocks,
+ bool removeFragmentOutputs);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_REMOVEINACTIVEVARIABLES_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveInvariantDeclaration.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveInvariantDeclaration.cpp
new file mode 100644
index 0000000000..5a8ca44150
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveInvariantDeclaration.cpp
@@ -0,0 +1,47 @@
+//
+// 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.
+//
+
+#include "compiler/translator/tree_ops/RemoveInvariantDeclaration.h"
+
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+// An AST traverser that removes invariant declaration for input in fragment shader
+// when GLSL >= 4.20 and for output in vertex shader when GLSL < 4.2.
+class RemoveInvariantDeclarationTraverser : public TIntermTraverser
+{
+ public:
+ RemoveInvariantDeclarationTraverser() : TIntermTraverser(true, false, false) {}
+
+ private:
+ bool visitGlobalQualifierDeclaration(Visit visit,
+ TIntermGlobalQualifierDeclaration *node) override
+ {
+ if (node->isInvariant())
+ {
+ TIntermSequence emptyReplacement;
+ mMultiReplacements.emplace_back(getParentNode()->getAsBlock(), node,
+ std::move(emptyReplacement));
+ }
+ return false;
+ }
+};
+
+} // anonymous namespace
+
+bool RemoveInvariantDeclaration(TCompiler *compiler, TIntermNode *root)
+{
+ RemoveInvariantDeclarationTraverser traverser;
+ root->traverse(&traverser);
+ return traverser.updateTree(compiler, root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveInvariantDeclaration.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveInvariantDeclaration.h
new file mode 100644
index 0000000000..0fee87b3b1
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveInvariantDeclaration.h
@@ -0,0 +1,21 @@
+//
+// 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.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_REMOVEINVARIANTDECLARATION_H_
+#define COMPILER_TRANSLATOR_TREEOPS_REMOVEINVARIANTDECLARATION_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermNode;
+
+[[nodiscard]] bool RemoveInvariantDeclaration(TCompiler *compiler, TIntermNode *root);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_REMOVEINVARIANTDECLARATION_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveUnreferencedVariables.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveUnreferencedVariables.cpp
new file mode 100644
index 0000000000..b87ad33633
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveUnreferencedVariables.cpp
@@ -0,0 +1,371 @@
+//
+// Copyright 2017 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.
+//
+// RemoveUnreferencedVariables.cpp:
+// Drop variables that are declared but never referenced in the AST. This avoids adding unnecessary
+// initialization code for them. Also removes unreferenced struct types.
+//
+
+#include "compiler/translator/tree_ops/RemoveUnreferencedVariables.h"
+
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class CollectVariableRefCountsTraverser : public TIntermTraverser
+{
+ public:
+ CollectVariableRefCountsTraverser();
+
+ using RefCountMap = angle::HashMap<int, unsigned int>;
+ RefCountMap &getSymbolIdRefCounts() { return mSymbolIdRefCounts; }
+ RefCountMap &getStructIdRefCounts() { return mStructIdRefCounts; }
+
+ void visitSymbol(TIntermSymbol *node) override;
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override;
+ void visitFunctionPrototype(TIntermFunctionPrototype *node) override;
+
+ private:
+ void incrementStructTypeRefCount(const TType &type);
+
+ RefCountMap mSymbolIdRefCounts;
+
+ // Structure reference counts are counted from symbols, constructors, function calls, function
+ // return values and from interface block and structure fields. We need to track both function
+ // calls and function return values since there's a compiler option not to prune unused
+ // functions. The type of a constant union may also be a struct, but statements that are just a
+ // constant union are always pruned, and if the constant union is used somehow it will get
+ // counted by something else.
+ RefCountMap mStructIdRefCounts;
+};
+
+CollectVariableRefCountsTraverser::CollectVariableRefCountsTraverser()
+ : TIntermTraverser(true, false, false)
+{}
+
+void CollectVariableRefCountsTraverser::incrementStructTypeRefCount(const TType &type)
+{
+ if (type.isInterfaceBlock())
+ {
+ const auto *block = type.getInterfaceBlock();
+ ASSERT(block);
+
+ // We can end up incrementing ref counts of struct types referenced from an interface block
+ // multiple times for the same block. This doesn't matter, because interface blocks can't be
+ // pruned so we'll never do the reverse operation.
+ for (const auto &field : block->fields())
+ {
+ ASSERT(!field->type()->isInterfaceBlock());
+ incrementStructTypeRefCount(*field->type());
+ }
+ return;
+ }
+
+ const auto *structure = type.getStruct();
+ if (structure != nullptr)
+ {
+ auto structIter = mStructIdRefCounts.find(structure->uniqueId().get());
+ if (structIter == mStructIdRefCounts.end())
+ {
+ mStructIdRefCounts[structure->uniqueId().get()] = 1u;
+
+ for (const auto &field : structure->fields())
+ {
+ incrementStructTypeRefCount(*field->type());
+ }
+
+ return;
+ }
+ ++(structIter->second);
+ }
+}
+
+void CollectVariableRefCountsTraverser::visitSymbol(TIntermSymbol *node)
+{
+ incrementStructTypeRefCount(node->getType());
+
+ auto iter = mSymbolIdRefCounts.find(node->uniqueId().get());
+ if (iter == mSymbolIdRefCounts.end())
+ {
+ mSymbolIdRefCounts[node->uniqueId().get()] = 1u;
+ return;
+ }
+ ++(iter->second);
+}
+
+bool CollectVariableRefCountsTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
+{
+ // This tracks struct references in both function calls and constructors.
+ incrementStructTypeRefCount(node->getType());
+ return true;
+}
+
+void CollectVariableRefCountsTraverser::visitFunctionPrototype(TIntermFunctionPrototype *node)
+{
+ incrementStructTypeRefCount(node->getType());
+ size_t paramCount = node->getFunction()->getParamCount();
+ for (size_t i = 0; i < paramCount; ++i)
+ {
+ incrementStructTypeRefCount(node->getFunction()->getParam(i)->getType());
+ }
+}
+
+// Traverser that removes all unreferenced variables on one traversal.
+class RemoveUnreferencedVariablesTraverser : public TIntermTraverser
+{
+ public:
+ RemoveUnreferencedVariablesTraverser(
+ CollectVariableRefCountsTraverser::RefCountMap *symbolIdRefCounts,
+ CollectVariableRefCountsTraverser::RefCountMap *structIdRefCounts,
+ TSymbolTable *symbolTable);
+
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
+ void visitSymbol(TIntermSymbol *node) override;
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override;
+
+ // Traverse loop and block nodes in reverse order. Note that this traverser does not track
+ // parent block positions, so insertStatementInParentBlock is unusable!
+ void traverseBlock(TIntermBlock *block) override;
+ void traverseLoop(TIntermLoop *loop) override;
+
+ private:
+ void removeVariableDeclaration(TIntermDeclaration *node, TIntermTyped *declarator);
+ void decrementStructTypeRefCount(const TType &type);
+
+ CollectVariableRefCountsTraverser::RefCountMap *mSymbolIdRefCounts;
+ CollectVariableRefCountsTraverser::RefCountMap *mStructIdRefCounts;
+ bool mRemoveReferences;
+};
+
+RemoveUnreferencedVariablesTraverser::RemoveUnreferencedVariablesTraverser(
+ CollectVariableRefCountsTraverser::RefCountMap *symbolIdRefCounts,
+ CollectVariableRefCountsTraverser::RefCountMap *structIdRefCounts,
+ TSymbolTable *symbolTable)
+ : TIntermTraverser(true, false, true, symbolTable),
+ mSymbolIdRefCounts(symbolIdRefCounts),
+ mStructIdRefCounts(structIdRefCounts),
+ mRemoveReferences(false)
+{}
+
+void RemoveUnreferencedVariablesTraverser::decrementStructTypeRefCount(const TType &type)
+{
+ auto *structure = type.getStruct();
+ if (structure != nullptr)
+ {
+ ASSERT(mStructIdRefCounts->find(structure->uniqueId().get()) != mStructIdRefCounts->end());
+ unsigned int structRefCount = --(*mStructIdRefCounts)[structure->uniqueId().get()];
+
+ if (structRefCount == 0)
+ {
+ for (const auto &field : structure->fields())
+ {
+ decrementStructTypeRefCount(*field->type());
+ }
+ }
+ }
+}
+
+void RemoveUnreferencedVariablesTraverser::removeVariableDeclaration(TIntermDeclaration *node,
+ TIntermTyped *declarator)
+{
+ if (declarator->getType().isStructSpecifier() && !declarator->getType().isNamelessStruct())
+ {
+ unsigned int structId = declarator->getType().getStruct()->uniqueId().get();
+ unsigned int structRefCountInThisDeclarator = 1u;
+ if (declarator->getAsBinaryNode() &&
+ declarator->getAsBinaryNode()->getRight()->getAsAggregate())
+ {
+ ASSERT(declarator->getAsBinaryNode()->getLeft()->getType().getStruct() ==
+ declarator->getType().getStruct());
+ ASSERT(declarator->getAsBinaryNode()->getRight()->getType().getStruct() ==
+ declarator->getType().getStruct());
+ structRefCountInThisDeclarator = 2u;
+ }
+ if ((*mStructIdRefCounts)[structId] > structRefCountInThisDeclarator)
+ {
+ // If this declaration declares a named struct type that is used elsewhere, we need to
+ // keep it. We can still change the declarator though so that it doesn't declare an
+ // unreferenced variable.
+
+ // Note that since we're not removing the entire declaration, the struct's reference
+ // count will end up being one less than the correct refcount. But since the struct
+ // declaration is kept, the incorrect refcount can't cause any other problems.
+
+ if (declarator->getAsSymbolNode() &&
+ declarator->getAsSymbolNode()->variable().symbolType() == SymbolType::Empty)
+ {
+ // Already an empty declaration - nothing to do.
+ return;
+ }
+ TVariable *emptyVariable =
+ new TVariable(mSymbolTable, kEmptyImmutableString, new TType(declarator->getType()),
+ SymbolType::Empty);
+ queueReplacementWithParent(node, declarator, new TIntermSymbol(emptyVariable),
+ OriginalNode::IS_DROPPED);
+ return;
+ }
+ }
+
+ if (getParentNode()->getAsBlock())
+ {
+ TIntermSequence emptyReplacement;
+ mMultiReplacements.emplace_back(getParentNode()->getAsBlock(), node,
+ std::move(emptyReplacement));
+ }
+ else
+ {
+ ASSERT(getParentNode()->getAsLoopNode());
+ queueReplacement(nullptr, OriginalNode::IS_DROPPED);
+ }
+}
+
+bool RemoveUnreferencedVariablesTraverser::visitDeclaration(Visit visit, TIntermDeclaration *node)
+{
+ if (visit == PreVisit)
+ {
+ // SeparateDeclarations should have already been run.
+ ASSERT(node->getSequence()->size() == 1u);
+
+ TIntermTyped *declarator = node->getSequence()->back()->getAsTyped();
+ ASSERT(declarator);
+
+ // We can only remove variables that are not a part of the shader interface.
+ TQualifier qualifier = declarator->getQualifier();
+ if (qualifier != EvqTemporary && qualifier != EvqGlobal && qualifier != EvqConst)
+ {
+ return true;
+ }
+
+ bool canRemoveVariable = false;
+ TIntermSymbol *symbolNode = declarator->getAsSymbolNode();
+ if (symbolNode != nullptr)
+ {
+ canRemoveVariable = (*mSymbolIdRefCounts)[symbolNode->uniqueId().get()] == 1u ||
+ symbolNode->variable().symbolType() == SymbolType::Empty;
+ }
+ TIntermBinary *initNode = declarator->getAsBinaryNode();
+ if (initNode != nullptr)
+ {
+ ASSERT(initNode->getLeft()->getAsSymbolNode());
+ int symbolId = initNode->getLeft()->getAsSymbolNode()->uniqueId().get();
+ canRemoveVariable =
+ (*mSymbolIdRefCounts)[symbolId] == 1u && !initNode->getRight()->hasSideEffects();
+ }
+
+ if (canRemoveVariable)
+ {
+ removeVariableDeclaration(node, declarator);
+ mRemoveReferences = true;
+ }
+ return true;
+ }
+ ASSERT(visit == PostVisit);
+ mRemoveReferences = false;
+ return true;
+}
+
+void RemoveUnreferencedVariablesTraverser::visitSymbol(TIntermSymbol *node)
+{
+ if (mRemoveReferences)
+ {
+ ASSERT(mSymbolIdRefCounts->find(node->uniqueId().get()) != mSymbolIdRefCounts->end());
+ --(*mSymbolIdRefCounts)[node->uniqueId().get()];
+
+ decrementStructTypeRefCount(node->getType());
+ }
+}
+
+bool RemoveUnreferencedVariablesTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
+{
+ if (visit == PreVisit && mRemoveReferences)
+ {
+ decrementStructTypeRefCount(node->getType());
+ }
+ return true;
+}
+
+void RemoveUnreferencedVariablesTraverser::traverseBlock(TIntermBlock *node)
+{
+ // We traverse blocks in reverse order. This way reference counts can be decremented when
+ // removing initializers, and variables that become unused when initializers are removed can be
+ // removed on the same traversal.
+
+ ScopedNodeInTraversalPath addToPath(this, node);
+
+ bool visit = true;
+
+ TIntermSequence *sequence = node->getSequence();
+
+ if (preVisit)
+ visit = visitBlock(PreVisit, node);
+
+ if (visit)
+ {
+ for (auto iter = sequence->rbegin(); iter != sequence->rend(); ++iter)
+ {
+ (*iter)->traverse(this);
+ if (visit && inVisit)
+ {
+ if ((iter + 1) != sequence->rend())
+ visit = visitBlock(InVisit, node);
+ }
+ }
+ }
+
+ if (visit && postVisit)
+ visitBlock(PostVisit, node);
+}
+
+void RemoveUnreferencedVariablesTraverser::traverseLoop(TIntermLoop *node)
+{
+ // We traverse loops in reverse order as well. The loop body gets traversed before the init
+ // node.
+
+ ScopedNodeInTraversalPath addToPath(this, node);
+
+ bool visit = true;
+
+ if (preVisit)
+ visit = visitLoop(PreVisit, node);
+
+ if (visit)
+ {
+ // We don't need to traverse loop expressions or conditions since they can't be declarations
+ // in the AST (loops which have a declaration in their condition get transformed in the
+ // parsing stage).
+ ASSERT(node->getExpression() == nullptr ||
+ node->getExpression()->getAsDeclarationNode() == nullptr);
+ ASSERT(node->getCondition() == nullptr ||
+ node->getCondition()->getAsDeclarationNode() == nullptr);
+
+ if (node->getBody())
+ node->getBody()->traverse(this);
+
+ if (node->getInit())
+ node->getInit()->traverse(this);
+ }
+
+ if (visit && postVisit)
+ visitLoop(PostVisit, node);
+}
+
+} // namespace
+
+bool RemoveUnreferencedVariables(TCompiler *compiler, TIntermBlock *root, TSymbolTable *symbolTable)
+{
+ CollectVariableRefCountsTraverser collector;
+ root->traverse(&collector);
+ RemoveUnreferencedVariablesTraverser traverser(&collector.getSymbolIdRefCounts(),
+ &collector.getStructIdRefCounts(), symbolTable);
+ root->traverse(&traverser);
+ return traverser.updateTree(compiler, root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveUnreferencedVariables.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveUnreferencedVariables.h
new file mode 100644
index 0000000000..071d19e51e
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RemoveUnreferencedVariables.h
@@ -0,0 +1,29 @@
+//
+// Copyright 2017 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.
+//
+// RemoveUnreferencedVariables.h:
+// Drop variables that are declared but never referenced in the AST. This avoids adding unnecessary
+// initialization code for them. Also removes unreferenced struct types.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_REMOVEUNREFERENCEDVARIABLES_H_
+#define COMPILER_TRANSLATOR_TREEOPS_REMOVEUNREFERENCEDVARIABLES_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+[[nodiscard]] bool RemoveUnreferencedVariables(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_REMOVEUNREFERENCEDVARIABLES_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteArrayOfArrayOfOpaqueUniforms.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteArrayOfArrayOfOpaqueUniforms.cpp
new file mode 100644
index 0000000000..bd12cd1006
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteArrayOfArrayOfOpaqueUniforms.cpp
@@ -0,0 +1,348 @@
+//
+// Copyright 2019 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.
+//
+// RewriteAtomicCounters: Emulate atomic counter buffers with storage buffers.
+//
+
+#include "compiler/translator/tree_ops/RewriteArrayOfArrayOfOpaqueUniforms.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/ImmutableStringBuilder.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/tree_util/ReplaceVariable.h"
+
+namespace sh
+{
+namespace
+{
+struct UniformData
+{
+ // Corresponding to an array of array of opaque uniform variable, this is the flattened variable
+ // that is replacing it.
+ const TVariable *flattened;
+ // Assume a general case of array declaration with N dimensions:
+ //
+ // uniform type u[Dn]..[D2][D1];
+ //
+ // Let's define
+ //
+ // Pn = D(n-1)*...*D2*D1
+ //
+ // In that case, we have:
+ //
+ // u[In] = ac + In*Pn
+ // u[In][I(n-1)] = ac + In*Pn + I(n-1)*P(n-1)
+ // u[In]...[Ii] = ac + In*Pn + ... + Ii*Pi
+ //
+ // This array contains Pi. Note that the like TType::mArraySizes, the last element is the
+ // outermost dimension. Element 0 is necessarily 1.
+ TVector<unsigned int> mSubArraySizes;
+};
+
+using UniformMap = angle::HashMap<const TVariable *, UniformData>;
+
+TIntermTyped *RewriteArrayOfArraySubscriptExpression(TCompiler *compiler,
+ TIntermBinary *node,
+ const UniformMap &uniformMap);
+
+// Given an expression, this traverser calculates a new expression where array of array of opaque
+// uniforms are replaced with their flattened ones. In particular, this is run on the right node of
+// EOpIndexIndirect binary nodes, so that the expression in the index gets a chance to go through
+// this transformation.
+class RewriteExpressionTraverser final : public TIntermTraverser
+{
+ public:
+ explicit RewriteExpressionTraverser(TCompiler *compiler, const UniformMap &uniformMap)
+ : TIntermTraverser(true, false, false), mCompiler(compiler), mUniformMap(uniformMap)
+ {}
+
+ bool visitBinary(Visit visit, TIntermBinary *node) override
+ {
+ TIntermTyped *rewritten =
+ RewriteArrayOfArraySubscriptExpression(mCompiler, node, mUniformMap);
+ if (rewritten == nullptr)
+ {
+ return true;
+ }
+
+ queueReplacement(rewritten, OriginalNode::IS_DROPPED);
+
+ // Don't iterate as the expression is rewritten.
+ return false;
+ }
+
+ void visitSymbol(TIntermSymbol *node) override
+ {
+ // We cannot reach here for an opaque uniform that is being replaced. visitBinary should
+ // have taken care of it.
+ ASSERT(!IsOpaqueType(node->getType().getBasicType()) ||
+ mUniformMap.find(&node->variable()) == mUniformMap.end());
+ }
+
+ private:
+ TCompiler *mCompiler;
+
+ const UniformMap &mUniformMap;
+};
+
+// Rewrite the index of an EOpIndexIndirect expression. The root can never need replacing, because
+// it cannot be an opaque uniform itself.
+void RewriteIndexExpression(TCompiler *compiler,
+ TIntermTyped *expression,
+ const UniformMap &uniformMap)
+{
+ RewriteExpressionTraverser traverser(compiler, uniformMap);
+ expression->traverse(&traverser);
+ bool valid = traverser.updateTree(compiler, expression);
+ ASSERT(valid);
+}
+
+// Given an expression such as the following:
+//
+// EOpIndex(In)Direct (opaque uniform)
+// / \
+// EOpIndex(In)Direct I1
+// / \
+// ... I2
+// /
+// EOpIndex(In)Direct
+// / \
+// uniform In
+//
+// produces:
+//
+// EOpIndex(In)Direct
+// / \
+// uniform In*Pn + ... + I2*P2 + I1*P1
+//
+TIntermTyped *RewriteArrayOfArraySubscriptExpression(TCompiler *compiler,
+ TIntermBinary *node,
+ const UniformMap &uniformMap)
+{
+ // Only interested in opaque uniforms.
+ if (!IsOpaqueType(node->getType().getBasicType()))
+ {
+ return nullptr;
+ }
+
+ TIntermSymbol *opaqueUniform = nullptr;
+
+ // Iterate once and find the opaque uniform that's being indexed.
+ TIntermBinary *iter = node;
+ while (opaqueUniform == nullptr)
+ {
+ ASSERT(iter->getOp() == EOpIndexDirect || iter->getOp() == EOpIndexIndirect);
+
+ opaqueUniform = iter->getLeft()->getAsSymbolNode();
+ iter = iter->getLeft()->getAsBinaryNode();
+ }
+
+ // If not being replaced, there's nothing to do.
+ auto flattenedIter = uniformMap.find(&opaqueUniform->variable());
+ if (flattenedIter == uniformMap.end())
+ {
+ return nullptr;
+ }
+
+ const UniformData &data = flattenedIter->second;
+
+ // Iterate again and build the index expression. The index expression constitutes the sum of
+ // the variable indices plus a constant offset calculated from the constant indices. For
+ // example, smplr[1][x][2][y] will have an index of x*P3 + y*P1 + c, where c = (1*P4 + 2*P2).
+ unsigned int constantOffset = 0;
+ TIntermTyped *variableIndex = nullptr;
+
+ // Since the opaque uniforms are fully subscripted, we know exactly how many EOpIndex* nodes
+ // there should be.
+ for (size_t dimIndex = 0; dimIndex < data.mSubArraySizes.size(); ++dimIndex)
+ {
+ ASSERT(node);
+
+ unsigned int subArraySize = data.mSubArraySizes[dimIndex];
+
+ switch (node->getOp())
+ {
+ case EOpIndexDirect:
+ // Accumulate the constant index.
+ constantOffset +=
+ node->getRight()->getAsConstantUnion()->getIConst(0) * subArraySize;
+ break;
+ case EOpIndexIndirect:
+ {
+ // Run RewriteExpressionTraverser on the right node. It may itself be an expression
+ // with an array of array of opaque uniform inside that needs to be rewritten.
+ TIntermTyped *indexExpression = node->getRight();
+ RewriteIndexExpression(compiler, indexExpression, uniformMap);
+
+ // Scale and accumulate.
+ if (subArraySize != 1)
+ {
+ indexExpression =
+ new TIntermBinary(EOpMul, indexExpression, CreateIndexNode(subArraySize));
+ }
+
+ if (variableIndex == nullptr)
+ {
+ variableIndex = indexExpression;
+ }
+ else
+ {
+ variableIndex = new TIntermBinary(EOpAdd, variableIndex, indexExpression);
+ }
+ break;
+ }
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ node = node->getLeft()->getAsBinaryNode();
+ }
+
+ // Add the two accumulated indices together.
+ TIntermTyped *index = nullptr;
+ if (constantOffset == 0 && variableIndex != nullptr)
+ {
+ // No constant offset, but there's variable offset. Take that as offset.
+ index = variableIndex;
+ }
+ else
+ {
+ // Either the constant offset is non zero, or there's no variable offset (so constant 0
+ // should be used).
+ index = CreateIndexNode(constantOffset);
+
+ if (variableIndex)
+ {
+ index = new TIntermBinary(EOpAdd, index, variableIndex);
+ }
+ }
+
+ // Create an index into the flattened uniform.
+ TOperator op = variableIndex ? EOpIndexIndirect : EOpIndexDirect;
+ return new TIntermBinary(op, new TIntermSymbol(data.flattened), index);
+}
+
+// Traverser that takes:
+//
+// uniform sampler/image/atomic_uint u[N][M]..
+//
+// and transforms it to:
+//
+// uniform sampler/image/atomic_uint u[N * M * ..]
+//
+// MonomorphizeUnsupportedFunctions makes it impossible for this array to be partially
+// subscripted, or passed as argument to a function unsubscripted. This means that every encounter
+// of this uniform can be expected to be fully subscripted.
+//
+class RewriteArrayOfArrayOfOpaqueUniformsTraverser : public TIntermTraverser
+{
+ public:
+ RewriteArrayOfArrayOfOpaqueUniformsTraverser(TCompiler *compiler, TSymbolTable *symbolTable)
+ : TIntermTraverser(true, false, false, symbolTable), mCompiler(compiler)
+ {}
+
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override
+ {
+ if (!mInGlobalScope)
+ {
+ return true;
+ }
+
+ const TIntermSequence &sequence = *(node->getSequence());
+
+ TIntermTyped *variable = sequence.front()->getAsTyped();
+ const TType &type = variable->getType();
+ bool isOpaqueUniform =
+ type.getQualifier() == EvqUniform && IsOpaqueType(type.getBasicType());
+
+ // Only interested in array of array of opaque uniforms.
+ if (!isOpaqueUniform || !type.isArrayOfArrays())
+ {
+ return false;
+ }
+
+ // Opaque uniforms cannot have initializers, so the declaration must necessarily be a
+ // symbol.
+ TIntermSymbol *symbol = variable->getAsSymbolNode();
+ ASSERT(symbol != nullptr);
+
+ const TVariable *uniformVariable = &symbol->variable();
+
+ // Create an entry in the map.
+ ASSERT(mUniformMap.find(uniformVariable) == mUniformMap.end());
+ UniformData &data = mUniformMap[uniformVariable];
+
+ // Calculate the accumulated dimension products. See UniformData::mSubArraySizes.
+ const TSpan<const unsigned int> &arraySizes = type.getArraySizes();
+ mUniformMap[uniformVariable].mSubArraySizes.resize(arraySizes.size());
+ unsigned int runningProduct = 1;
+ for (size_t dimension = 0; dimension < arraySizes.size(); ++dimension)
+ {
+ data.mSubArraySizes[dimension] = runningProduct;
+ runningProduct *= arraySizes[dimension];
+ }
+
+ // Create a replacement variable with the array flattened.
+ TType *newType = new TType(type);
+ newType->toArrayBaseType();
+ newType->makeArray(runningProduct);
+
+ data.flattened = new TVariable(mSymbolTable, uniformVariable->name(), newType,
+ uniformVariable->symbolType());
+
+ TIntermDeclaration *decl = new TIntermDeclaration;
+ decl->appendDeclarator(new TIntermSymbol(data.flattened));
+
+ queueReplacement(decl, OriginalNode::IS_DROPPED);
+ return false;
+ }
+
+ bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override
+ {
+ // As an optimization, don't bother inspecting functions if there aren't any opaque uniforms
+ // to replace.
+ return !mUniformMap.empty();
+ }
+
+ // Same implementation as in RewriteExpressionTraverser. That traverser cannot replace root.
+ bool visitBinary(Visit visit, TIntermBinary *node) override
+ {
+ TIntermTyped *rewritten =
+ RewriteArrayOfArraySubscriptExpression(mCompiler, node, mUniformMap);
+ if (rewritten == nullptr)
+ {
+ return true;
+ }
+
+ queueReplacement(rewritten, OriginalNode::IS_DROPPED);
+
+ // Don't iterate as the expression is rewritten.
+ return false;
+ }
+
+ void visitSymbol(TIntermSymbol *node) override
+ {
+ ASSERT(!IsOpaqueType(node->getType().getBasicType()) ||
+ mUniformMap.find(&node->variable()) == mUniformMap.end());
+ }
+
+ private:
+ TCompiler *mCompiler;
+ UniformMap mUniformMap;
+};
+} // anonymous namespace
+
+bool RewriteArrayOfArrayOfOpaqueUniforms(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable)
+{
+ RewriteArrayOfArrayOfOpaqueUniformsTraverser traverser(compiler, symbolTable);
+ root->traverse(&traverser);
+ return traverser.updateTree(compiler, root);
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteArrayOfArrayOfOpaqueUniforms.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteArrayOfArrayOfOpaqueUniforms.h
new file mode 100644
index 0000000000..859ce16dc8
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteArrayOfArrayOfOpaqueUniforms.h
@@ -0,0 +1,25 @@
+//
+// Copyright 2021 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.
+//
+// RewriteArrayOfArrayOfOpaqueUniforms: Flatten array of array of opaque uniforms. Requires
+// MonomorphizeUnsupportedFunctions and RewriteStructSamplers to have been run.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_REWRITEARRAYOFARRAYOFOPAQUEUNIFORMS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_REWRITEARRAYOFARRAYOFOPAQUEUNIFORMS_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+[[nodiscard]] bool RewriteArrayOfArrayOfOpaqueUniforms(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_REWRITEARRAYOFARRAYOFOPAQUEUNIFORMS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteAtomicCounters.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteAtomicCounters.cpp
new file mode 100644
index 0000000000..defc59bcc0
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteAtomicCounters.cpp
@@ -0,0 +1,328 @@
+//
+// Copyright 2019 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.
+//
+// RewriteAtomicCounters: Emulate atomic counter buffers with storage buffers.
+//
+
+#include "compiler/translator/tree_ops/RewriteAtomicCounters.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/ImmutableStringBuilder.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/tree_util/ReplaceVariable.h"
+
+namespace sh
+{
+namespace
+{
+constexpr ImmutableString kAtomicCountersVarName = ImmutableString("atomicCounters");
+constexpr ImmutableString kAtomicCounterFieldName = ImmutableString("counters");
+
+// DeclareAtomicCountersBuffer adds a storage buffer array that's used with atomic counters.
+const TVariable *DeclareAtomicCountersBuffers(TIntermBlock *root, TSymbolTable *symbolTable)
+{
+ // Define `uint counters[];` as the only field in the interface block.
+ TFieldList *fieldList = new TFieldList;
+ TType *counterType = new TType(EbtUInt, EbpHigh, EvqGlobal);
+ counterType->makeArray(0);
+
+ TField *countersField =
+ new TField(counterType, kAtomicCounterFieldName, TSourceLoc(), SymbolType::AngleInternal);
+
+ fieldList->push_back(countersField);
+
+ TMemoryQualifier coherentMemory = TMemoryQualifier::Create();
+ coherentMemory.coherent = true;
+
+ // There are a maximum of 8 atomic counter buffers per IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFERS
+ // in libANGLE/Constants.h.
+ constexpr uint32_t kMaxAtomicCounterBuffers = 8;
+
+ // Define a storage block "ANGLEAtomicCounters" with instance name "atomicCounters".
+ TLayoutQualifier layoutQualifier = TLayoutQualifier::Create();
+ layoutQualifier.blockStorage = EbsStd430;
+
+ return DeclareInterfaceBlock(root, symbolTable, fieldList, EvqBuffer, layoutQualifier,
+ coherentMemory, kMaxAtomicCounterBuffers,
+ ImmutableString(vk::kAtomicCountersBlockName),
+ kAtomicCountersVarName);
+}
+
+TIntermTyped *CreateUniformBufferOffset(const TIntermTyped *uniformBufferOffsets, int binding)
+{
+ // Each uint in the |acbBufferOffsets| uniform contains offsets for 4 bindings. Therefore, the
+ // expression to get the uniform offset for the binding is:
+ //
+ // acbBufferOffsets[binding / 4] >> ((binding % 4) * 8) & 0xFF
+
+ // acbBufferOffsets[binding / 4]
+ TIntermBinary *uniformBufferOffsetUint = new TIntermBinary(
+ EOpIndexDirect, uniformBufferOffsets->deepCopy(), CreateIndexNode(binding / 4));
+
+ // acbBufferOffsets[binding / 4] >> ((binding % 4) * 8)
+ TIntermBinary *uniformBufferOffsetShifted = uniformBufferOffsetUint;
+ if (binding % 4 != 0)
+ {
+ uniformBufferOffsetShifted = new TIntermBinary(EOpBitShiftRight, uniformBufferOffsetUint,
+ CreateUIntNode((binding % 4) * 8));
+ }
+
+ // acbBufferOffsets[binding / 4] >> ((binding % 4) * 8) & 0xFF
+ return new TIntermBinary(EOpBitwiseAnd, uniformBufferOffsetShifted, CreateUIntNode(0xFF));
+}
+
+TIntermBinary *CreateAtomicCounterRef(TIntermTyped *atomicCounterExpression,
+ const TVariable *atomicCounters,
+ const TIntermTyped *uniformBufferOffsets)
+{
+ // The atomic counters storage buffer declaration looks as such:
+ //
+ // layout(...) buffer ANGLEAtomicCounters
+ // {
+ // uint counters[];
+ // } atomicCounters[N];
+ //
+ // Where N is large enough to accommodate atomic counter buffer bindings used in the shader.
+ //
+ // This function takes an expression that uses an atomic counter, which can either be:
+ //
+ // - ac
+ // - acArray[index]
+ //
+ // Note that RewriteArrayOfArrayOfOpaqueUniforms has already flattened array of array of atomic
+ // counters.
+ //
+ // For the first case (ac), the following code is generated:
+ //
+ // atomicCounters[binding].counters[offset]
+ //
+ // For the second case (acArray[index]), the following code is generated:
+ //
+ // atomicCounters[binding].counters[offset + index]
+ //
+ // In either case, an offset given through uniforms is also added to |offset|. The binding is
+ // necessarily a constant thanks to MonomorphizeUnsupportedFunctions.
+
+ // First determine if there's an index, and extract the atomic counter symbol out of the
+ // expression.
+ TIntermSymbol *atomicCounterSymbol = atomicCounterExpression->getAsSymbolNode();
+ TIntermTyped *atomicCounterIndex = nullptr;
+ int atomicCounterConstIndex = 0;
+ TIntermBinary *asBinary = atomicCounterExpression->getAsBinaryNode();
+ if (asBinary != nullptr)
+ {
+ atomicCounterSymbol = asBinary->getLeft()->getAsSymbolNode();
+
+ switch (asBinary->getOp())
+ {
+ case EOpIndexDirect:
+ atomicCounterConstIndex = asBinary->getRight()->getAsConstantUnion()->getIConst(0);
+ break;
+ case EOpIndexIndirect:
+ atomicCounterIndex = asBinary->getRight();
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ // Extract binding and offset information out of the atomic counter symbol.
+ ASSERT(atomicCounterSymbol);
+ const TVariable *atomicCounterVar = &atomicCounterSymbol->variable();
+ const TType &atomicCounterType = atomicCounterVar->getType();
+
+ const int binding = atomicCounterType.getLayoutQualifier().binding;
+ int offset = atomicCounterType.getLayoutQualifier().offset / 4;
+
+ // Create the expression:
+ //
+ // offset + arrayIndex + uniformOffset
+ //
+ // If arrayIndex is a constant, it's added with offset right here.
+
+ offset += atomicCounterConstIndex;
+
+ TIntermTyped *index = CreateUniformBufferOffset(uniformBufferOffsets, binding);
+ if (atomicCounterIndex != nullptr)
+ {
+ index = new TIntermBinary(EOpAdd, index, atomicCounterIndex);
+ }
+ if (offset != 0)
+ {
+ index = new TIntermBinary(EOpAdd, index, CreateIndexNode(offset));
+ }
+
+ // Finally, create the complete expression:
+ //
+ // atomicCounters[binding].counters[index]
+
+ TIntermSymbol *atomicCountersRef = new TIntermSymbol(atomicCounters);
+
+ // atomicCounters[binding]
+ TIntermBinary *countersBlock =
+ new TIntermBinary(EOpIndexDirect, atomicCountersRef, CreateIndexNode(binding));
+
+ // atomicCounters[binding].counters
+ TIntermBinary *counters =
+ new TIntermBinary(EOpIndexDirectInterfaceBlock, countersBlock, CreateIndexNode(0));
+
+ return new TIntermBinary(EOpIndexIndirect, counters, index);
+}
+
+// Traverser that:
+//
+// 1. Removes the |uniform atomic_uint| declarations and remembers the binding and offset.
+// 2. Substitutes |atomicVar[n]| with |buffer[binding].counters[offset + n]|.
+class RewriteAtomicCountersTraverser : public TIntermTraverser
+{
+ public:
+ RewriteAtomicCountersTraverser(TSymbolTable *symbolTable,
+ const TVariable *atomicCounters,
+ const TIntermTyped *acbBufferOffsets)
+ : TIntermTraverser(true, false, false, symbolTable),
+ mAtomicCounters(atomicCounters),
+ mAcbBufferOffsets(acbBufferOffsets)
+ {}
+
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override
+ {
+ if (!mInGlobalScope)
+ {
+ return true;
+ }
+
+ const TIntermSequence &sequence = *(node->getSequence());
+
+ TIntermTyped *variable = sequence.front()->getAsTyped();
+ const TType &type = variable->getType();
+ bool isAtomicCounter = type.isAtomicCounter();
+
+ if (isAtomicCounter)
+ {
+ ASSERT(type.getQualifier() == EvqUniform);
+ TIntermSequence emptySequence;
+ mMultiReplacements.emplace_back(getParentNode()->getAsBlock(), node,
+ std::move(emptySequence));
+
+ return false;
+ }
+
+ return true;
+ }
+
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override
+ {
+ if (BuiltInGroup::IsBuiltIn(node->getOp()))
+ {
+ bool converted = convertBuiltinFunction(node);
+ return !converted;
+ }
+
+ // AST functions don't require modification as atomic counter function parameters are
+ // removed by MonomorphizeUnsupportedFunctions.
+ return true;
+ }
+
+ void visitSymbol(TIntermSymbol *symbol) override
+ {
+ // Cannot encounter the atomic counter symbol directly. It can only be used with functions,
+ // and therefore it's handled by visitAggregate.
+ ASSERT(!symbol->getType().isAtomicCounter());
+ }
+
+ bool visitBinary(Visit visit, TIntermBinary *node) override
+ {
+ // Cannot encounter an atomic counter expression directly. It can only be used with
+ // functions, and therefore it's handled by visitAggregate.
+ ASSERT(!node->getType().isAtomicCounter());
+ return true;
+ }
+
+ private:
+ bool convertBuiltinFunction(TIntermAggregate *node)
+ {
+ const TOperator op = node->getOp();
+
+ // If the function is |memoryBarrierAtomicCounter|, simply replace it with
+ // |memoryBarrierBuffer|.
+ if (op == EOpMemoryBarrierAtomicCounter)
+ {
+ TIntermSequence emptySequence;
+ TIntermTyped *substituteCall = CreateBuiltInFunctionCallNode(
+ "memoryBarrierBuffer", &emptySequence, *mSymbolTable, 310);
+ queueReplacement(substituteCall, OriginalNode::IS_DROPPED);
+ return true;
+ }
+
+ // If it's an |atomicCounter*| function, replace the function with an |atomic*| equivalent.
+ if (!node->getFunction()->isAtomicCounterFunction())
+ {
+ return false;
+ }
+
+ // Note: atomicAdd(0) is used for atomic reads.
+ uint32_t valueChange = 0;
+ constexpr char kAtomicAddFunction[] = "atomicAdd";
+ bool isDecrement = false;
+
+ if (op == EOpAtomicCounterIncrement)
+ {
+ valueChange = 1;
+ }
+ else if (op == EOpAtomicCounterDecrement)
+ {
+ // uint values are required to wrap around, so 0xFFFFFFFFu is used as -1.
+ valueChange = std::numeric_limits<uint32_t>::max();
+ static_assert(static_cast<uint32_t>(-1) == std::numeric_limits<uint32_t>::max(),
+ "uint32_t max is not -1");
+
+ isDecrement = true;
+ }
+ else
+ {
+ ASSERT(op == EOpAtomicCounter);
+ }
+
+ TIntermTyped *param = (*node->getSequence())[0]->getAsTyped();
+
+ TIntermSequence substituteArguments;
+ substituteArguments.push_back(
+ CreateAtomicCounterRef(param, mAtomicCounters, mAcbBufferOffsets));
+ substituteArguments.push_back(CreateUIntNode(valueChange));
+
+ TIntermTyped *substituteCall = CreateBuiltInFunctionCallNode(
+ kAtomicAddFunction, &substituteArguments, *mSymbolTable, 310);
+
+ // Note that atomicCounterDecrement returns the *new* value instead of the prior value,
+ // unlike atomicAdd. So we need to do a -1 on the result as well.
+ if (isDecrement)
+ {
+ substituteCall = new TIntermBinary(EOpSub, substituteCall, CreateUIntNode(1));
+ }
+
+ queueReplacement(substituteCall, OriginalNode::IS_DROPPED);
+ return true;
+ }
+
+ const TVariable *mAtomicCounters;
+ const TIntermTyped *mAcbBufferOffsets;
+};
+
+} // anonymous namespace
+
+bool RewriteAtomicCounters(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ const TIntermTyped *acbBufferOffsets)
+{
+ const TVariable *atomicCounters = DeclareAtomicCountersBuffers(root, symbolTable);
+
+ RewriteAtomicCountersTraverser traverser(symbolTable, atomicCounters, acbBufferOffsets);
+ root->traverse(&traverser);
+ return traverser.updateTree(compiler, root);
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteAtomicCounters.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteAtomicCounters.h
new file mode 100644
index 0000000000..8a94f84b3a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteAtomicCounters.h
@@ -0,0 +1,28 @@
+//
+// Copyright 2019 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.
+//
+// RewriteAtomicCounters: Change atomic counter buffers to storage buffers, with atomic counter
+// variables being offsets into the uint array of that storage buffer.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_REWRITEATOMICCOUNTERS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_REWRITEATOMICCOUNTERS_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermBlock;
+class TIntermTyped;
+class TSymbolTable;
+class TVariable;
+
+[[nodiscard]] bool RewriteAtomicCounters(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ const TIntermTyped *acbBufferOffsets);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_REWRITEATOMICCOUNTERS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteCubeMapSamplersAs2DArray.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteCubeMapSamplersAs2DArray.cpp
new file mode 100644
index 0000000000..f7e5814361
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteCubeMapSamplersAs2DArray.cpp
@@ -0,0 +1,984 @@
+//
+// Copyright 2019 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.
+//
+// RewriteCubeMapSamplersAs2DArray: Change samplerCube samplers to sampler2DArray for seamful cube
+// map emulation.
+//
+// Relies on MonomorphizeUnsupportedFunctions to ensure samplerCube variables are not
+// passed to functions (for simplicity).
+//
+
+#include "compiler/translator/tree_ops/RewriteCubeMapSamplersAs2DArray.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/ImmutableStringBuilder.h"
+#include "compiler/translator/StaticType.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/tree_util/ReplaceVariable.h"
+
+namespace sh
+{
+namespace
+{
+constexpr ImmutableString kCoordTransformFuncName("ANGLECubeMapCoordTransform");
+constexpr ImmutableString kCoordTransformFuncNameImplicit("ANGLECubeMapCoordTransformImplicit");
+
+TIntermTyped *DerivativeQuotient(TIntermTyped *u,
+ TIntermTyped *du,
+ TIntermTyped *v,
+ TIntermTyped *dv,
+ TIntermTyped *vRecip)
+{
+ // (du v - dv u) / v^2
+ return new TIntermBinary(
+ EOpMul,
+ new TIntermBinary(EOpSub, new TIntermBinary(EOpMul, du->deepCopy(), v->deepCopy()),
+ new TIntermBinary(EOpMul, dv->deepCopy(), u->deepCopy())),
+ new TIntermBinary(EOpMul, vRecip->deepCopy(), vRecip->deepCopy()));
+}
+
+TIntermTyped *Swizzle1(TIntermTyped *array, int i)
+{
+ return new TIntermSwizzle(array, {i});
+}
+
+TIntermTyped *IndexDirect(TIntermTyped *array, int i)
+{
+ return new TIntermBinary(EOpIndexDirect, array, CreateIndexNode(i));
+}
+
+// Generated the common transformation in each coord transformation case. See comment in
+// declareCoordTranslationFunction(). Called with P, dPdx and dPdy.
+void TransformXMajor(const TSymbolTable &symbolTable,
+ TIntermBlock *block,
+ TIntermTyped *x,
+ TIntermTyped *y,
+ TIntermTyped *z,
+ TIntermTyped *uc,
+ TIntermTyped *vc)
+{
+ // uc = -sign(x)*z
+ // vc = -y
+ TIntermTyped *signX =
+ CreateBuiltInUnaryFunctionCallNode("sign", x->deepCopy(), symbolTable, 100);
+
+ TIntermTyped *ucValue =
+ new TIntermUnary(EOpNegative, new TIntermBinary(EOpMul, signX, z->deepCopy()), nullptr);
+ TIntermTyped *vcValue = new TIntermUnary(EOpNegative, y->deepCopy(), nullptr);
+
+ block->appendStatement(new TIntermBinary(EOpAssign, uc->deepCopy(), ucValue));
+ block->appendStatement(new TIntermBinary(EOpAssign, vc->deepCopy(), vcValue));
+}
+
+void TransformDerivativeXMajor(TIntermBlock *block,
+ TSymbolTable *symbolTable,
+ TIntermTyped *x,
+ TIntermTyped *y,
+ TIntermTyped *z,
+ TIntermTyped *dx,
+ TIntermTyped *dy,
+ TIntermTyped *dz,
+ TIntermTyped *du,
+ TIntermTyped *dv,
+ TIntermTyped *xRecip)
+{
+ // Only the magnitude of the derivative matters, so we ignore the sign(x)
+ // and the negations.
+ TIntermTyped *duValue = DerivativeQuotient(z, dz, x, dx, xRecip);
+ TIntermTyped *dvValue = DerivativeQuotient(y, dy, x, dx, xRecip);
+ duValue = new TIntermBinary(EOpMul, duValue, CreateFloatNode(0.5f, EbpMedium));
+ dvValue = new TIntermBinary(EOpMul, dvValue, CreateFloatNode(0.5f, EbpMedium));
+ block->appendStatement(new TIntermBinary(EOpAssign, du->deepCopy(), duValue));
+ block->appendStatement(new TIntermBinary(EOpAssign, dv->deepCopy(), dvValue));
+}
+
+void TransformImplicitDerivativeXMajor(TIntermBlock *block,
+ TIntermTyped *dOuter,
+ TIntermTyped *du,
+ TIntermTyped *dv)
+{
+ block->appendStatement(
+ new TIntermBinary(EOpAssign, du->deepCopy(), Swizzle1(dOuter->deepCopy(), 2)));
+ block->appendStatement(
+ new TIntermBinary(EOpAssign, dv->deepCopy(), Swizzle1(dOuter->deepCopy(), 1)));
+}
+
+void TransformYMajor(const TSymbolTable &symbolTable,
+ TIntermBlock *block,
+ TIntermTyped *x,
+ TIntermTyped *y,
+ TIntermTyped *z,
+ TIntermTyped *uc,
+ TIntermTyped *vc)
+{
+ // uc = x
+ // vc = sign(y)*z
+ TIntermTyped *signY =
+ CreateBuiltInUnaryFunctionCallNode("sign", y->deepCopy(), symbolTable, 100);
+
+ TIntermTyped *ucValue = x->deepCopy();
+ TIntermTyped *vcValue = new TIntermBinary(EOpMul, signY, z->deepCopy());
+
+ block->appendStatement(new TIntermBinary(EOpAssign, uc->deepCopy(), ucValue));
+ block->appendStatement(new TIntermBinary(EOpAssign, vc->deepCopy(), vcValue));
+}
+
+void TransformDerivativeYMajor(TIntermBlock *block,
+ TSymbolTable *symbolTable,
+ TIntermTyped *x,
+ TIntermTyped *y,
+ TIntermTyped *z,
+ TIntermTyped *dx,
+ TIntermTyped *dy,
+ TIntermTyped *dz,
+ TIntermTyped *du,
+ TIntermTyped *dv,
+ TIntermTyped *yRecip)
+{
+ // Only the magnitude of the derivative matters, so we ignore the sign(x)
+ // and the negations.
+ TIntermTyped *duValue = DerivativeQuotient(x, dx, y, dy, yRecip);
+ TIntermTyped *dvValue = DerivativeQuotient(z, dz, y, dy, yRecip);
+ duValue = new TIntermBinary(EOpMul, duValue, CreateFloatNode(0.5f, EbpMedium));
+ dvValue = new TIntermBinary(EOpMul, dvValue, CreateFloatNode(0.5f, EbpMedium));
+ block->appendStatement(new TIntermBinary(EOpAssign, du->deepCopy(), duValue));
+ block->appendStatement(new TIntermBinary(EOpAssign, dv->deepCopy(), dvValue));
+}
+
+void TransformImplicitDerivativeYMajor(TIntermBlock *block,
+ TIntermTyped *dOuter,
+ TIntermTyped *du,
+ TIntermTyped *dv)
+{
+ block->appendStatement(
+ new TIntermBinary(EOpAssign, du->deepCopy(), Swizzle1(dOuter->deepCopy(), 0)));
+ block->appendStatement(
+ new TIntermBinary(EOpAssign, dv->deepCopy(), Swizzle1(dOuter->deepCopy(), 2)));
+}
+
+void TransformZMajor(const TSymbolTable &symbolTable,
+ TIntermBlock *block,
+ TIntermTyped *x,
+ TIntermTyped *y,
+ TIntermTyped *z,
+ TIntermTyped *uc,
+ TIntermTyped *vc)
+{
+ // uc = size(z)*x
+ // vc = -y
+ TIntermTyped *signZ =
+ CreateBuiltInUnaryFunctionCallNode("sign", z->deepCopy(), symbolTable, 100);
+
+ TIntermTyped *ucValue = new TIntermBinary(EOpMul, signZ, x->deepCopy());
+ TIntermTyped *vcValue = new TIntermUnary(EOpNegative, y->deepCopy(), nullptr);
+
+ block->appendStatement(new TIntermBinary(EOpAssign, uc->deepCopy(), ucValue));
+ block->appendStatement(new TIntermBinary(EOpAssign, vc->deepCopy(), vcValue));
+}
+
+void TransformDerivativeZMajor(TIntermBlock *block,
+ TSymbolTable *symbolTable,
+ TIntermTyped *x,
+ TIntermTyped *y,
+ TIntermTyped *z,
+ TIntermTyped *dx,
+ TIntermTyped *dy,
+ TIntermTyped *dz,
+ TIntermTyped *du,
+ TIntermTyped *dv,
+ TIntermTyped *zRecip)
+{
+ // Only the magnitude of the derivative matters, so we ignore the sign(x)
+ // and the negations.
+ TIntermTyped *duValue = DerivativeQuotient(x, dx, z, dz, zRecip);
+ TIntermTyped *dvValue = DerivativeQuotient(y, dy, z, dz, zRecip);
+ duValue = new TIntermBinary(EOpMul, duValue, CreateFloatNode(0.5f, EbpMedium));
+ dvValue = new TIntermBinary(EOpMul, dvValue, CreateFloatNode(0.5f, EbpMedium));
+ block->appendStatement(new TIntermBinary(EOpAssign, du->deepCopy(), duValue));
+ block->appendStatement(new TIntermBinary(EOpAssign, dv->deepCopy(), dvValue));
+}
+
+void TransformImplicitDerivativeZMajor(TIntermBlock *block,
+ TIntermTyped *dOuter,
+ TIntermTyped *du,
+ TIntermTyped *dv)
+{
+ block->appendStatement(
+ new TIntermBinary(EOpAssign, du->deepCopy(), Swizzle1(dOuter->deepCopy(), 0)));
+ block->appendStatement(
+ new TIntermBinary(EOpAssign, dv->deepCopy(), Swizzle1(dOuter->deepCopy(), 1)));
+}
+
+class RewriteCubeMapSamplersAs2DArrayTraverser : public TIntermTraverser
+{
+ public:
+ RewriteCubeMapSamplersAs2DArrayTraverser(TSymbolTable *symbolTable, bool isFragmentShader)
+ : TIntermTraverser(true, false, false, symbolTable),
+ mCubeXYZToArrayUVL(nullptr),
+ mCubeXYZToArrayUVLImplicit(nullptr),
+ mIsFragmentShader(isFragmentShader),
+ mCoordTranslationFunctionDecl(nullptr),
+ mCoordTranslationFunctionImplicitDecl(nullptr)
+ {}
+
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override
+ {
+ const TIntermSequence &sequence = *(node->getSequence());
+
+ TIntermTyped *variable = sequence.front()->getAsTyped();
+ const TType &type = variable->getType();
+ bool isSamplerCube = type.getQualifier() == EvqUniform && type.isSamplerCube();
+
+ if (isSamplerCube)
+ {
+ // Samplers cannot have initializers, so the declaration must necessarily be a symbol.
+ TIntermSymbol *samplerVariable = variable->getAsSymbolNode();
+ ASSERT(samplerVariable != nullptr);
+
+ declareSampler2DArray(&samplerVariable->variable(), node);
+ return false;
+ }
+
+ return true;
+ }
+
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override
+ {
+ if (BuiltInGroup::IsBuiltIn(node->getOp()))
+ {
+ bool converted = convertBuiltinFunction(node);
+ return !converted;
+ }
+
+ // AST functions don't require modification as samplerCube function parameters are removed
+ // by MonomorphizeUnsupportedFunctions.
+ return true;
+ }
+
+ TIntermFunctionDefinition *getCoordTranslationFunctionDecl()
+ {
+ return mCoordTranslationFunctionDecl;
+ }
+
+ TIntermFunctionDefinition *getCoordTranslationFunctionDeclImplicit()
+ {
+ return mCoordTranslationFunctionImplicitDecl;
+ }
+
+ private:
+ void declareSampler2DArray(const TVariable *samplerCubeVar, TIntermDeclaration *node)
+ {
+ if (mCubeXYZToArrayUVL == nullptr)
+ {
+ // If not done yet, declare the function that transforms cube map texture sampling
+ // coordinates to face index and uv coordinates.
+ declareCoordTranslationFunction(false, kCoordTransformFuncName, &mCubeXYZToArrayUVL,
+ &mCoordTranslationFunctionDecl);
+ }
+ if (mCubeXYZToArrayUVLImplicit == nullptr && mIsFragmentShader)
+ {
+ declareCoordTranslationFunction(true, kCoordTransformFuncNameImplicit,
+ &mCubeXYZToArrayUVLImplicit,
+ &mCoordTranslationFunctionImplicitDecl);
+ }
+
+ TType *newType = new TType(samplerCubeVar->getType());
+ newType->setBasicType(EbtSampler2DArray);
+
+ TVariable *sampler2DArrayVar = new TVariable(mSymbolTable, samplerCubeVar->name(), newType,
+ samplerCubeVar->symbolType());
+
+ TIntermDeclaration *sampler2DArrayDecl = new TIntermDeclaration();
+ sampler2DArrayDecl->appendDeclarator(new TIntermSymbol(sampler2DArrayVar));
+
+ queueReplacement(sampler2DArrayDecl, OriginalNode::IS_DROPPED);
+
+ // Remember the sampler2DArray variable.
+ mSamplerMap[samplerCubeVar] = sampler2DArrayVar;
+ }
+
+ void declareCoordTranslationFunction(bool implicit,
+ const ImmutableString &name,
+ TFunction **functionOut,
+ TIntermFunctionDefinition **declOut)
+ {
+ // GLES2.0 (as well as desktop OpenGL 2.0) define the coordination transformation as
+ // follows. Given xyz cube coordinates, where each channel is in [-1, 1], the following
+ // table calculates uc, vc and ma as well as the cube map face.
+ //
+ // Major Axis Direction Target uc vc ma
+ // +x TEXTURE_CUBE_MAP_POSITIVE_X -z -y |x|
+ // -x TEXTURE_CUBE_MAP_NEGATIVE_X z -y |x|
+ // +y TEXTURE_CUBE_MAP_POSITIVE_Y x z |y|
+ // -y TEXTURE_CUBE_MAP_NEGATIVE_Y x -z |y|
+ // +z TEXTURE_CUBE_MAP_POSITIVE_Z x -y |z|
+ // -z TEXTURE_CUBE_MAP_NEGATIVE_Z -x -y |z|
+ //
+ // "Major" is an indication of the axis with the largest value. The cube map face indicates
+ // the layer to sample from. The uv coordinates to sample from are calculated as,
+ // effectively transforming the uv values to [0, 1]:
+ //
+ // u = (1 + uc/ma) / 2
+ // v = (1 + vc/ma) / 2
+ //
+ // The function can be implemented as 6 ifs, though it would be far from efficient. The
+ // following calculations implement the table above in a smaller number of instructions.
+ //
+ // First, ma can be calculated as the max of the three axes.
+ //
+ // ma = max3(|x|, |y|, |z|)
+ //
+ // We have three cases:
+ //
+ // ma == |x|: uc = -sign(x)*z
+ // vc = -y
+ // layer = float(x < 0)
+ //
+ // ma == |y|: uc = x
+ // vc = sign(y)*z
+ // layer = 2 + float(y < 0)
+ //
+ // ma == |z|: uc = size(z)*x
+ // vc = -y
+ // layer = 4 + float(z < 0)
+ //
+ // This can be implemented with a number of ?: instructions or 3 ifs. ?: would require all
+ // expressions to be evaluated (vector ALU) while if would require exec mask and jumps
+ // (scalar operations). We implement this using ifs as there would otherwise be many vector
+ // operations and not much of anything else.
+ //
+ // If textureCubeGrad is used, we also need to transform the provided dPdx and dPdy (both
+ // vec3) to a dUVdx and dUVdy. Assume P=(r,s,t) and we are investigating dx (note the
+ // change from xyz to rst to not confuse with dx and dy):
+ //
+ // uv = (f(r,s,t)/ma + 1)/2
+ //
+ // Where f is one of the transformations above for uc and vc. Between two neighbors along
+ // the x axis, we have P0=(r0,s0,t0) and P1=(r1,s1,t1)
+ //
+ // dP = (r1-r0, s1-s0, t1-t0)
+ // dUV = (f(r1,s1,t1)/ma1 - g(r0,s0,t0)/ma0) / 2
+ //
+ // f and g may not necessarily be the same because the two points may have different major
+ // axes. Even with the same major access, the sign that's used in the formulas may not be
+ // the same. Furthermore, ma0 and ma1 may not be the same. This makes it impossible to
+ // derive dUV from dP exactly.
+ //
+ // However, gradient transformation is implementation dependant, so we will simplify and
+ // assume all the above complications are non-existent. We therefore have:
+ //
+ // dUV = (f(r1,s1,t1)/ma0 - f(r0,s0,t0)/ma0)/2
+ //
+ // Given that we assumed the sign functions are returning identical results for the two
+ // points, f becomes a linear transformation. Thus:
+ //
+ // dUV = f(r1-r0,s1-0,t1-t0)/ma0/2
+ //
+ // In other words, we use the same formulae that transform XYZ (RST here) to UV to
+ // transform the derivatives.
+ //
+ // ma == |x|: dUdx = -sign(x)*dPdx.z / ma / 2
+ // dVdx = -dPdx.y / ma / 2
+ //
+ // ma == |y|: dUdx = dPdx.x / ma / 2
+ // dVdx = sign(y)*dPdx.z / ma / 2
+ //
+ // ma == |z|: dUdx = size(z)*dPdx.x / ma / 2
+ // dVdx = -dPdx.y / ma / 2
+ //
+ // Similarly for dy.
+
+ // Create the function parameters: vec3 P, vec3 dPdx, vec3 dPdy,
+ // out vec2 dUVdx, out vec2 dUVdy
+ const TType *vec3Type = StaticType::GetBasic<EbtFloat, EbpHigh, 3>();
+ TType *inVec3Type = new TType(*vec3Type);
+ inVec3Type->setQualifier(EvqParamIn);
+
+ TVariable *pVar = new TVariable(mSymbolTable, ImmutableString("P"), inVec3Type,
+ SymbolType::AngleInternal);
+ TVariable *dPdxVar = new TVariable(mSymbolTable, ImmutableString("dPdx"), inVec3Type,
+ SymbolType::AngleInternal);
+ TVariable *dPdyVar = new TVariable(mSymbolTable, ImmutableString("dPdy"), inVec3Type,
+ SymbolType::AngleInternal);
+
+ const TType *vec2Type = StaticType::GetBasic<EbtFloat, EbpHigh, 2>();
+ TType *outVec2Type = new TType(*vec2Type);
+ outVec2Type->setQualifier(EvqParamOut);
+
+ TVariable *dUVdxVar = new TVariable(mSymbolTable, ImmutableString("dUVdx"), outVec2Type,
+ SymbolType::AngleInternal);
+ TVariable *dUVdyVar = new TVariable(mSymbolTable, ImmutableString("dUVdy"), outVec2Type,
+ SymbolType::AngleInternal);
+
+ TIntermSymbol *p = new TIntermSymbol(pVar);
+ TIntermSymbol *dPdx = new TIntermSymbol(dPdxVar);
+ TIntermSymbol *dPdy = new TIntermSymbol(dPdyVar);
+ TIntermSymbol *dUVdx = new TIntermSymbol(dUVdxVar);
+ TIntermSymbol *dUVdy = new TIntermSymbol(dUVdyVar);
+
+ // Create the function body as statements are generated.
+ TIntermBlock *body = new TIntermBlock;
+
+ // Create the swizzle nodes that will be used in multiple expressions:
+ TIntermSwizzle *x = new TIntermSwizzle(p->deepCopy(), {0});
+ TIntermSwizzle *y = new TIntermSwizzle(p->deepCopy(), {1});
+ TIntermSwizzle *z = new TIntermSwizzle(p->deepCopy(), {2});
+
+ // Create abs and "< 0" expressions from the channels.
+ const TType *floatType = StaticType::GetBasic<EbtFloat, EbpHigh>();
+
+ TIntermTyped *isNegX = new TIntermBinary(EOpLessThan, x, CreateZeroNode(*floatType));
+ TIntermTyped *isNegY = new TIntermBinary(EOpLessThan, y, CreateZeroNode(*floatType));
+ TIntermTyped *isNegZ = new TIntermBinary(EOpLessThan, z, CreateZeroNode(*floatType));
+
+ TIntermSymbol *absX = new TIntermSymbol(CreateTempVariable(mSymbolTable, floatType));
+ TIntermSymbol *absY = new TIntermSymbol(CreateTempVariable(mSymbolTable, floatType));
+ TIntermSymbol *absZ = new TIntermSymbol(CreateTempVariable(mSymbolTable, floatType));
+
+ TIntermDeclaration *absXDecl = CreateTempInitDeclarationNode(
+ &absX->variable(),
+ CreateBuiltInUnaryFunctionCallNode("abs", x->deepCopy(), *mSymbolTable, 100));
+ TIntermDeclaration *absYDecl = CreateTempInitDeclarationNode(
+ &absY->variable(),
+ CreateBuiltInUnaryFunctionCallNode("abs", y->deepCopy(), *mSymbolTable, 100));
+ TIntermDeclaration *absZDecl = CreateTempInitDeclarationNode(
+ &absZ->variable(),
+ CreateBuiltInUnaryFunctionCallNode("abs", z->deepCopy(), *mSymbolTable, 100));
+
+ body->appendStatement(absXDecl);
+ body->appendStatement(absYDecl);
+ body->appendStatement(absZDecl);
+
+ // Create temporary variable for division outer product matrix and its
+ // derivatives.
+ // recipOuter[i][j] = 0.5 * P[j] / P[i]
+ const TType *mat3Type = StaticType::GetBasic<EbtFloat, EbpHigh, 3, 3>();
+ TIntermSymbol *recipOuter = new TIntermSymbol(CreateTempVariable(mSymbolTable, mat3Type));
+
+ TIntermTyped *pRecip =
+ new TIntermBinary(EOpDiv, CreateFloatNode(1.0, EbpMedium), p->deepCopy());
+ TIntermSymbol *pRecipVar = new TIntermSymbol(CreateTempVariable(mSymbolTable, vec3Type));
+
+ body->appendStatement(CreateTempInitDeclarationNode(&pRecipVar->variable(), pRecip));
+
+ TIntermSequence args = {
+ p->deepCopy(), new TIntermBinary(EOpVectorTimesScalar, CreateFloatNode(0.5, EbpMedium),
+ pRecipVar->deepCopy())};
+ TIntermDeclaration *recipOuterDecl = CreateTempInitDeclarationNode(
+ &recipOuter->variable(),
+ CreateBuiltInFunctionCallNode("outerProduct", &args, *mSymbolTable, 300));
+ body->appendStatement(recipOuterDecl);
+
+ TIntermSymbol *dPDXdx = nullptr;
+ TIntermSymbol *dPDYdx = nullptr;
+ TIntermSymbol *dPDZdx = nullptr;
+ TIntermSymbol *dPDXdy = nullptr;
+ TIntermSymbol *dPDYdy = nullptr;
+ TIntermSymbol *dPDZdy = nullptr;
+ if (implicit)
+ {
+ dPDXdx = new TIntermSymbol(CreateTempVariable(mSymbolTable, vec3Type));
+ dPDYdx = new TIntermSymbol(CreateTempVariable(mSymbolTable, vec3Type));
+ dPDZdx = new TIntermSymbol(CreateTempVariable(mSymbolTable, vec3Type));
+ dPDXdy = new TIntermSymbol(CreateTempVariable(mSymbolTable, vec3Type));
+ dPDYdy = new TIntermSymbol(CreateTempVariable(mSymbolTable, vec3Type));
+ dPDZdy = new TIntermSymbol(CreateTempVariable(mSymbolTable, vec3Type));
+
+ TIntermDeclaration *dPDXdxDecl = CreateTempInitDeclarationNode(
+ &dPDXdx->variable(),
+ CreateBuiltInUnaryFunctionCallNode("dFdx", IndexDirect(recipOuter, 0)->deepCopy(),
+ *mSymbolTable, 300));
+ TIntermDeclaration *dPDYdxDecl = CreateTempInitDeclarationNode(
+ &dPDYdx->variable(),
+ CreateBuiltInUnaryFunctionCallNode("dFdx", IndexDirect(recipOuter, 1)->deepCopy(),
+ *mSymbolTable, 300));
+ TIntermDeclaration *dPDZdxDecl = CreateTempInitDeclarationNode(
+ &dPDZdx->variable(),
+ CreateBuiltInUnaryFunctionCallNode("dFdx", IndexDirect(recipOuter, 2)->deepCopy(),
+ *mSymbolTable, 300));
+ TIntermDeclaration *dPDXdyDecl = CreateTempInitDeclarationNode(
+ &dPDXdy->variable(),
+ CreateBuiltInUnaryFunctionCallNode("dFdy", IndexDirect(recipOuter, 0)->deepCopy(),
+ *mSymbolTable, 300));
+ TIntermDeclaration *dPDYdyDecl = CreateTempInitDeclarationNode(
+ &dPDYdy->variable(),
+ CreateBuiltInUnaryFunctionCallNode("dFdy", IndexDirect(recipOuter, 1)->deepCopy(),
+ *mSymbolTable, 300));
+ TIntermDeclaration *dPDZdyDecl = CreateTempInitDeclarationNode(
+ &dPDZdy->variable(),
+ CreateBuiltInUnaryFunctionCallNode("dFdy", IndexDirect(recipOuter, 2)->deepCopy(),
+ *mSymbolTable, 300));
+
+ body->appendStatement(dPDXdxDecl);
+ body->appendStatement(dPDYdxDecl);
+ body->appendStatement(dPDZdxDecl);
+ body->appendStatement(dPDXdyDecl);
+ body->appendStatement(dPDYdyDecl);
+ body->appendStatement(dPDZdyDecl);
+ }
+
+ // Create temporary variables for ma, uc, vc, and l (layer), as well as dUdx, dVdx, dUdy
+ // and dVdy.
+ TIntermSymbol *ma = new TIntermSymbol(CreateTempVariable(mSymbolTable, floatType));
+ TIntermSymbol *l = new TIntermSymbol(CreateTempVariable(mSymbolTable, floatType));
+ TIntermSymbol *uc = new TIntermSymbol(CreateTempVariable(mSymbolTable, floatType));
+ TIntermSymbol *vc = new TIntermSymbol(CreateTempVariable(mSymbolTable, floatType));
+ TIntermSymbol *dUdx = new TIntermSymbol(CreateTempVariable(mSymbolTable, floatType));
+ TIntermSymbol *dVdx = new TIntermSymbol(CreateTempVariable(mSymbolTable, floatType));
+ TIntermSymbol *dUdy = new TIntermSymbol(CreateTempVariable(mSymbolTable, floatType));
+ TIntermSymbol *dVdy = new TIntermSymbol(CreateTempVariable(mSymbolTable, floatType));
+
+ body->appendStatement(CreateTempDeclarationNode(&ma->variable()));
+ body->appendStatement(CreateTempDeclarationNode(&l->variable()));
+ body->appendStatement(CreateTempDeclarationNode(&uc->variable()));
+ body->appendStatement(CreateTempDeclarationNode(&vc->variable()));
+ body->appendStatement(CreateTempDeclarationNode(&dUdx->variable()));
+ body->appendStatement(CreateTempDeclarationNode(&dVdx->variable()));
+ body->appendStatement(CreateTempDeclarationNode(&dUdy->variable()));
+ body->appendStatement(CreateTempDeclarationNode(&dVdy->variable()));
+
+ // ma = max(|x|, max(|y|, |z|))
+ TIntermSequence argsMaxYZ = {absY->deepCopy(), absZ->deepCopy()};
+ TIntermTyped *maxYZ = CreateBuiltInFunctionCallNode("max", &argsMaxYZ, *mSymbolTable, 100);
+ TIntermSequence argsMaxValue = {absX->deepCopy(), maxYZ};
+ TIntermTyped *maValue =
+ CreateBuiltInFunctionCallNode("max", &argsMaxValue, *mSymbolTable, 100);
+ body->appendStatement(new TIntermBinary(EOpAssign, ma, maValue));
+
+ // ma == |x| and ma == |y| expressions
+ TIntermTyped *isXMajor = new TIntermBinary(EOpEqual, ma->deepCopy(), absX->deepCopy());
+ TIntermTyped *isYMajor = new TIntermBinary(EOpEqual, ma->deepCopy(), absY->deepCopy());
+
+ // Determine the cube face:
+
+ // The case where x is major:
+ // layer = float(x < 0)
+ TIntermSequence argsNegX = {isNegX};
+ TIntermTyped *xl = TIntermAggregate::CreateConstructor(*floatType, &argsNegX);
+
+ TIntermBlock *calculateXL = new TIntermBlock;
+ calculateXL->appendStatement(new TIntermBinary(EOpAssign, l->deepCopy(), xl));
+
+ // The case where y is major:
+ // layer = 2 + float(y < 0)
+ TIntermSequence argsNegY = {isNegY};
+ TIntermTyped *yl =
+ new TIntermBinary(EOpAdd, CreateFloatNode(2.0f, EbpMedium),
+ TIntermAggregate::CreateConstructor(*floatType, &argsNegY));
+
+ TIntermBlock *calculateYL = new TIntermBlock;
+ calculateYL->appendStatement(new TIntermBinary(EOpAssign, l->deepCopy(), yl));
+
+ // The case where z is major:
+ // layer = 4 + float(z < 0)
+ TIntermSequence argsNegZ = {isNegZ};
+ TIntermTyped *zl =
+ new TIntermBinary(EOpAdd, CreateFloatNode(4.0f, EbpMedium),
+ TIntermAggregate::CreateConstructor(*floatType, &argsNegZ));
+
+ TIntermBlock *calculateZL = new TIntermBlock;
+ calculateZL->appendStatement(new TIntermBinary(EOpAssign, l->deepCopy(), zl));
+
+ // Create the if-else paths:
+ TIntermIfElse *calculateYZL = new TIntermIfElse(isYMajor, calculateYL, calculateZL);
+ TIntermBlock *calculateYZLBlock = new TIntermBlock;
+ calculateYZLBlock->appendStatement(calculateYZL);
+ TIntermIfElse *calculateXYZL = new TIntermIfElse(isXMajor, calculateXL, calculateYZLBlock);
+ body->appendStatement(calculateXYZL);
+
+ // layer < 1.5 (covering faces 0 and 1, corresponding to major axis being X) and layer < 3.5
+ // (covering faces 2 and 3, corresponding to major axis being Y). Used to determine which
+ // of the three transformations to apply. Previously, ma == |X| and ma == |Y| was used,
+ // which is no longer correct for helper invocations. The value of ma is updated in each
+ // case for these invocations.
+ isXMajor = new TIntermBinary(EOpLessThan, l->deepCopy(), CreateFloatNode(1.5f, EbpMedium));
+ isYMajor = new TIntermBinary(EOpLessThan, l->deepCopy(), CreateFloatNode(3.5f, EbpMedium));
+
+ TIntermSwizzle *dPdxX = new TIntermSwizzle(dPdx->deepCopy(), {0});
+ TIntermSwizzle *dPdxY = new TIntermSwizzle(dPdx->deepCopy(), {1});
+ TIntermSwizzle *dPdxZ = new TIntermSwizzle(dPdx->deepCopy(), {2});
+
+ TIntermSwizzle *dPdyX = new TIntermSwizzle(dPdy->deepCopy(), {0});
+ TIntermSwizzle *dPdyY = new TIntermSwizzle(dPdy->deepCopy(), {1});
+ TIntermSwizzle *dPdyZ = new TIntermSwizzle(dPdy->deepCopy(), {2});
+
+ TIntermBlock *calculateXUcVc = new TIntermBlock;
+ calculateXUcVc->appendStatement(
+ new TIntermBinary(EOpAssign, ma->deepCopy(), absX->deepCopy()));
+ TransformXMajor(*mSymbolTable, calculateXUcVc, x, y, z, uc, vc);
+
+ TIntermBlock *calculateYUcVc = new TIntermBlock;
+ calculateYUcVc->appendStatement(
+ new TIntermBinary(EOpAssign, ma->deepCopy(), absY->deepCopy()));
+ TransformYMajor(*mSymbolTable, calculateYUcVc, x, y, z, uc, vc);
+
+ TIntermBlock *calculateZUcVc = new TIntermBlock;
+ calculateZUcVc->appendStatement(
+ new TIntermBinary(EOpAssign, ma->deepCopy(), absZ->deepCopy()));
+ TransformZMajor(*mSymbolTable, calculateZUcVc, x, y, z, uc, vc);
+
+ // Compute derivatives.
+ if (implicit)
+ {
+ TransformImplicitDerivativeXMajor(calculateXUcVc, dPDXdx, dUdx, dVdx);
+ TransformImplicitDerivativeXMajor(calculateXUcVc, dPDXdy, dUdy, dVdy);
+ TransformImplicitDerivativeYMajor(calculateYUcVc, dPDYdx, dUdx, dVdx);
+ TransformImplicitDerivativeYMajor(calculateYUcVc, dPDYdy, dUdy, dVdy);
+ TransformImplicitDerivativeZMajor(calculateZUcVc, dPDZdx, dUdx, dVdx);
+ TransformImplicitDerivativeZMajor(calculateZUcVc, dPDZdy, dUdy, dVdy);
+ }
+ else
+ {
+ TransformDerivativeXMajor(calculateXUcVc, mSymbolTable, x, y, z, dPdxX, dPdxY, dPdxZ,
+ dUdx, dVdx, Swizzle1(pRecipVar->deepCopy(), 0));
+ TransformDerivativeXMajor(calculateXUcVc, mSymbolTable, x, y, z, dPdyX, dPdyY, dPdyZ,
+ dUdy, dVdy, Swizzle1(pRecipVar->deepCopy(), 0));
+ TransformDerivativeYMajor(calculateYUcVc, mSymbolTable, x, y, z, dPdxX, dPdxY, dPdxZ,
+ dUdx, dVdx, Swizzle1(pRecipVar->deepCopy(), 1));
+ TransformDerivativeYMajor(calculateYUcVc, mSymbolTable, x, y, z, dPdyX, dPdyY, dPdyZ,
+ dUdy, dVdy, Swizzle1(pRecipVar->deepCopy(), 1));
+ TransformDerivativeZMajor(calculateZUcVc, mSymbolTable, x, y, z, dPdxX, dPdxY, dPdxZ,
+ dUdx, dVdx, Swizzle1(pRecipVar->deepCopy(), 2));
+ TransformDerivativeZMajor(calculateZUcVc, mSymbolTable, x, y, z, dPdyX, dPdyY, dPdyZ,
+ dUdy, dVdy, Swizzle1(pRecipVar->deepCopy(), 2));
+ }
+
+ // Create the if-else paths:
+ TIntermIfElse *calculateYZUcVc =
+ new TIntermIfElse(isYMajor, calculateYUcVc, calculateZUcVc);
+ TIntermBlock *calculateYZUcVcBlock = new TIntermBlock;
+ calculateYZUcVcBlock->appendStatement(calculateYZUcVc);
+ TIntermIfElse *calculateXYZUcVc =
+ new TIntermIfElse(isXMajor, calculateXUcVc, calculateYZUcVcBlock);
+ body->appendStatement(calculateXYZUcVc);
+
+ // u = (1 + uc/|ma|) / 2
+ // v = (1 + vc/|ma|) / 2
+ TIntermTyped *maTimesTwoRecip = new TIntermBinary(
+ EOpAssign, ma->deepCopy(),
+ new TIntermBinary(EOpDiv, CreateFloatNode(0.5f, EbpMedium), ma->deepCopy()));
+ body->appendStatement(maTimesTwoRecip);
+
+ TIntermTyped *ucDivMa = new TIntermBinary(EOpMul, uc, ma->deepCopy());
+ TIntermTyped *vcDivMa = new TIntermBinary(EOpMul, vc, ma->deepCopy());
+ TIntermTyped *uNormalized =
+ new TIntermBinary(EOpAdd, CreateFloatNode(0.5f, EbpMedium), ucDivMa);
+ TIntermTyped *vNormalized =
+ new TIntermBinary(EOpAdd, CreateFloatNode(0.5f, EbpMedium), vcDivMa);
+
+ body->appendStatement(new TIntermBinary(EOpAssign, uc->deepCopy(), uNormalized));
+ body->appendStatement(new TIntermBinary(EOpAssign, vc->deepCopy(), vNormalized));
+
+ TIntermSequence argsDUVdx = {dUdx, dVdx};
+ TIntermTyped *dUVdxValue = TIntermAggregate::CreateConstructor(*vec2Type, &argsDUVdx);
+
+ TIntermSequence argsDUVdy = {dUdy, dVdy};
+ TIntermTyped *dUVdyValue = TIntermAggregate::CreateConstructor(*vec2Type, &argsDUVdy);
+
+ body->appendStatement(new TIntermBinary(EOpAssign, dUVdx, dUVdxValue));
+ body->appendStatement(new TIntermBinary(EOpAssign, dUVdy, dUVdyValue));
+
+ // return vec3(u, v, l)
+ TIntermSequence argsUVL = {uc->deepCopy(), vc->deepCopy(), l};
+ TIntermBranch *returnStatement =
+ new TIntermBranch(EOpReturn, TIntermAggregate::CreateConstructor(*vec3Type, &argsUVL));
+ body->appendStatement(returnStatement);
+
+ TFunction *function;
+ function = new TFunction(mSymbolTable, name, SymbolType::AngleInternal, vec3Type, true);
+ function->addParameter(pVar);
+ function->addParameter(dPdxVar);
+ function->addParameter(dPdyVar);
+ function->addParameter(dUVdxVar);
+ function->addParameter(dUVdyVar);
+
+ *functionOut = function;
+
+ *declOut = CreateInternalFunctionDefinitionNode(*function, body);
+ }
+
+ TIntermTyped *createCoordTransformationCall(TIntermTyped *P,
+ TIntermTyped *dPdx,
+ TIntermTyped *dPdy,
+ TIntermTyped *dUVdx,
+ TIntermTyped *dUVdy)
+ {
+ TIntermSequence args = {P, dPdx, dPdy, dUVdx, dUVdy};
+ return TIntermAggregate::CreateFunctionCall(*mCubeXYZToArrayUVL, &args);
+ }
+
+ TIntermTyped *createImplicitCoordTransformationCall(TIntermTyped *P,
+ TIntermTyped *dUVdx,
+ TIntermTyped *dUVdy)
+ {
+ const TType *vec3Type = StaticType::GetBasic<EbtFloat, EbpHigh, 3>();
+ TIntermTyped *dPdx = CreateZeroNode(*vec3Type);
+ TIntermTyped *dPdy = CreateZeroNode(*vec3Type);
+ TIntermSequence args = {P, dPdx, dPdy, dUVdx, dUVdy};
+ return TIntermAggregate::CreateFunctionCall(*mCubeXYZToArrayUVLImplicit, &args);
+ }
+
+ TIntermTyped *getMappedSamplerExpression(TIntermNode *samplerCubeExpression)
+ {
+ // The argument passed to a function can either be the sampler, if not array, or a subscript
+ // into the sampler array.
+ TIntermSymbol *asSymbol = samplerCubeExpression->getAsSymbolNode();
+ TIntermBinary *asBinary = samplerCubeExpression->getAsBinaryNode();
+
+ if (asBinary)
+ {
+ // Only constant indexing is supported in ES2.0.
+ ASSERT(asBinary->getOp() == EOpIndexDirect);
+ asSymbol = asBinary->getLeft()->getAsSymbolNode();
+ }
+
+ // Arrays of arrays are not available in ES2.0.
+ ASSERT(asSymbol != nullptr);
+ const TVariable *samplerCubeVar = &asSymbol->variable();
+
+ ASSERT(mSamplerMap.find(samplerCubeVar) != mSamplerMap.end());
+ const TVariable *mappedSamplerVar = mSamplerMap.at(samplerCubeVar);
+
+ TIntermTyped *mappedExpression = new TIntermSymbol(mappedSamplerVar);
+ if (asBinary)
+ {
+ mappedExpression =
+ new TIntermBinary(asBinary->getOp(), mappedExpression, asBinary->getRight());
+ }
+
+ return mappedExpression;
+ }
+
+ bool convertBuiltinFunction(TIntermAggregate *node)
+ {
+ const TFunction *function = node->getFunction();
+ if (!function->name().beginsWith("textureCube"))
+ {
+ return false;
+ }
+
+ // All textureCube* functions are in the form:
+ //
+ // textureCube??(samplerCube, vec3, ??)
+ //
+ // They should be converted to:
+ //
+ // texture??(sampler2DArray, convertCoords(vec3), ??)
+ //
+ // We assume the target platform supports texture() functions (currently only used in
+ // Vulkan).
+ //
+ // The intrinsics map as follows:
+ //
+ // textureCube -> textureGrad
+ // textureCubeLod -> textureLod
+ // textureCubeLodEXT -> textureLod
+ // textureCubeGrad -> textureGrad
+ // textureCubeGradEXT -> textureGrad
+ //
+ // Note that dPdx and dPdy in textureCubeGrad* are vec3, while the textureGrad equivalent
+ // for sampler2DArray is vec2. The EXT_shader_texture_lod that introduces thid function
+ // says:
+ //
+ // > For the "Grad" functions, dPdx is the explicit derivative of P with respect
+ // > to window x, and similarly dPdy with respect to window y. ... For a cube map texture,
+ // > dPdx and dPdy are vec3.
+ // >
+ // > Let
+ // >
+ // > dSdx = dPdx.s;
+ // > dSdy = dPdy.s;
+ // > dTdx = dPdx.t;
+ // > dTdy = dPdy.t;
+ // >
+ // > and
+ // >
+ // > / 0.0; for two-dimensional texture
+ // > dRdx = (
+ // > \ dPdx.p; for cube map texture
+ // >
+ // > / 0.0; for two-dimensional texture
+ // > dRdy = (
+ // > \ dPdy.p; for cube map texture
+ // >
+ // > (See equation 3.12a in The OpenGL ES 2.0 Specification.)
+ //
+ // It's unclear to me what dRdx and dRdy are. EXT_gpu_shader4 that promotes this function
+ // has the following additional information:
+ //
+ // > For the "Cube" versions, the partial
+ // > derivatives ddx and ddy are assumed to be in the coordinate system used
+ // > before texture coordinates are projected onto the appropriate cube
+ // > face. The partial derivatives of the post-projection texture coordinates,
+ // > which are used for level-of-detail and anisotropic filtering
+ // > calculations, are derived from coord, ddx and ddy in an
+ // > implementation-dependent manner.
+ //
+ // The calculation of dPdx and dPdy is declared as implementation-dependent, so we have
+ // freedom to calculate it as fit, even if not precisely the same as hardware might.
+
+ const char *substituteFunctionName = "textureGrad";
+ bool isGrad = false;
+ bool isTranslatedGrad = true;
+ bool hasBias = false;
+ if (function->name().beginsWith("textureCubeLod"))
+ {
+ substituteFunctionName = "textureLod";
+ isTranslatedGrad = false;
+ }
+ else if (function->name().beginsWith("textureCubeGrad"))
+ {
+ isGrad = true;
+ }
+ else if (!mIsFragmentShader)
+ {
+ substituteFunctionName = "texture";
+ isTranslatedGrad = false;
+ }
+
+ TIntermSequence *arguments = node->getSequence();
+ ASSERT(arguments->size() >= 2);
+
+ const TType *vec2Type = StaticType::GetBasic<EbtFloat, EbpHigh, 2>();
+ const TType *vec3Type = StaticType::GetBasic<EbtFloat, EbpHigh, 3>();
+ TIntermSymbol *uvl = new TIntermSymbol(CreateTempVariable(mSymbolTable, vec3Type));
+ TIntermSymbol *dUVdx = new TIntermSymbol(CreateTempVariable(mSymbolTable, vec2Type));
+ TIntermSymbol *dUVdy = new TIntermSymbol(CreateTempVariable(mSymbolTable, vec2Type));
+
+ TIntermTyped *dPdx = nullptr;
+ TIntermTyped *dPdy = nullptr;
+ if (isGrad)
+ {
+ ASSERT(arguments->size() == 4);
+ dPdx = (*arguments)[2]->getAsTyped()->deepCopy();
+ dPdy = (*arguments)[3]->getAsTyped()->deepCopy();
+ }
+ else if (isTranslatedGrad && mIsFragmentShader && arguments->size() == 3)
+ {
+ hasBias = true;
+ }
+ else
+ {
+ dPdx = CreateZeroNode(*vec3Type);
+ dPdy = CreateZeroNode(*vec3Type);
+ }
+
+ if (isTranslatedGrad && !mIsFragmentShader)
+ {
+ substituteFunctionName = "texture";
+ isTranslatedGrad = false;
+ }
+
+ // The function call to transform the coordinates, dPdx and dPdy. If not textureCubeGrad,
+ // the driver compiler will optimize out the unnecessary calculations.
+ TIntermSequence coordTransform;
+ coordTransform.push_back(CreateTempDeclarationNode(&dUVdx->variable()));
+ coordTransform.push_back(CreateTempDeclarationNode(&dUVdy->variable()));
+ TIntermTyped *coordTransformCall;
+ if (isGrad || !isTranslatedGrad)
+ {
+ coordTransformCall = createCoordTransformationCall(
+ (*arguments)[1]->getAsTyped()->deepCopy(), dPdx, dPdy, dUVdx, dUVdy);
+ }
+ else
+ {
+ coordTransformCall = createImplicitCoordTransformationCall(
+ (*arguments)[1]->getAsTyped()->deepCopy(), dUVdx, dUVdy);
+ }
+ coordTransform.push_back(
+ CreateTempInitDeclarationNode(&uvl->variable(), coordTransformCall));
+
+ TIntermTyped *dUVdxArg = dUVdx;
+ TIntermTyped *dUVdyArg = dUVdy;
+ if (hasBias)
+ {
+ const TType *floatType = StaticType::GetBasic<EbtFloat, EbpHigh>();
+ TIntermTyped *bias = (*arguments)[2]->getAsTyped()->deepCopy();
+ TIntermSequence exp2Args = {bias};
+ TIntermTyped *exp2Call =
+ CreateBuiltInFunctionCallNode("exp2", &exp2Args, *mSymbolTable, 100);
+ TIntermSymbol *biasFac = new TIntermSymbol(CreateTempVariable(mSymbolTable, floatType));
+ coordTransform.push_back(CreateTempInitDeclarationNode(&biasFac->variable(), exp2Call));
+ dUVdxArg =
+ new TIntermBinary(EOpVectorTimesScalar, biasFac->deepCopy(), dUVdx->deepCopy());
+ dUVdyArg =
+ new TIntermBinary(EOpVectorTimesScalar, biasFac->deepCopy(), dUVdy->deepCopy());
+ }
+
+ insertStatementsInParentBlock(coordTransform);
+
+ TIntermSequence substituteArguments;
+ // Replace the first argument (samplerCube) with the sampler2DArray.
+ substituteArguments.push_back(getMappedSamplerExpression((*arguments)[0]));
+ // Replace the second argument with the coordination transformation.
+ substituteArguments.push_back(uvl->deepCopy());
+ if (isTranslatedGrad)
+ {
+ substituteArguments.push_back(dUVdxArg->deepCopy());
+ substituteArguments.push_back(dUVdyArg->deepCopy());
+ }
+ else
+ {
+ // Pass the rest of the parameters as is.
+ for (size_t argIndex = 2; argIndex < arguments->size(); ++argIndex)
+ {
+ substituteArguments.push_back((*arguments)[argIndex]->getAsTyped()->deepCopy());
+ }
+ }
+
+ TIntermTyped *substituteCall = CreateBuiltInFunctionCallNode(
+ substituteFunctionName, &substituteArguments, *mSymbolTable, 300);
+
+ queueReplacement(substituteCall, OriginalNode::IS_DROPPED);
+
+ return true;
+ }
+
+ // A map from the samplerCube variable to the sampler2DArray one.
+ angle::HashMap<const TVariable *, const TVariable *> mSamplerMap;
+
+ // A helper function to convert xyz coordinates passed to a cube map sampling function into the
+ // array layer (cube map face) and uv coordinates.
+ TFunction *mCubeXYZToArrayUVL;
+ // A specialized version of the same function which uses implicit derivatives.
+ TFunction *mCubeXYZToArrayUVLImplicit;
+
+ bool mIsFragmentShader;
+
+ // Stored to be put before the first function after the pass.
+ TIntermFunctionDefinition *mCoordTranslationFunctionDecl;
+ TIntermFunctionDefinition *mCoordTranslationFunctionImplicitDecl;
+};
+} // anonymous namespace
+
+bool RewriteCubeMapSamplersAs2DArray(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ bool isFragmentShader)
+{
+ RewriteCubeMapSamplersAs2DArrayTraverser traverser(symbolTable, isFragmentShader);
+ root->traverse(&traverser);
+
+ TIntermFunctionDefinition *coordTranslationFunctionDecl =
+ traverser.getCoordTranslationFunctionDecl();
+ TIntermFunctionDefinition *coordTranslationFunctionDeclImplicit =
+ traverser.getCoordTranslationFunctionDeclImplicit();
+ size_t firstFunctionIndex = FindFirstFunctionDefinitionIndex(root);
+ if (coordTranslationFunctionDecl)
+ {
+ root->insertChildNodes(firstFunctionIndex, TIntermSequence({coordTranslationFunctionDecl}));
+ }
+ if (coordTranslationFunctionDeclImplicit)
+ {
+ root->insertChildNodes(firstFunctionIndex,
+ TIntermSequence({coordTranslationFunctionDeclImplicit}));
+ }
+
+ return traverser.updateTree(compiler, root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteCubeMapSamplersAs2DArray.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteCubeMapSamplersAs2DArray.h
new file mode 100644
index 0000000000..515c1de103
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteCubeMapSamplersAs2DArray.h
@@ -0,0 +1,29 @@
+//
+// Copyright 2019 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.
+//
+// RewriteCubeMapSamplersAs2DArray: Change samplerCube samplers to sampler2DArray, and the
+// textureCube* function calls to calls to helper functions that select the cube map face and sample
+// from the face as a 2D texture. This emulates seamful cube map sampling in ES2 (or desktop GL 2)
+// and therefore only looks at samplerCube (i.e. not integer variants or cube arrays) and sampling
+// functions that are defined in ES GLSL 1.0 (i.e. not the cube overload of texture()).
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_REWRITECUBEMAPSAMPLERSAS2DARRAY_H_
+#define COMPILER_TRANSLATOR_TREEOPS_REWRITECUBEMAPSAMPLERSAS2DARRAY_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+[[nodiscard]] bool RewriteCubeMapSamplersAs2DArray(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ bool isFragmentShader);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_REWRITECUBEMAPSAMPLERSAS2DARRAY_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteDfdy.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteDfdy.cpp
new file mode 100644
index 0000000000..1a2aabf7dc
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteDfdy.cpp
@@ -0,0 +1,141 @@
+//
+// Copyright 2019 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 dFdy viewport transformation.
+// See header for more info.
+
+#include "compiler/translator/tree_ops/RewriteDfdy.h"
+
+#include "common/angleutils.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/TranslatorVulkan.h"
+#include "compiler/translator/tree_util/DriverUniform.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/tree_util/SpecializationConstant.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class Traverser : public TIntermTraverser
+{
+ public:
+ Traverser(TSymbolTable *symbolTable, SpecConst *specConst, const DriverUniform *driverUniforms);
+
+ private:
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override;
+
+ SpecConst *mSpecConst = nullptr;
+ const DriverUniform *mDriverUniforms = nullptr;
+};
+
+Traverser::Traverser(TSymbolTable *symbolTable,
+ SpecConst *specConst,
+ const DriverUniform *driverUniforms)
+ : TIntermTraverser(true, false, false, symbolTable),
+ mSpecConst(specConst),
+ mDriverUniforms(driverUniforms)
+{}
+
+bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node)
+{
+ // Decide if the node represents a call to dFdx() or dFdy()
+ if (node->getOp() != EOpDFdx && node->getOp() != EOpDFdy)
+ {
+ return true;
+ }
+
+ const bool isDFdx = node->getOp() == EOpDFdx;
+
+ // Two transformations are done on dFdx and dFdy:
+ //
+ // - If pre-rotation is applied, dFdx and dFdy may need to swap their axis based on the degree
+ // of rotation. dFdx becomes dFdy if rotation is 90 or 270 degrees. Similarly, dFdy becomes
+ // dFdx.
+ // - The result is potentially negated. This could be due to viewport y-flip or pre-rotation.
+ //
+ // Accordingly, there are two variables controlling the above transformations:
+ //
+ // - Rotation: A vec2 that is either (0, 1) or (1, 0). dFdx and dFdy are replaced with:
+ //
+ // dFdx * Rotation.x + dFdy * Rotation.y
+ //
+ // - Scale: A vec2 with -1 or 1 for either x or y components. The previous result is multiplied
+ // by this.
+ //
+ // Together, the above operations account for the combinations of 4 possible rotations and
+ // y-flip.
+
+ // Get the results of dFdx(operand) and dFdy(operand), and multiply them by the swizzles
+ TIntermTyped *operand = node->getChildNode(0)->getAsTyped();
+
+ TIntermTyped *dFdx = CreateBuiltInUnaryFunctionCallNode("dFdx", operand, *mSymbolTable, 300);
+ TIntermTyped *dFdy =
+ CreateBuiltInUnaryFunctionCallNode("dFdy", operand->deepCopy(), *mSymbolTable, 300);
+
+ // Get rotation multiplier
+ TIntermTyped *swapXY = mSpecConst->getSwapXY();
+ if (swapXY == nullptr)
+ {
+ swapXY = mDriverUniforms->getSwapXY();
+ }
+
+ TIntermTyped *swapXMultiplier = MakeSwapXMultiplier(swapXY);
+ TIntermTyped *swapYMultiplier = MakeSwapYMultiplier(swapXY->deepCopy());
+
+ // Get flip multiplier
+ TIntermTyped *flipXY = mDriverUniforms->getFlipXY(mSymbolTable, DriverUniformFlip::Fragment);
+
+ // Multiply the flip and rotation multipliers
+ TIntermTyped *xMultiplier =
+ new TIntermBinary(EOpMul, isDFdx ? swapXMultiplier : swapYMultiplier,
+ (new TIntermSwizzle(flipXY->deepCopy(), {0}))->fold(nullptr));
+ TIntermTyped *yMultiplier =
+ new TIntermBinary(EOpMul, isDFdx ? swapYMultiplier : swapXMultiplier,
+ (new TIntermSwizzle(flipXY->deepCopy(), {1}))->fold(nullptr));
+
+ const TOperator mulOp = dFdx->getType().isVector() ? EOpVectorTimesScalar : EOpMul;
+ TIntermTyped *rotatedFlippedDfdx = new TIntermBinary(mulOp, dFdx, xMultiplier);
+ TIntermTyped *rotatedFlippedDfdy = new TIntermBinary(mulOp, dFdy, yMultiplier);
+
+ // Sum them together into the result
+ TIntermBinary *rotatedFlippedResult =
+ new TIntermBinary(EOpAdd, rotatedFlippedDfdx, rotatedFlippedDfdy);
+
+ // Replace the old dFdx() or dFdy() node with the new node that contains the corrected value
+ //
+ // Note the following bugs (anglebug.com/7346):
+ //
+ // - Side effects of operand are duplicated with the above
+ // - If the direct child of this node is itself dFdx/y, its queueReplacement will not be
+ // effective as the parent is also replaced.
+ queueReplacement(rotatedFlippedResult, OriginalNode::IS_DROPPED);
+
+ return true;
+}
+} // anonymous namespace
+
+bool RewriteDfdy(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ int shaderVersion,
+ SpecConst *specConst,
+ const DriverUniform *driverUniforms)
+{
+ // dFdx/dFdy is only valid in GLSL 3.0 and later.
+ if (shaderVersion < 300)
+ {
+ return true;
+ }
+
+ Traverser traverser(symbolTable, specConst, driverUniforms);
+ root->traverse(&traverser);
+ return traverser.updateTree(compiler, root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteDfdy.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteDfdy.h
new file mode 100644
index 0000000000..d1a6399696
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteDfdy.h
@@ -0,0 +1,32 @@
+//
+// Copyright 2019 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.
+//
+// RewriteDfdy: Transform dFdx and dFdy according to pre-rotation and viewport y-flip.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_REWRITEDFDY_H_
+#define COMPILER_TRANSLATOR_TREEOPS_REWRITEDFDY_H_
+
+#include "common/angleutils.h"
+#include "compiler/translator/Compiler.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+class SpecConst;
+class DriverUniform;
+
+[[nodiscard]] bool RewriteDfdy(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ int shaderVersion,
+ SpecConst *specConst,
+ const DriverUniform *driverUniforms);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_REWRITEDFDY_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RewritePixelLocalStorage.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewritePixelLocalStorage.cpp
new file mode 100644
index 0000000000..1c86cafe03
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewritePixelLocalStorage.cpp
@@ -0,0 +1,861 @@
+//
+// Copyright 2022 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/tree_ops/RewritePixelLocalStorage.h"
+
+#include "common/angleutils.h"
+#include "compiler/translator/StaticType.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_ops/MonomorphizeUnsupportedFunctions.h"
+#include "compiler/translator/tree_util/BuiltIn.h"
+#include "compiler/translator/tree_util/FindMain.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+namespace
+{
+constexpr static TBasicType DataTypeOfPLSType(TBasicType plsType)
+{
+ switch (plsType)
+ {
+ case EbtPixelLocalANGLE:
+ return EbtFloat;
+ case EbtIPixelLocalANGLE:
+ return EbtInt;
+ case EbtUPixelLocalANGLE:
+ return EbtUInt;
+ default:
+ UNREACHABLE();
+ return EbtVoid;
+ }
+}
+
+constexpr static TBasicType DataTypeOfImageType(TBasicType imageType)
+{
+ switch (imageType)
+ {
+ case EbtImage2D:
+ return EbtFloat;
+ case EbtIImage2D:
+ return EbtInt;
+ case EbtUImage2D:
+ return EbtUInt;
+ default:
+ UNREACHABLE();
+ return EbtVoid;
+ }
+}
+
+// Maps PLS symbols to a backing store.
+template <typename T>
+class PLSBackingStoreMap
+{
+ public:
+ // Sets the given variable as the backing storage for the plsSymbol's binding point. An entry
+ // must not already exist in the map for this binding point.
+ void insertNew(TIntermSymbol *plsSymbol, const T &backingStore)
+ {
+ ASSERT(plsSymbol);
+ ASSERT(IsPixelLocal(plsSymbol->getBasicType()));
+ int binding = plsSymbol->getType().getLayoutQualifier().binding;
+ ASSERT(binding >= 0);
+ auto result = mMap.insert({binding, backingStore});
+ ASSERT(result.second); // Ensure an image didn't already exist for this symbol.
+ }
+
+ // Looks up the backing store for the given plsSymbol's binding point. An entry must already
+ // exist in the map for this binding point.
+ const T &find(TIntermSymbol *plsSymbol)
+ {
+ ASSERT(plsSymbol);
+ ASSERT(IsPixelLocal(plsSymbol->getBasicType()));
+ int binding = plsSymbol->getType().getLayoutQualifier().binding;
+ ASSERT(binding >= 0);
+ auto iter = mMap.find(binding);
+ ASSERT(iter != mMap.end()); // Ensure PLSImages already exist for this symbol.
+ return iter->second;
+ }
+
+ const std::map<int, T> &bindingOrderedMap() const { return mMap; }
+
+ private:
+ // Use std::map so the backing stores are ordered by binding when we iterate.
+ std::map<int, T> mMap;
+};
+
+// Base class for rewriting high level PLS operations to AST operations specified by
+// ShPixelLocalStorageType.
+class RewritePLSTraverser : public TIntermTraverser
+{
+ public:
+ RewritePLSTraverser(TCompiler *compiler,
+ TSymbolTable &symbolTable,
+ const ShCompileOptions &compileOptions,
+ int shaderVersion)
+ : TIntermTraverser(true, false, false, &symbolTable),
+ mCompiler(compiler),
+ mCompileOptions(&compileOptions),
+ mShaderVersion(shaderVersion)
+ {}
+
+ bool visitDeclaration(Visit, TIntermDeclaration *decl) override
+ {
+ TIntermTyped *declVariable = (decl->getSequence())->front()->getAsTyped();
+ ASSERT(declVariable);
+
+ if (!IsPixelLocal(declVariable->getBasicType()))
+ {
+ return true;
+ }
+
+ // PLS is not allowed in arrays.
+ ASSERT(!declVariable->isArray());
+
+ // This visitDeclaration doesn't get called for function arguments, and opaque types can
+ // otherwise only be uniforms.
+ ASSERT(declVariable->getQualifier() == EvqUniform);
+
+ TIntermSymbol *plsSymbol = declVariable->getAsSymbolNode();
+ ASSERT(plsSymbol);
+
+ visitPLSDeclaration(plsSymbol);
+
+ return false;
+ }
+
+ bool visitAggregate(Visit, TIntermAggregate *aggregate) override
+ {
+ if (!BuiltInGroup::IsPixelLocal(aggregate->getOp()))
+ {
+ return true;
+ }
+
+ const TIntermSequence &args = *aggregate->getSequence();
+ ASSERT(args.size() >= 1);
+ TIntermSymbol *plsSymbol = args[0]->getAsSymbolNode();
+
+ // Rewrite pixelLocalLoadANGLE -> imageLoad.
+ if (aggregate->getOp() == EOpPixelLocalLoadANGLE)
+ {
+ visitPLSLoad(plsSymbol);
+ return false; // No need to recurse since this node is being dropped.
+ }
+
+ // Rewrite pixelLocalStoreANGLE -> imageStore.
+ if (aggregate->getOp() == EOpPixelLocalStoreANGLE)
+ {
+ // Also hoist the 'value' expression into a temp. In the event of
+ // "pixelLocalStoreANGLE(..., pixelLocalLoadANGLE(...))", this ensures the load occurs
+ // _before_ any potential barriers required by the subclass.
+ //
+ // NOTE: It is generally unsafe to hoist function arguments due to short circuiting,
+ // e.g., "if (false && function(...))", but pixelLocalStoreANGLE returns type void, so
+ // it is safe in this particular case.
+ TType *valueType = new TType(DataTypeOfPLSType(plsSymbol->getBasicType()),
+ plsSymbol->getPrecision(), EvqTemporary, 4);
+ TVariable *valueVar = CreateTempVariable(mSymbolTable, valueType);
+ TIntermDeclaration *valueDecl =
+ CreateTempInitDeclarationNode(valueVar, args[1]->getAsTyped());
+ valueDecl->traverse(this); // Rewrite any potential pixelLocalLoadANGLEs in valueDecl.
+ insertStatementInParentBlock(valueDecl);
+
+ visitPLSStore(plsSymbol, valueVar);
+ return false; // No need to recurse since this node is being dropped.
+ }
+
+ return true;
+ }
+
+ // Called after rewrite. Injects one-time setup code that needs to run before any PLS accesses.
+ virtual void injectSetupCode(TCompiler *,
+ TSymbolTable &,
+ const ShCompileOptions &,
+ TIntermBlock *mainBody,
+ size_t plsBeginPosition)
+ {}
+
+ // Called after rewrite. Injects one-time finalization code that needs to run after all PLS.
+ virtual void injectFinalizeCode(TCompiler *,
+ TSymbolTable &,
+ const ShCompileOptions &,
+ TIntermBlock *mainBody,
+ size_t plsEndPosition)
+ {}
+
+ TVariable *globalPixelCoord() const { return mGlobalPixelCoord; }
+
+ protected:
+ virtual void visitPLSDeclaration(TIntermSymbol *plsSymbol) = 0;
+ virtual void visitPLSLoad(TIntermSymbol *plsSymbol) = 0;
+ virtual void visitPLSStore(TIntermSymbol *plsSymbol, TVariable *value) = 0;
+
+ void ensureGlobalPixelCoordDeclared()
+ {
+ // Insert a global to hold the pixel coordinate as soon as we see PLS declared. This will be
+ // initialized at the beginning of main().
+ if (!mGlobalPixelCoord)
+ {
+ TType *coordType = new TType(EbtInt, EbpHigh, EvqGlobal, 2);
+ mGlobalPixelCoord = CreateTempVariable(mSymbolTable, coordType);
+ insertStatementInParentBlock(CreateTempDeclarationNode(mGlobalPixelCoord));
+ }
+ }
+
+ const TCompiler *const mCompiler;
+ const ShCompileOptions *const mCompileOptions;
+ const int mShaderVersion;
+
+ // Stores the shader invocation's pixel coordinate as "ivec2(floor(gl_FragCoord.xy))".
+ TVariable *mGlobalPixelCoord = nullptr;
+};
+
+// Rewrites high level PLS operations to shader image operations.
+class RewritePLSToImagesTraverser : public RewritePLSTraverser
+{
+ public:
+ RewritePLSToImagesTraverser(TCompiler *compiler,
+ TSymbolTable &symbolTable,
+ const ShCompileOptions &compileOptions,
+ int shaderVersion)
+ : RewritePLSTraverser(compiler, symbolTable, compileOptions, shaderVersion)
+ {}
+
+ private:
+ void visitPLSDeclaration(TIntermSymbol *plsSymbol) override
+ {
+ // Replace the PLS declaration with an image2D.
+ ensureGlobalPixelCoordDeclared();
+ TVariable *image2D = createPLSImageReplacement(plsSymbol);
+ mImages.insertNew(plsSymbol, image2D);
+ queueReplacement(new TIntermDeclaration({new TIntermSymbol(image2D)}),
+ OriginalNode::IS_DROPPED);
+ }
+
+ // Do all PLS formats need to be packed into r32f, r32i, or r32ui image2Ds?
+ bool needsR32Packing() const
+ {
+ return mCompileOptions->pls.type == ShPixelLocalStorageType::ImageStoreR32PackedFormats;
+ }
+
+ // Creates an image2D that replaces a pixel local storage handle.
+ TVariable *createPLSImageReplacement(const TIntermSymbol *plsSymbol)
+ {
+ ASSERT(plsSymbol);
+ ASSERT(IsPixelLocal(plsSymbol->getBasicType()));
+
+ TType *imageType = new TType(plsSymbol->getType());
+
+ TLayoutQualifier layoutQualifier = imageType->getLayoutQualifier();
+ switch (layoutQualifier.imageInternalFormat)
+ {
+ case TLayoutImageInternalFormat::EiifRGBA8:
+ if (needsR32Packing())
+ {
+ layoutQualifier.imageInternalFormat = EiifR32UI;
+ imageType->setPrecision(EbpHigh);
+ imageType->setBasicType(EbtUImage2D);
+ }
+ else
+ {
+ imageType->setBasicType(EbtImage2D);
+ }
+ break;
+ case TLayoutImageInternalFormat::EiifRGBA8I:
+ if (needsR32Packing())
+ {
+ layoutQualifier.imageInternalFormat = EiifR32I;
+ imageType->setPrecision(EbpHigh);
+ }
+ imageType->setBasicType(EbtIImage2D);
+ break;
+ case TLayoutImageInternalFormat::EiifRGBA8UI:
+ if (needsR32Packing())
+ {
+ layoutQualifier.imageInternalFormat = EiifR32UI;
+ imageType->setPrecision(EbpHigh);
+ }
+ imageType->setBasicType(EbtUImage2D);
+ break;
+ case TLayoutImageInternalFormat::EiifR32F:
+ imageType->setBasicType(EbtImage2D);
+ break;
+ case TLayoutImageInternalFormat::EiifR32UI:
+ imageType->setBasicType(EbtUImage2D);
+ break;
+ default:
+ UNREACHABLE();
+ }
+ layoutQualifier.rasterOrdered = mCompileOptions->pls.fragmentSynchronizationType ==
+ ShFragmentSynchronizationType::RasterizerOrderViews_D3D;
+ imageType->setLayoutQualifier(layoutQualifier);
+
+ TMemoryQualifier memoryQualifier{};
+ memoryQualifier.coherent = true;
+ memoryQualifier.restrictQualifier = true;
+ memoryQualifier.volatileQualifier = false;
+ // TODO(anglebug.com/7279): Maybe we could walk the tree first and see which PLS is used
+ // how. If the PLS is never loaded, we could add a writeonly qualifier, for example.
+ memoryQualifier.readonly = false;
+ memoryQualifier.writeonly = false;
+ imageType->setMemoryQualifier(memoryQualifier);
+
+ const TVariable &plsVar = plsSymbol->variable();
+ return new TVariable(plsVar.uniqueId(), plsVar.name(), plsVar.symbolType(),
+ plsVar.extensions(), imageType);
+ }
+
+ void visitPLSLoad(TIntermSymbol *plsSymbol) override
+ {
+ // Replace the pixelLocalLoadANGLE with imageLoad.
+ TVariable *image2D = mImages.find(plsSymbol);
+ ASSERT(mGlobalPixelCoord);
+ TIntermTyped *pls = CreateBuiltInFunctionCallNode(
+ "imageLoad", {new TIntermSymbol(image2D), new TIntermSymbol(mGlobalPixelCoord)},
+ *mSymbolTable, 310);
+ pls = unpackImageDataIfNecessary(pls, plsSymbol, image2D);
+ queueReplacement(pls, OriginalNode::IS_DROPPED);
+ }
+
+ // Unpacks the raw PLS data if the output shader language needs r32* packing.
+ TIntermTyped *unpackImageDataIfNecessary(TIntermTyped *data,
+ TIntermSymbol *plsSymbol,
+ TVariable *image2D)
+ {
+ TLayoutImageInternalFormat plsFormat =
+ plsSymbol->getType().getLayoutQualifier().imageInternalFormat;
+ TLayoutImageInternalFormat imageFormat =
+ image2D->getType().getLayoutQualifier().imageInternalFormat;
+ if (plsFormat == imageFormat)
+ {
+ return data; // This PLS storage isn't packed.
+ }
+ ASSERT(needsR32Packing());
+ switch (plsFormat)
+ {
+ case EiifRGBA8:
+ // Unpack and normalize r,g,b,a from a single 32-bit unsigned int:
+ //
+ // unpackUnorm4x8(data.r)
+ //
+ data = CreateBuiltInFunctionCallNode("unpackUnorm4x8", {CreateSwizzle(data, 0)},
+ *mSymbolTable, 310);
+ break;
+ case EiifRGBA8I:
+ case EiifRGBA8UI:
+ {
+ constexpr unsigned shifts[] = {24, 16, 8, 0};
+ // Unpack r,g,b,a form a single (signed or unsigned) 32-bit int. Shift left,
+ // then right, to preserve the sign for ints. (highp integers are exactly
+ // 32-bit, two's compliment.)
+ //
+ // data.rrrr << uvec4(24, 16, 8, 0) >> 24u
+ //
+ data = CreateSwizzle(data, 0, 0, 0, 0);
+ data = new TIntermBinary(EOpBitShiftLeft, data, CreateUVecNode(shifts, 4, EbpHigh));
+ data = new TIntermBinary(EOpBitShiftRight, data, CreateUIntNode(24));
+ break;
+ }
+ default:
+ UNREACHABLE();
+ }
+ return data;
+ }
+
+ void visitPLSStore(TIntermSymbol *plsSymbol, TVariable *value) override
+ {
+ TVariable *image2D = mImages.find(plsSymbol);
+ TIntermTyped *packedData = clampAndPackPLSDataIfNecessary(value, plsSymbol, image2D);
+
+ // Surround the store with memoryBarrierImage calls in order to ensure dependent stores and
+ // loads in a single shader invocation are coherent. From the ES 3.1 spec:
+ //
+ // Using variables declared as "coherent" guarantees only that the results of stores will
+ // be immediately visible to shader invocations using similarly-declared variables;
+ // calling MemoryBarrier is required to ensure that the stores are visible to other
+ // operations.
+ //
+ insertStatementsInParentBlock(
+ {CreateBuiltInFunctionCallNode("memoryBarrierImage", {}, *mSymbolTable,
+ 310)}, // Before.
+ {CreateBuiltInFunctionCallNode("memoryBarrierImage", {}, *mSymbolTable,
+ 310)}); // After.
+
+ // Rewrite the pixelLocalStoreANGLE with imageStore.
+ ASSERT(mGlobalPixelCoord);
+ queueReplacement(
+ CreateBuiltInFunctionCallNode(
+ "imageStore",
+ {new TIntermSymbol(image2D), new TIntermSymbol(mGlobalPixelCoord), packedData},
+ *mSymbolTable, 310),
+ OriginalNode::IS_DROPPED);
+ }
+
+ // Packs the PLS to raw data if the output shader language needs r32* packing.
+ TIntermTyped *clampAndPackPLSDataIfNecessary(TVariable *plsVar,
+ TIntermSymbol *plsSymbol,
+ TVariable *image2D)
+ {
+ TLayoutImageInternalFormat plsFormat =
+ plsSymbol->getType().getLayoutQualifier().imageInternalFormat;
+ // anglebug.com/7524: Storing to integer formats with values larger than can be represented
+ // is specified differently on different APIs. Clamp integer formats here to make it uniform
+ // and more GL-like.
+ switch (plsFormat)
+ {
+ case EiifRGBA8I:
+ {
+ // Clamp r,g,b,a to their min/max 8-bit values:
+ //
+ // plsVar = clamp(plsVar, -128, 127) & 0xff
+ //
+ TIntermTyped *newPLSValue = CreateBuiltInFunctionCallNode(
+ "clamp",
+ {new TIntermSymbol(plsVar), CreateIndexNode(-128), CreateIndexNode(127)},
+ *mSymbolTable, mShaderVersion);
+ insertStatementInParentBlock(CreateTempAssignmentNode(plsVar, newPLSValue));
+ break;
+ }
+ case EiifRGBA8UI:
+ {
+ // Clamp r,g,b,a to their max 8-bit values:
+ //
+ // plsVar = min(plsVar, 255)
+ //
+ TIntermTyped *newPLSValue = CreateBuiltInFunctionCallNode(
+ "min", {new TIntermSymbol(plsVar), CreateUIntNode(255)}, *mSymbolTable,
+ mShaderVersion);
+ insertStatementInParentBlock(CreateTempAssignmentNode(plsVar, newPLSValue));
+ break;
+ }
+ default:
+ break;
+ }
+ TIntermTyped *result = new TIntermSymbol(plsVar);
+ TLayoutImageInternalFormat imageFormat =
+ image2D->getType().getLayoutQualifier().imageInternalFormat;
+ if (plsFormat == imageFormat)
+ {
+ return result; // This PLS storage isn't packed.
+ }
+ ASSERT(needsR32Packing());
+ switch (plsFormat)
+ {
+ case EiifRGBA8:
+ {
+ if (mCompileOptions->passHighpToPackUnormSnormBuiltins)
+ {
+ // anglebug.com/7527: unpackUnorm4x8 doesn't work on Pixel 4 when passed
+ // a mediump vec4. Use an intermediate highp vec4.
+ //
+ // It's safe to inject a variable here because it happens right before
+ // pixelLocalStoreANGLE, which returns type void. (See visitAggregate.)
+ TType *highpType = new TType(EbtFloat, EbpHigh, EvqTemporary, 4);
+ TVariable *workaroundHighpVar = CreateTempVariable(mSymbolTable, highpType);
+ insertStatementInParentBlock(
+ CreateTempInitDeclarationNode(workaroundHighpVar, result));
+ result = new TIntermSymbol(workaroundHighpVar);
+ }
+
+ // Denormalize and pack r,g,b,a into a single 32-bit unsigned int:
+ //
+ // packUnorm4x8(workaroundHighpVar)
+ //
+ result =
+ CreateBuiltInFunctionCallNode("packUnorm4x8", {result}, *mSymbolTable, 310);
+ break;
+ }
+ case EiifRGBA8I:
+ case EiifRGBA8UI:
+ {
+ if (plsFormat == EiifRGBA8I)
+ {
+ // Mask off extra sign bits beyond 8.
+ //
+ // plsVar &= 0xff
+ //
+ insertStatementInParentBlock(new TIntermBinary(
+ EOpBitwiseAndAssign, new TIntermSymbol(plsVar), CreateIndexNode(0xff)));
+ }
+ // Pack r,g,b,a into a single 32-bit (signed or unsigned) int:
+ //
+ // r | (g << 8) | (b << 16) | (a << 24)
+ //
+ auto shiftComponent = [=](int componentIdx) {
+ return new TIntermBinary(EOpBitShiftLeft,
+ CreateSwizzle(new TIntermSymbol(plsVar), componentIdx),
+ CreateUIntNode(componentIdx * 8));
+ };
+ result = CreateSwizzle(result, 0);
+ result = new TIntermBinary(EOpBitwiseOr, result, shiftComponent(1));
+ result = new TIntermBinary(EOpBitwiseOr, result, shiftComponent(2));
+ result = new TIntermBinary(EOpBitwiseOr, result, shiftComponent(3));
+ break;
+ }
+ default:
+ UNREACHABLE();
+ }
+ // Convert the packed data to a {u,i}vec4 for imageStore.
+ TType imageStoreType(DataTypeOfImageType(image2D->getType().getBasicType()), 4);
+ return TIntermAggregate::CreateConstructor(imageStoreType, {result});
+ }
+
+ void injectSetupCode(TCompiler *compiler,
+ TSymbolTable &symbolTable,
+ const ShCompileOptions &compileOptions,
+ TIntermBlock *mainBody,
+ size_t plsBeginPosition) override
+ {
+ // When PLS is implemented with images, early_fragment_tests ensure that depth/stencil
+ // can also block stores to PLS.
+ compiler->specifyEarlyFragmentTests();
+
+ // Delimit the beginning of a per-pixel critical section, if supported. This makes pixel
+ // local storage coherent.
+ //
+ // Either: GL_NV_fragment_shader_interlock
+ // GL_INTEL_fragment_shader_ordering
+ // GL_ARB_fragment_shader_interlock (may compile to
+ // SPV_EXT_fragment_shader_interlock)
+ switch (compileOptions.pls.fragmentSynchronizationType)
+ {
+ // ROVs don't need explicit synchronization calls.
+ case ShFragmentSynchronizationType::RasterizerOrderViews_D3D:
+ case ShFragmentSynchronizationType::NotSupported:
+ break;
+ case ShFragmentSynchronizationType::FragmentShaderInterlock_NV_GL:
+ mainBody->insertStatement(
+ plsBeginPosition,
+ CreateBuiltInFunctionCallNode("beginInvocationInterlockNV", {}, symbolTable,
+ kESSLInternalBackendBuiltIns));
+ break;
+ case ShFragmentSynchronizationType::FragmentShaderOrdering_INTEL_GL:
+ mainBody->insertStatement(
+ plsBeginPosition,
+ CreateBuiltInFunctionCallNode("beginFragmentShaderOrderingINTEL", {},
+ symbolTable, kESSLInternalBackendBuiltIns));
+ break;
+ case ShFragmentSynchronizationType::FragmentShaderInterlock_ARB_GL:
+ mainBody->insertStatement(
+ plsBeginPosition,
+ CreateBuiltInFunctionCallNode("beginInvocationInterlockARB", {}, symbolTable,
+ kESSLInternalBackendBuiltIns));
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ void injectFinalizeCode(TCompiler *,
+ TSymbolTable &symbolTable,
+ const ShCompileOptions &compileOptions,
+ TIntermBlock *mainBody,
+ size_t plsEndPosition) override
+ {
+ // Delimit the end of the PLS critical section, if required.
+ //
+ // Either: GL_NV_fragment_shader_interlock
+ // GL_ARB_fragment_shader_interlock (may compile to
+ // SPV_EXT_fragment_shader_interlock)
+ switch (compileOptions.pls.fragmentSynchronizationType)
+ {
+ // ROVs don't need explicit synchronization calls.
+ case ShFragmentSynchronizationType::RasterizerOrderViews_D3D:
+ // GL_INTEL_fragment_shader_ordering doesn't have an "end()" call.
+ case ShFragmentSynchronizationType::FragmentShaderOrdering_INTEL_GL:
+ case ShFragmentSynchronizationType::NotSupported:
+ break;
+ case ShFragmentSynchronizationType::FragmentShaderInterlock_NV_GL:
+
+ mainBody->insertStatement(
+ plsEndPosition,
+ CreateBuiltInFunctionCallNode("endInvocationInterlockNV", {}, symbolTable,
+ kESSLInternalBackendBuiltIns));
+ break;
+ case ShFragmentSynchronizationType::FragmentShaderInterlock_ARB_GL:
+ mainBody->insertStatement(
+ plsEndPosition,
+ CreateBuiltInFunctionCallNode("endInvocationInterlockARB", {}, symbolTable,
+ kESSLInternalBackendBuiltIns));
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ PLSBackingStoreMap<TVariable *> mImages;
+};
+
+// Rewrites high level PLS operations to framebuffer fetch operations.
+class RewritePLSToFramebufferFetchTraverser : public RewritePLSTraverser
+{
+ public:
+ RewritePLSToFramebufferFetchTraverser(TCompiler *compiler,
+ TSymbolTable &symbolTable,
+ const ShCompileOptions &compileOptions,
+ int shaderVersion)
+ : RewritePLSTraverser(compiler, symbolTable, compileOptions, shaderVersion)
+ {}
+
+ void visitPLSDeclaration(TIntermSymbol *plsSymbol) override
+ {
+ // Replace the PLS declaration with a framebuffer attachment.
+ PLSAttachment attachment(mCompiler, mSymbolTable, *mCompileOptions, plsSymbol->variable());
+ mPLSAttachments.insertNew(plsSymbol, attachment);
+ insertStatementInParentBlock(
+ new TIntermDeclaration({new TIntermSymbol(attachment.fragmentVar)}));
+ queueReplacement(CreateTempDeclarationNode(attachment.accessVar), OriginalNode::IS_DROPPED);
+ }
+
+ void visitPLSLoad(TIntermSymbol *plsSymbol) override
+ {
+ // Read our temporary accessVar.
+ const PLSAttachment &attachment = mPLSAttachments.find(plsSymbol);
+ queueReplacement(attachment.expandAccessVar(), OriginalNode::IS_DROPPED);
+ }
+
+ void visitPLSStore(TIntermSymbol *plsSymbol, TVariable *value) override
+ {
+ // Set our temporary accessVar.
+ const PLSAttachment &attachment = mPLSAttachments.find(plsSymbol);
+ queueReplacement(CreateTempAssignmentNode(attachment.accessVar, attachment.swizzle(value)),
+ OriginalNode::IS_DROPPED);
+ }
+
+ void injectSetupCode(TCompiler *compiler,
+ TSymbolTable &symbolTable,
+ const ShCompileOptions &compileOptions,
+ TIntermBlock *mainBody,
+ size_t plsBeginPosition) override
+ {
+ // [OpenGL ES Version 3.0.6, 3.9.2.3 "Shader Output"]: Any colors, or color components,
+ // associated with a fragment that are not written by the fragment shader are undefined.
+ //
+ // [EXT_shader_framebuffer_fetch]: Prior to fragment shading, fragment outputs declared
+ // inout are populated with the value last written to the framebuffer at the same(x, y,
+ // sample) position.
+ //
+ // It's unclear from the EXT_shader_framebuffer_fetch spec whether inout fragment variables
+ // become undefined if not explicitly written, but either way, when this compiles to subpass
+ // loads in Vulkan, we definitely get undefined behavior if PLS variables are not written.
+ //
+ // To make sure every PLS variable gets written, we read them all before PLS operations,
+ // then write them all back out after all PLS is complete.
+ std::vector<TIntermNode *> plsPreloads;
+ plsPreloads.reserve(mPLSAttachments.bindingOrderedMap().size());
+ for (const auto &entry : mPLSAttachments.bindingOrderedMap())
+ {
+ const PLSAttachment &attachment = entry.second;
+ plsPreloads.push_back(
+ CreateTempAssignmentNode(attachment.accessVar, attachment.swizzleFragmentVar()));
+ }
+ mainBody->getSequence()->insert(mainBody->getSequence()->begin() + plsBeginPosition,
+ plsPreloads.begin(), plsPreloads.end());
+ }
+
+ void injectFinalizeCode(TCompiler *,
+ TSymbolTable &symbolTable,
+ const ShCompileOptions &compileOptions,
+ TIntermBlock *mainBody,
+ size_t plsEndPosition) override
+ {
+ std::vector<TIntermNode *> plsWrites;
+ plsWrites.reserve(mPLSAttachments.bindingOrderedMap().size());
+ for (const auto &entry : mPLSAttachments.bindingOrderedMap())
+ {
+ const PLSAttachment &attachment = entry.second;
+ plsWrites.push_back(new TIntermBinary(EOpAssign, attachment.swizzleFragmentVar(),
+ new TIntermSymbol(attachment.accessVar)));
+ }
+ mainBody->getSequence()->insert(mainBody->getSequence()->begin() + plsEndPosition,
+ plsWrites.begin(), plsWrites.end());
+ }
+
+ private:
+ struct PLSAttachment
+ {
+ PLSAttachment(const TCompiler *compiler,
+ TSymbolTable *symbolTable,
+ const ShCompileOptions &compileOptions,
+ const TVariable &plsVar)
+ {
+ const TType &plsType = plsVar.getType();
+
+ TType *accessVarType;
+ switch (plsType.getLayoutQualifier().imageInternalFormat)
+ {
+ default:
+ UNREACHABLE();
+ [[fallthrough]];
+ case EiifRGBA8:
+ accessVarType = new TType(EbtFloat, 4);
+ break;
+ case EiifRGBA8I:
+ accessVarType = new TType(EbtInt, 4);
+ break;
+ case EiifRGBA8UI:
+ accessVarType = new TType(EbtUInt, 4);
+ break;
+ case EiifR32F:
+ accessVarType = new TType(EbtFloat, 1);
+ break;
+ case EiifR32UI:
+ accessVarType = new TType(EbtUInt, 1);
+ break;
+ }
+ accessVarType->setPrecision(plsType.getPrecision());
+ accessVar = CreateTempVariable(symbolTable, accessVarType);
+
+ // Qualcomm seems to want fragment outputs to be 4-component vectors, and produces a
+ // compile error from "inout uint". Our Metal translator also saturates color outputs to
+ // 4 components. And since the spec also seems silent on how many components an output
+ // must have, we always use 4.
+ TType *fragmentVarType = new TType(accessVarType->getBasicType(), 4);
+ fragmentVarType->setPrecision(plsType.getPrecision());
+ fragmentVarType->setQualifier(EvqFragmentInOut);
+
+ // PLS attachments are bound in reverse order from the rear.
+ TLayoutQualifier layoutQualifier = TLayoutQualifier::Create();
+ layoutQualifier.location =
+ compiler->getResources().MaxCombinedDrawBuffersAndPixelLocalStoragePlanes -
+ plsType.getLayoutQualifier().binding - 1;
+ layoutQualifier.locationsSpecified = 1;
+ if (compileOptions.pls.fragmentSynchronizationType ==
+ ShFragmentSynchronizationType::NotSupported)
+ {
+ // We're using EXT_shader_framebuffer_fetch_non_coherent, which requires the
+ // "noncoherent" qualifier.
+ layoutQualifier.noncoherent = true;
+ }
+ fragmentVarType->setLayoutQualifier(layoutQualifier);
+
+ fragmentVar = new TVariable(plsVar.uniqueId(), plsVar.name(), plsVar.symbolType(),
+ plsVar.extensions(), fragmentVarType);
+ }
+
+ // Expands our accessVar to 4 components, regardless of the size of the pixel local storage
+ // internalformat.
+ TIntermTyped *expandAccessVar() const
+ {
+ TIntermTyped *expanded = new TIntermSymbol(accessVar);
+ if (accessVar->getType().getNominalSize() == 1)
+ {
+ switch (accessVar->getType().getBasicType())
+ {
+ case EbtFloat:
+ expanded = TIntermAggregate::CreateConstructor( // "vec4(r, 0, 0, 1)"
+ TType(EbtFloat, 4),
+ {expanded, CreateFloatNode(0, EbpHigh), CreateFloatNode(0, EbpHigh),
+ CreateFloatNode(1, EbpHigh)});
+ break;
+ case EbtUInt:
+ expanded = TIntermAggregate::CreateConstructor( // "uvec4(r, 0, 0, 1)"
+ TType(EbtUInt, 4),
+ {expanded, CreateUIntNode(0), CreateUIntNode(0), CreateUIntNode(1)});
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ }
+ return expanded;
+ }
+
+ // Swizzles a variable down to the same number of components as the PLS internalformat.
+ TIntermTyped *swizzle(TVariable *var) const
+ {
+ TIntermTyped *swizzled = new TIntermSymbol(var);
+ if (var->getType().getNominalSize() != accessVar->getType().getNominalSize())
+ {
+ ASSERT(var->getType().getNominalSize() > accessVar->getType().getNominalSize());
+ TVector swizzleOffsets{0, 1, 2, 3};
+ swizzleOffsets.resize(accessVar->getType().getNominalSize());
+ swizzled = new TIntermSwizzle(swizzled, swizzleOffsets);
+ }
+ return swizzled;
+ }
+
+ TIntermTyped *swizzleFragmentVar() const { return swizzle(fragmentVar); }
+
+ TVariable *fragmentVar;
+ TVariable *accessVar;
+ };
+
+ PLSBackingStoreMap<PLSAttachment> mPLSAttachments;
+};
+} // anonymous namespace
+
+bool RewritePixelLocalStorage(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable &symbolTable,
+ const ShCompileOptions &compileOptions,
+ int shaderVersion)
+{
+ // If any functions take PLS arguments, monomorphize the functions by removing said parameters
+ // and making the PLS calls from main() instead, using the global uniform from the call site
+ // instead of the function argument. This is necessary because function arguments don't carry
+ // the necessary "binding" or "format" layout qualifiers.
+ if (!MonomorphizeUnsupportedFunctions(
+ compiler, root, &symbolTable, compileOptions,
+ UnsupportedFunctionArgsBitSet{UnsupportedFunctionArgs::PixelLocalStorage}))
+ {
+ return false;
+ }
+
+ TIntermBlock *mainBody = FindMainBody(root);
+
+ std::unique_ptr<RewritePLSTraverser> traverser;
+ switch (compileOptions.pls.type)
+ {
+ case ShPixelLocalStorageType::ImageStoreR32PackedFormats:
+ case ShPixelLocalStorageType::ImageStoreNativeFormats:
+ traverser = std::make_unique<RewritePLSToImagesTraverser>(
+ compiler, symbolTable, compileOptions, shaderVersion);
+ break;
+ case ShPixelLocalStorageType::FramebufferFetch:
+ traverser = std::make_unique<RewritePLSToFramebufferFetchTraverser>(
+ compiler, symbolTable, compileOptions, shaderVersion);
+ break;
+ default:
+ UNREACHABLE();
+ return false;
+ }
+
+ // Rewrite PLS operations to image operations.
+ root->traverse(traverser.get());
+ if (!traverser->updateTree(compiler, root))
+ {
+ return false;
+ }
+
+ // Inject the code that needs to run before and after all PLS operations.
+ // TODO(anglebug.com/7279): Inject these functions in a tight critical section, instead of
+ // just locking the entire main() function:
+ // - Monomorphize all PLS calls into main().
+ // - Insert begin/end calls around the first/last PLS calls (and outside of flow control).
+ traverser->injectSetupCode(compiler, symbolTable, compileOptions, mainBody, 0);
+ traverser->injectFinalizeCode(compiler, symbolTable, compileOptions, mainBody,
+ mainBody->getChildCount());
+
+ if (traverser->globalPixelCoord())
+ {
+ // Initialize the global pixel coord at the beginning of main():
+ //
+ // pixelCoord = ivec2(floor(gl_FragCoord.xy));
+ //
+ TIntermTyped *exp;
+ exp = ReferenceBuiltInVariable(ImmutableString("gl_FragCoord"), symbolTable, shaderVersion);
+ exp = CreateSwizzle(exp, 0, 1);
+ exp = CreateBuiltInFunctionCallNode("floor", {exp}, symbolTable, shaderVersion);
+ exp = TIntermAggregate::CreateConstructor(TType(EbtInt, 2), {exp});
+ exp = CreateTempAssignmentNode(traverser->globalPixelCoord(), exp);
+ mainBody->insertStatement(0, exp);
+ }
+
+ return compiler->validateAST(root);
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RewritePixelLocalStorage.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewritePixelLocalStorage.h
new file mode 100644
index 0000000000..9bcfcbb62e
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewritePixelLocalStorage.h
@@ -0,0 +1,29 @@
+//
+// Copyright 2022 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_TREEOPS_REWRITE_PIXELLOCALSTORAGE_H_
+#define COMPILER_TRANSLATOR_TREEOPS_REWRITE_PIXELLOCALSTORAGE_H_
+
+#include <GLSLANG/ShaderLang.h>
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+// This mutating tree traversal rewrites high level ANGLE_shader_pixel_local_storage operations to
+// the type of shader operations specified by ShPixelLocalStorageType, found in ShCompileOptions.
+[[nodiscard]] bool RewritePixelLocalStorage(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable &symbolTable,
+ const ShCompileOptions &compileOptions,
+ int shaderVersion);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_REWRITE_PIXELLOCALSTORAGE_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteStructSamplers.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteStructSamplers.cpp
new file mode 100644
index 0000000000..219a6b31fc
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteStructSamplers.cpp
@@ -0,0 +1,673 @@
+//
+// Copyright 2018 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.
+//
+// RewriteStructSamplers: Extract samplers from structs.
+//
+
+#include "compiler/translator/tree_ops/RewriteStructSamplers.h"
+
+#include "compiler/translator/ImmutableStringBuilder.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+namespace
+{
+
+// Used to map one structure type to another (one where the samplers are removed).
+struct StructureData
+{
+ // The structure this was replaced with. If nullptr, it means the structure is removed (because
+ // it had all samplers).
+ const TStructure *modified;
+ // Indexed by the field index of original structure, to get the field index of the modified
+ // structure. For example:
+ //
+ // struct Original
+ // {
+ // sampler2D s1;
+ // vec4 f1;
+ // sampler2D s2;
+ // sampler2D s3;
+ // vec4 f2;
+ // };
+ //
+ // struct Modified
+ // {
+ // vec4 f1;
+ // vec4 f2;
+ // };
+ //
+ // fieldMap:
+ // 0 -> Invalid
+ // 1 -> 0
+ // 2 -> Invalid
+ // 3 -> Invalid
+ // 4 -> 1
+ //
+ TVector<int> fieldMap;
+};
+
+using StructureMap = angle::HashMap<const TStructure *, StructureData>;
+using StructureUniformMap = angle::HashMap<const TVariable *, const TVariable *>;
+using ExtractedSamplerMap = angle::HashMap<std::string, const TVariable *>;
+
+TIntermTyped *RewriteModifiedStructFieldSelectionExpression(
+ TCompiler *compiler,
+ TIntermBinary *node,
+ const StructureMap &structureMap,
+ const StructureUniformMap &structureUniformMap,
+ const ExtractedSamplerMap &extractedSamplers);
+
+TIntermTyped *RewriteExpressionVisitBinaryHelper(TCompiler *compiler,
+ TIntermBinary *node,
+ const StructureMap &structureMap,
+ const StructureUniformMap &structureUniformMap,
+ const ExtractedSamplerMap &extractedSamplers)
+{
+ // Only interested in EOpIndexDirectStruct binary nodes.
+ if (node->getOp() != EOpIndexDirectStruct)
+ {
+ return nullptr;
+ }
+
+ const TStructure *structure = node->getLeft()->getType().getStruct();
+ ASSERT(structure);
+
+ // If the result of the index is not a sampler and the struct is not replaced, there's nothing
+ // to do.
+ if (!node->getType().isSampler() && structureMap.find(structure) == structureMap.end())
+ {
+ return nullptr;
+ }
+
+ // Otherwise, replace the whole expression such that:
+ //
+ // - if sampler, it's indexed with whatever indices the parent structs were indexed with,
+ // - otherwise, the chain of field selections is rewritten by modifying the base uniform so all
+ // the intermediate nodes would have the correct type (and therefore fields).
+ ASSERT(structureMap.find(structure) != structureMap.end());
+
+ return RewriteModifiedStructFieldSelectionExpression(compiler, node, structureMap,
+ structureUniformMap, extractedSamplers);
+}
+
+// Given an expression, this traverser calculates a new expression where sampler-in-structs are
+// replaced with their extracted ones, and field indices are adjusted for the rest of the fields.
+// In particular, this is run on the right node of EOpIndexIndirect binary nodes, so that the
+// expression in the index gets a chance to go through this transformation.
+class RewriteExpressionTraverser final : public TIntermTraverser
+{
+ public:
+ explicit RewriteExpressionTraverser(TCompiler *compiler,
+ const StructureMap &structureMap,
+ const StructureUniformMap &structureUniformMap,
+ const ExtractedSamplerMap &extractedSamplers)
+ : TIntermTraverser(true, false, false),
+ mCompiler(compiler),
+ mStructureMap(structureMap),
+ mStructureUniformMap(structureUniformMap),
+ mExtractedSamplers(extractedSamplers)
+ {}
+
+ bool visitBinary(Visit visit, TIntermBinary *node) override
+ {
+ TIntermTyped *rewritten = RewriteExpressionVisitBinaryHelper(
+ mCompiler, node, mStructureMap, mStructureUniformMap, mExtractedSamplers);
+
+ if (rewritten == nullptr)
+ {
+ return true;
+ }
+
+ queueReplacement(rewritten, OriginalNode::IS_DROPPED);
+
+ // Don't iterate as the expression is rewritten.
+ return false;
+ }
+
+ void visitSymbol(TIntermSymbol *node) override
+ {
+ // It's impossible to reach here with a symbol that needs replacement.
+ // MonomorphizeUnsupportedFunctions makes sure that whole structs containing
+ // samplers are not passed to functions, so any instance of the struct uniform is
+ // necessarily indexed right away. visitBinary should have already taken care of it.
+ ASSERT(mStructureUniformMap.find(&node->variable()) == mStructureUniformMap.end());
+ }
+
+ private:
+ TCompiler *mCompiler;
+
+ // See RewriteStructSamplersTraverser.
+ const StructureMap &mStructureMap;
+ const StructureUniformMap &mStructureUniformMap;
+ const ExtractedSamplerMap &mExtractedSamplers;
+};
+
+// Rewrite the index of an EOpIndexIndirect expression. The root can never need replacing, because
+// it cannot be a sampler itself or of a struct type.
+void RewriteIndexExpression(TCompiler *compiler,
+ TIntermTyped *expression,
+ const StructureMap &structureMap,
+ const StructureUniformMap &structureUniformMap,
+ const ExtractedSamplerMap &extractedSamplers)
+{
+ RewriteExpressionTraverser traverser(compiler, structureMap, structureUniformMap,
+ extractedSamplers);
+ expression->traverse(&traverser);
+ bool valid = traverser.updateTree(compiler, expression);
+ ASSERT(valid);
+}
+
+// Given an expression such as the following:
+//
+// EOpIndexDirectStruct (sampler)
+// / \
+// EOpIndex* field index
+// / \
+// EOpIndexDirectStruct index 2
+// / \
+// EOpIndex* field index
+// / \
+// EOpIndexDirectStruct index 1
+// / \
+// Uniform Struct field index
+//
+// produces:
+//
+// EOpIndex*
+// / \
+// EOpIndex* index 2
+// / \
+// sampler index 1
+//
+// Alternatively, if the expression is as such:
+//
+// EOpIndexDirectStruct
+// / \
+// (modified struct type) EOpIndex* field index
+// / \
+// EOpIndexDirectStruct index 2
+// / \
+// EOpIndex* field index
+// / \
+// EOpIndexDirectStruct index 1
+// / \
+// Uniform Struct field index
+//
+// produces:
+//
+// EOpIndexDirectStruct
+// / \
+// EOpIndex* mapped field index
+// / \
+// EOpIndexDirectStruct index 2
+// / \
+// EOpIndex* mapped field index
+// / \
+// EOpIndexDirectStruct index 1
+// / \
+// Uniform Struct mapped field index
+//
+TIntermTyped *RewriteModifiedStructFieldSelectionExpression(
+ TCompiler *compiler,
+ TIntermBinary *node,
+ const StructureMap &structureMap,
+ const StructureUniformMap &structureUniformMap,
+ const ExtractedSamplerMap &extractedSamplers)
+{
+ ASSERT(node->getOp() == EOpIndexDirectStruct);
+
+ const bool isSampler = node->getType().isSampler();
+
+ TIntermSymbol *baseUniform = nullptr;
+ std::string samplerName;
+
+ TVector<TIntermBinary *> indexNodeStack;
+
+ // Iterate once and build the name of the sampler.
+ TIntermBinary *iter = node;
+ while (baseUniform == nullptr)
+ {
+ indexNodeStack.push_back(iter);
+ baseUniform = iter->getLeft()->getAsSymbolNode();
+
+ if (isSampler)
+ {
+ if (iter->getOp() == EOpIndexDirectStruct)
+ {
+ // When indexed into a struct, get the field name instead and construct the sampler
+ // name.
+ samplerName.insert(0, iter->getIndexStructFieldName().data());
+ samplerName.insert(0, "_");
+ }
+
+ if (baseUniform)
+ {
+ // If left is a symbol, we have reached the end of the chain. Use the struct name
+ // to finish building the name of the sampler.
+ samplerName.insert(0, baseUniform->variable().name().data());
+ }
+ }
+
+ iter = iter->getLeft()->getAsBinaryNode();
+ }
+
+ TIntermTyped *rewritten = nullptr;
+
+ if (isSampler)
+ {
+ ASSERT(extractedSamplers.find(samplerName) != extractedSamplers.end());
+ rewritten = new TIntermSymbol(extractedSamplers.at(samplerName));
+ }
+ else
+ {
+ const TVariable *baseUniformVar = &baseUniform->variable();
+ ASSERT(structureUniformMap.find(baseUniformVar) != structureUniformMap.end());
+ rewritten = new TIntermSymbol(structureUniformMap.at(baseUniformVar));
+ }
+
+ // Iterate again and build the expression from bottom up.
+ for (auto it = indexNodeStack.rbegin(); it != indexNodeStack.rend(); ++it)
+ {
+ TIntermBinary *indexNode = *it;
+
+ switch (indexNode->getOp())
+ {
+ case EOpIndexDirectStruct:
+ if (!isSampler)
+ {
+ // Remap the field.
+ const TStructure *structure = indexNode->getLeft()->getType().getStruct();
+ ASSERT(structureMap.find(structure) != structureMap.end());
+
+ TIntermConstantUnion *asConstantUnion =
+ indexNode->getRight()->getAsConstantUnion();
+ ASSERT(asConstantUnion);
+
+ const int fieldIndex = asConstantUnion->getIConst(0);
+ ASSERT(fieldIndex <
+ static_cast<int>(structureMap.at(structure).fieldMap.size()));
+
+ const int mappedFieldIndex = structureMap.at(structure).fieldMap[fieldIndex];
+
+ rewritten = new TIntermBinary(EOpIndexDirectStruct, rewritten,
+ CreateIndexNode(mappedFieldIndex));
+ }
+ break;
+
+ case EOpIndexDirect:
+ rewritten = new TIntermBinary(EOpIndexDirect, rewritten, indexNode->getRight());
+ break;
+
+ case EOpIndexIndirect:
+ {
+ // Run RewriteExpressionTraverser on the right node. It may itself be an expression
+ // with a sampler inside that needs to be rewritten, or simply use a field of a
+ // struct that's remapped.
+ TIntermTyped *indexExpression = indexNode->getRight();
+ RewriteIndexExpression(compiler, indexExpression, structureMap, structureUniformMap,
+ extractedSamplers);
+ rewritten = new TIntermBinary(EOpIndexIndirect, rewritten, indexExpression);
+ break;
+ }
+
+ default:
+ UNREACHABLE();
+ break;
+ }
+ }
+
+ return rewritten;
+}
+
+class RewriteStructSamplersTraverser final : public TIntermTraverser
+{
+ public:
+ explicit RewriteStructSamplersTraverser(TCompiler *compiler, TSymbolTable *symbolTable)
+ : TIntermTraverser(true, false, false, symbolTable),
+ mCompiler(compiler),
+ mRemovedUniformsCount(0)
+ {}
+
+ int removedUniformsCount() const { return mRemovedUniformsCount; }
+
+ // Each struct sampler declaration is stripped of its samplers. New uniforms are added for each
+ // stripped struct sampler.
+ bool visitDeclaration(Visit visit, TIntermDeclaration *decl) override
+ {
+ if (!mInGlobalScope)
+ {
+ return true;
+ }
+
+ const TIntermSequence &sequence = *(decl->getSequence());
+ TIntermTyped *declarator = sequence.front()->getAsTyped();
+ const TType &type = declarator->getType();
+
+ if (!type.isStructureContainingSamplers())
+ {
+ return false;
+ }
+
+ TIntermSequence newSequence;
+
+ if (type.isStructSpecifier())
+ {
+ // If this is just a struct definition (not a uniform variable declaration of a
+ // struct type), just remove the samplers. They are not instantiated yet.
+ const TStructure *structure = type.getStruct();
+ ASSERT(structure && mStructureMap.find(structure) == mStructureMap.end());
+
+ stripStructSpecifierSamplers(structure, &newSequence);
+ }
+ else
+ {
+ const TStructure *structure = type.getStruct();
+
+ // If the structure is defined at the same time, create the mapping to the stripped
+ // version first.
+ if (mStructureMap.find(structure) == mStructureMap.end())
+ {
+ stripStructSpecifierSamplers(structure, &newSequence);
+ }
+
+ // Then, extract the samplers from the struct and create global-scope variables instead.
+ TIntermSymbol *asSymbol = declarator->getAsSymbolNode();
+ ASSERT(asSymbol);
+ const TVariable &variable = asSymbol->variable();
+ ASSERT(variable.symbolType() != SymbolType::Empty);
+
+ extractStructSamplerUniforms(variable, structure, &newSequence);
+ }
+
+ mMultiReplacements.emplace_back(getParentNode()->getAsBlock(), decl,
+ std::move(newSequence));
+
+ return false;
+ }
+
+ // Same implementation as in RewriteExpressionTraverser. That traverser cannot replace root.
+ bool visitBinary(Visit visit, TIntermBinary *node) override
+ {
+ TIntermTyped *rewritten = RewriteExpressionVisitBinaryHelper(
+ mCompiler, node, mStructureMap, mStructureUniformMap, mExtractedSamplers);
+
+ if (rewritten == nullptr)
+ {
+ return true;
+ }
+
+ queueReplacement(rewritten, OriginalNode::IS_DROPPED);
+
+ // Don't iterate as the expression is rewritten.
+ return false;
+ }
+
+ // Same implementation as in RewriteExpressionTraverser. That traverser cannot replace root.
+ void visitSymbol(TIntermSymbol *node) override
+ {
+ ASSERT(mStructureUniformMap.find(&node->variable()) == mStructureUniformMap.end());
+ }
+
+ private:
+ // Removes all samplers from a struct specifier.
+ void stripStructSpecifierSamplers(const TStructure *structure, TIntermSequence *newSequence)
+ {
+ TFieldList *newFieldList = new TFieldList;
+ ASSERT(structure->containsSamplers());
+
+ // Add this struct to the struct map
+ ASSERT(mStructureMap.find(structure) == mStructureMap.end());
+ StructureData *modifiedData = &mStructureMap[structure];
+
+ modifiedData->modified = nullptr;
+ modifiedData->fieldMap.resize(structure->fields().size(), std::numeric_limits<int>::max());
+
+ for (size_t fieldIndex = 0; fieldIndex < structure->fields().size(); ++fieldIndex)
+ {
+ const TField *field = structure->fields()[fieldIndex];
+ const TType &fieldType = *field->type();
+
+ // If the field is a sampler, or a struct that's entirely removed, skip it.
+ if (!fieldType.isSampler() && !isRemovedStructType(fieldType))
+ {
+ TType *newType = nullptr;
+
+ // Otherwise, if it's a struct that's replaced, create a new field of the replaced
+ // type.
+ if (fieldType.isStructureContainingSamplers())
+ {
+ const TStructure *fieldStruct = fieldType.getStruct();
+ ASSERT(mStructureMap.find(fieldStruct) != mStructureMap.end());
+
+ const TStructure *modifiedStruct = mStructureMap[fieldStruct].modified;
+ ASSERT(modifiedStruct);
+
+ newType = new TType(modifiedStruct, true);
+ if (fieldType.isArray())
+ {
+ newType->makeArrays(fieldType.getArraySizes());
+ }
+ }
+ else
+ {
+ // If not, duplicate the field as is.
+ newType = new TType(fieldType);
+ }
+
+ // Record the mapping of the field indices, so future EOpIndexDirectStruct's into
+ // this struct can be fixed up.
+ modifiedData->fieldMap[fieldIndex] = static_cast<int>(newFieldList->size());
+
+ TField *newField =
+ new TField(newType, field->name(), field->line(), field->symbolType());
+ newFieldList->push_back(newField);
+ }
+ }
+
+ // Prune empty structs.
+ if (newFieldList->empty())
+ {
+ return;
+ }
+
+ // Declare a new struct with the same name and the new fields.
+ modifiedData->modified =
+ new TStructure(mSymbolTable, structure->name(), newFieldList, structure->symbolType());
+ TType *newStructType = new TType(modifiedData->modified, true);
+ TVariable *newStructVar =
+ new TVariable(mSymbolTable, kEmptyImmutableString, newStructType, SymbolType::Empty);
+ TIntermSymbol *newStructRef = new TIntermSymbol(newStructVar);
+
+ TIntermDeclaration *structDecl = new TIntermDeclaration;
+ structDecl->appendDeclarator(newStructRef);
+
+ newSequence->push_back(structDecl);
+ }
+
+ // Returns true if the type is a struct that was removed because we extracted all the members.
+ bool isRemovedStructType(const TType &type) const
+ {
+ const TStructure *structure = type.getStruct();
+ if (structure == nullptr)
+ {
+ // Not a struct
+ return false;
+ }
+
+ // A struct is removed if it is in the map, but doesn't have a replacement struct.
+ auto iter = mStructureMap.find(structure);
+ return iter != mStructureMap.end() && iter->second.modified == nullptr;
+ }
+
+ // Removes samplers from struct uniforms. For each sampler removed also adds a new globally
+ // defined sampler uniform.
+ void extractStructSamplerUniforms(const TVariable &variable,
+ const TStructure *structure,
+ TIntermSequence *newSequence)
+ {
+ ASSERT(structure->containsSamplers());
+ ASSERT(mStructureMap.find(structure) != mStructureMap.end());
+
+ const TType &type = variable.getType();
+ enterArray(type);
+
+ for (const TField *field : structure->fields())
+ {
+ extractFieldSamplers(variable.name().data(), field, newSequence);
+ }
+
+ // If there's a replacement structure (because there are non-sampler fields in the struct),
+ // add a declaration with that type.
+ const TStructure *modified = mStructureMap[structure].modified;
+ if (modified != nullptr)
+ {
+ TType *newType = new TType(modified, false);
+ if (type.isArray())
+ {
+ newType->makeArrays(type.getArraySizes());
+ }
+ newType->setQualifier(EvqUniform);
+ const TVariable *newVariable =
+ new TVariable(mSymbolTable, variable.name(), newType, variable.symbolType());
+
+ TIntermDeclaration *newDecl = new TIntermDeclaration();
+ newDecl->appendDeclarator(new TIntermSymbol(newVariable));
+
+ newSequence->push_back(newDecl);
+
+ ASSERT(mStructureUniformMap.find(&variable) == mStructureUniformMap.end());
+ mStructureUniformMap[&variable] = newVariable;
+ }
+ else
+ {
+ mRemovedUniformsCount++;
+ }
+
+ exitArray(type);
+ }
+
+ // Extracts samplers from a field of a struct. Works with nested structs and arrays.
+ void extractFieldSamplers(const std::string &prefix,
+ const TField *field,
+ TIntermSequence *newSequence)
+ {
+ const TType &fieldType = *field->type();
+ if (fieldType.isSampler() || fieldType.isStructureContainingSamplers())
+ {
+ std::string newPrefix = prefix + "_" + field->name().data();
+
+ if (fieldType.isSampler())
+ {
+ extractSampler(newPrefix, fieldType, newSequence);
+ }
+ else
+ {
+ enterArray(fieldType);
+ const TStructure *structure = fieldType.getStruct();
+ for (const TField *nestedField : structure->fields())
+ {
+ extractFieldSamplers(newPrefix, nestedField, newSequence);
+ }
+ exitArray(fieldType);
+ }
+ }
+ }
+
+ void GenerateArraySizesFromStack(TVector<unsigned int> *sizesOut)
+ {
+ sizesOut->reserve(mArraySizeStack.size());
+
+ for (auto it = mArraySizeStack.rbegin(); it != mArraySizeStack.rend(); ++it)
+ {
+ sizesOut->push_back(*it);
+ }
+ }
+
+ // Extracts a sampler from a struct. Declares the new extracted sampler.
+ void extractSampler(const std::string &newName,
+ const TType &fieldType,
+ TIntermSequence *newSequence)
+ {
+ ASSERT(fieldType.isSampler());
+
+ TType *newType = new TType(fieldType);
+
+ // Add array dimensions accumulated so far due to struct arrays. Note that to support
+ // nested arrays, mArraySizeStack has the outermost size in the front. |makeArrays| thus
+ // expects this in reverse order.
+ TVector<unsigned int> parentArraySizes;
+ GenerateArraySizesFromStack(&parentArraySizes);
+ newType->makeArrays(parentArraySizes);
+
+ ImmutableStringBuilder nameBuilder(newName.size() + 1);
+ nameBuilder << newName;
+
+ newType->setQualifier(EvqUniform);
+ TVariable *newVariable =
+ new TVariable(mSymbolTable, nameBuilder, newType, SymbolType::AngleInternal);
+ TIntermSymbol *newSymbol = new TIntermSymbol(newVariable);
+
+ TIntermDeclaration *samplerDecl = new TIntermDeclaration;
+ samplerDecl->appendDeclarator(newSymbol);
+
+ newSequence->push_back(samplerDecl);
+
+ // TODO: Use a temp name instead of generating a name as currently done. There is no
+ // guarantee that these generated names cannot clash. Create a mapping from the previous
+ // name to the name assigned to the temp variable so ShaderVariable::mappedName can be
+ // updated post-transformation. http://anglebug.com/4301
+ ASSERT(mExtractedSamplers.find(newName) == mExtractedSamplers.end());
+ mExtractedSamplers[newName] = newVariable;
+ }
+
+ void enterArray(const TType &arrayType)
+ {
+ const TSpan<const unsigned int> &arraySizes = arrayType.getArraySizes();
+ for (auto it = arraySizes.rbegin(); it != arraySizes.rend(); ++it)
+ {
+ unsigned int arraySize = *it;
+ mArraySizeStack.push_back(arraySize);
+ }
+ }
+
+ void exitArray(const TType &arrayType)
+ {
+ mArraySizeStack.resize(mArraySizeStack.size() - arrayType.getNumArraySizes());
+ }
+
+ TCompiler *mCompiler;
+ int mRemovedUniformsCount;
+
+ // Map structures with samplers to ones that have their samplers removed.
+ StructureMap mStructureMap;
+
+ // Map uniform variables of structure type that are replaced with another variable.
+ StructureUniformMap mStructureUniformMap;
+
+ // Map a constructed sampler name to its variable. Used to replace an expression that uses this
+ // sampler with the extracted one.
+ ExtractedSamplerMap mExtractedSamplers;
+
+ // A stack of array sizes. Used to figure out the array dimensions of the extracted sampler,
+ // for example when it's nested in an array of structs in an array of structs.
+ TVector<unsigned int> mArraySizeStack;
+};
+} // anonymous namespace
+
+bool RewriteStructSamplers(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ int *removedUniformsCountOut)
+{
+ RewriteStructSamplersTraverser traverser(compiler, symbolTable);
+ root->traverse(&traverser);
+ *removedUniformsCountOut = traverser.removedUniformsCount();
+ return traverser.updateTree(compiler, root);
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteStructSamplers.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteStructSamplers.h
new file mode 100644
index 0000000000..f4c73a27fc
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteStructSamplers.h
@@ -0,0 +1,38 @@
+//
+// Copyright 2018 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.
+//
+// RewriteStructSamplers: Extract structs from samplers.
+//
+// This traverser is designed to strip out samplers from structs. It moves them into separate
+// uniform sampler declarations. This allows the struct to be stored in the default uniform block.
+// This transformation requires MonomorphizeUnsupportedFunctions to have been run so it
+// wouldn't need to deal with functions that are passed such structs.
+//
+// For example:
+// struct S { sampler2D samp; int i; };
+// uniform S uni;
+// Is rewritten as:
+// struct S { int i; };
+// uniform S uni;
+// uniform sampler2D uni_i;
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_REWRITESTRUCTSAMPLERS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_REWRITESTRUCTSAMPLERS_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+[[nodiscard]] bool RewriteStructSamplers(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ int *removedUniformsCountOut);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_VULKAN_REWRITESTRUCTSAMPLERS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteTexelFetchOffset.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteTexelFetchOffset.cpp
new file mode 100644
index 0000000000..71284ecc1b
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteTexelFetchOffset.cpp
@@ -0,0 +1,168 @@
+//
+// 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.
+//
+// Implementation of texelFetchOffset translation issue workaround.
+// See header for more info.
+
+#include "compiler/translator/tree_ops/RewriteTexelFetchOffset.h"
+
+#include "common/angleutils.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class Traverser : public TIntermTraverser
+{
+ public:
+ [[nodiscard]] static bool Apply(TCompiler *compiler,
+ 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
+bool Traverser::Apply(TCompiler *compiler,
+ TIntermNode *root,
+ const TSymbolTable &symbolTable,
+ int shaderVersion)
+{
+ Traverser traverser(symbolTable, shaderVersion);
+ do
+ {
+ traverser.nextIteration();
+ root->traverse(&traverser);
+ if (traverser.mFound)
+ {
+ if (!traverser.updateTree(compiler, root))
+ {
+ return false;
+ }
+ }
+ } while (traverser.mFound);
+
+ return true;
+}
+
+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 (!BuiltInGroup::IsBuiltIn(node->getOp()))
+ {
+ return true;
+ }
+
+ ASSERT(node->getFunction()->symbolType() == SymbolType::BuiltIn);
+ if (node->getFunction()->name() != "texelFetchOffset")
+ {
+ return true;
+ }
+
+ // Potential problem case detected, apply workaround.
+ const TIntermSequence *sequence = node->getSequence();
+ ASSERT(sequence->size() == 4u);
+
+ // Decide if the sampler is a 2DArray sampler. In that case position is ivec3 and offset is
+ // ivec2.
+ bool is2DArray = sequence->at(1)->getAsTyped()->getNominalSize() == 3 &&
+ sequence->at(3)->getAsTyped()->getNominalSize() == 2;
+
+ // Create new node that represents the call of function texelFetch.
+ // Its argument list will be: texelFetch(sampler, Position+offset, lod).
+
+ TIntermSequence texelFetchArguments;
+
+ // sampler
+ texelFetchArguments.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.
+ TIntermSequence constructOffsetIvecArguments;
+ constructOffsetIvecArguments.push_back(sequence->at(3)->getAsTyped());
+
+ TIntermTyped *zeroNode = CreateZeroNode(TType(EbtInt));
+ constructOffsetIvecArguments.push_back(zeroNode);
+
+ offsetNode = TIntermAggregate::CreateConstructor(texCoordNode->getType(),
+ &constructOffsetIvecArguments);
+ offsetNode->setLine(texCoordNode->getLine());
+ }
+ else
+ {
+ offsetNode = sequence->at(3)->getAsTyped();
+ }
+
+ // Position+offset
+ TIntermBinary *add = new TIntermBinary(EOpAdd, texCoordNode, offsetNode);
+ add->setLine(texCoordNode->getLine());
+ texelFetchArguments.push_back(add);
+
+ // lod
+ texelFetchArguments.push_back(sequence->at(2));
+
+ ASSERT(texelFetchArguments.size() == 3u);
+
+ TIntermTyped *texelFetchNode = CreateBuiltInFunctionCallNode("texelFetch", &texelFetchArguments,
+ *symbolTable, shaderVersion);
+ texelFetchNode->setLine(node->getLine());
+
+ // Replace the old node by this new node.
+ queueReplacement(texelFetchNode, OriginalNode::IS_DROPPED);
+ mFound = true;
+ return false;
+}
+
+} // anonymous namespace
+
+bool RewriteTexelFetchOffset(TCompiler *compiler,
+ TIntermNode *root,
+ const TSymbolTable &symbolTable,
+ int shaderVersion)
+{
+ // texelFetchOffset is only valid in GLSL 3.0 and later.
+ if (shaderVersion < 300)
+ return true;
+
+ return Traverser::Apply(compiler, root, symbolTable, shaderVersion);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteTexelFetchOffset.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteTexelFetchOffset.h
new file mode 100644
index 0000000000..c2c3c07aad
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/RewriteTexelFetchOffset.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.
+//
+// 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_TREEOPS_REWRITE_TEXELFETCHOFFSET_H_
+#define COMPILER_TRANSLATOR_TREEOPS_REWRITE_TEXELFETCHOFFSET_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermNode;
+class TSymbolTable;
+
+[[nodiscard]] bool RewriteTexelFetchOffset(TCompiler *compiler,
+ TIntermNode *root,
+ const TSymbolTable &symbolTable,
+ int shaderVersion);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_REWRITE_TEXELFETCHOFFSET_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/ScalarizeVecAndMatConstructorArgs.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/ScalarizeVecAndMatConstructorArgs.cpp
new file mode 100644
index 0000000000..4eab90e4fa
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/ScalarizeVecAndMatConstructorArgs.cpp
@@ -0,0 +1,223 @@
+//
+// Copyright 2002 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.
+//
+// Scalarize vector and matrix constructor args, so that vectors built from components don't have
+// matrix arguments, and matrices built from components don't have vector arguments. This avoids
+// driver bugs around vector and matrix constructors.
+//
+
+#include "compiler/translator/tree_ops/ScalarizeVecAndMatConstructorArgs.h"
+#include "common/debug.h"
+
+#include <algorithm>
+
+#include "angle_gl.h"
+#include "common/angleutils.h"
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/tree_util/IntermNodePatternMatcher.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+TIntermBinary *ConstructVectorIndexBinaryNode(TIntermTyped *symbolNode, int index)
+{
+ return new TIntermBinary(EOpIndexDirect, symbolNode, CreateIndexNode(index));
+}
+
+TIntermBinary *ConstructMatrixIndexBinaryNode(TIntermTyped *symbolNode, int colIndex, int rowIndex)
+{
+ TIntermBinary *colVectorNode = ConstructVectorIndexBinaryNode(symbolNode, colIndex);
+
+ return new TIntermBinary(EOpIndexDirect, colVectorNode, CreateIndexNode(rowIndex));
+}
+
+class ScalarizeArgsTraverser : public TIntermTraverser
+{
+ public:
+ ScalarizeArgsTraverser(TSymbolTable *symbolTable)
+ : TIntermTraverser(true, false, false, symbolTable),
+ mNodesToScalarize(IntermNodePatternMatcher::kScalarizedVecOrMatConstructor)
+ {}
+
+ protected:
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override;
+ bool visitBlock(Visit visit, TIntermBlock *node) override;
+
+ private:
+ void scalarizeArgs(TIntermAggregate *aggregate, bool scalarizeVector, bool scalarizeMatrix);
+
+ // If we have the following code:
+ // mat4 m(0);
+ // vec4 v(1, m);
+ // We will rewrite to:
+ // mat4 m(0);
+ // mat4 s0 = m;
+ // vec4 v(1, s0[0][0], s0[0][1], s0[0][2]);
+ // This function is to create nodes for "mat4 s0 = m;" and insert it to the code sequence. This
+ // way the possible side effects of the constructor argument will only be evaluated once.
+ TIntermTyped *createTempVariable(TIntermTyped *original);
+
+ std::vector<TIntermSequence> mBlockStack;
+
+ IntermNodePatternMatcher mNodesToScalarize;
+};
+
+bool ScalarizeArgsTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
+{
+ ASSERT(visit == PreVisit);
+ if (mNodesToScalarize.match(node, getParentNode()))
+ {
+ if (node->getType().isVector())
+ {
+ scalarizeArgs(node, false, true);
+ }
+ else
+ {
+ ASSERT(node->getType().isMatrix());
+ scalarizeArgs(node, true, false);
+ }
+ }
+ return true;
+}
+
+bool ScalarizeArgsTraverser::visitBlock(Visit visit, TIntermBlock *node)
+{
+ mBlockStack.push_back(TIntermSequence());
+ {
+ for (TIntermNode *child : *node->getSequence())
+ {
+ ASSERT(child != nullptr);
+ child->traverse(this);
+ mBlockStack.back().push_back(child);
+ }
+ }
+ if (mBlockStack.back().size() > node->getSequence()->size())
+ {
+ node->getSequence()->clear();
+ *(node->getSequence()) = mBlockStack.back();
+ }
+ mBlockStack.pop_back();
+ return false;
+}
+
+void ScalarizeArgsTraverser::scalarizeArgs(TIntermAggregate *aggregate,
+ bool scalarizeVector,
+ bool scalarizeMatrix)
+{
+ ASSERT(aggregate);
+ ASSERT(!aggregate->isArray());
+ int size = static_cast<int>(aggregate->getType().getObjectSize());
+ TIntermSequence *sequence = aggregate->getSequence();
+ TIntermSequence originalArgs(*sequence);
+ sequence->clear();
+ for (TIntermNode *originalArgNode : originalArgs)
+ {
+ ASSERT(size > 0);
+ TIntermTyped *originalArg = originalArgNode->getAsTyped();
+ ASSERT(originalArg);
+ TIntermTyped *argVariable = createTempVariable(originalArg);
+ if (originalArg->isScalar())
+ {
+ sequence->push_back(argVariable);
+ size--;
+ }
+ else if (originalArg->isVector())
+ {
+ if (scalarizeVector)
+ {
+ int repeat = std::min<int>(size, originalArg->getNominalSize());
+ size -= repeat;
+ for (int index = 0; index < repeat; ++index)
+ {
+ TIntermBinary *newNode =
+ ConstructVectorIndexBinaryNode(argVariable->deepCopy(), index);
+ sequence->push_back(newNode);
+ }
+ }
+ else
+ {
+ sequence->push_back(argVariable);
+ size -= originalArg->getNominalSize();
+ }
+ }
+ else
+ {
+ ASSERT(originalArg->isMatrix());
+ if (scalarizeMatrix)
+ {
+ int colIndex = 0, rowIndex = 0;
+ int repeat = std::min<int>(size, originalArg->getCols() * originalArg->getRows());
+ size -= repeat;
+ while (repeat > 0)
+ {
+ TIntermBinary *newNode =
+ ConstructMatrixIndexBinaryNode(argVariable->deepCopy(), colIndex, rowIndex);
+ sequence->push_back(newNode);
+ rowIndex++;
+ if (rowIndex >= originalArg->getRows())
+ {
+ rowIndex = 0;
+ colIndex++;
+ }
+ repeat--;
+ }
+ }
+ else
+ {
+ sequence->push_back(argVariable);
+ size -= originalArg->getCols() * originalArg->getRows();
+ }
+ }
+ }
+}
+
+TIntermTyped *ScalarizeArgsTraverser::createTempVariable(TIntermTyped *original)
+{
+ ASSERT(original);
+
+ TType *type = new TType(original->getType());
+ type->setQualifier(EvqTemporary);
+
+ // The precision of the constant must have been retained (or derived), which will now apply to
+ // the temp variable. In some cases, the precision cannot be derived, so use the constant as
+ // is. For example, in the following standalone statement, the precision of the constant 0
+ // cannot be determined:
+ //
+ // mat2(0, bvec3(m));
+ //
+ if (IsPrecisionApplicableToType(type->getBasicType()) && type->getPrecision() == EbpUndefined)
+ {
+ return original;
+ }
+
+ TVariable *variable = CreateTempVariable(mSymbolTable, type);
+
+ ASSERT(mBlockStack.size() > 0);
+ TIntermSequence &sequence = mBlockStack.back();
+ TIntermDeclaration *declaration = CreateTempInitDeclarationNode(variable, original);
+ sequence.push_back(declaration);
+
+ return CreateTempSymbolNode(variable);
+}
+
+} // namespace
+
+bool ScalarizeVecAndMatConstructorArgs(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable)
+{
+ ScalarizeArgsTraverser scalarizer(symbolTable);
+ root->traverse(&scalarizer);
+
+ return compiler->validateAST(root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/ScalarizeVecAndMatConstructorArgs.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/ScalarizeVecAndMatConstructorArgs.h
new file mode 100644
index 0000000000..617cbd7682
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/ScalarizeVecAndMatConstructorArgs.h
@@ -0,0 +1,28 @@
+//
+// Copyright 2002 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.
+//
+// Scalarize vector and matrix constructor args, so that vectors built from components don't have
+// matrix arguments, and matrices built from components don't have vector arguments. This avoids
+// driver bugs around vector and matrix constructors.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_SCALARIZEVECANDMATCONSTRUCTORARGS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_SCALARIZEVECANDMATCONSTRUCTORARGS_H_
+
+#include "GLSLANG/ShaderLang.h"
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+[[nodiscard]] bool ScalarizeVecAndMatConstructorArgs(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_SCALARIZEVECANDMATCONSTRUCTORARGS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateDeclarations.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateDeclarations.cpp
new file mode 100644
index 0000000000..6d48449154
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateDeclarations.cpp
@@ -0,0 +1,199 @@
+//
+// Copyright 2002 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.
+//
+// The SeparateDeclarations function processes declarations, so that in the end each declaration
+// contains only one declarator.
+// This is useful as an intermediate step when initialization needs to be separated from
+// declaration, or when things need to be unfolded out of the initializer.
+// Example:
+// int a[1] = int[1](1), b[1] = int[1](2);
+// gets transformed when run through this class into the AST equivalent of:
+// int a[1] = int[1](1);
+// int b[1] = int[1](2);
+
+#include "compiler/translator/tree_ops/SeparateDeclarations.h"
+
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/tree_util/ReplaceVariable.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class SeparateDeclarationsTraverser : private TIntermTraverser
+{
+ public:
+ [[nodiscard]] static bool apply(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable);
+
+ private:
+ SeparateDeclarationsTraverser(TSymbolTable *symbolTable);
+ bool visitDeclaration(Visit, TIntermDeclaration *node) override;
+ void visitSymbol(TIntermSymbol *symbol) override;
+
+ void separateDeclarator(TIntermSequence *sequence,
+ size_t index,
+ TIntermSequence *replacementDeclarations,
+ const TStructure **replacementStructure);
+
+ VariableReplacementMap mVariableMap;
+};
+
+bool SeparateDeclarationsTraverser::apply(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable)
+{
+ SeparateDeclarationsTraverser separateDecl(symbolTable);
+ root->traverse(&separateDecl);
+ return separateDecl.updateTree(compiler, root);
+}
+
+SeparateDeclarationsTraverser::SeparateDeclarationsTraverser(TSymbolTable *symbolTable)
+ : TIntermTraverser(true, false, false, symbolTable)
+{}
+
+bool SeparateDeclarationsTraverser::visitDeclaration(Visit, TIntermDeclaration *node)
+{
+ TIntermSequence *sequence = node->getSequence();
+ if (sequence->size() <= 1)
+ {
+ return true;
+ }
+
+ TIntermBlock *parentBlock = getParentNode()->getAsBlock();
+ ASSERT(parentBlock != nullptr);
+
+ TIntermSequence replacementDeclarations;
+ const TStructure *replacementStructure = nullptr;
+ for (size_t ii = 0; ii < sequence->size(); ++ii)
+ {
+ separateDeclarator(sequence, ii, &replacementDeclarations, &replacementStructure);
+ }
+
+ mMultiReplacements.emplace_back(parentBlock, node, std::move(replacementDeclarations));
+ return false;
+}
+
+void SeparateDeclarationsTraverser::visitSymbol(TIntermSymbol *symbol)
+{
+ const TVariable *variable = &symbol->variable();
+ if (mVariableMap.count(variable) > 0)
+ {
+ queueAccessChainReplacement(mVariableMap[variable]->deepCopy());
+ }
+}
+
+void SeparateDeclarationsTraverser::separateDeclarator(TIntermSequence *sequence,
+ size_t index,
+ TIntermSequence *replacementDeclarations,
+ const TStructure **replacementStructure)
+{
+ TIntermTyped *declarator = sequence->at(index)->getAsTyped();
+ const TType &declaratorType = declarator->getType();
+
+ // If the declaration is not simultaneously declaring a struct, can use the same declarator.
+ // Otherwise, the first declarator is taken as-is if the struct has a name.
+ const TStructure *structure = declaratorType.getStruct();
+ const bool isStructSpecifier = declaratorType.isStructSpecifier();
+ if (!isStructSpecifier || (index == 0 && structure->symbolType() != SymbolType::Empty))
+ {
+ TIntermDeclaration *replacementDeclaration = new TIntermDeclaration;
+
+ // Make sure to update the declarator's initializers if any.
+ declarator->traverse(this);
+
+ replacementDeclaration->appendDeclarator(declarator);
+ replacementDeclaration->setLine(declarator->getLine());
+ replacementDeclarations->push_back(replacementDeclaration);
+ return;
+ }
+
+ // If the struct is nameless, split it out first.
+ if (structure->symbolType() == SymbolType::Empty)
+ {
+ if (*replacementStructure == nullptr)
+ {
+ TStructure *newStructure =
+ new TStructure(mSymbolTable, kEmptyImmutableString, &structure->fields(),
+ SymbolType::AngleInternal);
+ newStructure->setAtGlobalScope(structure->atGlobalScope());
+ *replacementStructure = structure = newStructure;
+
+ TType *namedType = new TType(structure, true);
+ namedType->setQualifier(EvqGlobal);
+
+ TVariable *structVariable =
+ new TVariable(mSymbolTable, kEmptyImmutableString, namedType, SymbolType::Empty);
+
+ TIntermDeclaration *structDeclaration = new TIntermDeclaration;
+ structDeclaration->appendDeclarator(new TIntermSymbol(structVariable));
+ structDeclaration->setLine(declarator->getLine());
+ replacementDeclarations->push_back(structDeclaration);
+ }
+ else
+ {
+ structure = *replacementStructure;
+ }
+ }
+
+ // Redeclare the declarator but not as a struct specifier.
+ TIntermSymbol *asSymbol = declarator->getAsSymbolNode();
+ TIntermTyped *initializer = nullptr;
+ if (asSymbol == nullptr)
+ {
+ TIntermBinary *asBinary = declarator->getAsBinaryNode();
+ ASSERT(asBinary->getOp() == EOpInitialize);
+ asSymbol = asBinary->getLeft()->getAsSymbolNode();
+ initializer = asBinary->getRight();
+
+ // Make sure the initializer itself has its variables replaced if necessary.
+ if (initializer->getAsSymbolNode())
+ {
+ const TVariable *initializerVariable = &initializer->getAsSymbolNode()->variable();
+ if (mVariableMap.count(initializerVariable) > 0)
+ {
+ initializer = mVariableMap[initializerVariable]->deepCopy();
+ }
+ }
+ else
+ {
+ initializer->traverse(this);
+ }
+ }
+
+ ASSERT(asSymbol && asSymbol->variable().symbolType() != SymbolType::Empty);
+
+ TType *newType = new TType(structure, false);
+ newType->setQualifier(asSymbol->getType().getQualifier());
+ newType->makeArrays(asSymbol->getType().getArraySizes());
+
+ TVariable *replacementVar = new TVariable(mSymbolTable, asSymbol->getName(), newType,
+ asSymbol->variable().symbolType());
+ TIntermSymbol *replacementSymbol = new TIntermSymbol(replacementVar);
+ TIntermTyped *replacement = replacementSymbol;
+ if (initializer)
+ {
+ replacement = new TIntermBinary(EOpInitialize, replacement, initializer);
+ }
+
+ TIntermDeclaration *replacementDeclaration = new TIntermDeclaration;
+ replacementDeclaration->appendDeclarator(replacement);
+ replacementDeclaration->setLine(declarator->getLine());
+ replacementDeclarations->push_back(replacementDeclaration);
+
+ mVariableMap[&asSymbol->variable()] = replacementSymbol;
+}
+} // namespace
+
+bool SeparateDeclarations(TCompiler *compiler, TIntermNode *root, TSymbolTable *symbolTable)
+{
+ return SeparateDeclarationsTraverser::apply(compiler, root, symbolTable);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateDeclarations.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateDeclarations.h
new file mode 100644
index 0000000000..5f55162ef4
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateDeclarations.h
@@ -0,0 +1,32 @@
+//
+// Copyright 2002 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.
+//
+// The SeparateDeclarations function processes declarations, so that in the end each declaration
+// contains only one declarator.
+// This is useful as an intermediate step when initialization needs to be separated from
+// declaration, or when things need to be unfolded out of the initializer.
+// Example:
+// int a[1] = int[1](1), b[1] = int[1](2);
+// gets transformed when run through this class into the AST equivalent of:
+// int a[1] = int[1](1);
+// int b[1] = int[1](2);
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_SEPARATEDECLARATIONS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_SEPARATEDECLARATIONS_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermNode;
+class TSymbolTable;
+
+[[nodiscard]] bool SeparateDeclarations(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_SEPARATEDECLARATIONS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateStructFromUniformDeclarations.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateStructFromUniformDeclarations.cpp
new file mode 100644
index 0000000000..fb3f4ba1c1
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateStructFromUniformDeclarations.cpp
@@ -0,0 +1,115 @@
+//
+// Copyright 2018 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.
+//
+// SeparateStructFromUniformDeclarations: Separate struct declarations from uniform declarations.
+//
+
+#include "compiler/translator/tree_ops/SeparateStructFromUniformDeclarations.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/tree_util/ReplaceVariable.h"
+
+namespace sh
+{
+namespace
+{
+// This traverser translates embedded uniform structs into a specifier and declaration.
+// This makes the declarations easier to move into uniform blocks.
+class Traverser : public TIntermTraverser
+{
+ public:
+ explicit Traverser(TSymbolTable *symbolTable)
+ : TIntermTraverser(true, false, false, symbolTable)
+ {}
+
+ bool visitDeclaration(Visit visit, TIntermDeclaration *decl) override
+ {
+ ASSERT(visit == PreVisit);
+
+ if (!mInGlobalScope)
+ {
+ return true;
+ }
+
+ const TIntermSequence &sequence = *(decl->getSequence());
+ ASSERT(sequence.size() == 1);
+ TIntermTyped *declarator = sequence.front()->getAsTyped();
+ const TType &type = declarator->getType();
+
+ if (type.isStructSpecifier() && type.getQualifier() == EvqUniform)
+ {
+ doReplacement(decl, declarator, type);
+ return false;
+ }
+
+ return true;
+ }
+
+ void visitSymbol(TIntermSymbol *symbol) override
+ {
+ const TVariable *variable = &symbol->variable();
+ if (mVariableMap.count(variable) > 0)
+ {
+ queueAccessChainReplacement(mVariableMap[variable]->deepCopy());
+ }
+ }
+
+ private:
+ void doReplacement(TIntermDeclaration *decl, TIntermTyped *declarator, const TType &oldType)
+ {
+ const TStructure *structure = oldType.getStruct();
+ if (structure->symbolType() == SymbolType::Empty)
+ {
+ // Handle nameless structs: uniform struct { ... } variable;
+ structure = new TStructure(mSymbolTable, kEmptyImmutableString, &structure->fields(),
+ SymbolType::AngleInternal);
+ }
+ TType *namedType = new TType(structure, true);
+ namedType->setQualifier(EvqGlobal);
+
+ TVariable *structVariable =
+ new TVariable(mSymbolTable, kEmptyImmutableString, namedType, SymbolType::Empty);
+ TIntermSymbol *structDeclarator = new TIntermSymbol(structVariable);
+ TIntermDeclaration *structDeclaration = new TIntermDeclaration;
+ structDeclaration->appendDeclarator(structDeclarator);
+
+ TIntermSequence newSequence;
+ newSequence.push_back(structDeclaration);
+
+ // Redeclare the uniform with the (potentially) new struct type
+ TIntermSymbol *asSymbol = declarator->getAsSymbolNode();
+ ASSERT(asSymbol && asSymbol->variable().symbolType() != SymbolType::Empty);
+
+ TIntermDeclaration *namedDecl = new TIntermDeclaration;
+ TType *uniformType = new TType(structure, false);
+ uniformType->setQualifier(EvqUniform);
+ uniformType->makeArrays(oldType.getArraySizes());
+
+ TVariable *newVar = new TVariable(mSymbolTable, asSymbol->getName(), uniformType,
+ asSymbol->variable().symbolType());
+ TIntermSymbol *newSymbol = new TIntermSymbol(newVar);
+ namedDecl->appendDeclarator(newSymbol);
+
+ newSequence.push_back(namedDecl);
+
+ mVariableMap[&asSymbol->variable()] = newSymbol;
+
+ mMultiReplacements.emplace_back(getParentNode()->getAsBlock(), decl,
+ std::move(newSequence));
+ }
+
+ VariableReplacementMap mVariableMap;
+};
+} // anonymous namespace
+
+bool SeparateStructFromUniformDeclarations(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable)
+{
+ Traverser separateStructDecls(symbolTable);
+ root->traverse(&separateStructDecls);
+ return separateStructDecls.updateTree(compiler, root);
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateStructFromUniformDeclarations.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateStructFromUniformDeclarations.h
new file mode 100644
index 0000000000..424a742e54
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/SeparateStructFromUniformDeclarations.h
@@ -0,0 +1,39 @@
+//
+// Copyright 2018 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.
+//
+// SeparateStructFromUniformDeclarations: Separate struct declarations from uniform declarations.
+// It necessarily gives nameless uniform structs internal names.
+//
+// For example:
+// uniform struct { int a; } uni;
+// becomes:
+// struct s1 { int a; };
+// uniform s1 uni;
+//
+// And:
+// uniform struct S { int a; } uni;
+// becomes:
+// struct S { int a; };
+// uniform S uni;
+//
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_SEPARATESTRUCTFROMUNIFORMDECLARATIONS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_SEPARATESTRUCTFROMUNIFORMDECLARATIONS_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+[[nodiscard]] bool SeparateStructFromUniformDeclarations(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_SEPARATESTRUCTFROMUNIFORMDECLARATIONS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/SimplifyLoopConditions.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/SimplifyLoopConditions.cpp
new file mode 100644
index 0000000000..c6a3e0b9ee
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/SimplifyLoopConditions.cpp
@@ -0,0 +1,499 @@
+//
+// 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.
+//
+// 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/tree_ops/SimplifyLoopConditions.h"
+
+#include "compiler/translator/StaticType.h"
+#include "compiler/translator/tree_util/IntermNodePatternMatcher.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+struct LoopInfo
+{
+ const TVariable *conditionVariable = nullptr;
+ TIntermTyped *condition = nullptr;
+ TIntermTyped *expression = nullptr;
+};
+
+class SimplifyLoopConditionsTraverser : public TLValueTrackingTraverser
+{
+ public:
+ SimplifyLoopConditionsTraverser(const IntermNodePatternMatcher *conditionsToSimplify,
+ TSymbolTable *symbolTable);
+
+ void traverseLoop(TIntermLoop *node) override;
+
+ bool visitUnary(Visit visit, TIntermUnary *node) override;
+ bool visitBinary(Visit visit, TIntermBinary *node) override;
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override;
+ bool visitTernary(Visit visit, TIntermTernary *node) override;
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
+ bool visitBranch(Visit visit, TIntermBranch *node) override;
+
+ bool foundLoopToChange() const { return mFoundLoopToChange; }
+
+ protected:
+ // Marked to true once an operation that needs to be hoisted out of a loop expression has been
+ // found.
+ bool mFoundLoopToChange;
+ bool mInsideLoopInitConditionOrExpression;
+ const IntermNodePatternMatcher *mConditionsToSimplify;
+
+ private:
+ LoopInfo mLoop;
+};
+
+SimplifyLoopConditionsTraverser::SimplifyLoopConditionsTraverser(
+ const IntermNodePatternMatcher *conditionsToSimplify,
+ TSymbolTable *symbolTable)
+ : TLValueTrackingTraverser(true, false, false, symbolTable),
+ mFoundLoopToChange(false),
+ mInsideLoopInitConditionOrExpression(false),
+ mConditionsToSimplify(conditionsToSimplify)
+{}
+
+// If we're inside a loop initialization, 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
+// transformed.
+// If we're not inside loop initialization, condition, or expression, we only need to traverse nodes
+// that may contain loops.
+
+bool SimplifyLoopConditionsTraverser::visitUnary(Visit visit, TIntermUnary *node)
+{
+ if (!mInsideLoopInitConditionOrExpression)
+ return false;
+
+ if (mFoundLoopToChange)
+ return false; // Already decided to change this loop.
+
+ ASSERT(mConditionsToSimplify);
+ mFoundLoopToChange = mConditionsToSimplify->match(node);
+ return !mFoundLoopToChange;
+}
+
+bool SimplifyLoopConditionsTraverser::visitBinary(Visit visit, TIntermBinary *node)
+{
+ if (!mInsideLoopInitConditionOrExpression)
+ return false;
+
+ if (mFoundLoopToChange)
+ return false; // Already decided to change this loop.
+
+ ASSERT(mConditionsToSimplify);
+ mFoundLoopToChange =
+ mConditionsToSimplify->match(node, getParentNode(), isLValueRequiredHere());
+ return !mFoundLoopToChange;
+}
+
+bool SimplifyLoopConditionsTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
+{
+ if (!mInsideLoopInitConditionOrExpression)
+ return false;
+
+ if (mFoundLoopToChange)
+ return false; // Already decided to change this loop.
+
+ ASSERT(mConditionsToSimplify);
+ mFoundLoopToChange = mConditionsToSimplify->match(node, getParentNode());
+ return !mFoundLoopToChange;
+}
+
+bool SimplifyLoopConditionsTraverser::visitTernary(Visit visit, TIntermTernary *node)
+{
+ if (!mInsideLoopInitConditionOrExpression)
+ return false;
+
+ if (mFoundLoopToChange)
+ return false; // Already decided to change this loop.
+
+ ASSERT(mConditionsToSimplify);
+ mFoundLoopToChange = mConditionsToSimplify->match(node);
+ return !mFoundLoopToChange;
+}
+
+bool SimplifyLoopConditionsTraverser::visitDeclaration(Visit visit, TIntermDeclaration *node)
+{
+ if (!mInsideLoopInitConditionOrExpression)
+ return false;
+
+ if (mFoundLoopToChange)
+ return false; // Already decided to change this loop.
+
+ ASSERT(mConditionsToSimplify);
+ mFoundLoopToChange = mConditionsToSimplify->match(node);
+ return !mFoundLoopToChange;
+}
+
+bool SimplifyLoopConditionsTraverser::visitBranch(Visit visit, TIntermBranch *node)
+{
+ if (node->getFlowOp() == EOpContinue && (mLoop.condition || mLoop.expression))
+ {
+ TIntermBlock *parent = getParentNode()->getAsBlock();
+ ASSERT(parent);
+ TIntermSequence seq;
+ if (mLoop.expression)
+ {
+ seq.push_back(mLoop.expression->deepCopy());
+ }
+ if (mLoop.condition)
+ {
+ ASSERT(mLoop.conditionVariable);
+ seq.push_back(
+ CreateTempAssignmentNode(mLoop.conditionVariable, mLoop.condition->deepCopy()));
+ }
+ seq.push_back(node);
+ mMultiReplacements.push_back(NodeReplaceWithMultipleEntry(parent, node, std::move(seq)));
+ }
+
+ return true;
+}
+
+TIntermBlock *CreateFromBody(TIntermLoop *node, bool *bodyEndsInBranchOut)
+{
+ TIntermBlock *newBody = new TIntermBlock();
+ *bodyEndsInBranchOut = false;
+
+ TIntermBlock *nodeBody = node->getBody();
+ if (nodeBody != nullptr)
+ {
+ newBody->getSequence()->push_back(nodeBody);
+ *bodyEndsInBranchOut = EndsInBranch(nodeBody);
+ }
+ return newBody;
+}
+
+void SimplifyLoopConditionsTraverser::traverseLoop(TIntermLoop *node)
+{
+ // Mark that we're inside a loop condition or expression, and determine if the loop needs to be
+ // transformed.
+
+ ScopedNodeInTraversalPath addToPath(this, node);
+
+ mInsideLoopInitConditionOrExpression = true;
+ mFoundLoopToChange = !mConditionsToSimplify;
+
+ if (!mFoundLoopToChange && node->getInit())
+ {
+ node->getInit()->traverse(this);
+ }
+
+ if (!mFoundLoopToChange && node->getCondition())
+ {
+ node->getCondition()->traverse(this);
+ }
+
+ if (!mFoundLoopToChange && node->getExpression())
+ {
+ node->getExpression()->traverse(this);
+ }
+
+ mInsideLoopInitConditionOrExpression = false;
+
+ const LoopInfo prevLoop = mLoop;
+
+ if (mFoundLoopToChange)
+ {
+ const TType *boolType = StaticType::Get<EbtBool, EbpUndefined, EvqTemporary, 1, 1>();
+ mLoop.conditionVariable = CreateTempVariable(mSymbolTable, boolType);
+ mLoop.condition = node->getCondition();
+ mLoop.expression = node->getExpression();
+
+ // Replace the loop condition with a boolean variable that's updated on each iteration.
+ TLoopType loopType = node->getType();
+ if (loopType == ELoopWhile)
+ {
+ ASSERT(!mLoop.expression);
+
+ if (mLoop.condition->getAsSymbolNode())
+ {
+ // Mask continue statement condition variable update.
+ mLoop.condition = nullptr;
+ }
+ else if (mLoop.condition->getAsConstantUnion())
+ {
+ // Transform:
+ // while (expr) { body; }
+ // into
+ // bool s0 = expr;
+ // while (s0) { body; }
+ TIntermDeclaration *tempInitDeclaration =
+ CreateTempInitDeclarationNode(mLoop.conditionVariable, mLoop.condition);
+ insertStatementInParentBlock(tempInitDeclaration);
+
+ node->setCondition(CreateTempSymbolNode(mLoop.conditionVariable));
+
+ // Mask continue statement condition variable update.
+ mLoop.condition = nullptr;
+ }
+ else
+ {
+ // Transform:
+ // while (expr) { body; }
+ // into
+ // bool s0 = expr;
+ // while (s0) { { body; } s0 = expr; }
+ //
+ // Local case statements are transformed into:
+ // s0 = expr; continue;
+ TIntermDeclaration *tempInitDeclaration =
+ CreateTempInitDeclarationNode(mLoop.conditionVariable, mLoop.condition);
+ insertStatementInParentBlock(tempInitDeclaration);
+
+ bool bodyEndsInBranch;
+ TIntermBlock *newBody = CreateFromBody(node, &bodyEndsInBranch);
+ if (!bodyEndsInBranch)
+ {
+ newBody->getSequence()->push_back(CreateTempAssignmentNode(
+ mLoop.conditionVariable, mLoop.condition->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 - the new body will still be
+ // traversed, but that won't create any problems.
+ node->setBody(newBody);
+ node->setCondition(CreateTempSymbolNode(mLoop.conditionVariable));
+ }
+ }
+ else if (loopType == ELoopDoWhile)
+ {
+ ASSERT(!mLoop.expression);
+
+ if (mLoop.condition->getAsSymbolNode())
+ {
+ // Mask continue statement condition variable update.
+ mLoop.condition = nullptr;
+ }
+ else if (mLoop.condition->getAsConstantUnion())
+ {
+ // Transform:
+ // do {
+ // body;
+ // } while (expr);
+ // into
+ // bool s0 = expr;
+ // do {
+ // body;
+ // } while (s0);
+ TIntermDeclaration *tempInitDeclaration =
+ CreateTempInitDeclarationNode(mLoop.conditionVariable, mLoop.condition);
+ insertStatementInParentBlock(tempInitDeclaration);
+
+ node->setCondition(CreateTempSymbolNode(mLoop.conditionVariable));
+
+ // Mask continue statement condition variable update.
+ mLoop.condition = nullptr;
+ }
+ else
+ {
+ // Transform:
+ // do {
+ // body;
+ // } while (expr);
+ // into
+ // bool s0;
+ // do {
+ // { body; }
+ // s0 = expr;
+ // } while (s0);
+ // Local case statements are transformed into:
+ // s0 = expr; continue;
+ TIntermDeclaration *tempInitDeclaration =
+ CreateTempDeclarationNode(mLoop.conditionVariable);
+ insertStatementInParentBlock(tempInitDeclaration);
+
+ bool bodyEndsInBranch;
+ TIntermBlock *newBody = CreateFromBody(node, &bodyEndsInBranch);
+ if (!bodyEndsInBranch)
+ {
+ newBody->getSequence()->push_back(
+ CreateTempAssignmentNode(mLoop.conditionVariable, mLoop.condition));
+ }
+
+ // Can't use queueReplacement to replace old body, since it may have been nullptr.
+ // It's safe to do the replacements in place here - the new body will still be
+ // traversed, but that won't create any problems.
+ node->setBody(newBody);
+ node->setCondition(CreateTempSymbolNode(mLoop.conditionVariable));
+ }
+ }
+ else if (loopType == ELoopFor)
+ {
+ if (!mLoop.condition)
+ {
+ mLoop.condition = CreateBoolNode(true);
+ }
+
+ TIntermLoop *whileLoop;
+ TIntermBlock *loopScope = new TIntermBlock();
+ TIntermSequence *loopScopeSequence = loopScope->getSequence();
+
+ // Insert "init;"
+ if (node->getInit())
+ {
+ loopScopeSequence->push_back(node->getInit());
+ }
+
+ if (mLoop.condition->getAsSymbolNode())
+ {
+ // Move the loop condition inside the loop.
+ // Transform:
+ // for (init; expr; exprB) { body; }
+ // into
+ // {
+ // init;
+ // while (expr) {
+ // { body; }
+ // exprB;
+ // }
+ // }
+ //
+ // Local case statements are transformed into:
+ // exprB; continue;
+
+ // Insert "{ body; }" in the while loop
+ bool bodyEndsInBranch;
+ TIntermBlock *whileLoopBody = CreateFromBody(node, &bodyEndsInBranch);
+ // Insert "exprB;" in the while loop
+ if (!bodyEndsInBranch && node->getExpression())
+ {
+ whileLoopBody->getSequence()->push_back(node->getExpression());
+ }
+ // Create "while(expr) { whileLoopBody }"
+ whileLoop =
+ new TIntermLoop(ELoopWhile, nullptr, mLoop.condition, nullptr, whileLoopBody);
+
+ // Mask continue statement condition variable update.
+ mLoop.condition = nullptr;
+ }
+ else if (mLoop.condition->getAsConstantUnion())
+ {
+ // Move the loop condition inside the loop.
+ // Transform:
+ // for (init; expr; exprB) { body; }
+ // into
+ // {
+ // init;
+ // bool s0 = expr;
+ // while (s0) {
+ // { body; }
+ // exprB;
+ // }
+ // }
+ //
+ // Local case statements are transformed into:
+ // exprB; continue;
+
+ // Insert "bool s0 = expr;"
+ loopScopeSequence->push_back(
+ CreateTempInitDeclarationNode(mLoop.conditionVariable, mLoop.condition));
+ // Insert "{ body; }" in the while loop
+ bool bodyEndsInBranch;
+ TIntermBlock *whileLoopBody = CreateFromBody(node, &bodyEndsInBranch);
+ // Insert "exprB;" in the while loop
+ if (!bodyEndsInBranch && node->getExpression())
+ {
+ whileLoopBody->getSequence()->push_back(node->getExpression());
+ }
+ // Create "while(s0) { whileLoopBody }"
+ whileLoop = new TIntermLoop(ELoopWhile, nullptr,
+ CreateTempSymbolNode(mLoop.conditionVariable), nullptr,
+ whileLoopBody);
+
+ // Mask continue statement condition variable update.
+ mLoop.condition = nullptr;
+ }
+ else
+ {
+ // Move the loop condition inside the loop.
+ // Transform:
+ // for (init; expr; exprB) { body; }
+ // into
+ // {
+ // init;
+ // bool s0 = expr;
+ // while (s0) {
+ // { body; }
+ // exprB;
+ // s0 = expr;
+ // }
+ // }
+ //
+ // Local case statements are transformed into:
+ // exprB; s0 = expr; continue;
+
+ // Insert "bool s0 = expr;"
+ loopScopeSequence->push_back(
+ CreateTempInitDeclarationNode(mLoop.conditionVariable, mLoop.condition));
+ // Insert "{ body; }" in the while loop
+ bool bodyEndsInBranch;
+ TIntermBlock *whileLoopBody = CreateFromBody(node, &bodyEndsInBranch);
+ // Insert "exprB;" in the while loop
+ if (!bodyEndsInBranch && node->getExpression())
+ {
+ whileLoopBody->getSequence()->push_back(node->getExpression());
+ }
+ // Insert "s0 = expr;" in the while loop
+ if (!bodyEndsInBranch)
+ {
+ whileLoopBody->getSequence()->push_back(CreateTempAssignmentNode(
+ mLoop.conditionVariable, mLoop.condition->deepCopy()));
+ }
+ // Create "while(s0) { whileLoopBody }"
+ whileLoop = new TIntermLoop(ELoopWhile, nullptr,
+ CreateTempSymbolNode(mLoop.conditionVariable), nullptr,
+ whileLoopBody);
+ }
+
+ loopScope->getSequence()->push_back(whileLoop);
+ queueReplacement(loopScope, OriginalNode::IS_DROPPED);
+
+ // After this the old body node will be traversed and loops inside it may be
+ // transformed. This is fine, since the old body node will still be in the AST after
+ // the transformation that's queued here, and transforming loops inside it doesn't
+ // need to know the exact post-transform path to it.
+ }
+ }
+
+ mFoundLoopToChange = false;
+
+ // We traverse the body of the loop even if the loop is transformed.
+ if (node->getBody())
+ node->getBody()->traverse(this);
+
+ mLoop = prevLoop;
+}
+
+} // namespace
+
+bool SimplifyLoopConditions(TCompiler *compiler, TIntermNode *root, TSymbolTable *symbolTable)
+{
+ SimplifyLoopConditionsTraverser traverser(nullptr, symbolTable);
+ root->traverse(&traverser);
+ return traverser.updateTree(compiler, root);
+}
+
+bool SimplifyLoopConditions(TCompiler *compiler,
+ TIntermNode *root,
+ unsigned int conditionsToSimplifyMask,
+ TSymbolTable *symbolTable)
+{
+ IntermNodePatternMatcher conditionsToSimplify(conditionsToSimplifyMask);
+ SimplifyLoopConditionsTraverser traverser(&conditionsToSimplify, symbolTable);
+ root->traverse(&traverser);
+ return traverser.updateTree(compiler, root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/SimplifyLoopConditions.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/SimplifyLoopConditions.h
new file mode 100644
index 0000000000..2a554c019d
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/SimplifyLoopConditions.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.
+//
+// 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_TREEOPS_SIMPLIFYLOOPCONDITIONS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_SIMPLIFYLOOPCONDITIONS_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermNode;
+class TSymbolTable;
+
+[[nodiscard]] bool SimplifyLoopConditions(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable);
+
+[[nodiscard]] bool SimplifyLoopConditions(TCompiler *compiler,
+ TIntermNode *root,
+ unsigned int conditionsToSimplify,
+ TSymbolTable *symbolTable);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_SIMPLIFYLOOPCONDITIONS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/SplitSequenceOperator.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/SplitSequenceOperator.cpp
new file mode 100644
index 0000000000..45985954b0
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/SplitSequenceOperator.cpp
@@ -0,0 +1,173 @@
+//
+// 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.
+//
+// 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/tree_ops/SplitSequenceOperator.h"
+
+#include "compiler/translator/tree_util/IntermNodePatternMatcher.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class SplitSequenceOperatorTraverser : public TLValueTrackingTraverser
+{
+ public:
+ SplitSequenceOperatorTraverser(unsigned int patternsToSplitMask, TSymbolTable *symbolTable);
+
+ bool visitUnary(Visit visit, TIntermUnary *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 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,
+ TSymbolTable *symbolTable)
+ : TLValueTrackingTraverser(true, false, true, symbolTable),
+ mFoundExpressionToSplit(false),
+ mInsideSequenceOperator(0),
+ mPatternToSplitMatcher(patternsToSplitMask)
+{}
+
+void SplitSequenceOperatorTraverser::nextIteration()
+{
+ mFoundExpressionToSplit = false;
+ mInsideSequenceOperator = 0;
+}
+
+bool SplitSequenceOperatorTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
+{
+ 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::visitUnary(Visit visit, TIntermUnary *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;
+}
+
+bool SplitSequenceOperatorTraverser::visitBinary(Visit visit, TIntermBinary *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 the left side operand into a separate statement in the parent block.
+ TIntermSequence insertions;
+ insertions.push_back(node->getLeft());
+ insertStatementsInParentBlock(insertions);
+ // Replace the comma node with its right side operand.
+ queueReplacement(node->getRight(), 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(), isLValueRequiredHere());
+ 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
+
+bool SplitSequenceOperator(TCompiler *compiler,
+ TIntermNode *root,
+ int patternsToSplitMask,
+ TSymbolTable *symbolTable)
+{
+ SplitSequenceOperatorTraverser traverser(patternsToSplitMask, symbolTable);
+ // Separate one expression at a time, and reset the traverser between iterations.
+ do
+ {
+ traverser.nextIteration();
+ root->traverse(&traverser);
+ if (traverser.foundExpressionToSplit())
+ {
+ if (!traverser.updateTree(compiler, root))
+ {
+ return false;
+ }
+ }
+ } while (traverser.foundExpressionToSplit());
+
+ return true;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/SplitSequenceOperator.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/SplitSequenceOperator.h
new file mode 100644
index 0000000000..2a9f09a1f2
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/SplitSequenceOperator.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.
+//
+// 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_TREEOPS_SPLITSEQUENCEOPERATOR_H_
+#define COMPILER_TRANSLATOR_TREEOPS_SPLITSEQUENCEOPERATOR_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermNode;
+class TSymbolTable;
+
+[[nodiscard]] bool SplitSequenceOperator(TCompiler *compiler,
+ TIntermNode *root,
+ int patternsToSplitMask,
+ TSymbolTable *symbolTable);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_SPLITSEQUENCEOPERATOR_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/AddAndTrueToLoopCondition.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/AddAndTrueToLoopCondition.cpp
new file mode 100644
index 0000000000..36e426f8e1
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/AddAndTrueToLoopCondition.cpp
@@ -0,0 +1,60 @@
+//
+// 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.
+//
+
+#include "compiler/translator/tree_ops/apple/AddAndTrueToLoopCondition.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.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.
+ TIntermTyped *trueValue = CreateBoolNode(true);
+
+ // CONDITION && true.
+ TIntermBinary *andOp = new TIntermBinary(EOpLogicalAnd, loop->getCondition(), trueValue);
+ loop->setCondition(andOp);
+
+ return true;
+ }
+};
+
+} // anonymous namespace
+
+bool AddAndTrueToLoopCondition(TCompiler *compiler, TIntermNode *root)
+{
+ AddAndTrueToLoopConditionTraverser traverser;
+ root->traverse(&traverser);
+ return compiler->validateAST(root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/AddAndTrueToLoopCondition.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/AddAndTrueToLoopCondition.h
new file mode 100644
index 0000000000..d23158e81a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/AddAndTrueToLoopCondition.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.
+//
+
+// Rewrite condition in for and while loops to work around driver bug on Intel Mac.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_APPLE_ADDANDTRUETOLOOPCONDITION_H_
+#define COMPILER_TRANSLATOR_TREEOPS_APPLE_ADDANDTRUETOLOOPCONDITION_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermNode;
+
+#if defined(ANGLE_ENABLE_GLSL) && defined(ANGLE_ENABLE_APPLE_WORKAROUNDS)
+[[nodiscard]] bool AddAndTrueToLoopCondition(TCompiler *compiler, TIntermNode *root);
+#else
+[[nodiscard]] ANGLE_INLINE bool AddAndTrueToLoopCondition(TCompiler *compiler, TIntermNode *root)
+{
+ UNREACHABLE();
+ return false;
+}
+#endif
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_APPLE_ADDANDTRUETOLOOPCONDITION_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteDoWhile.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteDoWhile.cpp
new file mode 100644
index 0000000000..de322aadab
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteDoWhile.cpp
@@ -0,0 +1,147 @@
+//
+// 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.
+//
+
+// RewriteDoWhile.cpp: rewrites do-while loops using another equivalent
+// construct.
+
+#include "compiler/translator/tree_ops/apple/RewriteDoWhile.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/StaticType.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+// An AST traverser that rewrites loops of the form
+// do {
+// CODE;
+// } while (CONDITION)
+//
+// to loops of the form
+// bool temp = false;
+// while (true) {
+// if (temp) {
+// if (!CONDITION) {
+// break;
+// }
+// }
+// temp = true;
+// CODE;
+// }
+//
+// The reason we don't use a simpler form, with for example just (temp && !CONDITION) in the
+// while condition, is that short-circuit is often badly supported by driver shader compiler.
+// The double if has the same effect, but forces shader compilers to behave.
+//
+// TODO(cwallez) when UnfoldShortCircuitIntoIf handles loops correctly, revisit this as we might
+// be able to use while (temp || CONDITION) with temp initially set to true then run
+// UnfoldShortCircuitIntoIf
+class DoWhileRewriter : public TIntermTraverser
+{
+ public:
+ DoWhileRewriter(TSymbolTable *symbolTable) : TIntermTraverser(true, false, false, symbolTable)
+ {}
+
+ bool visitBlock(Visit, TIntermBlock *node) override
+ {
+ // A well-formed AST can only have do-while inside TIntermBlock. By doing a prefix traversal
+ // we are able to replace the do-while in the sequence directly as the content of the
+ // do-while will be traversed later.
+
+ TIntermSequence *statements = node->getSequence();
+
+ // The statements vector will have new statements inserted when we encounter a do-while,
+ // which prevents us from using a range-based for loop. Using the usual i++ works, as
+ // the (two) new statements inserted replace the statement at the current position.
+ for (size_t i = 0; i < statements->size(); i++)
+ {
+ TIntermNode *statement = (*statements)[i];
+ TIntermLoop *loop = statement->getAsLoopNode();
+
+ if (loop == nullptr || loop->getType() != ELoopDoWhile)
+ {
+ continue;
+ }
+
+ // Found a loop to change.
+ const TType *boolType = StaticType::Get<EbtBool, EbpUndefined, EvqTemporary, 1, 1>();
+ TVariable *conditionVariable = CreateTempVariable(mSymbolTable, boolType);
+
+ // bool temp = false;
+ TIntermDeclaration *tempDeclaration =
+ CreateTempInitDeclarationNode(conditionVariable, CreateBoolNode(false));
+
+ // temp = true;
+ TIntermBinary *assignTrue =
+ CreateTempAssignmentNode(conditionVariable, CreateBoolNode(true));
+
+ // if (temp) {
+ // if (!CONDITION) {
+ // break;
+ // }
+ // }
+ TIntermIfElse *breakIf = nullptr;
+ {
+ TIntermBranch *breakStatement = new TIntermBranch(EOpBreak, nullptr);
+
+ TIntermBlock *breakBlock = new TIntermBlock();
+ breakBlock->getSequence()->push_back(breakStatement);
+
+ TIntermUnary *negatedCondition =
+ new TIntermUnary(EOpLogicalNot, loop->getCondition(), nullptr);
+
+ TIntermIfElse *innerIf = new TIntermIfElse(negatedCondition, breakBlock, nullptr);
+
+ TIntermBlock *innerIfBlock = new TIntermBlock();
+ innerIfBlock->getSequence()->push_back(innerIf);
+
+ breakIf = new TIntermIfElse(CreateTempSymbolNode(conditionVariable), innerIfBlock,
+ nullptr);
+ }
+
+ // Assemble the replacement loops, reusing the do-while loop's body and inserting our
+ // statements at the front.
+ TIntermLoop *newLoop = nullptr;
+ {
+ TIntermBlock *body = loop->getBody();
+ if (body == nullptr)
+ {
+ body = new TIntermBlock();
+ }
+ auto sequence = body->getSequence();
+ sequence->insert(sequence->begin(), assignTrue);
+ sequence->insert(sequence->begin(), breakIf);
+
+ newLoop = new TIntermLoop(ELoopWhile, nullptr, CreateBoolNode(true), nullptr, body);
+ }
+
+ TIntermSequence replacement;
+ replacement.push_back(tempDeclaration);
+ replacement.push_back(newLoop);
+
+ node->replaceChildNodeWithMultiple(loop, replacement);
+ }
+ return true;
+ }
+};
+
+} // anonymous namespace
+
+bool RewriteDoWhile(TCompiler *compiler, TIntermNode *root, TSymbolTable *symbolTable)
+{
+ DoWhileRewriter rewriter(symbolTable);
+
+ root->traverse(&rewriter);
+
+ return compiler->validateAST(root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteDoWhile.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteDoWhile.h
new file mode 100644
index 0000000000..71bdc8857b
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteDoWhile.h
@@ -0,0 +1,38 @@
+//
+// 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.
+//
+
+// RewriteDoWhile.h: rewrite do-while loops as while loops to work around
+// driver bugs
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_APPLE_REWRITEDOWHILE_H_
+#define COMPILER_TRANSLATOR_TREEOPS_APPLE_REWRITEDOWHILE_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermNode;
+class TSymbolTable;
+
+#if defined(ANGLE_ENABLE_GLSL) && defined(ANGLE_ENABLE_APPLE_WORKAROUNDS)
+[[nodiscard]] bool RewriteDoWhile(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable);
+#else
+[[nodiscard]] ANGLE_INLINE bool RewriteDoWhile(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable)
+{
+ UNREACHABLE();
+ return false;
+}
+#endif
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_APPLE_REWRITEDOWHILE_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteRowMajorMatrices.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteRowMajorMatrices.cpp
new file mode 100644
index 0000000000..49dc11efe2
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteRowMajorMatrices.cpp
@@ -0,0 +1,1595 @@
+//
+// Copyright 2019 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.
+//
+// RewriteRowMajorMatrices: Rewrite row-major matrices as column-major.
+//
+
+#include "compiler/translator/tree_ops/apple/RewriteRowMajorMatrices.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/ImmutableStringBuilder.h"
+#include "compiler/translator/StaticType.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/tree_util/ReplaceVariable.h"
+
+namespace sh
+{
+namespace
+{
+// Only structs with matrices are tracked. If layout(row_major) is applied to a struct that doesn't
+// have matrices, it's silently dropped. This is also used to avoid creating duplicates for inner
+// structs that don't have matrices.
+struct StructConversionData
+{
+ // The converted struct with every matrix transposed.
+ TStructure *convertedStruct = nullptr;
+
+ // The copy-from and copy-to functions copying from a struct to its converted version and back.
+ TFunction *copyFromOriginal = nullptr;
+ TFunction *copyToOriginal = nullptr;
+};
+
+bool DoesFieldContainRowMajorMatrix(const TField *field, bool isBlockRowMajor)
+{
+ TLayoutMatrixPacking matrixPacking = field->type()->getLayoutQualifier().matrixPacking;
+
+ // The field is row major if either explicitly specified as such, or if it inherits it from the
+ // block layout qualifier.
+ if (matrixPacking == EmpColumnMajor || (matrixPacking == EmpUnspecified && !isBlockRowMajor))
+ {
+ return false;
+ }
+
+ // The field is qualified with row_major, but if it's not a matrix or a struct containing
+ // matrices, that's a useless qualifier.
+ const TType *type = field->type();
+ return type->isMatrix() || type->isStructureContainingMatrices();
+}
+
+TField *DuplicateField(const TField *field)
+{
+ return new TField(new TType(*field->type()), field->name(), field->line(), field->symbolType());
+}
+
+void SetColumnMajor(TType *type)
+{
+ TLayoutQualifier layoutQualifier = type->getLayoutQualifier();
+ layoutQualifier.matrixPacking = EmpColumnMajor;
+ type->setLayoutQualifier(layoutQualifier);
+}
+
+TType *TransposeMatrixType(const TType *type)
+{
+ TType *newType = new TType(*type);
+
+ SetColumnMajor(newType);
+
+ newType->setPrimarySize(type->getRows());
+ newType->setSecondarySize(type->getCols());
+
+ return newType;
+}
+
+void CopyArraySizes(const TType *from, TType *to)
+{
+ if (from->isArray())
+ {
+ to->makeArrays(from->getArraySizes());
+ }
+}
+
+// Determine if the node is an index node (array index or struct field selection). For the purposes
+// of this transformation, swizzle nodes are considered index nodes too.
+bool IsIndexNode(TIntermNode *node, TIntermNode *child)
+{
+ if (node->getAsSwizzleNode())
+ {
+ return true;
+ }
+
+ TIntermBinary *binaryNode = node->getAsBinaryNode();
+ if (binaryNode == nullptr || child != binaryNode->getLeft())
+ {
+ return false;
+ }
+
+ TOperator op = binaryNode->getOp();
+
+ return op == EOpIndexDirect || op == EOpIndexDirectInterfaceBlock ||
+ op == EOpIndexDirectStruct || op == EOpIndexIndirect;
+}
+
+TIntermSymbol *CopyToTempVariable(TSymbolTable *symbolTable,
+ TIntermTyped *node,
+ TIntermSequence *prependStatements)
+{
+ TVariable *temp = CreateTempVariable(symbolTable, &node->getType());
+ TIntermDeclaration *tempDecl = CreateTempInitDeclarationNode(temp, node);
+ prependStatements->push_back(tempDecl);
+
+ return new TIntermSymbol(temp);
+}
+
+TIntermAggregate *CreateStructCopyCall(const TFunction *copyFunc, TIntermTyped *expression)
+{
+ TIntermSequence args = {expression};
+ return TIntermAggregate::CreateFunctionCall(*copyFunc, &args);
+}
+
+TIntermTyped *CreateTransposeCall(TSymbolTable *symbolTable, TIntermTyped *expression)
+{
+ TIntermSequence args = {expression};
+ return CreateBuiltInFunctionCallNode("transpose", &args, *symbolTable, 300);
+}
+
+TOperator GetIndex(TSymbolTable *symbolTable,
+ TIntermNode *node,
+ TIntermSequence *indices,
+ TIntermSequence *prependStatements)
+{
+ // Swizzle nodes are converted EOpIndexDirect for simplicity, with one index per swizzle
+ // channel.
+ TIntermSwizzle *asSwizzle = node->getAsSwizzleNode();
+ if (asSwizzle)
+ {
+ for (int channel : asSwizzle->getSwizzleOffsets())
+ {
+ indices->push_back(CreateIndexNode(channel));
+ }
+ return EOpIndexDirect;
+ }
+
+ TIntermBinary *binaryNode = node->getAsBinaryNode();
+ ASSERT(binaryNode);
+
+ TOperator op = binaryNode->getOp();
+ ASSERT(op == EOpIndexDirect || op == EOpIndexDirectInterfaceBlock ||
+ op == EOpIndexDirectStruct || op == EOpIndexIndirect);
+
+ TIntermTyped *rhs = binaryNode->getRight()->deepCopy();
+ if (rhs->getAsConstantUnion() == nullptr)
+ {
+ rhs = CopyToTempVariable(symbolTable, rhs, prependStatements);
+ }
+
+ indices->push_back(rhs);
+ return op;
+}
+
+TIntermTyped *ReplicateIndexNode(TSymbolTable *symbolTable,
+ TIntermNode *node,
+ TIntermTyped *lhs,
+ TIntermSequence *indices)
+{
+ TIntermSwizzle *asSwizzle = node->getAsSwizzleNode();
+ if (asSwizzle)
+ {
+ return new TIntermSwizzle(lhs, asSwizzle->getSwizzleOffsets());
+ }
+
+ TIntermBinary *binaryNode = node->getAsBinaryNode();
+ ASSERT(binaryNode);
+
+ ASSERT(indices->size() == 1);
+ TIntermTyped *rhs = indices->front()->getAsTyped();
+
+ return new TIntermBinary(binaryNode->getOp(), lhs, rhs);
+}
+
+TOperator GetIndexOp(TIntermNode *node)
+{
+ return node->getAsConstantUnion() ? EOpIndexDirect : EOpIndexIndirect;
+}
+
+bool IsConvertedField(TIntermTyped *indexNode,
+ const angle::HashMap<const TField *, bool> &convertedFields)
+{
+ TIntermBinary *asBinary = indexNode->getAsBinaryNode();
+ if (asBinary == nullptr)
+ {
+ return false;
+ }
+
+ if (asBinary->getOp() != EOpIndexDirectInterfaceBlock)
+ {
+ return false;
+ }
+
+ const TInterfaceBlock *interfaceBlock = asBinary->getLeft()->getType().getInterfaceBlock();
+ ASSERT(interfaceBlock);
+
+ TIntermConstantUnion *fieldIndexNode = asBinary->getRight()->getAsConstantUnion();
+ ASSERT(fieldIndexNode);
+ ASSERT(fieldIndexNode->getConstantValue() != nullptr);
+
+ int fieldIndex = fieldIndexNode->getConstantValue()->getIConst();
+ const TField *field = interfaceBlock->fields()[fieldIndex];
+
+ return convertedFields.count(field) > 0 && convertedFields.at(field);
+}
+
+// A helper class to transform expressions of array type. Iterates over every element of the
+// array.
+class TransformArrayHelper
+{
+ public:
+ TransformArrayHelper(TIntermTyped *baseExpression)
+ : mBaseExpression(baseExpression),
+ mBaseExpressionType(baseExpression->getType()),
+ mArrayIndices(mBaseExpressionType.getArraySizes().size(), 0)
+ {}
+
+ TIntermTyped *getNextElement(TIntermTyped *valueExpression, TIntermTyped **valueElementOut)
+ {
+ const TSpan<const unsigned int> &arraySizes = mBaseExpressionType.getArraySizes();
+
+ // If the last index overflows, element enumeration is done.
+ if (mArrayIndices.back() >= arraySizes.back())
+ {
+ return nullptr;
+ }
+
+ TIntermTyped *element = getCurrentElement(mBaseExpression);
+ if (valueExpression)
+ {
+ *valueElementOut = getCurrentElement(valueExpression);
+ }
+
+ incrementIndices(arraySizes);
+ return element;
+ }
+
+ void accumulateForRead(TSymbolTable *symbolTable,
+ TIntermTyped *transformedElement,
+ TIntermSequence *prependStatements)
+ {
+ TIntermTyped *temp = CopyToTempVariable(symbolTable, transformedElement, prependStatements);
+ mReadTransformConstructorArgs.push_back(temp);
+ }
+
+ TIntermTyped *constructReadTransformExpression()
+ {
+ const TSpan<const unsigned int> &baseTypeArraySizes = mBaseExpressionType.getArraySizes();
+ TVector<unsigned int> arraySizes(baseTypeArraySizes.begin(), baseTypeArraySizes.end());
+ TIntermTyped *firstElement = mReadTransformConstructorArgs.front()->getAsTyped();
+ const TType &baseType = firstElement->getType();
+
+ // If N dimensions, acc[0] == size[0] and acc[i] == size[i] * acc[i-1].
+ // The last value is unused, and is not present.
+ TVector<unsigned int> accumulatedArraySizes(arraySizes.size() - 1);
+
+ if (accumulatedArraySizes.size() > 0)
+ {
+ accumulatedArraySizes[0] = arraySizes[0];
+ }
+ for (size_t index = 1; index + 1 < arraySizes.size(); ++index)
+ {
+ accumulatedArraySizes[index] = accumulatedArraySizes[index - 1] * arraySizes[index];
+ }
+
+ return constructReadTransformExpressionHelper(arraySizes, accumulatedArraySizes, baseType,
+ 0);
+ }
+
+ private:
+ TIntermTyped *getCurrentElement(TIntermTyped *expression)
+ {
+ TIntermTyped *element = expression->deepCopy();
+ for (auto it = mArrayIndices.rbegin(); it != mArrayIndices.rend(); ++it)
+ {
+ unsigned int index = *it;
+ element = new TIntermBinary(EOpIndexDirect, element, CreateIndexNode(index));
+ }
+ return element;
+ }
+
+ void incrementIndices(const TSpan<const unsigned int> &arraySizes)
+ {
+ // Assume mArrayIndices is an N digit number, where digit i is in the range
+ // [0, arraySizes[i]). This function increments this number. Last digit is the most
+ // significant digit.
+ for (size_t digitIndex = 0; digitIndex < arraySizes.size(); ++digitIndex)
+ {
+ ++mArrayIndices[digitIndex];
+ if (mArrayIndices[digitIndex] < arraySizes[digitIndex])
+ {
+ break;
+ }
+ if (digitIndex + 1 != arraySizes.size())
+ {
+ // This digit has now overflown and is reset to 0, carry will be added to the next
+ // digit. The most significant digit will keep the overflow though, to make it
+ // clear we have exhausted the range.
+ mArrayIndices[digitIndex] = 0;
+ }
+ }
+ }
+
+ TIntermTyped *constructReadTransformExpressionHelper(
+ const TVector<unsigned int> &arraySizes,
+ const TVector<unsigned int> &accumulatedArraySizes,
+ const TType &baseType,
+ size_t elementsOffset)
+ {
+ ASSERT(!arraySizes.empty());
+
+ TType *transformedType = new TType(baseType);
+ transformedType->makeArrays(arraySizes);
+
+ // If one dimensional, create the constructor with the given elements.
+ if (arraySizes.size() == 1)
+ {
+ ASSERT(accumulatedArraySizes.size() == 0);
+
+ auto sliceStart = mReadTransformConstructorArgs.begin() + elementsOffset;
+ TIntermSequence slice(sliceStart, sliceStart + arraySizes[0]);
+
+ return TIntermAggregate::CreateConstructor(*transformedType, &slice);
+ }
+
+ // If not, create constructors for every column recursively.
+ TVector<unsigned int> subArraySizes(arraySizes.begin(), arraySizes.end() - 1);
+ TVector<unsigned int> subArrayAccumulatedSizes(accumulatedArraySizes.begin(),
+ accumulatedArraySizes.end() - 1);
+
+ TIntermSequence constructorArgs;
+ unsigned int colStride = accumulatedArraySizes.back();
+ for (size_t col = 0; col < arraySizes.back(); ++col)
+ {
+ size_t colElementsOffset = elementsOffset + col * colStride;
+
+ constructorArgs.push_back(constructReadTransformExpressionHelper(
+ subArraySizes, subArrayAccumulatedSizes, baseType, colElementsOffset));
+ }
+
+ return TIntermAggregate::CreateConstructor(*transformedType, &constructorArgs);
+ }
+
+ TIntermTyped *mBaseExpression;
+ const TType &mBaseExpressionType;
+ TVector<unsigned int> mArrayIndices;
+
+ TIntermSequence mReadTransformConstructorArgs;
+};
+
+// Traverser that:
+//
+// 1. Converts |layout(row_major) matCxR M| to |layout(column_major) matRxC Mt|.
+// 2. Converts |layout(row_major) S s| to |layout(column_major) St st|, where S is a struct that
+// contains matrices, and St is a new struct with the transformation in 1 applied to matrix
+// members (recursively).
+// 3. When read from, the following transformations are applied:
+//
+// M -> transpose(Mt)
+// M[c] -> gvecN(Mt[0][c], Mt[1][c], ..., Mt[N-1][c])
+// M[c][r] -> Mt[r][c]
+// M[c].yz -> gvec2(Mt[1][c], Mt[2][c])
+// MArr -> MType[D1]..[DN](transpose(MtArr[0]...[0]), ...)
+// s -> copy_St_to_S(st)
+// sArr -> SType[D1]...[DN](copy_St_to_S(stArr[0]..[0]), ...)
+// (matrix reads through struct are transformed similarly to M)
+//
+// 4. When written to, the following transformations are applied:
+//
+// M = exp -> Mt = transpose(exp)
+// M[c] = exp -> temp = exp
+// Mt[0][c] = temp[0]
+// Mt[1][c] = temp[1]
+// ...
+// Mt[N-1][c] = temp[N-1]
+// M[c][r] = exp -> Mt[r][c] = exp
+// M[c].yz = exp -> temp = exp
+// Mt[1][c] = temp[0]
+// Mt[2][c] = temp[1]
+// MArr = exp -> temp = exp
+// Mt = MtType[D1]..[DN](temp([0]...[0]), ...)
+// s = exp -> st = copy_S_to_St(exp)
+// sArr = exp -> temp = exp
+// St = StType[D1]...[DN](copy_S_to_St(temp[0]..[0]), ...)
+// (matrix writes through struct are transformed similarly to M)
+//
+// 5. If any of the above is passed to an `inout` parameter, both transformations are applied:
+//
+// f(M[c]) -> temp = gvecN(Mt[0][c], Mt[1][c], ..., Mt[N-1][c])
+// f(temp)
+// Mt[0][c] = temp[0]
+// Mt[1][c] = temp[1]
+// ...
+// Mt[N-1][c] = temp[N-1]
+//
+// f(s) -> temp = copy_St_to_S(st)
+// f(temp)
+// st = copy_S_to_St(temp)
+//
+// If passed to an `out` parameter, the `temp` parameter is simply not initialized.
+//
+// 6. If the expression leading to the matrix or struct has array subscripts, temp values are
+// created for them to avoid duplicating side effects.
+//
+class RewriteRowMajorMatricesTraverser : public TIntermTraverser
+{
+ public:
+ RewriteRowMajorMatricesTraverser(TCompiler *compiler, TSymbolTable *symbolTable)
+ : TIntermTraverser(true, true, true, symbolTable),
+ mCompiler(compiler),
+ mStructMapOut(&mOuterPass.structMap),
+ mInterfaceBlockMap(&mOuterPass.interfaceBlockMap),
+ mInterfaceBlockFieldConvertedIn(mOuterPass.interfaceBlockFieldConverted),
+ mCopyFunctionDefinitionsOut(&mOuterPass.copyFunctionDefinitions),
+ mOuterTraverser(nullptr),
+ mInnerPassRoot(nullptr),
+ mIsProcessingInnerPassSubtree(false)
+ {}
+
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override
+ {
+ // No need to process declarations in inner passes.
+ if (mInnerPassRoot != nullptr)
+ {
+ return true;
+ }
+
+ if (visit != PreVisit)
+ {
+ return true;
+ }
+
+ const TIntermSequence &sequence = *(node->getSequence());
+
+ TIntermTyped *variable = sequence.front()->getAsTyped();
+ const TType &type = variable->getType();
+
+ // If it's a struct declaration that has matrices, remember it. If a row-major instance
+ // of it is created, it will have to be converted.
+ if (type.isStructSpecifier() && type.isStructureContainingMatrices())
+ {
+ const TStructure *structure = type.getStruct();
+ ASSERT(structure);
+
+ ASSERT(mOuterPass.structMap.count(structure) == 0);
+
+ StructConversionData structData;
+ mOuterPass.structMap[structure] = structData;
+
+ return false;
+ }
+
+ // If it's an interface block, it may have to be converted if it contains any row-major
+ // fields.
+ if (type.isInterfaceBlock() && type.getInterfaceBlock()->containsMatrices())
+ {
+ const TInterfaceBlock *block = type.getInterfaceBlock();
+ ASSERT(block);
+ bool isBlockRowMajor = type.getLayoutQualifier().matrixPacking == EmpRowMajor;
+
+ const TFieldList &fields = block->fields();
+ bool anyRowMajor = isBlockRowMajor;
+
+ for (const TField *field : fields)
+ {
+ if (DoesFieldContainRowMajorMatrix(field, isBlockRowMajor))
+ {
+ anyRowMajor = true;
+ break;
+ }
+ }
+
+ if (anyRowMajor)
+ {
+ convertInterfaceBlock(node);
+ }
+
+ return false;
+ }
+
+ return true;
+ }
+
+ void visitSymbol(TIntermSymbol *symbol) override
+ {
+ // If in inner pass, only process if the symbol is under that root.
+ if (mInnerPassRoot != nullptr && !mIsProcessingInnerPassSubtree)
+ {
+ return;
+ }
+
+ const TVariable *variable = &symbol->variable();
+ bool needsRewrite = mInterfaceBlockMap->count(variable) != 0;
+
+ // If it's a field of a nameless interface block, it may still need conversion.
+ if (!needsRewrite)
+ {
+ // Nameless interface block field symbols have the interface block pointer set, but are
+ // not interface blocks.
+ if (symbol->getType().getInterfaceBlock() && !variable->getType().isInterfaceBlock())
+ {
+ needsRewrite = convertNamelessInterfaceBlockField(symbol);
+ }
+ }
+
+ if (needsRewrite)
+ {
+ transformExpression(symbol);
+ }
+ }
+
+ bool visitBinary(Visit visit, TIntermBinary *node) override
+ {
+ if (node == mInnerPassRoot)
+ {
+ // We only want to process the right-hand side of an assignment in inner passes. When
+ // visit is InVisit, the left-hand side is already processed, and the right-hand side is
+ // next. Set a flag to mark this duration.
+ mIsProcessingInnerPassSubtree = visit == InVisit;
+ }
+
+ return true;
+ }
+
+ TIntermSequence *getStructCopyFunctions() { return &mOuterPass.copyFunctionDefinitions; }
+
+ private:
+ typedef angle::HashMap<const TStructure *, StructConversionData> StructMap;
+ typedef angle::HashMap<const TVariable *, TVariable *> InterfaceBlockMap;
+ typedef angle::HashMap<const TField *, bool> InterfaceBlockFieldConverted;
+
+ RewriteRowMajorMatricesTraverser(
+ TSymbolTable *symbolTable,
+ RewriteRowMajorMatricesTraverser *outerTraverser,
+ InterfaceBlockMap *interfaceBlockMap,
+ const InterfaceBlockFieldConverted &interfaceBlockFieldConverted,
+ StructMap *structMap,
+ TIntermSequence *copyFunctionDefinitions,
+ TIntermBinary *innerPassRoot)
+ : TIntermTraverser(true, true, true, symbolTable),
+ mStructMapOut(structMap),
+ mInterfaceBlockMap(interfaceBlockMap),
+ mInterfaceBlockFieldConvertedIn(interfaceBlockFieldConverted),
+ mCopyFunctionDefinitionsOut(copyFunctionDefinitions),
+ mOuterTraverser(outerTraverser),
+ mInnerPassRoot(innerPassRoot),
+ mIsProcessingInnerPassSubtree(false)
+ {}
+
+ void convertInterfaceBlock(TIntermDeclaration *node)
+ {
+ ASSERT(mInnerPassRoot == nullptr);
+
+ const TIntermSequence &sequence = *(node->getSequence());
+
+ TIntermTyped *variableNode = sequence.front()->getAsTyped();
+ const TType &type = variableNode->getType();
+ const TInterfaceBlock *block = type.getInterfaceBlock();
+ ASSERT(block);
+
+ bool isBlockRowMajor = type.getLayoutQualifier().matrixPacking == EmpRowMajor;
+
+ // Recreate the struct with its row-major fields converted to column-major equivalents.
+ TIntermSequence newDeclarations;
+
+ TFieldList *newFields = new TFieldList;
+ for (const TField *field : block->fields())
+ {
+ TField *newField = nullptr;
+
+ if (DoesFieldContainRowMajorMatrix(field, isBlockRowMajor))
+ {
+ newField = convertField(field, &newDeclarations);
+
+ // Remember that this field was converted.
+ mOuterPass.interfaceBlockFieldConverted[field] = true;
+ }
+ else
+ {
+ newField = DuplicateField(field);
+ }
+
+ newFields->push_back(newField);
+ }
+
+ // Create a new interface block with these fields.
+ TLayoutQualifier blockLayoutQualifier = type.getLayoutQualifier();
+ blockLayoutQualifier.matrixPacking = EmpColumnMajor;
+
+ TInterfaceBlock *newInterfaceBlock =
+ new TInterfaceBlock(mSymbolTable, block->name(), newFields, blockLayoutQualifier,
+ block->symbolType(), block->extensions());
+
+ // Create a new declaration with the new type. Declarations are separated at this point,
+ // so there should be only one variable here.
+ ASSERT(sequence.size() == 1);
+
+ TType *newInterfaceBlockType =
+ new TType(newInterfaceBlock, type.getQualifier(), blockLayoutQualifier);
+
+ TIntermDeclaration *newDeclaration = new TIntermDeclaration;
+ const TVariable *variable = &variableNode->getAsSymbolNode()->variable();
+
+ const TType *newType = newInterfaceBlockType;
+ if (type.isArray())
+ {
+ TType *newArrayType = new TType(*newType);
+ CopyArraySizes(&type, newArrayType);
+ newType = newArrayType;
+ }
+
+ // If the interface block variable itself is temp, use an empty name.
+ bool variableIsTemp = variable->symbolType() == SymbolType::Empty;
+ const ImmutableString &variableName =
+ variableIsTemp ? kEmptyImmutableString : variable->name();
+
+ TVariable *newVariable = new TVariable(mSymbolTable, variableName, newType,
+ variable->symbolType(), variable->extensions());
+
+ newDeclaration->appendDeclarator(new TIntermSymbol(newVariable));
+
+ mOuterPass.interfaceBlockMap[variable] = newVariable;
+
+ newDeclarations.push_back(newDeclaration);
+
+ // Replace the interface block definition with the new one, prepending any new struct
+ // definitions.
+ mMultiReplacements.emplace_back(getParentNode()->getAsBlock(), node,
+ std::move(newDeclarations));
+ }
+
+ bool convertNamelessInterfaceBlockField(TIntermSymbol *symbol)
+ {
+ const TVariable *variable = &symbol->variable();
+ const TInterfaceBlock *interfaceBlock = symbol->getType().getInterfaceBlock();
+
+ // Find the variable corresponding to this interface block. If the interface block
+ // is not rewritten, or this refers to a field that is not rewritten, there's
+ // nothing to do.
+ for (auto iter : *mInterfaceBlockMap)
+ {
+ // Skip other rewritten nameless interface block fields.
+ if (!iter.first->getType().isInterfaceBlock())
+ {
+ continue;
+ }
+
+ // Skip if this is not a field of this rewritten interface block.
+ if (iter.first->getType().getInterfaceBlock() != interfaceBlock)
+ {
+ continue;
+ }
+
+ const ImmutableString symbolName = symbol->getName();
+
+ // Find which field it is
+ const TVector<TField *> fields = interfaceBlock->fields();
+ const size_t fieldIndex = variable->getType().getInterfaceBlockFieldIndex();
+ ASSERT(fieldIndex < fields.size());
+
+ const TField *field = fields[fieldIndex];
+ ASSERT(field->name() == symbolName);
+
+ // If this field doesn't need a rewrite, there's nothing to do.
+ if (mInterfaceBlockFieldConvertedIn.count(field) == 0 ||
+ !mInterfaceBlockFieldConvertedIn.at(field))
+ {
+ break;
+ }
+
+ // Create a new variable that references the replaced interface block.
+ TType *newType = new TType(variable->getType());
+ newType->setInterfaceBlockField(iter.second->getType().getInterfaceBlock(), fieldIndex);
+
+ TVariable *newVariable = new TVariable(mSymbolTable, variable->name(), newType,
+ variable->symbolType(), variable->extensions());
+
+ (*mInterfaceBlockMap)[variable] = newVariable;
+
+ return true;
+ }
+
+ return false;
+ }
+
+ void convertStruct(const TStructure *structure, TIntermSequence *newDeclarations)
+ {
+ ASSERT(mInnerPassRoot == nullptr);
+
+ ASSERT(mOuterPass.structMap.count(structure) != 0);
+ StructConversionData *structData = &mOuterPass.structMap[structure];
+
+ if (structData->convertedStruct)
+ {
+ return;
+ }
+
+ TFieldList *newFields = new TFieldList;
+ for (const TField *field : structure->fields())
+ {
+ newFields->push_back(convertField(field, newDeclarations));
+ }
+
+ // Create unique names for the converted structs. We can't leave them nameless and have
+ // a name autogenerated similar to temp variables, as nameless structs exist. A fake
+ // variable is created for the sole purpose of generating a temp name.
+ TVariable *newStructTypeName =
+ new TVariable(mSymbolTable, kEmptyImmutableString,
+ StaticType::GetBasic<EbtUInt, EbpUndefined>(), SymbolType::Empty);
+
+ TStructure *newStruct = new TStructure(mSymbolTable, newStructTypeName->name(), newFields,
+ SymbolType::AngleInternal);
+ TType *newType = new TType(newStruct, true);
+ TVariable *newStructVar =
+ new TVariable(mSymbolTable, kEmptyImmutableString, newType, SymbolType::Empty);
+
+ TIntermDeclaration *structDecl = new TIntermDeclaration;
+ structDecl->appendDeclarator(new TIntermSymbol(newStructVar));
+
+ newDeclarations->push_back(structDecl);
+
+ structData->convertedStruct = newStruct;
+ }
+
+ TField *convertField(const TField *field, TIntermSequence *newDeclarations)
+ {
+ ASSERT(mInnerPassRoot == nullptr);
+
+ TField *newField = nullptr;
+
+ const TType *fieldType = field->type();
+ TType *newType = nullptr;
+
+ if (fieldType->isStructureContainingMatrices())
+ {
+ // If the field is a struct instance, convert the struct and replace the field
+ // with an instance of the new struct.
+ const TStructure *fieldTypeStruct = fieldType->getStruct();
+ convertStruct(fieldTypeStruct, newDeclarations);
+
+ StructConversionData &structData = mOuterPass.structMap[fieldTypeStruct];
+ newType = new TType(structData.convertedStruct, false);
+ SetColumnMajor(newType);
+ CopyArraySizes(fieldType, newType);
+ }
+ else if (fieldType->isMatrix())
+ {
+ // If the field is a matrix, transpose the matrix and replace the field with
+ // that, removing the matrix packing qualifier.
+ newType = TransposeMatrixType(fieldType);
+ }
+
+ if (newType)
+ {
+ newField = new TField(newType, field->name(), field->line(), field->symbolType());
+ }
+ else
+ {
+ newField = DuplicateField(field);
+ }
+
+ return newField;
+ }
+
+ void determineAccess(TIntermNode *expression,
+ TIntermNode *accessor,
+ bool *isReadOut,
+ bool *isWriteOut)
+ {
+ // If passing to a function, look at whether the parameter is in, out or inout.
+ TIntermAggregate *functionCall = accessor->getAsAggregate();
+
+ if (functionCall)
+ {
+ TIntermSequence *arguments = functionCall->getSequence();
+ for (size_t argIndex = 0; argIndex < arguments->size(); ++argIndex)
+ {
+ if ((*arguments)[argIndex] == expression)
+ {
+ TQualifier qualifier = EvqParamIn;
+
+ // If the aggregate is not a function call, it's a constructor, and so every
+ // argument is an input.
+ const TFunction *function = functionCall->getFunction();
+ if (function)
+ {
+ const TVariable *param = function->getParam(argIndex);
+ qualifier = param->getType().getQualifier();
+ }
+
+ *isReadOut = qualifier != EvqParamOut;
+ *isWriteOut = qualifier == EvqParamOut || qualifier == EvqParamInOut;
+ break;
+ }
+ }
+ return;
+ }
+
+ TIntermBinary *assignment = accessor->getAsBinaryNode();
+ if (assignment && IsAssignment(assignment->getOp()))
+ {
+ // If expression is on the right of assignment, it's being read from.
+ *isReadOut = assignment->getRight() == expression;
+ // If it's on the left of assignment, it's being written to.
+ *isWriteOut = assignment->getLeft() == expression;
+ return;
+ }
+
+ // Any other usage is a read.
+ *isReadOut = true;
+ *isWriteOut = false;
+ }
+
+ void transformExpression(TIntermSymbol *symbol)
+ {
+ // Walk up the parent chain while the nodes are EOpIndex* (whether array indexing or struct
+ // field selection) or swizzle and construct the replacement expression. This traversal can
+ // lead to one of the following possibilities:
+ //
+ // - a.b[N].etc.s (struct, or struct array): copy function should be declared and used,
+ // - a.b[N].etc.M (matrix or matrix array): transpose() should be used,
+ // - a.b[N].etc.M[c] (a column): each element in column needs to be handled separately,
+ // - a.b[N].etc.M[c].yz (multiple elements): similar to whole column, but a subset of
+ // elements,
+ // - a.b[N].etc.M[c][r] (an element): single element to handle.
+ // - a.b[N].etc.x (not struct or matrix): not modified
+ //
+ // primaryIndex will contain c, if any. secondaryIndices will contain {0, ..., R-1}
+ // (if no [r] or swizzle), {r} (if [r]), or {1, 2} (corresponding to .yz) if any.
+ //
+ // In all cases, the base symbol is replaced. |baseExpression| will contain everything up
+ // to (and not including) the last index/swizzle operations, i.e. a.b[N].etc.s/M/x. Any
+ // non constant array subscript is assigned to a temp variable to avoid duplicating side
+ // effects.
+ //
+ // ---
+ //
+ // NOTE that due to the use of insertStatementsInParentBlock, cases like this will be
+ // mistranslated, and this bug is likely present in most transformations that use this
+ // feature:
+ //
+ // if (x == 1 && a.b[x = 2].etc.M = value)
+ //
+ // which will translate to:
+ //
+ // temp = (x = 2)
+ // if (x == 1 && a.b[temp].etc.M = transpose(value))
+ //
+ // See http://anglebug.com/3829.
+ //
+ TIntermTyped *baseExpression =
+ new TIntermSymbol(mInterfaceBlockMap->at(&symbol->variable()));
+ const TStructure *structure = nullptr;
+
+ TIntermNode *primaryIndex = nullptr;
+ TIntermSequence secondaryIndices;
+
+ // In some cases, it is necessary to prepend or append statements. Those are captured in
+ // |prependStatements| and |appendStatements|.
+ TIntermSequence prependStatements;
+ TIntermSequence appendStatements;
+
+ // If the expression is neither a struct or matrix, no modification is necessary.
+ // If it's a struct that doesn't have matrices, again there's no transformation necessary.
+ // If it's an interface block matrix field that didn't need to be transposed, no
+ // transpformation is necessary.
+ //
+ // In all these cases, |baseExpression| contains all of the original expression.
+ //
+ // If the starting symbol itself is a field of a nameless interface block, it needs
+ // conversion if we reach here.
+ bool requiresTransformation = !symbol->getType().isInterfaceBlock();
+
+ uint32_t accessorIndex = 0;
+ TIntermTyped *previousAncestor = symbol;
+ while (IsIndexNode(getAncestorNode(accessorIndex), previousAncestor))
+ {
+ TIntermTyped *ancestor = getAncestorNode(accessorIndex)->getAsTyped();
+ ASSERT(ancestor);
+
+ const TType &previousAncestorType = previousAncestor->getType();
+
+ TIntermSequence indices;
+ TOperator op = GetIndex(mSymbolTable, ancestor, &indices, &prependStatements);
+
+ bool opIsIndex = op == EOpIndexDirect || op == EOpIndexIndirect;
+ bool isArrayIndex = opIsIndex && previousAncestorType.isArray();
+ bool isMatrixIndex = opIsIndex && previousAncestorType.isMatrix();
+
+ // If it's a direct index in a matrix, it's the primary index.
+ bool isMatrixPrimarySubscript = isMatrixIndex && !isArrayIndex;
+ ASSERT(!isMatrixPrimarySubscript ||
+ (primaryIndex == nullptr && secondaryIndices.empty()));
+ // If primary index is seen and the ancestor is still an index, it must be a direct
+ // index as the secondary one. Note that if primaryIndex is set, there can only ever be
+ // one more parent of interest, and that's subscripting the second dimension.
+ bool isMatrixSecondarySubscript = primaryIndex != nullptr;
+ ASSERT(!isMatrixSecondarySubscript || (opIsIndex && !isArrayIndex));
+
+ if (requiresTransformation && isMatrixPrimarySubscript)
+ {
+ ASSERT(indices.size() == 1);
+ primaryIndex = indices.front();
+
+ // Default the secondary indices to include every row. If there's a secondary
+ // subscript provided, it will override this.
+ const uint8_t rows = previousAncestorType.getRows();
+ for (uint8_t r = 0; r < rows; ++r)
+ {
+ secondaryIndices.push_back(CreateIndexNode(r));
+ }
+ }
+ else if (isMatrixSecondarySubscript)
+ {
+ ASSERT(requiresTransformation);
+
+ secondaryIndices = indices;
+
+ // Indices after this point are not interesting. There can't actually be any other
+ // index nodes other than desktop GLSL's swizzles on scalars, like M[1][2].yyy.
+ ++accessorIndex;
+ break;
+ }
+ else
+ {
+ // Replicate the expression otherwise.
+ baseExpression =
+ ReplicateIndexNode(mSymbolTable, ancestor, baseExpression, &indices);
+
+ const TType &ancestorType = ancestor->getType();
+ structure = ancestorType.getStruct();
+
+ requiresTransformation =
+ requiresTransformation ||
+ IsConvertedField(ancestor, mInterfaceBlockFieldConvertedIn);
+
+ // If we reach a point where the expression is neither a matrix-containing struct
+ // nor a matrix, there's no transformation required. This can happen if we decend
+ // through a struct marked with row-major but arrive at a member that doesn't
+ // include a matrix.
+ if (!ancestorType.isMatrix() && !ancestorType.isStructureContainingMatrices())
+ {
+ requiresTransformation = false;
+ }
+ }
+
+ previousAncestor = ancestor;
+ ++accessorIndex;
+ }
+
+ TIntermNode *originalExpression =
+ accessorIndex == 0 ? symbol : getAncestorNode(accessorIndex - 1);
+ TIntermNode *accessor = getAncestorNode(accessorIndex);
+
+ // if accessor is EOpArrayLength, we don't need to perform any transformations either.
+ // Note that this only applies to unsized arrays, as the RemoveArrayLengthMethod()
+ // transformation would have removed this operation otherwise.
+ TIntermUnary *accessorAsUnary = accessor->getAsUnaryNode();
+ if (requiresTransformation && accessorAsUnary && accessorAsUnary->getOp() == EOpArrayLength)
+ {
+ ASSERT(accessorAsUnary->getOperand() == originalExpression);
+ ASSERT(accessorAsUnary->getOperand()->getType().isUnsizedArray());
+
+ requiresTransformation = false;
+
+ // We need to replace the whole expression including the EOpArrayLength, to avoid
+ // confusing the replacement code as the original and new expressions don't have the
+ // same type (one is the transpose of the other). This doesn't affect the .length()
+ // operation, so this replacement is ok, though it's not worth special-casing this in
+ // the node replacement algorithm.
+ //
+ // Note: the |if (!requiresTransformation)| immediately below will be entered after
+ // this.
+ originalExpression = accessor;
+ accessor = getAncestorNode(accessorIndex + 1);
+ baseExpression = new TIntermUnary(EOpArrayLength, baseExpression, nullptr);
+ }
+
+ if (!requiresTransformation)
+ {
+ ASSERT(primaryIndex == nullptr);
+ queueReplacementWithParent(accessor, originalExpression, baseExpression,
+ OriginalNode::IS_DROPPED);
+
+ RewriteRowMajorMatricesTraverser *traverser = mOuterTraverser ? mOuterTraverser : this;
+ traverser->insertStatementsInParentBlock(prependStatements, appendStatements);
+ return;
+ }
+
+ ASSERT(structure == nullptr || primaryIndex == nullptr);
+ ASSERT(structure != nullptr || baseExpression->getType().isMatrix());
+
+ // At the end, we can determine if the expression is being read from or written to (or both,
+ // if sent as an inout parameter to a function). For the sake of the transformation, the
+ // left-hand side of operations like += can be treated as "written to", without necessarily
+ // "read from".
+ bool isRead = false;
+ bool isWrite = false;
+
+ determineAccess(originalExpression, accessor, &isRead, &isWrite);
+
+ ASSERT(isRead || isWrite);
+
+ TIntermTyped *readExpression = nullptr;
+ if (isRead)
+ {
+ readExpression = transformReadExpression(
+ baseExpression, primaryIndex, &secondaryIndices, structure, &prependStatements);
+
+ // If both read from and written to (i.e. passed to inout parameter), store the
+ // expression in a temp variable and pass that to the function.
+ if (isWrite)
+ {
+ readExpression =
+ CopyToTempVariable(mSymbolTable, readExpression, &prependStatements);
+ }
+
+ // Replace the original expression with the transformed one. Read transformations
+ // always generate a single expression that can be used in place of the original (as
+ // oppposed to write transformations that can generate multiple statements).
+ queueReplacementWithParent(accessor, originalExpression, readExpression,
+ OriginalNode::IS_DROPPED);
+ }
+
+ TIntermSequence postTransformPrependStatements;
+ TIntermSequence *writeStatements = &appendStatements;
+ TOperator assignmentOperator = EOpAssign;
+
+ if (isWrite)
+ {
+ TIntermTyped *valueExpression = readExpression;
+
+ if (!valueExpression)
+ {
+ // If there's already a read expression, this was an inout parameter and
+ // |valueExpression| will contain the temp variable that was passed to the function
+ // instead.
+ //
+ // If not, then the modification is either through being passed as an out parameter
+ // to a function, or an assignment. In the former case, create a temp variable to
+ // be passed to the function. In the latter case, create a temp variable that holds
+ // the right hand side expression.
+ //
+ // In either case, use that temp value as the value to assign to |baseExpression|.
+
+ TVariable *temp =
+ CreateTempVariable(mSymbolTable, &originalExpression->getAsTyped()->getType());
+ TIntermDeclaration *tempDecl = nullptr;
+
+ valueExpression = new TIntermSymbol(temp);
+
+ TIntermBinary *assignment = accessor->getAsBinaryNode();
+ if (assignment)
+ {
+ assignmentOperator = assignment->getOp();
+ ASSERT(IsAssignment(assignmentOperator));
+
+ // We are converting the assignment to the left-hand side of an expression in
+ // the form M=exp. A subexpression of exp itself could require a
+ // transformation. This complicates things as there would be two replacements:
+ //
+ // - Replace M=exp with temp (because the return value of the assignment could
+ // be used)
+ // - Replace exp with exp2, where parent is M=exp
+ //
+ // The second replacement however is ineffective as the whole of M=exp is
+ // already transformed. What's worse, M=exp is transformed without taking exp's
+ // transformations into account. To address this issue, this same traverser is
+ // called on the right-hand side expression, with a special flag such that it
+ // only processes that expression.
+ //
+ RewriteRowMajorMatricesTraverser *outerTraverser =
+ mOuterTraverser ? mOuterTraverser : this;
+ RewriteRowMajorMatricesTraverser rhsTraverser(
+ mSymbolTable, outerTraverser, mInterfaceBlockMap,
+ mInterfaceBlockFieldConvertedIn, mStructMapOut, mCopyFunctionDefinitionsOut,
+ assignment);
+ getRootNode()->traverse(&rhsTraverser);
+ bool valid = rhsTraverser.updateTree(mCompiler, getRootNode());
+ ASSERT(valid);
+
+ tempDecl = CreateTempInitDeclarationNode(temp, assignment->getRight());
+
+ // Replace the whole assignment expression with the right-hand side as a read
+ // expression, in case the result of the assignment is used. For example, this
+ // transforms:
+ //
+ // if ((M += exp) == X)
+ // {
+ // // use M
+ // }
+ //
+ // to:
+ //
+ // temp = exp;
+ // M += transform(temp);
+ // if (transform(M) == X)
+ // {
+ // // use M
+ // }
+ //
+ // Note that in this case the assignment to M must be prepended in the parent
+ // block. In contrast, when sent to a function, the assignment to M should be
+ // done after the current function call is done.
+ //
+ // If the read from M itself (to replace assigmnet) needs to generate extra
+ // statements, they should be appended after the statements that write to M.
+ // These statements are stored in postTransformPrependStatements and appended to
+ // prependStatements in the end.
+ //
+ writeStatements = &prependStatements;
+
+ TIntermTyped *assignmentResultExpression = transformReadExpression(
+ baseExpression->deepCopy(), primaryIndex, &secondaryIndices, structure,
+ &postTransformPrependStatements);
+
+ // Replace the whole assignment, instead of just the right hand side.
+ TIntermNode *accessorParent = getAncestorNode(accessorIndex + 1);
+ queueReplacementWithParent(accessorParent, accessor, assignmentResultExpression,
+ OriginalNode::IS_DROPPED);
+ }
+ else
+ {
+ tempDecl = CreateTempDeclarationNode(temp);
+
+ // Replace the write expression (a function call argument) with the temp
+ // variable.
+ queueReplacementWithParent(accessor, originalExpression, valueExpression,
+ OriginalNode::IS_DROPPED);
+ }
+ prependStatements.push_back(tempDecl);
+ }
+
+ if (isRead)
+ {
+ baseExpression = baseExpression->deepCopy();
+ }
+ transformWriteExpression(baseExpression, primaryIndex, &secondaryIndices, structure,
+ valueExpression, assignmentOperator, writeStatements);
+ }
+
+ prependStatements.insert(prependStatements.end(), postTransformPrependStatements.begin(),
+ postTransformPrependStatements.end());
+
+ RewriteRowMajorMatricesTraverser *traverser = mOuterTraverser ? mOuterTraverser : this;
+ traverser->insertStatementsInParentBlock(prependStatements, appendStatements);
+ }
+
+ TIntermTyped *transformReadExpression(TIntermTyped *baseExpression,
+ TIntermNode *primaryIndex,
+ TIntermSequence *secondaryIndices,
+ const TStructure *structure,
+ TIntermSequence *prependStatements)
+ {
+ const TType &baseExpressionType = baseExpression->getType();
+
+ if (structure)
+ {
+ ASSERT(primaryIndex == nullptr && secondaryIndices->empty());
+ ASSERT(mStructMapOut->count(structure) != 0);
+ ASSERT((*mStructMapOut)[structure].convertedStruct != nullptr);
+
+ // Declare copy-from-converted-to-original-struct function (if not already).
+ declareStructCopyToOriginal(structure);
+
+ const TFunction *copyToOriginal = (*mStructMapOut)[structure].copyToOriginal;
+
+ if (baseExpressionType.isArray())
+ {
+ // If base expression is an array, transform every element.
+ TransformArrayHelper transformHelper(baseExpression);
+
+ TIntermTyped *element = nullptr;
+ while ((element = transformHelper.getNextElement(nullptr, nullptr)) != nullptr)
+ {
+ TIntermTyped *transformedElement =
+ CreateStructCopyCall(copyToOriginal, element);
+ transformHelper.accumulateForRead(mSymbolTable, transformedElement,
+ prependStatements);
+ }
+ return transformHelper.constructReadTransformExpression();
+ }
+ else
+ {
+ // If not reading an array, the result is simply a call to this function with the
+ // base expression.
+ return CreateStructCopyCall(copyToOriginal, baseExpression);
+ }
+ }
+
+ // If not indexed, the result is transpose(exp)
+ if (primaryIndex == nullptr)
+ {
+ ASSERT(secondaryIndices->empty());
+
+ if (baseExpressionType.isArray())
+ {
+ // If array, transpose every element.
+ TransformArrayHelper transformHelper(baseExpression);
+
+ TIntermTyped *element = nullptr;
+ while ((element = transformHelper.getNextElement(nullptr, nullptr)) != nullptr)
+ {
+ TIntermTyped *transformedElement = CreateTransposeCall(mSymbolTable, element);
+ transformHelper.accumulateForRead(mSymbolTable, transformedElement,
+ prependStatements);
+ }
+ return transformHelper.constructReadTransformExpression();
+ }
+ else
+ {
+ return CreateTransposeCall(mSymbolTable, baseExpression);
+ }
+ }
+
+ // If indexed the result is a vector (or just one element) where the primary and secondary
+ // indices are swapped.
+ ASSERT(!secondaryIndices->empty());
+
+ TOperator primaryIndexOp = GetIndexOp(primaryIndex);
+ TIntermTyped *primaryIndexAsTyped = primaryIndex->getAsTyped();
+
+ TIntermSequence transposedColumn;
+ for (TIntermNode *secondaryIndex : *secondaryIndices)
+ {
+ TOperator secondaryIndexOp = GetIndexOp(secondaryIndex);
+ TIntermTyped *secondaryIndexAsTyped = secondaryIndex->getAsTyped();
+
+ TIntermBinary *colIndexed = new TIntermBinary(
+ secondaryIndexOp, baseExpression->deepCopy(), secondaryIndexAsTyped->deepCopy());
+ TIntermBinary *colRowIndexed =
+ new TIntermBinary(primaryIndexOp, colIndexed, primaryIndexAsTyped->deepCopy());
+
+ transposedColumn.push_back(colRowIndexed);
+ }
+
+ if (secondaryIndices->size() == 1)
+ {
+ // If only one element, return that directly.
+ return transposedColumn.front()->getAsTyped();
+ }
+
+ // Otherwise create a constructor with the appropriate dimension.
+ TType *vecType = new TType(baseExpressionType.getBasicType(), secondaryIndices->size());
+ return TIntermAggregate::CreateConstructor(*vecType, &transposedColumn);
+ }
+
+ void transformWriteExpression(TIntermTyped *baseExpression,
+ TIntermNode *primaryIndex,
+ TIntermSequence *secondaryIndices,
+ const TStructure *structure,
+ TIntermTyped *valueExpression,
+ TOperator assignmentOperator,
+ TIntermSequence *writeStatements)
+ {
+ const TType &baseExpressionType = baseExpression->getType();
+
+ if (structure)
+ {
+ ASSERT(primaryIndex == nullptr && secondaryIndices->empty());
+ ASSERT(mStructMapOut->count(structure) != 0);
+ ASSERT((*mStructMapOut)[structure].convertedStruct != nullptr);
+
+ // Declare copy-to-converted-from-original-struct function (if not already).
+ declareStructCopyFromOriginal(structure);
+
+ // The result is call to this function with the value expression assigned to base
+ // expression.
+ const TFunction *copyFromOriginal = (*mStructMapOut)[structure].copyFromOriginal;
+
+ if (baseExpressionType.isArray())
+ {
+ // If array, assign every element.
+ TransformArrayHelper transformHelper(baseExpression);
+
+ TIntermTyped *element = nullptr;
+ TIntermTyped *valueElement = nullptr;
+ while ((element = transformHelper.getNextElement(valueExpression, &valueElement)) !=
+ nullptr)
+ {
+ TIntermTyped *functionCall =
+ CreateStructCopyCall(copyFromOriginal, valueElement);
+ writeStatements->push_back(new TIntermBinary(EOpAssign, element, functionCall));
+ }
+ }
+ else
+ {
+ TIntermTyped *functionCall =
+ CreateStructCopyCall(copyFromOriginal, valueExpression->deepCopy());
+ writeStatements->push_back(
+ new TIntermBinary(EOpAssign, baseExpression, functionCall));
+ }
+
+ return;
+ }
+
+ // If not indexed, the result is transpose(exp)
+ if (primaryIndex == nullptr)
+ {
+ ASSERT(secondaryIndices->empty());
+
+ if (baseExpressionType.isArray())
+ {
+ // If array, assign every element.
+ TransformArrayHelper transformHelper(baseExpression);
+
+ TIntermTyped *element = nullptr;
+ TIntermTyped *valueElement = nullptr;
+ while ((element = transformHelper.getNextElement(valueExpression, &valueElement)) !=
+ nullptr)
+ {
+ TIntermTyped *valueTransposed = CreateTransposeCall(mSymbolTable, valueElement);
+ writeStatements->push_back(
+ new TIntermBinary(EOpAssign, element, valueTransposed));
+ }
+ }
+ else
+ {
+ TIntermTyped *valueTransposed =
+ CreateTransposeCall(mSymbolTable, valueExpression->deepCopy());
+ writeStatements->push_back(
+ new TIntermBinary(assignmentOperator, baseExpression, valueTransposed));
+ }
+
+ return;
+ }
+
+ // If indexed, create one assignment per secondary index. If the right-hand side is a
+ // scalar, it's used with every assignment. If it's a vector, the assignment is
+ // per-component. The right-hand side cannot be a matrix as that would imply left-hand
+ // side being a matrix too, which is covered above where |primaryIndex == nullptr|.
+ ASSERT(!secondaryIndices->empty());
+
+ bool isValueExpressionScalar = valueExpression->getType().getNominalSize() == 1;
+ ASSERT(isValueExpressionScalar || valueExpression->getType().getNominalSize() ==
+ static_cast<int>(secondaryIndices->size()));
+
+ TOperator primaryIndexOp = GetIndexOp(primaryIndex);
+ TIntermTyped *primaryIndexAsTyped = primaryIndex->getAsTyped();
+
+ for (TIntermNode *secondaryIndex : *secondaryIndices)
+ {
+ TOperator secondaryIndexOp = GetIndexOp(secondaryIndex);
+ TIntermTyped *secondaryIndexAsTyped = secondaryIndex->getAsTyped();
+
+ TIntermBinary *colIndexed = new TIntermBinary(
+ secondaryIndexOp, baseExpression->deepCopy(), secondaryIndexAsTyped->deepCopy());
+ TIntermBinary *colRowIndexed =
+ new TIntermBinary(primaryIndexOp, colIndexed, primaryIndexAsTyped->deepCopy());
+
+ TIntermTyped *valueExpressionIndexed = valueExpression->deepCopy();
+ if (!isValueExpressionScalar)
+ {
+ valueExpressionIndexed = new TIntermBinary(secondaryIndexOp, valueExpressionIndexed,
+ secondaryIndexAsTyped->deepCopy());
+ }
+
+ writeStatements->push_back(
+ new TIntermBinary(assignmentOperator, colRowIndexed, valueExpressionIndexed));
+ }
+ }
+
+ const TFunction *getCopyStructFieldFunction(const TType *fromFieldType,
+ const TType *toFieldType,
+ bool isCopyToOriginal)
+ {
+ ASSERT(fromFieldType->getStruct());
+ ASSERT(toFieldType->getStruct());
+
+ // If copying from or to the original struct, the "to" field struct could require
+ // conversion to or from the "from" field struct. |isCopyToOriginal| tells us if we
+ // should expect to find toField or fromField in mStructMapOut, if true or false
+ // respectively.
+ const TFunction *fieldCopyFunction = nullptr;
+ if (isCopyToOriginal)
+ {
+ const TStructure *toFieldStruct = toFieldType->getStruct();
+
+ auto iter = mStructMapOut->find(toFieldStruct);
+ if (iter != mStructMapOut->end())
+ {
+ declareStructCopyToOriginal(toFieldStruct);
+ fieldCopyFunction = iter->second.copyToOriginal;
+ }
+ }
+ else
+ {
+ const TStructure *fromFieldStruct = fromFieldType->getStruct();
+
+ auto iter = mStructMapOut->find(fromFieldStruct);
+ if (iter != mStructMapOut->end())
+ {
+ declareStructCopyFromOriginal(fromFieldStruct);
+ fieldCopyFunction = iter->second.copyFromOriginal;
+ }
+ }
+
+ return fieldCopyFunction;
+ }
+
+ void addFieldCopy(TIntermBlock *body,
+ TIntermTyped *to,
+ TIntermTyped *from,
+ bool isCopyToOriginal)
+ {
+ const TType &fromType = from->getType();
+ const TType &toType = to->getType();
+
+ TIntermTyped *rhs = from;
+
+ if (fromType.getStruct())
+ {
+ const TFunction *fieldCopyFunction =
+ getCopyStructFieldFunction(&fromType, &toType, isCopyToOriginal);
+
+ if (fieldCopyFunction)
+ {
+ rhs = CreateStructCopyCall(fieldCopyFunction, from);
+ }
+ }
+ else if (fromType.isMatrix())
+ {
+ rhs = CreateTransposeCall(mSymbolTable, from);
+ }
+
+ body->appendStatement(new TIntermBinary(EOpAssign, to, rhs));
+ }
+
+ TFunction *declareStructCopy(const TStructure *from,
+ const TStructure *to,
+ bool isCopyToOriginal)
+ {
+ TType *fromType = new TType(from, true);
+ TType *toType = new TType(to, true);
+
+ // Create the parameter and return value variables.
+ TVariable *fromVar = new TVariable(mSymbolTable, ImmutableString("from"), fromType,
+ SymbolType::AngleInternal);
+ TVariable *toVar =
+ new TVariable(mSymbolTable, ImmutableString("to"), toType, SymbolType::AngleInternal);
+
+ TIntermSymbol *fromSymbol = new TIntermSymbol(fromVar);
+ TIntermSymbol *toSymbol = new TIntermSymbol(toVar);
+
+ // Create the function body as statements are generated.
+ TIntermBlock *body = new TIntermBlock;
+
+ // Declare the result variable.
+ TIntermDeclaration *toDecl = new TIntermDeclaration();
+ toDecl->appendDeclarator(toSymbol);
+ body->appendStatement(toDecl);
+
+ // Iterate over fields of the struct and copy one by one, transposing the matrices. If a
+ // struct is encountered that requires a transformation, this function is recursively
+ // called. As a result, it is important that the copy functions are placed in the code in
+ // order.
+ const TFieldList &fromFields = from->fields();
+ const TFieldList &toFields = to->fields();
+ ASSERT(fromFields.size() == toFields.size());
+
+ for (size_t fieldIndex = 0; fieldIndex < fromFields.size(); ++fieldIndex)
+ {
+ TIntermTyped *fieldIndexNode = CreateIndexNode(static_cast<int>(fieldIndex));
+
+ TIntermTyped *fromField =
+ new TIntermBinary(EOpIndexDirectStruct, fromSymbol->deepCopy(), fieldIndexNode);
+ TIntermTyped *toField = new TIntermBinary(EOpIndexDirectStruct, toSymbol->deepCopy(),
+ fieldIndexNode->deepCopy());
+
+ const TType *fromFieldType = fromFields[fieldIndex]->type();
+ bool isStructOrMatrix = fromFieldType->getStruct() || fromFieldType->isMatrix();
+
+ if (fromFieldType->isArray() && isStructOrMatrix)
+ {
+ // If struct or matrix array, we need to copy element by element.
+ TransformArrayHelper transformHelper(toField);
+
+ TIntermTyped *toElement = nullptr;
+ TIntermTyped *fromElement = nullptr;
+ while ((toElement = transformHelper.getNextElement(fromField, &fromElement)) !=
+ nullptr)
+ {
+ addFieldCopy(body, toElement, fromElement, isCopyToOriginal);
+ }
+ }
+ else
+ {
+ addFieldCopy(body, toField, fromField, isCopyToOriginal);
+ }
+ }
+
+ // Add return statement.
+ body->appendStatement(new TIntermBranch(EOpReturn, toSymbol->deepCopy()));
+
+ // Declare the function
+ TFunction *copyFunction = new TFunction(mSymbolTable, kEmptyImmutableString,
+ SymbolType::AngleInternal, toType, true);
+ copyFunction->addParameter(fromVar);
+
+ TIntermFunctionDefinition *functionDef =
+ CreateInternalFunctionDefinitionNode(*copyFunction, body);
+ mCopyFunctionDefinitionsOut->push_back(functionDef);
+
+ return copyFunction;
+ }
+
+ void declareStructCopyFromOriginal(const TStructure *structure)
+ {
+ StructConversionData *structData = &(*mStructMapOut)[structure];
+ if (structData->copyFromOriginal)
+ {
+ return;
+ }
+
+ structData->copyFromOriginal =
+ declareStructCopy(structure, structData->convertedStruct, false);
+ }
+
+ void declareStructCopyToOriginal(const TStructure *structure)
+ {
+ StructConversionData *structData = &(*mStructMapOut)[structure];
+ if (structData->copyToOriginal)
+ {
+ return;
+ }
+
+ structData->copyToOriginal =
+ declareStructCopy(structData->convertedStruct, structure, true);
+ }
+
+ TCompiler *mCompiler;
+
+ // This traverser can call itself to transform a subexpression before moving on. However, it
+ // needs to accumulate conversion functions in inner passes. The fields below marked with Out
+ // or In are inherited from the outer pass (for inner passes), or point to storage fields in
+ // mOuterPass (for the outer pass). The latter should not be used by the inner passes as they
+ // would be empty, so they are placed inside a struct to make them explicit.
+ struct
+ {
+ StructMap structMap;
+ InterfaceBlockMap interfaceBlockMap;
+ InterfaceBlockFieldConverted interfaceBlockFieldConverted;
+ TIntermSequence copyFunctionDefinitions;
+ } mOuterPass;
+
+ // A map from structures with matrices to their converted version.
+ StructMap *mStructMapOut;
+ // A map from interface block instances with row-major matrices to their converted variable. If
+ // an interface block is nameless, its fields are placed in this map instead. When a variable
+ // in this map is encountered, it signals the start of an expression that my need conversion,
+ // which is either "interfaceBlock.field..." or "field..." if nameless.
+ InterfaceBlockMap *mInterfaceBlockMap;
+ // A map from interface block fields to whether they need to be converted. If a field was
+ // already column-major, it shouldn't be transposed.
+ const InterfaceBlockFieldConverted &mInterfaceBlockFieldConvertedIn;
+
+ TIntermSequence *mCopyFunctionDefinitionsOut;
+
+ // If set, it's an inner pass and this will point to the outer pass traverser. All statement
+ // insertions are stored in the outer traverser and applied at once in the end. This prevents
+ // the inner passes from adding statements which invalidates the outer traverser's statement
+ // position tracking.
+ RewriteRowMajorMatricesTraverser *mOuterTraverser;
+
+ // If set, it's an inner pass that should only process the right-hand side of this particular
+ // node.
+ TIntermBinary *mInnerPassRoot;
+ bool mIsProcessingInnerPassSubtree;
+};
+
+} // anonymous namespace
+
+bool RewriteRowMajorMatrices(TCompiler *compiler, TIntermBlock *root, TSymbolTable *symbolTable)
+{
+ RewriteRowMajorMatricesTraverser traverser(compiler, symbolTable);
+ root->traverse(&traverser);
+ if (!traverser.updateTree(compiler, root))
+ {
+ return false;
+ }
+
+ size_t firstFunctionIndex = FindFirstFunctionDefinitionIndex(root);
+ root->insertChildNodes(firstFunctionIndex, *traverser.getStructCopyFunctions());
+
+ return compiler->validateAST(root);
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteRowMajorMatrices.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteRowMajorMatrices.h
new file mode 100644
index 0000000000..2f3577248e
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteRowMajorMatrices.h
@@ -0,0 +1,37 @@
+//
+// Copyright 2019 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.
+//
+// RewriteRowMajorMatrices: Change row-major matrices to column-major in uniform and storage
+// buffers.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_APPLE_REWRITEROWMAJORMATRICES_H_
+#define COMPILER_TRANSLATOR_TREEOPS_APPLE_REWRITEROWMAJORMATRICES_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+#if (defined(ANGLE_ENABLE_GLSL) || defined(ANGLE_ENABLE_METAL)) && \
+ defined(ANGLE_ENABLE_APPLE_WORKAROUNDS)
+[[nodiscard]] bool RewriteRowMajorMatrices(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable);
+#else
+[[nodiscard]] ANGLE_INLINE bool RewriteRowMajorMatrices(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable)
+{
+ UNREACHABLE();
+ return false;
+}
+#endif
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_APPLE_REWRITEROWMAJORMATRICES_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteUnaryMinusOperatorFloat.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteUnaryMinusOperatorFloat.cpp
new file mode 100644
index 0000000000..4aa8a28203
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteUnaryMinusOperatorFloat.cpp
@@ -0,0 +1,97 @@
+//
+// 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.
+//
+
+#include "compiler/translator/tree_ops/apple/RewriteUnaryMinusOperatorFloat.h"
+
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class Traverser : public TIntermTraverser
+{
+ public:
+ [[nodiscard]] static bool Apply(TCompiler *compiler, TIntermNode *root);
+
+ private:
+ Traverser();
+ bool visitUnary(Visit visit, TIntermUnary *node) override;
+ void nextIteration();
+
+ bool mFound = false;
+};
+
+// static
+bool Traverser::Apply(TCompiler *compiler, TIntermNode *root)
+{
+ Traverser traverser;
+ do
+ {
+ traverser.nextIteration();
+ root->traverse(&traverser);
+ if (traverser.mFound)
+ {
+ if (!traverser.updateTree(compiler, root))
+ {
+ return false;
+ }
+ }
+ } while (traverser.mFound);
+
+ return true;
+}
+
+Traverser::Traverser() : TIntermTraverser(true, false, false) {}
+
+void Traverser::nextIteration()
+{
+ mFound = false;
+}
+
+bool Traverser::visitUnary(Visit visit, TIntermUnary *node)
+{
+ if (mFound)
+ {
+ return false;
+ }
+
+ // Detect if the current operator is unary minus operator.
+ if (node->getOp() != EOpNegative)
+ {
+ return true;
+ }
+
+ // Detect if the current operand is a float variable.
+ TIntermTyped *fValue = node->getOperand();
+ if (!fValue->getType().isScalarFloat())
+ {
+ return true;
+ }
+
+ // 0.0 - float
+ TIntermTyped *zero = CreateZeroNode(fValue->getType());
+ zero->setLine(fValue->getLine());
+ TIntermBinary *sub = new TIntermBinary(EOpSub, zero, fValue);
+ sub->setLine(fValue->getLine());
+
+ queueReplacement(sub, OriginalNode::IS_DROPPED);
+
+ mFound = true;
+ return false;
+}
+
+} // anonymous namespace
+
+bool RewriteUnaryMinusOperatorFloat(TCompiler *compiler, TIntermNode *root)
+{
+ return Traverser::Apply(compiler, root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteUnaryMinusOperatorFloat.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteUnaryMinusOperatorFloat.h
new file mode 100644
index 0000000000..30c4d25d01
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/RewriteUnaryMinusOperatorFloat.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.
+//
+// Rewrite "-float" to "0.0 - float" to work around unary minus operator on float issue on Intel Mac
+// OSX 10.11.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_APPLE_REWRITEUNARYMINUSOPERATORFLOAT_H_
+#define COMPILER_TRANSLATOR_TREEOPS_APPLE_REWRITEUNARYMINUSOPERATORFLOAT_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermNode;
+
+#if defined(ANGLE_ENABLE_GLSL) && defined(ANGLE_ENABLE_APPLE_WORKAROUNDS)
+[[nodiscard]] bool RewriteUnaryMinusOperatorFloat(TCompiler *compiler, TIntermNode *root);
+#else
+[[nodiscard]] ANGLE_INLINE bool RewriteUnaryMinusOperatorFloat(TCompiler *compiler,
+ TIntermNode *root)
+{
+ UNREACHABLE();
+ return false;
+}
+#endif
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_APPLE_REWRITEUNARYMINUSOPERATORFLOAT_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/UnfoldShortCircuitAST.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/UnfoldShortCircuitAST.cpp
new file mode 100644
index 0000000000..55e2f8b971
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/UnfoldShortCircuitAST.cpp
@@ -0,0 +1,74 @@
+//
+// Copyright 2002 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/tree_ops/apple/UnfoldShortCircuitAST.h"
+
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+// "x || y" is equivalent to "x ? true : y".
+TIntermTernary *UnfoldOR(TIntermTyped *x, TIntermTyped *y)
+{
+ return new TIntermTernary(x, CreateBoolNode(true), y);
+}
+
+// "x && y" is equivalent to "x ? y : false".
+TIntermTernary *UnfoldAND(TIntermTyped *x, TIntermTyped *y)
+{
+ return new TIntermTernary(x, y, CreateBoolNode(false));
+}
+
+// This traverser identifies all the short circuit binary nodes that need to
+// be replaced, and creates the corresponding replacement nodes. However,
+// the actual replacements happen after the traverse through updateTree().
+
+class UnfoldShortCircuitASTTraverser : public TIntermTraverser
+{
+ public:
+ UnfoldShortCircuitASTTraverser() : TIntermTraverser(true, false, false) {}
+
+ bool visitBinary(Visit visit, TIntermBinary *) override;
+};
+
+bool UnfoldShortCircuitASTTraverser::visitBinary(Visit visit, TIntermBinary *node)
+{
+ TIntermTernary *replacement = nullptr;
+
+ switch (node->getOp())
+ {
+ case EOpLogicalOr:
+ replacement = UnfoldOR(node->getLeft(), node->getRight());
+ break;
+ case EOpLogicalAnd:
+ replacement = UnfoldAND(node->getLeft(), node->getRight());
+ break;
+ default:
+ break;
+ }
+ if (replacement)
+ {
+ queueReplacement(replacement, OriginalNode::IS_DROPPED);
+ }
+ return true;
+}
+
+} // anonymous namespace
+
+bool UnfoldShortCircuitAST(TCompiler *compiler, TIntermBlock *root)
+{
+ UnfoldShortCircuitASTTraverser traverser;
+ root->traverse(&traverser);
+ return traverser.updateTree(compiler, root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/UnfoldShortCircuitAST.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/UnfoldShortCircuitAST.h
new file mode 100644
index 0000000000..648c7190a9
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/apple/UnfoldShortCircuitAST.h
@@ -0,0 +1,33 @@
+//
+// Copyright 2002 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.
+//
+// UnfoldShortCircuitAST is an AST traverser to replace short-circuiting
+// operations with ternary operations.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_APPLE_UNFOLDSHORTCIRCUITAST_H_
+#define COMPILER_TRANSLATOR_TREEOPS_APPLE_UNFOLDSHORTCIRCUITAST_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermBlock;
+
+#if defined(ANGLE_ENABLE_GLSL) && defined(ANGLE_ENABLE_APPLE_WORKAROUNDS)
+[[nodiscard]] bool UnfoldShortCircuitAST(TCompiler *compiler, TIntermBlock *root);
+#else
+[[nodiscard]] ANGLE_INLINE bool UnfoldShortCircuitAST(TCompiler *compiler, TIntermBlock *root)
+{
+ UNREACHABLE();
+ return false;
+}
+#endif
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_APPLE_UNFOLDSHORTCIRCUITAST_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AddDefaultReturnStatements.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AddDefaultReturnStatements.cpp
new file mode 100644
index 0000000000..8790c4f5f2
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AddDefaultReturnStatements.cpp
@@ -0,0 +1,61 @@
+//
+// 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.
+//
+// AddDefaultReturnStatements.cpp: Add default return statements to functions that do not end in a
+// return.
+//
+
+#include "compiler/translator/tree_ops/d3d/AddDefaultReturnStatements.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+bool NeedsReturnStatement(TIntermFunctionDefinition *node, TType *returnType)
+{
+ *returnType = node->getFunctionPrototype()->getType();
+ if (returnType->getBasicType() == EbtVoid)
+ {
+ return false;
+ }
+
+ TIntermBlock *bodyNode = node->getBody();
+ TIntermBranch *returnNode = bodyNode->getSequence()->back()->getAsBranchNode();
+ if (returnNode != nullptr && returnNode->getFlowOp() == EOpReturn)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+} // anonymous namespace
+
+bool AddDefaultReturnStatements(TCompiler *compiler, TIntermBlock *root)
+{
+ TType returnType;
+ for (TIntermNode *node : *root->getSequence())
+ {
+ TIntermFunctionDefinition *definition = node->getAsFunctionDefinition();
+ if (definition != nullptr && NeedsReturnStatement(definition, &returnType))
+ {
+ TIntermBranch *branch = new TIntermBranch(EOpReturn, CreateZeroNode(returnType));
+
+ TIntermBlock *bodyNode = definition->getBody();
+ bodyNode->getSequence()->push_back(branch);
+ }
+ }
+
+ return compiler->validateAST(root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AddDefaultReturnStatements.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AddDefaultReturnStatements.h
new file mode 100644
index 0000000000..52b601514c
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AddDefaultReturnStatements.h
@@ -0,0 +1,24 @@
+//
+// 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.
+//
+// AddDefaultReturnStatements.h: Add default return statements to functions that do not end in a
+// return.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_D3D_ADDDEFAULTRETURNSTATEMENTS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_D3D_ADDDEFAULTRETURNSTATEMENTS_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermBlock;
+
+[[nodiscard]] bool AddDefaultReturnStatements(TCompiler *compiler, TIntermBlock *root);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_D3D_ADDDEFAULTRETURNSTATEMENTS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AggregateAssignArraysInSSBOs.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AggregateAssignArraysInSSBOs.cpp
new file mode 100644
index 0000000000..d9a0c9bebc
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AggregateAssignArraysInSSBOs.cpp
@@ -0,0 +1,82 @@
+//
+// Copyright 2022 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/tree_ops/d3d/AggregateAssignArraysInSSBOs.h"
+
+#include "compiler/translator/StaticType.h"
+#include "compiler/translator/Symbol.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class AggregateAssignArraysInSSBOsTraverser : public TIntermTraverser
+{
+ public:
+ AggregateAssignArraysInSSBOsTraverser(TSymbolTable *symbolTable)
+ : TIntermTraverser(true, false, false, symbolTable)
+ {}
+
+ protected:
+ bool visitBinary(Visit visit, TIntermBinary *node) override
+ {
+ // Replace all aggregate assignments to arrays in SSBOs with element-by-element assignments.
+ // TODO(anglebug.com/7363): this implementation only works for the simple case (assignment
+ // statement), not more complex cases such as assignment-as-expression or functions with
+ // side effects in the RHS.
+
+ if (node->getOp() != EOpAssign)
+ {
+ return true;
+ }
+ else if (!node->getLeft()->getType().isArray())
+ {
+ return true;
+ }
+ else if (!IsInShaderStorageBlock(node->getLeft()))
+ {
+ return true;
+ }
+ const TType *mediumpIndexType = StaticType::Get<EbtInt, EbpMedium, EvqTemporary, 1, 1>();
+ auto *indexVariable = CreateTempVariable(mSymbolTable, mediumpIndexType);
+ auto *indexInit =
+ CreateTempInitDeclarationNode(indexVariable, CreateZeroNode(indexVariable->getType()));
+ auto *arraySizeNode = CreateIndexNode(node->getOutermostArraySize());
+ auto *indexSymbolNode = CreateTempSymbolNode(indexVariable);
+ auto *cond = new TIntermBinary(EOpLessThan, indexSymbolNode->deepCopy(), arraySizeNode);
+ auto *indexIncrement =
+ new TIntermUnary(EOpPreIncrement, indexSymbolNode->deepCopy(), nullptr);
+ auto *forLoopBody = new TIntermBlock();
+ auto *indexedLeft =
+ new TIntermBinary(EOpIndexDirect, node->getLeft(), indexSymbolNode->deepCopy());
+ auto *indexedRight =
+ new TIntermBinary(EOpIndexDirect, node->getRight(), indexSymbolNode->deepCopy());
+ auto *assign = new TIntermBinary(TOperator::EOpAssign, indexedLeft, indexedRight);
+ forLoopBody->appendStatement(assign);
+ auto *forLoop =
+ new TIntermLoop(ELoopFor, indexInit, cond, indexIncrement, EnsureBlock(forLoopBody));
+ queueReplacement(forLoop, OriginalNode::IS_DROPPED);
+ return false;
+ }
+};
+
+} // namespace
+
+bool AggregateAssignArraysInSSBOs(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable)
+{
+ AggregateAssignArraysInSSBOsTraverser traverser(symbolTable);
+ root->traverse(&traverser);
+ return traverser.updateTree(compiler, root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AggregateAssignArraysInSSBOs.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AggregateAssignArraysInSSBOs.h
new file mode 100644
index 0000000000..ce965bb002
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AggregateAssignArraysInSSBOs.h
@@ -0,0 +1,23 @@
+//
+// Copyright 2022 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_TREEOPS_D3D_AGGREGATEASSIGNARRAYSINSSBOS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_D3D_AGGREGATEASSIGNARRAYSINSSBOS_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+[[nodiscard]] bool AggregateAssignArraysInSSBOs(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_D3D_AGGREGATEASSIGNARRAYSINSSBOS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AggregateAssignStructsInSSBOs.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AggregateAssignStructsInSSBOs.cpp
new file mode 100644
index 0000000000..4293f4c4da
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AggregateAssignStructsInSSBOs.cpp
@@ -0,0 +1,76 @@
+//
+// Copyright 2022 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/tree_ops/d3d/AggregateAssignStructsInSSBOs.h"
+
+#include "compiler/translator/StaticType.h"
+#include "compiler/translator/Symbol.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class AggregateAssignStructsInSSBOsTraverser : public TIntermTraverser
+{
+ public:
+ AggregateAssignStructsInSSBOsTraverser(TSymbolTable *symbolTable)
+ : TIntermTraverser(true, false, false, symbolTable)
+ {}
+
+ protected:
+ bool visitBinary(Visit visit, TIntermBinary *node) override
+ {
+ // Replace all assignments to structs in SSBOs with field-by-field asignments.
+ // TODO(anglebug.com/7362): this implementation only works for the simple case (assignment
+ // statement), not more complex cases such as assignment-as-expression or functions with
+ // side effects in the RHS.
+ const TStructure *s;
+ if (node->getOp() != EOpAssign)
+ {
+ return true;
+ }
+ else if (!IsInShaderStorageBlock(node->getLeft()))
+ {
+ return true;
+ }
+ else if (!(s = node->getLeft()->getType().getStruct()))
+ {
+ return true;
+ }
+ ASSERT(node->getRight()->getType().getStruct() == s);
+ auto *block = new TIntermBlock();
+ for (int i = 0; i < static_cast<int>(s->fields().size()); ++i)
+ {
+ auto *left = new TIntermBinary(EOpIndexDirectStruct, node->getLeft()->deepCopy(),
+ CreateIndexNode(i));
+ auto *right = new TIntermBinary(EOpIndexDirectStruct, node->getRight()->deepCopy(),
+ CreateIndexNode(i));
+ auto *assign = new TIntermBinary(TOperator::EOpAssign, left, right);
+ block->appendStatement(assign);
+ }
+
+ queueReplacement(block, OriginalNode::IS_DROPPED);
+ return false;
+ }
+};
+
+} // namespace
+
+bool AggregateAssignStructsInSSBOs(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable)
+{
+ AggregateAssignStructsInSSBOsTraverser traverser(symbolTable);
+ root->traverse(&traverser);
+ return traverser.updateTree(compiler, root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AggregateAssignStructsInSSBOs.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AggregateAssignStructsInSSBOs.h
new file mode 100644
index 0000000000..910345902b
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/AggregateAssignStructsInSSBOs.h
@@ -0,0 +1,23 @@
+//
+// Copyright 2022 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_TREEOPS_D3D_AGGREGATEASSIGNSTRUCTSINSSBOS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_D3D_AGGREGATEASSIGNSTRUCTSINSSBOS_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+[[nodiscard]] bool AggregateAssignStructsInSSBOs(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_D3D_AGGREGATEASSIGNSTRUCTSINSSBOS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/ArrayReturnValueToOutParameter.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/ArrayReturnValueToOutParameter.cpp
new file mode 100644
index 0000000000..54d8fc0808
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/ArrayReturnValueToOutParameter.cpp
@@ -0,0 +1,233 @@
+//
+// Copyright 2002 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.
+//
+// The ArrayReturnValueToOutParameter function changes return values of an array type to out
+// parameters in function definitions, prototypes, and call sites.
+
+#include "compiler/translator/tree_ops/d3d/ArrayReturnValueToOutParameter.h"
+
+#include <map>
+
+#include "compiler/translator/StaticType.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+constexpr const ImmutableString kReturnValueVariableName("angle_return");
+
+class ArrayReturnValueToOutParameterTraverser : private TIntermTraverser
+{
+ public:
+ [[nodiscard]] static bool apply(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable);
+
+ private:
+ ArrayReturnValueToOutParameterTraverser(TSymbolTable *symbolTable);
+
+ void visitFunctionPrototype(TIntermFunctionPrototype *node) override;
+ bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override;
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override;
+ bool visitBranch(Visit visit, TIntermBranch *node) override;
+ bool visitBinary(Visit visit, TIntermBinary *node) override;
+
+ TIntermAggregate *createReplacementCall(TIntermAggregate *originalCall,
+ TIntermTyped *returnValueTarget);
+
+ // Set when traversal is inside a function with array return value.
+ TIntermFunctionDefinition *mFunctionWithArrayReturnValue;
+
+ struct ChangedFunction
+ {
+ const TVariable *returnValueVariable;
+ const TFunction *func;
+ };
+
+ // Map from function symbol ids to the changed function.
+ std::map<int, ChangedFunction> mChangedFunctions;
+};
+
+TIntermAggregate *ArrayReturnValueToOutParameterTraverser::createReplacementCall(
+ TIntermAggregate *originalCall,
+ TIntermTyped *returnValueTarget)
+{
+ TIntermSequence replacementArguments;
+ TIntermSequence *originalArguments = originalCall->getSequence();
+ for (auto &arg : *originalArguments)
+ {
+ replacementArguments.push_back(arg);
+ }
+ replacementArguments.push_back(returnValueTarget);
+ ASSERT(originalCall->getFunction());
+ const TSymbolUniqueId &originalId = originalCall->getFunction()->uniqueId();
+ TIntermAggregate *replacementCall = TIntermAggregate::CreateFunctionCall(
+ *mChangedFunctions[originalId.get()].func, &replacementArguments);
+ replacementCall->setLine(originalCall->getLine());
+ return replacementCall;
+}
+
+bool ArrayReturnValueToOutParameterTraverser::apply(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable)
+{
+ ArrayReturnValueToOutParameterTraverser arrayReturnValueToOutParam(symbolTable);
+ root->traverse(&arrayReturnValueToOutParam);
+ return arrayReturnValueToOutParam.updateTree(compiler, root);
+}
+
+ArrayReturnValueToOutParameterTraverser::ArrayReturnValueToOutParameterTraverser(
+ TSymbolTable *symbolTable)
+ : TIntermTraverser(true, false, true, symbolTable), mFunctionWithArrayReturnValue(nullptr)
+{}
+
+bool ArrayReturnValueToOutParameterTraverser::visitFunctionDefinition(
+ Visit visit,
+ TIntermFunctionDefinition *node)
+{
+ if (node->getFunctionPrototype()->isArray() && visit == PreVisit)
+ {
+ // Replacing the function header is done on visitFunctionPrototype().
+ mFunctionWithArrayReturnValue = node;
+ }
+ if (visit == PostVisit)
+ {
+ mFunctionWithArrayReturnValue = nullptr;
+ }
+ return true;
+}
+
+void ArrayReturnValueToOutParameterTraverser::visitFunctionPrototype(TIntermFunctionPrototype *node)
+{
+ if (node->isArray())
+ {
+ // Replace the whole prototype node with another node that has the out parameter
+ // added. Also set the function to return void.
+ const TSymbolUniqueId &functionId = node->getFunction()->uniqueId();
+ if (mChangedFunctions.find(functionId.get()) == mChangedFunctions.end())
+ {
+ TType *returnValueVariableType = new TType(node->getType());
+ returnValueVariableType->setQualifier(EvqParamOut);
+ ChangedFunction changedFunction;
+ changedFunction.returnValueVariable =
+ new TVariable(mSymbolTable, kReturnValueVariableName, returnValueVariableType,
+ SymbolType::AngleInternal);
+ TFunction *func = new TFunction(mSymbolTable, node->getFunction()->name(),
+ node->getFunction()->symbolType(),
+ StaticType::GetBasic<EbtVoid, EbpUndefined>(), false);
+ for (size_t i = 0; i < node->getFunction()->getParamCount(); ++i)
+ {
+ func->addParameter(node->getFunction()->getParam(i));
+ }
+ func->addParameter(changedFunction.returnValueVariable);
+ changedFunction.func = func;
+ mChangedFunctions[functionId.get()] = changedFunction;
+ }
+ TIntermFunctionPrototype *replacement =
+ new TIntermFunctionPrototype(mChangedFunctions[functionId.get()].func);
+ replacement->setLine(node->getLine());
+
+ queueReplacement(replacement, OriginalNode::IS_DROPPED);
+ }
+}
+
+bool ArrayReturnValueToOutParameterTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
+{
+ ASSERT(!node->isArray() || node->getOp() != EOpCallInternalRawFunction);
+ if (visit == PreVisit && node->isArray() && node->getOp() == EOpCallFunctionInAST)
+ {
+ // Handle call sites where the returned array is not assigned.
+ // Examples where f() is a function returning an array:
+ // 1. f();
+ // 2. another_array == f();
+ // 3. another_function(f());
+ // 4. return f();
+ // Cases 2 to 4 are already converted to simpler cases by
+ // SeparateExpressionsReturningArrays, so we only need to worry about the case where a
+ // function call returning an array forms an expression by itself.
+ TIntermBlock *parentBlock = getParentNode()->getAsBlock();
+ if (parentBlock)
+ {
+ // replace
+ // f();
+ // with
+ // type s0[size]; f(s0);
+ TIntermSequence replacements;
+
+ // type s0[size];
+ TIntermDeclaration *returnValueDeclaration = nullptr;
+ TVariable *returnValue = DeclareTempVariable(mSymbolTable, new TType(node->getType()),
+ EvqTemporary, &returnValueDeclaration);
+ replacements.push_back(returnValueDeclaration);
+
+ // f(s0);
+ TIntermSymbol *returnValueSymbol = CreateTempSymbolNode(returnValue);
+ replacements.push_back(createReplacementCall(node, returnValueSymbol));
+ mMultiReplacements.emplace_back(parentBlock, node, std::move(replacements));
+ }
+ return false;
+ }
+ return true;
+}
+
+bool ArrayReturnValueToOutParameterTraverser::visitBranch(Visit visit, TIntermBranch *node)
+{
+ if (mFunctionWithArrayReturnValue && node->getFlowOp() == EOpReturn)
+ {
+ // Instead of returning a value, assign to the out parameter and then return.
+ TIntermSequence replacements;
+
+ TIntermTyped *expression = node->getExpression();
+ ASSERT(expression != nullptr);
+ const TSymbolUniqueId &functionId =
+ mFunctionWithArrayReturnValue->getFunction()->uniqueId();
+ ASSERT(mChangedFunctions.find(functionId.get()) != mChangedFunctions.end());
+ TIntermSymbol *returnValueSymbol =
+ new TIntermSymbol(mChangedFunctions[functionId.get()].returnValueVariable);
+ TIntermBinary *replacementAssignment =
+ new TIntermBinary(EOpAssign, returnValueSymbol, expression);
+ replacementAssignment->setLine(expression->getLine());
+ replacements.push_back(replacementAssignment);
+
+ TIntermBranch *replacementBranch = new TIntermBranch(EOpReturn, nullptr);
+ replacementBranch->setLine(node->getLine());
+ replacements.push_back(replacementBranch);
+
+ mMultiReplacements.emplace_back(getParentNode()->getAsBlock(), node,
+ std::move(replacements));
+ }
+ return false;
+}
+
+bool ArrayReturnValueToOutParameterTraverser::visitBinary(Visit visit, TIntermBinary *node)
+{
+ if (node->getOp() == EOpAssign && node->getLeft()->isArray())
+ {
+ TIntermAggregate *rightAgg = node->getRight()->getAsAggregate();
+ ASSERT(rightAgg == nullptr || rightAgg->getOp() != EOpCallInternalRawFunction);
+ if (rightAgg != nullptr && rightAgg->getOp() == EOpCallFunctionInAST)
+ {
+ TIntermAggregate *replacementCall = createReplacementCall(rightAgg, node->getLeft());
+ queueReplacement(replacementCall, OriginalNode::IS_DROPPED);
+ }
+ }
+ return false;
+}
+
+} // namespace
+
+bool ArrayReturnValueToOutParameter(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable)
+{
+ return ArrayReturnValueToOutParameterTraverser::apply(compiler, root, symbolTable);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/ArrayReturnValueToOutParameter.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/ArrayReturnValueToOutParameter.h
new file mode 100644
index 0000000000..ae8d04ae9a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/ArrayReturnValueToOutParameter.h
@@ -0,0 +1,27 @@
+//
+// Copyright 2002 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.
+//
+// The ArrayReturnValueToOutParameter function changes return values of an array type to out
+// parameters in function definitions, prototypes and call sites.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_D3D_ARRAYRETURNVALUETOOUTPARAMETER_H_
+#define COMPILER_TRANSLATOR_TREEOPS_D3D_ARRAYRETURNVALUETOOUTPARAMETER_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermNode;
+class TSymbolTable;
+
+[[nodiscard]] bool ArrayReturnValueToOutParameter(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_D3D_ARRAYRETURNVALUETOOUTPARAMETER_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/BreakVariableAliasingInInnerLoops.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/BreakVariableAliasingInInnerLoops.cpp
new file mode 100644
index 0000000000..908da7a8c2
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/BreakVariableAliasingInInnerLoops.cpp
@@ -0,0 +1,110 @@
+//
+// 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.
+//
+
+// 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 "compiler/translator/tree_ops/d3d/BreakVariableAliasingInInnerLoops.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.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 sh
+{
+
+namespace
+{
+
+class AliasingBreaker : public TIntermTraverser
+{
+ public:
+ AliasingBreaker() : TIntermTraverser(true, false, true) {}
+
+ protected:
+ bool visitBinary(Visit visit, TIntermBinary *binary) override
+ {
+ 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, CreateZeroNode(type));
+ bPlusZero->setLine(B->getLine());
+
+ binary->replaceChildNode(B, bPlusZero);
+
+ return true;
+ }
+
+ bool visitLoop(Visit visit, TIntermLoop *loop) override
+ {
+ if (visit == PreVisit)
+ {
+ mLoopLevel++;
+ }
+ else
+ {
+ ASSERT(mLoopLevel > 0);
+ mLoopLevel--;
+ }
+
+ return true;
+ }
+
+ private:
+ int mLoopLevel = 0;
+};
+
+} // anonymous namespace
+
+bool BreakVariableAliasingInInnerLoops(TCompiler *compiler, TIntermNode *root)
+{
+ AliasingBreaker breaker;
+ root->traverse(&breaker);
+
+ return compiler->validateAST(root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/BreakVariableAliasingInInnerLoops.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/BreakVariableAliasingInInnerLoops.h
new file mode 100644
index 0000000000..455c7c322d
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/BreakVariableAliasingInInnerLoops.h
@@ -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.
+//
+
+// 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_TREEOPS_D3D_BREAKVARIABLEALIASINGININNERLOOPS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_D3D_BREAKVARIABLEALIASINGININNERLOOPS_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermNode;
+
+[[nodiscard]] bool BreakVariableAliasingInInnerLoops(TCompiler *compiler, TIntermNode *root);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_D3D_BREAKVARIABLEALIASINGININNERLOOPS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/ExpandIntegerPowExpressions.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/ExpandIntegerPowExpressions.cpp
new file mode 100644
index 0000000000..e873db56cd
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/ExpandIntegerPowExpressions.cpp
@@ -0,0 +1,152 @@
+//
+// 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.
+//
+// Implementation of the integer pow expressions HLSL bug workaround.
+// See header for more info.
+
+#include "compiler/translator/tree_ops/d3d/ExpandIntegerPowExpressions.h"
+
+#include <cmath>
+#include <cstdlib>
+
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class Traverser : public TIntermTraverser
+{
+ public:
+ [[nodiscard]] static bool Apply(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable);
+
+ private:
+ Traverser(TSymbolTable *symbolTable);
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override;
+ void nextIteration();
+
+ bool mFound = false;
+};
+
+// static
+bool Traverser::Apply(TCompiler *compiler, TIntermNode *root, TSymbolTable *symbolTable)
+{
+ Traverser traverser(symbolTable);
+ do
+ {
+ traverser.nextIteration();
+ root->traverse(&traverser);
+ if (traverser.mFound)
+ {
+ if (!traverser.updateTree(compiler, root))
+ {
+ return false;
+ }
+ }
+ } while (traverser.mFound);
+
+ return true;
+}
+
+Traverser::Traverser(TSymbolTable *symbolTable) : TIntermTraverser(true, false, false, symbolTable)
+{}
+
+void Traverser::nextIteration()
+{
+ mFound = false;
+}
+
+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 *constantExponent = sequence->at(1)->getAsConstantUnion();
+
+ // Test 1: check for a single constant.
+ if (!constantExponent || constantExponent->getNominalSize() != 1)
+ {
+ return true;
+ }
+
+ float exponentValue = constantExponent->getConstantValue()->getFConst();
+
+ // Test 2: exponentValue is in the problematic range.
+ if (exponentValue < -5.0f || exponentValue > 9.0f)
+ {
+ return true;
+ }
+
+ // Test 3: exponentValue is integer or pretty close to an integer.
+ if (std::abs(exponentValue - std::round(exponentValue)) > 0.0001f)
+ {
+ return true;
+ }
+
+ // Test 4: skip -1, 0, and 1
+ int exponent = static_cast<int>(std::round(exponentValue));
+ int n = std::abs(exponent);
+ if (n < 2)
+ {
+ return true;
+ }
+
+ // Potential problem case detected, apply workaround.
+
+ TIntermTyped *lhs = sequence->at(0)->getAsTyped();
+ ASSERT(lhs);
+
+ TIntermDeclaration *lhsVariableDeclaration = nullptr;
+ TVariable *lhsVariable =
+ DeclareTempVariable(mSymbolTable, lhs, EvqTemporary, &lhsVariableDeclaration);
+ insertStatementInParentBlock(lhsVariableDeclaration);
+
+ // Create a chain of n-1 multiples.
+ TIntermTyped *current = CreateTempSymbolNode(lhsVariable);
+ for (int i = 1; i < n; ++i)
+ {
+ TIntermBinary *mul = new TIntermBinary(EOpMul, current, CreateTempSymbolNode(lhsVariable));
+ 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(current, OriginalNode::IS_DROPPED);
+ mFound = true;
+ return false;
+}
+
+} // anonymous namespace
+
+bool ExpandIntegerPowExpressions(TCompiler *compiler, TIntermNode *root, TSymbolTable *symbolTable)
+{
+ return Traverser::Apply(compiler, root, symbolTable);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/ExpandIntegerPowExpressions.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/ExpandIntegerPowExpressions.h
new file mode 100644
index 0000000000..2404fb08ac
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/ExpandIntegerPowExpressions.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.
+//
+// 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_TREEOPS_D3D_EXPANDINTEGERPOWEXPRESSIONS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_D3D_EXPANDINTEGERPOWEXPRESSIONS_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermNode;
+class TSymbolTable;
+
+[[nodiscard]] bool ExpandIntegerPowExpressions(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_D3D_EXPANDINTEGERPOWEXPRESSIONS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RecordUniformBlocksWithLargeArrayMember.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RecordUniformBlocksWithLargeArrayMember.cpp
new file mode 100644
index 0000000000..18d49814ac
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RecordUniformBlocksWithLargeArrayMember.cpp
@@ -0,0 +1,385 @@
+//
+// Copyright 2020 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.
+//
+// RecordUniformBlocksWithLargeArrayMember.h:
+// Collect all uniform blocks which have one or more large array members,
+// and the array sizes are greater than or equal to 50. If some of them
+// satify some conditions, we will translate them to StructuredBuffers
+// on Direct3D backend.
+//
+
+#include "compiler/translator/tree_ops/d3d/RecordUniformBlocksWithLargeArrayMember.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+// Only when a uniform block member's array size is greater than or equal to
+// kMinArraySizeUseStructuredBuffer, then we may translate the uniform block
+// to a StructuredBuffer on Direct3D backend.
+const unsigned int kMinArraySizeUseStructuredBuffer = 50u;
+
+// There is a maximum of D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT(128) slots that are
+// available for shader resources on Direct3D 11. When shader version is 300, we only use
+// D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT(16) slots for texture units. We allow StructuredBuffer
+// to use the maximum of 60 slots, that is enough here.
+const unsigned int kMaxAllowToUseRegisterCount = 60u;
+
+// Traverser that all uniform blocks which have one or more large array members, and the array
+// sizes are greater than or equal to 50.
+class UniformBlocksWithLargeArrayMemberTraverser : public TIntermTraverser
+{
+ public:
+ UniformBlocksWithLargeArrayMemberTraverser();
+
+ void visitSymbol(TIntermSymbol *node) override;
+ bool visitBinary(Visit visit, TIntermBinary *node) override;
+ std::map<int, const TInterfaceBlock *> &getUniformBlockMayTranslation()
+ {
+ return mUniformBlockMayTranslation;
+ }
+ std::map<int, const TInterfaceBlock *> &getUniformBlockNotAllowTranslation()
+ {
+ return mUniformBlockNotAllowTranslation;
+ }
+ std::map<int, unsigned int> &getUniformBlockUsedRegisterCount()
+ {
+ return mUniformBlockUsedRegisterCount;
+ }
+ std::map<int, const TInterfaceBlock *> &getUniformBlockWithLargeArrayMember()
+ {
+ return mUniformBlockWithLargeArrayMember;
+ }
+
+ private:
+ std::map<int, const TInterfaceBlock *> mUniformBlockMayTranslation;
+ std::map<int, const TInterfaceBlock *> mUniformBlockNotAllowTranslation;
+ std::map<int, unsigned int> mUniformBlockUsedRegisterCount;
+ std::map<int, const TInterfaceBlock *> mUniformBlockWithLargeArrayMember;
+};
+
+UniformBlocksWithLargeArrayMemberTraverser::UniformBlocksWithLargeArrayMemberTraverser()
+ : TIntermTraverser(true, true, false)
+{}
+
+static bool IsSupportedTypeForStructuredBuffer(const TType &type)
+{
+ const TStructure *structure = type.getStruct();
+ const TLayoutMatrixPacking matrixPacking = type.getLayoutQualifier().matrixPacking;
+ if (structure)
+ {
+ const TFieldList &fields = structure->fields();
+ for (size_t i = 0; i < fields.size(); i++)
+ {
+ const TType &fieldType = *fields[i]->type();
+ // Do not allow the structure's member is array or structure.
+ if (!fieldType.isArray() && !fieldType.getStruct() &&
+ (fieldType.isScalar() || fieldType.isVector() ||
+ (fieldType.isMatrix() &&
+ ((matrixPacking != EmpRowMajor && fieldType.getRows() == 4) ||
+ (matrixPacking == EmpRowMajor && fieldType.getCols() == 4)))))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ else if (type.isMatrix())
+ {
+ // Only supports the matrix types that we do not need to pad in a structure or an array
+ // explicitly.
+ return (matrixPacking != EmpRowMajor && type.getRows() == 4) ||
+ (matrixPacking == EmpRowMajor && type.getCols() == 4);
+ }
+ else
+ {
+ // Supports vector and scalar types in a structure or an array.
+ return true;
+ }
+}
+
+static bool CanTranslateUniformBlockToStructuredBuffer(const TInterfaceBlock &interfaceBlock)
+{
+ const TLayoutBlockStorage blockStorage = interfaceBlock.blockStorage();
+
+ if (blockStorage == EbsStd140 && interfaceBlock.fields().size() == 1u)
+ {
+ const TType &fieldType = *interfaceBlock.fields()[0]->type();
+ if (fieldType.getNumArraySizes() == 1u &&
+ fieldType.getOutermostArraySize() >= kMinArraySizeUseStructuredBuffer)
+ {
+ return IsSupportedTypeForStructuredBuffer(fieldType);
+ }
+ }
+
+ return false;
+}
+
+static bool FieldIsOrHasLargeArrayField(const TField &field)
+{
+ const TType *type = field.type();
+ if (type->getArraySizeProduct() >= kMinArraySizeUseStructuredBuffer)
+ {
+ return true;
+ }
+
+ const TStructure *structure = type->getStruct();
+ if (structure)
+ {
+ const TFieldList &fields = structure->fields();
+ bool hasLargeArrayField = false;
+ for (size_t i = 0; i < fields.size(); i++)
+ {
+ hasLargeArrayField = FieldIsOrHasLargeArrayField(*fields[i]);
+ if (hasLargeArrayField)
+ {
+ break;
+ }
+ }
+ return hasLargeArrayField;
+ }
+
+ return false;
+}
+
+static bool IsInterfaceBlockWithLargeArrayField(const TInterfaceBlock &interfaceBlock)
+{
+ const TFieldList &fields = interfaceBlock.fields();
+ bool isLargeArrayField = false;
+ for (size_t i = 0; i < fields.size(); i++)
+ {
+ isLargeArrayField = FieldIsOrHasLargeArrayField(*fields[i]);
+ if (isLargeArrayField)
+ {
+ break;
+ }
+ }
+
+ return isLargeArrayField;
+}
+
+void UniformBlocksWithLargeArrayMemberTraverser::visitSymbol(TIntermSymbol *node)
+{
+ const TVariable &variable = node->variable();
+ const TType &variableType = variable.getType();
+ TQualifier qualifier = variable.getType().getQualifier();
+
+ if (qualifier == EvqUniform)
+ {
+ const TInterfaceBlock *interfaceBlock = variableType.getInterfaceBlock();
+ if (interfaceBlock)
+ {
+ if (CanTranslateUniformBlockToStructuredBuffer(*interfaceBlock))
+ {
+ if (mUniformBlockMayTranslation.count(interfaceBlock->uniqueId().get()) == 0)
+ {
+ mUniformBlockMayTranslation[interfaceBlock->uniqueId().get()] = interfaceBlock;
+ }
+
+ if (!variableType.isInterfaceBlock())
+ {
+ TIntermNode *accessor = getAncestorNode(0);
+ TIntermBinary *accessorAsBinary = accessor->getAsBinaryNode();
+ // The uniform block variable is array type, only indexing operator is allowed
+ // to operate on the variable, otherwise do not translate the uniform block to
+ // HLSL StructuredBuffer.
+ if (!accessorAsBinary ||
+ !(accessorAsBinary && (accessorAsBinary->getOp() == EOpIndexDirect ||
+ accessorAsBinary->getOp() == EOpIndexIndirect)))
+ {
+ if (mUniformBlockNotAllowTranslation.count(
+ interfaceBlock->uniqueId().get()) == 0)
+ {
+ mUniformBlockNotAllowTranslation[interfaceBlock->uniqueId().get()] =
+ interfaceBlock;
+ }
+ }
+ else
+ {
+ if (mUniformBlockUsedRegisterCount.count(
+ interfaceBlock->uniqueId().get()) == 0)
+ {
+ // The uniform block is not an instanced one, so it only uses one
+ // register.
+ mUniformBlockUsedRegisterCount[interfaceBlock->uniqueId().get()] = 1;
+ }
+ }
+ }
+ else
+ {
+ if (mUniformBlockUsedRegisterCount.count(interfaceBlock->uniqueId().get()) == 0)
+ {
+ // The uniform block is an instanced one, the count of used registers
+ // depends on the array size of variable.
+ mUniformBlockUsedRegisterCount[interfaceBlock->uniqueId().get()] =
+ variableType.isArray() ? variableType.getOutermostArraySize() : 1;
+ }
+ }
+ }
+
+ if (interfaceBlock->blockStorage() == EbsStd140 &&
+ IsInterfaceBlockWithLargeArrayField(*interfaceBlock))
+ {
+ if (!variableType.isInterfaceBlock())
+ {
+ TIntermNode *accessor = getAncestorNode(0);
+ TIntermBinary *accessorAsBinary = accessor->getAsBinaryNode();
+ if (accessorAsBinary && (accessorAsBinary->getOp() == EOpIndexDirect ||
+ accessorAsBinary->getOp() == EOpIndexIndirect))
+ {
+ if (mUniformBlockWithLargeArrayMember.count(
+ interfaceBlock->uniqueId().get()) == 0)
+ {
+ mUniformBlockWithLargeArrayMember[interfaceBlock->uniqueId().get()] =
+ interfaceBlock;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+bool UniformBlocksWithLargeArrayMemberTraverser::visitBinary(Visit visit, TIntermBinary *node)
+{
+ switch (node->getOp())
+ {
+ case EOpIndexDirect:
+ {
+ if (visit == PreVisit)
+ {
+ const TType &leftType = node->getLeft()->getType();
+ if (leftType.isInterfaceBlock())
+ {
+ const TInterfaceBlock *interfaceBlock = leftType.getInterfaceBlock();
+ if (CanTranslateUniformBlockToStructuredBuffer(*interfaceBlock) &&
+ mUniformBlockMayTranslation.count(interfaceBlock->uniqueId().get()) == 0)
+ {
+ mUniformBlockMayTranslation[interfaceBlock->uniqueId().get()] =
+ interfaceBlock;
+ if (mUniformBlockUsedRegisterCount.count(
+ interfaceBlock->uniqueId().get()) == 0)
+ {
+ // The uniform block is an instanced one, the count of used registers
+ // depends on the array size of variable.
+ mUniformBlockUsedRegisterCount[interfaceBlock->uniqueId().get()] =
+ leftType.isArray() ? leftType.getOutermostArraySize() : 1;
+ }
+ return false;
+ }
+
+ if (interfaceBlock->blockStorage() == EbsStd140 &&
+ IsInterfaceBlockWithLargeArrayField(*interfaceBlock))
+ {
+ if (mUniformBlockWithLargeArrayMember.count(
+ interfaceBlock->uniqueId().get()) == 0)
+ {
+ mUniformBlockWithLargeArrayMember[interfaceBlock->uniqueId().get()] =
+ interfaceBlock;
+ }
+ }
+ }
+ }
+ break;
+ }
+ case EOpIndexDirectInterfaceBlock:
+ {
+ if (visit == InVisit)
+ {
+ const TInterfaceBlock *interfaceBlock =
+ node->getLeft()->getType().getInterfaceBlock();
+ if (CanTranslateUniformBlockToStructuredBuffer(*interfaceBlock))
+ {
+ TIntermNode *accessor = getAncestorNode(0);
+ TIntermBinary *accessorAsBinary = accessor->getAsBinaryNode();
+ // The uniform block variable is array type, only indexing operator is allowed
+ // to operate on the variable, otherwise do not translate the uniform block to
+ // HLSL StructuredBuffer.
+ if ((!accessorAsBinary ||
+ !(accessorAsBinary && (accessorAsBinary->getOp() == EOpIndexDirect ||
+ accessorAsBinary->getOp() == EOpIndexIndirect))) &&
+ mUniformBlockNotAllowTranslation.count(interfaceBlock->uniqueId().get()) ==
+ 0)
+ {
+ mUniformBlockNotAllowTranslation[interfaceBlock->uniqueId().get()] =
+ interfaceBlock;
+ return false;
+ }
+ }
+
+ if (interfaceBlock->blockStorage() == EbsStd140 &&
+ IsInterfaceBlockWithLargeArrayField(*interfaceBlock))
+ {
+ TIntermNode *accessor = getAncestorNode(0);
+ TIntermBinary *accessorAsBinary = accessor->getAsBinaryNode();
+ if (accessorAsBinary && (accessorAsBinary->getOp() == EOpIndexDirect ||
+ accessorAsBinary->getOp() == EOpIndexIndirect))
+ {
+ if (mUniformBlockWithLargeArrayMember.count(
+ interfaceBlock->uniqueId().get()) == 0)
+ {
+ mUniformBlockWithLargeArrayMember[interfaceBlock->uniqueId().get()] =
+ interfaceBlock;
+ }
+ }
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ return true;
+}
+} // namespace
+
+bool RecordUniformBlocksWithLargeArrayMember(
+ TIntermNode *root,
+ std::map<int, const TInterfaceBlock *> &uniformBlockOptimizedMap,
+ std::set<std::string> &slowCompilingUniformBlockSet)
+{
+ UniformBlocksWithLargeArrayMemberTraverser traverser;
+ root->traverse(&traverser);
+ std::map<int, const TInterfaceBlock *> &uniformBlockMayTranslation =
+ traverser.getUniformBlockMayTranslation();
+ std::map<int, const TInterfaceBlock *> &uniformBlockNotAllowTranslation =
+ traverser.getUniformBlockNotAllowTranslation();
+ std::map<int, unsigned int> &uniformBlockUsedRegisterCount =
+ traverser.getUniformBlockUsedRegisterCount();
+ std::map<int, const TInterfaceBlock *> &uniformBlockWithLargeArrayMember =
+ traverser.getUniformBlockWithLargeArrayMember();
+
+ unsigned int usedRegisterCount = 0;
+ for (auto &uniformBlock : uniformBlockMayTranslation)
+ {
+ if (uniformBlockNotAllowTranslation.count(uniformBlock.first) == 0)
+ {
+ usedRegisterCount += uniformBlockUsedRegisterCount[uniformBlock.first];
+ if (usedRegisterCount > kMaxAllowToUseRegisterCount)
+ {
+ break;
+ }
+ uniformBlockOptimizedMap[uniformBlock.first] = uniformBlock.second;
+ }
+ }
+
+ for (auto &uniformBlock : uniformBlockWithLargeArrayMember)
+ {
+ if (uniformBlockOptimizedMap.count(uniformBlock.first) == 0)
+ {
+ slowCompilingUniformBlockSet.insert(uniformBlock.second->name().data());
+ }
+ }
+
+ return true;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RecordUniformBlocksWithLargeArrayMember.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RecordUniformBlocksWithLargeArrayMember.h
new file mode 100644
index 0000000000..d7825c28cb
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RecordUniformBlocksWithLargeArrayMember.h
@@ -0,0 +1,28 @@
+//
+// Copyright 2020 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.
+//
+// RecordUniformBlocksWithLargeArrayMember.h:
+// Collect all uniform blocks which have one or more large array members,
+// and the array sizes are greater than or equal to 50. If some of them
+// satify some conditions, we will translate them to StructuredBuffers
+// on Direct3D backend.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_D3D_RECORDUNIFORMBLOCKSWITHLARGEARRAYMEMBER_H_
+#define COMPILER_TRANSLATOR_TREEOPS_D3D_RECORDUNIFORMBLOCKSWITHLARGEARRAYMEMBER_H_
+
+#include "compiler/translator/IntermNode.h"
+
+namespace sh
+{
+class TIntermNode;
+
+[[nodiscard]] bool RecordUniformBlocksWithLargeArrayMember(
+ TIntermNode *root,
+ std::map<int, const TInterfaceBlock *> &uniformBlockOptimizedMap,
+ std::set<std::string> &slowCompilingUniformBlockSet);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_D3D_RECORDUNIFORMBLOCKSWITHLARGEARRAYMEMBER_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RemoveSwitchFallThrough.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RemoveSwitchFallThrough.cpp
new file mode 100644
index 0000000000..6360f1083c
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RemoveSwitchFallThrough.cpp
@@ -0,0 +1,270 @@
+//
+// Copyright 2002 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.
+//
+// RemoveSwitchFallThrough.cpp: Remove fall-through from switch statements.
+// Note that it is unsafe to do further AST transformations on the AST generated
+// by this function. It leaves duplicate nodes in the AST making replacements
+// unreliable.
+
+#include "compiler/translator/tree_ops/d3d/RemoveSwitchFallThrough.h"
+
+#include "compiler/translator/Diagnostics.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class RemoveSwitchFallThroughTraverser : public TIntermTraverser
+{
+ public:
+ static TIntermBlock *removeFallThrough(TIntermBlock *statementList,
+ PerformanceDiagnostics *perfDiagnostics);
+
+ private:
+ RemoveSwitchFallThroughTraverser(TIntermBlock *statementList,
+ PerformanceDiagnostics *perfDiagnostics);
+
+ void visitSymbol(TIntermSymbol *node) override;
+ void visitConstantUnion(TIntermConstantUnion *node) override;
+ bool visitDeclaration(Visit, TIntermDeclaration *node) override;
+ bool visitBinary(Visit, TIntermBinary *node) override;
+ bool visitUnary(Visit, TIntermUnary *node) override;
+ bool visitTernary(Visit visit, TIntermTernary *node) override;
+ bool visitSwizzle(Visit, TIntermSwizzle *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;
+ bool visitBlock(Visit, TIntermBlock *node) override;
+ bool visitLoop(Visit, TIntermLoop *node) override;
+ bool visitBranch(Visit, TIntermBranch *node) override;
+
+ void outputSequence(TIntermSequence *sequence, size_t startIndex);
+ void handlePreviousCase();
+
+ TIntermBlock *mStatementList;
+ TIntermBlock *mStatementListOut;
+ bool mLastStatementWasBreak;
+ TIntermBlock *mPreviousCase;
+ std::vector<TIntermBlock *> mCasesSharingBreak;
+ PerformanceDiagnostics *mPerfDiagnostics;
+};
+
+TIntermBlock *RemoveSwitchFallThroughTraverser::removeFallThrough(
+ TIntermBlock *statementList,
+ PerformanceDiagnostics *perfDiagnostics)
+{
+ RemoveSwitchFallThroughTraverser rm(statementList, perfDiagnostics);
+ ASSERT(statementList);
+ statementList->traverse(&rm);
+ ASSERT(rm.mPreviousCase || statementList->getSequence()->empty());
+ if (!rm.mLastStatementWasBreak && rm.mPreviousCase)
+ {
+ // Make sure that there's a branch at the end of the final case inside the switch statement.
+ // This also ensures that any cases that fall through to the final case will get the break.
+ TIntermBranch *finalBreak = new TIntermBranch(EOpBreak, nullptr);
+ rm.mPreviousCase->getSequence()->push_back(finalBreak);
+ rm.mLastStatementWasBreak = true;
+ }
+ rm.handlePreviousCase();
+ return rm.mStatementListOut;
+}
+
+RemoveSwitchFallThroughTraverser::RemoveSwitchFallThroughTraverser(
+ TIntermBlock *statementList,
+ PerformanceDiagnostics *perfDiagnostics)
+ : TIntermTraverser(true, false, false),
+ mStatementList(statementList),
+ mLastStatementWasBreak(false),
+ mPreviousCase(nullptr),
+ mPerfDiagnostics(perfDiagnostics)
+{
+ mStatementListOut = new TIntermBlock();
+}
+
+void RemoveSwitchFallThroughTraverser::visitSymbol(TIntermSymbol *node)
+{
+ // Note that this assumes that switch statements which don't begin by a case statement
+ // have already been weeded out in validation.
+ mPreviousCase->getSequence()->push_back(node);
+ mLastStatementWasBreak = false;
+}
+
+void RemoveSwitchFallThroughTraverser::visitConstantUnion(TIntermConstantUnion *node)
+{
+ // Conditions of case labels are not traversed, so this is a constant statement like "0;".
+ // These are no-ops so there's no need to add them back to the statement list. Should have
+ // already been pruned out of the AST, in fact.
+ UNREACHABLE();
+}
+
+bool RemoveSwitchFallThroughTraverser::visitDeclaration(Visit, TIntermDeclaration *node)
+{
+ mPreviousCase->getSequence()->push_back(node);
+ mLastStatementWasBreak = false;
+ return false;
+}
+
+bool RemoveSwitchFallThroughTraverser::visitBinary(Visit, TIntermBinary *node)
+{
+ mPreviousCase->getSequence()->push_back(node);
+ mLastStatementWasBreak = false;
+ return false;
+}
+
+bool RemoveSwitchFallThroughTraverser::visitUnary(Visit, TIntermUnary *node)
+{
+ mPreviousCase->getSequence()->push_back(node);
+ mLastStatementWasBreak = false;
+ return false;
+}
+
+bool RemoveSwitchFallThroughTraverser::visitTernary(Visit, TIntermTernary *node)
+{
+ mPreviousCase->getSequence()->push_back(node);
+ mLastStatementWasBreak = false;
+ return false;
+}
+
+bool RemoveSwitchFallThroughTraverser::visitSwizzle(Visit, TIntermSwizzle *node)
+{
+ mPreviousCase->getSequence()->push_back(node);
+ mLastStatementWasBreak = false;
+ return false;
+}
+
+bool RemoveSwitchFallThroughTraverser::visitIfElse(Visit, TIntermIfElse *node)
+{
+ mPreviousCase->getSequence()->push_back(node);
+ mLastStatementWasBreak = false;
+ return false;
+}
+
+bool RemoveSwitchFallThroughTraverser::visitSwitch(Visit, TIntermSwitch *node)
+{
+ mPreviousCase->getSequence()->push_back(node);
+ mLastStatementWasBreak = false;
+ // Don't go into nested switch statements
+ return false;
+}
+
+void RemoveSwitchFallThroughTraverser::outputSequence(TIntermSequence *sequence, size_t startIndex)
+{
+ for (size_t i = startIndex; i < sequence->size(); ++i)
+ {
+ mStatementListOut->getSequence()->push_back(sequence->at(i));
+ }
+}
+
+void RemoveSwitchFallThroughTraverser::handlePreviousCase()
+{
+ if (mPreviousCase)
+ mCasesSharingBreak.push_back(mPreviousCase);
+ if (mLastStatementWasBreak)
+ {
+ for (size_t i = 0; i < mCasesSharingBreak.size(); ++i)
+ {
+ ASSERT(!mCasesSharingBreak.at(i)->getSequence()->empty());
+ if (mCasesSharingBreak.at(i)->getSequence()->size() == 1)
+ {
+ // Fall-through is allowed in case the label has no statements.
+ outputSequence(mCasesSharingBreak.at(i)->getSequence(), 0);
+ }
+ else
+ {
+ // Include all the statements that this case can fall through under the same label.
+ if (mCasesSharingBreak.size() > i + 1u)
+ {
+ mPerfDiagnostics->warning(mCasesSharingBreak.at(i)->getLine(),
+ "Performance: non-empty fall-through cases in "
+ "switch statements generate extra code.",
+ "switch");
+ }
+ for (size_t j = i; j < mCasesSharingBreak.size(); ++j)
+ {
+ size_t startIndex =
+ j > i ? 1 : 0; // Add the label only from the first sequence.
+ outputSequence(mCasesSharingBreak.at(j)->getSequence(), startIndex);
+ }
+ }
+ }
+ mCasesSharingBreak.clear();
+ }
+ mLastStatementWasBreak = false;
+ mPreviousCase = nullptr;
+}
+
+bool RemoveSwitchFallThroughTraverser::visitCase(Visit, TIntermCase *node)
+{
+ handlePreviousCase();
+ mPreviousCase = new TIntermBlock();
+ mPreviousCase->getSequence()->push_back(node);
+ mPreviousCase->setLine(node->getLine());
+ // Don't traverse the condition of the case statement
+ return false;
+}
+
+bool RemoveSwitchFallThroughTraverser::visitAggregate(Visit, TIntermAggregate *node)
+{
+ mPreviousCase->getSequence()->push_back(node);
+ mLastStatementWasBreak = false;
+ return false;
+}
+
+bool DoesBlockAlwaysBreak(TIntermBlock *node)
+{
+ if (node->getSequence()->empty())
+ {
+ return false;
+ }
+
+ TIntermBlock *lastStatementAsBlock = node->getSequence()->back()->getAsBlock();
+ if (lastStatementAsBlock)
+ {
+ return DoesBlockAlwaysBreak(lastStatementAsBlock);
+ }
+
+ TIntermBranch *lastStatementAsBranch = node->getSequence()->back()->getAsBranchNode();
+ return lastStatementAsBranch != nullptr;
+}
+
+bool RemoveSwitchFallThroughTraverser::visitBlock(Visit, TIntermBlock *node)
+{
+ if (node != mStatementList)
+ {
+ mPreviousCase->getSequence()->push_back(node);
+ mLastStatementWasBreak = DoesBlockAlwaysBreak(node);
+ return false;
+ }
+ return true;
+}
+
+bool RemoveSwitchFallThroughTraverser::visitLoop(Visit, TIntermLoop *node)
+{
+ mPreviousCase->getSequence()->push_back(node);
+ mLastStatementWasBreak = false;
+ return false;
+}
+
+bool RemoveSwitchFallThroughTraverser::visitBranch(Visit, TIntermBranch *node)
+{
+ mPreviousCase->getSequence()->push_back(node);
+ // TODO: Verify that accepting return or continue statements here doesn't cause problems.
+ mLastStatementWasBreak = true;
+ return false;
+}
+
+} // anonymous namespace
+
+TIntermBlock *RemoveSwitchFallThrough(TIntermBlock *statementList,
+ PerformanceDiagnostics *perfDiagnostics)
+{
+ return RemoveSwitchFallThroughTraverser::removeFallThrough(statementList, perfDiagnostics);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RemoveSwitchFallThrough.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RemoveSwitchFallThrough.h
new file mode 100644
index 0000000000..b92e7e5f6d
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RemoveSwitchFallThrough.h
@@ -0,0 +1,27 @@
+//
+// Copyright 2002 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.
+//
+// RemoveSwitchFallThrough.h: Remove fall-through from switch statements.
+// Note that it is unsafe to do further AST transformations on the AST generated
+// by this function. It leaves duplicate nodes in the AST making replacements
+// unreliable.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_D3D_REMOVESWITCHFALLTHROUGH_H_
+#define COMPILER_TRANSLATOR_TREEOPS_D3D_REMOVESWITCHFALLTHROUGH_H_
+
+namespace sh
+{
+
+class TIntermBlock;
+class PerformanceDiagnostics;
+
+// When given a statementList from a switch AST node, return an updated
+// statementList that has fall-through removed.
+TIntermBlock *RemoveSwitchFallThrough(TIntermBlock *statementList,
+ PerformanceDiagnostics *perfDiagnostics);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_D3D_REMOVESWITCHFALLTHROUGH_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteAtomicFunctionExpressions.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteAtomicFunctionExpressions.cpp
new file mode 100644
index 0000000000..b2de6079b7
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteAtomicFunctionExpressions.cpp
@@ -0,0 +1,183 @@
+//
+// Copyright 2018 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 function RewriteAtomicFunctionExpressions.
+// See the header for more details.
+
+#include "compiler/translator/tree_ops/d3d/RewriteAtomicFunctionExpressions.h"
+
+#include "compiler/translator/tree_util/IntermNodePatternMatcher.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+namespace
+{
+// Traverser that simplifies all the atomic function expressions into the ones that can be directly
+// translated into HLSL.
+//
+// case 1 (only for atomicExchange and atomicCompSwap):
+// original:
+// atomicExchange(counter, newValue);
+// new:
+// tempValue = atomicExchange(counter, newValue);
+//
+// case 2 (atomic function, temporary variable required):
+// original:
+// value = atomicAdd(counter, 1) * otherValue;
+// someArray[atomicAdd(counter, 1)] = someOtherValue;
+// new:
+// value = ((tempValue = atomicAdd(counter, 1)), tempValue) * otherValue;
+// someArray[((tempValue = atomicAdd(counter, 1)), tempValue)] = someOtherValue;
+//
+// case 3 (atomic function used directly initialize a variable):
+// original:
+// int value = atomicAdd(counter, 1);
+// new:
+// tempValue = atomicAdd(counter, 1);
+// int value = tempValue;
+//
+class RewriteAtomicFunctionExpressionsTraverser : public TIntermTraverser
+{
+ public:
+ RewriteAtomicFunctionExpressionsTraverser(TSymbolTable *symbolTable, int shaderVersion);
+
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override;
+ bool visitBlock(Visit visit, TIntermBlock *node) override;
+
+ private:
+ static bool IsAtomicExchangeOrCompSwapNoReturnValue(TIntermAggregate *node,
+ TIntermNode *parentNode);
+ static bool IsAtomicFunctionInsideExpression(TIntermAggregate *node, TIntermNode *parentNode);
+
+ void rewriteAtomicFunctionCallNode(TIntermAggregate *oldAtomicFunctionNode);
+
+ const TVariable *getTempVariable(const TType *type);
+
+ int mShaderVersion;
+ TIntermSequence mTempVariables;
+};
+
+RewriteAtomicFunctionExpressionsTraverser::RewriteAtomicFunctionExpressionsTraverser(
+ TSymbolTable *symbolTable,
+ int shaderVersion)
+ : TIntermTraverser(false, false, true, symbolTable), mShaderVersion(shaderVersion)
+{}
+
+void RewriteAtomicFunctionExpressionsTraverser::rewriteAtomicFunctionCallNode(
+ TIntermAggregate *oldAtomicFunctionNode)
+{
+ ASSERT(oldAtomicFunctionNode);
+
+ const TVariable *returnVariable = getTempVariable(&oldAtomicFunctionNode->getType());
+
+ TIntermBinary *rewrittenNode = new TIntermBinary(
+ TOperator::EOpAssign, CreateTempSymbolNode(returnVariable), oldAtomicFunctionNode);
+
+ auto *parentNode = getParentNode();
+
+ auto *parentBinary = parentNode->getAsBinaryNode();
+ if (parentBinary && parentBinary->getOp() == EOpInitialize)
+ {
+ insertStatementInParentBlock(rewrittenNode);
+ queueReplacement(CreateTempSymbolNode(returnVariable), OriginalNode::IS_DROPPED);
+ }
+ else
+ {
+ // As all atomic function assignment will be converted to the last argument of an
+ // interlocked function, if we need the return value, assignment needs to be wrapped with
+ // the comma operator and the temporary variables.
+ if (!parentNode->getAsBlock())
+ {
+ rewrittenNode = TIntermBinary::CreateComma(
+ rewrittenNode, new TIntermSymbol(returnVariable), mShaderVersion);
+ }
+
+ queueReplacement(rewrittenNode, OriginalNode::IS_DROPPED);
+ }
+}
+
+const TVariable *RewriteAtomicFunctionExpressionsTraverser::getTempVariable(const TType *type)
+{
+ TIntermDeclaration *variableDeclaration;
+ TVariable *returnVariable =
+ DeclareTempVariable(mSymbolTable, type, EvqTemporary, &variableDeclaration);
+ mTempVariables.push_back(variableDeclaration);
+ return returnVariable;
+}
+
+bool RewriteAtomicFunctionExpressionsTraverser::IsAtomicExchangeOrCompSwapNoReturnValue(
+ TIntermAggregate *node,
+ TIntermNode *parentNode)
+{
+ ASSERT(node);
+ return (node->getOp() == EOpAtomicExchange || node->getOp() == EOpAtomicCompSwap) &&
+ parentNode && parentNode->getAsBlock();
+}
+
+bool RewriteAtomicFunctionExpressionsTraverser::IsAtomicFunctionInsideExpression(
+ TIntermAggregate *node,
+ TIntermNode *parentNode)
+{
+ ASSERT(node);
+ // We only need to handle atomic functions with a parent that it is not block nodes. If the
+ // parent node is block, it means that the atomic function is not inside an expression.
+ if (!BuiltInGroup::IsAtomicMemory(node->getOp()) || parentNode->getAsBlock())
+ {
+ return false;
+ }
+
+ auto *parentAsBinary = parentNode->getAsBinaryNode();
+ // Assignments are handled in OutputHLSL
+ return !parentAsBinary || parentAsBinary->getOp() != EOpAssign;
+}
+
+bool RewriteAtomicFunctionExpressionsTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
+{
+ ASSERT(visit == PostVisit);
+ // Skip atomic memory functions for SSBO. They will be processed in the OutputHLSL traverser.
+ if (BuiltInGroup::IsAtomicMemory(node->getOp()) &&
+ IsInShaderStorageBlock((*node->getSequence())[0]->getAsTyped()))
+ {
+ return false;
+ }
+
+ TIntermNode *parentNode = getParentNode();
+ if (IsAtomicExchangeOrCompSwapNoReturnValue(node, parentNode) ||
+ IsAtomicFunctionInsideExpression(node, parentNode))
+ {
+ rewriteAtomicFunctionCallNode(node);
+ }
+
+ return true;
+}
+
+bool RewriteAtomicFunctionExpressionsTraverser::visitBlock(Visit visit, TIntermBlock *node)
+{
+ ASSERT(visit == PostVisit);
+
+ if (!mTempVariables.empty() && getParentNode()->getAsFunctionDefinition())
+ {
+ insertStatementsInBlockAtPosition(node, 0, mTempVariables, TIntermSequence());
+ mTempVariables.clear();
+ }
+
+ return true;
+}
+
+} // anonymous namespace
+
+bool RewriteAtomicFunctionExpressions(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable,
+ int shaderVersion)
+{
+ RewriteAtomicFunctionExpressionsTraverser traverser(symbolTable, shaderVersion);
+ traverser.traverse(root);
+ return traverser.updateTree(compiler, root);
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteAtomicFunctionExpressions.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteAtomicFunctionExpressions.h
new file mode 100644
index 0000000000..60e6ffa2d1
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteAtomicFunctionExpressions.h
@@ -0,0 +1,42 @@
+//
+// Copyright 2018 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.
+//
+// RewriteAtomicFunctionExpressions rewrites the expressions that contain
+// atomic function calls and cannot be directly translated into HLSL into
+// several simple ones that can be easily handled in the HLSL translator.
+//
+// We need to rewite these expressions because:
+// 1. All GLSL atomic functions have return values, which all represent the
+// original value of the shared or ssbo variable; while all HLSL atomic
+// functions don't, and the original value can be stored in the last
+// parameter of the function call.
+// 2. For HLSL atomic functions, the last parameter that stores the original
+// value is optional except for InterlockedExchange and
+// InterlockedCompareExchange. Missing original_value in the call of
+// InterlockedExchange or InterlockedCompareExchange results in a compile
+// error from HLSL compiler.
+//
+// RewriteAtomicFunctionExpressions is a function that can modify the AST
+// to ensure all the expressions that contain atomic function calls can be
+// directly translated into HLSL expressions.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_D3D_REWRITE_ATOMIC_FUNCTION_EXPRESSIONS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_D3D_REWRITE_ATOMIC_FUNCTION_EXPRESSIONS_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermNode;
+class TSymbolTable;
+
+[[nodiscard]] bool RewriteAtomicFunctionExpressions(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable,
+ int shaderVersion);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_D3D_REWRITE_ATOMIC_FUNCTION_EXPRESSIONS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteElseBlocks.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteElseBlocks.cpp
new file mode 100644
index 0000000000..10647d1bf1
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteElseBlocks.cpp
@@ -0,0 +1,123 @@
+//
+// 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.
+//
+// RewriteElseBlocks.cpp: Implementation for tree transform to change
+// all if-else blocks to if-if blocks.
+//
+
+#include "compiler/translator/tree_ops/d3d/RewriteElseBlocks.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/NodeSearch.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class ElseBlockRewriter : public TIntermTraverser
+{
+ public:
+ ElseBlockRewriter(TSymbolTable *symbolTable);
+
+ protected:
+ bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *aggregate) override;
+ bool visitBlock(Visit visit, TIntermBlock *block) override;
+
+ private:
+ TIntermNode *rewriteIfElse(TIntermIfElse *ifElse);
+
+ const TType *mFunctionType;
+};
+
+ElseBlockRewriter::ElseBlockRewriter(TSymbolTable *symbolTable)
+ : TIntermTraverser(true, false, true, symbolTable), mFunctionType(nullptr)
+{}
+
+bool ElseBlockRewriter::visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node)
+{
+ // Store the current function context (see comment below)
+ mFunctionType = ((visit == PreVisit) ? &node->getFunctionPrototype()->getType() : nullptr);
+ return true;
+}
+
+bool ElseBlockRewriter::visitBlock(Visit visit, TIntermBlock *node)
+{
+ if (visit == PostVisit)
+ {
+ for (size_t statementIndex = 0; statementIndex != node->getSequence()->size();
+ statementIndex++)
+ {
+ TIntermNode *statement = (*node->getSequence())[statementIndex];
+ TIntermIfElse *ifElse = statement->getAsIfElseNode();
+ if (ifElse && ifElse->getFalseBlock() != nullptr)
+ {
+ (*node->getSequence())[statementIndex] = rewriteIfElse(ifElse);
+ }
+ }
+ }
+ return true;
+}
+
+TIntermNode *ElseBlockRewriter::rewriteIfElse(TIntermIfElse *ifElse)
+{
+ ASSERT(ifElse != nullptr);
+
+ TIntermDeclaration *storeCondition = nullptr;
+ TVariable *conditionVariable =
+ DeclareTempVariable(mSymbolTable, ifElse->getCondition(), EvqTemporary, &storeCondition);
+
+ TIntermBlock *falseBlock = nullptr;
+
+ TType boolType(EbtBool, EbpUndefined, EvqTemporary);
+
+ if (ifElse->getFalseBlock())
+ {
+ TIntermBlock *negatedElse = nullptr;
+ // crbug.com/346463
+ // D3D generates error messages claiming a function has no return value, when rewriting
+ // an if-else clause that returns something non-void in a function. By appending mock
+ // returns (that are unreachable) we can silence this compile error.
+ if (mFunctionType && mFunctionType->getBasicType() != EbtVoid)
+ {
+ TIntermNode *returnNode = new TIntermBranch(EOpReturn, CreateZeroNode(*mFunctionType));
+ negatedElse = new TIntermBlock();
+ negatedElse->appendStatement(returnNode);
+ }
+
+ TIntermSymbol *conditionSymbolElse = CreateTempSymbolNode(conditionVariable);
+ TIntermUnary *negatedCondition =
+ new TIntermUnary(EOpLogicalNot, conditionSymbolElse, nullptr);
+ TIntermIfElse *falseIfElse =
+ new TIntermIfElse(negatedCondition, ifElse->getFalseBlock(), negatedElse);
+ falseBlock = EnsureBlock(falseIfElse);
+ }
+
+ TIntermSymbol *conditionSymbolSel = CreateTempSymbolNode(conditionVariable);
+ TIntermIfElse *newIfElse =
+ new TIntermIfElse(conditionSymbolSel, ifElse->getTrueBlock(), falseBlock);
+
+ TIntermBlock *block = new TIntermBlock();
+ block->getSequence()->push_back(storeCondition);
+ block->getSequence()->push_back(newIfElse);
+
+ return block;
+}
+
+} // anonymous namespace
+
+bool RewriteElseBlocks(TCompiler *compiler, TIntermNode *node, TSymbolTable *symbolTable)
+{
+ ElseBlockRewriter rewriter(symbolTable);
+ node->traverse(&rewriter);
+
+ return compiler->validateAST(node);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteElseBlocks.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteElseBlocks.h
new file mode 100644
index 0000000000..cab0f7090c
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteElseBlocks.h
@@ -0,0 +1,27 @@
+//
+// 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.
+//
+// RewriteElseBlocks.h: Prototype for tree transform to change
+// all if-else blocks to if-if blocks.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_D3D_REWRITEELSEBLOCKS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_D3D_REWRITEELSEBLOCKS_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermNode;
+class TSymbolTable;
+
+[[nodiscard]] bool RewriteElseBlocks(TCompiler *compiler,
+ TIntermNode *node,
+ TSymbolTable *symbolTable);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_D3D_REWRITEELSEBLOCKS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteExpressionsWithShaderStorageBlock.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteExpressionsWithShaderStorageBlock.cpp
new file mode 100644
index 0000000000..709f394878
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteExpressionsWithShaderStorageBlock.cpp
@@ -0,0 +1,420 @@
+//
+// Copyright 2018 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.
+//
+// RewriteExpressionsWithShaderStorageBlock rewrites the expressions that contain shader storage
+// block calls into several simple ones that can be easily handled in the HLSL translator. After the
+// AST pass, all ssbo related blocks will be like below:
+// ssbo_access_chain = ssbo_access_chain;
+// ssbo_access_chain = expr_no_ssbo;
+// lvalue_no_ssbo = ssbo_access_chain;
+//
+
+#include "compiler/translator/tree_ops/d3d/RewriteExpressionsWithShaderStorageBlock.h"
+
+#include "compiler/translator/Symbol.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+namespace
+{
+
+bool IsIncrementOrDecrementOperator(TOperator op)
+{
+ switch (op)
+ {
+ case EOpPostIncrement:
+ case EOpPostDecrement:
+ case EOpPreIncrement:
+ case EOpPreDecrement:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool IsCompoundAssignment(TOperator op)
+{
+ switch (op)
+ {
+ 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;
+ }
+}
+
+// EOpIndexDirect, EOpIndexIndirect, EOpIndexDirectStruct, EOpIndexDirectInterfaceBlock belong to
+// operators in SSBO access chain.
+bool IsReadonlyBinaryOperatorNotInSSBOAccessChain(TOperator op)
+{
+ switch (op)
+ {
+ case EOpComma:
+ case EOpAdd:
+ case EOpSub:
+ case EOpMul:
+ case EOpDiv:
+ case EOpIMod:
+ case EOpBitShiftLeft:
+ case EOpBitShiftRight:
+ case EOpBitwiseAnd:
+ case EOpBitwiseXor:
+ case EOpBitwiseOr:
+ case EOpEqual:
+ case EOpNotEqual:
+ case EOpLessThan:
+ case EOpGreaterThan:
+ case EOpLessThanEqual:
+ case EOpGreaterThanEqual:
+ case EOpVectorTimesScalar:
+ case EOpMatrixTimesScalar:
+ case EOpVectorTimesMatrix:
+ case EOpMatrixTimesVector:
+ case EOpMatrixTimesMatrix:
+ case EOpLogicalOr:
+ case EOpLogicalXor:
+ case EOpLogicalAnd:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool HasSSBOAsFunctionArgument(TIntermSequence *arguments)
+{
+ for (TIntermNode *arg : *arguments)
+ {
+ TIntermTyped *typedArg = arg->getAsTyped();
+ if (IsInShaderStorageBlock(typedArg))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+class RewriteExpressionsWithShaderStorageBlockTraverser : public TIntermTraverser
+{
+ public:
+ RewriteExpressionsWithShaderStorageBlockTraverser(TSymbolTable *symbolTable);
+ void nextIteration();
+ bool foundSSBO() const { return mFoundSSBO; }
+
+ private:
+ bool visitBinary(Visit, TIntermBinary *node) override;
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override;
+ bool visitUnary(Visit visit, TIntermUnary *node) override;
+
+ TIntermSymbol *insertInitStatementAndReturnTempSymbol(TIntermTyped *node,
+ TIntermSequence *insertions);
+
+ bool mFoundSSBO;
+};
+
+RewriteExpressionsWithShaderStorageBlockTraverser::
+ RewriteExpressionsWithShaderStorageBlockTraverser(TSymbolTable *symbolTable)
+ : TIntermTraverser(true, true, false, symbolTable), mFoundSSBO(false)
+{}
+
+TIntermSymbol *
+RewriteExpressionsWithShaderStorageBlockTraverser::insertInitStatementAndReturnTempSymbol(
+ TIntermTyped *node,
+ TIntermSequence *insertions)
+{
+ TIntermDeclaration *variableDeclaration;
+ TVariable *tempVariable =
+ DeclareTempVariable(mSymbolTable, node, EvqTemporary, &variableDeclaration);
+
+ insertions->push_back(variableDeclaration);
+ return CreateTempSymbolNode(tempVariable);
+}
+
+bool RewriteExpressionsWithShaderStorageBlockTraverser::visitBinary(Visit visit,
+ TIntermBinary *node)
+{
+ // Make sure that the expression is caculated from left to right.
+ if (visit != InVisit)
+ {
+ return true;
+ }
+
+ if (mFoundSSBO)
+ {
+ return false;
+ }
+
+ bool rightSSBO = IsInShaderStorageBlock(node->getRight());
+ bool leftSSBO = IsInShaderStorageBlock(node->getLeft());
+ if (!leftSSBO && !rightSSBO)
+ {
+ return true;
+ }
+
+ // case 1: Compound assigment operator
+ // original:
+ // lssbo += expr;
+ // new:
+ // var rvalue = expr;
+ // var temp = lssbo;
+ // temp += rvalue;
+ // lssbo = temp;
+ //
+ // original:
+ // lvalue_no_ssbo += rssbo;
+ // new:
+ // var rvalue = rssbo;
+ // lvalue_no_ssbo += rvalue;
+ if (IsCompoundAssignment(node->getOp()))
+ {
+ mFoundSSBO = true;
+ TIntermSequence insertions;
+ TIntermTyped *rightNode =
+ insertInitStatementAndReturnTempSymbol(node->getRight(), &insertions);
+ if (leftSSBO)
+ {
+ TIntermSymbol *tempSymbol =
+ insertInitStatementAndReturnTempSymbol(node->getLeft()->deepCopy(), &insertions);
+ TIntermBinary *tempCompoundOperate =
+ new TIntermBinary(node->getOp(), tempSymbol->deepCopy(), rightNode->deepCopy());
+ insertions.push_back(tempCompoundOperate);
+ insertStatementsInParentBlock(insertions);
+
+ TIntermBinary *assignTempValueToSSBO =
+ new TIntermBinary(EOpAssign, node->getLeft(), tempSymbol->deepCopy());
+ queueReplacement(assignTempValueToSSBO, OriginalNode::IS_DROPPED);
+ }
+ else
+ {
+ insertStatementsInParentBlock(insertions);
+ TIntermBinary *compoundAssignRValueToLValue =
+ new TIntermBinary(node->getOp(), node->getLeft(), rightNode->deepCopy());
+ queueReplacement(compoundAssignRValueToLValue, OriginalNode::IS_DROPPED);
+ }
+ }
+ // case 2: Readonly binary operator
+ // original:
+ // ssbo0 + ssbo1 + ssbo2;
+ // new:
+ // var temp0 = ssbo0;
+ // var temp1 = ssbo1;
+ // var temp2 = ssbo2;
+ // temp0 + temp1 + temp2;
+ else if (IsReadonlyBinaryOperatorNotInSSBOAccessChain(node->getOp()) && (leftSSBO || rightSSBO))
+ {
+ mFoundSSBO = true;
+ TIntermTyped *rightNode = node->getRight();
+ TIntermTyped *leftNode = node->getLeft();
+ TIntermSequence insertions;
+ if (rightSSBO)
+ {
+ rightNode = insertInitStatementAndReturnTempSymbol(node->getRight(), &insertions);
+ }
+ if (leftSSBO)
+ {
+ leftNode = insertInitStatementAndReturnTempSymbol(node->getLeft(), &insertions);
+ }
+
+ insertStatementsInParentBlock(insertions);
+ TIntermBinary *newExpr =
+ new TIntermBinary(node->getOp(), leftNode->deepCopy(), rightNode->deepCopy());
+ queueReplacement(newExpr, OriginalNode::IS_DROPPED);
+ }
+ return !mFoundSSBO;
+}
+
+// case 3: ssbo as the argument of aggregate type
+// original:
+// foo(ssbo);
+// new:
+// var tempArg = ssbo;
+// foo(tempArg);
+// ssbo = tempArg; (Optional based on whether ssbo is an out|input argument)
+//
+// original:
+// foo(ssbo) * expr;
+// new:
+// var tempArg = ssbo;
+// var tempReturn = foo(tempArg);
+// ssbo = tempArg; (Optional based on whether ssbo is an out|input argument)
+// tempReturn * expr;
+bool RewriteExpressionsWithShaderStorageBlockTraverser::visitAggregate(Visit visit,
+ TIntermAggregate *node)
+{
+ // Make sure that visitAggregate is only executed once for same node.
+ if (visit != PreVisit)
+ {
+ return true;
+ }
+
+ if (mFoundSSBO)
+ {
+ return false;
+ }
+
+ // We still need to process the ssbo as the non-first argument of atomic memory functions.
+ if (BuiltInGroup::IsAtomicMemory(node->getOp()) &&
+ IsInShaderStorageBlock((*node->getSequence())[0]->getAsTyped()))
+ {
+ return true;
+ }
+
+ if (!HasSSBOAsFunctionArgument(node->getSequence()))
+ {
+ return true;
+ }
+
+ mFoundSSBO = true;
+ TIntermSequence insertions;
+ TIntermSequence readBackToSSBOs;
+ TIntermSequence *originalArguments = node->getSequence();
+ for (size_t i = 0; i < node->getChildCount(); ++i)
+ {
+ TIntermTyped *ssboArgument = (*originalArguments)[i]->getAsTyped();
+ if (IsInShaderStorageBlock(ssboArgument))
+ {
+ TIntermSymbol *argumentCopy =
+ insertInitStatementAndReturnTempSymbol(ssboArgument, &insertions);
+ if (node->getFunction() != nullptr)
+ {
+ TQualifier qual = node->getFunction()->getParam(i)->getType().getQualifier();
+ if (qual == EvqParamInOut || qual == EvqParamOut)
+ {
+ TIntermBinary *readBackToSSBO = new TIntermBinary(
+ EOpAssign, ssboArgument->deepCopy(), argumentCopy->deepCopy());
+ readBackToSSBOs.push_back(readBackToSSBO);
+ }
+ }
+ node->replaceChildNode(ssboArgument, argumentCopy);
+ }
+ }
+
+ TIntermBlock *parentBlock = getParentNode()->getAsBlock();
+ if (parentBlock)
+ {
+ // Aggregate node is as a single sentence.
+ insertions.push_back(node);
+ if (!readBackToSSBOs.empty())
+ {
+ insertions.insert(insertions.end(), readBackToSSBOs.begin(), readBackToSSBOs.end());
+ }
+ mMultiReplacements.emplace_back(parentBlock, node, std::move(insertions));
+ }
+ else
+ {
+ // Aggregate node is inside an expression.
+ TIntermSymbol *tempSymbol = insertInitStatementAndReturnTempSymbol(node, &insertions);
+ if (!readBackToSSBOs.empty())
+ {
+ insertions.insert(insertions.end(), readBackToSSBOs.begin(), readBackToSSBOs.end());
+ }
+ insertStatementsInParentBlock(insertions);
+ queueReplacement(tempSymbol->deepCopy(), OriginalNode::IS_DROPPED);
+ }
+
+ return false;
+}
+
+bool RewriteExpressionsWithShaderStorageBlockTraverser::visitUnary(Visit visit, TIntermUnary *node)
+{
+ if (mFoundSSBO)
+ {
+ return false;
+ }
+
+ if (!IsInShaderStorageBlock(node->getOperand()))
+ {
+ return true;
+ }
+
+ // .length() is processed in OutputHLSL.
+ if (node->getOp() == EOpArrayLength)
+ {
+ return true;
+ }
+
+ mFoundSSBO = true;
+
+ // case 4: ssbo as the operand of ++/--
+ // original:
+ // ++ssbo * expr;
+ // new:
+ // var temp1 = ssbo;
+ // var temp2 = ++temp1;
+ // ssbo = temp1;
+ // temp2 * expr;
+ if (IsIncrementOrDecrementOperator(node->getOp()))
+ {
+ TIntermSequence insertions;
+ TIntermSymbol *temp1 =
+ insertInitStatementAndReturnTempSymbol(node->getOperand(), &insertions);
+ TIntermUnary *newUnary = new TIntermUnary(node->getOp(), temp1->deepCopy(), nullptr);
+ TIntermSymbol *temp2 = insertInitStatementAndReturnTempSymbol(newUnary, &insertions);
+ TIntermBinary *readBackToSSBO =
+ new TIntermBinary(EOpAssign, node->getOperand()->deepCopy(), temp1->deepCopy());
+ insertions.push_back(readBackToSSBO);
+ insertStatementsInParentBlock(insertions);
+ queueReplacement(temp2->deepCopy(), OriginalNode::IS_DROPPED);
+ }
+ // case 5: ssbo as the operand of readonly unary operator
+ // original:
+ // ~ssbo * expr;
+ // new:
+ // var temp = ssbo;
+ // ~temp * expr;
+ else
+ {
+ TIntermSequence insertions;
+ TIntermSymbol *temp =
+ insertInitStatementAndReturnTempSymbol(node->getOperand(), &insertions);
+ insertStatementsInParentBlock(insertions);
+ node->replaceChildNode(node->getOperand(), temp->deepCopy());
+ }
+ return false;
+}
+
+void RewriteExpressionsWithShaderStorageBlockTraverser::nextIteration()
+{
+ mFoundSSBO = false;
+}
+
+} // anonymous namespace
+
+bool RewriteExpressionsWithShaderStorageBlock(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable)
+{
+ RewriteExpressionsWithShaderStorageBlockTraverser traverser(symbolTable);
+ do
+ {
+ traverser.nextIteration();
+ root->traverse(&traverser);
+ if (traverser.foundSSBO())
+ {
+ if (!traverser.updateTree(compiler, root))
+ {
+ return false;
+ }
+ }
+ } while (traverser.foundSSBO());
+
+ return true;
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteExpressionsWithShaderStorageBlock.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteExpressionsWithShaderStorageBlock.h
new file mode 100644
index 0000000000..bf824c4a23
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteExpressionsWithShaderStorageBlock.h
@@ -0,0 +1,37 @@
+//
+// Copyright 2018 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.
+//
+// RewriteExpressionsWithShaderStorageBlock rewrites the expressions that contain shader storage
+// block calls into several simple ones that can be easily handled in the HLSL translator. After the
+// AST pass, all ssbo related blocks will be like below:
+// ssbo_access_chain = ssbo_access_chain;
+// ssbo_access_chain = expr_no_ssbo;
+// lvalue_no_ssbo = ssbo_access_chain;
+//
+// Below situations are needed to be rewritten (Details can be found in .cpp file).
+// SSBO as the operand of compound assignment operators.
+// SSBO as the operand of ++/--.
+// SSBO as the operand of repeated assignment.
+// SSBO as the operand of readonly unary/binary/ternary operators.
+// SSBO as the argument of aggregate type.
+// SSBO as the condition of if/switch/while/do-while/for
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_D3D_REWRITE_EXPRESSIONS_WITH_SHADER_STORAGE_BLOCK_H_
+#define COMPILER_TRANSLATOR_TREEOPS_D3D_REWRITE_EXPRESSIONS_WITH_SHADER_STORAGE_BLOCK_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermNode;
+class TSymbolTable;
+
+[[nodiscard]] bool RewriteExpressionsWithShaderStorageBlock(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_D3D_REWRITE_EXPRESSIONS_WITH_SHADER_STORAGE_BLOCK_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteUnaryMinusOperatorInt.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteUnaryMinusOperatorInt.cpp
new file mode 100644
index 0000000000..5d8cdb657d
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteUnaryMinusOperatorInt.cpp
@@ -0,0 +1,117 @@
+//
+// 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.
+//
+// Implementation of evaluating unary integer variable bug workaround.
+// See header for more info.
+
+#include "compiler/translator/tree_ops/d3d/RewriteUnaryMinusOperatorInt.h"
+
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class Traverser : public TIntermTraverser
+{
+ public:
+ [[nodiscard]] static bool Apply(TCompiler *compiler, TIntermNode *root);
+
+ private:
+ Traverser();
+ bool visitUnary(Visit visit, TIntermUnary *node) override;
+ void nextIteration();
+
+ bool mFound = false;
+};
+
+// static
+bool Traverser::Apply(TCompiler *compiler, TIntermNode *root)
+{
+ Traverser traverser;
+ do
+ {
+ traverser.nextIteration();
+ root->traverse(&traverser);
+ if (traverser.mFound)
+ {
+ if (!traverser.updateTree(compiler, root))
+ {
+ return false;
+ }
+ }
+ } while (traverser.mFound);
+
+ return true;
+}
+
+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, nullptr);
+ bitwiseNot->setLine(opr->getLine());
+
+ // Constant 1 (or 1u)
+ TConstantUnion *one = new TConstantUnion();
+ if (opr->getType().getBasicType() == EbtInt)
+ {
+ one->setIConst(1);
+ }
+ else
+ {
+ one->setUConst(1u);
+ }
+ TType *oneType = new TType(opr->getType());
+ oneType->setQualifier(EvqConst);
+
+ TIntermConstantUnion *oneNode = new TIntermConstantUnion(one, *oneType);
+ oneNode->setLine(opr->getLine());
+
+ // ~(int) + 1
+ TIntermBinary *add = new TIntermBinary(EOpAdd, bitwiseNot, oneNode);
+ add->setLine(opr->getLine());
+
+ queueReplacement(add, OriginalNode::IS_DROPPED);
+
+ mFound = true;
+ return false;
+}
+
+} // anonymous namespace
+
+bool RewriteUnaryMinusOperatorInt(TCompiler *compiler, TIntermNode *root)
+{
+ return Traverser::Apply(compiler, root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteUnaryMinusOperatorInt.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteUnaryMinusOperatorInt.h
new file mode 100644
index 0000000000..cc5ac86456
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/RewriteUnaryMinusOperatorInt.h
@@ -0,0 +1,23 @@
+// 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.
+//
+// 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_TREEOPS_D3D_REWRITEUNARYMINUSOPERATORINT_H_
+#define COMPILER_TRANSLATOR_TREEOPS_D3D_REWRITEUNARYMINUSOPERATORINT_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermNode;
+
+[[nodiscard]] bool RewriteUnaryMinusOperatorInt(TCompiler *compiler, TIntermNode *root);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_D3D_REWRITEUNARYMINUSOPERATORINT_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateArrayConstructorStatements.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateArrayConstructorStatements.cpp
new file mode 100644
index 0000000000..170b29acd7
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateArrayConstructorStatements.cpp
@@ -0,0 +1,83 @@
+//
+// Copyright 2018 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.
+//
+// SeparateArrayConstructorStatements splits statements that are array constructors and drops all of
+// their constant arguments. For example, a statement like:
+// int[2](0, i++);
+// Will be changed to:
+// i++;
+
+#include "compiler/translator/tree_ops/d3d/SeparateArrayConstructorStatements.h"
+
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+void SplitConstructorArgs(const TIntermSequence &originalArgs, TIntermSequence *argsOut)
+{
+ for (TIntermNode *arg : originalArgs)
+ {
+ TIntermTyped *argTyped = arg->getAsTyped();
+ if (argTyped->hasSideEffects())
+ {
+ TIntermAggregate *argAggregate = argTyped->getAsAggregate();
+ if (argTyped->isArray() && argAggregate && argAggregate->isConstructor())
+ {
+ SplitConstructorArgs(*argAggregate->getSequence(), argsOut);
+ }
+ else
+ {
+ argsOut->push_back(argTyped);
+ }
+ }
+ }
+}
+
+class SeparateArrayConstructorStatementsTraverser : public TIntermTraverser
+{
+ public:
+ SeparateArrayConstructorStatementsTraverser();
+
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override;
+};
+
+SeparateArrayConstructorStatementsTraverser::SeparateArrayConstructorStatementsTraverser()
+ : TIntermTraverser(true, false, false)
+{}
+
+bool SeparateArrayConstructorStatementsTraverser::visitAggregate(Visit visit,
+ TIntermAggregate *node)
+{
+ TIntermBlock *parentAsBlock = getParentNode()->getAsBlock();
+ if (!parentAsBlock)
+ {
+ return false;
+ }
+ if (!node->isArray() || !node->isConstructor())
+ {
+ return false;
+ }
+
+ TIntermSequence constructorArgs;
+ SplitConstructorArgs(*node->getSequence(), &constructorArgs);
+ mMultiReplacements.emplace_back(parentAsBlock, node, std::move(constructorArgs));
+
+ return false;
+}
+
+} // namespace
+
+bool SeparateArrayConstructorStatements(TCompiler *compiler, TIntermBlock *root)
+{
+ SeparateArrayConstructorStatementsTraverser traverser;
+ root->traverse(&traverser);
+ return traverser.updateTree(compiler, root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateArrayConstructorStatements.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateArrayConstructorStatements.h
new file mode 100644
index 0000000000..225a4651da
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateArrayConstructorStatements.h
@@ -0,0 +1,25 @@
+//
+// Copyright 2018 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.
+//
+// SeparateArrayConstructorStatements splits statements that are array constructors and drops all of
+// their constant arguments. For example, a statement like:
+// int[2](0, i++);
+// Will be changed to:
+// i++;
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_D3D_SEPARATEARRAYCONSTRUCTORSTATEMENTS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_D3D_SEPARATEARRAYCONSTRUCTORSTATEMENTS_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermBlock;
+
+[[nodiscard]] bool SeparateArrayConstructorStatements(TCompiler *compiler, TIntermBlock *root);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_D3D_SEPARATEARRAYCONSTRUCTORSTATEMENTS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateArrayInitialization.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateArrayInitialization.cpp
new file mode 100644
index 0000000000..de5c393cf6
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateArrayInitialization.cpp
@@ -0,0 +1,89 @@
+//
+// Copyright 2002 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.
+//
+// The SeparateArrayInitialization function splits each array initialization into a declaration and
+// an assignment.
+// Example:
+// type[n] a = initializer;
+// will effectively become
+// type[n] a;
+// a = initializer;
+//
+// Note that if the array is declared as const, the initialization may still be split, making the
+// AST technically invalid. Because of that this transformation should only be used when subsequent
+// stages don't care about const qualifiers. However, the initialization will not be split if the
+// initializer can be written as a HLSL literal.
+
+#include "compiler/translator/tree_ops/d3d/SeparateArrayInitialization.h"
+
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/OutputHLSL.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class SeparateArrayInitTraverser : private TIntermTraverser
+{
+ public:
+ [[nodiscard]] static bool apply(TCompiler *compiler, TIntermNode *root);
+
+ private:
+ SeparateArrayInitTraverser();
+ bool visitDeclaration(Visit, TIntermDeclaration *node) override;
+};
+
+bool SeparateArrayInitTraverser::apply(TCompiler *compiler, TIntermNode *root)
+{
+ SeparateArrayInitTraverser separateInit;
+ root->traverse(&separateInit);
+ return separateInit.updateTree(compiler, root);
+}
+
+SeparateArrayInitTraverser::SeparateArrayInitTraverser() : TIntermTraverser(true, false, false) {}
+
+bool SeparateArrayInitTraverser::visitDeclaration(Visit, TIntermDeclaration *node)
+{
+ TIntermSequence *sequence = node->getSequence();
+ TIntermBinary *initNode = sequence->back()->getAsBinaryNode();
+ if (initNode != nullptr && initNode->getOp() == EOpInitialize)
+ {
+ TIntermTyped *initializer = initNode->getRight();
+ if (initializer->isArray() && !initializer->hasConstantValue())
+ {
+ // We rely on that array declarations have been isolated to single declarations.
+ ASSERT(sequence->size() == 1);
+ TIntermTyped *symbol = initNode->getLeft();
+ TIntermBlock *parentBlock = getParentNode()->getAsBlock();
+ ASSERT(parentBlock != nullptr);
+
+ TIntermSequence replacements;
+
+ TIntermDeclaration *replacementDeclaration = new TIntermDeclaration();
+ replacementDeclaration->appendDeclarator(symbol);
+ replacementDeclaration->setLine(symbol->getLine());
+ replacements.push_back(replacementDeclaration);
+
+ TIntermBinary *replacementAssignment =
+ new TIntermBinary(EOpAssign, symbol, initializer);
+ replacementAssignment->setLine(symbol->getLine());
+ replacements.push_back(replacementAssignment);
+
+ mMultiReplacements.emplace_back(parentBlock, node, std::move(replacements));
+ }
+ }
+ return false;
+}
+
+} // namespace
+
+bool SeparateArrayInitialization(TCompiler *compiler, TIntermNode *root)
+{
+ return SeparateArrayInitTraverser::apply(compiler, root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateArrayInitialization.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateArrayInitialization.h
new file mode 100644
index 0000000000..e83554186a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateArrayInitialization.h
@@ -0,0 +1,32 @@
+//
+// Copyright 2002 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.
+//
+// The SeparateArrayInitialization function splits each array initialization into a declaration and
+// an assignment.
+// Example:
+// type[n] a = initializer;
+// will effectively become
+// type[n] a;
+// a = initializer;
+//
+// Note that if the array is declared as const, the initialization may still be split, making the
+// AST technically invalid. Because of that this transformation should only be used when subsequent
+// stages don't care about const qualifiers. However, the initialization will not be split if the
+// initializer can be written as a HLSL literal.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_D3D_SEPARATEARRAYINITIALIZATION_H_
+#define COMPILER_TRANSLATOR_TREEOPS_D3D_SEPARATEARRAYINITIALIZATION_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermNode;
+
+[[nodiscard]] bool SeparateArrayInitialization(TCompiler *compiler, TIntermNode *root);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_D3D_SEPARATEARRAYINITIALIZATION_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateExpressionsReturningArrays.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateExpressionsReturningArrays.cpp
new file mode 100644
index 0000000000..58d8a0a9be
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateExpressionsReturningArrays.cpp
@@ -0,0 +1,138 @@
+//
+// Copyright 2002 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.
+//
+// SeparateExpressionsReturningArrays splits array-returning expressions that are not array names
+// from more complex expressions, assigning them to a temporary variable a#.
+// Examples where a, b and c are all arrays:
+// (a = b) == (a = c) is split into a = b; type[n] a1 = a; a = c; type[n] a2 = a; a1 == a2;
+// type d = type[n](...)[i]; is split into type[n] a1 = type[n](...); type d = a1[i];
+
+#include "compiler/translator/tree_ops/d3d/SeparateExpressionsReturningArrays.h"
+
+#include "compiler/translator/tree_util/IntermNodePatternMatcher.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+// Traverser that separates one array expression into a statement at a time.
+class SeparateExpressionsTraverser : public TIntermTraverser
+{
+ public:
+ SeparateExpressionsTraverser(TSymbolTable *symbolTable);
+
+ bool visitBinary(Visit visit, TIntermBinary *node) override;
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override;
+
+ void nextIteration();
+ bool foundArrayExpression() const { return mFoundArrayExpression; }
+
+ 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 mFoundArrayExpression;
+
+ IntermNodePatternMatcher mPatternToSeparateMatcher;
+};
+
+SeparateExpressionsTraverser::SeparateExpressionsTraverser(TSymbolTable *symbolTable)
+ : TIntermTraverser(true, false, false, symbolTable),
+ mFoundArrayExpression(false),
+ mPatternToSeparateMatcher(IntermNodePatternMatcher::kExpressionReturningArray)
+{}
+
+// Performs a shallow copy of an assignment node.
+// These shallow copies are useful when a node gets inserted into an aggregate node
+// and also needs to be replaced in its original location by a different node.
+TIntermBinary *CopyAssignmentNode(TIntermBinary *node)
+{
+ return new TIntermBinary(node->getOp(), node->getLeft(), node->getRight());
+}
+
+bool SeparateExpressionsTraverser::visitBinary(Visit visit, TIntermBinary *node)
+{
+ if (mFoundArrayExpression)
+ return false;
+
+ // Return if the expression is not an array or if we're not inside a complex expression.
+ if (!mPatternToSeparateMatcher.match(node, getParentNode()))
+ 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.
+ TIntermDeclaration *arrayVariableDeclaration;
+ TVariable *arrayVariable =
+ DeclareTempVariable(mSymbolTable, node->getLeft(), EvqTemporary, &arrayVariableDeclaration);
+ insertions.push_back(arrayVariableDeclaration);
+ insertStatementsInParentBlock(insertions);
+
+ queueReplacement(CreateTempSymbolNode(arrayVariable), OriginalNode::IS_DROPPED);
+
+ return false;
+}
+
+bool SeparateExpressionsTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
+{
+ if (mFoundArrayExpression)
+ return false; // No need to traverse further
+
+ if (!mPatternToSeparateMatcher.match(node, getParentNode()))
+ return true;
+
+ ASSERT(node->isConstructor() || node->getOp() == EOpCallFunctionInAST);
+
+ mFoundArrayExpression = true;
+
+ TIntermDeclaration *arrayVariableDeclaration;
+ TVariable *arrayVariable = DeclareTempVariable(mSymbolTable, node->shallowCopy(), EvqTemporary,
+ &arrayVariableDeclaration);
+ insertStatementInParentBlock(arrayVariableDeclaration);
+
+ queueReplacement(CreateTempSymbolNode(arrayVariable), OriginalNode::IS_DROPPED);
+
+ return false;
+}
+
+void SeparateExpressionsTraverser::nextIteration()
+{
+ mFoundArrayExpression = false;
+}
+
+} // namespace
+
+bool SeparateExpressionsReturningArrays(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable)
+{
+ SeparateExpressionsTraverser traverser(symbolTable);
+ // Separate one expression at a time, and reset the traverser between iterations.
+ do
+ {
+ traverser.nextIteration();
+ root->traverse(&traverser);
+ if (traverser.foundArrayExpression())
+ {
+ if (!traverser.updateTree(compiler, root))
+ {
+ return false;
+ }
+ }
+ } while (traverser.foundArrayExpression());
+
+ return true;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateExpressionsReturningArrays.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateExpressionsReturningArrays.h
new file mode 100644
index 0000000000..6a9350d89a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/SeparateExpressionsReturningArrays.h
@@ -0,0 +1,28 @@
+//
+// Copyright 2002 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.
+//
+// SeparateExpressionsReturningArrays splits array-returning expressions that are not array names
+// from more complex expressions, assigning them to a temporary variable a#.
+// Examples where a, b and c are all arrays:
+// (a = b) == (a = c) is split into a = b; type[n] a1 = a; a = c; type[n] a2 = a; a1 == a2;
+// type d = type[n](...)[i]; is split into type[n] a1 = type[n](...); type d = a1[i];
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_D3D_SEPARATEEXPRESSIONSRETURNINGARRAYS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_D3D_SEPARATEEXPRESSIONSRETURNINGARRAYS_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermNode;
+class TSymbolTable;
+
+[[nodiscard]] bool SeparateExpressionsReturningArrays(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_D3D_SEPARATEEXPRESSIONSRETURNINGARRAYS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/UnfoldShortCircuitToIf.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/UnfoldShortCircuitToIf.cpp
new file mode 100644
index 0000000000..5b104c4889
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/UnfoldShortCircuitToIf.cpp
@@ -0,0 +1,200 @@
+//
+// Copyright 2002 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.
+//
+// UnfoldShortCircuitToIf is an AST traverser to convert short-circuiting operators to if-else
+// statements.
+// The results are assigned to s# temporaries, which are used by the main translator instead of
+// the original expression.
+//
+
+#include "compiler/translator/tree_ops/d3d/UnfoldShortCircuitToIf.h"
+
+#include "compiler/translator/StaticType.h"
+#include "compiler/translator/tree_util/IntermNodePatternMatcher.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+// Traverser that unfolds one short-circuiting operation at a time.
+class UnfoldShortCircuitTraverser : public TIntermTraverser
+{
+ public:
+ UnfoldShortCircuitTraverser(TSymbolTable *symbolTable);
+
+ bool visitBinary(Visit visit, TIntermBinary *node) override;
+ bool visitTernary(Visit visit, TIntermTernary *node) override;
+
+ void nextIteration();
+ bool foundShortCircuit() const { return mFoundShortCircuit; }
+
+ protected:
+ // 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;
+
+ IntermNodePatternMatcher mPatternToUnfoldMatcher;
+};
+
+UnfoldShortCircuitTraverser::UnfoldShortCircuitTraverser(TSymbolTable *symbolTable)
+ : TIntermTraverser(true, false, true, symbolTable),
+ mFoundShortCircuit(false),
+ mPatternToUnfoldMatcher(IntermNodePatternMatcher::kUnfoldedShortCircuitExpression)
+{}
+
+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)
+ ASSERT(node->getRight()->hasSideEffects());
+
+ mFoundShortCircuit = true;
+
+ switch (node->getOp())
+ {
+ case EOpLogicalOr:
+ {
+ // "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;
+ const TType *boolType = StaticType::Get<EbtBool, EbpUndefined, EvqTemporary, 1, 1>();
+ TVariable *resultVariable = CreateTempVariable(mSymbolTable, boolType);
+
+ ASSERT(node->getLeft()->getType() == *boolType);
+ insertions.push_back(CreateTempInitDeclarationNode(resultVariable, node->getLeft()));
+
+ TIntermBlock *assignRightBlock = new TIntermBlock();
+ ASSERT(node->getRight()->getType() == *boolType);
+ assignRightBlock->getSequence()->push_back(
+ CreateTempAssignmentNode(resultVariable, node->getRight()));
+
+ TIntermUnary *notTempSymbol =
+ new TIntermUnary(EOpLogicalNot, CreateTempSymbolNode(resultVariable), nullptr);
+ TIntermIfElse *ifNode = new TIntermIfElse(notTempSymbol, assignRightBlock, nullptr);
+ insertions.push_back(ifNode);
+
+ insertStatementsInParentBlock(insertions);
+
+ queueReplacement(CreateTempSymbolNode(resultVariable), OriginalNode::IS_DROPPED);
+ return false;
+ }
+ case EOpLogicalAnd:
+ {
+ // "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;
+ const TType *boolType = StaticType::Get<EbtBool, EbpUndefined, EvqTemporary, 1, 1>();
+ TVariable *resultVariable = CreateTempVariable(mSymbolTable, boolType);
+
+ ASSERT(node->getLeft()->getType() == *boolType);
+ insertions.push_back(CreateTempInitDeclarationNode(resultVariable, node->getLeft()));
+
+ TIntermBlock *assignRightBlock = new TIntermBlock();
+ ASSERT(node->getRight()->getType() == *boolType);
+ assignRightBlock->getSequence()->push_back(
+ CreateTempAssignmentNode(resultVariable, node->getRight()));
+
+ TIntermIfElse *ifNode =
+ new TIntermIfElse(CreateTempSymbolNode(resultVariable), assignRightBlock, nullptr);
+ insertions.push_back(ifNode);
+
+ insertStatementsInParentBlock(insertions);
+
+ queueReplacement(CreateTempSymbolNode(resultVariable), OriginalNode::IS_DROPPED);
+ return false;
+ }
+ default:
+ UNREACHABLE();
+ return true;
+ }
+}
+
+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;"
+ TIntermSequence insertions;
+ TIntermDeclaration *tempDeclaration = nullptr;
+ TVariable *resultVariable = DeclareTempVariable(mSymbolTable, new TType(node->getType()),
+ EvqTemporary, &tempDeclaration);
+ insertions.push_back(tempDeclaration);
+
+ TIntermBlock *trueBlock = new TIntermBlock();
+ TIntermBinary *trueAssignment =
+ CreateTempAssignmentNode(resultVariable, node->getTrueExpression());
+ trueBlock->getSequence()->push_back(trueAssignment);
+
+ TIntermBlock *falseBlock = new TIntermBlock();
+ TIntermBinary *falseAssignment =
+ CreateTempAssignmentNode(resultVariable, node->getFalseExpression());
+ falseBlock->getSequence()->push_back(falseAssignment);
+
+ TIntermIfElse *ifNode =
+ new TIntermIfElse(node->getCondition()->getAsTyped(), trueBlock, falseBlock);
+ insertions.push_back(ifNode);
+
+ insertStatementsInParentBlock(insertions);
+
+ TIntermSymbol *ternaryResult = CreateTempSymbolNode(resultVariable);
+ queueReplacement(ternaryResult, OriginalNode::IS_DROPPED);
+
+ return false;
+}
+
+void UnfoldShortCircuitTraverser::nextIteration()
+{
+ mFoundShortCircuit = false;
+}
+
+} // namespace
+
+bool UnfoldShortCircuitToIf(TCompiler *compiler, TIntermNode *root, TSymbolTable *symbolTable)
+{
+ UnfoldShortCircuitTraverser traverser(symbolTable);
+ // Unfold one operator at a time, and reset the traverser between iterations.
+ do
+ {
+ traverser.nextIteration();
+ root->traverse(&traverser);
+ if (traverser.foundShortCircuit())
+ {
+ if (!traverser.updateTree(compiler, root))
+ {
+ return false;
+ }
+ }
+ } while (traverser.foundShortCircuit());
+
+ return true;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/UnfoldShortCircuitToIf.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/UnfoldShortCircuitToIf.h
new file mode 100644
index 0000000000..97587e4d38
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/UnfoldShortCircuitToIf.h
@@ -0,0 +1,30 @@
+//
+// Copyright 2002 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.
+//
+// UnfoldShortCircuitToIf is an AST traverser to convert short-circuiting operators to if-else
+// statements.
+// The results are assigned to s# temporaries, which are used by the main translator instead of
+// the original expression.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_D3D_UNFOLDSHORTCIRCUIT_H_
+#define COMPILER_TRANSLATOR_TREEOPS_D3D_UNFOLDSHORTCIRCUIT_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermNode;
+class TSymbolTable;
+
+[[nodiscard]] bool UnfoldShortCircuitToIf(TCompiler *compiler,
+ TIntermNode *root,
+ TSymbolTable *symbolTable);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_D3D_UNFOLDSHORTCIRCUIT_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/WrapSwitchStatementsInBlocks.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/WrapSwitchStatementsInBlocks.cpp
new file mode 100644
index 0000000000..58a941da0e
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/WrapSwitchStatementsInBlocks.cpp
@@ -0,0 +1,126 @@
+//
+// Copyright 2017 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.
+//
+// WrapSwitchStatementsInBlocks.cpp: Wrap switch statements in blocks and declare all switch-scoped
+// variables there to make the AST compatible with HLSL output.
+//
+// switch (init)
+// {
+// case 0:
+// float f;
+// default:
+// f = 1.0;
+// }
+//
+// becomes
+//
+// {
+// float f;
+// switch (init)
+// {
+// case 0:
+// default:
+// f = 1.0;
+// }
+// }
+
+#include "compiler/translator/tree_ops/d3d/WrapSwitchStatementsInBlocks.h"
+
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class WrapSwitchStatementsInBlocksTraverser : public TIntermTraverser
+{
+ public:
+ WrapSwitchStatementsInBlocksTraverser() : TIntermTraverser(true, false, false) {}
+
+ bool visitSwitch(Visit visit, TIntermSwitch *node) override;
+};
+
+bool WrapSwitchStatementsInBlocksTraverser::visitSwitch(Visit, TIntermSwitch *node)
+{
+ std::vector<TIntermDeclaration *> declarations;
+ TIntermSequence *statementList = node->getStatementList()->getSequence();
+ for (TIntermNode *statement : *statementList)
+ {
+ TIntermDeclaration *asDeclaration = statement->getAsDeclarationNode();
+ if (asDeclaration)
+ {
+ declarations.push_back(asDeclaration);
+ }
+ }
+ if (declarations.empty())
+ {
+ // We don't need to wrap the switch if it doesn't contain declarations as its direct
+ // descendants.
+ return true;
+ }
+
+ TIntermBlock *wrapperBlock = new TIntermBlock();
+ for (TIntermDeclaration *declaration : declarations)
+ {
+ // SeparateDeclarations should have already been run.
+ ASSERT(declaration->getSequence()->size() == 1);
+
+ TIntermDeclaration *declarationInBlock = new TIntermDeclaration();
+ TIntermSymbol *declaratorAsSymbol = declaration->getSequence()->at(0)->getAsSymbolNode();
+ if (declaratorAsSymbol)
+ {
+ // This is a simple declaration like: "float f;"
+ // Remove the declaration from inside the switch and put it in the wrapping block.
+ TIntermSequence emptyReplacement;
+ mMultiReplacements.emplace_back(node->getStatementList(), declaration,
+ std::move(emptyReplacement));
+
+ declarationInBlock->appendDeclarator(declaratorAsSymbol->deepCopy());
+ // The declaration can't be the last statement inside the switch since unused variables
+ // should already have been pruned.
+ ASSERT(declaration != statementList->back());
+ }
+ else
+ {
+ // This is an init declaration like: "float f = 0.0;"
+ // Change the init declaration inside the switch into an assignment and put a plain
+ // declaration in the wrapping block.
+ TIntermBinary *declaratorAsBinary =
+ declaration->getSequence()->at(0)->getAsBinaryNode();
+ ASSERT(declaratorAsBinary);
+
+ TIntermBinary *initAssignment = new TIntermBinary(
+ EOpAssign, declaratorAsBinary->getLeft(), declaratorAsBinary->getRight());
+
+ queueReplacementWithParent(node->getStatementList(), declaration, initAssignment,
+ OriginalNode::IS_DROPPED);
+
+ declarationInBlock->appendDeclarator(declaratorAsBinary->getLeft()->deepCopy());
+ }
+ wrapperBlock->appendStatement(declarationInBlock);
+ }
+
+ wrapperBlock->appendStatement(node);
+ queueReplacement(wrapperBlock, OriginalNode::BECOMES_CHILD);
+
+ // Should be fine to process multiple switch statements, even nesting ones in the same
+ // traversal.
+ return true;
+}
+
+} // anonymous namespace
+
+// Wrap switch statements in the AST into blocks when needed.
+bool WrapSwitchStatementsInBlocks(TCompiler *compiler, TIntermBlock *root)
+{
+ WrapSwitchStatementsInBlocksTraverser traverser;
+ root->traverse(&traverser);
+ return traverser.updateTree(compiler, root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/WrapSwitchStatementsInBlocks.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/WrapSwitchStatementsInBlocks.h
new file mode 100644
index 0000000000..0c765c306a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/d3d/WrapSwitchStatementsInBlocks.h
@@ -0,0 +1,25 @@
+//
+// Copyright 2017 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.
+//
+// WrapSwitchStatementsInBlocks.h: Wrap switch statements in blocks and declare all switch-scoped
+// variables there to make the AST compatible with HLSL output.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_D3D_WRAPSWITCHSTATEMENTSINBLOCKS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_D3D_WRAPSWITCHSTATEMENTSINBLOCKS_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermBlock;
+
+// Wrap switch statements in the AST into blocks when needed. Returns true if the AST was changed.
+[[nodiscard]] bool WrapSwitchStatementsInBlocks(TCompiler *compiler, TIntermBlock *root);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_D3D_WRAPSWITCHSTATEMENTSINBLOCKS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/ClampFragDepth.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/ClampFragDepth.cpp
new file mode 100644
index 0000000000..309cb14752
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/ClampFragDepth.cpp
@@ -0,0 +1,54 @@
+//
+// Copyright 2017 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.
+//
+// ClampFragDepth.cpp: Limit the value that is written to gl_FragDepth to the range [0.0, 1.0].
+// The clamping is run at the very end of shader execution, and is only performed if the shader
+// statically accesses gl_FragDepth.
+//
+
+#include "compiler/translator/tree_ops/gl/ClampFragDepth.h"
+
+#include "compiler/translator/ImmutableString.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/BuiltIn.h"
+#include "compiler/translator/tree_util/FindSymbolNode.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/RunAtTheEndOfShader.h"
+
+namespace sh
+{
+
+bool ClampFragDepth(TCompiler *compiler, TIntermBlock *root, TSymbolTable *symbolTable)
+{
+ // Only clamp gl_FragDepth if it's used in the shader.
+ if (!FindSymbolNode(root, ImmutableString("gl_FragDepth")))
+ {
+ return true;
+ }
+
+ TIntermSymbol *fragDepthNode = new TIntermSymbol(BuiltInVariable::gl_FragDepth());
+
+ TIntermTyped *minFragDepthNode = CreateZeroNode(TType(EbtFloat, EbpHigh, EvqConst));
+
+ TConstantUnion *maxFragDepthConstant = new TConstantUnion();
+ maxFragDepthConstant->setFConst(1.0);
+ TIntermConstantUnion *maxFragDepthNode =
+ new TIntermConstantUnion(maxFragDepthConstant, TType(EbtFloat, EbpHigh, EvqConst));
+
+ // clamp(gl_FragDepth, 0.0, 1.0)
+ TIntermSequence clampArguments;
+ clampArguments.push_back(fragDepthNode->deepCopy());
+ clampArguments.push_back(minFragDepthNode);
+ clampArguments.push_back(maxFragDepthNode);
+ TIntermTyped *clampedFragDepth =
+ CreateBuiltInFunctionCallNode("clamp", &clampArguments, *symbolTable, 100);
+
+ // gl_FragDepth = clamp(gl_FragDepth, 0.0, 1.0)
+ TIntermBinary *assignFragDepth = new TIntermBinary(EOpAssign, fragDepthNode, clampedFragDepth);
+
+ return RunAtTheEndOfShader(compiler, root, assignFragDepth, symbolTable);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/ClampFragDepth.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/ClampFragDepth.h
new file mode 100644
index 0000000000..70326c9a34
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/ClampFragDepth.h
@@ -0,0 +1,39 @@
+//
+// Copyright 2017 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.
+//
+// ClampFragDepth.h: Limit the value that is written to gl_FragDepth to the range [0.0, 1.0].
+// The clamping is run at the very end of shader execution, and is only performed if the shader
+// statically accesses gl_FragDepth.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_GL_CLAMPFRAGDEPTH_H_
+#define COMPILER_TRANSLATOR_TREEOPS_GL_CLAMPFRAGDEPTH_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+#ifdef ANGLE_ENABLE_GLSL
+[[nodiscard]] bool ClampFragDepth(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable);
+#else
+[[nodiscard]] ANGLE_INLINE bool ClampFragDepth(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable)
+{
+ UNREACHABLE();
+ return false;
+}
+#endif
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_GL_CLAMPFRAGDEPTH_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/RegenerateStructNames.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/RegenerateStructNames.cpp
new file mode 100644
index 0000000000..e15ef32166
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/RegenerateStructNames.cpp
@@ -0,0 +1,119 @@
+//
+// Copyright 2002 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/tree_ops/gl/RegenerateStructNames.h"
+
+#include "common/debug.h"
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/ImmutableStringBuilder.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+#include <set>
+
+namespace sh
+{
+
+namespace
+{
+constexpr const ImmutableString kPrefix("_webgl_struct_");
+} // anonymous namespace
+
+class RegenerateStructNamesTraverser : public TIntermTraverser
+{
+ public:
+ RegenerateStructNamesTraverser(TSymbolTable *symbolTable)
+ : TIntermTraverser(true, false, false, symbolTable), mScopeDepth(0)
+ {}
+
+ protected:
+ void visitSymbol(TIntermSymbol *) override;
+ bool visitBlock(Visit, TIntermBlock *block) override;
+
+ private:
+ // Indicating the depth of the current scope.
+ // The global scope is 1.
+ int mScopeDepth;
+
+ // If a struct is declared globally, push its ID in this set.
+ std::set<int> mDeclaredGlobalStructs;
+};
+
+void RegenerateStructNamesTraverser::visitSymbol(TIntermSymbol *symbol)
+{
+ ASSERT(symbol);
+ const TType &type = symbol->getType();
+ const TStructure *userType = type.getStruct();
+ if (!userType)
+ return;
+
+ if (userType->symbolType() == SymbolType::BuiltIn ||
+ userType->symbolType() == SymbolType::Empty)
+ {
+ // Built-in struct or nameless struct, do not touch it.
+ return;
+ }
+
+ int uniqueId = userType->uniqueId().get();
+
+ ASSERT(mScopeDepth > 0);
+ if (mScopeDepth == 1)
+ {
+ // If a struct is defined at global scope, we don't map its name.
+ // This is because at global level, the struct might be used to
+ // declare a uniform, so the same name needs to stay the same for
+ // vertex/fragment shaders. However, our mapping uses internal ID,
+ // which will be different for the same struct in vertex/fragment
+ // shaders.
+ // This is OK because names for any structs defined in other scopes
+ // will begin with "_webgl", which is reserved. So there will be
+ // no conflicts among unmapped struct names from global scope and
+ // mapped struct names from other scopes.
+ // However, we need to keep track of these global structs, so if a
+ // variable is used in a local scope, we don't try to modify the
+ // struct name through that variable.
+ mDeclaredGlobalStructs.insert(uniqueId);
+ return;
+ }
+ if (mDeclaredGlobalStructs.count(uniqueId) > 0)
+ return;
+ // Map {name} to _webgl_struct_{uniqueId}_{name}.
+ if (userType->name().beginsWith(kPrefix))
+ {
+ // The name has already been regenerated.
+ return;
+ }
+ ImmutableStringBuilder tmp(kPrefix.length() + sizeof(uniqueId) * 2u + 1u +
+ userType->name().length());
+ tmp << kPrefix;
+ tmp.appendHex(uniqueId);
+ tmp << '_' << userType->name();
+
+ // TODO(oetuaho): Add another mechanism to change symbol names so that the const_cast is not
+ // needed.
+ const_cast<TStructure *>(userType)->setName(tmp);
+}
+
+bool RegenerateStructNamesTraverser::visitBlock(Visit, TIntermBlock *block)
+{
+ ++mScopeDepth;
+ TIntermSequence &sequence = *(block->getSequence());
+ for (TIntermNode *node : sequence)
+ {
+ node->traverse(this);
+ }
+ --mScopeDepth;
+ return false;
+}
+
+bool RegenerateStructNames(TCompiler *compiler, TIntermBlock *root, TSymbolTable *symbolTable)
+{
+ RegenerateStructNamesTraverser traverser(symbolTable);
+ root->traverse(&traverser);
+ return compiler->validateAST(root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/RegenerateStructNames.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/RegenerateStructNames.h
new file mode 100644
index 0000000000..04cfe6a476
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/RegenerateStructNames.h
@@ -0,0 +1,34 @@
+//
+// Copyright 2002 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_TREEOPS_GL_REGENERATESTRUCTNAMES_H_
+#define COMPILER_TRANSLATOR_TREEOPS_GL_REGENERATESTRUCTNAMES_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+#if defined(ANGLE_ENABLE_GLSL)
+[[nodiscard]] bool RegenerateStructNames(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable);
+#else
+[[nodiscard]] ANGLE_INLINE bool RegenerateStructNames(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable)
+{
+ UNREACHABLE();
+ return false;
+}
+#endif
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_GL_REGENERATESTRUCTNAMES_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/RewriteRepeatedAssignToSwizzled.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/RewriteRepeatedAssignToSwizzled.cpp
new file mode 100644
index 0000000000..83a0f029b8
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/RewriteRepeatedAssignToSwizzled.cpp
@@ -0,0 +1,97 @@
+//
+// Copyright 2018 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.
+//
+// RewriteRepeatedAssignToSwizzled.cpp: Rewrite expressions that assign an assignment to a swizzled
+// vector, like:
+// v.x = z = expression;
+// to:
+// z = expression;
+// v.x = z;
+//
+// Note that this doesn't handle some corner cases: expressions nested inside other expressions,
+// inside loop headers, or inside if conditions.
+
+#include "compiler/translator/tree_ops/gl/RewriteRepeatedAssignToSwizzled.h"
+
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class RewriteAssignToSwizzledTraverser : public TIntermTraverser
+{
+ public:
+ [[nodiscard]] static bool rewrite(TCompiler *compiler, TIntermBlock *root);
+
+ private:
+ RewriteAssignToSwizzledTraverser();
+
+ bool visitBinary(Visit, TIntermBinary *node) override;
+
+ void nextIteration();
+
+ bool didRewrite() { return mDidRewrite; }
+
+ bool mDidRewrite;
+};
+
+// static
+bool RewriteAssignToSwizzledTraverser::rewrite(TCompiler *compiler, TIntermBlock *root)
+{
+ RewriteAssignToSwizzledTraverser rewrite;
+ do
+ {
+ rewrite.nextIteration();
+ root->traverse(&rewrite);
+ if (!rewrite.updateTree(compiler, root))
+ {
+ return false;
+ }
+ } while (rewrite.didRewrite());
+
+ return true;
+}
+
+RewriteAssignToSwizzledTraverser::RewriteAssignToSwizzledTraverser()
+ : TIntermTraverser(true, false, false), mDidRewrite(false)
+{}
+
+void RewriteAssignToSwizzledTraverser::nextIteration()
+{
+ mDidRewrite = false;
+}
+
+bool RewriteAssignToSwizzledTraverser::visitBinary(Visit, TIntermBinary *node)
+{
+ TIntermBinary *rightBinary = node->getRight()->getAsBinaryNode();
+ TIntermBlock *parentBlock = getParentNode()->getAsBlock();
+ if (parentBlock && node->isAssignment() && node->getLeft()->getAsSwizzleNode() && rightBinary &&
+ rightBinary->isAssignment())
+ {
+ TIntermSequence replacements;
+ replacements.push_back(rightBinary);
+ TIntermTyped *rightAssignmentTargetCopy = rightBinary->getLeft()->deepCopy();
+ TIntermBinary *lastAssign =
+ new TIntermBinary(EOpAssign, node->getLeft(), rightAssignmentTargetCopy);
+ replacements.push_back(lastAssign);
+ mMultiReplacements.emplace_back(parentBlock, node, std::move(replacements));
+ mDidRewrite = true;
+ return false;
+ }
+ return true;
+}
+
+} // anonymous namespace
+
+bool RewriteRepeatedAssignToSwizzled(TCompiler *compiler, TIntermBlock *root)
+{
+ return RewriteAssignToSwizzledTraverser::rewrite(compiler, root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/RewriteRepeatedAssignToSwizzled.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/RewriteRepeatedAssignToSwizzled.h
new file mode 100644
index 0000000000..1ab9b7ebb8
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/RewriteRepeatedAssignToSwizzled.h
@@ -0,0 +1,40 @@
+//
+// Copyright 2018 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.
+//
+// RewriteRepeatedAssignToSwizzled.h: Rewrite expressions that assign an assignment to a swizzled
+// vector, like:
+// v.x = z = expression;
+// to:
+// z = expression;
+// v.x = z;
+//
+// Note that this doesn't handle some corner cases: expressions nested inside other expressions,
+// inside loop headers, or inside if conditions.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_GL_REWRITEREPEATEDASSIGNTOSWIZZLED_H_
+#define COMPILER_TRANSLATOR_TREEOPS_GL_REWRITEREPEATEDASSIGNTOSWIZZLED_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermBlock;
+
+#ifdef ANGLE_ENABLE_GLSL
+[[nodiscard]] bool RewriteRepeatedAssignToSwizzled(TCompiler *compiler, TIntermBlock *root);
+#else
+[[nodiscard]] ANGLE_INLINE bool RewriteRepeatedAssignToSwizzled(TCompiler *compiler,
+ TIntermBlock *root)
+{
+ UNREACHABLE();
+ return false;
+}
+#endif
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_GL_REWRITEREPEATEDASSIGNTOSWIZZLED_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/UseInterfaceBlockFields.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/UseInterfaceBlockFields.cpp
new file mode 100644
index 0000000000..e94ca2fd17
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/UseInterfaceBlockFields.cpp
@@ -0,0 +1,108 @@
+//
+// 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.
+//
+
+// UseInterfaceBlockFields.cpp: insert statements to reference all members in InterfaceBlock list at
+// the beginning of main. This is to work around a Mac driver that treats unused standard/shared
+// uniform blocks as inactive.
+
+#include "compiler/translator/tree_ops/gl/UseInterfaceBlockFields.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/FindMain.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+void AddNodeUseStatements(TIntermTyped *node, TIntermSequence *sequence)
+{
+ if (node->isArray())
+ {
+ for (unsigned int i = 0u; i < node->getOutermostArraySize(); ++i)
+ {
+ TIntermBinary *element =
+ new TIntermBinary(EOpIndexDirect, node->deepCopy(), CreateIndexNode(i));
+ AddNodeUseStatements(element, sequence);
+ }
+ }
+ else
+ {
+ sequence->insert(sequence->begin(), node);
+ }
+}
+
+void AddFieldUseStatements(const ShaderVariable &var,
+ TIntermSequence *sequence,
+ const TSymbolTable &symbolTable)
+{
+ ASSERT(var.name.find_last_of('[') == std::string::npos);
+ TIntermSymbol *symbol = ReferenceGlobalVariable(ImmutableString(var.name), symbolTable);
+ AddNodeUseStatements(symbol, sequence);
+}
+
+void InsertUseCode(const InterfaceBlock &block, TIntermTyped *blockNode, TIntermSequence *sequence)
+{
+ for (unsigned int i = 0; i < block.fields.size(); ++i)
+ {
+ TIntermBinary *element = new TIntermBinary(EOpIndexDirectInterfaceBlock,
+ blockNode->deepCopy(), CreateIndexNode(i));
+ sequence->insert(sequence->begin(), element);
+ }
+}
+
+void InsertUseCode(TIntermSequence *sequence,
+ const InterfaceBlockList &blocks,
+ const TSymbolTable &symbolTable)
+{
+ for (const auto &block : blocks)
+ {
+ if (block.instanceName.empty())
+ {
+ for (const auto &var : block.fields)
+ {
+ AddFieldUseStatements(var, sequence, symbolTable);
+ }
+ }
+ else if (block.arraySize > 0u)
+ {
+ TIntermSymbol *arraySymbol =
+ ReferenceGlobalVariable(ImmutableString(block.instanceName), symbolTable);
+ for (unsigned int i = 0u; i < block.arraySize; ++i)
+ {
+ TIntermBinary *elementSymbol =
+ new TIntermBinary(EOpIndexDirect, arraySymbol->deepCopy(), CreateIndexNode(i));
+ InsertUseCode(block, elementSymbol, sequence);
+ }
+ }
+ else
+ {
+ TIntermSymbol *blockSymbol =
+ ReferenceGlobalVariable(ImmutableString(block.instanceName), symbolTable);
+ InsertUseCode(block, blockSymbol, sequence);
+ }
+ }
+}
+
+} // namespace
+
+bool UseInterfaceBlockFields(TCompiler *compiler,
+ TIntermBlock *root,
+ const InterfaceBlockList &blocks,
+ const TSymbolTable &symbolTable)
+{
+ TIntermBlock *mainBody = FindMainBody(root);
+ InsertUseCode(mainBody->getSequence(), blocks, symbolTable);
+
+ return compiler->validateAST(root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/UseInterfaceBlockFields.h b/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/UseInterfaceBlockFields.h
new file mode 100644
index 0000000000..a4f5f3e5e6
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/UseInterfaceBlockFields.h
@@ -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.
+//
+
+// UseInterfaceBlockFields.h: insert statements to reference all members in InterfaceBlock list at
+// the beginning of main. This is to work around a Mac driver that treats unused standard/shared
+// uniform blocks as inactive.
+
+#ifndef COMPILER_TRANSLATOR_TREEOPS_GL_USEINTERFACEBLOCKFIELDS_H_
+#define COMPILER_TRANSLATOR_TREEOPS_GL_USEINTERFACEBLOCKFIELDS_H_
+
+#include <GLSLANG/ShaderLang.h>
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+using InterfaceBlockList = std::vector<sh::InterfaceBlock>;
+
+#ifdef ANGLE_ENABLE_GLSL
+[[nodiscard]] bool UseInterfaceBlockFields(TCompiler *compiler,
+ TIntermBlock *root,
+ const InterfaceBlockList &blocks,
+ const TSymbolTable &symbolTable);
+#else
+[[nodiscard]] ANGLE_INLINE bool UseInterfaceBlockFields(TCompiler *compiler,
+ TIntermBlock *root,
+ const InterfaceBlockList &blocks,
+ const TSymbolTable &symbolTable)
+{
+ UNREACHABLE();
+ return false;
+}
+#endif
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEOPS_GL_USEINTERFACEBLOCKFIELDS_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/AsNode.h b/gfx/angle/checkout/src/compiler/translator/tree_util/AsNode.h
new file mode 100644
index 0000000000..1c6de182d9
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/AsNode.h
@@ -0,0 +1,212 @@
+//
+// Copyright 2020 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_TREEUTIL_INTERMASNODE_H_
+#define COMPILER_TRANSLATOR_TREEUTIL_INTERMASNODE_H_
+
+#include "common/angleutils.h"
+#include "compiler/translator/IntermNode.h"
+
+#include <utility>
+
+namespace sh
+{
+
+namespace priv
+{
+
+template <typename T>
+struct AsNode
+{};
+
+template <>
+struct AsNode<TIntermNode>
+{
+ static ANGLE_INLINE TIntermNode *exec(TIntermNode *node) { return node; }
+};
+
+template <>
+struct AsNode<TIntermTyped>
+{
+ static ANGLE_INLINE TIntermTyped *exec(TIntermNode *node)
+ {
+ return node ? node->getAsTyped() : nullptr;
+ }
+};
+
+template <>
+struct AsNode<TIntermSymbol>
+{
+ static ANGLE_INLINE TIntermSymbol *exec(TIntermNode *node)
+ {
+ return node ? node->getAsSymbolNode() : nullptr;
+ }
+};
+
+template <>
+struct AsNode<TIntermConstantUnion>
+{
+ static ANGLE_INLINE TIntermConstantUnion *exec(TIntermNode *node)
+ {
+ return node ? node->getAsConstantUnion() : nullptr;
+ }
+};
+
+template <>
+struct AsNode<TIntermFunctionPrototype>
+{
+ static ANGLE_INLINE TIntermFunctionPrototype *exec(TIntermNode *node)
+ {
+ return node ? node->getAsFunctionPrototypeNode() : nullptr;
+ }
+};
+
+template <>
+struct AsNode<TIntermPreprocessorDirective>
+{
+ static ANGLE_INLINE TIntermPreprocessorDirective *exec(TIntermNode *node)
+ {
+ return node ? node->getAsPreprocessorDirective() : nullptr;
+ }
+};
+
+template <>
+struct AsNode<TIntermSwizzle>
+{
+ static ANGLE_INLINE TIntermSwizzle *exec(TIntermNode *node)
+ {
+ return node ? node->getAsSwizzleNode() : nullptr;
+ }
+};
+
+template <>
+struct AsNode<TIntermBinary>
+{
+ static ANGLE_INLINE TIntermBinary *exec(TIntermNode *node)
+ {
+ return node ? node->getAsBinaryNode() : nullptr;
+ }
+};
+
+template <>
+struct AsNode<TIntermUnary>
+{
+ static ANGLE_INLINE TIntermUnary *exec(TIntermNode *node)
+ {
+ return node ? node->getAsUnaryNode() : nullptr;
+ }
+};
+
+template <>
+struct AsNode<TIntermTernary>
+{
+ static ANGLE_INLINE TIntermTernary *exec(TIntermNode *node)
+ {
+ return node ? node->getAsTernaryNode() : nullptr;
+ }
+};
+
+template <>
+struct AsNode<TIntermIfElse>
+{
+ static ANGLE_INLINE TIntermIfElse *exec(TIntermNode *node)
+ {
+ return node ? node->getAsIfElseNode() : nullptr;
+ }
+};
+
+template <>
+struct AsNode<TIntermSwitch>
+{
+ static ANGLE_INLINE TIntermSwitch *exec(TIntermNode *node)
+ {
+ return node ? node->getAsSwitchNode() : nullptr;
+ }
+};
+
+template <>
+struct AsNode<TIntermCase>
+{
+ static ANGLE_INLINE TIntermCase *exec(TIntermNode *node)
+ {
+ return node ? node->getAsCaseNode() : nullptr;
+ }
+};
+
+template <>
+struct AsNode<TIntermFunctionDefinition>
+{
+ static ANGLE_INLINE TIntermFunctionDefinition *exec(TIntermNode *node)
+ {
+ return node ? node->getAsFunctionDefinition() : nullptr;
+ }
+};
+
+template <>
+struct AsNode<TIntermAggregate>
+{
+ static ANGLE_INLINE TIntermAggregate *exec(TIntermNode *node)
+ {
+ return node ? node->getAsAggregate() : nullptr;
+ }
+};
+
+template <>
+struct AsNode<TIntermBlock>
+{
+ static ANGLE_INLINE TIntermBlock *exec(TIntermNode *node)
+ {
+ return node ? node->getAsBlock() : nullptr;
+ }
+};
+
+template <>
+struct AsNode<TIntermGlobalQualifierDeclaration>
+{
+ static ANGLE_INLINE TIntermGlobalQualifierDeclaration *exec(TIntermNode *node)
+ {
+ return node ? node->getAsGlobalQualifierDeclarationNode() : nullptr;
+ }
+};
+
+template <>
+struct AsNode<TIntermDeclaration>
+{
+ static ANGLE_INLINE TIntermDeclaration *exec(TIntermNode *node)
+ {
+ return node ? node->getAsDeclarationNode() : nullptr;
+ }
+};
+
+template <>
+struct AsNode<TIntermLoop>
+{
+ static ANGLE_INLINE TIntermLoop *exec(TIntermNode *node)
+ {
+ return node ? node->getAsLoopNode() : nullptr;
+ }
+};
+
+template <>
+struct AsNode<TIntermBranch>
+{
+ static ANGLE_INLINE TIntermBranch *exec(TIntermNode *node)
+ {
+ return node ? node->getAsBranchNode() : nullptr;
+ }
+};
+
+} // namespace priv
+
+template <typename T>
+ANGLE_INLINE T *asNode(TIntermNode *node)
+{
+ return priv::AsNode<T>::exec(node);
+}
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEUTIL_INTERMASNODE_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/BuiltIn.h b/gfx/angle/checkout/src/compiler/translator/tree_util/BuiltIn.h
new file mode 100644
index 0000000000..22c33f9fc0
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/BuiltIn.h
@@ -0,0 +1,18 @@
+// Copyright 2019 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.
+//
+// BuiltIn.h:
+// Chooses BuiltIn_complete_autogen.h or BuiltIn_ESSL_autogen.h
+// depending on whether platform is android
+
+#ifndef COMPILER_TRANSLATOR_TREEUTIL_BUILTIN_H_
+#define COMPILER_TRANSLATOR_TREEUTIL_BUILTIN_H_
+
+#if defined(ANDROID)
+# include "BuiltIn_ESSL_autogen.h"
+#else
+# include "BuiltIn_complete_autogen.h"
+#endif
+
+#endif // COMPILER_TRANSLATOR_TREEUTIL_BUILTIN_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/BuiltIn_ESSL_autogen.h b/gfx/angle/checkout/src/compiler/translator/tree_util/BuiltIn_ESSL_autogen.h
new file mode 100644
index 0000000000..5380d82c68
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/BuiltIn_ESSL_autogen.h
@@ -0,0 +1,4177 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_builtin_symbols.py using data from builtin_variables.json and
+// builtin_function_declarations.txt.
+//
+// Copyright 2020 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.
+//
+// BuiltIn_ESSL_autogen.h:
+// Compile-time initialized built-ins.
+
+#ifndef COMPILER_TRANSLATOR_TREEUTIL_BUILTIN_AUTOGEN_H_
+#define COMPILER_TRANSLATOR_TREEUTIL_BUILTIN_AUTOGEN_H_
+
+#include "compiler/translator/SymbolUniqueId.h"
+
+namespace sh
+{
+
+class TVariable;
+
+class BuiltInId
+{
+ public:
+ static constexpr const TSymbolUniqueId radians_Float1 = TSymbolUniqueId(3086);
+ static constexpr const TSymbolUniqueId pt00B = TSymbolUniqueId(3087);
+ static constexpr const TSymbolUniqueId radians_Float2 = TSymbolUniqueId(3088);
+ static constexpr const TSymbolUniqueId pt10B = TSymbolUniqueId(3089);
+ static constexpr const TSymbolUniqueId radians_Float3 = TSymbolUniqueId(3090);
+ static constexpr const TSymbolUniqueId pt20B = TSymbolUniqueId(3091);
+ static constexpr const TSymbolUniqueId radians_Float4 = TSymbolUniqueId(3092);
+ static constexpr const TSymbolUniqueId pt30B = TSymbolUniqueId(3093);
+ static constexpr const TSymbolUniqueId degrees_Float1 = TSymbolUniqueId(3094);
+ static constexpr const TSymbolUniqueId degrees_Float2 = TSymbolUniqueId(3095);
+ static constexpr const TSymbolUniqueId degrees_Float3 = TSymbolUniqueId(3096);
+ static constexpr const TSymbolUniqueId degrees_Float4 = TSymbolUniqueId(3097);
+ static constexpr const TSymbolUniqueId sin_Float1 = TSymbolUniqueId(3098);
+ static constexpr const TSymbolUniqueId sin_Float2 = TSymbolUniqueId(3099);
+ static constexpr const TSymbolUniqueId sin_Float3 = TSymbolUniqueId(3100);
+ static constexpr const TSymbolUniqueId sin_Float4 = TSymbolUniqueId(3101);
+ static constexpr const TSymbolUniqueId cos_Float1 = TSymbolUniqueId(3102);
+ static constexpr const TSymbolUniqueId cos_Float2 = TSymbolUniqueId(3103);
+ static constexpr const TSymbolUniqueId cos_Float3 = TSymbolUniqueId(3104);
+ static constexpr const TSymbolUniqueId cos_Float4 = TSymbolUniqueId(3105);
+ static constexpr const TSymbolUniqueId tan_Float1 = TSymbolUniqueId(3106);
+ static constexpr const TSymbolUniqueId tan_Float2 = TSymbolUniqueId(3107);
+ static constexpr const TSymbolUniqueId tan_Float3 = TSymbolUniqueId(3108);
+ static constexpr const TSymbolUniqueId tan_Float4 = TSymbolUniqueId(3109);
+ static constexpr const TSymbolUniqueId asin_Float1 = TSymbolUniqueId(3110);
+ static constexpr const TSymbolUniqueId asin_Float2 = TSymbolUniqueId(3111);
+ static constexpr const TSymbolUniqueId asin_Float3 = TSymbolUniqueId(3112);
+ static constexpr const TSymbolUniqueId asin_Float4 = TSymbolUniqueId(3113);
+ static constexpr const TSymbolUniqueId acos_Float1 = TSymbolUniqueId(3114);
+ static constexpr const TSymbolUniqueId acos_Float2 = TSymbolUniqueId(3115);
+ static constexpr const TSymbolUniqueId acos_Float3 = TSymbolUniqueId(3116);
+ static constexpr const TSymbolUniqueId acos_Float4 = TSymbolUniqueId(3117);
+ static constexpr const TSymbolUniqueId atan_Float1_Float1 = TSymbolUniqueId(3118);
+ static constexpr const TSymbolUniqueId atan_Float2_Float2 = TSymbolUniqueId(3119);
+ static constexpr const TSymbolUniqueId atan_Float3_Float3 = TSymbolUniqueId(3120);
+ static constexpr const TSymbolUniqueId atan_Float4_Float4 = TSymbolUniqueId(3121);
+ static constexpr const TSymbolUniqueId atan_Float1 = TSymbolUniqueId(3122);
+ static constexpr const TSymbolUniqueId atan_Float2 = TSymbolUniqueId(3123);
+ static constexpr const TSymbolUniqueId atan_Float3 = TSymbolUniqueId(3124);
+ static constexpr const TSymbolUniqueId atan_Float4 = TSymbolUniqueId(3125);
+ static constexpr const TSymbolUniqueId sinh_Float1 = TSymbolUniqueId(3126);
+ static constexpr const TSymbolUniqueId sinh_Float2 = TSymbolUniqueId(3127);
+ static constexpr const TSymbolUniqueId sinh_Float3 = TSymbolUniqueId(3128);
+ static constexpr const TSymbolUniqueId sinh_Float4 = TSymbolUniqueId(3129);
+ static constexpr const TSymbolUniqueId cosh_Float1 = TSymbolUniqueId(3130);
+ static constexpr const TSymbolUniqueId cosh_Float2 = TSymbolUniqueId(3131);
+ static constexpr const TSymbolUniqueId cosh_Float3 = TSymbolUniqueId(3132);
+ static constexpr const TSymbolUniqueId cosh_Float4 = TSymbolUniqueId(3133);
+ static constexpr const TSymbolUniqueId tanh_Float1 = TSymbolUniqueId(3134);
+ static constexpr const TSymbolUniqueId tanh_Float2 = TSymbolUniqueId(3135);
+ static constexpr const TSymbolUniqueId tanh_Float3 = TSymbolUniqueId(3136);
+ static constexpr const TSymbolUniqueId tanh_Float4 = TSymbolUniqueId(3137);
+ static constexpr const TSymbolUniqueId asinh_Float1 = TSymbolUniqueId(3138);
+ static constexpr const TSymbolUniqueId asinh_Float2 = TSymbolUniqueId(3139);
+ static constexpr const TSymbolUniqueId asinh_Float3 = TSymbolUniqueId(3140);
+ static constexpr const TSymbolUniqueId asinh_Float4 = TSymbolUniqueId(3141);
+ static constexpr const TSymbolUniqueId acosh_Float1 = TSymbolUniqueId(3142);
+ static constexpr const TSymbolUniqueId acosh_Float2 = TSymbolUniqueId(3143);
+ static constexpr const TSymbolUniqueId acosh_Float3 = TSymbolUniqueId(3144);
+ static constexpr const TSymbolUniqueId acosh_Float4 = TSymbolUniqueId(3145);
+ static constexpr const TSymbolUniqueId atanh_Float1 = TSymbolUniqueId(3146);
+ static constexpr const TSymbolUniqueId atanh_Float2 = TSymbolUniqueId(3147);
+ static constexpr const TSymbolUniqueId atanh_Float3 = TSymbolUniqueId(3148);
+ static constexpr const TSymbolUniqueId atanh_Float4 = TSymbolUniqueId(3149);
+ static constexpr const TSymbolUniqueId pow_Float1_Float1 = TSymbolUniqueId(3150);
+ static constexpr const TSymbolUniqueId pow_Float2_Float2 = TSymbolUniqueId(3151);
+ static constexpr const TSymbolUniqueId pow_Float3_Float3 = TSymbolUniqueId(3152);
+ static constexpr const TSymbolUniqueId pow_Float4_Float4 = TSymbolUniqueId(3153);
+ static constexpr const TSymbolUniqueId exp_Float1 = TSymbolUniqueId(3154);
+ static constexpr const TSymbolUniqueId exp_Float2 = TSymbolUniqueId(3155);
+ static constexpr const TSymbolUniqueId exp_Float3 = TSymbolUniqueId(3156);
+ static constexpr const TSymbolUniqueId exp_Float4 = TSymbolUniqueId(3157);
+ static constexpr const TSymbolUniqueId log_Float1 = TSymbolUniqueId(3158);
+ static constexpr const TSymbolUniqueId log_Float2 = TSymbolUniqueId(3159);
+ static constexpr const TSymbolUniqueId log_Float3 = TSymbolUniqueId(3160);
+ static constexpr const TSymbolUniqueId log_Float4 = TSymbolUniqueId(3161);
+ static constexpr const TSymbolUniqueId exp2_Float1 = TSymbolUniqueId(3162);
+ static constexpr const TSymbolUniqueId exp2_Float2 = TSymbolUniqueId(3163);
+ static constexpr const TSymbolUniqueId exp2_Float3 = TSymbolUniqueId(3164);
+ static constexpr const TSymbolUniqueId exp2_Float4 = TSymbolUniqueId(3165);
+ static constexpr const TSymbolUniqueId log2_Float1 = TSymbolUniqueId(3166);
+ static constexpr const TSymbolUniqueId log2_Float2 = TSymbolUniqueId(3167);
+ static constexpr const TSymbolUniqueId log2_Float3 = TSymbolUniqueId(3168);
+ static constexpr const TSymbolUniqueId log2_Float4 = TSymbolUniqueId(3169);
+ static constexpr const TSymbolUniqueId sqrt_Float1 = TSymbolUniqueId(3170);
+ static constexpr const TSymbolUniqueId sqrt_Float2 = TSymbolUniqueId(3171);
+ static constexpr const TSymbolUniqueId sqrt_Float3 = TSymbolUniqueId(3172);
+ static constexpr const TSymbolUniqueId sqrt_Float4 = TSymbolUniqueId(3173);
+ static constexpr const TSymbolUniqueId inversesqrt_Float1 = TSymbolUniqueId(3174);
+ static constexpr const TSymbolUniqueId inversesqrt_Float2 = TSymbolUniqueId(3175);
+ static constexpr const TSymbolUniqueId inversesqrt_Float3 = TSymbolUniqueId(3176);
+ static constexpr const TSymbolUniqueId inversesqrt_Float4 = TSymbolUniqueId(3177);
+ static constexpr const TSymbolUniqueId abs_Float1 = TSymbolUniqueId(3178);
+ static constexpr const TSymbolUniqueId abs_Float2 = TSymbolUniqueId(3179);
+ static constexpr const TSymbolUniqueId abs_Float3 = TSymbolUniqueId(3180);
+ static constexpr const TSymbolUniqueId abs_Float4 = TSymbolUniqueId(3181);
+ static constexpr const TSymbolUniqueId abs_Int1 = TSymbolUniqueId(3182);
+ static constexpr const TSymbolUniqueId pt00D = TSymbolUniqueId(3183);
+ static constexpr const TSymbolUniqueId abs_Int2 = TSymbolUniqueId(3184);
+ static constexpr const TSymbolUniqueId pt10D = TSymbolUniqueId(3185);
+ static constexpr const TSymbolUniqueId abs_Int3 = TSymbolUniqueId(3186);
+ static constexpr const TSymbolUniqueId pt20D = TSymbolUniqueId(3187);
+ static constexpr const TSymbolUniqueId abs_Int4 = TSymbolUniqueId(3188);
+ static constexpr const TSymbolUniqueId pt30D = TSymbolUniqueId(3189);
+ static constexpr const TSymbolUniqueId sign_Float1 = TSymbolUniqueId(3190);
+ static constexpr const TSymbolUniqueId sign_Float2 = TSymbolUniqueId(3191);
+ static constexpr const TSymbolUniqueId sign_Float3 = TSymbolUniqueId(3192);
+ static constexpr const TSymbolUniqueId sign_Float4 = TSymbolUniqueId(3193);
+ static constexpr const TSymbolUniqueId sign_Int1 = TSymbolUniqueId(3194);
+ static constexpr const TSymbolUniqueId sign_Int2 = TSymbolUniqueId(3195);
+ static constexpr const TSymbolUniqueId sign_Int3 = TSymbolUniqueId(3196);
+ static constexpr const TSymbolUniqueId sign_Int4 = TSymbolUniqueId(3197);
+ static constexpr const TSymbolUniqueId floor_Float1 = TSymbolUniqueId(3198);
+ static constexpr const TSymbolUniqueId floor_Float2 = TSymbolUniqueId(3199);
+ static constexpr const TSymbolUniqueId floor_Float3 = TSymbolUniqueId(3200);
+ static constexpr const TSymbolUniqueId floor_Float4 = TSymbolUniqueId(3201);
+ static constexpr const TSymbolUniqueId trunc_Float1 = TSymbolUniqueId(3202);
+ static constexpr const TSymbolUniqueId trunc_Float2 = TSymbolUniqueId(3203);
+ static constexpr const TSymbolUniqueId trunc_Float3 = TSymbolUniqueId(3204);
+ static constexpr const TSymbolUniqueId trunc_Float4 = TSymbolUniqueId(3205);
+ static constexpr const TSymbolUniqueId round_Float1 = TSymbolUniqueId(3206);
+ static constexpr const TSymbolUniqueId round_Float2 = TSymbolUniqueId(3207);
+ static constexpr const TSymbolUniqueId round_Float3 = TSymbolUniqueId(3208);
+ static constexpr const TSymbolUniqueId round_Float4 = TSymbolUniqueId(3209);
+ static constexpr const TSymbolUniqueId roundEven_Float1 = TSymbolUniqueId(3210);
+ static constexpr const TSymbolUniqueId roundEven_Float2 = TSymbolUniqueId(3211);
+ static constexpr const TSymbolUniqueId roundEven_Float3 = TSymbolUniqueId(3212);
+ static constexpr const TSymbolUniqueId roundEven_Float4 = TSymbolUniqueId(3213);
+ static constexpr const TSymbolUniqueId ceil_Float1 = TSymbolUniqueId(3214);
+ static constexpr const TSymbolUniqueId ceil_Float2 = TSymbolUniqueId(3215);
+ static constexpr const TSymbolUniqueId ceil_Float3 = TSymbolUniqueId(3216);
+ static constexpr const TSymbolUniqueId ceil_Float4 = TSymbolUniqueId(3217);
+ static constexpr const TSymbolUniqueId fract_Float1 = TSymbolUniqueId(3218);
+ static constexpr const TSymbolUniqueId fract_Float2 = TSymbolUniqueId(3219);
+ static constexpr const TSymbolUniqueId fract_Float3 = TSymbolUniqueId(3220);
+ static constexpr const TSymbolUniqueId fract_Float4 = TSymbolUniqueId(3221);
+ static constexpr const TSymbolUniqueId mod_Float1_Float1 = TSymbolUniqueId(3222);
+ static constexpr const TSymbolUniqueId mod_Float2_Float1 = TSymbolUniqueId(3223);
+ static constexpr const TSymbolUniqueId mod_Float3_Float1 = TSymbolUniqueId(3224);
+ static constexpr const TSymbolUniqueId mod_Float4_Float1 = TSymbolUniqueId(3225);
+ static constexpr const TSymbolUniqueId mod_Float2_Float2 = TSymbolUniqueId(3226);
+ static constexpr const TSymbolUniqueId mod_Float3_Float3 = TSymbolUniqueId(3227);
+ static constexpr const TSymbolUniqueId mod_Float4_Float4 = TSymbolUniqueId(3228);
+ static constexpr const TSymbolUniqueId min_Float1_Float1 = TSymbolUniqueId(3229);
+ static constexpr const TSymbolUniqueId min_Float2_Float1 = TSymbolUniqueId(3230);
+ static constexpr const TSymbolUniqueId min_Float3_Float1 = TSymbolUniqueId(3231);
+ static constexpr const TSymbolUniqueId min_Float4_Float1 = TSymbolUniqueId(3232);
+ static constexpr const TSymbolUniqueId min_Float2_Float2 = TSymbolUniqueId(3233);
+ static constexpr const TSymbolUniqueId min_Float3_Float3 = TSymbolUniqueId(3234);
+ static constexpr const TSymbolUniqueId min_Float4_Float4 = TSymbolUniqueId(3235);
+ static constexpr const TSymbolUniqueId min_Int1_Int1 = TSymbolUniqueId(3236);
+ static constexpr const TSymbolUniqueId min_Int2_Int2 = TSymbolUniqueId(3237);
+ static constexpr const TSymbolUniqueId min_Int3_Int3 = TSymbolUniqueId(3238);
+ static constexpr const TSymbolUniqueId min_Int4_Int4 = TSymbolUniqueId(3239);
+ static constexpr const TSymbolUniqueId min_Int2_Int1 = TSymbolUniqueId(3240);
+ static constexpr const TSymbolUniqueId min_Int3_Int1 = TSymbolUniqueId(3241);
+ static constexpr const TSymbolUniqueId min_Int4_Int1 = TSymbolUniqueId(3242);
+ static constexpr const TSymbolUniqueId min_UInt1_UInt1 = TSymbolUniqueId(3243);
+ static constexpr const TSymbolUniqueId pt00E = TSymbolUniqueId(3244);
+ static constexpr const TSymbolUniqueId min_UInt2_UInt2 = TSymbolUniqueId(3245);
+ static constexpr const TSymbolUniqueId pt10E = TSymbolUniqueId(3246);
+ static constexpr const TSymbolUniqueId min_UInt3_UInt3 = TSymbolUniqueId(3247);
+ static constexpr const TSymbolUniqueId pt20E = TSymbolUniqueId(3248);
+ static constexpr const TSymbolUniqueId min_UInt4_UInt4 = TSymbolUniqueId(3249);
+ static constexpr const TSymbolUniqueId pt30E = TSymbolUniqueId(3250);
+ static constexpr const TSymbolUniqueId min_UInt2_UInt1 = TSymbolUniqueId(3251);
+ static constexpr const TSymbolUniqueId min_UInt3_UInt1 = TSymbolUniqueId(3252);
+ static constexpr const TSymbolUniqueId min_UInt4_UInt1 = TSymbolUniqueId(3253);
+ static constexpr const TSymbolUniqueId max_Float1_Float1 = TSymbolUniqueId(3254);
+ static constexpr const TSymbolUniqueId max_Float2_Float1 = TSymbolUniqueId(3255);
+ static constexpr const TSymbolUniqueId max_Float3_Float1 = TSymbolUniqueId(3256);
+ static constexpr const TSymbolUniqueId max_Float4_Float1 = TSymbolUniqueId(3257);
+ static constexpr const TSymbolUniqueId max_Float2_Float2 = TSymbolUniqueId(3258);
+ static constexpr const TSymbolUniqueId max_Float3_Float3 = TSymbolUniqueId(3259);
+ static constexpr const TSymbolUniqueId max_Float4_Float4 = TSymbolUniqueId(3260);
+ static constexpr const TSymbolUniqueId max_Int1_Int1 = TSymbolUniqueId(3261);
+ static constexpr const TSymbolUniqueId max_Int2_Int2 = TSymbolUniqueId(3262);
+ static constexpr const TSymbolUniqueId max_Int3_Int3 = TSymbolUniqueId(3263);
+ static constexpr const TSymbolUniqueId max_Int4_Int4 = TSymbolUniqueId(3264);
+ static constexpr const TSymbolUniqueId max_Int2_Int1 = TSymbolUniqueId(3265);
+ static constexpr const TSymbolUniqueId max_Int3_Int1 = TSymbolUniqueId(3266);
+ static constexpr const TSymbolUniqueId max_Int4_Int1 = TSymbolUniqueId(3267);
+ static constexpr const TSymbolUniqueId max_UInt1_UInt1 = TSymbolUniqueId(3268);
+ static constexpr const TSymbolUniqueId max_UInt2_UInt2 = TSymbolUniqueId(3269);
+ static constexpr const TSymbolUniqueId max_UInt3_UInt3 = TSymbolUniqueId(3270);
+ static constexpr const TSymbolUniqueId max_UInt4_UInt4 = TSymbolUniqueId(3271);
+ static constexpr const TSymbolUniqueId max_UInt2_UInt1 = TSymbolUniqueId(3272);
+ static constexpr const TSymbolUniqueId max_UInt3_UInt1 = TSymbolUniqueId(3273);
+ static constexpr const TSymbolUniqueId max_UInt4_UInt1 = TSymbolUniqueId(3274);
+ static constexpr const TSymbolUniqueId clamp_Float1_Float1_Float1 = TSymbolUniqueId(3275);
+ static constexpr const TSymbolUniqueId clamp_Float2_Float1_Float1 = TSymbolUniqueId(3276);
+ static constexpr const TSymbolUniqueId clamp_Float3_Float1_Float1 = TSymbolUniqueId(3277);
+ static constexpr const TSymbolUniqueId clamp_Float4_Float1_Float1 = TSymbolUniqueId(3278);
+ static constexpr const TSymbolUniqueId clamp_Float2_Float2_Float2 = TSymbolUniqueId(3279);
+ static constexpr const TSymbolUniqueId clamp_Float3_Float3_Float3 = TSymbolUniqueId(3280);
+ static constexpr const TSymbolUniqueId clamp_Float4_Float4_Float4 = TSymbolUniqueId(3281);
+ static constexpr const TSymbolUniqueId clamp_Int1_Int1_Int1 = TSymbolUniqueId(3282);
+ static constexpr const TSymbolUniqueId clamp_Int2_Int1_Int1 = TSymbolUniqueId(3283);
+ static constexpr const TSymbolUniqueId clamp_Int3_Int1_Int1 = TSymbolUniqueId(3284);
+ static constexpr const TSymbolUniqueId clamp_Int4_Int1_Int1 = TSymbolUniqueId(3285);
+ static constexpr const TSymbolUniqueId clamp_Int2_Int2_Int2 = TSymbolUniqueId(3286);
+ static constexpr const TSymbolUniqueId clamp_Int3_Int3_Int3 = TSymbolUniqueId(3287);
+ static constexpr const TSymbolUniqueId clamp_Int4_Int4_Int4 = TSymbolUniqueId(3288);
+ static constexpr const TSymbolUniqueId clamp_UInt1_UInt1_UInt1 = TSymbolUniqueId(3289);
+ static constexpr const TSymbolUniqueId clamp_UInt2_UInt1_UInt1 = TSymbolUniqueId(3290);
+ static constexpr const TSymbolUniqueId clamp_UInt3_UInt1_UInt1 = TSymbolUniqueId(3291);
+ static constexpr const TSymbolUniqueId clamp_UInt4_UInt1_UInt1 = TSymbolUniqueId(3292);
+ static constexpr const TSymbolUniqueId clamp_UInt2_UInt2_UInt2 = TSymbolUniqueId(3293);
+ static constexpr const TSymbolUniqueId clamp_UInt3_UInt3_UInt3 = TSymbolUniqueId(3294);
+ static constexpr const TSymbolUniqueId clamp_UInt4_UInt4_UInt4 = TSymbolUniqueId(3295);
+ static constexpr const TSymbolUniqueId mix_Float1_Float1_Float1 = TSymbolUniqueId(3296);
+ static constexpr const TSymbolUniqueId mix_Float2_Float2_Float1 = TSymbolUniqueId(3297);
+ static constexpr const TSymbolUniqueId mix_Float3_Float3_Float1 = TSymbolUniqueId(3298);
+ static constexpr const TSymbolUniqueId mix_Float4_Float4_Float1 = TSymbolUniqueId(3299);
+ static constexpr const TSymbolUniqueId mix_Float2_Float2_Float2 = TSymbolUniqueId(3300);
+ static constexpr const TSymbolUniqueId mix_Float3_Float3_Float3 = TSymbolUniqueId(3301);
+ static constexpr const TSymbolUniqueId mix_Float4_Float4_Float4 = TSymbolUniqueId(3302);
+ static constexpr const TSymbolUniqueId mix_Float1_Float1_Bool1 = TSymbolUniqueId(3303);
+ static constexpr const TSymbolUniqueId pt00F = TSymbolUniqueId(3304);
+ static constexpr const TSymbolUniqueId mix_Float2_Float2_Bool2 = TSymbolUniqueId(3305);
+ static constexpr const TSymbolUniqueId pt10F = TSymbolUniqueId(3306);
+ static constexpr const TSymbolUniqueId mix_Float3_Float3_Bool3 = TSymbolUniqueId(3307);
+ static constexpr const TSymbolUniqueId pt20F = TSymbolUniqueId(3308);
+ static constexpr const TSymbolUniqueId mix_Float4_Float4_Bool4 = TSymbolUniqueId(3309);
+ static constexpr const TSymbolUniqueId pt30F = TSymbolUniqueId(3310);
+ static constexpr const TSymbolUniqueId mix_Int1_Int1_Bool1 = TSymbolUniqueId(3311);
+ static constexpr const TSymbolUniqueId mix_Int2_Int2_Bool2 = TSymbolUniqueId(3312);
+ static constexpr const TSymbolUniqueId mix_Int3_Int3_Bool3 = TSymbolUniqueId(3313);
+ static constexpr const TSymbolUniqueId mix_Int4_Int4_Bool4 = TSymbolUniqueId(3314);
+ static constexpr const TSymbolUniqueId mix_UInt1_UInt1_Bool1 = TSymbolUniqueId(3315);
+ static constexpr const TSymbolUniqueId mix_UInt2_UInt2_Bool2 = TSymbolUniqueId(3316);
+ static constexpr const TSymbolUniqueId mix_UInt3_UInt3_Bool3 = TSymbolUniqueId(3317);
+ static constexpr const TSymbolUniqueId mix_UInt4_UInt4_Bool4 = TSymbolUniqueId(3318);
+ static constexpr const TSymbolUniqueId mix_Bool1_Bool1_Bool1 = TSymbolUniqueId(3319);
+ static constexpr const TSymbolUniqueId mix_Bool2_Bool2_Bool2 = TSymbolUniqueId(3320);
+ static constexpr const TSymbolUniqueId mix_Bool3_Bool3_Bool3 = TSymbolUniqueId(3321);
+ static constexpr const TSymbolUniqueId mix_Bool4_Bool4_Bool4 = TSymbolUniqueId(3322);
+ static constexpr const TSymbolUniqueId step_Float1_Float1 = TSymbolUniqueId(3323);
+ static constexpr const TSymbolUniqueId step_Float2_Float2 = TSymbolUniqueId(3324);
+ static constexpr const TSymbolUniqueId step_Float3_Float3 = TSymbolUniqueId(3325);
+ static constexpr const TSymbolUniqueId step_Float4_Float4 = TSymbolUniqueId(3326);
+ static constexpr const TSymbolUniqueId step_Float1_Float2 = TSymbolUniqueId(3327);
+ static constexpr const TSymbolUniqueId step_Float1_Float3 = TSymbolUniqueId(3328);
+ static constexpr const TSymbolUniqueId step_Float1_Float4 = TSymbolUniqueId(3329);
+ static constexpr const TSymbolUniqueId smoothstep_Float1_Float1_Float1 = TSymbolUniqueId(3330);
+ static constexpr const TSymbolUniqueId smoothstep_Float2_Float2_Float2 = TSymbolUniqueId(3331);
+ static constexpr const TSymbolUniqueId smoothstep_Float3_Float3_Float3 = TSymbolUniqueId(3332);
+ static constexpr const TSymbolUniqueId smoothstep_Float4_Float4_Float4 = TSymbolUniqueId(3333);
+ static constexpr const TSymbolUniqueId smoothstep_Float1_Float1_Float2 = TSymbolUniqueId(3334);
+ static constexpr const TSymbolUniqueId smoothstep_Float1_Float1_Float3 = TSymbolUniqueId(3335);
+ static constexpr const TSymbolUniqueId smoothstep_Float1_Float1_Float4 = TSymbolUniqueId(3336);
+ static constexpr const TSymbolUniqueId modf_Float1_Float1 = TSymbolUniqueId(3337);
+ static constexpr const TSymbolUniqueId pt_o_00B = TSymbolUniqueId(3338);
+ static constexpr const TSymbolUniqueId modf_Float2_Float2 = TSymbolUniqueId(3339);
+ static constexpr const TSymbolUniqueId pt_o_10B = TSymbolUniqueId(3340);
+ static constexpr const TSymbolUniqueId modf_Float3_Float3 = TSymbolUniqueId(3341);
+ static constexpr const TSymbolUniqueId pt_o_20B = TSymbolUniqueId(3342);
+ static constexpr const TSymbolUniqueId modf_Float4_Float4 = TSymbolUniqueId(3343);
+ static constexpr const TSymbolUniqueId pt_o_30B = TSymbolUniqueId(3344);
+ static constexpr const TSymbolUniqueId isnan_Float1 = TSymbolUniqueId(3345);
+ static constexpr const TSymbolUniqueId isnan_Float2 = TSymbolUniqueId(3346);
+ static constexpr const TSymbolUniqueId isnan_Float3 = TSymbolUniqueId(3347);
+ static constexpr const TSymbolUniqueId isnan_Float4 = TSymbolUniqueId(3348);
+ static constexpr const TSymbolUniqueId isinf_Float1 = TSymbolUniqueId(3349);
+ static constexpr const TSymbolUniqueId isinf_Float2 = TSymbolUniqueId(3350);
+ static constexpr const TSymbolUniqueId isinf_Float3 = TSymbolUniqueId(3351);
+ static constexpr const TSymbolUniqueId isinf_Float4 = TSymbolUniqueId(3352);
+ static constexpr const TSymbolUniqueId floatBitsToInt_Float1 = TSymbolUniqueId(3353);
+ static constexpr const TSymbolUniqueId floatBitsToInt_Float2 = TSymbolUniqueId(3354);
+ static constexpr const TSymbolUniqueId floatBitsToInt_Float3 = TSymbolUniqueId(3355);
+ static constexpr const TSymbolUniqueId floatBitsToInt_Float4 = TSymbolUniqueId(3356);
+ static constexpr const TSymbolUniqueId floatBitsToUint_Float1 = TSymbolUniqueId(3357);
+ static constexpr const TSymbolUniqueId floatBitsToUint_Float2 = TSymbolUniqueId(3358);
+ static constexpr const TSymbolUniqueId floatBitsToUint_Float3 = TSymbolUniqueId(3359);
+ static constexpr const TSymbolUniqueId floatBitsToUint_Float4 = TSymbolUniqueId(3360);
+ static constexpr const TSymbolUniqueId intBitsToFloat_Int1 = TSymbolUniqueId(3361);
+ static constexpr const TSymbolUniqueId intBitsToFloat_Int2 = TSymbolUniqueId(3362);
+ static constexpr const TSymbolUniqueId intBitsToFloat_Int3 = TSymbolUniqueId(3363);
+ static constexpr const TSymbolUniqueId intBitsToFloat_Int4 = TSymbolUniqueId(3364);
+ static constexpr const TSymbolUniqueId uintBitsToFloat_UInt1 = TSymbolUniqueId(3365);
+ static constexpr const TSymbolUniqueId uintBitsToFloat_UInt2 = TSymbolUniqueId(3366);
+ static constexpr const TSymbolUniqueId uintBitsToFloat_UInt3 = TSymbolUniqueId(3367);
+ static constexpr const TSymbolUniqueId uintBitsToFloat_UInt4 = TSymbolUniqueId(3368);
+ static constexpr const TSymbolUniqueId fma_Float1_Float1_Float1 = TSymbolUniqueId(3369);
+ static constexpr const TSymbolUniqueId fma_Float2_Float2_Float2 = TSymbolUniqueId(3370);
+ static constexpr const TSymbolUniqueId fma_Float3_Float3_Float3 = TSymbolUniqueId(3371);
+ static constexpr const TSymbolUniqueId fma_Float4_Float4_Float4 = TSymbolUniqueId(3372);
+ static constexpr const TSymbolUniqueId fmaExt_Float1_Float1_Float1 = TSymbolUniqueId(3373);
+ static constexpr const TSymbolUniqueId fmaExt_Float2_Float2_Float2 = TSymbolUniqueId(3374);
+ static constexpr const TSymbolUniqueId fmaExt_Float3_Float3_Float3 = TSymbolUniqueId(3375);
+ static constexpr const TSymbolUniqueId fmaExt_Float4_Float4_Float4 = TSymbolUniqueId(3376);
+ static constexpr const TSymbolUniqueId frexp_Float1_Int1 = TSymbolUniqueId(3377);
+ static constexpr const TSymbolUniqueId pt_o_00D = TSymbolUniqueId(3378);
+ static constexpr const TSymbolUniqueId frexp_Float2_Int2 = TSymbolUniqueId(3379);
+ static constexpr const TSymbolUniqueId pt_o_10D = TSymbolUniqueId(3380);
+ static constexpr const TSymbolUniqueId frexp_Float3_Int3 = TSymbolUniqueId(3381);
+ static constexpr const TSymbolUniqueId pt_o_20D = TSymbolUniqueId(3382);
+ static constexpr const TSymbolUniqueId frexp_Float4_Int4 = TSymbolUniqueId(3383);
+ static constexpr const TSymbolUniqueId pt_o_30D = TSymbolUniqueId(3384);
+ static constexpr const TSymbolUniqueId ldexp_Float1_Int1 = TSymbolUniqueId(3385);
+ static constexpr const TSymbolUniqueId ldexp_Float2_Int2 = TSymbolUniqueId(3386);
+ static constexpr const TSymbolUniqueId ldexp_Float3_Int3 = TSymbolUniqueId(3387);
+ static constexpr const TSymbolUniqueId ldexp_Float4_Int4 = TSymbolUniqueId(3388);
+ static constexpr const TSymbolUniqueId packSnorm2x16_Float2 = TSymbolUniqueId(3389);
+ static constexpr const TSymbolUniqueId packHalf2x16_Float2 = TSymbolUniqueId(3390);
+ static constexpr const TSymbolUniqueId unpackSnorm2x16_UInt1 = TSymbolUniqueId(3391);
+ static constexpr const TSymbolUniqueId unpackHalf2x16_UInt1 = TSymbolUniqueId(3392);
+ static constexpr const TSymbolUniqueId packUnorm2x16_Float2 = TSymbolUniqueId(3393);
+ static constexpr const TSymbolUniqueId unpackUnorm2x16_UInt1 = TSymbolUniqueId(3394);
+ static constexpr const TSymbolUniqueId packUnorm4x8_Float4 = TSymbolUniqueId(3395);
+ static constexpr const TSymbolUniqueId packSnorm4x8_Float4 = TSymbolUniqueId(3396);
+ static constexpr const TSymbolUniqueId unpackUnorm4x8_UInt1 = TSymbolUniqueId(3397);
+ static constexpr const TSymbolUniqueId unpackSnorm4x8_UInt1 = TSymbolUniqueId(3398);
+ static constexpr const TSymbolUniqueId length_Float1 = TSymbolUniqueId(3399);
+ static constexpr const TSymbolUniqueId length_Float2 = TSymbolUniqueId(3400);
+ static constexpr const TSymbolUniqueId length_Float3 = TSymbolUniqueId(3401);
+ static constexpr const TSymbolUniqueId length_Float4 = TSymbolUniqueId(3402);
+ static constexpr const TSymbolUniqueId distance_Float1_Float1 = TSymbolUniqueId(3403);
+ static constexpr const TSymbolUniqueId distance_Float2_Float2 = TSymbolUniqueId(3404);
+ static constexpr const TSymbolUniqueId distance_Float3_Float3 = TSymbolUniqueId(3405);
+ static constexpr const TSymbolUniqueId distance_Float4_Float4 = TSymbolUniqueId(3406);
+ static constexpr const TSymbolUniqueId dot_Float1_Float1 = TSymbolUniqueId(3407);
+ static constexpr const TSymbolUniqueId dot_Float2_Float2 = TSymbolUniqueId(3408);
+ static constexpr const TSymbolUniqueId dot_Float3_Float3 = TSymbolUniqueId(3409);
+ static constexpr const TSymbolUniqueId dot_Float4_Float4 = TSymbolUniqueId(3410);
+ static constexpr const TSymbolUniqueId cross_Float3_Float3 = TSymbolUniqueId(3411);
+ static constexpr const TSymbolUniqueId normalize_Float1 = TSymbolUniqueId(3412);
+ static constexpr const TSymbolUniqueId normalize_Float2 = TSymbolUniqueId(3413);
+ static constexpr const TSymbolUniqueId normalize_Float3 = TSymbolUniqueId(3414);
+ static constexpr const TSymbolUniqueId normalize_Float4 = TSymbolUniqueId(3415);
+ static constexpr const TSymbolUniqueId faceforward_Float1_Float1_Float1 = TSymbolUniqueId(3416);
+ static constexpr const TSymbolUniqueId faceforward_Float2_Float2_Float2 = TSymbolUniqueId(3417);
+ static constexpr const TSymbolUniqueId faceforward_Float3_Float3_Float3 = TSymbolUniqueId(3418);
+ static constexpr const TSymbolUniqueId faceforward_Float4_Float4_Float4 = TSymbolUniqueId(3419);
+ static constexpr const TSymbolUniqueId reflect_Float1_Float1 = TSymbolUniqueId(3420);
+ static constexpr const TSymbolUniqueId reflect_Float2_Float2 = TSymbolUniqueId(3421);
+ static constexpr const TSymbolUniqueId reflect_Float3_Float3 = TSymbolUniqueId(3422);
+ static constexpr const TSymbolUniqueId reflect_Float4_Float4 = TSymbolUniqueId(3423);
+ static constexpr const TSymbolUniqueId refract_Float1_Float1_Float1 = TSymbolUniqueId(3424);
+ static constexpr const TSymbolUniqueId refract_Float2_Float2_Float1 = TSymbolUniqueId(3425);
+ static constexpr const TSymbolUniqueId refract_Float3_Float3_Float1 = TSymbolUniqueId(3426);
+ static constexpr const TSymbolUniqueId refract_Float4_Float4_Float1 = TSymbolUniqueId(3427);
+ static constexpr const TSymbolUniqueId matrixCompMult_Float2x2_Float2x2 = TSymbolUniqueId(3428);
+ static constexpr const TSymbolUniqueId pt50B = TSymbolUniqueId(3429);
+ static constexpr const TSymbolUniqueId matrixCompMult_Float3x3_Float3x3 = TSymbolUniqueId(3430);
+ static constexpr const TSymbolUniqueId ptA0B = TSymbolUniqueId(3431);
+ static constexpr const TSymbolUniqueId matrixCompMult_Float4x4_Float4x4 = TSymbolUniqueId(3432);
+ static constexpr const TSymbolUniqueId ptF0B = TSymbolUniqueId(3433);
+ static constexpr const TSymbolUniqueId matrixCompMult_Float2x3_Float2x3 = TSymbolUniqueId(3434);
+ static constexpr const TSymbolUniqueId pt90B = TSymbolUniqueId(3435);
+ static constexpr const TSymbolUniqueId matrixCompMult_Float3x2_Float3x2 = TSymbolUniqueId(3436);
+ static constexpr const TSymbolUniqueId pt60B = TSymbolUniqueId(3437);
+ static constexpr const TSymbolUniqueId matrixCompMult_Float2x4_Float2x4 = TSymbolUniqueId(3438);
+ static constexpr const TSymbolUniqueId ptD0B = TSymbolUniqueId(3439);
+ static constexpr const TSymbolUniqueId matrixCompMult_Float4x2_Float4x2 = TSymbolUniqueId(3440);
+ static constexpr const TSymbolUniqueId pt70B = TSymbolUniqueId(3441);
+ static constexpr const TSymbolUniqueId matrixCompMult_Float3x4_Float3x4 = TSymbolUniqueId(3442);
+ static constexpr const TSymbolUniqueId ptE0B = TSymbolUniqueId(3443);
+ static constexpr const TSymbolUniqueId matrixCompMult_Float4x3_Float4x3 = TSymbolUniqueId(3444);
+ static constexpr const TSymbolUniqueId ptB0B = TSymbolUniqueId(3445);
+ static constexpr const TSymbolUniqueId outerProduct_Float2_Float2 = TSymbolUniqueId(3446);
+ static constexpr const TSymbolUniqueId outerProduct_Float3_Float3 = TSymbolUniqueId(3447);
+ static constexpr const TSymbolUniqueId outerProduct_Float4_Float4 = TSymbolUniqueId(3448);
+ static constexpr const TSymbolUniqueId outerProduct_Float3_Float2 = TSymbolUniqueId(3449);
+ static constexpr const TSymbolUniqueId outerProduct_Float2_Float3 = TSymbolUniqueId(3450);
+ static constexpr const TSymbolUniqueId outerProduct_Float4_Float2 = TSymbolUniqueId(3451);
+ static constexpr const TSymbolUniqueId outerProduct_Float2_Float4 = TSymbolUniqueId(3452);
+ static constexpr const TSymbolUniqueId outerProduct_Float4_Float3 = TSymbolUniqueId(3453);
+ static constexpr const TSymbolUniqueId outerProduct_Float3_Float4 = TSymbolUniqueId(3454);
+ static constexpr const TSymbolUniqueId transpose_Float2x2 = TSymbolUniqueId(3455);
+ static constexpr const TSymbolUniqueId transpose_Float3x3 = TSymbolUniqueId(3456);
+ static constexpr const TSymbolUniqueId transpose_Float4x4 = TSymbolUniqueId(3457);
+ static constexpr const TSymbolUniqueId transpose_Float3x2 = TSymbolUniqueId(3458);
+ static constexpr const TSymbolUniqueId transpose_Float2x3 = TSymbolUniqueId(3459);
+ static constexpr const TSymbolUniqueId transpose_Float4x2 = TSymbolUniqueId(3460);
+ static constexpr const TSymbolUniqueId transpose_Float2x4 = TSymbolUniqueId(3461);
+ static constexpr const TSymbolUniqueId transpose_Float4x3 = TSymbolUniqueId(3462);
+ static constexpr const TSymbolUniqueId transpose_Float3x4 = TSymbolUniqueId(3463);
+ static constexpr const TSymbolUniqueId determinant_Float2x2 = TSymbolUniqueId(3464);
+ static constexpr const TSymbolUniqueId determinant_Float3x3 = TSymbolUniqueId(3465);
+ static constexpr const TSymbolUniqueId determinant_Float4x4 = TSymbolUniqueId(3466);
+ static constexpr const TSymbolUniqueId inverse_Float2x2 = TSymbolUniqueId(3467);
+ static constexpr const TSymbolUniqueId inverse_Float3x3 = TSymbolUniqueId(3468);
+ static constexpr const TSymbolUniqueId inverse_Float4x4 = TSymbolUniqueId(3469);
+ static constexpr const TSymbolUniqueId lessThan_Float2_Float2 = TSymbolUniqueId(3470);
+ static constexpr const TSymbolUniqueId lessThan_Float3_Float3 = TSymbolUniqueId(3471);
+ static constexpr const TSymbolUniqueId lessThan_Float4_Float4 = TSymbolUniqueId(3472);
+ static constexpr const TSymbolUniqueId lessThan_Int2_Int2 = TSymbolUniqueId(3473);
+ static constexpr const TSymbolUniqueId lessThan_Int3_Int3 = TSymbolUniqueId(3474);
+ static constexpr const TSymbolUniqueId lessThan_Int4_Int4 = TSymbolUniqueId(3475);
+ static constexpr const TSymbolUniqueId lessThan_UInt2_UInt2 = TSymbolUniqueId(3476);
+ static constexpr const TSymbolUniqueId lessThan_UInt3_UInt3 = TSymbolUniqueId(3477);
+ static constexpr const TSymbolUniqueId lessThan_UInt4_UInt4 = TSymbolUniqueId(3478);
+ static constexpr const TSymbolUniqueId lessThanEqual_Float2_Float2 = TSymbolUniqueId(3479);
+ static constexpr const TSymbolUniqueId lessThanEqual_Float3_Float3 = TSymbolUniqueId(3480);
+ static constexpr const TSymbolUniqueId lessThanEqual_Float4_Float4 = TSymbolUniqueId(3481);
+ static constexpr const TSymbolUniqueId lessThanEqual_Int2_Int2 = TSymbolUniqueId(3482);
+ static constexpr const TSymbolUniqueId lessThanEqual_Int3_Int3 = TSymbolUniqueId(3483);
+ static constexpr const TSymbolUniqueId lessThanEqual_Int4_Int4 = TSymbolUniqueId(3484);
+ static constexpr const TSymbolUniqueId lessThanEqual_UInt2_UInt2 = TSymbolUniqueId(3485);
+ static constexpr const TSymbolUniqueId lessThanEqual_UInt3_UInt3 = TSymbolUniqueId(3486);
+ static constexpr const TSymbolUniqueId lessThanEqual_UInt4_UInt4 = TSymbolUniqueId(3487);
+ static constexpr const TSymbolUniqueId greaterThan_Float2_Float2 = TSymbolUniqueId(3488);
+ static constexpr const TSymbolUniqueId greaterThan_Float3_Float3 = TSymbolUniqueId(3489);
+ static constexpr const TSymbolUniqueId greaterThan_Float4_Float4 = TSymbolUniqueId(3490);
+ static constexpr const TSymbolUniqueId greaterThan_Int2_Int2 = TSymbolUniqueId(3491);
+ static constexpr const TSymbolUniqueId greaterThan_Int3_Int3 = TSymbolUniqueId(3492);
+ static constexpr const TSymbolUniqueId greaterThan_Int4_Int4 = TSymbolUniqueId(3493);
+ static constexpr const TSymbolUniqueId greaterThan_UInt2_UInt2 = TSymbolUniqueId(3494);
+ static constexpr const TSymbolUniqueId greaterThan_UInt3_UInt3 = TSymbolUniqueId(3495);
+ static constexpr const TSymbolUniqueId greaterThan_UInt4_UInt4 = TSymbolUniqueId(3496);
+ static constexpr const TSymbolUniqueId greaterThanEqual_Float2_Float2 = TSymbolUniqueId(3497);
+ static constexpr const TSymbolUniqueId greaterThanEqual_Float3_Float3 = TSymbolUniqueId(3498);
+ static constexpr const TSymbolUniqueId greaterThanEqual_Float4_Float4 = TSymbolUniqueId(3499);
+ static constexpr const TSymbolUniqueId greaterThanEqual_Int2_Int2 = TSymbolUniqueId(3500);
+ static constexpr const TSymbolUniqueId greaterThanEqual_Int3_Int3 = TSymbolUniqueId(3501);
+ static constexpr const TSymbolUniqueId greaterThanEqual_Int4_Int4 = TSymbolUniqueId(3502);
+ static constexpr const TSymbolUniqueId greaterThanEqual_UInt2_UInt2 = TSymbolUniqueId(3503);
+ static constexpr const TSymbolUniqueId greaterThanEqual_UInt3_UInt3 = TSymbolUniqueId(3504);
+ static constexpr const TSymbolUniqueId greaterThanEqual_UInt4_UInt4 = TSymbolUniqueId(3505);
+ static constexpr const TSymbolUniqueId equal_Float2_Float2 = TSymbolUniqueId(3506);
+ static constexpr const TSymbolUniqueId equal_Float3_Float3 = TSymbolUniqueId(3507);
+ static constexpr const TSymbolUniqueId equal_Float4_Float4 = TSymbolUniqueId(3508);
+ static constexpr const TSymbolUniqueId equal_Int2_Int2 = TSymbolUniqueId(3509);
+ static constexpr const TSymbolUniqueId equal_Int3_Int3 = TSymbolUniqueId(3510);
+ static constexpr const TSymbolUniqueId equal_Int4_Int4 = TSymbolUniqueId(3511);
+ static constexpr const TSymbolUniqueId equal_UInt2_UInt2 = TSymbolUniqueId(3512);
+ static constexpr const TSymbolUniqueId equal_UInt3_UInt3 = TSymbolUniqueId(3513);
+ static constexpr const TSymbolUniqueId equal_UInt4_UInt4 = TSymbolUniqueId(3514);
+ static constexpr const TSymbolUniqueId equal_Bool2_Bool2 = TSymbolUniqueId(3515);
+ static constexpr const TSymbolUniqueId equal_Bool3_Bool3 = TSymbolUniqueId(3516);
+ static constexpr const TSymbolUniqueId equal_Bool4_Bool4 = TSymbolUniqueId(3517);
+ static constexpr const TSymbolUniqueId notEqual_Float2_Float2 = TSymbolUniqueId(3518);
+ static constexpr const TSymbolUniqueId notEqual_Float3_Float3 = TSymbolUniqueId(3519);
+ static constexpr const TSymbolUniqueId notEqual_Float4_Float4 = TSymbolUniqueId(3520);
+ static constexpr const TSymbolUniqueId notEqual_Int2_Int2 = TSymbolUniqueId(3521);
+ static constexpr const TSymbolUniqueId notEqual_Int3_Int3 = TSymbolUniqueId(3522);
+ static constexpr const TSymbolUniqueId notEqual_Int4_Int4 = TSymbolUniqueId(3523);
+ static constexpr const TSymbolUniqueId notEqual_UInt2_UInt2 = TSymbolUniqueId(3524);
+ static constexpr const TSymbolUniqueId notEqual_UInt3_UInt3 = TSymbolUniqueId(3525);
+ static constexpr const TSymbolUniqueId notEqual_UInt4_UInt4 = TSymbolUniqueId(3526);
+ static constexpr const TSymbolUniqueId notEqual_Bool2_Bool2 = TSymbolUniqueId(3527);
+ static constexpr const TSymbolUniqueId notEqual_Bool3_Bool3 = TSymbolUniqueId(3528);
+ static constexpr const TSymbolUniqueId notEqual_Bool4_Bool4 = TSymbolUniqueId(3529);
+ static constexpr const TSymbolUniqueId any_Bool2 = TSymbolUniqueId(3530);
+ static constexpr const TSymbolUniqueId any_Bool3 = TSymbolUniqueId(3531);
+ static constexpr const TSymbolUniqueId any_Bool4 = TSymbolUniqueId(3532);
+ static constexpr const TSymbolUniqueId all_Bool2 = TSymbolUniqueId(3533);
+ static constexpr const TSymbolUniqueId all_Bool3 = TSymbolUniqueId(3534);
+ static constexpr const TSymbolUniqueId all_Bool4 = TSymbolUniqueId(3535);
+ static constexpr const TSymbolUniqueId notFunc_Bool2 = TSymbolUniqueId(3536);
+ static constexpr const TSymbolUniqueId notFunc_Bool3 = TSymbolUniqueId(3537);
+ static constexpr const TSymbolUniqueId notFunc_Bool4 = TSymbolUniqueId(3538);
+ static constexpr const TSymbolUniqueId bitfieldExtract_Int1_Int1_Int1 = TSymbolUniqueId(3539);
+ static constexpr const TSymbolUniqueId bitfieldExtract_Int2_Int1_Int1 = TSymbolUniqueId(3540);
+ static constexpr const TSymbolUniqueId bitfieldExtract_Int3_Int1_Int1 = TSymbolUniqueId(3541);
+ static constexpr const TSymbolUniqueId bitfieldExtract_Int4_Int1_Int1 = TSymbolUniqueId(3542);
+ static constexpr const TSymbolUniqueId bitfieldExtract_UInt1_Int1_Int1 = TSymbolUniqueId(3543);
+ static constexpr const TSymbolUniqueId bitfieldExtract_UInt2_Int1_Int1 = TSymbolUniqueId(3544);
+ static constexpr const TSymbolUniqueId bitfieldExtract_UInt3_Int1_Int1 = TSymbolUniqueId(3545);
+ static constexpr const TSymbolUniqueId bitfieldExtract_UInt4_Int1_Int1 = TSymbolUniqueId(3546);
+ static constexpr const TSymbolUniqueId bitfieldInsert_Int1_Int1_Int1_Int1 =
+ TSymbolUniqueId(3547);
+ static constexpr const TSymbolUniqueId bitfieldInsert_Int2_Int2_Int1_Int1 =
+ TSymbolUniqueId(3548);
+ static constexpr const TSymbolUniqueId bitfieldInsert_Int3_Int3_Int1_Int1 =
+ TSymbolUniqueId(3549);
+ static constexpr const TSymbolUniqueId bitfieldInsert_Int4_Int4_Int1_Int1 =
+ TSymbolUniqueId(3550);
+ static constexpr const TSymbolUniqueId bitfieldInsert_UInt1_UInt1_Int1_Int1 =
+ TSymbolUniqueId(3551);
+ static constexpr const TSymbolUniqueId bitfieldInsert_UInt2_UInt2_Int1_Int1 =
+ TSymbolUniqueId(3552);
+ static constexpr const TSymbolUniqueId bitfieldInsert_UInt3_UInt3_Int1_Int1 =
+ TSymbolUniqueId(3553);
+ static constexpr const TSymbolUniqueId bitfieldInsert_UInt4_UInt4_Int1_Int1 =
+ TSymbolUniqueId(3554);
+ static constexpr const TSymbolUniqueId bitfieldReverse_Int1 = TSymbolUniqueId(3555);
+ static constexpr const TSymbolUniqueId bitfieldReverse_Int2 = TSymbolUniqueId(3556);
+ static constexpr const TSymbolUniqueId bitfieldReverse_Int3 = TSymbolUniqueId(3557);
+ static constexpr const TSymbolUniqueId bitfieldReverse_Int4 = TSymbolUniqueId(3558);
+ static constexpr const TSymbolUniqueId bitfieldReverse_UInt1 = TSymbolUniqueId(3559);
+ static constexpr const TSymbolUniqueId bitfieldReverse_UInt2 = TSymbolUniqueId(3560);
+ static constexpr const TSymbolUniqueId bitfieldReverse_UInt3 = TSymbolUniqueId(3561);
+ static constexpr const TSymbolUniqueId bitfieldReverse_UInt4 = TSymbolUniqueId(3562);
+ static constexpr const TSymbolUniqueId bitCount_Int1 = TSymbolUniqueId(3563);
+ static constexpr const TSymbolUniqueId bitCount_Int2 = TSymbolUniqueId(3564);
+ static constexpr const TSymbolUniqueId bitCount_Int3 = TSymbolUniqueId(3565);
+ static constexpr const TSymbolUniqueId bitCount_Int4 = TSymbolUniqueId(3566);
+ static constexpr const TSymbolUniqueId bitCount_UInt1 = TSymbolUniqueId(3567);
+ static constexpr const TSymbolUniqueId bitCount_UInt2 = TSymbolUniqueId(3568);
+ static constexpr const TSymbolUniqueId bitCount_UInt3 = TSymbolUniqueId(3569);
+ static constexpr const TSymbolUniqueId bitCount_UInt4 = TSymbolUniqueId(3570);
+ static constexpr const TSymbolUniqueId findLSB_Int1 = TSymbolUniqueId(3571);
+ static constexpr const TSymbolUniqueId findLSB_Int2 = TSymbolUniqueId(3572);
+ static constexpr const TSymbolUniqueId findLSB_Int3 = TSymbolUniqueId(3573);
+ static constexpr const TSymbolUniqueId findLSB_Int4 = TSymbolUniqueId(3574);
+ static constexpr const TSymbolUniqueId findLSB_UInt1 = TSymbolUniqueId(3575);
+ static constexpr const TSymbolUniqueId findLSB_UInt2 = TSymbolUniqueId(3576);
+ static constexpr const TSymbolUniqueId findLSB_UInt3 = TSymbolUniqueId(3577);
+ static constexpr const TSymbolUniqueId findLSB_UInt4 = TSymbolUniqueId(3578);
+ static constexpr const TSymbolUniqueId findMSB_Int1 = TSymbolUniqueId(3579);
+ static constexpr const TSymbolUniqueId findMSB_Int2 = TSymbolUniqueId(3580);
+ static constexpr const TSymbolUniqueId findMSB_Int3 = TSymbolUniqueId(3581);
+ static constexpr const TSymbolUniqueId findMSB_Int4 = TSymbolUniqueId(3582);
+ static constexpr const TSymbolUniqueId findMSB_UInt1 = TSymbolUniqueId(3583);
+ static constexpr const TSymbolUniqueId findMSB_UInt2 = TSymbolUniqueId(3584);
+ static constexpr const TSymbolUniqueId findMSB_UInt3 = TSymbolUniqueId(3585);
+ static constexpr const TSymbolUniqueId findMSB_UInt4 = TSymbolUniqueId(3586);
+ static constexpr const TSymbolUniqueId uaddCarry_UInt1_UInt1_UInt1 = TSymbolUniqueId(3587);
+ static constexpr const TSymbolUniqueId pt_o_00E = TSymbolUniqueId(3588);
+ static constexpr const TSymbolUniqueId uaddCarry_UInt2_UInt2_UInt2 = TSymbolUniqueId(3589);
+ static constexpr const TSymbolUniqueId pt_o_10E = TSymbolUniqueId(3590);
+ static constexpr const TSymbolUniqueId uaddCarry_UInt3_UInt3_UInt3 = TSymbolUniqueId(3591);
+ static constexpr const TSymbolUniqueId pt_o_20E = TSymbolUniqueId(3592);
+ static constexpr const TSymbolUniqueId uaddCarry_UInt4_UInt4_UInt4 = TSymbolUniqueId(3593);
+ static constexpr const TSymbolUniqueId pt_o_30E = TSymbolUniqueId(3594);
+ static constexpr const TSymbolUniqueId usubBorrow_UInt1_UInt1_UInt1 = TSymbolUniqueId(3595);
+ static constexpr const TSymbolUniqueId usubBorrow_UInt2_UInt2_UInt2 = TSymbolUniqueId(3596);
+ static constexpr const TSymbolUniqueId usubBorrow_UInt3_UInt3_UInt3 = TSymbolUniqueId(3597);
+ static constexpr const TSymbolUniqueId usubBorrow_UInt4_UInt4_UInt4 = TSymbolUniqueId(3598);
+ static constexpr const TSymbolUniqueId umulExtended_UInt1_UInt1_UInt1_UInt1 =
+ TSymbolUniqueId(3599);
+ static constexpr const TSymbolUniqueId umulExtended_UInt2_UInt2_UInt2_UInt2 =
+ TSymbolUniqueId(3600);
+ static constexpr const TSymbolUniqueId umulExtended_UInt3_UInt3_UInt3_UInt3 =
+ TSymbolUniqueId(3601);
+ static constexpr const TSymbolUniqueId umulExtended_UInt4_UInt4_UInt4_UInt4 =
+ TSymbolUniqueId(3602);
+ static constexpr const TSymbolUniqueId imulExtended_Int1_Int1_Int1_Int1 = TSymbolUniqueId(3603);
+ static constexpr const TSymbolUniqueId imulExtended_Int2_Int2_Int2_Int2 = TSymbolUniqueId(3604);
+ static constexpr const TSymbolUniqueId imulExtended_Int3_Int3_Int3_Int3 = TSymbolUniqueId(3605);
+ static constexpr const TSymbolUniqueId imulExtended_Int4_Int4_Int4_Int4 = TSymbolUniqueId(3606);
+ static constexpr const TSymbolUniqueId texture2D_Sampler2D1_Float2 = TSymbolUniqueId(3607);
+ static constexpr const TSymbolUniqueId pt00I = TSymbolUniqueId(3608);
+ static constexpr const TSymbolUniqueId texture2DProj_Sampler2D1_Float3 = TSymbolUniqueId(3609);
+ static constexpr const TSymbolUniqueId texture2DProj_Sampler2D1_Float4 = TSymbolUniqueId(3610);
+ static constexpr const TSymbolUniqueId textureCube_SamplerCube1_Float3 = TSymbolUniqueId(3611);
+ static constexpr const TSymbolUniqueId pt00K = TSymbolUniqueId(3612);
+ static constexpr const TSymbolUniqueId texture3D_Sampler3D1_Float3 = TSymbolUniqueId(3613);
+ static constexpr const TSymbolUniqueId pt00J = TSymbolUniqueId(3614);
+ static constexpr const TSymbolUniqueId texture3DProj_Sampler3D1_Float4 = TSymbolUniqueId(3615);
+ static constexpr const TSymbolUniqueId shadow2DEXT_Sampler2DShadow1_Float3 =
+ TSymbolUniqueId(3616);
+ static constexpr const TSymbolUniqueId pt00d = TSymbolUniqueId(3617);
+ static constexpr const TSymbolUniqueId shadow2DProjEXT_Sampler2DShadow1_Float4 =
+ TSymbolUniqueId(3618);
+ static constexpr const TSymbolUniqueId texture2D_SamplerExternalOES1_Float2 =
+ TSymbolUniqueId(3619);
+ static constexpr const TSymbolUniqueId pt00M = TSymbolUniqueId(3620);
+ static constexpr const TSymbolUniqueId texture2DProj_SamplerExternalOES1_Float3 =
+ TSymbolUniqueId(3621);
+ static constexpr const TSymbolUniqueId texture2DProj_SamplerExternalOES1_Float4 =
+ TSymbolUniqueId(3622);
+ static constexpr const TSymbolUniqueId texture2DRect_Sampler2DRect1_Float2 =
+ TSymbolUniqueId(3623);
+ static constexpr const TSymbolUniqueId pt00O = TSymbolUniqueId(3624);
+ static constexpr const TSymbolUniqueId texture2DRectProj_Sampler2DRect1_Float3 =
+ TSymbolUniqueId(3625);
+ static constexpr const TSymbolUniqueId texture2DRectProj_Sampler2DRect1_Float4 =
+ TSymbolUniqueId(3626);
+ static constexpr const TSymbolUniqueId texture2DGradEXT_Sampler2D1_Float2_Float2_Float2 =
+ TSymbolUniqueId(3627);
+ static constexpr const TSymbolUniqueId texture2DProjGradEXT_Sampler2D1_Float3_Float2_Float2 =
+ TSymbolUniqueId(3628);
+ static constexpr const TSymbolUniqueId texture2DProjGradEXT_Sampler2D1_Float4_Float2_Float2 =
+ TSymbolUniqueId(3629);
+ static constexpr const TSymbolUniqueId textureCubeGradEXT_SamplerCube1_Float3_Float3_Float3 =
+ TSymbolUniqueId(3630);
+ static constexpr const TSymbolUniqueId textureVideoWEBGL_SamplerVideoWEBGL1_Float2 =
+ TSymbolUniqueId(3631);
+ static constexpr const TSymbolUniqueId pt00y = TSymbolUniqueId(3632);
+ static constexpr const TSymbolUniqueId texture2D_Sampler2D1_Float2_Float1 =
+ TSymbolUniqueId(3633);
+ static constexpr const TSymbolUniqueId texture2DProj_Sampler2D1_Float3_Float1 =
+ TSymbolUniqueId(3634);
+ static constexpr const TSymbolUniqueId texture2DProj_Sampler2D1_Float4_Float1 =
+ TSymbolUniqueId(3635);
+ static constexpr const TSymbolUniqueId textureCube_SamplerCube1_Float3_Float1 =
+ TSymbolUniqueId(3636);
+ static constexpr const TSymbolUniqueId texture3D_Sampler3D1_Float3_Float1 =
+ TSymbolUniqueId(3637);
+ static constexpr const TSymbolUniqueId texture3DProj_Sampler3D1_Float4_Float1 =
+ TSymbolUniqueId(3638);
+ static constexpr const TSymbolUniqueId texture3DLod_Sampler3D1_Float3_Float1 =
+ TSymbolUniqueId(3639);
+ static constexpr const TSymbolUniqueId texture3DProjLod_Sampler3D1_Float4_Float1 =
+ TSymbolUniqueId(3640);
+ static constexpr const TSymbolUniqueId texture2DLod_Sampler2D1_Float2_Float1 =
+ TSymbolUniqueId(3641);
+ static constexpr const TSymbolUniqueId texture2DProjLod_Sampler2D1_Float3_Float1 =
+ TSymbolUniqueId(3642);
+ static constexpr const TSymbolUniqueId texture2DProjLod_Sampler2D1_Float4_Float1 =
+ TSymbolUniqueId(3643);
+ static constexpr const TSymbolUniqueId textureCubeLod_SamplerCube1_Float3_Float1 =
+ TSymbolUniqueId(3644);
+ static constexpr const TSymbolUniqueId texture2DLodEXT_Sampler2D1_Float2_Float1 =
+ TSymbolUniqueId(3645);
+ static constexpr const TSymbolUniqueId texture2DProjLodEXT_Sampler2D1_Float3_Float1 =
+ TSymbolUniqueId(3646);
+ static constexpr const TSymbolUniqueId texture2DProjLodEXT_Sampler2D1_Float4_Float1 =
+ TSymbolUniqueId(3647);
+ static constexpr const TSymbolUniqueId textureCubeLodEXT_SamplerCube1_Float3_Float1 =
+ TSymbolUniqueId(3648);
+ static constexpr const TSymbolUniqueId texture_Sampler2D1_Float2 = TSymbolUniqueId(3649);
+ static constexpr const TSymbolUniqueId texture_ISampler2D1_Float2 = TSymbolUniqueId(3650);
+ static constexpr const TSymbolUniqueId pt00R = TSymbolUniqueId(3651);
+ static constexpr const TSymbolUniqueId texture_USampler2D1_Float2 = TSymbolUniqueId(3652);
+ static constexpr const TSymbolUniqueId pt00X = TSymbolUniqueId(3653);
+ static constexpr const TSymbolUniqueId texture_Sampler3D1_Float3 = TSymbolUniqueId(3654);
+ static constexpr const TSymbolUniqueId texture_ISampler3D1_Float3 = TSymbolUniqueId(3655);
+ static constexpr const TSymbolUniqueId pt00S = TSymbolUniqueId(3656);
+ static constexpr const TSymbolUniqueId texture_USampler3D1_Float3 = TSymbolUniqueId(3657);
+ static constexpr const TSymbolUniqueId pt00Y = TSymbolUniqueId(3658);
+ static constexpr const TSymbolUniqueId texture_SamplerCube1_Float3 = TSymbolUniqueId(3659);
+ static constexpr const TSymbolUniqueId texture_ISamplerCube1_Float3 = TSymbolUniqueId(3660);
+ static constexpr const TSymbolUniqueId pt00T = TSymbolUniqueId(3661);
+ static constexpr const TSymbolUniqueId texture_USamplerCube1_Float3 = TSymbolUniqueId(3662);
+ static constexpr const TSymbolUniqueId pt00Z = TSymbolUniqueId(3663);
+ static constexpr const TSymbolUniqueId texture_Sampler2DArray1_Float3 = TSymbolUniqueId(3664);
+ static constexpr const TSymbolUniqueId pt00L = TSymbolUniqueId(3665);
+ static constexpr const TSymbolUniqueId texture_ISampler2DArray1_Float3 = TSymbolUniqueId(3666);
+ static constexpr const TSymbolUniqueId pt00U = TSymbolUniqueId(3667);
+ static constexpr const TSymbolUniqueId texture_USampler2DArray1_Float3 = TSymbolUniqueId(3668);
+ static constexpr const TSymbolUniqueId pt00a = TSymbolUniqueId(3669);
+ static constexpr const TSymbolUniqueId texture_Sampler2DShadow1_Float3 = TSymbolUniqueId(3670);
+ static constexpr const TSymbolUniqueId texture_SamplerCubeShadow1_Float4 =
+ TSymbolUniqueId(3671);
+ static constexpr const TSymbolUniqueId pt00e = TSymbolUniqueId(3672);
+ static constexpr const TSymbolUniqueId texture_Sampler2DArrayShadow1_Float4 =
+ TSymbolUniqueId(3673);
+ static constexpr const TSymbolUniqueId pt00f = TSymbolUniqueId(3674);
+ static constexpr const TSymbolUniqueId texture_SamplerCubeArray1_Float4 = TSymbolUniqueId(3675);
+ static constexpr const TSymbolUniqueId pt00k = TSymbolUniqueId(3676);
+ static constexpr const TSymbolUniqueId texture_ISamplerCubeArray1_Float4 =
+ TSymbolUniqueId(3677);
+ static constexpr const TSymbolUniqueId pt00s = TSymbolUniqueId(3678);
+ static constexpr const TSymbolUniqueId texture_USamplerCubeArray1_Float4 =
+ TSymbolUniqueId(3679);
+ static constexpr const TSymbolUniqueId pt00x = TSymbolUniqueId(3680);
+ static constexpr const TSymbolUniqueId texture_SamplerCubeArrayShadow1_Float4_Float1 =
+ TSymbolUniqueId(3681);
+ static constexpr const TSymbolUniqueId pt00l = TSymbolUniqueId(3682);
+ static constexpr const TSymbolUniqueId textureExt_SamplerCubeArray1_Float4 =
+ TSymbolUniqueId(3683);
+ static constexpr const TSymbolUniqueId textureExt_ISamplerCubeArray1_Float4 =
+ TSymbolUniqueId(3684);
+ static constexpr const TSymbolUniqueId textureExt_USamplerCubeArray1_Float4 =
+ TSymbolUniqueId(3685);
+ static constexpr const TSymbolUniqueId textureExt_SamplerCubeArrayShadow1_Float4_Float1 =
+ TSymbolUniqueId(3686);
+ static constexpr const TSymbolUniqueId texture_SamplerExternalOES1_Float2 =
+ TSymbolUniqueId(3687);
+ static constexpr const TSymbolUniqueId texture_SamplerExternal2DY2YEXT1_Float2 =
+ TSymbolUniqueId(3688);
+ static constexpr const TSymbolUniqueId pt00N = TSymbolUniqueId(3689);
+ static constexpr const TSymbolUniqueId texture_Sampler2DRect1_Float2 = TSymbolUniqueId(3690);
+ static constexpr const TSymbolUniqueId texture_SamplerVideoWEBGL1_Float2 =
+ TSymbolUniqueId(3691);
+ static constexpr const TSymbolUniqueId textureProj_Sampler2D1_Float3 = TSymbolUniqueId(3692);
+ static constexpr const TSymbolUniqueId textureProj_ISampler2D1_Float3 = TSymbolUniqueId(3693);
+ static constexpr const TSymbolUniqueId textureProj_USampler2D1_Float3 = TSymbolUniqueId(3694);
+ static constexpr const TSymbolUniqueId textureProj_Sampler2D1_Float4 = TSymbolUniqueId(3695);
+ static constexpr const TSymbolUniqueId textureProj_ISampler2D1_Float4 = TSymbolUniqueId(3696);
+ static constexpr const TSymbolUniqueId textureProj_USampler2D1_Float4 = TSymbolUniqueId(3697);
+ static constexpr const TSymbolUniqueId textureProj_Sampler3D1_Float4 = TSymbolUniqueId(3698);
+ static constexpr const TSymbolUniqueId textureProj_ISampler3D1_Float4 = TSymbolUniqueId(3699);
+ static constexpr const TSymbolUniqueId textureProj_USampler3D1_Float4 = TSymbolUniqueId(3700);
+ static constexpr const TSymbolUniqueId textureProj_Sampler2DShadow1_Float4 =
+ TSymbolUniqueId(3701);
+ static constexpr const TSymbolUniqueId textureProj_SamplerExternalOES1_Float3 =
+ TSymbolUniqueId(3702);
+ static constexpr const TSymbolUniqueId textureProj_SamplerExternalOES1_Float4 =
+ TSymbolUniqueId(3703);
+ static constexpr const TSymbolUniqueId textureProj_SamplerExternal2DY2YEXT1_Float3 =
+ TSymbolUniqueId(3704);
+ static constexpr const TSymbolUniqueId textureProj_SamplerExternal2DY2YEXT1_Float4 =
+ TSymbolUniqueId(3705);
+ static constexpr const TSymbolUniqueId textureProj_Sampler2DRect1_Float3 =
+ TSymbolUniqueId(3706);
+ static constexpr const TSymbolUniqueId textureProj_Sampler2DRect1_Float4 =
+ TSymbolUniqueId(3707);
+ static constexpr const TSymbolUniqueId textureLod_Sampler2D1_Float2_Float1 =
+ TSymbolUniqueId(3708);
+ static constexpr const TSymbolUniqueId textureLod_ISampler2D1_Float2_Float1 =
+ TSymbolUniqueId(3709);
+ static constexpr const TSymbolUniqueId textureLod_USampler2D1_Float2_Float1 =
+ TSymbolUniqueId(3710);
+ static constexpr const TSymbolUniqueId textureLod_Sampler3D1_Float3_Float1 =
+ TSymbolUniqueId(3711);
+ static constexpr const TSymbolUniqueId textureLod_ISampler3D1_Float3_Float1 =
+ TSymbolUniqueId(3712);
+ static constexpr const TSymbolUniqueId textureLod_USampler3D1_Float3_Float1 =
+ TSymbolUniqueId(3713);
+ static constexpr const TSymbolUniqueId textureLod_SamplerCube1_Float3_Float1 =
+ TSymbolUniqueId(3714);
+ static constexpr const TSymbolUniqueId textureLod_ISamplerCube1_Float3_Float1 =
+ TSymbolUniqueId(3715);
+ static constexpr const TSymbolUniqueId textureLod_USamplerCube1_Float3_Float1 =
+ TSymbolUniqueId(3716);
+ static constexpr const TSymbolUniqueId textureLod_Sampler2DArray1_Float3_Float1 =
+ TSymbolUniqueId(3717);
+ static constexpr const TSymbolUniqueId textureLod_ISampler2DArray1_Float3_Float1 =
+ TSymbolUniqueId(3718);
+ static constexpr const TSymbolUniqueId textureLod_USampler2DArray1_Float3_Float1 =
+ TSymbolUniqueId(3719);
+ static constexpr const TSymbolUniqueId textureLod_Sampler2DShadow1_Float3_Float1 =
+ TSymbolUniqueId(3720);
+ static constexpr const TSymbolUniqueId textureLod_SamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(3721);
+ static constexpr const TSymbolUniqueId textureLod_ISamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(3722);
+ static constexpr const TSymbolUniqueId textureLod_USamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(3723);
+ static constexpr const TSymbolUniqueId textureLodExt_SamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(3724);
+ static constexpr const TSymbolUniqueId textureLodExt_ISamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(3725);
+ static constexpr const TSymbolUniqueId textureLodExt_USamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(3726);
+ static constexpr const TSymbolUniqueId textureSize_Sampler2D1_Int1 = TSymbolUniqueId(3727);
+ static constexpr const TSymbolUniqueId textureSize_ISampler2D1_Int1 = TSymbolUniqueId(3728);
+ static constexpr const TSymbolUniqueId textureSize_USampler2D1_Int1 = TSymbolUniqueId(3729);
+ static constexpr const TSymbolUniqueId textureSize_Sampler3D1_Int1 = TSymbolUniqueId(3730);
+ static constexpr const TSymbolUniqueId textureSize_ISampler3D1_Int1 = TSymbolUniqueId(3731);
+ static constexpr const TSymbolUniqueId textureSize_USampler3D1_Int1 = TSymbolUniqueId(3732);
+ static constexpr const TSymbolUniqueId textureSize_SamplerCube1_Int1 = TSymbolUniqueId(3733);
+ static constexpr const TSymbolUniqueId textureSize_ISamplerCube1_Int1 = TSymbolUniqueId(3734);
+ static constexpr const TSymbolUniqueId textureSize_USamplerCube1_Int1 = TSymbolUniqueId(3735);
+ static constexpr const TSymbolUniqueId textureSize_Sampler2DArray1_Int1 = TSymbolUniqueId(3736);
+ static constexpr const TSymbolUniqueId textureSize_ISampler2DArray1_Int1 =
+ TSymbolUniqueId(3737);
+ static constexpr const TSymbolUniqueId textureSize_USampler2DArray1_Int1 =
+ TSymbolUniqueId(3738);
+ static constexpr const TSymbolUniqueId textureSize_Sampler2DShadow1_Int1 =
+ TSymbolUniqueId(3739);
+ static constexpr const TSymbolUniqueId textureSize_SamplerCubeShadow1_Int1 =
+ TSymbolUniqueId(3740);
+ static constexpr const TSymbolUniqueId textureSize_Sampler2DArrayShadow1_Int1 =
+ TSymbolUniqueId(3741);
+ static constexpr const TSymbolUniqueId textureSize_SamplerCubeArray1_Int1 =
+ TSymbolUniqueId(3742);
+ static constexpr const TSymbolUniqueId textureSize_ISamplerCubeArray1_Int1 =
+ TSymbolUniqueId(3743);
+ static constexpr const TSymbolUniqueId textureSize_USamplerCubeArray1_Int1 =
+ TSymbolUniqueId(3744);
+ static constexpr const TSymbolUniqueId textureSize_SamplerCubeArrayShadow1_Int1 =
+ TSymbolUniqueId(3745);
+ static constexpr const TSymbolUniqueId textureSizeExt_SamplerCubeArray1_Int1 =
+ TSymbolUniqueId(3746);
+ static constexpr const TSymbolUniqueId textureSizeExt_ISamplerCubeArray1_Int1 =
+ TSymbolUniqueId(3747);
+ static constexpr const TSymbolUniqueId textureSizeExt_USamplerCubeArray1_Int1 =
+ TSymbolUniqueId(3748);
+ static constexpr const TSymbolUniqueId textureSizeExt_SamplerCubeArrayShadow1_Int1 =
+ TSymbolUniqueId(3749);
+ static constexpr const TSymbolUniqueId textureSize_SamplerBuffer1 = TSymbolUniqueId(3750);
+ static constexpr const TSymbolUniqueId pt00j = TSymbolUniqueId(3751);
+ static constexpr const TSymbolUniqueId textureSize_ISamplerBuffer1 = TSymbolUniqueId(3752);
+ static constexpr const TSymbolUniqueId pt00r = TSymbolUniqueId(3753);
+ static constexpr const TSymbolUniqueId textureSize_USamplerBuffer1 = TSymbolUniqueId(3754);
+ static constexpr const TSymbolUniqueId pt00w = TSymbolUniqueId(3755);
+ static constexpr const TSymbolUniqueId textureSizeExt_SamplerBuffer1 = TSymbolUniqueId(3756);
+ static constexpr const TSymbolUniqueId textureSizeExt_ISamplerBuffer1 = TSymbolUniqueId(3757);
+ static constexpr const TSymbolUniqueId textureSizeExt_USamplerBuffer1 = TSymbolUniqueId(3758);
+ static constexpr const TSymbolUniqueId textureSize_Sampler2DMS1 = TSymbolUniqueId(3759);
+ static constexpr const TSymbolUniqueId pt00P = TSymbolUniqueId(3760);
+ static constexpr const TSymbolUniqueId textureSize_ISampler2DMS1 = TSymbolUniqueId(3761);
+ static constexpr const TSymbolUniqueId pt00V = TSymbolUniqueId(3762);
+ static constexpr const TSymbolUniqueId textureSize_USampler2DMS1 = TSymbolUniqueId(3763);
+ static constexpr const TSymbolUniqueId pt00b = TSymbolUniqueId(3764);
+ static constexpr const TSymbolUniqueId textureSizeExt_Sampler2DMS1 = TSymbolUniqueId(3765);
+ static constexpr const TSymbolUniqueId textureSizeExt_ISampler2DMS1 = TSymbolUniqueId(3766);
+ static constexpr const TSymbolUniqueId textureSizeExt_USampler2DMS1 = TSymbolUniqueId(3767);
+ static constexpr const TSymbolUniqueId textureSize_Sampler2DMSArray1 = TSymbolUniqueId(3768);
+ static constexpr const TSymbolUniqueId pt00Q = TSymbolUniqueId(3769);
+ static constexpr const TSymbolUniqueId textureSize_ISampler2DMSArray1 = TSymbolUniqueId(3770);
+ static constexpr const TSymbolUniqueId pt00W = TSymbolUniqueId(3771);
+ static constexpr const TSymbolUniqueId textureSize_USampler2DMSArray1 = TSymbolUniqueId(3772);
+ static constexpr const TSymbolUniqueId pt00c = TSymbolUniqueId(3773);
+ static constexpr const TSymbolUniqueId textureSizeExt_Sampler2DMSArray1 = TSymbolUniqueId(3774);
+ static constexpr const TSymbolUniqueId textureSizeExt_ISampler2DMSArray1 =
+ TSymbolUniqueId(3775);
+ static constexpr const TSymbolUniqueId textureSizeExt_USampler2DMSArray1 =
+ TSymbolUniqueId(3776);
+ static constexpr const TSymbolUniqueId textureSize_SamplerExternalOES1_Int1 =
+ TSymbolUniqueId(3777);
+ static constexpr const TSymbolUniqueId textureSize_SamplerExternal2DY2YEXT1_Int1 =
+ TSymbolUniqueId(3778);
+ static constexpr const TSymbolUniqueId textureProjLod_Sampler2D1_Float3_Float1 =
+ TSymbolUniqueId(3779);
+ static constexpr const TSymbolUniqueId textureProjLod_ISampler2D1_Float3_Float1 =
+ TSymbolUniqueId(3780);
+ static constexpr const TSymbolUniqueId textureProjLod_USampler2D1_Float3_Float1 =
+ TSymbolUniqueId(3781);
+ static constexpr const TSymbolUniqueId textureProjLod_Sampler2D1_Float4_Float1 =
+ TSymbolUniqueId(3782);
+ static constexpr const TSymbolUniqueId textureProjLod_ISampler2D1_Float4_Float1 =
+ TSymbolUniqueId(3783);
+ static constexpr const TSymbolUniqueId textureProjLod_USampler2D1_Float4_Float1 =
+ TSymbolUniqueId(3784);
+ static constexpr const TSymbolUniqueId textureProjLod_Sampler3D1_Float4_Float1 =
+ TSymbolUniqueId(3785);
+ static constexpr const TSymbolUniqueId textureProjLod_ISampler3D1_Float4_Float1 =
+ TSymbolUniqueId(3786);
+ static constexpr const TSymbolUniqueId textureProjLod_USampler3D1_Float4_Float1 =
+ TSymbolUniqueId(3787);
+ static constexpr const TSymbolUniqueId textureProjLod_Sampler2DShadow1_Float4_Float1 =
+ TSymbolUniqueId(3788);
+ static constexpr const TSymbolUniqueId texelFetch_Sampler2D1_Int2_Int1 = TSymbolUniqueId(3789);
+ static constexpr const TSymbolUniqueId texelFetch_ISampler2D1_Int2_Int1 = TSymbolUniqueId(3790);
+ static constexpr const TSymbolUniqueId texelFetch_USampler2D1_Int2_Int1 = TSymbolUniqueId(3791);
+ static constexpr const TSymbolUniqueId texelFetch_Sampler3D1_Int3_Int1 = TSymbolUniqueId(3792);
+ static constexpr const TSymbolUniqueId texelFetch_ISampler3D1_Int3_Int1 = TSymbolUniqueId(3793);
+ static constexpr const TSymbolUniqueId texelFetch_USampler3D1_Int3_Int1 = TSymbolUniqueId(3794);
+ static constexpr const TSymbolUniqueId texelFetch_Sampler2DArray1_Int3_Int1 =
+ TSymbolUniqueId(3795);
+ static constexpr const TSymbolUniqueId texelFetch_ISampler2DArray1_Int3_Int1 =
+ TSymbolUniqueId(3796);
+ static constexpr const TSymbolUniqueId texelFetch_USampler2DArray1_Int3_Int1 =
+ TSymbolUniqueId(3797);
+ static constexpr const TSymbolUniqueId texelFetch_SamplerBuffer1_Int1 = TSymbolUniqueId(3798);
+ static constexpr const TSymbolUniqueId texelFetch_ISamplerBuffer1_Int1 = TSymbolUniqueId(3799);
+ static constexpr const TSymbolUniqueId texelFetch_USamplerBuffer1_Int1 = TSymbolUniqueId(3800);
+ static constexpr const TSymbolUniqueId texelFetchExt_SamplerBuffer1_Int1 =
+ TSymbolUniqueId(3801);
+ static constexpr const TSymbolUniqueId texelFetchExt_ISamplerBuffer1_Int1 =
+ TSymbolUniqueId(3802);
+ static constexpr const TSymbolUniqueId texelFetchExt_USamplerBuffer1_Int1 =
+ TSymbolUniqueId(3803);
+ static constexpr const TSymbolUniqueId texelFetch_Sampler2DMS1_Int2_Int1 =
+ TSymbolUniqueId(3804);
+ static constexpr const TSymbolUniqueId texelFetch_ISampler2DMS1_Int2_Int1 =
+ TSymbolUniqueId(3805);
+ static constexpr const TSymbolUniqueId texelFetch_USampler2DMS1_Int2_Int1 =
+ TSymbolUniqueId(3806);
+ static constexpr const TSymbolUniqueId texelFetchExt_Sampler2DMS1_Int2_Int1 =
+ TSymbolUniqueId(3807);
+ static constexpr const TSymbolUniqueId texelFetchExt_ISampler2DMS1_Int2_Int1 =
+ TSymbolUniqueId(3808);
+ static constexpr const TSymbolUniqueId texelFetchExt_USampler2DMS1_Int2_Int1 =
+ TSymbolUniqueId(3809);
+ static constexpr const TSymbolUniqueId texelFetch_Sampler2DMSArray1_Int3_Int1 =
+ TSymbolUniqueId(3810);
+ static constexpr const TSymbolUniqueId texelFetch_ISampler2DMSArray1_Int3_Int1 =
+ TSymbolUniqueId(3811);
+ static constexpr const TSymbolUniqueId texelFetch_USampler2DMSArray1_Int3_Int1 =
+ TSymbolUniqueId(3812);
+ static constexpr const TSymbolUniqueId texelFetchExt_Sampler2DMSArray1_Int3_Int1 =
+ TSymbolUniqueId(3813);
+ static constexpr const TSymbolUniqueId texelFetchExt_ISampler2DMSArray1_Int3_Int1 =
+ TSymbolUniqueId(3814);
+ static constexpr const TSymbolUniqueId texelFetchExt_USampler2DMSArray1_Int3_Int1 =
+ TSymbolUniqueId(3815);
+ static constexpr const TSymbolUniqueId texelFetch_SamplerExternalOES1_Int2_Int1 =
+ TSymbolUniqueId(3816);
+ static constexpr const TSymbolUniqueId texelFetch_SamplerExternal2DY2YEXT1_Int2_Int1 =
+ TSymbolUniqueId(3817);
+ static constexpr const TSymbolUniqueId textureGrad_Sampler2D1_Float2_Float2_Float2 =
+ TSymbolUniqueId(3818);
+ static constexpr const TSymbolUniqueId textureGrad_ISampler2D1_Float2_Float2_Float2 =
+ TSymbolUniqueId(3819);
+ static constexpr const TSymbolUniqueId textureGrad_USampler2D1_Float2_Float2_Float2 =
+ TSymbolUniqueId(3820);
+ static constexpr const TSymbolUniqueId textureGrad_Sampler3D1_Float3_Float3_Float3 =
+ TSymbolUniqueId(3821);
+ static constexpr const TSymbolUniqueId textureGrad_ISampler3D1_Float3_Float3_Float3 =
+ TSymbolUniqueId(3822);
+ static constexpr const TSymbolUniqueId textureGrad_USampler3D1_Float3_Float3_Float3 =
+ TSymbolUniqueId(3823);
+ static constexpr const TSymbolUniqueId textureGrad_SamplerCube1_Float3_Float3_Float3 =
+ TSymbolUniqueId(3824);
+ static constexpr const TSymbolUniqueId textureGrad_ISamplerCube1_Float3_Float3_Float3 =
+ TSymbolUniqueId(3825);
+ static constexpr const TSymbolUniqueId textureGrad_USamplerCube1_Float3_Float3_Float3 =
+ TSymbolUniqueId(3826);
+ static constexpr const TSymbolUniqueId textureGrad_Sampler2DShadow1_Float3_Float2_Float2 =
+ TSymbolUniqueId(3827);
+ static constexpr const TSymbolUniqueId textureGrad_SamplerCubeShadow1_Float4_Float3_Float3 =
+ TSymbolUniqueId(3828);
+ static constexpr const TSymbolUniqueId textureGrad_Sampler2DArray1_Float3_Float2_Float2 =
+ TSymbolUniqueId(3829);
+ static constexpr const TSymbolUniqueId textureGrad_ISampler2DArray1_Float3_Float2_Float2 =
+ TSymbolUniqueId(3830);
+ static constexpr const TSymbolUniqueId textureGrad_USampler2DArray1_Float3_Float2_Float2 =
+ TSymbolUniqueId(3831);
+ static constexpr const TSymbolUniqueId textureGrad_Sampler2DArrayShadow1_Float4_Float2_Float2 =
+ TSymbolUniqueId(3832);
+ static constexpr const TSymbolUniqueId textureGrad_SamplerCubeArray1_Float4_Float3_Float3 =
+ TSymbolUniqueId(3833);
+ static constexpr const TSymbolUniqueId textureGrad_ISamplerCubeArray1_Float4_Float3_Float3 =
+ TSymbolUniqueId(3834);
+ static constexpr const TSymbolUniqueId textureGrad_USamplerCubeArray1_Float4_Float3_Float3 =
+ TSymbolUniqueId(3835);
+ static constexpr const TSymbolUniqueId textureGradExt_SamplerCubeArray1_Float4_Float3_Float3 =
+ TSymbolUniqueId(3836);
+ static constexpr const TSymbolUniqueId textureGradExt_ISamplerCubeArray1_Float4_Float3_Float3 =
+ TSymbolUniqueId(3837);
+ static constexpr const TSymbolUniqueId textureGradExt_USamplerCubeArray1_Float4_Float3_Float3 =
+ TSymbolUniqueId(3838);
+ static constexpr const TSymbolUniqueId textureProjGrad_Sampler2D1_Float3_Float2_Float2 =
+ TSymbolUniqueId(3839);
+ static constexpr const TSymbolUniqueId textureProjGrad_ISampler2D1_Float3_Float2_Float2 =
+ TSymbolUniqueId(3840);
+ static constexpr const TSymbolUniqueId textureProjGrad_USampler2D1_Float3_Float2_Float2 =
+ TSymbolUniqueId(3841);
+ static constexpr const TSymbolUniqueId textureProjGrad_Sampler2D1_Float4_Float2_Float2 =
+ TSymbolUniqueId(3842);
+ static constexpr const TSymbolUniqueId textureProjGrad_ISampler2D1_Float4_Float2_Float2 =
+ TSymbolUniqueId(3843);
+ static constexpr const TSymbolUniqueId textureProjGrad_USampler2D1_Float4_Float2_Float2 =
+ TSymbolUniqueId(3844);
+ static constexpr const TSymbolUniqueId textureProjGrad_Sampler3D1_Float4_Float3_Float3 =
+ TSymbolUniqueId(3845);
+ static constexpr const TSymbolUniqueId textureProjGrad_ISampler3D1_Float4_Float3_Float3 =
+ TSymbolUniqueId(3846);
+ static constexpr const TSymbolUniqueId textureProjGrad_USampler3D1_Float4_Float3_Float3 =
+ TSymbolUniqueId(3847);
+ static constexpr const TSymbolUniqueId textureProjGrad_Sampler2DShadow1_Float4_Float2_Float2 =
+ TSymbolUniqueId(3848);
+ static constexpr const TSymbolUniqueId texture_Sampler2D1_Float2_Float1 = TSymbolUniqueId(3849);
+ static constexpr const TSymbolUniqueId texture_ISampler2D1_Float2_Float1 =
+ TSymbolUniqueId(3850);
+ static constexpr const TSymbolUniqueId texture_USampler2D1_Float2_Float1 =
+ TSymbolUniqueId(3851);
+ static constexpr const TSymbolUniqueId texture_Sampler3D1_Float3_Float1 = TSymbolUniqueId(3852);
+ static constexpr const TSymbolUniqueId texture_ISampler3D1_Float3_Float1 =
+ TSymbolUniqueId(3853);
+ static constexpr const TSymbolUniqueId texture_USampler3D1_Float3_Float1 =
+ TSymbolUniqueId(3854);
+ static constexpr const TSymbolUniqueId texture_SamplerCube1_Float3_Float1 =
+ TSymbolUniqueId(3855);
+ static constexpr const TSymbolUniqueId texture_ISamplerCube1_Float3_Float1 =
+ TSymbolUniqueId(3856);
+ static constexpr const TSymbolUniqueId texture_USamplerCube1_Float3_Float1 =
+ TSymbolUniqueId(3857);
+ static constexpr const TSymbolUniqueId texture_Sampler2DArray1_Float3_Float1 =
+ TSymbolUniqueId(3858);
+ static constexpr const TSymbolUniqueId texture_ISampler2DArray1_Float3_Float1 =
+ TSymbolUniqueId(3859);
+ static constexpr const TSymbolUniqueId texture_USampler2DArray1_Float3_Float1 =
+ TSymbolUniqueId(3860);
+ static constexpr const TSymbolUniqueId textureProj_Sampler2D1_Float3_Float1 =
+ TSymbolUniqueId(3861);
+ static constexpr const TSymbolUniqueId textureProj_ISampler2D1_Float3_Float1 =
+ TSymbolUniqueId(3862);
+ static constexpr const TSymbolUniqueId textureProj_USampler2D1_Float3_Float1 =
+ TSymbolUniqueId(3863);
+ static constexpr const TSymbolUniqueId textureProj_Sampler2D1_Float4_Float1 =
+ TSymbolUniqueId(3864);
+ static constexpr const TSymbolUniqueId textureProj_ISampler2D1_Float4_Float1 =
+ TSymbolUniqueId(3865);
+ static constexpr const TSymbolUniqueId textureProj_USampler2D1_Float4_Float1 =
+ TSymbolUniqueId(3866);
+ static constexpr const TSymbolUniqueId textureProj_Sampler3D1_Float4_Float1 =
+ TSymbolUniqueId(3867);
+ static constexpr const TSymbolUniqueId textureProj_ISampler3D1_Float4_Float1 =
+ TSymbolUniqueId(3868);
+ static constexpr const TSymbolUniqueId textureProj_USampler3D1_Float4_Float1 =
+ TSymbolUniqueId(3869);
+ static constexpr const TSymbolUniqueId texture_Sampler2DShadow1_Float3_Float1 =
+ TSymbolUniqueId(3870);
+ static constexpr const TSymbolUniqueId texture_SamplerCubeShadow1_Float4_Float1 =
+ TSymbolUniqueId(3871);
+ static constexpr const TSymbolUniqueId textureProj_Sampler2DShadow1_Float4_Float1 =
+ TSymbolUniqueId(3872);
+ static constexpr const TSymbolUniqueId texture_SamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(3873);
+ static constexpr const TSymbolUniqueId texture_ISamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(3874);
+ static constexpr const TSymbolUniqueId texture_USamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(3875);
+ static constexpr const TSymbolUniqueId textureExt_SamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(3876);
+ static constexpr const TSymbolUniqueId textureExt_ISamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(3877);
+ static constexpr const TSymbolUniqueId textureExt_USamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(3878);
+ static constexpr const TSymbolUniqueId texture_SamplerExternalOES1_Float2_Float1 =
+ TSymbolUniqueId(3879);
+ static constexpr const TSymbolUniqueId textureProj_SamplerExternalOES1_Float3_Float1 =
+ TSymbolUniqueId(3880);
+ static constexpr const TSymbolUniqueId textureProj_SamplerExternalOES1_Float4_Float1 =
+ TSymbolUniqueId(3881);
+ static constexpr const TSymbolUniqueId texture_SamplerExternal2DY2YEXT1_Float2_Float1 =
+ TSymbolUniqueId(3882);
+ static constexpr const TSymbolUniqueId textureProj_SamplerExternal2DY2YEXT1_Float3_Float1 =
+ TSymbolUniqueId(3883);
+ static constexpr const TSymbolUniqueId textureProj_SamplerExternal2DY2YEXT1_Float4_Float1 =
+ TSymbolUniqueId(3884);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler2D1_Float2_Int2 =
+ TSymbolUniqueId(3885);
+ static constexpr const TSymbolUniqueId textureOffset_ISampler2D1_Float2_Int2 =
+ TSymbolUniqueId(3886);
+ static constexpr const TSymbolUniqueId textureOffset_USampler2D1_Float2_Int2 =
+ TSymbolUniqueId(3887);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler3D1_Float3_Int3 =
+ TSymbolUniqueId(3888);
+ static constexpr const TSymbolUniqueId textureOffset_ISampler3D1_Float3_Int3 =
+ TSymbolUniqueId(3889);
+ static constexpr const TSymbolUniqueId textureOffset_USampler3D1_Float3_Int3 =
+ TSymbolUniqueId(3890);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler2DShadow1_Float3_Int2 =
+ TSymbolUniqueId(3891);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler2DArray1_Float3_Int2 =
+ TSymbolUniqueId(3892);
+ static constexpr const TSymbolUniqueId textureOffset_ISampler2DArray1_Float3_Int2 =
+ TSymbolUniqueId(3893);
+ static constexpr const TSymbolUniqueId textureOffset_USampler2DArray1_Float3_Int2 =
+ TSymbolUniqueId(3894);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler2D1_Float3_Int2 =
+ TSymbolUniqueId(3895);
+ static constexpr const TSymbolUniqueId textureProjOffset_ISampler2D1_Float3_Int2 =
+ TSymbolUniqueId(3896);
+ static constexpr const TSymbolUniqueId textureProjOffset_USampler2D1_Float3_Int2 =
+ TSymbolUniqueId(3897);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler2D1_Float4_Int2 =
+ TSymbolUniqueId(3898);
+ static constexpr const TSymbolUniqueId textureProjOffset_ISampler2D1_Float4_Int2 =
+ TSymbolUniqueId(3899);
+ static constexpr const TSymbolUniqueId textureProjOffset_USampler2D1_Float4_Int2 =
+ TSymbolUniqueId(3900);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler3D1_Float4_Int3 =
+ TSymbolUniqueId(3901);
+ static constexpr const TSymbolUniqueId textureProjOffset_ISampler3D1_Float4_Int3 =
+ TSymbolUniqueId(3902);
+ static constexpr const TSymbolUniqueId textureProjOffset_USampler3D1_Float4_Int3 =
+ TSymbolUniqueId(3903);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler2DShadow1_Float4_Int2 =
+ TSymbolUniqueId(3904);
+ static constexpr const TSymbolUniqueId textureLodOffset_Sampler2D1_Float2_Float1_Int2 =
+ TSymbolUniqueId(3905);
+ static constexpr const TSymbolUniqueId textureLodOffset_ISampler2D1_Float2_Float1_Int2 =
+ TSymbolUniqueId(3906);
+ static constexpr const TSymbolUniqueId textureLodOffset_USampler2D1_Float2_Float1_Int2 =
+ TSymbolUniqueId(3907);
+ static constexpr const TSymbolUniqueId textureLodOffset_Sampler3D1_Float3_Float1_Int3 =
+ TSymbolUniqueId(3908);
+ static constexpr const TSymbolUniqueId textureLodOffset_ISampler3D1_Float3_Float1_Int3 =
+ TSymbolUniqueId(3909);
+ static constexpr const TSymbolUniqueId textureLodOffset_USampler3D1_Float3_Float1_Int3 =
+ TSymbolUniqueId(3910);
+ static constexpr const TSymbolUniqueId textureLodOffset_Sampler2DShadow1_Float3_Float1_Int2 =
+ TSymbolUniqueId(3911);
+ static constexpr const TSymbolUniqueId textureLodOffset_Sampler2DArray1_Float3_Float1_Int2 =
+ TSymbolUniqueId(3912);
+ static constexpr const TSymbolUniqueId textureLodOffset_ISampler2DArray1_Float3_Float1_Int2 =
+ TSymbolUniqueId(3913);
+ static constexpr const TSymbolUniqueId textureLodOffset_USampler2DArray1_Float3_Float1_Int2 =
+ TSymbolUniqueId(3914);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_Sampler2D1_Float3_Float1_Int2 =
+ TSymbolUniqueId(3915);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_ISampler2D1_Float3_Float1_Int2 =
+ TSymbolUniqueId(3916);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_USampler2D1_Float3_Float1_Int2 =
+ TSymbolUniqueId(3917);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_Sampler2D1_Float4_Float1_Int2 =
+ TSymbolUniqueId(3918);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_ISampler2D1_Float4_Float1_Int2 =
+ TSymbolUniqueId(3919);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_USampler2D1_Float4_Float1_Int2 =
+ TSymbolUniqueId(3920);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_Sampler3D1_Float4_Float1_Int3 =
+ TSymbolUniqueId(3921);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_ISampler3D1_Float4_Float1_Int3 =
+ TSymbolUniqueId(3922);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_USampler3D1_Float4_Float1_Int3 =
+ TSymbolUniqueId(3923);
+ static constexpr const TSymbolUniqueId
+ textureProjLodOffset_Sampler2DShadow1_Float4_Float1_Int2 = TSymbolUniqueId(3924);
+ static constexpr const TSymbolUniqueId texelFetchOffset_Sampler2D1_Int2_Int1_Int2 =
+ TSymbolUniqueId(3925);
+ static constexpr const TSymbolUniqueId texelFetchOffset_ISampler2D1_Int2_Int1_Int2 =
+ TSymbolUniqueId(3926);
+ static constexpr const TSymbolUniqueId texelFetchOffset_USampler2D1_Int2_Int1_Int2 =
+ TSymbolUniqueId(3927);
+ static constexpr const TSymbolUniqueId texelFetchOffset_Sampler3D1_Int3_Int1_Int3 =
+ TSymbolUniqueId(3928);
+ static constexpr const TSymbolUniqueId texelFetchOffset_ISampler3D1_Int3_Int1_Int3 =
+ TSymbolUniqueId(3929);
+ static constexpr const TSymbolUniqueId texelFetchOffset_USampler3D1_Int3_Int1_Int3 =
+ TSymbolUniqueId(3930);
+ static constexpr const TSymbolUniqueId texelFetchOffset_Sampler2DArray1_Int3_Int1_Int2 =
+ TSymbolUniqueId(3931);
+ static constexpr const TSymbolUniqueId texelFetchOffset_ISampler2DArray1_Int3_Int1_Int2 =
+ TSymbolUniqueId(3932);
+ static constexpr const TSymbolUniqueId texelFetchOffset_USampler2DArray1_Int3_Int1_Int2 =
+ TSymbolUniqueId(3933);
+ static constexpr const TSymbolUniqueId textureGradOffset_Sampler2D1_Float2_Float2_Float2_Int2 =
+ TSymbolUniqueId(3934);
+ static constexpr const TSymbolUniqueId textureGradOffset_ISampler2D1_Float2_Float2_Float2_Int2 =
+ TSymbolUniqueId(3935);
+ static constexpr const TSymbolUniqueId textureGradOffset_USampler2D1_Float2_Float2_Float2_Int2 =
+ TSymbolUniqueId(3936);
+ static constexpr const TSymbolUniqueId textureGradOffset_Sampler3D1_Float3_Float3_Float3_Int3 =
+ TSymbolUniqueId(3937);
+ static constexpr const TSymbolUniqueId textureGradOffset_ISampler3D1_Float3_Float3_Float3_Int3 =
+ TSymbolUniqueId(3938);
+ static constexpr const TSymbolUniqueId textureGradOffset_USampler3D1_Float3_Float3_Float3_Int3 =
+ TSymbolUniqueId(3939);
+ static constexpr const TSymbolUniqueId
+ textureGradOffset_Sampler2DShadow1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(3940);
+ static constexpr const TSymbolUniqueId
+ textureGradOffset_Sampler2DArray1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(3941);
+ static constexpr const TSymbolUniqueId
+ textureGradOffset_ISampler2DArray1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(3942);
+ static constexpr const TSymbolUniqueId
+ textureGradOffset_USampler2DArray1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(3943);
+ static constexpr const TSymbolUniqueId
+ textureGradOffset_Sampler2DArrayShadow1_Float4_Float2_Float2_Int2 = TSymbolUniqueId(3944);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_Sampler2D1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(3945);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_ISampler2D1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(3946);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_USampler2D1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(3947);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_Sampler2D1_Float4_Float2_Float2_Int2 = TSymbolUniqueId(3948);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_ISampler2D1_Float4_Float2_Float2_Int2 = TSymbolUniqueId(3949);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_USampler2D1_Float4_Float2_Float2_Int2 = TSymbolUniqueId(3950);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_Sampler3D1_Float4_Float3_Float3_Int3 = TSymbolUniqueId(3951);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_ISampler3D1_Float4_Float3_Float3_Int3 = TSymbolUniqueId(3952);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_USampler3D1_Float4_Float3_Float3_Int3 = TSymbolUniqueId(3953);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_Sampler2DShadow1_Float4_Float2_Float2_Int2 = TSymbolUniqueId(3954);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler2D1_Float2_Int2_Float1 =
+ TSymbolUniqueId(3955);
+ static constexpr const TSymbolUniqueId textureOffset_ISampler2D1_Float2_Int2_Float1 =
+ TSymbolUniqueId(3956);
+ static constexpr const TSymbolUniqueId textureOffset_USampler2D1_Float2_Int2_Float1 =
+ TSymbolUniqueId(3957);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler3D1_Float3_Int3_Float1 =
+ TSymbolUniqueId(3958);
+ static constexpr const TSymbolUniqueId textureOffset_ISampler3D1_Float3_Int3_Float1 =
+ TSymbolUniqueId(3959);
+ static constexpr const TSymbolUniqueId textureOffset_USampler3D1_Float3_Int3_Float1 =
+ TSymbolUniqueId(3960);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler2DShadow1_Float3_Int2_Float1 =
+ TSymbolUniqueId(3961);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler2DArray1_Float3_Int2_Float1 =
+ TSymbolUniqueId(3962);
+ static constexpr const TSymbolUniqueId textureOffset_ISampler2DArray1_Float3_Int2_Float1 =
+ TSymbolUniqueId(3963);
+ static constexpr const TSymbolUniqueId textureOffset_USampler2DArray1_Float3_Int2_Float1 =
+ TSymbolUniqueId(3964);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler2D1_Float3_Int2_Float1 =
+ TSymbolUniqueId(3965);
+ static constexpr const TSymbolUniqueId textureProjOffset_ISampler2D1_Float3_Int2_Float1 =
+ TSymbolUniqueId(3966);
+ static constexpr const TSymbolUniqueId textureProjOffset_USampler2D1_Float3_Int2_Float1 =
+ TSymbolUniqueId(3967);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler2D1_Float4_Int2_Float1 =
+ TSymbolUniqueId(3968);
+ static constexpr const TSymbolUniqueId textureProjOffset_ISampler2D1_Float4_Int2_Float1 =
+ TSymbolUniqueId(3969);
+ static constexpr const TSymbolUniqueId textureProjOffset_USampler2D1_Float4_Int2_Float1 =
+ TSymbolUniqueId(3970);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler3D1_Float4_Int3_Float1 =
+ TSymbolUniqueId(3971);
+ static constexpr const TSymbolUniqueId textureProjOffset_ISampler3D1_Float4_Int3_Float1 =
+ TSymbolUniqueId(3972);
+ static constexpr const TSymbolUniqueId textureProjOffset_USampler3D1_Float4_Int3_Float1 =
+ TSymbolUniqueId(3973);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler2DShadow1_Float4_Int2_Float1 =
+ TSymbolUniqueId(3974);
+ static constexpr const TSymbolUniqueId textureGather_Sampler2D1_Float2 = TSymbolUniqueId(3975);
+ static constexpr const TSymbolUniqueId textureGather_ISampler2D1_Float2 = TSymbolUniqueId(3976);
+ static constexpr const TSymbolUniqueId textureGather_USampler2D1_Float2 = TSymbolUniqueId(3977);
+ static constexpr const TSymbolUniqueId textureGather_Sampler2D1_Float2_Int1 =
+ TSymbolUniqueId(3978);
+ static constexpr const TSymbolUniqueId textureGather_ISampler2D1_Float2_Int1 =
+ TSymbolUniqueId(3979);
+ static constexpr const TSymbolUniqueId textureGather_USampler2D1_Float2_Int1 =
+ TSymbolUniqueId(3980);
+ static constexpr const TSymbolUniqueId textureGather_Sampler2DArray1_Float3 =
+ TSymbolUniqueId(3981);
+ static constexpr const TSymbolUniqueId textureGather_ISampler2DArray1_Float3 =
+ TSymbolUniqueId(3982);
+ static constexpr const TSymbolUniqueId textureGather_USampler2DArray1_Float3 =
+ TSymbolUniqueId(3983);
+ static constexpr const TSymbolUniqueId textureGather_Sampler2DArray1_Float3_Int1 =
+ TSymbolUniqueId(3984);
+ static constexpr const TSymbolUniqueId textureGather_ISampler2DArray1_Float3_Int1 =
+ TSymbolUniqueId(3985);
+ static constexpr const TSymbolUniqueId textureGather_USampler2DArray1_Float3_Int1 =
+ TSymbolUniqueId(3986);
+ static constexpr const TSymbolUniqueId textureGather_SamplerCube1_Float3 =
+ TSymbolUniqueId(3987);
+ static constexpr const TSymbolUniqueId textureGather_ISamplerCube1_Float3 =
+ TSymbolUniqueId(3988);
+ static constexpr const TSymbolUniqueId textureGather_USamplerCube1_Float3 =
+ TSymbolUniqueId(3989);
+ static constexpr const TSymbolUniqueId textureGather_SamplerCube1_Float3_Int1 =
+ TSymbolUniqueId(3990);
+ static constexpr const TSymbolUniqueId textureGather_ISamplerCube1_Float3_Int1 =
+ TSymbolUniqueId(3991);
+ static constexpr const TSymbolUniqueId textureGather_USamplerCube1_Float3_Int1 =
+ TSymbolUniqueId(3992);
+ static constexpr const TSymbolUniqueId textureGather_SamplerCubeArray1_Float4 =
+ TSymbolUniqueId(3993);
+ static constexpr const TSymbolUniqueId textureGather_ISamplerCubeArray1_Float4 =
+ TSymbolUniqueId(3994);
+ static constexpr const TSymbolUniqueId textureGather_USamplerCubeArray1_Float4 =
+ TSymbolUniqueId(3995);
+ static constexpr const TSymbolUniqueId textureGather_SamplerCubeArray1_Float4_Int1 =
+ TSymbolUniqueId(3996);
+ static constexpr const TSymbolUniqueId textureGather_ISamplerCubeArray1_Float4_Int1 =
+ TSymbolUniqueId(3997);
+ static constexpr const TSymbolUniqueId textureGather_USamplerCubeArray1_Float4_Int1 =
+ TSymbolUniqueId(3998);
+ static constexpr const TSymbolUniqueId textureGather_SamplerCubeArrayShadow1_Float4_Float1 =
+ TSymbolUniqueId(3999);
+ static constexpr const TSymbolUniqueId textureGatherExt_SamplerCubeArray1_Float4 =
+ TSymbolUniqueId(4000);
+ static constexpr const TSymbolUniqueId textureGatherExt_ISamplerCubeArray1_Float4 =
+ TSymbolUniqueId(4001);
+ static constexpr const TSymbolUniqueId textureGatherExt_USamplerCubeArray1_Float4 =
+ TSymbolUniqueId(4002);
+ static constexpr const TSymbolUniqueId textureGatherExt_SamplerCubeArray1_Float4_Int1 =
+ TSymbolUniqueId(4003);
+ static constexpr const TSymbolUniqueId textureGatherExt_ISamplerCubeArray1_Float4_Int1 =
+ TSymbolUniqueId(4004);
+ static constexpr const TSymbolUniqueId textureGatherExt_USamplerCubeArray1_Float4_Int1 =
+ TSymbolUniqueId(4005);
+ static constexpr const TSymbolUniqueId textureGatherExt_SamplerCubeArrayShadow1_Float4_Float1 =
+ TSymbolUniqueId(4006);
+ static constexpr const TSymbolUniqueId textureGather_Sampler2DShadow1_Float2 =
+ TSymbolUniqueId(4007);
+ static constexpr const TSymbolUniqueId textureGather_Sampler2DShadow1_Float2_Float1 =
+ TSymbolUniqueId(4008);
+ static constexpr const TSymbolUniqueId textureGather_Sampler2DArrayShadow1_Float3 =
+ TSymbolUniqueId(4009);
+ static constexpr const TSymbolUniqueId textureGather_Sampler2DArrayShadow1_Float3_Float1 =
+ TSymbolUniqueId(4010);
+ static constexpr const TSymbolUniqueId textureGather_SamplerCubeShadow1_Float3 =
+ TSymbolUniqueId(4011);
+ static constexpr const TSymbolUniqueId textureGather_SamplerCubeShadow1_Float3_Float1 =
+ TSymbolUniqueId(4012);
+ static constexpr const TSymbolUniqueId textureGatherOffset_Sampler2D1_Float2_Int2 =
+ TSymbolUniqueId(4013);
+ static constexpr const TSymbolUniqueId textureGatherOffset_ISampler2D1_Float2_Int2 =
+ TSymbolUniqueId(4014);
+ static constexpr const TSymbolUniqueId textureGatherOffset_USampler2D1_Float2_Int2 =
+ TSymbolUniqueId(4015);
+ static constexpr const TSymbolUniqueId textureGatherOffset_Sampler2DArray1_Float3_Int2 =
+ TSymbolUniqueId(4016);
+ static constexpr const TSymbolUniqueId textureGatherOffset_ISampler2DArray1_Float3_Int2 =
+ TSymbolUniqueId(4017);
+ static constexpr const TSymbolUniqueId textureGatherOffset_USampler2DArray1_Float3_Int2 =
+ TSymbolUniqueId(4018);
+ static constexpr const TSymbolUniqueId textureGatherOffset_Sampler2DShadow1_Float2_Float1_Int2 =
+ TSymbolUniqueId(4019);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffset_Sampler2DArrayShadow1_Float3_Float1_Int2 = TSymbolUniqueId(4020);
+ static constexpr const TSymbolUniqueId textureGatherOffset_Sampler2D1_Float2_Int2_Int1 =
+ TSymbolUniqueId(4021);
+ static constexpr const TSymbolUniqueId textureGatherOffset_ISampler2D1_Float2_Int2_Int1 =
+ TSymbolUniqueId(4022);
+ static constexpr const TSymbolUniqueId textureGatherOffset_USampler2D1_Float2_Int2_Int1 =
+ TSymbolUniqueId(4023);
+ static constexpr const TSymbolUniqueId textureGatherOffset_Sampler2DArray1_Float3_Int2_Int1 =
+ TSymbolUniqueId(4024);
+ static constexpr const TSymbolUniqueId textureGatherOffset_ISampler2DArray1_Float3_Int2_Int1 =
+ TSymbolUniqueId(4025);
+ static constexpr const TSymbolUniqueId textureGatherOffset_USampler2DArray1_Float3_Int2_Int1 =
+ TSymbolUniqueId(4026);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_Sampler2D1_Float2_4xInt2 =
+ TSymbolUniqueId(4027);
+ static constexpr const TSymbolUniqueId pt10Dx4 = TSymbolUniqueId(4028);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_ISampler2D1_Float2_4xInt2 =
+ TSymbolUniqueId(4029);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_USampler2D1_Float2_4xInt2 =
+ TSymbolUniqueId(4030);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_Sampler2DArray1_Float3_4xInt2 =
+ TSymbolUniqueId(4031);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_ISampler2DArray1_Float3_4xInt2 =
+ TSymbolUniqueId(4032);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_USampler2DArray1_Float3_4xInt2 =
+ TSymbolUniqueId(4033);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffsets_Sampler2DShadow1_Float2_Float1_4xInt2 = TSymbolUniqueId(4034);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffsets_Sampler2DArrayShadow1_Float3_Float1_4xInt2 = TSymbolUniqueId(4035);
+ static constexpr const TSymbolUniqueId textureGatherOffsetsExt_Sampler2D1_Float2_4xInt2 =
+ TSymbolUniqueId(4036);
+ static constexpr const TSymbolUniqueId textureGatherOffsetsExt_ISampler2D1_Float2_4xInt2 =
+ TSymbolUniqueId(4037);
+ static constexpr const TSymbolUniqueId textureGatherOffsetsExt_USampler2D1_Float2_4xInt2 =
+ TSymbolUniqueId(4038);
+ static constexpr const TSymbolUniqueId textureGatherOffsetsExt_Sampler2DArray1_Float3_4xInt2 =
+ TSymbolUniqueId(4039);
+ static constexpr const TSymbolUniqueId textureGatherOffsetsExt_ISampler2DArray1_Float3_4xInt2 =
+ TSymbolUniqueId(4040);
+ static constexpr const TSymbolUniqueId textureGatherOffsetsExt_USampler2DArray1_Float3_4xInt2 =
+ TSymbolUniqueId(4041);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffsetsExt_Sampler2DShadow1_Float2_Float1_4xInt2 = TSymbolUniqueId(4042);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffsetsExt_Sampler2DArrayShadow1_Float3_Float1_4xInt2 = TSymbolUniqueId(4043);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_Sampler2D1_Float2_4xInt2_Int1 =
+ TSymbolUniqueId(4044);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_ISampler2D1_Float2_4xInt2_Int1 =
+ TSymbolUniqueId(4045);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_USampler2D1_Float2_4xInt2_Int1 =
+ TSymbolUniqueId(4046);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_Sampler2DArray1_Float3_4xInt2_Int1 =
+ TSymbolUniqueId(4047);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffsets_ISampler2DArray1_Float3_4xInt2_Int1 = TSymbolUniqueId(4048);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffsets_USampler2DArray1_Float3_4xInt2_Int1 = TSymbolUniqueId(4049);
+ static constexpr const TSymbolUniqueId textureGatherOffsetsExt_Sampler2D1_Float2_4xInt2_Int1 =
+ TSymbolUniqueId(4050);
+ static constexpr const TSymbolUniqueId textureGatherOffsetsExt_ISampler2D1_Float2_4xInt2_Int1 =
+ TSymbolUniqueId(4051);
+ static constexpr const TSymbolUniqueId textureGatherOffsetsExt_USampler2D1_Float2_4xInt2_Int1 =
+ TSymbolUniqueId(4052);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffsetsExt_Sampler2DArray1_Float3_4xInt2_Int1 = TSymbolUniqueId(4053);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffsetsExt_ISampler2DArray1_Float3_4xInt2_Int1 = TSymbolUniqueId(4054);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffsetsExt_USampler2DArray1_Float3_4xInt2_Int1 = TSymbolUniqueId(4055);
+ static constexpr const TSymbolUniqueId rgb_2_yuv_Float3_YuvCscStandardEXT1 =
+ TSymbolUniqueId(4056);
+ static constexpr const TSymbolUniqueId pt00H = TSymbolUniqueId(4057);
+ static constexpr const TSymbolUniqueId yuv_2_rgb_Float3_YuvCscStandardEXT1 =
+ TSymbolUniqueId(4058);
+ static constexpr const TSymbolUniqueId dFdxExt_Float1 = TSymbolUniqueId(4059);
+ static constexpr const TSymbolUniqueId dFdxExt_Float2 = TSymbolUniqueId(4060);
+ static constexpr const TSymbolUniqueId dFdxExt_Float3 = TSymbolUniqueId(4061);
+ static constexpr const TSymbolUniqueId dFdxExt_Float4 = TSymbolUniqueId(4062);
+ static constexpr const TSymbolUniqueId dFdyExt_Float1 = TSymbolUniqueId(4063);
+ static constexpr const TSymbolUniqueId dFdyExt_Float2 = TSymbolUniqueId(4064);
+ static constexpr const TSymbolUniqueId dFdyExt_Float3 = TSymbolUniqueId(4065);
+ static constexpr const TSymbolUniqueId dFdyExt_Float4 = TSymbolUniqueId(4066);
+ static constexpr const TSymbolUniqueId fwidthExt_Float1 = TSymbolUniqueId(4067);
+ static constexpr const TSymbolUniqueId fwidthExt_Float2 = TSymbolUniqueId(4068);
+ static constexpr const TSymbolUniqueId fwidthExt_Float3 = TSymbolUniqueId(4069);
+ static constexpr const TSymbolUniqueId fwidthExt_Float4 = TSymbolUniqueId(4070);
+ static constexpr const TSymbolUniqueId dFdx_Float1 = TSymbolUniqueId(4071);
+ static constexpr const TSymbolUniqueId dFdx_Float2 = TSymbolUniqueId(4072);
+ static constexpr const TSymbolUniqueId dFdx_Float3 = TSymbolUniqueId(4073);
+ static constexpr const TSymbolUniqueId dFdx_Float4 = TSymbolUniqueId(4074);
+ static constexpr const TSymbolUniqueId dFdy_Float1 = TSymbolUniqueId(4075);
+ static constexpr const TSymbolUniqueId dFdy_Float2 = TSymbolUniqueId(4076);
+ static constexpr const TSymbolUniqueId dFdy_Float3 = TSymbolUniqueId(4077);
+ static constexpr const TSymbolUniqueId dFdy_Float4 = TSymbolUniqueId(4078);
+ static constexpr const TSymbolUniqueId fwidth_Float1 = TSymbolUniqueId(4079);
+ static constexpr const TSymbolUniqueId fwidth_Float2 = TSymbolUniqueId(4080);
+ static constexpr const TSymbolUniqueId fwidth_Float3 = TSymbolUniqueId(4081);
+ static constexpr const TSymbolUniqueId fwidth_Float4 = TSymbolUniqueId(4082);
+ static constexpr const TSymbolUniqueId interpolateAtCentroid_Float1 = TSymbolUniqueId(4083);
+ static constexpr const TSymbolUniqueId interpolateAtCentroid_Float2 = TSymbolUniqueId(4084);
+ static constexpr const TSymbolUniqueId interpolateAtCentroid_Float3 = TSymbolUniqueId(4085);
+ static constexpr const TSymbolUniqueId interpolateAtCentroid_Float4 = TSymbolUniqueId(4086);
+ static constexpr const TSymbolUniqueId interpolateAtSample_Float1_Int1 = TSymbolUniqueId(4087);
+ static constexpr const TSymbolUniqueId interpolateAtSample_Float2_Int1 = TSymbolUniqueId(4088);
+ static constexpr const TSymbolUniqueId interpolateAtSample_Float3_Int1 = TSymbolUniqueId(4089);
+ static constexpr const TSymbolUniqueId interpolateAtSample_Float4_Int1 = TSymbolUniqueId(4090);
+ static constexpr const TSymbolUniqueId interpolateAtOffset_Float1_Float2 =
+ TSymbolUniqueId(4091);
+ static constexpr const TSymbolUniqueId interpolateAtOffset_Float2_Float2 =
+ TSymbolUniqueId(4092);
+ static constexpr const TSymbolUniqueId interpolateAtOffset_Float3_Float2 =
+ TSymbolUniqueId(4093);
+ static constexpr const TSymbolUniqueId interpolateAtOffset_Float4_Float2 =
+ TSymbolUniqueId(4094);
+ static constexpr const TSymbolUniqueId interpolateAtCentroidExt_Float1 = TSymbolUniqueId(4095);
+ static constexpr const TSymbolUniqueId interpolateAtCentroidExt_Float2 = TSymbolUniqueId(4096);
+ static constexpr const TSymbolUniqueId interpolateAtCentroidExt_Float3 = TSymbolUniqueId(4097);
+ static constexpr const TSymbolUniqueId interpolateAtCentroidExt_Float4 = TSymbolUniqueId(4098);
+ static constexpr const TSymbolUniqueId interpolateAtSampleExt_Float1_Int1 =
+ TSymbolUniqueId(4099);
+ static constexpr const TSymbolUniqueId interpolateAtSampleExt_Float2_Int1 =
+ TSymbolUniqueId(4100);
+ static constexpr const TSymbolUniqueId interpolateAtSampleExt_Float3_Int1 =
+ TSymbolUniqueId(4101);
+ static constexpr const TSymbolUniqueId interpolateAtSampleExt_Float4_Int1 =
+ TSymbolUniqueId(4102);
+ static constexpr const TSymbolUniqueId interpolateAtOffsetExt_Float1_Float2 =
+ TSymbolUniqueId(4103);
+ static constexpr const TSymbolUniqueId interpolateAtOffsetExt_Float2_Float2 =
+ TSymbolUniqueId(4104);
+ static constexpr const TSymbolUniqueId interpolateAtOffsetExt_Float3_Float2 =
+ TSymbolUniqueId(4105);
+ static constexpr const TSymbolUniqueId interpolateAtOffsetExt_Float4_Float2 =
+ TSymbolUniqueId(4106);
+ static constexpr const TSymbolUniqueId atomicCounter_AtomicCounter1 = TSymbolUniqueId(4107);
+ static constexpr const TSymbolUniqueId pt00G = TSymbolUniqueId(4108);
+ static constexpr const TSymbolUniqueId atomicCounterIncrement_AtomicCounter1 =
+ TSymbolUniqueId(4109);
+ static constexpr const TSymbolUniqueId atomicCounterDecrement_AtomicCounter1 =
+ TSymbolUniqueId(4110);
+ static constexpr const TSymbolUniqueId atomicAdd_UInt1_UInt1 = TSymbolUniqueId(4111);
+ static constexpr const TSymbolUniqueId pt_io_00E = TSymbolUniqueId(4112);
+ static constexpr const TSymbolUniqueId atomicAdd_Int1_Int1 = TSymbolUniqueId(4113);
+ static constexpr const TSymbolUniqueId pt_io_00D = TSymbolUniqueId(4114);
+ static constexpr const TSymbolUniqueId atomicMin_UInt1_UInt1 = TSymbolUniqueId(4115);
+ static constexpr const TSymbolUniqueId atomicMin_Int1_Int1 = TSymbolUniqueId(4116);
+ static constexpr const TSymbolUniqueId atomicMax_UInt1_UInt1 = TSymbolUniqueId(4117);
+ static constexpr const TSymbolUniqueId atomicMax_Int1_Int1 = TSymbolUniqueId(4118);
+ static constexpr const TSymbolUniqueId atomicAnd_UInt1_UInt1 = TSymbolUniqueId(4119);
+ static constexpr const TSymbolUniqueId atomicAnd_Int1_Int1 = TSymbolUniqueId(4120);
+ static constexpr const TSymbolUniqueId atomicOr_UInt1_UInt1 = TSymbolUniqueId(4121);
+ static constexpr const TSymbolUniqueId atomicOr_Int1_Int1 = TSymbolUniqueId(4122);
+ static constexpr const TSymbolUniqueId atomicXor_UInt1_UInt1 = TSymbolUniqueId(4123);
+ static constexpr const TSymbolUniqueId atomicXor_Int1_Int1 = TSymbolUniqueId(4124);
+ static constexpr const TSymbolUniqueId atomicExchange_UInt1_UInt1 = TSymbolUniqueId(4125);
+ static constexpr const TSymbolUniqueId atomicExchange_Int1_Int1 = TSymbolUniqueId(4126);
+ static constexpr const TSymbolUniqueId atomicCompSwap_UInt1_UInt1_UInt1 = TSymbolUniqueId(4127);
+ static constexpr const TSymbolUniqueId atomicCompSwap_Int1_Int1_Int1 = TSymbolUniqueId(4128);
+ static constexpr const TSymbolUniqueId imageSize_Image2D1 = TSymbolUniqueId(4129);
+ static constexpr const TSymbolUniqueId pt00z = TSymbolUniqueId(4130);
+ static constexpr const TSymbolUniqueId imageSize_IImage2D1 = TSymbolUniqueId(4131);
+ static constexpr const TSymbolUniqueId pt01K = TSymbolUniqueId(4132);
+ static constexpr const TSymbolUniqueId imageSize_UImage2D1 = TSymbolUniqueId(4133);
+ static constexpr const TSymbolUniqueId pt01V = TSymbolUniqueId(4134);
+ static constexpr const TSymbolUniqueId imageSize_Image3D1 = TSymbolUniqueId(4135);
+ static constexpr const TSymbolUniqueId pt01A = TSymbolUniqueId(4136);
+ static constexpr const TSymbolUniqueId imageSize_IImage3D1 = TSymbolUniqueId(4137);
+ static constexpr const TSymbolUniqueId pt01L = TSymbolUniqueId(4138);
+ static constexpr const TSymbolUniqueId imageSize_UImage3D1 = TSymbolUniqueId(4139);
+ static constexpr const TSymbolUniqueId pt01W = TSymbolUniqueId(4140);
+ static constexpr const TSymbolUniqueId imageSize_Image2DArray1 = TSymbolUniqueId(4141);
+ static constexpr const TSymbolUniqueId pt01B = TSymbolUniqueId(4142);
+ static constexpr const TSymbolUniqueId imageSize_IImage2DArray1 = TSymbolUniqueId(4143);
+ static constexpr const TSymbolUniqueId pt01M = TSymbolUniqueId(4144);
+ static constexpr const TSymbolUniqueId imageSize_UImage2DArray1 = TSymbolUniqueId(4145);
+ static constexpr const TSymbolUniqueId pt01X = TSymbolUniqueId(4146);
+ static constexpr const TSymbolUniqueId imageSize_ImageCube1 = TSymbolUniqueId(4147);
+ static constexpr const TSymbolUniqueId pt01C = TSymbolUniqueId(4148);
+ static constexpr const TSymbolUniqueId imageSize_IImageCube1 = TSymbolUniqueId(4149);
+ static constexpr const TSymbolUniqueId pt01N = TSymbolUniqueId(4150);
+ static constexpr const TSymbolUniqueId imageSize_UImageCube1 = TSymbolUniqueId(4151);
+ static constexpr const TSymbolUniqueId pt01Y = TSymbolUniqueId(4152);
+ static constexpr const TSymbolUniqueId imageSize_ImageCubeArray1 = TSymbolUniqueId(4153);
+ static constexpr const TSymbolUniqueId pt01H = TSymbolUniqueId(4154);
+ static constexpr const TSymbolUniqueId imageSize_IImageCubeArray1 = TSymbolUniqueId(4155);
+ static constexpr const TSymbolUniqueId pt01S = TSymbolUniqueId(4156);
+ static constexpr const TSymbolUniqueId imageSize_UImageCubeArray1 = TSymbolUniqueId(4157);
+ static constexpr const TSymbolUniqueId pt01d = TSymbolUniqueId(4158);
+ static constexpr const TSymbolUniqueId imageSizeExt_ImageCubeArray1 = TSymbolUniqueId(4159);
+ static constexpr const TSymbolUniqueId imageSizeExt_IImageCubeArray1 = TSymbolUniqueId(4160);
+ static constexpr const TSymbolUniqueId imageSizeExt_UImageCubeArray1 = TSymbolUniqueId(4161);
+ static constexpr const TSymbolUniqueId imageSize_ImageBuffer1 = TSymbolUniqueId(4162);
+ static constexpr const TSymbolUniqueId pt01J = TSymbolUniqueId(4163);
+ static constexpr const TSymbolUniqueId imageSize_IImageBuffer1 = TSymbolUniqueId(4164);
+ static constexpr const TSymbolUniqueId pt01U = TSymbolUniqueId(4165);
+ static constexpr const TSymbolUniqueId imageSize_UImageBuffer1 = TSymbolUniqueId(4166);
+ static constexpr const TSymbolUniqueId pt01f = TSymbolUniqueId(4167);
+ static constexpr const TSymbolUniqueId imageSizeExt_ImageBuffer1 = TSymbolUniqueId(4168);
+ static constexpr const TSymbolUniqueId imageSizeExt_IImageBuffer1 = TSymbolUniqueId(4169);
+ static constexpr const TSymbolUniqueId imageSizeExt_UImageBuffer1 = TSymbolUniqueId(4170);
+ static constexpr const TSymbolUniqueId imageStore_Image2D1_Int2_Float4 = TSymbolUniqueId(4171);
+ static constexpr const TSymbolUniqueId imageStore_IImage2D1_Int2_Int4 = TSymbolUniqueId(4172);
+ static constexpr const TSymbolUniqueId imageStore_UImage2D1_Int2_UInt4 = TSymbolUniqueId(4173);
+ static constexpr const TSymbolUniqueId imageStore_Image3D1_Int3_Float4 = TSymbolUniqueId(4174);
+ static constexpr const TSymbolUniqueId imageStore_IImage3D1_Int3_Int4 = TSymbolUniqueId(4175);
+ static constexpr const TSymbolUniqueId imageStore_UImage3D1_Int3_UInt4 = TSymbolUniqueId(4176);
+ static constexpr const TSymbolUniqueId imageStore_Image2DArray1_Int3_Float4 =
+ TSymbolUniqueId(4177);
+ static constexpr const TSymbolUniqueId imageStore_IImage2DArray1_Int3_Int4 =
+ TSymbolUniqueId(4178);
+ static constexpr const TSymbolUniqueId imageStore_UImage2DArray1_Int3_UInt4 =
+ TSymbolUniqueId(4179);
+ static constexpr const TSymbolUniqueId imageStore_ImageCube1_Int3_Float4 =
+ TSymbolUniqueId(4180);
+ static constexpr const TSymbolUniqueId imageStore_IImageCube1_Int3_Int4 = TSymbolUniqueId(4181);
+ static constexpr const TSymbolUniqueId imageStore_UImageCube1_Int3_UInt4 =
+ TSymbolUniqueId(4182);
+ static constexpr const TSymbolUniqueId imageStore_ImageCubeArray1_Int3_Float4 =
+ TSymbolUniqueId(4183);
+ static constexpr const TSymbolUniqueId imageStore_IImageCubeArray1_Int3_Int4 =
+ TSymbolUniqueId(4184);
+ static constexpr const TSymbolUniqueId imageStore_UImageCubeArray1_Int3_UInt4 =
+ TSymbolUniqueId(4185);
+ static constexpr const TSymbolUniqueId imageStoreExt_ImageCubeArray1_Int3_Float4 =
+ TSymbolUniqueId(4186);
+ static constexpr const TSymbolUniqueId imageStoreExt_IImageCubeArray1_Int3_Int4 =
+ TSymbolUniqueId(4187);
+ static constexpr const TSymbolUniqueId imageStoreExt_UImageCubeArray1_Int3_UInt4 =
+ TSymbolUniqueId(4188);
+ static constexpr const TSymbolUniqueId imageStore_ImageBuffer1_Int1_Float4 =
+ TSymbolUniqueId(4189);
+ static constexpr const TSymbolUniqueId imageStore_IImageBuffer1_Int1_Int4 =
+ TSymbolUniqueId(4190);
+ static constexpr const TSymbolUniqueId imageStore_UImageBuffer1_Int1_UInt4 =
+ TSymbolUniqueId(4191);
+ static constexpr const TSymbolUniqueId imageStoreExt_ImageBuffer1_Int1_Float4 =
+ TSymbolUniqueId(4192);
+ static constexpr const TSymbolUniqueId imageStoreExt_IImageBuffer1_Int1_Int4 =
+ TSymbolUniqueId(4193);
+ static constexpr const TSymbolUniqueId imageStoreExt_UImageBuffer1_Int1_UInt4 =
+ TSymbolUniqueId(4194);
+ static constexpr const TSymbolUniqueId imageLoad_Image2D1_Int2 = TSymbolUniqueId(4195);
+ static constexpr const TSymbolUniqueId imageLoad_IImage2D1_Int2 = TSymbolUniqueId(4196);
+ static constexpr const TSymbolUniqueId imageLoad_UImage2D1_Int2 = TSymbolUniqueId(4197);
+ static constexpr const TSymbolUniqueId imageLoad_Image3D1_Int3 = TSymbolUniqueId(4198);
+ static constexpr const TSymbolUniqueId imageLoad_IImage3D1_Int3 = TSymbolUniqueId(4199);
+ static constexpr const TSymbolUniqueId imageLoad_UImage3D1_Int3 = TSymbolUniqueId(4200);
+ static constexpr const TSymbolUniqueId imageLoad_Image2DArray1_Int3 = TSymbolUniqueId(4201);
+ static constexpr const TSymbolUniqueId imageLoad_IImage2DArray1_Int3 = TSymbolUniqueId(4202);
+ static constexpr const TSymbolUniqueId imageLoad_UImage2DArray1_Int3 = TSymbolUniqueId(4203);
+ static constexpr const TSymbolUniqueId imageLoad_ImageCube1_Int3 = TSymbolUniqueId(4204);
+ static constexpr const TSymbolUniqueId imageLoad_IImageCube1_Int3 = TSymbolUniqueId(4205);
+ static constexpr const TSymbolUniqueId imageLoad_UImageCube1_Int3 = TSymbolUniqueId(4206);
+ static constexpr const TSymbolUniqueId imageLoad_ImageCubeArray1_Int3 = TSymbolUniqueId(4207);
+ static constexpr const TSymbolUniqueId imageLoad_IImageCubeArray1_Int3 = TSymbolUniqueId(4208);
+ static constexpr const TSymbolUniqueId imageLoad_UImageCubeArray1_Int3 = TSymbolUniqueId(4209);
+ static constexpr const TSymbolUniqueId imageLoadExt_ImageCubeArray1_Int3 =
+ TSymbolUniqueId(4210);
+ static constexpr const TSymbolUniqueId imageLoadExt_IImageCubeArray1_Int3 =
+ TSymbolUniqueId(4211);
+ static constexpr const TSymbolUniqueId imageLoadExt_UImageCubeArray1_Int3 =
+ TSymbolUniqueId(4212);
+ static constexpr const TSymbolUniqueId imageLoad_ImageBuffer1_Int1 = TSymbolUniqueId(4213);
+ static constexpr const TSymbolUniqueId imageLoad_IImageBuffer1_Int1 = TSymbolUniqueId(4214);
+ static constexpr const TSymbolUniqueId imageLoad_UImageBuffer1_Int1 = TSymbolUniqueId(4215);
+ static constexpr const TSymbolUniqueId imageLoadExt_ImageBuffer1_Int1 = TSymbolUniqueId(4216);
+ static constexpr const TSymbolUniqueId imageLoadExt_IImageBuffer1_Int1 = TSymbolUniqueId(4217);
+ static constexpr const TSymbolUniqueId imageLoadExt_UImageBuffer1_Int1 = TSymbolUniqueId(4218);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(4219);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4220);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4221);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(4222);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4223);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4224);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4225);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4226);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4227);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4228);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4229);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4230);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4231);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4232);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4233);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4234);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4235);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4236);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(4237);
+ static constexpr const TSymbolUniqueId pt01D = TSymbolUniqueId(4238);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(4239);
+ static constexpr const TSymbolUniqueId pt01O = TSymbolUniqueId(4240);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(4241);
+ static constexpr const TSymbolUniqueId pt01Z = TSymbolUniqueId(4242);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4243);
+ static constexpr const TSymbolUniqueId pt01E = TSymbolUniqueId(4244);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4245);
+ static constexpr const TSymbolUniqueId pt01P = TSymbolUniqueId(4246);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4247);
+ static constexpr const TSymbolUniqueId pt01a = TSymbolUniqueId(4248);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4249);
+ static constexpr const TSymbolUniqueId pt01I = TSymbolUniqueId(4250);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4251);
+ static constexpr const TSymbolUniqueId pt01T = TSymbolUniqueId(4252);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4253);
+ static constexpr const TSymbolUniqueId pt01e = TSymbolUniqueId(4254);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4255);
+ static constexpr const TSymbolUniqueId pt01F = TSymbolUniqueId(4256);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4257);
+ static constexpr const TSymbolUniqueId pt01Q = TSymbolUniqueId(4258);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4259);
+ static constexpr const TSymbolUniqueId pt01b = TSymbolUniqueId(4260);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4261);
+ static constexpr const TSymbolUniqueId pt01G = TSymbolUniqueId(4262);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4263);
+ static constexpr const TSymbolUniqueId pt01R = TSymbolUniqueId(4264);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4265);
+ static constexpr const TSymbolUniqueId pt01c = TSymbolUniqueId(4266);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(4267);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(4268);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(4269);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(4270);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(4271);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(4272);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4273);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4274);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4275);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4276);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4277);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4278);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4279);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4280);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4281);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4282);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4283);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4284);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(4285);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(4286);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(4287);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4288);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4289);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4290);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4291);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4292);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4293);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4294);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4295);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4296);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4297);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4298);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4299);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(4300);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4301);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4302);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(4303);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4304);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4305);
+ static constexpr const TSymbolUniqueId imageAtomicMin_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4306);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4307);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4308);
+ static constexpr const TSymbolUniqueId imageAtomicMin_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4309);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4310);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4311);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4312);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4313);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4314);
+ static constexpr const TSymbolUniqueId imageAtomicMin_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4315);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4316);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4317);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(4318);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(4319);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(4320);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4321);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4322);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4323);
+ static constexpr const TSymbolUniqueId imageAtomicMin_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4324);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4325);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4326);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4327);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4328);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4329);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4330);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4331);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4332);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(4333);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(4334);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(4335);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(4336);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(4337);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(4338);
+ static constexpr const TSymbolUniqueId imageAtomicMin_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4339);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4340);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4341);
+ static constexpr const TSymbolUniqueId imageAtomicMin_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4342);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4343);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4344);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4345);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4346);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4347);
+ static constexpr const TSymbolUniqueId imageAtomicMin_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4348);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4349);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4350);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(4351);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(4352);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(4353);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4354);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4355);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4356);
+ static constexpr const TSymbolUniqueId imageAtomicMin_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4357);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4358);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4359);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4360);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4361);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4362);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4363);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4364);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4365);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(4366);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4367);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4368);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(4369);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4370);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4371);
+ static constexpr const TSymbolUniqueId imageAtomicMax_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4372);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4373);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4374);
+ static constexpr const TSymbolUniqueId imageAtomicMax_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4375);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4376);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4377);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4378);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4379);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4380);
+ static constexpr const TSymbolUniqueId imageAtomicMax_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4381);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4382);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4383);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(4384);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(4385);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(4386);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4387);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4388);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4389);
+ static constexpr const TSymbolUniqueId imageAtomicMax_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4390);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4391);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4392);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4393);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4394);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4395);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4396);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4397);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4398);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(4399);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(4400);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(4401);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(4402);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(4403);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(4404);
+ static constexpr const TSymbolUniqueId imageAtomicMax_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4405);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4406);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4407);
+ static constexpr const TSymbolUniqueId imageAtomicMax_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4408);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4409);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4410);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4411);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4412);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4413);
+ static constexpr const TSymbolUniqueId imageAtomicMax_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4414);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4415);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4416);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(4417);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(4418);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(4419);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4420);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4421);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4422);
+ static constexpr const TSymbolUniqueId imageAtomicMax_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4423);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4424);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4425);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4426);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4427);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4428);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4429);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4430);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4431);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(4432);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4433);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4434);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(4435);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4436);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4437);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4438);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4439);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4440);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4441);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4442);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4443);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4444);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4445);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4446);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4447);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4448);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4449);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(4450);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(4451);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(4452);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4453);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4454);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4455);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4456);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4457);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4458);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4459);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4460);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4461);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4462);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4463);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4464);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(4465);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(4466);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(4467);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(4468);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(4469);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(4470);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4471);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4472);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4473);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4474);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4475);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4476);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4477);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4478);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4479);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4480);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4481);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4482);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(4483);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(4484);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(4485);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4486);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4487);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4488);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4489);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4490);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4491);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4492);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4493);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4494);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4495);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4496);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4497);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(4498);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4499);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4500);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(4501);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4502);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4503);
+ static constexpr const TSymbolUniqueId imageAtomicOr_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4504);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4505);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4506);
+ static constexpr const TSymbolUniqueId imageAtomicOr_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4507);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4508);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4509);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4510);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4511);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4512);
+ static constexpr const TSymbolUniqueId imageAtomicOr_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4513);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4514);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4515);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(4516);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(4517);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(4518);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4519);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4520);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4521);
+ static constexpr const TSymbolUniqueId imageAtomicOr_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4522);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4523);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4524);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4525);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4526);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4527);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4528);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4529);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4530);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image2D1_Int2_Int1 = TSymbolUniqueId(4531);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(4532);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(4533);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image3D1_Int3_Int1 = TSymbolUniqueId(4534);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(4535);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(4536);
+ static constexpr const TSymbolUniqueId imageAtomicOr_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4537);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4538);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4539);
+ static constexpr const TSymbolUniqueId imageAtomicOr_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4540);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4541);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4542);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4543);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4544);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4545);
+ static constexpr const TSymbolUniqueId imageAtomicOr_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4546);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4547);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4548);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image1D1_Int1_Int1 = TSymbolUniqueId(4549);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(4550);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(4551);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4552);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4553);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4554);
+ static constexpr const TSymbolUniqueId imageAtomicOr_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4555);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4556);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4557);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4558);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4559);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4560);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4561);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4562);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4563);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(4564);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4565);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4566);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(4567);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4568);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4569);
+ static constexpr const TSymbolUniqueId imageAtomicXor_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4570);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4571);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4572);
+ static constexpr const TSymbolUniqueId imageAtomicXor_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4573);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4574);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4575);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4576);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4577);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4578);
+ static constexpr const TSymbolUniqueId imageAtomicXor_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4579);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4580);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4581);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(4582);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(4583);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(4584);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4585);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4586);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4587);
+ static constexpr const TSymbolUniqueId imageAtomicXor_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4588);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4589);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4590);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4591);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4592);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4593);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4594);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4595);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4596);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(4597);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(4598);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(4599);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(4600);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(4601);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(4602);
+ static constexpr const TSymbolUniqueId imageAtomicXor_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4603);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4604);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4605);
+ static constexpr const TSymbolUniqueId imageAtomicXor_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4606);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4607);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4608);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4609);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4610);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4611);
+ static constexpr const TSymbolUniqueId imageAtomicXor_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4612);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4613);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4614);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(4615);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(4616);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(4617);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4618);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4619);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4620);
+ static constexpr const TSymbolUniqueId imageAtomicXor_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4621);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4622);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4623);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4624);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4625);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4626);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4627);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4628);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4629);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(4630);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4631);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4632);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(4633);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4634);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4635);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4636);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4637);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4638);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4639);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4640);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4641);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4642);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4643);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4644);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4645);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4646);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4647);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(4648);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(4649);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(4650);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4651);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4652);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4653);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4654);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4655);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4656);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4657);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4658);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4659);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4660);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4661);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4662);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(4663);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(4664);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(4665);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(4666);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(4667);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(4668);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4669);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4670);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4671);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4672);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4673);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4674);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4675);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4676);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4677);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4678);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4679);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4680);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(4681);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(4682);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(4683);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4684);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4685);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4686);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4687);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4688);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4689);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4690);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4691);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4692);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4693);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4694);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4695);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2D1_Int2_Float1 =
+ TSymbolUniqueId(4696);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2D1_Int2_Float1 =
+ TSymbolUniqueId(4697);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2D1_Int2_Float1 =
+ TSymbolUniqueId(4698);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image3D1_Int3_Float1 =
+ TSymbolUniqueId(4699);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage3D1_Int3_Float1 =
+ TSymbolUniqueId(4700);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage3D1_Int3_Float1 =
+ TSymbolUniqueId(4701);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageCube1_Int3_Float1 =
+ TSymbolUniqueId(4702);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageCube1_Int3_Float1 =
+ TSymbolUniqueId(4703);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageCube1_Int3_Float1 =
+ TSymbolUniqueId(4704);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageBuffer1_Int1_Float1 =
+ TSymbolUniqueId(4705);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageBuffer1_Int1_Float1 =
+ TSymbolUniqueId(4706);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageBuffer1_Int1_Float1 =
+ TSymbolUniqueId(4707);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2DArray1_Int3_Float1 =
+ TSymbolUniqueId(4708);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2DArray1_Int3_Float1 =
+ TSymbolUniqueId(4709);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2DArray1_Int3_Float1 =
+ TSymbolUniqueId(4710);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageCubeArray1_Int3_Float1 =
+ TSymbolUniqueId(4711);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageCubeArray1_Int3_Float1 =
+ TSymbolUniqueId(4712);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageCubeArray1_Int3_Float1 =
+ TSymbolUniqueId(4713);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image1D1_Int1_Float1 =
+ TSymbolUniqueId(4714);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage1D1_Int1_Float1 =
+ TSymbolUniqueId(4715);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage1D1_Int1_Float1 =
+ TSymbolUniqueId(4716);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image1DArray1_Int2_Float1 =
+ TSymbolUniqueId(4717);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage1DArray1_Int2_Float1 =
+ TSymbolUniqueId(4718);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage1DArray1_Int2_Float1 =
+ TSymbolUniqueId(4719);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageRect1_Int2_Float1 =
+ TSymbolUniqueId(4720);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageRect1_Int2_Float1 =
+ TSymbolUniqueId(4721);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageRect1_Int2_Float1 =
+ TSymbolUniqueId(4722);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2DMS1_Int2_Int1_Float1 =
+ TSymbolUniqueId(4723);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2DMS1_Int2_Int1_Float1 =
+ TSymbolUniqueId(4724);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2DMS1_Int2_Int1_Float1 =
+ TSymbolUniqueId(4725);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2DMSArray1_Int3_Int1_Float1 =
+ TSymbolUniqueId(4726);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2DMSArray1_Int3_Int1_Float1 =
+ TSymbolUniqueId(4727);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2DMSArray1_Int3_Int1_Float1 =
+ TSymbolUniqueId(4728);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image2D1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(4729);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage2D1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(4730);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage2D1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(4731);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image3D1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(4732);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage3D1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(4733);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage3D1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(4734);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_ImageCube1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(4735);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImageCube1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(4736);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImageCube1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(4737);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_ImageBuffer1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(4738);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImageBuffer1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(4739);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImageBuffer1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(4740);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image2DArray1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(4741);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage2DArray1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(4742);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage2DArray1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(4743);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_ImageCubeArray1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(4744);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImageCubeArray1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(4745);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImageCubeArray1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(4746);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image1D1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(4747);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage1D1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(4748);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage1D1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(4749);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image1DArray1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(4750);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage1DArray1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(4751);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage1DArray1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(4752);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_ImageRect1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(4753);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImageRect1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(4754);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImageRect1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(4755);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image2DMS1_Int2_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(4756);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage2DMS1_Int2_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(4757);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage2DMS1_Int2_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(4758);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwap_Image2DMSArray1_Int3_Int1_UInt1_UInt1 = TSymbolUniqueId(4759);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwap_IImage2DMSArray1_Int3_Int1_UInt1_UInt1 = TSymbolUniqueId(4760);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwap_UImage2DMSArray1_Int3_Int1_UInt1_UInt1 = TSymbolUniqueId(4761);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image2D1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4762);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage2D1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4763);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage2D1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4764);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image3D1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4765);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage3D1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4766);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage3D1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4767);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_ImageCube1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4768);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImageCube1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4769);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImageCube1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4770);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_ImageBuffer1_Int1_Int1_Int1 =
+ TSymbolUniqueId(4771);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImageBuffer1_Int1_Int1_Int1 =
+ TSymbolUniqueId(4772);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImageBuffer1_Int1_Int1_Int1 =
+ TSymbolUniqueId(4773);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image2DArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4774);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage2DArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4775);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage2DArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4776);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_ImageCubeArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4777);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImageCubeArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4778);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImageCubeArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4779);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image1D1_Int1_Int1_Int1 =
+ TSymbolUniqueId(4780);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage1D1_Int1_Int1_Int1 =
+ TSymbolUniqueId(4781);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage1D1_Int1_Int1_Int1 =
+ TSymbolUniqueId(4782);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image1DArray1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4783);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage1DArray1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4784);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage1DArray1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4785);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_ImageRect1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4786);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImageRect1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4787);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImageRect1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4788);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image2DMS1_Int2_Int1_Int1_Int1 =
+ TSymbolUniqueId(4789);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage2DMS1_Int2_Int1_Int1_Int1 =
+ TSymbolUniqueId(4790);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage2DMS1_Int2_Int1_Int1_Int1 =
+ TSymbolUniqueId(4791);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image2DMSArray1_Int3_Int1_Int1_Int1 =
+ TSymbolUniqueId(4792);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwap_IImage2DMSArray1_Int3_Int1_Int1_Int1 = TSymbolUniqueId(4793);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwap_UImage2DMSArray1_Int3_Int1_Int1_Int1 = TSymbolUniqueId(4794);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(4795);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4796);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4797);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(4798);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4799);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4800);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4801);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4802);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4803);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4804);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4805);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4806);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4807);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4808);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4809);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4810);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4811);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4812);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(4813);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(4814);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(4815);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4816);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4817);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4818);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4819);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4820);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4821);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4822);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4823);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4824);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4825);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4826);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4827);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(4828);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(4829);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(4830);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(4831);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(4832);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(4833);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4834);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4835);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4836);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4837);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4838);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4839);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4840);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4841);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4842);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4843);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4844);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4845);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(4846);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(4847);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(4848);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4849);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4850);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4851);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4852);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4853);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4854);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4855);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4856);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4857);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4858);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4859);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4860);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(4861);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4862);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4863);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(4864);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4865);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4866);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4867);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4868);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4869);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4870);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4871);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4872);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4873);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4874);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4875);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4876);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4877);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4878);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(4879);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(4880);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(4881);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4882);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4883);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4884);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4885);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4886);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4887);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4888);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4889);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4890);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4891);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4892);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4893);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(4894);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(4895);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(4896);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(4897);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(4898);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(4899);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4900);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4901);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4902);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4903);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4904);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4905);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4906);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4907);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4908);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4909);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4910);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4911);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(4912);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(4913);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(4914);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4915);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4916);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4917);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4918);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4919);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4920);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4921);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4922);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4923);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4924);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4925);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4926);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(4927);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4928);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4929);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(4930);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4931);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4932);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4933);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4934);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4935);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4936);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4937);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(4938);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4939);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4940);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(4941);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4942);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4943);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(4944);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(4945);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(4946);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(4947);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4948);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4949);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(4950);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4951);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4952);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(4953);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4954);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4955);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(4956);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4957);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4958);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(4959);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(4960);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(4961);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(4962);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(4963);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(4964);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(4965);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4966);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4967);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(4968);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4969);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4970);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(4971);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4972);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4973);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(4974);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4975);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4976);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(4977);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(4978);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(4979);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(4980);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4981);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4982);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(4983);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4984);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4985);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(4986);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4987);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4988);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(4989);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4990);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4991);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(4992);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(4993);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4994);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(4995);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(4996);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4997);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(4998);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(4999);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(5000);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(5001);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(5002);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(5003);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(5004);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(5005);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(5006);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(5007);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(5008);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(5009);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(5010);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(5011);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(5012);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(5013);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(5014);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(5015);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(5016);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(5017);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(5018);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(5019);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(5020);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(5021);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(5022);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(5023);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(5024);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(5025);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(5026);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(5027);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(5028);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(5029);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(5030);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(5031);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(5032);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(5033);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(5034);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(5035);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(5036);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(5037);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(5038);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(5039);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(5040);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(5041);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(5042);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(5043);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(5044);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(5045);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(5046);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(5047);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(5048);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(5049);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(5050);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(5051);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(5052);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(5053);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(5054);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(5055);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5056);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5057);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5058);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(5059);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(5060);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(5061);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(5062);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(5063);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(5064);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(5065);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(5066);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(5067);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(5068);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(5069);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(5070);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(5071);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(5072);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(5073);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(5074);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(5075);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(5076);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(5077);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(5078);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(5079);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(5080);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(5081);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(5082);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(5083);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(5084);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(5085);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(5086);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(5087);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(5088);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(5089);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(5090);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(5091);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(5092);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(5093);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(5094);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(5095);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(5096);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(5097);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(5098);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(5099);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(5100);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(5101);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(5102);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(5103);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(5104);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(5105);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(5106);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(5107);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(5108);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(5109);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(5110);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(5111);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(5112);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(5113);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(5114);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(5115);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(5116);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(5117);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(5118);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(5119);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(5120);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(5121);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5122);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5123);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5124);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(5125);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(5126);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(5127);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(5128);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(5129);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(5130);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(5131);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(5132);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(5133);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(5134);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(5135);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(5136);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(5137);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(5138);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(5139);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(5140);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(5141);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(5142);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(5143);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(5144);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(5145);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(5146);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(5147);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(5148);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(5149);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(5150);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(5151);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(5152);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(5153);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(5154);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(5155);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(5156);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(5157);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(5158);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(5159);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(5160);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(5161);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(5162);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(5163);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(5164);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(5165);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(5166);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(5167);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(5168);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(5169);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(5170);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(5171);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(5172);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(5173);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(5174);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(5175);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(5176);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(5177);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(5178);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(5179);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(5180);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(5181);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(5182);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(5183);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(5184);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(5185);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(5186);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(5187);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5188);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5189);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5190);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(5191);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(5192);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(5193);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(5194);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(5195);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(5196);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(5197);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(5198);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(5199);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(5200);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(5201);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(5202);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(5203);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(5204);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(5205);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(5206);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(5207);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(5208);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(5209);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(5210);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(5211);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(5212);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(5213);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(5214);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(5215);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(5216);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(5217);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(5218);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(5219);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(5220);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(5221);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(5222);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(5223);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(5224);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(5225);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(5226);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(5227);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(5228);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(5229);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(5230);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(5231);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(5232);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(5233);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(5234);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(5235);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(5236);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(5237);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(5238);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(5239);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(5240);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(5241);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(5242);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(5243);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(5244);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(5245);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(5246);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(5247);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(5248);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(5249);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(5250);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(5251);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(5252);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(5253);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5254);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5255);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5256);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2D1_Int2_Float1 =
+ TSymbolUniqueId(5257);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2D1_Int2_Float1 =
+ TSymbolUniqueId(5258);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2D1_Int2_Float1 =
+ TSymbolUniqueId(5259);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image3D1_Int3_Float1 =
+ TSymbolUniqueId(5260);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage3D1_Int3_Float1 =
+ TSymbolUniqueId(5261);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage3D1_Int3_Float1 =
+ TSymbolUniqueId(5262);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageCube1_Int3_Float1 =
+ TSymbolUniqueId(5263);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageCube1_Int3_Float1 =
+ TSymbolUniqueId(5264);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageCube1_Int3_Float1 =
+ TSymbolUniqueId(5265);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageBuffer1_Int1_Float1 =
+ TSymbolUniqueId(5266);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageBuffer1_Int1_Float1 =
+ TSymbolUniqueId(5267);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageBuffer1_Int1_Float1 =
+ TSymbolUniqueId(5268);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2DArray1_Int3_Float1 =
+ TSymbolUniqueId(5269);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2DArray1_Int3_Float1 =
+ TSymbolUniqueId(5270);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2DArray1_Int3_Float1 =
+ TSymbolUniqueId(5271);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageCubeArray1_Int3_Float1 =
+ TSymbolUniqueId(5272);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageCubeArray1_Int3_Float1 =
+ TSymbolUniqueId(5273);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageCubeArray1_Int3_Float1 =
+ TSymbolUniqueId(5274);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image1D1_Int1_Float1 =
+ TSymbolUniqueId(5275);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage1D1_Int1_Float1 =
+ TSymbolUniqueId(5276);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage1D1_Int1_Float1 =
+ TSymbolUniqueId(5277);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image1DArray1_Int2_Float1 =
+ TSymbolUniqueId(5278);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage1DArray1_Int2_Float1 =
+ TSymbolUniqueId(5279);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage1DArray1_Int2_Float1 =
+ TSymbolUniqueId(5280);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageRect1_Int2_Float1 =
+ TSymbolUniqueId(5281);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageRect1_Int2_Float1 =
+ TSymbolUniqueId(5282);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageRect1_Int2_Float1 =
+ TSymbolUniqueId(5283);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2DMS1_Int2_Int1_Float1 =
+ TSymbolUniqueId(5284);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2DMS1_Int2_Int1_Float1 =
+ TSymbolUniqueId(5285);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2DMS1_Int2_Int1_Float1 =
+ TSymbolUniqueId(5286);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2DMSArray1_Int3_Int1_Float1 =
+ TSymbolUniqueId(5287);
+ static constexpr const TSymbolUniqueId
+ imageAtomicExchangeExt_IImage2DMSArray1_Int3_Int1_Float1 = TSymbolUniqueId(5288);
+ static constexpr const TSymbolUniqueId
+ imageAtomicExchangeExt_UImage2DMSArray1_Int3_Int1_Float1 = TSymbolUniqueId(5289);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image2D1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(5290);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage2D1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(5291);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage2D1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(5292);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image3D1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(5293);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage3D1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(5294);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage3D1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(5295);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_ImageCube1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(5296);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImageCube1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(5297);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImageCube1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(5298);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_ImageBuffer1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(5299);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImageBuffer1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(5300);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImageBuffer1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(5301);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image2DArray1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(5302);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage2DArray1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(5303);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage2DArray1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(5304);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_ImageCubeArray1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(5305);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwapExt_IImageCubeArray1_Int3_UInt1_UInt1 = TSymbolUniqueId(5306);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwapExt_UImageCubeArray1_Int3_UInt1_UInt1 = TSymbolUniqueId(5307);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image1D1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(5308);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage1D1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(5309);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage1D1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(5310);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image1DArray1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(5311);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage1DArray1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(5312);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage1DArray1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(5313);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_ImageRect1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(5314);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImageRect1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(5315);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImageRect1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(5316);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image2DMS1_Int2_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(5317);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwapExt_IImage2DMS1_Int2_Int1_UInt1_UInt1 = TSymbolUniqueId(5318);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwapExt_UImage2DMS1_Int2_Int1_UInt1_UInt1 = TSymbolUniqueId(5319);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwapExt_Image2DMSArray1_Int3_Int1_UInt1_UInt1 = TSymbolUniqueId(5320);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwapExt_IImage2DMSArray1_Int3_Int1_UInt1_UInt1 = TSymbolUniqueId(5321);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwapExt_UImage2DMSArray1_Int3_Int1_UInt1_UInt1 = TSymbolUniqueId(5322);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image2D1_Int2_Int1_Int1 =
+ TSymbolUniqueId(5323);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage2D1_Int2_Int1_Int1 =
+ TSymbolUniqueId(5324);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage2D1_Int2_Int1_Int1 =
+ TSymbolUniqueId(5325);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image3D1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5326);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage3D1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5327);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage3D1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5328);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_ImageCube1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5329);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImageCube1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5330);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImageCube1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5331);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_ImageBuffer1_Int1_Int1_Int1 =
+ TSymbolUniqueId(5332);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImageBuffer1_Int1_Int1_Int1 =
+ TSymbolUniqueId(5333);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImageBuffer1_Int1_Int1_Int1 =
+ TSymbolUniqueId(5334);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image2DArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5335);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage2DArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5336);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage2DArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5337);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_ImageCubeArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5338);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImageCubeArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5339);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImageCubeArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(5340);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image1D1_Int1_Int1_Int1 =
+ TSymbolUniqueId(5341);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage1D1_Int1_Int1_Int1 =
+ TSymbolUniqueId(5342);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage1D1_Int1_Int1_Int1 =
+ TSymbolUniqueId(5343);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image1DArray1_Int2_Int1_Int1 =
+ TSymbolUniqueId(5344);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage1DArray1_Int2_Int1_Int1 =
+ TSymbolUniqueId(5345);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage1DArray1_Int2_Int1_Int1 =
+ TSymbolUniqueId(5346);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_ImageRect1_Int2_Int1_Int1 =
+ TSymbolUniqueId(5347);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImageRect1_Int2_Int1_Int1 =
+ TSymbolUniqueId(5348);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImageRect1_Int2_Int1_Int1 =
+ TSymbolUniqueId(5349);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image2DMS1_Int2_Int1_Int1_Int1 =
+ TSymbolUniqueId(5350);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage2DMS1_Int2_Int1_Int1_Int1 =
+ TSymbolUniqueId(5351);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage2DMS1_Int2_Int1_Int1_Int1 =
+ TSymbolUniqueId(5352);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwapExt_Image2DMSArray1_Int3_Int1_Int1_Int1 = TSymbolUniqueId(5353);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwapExt_IImage2DMSArray1_Int3_Int1_Int1_Int1 = TSymbolUniqueId(5354);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwapExt_UImage2DMSArray1_Int3_Int1_Int1_Int1 = TSymbolUniqueId(5355);
+ static constexpr const TSymbolUniqueId pixelLocalLoadANGLE_PixelLocalANGLE1 =
+ TSymbolUniqueId(5356);
+ static constexpr const TSymbolUniqueId pt01g = TSymbolUniqueId(5357);
+ static constexpr const TSymbolUniqueId pixelLocalLoadANGLE_IPixelLocalANGLE1 =
+ TSymbolUniqueId(5358);
+ static constexpr const TSymbolUniqueId pt01h = TSymbolUniqueId(5359);
+ static constexpr const TSymbolUniqueId pixelLocalLoadANGLE_UPixelLocalANGLE1 =
+ TSymbolUniqueId(5360);
+ static constexpr const TSymbolUniqueId pt01i = TSymbolUniqueId(5361);
+ static constexpr const TSymbolUniqueId pixelLocalStoreANGLE_PixelLocalANGLE1_Float4 =
+ TSymbolUniqueId(5362);
+ static constexpr const TSymbolUniqueId pixelLocalStoreANGLE_IPixelLocalANGLE1_Int4 =
+ TSymbolUniqueId(5363);
+ static constexpr const TSymbolUniqueId pixelLocalStoreANGLE_UPixelLocalANGLE1_UInt4 =
+ TSymbolUniqueId(5364);
+ static constexpr const TSymbolUniqueId beginInvocationInterlockNV = TSymbolUniqueId(5365);
+ static constexpr const TSymbolUniqueId endInvocationInterlockNV = TSymbolUniqueId(5366);
+ static constexpr const TSymbolUniqueId beginFragmentShaderOrderingINTEL = TSymbolUniqueId(5367);
+ static constexpr const TSymbolUniqueId beginInvocationInterlockARB = TSymbolUniqueId(5368);
+ static constexpr const TSymbolUniqueId endInvocationInterlockARB = TSymbolUniqueId(5369);
+ static constexpr const TSymbolUniqueId memoryBarrier = TSymbolUniqueId(5370);
+ static constexpr const TSymbolUniqueId memoryBarrierAtomicCounter = TSymbolUniqueId(5371);
+ static constexpr const TSymbolUniqueId memoryBarrierBuffer = TSymbolUniqueId(5372);
+ static constexpr const TSymbolUniqueId memoryBarrierImage = TSymbolUniqueId(5373);
+ static constexpr const TSymbolUniqueId barrier = TSymbolUniqueId(5374);
+ static constexpr const TSymbolUniqueId memoryBarrierShared = TSymbolUniqueId(5375);
+ static constexpr const TSymbolUniqueId groupMemoryBarrier = TSymbolUniqueId(5376);
+ static constexpr const TSymbolUniqueId barrierTCS = TSymbolUniqueId(5377);
+ static constexpr const TSymbolUniqueId barrierTCSES3_2 = TSymbolUniqueId(5378);
+ static constexpr const TSymbolUniqueId EmitVertex = TSymbolUniqueId(5379);
+ static constexpr const TSymbolUniqueId EmitVertexES3_2 = TSymbolUniqueId(5380);
+ static constexpr const TSymbolUniqueId EndPrimitive = TSymbolUniqueId(5381);
+ static constexpr const TSymbolUniqueId EndPrimitiveES3_2 = TSymbolUniqueId(5382);
+ static constexpr const TSymbolUniqueId subpassLoad_SubpassInput1 = TSymbolUniqueId(5383);
+ static constexpr const TSymbolUniqueId pt01j = TSymbolUniqueId(5384);
+ static constexpr const TSymbolUniqueId subpassLoad_ISubpassInput1 = TSymbolUniqueId(5385);
+ static constexpr const TSymbolUniqueId pt01k = TSymbolUniqueId(5386);
+ static constexpr const TSymbolUniqueId subpassLoad_USubpassInput1 = TSymbolUniqueId(5387);
+ static constexpr const TSymbolUniqueId pt01l = TSymbolUniqueId(5388);
+ static constexpr const TSymbolUniqueId subpassLoad_SubpassInputMS1_Int1 = TSymbolUniqueId(5389);
+ static constexpr const TSymbolUniqueId pt01m = TSymbolUniqueId(5390);
+ static constexpr const TSymbolUniqueId subpassLoad_ISubpassInputMS1_Int1 =
+ TSymbolUniqueId(5391);
+ static constexpr const TSymbolUniqueId pt01n = TSymbolUniqueId(5392);
+ static constexpr const TSymbolUniqueId subpassLoad_USubpassInputMS1_Int1 =
+ TSymbolUniqueId(5393);
+ static constexpr const TSymbolUniqueId pt01o = TSymbolUniqueId(5394);
+ static constexpr const TSymbolUniqueId gl_DepthRangeParameters = TSymbolUniqueId(5395);
+ static constexpr const TSymbolUniqueId gl_DepthRange = TSymbolUniqueId(5396);
+ static constexpr const TSymbolUniqueId gl_NumSamples = TSymbolUniqueId(5397);
+ static constexpr const TSymbolUniqueId gl_NumSamplesES3_2 = TSymbolUniqueId(5398);
+ static constexpr const TSymbolUniqueId gl_MaxVertexAttribs = TSymbolUniqueId(5399);
+ static constexpr const TSymbolUniqueId gl_MaxVertexUniformVectors = TSymbolUniqueId(5400);
+ static constexpr const TSymbolUniqueId gl_MaxVertexTextureImageUnits = TSymbolUniqueId(5401);
+ static constexpr const TSymbolUniqueId gl_MaxCombinedTextureImageUnits = TSymbolUniqueId(5402);
+ static constexpr const TSymbolUniqueId gl_MaxTextureImageUnits = TSymbolUniqueId(5403);
+ static constexpr const TSymbolUniqueId gl_MaxFragmentUniformVectors = TSymbolUniqueId(5404);
+ static constexpr const TSymbolUniqueId gl_MaxVaryingVectors = TSymbolUniqueId(5405);
+ static constexpr const TSymbolUniqueId gl_MaxDrawBuffers = TSymbolUniqueId(5406);
+ static constexpr const TSymbolUniqueId gl_MaxDualSourceDrawBuffersEXT = TSymbolUniqueId(5407);
+ static constexpr const TSymbolUniqueId gl_MaxVertexOutputVectors = TSymbolUniqueId(5408);
+ static constexpr const TSymbolUniqueId gl_MaxFragmentInputVectors = TSymbolUniqueId(5409);
+ static constexpr const TSymbolUniqueId gl_MinProgramTexelOffset = TSymbolUniqueId(5410);
+ static constexpr const TSymbolUniqueId gl_MaxProgramTexelOffset = TSymbolUniqueId(5411);
+ static constexpr const TSymbolUniqueId gl_MaxImageUnits = TSymbolUniqueId(5412);
+ static constexpr const TSymbolUniqueId gl_MaxVertexImageUniforms = TSymbolUniqueId(5413);
+ static constexpr const TSymbolUniqueId gl_MaxFragmentImageUniforms = TSymbolUniqueId(5414);
+ static constexpr const TSymbolUniqueId gl_MaxComputeImageUniforms = TSymbolUniqueId(5415);
+ static constexpr const TSymbolUniqueId gl_MaxCombinedImageUniforms = TSymbolUniqueId(5416);
+ static constexpr const TSymbolUniqueId gl_MaxCombinedShaderOutputResources =
+ TSymbolUniqueId(5417);
+ static constexpr const TSymbolUniqueId gl_MaxComputeWorkGroupCount = TSymbolUniqueId(5418);
+ static constexpr const TSymbolUniqueId gl_MaxComputeWorkGroupSize = TSymbolUniqueId(5419);
+ static constexpr const TSymbolUniqueId gl_MaxComputeUniformComponents = TSymbolUniqueId(5420);
+ static constexpr const TSymbolUniqueId gl_MaxComputeTextureImageUnits = TSymbolUniqueId(5421);
+ static constexpr const TSymbolUniqueId gl_MaxComputeAtomicCounters = TSymbolUniqueId(5422);
+ static constexpr const TSymbolUniqueId gl_MaxComputeAtomicCounterBuffers =
+ TSymbolUniqueId(5423);
+ static constexpr const TSymbolUniqueId gl_MaxVertexAtomicCounters = TSymbolUniqueId(5424);
+ static constexpr const TSymbolUniqueId gl_MaxFragmentAtomicCounters = TSymbolUniqueId(5425);
+ static constexpr const TSymbolUniqueId gl_MaxCombinedAtomicCounters = TSymbolUniqueId(5426);
+ static constexpr const TSymbolUniqueId gl_MaxAtomicCounterBindings = TSymbolUniqueId(5427);
+ static constexpr const TSymbolUniqueId gl_MaxVertexAtomicCounterBuffers = TSymbolUniqueId(5428);
+ static constexpr const TSymbolUniqueId gl_MaxFragmentAtomicCounterBuffers =
+ TSymbolUniqueId(5429);
+ static constexpr const TSymbolUniqueId gl_MaxCombinedAtomicCounterBuffers =
+ TSymbolUniqueId(5430);
+ static constexpr const TSymbolUniqueId gl_MaxAtomicCounterBufferSize = TSymbolUniqueId(5431);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryInputComponents = TSymbolUniqueId(5432);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryInputComponentsES3_2 =
+ TSymbolUniqueId(5433);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryOutputComponents = TSymbolUniqueId(5434);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryOutputComponentsES3_2 =
+ TSymbolUniqueId(5435);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryImageUniforms = TSymbolUniqueId(5436);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryImageUniformsES3_2 = TSymbolUniqueId(5437);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryTextureImageUnits = TSymbolUniqueId(5438);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryTextureImageUnitsES3_2 =
+ TSymbolUniqueId(5439);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryOutputVertices = TSymbolUniqueId(5440);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryOutputVerticesES3_2 =
+ TSymbolUniqueId(5441);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryTotalOutputComponents =
+ TSymbolUniqueId(5442);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryTotalOutputComponentsES3_2 =
+ TSymbolUniqueId(5443);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryUniformComponents = TSymbolUniqueId(5444);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryUniformComponentsES3_2 =
+ TSymbolUniqueId(5445);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryAtomicCounters = TSymbolUniqueId(5446);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryAtomicCountersES3_2 =
+ TSymbolUniqueId(5447);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryAtomicCounterBuffers =
+ TSymbolUniqueId(5448);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryAtomicCounterBuffersES3_2 =
+ TSymbolUniqueId(5449);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlInputComponents = TSymbolUniqueId(5450);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlInputComponentsES3_2 =
+ TSymbolUniqueId(5451);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlOutputComponents =
+ TSymbolUniqueId(5452);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlOutputComponentsES3_2 =
+ TSymbolUniqueId(5453);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlTextureImageUnits =
+ TSymbolUniqueId(5454);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlTextureImageUnitsES3_2 =
+ TSymbolUniqueId(5455);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlUniformComponents =
+ TSymbolUniqueId(5456);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlUniformComponentsES3_2 =
+ TSymbolUniqueId(5457);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlTotalOutputComponents =
+ TSymbolUniqueId(5458);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlTotalOutputComponentsES3_2 =
+ TSymbolUniqueId(5459);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlImageUniforms = TSymbolUniqueId(5460);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlImageUniformsES3_2 =
+ TSymbolUniqueId(5461);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlAtomicCounters = TSymbolUniqueId(5462);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlAtomicCountersES3_2 =
+ TSymbolUniqueId(5463);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlAtomicCounterBuffers =
+ TSymbolUniqueId(5464);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlAtomicCounterBuffersES3_2 =
+ TSymbolUniqueId(5465);
+ static constexpr const TSymbolUniqueId gl_MaxTessPatchComponents = TSymbolUniqueId(5466);
+ static constexpr const TSymbolUniqueId gl_MaxTessPatchComponentsES3_2 = TSymbolUniqueId(5467);
+ static constexpr const TSymbolUniqueId gl_MaxPatchVertices = TSymbolUniqueId(5468);
+ static constexpr const TSymbolUniqueId gl_MaxPatchVerticesES3_2 = TSymbolUniqueId(5469);
+ static constexpr const TSymbolUniqueId gl_MaxTessGenLevel = TSymbolUniqueId(5470);
+ static constexpr const TSymbolUniqueId gl_MaxTessGenLevelES3_2 = TSymbolUniqueId(5471);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationInputComponents =
+ TSymbolUniqueId(5472);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationInputComponentsES3_2 =
+ TSymbolUniqueId(5473);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationOutputComponents =
+ TSymbolUniqueId(5474);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationOutputComponentsES3_2 =
+ TSymbolUniqueId(5475);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationTextureImageUnits =
+ TSymbolUniqueId(5476);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationTextureImageUnitsES3_2 =
+ TSymbolUniqueId(5477);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationUniformComponents =
+ TSymbolUniqueId(5478);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationUniformComponentsES3_2 =
+ TSymbolUniqueId(5479);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationImageUniforms =
+ TSymbolUniqueId(5480);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationImageUniformsES3_2 =
+ TSymbolUniqueId(5481);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationAtomicCounters =
+ TSymbolUniqueId(5482);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationAtomicCountersES3_2 =
+ TSymbolUniqueId(5483);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationAtomicCounterBuffers =
+ TSymbolUniqueId(5484);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationAtomicCounterBuffersES3_2 =
+ TSymbolUniqueId(5485);
+ static constexpr const TSymbolUniqueId gl_MaxSamples = TSymbolUniqueId(5486);
+ static constexpr const TSymbolUniqueId gl_MaxSamplesES3_2 = TSymbolUniqueId(5487);
+ static constexpr const TSymbolUniqueId gl_MaxClipDistancesAPPLE = TSymbolUniqueId(5488);
+ static constexpr const TSymbolUniqueId gl_MaxCullDistancesEXT = TSymbolUniqueId(5489);
+ static constexpr const TSymbolUniqueId gl_MaxCombinedClipAndCullDistancesEXT =
+ TSymbolUniqueId(5490);
+ static constexpr const TSymbolUniqueId gl_FragCoord = TSymbolUniqueId(5491);
+ static constexpr const TSymbolUniqueId gl_FrontFacing = TSymbolUniqueId(5492);
+ static constexpr const TSymbolUniqueId gl_PointCoord = TSymbolUniqueId(5493);
+ static constexpr const TSymbolUniqueId gl_FragColor = TSymbolUniqueId(5494);
+ static constexpr const TSymbolUniqueId gl_FragData = TSymbolUniqueId(5495);
+ static constexpr const TSymbolUniqueId gl_FragDepth = TSymbolUniqueId(5496);
+ static constexpr const TSymbolUniqueId gl_HelperInvocation = TSymbolUniqueId(5497);
+ static constexpr const TSymbolUniqueId gl_FragCoord300 = TSymbolUniqueId(5498);
+ static constexpr const TSymbolUniqueId gl_SecondaryFragColorEXT = TSymbolUniqueId(5499);
+ static constexpr const TSymbolUniqueId gl_SecondaryFragDataEXT = TSymbolUniqueId(5500);
+ static constexpr const TSymbolUniqueId gl_FragDepthEXT = TSymbolUniqueId(5501);
+ static constexpr const TSymbolUniqueId gl_LastFragData = TSymbolUniqueId(5502);
+ static constexpr const TSymbolUniqueId gl_LastFragColor = TSymbolUniqueId(5503);
+ static constexpr const TSymbolUniqueId gl_LastFragDataNV = TSymbolUniqueId(5504);
+ static constexpr const TSymbolUniqueId gl_LastFragColorARM = TSymbolUniqueId(5505);
+ static constexpr const TSymbolUniqueId gl_PrimitiveID = TSymbolUniqueId(5506);
+ static constexpr const TSymbolUniqueId gl_PrimitiveIDES3_2 = TSymbolUniqueId(5507);
+ static constexpr const TSymbolUniqueId gl_Layer = TSymbolUniqueId(5508);
+ static constexpr const TSymbolUniqueId gl_LayerES3_2 = TSymbolUniqueId(5509);
+ static constexpr const TSymbolUniqueId gl_SampleID = TSymbolUniqueId(5510);
+ static constexpr const TSymbolUniqueId gl_SampleIDES3_2 = TSymbolUniqueId(5511);
+ static constexpr const TSymbolUniqueId gl_SamplePosition = TSymbolUniqueId(5512);
+ static constexpr const TSymbolUniqueId gl_SamplePositionES3_2 = TSymbolUniqueId(5513);
+ static constexpr const TSymbolUniqueId gl_SampleMaskIn = TSymbolUniqueId(5514);
+ static constexpr const TSymbolUniqueId gl_SampleMaskInES3_2 = TSymbolUniqueId(5515);
+ static constexpr const TSymbolUniqueId gl_SampleMask = TSymbolUniqueId(5516);
+ static constexpr const TSymbolUniqueId gl_SampleMaskES3_2 = TSymbolUniqueId(5517);
+ static constexpr const TSymbolUniqueId gl_CullDistance = TSymbolUniqueId(5518);
+ static constexpr const TSymbolUniqueId gl_ClipDistance = TSymbolUniqueId(5519);
+ static constexpr const TSymbolUniqueId gl_Position = TSymbolUniqueId(5520);
+ static constexpr const TSymbolUniqueId gl_PointSize = TSymbolUniqueId(5521);
+ static constexpr const TSymbolUniqueId gl_InstanceID = TSymbolUniqueId(5522);
+ static constexpr const TSymbolUniqueId gl_InstanceIndex = TSymbolUniqueId(5523);
+ static constexpr const TSymbolUniqueId gl_VertexID = TSymbolUniqueId(5524);
+ static constexpr const TSymbolUniqueId gl_VertexIndex = TSymbolUniqueId(5525);
+ static constexpr const TSymbolUniqueId gl_ViewportIndex = TSymbolUniqueId(5526);
+ static constexpr const TSymbolUniqueId gl_LayerVS = TSymbolUniqueId(5527);
+ static constexpr const TSymbolUniqueId gl_PointSize300 = TSymbolUniqueId(5528);
+ static constexpr const TSymbolUniqueId gl_DrawID = TSymbolUniqueId(5529);
+ static constexpr const TSymbolUniqueId gl_BaseVertex = TSymbolUniqueId(5530);
+ static constexpr const TSymbolUniqueId gl_BaseInstance = TSymbolUniqueId(5531);
+ static constexpr const TSymbolUniqueId angle_BaseVertex = TSymbolUniqueId(5532);
+ static constexpr const TSymbolUniqueId angle_BaseInstance = TSymbolUniqueId(5533);
+ static constexpr const TSymbolUniqueId gl_ClipDistanceAPPLE = TSymbolUniqueId(5534);
+ static constexpr const TSymbolUniqueId gl_CullDistanceEXT = TSymbolUniqueId(5535);
+ static constexpr const TSymbolUniqueId gl_NumWorkGroups = TSymbolUniqueId(5536);
+ static constexpr const TSymbolUniqueId gl_WorkGroupSize = TSymbolUniqueId(5537);
+ static constexpr const TSymbolUniqueId gl_WorkGroupID = TSymbolUniqueId(5538);
+ static constexpr const TSymbolUniqueId gl_LocalInvocationID = TSymbolUniqueId(5539);
+ static constexpr const TSymbolUniqueId gl_GlobalInvocationID = TSymbolUniqueId(5540);
+ static constexpr const TSymbolUniqueId gl_LocalInvocationIndex = TSymbolUniqueId(5541);
+ static constexpr const TSymbolUniqueId gl_PrimitiveIDIn = TSymbolUniqueId(5542);
+ static constexpr const TSymbolUniqueId gl_PrimitiveIDInES3_2 = TSymbolUniqueId(5543);
+ static constexpr const TSymbolUniqueId gl_InvocationID = TSymbolUniqueId(5544);
+ static constexpr const TSymbolUniqueId gl_InvocationIDES3_2 = TSymbolUniqueId(5545);
+ static constexpr const TSymbolUniqueId gl_PrimitiveIDGS = TSymbolUniqueId(5546);
+ static constexpr const TSymbolUniqueId gl_PrimitiveIDGSES3_2 = TSymbolUniqueId(5547);
+ static constexpr const TSymbolUniqueId gl_LayerGS = TSymbolUniqueId(5548);
+ static constexpr const TSymbolUniqueId gl_LayerGSES3_2 = TSymbolUniqueId(5549);
+ static constexpr const TSymbolUniqueId gl_PerVertex = TSymbolUniqueId(5550);
+ static constexpr const TSymbolUniqueId gl_PerVertexES3_2 = TSymbolUniqueId(5551);
+ static constexpr const TSymbolUniqueId gl_in = TSymbolUniqueId(5552);
+ static constexpr const TSymbolUniqueId gl_inES3_2 = TSymbolUniqueId(5553);
+ static constexpr const TSymbolUniqueId gl_PerVertexOutBlock = TSymbolUniqueId(5554);
+ static constexpr const TSymbolUniqueId gl_PerVertexOutBlockES3_2 = TSymbolUniqueId(5555);
+ static constexpr const TSymbolUniqueId gl_PositionGS = TSymbolUniqueId(5556);
+ static constexpr const TSymbolUniqueId gl_PositionGSES3_2 = TSymbolUniqueId(5557);
+ static constexpr const TSymbolUniqueId gl_PatchVerticesInTCS = TSymbolUniqueId(5558);
+ static constexpr const TSymbolUniqueId gl_PatchVerticesInTCSES3_2 = TSymbolUniqueId(5559);
+ static constexpr const TSymbolUniqueId gl_InvocationIDTCS = TSymbolUniqueId(5560);
+ static constexpr const TSymbolUniqueId gl_InvocationIDTCSES3_2 = TSymbolUniqueId(5561);
+ static constexpr const TSymbolUniqueId gl_PrimitiveIDTCS = TSymbolUniqueId(5562);
+ static constexpr const TSymbolUniqueId gl_PrimitiveIDTCSES3_2 = TSymbolUniqueId(5563);
+ static constexpr const TSymbolUniqueId gl_TessLevelOuterTCS = TSymbolUniqueId(5564);
+ static constexpr const TSymbolUniqueId gl_TessLevelOuterTCSES3_2 = TSymbolUniqueId(5565);
+ static constexpr const TSymbolUniqueId gl_TessLevelInnerTCS = TSymbolUniqueId(5566);
+ static constexpr const TSymbolUniqueId gl_TessLevelInnerTCSES3_2 = TSymbolUniqueId(5567);
+ static constexpr const TSymbolUniqueId gl_PerVertexTCS = TSymbolUniqueId(5568);
+ static constexpr const TSymbolUniqueId gl_PerVertexTCSES3_2 = TSymbolUniqueId(5569);
+ static constexpr const TSymbolUniqueId gl_inTCS = TSymbolUniqueId(5570);
+ static constexpr const TSymbolUniqueId gl_inTCSES3_2 = TSymbolUniqueId(5571);
+ static constexpr const TSymbolUniqueId gl_outTCS = TSymbolUniqueId(5572);
+ static constexpr const TSymbolUniqueId gl_outTCSES3_2 = TSymbolUniqueId(5573);
+ static constexpr const TSymbolUniqueId gl_BoundingBoxTCS = TSymbolUniqueId(5574);
+ static constexpr const TSymbolUniqueId gl_BoundingBoxTCSES3_2 = TSymbolUniqueId(5575);
+ static constexpr const TSymbolUniqueId gl_PerVertexOutTcsBlock = TSymbolUniqueId(5576);
+ static constexpr const TSymbolUniqueId gl_PerVertexOutTcsBlockES3_2 = TSymbolUniqueId(5577);
+ static constexpr const TSymbolUniqueId gl_PositionTCS = TSymbolUniqueId(5578);
+ static constexpr const TSymbolUniqueId gl_PositionTCSES3_2 = TSymbolUniqueId(5579);
+ static constexpr const TSymbolUniqueId gl_BoundingBoxEXTTCS = TSymbolUniqueId(5580);
+ static constexpr const TSymbolUniqueId gl_BoundingBoxEXTTCSES3_2 = TSymbolUniqueId(5581);
+ static constexpr const TSymbolUniqueId gl_BoundingBoxOESTCS = TSymbolUniqueId(5582);
+ static constexpr const TSymbolUniqueId gl_BoundingBoxOESTCSES3_2 = TSymbolUniqueId(5583);
+ static constexpr const TSymbolUniqueId gl_PatchVerticesInTES = TSymbolUniqueId(5584);
+ static constexpr const TSymbolUniqueId gl_PatchVerticesInTESES3_2 = TSymbolUniqueId(5585);
+ static constexpr const TSymbolUniqueId gl_PrimitiveIDTES = TSymbolUniqueId(5586);
+ static constexpr const TSymbolUniqueId gl_PrimitiveIDTESES3_2 = TSymbolUniqueId(5587);
+ static constexpr const TSymbolUniqueId gl_TessCoord = TSymbolUniqueId(5588);
+ static constexpr const TSymbolUniqueId gl_TessLevelOuterTES = TSymbolUniqueId(5589);
+ static constexpr const TSymbolUniqueId gl_TessLevelOuterTESES3_2 = TSymbolUniqueId(5590);
+ static constexpr const TSymbolUniqueId gl_TessLevelInnerTES = TSymbolUniqueId(5591);
+ static constexpr const TSymbolUniqueId gl_TessLevelInnerTESES3_2 = TSymbolUniqueId(5592);
+ static constexpr const TSymbolUniqueId gl_PerVertexTES = TSymbolUniqueId(5593);
+ static constexpr const TSymbolUniqueId gl_PerVertexTESES3_2 = TSymbolUniqueId(5594);
+ static constexpr const TSymbolUniqueId gl_inTES = TSymbolUniqueId(5595);
+ static constexpr const TSymbolUniqueId gl_inTESES3_2 = TSymbolUniqueId(5596);
+ static constexpr const TSymbolUniqueId gl_outTES = TSymbolUniqueId(5597);
+ static constexpr const TSymbolUniqueId gl_outTESES3_2 = TSymbolUniqueId(5598);
+ static constexpr const TSymbolUniqueId gl_PerVertexOutTesBlock = TSymbolUniqueId(5599);
+ static constexpr const TSymbolUniqueId gl_PerVertexOutTesBlockES3_2 = TSymbolUniqueId(5600);
+ static constexpr const TSymbolUniqueId gl_PositionTES = TSymbolUniqueId(5601);
+ static constexpr const TSymbolUniqueId gl_PositionTESES3_2 = TSymbolUniqueId(5602);
+ static constexpr const TSymbolUniqueId gl_ViewID_OVR = TSymbolUniqueId(5603);
+
+}; // class BuiltInId
+
+namespace BuiltInVariable
+{
+
+const TVariable *angle_BaseInstance();
+const TVariable *angle_BaseVertex();
+const TVariable *gl_BaseInstance();
+const TVariable *gl_BaseVertex();
+const TVariable *gl_DrawID();
+const TVariable *gl_FragColor();
+const TVariable *gl_FragCoord();
+const TVariable *gl_FragCoord300();
+const TVariable *gl_FragDepth();
+const TVariable *gl_FrontFacing();
+const TVariable *gl_GlobalInvocationID();
+const TVariable *gl_HelperInvocation();
+const TVariable *gl_InstanceID();
+const TVariable *gl_InstanceIndex();
+const TVariable *gl_InvocationID();
+const TVariable *gl_InvocationIDES3_2();
+const TVariable *gl_InvocationIDTCS();
+const TVariable *gl_InvocationIDTCSES3_2();
+const TVariable *gl_LastFragColor();
+const TVariable *gl_LastFragColorARM();
+const TVariable *gl_Layer();
+const TVariable *gl_LayerES3_2();
+const TVariable *gl_LayerGS();
+const TVariable *gl_LayerGSES3_2();
+const TVariable *gl_LayerVS();
+const TVariable *gl_LocalInvocationID();
+const TVariable *gl_LocalInvocationIndex();
+const TVariable *gl_NumSamples();
+const TVariable *gl_NumSamplesES3_2();
+const TVariable *gl_NumWorkGroups();
+const TVariable *gl_PatchVerticesInTCS();
+const TVariable *gl_PatchVerticesInTCSES3_2();
+const TVariable *gl_PatchVerticesInTES();
+const TVariable *gl_PatchVerticesInTESES3_2();
+const TVariable *gl_PointCoord();
+const TVariable *gl_PointSize();
+const TVariable *gl_PointSize300();
+const TVariable *gl_Position();
+const TVariable *gl_PrimitiveID();
+const TVariable *gl_PrimitiveIDES3_2();
+const TVariable *gl_PrimitiveIDGS();
+const TVariable *gl_PrimitiveIDGSES3_2();
+const TVariable *gl_PrimitiveIDIn();
+const TVariable *gl_PrimitiveIDInES3_2();
+const TVariable *gl_PrimitiveIDTCS();
+const TVariable *gl_PrimitiveIDTCSES3_2();
+const TVariable *gl_PrimitiveIDTES();
+const TVariable *gl_PrimitiveIDTESES3_2();
+const TVariable *gl_SampleID();
+const TVariable *gl_SampleIDES3_2();
+const TVariable *gl_SamplePosition();
+const TVariable *gl_SamplePositionES3_2();
+const TVariable *gl_SecondaryFragColorEXT();
+const TVariable *gl_TessCoord();
+const TVariable *gl_VertexID();
+const TVariable *gl_VertexIndex();
+const TVariable *gl_ViewID_OVR();
+const TVariable *gl_ViewportIndex();
+const TVariable *gl_WorkGroupID();
+const TVariable *gl_WorkGroupSize();
+
+} // namespace BuiltInVariable
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEUTIL_BUILTIN_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/BuiltIn_complete_autogen.h b/gfx/angle/checkout/src/compiler/translator/tree_util/BuiltIn_complete_autogen.h
new file mode 100644
index 0000000000..406d930d56
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/BuiltIn_complete_autogen.h
@@ -0,0 +1,5008 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_builtin_symbols.py using data from builtin_variables.json and
+// builtin_function_declarations.txt.
+//
+// Copyright 2020 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.
+//
+// BuiltIn_complete_autogen.h:
+// Compile-time initialized built-ins.
+
+#ifndef COMPILER_TRANSLATOR_TREEUTIL_BUILTIN_AUTOGEN_H_
+#define COMPILER_TRANSLATOR_TREEUTIL_BUILTIN_AUTOGEN_H_
+
+#include "compiler/translator/SymbolUniqueId.h"
+
+namespace sh
+{
+
+class TVariable;
+
+class BuiltInId
+{
+ public:
+ static constexpr const TSymbolUniqueId radians_Float1 = TSymbolUniqueId(0);
+ static constexpr const TSymbolUniqueId pt00B = TSymbolUniqueId(1);
+ static constexpr const TSymbolUniqueId radians_Float2 = TSymbolUniqueId(2);
+ static constexpr const TSymbolUniqueId pt10B = TSymbolUniqueId(3);
+ static constexpr const TSymbolUniqueId radians_Float3 = TSymbolUniqueId(4);
+ static constexpr const TSymbolUniqueId pt20B = TSymbolUniqueId(5);
+ static constexpr const TSymbolUniqueId radians_Float4 = TSymbolUniqueId(6);
+ static constexpr const TSymbolUniqueId pt30B = TSymbolUniqueId(7);
+ static constexpr const TSymbolUniqueId degrees_Float1 = TSymbolUniqueId(8);
+ static constexpr const TSymbolUniqueId degrees_Float2 = TSymbolUniqueId(9);
+ static constexpr const TSymbolUniqueId degrees_Float3 = TSymbolUniqueId(10);
+ static constexpr const TSymbolUniqueId degrees_Float4 = TSymbolUniqueId(11);
+ static constexpr const TSymbolUniqueId sin_Float1 = TSymbolUniqueId(12);
+ static constexpr const TSymbolUniqueId sin_Float2 = TSymbolUniqueId(13);
+ static constexpr const TSymbolUniqueId sin_Float3 = TSymbolUniqueId(14);
+ static constexpr const TSymbolUniqueId sin_Float4 = TSymbolUniqueId(15);
+ static constexpr const TSymbolUniqueId cos_Float1 = TSymbolUniqueId(16);
+ static constexpr const TSymbolUniqueId cos_Float2 = TSymbolUniqueId(17);
+ static constexpr const TSymbolUniqueId cos_Float3 = TSymbolUniqueId(18);
+ static constexpr const TSymbolUniqueId cos_Float4 = TSymbolUniqueId(19);
+ static constexpr const TSymbolUniqueId tan_Float1 = TSymbolUniqueId(20);
+ static constexpr const TSymbolUniqueId tan_Float2 = TSymbolUniqueId(21);
+ static constexpr const TSymbolUniqueId tan_Float3 = TSymbolUniqueId(22);
+ static constexpr const TSymbolUniqueId tan_Float4 = TSymbolUniqueId(23);
+ static constexpr const TSymbolUniqueId asin_Float1 = TSymbolUniqueId(24);
+ static constexpr const TSymbolUniqueId asin_Float2 = TSymbolUniqueId(25);
+ static constexpr const TSymbolUniqueId asin_Float3 = TSymbolUniqueId(26);
+ static constexpr const TSymbolUniqueId asin_Float4 = TSymbolUniqueId(27);
+ static constexpr const TSymbolUniqueId acos_Float1 = TSymbolUniqueId(28);
+ static constexpr const TSymbolUniqueId acos_Float2 = TSymbolUniqueId(29);
+ static constexpr const TSymbolUniqueId acos_Float3 = TSymbolUniqueId(30);
+ static constexpr const TSymbolUniqueId acos_Float4 = TSymbolUniqueId(31);
+ static constexpr const TSymbolUniqueId atan_Float1_Float1 = TSymbolUniqueId(32);
+ static constexpr const TSymbolUniqueId atan_Float2_Float2 = TSymbolUniqueId(33);
+ static constexpr const TSymbolUniqueId atan_Float3_Float3 = TSymbolUniqueId(34);
+ static constexpr const TSymbolUniqueId atan_Float4_Float4 = TSymbolUniqueId(35);
+ static constexpr const TSymbolUniqueId atan_Float1 = TSymbolUniqueId(36);
+ static constexpr const TSymbolUniqueId atan_Float2 = TSymbolUniqueId(37);
+ static constexpr const TSymbolUniqueId atan_Float3 = TSymbolUniqueId(38);
+ static constexpr const TSymbolUniqueId atan_Float4 = TSymbolUniqueId(39);
+ static constexpr const TSymbolUniqueId sinh_Float1 = TSymbolUniqueId(40);
+ static constexpr const TSymbolUniqueId sinh_Float2 = TSymbolUniqueId(41);
+ static constexpr const TSymbolUniqueId sinh_Float3 = TSymbolUniqueId(42);
+ static constexpr const TSymbolUniqueId sinh_Float4 = TSymbolUniqueId(43);
+ static constexpr const TSymbolUniqueId cosh_Float1 = TSymbolUniqueId(44);
+ static constexpr const TSymbolUniqueId cosh_Float2 = TSymbolUniqueId(45);
+ static constexpr const TSymbolUniqueId cosh_Float3 = TSymbolUniqueId(46);
+ static constexpr const TSymbolUniqueId cosh_Float4 = TSymbolUniqueId(47);
+ static constexpr const TSymbolUniqueId tanh_Float1 = TSymbolUniqueId(48);
+ static constexpr const TSymbolUniqueId tanh_Float2 = TSymbolUniqueId(49);
+ static constexpr const TSymbolUniqueId tanh_Float3 = TSymbolUniqueId(50);
+ static constexpr const TSymbolUniqueId tanh_Float4 = TSymbolUniqueId(51);
+ static constexpr const TSymbolUniqueId asinh_Float1 = TSymbolUniqueId(52);
+ static constexpr const TSymbolUniqueId asinh_Float2 = TSymbolUniqueId(53);
+ static constexpr const TSymbolUniqueId asinh_Float3 = TSymbolUniqueId(54);
+ static constexpr const TSymbolUniqueId asinh_Float4 = TSymbolUniqueId(55);
+ static constexpr const TSymbolUniqueId acosh_Float1 = TSymbolUniqueId(56);
+ static constexpr const TSymbolUniqueId acosh_Float2 = TSymbolUniqueId(57);
+ static constexpr const TSymbolUniqueId acosh_Float3 = TSymbolUniqueId(58);
+ static constexpr const TSymbolUniqueId acosh_Float4 = TSymbolUniqueId(59);
+ static constexpr const TSymbolUniqueId atanh_Float1 = TSymbolUniqueId(60);
+ static constexpr const TSymbolUniqueId atanh_Float2 = TSymbolUniqueId(61);
+ static constexpr const TSymbolUniqueId atanh_Float3 = TSymbolUniqueId(62);
+ static constexpr const TSymbolUniqueId atanh_Float4 = TSymbolUniqueId(63);
+ static constexpr const TSymbolUniqueId pow_Float1_Float1 = TSymbolUniqueId(64);
+ static constexpr const TSymbolUniqueId pow_Float2_Float2 = TSymbolUniqueId(65);
+ static constexpr const TSymbolUniqueId pow_Float3_Float3 = TSymbolUniqueId(66);
+ static constexpr const TSymbolUniqueId pow_Float4_Float4 = TSymbolUniqueId(67);
+ static constexpr const TSymbolUniqueId exp_Float1 = TSymbolUniqueId(68);
+ static constexpr const TSymbolUniqueId exp_Float2 = TSymbolUniqueId(69);
+ static constexpr const TSymbolUniqueId exp_Float3 = TSymbolUniqueId(70);
+ static constexpr const TSymbolUniqueId exp_Float4 = TSymbolUniqueId(71);
+ static constexpr const TSymbolUniqueId log_Float1 = TSymbolUniqueId(72);
+ static constexpr const TSymbolUniqueId log_Float2 = TSymbolUniqueId(73);
+ static constexpr const TSymbolUniqueId log_Float3 = TSymbolUniqueId(74);
+ static constexpr const TSymbolUniqueId log_Float4 = TSymbolUniqueId(75);
+ static constexpr const TSymbolUniqueId exp2_Float1 = TSymbolUniqueId(76);
+ static constexpr const TSymbolUniqueId exp2_Float2 = TSymbolUniqueId(77);
+ static constexpr const TSymbolUniqueId exp2_Float3 = TSymbolUniqueId(78);
+ static constexpr const TSymbolUniqueId exp2_Float4 = TSymbolUniqueId(79);
+ static constexpr const TSymbolUniqueId log2_Float1 = TSymbolUniqueId(80);
+ static constexpr const TSymbolUniqueId log2_Float2 = TSymbolUniqueId(81);
+ static constexpr const TSymbolUniqueId log2_Float3 = TSymbolUniqueId(82);
+ static constexpr const TSymbolUniqueId log2_Float4 = TSymbolUniqueId(83);
+ static constexpr const TSymbolUniqueId sqrt_Float1 = TSymbolUniqueId(84);
+ static constexpr const TSymbolUniqueId sqrt_Float2 = TSymbolUniqueId(85);
+ static constexpr const TSymbolUniqueId sqrt_Float3 = TSymbolUniqueId(86);
+ static constexpr const TSymbolUniqueId sqrt_Float4 = TSymbolUniqueId(87);
+ static constexpr const TSymbolUniqueId sqrt_Double1 = TSymbolUniqueId(88);
+ static constexpr const TSymbolUniqueId pt00C = TSymbolUniqueId(89);
+ static constexpr const TSymbolUniqueId sqrt_Double2 = TSymbolUniqueId(90);
+ static constexpr const TSymbolUniqueId pt10C = TSymbolUniqueId(91);
+ static constexpr const TSymbolUniqueId sqrt_Double3 = TSymbolUniqueId(92);
+ static constexpr const TSymbolUniqueId pt20C = TSymbolUniqueId(93);
+ static constexpr const TSymbolUniqueId sqrt_Double4 = TSymbolUniqueId(94);
+ static constexpr const TSymbolUniqueId pt30C = TSymbolUniqueId(95);
+ static constexpr const TSymbolUniqueId inversesqrt_Float1 = TSymbolUniqueId(96);
+ static constexpr const TSymbolUniqueId inversesqrt_Float2 = TSymbolUniqueId(97);
+ static constexpr const TSymbolUniqueId inversesqrt_Float3 = TSymbolUniqueId(98);
+ static constexpr const TSymbolUniqueId inversesqrt_Float4 = TSymbolUniqueId(99);
+ static constexpr const TSymbolUniqueId inversesqrt_Double1 = TSymbolUniqueId(100);
+ static constexpr const TSymbolUniqueId inversesqrt_Double2 = TSymbolUniqueId(101);
+ static constexpr const TSymbolUniqueId inversesqrt_Double3 = TSymbolUniqueId(102);
+ static constexpr const TSymbolUniqueId inversesqrt_Double4 = TSymbolUniqueId(103);
+ static constexpr const TSymbolUniqueId abs_Float1 = TSymbolUniqueId(104);
+ static constexpr const TSymbolUniqueId abs_Float2 = TSymbolUniqueId(105);
+ static constexpr const TSymbolUniqueId abs_Float3 = TSymbolUniqueId(106);
+ static constexpr const TSymbolUniqueId abs_Float4 = TSymbolUniqueId(107);
+ static constexpr const TSymbolUniqueId abs_Int1 = TSymbolUniqueId(108);
+ static constexpr const TSymbolUniqueId pt00D = TSymbolUniqueId(109);
+ static constexpr const TSymbolUniqueId abs_Int2 = TSymbolUniqueId(110);
+ static constexpr const TSymbolUniqueId pt10D = TSymbolUniqueId(111);
+ static constexpr const TSymbolUniqueId abs_Int3 = TSymbolUniqueId(112);
+ static constexpr const TSymbolUniqueId pt20D = TSymbolUniqueId(113);
+ static constexpr const TSymbolUniqueId abs_Int4 = TSymbolUniqueId(114);
+ static constexpr const TSymbolUniqueId pt30D = TSymbolUniqueId(115);
+ static constexpr const TSymbolUniqueId abs_Double1 = TSymbolUniqueId(116);
+ static constexpr const TSymbolUniqueId abs_Double2 = TSymbolUniqueId(117);
+ static constexpr const TSymbolUniqueId abs_Double3 = TSymbolUniqueId(118);
+ static constexpr const TSymbolUniqueId abs_Double4 = TSymbolUniqueId(119);
+ static constexpr const TSymbolUniqueId sign_Float1 = TSymbolUniqueId(120);
+ static constexpr const TSymbolUniqueId sign_Float2 = TSymbolUniqueId(121);
+ static constexpr const TSymbolUniqueId sign_Float3 = TSymbolUniqueId(122);
+ static constexpr const TSymbolUniqueId sign_Float4 = TSymbolUniqueId(123);
+ static constexpr const TSymbolUniqueId sign_Int1 = TSymbolUniqueId(124);
+ static constexpr const TSymbolUniqueId sign_Int2 = TSymbolUniqueId(125);
+ static constexpr const TSymbolUniqueId sign_Int3 = TSymbolUniqueId(126);
+ static constexpr const TSymbolUniqueId sign_Int4 = TSymbolUniqueId(127);
+ static constexpr const TSymbolUniqueId sign_Double1 = TSymbolUniqueId(128);
+ static constexpr const TSymbolUniqueId sign_Double2 = TSymbolUniqueId(129);
+ static constexpr const TSymbolUniqueId sign_Double3 = TSymbolUniqueId(130);
+ static constexpr const TSymbolUniqueId sign_Double4 = TSymbolUniqueId(131);
+ static constexpr const TSymbolUniqueId floor_Float1 = TSymbolUniqueId(132);
+ static constexpr const TSymbolUniqueId floor_Float2 = TSymbolUniqueId(133);
+ static constexpr const TSymbolUniqueId floor_Float3 = TSymbolUniqueId(134);
+ static constexpr const TSymbolUniqueId floor_Float4 = TSymbolUniqueId(135);
+ static constexpr const TSymbolUniqueId floor_Double1 = TSymbolUniqueId(136);
+ static constexpr const TSymbolUniqueId floor_Double2 = TSymbolUniqueId(137);
+ static constexpr const TSymbolUniqueId floor_Double3 = TSymbolUniqueId(138);
+ static constexpr const TSymbolUniqueId floor_Double4 = TSymbolUniqueId(139);
+ static constexpr const TSymbolUniqueId trunc_Float1 = TSymbolUniqueId(140);
+ static constexpr const TSymbolUniqueId trunc_Float2 = TSymbolUniqueId(141);
+ static constexpr const TSymbolUniqueId trunc_Float3 = TSymbolUniqueId(142);
+ static constexpr const TSymbolUniqueId trunc_Float4 = TSymbolUniqueId(143);
+ static constexpr const TSymbolUniqueId trunc_Double1 = TSymbolUniqueId(144);
+ static constexpr const TSymbolUniqueId trunc_Double2 = TSymbolUniqueId(145);
+ static constexpr const TSymbolUniqueId trunc_Double3 = TSymbolUniqueId(146);
+ static constexpr const TSymbolUniqueId trunc_Double4 = TSymbolUniqueId(147);
+ static constexpr const TSymbolUniqueId round_Float1 = TSymbolUniqueId(148);
+ static constexpr const TSymbolUniqueId round_Float2 = TSymbolUniqueId(149);
+ static constexpr const TSymbolUniqueId round_Float3 = TSymbolUniqueId(150);
+ static constexpr const TSymbolUniqueId round_Float4 = TSymbolUniqueId(151);
+ static constexpr const TSymbolUniqueId round_Double1 = TSymbolUniqueId(152);
+ static constexpr const TSymbolUniqueId round_Double2 = TSymbolUniqueId(153);
+ static constexpr const TSymbolUniqueId round_Double3 = TSymbolUniqueId(154);
+ static constexpr const TSymbolUniqueId round_Double4 = TSymbolUniqueId(155);
+ static constexpr const TSymbolUniqueId roundEven_Float1 = TSymbolUniqueId(156);
+ static constexpr const TSymbolUniqueId roundEven_Float2 = TSymbolUniqueId(157);
+ static constexpr const TSymbolUniqueId roundEven_Float3 = TSymbolUniqueId(158);
+ static constexpr const TSymbolUniqueId roundEven_Float4 = TSymbolUniqueId(159);
+ static constexpr const TSymbolUniqueId roundEven_Double1 = TSymbolUniqueId(160);
+ static constexpr const TSymbolUniqueId roundEven_Double2 = TSymbolUniqueId(161);
+ static constexpr const TSymbolUniqueId roundEven_Double3 = TSymbolUniqueId(162);
+ static constexpr const TSymbolUniqueId roundEven_Double4 = TSymbolUniqueId(163);
+ static constexpr const TSymbolUniqueId ceil_Float1 = TSymbolUniqueId(164);
+ static constexpr const TSymbolUniqueId ceil_Float2 = TSymbolUniqueId(165);
+ static constexpr const TSymbolUniqueId ceil_Float3 = TSymbolUniqueId(166);
+ static constexpr const TSymbolUniqueId ceil_Float4 = TSymbolUniqueId(167);
+ static constexpr const TSymbolUniqueId ceil_Double1 = TSymbolUniqueId(168);
+ static constexpr const TSymbolUniqueId ceil_Double2 = TSymbolUniqueId(169);
+ static constexpr const TSymbolUniqueId ceil_Double3 = TSymbolUniqueId(170);
+ static constexpr const TSymbolUniqueId ceil_Double4 = TSymbolUniqueId(171);
+ static constexpr const TSymbolUniqueId fract_Float1 = TSymbolUniqueId(172);
+ static constexpr const TSymbolUniqueId fract_Float2 = TSymbolUniqueId(173);
+ static constexpr const TSymbolUniqueId fract_Float3 = TSymbolUniqueId(174);
+ static constexpr const TSymbolUniqueId fract_Float4 = TSymbolUniqueId(175);
+ static constexpr const TSymbolUniqueId fract_Double1 = TSymbolUniqueId(176);
+ static constexpr const TSymbolUniqueId fract_Double2 = TSymbolUniqueId(177);
+ static constexpr const TSymbolUniqueId fract_Double3 = TSymbolUniqueId(178);
+ static constexpr const TSymbolUniqueId fract_Double4 = TSymbolUniqueId(179);
+ static constexpr const TSymbolUniqueId mod_Float1_Float1 = TSymbolUniqueId(180);
+ static constexpr const TSymbolUniqueId mod_Float2_Float1 = TSymbolUniqueId(181);
+ static constexpr const TSymbolUniqueId mod_Float3_Float1 = TSymbolUniqueId(182);
+ static constexpr const TSymbolUniqueId mod_Float4_Float1 = TSymbolUniqueId(183);
+ static constexpr const TSymbolUniqueId mod_Float2_Float2 = TSymbolUniqueId(184);
+ static constexpr const TSymbolUniqueId mod_Float3_Float3 = TSymbolUniqueId(185);
+ static constexpr const TSymbolUniqueId mod_Float4_Float4 = TSymbolUniqueId(186);
+ static constexpr const TSymbolUniqueId mod_Double1_Double1 = TSymbolUniqueId(187);
+ static constexpr const TSymbolUniqueId mod_Double2_Double1 = TSymbolUniqueId(188);
+ static constexpr const TSymbolUniqueId mod_Double3_Double1 = TSymbolUniqueId(189);
+ static constexpr const TSymbolUniqueId mod_Double4_Double1 = TSymbolUniqueId(190);
+ static constexpr const TSymbolUniqueId mod_Double2_Double2 = TSymbolUniqueId(191);
+ static constexpr const TSymbolUniqueId mod_Double3_Double3 = TSymbolUniqueId(192);
+ static constexpr const TSymbolUniqueId mod_Double4_Double4 = TSymbolUniqueId(193);
+ static constexpr const TSymbolUniqueId min_Float1_Float1 = TSymbolUniqueId(194);
+ static constexpr const TSymbolUniqueId min_Float2_Float1 = TSymbolUniqueId(195);
+ static constexpr const TSymbolUniqueId min_Float3_Float1 = TSymbolUniqueId(196);
+ static constexpr const TSymbolUniqueId min_Float4_Float1 = TSymbolUniqueId(197);
+ static constexpr const TSymbolUniqueId min_Float2_Float2 = TSymbolUniqueId(198);
+ static constexpr const TSymbolUniqueId min_Float3_Float3 = TSymbolUniqueId(199);
+ static constexpr const TSymbolUniqueId min_Float4_Float4 = TSymbolUniqueId(200);
+ static constexpr const TSymbolUniqueId min_Double1_Double1 = TSymbolUniqueId(201);
+ static constexpr const TSymbolUniqueId min_Double2_Double2 = TSymbolUniqueId(202);
+ static constexpr const TSymbolUniqueId min_Double3_Double3 = TSymbolUniqueId(203);
+ static constexpr const TSymbolUniqueId min_Double4_Double4 = TSymbolUniqueId(204);
+ static constexpr const TSymbolUniqueId min_Double2_Double1 = TSymbolUniqueId(205);
+ static constexpr const TSymbolUniqueId min_Double3_Double1 = TSymbolUniqueId(206);
+ static constexpr const TSymbolUniqueId min_Double4_Double1 = TSymbolUniqueId(207);
+ static constexpr const TSymbolUniqueId min_Int1_Int1 = TSymbolUniqueId(208);
+ static constexpr const TSymbolUniqueId min_Int2_Int2 = TSymbolUniqueId(209);
+ static constexpr const TSymbolUniqueId min_Int3_Int3 = TSymbolUniqueId(210);
+ static constexpr const TSymbolUniqueId min_Int4_Int4 = TSymbolUniqueId(211);
+ static constexpr const TSymbolUniqueId min_Int2_Int1 = TSymbolUniqueId(212);
+ static constexpr const TSymbolUniqueId min_Int3_Int1 = TSymbolUniqueId(213);
+ static constexpr const TSymbolUniqueId min_Int4_Int1 = TSymbolUniqueId(214);
+ static constexpr const TSymbolUniqueId min_UInt1_UInt1 = TSymbolUniqueId(215);
+ static constexpr const TSymbolUniqueId pt00E = TSymbolUniqueId(216);
+ static constexpr const TSymbolUniqueId min_UInt2_UInt2 = TSymbolUniqueId(217);
+ static constexpr const TSymbolUniqueId pt10E = TSymbolUniqueId(218);
+ static constexpr const TSymbolUniqueId min_UInt3_UInt3 = TSymbolUniqueId(219);
+ static constexpr const TSymbolUniqueId pt20E = TSymbolUniqueId(220);
+ static constexpr const TSymbolUniqueId min_UInt4_UInt4 = TSymbolUniqueId(221);
+ static constexpr const TSymbolUniqueId pt30E = TSymbolUniqueId(222);
+ static constexpr const TSymbolUniqueId min_UInt2_UInt1 = TSymbolUniqueId(223);
+ static constexpr const TSymbolUniqueId min_UInt3_UInt1 = TSymbolUniqueId(224);
+ static constexpr const TSymbolUniqueId min_UInt4_UInt1 = TSymbolUniqueId(225);
+ static constexpr const TSymbolUniqueId max_Float1_Float1 = TSymbolUniqueId(226);
+ static constexpr const TSymbolUniqueId max_Float2_Float1 = TSymbolUniqueId(227);
+ static constexpr const TSymbolUniqueId max_Float3_Float1 = TSymbolUniqueId(228);
+ static constexpr const TSymbolUniqueId max_Float4_Float1 = TSymbolUniqueId(229);
+ static constexpr const TSymbolUniqueId max_Float2_Float2 = TSymbolUniqueId(230);
+ static constexpr const TSymbolUniqueId max_Float3_Float3 = TSymbolUniqueId(231);
+ static constexpr const TSymbolUniqueId max_Float4_Float4 = TSymbolUniqueId(232);
+ static constexpr const TSymbolUniqueId max_Double1_Double1 = TSymbolUniqueId(233);
+ static constexpr const TSymbolUniqueId max_Double2_Double2 = TSymbolUniqueId(234);
+ static constexpr const TSymbolUniqueId max_Double3_Double3 = TSymbolUniqueId(235);
+ static constexpr const TSymbolUniqueId max_Double4_Double4 = TSymbolUniqueId(236);
+ static constexpr const TSymbolUniqueId max_Double2_Double1 = TSymbolUniqueId(237);
+ static constexpr const TSymbolUniqueId max_Double3_Double1 = TSymbolUniqueId(238);
+ static constexpr const TSymbolUniqueId max_Double4_Double1 = TSymbolUniqueId(239);
+ static constexpr const TSymbolUniqueId max_Int1_Int1 = TSymbolUniqueId(240);
+ static constexpr const TSymbolUniqueId max_Int2_Int2 = TSymbolUniqueId(241);
+ static constexpr const TSymbolUniqueId max_Int3_Int3 = TSymbolUniqueId(242);
+ static constexpr const TSymbolUniqueId max_Int4_Int4 = TSymbolUniqueId(243);
+ static constexpr const TSymbolUniqueId max_Int2_Int1 = TSymbolUniqueId(244);
+ static constexpr const TSymbolUniqueId max_Int3_Int1 = TSymbolUniqueId(245);
+ static constexpr const TSymbolUniqueId max_Int4_Int1 = TSymbolUniqueId(246);
+ static constexpr const TSymbolUniqueId max_UInt1_UInt1 = TSymbolUniqueId(247);
+ static constexpr const TSymbolUniqueId max_UInt2_UInt2 = TSymbolUniqueId(248);
+ static constexpr const TSymbolUniqueId max_UInt3_UInt3 = TSymbolUniqueId(249);
+ static constexpr const TSymbolUniqueId max_UInt4_UInt4 = TSymbolUniqueId(250);
+ static constexpr const TSymbolUniqueId max_UInt2_UInt1 = TSymbolUniqueId(251);
+ static constexpr const TSymbolUniqueId max_UInt3_UInt1 = TSymbolUniqueId(252);
+ static constexpr const TSymbolUniqueId max_UInt4_UInt1 = TSymbolUniqueId(253);
+ static constexpr const TSymbolUniqueId clamp_Float1_Float1_Float1 = TSymbolUniqueId(254);
+ static constexpr const TSymbolUniqueId clamp_Float2_Float1_Float1 = TSymbolUniqueId(255);
+ static constexpr const TSymbolUniqueId clamp_Float3_Float1_Float1 = TSymbolUniqueId(256);
+ static constexpr const TSymbolUniqueId clamp_Float4_Float1_Float1 = TSymbolUniqueId(257);
+ static constexpr const TSymbolUniqueId clamp_Float2_Float2_Float2 = TSymbolUniqueId(258);
+ static constexpr const TSymbolUniqueId clamp_Float3_Float3_Float3 = TSymbolUniqueId(259);
+ static constexpr const TSymbolUniqueId clamp_Float4_Float4_Float4 = TSymbolUniqueId(260);
+ static constexpr const TSymbolUniqueId clamp_Double1_Double1_Double1 = TSymbolUniqueId(261);
+ static constexpr const TSymbolUniqueId clamp_Double2_Double1_Double1 = TSymbolUniqueId(262);
+ static constexpr const TSymbolUniqueId clamp_Double3_Double1_Double1 = TSymbolUniqueId(263);
+ static constexpr const TSymbolUniqueId clamp_Double4_Double1_Double1 = TSymbolUniqueId(264);
+ static constexpr const TSymbolUniqueId clamp_Double2_Double2_Double2 = TSymbolUniqueId(265);
+ static constexpr const TSymbolUniqueId clamp_Double3_Double3_Double3 = TSymbolUniqueId(266);
+ static constexpr const TSymbolUniqueId clamp_Double4_Double4_Double4 = TSymbolUniqueId(267);
+ static constexpr const TSymbolUniqueId clamp_Int1_Int1_Int1 = TSymbolUniqueId(268);
+ static constexpr const TSymbolUniqueId clamp_Int2_Int1_Int1 = TSymbolUniqueId(269);
+ static constexpr const TSymbolUniqueId clamp_Int3_Int1_Int1 = TSymbolUniqueId(270);
+ static constexpr const TSymbolUniqueId clamp_Int4_Int1_Int1 = TSymbolUniqueId(271);
+ static constexpr const TSymbolUniqueId clamp_Int2_Int2_Int2 = TSymbolUniqueId(272);
+ static constexpr const TSymbolUniqueId clamp_Int3_Int3_Int3 = TSymbolUniqueId(273);
+ static constexpr const TSymbolUniqueId clamp_Int4_Int4_Int4 = TSymbolUniqueId(274);
+ static constexpr const TSymbolUniqueId clamp_UInt1_UInt1_UInt1 = TSymbolUniqueId(275);
+ static constexpr const TSymbolUniqueId clamp_UInt2_UInt1_UInt1 = TSymbolUniqueId(276);
+ static constexpr const TSymbolUniqueId clamp_UInt3_UInt1_UInt1 = TSymbolUniqueId(277);
+ static constexpr const TSymbolUniqueId clamp_UInt4_UInt1_UInt1 = TSymbolUniqueId(278);
+ static constexpr const TSymbolUniqueId clamp_UInt2_UInt2_UInt2 = TSymbolUniqueId(279);
+ static constexpr const TSymbolUniqueId clamp_UInt3_UInt3_UInt3 = TSymbolUniqueId(280);
+ static constexpr const TSymbolUniqueId clamp_UInt4_UInt4_UInt4 = TSymbolUniqueId(281);
+ static constexpr const TSymbolUniqueId mix_Float1_Float1_Float1 = TSymbolUniqueId(282);
+ static constexpr const TSymbolUniqueId mix_Float2_Float2_Float1 = TSymbolUniqueId(283);
+ static constexpr const TSymbolUniqueId mix_Float3_Float3_Float1 = TSymbolUniqueId(284);
+ static constexpr const TSymbolUniqueId mix_Float4_Float4_Float1 = TSymbolUniqueId(285);
+ static constexpr const TSymbolUniqueId mix_Float2_Float2_Float2 = TSymbolUniqueId(286);
+ static constexpr const TSymbolUniqueId mix_Float3_Float3_Float3 = TSymbolUniqueId(287);
+ static constexpr const TSymbolUniqueId mix_Float4_Float4_Float4 = TSymbolUniqueId(288);
+ static constexpr const TSymbolUniqueId mix_Double1_Double1_Double1 = TSymbolUniqueId(289);
+ static constexpr const TSymbolUniqueId mix_Double2_Double2_Double1 = TSymbolUniqueId(290);
+ static constexpr const TSymbolUniqueId mix_Double3_Double3_Double1 = TSymbolUniqueId(291);
+ static constexpr const TSymbolUniqueId mix_Double4_Double4_Double1 = TSymbolUniqueId(292);
+ static constexpr const TSymbolUniqueId mix_Double2_Double2_Double2 = TSymbolUniqueId(293);
+ static constexpr const TSymbolUniqueId mix_Double3_Double3_Double3 = TSymbolUniqueId(294);
+ static constexpr const TSymbolUniqueId mix_Double4_Double4_Double4 = TSymbolUniqueId(295);
+ static constexpr const TSymbolUniqueId mix_Float1_Float1_Bool1 = TSymbolUniqueId(296);
+ static constexpr const TSymbolUniqueId pt00F = TSymbolUniqueId(297);
+ static constexpr const TSymbolUniqueId mix_Float2_Float2_Bool2 = TSymbolUniqueId(298);
+ static constexpr const TSymbolUniqueId pt10F = TSymbolUniqueId(299);
+ static constexpr const TSymbolUniqueId mix_Float3_Float3_Bool3 = TSymbolUniqueId(300);
+ static constexpr const TSymbolUniqueId pt20F = TSymbolUniqueId(301);
+ static constexpr const TSymbolUniqueId mix_Float4_Float4_Bool4 = TSymbolUniqueId(302);
+ static constexpr const TSymbolUniqueId pt30F = TSymbolUniqueId(303);
+ static constexpr const TSymbolUniqueId mix_Double1_Double1_Bool1 = TSymbolUniqueId(304);
+ static constexpr const TSymbolUniqueId mix_Double2_Double2_Bool2 = TSymbolUniqueId(305);
+ static constexpr const TSymbolUniqueId mix_Double3_Double3_Bool3 = TSymbolUniqueId(306);
+ static constexpr const TSymbolUniqueId mix_Double4_Double4_Bool4 = TSymbolUniqueId(307);
+ static constexpr const TSymbolUniqueId mix_Int1_Int1_Bool1 = TSymbolUniqueId(308);
+ static constexpr const TSymbolUniqueId mix_Int2_Int2_Bool2 = TSymbolUniqueId(309);
+ static constexpr const TSymbolUniqueId mix_Int3_Int3_Bool3 = TSymbolUniqueId(310);
+ static constexpr const TSymbolUniqueId mix_Int4_Int4_Bool4 = TSymbolUniqueId(311);
+ static constexpr const TSymbolUniqueId mix_UInt1_UInt1_Bool1 = TSymbolUniqueId(312);
+ static constexpr const TSymbolUniqueId mix_UInt2_UInt2_Bool2 = TSymbolUniqueId(313);
+ static constexpr const TSymbolUniqueId mix_UInt3_UInt3_Bool3 = TSymbolUniqueId(314);
+ static constexpr const TSymbolUniqueId mix_UInt4_UInt4_Bool4 = TSymbolUniqueId(315);
+ static constexpr const TSymbolUniqueId mix_Bool1_Bool1_Bool1 = TSymbolUniqueId(316);
+ static constexpr const TSymbolUniqueId mix_Bool2_Bool2_Bool2 = TSymbolUniqueId(317);
+ static constexpr const TSymbolUniqueId mix_Bool3_Bool3_Bool3 = TSymbolUniqueId(318);
+ static constexpr const TSymbolUniqueId mix_Bool4_Bool4_Bool4 = TSymbolUniqueId(319);
+ static constexpr const TSymbolUniqueId step_Float1_Float1 = TSymbolUniqueId(320);
+ static constexpr const TSymbolUniqueId step_Float2_Float2 = TSymbolUniqueId(321);
+ static constexpr const TSymbolUniqueId step_Float3_Float3 = TSymbolUniqueId(322);
+ static constexpr const TSymbolUniqueId step_Float4_Float4 = TSymbolUniqueId(323);
+ static constexpr const TSymbolUniqueId step_Float1_Float2 = TSymbolUniqueId(324);
+ static constexpr const TSymbolUniqueId step_Float1_Float3 = TSymbolUniqueId(325);
+ static constexpr const TSymbolUniqueId step_Float1_Float4 = TSymbolUniqueId(326);
+ static constexpr const TSymbolUniqueId step_Double1_Double1 = TSymbolUniqueId(327);
+ static constexpr const TSymbolUniqueId step_Double2_Double2 = TSymbolUniqueId(328);
+ static constexpr const TSymbolUniqueId step_Double3_Double3 = TSymbolUniqueId(329);
+ static constexpr const TSymbolUniqueId step_Double4_Double4 = TSymbolUniqueId(330);
+ static constexpr const TSymbolUniqueId step_Double1_Double2 = TSymbolUniqueId(331);
+ static constexpr const TSymbolUniqueId step_Double1_Double3 = TSymbolUniqueId(332);
+ static constexpr const TSymbolUniqueId step_Double1_Double4 = TSymbolUniqueId(333);
+ static constexpr const TSymbolUniqueId smoothstep_Double1_Double1_Double1 =
+ TSymbolUniqueId(334);
+ static constexpr const TSymbolUniqueId smoothstep_Double2_Double2_Double2 =
+ TSymbolUniqueId(335);
+ static constexpr const TSymbolUniqueId smoothstep_Double3_Double3_Double3 =
+ TSymbolUniqueId(336);
+ static constexpr const TSymbolUniqueId smoothstep_Double4_Double4_Double4 =
+ TSymbolUniqueId(337);
+ static constexpr const TSymbolUniqueId smoothstep_Double1_Double1_Double2 =
+ TSymbolUniqueId(338);
+ static constexpr const TSymbolUniqueId smoothstep_Double1_Double1_Double3 =
+ TSymbolUniqueId(339);
+ static constexpr const TSymbolUniqueId smoothstep_Double1_Double1_Double4 =
+ TSymbolUniqueId(340);
+ static constexpr const TSymbolUniqueId smoothstep_Float1_Float1_Float1 = TSymbolUniqueId(341);
+ static constexpr const TSymbolUniqueId smoothstep_Float2_Float2_Float2 = TSymbolUniqueId(342);
+ static constexpr const TSymbolUniqueId smoothstep_Float3_Float3_Float3 = TSymbolUniqueId(343);
+ static constexpr const TSymbolUniqueId smoothstep_Float4_Float4_Float4 = TSymbolUniqueId(344);
+ static constexpr const TSymbolUniqueId smoothstep_Float1_Float1_Float2 = TSymbolUniqueId(345);
+ static constexpr const TSymbolUniqueId smoothstep_Float1_Float1_Float3 = TSymbolUniqueId(346);
+ static constexpr const TSymbolUniqueId smoothstep_Float1_Float1_Float4 = TSymbolUniqueId(347);
+ static constexpr const TSymbolUniqueId modf_Float1_Float1 = TSymbolUniqueId(348);
+ static constexpr const TSymbolUniqueId pt_o_00B = TSymbolUniqueId(349);
+ static constexpr const TSymbolUniqueId modf_Float2_Float2 = TSymbolUniqueId(350);
+ static constexpr const TSymbolUniqueId pt_o_10B = TSymbolUniqueId(351);
+ static constexpr const TSymbolUniqueId modf_Float3_Float3 = TSymbolUniqueId(352);
+ static constexpr const TSymbolUniqueId pt_o_20B = TSymbolUniqueId(353);
+ static constexpr const TSymbolUniqueId modf_Float4_Float4 = TSymbolUniqueId(354);
+ static constexpr const TSymbolUniqueId pt_o_30B = TSymbolUniqueId(355);
+ static constexpr const TSymbolUniqueId modf_Double1_Double1 = TSymbolUniqueId(356);
+ static constexpr const TSymbolUniqueId pt_o_00C = TSymbolUniqueId(357);
+ static constexpr const TSymbolUniqueId modf_Double2_Double2 = TSymbolUniqueId(358);
+ static constexpr const TSymbolUniqueId pt_o_10C = TSymbolUniqueId(359);
+ static constexpr const TSymbolUniqueId modf_Double3_Double3 = TSymbolUniqueId(360);
+ static constexpr const TSymbolUniqueId pt_o_20C = TSymbolUniqueId(361);
+ static constexpr const TSymbolUniqueId modf_Double4_Double4 = TSymbolUniqueId(362);
+ static constexpr const TSymbolUniqueId pt_o_30C = TSymbolUniqueId(363);
+ static constexpr const TSymbolUniqueId isnan_Float1 = TSymbolUniqueId(364);
+ static constexpr const TSymbolUniqueId isnan_Float2 = TSymbolUniqueId(365);
+ static constexpr const TSymbolUniqueId isnan_Float3 = TSymbolUniqueId(366);
+ static constexpr const TSymbolUniqueId isnan_Float4 = TSymbolUniqueId(367);
+ static constexpr const TSymbolUniqueId isnan_Double1 = TSymbolUniqueId(368);
+ static constexpr const TSymbolUniqueId isnan_Double2 = TSymbolUniqueId(369);
+ static constexpr const TSymbolUniqueId isnan_Double3 = TSymbolUniqueId(370);
+ static constexpr const TSymbolUniqueId isnan_Double4 = TSymbolUniqueId(371);
+ static constexpr const TSymbolUniqueId isinf_Float1 = TSymbolUniqueId(372);
+ static constexpr const TSymbolUniqueId isinf_Float2 = TSymbolUniqueId(373);
+ static constexpr const TSymbolUniqueId isinf_Float3 = TSymbolUniqueId(374);
+ static constexpr const TSymbolUniqueId isinf_Float4 = TSymbolUniqueId(375);
+ static constexpr const TSymbolUniqueId isinf_Double1 = TSymbolUniqueId(376);
+ static constexpr const TSymbolUniqueId isinf_Double2 = TSymbolUniqueId(377);
+ static constexpr const TSymbolUniqueId isinf_Double3 = TSymbolUniqueId(378);
+ static constexpr const TSymbolUniqueId isinf_Double4 = TSymbolUniqueId(379);
+ static constexpr const TSymbolUniqueId floatBitsToInt_Float1 = TSymbolUniqueId(380);
+ static constexpr const TSymbolUniqueId floatBitsToInt_Float2 = TSymbolUniqueId(381);
+ static constexpr const TSymbolUniqueId floatBitsToInt_Float3 = TSymbolUniqueId(382);
+ static constexpr const TSymbolUniqueId floatBitsToInt_Float4 = TSymbolUniqueId(383);
+ static constexpr const TSymbolUniqueId floatBitsToUint_Float1 = TSymbolUniqueId(384);
+ static constexpr const TSymbolUniqueId floatBitsToUint_Float2 = TSymbolUniqueId(385);
+ static constexpr const TSymbolUniqueId floatBitsToUint_Float3 = TSymbolUniqueId(386);
+ static constexpr const TSymbolUniqueId floatBitsToUint_Float4 = TSymbolUniqueId(387);
+ static constexpr const TSymbolUniqueId intBitsToFloat_Int1 = TSymbolUniqueId(388);
+ static constexpr const TSymbolUniqueId intBitsToFloat_Int2 = TSymbolUniqueId(389);
+ static constexpr const TSymbolUniqueId intBitsToFloat_Int3 = TSymbolUniqueId(390);
+ static constexpr const TSymbolUniqueId intBitsToFloat_Int4 = TSymbolUniqueId(391);
+ static constexpr const TSymbolUniqueId uintBitsToFloat_UInt1 = TSymbolUniqueId(392);
+ static constexpr const TSymbolUniqueId uintBitsToFloat_UInt2 = TSymbolUniqueId(393);
+ static constexpr const TSymbolUniqueId uintBitsToFloat_UInt3 = TSymbolUniqueId(394);
+ static constexpr const TSymbolUniqueId uintBitsToFloat_UInt4 = TSymbolUniqueId(395);
+ static constexpr const TSymbolUniqueId fma_Float1_Float1_Float1 = TSymbolUniqueId(396);
+ static constexpr const TSymbolUniqueId fma_Float2_Float2_Float2 = TSymbolUniqueId(397);
+ static constexpr const TSymbolUniqueId fma_Float3_Float3_Float3 = TSymbolUniqueId(398);
+ static constexpr const TSymbolUniqueId fma_Float4_Float4_Float4 = TSymbolUniqueId(399);
+ static constexpr const TSymbolUniqueId fmaExt_Float1_Float1_Float1 = TSymbolUniqueId(400);
+ static constexpr const TSymbolUniqueId fmaExt_Float2_Float2_Float2 = TSymbolUniqueId(401);
+ static constexpr const TSymbolUniqueId fmaExt_Float3_Float3_Float3 = TSymbolUniqueId(402);
+ static constexpr const TSymbolUniqueId fmaExt_Float4_Float4_Float4 = TSymbolUniqueId(403);
+ static constexpr const TSymbolUniqueId fma_Double1_Double1_Double1 = TSymbolUniqueId(404);
+ static constexpr const TSymbolUniqueId fma_Double2_Double2_Double2 = TSymbolUniqueId(405);
+ static constexpr const TSymbolUniqueId fma_Double3_Double3_Double3 = TSymbolUniqueId(406);
+ static constexpr const TSymbolUniqueId fma_Double4_Double4_Double4 = TSymbolUniqueId(407);
+ static constexpr const TSymbolUniqueId frexp_Float1_Int1 = TSymbolUniqueId(408);
+ static constexpr const TSymbolUniqueId pt_o_00D = TSymbolUniqueId(409);
+ static constexpr const TSymbolUniqueId frexp_Float2_Int2 = TSymbolUniqueId(410);
+ static constexpr const TSymbolUniqueId pt_o_10D = TSymbolUniqueId(411);
+ static constexpr const TSymbolUniqueId frexp_Float3_Int3 = TSymbolUniqueId(412);
+ static constexpr const TSymbolUniqueId pt_o_20D = TSymbolUniqueId(413);
+ static constexpr const TSymbolUniqueId frexp_Float4_Int4 = TSymbolUniqueId(414);
+ static constexpr const TSymbolUniqueId pt_o_30D = TSymbolUniqueId(415);
+ static constexpr const TSymbolUniqueId frexp_Double1_Int1 = TSymbolUniqueId(416);
+ static constexpr const TSymbolUniqueId frexp_Double2_Int2 = TSymbolUniqueId(417);
+ static constexpr const TSymbolUniqueId frexp_Double3_Int3 = TSymbolUniqueId(418);
+ static constexpr const TSymbolUniqueId frexp_Double4_Int4 = TSymbolUniqueId(419);
+ static constexpr const TSymbolUniqueId ldexp_Float1_Int1 = TSymbolUniqueId(420);
+ static constexpr const TSymbolUniqueId ldexp_Float2_Int2 = TSymbolUniqueId(421);
+ static constexpr const TSymbolUniqueId ldexp_Float3_Int3 = TSymbolUniqueId(422);
+ static constexpr const TSymbolUniqueId ldexp_Float4_Int4 = TSymbolUniqueId(423);
+ static constexpr const TSymbolUniqueId ldexp_Double1_Int1 = TSymbolUniqueId(424);
+ static constexpr const TSymbolUniqueId ldexp_Double2_Int2 = TSymbolUniqueId(425);
+ static constexpr const TSymbolUniqueId ldexp_Double3_Int3 = TSymbolUniqueId(426);
+ static constexpr const TSymbolUniqueId ldexp_Double4_Int4 = TSymbolUniqueId(427);
+ static constexpr const TSymbolUniqueId packSnorm2x16_Float2 = TSymbolUniqueId(428);
+ static constexpr const TSymbolUniqueId packHalf2x16_Float2 = TSymbolUniqueId(429);
+ static constexpr const TSymbolUniqueId unpackSnorm2x16_UInt1 = TSymbolUniqueId(430);
+ static constexpr const TSymbolUniqueId unpackHalf2x16_UInt1 = TSymbolUniqueId(431);
+ static constexpr const TSymbolUniqueId packUnorm2x16_Float2 = TSymbolUniqueId(432);
+ static constexpr const TSymbolUniqueId unpackUnorm2x16_UInt1 = TSymbolUniqueId(433);
+ static constexpr const TSymbolUniqueId packUnorm4x8_Float4 = TSymbolUniqueId(434);
+ static constexpr const TSymbolUniqueId packSnorm4x8_Float4 = TSymbolUniqueId(435);
+ static constexpr const TSymbolUniqueId unpackUnorm4x8_UInt1 = TSymbolUniqueId(436);
+ static constexpr const TSymbolUniqueId unpackSnorm4x8_UInt1 = TSymbolUniqueId(437);
+ static constexpr const TSymbolUniqueId packDouble2x32_UInt2 = TSymbolUniqueId(438);
+ static constexpr const TSymbolUniqueId unpackDouble2x32_Double1 = TSymbolUniqueId(439);
+ static constexpr const TSymbolUniqueId length_Float1 = TSymbolUniqueId(440);
+ static constexpr const TSymbolUniqueId length_Float2 = TSymbolUniqueId(441);
+ static constexpr const TSymbolUniqueId length_Float3 = TSymbolUniqueId(442);
+ static constexpr const TSymbolUniqueId length_Float4 = TSymbolUniqueId(443);
+ static constexpr const TSymbolUniqueId length_Double1 = TSymbolUniqueId(444);
+ static constexpr const TSymbolUniqueId length_Double2 = TSymbolUniqueId(445);
+ static constexpr const TSymbolUniqueId length_Double3 = TSymbolUniqueId(446);
+ static constexpr const TSymbolUniqueId length_Double4 = TSymbolUniqueId(447);
+ static constexpr const TSymbolUniqueId distance_Float1_Float1 = TSymbolUniqueId(448);
+ static constexpr const TSymbolUniqueId distance_Float2_Float2 = TSymbolUniqueId(449);
+ static constexpr const TSymbolUniqueId distance_Float3_Float3 = TSymbolUniqueId(450);
+ static constexpr const TSymbolUniqueId distance_Float4_Float4 = TSymbolUniqueId(451);
+ static constexpr const TSymbolUniqueId distance_Double1_Double1 = TSymbolUniqueId(452);
+ static constexpr const TSymbolUniqueId distance_Double2_Double2 = TSymbolUniqueId(453);
+ static constexpr const TSymbolUniqueId distance_Double3_Double3 = TSymbolUniqueId(454);
+ static constexpr const TSymbolUniqueId distance_Double4_Double4 = TSymbolUniqueId(455);
+ static constexpr const TSymbolUniqueId dot_Float1_Float1 = TSymbolUniqueId(456);
+ static constexpr const TSymbolUniqueId dot_Float2_Float2 = TSymbolUniqueId(457);
+ static constexpr const TSymbolUniqueId dot_Float3_Float3 = TSymbolUniqueId(458);
+ static constexpr const TSymbolUniqueId dot_Float4_Float4 = TSymbolUniqueId(459);
+ static constexpr const TSymbolUniqueId dot_Double1_Double1 = TSymbolUniqueId(460);
+ static constexpr const TSymbolUniqueId dot_Double2_Double2 = TSymbolUniqueId(461);
+ static constexpr const TSymbolUniqueId dot_Double3_Double3 = TSymbolUniqueId(462);
+ static constexpr const TSymbolUniqueId dot_Double4_Double4 = TSymbolUniqueId(463);
+ static constexpr const TSymbolUniqueId cross_Float3_Float3 = TSymbolUniqueId(464);
+ static constexpr const TSymbolUniqueId cross_Double3_Double3 = TSymbolUniqueId(465);
+ static constexpr const TSymbolUniqueId normalize_Float1 = TSymbolUniqueId(466);
+ static constexpr const TSymbolUniqueId normalize_Float2 = TSymbolUniqueId(467);
+ static constexpr const TSymbolUniqueId normalize_Float3 = TSymbolUniqueId(468);
+ static constexpr const TSymbolUniqueId normalize_Float4 = TSymbolUniqueId(469);
+ static constexpr const TSymbolUniqueId normalize_Double1 = TSymbolUniqueId(470);
+ static constexpr const TSymbolUniqueId normalize_Double2 = TSymbolUniqueId(471);
+ static constexpr const TSymbolUniqueId normalize_Double3 = TSymbolUniqueId(472);
+ static constexpr const TSymbolUniqueId normalize_Double4 = TSymbolUniqueId(473);
+ static constexpr const TSymbolUniqueId faceforward_Float1_Float1_Float1 = TSymbolUniqueId(474);
+ static constexpr const TSymbolUniqueId faceforward_Float2_Float2_Float2 = TSymbolUniqueId(475);
+ static constexpr const TSymbolUniqueId faceforward_Float3_Float3_Float3 = TSymbolUniqueId(476);
+ static constexpr const TSymbolUniqueId faceforward_Float4_Float4_Float4 = TSymbolUniqueId(477);
+ static constexpr const TSymbolUniqueId faceforward_Double1_Double1_Double1 =
+ TSymbolUniqueId(478);
+ static constexpr const TSymbolUniqueId faceforward_Double2_Double2_Double2 =
+ TSymbolUniqueId(479);
+ static constexpr const TSymbolUniqueId faceforward_Double3_Double3_Double3 =
+ TSymbolUniqueId(480);
+ static constexpr const TSymbolUniqueId faceforward_Double4_Double4_Double4 =
+ TSymbolUniqueId(481);
+ static constexpr const TSymbolUniqueId reflect_Float1_Float1 = TSymbolUniqueId(482);
+ static constexpr const TSymbolUniqueId reflect_Float2_Float2 = TSymbolUniqueId(483);
+ static constexpr const TSymbolUniqueId reflect_Float3_Float3 = TSymbolUniqueId(484);
+ static constexpr const TSymbolUniqueId reflect_Float4_Float4 = TSymbolUniqueId(485);
+ static constexpr const TSymbolUniqueId reflect_Double1_Double1 = TSymbolUniqueId(486);
+ static constexpr const TSymbolUniqueId reflect_Double2_Double2 = TSymbolUniqueId(487);
+ static constexpr const TSymbolUniqueId reflect_Double3_Double3 = TSymbolUniqueId(488);
+ static constexpr const TSymbolUniqueId reflect_Double4_Double4 = TSymbolUniqueId(489);
+ static constexpr const TSymbolUniqueId refract_Float1_Float1_Float1 = TSymbolUniqueId(490);
+ static constexpr const TSymbolUniqueId refract_Float2_Float2_Float1 = TSymbolUniqueId(491);
+ static constexpr const TSymbolUniqueId refract_Float3_Float3_Float1 = TSymbolUniqueId(492);
+ static constexpr const TSymbolUniqueId refract_Float4_Float4_Float1 = TSymbolUniqueId(493);
+ static constexpr const TSymbolUniqueId refract_Double1_Double1_Float1 = TSymbolUniqueId(494);
+ static constexpr const TSymbolUniqueId refract_Double2_Double2_Float1 = TSymbolUniqueId(495);
+ static constexpr const TSymbolUniqueId refract_Double3_Double3_Float1 = TSymbolUniqueId(496);
+ static constexpr const TSymbolUniqueId refract_Double4_Double4_Float1 = TSymbolUniqueId(497);
+ static constexpr const TSymbolUniqueId ftransform = TSymbolUniqueId(498);
+ static constexpr const TSymbolUniqueId matrixCompMult_Float2x2_Float2x2 = TSymbolUniqueId(499);
+ static constexpr const TSymbolUniqueId pt50B = TSymbolUniqueId(500);
+ static constexpr const TSymbolUniqueId matrixCompMult_Float3x3_Float3x3 = TSymbolUniqueId(501);
+ static constexpr const TSymbolUniqueId ptA0B = TSymbolUniqueId(502);
+ static constexpr const TSymbolUniqueId matrixCompMult_Float4x4_Float4x4 = TSymbolUniqueId(503);
+ static constexpr const TSymbolUniqueId ptF0B = TSymbolUniqueId(504);
+ static constexpr const TSymbolUniqueId matrixCompMult_Float2x3_Float2x3 = TSymbolUniqueId(505);
+ static constexpr const TSymbolUniqueId pt90B = TSymbolUniqueId(506);
+ static constexpr const TSymbolUniqueId matrixCompMult_Float3x2_Float3x2 = TSymbolUniqueId(507);
+ static constexpr const TSymbolUniqueId pt60B = TSymbolUniqueId(508);
+ static constexpr const TSymbolUniqueId matrixCompMult_Float2x4_Float2x4 = TSymbolUniqueId(509);
+ static constexpr const TSymbolUniqueId ptD0B = TSymbolUniqueId(510);
+ static constexpr const TSymbolUniqueId matrixCompMult_Float4x2_Float4x2 = TSymbolUniqueId(511);
+ static constexpr const TSymbolUniqueId pt70B = TSymbolUniqueId(512);
+ static constexpr const TSymbolUniqueId matrixCompMult_Float3x4_Float3x4 = TSymbolUniqueId(513);
+ static constexpr const TSymbolUniqueId ptE0B = TSymbolUniqueId(514);
+ static constexpr const TSymbolUniqueId matrixCompMult_Float4x3_Float4x3 = TSymbolUniqueId(515);
+ static constexpr const TSymbolUniqueId ptB0B = TSymbolUniqueId(516);
+ static constexpr const TSymbolUniqueId outerProduct_Float2_Float2 = TSymbolUniqueId(517);
+ static constexpr const TSymbolUniqueId outerProduct_Float3_Float3 = TSymbolUniqueId(518);
+ static constexpr const TSymbolUniqueId outerProduct_Float4_Float4 = TSymbolUniqueId(519);
+ static constexpr const TSymbolUniqueId outerProduct_Float3_Float2 = TSymbolUniqueId(520);
+ static constexpr const TSymbolUniqueId outerProduct_Float2_Float3 = TSymbolUniqueId(521);
+ static constexpr const TSymbolUniqueId outerProduct_Float4_Float2 = TSymbolUniqueId(522);
+ static constexpr const TSymbolUniqueId outerProduct_Float2_Float4 = TSymbolUniqueId(523);
+ static constexpr const TSymbolUniqueId outerProduct_Float4_Float3 = TSymbolUniqueId(524);
+ static constexpr const TSymbolUniqueId outerProduct_Float3_Float4 = TSymbolUniqueId(525);
+ static constexpr const TSymbolUniqueId transpose_Float2x2 = TSymbolUniqueId(526);
+ static constexpr const TSymbolUniqueId transpose_Float3x3 = TSymbolUniqueId(527);
+ static constexpr const TSymbolUniqueId transpose_Float4x4 = TSymbolUniqueId(528);
+ static constexpr const TSymbolUniqueId transpose_Float3x2 = TSymbolUniqueId(529);
+ static constexpr const TSymbolUniqueId transpose_Float2x3 = TSymbolUniqueId(530);
+ static constexpr const TSymbolUniqueId transpose_Float4x2 = TSymbolUniqueId(531);
+ static constexpr const TSymbolUniqueId transpose_Float2x4 = TSymbolUniqueId(532);
+ static constexpr const TSymbolUniqueId transpose_Float4x3 = TSymbolUniqueId(533);
+ static constexpr const TSymbolUniqueId transpose_Float3x4 = TSymbolUniqueId(534);
+ static constexpr const TSymbolUniqueId determinant_Float2x2 = TSymbolUniqueId(535);
+ static constexpr const TSymbolUniqueId determinant_Float3x3 = TSymbolUniqueId(536);
+ static constexpr const TSymbolUniqueId determinant_Float4x4 = TSymbolUniqueId(537);
+ static constexpr const TSymbolUniqueId inverse_Float2x2 = TSymbolUniqueId(538);
+ static constexpr const TSymbolUniqueId inverse_Float3x3 = TSymbolUniqueId(539);
+ static constexpr const TSymbolUniqueId inverse_Float4x4 = TSymbolUniqueId(540);
+ static constexpr const TSymbolUniqueId lessThan_Float2_Float2 = TSymbolUniqueId(541);
+ static constexpr const TSymbolUniqueId lessThan_Float3_Float3 = TSymbolUniqueId(542);
+ static constexpr const TSymbolUniqueId lessThan_Float4_Float4 = TSymbolUniqueId(543);
+ static constexpr const TSymbolUniqueId lessThan_Int2_Int2 = TSymbolUniqueId(544);
+ static constexpr const TSymbolUniqueId lessThan_Int3_Int3 = TSymbolUniqueId(545);
+ static constexpr const TSymbolUniqueId lessThan_Int4_Int4 = TSymbolUniqueId(546);
+ static constexpr const TSymbolUniqueId lessThan_UInt2_UInt2 = TSymbolUniqueId(547);
+ static constexpr const TSymbolUniqueId lessThan_UInt3_UInt3 = TSymbolUniqueId(548);
+ static constexpr const TSymbolUniqueId lessThan_UInt4_UInt4 = TSymbolUniqueId(549);
+ static constexpr const TSymbolUniqueId lessThanEqual_Float2_Float2 = TSymbolUniqueId(550);
+ static constexpr const TSymbolUniqueId lessThanEqual_Float3_Float3 = TSymbolUniqueId(551);
+ static constexpr const TSymbolUniqueId lessThanEqual_Float4_Float4 = TSymbolUniqueId(552);
+ static constexpr const TSymbolUniqueId lessThanEqual_Int2_Int2 = TSymbolUniqueId(553);
+ static constexpr const TSymbolUniqueId lessThanEqual_Int3_Int3 = TSymbolUniqueId(554);
+ static constexpr const TSymbolUniqueId lessThanEqual_Int4_Int4 = TSymbolUniqueId(555);
+ static constexpr const TSymbolUniqueId lessThanEqual_UInt2_UInt2 = TSymbolUniqueId(556);
+ static constexpr const TSymbolUniqueId lessThanEqual_UInt3_UInt3 = TSymbolUniqueId(557);
+ static constexpr const TSymbolUniqueId lessThanEqual_UInt4_UInt4 = TSymbolUniqueId(558);
+ static constexpr const TSymbolUniqueId greaterThan_Float2_Float2 = TSymbolUniqueId(559);
+ static constexpr const TSymbolUniqueId greaterThan_Float3_Float3 = TSymbolUniqueId(560);
+ static constexpr const TSymbolUniqueId greaterThan_Float4_Float4 = TSymbolUniqueId(561);
+ static constexpr const TSymbolUniqueId greaterThan_Int2_Int2 = TSymbolUniqueId(562);
+ static constexpr const TSymbolUniqueId greaterThan_Int3_Int3 = TSymbolUniqueId(563);
+ static constexpr const TSymbolUniqueId greaterThan_Int4_Int4 = TSymbolUniqueId(564);
+ static constexpr const TSymbolUniqueId greaterThan_UInt2_UInt2 = TSymbolUniqueId(565);
+ static constexpr const TSymbolUniqueId greaterThan_UInt3_UInt3 = TSymbolUniqueId(566);
+ static constexpr const TSymbolUniqueId greaterThan_UInt4_UInt4 = TSymbolUniqueId(567);
+ static constexpr const TSymbolUniqueId greaterThanEqual_Float2_Float2 = TSymbolUniqueId(568);
+ static constexpr const TSymbolUniqueId greaterThanEqual_Float3_Float3 = TSymbolUniqueId(569);
+ static constexpr const TSymbolUniqueId greaterThanEqual_Float4_Float4 = TSymbolUniqueId(570);
+ static constexpr const TSymbolUniqueId greaterThanEqual_Int2_Int2 = TSymbolUniqueId(571);
+ static constexpr const TSymbolUniqueId greaterThanEqual_Int3_Int3 = TSymbolUniqueId(572);
+ static constexpr const TSymbolUniqueId greaterThanEqual_Int4_Int4 = TSymbolUniqueId(573);
+ static constexpr const TSymbolUniqueId greaterThanEqual_UInt2_UInt2 = TSymbolUniqueId(574);
+ static constexpr const TSymbolUniqueId greaterThanEqual_UInt3_UInt3 = TSymbolUniqueId(575);
+ static constexpr const TSymbolUniqueId greaterThanEqual_UInt4_UInt4 = TSymbolUniqueId(576);
+ static constexpr const TSymbolUniqueId equal_Float2_Float2 = TSymbolUniqueId(577);
+ static constexpr const TSymbolUniqueId equal_Float3_Float3 = TSymbolUniqueId(578);
+ static constexpr const TSymbolUniqueId equal_Float4_Float4 = TSymbolUniqueId(579);
+ static constexpr const TSymbolUniqueId equal_Int2_Int2 = TSymbolUniqueId(580);
+ static constexpr const TSymbolUniqueId equal_Int3_Int3 = TSymbolUniqueId(581);
+ static constexpr const TSymbolUniqueId equal_Int4_Int4 = TSymbolUniqueId(582);
+ static constexpr const TSymbolUniqueId equal_UInt2_UInt2 = TSymbolUniqueId(583);
+ static constexpr const TSymbolUniqueId equal_UInt3_UInt3 = TSymbolUniqueId(584);
+ static constexpr const TSymbolUniqueId equal_UInt4_UInt4 = TSymbolUniqueId(585);
+ static constexpr const TSymbolUniqueId equal_Bool2_Bool2 = TSymbolUniqueId(586);
+ static constexpr const TSymbolUniqueId equal_Bool3_Bool3 = TSymbolUniqueId(587);
+ static constexpr const TSymbolUniqueId equal_Bool4_Bool4 = TSymbolUniqueId(588);
+ static constexpr const TSymbolUniqueId notEqual_Float2_Float2 = TSymbolUniqueId(589);
+ static constexpr const TSymbolUniqueId notEqual_Float3_Float3 = TSymbolUniqueId(590);
+ static constexpr const TSymbolUniqueId notEqual_Float4_Float4 = TSymbolUniqueId(591);
+ static constexpr const TSymbolUniqueId notEqual_Int2_Int2 = TSymbolUniqueId(592);
+ static constexpr const TSymbolUniqueId notEqual_Int3_Int3 = TSymbolUniqueId(593);
+ static constexpr const TSymbolUniqueId notEqual_Int4_Int4 = TSymbolUniqueId(594);
+ static constexpr const TSymbolUniqueId notEqual_UInt2_UInt2 = TSymbolUniqueId(595);
+ static constexpr const TSymbolUniqueId notEqual_UInt3_UInt3 = TSymbolUniqueId(596);
+ static constexpr const TSymbolUniqueId notEqual_UInt4_UInt4 = TSymbolUniqueId(597);
+ static constexpr const TSymbolUniqueId notEqual_Bool2_Bool2 = TSymbolUniqueId(598);
+ static constexpr const TSymbolUniqueId notEqual_Bool3_Bool3 = TSymbolUniqueId(599);
+ static constexpr const TSymbolUniqueId notEqual_Bool4_Bool4 = TSymbolUniqueId(600);
+ static constexpr const TSymbolUniqueId any_Bool2 = TSymbolUniqueId(601);
+ static constexpr const TSymbolUniqueId any_Bool3 = TSymbolUniqueId(602);
+ static constexpr const TSymbolUniqueId any_Bool4 = TSymbolUniqueId(603);
+ static constexpr const TSymbolUniqueId all_Bool2 = TSymbolUniqueId(604);
+ static constexpr const TSymbolUniqueId all_Bool3 = TSymbolUniqueId(605);
+ static constexpr const TSymbolUniqueId all_Bool4 = TSymbolUniqueId(606);
+ static constexpr const TSymbolUniqueId notFunc_Bool2 = TSymbolUniqueId(607);
+ static constexpr const TSymbolUniqueId notFunc_Bool3 = TSymbolUniqueId(608);
+ static constexpr const TSymbolUniqueId notFunc_Bool4 = TSymbolUniqueId(609);
+ static constexpr const TSymbolUniqueId bitfieldExtract_Int1_Int1_Int1 = TSymbolUniqueId(610);
+ static constexpr const TSymbolUniqueId bitfieldExtract_Int2_Int1_Int1 = TSymbolUniqueId(611);
+ static constexpr const TSymbolUniqueId bitfieldExtract_Int3_Int1_Int1 = TSymbolUniqueId(612);
+ static constexpr const TSymbolUniqueId bitfieldExtract_Int4_Int1_Int1 = TSymbolUniqueId(613);
+ static constexpr const TSymbolUniqueId bitfieldExtract_UInt1_Int1_Int1 = TSymbolUniqueId(614);
+ static constexpr const TSymbolUniqueId bitfieldExtract_UInt2_Int1_Int1 = TSymbolUniqueId(615);
+ static constexpr const TSymbolUniqueId bitfieldExtract_UInt3_Int1_Int1 = TSymbolUniqueId(616);
+ static constexpr const TSymbolUniqueId bitfieldExtract_UInt4_Int1_Int1 = TSymbolUniqueId(617);
+ static constexpr const TSymbolUniqueId bitfieldInsert_Int1_Int1_Int1_Int1 =
+ TSymbolUniqueId(618);
+ static constexpr const TSymbolUniqueId bitfieldInsert_Int2_Int2_Int1_Int1 =
+ TSymbolUniqueId(619);
+ static constexpr const TSymbolUniqueId bitfieldInsert_Int3_Int3_Int1_Int1 =
+ TSymbolUniqueId(620);
+ static constexpr const TSymbolUniqueId bitfieldInsert_Int4_Int4_Int1_Int1 =
+ TSymbolUniqueId(621);
+ static constexpr const TSymbolUniqueId bitfieldInsert_UInt1_UInt1_Int1_Int1 =
+ TSymbolUniqueId(622);
+ static constexpr const TSymbolUniqueId bitfieldInsert_UInt2_UInt2_Int1_Int1 =
+ TSymbolUniqueId(623);
+ static constexpr const TSymbolUniqueId bitfieldInsert_UInt3_UInt3_Int1_Int1 =
+ TSymbolUniqueId(624);
+ static constexpr const TSymbolUniqueId bitfieldInsert_UInt4_UInt4_Int1_Int1 =
+ TSymbolUniqueId(625);
+ static constexpr const TSymbolUniqueId bitfieldReverse_Int1 = TSymbolUniqueId(626);
+ static constexpr const TSymbolUniqueId bitfieldReverse_Int2 = TSymbolUniqueId(627);
+ static constexpr const TSymbolUniqueId bitfieldReverse_Int3 = TSymbolUniqueId(628);
+ static constexpr const TSymbolUniqueId bitfieldReverse_Int4 = TSymbolUniqueId(629);
+ static constexpr const TSymbolUniqueId bitfieldReverse_UInt1 = TSymbolUniqueId(630);
+ static constexpr const TSymbolUniqueId bitfieldReverse_UInt2 = TSymbolUniqueId(631);
+ static constexpr const TSymbolUniqueId bitfieldReverse_UInt3 = TSymbolUniqueId(632);
+ static constexpr const TSymbolUniqueId bitfieldReverse_UInt4 = TSymbolUniqueId(633);
+ static constexpr const TSymbolUniqueId bitCount_Int1 = TSymbolUniqueId(634);
+ static constexpr const TSymbolUniqueId bitCount_Int2 = TSymbolUniqueId(635);
+ static constexpr const TSymbolUniqueId bitCount_Int3 = TSymbolUniqueId(636);
+ static constexpr const TSymbolUniqueId bitCount_Int4 = TSymbolUniqueId(637);
+ static constexpr const TSymbolUniqueId bitCount_UInt1 = TSymbolUniqueId(638);
+ static constexpr const TSymbolUniqueId bitCount_UInt2 = TSymbolUniqueId(639);
+ static constexpr const TSymbolUniqueId bitCount_UInt3 = TSymbolUniqueId(640);
+ static constexpr const TSymbolUniqueId bitCount_UInt4 = TSymbolUniqueId(641);
+ static constexpr const TSymbolUniqueId findLSB_Int1 = TSymbolUniqueId(642);
+ static constexpr const TSymbolUniqueId findLSB_Int2 = TSymbolUniqueId(643);
+ static constexpr const TSymbolUniqueId findLSB_Int3 = TSymbolUniqueId(644);
+ static constexpr const TSymbolUniqueId findLSB_Int4 = TSymbolUniqueId(645);
+ static constexpr const TSymbolUniqueId findLSB_UInt1 = TSymbolUniqueId(646);
+ static constexpr const TSymbolUniqueId findLSB_UInt2 = TSymbolUniqueId(647);
+ static constexpr const TSymbolUniqueId findLSB_UInt3 = TSymbolUniqueId(648);
+ static constexpr const TSymbolUniqueId findLSB_UInt4 = TSymbolUniqueId(649);
+ static constexpr const TSymbolUniqueId findMSB_Int1 = TSymbolUniqueId(650);
+ static constexpr const TSymbolUniqueId findMSB_Int2 = TSymbolUniqueId(651);
+ static constexpr const TSymbolUniqueId findMSB_Int3 = TSymbolUniqueId(652);
+ static constexpr const TSymbolUniqueId findMSB_Int4 = TSymbolUniqueId(653);
+ static constexpr const TSymbolUniqueId findMSB_UInt1 = TSymbolUniqueId(654);
+ static constexpr const TSymbolUniqueId findMSB_UInt2 = TSymbolUniqueId(655);
+ static constexpr const TSymbolUniqueId findMSB_UInt3 = TSymbolUniqueId(656);
+ static constexpr const TSymbolUniqueId findMSB_UInt4 = TSymbolUniqueId(657);
+ static constexpr const TSymbolUniqueId uaddCarry_UInt1_UInt1_UInt1 = TSymbolUniqueId(658);
+ static constexpr const TSymbolUniqueId pt_o_00E = TSymbolUniqueId(659);
+ static constexpr const TSymbolUniqueId uaddCarry_UInt2_UInt2_UInt2 = TSymbolUniqueId(660);
+ static constexpr const TSymbolUniqueId pt_o_10E = TSymbolUniqueId(661);
+ static constexpr const TSymbolUniqueId uaddCarry_UInt3_UInt3_UInt3 = TSymbolUniqueId(662);
+ static constexpr const TSymbolUniqueId pt_o_20E = TSymbolUniqueId(663);
+ static constexpr const TSymbolUniqueId uaddCarry_UInt4_UInt4_UInt4 = TSymbolUniqueId(664);
+ static constexpr const TSymbolUniqueId pt_o_30E = TSymbolUniqueId(665);
+ static constexpr const TSymbolUniqueId usubBorrow_UInt1_UInt1_UInt1 = TSymbolUniqueId(666);
+ static constexpr const TSymbolUniqueId usubBorrow_UInt2_UInt2_UInt2 = TSymbolUniqueId(667);
+ static constexpr const TSymbolUniqueId usubBorrow_UInt3_UInt3_UInt3 = TSymbolUniqueId(668);
+ static constexpr const TSymbolUniqueId usubBorrow_UInt4_UInt4_UInt4 = TSymbolUniqueId(669);
+ static constexpr const TSymbolUniqueId umulExtended_UInt1_UInt1_UInt1_UInt1 =
+ TSymbolUniqueId(670);
+ static constexpr const TSymbolUniqueId umulExtended_UInt2_UInt2_UInt2_UInt2 =
+ TSymbolUniqueId(671);
+ static constexpr const TSymbolUniqueId umulExtended_UInt3_UInt3_UInt3_UInt3 =
+ TSymbolUniqueId(672);
+ static constexpr const TSymbolUniqueId umulExtended_UInt4_UInt4_UInt4_UInt4 =
+ TSymbolUniqueId(673);
+ static constexpr const TSymbolUniqueId imulExtended_Int1_Int1_Int1_Int1 = TSymbolUniqueId(674);
+ static constexpr const TSymbolUniqueId imulExtended_Int2_Int2_Int2_Int2 = TSymbolUniqueId(675);
+ static constexpr const TSymbolUniqueId imulExtended_Int3_Int3_Int3_Int3 = TSymbolUniqueId(676);
+ static constexpr const TSymbolUniqueId imulExtended_Int4_Int4_Int4_Int4 = TSymbolUniqueId(677);
+ static constexpr const TSymbolUniqueId texture2D_Sampler2D1_Float2 = TSymbolUniqueId(678);
+ static constexpr const TSymbolUniqueId pt00I = TSymbolUniqueId(679);
+ static constexpr const TSymbolUniqueId texture2DProj_Sampler2D1_Float3 = TSymbolUniqueId(680);
+ static constexpr const TSymbolUniqueId texture2DProj_Sampler2D1_Float4 = TSymbolUniqueId(681);
+ static constexpr const TSymbolUniqueId textureCube_SamplerCube1_Float3 = TSymbolUniqueId(682);
+ static constexpr const TSymbolUniqueId pt00K = TSymbolUniqueId(683);
+ static constexpr const TSymbolUniqueId texture1D_Sampler1D1_Float1 = TSymbolUniqueId(684);
+ static constexpr const TSymbolUniqueId pt00g = TSymbolUniqueId(685);
+ static constexpr const TSymbolUniqueId texture1DProj_Sampler1D1_Float2 = TSymbolUniqueId(686);
+ static constexpr const TSymbolUniqueId texture1DProj_Sampler1D1_Float4 = TSymbolUniqueId(687);
+ static constexpr const TSymbolUniqueId texture3D_Sampler3D1_Float3 = TSymbolUniqueId(688);
+ static constexpr const TSymbolUniqueId pt00J = TSymbolUniqueId(689);
+ static constexpr const TSymbolUniqueId texture3DProj_Sampler3D1_Float4 = TSymbolUniqueId(690);
+ static constexpr const TSymbolUniqueId shadow1D_Sampler1DShadow1_Float3 = TSymbolUniqueId(691);
+ static constexpr const TSymbolUniqueId pt00m = TSymbolUniqueId(692);
+ static constexpr const TSymbolUniqueId shadow1DProj_Sampler1DShadow1_Float4 =
+ TSymbolUniqueId(693);
+ static constexpr const TSymbolUniqueId shadow2D_Sampler2DShadow1_Float3 = TSymbolUniqueId(694);
+ static constexpr const TSymbolUniqueId pt00d = TSymbolUniqueId(695);
+ static constexpr const TSymbolUniqueId shadow2DProj_Sampler2DShadow1_Float4 =
+ TSymbolUniqueId(696);
+ static constexpr const TSymbolUniqueId shadow2DEXT_Sampler2DShadow1_Float3 =
+ TSymbolUniqueId(697);
+ static constexpr const TSymbolUniqueId shadow2DProjEXT_Sampler2DShadow1_Float4 =
+ TSymbolUniqueId(698);
+ static constexpr const TSymbolUniqueId texture2D_SamplerExternalOES1_Float2 =
+ TSymbolUniqueId(699);
+ static constexpr const TSymbolUniqueId pt00M = TSymbolUniqueId(700);
+ static constexpr const TSymbolUniqueId texture2DProj_SamplerExternalOES1_Float3 =
+ TSymbolUniqueId(701);
+ static constexpr const TSymbolUniqueId texture2DProj_SamplerExternalOES1_Float4 =
+ TSymbolUniqueId(702);
+ static constexpr const TSymbolUniqueId texture2DRect_Sampler2DRect1_Float2 =
+ TSymbolUniqueId(703);
+ static constexpr const TSymbolUniqueId pt00O = TSymbolUniqueId(704);
+ static constexpr const TSymbolUniqueId texture2DRectProj_Sampler2DRect1_Float3 =
+ TSymbolUniqueId(705);
+ static constexpr const TSymbolUniqueId texture2DRectProj_Sampler2DRect1_Float4 =
+ TSymbolUniqueId(706);
+ static constexpr const TSymbolUniqueId texture2DGradEXT_Sampler2D1_Float2_Float2_Float2 =
+ TSymbolUniqueId(707);
+ static constexpr const TSymbolUniqueId texture2DProjGradEXT_Sampler2D1_Float3_Float2_Float2 =
+ TSymbolUniqueId(708);
+ static constexpr const TSymbolUniqueId texture2DProjGradEXT_Sampler2D1_Float4_Float2_Float2 =
+ TSymbolUniqueId(709);
+ static constexpr const TSymbolUniqueId textureCubeGradEXT_SamplerCube1_Float3_Float3_Float3 =
+ TSymbolUniqueId(710);
+ static constexpr const TSymbolUniqueId textureVideoWEBGL_SamplerVideoWEBGL1_Float2 =
+ TSymbolUniqueId(711);
+ static constexpr const TSymbolUniqueId pt00y = TSymbolUniqueId(712);
+ static constexpr const TSymbolUniqueId texture2D_Sampler2D1_Float2_Float1 =
+ TSymbolUniqueId(713);
+ static constexpr const TSymbolUniqueId texture2DProj_Sampler2D1_Float3_Float1 =
+ TSymbolUniqueId(714);
+ static constexpr const TSymbolUniqueId texture2DProj_Sampler2D1_Float4_Float1 =
+ TSymbolUniqueId(715);
+ static constexpr const TSymbolUniqueId textureCube_SamplerCube1_Float3_Float1 =
+ TSymbolUniqueId(716);
+ static constexpr const TSymbolUniqueId texture3D_Sampler3D1_Float3_Float1 =
+ TSymbolUniqueId(717);
+ static constexpr const TSymbolUniqueId texture3DProj_Sampler3D1_Float4_Float1 =
+ TSymbolUniqueId(718);
+ static constexpr const TSymbolUniqueId texture1D_Sampler1D1_Float1_Float1 =
+ TSymbolUniqueId(719);
+ static constexpr const TSymbolUniqueId texture1DProj_Sampler1D1_Float2_Float1 =
+ TSymbolUniqueId(720);
+ static constexpr const TSymbolUniqueId texture1DProj_Sampler1D1_Float4_Float1 =
+ TSymbolUniqueId(721);
+ static constexpr const TSymbolUniqueId shadow1D_Sampler1DShadow1_Float3_Float1 =
+ TSymbolUniqueId(722);
+ static constexpr const TSymbolUniqueId shadow1DProj_Sampler1DShadow1_Float4_Float1 =
+ TSymbolUniqueId(723);
+ static constexpr const TSymbolUniqueId shadow2D_Sampler2DShadow1_Float3_Float1 =
+ TSymbolUniqueId(724);
+ static constexpr const TSymbolUniqueId shadow2DProj_Sampler2DShadow1_Float4_Float1 =
+ TSymbolUniqueId(725);
+ static constexpr const TSymbolUniqueId texture2DLod_Sampler2D1_Float2_Float1 =
+ TSymbolUniqueId(726);
+ static constexpr const TSymbolUniqueId texture2DProjLod_Sampler2D1_Float3_Float1 =
+ TSymbolUniqueId(727);
+ static constexpr const TSymbolUniqueId texture2DProjLod_Sampler2D1_Float4_Float1 =
+ TSymbolUniqueId(728);
+ static constexpr const TSymbolUniqueId textureCubeLod_SamplerCube1_Float3_Float1 =
+ TSymbolUniqueId(729);
+ static constexpr const TSymbolUniqueId texture1DLod_Sampler1D1_Float1_Float1 =
+ TSymbolUniqueId(730);
+ static constexpr const TSymbolUniqueId texture1DProjLod_Sampler1D1_Float2_Float1 =
+ TSymbolUniqueId(731);
+ static constexpr const TSymbolUniqueId texture1DProjLod_Sampler1D1_Float4_Float1 =
+ TSymbolUniqueId(732);
+ static constexpr const TSymbolUniqueId shadow1DLod_Sampler1DShadow1_Float3_Float1 =
+ TSymbolUniqueId(733);
+ static constexpr const TSymbolUniqueId shadow1DProjLod_Sampler1DShadow1_Float4_Float1 =
+ TSymbolUniqueId(734);
+ static constexpr const TSymbolUniqueId shadow2DLod_Sampler2DShadow1_Float3_Float1 =
+ TSymbolUniqueId(735);
+ static constexpr const TSymbolUniqueId shadow2DProjLod_Sampler2DShadow1_Float4_Float1 =
+ TSymbolUniqueId(736);
+ static constexpr const TSymbolUniqueId texture3DLod_Sampler3D1_Float3_Float1 =
+ TSymbolUniqueId(737);
+ static constexpr const TSymbolUniqueId texture3DProjLod_Sampler3D1_Float4_Float1 =
+ TSymbolUniqueId(738);
+ static constexpr const TSymbolUniqueId texture2DLodEXT_Sampler2D1_Float2_Float1 =
+ TSymbolUniqueId(739);
+ static constexpr const TSymbolUniqueId texture2DProjLodEXT_Sampler2D1_Float3_Float1 =
+ TSymbolUniqueId(740);
+ static constexpr const TSymbolUniqueId texture2DProjLodEXT_Sampler2D1_Float4_Float1 =
+ TSymbolUniqueId(741);
+ static constexpr const TSymbolUniqueId textureCubeLodEXT_SamplerCube1_Float3_Float1 =
+ TSymbolUniqueId(742);
+ static constexpr const TSymbolUniqueId texture_Sampler2D1_Float2 = TSymbolUniqueId(743);
+ static constexpr const TSymbolUniqueId texture_ISampler2D1_Float2 = TSymbolUniqueId(744);
+ static constexpr const TSymbolUniqueId pt00R = TSymbolUniqueId(745);
+ static constexpr const TSymbolUniqueId texture_USampler2D1_Float2 = TSymbolUniqueId(746);
+ static constexpr const TSymbolUniqueId pt00X = TSymbolUniqueId(747);
+ static constexpr const TSymbolUniqueId texture_Sampler3D1_Float3 = TSymbolUniqueId(748);
+ static constexpr const TSymbolUniqueId texture_ISampler3D1_Float3 = TSymbolUniqueId(749);
+ static constexpr const TSymbolUniqueId pt00S = TSymbolUniqueId(750);
+ static constexpr const TSymbolUniqueId texture_USampler3D1_Float3 = TSymbolUniqueId(751);
+ static constexpr const TSymbolUniqueId pt00Y = TSymbolUniqueId(752);
+ static constexpr const TSymbolUniqueId texture_SamplerCube1_Float3 = TSymbolUniqueId(753);
+ static constexpr const TSymbolUniqueId texture_ISamplerCube1_Float3 = TSymbolUniqueId(754);
+ static constexpr const TSymbolUniqueId pt00T = TSymbolUniqueId(755);
+ static constexpr const TSymbolUniqueId texture_USamplerCube1_Float3 = TSymbolUniqueId(756);
+ static constexpr const TSymbolUniqueId pt00Z = TSymbolUniqueId(757);
+ static constexpr const TSymbolUniqueId texture_Sampler2DArray1_Float3 = TSymbolUniqueId(758);
+ static constexpr const TSymbolUniqueId pt00L = TSymbolUniqueId(759);
+ static constexpr const TSymbolUniqueId texture_ISampler2DArray1_Float3 = TSymbolUniqueId(760);
+ static constexpr const TSymbolUniqueId pt00U = TSymbolUniqueId(761);
+ static constexpr const TSymbolUniqueId texture_USampler2DArray1_Float3 = TSymbolUniqueId(762);
+ static constexpr const TSymbolUniqueId pt00a = TSymbolUniqueId(763);
+ static constexpr const TSymbolUniqueId texture_Sampler2DShadow1_Float3 = TSymbolUniqueId(764);
+ static constexpr const TSymbolUniqueId texture_SamplerCubeShadow1_Float4 = TSymbolUniqueId(765);
+ static constexpr const TSymbolUniqueId pt00e = TSymbolUniqueId(766);
+ static constexpr const TSymbolUniqueId texture_Sampler2DArrayShadow1_Float4 =
+ TSymbolUniqueId(767);
+ static constexpr const TSymbolUniqueId pt00f = TSymbolUniqueId(768);
+ static constexpr const TSymbolUniqueId texture_Sampler1D1_Float1 = TSymbolUniqueId(769);
+ static constexpr const TSymbolUniqueId texture_ISampler1D1_Float1 = TSymbolUniqueId(770);
+ static constexpr const TSymbolUniqueId pt00o = TSymbolUniqueId(771);
+ static constexpr const TSymbolUniqueId texture_USampler1D1_Float1 = TSymbolUniqueId(772);
+ static constexpr const TSymbolUniqueId pt00t = TSymbolUniqueId(773);
+ static constexpr const TSymbolUniqueId texture_Sampler1DShadow1_Float3 = TSymbolUniqueId(774);
+ static constexpr const TSymbolUniqueId texture_Sampler1DArray1_Float3 = TSymbolUniqueId(775);
+ static constexpr const TSymbolUniqueId pt00h = TSymbolUniqueId(776);
+ static constexpr const TSymbolUniqueId texture_ISampler1DArray1_Float3 = TSymbolUniqueId(777);
+ static constexpr const TSymbolUniqueId pt00p = TSymbolUniqueId(778);
+ static constexpr const TSymbolUniqueId texture_USampler1DArray1_Float3 = TSymbolUniqueId(779);
+ static constexpr const TSymbolUniqueId pt00u = TSymbolUniqueId(780);
+ static constexpr const TSymbolUniqueId texture_Sampler1DArrayShadow1_Float3 =
+ TSymbolUniqueId(781);
+ static constexpr const TSymbolUniqueId pt00i = TSymbolUniqueId(782);
+ static constexpr const TSymbolUniqueId texture_Sampler2DRect1_Float2 = TSymbolUniqueId(783);
+ static constexpr const TSymbolUniqueId texture_ISampler2DRect1_Float2 = TSymbolUniqueId(784);
+ static constexpr const TSymbolUniqueId pt00q = TSymbolUniqueId(785);
+ static constexpr const TSymbolUniqueId texture_USampler2DRect1_Float2 = TSymbolUniqueId(786);
+ static constexpr const TSymbolUniqueId pt00v = TSymbolUniqueId(787);
+ static constexpr const TSymbolUniqueId texture_Sampler2DRectShadow1_Float3 =
+ TSymbolUniqueId(788);
+ static constexpr const TSymbolUniqueId pt00n = TSymbolUniqueId(789);
+ static constexpr const TSymbolUniqueId texture_SamplerCubeArray1_Float4 = TSymbolUniqueId(790);
+ static constexpr const TSymbolUniqueId pt00k = TSymbolUniqueId(791);
+ static constexpr const TSymbolUniqueId texture_ISamplerCubeArray1_Float4 = TSymbolUniqueId(792);
+ static constexpr const TSymbolUniqueId pt00s = TSymbolUniqueId(793);
+ static constexpr const TSymbolUniqueId texture_USamplerCubeArray1_Float4 = TSymbolUniqueId(794);
+ static constexpr const TSymbolUniqueId pt00x = TSymbolUniqueId(795);
+ static constexpr const TSymbolUniqueId texture_SamplerCubeArrayShadow1_Float4_Float1 =
+ TSymbolUniqueId(796);
+ static constexpr const TSymbolUniqueId pt00l = TSymbolUniqueId(797);
+ static constexpr const TSymbolUniqueId textureExt_SamplerCubeArray1_Float4 =
+ TSymbolUniqueId(798);
+ static constexpr const TSymbolUniqueId textureExt_ISamplerCubeArray1_Float4 =
+ TSymbolUniqueId(799);
+ static constexpr const TSymbolUniqueId textureExt_USamplerCubeArray1_Float4 =
+ TSymbolUniqueId(800);
+ static constexpr const TSymbolUniqueId textureExt_SamplerCubeArrayShadow1_Float4_Float1 =
+ TSymbolUniqueId(801);
+ static constexpr const TSymbolUniqueId texture_SamplerExternalOES1_Float2 =
+ TSymbolUniqueId(802);
+ static constexpr const TSymbolUniqueId texture_SamplerExternal2DY2YEXT1_Float2 =
+ TSymbolUniqueId(803);
+ static constexpr const TSymbolUniqueId pt00N = TSymbolUniqueId(804);
+ static constexpr const TSymbolUniqueId texture_SamplerVideoWEBGL1_Float2 = TSymbolUniqueId(805);
+ static constexpr const TSymbolUniqueId textureProj_Sampler2D1_Float3 = TSymbolUniqueId(806);
+ static constexpr const TSymbolUniqueId textureProj_ISampler2D1_Float3 = TSymbolUniqueId(807);
+ static constexpr const TSymbolUniqueId textureProj_USampler2D1_Float3 = TSymbolUniqueId(808);
+ static constexpr const TSymbolUniqueId textureProj_Sampler2D1_Float4 = TSymbolUniqueId(809);
+ static constexpr const TSymbolUniqueId textureProj_ISampler2D1_Float4 = TSymbolUniqueId(810);
+ static constexpr const TSymbolUniqueId textureProj_USampler2D1_Float4 = TSymbolUniqueId(811);
+ static constexpr const TSymbolUniqueId textureProj_Sampler3D1_Float4 = TSymbolUniqueId(812);
+ static constexpr const TSymbolUniqueId textureProj_ISampler3D1_Float4 = TSymbolUniqueId(813);
+ static constexpr const TSymbolUniqueId textureProj_USampler3D1_Float4 = TSymbolUniqueId(814);
+ static constexpr const TSymbolUniqueId textureProj_Sampler2DShadow1_Float4 =
+ TSymbolUniqueId(815);
+ static constexpr const TSymbolUniqueId textureProj_Sampler1D1_Float2 = TSymbolUniqueId(816);
+ static constexpr const TSymbolUniqueId textureProj_ISampler1D1_Float2 = TSymbolUniqueId(817);
+ static constexpr const TSymbolUniqueId textureProj_USampler1D1_Float2 = TSymbolUniqueId(818);
+ static constexpr const TSymbolUniqueId textureProj_Sampler1D1_Float4 = TSymbolUniqueId(819);
+ static constexpr const TSymbolUniqueId textureProj_ISampler1D1_Float4 = TSymbolUniqueId(820);
+ static constexpr const TSymbolUniqueId textureProj_USampler1D1_Float4 = TSymbolUniqueId(821);
+ static constexpr const TSymbolUniqueId textureProj_Sampler1DShadow1_Float4 =
+ TSymbolUniqueId(822);
+ static constexpr const TSymbolUniqueId textureProj_Sampler2DRect1_Float3 = TSymbolUniqueId(823);
+ static constexpr const TSymbolUniqueId textureProj_ISampler2DRect1_Float3 =
+ TSymbolUniqueId(824);
+ static constexpr const TSymbolUniqueId textureProj_USampler2DRect1_Float3 =
+ TSymbolUniqueId(825);
+ static constexpr const TSymbolUniqueId textureProj_Sampler2DRect1_Float4 = TSymbolUniqueId(826);
+ static constexpr const TSymbolUniqueId textureProj_ISampler2DRect1_Float4 =
+ TSymbolUniqueId(827);
+ static constexpr const TSymbolUniqueId textureProj_USampler2DRect1_Float4 =
+ TSymbolUniqueId(828);
+ static constexpr const TSymbolUniqueId textureProj_Sampler2DRectShadow1_Float4 =
+ TSymbolUniqueId(829);
+ static constexpr const TSymbolUniqueId textureProj_SamplerExternalOES1_Float3 =
+ TSymbolUniqueId(830);
+ static constexpr const TSymbolUniqueId textureProj_SamplerExternalOES1_Float4 =
+ TSymbolUniqueId(831);
+ static constexpr const TSymbolUniqueId textureProj_SamplerExternal2DY2YEXT1_Float3 =
+ TSymbolUniqueId(832);
+ static constexpr const TSymbolUniqueId textureProj_SamplerExternal2DY2YEXT1_Float4 =
+ TSymbolUniqueId(833);
+ static constexpr const TSymbolUniqueId textureLod_Sampler2D1_Float2_Float1 =
+ TSymbolUniqueId(834);
+ static constexpr const TSymbolUniqueId textureLod_ISampler2D1_Float2_Float1 =
+ TSymbolUniqueId(835);
+ static constexpr const TSymbolUniqueId textureLod_USampler2D1_Float2_Float1 =
+ TSymbolUniqueId(836);
+ static constexpr const TSymbolUniqueId textureLod_Sampler3D1_Float3_Float1 =
+ TSymbolUniqueId(837);
+ static constexpr const TSymbolUniqueId textureLod_ISampler3D1_Float3_Float1 =
+ TSymbolUniqueId(838);
+ static constexpr const TSymbolUniqueId textureLod_USampler3D1_Float3_Float1 =
+ TSymbolUniqueId(839);
+ static constexpr const TSymbolUniqueId textureLod_SamplerCube1_Float3_Float1 =
+ TSymbolUniqueId(840);
+ static constexpr const TSymbolUniqueId textureLod_ISamplerCube1_Float3_Float1 =
+ TSymbolUniqueId(841);
+ static constexpr const TSymbolUniqueId textureLod_USamplerCube1_Float3_Float1 =
+ TSymbolUniqueId(842);
+ static constexpr const TSymbolUniqueId textureLod_Sampler2DArray1_Float3_Float1 =
+ TSymbolUniqueId(843);
+ static constexpr const TSymbolUniqueId textureLod_ISampler2DArray1_Float3_Float1 =
+ TSymbolUniqueId(844);
+ static constexpr const TSymbolUniqueId textureLod_USampler2DArray1_Float3_Float1 =
+ TSymbolUniqueId(845);
+ static constexpr const TSymbolUniqueId textureLod_Sampler2DShadow1_Float3_Float1 =
+ TSymbolUniqueId(846);
+ static constexpr const TSymbolUniqueId textureLod_Sampler1D1_Float1_Float1 =
+ TSymbolUniqueId(847);
+ static constexpr const TSymbolUniqueId textureLod_ISampler1D1_Float1_Float1 =
+ TSymbolUniqueId(848);
+ static constexpr const TSymbolUniqueId textureLod_USampler1D1_Float1_Float1 =
+ TSymbolUniqueId(849);
+ static constexpr const TSymbolUniqueId textureLod_Sampler1DShadow1_Float3_Float1 =
+ TSymbolUniqueId(850);
+ static constexpr const TSymbolUniqueId textureLod_Sampler1DArray1_Float2_Float1 =
+ TSymbolUniqueId(851);
+ static constexpr const TSymbolUniqueId textureLod_ISampler1DArray1_Float2_Float1 =
+ TSymbolUniqueId(852);
+ static constexpr const TSymbolUniqueId textureLod_USampler1DArray1_Float2_Float1 =
+ TSymbolUniqueId(853);
+ static constexpr const TSymbolUniqueId textureLod_Sampler1DArrayShadow1_Float3_Float1 =
+ TSymbolUniqueId(854);
+ static constexpr const TSymbolUniqueId textureLod_SamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(855);
+ static constexpr const TSymbolUniqueId textureLod_ISamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(856);
+ static constexpr const TSymbolUniqueId textureLod_USamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(857);
+ static constexpr const TSymbolUniqueId textureLodExt_SamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(858);
+ static constexpr const TSymbolUniqueId textureLodExt_ISamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(859);
+ static constexpr const TSymbolUniqueId textureLodExt_USamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(860);
+ static constexpr const TSymbolUniqueId textureSize_Sampler2D1_Int1 = TSymbolUniqueId(861);
+ static constexpr const TSymbolUniqueId textureSize_ISampler2D1_Int1 = TSymbolUniqueId(862);
+ static constexpr const TSymbolUniqueId textureSize_USampler2D1_Int1 = TSymbolUniqueId(863);
+ static constexpr const TSymbolUniqueId textureSize_Sampler3D1_Int1 = TSymbolUniqueId(864);
+ static constexpr const TSymbolUniqueId textureSize_ISampler3D1_Int1 = TSymbolUniqueId(865);
+ static constexpr const TSymbolUniqueId textureSize_USampler3D1_Int1 = TSymbolUniqueId(866);
+ static constexpr const TSymbolUniqueId textureSize_SamplerCube1_Int1 = TSymbolUniqueId(867);
+ static constexpr const TSymbolUniqueId textureSize_ISamplerCube1_Int1 = TSymbolUniqueId(868);
+ static constexpr const TSymbolUniqueId textureSize_USamplerCube1_Int1 = TSymbolUniqueId(869);
+ static constexpr const TSymbolUniqueId textureSize_Sampler2DArray1_Int1 = TSymbolUniqueId(870);
+ static constexpr const TSymbolUniqueId textureSize_ISampler2DArray1_Int1 = TSymbolUniqueId(871);
+ static constexpr const TSymbolUniqueId textureSize_USampler2DArray1_Int1 = TSymbolUniqueId(872);
+ static constexpr const TSymbolUniqueId textureSize_Sampler2DShadow1_Int1 = TSymbolUniqueId(873);
+ static constexpr const TSymbolUniqueId textureSize_SamplerCubeShadow1_Int1 =
+ TSymbolUniqueId(874);
+ static constexpr const TSymbolUniqueId textureSize_Sampler2DArrayShadow1_Int1 =
+ TSymbolUniqueId(875);
+ static constexpr const TSymbolUniqueId textureSize_Sampler1D1_Int1 = TSymbolUniqueId(876);
+ static constexpr const TSymbolUniqueId textureSize_ISampler1D1_Int1 = TSymbolUniqueId(877);
+ static constexpr const TSymbolUniqueId textureSize_USampler1D1_Int1 = TSymbolUniqueId(878);
+ static constexpr const TSymbolUniqueId textureSize_Sampler1DShadow1_Int1 = TSymbolUniqueId(879);
+ static constexpr const TSymbolUniqueId textureSize_SamplerCubeArray1_Int1 =
+ TSymbolUniqueId(880);
+ static constexpr const TSymbolUniqueId textureSize_ISamplerCubeArray1_Int1 =
+ TSymbolUniqueId(881);
+ static constexpr const TSymbolUniqueId textureSize_USamplerCubeArray1_Int1 =
+ TSymbolUniqueId(882);
+ static constexpr const TSymbolUniqueId textureSize_SamplerCubeArrayShadow1_Int1 =
+ TSymbolUniqueId(883);
+ static constexpr const TSymbolUniqueId textureSizeExt_SamplerCubeArray1_Int1 =
+ TSymbolUniqueId(884);
+ static constexpr const TSymbolUniqueId textureSizeExt_ISamplerCubeArray1_Int1 =
+ TSymbolUniqueId(885);
+ static constexpr const TSymbolUniqueId textureSizeExt_USamplerCubeArray1_Int1 =
+ TSymbolUniqueId(886);
+ static constexpr const TSymbolUniqueId textureSizeExt_SamplerCubeArrayShadow1_Int1 =
+ TSymbolUniqueId(887);
+ static constexpr const TSymbolUniqueId textureSize_Sampler2DRect1 = TSymbolUniqueId(888);
+ static constexpr const TSymbolUniqueId textureSize_ISampler2DRect1 = TSymbolUniqueId(889);
+ static constexpr const TSymbolUniqueId textureSize_USampler2DRect1 = TSymbolUniqueId(890);
+ static constexpr const TSymbolUniqueId textureSize_Sampler2DRectShadow1 = TSymbolUniqueId(891);
+ static constexpr const TSymbolUniqueId textureSize_Sampler1DArray1_Int1 = TSymbolUniqueId(892);
+ static constexpr const TSymbolUniqueId textureSize_ISampler1DArray1_Int1 = TSymbolUniqueId(893);
+ static constexpr const TSymbolUniqueId textureSize_USampler1DArray1_Int1 = TSymbolUniqueId(894);
+ static constexpr const TSymbolUniqueId textureSize_Sampler1DArrayShadow1_Int1 =
+ TSymbolUniqueId(895);
+ static constexpr const TSymbolUniqueId textureSize_SamplerBuffer1 = TSymbolUniqueId(896);
+ static constexpr const TSymbolUniqueId pt00j = TSymbolUniqueId(897);
+ static constexpr const TSymbolUniqueId textureSize_ISamplerBuffer1 = TSymbolUniqueId(898);
+ static constexpr const TSymbolUniqueId pt00r = TSymbolUniqueId(899);
+ static constexpr const TSymbolUniqueId textureSize_USamplerBuffer1 = TSymbolUniqueId(900);
+ static constexpr const TSymbolUniqueId pt00w = TSymbolUniqueId(901);
+ static constexpr const TSymbolUniqueId textureSizeExt_SamplerBuffer1 = TSymbolUniqueId(902);
+ static constexpr const TSymbolUniqueId textureSizeExt_ISamplerBuffer1 = TSymbolUniqueId(903);
+ static constexpr const TSymbolUniqueId textureSizeExt_USamplerBuffer1 = TSymbolUniqueId(904);
+ static constexpr const TSymbolUniqueId textureSize_Sampler2DMS1 = TSymbolUniqueId(905);
+ static constexpr const TSymbolUniqueId pt00P = TSymbolUniqueId(906);
+ static constexpr const TSymbolUniqueId textureSize_ISampler2DMS1 = TSymbolUniqueId(907);
+ static constexpr const TSymbolUniqueId pt00V = TSymbolUniqueId(908);
+ static constexpr const TSymbolUniqueId textureSize_USampler2DMS1 = TSymbolUniqueId(909);
+ static constexpr const TSymbolUniqueId pt00b = TSymbolUniqueId(910);
+ static constexpr const TSymbolUniqueId textureSizeExt_Sampler2DMS1 = TSymbolUniqueId(911);
+ static constexpr const TSymbolUniqueId textureSizeExt_ISampler2DMS1 = TSymbolUniqueId(912);
+ static constexpr const TSymbolUniqueId textureSizeExt_USampler2DMS1 = TSymbolUniqueId(913);
+ static constexpr const TSymbolUniqueId textureSize_Sampler2DMSArray1 = TSymbolUniqueId(914);
+ static constexpr const TSymbolUniqueId pt00Q = TSymbolUniqueId(915);
+ static constexpr const TSymbolUniqueId textureSize_ISampler2DMSArray1 = TSymbolUniqueId(916);
+ static constexpr const TSymbolUniqueId pt00W = TSymbolUniqueId(917);
+ static constexpr const TSymbolUniqueId textureSize_USampler2DMSArray1 = TSymbolUniqueId(918);
+ static constexpr const TSymbolUniqueId pt00c = TSymbolUniqueId(919);
+ static constexpr const TSymbolUniqueId textureSizeExt_Sampler2DMSArray1 = TSymbolUniqueId(920);
+ static constexpr const TSymbolUniqueId textureSizeExt_ISampler2DMSArray1 = TSymbolUniqueId(921);
+ static constexpr const TSymbolUniqueId textureSizeExt_USampler2DMSArray1 = TSymbolUniqueId(922);
+ static constexpr const TSymbolUniqueId textureSize_SamplerExternalOES1_Int1 =
+ TSymbolUniqueId(923);
+ static constexpr const TSymbolUniqueId textureSize_SamplerExternal2DY2YEXT1_Int1 =
+ TSymbolUniqueId(924);
+ static constexpr const TSymbolUniqueId textureProjLod_Sampler2D1_Float3_Float1 =
+ TSymbolUniqueId(925);
+ static constexpr const TSymbolUniqueId textureProjLod_ISampler2D1_Float3_Float1 =
+ TSymbolUniqueId(926);
+ static constexpr const TSymbolUniqueId textureProjLod_USampler2D1_Float3_Float1 =
+ TSymbolUniqueId(927);
+ static constexpr const TSymbolUniqueId textureProjLod_Sampler2D1_Float4_Float1 =
+ TSymbolUniqueId(928);
+ static constexpr const TSymbolUniqueId textureProjLod_ISampler2D1_Float4_Float1 =
+ TSymbolUniqueId(929);
+ static constexpr const TSymbolUniqueId textureProjLod_USampler2D1_Float4_Float1 =
+ TSymbolUniqueId(930);
+ static constexpr const TSymbolUniqueId textureProjLod_Sampler3D1_Float4_Float1 =
+ TSymbolUniqueId(931);
+ static constexpr const TSymbolUniqueId textureProjLod_ISampler3D1_Float4_Float1 =
+ TSymbolUniqueId(932);
+ static constexpr const TSymbolUniqueId textureProjLod_USampler3D1_Float4_Float1 =
+ TSymbolUniqueId(933);
+ static constexpr const TSymbolUniqueId textureProjLod_Sampler2DShadow1_Float4_Float1 =
+ TSymbolUniqueId(934);
+ static constexpr const TSymbolUniqueId textureProjLod_Sampler1D1_Float2_Float1 =
+ TSymbolUniqueId(935);
+ static constexpr const TSymbolUniqueId textureProjLod_ISampler1D1_Float2_Float1 =
+ TSymbolUniqueId(936);
+ static constexpr const TSymbolUniqueId textureProjLod_USampler1D1_Float2_Float1 =
+ TSymbolUniqueId(937);
+ static constexpr const TSymbolUniqueId textureProjLod_Sampler1D1_Float4_Float1 =
+ TSymbolUniqueId(938);
+ static constexpr const TSymbolUniqueId textureProjLod_ISampler1D1_Float4_Float1 =
+ TSymbolUniqueId(939);
+ static constexpr const TSymbolUniqueId textureProjLod_USampler1D1_Float4_Float1 =
+ TSymbolUniqueId(940);
+ static constexpr const TSymbolUniqueId textureProjLod_Sampler1DShadow1_Float4_Float1 =
+ TSymbolUniqueId(941);
+ static constexpr const TSymbolUniqueId texelFetch_Sampler2D1_Int2_Int1 = TSymbolUniqueId(942);
+ static constexpr const TSymbolUniqueId texelFetch_ISampler2D1_Int2_Int1 = TSymbolUniqueId(943);
+ static constexpr const TSymbolUniqueId texelFetch_USampler2D1_Int2_Int1 = TSymbolUniqueId(944);
+ static constexpr const TSymbolUniqueId texelFetch_Sampler3D1_Int3_Int1 = TSymbolUniqueId(945);
+ static constexpr const TSymbolUniqueId texelFetch_ISampler3D1_Int3_Int1 = TSymbolUniqueId(946);
+ static constexpr const TSymbolUniqueId texelFetch_USampler3D1_Int3_Int1 = TSymbolUniqueId(947);
+ static constexpr const TSymbolUniqueId texelFetch_Sampler2DArray1_Int3_Int1 =
+ TSymbolUniqueId(948);
+ static constexpr const TSymbolUniqueId texelFetch_ISampler2DArray1_Int3_Int1 =
+ TSymbolUniqueId(949);
+ static constexpr const TSymbolUniqueId texelFetch_USampler2DArray1_Int3_Int1 =
+ TSymbolUniqueId(950);
+ static constexpr const TSymbolUniqueId texelFetch_Sampler1D1_Int1_Int1 = TSymbolUniqueId(951);
+ static constexpr const TSymbolUniqueId texelFetch_ISampler1D1_Int1_Int1 = TSymbolUniqueId(952);
+ static constexpr const TSymbolUniqueId texelFetch_USampler1D1_Int1_Int1 = TSymbolUniqueId(953);
+ static constexpr const TSymbolUniqueId texelFetch_Sampler2DRect1_Int2 = TSymbolUniqueId(954);
+ static constexpr const TSymbolUniqueId texelFetch_ISampler2DRect1_Int2 = TSymbolUniqueId(955);
+ static constexpr const TSymbolUniqueId texelFetch_USampler2DRect1_Int2 = TSymbolUniqueId(956);
+ static constexpr const TSymbolUniqueId texelFetch_Sampler1DArray1_Int2_Int1 =
+ TSymbolUniqueId(957);
+ static constexpr const TSymbolUniqueId texelFetch_ISampler1DArray1_Int2_Int1 =
+ TSymbolUniqueId(958);
+ static constexpr const TSymbolUniqueId texelFetch_USampler1DArray1_Int2_Int1 =
+ TSymbolUniqueId(959);
+ static constexpr const TSymbolUniqueId texelFetch_SamplerBuffer1_Int1 = TSymbolUniqueId(960);
+ static constexpr const TSymbolUniqueId texelFetch_ISamplerBuffer1_Int1 = TSymbolUniqueId(961);
+ static constexpr const TSymbolUniqueId texelFetch_USamplerBuffer1_Int1 = TSymbolUniqueId(962);
+ static constexpr const TSymbolUniqueId texelFetchExt_SamplerBuffer1_Int1 = TSymbolUniqueId(963);
+ static constexpr const TSymbolUniqueId texelFetchExt_ISamplerBuffer1_Int1 =
+ TSymbolUniqueId(964);
+ static constexpr const TSymbolUniqueId texelFetchExt_USamplerBuffer1_Int1 =
+ TSymbolUniqueId(965);
+ static constexpr const TSymbolUniqueId texelFetch_Sampler2DMS1_Int2_Int1 = TSymbolUniqueId(966);
+ static constexpr const TSymbolUniqueId texelFetch_ISampler2DMS1_Int2_Int1 =
+ TSymbolUniqueId(967);
+ static constexpr const TSymbolUniqueId texelFetch_USampler2DMS1_Int2_Int1 =
+ TSymbolUniqueId(968);
+ static constexpr const TSymbolUniqueId texelFetchExt_Sampler2DMS1_Int2_Int1 =
+ TSymbolUniqueId(969);
+ static constexpr const TSymbolUniqueId texelFetchExt_ISampler2DMS1_Int2_Int1 =
+ TSymbolUniqueId(970);
+ static constexpr const TSymbolUniqueId texelFetchExt_USampler2DMS1_Int2_Int1 =
+ TSymbolUniqueId(971);
+ static constexpr const TSymbolUniqueId texelFetch_Sampler2DMSArray1_Int3_Int1 =
+ TSymbolUniqueId(972);
+ static constexpr const TSymbolUniqueId texelFetch_ISampler2DMSArray1_Int3_Int1 =
+ TSymbolUniqueId(973);
+ static constexpr const TSymbolUniqueId texelFetch_USampler2DMSArray1_Int3_Int1 =
+ TSymbolUniqueId(974);
+ static constexpr const TSymbolUniqueId texelFetchExt_Sampler2DMSArray1_Int3_Int1 =
+ TSymbolUniqueId(975);
+ static constexpr const TSymbolUniqueId texelFetchExt_ISampler2DMSArray1_Int3_Int1 =
+ TSymbolUniqueId(976);
+ static constexpr const TSymbolUniqueId texelFetchExt_USampler2DMSArray1_Int3_Int1 =
+ TSymbolUniqueId(977);
+ static constexpr const TSymbolUniqueId texelFetch_SamplerExternalOES1_Int2_Int1 =
+ TSymbolUniqueId(978);
+ static constexpr const TSymbolUniqueId texelFetch_SamplerExternal2DY2YEXT1_Int2_Int1 =
+ TSymbolUniqueId(979);
+ static constexpr const TSymbolUniqueId textureGrad_Sampler2D1_Float2_Float2_Float2 =
+ TSymbolUniqueId(980);
+ static constexpr const TSymbolUniqueId textureGrad_ISampler2D1_Float2_Float2_Float2 =
+ TSymbolUniqueId(981);
+ static constexpr const TSymbolUniqueId textureGrad_USampler2D1_Float2_Float2_Float2 =
+ TSymbolUniqueId(982);
+ static constexpr const TSymbolUniqueId textureGrad_Sampler3D1_Float3_Float3_Float3 =
+ TSymbolUniqueId(983);
+ static constexpr const TSymbolUniqueId textureGrad_ISampler3D1_Float3_Float3_Float3 =
+ TSymbolUniqueId(984);
+ static constexpr const TSymbolUniqueId textureGrad_USampler3D1_Float3_Float3_Float3 =
+ TSymbolUniqueId(985);
+ static constexpr const TSymbolUniqueId textureGrad_SamplerCube1_Float3_Float3_Float3 =
+ TSymbolUniqueId(986);
+ static constexpr const TSymbolUniqueId textureGrad_ISamplerCube1_Float3_Float3_Float3 =
+ TSymbolUniqueId(987);
+ static constexpr const TSymbolUniqueId textureGrad_USamplerCube1_Float3_Float3_Float3 =
+ TSymbolUniqueId(988);
+ static constexpr const TSymbolUniqueId textureGrad_Sampler2D1_Float1_Float1_Float1 =
+ TSymbolUniqueId(989);
+ static constexpr const TSymbolUniqueId textureGrad_ISampler2D1_Float1_Float1_Float1 =
+ TSymbolUniqueId(990);
+ static constexpr const TSymbolUniqueId textureGrad_USampler2D1_Float1_Float1_Float1 =
+ TSymbolUniqueId(991);
+ static constexpr const TSymbolUniqueId textureGrad_Sampler2DRect1_Float2_Float2_Float2 =
+ TSymbolUniqueId(992);
+ static constexpr const TSymbolUniqueId textureGrad_ISampler2DRect1_Float2_Float2_Float2 =
+ TSymbolUniqueId(993);
+ static constexpr const TSymbolUniqueId textureGrad_USampler2DRect1_Float2_Float2_Float2 =
+ TSymbolUniqueId(994);
+ static constexpr const TSymbolUniqueId textureGrad_Sampler2DRectShadow1_Float3_Float2_Float2 =
+ TSymbolUniqueId(995);
+ static constexpr const TSymbolUniqueId textureGrad_Sampler2DShadow1_Float3_Float2_Float2 =
+ TSymbolUniqueId(996);
+ static constexpr const TSymbolUniqueId textureGrad_SamplerCubeShadow1_Float4_Float3_Float3 =
+ TSymbolUniqueId(997);
+ static constexpr const TSymbolUniqueId textureGrad_Sampler2DArray1_Float3_Float2_Float2 =
+ TSymbolUniqueId(998);
+ static constexpr const TSymbolUniqueId textureGrad_ISampler2DArray1_Float3_Float2_Float2 =
+ TSymbolUniqueId(999);
+ static constexpr const TSymbolUniqueId textureGrad_USampler2DArray1_Float3_Float2_Float2 =
+ TSymbolUniqueId(1000);
+ static constexpr const TSymbolUniqueId textureGrad_Sampler2DArrayShadow1_Float4_Float2_Float2 =
+ TSymbolUniqueId(1001);
+ static constexpr const TSymbolUniqueId textureGrad_Sampler1DShadow1_Float3_Float1_Float1 =
+ TSymbolUniqueId(1002);
+ static constexpr const TSymbolUniqueId textureGrad_Sampler1DArray1_Float2_Float1_Float1 =
+ TSymbolUniqueId(1003);
+ static constexpr const TSymbolUniqueId textureGrad_ISampler1DArray1_Float2_Float1_Float1 =
+ TSymbolUniqueId(1004);
+ static constexpr const TSymbolUniqueId textureGrad_USampler1DArray1_Float2_Float1_Float1 =
+ TSymbolUniqueId(1005);
+ static constexpr const TSymbolUniqueId textureGrad_Sampler1DArrayShadow1_Float3_Float1_Float1 =
+ TSymbolUniqueId(1006);
+ static constexpr const TSymbolUniqueId textureGrad_SamplerCubeArray1_Float4_Float3_Float3 =
+ TSymbolUniqueId(1007);
+ static constexpr const TSymbolUniqueId textureGrad_ISamplerCubeArray1_Float4_Float3_Float3 =
+ TSymbolUniqueId(1008);
+ static constexpr const TSymbolUniqueId textureGrad_USamplerCubeArray1_Float4_Float3_Float3 =
+ TSymbolUniqueId(1009);
+ static constexpr const TSymbolUniqueId textureGradExt_SamplerCubeArray1_Float4_Float3_Float3 =
+ TSymbolUniqueId(1010);
+ static constexpr const TSymbolUniqueId textureGradExt_ISamplerCubeArray1_Float4_Float3_Float3 =
+ TSymbolUniqueId(1011);
+ static constexpr const TSymbolUniqueId textureGradExt_USamplerCubeArray1_Float4_Float3_Float3 =
+ TSymbolUniqueId(1012);
+ static constexpr const TSymbolUniqueId textureProjGrad_Sampler2D1_Float3_Float2_Float2 =
+ TSymbolUniqueId(1013);
+ static constexpr const TSymbolUniqueId textureProjGrad_ISampler2D1_Float3_Float2_Float2 =
+ TSymbolUniqueId(1014);
+ static constexpr const TSymbolUniqueId textureProjGrad_USampler2D1_Float3_Float2_Float2 =
+ TSymbolUniqueId(1015);
+ static constexpr const TSymbolUniqueId textureProjGrad_Sampler2D1_Float4_Float2_Float2 =
+ TSymbolUniqueId(1016);
+ static constexpr const TSymbolUniqueId textureProjGrad_ISampler2D1_Float4_Float2_Float2 =
+ TSymbolUniqueId(1017);
+ static constexpr const TSymbolUniqueId textureProjGrad_USampler2D1_Float4_Float2_Float2 =
+ TSymbolUniqueId(1018);
+ static constexpr const TSymbolUniqueId textureProjGrad_Sampler3D1_Float4_Float3_Float3 =
+ TSymbolUniqueId(1019);
+ static constexpr const TSymbolUniqueId textureProjGrad_ISampler3D1_Float4_Float3_Float3 =
+ TSymbolUniqueId(1020);
+ static constexpr const TSymbolUniqueId textureProjGrad_USampler3D1_Float4_Float3_Float3 =
+ TSymbolUniqueId(1021);
+ static constexpr const TSymbolUniqueId textureProjGrad_Sampler2DShadow1_Float4_Float2_Float2 =
+ TSymbolUniqueId(1022);
+ static constexpr const TSymbolUniqueId textureProjGrad_Sampler1D1_Float2_Float1_Float1 =
+ TSymbolUniqueId(1023);
+ static constexpr const TSymbolUniqueId textureProjGrad_ISampler1D1_Float2_Float1_Float1 =
+ TSymbolUniqueId(1024);
+ static constexpr const TSymbolUniqueId textureProjGrad_USampler1D1_Float2_Float1_Float1 =
+ TSymbolUniqueId(1025);
+ static constexpr const TSymbolUniqueId textureProjGrad_Sampler1D1_Float4_Float1_Float1 =
+ TSymbolUniqueId(1026);
+ static constexpr const TSymbolUniqueId textureProjGrad_ISampler1D1_Float4_Float1_Float1 =
+ TSymbolUniqueId(1027);
+ static constexpr const TSymbolUniqueId textureProjGrad_USampler1D1_Float4_Float1_Float1 =
+ TSymbolUniqueId(1028);
+ static constexpr const TSymbolUniqueId textureProjGrad_Sampler1DShadow1_Float4_Float1_Float1 =
+ TSymbolUniqueId(1029);
+ static constexpr const TSymbolUniqueId textureProjGrad_Sampler2DRect1_Float3_Float2_Float2 =
+ TSymbolUniqueId(1030);
+ static constexpr const TSymbolUniqueId textureProjGrad_ISampler2DRect1_Float3_Float2_Float2 =
+ TSymbolUniqueId(1031);
+ static constexpr const TSymbolUniqueId textureProjGrad_USampler2DRect1_Float3_Float2_Float2 =
+ TSymbolUniqueId(1032);
+ static constexpr const TSymbolUniqueId textureProjGrad_Sampler2DRect1_Float4_Float2_Float2 =
+ TSymbolUniqueId(1033);
+ static constexpr const TSymbolUniqueId textureProjGrad_ISampler2DRect1_Float4_Float2_Float2 =
+ TSymbolUniqueId(1034);
+ static constexpr const TSymbolUniqueId textureProjGrad_USampler2DRect1_Float4_Float2_Float2 =
+ TSymbolUniqueId(1035);
+ static constexpr const TSymbolUniqueId
+ textureProjGrad_Sampler2DRectShadow1_Float4_Float2_Float2 = TSymbolUniqueId(1036);
+ static constexpr const TSymbolUniqueId textureQueryLevels_Sampler1D1 = TSymbolUniqueId(1037);
+ static constexpr const TSymbolUniqueId textureQueryLevels_ISampler1D1 = TSymbolUniqueId(1038);
+ static constexpr const TSymbolUniqueId textureQueryLevels_USampler1D1 = TSymbolUniqueId(1039);
+ static constexpr const TSymbolUniqueId textureQueryLevels_Sampler2D1 = TSymbolUniqueId(1040);
+ static constexpr const TSymbolUniqueId textureQueryLevels_ISampler2D1 = TSymbolUniqueId(1041);
+ static constexpr const TSymbolUniqueId textureQueryLevels_USampler2D1 = TSymbolUniqueId(1042);
+ static constexpr const TSymbolUniqueId textureQueryLevels_Sampler3D1 = TSymbolUniqueId(1043);
+ static constexpr const TSymbolUniqueId textureQueryLevels_ISampler3D1 = TSymbolUniqueId(1044);
+ static constexpr const TSymbolUniqueId textureQueryLevels_USampler3D1 = TSymbolUniqueId(1045);
+ static constexpr const TSymbolUniqueId textureQueryLevels_SamplerCube1 = TSymbolUniqueId(1046);
+ static constexpr const TSymbolUniqueId textureQueryLevels_ISamplerCube1 = TSymbolUniqueId(1047);
+ static constexpr const TSymbolUniqueId textureQueryLevels_USamplerCube1 = TSymbolUniqueId(1048);
+ static constexpr const TSymbolUniqueId textureQueryLevels_Sampler1DArray1 =
+ TSymbolUniqueId(1049);
+ static constexpr const TSymbolUniqueId textureQueryLevels_ISampler1DArray1 =
+ TSymbolUniqueId(1050);
+ static constexpr const TSymbolUniqueId textureQueryLevels_USampler1DArray1 =
+ TSymbolUniqueId(1051);
+ static constexpr const TSymbolUniqueId textureQueryLevels_Sampler2DArray1 =
+ TSymbolUniqueId(1052);
+ static constexpr const TSymbolUniqueId textureQueryLevels_ISampler2DArray1 =
+ TSymbolUniqueId(1053);
+ static constexpr const TSymbolUniqueId textureQueryLevels_USampler2DArray1 =
+ TSymbolUniqueId(1054);
+ static constexpr const TSymbolUniqueId textureQueryLevels_SamplerCubeArray1 =
+ TSymbolUniqueId(1055);
+ static constexpr const TSymbolUniqueId textureQueryLevels_ISamplerCubeArray1 =
+ TSymbolUniqueId(1056);
+ static constexpr const TSymbolUniqueId textureQueryLevels_USamplerCubeArray1 =
+ TSymbolUniqueId(1057);
+ static constexpr const TSymbolUniqueId textureQueryLevels_Sampler1DShadow1 =
+ TSymbolUniqueId(1058);
+ static constexpr const TSymbolUniqueId textureQueryLevels_Sampler2DShadow1 =
+ TSymbolUniqueId(1059);
+ static constexpr const TSymbolUniqueId textureQueryLevels_SamplerCubeShadow1 =
+ TSymbolUniqueId(1060);
+ static constexpr const TSymbolUniqueId textureQueryLevels_Sampler1DArrayShadow1 =
+ TSymbolUniqueId(1061);
+ static constexpr const TSymbolUniqueId textureQueryLevels_Sampler2DArrayShadow1 =
+ TSymbolUniqueId(1062);
+ static constexpr const TSymbolUniqueId textureQueryLevels_SamplerCubeArrayShadow1 =
+ TSymbolUniqueId(1063);
+ static constexpr const TSymbolUniqueId textureSamples_Sampler2DMS1 = TSymbolUniqueId(1064);
+ static constexpr const TSymbolUniqueId textureSamples_ISampler2DMS1 = TSymbolUniqueId(1065);
+ static constexpr const TSymbolUniqueId textureSamples_USampler2DMS1 = TSymbolUniqueId(1066);
+ static constexpr const TSymbolUniqueId textureSamples_Sampler2DMSArray1 = TSymbolUniqueId(1067);
+ static constexpr const TSymbolUniqueId textureSamples_ISampler2DMSArray1 =
+ TSymbolUniqueId(1068);
+ static constexpr const TSymbolUniqueId textureSamples_USampler2DMSArray1 =
+ TSymbolUniqueId(1069);
+ static constexpr const TSymbolUniqueId texture_Sampler2D1_Float2_Float1 = TSymbolUniqueId(1070);
+ static constexpr const TSymbolUniqueId texture_ISampler2D1_Float2_Float1 =
+ TSymbolUniqueId(1071);
+ static constexpr const TSymbolUniqueId texture_USampler2D1_Float2_Float1 =
+ TSymbolUniqueId(1072);
+ static constexpr const TSymbolUniqueId texture_Sampler3D1_Float3_Float1 = TSymbolUniqueId(1073);
+ static constexpr const TSymbolUniqueId texture_ISampler3D1_Float3_Float1 =
+ TSymbolUniqueId(1074);
+ static constexpr const TSymbolUniqueId texture_USampler3D1_Float3_Float1 =
+ TSymbolUniqueId(1075);
+ static constexpr const TSymbolUniqueId texture_SamplerCube1_Float3_Float1 =
+ TSymbolUniqueId(1076);
+ static constexpr const TSymbolUniqueId texture_ISamplerCube1_Float3_Float1 =
+ TSymbolUniqueId(1077);
+ static constexpr const TSymbolUniqueId texture_USamplerCube1_Float3_Float1 =
+ TSymbolUniqueId(1078);
+ static constexpr const TSymbolUniqueId texture_Sampler2DArray1_Float3_Float1 =
+ TSymbolUniqueId(1079);
+ static constexpr const TSymbolUniqueId texture_ISampler2DArray1_Float3_Float1 =
+ TSymbolUniqueId(1080);
+ static constexpr const TSymbolUniqueId texture_USampler2DArray1_Float3_Float1 =
+ TSymbolUniqueId(1081);
+ static constexpr const TSymbolUniqueId textureProj_Sampler2D1_Float3_Float1 =
+ TSymbolUniqueId(1082);
+ static constexpr const TSymbolUniqueId textureProj_ISampler2D1_Float3_Float1 =
+ TSymbolUniqueId(1083);
+ static constexpr const TSymbolUniqueId textureProj_USampler2D1_Float3_Float1 =
+ TSymbolUniqueId(1084);
+ static constexpr const TSymbolUniqueId textureProj_Sampler2D1_Float4_Float1 =
+ TSymbolUniqueId(1085);
+ static constexpr const TSymbolUniqueId textureProj_ISampler2D1_Float4_Float1 =
+ TSymbolUniqueId(1086);
+ static constexpr const TSymbolUniqueId textureProj_USampler2D1_Float4_Float1 =
+ TSymbolUniqueId(1087);
+ static constexpr const TSymbolUniqueId textureProj_Sampler3D1_Float4_Float1 =
+ TSymbolUniqueId(1088);
+ static constexpr const TSymbolUniqueId textureProj_ISampler3D1_Float4_Float1 =
+ TSymbolUniqueId(1089);
+ static constexpr const TSymbolUniqueId textureProj_USampler3D1_Float4_Float1 =
+ TSymbolUniqueId(1090);
+ static constexpr const TSymbolUniqueId texture_Sampler2DShadow1_Float3_Float1 =
+ TSymbolUniqueId(1091);
+ static constexpr const TSymbolUniqueId texture_SamplerCubeShadow1_Float4_Float1 =
+ TSymbolUniqueId(1092);
+ static constexpr const TSymbolUniqueId textureProj_Sampler2DShadow1_Float4_Float1 =
+ TSymbolUniqueId(1093);
+ static constexpr const TSymbolUniqueId texture_Sampler1D1_Float1_Float1 = TSymbolUniqueId(1094);
+ static constexpr const TSymbolUniqueId texture_ISampler1D1_Float1_Float1 =
+ TSymbolUniqueId(1095);
+ static constexpr const TSymbolUniqueId texture_USampler1D1_Float1_Float1 =
+ TSymbolUniqueId(1096);
+ static constexpr const TSymbolUniqueId texture_Sampler1DShadow1_Float3_Float1 =
+ TSymbolUniqueId(1097);
+ static constexpr const TSymbolUniqueId texture_Sampler1DArray1_Float3_Float1 =
+ TSymbolUniqueId(1098);
+ static constexpr const TSymbolUniqueId texture_ISampler1DArray1_Float3_Float1 =
+ TSymbolUniqueId(1099);
+ static constexpr const TSymbolUniqueId texture_USampler1DArray1_Float3_Float1 =
+ TSymbolUniqueId(1100);
+ static constexpr const TSymbolUniqueId texture_Sampler1DArrayShadow1_Float3_Float1 =
+ TSymbolUniqueId(1101);
+ static constexpr const TSymbolUniqueId texture_Sampler2DArrayShadow1_Float4_Float1 =
+ TSymbolUniqueId(1102);
+ static constexpr const TSymbolUniqueId textureProj_Sampler1D1_Float2_Float1 =
+ TSymbolUniqueId(1103);
+ static constexpr const TSymbolUniqueId textureProj_ISampler1D1_Float2_Float1 =
+ TSymbolUniqueId(1104);
+ static constexpr const TSymbolUniqueId textureProj_USampler1D1_Float2_Float1 =
+ TSymbolUniqueId(1105);
+ static constexpr const TSymbolUniqueId textureProj_Sampler1D1_Float4_Float1 =
+ TSymbolUniqueId(1106);
+ static constexpr const TSymbolUniqueId textureProj_ISampler1D1_Float4_Float1 =
+ TSymbolUniqueId(1107);
+ static constexpr const TSymbolUniqueId textureProj_USampler1D1_Float4_Float1 =
+ TSymbolUniqueId(1108);
+ static constexpr const TSymbolUniqueId textureProj_Sampler1DShadow1_Float4_Float1 =
+ TSymbolUniqueId(1109);
+ static constexpr const TSymbolUniqueId texture_SamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(1110);
+ static constexpr const TSymbolUniqueId texture_ISamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(1111);
+ static constexpr const TSymbolUniqueId texture_USamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(1112);
+ static constexpr const TSymbolUniqueId textureExt_SamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(1113);
+ static constexpr const TSymbolUniqueId textureExt_ISamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(1114);
+ static constexpr const TSymbolUniqueId textureExt_USamplerCubeArray1_Float4_Float1 =
+ TSymbolUniqueId(1115);
+ static constexpr const TSymbolUniqueId texture_SamplerExternalOES1_Float2_Float1 =
+ TSymbolUniqueId(1116);
+ static constexpr const TSymbolUniqueId textureProj_SamplerExternalOES1_Float3_Float1 =
+ TSymbolUniqueId(1117);
+ static constexpr const TSymbolUniqueId textureProj_SamplerExternalOES1_Float4_Float1 =
+ TSymbolUniqueId(1118);
+ static constexpr const TSymbolUniqueId texture_SamplerExternal2DY2YEXT1_Float2_Float1 =
+ TSymbolUniqueId(1119);
+ static constexpr const TSymbolUniqueId textureProj_SamplerExternal2DY2YEXT1_Float3_Float1 =
+ TSymbolUniqueId(1120);
+ static constexpr const TSymbolUniqueId textureProj_SamplerExternal2DY2YEXT1_Float4_Float1 =
+ TSymbolUniqueId(1121);
+ static constexpr const TSymbolUniqueId textureQueryLod_Sampler1D1_Float1 =
+ TSymbolUniqueId(1122);
+ static constexpr const TSymbolUniqueId textureQueryLod_ISampler1D1_Float1 =
+ TSymbolUniqueId(1123);
+ static constexpr const TSymbolUniqueId textureQueryLod_USampler1D1_Float1 =
+ TSymbolUniqueId(1124);
+ static constexpr const TSymbolUniqueId textureQueryLod_Sampler2D1_Float2 =
+ TSymbolUniqueId(1125);
+ static constexpr const TSymbolUniqueId textureQueryLod_ISampler2D1_Float2 =
+ TSymbolUniqueId(1126);
+ static constexpr const TSymbolUniqueId textureQueryLod_USampler2D1_Float2 =
+ TSymbolUniqueId(1127);
+ static constexpr const TSymbolUniqueId textureQueryLod_Sampler3D1_Float3 =
+ TSymbolUniqueId(1128);
+ static constexpr const TSymbolUniqueId textureQueryLod_ISampler3D1_Float3 =
+ TSymbolUniqueId(1129);
+ static constexpr const TSymbolUniqueId textureQueryLod_USampler3D1_Float3 =
+ TSymbolUniqueId(1130);
+ static constexpr const TSymbolUniqueId textureQueryLod_SamplerCube1_Float3 =
+ TSymbolUniqueId(1131);
+ static constexpr const TSymbolUniqueId textureQueryLod_ISamplerCube1_Float3 =
+ TSymbolUniqueId(1132);
+ static constexpr const TSymbolUniqueId textureQueryLod_USamplerCube1_Float3 =
+ TSymbolUniqueId(1133);
+ static constexpr const TSymbolUniqueId textureQueryLod_Sampler1DArray1_Float1 =
+ TSymbolUniqueId(1134);
+ static constexpr const TSymbolUniqueId textureQueryLod_ISampler1DArray1_Float1 =
+ TSymbolUniqueId(1135);
+ static constexpr const TSymbolUniqueId textureQueryLod_USampler1DArray1_Float1 =
+ TSymbolUniqueId(1136);
+ static constexpr const TSymbolUniqueId textureQueryLod_Sampler2DArray1_Float2 =
+ TSymbolUniqueId(1137);
+ static constexpr const TSymbolUniqueId textureQueryLod_ISampler2DArray1_Float2 =
+ TSymbolUniqueId(1138);
+ static constexpr const TSymbolUniqueId textureQueryLod_USampler2DArray1_Float2 =
+ TSymbolUniqueId(1139);
+ static constexpr const TSymbolUniqueId textureQueryLod_SamplerCubeArray1_Float3 =
+ TSymbolUniqueId(1140);
+ static constexpr const TSymbolUniqueId textureQueryLod_ISamplerCubeArray1_Float3 =
+ TSymbolUniqueId(1141);
+ static constexpr const TSymbolUniqueId textureQueryLod_USamplerCubeArray1_Float3 =
+ TSymbolUniqueId(1142);
+ static constexpr const TSymbolUniqueId textureQueryLod_Sampler1DShadow1_Float1 =
+ TSymbolUniqueId(1143);
+ static constexpr const TSymbolUniqueId textureQueryLod_Sampler2DShadow1_Float2 =
+ TSymbolUniqueId(1144);
+ static constexpr const TSymbolUniqueId textureQueryLod_SamplerCubeShadow1_Float3 =
+ TSymbolUniqueId(1145);
+ static constexpr const TSymbolUniqueId textureQueryLod_Sampler1DArrayShadow1_Float1 =
+ TSymbolUniqueId(1146);
+ static constexpr const TSymbolUniqueId textureQueryLod_Sampler2DArrayShadow1_Float2 =
+ TSymbolUniqueId(1147);
+ static constexpr const TSymbolUniqueId textureQueryLod_SamplerCubeArrayShadow1_Float3 =
+ TSymbolUniqueId(1148);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler2D1_Float2_Int2 =
+ TSymbolUniqueId(1149);
+ static constexpr const TSymbolUniqueId textureOffset_ISampler2D1_Float2_Int2 =
+ TSymbolUniqueId(1150);
+ static constexpr const TSymbolUniqueId textureOffset_USampler2D1_Float2_Int2 =
+ TSymbolUniqueId(1151);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler3D1_Float3_Int3 =
+ TSymbolUniqueId(1152);
+ static constexpr const TSymbolUniqueId textureOffset_ISampler3D1_Float3_Int3 =
+ TSymbolUniqueId(1153);
+ static constexpr const TSymbolUniqueId textureOffset_USampler3D1_Float3_Int3 =
+ TSymbolUniqueId(1154);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler2DShadow1_Float3_Int2 =
+ TSymbolUniqueId(1155);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler2DArray1_Float3_Int2 =
+ TSymbolUniqueId(1156);
+ static constexpr const TSymbolUniqueId textureOffset_ISampler2DArray1_Float3_Int2 =
+ TSymbolUniqueId(1157);
+ static constexpr const TSymbolUniqueId textureOffset_USampler2DArray1_Float3_Int2 =
+ TSymbolUniqueId(1158);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler1D1_Float1_Int1 =
+ TSymbolUniqueId(1159);
+ static constexpr const TSymbolUniqueId textureOffset_ISampler1D1_Float1_Int1 =
+ TSymbolUniqueId(1160);
+ static constexpr const TSymbolUniqueId textureOffset_USampler1D1_Float1_Int1 =
+ TSymbolUniqueId(1161);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler2DRect1_Float2_Int2 =
+ TSymbolUniqueId(1162);
+ static constexpr const TSymbolUniqueId textureOffset_ISampler2DRect1_Float2_Int2 =
+ TSymbolUniqueId(1163);
+ static constexpr const TSymbolUniqueId textureOffset_USampler2DRect1_Float2_Int2 =
+ TSymbolUniqueId(1164);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler2DRectShadow1_Float3_Int2 =
+ TSymbolUniqueId(1165);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler1DShadow1_Float3_Int1 =
+ TSymbolUniqueId(1166);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler1DArray1_Float2_Int1 =
+ TSymbolUniqueId(1167);
+ static constexpr const TSymbolUniqueId textureOffset_ISampler1DArray1_Float2_Int1 =
+ TSymbolUniqueId(1168);
+ static constexpr const TSymbolUniqueId textureOffset_USampler1DArray1_Float2_Int1 =
+ TSymbolUniqueId(1169);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler1DArrayShadow1_Float3_Int1 =
+ TSymbolUniqueId(1170);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler2DArrayShadow1_Float4_Int2 =
+ TSymbolUniqueId(1171);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler2D1_Float3_Int2 =
+ TSymbolUniqueId(1172);
+ static constexpr const TSymbolUniqueId textureProjOffset_ISampler2D1_Float3_Int2 =
+ TSymbolUniqueId(1173);
+ static constexpr const TSymbolUniqueId textureProjOffset_USampler2D1_Float3_Int2 =
+ TSymbolUniqueId(1174);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler2D1_Float4_Int2 =
+ TSymbolUniqueId(1175);
+ static constexpr const TSymbolUniqueId textureProjOffset_ISampler2D1_Float4_Int2 =
+ TSymbolUniqueId(1176);
+ static constexpr const TSymbolUniqueId textureProjOffset_USampler2D1_Float4_Int2 =
+ TSymbolUniqueId(1177);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler3D1_Float4_Int3 =
+ TSymbolUniqueId(1178);
+ static constexpr const TSymbolUniqueId textureProjOffset_ISampler3D1_Float4_Int3 =
+ TSymbolUniqueId(1179);
+ static constexpr const TSymbolUniqueId textureProjOffset_USampler3D1_Float4_Int3 =
+ TSymbolUniqueId(1180);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler2DShadow1_Float4_Int2 =
+ TSymbolUniqueId(1181);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler1D1_Float2_Int1 =
+ TSymbolUniqueId(1182);
+ static constexpr const TSymbolUniqueId textureProjOffset_ISampler1D1_Float2_Int1 =
+ TSymbolUniqueId(1183);
+ static constexpr const TSymbolUniqueId textureProjOffset_USampler1D1_Float2_Int1 =
+ TSymbolUniqueId(1184);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler1D1_Float4_Int1 =
+ TSymbolUniqueId(1185);
+ static constexpr const TSymbolUniqueId textureProjOffset_ISampler1D1_Float4_Int1 =
+ TSymbolUniqueId(1186);
+ static constexpr const TSymbolUniqueId textureProjOffset_USampler1D1_Float4_Int1 =
+ TSymbolUniqueId(1187);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler2DRect1_Float3_Int2 =
+ TSymbolUniqueId(1188);
+ static constexpr const TSymbolUniqueId textureProjOffset_ISampler2DRect1_Float3_Int2 =
+ TSymbolUniqueId(1189);
+ static constexpr const TSymbolUniqueId textureProjOffset_USampler2DRect1_Float3_Int2 =
+ TSymbolUniqueId(1190);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler2DRect1_Float4_Int2 =
+ TSymbolUniqueId(1191);
+ static constexpr const TSymbolUniqueId textureProjOffset_ISampler2DRect1_Float4_Int2 =
+ TSymbolUniqueId(1192);
+ static constexpr const TSymbolUniqueId textureProjOffset_USampler2DRect1_Float4_Int2 =
+ TSymbolUniqueId(1193);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler2DRectShadow1_Float4_Int2 =
+ TSymbolUniqueId(1194);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler1DShadow1_Float4_Int1 =
+ TSymbolUniqueId(1195);
+ static constexpr const TSymbolUniqueId textureLodOffset_Sampler2D1_Float2_Float1_Int2 =
+ TSymbolUniqueId(1196);
+ static constexpr const TSymbolUniqueId textureLodOffset_ISampler2D1_Float2_Float1_Int2 =
+ TSymbolUniqueId(1197);
+ static constexpr const TSymbolUniqueId textureLodOffset_USampler2D1_Float2_Float1_Int2 =
+ TSymbolUniqueId(1198);
+ static constexpr const TSymbolUniqueId textureLodOffset_Sampler3D1_Float3_Float1_Int3 =
+ TSymbolUniqueId(1199);
+ static constexpr const TSymbolUniqueId textureLodOffset_ISampler3D1_Float3_Float1_Int3 =
+ TSymbolUniqueId(1200);
+ static constexpr const TSymbolUniqueId textureLodOffset_USampler3D1_Float3_Float1_Int3 =
+ TSymbolUniqueId(1201);
+ static constexpr const TSymbolUniqueId textureLodOffset_Sampler2DShadow1_Float3_Float1_Int2 =
+ TSymbolUniqueId(1202);
+ static constexpr const TSymbolUniqueId textureLodOffset_Sampler2DArray1_Float3_Float1_Int2 =
+ TSymbolUniqueId(1203);
+ static constexpr const TSymbolUniqueId textureLodOffset_ISampler2DArray1_Float3_Float1_Int2 =
+ TSymbolUniqueId(1204);
+ static constexpr const TSymbolUniqueId textureLodOffset_USampler2DArray1_Float3_Float1_Int2 =
+ TSymbolUniqueId(1205);
+ static constexpr const TSymbolUniqueId textureLodOffset_Sampler1D1_Float1_Float1_Int1 =
+ TSymbolUniqueId(1206);
+ static constexpr const TSymbolUniqueId textureLodOffset_ISampler1D1_Float1_Float1_Int1 =
+ TSymbolUniqueId(1207);
+ static constexpr const TSymbolUniqueId textureLodOffset_USampler1D1_Float1_Float1_Int1 =
+ TSymbolUniqueId(1208);
+ static constexpr const TSymbolUniqueId textureLodOffset_Sampler1DShadow1_Float3_Float1_Int1 =
+ TSymbolUniqueId(1209);
+ static constexpr const TSymbolUniqueId textureLodOffset_Sampler1DArray1_Float2_Float1_Int1 =
+ TSymbolUniqueId(1210);
+ static constexpr const TSymbolUniqueId textureLodOffset_ISampler1DArray1_Float2_Float1_Int1 =
+ TSymbolUniqueId(1211);
+ static constexpr const TSymbolUniqueId textureLodOffset_USampler1DArray1_Float2_Float1_Int1 =
+ TSymbolUniqueId(1212);
+ static constexpr const TSymbolUniqueId
+ textureLodOffset_Sampler1DArrayShadow1_Float3_Float1_Int1 = TSymbolUniqueId(1213);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_Sampler2D1_Float3_Float1_Int2 =
+ TSymbolUniqueId(1214);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_ISampler2D1_Float3_Float1_Int2 =
+ TSymbolUniqueId(1215);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_USampler2D1_Float3_Float1_Int2 =
+ TSymbolUniqueId(1216);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_Sampler2D1_Float4_Float1_Int2 =
+ TSymbolUniqueId(1217);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_ISampler2D1_Float4_Float1_Int2 =
+ TSymbolUniqueId(1218);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_USampler2D1_Float4_Float1_Int2 =
+ TSymbolUniqueId(1219);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_Sampler3D1_Float4_Float1_Int3 =
+ TSymbolUniqueId(1220);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_ISampler3D1_Float4_Float1_Int3 =
+ TSymbolUniqueId(1221);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_USampler3D1_Float4_Float1_Int3 =
+ TSymbolUniqueId(1222);
+ static constexpr const TSymbolUniqueId
+ textureProjLodOffset_Sampler2DShadow1_Float4_Float1_Int2 = TSymbolUniqueId(1223);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_Sampler1D1_Float2_Float1_Int1 =
+ TSymbolUniqueId(1224);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_ISampler1D1_Float2_Float1_Int1 =
+ TSymbolUniqueId(1225);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_USampler1D1_Float2_Float1_Int1 =
+ TSymbolUniqueId(1226);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_Sampler1D1_Float4_Float1_Int1 =
+ TSymbolUniqueId(1227);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_ISampler1D1_Float4_Float1_Int1 =
+ TSymbolUniqueId(1228);
+ static constexpr const TSymbolUniqueId textureProjLodOffset_USampler1D1_Float4_Float1_Int1 =
+ TSymbolUniqueId(1229);
+ static constexpr const TSymbolUniqueId
+ textureProjLodOffset_Sampler1DShadow1_Float4_Float1_Int1 = TSymbolUniqueId(1230);
+ static constexpr const TSymbolUniqueId texelFetchOffset_Sampler2D1_Int2_Int1_Int2 =
+ TSymbolUniqueId(1231);
+ static constexpr const TSymbolUniqueId texelFetchOffset_ISampler2D1_Int2_Int1_Int2 =
+ TSymbolUniqueId(1232);
+ static constexpr const TSymbolUniqueId texelFetchOffset_USampler2D1_Int2_Int1_Int2 =
+ TSymbolUniqueId(1233);
+ static constexpr const TSymbolUniqueId texelFetchOffset_Sampler3D1_Int3_Int1_Int3 =
+ TSymbolUniqueId(1234);
+ static constexpr const TSymbolUniqueId texelFetchOffset_ISampler3D1_Int3_Int1_Int3 =
+ TSymbolUniqueId(1235);
+ static constexpr const TSymbolUniqueId texelFetchOffset_USampler3D1_Int3_Int1_Int3 =
+ TSymbolUniqueId(1236);
+ static constexpr const TSymbolUniqueId texelFetchOffset_Sampler2DArray1_Int3_Int1_Int2 =
+ TSymbolUniqueId(1237);
+ static constexpr const TSymbolUniqueId texelFetchOffset_ISampler2DArray1_Int3_Int1_Int2 =
+ TSymbolUniqueId(1238);
+ static constexpr const TSymbolUniqueId texelFetchOffset_USampler2DArray1_Int3_Int1_Int2 =
+ TSymbolUniqueId(1239);
+ static constexpr const TSymbolUniqueId texelFetchOffset_Sampler1D1_Int1_Int1_Int1 =
+ TSymbolUniqueId(1240);
+ static constexpr const TSymbolUniqueId texelFetchOffset_ISampler1D1_Int1_Int1_Int1 =
+ TSymbolUniqueId(1241);
+ static constexpr const TSymbolUniqueId texelFetchOffset_USampler1D1_Int1_Int1_Int1 =
+ TSymbolUniqueId(1242);
+ static constexpr const TSymbolUniqueId texelFetchOffset_Sampler2DRect1_Int2_Int2 =
+ TSymbolUniqueId(1243);
+ static constexpr const TSymbolUniqueId texelFetchOffset_ISampler2DRect1_Int2_Int2 =
+ TSymbolUniqueId(1244);
+ static constexpr const TSymbolUniqueId texelFetchOffset_USampler2DRect1_Int2_Int2 =
+ TSymbolUniqueId(1245);
+ static constexpr const TSymbolUniqueId texelFetchOffset_Sampler1DArray1_Int2_Int1_Int1 =
+ TSymbolUniqueId(1246);
+ static constexpr const TSymbolUniqueId texelFetchOffset_ISampler1DArray1_Int2_Int1_Int1 =
+ TSymbolUniqueId(1247);
+ static constexpr const TSymbolUniqueId texelFetchOffset_USampler1DArray1_Int2_Int1_Int1 =
+ TSymbolUniqueId(1248);
+ static constexpr const TSymbolUniqueId textureGradOffset_Sampler2D1_Float2_Float2_Float2_Int2 =
+ TSymbolUniqueId(1249);
+ static constexpr const TSymbolUniqueId textureGradOffset_ISampler2D1_Float2_Float2_Float2_Int2 =
+ TSymbolUniqueId(1250);
+ static constexpr const TSymbolUniqueId textureGradOffset_USampler2D1_Float2_Float2_Float2_Int2 =
+ TSymbolUniqueId(1251);
+ static constexpr const TSymbolUniqueId textureGradOffset_Sampler3D1_Float3_Float3_Float3_Int3 =
+ TSymbolUniqueId(1252);
+ static constexpr const TSymbolUniqueId textureGradOffset_ISampler3D1_Float3_Float3_Float3_Int3 =
+ TSymbolUniqueId(1253);
+ static constexpr const TSymbolUniqueId textureGradOffset_USampler3D1_Float3_Float3_Float3_Int3 =
+ TSymbolUniqueId(1254);
+ static constexpr const TSymbolUniqueId
+ textureGradOffset_Sampler2DShadow1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(1255);
+ static constexpr const TSymbolUniqueId
+ textureGradOffset_Sampler2DArray1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(1256);
+ static constexpr const TSymbolUniqueId
+ textureGradOffset_ISampler2DArray1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(1257);
+ static constexpr const TSymbolUniqueId
+ textureGradOffset_USampler2DArray1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(1258);
+ static constexpr const TSymbolUniqueId
+ textureGradOffset_Sampler2DArrayShadow1_Float4_Float2_Float2_Int2 = TSymbolUniqueId(1259);
+ static constexpr const TSymbolUniqueId textureGradOffset_Sampler1D1_Float1_Float1_Float1_Int1 =
+ TSymbolUniqueId(1260);
+ static constexpr const TSymbolUniqueId textureGradOffset_ISampler1D1_Float1_Float1_Float1_Int1 =
+ TSymbolUniqueId(1261);
+ static constexpr const TSymbolUniqueId textureGradOffset_USampler1D1_Float1_Float1_Float1_Int1 =
+ TSymbolUniqueId(1262);
+ static constexpr const TSymbolUniqueId
+ textureGradOffset_Sampler2DRect1_Float2_Float2_Float2_Int2 = TSymbolUniqueId(1263);
+ static constexpr const TSymbolUniqueId
+ textureGradOffset_ISampler2DRect1_Float2_Float2_Float2_Int2 = TSymbolUniqueId(1264);
+ static constexpr const TSymbolUniqueId
+ textureGradOffset_USampler2DRect1_Float2_Float2_Float2_Int2 = TSymbolUniqueId(1265);
+ static constexpr const TSymbolUniqueId
+ textureGradOffset_Sampler2DRectShadow1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(1266);
+ static constexpr const TSymbolUniqueId
+ textureGradOffset_Sampler1DShadow1_Float3_Float1_Float1_Int1 = TSymbolUniqueId(1267);
+ static constexpr const TSymbolUniqueId
+ textureGradOffset_Sampler1DArray1_Float2_Float1_Float1_Int1 = TSymbolUniqueId(1268);
+ static constexpr const TSymbolUniqueId
+ textureGradOffset_ISampler1DArray1_Float2_Float1_Float1_Int1 = TSymbolUniqueId(1269);
+ static constexpr const TSymbolUniqueId
+ textureGradOffset_USampler1DArray1_Float2_Float1_Float1_Int1 = TSymbolUniqueId(1270);
+ static constexpr const TSymbolUniqueId
+ textureGradOffset_Sampler1DArrayShadow1_Float3_Float1_Float1_Int1 = TSymbolUniqueId(1271);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_Sampler2D1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(1272);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_ISampler2D1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(1273);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_USampler2D1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(1274);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_Sampler2D1_Float4_Float2_Float2_Int2 = TSymbolUniqueId(1275);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_ISampler2D1_Float4_Float2_Float2_Int2 = TSymbolUniqueId(1276);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_USampler2D1_Float4_Float2_Float2_Int2 = TSymbolUniqueId(1277);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_Sampler3D1_Float4_Float3_Float3_Int3 = TSymbolUniqueId(1278);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_ISampler3D1_Float4_Float3_Float3_Int3 = TSymbolUniqueId(1279);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_USampler3D1_Float4_Float3_Float3_Int3 = TSymbolUniqueId(1280);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_Sampler2DShadow1_Float4_Float2_Float2_Int2 = TSymbolUniqueId(1281);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_Sampler1D1_Float2_Float1_Float1_Int1 = TSymbolUniqueId(1282);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_ISampler1D1_Float2_Float1_Float1_Int1 = TSymbolUniqueId(1283);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_USampler1D1_Float2_Float1_Float1_Int1 = TSymbolUniqueId(1284);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_Sampler1D1_Float4_Float1_Float1_Int1 = TSymbolUniqueId(1285);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_ISampler1D1_Float4_Float1_Float1_Int1 = TSymbolUniqueId(1286);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_USampler1D1_Float4_Float1_Float1_Int1 = TSymbolUniqueId(1287);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_Sampler2DRect1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(1288);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_ISampler2DRect1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(1289);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_USampler2DRect1_Float3_Float2_Float2_Int2 = TSymbolUniqueId(1290);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_Sampler2DRect1_Float4_Float2_Float2_Int2 = TSymbolUniqueId(1291);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_ISampler2DRect1_Float4_Float2_Float2_Int2 = TSymbolUniqueId(1292);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_USampler2DRect1_Float4_Float2_Float2_Int2 = TSymbolUniqueId(1293);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_Sampler2DRectShadow1_Float4_Float2_Float2_Int2 =
+ TSymbolUniqueId(1294);
+ static constexpr const TSymbolUniqueId
+ textureProjGradOffset_Sampler1DShadow1_Float4_Float1_Float1_Int1 = TSymbolUniqueId(1295);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler2D1_Float2_Int2_Float1 =
+ TSymbolUniqueId(1296);
+ static constexpr const TSymbolUniqueId textureOffset_ISampler2D1_Float2_Int2_Float1 =
+ TSymbolUniqueId(1297);
+ static constexpr const TSymbolUniqueId textureOffset_USampler2D1_Float2_Int2_Float1 =
+ TSymbolUniqueId(1298);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler3D1_Float3_Int3_Float1 =
+ TSymbolUniqueId(1299);
+ static constexpr const TSymbolUniqueId textureOffset_ISampler3D1_Float3_Int3_Float1 =
+ TSymbolUniqueId(1300);
+ static constexpr const TSymbolUniqueId textureOffset_USampler3D1_Float3_Int3_Float1 =
+ TSymbolUniqueId(1301);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler2DShadow1_Float3_Int2_Float1 =
+ TSymbolUniqueId(1302);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler2DArray1_Float3_Int2_Float1 =
+ TSymbolUniqueId(1303);
+ static constexpr const TSymbolUniqueId textureOffset_ISampler2DArray1_Float3_Int2_Float1 =
+ TSymbolUniqueId(1304);
+ static constexpr const TSymbolUniqueId textureOffset_USampler2DArray1_Float3_Int2_Float1 =
+ TSymbolUniqueId(1305);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler1D1_Float1_Int1_Float1 =
+ TSymbolUniqueId(1306);
+ static constexpr const TSymbolUniqueId textureOffset_ISampler1D1_Float1_Int1_Float1 =
+ TSymbolUniqueId(1307);
+ static constexpr const TSymbolUniqueId textureOffset_USampler1D1_Float1_Int1_Float1 =
+ TSymbolUniqueId(1308);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler1DShadow1_Float3_Int1_Float1 =
+ TSymbolUniqueId(1309);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler1DArray1_Float2_Int1_Float1 =
+ TSymbolUniqueId(1310);
+ static constexpr const TSymbolUniqueId textureOffset_ISampler1DArray1_Float2_Int1_Float1 =
+ TSymbolUniqueId(1311);
+ static constexpr const TSymbolUniqueId textureOffset_USampler1DArray1_Float2_Int1_Float1 =
+ TSymbolUniqueId(1312);
+ static constexpr const TSymbolUniqueId textureOffset_Sampler1DArrayShadow1_Float3_Int1_Float1 =
+ TSymbolUniqueId(1313);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler2D1_Float3_Int2_Float1 =
+ TSymbolUniqueId(1314);
+ static constexpr const TSymbolUniqueId textureProjOffset_ISampler2D1_Float3_Int2_Float1 =
+ TSymbolUniqueId(1315);
+ static constexpr const TSymbolUniqueId textureProjOffset_USampler2D1_Float3_Int2_Float1 =
+ TSymbolUniqueId(1316);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler2D1_Float4_Int2_Float1 =
+ TSymbolUniqueId(1317);
+ static constexpr const TSymbolUniqueId textureProjOffset_ISampler2D1_Float4_Int2_Float1 =
+ TSymbolUniqueId(1318);
+ static constexpr const TSymbolUniqueId textureProjOffset_USampler2D1_Float4_Int2_Float1 =
+ TSymbolUniqueId(1319);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler3D1_Float4_Int3_Float1 =
+ TSymbolUniqueId(1320);
+ static constexpr const TSymbolUniqueId textureProjOffset_ISampler3D1_Float4_Int3_Float1 =
+ TSymbolUniqueId(1321);
+ static constexpr const TSymbolUniqueId textureProjOffset_USampler3D1_Float4_Int3_Float1 =
+ TSymbolUniqueId(1322);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler2DShadow1_Float4_Int2_Float1 =
+ TSymbolUniqueId(1323);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler1D1_Float2_Int1_Float1 =
+ TSymbolUniqueId(1324);
+ static constexpr const TSymbolUniqueId textureProjOffset_ISampler1D1_Float2_Int1_Float1 =
+ TSymbolUniqueId(1325);
+ static constexpr const TSymbolUniqueId textureProjOffset_USampler1D1_Float2_Int1_Float1 =
+ TSymbolUniqueId(1326);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler1D1_Float4_Int1_Float1 =
+ TSymbolUniqueId(1327);
+ static constexpr const TSymbolUniqueId textureProjOffset_ISampler1D1_Float4_Int1_Float1 =
+ TSymbolUniqueId(1328);
+ static constexpr const TSymbolUniqueId textureProjOffset_USampler1D1_Float4_Int1_Float1 =
+ TSymbolUniqueId(1329);
+ static constexpr const TSymbolUniqueId textureProjOffset_Sampler1DShadow1_Float4_Int1_Float1 =
+ TSymbolUniqueId(1330);
+ static constexpr const TSymbolUniqueId textureGather_Sampler2D1_Float2 = TSymbolUniqueId(1331);
+ static constexpr const TSymbolUniqueId textureGather_ISampler2D1_Float2 = TSymbolUniqueId(1332);
+ static constexpr const TSymbolUniqueId textureGather_USampler2D1_Float2 = TSymbolUniqueId(1333);
+ static constexpr const TSymbolUniqueId textureGather_Sampler2D1_Float2_Int1 =
+ TSymbolUniqueId(1334);
+ static constexpr const TSymbolUniqueId textureGather_ISampler2D1_Float2_Int1 =
+ TSymbolUniqueId(1335);
+ static constexpr const TSymbolUniqueId textureGather_USampler2D1_Float2_Int1 =
+ TSymbolUniqueId(1336);
+ static constexpr const TSymbolUniqueId textureGather_Sampler2DArray1_Float3 =
+ TSymbolUniqueId(1337);
+ static constexpr const TSymbolUniqueId textureGather_ISampler2DArray1_Float3 =
+ TSymbolUniqueId(1338);
+ static constexpr const TSymbolUniqueId textureGather_USampler2DArray1_Float3 =
+ TSymbolUniqueId(1339);
+ static constexpr const TSymbolUniqueId textureGather_Sampler2DArray1_Float3_Int1 =
+ TSymbolUniqueId(1340);
+ static constexpr const TSymbolUniqueId textureGather_ISampler2DArray1_Float3_Int1 =
+ TSymbolUniqueId(1341);
+ static constexpr const TSymbolUniqueId textureGather_USampler2DArray1_Float3_Int1 =
+ TSymbolUniqueId(1342);
+ static constexpr const TSymbolUniqueId textureGather_SamplerCube1_Float3 =
+ TSymbolUniqueId(1343);
+ static constexpr const TSymbolUniqueId textureGather_ISamplerCube1_Float3 =
+ TSymbolUniqueId(1344);
+ static constexpr const TSymbolUniqueId textureGather_USamplerCube1_Float3 =
+ TSymbolUniqueId(1345);
+ static constexpr const TSymbolUniqueId textureGather_SamplerCube1_Float3_Int1 =
+ TSymbolUniqueId(1346);
+ static constexpr const TSymbolUniqueId textureGather_ISamplerCube1_Float3_Int1 =
+ TSymbolUniqueId(1347);
+ static constexpr const TSymbolUniqueId textureGather_USamplerCube1_Float3_Int1 =
+ TSymbolUniqueId(1348);
+ static constexpr const TSymbolUniqueId textureGather_SamplerCubeArray1_Float4 =
+ TSymbolUniqueId(1349);
+ static constexpr const TSymbolUniqueId textureGather_ISamplerCubeArray1_Float4 =
+ TSymbolUniqueId(1350);
+ static constexpr const TSymbolUniqueId textureGather_USamplerCubeArray1_Float4 =
+ TSymbolUniqueId(1351);
+ static constexpr const TSymbolUniqueId textureGather_SamplerCubeArray1_Float4_Int1 =
+ TSymbolUniqueId(1352);
+ static constexpr const TSymbolUniqueId textureGather_ISamplerCubeArray1_Float4_Int1 =
+ TSymbolUniqueId(1353);
+ static constexpr const TSymbolUniqueId textureGather_USamplerCubeArray1_Float4_Int1 =
+ TSymbolUniqueId(1354);
+ static constexpr const TSymbolUniqueId textureGather_SamplerCubeArrayShadow1_Float4_Float1 =
+ TSymbolUniqueId(1355);
+ static constexpr const TSymbolUniqueId textureGatherExt_SamplerCubeArray1_Float4 =
+ TSymbolUniqueId(1356);
+ static constexpr const TSymbolUniqueId textureGatherExt_ISamplerCubeArray1_Float4 =
+ TSymbolUniqueId(1357);
+ static constexpr const TSymbolUniqueId textureGatherExt_USamplerCubeArray1_Float4 =
+ TSymbolUniqueId(1358);
+ static constexpr const TSymbolUniqueId textureGatherExt_SamplerCubeArray1_Float4_Int1 =
+ TSymbolUniqueId(1359);
+ static constexpr const TSymbolUniqueId textureGatherExt_ISamplerCubeArray1_Float4_Int1 =
+ TSymbolUniqueId(1360);
+ static constexpr const TSymbolUniqueId textureGatherExt_USamplerCubeArray1_Float4_Int1 =
+ TSymbolUniqueId(1361);
+ static constexpr const TSymbolUniqueId textureGatherExt_SamplerCubeArrayShadow1_Float4_Float1 =
+ TSymbolUniqueId(1362);
+ static constexpr const TSymbolUniqueId textureGather_Sampler2DRect1_Float3 =
+ TSymbolUniqueId(1363);
+ static constexpr const TSymbolUniqueId textureGather_ISampler2DRect1_Float3 =
+ TSymbolUniqueId(1364);
+ static constexpr const TSymbolUniqueId textureGather_USampler2DRect1_Float3 =
+ TSymbolUniqueId(1365);
+ static constexpr const TSymbolUniqueId textureGather_Sampler2DRect1_Float3_Int1 =
+ TSymbolUniqueId(1366);
+ static constexpr const TSymbolUniqueId textureGather_ISampler2DRect1_Float3_Int1 =
+ TSymbolUniqueId(1367);
+ static constexpr const TSymbolUniqueId textureGather_USampler2DRect1_Float3_Int1 =
+ TSymbolUniqueId(1368);
+ static constexpr const TSymbolUniqueId textureGather_Sampler2DRectShadow1_Float2_Float1 =
+ TSymbolUniqueId(1369);
+ static constexpr const TSymbolUniqueId textureGather_Sampler2DShadow1_Float2 =
+ TSymbolUniqueId(1370);
+ static constexpr const TSymbolUniqueId textureGather_Sampler2DShadow1_Float2_Float1 =
+ TSymbolUniqueId(1371);
+ static constexpr const TSymbolUniqueId textureGather_Sampler2DArrayShadow1_Float3 =
+ TSymbolUniqueId(1372);
+ static constexpr const TSymbolUniqueId textureGather_Sampler2DArrayShadow1_Float3_Float1 =
+ TSymbolUniqueId(1373);
+ static constexpr const TSymbolUniqueId textureGather_SamplerCubeShadow1_Float3 =
+ TSymbolUniqueId(1374);
+ static constexpr const TSymbolUniqueId textureGather_SamplerCubeShadow1_Float3_Float1 =
+ TSymbolUniqueId(1375);
+ static constexpr const TSymbolUniqueId textureGatherOffset_Sampler2D1_Float2_Int2 =
+ TSymbolUniqueId(1376);
+ static constexpr const TSymbolUniqueId textureGatherOffset_ISampler2D1_Float2_Int2 =
+ TSymbolUniqueId(1377);
+ static constexpr const TSymbolUniqueId textureGatherOffset_USampler2D1_Float2_Int2 =
+ TSymbolUniqueId(1378);
+ static constexpr const TSymbolUniqueId textureGatherOffset_Sampler2DArray1_Float3_Int2 =
+ TSymbolUniqueId(1379);
+ static constexpr const TSymbolUniqueId textureGatherOffset_ISampler2DArray1_Float3_Int2 =
+ TSymbolUniqueId(1380);
+ static constexpr const TSymbolUniqueId textureGatherOffset_USampler2DArray1_Float3_Int2 =
+ TSymbolUniqueId(1381);
+ static constexpr const TSymbolUniqueId textureGatherOffset_Sampler2DShadow1_Float2_Float1_Int2 =
+ TSymbolUniqueId(1382);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffset_Sampler2DArrayShadow1_Float3_Float1_Int2 = TSymbolUniqueId(1383);
+ static constexpr const TSymbolUniqueId textureGatherOffset_Sampler2DRect1_Float2_Int2 =
+ TSymbolUniqueId(1384);
+ static constexpr const TSymbolUniqueId textureGatherOffset_ISampler2DRect1_Float2_Int2 =
+ TSymbolUniqueId(1385);
+ static constexpr const TSymbolUniqueId textureGatherOffset_USampler2DRect1_Float2_Int2 =
+ TSymbolUniqueId(1386);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffset_Sampler2DRectShadow1_Float2_Float1_Int2 = TSymbolUniqueId(1387);
+ static constexpr const TSymbolUniqueId textureGatherOffset_Sampler2D1_Float2_Int2_Int1 =
+ TSymbolUniqueId(1388);
+ static constexpr const TSymbolUniqueId textureGatherOffset_ISampler2D1_Float2_Int2_Int1 =
+ TSymbolUniqueId(1389);
+ static constexpr const TSymbolUniqueId textureGatherOffset_USampler2D1_Float2_Int2_Int1 =
+ TSymbolUniqueId(1390);
+ static constexpr const TSymbolUniqueId textureGatherOffset_Sampler2DArray1_Float3_Int2_Int1 =
+ TSymbolUniqueId(1391);
+ static constexpr const TSymbolUniqueId textureGatherOffset_ISampler2DArray1_Float3_Int2_Int1 =
+ TSymbolUniqueId(1392);
+ static constexpr const TSymbolUniqueId textureGatherOffset_USampler2DArray1_Float3_Int2_Int1 =
+ TSymbolUniqueId(1393);
+ static constexpr const TSymbolUniqueId textureGatherOffset_Sampler2DRect1_Float2_Int2_Int1 =
+ TSymbolUniqueId(1394);
+ static constexpr const TSymbolUniqueId textureGatherOffset_ISampler2DRect1_Float2_Int2_Int1 =
+ TSymbolUniqueId(1395);
+ static constexpr const TSymbolUniqueId textureGatherOffset_USampler2DRect1_Float2_Int2_Int1 =
+ TSymbolUniqueId(1396);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_Sampler2D1_Float2_4xInt2 =
+ TSymbolUniqueId(1397);
+ static constexpr const TSymbolUniqueId pt10Dx4 = TSymbolUniqueId(1398);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_ISampler2D1_Float2_4xInt2 =
+ TSymbolUniqueId(1399);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_USampler2D1_Float2_4xInt2 =
+ TSymbolUniqueId(1400);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_Sampler2DArray1_Float3_4xInt2 =
+ TSymbolUniqueId(1401);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_ISampler2DArray1_Float3_4xInt2 =
+ TSymbolUniqueId(1402);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_USampler2DArray1_Float3_4xInt2 =
+ TSymbolUniqueId(1403);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffsets_Sampler2DShadow1_Float2_Float1_4xInt2 = TSymbolUniqueId(1404);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffsets_Sampler2DArrayShadow1_Float3_Float1_4xInt2 = TSymbolUniqueId(1405);
+ static constexpr const TSymbolUniqueId textureGatherOffsetsExt_Sampler2D1_Float2_4xInt2 =
+ TSymbolUniqueId(1406);
+ static constexpr const TSymbolUniqueId textureGatherOffsetsExt_ISampler2D1_Float2_4xInt2 =
+ TSymbolUniqueId(1407);
+ static constexpr const TSymbolUniqueId textureGatherOffsetsExt_USampler2D1_Float2_4xInt2 =
+ TSymbolUniqueId(1408);
+ static constexpr const TSymbolUniqueId textureGatherOffsetsExt_Sampler2DArray1_Float3_4xInt2 =
+ TSymbolUniqueId(1409);
+ static constexpr const TSymbolUniqueId textureGatherOffsetsExt_ISampler2DArray1_Float3_4xInt2 =
+ TSymbolUniqueId(1410);
+ static constexpr const TSymbolUniqueId textureGatherOffsetsExt_USampler2DArray1_Float3_4xInt2 =
+ TSymbolUniqueId(1411);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffsetsExt_Sampler2DShadow1_Float2_Float1_4xInt2 = TSymbolUniqueId(1412);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffsetsExt_Sampler2DArrayShadow1_Float3_Float1_4xInt2 = TSymbolUniqueId(1413);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_Sampler2DRect1_Float2_4xInt2 =
+ TSymbolUniqueId(1414);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_ISampler2DRect1_Float2_4xInt2 =
+ TSymbolUniqueId(1415);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_USampler2DRect1_Float2_4xInt2 =
+ TSymbolUniqueId(1416);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffsets_Sampler2DRectShadow1_Float2_Float1_4xInt2 = TSymbolUniqueId(1417);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_Sampler2D1_Float2_4xInt2_Int1 =
+ TSymbolUniqueId(1418);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_ISampler2D1_Float2_4xInt2_Int1 =
+ TSymbolUniqueId(1419);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_USampler2D1_Float2_4xInt2_Int1 =
+ TSymbolUniqueId(1420);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_Sampler2DArray1_Float3_4xInt2_Int1 =
+ TSymbolUniqueId(1421);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffsets_ISampler2DArray1_Float3_4xInt2_Int1 = TSymbolUniqueId(1422);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffsets_USampler2DArray1_Float3_4xInt2_Int1 = TSymbolUniqueId(1423);
+ static constexpr const TSymbolUniqueId textureGatherOffsetsExt_Sampler2D1_Float2_4xInt2_Int1 =
+ TSymbolUniqueId(1424);
+ static constexpr const TSymbolUniqueId textureGatherOffsetsExt_ISampler2D1_Float2_4xInt2_Int1 =
+ TSymbolUniqueId(1425);
+ static constexpr const TSymbolUniqueId textureGatherOffsetsExt_USampler2D1_Float2_4xInt2_Int1 =
+ TSymbolUniqueId(1426);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffsetsExt_Sampler2DArray1_Float3_4xInt2_Int1 = TSymbolUniqueId(1427);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffsetsExt_ISampler2DArray1_Float3_4xInt2_Int1 = TSymbolUniqueId(1428);
+ static constexpr const TSymbolUniqueId
+ textureGatherOffsetsExt_USampler2DArray1_Float3_4xInt2_Int1 = TSymbolUniqueId(1429);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_Sampler2DRect1_Float2_4xInt2_Int1 =
+ TSymbolUniqueId(1430);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_ISampler2DRect1_Float2_4xInt2_Int1 =
+ TSymbolUniqueId(1431);
+ static constexpr const TSymbolUniqueId textureGatherOffsets_USampler2DRect1_Float2_4xInt2_Int1 =
+ TSymbolUniqueId(1432);
+ static constexpr const TSymbolUniqueId rgb_2_yuv_Float3_YuvCscStandardEXT1 =
+ TSymbolUniqueId(1433);
+ static constexpr const TSymbolUniqueId pt00H = TSymbolUniqueId(1434);
+ static constexpr const TSymbolUniqueId yuv_2_rgb_Float3_YuvCscStandardEXT1 =
+ TSymbolUniqueId(1435);
+ static constexpr const TSymbolUniqueId dFdxExt_Float1 = TSymbolUniqueId(1436);
+ static constexpr const TSymbolUniqueId dFdxExt_Float2 = TSymbolUniqueId(1437);
+ static constexpr const TSymbolUniqueId dFdxExt_Float3 = TSymbolUniqueId(1438);
+ static constexpr const TSymbolUniqueId dFdxExt_Float4 = TSymbolUniqueId(1439);
+ static constexpr const TSymbolUniqueId dFdyExt_Float1 = TSymbolUniqueId(1440);
+ static constexpr const TSymbolUniqueId dFdyExt_Float2 = TSymbolUniqueId(1441);
+ static constexpr const TSymbolUniqueId dFdyExt_Float3 = TSymbolUniqueId(1442);
+ static constexpr const TSymbolUniqueId dFdyExt_Float4 = TSymbolUniqueId(1443);
+ static constexpr const TSymbolUniqueId fwidthExt_Float1 = TSymbolUniqueId(1444);
+ static constexpr const TSymbolUniqueId fwidthExt_Float2 = TSymbolUniqueId(1445);
+ static constexpr const TSymbolUniqueId fwidthExt_Float3 = TSymbolUniqueId(1446);
+ static constexpr const TSymbolUniqueId fwidthExt_Float4 = TSymbolUniqueId(1447);
+ static constexpr const TSymbolUniqueId dFdx_Float1 = TSymbolUniqueId(1448);
+ static constexpr const TSymbolUniqueId dFdx_Float2 = TSymbolUniqueId(1449);
+ static constexpr const TSymbolUniqueId dFdx_Float3 = TSymbolUniqueId(1450);
+ static constexpr const TSymbolUniqueId dFdx_Float4 = TSymbolUniqueId(1451);
+ static constexpr const TSymbolUniqueId dFdy_Float1 = TSymbolUniqueId(1452);
+ static constexpr const TSymbolUniqueId dFdy_Float2 = TSymbolUniqueId(1453);
+ static constexpr const TSymbolUniqueId dFdy_Float3 = TSymbolUniqueId(1454);
+ static constexpr const TSymbolUniqueId dFdy_Float4 = TSymbolUniqueId(1455);
+ static constexpr const TSymbolUniqueId fwidth_Float1 = TSymbolUniqueId(1456);
+ static constexpr const TSymbolUniqueId fwidth_Float2 = TSymbolUniqueId(1457);
+ static constexpr const TSymbolUniqueId fwidth_Float3 = TSymbolUniqueId(1458);
+ static constexpr const TSymbolUniqueId fwidth_Float4 = TSymbolUniqueId(1459);
+ static constexpr const TSymbolUniqueId dFdxFine_Float1 = TSymbolUniqueId(1460);
+ static constexpr const TSymbolUniqueId dFdxFine_Float2 = TSymbolUniqueId(1461);
+ static constexpr const TSymbolUniqueId dFdxFine_Float3 = TSymbolUniqueId(1462);
+ static constexpr const TSymbolUniqueId dFdxFine_Float4 = TSymbolUniqueId(1463);
+ static constexpr const TSymbolUniqueId dFdyFine_Float1 = TSymbolUniqueId(1464);
+ static constexpr const TSymbolUniqueId dFdyFine_Float2 = TSymbolUniqueId(1465);
+ static constexpr const TSymbolUniqueId dFdyFine_Float3 = TSymbolUniqueId(1466);
+ static constexpr const TSymbolUniqueId dFdyFine_Float4 = TSymbolUniqueId(1467);
+ static constexpr const TSymbolUniqueId dFdxCoarse_Float1 = TSymbolUniqueId(1468);
+ static constexpr const TSymbolUniqueId dFdxCoarse_Float2 = TSymbolUniqueId(1469);
+ static constexpr const TSymbolUniqueId dFdxCoarse_Float3 = TSymbolUniqueId(1470);
+ static constexpr const TSymbolUniqueId dFdxCoarse_Float4 = TSymbolUniqueId(1471);
+ static constexpr const TSymbolUniqueId dFdyCoarse_Float1 = TSymbolUniqueId(1472);
+ static constexpr const TSymbolUniqueId dFdyCoarse_Float2 = TSymbolUniqueId(1473);
+ static constexpr const TSymbolUniqueId dFdyCoarse_Float3 = TSymbolUniqueId(1474);
+ static constexpr const TSymbolUniqueId dFdyCoarse_Float4 = TSymbolUniqueId(1475);
+ static constexpr const TSymbolUniqueId fwidthFine_Float1 = TSymbolUniqueId(1476);
+ static constexpr const TSymbolUniqueId fwidthFine_Float2 = TSymbolUniqueId(1477);
+ static constexpr const TSymbolUniqueId fwidthFine_Float3 = TSymbolUniqueId(1478);
+ static constexpr const TSymbolUniqueId fwidthFine_Float4 = TSymbolUniqueId(1479);
+ static constexpr const TSymbolUniqueId fwidthCoarse_Float1 = TSymbolUniqueId(1480);
+ static constexpr const TSymbolUniqueId fwidthCoarse_Float2 = TSymbolUniqueId(1481);
+ static constexpr const TSymbolUniqueId fwidthCoarse_Float3 = TSymbolUniqueId(1482);
+ static constexpr const TSymbolUniqueId fwidthCoarse_Float4 = TSymbolUniqueId(1483);
+ static constexpr const TSymbolUniqueId interpolateAtCentroid_Float1 = TSymbolUniqueId(1484);
+ static constexpr const TSymbolUniqueId interpolateAtCentroid_Float2 = TSymbolUniqueId(1485);
+ static constexpr const TSymbolUniqueId interpolateAtCentroid_Float3 = TSymbolUniqueId(1486);
+ static constexpr const TSymbolUniqueId interpolateAtCentroid_Float4 = TSymbolUniqueId(1487);
+ static constexpr const TSymbolUniqueId interpolateAtSample_Float1_Int1 = TSymbolUniqueId(1488);
+ static constexpr const TSymbolUniqueId interpolateAtSample_Float2_Int1 = TSymbolUniqueId(1489);
+ static constexpr const TSymbolUniqueId interpolateAtSample_Float3_Int1 = TSymbolUniqueId(1490);
+ static constexpr const TSymbolUniqueId interpolateAtSample_Float4_Int1 = TSymbolUniqueId(1491);
+ static constexpr const TSymbolUniqueId interpolateAtOffset_Float1_Float2 =
+ TSymbolUniqueId(1492);
+ static constexpr const TSymbolUniqueId interpolateAtOffset_Float2_Float2 =
+ TSymbolUniqueId(1493);
+ static constexpr const TSymbolUniqueId interpolateAtOffset_Float3_Float2 =
+ TSymbolUniqueId(1494);
+ static constexpr const TSymbolUniqueId interpolateAtOffset_Float4_Float2 =
+ TSymbolUniqueId(1495);
+ static constexpr const TSymbolUniqueId interpolateAtCentroidExt_Float1 = TSymbolUniqueId(1496);
+ static constexpr const TSymbolUniqueId interpolateAtCentroidExt_Float2 = TSymbolUniqueId(1497);
+ static constexpr const TSymbolUniqueId interpolateAtCentroidExt_Float3 = TSymbolUniqueId(1498);
+ static constexpr const TSymbolUniqueId interpolateAtCentroidExt_Float4 = TSymbolUniqueId(1499);
+ static constexpr const TSymbolUniqueId interpolateAtSampleExt_Float1_Int1 =
+ TSymbolUniqueId(1500);
+ static constexpr const TSymbolUniqueId interpolateAtSampleExt_Float2_Int1 =
+ TSymbolUniqueId(1501);
+ static constexpr const TSymbolUniqueId interpolateAtSampleExt_Float3_Int1 =
+ TSymbolUniqueId(1502);
+ static constexpr const TSymbolUniqueId interpolateAtSampleExt_Float4_Int1 =
+ TSymbolUniqueId(1503);
+ static constexpr const TSymbolUniqueId interpolateAtOffsetExt_Float1_Float2 =
+ TSymbolUniqueId(1504);
+ static constexpr const TSymbolUniqueId interpolateAtOffsetExt_Float2_Float2 =
+ TSymbolUniqueId(1505);
+ static constexpr const TSymbolUniqueId interpolateAtOffsetExt_Float3_Float2 =
+ TSymbolUniqueId(1506);
+ static constexpr const TSymbolUniqueId interpolateAtOffsetExt_Float4_Float2 =
+ TSymbolUniqueId(1507);
+ static constexpr const TSymbolUniqueId atomicCounter_AtomicCounter1 = TSymbolUniqueId(1508);
+ static constexpr const TSymbolUniqueId pt00G = TSymbolUniqueId(1509);
+ static constexpr const TSymbolUniqueId atomicCounterIncrement_AtomicCounter1 =
+ TSymbolUniqueId(1510);
+ static constexpr const TSymbolUniqueId atomicCounterDecrement_AtomicCounter1 =
+ TSymbolUniqueId(1511);
+ static constexpr const TSymbolUniqueId atomicCounterAdd_AtomicCounter1_UInt1 =
+ TSymbolUniqueId(1512);
+ static constexpr const TSymbolUniqueId atomicCounterSubtract_AtomicCounter1_UInt1 =
+ TSymbolUniqueId(1513);
+ static constexpr const TSymbolUniqueId atomicCounterMin_AtomicCounter1_UInt1 =
+ TSymbolUniqueId(1514);
+ static constexpr const TSymbolUniqueId atomicCounterMax_AtomicCounter1_UInt1 =
+ TSymbolUniqueId(1515);
+ static constexpr const TSymbolUniqueId atomicCounterAnd_AtomicCounter1_UInt1 =
+ TSymbolUniqueId(1516);
+ static constexpr const TSymbolUniqueId atomicCounterOr_AtomicCounter1_UInt1 =
+ TSymbolUniqueId(1517);
+ static constexpr const TSymbolUniqueId atomicCounterXor_AtomicCounter1_UInt1 =
+ TSymbolUniqueId(1518);
+ static constexpr const TSymbolUniqueId atomicCounterExchange_AtomicCounter1_UInt1 =
+ TSymbolUniqueId(1519);
+ static constexpr const TSymbolUniqueId atomicCounterCompSwap_AtomicCounter1_UInt1_UInt1 =
+ TSymbolUniqueId(1520);
+ static constexpr const TSymbolUniqueId atomicAdd_UInt1_UInt1 = TSymbolUniqueId(1521);
+ static constexpr const TSymbolUniqueId pt_io_00E = TSymbolUniqueId(1522);
+ static constexpr const TSymbolUniqueId atomicAdd_Int1_Int1 = TSymbolUniqueId(1523);
+ static constexpr const TSymbolUniqueId pt_io_00D = TSymbolUniqueId(1524);
+ static constexpr const TSymbolUniqueId atomicMin_UInt1_UInt1 = TSymbolUniqueId(1525);
+ static constexpr const TSymbolUniqueId atomicMin_Int1_Int1 = TSymbolUniqueId(1526);
+ static constexpr const TSymbolUniqueId atomicMax_UInt1_UInt1 = TSymbolUniqueId(1527);
+ static constexpr const TSymbolUniqueId atomicMax_Int1_Int1 = TSymbolUniqueId(1528);
+ static constexpr const TSymbolUniqueId atomicAnd_UInt1_UInt1 = TSymbolUniqueId(1529);
+ static constexpr const TSymbolUniqueId atomicAnd_Int1_Int1 = TSymbolUniqueId(1530);
+ static constexpr const TSymbolUniqueId atomicOr_UInt1_UInt1 = TSymbolUniqueId(1531);
+ static constexpr const TSymbolUniqueId atomicOr_Int1_Int1 = TSymbolUniqueId(1532);
+ static constexpr const TSymbolUniqueId atomicXor_UInt1_UInt1 = TSymbolUniqueId(1533);
+ static constexpr const TSymbolUniqueId atomicXor_Int1_Int1 = TSymbolUniqueId(1534);
+ static constexpr const TSymbolUniqueId atomicExchange_UInt1_UInt1 = TSymbolUniqueId(1535);
+ static constexpr const TSymbolUniqueId atomicExchange_Int1_Int1 = TSymbolUniqueId(1536);
+ static constexpr const TSymbolUniqueId atomicCompSwap_UInt1_UInt1_UInt1 = TSymbolUniqueId(1537);
+ static constexpr const TSymbolUniqueId atomicCompSwap_Int1_Int1_Int1 = TSymbolUniqueId(1538);
+ static constexpr const TSymbolUniqueId imageSize_Image2D1 = TSymbolUniqueId(1539);
+ static constexpr const TSymbolUniqueId pt00z = TSymbolUniqueId(1540);
+ static constexpr const TSymbolUniqueId imageSize_IImage2D1 = TSymbolUniqueId(1541);
+ static constexpr const TSymbolUniqueId pt01K = TSymbolUniqueId(1542);
+ static constexpr const TSymbolUniqueId imageSize_UImage2D1 = TSymbolUniqueId(1543);
+ static constexpr const TSymbolUniqueId pt01V = TSymbolUniqueId(1544);
+ static constexpr const TSymbolUniqueId imageSize_Image3D1 = TSymbolUniqueId(1545);
+ static constexpr const TSymbolUniqueId pt01A = TSymbolUniqueId(1546);
+ static constexpr const TSymbolUniqueId imageSize_IImage3D1 = TSymbolUniqueId(1547);
+ static constexpr const TSymbolUniqueId pt01L = TSymbolUniqueId(1548);
+ static constexpr const TSymbolUniqueId imageSize_UImage3D1 = TSymbolUniqueId(1549);
+ static constexpr const TSymbolUniqueId pt01W = TSymbolUniqueId(1550);
+ static constexpr const TSymbolUniqueId imageSize_Image2DArray1 = TSymbolUniqueId(1551);
+ static constexpr const TSymbolUniqueId pt01B = TSymbolUniqueId(1552);
+ static constexpr const TSymbolUniqueId imageSize_IImage2DArray1 = TSymbolUniqueId(1553);
+ static constexpr const TSymbolUniqueId pt01M = TSymbolUniqueId(1554);
+ static constexpr const TSymbolUniqueId imageSize_UImage2DArray1 = TSymbolUniqueId(1555);
+ static constexpr const TSymbolUniqueId pt01X = TSymbolUniqueId(1556);
+ static constexpr const TSymbolUniqueId imageSize_ImageCube1 = TSymbolUniqueId(1557);
+ static constexpr const TSymbolUniqueId pt01C = TSymbolUniqueId(1558);
+ static constexpr const TSymbolUniqueId imageSize_IImageCube1 = TSymbolUniqueId(1559);
+ static constexpr const TSymbolUniqueId pt01N = TSymbolUniqueId(1560);
+ static constexpr const TSymbolUniqueId imageSize_UImageCube1 = TSymbolUniqueId(1561);
+ static constexpr const TSymbolUniqueId pt01Y = TSymbolUniqueId(1562);
+ static constexpr const TSymbolUniqueId imageSize_ImageCubeArray1 = TSymbolUniqueId(1563);
+ static constexpr const TSymbolUniqueId pt01H = TSymbolUniqueId(1564);
+ static constexpr const TSymbolUniqueId imageSize_IImageCubeArray1 = TSymbolUniqueId(1565);
+ static constexpr const TSymbolUniqueId pt01S = TSymbolUniqueId(1566);
+ static constexpr const TSymbolUniqueId imageSize_UImageCubeArray1 = TSymbolUniqueId(1567);
+ static constexpr const TSymbolUniqueId pt01d = TSymbolUniqueId(1568);
+ static constexpr const TSymbolUniqueId imageSizeExt_ImageCubeArray1 = TSymbolUniqueId(1569);
+ static constexpr const TSymbolUniqueId imageSizeExt_IImageCubeArray1 = TSymbolUniqueId(1570);
+ static constexpr const TSymbolUniqueId imageSizeExt_UImageCubeArray1 = TSymbolUniqueId(1571);
+ static constexpr const TSymbolUniqueId imageSize_ImageBuffer1 = TSymbolUniqueId(1572);
+ static constexpr const TSymbolUniqueId pt01J = TSymbolUniqueId(1573);
+ static constexpr const TSymbolUniqueId imageSize_IImageBuffer1 = TSymbolUniqueId(1574);
+ static constexpr const TSymbolUniqueId pt01U = TSymbolUniqueId(1575);
+ static constexpr const TSymbolUniqueId imageSize_UImageBuffer1 = TSymbolUniqueId(1576);
+ static constexpr const TSymbolUniqueId pt01f = TSymbolUniqueId(1577);
+ static constexpr const TSymbolUniqueId imageSizeExt_ImageBuffer1 = TSymbolUniqueId(1578);
+ static constexpr const TSymbolUniqueId imageSizeExt_IImageBuffer1 = TSymbolUniqueId(1579);
+ static constexpr const TSymbolUniqueId imageSizeExt_UImageBuffer1 = TSymbolUniqueId(1580);
+ static constexpr const TSymbolUniqueId imageSize_Image1D1 = TSymbolUniqueId(1581);
+ static constexpr const TSymbolUniqueId pt01D = TSymbolUniqueId(1582);
+ static constexpr const TSymbolUniqueId imageSize_IImage1D1 = TSymbolUniqueId(1583);
+ static constexpr const TSymbolUniqueId pt01O = TSymbolUniqueId(1584);
+ static constexpr const TSymbolUniqueId imageSize_UImage1D1 = TSymbolUniqueId(1585);
+ static constexpr const TSymbolUniqueId pt01Z = TSymbolUniqueId(1586);
+ static constexpr const TSymbolUniqueId imageSize_ImageRect1 = TSymbolUniqueId(1587);
+ static constexpr const TSymbolUniqueId pt01I = TSymbolUniqueId(1588);
+ static constexpr const TSymbolUniqueId imageSize_IImageRect1 = TSymbolUniqueId(1589);
+ static constexpr const TSymbolUniqueId pt01T = TSymbolUniqueId(1590);
+ static constexpr const TSymbolUniqueId imageSize_UImageRect1 = TSymbolUniqueId(1591);
+ static constexpr const TSymbolUniqueId pt01e = TSymbolUniqueId(1592);
+ static constexpr const TSymbolUniqueId imageSize_Image1DArray1 = TSymbolUniqueId(1593);
+ static constexpr const TSymbolUniqueId pt01E = TSymbolUniqueId(1594);
+ static constexpr const TSymbolUniqueId imageSize_IImage1DArray1 = TSymbolUniqueId(1595);
+ static constexpr const TSymbolUniqueId pt01P = TSymbolUniqueId(1596);
+ static constexpr const TSymbolUniqueId imageSize_UImage1DArray1 = TSymbolUniqueId(1597);
+ static constexpr const TSymbolUniqueId pt01a = TSymbolUniqueId(1598);
+ static constexpr const TSymbolUniqueId imageSize_Image2DMS1 = TSymbolUniqueId(1599);
+ static constexpr const TSymbolUniqueId pt01F = TSymbolUniqueId(1600);
+ static constexpr const TSymbolUniqueId imageSize_IImage2DMS1 = TSymbolUniqueId(1601);
+ static constexpr const TSymbolUniqueId pt01Q = TSymbolUniqueId(1602);
+ static constexpr const TSymbolUniqueId imageSize_UImage2DMS1 = TSymbolUniqueId(1603);
+ static constexpr const TSymbolUniqueId pt01b = TSymbolUniqueId(1604);
+ static constexpr const TSymbolUniqueId imageSize_Image2DMSArray1 = TSymbolUniqueId(1605);
+ static constexpr const TSymbolUniqueId pt01G = TSymbolUniqueId(1606);
+ static constexpr const TSymbolUniqueId imageSize_IImage2DMSArray1 = TSymbolUniqueId(1607);
+ static constexpr const TSymbolUniqueId pt01R = TSymbolUniqueId(1608);
+ static constexpr const TSymbolUniqueId imageSize_UImage2DMSArray1 = TSymbolUniqueId(1609);
+ static constexpr const TSymbolUniqueId pt01c = TSymbolUniqueId(1610);
+ static constexpr const TSymbolUniqueId imageSamples_Image2DMS1 = TSymbolUniqueId(1611);
+ static constexpr const TSymbolUniqueId imageSamples_IImage2DMS1 = TSymbolUniqueId(1612);
+ static constexpr const TSymbolUniqueId imageSamples_UImage2DMS1 = TSymbolUniqueId(1613);
+ static constexpr const TSymbolUniqueId imageSamples_Image2DMSArray1 = TSymbolUniqueId(1614);
+ static constexpr const TSymbolUniqueId imageSamples_IImage2DMSArray1 = TSymbolUniqueId(1615);
+ static constexpr const TSymbolUniqueId imageSamples_UImage2DMSArray1 = TSymbolUniqueId(1616);
+ static constexpr const TSymbolUniqueId imageStore_Image2D1_Int2_Float4 = TSymbolUniqueId(1617);
+ static constexpr const TSymbolUniqueId imageStore_IImage2D1_Int2_Int4 = TSymbolUniqueId(1618);
+ static constexpr const TSymbolUniqueId imageStore_UImage2D1_Int2_UInt4 = TSymbolUniqueId(1619);
+ static constexpr const TSymbolUniqueId imageStore_Image3D1_Int3_Float4 = TSymbolUniqueId(1620);
+ static constexpr const TSymbolUniqueId imageStore_IImage3D1_Int3_Int4 = TSymbolUniqueId(1621);
+ static constexpr const TSymbolUniqueId imageStore_UImage3D1_Int3_UInt4 = TSymbolUniqueId(1622);
+ static constexpr const TSymbolUniqueId imageStore_Image2DArray1_Int3_Float4 =
+ TSymbolUniqueId(1623);
+ static constexpr const TSymbolUniqueId imageStore_IImage2DArray1_Int3_Int4 =
+ TSymbolUniqueId(1624);
+ static constexpr const TSymbolUniqueId imageStore_UImage2DArray1_Int3_UInt4 =
+ TSymbolUniqueId(1625);
+ static constexpr const TSymbolUniqueId imageStore_ImageCube1_Int3_Float4 =
+ TSymbolUniqueId(1626);
+ static constexpr const TSymbolUniqueId imageStore_IImageCube1_Int3_Int4 = TSymbolUniqueId(1627);
+ static constexpr const TSymbolUniqueId imageStore_UImageCube1_Int3_UInt4 =
+ TSymbolUniqueId(1628);
+ static constexpr const TSymbolUniqueId imageStore_ImageCubeArray1_Int3_Float4 =
+ TSymbolUniqueId(1629);
+ static constexpr const TSymbolUniqueId imageStore_IImageCubeArray1_Int3_Int4 =
+ TSymbolUniqueId(1630);
+ static constexpr const TSymbolUniqueId imageStore_UImageCubeArray1_Int3_UInt4 =
+ TSymbolUniqueId(1631);
+ static constexpr const TSymbolUniqueId imageStoreExt_ImageCubeArray1_Int3_Float4 =
+ TSymbolUniqueId(1632);
+ static constexpr const TSymbolUniqueId imageStoreExt_IImageCubeArray1_Int3_Int4 =
+ TSymbolUniqueId(1633);
+ static constexpr const TSymbolUniqueId imageStoreExt_UImageCubeArray1_Int3_UInt4 =
+ TSymbolUniqueId(1634);
+ static constexpr const TSymbolUniqueId imageStore_ImageBuffer1_Int1_Float4 =
+ TSymbolUniqueId(1635);
+ static constexpr const TSymbolUniqueId imageStore_IImageBuffer1_Int1_Int4 =
+ TSymbolUniqueId(1636);
+ static constexpr const TSymbolUniqueId imageStore_UImageBuffer1_Int1_UInt4 =
+ TSymbolUniqueId(1637);
+ static constexpr const TSymbolUniqueId imageStoreExt_ImageBuffer1_Int1_Float4 =
+ TSymbolUniqueId(1638);
+ static constexpr const TSymbolUniqueId imageStoreExt_IImageBuffer1_Int1_Int4 =
+ TSymbolUniqueId(1639);
+ static constexpr const TSymbolUniqueId imageStoreExt_UImageBuffer1_Int1_UInt4 =
+ TSymbolUniqueId(1640);
+ static constexpr const TSymbolUniqueId imageStore_Image1D1_Int1_Float4 = TSymbolUniqueId(1641);
+ static constexpr const TSymbolUniqueId imageStore_IImage1D1_Int1_Int4 = TSymbolUniqueId(1642);
+ static constexpr const TSymbolUniqueId imageStore_UImage1D1_Int1_UInt4 = TSymbolUniqueId(1643);
+ static constexpr const TSymbolUniqueId imageStore_Image1DArray1_Int2_Float4 =
+ TSymbolUniqueId(1644);
+ static constexpr const TSymbolUniqueId imageStore_IImage1DArray1_Int2_Int4 =
+ TSymbolUniqueId(1645);
+ static constexpr const TSymbolUniqueId imageStore_UImage1DArray1_Int2_UInt4 =
+ TSymbolUniqueId(1646);
+ static constexpr const TSymbolUniqueId imageStore_ImageRect1_Int2_Float4 =
+ TSymbolUniqueId(1647);
+ static constexpr const TSymbolUniqueId imageStore_IImageRect1_Int2_Int4 = TSymbolUniqueId(1648);
+ static constexpr const TSymbolUniqueId imageStore_UImageRect1_Int2_UInt4 =
+ TSymbolUniqueId(1649);
+ static constexpr const TSymbolUniqueId imageStore_Image2DMS1_Int2_Int1_Float4 =
+ TSymbolUniqueId(1650);
+ static constexpr const TSymbolUniqueId imageStore_IImage2DMS1_Int2_Int1_Int4 =
+ TSymbolUniqueId(1651);
+ static constexpr const TSymbolUniqueId imageStore_UImage2DMS1_Int2_Int1_UInt4 =
+ TSymbolUniqueId(1652);
+ static constexpr const TSymbolUniqueId imageStore_Image2DMSArray1_Int3_Int1_Float4 =
+ TSymbolUniqueId(1653);
+ static constexpr const TSymbolUniqueId imageStore_IImage2DMSArray1_Int3_Int1_Int4 =
+ TSymbolUniqueId(1654);
+ static constexpr const TSymbolUniqueId imageStore_UImage2DMSArray1_Int3_Int1_UInt4 =
+ TSymbolUniqueId(1655);
+ static constexpr const TSymbolUniqueId imageLoad_Image2D1_Int2 = TSymbolUniqueId(1656);
+ static constexpr const TSymbolUniqueId imageLoad_IImage2D1_Int2 = TSymbolUniqueId(1657);
+ static constexpr const TSymbolUniqueId imageLoad_UImage2D1_Int2 = TSymbolUniqueId(1658);
+ static constexpr const TSymbolUniqueId imageLoad_Image3D1_Int3 = TSymbolUniqueId(1659);
+ static constexpr const TSymbolUniqueId imageLoad_IImage3D1_Int3 = TSymbolUniqueId(1660);
+ static constexpr const TSymbolUniqueId imageLoad_UImage3D1_Int3 = TSymbolUniqueId(1661);
+ static constexpr const TSymbolUniqueId imageLoad_Image2DArray1_Int3 = TSymbolUniqueId(1662);
+ static constexpr const TSymbolUniqueId imageLoad_IImage2DArray1_Int3 = TSymbolUniqueId(1663);
+ static constexpr const TSymbolUniqueId imageLoad_UImage2DArray1_Int3 = TSymbolUniqueId(1664);
+ static constexpr const TSymbolUniqueId imageLoad_ImageCube1_Int3 = TSymbolUniqueId(1665);
+ static constexpr const TSymbolUniqueId imageLoad_IImageCube1_Int3 = TSymbolUniqueId(1666);
+ static constexpr const TSymbolUniqueId imageLoad_UImageCube1_Int3 = TSymbolUniqueId(1667);
+ static constexpr const TSymbolUniqueId imageLoad_ImageCubeArray1_Int3 = TSymbolUniqueId(1668);
+ static constexpr const TSymbolUniqueId imageLoad_IImageCubeArray1_Int3 = TSymbolUniqueId(1669);
+ static constexpr const TSymbolUniqueId imageLoad_UImageCubeArray1_Int3 = TSymbolUniqueId(1670);
+ static constexpr const TSymbolUniqueId imageLoadExt_ImageCubeArray1_Int3 =
+ TSymbolUniqueId(1671);
+ static constexpr const TSymbolUniqueId imageLoadExt_IImageCubeArray1_Int3 =
+ TSymbolUniqueId(1672);
+ static constexpr const TSymbolUniqueId imageLoadExt_UImageCubeArray1_Int3 =
+ TSymbolUniqueId(1673);
+ static constexpr const TSymbolUniqueId imageLoad_ImageBuffer1_Int1 = TSymbolUniqueId(1674);
+ static constexpr const TSymbolUniqueId imageLoad_IImageBuffer1_Int1 = TSymbolUniqueId(1675);
+ static constexpr const TSymbolUniqueId imageLoad_UImageBuffer1_Int1 = TSymbolUniqueId(1676);
+ static constexpr const TSymbolUniqueId imageLoadExt_ImageBuffer1_Int1 = TSymbolUniqueId(1677);
+ static constexpr const TSymbolUniqueId imageLoadExt_IImageBuffer1_Int1 = TSymbolUniqueId(1678);
+ static constexpr const TSymbolUniqueId imageLoadExt_UImageBuffer1_Int1 = TSymbolUniqueId(1679);
+ static constexpr const TSymbolUniqueId imageLoad_Image1D1_Int1 = TSymbolUniqueId(1680);
+ static constexpr const TSymbolUniqueId imageLoad_IImage1D1_Int1 = TSymbolUniqueId(1681);
+ static constexpr const TSymbolUniqueId imageLoad_UImage1D1_Int1 = TSymbolUniqueId(1682);
+ static constexpr const TSymbolUniqueId imageLoad_Image1DArray1_Int2 = TSymbolUniqueId(1683);
+ static constexpr const TSymbolUniqueId imageLoad_IImage1DArray1_Int2 = TSymbolUniqueId(1684);
+ static constexpr const TSymbolUniqueId imageLoad_UImage1DArray1_Int2 = TSymbolUniqueId(1685);
+ static constexpr const TSymbolUniqueId imageLoad_ImageRect1_Int2 = TSymbolUniqueId(1686);
+ static constexpr const TSymbolUniqueId imageLoad_IImageRect1_Int2 = TSymbolUniqueId(1687);
+ static constexpr const TSymbolUniqueId imageLoad_UImageRect1_Int2 = TSymbolUniqueId(1688);
+ static constexpr const TSymbolUniqueId imageLoad_Image2DMS1_Int2_Int1 = TSymbolUniqueId(1689);
+ static constexpr const TSymbolUniqueId imageLoad_IImage2DMS1_Int2_Int1 = TSymbolUniqueId(1690);
+ static constexpr const TSymbolUniqueId imageLoad_UImage2DMS1_Int2_Int1 = TSymbolUniqueId(1691);
+ static constexpr const TSymbolUniqueId imageLoad_Image2DMSArray1_Int3_Int1 =
+ TSymbolUniqueId(1692);
+ static constexpr const TSymbolUniqueId imageLoad_IImage2DMSArray1_Int3_Int1 =
+ TSymbolUniqueId(1693);
+ static constexpr const TSymbolUniqueId imageLoad_UImage2DMSArray1_Int3_Int1 =
+ TSymbolUniqueId(1694);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(1695);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(1696);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(1697);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(1698);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(1699);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(1700);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(1701);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(1702);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(1703);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(1704);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(1705);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(1706);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(1707);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(1708);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(1709);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(1710);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(1711);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(1712);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(1713);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(1714);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(1715);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(1716);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(1717);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(1718);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(1719);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(1720);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(1721);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(1722);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(1723);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(1724);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(1725);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(1726);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(1727);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(1728);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(1729);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(1730);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(1731);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(1732);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(1733);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(1734);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(1735);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(1736);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(1737);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(1738);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(1739);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(1740);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(1741);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(1742);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(1743);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(1744);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(1745);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(1746);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(1747);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(1748);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(1749);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(1750);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(1751);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(1752);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(1753);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(1754);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(1755);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(1756);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(1757);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(1758);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(1759);
+ static constexpr const TSymbolUniqueId imageAtomicAdd_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(1760);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(1761);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(1762);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(1763);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(1764);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(1765);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(1766);
+ static constexpr const TSymbolUniqueId imageAtomicMin_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(1767);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(1768);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(1769);
+ static constexpr const TSymbolUniqueId imageAtomicMin_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(1770);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(1771);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(1772);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(1773);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(1774);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(1775);
+ static constexpr const TSymbolUniqueId imageAtomicMin_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(1776);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(1777);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(1778);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(1779);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(1780);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(1781);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(1782);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(1783);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(1784);
+ static constexpr const TSymbolUniqueId imageAtomicMin_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(1785);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(1786);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(1787);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(1788);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(1789);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(1790);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(1791);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(1792);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(1793);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(1794);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(1795);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(1796);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(1797);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(1798);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(1799);
+ static constexpr const TSymbolUniqueId imageAtomicMin_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(1800);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(1801);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(1802);
+ static constexpr const TSymbolUniqueId imageAtomicMin_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(1803);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(1804);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(1805);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(1806);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(1807);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(1808);
+ static constexpr const TSymbolUniqueId imageAtomicMin_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(1809);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(1810);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(1811);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(1812);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(1813);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(1814);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(1815);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(1816);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(1817);
+ static constexpr const TSymbolUniqueId imageAtomicMin_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(1818);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(1819);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(1820);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(1821);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(1822);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(1823);
+ static constexpr const TSymbolUniqueId imageAtomicMin_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(1824);
+ static constexpr const TSymbolUniqueId imageAtomicMin_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(1825);
+ static constexpr const TSymbolUniqueId imageAtomicMin_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(1826);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(1827);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(1828);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(1829);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(1830);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(1831);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(1832);
+ static constexpr const TSymbolUniqueId imageAtomicMax_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(1833);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(1834);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(1835);
+ static constexpr const TSymbolUniqueId imageAtomicMax_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(1836);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(1837);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(1838);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(1839);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(1840);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(1841);
+ static constexpr const TSymbolUniqueId imageAtomicMax_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(1842);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(1843);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(1844);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(1845);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(1846);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(1847);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(1848);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(1849);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(1850);
+ static constexpr const TSymbolUniqueId imageAtomicMax_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(1851);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(1852);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(1853);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(1854);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(1855);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(1856);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(1857);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(1858);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(1859);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(1860);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(1861);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(1862);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(1863);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(1864);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(1865);
+ static constexpr const TSymbolUniqueId imageAtomicMax_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(1866);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(1867);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(1868);
+ static constexpr const TSymbolUniqueId imageAtomicMax_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(1869);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(1870);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(1871);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(1872);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(1873);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(1874);
+ static constexpr const TSymbolUniqueId imageAtomicMax_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(1875);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(1876);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(1877);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(1878);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(1879);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(1880);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(1881);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(1882);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(1883);
+ static constexpr const TSymbolUniqueId imageAtomicMax_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(1884);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(1885);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(1886);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(1887);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(1888);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(1889);
+ static constexpr const TSymbolUniqueId imageAtomicMax_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(1890);
+ static constexpr const TSymbolUniqueId imageAtomicMax_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(1891);
+ static constexpr const TSymbolUniqueId imageAtomicMax_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(1892);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(1893);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(1894);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(1895);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(1896);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(1897);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(1898);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(1899);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(1900);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(1901);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(1902);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(1903);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(1904);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(1905);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(1906);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(1907);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(1908);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(1909);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(1910);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(1911);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(1912);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(1913);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(1914);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(1915);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(1916);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(1917);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(1918);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(1919);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(1920);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(1921);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(1922);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(1923);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(1924);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(1925);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(1926);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(1927);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(1928);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(1929);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(1930);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(1931);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(1932);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(1933);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(1934);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(1935);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(1936);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(1937);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(1938);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(1939);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(1940);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(1941);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(1942);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(1943);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(1944);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(1945);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(1946);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(1947);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(1948);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(1949);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(1950);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(1951);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(1952);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(1953);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(1954);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(1955);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(1956);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(1957);
+ static constexpr const TSymbolUniqueId imageAtomicAnd_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(1958);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(1959);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(1960);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(1961);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(1962);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(1963);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(1964);
+ static constexpr const TSymbolUniqueId imageAtomicOr_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(1965);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(1966);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(1967);
+ static constexpr const TSymbolUniqueId imageAtomicOr_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(1968);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(1969);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(1970);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(1971);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(1972);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(1973);
+ static constexpr const TSymbolUniqueId imageAtomicOr_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(1974);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(1975);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(1976);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(1977);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(1978);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(1979);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(1980);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(1981);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(1982);
+ static constexpr const TSymbolUniqueId imageAtomicOr_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(1983);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(1984);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(1985);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(1986);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(1987);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(1988);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(1989);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(1990);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(1991);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image2D1_Int2_Int1 = TSymbolUniqueId(1992);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(1993);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(1994);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image3D1_Int3_Int1 = TSymbolUniqueId(1995);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(1996);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(1997);
+ static constexpr const TSymbolUniqueId imageAtomicOr_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(1998);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(1999);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2000);
+ static constexpr const TSymbolUniqueId imageAtomicOr_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2001);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2002);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2003);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2004);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2005);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2006);
+ static constexpr const TSymbolUniqueId imageAtomicOr_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2007);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2008);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2009);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image1D1_Int1_Int1 = TSymbolUniqueId(2010);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(2011);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(2012);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2013);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2014);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2015);
+ static constexpr const TSymbolUniqueId imageAtomicOr_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2016);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2017);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2018);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2019);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2020);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2021);
+ static constexpr const TSymbolUniqueId imageAtomicOr_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2022);
+ static constexpr const TSymbolUniqueId imageAtomicOr_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2023);
+ static constexpr const TSymbolUniqueId imageAtomicOr_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2024);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(2025);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(2026);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(2027);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(2028);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(2029);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(2030);
+ static constexpr const TSymbolUniqueId imageAtomicXor_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2031);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2032);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2033);
+ static constexpr const TSymbolUniqueId imageAtomicXor_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2034);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2035);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2036);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2037);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2038);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2039);
+ static constexpr const TSymbolUniqueId imageAtomicXor_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2040);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2041);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2042);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(2043);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(2044);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(2045);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2046);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2047);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2048);
+ static constexpr const TSymbolUniqueId imageAtomicXor_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2049);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2050);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2051);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2052);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2053);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2054);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2055);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2056);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2057);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(2058);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(2059);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(2060);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(2061);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(2062);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(2063);
+ static constexpr const TSymbolUniqueId imageAtomicXor_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2064);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2065);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2066);
+ static constexpr const TSymbolUniqueId imageAtomicXor_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2067);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2068);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2069);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2070);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2071);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2072);
+ static constexpr const TSymbolUniqueId imageAtomicXor_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2073);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2074);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2075);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(2076);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(2077);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(2078);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2079);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2080);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2081);
+ static constexpr const TSymbolUniqueId imageAtomicXor_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2082);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2083);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2084);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2085);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2086);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2087);
+ static constexpr const TSymbolUniqueId imageAtomicXor_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2088);
+ static constexpr const TSymbolUniqueId imageAtomicXor_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2089);
+ static constexpr const TSymbolUniqueId imageAtomicXor_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2090);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(2091);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(2092);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(2093);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(2094);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(2095);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(2096);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2097);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2098);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2099);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2100);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2101);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2102);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2103);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2104);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2105);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2106);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2107);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2108);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(2109);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(2110);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(2111);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2112);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2113);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2114);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2115);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2116);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2117);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2118);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2119);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2120);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2121);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2122);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2123);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(2124);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(2125);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(2126);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(2127);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(2128);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(2129);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2130);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2131);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2132);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2133);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2134);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2135);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2136);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2137);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2138);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2139);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2140);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2141);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(2142);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(2143);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(2144);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2145);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2146);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2147);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2148);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2149);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2150);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2151);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2152);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2153);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2154);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2155);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2156);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2D1_Int2_Float1 =
+ TSymbolUniqueId(2157);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2D1_Int2_Float1 =
+ TSymbolUniqueId(2158);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2D1_Int2_Float1 =
+ TSymbolUniqueId(2159);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image3D1_Int3_Float1 =
+ TSymbolUniqueId(2160);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage3D1_Int3_Float1 =
+ TSymbolUniqueId(2161);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage3D1_Int3_Float1 =
+ TSymbolUniqueId(2162);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageCube1_Int3_Float1 =
+ TSymbolUniqueId(2163);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageCube1_Int3_Float1 =
+ TSymbolUniqueId(2164);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageCube1_Int3_Float1 =
+ TSymbolUniqueId(2165);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageBuffer1_Int1_Float1 =
+ TSymbolUniqueId(2166);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageBuffer1_Int1_Float1 =
+ TSymbolUniqueId(2167);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageBuffer1_Int1_Float1 =
+ TSymbolUniqueId(2168);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2DArray1_Int3_Float1 =
+ TSymbolUniqueId(2169);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2DArray1_Int3_Float1 =
+ TSymbolUniqueId(2170);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2DArray1_Int3_Float1 =
+ TSymbolUniqueId(2171);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageCubeArray1_Int3_Float1 =
+ TSymbolUniqueId(2172);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageCubeArray1_Int3_Float1 =
+ TSymbolUniqueId(2173);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageCubeArray1_Int3_Float1 =
+ TSymbolUniqueId(2174);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image1D1_Int1_Float1 =
+ TSymbolUniqueId(2175);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage1D1_Int1_Float1 =
+ TSymbolUniqueId(2176);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage1D1_Int1_Float1 =
+ TSymbolUniqueId(2177);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image1DArray1_Int2_Float1 =
+ TSymbolUniqueId(2178);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage1DArray1_Int2_Float1 =
+ TSymbolUniqueId(2179);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage1DArray1_Int2_Float1 =
+ TSymbolUniqueId(2180);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_ImageRect1_Int2_Float1 =
+ TSymbolUniqueId(2181);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImageRect1_Int2_Float1 =
+ TSymbolUniqueId(2182);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImageRect1_Int2_Float1 =
+ TSymbolUniqueId(2183);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2DMS1_Int2_Int1_Float1 =
+ TSymbolUniqueId(2184);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2DMS1_Int2_Int1_Float1 =
+ TSymbolUniqueId(2185);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2DMS1_Int2_Int1_Float1 =
+ TSymbolUniqueId(2186);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_Image2DMSArray1_Int3_Int1_Float1 =
+ TSymbolUniqueId(2187);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_IImage2DMSArray1_Int3_Int1_Float1 =
+ TSymbolUniqueId(2188);
+ static constexpr const TSymbolUniqueId imageAtomicExchange_UImage2DMSArray1_Int3_Int1_Float1 =
+ TSymbolUniqueId(2189);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image2D1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(2190);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage2D1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(2191);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage2D1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(2192);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image3D1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2193);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage3D1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2194);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage3D1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2195);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_ImageCube1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2196);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImageCube1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2197);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImageCube1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2198);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_ImageBuffer1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(2199);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImageBuffer1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(2200);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImageBuffer1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(2201);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image2DArray1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2202);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage2DArray1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2203);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage2DArray1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2204);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_ImageCubeArray1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2205);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImageCubeArray1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2206);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImageCubeArray1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2207);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image1D1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(2208);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage1D1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(2209);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage1D1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(2210);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image1DArray1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(2211);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage1DArray1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(2212);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage1DArray1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(2213);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_ImageRect1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(2214);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImageRect1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(2215);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImageRect1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(2216);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image2DMS1_Int2_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(2217);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage2DMS1_Int2_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(2218);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage2DMS1_Int2_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(2219);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwap_Image2DMSArray1_Int3_Int1_UInt1_UInt1 = TSymbolUniqueId(2220);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwap_IImage2DMSArray1_Int3_Int1_UInt1_UInt1 = TSymbolUniqueId(2221);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwap_UImage2DMSArray1_Int3_Int1_UInt1_UInt1 = TSymbolUniqueId(2222);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image2D1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2223);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage2D1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2224);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage2D1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2225);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image3D1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2226);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage3D1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2227);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage3D1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2228);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_ImageCube1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2229);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImageCube1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2230);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImageCube1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2231);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_ImageBuffer1_Int1_Int1_Int1 =
+ TSymbolUniqueId(2232);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImageBuffer1_Int1_Int1_Int1 =
+ TSymbolUniqueId(2233);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImageBuffer1_Int1_Int1_Int1 =
+ TSymbolUniqueId(2234);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image2DArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2235);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage2DArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2236);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage2DArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2237);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_ImageCubeArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2238);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImageCubeArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2239);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImageCubeArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2240);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image1D1_Int1_Int1_Int1 =
+ TSymbolUniqueId(2241);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage1D1_Int1_Int1_Int1 =
+ TSymbolUniqueId(2242);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage1D1_Int1_Int1_Int1 =
+ TSymbolUniqueId(2243);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image1DArray1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2244);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage1DArray1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2245);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage1DArray1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2246);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_ImageRect1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2247);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImageRect1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2248);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImageRect1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2249);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image2DMS1_Int2_Int1_Int1_Int1 =
+ TSymbolUniqueId(2250);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_IImage2DMS1_Int2_Int1_Int1_Int1 =
+ TSymbolUniqueId(2251);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_UImage2DMS1_Int2_Int1_Int1_Int1 =
+ TSymbolUniqueId(2252);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwap_Image2DMSArray1_Int3_Int1_Int1_Int1 =
+ TSymbolUniqueId(2253);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwap_IImage2DMSArray1_Int3_Int1_Int1_Int1 = TSymbolUniqueId(2254);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwap_UImage2DMSArray1_Int3_Int1_Int1_Int1 = TSymbolUniqueId(2255);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(2256);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(2257);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(2258);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(2259);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(2260);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(2261);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2262);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2263);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2264);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2265);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2266);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2267);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2268);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2269);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2270);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2271);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2272);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2273);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(2274);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(2275);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(2276);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2277);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2278);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2279);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2280);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2281);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2282);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2283);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2284);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2285);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2286);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2287);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2288);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(2289);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(2290);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(2291);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(2292);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(2293);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(2294);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2295);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2296);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2297);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2298);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2299);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2300);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2301);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2302);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2303);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2304);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2305);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2306);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(2307);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(2308);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(2309);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2310);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2311);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2312);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2313);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2314);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2315);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2316);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2317);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2318);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2319);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2320);
+ static constexpr const TSymbolUniqueId imageAtomicAddExt_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2321);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(2322);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(2323);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(2324);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(2325);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(2326);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(2327);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2328);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2329);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2330);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2331);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2332);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2333);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2334);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2335);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2336);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2337);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2338);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2339);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(2340);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(2341);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(2342);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2343);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2344);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2345);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2346);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2347);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2348);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2349);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2350);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2351);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2352);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2353);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2354);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(2355);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(2356);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(2357);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(2358);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(2359);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(2360);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2361);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2362);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2363);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2364);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2365);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2366);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2367);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2368);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2369);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2370);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2371);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2372);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(2373);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(2374);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(2375);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2376);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2377);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2378);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2379);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2380);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2381);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2382);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2383);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2384);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2385);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2386);
+ static constexpr const TSymbolUniqueId imageAtomicMinExt_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2387);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(2388);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(2389);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(2390);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(2391);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(2392);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(2393);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2394);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2395);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2396);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2397);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2398);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2399);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2400);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2401);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2402);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2403);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2404);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2405);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(2406);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(2407);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(2408);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2409);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2410);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2411);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2412);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2413);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2414);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2415);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2416);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2417);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2418);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2419);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2420);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(2421);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(2422);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(2423);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(2424);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(2425);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(2426);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2427);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2428);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2429);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2430);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2431);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2432);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2433);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2434);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2435);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2436);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2437);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2438);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(2439);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(2440);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(2441);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2442);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2443);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2444);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2445);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2446);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2447);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2448);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2449);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2450);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2451);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2452);
+ static constexpr const TSymbolUniqueId imageAtomicMaxExt_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2453);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(2454);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(2455);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(2456);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(2457);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(2458);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(2459);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2460);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2461);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2462);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2463);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2464);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2465);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2466);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2467);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2468);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2469);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2470);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2471);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(2472);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(2473);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(2474);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2475);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2476);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2477);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2478);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2479);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2480);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2481);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2482);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2483);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2484);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2485);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2486);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(2487);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(2488);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(2489);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(2490);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(2491);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(2492);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2493);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2494);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2495);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2496);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2497);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2498);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2499);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2500);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2501);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2502);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2503);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2504);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(2505);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(2506);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(2507);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2508);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2509);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2510);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2511);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2512);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2513);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2514);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2515);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2516);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2517);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2518);
+ static constexpr const TSymbolUniqueId imageAtomicAndExt_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2519);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(2520);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(2521);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(2522);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(2523);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(2524);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(2525);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2526);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2527);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2528);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2529);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2530);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2531);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2532);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2533);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2534);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2535);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2536);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2537);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(2538);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(2539);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(2540);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2541);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2542);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2543);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2544);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2545);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2546);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2547);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2548);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2549);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2550);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2551);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2552);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(2553);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(2554);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(2555);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(2556);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(2557);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(2558);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2559);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2560);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2561);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2562);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2563);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2564);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2565);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2566);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2567);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2568);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2569);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2570);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(2571);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(2572);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(2573);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2574);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2575);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2576);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2577);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2578);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2579);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2580);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2581);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2582);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2583);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2584);
+ static constexpr const TSymbolUniqueId imageAtomicOrExt_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2585);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(2586);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(2587);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(2588);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(2589);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(2590);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(2591);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2592);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2593);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2594);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2595);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2596);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2597);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2598);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2599);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2600);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2601);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2602);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2603);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(2604);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(2605);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(2606);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2607);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2608);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2609);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2610);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2611);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2612);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2613);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2614);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2615);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2616);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2617);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2618);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(2619);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(2620);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(2621);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(2622);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(2623);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(2624);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2625);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2626);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2627);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2628);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2629);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2630);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2631);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2632);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2633);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2634);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2635);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2636);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(2637);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(2638);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(2639);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2640);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2641);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2642);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2643);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2644);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2645);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2646);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2647);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2648);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2649);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2650);
+ static constexpr const TSymbolUniqueId imageAtomicXorExt_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2651);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2D1_Int2_UInt1 =
+ TSymbolUniqueId(2652);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(2653);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2D1_Int2_UInt1 =
+ TSymbolUniqueId(2654);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image3D1_Int3_UInt1 =
+ TSymbolUniqueId(2655);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(2656);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage3D1_Int3_UInt1 =
+ TSymbolUniqueId(2657);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2658);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2659);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageCube1_Int3_UInt1 =
+ TSymbolUniqueId(2660);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2661);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2662);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageBuffer1_Int1_UInt1 =
+ TSymbolUniqueId(2663);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2664);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2665);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2DArray1_Int3_UInt1 =
+ TSymbolUniqueId(2666);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2667);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2668);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageCubeArray1_Int3_UInt1 =
+ TSymbolUniqueId(2669);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image1D1_Int1_UInt1 =
+ TSymbolUniqueId(2670);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(2671);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage1D1_Int1_UInt1 =
+ TSymbolUniqueId(2672);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2673);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2674);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage1DArray1_Int2_UInt1 =
+ TSymbolUniqueId(2675);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2676);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2677);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageRect1_Int2_UInt1 =
+ TSymbolUniqueId(2678);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2679);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2680);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2DMS1_Int2_Int1_UInt1 =
+ TSymbolUniqueId(2681);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2682);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2683);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2DMSArray1_Int3_Int1_UInt1 =
+ TSymbolUniqueId(2684);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2D1_Int2_Int1 =
+ TSymbolUniqueId(2685);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2D1_Int2_Int1 =
+ TSymbolUniqueId(2686);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2D1_Int2_Int1 =
+ TSymbolUniqueId(2687);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image3D1_Int3_Int1 =
+ TSymbolUniqueId(2688);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage3D1_Int3_Int1 =
+ TSymbolUniqueId(2689);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage3D1_Int3_Int1 =
+ TSymbolUniqueId(2690);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2691);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2692);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageCube1_Int3_Int1 =
+ TSymbolUniqueId(2693);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2694);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2695);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageBuffer1_Int1_Int1 =
+ TSymbolUniqueId(2696);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2697);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2698);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2DArray1_Int3_Int1 =
+ TSymbolUniqueId(2699);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2700);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2701);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageCubeArray1_Int3_Int1 =
+ TSymbolUniqueId(2702);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image1D1_Int1_Int1 =
+ TSymbolUniqueId(2703);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage1D1_Int1_Int1 =
+ TSymbolUniqueId(2704);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage1D1_Int1_Int1 =
+ TSymbolUniqueId(2705);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2706);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2707);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage1DArray1_Int2_Int1 =
+ TSymbolUniqueId(2708);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2709);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2710);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageRect1_Int2_Int1 =
+ TSymbolUniqueId(2711);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2712);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2713);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2DMS1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2714);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2715);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2716);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2DMSArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2717);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2D1_Int2_Float1 =
+ TSymbolUniqueId(2718);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2D1_Int2_Float1 =
+ TSymbolUniqueId(2719);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2D1_Int2_Float1 =
+ TSymbolUniqueId(2720);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image3D1_Int3_Float1 =
+ TSymbolUniqueId(2721);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage3D1_Int3_Float1 =
+ TSymbolUniqueId(2722);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage3D1_Int3_Float1 =
+ TSymbolUniqueId(2723);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageCube1_Int3_Float1 =
+ TSymbolUniqueId(2724);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageCube1_Int3_Float1 =
+ TSymbolUniqueId(2725);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageCube1_Int3_Float1 =
+ TSymbolUniqueId(2726);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageBuffer1_Int1_Float1 =
+ TSymbolUniqueId(2727);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageBuffer1_Int1_Float1 =
+ TSymbolUniqueId(2728);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageBuffer1_Int1_Float1 =
+ TSymbolUniqueId(2729);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2DArray1_Int3_Float1 =
+ TSymbolUniqueId(2730);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2DArray1_Int3_Float1 =
+ TSymbolUniqueId(2731);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2DArray1_Int3_Float1 =
+ TSymbolUniqueId(2732);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageCubeArray1_Int3_Float1 =
+ TSymbolUniqueId(2733);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageCubeArray1_Int3_Float1 =
+ TSymbolUniqueId(2734);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageCubeArray1_Int3_Float1 =
+ TSymbolUniqueId(2735);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image1D1_Int1_Float1 =
+ TSymbolUniqueId(2736);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage1D1_Int1_Float1 =
+ TSymbolUniqueId(2737);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage1D1_Int1_Float1 =
+ TSymbolUniqueId(2738);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image1DArray1_Int2_Float1 =
+ TSymbolUniqueId(2739);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage1DArray1_Int2_Float1 =
+ TSymbolUniqueId(2740);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage1DArray1_Int2_Float1 =
+ TSymbolUniqueId(2741);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_ImageRect1_Int2_Float1 =
+ TSymbolUniqueId(2742);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImageRect1_Int2_Float1 =
+ TSymbolUniqueId(2743);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImageRect1_Int2_Float1 =
+ TSymbolUniqueId(2744);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2DMS1_Int2_Int1_Float1 =
+ TSymbolUniqueId(2745);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_IImage2DMS1_Int2_Int1_Float1 =
+ TSymbolUniqueId(2746);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_UImage2DMS1_Int2_Int1_Float1 =
+ TSymbolUniqueId(2747);
+ static constexpr const TSymbolUniqueId imageAtomicExchangeExt_Image2DMSArray1_Int3_Int1_Float1 =
+ TSymbolUniqueId(2748);
+ static constexpr const TSymbolUniqueId
+ imageAtomicExchangeExt_IImage2DMSArray1_Int3_Int1_Float1 = TSymbolUniqueId(2749);
+ static constexpr const TSymbolUniqueId
+ imageAtomicExchangeExt_UImage2DMSArray1_Int3_Int1_Float1 = TSymbolUniqueId(2750);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image2D1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(2751);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage2D1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(2752);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage2D1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(2753);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image3D1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2754);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage3D1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2755);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage3D1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2756);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_ImageCube1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2757);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImageCube1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2758);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImageCube1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2759);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_ImageBuffer1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(2760);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImageBuffer1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(2761);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImageBuffer1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(2762);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image2DArray1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2763);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage2DArray1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2764);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage2DArray1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2765);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_ImageCubeArray1_Int3_UInt1_UInt1 =
+ TSymbolUniqueId(2766);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwapExt_IImageCubeArray1_Int3_UInt1_UInt1 = TSymbolUniqueId(2767);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwapExt_UImageCubeArray1_Int3_UInt1_UInt1 = TSymbolUniqueId(2768);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image1D1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(2769);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage1D1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(2770);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage1D1_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(2771);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image1DArray1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(2772);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage1DArray1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(2773);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage1DArray1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(2774);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_ImageRect1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(2775);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImageRect1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(2776);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImageRect1_Int2_UInt1_UInt1 =
+ TSymbolUniqueId(2777);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image2DMS1_Int2_Int1_UInt1_UInt1 =
+ TSymbolUniqueId(2778);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwapExt_IImage2DMS1_Int2_Int1_UInt1_UInt1 = TSymbolUniqueId(2779);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwapExt_UImage2DMS1_Int2_Int1_UInt1_UInt1 = TSymbolUniqueId(2780);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwapExt_Image2DMSArray1_Int3_Int1_UInt1_UInt1 = TSymbolUniqueId(2781);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwapExt_IImage2DMSArray1_Int3_Int1_UInt1_UInt1 = TSymbolUniqueId(2782);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwapExt_UImage2DMSArray1_Int3_Int1_UInt1_UInt1 = TSymbolUniqueId(2783);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image2D1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2784);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage2D1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2785);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage2D1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2786);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image3D1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2787);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage3D1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2788);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage3D1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2789);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_ImageCube1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2790);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImageCube1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2791);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImageCube1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2792);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_ImageBuffer1_Int1_Int1_Int1 =
+ TSymbolUniqueId(2793);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImageBuffer1_Int1_Int1_Int1 =
+ TSymbolUniqueId(2794);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImageBuffer1_Int1_Int1_Int1 =
+ TSymbolUniqueId(2795);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image2DArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2796);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage2DArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2797);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage2DArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2798);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_ImageCubeArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2799);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImageCubeArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2800);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImageCubeArray1_Int3_Int1_Int1 =
+ TSymbolUniqueId(2801);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image1D1_Int1_Int1_Int1 =
+ TSymbolUniqueId(2802);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage1D1_Int1_Int1_Int1 =
+ TSymbolUniqueId(2803);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage1D1_Int1_Int1_Int1 =
+ TSymbolUniqueId(2804);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image1DArray1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2805);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage1DArray1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2806);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage1DArray1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2807);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_ImageRect1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2808);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImageRect1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2809);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImageRect1_Int2_Int1_Int1 =
+ TSymbolUniqueId(2810);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_Image2DMS1_Int2_Int1_Int1_Int1 =
+ TSymbolUniqueId(2811);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_IImage2DMS1_Int2_Int1_Int1_Int1 =
+ TSymbolUniqueId(2812);
+ static constexpr const TSymbolUniqueId imageAtomicCompSwapExt_UImage2DMS1_Int2_Int1_Int1_Int1 =
+ TSymbolUniqueId(2813);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwapExt_Image2DMSArray1_Int3_Int1_Int1_Int1 = TSymbolUniqueId(2814);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwapExt_IImage2DMSArray1_Int3_Int1_Int1_Int1 = TSymbolUniqueId(2815);
+ static constexpr const TSymbolUniqueId
+ imageAtomicCompSwapExt_UImage2DMSArray1_Int3_Int1_Int1_Int1 = TSymbolUniqueId(2816);
+ static constexpr const TSymbolUniqueId pixelLocalLoadANGLE_PixelLocalANGLE1 =
+ TSymbolUniqueId(2817);
+ static constexpr const TSymbolUniqueId pt01g = TSymbolUniqueId(2818);
+ static constexpr const TSymbolUniqueId pixelLocalLoadANGLE_IPixelLocalANGLE1 =
+ TSymbolUniqueId(2819);
+ static constexpr const TSymbolUniqueId pt01h = TSymbolUniqueId(2820);
+ static constexpr const TSymbolUniqueId pixelLocalLoadANGLE_UPixelLocalANGLE1 =
+ TSymbolUniqueId(2821);
+ static constexpr const TSymbolUniqueId pt01i = TSymbolUniqueId(2822);
+ static constexpr const TSymbolUniqueId pixelLocalStoreANGLE_PixelLocalANGLE1_Float4 =
+ TSymbolUniqueId(2823);
+ static constexpr const TSymbolUniqueId pixelLocalStoreANGLE_IPixelLocalANGLE1_Int4 =
+ TSymbolUniqueId(2824);
+ static constexpr const TSymbolUniqueId pixelLocalStoreANGLE_UPixelLocalANGLE1_UInt4 =
+ TSymbolUniqueId(2825);
+ static constexpr const TSymbolUniqueId beginInvocationInterlockNV = TSymbolUniqueId(2826);
+ static constexpr const TSymbolUniqueId endInvocationInterlockNV = TSymbolUniqueId(2827);
+ static constexpr const TSymbolUniqueId beginFragmentShaderOrderingINTEL = TSymbolUniqueId(2828);
+ static constexpr const TSymbolUniqueId beginInvocationInterlockARB = TSymbolUniqueId(2829);
+ static constexpr const TSymbolUniqueId endInvocationInterlockARB = TSymbolUniqueId(2830);
+ static constexpr const TSymbolUniqueId noise1_Float1 = TSymbolUniqueId(2831);
+ static constexpr const TSymbolUniqueId noise1_Float2 = TSymbolUniqueId(2832);
+ static constexpr const TSymbolUniqueId noise1_Float3 = TSymbolUniqueId(2833);
+ static constexpr const TSymbolUniqueId noise1_Float4 = TSymbolUniqueId(2834);
+ static constexpr const TSymbolUniqueId noise2_Float1 = TSymbolUniqueId(2835);
+ static constexpr const TSymbolUniqueId noise2_Float2 = TSymbolUniqueId(2836);
+ static constexpr const TSymbolUniqueId noise2_Float3 = TSymbolUniqueId(2837);
+ static constexpr const TSymbolUniqueId noise2_Float4 = TSymbolUniqueId(2838);
+ static constexpr const TSymbolUniqueId noise3_Float1 = TSymbolUniqueId(2839);
+ static constexpr const TSymbolUniqueId noise3_Float2 = TSymbolUniqueId(2840);
+ static constexpr const TSymbolUniqueId noise3_Float3 = TSymbolUniqueId(2841);
+ static constexpr const TSymbolUniqueId noise3_Float4 = TSymbolUniqueId(2842);
+ static constexpr const TSymbolUniqueId noise4_Float1 = TSymbolUniqueId(2843);
+ static constexpr const TSymbolUniqueId noise4_Float2 = TSymbolUniqueId(2844);
+ static constexpr const TSymbolUniqueId noise4_Float3 = TSymbolUniqueId(2845);
+ static constexpr const TSymbolUniqueId noise4_Float4 = TSymbolUniqueId(2846);
+ static constexpr const TSymbolUniqueId memoryBarrier = TSymbolUniqueId(2847);
+ static constexpr const TSymbolUniqueId memoryBarrierAtomicCounter = TSymbolUniqueId(2848);
+ static constexpr const TSymbolUniqueId memoryBarrierBuffer = TSymbolUniqueId(2849);
+ static constexpr const TSymbolUniqueId memoryBarrierImage = TSymbolUniqueId(2850);
+ static constexpr const TSymbolUniqueId barrier = TSymbolUniqueId(2851);
+ static constexpr const TSymbolUniqueId memoryBarrierShared = TSymbolUniqueId(2852);
+ static constexpr const TSymbolUniqueId groupMemoryBarrier = TSymbolUniqueId(2853);
+ static constexpr const TSymbolUniqueId barrierTCS = TSymbolUniqueId(2854);
+ static constexpr const TSymbolUniqueId barrierTCSES3_2 = TSymbolUniqueId(2855);
+ static constexpr const TSymbolUniqueId EmitVertex = TSymbolUniqueId(2856);
+ static constexpr const TSymbolUniqueId EmitVertexES3_2 = TSymbolUniqueId(2857);
+ static constexpr const TSymbolUniqueId EndPrimitive = TSymbolUniqueId(2858);
+ static constexpr const TSymbolUniqueId EndPrimitiveES3_2 = TSymbolUniqueId(2859);
+ static constexpr const TSymbolUniqueId EmitStreamVertex_Int1 = TSymbolUniqueId(2860);
+ static constexpr const TSymbolUniqueId EndStreamPrimitive_Int1 = TSymbolUniqueId(2861);
+ static constexpr const TSymbolUniqueId subpassLoad_SubpassInput1 = TSymbolUniqueId(2862);
+ static constexpr const TSymbolUniqueId pt01j = TSymbolUniqueId(2863);
+ static constexpr const TSymbolUniqueId subpassLoad_ISubpassInput1 = TSymbolUniqueId(2864);
+ static constexpr const TSymbolUniqueId pt01k = TSymbolUniqueId(2865);
+ static constexpr const TSymbolUniqueId subpassLoad_USubpassInput1 = TSymbolUniqueId(2866);
+ static constexpr const TSymbolUniqueId pt01l = TSymbolUniqueId(2867);
+ static constexpr const TSymbolUniqueId subpassLoad_SubpassInputMS1_Int1 = TSymbolUniqueId(2868);
+ static constexpr const TSymbolUniqueId pt01m = TSymbolUniqueId(2869);
+ static constexpr const TSymbolUniqueId subpassLoad_ISubpassInputMS1_Int1 =
+ TSymbolUniqueId(2870);
+ static constexpr const TSymbolUniqueId pt01n = TSymbolUniqueId(2871);
+ static constexpr const TSymbolUniqueId subpassLoad_USubpassInputMS1_Int1 =
+ TSymbolUniqueId(2872);
+ static constexpr const TSymbolUniqueId pt01o = TSymbolUniqueId(2873);
+ static constexpr const TSymbolUniqueId anyInvocation_Bool1 = TSymbolUniqueId(2874);
+ static constexpr const TSymbolUniqueId allInvocations_Bool1 = TSymbolUniqueId(2875);
+ static constexpr const TSymbolUniqueId allInvocationsEqual_Bool1 = TSymbolUniqueId(2876);
+ static constexpr const TSymbolUniqueId gl_DepthRangeParameters = TSymbolUniqueId(2877);
+ static constexpr const TSymbolUniqueId gl_DepthRange = TSymbolUniqueId(2878);
+ static constexpr const TSymbolUniqueId gl_NumSamples = TSymbolUniqueId(2879);
+ static constexpr const TSymbolUniqueId gl_NumSamplesES3_2 = TSymbolUniqueId(2880);
+ static constexpr const TSymbolUniqueId gl_MaxVertexAttribs = TSymbolUniqueId(2881);
+ static constexpr const TSymbolUniqueId gl_MaxVertexUniformVectors = TSymbolUniqueId(2882);
+ static constexpr const TSymbolUniqueId gl_MaxVertexTextureImageUnits = TSymbolUniqueId(2883);
+ static constexpr const TSymbolUniqueId gl_MaxCombinedTextureImageUnits = TSymbolUniqueId(2884);
+ static constexpr const TSymbolUniqueId gl_MaxTextureImageUnits = TSymbolUniqueId(2885);
+ static constexpr const TSymbolUniqueId gl_MaxFragmentUniformVectors = TSymbolUniqueId(2886);
+ static constexpr const TSymbolUniqueId gl_MaxVaryingVectors = TSymbolUniqueId(2887);
+ static constexpr const TSymbolUniqueId gl_MaxDrawBuffers = TSymbolUniqueId(2888);
+ static constexpr const TSymbolUniqueId gl_MaxDualSourceDrawBuffersEXT = TSymbolUniqueId(2889);
+ static constexpr const TSymbolUniqueId gl_MaxVertexOutputVectors = TSymbolUniqueId(2890);
+ static constexpr const TSymbolUniqueId gl_MaxFragmentInputVectors = TSymbolUniqueId(2891);
+ static constexpr const TSymbolUniqueId gl_MinProgramTexelOffset = TSymbolUniqueId(2892);
+ static constexpr const TSymbolUniqueId gl_MaxProgramTexelOffset = TSymbolUniqueId(2893);
+ static constexpr const TSymbolUniqueId gl_MaxImageUnits = TSymbolUniqueId(2894);
+ static constexpr const TSymbolUniqueId gl_MaxVertexImageUniforms = TSymbolUniqueId(2895);
+ static constexpr const TSymbolUniqueId gl_MaxFragmentImageUniforms = TSymbolUniqueId(2896);
+ static constexpr const TSymbolUniqueId gl_MaxComputeImageUniforms = TSymbolUniqueId(2897);
+ static constexpr const TSymbolUniqueId gl_MaxCombinedImageUniforms = TSymbolUniqueId(2898);
+ static constexpr const TSymbolUniqueId gl_MaxCombinedShaderOutputResources =
+ TSymbolUniqueId(2899);
+ static constexpr const TSymbolUniqueId gl_MaxComputeWorkGroupCount = TSymbolUniqueId(2900);
+ static constexpr const TSymbolUniqueId gl_MaxComputeWorkGroupSize = TSymbolUniqueId(2901);
+ static constexpr const TSymbolUniqueId gl_MaxComputeUniformComponents = TSymbolUniqueId(2902);
+ static constexpr const TSymbolUniqueId gl_MaxComputeTextureImageUnits = TSymbolUniqueId(2903);
+ static constexpr const TSymbolUniqueId gl_MaxComputeAtomicCounters = TSymbolUniqueId(2904);
+ static constexpr const TSymbolUniqueId gl_MaxComputeAtomicCounterBuffers =
+ TSymbolUniqueId(2905);
+ static constexpr const TSymbolUniqueId gl_MaxVertexAtomicCounters = TSymbolUniqueId(2906);
+ static constexpr const TSymbolUniqueId gl_MaxFragmentAtomicCounters = TSymbolUniqueId(2907);
+ static constexpr const TSymbolUniqueId gl_MaxCombinedAtomicCounters = TSymbolUniqueId(2908);
+ static constexpr const TSymbolUniqueId gl_MaxAtomicCounterBindings = TSymbolUniqueId(2909);
+ static constexpr const TSymbolUniqueId gl_MaxVertexAtomicCounterBuffers = TSymbolUniqueId(2910);
+ static constexpr const TSymbolUniqueId gl_MaxFragmentAtomicCounterBuffers =
+ TSymbolUniqueId(2911);
+ static constexpr const TSymbolUniqueId gl_MaxCombinedAtomicCounterBuffers =
+ TSymbolUniqueId(2912);
+ static constexpr const TSymbolUniqueId gl_MaxAtomicCounterBufferSize = TSymbolUniqueId(2913);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryInputComponents = TSymbolUniqueId(2914);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryInputComponentsES3_2 =
+ TSymbolUniqueId(2915);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryOutputComponents = TSymbolUniqueId(2916);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryOutputComponentsES3_2 =
+ TSymbolUniqueId(2917);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryImageUniforms = TSymbolUniqueId(2918);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryImageUniformsES3_2 = TSymbolUniqueId(2919);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryTextureImageUnits = TSymbolUniqueId(2920);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryTextureImageUnitsES3_2 =
+ TSymbolUniqueId(2921);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryOutputVertices = TSymbolUniqueId(2922);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryOutputVerticesES3_2 =
+ TSymbolUniqueId(2923);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryTotalOutputComponents =
+ TSymbolUniqueId(2924);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryTotalOutputComponentsES3_2 =
+ TSymbolUniqueId(2925);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryUniformComponents = TSymbolUniqueId(2926);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryUniformComponentsES3_2 =
+ TSymbolUniqueId(2927);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryAtomicCounters = TSymbolUniqueId(2928);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryAtomicCountersES3_2 =
+ TSymbolUniqueId(2929);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryAtomicCounterBuffers =
+ TSymbolUniqueId(2930);
+ static constexpr const TSymbolUniqueId gl_MaxGeometryAtomicCounterBuffersES3_2 =
+ TSymbolUniqueId(2931);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlInputComponents = TSymbolUniqueId(2932);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlInputComponentsES3_2 =
+ TSymbolUniqueId(2933);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlOutputComponents =
+ TSymbolUniqueId(2934);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlOutputComponentsES3_2 =
+ TSymbolUniqueId(2935);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlTextureImageUnits =
+ TSymbolUniqueId(2936);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlTextureImageUnitsES3_2 =
+ TSymbolUniqueId(2937);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlUniformComponents =
+ TSymbolUniqueId(2938);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlUniformComponentsES3_2 =
+ TSymbolUniqueId(2939);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlTotalOutputComponents =
+ TSymbolUniqueId(2940);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlTotalOutputComponentsES3_2 =
+ TSymbolUniqueId(2941);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlImageUniforms = TSymbolUniqueId(2942);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlImageUniformsES3_2 =
+ TSymbolUniqueId(2943);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlAtomicCounters = TSymbolUniqueId(2944);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlAtomicCountersES3_2 =
+ TSymbolUniqueId(2945);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlAtomicCounterBuffers =
+ TSymbolUniqueId(2946);
+ static constexpr const TSymbolUniqueId gl_MaxTessControlAtomicCounterBuffersES3_2 =
+ TSymbolUniqueId(2947);
+ static constexpr const TSymbolUniqueId gl_MaxTessPatchComponents = TSymbolUniqueId(2948);
+ static constexpr const TSymbolUniqueId gl_MaxTessPatchComponentsES3_2 = TSymbolUniqueId(2949);
+ static constexpr const TSymbolUniqueId gl_MaxPatchVertices = TSymbolUniqueId(2950);
+ static constexpr const TSymbolUniqueId gl_MaxPatchVerticesES3_2 = TSymbolUniqueId(2951);
+ static constexpr const TSymbolUniqueId gl_MaxTessGenLevel = TSymbolUniqueId(2952);
+ static constexpr const TSymbolUniqueId gl_MaxTessGenLevelES3_2 = TSymbolUniqueId(2953);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationInputComponents =
+ TSymbolUniqueId(2954);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationInputComponentsES3_2 =
+ TSymbolUniqueId(2955);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationOutputComponents =
+ TSymbolUniqueId(2956);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationOutputComponentsES3_2 =
+ TSymbolUniqueId(2957);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationTextureImageUnits =
+ TSymbolUniqueId(2958);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationTextureImageUnitsES3_2 =
+ TSymbolUniqueId(2959);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationUniformComponents =
+ TSymbolUniqueId(2960);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationUniformComponentsES3_2 =
+ TSymbolUniqueId(2961);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationImageUniforms =
+ TSymbolUniqueId(2962);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationImageUniformsES3_2 =
+ TSymbolUniqueId(2963);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationAtomicCounters =
+ TSymbolUniqueId(2964);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationAtomicCountersES3_2 =
+ TSymbolUniqueId(2965);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationAtomicCounterBuffers =
+ TSymbolUniqueId(2966);
+ static constexpr const TSymbolUniqueId gl_MaxTessEvaluationAtomicCounterBuffersES3_2 =
+ TSymbolUniqueId(2967);
+ static constexpr const TSymbolUniqueId gl_MaxSamples = TSymbolUniqueId(2968);
+ static constexpr const TSymbolUniqueId gl_MaxSamplesES3_2 = TSymbolUniqueId(2969);
+ static constexpr const TSymbolUniqueId gl_MaxClipDistancesAPPLE = TSymbolUniqueId(2970);
+ static constexpr const TSymbolUniqueId gl_MaxCullDistancesEXT = TSymbolUniqueId(2971);
+ static constexpr const TSymbolUniqueId gl_MaxCombinedClipAndCullDistancesEXT =
+ TSymbolUniqueId(2972);
+ static constexpr const TSymbolUniqueId gl_FragCoord = TSymbolUniqueId(2973);
+ static constexpr const TSymbolUniqueId gl_FrontFacing = TSymbolUniqueId(2974);
+ static constexpr const TSymbolUniqueId gl_PointCoord = TSymbolUniqueId(2975);
+ static constexpr const TSymbolUniqueId gl_FragColor = TSymbolUniqueId(2976);
+ static constexpr const TSymbolUniqueId gl_FragData = TSymbolUniqueId(2977);
+ static constexpr const TSymbolUniqueId gl_FragDepth = TSymbolUniqueId(2978);
+ static constexpr const TSymbolUniqueId gl_HelperInvocation = TSymbolUniqueId(2979);
+ static constexpr const TSymbolUniqueId gl_FragCoord300 = TSymbolUniqueId(2980);
+ static constexpr const TSymbolUniqueId gl_SecondaryFragColorEXT = TSymbolUniqueId(2981);
+ static constexpr const TSymbolUniqueId gl_SecondaryFragDataEXT = TSymbolUniqueId(2982);
+ static constexpr const TSymbolUniqueId gl_FragDepthEXT = TSymbolUniqueId(2983);
+ static constexpr const TSymbolUniqueId gl_LastFragData = TSymbolUniqueId(2984);
+ static constexpr const TSymbolUniqueId gl_LastFragColor = TSymbolUniqueId(2985);
+ static constexpr const TSymbolUniqueId gl_LastFragDataNV = TSymbolUniqueId(2986);
+ static constexpr const TSymbolUniqueId gl_LastFragColorARM = TSymbolUniqueId(2987);
+ static constexpr const TSymbolUniqueId gl_PrimitiveID = TSymbolUniqueId(2988);
+ static constexpr const TSymbolUniqueId gl_PrimitiveIDES3_2 = TSymbolUniqueId(2989);
+ static constexpr const TSymbolUniqueId gl_Layer = TSymbolUniqueId(2990);
+ static constexpr const TSymbolUniqueId gl_LayerES3_2 = TSymbolUniqueId(2991);
+ static constexpr const TSymbolUniqueId gl_SampleID = TSymbolUniqueId(2992);
+ static constexpr const TSymbolUniqueId gl_SampleIDES3_2 = TSymbolUniqueId(2993);
+ static constexpr const TSymbolUniqueId gl_SamplePosition = TSymbolUniqueId(2994);
+ static constexpr const TSymbolUniqueId gl_SamplePositionES3_2 = TSymbolUniqueId(2995);
+ static constexpr const TSymbolUniqueId gl_SampleMaskIn = TSymbolUniqueId(2996);
+ static constexpr const TSymbolUniqueId gl_SampleMaskInES3_2 = TSymbolUniqueId(2997);
+ static constexpr const TSymbolUniqueId gl_SampleMask = TSymbolUniqueId(2998);
+ static constexpr const TSymbolUniqueId gl_SampleMaskES3_2 = TSymbolUniqueId(2999);
+ static constexpr const TSymbolUniqueId gl_CullDistance = TSymbolUniqueId(3000);
+ static constexpr const TSymbolUniqueId gl_ClipDistance = TSymbolUniqueId(3001);
+ static constexpr const TSymbolUniqueId gl_Position = TSymbolUniqueId(3002);
+ static constexpr const TSymbolUniqueId gl_PointSize = TSymbolUniqueId(3003);
+ static constexpr const TSymbolUniqueId gl_InstanceID = TSymbolUniqueId(3004);
+ static constexpr const TSymbolUniqueId gl_InstanceIndex = TSymbolUniqueId(3005);
+ static constexpr const TSymbolUniqueId gl_VertexID = TSymbolUniqueId(3006);
+ static constexpr const TSymbolUniqueId gl_VertexIndex = TSymbolUniqueId(3007);
+ static constexpr const TSymbolUniqueId gl_ViewportIndex = TSymbolUniqueId(3008);
+ static constexpr const TSymbolUniqueId gl_LayerVS = TSymbolUniqueId(3009);
+ static constexpr const TSymbolUniqueId gl_PointSize300 = TSymbolUniqueId(3010);
+ static constexpr const TSymbolUniqueId gl_DrawID = TSymbolUniqueId(3011);
+ static constexpr const TSymbolUniqueId gl_BaseVertex = TSymbolUniqueId(3012);
+ static constexpr const TSymbolUniqueId gl_BaseInstance = TSymbolUniqueId(3013);
+ static constexpr const TSymbolUniqueId angle_BaseVertex = TSymbolUniqueId(3014);
+ static constexpr const TSymbolUniqueId angle_BaseInstance = TSymbolUniqueId(3015);
+ static constexpr const TSymbolUniqueId gl_ClipDistanceAPPLE = TSymbolUniqueId(3016);
+ static constexpr const TSymbolUniqueId gl_CullDistanceEXT = TSymbolUniqueId(3017);
+ static constexpr const TSymbolUniqueId gl_NumWorkGroups = TSymbolUniqueId(3018);
+ static constexpr const TSymbolUniqueId gl_WorkGroupSize = TSymbolUniqueId(3019);
+ static constexpr const TSymbolUniqueId gl_WorkGroupID = TSymbolUniqueId(3020);
+ static constexpr const TSymbolUniqueId gl_LocalInvocationID = TSymbolUniqueId(3021);
+ static constexpr const TSymbolUniqueId gl_GlobalInvocationID = TSymbolUniqueId(3022);
+ static constexpr const TSymbolUniqueId gl_LocalInvocationIndex = TSymbolUniqueId(3023);
+ static constexpr const TSymbolUniqueId gl_PrimitiveIDIn = TSymbolUniqueId(3024);
+ static constexpr const TSymbolUniqueId gl_PrimitiveIDInES3_2 = TSymbolUniqueId(3025);
+ static constexpr const TSymbolUniqueId gl_InvocationID = TSymbolUniqueId(3026);
+ static constexpr const TSymbolUniqueId gl_InvocationIDES3_2 = TSymbolUniqueId(3027);
+ static constexpr const TSymbolUniqueId gl_PrimitiveIDGS = TSymbolUniqueId(3028);
+ static constexpr const TSymbolUniqueId gl_PrimitiveIDGSES3_2 = TSymbolUniqueId(3029);
+ static constexpr const TSymbolUniqueId gl_LayerGS = TSymbolUniqueId(3030);
+ static constexpr const TSymbolUniqueId gl_LayerGSES3_2 = TSymbolUniqueId(3031);
+ static constexpr const TSymbolUniqueId gl_PerVertex = TSymbolUniqueId(3032);
+ static constexpr const TSymbolUniqueId gl_PerVertexES3_2 = TSymbolUniqueId(3033);
+ static constexpr const TSymbolUniqueId gl_in = TSymbolUniqueId(3034);
+ static constexpr const TSymbolUniqueId gl_inES3_2 = TSymbolUniqueId(3035);
+ static constexpr const TSymbolUniqueId gl_PerVertexOutBlock = TSymbolUniqueId(3036);
+ static constexpr const TSymbolUniqueId gl_PerVertexOutBlockES3_2 = TSymbolUniqueId(3037);
+ static constexpr const TSymbolUniqueId gl_PositionGS = TSymbolUniqueId(3038);
+ static constexpr const TSymbolUniqueId gl_PositionGSES3_2 = TSymbolUniqueId(3039);
+ static constexpr const TSymbolUniqueId gl_PatchVerticesInTCS = TSymbolUniqueId(3040);
+ static constexpr const TSymbolUniqueId gl_PatchVerticesInTCSES3_2 = TSymbolUniqueId(3041);
+ static constexpr const TSymbolUniqueId gl_InvocationIDTCS = TSymbolUniqueId(3042);
+ static constexpr const TSymbolUniqueId gl_InvocationIDTCSES3_2 = TSymbolUniqueId(3043);
+ static constexpr const TSymbolUniqueId gl_PrimitiveIDTCS = TSymbolUniqueId(3044);
+ static constexpr const TSymbolUniqueId gl_PrimitiveIDTCSES3_2 = TSymbolUniqueId(3045);
+ static constexpr const TSymbolUniqueId gl_TessLevelOuterTCS = TSymbolUniqueId(3046);
+ static constexpr const TSymbolUniqueId gl_TessLevelOuterTCSES3_2 = TSymbolUniqueId(3047);
+ static constexpr const TSymbolUniqueId gl_TessLevelInnerTCS = TSymbolUniqueId(3048);
+ static constexpr const TSymbolUniqueId gl_TessLevelInnerTCSES3_2 = TSymbolUniqueId(3049);
+ static constexpr const TSymbolUniqueId gl_PerVertexTCS = TSymbolUniqueId(3050);
+ static constexpr const TSymbolUniqueId gl_PerVertexTCSES3_2 = TSymbolUniqueId(3051);
+ static constexpr const TSymbolUniqueId gl_inTCS = TSymbolUniqueId(3052);
+ static constexpr const TSymbolUniqueId gl_inTCSES3_2 = TSymbolUniqueId(3053);
+ static constexpr const TSymbolUniqueId gl_outTCS = TSymbolUniqueId(3054);
+ static constexpr const TSymbolUniqueId gl_outTCSES3_2 = TSymbolUniqueId(3055);
+ static constexpr const TSymbolUniqueId gl_BoundingBoxTCS = TSymbolUniqueId(3056);
+ static constexpr const TSymbolUniqueId gl_BoundingBoxTCSES3_2 = TSymbolUniqueId(3057);
+ static constexpr const TSymbolUniqueId gl_PerVertexOutTcsBlock = TSymbolUniqueId(3058);
+ static constexpr const TSymbolUniqueId gl_PerVertexOutTcsBlockES3_2 = TSymbolUniqueId(3059);
+ static constexpr const TSymbolUniqueId gl_PositionTCS = TSymbolUniqueId(3060);
+ static constexpr const TSymbolUniqueId gl_PositionTCSES3_2 = TSymbolUniqueId(3061);
+ static constexpr const TSymbolUniqueId gl_BoundingBoxEXTTCS = TSymbolUniqueId(3062);
+ static constexpr const TSymbolUniqueId gl_BoundingBoxEXTTCSES3_2 = TSymbolUniqueId(3063);
+ static constexpr const TSymbolUniqueId gl_BoundingBoxOESTCS = TSymbolUniqueId(3064);
+ static constexpr const TSymbolUniqueId gl_BoundingBoxOESTCSES3_2 = TSymbolUniqueId(3065);
+ static constexpr const TSymbolUniqueId gl_PatchVerticesInTES = TSymbolUniqueId(3066);
+ static constexpr const TSymbolUniqueId gl_PatchVerticesInTESES3_2 = TSymbolUniqueId(3067);
+ static constexpr const TSymbolUniqueId gl_PrimitiveIDTES = TSymbolUniqueId(3068);
+ static constexpr const TSymbolUniqueId gl_PrimitiveIDTESES3_2 = TSymbolUniqueId(3069);
+ static constexpr const TSymbolUniqueId gl_TessCoord = TSymbolUniqueId(3070);
+ static constexpr const TSymbolUniqueId gl_TessLevelOuterTES = TSymbolUniqueId(3071);
+ static constexpr const TSymbolUniqueId gl_TessLevelOuterTESES3_2 = TSymbolUniqueId(3072);
+ static constexpr const TSymbolUniqueId gl_TessLevelInnerTES = TSymbolUniqueId(3073);
+ static constexpr const TSymbolUniqueId gl_TessLevelInnerTESES3_2 = TSymbolUniqueId(3074);
+ static constexpr const TSymbolUniqueId gl_PerVertexTES = TSymbolUniqueId(3075);
+ static constexpr const TSymbolUniqueId gl_PerVertexTESES3_2 = TSymbolUniqueId(3076);
+ static constexpr const TSymbolUniqueId gl_inTES = TSymbolUniqueId(3077);
+ static constexpr const TSymbolUniqueId gl_inTESES3_2 = TSymbolUniqueId(3078);
+ static constexpr const TSymbolUniqueId gl_outTES = TSymbolUniqueId(3079);
+ static constexpr const TSymbolUniqueId gl_outTESES3_2 = TSymbolUniqueId(3080);
+ static constexpr const TSymbolUniqueId gl_PerVertexOutTesBlock = TSymbolUniqueId(3081);
+ static constexpr const TSymbolUniqueId gl_PerVertexOutTesBlockES3_2 = TSymbolUniqueId(3082);
+ static constexpr const TSymbolUniqueId gl_PositionTES = TSymbolUniqueId(3083);
+ static constexpr const TSymbolUniqueId gl_PositionTESES3_2 = TSymbolUniqueId(3084);
+ static constexpr const TSymbolUniqueId gl_ViewID_OVR = TSymbolUniqueId(3085);
+
+}; // class BuiltInId
+
+namespace BuiltInVariable
+{
+
+const TVariable *angle_BaseInstance();
+const TVariable *angle_BaseVertex();
+const TVariable *gl_BaseInstance();
+const TVariable *gl_BaseVertex();
+const TVariable *gl_DrawID();
+const TVariable *gl_FragColor();
+const TVariable *gl_FragCoord();
+const TVariable *gl_FragCoord300();
+const TVariable *gl_FragDepth();
+const TVariable *gl_FrontFacing();
+const TVariable *gl_GlobalInvocationID();
+const TVariable *gl_HelperInvocation();
+const TVariable *gl_InstanceID();
+const TVariable *gl_InstanceIndex();
+const TVariable *gl_InvocationID();
+const TVariable *gl_InvocationIDES3_2();
+const TVariable *gl_InvocationIDTCS();
+const TVariable *gl_InvocationIDTCSES3_2();
+const TVariable *gl_LastFragColor();
+const TVariable *gl_LastFragColorARM();
+const TVariable *gl_Layer();
+const TVariable *gl_LayerES3_2();
+const TVariable *gl_LayerGS();
+const TVariable *gl_LayerGSES3_2();
+const TVariable *gl_LayerVS();
+const TVariable *gl_LocalInvocationID();
+const TVariable *gl_LocalInvocationIndex();
+const TVariable *gl_NumSamples();
+const TVariable *gl_NumSamplesES3_2();
+const TVariable *gl_NumWorkGroups();
+const TVariable *gl_PatchVerticesInTCS();
+const TVariable *gl_PatchVerticesInTCSES3_2();
+const TVariable *gl_PatchVerticesInTES();
+const TVariable *gl_PatchVerticesInTESES3_2();
+const TVariable *gl_PointCoord();
+const TVariable *gl_PointSize();
+const TVariable *gl_PointSize300();
+const TVariable *gl_Position();
+const TVariable *gl_PrimitiveID();
+const TVariable *gl_PrimitiveIDES3_2();
+const TVariable *gl_PrimitiveIDGS();
+const TVariable *gl_PrimitiveIDGSES3_2();
+const TVariable *gl_PrimitiveIDIn();
+const TVariable *gl_PrimitiveIDInES3_2();
+const TVariable *gl_PrimitiveIDTCS();
+const TVariable *gl_PrimitiveIDTCSES3_2();
+const TVariable *gl_PrimitiveIDTES();
+const TVariable *gl_PrimitiveIDTESES3_2();
+const TVariable *gl_SampleID();
+const TVariable *gl_SampleIDES3_2();
+const TVariable *gl_SamplePosition();
+const TVariable *gl_SamplePositionES3_2();
+const TVariable *gl_SecondaryFragColorEXT();
+const TVariable *gl_TessCoord();
+const TVariable *gl_VertexID();
+const TVariable *gl_VertexIndex();
+const TVariable *gl_ViewID_OVR();
+const TVariable *gl_ViewportIndex();
+const TVariable *gl_WorkGroupID();
+const TVariable *gl_WorkGroupSize();
+
+} // namespace BuiltInVariable
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEUTIL_BUILTIN_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/DriverUniform.cpp b/gfx/angle/checkout/src/compiler/translator/tree_util/DriverUniform.cpp
new file mode 100644
index 0000000000..9cf4dddcd0
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/DriverUniform.cpp
@@ -0,0 +1,435 @@
+//
+// Copyright 2020 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.
+//
+// DriverUniform.cpp: Add code to support driver uniforms
+//
+
+#include "compiler/translator/tree_util/DriverUniform.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/StaticType.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/FindMain.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+constexpr ImmutableString kEmulatedDepthRangeParams = ImmutableString("ANGLEDepthRangeParams");
+
+constexpr const char kAcbBufferOffsets[] = "acbBufferOffsets";
+constexpr const char kDepthRange[] = "depthRange";
+constexpr const char kRenderArea[] = "renderArea";
+constexpr const char kFlipXY[] = "flipXY";
+constexpr const char kDither[] = "dither";
+constexpr const char kMisc[] = "misc";
+
+// Extended uniforms
+constexpr const char kXfbBufferOffsets[] = "xfbBufferOffsets";
+constexpr const char kXfbVerticesPerInstance[] = "xfbVerticesPerInstance";
+constexpr const char kUnused[] = "unused";
+constexpr const char kUnused2[] = "unused2";
+} // anonymous namespace
+
+// Class DriverUniform
+bool DriverUniform::addComputeDriverUniformsToShader(TIntermBlock *root, TSymbolTable *symbolTable)
+{
+ constexpr size_t kNumComputeDriverUniforms = 1;
+ constexpr std::array<const char *, kNumComputeDriverUniforms> kComputeDriverUniformNames = {
+ {kAcbBufferOffsets}};
+
+ ASSERT(!mDriverUniforms);
+ // This field list mirrors the structure of ComputeDriverUniforms in ContextVk.cpp.
+ TFieldList *driverFieldList = new TFieldList;
+
+ const std::array<TType *, kNumComputeDriverUniforms> kDriverUniformTypes = {{
+ new TType(EbtUInt, EbpHigh, EvqGlobal, 4),
+ }};
+
+ for (size_t uniformIndex = 0; uniformIndex < kNumComputeDriverUniforms; ++uniformIndex)
+ {
+ TField *driverUniformField =
+ new TField(kDriverUniformTypes[uniformIndex],
+ ImmutableString(kComputeDriverUniformNames[uniformIndex]), TSourceLoc(),
+ SymbolType::AngleInternal);
+ driverFieldList->push_back(driverUniformField);
+ }
+
+ // Define a driver uniform block "ANGLEUniformBlock" with instance name "ANGLEUniforms".
+ TLayoutQualifier layoutQualifier = TLayoutQualifier::Create();
+ layoutQualifier.blockStorage = EbsStd140;
+ layoutQualifier.pushConstant = true;
+
+ mDriverUniforms = DeclareInterfaceBlock(root, symbolTable, driverFieldList, EvqUniform,
+ layoutQualifier, TMemoryQualifier::Create(), 0,
+ ImmutableString(vk::kDriverUniformsBlockName),
+ ImmutableString(vk::kDriverUniformsVarName));
+ return mDriverUniforms != nullptr;
+}
+
+TFieldList *DriverUniform::createUniformFields(TSymbolTable *symbolTable)
+{
+ constexpr size_t kNumGraphicsDriverUniforms = 6;
+ constexpr std::array<const char *, kNumGraphicsDriverUniforms> kGraphicsDriverUniformNames = {{
+ kAcbBufferOffsets,
+ kDepthRange,
+ kRenderArea,
+ kFlipXY,
+ kDither,
+ kMisc,
+ }};
+
+ // This field list mirrors the structure of GraphicsDriverUniforms in ContextVk.cpp.
+ TFieldList *driverFieldList = new TFieldList;
+
+ const std::array<TType *, kNumGraphicsDriverUniforms> kDriverUniformTypes = {{
+ // acbBufferOffsets: Packed ubyte8
+ new TType(EbtUInt, EbpHigh, EvqGlobal, 2),
+ // depthRange: Near and far depth
+ new TType(EbtFloat, EbpHigh, EvqGlobal, 2),
+ // renderArea: Packed ushort2
+ new TType(EbtUInt, EbpHigh, EvqGlobal),
+ // flipXY: Packed snorm4
+ new TType(EbtUInt, EbpHigh, EvqGlobal),
+ // dither: ushort
+ new TType(EbtUInt, EbpHigh, EvqGlobal),
+ // misc: Various bits of state
+ new TType(EbtUInt, EbpHigh, EvqGlobal),
+ }};
+
+ for (size_t uniformIndex = 0; uniformIndex < kNumGraphicsDriverUniforms; ++uniformIndex)
+ {
+ TField *driverUniformField =
+ new TField(kDriverUniformTypes[uniformIndex],
+ ImmutableString(kGraphicsDriverUniformNames[uniformIndex]), TSourceLoc(),
+ SymbolType::AngleInternal);
+ driverFieldList->push_back(driverUniformField);
+ }
+
+ return driverFieldList;
+}
+
+const TType *DriverUniform::createEmulatedDepthRangeType(TSymbolTable *symbolTable)
+{
+ // If already defined, return it immediately.
+ if (mEmulatedDepthRangeType != nullptr)
+ {
+ return mEmulatedDepthRangeType;
+ }
+
+ // Create the depth range type.
+ TFieldList *depthRangeParamsFields = new TFieldList();
+ TType *floatType = new TType(EbtFloat, EbpHigh, EvqGlobal, 1, 1);
+ depthRangeParamsFields->push_back(
+ new TField(floatType, ImmutableString("near"), TSourceLoc(), SymbolType::AngleInternal));
+ depthRangeParamsFields->push_back(
+ new TField(floatType, ImmutableString("far"), TSourceLoc(), SymbolType::AngleInternal));
+ depthRangeParamsFields->push_back(
+ new TField(floatType, ImmutableString("diff"), TSourceLoc(), SymbolType::AngleInternal));
+
+ TStructure *emulatedDepthRangeParams = new TStructure(
+ symbolTable, kEmulatedDepthRangeParams, depthRangeParamsFields, SymbolType::AngleInternal);
+
+ mEmulatedDepthRangeType = new TType(emulatedDepthRangeParams, false);
+
+ return mEmulatedDepthRangeType;
+}
+
+// The Add*DriverUniformsToShader operation adds an internal uniform block to a shader. The driver
+// block is used to implement Vulkan-specific features and workarounds. Returns the driver uniforms
+// variable.
+//
+// There are Graphics and Compute variations as they require different uniforms.
+bool DriverUniform::addGraphicsDriverUniformsToShader(TIntermBlock *root, TSymbolTable *symbolTable)
+{
+ ASSERT(!mDriverUniforms);
+
+ // Declare the depth range struct type.
+ const TType *emulatedDepthRangeType = createEmulatedDepthRangeType(symbolTable);
+ const TType *emulatedDepthRangeDeclType = new TType(emulatedDepthRangeType->getStruct(), true);
+
+ const TVariable *depthRangeVar =
+ new TVariable(symbolTable->nextUniqueId(), kEmptyImmutableString, SymbolType::Empty,
+ TExtension::UNDEFINED, emulatedDepthRangeDeclType);
+
+ DeclareGlobalVariable(root, depthRangeVar);
+
+ TFieldList *driverFieldList = createUniformFields(symbolTable);
+ if (mMode == DriverUniformMode::InterfaceBlock)
+ {
+ // Define a driver uniform block "ANGLEUniformBlock" with instance name "ANGLEUniforms".
+ TLayoutQualifier layoutQualifier = TLayoutQualifier::Create();
+ layoutQualifier.blockStorage = EbsStd140;
+ layoutQualifier.pushConstant = true;
+
+ mDriverUniforms = DeclareInterfaceBlock(root, symbolTable, driverFieldList, EvqUniform,
+ layoutQualifier, TMemoryQualifier::Create(), 0,
+ ImmutableString(vk::kDriverUniformsBlockName),
+ ImmutableString(vk::kDriverUniformsVarName));
+ }
+ else
+ {
+ // Declare a structure "ANGLEUniformBlock" with instance name "ANGLE_angleUniforms".
+ // This code path is taken only by the direct-to-Metal backend, and the assumptions
+ // about the naming conventions of ANGLE-internal variables run too deeply to rename
+ // this one.
+ auto varName = ImmutableString("ANGLE_angleUniforms");
+ auto result = DeclareStructure(root, symbolTable, driverFieldList, EvqUniform,
+ TMemoryQualifier::Create(), 0,
+ ImmutableString(vk::kDriverUniformsBlockName), &varName);
+ mDriverUniforms = result.second;
+ }
+
+ return mDriverUniforms != nullptr;
+}
+
+TIntermTyped *DriverUniform::createDriverUniformRef(const char *fieldName) const
+{
+ size_t fieldIndex = 0;
+ if (mMode == DriverUniformMode::InterfaceBlock)
+ {
+ fieldIndex =
+ FindFieldIndex(mDriverUniforms->getType().getInterfaceBlock()->fields(), fieldName);
+ }
+ else
+ {
+ fieldIndex = FindFieldIndex(mDriverUniforms->getType().getStruct()->fields(), fieldName);
+ }
+
+ TIntermSymbol *angleUniformsRef = new TIntermSymbol(mDriverUniforms);
+ TConstantUnion *uniformIndex = new TConstantUnion;
+ uniformIndex->setIConst(static_cast<int>(fieldIndex));
+ TIntermConstantUnion *indexRef =
+ new TIntermConstantUnion(uniformIndex, *StaticType::GetBasic<EbtInt, EbpLow>());
+ if (mMode == DriverUniformMode::InterfaceBlock)
+ {
+ return new TIntermBinary(EOpIndexDirectInterfaceBlock, angleUniformsRef, indexRef);
+ }
+ return new TIntermBinary(EOpIndexDirectStruct, angleUniformsRef, indexRef);
+}
+
+TIntermTyped *DriverUniform::getAcbBufferOffsets() const
+{
+ return createDriverUniformRef(kAcbBufferOffsets);
+}
+
+TIntermTyped *DriverUniform::getDepthRange() const
+{
+ ASSERT(mEmulatedDepthRangeType != nullptr);
+
+ TIntermTyped *depthRangeRef = createDriverUniformRef(kDepthRange);
+ TIntermTyped *nearRef = new TIntermSwizzle(depthRangeRef, {0});
+ TIntermTyped *farRef = new TIntermSwizzle(depthRangeRef->deepCopy(), {1});
+ TIntermTyped *diff = new TIntermBinary(EOpSub, farRef, nearRef);
+
+ TIntermSequence args = {
+ nearRef->deepCopy(),
+ farRef->deepCopy(),
+ diff,
+ };
+
+ return TIntermAggregate::CreateConstructor(*mEmulatedDepthRangeType, &args);
+}
+
+TIntermTyped *DriverUniform::getViewportZScale() const
+{
+ ASSERT(mEmulatedDepthRangeType != nullptr);
+
+ TIntermTyped *depthRangeRef = createDriverUniformRef(kDepthRange);
+ TIntermTyped *nearRef = new TIntermSwizzle(depthRangeRef, {0});
+ TIntermTyped *farRef = new TIntermSwizzle(depthRangeRef->deepCopy(), {1});
+
+ TIntermTyped *isNegative = new TIntermBinary(EOpLessThan, farRef, nearRef);
+
+ return new TIntermTernary(isNegative, CreateFloatNode(-1, EbpMedium),
+ CreateFloatNode(1, EbpMedium));
+}
+
+TIntermTyped *DriverUniform::getHalfRenderArea() const
+{
+ TIntermTyped *renderAreaRef = createDriverUniformRef(kRenderArea);
+ TIntermTyped *width = new TIntermBinary(EOpBitwiseAnd, renderAreaRef, CreateUIntNode(0xFFFF));
+ TIntermTyped *height =
+ new TIntermBinary(EOpBitShiftRight, renderAreaRef->deepCopy(), CreateUIntNode(16));
+
+ TIntermSequence widthArgs = {
+ width,
+ };
+ TIntermTyped *widthAsFloat =
+ TIntermAggregate::CreateConstructor(*StaticType::GetBasic<EbtFloat, EbpHigh>(), &widthArgs);
+
+ TIntermSequence heightArgs = {
+ height,
+ };
+ TIntermTyped *heightAsFloat = TIntermAggregate::CreateConstructor(
+ *StaticType::GetBasic<EbtFloat, EbpHigh>(), &heightArgs);
+
+ TIntermSequence args = {
+ widthAsFloat,
+ heightAsFloat,
+ };
+
+ TIntermTyped *renderArea =
+ TIntermAggregate::CreateConstructor(*StaticType::GetBasic<EbtFloat, EbpHigh, 2>(), &args);
+ return new TIntermBinary(EOpVectorTimesScalar, renderArea, CreateFloatNode(0.5, EbpMedium));
+}
+
+TIntermTyped *DriverUniform::getFlipXY(TSymbolTable *symbolTable, DriverUniformFlip stage) const
+{
+ TIntermTyped *flipXY = createDriverUniformRef(kFlipXY);
+ TIntermTyped *values = CreateBuiltInUnaryFunctionCallNode(
+ "unpackSnorm4x8", flipXY, *symbolTable,
+ GetESSLOrGLSLVersion(symbolTable->getShaderSpec(), 310, 400));
+
+ if (stage == DriverUniformFlip::Fragment)
+ {
+ return new TIntermSwizzle(values, {0, 1});
+ }
+
+ return new TIntermSwizzle(values, {2, 3});
+}
+
+TIntermTyped *DriverUniform::getNegFlipXY(TSymbolTable *symbolTable, DriverUniformFlip stage) const
+{
+ TIntermTyped *flipXY = getFlipXY(symbolTable, stage);
+
+ constexpr std::array<float, 2> kMultiplier = {1, -1};
+ return new TIntermBinary(EOpMul, flipXY, CreateVecNode(kMultiplier.data(), 2, EbpLow));
+}
+
+TIntermTyped *DriverUniform::getDither() const
+{
+ return createDriverUniformRef(kDither);
+}
+
+TIntermTyped *DriverUniform::getSwapXY() const
+{
+ TIntermTyped *miscRef = createDriverUniformRef(kMisc);
+ TIntermTyped *swapXY = new TIntermBinary(EOpBitwiseAnd, miscRef,
+ CreateUIntNode(vk::kDriverUniformsMiscSwapXYMask));
+
+ TIntermSequence args = {
+ swapXY,
+ };
+ return TIntermAggregate::CreateConstructor(*StaticType::GetBasic<EbtBool, EbpUndefined>(),
+ &args);
+}
+
+TIntermTyped *DriverUniform::getAdvancedBlendEquation() const
+{
+ TIntermTyped *miscRef = createDriverUniformRef(kMisc);
+ TIntermTyped *equation =
+ new TIntermBinary(EOpBitShiftRight, miscRef,
+ CreateUIntNode(vk::kDriverUniformsMiscAdvancedBlendEquationOffset));
+ equation = new TIntermBinary(EOpBitwiseAnd, equation,
+ CreateUIntNode(vk::kDriverUniformsMiscAdvancedBlendEquationMask));
+
+ return equation;
+}
+
+TIntermTyped *DriverUniform::getNumSamples() const
+{
+ TIntermTyped *miscRef = createDriverUniformRef(kMisc);
+ TIntermTyped *sampleCount = new TIntermBinary(
+ EOpBitShiftRight, miscRef, CreateUIntNode(vk::kDriverUniformsMiscSampleCountOffset));
+ sampleCount = new TIntermBinary(EOpBitwiseAnd, sampleCount,
+ CreateUIntNode(vk::kDriverUniformsMiscSampleCountMask));
+
+ return sampleCount;
+}
+
+TIntermTyped *DriverUniform::getClipDistancesEnabled() const
+{
+ TIntermTyped *miscRef = createDriverUniformRef(kMisc);
+ TIntermTyped *enabledMask = new TIntermBinary(
+ EOpBitShiftRight, miscRef, CreateUIntNode(vk::kDriverUniformsMiscEnabledClipPlanesOffset));
+ enabledMask = new TIntermBinary(EOpBitwiseAnd, enabledMask,
+ CreateUIntNode(vk::kDriverUniformsMiscEnabledClipPlanesMask));
+
+ return enabledMask;
+}
+
+TIntermTyped *DriverUniform::getTransformDepth() const
+{
+ TIntermTyped *miscRef = createDriverUniformRef(kMisc);
+ TIntermTyped *transformDepth = new TIntermBinary(
+ EOpBitShiftRight, miscRef, CreateUIntNode(vk::kDriverUniformsMiscTransformDepthOffset));
+ transformDepth = new TIntermBinary(EOpBitwiseAnd, transformDepth,
+ CreateUIntNode(vk::kDriverUniformsMiscTransformDepthMask));
+
+ TIntermSequence args = {
+ transformDepth,
+ };
+ return TIntermAggregate::CreateConstructor(*StaticType::GetBasic<EbtBool, EbpUndefined>(),
+ &args);
+}
+
+//
+// Class DriverUniformExtended
+//
+TFieldList *DriverUniformExtended::createUniformFields(TSymbolTable *symbolTable)
+{
+ TFieldList *driverFieldList = DriverUniform::createUniformFields(symbolTable);
+
+ constexpr size_t kNumGraphicsDriverUniformsExt = 4;
+ constexpr std::array<const char *, kNumGraphicsDriverUniformsExt>
+ kGraphicsDriverUniformNamesExt = {
+ {kXfbBufferOffsets, kXfbVerticesPerInstance, kUnused, kUnused2}};
+
+ const std::array<TType *, kNumGraphicsDriverUniformsExt> kDriverUniformTypesExt = {{
+ // xfbBufferOffsets: uvec4
+ new TType(EbtInt, EbpHigh, EvqGlobal, 4),
+ // xfbVerticesPerInstance: uint
+ new TType(EbtInt, EbpHigh, EvqGlobal),
+ // unused: uvec3
+ new TType(EbtUInt, EbpHigh, EvqGlobal),
+ new TType(EbtUInt, EbpHigh, EvqGlobal, 2),
+ }};
+
+ for (size_t uniformIndex = 0; uniformIndex < kNumGraphicsDriverUniformsExt; ++uniformIndex)
+ {
+ TField *driverUniformField =
+ new TField(kDriverUniformTypesExt[uniformIndex],
+ ImmutableString(kGraphicsDriverUniformNamesExt[uniformIndex]), TSourceLoc(),
+ SymbolType::AngleInternal);
+ driverFieldList->push_back(driverUniformField);
+ }
+
+ return driverFieldList;
+}
+
+TIntermTyped *DriverUniformExtended::getXfbBufferOffsets() const
+{
+ return createDriverUniformRef(kXfbBufferOffsets);
+}
+
+TIntermTyped *DriverUniformExtended::getXfbVerticesPerInstance() const
+{
+ return createDriverUniformRef(kXfbVerticesPerInstance);
+}
+
+TIntermTyped *MakeSwapXMultiplier(TIntermTyped *swapped)
+{
+ // float(!swapped)
+ TIntermSequence args = {
+ new TIntermUnary(EOpLogicalNot, swapped, nullptr),
+ };
+ return TIntermAggregate::CreateConstructor(*StaticType::GetBasic<EbtFloat, EbpLow>(), &args);
+}
+
+TIntermTyped *MakeSwapYMultiplier(TIntermTyped *swapped)
+{
+ // float(swapped)
+ TIntermSequence args = {
+ swapped,
+ };
+ return TIntermAggregate::CreateConstructor(*StaticType::GetBasic<EbtFloat, EbpLow>(), &args);
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/DriverUniform.h b/gfx/angle/checkout/src/compiler/translator/tree_util/DriverUniform.h
new file mode 100644
index 0000000000..53eebae74d
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/DriverUniform.h
@@ -0,0 +1,110 @@
+//
+// Copyright 2020 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.
+//
+// DriverUniform.h: Add code to support driver uniforms
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEUTIL_DRIVERUNIFORM_H_
+#define COMPILER_TRANSLATOR_TREEUTIL_DRIVERUNIFORM_H_
+
+#include "common/angleutils.h"
+#include "compiler/translator/Types.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermBlock;
+class TIntermNode;
+class TSymbolTable;
+class TIntermTyped;
+class TIntermSwizzle;
+class TIntermBinary;
+
+enum class DriverUniformMode
+{
+ // Define the driver uniforms as an interface block. Used by the
+ // Vulkan and Metal/SPIR-V backends.
+ InterfaceBlock,
+
+ // Define the driver uniforms as a structure. Used by the
+ // direct-to-MSL Metal backend.
+ Structure
+};
+
+enum class DriverUniformFlip
+{
+ // Flip uniforms for fragment shaders
+ Fragment,
+ // Flip uniforms for pre-rasterization stages. These differ from the fragment values by whether
+ // the viewport needs to be flipped, and whether negative viewports are supported.
+ PreFragment,
+};
+
+class DriverUniform
+{
+ public:
+ DriverUniform(DriverUniformMode mode)
+ : mMode(mode), mDriverUniforms(nullptr), mEmulatedDepthRangeType(nullptr)
+ {}
+ virtual ~DriverUniform() = default;
+
+ bool addComputeDriverUniformsToShader(TIntermBlock *root, TSymbolTable *symbolTable);
+ bool addGraphicsDriverUniformsToShader(TIntermBlock *root, TSymbolTable *symbolTable);
+
+ TIntermTyped *getAcbBufferOffsets() const;
+ TIntermTyped *getDepthRange() const;
+ TIntermTyped *getViewportZScale() const;
+ TIntermTyped *getHalfRenderArea() const;
+ TIntermTyped *getFlipXY(TSymbolTable *symbolTable, DriverUniformFlip stage) const;
+ // Returns vec2(flip.x, -flip.y)
+ TIntermTyped *getNegFlipXY(TSymbolTable *symbolTable, DriverUniformFlip stage) const;
+ TIntermTyped *getDither() const;
+ TIntermTyped *getSwapXY() const;
+ TIntermTyped *getAdvancedBlendEquation() const;
+ TIntermTyped *getNumSamples() const;
+ TIntermTyped *getClipDistancesEnabled() const;
+ TIntermTyped *getTransformDepth() const;
+
+ virtual TIntermTyped *getViewport() const { return nullptr; }
+ virtual TIntermTyped *getXfbBufferOffsets() const { return nullptr; }
+ virtual TIntermTyped *getXfbVerticesPerInstance() const { return nullptr; }
+
+ const TVariable *getDriverUniformsVariable() const { return mDriverUniforms; }
+
+ protected:
+ TIntermTyped *createDriverUniformRef(const char *fieldName) const;
+ virtual TFieldList *createUniformFields(TSymbolTable *symbolTable);
+ const TType *createEmulatedDepthRangeType(TSymbolTable *symbolTable);
+
+ const DriverUniformMode mMode;
+ const TVariable *mDriverUniforms;
+ TType *mEmulatedDepthRangeType;
+};
+
+class DriverUniformExtended : public DriverUniform
+{
+ public:
+ DriverUniformExtended(DriverUniformMode mode) : DriverUniform(mode) {}
+ ~DriverUniformExtended() override {}
+
+ TIntermTyped *getXfbBufferOffsets() const override;
+ TIntermTyped *getXfbVerticesPerInstance() const override;
+
+ protected:
+ TFieldList *createUniformFields(TSymbolTable *symbolTable) override;
+};
+
+// Returns either (1,0) or (0,1) based on whether X and Y should remain as-is or swapped
+// respectively. dot((x,y), multiplier) will yield x, and dot((x,y), multiplier.yx) will yield y in
+// the possibly-swapped coordinates.
+//
+// Each component is separately returned by a function
+TIntermTyped *MakeSwapXMultiplier(TIntermTyped *swapped);
+TIntermTyped *MakeSwapYMultiplier(TIntermTyped *swapped);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEUTIL_DRIVERUNIFORM_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/FindFunction.cpp b/gfx/angle/checkout/src/compiler/translator/tree_util/FindFunction.cpp
new file mode 100644
index 0000000000..198040df14
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/FindFunction.cpp
@@ -0,0 +1,32 @@
+//
+// Copyright 2019 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.
+//
+
+// FindFunction.cpp: Find functions.
+
+#include "compiler/translator/tree_util/FindFunction.h"
+
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/Symbol.h"
+
+namespace sh
+{
+
+size_t FindFirstFunctionDefinitionIndex(TIntermBlock *root)
+{
+ const TIntermSequence &sequence = *root->getSequence();
+ for (size_t index = 0; index < sequence.size(); ++index)
+ {
+ TIntermNode *node = sequence[index];
+ TIntermFunctionDefinition *nodeFunction = node->getAsFunctionDefinition();
+ if (nodeFunction != nullptr)
+ {
+ return index;
+ }
+ }
+ return std::numeric_limits<size_t>::max();
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/FindFunction.h b/gfx/angle/checkout/src/compiler/translator/tree_util/FindFunction.h
new file mode 100644
index 0000000000..ced6b7e96e
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/FindFunction.h
@@ -0,0 +1,21 @@
+//
+// Copyright 2019 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.
+//
+
+// FindFunction.h: Adds functions to find functions
+
+#ifndef COMPILER_TRANSLATOR_TREEUTIL_FINDFUNCTION_H_
+#define COMPILER_TRANSLATOR_TREEUTIL_FINDFUNCTION_H_
+
+#include <cstddef>
+
+namespace sh
+{
+class TIntermBlock;
+
+size_t FindFirstFunctionDefinitionIndex(TIntermBlock *root);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEUTIL_FINDFUNCTION_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/FindMain.cpp b/gfx/angle/checkout/src/compiler/translator/tree_util/FindMain.cpp
new file mode 100644
index 0000000000..833948602a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/FindMain.cpp
@@ -0,0 +1,54 @@
+//
+// Copyright 2017 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.
+//
+
+// FindMain.cpp: Find the main() function definition in a given AST.
+
+#include "compiler/translator/tree_util/FindMain.h"
+
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/Symbol.h"
+
+namespace sh
+{
+
+size_t FindMainIndex(TIntermBlock *root)
+{
+ const TIntermSequence &sequence = *root->getSequence();
+ for (size_t index = 0; index < sequence.size(); ++index)
+ {
+ TIntermNode *node = sequence[index];
+ TIntermFunctionDefinition *nodeFunction = node->getAsFunctionDefinition();
+ if (nodeFunction != nullptr && nodeFunction->getFunction()->isMain())
+ {
+ return index;
+ }
+ }
+ return std::numeric_limits<size_t>::max();
+}
+
+TIntermFunctionDefinition *FindMain(TIntermBlock *root)
+{
+ for (TIntermNode *node : *root->getSequence())
+ {
+ TIntermFunctionDefinition *nodeFunction = node->getAsFunctionDefinition();
+ if (nodeFunction != nullptr && nodeFunction->getFunction()->isMain())
+ {
+ return nodeFunction;
+ }
+ }
+ return nullptr;
+}
+
+TIntermBlock *FindMainBody(TIntermBlock *root)
+{
+ TIntermFunctionDefinition *main = FindMain(root);
+ ASSERT(main != nullptr);
+ TIntermBlock *mainBody = main->getBody();
+ ASSERT(mainBody != nullptr);
+ return mainBody;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/FindMain.h b/gfx/angle/checkout/src/compiler/translator/tree_util/FindMain.h
new file mode 100644
index 0000000000..bbdcbe978a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/FindMain.h
@@ -0,0 +1,24 @@
+//
+// Copyright 2017 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.
+//
+
+// FindMain.h: Adds functions to get the main function definition and its body.
+
+#ifndef COMPILER_TRANSLATOR_TREEUTIL_FINDMAIN_H_
+#define COMPILER_TRANSLATOR_TREEUTIL_FINDMAIN_H_
+
+#include <cstddef>
+
+namespace sh
+{
+class TIntermBlock;
+class TIntermFunctionDefinition;
+
+size_t FindMainIndex(TIntermBlock *root);
+TIntermFunctionDefinition *FindMain(TIntermBlock *root);
+TIntermBlock *FindMainBody(TIntermBlock *root);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEUTIL_FINDMAIN_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/FindPreciseNodes.cpp b/gfx/angle/checkout/src/compiler/translator/tree_util/FindPreciseNodes.cpp
new file mode 100644
index 0000000000..2943117314
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/FindPreciseNodes.cpp
@@ -0,0 +1,703 @@
+//
+// Copyright 2021 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.
+//
+// FindPreciseNodes.cpp: Propagates |precise| to AST nodes.
+//
+// The high level algorithm is as follows. For every node that "assigns" to a precise object,
+// subobject (a precise struct whose field is being assigned) or superobject (a struct with a
+// precise field), two things happen:
+//
+// - The operation is marked precise if it's an arithmetic operation
+// - The right hand side of the assignment is made precise. If only a subobject is precise, only
+// the corresponding subobject of the right hand side is made precise.
+//
+
+#include "compiler/translator/tree_util/FindPreciseNodes.h"
+
+#include "common/hash_utils.h"
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/Symbol.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+// An access chain applied to a variable. The |precise|-ness of a node does not change when
+// indexing arrays, selecting matrix columns or swizzle vectors. This access chain thus only
+// includes block field selections. The access chain is used to identify the part of an object
+// that is or should be |precise|. If both a.b.c and a.b are precise, only a.b is every considered.
+class AccessChain
+{
+ public:
+ AccessChain() = default;
+
+ bool operator==(const AccessChain &other) const { return mChain == other.mChain; }
+
+ const TVariable *build(TIntermTyped *lvalue);
+
+ const TVector<size_t> &getChain() const { return mChain; }
+
+ void reduceChain(size_t newSize)
+ {
+ ASSERT(newSize <= mChain.size());
+ mChain.resize(newSize);
+ }
+ void clear() { reduceChain(0); }
+ void push_back(size_t index) { mChain.push_back(index); }
+ void pop_front(size_t n);
+ void append(const AccessChain &other)
+ {
+ mChain.insert(mChain.end(), other.mChain.begin(), other.mChain.end());
+ }
+ bool removePrefix(const AccessChain &other);
+
+ private:
+ TVector<size_t> mChain;
+};
+
+bool IsIndexOp(TOperator op)
+{
+ switch (op)
+ {
+ case EOpIndexDirect:
+ case EOpIndexDirectStruct:
+ case EOpIndexDirectInterfaceBlock:
+ case EOpIndexIndirect:
+ return true;
+ default:
+ return false;
+ }
+}
+
+const TVariable *AccessChain::build(TIntermTyped *lvalue)
+{
+ if (lvalue->getAsSwizzleNode())
+ {
+ return build(lvalue->getAsSwizzleNode()->getOperand());
+ }
+ if (lvalue->getAsSymbolNode())
+ {
+ const TVariable *var = &lvalue->getAsSymbolNode()->variable();
+
+ // For fields of nameless interface blocks, add the field index too.
+ if (var->getType().getInterfaceBlock() != nullptr)
+ {
+ mChain.push_back(var->getType().getInterfaceBlockFieldIndex());
+ }
+
+ return var;
+ }
+ TIntermBinary *binary = lvalue->getAsBinaryNode();
+ ASSERT(binary);
+
+ TOperator op = binary->getOp();
+ ASSERT(IsIndexOp(op));
+
+ const TVariable *var = build(binary->getLeft());
+
+ if (op == EOpIndexDirectStruct || op == EOpIndexDirectInterfaceBlock)
+ {
+ int fieldIndex = binary->getRight()->getAsConstantUnion()->getIConst(0);
+ mChain.push_back(fieldIndex);
+ }
+
+ return var;
+}
+
+void AccessChain::pop_front(size_t n)
+{
+ std::rotate(mChain.begin(), mChain.begin() + n, mChain.end());
+ reduceChain(mChain.size() - n);
+}
+
+bool AccessChain::removePrefix(const AccessChain &other)
+{
+ // First, make sure the common part of the two access chains match.
+ size_t commonSize = std::min(mChain.size(), other.mChain.size());
+
+ for (size_t index = 0; index < commonSize; ++index)
+ {
+ if (mChain[index] != other.mChain[index])
+ {
+ return false;
+ }
+ }
+
+ // Remove the common part from the access chain. If other is a deeper access chain, this access
+ // chain will become empty.
+ pop_front(commonSize);
+
+ return true;
+}
+
+AccessChain GetAssignmentAccessChain(TIntermOperator *node)
+{
+ // The assignment is either a unary or a binary node, and the lvalue is always the first child.
+ AccessChain lvalueAccessChain;
+ lvalueAccessChain.build(node->getChildNode(0)->getAsTyped());
+ return lvalueAccessChain;
+}
+
+template <typename Traverser>
+void TraverseIndexNodesOnly(TIntermNode *node, Traverser *traverser)
+{
+ if (node->getAsSwizzleNode())
+ {
+ node = node->getAsSwizzleNode()->getOperand();
+ }
+
+ if (node->getAsSymbolNode())
+ {
+ return;
+ }
+
+ TIntermBinary *binary = node->getAsBinaryNode();
+ ASSERT(binary);
+
+ TOperator op = binary->getOp();
+ ASSERT(IsIndexOp(op));
+
+ if (op == EOpIndexIndirect)
+ {
+ binary->getRight()->traverse(traverser);
+ }
+
+ TraverseIndexNodesOnly(binary->getLeft(), traverser);
+}
+
+// An object, which could be a sub-object of a variable.
+struct ObjectAndAccessChain
+{
+ const TVariable *variable;
+ AccessChain accessChain;
+};
+
+bool operator==(const ObjectAndAccessChain &a, const ObjectAndAccessChain &b)
+{
+ return a.variable == b.variable && a.accessChain == b.accessChain;
+}
+
+struct ObjectAndAccessChainHash
+{
+ size_t operator()(const ObjectAndAccessChain &object) const
+ {
+ size_t result = angle::ComputeGenericHash(&object.variable, sizeof(object.variable));
+ if (!object.accessChain.getChain().empty())
+ {
+ result =
+ result ^ angle::ComputeGenericHash(object.accessChain.getChain().data(),
+ object.accessChain.getChain().size() *
+ sizeof(object.accessChain.getChain()[0]));
+ }
+ return result;
+ }
+};
+
+// A map from variables to AST nodes that modify them (i.e. nodes where IsAssignment(op)).
+using VariableToAssignmentNodeMap = angle::HashMap<const TVariable *, TVector<TIntermOperator *>>;
+// A set of |return| nodes from functions with a |precise| return value.
+using PreciseReturnNodes = angle::HashSet<TIntermBranch *>;
+// A set of precise objects that need processing, or have been processed.
+using PreciseObjectSet = angle::HashSet<ObjectAndAccessChain, ObjectAndAccessChainHash>;
+
+struct ASTInfo
+{
+ // Generic information about the tree:
+ VariableToAssignmentNodeMap variableAssignmentNodeMap;
+ // Information pertaining to |precise| expressions:
+ PreciseReturnNodes preciseReturnNodes;
+ PreciseObjectSet preciseObjectsToProcess;
+ PreciseObjectSet preciseObjectsVisited;
+};
+
+int GetObjectPreciseSubChainLength(const ObjectAndAccessChain &object)
+{
+ const TType &type = object.variable->getType();
+
+ if (type.isPrecise())
+ {
+ return 0;
+ }
+
+ const TFieldListCollection *block = type.getInterfaceBlock();
+ if (block == nullptr)
+ {
+ block = type.getStruct();
+ }
+ const TVector<size_t> &accessChain = object.accessChain.getChain();
+
+ for (size_t length = 0; length < accessChain.size(); ++length)
+ {
+ ASSERT(block != nullptr);
+
+ const TField *field = block->fields()[accessChain[length]];
+ if (field->type()->isPrecise())
+ {
+ return static_cast<int>(length + 1);
+ }
+
+ block = field->type()->getStruct();
+ }
+
+ return -1;
+}
+
+void AddPreciseObject(ASTInfo *info, const ObjectAndAccessChain &object)
+{
+ if (info->preciseObjectsVisited.count(object) > 0)
+ {
+ return;
+ }
+
+ info->preciseObjectsToProcess.insert(object);
+ info->preciseObjectsVisited.insert(object);
+}
+
+void AddPreciseSubObjects(ASTInfo *info, const ObjectAndAccessChain &object);
+
+void AddObjectIfPrecise(ASTInfo *info, const ObjectAndAccessChain &object)
+{
+ // See if the access chain is already precise, and if so add the minimum access chain that is
+ // precise.
+ int preciseSubChainLength = GetObjectPreciseSubChainLength(object);
+ if (preciseSubChainLength == -1)
+ {
+ // If the access chain is not precise, see if there are any fields of it that are precise,
+ // and add those individually.
+ AddPreciseSubObjects(info, object);
+ return;
+ }
+
+ ObjectAndAccessChain preciseObject = object;
+ preciseObject.accessChain.reduceChain(preciseSubChainLength);
+
+ AddPreciseObject(info, preciseObject);
+}
+
+void AddPreciseSubObjects(ASTInfo *info, const ObjectAndAccessChain &object)
+{
+ const TFieldListCollection *block = object.variable->getType().getInterfaceBlock();
+ if (block == nullptr)
+ {
+ block = object.variable->getType().getStruct();
+ }
+ const TVector<size_t> &accessChain = object.accessChain.getChain();
+
+ for (size_t length = 0; length < accessChain.size(); ++length)
+ {
+ block = block->fields()[accessChain[length]]->type()->getStruct();
+ }
+
+ if (block == nullptr)
+ {
+ return;
+ }
+
+ for (size_t fieldIndex = 0; fieldIndex < block->fields().size(); ++fieldIndex)
+ {
+ ObjectAndAccessChain subObject = object;
+ subObject.accessChain.push_back(fieldIndex);
+
+ // If the field is precise, add it as a precise subobject. Otherwise recurse.
+ if (block->fields()[fieldIndex]->type()->isPrecise())
+ {
+ AddPreciseObject(info, subObject);
+ }
+ else
+ {
+ AddPreciseSubObjects(info, subObject);
+ }
+ }
+}
+
+bool IsArithmeticOp(TOperator op)
+{
+ switch (op)
+ {
+ case EOpNegative:
+
+ case EOpPostIncrement:
+ case EOpPostDecrement:
+ case EOpPreIncrement:
+ case EOpPreDecrement:
+
+ case EOpAdd:
+ case EOpSub:
+ case EOpMul:
+ case EOpDiv:
+ case EOpIMod:
+
+ case EOpVectorTimesScalar:
+ case EOpVectorTimesMatrix:
+ case EOpMatrixTimesVector:
+ case EOpMatrixTimesScalar:
+ case EOpMatrixTimesMatrix:
+
+ case EOpAddAssign:
+ case EOpSubAssign:
+
+ case EOpMulAssign:
+ case EOpVectorTimesMatrixAssign:
+ case EOpVectorTimesScalarAssign:
+ case EOpMatrixTimesScalarAssign:
+ case EOpMatrixTimesMatrixAssign:
+
+ case EOpDivAssign:
+ case EOpIModAssign:
+
+ case EOpDot:
+ return true;
+ default:
+ return false;
+ }
+}
+
+// A traverser that gathers the following information, used to kick off processing:
+//
+// - For each variable, the AST nodes that modify it.
+// - The set of |precise| return AST node.
+// - The set of |precise| access chains assigned to.
+//
+class InfoGatherTraverser : public TIntermTraverser
+{
+ public:
+ InfoGatherTraverser(ASTInfo *info) : TIntermTraverser(true, false, false), mInfo(info) {}
+
+ bool visitUnary(Visit visit, TIntermUnary *node) override
+ {
+ // If the node is an assignment (i.e. ++ and --), store the relevant information.
+ if (!IsAssignment(node->getOp()))
+ {
+ return true;
+ }
+
+ visitLvalue(node, node->getOperand());
+ return false;
+ }
+
+ bool visitBinary(Visit visit, TIntermBinary *node) override
+ {
+ if (IsAssignment(node->getOp()))
+ {
+ visitLvalue(node, node->getLeft());
+
+ node->getRight()->traverse(this);
+
+ return false;
+ }
+
+ return true;
+ }
+
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override
+ {
+ const TIntermSequence &sequence = *(node->getSequence());
+ TIntermSymbol *symbol = sequence.front()->getAsSymbolNode();
+ TIntermBinary *initNode = sequence.front()->getAsBinaryNode();
+ TIntermTyped *initExpression = nullptr;
+
+ if (symbol == nullptr)
+ {
+ ASSERT(initNode->getOp() == EOpInitialize);
+
+ symbol = initNode->getLeft()->getAsSymbolNode();
+ initExpression = initNode->getRight();
+ }
+
+ ASSERT(symbol);
+ ObjectAndAccessChain object = {&symbol->variable(), {}};
+ AddObjectIfPrecise(mInfo, object);
+
+ if (initExpression)
+ {
+ mInfo->variableAssignmentNodeMap[object.variable].push_back(initNode);
+
+ // Visit the init expression, which may itself have assignments.
+ initExpression->traverse(this);
+ }
+
+ return false;
+ }
+
+ bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override
+ {
+ mCurrentFunction = node->getFunction();
+
+ for (size_t paramIndex = 0; paramIndex < mCurrentFunction->getParamCount(); ++paramIndex)
+ {
+ ObjectAndAccessChain param = {mCurrentFunction->getParam(paramIndex), {}};
+ AddObjectIfPrecise(mInfo, param);
+ }
+
+ return true;
+ }
+
+ bool visitBranch(Visit visit, TIntermBranch *node) override
+ {
+ if (node->getFlowOp() == EOpReturn && node->getChildCount() == 1 &&
+ mCurrentFunction->getReturnType().isPrecise())
+ {
+ mInfo->preciseReturnNodes.insert(node);
+ }
+
+ return true;
+ }
+
+ bool visitGlobalQualifierDeclaration(Visit visit,
+ TIntermGlobalQualifierDeclaration *node) override
+ {
+ if (node->isPrecise())
+ {
+ ObjectAndAccessChain preciseObject = {&node->getSymbol()->variable(), {}};
+ AddPreciseObject(mInfo, preciseObject);
+ }
+
+ return false;
+ }
+
+ private:
+ void visitLvalue(TIntermOperator *assignmentNode, TIntermTyped *lvalueNode)
+ {
+ AccessChain lvalueChain;
+ const TVariable *lvalueBase = lvalueChain.build(lvalueNode);
+ mInfo->variableAssignmentNodeMap[lvalueBase].push_back(assignmentNode);
+
+ ObjectAndAccessChain lvalue = {lvalueBase, lvalueChain};
+ AddObjectIfPrecise(mInfo, lvalue);
+
+ TraverseIndexNodesOnly(lvalueNode, this);
+ }
+
+ ASTInfo *mInfo = nullptr;
+ const TFunction *mCurrentFunction = nullptr;
+};
+
+// A traverser that, given an access chain, traverses an expression and marks parts of it |precise|.
+// For example, in the expression |Struct1(a, Struct2(b, c), d)|:
+//
+// - Given access chain [1], both |b| and |c| are marked precise.
+// - Given access chain [1, 0], only |b| is marked precise.
+//
+// When access chain is empty, arithmetic nodes are marked |precise| and any access chains found in
+// their children is recursively added for processing.
+//
+// The access chain given to the traverser is derived from the left hand side of an assignment,
+// while the traverser is run on the right hand side.
+class PropagatePreciseTraverser : public TIntermTraverser
+{
+ public:
+ PropagatePreciseTraverser(ASTInfo *info) : TIntermTraverser(true, false, false), mInfo(info) {}
+
+ void propagatePrecise(TIntermNode *expression, const AccessChain &accessChain)
+ {
+ mCurrentAccessChain = accessChain;
+ expression->traverse(this);
+ }
+
+ bool visitUnary(Visit visit, TIntermUnary *node) override
+ {
+ // Unary operations cannot be applied to structures.
+ ASSERT(mCurrentAccessChain.getChain().empty());
+
+ // Mark arithmetic nodes as |precise|.
+ if (IsArithmeticOp(node->getOp()))
+ {
+ node->setIsPrecise();
+ }
+
+ // Mark the operand itself |precise| too.
+ return true;
+ }
+
+ bool visitBinary(Visit visit, TIntermBinary *node) override
+ {
+ if (IsIndexOp(node->getOp()))
+ {
+ // Append the remaining access chain with that of the node, and mark that as |precise|.
+ // For example, if we are evaluating an expression and expecting to mark the access
+ // chain [1, 3] as |precise|, and the node itself has access chain [0, 2] applied to
+ // variable V, then what ends up being |precise| is V with access chain [0, 2, 1, 3].
+ AccessChain nodeAccessChain;
+ const TVariable *baseVariable = nodeAccessChain.build(node);
+ nodeAccessChain.append(mCurrentAccessChain);
+
+ ObjectAndAccessChain preciseObject = {baseVariable, nodeAccessChain};
+ AddPreciseObject(mInfo, preciseObject);
+
+ // Visit index nodes, each of which should be considered |precise| in its entirety.
+ mCurrentAccessChain.clear();
+ TraverseIndexNodesOnly(node, this);
+
+ return false;
+ }
+
+ if (node->getOp() == EOpComma)
+ {
+ // For expr1,expr2, consider only expr2 as that's the one whose calculation is relevant.
+ node->getRight()->traverse(this);
+ return false;
+ }
+
+ // Mark arithmetic nodes as |precise|.
+ if (IsArithmeticOp(node->getOp()))
+ {
+ node->setIsPrecise();
+ }
+
+ if (IsAssignment(node->getOp()) || node->getOp() == EOpInitialize)
+ {
+ // If the node itself is a[...] op= expr, consider only expr as |precise|, as that's the
+ // one whose calculation is significant.
+ node->getRight()->traverse(this);
+
+ // The indices used on the left hand side are also significant in their entirety.
+ mCurrentAccessChain.clear();
+ TraverseIndexNodesOnly(node->getLeft(), this);
+
+ return false;
+ }
+
+ // Binary operations cannot be applied to structures.
+ ASSERT(mCurrentAccessChain.getChain().empty());
+
+ // Mark the operands themselves |precise| too.
+ return true;
+ }
+
+ void visitSymbol(TIntermSymbol *symbol) override
+ {
+ // Mark the symbol together with the current access chain as |precise|.
+ ObjectAndAccessChain preciseObject = {&symbol->variable(), mCurrentAccessChain};
+ AddPreciseObject(mInfo, preciseObject);
+ }
+
+ bool visitAggregate(Visit visit, TIntermAggregate *node) override
+ {
+ // If this is a struct constructor and the access chain is not empty, only apply |precise|
+ // to the field selected by the access chain.
+ const TType &type = node->getType();
+ const bool isStructConstructor =
+ node->getOp() == EOpConstruct && type.getStruct() != nullptr && !type.isArray();
+
+ if (!mCurrentAccessChain.getChain().empty() && isStructConstructor)
+ {
+ size_t selectedFieldIndex = mCurrentAccessChain.getChain().front();
+ mCurrentAccessChain.pop_front(1);
+
+ ASSERT(selectedFieldIndex < node->getChildCount());
+
+ // Visit only said field.
+ node->getChildNode(selectedFieldIndex)->traverse(this);
+ return false;
+ }
+
+ // If this is an array constructor, each element is equally |precise| with the same access
+ // chain. Otherwise there cannot be any access chain for constructors.
+ if (node->getOp() == EOpConstruct)
+ {
+ ASSERT(type.isArray() || mCurrentAccessChain.getChain().empty());
+ return true;
+ }
+
+ // Otherwise this is a function call. The access chain is irrelevant and every (non-out)
+ // parameter of the function call should be considered |precise|.
+ mCurrentAccessChain.clear();
+
+ const TFunction *function = node->getFunction();
+ ASSERT(function);
+
+ for (size_t paramIndex = 0; paramIndex < function->getParamCount(); ++paramIndex)
+ {
+ if (function->getParam(paramIndex)->getType().getQualifier() != EvqParamOut)
+ {
+ node->getChildNode(paramIndex)->traverse(this);
+ }
+ }
+
+ // Mark arithmetic nodes as |precise|.
+ if (IsArithmeticOp(node->getOp()))
+ {
+ node->setIsPrecise();
+ }
+
+ return false;
+ }
+
+ private:
+ ASTInfo *mInfo = nullptr;
+ AccessChain mCurrentAccessChain;
+};
+} // anonymous namespace
+
+void FindPreciseNodes(TCompiler *compiler, TIntermBlock *root)
+{
+ ASTInfo info;
+
+ InfoGatherTraverser infoGather(&info);
+ root->traverse(&infoGather);
+
+ PropagatePreciseTraverser propagator(&info);
+
+ // First, get return expressions out of the way by propagating |precise|.
+ for (TIntermBranch *returnNode : info.preciseReturnNodes)
+ {
+ ASSERT(returnNode->getChildCount() == 1);
+ propagator.propagatePrecise(returnNode->getChildNode(0), {});
+ }
+
+ // Now take |precise| access chains one by one, and propagate their |precise|-ness to the right
+ // hand side of all assignments in which they are on the left hand side, as well as the
+ // arithmetic expression that assigns to them.
+
+ while (!info.preciseObjectsToProcess.empty())
+ {
+ // Get one |precise| object to process.
+ auto first = info.preciseObjectsToProcess.begin();
+ const ObjectAndAccessChain toProcess = *first;
+ info.preciseObjectsToProcess.erase(first);
+
+ // Propagate |precise| to every node where it's assigned to.
+ const TVector<TIntermOperator *> &assignmentNodes =
+ info.variableAssignmentNodeMap[toProcess.variable];
+ for (TIntermOperator *assignmentNode : assignmentNodes)
+ {
+ AccessChain assignmentAccessChain = GetAssignmentAccessChain(assignmentNode);
+
+ // There are two possibilities:
+ //
+ // - The assignment is to a bigger access chain than that which is being processed, in
+ // which case the entire right hand side is marked |precise|,
+ // - The assignment is to a smaller access chain, in which case only the subobject of
+ // the right hand side that corresponds to the remaining part of the access chain must
+ // be marked |precise|.
+ //
+ // For example, if processing |a.b.c| as a |precise| access chain:
+ //
+ // - If the assignment is to |a.b.c.d|, then the entire right hand side must be
+ // |precise|.
+ // - If the assignment is to |a.b|, only the |.c| part of the right hand side expression
+ // must be |precise|.
+ // - If the assignment is to |a.e|, there is nothing to do.
+ //
+ AccessChain remainingAccessChain = toProcess.accessChain;
+ if (!remainingAccessChain.removePrefix(assignmentAccessChain))
+ {
+ continue;
+ }
+
+ propagator.propagatePrecise(assignmentNode, remainingAccessChain);
+ }
+ }
+
+ // The AST nodes now contain information gathered by this post-processing step, and so the tree
+ // must no longer be transformed.
+ compiler->enableValidateNoMoreTransformations();
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/FindPreciseNodes.h b/gfx/angle/checkout/src/compiler/translator/tree_util/FindPreciseNodes.h
new file mode 100644
index 0000000000..1992ff15af
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/FindPreciseNodes.h
@@ -0,0 +1,25 @@
+//
+// Copyright 2021 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.
+//
+// FindPreciseNodes.h: Propagates |precise| to AST nodes. In SPIR-V, the corresponding decoration
+// (NoContraction) is applied on the intermediate result of operations that affect the |precise|
+// variables, not the variables themselves.
+
+#ifndef COMPILER_TRANSLATOR_TREEUTIL_FINDPRECISENODES_H_
+#define COMPILER_TRANSLATOR_TREEUTIL_FINDPRECISENODES_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermBlock;
+
+void FindPreciseNodes(TCompiler *compiler, TIntermBlock *root);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEUTIL_FINDPRECISENODES_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/FindSymbolNode.cpp b/gfx/angle/checkout/src/compiler/translator/tree_util/FindSymbolNode.cpp
new file mode 100644
index 0000000000..2951399390
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/FindSymbolNode.cpp
@@ -0,0 +1,53 @@
+//
+// 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.
+//
+// FindSymbol.cpp:
+// Utility for finding a symbol node inside an AST tree.
+
+#include "compiler/translator/tree_util/FindSymbolNode.h"
+
+#include "compiler/translator/ImmutableString.h"
+#include "compiler/translator/Symbol.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class SymbolFinder : public TIntermTraverser
+{
+ public:
+ SymbolFinder(const ImmutableString &symbolName)
+ : TIntermTraverser(true, false, false), mSymbolName(symbolName), mNodeFound(nullptr)
+ {}
+
+ void visitSymbol(TIntermSymbol *node) override
+ {
+ if (node->variable().symbolType() != SymbolType::Empty && node->getName() == mSymbolName)
+ {
+ mNodeFound = node;
+ }
+ }
+
+ bool isFound() const { return mNodeFound != nullptr; }
+ const TIntermSymbol *getNode() const { return mNodeFound; }
+
+ private:
+ ImmutableString mSymbolName;
+ TIntermSymbol *mNodeFound;
+};
+
+} // anonymous namespace
+
+const TIntermSymbol *FindSymbolNode(TIntermNode *root, const ImmutableString &symbolName)
+{
+ SymbolFinder finder(symbolName);
+ root->traverse(&finder);
+ return finder.getNode();
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/FindSymbolNode.h b/gfx/angle/checkout/src/compiler/translator/tree_util/FindSymbolNode.h
new file mode 100644
index 0000000000..09349484a4
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/FindSymbolNode.h
@@ -0,0 +1,23 @@
+//
+// 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.
+//
+// FindSymbolNode.h:
+// Utility for finding a symbol node inside an AST tree.
+
+#ifndef COMPILER_TRANSLATOR_TREEUTIL_FINDSYMBOLNODE_H_
+#define COMPILER_TRANSLATOR_TREEUTIL_FINDSYMBOLNODE_H_
+
+namespace sh
+{
+
+class ImmutableString;
+class TIntermNode;
+class TIntermSymbol;
+
+const TIntermSymbol *FindSymbolNode(TIntermNode *root, const ImmutableString &symbolName);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEUTIL_FINDSYMBOLNODE_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/IntermNodePatternMatcher.cpp b/gfx/angle/checkout/src/compiler/translator/tree_util/IntermNodePatternMatcher.cpp
new file mode 100644
index 0000000000..59241bcf7a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/IntermNodePatternMatcher.cpp
@@ -0,0 +1,213 @@
+//
+// 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.
+//
+// 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/tree_util/IntermNodePatternMatcher.h"
+
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+namespace
+{
+
+bool ContainsMatrixNode(const TIntermSequence &sequence)
+{
+ for (size_t ii = 0; ii < sequence.size(); ++ii)
+ {
+ TIntermTyped *node = sequence[ii]->getAsTyped();
+ if (node && node->isMatrix())
+ return true;
+ }
+ return false;
+}
+
+bool ContainsVectorNode(const TIntermSequence &sequence)
+{
+ for (size_t ii = 0; ii < sequence.size(); ++ii)
+ {
+ TIntermTyped *node = sequence[ii]->getAsTyped();
+ if (node && node->isVector())
+ return true;
+ }
+ return false;
+}
+
+} // anonymous namespace
+
+IntermNodePatternMatcher::IntermNodePatternMatcher(const unsigned int mask) : mMask(mask) {}
+
+// static
+bool IntermNodePatternMatcher::IsDynamicIndexingOfNonSSBOVectorOrMatrix(TIntermBinary *node)
+{
+ return IsDynamicIndexingOfVectorOrMatrix(node) && !IsInShaderStorageBlock(node->getLeft());
+}
+
+// static
+bool IntermNodePatternMatcher::IsDynamicIndexingOfVectorOrMatrix(TIntermBinary *node)
+{
+ return node->getOp() == EOpIndexIndirect && !node->getLeft()->isArray() &&
+ node->getLeft()->getBasicType() != EbtStruct;
+}
+
+// static
+bool IntermNodePatternMatcher::IsDynamicIndexingOfSwizzledVector(TIntermBinary *node)
+{
+ return IsDynamicIndexingOfVectorOrMatrix(node) && node->getLeft()->getAsSwizzleNode();
+}
+
+bool IntermNodePatternMatcher::matchInternal(TIntermBinary *node, TIntermNode *parentNode) const
+{
+ if ((mMask & kExpressionReturningArray) != 0)
+ {
+ if (node->isArray() && node->getOp() == EOpAssign && parentNode != nullptr &&
+ !parentNode->getAsBlock())
+ {
+ return true;
+ }
+ }
+
+ if ((mMask & kUnfoldedShortCircuitExpression) != 0)
+ {
+ if (node->getRight()->hasSideEffects() &&
+ (node->getOp() == EOpLogicalOr || node->getOp() == EOpLogicalAnd))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool IntermNodePatternMatcher::match(TIntermUnary *node) const
+{
+ if ((mMask & kArrayLengthMethod) != 0)
+ {
+ if (node->getOp() == EOpArrayLength)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool IntermNodePatternMatcher::match(TIntermBinary *node, TIntermNode *parentNode) const
+{
+ // 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) const
+{
+ 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) const
+{
+ 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->isFunctionCall() ||
+ (BuiltInGroup::IsBuiltIn(node->getOp()) &&
+ !BuiltInGroup::IsMath(node->getOp()))) &&
+ !parentNode->getAsBlock())
+ {
+ return true;
+ }
+ }
+ }
+ if ((mMask & kScalarizedVecOrMatConstructor) != 0)
+ {
+ if (node->getOp() == EOpConstruct)
+ {
+ if (node->getType().isVector() && ContainsMatrixNode(*(node->getSequence())))
+ {
+ return true;
+ }
+ else if (node->getType().isMatrix() && ContainsVectorNode(*(node->getSequence())))
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool IntermNodePatternMatcher::match(TIntermTernary *node) const
+{
+ if ((mMask & kUnfoldedShortCircuitExpression) != 0)
+ {
+ return true;
+ }
+ return false;
+}
+
+bool IntermNodePatternMatcher::match(TIntermDeclaration *node) const
+{
+ if ((mMask & kMultiDeclaration) != 0)
+ {
+ if (node->getSequence()->size() > 1)
+ {
+ return true;
+ }
+ }
+ if ((mMask & kArrayDeclaration) != 0)
+ {
+ if (node->getSequence()->front()->getAsTyped()->getType().isStructureContainingArrays())
+ {
+ return true;
+ }
+ // Need to check from all declarators whether they are arrays since that may vary between
+ // declarators.
+ for (TIntermNode *declarator : *node->getSequence())
+ {
+ if (declarator->getAsTyped()->isArray())
+ {
+ return true;
+ }
+ }
+ }
+ if ((mMask & kNamelessStructDeclaration) != 0)
+ {
+ TIntermTyped *declarator = node->getSequence()->front()->getAsTyped();
+ if (declarator->getBasicType() == EbtStruct &&
+ declarator->getType().getStruct()->symbolType() == SymbolType::Empty)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/IntermNodePatternMatcher.h b/gfx/angle/checkout/src/compiler/translator/tree_util/IntermNodePatternMatcher.h
new file mode 100644
index 0000000000..b8321b930c
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/IntermNodePatternMatcher.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.
+//
+// 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_TREEUTIL_INTERMNODEPATTERNMATCHER_H_
+#define COMPILER_TRANSLATOR_TREEUTIL_INTERMNODEPATTERNMATCHER_H_
+
+namespace sh
+{
+
+class TIntermAggregate;
+class TIntermBinary;
+class TIntermDeclaration;
+class TIntermNode;
+class TIntermTernary;
+class TIntermUnary;
+
+class IntermNodePatternMatcher
+{
+ public:
+ static bool IsDynamicIndexingOfNonSSBOVectorOrMatrix(TIntermBinary *node);
+ static bool IsDynamicIndexingOfVectorOrMatrix(TIntermBinary *node);
+ static bool IsDynamicIndexingOfSwizzledVector(TIntermBinary *node);
+
+ enum PatternType : unsigned int
+ {
+ // Matches expressions that are unfolded to if statements by UnfoldShortCircuitToIf
+ kUnfoldedShortCircuitExpression = 1u << 0u,
+
+ // Matches expressions that return arrays with the exception of simple statements where a
+ // constructor or function call result is assigned.
+ kExpressionReturningArray = 1u << 1u,
+
+ // Matches dynamic indexing of vectors or matrices in l-values.
+ kDynamicIndexingOfVectorOrMatrixInLValue = 1u << 2u,
+
+ // Matches declarations with more than one declared variables.
+ kMultiDeclaration = 1u << 3u,
+
+ // Matches declarations of arrays.
+ kArrayDeclaration = 1u << 4u,
+
+ // Matches declarations of structs where the struct type does not have a name.
+ kNamelessStructDeclaration = 1u << 5u,
+
+ // Matches array length() method.
+ kArrayLengthMethod = 1u << 6u,
+
+ // Matches a vector or matrix constructor whose arguments are scalarized by the
+ // scalarizeVecOrMatConstructorArguments workaround.
+ kScalarizedVecOrMatConstructor = 1u << 7u,
+ };
+ IntermNodePatternMatcher(const unsigned int mask);
+
+ bool match(TIntermUnary *node) const;
+
+ bool match(TIntermBinary *node, TIntermNode *parentNode) const;
+
+ // Use this version for checking binary node matches in case you're using flag
+ // kDynamicIndexingOfVectorOrMatrixInLValue.
+ bool match(TIntermBinary *node, TIntermNode *parentNode, bool isLValueRequiredHere) const;
+
+ bool match(TIntermAggregate *node, TIntermNode *parentNode) const;
+ bool match(TIntermTernary *node) const;
+ bool match(TIntermDeclaration *node) const;
+
+ private:
+ const unsigned int mMask;
+
+ bool matchInternal(TIntermBinary *node, TIntermNode *parentNode) const;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEUTIL_INTERMNODEPATTERNMATCHER_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/IntermNode_util.cpp b/gfx/angle/checkout/src/compiler/translator/tree_util/IntermNode_util.cpp
new file mode 100644
index 0000000000..a7bb211425
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/IntermNode_util.cpp
@@ -0,0 +1,436 @@
+//
+// Copyright 2017 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.
+//
+// IntermNode_util.cpp: High-level utilities for creating AST nodes and node hierarchies. Mostly
+// meant to be used in AST transforms.
+
+#include "compiler/translator/tree_util/IntermNode_util.h"
+
+#include "compiler/translator/FunctionLookup.h"
+#include "compiler/translator/SymbolTable.h"
+
+namespace sh
+{
+
+namespace
+{
+
+const TFunction *LookUpBuiltInFunction(const char *name,
+ const TIntermSequence *arguments,
+ const TSymbolTable &symbolTable,
+ int shaderVersion)
+{
+ const ImmutableString &mangledName = TFunctionLookup::GetMangledName(name, *arguments);
+ const TSymbol *symbol = symbolTable.findBuiltIn(mangledName, shaderVersion);
+ if (symbol)
+ {
+ ASSERT(symbol->isFunction());
+ return static_cast<const TFunction *>(symbol);
+ }
+ return nullptr;
+}
+
+} // anonymous namespace
+
+TIntermFunctionPrototype *CreateInternalFunctionPrototypeNode(const TFunction &func)
+{
+ return new TIntermFunctionPrototype(&func);
+}
+
+TIntermFunctionDefinition *CreateInternalFunctionDefinitionNode(const TFunction &func,
+ TIntermBlock *functionBody)
+{
+ return new TIntermFunctionDefinition(new TIntermFunctionPrototype(&func), functionBody);
+}
+
+TIntermTyped *CreateZeroNode(const TType &type)
+{
+ TType constType(type);
+ constType.setQualifier(EvqConst);
+
+ if (!type.isArray() && type.getBasicType() != EbtStruct)
+ {
+ 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:
+ // CreateZeroNode is called by ParseContext that keeps parsing even when an
+ // error occurs, so it is possible for CreateZeroNode to be called with
+ // non-basic types. This happens only on error condition but CreateZeroNode
+ // needs to return a value with the correct type to continue the type check.
+ // That's why we handle non-basic type by setting whatever value, we just need
+ // the type to be right.
+ u[i].setIConst(42);
+ break;
+ }
+ }
+
+ TIntermConstantUnion *node = new TIntermConstantUnion(u, constType);
+ return node;
+ }
+
+ TIntermSequence arguments;
+
+ if (type.isArray())
+ {
+ TType elementType(type);
+ elementType.toArrayElementType();
+
+ size_t arraySize = type.getOutermostArraySize();
+ for (size_t i = 0; i < arraySize; ++i)
+ {
+ arguments.push_back(CreateZeroNode(elementType));
+ }
+ }
+ else
+ {
+ ASSERT(type.getBasicType() == EbtStruct);
+
+ const TStructure *structure = type.getStruct();
+ for (const auto &field : structure->fields())
+ {
+ arguments.push_back(CreateZeroNode(*field->type()));
+ }
+ }
+
+ return TIntermAggregate::CreateConstructor(constType, &arguments);
+}
+
+TIntermConstantUnion *CreateFloatNode(float value, TPrecision precision)
+{
+ TConstantUnion *u = new TConstantUnion[1];
+ u[0].setFConst(value);
+
+ TType type(EbtFloat, precision, EvqConst, 1);
+ return new TIntermConstantUnion(u, type);
+}
+
+TIntermConstantUnion *CreateVecNode(const float values[],
+ unsigned int vecSize,
+ TPrecision precision)
+{
+ TConstantUnion *u = new TConstantUnion[vecSize];
+ for (unsigned int channel = 0; channel < vecSize; ++channel)
+ {
+ u[channel].setFConst(values[channel]);
+ }
+
+ TType type(EbtFloat, precision, EvqConst, static_cast<uint8_t>(vecSize));
+ return new TIntermConstantUnion(u, type);
+}
+
+TIntermConstantUnion *CreateUVecNode(const unsigned int values[],
+ unsigned int vecSize,
+ TPrecision precision)
+{
+ TConstantUnion *u = new TConstantUnion[vecSize];
+ for (unsigned int channel = 0; channel < vecSize; ++channel)
+ {
+ u[channel].setUConst(values[channel]);
+ }
+
+ TType type(EbtUInt, precision, EvqConst, static_cast<uint8_t>(vecSize));
+ return new TIntermConstantUnion(u, type);
+}
+
+TIntermConstantUnion *CreateIndexNode(int index)
+{
+ TConstantUnion *u = new TConstantUnion[1];
+ u[0].setIConst(index);
+
+ TType type(EbtInt, EbpHigh, EvqConst, 1);
+ return new TIntermConstantUnion(u, type);
+}
+
+TIntermConstantUnion *CreateUIntNode(unsigned int value)
+{
+ TConstantUnion *u = new TConstantUnion[1];
+ u[0].setUConst(value);
+
+ TType type(EbtUInt, EbpHigh, EvqConst, 1);
+ return new TIntermConstantUnion(u, type);
+}
+
+TIntermConstantUnion *CreateBoolNode(bool value)
+{
+ TConstantUnion *u = new TConstantUnion[1];
+ u[0].setBConst(value);
+
+ TType type(EbtBool, EbpUndefined, EvqConst, 1);
+ return new TIntermConstantUnion(u, type);
+}
+
+TVariable *CreateTempVariable(TSymbolTable *symbolTable, const TType *type)
+{
+ ASSERT(symbolTable != nullptr);
+ // TODO(oetuaho): Might be useful to sanitize layout qualifier etc. on the type of the created
+ // variable. This might need to be done in other places as well.
+ return new TVariable(symbolTable, kEmptyImmutableString, type, SymbolType::AngleInternal);
+}
+
+TVariable *CreateTempVariable(TSymbolTable *symbolTable, const TType *type, TQualifier qualifier)
+{
+ ASSERT(symbolTable != nullptr);
+ if (type->getQualifier() == qualifier)
+ {
+ return CreateTempVariable(symbolTable, type);
+ }
+ TType *typeWithQualifier = new TType(*type);
+ typeWithQualifier->setQualifier(qualifier);
+ return CreateTempVariable(symbolTable, typeWithQualifier);
+}
+
+TIntermSymbol *CreateTempSymbolNode(const TVariable *tempVariable)
+{
+ ASSERT(tempVariable->symbolType() == SymbolType::AngleInternal);
+ ASSERT(tempVariable->getType().getQualifier() == EvqTemporary ||
+ tempVariable->getType().getQualifier() == EvqConst ||
+ tempVariable->getType().getQualifier() == EvqGlobal);
+ return new TIntermSymbol(tempVariable);
+}
+
+TIntermDeclaration *CreateTempDeclarationNode(const TVariable *tempVariable)
+{
+ TIntermDeclaration *tempDeclaration = new TIntermDeclaration();
+ tempDeclaration->appendDeclarator(CreateTempSymbolNode(tempVariable));
+ return tempDeclaration;
+}
+
+TIntermDeclaration *CreateTempInitDeclarationNode(const TVariable *tempVariable,
+ TIntermTyped *initializer)
+{
+ ASSERT(initializer != nullptr);
+ TIntermSymbol *tempSymbol = CreateTempSymbolNode(tempVariable);
+ TIntermDeclaration *tempDeclaration = new TIntermDeclaration();
+ TIntermBinary *tempInit = new TIntermBinary(EOpInitialize, tempSymbol, initializer);
+ tempDeclaration->appendDeclarator(tempInit);
+ return tempDeclaration;
+}
+
+TIntermBinary *CreateTempAssignmentNode(const TVariable *tempVariable, TIntermTyped *rightNode)
+{
+ ASSERT(rightNode != nullptr);
+ TIntermSymbol *tempSymbol = CreateTempSymbolNode(tempVariable);
+ return new TIntermBinary(EOpAssign, tempSymbol, rightNode);
+}
+
+TVariable *DeclareTempVariable(TSymbolTable *symbolTable,
+ const TType *type,
+ TQualifier qualifier,
+ TIntermDeclaration **declarationOut)
+{
+ TVariable *variable = CreateTempVariable(symbolTable, type, qualifier);
+ *declarationOut = CreateTempDeclarationNode(variable);
+ return variable;
+}
+
+TVariable *DeclareTempVariable(TSymbolTable *symbolTable,
+ TIntermTyped *initializer,
+ TQualifier qualifier,
+ TIntermDeclaration **declarationOut)
+{
+ TVariable *variable =
+ CreateTempVariable(symbolTable, new TType(initializer->getType()), qualifier);
+ *declarationOut = CreateTempInitDeclarationNode(variable, initializer);
+ return variable;
+}
+
+std::pair<const TVariable *, const TVariable *> DeclareStructure(
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ TFieldList *fieldList,
+ TQualifier qualifier,
+ const TMemoryQualifier &memoryQualifier,
+ uint32_t arraySize,
+ const ImmutableString &structTypeName,
+ const ImmutableString *structInstanceName)
+{
+ TStructure *structure =
+ new TStructure(symbolTable, structTypeName, fieldList, SymbolType::AngleInternal);
+
+ auto makeStructureType = [&](bool isStructSpecifier) {
+ TType *structureType = new TType(structure, isStructSpecifier);
+ structureType->setQualifier(qualifier);
+ structureType->setMemoryQualifier(memoryQualifier);
+ if (arraySize > 0)
+ {
+ structureType->makeArray(arraySize);
+ }
+ return structureType;
+ };
+
+ TIntermSequence insertSequence;
+
+ TVariable *typeVar = new TVariable(symbolTable, kEmptyImmutableString, makeStructureType(true),
+ SymbolType::Empty);
+ insertSequence.push_back(new TIntermDeclaration{typeVar});
+
+ TVariable *instanceVar = nullptr;
+ if (structInstanceName)
+ {
+ instanceVar = new TVariable(symbolTable, *structInstanceName, makeStructureType(false),
+ SymbolType::AngleInternal);
+ insertSequence.push_back(new TIntermDeclaration{instanceVar});
+ }
+
+ size_t firstFunctionIndex = FindFirstFunctionDefinitionIndex(root);
+ root->insertChildNodes(firstFunctionIndex, insertSequence);
+
+ return {typeVar, instanceVar};
+}
+
+const TVariable *DeclareInterfaceBlock(TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ TFieldList *fieldList,
+ TQualifier qualifier,
+ const TLayoutQualifier &layoutQualifier,
+ const TMemoryQualifier &memoryQualifier,
+ uint32_t arraySize,
+ const ImmutableString &blockTypeName,
+ const ImmutableString &blockVariableName)
+{
+ // Define an interface block.
+ TInterfaceBlock *interfaceBlock = new TInterfaceBlock(
+ symbolTable, blockTypeName, fieldList, layoutQualifier, SymbolType::AngleInternal);
+
+ // Turn the inteface block into a declaration.
+ TType *interfaceBlockType = new TType(interfaceBlock, qualifier, layoutQualifier);
+ interfaceBlockType->setMemoryQualifier(memoryQualifier);
+ if (arraySize > 0)
+ {
+ interfaceBlockType->makeArray(arraySize);
+ }
+
+ TIntermDeclaration *interfaceBlockDecl = new TIntermDeclaration;
+ TVariable *interfaceBlockVar =
+ new TVariable(symbolTable, blockVariableName, interfaceBlockType,
+ blockVariableName.empty() ? SymbolType::Empty : SymbolType::AngleInternal);
+ TIntermSymbol *interfaceBlockDeclarator = new TIntermSymbol(interfaceBlockVar);
+ interfaceBlockDecl->appendDeclarator(interfaceBlockDeclarator);
+
+ // Insert the declarations before the first function.
+ TIntermSequence insertSequence;
+ insertSequence.push_back(interfaceBlockDecl);
+
+ size_t firstFunctionIndex = FindFirstFunctionDefinitionIndex(root);
+ root->insertChildNodes(firstFunctionIndex, insertSequence);
+
+ return interfaceBlockVar;
+}
+
+TIntermBlock *EnsureBlock(TIntermNode *node)
+{
+ if (node == nullptr)
+ return nullptr;
+ TIntermBlock *blockNode = node->getAsBlock();
+ if (blockNode != nullptr)
+ return blockNode;
+
+ blockNode = new TIntermBlock();
+ blockNode->setLine(node->getLine());
+ blockNode->appendStatement(node);
+ return blockNode;
+}
+
+TIntermSymbol *ReferenceGlobalVariable(const ImmutableString &name, const TSymbolTable &symbolTable)
+{
+ const TSymbol *symbol = symbolTable.findGlobal(name);
+ ASSERT(symbol && symbol->isVariable());
+ return new TIntermSymbol(static_cast<const TVariable *>(symbol));
+}
+
+TIntermSymbol *ReferenceBuiltInVariable(const ImmutableString &name,
+ const TSymbolTable &symbolTable,
+ int shaderVersion)
+{
+ const TVariable *var =
+ static_cast<const TVariable *>(symbolTable.findBuiltIn(name, shaderVersion));
+ ASSERT(var);
+ return new TIntermSymbol(var);
+}
+
+TIntermTyped *CreateBuiltInFunctionCallNode(const char *name,
+ TIntermSequence *arguments,
+ const TSymbolTable &symbolTable,
+ int shaderVersion)
+{
+ const TFunction *fn = LookUpBuiltInFunction(name, arguments, symbolTable, shaderVersion);
+ ASSERT(fn);
+ TOperator op = fn->getBuiltInOp();
+ if (BuiltInGroup::IsMath(op) && arguments->size() == 1)
+ {
+ return new TIntermUnary(op, arguments->at(0)->getAsTyped(), fn);
+ }
+ return TIntermAggregate::CreateBuiltInFunctionCall(*fn, arguments);
+}
+
+TIntermTyped *CreateBuiltInFunctionCallNode(const char *name,
+ const std::initializer_list<TIntermNode *> &arguments,
+ const TSymbolTable &symbolTable,
+ int shaderVersion)
+{
+ TIntermSequence argSequence(arguments);
+ return CreateBuiltInFunctionCallNode(name, &argSequence, symbolTable, shaderVersion);
+}
+
+TIntermTyped *CreateBuiltInUnaryFunctionCallNode(const char *name,
+ TIntermTyped *argument,
+ const TSymbolTable &symbolTable,
+ int shaderVersion)
+{
+ return CreateBuiltInFunctionCallNode(name, {argument}, symbolTable, shaderVersion);
+}
+
+int GetESSLOrGLSLVersion(ShShaderSpec spec, int esslVersion, int glslVersion)
+{
+ return IsDesktopGLSpec(spec) ? glslVersion : esslVersion;
+}
+
+// Returns true if a block ends in a branch (break, continue, return, etc). This is only correct
+// after PruneNoOps, because it expects empty blocks after a branch to have been already pruned,
+// i.e. a block can only end in a branch if its last statement is a branch or is a block ending in
+// branch.
+bool EndsInBranch(TIntermBlock *block)
+{
+ while (block != nullptr)
+ {
+ // Get the last statement of the block.
+ TIntermSequence &statements = *block->getSequence();
+ if (statements.empty())
+ {
+ return false;
+ }
+
+ TIntermNode *lastStatement = statements.back();
+
+ // If it's a branch itself, we have the answer.
+ if (lastStatement->getAsBranchNode())
+ {
+ return true;
+ }
+
+ // Otherwise, see if it's a block that ends in a branch
+ block = lastStatement->getAsBlock();
+ }
+
+ return false;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/IntermNode_util.h b/gfx/angle/checkout/src/compiler/translator/tree_util/IntermNode_util.h
new file mode 100644
index 0000000000..5cf0a117d3
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/IntermNode_util.h
@@ -0,0 +1,128 @@
+//
+// Copyright 2017 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.
+//
+// IntermNode_util.h: High-level utilities for creating AST nodes and node hierarchies. Mostly meant
+// to be used in AST transforms.
+
+#ifndef COMPILER_TRANSLATOR_INTERMNODEUTIL_H_
+#define COMPILER_TRANSLATOR_INTERMNODEUTIL_H_
+
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/tree_util/FindFunction.h"
+
+namespace sh
+{
+
+class TSymbolTable;
+class TVariable;
+
+TIntermFunctionPrototype *CreateInternalFunctionPrototypeNode(const TFunction &func);
+TIntermFunctionDefinition *CreateInternalFunctionDefinitionNode(const TFunction &func,
+ TIntermBlock *functionBody);
+
+TIntermTyped *CreateZeroNode(const TType &type);
+TIntermConstantUnion *CreateFloatNode(float value, TPrecision precision);
+TIntermConstantUnion *CreateVecNode(const float values[],
+ unsigned int vecSize,
+ TPrecision precision);
+TIntermConstantUnion *CreateUVecNode(const unsigned int values[],
+ unsigned int vecSize,
+ TPrecision precision);
+TIntermConstantUnion *CreateIndexNode(int index);
+TIntermConstantUnion *CreateUIntNode(unsigned int value);
+TIntermConstantUnion *CreateBoolNode(bool value);
+
+TVariable *CreateTempVariable(TSymbolTable *symbolTable, const TType *type);
+TVariable *CreateTempVariable(TSymbolTable *symbolTable, const TType *type, TQualifier qualifier);
+
+TIntermSymbol *CreateTempSymbolNode(const TVariable *tempVariable);
+TIntermDeclaration *CreateTempDeclarationNode(const TVariable *tempVariable);
+TIntermDeclaration *CreateTempInitDeclarationNode(const TVariable *tempVariable,
+ TIntermTyped *initializer);
+TIntermBinary *CreateTempAssignmentNode(const TVariable *tempVariable, TIntermTyped *rightNode);
+
+TVariable *DeclareTempVariable(TSymbolTable *symbolTable,
+ const TType *type,
+ TQualifier qualifier,
+ TIntermDeclaration **declarationOut);
+TVariable *DeclareTempVariable(TSymbolTable *symbolTable,
+ TIntermTyped *initializer,
+ TQualifier qualifier,
+ TIntermDeclaration **declarationOut);
+std::pair<const TVariable *, const TVariable *> DeclareStructure(
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ TFieldList *fieldList,
+ TQualifier qualifier,
+ const TMemoryQualifier &memoryQualifier,
+ uint32_t arraySize,
+ const ImmutableString &structTypeName,
+ const ImmutableString *structInstanceName);
+const TVariable *DeclareInterfaceBlock(TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ TFieldList *fieldList,
+ TQualifier qualifier,
+ const TLayoutQualifier &layoutQualifier,
+ const TMemoryQualifier &memoryQualifier,
+ uint32_t arraySize,
+ const ImmutableString &blockTypeName,
+ const ImmutableString &blockVariableName);
+
+// If the input node is nullptr, return nullptr.
+// If the input node is a block node, return it.
+// If the input node is not a block node, put it inside a block node and return that.
+TIntermBlock *EnsureBlock(TIntermNode *node);
+
+// Should be called from inside Compiler::compileTreeImpl() where the global level is in scope.
+TIntermSymbol *ReferenceGlobalVariable(const ImmutableString &name,
+ const TSymbolTable &symbolTable);
+
+// Note: this can't access desktop GLSL built-ins. Those can only be accessed directly through
+// BuiltIn.h.
+TIntermSymbol *ReferenceBuiltInVariable(const ImmutableString &name,
+ const TSymbolTable &symbolTable,
+ int shaderVersion);
+
+TIntermTyped *CreateBuiltInFunctionCallNode(const char *name,
+ TIntermSequence *arguments,
+ const TSymbolTable &symbolTable,
+ int shaderVersion);
+TIntermTyped *CreateBuiltInFunctionCallNode(const char *name,
+ const std::initializer_list<TIntermNode *> &arguments,
+ const TSymbolTable &symbolTable,
+ int shaderVersion);
+TIntermTyped *CreateBuiltInUnaryFunctionCallNode(const char *name,
+ TIntermTyped *argument,
+ const TSymbolTable &symbolTable,
+ int shaderVersion);
+
+int GetESSLOrGLSLVersion(ShShaderSpec spec, int esslVersion, int glslVersion);
+
+inline void GetSwizzleIndex(TVector<int> *indexOut) {}
+
+template <typename T, typename... ArgsT>
+void GetSwizzleIndex(TVector<int> *indexOut, T arg, ArgsT... args)
+{
+ indexOut->push_back(arg);
+ GetSwizzleIndex(indexOut, args...);
+}
+
+template <typename... ArgsT>
+TIntermSwizzle *CreateSwizzle(TIntermTyped *reference, ArgsT... args)
+{
+ TVector<int> swizzleIndex;
+ GetSwizzleIndex(&swizzleIndex, args...);
+ return new TIntermSwizzle(reference, swizzleIndex);
+}
+
+// Returns true if a block ends in a branch (break, continue, return, etc). This is only correct
+// after PruneNoOps, because it expects empty blocks after a branch to have been already pruned,
+// i.e. a block can only end in a branch if its last statement is a branch or is a block ending in
+// branch.
+bool EndsInBranch(TIntermBlock *block);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_INTERMNODEUTIL_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/IntermRebuild.cpp b/gfx/angle/checkout/src/compiler/translator/tree_util/IntermRebuild.cpp
new file mode 100644
index 0000000000..667535fa63
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/IntermRebuild.cpp
@@ -0,0 +1,1046 @@
+//
+// Copyright 2020 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 <algorithm>
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/AsNode.h"
+#include "compiler/translator/tree_util/IntermRebuild.h"
+
+#define GUARD2(cond, failVal) \
+ do \
+ { \
+ if (!(cond)) \
+ { \
+ return failVal; \
+ } \
+ } while (false)
+
+#define GUARD(cond) GUARD2(cond, nullptr)
+
+namespace sh
+{
+
+template <typename T, typename U>
+ANGLE_INLINE bool AllBits(T haystack, U needle)
+{
+ return (haystack & needle) == needle;
+}
+
+template <typename T, typename U>
+ANGLE_INLINE bool AnyBits(T haystack, U needle)
+{
+ return (haystack & needle) != 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+TIntermRebuild::BaseResult::BaseResult(BaseResult &other)
+ : mAction(other.mAction),
+ mVisit(other.mVisit),
+ mSingle(other.mSingle),
+ mMulti(std::move(other.mMulti))
+{}
+
+TIntermRebuild::BaseResult::BaseResult(TIntermNode &node, VisitBits visit)
+ : mAction(Action::ReplaceSingle), mVisit(visit), mSingle(&node)
+{}
+
+TIntermRebuild::BaseResult::BaseResult(TIntermNode *node, VisitBits visit)
+ : mAction(node ? Action::ReplaceSingle : Action::Drop),
+ mVisit(node ? visit : VisitBits::Neither),
+ mSingle(node)
+{}
+
+TIntermRebuild::BaseResult::BaseResult(std::nullptr_t)
+ : mAction(Action::Drop), mVisit(VisitBits::Neither), mSingle(nullptr)
+{}
+
+TIntermRebuild::BaseResult::BaseResult(Fail)
+ : mAction(Action::Fail), mVisit(VisitBits::Neither), mSingle(nullptr)
+{}
+
+TIntermRebuild::BaseResult::BaseResult(std::vector<TIntermNode *> &&nodes)
+ : mAction(Action::ReplaceMulti),
+ mVisit(VisitBits::Neither),
+ mSingle(nullptr),
+ mMulti(std::move(nodes))
+{}
+
+void TIntermRebuild::BaseResult::moveAssignImpl(BaseResult &other)
+{
+ mAction = other.mAction;
+ mVisit = other.mVisit;
+ mSingle = other.mSingle;
+ mMulti = std::move(other.mMulti);
+}
+
+TIntermRebuild::BaseResult TIntermRebuild::BaseResult::Multi(std::vector<TIntermNode *> &&nodes)
+{
+ auto it = std::remove(nodes.begin(), nodes.end(), nullptr);
+ nodes.erase(it, nodes.end());
+ return std::move(nodes);
+}
+
+bool TIntermRebuild::BaseResult::isFail() const
+{
+ return mAction == Action::Fail;
+}
+
+bool TIntermRebuild::BaseResult::isDrop() const
+{
+ return mAction == Action::Drop;
+}
+
+TIntermNode *TIntermRebuild::BaseResult::single() const
+{
+ return mSingle;
+}
+
+const std::vector<TIntermNode *> *TIntermRebuild::BaseResult::multi() const
+{
+ if (mAction == Action::ReplaceMulti)
+ {
+ return &mMulti;
+ }
+ return nullptr;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+using PreResult = TIntermRebuild::PreResult;
+
+PreResult::PreResult(TIntermNode &node, VisitBits visit) : BaseResult(node, visit) {}
+PreResult::PreResult(TIntermNode *node, VisitBits visit) : BaseResult(node, visit) {}
+PreResult::PreResult(std::nullptr_t) : BaseResult(nullptr) {}
+PreResult::PreResult(Fail) : BaseResult(Fail()) {}
+
+PreResult::PreResult(BaseResult &&other) : BaseResult(other) {}
+PreResult::PreResult(PreResult &&other) : BaseResult(other) {}
+
+void PreResult::operator=(PreResult &&other)
+{
+ moveAssignImpl(other);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+using PostResult = TIntermRebuild::PostResult;
+
+PostResult::PostResult(TIntermNode &node) : BaseResult(node, VisitBits::Neither) {}
+PostResult::PostResult(TIntermNode *node) : BaseResult(node, VisitBits::Neither) {}
+PostResult::PostResult(std::nullptr_t) : BaseResult(nullptr) {}
+PostResult::PostResult(Fail) : BaseResult(Fail()) {}
+
+PostResult::PostResult(PostResult &&other) : BaseResult(other) {}
+PostResult::PostResult(BaseResult &&other) : BaseResult(other) {}
+
+void PostResult::operator=(PostResult &&other)
+{
+ moveAssignImpl(other);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+TIntermRebuild::TIntermRebuild(TCompiler &compiler, bool preVisit, bool postVisit)
+ : mCompiler(compiler),
+ mSymbolTable(compiler.getSymbolTable()),
+ mPreVisit(preVisit),
+ mPostVisit(postVisit)
+{
+ ASSERT(preVisit || postVisit);
+}
+
+TIntermRebuild::~TIntermRebuild()
+{
+ ASSERT(!mNodeStack.value);
+ ASSERT(!mNodeStack.tail);
+}
+
+const TFunction *TIntermRebuild::getParentFunction() const
+{
+ return mParentFunc;
+}
+
+TIntermNode *TIntermRebuild::getParentNode(size_t offset) const
+{
+ ASSERT(mNodeStack.tail);
+ auto parent = *mNodeStack.tail;
+ while (offset > 0)
+ {
+ --offset;
+ ASSERT(parent.tail);
+ parent = *parent.tail;
+ }
+ return parent.value;
+}
+
+bool TIntermRebuild::rebuildRoot(TIntermBlock &root)
+{
+ if (!rebuildInPlace(root))
+ {
+ return false;
+ }
+ return mCompiler.validateAST(&root);
+}
+
+bool TIntermRebuild::rebuildInPlace(TIntermAggregate &node)
+{
+ return rebuildInPlaceImpl(node);
+}
+
+bool TIntermRebuild::rebuildInPlace(TIntermBlock &node)
+{
+ return rebuildInPlaceImpl(node);
+}
+
+bool TIntermRebuild::rebuildInPlace(TIntermDeclaration &node)
+{
+ return rebuildInPlaceImpl(node);
+}
+
+template <typename Node>
+bool TIntermRebuild::rebuildInPlaceImpl(Node &node)
+{
+ auto *newNode = traverseAnyAs<Node>(node);
+ if (!newNode)
+ {
+ return false;
+ }
+
+ if (newNode != &node)
+ {
+ *node.getSequence() = std::move(*newNode->getSequence());
+ }
+
+ return true;
+}
+
+PostResult TIntermRebuild::rebuild(TIntermNode &node)
+{
+ return traverseAny(node);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+template <typename Node>
+Node *TIntermRebuild::traverseAnyAs(TIntermNode &node)
+{
+ PostResult result(traverseAny(node));
+ if (result.mAction == Action::Fail || !result.mSingle)
+ {
+ return nullptr;
+ }
+ return asNode<Node>(result.mSingle);
+}
+
+template <typename Node>
+bool TIntermRebuild::traverseAnyAs(TIntermNode &node, Node *&out)
+{
+ PostResult result(traverseAny(node));
+ if (result.mAction == Action::Fail || result.mAction == Action::ReplaceMulti)
+ {
+ return false;
+ }
+ if (!result.mSingle)
+ {
+ return true;
+ }
+ out = asNode<Node>(result.mSingle);
+ return out != nullptr;
+}
+
+bool TIntermRebuild::traverseAggregateBaseChildren(TIntermAggregateBase &node)
+{
+ auto *const children = node.getSequence();
+ ASSERT(children);
+ TIntermSequence newChildren;
+
+ for (TIntermNode *child : *children)
+ {
+ ASSERT(child);
+ PostResult result(traverseAny(*child));
+
+ switch (result.mAction)
+ {
+ case Action::ReplaceSingle:
+ newChildren.push_back(result.mSingle);
+ break;
+
+ case Action::ReplaceMulti:
+ for (TIntermNode *newNode : result.mMulti)
+ {
+ if (newNode)
+ {
+ newChildren.push_back(newNode);
+ }
+ }
+ break;
+
+ case Action::Drop:
+ break;
+
+ case Action::Fail:
+ return false;
+
+ default:
+ ASSERT(false);
+ return false;
+ }
+ }
+
+ *children = std::move(newChildren);
+
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+struct TIntermRebuild::NodeStackGuard
+{
+ ConsList<TIntermNode *> oldNodeStack;
+ ConsList<TIntermNode *> &nodeStack;
+ NodeStackGuard(ConsList<TIntermNode *> &nodeStack, TIntermNode *node)
+ : oldNodeStack(nodeStack), nodeStack(nodeStack)
+ {
+ nodeStack = {node, &oldNodeStack};
+ }
+ ~NodeStackGuard() { nodeStack = oldNodeStack; }
+};
+
+PostResult TIntermRebuild::traverseAny(TIntermNode &originalNode)
+{
+ PreResult preResult = traversePre(originalNode);
+ if (!preResult.mSingle)
+ {
+ ASSERT(preResult.mVisit == VisitBits::Neither);
+ return std::move(preResult);
+ }
+
+ TIntermNode *currNode = preResult.mSingle;
+ const VisitBits visit = preResult.mVisit;
+ const NodeType currNodeType = getNodeType(*currNode);
+
+ currNode = traverseChildren(currNodeType, originalNode, *currNode, visit);
+ if (!currNode)
+ {
+ return Fail();
+ }
+
+ return traversePost(currNodeType, originalNode, *currNode, visit);
+}
+
+PreResult TIntermRebuild::traversePre(TIntermNode &originalNode)
+{
+ if (!mPreVisit)
+ {
+ return {originalNode, VisitBits::Both};
+ }
+
+ NodeStackGuard guard(mNodeStack, &originalNode);
+
+ const NodeType originalNodeType = getNodeType(originalNode);
+
+ switch (originalNodeType)
+ {
+ case NodeType::Unknown:
+ ASSERT(false);
+ return Fail();
+ case NodeType::Symbol:
+ return visitSymbolPre(*originalNode.getAsSymbolNode());
+ case NodeType::ConstantUnion:
+ return visitConstantUnionPre(*originalNode.getAsConstantUnion());
+ case NodeType::FunctionPrototype:
+ return visitFunctionPrototypePre(*originalNode.getAsFunctionPrototypeNode());
+ case NodeType::PreprocessorDirective:
+ return visitPreprocessorDirectivePre(*originalNode.getAsPreprocessorDirective());
+ case NodeType::Unary:
+ return visitUnaryPre(*originalNode.getAsUnaryNode());
+ case NodeType::Binary:
+ return visitBinaryPre(*originalNode.getAsBinaryNode());
+ case NodeType::Ternary:
+ return visitTernaryPre(*originalNode.getAsTernaryNode());
+ case NodeType::Swizzle:
+ return visitSwizzlePre(*originalNode.getAsSwizzleNode());
+ case NodeType::IfElse:
+ return visitIfElsePre(*originalNode.getAsIfElseNode());
+ case NodeType::Switch:
+ return visitSwitchPre(*originalNode.getAsSwitchNode());
+ case NodeType::Case:
+ return visitCasePre(*originalNode.getAsCaseNode());
+ case NodeType::FunctionDefinition:
+ return visitFunctionDefinitionPre(*originalNode.getAsFunctionDefinition());
+ case NodeType::Aggregate:
+ return visitAggregatePre(*originalNode.getAsAggregate());
+ case NodeType::Block:
+ return visitBlockPre(*originalNode.getAsBlock());
+ case NodeType::GlobalQualifierDeclaration:
+ return visitGlobalQualifierDeclarationPre(
+ *originalNode.getAsGlobalQualifierDeclarationNode());
+ case NodeType::Declaration:
+ return visitDeclarationPre(*originalNode.getAsDeclarationNode());
+ case NodeType::Loop:
+ return visitLoopPre(*originalNode.getAsLoopNode());
+ case NodeType::Branch:
+ return visitBranchPre(*originalNode.getAsBranchNode());
+ default:
+ ASSERT(false);
+ return Fail();
+ }
+}
+
+TIntermNode *TIntermRebuild::traverseChildren(NodeType currNodeType,
+ const TIntermNode &originalNode,
+ TIntermNode &currNode,
+ VisitBits visit)
+{
+ if (!AnyBits(visit, VisitBits::Children))
+ {
+ return &currNode;
+ }
+
+ if (AnyBits(visit, VisitBits::ChildrenRequiresSame) && &originalNode != &currNode)
+ {
+ return &currNode;
+ }
+
+ NodeStackGuard guard(mNodeStack, &currNode);
+
+ switch (currNodeType)
+ {
+ case NodeType::Unknown:
+ ASSERT(false);
+ return nullptr;
+ case NodeType::Symbol:
+ return &currNode;
+ case NodeType::ConstantUnion:
+ return &currNode;
+ case NodeType::FunctionPrototype:
+ return &currNode;
+ case NodeType::PreprocessorDirective:
+ return &currNode;
+ case NodeType::Unary:
+ return traverseUnaryChildren(*currNode.getAsUnaryNode());
+ case NodeType::Binary:
+ return traverseBinaryChildren(*currNode.getAsBinaryNode());
+ case NodeType::Ternary:
+ return traverseTernaryChildren(*currNode.getAsTernaryNode());
+ case NodeType::Swizzle:
+ return traverseSwizzleChildren(*currNode.getAsSwizzleNode());
+ case NodeType::IfElse:
+ return traverseIfElseChildren(*currNode.getAsIfElseNode());
+ case NodeType::Switch:
+ return traverseSwitchChildren(*currNode.getAsSwitchNode());
+ case NodeType::Case:
+ return traverseCaseChildren(*currNode.getAsCaseNode());
+ case NodeType::FunctionDefinition:
+ return traverseFunctionDefinitionChildren(*currNode.getAsFunctionDefinition());
+ case NodeType::Aggregate:
+ return traverseAggregateChildren(*currNode.getAsAggregate());
+ case NodeType::Block:
+ return traverseBlockChildren(*currNode.getAsBlock());
+ case NodeType::GlobalQualifierDeclaration:
+ return traverseGlobalQualifierDeclarationChildren(
+ *currNode.getAsGlobalQualifierDeclarationNode());
+ case NodeType::Declaration:
+ return traverseDeclarationChildren(*currNode.getAsDeclarationNode());
+ case NodeType::Loop:
+ return traverseLoopChildren(*currNode.getAsLoopNode());
+ case NodeType::Branch:
+ return traverseBranchChildren(*currNode.getAsBranchNode());
+ default:
+ ASSERT(false);
+ return nullptr;
+ }
+}
+
+PostResult TIntermRebuild::traversePost(NodeType currNodeType,
+ const TIntermNode &originalNode,
+ TIntermNode &currNode,
+ VisitBits visit)
+{
+ if (!mPostVisit)
+ {
+ return currNode;
+ }
+
+ if (!AnyBits(visit, VisitBits::Post))
+ {
+ return currNode;
+ }
+
+ if (AnyBits(visit, VisitBits::PostRequiresSame) && &originalNode != &currNode)
+ {
+ return currNode;
+ }
+
+ NodeStackGuard guard(mNodeStack, &currNode);
+
+ switch (currNodeType)
+ {
+ case NodeType::Unknown:
+ ASSERT(false);
+ return Fail();
+ case NodeType::Symbol:
+ return visitSymbolPost(*currNode.getAsSymbolNode());
+ case NodeType::ConstantUnion:
+ return visitConstantUnionPost(*currNode.getAsConstantUnion());
+ case NodeType::FunctionPrototype:
+ return visitFunctionPrototypePost(*currNode.getAsFunctionPrototypeNode());
+ case NodeType::PreprocessorDirective:
+ return visitPreprocessorDirectivePost(*currNode.getAsPreprocessorDirective());
+ case NodeType::Unary:
+ return visitUnaryPost(*currNode.getAsUnaryNode());
+ case NodeType::Binary:
+ return visitBinaryPost(*currNode.getAsBinaryNode());
+ case NodeType::Ternary:
+ return visitTernaryPost(*currNode.getAsTernaryNode());
+ case NodeType::Swizzle:
+ return visitSwizzlePost(*currNode.getAsSwizzleNode());
+ case NodeType::IfElse:
+ return visitIfElsePost(*currNode.getAsIfElseNode());
+ case NodeType::Switch:
+ return visitSwitchPost(*currNode.getAsSwitchNode());
+ case NodeType::Case:
+ return visitCasePost(*currNode.getAsCaseNode());
+ case NodeType::FunctionDefinition:
+ return visitFunctionDefinitionPost(*currNode.getAsFunctionDefinition());
+ case NodeType::Aggregate:
+ return visitAggregatePost(*currNode.getAsAggregate());
+ case NodeType::Block:
+ return visitBlockPost(*currNode.getAsBlock());
+ case NodeType::GlobalQualifierDeclaration:
+ return visitGlobalQualifierDeclarationPost(
+ *currNode.getAsGlobalQualifierDeclarationNode());
+ case NodeType::Declaration:
+ return visitDeclarationPost(*currNode.getAsDeclarationNode());
+ case NodeType::Loop:
+ return visitLoopPost(*currNode.getAsLoopNode());
+ case NodeType::Branch:
+ return visitBranchPost(*currNode.getAsBranchNode());
+ default:
+ ASSERT(false);
+ return Fail();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+TIntermNode *TIntermRebuild::traverseAggregateChildren(TIntermAggregate &node)
+{
+ if (traverseAggregateBaseChildren(node))
+ {
+ return &node;
+ }
+ return nullptr;
+}
+
+TIntermNode *TIntermRebuild::traverseBlockChildren(TIntermBlock &node)
+{
+ if (traverseAggregateBaseChildren(node))
+ {
+ return &node;
+ }
+ return nullptr;
+}
+
+TIntermNode *TIntermRebuild::traverseDeclarationChildren(TIntermDeclaration &node)
+{
+ if (traverseAggregateBaseChildren(node))
+ {
+ return &node;
+ }
+ return nullptr;
+}
+
+TIntermNode *TIntermRebuild::traverseSwizzleChildren(TIntermSwizzle &node)
+{
+ auto *const operand = node.getOperand();
+ ASSERT(operand);
+
+ auto *newOperand = traverseAnyAs<TIntermTyped>(*operand);
+ GUARD(newOperand);
+
+ if (newOperand != operand)
+ {
+ return new TIntermSwizzle(newOperand, node.getSwizzleOffsets());
+ }
+
+ return &node;
+}
+
+TIntermNode *TIntermRebuild::traverseBinaryChildren(TIntermBinary &node)
+{
+ auto *const left = node.getLeft();
+ ASSERT(left);
+ auto *const right = node.getRight();
+ ASSERT(right);
+
+ auto *const newLeft = traverseAnyAs<TIntermTyped>(*left);
+ GUARD(newLeft);
+ auto *const newRight = traverseAnyAs<TIntermTyped>(*right);
+ GUARD(newRight);
+
+ if (newLeft != left || newRight != right)
+ {
+ TOperator op = node.getOp();
+ switch (op)
+ {
+ case TOperator::EOpIndexDirectStruct:
+ {
+ if (newLeft->getType().getInterfaceBlock())
+ {
+ op = TOperator::EOpIndexDirectInterfaceBlock;
+ }
+ }
+ break;
+
+ case TOperator::EOpIndexDirectInterfaceBlock:
+ {
+ if (newLeft->getType().getStruct())
+ {
+ op = TOperator::EOpIndexDirectStruct;
+ }
+ }
+ break;
+
+ case TOperator::EOpComma:
+ return TIntermBinary::CreateComma(newLeft, newRight, mCompiler.getShaderVersion());
+
+ default:
+ break;
+ }
+
+ return new TIntermBinary(op, newLeft, newRight);
+ }
+
+ return &node;
+}
+
+TIntermNode *TIntermRebuild::traverseUnaryChildren(TIntermUnary &node)
+{
+ auto *const operand = node.getOperand();
+ ASSERT(operand);
+
+ auto *const newOperand = traverseAnyAs<TIntermTyped>(*operand);
+ GUARD(newOperand);
+
+ if (newOperand != operand)
+ {
+ return new TIntermUnary(node.getOp(), newOperand, node.getFunction());
+ }
+
+ return &node;
+}
+
+TIntermNode *TIntermRebuild::traverseTernaryChildren(TIntermTernary &node)
+{
+ auto *const cond = node.getCondition();
+ ASSERT(cond);
+ auto *const true_ = node.getTrueExpression();
+ ASSERT(true_);
+ auto *const false_ = node.getFalseExpression();
+ ASSERT(false_);
+
+ auto *const newCond = traverseAnyAs<TIntermTyped>(*cond);
+ GUARD(newCond);
+ auto *const newTrue = traverseAnyAs<TIntermTyped>(*true_);
+ GUARD(newTrue);
+ auto *const newFalse = traverseAnyAs<TIntermTyped>(*false_);
+ GUARD(newFalse);
+
+ if (newCond != cond || newTrue != true_ || newFalse != false_)
+ {
+ return new TIntermTernary(newCond, newTrue, newFalse);
+ }
+
+ return &node;
+}
+
+TIntermNode *TIntermRebuild::traverseIfElseChildren(TIntermIfElse &node)
+{
+ auto *const cond = node.getCondition();
+ ASSERT(cond);
+ auto *const true_ = node.getTrueBlock();
+ auto *const false_ = node.getFalseBlock();
+
+ auto *const newCond = traverseAnyAs<TIntermTyped>(*cond);
+ GUARD(newCond);
+ TIntermBlock *newTrue = nullptr;
+ if (true_)
+ {
+ GUARD(traverseAnyAs(*true_, newTrue));
+ }
+ TIntermBlock *newFalse = nullptr;
+ if (false_)
+ {
+ GUARD(traverseAnyAs(*false_, newFalse));
+ }
+
+ if (newCond != cond || newTrue != true_ || newFalse != false_)
+ {
+ return new TIntermIfElse(newCond, newTrue, newFalse);
+ }
+
+ return &node;
+}
+
+TIntermNode *TIntermRebuild::traverseSwitchChildren(TIntermSwitch &node)
+{
+ auto *const init = node.getInit();
+ ASSERT(init);
+ auto *const stmts = node.getStatementList();
+ ASSERT(stmts);
+
+ auto *const newInit = traverseAnyAs<TIntermTyped>(*init);
+ GUARD(newInit);
+ auto *const newStmts = traverseAnyAs<TIntermBlock>(*stmts);
+ GUARD(newStmts);
+
+ if (newInit != init || newStmts != stmts)
+ {
+ return new TIntermSwitch(newInit, newStmts);
+ }
+
+ return &node;
+}
+
+TIntermNode *TIntermRebuild::traverseCaseChildren(TIntermCase &node)
+{
+ auto *const cond = node.getCondition();
+
+ TIntermTyped *newCond = nullptr;
+ if (cond)
+ {
+ GUARD(traverseAnyAs(*cond, newCond));
+ }
+
+ if (newCond != cond)
+ {
+ return new TIntermCase(newCond);
+ }
+
+ return &node;
+}
+
+TIntermNode *TIntermRebuild::traverseFunctionDefinitionChildren(TIntermFunctionDefinition &node)
+{
+ GUARD(!mParentFunc); // Function definitions cannot be nested.
+ mParentFunc = node.getFunction();
+ struct OnExit
+ {
+ const TFunction *&parentFunc;
+ OnExit(const TFunction *&parentFunc) : parentFunc(parentFunc) {}
+ ~OnExit() { parentFunc = nullptr; }
+ } onExit(mParentFunc);
+
+ auto *const proto = node.getFunctionPrototype();
+ ASSERT(proto);
+ auto *const body = node.getBody();
+ ASSERT(body);
+
+ auto *const newProto = traverseAnyAs<TIntermFunctionPrototype>(*proto);
+ GUARD(newProto);
+ auto *const newBody = traverseAnyAs<TIntermBlock>(*body);
+ GUARD(newBody);
+
+ if (newProto != proto || newBody != body)
+ {
+ return new TIntermFunctionDefinition(newProto, newBody);
+ }
+
+ return &node;
+}
+
+TIntermNode *TIntermRebuild::traverseGlobalQualifierDeclarationChildren(
+ TIntermGlobalQualifierDeclaration &node)
+{
+ auto *const symbol = node.getSymbol();
+ ASSERT(symbol);
+
+ auto *const newSymbol = traverseAnyAs<TIntermSymbol>(*symbol);
+ GUARD(newSymbol);
+
+ if (newSymbol != symbol)
+ {
+ return new TIntermGlobalQualifierDeclaration(newSymbol, node.isPrecise(), node.getLine());
+ }
+
+ return &node;
+}
+
+TIntermNode *TIntermRebuild::traverseLoopChildren(TIntermLoop &node)
+{
+ const TLoopType loopType = node.getType();
+
+ auto *const init = node.getInit();
+ auto *const cond = node.getCondition();
+ auto *const expr = node.getExpression();
+ auto *const body = node.getBody();
+ ASSERT(body);
+
+#if defined(ANGLE_ENABLE_ASSERTS)
+ switch (loopType)
+ {
+ case TLoopType::ELoopFor:
+ break;
+ case TLoopType::ELoopWhile:
+ case TLoopType::ELoopDoWhile:
+ ASSERT(cond);
+ ASSERT(!init && !expr);
+ break;
+ default:
+ ASSERT(false);
+ break;
+ }
+#endif
+
+ auto *const newBody = traverseAnyAs<TIntermBlock>(*body);
+ GUARD(newBody);
+ TIntermNode *newInit = nullptr;
+ if (init)
+ {
+ GUARD(traverseAnyAs(*init, newInit));
+ }
+ TIntermTyped *newCond = nullptr;
+ if (cond)
+ {
+ GUARD(traverseAnyAs(*cond, newCond));
+ }
+ TIntermTyped *newExpr = nullptr;
+ if (expr)
+ {
+ GUARD(traverseAnyAs(*expr, newExpr));
+ }
+
+ if (newInit != init || newCond != cond || newExpr != expr || newBody != body)
+ {
+ switch (loopType)
+ {
+ case TLoopType::ELoopFor:
+ GUARD(newBody);
+ break;
+ case TLoopType::ELoopWhile:
+ case TLoopType::ELoopDoWhile:
+ GUARD(newCond && newBody);
+ GUARD(!newInit && !newExpr);
+ break;
+ default:
+ ASSERT(false);
+ break;
+ }
+ return new TIntermLoop(loopType, newInit, newCond, newExpr, newBody);
+ }
+
+ return &node;
+}
+
+TIntermNode *TIntermRebuild::traverseBranchChildren(TIntermBranch &node)
+{
+ auto *const expr = node.getExpression();
+
+ TIntermTyped *newExpr = nullptr;
+ if (expr)
+ {
+ GUARD(traverseAnyAs<TIntermTyped>(*expr, newExpr));
+ }
+
+ if (newExpr != expr)
+ {
+ return new TIntermBranch(node.getFlowOp(), newExpr);
+ }
+
+ return &node;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+PreResult TIntermRebuild::visitSymbolPre(TIntermSymbol &node)
+{
+ return {node, VisitBits::Both};
+}
+
+PreResult TIntermRebuild::visitConstantUnionPre(TIntermConstantUnion &node)
+{
+ return {node, VisitBits::Both};
+}
+
+PreResult TIntermRebuild::visitFunctionPrototypePre(TIntermFunctionPrototype &node)
+{
+ return {node, VisitBits::Both};
+}
+
+PreResult TIntermRebuild::visitPreprocessorDirectivePre(TIntermPreprocessorDirective &node)
+{
+ return {node, VisitBits::Both};
+}
+
+PreResult TIntermRebuild::visitUnaryPre(TIntermUnary &node)
+{
+ return {node, VisitBits::Both};
+}
+
+PreResult TIntermRebuild::visitBinaryPre(TIntermBinary &node)
+{
+ return {node, VisitBits::Both};
+}
+
+PreResult TIntermRebuild::visitTernaryPre(TIntermTernary &node)
+{
+ return {node, VisitBits::Both};
+}
+
+PreResult TIntermRebuild::visitSwizzlePre(TIntermSwizzle &node)
+{
+ return {node, VisitBits::Both};
+}
+
+PreResult TIntermRebuild::visitIfElsePre(TIntermIfElse &node)
+{
+ return {node, VisitBits::Both};
+}
+
+PreResult TIntermRebuild::visitSwitchPre(TIntermSwitch &node)
+{
+ return {node, VisitBits::Both};
+}
+
+PreResult TIntermRebuild::visitCasePre(TIntermCase &node)
+{
+ return {node, VisitBits::Both};
+}
+
+PreResult TIntermRebuild::visitLoopPre(TIntermLoop &node)
+{
+ return {node, VisitBits::Both};
+}
+
+PreResult TIntermRebuild::visitBranchPre(TIntermBranch &node)
+{
+ return {node, VisitBits::Both};
+}
+
+PreResult TIntermRebuild::visitDeclarationPre(TIntermDeclaration &node)
+{
+ return {node, VisitBits::Both};
+}
+
+PreResult TIntermRebuild::visitBlockPre(TIntermBlock &node)
+{
+ return {node, VisitBits::Both};
+}
+
+PreResult TIntermRebuild::visitAggregatePre(TIntermAggregate &node)
+{
+ return {node, VisitBits::Both};
+}
+
+PreResult TIntermRebuild::visitFunctionDefinitionPre(TIntermFunctionDefinition &node)
+{
+ return {node, VisitBits::Both};
+}
+
+PreResult TIntermRebuild::visitGlobalQualifierDeclarationPre(
+ TIntermGlobalQualifierDeclaration &node)
+{
+ return {node, VisitBits::Both};
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+PostResult TIntermRebuild::visitSymbolPost(TIntermSymbol &node)
+{
+ return node;
+}
+
+PostResult TIntermRebuild::visitConstantUnionPost(TIntermConstantUnion &node)
+{
+ return node;
+}
+
+PostResult TIntermRebuild::visitFunctionPrototypePost(TIntermFunctionPrototype &node)
+{
+ return node;
+}
+
+PostResult TIntermRebuild::visitPreprocessorDirectivePost(TIntermPreprocessorDirective &node)
+{
+ return node;
+}
+
+PostResult TIntermRebuild::visitUnaryPost(TIntermUnary &node)
+{
+ return node;
+}
+
+PostResult TIntermRebuild::visitBinaryPost(TIntermBinary &node)
+{
+ return node;
+}
+
+PostResult TIntermRebuild::visitTernaryPost(TIntermTernary &node)
+{
+ return node;
+}
+
+PostResult TIntermRebuild::visitSwizzlePost(TIntermSwizzle &node)
+{
+ return node;
+}
+
+PostResult TIntermRebuild::visitIfElsePost(TIntermIfElse &node)
+{
+ return node;
+}
+
+PostResult TIntermRebuild::visitSwitchPost(TIntermSwitch &node)
+{
+ return node;
+}
+
+PostResult TIntermRebuild::visitCasePost(TIntermCase &node)
+{
+ return node;
+}
+
+PostResult TIntermRebuild::visitLoopPost(TIntermLoop &node)
+{
+ return node;
+}
+
+PostResult TIntermRebuild::visitBranchPost(TIntermBranch &node)
+{
+ return node;
+}
+
+PostResult TIntermRebuild::visitDeclarationPost(TIntermDeclaration &node)
+{
+ return node;
+}
+
+PostResult TIntermRebuild::visitBlockPost(TIntermBlock &node)
+{
+ return node;
+}
+
+PostResult TIntermRebuild::visitAggregatePost(TIntermAggregate &node)
+{
+ return node;
+}
+
+PostResult TIntermRebuild::visitFunctionDefinitionPost(TIntermFunctionDefinition &node)
+{
+ return node;
+}
+
+PostResult TIntermRebuild::visitGlobalQualifierDeclarationPost(
+ TIntermGlobalQualifierDeclaration &node)
+{
+ return node;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/IntermRebuild.h b/gfx/angle/checkout/src/compiler/translator/tree_util/IntermRebuild.h
new file mode 100644
index 0000000000..7907d283ef
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/IntermRebuild.h
@@ -0,0 +1,328 @@
+//
+// Copyright 2020 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_TRANSLATORMETALDIRECT_INTERMREBUILD_H_
+#define COMPILER_TRANSLATOR_TRANSLATORMETALDIRECT_INTERMREBUILD_H_
+
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/tree_util/NodeType.h"
+
+namespace sh
+{
+
+// Walks the tree to rebuild nodes.
+// This class is intended to be derived with overridden visitXXX functions.
+//
+// Each visitXXX function that does not have a Visit parameter simply has the visitor called
+// exactly once, regardless of (preVisit) or (postVisit) values.
+
+// Each visitXXX function that has a Visit parameter behaves as follows:
+// * If (preVisit):
+// - The node is visited before children are traversed.
+// - The returned value is used to replace the visited node. The returned value may be the same
+// as the original node.
+// - If multiple nodes are returned, children and post visits of the returned nodes are not
+// preformed, even if it is a singleton collection.
+// * If (childVisit)
+// - If any new children are returned, the node is automatically rebuilt with the new children
+// before post visit.
+// - Depending on the type of the node, null children may be discarded.
+// - Ill-typed children cause rebuild errors. Ill-typed means the node to automatically rebuild
+// cannot accept a child of a certain type as input to its constructor.
+// - Only instances of TIntermAggregateBase can accept Multi results for any of its children.
+// If supplied, the nodes are spliced children at the spot of the original child.
+// * If (postVisit)
+// - The node is visited after any children are traversed.
+// - Only after such a rebuild (or lack thereof), the post-visit is performed.
+//
+// Nodes in visit functions are allowed to be modified in place, including TIntermAggregateBase
+// child sequences.
+//
+// The default implementations of all the visitXXX functions support full pre and post traversal
+// without modifying the visited nodes.
+//
+class TIntermRebuild : angle::NonCopyable
+{
+
+ enum class Action
+ {
+ ReplaceSingle,
+ ReplaceMulti,
+ Drop,
+ Fail,
+ };
+
+ public:
+ struct Fail
+ {};
+
+ enum VisitBits : size_t
+ {
+ // No bits are set.
+ Empty = 0u,
+
+ // Allow visit of returned node's children.
+ Children = 1u << 0u,
+
+ // Allow post visit of returned node.
+ Post = 1u << 1u,
+
+ // If (Children) bit, only visit if the returned node is the same as the original node.
+ ChildrenRequiresSame = 1u << 2u,
+
+ // If (Post) bit, only visit if the returned node is the same as the original node.
+ PostRequiresSame = 1u << 3u,
+
+ RequireSame = ChildrenRequiresSame | PostRequiresSame,
+ Neither = Empty,
+ Both = Children | Post,
+ BothWhenSame = Both | RequireSame,
+ };
+
+ private:
+ struct NodeStackGuard;
+
+ template <typename T>
+ struct ConsList
+ {
+ T value;
+ ConsList<T> *tail;
+ };
+
+ class BaseResult
+ {
+ BaseResult(const BaseResult &) = delete;
+ BaseResult &operator=(const BaseResult &) = delete;
+
+ public:
+ BaseResult(BaseResult &&other) = default;
+ BaseResult(BaseResult &other); // For subclass move constructor impls
+ BaseResult(TIntermNode &node, VisitBits visit);
+ BaseResult(TIntermNode *node, VisitBits visit);
+ BaseResult(std::nullptr_t);
+ BaseResult(Fail);
+ BaseResult(std::vector<TIntermNode *> &&nodes);
+
+ void moveAssignImpl(BaseResult &other); // For subclass move assign impls
+
+ static BaseResult Multi(std::vector<TIntermNode *> &&nodes);
+
+ template <typename Iter>
+ static BaseResult Multi(Iter nodesBegin, Iter nodesEnd)
+ {
+ std::vector<TIntermNode *> nodes;
+ for (Iter nodesCurr = nodesBegin; nodesCurr != nodesEnd; ++nodesCurr)
+ {
+ nodes.push_back(*nodesCurr);
+ }
+ return std::move(nodes);
+ }
+
+ bool isFail() const;
+ bool isDrop() const;
+ TIntermNode *single() const;
+ const std::vector<TIntermNode *> *multi() const;
+
+ public:
+ Action mAction;
+ VisitBits mVisit;
+ TIntermNode *mSingle;
+ std::vector<TIntermNode *> mMulti;
+ };
+
+ public:
+ class PreResult : private BaseResult
+ {
+ friend class TIntermRebuild;
+
+ public:
+ PreResult(PreResult &&other);
+ PreResult(TIntermNode &node, VisitBits visit = VisitBits::BothWhenSame);
+ PreResult(TIntermNode *node, VisitBits visit = VisitBits::BothWhenSame);
+ PreResult(std::nullptr_t); // Used to drop a node.
+ PreResult(Fail); // Used to signal failure.
+
+ void operator=(PreResult &&other);
+
+ static PreResult Multi(std::vector<TIntermNode *> &&nodes)
+ {
+ return BaseResult::Multi(std::move(nodes));
+ }
+
+ template <typename Iter>
+ static PreResult Multi(Iter nodesBegin, Iter nodesEnd)
+ {
+ return BaseResult::Multi(nodesBegin, nodesEnd);
+ }
+
+ using BaseResult::isDrop;
+ using BaseResult::isFail;
+ using BaseResult::multi;
+ using BaseResult::single;
+
+ private:
+ PreResult(BaseResult &&other);
+ };
+
+ class PostResult : private BaseResult
+ {
+ friend class TIntermRebuild;
+
+ public:
+ PostResult(PostResult &&other);
+ PostResult(TIntermNode &node);
+ PostResult(TIntermNode *node);
+ PostResult(std::nullptr_t); // Used to drop a node
+ PostResult(Fail); // Used to signal failure.
+
+ void operator=(PostResult &&other);
+
+ static PostResult Multi(std::vector<TIntermNode *> &&nodes)
+ {
+ return BaseResult::Multi(std::move(nodes));
+ }
+
+ template <typename Iter>
+ static PostResult Multi(Iter nodesBegin, Iter nodesEnd)
+ {
+ return BaseResult::Multi(nodesBegin, nodesEnd);
+ }
+
+ using BaseResult::isDrop;
+ using BaseResult::isFail;
+ using BaseResult::multi;
+ using BaseResult::single;
+
+ private:
+ PostResult(BaseResult &&other);
+ };
+
+ public:
+ TIntermRebuild(TCompiler &compiler, bool preVisit, bool postVisit);
+
+ virtual ~TIntermRebuild();
+
+ // Rebuilds the tree starting at the provided root. If a new node would be returned for the
+ // root, the root node's children become that of the new node instead. Returns false if failure
+ // occurred.
+ [[nodiscard]] bool rebuildRoot(TIntermBlock &root);
+
+ protected:
+ virtual PreResult visitSymbolPre(TIntermSymbol &node);
+ virtual PreResult visitConstantUnionPre(TIntermConstantUnion &node);
+ virtual PreResult visitFunctionPrototypePre(TIntermFunctionPrototype &node);
+ virtual PreResult visitPreprocessorDirectivePre(TIntermPreprocessorDirective &node);
+ virtual PreResult visitUnaryPre(TIntermUnary &node);
+ virtual PreResult visitBinaryPre(TIntermBinary &node);
+ virtual PreResult visitTernaryPre(TIntermTernary &node);
+ virtual PreResult visitSwizzlePre(TIntermSwizzle &node);
+ virtual PreResult visitIfElsePre(TIntermIfElse &node);
+ virtual PreResult visitSwitchPre(TIntermSwitch &node);
+ virtual PreResult visitCasePre(TIntermCase &node);
+ virtual PreResult visitLoopPre(TIntermLoop &node);
+ virtual PreResult visitBranchPre(TIntermBranch &node);
+ virtual PreResult visitDeclarationPre(TIntermDeclaration &node);
+ virtual PreResult visitBlockPre(TIntermBlock &node);
+ virtual PreResult visitAggregatePre(TIntermAggregate &node);
+ virtual PreResult visitFunctionDefinitionPre(TIntermFunctionDefinition &node);
+ virtual PreResult visitGlobalQualifierDeclarationPre(TIntermGlobalQualifierDeclaration &node);
+
+ virtual PostResult visitSymbolPost(TIntermSymbol &node);
+ virtual PostResult visitConstantUnionPost(TIntermConstantUnion &node);
+ virtual PostResult visitFunctionPrototypePost(TIntermFunctionPrototype &node);
+ virtual PostResult visitPreprocessorDirectivePost(TIntermPreprocessorDirective &node);
+ virtual PostResult visitUnaryPost(TIntermUnary &node);
+ virtual PostResult visitBinaryPost(TIntermBinary &node);
+ virtual PostResult visitTernaryPost(TIntermTernary &node);
+ virtual PostResult visitSwizzlePost(TIntermSwizzle &node);
+ virtual PostResult visitIfElsePost(TIntermIfElse &node);
+ virtual PostResult visitSwitchPost(TIntermSwitch &node);
+ virtual PostResult visitCasePost(TIntermCase &node);
+ virtual PostResult visitLoopPost(TIntermLoop &node);
+ virtual PostResult visitBranchPost(TIntermBranch &node);
+ virtual PostResult visitDeclarationPost(TIntermDeclaration &node);
+ virtual PostResult visitBlockPost(TIntermBlock &node);
+ virtual PostResult visitAggregatePost(TIntermAggregate &node);
+ virtual PostResult visitFunctionDefinitionPost(TIntermFunctionDefinition &node);
+ virtual PostResult visitGlobalQualifierDeclarationPost(TIntermGlobalQualifierDeclaration &node);
+
+ // Can be used to rebuild a specific node during a traversal. Useful for fine control of
+ // rebuilding a node's children.
+ [[nodiscard]] PostResult rebuild(TIntermNode &node);
+
+ // Rebuilds the provided node in place. If a new node would be returned, the old node's children
+ // become that of the new node instead. Returns false if failure occurred.
+ [[nodiscard]] bool rebuildInPlace(TIntermAggregate &node);
+
+ // Rebuilds the provided node in place. If a new node would be returned, the old node's children
+ // become that of the new node instead. Returns false if failure occurred.
+ [[nodiscard]] bool rebuildInPlace(TIntermBlock &node);
+
+ // Rebuilds the provided node in place. If a new node would be returned, the old node's children
+ // become that of the new node instead. Returns false if failure occurred.
+ [[nodiscard]] bool rebuildInPlace(TIntermDeclaration &node);
+
+ // If currently at or below a function declaration body, this returns the function that encloses
+ // the currently visited node. (This returns null if at a function declaration node.)
+ const TFunction *getParentFunction() const;
+
+ TIntermNode *getParentNode(size_t offset = 0) const;
+
+ private:
+ template <typename Node>
+ [[nodiscard]] bool rebuildInPlaceImpl(Node &node);
+
+ PostResult traverseAny(TIntermNode &node);
+
+ template <typename Node>
+ Node *traverseAnyAs(TIntermNode &node);
+
+ template <typename Node>
+ bool traverseAnyAs(TIntermNode &node, Node *&out);
+
+ PreResult traversePre(TIntermNode &originalNode);
+ TIntermNode *traverseChildren(NodeType currNodeType,
+ const TIntermNode &originalNode,
+ TIntermNode &currNode,
+ VisitBits visit);
+ PostResult traversePost(NodeType nodeType,
+ const TIntermNode &originalNode,
+ TIntermNode &currNode,
+ VisitBits visit);
+
+ bool traverseAggregateBaseChildren(TIntermAggregateBase &node);
+
+ TIntermNode *traverseUnaryChildren(TIntermUnary &node);
+ TIntermNode *traverseBinaryChildren(TIntermBinary &node);
+ TIntermNode *traverseTernaryChildren(TIntermTernary &node);
+ TIntermNode *traverseSwizzleChildren(TIntermSwizzle &node);
+ TIntermNode *traverseIfElseChildren(TIntermIfElse &node);
+ TIntermNode *traverseSwitchChildren(TIntermSwitch &node);
+ TIntermNode *traverseCaseChildren(TIntermCase &node);
+ TIntermNode *traverseLoopChildren(TIntermLoop &node);
+ TIntermNode *traverseBranchChildren(TIntermBranch &node);
+ TIntermNode *traverseDeclarationChildren(TIntermDeclaration &node);
+ TIntermNode *traverseBlockChildren(TIntermBlock &node);
+ TIntermNode *traverseAggregateChildren(TIntermAggregate &node);
+ TIntermNode *traverseFunctionDefinitionChildren(TIntermFunctionDefinition &node);
+ TIntermNode *traverseGlobalQualifierDeclarationChildren(
+ TIntermGlobalQualifierDeclaration &node);
+
+ protected:
+ TCompiler &mCompiler;
+ TSymbolTable &mSymbolTable;
+ const TFunction *mParentFunc = nullptr;
+ GetNodeType getNodeType;
+
+ private:
+ ConsList<TIntermNode *> mNodeStack{nullptr, nullptr};
+ bool mPreVisit;
+ bool mPostVisit;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TRANSLATORMETALDIRECT_INTERMREBUILD_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/IntermTraverse.cpp b/gfx/angle/checkout/src/compiler/translator/tree_util/IntermTraverse.cpp
new file mode 100644
index 0000000000..c4bbe1fa4d
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/IntermTraverse.cpp
@@ -0,0 +1,708 @@
+//
+// Copyright 2002 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/tree_util/IntermTraverse.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/InfoSink.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+// Traverse the intermediate representation tree, and call a node type specific visit function for
+// each node. Traversal is done recursively through the node member function traverse(). Nodes with
+// children can have their whole subtree skipped if preVisit is turned on and the type specific
+// function returns false.
+template <typename T>
+void TIntermTraverser::traverse(T *node)
+{
+ ScopedNodeInTraversalPath addToPath(this, node);
+ if (!addToPath.isWithinDepthLimit())
+ return;
+
+ bool visit = true;
+
+ // Visit the node before children if pre-visiting.
+ if (preVisit)
+ visit = node->visit(PreVisit, this);
+
+ if (visit)
+ {
+ size_t childIndex = 0;
+ size_t childCount = node->getChildCount();
+
+ while (childIndex < childCount && visit)
+ {
+ mCurrentChildIndex = childIndex;
+ node->getChildNode(childIndex)->traverse(this);
+ mCurrentChildIndex = childIndex;
+
+ if (inVisit && childIndex != childCount - 1)
+ {
+ visit = node->visit(InVisit, this);
+ }
+ ++childIndex;
+ }
+
+ if (visit && postVisit)
+ node->visit(PostVisit, this);
+ }
+}
+
+// Instantiate template for RewriteAtomicFunctionExpressions, in case this gets inlined thus not
+// exported from the TU.
+template void TIntermTraverser::traverse(TIntermNode *);
+
+void TIntermNode::traverse(TIntermTraverser *it)
+{
+ it->traverse(this);
+}
+
+void TIntermSymbol::traverse(TIntermTraverser *it)
+{
+ TIntermTraverser::ScopedNodeInTraversalPath addToPath(it, this);
+ it->visitSymbol(this);
+}
+
+void TIntermConstantUnion::traverse(TIntermTraverser *it)
+{
+ TIntermTraverser::ScopedNodeInTraversalPath addToPath(it, this);
+ it->visitConstantUnion(this);
+}
+
+void TIntermFunctionPrototype::traverse(TIntermTraverser *it)
+{
+ TIntermTraverser::ScopedNodeInTraversalPath addToPath(it, this);
+ it->visitFunctionPrototype(this);
+}
+
+void TIntermBinary::traverse(TIntermTraverser *it)
+{
+ it->traverseBinary(this);
+}
+
+void TIntermUnary::traverse(TIntermTraverser *it)
+{
+ it->traverseUnary(this);
+}
+
+void TIntermFunctionDefinition::traverse(TIntermTraverser *it)
+{
+ it->traverseFunctionDefinition(this);
+}
+
+void TIntermBlock::traverse(TIntermTraverser *it)
+{
+ it->traverseBlock(this);
+}
+
+void TIntermAggregate::traverse(TIntermTraverser *it)
+{
+ it->traverseAggregate(this);
+}
+
+void TIntermLoop::traverse(TIntermTraverser *it)
+{
+ it->traverseLoop(this);
+}
+
+void TIntermPreprocessorDirective::traverse(TIntermTraverser *it)
+{
+ it->visitPreprocessorDirective(this);
+}
+
+bool TIntermSymbol::visit(Visit visit, TIntermTraverser *it)
+{
+ it->visitSymbol(this);
+ return false;
+}
+
+bool TIntermConstantUnion::visit(Visit visit, TIntermTraverser *it)
+{
+ it->visitConstantUnion(this);
+ return false;
+}
+
+bool TIntermFunctionPrototype::visit(Visit visit, TIntermTraverser *it)
+{
+ it->visitFunctionPrototype(this);
+ return false;
+}
+
+bool TIntermFunctionDefinition::visit(Visit visit, TIntermTraverser *it)
+{
+ return it->visitFunctionDefinition(visit, this);
+}
+
+bool TIntermUnary::visit(Visit visit, TIntermTraverser *it)
+{
+ return it->visitUnary(visit, this);
+}
+
+bool TIntermSwizzle::visit(Visit visit, TIntermTraverser *it)
+{
+ return it->visitSwizzle(visit, this);
+}
+
+bool TIntermBinary::visit(Visit visit, TIntermTraverser *it)
+{
+ return it->visitBinary(visit, this);
+}
+
+bool TIntermTernary::visit(Visit visit, TIntermTraverser *it)
+{
+ return it->visitTernary(visit, this);
+}
+
+bool TIntermAggregate::visit(Visit visit, TIntermTraverser *it)
+{
+ return it->visitAggregate(visit, this);
+}
+
+bool TIntermDeclaration::visit(Visit visit, TIntermTraverser *it)
+{
+ return it->visitDeclaration(visit, this);
+}
+
+bool TIntermGlobalQualifierDeclaration::visit(Visit visit, TIntermTraverser *it)
+{
+ return it->visitGlobalQualifierDeclaration(visit, this);
+}
+
+bool TIntermBlock::visit(Visit visit, TIntermTraverser *it)
+{
+ return it->visitBlock(visit, this);
+}
+
+bool TIntermIfElse::visit(Visit visit, TIntermTraverser *it)
+{
+ return it->visitIfElse(visit, this);
+}
+
+bool TIntermLoop::visit(Visit visit, TIntermTraverser *it)
+{
+ return it->visitLoop(visit, this);
+}
+
+bool TIntermBranch::visit(Visit visit, TIntermTraverser *it)
+{
+ return it->visitBranch(visit, this);
+}
+
+bool TIntermSwitch::visit(Visit visit, TIntermTraverser *it)
+{
+ return it->visitSwitch(visit, this);
+}
+
+bool TIntermCase::visit(Visit visit, TIntermTraverser *it)
+{
+ return it->visitCase(visit, this);
+}
+
+bool TIntermPreprocessorDirective::visit(Visit visit, TIntermTraverser *it)
+{
+ it->visitPreprocessorDirective(this);
+ return false;
+}
+
+TIntermTraverser::TIntermTraverser(bool preVisit,
+ bool inVisit,
+ bool postVisit,
+ TSymbolTable *symbolTable)
+ : preVisit(preVisit),
+ inVisit(inVisit),
+ postVisit(postVisit),
+ mMaxDepth(0),
+ mMaxAllowedDepth(std::numeric_limits<int>::max()),
+ mInGlobalScope(true),
+ mSymbolTable(symbolTable),
+ mCurrentChildIndex(0)
+{
+ // Only enabling inVisit is not supported.
+ ASSERT(!(inVisit && !preVisit && !postVisit));
+}
+
+TIntermTraverser::~TIntermTraverser() {}
+
+void TIntermTraverser::setMaxAllowedDepth(int depth)
+{
+ mMaxAllowedDepth = depth;
+}
+
+const TIntermBlock *TIntermTraverser::getParentBlock() const
+{
+ if (!mParentBlockStack.empty())
+ {
+ return mParentBlockStack.back().node;
+ }
+ return nullptr;
+}
+
+void TIntermTraverser::pushParentBlock(TIntermBlock *node)
+{
+ mParentBlockStack.push_back(ParentBlock(node, 0));
+}
+
+void TIntermTraverser::incrementParentBlockPos()
+{
+ ++mParentBlockStack.back().pos;
+}
+
+void TIntermTraverser::popParentBlock()
+{
+ ASSERT(!mParentBlockStack.empty());
+ mParentBlockStack.pop_back();
+}
+
+void TIntermTraverser::insertStatementsInParentBlock(const TIntermSequence &insertions)
+{
+ TIntermSequence emptyInsertionsAfter;
+ insertStatementsInParentBlock(insertions, emptyInsertionsAfter);
+}
+
+void TIntermTraverser::insertStatementsInParentBlock(const TIntermSequence &insertionsBefore,
+ const TIntermSequence &insertionsAfter)
+{
+ ASSERT(!mParentBlockStack.empty());
+ ParentBlock &parentBlock = mParentBlockStack.back();
+ if (mPath.back() == parentBlock.node)
+ {
+ ASSERT(mParentBlockStack.size() >= 2u);
+ // The current node is a block node, so the parent block is not the topmost one in the block
+ // stack, but the one below that.
+ parentBlock = mParentBlockStack.at(mParentBlockStack.size() - 2u);
+ }
+ NodeInsertMultipleEntry insert(parentBlock.node, parentBlock.pos, insertionsBefore,
+ insertionsAfter);
+ mInsertions.push_back(insert);
+}
+
+void TIntermTraverser::insertStatementInParentBlock(TIntermNode *statement)
+{
+ TIntermSequence insertions;
+ insertions.push_back(statement);
+ insertStatementsInParentBlock(insertions);
+}
+
+void TIntermTraverser::insertStatementsInBlockAtPosition(TIntermBlock *parent,
+ size_t position,
+ const TIntermSequence &insertionsBefore,
+ const TIntermSequence &insertionsAfter)
+{
+ ASSERT(parent);
+ ASSERT(position >= 0);
+ ASSERT(position < parent->getChildCount());
+
+ mInsertions.emplace_back(parent, position, insertionsBefore, insertionsAfter);
+}
+
+void TLValueTrackingTraverser::setInFunctionCallOutParameter(bool inOutParameter)
+{
+ mInFunctionCallOutParameter = inOutParameter;
+}
+
+bool TLValueTrackingTraverser::isInFunctionCallOutParameter() const
+{
+ return mInFunctionCallOutParameter;
+}
+
+void TIntermTraverser::traverseBinary(TIntermBinary *node)
+{
+ traverse(node);
+}
+
+void TLValueTrackingTraverser::traverseBinary(TIntermBinary *node)
+{
+ ScopedNodeInTraversalPath addToPath(this, node);
+ if (!addToPath.isWithinDepthLimit())
+ return;
+
+ bool visit = true;
+
+ // visit the node before children if pre-visiting.
+ if (preVisit)
+ visit = node->visit(PreVisit, this);
+
+ // Visit the children, in the right order.
+ if (visit)
+ {
+ if (node->isAssignment())
+ {
+ ASSERT(!isLValueRequiredHere());
+ setOperatorRequiresLValue(true);
+ }
+
+ node->getLeft()->traverse(this);
+
+ if (node->isAssignment())
+ setOperatorRequiresLValue(false);
+
+ if (inVisit)
+ visit = node->visit(InVisit, this);
+
+ if (visit)
+ {
+ // Some binary operations like indexing can be inside an expression which must be an
+ // l-value.
+ bool parentOperatorRequiresLValue = operatorRequiresLValue();
+ bool parentInFunctionCallOutParameter = isInFunctionCallOutParameter();
+
+ // Index is not required to be an l-value even when the surrounding expression is
+ // required to be an l-value.
+ TOperator op = node->getOp();
+ if (op == EOpIndexDirect || op == EOpIndexDirectInterfaceBlock ||
+ op == EOpIndexDirectStruct || op == EOpIndexIndirect)
+ {
+ setOperatorRequiresLValue(false);
+ setInFunctionCallOutParameter(false);
+ }
+
+ node->getRight()->traverse(this);
+
+ setOperatorRequiresLValue(parentOperatorRequiresLValue);
+ setInFunctionCallOutParameter(parentInFunctionCallOutParameter);
+
+ // Visit the node after the children, if requested and the traversal
+ // hasn't been cancelled yet.
+ if (postVisit)
+ visit = node->visit(PostVisit, this);
+ }
+ }
+}
+
+void TIntermTraverser::traverseUnary(TIntermUnary *node)
+{
+ traverse(node);
+}
+
+void TLValueTrackingTraverser::traverseUnary(TIntermUnary *node)
+{
+ ScopedNodeInTraversalPath addToPath(this, node);
+ if (!addToPath.isWithinDepthLimit())
+ return;
+
+ bool visit = true;
+
+ if (preVisit)
+ visit = node->visit(PreVisit, this);
+
+ if (visit)
+ {
+ ASSERT(!operatorRequiresLValue());
+ switch (node->getOp())
+ {
+ case EOpPostIncrement:
+ case EOpPostDecrement:
+ case EOpPreIncrement:
+ case EOpPreDecrement:
+ setOperatorRequiresLValue(true);
+ break;
+ default:
+ break;
+ }
+
+ node->getOperand()->traverse(this);
+
+ setOperatorRequiresLValue(false);
+
+ if (postVisit)
+ visit = node->visit(PostVisit, this);
+ }
+}
+
+// Traverse a function definition node. This keeps track of global scope.
+void TIntermTraverser::traverseFunctionDefinition(TIntermFunctionDefinition *node)
+{
+ ScopedNodeInTraversalPath addToPath(this, node);
+ if (!addToPath.isWithinDepthLimit())
+ return;
+
+ bool visit = true;
+
+ if (preVisit)
+ visit = node->visit(PreVisit, this);
+
+ if (visit)
+ {
+ mCurrentChildIndex = 0;
+ node->getFunctionPrototype()->traverse(this);
+ mCurrentChildIndex = 0;
+
+ if (inVisit)
+ visit = node->visit(InVisit, this);
+ if (visit)
+ {
+ mInGlobalScope = false;
+ mCurrentChildIndex = 1;
+ node->getBody()->traverse(this);
+ mCurrentChildIndex = 1;
+ mInGlobalScope = true;
+ if (postVisit)
+ visit = node->visit(PostVisit, this);
+ }
+ }
+}
+
+// Traverse a block node. This keeps track of the position of traversed child nodes within the block
+// so that nodes may be inserted before or after them.
+void TIntermTraverser::traverseBlock(TIntermBlock *node)
+{
+ ScopedNodeInTraversalPath addToPath(this, node);
+ if (!addToPath.isWithinDepthLimit())
+ return;
+
+ pushParentBlock(node);
+
+ bool visit = true;
+
+ TIntermSequence *sequence = node->getSequence();
+
+ if (preVisit)
+ visit = node->visit(PreVisit, this);
+
+ if (visit)
+ {
+ for (size_t childIndex = 0; childIndex < sequence->size(); ++childIndex)
+ {
+ TIntermNode *child = (*sequence)[childIndex];
+ if (visit)
+ {
+ mCurrentChildIndex = childIndex;
+ child->traverse(this);
+ mCurrentChildIndex = childIndex;
+
+ if (inVisit)
+ {
+ if (child != sequence->back())
+ visit = node->visit(InVisit, this);
+ }
+
+ incrementParentBlockPos();
+ }
+ }
+
+ if (visit && postVisit)
+ visit = node->visit(PostVisit, this);
+ }
+
+ popParentBlock();
+}
+
+void TIntermTraverser::traverseAggregate(TIntermAggregate *node)
+{
+ traverse(node);
+}
+
+bool TIntermTraverser::CompareInsertion(const NodeInsertMultipleEntry &a,
+ const NodeInsertMultipleEntry &b)
+{
+ if (a.parent != b.parent)
+ {
+ return a.parent < b.parent;
+ }
+ return a.position < b.position;
+}
+
+bool TIntermTraverser::updateTree(TCompiler *compiler, TIntermNode *node)
+{
+ // Sort the insertions so that insertion position is increasing and same position insertions are
+ // not reordered. The insertions are processed in reverse order so that multiple insertions to
+ // the same parent node are handled correctly.
+ std::stable_sort(mInsertions.begin(), mInsertions.end(), CompareInsertion);
+ for (size_t ii = 0; ii < mInsertions.size(); ++ii)
+ {
+ // If two insertions are to the same position, insert them in the order they were specified.
+ // The std::stable_sort call above will automatically guarantee this.
+ const NodeInsertMultipleEntry &insertion = mInsertions[mInsertions.size() - ii - 1];
+ ASSERT(insertion.parent);
+ if (!insertion.insertionsAfter.empty())
+ {
+ bool inserted = insertion.parent->insertChildNodes(insertion.position + 1,
+ insertion.insertionsAfter);
+ ASSERT(inserted);
+ }
+ if (!insertion.insertionsBefore.empty())
+ {
+ bool inserted =
+ insertion.parent->insertChildNodes(insertion.position, insertion.insertionsBefore);
+ ASSERT(inserted);
+ }
+ }
+ for (size_t ii = 0; ii < mReplacements.size(); ++ii)
+ {
+ const NodeUpdateEntry &replacement = mReplacements[ii];
+ ASSERT(replacement.parent);
+ bool replaced =
+ replacement.parent->replaceChildNode(replacement.original, replacement.replacement);
+ ASSERT(replaced);
+
+ // Make sure the precision is not accidentally dropped. It's ok if the precision is not the
+ // same, as the transformations are allowed to replace an expression with one that is
+ // temporarily evaluated at a different (likely higher) precision.
+ TIntermTyped *originalAsTyped = replacement.original->getAsTyped();
+ TIntermTyped *replacementAsTyped =
+ replacement.replacement ? replacement.replacement->getAsTyped() : nullptr;
+ if (originalAsTyped != nullptr && replacementAsTyped != nullptr)
+ {
+ const TType &originalType = originalAsTyped->getType();
+ const TType &replacementType = replacementAsTyped->getType();
+ ASSERT(!IsPrecisionApplicableToType(originalType.getBasicType()) ||
+ !IsPrecisionApplicableToType(replacementType.getBasicType()) ||
+ originalType.getPrecision() == EbpUndefined ||
+ replacementType.getPrecision() != EbpUndefined);
+ }
+
+ if (!replacement.originalBecomesChildOfReplacement)
+ {
+ // In AST traversing, a parent is visited before its children.
+ // After we replace a node, if its immediate child is to
+ // be replaced, we need to make sure we don't update the replaced
+ // node; instead, we update the replacement node.
+ for (size_t jj = ii + 1; jj < mReplacements.size(); ++jj)
+ {
+ NodeUpdateEntry &replacement2 = mReplacements[jj];
+ if (replacement2.parent == replacement.original)
+ replacement2.parent = replacement.replacement;
+ }
+ }
+ }
+ for (size_t ii = 0; ii < mMultiReplacements.size(); ++ii)
+ {
+ const NodeReplaceWithMultipleEntry &replacement = mMultiReplacements[ii];
+ ASSERT(replacement.parent);
+ bool replaced = replacement.parent->replaceChildNodeWithMultiple(replacement.original,
+ replacement.replacements);
+ ASSERT(replaced);
+ }
+
+ clearReplacementQueue();
+
+ return compiler->validateAST(node);
+}
+
+void TIntermTraverser::clearReplacementQueue()
+{
+ mReplacements.clear();
+ mMultiReplacements.clear();
+ mInsertions.clear();
+}
+
+void TIntermTraverser::queueReplacement(TIntermNode *replacement, OriginalNode originalStatus)
+{
+ queueReplacementWithParent(getParentNode(), mPath.back(), 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));
+}
+
+void TIntermTraverser::queueAccessChainReplacement(TIntermTyped *replacement)
+{
+ uint32_t ancestorIndex = 0;
+ TIntermTyped *toReplace = nullptr;
+ while (true)
+ {
+ TIntermNode *ancestor = getAncestorNode(ancestorIndex);
+ ASSERT(ancestor != nullptr);
+
+ TIntermBinary *asBinary = ancestor->getAsBinaryNode();
+ if (asBinary == nullptr ||
+ (asBinary->getOp() != EOpIndexDirect && asBinary->getOp() != EOpIndexIndirect))
+ {
+ break;
+ }
+
+ replacement = new TIntermBinary(asBinary->getOp(), replacement, asBinary->getRight());
+ toReplace = asBinary;
+
+ ++ancestorIndex;
+ }
+
+ if (toReplace == nullptr)
+ {
+ queueReplacement(replacement, OriginalNode::IS_DROPPED);
+ }
+ else
+ {
+ queueReplacementWithParent(getAncestorNode(ancestorIndex), toReplace, replacement,
+ OriginalNode::IS_DROPPED);
+ }
+}
+
+TLValueTrackingTraverser::TLValueTrackingTraverser(bool preVisitIn,
+ bool inVisitIn,
+ bool postVisitIn,
+ TSymbolTable *symbolTable)
+ : TIntermTraverser(preVisitIn, inVisitIn, postVisitIn, symbolTable),
+ mOperatorRequiresLValue(false),
+ mInFunctionCallOutParameter(false)
+{
+ ASSERT(symbolTable);
+}
+
+void TLValueTrackingTraverser::traverseAggregate(TIntermAggregate *node)
+{
+ ScopedNodeInTraversalPath addToPath(this, node);
+ if (!addToPath.isWithinDepthLimit())
+ return;
+
+ bool visit = true;
+
+ TIntermSequence *sequence = node->getSequence();
+
+ if (preVisit)
+ visit = node->visit(PreVisit, this);
+
+ if (visit)
+ {
+ size_t paramIndex = 0u;
+ for (auto *child : *sequence)
+ {
+ if (visit)
+ {
+ if (node->getFunction())
+ {
+ // Both built-ins and user defined functions should have the function symbol
+ // set.
+ ASSERT(paramIndex < node->getFunction()->getParamCount());
+ TQualifier qualifier =
+ node->getFunction()->getParam(paramIndex)->getType().getQualifier();
+ setInFunctionCallOutParameter(qualifier == EvqParamOut ||
+ qualifier == EvqParamInOut);
+ ++paramIndex;
+ }
+ else
+ {
+ ASSERT(node->isConstructor());
+ }
+ child->traverse(this);
+ if (inVisit)
+ {
+ if (child != sequence->back())
+ visit = node->visit(InVisit, this);
+ }
+ }
+ }
+ setInFunctionCallOutParameter(false);
+
+ if (visit && postVisit)
+ visit = node->visit(PostVisit, this);
+ }
+}
+
+void TIntermTraverser::traverseLoop(TIntermLoop *node)
+{
+ traverse(node);
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/IntermTraverse.h b/gfx/angle/checkout/src/compiler/translator/tree_util/IntermTraverse.h
new file mode 100644
index 0000000000..3a48556a1f
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/IntermTraverse.h
@@ -0,0 +1,379 @@
+//
+// Copyright 2017 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.
+//
+// IntermTraverse.h : base classes for AST traversers that walk the AST and
+// also have the ability to transform it by replacing nodes.
+
+#ifndef COMPILER_TRANSLATOR_TREEUTIL_INTERMTRAVERSE_H_
+#define COMPILER_TRANSLATOR_TREEUTIL_INTERMTRAVERSE_H_
+
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/tree_util/Visit.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TSymbolTable;
+class TSymbolUniqueId;
+
+// For traversing the tree. User should derive from this class overriding the visit functions,
+// and then pass an object of the subclass to a traverse method of a node.
+//
+// The traverse*() functions may also be overridden to do other bookkeeping on the tree to provide
+// contextual information to the visit functions, such as whether the node is the target of an
+// assignment. This is complex to maintain and so should only be done in special cases.
+//
+// When using this, just fill in the methods for nodes you want visited.
+// Return false from a pre-visit to skip visiting that node's subtree.
+//
+// See also how to write AST transformations documentation:
+// https://github.com/google/angle/blob/master/doc/WritingShaderASTTransformations.md
+class TIntermTraverser : angle::NonCopyable
+{
+ public:
+ POOL_ALLOCATOR_NEW_DELETE
+ TIntermTraverser(bool preVisitIn,
+ bool inVisitIn,
+ bool postVisitIn,
+ TSymbolTable *symbolTable = nullptr);
+ virtual ~TIntermTraverser();
+
+ virtual void visitSymbol(TIntermSymbol *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 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 void visitFunctionPrototype(TIntermFunctionPrototype *node) {}
+ virtual bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node)
+ {
+ return true;
+ }
+ virtual bool visitAggregate(Visit visit, TIntermAggregate *node) { return true; }
+ virtual bool visitBlock(Visit visit, TIntermBlock *node) { return true; }
+ virtual bool visitGlobalQualifierDeclaration(Visit visit,
+ TIntermGlobalQualifierDeclaration *node)
+ {
+ return true;
+ }
+ virtual bool visitDeclaration(Visit visit, TIntermDeclaration *node) { return true; }
+ virtual bool visitLoop(Visit visit, TIntermLoop *node) { return true; }
+ virtual bool visitBranch(Visit visit, TIntermBranch *node) { return true; }
+ virtual void visitPreprocessorDirective(TIntermPreprocessorDirective *node) {}
+
+ // The traverse functions contain logic for iterating over the children of the node
+ // and calling the visit functions in the appropriate places. They also track some
+ // context that may be used by the visit functions.
+
+ // The generic traverse() function is used for nodes that don't need special handling.
+ // It's templated in order to avoid virtual function calls, this gains around 2% compiler
+ // performance.
+ template <typename T>
+ void traverse(T *node);
+
+ // Specialized traverse functions are implemented for node types where traversal logic may need
+ // to be overridden or where some special bookkeeping needs to be done.
+ virtual void traverseBinary(TIntermBinary *node);
+ virtual void traverseUnary(TIntermUnary *node);
+ virtual void traverseFunctionDefinition(TIntermFunctionDefinition *node);
+ virtual void traverseAggregate(TIntermAggregate *node);
+ virtual void traverseBlock(TIntermBlock *node);
+ virtual void traverseLoop(TIntermLoop *node);
+
+ int getMaxDepth() const { return mMaxDepth; }
+
+ // If traversers need to replace nodes, they can add the replacements in
+ // mReplacements/mMultiReplacements during traversal and the user of the traverser should call
+ // this function after traversal to perform them.
+ //
+ // Compiler is used to validate the tree. Node is the same given to traverse(). Returns false
+ // if the tree is invalid after update.
+ [[nodiscard]] bool updateTree(TCompiler *compiler, TIntermNode *node);
+
+ protected:
+ void setMaxAllowedDepth(int depth);
+
+ // Should only be called from traverse*() functions
+ bool incrementDepth(TIntermNode *current)
+ {
+ mMaxDepth = std::max(mMaxDepth, static_cast<int>(mPath.size()));
+ mPath.push_back(current);
+ return mMaxDepth < mMaxAllowedDepth;
+ }
+
+ // Should only be called from traverse*() functions
+ void decrementDepth() { mPath.pop_back(); }
+
+ int getCurrentTraversalDepth() const { return static_cast<int>(mPath.size()) - 1; }
+ int getCurrentBlockDepth() const { return static_cast<int>(mParentBlockStack.size()) - 1; }
+
+ // RAII helper for incrementDepth/decrementDepth
+ class [[nodiscard]] ScopedNodeInTraversalPath
+ {
+ public:
+ ScopedNodeInTraversalPath(TIntermTraverser *traverser, TIntermNode *current)
+ : mTraverser(traverser)
+ {
+ mWithinDepthLimit = mTraverser->incrementDepth(current);
+ }
+ ~ScopedNodeInTraversalPath() { mTraverser->decrementDepth(); }
+
+ bool isWithinDepthLimit() { return mWithinDepthLimit; }
+
+ private:
+ TIntermTraverser *mTraverser;
+ bool mWithinDepthLimit;
+ };
+ // Optimized traversal functions for leaf nodes directly access ScopedNodeInTraversalPath.
+ friend void TIntermSymbol::traverse(TIntermTraverser *);
+ friend void TIntermConstantUnion::traverse(TIntermTraverser *);
+ friend void TIntermFunctionPrototype::traverse(TIntermTraverser *);
+
+ TIntermNode *getParentNode() const
+ {
+ return mPath.size() <= 1 ? nullptr : mPath[mPath.size() - 2u];
+ }
+
+ // Return the nth ancestor of the node being traversed. getAncestorNode(0) == getParentNode()
+ TIntermNode *getAncestorNode(unsigned int n) const
+ {
+ if (mPath.size() > n + 1u)
+ {
+ return mPath[mPath.size() - n - 2u];
+ }
+ return nullptr;
+ }
+
+ // Returns what child index is currently being visited. For example when visiting the children
+ // of an aggregate, it can be used to find out which argument of the parent (aggregate) node
+ // they correspond to. Only valid in the PreVisit call of the child.
+ size_t getParentChildIndex(Visit visit) const
+ {
+ ASSERT(visit == PreVisit);
+ return mCurrentChildIndex;
+ }
+ // Returns what child index has just been processed. Only valid in the InVisit and PostVisit
+ // calls of the parent node.
+ size_t getLastTraversedChildIndex(Visit visit) const
+ {
+ ASSERT(visit != PreVisit);
+ return mCurrentChildIndex;
+ }
+
+ const TIntermBlock *getParentBlock() const;
+
+ TIntermNode *getRootNode() const
+ {
+ ASSERT(!mPath.empty());
+ return mPath.front();
+ }
+
+ void pushParentBlock(TIntermBlock *node);
+ void incrementParentBlockPos();
+ void popParentBlock();
+
+ // To replace a single node with multiple nodes in the parent aggregate. May be used with blocks
+ // but also with other nodes like declarations.
+ struct NodeReplaceWithMultipleEntry
+ {
+ NodeReplaceWithMultipleEntry(TIntermAggregateBase *parentIn,
+ TIntermNode *originalIn,
+ TIntermSequence &&replacementsIn)
+ : parent(parentIn), original(originalIn), replacements(std::move(replacementsIn))
+ {}
+
+ TIntermAggregateBase *parent;
+ TIntermNode *original;
+ TIntermSequence replacements;
+ };
+
+ // Helper to insert statements in the parent block 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 if called from block nodes.
+ // Note that two insertions to the same position in the same block are not supported.
+ void insertStatementsInParentBlock(const TIntermSequence &insertions);
+
+ // Same as above, but supports simultaneous insertion of statements before and after the node
+ // currently being traversed.
+ void insertStatementsInParentBlock(const TIntermSequence &insertionsBefore,
+ const TIntermSequence &insertionsAfter);
+
+ // Helper to insert a single statement.
+ void insertStatementInParentBlock(TIntermNode *statement);
+
+ // Explicitly specify where to insert statements. The statements are inserted before and after
+ // the specified position. The statements will be inserted once updateTree is called. Note that
+ // two insertions to the same position in the same block are not supported.
+ void insertStatementsInBlockAtPosition(TIntermBlock *parent,
+ size_t position,
+ const TIntermSequence &insertionsBefore,
+ const TIntermSequence &insertionsAfter);
+
+ enum class OriginalNode
+ {
+ BECOMES_CHILD,
+ IS_DROPPED
+ };
+
+ void clearReplacementQueue();
+
+ // Replace the node currently being visited with replacement.
+ void queueReplacement(TIntermNode *replacement, OriginalNode originalStatus);
+ // Explicitly specify a node to replace with replacement.
+ void queueReplacementWithParent(TIntermNode *parent,
+ TIntermNode *original,
+ TIntermNode *replacement,
+ OriginalNode originalStatus);
+ // Walk the ancestors and replace the access chain that leads to this symbol. This fixes up the
+ // types of the intermediate nodes, so it should be used when the type of the symbol changes.
+ // The AST transformation must still visit the (indirect) index nodes to transform the
+ // expression inside those nodes. Note that due to the way these replacements work, the AST
+ // transformation should not attempt to replace the actual index node itself, but only a subnode
+ // of that.
+ //
+ // Node 1 Node 6
+ // EOpIndexDirect EOpIndexDirect
+ // / \ / \
+ // Node 2 Node 3 Node 7 Node 3
+ // EOpIndexIndirect N --> replaced with --> EOpIndexIndirect N
+ // / \ / \
+ // Node 4 Node 5 Node 8 Node 5
+ // symbol expression replacement expression
+ // ^ ^
+ // | |
+ // This symbol is being replaced, This node is directly placed in the
+ // and the replacement is given new access chain, and its parent is
+ // to this function. is changed. This is why a
+ // replacment attempt for this node
+ // itself will not work.
+ //
+ void queueAccessChainReplacement(TIntermTyped *replacement);
+
+ const bool preVisit;
+ const bool inVisit;
+ const bool postVisit;
+
+ int mMaxDepth;
+ int mMaxAllowedDepth;
+
+ 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;
+
+ TSymbolTable *mSymbolTable;
+
+ private:
+ // To insert multiple nodes into the parent block.
+ struct NodeInsertMultipleEntry
+ {
+ NodeInsertMultipleEntry(TIntermBlock *_parent,
+ TIntermSequence::size_type _position,
+ TIntermSequence _insertionsBefore,
+ TIntermSequence _insertionsAfter)
+ : parent(_parent),
+ position(_position),
+ insertionsBefore(_insertionsBefore),
+ insertionsAfter(_insertionsAfter)
+ {}
+
+ TIntermBlock *parent;
+ TIntermSequence::size_type position;
+ TIntermSequence insertionsBefore;
+ TIntermSequence insertionsAfter;
+ };
+
+ static bool CompareInsertion(const NodeInsertMultipleEntry &a,
+ const NodeInsertMultipleEntry &b);
+
+ // 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(TIntermBlock *nodeIn, TIntermSequence::size_type posIn)
+ : node(nodeIn), pos(posIn)
+ {}
+
+ TIntermBlock *node;
+ TIntermSequence::size_type pos;
+ };
+
+ std::vector<NodeInsertMultipleEntry> mInsertions;
+ std::vector<NodeUpdateEntry> mReplacements;
+
+ // All the nodes from root to the current node during traversing.
+ TVector<TIntermNode *> mPath;
+ // The current child of parent being traversed.
+ size_t mCurrentChildIndex;
+
+ // All the code blocks from the root to the current node's parent during traversal.
+ std::vector<ParentBlock> mParentBlockStack;
+};
+
+// Traverser parent class that tracks where a node is a destination of a write operation and so is
+// required to be an l-value.
+class TLValueTrackingTraverser : public TIntermTraverser
+{
+ public:
+ TLValueTrackingTraverser(bool preVisit,
+ bool inVisit,
+ bool postVisit,
+ TSymbolTable *symbolTable);
+ ~TLValueTrackingTraverser() override {}
+
+ void traverseBinary(TIntermBinary *node) final;
+ void traverseUnary(TIntermUnary *node) final;
+ void traverseAggregate(TIntermAggregate *node) final;
+
+ protected:
+ bool isLValueRequiredHere() const
+ {
+ return mOperatorRequiresLValue || mInFunctionCallOutParameter;
+ }
+
+ private:
+ // Track whether an l-value is required in the node that is currently being traversed by the
+ // surrounding operator.
+ // Use isLValueRequiredHere to check all conditions which require an l-value.
+ void setOperatorRequiresLValue(bool lValueRequired)
+ {
+ mOperatorRequiresLValue = lValueRequired;
+ }
+ bool operatorRequiresLValue() const { return mOperatorRequiresLValue; }
+
+ // Track whether an l-value is required inside a function call.
+ void setInFunctionCallOutParameter(bool inOutParameter);
+ bool isInFunctionCallOutParameter() const;
+
+ bool mOperatorRequiresLValue;
+ bool mInFunctionCallOutParameter;
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEUTIL_INTERMTRAVERSE_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/NodeSearch.h b/gfx/angle/checkout/src/compiler/translator/tree_util/NodeSearch.h
new file mode 100644
index 0000000000..7764a2ebe3
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/NodeSearch.h
@@ -0,0 +1,56 @@
+//
+// Copyright 2002 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.
+//
+// NodeSearch.h: Utilities for searching translator node graphs
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEUTIL_NODESEARCH_H_
+#define COMPILER_TRANSLATOR_TREEUTIL_NODESEARCH_H_
+
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+template <class Parent>
+class NodeSearchTraverser : public TIntermTraverser
+{
+ public:
+ NodeSearchTraverser() : TIntermTraverser(true, false, false), mFound(false) {}
+
+ bool found() const { return mFound; }
+
+ static bool search(TIntermNode *node)
+ {
+ Parent searchTraverser;
+ node->traverse(&searchTraverser);
+ return searchTraverser.found();
+ }
+
+ protected:
+ bool mFound;
+};
+
+class FindDiscard : public NodeSearchTraverser<FindDiscard>
+{
+ public:
+ bool visitBranch(Visit visit, TIntermBranch *node) override
+ {
+ switch (node->getFlowOp())
+ {
+ case EOpKill:
+ mFound = true;
+ break;
+
+ default:
+ break;
+ }
+
+ return !mFound;
+ }
+};
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEUTIL_NODESEARCH_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/NodeType.h b/gfx/angle/checkout/src/compiler/translator/tree_util/NodeType.h
new file mode 100644
index 0000000000..4ab63dbebb
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/NodeType.h
@@ -0,0 +1,155 @@
+//
+// Copyright 2020 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_TRANSLATORMETALDIRECT_NODETYPE_H_
+#define COMPILER_TRANSLATOR_TRANSLATORMETALDIRECT_NODETYPE_H_
+
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+enum class NodeType
+{
+ Unknown,
+ Symbol,
+ ConstantUnion,
+ FunctionPrototype,
+ PreprocessorDirective,
+ Unary,
+ Binary,
+ Ternary,
+ Swizzle,
+ IfElse,
+ Switch,
+ Case,
+ FunctionDefinition,
+ Aggregate,
+ Block,
+ GlobalQualifierDeclaration,
+ Declaration,
+ Loop,
+ Branch,
+};
+
+// This is a function like object instead of a function that stack allocates this because
+// TIntermTraverser is a heavy object to construct.
+class GetNodeType : private TIntermTraverser
+{
+ NodeType nodeType;
+
+ public:
+ GetNodeType() : TIntermTraverser(true, false, false) {}
+
+ NodeType operator()(TIntermNode &node)
+ {
+ node.visit(Visit::PreVisit, this);
+ return nodeType;
+ }
+
+ private:
+ void visitSymbol(TIntermSymbol *) override { nodeType = NodeType::Symbol; }
+
+ void visitConstantUnion(TIntermConstantUnion *) override { nodeType = NodeType::ConstantUnion; }
+
+ void visitFunctionPrototype(TIntermFunctionPrototype *) override
+ {
+ nodeType = NodeType::FunctionPrototype;
+ }
+
+ void visitPreprocessorDirective(TIntermPreprocessorDirective *) override
+ {
+ nodeType = NodeType::PreprocessorDirective;
+ }
+
+ bool visitSwizzle(Visit, TIntermSwizzle *) override
+ {
+ nodeType = NodeType::Swizzle;
+ return false;
+ }
+
+ bool visitBinary(Visit, TIntermBinary *) override
+ {
+ nodeType = NodeType::Binary;
+ return false;
+ }
+
+ bool visitUnary(Visit, TIntermUnary *) override
+ {
+ nodeType = NodeType::Unary;
+ return false;
+ }
+
+ bool visitTernary(Visit, TIntermTernary *) override
+ {
+ nodeType = NodeType::Ternary;
+ return false;
+ }
+
+ bool visitIfElse(Visit, TIntermIfElse *) override
+ {
+ nodeType = NodeType::IfElse;
+ return false;
+ }
+
+ bool visitSwitch(Visit, TIntermSwitch *) override
+ {
+ nodeType = NodeType::Switch;
+ return false;
+ }
+
+ bool visitCase(Visit, TIntermCase *) override
+ {
+ nodeType = NodeType::Case;
+ return false;
+ }
+
+ bool visitFunctionDefinition(Visit, TIntermFunctionDefinition *) override
+ {
+ nodeType = NodeType::FunctionDefinition;
+ return false;
+ }
+
+ bool visitAggregate(Visit, TIntermAggregate *) override
+ {
+ nodeType = NodeType::Aggregate;
+ return false;
+ }
+
+ bool visitBlock(Visit, TIntermBlock *) override
+ {
+ nodeType = NodeType::Block;
+ return false;
+ }
+
+ bool visitGlobalQualifierDeclaration(Visit, TIntermGlobalQualifierDeclaration *) override
+ {
+ nodeType = NodeType::GlobalQualifierDeclaration;
+ return false;
+ }
+
+ bool visitDeclaration(Visit, TIntermDeclaration *) override
+ {
+ nodeType = NodeType::Declaration;
+ return false;
+ }
+
+ bool visitLoop(Visit, TIntermLoop *) override
+ {
+ nodeType = NodeType::Loop;
+ return false;
+ }
+
+ bool visitBranch(Visit, TIntermBranch *) override
+ {
+ nodeType = NodeType::Branch;
+ return false;
+ }
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TRANSLATORMETALDIRECT_NODETYPE_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceArrayOfMatrixVarying.cpp b/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceArrayOfMatrixVarying.cpp
new file mode 100644
index 0000000000..ddbb22685d
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceArrayOfMatrixVarying.cpp
@@ -0,0 +1,175 @@
+//
+// Copyright 2020 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.
+//
+// ReplaceArrayOfMatrixVarying: Find any references to array of matrices varying
+// and replace it with array of vectors.
+//
+
+#include "compiler/translator/tree_util/ReplaceArrayOfMatrixVarying.h"
+
+#include <vector>
+
+#include "common/bitset_utils.h"
+#include "common/debug.h"
+#include "common/utilities.h"
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/BuiltIn.h"
+#include "compiler/translator/tree_util/FindMain.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/tree_util/ReplaceVariable.h"
+#include "compiler/translator/tree_util/RunAtTheEndOfShader.h"
+#include "compiler/translator/util.h"
+
+namespace sh
+{
+
+// We create two variables to replace the given varying:
+// - The new varying which is an array of vectors to be used at input/ouput only.
+// - The new global variable which is a same type as given variable, to temporarily be used
+// as replacements for assignments, arithmetic ops and so on. During input/ouput phrase, this temp
+// variable will be copied from/to the array of vectors variable above.
+// NOTE(hqle): Consider eliminating the need for using temp variable.
+
+namespace
+{
+class CollectVaryingTraverser : public TIntermTraverser
+{
+ public:
+ CollectVaryingTraverser(std::vector<const TVariable *> *varyingsOut)
+ : TIntermTraverser(true, false, false), mVaryingsOut(varyingsOut)
+ {}
+
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override
+ {
+ const TIntermSequence &sequence = *(node->getSequence());
+
+ if (sequence.size() != 1)
+ {
+ return false;
+ }
+
+ TIntermTyped *variableType = sequence.front()->getAsTyped();
+ if (!variableType || !IsVarying(variableType->getQualifier()) ||
+ !variableType->isMatrix() || !variableType->isArray())
+ {
+ return false;
+ }
+
+ TIntermSymbol *variableSymbol = variableType->getAsSymbolNode();
+ if (!variableSymbol)
+ {
+ return false;
+ }
+
+ mVaryingsOut->push_back(&variableSymbol->variable());
+
+ return false;
+ }
+
+ private:
+ std::vector<const TVariable *> *mVaryingsOut;
+};
+} // namespace
+
+[[nodiscard]] bool ReplaceArrayOfMatrixVarying(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ const TVariable *varying)
+{
+ const TType &type = varying->getType();
+
+ // Create global variable to temporarily acts as the given variable in places such as
+ // arithmetic, assignments an so on.
+ TType *tmpReplacementType = new TType(type);
+ tmpReplacementType->setQualifier(EvqGlobal);
+
+ TVariable *tempReplaceVar = new TVariable(
+ symbolTable, ImmutableString(std::string("ANGLE_AOM_Temp_") + varying->name().data()),
+ tmpReplacementType, SymbolType::AngleInternal);
+
+ if (!ReplaceVariable(compiler, root, varying, tempReplaceVar))
+ {
+ return false;
+ }
+
+ // Create array of vectors type
+ TType *varyingReplaceType = new TType(type);
+ varyingReplaceType->toMatrixColumnType();
+ varyingReplaceType->toArrayElementType();
+ varyingReplaceType->makeArray(type.getCols() * type.getOutermostArraySize());
+
+ TVariable *varyingReplaceVar =
+ new TVariable(symbolTable, varying->name(), varyingReplaceType, SymbolType::UserDefined);
+
+ TIntermSymbol *varyingReplaceDeclarator = new TIntermSymbol(varyingReplaceVar);
+ TIntermDeclaration *varyingReplaceDecl = new TIntermDeclaration;
+ varyingReplaceDecl->appendDeclarator(varyingReplaceDeclarator);
+ root->insertStatement(0, varyingReplaceDecl);
+
+ // Copy from/to the temp variable
+ TIntermBlock *reassignBlock = new TIntermBlock;
+ TIntermSymbol *tempReplaceSymbol = new TIntermSymbol(tempReplaceVar);
+ TIntermSymbol *varyingReplaceSymbol = new TIntermSymbol(varyingReplaceVar);
+ bool isInput = IsVaryingIn(type.getQualifier());
+
+ for (unsigned int i = 0; i < type.getOutermostArraySize(); ++i)
+ {
+ TIntermBinary *tempMatrixIndexed =
+ new TIntermBinary(EOpIndexDirect, tempReplaceSymbol->deepCopy(), CreateIndexNode(i));
+ for (uint8_t col = 0; col < type.getCols(); ++col)
+ {
+
+ TIntermBinary *tempMatrixColIndexed = new TIntermBinary(
+ EOpIndexDirect, tempMatrixIndexed->deepCopy(), CreateIndexNode(col));
+ TIntermBinary *vectorIndexed =
+ new TIntermBinary(EOpIndexDirect, varyingReplaceSymbol->deepCopy(),
+ CreateIndexNode(i * type.getCols() + col));
+ TIntermBinary *assignment;
+ if (isInput)
+ {
+ assignment = new TIntermBinary(EOpAssign, tempMatrixColIndexed, vectorIndexed);
+ }
+ else
+ {
+ assignment = new TIntermBinary(EOpAssign, vectorIndexed, tempMatrixColIndexed);
+ }
+ reassignBlock->appendStatement(assignment);
+ }
+ }
+
+ if (isInput)
+ {
+ TIntermFunctionDefinition *main = FindMain(root);
+ main->getBody()->insertStatement(0, reassignBlock);
+ return compiler->validateAST(root);
+ }
+ else
+ {
+ return RunAtTheEndOfShader(compiler, root, reassignBlock, symbolTable);
+ }
+}
+
+[[nodiscard]] bool ReplaceArrayOfMatrixVaryings(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable)
+{
+ std::vector<const TVariable *> arrayOfMatrixVars;
+ CollectVaryingTraverser varCollector(&arrayOfMatrixVars);
+ root->traverse(&varCollector);
+
+ for (const TVariable *var : arrayOfMatrixVars)
+ {
+ if (!ReplaceArrayOfMatrixVarying(compiler, root, symbolTable, var))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceArrayOfMatrixVarying.h b/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceArrayOfMatrixVarying.h
new file mode 100644
index 0000000000..62b6b320af
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceArrayOfMatrixVarying.h
@@ -0,0 +1,33 @@
+//
+// Copyright 2020 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.
+//
+// ReplaceArrayOfMatrixVarying: Find any references to array of matrices varying
+// and replace it with array of vectors.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEUTIL_REPLACEARRAYOFMATRIXVARYING_H_
+#define COMPILER_TRANSLATOR_TREEUTIL_REPLACEARRAYOFMATRIXVARYING_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+class TVariable;
+
+[[nodiscard]] bool ReplaceArrayOfMatrixVarying(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ const TVariable *varying);
+
+[[nodiscard]] bool ReplaceArrayOfMatrixVaryings(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable);
+} // namespace sh
+
+#endif
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceClipCullDistanceVariable.cpp b/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceClipCullDistanceVariable.cpp
new file mode 100644
index 0000000000..a8379f48f1
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceClipCullDistanceVariable.cpp
@@ -0,0 +1,591 @@
+//
+// Copyright 2020 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.
+//
+// ReplaceClipCullDistanceVariable.cpp: Find any references to gl_ClipDistance or gl_CullDistance
+// and replace it with ANGLEClipDistance or ANGLECullDistance.
+//
+
+#include "compiler/translator/tree_util/ReplaceClipCullDistanceVariable.h"
+
+#include "common/bitset_utils.h"
+#include "common/debug.h"
+#include "common/utilities.h"
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/BuiltIn.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/tree_util/ReplaceVariable.h"
+#include "compiler/translator/tree_util/RunAtTheBeginningOfShader.h"
+#include "compiler/translator/tree_util/RunAtTheEndOfShader.h"
+
+namespace sh
+{
+namespace
+{
+
+using ClipCullDistanceIdxSet = angle::BitSet<32>;
+
+typedef TIntermNode *AssignFunc(const unsigned int index,
+ TIntermSymbol *left,
+ TIntermSymbol *right,
+ const TIntermTyped *enableFlags);
+
+template <typename Variable>
+const Variable *FindVariable(const std::vector<Variable> &mVars, const ImmutableString &name)
+{
+ for (const Variable &var : mVars)
+ {
+ if (name == var.instanceName)
+ {
+ return &var;
+ }
+ }
+
+ return nullptr;
+}
+
+// Traverse the tree and collect the redeclaration and all constant index references of
+// gl_ClipDistance/gl_CullDistance
+class GLClipCullDistanceReferenceTraverser : public TIntermTraverser
+{
+ public:
+ GLClipCullDistanceReferenceTraverser(const TIntermSymbol **redeclaredSymOut,
+ bool *nonConstIdxUsedOut,
+ unsigned int *maxConstIdxOut,
+ ClipCullDistanceIdxSet *constIndicesOut,
+ TQualifier targetQualifier)
+ : TIntermTraverser(true, false, false),
+ mRedeclaredSym(redeclaredSymOut),
+ mUseNonConstClipCullDistanceIndex(nonConstIdxUsedOut),
+ mMaxConstClipCullDistanceIndex(maxConstIdxOut),
+ mConstClipCullDistanceIndices(constIndicesOut),
+ mTargetQualifier(targetQualifier)
+ {
+ *mRedeclaredSym = nullptr;
+ *mUseNonConstClipCullDistanceIndex = false;
+ *mMaxConstClipCullDistanceIndex = 0;
+ mConstClipCullDistanceIndices->reset();
+ }
+
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override
+ {
+ // If gl_ClipDistance/gl_CullDistance is redeclared, we need to collect its information
+ const TIntermSequence &sequence = *(node->getSequence());
+
+ if (sequence.size() != 1)
+ {
+ return true;
+ }
+
+ TIntermSymbol *variable = sequence.front()->getAsSymbolNode();
+ if (variable == nullptr || variable->getType().getQualifier() != mTargetQualifier)
+ {
+ return true;
+ }
+
+ *mRedeclaredSym = variable->getAsSymbolNode();
+
+ return true;
+ }
+
+ bool visitBinary(Visit visit, TIntermBinary *node) override
+ {
+ TOperator op = node->getOp();
+ if (op != EOpIndexDirect && op != EOpIndexIndirect)
+ {
+ return true;
+ }
+
+ // gl_ClipDistance / gl_CullDistance
+ TIntermTyped *left = node->getLeft()->getAsTyped();
+ if (!left)
+ {
+ return true;
+ }
+
+ ASSERT(op == EOpIndexDirect || op == EOpIndexIndirect);
+
+ TIntermSymbol *clipCullDistance = left->getAsSymbolNode();
+ if (!clipCullDistance)
+ {
+ return true;
+ }
+ if (clipCullDistance->getType().getQualifier() != mTargetQualifier)
+ {
+ return true;
+ }
+
+ const TConstantUnion *constIdx = node->getRight()->getConstantValue();
+ if (!constIdx)
+ {
+ *mUseNonConstClipCullDistanceIndex = true;
+ }
+ else
+ {
+ unsigned int idx = 0;
+ switch (constIdx->getType())
+ {
+ case EbtInt:
+ idx = constIdx->getIConst();
+ break;
+ case EbtUInt:
+ idx = constIdx->getUConst();
+ break;
+ case EbtFloat:
+ idx = static_cast<unsigned int>(constIdx->getFConst());
+ break;
+ case EbtBool:
+ idx = constIdx->getBConst() ? 1 : 0;
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ ASSERT(idx < mConstClipCullDistanceIndices->size());
+ mConstClipCullDistanceIndices->set(idx);
+
+ *mMaxConstClipCullDistanceIndex = std::max(*mMaxConstClipCullDistanceIndex, idx);
+ }
+
+ return true;
+ }
+
+ private:
+ const TIntermSymbol **mRedeclaredSym;
+ // Flag indicating whether there is at least one reference of gl_ClipDistance with non-constant
+ // index
+ bool *mUseNonConstClipCullDistanceIndex;
+ // Max constant index that is used to reference gl_ClipDistance
+ unsigned int *mMaxConstClipCullDistanceIndex;
+ // List of constant index reference of gl_ClipDistance
+ ClipCullDistanceIdxSet *mConstClipCullDistanceIndices;
+ // Qualifier for gl_ClipDistance/gl_CullDistance
+ const TQualifier mTargetQualifier;
+};
+
+// Replace all symbolic occurrences of given variables except one symbol.
+class ReplaceVariableExceptOneTraverser : public TIntermTraverser
+{
+ public:
+ ReplaceVariableExceptOneTraverser(const TVariable *toBeReplaced,
+ const TIntermTyped *replacement,
+ const TIntermSymbol *exception)
+ : TIntermTraverser(true, false, false),
+ mToBeReplaced(toBeReplaced),
+ mException(exception),
+ mReplacement(replacement)
+ {}
+
+ void visitSymbol(TIntermSymbol *node) override
+ {
+ if (&node->variable() == mToBeReplaced && node != mException)
+ {
+ queueReplacement(mReplacement->deepCopy(), OriginalNode::IS_DROPPED);
+ }
+ }
+
+ private:
+ const TVariable *const mToBeReplaced;
+ const TIntermSymbol *const mException;
+ const TIntermTyped *const mReplacement;
+};
+
+TIntermNode *simpleAssignFunc(const unsigned int index,
+ TIntermSymbol *leftSymbol,
+ TIntermSymbol *rightSymbol,
+ const TIntermTyped * /*enableFlags*/)
+{
+ // leftSymbol[index] = rightSymbol[index]
+ // E.g., ANGLEClipDistance[index] = gl_ClipDistance[index]
+ TIntermBinary *left =
+ new TIntermBinary(EOpIndexDirect, leftSymbol->deepCopy(), CreateIndexNode(index));
+ TIntermBinary *right =
+ new TIntermBinary(EOpIndexDirect, rightSymbol->deepCopy(), CreateIndexNode(index));
+
+ return new TIntermBinary(EOpAssign, left, right);
+}
+
+// This is only used for gl_ClipDistance
+TIntermNode *assignFuncWithEnableFlags(const unsigned int index,
+ TIntermSymbol *leftSymbol,
+ TIntermSymbol *rightSymbol,
+ const TIntermTyped *enableFlags)
+{
+ // if (ANGLEUniforms.clipDistancesEnabled & (0x1 << index))
+ // gl_ClipDistance[index] = ANGLEClipDistance[index];
+ // else
+ // gl_ClipDistance[index] = 0;
+ TIntermConstantUnion *bitMask = CreateUIntNode(0x1 << index);
+ TIntermBinary *bitwiseAnd = new TIntermBinary(EOpBitwiseAnd, enableFlags->deepCopy(), bitMask);
+ TIntermBinary *nonZero = new TIntermBinary(EOpNotEqual, bitwiseAnd, CreateUIntNode(0));
+
+ TIntermBinary *left =
+ new TIntermBinary(EOpIndexDirect, leftSymbol->deepCopy(), CreateIndexNode(index));
+ TIntermBinary *right =
+ new TIntermBinary(EOpIndexDirect, rightSymbol->deepCopy(), CreateIndexNode(index));
+ TIntermBinary *assignment = new TIntermBinary(EOpAssign, left, right);
+ TIntermBlock *trueBlock = new TIntermBlock();
+ trueBlock->appendStatement(assignment);
+
+ TIntermBinary *zeroAssignment =
+ new TIntermBinary(EOpAssign, left->deepCopy(), CreateFloatNode(0, EbpMedium));
+ TIntermBlock *falseBlock = new TIntermBlock();
+ falseBlock->appendStatement(zeroAssignment);
+
+ return new TIntermIfElse(nonZero, trueBlock, falseBlock);
+}
+
+class ReplaceClipCullDistanceAssignments : angle::NonCopyable
+{
+ public:
+ ReplaceClipCullDistanceAssignments(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ const TVariable *glClipCullDistanceVar,
+ const TIntermSymbol *redeclaredGlClipDistance,
+ const ImmutableString &angleVarName)
+ : mCompiler(compiler),
+ mRoot(root),
+ mSymbolTable(symbolTable),
+ mGlVar(glClipCullDistanceVar),
+ mRedeclaredGLVar(redeclaredGlClipDistance),
+ mANGLEVarName(angleVarName)
+ {
+ mEnabledDistances = 0;
+ }
+
+ unsigned int getEnabledClipCullDistance(const bool useNonConstIndex,
+ const unsigned int maxConstIndex);
+ const TVariable *declareANGLEVariable(const TVariable *originalVariable);
+ bool assignOriginalValueToANGLEVariable(const GLenum shaderType);
+ bool assignANGLEValueToOriginalVariable(const GLenum shaderType,
+ const bool isRedeclared,
+ const TIntermTyped *enableFlags,
+ const ClipCullDistanceIdxSet *constIndices);
+
+ private:
+ bool assignOriginalValueToANGLEVariableImpl();
+ bool assignANGLEValueToOriginalVariableImpl(const bool isRedeclared,
+ const TIntermTyped *enableFlags,
+ const ClipCullDistanceIdxSet *constIndices,
+ AssignFunc assignFunc);
+
+ // Common variables for replacing gl_Clip/CullDistances with ANGLEClip/CullDistances
+ TCompiler *mCompiler;
+ TIntermBlock *mRoot;
+ TSymbolTable *mSymbolTable;
+
+ const TVariable *mGlVar;
+ const TIntermSymbol *mRedeclaredGLVar;
+ const ImmutableString mANGLEVarName;
+
+ unsigned int mEnabledDistances;
+ const TVariable *mANGLEVar;
+};
+
+unsigned int ReplaceClipCullDistanceAssignments::getEnabledClipCullDistance(
+ const bool useNonConstIndex,
+ const unsigned int maxConstIndex)
+{
+ if (mRedeclaredGLVar)
+ {
+ // If array is redeclared by user, use that redeclared size.
+ mEnabledDistances = mRedeclaredGLVar->getType().getOutermostArraySize();
+ }
+ else if (!useNonConstIndex)
+ {
+ ASSERT(maxConstIndex < mGlVar->getType().getOutermostArraySize());
+ // Only use constant index, then use max array index used.
+ mEnabledDistances = maxConstIndex + 1;
+ }
+
+ return mEnabledDistances;
+}
+
+const TVariable *ReplaceClipCullDistanceAssignments::declareANGLEVariable(
+ const TVariable *originalVariable)
+{
+ ASSERT(mEnabledDistances > 0);
+
+ TType *clipCullDistanceType = new TType(originalVariable->getType());
+ clipCullDistanceType->setQualifier(EvqGlobal);
+ clipCullDistanceType->toArrayBaseType();
+ clipCullDistanceType->makeArray(mEnabledDistances);
+
+ mANGLEVar =
+ new TVariable(mSymbolTable, mANGLEVarName, clipCullDistanceType, SymbolType::AngleInternal);
+
+ TIntermSymbol *clipCullDistanceDeclarator = new TIntermSymbol(mANGLEVar);
+ TIntermDeclaration *clipCullDistanceDecl = new TIntermDeclaration;
+ clipCullDistanceDecl->appendDeclarator(clipCullDistanceDeclarator);
+
+ // Must declare ANGLEClipdistance/ANGLECullDistance before any function, since
+ // gl_ClipDistance/gl_CullDistance might be accessed within a function declared before main.
+ mRoot->insertStatement(0, clipCullDistanceDecl);
+
+ return mANGLEVar;
+}
+
+bool ReplaceClipCullDistanceAssignments::assignOriginalValueToANGLEVariableImpl()
+{
+ ASSERT(mEnabledDistances > 0);
+
+ TIntermBlock *readBlock = new TIntermBlock;
+ TIntermSymbol *glClipCullDistanceSymbol = new TIntermSymbol(mGlVar);
+ TIntermSymbol *clipCullDistanceSymbol = new TIntermSymbol(mANGLEVar);
+
+ for (unsigned int i = 0; i < mEnabledDistances; i++)
+ {
+ readBlock->appendStatement(
+ simpleAssignFunc(i, clipCullDistanceSymbol, glClipCullDistanceSymbol, nullptr));
+ }
+
+ return RunAtTheBeginningOfShader(mCompiler, mRoot, readBlock);
+}
+
+bool ReplaceClipCullDistanceAssignments::assignANGLEValueToOriginalVariableImpl(
+ const bool isRedeclared,
+ const TIntermTyped *enableFlags,
+ const ClipCullDistanceIdxSet *constIndices,
+ AssignFunc assignFunc)
+{
+ ASSERT(mEnabledDistances > 0);
+
+ TIntermBlock *assignBlock = new TIntermBlock;
+ TIntermSymbol *glClipCullDistanceSymbol = new TIntermSymbol(mGlVar);
+ TIntermSymbol *clipCullDistanceSymbol = new TIntermSymbol(mANGLEVar);
+
+ // The array size is decided by either redeclaring the variable or accessing the variable with a
+ // integral constant index. And this size is the count of the enabled value. So, if the index
+ // which is greater than the array size, is used to access the variable, this access will be
+ // ignored.
+ if (isRedeclared || !constIndices)
+ {
+ for (unsigned int i = 0; i < mEnabledDistances; ++i)
+ {
+ assignBlock->appendStatement(
+ assignFunc(i, glClipCullDistanceSymbol, clipCullDistanceSymbol, enableFlags));
+ }
+ }
+ else
+ {
+ // Assign ANGLEClip/CullDistance[i]'s value to gl_Clip/CullDistance[i] if i is in the
+ // constant indices list. Those elements whose index is not in the constant index list will
+ // be zeroise for initialization.
+ for (unsigned int i = 0; i < mEnabledDistances; ++i)
+ {
+ if (constIndices->test(i))
+ {
+ assignBlock->appendStatement(
+ assignFunc(i, glClipCullDistanceSymbol, clipCullDistanceSymbol, enableFlags));
+ }
+ else
+ {
+ // gl_Clip/CullDistance[i] = 0;
+ TIntermBinary *left = new TIntermBinary(
+ EOpIndexDirect, glClipCullDistanceSymbol->deepCopy(), CreateIndexNode(i));
+ TIntermBinary *zeroAssignment =
+ new TIntermBinary(EOpAssign, left, CreateFloatNode(0, EbpMedium));
+ assignBlock->appendStatement(zeroAssignment);
+ }
+ }
+ }
+
+ return RunAtTheEndOfShader(mCompiler, mRoot, assignBlock, mSymbolTable);
+}
+
+[[nodiscard]] bool ReplaceClipCullDistanceAssignments::assignOriginalValueToANGLEVariable(
+ const GLenum shaderType)
+{
+ switch (shaderType)
+ {
+ case GL_VERTEX_SHADER:
+ // Vertex shader can use gl_Clip/CullDistance as a output only
+ break;
+ case GL_FRAGMENT_SHADER:
+ {
+ // These shader types can use gl_Clip/CullDistance as input
+ if (!assignOriginalValueToANGLEVariableImpl())
+ {
+ return false;
+ }
+ break;
+ }
+ default:
+ {
+ UNREACHABLE();
+ return false;
+ }
+ }
+
+ return true;
+}
+
+[[nodiscard]] bool ReplaceClipCullDistanceAssignments::assignANGLEValueToOriginalVariable(
+ const GLenum shaderType,
+ const bool isRedeclared,
+ const TIntermTyped *enableFlags,
+ const ClipCullDistanceIdxSet *constIndices)
+{
+ switch (shaderType)
+ {
+ case GL_VERTEX_SHADER:
+ {
+ // Vertex shader can use gl_Clip/CullDistance as output.
+ // If the enabled gl_Clip/CullDistances are not initialized, results are undefined.
+ // EXT_clip_cull_distance spec :
+ // The shader must also set all values in gl_ClipDistance that have been enabled via the
+ // OpenGL ES API, or results are undefined. Values written into gl_ClipDistance for
+ // planes that are not enabled have no effect.
+ // ...
+ // Shaders writing gl_CullDistance must write all enabled distances, or culling results
+ // are undefined.
+ if (!assignANGLEValueToOriginalVariableImpl(
+ isRedeclared, enableFlags, constIndices,
+ enableFlags ? assignFuncWithEnableFlags : simpleAssignFunc))
+ {
+ return false;
+ }
+ break;
+ }
+ case GL_FRAGMENT_SHADER:
+ // Fragment shader can use gl_Clip/CullDistance as input only
+ break;
+ default:
+ {
+ UNREACHABLE();
+ return false;
+ }
+ }
+
+ return true;
+}
+
+// Common code to transform gl_ClipDistance and gl_CullDistance. Comments reference
+// gl_ClipDistance, but are also applicable to gl_CullDistance.
+[[nodiscard]] bool ReplaceClipCullDistanceAssignmentsImpl(
+ TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ const GLenum shaderType,
+ const TIntermTyped *clipDistanceEnableFlags,
+ const char *builtInName,
+ const char *replacementName,
+ TQualifier builtInQualifier)
+{
+ // Collect all constant index references of gl_ClipDistance
+ ImmutableString name(builtInName);
+ ClipCullDistanceIdxSet constIndices;
+ bool useNonConstIndex = false;
+ const TIntermSymbol *redeclaredBuiltIn = nullptr;
+ unsigned int maxConstIndex = 0;
+ GLClipCullDistanceReferenceTraverser indexTraverser(
+ &redeclaredBuiltIn, &useNonConstIndex, &maxConstIndex, &constIndices, builtInQualifier);
+ root->traverse(&indexTraverser);
+ if (!useNonConstIndex && constIndices.none())
+ {
+ // No references of gl_ClipDistance
+ return true;
+ }
+
+ // Retrieve gl_ClipDistance variable reference
+ // Search user redeclared gl_ClipDistance first
+ const TVariable *builtInVar = nullptr;
+ if (redeclaredBuiltIn)
+ {
+ builtInVar = &redeclaredBuiltIn->variable();
+ }
+ else
+ {
+ // User defined not found, find in built-in table
+ builtInVar = static_cast<const TVariable *>(
+ symbolTable->findBuiltIn(name, compiler->getShaderVersion()));
+ }
+ if (!builtInVar)
+ {
+ return false;
+ }
+
+ ReplaceClipCullDistanceAssignments replacementUtils(compiler, root, symbolTable, builtInVar,
+ redeclaredBuiltIn,
+ ImmutableString(replacementName));
+
+ // Declare a global variable substituting gl_ClipDistance
+ unsigned int enabledClipDistances =
+ replacementUtils.getEnabledClipCullDistance(useNonConstIndex, maxConstIndex);
+ if (!enabledClipDistances)
+ {
+ // Spec :
+ // The gl_ClipDistance array is predeclared as unsized and must be explicitly sized by the
+ // shader either redeclaring it with a size or implicitly sized by indexing it only with
+ // integral constant expressions.
+ return false;
+ }
+
+ const TVariable *replacementVar = replacementUtils.declareANGLEVariable(builtInVar);
+
+ // Replace gl_ClipDistance reference with ANGLEClipDistance, except the declaration
+ ReplaceVariableExceptOneTraverser replaceTraverser(builtInVar,
+ new TIntermSymbol(replacementVar),
+ /** exception */ redeclaredBuiltIn);
+ root->traverse(&replaceTraverser);
+ if (!replaceTraverser.updateTree(compiler, root))
+ {
+ return false;
+ }
+
+ // Read gl_ClipDistance to ANGLEClipDistance for getting a original data
+ if (!replacementUtils.assignOriginalValueToANGLEVariable(shaderType))
+ {
+ return false;
+ }
+
+ // Reassign ANGLEClipDistance to gl_ClipDistance but ignore those that are disabled
+ const bool isRedeclared = redeclaredBuiltIn != nullptr;
+ if (!replacementUtils.assignANGLEValueToOriginalVariable(
+ shaderType, isRedeclared, clipDistanceEnableFlags, &constIndices))
+ {
+ return false;
+ }
+
+ // If not redeclared, replace the built-in with one that is appropriately sized
+ if (!isRedeclared)
+ {
+ TType *resizedType = new TType(builtInVar->getType());
+ resizedType->setArraySize(0, enabledClipDistances);
+
+ TVariable *resizedVar = new TVariable(symbolTable, name, resizedType, SymbolType::BuiltIn);
+
+ return ReplaceVariable(compiler, root, builtInVar, resizedVar);
+ }
+
+ return true;
+}
+
+} // anonymous namespace
+
+[[nodiscard]] bool ReplaceClipDistanceAssignments(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ const GLenum shaderType,
+ const TIntermTyped *clipDistanceEnableFlags)
+{
+ return ReplaceClipCullDistanceAssignmentsImpl(compiler, root, symbolTable, shaderType,
+ clipDistanceEnableFlags, "gl_ClipDistance",
+ "ANGLEClipDistance", EvqClipDistance);
+}
+
+[[nodiscard]] bool ReplaceCullDistanceAssignments(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ const GLenum shaderType)
+{
+ return ReplaceClipCullDistanceAssignmentsImpl(compiler, root, symbolTable, shaderType, nullptr,
+ "gl_CullDistance", "ANGLECullDistance",
+ EvqCullDistance);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceClipCullDistanceVariable.h b/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceClipCullDistanceVariable.h
new file mode 100644
index 0000000000..93d19f9fe2
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceClipCullDistanceVariable.h
@@ -0,0 +1,43 @@
+//
+// Copyright 2020 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.
+//
+// ReplaceClipCullDistanceVariable.h: Find any references to gl_ClipDistance or gl_CullDistance and
+// replace it with ANGLEClipDistance or ANGLECullDistance.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEUTIL_REPLACECLIPCULLDISTANCEVARIABLE_H_
+#define COMPILER_TRANSLATOR_TREEUTIL_REPLACECLIPCULLDISTANCEVARIABLE_H_
+
+#include "GLSLANG/ShaderLang.h"
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+struct InterfaceBlock;
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+class TIntermTyped;
+
+// Replace every gl_ClipDistance assignment with assignment to "ANGLEClipDistance",
+// then at the end of shader re-assign the values of this global variable to gl_ClipDistance.
+// This to solve some complex usages such as user passing gl_ClipDistance as output reference
+// to a function.
+// Furthermore, at the end shader, some disabled gl_ClipDistance[i] can be skipped from the
+// assignment.
+[[nodiscard]] bool ReplaceClipDistanceAssignments(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ const GLenum shaderType,
+ const TIntermTyped *clipDistanceEnableFlags);
+
+[[nodiscard]] bool ReplaceCullDistanceAssignments(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ const GLenum shaderType);
+} // namespace sh
+
+#endif
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceShadowingVariables.cpp b/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceShadowingVariables.cpp
new file mode 100644
index 0000000000..47842eaade
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceShadowingVariables.cpp
@@ -0,0 +1,142 @@
+//
+// Copyright 2019 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.
+//
+// ReplaceShadowingVariables.cpp: Replace all references to any variable in the AST that is
+// a redefinition of a variable in a nested scope. This is a useful for ESSL 1.00 shaders
+// where the spec section "4.2.3. Redeclaring Variables" states "However, a nested scope can
+// override an outer scope's declaration of a particular variable name." This is changed in
+// later spec versions, such as ESSL 3.20 spec which states "If [a variable] is declared as
+// a parameter in a function definition, it is scoped until the end of that function
+// definition. A function's parameter declarations and body together form a single scope."
+//
+// So this class is useful when translating from ESSL 1.00 shaders, where function body var
+// redefinition is allowed, to later shader versions where it's not allowed.
+//
+
+#include "compiler/translator/tree_util/ReplaceShadowingVariables.h"
+#include "compiler/translator/tree_util/ReplaceVariable.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/Symbol.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+#include <unordered_set>
+
+namespace sh
+{
+
+namespace
+{
+
+// Custom struct to queue up any replacements until after AST traversal
+struct DeferredReplacementBlock
+{
+ const TVariable *originalVariable; // variable to be replaced
+ TVariable *replacementVariable; // variable to replace originalVar with
+ TIntermBlock *functionBody; // function body where replacement occurs
+};
+
+class ReplaceShadowingVariablesTraverser : public TIntermTraverser
+{
+ public:
+ ReplaceShadowingVariablesTraverser(TSymbolTable *symbolTable)
+ : TIntermTraverser(true, true, true, symbolTable), mParameterNames{}, mFunctionBody(nullptr)
+ {}
+
+ bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override
+ {
+ // In pre-visit of function, record params
+ if (visit == PreVisit)
+ {
+ ASSERT(mParameterNames.size() == 0);
+ const TFunction *func = node->getFunctionPrototype()->getFunction();
+ // Grab all of the parameter names from the function prototype
+ size_t paramCount = func->getParamCount();
+ for (size_t i = 0; i < paramCount; ++i)
+ {
+ mParameterNames.emplace(std::string(func->getParam(i)->name().data()));
+ }
+ if (mParameterNames.size() > 0)
+ mFunctionBody = node->getBody();
+ }
+ else if (visit == PostVisit)
+ {
+ // Clear data saved from function definition
+ mParameterNames.clear();
+ mFunctionBody = nullptr;
+ }
+ return true;
+ }
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override
+ {
+ if (visit == PreVisit && mParameterNames.size() != 0)
+ {
+ TIntermSequence *decls = node->getSequence();
+ for (auto &declVector : *decls)
+ {
+ // no init case
+ TIntermSymbol *symNode = declVector->getAsSymbolNode();
+ if (symNode == nullptr)
+ {
+ // init case
+ TIntermBinary *binaryNode = declVector->getAsBinaryNode();
+ ASSERT(binaryNode->getOp() == EOpInitialize);
+ symNode = binaryNode->getLeft()->getAsSymbolNode();
+ }
+ ASSERT(symNode != nullptr);
+ std::string varName = std::string(symNode->variable().name().data());
+ if (mParameterNames.count(varName) > 0)
+ {
+ // We found a redefined var so queue replacement
+ mReplacements.emplace_back(DeferredReplacementBlock{
+ &symNode->variable(),
+ CreateTempVariable(mSymbolTable, &symNode->variable().getType()),
+ mFunctionBody});
+ }
+ }
+ }
+ return true;
+ }
+ // Perform replacement of vars for any deferred replacements that were identified
+ [[nodiscard]] bool executeReplacements(TCompiler *compiler)
+ {
+ for (DeferredReplacementBlock &replace : mReplacements)
+ {
+ if (!ReplaceVariable(compiler, replace.functionBody, replace.originalVariable,
+ replace.replacementVariable))
+ {
+ return false;
+ }
+ }
+ mReplacements.clear();
+ return true;
+ }
+
+ private:
+ std::unordered_set<std::string> mParameterNames;
+ TIntermBlock *mFunctionBody;
+ std::vector<DeferredReplacementBlock> mReplacements;
+};
+
+} // anonymous namespace
+
+// Replaces every occurrence of a variable with another variable.
+[[nodiscard]] bool ReplaceShadowingVariables(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable)
+{
+ ReplaceShadowingVariablesTraverser traverser(symbolTable);
+ root->traverse(&traverser);
+ if (!traverser.executeReplacements(compiler))
+ {
+ return false;
+ }
+ return traverser.updateTree(compiler, root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceShadowingVariables.h b/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceShadowingVariables.h
new file mode 100644
index 0000000000..f6da350f5f
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceShadowingVariables.h
@@ -0,0 +1,26 @@
+//
+// Copyright 2019 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.
+//
+// ReplaceShadowingVariables.h: Find any variables that are redefined within a nested
+// scope and replace them with a newly named variable.
+
+#ifndef COMPILER_TRANSLATOR_TREEUTIL_REPLACESHADOWINGVARIABLES_H_
+#define COMPILER_TRANSLATOR_TREEUTIL_REPLACESHADOWINGVARIABLES_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+
+[[nodiscard]] bool ReplaceShadowingVariables(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEUTIL_REPLACESHADOWINGVARIABLES_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceVariable.cpp b/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceVariable.cpp
new file mode 100644
index 0000000000..697cfe6c74
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceVariable.cpp
@@ -0,0 +1,145 @@
+//
+// Copyright 2018 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.
+//
+// ReplaceVariable.cpp: Replace all references to a specific variable in the AST with references to
+// another variable.
+
+#include "compiler/translator/tree_util/ReplaceVariable.h"
+
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/Symbol.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+class ReplaceVariableTraverser : public TIntermTraverser
+{
+ public:
+ ReplaceVariableTraverser(const TVariable *toBeReplaced, const TIntermTyped *replacement)
+ : TIntermTraverser(true, false, false),
+ mToBeReplaced(toBeReplaced),
+ mReplacement(replacement)
+ {}
+
+ void visitSymbol(TIntermSymbol *node) override
+ {
+ if (&node->variable() == mToBeReplaced)
+ {
+ queueReplacement(mReplacement->deepCopy(), OriginalNode::IS_DROPPED);
+ }
+ }
+
+ private:
+ const TVariable *const mToBeReplaced;
+ const TIntermTyped *const mReplacement;
+};
+
+class ReplaceVariablesTraverser : public TIntermTraverser
+{
+ public:
+ ReplaceVariablesTraverser(const VariableReplacementMap &variableMap)
+ : TIntermTraverser(true, false, false), mVariableMap(variableMap)
+ {}
+
+ void visitSymbol(TIntermSymbol *node) override
+ {
+ auto iter = mVariableMap.find(&node->variable());
+ if (iter != mVariableMap.end())
+ {
+ queueReplacement(iter->second->deepCopy(), OriginalNode::IS_DROPPED);
+ }
+ }
+
+ private:
+ const VariableReplacementMap &mVariableMap;
+};
+
+class GetDeclaratorReplacementsTraverser : public TIntermTraverser
+{
+ public:
+ GetDeclaratorReplacementsTraverser(TSymbolTable *symbolTable,
+ VariableReplacementMap *variableMap)
+ : TIntermTraverser(true, false, false, symbolTable), mVariableMap(variableMap)
+ {}
+
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override
+ {
+ const TIntermSequence &sequence = *(node->getSequence());
+
+ for (TIntermNode *decl : sequence)
+ {
+ TIntermSymbol *asSymbol = decl->getAsSymbolNode();
+ TIntermBinary *asBinary = decl->getAsBinaryNode();
+
+ if (asBinary != nullptr)
+ {
+ ASSERT(asBinary->getOp() == EOpInitialize);
+ asSymbol = asBinary->getLeft()->getAsSymbolNode();
+ }
+
+ ASSERT(asSymbol);
+ const TVariable &variable = asSymbol->variable();
+
+ ASSERT(mVariableMap->find(&variable) == mVariableMap->end());
+
+ const TVariable *replacementVariable = new TVariable(
+ mSymbolTable, variable.name(), &variable.getType(), variable.symbolType());
+
+ (*mVariableMap)[&variable] = new TIntermSymbol(replacementVariable);
+ }
+
+ return false;
+ }
+
+ private:
+ VariableReplacementMap *mVariableMap;
+};
+
+} // anonymous namespace
+
+// Replaces every occurrence of a variable with another variable.
+[[nodiscard]] bool ReplaceVariable(TCompiler *compiler,
+ TIntermBlock *root,
+ const TVariable *toBeReplaced,
+ const TVariable *replacement)
+{
+ ReplaceVariableTraverser traverser(toBeReplaced, new TIntermSymbol(replacement));
+ root->traverse(&traverser);
+ return traverser.updateTree(compiler, root);
+}
+
+[[nodiscard]] bool ReplaceVariables(TCompiler *compiler,
+ TIntermBlock *root,
+ const VariableReplacementMap &variableMap)
+{
+ ReplaceVariablesTraverser traverser(variableMap);
+ root->traverse(&traverser);
+ return traverser.updateTree(compiler, root);
+}
+
+void GetDeclaratorReplacements(TSymbolTable *symbolTable,
+ TIntermBlock *root,
+ VariableReplacementMap *variableMap)
+{
+ GetDeclaratorReplacementsTraverser traverser(symbolTable, variableMap);
+ root->traverse(&traverser);
+}
+
+// Replaces every occurrence of a variable with a TIntermNode.
+[[nodiscard]] bool ReplaceVariableWithTyped(TCompiler *compiler,
+ TIntermBlock *root,
+ const TVariable *toBeReplaced,
+ const TIntermTyped *replacement)
+{
+ ReplaceVariableTraverser traverser(toBeReplaced, replacement);
+ root->traverse(&traverser);
+ return traverser.updateTree(compiler, root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceVariable.h b/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceVariable.h
new file mode 100644
index 0000000000..e96bbc7a82
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/ReplaceVariable.h
@@ -0,0 +1,48 @@
+//
+// Copyright 2018 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.
+//
+// ReplaceVariable.h: Replace all references to a specific variable in the AST with references to
+// another variable.
+
+#ifndef COMPILER_TRANSLATOR_TREEUTIL_REPLACEVARIABLE_H_
+#define COMPILER_TRANSLATOR_TREEUTIL_REPLACEVARIABLE_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermBlock;
+class TIntermTyped;
+class TSymbolTable;
+class TVariable;
+
+[[nodiscard]] bool ReplaceVariable(TCompiler *compiler,
+ TIntermBlock *root,
+ const TVariable *toBeReplaced,
+ const TVariable *replacement);
+[[nodiscard]] bool ReplaceVariableWithTyped(TCompiler *compiler,
+ TIntermBlock *root,
+ const TVariable *toBeReplaced,
+ const TIntermTyped *replacement);
+
+using VariableReplacementMap = angle::HashMap<const TVariable *, const TIntermTyped *>;
+
+// Replace a set of variables with their corresponding expression.
+[[nodiscard]] bool ReplaceVariables(TCompiler *compiler,
+ TIntermBlock *root,
+ const VariableReplacementMap &variableMap);
+
+// Find all declarators, and replace the TVariable they are declaring with a duplicate. This is
+// used to support deepCopy of TIntermBlock and TIntermLoop nodes that include declarations.
+// Replacements already present in variableMap are preserved.
+void GetDeclaratorReplacements(TSymbolTable *symbolTable,
+ TIntermBlock *root,
+ VariableReplacementMap *variableMap);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEUTIL_REPLACEVARIABLE_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/RewriteSampleMaskVariable.cpp b/gfx/angle/checkout/src/compiler/translator/tree_util/RewriteSampleMaskVariable.cpp
new file mode 100644
index 0000000000..a81d230492
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/RewriteSampleMaskVariable.cpp
@@ -0,0 +1,198 @@
+//
+// Copyright 2020 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.
+//
+// RewriteSampleMaskVariable.cpp: Find any references to gl_SampleMask and gl_SampleMaskIn, and
+// rewrite it with ANGLESampleMask or ANGLESampleMaskIn.
+//
+
+#include "compiler/translator/tree_util/RewriteSampleMaskVariable.h"
+
+#include "common/bitset_utils.h"
+#include "common/debug.h"
+#include "common/utilities.h"
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/BuiltIn.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+#include "compiler/translator/tree_util/RunAtTheEndOfShader.h"
+
+namespace sh
+{
+namespace
+{
+constexpr int kMaxIndexForSampleMaskVar = 0;
+constexpr int kFullSampleMask = 0xFFFFFFFF;
+
+// Traverse the tree and collect the redeclaration and replace all non constant index references of
+// gl_SampleMask or gl_SampleMaskIn with constant index references
+class GLSampleMaskRelatedReferenceTraverser : public TIntermTraverser
+{
+ public:
+ GLSampleMaskRelatedReferenceTraverser(const TIntermSymbol **redeclaredSymOut,
+ const ImmutableString &targetStr)
+ : TIntermTraverser(true, false, false),
+ mRedeclaredSym(redeclaredSymOut),
+ mTargetStr(targetStr)
+ {
+ *mRedeclaredSym = nullptr;
+ }
+
+ bool visitDeclaration(Visit visit, TIntermDeclaration *node) override
+ {
+ // If gl_SampleMask is redeclared, we need to collect its information
+ const TIntermSequence &sequence = *(node->getSequence());
+
+ if (sequence.size() != 1)
+ {
+ return true;
+ }
+
+ TIntermTyped *variable = sequence.front()->getAsTyped();
+ TIntermSymbol *symbol = variable->getAsSymbolNode();
+ if (symbol == nullptr || symbol->getName() != mTargetStr)
+ {
+ return true;
+ }
+
+ *mRedeclaredSym = symbol;
+
+ return true;
+ }
+
+ bool visitBinary(Visit visit, TIntermBinary *node) override
+ {
+ TOperator op = node->getOp();
+ if (op != EOpIndexDirect && op != EOpIndexIndirect)
+ {
+ return true;
+ }
+ TIntermSymbol *left = node->getLeft()->getAsSymbolNode();
+ if (!left)
+ {
+ return true;
+ }
+ if (left->getName() != mTargetStr)
+ {
+ return true;
+ }
+ const TConstantUnion *constIdx = node->getRight()->getConstantValue();
+ if (!constIdx)
+ {
+ if (node->getRight()->hasSideEffects())
+ {
+ insertStatementInParentBlock(node->getRight());
+ }
+
+ queueReplacementWithParent(node, node->getRight(),
+ CreateIndexNode(kMaxIndexForSampleMaskVar),
+ OriginalNode::IS_DROPPED);
+ }
+
+ return true;
+ }
+
+ private:
+ const TIntermSymbol **mRedeclaredSym;
+ const ImmutableString mTargetStr;
+};
+
+} // anonymous namespace
+
+[[nodiscard]] bool RewriteSampleMask(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ const TIntermTyped *numSamplesUniform)
+{
+ const TIntermSymbol *redeclaredGLSampleMask = nullptr;
+ GLSampleMaskRelatedReferenceTraverser indexTraverser(&redeclaredGLSampleMask,
+ ImmutableString("gl_SampleMask"));
+
+ root->traverse(&indexTraverser);
+ if (!indexTraverser.updateTree(compiler, root))
+ {
+ return false;
+ }
+
+ // Retrieve gl_SampleMask variable reference
+ // Search user redeclared it first
+ const TVariable *glSampleMaskVar = nullptr;
+ if (redeclaredGLSampleMask)
+ {
+ glSampleMaskVar = &redeclaredGLSampleMask->variable();
+ }
+ else
+ {
+ // User defined not found, find in built-in table
+ glSampleMaskVar = static_cast<const TVariable *>(symbolTable->findBuiltIn(
+ ImmutableString("gl_SampleMask"), compiler->getShaderVersion()));
+ }
+ if (!glSampleMaskVar)
+ {
+ return false;
+ }
+
+ // Current ANGLE assumes that the maximum number of samples is less than or equal to
+ // VK_SAMPLE_COUNT_32_BIT. So, the size of gl_SampleMask array is always one.
+ const unsigned int arraySizeOfSampleMask = glSampleMaskVar->getType().getOutermostArraySize();
+ ASSERT(arraySizeOfSampleMask == 1);
+
+ TIntermSymbol *glSampleMaskSymbol = new TIntermSymbol(glSampleMaskVar);
+
+ // if (ANGLEUniforms.numSamples == 1)
+ // {
+ // gl_SampleMask[0] = int(0xFFFFFFFF);
+ // }
+ TIntermConstantUnion *singleSampleCount = CreateUIntNode(1);
+ TIntermBinary *equalTo =
+ new TIntermBinary(EOpEqual, numSamplesUniform->deepCopy(), singleSampleCount);
+
+ TIntermBlock *trueBlock = new TIntermBlock();
+
+ TIntermBinary *sampleMaskVar = new TIntermBinary(EOpIndexDirect, glSampleMaskSymbol->deepCopy(),
+ CreateIndexNode(kMaxIndexForSampleMaskVar));
+ TIntermConstantUnion *fullSampleMask = CreateIndexNode(kFullSampleMask);
+ TIntermBinary *assignment = new TIntermBinary(EOpAssign, sampleMaskVar, fullSampleMask);
+
+ trueBlock->appendStatement(assignment);
+
+ TIntermIfElse *multiSampleOrNot = new TIntermIfElse(equalTo, trueBlock, nullptr);
+
+ return RunAtTheEndOfShader(compiler, root, multiSampleOrNot, symbolTable);
+}
+
+[[nodiscard]] bool RewriteSampleMaskIn(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable)
+{
+ const TIntermSymbol *redeclaredGLSampleMaskIn = nullptr;
+ GLSampleMaskRelatedReferenceTraverser indexTraverser(&redeclaredGLSampleMaskIn,
+ ImmutableString("gl_SampleMaskIn"));
+
+ root->traverse(&indexTraverser);
+ if (!indexTraverser.updateTree(compiler, root))
+ {
+ return false;
+ }
+
+ // Retrieve gl_SampleMaskIn variable reference
+ const TVariable *glSampleMaskInVar = nullptr;
+ glSampleMaskInVar = static_cast<const TVariable *>(
+ symbolTable->findBuiltIn(ImmutableString("gl_SampleMaskIn"), compiler->getShaderVersion()));
+ if (!glSampleMaskInVar)
+ {
+ return false;
+ }
+
+ // Current ANGLE assumes that the maximum number of samples is less than or equal to
+ // VK_SAMPLE_COUNT_32_BIT. So, the size of gl_SampleMask array is always one.
+ const unsigned int arraySizeOfSampleMaskIn =
+ glSampleMaskInVar->getType().getOutermostArraySize();
+ ASSERT(arraySizeOfSampleMaskIn == 1);
+
+ return true;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/RewriteSampleMaskVariable.h b/gfx/angle/checkout/src/compiler/translator/tree_util/RewriteSampleMaskVariable.h
new file mode 100644
index 0000000000..20f19313b2
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/RewriteSampleMaskVariable.h
@@ -0,0 +1,38 @@
+//
+// Copyright 2020 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.
+//
+// RewriteSampleMaskVariable.cpp: Find any references to gl_SampleMask and gl_SampleMaskIn, and
+// rewrite it with ANGLESampleMask or ANGLESampleMaskIn.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEUTIL_REWRITESAMPLEMASKVARIABLE_H_
+#define COMPILER_TRANSLATOR_TREEUTIL_REWRITESAMPLEMASKVARIABLE_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermBlock;
+class TSymbolTable;
+class TIntermTyped;
+
+// Rewrite every gl_SampleMask or gl_SampleMaskIn to "ANGLESampleMask" or "ANGLESampleMaskIn", then
+// at the end of shader re-assign the values of this global variable to gl_SampleMask and
+// gl_SampleMaskIn. This to solve the problem which the non constant index is used for the unsized
+// array problem.
+[[nodiscard]] bool RewriteSampleMask(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable,
+ const TIntermTyped *numSamplesUniform);
+
+[[nodiscard]] bool RewriteSampleMaskIn(TCompiler *compiler,
+ TIntermBlock *root,
+ TSymbolTable *symbolTable);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEUTIL_REWRITESAMPLEMASKVARIABLE_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/RunAtTheBeginningOfShader.cpp b/gfx/angle/checkout/src/compiler/translator/tree_util/RunAtTheBeginningOfShader.cpp
new file mode 100644
index 0000000000..99be6add13
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/RunAtTheBeginningOfShader.cpp
@@ -0,0 +1,35 @@
+//
+// Copyright 2020 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.
+//
+// RunAtTheBeginningOfShader.cpp: Add code to be run at the beginning of the shader.
+// void main() { body }
+// =>
+// void main()
+// {
+// codeToRun
+// body
+// }
+//
+
+#include "compiler/translator/tree_util/RunAtTheBeginningOfShader.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/FindMain.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+bool RunAtTheBeginningOfShader(TCompiler *compiler, TIntermBlock *root, TIntermNode *codeToRun)
+{
+ TIntermFunctionDefinition *main = FindMain(root);
+ main->getBody()->insertStatement(0, codeToRun);
+ return compiler->validateAST(root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/RunAtTheBeginningOfShader.h b/gfx/angle/checkout/src/compiler/translator/tree_util/RunAtTheBeginningOfShader.h
new file mode 100644
index 0000000000..23ed9f9372
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/RunAtTheBeginningOfShader.h
@@ -0,0 +1,27 @@
+//
+// Copyright 2020 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.
+//
+// RunAtTheBeginningOfShader.h: Add code to be run at the beginning of the shader.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEUTIL_RUNATTHEBEGINNINGOFSHADER_H_
+#define COMPILER_TRANSLATOR_TREEUTIL_RUNATTHEBEGINNINGOFSHADER_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermBlock;
+class TIntermNode;
+
+[[nodiscard]] bool RunAtTheBeginningOfShader(TCompiler *compiler,
+ TIntermBlock *root,
+ TIntermNode *codeToRun);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEUTIL_RUNATTHEBEGINNINGOFSHADER_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/RunAtTheEndOfShader.cpp b/gfx/angle/checkout/src/compiler/translator/tree_util/RunAtTheEndOfShader.cpp
new file mode 100644
index 0000000000..daf99185ab
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/RunAtTheEndOfShader.cpp
@@ -0,0 +1,129 @@
+//
+// Copyright 2017 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.
+//
+// RunAtTheEndOfShader.cpp: Add code to be run at the end of the shader. In case main() contains a
+// return statement, this is done by replacing the main() function with another function that calls
+// the old main, like this:
+//
+// void main() { body }
+// =>
+// void main0() { body }
+// void main()
+// {
+// main0();
+// codeToRun
+// }
+//
+// This way the code will get run even if the return statement inside main is executed.
+//
+// This is done if main ends in an unconditional |discard| as well, to help with SPIR-V generation
+// that expects no dead-code to be present after branches in a block. To avoid bugs when |discard|
+// is wrapped in unconditional blocks, any |discard| in main() is used as a signal to wrap it.
+//
+
+#include "compiler/translator/tree_util/RunAtTheEndOfShader.h"
+
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/StaticType.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/FindMain.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+#include "compiler/translator/tree_util/IntermTraverse.h"
+
+namespace sh
+{
+
+namespace
+{
+
+constexpr const ImmutableString kMainString("main");
+
+class ContainsReturnOrDiscardTraverser : public TIntermTraverser
+{
+ public:
+ ContainsReturnOrDiscardTraverser()
+ : TIntermTraverser(true, false, false), mContainsReturnOrDiscard(false)
+ {}
+
+ bool visitBranch(Visit visit, TIntermBranch *node) override
+ {
+ if (node->getFlowOp() == EOpReturn || node->getFlowOp() == EOpKill)
+ {
+ mContainsReturnOrDiscard = true;
+ }
+ return false;
+ }
+
+ bool containsReturnOrDiscard() { return mContainsReturnOrDiscard; }
+
+ private:
+ bool mContainsReturnOrDiscard;
+};
+
+bool ContainsReturnOrDiscard(TIntermNode *node)
+{
+ ContainsReturnOrDiscardTraverser traverser;
+ node->traverse(&traverser);
+ return traverser.containsReturnOrDiscard();
+}
+
+void WrapMainAndAppend(TIntermBlock *root,
+ TIntermFunctionDefinition *main,
+ TIntermNode *codeToRun,
+ TSymbolTable *symbolTable)
+{
+ // Replace main() with main0() with the same body.
+ TFunction *oldMain =
+ new TFunction(symbolTable, kEmptyImmutableString, SymbolType::AngleInternal,
+ StaticType::GetBasic<EbtVoid, EbpUndefined>(), false);
+ TIntermFunctionDefinition *oldMainDefinition =
+ CreateInternalFunctionDefinitionNode(*oldMain, main->getBody());
+
+ bool replaced = root->replaceChildNode(main, oldMainDefinition);
+ ASSERT(replaced);
+
+ // void main()
+ TFunction *newMain = new TFunction(symbolTable, kMainString, SymbolType::UserDefined,
+ StaticType::GetBasic<EbtVoid, EbpUndefined>(), false);
+ TIntermFunctionPrototype *newMainProto = new TIntermFunctionPrototype(newMain);
+
+ // {
+ // main0();
+ // codeToRun
+ // }
+ TIntermBlock *newMainBody = new TIntermBlock();
+ TIntermSequence emptySequence;
+ TIntermAggregate *oldMainCall = TIntermAggregate::CreateFunctionCall(*oldMain, &emptySequence);
+ newMainBody->appendStatement(oldMainCall);
+ newMainBody->appendStatement(codeToRun);
+
+ // Add the new main() to the root node.
+ TIntermFunctionDefinition *newMainDefinition =
+ new TIntermFunctionDefinition(newMainProto, newMainBody);
+ root->appendStatement(newMainDefinition);
+}
+
+} // anonymous namespace
+
+bool RunAtTheEndOfShader(TCompiler *compiler,
+ TIntermBlock *root,
+ TIntermNode *codeToRun,
+ TSymbolTable *symbolTable)
+{
+ TIntermFunctionDefinition *main = FindMain(root);
+ if (ContainsReturnOrDiscard(main))
+ {
+ WrapMainAndAppend(root, main, codeToRun, symbolTable);
+ }
+ else
+ {
+ main->getBody()->appendStatement(codeToRun);
+ }
+
+ return compiler->validateAST(root);
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/RunAtTheEndOfShader.h b/gfx/angle/checkout/src/compiler/translator/tree_util/RunAtTheEndOfShader.h
new file mode 100644
index 0000000000..cfa5fb1fab
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/RunAtTheEndOfShader.h
@@ -0,0 +1,29 @@
+//
+// Copyright 2017 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.
+//
+// RunAtTheEndOfShader.h: Add code to be run at the end of the shader.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEUTIL_RUNATTHEENDOFSHADER_H_
+#define COMPILER_TRANSLATOR_TREEUTIL_RUNATTHEENDOFSHADER_H_
+
+#include "common/angleutils.h"
+
+namespace sh
+{
+
+class TCompiler;
+class TIntermBlock;
+class TIntermNode;
+class TSymbolTable;
+
+[[nodiscard]] bool RunAtTheEndOfShader(TCompiler *compiler,
+ TIntermBlock *root,
+ TIntermNode *codeToRun,
+ TSymbolTable *symbolTable);
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEUTIL_RUNATTHEENDOFSHADER_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/SpecializationConstant.cpp b/gfx/angle/checkout/src/compiler/translator/tree_util/SpecializationConstant.cpp
new file mode 100644
index 0000000000..6a7254802c
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/SpecializationConstant.cpp
@@ -0,0 +1,122 @@
+//
+// Copyright 2020 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.
+//
+// SpecializationConst.cpp: Add code to generate AST node for various specialization constants.
+//
+
+#include "compiler/translator/tree_util/SpecializationConstant.h"
+#include "common/PackedEnums.h"
+#include "common/angleutils.h"
+#include "compiler/translator/StaticType.h"
+#include "compiler/translator/SymbolTable.h"
+#include "compiler/translator/tree_util/IntermNode_util.h"
+
+namespace sh
+{
+
+namespace
+{
+// Specialization constant names
+constexpr ImmutableString kSurfaceRotationSpecConstVarName =
+ ImmutableString("ANGLESurfaceRotation");
+constexpr ImmutableString kDitherSpecConstVarName = ImmutableString("ANGLEDither");
+
+const TType *MakeSpecConst(const TType &type, vk::SpecializationConstantId id)
+{
+ // Create a new type with the EvqSpecConst qualifier
+ TType *specConstType = new TType(type);
+ specConstType->setQualifier(EvqSpecConst);
+
+ // Set the constant_id of the spec const
+ TLayoutQualifier layoutQualifier = TLayoutQualifier::Create();
+ layoutQualifier.location = static_cast<int>(id);
+ specConstType->setLayoutQualifier(layoutQualifier);
+
+ return specConstType;
+}
+} // anonymous namespace
+
+SpecConst::SpecConst(TSymbolTable *symbolTable,
+ const ShCompileOptions &compileOptions,
+ GLenum shaderType)
+ : mSymbolTable(symbolTable),
+ mCompileOptions(compileOptions),
+ mSurfaceRotationVar(nullptr),
+ mDitherVar(nullptr)
+{
+ if (shaderType == GL_FRAGMENT_SHADER || shaderType == GL_COMPUTE_SHADER)
+ {
+ return;
+ }
+
+ // Mark SpecConstUsage::Rotation unconditionally. gl_Position is always rotated.
+ if (mCompileOptions.useSpecializationConstant)
+ {
+ mUsageBits.set(vk::SpecConstUsage::Rotation);
+ }
+}
+
+SpecConst::~SpecConst() {}
+
+void SpecConst::declareSpecConsts(TIntermBlock *root)
+{
+ // Add specialization constant declarations. The default value of the specialization
+ // constant is irrelevant, as it will be set when creating the pipeline.
+ // Only emit specialized const declaration if it has been referenced.
+ if (mSurfaceRotationVar != nullptr)
+ {
+ TIntermDeclaration *decl = new TIntermDeclaration();
+ decl->appendDeclarator(
+ new TIntermBinary(EOpInitialize, getRotation(), CreateBoolNode(false)));
+
+ root->insertStatement(0, decl);
+ }
+
+ if (mDitherVar != nullptr)
+ {
+ TIntermDeclaration *decl = new TIntermDeclaration();
+ decl->appendDeclarator(new TIntermBinary(EOpInitialize, getDither(), CreateUIntNode(0)));
+
+ root->insertStatement(0, decl);
+ }
+}
+
+TIntermSymbol *SpecConst::getRotation()
+{
+ if (mSurfaceRotationVar == nullptr)
+ {
+ const TType *type = MakeSpecConst(*StaticType::GetBasic<EbtBool, EbpUndefined>(),
+ vk::SpecializationConstantId::SurfaceRotation);
+
+ mSurfaceRotationVar = new TVariable(mSymbolTable, kSurfaceRotationSpecConstVarName, type,
+ SymbolType::AngleInternal);
+ }
+ return new TIntermSymbol(mSurfaceRotationVar);
+}
+
+TIntermTyped *SpecConst::getSwapXY()
+{
+ if (!mCompileOptions.useSpecializationConstant)
+ {
+ return nullptr;
+ }
+ mUsageBits.set(vk::SpecConstUsage::Rotation);
+ return getRotation();
+}
+
+TIntermTyped *SpecConst::getDither()
+{
+ if (mDitherVar == nullptr)
+ {
+ const TType *type = MakeSpecConst(*StaticType::GetBasic<EbtUInt, EbpHigh>(),
+ vk::SpecializationConstantId::Dither);
+
+ mDitherVar =
+ new TVariable(mSymbolTable, kDitherSpecConstVarName, type, SymbolType::AngleInternal);
+ mUsageBits.set(vk::SpecConstUsage::Dither);
+ }
+ return new TIntermSymbol(mDitherVar);
+}
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/SpecializationConstant.h b/gfx/angle/checkout/src/compiler/translator/tree_util/SpecializationConstant.h
new file mode 100644
index 0000000000..6644706567
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/SpecializationConstant.h
@@ -0,0 +1,55 @@
+//
+// Copyright 2020 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.
+//
+// SpecializationConst.h: Add code to generate AST node for specialization constant.
+//
+
+#ifndef COMPILER_TRANSLATOR_TREEUTIL_SPECIALIZATIONCONSTANT_H_
+#define COMPILER_TRANSLATOR_TREEUTIL_SPECIALIZATIONCONSTANT_H_
+
+#include "common/angleutils.h"
+#include "compiler/translator/Compiler.h"
+#include "compiler/translator/SymbolTable.h"
+
+class TIntermBlock;
+class TIntermTyped;
+class TIntermSymbol;
+class TVariable;
+
+namespace sh
+{
+
+class SpecConst
+{
+ public:
+ SpecConst(TSymbolTable *symbolTable, const ShCompileOptions &compileOptions, GLenum shaderType);
+ virtual ~SpecConst();
+
+ // Flip/rotation
+ // Returns a boolean: should X and Y be swapped?
+ TIntermTyped *getSwapXY();
+
+ // Dither emulation
+ TIntermTyped *getDither();
+
+ void declareSpecConsts(TIntermBlock *root);
+ SpecConstUsageBits getSpecConstUsageBits() const { return mUsageBits; }
+
+ private:
+ TIntermSymbol *getRotation();
+
+ // If unsupported, this should be set to null.
+ TSymbolTable *mSymbolTable;
+ const ShCompileOptions &mCompileOptions;
+
+ TVariable *mSurfaceRotationVar;
+ TVariable *mDitherVar;
+
+ // Bit is set if YFlip or Rotation has been used
+ SpecConstUsageBits mUsageBits;
+};
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEUTIL_SPECIALIZATIONCONSTANT_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_util/Visit.h b/gfx/angle/checkout/src/compiler/translator/tree_util/Visit.h
new file mode 100644
index 0000000000..36a8f14a52
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/tree_util/Visit.h
@@ -0,0 +1,22 @@
+//
+// Copyright 2018 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_TREEUTIL_VISIT_H_
+#define COMPILER_TRANSLATOR_TREEUTIL_VISIT_H_
+
+namespace sh
+{
+
+enum Visit
+{
+ PreVisit,
+ InVisit,
+ PostVisit
+};
+
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_TREEUTIL_VISIT_H_
diff --git a/gfx/angle/checkout/src/compiler/translator/util.cpp b/gfx/angle/checkout/src/compiler/translator/util.cpp
new file mode 100644
index 0000000000..f1dd8c2fb3
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/util.cpp
@@ -0,0 +1,1023 @@
+//
+// Copyright 2010 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/util.h"
+
+#include <limits>
+
+#include "common/utilities.h"
+#include "compiler/preprocessor/numeric_lex.h"
+#include "compiler/translator/ImmutableStringBuilder.h"
+#include "compiler/translator/SymbolTable.h"
+
+bool atoi_clamp(const char *str, unsigned int *value)
+{
+ bool success = angle::pp::numeric_lex_int(str, value);
+ if (!success)
+ *value = std::numeric_limits<unsigned int>::max();
+ return success;
+}
+
+namespace sh
+{
+
+namespace
+{
+// [primarySize-1][secondarySize-1] is the GL type with a basic type of float.
+constexpr GLenum kFloatGLType[4][4] = {
+ // float1xS only makes sense for S == 1
+ {
+ GL_FLOAT,
+ GL_NONE,
+ GL_NONE,
+ GL_NONE,
+ },
+ // float2xS is vec2 for S == 1, and mat2xS o.w.
+ {
+ GL_FLOAT_VEC2,
+ GL_FLOAT_MAT2,
+ GL_FLOAT_MAT2x3,
+ GL_FLOAT_MAT2x4,
+ },
+ // float3xS is vec3 for S == 1, and mat3xS o.w.
+ {
+ GL_FLOAT_VEC3,
+ GL_FLOAT_MAT3x2,
+ GL_FLOAT_MAT3,
+ GL_FLOAT_MAT3x4,
+ },
+ // float4xS is vec4 for S == 1, and mat4xS o.w.
+ {
+ GL_FLOAT_VEC4,
+ GL_FLOAT_MAT4x2,
+ GL_FLOAT_MAT4x3,
+ GL_FLOAT_MAT4,
+ },
+};
+// [primarySize-1] is the GL type with a basic type of int.
+constexpr GLenum kIntGLType[4] = {GL_INT, GL_INT_VEC2, GL_INT_VEC3, GL_INT_VEC4};
+// [primarySize-1] is the GL type with a basic type of uint.
+constexpr GLenum kUIntGLType[4] = {GL_UNSIGNED_INT, GL_UNSIGNED_INT_VEC2, GL_UNSIGNED_INT_VEC3,
+ GL_UNSIGNED_INT_VEC4};
+// [primarySize-1] is the GL type with a basic type of bool.
+constexpr GLenum kBoolGLType[4] = {GL_BOOL, GL_BOOL_VEC2, GL_BOOL_VEC3, GL_BOOL_VEC4};
+
+bool IsInterpolationIn(TQualifier qualifier)
+{
+ switch (qualifier)
+ {
+ case EvqSmoothIn:
+ case EvqFlatIn:
+ case EvqNoPerspectiveIn:
+ case EvqCentroidIn:
+ case EvqSampleIn:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool IsInterpolationOut(TQualifier qualifier)
+{
+ switch (qualifier)
+ {
+ case EvqSmoothOut:
+ case EvqFlatOut:
+ case EvqNoPerspectiveOut:
+ case EvqCentroidOut:
+ case EvqSampleOut:
+ return true;
+ default:
+ return false;
+ }
+}
+} // anonymous namespace
+
+float NumericLexFloat32OutOfRangeToInfinity(const std::string &str)
+{
+ // Parses a decimal string using scientific notation into a floating point number.
+ // Out-of-range values are converted to infinity. Values that are too small to be
+ // represented are converted to zero.
+
+ // The mantissa in decimal scientific notation. The magnitude of the mantissa integer does not
+ // matter.
+ unsigned int decimalMantissa = 0;
+ size_t i = 0;
+ bool decimalPointSeen = false;
+ bool nonZeroSeenInMantissa = false;
+
+ // The exponent offset reflects the position of the decimal point.
+ int exponentOffset = -1;
+
+ // This is just a counter for how many decimal digits are written to decimalMantissa.
+ int mantissaDecimalDigits = 0;
+
+ while (i < str.length())
+ {
+ const char c = str[i];
+ if (c == 'e' || c == 'E')
+ {
+ break;
+ }
+ if (c == '.')
+ {
+ decimalPointSeen = true;
+ ++i;
+ continue;
+ }
+
+ unsigned int digit = static_cast<unsigned int>(c - '0');
+ ASSERT(digit < 10u);
+ if (digit != 0u)
+ {
+ nonZeroSeenInMantissa = true;
+ }
+ if (nonZeroSeenInMantissa)
+ {
+ // Add bits to the mantissa until space runs out in 32-bit int. This should be
+ // enough precision to make the resulting binary mantissa accurate to 1 ULP.
+ if (decimalMantissa <= (std::numeric_limits<unsigned int>::max() - 9u) / 10u)
+ {
+ decimalMantissa = decimalMantissa * 10u + digit;
+ ++mantissaDecimalDigits;
+ }
+ if (!decimalPointSeen)
+ {
+ ++exponentOffset;
+ }
+ }
+ else if (decimalPointSeen)
+ {
+ --exponentOffset;
+ }
+ ++i;
+ }
+ if (decimalMantissa == 0)
+ {
+ return 0.0f;
+ }
+ int exponent = 0;
+ if (i < str.length())
+ {
+ ASSERT(str[i] == 'e' || str[i] == 'E');
+ ++i;
+ bool exponentOutOfRange = false;
+ bool negativeExponent = false;
+ if (str[i] == '-')
+ {
+ negativeExponent = true;
+ ++i;
+ }
+ else if (str[i] == '+')
+ {
+ ++i;
+ }
+ while (i < str.length())
+ {
+ const char c = str[i];
+ unsigned int digit = static_cast<unsigned int>(c - '0');
+ ASSERT(digit < 10u);
+ if (exponent <= (std::numeric_limits<int>::max() - 9) / 10)
+ {
+ exponent = exponent * 10 + digit;
+ }
+ else
+ {
+ exponentOutOfRange = true;
+ }
+ ++i;
+ }
+ if (negativeExponent)
+ {
+ exponent = -exponent;
+ }
+ if (exponentOutOfRange)
+ {
+ if (negativeExponent)
+ {
+ return 0.0f;
+ }
+ else
+ {
+ return std::numeric_limits<float>::infinity();
+ }
+ }
+ }
+ // Do the calculation in 64-bit to avoid overflow.
+ long long exponentLong =
+ static_cast<long long>(exponent) + static_cast<long long>(exponentOffset);
+ if (exponentLong > std::numeric_limits<float>::max_exponent10)
+ {
+ return std::numeric_limits<float>::infinity();
+ }
+ else if (exponentLong < std::numeric_limits<float>::min_exponent10)
+ {
+ return 0.0f;
+ }
+ // The exponent is in range, so we need to actually evaluate the float.
+ exponent = static_cast<int>(exponentLong);
+ double value = decimalMantissa;
+
+ // Calculate the exponent offset to normalize the mantissa.
+ int normalizationExponentOffset = 1 - mantissaDecimalDigits;
+ // Apply the exponent.
+ value *= std::pow(10.0, static_cast<double>(exponent + normalizationExponentOffset));
+ if (value > static_cast<double>(std::numeric_limits<float>::max()))
+ {
+ return std::numeric_limits<float>::infinity();
+ }
+ if (value < static_cast<double>(std::numeric_limits<float>::min()))
+ {
+ return 0.0f;
+ }
+ return static_cast<float>(value);
+}
+
+bool strtof_clamp(const std::string &str, float *value)
+{
+ // Custom float parsing that can handle the following corner cases:
+ // 1. The decimal mantissa is very small but the exponent is very large, putting the resulting
+ // number inside the float range.
+ // 2. The decimal mantissa is very large but the exponent is very small, putting the resulting
+ // number inside the float range.
+ // 3. The value is out-of-range and should be evaluated as infinity.
+ // 4. The value is too small and should be evaluated as zero.
+ // See ESSL 3.00.6 section 4.1.4 for the relevant specification.
+ *value = NumericLexFloat32OutOfRangeToInfinity(str);
+ return !gl::isInf(*value);
+}
+
+GLenum GLVariableType(const TType &type)
+{
+ switch (type.getBasicType())
+ {
+ case EbtFloat:
+ ASSERT(type.getNominalSize() >= 1 && type.getNominalSize() <= 4);
+ ASSERT(type.getSecondarySize() >= 1 && type.getSecondarySize() <= 4);
+
+ return kFloatGLType[type.getNominalSize() - 1][type.getSecondarySize() - 1];
+
+ case EbtInt:
+ ASSERT(type.getNominalSize() >= 1 && type.getNominalSize() <= 4);
+ ASSERT(type.getSecondarySize() == 1);
+
+ return kIntGLType[type.getNominalSize() - 1];
+
+ case EbtUInt:
+ ASSERT(type.getNominalSize() >= 1 && type.getNominalSize() <= 4);
+ ASSERT(type.getSecondarySize() == 1);
+
+ return kUIntGLType[type.getNominalSize() - 1];
+
+ case EbtBool:
+ ASSERT(type.getNominalSize() >= 1 && type.getNominalSize() <= 4);
+ ASSERT(type.getSecondarySize() == 1);
+
+ return kBoolGLType[type.getNominalSize() - 1];
+
+ case EbtSampler2D:
+ return GL_SAMPLER_2D;
+ case EbtSampler3D:
+ return GL_SAMPLER_3D;
+ case EbtSamplerCube:
+ return GL_SAMPLER_CUBE;
+ case EbtSamplerExternalOES:
+ return GL_SAMPLER_EXTERNAL_OES;
+ case EbtSamplerExternal2DY2YEXT:
+ return GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT;
+ case EbtSampler2DRect:
+ return GL_SAMPLER_2D_RECT_ANGLE;
+ case EbtSampler2DArray:
+ return GL_SAMPLER_2D_ARRAY;
+ case EbtSampler2DMS:
+ return GL_SAMPLER_2D_MULTISAMPLE;
+ case EbtSampler2DMSArray:
+ return GL_SAMPLER_2D_MULTISAMPLE_ARRAY;
+ case EbtSamplerCubeArray:
+ return GL_SAMPLER_CUBE_MAP_ARRAY;
+ case EbtSamplerBuffer:
+ return GL_SAMPLER_BUFFER;
+ case EbtISampler2D:
+ return GL_INT_SAMPLER_2D;
+ case EbtISampler3D:
+ return GL_INT_SAMPLER_3D;
+ case EbtISamplerCube:
+ return GL_INT_SAMPLER_CUBE;
+ case EbtISampler2DArray:
+ return GL_INT_SAMPLER_2D_ARRAY;
+ case EbtISampler2DMS:
+ return GL_INT_SAMPLER_2D_MULTISAMPLE;
+ case EbtISampler2DMSArray:
+ return GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY;
+ case EbtISamplerCubeArray:
+ return GL_INT_SAMPLER_CUBE_MAP_ARRAY;
+ case EbtISamplerBuffer:
+ return GL_INT_SAMPLER_BUFFER;
+ case EbtUSampler2D:
+ return GL_UNSIGNED_INT_SAMPLER_2D;
+ case EbtUSampler3D:
+ return GL_UNSIGNED_INT_SAMPLER_3D;
+ case EbtUSamplerCube:
+ return GL_UNSIGNED_INT_SAMPLER_CUBE;
+ case EbtUSampler2DArray:
+ return GL_UNSIGNED_INT_SAMPLER_2D_ARRAY;
+ case EbtUSampler2DMS:
+ return GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE;
+ case EbtUSampler2DMSArray:
+ return GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY;
+ case EbtUSamplerCubeArray:
+ return GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY;
+ case EbtUSamplerBuffer:
+ return GL_UNSIGNED_INT_SAMPLER_BUFFER;
+ case EbtSampler2DShadow:
+ return GL_SAMPLER_2D_SHADOW;
+ case EbtSamplerCubeShadow:
+ return GL_SAMPLER_CUBE_SHADOW;
+ case EbtSampler2DArrayShadow:
+ return GL_SAMPLER_2D_ARRAY_SHADOW;
+ case EbtSamplerCubeArrayShadow:
+ return GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW;
+ case EbtImage2D:
+ return GL_IMAGE_2D;
+ case EbtIImage2D:
+ return GL_INT_IMAGE_2D;
+ case EbtUImage2D:
+ return GL_UNSIGNED_INT_IMAGE_2D;
+ case EbtImage2DArray:
+ return GL_IMAGE_2D_ARRAY;
+ case EbtIImage2DArray:
+ return GL_INT_IMAGE_2D_ARRAY;
+ case EbtUImage2DArray:
+ return GL_UNSIGNED_INT_IMAGE_2D_ARRAY;
+ case EbtImage3D:
+ return GL_IMAGE_3D;
+ case EbtIImage3D:
+ return GL_INT_IMAGE_3D;
+ case EbtUImage3D:
+ return GL_UNSIGNED_INT_IMAGE_3D;
+ case EbtImageCube:
+ return GL_IMAGE_CUBE;
+ case EbtIImageCube:
+ return GL_INT_IMAGE_CUBE;
+ case EbtUImageCube:
+ return GL_UNSIGNED_INT_IMAGE_CUBE;
+ case EbtImageCubeArray:
+ return GL_IMAGE_CUBE_MAP_ARRAY;
+ case EbtIImageCubeArray:
+ return GL_INT_IMAGE_CUBE_MAP_ARRAY;
+ case EbtUImageCubeArray:
+ return GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY;
+ case EbtImageBuffer:
+ return GL_IMAGE_BUFFER;
+ case EbtIImageBuffer:
+ return GL_INT_IMAGE_BUFFER;
+ case EbtUImageBuffer:
+ return GL_UNSIGNED_INT_IMAGE_BUFFER;
+ case EbtAtomicCounter:
+ return GL_UNSIGNED_INT_ATOMIC_COUNTER;
+ case EbtSamplerVideoWEBGL:
+ return GL_SAMPLER_VIDEO_IMAGE_WEBGL;
+ case EbtPixelLocalANGLE:
+ case EbtIPixelLocalANGLE:
+ case EbtUPixelLocalANGLE:
+ // TODO(anglebug.com/7279): For now, we can expect PLS handles to be rewritten to images
+ // before anyone calls into here.
+ [[fallthrough]];
+ default:
+ UNREACHABLE();
+ return GL_NONE;
+ }
+}
+
+GLenum GLVariablePrecision(const TType &type)
+{
+ if (type.getBasicType() == EbtFloat)
+ {
+ switch (type.getPrecision())
+ {
+ case EbpHigh:
+ return GL_HIGH_FLOAT;
+ case EbpMedium:
+ return GL_MEDIUM_FLOAT;
+ case EbpLow:
+ return GL_LOW_FLOAT;
+ case EbpUndefined:
+ // Desktop specs do not use precision
+ return GL_NONE;
+ default:
+ UNREACHABLE();
+ }
+ }
+ else if (type.getBasicType() == EbtInt || type.getBasicType() == EbtUInt)
+ {
+ switch (type.getPrecision())
+ {
+ case EbpHigh:
+ return GL_HIGH_INT;
+ case EbpMedium:
+ return GL_MEDIUM_INT;
+ case EbpLow:
+ return GL_LOW_INT;
+ case EbpUndefined:
+ // Desktop specs do not use precision
+ return GL_NONE;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ // Other types (boolean, sampler) don't have a precision
+ return GL_NONE;
+}
+
+ImmutableString ArrayString(const TType &type)
+{
+ if (!type.isArray())
+ return ImmutableString("");
+
+ const TSpan<const unsigned int> &arraySizes = type.getArraySizes();
+ constexpr const size_t kMaxDecimalDigitsPerSize = 10u;
+ ImmutableStringBuilder arrayString(arraySizes.size() * (kMaxDecimalDigitsPerSize + 2u));
+ for (auto arraySizeIter = arraySizes.rbegin(); arraySizeIter != arraySizes.rend();
+ ++arraySizeIter)
+ {
+ arrayString << "[";
+ if (*arraySizeIter > 0)
+ {
+ arrayString.appendDecimal(*arraySizeIter);
+ }
+ arrayString << "]";
+ }
+ return arrayString;
+}
+
+ImmutableString GetTypeName(const TType &type, ShHashFunction64 hashFunction, NameMap *nameMap)
+{
+ if (type.getBasicType() == EbtStruct)
+ return HashName(type.getStruct(), hashFunction, nameMap);
+ else
+ return ImmutableString(type.getBuiltInTypeNameString());
+}
+
+bool IsVaryingOut(TQualifier qualifier)
+{
+ switch (qualifier)
+ {
+ case EvqVaryingOut:
+ case EvqSmoothOut:
+ case EvqFlatOut:
+ case EvqNoPerspectiveOut:
+ case EvqCentroidOut:
+ case EvqVertexOut:
+ case EvqGeometryOut:
+ case EvqTessControlOut:
+ case EvqTessEvaluationOut:
+ case EvqSampleOut:
+ case EvqPatchOut:
+ return true;
+
+ default:
+ break;
+ }
+
+ return false;
+}
+
+bool IsVaryingIn(TQualifier qualifier)
+{
+ switch (qualifier)
+ {
+ case EvqVaryingIn:
+ case EvqSmoothIn:
+ case EvqFlatIn:
+ case EvqNoPerspectiveIn:
+ case EvqCentroidIn:
+ case EvqFragmentIn:
+ case EvqGeometryIn:
+ case EvqTessControlIn:
+ case EvqTessEvaluationIn:
+ case EvqSampleIn:
+ case EvqPatchIn:
+ return true;
+
+ default:
+ break;
+ }
+
+ return false;
+}
+
+bool IsVarying(TQualifier qualifier)
+{
+ return IsVaryingIn(qualifier) || IsVaryingOut(qualifier);
+}
+
+bool IsMatrixGLType(GLenum type)
+{
+ switch (type)
+ {
+ case GL_FLOAT_MAT2:
+ case GL_FLOAT_MAT3:
+ case GL_FLOAT_MAT4:
+ case GL_FLOAT_MAT2x3:
+ case GL_FLOAT_MAT2x4:
+ case GL_FLOAT_MAT3x2:
+ case GL_FLOAT_MAT3x4:
+ case GL_FLOAT_MAT4x2:
+ case GL_FLOAT_MAT4x3:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool IsGeometryShaderInput(GLenum shaderType, TQualifier qualifier)
+{
+ return (qualifier == EvqGeometryIn) ||
+ ((shaderType == GL_GEOMETRY_SHADER_EXT) && IsInterpolationIn(qualifier));
+}
+
+bool IsTessellationControlShaderInput(GLenum shaderType, TQualifier qualifier)
+{
+ return qualifier == EvqTessControlIn ||
+ ((shaderType == GL_TESS_CONTROL_SHADER) && IsInterpolationIn(qualifier));
+}
+
+bool IsTessellationControlShaderOutput(GLenum shaderType, TQualifier qualifier)
+{
+ return qualifier == EvqTessControlOut ||
+ ((shaderType == GL_TESS_CONTROL_SHADER) && IsInterpolationOut(qualifier));
+}
+
+bool IsTessellationEvaluationShaderInput(GLenum shaderType, TQualifier qualifier)
+{
+ return qualifier == EvqTessEvaluationIn ||
+ ((shaderType == GL_TESS_EVALUATION_SHADER) && IsInterpolationIn(qualifier));
+}
+
+InterpolationType GetInterpolationType(TQualifier qualifier)
+{
+ switch (qualifier)
+ {
+ case EvqFlatIn:
+ case EvqFlatOut:
+ // The auxiliary storage qualifier patch is not used for interpolation
+ // it is a compile-time error to use interpolation qualifiers with patch
+ case EvqPatchIn:
+ case EvqPatchOut:
+ return INTERPOLATION_FLAT;
+
+ case EvqNoPerspectiveIn:
+ case EvqNoPerspectiveOut:
+ return INTERPOLATION_NOPERSPECTIVE;
+
+ case EvqSmoothIn:
+ case EvqSmoothOut:
+ case EvqVertexOut:
+ case EvqFragmentIn:
+ case EvqVaryingIn:
+ case EvqVaryingOut:
+ case EvqGeometryIn:
+ case EvqGeometryOut:
+ case EvqTessControlIn:
+ case EvqTessControlOut:
+ case EvqTessEvaluationIn:
+ case EvqTessEvaluationOut:
+ return INTERPOLATION_SMOOTH;
+
+ case EvqCentroidIn:
+ case EvqCentroidOut:
+ return INTERPOLATION_CENTROID;
+
+ case EvqSampleIn:
+ case EvqSampleOut:
+ return INTERPOLATION_SAMPLE;
+ default:
+ UNREACHABLE();
+ return INTERPOLATION_SMOOTH;
+ }
+}
+
+// a field may not have qualifer without in or out.
+InterpolationType GetFieldInterpolationType(TQualifier qualifier)
+{
+ switch (qualifier)
+ {
+ case EvqFlat:
+ return INTERPOLATION_FLAT;
+ case EvqNoPerspective:
+ return INTERPOLATION_NOPERSPECTIVE;
+ case EvqSmooth:
+ return INTERPOLATION_SMOOTH;
+ case EvqCentroid:
+ return INTERPOLATION_CENTROID;
+ default:
+ return GetInterpolationType(qualifier);
+ }
+}
+
+TType GetShaderVariableBasicType(const sh::ShaderVariable &var)
+{
+ switch (var.type)
+ {
+ case GL_BOOL:
+ return TType(EbtBool);
+ case GL_BOOL_VEC2:
+ return TType(EbtBool, 2);
+ case GL_BOOL_VEC3:
+ return TType(EbtBool, 3);
+ case GL_BOOL_VEC4:
+ return TType(EbtBool, 4);
+ 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();
+ }
+}
+
+void DeclareGlobalVariable(TIntermBlock *root, const TVariable *variable)
+{
+ TIntermDeclaration *declaration = new TIntermDeclaration();
+ declaration->appendDeclarator(new TIntermSymbol(variable));
+
+ TIntermSequence *globalSequence = root->getSequence();
+ globalSequence->insert(globalSequence->begin(), declaration);
+}
+
+// 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) || qualifier == EvqFragmentInOut;
+}
+
+bool IsBuiltinOutputVariable(TQualifier qualifier)
+{
+ switch (qualifier)
+ {
+ case EvqPosition:
+ case EvqPointSize:
+ case EvqFragDepth:
+ case EvqFragColor:
+ case EvqSecondaryFragColorEXT:
+ case EvqFragData:
+ case EvqSecondaryFragDataEXT:
+ case EvqClipDistance:
+ case EvqCullDistance:
+ case EvqLastFragData:
+ case EvqSampleMask:
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
+
+bool IsBuiltinFragmentInputVariable(TQualifier qualifier)
+{
+ switch (qualifier)
+ {
+ case EvqFragCoord:
+ case EvqPointCoord:
+ case EvqFrontFacing:
+ case EvqHelperInvocation:
+ case EvqLastFragData:
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
+
+bool IsShaderOutput(TQualifier qualifier)
+{
+ return IsVaryingOut(qualifier) || IsBuiltinOutputVariable(qualifier);
+}
+
+bool IsFragmentOutput(TQualifier qualifier)
+{
+ switch (qualifier)
+ {
+ case EvqFragmentOut:
+ case EvqFragmentInOut:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool IsOutputESSL(ShShaderOutput output)
+{
+ return output == SH_ESSL_OUTPUT;
+}
+
+bool IsOutputGLSL(ShShaderOutput output)
+{
+ switch (output)
+ {
+ case SH_GLSL_130_OUTPUT:
+ case SH_GLSL_140_OUTPUT:
+ case SH_GLSL_150_CORE_OUTPUT:
+ case SH_GLSL_330_CORE_OUTPUT:
+ case SH_GLSL_400_CORE_OUTPUT:
+ case SH_GLSL_410_CORE_OUTPUT:
+ case SH_GLSL_420_CORE_OUTPUT:
+ case SH_GLSL_430_CORE_OUTPUT:
+ case SH_GLSL_440_CORE_OUTPUT:
+ case SH_GLSL_450_CORE_OUTPUT:
+ case SH_GLSL_COMPATIBILITY_OUTPUT:
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
+bool IsOutputHLSL(ShShaderOutput output)
+{
+ switch (output)
+ {
+ case SH_HLSL_3_0_OUTPUT:
+ case SH_HLSL_4_1_OUTPUT:
+ case SH_HLSL_4_0_FL9_3_OUTPUT:
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
+bool IsOutputVulkan(ShShaderOutput output)
+{
+ return output == SH_SPIRV_VULKAN_OUTPUT;
+}
+bool IsOutputMetal(ShShaderOutput output)
+{
+ return output == SH_SPIRV_METAL_OUTPUT;
+}
+bool IsOutputMetalDirect(ShShaderOutput output)
+{
+ return output == SH_MSL_METAL_OUTPUT;
+}
+
+bool IsInShaderStorageBlock(TIntermTyped *node)
+{
+ TIntermSwizzle *swizzleNode = node->getAsSwizzleNode();
+ if (swizzleNode)
+ {
+ return IsInShaderStorageBlock(swizzleNode->getOperand());
+ }
+
+ TIntermBinary *binaryNode = node->getAsBinaryNode();
+ if (binaryNode)
+ {
+ switch (binaryNode->getOp())
+ {
+ case EOpIndexDirectInterfaceBlock:
+ case EOpIndexIndirect:
+ case EOpIndexDirect:
+ case EOpIndexDirectStruct:
+ return IsInShaderStorageBlock(binaryNode->getLeft());
+ default:
+ return false;
+ }
+ }
+
+ const TType &type = node->getType();
+ return type.getQualifier() == EvqBuffer;
+}
+
+GLenum GetImageInternalFormatType(TLayoutImageInternalFormat iifq)
+{
+ switch (iifq)
+ {
+ case EiifRGBA32F:
+ return GL_RGBA32F;
+ case EiifRGBA16F:
+ return GL_RGBA16F;
+ case EiifR32F:
+ return GL_R32F;
+ case EiifRGBA32UI:
+ return GL_RGBA32UI;
+ case EiifRGBA16UI:
+ return GL_RGBA16UI;
+ case EiifRGBA8UI:
+ return GL_RGBA8UI;
+ case EiifR32UI:
+ return GL_R32UI;
+ case EiifRGBA32I:
+ return GL_RGBA32I;
+ case EiifRGBA16I:
+ return GL_RGBA16I;
+ case EiifRGBA8I:
+ return GL_RGBA8I;
+ case EiifR32I:
+ return GL_R32I;
+ case EiifRGBA8:
+ return GL_RGBA8;
+ case EiifRGBA8_SNORM:
+ return GL_RGBA8_SNORM;
+ default:
+ return GL_NONE;
+ }
+}
+
+bool IsSpecWithFunctionBodyNewScope(ShShaderSpec shaderSpec, int shaderVersion)
+{
+ return (shaderVersion == 100 && !sh::IsWebGLBasedSpec(shaderSpec));
+}
+
+ImplicitTypeConversion GetConversion(TBasicType t1, TBasicType t2)
+{
+ if (t1 == t2)
+ return ImplicitTypeConversion::Same;
+
+ switch (t1)
+ {
+ case EbtInt:
+ switch (t2)
+ {
+ case EbtInt:
+ UNREACHABLE();
+ break;
+ case EbtUInt:
+ return ImplicitTypeConversion::Invalid;
+ case EbtFloat:
+ return ImplicitTypeConversion::Left;
+ default:
+ return ImplicitTypeConversion::Invalid;
+ }
+ break;
+ case EbtUInt:
+ switch (t2)
+ {
+ case EbtInt:
+ return ImplicitTypeConversion::Invalid;
+ case EbtUInt:
+ UNREACHABLE();
+ break;
+ case EbtFloat:
+ return ImplicitTypeConversion::Left;
+ default:
+ return ImplicitTypeConversion::Invalid;
+ }
+ break;
+ case EbtFloat:
+ switch (t2)
+ {
+ case EbtInt:
+ case EbtUInt:
+ return ImplicitTypeConversion::Right;
+ case EbtFloat:
+ UNREACHABLE();
+ break;
+ default:
+ return ImplicitTypeConversion::Invalid;
+ }
+ break;
+ default:
+ return ImplicitTypeConversion::Invalid;
+ }
+ return ImplicitTypeConversion::Invalid;
+}
+
+bool IsValidImplicitConversion(sh::ImplicitTypeConversion conversion, TOperator op)
+{
+ switch (conversion)
+ {
+ case sh::ImplicitTypeConversion::Same:
+ return true;
+ case sh::ImplicitTypeConversion::Left:
+ switch (op)
+ {
+ case EOpEqual:
+ case EOpNotEqual:
+ case EOpLessThan:
+ case EOpGreaterThan:
+ case EOpLessThanEqual:
+ case EOpGreaterThanEqual:
+ case EOpAdd:
+ case EOpSub:
+ case EOpMul:
+ case EOpDiv:
+ return true;
+ default:
+ break;
+ }
+ break;
+ case sh::ImplicitTypeConversion::Right:
+ switch (op)
+ {
+ case EOpAssign:
+ case EOpInitialize:
+ case EOpEqual:
+ case EOpNotEqual:
+ case EOpLessThan:
+ case EOpGreaterThan:
+ case EOpLessThanEqual:
+ case EOpGreaterThanEqual:
+ case EOpAdd:
+ case EOpSub:
+ case EOpMul:
+ case EOpDiv:
+ case EOpAddAssign:
+ case EOpSubAssign:
+ case EOpMulAssign:
+ case EOpDivAssign:
+ return true;
+ default:
+ break;
+ }
+ break;
+ case sh::ImplicitTypeConversion::Invalid:
+ break;
+ }
+ return false;
+}
+
+bool IsPrecisionApplicableToType(TBasicType type)
+{
+ switch (type)
+ {
+ case EbtInt:
+ case EbtUInt:
+ case EbtFloat:
+ // TODO: find all types where precision is applicable; for example samplers.
+ // http://anglebug.com/6132
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool IsRedeclarableBuiltIn(const ImmutableString &name)
+{
+ return name == "gl_ClipDistance" || name == "gl_CullDistance" || name == "gl_LastFragData" ||
+ name == "gl_PerVertex" || name == "gl_Position" || name == "gl_PointSize";
+}
+
+size_t FindFieldIndex(const TFieldList &fieldList, const char *fieldName)
+{
+ for (size_t fieldIndex = 0; fieldIndex < fieldList.size(); ++fieldIndex)
+ {
+ if (strcmp(fieldList[fieldIndex]->name().data(), fieldName) == 0)
+ {
+ return fieldIndex;
+ }
+ }
+ UNREACHABLE();
+ return 0;
+}
+
+} // namespace sh
diff --git a/gfx/angle/checkout/src/compiler/translator/util.h b/gfx/angle/checkout/src/compiler/translator/util.h
new file mode 100644
index 0000000000..7d7a929f8a
--- /dev/null
+++ b/gfx/angle/checkout/src/compiler/translator/util.h
@@ -0,0 +1,108 @@
+//
+// Copyright 2002 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_UTIL_H_
+#define COMPILER_TRANSLATOR_UTIL_H_
+
+#include <stack>
+
+#include <GLSLANG/ShaderLang.h>
+#include "angle_gl.h"
+
+#include "compiler/translator/HashNames.h"
+#include "compiler/translator/ImmutableString.h"
+#include "compiler/translator/Operator_autogen.h"
+#include "compiler/translator/Types.h"
+
+// If overflow happens, clamp the value to UINT_MIN or UINT_MAX.
+// Return false if overflow happens.
+bool atoi_clamp(const char *str, unsigned int *value);
+
+namespace sh
+{
+
+// Keeps track of whether an implicit conversion from int/uint to float is possible.
+// These conversions are supported in desktop GLSL shaders only.
+// Also keeps track of which side of operation should be converted.
+enum class ImplicitTypeConversion
+{
+ Same,
+ Left,
+ Right,
+ Invalid,
+};
+
+class TIntermBlock;
+class TSymbolTable;
+class TIntermTyped;
+
+float NumericLexFloat32OutOfRangeToInfinity(const std::string &str);
+
+// strtof_clamp is like strtof but
+// 1. it forces C locale, i.e. forcing '.' as decimal point.
+// 2. it sets the value to infinity if overflow happens.
+// 3. str should be guaranteed to be in the valid format for a floating point number as defined
+// by the grammar in the ESSL 3.00.6 spec section 4.1.4.
+// Return false if overflow happens.
+bool strtof_clamp(const std::string &str, float *value);
+
+GLenum GLVariableType(const TType &type);
+GLenum GLVariablePrecision(const TType &type);
+bool IsVaryingIn(TQualifier qualifier);
+bool IsVaryingOut(TQualifier qualifier);
+bool IsVarying(TQualifier qualifier);
+bool IsMatrixGLType(GLenum type);
+bool IsGeometryShaderInput(GLenum shaderType, TQualifier qualifier);
+bool IsTessellationControlShaderInput(GLenum shaderType, TQualifier qualifier);
+bool IsTessellationControlShaderOutput(GLenum shaderType, TQualifier qualifier);
+bool IsTessellationEvaluationShaderInput(GLenum shaderType, TQualifier qualifier);
+InterpolationType GetInterpolationType(TQualifier qualifier);
+InterpolationType GetFieldInterpolationType(TQualifier qualifier);
+
+// Returns array brackets including size with outermost array size first, as specified in GLSL ES
+// 3.10 section 4.1.9.
+ImmutableString ArrayString(const TType &type);
+
+ImmutableString GetTypeName(const TType &type, ShHashFunction64 hashFunction, NameMap *nameMap);
+
+TType GetShaderVariableBasicType(const sh::ShaderVariable &var);
+
+void DeclareGlobalVariable(TIntermBlock *root, const TVariable *variable);
+
+bool IsBuiltinOutputVariable(TQualifier qualifier);
+bool IsBuiltinFragmentInputVariable(TQualifier qualifier);
+bool CanBeInvariantESSL1(TQualifier qualifier);
+bool CanBeInvariantESSL3OrGreater(TQualifier qualifier);
+bool IsShaderOutput(TQualifier qualifier);
+bool IsFragmentOutput(TQualifier qualifier);
+bool IsOutputESSL(ShShaderOutput output);
+bool IsOutputGLSL(ShShaderOutput output);
+bool IsOutputHLSL(ShShaderOutput output);
+bool IsOutputVulkan(ShShaderOutput output);
+bool IsOutputMetal(ShShaderOutput output);
+bool IsOutputMetalDirect(ShShaderOutput output);
+
+bool IsInShaderStorageBlock(TIntermTyped *node);
+
+GLenum GetImageInternalFormatType(TLayoutImageInternalFormat iifq);
+// ESSL 1.00 shaders nest function body scope within function parameter scope
+bool IsSpecWithFunctionBodyNewScope(ShShaderSpec shaderSpec, int shaderVersion);
+
+// Helper functions for implicit conversions
+ImplicitTypeConversion GetConversion(TBasicType t1, TBasicType t2);
+
+bool IsValidImplicitConversion(ImplicitTypeConversion conversion, TOperator op);
+
+// Whether the given basic type requires precision.
+bool IsPrecisionApplicableToType(TBasicType type);
+
+// Whether this is the name of a built-in that can be redeclared by the shader.
+bool IsRedeclarableBuiltIn(const ImmutableString &name);
+
+size_t FindFieldIndex(const TFieldList &fieldList, const char *fieldName);
+} // namespace sh
+
+#endif // COMPILER_TRANSLATOR_UTIL_H_
diff --git a/gfx/angle/checkout/src/gpu_info_util/SystemInfo.cpp b/gfx/angle/checkout/src/gpu_info_util/SystemInfo.cpp
new file mode 100644
index 0000000000..b2149c9f63
--- /dev/null
+++ b/gfx/angle/checkout/src/gpu_info_util/SystemInfo.cpp
@@ -0,0 +1,418 @@
+//
+// Copyright 2013 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.
+//
+
+// SystemInfo.cpp: implementation of the system-agnostic parts of SystemInfo.h
+
+#include "gpu_info_util/SystemInfo.h"
+
+#include <cstring>
+#include <iostream>
+#include <sstream>
+
+#include "anglebase/no_destructor.h"
+#include "common/debug.h"
+#include "common/string_utils.h"
+#include "common/system_utils.h"
+
+namespace angle
+{
+namespace
+{
+constexpr char kANGLEPreferredDeviceEnv[] = "ANGLE_PREFERRED_DEVICE";
+}
+
+std::string VendorName(VendorID vendor)
+{
+ switch (vendor)
+ {
+ case kVendorID_AMD:
+ return "AMD";
+ case kVendorID_ARM:
+ return "ARM";
+ case kVendorID_Broadcom:
+ return "Broadcom";
+ case kVendorID_GOOGLE:
+ return "Google";
+ case kVendorID_ImgTec:
+ return "ImgTec";
+ case kVendorID_Intel:
+ return "Intel";
+ case kVendorID_Kazan:
+ return "Kazan";
+ case kVendorID_NVIDIA:
+ return "NVIDIA";
+ case kVendorID_Qualcomm:
+ return "Qualcomm";
+ case kVendorID_VeriSilicon:
+ return "VeriSilicon";
+ case kVendorID_Vivante:
+ return "Vivante";
+ case kVendorID_VMWare:
+ return "VMWare";
+ case kVendorID_Apple:
+ return "Apple";
+ case kVendorID_Microsoft:
+ return "Microsoft";
+ default:
+ return "Unknown (" + std::to_string(vendor) + ")";
+ }
+}
+
+GPUDeviceInfo::GPUDeviceInfo() = default;
+
+GPUDeviceInfo::~GPUDeviceInfo() = default;
+
+GPUDeviceInfo::GPUDeviceInfo(const GPUDeviceInfo &other) = default;
+
+SystemInfo::SystemInfo() = default;
+
+SystemInfo::~SystemInfo() = default;
+
+SystemInfo::SystemInfo(const SystemInfo &other) = default;
+
+bool SystemInfo::hasNVIDIAGPU() const
+{
+ for (const GPUDeviceInfo &gpu : gpus)
+ {
+ if (IsNVIDIA(gpu.vendorId))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool SystemInfo::hasIntelGPU() const
+{
+ for (const GPUDeviceInfo &gpu : gpus)
+ {
+ if (IsIntel(gpu.vendorId))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool SystemInfo::hasAMDGPU() const
+{
+ for (const GPUDeviceInfo &gpu : gpus)
+ {
+ if (IsAMD(gpu.vendorId))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+std::optional<size_t> SystemInfo::getPreferredGPUIndex() const
+{
+ std::string device = GetPreferredDeviceString();
+ if (!device.empty())
+ {
+ for (size_t i = 0; i < gpus.size(); ++i)
+ {
+ std::string vendor = VendorName(gpus[i].vendorId);
+ ToLower(&vendor);
+ if (vendor == device)
+ return i;
+ }
+ }
+ return std::nullopt;
+}
+
+bool IsAMD(VendorID vendorId)
+{
+ return vendorId == kVendorID_AMD;
+}
+
+bool IsARM(VendorID vendorId)
+{
+ return vendorId == kVendorID_ARM;
+}
+
+bool IsBroadcom(VendorID vendorId)
+{
+ return vendorId == kVendorID_Broadcom;
+}
+
+bool IsImgTec(VendorID vendorId)
+{
+ return vendorId == kVendorID_ImgTec;
+}
+
+bool IsKazan(VendorID vendorId)
+{
+ return vendorId == kVendorID_Kazan;
+}
+
+bool IsIntel(VendorID vendorId)
+{
+ return vendorId == kVendorID_Intel;
+}
+
+bool IsNVIDIA(VendorID vendorId)
+{
+ return vendorId == kVendorID_NVIDIA;
+}
+
+bool IsQualcomm(VendorID vendorId)
+{
+ return vendorId == kVendorID_Qualcomm;
+}
+
+bool IsGoogle(VendorID vendorId)
+{
+ return vendorId == kVendorID_GOOGLE;
+}
+
+bool IsVeriSilicon(VendorID vendorId)
+{
+ return vendorId == kVendorID_VeriSilicon;
+}
+
+bool IsVMWare(VendorID vendorId)
+{
+ return vendorId == kVendorID_VMWare;
+}
+
+bool IsVivante(VendorID vendorId)
+{
+ return vendorId == kVendorID_Vivante;
+}
+
+bool IsApple(VendorID vendorId)
+{
+ return vendorId == kVendorID_Apple;
+}
+
+bool IsMicrosoft(VendorID vendorId)
+{
+ return vendorId == kVendorID_Microsoft;
+}
+
+bool ParseAMDBrahmaDriverVersion(const std::string &content, std::string *version)
+{
+ const size_t begin = content.find_first_of("0123456789");
+ if (begin == std::string::npos)
+ {
+ return false;
+ }
+
+ const size_t end = content.find_first_not_of("0123456789.", begin);
+ if (end == std::string::npos)
+ {
+ *version = content.substr(begin);
+ }
+ else
+ {
+ *version = content.substr(begin, end - begin);
+ }
+ return true;
+}
+
+bool ParseAMDCatalystDriverVersion(const std::string &content, std::string *version)
+{
+ std::istringstream stream(content);
+
+ std::string line;
+ while (std::getline(stream, line))
+ {
+ static const char kReleaseVersion[] = "ReleaseVersion=";
+ if (line.compare(0, std::strlen(kReleaseVersion), kReleaseVersion) != 0)
+ {
+ continue;
+ }
+
+ if (ParseAMDBrahmaDriverVersion(line, version))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool ParseMacMachineModel(const std::string &identifier,
+ std::string *type,
+ int32_t *major,
+ int32_t *minor)
+{
+ size_t numberLoc = identifier.find_first_of("0123456789");
+ if (numberLoc == std::string::npos)
+ {
+ return false;
+ }
+
+ size_t commaLoc = identifier.find(',', numberLoc);
+ if (commaLoc == std::string::npos || commaLoc >= identifier.size())
+ {
+ return false;
+ }
+
+ const char *numberPtr = &identifier[numberLoc];
+ const char *commaPtr = &identifier[commaLoc + 1];
+ char *endPtr = nullptr;
+
+ int32_t majorTmp = static_cast<int32_t>(std::strtol(numberPtr, &endPtr, 10));
+ if (endPtr == numberPtr)
+ {
+ return false;
+ }
+
+ int32_t minorTmp = static_cast<int32_t>(std::strtol(commaPtr, &endPtr, 10));
+ if (endPtr == commaPtr)
+ {
+ return false;
+ }
+
+ *major = majorTmp;
+ *minor = minorTmp;
+ *type = identifier.substr(0, numberLoc);
+
+ return true;
+}
+
+bool CMDeviceIDToDeviceAndVendorID(const std::string &id, uint32_t *vendorId, uint32_t *deviceId)
+{
+ unsigned int vendor = 0;
+ unsigned int device = 0;
+
+ bool success = id.length() >= 21 && HexStringToUInt(id.substr(8, 4), &vendor) &&
+ HexStringToUInt(id.substr(17, 4), &device);
+
+ *vendorId = vendor;
+ *deviceId = device;
+ return success;
+}
+
+void GetDualGPUInfo(SystemInfo *info)
+{
+ ASSERT(!info->gpus.empty());
+
+ // On dual-GPU systems we assume the non-Intel GPU is the graphics one.
+ // TODO: this is incorrect and problematic. activeGPUIndex must be removed if it cannot be
+ // determined correctly. A potential solution is to create an OpenGL context and parse
+ // GL_VENDOR. Currently, our test infrastructure is relying on this information and incorrectly
+ // applies test expectations on dual-GPU systems when the Intel GPU is active.
+ // http://anglebug.com/6174.
+ int active = 0;
+ bool hasIntel = false;
+ for (size_t i = 0; i < info->gpus.size(); ++i)
+ {
+ if (IsIntel(info->gpus[i].vendorId))
+ {
+ hasIntel = true;
+ }
+ if (IsIntel(info->gpus[active].vendorId))
+ {
+ active = static_cast<int>(i);
+ }
+ }
+
+ // Assume that a combination of NVIDIA or AMD with Intel means Optimus or AMD Switchable
+ info->activeGPUIndex = active;
+ info->isOptimus = hasIntel && IsNVIDIA(info->gpus[active].vendorId);
+ info->isAMDSwitchable = hasIntel && IsAMD(info->gpus[active].vendorId);
+}
+
+void PrintSystemInfo(const SystemInfo &info)
+{
+ std::cout << info.gpus.size() << " GPUs:\n";
+
+ for (size_t i = 0; i < info.gpus.size(); i++)
+ {
+ const auto &gpu = info.gpus[i];
+
+ std::cout << " " << i << " - " << VendorName(gpu.vendorId) << " device id: 0x" << std::hex
+ << std::uppercase << gpu.deviceId << std::dec << ", revision id: 0x" << std::hex
+ << std::uppercase << gpu.revisionId << std::dec << ", system device id: 0x"
+ << std::hex << std::uppercase << gpu.systemDeviceId << std::dec << "\n";
+ if (!gpu.driverVendor.empty())
+ {
+ std::cout << " Driver Vendor: " << gpu.driverVendor << "\n";
+ }
+ if (!gpu.driverVersion.empty())
+ {
+ std::cout << " Driver Version: " << gpu.driverVersion << "\n";
+ }
+ if (!gpu.driverDate.empty())
+ {
+ std::cout << " Driver Date: " << gpu.driverDate << "\n";
+ }
+ if (gpu.detailedDriverVersion.major != 0 || gpu.detailedDriverVersion.minor != 0 ||
+ gpu.detailedDriverVersion.subMinor != 0 || gpu.detailedDriverVersion.patch != 0)
+ {
+ std::cout << " Detailed Driver Version:\n"
+ << " major: " << gpu.detailedDriverVersion.major
+ << " minor: " << gpu.detailedDriverVersion.minor
+ << " subMinor: " << gpu.detailedDriverVersion.subMinor
+ << " patch: " << gpu.detailedDriverVersion.patch << "\n";
+ }
+ }
+
+ std::cout << "\n";
+ std::cout << "Active GPU: " << info.activeGPUIndex << "\n";
+
+ std::cout << "\n";
+ std::cout << "Optimus: " << (info.isOptimus ? "true" : "false") << "\n";
+ std::cout << "AMD Switchable: " << (info.isAMDSwitchable ? "true" : "false") << "\n";
+ std::cout << "Mac Switchable: " << (info.isMacSwitchable ? "true" : "false") << "\n";
+ std::cout << "Needs EAGL on Mac: " << (info.needsEAGLOnMac ? "true" : "false") << "\n";
+
+ std::cout << "\n";
+ if (!info.machineManufacturer.empty())
+ {
+ std::cout << "Machine Manufacturer: " << info.machineManufacturer << "\n";
+ }
+ if (info.androidSdkLevel != 0)
+ {
+ std::cout << "Android SDK Level: " << info.androidSdkLevel << "\n";
+ }
+ if (!info.machineModelName.empty())
+ {
+ std::cout << "Machine Model: " << info.machineModelName << "\n";
+ }
+ if (!info.machineModelVersion.empty())
+ {
+ std::cout << "Machine Model Version: " << info.machineModelVersion << "\n";
+ }
+ std::cout << std::endl;
+}
+
+VersionInfo ParseNvidiaDriverVersion(uint32_t version)
+{
+ return {
+ version >> 22, // major
+ version >> 14 & 0xff, // minor
+ version >> 6 & 0xff, // subMinor
+ version & 0x3f // patch
+ };
+}
+
+uint64_t GetSystemDeviceIdFromParts(uint32_t highPart, uint32_t lowPart)
+{
+ return (static_cast<uint64_t>(highPart) << 32) | lowPart;
+}
+
+uint32_t GetSystemDeviceIdHighPart(uint64_t systemDeviceId)
+{
+ return (systemDeviceId >> 32) & 0xffffffff;
+}
+
+uint32_t GetSystemDeviceIdLowPart(uint64_t systemDeviceId)
+{
+ return systemDeviceId & 0xffffffff;
+}
+
+std::string GetPreferredDeviceString()
+{
+ std::string device = angle::GetEnvironmentVar(kANGLEPreferredDeviceEnv);
+ ToLower(&device);
+ return device;
+}
+
+} // namespace angle
diff --git a/gfx/angle/checkout/src/gpu_info_util/SystemInfo.h b/gfx/angle/checkout/src/gpu_info_util/SystemInfo.h
new file mode 100644
index 0000000000..7347404ae7
--- /dev/null
+++ b/gfx/angle/checkout/src/gpu_info_util/SystemInfo.h
@@ -0,0 +1,179 @@
+//
+// Copyright 2013 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.
+//
+
+// SystemInfo.h: gathers information available without starting a GPU driver.
+
+#ifndef GPU_INFO_UTIL_SYSTEM_INFO_H_
+#define GPU_INFO_UTIL_SYSTEM_INFO_H_
+
+#include <cstdint>
+#include <optional>
+#include <string>
+#include <vector>
+
+namespace angle
+{
+
+using VendorID = uint32_t;
+using DeviceID = uint32_t;
+using RevisionID = uint32_t;
+using SystemDeviceID = uint64_t;
+using DriverID = uint32_t;
+
+struct VersionInfo
+{
+ uint32_t major = 0;
+ uint32_t minor = 0;
+ uint32_t subMinor = 0;
+ uint32_t patch = 0;
+};
+
+struct GPUDeviceInfo
+{
+ GPUDeviceInfo();
+ ~GPUDeviceInfo();
+
+ GPUDeviceInfo(const GPUDeviceInfo &other);
+
+ VendorID vendorId = 0;
+ DeviceID deviceId = 0;
+ RevisionID revisionId = 0;
+ SystemDeviceID systemDeviceId = 0;
+
+ std::string driverVendor;
+ std::string driverVersion;
+ std::string driverDate;
+
+ // Fields only available via GetSystemInfoVulkan:
+ VersionInfo detailedDriverVersion;
+ DriverID driverId = 0;
+ uint32_t driverApiVersion = 0;
+};
+
+struct SystemInfo
+{
+ SystemInfo();
+ ~SystemInfo();
+
+ SystemInfo(const SystemInfo &other);
+
+ bool hasNVIDIAGPU() const;
+ bool hasIntelGPU() const;
+ bool hasAMDGPU() const;
+
+ // Returns the index to `gpus` if the entry matches the preferred device string.
+ std::optional<size_t> getPreferredGPUIndex() const;
+
+ std::vector<GPUDeviceInfo> gpus;
+
+ // Index of the GPU expected to be used for 3D graphics. Based on a best-guess heuristic on
+ // some platforms. On Windows, this is accurate. Note `gpus` must be checked for empty before
+ // indexing.
+ int activeGPUIndex = 0;
+
+ bool isOptimus = false;
+ bool isAMDSwitchable = false;
+ // Only true on dual-GPU Mac laptops.
+ bool isMacSwitchable = false;
+ // Only true on Apple Silicon Macs when running in macCatalyst.
+ bool needsEAGLOnMac = false;
+
+ // Only available on Android
+ std::string machineManufacturer;
+ int androidSdkLevel = 0;
+
+ // Only available on macOS and Android
+ std::string machineModelName;
+
+ // Only available on macOS
+ std::string machineModelVersion;
+};
+
+// Gathers information about the system without starting a GPU driver and returns them in `info`.
+// Returns true if all info was gathered, false otherwise. Even when false is returned, `info` will
+// be filled with partial information.
+bool GetSystemInfo(SystemInfo *info);
+
+// Vulkan-specific info collection.
+bool GetSystemInfoVulkan(SystemInfo *info);
+
+// Known PCI vendor IDs
+constexpr VendorID kVendorID_AMD = 0x1002;
+constexpr VendorID kVendorID_ARM = 0x13B5;
+constexpr VendorID kVendorID_Broadcom = 0x14E4;
+constexpr VendorID kVendorID_GOOGLE = 0x1AE0;
+constexpr VendorID kVendorID_ImgTec = 0x1010;
+constexpr VendorID kVendorID_Intel = 0x8086;
+constexpr VendorID kVendorID_NVIDIA = 0x10DE;
+constexpr VendorID kVendorID_Qualcomm = 0x5143;
+constexpr VendorID kVendorID_VMWare = 0x15ad;
+constexpr VendorID kVendorID_Apple = 0x106B;
+constexpr VendorID kVendorID_Microsoft = 0x1414;
+
+// Known non-PCI (i.e. Khronos-registered) vendor IDs
+constexpr VendorID kVendorID_Vivante = 0x10001;
+constexpr VendorID kVendorID_VeriSilicon = 0x10002;
+constexpr VendorID kVendorID_Kazan = 0x10003;
+constexpr VendorID kVendorID_CodePlay = 0x10004;
+constexpr VendorID kVendorID_Mesa = 0x10005;
+constexpr VendorID kVendorID_PoCL = 0x10006;
+
+// Known device IDs
+constexpr DeviceID kDeviceID_Swiftshader = 0xC0DE;
+constexpr DeviceID kDeviceID_Adreno540 = 0x5040001;
+constexpr DeviceID kDeviceID_UHD630Mobile = 0x3E9B;
+
+// Predicates on vendor IDs
+bool IsAMD(VendorID vendorId);
+bool IsARM(VendorID vendorId);
+bool IsBroadcom(VendorID vendorId);
+bool IsImgTec(VendorID vendorId);
+bool IsIntel(VendorID vendorId);
+bool IsKazan(VendorID vendorId);
+bool IsNVIDIA(VendorID vendorId);
+bool IsQualcomm(VendorID vendorId);
+bool IsGoogle(VendorID vendorId);
+bool IsSwiftshader(VendorID vendorId);
+bool IsVeriSilicon(VendorID vendorId);
+bool IsVMWare(VendorID vendorId);
+bool IsVivante(VendorID vendorId);
+bool IsApple(VendorID vendorId);
+bool IsMicrosoft(VendorID vendorId);
+
+// Returns a readable vendor name given the VendorID
+std::string VendorName(VendorID vendor);
+
+// Use a heuristic to attempt to find the GPU used for 3D graphics. Sets activeGPUIndex,
+// isOptimus, and isAMDSwitchable.
+// Always assumes the non-Intel GPU is active on dual-GPU machines.
+void GetDualGPUInfo(SystemInfo *info);
+
+// Dumps the system info to stdout.
+void PrintSystemInfo(const SystemInfo &info);
+
+VersionInfo ParseNvidiaDriverVersion(uint32_t version);
+
+#if defined(ANGLE_PLATFORM_MACOS) || defined(ANGLE_PLATFORM_MACCATALYST)
+// Helper to get the active GPU ID from a given Core Graphics display ID.
+uint64_t GetGpuIDFromDisplayID(uint32_t displayID);
+
+// Helper to get the active GPU ID from an OpenGL display mask.
+uint64_t GetGpuIDFromOpenGLDisplayMask(uint32_t displayMask);
+
+// Get VendorID from metal device's registry ID
+VendorID GetVendorIDFromMetalDeviceRegistryID(uint64_t registryID);
+#endif
+
+uint64_t GetSystemDeviceIdFromParts(uint32_t highPart, uint32_t lowPart);
+uint32_t GetSystemDeviceIdHighPart(uint64_t systemDeviceId);
+uint32_t GetSystemDeviceIdLowPart(uint64_t systemDeviceId);
+
+// Returns lower-case of ANGLE_PREFERRED_DEVICE environment variable contents.
+std::string GetPreferredDeviceString();
+
+} // namespace angle
+
+#endif // GPU_INFO_UTIL_SYSTEM_INFO_H_
diff --git a/gfx/angle/checkout/src/gpu_info_util/SystemInfo_internal.h b/gfx/angle/checkout/src/gpu_info_util/SystemInfo_internal.h
new file mode 100644
index 0000000000..d300bd81a9
--- /dev/null
+++ b/gfx/angle/checkout/src/gpu_info_util/SystemInfo_internal.h
@@ -0,0 +1,42 @@
+//
+// Copyright 2013 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.
+//
+
+// SystemInfo_internal.h: Functions used by the SystemInfo_* files and unittests
+
+#ifndef GPU_INFO_UTIL_SYSTEM_INFO_INTERNAL_H_
+#define GPU_INFO_UTIL_SYSTEM_INFO_INTERNAL_H_
+
+#include "gpu_info_util/SystemInfo.h"
+
+namespace angle
+{
+
+// Defined in SystemInfo_libpci when GPU_INFO_USE_LIBPCI is defined.
+bool GetPCIDevicesWithLibPCI(std::vector<GPUDeviceInfo> *devices);
+// Defined in SystemInfo_x11 when GPU_INFO_USE_X11 is defined.
+bool GetNvidiaDriverVersionWithXNVCtrl(std::string *version);
+
+// Target specific helper functions that can be compiled on all targets
+// Live in SystemInfo.cpp
+bool ParseAMDBrahmaDriverVersion(const std::string &content, std::string *version);
+bool ParseAMDCatalystDriverVersion(const std::string &content, std::string *version);
+bool ParseMacMachineModel(const std::string &identifier,
+ std::string *type,
+ int32_t *major,
+ int32_t *minor);
+bool CMDeviceIDToDeviceAndVendorID(const std::string &id, uint32_t *vendorId, uint32_t *deviceId);
+
+#if defined(ANGLE_PLATFORM_MACOS) || defined(ANGLE_PLATFORM_MACCATALYST)
+bool GetSystemInfo_mac(SystemInfo *info);
+#endif
+
+#if defined(ANGLE_PLATFORM_IOS) || (defined(ANGLE_PLATFORM_MACCATALYST) && defined(ANGLE_CPU_ARM64))
+bool GetSystemInfo_ios(SystemInfo *info);
+#endif
+
+} // namespace angle
+
+#endif // GPU_INFO_UTIL_SYSTEM_INFO_INTERNAL_H_
diff --git a/gfx/angle/checkout/src/gpu_info_util/SystemInfo_vulkan.cpp b/gfx/angle/checkout/src/gpu_info_util/SystemInfo_vulkan.cpp
new file mode 100644
index 0000000000..96b6019fd3
--- /dev/null
+++ b/gfx/angle/checkout/src/gpu_info_util/SystemInfo_vulkan.cpp
@@ -0,0 +1,284 @@
+//
+// Copyright 2020 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.
+//
+
+// SystemInfo_vulkan.cpp: Generic vulkan implementation of SystemInfo.h
+// TODO: Use VK_KHR_driver_properties. http://anglebug.com/5103
+
+#include "gpu_info_util/SystemInfo_vulkan.h"
+
+#include <vulkan/vulkan.h>
+#include "gpu_info_util/SystemInfo_internal.h"
+
+#include <cstring>
+#include <fstream>
+
+#include "common/angleutils.h"
+#include "common/debug.h"
+#include "common/system_utils.h"
+#include "common/vulkan/libvulkan_loader.h"
+
+namespace angle
+{
+class VulkanLibrary final : NonCopyable
+{
+ public:
+ VulkanLibrary() = default;
+
+ ~VulkanLibrary()
+ {
+ if (mInstance != VK_NULL_HANDLE)
+ {
+ auto pfnDestroyInstance = getProc<PFN_vkDestroyInstance>("vkDestroyInstance");
+ if (pfnDestroyInstance)
+ {
+ pfnDestroyInstance(mInstance, nullptr);
+ }
+ }
+
+ CloseSystemLibrary(mLibVulkan);
+ }
+
+ VkInstance getVulkanInstance()
+ {
+ mLibVulkan = vk::OpenLibVulkan();
+ if (!mLibVulkan)
+ {
+ // If Vulkan doesn't exist, bail-out early:
+ return VK_NULL_HANDLE;
+ }
+
+ // Determine the available Vulkan instance version:
+ uint32_t instanceVersion = VK_API_VERSION_1_0;
+#if defined(VK_VERSION_1_1)
+ auto pfnEnumerateInstanceVersion =
+ getProc<PFN_vkEnumerateInstanceVersion>("vkEnumerateInstanceVersion");
+ if (!pfnEnumerateInstanceVersion ||
+ pfnEnumerateInstanceVersion(&instanceVersion) != VK_SUCCESS)
+ {
+ instanceVersion = VK_API_VERSION_1_0;
+ }
+#endif // VK_VERSION_1_1
+
+ // Create a Vulkan instance:
+ VkApplicationInfo appInfo;
+ appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
+ appInfo.pNext = nullptr;
+ appInfo.pApplicationName = "";
+ appInfo.applicationVersion = 1;
+ appInfo.pEngineName = "";
+ appInfo.engineVersion = 1;
+ appInfo.apiVersion = instanceVersion;
+
+ VkInstanceCreateInfo createInstanceInfo;
+ createInstanceInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
+ createInstanceInfo.pNext = nullptr;
+ createInstanceInfo.flags = 0;
+ createInstanceInfo.pApplicationInfo = &appInfo;
+ createInstanceInfo.enabledLayerCount = 0;
+ createInstanceInfo.ppEnabledLayerNames = nullptr;
+ createInstanceInfo.enabledExtensionCount = 0;
+ createInstanceInfo.ppEnabledExtensionNames = nullptr;
+
+ auto pfnCreateInstance = getProc<PFN_vkCreateInstance>("vkCreateInstance");
+ if (!pfnCreateInstance ||
+ pfnCreateInstance(&createInstanceInfo, nullptr, &mInstance) != VK_SUCCESS)
+ {
+ return VK_NULL_HANDLE;
+ }
+
+ return mInstance;
+ }
+
+ template <typename Func>
+ Func getProc(const char *fn) const
+ {
+ return reinterpret_cast<Func>(angle::GetLibrarySymbol(mLibVulkan, fn));
+ }
+
+ private:
+ void *mLibVulkan = nullptr;
+ VkInstance mInstance = VK_NULL_HANDLE;
+};
+
+ANGLE_FORMAT_PRINTF(1, 2)
+std::string FormatString(const char *fmt, ...)
+{
+ va_list vararg;
+ va_start(vararg, fmt);
+
+ std::vector<char> buffer;
+ size_t len = FormatStringIntoVector(fmt, vararg, buffer);
+ va_end(vararg);
+
+ return std::string(&buffer[0], len);
+}
+
+bool GetSystemInfoVulkan(SystemInfo *info)
+{
+ return GetSystemInfoVulkanWithICD(info, vk::ICD::Default);
+}
+
+bool GetSystemInfoVulkanWithICD(SystemInfo *info, vk::ICD preferredICD)
+{
+ const bool enableValidationLayers = false;
+ vk::ScopedVkLoaderEnvironment scopedEnvironment(enableValidationLayers, preferredICD);
+
+ // This implementation builds on top of the Vulkan API, but cannot assume the existence of the
+ // Vulkan library. ANGLE can be installed on versions of Android as old as Ice Cream Sandwich.
+ // Therefore, we need to use dlopen()/dlsym() in order to see if Vulkan is installed on the
+ // system, and if so, to use it:
+ VulkanLibrary vkLibrary;
+ VkInstance instance = vkLibrary.getVulkanInstance();
+ if (instance == VK_NULL_HANDLE)
+ {
+ // If Vulkan doesn't exist, bail-out early:
+ return false;
+ }
+
+ // Enumerate the Vulkan physical devices, which are ANGLE gpus:
+ auto pfnEnumeratePhysicalDevices =
+ vkLibrary.getProc<PFN_vkEnumeratePhysicalDevices>("vkEnumeratePhysicalDevices");
+ auto pfnGetPhysicalDeviceProperties =
+ vkLibrary.getProc<PFN_vkGetPhysicalDeviceProperties>("vkGetPhysicalDeviceProperties");
+ auto pfnGetPhysicalDeviceProperties2 =
+ vkLibrary.getProc<PFN_vkGetPhysicalDeviceProperties2>("vkGetPhysicalDeviceProperties2");
+ uint32_t physicalDeviceCount = 0;
+ if (!pfnEnumeratePhysicalDevices || !pfnGetPhysicalDeviceProperties ||
+ pfnEnumeratePhysicalDevices(instance, &physicalDeviceCount, nullptr) != VK_SUCCESS)
+ {
+ return false;
+ }
+ std::vector<VkPhysicalDevice> physicalDevices(physicalDeviceCount);
+ if (pfnEnumeratePhysicalDevices(instance, &physicalDeviceCount, physicalDevices.data()) !=
+ VK_SUCCESS)
+ {
+ return false;
+ }
+
+ // If we get to here, we will likely provide a valid answer (unless an unknown vendorID):
+ info->gpus.resize(physicalDeviceCount);
+
+ for (uint32_t i = 0; i < physicalDeviceCount; i++)
+ {
+ VkPhysicalDeviceDriverProperties driverProperties = {};
+ driverProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES;
+
+ VkPhysicalDeviceProperties2 properties2 = {};
+ properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
+ properties2.pNext = &driverProperties;
+
+ VkPhysicalDeviceProperties &properties = properties2.properties;
+ pfnGetPhysicalDeviceProperties(physicalDevices[i], &properties);
+
+ // vkGetPhysicalDeviceProperties2() is supported since 1.1
+ // Use vkGetPhysicalDeviceProperties2() to get driver information.
+ if (properties.apiVersion >= VK_API_VERSION_1_1)
+ {
+ pfnGetPhysicalDeviceProperties2(physicalDevices[i], &properties2);
+ }
+
+ // Fill in data for a given physical device (a.k.a. gpu):
+ GPUDeviceInfo &gpu = info->gpus[i];
+ gpu.vendorId = properties.vendorID;
+ gpu.deviceId = properties.deviceID;
+ // Need to parse/re-format properties.driverVersion.
+ //
+ // TODO(ianelliott): Determine the formatting used for each vendor
+ // (http://anglebug.com/2677)
+ // TODO(http://anglebug.com/7677): Use driverID instead of the hardware vendorID to detect
+ // driveVendor, etc.
+ switch (properties.vendorID)
+ {
+ case kVendorID_AMD:
+ gpu.driverVendor = "Advanced Micro Devices, Inc";
+ gpu.driverVersion = FormatString("0x%x", properties.driverVersion);
+ gpu.detailedDriverVersion.major = properties.driverVersion;
+ break;
+ case kVendorID_ARM:
+ gpu.driverVendor = "Arm Holdings";
+ gpu.driverVersion = FormatString("0x%x", properties.driverVersion);
+ gpu.detailedDriverVersion.major = properties.driverVersion;
+ break;
+ case kVendorID_Broadcom:
+ gpu.driverVendor = "Broadcom";
+ gpu.driverVersion = FormatString("0x%x", properties.driverVersion);
+ gpu.detailedDriverVersion.major = properties.driverVersion;
+ break;
+ case kVendorID_GOOGLE:
+ gpu.driverVendor = "Google";
+ gpu.driverVersion = FormatString("0x%x", properties.driverVersion);
+ gpu.detailedDriverVersion.major = properties.driverVersion;
+ break;
+ case kVendorID_ImgTec:
+ gpu.driverVendor = "Imagination Technologies Limited";
+ gpu.driverVersion = FormatString("0x%x", properties.driverVersion);
+ gpu.detailedDriverVersion.major = properties.driverVersion;
+ break;
+ case kVendorID_Intel:
+ gpu.driverVendor = "Intel Corporation";
+ gpu.driverVersion = FormatString("0x%x", properties.driverVersion);
+ gpu.detailedDriverVersion.major = properties.driverVersion;
+ break;
+ case kVendorID_Kazan:
+ gpu.driverVendor = "Kazan Software";
+ gpu.driverVersion = FormatString("0x%x", properties.driverVersion);
+ gpu.detailedDriverVersion.major = properties.driverVersion;
+ break;
+ case kVendorID_NVIDIA:
+ gpu.driverVendor = "NVIDIA Corporation";
+ gpu.driverVersion = FormatString("%d.%d.%d.%d", properties.driverVersion >> 22,
+ (properties.driverVersion >> 14) & 0XFF,
+ (properties.driverVersion >> 6) & 0XFF,
+ properties.driverVersion & 0x3F);
+ gpu.detailedDriverVersion.major = properties.driverVersion >> 22;
+ gpu.detailedDriverVersion.minor = (properties.driverVersion >> 14) & 0xFF;
+ gpu.detailedDriverVersion.subMinor = (properties.driverVersion >> 6) & 0xFF;
+ gpu.detailedDriverVersion.patch = properties.driverVersion & 0x3F;
+ break;
+ case kVendorID_Qualcomm:
+ gpu.driverVendor = "Qualcomm Technologies, Inc";
+ if (properties.driverVersion & 0x80000000)
+ {
+ gpu.driverVersion = FormatString("%d.%d.%d", properties.driverVersion >> 22,
+ (properties.driverVersion >> 12) & 0X3FF,
+ properties.driverVersion & 0xFFF);
+ gpu.detailedDriverVersion.major = properties.driverVersion >> 22;
+ gpu.detailedDriverVersion.minor = (properties.driverVersion >> 12) & 0x3FF;
+ gpu.detailedDriverVersion.subMinor = properties.driverVersion & 0xFFF;
+ }
+ else
+ {
+ gpu.driverVersion = FormatString("0x%x", properties.driverVersion);
+ gpu.detailedDriverVersion.major = properties.driverVersion;
+ }
+ break;
+ case kVendorID_VeriSilicon:
+ gpu.driverVendor = "VeriSilicon";
+ gpu.driverVersion = FormatString("0x%x", properties.driverVersion);
+ gpu.detailedDriverVersion.major = properties.driverVersion;
+ break;
+ case kVendorID_Vivante:
+ gpu.driverVendor = "Vivante";
+ gpu.driverVersion = FormatString("0x%x", properties.driverVersion);
+ gpu.detailedDriverVersion.major = properties.driverVersion;
+ break;
+ case kVendorID_Mesa:
+ gpu.driverVendor = "Mesa";
+ gpu.driverVersion = FormatString("0x%x", properties.driverVersion);
+ gpu.detailedDriverVersion.major = properties.driverVersion;
+ break;
+ default:
+ return false;
+ }
+ gpu.driverId = static_cast<DriverID>(driverProperties.driverID);
+ gpu.driverApiVersion = properties.apiVersion;
+ gpu.driverDate = "";
+ }
+
+ return true;
+}
+
+} // namespace angle
diff --git a/gfx/angle/checkout/src/gpu_info_util/SystemInfo_vulkan.h b/gfx/angle/checkout/src/gpu_info_util/SystemInfo_vulkan.h
new file mode 100644
index 0000000000..10c7d69295
--- /dev/null
+++ b/gfx/angle/checkout/src/gpu_info_util/SystemInfo_vulkan.h
@@ -0,0 +1,23 @@
+//
+// Copyright 2020 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.
+//
+
+// SystemInfo_vulkan.h: Reusable Vulkan implementation for SystemInfo.h
+
+#ifndef GPU_INFO_UTIL_SYSTEM_INFO_VULKAN_H_
+#define GPU_INFO_UTIL_SYSTEM_INFO_VULKAN_H_
+
+#include "common/vulkan/vulkan_icd.h"
+
+namespace angle
+{
+struct SystemInfo;
+
+// Reusable vulkan implementation of GetSystemInfo(). See SystemInfo.h.
+bool GetSystemInfoVulkan(SystemInfo *info);
+bool GetSystemInfoVulkanWithICD(SystemInfo *info, vk::ICD preferredICD);
+} // namespace angle
+
+#endif // GPU_INFO_UTIL_SYSTEM_INFO_VULKAN_H_
diff --git a/gfx/angle/checkout/src/gpu_info_util/SystemInfo_win.cpp b/gfx/angle/checkout/src/gpu_info_util/SystemInfo_win.cpp
new file mode 100644
index 0000000000..291acc1ef0
--- /dev/null
+++ b/gfx/angle/checkout/src/gpu_info_util/SystemInfo_win.cpp
@@ -0,0 +1,117 @@
+//
+// Copyright 2013 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.
+//
+
+// SystemInfo_win.cpp: implementation of the Windows-specific parts of SystemInfo.h
+
+#include "gpu_info_util/SystemInfo_internal.h"
+
+#include "common/debug.h"
+#include "common/string_utils.h"
+
+// Windows.h needs to be included first
+#include <windows.h>
+
+#include <dxgi.h>
+
+#include <array>
+#include <sstream>
+
+namespace angle
+{
+
+namespace
+{
+
+bool GetDevicesFromDXGI(std::vector<GPUDeviceInfo> *devices)
+{
+#if defined(ANGLE_ENABLE_WINDOWS_UWP)
+ IDXGIFactory1 *factory;
+ if (!SUCCEEDED(
+ CreateDXGIFactory1(__uuidof(IDXGIFactory1), reinterpret_cast<void **>(&factory))))
+ {
+ return false;
+ }
+#else
+ IDXGIFactory *factory;
+ if (!SUCCEEDED(CreateDXGIFactory(__uuidof(IDXGIFactory), reinterpret_cast<void **>(&factory))))
+ {
+ return false;
+ }
+#endif
+
+ UINT i = 0;
+ IDXGIAdapter *adapter = nullptr;
+ while (factory->EnumAdapters(i++, &adapter) != DXGI_ERROR_NOT_FOUND)
+ {
+ DXGI_ADAPTER_DESC desc;
+ adapter->GetDesc(&desc);
+
+ LARGE_INTEGER umdVersion;
+ if (adapter->CheckInterfaceSupport(__uuidof(IDXGIDevice), &umdVersion) ==
+ DXGI_ERROR_UNSUPPORTED)
+ {
+ adapter->Release();
+ continue;
+ }
+
+ // The UMD driver version here is the same as in the registry except for the last number.
+ uint64_t intVersion = umdVersion.QuadPart;
+ std::ostringstream o;
+
+ constexpr uint64_t kMask16 = std::numeric_limits<uint16_t>::max();
+ o << ((intVersion >> 48) & kMask16) << ".";
+ o << ((intVersion >> 32) & kMask16) << ".";
+ o << ((intVersion >> 16) & kMask16) << ".";
+ o << (intVersion & kMask16);
+
+ GPUDeviceInfo device;
+ device.vendorId = desc.VendorId;
+ device.deviceId = desc.DeviceId;
+ device.driverVersion = o.str();
+ device.systemDeviceId =
+ GetSystemDeviceIdFromParts(desc.AdapterLuid.HighPart, desc.AdapterLuid.LowPart);
+
+ devices->push_back(device);
+
+ adapter->Release();
+ }
+
+ factory->Release();
+
+ return (i > 0);
+}
+
+} // anonymous namespace
+
+bool GetSystemInfo(SystemInfo *info)
+{
+ if (!GetDevicesFromDXGI(&info->gpus))
+ {
+ return false;
+ }
+
+ if (info->gpus.size() == 0)
+ {
+ return false;
+ }
+
+ // Call GetDualGPUInfo to populate activeGPUIndex, isOptimus, and isAMDSwitchable.
+ GetDualGPUInfo(info);
+
+ // Override activeGPUIndex. The first index returned by EnumAdapters is the active GPU. We
+ // can override the heuristic to find the active GPU
+ info->activeGPUIndex = 0;
+
+#if !defined(ANGLE_ENABLE_WINDOWS_UWP)
+ // Override isOptimus. nvd3d9wrap.dll is loaded into all processes when Optimus is enabled.
+ HMODULE nvd3d9wrap = GetModuleHandleW(L"nvd3d9wrap.dll");
+ info->isOptimus = nvd3d9wrap != nullptr;
+#endif
+
+ return true;
+}
+
+} // namespace angle
diff --git a/gfx/angle/checkout/src/image_util/copyimage.cpp b/gfx/angle/checkout/src/image_util/copyimage.cpp
new file mode 100644
index 0000000000..b5c2773e21
--- /dev/null
+++ b/gfx/angle/checkout/src/image_util/copyimage.cpp
@@ -0,0 +1,74 @@
+//
+// Copyright 2013 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.
+//
+
+// copyimage.cpp: Defines image copying functions
+
+#include "image_util/copyimage.h"
+
+namespace angle
+{
+
+namespace
+{
+inline uint32_t SwizzleBGRAToRGBA(uint32_t argb)
+{
+ return ((argb & 0x000000FF) << 16) | // Move BGRA blue to RGBA blue
+ ((argb & 0x00FF0000) >> 16) | // Move BGRA red to RGBA red
+ ((argb & 0xFF00FF00)); // Keep alpha and green
+}
+
+void CopyBGRA8ToRGBA8Fast(const uint8_t *source,
+ int srcYAxisPitch,
+ uint8_t *dest,
+ int destYAxisPitch,
+ int destWidth,
+ int destHeight)
+{
+ for (int y = 0; y < destHeight; ++y)
+ {
+ const uint32_t *src32 = reinterpret_cast<const uint32_t *>(source + y * srcYAxisPitch);
+ uint32_t *dest32 = reinterpret_cast<uint32_t *>(dest + y * destYAxisPitch);
+ const uint32_t *end32 = src32 + destWidth;
+ while (src32 != end32)
+ {
+ *dest32++ = SwizzleBGRAToRGBA(*src32++);
+ }
+ }
+}
+} // namespace
+
+void CopyBGRA8ToRGBA8(const uint8_t *source,
+ int srcXAxisPitch,
+ int srcYAxisPitch,
+ uint8_t *dest,
+ int destXAxisPitch,
+ int destYAxisPitch,
+ int destWidth,
+ int destHeight)
+{
+ if (srcXAxisPitch == 4 && destXAxisPitch == 4)
+ {
+ CopyBGRA8ToRGBA8Fast(source, srcYAxisPitch, dest, destYAxisPitch, destWidth, destHeight);
+ return;
+ }
+
+ for (int y = 0; y < destHeight; ++y)
+ {
+ uint8_t *dst = dest + y * destYAxisPitch;
+ const uint8_t *src = source + y * srcYAxisPitch;
+ const uint8_t *end = src + destWidth * srcXAxisPitch;
+
+ while (src != end)
+ {
+ *reinterpret_cast<uint32_t *>(dst) =
+ SwizzleBGRAToRGBA(*reinterpret_cast<const uint32_t *>(src));
+ src += srcXAxisPitch;
+ dst += destXAxisPitch;
+ }
+ }
+}
+
+} // namespace angle
diff --git a/gfx/angle/checkout/src/image_util/copyimage.h b/gfx/angle/checkout/src/image_util/copyimage.h
new file mode 100644
index 0000000000..9825b86f98
--- /dev/null
+++ b/gfx/angle/checkout/src/image_util/copyimage.h
@@ -0,0 +1,46 @@
+//
+// Copyright 2013 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.
+//
+
+// copyimage.h: Defines image copying functions
+
+#ifndef IMAGEUTIL_COPYIMAGE_H_
+#define IMAGEUTIL_COPYIMAGE_H_
+
+#include "common/Color.h"
+
+#include "image_util/imageformats.h"
+
+#include <stdint.h>
+
+namespace angle
+{
+
+template <typename sourceType, typename colorDataType>
+void ReadColor(const uint8_t *source, uint8_t *dest);
+
+template <typename destType, typename colorDataType>
+void WriteColor(const uint8_t *source, uint8_t *dest);
+
+template <typename SourceType>
+void ReadDepthStencil(const uint8_t *source, uint8_t *dest);
+
+template <typename DestType>
+void WriteDepthStencil(const uint8_t *source, uint8_t *dest);
+
+void CopyBGRA8ToRGBA8(const uint8_t *source,
+ int srcXAxisPitch,
+ int srcYAxisPitch,
+ uint8_t *dest,
+ int destXAxisPitch,
+ int destYAxisPitch,
+ int destWidth,
+ int destHeight);
+
+} // namespace angle
+
+#include "copyimage.inc"
+
+#endif // IMAGEUTIL_COPYIMAGE_H_
diff --git a/gfx/angle/checkout/src/image_util/copyimage.inc b/gfx/angle/checkout/src/image_util/copyimage.inc
new file mode 100644
index 0000000000..42ad6b9421
--- /dev/null
+++ b/gfx/angle/checkout/src/image_util/copyimage.inc
@@ -0,0 +1,38 @@
+//
+// 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.
+//
+
+// copyimage.inc: Defines image copying functions
+
+namespace angle
+{
+template <typename sourceType, typename colorDataType>
+void ReadColor(const uint8_t *source, uint8_t *dest)
+{
+ sourceType::readColor(reinterpret_cast<Color<colorDataType>*>(dest),
+ reinterpret_cast<const sourceType*>(source));
+}
+
+template <typename destType, typename colorDataType>
+void WriteColor(const uint8_t *source, uint8_t *dest)
+{
+ destType::writeColor(reinterpret_cast<destType*>(dest),
+ reinterpret_cast<const Color<colorDataType>*>(source));
+}
+
+template <typename SourceType>
+void ReadDepthStencil(const uint8_t *source, uint8_t *dest)
+{
+ SourceType::ReadDepthStencil(reinterpret_cast<DepthStencil *>(dest),
+ reinterpret_cast<const SourceType *>(source));
+}
+
+template <typename DestType>
+void WriteDepthStencil(const uint8_t *source, uint8_t *dest)
+{
+ DestType::WriteDepthStencil(reinterpret_cast<DestType *>(dest),
+ reinterpret_cast<const DepthStencil *>(source));
+}
+} // namespace angle
diff --git a/gfx/angle/checkout/src/image_util/generatemip.h b/gfx/angle/checkout/src/image_util/generatemip.h
new file mode 100644
index 0000000000..523c296298
--- /dev/null
+++ b/gfx/angle/checkout/src/image_util/generatemip.h
@@ -0,0 +1,34 @@
+//
+// Copyright 2002 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.inc"
+
+#endif // IMAGEUTIL_GENERATEMIP_H_
diff --git a/gfx/angle/checkout/src/image_util/generatemip.inc b/gfx/angle/checkout/src/image_util/generatemip.inc
new file mode 100644
index 0000000000..7a7f5abe9c
--- /dev/null
+++ b/gfx/angle/checkout/src/image_util/generatemip.inc
@@ -0,0 +1,268 @@
+//
+// 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.
+//
+
+// generatemip.inc: Defines the GenerateMip function, templated on the format
+// type of the image for which mip levels are being generated.
+
+#include "common/mathutil.h"
+
+#include "image_util/imageformats.h"
+
+namespace angle
+{
+
+namespace priv
+{
+
+template <typename T>
+static inline T *GetPixel(uint8_t *data, size_t x, size_t y, size_t z, size_t rowPitch, size_t depthPitch)
+{
+ return reinterpret_cast<T*>(data + (x * sizeof(T)) + (y * rowPitch) + (z * depthPitch));
+}
+
+template <typename T>
+static inline const T *GetPixel(const uint8_t *data, size_t x, size_t y, size_t z, size_t rowPitch, size_t depthPitch)
+{
+ return reinterpret_cast<const T*>(data + (x * sizeof(T)) + (y * rowPitch) + (z * depthPitch));
+}
+
+template <typename T>
+static void GenerateMip_Y(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth,
+ const uint8_t *sourceData, size_t sourceRowPitch, size_t sourceDepthPitch,
+ size_t destWidth, size_t destHeight, size_t destDepth,
+ uint8_t *destData, size_t destRowPitch, size_t destDepthPitch)
+{
+ ASSERT(sourceWidth == 1);
+ ASSERT(sourceHeight > 1);
+ ASSERT(sourceDepth == 1);
+
+ for (size_t y = 0; y < destHeight; y++)
+ {
+ const T *src0 = GetPixel<T>(sourceData, 0, y * 2, 0, sourceRowPitch, sourceDepthPitch);
+ const T *src1 = GetPixel<T>(sourceData, 0, y * 2 + 1, 0, sourceRowPitch, sourceDepthPitch);
+ T *dst = GetPixel<T>(destData, 0, y, 0, destRowPitch, destDepthPitch);
+
+ T::average(dst, src0, src1);
+ }
+}
+
+template <typename T>
+static void GenerateMip_X(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth,
+ const uint8_t *sourceData, size_t sourceRowPitch, size_t sourceDepthPitch,
+ size_t destWidth, size_t destHeight, size_t destDepth,
+ uint8_t *destData, size_t destRowPitch, size_t destDepthPitch)
+{
+ ASSERT(sourceWidth > 1);
+ ASSERT(sourceHeight == 1);
+ ASSERT(sourceDepth == 1);
+
+ for (size_t x = 0; x < destWidth; x++)
+ {
+ const T *src0 = GetPixel<T>(sourceData, x * 2, 0, 0, sourceRowPitch, sourceDepthPitch);
+ const T *src1 = GetPixel<T>(sourceData, x * 2 + 1, 0, 0, sourceRowPitch, sourceDepthPitch);
+ T *dst = GetPixel<T>(destData, x, 0, 0, destRowPitch, destDepthPitch);
+
+ T::average(dst, src0, src1);
+ }
+}
+
+template <typename T>
+static void GenerateMip_Z(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth,
+ const uint8_t *sourceData, size_t sourceRowPitch, size_t sourceDepthPitch,
+ size_t destWidth, size_t destHeight, size_t destDepth,
+ uint8_t *destData, size_t destRowPitch, size_t destDepthPitch)
+{
+ ASSERT(sourceWidth == 1);
+ ASSERT(sourceHeight == 1);
+ ASSERT(sourceDepth > 1);
+
+ for (size_t z = 0; z < destDepth; z++)
+ {
+ const T *src0 = GetPixel<T>(sourceData, 0, 0, z * 2, sourceRowPitch, sourceDepthPitch);
+ const T *src1 = GetPixel<T>(sourceData, 0, 0, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
+ T *dst = GetPixel<T>(destData, 0, 0, z, destRowPitch, destDepthPitch);
+
+ T::average(dst, src0, src1);
+ }
+}
+
+template <typename T>
+static void GenerateMip_XY(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth,
+ const uint8_t *sourceData, size_t sourceRowPitch, size_t sourceDepthPitch,
+ size_t destWidth, size_t destHeight, size_t destDepth,
+ uint8_t *destData, size_t destRowPitch, size_t destDepthPitch)
+{
+ ASSERT(sourceWidth > 1);
+ ASSERT(sourceHeight > 1);
+ ASSERT(sourceDepth == 1);
+
+ for (size_t y = 0; y < destHeight; y++)
+ {
+ for (size_t x = 0; x < destWidth; x++)
+ {
+ const T *src0 = GetPixel<T>(sourceData, x * 2, y * 2, 0, sourceRowPitch, sourceDepthPitch);
+ const T *src1 = GetPixel<T>(sourceData, x * 2, y * 2 + 1, 0, sourceRowPitch, sourceDepthPitch);
+ const T *src2 = GetPixel<T>(sourceData, x * 2 + 1, y * 2, 0, sourceRowPitch, sourceDepthPitch);
+ const T *src3 = GetPixel<T>(sourceData, x * 2 + 1, y * 2 + 1, 0, sourceRowPitch, sourceDepthPitch);
+ T *dst = GetPixel<T>(destData, x, y, 0, destRowPitch, destDepthPitch);
+
+ T tmp0, tmp1;
+
+ T::average(&tmp0, src0, src1);
+ T::average(&tmp1, src2, src3);
+ T::average(dst, &tmp0, &tmp1);
+ }
+ }
+}
+
+template <typename T>
+static void GenerateMip_YZ(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth,
+ const uint8_t *sourceData, size_t sourceRowPitch, size_t sourceDepthPitch,
+ size_t destWidth, size_t destHeight, size_t destDepth,
+ uint8_t *destData, size_t destRowPitch, size_t destDepthPitch)
+{
+ ASSERT(sourceWidth == 1);
+ ASSERT(sourceHeight > 1);
+ ASSERT(sourceDepth > 1);
+
+ for (size_t z = 0; z < destDepth; z++)
+ {
+ for (size_t y = 0; y < destHeight; y++)
+ {
+ const T *src0 = GetPixel<T>(sourceData, 0, y * 2, z * 2, sourceRowPitch, sourceDepthPitch);
+ const T *src1 = GetPixel<T>(sourceData, 0, y * 2, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
+ const T *src2 = GetPixel<T>(sourceData, 0, y * 2 + 1, z * 2, sourceRowPitch, sourceDepthPitch);
+ const T *src3 = GetPixel<T>(sourceData, 0, y * 2 + 1, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
+ T *dst = GetPixel<T>(destData, 0, y, z, destRowPitch, destDepthPitch);
+
+ T tmp0, tmp1;
+
+ T::average(&tmp0, src0, src1);
+ T::average(&tmp1, src2, src3);
+ T::average(dst, &tmp0, &tmp1);
+ }
+ }
+}
+
+template <typename T>
+static void GenerateMip_XZ(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth,
+ const uint8_t *sourceData, size_t sourceRowPitch, size_t sourceDepthPitch,
+ size_t destWidth, size_t destHeight, size_t destDepth,
+ uint8_t *destData, size_t destRowPitch, size_t destDepthPitch)
+{
+ ASSERT(sourceWidth > 1);
+ ASSERT(sourceHeight == 1);
+ ASSERT(sourceDepth > 1);
+
+ for (size_t z = 0; z < destDepth; z++)
+ {
+ for (size_t x = 0; x < destWidth; x++)
+ {
+ const T *src0 = GetPixel<T>(sourceData, x * 2, 0, z * 2, sourceRowPitch, sourceDepthPitch);
+ const T *src1 = GetPixel<T>(sourceData, x * 2, 0, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
+ const T *src2 = GetPixel<T>(sourceData, x * 2 + 1, 0, z * 2, sourceRowPitch, sourceDepthPitch);
+ const T *src3 = GetPixel<T>(sourceData, x * 2 + 1, 0, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
+ T *dst = GetPixel<T>(destData, x, 0, z, destRowPitch, destDepthPitch);
+
+ T tmp0, tmp1;
+
+ T::average(&tmp0, src0, src1);
+ T::average(&tmp1, src2, src3);
+ T::average(dst, &tmp0, &tmp1);
+ }
+ }
+}
+
+template <typename T>
+static void GenerateMip_XYZ(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth,
+ const uint8_t *sourceData, size_t sourceRowPitch, size_t sourceDepthPitch,
+ size_t destWidth, size_t destHeight, size_t destDepth,
+ uint8_t *destData, size_t destRowPitch, size_t destDepthPitch)
+{
+ ASSERT(sourceWidth > 1);
+ ASSERT(sourceHeight > 1);
+ ASSERT(sourceDepth > 1);
+
+ for (size_t z = 0; z < destDepth; z++)
+ {
+ for (size_t y = 0; y < destHeight; y++)
+ {
+ for (size_t x = 0; x < destWidth; x++)
+ {
+ const T *src0 = GetPixel<T>(sourceData, x * 2, y * 2, z * 2, sourceRowPitch, sourceDepthPitch);
+ const T *src1 = GetPixel<T>(sourceData, x * 2, y * 2, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
+ const T *src2 = GetPixel<T>(sourceData, x * 2, y * 2 + 1, z * 2, sourceRowPitch, sourceDepthPitch);
+ const T *src3 = GetPixel<T>(sourceData, x * 2, y * 2 + 1, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
+ const T *src4 = GetPixel<T>(sourceData, x * 2 + 1, y * 2, z * 2, sourceRowPitch, sourceDepthPitch);
+ const T *src5 = GetPixel<T>(sourceData, x * 2 + 1, y * 2, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
+ const T *src6 = GetPixel<T>(sourceData, x * 2 + 1, y * 2 + 1, z * 2, sourceRowPitch, sourceDepthPitch);
+ const T *src7 = GetPixel<T>(sourceData, x * 2 + 1, y * 2 + 1, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
+ T *dst = GetPixel<T>(destData, x, y, z, destRowPitch, destDepthPitch);
+
+ T tmp0, tmp1, tmp2, tmp3, tmp4, tmp5;
+
+ T::average(&tmp0, src0, src1);
+ T::average(&tmp1, src2, src3);
+ T::average(&tmp2, src4, src5);
+ T::average(&tmp3, src6, src7);
+
+ T::average(&tmp4, &tmp0, &tmp1);
+ T::average(&tmp5, &tmp2, &tmp3);
+
+ T::average(dst, &tmp4, &tmp5);
+ }
+ }
+ }
+}
+
+
+typedef void (*MipGenerationFunction)(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth,
+ const uint8_t *sourceData, size_t sourceRowPitch, size_t sourceDepthPitch,
+ size_t destWidth, size_t destHeight, size_t destDepth,
+ uint8_t *destData, size_t destRowPitch, size_t destDepthPitch);
+
+template <typename T>
+static MipGenerationFunction GetMipGenerationFunction(size_t sourceWidth, size_t sourceHeight, size_t sourceDepth)
+{
+ uint8_t index = ((sourceWidth > 1) ? 1 : 0) |
+ ((sourceHeight > 1) ? 2 : 0) |
+ ((sourceDepth > 1) ? 4 : 0);
+
+ switch (index)
+ {
+ case 0: return nullptr;
+ case 1: return GenerateMip_X<T>; // W x 1 x 1
+ case 2: return GenerateMip_Y<T>; // 1 x H x 1
+ case 3: return GenerateMip_XY<T>; // W x H x 1
+ case 4: return GenerateMip_Z<T>; // 1 x 1 x D
+ case 5: return GenerateMip_XZ<T>; // W x 1 x D
+ case 6: return GenerateMip_YZ<T>; // 1 x H x D
+ case 7: return GenerateMip_XYZ<T>; // W x H x D
+ }
+
+ UNREACHABLE();
+ return nullptr;
+}
+
+} // namespace priv
+
+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)
+{
+ size_t mipWidth = std::max<size_t>(1, sourceWidth >> 1);
+ size_t mipHeight = std::max<size_t>(1, sourceHeight >> 1);
+ size_t mipDepth = std::max<size_t>(1, sourceDepth >> 1);
+
+ priv::MipGenerationFunction generationFunction = priv::GetMipGenerationFunction<T>(sourceWidth, sourceHeight, sourceDepth);
+ ASSERT(generationFunction != nullptr);
+
+ generationFunction(sourceWidth, sourceHeight, sourceDepth, sourceData, sourceRowPitch, sourceDepthPitch,
+ mipWidth, mipHeight, mipDepth, destData, destRowPitch, destDepthPitch);
+}
+
+} // namespace angle
diff --git a/gfx/angle/checkout/src/image_util/imageformats.cpp b/gfx/angle/checkout/src/image_util/imageformats.cpp
new file mode 100644
index 0000000000..368b6d95d7
--- /dev/null
+++ b/gfx/angle/checkout/src/image_util/imageformats.cpp
@@ -0,0 +1,1954 @@
+//
+// 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.
+//
+
+// 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 R8G8B8A8SRGB::readColor(gl::ColorF *dst, const R8G8B8A8SRGB *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 R8G8B8A8SRGB::writeColor(R8G8B8A8SRGB *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 R8G8B8A8SRGB::average(R8G8B8A8SRGB *dst, const R8G8B8A8SRGB *src1, const R8G8B8A8SRGB *src2)
+{
+ dst->R =
+ gl::linearToSRGB(static_cast<uint8_t>((static_cast<uint16_t>(gl::sRGBToLinear(src1->R)) +
+ static_cast<uint16_t>(gl::sRGBToLinear(src2->R))) >>
+ 1));
+ dst->G =
+ gl::linearToSRGB(static_cast<uint8_t>((static_cast<uint16_t>(gl::sRGBToLinear(src1->G)) +
+ static_cast<uint16_t>(gl::sRGBToLinear(src2->G))) >>
+ 1));
+ dst->B =
+ gl::linearToSRGB(static_cast<uint8_t>((static_cast<uint16_t>(gl::sRGBToLinear(src1->B)) +
+ static_cast<uint16_t>(gl::sRGBToLinear(src2->B))) >>
+ 1));
+ dst->A = static_cast<uint8_t>(
+ (static_cast<uint16_t>(src1->A) + static_cast<uint16_t>(src2->A)) >> 1);
+}
+
+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 R8G8B8X8::readColor(gl::ColorUI *dst, const R8G8B8X8 *src)
+{
+ dst->red = src->R;
+ dst->green = src->G;
+ dst->blue = src->B;
+ dst->alpha = 1;
+}
+
+void R8G8B8X8::readColor(gl::ColorF *dst, const R8G8B8X8 *src)
+{
+ dst->red = gl::normalizedToFloat(src->R);
+ dst->green = gl::normalizedToFloat(src->G);
+ dst->blue = gl::normalizedToFloat(src->B);
+ dst->alpha = 1.0f;
+}
+
+void R8G8B8X8::writeColor(R8G8B8X8 *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 R8G8B8X8::writeColor(R8G8B8X8 *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 R8G8B8X8::average(R8G8B8X8 *dst, const R8G8B8X8 *src1, const R8G8B8X8 *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 R10G10B10A2S::readColor(gl::ColorI *dst, const R10G10B10A2S *src)
+{
+ dst->red = src->R;
+ dst->green = src->G;
+ dst->blue = src->B;
+ dst->alpha = src->A;
+}
+
+void R10G10B10A2S::readColor(gl::ColorF *dst, const R10G10B10A2S *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 R10G10B10A2S::writeColor(R10G10B10A2S *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 R10G10B10A2S::writeColor(R10G10B10A2S *dst, const gl::ColorF *src)
+{
+ dst->R = gl::floatToNormalized<10, int32_t>(src->red);
+ dst->G = gl::floatToNormalized<10, int32_t>(src->green);
+ dst->B = gl::floatToNormalized<10, int32_t>(src->blue);
+ dst->A = gl::floatToNormalized<2, int32_t>(src->alpha);
+}
+
+void R10G10B10A2S::average(R10G10B10A2S *dst, const R10G10B10A2S *src1, const R10G10B10A2S *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 R10G10B10X2::readColor(gl::ColorUI *dst, const R10G10B10X2 *src)
+{
+ dst->red = src->R;
+ dst->green = src->G;
+ dst->blue = src->B;
+ dst->alpha = 0x3;
+}
+
+void R10G10B10X2::readColor(gl::ColorF *dst, const R10G10B10X2 *src)
+{
+ dst->red = gl::normalizedToFloat<10>(src->R);
+ dst->green = gl::normalizedToFloat<10>(src->G);
+ dst->blue = gl::normalizedToFloat<10>(src->B);
+ dst->alpha = 1.0f;
+}
+
+void R10G10B10X2::writeColor(R10G10B10X2 *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 R10G10B10X2::writeColor(R10G10B10X2 *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);
+}
+
+void R10G10B10X2::average(R10G10B10X2 *dst, const R10G10B10X2 *src1, const R10G10B10X2 *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 B10G10R10A2::readColor(gl::ColorUI *dst, const B10G10R10A2 *src)
+{
+ dst->red = src->R;
+ dst->green = src->G;
+ dst->blue = src->B;
+ dst->alpha = src->A;
+}
+
+void B10G10R10A2::readColor(gl::ColorF *dst, const B10G10R10A2 *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 B10G10R10A2::writeColor(B10G10R10A2 *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 B10G10R10A2::writeColor(B10G10R10A2 *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 B10G10R10A2::average(B10G10R10A2 *dst, const B10G10R10A2 *src1, const B10G10R10A2 *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);
+}
+
+void D24S8::ReadDepthStencil(DepthStencil *dst, const D24S8 *src)
+{
+ dst->depth = gl::normalizedToFloat<24>(src->D);
+ dst->stencil = src->S;
+}
+
+void D24S8::WriteDepthStencil(D24S8 *dst, const DepthStencil *src)
+{
+ dst->D = gl::floatToNormalized<24, uint32_t>(static_cast<float>(src->depth));
+ dst->S = src->stencil & 0xFF;
+}
+
+void S8::ReadDepthStencil(DepthStencil *dst, const S8 *src)
+{
+ dst->depth = 0;
+ dst->stencil = src->S;
+}
+
+void S8::WriteDepthStencil(S8 *dst, const DepthStencil *src)
+{
+ dst->S = src->stencil & 0xFF;
+}
+
+void D16::ReadDepthStencil(DepthStencil *dst, const D16 *src)
+{
+ dst->depth = gl::normalizedToFloat(src->D);
+ dst->stencil = 0;
+}
+
+void D16::WriteDepthStencil(D16 *dst, const DepthStencil *src)
+{
+ dst->D = gl::floatToNormalized<uint16_t>(static_cast<float>(src->depth));
+}
+
+void D24X8::ReadDepthStencil(DepthStencil *dst, const D24X8 *src)
+{
+ dst->depth = gl::normalizedToFloat<24>(src->D & 0x00ffffff);
+}
+
+void D24X8::WriteDepthStencil(D24X8 *dst, const DepthStencil *src)
+{
+ dst->D = gl::floatToNormalized<24, uint32_t>(static_cast<float>(src->depth));
+}
+
+void D32F::ReadDepthStencil(DepthStencil *dst, const D32F *src)
+{
+ dst->depth = src->D;
+}
+
+void D32F::WriteDepthStencil(D32F *dst, const DepthStencil *src)
+{
+ dst->D = static_cast<float>(src->depth);
+}
+
+void D32::ReadDepthStencil(DepthStencil *dst, const D32 *src)
+{
+ dst->depth = gl::normalizedToFloat(src->D);
+ dst->stencil = 0;
+}
+
+void D32::WriteDepthStencil(D32 *dst, const DepthStencil *src)
+{
+ dst->D = gl::floatToNormalized<uint32_t>(static_cast<float>(src->depth));
+}
+
+void D32FS8X24::ReadDepthStencil(DepthStencil *dst, const D32FS8X24 *src)
+{
+ dst->depth = src->D;
+ dst->stencil = src->S;
+}
+
+void D32FS8X24::WriteDepthStencil(D32FS8X24 *dst, const DepthStencil *src)
+{
+ dst->D = static_cast<float>(src->depth);
+ dst->S = src->stencil & 0xFF;
+}
+} // namespace angle
diff --git a/gfx/angle/checkout/src/image_util/imageformats.h b/gfx/angle/checkout/src/image_util/imageformats.h
new file mode 100644
index 0000000000..58fe5fe1a2
--- /dev/null
+++ b/gfx/angle/checkout/src/image_util/imageformats.h
@@ -0,0 +1,816 @@
+//
+// Copyright 2013 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 R8G8B8A8SRGB
+{
+ uint8_t R;
+ uint8_t G;
+ uint8_t B;
+ uint8_t A;
+
+ static void readColor(gl::ColorF *dst, const R8G8B8A8SRGB *src);
+ static void writeColor(R8G8B8A8SRGB *dst, const gl::ColorF *src);
+ static void average(R8G8B8A8SRGB *dst, const R8G8B8A8SRGB *src1, const R8G8B8A8SRGB *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 R8G8B8X8
+{
+ uint8_t R;
+ uint8_t G;
+ uint8_t B;
+ uint8_t X;
+
+ static void readColor(gl::ColorF *dst, const R8G8B8X8 *src);
+ static void readColor(gl::ColorUI *dst, const R8G8B8X8 *src);
+ static void writeColor(R8G8B8X8 *dst, const gl::ColorF *src);
+ static void writeColor(R8G8B8X8 *dst, const gl::ColorUI *src);
+ static void average(R8G8B8X8 *dst, const R8G8B8X8 *src1, const R8G8B8X8 *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 R10G10B10A2S
+{
+ int32_t R : 10;
+ int32_t G : 10;
+ int32_t B : 10;
+ int32_t A : 2;
+
+ static void readColor(gl::ColorF *dst, const R10G10B10A2S *src);
+ static void readColor(gl::ColorI *dst, const R10G10B10A2S *src);
+ static void writeColor(R10G10B10A2S *dst, const gl::ColorF *src);
+ static void writeColor(R10G10B10A2S *dst, const gl::ColorI *src);
+ static void average(R10G10B10A2S *dst, const R10G10B10A2S *src1, const R10G10B10A2S *src2);
+};
+static_assert(sizeof(R10G10B10A2S) == 4, "R10G10B10A2S struct not 32-bits.");
+
+struct R10G10B10X2
+{
+ uint32_t R : 10;
+ uint32_t G : 10;
+ uint32_t B : 10;
+
+ static void readColor(gl::ColorF *dst, const R10G10B10X2 *src);
+ static void readColor(gl::ColorUI *dst, const R10G10B10X2 *src);
+ static void writeColor(R10G10B10X2 *dst, const gl::ColorF *src);
+ static void writeColor(R10G10B10X2 *dst, const gl::ColorUI *src);
+ static void average(R10G10B10X2 *dst, const R10G10B10X2 *src1, const R10G10B10X2 *src2);
+};
+static_assert(sizeof(R10G10B10X2) == 4, "R10G10B10X2 struct not 32-bits.");
+
+struct B10G10R10A2
+{
+ uint32_t B : 10;
+ uint32_t G : 10;
+ uint32_t R : 10;
+ uint32_t A : 2;
+
+ static void readColor(gl::ColorF *dst, const B10G10R10A2 *src);
+ static void readColor(gl::ColorUI *dst, const B10G10R10A2 *src);
+ static void writeColor(B10G10R10A2 *dst, const gl::ColorF *src);
+ static void writeColor(B10G10R10A2 *dst, const gl::ColorUI *src);
+ static void average(B10G10R10A2 *dst, const B10G10R10A2 *src1, const B10G10R10A2 *src2);
+};
+static_assert(sizeof(B10G10R10A2) == 4, "B10G10R10A2 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.");
+
+struct D24S8
+{
+ uint32_t S : 8;
+ uint32_t D : 24;
+
+ static void ReadDepthStencil(DepthStencil *dst, const D24S8 *src);
+ static void WriteDepthStencil(D24S8 *dst, const DepthStencil *src);
+};
+
+struct S8
+{
+ uint8_t S;
+
+ static void ReadDepthStencil(DepthStencil *dst, const S8 *src);
+ static void WriteDepthStencil(S8 *dst, const DepthStencil *src);
+};
+
+struct D16
+{
+ uint16_t D;
+
+ static void ReadDepthStencil(DepthStencil *dst, const D16 *src);
+ static void WriteDepthStencil(D16 *dst, const DepthStencil *src);
+};
+
+struct D24X8
+{
+ uint32_t D : 24;
+ uint32_t X : 8;
+
+ static void ReadDepthStencil(DepthStencil *dst, const D24X8 *src);
+ static void WriteDepthStencil(D24X8 *dst, const DepthStencil *src);
+};
+
+struct D32F
+{
+ float D;
+
+ static void ReadDepthStencil(DepthStencil *dst, const D32F *src);
+ static void WriteDepthStencil(D32F *dst, const DepthStencil *src);
+};
+
+struct D32
+{
+ uint32_t D;
+
+ static void ReadDepthStencil(DepthStencil *dst, const D32 *src);
+ static void WriteDepthStencil(D32 *dst, const DepthStencil *src);
+};
+
+struct D32FS8X24
+{
+ float D;
+ uint32_t S;
+
+ static void ReadDepthStencil(DepthStencil *dst, const D32FS8X24 *src);
+ static void WriteDepthStencil(D32FS8X24 *dst, const DepthStencil *src);
+};
+} // namespace angle
+
+#endif // IMAGEUTIL_IMAGEFORMATS_H_
diff --git a/gfx/angle/checkout/src/image_util/loadimage.cpp b/gfx/angle/checkout/src/image_util/loadimage.cpp
new file mode 100644
index 0000000000..97169c00f5
--- /dev/null
+++ b/gfx/angle/checkout/src/image_util/loadimage.cpp
@@ -0,0 +1,1796 @@
+//
+// Copyright 2013 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 LoadRGBA8ToRGBA4(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] = (r4 << 12) | (g4 << 8) | (b4 << 4) | a4;
+ }
+ }
+ }
+}
+
+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 LoadRGBA8ToRGB5A1(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] = (r5 << 11) | (g5 << 6) | (b5 << 1) | a1;
+ }
+ }
+ }
+}
+
+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 LoadRGB10A2ToRGB5A1(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] = (r5 << 11) | (g5 << 6) | (b5 << 1) | a1;
+ }
+ }
+ }
+}
+
+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 LoadRGB5A1ToBGR5A1(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++)
+ {
+ uint16_t rgba = source[x];
+ auto r5 = static_cast<uint16_t>((rgba & 0xF800) >> 11);
+ auto g5 = static_cast<uint16_t>((rgba & 0x07c0) >> 6);
+ auto b5 = static_cast<uint16_t>((rgba & 0x003e) >> 1);
+ auto a1 = static_cast<uint16_t>((rgba & 0x0001));
+ dest[x] = (b5 << 11) | (g5 << 6) | (r5 << 1) | a1;
+ }
+ }
+ }
+}
+
+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 LoadRGB10A2ToRGB10X2(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] | 0xC0000000;
+ }
+ }
+ }
+}
+
+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 LoadD24S8ToD32FS8X24(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);
+ 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] = (source[x] & 0xFFFFFF) / static_cast<float>(0xFFFFFF);
+ destStencil[x * 2] = source[x] & 0xFF000000;
+ }
+ }
+ }
+}
+
+void LoadD24S8ToD32F(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);
+ float *destDepth =
+ priv::OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
+ for (size_t x = 0; x < width; x++)
+ {
+ uint32_t sourcePixel = (source[x] >> 8) & 0xFFFFFF;
+ destDepth[x] = sourcePixel / static_cast<float>(0xFFFFFF);
+ }
+ }
+ }
+}
+
+void LoadD32ToD32FX32(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);
+ float *destDepth =
+ priv::OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
+ for (size_t x = 0; x < width; x++)
+ {
+ destDepth[x * 2] = source[x] / static_cast<float>(0xFFFFFFFF);
+ }
+ }
+ }
+}
+
+void LoadD32ToD32F(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);
+ float *destDepth =
+ priv::OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
+ for (size_t x = 0; x < width; x++)
+ {
+ uint32_t sourcePixel = source[x];
+ destDepth[x] = sourcePixel / static_cast<float>(0xFFFFFFFF);
+ }
+ }
+ }
+}
+
+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 LoadD32FS8X24ToD24S8(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;
+ uint32_t *dest =
+ priv::OffsetDataPointer<uint32_t>(output, y, z, outputRowPitch, outputDepthPitch);
+ for (size_t x = 0; x < width; x++)
+ {
+ uint32_t d = static_cast<uint32_t>(gl::clamp01(sourceDepth[x * 2]) * 0xFFFFFF);
+ uint32_t s = sourceStencil[x * 2] & 0xFF000000;
+ dest[x] = d | s;
+ }
+ }
+ }
+}
+
+void LoadX24S8ToS8(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 = reinterpret_cast<const uint32_t *>(
+ input + (y * inputRowPitch) + (z * inputDepthPitch));
+ uint8_t *destStencil =
+ reinterpret_cast<uint8_t *>(output + (y * outputRowPitch) + (z * outputDepthPitch));
+ for (size_t x = 0; x < width; x++)
+ {
+ destStencil[x] = (source[x] & 0xFF);
+ }
+ }
+ }
+}
+
+void LoadX32S8ToS8(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 = reinterpret_cast<const uint32_t *>(
+ input + (y * inputRowPitch) + (z * inputDepthPitch));
+ uint8_t *destStencil =
+ reinterpret_cast<uint8_t *>(output + (y * outputRowPitch) + (z * outputDepthPitch));
+ for (size_t x = 0; x < width; x++)
+ {
+ destStencil[x] = (source[(x * 2) + 1] & 0xFF);
+ }
+ }
+ }
+}
+
+void LoadD32FS8X24ToD32F(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);
+ float *destDepth =
+ priv::OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
+ for (size_t x = 0; x < width; x++)
+ {
+ destDepth[x] = gl::clamp01(sourceDepth[x * 2]);
+ }
+ }
+ }
+}
+
+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 LoadRGB32FToRGB16F(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 * 3 + 0] = gl::float32ToFloat16(source[x * 3 + 0]);
+ dest[x * 3 + 1] = gl::float32ToFloat16(source[x * 3 + 1]);
+ dest[x * 3 + 2] = gl::float32ToFloat16(source[x * 3 + 2]);
+ }
+ }
+ }
+}
+
+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;
+ }
+ }
+ }
+}
+
+// This conversion was added to support using a 32F depth buffer
+// as emulation for 16unorm depth buffer in Metal.
+// See angleproject:6597
+void LoadUNorm16To32F(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);
+ float *dest =
+ priv::OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
+ for (size_t x = 0; x < width; x++)
+ {
+ dest[x] = static_cast<float>(source[x]) / 0xFFFF;
+ }
+ }
+ }
+}
+
+// This conversion was added to support using a 32F depth buffer
+// as emulation for 16unorm depth buffer in Metal. In OpenGL ES 3.0
+// you're allowed to pass UNSIGNED_INT as input to texImage2D and
+// so this conversion is neccasary.
+//
+// See angleproject:6597
+void LoadUNorm32To32F(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);
+ float *dest =
+ priv::OffsetDataPointer<float>(output, y, z, outputRowPitch, outputDepthPitch);
+ for (size_t x = 0; x < width; x++)
+ {
+ dest[x] = static_cast<float>(source[x]) / static_cast<float>(0xFFFFFFFFU);
+ }
+ }
+ }
+}
+
+void LoadYuvToNative(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 YUV formats it is assumed that source has tightly packed data.
+ memcpy(output, input, inputDepthPitch);
+}
+
+} // namespace angle
diff --git a/gfx/angle/checkout/src/image_util/loadimage.h b/gfx/angle/checkout/src/image_util/loadimage.h
new file mode 100644
index 0000000000..5ae4d47938
--- /dev/null
+++ b/gfx/angle/checkout/src/image_util/loadimage.h
@@ -0,0 +1,976 @@
+//
+// Copyright 2013 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 LoadRGBA8ToRGBA4(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 LoadRGBA4ToRGBA4(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 LoadRGBA8ToRGB5A1(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 LoadRGB10A2ToRGB5A1(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 LoadRGB5A1ToRGB5A1(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 LoadRGB5A1ToBGR5A1(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 LoadRGB10A2ToRGB10X2(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 LoadD24S8ToD32FS8X24(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 LoadD24S8ToD32F(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 LoadD32ToD32FX32(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 LoadD32ToD32F(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 LoadD32FS8X24ToD24S8(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 LoadX24S8ToS8(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 LoadX32S8ToS8(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 LoadD32FS8X24ToD32F(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 LoadUNorm16To32F(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 LoadUNorm32To32F(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);
+
+void LoadRGB32FToRGB16F(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 blockDepth, 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 LoadASTCToRGBA8Inner(size_t width,
+ size_t height,
+ size_t depth,
+ uint32_t blockWidth,
+ uint32_t blockHeight,
+ 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>
+inline void LoadASTCToRGBA8(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 LoadEACR11ToR16(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 LoadEACR11SToR16(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 LoadEACRG11ToRG16(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 LoadEACRG11SToRG16(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 LoadEACR11ToR16F(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 LoadEACR11SToR16F(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 LoadEACRG11ToRG16F(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 LoadEACRG11SToRG16F(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 LoadETC2RGB8ToBC1(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 LoadETC2SRGB8ToBC1(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 LoadETC2RGB8A1ToBC1(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 LoadETC2SRGB8A1ToBC1(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);
+
+void LoadYuvToNative(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 LoadPalettedToRGBA8Impl(size_t width,
+ size_t height,
+ size_t depth,
+ uint32_t indexBits,
+ uint32_t redBlueBits,
+ uint32_t greenBits,
+ uint32_t alphaBits,
+ const uint8_t *input,
+ size_t inputRowPitch,
+ size_t inputDepthPitch,
+ uint8_t *output,
+ size_t outputRowPitch,
+ size_t outputDepthPitch);
+
+template <uint32_t indexBits, uint32_t redBlueBits, uint32_t greenBits, uint32_t alphaBits>
+inline void LoadPalettedToRGBA8(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.inc"
+
+#endif // IMAGEUTIL_LOADIMAGE_H_
diff --git a/gfx/angle/checkout/src/image_util/loadimage.inc b/gfx/angle/checkout/src/image_util/loadimage.inc
new file mode 100644
index 0000000000..58c0b9faf5
--- /dev/null
+++ b/gfx/angle/checkout/src/image_util/loadimage.inc
@@ -0,0 +1,201 @@
+//
+// 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.
+//
+
+#include "common/mathutil.h"
+
+#include <string.h>
+
+namespace angle
+{
+
+namespace priv
+{
+
+template <typename T>
+inline T *OffsetDataPointer(uint8_t *data, size_t y, size_t z, size_t rowPitch, size_t depthPitch)
+{
+ return reinterpret_cast<T*>(data + (y * rowPitch) + (z * depthPitch));
+}
+
+template <typename T>
+inline const T *OffsetDataPointer(const uint8_t *data, size_t y, size_t z, size_t rowPitch, size_t depthPitch)
+{
+ 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,
+ uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch)
+{
+ const size_t rowSize = width * sizeof(type) * componentCount;
+ const size_t layerSize = rowSize * height;
+ const size_t imageSize = layerSize * depth;
+
+ if (layerSize == inputDepthPitch && layerSize == outputDepthPitch)
+ {
+ ASSERT(rowSize == inputRowPitch && rowSize == outputRowPitch);
+ memcpy(output, input, imageSize);
+ }
+ else if (rowSize == inputRowPitch && rowSize == outputRowPitch)
+ {
+ for (size_t z = 0; z < depth; z++)
+ {
+ 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);
+ }
+ }
+ else
+ {
+ for (size_t z = 0; z < depth; z++)
+ {
+ for (size_t y = 0; y < height; y++)
+ {
+ 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);
+ }
+ }
+ }
+}
+
+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)
+{
+ const type fourthValue = gl::bitCast<type>(fourthComponentBits);
+
+ for (size_t z = 0; z < depth; z++)
+ {
+ for (size_t y = 0; y < height; y++)
+ {
+ 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++)
+ {
+ memcpy(&dest[x * 4], &source[x * 3], sizeof(type) * 3);
+ dest[x * 4 + 3] = fourthValue;
+ }
+ }
+ }
+}
+
+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)
+{
+ const size_t elementWidth = componentCount * width;
+
+ 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 < elementWidth; x++)
+ {
+ dest[x] = gl::float32ToFloat16(source[x]);
+ }
+ }
+ }
+}
+
+template <size_t blockWidth, size_t blockHeight, size_t blockDepth, 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)
+{
+ const size_t columns = (width + (blockWidth - 1)) / blockWidth;
+ const size_t rows = (height + (blockHeight - 1)) / blockHeight;
+ const size_t layers = (depth + (blockDepth - 1)) / blockDepth;
+
+ for (size_t z = 0; z < layers; ++z)
+ {
+ for (size_t y = 0; y < rows; ++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);
+ memcpy(dest, source, columns * blockSize);
+ }
+ }
+}
+
+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)
+{
+ type writeValues[4] =
+ {
+ gl::bitCast<type>(firstBits),
+ gl::bitCast<type>(secondBits),
+ gl::bitCast<type>(thirdBits),
+ gl::bitCast<type>(fourthBits),
+ };
+
+ for (size_t z = 0; z < depth; z++)
+ {
+ for (size_t y = 0; y < height; y++)
+ {
+ type *destRow = priv::OffsetDataPointer<type>(output, y, z, outputRowPitch, outputDepthPitch);
+ for (size_t x = 0; x < width; x++)
+ {
+ type* destPixel = destRow + x * 4;
+
+ // This could potentially be optimized by generating an entire row of initialization
+ // data and copying row by row instead of pixel by pixel.
+ memcpy(destPixel, writeValues, sizeof(type) * 4);
+ }
+ }
+ }
+}
+
+template <size_t blockWidth, size_t blockHeight>
+inline void LoadASTCToRGBA8(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)
+{
+ LoadASTCToRGBA8Inner(width, height, depth, blockWidth, blockHeight, input, inputRowPitch,
+ inputDepthPitch, output, outputRowPitch, outputDepthPitch);
+}
+
+template <uint32_t indexBits, uint32_t redBlueBits, uint32_t greenBits, uint32_t alphaBits>
+inline void LoadPalettedToRGBA8(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)
+{
+ static_assert(indexBits == 4 || indexBits == 8);
+ static_assert(redBlueBits == 4 || redBlueBits == 5 || redBlueBits == 8);
+ static_assert(greenBits == 4 || greenBits == 5 || greenBits == 6 || greenBits == 8);
+ static_assert(alphaBits == 0 || alphaBits == 1 || alphaBits == 4 || alphaBits == 8);
+ constexpr uint32_t colorBits = 2 * redBlueBits + greenBits + alphaBits;
+ static_assert(colorBits == 16 || colorBits == 24 || colorBits == 32);
+
+ LoadPalettedToRGBA8Impl(width, height, depth,
+ indexBits, redBlueBits, greenBits, alphaBits,
+ input, inputRowPitch, inputDepthPitch,
+ output, outputRowPitch, outputDepthPitch);
+}
+
+} // namespace angle
diff --git a/gfx/angle/checkout/src/image_util/loadimage_astc.cpp b/gfx/angle/checkout/src/image_util/loadimage_astc.cpp
new file mode 100644
index 0000000000..34fd164322
--- /dev/null
+++ b/gfx/angle/checkout/src/image_util/loadimage_astc.cpp
@@ -0,0 +1,84 @@
+//
+// Copyright 2022 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_astc.cpp: Decodes ASTC encoded textures.
+
+#ifdef ANGLE_HAS_ASTCENC
+# include <astcenc.h>
+#endif
+
+#include "image_util/loadimage.h"
+
+namespace angle
+{
+
+void LoadASTCToRGBA8Inner(size_t width,
+ size_t height,
+ size_t depth,
+ uint32_t blockWidth,
+ uint32_t blockHeight,
+ const uint8_t *input,
+ size_t inputRowPitch,
+ size_t inputDepthPitch,
+ uint8_t *output,
+ size_t outputRowPitch,
+ size_t outputDepthPitch)
+{
+#ifdef ANGLE_HAS_ASTCENC
+ astcenc_config config;
+
+ constexpr unsigned int kBlockZ = 1;
+
+ const float kQuality = ASTCENC_PRE_MEDIUM;
+ constexpr astcenc_profile kProfile = ASTCENC_PRF_LDR;
+
+ astcenc_error status;
+ status = astcenc_config_init(kProfile, blockWidth, blockHeight, kBlockZ, kQuality,
+ ASTCENC_FLG_DECOMPRESS_ONLY, &config);
+ if (status != ASTCENC_SUCCESS)
+ {
+ WARN() << "astcenc config init failed: " << astcenc_get_error_string(status);
+ return;
+ }
+
+ constexpr unsigned int kThreadCount = 1;
+
+ astcenc_context *context;
+ status = astcenc_context_alloc(&config, kThreadCount, &context);
+ if (status != ASTCENC_SUCCESS)
+ {
+ WARN() << "Could not allocate astcenc context: " << astcenc_get_error_string(status);
+ return;
+ }
+
+ // Compute the number of ASTC blocks in each dimension
+ uint32_t blockCountX = (static_cast<uint32_t>(width) + config.block_x - 1) / config.block_x;
+ uint32_t blockCountY = (static_cast<uint32_t>(height) + config.block_y - 1) / config.block_y;
+
+ // Space needed for 16 bytes of output per compressed block
+ size_t blockSize = blockCountX * blockCountY * 16;
+
+ astcenc_image image;
+ image.dim_x = static_cast<uint32_t>(width);
+ image.dim_y = static_cast<uint32_t>(height);
+ image.dim_z = 1;
+ image.data_type = ASTCENC_TYPE_U8;
+ image.data = reinterpret_cast<void **>(&output);
+
+ constexpr astcenc_swizzle swizzle{ASTCENC_SWZ_R, ASTCENC_SWZ_G, ASTCENC_SWZ_B, ASTCENC_SWZ_A};
+
+ status = astcenc_decompress_image(context, input, blockSize, &image, &swizzle, 0);
+ if (status != ASTCENC_SUCCESS)
+ {
+ WARN() << "astcenc decompress failed: " << astcenc_get_error_string(status);
+ }
+
+ astcenc_context_free(context);
+#else
+ ERR() << "Trying to decode ASTC without having ASTC support built.";
+#endif
+}
+} // namespace angle
diff --git a/gfx/angle/checkout/src/image_util/loadimage_etc.cpp b/gfx/angle/checkout/src/image_util/loadimage_etc.cpp
new file mode 100644
index 0000000000..5eca88ef04
--- /dev/null
+++ b/gfx/angle/checkout/src/image_util/loadimage_etc.cpp
@@ -0,0 +1,1994 @@
+//
+// Copyright 2013 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.cpp: Decodes ETC and EAC encoded textures.
+
+#include "image_util/loadimage.h"
+
+#include <type_traits>
+#include "common/mathutil.h"
+
+#include "image_util/imageformats.h"
+
+namespace angle
+{
+namespace
+{
+
+using IntensityModifier = const int[4];
+
+// Table 3.17.2 sorted according to table 3.17.3
+// clang-format off
+static IntensityModifier intensityModifierDefault[] =
+{
+ { 2, 8, -2, -8 },
+ { 5, 17, -5, -17 },
+ { 9, 29, -9, -29 },
+ { 13, 42, -13, -42 },
+ { 18, 60, -18, -60 },
+ { 24, 80, -24, -80 },
+ { 33, 106, -33, -106 },
+ { 47, 183, -47, -183 },
+};
+// clang-format on
+
+// Table C.12, intensity modifier for non opaque punchthrough alpha
+// clang-format off
+static IntensityModifier intensityModifierNonOpaque[] =
+{
+ { 0, 8, 0, -8 },
+ { 0, 17, 0, -17 },
+ { 0, 29, 0, -29 },
+ { 0, 42, 0, -42 },
+ { 0, 60, 0, -60 },
+ { 0, 80, 0, -80 },
+ { 0, 106, 0, -106 },
+ { 0, 183, 0, -183 },
+};
+// clang-format on
+
+static const int kNumPixelsInBlock = 16;
+
+struct ETC2Block
+{
+ // Decodes unsigned single or dual channel ETC2 block to 8-bit color
+ void decodeAsSingleETC2Channel(uint8_t *dest,
+ size_t x,
+ size_t y,
+ size_t w,
+ size_t h,
+ size_t destPixelStride,
+ size_t destRowPitch,
+ bool isSigned) const
+ {
+ for (size_t j = 0; j < 4 && (y + j) < h; j++)
+ {
+ uint8_t *row = dest + (j * destRowPitch);
+ for (size_t i = 0; i < 4 && (x + i) < w; i++)
+ {
+ uint8_t *pixel = row + (i * destPixelStride);
+ if (isSigned)
+ {
+ *pixel = clampSByte(getSingleETC2Channel(i, j, isSigned));
+ }
+ else
+ {
+ *pixel = clampByte(getSingleETC2Channel(i, j, isSigned));
+ }
+ }
+ }
+ }
+
+ // Decodes unsigned single or dual channel EAC block to 16-bit color
+ void decodeAsSingleEACChannel(uint16_t *dest,
+ size_t x,
+ size_t y,
+ size_t w,
+ size_t h,
+ size_t destPixelStride,
+ size_t destRowPitch,
+ bool isSigned,
+ bool isFloat) const
+ {
+ for (size_t j = 0; j < 4 && (y + j) < h; j++)
+ {
+ uint16_t *row = reinterpret_cast<uint16_t *>(reinterpret_cast<uint8_t *>(dest) +
+ (j * destRowPitch));
+ for (size_t i = 0; i < 4 && (x + i) < w; i++)
+ {
+ uint16_t *pixel = row + (i * destPixelStride);
+ if (isSigned)
+ {
+ int16_t tempPixel =
+ renormalizeEAC<int16_t>(getSingleEACChannel(i, j, isSigned));
+ *pixel =
+ isFloat ? gl::float32ToFloat16(float(gl::normalize(tempPixel))) : tempPixel;
+ }
+ else
+ {
+ uint16_t tempPixel =
+ renormalizeEAC<uint16_t>(getSingleEACChannel(i, j, isSigned));
+ *pixel =
+ isFloat ? gl::float32ToFloat16(float(gl::normalize(tempPixel))) : tempPixel;
+ }
+ }
+ }
+ }
+
+ // Decodes RGB block to rgba8
+ void decodeAsRGB(uint8_t *dest,
+ size_t x,
+ size_t y,
+ size_t w,
+ size_t h,
+ size_t destRowPitch,
+ const uint8_t alphaValues[4][4],
+ bool punchThroughAlpha) const
+ {
+ bool opaqueBit = u.idht.mode.idm.diffbit;
+ bool nonOpaquePunchThroughAlpha = punchThroughAlpha && !opaqueBit;
+ // Select mode
+ if (u.idht.mode.idm.diffbit || punchThroughAlpha)
+ {
+ 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);
+ if (r < 0 || r > 31)
+ {
+ decodeTBlock(dest, x, y, w, h, destRowPitch, alphaValues,
+ nonOpaquePunchThroughAlpha);
+ }
+ else if (g < 0 || g > 31)
+ {
+ decodeHBlock(dest, x, y, w, h, destRowPitch, alphaValues,
+ nonOpaquePunchThroughAlpha);
+ }
+ else if (b < 0 || b > 31)
+ {
+ decodePlanarBlock(dest, x, y, w, h, destRowPitch, alphaValues);
+ }
+ else
+ {
+ decodeDifferentialBlock(dest, x, y, w, h, destRowPitch, alphaValues,
+ nonOpaquePunchThroughAlpha);
+ }
+ }
+ else
+ {
+ decodeIndividualBlock(dest, x, y, w, h, destRowPitch, alphaValues,
+ nonOpaquePunchThroughAlpha);
+ }
+ }
+
+ // Transcodes RGB block to BC1
+ void transcodeAsBC1(uint8_t *dest,
+ size_t x,
+ size_t y,
+ size_t w,
+ size_t h,
+ const uint8_t alphaValues[4][4],
+ bool punchThroughAlpha) const
+ {
+ bool opaqueBit = u.idht.mode.idm.diffbit;
+ bool nonOpaquePunchThroughAlpha = punchThroughAlpha && !opaqueBit;
+ // Select mode
+ if (u.idht.mode.idm.diffbit || punchThroughAlpha)
+ {
+ 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);
+ if (r < 0 || r > 31)
+ {
+ transcodeTBlockToBC1(dest, x, y, w, h, alphaValues, nonOpaquePunchThroughAlpha);
+ }
+ else if (g < 0 || g > 31)
+ {
+ transcodeHBlockToBC1(dest, x, y, w, h, alphaValues, nonOpaquePunchThroughAlpha);
+ }
+ else if (b < 0 || b > 31)
+ {
+ transcodePlanarBlockToBC1(dest, x, y, w, h, alphaValues);
+ }
+ else
+ {
+ transcodeDifferentialBlockToBC1(dest, x, y, w, h, alphaValues,
+ nonOpaquePunchThroughAlpha);
+ }
+ }
+ else
+ {
+ transcodeIndividualBlockToBC1(dest, x, y, w, h, alphaValues,
+ nonOpaquePunchThroughAlpha);
+ }
+ }
+
+ private:
+ union
+ {
+ // Individual, differential, H and T modes
+ struct
+ {
+ union
+ {
+ // Individual and differential modes
+ struct
+ {
+ union
+ {
+ struct // Individual colors
+ {
+ unsigned char R2 : 4;
+ unsigned char R1 : 4;
+ unsigned char G2 : 4;
+ unsigned char G1 : 4;
+ unsigned char B2 : 4;
+ unsigned char B1 : 4;
+ } indiv;
+ struct // Differential colors
+ {
+ signed char dR : 3;
+ unsigned char R : 5;
+ signed char dG : 3;
+ unsigned char G : 5;
+ signed char dB : 3;
+ unsigned char B : 5;
+ } diff;
+ } colors;
+ bool flipbit : 1;
+ bool diffbit : 1;
+ unsigned char cw2 : 3;
+ unsigned char cw1 : 3;
+ } idm;
+ // T mode
+ struct
+ {
+ // Byte 1
+ unsigned char TR1b : 2;
+ unsigned char TunusedB : 1;
+ unsigned char TR1a : 2;
+ unsigned char TunusedA : 3;
+ // Byte 2
+ unsigned char TB1 : 4;
+ unsigned char TG1 : 4;
+ // Byte 3
+ unsigned char TG2 : 4;
+ unsigned char TR2 : 4;
+ // Byte 4
+ unsigned char Tdb : 1;
+ bool Tflipbit : 1;
+ unsigned char Tda : 2;
+ unsigned char TB2 : 4;
+ } tm;
+ // H mode
+ struct
+ {
+ // Byte 1
+ unsigned char HG1a : 3;
+ unsigned char HR1 : 4;
+ unsigned char HunusedA : 1;
+ // Byte 2
+ unsigned char HB1b : 2;
+ unsigned char HunusedC : 1;
+ unsigned char HB1a : 1;
+ unsigned char HG1b : 1;
+ unsigned char HunusedB : 3;
+ // Byte 3
+ unsigned char HG2a : 3;
+ unsigned char HR2 : 4;
+ unsigned char HB1c : 1;
+ // Byte 4
+ unsigned char Hdb : 1;
+ bool Hflipbit : 1;
+ unsigned char Hda : 1;
+ unsigned char HB2 : 4;
+ unsigned char HG2b : 1;
+ } hm;
+ } mode;
+ unsigned char pixelIndexMSB[2];
+ unsigned char pixelIndexLSB[2];
+ } idht;
+ // planar mode
+ struct
+ {
+ // Byte 1
+ unsigned char GO1 : 1;
+ unsigned char RO : 6;
+ unsigned char PunusedA : 1;
+ // Byte 2
+ unsigned char BO1 : 1;
+ unsigned char GO2 : 6;
+ unsigned char PunusedB : 1;
+ // Byte 3
+ unsigned char BO3a : 2;
+ unsigned char PunusedD : 1;
+ unsigned char BO2 : 2;
+ unsigned char PunusedC : 3;
+ // Byte 4
+ unsigned char RH2 : 1;
+ bool Pflipbit : 1;
+ unsigned char RH1 : 5;
+ unsigned char BO3b : 1;
+ // Byte 5
+ unsigned char BHa : 1;
+ unsigned char GH : 7;
+ // Byte 6
+ unsigned char RVa : 3;
+ unsigned char BHb : 5;
+ // Byte 7
+ unsigned char GVa : 5;
+ unsigned char RVb : 3;
+ // Byte 8
+ unsigned char BV : 6;
+ unsigned char GVb : 2;
+ } pblk;
+ // Single channel block
+ struct
+ {
+ union
+ {
+ unsigned char us;
+ signed char s;
+ } base_codeword;
+ unsigned char table_index : 4;
+ unsigned char multiplier : 4;
+ unsigned char mc1 : 2;
+ unsigned char mb : 3;
+ unsigned char ma : 3;
+ unsigned char mf1 : 1;
+ unsigned char me : 3;
+ unsigned char md : 3;
+ unsigned char mc2 : 1;
+ unsigned char mh : 3;
+ unsigned char mg : 3;
+ unsigned char mf2 : 2;
+ unsigned char mk1 : 2;
+ unsigned char mj : 3;
+ unsigned char mi : 3;
+ unsigned char mn1 : 1;
+ unsigned char mm : 3;
+ unsigned char ml : 3;
+ unsigned char mk2 : 1;
+ unsigned char mp : 3;
+ unsigned char mo : 3;
+ unsigned char mn2 : 2;
+ } scblk;
+ } u;
+
+ static unsigned char clampByte(int value)
+ {
+ return static_cast<unsigned char>(gl::clamp(value, 0, 255));
+ }
+
+ static signed char clampSByte(int value)
+ {
+ return static_cast<signed char>(gl::clamp(value, -128, 127));
+ }
+
+ template <typename T>
+ static T renormalizeEAC(int value)
+ {
+ int upper = 0;
+ int lower = 0;
+ int shift = 0;
+
+ if (std::is_same<T, int16_t>::value)
+ {
+ // The spec states that -1024 invalid and should be clamped to -1023
+ upper = 1023;
+ lower = -1023;
+ shift = 5;
+ }
+ else if (std::is_same<T, uint16_t>::value)
+ {
+ upper = 2047;
+ lower = 0;
+ shift = 5;
+ }
+ else
+ {
+ // We currently only support renormalizing int16_t or uint16_t
+ UNREACHABLE();
+ }
+
+ return static_cast<T>(gl::clamp(value, lower, upper)) << shift;
+ }
+
+ static R8G8B8A8 createRGBA(int red, int green, int blue, int alpha)
+ {
+ R8G8B8A8 rgba;
+ rgba.R = clampByte(red);
+ rgba.G = clampByte(green);
+ rgba.B = clampByte(blue);
+ rgba.A = clampByte(alpha);
+ return rgba;
+ }
+
+ static R8G8B8A8 createRGBA(int red, int green, int blue)
+ {
+ return createRGBA(red, green, blue, 255);
+ }
+
+ static int extend_4to8bits(int x) { return (x << 4) | x; }
+ static int extend_5to8bits(int x) { return (x << 3) | (x >> 2); }
+ static int extend_6to8bits(int x) { return (x << 2) | (x >> 4); }
+ static int extend_7to8bits(int x) { return (x << 1) | (x >> 6); }
+
+ void decodeIndividualBlock(uint8_t *dest,
+ size_t x,
+ size_t y,
+ size_t w,
+ size_t h,
+ size_t destRowPitch,
+ const uint8_t alphaValues[4][4],
+ bool nonOpaquePunchThroughAlpha) const
+ {
+ const auto &block = u.idht.mode.idm.colors.indiv;
+ int r1 = extend_4to8bits(block.R1);
+ int g1 = extend_4to8bits(block.G1);
+ int b1 = extend_4to8bits(block.B1);
+ int r2 = extend_4to8bits(block.R2);
+ int g2 = extend_4to8bits(block.G2);
+ int b2 = extend_4to8bits(block.B2);
+ decodeIndividualOrDifferentialBlock(dest, x, y, w, h, destRowPitch, r1, g1, b1, r2, g2, b2,
+ alphaValues, nonOpaquePunchThroughAlpha);
+ }
+
+ void decodeDifferentialBlock(uint8_t *dest,
+ size_t x,
+ size_t y,
+ size_t w,
+ size_t h,
+ size_t destRowPitch,
+ const uint8_t alphaValues[4][4],
+ bool nonOpaquePunchThroughAlpha) const
+ {
+ const auto &block = u.idht.mode.idm.colors.diff;
+ int b1 = extend_5to8bits(block.B);
+ int g1 = extend_5to8bits(block.G);
+ 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);
+ decodeIndividualOrDifferentialBlock(dest, x, y, w, h, destRowPitch, r1, g1, b1, r2, g2, b2,
+ alphaValues, nonOpaquePunchThroughAlpha);
+ }
+
+ void decodeIndividualOrDifferentialBlock(uint8_t *dest,
+ size_t x,
+ size_t y,
+ size_t w,
+ size_t h,
+ size_t destRowPitch,
+ int r1,
+ int g1,
+ int b1,
+ int r2,
+ int g2,
+ int b2,
+ const uint8_t alphaValues[4][4],
+ bool nonOpaquePunchThroughAlpha) const
+ {
+ const IntensityModifier *intensityModifier =
+ nonOpaquePunchThroughAlpha ? intensityModifierNonOpaque : intensityModifierDefault;
+
+ R8G8B8A8 subblockColors0[4];
+ R8G8B8A8 subblockColors1[4];
+ for (size_t modifierIdx = 0; modifierIdx < 4; modifierIdx++)
+ {
+ const int i1 = intensityModifier[u.idht.mode.idm.cw1][modifierIdx];
+ subblockColors0[modifierIdx] = createRGBA(r1 + i1, g1 + i1, b1 + i1);
+
+ const int i2 = intensityModifier[u.idht.mode.idm.cw2][modifierIdx];
+ subblockColors1[modifierIdx] = createRGBA(r2 + i2, g2 + i2, b2 + i2);
+ }
+
+ if (u.idht.mode.idm.flipbit)
+ {
+ uint8_t *curPixel = dest;
+ for (size_t j = 0; j < 2 && (y + j) < h; j++)
+ {
+ R8G8B8A8 *row = reinterpret_cast<R8G8B8A8 *>(curPixel);
+ for (size_t i = 0; i < 4 && (x + i) < w; i++)
+ {
+ row[i] = subblockColors0[getIndex(i, j)];
+ row[i].A = alphaValues[j][i];
+ }
+ curPixel += destRowPitch;
+ }
+ for (size_t j = 2; j < 4 && (y + j) < h; j++)
+ {
+ R8G8B8A8 *row = reinterpret_cast<R8G8B8A8 *>(curPixel);
+ for (size_t i = 0; i < 4 && (x + i) < w; i++)
+ {
+ row[i] = subblockColors1[getIndex(i, j)];
+ row[i].A = alphaValues[j][i];
+ }
+ curPixel += destRowPitch;
+ }
+ }
+ else
+ {
+ uint8_t *curPixel = dest;
+ for (size_t j = 0; j < 4 && (y + j) < h; j++)
+ {
+ R8G8B8A8 *row = reinterpret_cast<R8G8B8A8 *>(curPixel);
+ for (size_t i = 0; i < 2 && (x + i) < w; i++)
+ {
+ row[i] = subblockColors0[getIndex(i, j)];
+ row[i].A = alphaValues[j][i];
+ }
+ for (size_t i = 2; i < 4 && (x + i) < w; i++)
+ {
+ row[i] = subblockColors1[getIndex(i, j)];
+ row[i].A = alphaValues[j][i];
+ }
+ curPixel += destRowPitch;
+ }
+ }
+ if (nonOpaquePunchThroughAlpha)
+ {
+ decodePunchThroughAlphaBlock(dest, x, y, w, h, destRowPitch);
+ }
+ }
+
+ void decodeTBlock(uint8_t *dest,
+ size_t x,
+ size_t y,
+ size_t w,
+ size_t h,
+ size_t destRowPitch,
+ const uint8_t alphaValues[4][4],
+ bool nonOpaquePunchThroughAlpha) const
+ {
+ // Table C.8, distance index for T and H modes
+ const auto &block = u.idht.mode.tm;
+
+ int r1 = extend_4to8bits(block.TR1a << 2 | block.TR1b);
+ int g1 = extend_4to8bits(block.TG1);
+ int b1 = extend_4to8bits(block.TB1);
+ int r2 = extend_4to8bits(block.TR2);
+ int g2 = extend_4to8bits(block.TG2);
+ int b2 = extend_4to8bits(block.TB2);
+
+ static int distance[8] = {3, 6, 11, 16, 23, 32, 41, 64};
+ const int d = distance[block.Tda << 1 | block.Tdb];
+
+ const R8G8B8A8 paintColors[4] = {
+ createRGBA(r1, g1, b1),
+ createRGBA(r2 + d, g2 + d, b2 + d),
+ createRGBA(r2, g2, b2),
+ createRGBA(r2 - d, g2 - d, b2 - d),
+ };
+
+ uint8_t *curPixel = dest;
+ for (size_t j = 0; j < 4 && (y + j) < h; j++)
+ {
+ R8G8B8A8 *row = reinterpret_cast<R8G8B8A8 *>(curPixel);
+ for (size_t i = 0; i < 4 && (x + i) < w; i++)
+ {
+ row[i] = paintColors[getIndex(i, j)];
+ row[i].A = alphaValues[j][i];
+ }
+ curPixel += destRowPitch;
+ }
+
+ if (nonOpaquePunchThroughAlpha)
+ {
+ decodePunchThroughAlphaBlock(dest, x, y, w, h, destRowPitch);
+ }
+ }
+
+ void decodeHBlock(uint8_t *dest,
+ size_t x,
+ size_t y,
+ size_t w,
+ size_t h,
+ size_t destRowPitch,
+ const uint8_t alphaValues[4][4],
+ bool nonOpaquePunchThroughAlpha) const
+ {
+ // Table C.8, distance index for T and H modes
+ const auto &block = u.idht.mode.hm;
+
+ int r1 = extend_4to8bits(block.HR1);
+ int g1 = extend_4to8bits(block.HG1a << 1 | block.HG1b);
+ int b1 = extend_4to8bits(block.HB1a << 3 | block.HB1b << 1 | block.HB1c);
+ int r2 = extend_4to8bits(block.HR2);
+ int g2 = extend_4to8bits(block.HG2a << 1 | block.HG2b);
+ int b2 = extend_4to8bits(block.HB2);
+
+ static const int distance[8] = {3, 6, 11, 16, 23, 32, 41, 64};
+ const int orderingTrickBit =
+ ((r1 << 16 | g1 << 8 | b1) >= (r2 << 16 | g2 << 8 | b2) ? 1 : 0);
+ const int d = distance[(block.Hda << 2) | (block.Hdb << 1) | orderingTrickBit];
+
+ const R8G8B8A8 paintColors[4] = {
+ createRGBA(r1 + d, g1 + d, b1 + d),
+ createRGBA(r1 - d, g1 - d, b1 - d),
+ createRGBA(r2 + d, g2 + d, b2 + d),
+ createRGBA(r2 - d, g2 - d, b2 - d),
+ };
+
+ uint8_t *curPixel = dest;
+ for (size_t j = 0; j < 4 && (y + j) < h; j++)
+ {
+ R8G8B8A8 *row = reinterpret_cast<R8G8B8A8 *>(curPixel);
+ for (size_t i = 0; i < 4 && (x + i) < w; i++)
+ {
+ row[i] = paintColors[getIndex(i, j)];
+ row[i].A = alphaValues[j][i];
+ }
+ curPixel += destRowPitch;
+ }
+
+ if (nonOpaquePunchThroughAlpha)
+ {
+ decodePunchThroughAlphaBlock(dest, x, y, w, h, destRowPitch);
+ }
+ }
+
+ void decodePlanarBlock(uint8_t *dest,
+ size_t x,
+ size_t y,
+ size_t w,
+ size_t h,
+ size_t pitch,
+ const uint8_t alphaValues[4][4]) const
+ {
+ int ro = extend_6to8bits(u.pblk.RO);
+ int go = extend_7to8bits(u.pblk.GO1 << 6 | u.pblk.GO2);
+ int bo =
+ extend_6to8bits(u.pblk.BO1 << 5 | u.pblk.BO2 << 3 | u.pblk.BO3a << 1 | u.pblk.BO3b);
+ int rh = extend_6to8bits(u.pblk.RH1 << 1 | u.pblk.RH2);
+ int gh = extend_7to8bits(u.pblk.GH);
+ int bh = extend_6to8bits(u.pblk.BHa << 5 | u.pblk.BHb);
+ int rv = extend_6to8bits(u.pblk.RVa << 3 | u.pblk.RVb);
+ int gv = extend_7to8bits(u.pblk.GVa << 2 | u.pblk.GVb);
+ int bv = extend_6to8bits(u.pblk.BV);
+
+ uint8_t *curPixel = dest;
+ for (size_t j = 0; j < 4 && (y + j) < h; j++)
+ {
+ R8G8B8A8 *row = reinterpret_cast<R8G8B8A8 *>(curPixel);
+
+ int ry = static_cast<int>(j) * (rv - ro) + 2;
+ int gy = static_cast<int>(j) * (gv - go) + 2;
+ int by = static_cast<int>(j) * (bv - bo) + 2;
+ for (size_t i = 0; i < 4 && (x + i) < w; i++)
+ {
+ row[i] = createRGBA(((static_cast<int>(i) * (rh - ro) + ry) >> 2) + ro,
+ ((static_cast<int>(i) * (gh - go) + gy) >> 2) + go,
+ ((static_cast<int>(i) * (bh - bo) + by) >> 2) + bo,
+ alphaValues[j][i]);
+ }
+ curPixel += pitch;
+ }
+ }
+
+ // Index for individual, differential, H and T modes
+ size_t getIndex(size_t x, size_t y) const
+ {
+ 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;
+ return (msb << 1) | lsb;
+ }
+
+ void decodePunchThroughAlphaBlock(uint8_t *dest,
+ size_t x,
+ size_t y,
+ size_t w,
+ size_t h,
+ size_t destRowPitch) const
+ {
+ uint8_t *curPixel = dest;
+ for (size_t j = 0; j < 4 && (y + j) < h; j++)
+ {
+ R8G8B8A8 *row = reinterpret_cast<R8G8B8A8 *>(curPixel);
+ for (size_t i = 0; i < 4 && (x + i) < w; i++)
+ {
+ if (getIndex(i, j) == 2) // msb == 1 && lsb == 0
+ {
+ row[i] = createRGBA(0, 0, 0, 0);
+ }
+ }
+ curPixel += destRowPitch;
+ }
+ }
+
+ uint16_t RGB8ToRGB565(const R8G8B8A8 &rgba) const
+ {
+ return (static_cast<uint16_t>(rgba.R >> 3) << 11) |
+ (static_cast<uint16_t>(rgba.G >> 2) << 5) |
+ (static_cast<uint16_t>(rgba.B >> 3) << 0);
+ }
+
+ uint32_t matchBC1Bits(const int *pixelIndices,
+ const int *pixelIndexCounts,
+ const R8G8B8A8 *subblockColors,
+ size_t numColors,
+ const R8G8B8A8 &minColor,
+ const R8G8B8A8 &maxColor,
+ bool nonOpaquePunchThroughAlpha) const
+ {
+ // Project each pixel on the (maxColor, minColor) line to decide which
+ // BC1 code to assign to it.
+
+ uint8_t decodedColors[2][3] = {{maxColor.R, maxColor.G, maxColor.B},
+ {minColor.R, minColor.G, minColor.B}};
+
+ int direction[3];
+ for (int ch = 0; ch < 3; ch++)
+ {
+ direction[ch] = decodedColors[0][ch] - decodedColors[1][ch];
+ }
+
+ int stops[2];
+ for (int i = 0; i < 2; i++)
+ {
+ stops[i] = decodedColors[i][0] * direction[0] + decodedColors[i][1] * direction[1] +
+ decodedColors[i][2] * direction[2];
+ }
+
+ ASSERT(numColors <= kNumPixelsInBlock);
+
+ int encodedColors[kNumPixelsInBlock];
+ if (nonOpaquePunchThroughAlpha)
+ {
+ for (size_t i = 0; i < numColors; i++)
+ {
+ const int count = pixelIndexCounts[i];
+ if (count > 0)
+ {
+ // 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 (size_t i = 0; i < numColors; i++)
+ {
+ const int count = pixelIndexCounts[i];
+ if (count > 0)
+ {
+ // 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])) * 3 +
+ 0.5f),
+ 0, 3);
+ switch (factor)
+ {
+ case 0:
+ encodedColors[i] = 1;
+ break;
+ case 1:
+ encodedColors[i] = 3;
+ break;
+ case 2:
+ encodedColors[i] = 2;
+ break;
+ case 3:
+ default:
+ 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 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(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 (nonOpaquePunchThroughAlpha)
+ {
+ for (int i = 0; i < kNumPixelsInBlock; i++)
+ {
+ if (0 == subblockColors[pixelIndices[i]].A)
+ {
+ bits |= (3 << (i * 2));
+ }
+ }
+ }
+ }
+
+ if (max16 < min16)
+ {
+ std::swap(max16, min16);
+
+ uint32_t xorMask = 0;
+ if (nonOpaquePunchThroughAlpha)
+ {
+ // In transparent mode switching the colors is doing the
+ // following code swap: 0 <-> 1. 0xA selects the second bit of
+ // each code, bits >> 1 selects the first bit of the code when
+ // the seconds bit is set (case 2 and 3). We invert all the
+ // non-selected bits, that is the first bit when the code is
+ // 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;
+ }
+
+ struct BC1Block
+ {
+ uint16_t color0;
+ uint16_t color1;
+ uint32_t bits;
+ };
+
+ // Encode the opaqueness in the order of the two BC1 colors
+ BC1Block *dest = reinterpret_cast<BC1Block *>(bc1);
+ if (nonOpaquePunchThroughAlpha)
+ {
+ dest->color0 = min16;
+ dest->color1 = max16;
+ }
+ else
+ {
+ dest->color0 = max16;
+ dest->color1 = min16;
+ }
+ dest->bits = bits;
+ }
+
+ void transcodeIndividualBlockToBC1(uint8_t *dest,
+ size_t x,
+ size_t y,
+ size_t w,
+ size_t h,
+ const uint8_t alphaValues[4][4],
+ bool nonOpaquePunchThroughAlpha) const
+ {
+ const auto &block = u.idht.mode.idm.colors.indiv;
+ int r1 = extend_4to8bits(block.R1);
+ int g1 = extend_4to8bits(block.G1);
+ int b1 = extend_4to8bits(block.B1);
+ int r2 = extend_4to8bits(block.R2);
+ int g2 = extend_4to8bits(block.G2);
+ int b2 = extend_4to8bits(block.B2);
+ transcodeIndividualOrDifferentialBlockToBC1(dest, x, y, w, h, r1, g1, b1, r2, g2, b2,
+ alphaValues, nonOpaquePunchThroughAlpha);
+ }
+
+ void transcodeDifferentialBlockToBC1(uint8_t *dest,
+ size_t x,
+ size_t y,
+ size_t w,
+ size_t h,
+ const uint8_t alphaValues[4][4],
+ bool nonOpaquePunchThroughAlpha) const
+ {
+ const auto &block = u.idht.mode.idm.colors.diff;
+ int b1 = extend_5to8bits(block.B);
+ int g1 = extend_5to8bits(block.G);
+ 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);
+ transcodeIndividualOrDifferentialBlockToBC1(dest, x, y, w, h, r1, g1, b1, r2, g2, b2,
+ alphaValues, nonOpaquePunchThroughAlpha);
+ }
+
+ 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;
+ if (!flipbit)
+ {
+ std::swap(dxBegin, dyBegin);
+ std::swap(dxEnd, dyEnd);
+ }
+
+ for (size_t j = dyBegin; j < dyEnd; j++)
+ {
+ int *row = &pixelIndices[j * 4];
+ for (size_t i = dxBegin; i < dxEnd; i++)
+ {
+ const size_t pixelIndex = subblockIdx * 4 + getIndex(i, j);
+ row[i] = static_cast<int>(pixelIndex);
+ pixelIndicesCounts[pixelIndex]++;
+ }
+ }
+ }
+
+ void selectEndPointPCA(const int *pixelIndexCounts,
+ const R8G8B8A8 *subblockColors,
+ size_t numColors,
+ int *minColorIndex,
+ int *maxColorIndex) const
+ {
+ // determine color distribution
+ int mu[3], min[3], max[3];
+ for (int ch = 0; ch < 3; ch++)
+ {
+ int muv = 0;
+ int minv = 255;
+ int maxv = 0;
+ for (size_t i = 0; i < numColors; i++)
+ {
+ 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 + 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 < numColors; i++)
+ {
+ 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
+
+ // Starts with diagonal vector
+ float vfr = static_cast<float>(max[0] - min[0]);
+ float vfg = static_cast<float>(max[1] - min[1]);
+ float vfb = static_cast<float>(max[2] - min[2]);
+ float eigenvalue = 0.0f;
+
+ constexpr size_t kPowerIterations = 4;
+ for (size_t i = 0; i < kPowerIterations; i++)
+ {
+ float r = vfr * cov[0] + vfg * cov[1] + vfb * cov[2];
+ float g = vfr * cov[1] + vfg * cov[3] + vfb * cov[4];
+ float b = vfr * cov[2] + vfg * cov[4] + vfb * cov[5];
+
+ vfr = r;
+ vfg = g;
+ vfb = b;
+
+ eigenvalue = sqrt(r * r + g * g + b * b);
+ if (eigenvalue > 0)
+ {
+ float invNorm = 1.0f / eigenvalue;
+ vfr *= invNorm;
+ vfg *= invNorm;
+ vfb *= invNorm;
+ }
+ }
+
+ int vr, vg, vb;
+
+ static const float kDefaultLuminanceThreshold = 4.0f * 255;
+ 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
+ vr = 299;
+ vg = 587;
+ vb = 114;
+ }
+ else
+ {
+ // From the eigenvalue and eigenvector, choose the axis to project
+ // colors on. When projecting colors we want to do integer computations
+ // for speed, so we normalize the eigenvector to the [0, 512] range.
+ float magn = std::max(std::max(std::abs(vfr), std::abs(vfg)), std::abs(vfb));
+ magn = kQuantizeRange / magn;
+ vr = static_cast<int>(vfr * magn);
+ vg = static_cast<int>(vfg * magn);
+ vb = static_cast<int>(vfb * magn);
+ }
+
+ // Pick colors at extreme points
+ int minD = INT_MAX;
+ int maxD = 0;
+ size_t minIndex = 0;
+ size_t maxIndex = 0;
+ for (size_t i = 0; i < numColors; i++)
+ {
+ const int count = pixelIndexCounts[i];
+ if (count > 0)
+ {
+ 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;
+ }
+ }
+ }
+ }
+
+ *minColorIndex = static_cast<int>(minIndex);
+ *maxColorIndex = static_cast<int>(maxIndex);
+ }
+
+ void transcodeIndividualOrDifferentialBlockToBC1(uint8_t *dest,
+ size_t x,
+ size_t y,
+ size_t w,
+ size_t h,
+ int r1,
+ int g1,
+ int b1,
+ int r2,
+ int g2,
+ int b2,
+ const uint8_t alphaValues[4][4],
+ bool nonOpaquePunchThroughAlpha) const
+ {
+ // A BC1 block has 2 endpoints, pixels is encoded as linear
+ // interpolations of them. A ETC1/ETC2 individual or differential block
+ // has 2 subblocks. Each subblock has one color and a modifier. We
+ // 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.
+
+ // 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 IntensityModifier *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[kNumColors];
+ for (size_t modifierIdx = 0; modifierIdx < 4; modifierIdx++)
+ {
+ 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[4 + modifierIdx] = createRGBA(r2 + i2, g2 + i2, b2 + i2);
+ }
+ }
+
+ int pixelIndices[kNumPixelsInBlock];
+ int pixelIndexCounts[kNumColors] = {0};
+ // Extract pixel indices from a ETC block.
+ for (size_t blockIdx = 0; blockIdx < 2; blockIdx++)
+ {
+ extractPixelIndices(pixelIndices, pixelIndexCounts, x, y, w, h, u.idht.mode.idm.flipbit,
+ blockIdx);
+ }
+
+ int minColorIndex, maxColorIndex;
+ selectEndPointPCA(pixelIndexCounts, subblockColors, kNumColors, &minColorIndex,
+ &maxColorIndex);
+
+ packBC1(dest, pixelIndices, pixelIndexCounts, subblockColors, kNumColors, minColorIndex,
+ maxColorIndex, nonOpaquePunchThroughAlpha);
+ }
+
+ void transcodeTBlockToBC1(uint8_t *dest,
+ size_t x,
+ size_t y,
+ size_t w,
+ size_t h,
+ const uint8_t alphaValues[4][4],
+ bool nonOpaquePunchThroughAlpha) const
+ {
+ static const size_t kNumColors = 4;
+
+ // Table C.8, distance index for T and H modes
+ const auto &block = u.idht.mode.tm;
+
+ int r1 = extend_4to8bits(block.TR1a << 2 | block.TR1b);
+ int g1 = extend_4to8bits(block.TG1);
+ int b1 = extend_4to8bits(block.TB1);
+ int r2 = extend_4to8bits(block.TR2);
+ int g2 = extend_4to8bits(block.TG2);
+ int b2 = extend_4to8bits(block.TB2);
+
+ static int distance[8] = {3, 6, 11, 16, 23, 32, 41, 64};
+ const int d = distance[block.Tda << 1 | block.Tdb];
+
+ // In ETC opaque punch through formats, index == 2 means transparent pixel.
+ // Thus we don't need to compute its color, just assign it as black.
+ const R8G8B8A8 paintColors[kNumColors] = {
+ createRGBA(r1, g1, b1),
+ createRGBA(r2 + d, g2 + d, b2 + d),
+ nonOpaquePunchThroughAlpha ? createRGBA(0, 0, 0, 0) : createRGBA(r2, g2, b2),
+ createRGBA(r2 - d, g2 - d, b2 - d),
+ };
+
+ int pixelIndices[kNumPixelsInBlock];
+ int pixelIndexCounts[kNumColors] = {0};
+ for (size_t j = 0; j < 4; j++)
+ {
+ int *row = &pixelIndices[j * 4];
+ for (size_t i = 0; i < 4; i++)
+ {
+ const size_t pixelIndex = getIndex(i, j);
+ row[i] = static_cast<int>(pixelIndex);
+ pixelIndexCounts[pixelIndex]++;
+ }
+ }
+
+ int minColorIndex, maxColorIndex;
+ selectEndPointPCA(pixelIndexCounts, paintColors, kNumColors, &minColorIndex,
+ &maxColorIndex);
+
+ packBC1(dest, pixelIndices, pixelIndexCounts, paintColors, kNumColors, minColorIndex,
+ maxColorIndex, nonOpaquePunchThroughAlpha);
+ }
+
+ void transcodeHBlockToBC1(uint8_t *dest,
+ size_t x,
+ size_t y,
+ size_t w,
+ size_t h,
+ const uint8_t alphaValues[4][4],
+ bool nonOpaquePunchThroughAlpha) const
+ {
+ static const size_t kNumColors = 4;
+
+ // Table C.8, distance index for T and H modes
+ const auto &block = u.idht.mode.hm;
+
+ int r1 = extend_4to8bits(block.HR1);
+ int g1 = extend_4to8bits(block.HG1a << 1 | block.HG1b);
+ int b1 = extend_4to8bits(block.HB1a << 3 | block.HB1b << 1 | block.HB1c);
+ int r2 = extend_4to8bits(block.HR2);
+ int g2 = extend_4to8bits(block.HG2a << 1 | block.HG2b);
+ int b2 = extend_4to8bits(block.HB2);
+
+ static const int distance[8] = {3, 6, 11, 16, 23, 32, 41, 64};
+ const int orderingTrickBit =
+ ((r1 << 16 | g1 << 8 | b1) >= (r2 << 16 | g2 << 8 | b2) ? 1 : 0);
+ const int d = distance[(block.Hda << 2) | (block.Hdb << 1) | orderingTrickBit];
+
+ // In ETC opaque punch through formats, index == 2 means transparent pixel.
+ // Thus we don't need to compute its color, just assign it as black.
+ const R8G8B8A8 paintColors[kNumColors] = {
+ createRGBA(r1 + d, g1 + d, b1 + d),
+ createRGBA(r1 - d, g1 - d, b1 - d),
+ nonOpaquePunchThroughAlpha ? createRGBA(0, 0, 0, 0)
+ : createRGBA(r2 + d, g2 + d, b2 + d),
+ createRGBA(r2 - d, g2 - d, b2 - d),
+ };
+
+ int pixelIndices[kNumPixelsInBlock];
+ int pixelIndexCounts[kNumColors] = {0};
+ for (size_t j = 0; j < 4; j++)
+ {
+ int *row = &pixelIndices[j * 4];
+ for (size_t i = 0; i < 4; i++)
+ {
+ const size_t pixelIndex = getIndex(i, j);
+ row[i] = static_cast<int>(pixelIndex);
+ pixelIndexCounts[pixelIndex]++;
+ }
+ }
+
+ int minColorIndex, maxColorIndex;
+ selectEndPointPCA(pixelIndexCounts, paintColors, kNumColors, &minColorIndex,
+ &maxColorIndex);
+
+ packBC1(dest, pixelIndices, pixelIndexCounts, paintColors, kNumColors, minColorIndex,
+ maxColorIndex, nonOpaquePunchThroughAlpha);
+ }
+
+ void transcodePlanarBlockToBC1(uint8_t *dest,
+ size_t x,
+ size_t y,
+ size_t w,
+ size_t h,
+ const uint8_t alphaValues[4][4]) const
+ {
+ static const size_t kNumColors = kNumPixelsInBlock;
+
+ R8G8B8A8 rgbaBlock[kNumColors];
+ decodePlanarBlock(reinterpret_cast<uint8_t *>(rgbaBlock), x, y, w, h, sizeof(R8G8B8A8) * 4,
+ alphaValues);
+
+ // Planar block doesn't have a color table, fill indices as full
+ int pixelIndices[kNumPixelsInBlock] = {0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15};
+ int pixelIndexCounts[kNumColors] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
+
+ int minColorIndex, maxColorIndex;
+ selectEndPointPCA(pixelIndexCounts, rgbaBlock, kNumColors, &minColorIndex, &maxColorIndex);
+
+ packBC1(dest, pixelIndices, pixelIndexCounts, rgbaBlock, kNumColors, minColorIndex,
+ maxColorIndex, false);
+ }
+
+ // Single channel utility functions
+ int getSingleEACChannel(size_t x, size_t y, bool isSigned) const
+ {
+ int codeword = isSigned ? u.scblk.base_codeword.s : u.scblk.base_codeword.us;
+ int multiplier = (u.scblk.multiplier == 0) ? 1 : u.scblk.multiplier * 8;
+ return codeword * 8 + 4 + getSingleChannelModifier(x, y) * multiplier;
+ }
+
+ int getSingleETC2Channel(size_t x, size_t y, bool isSigned) const
+ {
+ int codeword = isSigned ? u.scblk.base_codeword.s : u.scblk.base_codeword.us;
+ return codeword + getSingleChannelModifier(x, y) * u.scblk.multiplier;
+ }
+
+ int getSingleChannelIndex(size_t x, size_t y) const
+ {
+ ASSERT(x < 4 && y < 4);
+
+ // clang-format off
+ switch (x * 4 + y)
+ {
+ case 0: return u.scblk.ma;
+ case 1: return u.scblk.mb;
+ case 2: return u.scblk.mc1 << 1 | u.scblk.mc2;
+ case 3: return u.scblk.md;
+ case 4: return u.scblk.me;
+ case 5: return u.scblk.mf1 << 2 | u.scblk.mf2;
+ case 6: return u.scblk.mg;
+ case 7: return u.scblk.mh;
+ case 8: return u.scblk.mi;
+ case 9: return u.scblk.mj;
+ case 10: return u.scblk.mk1 << 1 | u.scblk.mk2;
+ case 11: return u.scblk.ml;
+ case 12: return u.scblk.mm;
+ case 13: return u.scblk.mn1 << 2 | u.scblk.mn2;
+ case 14: return u.scblk.mo;
+ case 15: return u.scblk.mp;
+ default: UNREACHABLE(); return 0;
+ }
+ // clang-format on
+ }
+
+ int getSingleChannelModifier(size_t x, size_t y) const
+ {
+ // clang-format off
+ static const int modifierTable[16][8] =
+ {
+ { -3, -6, -9, -15, 2, 5, 8, 14 },
+ { -3, -7, -10, -13, 2, 6, 9, 12 },
+ { -2, -5, -8, -13, 1, 4, 7, 12 },
+ { -2, -4, -6, -13, 1, 3, 5, 12 },
+ { -3, -6, -8, -12, 2, 5, 7, 11 },
+ { -3, -7, -9, -11, 2, 6, 8, 10 },
+ { -4, -7, -8, -11, 3, 6, 7, 10 },
+ { -3, -5, -8, -11, 2, 4, 7, 10 },
+ { -2, -6, -8, -10, 1, 5, 7, 9 },
+ { -2, -5, -8, -10, 1, 4, 7, 9 },
+ { -2, -4, -8, -10, 1, 3, 7, 9 },
+ { -2, -5, -7, -10, 1, 4, 6, 9 },
+ { -3, -4, -7, -10, 2, 3, 6, 9 },
+ { -1, -2, -3, -10, 0, 1, 2, 9 },
+ { -4, -6, -8, -9, 3, 5, 7, 8 },
+ { -3, -5, -7, -9, 2, 4, 6, 8 }
+ };
+ // clang-format on
+
+ return modifierTable[u.scblk.table_index][getSingleChannelIndex(x, y)];
+ }
+};
+
+// clang-format off
+static const uint8_t DefaultETCAlphaValues[4][4] =
+{
+ { 255, 255, 255, 255 },
+ { 255, 255, 255, 255 },
+ { 255, 255, 255, 255 },
+ { 255, 255, 255, 255 },
+};
+
+// clang-format on
+void LoadR11EACToR8(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,
+ bool isSigned)
+{
+ for (size_t z = 0; z < depth; z++)
+ {
+ for (size_t y = 0; y < height; y += 4)
+ {
+ const ETC2Block *sourceRow =
+ priv::OffsetDataPointer<ETC2Block>(input, y / 4, z, inputRowPitch, inputDepthPitch);
+ uint8_t *destRow =
+ priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
+
+ for (size_t x = 0; x < width; x += 4)
+ {
+ const ETC2Block *sourceBlock = sourceRow + (x / 4);
+ uint8_t *destPixels = destRow + x;
+
+ sourceBlock->decodeAsSingleETC2Channel(destPixels, x, y, width, height, 1,
+ outputRowPitch, isSigned);
+ }
+ }
+ }
+}
+
+void LoadRG11EACToRG8(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,
+ bool isSigned)
+{
+ for (size_t z = 0; z < depth; z++)
+ {
+ for (size_t y = 0; y < height; y += 4)
+ {
+ const ETC2Block *sourceRow =
+ priv::OffsetDataPointer<ETC2Block>(input, y / 4, z, inputRowPitch, inputDepthPitch);
+ uint8_t *destRow =
+ priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
+
+ for (size_t x = 0; x < width; x += 4)
+ {
+ uint8_t *destPixelsRed = destRow + (x * 2);
+ const ETC2Block *sourceBlockRed = sourceRow + (x / 2);
+ sourceBlockRed->decodeAsSingleETC2Channel(destPixelsRed, x, y, width, height, 2,
+ outputRowPitch, isSigned);
+
+ uint8_t *destPixelsGreen = destPixelsRed + 1;
+ const ETC2Block *sourceBlockGreen = sourceBlockRed + 1;
+ sourceBlockGreen->decodeAsSingleETC2Channel(destPixelsGreen, x, y, width, height, 2,
+ outputRowPitch, isSigned);
+ }
+ }
+ }
+}
+
+void LoadR11EACToR16(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,
+ bool isSigned,
+ bool isFloat)
+{
+ for (size_t z = 0; z < depth; z++)
+ {
+ for (size_t y = 0; y < height; y += 4)
+ {
+ const ETC2Block *sourceRow =
+ priv::OffsetDataPointer<ETC2Block>(input, y / 4, z, inputRowPitch, inputDepthPitch);
+ uint16_t *destRow =
+ priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
+
+ for (size_t x = 0; x < width; x += 4)
+ {
+ const ETC2Block *sourceBlock = sourceRow + (x / 4);
+ uint16_t *destPixels = destRow + x;
+
+ sourceBlock->decodeAsSingleEACChannel(destPixels, x, y, width, height, 1,
+ outputRowPitch, isSigned, isFloat);
+ }
+ }
+ }
+}
+
+void LoadRG11EACToRG16(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,
+ bool isSigned,
+ bool isFloat)
+{
+ for (size_t z = 0; z < depth; z++)
+ {
+ for (size_t y = 0; y < height; y += 4)
+ {
+ const ETC2Block *sourceRow =
+ priv::OffsetDataPointer<ETC2Block>(input, y / 4, z, inputRowPitch, inputDepthPitch);
+ uint16_t *destRow =
+ priv::OffsetDataPointer<uint16_t>(output, y, z, outputRowPitch, outputDepthPitch);
+
+ for (size_t x = 0; x < width; x += 4)
+ {
+ uint16_t *destPixelsRed = destRow + (x * 2);
+ const ETC2Block *sourceBlockRed = sourceRow + (x / 2);
+ sourceBlockRed->decodeAsSingleEACChannel(destPixelsRed, x, y, width, height, 2,
+ outputRowPitch, isSigned, isFloat);
+
+ uint16_t *destPixelsGreen = destPixelsRed + 1;
+ const ETC2Block *sourceBlockGreen = sourceBlockRed + 1;
+ sourceBlockGreen->decodeAsSingleEACChannel(destPixelsGreen, x, y, width, height, 2,
+ outputRowPitch, isSigned, isFloat);
+ }
+ }
+ }
+}
+
+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,
+ bool punchthroughAlpha)
+{
+ for (size_t z = 0; z < depth; z++)
+ {
+ for (size_t y = 0; y < height; y += 4)
+ {
+ const ETC2Block *sourceRow =
+ priv::OffsetDataPointer<ETC2Block>(input, y / 4, z, inputRowPitch, inputDepthPitch);
+ uint8_t *destRow =
+ priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
+
+ for (size_t x = 0; x < width; x += 4)
+ {
+ const ETC2Block *sourceBlock = sourceRow + (x / 4);
+ uint8_t *destPixels = destRow + (x * 4);
+
+ sourceBlock->decodeAsRGB(destPixels, x, y, width, height, outputRowPitch,
+ DefaultETCAlphaValues, punchthroughAlpha);
+ }
+ }
+ }
+}
+
+void LoadETC2RGB8ToBC1(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,
+ bool punchthroughAlpha)
+{
+ for (size_t z = 0; z < depth; z++)
+ {
+ for (size_t y = 0; y < height; y += 4)
+ {
+ const ETC2Block *sourceRow =
+ 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)
+ {
+ const ETC2Block *sourceBlock = sourceRow + (x / 4);
+ uint8_t *destPixels = destRow + (x * 2);
+
+ sourceBlock->transcodeAsBC1(destPixels, x, y, width, height, DefaultETCAlphaValues,
+ punchthroughAlpha);
+ }
+ }
+ }
+}
+
+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,
+ bool srgb)
+{
+ uint8_t decodedAlphaValues[4][4];
+
+ for (size_t z = 0; z < depth; z++)
+ {
+ for (size_t y = 0; y < height; y += 4)
+ {
+ const ETC2Block *sourceRow =
+ priv::OffsetDataPointer<ETC2Block>(input, y / 4, z, inputRowPitch, inputDepthPitch);
+ uint8_t *destRow =
+ priv::OffsetDataPointer<uint8_t>(output, y, z, outputRowPitch, outputDepthPitch);
+
+ for (size_t x = 0; x < width; x += 4)
+ {
+ const ETC2Block *sourceBlockAlpha = sourceRow + (x / 2);
+ sourceBlockAlpha->decodeAsSingleETC2Channel(
+ reinterpret_cast<uint8_t *>(decodedAlphaValues), x, y, width, height, 1, 4,
+ false);
+
+ uint8_t *destPixels = destRow + (x * 4);
+ const ETC2Block *sourceBlockRGB = sourceBlockAlpha + 1;
+ sourceBlockRGB->decodeAsRGB(destPixels, x, y, width, height, outputRowPitch,
+ decodedAlphaValues, false);
+ }
+ }
+ }
+}
+
+} // anonymous namespace
+
+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)
+{
+ LoadETC2RGB8ToRGBA8(width, height, depth, input, inputRowPitch, inputDepthPitch, output,
+ outputRowPitch, outputDepthPitch, false);
+}
+
+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)
+{
+ LoadETC2RGB8ToBC1(width, height, depth, input, inputRowPitch, inputDepthPitch, output,
+ outputRowPitch, outputDepthPitch, false);
+}
+
+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)
+{
+ LoadR11EACToR8(width, height, depth, input, inputRowPitch, inputDepthPitch, output,
+ outputRowPitch, outputDepthPitch, false);
+}
+
+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)
+{
+ LoadR11EACToR8(width, height, depth, input, inputRowPitch, inputDepthPitch, output,
+ outputRowPitch, outputDepthPitch, true);
+}
+
+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)
+{
+ LoadRG11EACToRG8(width, height, depth, input, inputRowPitch, inputDepthPitch, output,
+ outputRowPitch, outputDepthPitch, false);
+}
+
+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)
+{
+ LoadRG11EACToRG8(width, height, depth, input, inputRowPitch, inputDepthPitch, output,
+ outputRowPitch, outputDepthPitch, true);
+}
+
+void LoadEACR11ToR16(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)
+{
+ LoadR11EACToR16(width, height, depth, input, inputRowPitch, inputDepthPitch, output,
+ outputRowPitch, outputDepthPitch, false, false);
+}
+
+void LoadEACR11SToR16(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)
+{
+ LoadR11EACToR16(width, height, depth, input, inputRowPitch, inputDepthPitch, output,
+ outputRowPitch, outputDepthPitch, true, false);
+}
+
+void LoadEACRG11ToRG16(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)
+{
+ LoadRG11EACToRG16(width, height, depth, input, inputRowPitch, inputDepthPitch, output,
+ outputRowPitch, outputDepthPitch, false, false);
+}
+
+void LoadEACRG11SToRG16(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)
+{
+ LoadRG11EACToRG16(width, height, depth, input, inputRowPitch, inputDepthPitch, output,
+ outputRowPitch, outputDepthPitch, true, false);
+}
+
+void LoadEACR11ToR16F(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)
+{
+ LoadR11EACToR16(width, height, depth, input, inputRowPitch, inputDepthPitch, output,
+ outputRowPitch, outputDepthPitch, false, true);
+}
+
+void LoadEACR11SToR16F(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)
+{
+ LoadR11EACToR16(width, height, depth, input, inputRowPitch, inputDepthPitch, output,
+ outputRowPitch, outputDepthPitch, true, true);
+}
+
+void LoadEACRG11ToRG16F(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)
+{
+ LoadRG11EACToRG16(width, height, depth, input, inputRowPitch, inputDepthPitch, output,
+ outputRowPitch, outputDepthPitch, false, true);
+}
+
+void LoadEACRG11SToRG16F(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)
+{
+ LoadRG11EACToRG16(width, height, depth, input, inputRowPitch, inputDepthPitch, output,
+ outputRowPitch, outputDepthPitch, true, true);
+}
+
+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)
+{
+ LoadETC2RGB8ToRGBA8(width, height, depth, input, inputRowPitch, inputDepthPitch, output,
+ outputRowPitch, outputDepthPitch, false);
+}
+
+void LoadETC2RGB8ToBC1(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)
+{
+ LoadETC2RGB8ToBC1(width, height, depth, input, inputRowPitch, inputDepthPitch, output,
+ outputRowPitch, outputDepthPitch, false);
+}
+
+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)
+{
+ LoadETC2RGB8ToRGBA8(width, height, depth, input, inputRowPitch, inputDepthPitch, output,
+ outputRowPitch, outputDepthPitch, false);
+}
+
+void LoadETC2SRGB8ToBC1(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)
+{
+ LoadETC2RGB8ToBC1(width, height, depth, input, inputRowPitch, inputDepthPitch, output,
+ outputRowPitch, outputDepthPitch, false);
+}
+
+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)
+{
+ LoadETC2RGB8ToRGBA8(width, height, depth, input, inputRowPitch, inputDepthPitch, output,
+ outputRowPitch, outputDepthPitch, true);
+}
+
+void LoadETC2RGB8A1ToBC1(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)
+{
+ LoadETC2RGB8ToBC1(width, height, depth, input, inputRowPitch, inputDepthPitch, output,
+ outputRowPitch, outputDepthPitch, true);
+}
+
+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)
+{
+ LoadETC2RGB8ToRGBA8(width, height, depth, input, inputRowPitch, inputDepthPitch, output,
+ outputRowPitch, outputDepthPitch, true);
+}
+
+void LoadETC2SRGB8A1ToBC1(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)
+{
+ LoadETC2RGB8ToBC1(width, height, depth, input, inputRowPitch, inputDepthPitch, output,
+ outputRowPitch, outputDepthPitch, true);
+}
+
+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)
+{
+ LoadETC2RGBA8ToRGBA8(width, height, depth, input, inputRowPitch, inputDepthPitch, output,
+ outputRowPitch, outputDepthPitch, false);
+}
+
+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)
+{
+ LoadETC2RGBA8ToRGBA8(width, height, depth, input, inputRowPitch, inputDepthPitch, output,
+ outputRowPitch, outputDepthPitch, true);
+}
+
+} // namespace angle
diff --git a/gfx/angle/checkout/src/image_util/loadimage_paletted.cpp b/gfx/angle/checkout/src/image_util/loadimage_paletted.cpp
new file mode 100644
index 0000000000..af36ce3cd6
--- /dev/null
+++ b/gfx/angle/checkout/src/image_util/loadimage_paletted.cpp
@@ -0,0 +1,158 @@
+//
+// Copyright 2022 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_paletted.cpp: Decodes GL_PALETTE_* textures.
+
+#include "image_util/loadimage.h"
+
+#include <type_traits>
+#include "common/mathutil.h"
+
+#include "image_util/imageformats.h"
+
+namespace angle
+{
+
+namespace
+{
+
+template <typename T>
+R8G8B8A8 ReadColor(const T *src)
+{
+ gl::ColorF tmp;
+ T::readColor(&tmp, src);
+ R8G8B8A8 rgba;
+ R8G8B8A8::writeColor(&rgba, &tmp);
+ return rgba;
+}
+
+size_t DecodeIndexIntoPalette(const uint8_t *row, size_t i, uint32_t indexBits)
+{
+ switch (indexBits)
+ {
+ case 4:
+ {
+ // From OES_compressed_paletted_texture, section Additions to
+ // Chapter 3 of the OpenGL 1.3 Specification (Rasterization):
+ //
+ // Texel Data Formats for compressed paletted textures
+ //
+ // PALETTE4_xxx:
+ //
+ // 7 6 5 4 3 2 1 0
+ // ---------------
+ // | 1st | 2nd |
+ // | texel | texel |
+ // ---------------
+
+ bool even = i % 2 == 0;
+ return (row[i / 2] >> (even ? 4 : 0)) & 0x0f;
+ }
+
+ case 8:
+ return row[i];
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+R8G8B8A8 DecodeColor(const uint8_t *src,
+ uint32_t redBlueBits,
+ uint32_t greenBits,
+ uint32_t alphaBits)
+{
+ switch (redBlueBits)
+ {
+ case 8:
+ ASSERT(greenBits == 8);
+ switch (alphaBits)
+ {
+ case 0:
+ return ReadColor<>(reinterpret_cast<const R8G8B8 *>(src));
+ case 8:
+ return ReadColor<>(reinterpret_cast<const R8G8B8A8 *>(src));
+ default:
+ UNREACHABLE();
+ break;
+ }
+ break;
+
+ case 5:
+ switch (greenBits)
+ {
+ case 6:
+ ASSERT(alphaBits == 0);
+ return ReadColor<>(reinterpret_cast<const R5G6B5 *>(src));
+ case 5:
+ ASSERT(alphaBits == 1);
+ return ReadColor<>(reinterpret_cast<const R5G5B5A1 *>(src));
+ default:
+ UNREACHABLE();
+ break;
+ }
+ break;
+
+ case 4:
+ ASSERT(greenBits == 4 && alphaBits == 4);
+ return ReadColor<>(reinterpret_cast<const R4G4B4A4 *>(src));
+
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ UNREACHABLE();
+ return R8G8B8A8{0, 0, 0, 255};
+}
+
+} // namespace
+
+// See LoadPalettedToRGBA8.
+void LoadPalettedToRGBA8Impl(size_t width,
+ size_t height,
+ size_t depth,
+ uint32_t indexBits,
+ uint32_t redBlueBits,
+ uint32_t greenBits,
+ uint32_t alphaBits,
+ const uint8_t *input,
+ size_t inputRowPitch,
+ size_t inputDepthPitch,
+ uint8_t *output,
+ size_t outputRowPitch,
+ size_t outputDepthPitch)
+{
+ size_t colorBytes = (redBlueBits + greenBits + redBlueBits + alphaBits) / 8;
+ size_t paletteSize = 1 << indexBits;
+ size_t paletteBytes = paletteSize * colorBytes;
+
+ const uint8_t *palette = input;
+
+ const uint8_t *texels = input + paletteBytes; // + TODO(http://anglebug.com/7688): mip levels
+
+ for (size_t z = 0; z < depth; z++)
+ {
+ for (size_t y = 0; y < height; y++)
+ {
+ const uint8_t *srcRow =
+ priv::OffsetDataPointer<uint8_t>(texels, y, z, inputRowPitch, inputDepthPitch);
+ R8G8B8A8 *dstRow =
+ priv::OffsetDataPointer<R8G8B8A8>(output, y, z, outputRowPitch, outputDepthPitch);
+
+ for (size_t x = 0; x < width; x++)
+ {
+ size_t indexIntoPalette = DecodeIndexIntoPalette(srcRow, x, indexBits);
+
+ dstRow[x] = DecodeColor(palette + indexIntoPalette * colorBytes, redBlueBits,
+ greenBits, alphaBits);
+ }
+ }
+ }
+}
+
+} // namespace angle
diff --git a/gfx/angle/checkout/src/libANGLE/AttributeMap.cpp b/gfx/angle/checkout/src/libANGLE/AttributeMap.cpp
new file mode 100644
index 0000000000..6b56aee142
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/AttributeMap.cpp
@@ -0,0 +1,147 @@
+//
+// 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.
+//
+
+#include "libANGLE/AttributeMap.h"
+
+#include "common/debug.h"
+
+namespace egl
+{
+
+AttributeMap::AttributeMap() = default;
+
+AttributeMap::AttributeMap(const AttributeMap &other) = default;
+
+AttributeMap &AttributeMap::operator=(const AttributeMap &other) = default;
+
+AttributeMap::~AttributeMap() = default;
+
+void AttributeMap::insert(EGLAttrib key, EGLAttrib value)
+{
+ mValidatedAttributes[key] = value;
+}
+
+bool AttributeMap::contains(EGLAttrib key) const
+{
+ return (attribs().find(key) != attribs().end());
+}
+
+EGLAttrib AttributeMap::get(EGLAttrib key) const
+{
+ auto iter = attribs().find(key);
+ ASSERT(iter != attribs().end());
+ return iter->second;
+}
+
+EGLAttrib AttributeMap::get(EGLAttrib key, EGLAttrib defaultValue) const
+{
+ auto iter = attribs().find(key);
+ return (iter != attribs().end()) ? iter->second : defaultValue;
+}
+
+EGLint AttributeMap::getAsInt(EGLAttrib key) const
+{
+ return static_cast<EGLint>(get(key));
+}
+
+EGLint AttributeMap::getAsInt(EGLAttrib key, EGLint defaultValue) const
+{
+ return static_cast<EGLint>(get(key, static_cast<EGLAttrib>(defaultValue)));
+}
+
+bool AttributeMap::isEmpty() const
+{
+ return attribs().empty();
+}
+
+std::vector<EGLint> AttributeMap::toIntVector() const
+{
+ std::vector<EGLint> ret;
+ for (const auto &pair : attribs())
+ {
+ ret.push_back(static_cast<EGLint>(pair.first));
+ ret.push_back(static_cast<EGLint>(pair.second));
+ }
+ ret.push_back(EGL_NONE);
+
+ return ret;
+}
+
+AttributeMap::const_iterator AttributeMap::begin() const
+{
+ return attribs().begin();
+}
+
+AttributeMap::const_iterator AttributeMap::end() const
+{
+ return attribs().end();
+}
+
+bool AttributeMap::validate(const ValidationContext *val,
+ const egl::Display *display,
+ AttributeValidationFunc validationFunc) const
+{
+ if (mIntPointer)
+ {
+ for (const EGLint *curAttrib = mIntPointer; curAttrib[0] != EGL_NONE; curAttrib += 2)
+ {
+ if (!validationFunc(val, display, curAttrib[0]))
+ {
+ return false;
+ }
+
+ mValidatedAttributes[static_cast<EGLAttrib>(curAttrib[0])] =
+ static_cast<EGLAttrib>(curAttrib[1]);
+ }
+ mIntPointer = nullptr;
+ }
+
+ if (mAttribPointer)
+ {
+ for (const EGLAttrib *curAttrib = mAttribPointer; curAttrib[0] != EGL_NONE; curAttrib += 2)
+ {
+ if (!validationFunc(val, display, curAttrib[0]))
+ {
+ return false;
+ }
+
+ mValidatedAttributes[curAttrib[0]] = curAttrib[1];
+ }
+ mAttribPointer = nullptr;
+ }
+
+ return true;
+}
+
+void AttributeMap::initializeWithoutValidation() const
+{
+ auto alwaysTrue = [](const ValidationContext *, const egl::Display *, EGLAttrib) {
+ return true;
+ };
+ (void)validate(nullptr, nullptr, alwaysTrue);
+}
+
+// static
+AttributeMap AttributeMap::CreateFromIntArray(const EGLint *attributes)
+{
+ AttributeMap map;
+ map.mIntPointer = attributes;
+ return map;
+}
+
+// static
+AttributeMap AttributeMap::CreateFromAttribArray(const EGLAttrib *attributes)
+{
+ AttributeMap map;
+ map.mAttribPointer = attributes;
+ return map;
+}
+
+bool AttributeMap::isValidated() const
+{
+ return mIntPointer == nullptr && mAttribPointer == nullptr;
+}
+} // namespace egl
diff --git a/gfx/angle/checkout/src/libANGLE/AttributeMap.h b/gfx/angle/checkout/src/libANGLE/AttributeMap.h
new file mode 100644
index 0000000000..60ba913fe1
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/AttributeMap.h
@@ -0,0 +1,100 @@
+//
+// 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.
+//
+
+#ifndef LIBANGLE_ATTRIBUTEMAP_H_
+#define LIBANGLE_ATTRIBUTEMAP_H_
+
+#include "common/FastVector.h"
+#include "common/PackedEnums.h"
+
+#include <EGL/egl.h>
+
+#include <functional>
+#include <vector>
+
+namespace egl
+{
+class Display;
+struct ValidationContext;
+
+// Validates {key, value} for each attribute. Generates an error and returns false on invalid usage.
+using AttributeValidationFunc =
+ std::function<bool(const ValidationContext *, const Display *, EGLAttrib)>;
+
+class AttributeMap final
+{
+ public:
+ static constexpr size_t kMapSize = 2;
+ using Map = angle::FlatUnorderedMap<EGLAttrib, EGLAttrib, kMapSize>;
+
+ AttributeMap();
+ AttributeMap(const AttributeMap &other);
+ AttributeMap &operator=(const AttributeMap &other);
+ ~AttributeMap();
+
+ void insert(EGLAttrib key, EGLAttrib value);
+ bool contains(EGLAttrib key) const;
+
+ EGLAttrib get(EGLAttrib key) const;
+ EGLAttrib get(EGLAttrib key, EGLAttrib defaultValue) const;
+ EGLint getAsInt(EGLAttrib key) const;
+ EGLint getAsInt(EGLAttrib key, EGLint defaultValue) const;
+
+ template <typename PackedEnumT>
+ PackedEnumT getAsPackedEnum(EGLAttrib key) const
+ {
+ return FromEGLenum<PackedEnumT>(static_cast<EGLenum>(get(key)));
+ }
+
+ using const_iterator = Map::const_iterator;
+
+ template <typename PackedEnumT>
+ PackedEnumT getAsPackedEnum(EGLAttrib key, PackedEnumT defaultValue) const
+ {
+ const_iterator iter = attribs().find(key);
+ return (attribs().find(key) != attribs().end())
+ ? FromEGLenum<PackedEnumT>(static_cast<EGLenum>(iter->second))
+ : defaultValue;
+ }
+
+ bool isEmpty() const;
+ std::vector<EGLint> toIntVector() const;
+
+ const_iterator begin() const;
+ const_iterator end() const;
+
+ [[nodiscard]] bool validate(const ValidationContext *val,
+ const egl::Display *display,
+ AttributeValidationFunc validationFunc) const;
+
+ // TODO: remove this and validate at every call site. http://anglebug.com/6671
+ void initializeWithoutValidation() const;
+
+ static AttributeMap CreateFromIntArray(const EGLint *attributes);
+ static AttributeMap CreateFromAttribArray(const EGLAttrib *attributes);
+
+ private:
+ bool isValidated() const;
+
+ const Map &attribs() const
+ {
+ ASSERT(isValidated());
+ return mValidatedAttributes;
+ }
+
+ Map &attribs()
+ {
+ ASSERT(isValidated());
+ return mValidatedAttributes;
+ }
+
+ mutable const EGLint *mIntPointer = nullptr;
+ mutable const EGLAttrib *mAttribPointer = nullptr;
+ mutable Map mValidatedAttributes;
+};
+} // namespace egl
+
+#endif // LIBANGLE_ATTRIBUTEMAP_H_
diff --git a/gfx/angle/checkout/src/libANGLE/BinaryStream.h b/gfx/angle/checkout/src/libANGLE/BinaryStream.h
new file mode 100644
index 0000000000..35672f62e8
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/BinaryStream.h
@@ -0,0 +1,286 @@
+//
+// Copyright 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.
+//
+
+// BinaryStream.h: Provides binary serialization of simple types.
+
+#ifndef LIBANGLE_BINARYSTREAM_H_
+#define LIBANGLE_BINARYSTREAM_H_
+
+#include <stdint.h>
+#include <cstddef>
+#include <string>
+#include <vector>
+
+#include "common/angleutils.h"
+#include "common/mathutil.h"
+
+namespace gl
+{
+template <typename IntT>
+struct PromotedIntegerType
+{
+ using type = typename std::conditional<
+ std::is_signed<IntT>::value,
+ typename std::conditional<sizeof(IntT) <= 4, int32_t, int64_t>::type,
+ typename std::conditional<sizeof(IntT) <= 4, uint32_t, uint64_t>::type>::type;
+};
+
+class BinaryInputStream : angle::NonCopyable
+{
+ public:
+ BinaryInputStream(const void *data, size_t length)
+ {
+ mError = false;
+ mOffset = 0;
+ mData = static_cast<const uint8_t *>(data);
+ mLength = length;
+ }
+
+ // readInt will generate an error for bool types
+ template <class IntT>
+ IntT readInt()
+ {
+ static_assert(!std::is_same<bool, std::remove_cv<IntT>()>(), "Use readBool");
+ using PromotedIntT = typename PromotedIntegerType<IntT>::type;
+ PromotedIntT value = 0;
+ read(&value);
+ ASSERT(angle::IsValueInRangeForNumericType<IntT>(value));
+ return static_cast<IntT>(value);
+ }
+
+ template <class IntT>
+ void readInt(IntT *outValue)
+ {
+ *outValue = readInt<IntT>();
+ }
+
+ template <class IntT, class VectorElementT>
+ void readIntVector(std::vector<VectorElementT> *param)
+ {
+ size_t size = readInt<size_t>();
+ for (size_t index = 0; index < size; ++index)
+ {
+ param->push_back(readInt<IntT>());
+ }
+ }
+
+ template <class EnumT>
+ EnumT readEnum()
+ {
+ using UnderlyingType = typename std::underlying_type<EnumT>::type;
+ return static_cast<EnumT>(readInt<UnderlyingType>());
+ }
+
+ template <class EnumT>
+ void readEnum(EnumT *outValue)
+ {
+ *outValue = readEnum<EnumT>();
+ }
+
+ bool readBool()
+ {
+ int value = 0;
+ read(&value);
+ return (value > 0);
+ }
+
+ void readBool(bool *outValue) { *outValue = readBool(); }
+
+ void readBytes(unsigned char outArray[], size_t count) { read<unsigned char>(outArray, count); }
+
+ std::string readString()
+ {
+ std::string outString;
+ readString(&outString);
+ return outString;
+ }
+
+ void readString(std::string *v)
+ {
+ size_t length;
+ readInt(&length);
+
+ if (mError)
+ {
+ return;
+ }
+
+ angle::CheckedNumeric<size_t> checkedOffset(mOffset);
+ checkedOffset += length;
+
+ if (!checkedOffset.IsValid() || mOffset + length > mLength)
+ {
+ mError = true;
+ return;
+ }
+
+ v->assign(reinterpret_cast<const char *>(mData) + mOffset, length);
+ mOffset = checkedOffset.ValueOrDie();
+ }
+
+ float readFloat()
+ {
+ float f;
+ read(&f, 1);
+ return f;
+ }
+
+ void skip(size_t length)
+ {
+ angle::CheckedNumeric<size_t> checkedOffset(mOffset);
+ checkedOffset += length;
+
+ if (!checkedOffset.IsValid() || mOffset + length > mLength)
+ {
+ mError = true;
+ return;
+ }
+
+ mOffset = checkedOffset.ValueOrDie();
+ }
+
+ size_t offset() const { return mOffset; }
+ size_t remainingSize() const
+ {
+ ASSERT(mLength >= mOffset);
+ return mLength - mOffset;
+ }
+
+ bool error() const { return mError; }
+
+ bool endOfStream() const { return mOffset == mLength; }
+
+ const uint8_t *data() { return mData; }
+
+ private:
+ bool mError;
+ size_t mOffset;
+ const uint8_t *mData;
+ size_t mLength;
+
+ template <typename T>
+ void read(T *v, size_t num)
+ {
+ static_assert(std::is_fundamental<T>::value, "T must be a fundamental type.");
+
+ angle::CheckedNumeric<size_t> checkedLength(num);
+ checkedLength *= sizeof(T);
+ if (!checkedLength.IsValid())
+ {
+ mError = true;
+ return;
+ }
+
+ angle::CheckedNumeric<size_t> checkedOffset(mOffset);
+ checkedOffset += checkedLength;
+
+ if (!checkedOffset.IsValid() || checkedOffset.ValueOrDie() > mLength)
+ {
+ mError = true;
+ return;
+ }
+
+ memcpy(v, mData + mOffset, checkedLength.ValueOrDie());
+ mOffset = checkedOffset.ValueOrDie();
+ }
+
+ template <typename T>
+ void read(T *v)
+ {
+ read(v, 1);
+ }
+};
+
+class BinaryOutputStream : angle::NonCopyable
+{
+ public:
+ BinaryOutputStream();
+ ~BinaryOutputStream();
+
+ // writeInt also handles bool types
+ template <class IntT>
+ void writeInt(IntT param)
+ {
+ static_assert(std::is_integral<IntT>::value, "Not an integral type");
+ static_assert(!std::is_same<bool, std::remove_cv<IntT>()>(), "Use writeBool");
+ using PromotedIntT = typename PromotedIntegerType<IntT>::type;
+ ASSERT(angle::IsValueInRangeForNumericType<PromotedIntT>(param));
+ PromotedIntT intValue = static_cast<PromotedIntT>(param);
+ write(&intValue, 1);
+ }
+
+ // Specialized writeInt for values that can also be exactly -1.
+ template <class UintT>
+ void writeIntOrNegOne(UintT param)
+ {
+ if (param == static_cast<UintT>(-1))
+ {
+ writeInt(-1);
+ }
+ else
+ {
+ writeInt(param);
+ }
+ }
+
+ template <class IntT>
+ void writeIntVector(const std::vector<IntT> &param)
+ {
+ writeInt(param.size());
+ for (IntT element : param)
+ {
+ writeIntOrNegOne(element);
+ }
+ }
+
+ template <class EnumT>
+ void writeEnum(EnumT param)
+ {
+ using UnderlyingType = typename std::underlying_type<EnumT>::type;
+ writeInt<UnderlyingType>(static_cast<UnderlyingType>(param));
+ }
+
+ void writeString(const std::string &v)
+ {
+ writeInt(v.length());
+ write(v.c_str(), v.length());
+ }
+
+ void writeBytes(const unsigned char *bytes, size_t count) { write(bytes, count); }
+
+ void writeBool(bool value)
+ {
+ int intValue = value ? 1 : 0;
+ write(&intValue, 1);
+ }
+
+ void writeFloat(float value) { write(&value, 1); }
+
+ size_t length() const { return mData.size(); }
+
+ const void *data() const { return mData.size() ? &mData[0] : nullptr; }
+
+ const std::vector<uint8_t> &getData() const { return mData; }
+
+ private:
+ template <typename T>
+ void write(const T *v, size_t num)
+ {
+ static_assert(std::is_fundamental<T>::value, "T must be a fundamental type.");
+ const char *asBytes = reinterpret_cast<const char *>(v);
+ mData.insert(mData.end(), asBytes, asBytes + num * sizeof(T));
+ }
+
+ std::vector<uint8_t> mData;
+};
+
+inline BinaryOutputStream::BinaryOutputStream() {}
+
+inline BinaryOutputStream::~BinaryOutputStream() = default;
+
+} // namespace gl
+
+#endif // LIBANGLE_BINARYSTREAM_H_
diff --git a/gfx/angle/checkout/src/libANGLE/BlobCache.cpp b/gfx/angle/checkout/src/libANGLE/BlobCache.cpp
new file mode 100644
index 0000000000..6a3e2dcc56
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/BlobCache.cpp
@@ -0,0 +1,277 @@
+//
+// Copyright 2018 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.
+//
+// BlobCache: Stores keyed blobs in memory to support EGL_ANDROID_blob_cache.
+// Can be used in conjunction with the platform layer to warm up the cache from
+// disk. MemoryProgramCache uses this to handle caching of compiled programs.
+
+#include "libANGLE/BlobCache.h"
+#include "common/utilities.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Display.h"
+#include "libANGLE/histogram_macros.h"
+#include "platform/PlatformMethods.h"
+
+#define USE_SYSTEM_ZLIB
+#include "compression_utils_portable.h"
+
+namespace egl
+{
+
+namespace
+{
+enum CacheResult
+{
+ kCacheMiss,
+ kCacheHitMemory,
+ kCacheHitDisk,
+ kCacheResultMax,
+};
+
+} // anonymous namespace
+
+// In oder to store more cache in blob cache, compress cacheData to compressedData
+// before being stored.
+bool CompressBlobCacheData(const size_t cacheSize,
+ const uint8_t *cacheData,
+ angle::MemoryBuffer *compressedData)
+{
+ uLong uncompressedSize = static_cast<uLong>(cacheSize);
+ uLong expectedCompressedSize = zlib_internal::GzipExpectedCompressedSize(uncompressedSize);
+
+ // Allocate memory.
+ if (!compressedData->resize(expectedCompressedSize))
+ {
+ ERR() << "Failed to allocate memory for compression";
+ return false;
+ }
+
+ int zResult = zlib_internal::GzipCompressHelper(compressedData->data(), &expectedCompressedSize,
+ cacheData, uncompressedSize, nullptr, nullptr);
+
+ if (zResult != Z_OK)
+ {
+ ERR() << "Failed to compress cache data: " << zResult;
+ return false;
+ }
+
+ // Resize it to expected size.
+ if (!compressedData->resize(expectedCompressedSize))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool DecompressBlobCacheData(const uint8_t *compressedData,
+ const size_t compressedSize,
+ angle::MemoryBuffer *uncompressedData)
+{
+ // Call zlib function to decompress.
+ uint32_t uncompressedSize =
+ zlib_internal::GetGzipUncompressedSize(compressedData, compressedSize);
+
+ // Allocate enough memory.
+ if (!uncompressedData->resize(uncompressedSize))
+ {
+ ERR() << "Failed to allocate memory for decompression";
+ return false;
+ }
+
+ uLong destLen = uncompressedSize;
+ int zResult = zlib_internal::GzipUncompressHelper(
+ uncompressedData->data(), &destLen, compressedData, static_cast<uLong>(compressedSize));
+
+ if (zResult != Z_OK)
+ {
+ ERR() << "Failed to decompress data: " << zResult << "\n";
+ return false;
+ }
+
+ // Resize it to expected size.
+ if (!uncompressedData->resize(destLen))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+BlobCache::BlobCache(size_t maxCacheSizeBytes)
+ : mBlobCache(maxCacheSizeBytes), mSetBlobFunc(nullptr), mGetBlobFunc(nullptr)
+{}
+
+BlobCache::~BlobCache() {}
+
+void BlobCache::put(const BlobCache::Key &key, angle::MemoryBuffer &&value)
+{
+ if (areBlobCacheFuncsSet())
+ {
+ std::scoped_lock<std::mutex> lock(mBlobCacheMutex);
+ // Store the result in the application's cache
+ mSetBlobFunc(key.data(), key.size(), value.data(), value.size());
+ }
+ else
+ {
+ populate(key, std::move(value), CacheSource::Memory);
+ }
+}
+
+bool BlobCache::compressAndPut(const BlobCache::Key &key,
+ angle::MemoryBuffer &&uncompressedValue,
+ size_t *compressedSize)
+{
+ angle::MemoryBuffer compressedValue;
+ if (!CompressBlobCacheData(uncompressedValue.size(), uncompressedValue.data(),
+ &compressedValue))
+ {
+ return false;
+ }
+ if (compressedSize != nullptr)
+ *compressedSize = compressedValue.size();
+ put(key, std::move(compressedValue));
+ return true;
+}
+
+void BlobCache::putApplication(const BlobCache::Key &key, const angle::MemoryBuffer &value)
+{
+ if (areBlobCacheFuncsSet())
+ {
+ std::scoped_lock<std::mutex> lock(mBlobCacheMutex);
+ mSetBlobFunc(key.data(), key.size(), value.data(), value.size());
+ }
+}
+
+void BlobCache::populate(const BlobCache::Key &key, angle::MemoryBuffer &&value, CacheSource source)
+{
+ std::scoped_lock<std::mutex> lock(mBlobCacheMutex);
+ CacheEntry newEntry;
+ newEntry.first = std::move(value);
+ newEntry.second = source;
+
+ // Cache it inside blob cache only if caching inside the application is not possible.
+ mBlobCache.put(key, std::move(newEntry), newEntry.first.size());
+}
+
+bool BlobCache::get(angle::ScratchBuffer *scratchBuffer,
+ const BlobCache::Key &key,
+ BlobCache::Value *valueOut,
+ size_t *bufferSizeOut)
+{
+ // Look into the application's cache, if there is such a cache
+ if (areBlobCacheFuncsSet())
+ {
+ std::scoped_lock<std::mutex> lock(mBlobCacheMutex);
+ EGLsizeiANDROID valueSize = mGetBlobFunc(key.data(), key.size(), nullptr, 0);
+ if (valueSize <= 0)
+ {
+ return false;
+ }
+
+ angle::MemoryBuffer *scratchMemory;
+ bool result = scratchBuffer->get(valueSize, &scratchMemory);
+ if (!result)
+ {
+ ERR() << "Failed to allocate memory for binary blob";
+ return false;
+ }
+
+ EGLsizeiANDROID originalValueSize = valueSize;
+ valueSize = mGetBlobFunc(key.data(), key.size(), scratchMemory->data(), valueSize);
+
+ // Make sure the key/value pair still exists/is unchanged after the second call
+ // (modifications to the application cache by another thread are a possibility)
+ if (valueSize != originalValueSize)
+ {
+ // This warning serves to find issues with the application cache, none of which are
+ // currently known to be thread-safe. If such a use ever arises, this WARN can be
+ // removed.
+ WARN() << "Binary blob no longer available in cache (removed by a thread?)";
+ return false;
+ }
+
+ *valueOut = BlobCache::Value(scratchMemory->data(), scratchMemory->size());
+ *bufferSizeOut = valueSize;
+ return true;
+ }
+
+ std::scoped_lock<std::mutex> lock(mBlobCacheMutex);
+ // Otherwise we are doing caching internally, so try to find it there
+ const CacheEntry *entry;
+ bool result = mBlobCache.get(key, &entry);
+
+ if (result)
+ {
+
+ *valueOut = BlobCache::Value(entry->first.data(), entry->first.size());
+ *bufferSizeOut = entry->first.size();
+ }
+
+ return result;
+}
+
+bool BlobCache::getAt(size_t index, const BlobCache::Key **keyOut, BlobCache::Value *valueOut)
+{
+ std::scoped_lock<std::mutex> lock(mBlobCacheMutex);
+ const CacheEntry *valueBuf;
+ bool result = mBlobCache.getAt(index, keyOut, &valueBuf);
+ if (result)
+ {
+ *valueOut = BlobCache::Value(valueBuf->first.data(), valueBuf->first.size());
+ }
+ return result;
+}
+
+BlobCache::GetAndDecompressResult BlobCache::getAndDecompress(
+ angle::ScratchBuffer *scratchBuffer,
+ const BlobCache::Key &key,
+ angle::MemoryBuffer *uncompressedValueOut)
+{
+ ASSERT(uncompressedValueOut);
+
+ Value compressedValue;
+ size_t compressedSize;
+ if (!get(scratchBuffer, key, &compressedValue, &compressedSize))
+ {
+ return GetAndDecompressResult::NotFound;
+ }
+
+ {
+ // This needs to be locked because `DecompressBlobCacheData` is reading shared memory from
+ // `compressedValue.data()`.
+ std::scoped_lock<std::mutex> lock(mBlobCacheMutex);
+ if (!DecompressBlobCacheData(compressedValue.data(), compressedSize, uncompressedValueOut))
+ {
+ return GetAndDecompressResult::DecompressFailure;
+ }
+ }
+
+ return GetAndDecompressResult::GetSuccess;
+}
+
+void BlobCache::remove(const BlobCache::Key &key)
+{
+ std::scoped_lock<std::mutex> lock(mBlobCacheMutex);
+ mBlobCache.eraseByKey(key);
+}
+
+void BlobCache::setBlobCacheFuncs(EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get)
+{
+ std::scoped_lock<std::mutex> lock(mBlobCacheMutex);
+ mSetBlobFunc = set;
+ mGetBlobFunc = get;
+}
+
+bool BlobCache::areBlobCacheFuncsSet() const
+{
+ std::scoped_lock<std::mutex> lock(mBlobCacheMutex);
+ // Either none or both of the callbacks should be set.
+ ASSERT((mSetBlobFunc != nullptr) == (mGetBlobFunc != nullptr));
+
+ return mSetBlobFunc != nullptr && mGetBlobFunc != nullptr;
+}
+
+} // namespace egl
diff --git a/gfx/angle/checkout/src/libANGLE/BlobCache.h b/gfx/angle/checkout/src/libANGLE/BlobCache.h
new file mode 100644
index 0000000000..772eee04aa
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/BlobCache.h
@@ -0,0 +1,182 @@
+//
+// Copyright 2018 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.
+//
+// BlobCache: Stores compiled and linked programs in memory so they don't
+// always have to be re-compiled. Can be used in conjunction with the platform
+// layer to warm up the cache from disk.
+
+#ifndef LIBANGLE_BLOB_CACHE_H_
+#define LIBANGLE_BLOB_CACHE_H_
+
+#include <array>
+#include <cstring>
+
+#include <anglebase/sha1.h>
+#include "common/MemoryBuffer.h"
+#include "common/hash_utils.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/SizedMRUCache.h"
+
+namespace gl
+{
+class Context;
+} // namespace gl
+
+namespace egl
+{
+// 160-bit SHA-1 hash key used for hasing a program. BlobCache opts in using fixed keys for
+// simplicity and efficiency.
+static constexpr size_t kBlobCacheKeyLength = angle::base::kSHA1Length;
+using BlobCacheKey = std::array<uint8_t, kBlobCacheKeyLength>;
+} // namespace egl
+
+namespace std
+{
+template <>
+struct hash<egl::BlobCacheKey>
+{
+ // Simple routine to hash four ints.
+ size_t operator()(const egl::BlobCacheKey &key) const
+ {
+ return angle::ComputeGenericHash(key.data(), key.size());
+ }
+};
+} // namespace std
+
+namespace egl
+{
+
+bool CompressBlobCacheData(const size_t cacheSize,
+ const uint8_t *cacheData,
+ angle::MemoryBuffer *compressedData);
+bool DecompressBlobCacheData(const uint8_t *compressedData,
+ const size_t compressedSize,
+ angle::MemoryBuffer *uncompressedData);
+
+class BlobCache final : angle::NonCopyable
+{
+ public:
+ // 160-bit SHA-1 hash key used for hasing a program. BlobCache opts in using fixed keys for
+ // simplicity and efficiency.
+ static constexpr size_t kKeyLength = kBlobCacheKeyLength;
+ using Key = BlobCacheKey;
+ class Value
+ {
+ public:
+ Value() : mPtr(nullptr), mSize(0) {}
+ Value(const uint8_t *ptr, size_t sz) : mPtr(ptr), mSize(sz) {}
+
+ // A very basic struct to hold the pointer and size together. The objects of this class
+ // don't own the memory.
+ const uint8_t *data() { return mPtr; }
+ size_t size() { return mSize; }
+
+ const uint8_t &operator[](size_t pos) const
+ {
+ ASSERT(pos < mSize);
+ return mPtr[pos];
+ }
+
+ private:
+ const uint8_t *mPtr;
+ size_t mSize;
+ };
+ enum class CacheSource
+ {
+ Memory,
+ Disk,
+ };
+
+ explicit BlobCache(size_t maxCacheSizeBytes);
+ ~BlobCache();
+
+ // Store a key-blob pair in the cache. If application callbacks are set, the application cache
+ // will be used. Otherwise the value is cached in this object.
+ void put(const BlobCache::Key &key, angle::MemoryBuffer &&value);
+
+ // Store a key-blob pair in the cache, but compress the blob before insertion. Returns false if
+ // compression fails, returns true otherwise.
+ bool compressAndPut(const BlobCache::Key &key,
+ angle::MemoryBuffer &&uncompressedValue,
+ size_t *compressedSize);
+
+ // Store a key-blob pair in the application cache, only if application callbacks are set.
+ void putApplication(const BlobCache::Key &key, const angle::MemoryBuffer &value);
+
+ // Store a key-blob pair in the cache without making callbacks to the application. This is used
+ // to repopulate this object's cache on startup without generating callback calls.
+ void populate(const BlobCache::Key &key,
+ angle::MemoryBuffer &&value,
+ CacheSource source = CacheSource::Disk);
+
+ // Check if the cache contains the blob corresponding to this key. If application callbacks are
+ // set, those will be used. Otherwise they key is looked up in this object's cache.
+ [[nodiscard]] bool get(angle::ScratchBuffer *scratchBuffer,
+ const BlobCache::Key &key,
+ BlobCache::Value *valueOut,
+ size_t *bufferSizeOut);
+
+ // For querying the contents of the cache.
+ [[nodiscard]] bool getAt(size_t index,
+ const BlobCache::Key **keyOut,
+ BlobCache::Value *valueOut);
+
+ enum class GetAndDecompressResult
+ {
+ GetSuccess,
+ NotFound,
+ DecompressFailure,
+ };
+ [[nodiscard]] GetAndDecompressResult getAndDecompress(
+ angle::ScratchBuffer *scratchBuffer,
+ const BlobCache::Key &key,
+ angle::MemoryBuffer *uncompressedValueOut);
+
+ // Evict a blob from the binary cache.
+ void remove(const BlobCache::Key &key);
+
+ // Empty the cache.
+ void clear() { mBlobCache.clear(); }
+
+ // Resize the cache. Discards current contents.
+ void resize(size_t maxCacheSizeBytes) { mBlobCache.resize(maxCacheSizeBytes); }
+
+ // Returns the number of entries in the cache.
+ size_t entryCount() const { return mBlobCache.entryCount(); }
+
+ // Reduces the current cache size and returns the number of bytes freed.
+ size_t trim(size_t limit) { return mBlobCache.shrinkToSize(limit); }
+
+ // Returns the current cache size in bytes.
+ size_t size() const { return mBlobCache.size(); }
+
+ // Returns whether the cache is empty
+ bool empty() const { return mBlobCache.empty(); }
+
+ // Returns the maximum cache size in bytes.
+ size_t maxSize() const { return mBlobCache.maxSize(); }
+
+ void setBlobCacheFuncs(EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get);
+
+ bool areBlobCacheFuncsSet() const;
+
+ bool isCachingEnabled() const { return areBlobCacheFuncsSet() || maxSize() > 0; }
+
+ std::mutex &getMutex() { return mBlobCacheMutex; }
+
+ private:
+ // This internal cache is used only if the application is not providing caching callbacks
+ using CacheEntry = std::pair<angle::MemoryBuffer, CacheSource>;
+
+ mutable std::mutex mBlobCacheMutex;
+ angle::SizedMRUCache<BlobCache::Key, CacheEntry> mBlobCache;
+
+ EGLSetBlobFuncANDROID mSetBlobFunc;
+ EGLGetBlobFuncANDROID mGetBlobFunc;
+};
+
+} // namespace egl
+
+#endif // LIBANGLE_MEMORY_PROGRAM_CACHE_H_
diff --git a/gfx/angle/checkout/src/libANGLE/Buffer.cpp b/gfx/angle/checkout/src/libANGLE/Buffer.cpp
new file mode 100644
index 0000000000..440cfd873a
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Buffer.cpp
@@ -0,0 +1,449 @@
+//
+// Copyright 2002 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.
+//
+
+// Buffer.cpp: Implements the gl::Buffer class, representing storage of vertex and/or
+// index data. Implements GL buffer objects and related functionality.
+// [OpenGL ES 2.0.24] section 2.9 page 21.
+
+#include "libANGLE/Buffer.h"
+
+#include "libANGLE/Context.h"
+#include "libANGLE/renderer/BufferImpl.h"
+#include "libANGLE/renderer/GLImplFactory.h"
+
+namespace gl
+{
+namespace
+{
+constexpr angle::SubjectIndex kImplementationSubjectIndex = 0;
+constexpr size_t kInvalidContentsObserverIndex = std::numeric_limits<size_t>::max();
+} // anonymous namespace
+
+BufferState::BufferState()
+ : mLabel(),
+ mUsage(BufferUsage::StaticDraw),
+ mSize(0),
+ mAccessFlags(0),
+ mAccess(GL_WRITE_ONLY_OES),
+ mMapped(GL_FALSE),
+ mMapPointer(nullptr),
+ mMapOffset(0),
+ mMapLength(0),
+ mBindingCount(0),
+ mTransformFeedbackIndexedBindingCount(0),
+ mTransformFeedbackGenericBindingCount(0),
+ mImmutable(GL_FALSE),
+ mStorageExtUsageFlags(0),
+ mExternal(GL_FALSE)
+{}
+
+BufferState::~BufferState() {}
+
+Buffer::Buffer(rx::GLImplFactory *factory, BufferID id)
+ : RefCountObject(factory->generateSerial(), id),
+ mImpl(factory->createBuffer(mState)),
+ mImplObserver(this, kImplementationSubjectIndex)
+{
+ mImplObserver.bind(mImpl);
+}
+
+Buffer::~Buffer()
+{
+ SafeDelete(mImpl);
+}
+
+void Buffer::onDestroy(const Context *context)
+{
+ // In tests, mImpl might be null.
+ if (mImpl)
+ mImpl->destroy(context);
+}
+
+angle::Result Buffer::setLabel(const Context *context, const std::string &label)
+{
+ mState.mLabel = label;
+ if (mImpl)
+ {
+ return mImpl->onLabelUpdate(context);
+ }
+ return angle::Result::Continue;
+}
+
+const std::string &Buffer::getLabel() const
+{
+ return mState.mLabel;
+}
+
+angle::Result Buffer::bufferStorageExternal(Context *context,
+ BufferBinding target,
+ GLsizeiptr size,
+ GLeglClientBufferEXT clientBuffer,
+ GLbitfield flags)
+{
+ return bufferExternalDataImpl(context, target, clientBuffer, size, flags);
+}
+
+angle::Result Buffer::bufferStorage(Context *context,
+ BufferBinding target,
+ GLsizeiptr size,
+ const void *data,
+ GLbitfield flags)
+{
+ return bufferDataImpl(context, target, data, size, BufferUsage::InvalidEnum, flags);
+}
+
+angle::Result Buffer::bufferData(Context *context,
+ BufferBinding target,
+ const void *data,
+ GLsizeiptr size,
+ BufferUsage usage)
+{
+ GLbitfield flags = (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_DYNAMIC_STORAGE_BIT_EXT);
+ return bufferDataImpl(context, target, data, size, usage, flags);
+}
+
+angle::Result Buffer::bufferDataImpl(Context *context,
+ BufferBinding target,
+ const void *data,
+ GLsizeiptr size,
+ BufferUsage usage,
+ GLbitfield flags)
+{
+ const void *dataForImpl = data;
+
+ if (mState.isMapped())
+ {
+ // Per the OpenGL ES 3.0 spec, buffers are implicity unmapped when a call to
+ // BufferData happens on a mapped buffer:
+ //
+ // If any portion of the buffer object is mapped in the current context or any context
+ // current to another thread, it is as though UnmapBuffer (see section 2.10.3) is
+ // executed in each such context prior to deleting the existing data store.
+ //
+ GLboolean dontCare = GL_FALSE;
+ ANGLE_TRY(unmap(context, &dontCare));
+ }
+
+ // If we are using robust resource init, make sure the buffer starts cleared.
+ // Note: the Context is checked for nullptr because of some testing code.
+ // TODO(jmadill): Investigate lazier clearing.
+ if (context && context->isRobustResourceInitEnabled() && !data && size > 0)
+ {
+ angle::MemoryBuffer *scratchBuffer = nullptr;
+ ANGLE_CHECK_GL_ALLOC(
+ context, context->getZeroFilledBuffer(static_cast<size_t>(size), &scratchBuffer));
+ dataForImpl = scratchBuffer->data();
+ }
+
+ if (mImpl->setDataWithUsageFlags(context, target, nullptr, dataForImpl, size, usage, flags) ==
+ angle::Result::Stop)
+ {
+ // If setData fails, the buffer contents are undefined. Set a zero size to indicate that.
+ mIndexRangeCache.clear();
+ mState.mSize = 0;
+
+ // Notify when storage changes.
+ onStateChange(angle::SubjectMessage::SubjectChanged);
+
+ return angle::Result::Stop;
+ }
+
+ bool wholeBuffer = size == mState.mSize;
+
+ mIndexRangeCache.clear();
+ mState.mUsage = usage;
+ mState.mSize = size;
+ mState.mImmutable = (usage == BufferUsage::InvalidEnum);
+ mState.mStorageExtUsageFlags = flags;
+
+ // Notify when storage changes.
+ if (wholeBuffer)
+ {
+ onContentsChange();
+ }
+ else
+ {
+ onStateChange(angle::SubjectMessage::SubjectChanged);
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result Buffer::bufferExternalDataImpl(Context *context,
+ BufferBinding target,
+ GLeglClientBufferEXT clientBuffer,
+ GLsizeiptr size,
+ GLbitfield flags)
+{
+ if (mState.isMapped())
+ {
+ // Per the OpenGL ES 3.0 spec, buffers are implicitly unmapped when a call to
+ // BufferData happens on a mapped buffer:
+ //
+ // If any portion of the buffer object is mapped in the current context or any context
+ // current to another thread, it is as though UnmapBuffer (see section 2.10.3) is
+ // executed in each such context prior to deleting the existing data store.
+ //
+ GLboolean dontCare = GL_FALSE;
+ ANGLE_TRY(unmap(context, &dontCare));
+ }
+
+ if (mImpl->setDataWithUsageFlags(context, target, clientBuffer, nullptr, size,
+ BufferUsage::InvalidEnum, flags) == angle::Result::Stop)
+ {
+ // If setData fails, the buffer contents are undefined. Set a zero size to indicate that.
+ mIndexRangeCache.clear();
+ mState.mSize = 0;
+
+ // Notify when storage changes.
+ onStateChange(angle::SubjectMessage::SubjectChanged);
+
+ return angle::Result::Stop;
+ }
+
+ mIndexRangeCache.clear();
+ mState.mUsage = BufferUsage::InvalidEnum;
+ mState.mSize = size;
+ mState.mImmutable = GL_TRUE;
+ mState.mStorageExtUsageFlags = flags;
+ mState.mExternal = GL_TRUE;
+
+ // Notify when storage changes.
+ onStateChange(angle::SubjectMessage::SubjectChanged);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Buffer::bufferSubData(const Context *context,
+ BufferBinding target,
+ const void *data,
+ GLsizeiptr size,
+ GLintptr offset)
+{
+ ANGLE_TRY(mImpl->setSubData(context, target, data, size, offset));
+
+ mIndexRangeCache.invalidateRange(static_cast<unsigned int>(offset),
+ static_cast<unsigned int>(size));
+
+ // Notify when data changes.
+ onContentsChange();
+
+ return angle::Result::Continue;
+}
+
+angle::Result Buffer::copyBufferSubData(const Context *context,
+ Buffer *source,
+ GLintptr sourceOffset,
+ GLintptr destOffset,
+ GLsizeiptr size)
+{
+ ANGLE_TRY(
+ mImpl->copySubData(context, source->getImplementation(), sourceOffset, destOffset, size));
+
+ mIndexRangeCache.invalidateRange(static_cast<unsigned int>(destOffset),
+ static_cast<unsigned int>(size));
+
+ // Notify when data changes.
+ onContentsChange();
+
+ return angle::Result::Continue;
+}
+
+angle::Result Buffer::map(const Context *context, GLenum access)
+{
+ ASSERT(!mState.mMapped);
+
+ mState.mMapPointer = nullptr;
+ ANGLE_TRY(mImpl->map(context, access, &mState.mMapPointer));
+
+ ASSERT(access == GL_WRITE_ONLY_OES);
+
+ mState.mMapped = GL_TRUE;
+ mState.mMapOffset = 0;
+ mState.mMapLength = mState.mSize;
+ mState.mAccess = access;
+ mState.mAccessFlags = GL_MAP_WRITE_BIT;
+ mIndexRangeCache.clear();
+
+ // Notify when state changes.
+ onStateChange(angle::SubjectMessage::SubjectMapped);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Buffer::mapRange(const Context *context,
+ GLintptr offset,
+ GLsizeiptr length,
+ GLbitfield access)
+{
+ ASSERT(!mState.mMapped);
+ ASSERT(offset + length <= mState.mSize);
+
+ mState.mMapPointer = nullptr;
+ ANGLE_TRY(mImpl->mapRange(context, offset, length, access, &mState.mMapPointer));
+
+ mState.mMapped = GL_TRUE;
+ mState.mMapOffset = static_cast<GLint64>(offset);
+ mState.mMapLength = static_cast<GLint64>(length);
+ mState.mAccess = GL_WRITE_ONLY_OES;
+ mState.mAccessFlags = access;
+
+ // The OES_mapbuffer extension states that GL_WRITE_ONLY_OES is the only valid
+ // value for GL_BUFFER_ACCESS_OES because it was written against ES2. Since there is
+ // no update for ES3 and the GL_READ_ONLY and GL_READ_WRITE enums don't exist for ES,
+ // we cannot properly set GL_BUFFER_ACCESS_OES when glMapBufferRange is called.
+
+ if ((access & GL_MAP_WRITE_BIT) > 0)
+ {
+ mIndexRangeCache.invalidateRange(static_cast<unsigned int>(offset),
+ static_cast<unsigned int>(length));
+ }
+
+ // Notify when state changes.
+ onStateChange(angle::SubjectMessage::SubjectMapped);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Buffer::unmap(const Context *context, GLboolean *result)
+{
+ ASSERT(mState.mMapped);
+
+ *result = GL_FALSE;
+ ANGLE_TRY(mImpl->unmap(context, result));
+
+ mState.mMapped = GL_FALSE;
+ mState.mMapPointer = nullptr;
+ mState.mMapOffset = 0;
+ mState.mMapLength = 0;
+ mState.mAccess = GL_WRITE_ONLY_OES;
+ mState.mAccessFlags = 0;
+
+ // Notify when data changes.
+ onStateChange(angle::SubjectMessage::SubjectUnmapped);
+
+ return angle::Result::Continue;
+}
+
+void Buffer::onDataChanged()
+{
+ mIndexRangeCache.clear();
+
+ // Notify when data changes.
+ onContentsChange();
+
+ mImpl->onDataChanged();
+}
+
+angle::Result Buffer::getIndexRange(const gl::Context *context,
+ DrawElementsType type,
+ size_t offset,
+ size_t count,
+ bool primitiveRestartEnabled,
+ IndexRange *outRange) const
+{
+ if (mIndexRangeCache.findRange(type, offset, count, primitiveRestartEnabled, outRange))
+ {
+ return angle::Result::Continue;
+ }
+
+ ANGLE_TRY(
+ mImpl->getIndexRange(context, type, offset, count, primitiveRestartEnabled, outRange));
+
+ mIndexRangeCache.addRange(type, offset, count, primitiveRestartEnabled, *outRange);
+
+ return angle::Result::Continue;
+}
+
+GLint64 Buffer::getMemorySize() const
+{
+ GLint64 implSize = mImpl->getMemorySize();
+ return implSize > 0 ? implSize : mState.mSize;
+}
+
+bool Buffer::isDoubleBoundForTransformFeedback() const
+{
+ return mState.mTransformFeedbackIndexedBindingCount > 1;
+}
+
+void Buffer::onTFBindingChanged(const Context *context, bool bound, bool indexed)
+{
+ ASSERT(bound || mState.mBindingCount > 0);
+ mState.mBindingCount += bound ? 1 : -1;
+ if (indexed)
+ {
+ ASSERT(bound || mState.mTransformFeedbackIndexedBindingCount > 0);
+ mState.mTransformFeedbackIndexedBindingCount += bound ? 1 : -1;
+
+ onStateChange(angle::SubjectMessage::BindingChanged);
+ }
+ else
+ {
+ mState.mTransformFeedbackGenericBindingCount += bound ? 1 : -1;
+ }
+}
+
+angle::Result Buffer::getSubData(const gl::Context *context,
+ GLintptr offset,
+ GLsizeiptr size,
+ void *outData)
+{
+ return mImpl->getSubData(context, offset, size, outData);
+}
+
+void Buffer::onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message)
+{
+ // Pass it along!
+ ASSERT(index == kImplementationSubjectIndex);
+ ASSERT(message == angle::SubjectMessage::SubjectChanged ||
+ message == angle::SubjectMessage::InternalMemoryAllocationChanged);
+ onStateChange(message);
+}
+
+size_t Buffer::getContentsObserverIndex(VertexArray *vertexArray, uint32_t bufferIndex) const
+{
+ for (size_t observerIndex = 0; observerIndex < mContentsObservers.size(); ++observerIndex)
+ {
+ const ContentsObserver &observer = mContentsObservers[observerIndex];
+ if (observer.vertexArray == vertexArray && observer.bufferIndex == bufferIndex)
+ {
+ return observerIndex;
+ }
+ }
+
+ return kInvalidContentsObserverIndex;
+}
+
+void Buffer::addContentsObserver(VertexArray *vertexArray, uint32_t bufferIndex)
+{
+ if (getContentsObserverIndex(vertexArray, bufferIndex) == kInvalidContentsObserverIndex)
+ {
+ mContentsObservers.push_back({vertexArray, bufferIndex});
+ }
+}
+
+void Buffer::removeContentsObserver(VertexArray *vertexArray, uint32_t bufferIndex)
+{
+ size_t foundObserver = getContentsObserverIndex(vertexArray, bufferIndex);
+ if (foundObserver != kInvalidContentsObserverIndex)
+ {
+ size_t lastObserverIndex = mContentsObservers.size() - 1;
+ if (foundObserver != lastObserverIndex)
+ {
+ mContentsObservers[foundObserver] = mContentsObservers[lastObserverIndex];
+ }
+ mContentsObservers.pop_back();
+ }
+}
+
+void Buffer::onContentsChange()
+{
+ for (const ContentsObserver &observer : mContentsObservers)
+ {
+ observer.vertexArray->onBufferContentsChange(observer.bufferIndex);
+ }
+}
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/Buffer.h b/gfx/angle/checkout/src/libANGLE/Buffer.h
new file mode 100644
index 0000000000..b71f6af89b
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Buffer.h
@@ -0,0 +1,218 @@
+//
+// Copyright 2002 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.
+//
+
+// Buffer.h: Defines the gl::Buffer class, representing storage of vertex and/or
+// index data. Implements GL buffer objects and related functionality.
+// [OpenGL ES 2.0.24] section 2.9 page 21.
+
+#ifndef LIBANGLE_BUFFER_H_
+#define LIBANGLE_BUFFER_H_
+
+#include "common/PackedEnums.h"
+#include "common/angleutils.h"
+#include "libANGLE/Debug.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/IndexRangeCache.h"
+#include "libANGLE/Observer.h"
+#include "libANGLE/RefCountObject.h"
+#include "libANGLE/angletypes.h"
+
+namespace rx
+{
+class BufferImpl;
+class GLImplFactory;
+} // namespace rx
+
+namespace gl
+{
+class Buffer;
+class Context;
+
+class BufferState final : angle::NonCopyable
+{
+ public:
+ BufferState();
+ ~BufferState();
+
+ BufferUsage getUsage() const { return mUsage; }
+ GLbitfield getAccessFlags() const { return mAccessFlags; }
+ GLenum getAccess() const { return mAccess; }
+ GLboolean isMapped() const { return mMapped; }
+ void *getMapPointer() const { return mMapPointer; }
+ GLint64 getMapOffset() const { return mMapOffset; }
+ GLint64 getMapLength() const { return mMapLength; }
+ GLint64 getSize() const { return mSize; }
+ bool isBoundForTransformFeedback() const { return mTransformFeedbackIndexedBindingCount != 0; }
+ std::string getLabel() const { return mLabel; }
+
+ private:
+ friend class Buffer;
+
+ std::string mLabel;
+
+ BufferUsage mUsage;
+ GLint64 mSize;
+ GLbitfield mAccessFlags;
+ GLenum mAccess;
+ GLboolean mMapped;
+ void *mMapPointer;
+ GLint64 mMapOffset;
+ GLint64 mMapLength;
+ int mBindingCount;
+ int mTransformFeedbackIndexedBindingCount;
+ int mTransformFeedbackGenericBindingCount;
+ GLboolean mImmutable;
+ GLbitfield mStorageExtUsageFlags;
+ GLboolean mExternal;
+};
+
+// Some Vertex Array Objects track buffer data updates.
+struct ContentsObserver
+{
+ VertexArray *vertexArray = nullptr;
+ uint32_t bufferIndex = 0;
+};
+
+ANGLE_INLINE bool operator==(const ContentsObserver &lhs, const ContentsObserver &rhs)
+{
+ return lhs.vertexArray == rhs.vertexArray && lhs.bufferIndex == rhs.bufferIndex;
+}
+
+class Buffer final : public RefCountObject<BufferID>,
+ public LabeledObject,
+ public angle::ObserverInterface,
+ public angle::Subject
+{
+ public:
+ Buffer(rx::GLImplFactory *factory, BufferID id);
+ ~Buffer() override;
+ void onDestroy(const Context *context) override;
+
+ angle::Result setLabel(const Context *context, const std::string &label) override;
+ const std::string &getLabel() const override;
+
+ angle::Result bufferStorageExternal(Context *context,
+ BufferBinding target,
+ GLsizeiptr size,
+ GLeglClientBufferEXT clientBuffer,
+ GLbitfield flags);
+ angle::Result bufferStorage(Context *context,
+ BufferBinding target,
+ GLsizeiptr size,
+ const void *data,
+ GLbitfield flags);
+ angle::Result bufferData(Context *context,
+ BufferBinding target,
+ const void *data,
+ GLsizeiptr size,
+ BufferUsage usage);
+ angle::Result bufferSubData(const Context *context,
+ BufferBinding target,
+ const void *data,
+ GLsizeiptr size,
+ GLintptr offset);
+ angle::Result copyBufferSubData(const Context *context,
+ Buffer *source,
+ GLintptr sourceOffset,
+ GLintptr destOffset,
+ GLsizeiptr size);
+ angle::Result map(const Context *context, GLenum access);
+ angle::Result mapRange(const Context *context,
+ GLintptr offset,
+ GLsizeiptr length,
+ GLbitfield access);
+ angle::Result unmap(const Context *context, GLboolean *result);
+
+ // These are called when another operation changes Buffer data.
+ void onDataChanged();
+
+ angle::Result getIndexRange(const gl::Context *context,
+ DrawElementsType type,
+ size_t offset,
+ size_t count,
+ bool primitiveRestartEnabled,
+ IndexRange *outRange) const;
+ const BufferState &getState() const { return mState; }
+ BufferUsage getUsage() const { return mState.mUsage; }
+ GLbitfield getAccessFlags() const { return mState.mAccessFlags; }
+ GLenum getAccess() const { return mState.mAccess; }
+ GLboolean isMapped() const { return mState.mMapped; }
+ bool isPersistentlyMapped() const
+ {
+ return (mState.mStorageExtUsageFlags & GL_MAP_PERSISTENT_BIT_EXT) != 0;
+ }
+ void *getMapPointer() const { return mState.mMapPointer; }
+ GLint64 getMapOffset() const { return mState.mMapOffset; }
+ GLint64 getMapLength() const { return mState.mMapLength; }
+ GLint64 getSize() const { return mState.mSize; }
+ GLint64 getMemorySize() const;
+ GLboolean isImmutable() const { return mState.mImmutable; }
+ GLbitfield getStorageExtUsageFlags() const { return mState.mStorageExtUsageFlags; }
+
+ // Buffers are always initialized immediately when allocated
+ InitState initState() const { return InitState::Initialized; }
+
+ rx::BufferImpl *getImplementation() const { return mImpl; }
+
+ // Note: we pass "isWebGL" to this function to clarify it's only valid if WebGL is enabled.
+ // We pass the boolean flag instead of the pointer because this header can't read Context.h.
+ ANGLE_INLINE bool hasWebGLXFBBindingConflict(bool isWebGL) const
+ {
+ if (!isWebGL)
+ {
+ return false;
+ }
+
+ // The transform feedback generic binding point is not an indexed binding point but it also
+ // does not count as a non-transform-feedback use of the buffer, so we subtract it from the
+ // binding count when checking if the buffer is bound to a non-transform-feedback location.
+ // See https://crbug.com/853978
+ return mState.mTransformFeedbackIndexedBindingCount > 0 &&
+ mState.mTransformFeedbackIndexedBindingCount !=
+ mState.mBindingCount - mState.mTransformFeedbackGenericBindingCount;
+ }
+
+ bool isDoubleBoundForTransformFeedback() const;
+ void onTFBindingChanged(const Context *context, bool bound, bool indexed);
+ void onNonTFBindingChanged(int incr) { mState.mBindingCount += incr; }
+ angle::Result getSubData(const gl::Context *context,
+ GLintptr offset,
+ GLsizeiptr size,
+ void *outData);
+
+ // angle::ObserverInterface implementation.
+ void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override;
+
+ void addContentsObserver(VertexArray *vertexArray, uint32_t bufferIndex);
+ void removeContentsObserver(VertexArray *vertexArray, uint32_t bufferIndex);
+
+ private:
+ angle::Result bufferDataImpl(Context *context,
+ BufferBinding target,
+ const void *data,
+ GLsizeiptr size,
+ BufferUsage usage,
+ GLbitfield flags);
+ angle::Result bufferExternalDataImpl(Context *context,
+ BufferBinding target,
+ GLeglClientBufferEXT clientBuffer,
+ GLsizeiptr size,
+ GLbitfield flags);
+
+ void onContentsChange();
+ size_t getContentsObserverIndex(VertexArray *vertexArray, uint32_t bufferIndex) const;
+
+ BufferState mState;
+ rx::BufferImpl *mImpl;
+ angle::ObserverBinding mImplObserver;
+
+ angle::FastVector<ContentsObserver, angle::kMaxFixedObservers> mContentsObservers;
+ mutable IndexRangeCache mIndexRangeCache;
+};
+
+} // namespace gl
+
+#endif // LIBANGLE_BUFFER_H_
diff --git a/gfx/angle/checkout/src/libANGLE/Caps.cpp b/gfx/angle/checkout/src/libANGLE/Caps.cpp
new file mode 100644
index 0000000000..d0b27ebbc2
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Caps.cpp
@@ -0,0 +1,1371 @@
+//
+// 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.
+//
+
+#include "libANGLE/Caps.h"
+
+#include "common/angleutils.h"
+#include "common/debug.h"
+
+#include "libANGLE/formatutils.h"
+
+#include "angle_gl.h"
+
+#include <algorithm>
+#include <sstream>
+
+static void InsertExtensionString(const std::string &extension,
+ bool supported,
+ std::vector<std::string> *extensionVector)
+{
+ if (supported)
+ {
+ extensionVector->push_back(extension);
+ }
+}
+
+namespace gl
+{
+
+TextureCaps::TextureCaps() = default;
+
+TextureCaps::TextureCaps(const TextureCaps &other) = default;
+
+TextureCaps &TextureCaps::operator=(const TextureCaps &other) = default;
+
+TextureCaps::~TextureCaps() = default;
+
+GLuint TextureCaps::getMaxSamples() const
+{
+ return !sampleCounts.empty() ? *sampleCounts.rbegin() : 0;
+}
+
+GLuint TextureCaps::getNearestSamples(GLuint requestedSamples) const
+{
+ if (requestedSamples == 0)
+ {
+ return 0;
+ }
+
+ for (SupportedSampleSet::const_iterator i = sampleCounts.begin(); i != sampleCounts.end(); i++)
+ {
+ GLuint samples = *i;
+ if (samples >= requestedSamples)
+ {
+ return samples;
+ }
+ }
+
+ return 0;
+}
+
+TextureCaps GenerateMinimumTextureCaps(GLenum sizedInternalFormat,
+ const Version &clientVersion,
+ const Extensions &extensions)
+{
+ TextureCaps caps;
+
+ const InternalFormat &internalFormatInfo = GetSizedInternalFormatInfo(sizedInternalFormat);
+ caps.texturable = internalFormatInfo.textureSupport(clientVersion, extensions);
+ caps.filterable = internalFormatInfo.filterSupport(clientVersion, extensions);
+ caps.textureAttachment = internalFormatInfo.textureAttachmentSupport(clientVersion, extensions);
+ caps.renderbuffer = internalFormatInfo.renderbufferSupport(clientVersion, extensions);
+ caps.blendable = internalFormatInfo.blendSupport(clientVersion, extensions);
+
+ caps.sampleCounts.insert(0);
+ if (internalFormatInfo.isRequiredRenderbufferFormat(clientVersion))
+ {
+ if ((clientVersion.major >= 3 && clientVersion.minor >= 1) ||
+ (clientVersion.major >= 3 && !internalFormatInfo.isInt()))
+ {
+ caps.sampleCounts.insert(4);
+ }
+ }
+
+ return caps;
+}
+
+TextureCapsMap::TextureCapsMap() {}
+
+TextureCapsMap::~TextureCapsMap() {}
+
+void TextureCapsMap::insert(GLenum internalFormat, const TextureCaps &caps)
+{
+ angle::FormatID formatID = angle::Format::InternalFormatToID(internalFormat);
+ get(formatID) = caps;
+}
+
+void TextureCapsMap::clear()
+{
+ mFormatData.fill(TextureCaps());
+}
+
+const TextureCaps &TextureCapsMap::get(GLenum internalFormat) const
+{
+ angle::FormatID formatID = angle::Format::InternalFormatToID(internalFormat);
+ return get(formatID);
+}
+
+const TextureCaps &TextureCapsMap::get(angle::FormatID formatID) const
+{
+ return mFormatData[formatID];
+}
+
+TextureCaps &TextureCapsMap::get(angle::FormatID formatID)
+{
+ return mFormatData[formatID];
+}
+
+void TextureCapsMap::set(angle::FormatID formatID, const TextureCaps &caps)
+{
+ get(formatID) = caps;
+}
+
+void InitMinimumTextureCapsMap(const Version &clientVersion,
+ const Extensions &extensions,
+ TextureCapsMap *capsMap)
+{
+ for (GLenum internalFormat : GetAllSizedInternalFormats())
+ {
+ capsMap->insert(internalFormat,
+ GenerateMinimumTextureCaps(internalFormat, clientVersion, extensions));
+ }
+}
+
+Extensions::Extensions() = default;
+
+Extensions::Extensions(const Extensions &other) = default;
+
+Extensions &Extensions::operator=(const Extensions &other) = default;
+
+std::vector<std::string> Extensions::getStrings() const
+{
+ std::vector<std::string> extensionStrings;
+
+ for (const auto &extensionInfo : GetExtensionInfoMap())
+ {
+ if (this->*(extensionInfo.second.ExtensionsMember))
+ {
+ extensionStrings.push_back(extensionInfo.first);
+ }
+ }
+
+ return extensionStrings;
+}
+
+Limitations::Limitations() = default;
+Limitations::Limitations(const Limitations &other) = default;
+
+Limitations &Limitations::operator=(const Limitations &other) = default;
+
+static bool GetFormatSupportBase(const TextureCapsMap &textureCaps,
+ const GLenum *requiredFormats,
+ size_t requiredFormatsSize,
+ bool requiresTexturing,
+ bool requiresFiltering,
+ bool requiresAttachingTexture,
+ bool requiresRenderbufferSupport,
+ bool requiresBlending)
+{
+ for (size_t i = 0; i < requiredFormatsSize; i++)
+ {
+ const TextureCaps &cap = textureCaps.get(requiredFormats[i]);
+ if (requiresTexturing && !cap.texturable)
+ {
+ return false;
+ }
+
+ if (requiresFiltering && !cap.filterable)
+ {
+ return false;
+ }
+
+ if (requiresAttachingTexture && !cap.textureAttachment)
+ {
+ return false;
+ }
+
+ if (requiresRenderbufferSupport && !cap.renderbuffer)
+ {
+ return false;
+ }
+
+ if (requiresBlending && !cap.blendable)
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+template <size_t N>
+static bool GetFormatSupport(const TextureCapsMap &textureCaps,
+ const GLenum (&requiredFormats)[N],
+ bool requiresTexturing,
+ bool requiresFiltering,
+ bool requiresAttachingTexture,
+ bool requiresRenderbufferSupport,
+ bool requiresBlending)
+{
+ return GetFormatSupportBase(textureCaps, requiredFormats, N, requiresTexturing,
+ requiresFiltering, requiresAttachingTexture,
+ requiresRenderbufferSupport, requiresBlending);
+}
+
+// Check for GL_OES_packed_depth_stencil support
+static bool DeterminePackedDepthStencilSupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_DEPTH24_STENCIL8,
+ };
+
+ return GetFormatSupport(textureCaps, requiredFormats, false, false, true, true, false);
+}
+
+// Checks for GL_NV_read_depth support
+static bool DetermineReadDepthSupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_DEPTH_COMPONENT16,
+ };
+
+ return GetFormatSupport(textureCaps, requiredFormats, true, false, true, false, false);
+}
+
+// Checks for GL_NV_read_stencil support
+static bool DetermineReadStencilSupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_STENCIL_INDEX8,
+ };
+
+ return GetFormatSupport(textureCaps, requiredFormats, false, false, true, false, false);
+}
+
+// Checks for GL_NV_depth_buffer_float2 support
+static bool DetermineDepthBufferFloat2Support(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_DEPTH_COMPONENT32F,
+ GL_DEPTH32F_STENCIL8,
+ };
+
+ return GetFormatSupport(textureCaps, requiredFormats, true, false, true, false, false);
+}
+
+// Checks for GL_OES_rgb8_rgba8 support
+static bool DetermineRGB8AndRGBA8TextureSupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_RGB8,
+ GL_RGBA8,
+ };
+
+ return GetFormatSupport(textureCaps, requiredFormats, false, false, false, true, false);
+}
+
+// Checks for GL_EXT_texture_format_BGRA8888 support
+static bool DetermineBGRA8TextureSupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_BGRA8_EXT,
+ };
+
+ return GetFormatSupport(textureCaps, requiredFormats, true, true, true, true, false);
+}
+
+// Checks for GL_EXT_read_format_bgra support
+static bool DetermineBGRAReadFormatSupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_BGRA8_EXT,
+ // TODO(http://anglebug.com/4302): GL_EXT_read_format_bgra specifies 2 more types, which are
+ // currently ignored. The equivalent formats would be: GL_BGRA4_ANGLEX, GL_BGR5_A1_ANGLEX
+ };
+
+ return GetFormatSupport(textureCaps, requiredFormats, true, false, true, true, false);
+}
+
+// Checks for GL_OES_color_buffer_half_float support
+static bool DetermineColorBufferHalfFloatSupport(const TextureCapsMap &textureCaps)
+{
+ // EXT_color_buffer_half_float issue #2 states that an implementation doesn't need to support
+ // rendering to any of the formats but is expected to be able to render to at least one. WebGL
+ // requires that at least RGBA16F is renderable so we make the same requirement.
+ constexpr GLenum requiredFormats[] = {
+ GL_RGBA16F,
+ };
+
+ return GetFormatSupport(textureCaps, requiredFormats, false, false, true, true, false);
+}
+
+// Checks for GL_OES_texture_half_float support
+static bool DetermineHalfFloatTextureSupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_RGBA16F, GL_RGB16F, GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE16F_EXT, GL_ALPHA16F_EXT,
+ };
+
+ return GetFormatSupport(textureCaps, requiredFormats, true, false, false, false, false);
+}
+
+// Checks for GL_OES_texture_half_float_linear support
+static bool DetermineHalfFloatTextureFilteringSupport(const TextureCapsMap &textureCaps,
+ bool checkLegacyFormats)
+{
+ constexpr GLenum requiredFormats[] = {GL_RGBA16F, GL_RGB16F};
+ // If GL_OES_texture_half_float is present, this extension must also support legacy formats
+ // introduced by that extension
+ constexpr GLenum requiredFormatsES2[] = {GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE16F_EXT,
+ GL_ALPHA16F_EXT};
+
+ if (checkLegacyFormats &&
+ !GetFormatSupport(textureCaps, requiredFormatsES2, false, true, false, false, false))
+ {
+ return false;
+ }
+
+ return GetFormatSupport(textureCaps, requiredFormats, false, true, false, false, false);
+}
+
+// Checks for GL_OES_texture_float support
+static bool DetermineFloatTextureSupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_RGBA32F, GL_RGB32F, GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE32F_EXT, GL_ALPHA32F_EXT,
+ };
+
+ return GetFormatSupport(textureCaps, requiredFormats, true, false, false, false, false);
+}
+
+// Checks for GL_OES_texture_float_linear support
+static bool DetermineFloatTextureFilteringSupport(const TextureCapsMap &textureCaps,
+ bool checkLegacyFormats)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_RGBA32F,
+ GL_RGB32F,
+ };
+ // If GL_OES_texture_float is present, this extension must also support legacy formats
+ // introduced by that extension
+ constexpr GLenum requiredFormatsES2[] = {
+ GL_LUMINANCE_ALPHA32F_EXT,
+ GL_LUMINANCE32F_EXT,
+ GL_ALPHA32F_EXT,
+ };
+
+ if (checkLegacyFormats &&
+ !GetFormatSupport(textureCaps, requiredFormatsES2, false, true, false, false, false))
+ {
+ return false;
+ }
+
+ return GetFormatSupport(textureCaps, requiredFormats, false, true, false, false, false);
+}
+
+// Checks for GL_EXT_texture_rg support
+static bool DetermineRGTextureSupport(const TextureCapsMap &textureCaps,
+ bool checkHalfFloatFormats,
+ bool checkFloatFormats)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_R8,
+ GL_RG8,
+ };
+ constexpr GLenum requiredHalfFloatFormats[] = {
+ GL_R16F,
+ GL_RG16F,
+ };
+ constexpr GLenum requiredFloatFormats[] = {
+ GL_R32F,
+ GL_RG32F,
+ };
+
+ if (checkHalfFloatFormats &&
+ !GetFormatSupport(textureCaps, requiredHalfFloatFormats, true, false, false, false, false))
+ {
+ return false;
+ }
+
+ if (checkFloatFormats &&
+ !GetFormatSupport(textureCaps, requiredFloatFormats, true, false, false, false, false))
+ {
+ return false;
+ }
+
+ return GetFormatSupport(textureCaps, requiredFormats, true, true, true, true, false);
+}
+
+static bool DetermineTextureFormat2101010Support(const TextureCapsMap &textureCaps)
+{
+ // GL_EXT_texture_type_2_10_10_10_REV specifies both RGBA and RGB support whereas desktop GL
+ // only specifies RGBA support, so check both RGBA and RGB before marking as supported.
+ constexpr GLenum requiredFormats[] = {
+ GL_RGB10_A2,
+ GL_RGB10_UNORM_ANGLEX,
+ };
+
+ return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
+}
+
+// Check for GL_EXT_texture_compression_dxt1 support
+static bool DetermineDXT1TextureSupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
+ GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
+ };
+
+ return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
+}
+
+// Check for GL_ANGLE_texture_compression_dxt3 support
+static bool DetermineDXT3TextureSupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE,
+ };
+
+ return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
+}
+
+// Check for GL_ANGLE_texture_compression_dxt5 support
+static bool DetermineDXT5TextureSupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE,
+ };
+
+ return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
+}
+
+// Check for GL_EXT_texture_compression_s3tc_srgb support
+static bool DetermineS3TCsRGBTextureSupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_COMPRESSED_SRGB_S3TC_DXT1_EXT,
+ GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT,
+ GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT,
+ GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT,
+ };
+
+ return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
+}
+
+// Check for GL_KHR_texture_compression_astc_ldr support
+static bool DetermineASTCLDRTextureSupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_COMPRESSED_RGBA_ASTC_4x4_KHR, GL_COMPRESSED_RGBA_ASTC_5x4_KHR,
+ GL_COMPRESSED_RGBA_ASTC_5x5_KHR, GL_COMPRESSED_RGBA_ASTC_6x5_KHR,
+ GL_COMPRESSED_RGBA_ASTC_6x6_KHR, GL_COMPRESSED_RGBA_ASTC_8x5_KHR,
+ GL_COMPRESSED_RGBA_ASTC_8x6_KHR, GL_COMPRESSED_RGBA_ASTC_8x8_KHR,
+ GL_COMPRESSED_RGBA_ASTC_10x5_KHR, GL_COMPRESSED_RGBA_ASTC_10x6_KHR,
+ GL_COMPRESSED_RGBA_ASTC_10x8_KHR, GL_COMPRESSED_RGBA_ASTC_10x10_KHR,
+ GL_COMPRESSED_RGBA_ASTC_12x10_KHR, GL_COMPRESSED_RGBA_ASTC_12x12_KHR,
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR,
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR,
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR,
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR,
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR,
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR,
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR,
+ };
+
+ return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
+}
+
+// Check for GL_OES_texture_compression_astc support
+static bool DetermineASTCOESTExtureSupport(const TextureCapsMap &textureCaps)
+{
+ if (!DetermineASTCLDRTextureSupport(textureCaps))
+ {
+ return false;
+ }
+
+ // The OES version of the extension also requires the 3D ASTC formats
+ constexpr GLenum requiredFormats[] = {
+ GL_COMPRESSED_RGBA_ASTC_3x3x3_OES, GL_COMPRESSED_RGBA_ASTC_4x3x3_OES,
+ GL_COMPRESSED_RGBA_ASTC_4x4x3_OES, GL_COMPRESSED_RGBA_ASTC_4x4x4_OES,
+ GL_COMPRESSED_RGBA_ASTC_5x4x4_OES, GL_COMPRESSED_RGBA_ASTC_5x5x4_OES,
+ GL_COMPRESSED_RGBA_ASTC_5x5x5_OES, GL_COMPRESSED_RGBA_ASTC_6x5x5_OES,
+ GL_COMPRESSED_RGBA_ASTC_6x6x5_OES, GL_COMPRESSED_RGBA_ASTC_6x6x6_OES,
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES,
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES,
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES,
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES,
+ GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES,
+ };
+
+ return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
+}
+
+// Check for GL_ETC1_RGB8_OES support
+static bool DetermineETC1RGB8TextureSupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_ETC1_RGB8_OES,
+ };
+
+ return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
+}
+
+// Check for OES_compressed_ETC2_RGB8_texture support
+static bool DetermineETC2RGB8TextureSupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_COMPRESSED_RGB8_ETC2,
+ };
+
+ return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
+}
+
+// Check for OES_compressed_ETC2_sRGB8_texture support
+static bool DetermineETC2sRGB8TextureSupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_COMPRESSED_SRGB8_ETC2,
+ };
+
+ return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
+}
+
+// Check for OES_compressed_ETC2_punchthroughA_RGBA8_texture support
+static bool DetermineETC2PunchthroughARGB8TextureSupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,
+ };
+
+ return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
+}
+
+// Check for OES_compressed_ETC2_punchthroughA_sRGB8_alpha_texture support
+static bool DetermineETC2PunchthroughAsRGB8AlphaTextureSupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,
+ };
+
+ return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
+}
+
+// Check for OES_compressed_ETC2_RGBA8_texture support
+static bool DetermineETC2RGBA8TextureSupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_COMPRESSED_RGBA8_ETC2_EAC,
+ };
+
+ return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
+}
+
+// Check for OES_compressed_ETC2_sRGB8_alpha8_texture support
+static bool DetermineETC2sRGB8Alpha8TextureSupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,
+ };
+
+ return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
+}
+
+// Check for OES_compressed_EAC_R11_unsigned_texture support
+static bool DetermineEACR11UnsignedTextureSupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_COMPRESSED_R11_EAC,
+ };
+
+ return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
+}
+
+// Check for OES_compressed_EAC_R11_signed_texture support
+static bool DetermineEACR11SignedTextureSupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_COMPRESSED_SIGNED_R11_EAC,
+ };
+
+ return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
+}
+
+// Check for OES_compressed_EAC_RG11_unsigned_texture support
+static bool DetermineEACRG11UnsignedTextureSupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_COMPRESSED_RG11_EAC,
+ };
+
+ return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
+}
+
+// Check for OES_compressed_EAC_RG11_signed_texture support
+static bool DetermineEACRG11SignedTextureSupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_COMPRESSED_SIGNED_RG11_EAC,
+ };
+
+ return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
+}
+
+// Check for GL_EXT_sRGB support
+static bool DetermineSRGBTextureSupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFilterFormats[] = {
+ GL_SRGB8,
+ GL_SRGB8_ALPHA8,
+ };
+
+ constexpr GLenum requiredRenderFormats[] = {
+ GL_SRGB8_ALPHA8,
+ };
+
+ return GetFormatSupport(textureCaps, requiredFilterFormats, true, true, false, false, false) &&
+ GetFormatSupport(textureCaps, requiredRenderFormats, true, false, true, true, false);
+}
+
+// Check for GL_EXT_texture_sRGB_R8 support
+static bool DetermineSRGBR8TextureSupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFilterFormats[] = {GL_SR8_EXT};
+
+ return GetFormatSupport(textureCaps, requiredFilterFormats, true, true, false, false, false);
+}
+
+// Check for GL_EXT_texture_sRGB_RG8 support
+static bool DetermineSRGBRG8TextureSupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFilterFormats[] = {GL_SRG8_EXT};
+
+ return GetFormatSupport(textureCaps, requiredFilterFormats, true, true, false, false, false);
+}
+
+// Check for GL_ANGLE_depth_texture support
+static bool DetermineDepthTextureANGLESupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_DEPTH_COMPONENT16,
+#if !defined(ANGLE_PLATFORM_IOS) && \
+ (!defined(ANGLE_PLATFORM_MACCATALYST) || !defined(ANGLE_CPU_ARM64))
+ // anglebug.com/6082
+ // TODO(dino): Temporarily Removing the need for GL_DEPTH_COMPONENT32_OES
+ // because it is not supported on iOS.
+ // TODO(dino): I think this needs to be a runtime check when running an iOS app on Mac.
+ GL_DEPTH_COMPONENT32_OES,
+#endif
+ GL_DEPTH24_STENCIL8_OES,
+ };
+
+ return GetFormatSupport(textureCaps, requiredFormats, true, false, true, false, false);
+}
+
+// Check for GL_OES_depth_texture support
+static bool DetermineDepthTextureOESSupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_DEPTH_COMPONENT16,
+#if !defined(ANGLE_PLATFORM_IOS) && \
+ (!defined(ANGLE_PLATFORM_MACCATALYST) || !defined(ANGLE_CPU_ARM64))
+ // anglebug.com/6082
+ // TODO(dino): Temporarily Removing the need for GL_DEPTH_COMPONENT32_OES
+ // because it is not supported on iOS.
+ // TODO(dino): I think this needs to be a runtime check when running an iOS app on Mac.
+ GL_DEPTH_COMPONENT32_OES,
+#endif
+ };
+
+ return GetFormatSupport(textureCaps, requiredFormats, true, false, true, true, false);
+}
+
+// Check for GL_OES_depth24
+static bool DetermineDepth24OESSupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_DEPTH_COMPONENT24_OES,
+ };
+
+ return GetFormatSupport(textureCaps, requiredFormats, false, false, false, true, false);
+}
+
+// Check for GL_OES_depth32 support
+static bool DetermineDepth32Support(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_DEPTH_COMPONENT32_OES,
+ };
+
+ return GetFormatSupport(textureCaps, requiredFormats, false, false, true, true, false);
+}
+
+// Check for GL_CHROMIUM_color_buffer_float_rgb support
+static bool DetermineColorBufferFloatRGBSupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_RGB32F,
+ };
+
+ return GetFormatSupport(textureCaps, requiredFormats, true, false, true, false, false);
+}
+
+// Check for GL_CHROMIUM_color_buffer_float_rgba support
+static bool DetermineColorBufferFloatRGBASupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_RGBA32F,
+ };
+
+ return GetFormatSupport(textureCaps, requiredFormats, true, false, true, true, false);
+}
+
+// Check for GL_EXT_color_buffer_float support
+static bool DetermineColorBufferFloatSupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum nonBlendableFormats[] = {
+ GL_R32F,
+ GL_RG32F,
+ GL_RGBA32F,
+ };
+
+ constexpr GLenum blendableFormats[] = {
+ GL_R16F,
+ GL_RG16F,
+ GL_RGBA16F,
+ GL_R11F_G11F_B10F,
+ };
+
+ return GetFormatSupport(textureCaps, nonBlendableFormats, true, false, true, true, false) &&
+ GetFormatSupport(textureCaps, blendableFormats, true, false, true, true, true);
+}
+
+// Check for GL_EXT_float_blend support
+static bool DetermineFloatBlendSupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_R32F,
+ GL_RG32F,
+ GL_RGBA32F,
+ };
+
+ return GetFormatSupport(textureCaps, requiredFormats, true, false, true, true, true);
+}
+
+// Check for GL_EXT_texture_norm16 support
+static bool DetermineTextureNorm16Support(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFilterFormats[] = {
+ GL_R16_EXT, GL_RG16_EXT, GL_RGB16_EXT, GL_RGBA16_EXT,
+ GL_R16_SNORM_EXT, GL_RG16_SNORM_EXT, GL_RGB16_SNORM_EXT, GL_RGBA16_SNORM_EXT,
+ };
+
+ constexpr GLenum requiredRenderFormats[] = {
+ GL_R16_EXT,
+ GL_RG16_EXT,
+ GL_RGBA16_EXT,
+ };
+
+ return GetFormatSupport(textureCaps, requiredFilterFormats, true, true, false, false, false) &&
+ GetFormatSupport(textureCaps, requiredRenderFormats, true, false, true, true, false);
+}
+
+// Check for EXT_texture_compression_rgtc support
+static bool DetermineRGTCTextureSupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_COMPRESSED_RED_RGTC1_EXT, GL_COMPRESSED_SIGNED_RED_RGTC1_EXT,
+ GL_COMPRESSED_RED_GREEN_RGTC2_EXT, GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT};
+
+ return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
+}
+
+// Check for EXT_texture_compression_bptc support
+static bool DetermineBPTCTextureSupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT,
+ GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT};
+
+ return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
+}
+
+// Check for GL_IMG_texture_compression_pvrtc support
+static bool DeterminePVRTCTextureSupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG, GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG,
+ GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG};
+
+ return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
+}
+
+// Check for GL_EXT_pvrtc_sRGB support
+static bool DeterminePVRTCsRGBTextureSupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT, GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT,
+ GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT, GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT};
+
+ return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
+}
+
+bool DetermineCompressedTextureETCSupport(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {GL_COMPRESSED_R11_EAC,
+ GL_COMPRESSED_SIGNED_R11_EAC,
+ GL_COMPRESSED_RG11_EAC,
+ GL_COMPRESSED_SIGNED_RG11_EAC,
+ GL_COMPRESSED_RGB8_ETC2,
+ GL_COMPRESSED_SRGB8_ETC2,
+ GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,
+ GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,
+ GL_COMPRESSED_RGBA8_ETC2_EAC,
+ GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC};
+
+ return GetFormatSupport(textureCaps, requiredFormats, true, true, false, false, false);
+}
+
+// Checks for GL_OES_texture_stencil8 support
+static bool DetermineStencilIndex8Support(const TextureCapsMap &textureCaps)
+{
+ constexpr GLenum requiredFormats[] = {
+ GL_STENCIL_INDEX8,
+ };
+
+ return GetFormatSupport(textureCaps, requiredFormats, false, false, true, false, false);
+}
+
+void Extensions::setTextureExtensionSupport(const TextureCapsMap &textureCaps)
+{
+ // TODO(ynovikov): rgb8Rgba8OES, colorBufferHalfFloatEXT, textureHalfFloatOES,
+ // textureHalfFloatLinearOES, textureFloatOES, textureFloatLinearOES, textureRgEXT, sRGB,
+ // colorBufferFloatRgbCHROMIUM, colorBufferFloatRgbaCHROMIUM and colorBufferFloatEXT were
+ // verified. Verify the rest.
+ packedDepthStencilOES = DeterminePackedDepthStencilSupport(textureCaps);
+ rgb8Rgba8OES = DetermineRGB8AndRGBA8TextureSupport(textureCaps);
+ readDepthNV = DetermineReadDepthSupport(textureCaps);
+ readStencilNV = DetermineReadStencilSupport(textureCaps);
+ depthBufferFloat2NV = DetermineDepthBufferFloat2Support(textureCaps);
+ textureFormatBGRA8888EXT = DetermineBGRA8TextureSupport(textureCaps);
+ readFormatBgraEXT = DetermineBGRAReadFormatSupport(textureCaps);
+ textureHalfFloatOES = DetermineHalfFloatTextureSupport(textureCaps);
+ textureHalfFloatLinearOES =
+ DetermineHalfFloatTextureFilteringSupport(textureCaps, textureHalfFloatOES);
+ textureFloatOES = DetermineFloatTextureSupport(textureCaps);
+ textureFloatLinearOES = DetermineFloatTextureFilteringSupport(textureCaps, textureFloatOES);
+ textureRgEXT = DetermineRGTextureSupport(textureCaps, textureHalfFloatOES, textureFloatOES);
+ colorBufferHalfFloatEXT =
+ textureHalfFloatOES && DetermineColorBufferHalfFloatSupport(textureCaps);
+ textureType2101010REVEXT = DetermineTextureFormat2101010Support(textureCaps);
+ textureCompressionDxt1EXT = DetermineDXT1TextureSupport(textureCaps);
+ textureCompressionDxt3ANGLE = DetermineDXT3TextureSupport(textureCaps);
+ textureCompressionDxt5ANGLE = DetermineDXT5TextureSupport(textureCaps);
+ textureCompressionS3tcSrgbEXT = DetermineS3TCsRGBTextureSupport(textureCaps);
+ textureCompressionAstcLdrKHR = DetermineASTCLDRTextureSupport(textureCaps);
+ textureCompressionAstcOES = DetermineASTCOESTExtureSupport(textureCaps);
+ compressedETC1RGB8TextureOES = DetermineETC1RGB8TextureSupport(textureCaps);
+ compressedETC2RGB8TextureOES = DetermineETC2RGB8TextureSupport(textureCaps);
+ compressedETC2SRGB8TextureOES = DetermineETC2sRGB8TextureSupport(textureCaps);
+ compressedETC2PunchthroughARGBA8TextureOES =
+ DetermineETC2PunchthroughARGB8TextureSupport(textureCaps);
+ compressedETC2PunchthroughASRGB8AlphaTextureOES =
+ DetermineETC2PunchthroughAsRGB8AlphaTextureSupport(textureCaps);
+ compressedETC2RGBA8TextureOES = DetermineETC2RGBA8TextureSupport(textureCaps);
+ compressedETC2SRGB8Alpha8TextureOES = DetermineETC2sRGB8Alpha8TextureSupport(textureCaps);
+ compressedEACR11UnsignedTextureOES = DetermineEACR11UnsignedTextureSupport(textureCaps);
+ compressedEACR11SignedTextureOES = DetermineEACR11SignedTextureSupport(textureCaps);
+ compressedEACRG11UnsignedTextureOES = DetermineEACRG11UnsignedTextureSupport(textureCaps);
+ compressedEACRG11SignedTextureOES = DetermineEACRG11SignedTextureSupport(textureCaps);
+ sRGBEXT = DetermineSRGBTextureSupport(textureCaps);
+ textureSRGBR8EXT = DetermineSRGBR8TextureSupport(textureCaps);
+ textureSRGBRG8EXT = DetermineSRGBRG8TextureSupport(textureCaps);
+ depthTextureANGLE = DetermineDepthTextureANGLESupport(textureCaps);
+ depthTextureOES = DetermineDepthTextureOESSupport(textureCaps);
+ depth24OES = DetermineDepth24OESSupport(textureCaps);
+ depth32OES = DetermineDepth32Support(textureCaps);
+ colorBufferFloatRgbCHROMIUM = DetermineColorBufferFloatRGBSupport(textureCaps);
+ colorBufferFloatRgbaCHROMIUM = DetermineColorBufferFloatRGBASupport(textureCaps);
+ colorBufferFloatEXT = DetermineColorBufferFloatSupport(textureCaps);
+ floatBlendEXT = DetermineFloatBlendSupport(textureCaps);
+ textureNorm16EXT = DetermineTextureNorm16Support(textureCaps);
+ textureCompressionRgtcEXT = DetermineRGTCTextureSupport(textureCaps);
+ textureCompressionBptcEXT = DetermineBPTCTextureSupport(textureCaps);
+ textureCompressionPvrtcIMG = DeterminePVRTCTextureSupport(textureCaps);
+ pvrtcSRGBEXT = DeterminePVRTCsRGBTextureSupport(textureCaps);
+ textureStencil8OES = DetermineStencilIndex8Support(textureCaps);
+}
+
+TypePrecision::TypePrecision() = default;
+
+TypePrecision::TypePrecision(const TypePrecision &other) = default;
+
+TypePrecision &TypePrecision::operator=(const TypePrecision &other) = default;
+
+void TypePrecision::setIEEEFloat()
+{
+ range = {{127, 127}};
+ precision = 23;
+}
+
+void TypePrecision::setIEEEHalfFloat()
+{
+ range = {{15, 15}};
+ precision = 10;
+}
+
+void TypePrecision::setTwosComplementInt(unsigned int bits)
+{
+ range = {{static_cast<GLint>(bits) - 1, static_cast<GLint>(bits) - 2}};
+ precision = 0;
+}
+
+void TypePrecision::setSimulatedFloat(unsigned int r, unsigned int p)
+{
+ range = {{static_cast<GLint>(r), static_cast<GLint>(r)}};
+ precision = static_cast<GLint>(p);
+}
+
+void TypePrecision::setSimulatedInt(unsigned int r)
+{
+ range = {{static_cast<GLint>(r), static_cast<GLint>(r)}};
+ precision = 0;
+}
+
+void TypePrecision::get(GLint *returnRange, GLint *returnPrecision) const
+{
+ std::copy(range.begin(), range.end(), returnRange);
+ *returnPrecision = precision;
+}
+
+Caps::Caps() = default;
+Caps::Caps(const Caps &other) = default;
+Caps::~Caps() = default;
+Caps &Caps::operator=(const Caps &other) = default;
+
+Caps GenerateMinimumCaps(const Version &clientVersion, const Extensions &extensions)
+{
+ Caps caps;
+
+ // GLES1 emulation (Minimums taken from Table 6.20 / 6.22 (ES 1.1 spec))
+ if (clientVersion < Version(2, 0))
+ {
+ caps.maxMultitextureUnits = 2;
+ caps.maxLights = 8;
+ caps.maxClipPlanes = 1;
+
+ caps.maxModelviewMatrixStackDepth = 16;
+ caps.maxProjectionMatrixStackDepth = 2;
+ caps.maxTextureMatrixStackDepth = 2;
+
+ caps.minSmoothPointSize = 1.0f;
+ caps.maxSmoothPointSize = 1.0f;
+ }
+
+ if (clientVersion >= Version(2, 0))
+ {
+ // Table 6.18
+ caps.max2DTextureSize = 64;
+ caps.maxCubeMapTextureSize = 16;
+ caps.maxViewportWidth = caps.max2DTextureSize;
+ caps.maxViewportHeight = caps.max2DTextureSize;
+ caps.minAliasedPointSize = 1;
+ caps.maxAliasedPointSize = 1;
+ caps.minAliasedLineWidth = 1;
+ caps.maxAliasedLineWidth = 1;
+
+ // Table 6.19
+ caps.vertexHighpFloat.setSimulatedFloat(62, 16);
+ caps.vertexMediumpFloat.setSimulatedFloat(14, 10);
+ caps.vertexLowpFloat.setSimulatedFloat(1, 8);
+ caps.vertexHighpInt.setSimulatedInt(16);
+ caps.vertexMediumpInt.setSimulatedInt(10);
+ caps.vertexLowpInt.setSimulatedInt(8);
+ caps.fragmentHighpFloat.setSimulatedFloat(62, 16);
+ caps.fragmentMediumpFloat.setSimulatedFloat(14, 10);
+ caps.fragmentLowpFloat.setSimulatedFloat(1, 8);
+ caps.fragmentHighpInt.setSimulatedInt(16);
+ caps.fragmentMediumpInt.setSimulatedInt(10);
+ caps.fragmentLowpInt.setSimulatedInt(8);
+
+ // Table 6.20
+ caps.maxVertexAttributes = 8;
+ caps.maxVertexUniformVectors = 128;
+ caps.maxVaryingVectors = 8;
+ caps.maxCombinedTextureImageUnits = 8;
+ caps.maxShaderTextureImageUnits[ShaderType::Fragment] = 8;
+ caps.maxFragmentUniformVectors = 16;
+ caps.maxRenderbufferSize = 1;
+
+ // Table 3.35
+ caps.maxSamples = 4;
+ }
+
+ if (clientVersion >= Version(3, 0))
+ {
+ // Table 6.28
+ caps.maxElementIndex = (1 << 24) - 1;
+ caps.max3DTextureSize = 256;
+ caps.max2DTextureSize = 2048;
+ caps.maxArrayTextureLayers = 256;
+ caps.maxLODBias = 2.0f;
+ caps.maxCubeMapTextureSize = 2048;
+ caps.maxRenderbufferSize = 2048;
+ caps.maxDrawBuffers = 4;
+ caps.maxColorAttachments = 4;
+ caps.maxViewportWidth = caps.max2DTextureSize;
+ caps.maxViewportHeight = caps.max2DTextureSize;
+
+ // Table 6.29
+ caps.compressedTextureFormats.push_back(GL_COMPRESSED_R11_EAC);
+ caps.compressedTextureFormats.push_back(GL_COMPRESSED_SIGNED_R11_EAC);
+ caps.compressedTextureFormats.push_back(GL_COMPRESSED_RG11_EAC);
+ caps.compressedTextureFormats.push_back(GL_COMPRESSED_SIGNED_RG11_EAC);
+ caps.compressedTextureFormats.push_back(GL_COMPRESSED_RGB8_ETC2);
+ caps.compressedTextureFormats.push_back(GL_COMPRESSED_SRGB8_ETC2);
+ caps.compressedTextureFormats.push_back(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2);
+ caps.compressedTextureFormats.push_back(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2);
+ caps.compressedTextureFormats.push_back(GL_COMPRESSED_RGBA8_ETC2_EAC);
+ caps.compressedTextureFormats.push_back(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC);
+ caps.vertexHighpFloat.setIEEEFloat();
+ caps.vertexHighpInt.setTwosComplementInt(32);
+ caps.vertexMediumpInt.setTwosComplementInt(16);
+ caps.vertexLowpInt.setTwosComplementInt(8);
+ caps.fragmentHighpFloat.setIEEEFloat();
+ caps.fragmentHighpInt.setSimulatedInt(32);
+ caps.fragmentMediumpInt.setTwosComplementInt(16);
+ caps.fragmentLowpInt.setTwosComplementInt(8);
+ caps.maxServerWaitTimeout = 0;
+
+ // Table 6.31
+ caps.maxVertexAttributes = 16;
+ caps.maxShaderUniformComponents[ShaderType::Vertex] = 1024;
+ caps.maxVertexUniformVectors = 256;
+ caps.maxShaderUniformBlocks[ShaderType::Vertex] = limits::kMinimumShaderUniformBlocks;
+ caps.maxVertexOutputComponents = limits::kMinimumVertexOutputComponents;
+ caps.maxShaderTextureImageUnits[ShaderType::Vertex] = 16;
+
+ // Table 6.32
+ caps.maxShaderUniformComponents[ShaderType::Fragment] = 896;
+ caps.maxFragmentUniformVectors = 224;
+ caps.maxShaderUniformBlocks[ShaderType::Fragment] = limits::kMinimumShaderUniformBlocks;
+ caps.maxFragmentInputComponents = 60;
+ caps.maxShaderTextureImageUnits[ShaderType::Fragment] = 16;
+ caps.minProgramTexelOffset = -8;
+ caps.maxProgramTexelOffset = 7;
+
+ // Table 6.33
+ caps.maxUniformBufferBindings = 24;
+ caps.maxUniformBlockSize = 16384;
+ caps.uniformBufferOffsetAlignment = 256;
+ caps.maxCombinedUniformBlocks = 24;
+ caps.maxVaryingComponents = 60;
+ caps.maxVaryingVectors = 15;
+ caps.maxCombinedTextureImageUnits = 32;
+
+ // Table 6.34
+ caps.maxTransformFeedbackInterleavedComponents = 64;
+ caps.maxTransformFeedbackSeparateAttributes = 4;
+ caps.maxTransformFeedbackSeparateComponents = 4;
+ }
+
+ if (clientVersion >= Version(3, 1))
+ {
+ // Table 20.40
+ caps.maxFramebufferWidth = 2048;
+ caps.maxFramebufferHeight = 2048;
+ caps.maxFramebufferSamples = 4;
+ caps.maxSampleMaskWords = 1;
+ caps.maxColorTextureSamples = 1;
+ caps.maxDepthTextureSamples = 1;
+ caps.maxIntegerSamples = 1;
+
+ // Table 20.41
+ caps.maxVertexAttribRelativeOffset = 2047;
+ caps.maxVertexAttribBindings = 16;
+ caps.maxVertexAttribStride = 2048;
+
+ // Table 20.43
+ caps.maxShaderAtomicCounterBuffers[ShaderType::Vertex] = 0;
+ caps.maxShaderAtomicCounters[ShaderType::Vertex] = 0;
+ caps.maxShaderImageUniforms[ShaderType::Vertex] = 0;
+ caps.maxShaderStorageBlocks[ShaderType::Vertex] = 0;
+
+ // Table 20.44
+ caps.maxShaderUniformComponents[ShaderType::Fragment] = 1024;
+ caps.maxFragmentUniformVectors = 256;
+ caps.maxShaderAtomicCounterBuffers[ShaderType::Fragment] = 0;
+ caps.maxShaderAtomicCounters[ShaderType::Fragment] = 0;
+ caps.maxShaderImageUniforms[ShaderType::Fragment] = 0;
+ caps.maxShaderStorageBlocks[ShaderType::Fragment] = 0;
+ caps.minProgramTextureGatherOffset = 0;
+ caps.maxProgramTextureGatherOffset = 0;
+
+ // Table 20.45
+ caps.maxComputeWorkGroupCount = {{65535, 65535, 65535}};
+ caps.maxComputeWorkGroupSize = {{128, 128, 64}};
+ caps.maxComputeWorkGroupInvocations = 12;
+ caps.maxShaderUniformBlocks[ShaderType::Compute] = limits::kMinimumShaderUniformBlocks;
+ caps.maxShaderTextureImageUnits[ShaderType::Compute] = 16;
+ caps.maxComputeSharedMemorySize = 16384;
+ caps.maxShaderUniformComponents[ShaderType::Compute] = 1024;
+ caps.maxShaderAtomicCounterBuffers[ShaderType::Compute] = 1;
+ caps.maxShaderAtomicCounters[ShaderType::Compute] = 8;
+ caps.maxShaderImageUniforms[ShaderType::Compute] = 4;
+ caps.maxShaderStorageBlocks[ShaderType::Compute] = 4;
+
+ // Table 20.46
+ caps.maxUniformBufferBindings = 36;
+ caps.maxCombinedTextureImageUnits = 48;
+ caps.maxCombinedShaderOutputResources = 4;
+
+ // Table 20.47
+ caps.maxUniformLocations = 1024;
+ caps.maxAtomicCounterBufferBindings = 1;
+ caps.maxAtomicCounterBufferSize = 32;
+ caps.maxCombinedAtomicCounterBuffers = 1;
+ caps.maxCombinedAtomicCounters = 8;
+ caps.maxImageUnits = 4;
+ caps.maxCombinedImageUniforms = 4;
+ caps.maxShaderStorageBufferBindings = 4;
+ caps.maxShaderStorageBlockSize = 1 << 27;
+ caps.maxCombinedShaderStorageBlocks = 4;
+ caps.shaderStorageBufferOffsetAlignment = 256;
+ }
+
+ if (extensions.textureRectangleANGLE)
+ {
+ caps.maxRectangleTextureSize = 64;
+ }
+
+ if (extensions.geometryShaderAny())
+ {
+ // Table 20.40 (GL_EXT_geometry_shader)
+ caps.maxFramebufferLayers = 256;
+ caps.layerProvokingVertex = GL_LAST_VERTEX_CONVENTION_EXT;
+
+ // Table 20.43gs (GL_EXT_geometry_shader)
+ caps.maxShaderUniformComponents[ShaderType::Geometry] = 1024;
+ caps.maxShaderUniformBlocks[ShaderType::Geometry] = limits::kMinimumShaderUniformBlocks;
+ caps.maxGeometryInputComponents = 64;
+ caps.maxGeometryOutputComponents = 64;
+ caps.maxGeometryOutputVertices = 256;
+ caps.maxGeometryTotalOutputComponents = 1024;
+ caps.maxShaderTextureImageUnits[ShaderType::Geometry] = 16;
+ caps.maxShaderAtomicCounterBuffers[ShaderType::Geometry] = 0;
+ caps.maxShaderAtomicCounters[ShaderType::Geometry] = 0;
+ caps.maxShaderStorageBlocks[ShaderType::Geometry] = 0;
+ caps.maxGeometryShaderInvocations = 32;
+
+ // Table 20.46 (GL_EXT_geometry_shader)
+ caps.maxShaderImageUniforms[ShaderType::Geometry] = 0;
+
+ // Table 20.46 (GL_EXT_geometry_shader)
+ caps.maxUniformBufferBindings = 48;
+ caps.maxCombinedUniformBlocks = 36;
+ caps.maxCombinedTextureImageUnits = 64;
+ }
+
+ if (extensions.tessellationShaderEXT)
+ {
+ // Table 20.43 "Implementation Dependent Tessellation Shader Limits"
+ caps.maxTessControlInputComponents = 64;
+ caps.maxTessControlOutputComponents = 64;
+ caps.maxShaderTextureImageUnits[ShaderType::TessControl] = 16;
+ caps.maxShaderUniformComponents[ShaderType::TessControl] = 1024;
+ caps.maxTessControlTotalOutputComponents = 2048;
+ caps.maxShaderImageUniforms[ShaderType::TessControl] = 0;
+ caps.maxShaderAtomicCounters[ShaderType::TessControl] = 0;
+ caps.maxShaderAtomicCounterBuffers[ShaderType::TessControl] = 0;
+
+ caps.maxTessPatchComponents = 120;
+ caps.maxPatchVertices = 32;
+ caps.maxTessGenLevel = 64;
+
+ caps.maxTessEvaluationInputComponents = 64;
+ caps.maxTessEvaluationOutputComponents = 64;
+ caps.maxShaderTextureImageUnits[ShaderType::TessEvaluation] = 16;
+ caps.maxShaderUniformComponents[ShaderType::TessEvaluation] = 1024;
+ caps.maxShaderImageUniforms[ShaderType::TessEvaluation] = 0;
+ caps.maxShaderAtomicCounters[ShaderType::TessEvaluation] = 0;
+ caps.maxShaderAtomicCounterBuffers[ShaderType::TessEvaluation] = 0;
+
+ // Table 20.46 "Implementation Dependent Aggregate Shader Limits"
+ caps.maxUniformBufferBindings = 72;
+ caps.maxCombinedUniformBlocks = 60;
+ caps.maxCombinedTextureImageUnits = 96;
+ }
+
+ for (ShaderType shaderType : AllShaderTypes())
+ {
+ caps.maxCombinedShaderUniformComponents[shaderType] =
+ caps.maxShaderUniformBlocks[shaderType] *
+ static_cast<GLuint>(caps.maxUniformBlockSize / 4) +
+ caps.maxShaderUniformComponents[shaderType];
+ }
+
+ return caps;
+}
+} // namespace gl
+
+namespace egl
+{
+
+Caps::Caps() = default;
+
+DisplayExtensions::DisplayExtensions() = default;
+
+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_d3d_texture_client_buffer", d3dTextureClientBuffer, &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_ANGLE_windows_ui_composition", windowsUIComposition, &extensionStrings);
+ InsertExtensionString("EGL_NV_post_sub_buffer", postSubBuffer, &extensionStrings);
+ InsertExtensionString("EGL_KHR_create_context", createContext, &extensionStrings);
+ InsertExtensionString("EGL_KHR_image", image, &extensionStrings);
+ InsertExtensionString("EGL_KHR_image_base", imageBase, &extensionStrings);
+ InsertExtensionString("EGL_KHR_image_pixmap", imagePixmap, &extensionStrings);
+ InsertExtensionString("EGL_EXT_image_gl_colorspace", imageGlColorspace, &extensionStrings);
+ InsertExtensionString("EGL_KHR_gl_colorspace", glColorspace, &extensionStrings);
+ InsertExtensionString("EGL_EXT_gl_colorspace_scrgb", glColorspaceScrgb, &extensionStrings);
+ InsertExtensionString("EGL_EXT_gl_colorspace_scrgb_linear", glColorspaceScrgbLinear, &extensionStrings);
+ InsertExtensionString("EGL_EXT_gl_colorspace_display_p3", glColorspaceDisplayP3, &extensionStrings);
+ InsertExtensionString("EGL_EXT_gl_colorspace_display_p3_linear", glColorspaceDisplayP3Linear, &extensionStrings);
+ InsertExtensionString("EGL_EXT_gl_colorspace_display_p3_passthrough", glColorspaceDisplayP3Passthrough, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_colorspace_attribute_passthrough", eglColorspaceAttributePassthroughANGLE, &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_KHR_fence_sync", fenceSync, &extensionStrings);
+ InsertExtensionString("EGL_KHR_wait_sync", waitSync, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_stream_producer_d3d_texture", streamProducerD3DTexture, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_create_context_webgl_compatibility", createContextWebGLCompatibility, &extensionStrings);
+ InsertExtensionString("EGL_CHROMIUM_create_context_bind_generates_resource", createContextBindGeneratesResource, &extensionStrings);
+ InsertExtensionString("EGL_CHROMIUM_sync_control", syncControlCHROMIUM, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_sync_control_rate", syncControlRateANGLE, &extensionStrings);
+ InsertExtensionString("EGL_KHR_swap_buffers_with_damage", swapBuffersWithDamage, &extensionStrings);
+ InsertExtensionString("EGL_EXT_pixel_format_float", pixelFormatFloat, &extensionStrings);
+ InsertExtensionString("EGL_KHR_surfaceless_context", surfacelessContext, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_display_texture_share_group", displayTextureShareGroup, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_display_semaphore_share_group", displaySemaphoreShareGroup, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_create_context_client_arrays", createContextClientArrays, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_program_cache_control", programCacheControlANGLE, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_robust_resource_initialization", robustResourceInitializationANGLE, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_iosurface_client_buffer", iosurfaceClientBuffer, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_metal_texture_client_buffer", mtlTextureClientBuffer, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_create_context_extensions_enabled", createContextExtensionsEnabled, &extensionStrings);
+ InsertExtensionString("EGL_ANDROID_presentation_time", presentationTime, &extensionStrings);
+ InsertExtensionString("EGL_ANDROID_blob_cache", blobCache, &extensionStrings);
+ InsertExtensionString("EGL_ANDROID_framebuffer_target", framebufferTargetANDROID, &extensionStrings);
+ InsertExtensionString("EGL_ANDROID_image_native_buffer", imageNativeBuffer, &extensionStrings);
+ InsertExtensionString("EGL_ANDROID_get_frame_timestamps", getFrameTimestamps, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_timestamp_surface_attribute", timestampSurfaceAttributeANGLE, &extensionStrings);
+ InsertExtensionString("EGL_ANDROID_recordable", recordable, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_power_preference", powerPreference, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_image_d3d11_texture", imageD3D11Texture, &extensionStrings);
+ InsertExtensionString("EGL_ANDROID_create_native_client_buffer", createNativeClientBufferANDROID, &extensionStrings);
+ InsertExtensionString("EGL_ANDROID_get_native_client_buffer", getNativeClientBufferANDROID, &extensionStrings);
+ InsertExtensionString("EGL_ANDROID_native_fence_sync", nativeFenceSyncANDROID, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_create_context_backwards_compatible", createContextBackwardsCompatible, &extensionStrings);
+ InsertExtensionString("EGL_KHR_no_config_context", noConfigContext, &extensionStrings);
+ InsertExtensionString("EGL_IMG_context_priority", contextPriority, &extensionStrings);
+ InsertExtensionString("EGL_KHR_create_context_no_error", createContextNoError, &extensionStrings);
+ InsertExtensionString("EGL_EXT_image_dma_buf_import", imageDmaBufImportEXT, &extensionStrings);
+ InsertExtensionString("EGL_EXT_image_dma_buf_import_modifiers", imageDmaBufImportModifiersEXT, &extensionStrings);
+ InsertExtensionString("EGL_NOK_texture_from_pixmap", textureFromPixmapNOK, &extensionStrings);
+ InsertExtensionString("EGL_NV_robustness_video_memory_purge", robustnessVideoMemoryPurgeNV, &extensionStrings);
+ InsertExtensionString("EGL_KHR_reusable_sync", reusableSyncKHR, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_external_context_and_surface", externalContextAndSurface, &extensionStrings);
+ InsertExtensionString("EGL_EXT_buffer_age", bufferAgeEXT, &extensionStrings);
+ InsertExtensionString("EGL_KHR_mutable_render_buffer", mutableRenderBufferKHR, &extensionStrings);
+ InsertExtensionString("EGL_EXT_protected_content", protectedContentEXT, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_create_surface_swap_interval", createSurfaceSwapIntervalANGLE, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_context_virtualization", contextVirtualizationANGLE, &extensionStrings);
+ InsertExtensionString("EGL_KHR_lock_surface3", lockSurface3KHR, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_vulkan_image", vulkanImageANGLE, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_metal_create_context_ownership_identity", metalCreateContextOwnershipIdentityANGLE, &extensionStrings);
+ InsertExtensionString("EGL_KHR_partial_update", partialUpdateKHR, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_metal_shared_event_sync", mtlSyncSharedEventANGLE, &extensionStrings);
+ // clang-format on
+
+ return extensionStrings;
+}
+
+DeviceExtensions::DeviceExtensions() = default;
+
+std::vector<std::string> DeviceExtensions::getStrings() const
+{
+ std::vector<std::string> extensionStrings;
+
+ // clang-format off
+ // | Extension name | Supported flag | Output vector |
+ InsertExtensionString("EGL_ANGLE_device_d3d", deviceD3D, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_device_cgl", deviceCGL, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_device_eagl", deviceEAGL, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_device_metal", deviceMetal, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_device_vulkan", deviceVulkan, &extensionStrings);
+
+ // clang-format on
+
+ return extensionStrings;
+}
+
+ClientExtensions::ClientExtensions() = default;
+ClientExtensions::ClientExtensions(const ClientExtensions &other) = default;
+
+std::vector<std::string> ClientExtensions::getStrings() const
+{
+ std::vector<std::string> extensionStrings;
+
+ // clang-format off
+ // | Extension name | Supported flag | Output vector |
+ InsertExtensionString("EGL_EXT_client_extensions", clientExtensions, &extensionStrings);
+ InsertExtensionString("EGL_EXT_device_query", deviceQueryEXT, &extensionStrings);
+ InsertExtensionString("EGL_EXT_platform_base", platformBase, &extensionStrings);
+ InsertExtensionString("EGL_EXT_platform_device", platformDevice, &extensionStrings);
+ InsertExtensionString("EGL_KHR_platform_gbm", platformGbmKHR, &extensionStrings);
+ InsertExtensionString("EGL_EXT_platform_wayland", platformWaylandEXT, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_platform_angle", platformANGLE, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_platform_angle_d3d", platformANGLED3D, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_platform_angle_d3d11on12", platformANGLED3D11ON12, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_platform_angle_device_type_egl_angle", platformANGLEDeviceTypeEGLANGLE, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_platform_angle_device_type_swiftshader", platformANGLEDeviceTypeSwiftShader, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_platform_angle_opengl", platformANGLEOpenGL, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_platform_angle_null", platformANGLENULL, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_platform_angle_vulkan", platformANGLEVulkan, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_platform_angle_metal", platformANGLEMetal, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_platform_device_context_volatile_eagl", platformANGLEDeviceContextVolatileEagl, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_platform_device_context_volatile_cgl", platformANGLEDeviceContextVolatileCgl, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_platform_angle_device_id", platformANGLEDeviceId, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_device_creation", deviceCreation, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_device_creation_d3d11", deviceCreationD3D11, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_x11_visual", x11Visual, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_experimental_present_path", experimentalPresentPath, &extensionStrings);
+ InsertExtensionString("EGL_KHR_client_get_all_proc_addresses", clientGetAllProcAddresses, &extensionStrings);
+ InsertExtensionString("EGL_KHR_debug", debug, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_feature_control", featureControlANGLE, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_display_power_preference", displayPowerPreferenceANGLE, &extensionStrings);
+ // clang-format on
+
+ return extensionStrings;
+}
+
+} // namespace egl
diff --git a/gfx/angle/checkout/src/libANGLE/Caps.h b/gfx/angle/checkout/src/libANGLE/Caps.h
new file mode 100644
index 0000000000..03b4ef8c9a
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Caps.h
@@ -0,0 +1,786 @@
+//
+// 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.
+//
+
+#ifndef LIBANGLE_CAPS_H_
+#define LIBANGLE_CAPS_H_
+
+#include "angle_gl.h"
+#include "libANGLE/Version.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/gles_extensions_autogen.h"
+#include "libANGLE/renderer/Format.h"
+
+#include <array>
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+
+namespace gl
+{
+struct TextureCaps
+{
+ TextureCaps();
+ TextureCaps(const TextureCaps &other);
+ TextureCaps &operator=(const TextureCaps &other);
+
+ ~TextureCaps();
+
+ // Supports for basic texturing: glTexImage, glTexSubImage, etc
+ bool texturable = false;
+
+ // Support for linear or anisotropic filtering
+ bool filterable = false;
+
+ // Support for being used as a framebuffer attachment, i.e. glFramebufferTexture2D
+ bool textureAttachment = false;
+
+ // Support for being used as a renderbuffer format, i.e. glFramebufferRenderbuffer
+ bool renderbuffer = false;
+
+ // Support for blend modes while being used as a framebuffer attachment
+ bool blendable = false;
+
+ // Set of supported sample counts, only guaranteed to be valid in ES3.
+ SupportedSampleSet sampleCounts;
+
+ // Get the maximum number of samples supported
+ GLuint getMaxSamples() const;
+
+ // Get the number of supported samples that is at least as many as requested. Returns 0 if
+ // there are no sample counts available
+ GLuint getNearestSamples(GLuint requestedSamples) const;
+};
+
+TextureCaps GenerateMinimumTextureCaps(GLenum internalFormat,
+ const Version &clientVersion,
+ const Extensions &extensions);
+
+class TextureCapsMap final : angle::NonCopyable
+{
+ public:
+ TextureCapsMap();
+ ~TextureCapsMap();
+
+ // These methods are deprecated. Please use angle::Format for new features.
+ void insert(GLenum internalFormat, const TextureCaps &caps);
+ const TextureCaps &get(GLenum internalFormat) const;
+
+ void clear();
+
+ // Prefer using angle::Format methods.
+ const TextureCaps &get(angle::FormatID formatID) const;
+ void set(angle::FormatID formatID, const TextureCaps &caps);
+
+ private:
+ TextureCaps &get(angle::FormatID formatID);
+
+ // Indexed by angle::FormatID
+ angle::FormatMap<TextureCaps> mFormatData;
+};
+
+void InitMinimumTextureCapsMap(const Version &clientVersion,
+ const Extensions &extensions,
+ TextureCapsMap *capsMap);
+
+// Returns true if all the formats required to support GL_ANGLE_compressed_texture_etc are
+// present. Does not determine if they are natively supported without decompression.
+bool DetermineCompressedTextureETCSupport(const TextureCapsMap &textureCaps);
+
+// Pointer to a boolean member of the Extensions struct
+using ExtensionBool = bool Extensions::*;
+
+struct ExtensionInfo
+{
+ // If this extension can be enabled or disabled with glRequestExtension
+ // (GL_ANGLE_request_extension)
+ bool Requestable = false;
+ bool Disablable = false;
+
+ // Pointer to a boolean member of the Extensions struct
+ ExtensionBool ExtensionsMember = nullptr;
+};
+
+using ExtensionInfoMap = std::map<std::string, ExtensionInfo>;
+const ExtensionInfoMap &GetExtensionInfoMap();
+
+struct Limitations
+{
+ Limitations();
+ Limitations(const Limitations &other);
+
+ Limitations &operator=(const Limitations &other);
+
+ // Renderer doesn't support gl_FrontFacing in fragment shaders
+ bool noFrontFacingSupport = false;
+
+ // Renderer doesn't support GL_SAMPLE_ALPHA_TO_COVERAGE
+ bool noSampleAlphaToCoverageSupport = false;
+
+ // In glVertexAttribDivisorANGLE, attribute zero must have a zero divisor
+ bool attributeZeroRequiresZeroDivisorInEXT = false;
+
+ // Unable to support different values for front and back faces for stencil refs and masks
+ bool noSeparateStencilRefsAndMasks = false;
+
+ // Renderer doesn't support non-constant indexing loops in fragment shader
+ bool shadersRequireIndexedLoopValidation = false;
+
+ // Renderer doesn't support Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA
+ // and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR blend functions.
+ bool noSimultaneousConstantColorAndAlphaBlendFunc = false;
+
+ // Renderer always clamps constant blend color.
+ bool noUnclampedBlendColor = false;
+
+ // D3D9 does not support flexible varying register packing.
+ bool noFlexibleVaryingPacking = false;
+
+ // D3D does not support having multiple transform feedback outputs go to the same buffer.
+ bool noDoubleBoundTransformFeedbackBuffers = false;
+
+ // D3D does not support vertex attribute aliasing
+ bool noVertexAttributeAliasing = false;
+
+ // Renderer doesn't support GL_TEXTURE_COMPARE_MODE=GL_NONE on a shadow sampler.
+ // TODO(http://anglebug.com/5231): add validation code to front-end.
+ bool noShadowSamplerCompareModeNone = false;
+
+ // PVRTC1 textures must be squares.
+ bool squarePvrtc1 = false;
+
+ // ETC1 texture support is emulated.
+ bool emulatedEtc1 = false;
+
+ // ASTC texture support is emulated.
+ bool emulatedAstc = false;
+
+ // No compressed TEXTURE_3D support.
+ bool noCompressedTexture3D = false;
+
+ // D3D does not support compressed textures where the base mip level is not a multiple of 4
+ bool compressedBaseMipLevelMultipleOfFour = false;
+
+ bool limitWebglMaxTextureSizeTo4096 = false;
+};
+
+struct TypePrecision
+{
+ TypePrecision();
+ TypePrecision(const TypePrecision &other);
+
+ TypePrecision &operator=(const TypePrecision &other);
+
+ void setIEEEFloat();
+ void setIEEEHalfFloat();
+ void setTwosComplementInt(unsigned int bits);
+ void setSimulatedFloat(unsigned int range, unsigned int precision);
+ void setSimulatedInt(unsigned int range);
+
+ void get(GLint *returnRange, GLint *returnPrecision) const;
+
+ std::array<GLint, 2> range = {0, 0};
+ GLint precision = 0;
+};
+
+struct Caps
+{
+ Caps();
+ Caps(const Caps &other);
+ Caps &operator=(const Caps &other);
+
+ ~Caps();
+
+ // If the values could be got by using GetIntegeri_v, they should
+ // be GLint instead of GLuint and call LimitToInt() to ensure
+ // they will not overflow.
+
+ GLfloat minInterpolationOffset = 0;
+ GLfloat maxInterpolationOffset = 0;
+ GLint subPixelInterpolationOffsetBits = 0;
+
+ // ES 3.1 (April 29, 2015) 20.39: implementation dependent values
+ GLint64 maxElementIndex = 0;
+ GLint max3DTextureSize = 0;
+ GLint max2DTextureSize = 0;
+ GLint maxRectangleTextureSize = 0;
+ GLint maxArrayTextureLayers = 0;
+ GLfloat maxLODBias = 0.0f;
+ GLint maxCubeMapTextureSize = 0;
+ GLint maxRenderbufferSize = 0;
+ GLfloat minAliasedPointSize = 1.0f;
+ GLfloat maxAliasedPointSize = 1.0f;
+ GLfloat minAliasedLineWidth = 0.0f;
+ GLfloat maxAliasedLineWidth = 0.0f;
+
+ // ES 3.1 (April 29, 2015) 20.40: implementation dependent values (cont.)
+ GLint maxDrawBuffers = 0;
+ GLint maxFramebufferWidth = 0;
+ GLint maxFramebufferHeight = 0;
+ GLint maxFramebufferSamples = 0;
+ GLint maxColorAttachments = 0;
+ GLint maxViewportWidth = 0;
+ GLint maxViewportHeight = 0;
+ GLint maxSampleMaskWords = 0;
+ GLint maxColorTextureSamples = 0;
+ GLint maxDepthTextureSamples = 0;
+ GLint maxIntegerSamples = 0;
+ GLint64 maxServerWaitTimeout = 0;
+
+ // ES 3.1 (April 29, 2015) Table 20.41: Implementation dependent values (cont.)
+ GLint maxVertexAttribRelativeOffset = 0;
+ GLint maxVertexAttribBindings = 0;
+ GLint maxVertexAttribStride = 0;
+ GLint maxElementsIndices = 0;
+ GLint maxElementsVertices = 0;
+ std::vector<GLenum> compressedTextureFormats;
+ std::vector<GLenum> programBinaryFormats;
+ std::vector<GLenum> shaderBinaryFormats;
+ TypePrecision vertexHighpFloat;
+ TypePrecision vertexMediumpFloat;
+ TypePrecision vertexLowpFloat;
+ TypePrecision vertexHighpInt;
+ TypePrecision vertexMediumpInt;
+ TypePrecision vertexLowpInt;
+ TypePrecision fragmentHighpFloat;
+ TypePrecision fragmentMediumpFloat;
+ TypePrecision fragmentLowpFloat;
+ TypePrecision fragmentHighpInt;
+ TypePrecision fragmentMediumpInt;
+ TypePrecision fragmentLowpInt;
+
+ // Implementation dependent limits required on all shader types.
+ // TODO(jiawei.shao@intel.com): organize all such limits into ShaderMap.
+ // ES 3.1 (April 29, 2015) Table 20.43: Implementation dependent Vertex shader limits
+ // ES 3.1 (April 29, 2015) Table 20.44: Implementation dependent Fragment shader limits
+ // ES 3.1 (April 29, 2015) Table 20.45: implementation dependent compute shader limits
+ // GL_EXT_geometry_shader (May 31, 2016) Table 20.43gs: Implementation dependent geometry shader
+ // limits
+ // GL_EXT_geometry_shader (May 31, 2016) Table 20.46: Implementation dependent aggregate shader
+ // limits
+ ShaderMap<GLint> maxShaderUniformBlocks = {};
+ ShaderMap<GLint> maxShaderTextureImageUnits = {};
+ ShaderMap<GLint> maxShaderStorageBlocks = {};
+ ShaderMap<GLint> maxShaderUniformComponents = {};
+ ShaderMap<GLint> maxShaderAtomicCounterBuffers = {};
+ ShaderMap<GLint> maxShaderAtomicCounters = {};
+ ShaderMap<GLint> maxShaderImageUniforms = {};
+ // Note that we can query MAX_COMPUTE_UNIFORM_COMPONENTS and MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT
+ // by GetIntegerv, but we can only use GetInteger64v on MAX_VERTEX_UNIFORM_COMPONENTS and
+ // MAX_FRAGMENT_UNIFORM_COMPONENTS. Currently we use GLuint64 to store all these values so that
+ // we can put them together into one ShaderMap.
+ ShaderMap<GLint64> maxCombinedShaderUniformComponents = {};
+
+ // ES 3.1 (April 29, 2015) Table 20.43: Implementation dependent Vertex shader limits
+ GLint maxVertexAttributes = 0;
+ GLint maxVertexUniformVectors = 0;
+ GLint maxVertexOutputComponents = 0;
+
+ // ES 3.1 (April 29, 2015) Table 20.44: Implementation dependent Fragment shader limits
+ GLint maxFragmentUniformVectors = 0;
+ GLint maxFragmentInputComponents = 0;
+ GLint minProgramTextureGatherOffset = 0;
+ GLint maxProgramTextureGatherOffset = 0;
+ GLint minProgramTexelOffset = 0;
+ GLint maxProgramTexelOffset = 0;
+
+ // ES 3.1 (April 29, 2015) Table 20.45: implementation dependent compute shader limits
+ std::array<GLint, 3> maxComputeWorkGroupCount = {0, 0, 0};
+ std::array<GLint, 3> maxComputeWorkGroupSize = {0, 0, 0};
+ GLint maxComputeWorkGroupInvocations = 0;
+ GLint maxComputeSharedMemorySize = 0;
+
+ // ES 3.1 (April 29, 2015) Table 20.46: implementation dependent aggregate shader limits
+ GLint maxUniformBufferBindings = 0;
+ GLint64 maxUniformBlockSize = 0;
+ GLint uniformBufferOffsetAlignment = 0;
+ GLint maxCombinedUniformBlocks = 0;
+ GLint maxVaryingComponents = 0;
+ GLint maxVaryingVectors = 0;
+ GLint maxCombinedTextureImageUnits = 0;
+ GLint maxCombinedShaderOutputResources = 0;
+
+ // ES 3.1 (April 29, 2015) Table 20.47: implementation dependent aggregate shader limits (cont.)
+ GLint maxUniformLocations = 0;
+ GLint maxAtomicCounterBufferBindings = 0;
+ GLint maxAtomicCounterBufferSize = 0;
+ GLint maxCombinedAtomicCounterBuffers = 0;
+ GLint maxCombinedAtomicCounters = 0;
+ GLint maxImageUnits = 0;
+ GLint maxCombinedImageUniforms = 0;
+ GLint maxShaderStorageBufferBindings = 0;
+ GLint64 maxShaderStorageBlockSize = 0;
+ GLint maxCombinedShaderStorageBlocks = 0;
+ GLint shaderStorageBufferOffsetAlignment = 0;
+
+ // ES 3.1 (April 29, 2015) Table 20.48: implementation dependent transform feedback limits
+ GLint maxTransformFeedbackInterleavedComponents = 0;
+ GLint maxTransformFeedbackSeparateAttributes = 0;
+ GLint maxTransformFeedbackSeparateComponents = 0;
+
+ // ES 3.1 (April 29, 2015) Table 20.49: Framebuffer Dependent Values
+ GLint maxSamples = 0;
+
+ // GL_EXT_geometry_shader (May 31, 2016) Table 20.40: Implementation-Dependent Values (cont.)
+ GLint maxFramebufferLayers = 0;
+ GLint layerProvokingVertex = 0;
+
+ // GL_EXT_geometry_shader (May 31, 2016) Table 20.43gs: Implementation dependent geometry shader
+ // limits
+ GLint maxGeometryInputComponents = 0;
+ GLint maxGeometryOutputComponents = 0;
+ GLint maxGeometryOutputVertices = 0;
+ GLint maxGeometryTotalOutputComponents = 0;
+ GLint maxGeometryShaderInvocations = 0;
+
+ // GL_EXT_tessellation_shader
+ GLint maxTessControlInputComponents = 0;
+ GLint maxTessControlOutputComponents = 0;
+ GLint maxTessControlTotalOutputComponents = 0;
+
+ GLint maxTessPatchComponents = 0;
+ GLint maxPatchVertices = 0;
+ GLint maxTessGenLevel = 0;
+
+ GLint maxTessEvaluationInputComponents = 0;
+ GLint maxTessEvaluationOutputComponents = 0;
+
+ GLuint subPixelBits = 4;
+
+ // GL_EXT_blend_func_extended
+ GLuint maxDualSourceDrawBuffers = 0;
+
+ // GL_EXT_texture_filter_anisotropic
+ GLfloat maxTextureAnisotropy = 0.0f;
+
+ // GL_EXT_disjoint_timer_query
+ GLuint queryCounterBitsTimeElapsed = 0;
+ GLuint queryCounterBitsTimestamp = 0;
+
+ // OVR_multiview
+ GLuint maxViews = 1;
+
+ // GL_KHR_debug
+ GLuint maxDebugMessageLength = 0;
+ GLuint maxDebugLoggedMessages = 0;
+ GLuint maxDebugGroupStackDepth = 0;
+ GLuint maxLabelLength = 0;
+
+ // GL_APPLE_clip_distance/GL_EXT_clip_cull_distance
+ GLuint maxClipDistances = 0;
+ GLuint maxCullDistances = 0;
+ GLuint maxCombinedClipAndCullDistances = 0;
+
+ // GL_ANGLE_shader_pixel_local_storage
+ GLuint maxPixelLocalStoragePlanes = 0;
+ GLuint maxColorAttachmentsWithActivePixelLocalStorage = 0;
+ GLuint maxCombinedDrawBuffersAndPixelLocalStoragePlanes = 0;
+
+ // GLES1 emulation: Caps for ES 1.1. Taken from Table 6.20 / 6.22 in the OpenGL ES 1.1 spec.
+ GLuint maxMultitextureUnits = 0;
+ GLuint maxClipPlanes = 0;
+ GLuint maxLights = 0;
+ static constexpr int GlobalMatrixStackDepth = 16;
+ GLuint maxModelviewMatrixStackDepth = 0;
+ GLuint maxProjectionMatrixStackDepth = 0;
+ GLuint maxTextureMatrixStackDepth = 0;
+ GLfloat minSmoothPointSize = 0.0f;
+ GLfloat maxSmoothPointSize = 0.0f;
+ GLfloat minSmoothLineWidth = 0.0f;
+ GLfloat maxSmoothLineWidth = 0.0f;
+
+ // ES 3.2 Table 20.41: Implementation Dependent Values (cont.)
+ GLint maxTextureBufferSize = 0;
+ GLint textureBufferOffsetAlignment = 0;
+};
+
+Caps GenerateMinimumCaps(const Version &clientVersion, const Extensions &extensions);
+} // namespace gl
+
+namespace egl
+{
+
+struct Caps
+{
+ Caps();
+
+ // Support for NPOT surfaces
+ bool textureNPOT;
+
+ // Support for Stencil8 configs
+ bool stencil8;
+};
+
+struct DisplayExtensions
+{
+ DisplayExtensions();
+
+ // Generate a vector of supported extension strings
+ std::vector<std::string> getStrings() const;
+
+ // EGL_EXT_create_context_robustness
+ bool createContextRobustness = false;
+
+ // EGL_ANGLE_d3d_share_handle_client_buffer
+ bool d3dShareHandleClientBuffer = false;
+
+ // EGL_ANGLE_d3d_texture_client_buffer
+ bool d3dTextureClientBuffer = false;
+
+ // EGL_ANGLE_surface_d3d_texture_2d_share_handle
+ bool surfaceD3DTexture2DShareHandle = false;
+
+ // EGL_ANGLE_query_surface_pointer
+ bool querySurfacePointer = false;
+
+ // EGL_ANGLE_window_fixed_size
+ bool windowFixedSize = false;
+
+ // EGL_ANGLE_keyed_mutex
+ bool keyedMutex = false;
+
+ // EGL_ANGLE_surface_orientation
+ bool surfaceOrientation = false;
+
+ // EGL_NV_post_sub_buffer
+ bool postSubBuffer = false;
+
+ // EGL_KHR_create_context
+ bool createContext = false;
+
+ // EGL_KHR_image
+ bool image = false;
+
+ // EGL_KHR_image_base
+ bool imageBase = false;
+
+ // EGL_KHR_image_pixmap
+ bool imagePixmap = false;
+
+ // EGL_KHR_gl_texture_2D_image
+ bool glTexture2DImage = false;
+
+ // EGL_KHR_gl_texture_cubemap_image
+ bool glTextureCubemapImage = false;
+
+ // EGL_KHR_gl_texture_3D_image
+ bool glTexture3DImage = false;
+
+ // EGL_KHR_gl_renderbuffer_image
+ bool glRenderbufferImage = false;
+
+ // EGL_KHR_get_all_proc_addresses
+ bool getAllProcAddresses = false;
+
+ // EGL_ANGLE_direct_composition
+ bool directComposition = false;
+
+ // EGL_ANGLE_windows_ui_composition
+ bool windowsUIComposition = false;
+
+ // KHR_create_context_no_error
+ bool createContextNoError = false;
+
+ // EGL_KHR_stream
+ bool stream = false;
+
+ // EGL_KHR_stream_consumer_gltexture
+ bool streamConsumerGLTexture = false;
+
+ // EGL_NV_stream_consumer_gltexture_yuv
+ bool streamConsumerGLTextureYUV = false;
+
+ // EGL_ANGLE_stream_producer_d3d_texture
+ bool streamProducerD3DTexture = false;
+
+ // EGL_KHR_fence_sync
+ bool fenceSync = false;
+
+ // EGL_KHR_wait_sync
+ bool waitSync = false;
+
+ // EGL_ANGLE_create_context_webgl_compatibility
+ bool createContextWebGLCompatibility = false;
+
+ // EGL_CHROMIUM_create_context_bind_generates_resource
+ bool createContextBindGeneratesResource = false;
+
+ // EGL_CHROMIUM_sync_control
+ bool syncControlCHROMIUM = false;
+
+ // EGL_ANGLE_sync_control_rate
+ bool syncControlRateANGLE = false;
+
+ // EGL_KHR_swap_buffers_with_damage
+ bool swapBuffersWithDamage = false;
+
+ // EGL_EXT_pixel_format_float
+ bool pixelFormatFloat = false;
+
+ // EGL_KHR_surfaceless_context
+ bool surfacelessContext = false;
+
+ // EGL_ANGLE_display_texture_share_group
+ bool displayTextureShareGroup = false;
+
+ // EGL_ANGLE_display_semaphore_share_group
+ bool displaySemaphoreShareGroup = false;
+
+ // EGL_ANGLE_create_context_client_arrays
+ bool createContextClientArrays = false;
+
+ // EGL_ANGLE_program_cache_control
+ bool programCacheControlANGLE = false;
+
+ // EGL_ANGLE_robust_resource_initialization
+ bool robustResourceInitializationANGLE = false;
+
+ // EGL_ANGLE_iosurface_client_buffer
+ bool iosurfaceClientBuffer = false;
+
+ // EGL_ANGLE_metal_texture_client_buffer
+ bool mtlTextureClientBuffer = false;
+
+ // EGL_ANGLE_create_context_extensions_enabled
+ bool createContextExtensionsEnabled = false;
+
+ // EGL_ANDROID_presentation_time
+ bool presentationTime = false;
+
+ // EGL_ANDROID_blob_cache
+ bool blobCache = false;
+
+ // EGL_ANDROID_image_native_buffer
+ bool imageNativeBuffer = false;
+
+ // EGL_ANDROID_get_frame_timestamps
+ bool getFrameTimestamps = false;
+
+ // EGL_ANGLE_timestamp_surface_attribute
+ bool timestampSurfaceAttributeANGLE = false;
+
+ // EGL_ANDROID_recordable
+ bool recordable = false;
+
+ // EGL_ANGLE_power_preference
+ bool powerPreference = false;
+
+ // EGL_ANGLE_image_d3d11_texture
+ bool imageD3D11Texture = false;
+
+ // EGL_ANDROID_get_native_client_buffer
+ bool getNativeClientBufferANDROID = false;
+
+ // EGL_ANDROID_create_native_client_buffer
+ bool createNativeClientBufferANDROID = false;
+
+ // EGL_ANDROID_native_fence_sync
+ bool nativeFenceSyncANDROID = false;
+
+ // EGL_ANGLE_create_context_backwards_compatible
+ bool createContextBackwardsCompatible = false;
+
+ // EGL_KHR_no_config_context
+ bool noConfigContext = false;
+
+ // EGL_IMG_context_priority
+ bool contextPriority = false;
+
+ // EGL_ANGLE_ggp_stream_descriptor
+ bool ggpStreamDescriptor = false;
+
+ // EGL_ANGLE_swap_with_frame_token
+ bool swapWithFrameToken = false;
+
+ // EGL_KHR_gl_colorspace
+ bool glColorspace = false;
+
+ // EGL_EXT_gl_colorspace_display_p3_linear
+ bool glColorspaceDisplayP3Linear = false;
+
+ // EGL_EXT_gl_colorspace_display_p3
+ bool glColorspaceDisplayP3 = false;
+
+ // EGL_EXT_gl_colorspace_scrgb
+ bool glColorspaceScrgb = false;
+
+ // EGL_EXT_gl_colorspace_scrgb_linear
+ bool glColorspaceScrgbLinear = false;
+
+ // EGL_EXT_gl_colorspace_display_p3_passthrough
+ bool glColorspaceDisplayP3Passthrough = false;
+
+ // EGL_ANGLE_colorspace_attribute_passthrough
+ bool eglColorspaceAttributePassthroughANGLE = false;
+
+ // EGL_ANDROID_framebuffer_target
+ bool framebufferTargetANDROID = false;
+
+ // EGL_EXT_image_gl_colorspace
+ bool imageGlColorspace = false;
+
+ // EGL_EXT_image_dma_buf_import
+ bool imageDmaBufImportEXT = false;
+
+ // EGL_EXT_image_dma_buf_import_modifiers
+ bool imageDmaBufImportModifiersEXT = false;
+
+ // EGL_NOK_texture_from_pixmap
+ bool textureFromPixmapNOK = false;
+
+ // EGL_NV_robustness_video_memory_purge
+ bool robustnessVideoMemoryPurgeNV = false;
+
+ // EGL_KHR_reusable_sync
+ bool reusableSyncKHR = false;
+
+ // EGL_ANGLE_external_context_and_surface
+ bool externalContextAndSurface = false;
+
+ // EGL_EXT_buffer_age
+ bool bufferAgeEXT = false;
+
+ // EGL_KHR_mutable_render_buffer
+ bool mutableRenderBufferKHR = false;
+
+ // EGL_EXT_protected_content
+ bool protectedContentEXT = false;
+
+ // EGL_ANGLE_create_surface_swap_interval
+ bool createSurfaceSwapIntervalANGLE = false;
+
+ // EGL_ANGLE_context_virtualization
+ bool contextVirtualizationANGLE = false;
+
+ // EGL_KHR_lock_surface3
+ bool lockSurface3KHR = false;
+
+ // EGL_ANGLE_vulkan_image
+ bool vulkanImageANGLE = false;
+
+ // EGL_ANGLE_metal_create_context_ownership_identity
+ bool metalCreateContextOwnershipIdentityANGLE = false;
+
+ // EGL_KHR_partial_update
+ bool partialUpdateKHR = false;
+
+ // EGL_ANGLE_sync_mtl_shared_event
+ bool mtlSyncSharedEventANGLE = false;
+};
+
+struct DeviceExtensions
+{
+ DeviceExtensions();
+
+ // Generate a vector of supported extension strings
+ std::vector<std::string> getStrings() const;
+
+ // EGL_ANGLE_device_d3d
+ bool deviceD3D = false;
+
+ // EGL_ANGLE_device_cgl
+ bool deviceCGL = false;
+
+ // EGL_ANGLE_device_eagl
+ bool deviceEAGL = false;
+
+ // EGL_ANGLE_device_metal
+ bool deviceMetal = false;
+
+ // EGL_ANGLE_device_vulkan
+ bool deviceVulkan = false;
+};
+
+struct ClientExtensions
+{
+ ClientExtensions();
+ ClientExtensions(const ClientExtensions &other);
+
+ // Generate a vector of supported extension strings
+ std::vector<std::string> getStrings() const;
+
+ // EGL_EXT_client_extensions
+ bool clientExtensions = false;
+
+ // EGL_EXT_platform_base
+ bool platformBase = false;
+
+ // EGL_EXT_platform_device
+ bool platformDevice = false;
+
+ // EGL_KHR_platform_gbm
+ bool platformGbmKHR = false;
+
+ // EGL_EXT_platform_wayland
+ bool platformWaylandEXT = false;
+
+ // EGL_ANGLE_platform_angle
+ bool platformANGLE = false;
+
+ // EGL_ANGLE_platform_angle_d3d
+ bool platformANGLED3D = false;
+
+ // EGL_ANGLE_platform_angle_d3d11on12
+ bool platformANGLED3D11ON12 = false;
+
+ // EGL_ANGLE_platform_angle_opengl
+ bool platformANGLEOpenGL = false;
+
+ // EGL_ANGLE_platform_angle_null
+ bool platformANGLENULL = false;
+
+ // EGL_ANGLE_platform_angle_vulkan
+ bool platformANGLEVulkan = false;
+
+ // EGL_ANGLE_platform_angle_metal
+ bool platformANGLEMetal = false;
+
+ // EGL_ANGLE_platform_angle_device_context_volatile_eagl
+ bool platformANGLEDeviceContextVolatileEagl = false;
+
+ // EGL_ANGLE_platform_angle_device_context_volatile_cgl
+ bool platformANGLEDeviceContextVolatileCgl = false;
+
+ // EGL_ANGLE_platform_angle_device_id
+ bool platformANGLEDeviceId = false;
+
+ // EGL_ANGLE_device_creation
+ bool deviceCreation = false;
+
+ // EGL_ANGLE_device_creation_d3d11
+ bool deviceCreationD3D11 = false;
+
+ // EGL_ANGLE_x11_visual
+ bool x11Visual = false;
+
+ // EGL_ANGLE_experimental_present_path
+ bool experimentalPresentPath = false;
+
+ // EGL_KHR_client_get_all_proc_addresses
+ bool clientGetAllProcAddresses = false;
+
+ // EGL_KHR_debug
+ bool debug = false;
+
+ // EGL_ANGLE_feature_control
+ bool featureControlANGLE = false;
+
+ // EGL_ANGLE_platform_angle_device_type_swiftshader
+ bool platformANGLEDeviceTypeSwiftShader = false;
+
+ // EGL_ANGLE_platform_angle_device_type_egl_angle
+ bool platformANGLEDeviceTypeEGLANGLE = false;
+
+ // EGL_EXT_device_query
+ bool deviceQueryEXT = false;
+
+ // EGL_ANGLE_display_power_preference
+ bool displayPowerPreferenceANGLE = false;
+};
+
+} // namespace egl
+
+#endif // LIBANGLE_CAPS_H_
diff --git a/gfx/angle/checkout/src/libANGLE/Compiler.cpp b/gfx/angle/checkout/src/libANGLE/Compiler.cpp
new file mode 100644
index 0000000000..a838f27ed6
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Compiler.cpp
@@ -0,0 +1,422 @@
+//
+// 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.
+//
+
+// Compiler.cpp: implements the gl::Compiler class.
+
+#include "libANGLE/Compiler.h"
+
+#include "common/debug.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Display.h"
+#include "libANGLE/State.h"
+#include "libANGLE/renderer/CompilerImpl.h"
+#include "libANGLE/renderer/GLImplFactory.h"
+
+namespace gl
+{
+
+namespace
+{
+
+// To know when to call sh::Initialize and sh::Finalize.
+size_t gActiveCompilers = 0;
+
+} // anonymous namespace
+
+Compiler::Compiler(rx::GLImplFactory *implFactory, const State &state, egl::Display *display)
+ : mImplementation(implFactory->createCompiler()),
+ mSpec(SelectShaderSpec(state)),
+ mOutputType(mImplementation->getTranslatorOutputType()),
+ mResources()
+{
+ // TODO(http://anglebug.com/3819): Update for GL version specific validation
+ ASSERT(state.getClientMajorVersion() == 1 || state.getClientMajorVersion() == 2 ||
+ state.getClientMajorVersion() == 3 || state.getClientMajorVersion() == 4);
+
+ {
+ std::lock_guard<std::mutex> lock(display->getDisplayGlobalMutex());
+ if (gActiveCompilers == 0)
+ {
+ sh::Initialize();
+ }
+ ++gActiveCompilers;
+ }
+
+ const Caps &caps = state.getCaps();
+ const Extensions &extensions = state.getExtensions();
+
+ sh::InitBuiltInResources(&mResources);
+ mResources.MaxVertexAttribs = caps.maxVertexAttributes;
+ mResources.MaxVertexUniformVectors = caps.maxVertexUniformVectors;
+ mResources.MaxVaryingVectors = caps.maxVaryingVectors;
+ mResources.MaxVertexTextureImageUnits = caps.maxShaderTextureImageUnits[ShaderType::Vertex];
+ mResources.MaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits;
+ mResources.MaxTextureImageUnits = caps.maxShaderTextureImageUnits[ShaderType::Fragment];
+ mResources.MaxFragmentUniformVectors = caps.maxFragmentUniformVectors;
+ mResources.MaxDrawBuffers = caps.maxDrawBuffers;
+ mResources.OES_standard_derivatives = extensions.standardDerivativesOES;
+ mResources.EXT_draw_buffers = extensions.drawBuffersEXT;
+ mResources.EXT_shader_texture_lod = extensions.shaderTextureLodEXT;
+ mResources.EXT_shader_non_constant_global_initializers =
+ extensions.shaderNonConstantGlobalInitializersEXT;
+ mResources.OES_EGL_image_external = extensions.EGLImageExternalOES;
+ mResources.OES_EGL_image_external_essl3 = extensions.EGLImageExternalEssl3OES;
+ mResources.NV_EGL_stream_consumer_external = extensions.EGLStreamConsumerExternalNV;
+ mResources.NV_shader_noperspective_interpolation =
+ extensions.shaderNoperspectiveInterpolationNV;
+ mResources.ARB_texture_rectangle = extensions.textureRectangleANGLE;
+ mResources.EXT_gpu_shader5 = extensions.gpuShader5EXT;
+ mResources.OES_shader_io_blocks = extensions.shaderIoBlocksOES;
+ mResources.EXT_shader_io_blocks = extensions.shaderIoBlocksEXT;
+ mResources.OES_texture_storage_multisample_2d_array =
+ extensions.textureStorageMultisample2dArrayOES;
+ mResources.OES_texture_3D = extensions.texture3DOES;
+ mResources.ANGLE_base_vertex_base_instance_shader_builtin =
+ extensions.baseVertexBaseInstanceShaderBuiltinANGLE;
+ mResources.ANGLE_multi_draw = extensions.multiDrawANGLE;
+ mResources.ANGLE_shader_pixel_local_storage = extensions.shaderPixelLocalStorageANGLE;
+ mResources.ANGLE_texture_multisample = extensions.textureMultisampleANGLE;
+ mResources.APPLE_clip_distance = extensions.clipDistanceAPPLE;
+ // OES_shader_multisample_interpolation
+ mResources.OES_shader_multisample_interpolation = extensions.shaderMultisampleInterpolationOES;
+ mResources.OES_shader_image_atomic = extensions.shaderImageAtomicOES;
+ // TODO: use shader precision caps to determine if high precision is supported?
+ mResources.FragmentPrecisionHigh = 1;
+ mResources.EXT_frag_depth = extensions.fragDepthEXT;
+
+ // OVR_multiview state
+ mResources.OVR_multiview = extensions.multiviewOVR;
+
+ // OVR_multiview2 state
+ mResources.OVR_multiview2 = extensions.multiview2OVR;
+ mResources.MaxViewsOVR = caps.maxViews;
+
+ // EXT_multisampled_render_to_texture and EXT_multisampled_render_to_texture2
+ mResources.EXT_multisampled_render_to_texture = extensions.multisampledRenderToTextureEXT;
+ mResources.EXT_multisampled_render_to_texture2 = extensions.multisampledRenderToTexture2EXT;
+
+ // WEBGL_video_texture
+ mResources.WEBGL_video_texture = extensions.videoTextureWEBGL;
+
+ // OES_texture_cube_map_array
+ mResources.OES_texture_cube_map_array = extensions.textureCubeMapArrayOES;
+ mResources.EXT_texture_cube_map_array = extensions.textureCubeMapArrayEXT;
+
+ // EXT_shadow_samplers
+ mResources.EXT_shadow_samplers = extensions.shadowSamplersEXT;
+
+ // OES_texture_buffer
+ mResources.OES_texture_buffer = extensions.textureBufferOES;
+ mResources.EXT_texture_buffer = extensions.textureBufferEXT;
+
+ // GL_EXT_YUV_target
+ mResources.EXT_YUV_target = extensions.YUVTargetEXT;
+
+ mResources.EXT_shader_framebuffer_fetch_non_coherent =
+ extensions.shaderFramebufferFetchNonCoherentEXT;
+
+ mResources.EXT_shader_framebuffer_fetch = extensions.shaderFramebufferFetchEXT;
+
+ // GL_EXT_clip_cull_distance
+ mResources.EXT_clip_cull_distance = extensions.clipCullDistanceEXT;
+
+ // GL_EXT_primitive_bounding_box
+ mResources.EXT_primitive_bounding_box = extensions.primitiveBoundingBoxEXT;
+
+ // GL_OES_primitive_bounding_box
+ mResources.OES_primitive_bounding_box = extensions.primitiveBoundingBoxOES;
+
+ // GLSL ES 3.0 constants
+ mResources.MaxVertexOutputVectors = caps.maxVertexOutputComponents / 4;
+ mResources.MaxFragmentInputVectors = caps.maxFragmentInputComponents / 4;
+ mResources.MinProgramTexelOffset = caps.minProgramTexelOffset;
+ mResources.MaxProgramTexelOffset = caps.maxProgramTexelOffset;
+
+ // EXT_blend_func_extended
+ mResources.EXT_blend_func_extended = extensions.blendFuncExtendedEXT;
+ mResources.MaxDualSourceDrawBuffers = caps.maxDualSourceDrawBuffers;
+
+ // APPLE_clip_distance/EXT_clip_cull_distance
+ mResources.MaxClipDistances = caps.maxClipDistances;
+ mResources.MaxCullDistances = caps.maxCullDistances;
+ mResources.MaxCombinedClipAndCullDistances = caps.maxCombinedClipAndCullDistances;
+
+ // ANGLE_shader_pixel_local_storage.
+ mResources.MaxPixelLocalStoragePlanes = caps.maxPixelLocalStoragePlanes;
+ mResources.MaxColorAttachmentsWithActivePixelLocalStorage =
+ caps.maxColorAttachmentsWithActivePixelLocalStorage;
+ mResources.MaxCombinedDrawBuffersAndPixelLocalStoragePlanes =
+ caps.maxCombinedDrawBuffersAndPixelLocalStoragePlanes;
+
+ // OES_sample_variables
+ mResources.OES_sample_variables = extensions.sampleVariablesOES;
+ mResources.MaxSamples = caps.maxSamples;
+
+ // ANDROID_extension_pack_es31a
+ mResources.ANDROID_extension_pack_es31a = extensions.extensionPackEs31aANDROID;
+
+ // KHR_blend_equation_advanced
+ mResources.KHR_blend_equation_advanced = extensions.blendEquationAdvancedKHR;
+
+ // GLSL ES 3.1 constants
+ mResources.MaxProgramTextureGatherOffset = caps.maxProgramTextureGatherOffset;
+ mResources.MinProgramTextureGatherOffset = caps.minProgramTextureGatherOffset;
+ mResources.MaxImageUnits = caps.maxImageUnits;
+ mResources.MaxVertexImageUniforms = caps.maxShaderImageUniforms[ShaderType::Vertex];
+ mResources.MaxFragmentImageUniforms = caps.maxShaderImageUniforms[ShaderType::Fragment];
+ mResources.MaxComputeImageUniforms = caps.maxShaderImageUniforms[ShaderType::Compute];
+ mResources.MaxCombinedImageUniforms = caps.maxCombinedImageUniforms;
+ mResources.MaxCombinedShaderOutputResources = caps.maxCombinedShaderOutputResources;
+ mResources.MaxUniformLocations = caps.maxUniformLocations;
+
+ for (size_t index = 0u; index < 3u; ++index)
+ {
+ mResources.MaxComputeWorkGroupCount[index] = caps.maxComputeWorkGroupCount[index];
+ mResources.MaxComputeWorkGroupSize[index] = caps.maxComputeWorkGroupSize[index];
+ }
+
+ mResources.MaxComputeUniformComponents = caps.maxShaderUniformComponents[ShaderType::Compute];
+ mResources.MaxComputeTextureImageUnits = caps.maxShaderTextureImageUnits[ShaderType::Compute];
+
+ mResources.MaxComputeAtomicCounters = caps.maxShaderAtomicCounters[ShaderType::Compute];
+ mResources.MaxComputeAtomicCounterBuffers =
+ caps.maxShaderAtomicCounterBuffers[ShaderType::Compute];
+
+ mResources.MaxVertexAtomicCounters = caps.maxShaderAtomicCounters[ShaderType::Vertex];
+ mResources.MaxFragmentAtomicCounters = caps.maxShaderAtomicCounters[ShaderType::Fragment];
+ mResources.MaxCombinedAtomicCounters = caps.maxCombinedAtomicCounters;
+ mResources.MaxAtomicCounterBindings = caps.maxAtomicCounterBufferBindings;
+ mResources.MaxVertexAtomicCounterBuffers =
+ caps.maxShaderAtomicCounterBuffers[ShaderType::Vertex];
+ mResources.MaxFragmentAtomicCounterBuffers =
+ caps.maxShaderAtomicCounterBuffers[ShaderType::Fragment];
+ mResources.MaxCombinedAtomicCounterBuffers = caps.maxCombinedAtomicCounterBuffers;
+ mResources.MaxAtomicCounterBufferSize = caps.maxAtomicCounterBufferSize;
+
+ mResources.MaxUniformBufferBindings = caps.maxUniformBufferBindings;
+ mResources.MaxShaderStorageBufferBindings = caps.maxShaderStorageBufferBindings;
+
+ // Needed by point size clamping workaround
+ mResources.MaxPointSize = caps.maxAliasedPointSize;
+
+ if (state.getClientMajorVersion() == 2 && !extensions.drawBuffersEXT)
+ {
+ mResources.MaxDrawBuffers = 1;
+ }
+
+ // Geometry Shader constants
+ mResources.EXT_geometry_shader = extensions.geometryShaderEXT;
+ mResources.OES_geometry_shader = extensions.geometryShaderOES;
+ mResources.MaxGeometryUniformComponents = caps.maxShaderUniformComponents[ShaderType::Geometry];
+ mResources.MaxGeometryUniformBlocks = caps.maxShaderUniformBlocks[ShaderType::Geometry];
+ mResources.MaxGeometryInputComponents = caps.maxGeometryInputComponents;
+ mResources.MaxGeometryOutputComponents = caps.maxGeometryOutputComponents;
+ mResources.MaxGeometryOutputVertices = caps.maxGeometryOutputVertices;
+ mResources.MaxGeometryTotalOutputComponents = caps.maxGeometryTotalOutputComponents;
+ mResources.MaxGeometryTextureImageUnits = caps.maxShaderTextureImageUnits[ShaderType::Geometry];
+
+ mResources.MaxGeometryAtomicCounterBuffers =
+ caps.maxShaderAtomicCounterBuffers[ShaderType::Geometry];
+ mResources.MaxGeometryAtomicCounters = caps.maxShaderAtomicCounters[ShaderType::Geometry];
+ mResources.MaxGeometryShaderStorageBlocks = caps.maxShaderStorageBlocks[ShaderType::Geometry];
+ mResources.MaxGeometryShaderInvocations = caps.maxGeometryShaderInvocations;
+ mResources.MaxGeometryImageUniforms = caps.maxShaderImageUniforms[ShaderType::Geometry];
+
+ // Tessellation Shader constants
+ mResources.EXT_tessellation_shader = extensions.tessellationShaderEXT;
+ mResources.MaxTessControlInputComponents = caps.maxTessControlInputComponents;
+ mResources.MaxTessControlOutputComponents = caps.maxTessControlOutputComponents;
+ mResources.MaxTessControlTextureImageUnits =
+ caps.maxShaderTextureImageUnits[ShaderType::TessControl];
+ mResources.MaxTessControlUniformComponents =
+ caps.maxShaderUniformComponents[ShaderType::TessControl];
+ mResources.MaxTessControlTotalOutputComponents = caps.maxTessControlTotalOutputComponents;
+ mResources.MaxTessControlImageUniforms = caps.maxShaderImageUniforms[ShaderType::TessControl];
+ mResources.MaxTessControlAtomicCounters = caps.maxShaderAtomicCounters[ShaderType::TessControl];
+ mResources.MaxTessControlAtomicCounterBuffers =
+ caps.maxShaderAtomicCounterBuffers[ShaderType::TessControl];
+
+ mResources.MaxTessPatchComponents = caps.maxTessPatchComponents;
+ mResources.MaxPatchVertices = caps.maxPatchVertices;
+ mResources.MaxTessGenLevel = caps.maxTessGenLevel;
+
+ mResources.MaxTessEvaluationInputComponents = caps.maxTessEvaluationInputComponents;
+ mResources.MaxTessEvaluationOutputComponents = caps.maxTessEvaluationOutputComponents;
+ mResources.MaxTessEvaluationTextureImageUnits =
+ caps.maxShaderTextureImageUnits[ShaderType::TessEvaluation];
+ mResources.MaxTessEvaluationUniformComponents =
+ caps.maxShaderUniformComponents[ShaderType::TessEvaluation];
+ mResources.MaxTessEvaluationImageUniforms =
+ caps.maxShaderImageUniforms[ShaderType::TessEvaluation];
+ mResources.MaxTessEvaluationAtomicCounters =
+ caps.maxShaderAtomicCounters[ShaderType::TessEvaluation];
+ mResources.MaxTessEvaluationAtomicCounterBuffers =
+ caps.maxShaderAtomicCounterBuffers[ShaderType::TessEvaluation];
+
+ // Subpixel bits.
+ mResources.SubPixelBits = static_cast<int>(caps.subPixelBits);
+}
+
+Compiler::~Compiler() = default;
+
+void Compiler::onDestroy(const Context *context)
+{
+ std::lock_guard<std::mutex> lock(context->getDisplay()->getDisplayGlobalMutex());
+ for (auto &pool : mPools)
+ {
+ for (ShCompilerInstance &instance : pool)
+ {
+ instance.destroy();
+ }
+ }
+ --gActiveCompilers;
+ if (gActiveCompilers == 0)
+ {
+ sh::Finalize();
+ }
+}
+
+ShCompilerInstance Compiler::getInstance(ShaderType type)
+{
+ ASSERT(type != ShaderType::InvalidEnum);
+ auto &pool = mPools[type];
+ if (pool.empty())
+ {
+ ShHandle handle = sh::ConstructCompiler(ToGLenum(type), mSpec, mOutputType, &mResources);
+ ASSERT(handle);
+ return ShCompilerInstance(handle, mOutputType, type);
+ }
+ else
+ {
+ ShCompilerInstance instance = std::move(pool.back());
+ pool.pop_back();
+ return instance;
+ }
+}
+
+void Compiler::putInstance(ShCompilerInstance &&instance)
+{
+ static constexpr size_t kMaxPoolSize = 32;
+ auto &pool = mPools[instance.getShaderType()];
+ if (pool.size() < kMaxPoolSize)
+ {
+ pool.push_back(std::move(instance));
+ }
+ else
+ {
+ instance.destroy();
+ }
+}
+
+ShShaderSpec Compiler::SelectShaderSpec(const State &state)
+{
+ const EGLenum clientType = state.getClientType();
+ const EGLint profileMask = state.getProfileMask();
+ const GLint majorVersion = state.getClientMajorVersion();
+ const GLint minorVersion = state.getClientMinorVersion();
+ bool isWebGL = state.isWebGL();
+
+ // For Desktop GL
+ if (clientType == EGL_OPENGL_API)
+ {
+ if ((profileMask & EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT) != 0)
+ {
+ return SH_GL_CORE_SPEC;
+ }
+ else
+ {
+ return SH_GL_COMPATIBILITY_SPEC;
+ }
+ }
+
+ if (majorVersion >= 3)
+ {
+ switch (minorVersion)
+ {
+ case 2:
+ ASSERT(!isWebGL);
+ return SH_GLES3_2_SPEC;
+ case 1:
+ return isWebGL ? SH_WEBGL3_SPEC : SH_GLES3_1_SPEC;
+ case 0:
+ return isWebGL ? SH_WEBGL2_SPEC : SH_GLES3_SPEC;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ // GLES1 emulation: Use GLES3 shader spec.
+ if (!isWebGL && majorVersion == 1)
+ {
+ return SH_GLES3_SPEC;
+ }
+
+ return isWebGL ? SH_WEBGL_SPEC : SH_GLES2_SPEC;
+}
+
+ShCompilerInstance::ShCompilerInstance() : mHandle(nullptr) {}
+
+ShCompilerInstance::ShCompilerInstance(ShHandle handle,
+ ShShaderOutput outputType,
+ ShaderType shaderType)
+ : mHandle(handle), mOutputType(outputType), mShaderType(shaderType)
+{}
+
+ShCompilerInstance::~ShCompilerInstance()
+{
+ ASSERT(mHandle == nullptr);
+}
+
+void ShCompilerInstance::destroy()
+{
+ if (mHandle != nullptr)
+ {
+ sh::Destruct(mHandle);
+ mHandle = nullptr;
+ }
+}
+
+ShCompilerInstance::ShCompilerInstance(ShCompilerInstance &&other)
+ : mHandle(other.mHandle), mOutputType(other.mOutputType), mShaderType(other.mShaderType)
+{
+ other.mHandle = nullptr;
+}
+
+ShCompilerInstance &ShCompilerInstance::operator=(ShCompilerInstance &&other)
+{
+ mHandle = other.mHandle;
+ mOutputType = other.mOutputType;
+ mShaderType = other.mShaderType;
+ other.mHandle = nullptr;
+ return *this;
+}
+
+ShHandle ShCompilerInstance::getHandle()
+{
+ return mHandle;
+}
+
+ShaderType ShCompilerInstance::getShaderType() const
+{
+ return mShaderType;
+}
+
+ShBuiltInResources ShCompilerInstance::getBuiltInResources() const
+{
+ return sh::GetBuiltInResources(mHandle);
+}
+
+const std::string &ShCompilerInstance::getBuiltinResourcesString() const
+{
+ return sh::GetBuiltInResourcesString(mHandle);
+}
+
+ShShaderOutput ShCompilerInstance::getShaderOutputType() const
+{
+ return mOutputType;
+}
+
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/Compiler.h b/gfx/angle/checkout/src/libANGLE/Compiler.h
new file mode 100644
index 0000000000..01428f36da
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Compiler.h
@@ -0,0 +1,78 @@
+//
+// 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.
+//
+
+// Compiler.h: Defines the gl::Compiler class, abstracting the ESSL compiler
+// that a GL context holds.
+
+#ifndef LIBANGLE_COMPILER_H_
+#define LIBANGLE_COMPILER_H_
+
+#include <vector>
+
+#include "GLSLANG/ShaderLang.h"
+#include "common/PackedEnums.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/RefCountObject.h"
+
+namespace rx
+{
+class CompilerImpl;
+class GLImplFactory;
+} // namespace rx
+
+namespace gl
+{
+class ShCompilerInstance;
+class State;
+
+class Compiler final : public RefCountObjectNoID
+{
+ public:
+ Compiler(rx::GLImplFactory *implFactory, const State &data, egl::Display *display);
+
+ void onDestroy(const Context *context) override;
+
+ ShCompilerInstance getInstance(ShaderType shaderType);
+ void putInstance(ShCompilerInstance &&instance);
+ ShShaderOutput getShaderOutputType() const { return mOutputType; }
+
+ static ShShaderSpec SelectShaderSpec(const State &state);
+
+ private:
+ ~Compiler() override;
+ std::unique_ptr<rx::CompilerImpl> mImplementation;
+ ShShaderSpec mSpec;
+ ShShaderOutput mOutputType;
+ ShBuiltInResources mResources;
+ ShaderMap<std::vector<ShCompilerInstance>> mPools;
+};
+
+class ShCompilerInstance final : public angle::NonCopyable
+{
+ public:
+ ShCompilerInstance();
+ ShCompilerInstance(ShHandle handle, ShShaderOutput outputType, ShaderType shaderType);
+ ~ShCompilerInstance();
+ void destroy();
+
+ ShCompilerInstance(ShCompilerInstance &&other);
+ ShCompilerInstance &operator=(ShCompilerInstance &&other);
+
+ ShHandle getHandle();
+ ShaderType getShaderType() const;
+ ShBuiltInResources getBuiltInResources() const;
+ const std::string &getBuiltinResourcesString() const;
+ ShShaderOutput getShaderOutputType() const;
+
+ private:
+ ShHandle mHandle;
+ ShShaderOutput mOutputType;
+ ShaderType mShaderType;
+};
+
+} // namespace gl
+
+#endif // LIBANGLE_COMPILER_H_
diff --git a/gfx/angle/checkout/src/libANGLE/Config.cpp b/gfx/angle/checkout/src/libANGLE/Config.cpp
new file mode 100644
index 0000000000..127480db1f
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Config.cpp
@@ -0,0 +1,416 @@
+//
+// Copyright 2002 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.
+//
+
+// Config.cpp: Implements the egl::Config class, describing the format, type
+// and size for an egl::Surface. Implements EGLConfig and related functionality.
+// [EGL 1.5] section 3.4 page 19.
+
+#include "libANGLE/Config.h"
+#include "libANGLE/AttributeMap.h"
+
+#include <algorithm>
+#include <vector>
+
+#include <EGL/eglext.h>
+#include "angle_gl.h"
+
+#include "common/debug.h"
+
+namespace egl
+{
+
+Config::Config()
+ : renderTargetFormat(GL_NONE),
+ depthStencilFormat(GL_NONE),
+ bufferSize(0),
+ redSize(0),
+ greenSize(0),
+ blueSize(0),
+ luminanceSize(0),
+ alphaSize(0),
+ alphaMaskSize(0),
+ bindToTextureRGB(EGL_FALSE),
+ bindToTextureRGBA(EGL_FALSE),
+ bindToTextureTarget(EGL_TEXTURE_2D),
+ colorBufferType(EGL_RGB_BUFFER),
+ configCaveat(EGL_NONE),
+ configID(0),
+ conformant(0),
+ depthSize(0),
+ level(0),
+ matchNativePixmap(EGL_FALSE),
+ maxPBufferWidth(0),
+ maxPBufferHeight(0),
+ maxPBufferPixels(0),
+ maxSwapInterval(0),
+ minSwapInterval(0),
+ nativeRenderable(EGL_FALSE),
+ nativeVisualID(0),
+ nativeVisualType(0),
+ renderableType(0),
+ sampleBuffers(0),
+ samples(0),
+ stencilSize(0),
+ surfaceType(0),
+ transparentType(EGL_NONE),
+ transparentRedValue(0),
+ transparentGreenValue(0),
+ transparentBlueValue(0),
+ optimalOrientation(0),
+ colorComponentType(EGL_COLOR_COMPONENT_TYPE_FIXED_EXT),
+ recordable(EGL_FALSE),
+ framebufferTarget(EGL_FALSE), // TODO: http://anglebug.com/4208
+ yInverted(EGL_FALSE)
+{}
+
+Config::~Config() {}
+
+Config::Config(const Config &other) = default;
+
+Config &Config::operator=(const Config &other) = default;
+
+ConfigSet::ConfigSet() = default;
+
+ConfigSet::ConfigSet(const ConfigSet &other) = default;
+
+ConfigSet &ConfigSet::operator=(const ConfigSet &other) = default;
+
+ConfigSet::~ConfigSet() = default;
+
+EGLint ConfigSet::add(const Config &config)
+{
+ // Set the config's ID to a small number that starts at 1 ([EGL 1.5] section 3.4)
+ EGLint id = static_cast<EGLint>(mConfigs.size()) + 1;
+
+ Config copyConfig(config);
+ copyConfig.configID = id;
+ mConfigs.insert(std::make_pair(id, copyConfig));
+
+ return id;
+}
+
+const Config &ConfigSet::get(EGLint id) const
+{
+ ASSERT(mConfigs.find(id) != mConfigs.end());
+ return mConfigs.find(id)->second;
+}
+
+void ConfigSet::clear()
+{
+ mConfigs.clear();
+}
+
+size_t ConfigSet::size() const
+{
+ return mConfigs.size();
+}
+
+bool ConfigSet::contains(const Config *config) const
+{
+ for (auto i = mConfigs.begin(); i != mConfigs.end(); i++)
+ {
+ const Config &item = i->second;
+ if (config == &item)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+// Function object used by STL sorting routines for ordering Configs according to [EGL 1.5]
+// section 3.4.1.2 page 28.
+class ConfigSorter
+{
+ public:
+ explicit ConfigSorter(const AttributeMap &attributeMap)
+ : mWantRed(false),
+ mWantGreen(false),
+ mWantBlue(false),
+ mWantAlpha(false),
+ mWantLuminance(false)
+ {
+ scanForWantedComponents(attributeMap);
+ }
+
+ bool operator()(const Config *x, const Config *y) const { return (*this)(*x, *y); }
+
+ bool operator()(const Config &x, const Config &y) const
+ {
+#define SORT(attribute) \
+ do \
+ { \
+ if (x.attribute != y.attribute) \
+ return x.attribute < y.attribute; \
+ } while (0)
+
+ static_assert(EGL_NONE < EGL_SLOW_CONFIG && EGL_SLOW_CONFIG < EGL_NON_CONFORMANT_CONFIG,
+ "Unexpected EGL enum value.");
+ SORT(configCaveat);
+
+ static_assert(EGL_COLOR_COMPONENT_TYPE_FIXED_EXT < EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT,
+ "Unexpected order of EGL enums.");
+ SORT(colorComponentType);
+
+ static_assert(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER, "Unexpected EGL enum value.");
+ SORT(colorBufferType);
+
+ // By larger total number of color bits, only considering those that are requested to be >
+ // 0.
+ EGLint xComponentsSize = wantedComponentsSize(x);
+ EGLint yComponentsSize = wantedComponentsSize(y);
+ if (xComponentsSize != yComponentsSize)
+ {
+ return xComponentsSize > yComponentsSize;
+ }
+
+ SORT(bufferSize);
+ SORT(sampleBuffers);
+ SORT(samples);
+ SORT(depthSize);
+ SORT(stencilSize);
+ SORT(alphaMaskSize);
+ SORT(nativeVisualType);
+ SORT(configID);
+
+#undef SORT
+
+ return false;
+ }
+
+ private:
+ static bool wantsComponent(const AttributeMap &attributeMap, EGLAttrib component)
+ {
+ // [EGL 1.5] section 3.4.1.2 page 30
+ // Sorting rule #3: by larger total number of color bits, not considering
+ // components that are 0 or don't-care.
+ EGLAttrib value = attributeMap.get(component, 0);
+ return value != 0 && value != EGL_DONT_CARE;
+ }
+
+ void scanForWantedComponents(const AttributeMap &attributeMap)
+ {
+ mWantRed = wantsComponent(attributeMap, EGL_RED_SIZE);
+ mWantGreen = wantsComponent(attributeMap, EGL_GREEN_SIZE);
+ mWantBlue = wantsComponent(attributeMap, EGL_BLUE_SIZE);
+ mWantAlpha = wantsComponent(attributeMap, EGL_ALPHA_SIZE);
+ mWantLuminance = wantsComponent(attributeMap, EGL_LUMINANCE_SIZE);
+ }
+
+ EGLint wantedComponentsSize(const Config &config) const
+ {
+ EGLint total = 0;
+
+ if (mWantRed)
+ total += config.redSize;
+ if (mWantGreen)
+ total += config.greenSize;
+ if (mWantBlue)
+ total += config.blueSize;
+ if (mWantAlpha)
+ total += config.alphaSize;
+ if (mWantLuminance)
+ total += config.luminanceSize;
+
+ return total;
+ }
+
+ bool mWantRed;
+ bool mWantGreen;
+ bool mWantBlue;
+ bool mWantAlpha;
+ bool mWantLuminance;
+};
+
+std::vector<const Config *> ConfigSet::filter(const AttributeMap &attributeMap) const
+{
+ std::vector<const Config *> result;
+ result.reserve(mConfigs.size());
+
+ for (auto configIter = mConfigs.begin(); configIter != mConfigs.end(); configIter++)
+ {
+ const Config &config = configIter->second;
+ bool match = true;
+
+ for (auto attribIter = attributeMap.begin(); attribIter != attributeMap.end(); attribIter++)
+ {
+ EGLAttrib attributeKey = attribIter->first;
+ EGLAttrib attributeValue = attribIter->second;
+
+ if (attributeValue == EGL_DONT_CARE)
+ {
+ continue;
+ }
+
+ switch (attributeKey)
+ {
+ case EGL_BUFFER_SIZE:
+ match = config.bufferSize >= attributeValue;
+ break;
+ case EGL_ALPHA_SIZE:
+ match = config.alphaSize >= attributeValue;
+ break;
+ case EGL_BLUE_SIZE:
+ match = config.blueSize >= attributeValue;
+ break;
+ case EGL_GREEN_SIZE:
+ match = config.greenSize >= attributeValue;
+ break;
+ case EGL_RED_SIZE:
+ match = config.redSize >= attributeValue;
+ break;
+ case EGL_DEPTH_SIZE:
+ match = config.depthSize >= attributeValue;
+ break;
+ case EGL_STENCIL_SIZE:
+ match = config.stencilSize >= attributeValue;
+ break;
+ case EGL_CONFIG_CAVEAT:
+ match = config.configCaveat == static_cast<EGLenum>(attributeValue);
+ break;
+ case EGL_CONFIG_ID:
+ match = config.configID == attributeValue;
+ break;
+ case EGL_LEVEL:
+ match = config.level == attributeValue;
+ break;
+ case EGL_NATIVE_RENDERABLE:
+ match = config.nativeRenderable == static_cast<EGLBoolean>(attributeValue);
+ break;
+ case EGL_NATIVE_VISUAL_TYPE:
+ match = config.nativeVisualType == attributeValue;
+ break;
+ case EGL_SAMPLES:
+ match = config.samples >= attributeValue;
+ break;
+ case EGL_SAMPLE_BUFFERS:
+ match = config.sampleBuffers >= attributeValue;
+ break;
+ case EGL_SURFACE_TYPE:
+ match = (config.surfaceType & attributeValue) == attributeValue;
+ break;
+ case EGL_TRANSPARENT_TYPE:
+ match = config.transparentType == static_cast<EGLenum>(attributeValue);
+ break;
+ case EGL_TRANSPARENT_BLUE_VALUE:
+ if (attributeMap.get(EGL_TRANSPARENT_TYPE, EGL_NONE) != EGL_NONE)
+ {
+ match = config.transparentBlueValue == attributeValue;
+ }
+ break;
+ case EGL_TRANSPARENT_GREEN_VALUE:
+ if (attributeMap.get(EGL_TRANSPARENT_TYPE, EGL_NONE) != EGL_NONE)
+ {
+ match = config.transparentGreenValue == attributeValue;
+ }
+ break;
+ case EGL_TRANSPARENT_RED_VALUE:
+ if (attributeMap.get(EGL_TRANSPARENT_TYPE, EGL_NONE) != EGL_NONE)
+ {
+ match = config.transparentRedValue == attributeValue;
+ }
+ break;
+ case EGL_BIND_TO_TEXTURE_RGB:
+ match = config.bindToTextureRGB == static_cast<EGLBoolean>(attributeValue);
+ break;
+ case EGL_BIND_TO_TEXTURE_RGBA:
+ match = config.bindToTextureRGBA == static_cast<EGLBoolean>(attributeValue);
+ break;
+ case EGL_BIND_TO_TEXTURE_TARGET_ANGLE:
+ match = config.bindToTextureTarget == static_cast<EGLenum>(attributeValue);
+ break;
+ case EGL_MIN_SWAP_INTERVAL:
+ match = config.minSwapInterval == attributeValue;
+ break;
+ case EGL_MAX_SWAP_INTERVAL:
+ match = config.maxSwapInterval == attributeValue;
+ break;
+ case EGL_LUMINANCE_SIZE:
+ match = config.luminanceSize >= attributeValue;
+ break;
+ case EGL_ALPHA_MASK_SIZE:
+ match = config.alphaMaskSize >= attributeValue;
+ break;
+ case EGL_COLOR_BUFFER_TYPE:
+ match = config.colorBufferType == static_cast<EGLenum>(attributeValue);
+ break;
+ case EGL_RENDERABLE_TYPE:
+ match = (config.renderableType & attributeValue) == attributeValue;
+ break;
+ case EGL_MATCH_NATIVE_PIXMAP:
+ match = false;
+ UNIMPLEMENTED();
+ break;
+ case EGL_CONFORMANT:
+ match = (config.conformant & attributeValue) == attributeValue;
+ break;
+ case EGL_MAX_PBUFFER_WIDTH:
+ match = config.maxPBufferWidth >= attributeValue;
+ break;
+ case EGL_MAX_PBUFFER_HEIGHT:
+ match = config.maxPBufferHeight >= attributeValue;
+ break;
+ case EGL_MAX_PBUFFER_PIXELS:
+ match = config.maxPBufferPixels >= attributeValue;
+ break;
+ case EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE:
+ match = config.optimalOrientation == attributeValue;
+ break;
+ case EGL_COLOR_COMPONENT_TYPE_EXT:
+ match = config.colorComponentType == static_cast<EGLenum>(attributeValue);
+ break;
+ case EGL_RECORDABLE_ANDROID:
+ match = config.recordable == static_cast<EGLBoolean>(attributeValue);
+ break;
+ case EGL_FRAMEBUFFER_TARGET_ANDROID:
+ match = config.framebufferTarget == static_cast<EGLBoolean>(attributeValue);
+ break;
+ case EGL_Y_INVERTED_NOK:
+ match = config.yInverted == static_cast<EGLBoolean>(attributeValue);
+ break;
+ case EGL_MATCH_FORMAT_KHR:
+ if (attributeValue == EGL_NONE)
+ {
+ match = (config.surfaceType & EGL_LOCK_SURFACE_BIT_KHR) == 0;
+ }
+ else
+ {
+ match = config.matchFormat == attributeValue;
+ }
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ if (!match)
+ {
+ break;
+ }
+ }
+
+ if (match)
+ {
+ result.push_back(&config);
+ }
+ }
+
+ // Sort the result
+ std::sort(result.begin(), result.end(), ConfigSorter(attributeMap));
+
+ return result;
+}
+
+ConfigSet::ConfigMap::iterator ConfigSet::begin()
+{
+ return mConfigs.begin();
+}
+
+ConfigSet::ConfigMap::iterator ConfigSet::end()
+{
+ return mConfigs.end();
+}
+} // namespace egl
diff --git a/gfx/angle/checkout/src/libANGLE/Config.h b/gfx/angle/checkout/src/libANGLE/Config.h
new file mode 100644
index 0000000000..7901c793ee
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Config.h
@@ -0,0 +1,115 @@
+//
+// Copyright 2002 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.
+//
+
+// Config.h: Defines the egl::Config class, describing the format, type
+// and size for an egl::Surface. Implements EGLConfig and related functionality.
+// [EGL 1.5] section 3.4 page 19.
+
+#ifndef INCLUDE_CONFIG_H_
+#define INCLUDE_CONFIG_H_
+
+#include "libANGLE/AttributeMap.h"
+
+#include "common/angleutils.h"
+
+#include <EGL/egl.h>
+#include <GLES2/gl2.h>
+
+#include <map>
+#include <vector>
+
+namespace egl
+{
+
+struct Config
+{
+ Config();
+ ~Config();
+ Config(const Config &other);
+ Config &operator=(const Config &other);
+
+ GLenum renderTargetFormat; // TODO(geofflang): remove this
+ GLenum depthStencilFormat; // TODO(geofflang): remove this
+
+ EGLint bufferSize; // Depth of the color buffer
+ EGLint redSize; // Bits of Red in the color buffer
+ EGLint greenSize; // Bits of Green in the color buffer
+ EGLint blueSize; // Bits of Blue in the color buffer
+ EGLint luminanceSize; // Bits of Luminance in the color buffer
+ EGLint alphaSize; // Bits of Alpha in the color buffer
+ EGLint alphaMaskSize; // Bits of Alpha Mask in the mask buffer
+ EGLBoolean bindToTextureRGB; // True if bindable to RGB textures.
+ EGLBoolean bindToTextureRGBA; // True if bindable to RGBA textures.
+ EGLenum bindToTextureTarget; // Which texture target should be used for pbuffers
+ EGLenum colorBufferType; // Color buffer type
+ EGLenum configCaveat; // Any caveats for the configuration
+ EGLint configID; // Unique EGLConfig identifier
+ EGLint conformant; // Whether contexts created with this config are conformant
+ EGLint depthSize; // Bits of Z in the depth buffer
+ EGLint level; // Frame buffer level
+ EGLBoolean matchNativePixmap; // Match the native pixmap format
+ EGLint maxPBufferWidth; // Maximum width of pbuffer
+ EGLint maxPBufferHeight; // Maximum height of pbuffer
+ EGLint maxPBufferPixels; // Maximum size of pbuffer
+ EGLint maxSwapInterval; // Maximum swap interval
+ EGLint minSwapInterval; // Minimum swap interval
+ EGLBoolean nativeRenderable; // EGL_TRUE if native rendering APIs can render to surface
+ EGLint nativeVisualID; // Handle of corresponding native visual
+ EGLint nativeVisualType; // Native visual type of the associated visual
+ EGLint renderableType; // Which client rendering APIs are supported.
+ EGLint sampleBuffers; // Number of multisample buffers
+ EGLint samples; // Number of samples per pixel
+ EGLint stencilSize; // Bits of Stencil in the stencil buffer
+ EGLint surfaceType; // Which types of EGL surfaces are supported.
+ EGLenum transparentType; // Type of transparency supported
+ EGLint transparentRedValue; // Transparent red value
+ EGLint transparentGreenValue; // Transparent green value
+ EGLint transparentBlueValue; // Transparent blue value
+ EGLint optimalOrientation; // Optimal window surface orientation
+ EGLenum colorComponentType; // Color component type
+ EGLBoolean recordable; // EGL_TRUE if a surface can support recording on Android
+ EGLBoolean framebufferTarget; // EGL_TRUE if the config supports rendering to a ANativeWindow
+ // for which the buffers are passed to the HWComposer HAL as a
+ // framebuffer target layer.
+ EGLBoolean yInverted; // True if the drawable's framebuffer is y-inverted. This can be used to
+ // determine if y-inverted texture coordinates need to be used when
+ // texturing from this drawable when it is bound to a texture target.
+ EGLint matchFormat; // LockSurface match format.
+};
+
+class ConfigSet
+{
+ private:
+ typedef std::map<EGLint, Config> ConfigMap;
+
+ public:
+ ConfigSet();
+ ConfigSet(const ConfigSet &other);
+ ~ConfigSet();
+ ConfigSet &operator=(const ConfigSet &other);
+
+ EGLint add(const Config &config);
+ const Config &get(EGLint id) const;
+
+ void clear();
+
+ size_t size() const;
+
+ bool contains(const Config *config) const;
+
+ // Filter configurations based on the table in [EGL 1.5] section 3.4.1.2 page 29
+ std::vector<const Config *> filter(const AttributeMap &attributeMap) const;
+
+ ConfigMap::iterator begin();
+ ConfigMap::iterator end();
+
+ private:
+ ConfigMap mConfigs;
+};
+
+} // namespace egl
+
+#endif // INCLUDE_CONFIG_H_
diff --git a/gfx/angle/checkout/src/libANGLE/Constants.h b/gfx/angle/checkout/src/libANGLE/Constants.h
new file mode 100644
index 0000000000..36152825e4
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Constants.h
@@ -0,0 +1,125 @@
+//
+// Copyright 2013 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.
+//
+
+// Contants.h: Defines some implementation specific and gl constants
+
+#ifndef LIBANGLE_CONSTANTS_H_
+#define LIBANGLE_CONSTANTS_H_
+
+#include "common/platform.h"
+
+#include <stdint.h>
+
+namespace gl
+{
+
+// The binary cache is currently left disable by default, and the application can enable it.
+const size_t kDefaultMaxProgramCacheMemoryBytes = 0;
+
+enum
+{
+ // Implementation upper limits, real maximums depend on the hardware
+
+ // Only up to 32x MSAA supported.
+ IMPLEMENTATION_MAX_SAMPLE_MASK_WORDS = 1,
+ IMPLEMENTATION_MAX_SAMPLES = 32,
+
+ MAX_VERTEX_ATTRIBS = 16,
+ MAX_VERTEX_ATTRIB_BINDINGS = 16,
+
+ IMPLEMENTATION_MAX_VARYING_VECTORS = 32,
+ IMPLEMENTATION_MAX_DRAW_BUFFERS = 8,
+ IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS =
+ IMPLEMENTATION_MAX_DRAW_BUFFERS + 2, // 2 extra for depth and/or stencil buffers
+
+ // The vast majority of devices support only one dual-source draw buffer
+ IMPLEMENTATION_MAX_DUAL_SOURCE_DRAW_BUFFERS = 1,
+
+ IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS = 16,
+ IMPLEMENTATION_MAX_GEOMETRY_SHADER_UNIFORM_BUFFERS = 16,
+ IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS = 16,
+ IMPLEMENTATION_MAX_COMPUTE_SHADER_UNIFORM_BUFFERS = 16,
+
+ // GL_EXT_geometry_shader increases the minimum value of GL_MAX_COMBINED_UNIFORM_BLOCKS to 36.
+ // GL_EXT_tessellation_shader increases the minimum value to 60.
+ IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS = 60,
+
+ // GL_EXT_geometry_shader increases the minimum value of GL_MAX_UNIFORM_BUFFER_BINDINGS to 48.
+ // GL_EXT_tessellation_shader increases the minimum value to 72.
+ IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS = 72,
+
+ // Transform feedback limits set to the minimum required by the spec.
+ IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS = 128,
+ IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS = 4,
+ IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS = 4,
+ IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS = 4,
+
+ // Maximum number of views which are supported by the implementation of ANGLE_multiview.
+ IMPLEMENTATION_ANGLE_MULTIVIEW_MAX_VIEWS = 4,
+
+ // These are the maximums the implementation can support
+ // The actual GL caps are limited by the device caps
+ // and should be queried from the Context
+ IMPLEMENTATION_MAX_2D_TEXTURE_SIZE = 32768,
+ IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE = 32768,
+ IMPLEMENTATION_MAX_3D_TEXTURE_SIZE = 16384,
+ IMPLEMENTATION_MAX_2D_ARRAY_TEXTURE_LAYERS = 2048,
+
+ // 1+log2 of max of MAX_*_TEXTURE_SIZE
+ IMPLEMENTATION_MAX_TEXTURE_LEVELS = 16,
+
+ IMPLEMENTATION_MAX_SHADER_TEXTURES = 32,
+
+ // In ES 3.1 and below, the limit for active textures is 64.
+ IMPLEMENTATION_MAX_ES31_ACTIVE_TEXTURES = 64,
+
+ // In ES 3.2 we need to support a minimum of 96 maximum textures.
+ IMPLEMENTATION_MAX_ACTIVE_TEXTURES = 96,
+ IMPLEMENTATION_MAX_IMAGE_UNITS = IMPLEMENTATION_MAX_ACTIVE_TEXTURES,
+
+ // Maximum number of slots allocated for atomic counter buffers.
+ IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS = 8,
+
+ // Implementation upper limits, real maximums depend on the hardware.
+ IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS = 64,
+
+ // Implementation upper limits of max number of clip distances (minimum required per spec)
+ IMPLEMENTATION_MAX_CLIP_DISTANCES = 8,
+
+ // Implementation upper limit for layered framebuffer layer count
+ IMPLEMENTATION_MAX_FRAMEBUFFER_LAYERS = 256,
+
+ // ANGLE_shader_pixel_local_storage: keep the maximum number of supported planes reasonably
+ // similar on all platforms.
+ IMPLEMENTATION_MAX_PIXEL_LOCAL_STORAGE_PLANES = 8,
+};
+
+namespace limits
+{
+// Almost all drivers use 2048 (the minimum value) as GL_MAX_VERTEX_ATTRIB_STRIDE. ANGLE advertizes
+// the same limit.
+constexpr uint32_t kMaxVertexAttribStride = 2048;
+
+// Some of the minimums required by GL, used to detect if the backend meets the minimum requirement.
+// Currently, there's no need to separate these values per spec version.
+constexpr uint32_t kMinimumComputeStorageBuffers = 4;
+
+// OpenGL ES 3.0+ Minimum Values
+// Table 6.31 MAX_VERTEX_UNIFORM_BLOCKS minimum value = 12
+// Table 6.32 MAX_FRAGMENT_UNIFORM_BLOCKS minimum value = 12
+constexpr uint32_t kMinimumShaderUniformBlocks = 12;
+// Table 6.31 MAX_VERTEX_OUTPUT_COMPONENTS minimum value = 64
+constexpr uint32_t kMinimumVertexOutputComponents = 64;
+
+// OpenGL ES 3.2+ Minimum Values
+// Table 21.42 TEXTURE_BUFFER_OFFSET_ALIGNMENT minimum value = 256
+constexpr uint32_t kMinTextureBufferOffsetAlignment = 256;
+
+} // namespace limits
+
+} // namespace gl
+
+#endif // LIBANGLE_CONSTANTS_H_
diff --git a/gfx/angle/checkout/src/libANGLE/Context.cpp b/gfx/angle/checkout/src/libANGLE/Context.cpp
new file mode 100644
index 0000000000..bfd490ab29
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Context.cpp
@@ -0,0 +1,10472 @@
+//
+// Copyright 2002 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.
+//
+
+// Context.cpp: Implements the gl::Context class, managing all GL state and performing
+// rendering operations. It is the GLES2 specific implementation of EGLContext.
+#include "libANGLE/Context.inl.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <iterator>
+#include <sstream>
+#include <vector>
+
+#include "common/PackedEnums.h"
+#include "common/angle_version_info.h"
+#include "common/matrix_utils.h"
+#include "common/platform.h"
+#include "common/system_utils.h"
+#include "common/utilities.h"
+#include "libANGLE/Buffer.h"
+#include "libANGLE/Compiler.h"
+#include "libANGLE/Display.h"
+#include "libANGLE/Fence.h"
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/MemoryObject.h"
+#include "libANGLE/PixelLocalStorage.h"
+#include "libANGLE/Program.h"
+#include "libANGLE/ProgramPipeline.h"
+#include "libANGLE/Query.h"
+#include "libANGLE/Renderbuffer.h"
+#include "libANGLE/ResourceManager.h"
+#include "libANGLE/Sampler.h"
+#include "libANGLE/Semaphore.h"
+#include "libANGLE/Surface.h"
+#include "libANGLE/Texture.h"
+#include "libANGLE/TransformFeedback.h"
+#include "libANGLE/VertexArray.h"
+#include "libANGLE/capture/FrameCapture.h"
+#include "libANGLE/capture/frame_capture_utils.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/queryconversions.h"
+#include "libANGLE/queryutils.h"
+#include "libANGLE/renderer/DisplayImpl.h"
+#include "libANGLE/renderer/Format.h"
+#include "libANGLE/validationES.h"
+
+#if defined(ANGLE_PLATFORM_APPLE)
+# include <dispatch/dispatch.h>
+# include "common/tls.h"
+#endif
+
+namespace gl
+{
+namespace
+{
+
+egl::ShareGroup *AllocateOrGetShareGroup(egl::Display *display, const gl::Context *shareContext)
+{
+ if (shareContext)
+ {
+ egl::ShareGroup *shareGroup = shareContext->getState().getShareGroup();
+ shareGroup->addRef();
+ return shareGroup;
+ }
+ else
+ {
+ return new egl::ShareGroup(display->getImplementation());
+ }
+}
+
+template <typename T>
+angle::Result GetQueryObjectParameter(const Context *context, Query *query, GLenum pname, T *params)
+{
+ if (!query)
+ {
+ // Some applications call into glGetQueryObjectuiv(...) prior to calling glBeginQuery(...)
+ // This wouldn't be an issue since the validation layer will handle such a usecases but when
+ // the app enables EGL_KHR_create_context_no_error extension, we skip the validation layer.
+ switch (pname)
+ {
+ case GL_QUERY_RESULT_EXT:
+ *params = 0;
+ break;
+ case GL_QUERY_RESULT_AVAILABLE_EXT:
+ *params = GL_FALSE;
+ break;
+ default:
+ UNREACHABLE();
+ return angle::Result::Stop;
+ }
+ return angle::Result::Continue;
+ }
+
+ switch (pname)
+ {
+ case GL_QUERY_RESULT_EXT:
+ return query->getResult(context, params);
+ case GL_QUERY_RESULT_AVAILABLE_EXT:
+ {
+ bool available = false;
+ if (context->isContextLost())
+ {
+ available = true;
+ }
+ else
+ {
+ ANGLE_TRY(query->isResultAvailable(context, &available));
+ }
+ *params = CastFromStateValue<T>(pname, static_cast<GLuint>(available));
+ return angle::Result::Continue;
+ }
+ default:
+ UNREACHABLE();
+ return angle::Result::Stop;
+ }
+}
+
+// Attribute map queries.
+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));
+}
+
+bool GetBackwardCompatibleContext(const egl::AttributeMap &attribs)
+{
+ return attribs.get(EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE, EGL_TRUE) == EGL_TRUE;
+}
+
+bool GetWebGLContext(const egl::AttributeMap &attribs)
+{
+ return (attribs.get(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE, EGL_FALSE) == EGL_TRUE);
+}
+
+Version GetClientVersion(egl::Display *display,
+ const egl::AttributeMap &attribs,
+ const EGLenum clientType)
+{
+ Version requestedVersion =
+ Version(GetClientMajorVersion(attribs), GetClientMinorVersion(attribs));
+ if (GetBackwardCompatibleContext(attribs))
+ {
+ if (clientType == EGL_OPENGL_API)
+ {
+ Optional<gl::Version> maxSupportedDesktopVersion =
+ display->getImplementation()->getMaxSupportedDesktopVersion();
+ if (maxSupportedDesktopVersion.valid())
+ return std::max(maxSupportedDesktopVersion.value(), requestedVersion);
+ else
+ return requestedVersion;
+ }
+ else if (requestedVersion.major == 1)
+ {
+ // If the user requests an ES1 context, we cannot return an ES 2+ context.
+ return Version(1, 1);
+ }
+ else
+ {
+ // Always up the version to at least the max conformant version this display supports.
+ // Only return a higher client version if requested.
+ const Version conformantVersion = std::max(
+ display->getImplementation()->getMaxConformantESVersion(), requestedVersion);
+ // Limit the WebGL context to at most version 3.1
+ const bool isWebGL = GetWebGLContext(attribs);
+ return isWebGL ? std::min(conformantVersion, Version(3, 1)) : conformantVersion;
+ }
+ }
+ else
+ {
+ return requestedVersion;
+ }
+}
+
+EGLint GetProfileMask(const egl::AttributeMap &attribs)
+{
+ return attribs.getAsInt(EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT);
+}
+
+GLenum GetResetStrategy(const egl::AttributeMap &attribs)
+{
+ EGLAttrib resetStrategyExt =
+ attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_NO_RESET_NOTIFICATION);
+ EGLAttrib resetStrategyCore =
+ attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY, resetStrategyExt);
+
+ switch (resetStrategyCore)
+ {
+ case EGL_NO_RESET_NOTIFICATION:
+ return GL_NO_RESET_NOTIFICATION_EXT;
+ case EGL_LOSE_CONTEXT_ON_RESET:
+ return GL_LOSE_CONTEXT_ON_RESET_EXT;
+ default:
+ UNREACHABLE();
+ return GL_NONE;
+ }
+}
+
+bool GetRobustAccess(const egl::AttributeMap &attribs)
+{
+ EGLAttrib robustAccessExt = attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE);
+ EGLAttrib robustAccessCore = attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS, robustAccessExt);
+
+ bool attribRobustAccess = (robustAccessCore == EGL_TRUE);
+ bool contextFlagsRobustAccess =
+ ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) != 0);
+
+ return (attribRobustAccess || contextFlagsRobustAccess);
+}
+
+bool GetDebug(const egl::AttributeMap &attribs)
+{
+ return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE) ||
+ ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) != 0);
+}
+
+bool GetNoError(const egl::AttributeMap &attribs)
+{
+ return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
+}
+
+bool GetExtensionsEnabled(const egl::AttributeMap &attribs, bool webGLContext)
+{
+ // If the context is WebGL, extensions are disabled by default
+ EGLAttrib defaultValue = webGLContext ? EGL_FALSE : EGL_TRUE;
+ return (attribs.get(EGL_EXTENSIONS_ENABLED_ANGLE, defaultValue) == EGL_TRUE);
+}
+
+bool GetBindGeneratesResource(const egl::AttributeMap &attribs)
+{
+ return (attribs.get(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE) == EGL_TRUE);
+}
+
+bool GetClientArraysEnabled(const egl::AttributeMap &attribs)
+{
+ return (attribs.get(EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE, EGL_TRUE) == EGL_TRUE);
+}
+
+bool GetRobustResourceInit(egl::Display *display, const egl::AttributeMap &attribs)
+{
+ const angle::FrontendFeatures &frontendFeatures = display->getFrontendFeatures();
+ return (frontendFeatures.forceRobustResourceInit.enabled ||
+ attribs.get(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE, EGL_FALSE) == EGL_TRUE);
+}
+
+EGLenum GetContextPriority(const egl::AttributeMap &attribs)
+{
+ return static_cast<EGLenum>(
+ attribs.getAsInt(EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_MEDIUM_IMG));
+}
+
+bool GetProtectedContent(const egl::AttributeMap &attribs)
+{
+ return static_cast<bool>(attribs.getAsInt(EGL_PROTECTED_CONTENT_EXT, EGL_FALSE));
+}
+
+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);
+ }
+}
+
+enum SubjectIndexes : angle::SubjectIndex
+{
+ kTexture0SubjectIndex = 0,
+ kTextureMaxSubjectIndex = kTexture0SubjectIndex + IMPLEMENTATION_MAX_ACTIVE_TEXTURES,
+ kImage0SubjectIndex = kTextureMaxSubjectIndex,
+ kImageMaxSubjectIndex = kImage0SubjectIndex + IMPLEMENTATION_MAX_IMAGE_UNITS,
+ kUniformBuffer0SubjectIndex = kImageMaxSubjectIndex,
+ kUniformBufferMaxSubjectIndex =
+ kUniformBuffer0SubjectIndex + IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS,
+ kAtomicCounterBuffer0SubjectIndex = kUniformBufferMaxSubjectIndex,
+ kAtomicCounterBufferMaxSubjectIndex =
+ kAtomicCounterBuffer0SubjectIndex + IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS,
+ kShaderStorageBuffer0SubjectIndex = kAtomicCounterBufferMaxSubjectIndex,
+ kShaderStorageBufferMaxSubjectIndex =
+ kShaderStorageBuffer0SubjectIndex + IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS,
+ kSampler0SubjectIndex = kShaderStorageBufferMaxSubjectIndex,
+ kSamplerMaxSubjectIndex = kSampler0SubjectIndex + IMPLEMENTATION_MAX_ACTIVE_TEXTURES,
+ kVertexArraySubjectIndex = kSamplerMaxSubjectIndex,
+ kReadFramebufferSubjectIndex,
+ kDrawFramebufferSubjectIndex,
+ kProgramPipelineSubjectIndex,
+};
+
+bool IsClearBufferEnabled(const FramebufferState &fbState, GLenum buffer, GLint drawbuffer)
+{
+ return buffer != GL_COLOR || fbState.getEnabledDrawBuffers()[drawbuffer];
+}
+
+bool IsEmptyScissor(const State &glState)
+{
+ if (!glState.isScissorTestEnabled())
+ {
+ return false;
+ }
+
+ const Extents &dimensions = glState.getDrawFramebuffer()->getExtents();
+ Rectangle framebufferArea(0, 0, dimensions.width, dimensions.height);
+ return !ClipRectangle(framebufferArea, glState.getScissor(), nullptr);
+}
+
+bool IsColorMaskedOut(const BlendStateExt &blendStateExt, const GLint drawbuffer)
+{
+ ASSERT(static_cast<size_t>(drawbuffer) < blendStateExt.getDrawBufferCount());
+ return blendStateExt.getColorMaskIndexed(static_cast<size_t>(drawbuffer)) == 0;
+}
+
+bool GetIsExternal(const egl::AttributeMap &attribs)
+{
+ return (attribs.get(EGL_EXTERNAL_CONTEXT_ANGLE, EGL_FALSE) == EGL_TRUE);
+}
+
+bool GetSaveAndRestoreState(const egl::AttributeMap &attribs)
+{
+ return (attribs.get(EGL_EXTERNAL_CONTEXT_SAVE_STATE_ANGLE, EGL_FALSE) == EGL_TRUE);
+}
+
+void GetPerfMonitorString(const std::string &name,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *stringOut)
+{
+ GLsizei numCharsWritten = std::min(bufSize, static_cast<GLsizei>(name.size()));
+
+ if (length)
+ {
+ if (bufSize == 0)
+ {
+ *length = static_cast<GLsizei>(name.size());
+ }
+ else
+ {
+ // Excludes null terminator.
+ ASSERT(numCharsWritten > 0);
+ *length = numCharsWritten - 1;
+ }
+ }
+
+ if (stringOut)
+ {
+ memcpy(stringOut, name.c_str(), numCharsWritten);
+ }
+}
+
+bool CanSupportAEP(const gl::Version &version, const gl::Extensions &extensions)
+{
+ // From the GL_ANDROID_extension_pack_es31a extension spec:
+ // OpenGL ES 3.1 and GLSL ES 3.10 are required.
+ // The following extensions are required:
+ // * KHR_debug
+ // * KHR_texture_compression_astc_ldr
+ // * KHR_blend_equation_advanced
+ // * OES_sample_shading
+ // * OES_sample_variables
+ // * OES_shader_image_atomic
+ // * OES_shader_multisample_interpolation
+ // * OES_texture_stencil8
+ // * OES_texture_storage_multisample_2d_array
+ // * EXT_copy_image
+ // * EXT_draw_buffers_indexed
+ // * EXT_geometry_shader
+ // * EXT_gpu_shader5
+ // * EXT_primitive_bounding_box
+ // * EXT_shader_io_blocks
+ // * EXT_tessellation_shader
+ // * EXT_texture_border_clamp
+ // * EXT_texture_buffer
+ // * EXT_texture_cube_map_array
+ // * EXT_texture_sRGB_decode
+ return (version >= ES_3_1 && extensions.debugKHR && extensions.textureCompressionAstcLdrKHR &&
+ extensions.blendEquationAdvancedKHR && extensions.sampleShadingOES &&
+ extensions.sampleVariablesOES && extensions.shaderImageAtomicOES &&
+ extensions.shaderMultisampleInterpolationOES && extensions.textureStencil8OES &&
+ extensions.textureStorageMultisample2dArrayOES && extensions.copyImageEXT &&
+ extensions.drawBuffersIndexedEXT && extensions.geometryShaderEXT &&
+ extensions.gpuShader5EXT && extensions.primitiveBoundingBoxEXT &&
+ extensions.shaderIoBlocksEXT && extensions.tessellationShaderEXT &&
+ extensions.textureBorderClampEXT && extensions.textureBufferEXT &&
+ extensions.textureCubeMapArrayEXT && extensions.textureSRGBDecodeEXT);
+}
+} // anonymous namespace
+
+#if defined(ANGLE_PLATFORM_APPLE)
+// TODO(angleproject:6479): Due to a bug in Apple's dyld loader, `thread_local` will cause
+// excessive memory use. Temporarily avoid it by using pthread's thread
+// local storage instead.
+static TLSIndex GetCurrentValidContextTLSIndex()
+{
+ static TLSIndex CurrentValidContextIndex = TLS_INVALID_INDEX;
+ static dispatch_once_t once;
+ dispatch_once(&once, ^{
+ ASSERT(CurrentValidContextIndex == TLS_INVALID_INDEX);
+ CurrentValidContextIndex = CreateTLSIndex(nullptr);
+ });
+ return CurrentValidContextIndex;
+}
+Context *GetCurrentValidContextTLS()
+{
+ TLSIndex CurrentValidContextIndex = GetCurrentValidContextTLSIndex();
+ ASSERT(CurrentValidContextIndex != TLS_INVALID_INDEX);
+ return static_cast<Context *>(GetTLSValue(CurrentValidContextIndex));
+}
+void SetCurrentValidContextTLS(Context *context)
+{
+ TLSIndex CurrentValidContextIndex = GetCurrentValidContextTLSIndex();
+ ASSERT(CurrentValidContextIndex != TLS_INVALID_INDEX);
+ SetTLSValue(CurrentValidContextIndex, context);
+}
+#else
+thread_local Context *gCurrentValidContext = nullptr;
+#endif
+
+Context::Context(egl::Display *display,
+ const egl::Config *config,
+ const Context *shareContext,
+ TextureManager *shareTextures,
+ SemaphoreManager *shareSemaphores,
+ MemoryProgramCache *memoryProgramCache,
+ MemoryShaderCache *memoryShaderCache,
+ const EGLenum clientType,
+ const egl::AttributeMap &attribs,
+ const egl::DisplayExtensions &displayExtensions,
+ const egl::ClientExtensions &clientExtensions)
+ : mState(shareContext ? &shareContext->mState : nullptr,
+ AllocateOrGetShareGroup(display, shareContext),
+ shareTextures,
+ shareSemaphores,
+ &mOverlay,
+ clientType,
+ GetClientVersion(display, attribs, clientType),
+ GetProfileMask(attribs),
+ GetDebug(attribs),
+ GetBindGeneratesResource(attribs),
+ GetClientArraysEnabled(attribs),
+ GetRobustResourceInit(display, attribs),
+ memoryProgramCache != nullptr,
+ GetContextPriority(attribs),
+ GetRobustAccess(attribs),
+ GetProtectedContent(attribs)),
+ mShared(shareContext != nullptr || shareTextures != nullptr || shareSemaphores != nullptr),
+ mSkipValidation(GetNoError(attribs)),
+ mDisplayTextureShareGroup(shareTextures != nullptr),
+ mDisplaySemaphoreShareGroup(shareSemaphores != nullptr),
+ mErrors(this),
+ mImplementation(display->getImplementation()
+ ->createContext(mState, &mErrors, config, shareContext, attribs)),
+ mLabel(nullptr),
+ mCompiler(),
+ mConfig(config),
+ mHasBeenCurrent(false),
+ mContextLost(false),
+ mResetStatus(GraphicsResetStatus::NoError),
+ mContextLostForced(false),
+ mResetStrategy(GetResetStrategy(attribs)),
+ mSurfacelessSupported(displayExtensions.surfacelessContext),
+ mCurrentDrawSurface(static_cast<egl::Surface *>(EGL_NO_SURFACE)),
+ mCurrentReadSurface(static_cast<egl::Surface *>(EGL_NO_SURFACE)),
+ mDisplay(display),
+ mWebGLContext(GetWebGLContext(attribs)),
+ mBufferAccessValidationEnabled(false),
+ mExtensionsEnabled(GetExtensionsEnabled(attribs, mWebGLContext)),
+ mMemoryProgramCache(memoryProgramCache),
+ mMemoryShaderCache(memoryShaderCache),
+ mVertexArrayObserverBinding(this, kVertexArraySubjectIndex),
+ mDrawFramebufferObserverBinding(this, kDrawFramebufferSubjectIndex),
+ mReadFramebufferObserverBinding(this, kReadFramebufferSubjectIndex),
+ mProgramPipelineObserverBinding(this, kProgramPipelineSubjectIndex),
+ mSingleThreadPool(nullptr),
+ mMultiThreadPool(nullptr),
+ mFrameCapture(new angle::FrameCapture),
+ mRefCount(0),
+ mOverlay(mImplementation.get()),
+ mIsExternal(GetIsExternal(attribs)),
+ mSaveAndRestoreState(GetSaveAndRestoreState(attribs)),
+ mIsDestroyed(false)
+{
+ for (angle::SubjectIndex uboIndex = kUniformBuffer0SubjectIndex;
+ uboIndex < kUniformBufferMaxSubjectIndex; ++uboIndex)
+ {
+ mUniformBufferObserverBindings.emplace_back(this, uboIndex);
+ }
+
+ for (angle::SubjectIndex acbIndex = kAtomicCounterBuffer0SubjectIndex;
+ acbIndex < kAtomicCounterBufferMaxSubjectIndex; ++acbIndex)
+ {
+ mAtomicCounterBufferObserverBindings.emplace_back(this, acbIndex);
+ }
+
+ for (angle::SubjectIndex ssboIndex = kShaderStorageBuffer0SubjectIndex;
+ ssboIndex < kShaderStorageBufferMaxSubjectIndex; ++ssboIndex)
+ {
+ mShaderStorageBufferObserverBindings.emplace_back(this, ssboIndex);
+ }
+
+ for (angle::SubjectIndex samplerIndex = kSampler0SubjectIndex;
+ samplerIndex < kSamplerMaxSubjectIndex; ++samplerIndex)
+ {
+ mSamplerObserverBindings.emplace_back(this, samplerIndex);
+ }
+
+ for (angle::SubjectIndex imageIndex = kImage0SubjectIndex; imageIndex < kImageMaxSubjectIndex;
+ ++imageIndex)
+ {
+ mImageObserverBindings.emplace_back(this, imageIndex);
+ }
+
+ // Implementations now require the display to be set at context creation.
+ ASSERT(mDisplay);
+}
+
+egl::Error Context::initialize()
+{
+ if (!mImplementation)
+ return egl::Error(EGL_NOT_INITIALIZED, "native context creation failed");
+ return egl::NoError();
+}
+
+void Context::initializeDefaultResources()
+{
+ mImplementation->setMemoryProgramCache(mMemoryProgramCache);
+
+ initCaps();
+
+ mState.initialize(this);
+
+ mDefaultFramebuffer = std::make_unique<Framebuffer>(this, mImplementation.get());
+
+ mFenceNVHandleAllocator.setBaseHandle(0);
+
+ // [OpenGL ES 2.0.24] section 3.7 page 83:
+ // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have two-dimensional
+ // and cube map texture state vectors respectively associated with them.
+ // In order that access to these initial textures not be lost, they are treated as texture
+ // objects all of whose names are 0.
+
+ Texture *zeroTexture2D = new Texture(mImplementation.get(), {0}, TextureType::_2D);
+ mZeroTextures[TextureType::_2D].set(this, zeroTexture2D);
+
+ Texture *zeroTextureCube = new Texture(mImplementation.get(), {0}, TextureType::CubeMap);
+ mZeroTextures[TextureType::CubeMap].set(this, zeroTextureCube);
+
+ if (getClientVersion() >= Version(3, 0) || mSupportedExtensions.texture3DOES)
+ {
+ Texture *zeroTexture3D = new Texture(mImplementation.get(), {0}, TextureType::_3D);
+ mZeroTextures[TextureType::_3D].set(this, zeroTexture3D);
+ }
+ if (getClientVersion() >= Version(3, 0))
+ {
+ Texture *zeroTexture2DArray =
+ new Texture(mImplementation.get(), {0}, TextureType::_2DArray);
+ mZeroTextures[TextureType::_2DArray].set(this, zeroTexture2DArray);
+ }
+ if (getClientVersion() >= Version(3, 1) || mSupportedExtensions.textureMultisampleANGLE)
+ {
+ Texture *zeroTexture2DMultisample =
+ new Texture(mImplementation.get(), {0}, TextureType::_2DMultisample);
+ mZeroTextures[TextureType::_2DMultisample].set(this, zeroTexture2DMultisample);
+ }
+ if (getClientVersion() >= Version(3, 1))
+ {
+ Texture *zeroTexture2DMultisampleArray =
+ new Texture(mImplementation.get(), {0}, TextureType::_2DMultisampleArray);
+ mZeroTextures[TextureType::_2DMultisampleArray].set(this, zeroTexture2DMultisampleArray);
+
+ for (int i = 0; i < mState.mCaps.maxAtomicCounterBufferBindings; i++)
+ {
+ bindBufferRange(BufferBinding::AtomicCounter, i, {0}, 0, 0);
+ }
+
+ for (int i = 0; i < mState.mCaps.maxShaderStorageBufferBindings; i++)
+ {
+ bindBufferRange(BufferBinding::ShaderStorage, i, {0}, 0, 0);
+ }
+ }
+
+ if ((getClientType() != EGL_OPENGL_API && getClientVersion() >= Version(3, 2)) ||
+ mSupportedExtensions.textureCubeMapArrayAny())
+ {
+ Texture *zeroTextureCubeMapArray =
+ new Texture(mImplementation.get(), {0}, TextureType::CubeMapArray);
+ mZeroTextures[TextureType::CubeMapArray].set(this, zeroTextureCubeMapArray);
+ }
+
+ if ((getClientType() != EGL_OPENGL_API && getClientVersion() >= Version(3, 2)) ||
+ mSupportedExtensions.textureBufferAny())
+ {
+ Texture *zeroTextureBuffer = new Texture(mImplementation.get(), {0}, TextureType::Buffer);
+ mZeroTextures[TextureType::Buffer].set(this, zeroTextureBuffer);
+ }
+
+ if (mSupportedExtensions.textureRectangleANGLE)
+ {
+ Texture *zeroTextureRectangle =
+ new Texture(mImplementation.get(), {0}, TextureType::Rectangle);
+ mZeroTextures[TextureType::Rectangle].set(this, zeroTextureRectangle);
+ }
+
+ if (mSupportedExtensions.EGLImageExternalOES ||
+ mSupportedExtensions.EGLStreamConsumerExternalNV)
+ {
+ Texture *zeroTextureExternal =
+ new Texture(mImplementation.get(), {0}, TextureType::External);
+ mZeroTextures[TextureType::External].set(this, zeroTextureExternal);
+ }
+
+ // This may change native TEXTURE_2D, TEXTURE_EXTERNAL_OES and TEXTURE_RECTANGLE,
+ // binding states. Ensure state manager is aware of this when binding
+ // this texture type.
+ if (mSupportedExtensions.videoTextureWEBGL)
+ {
+ Texture *zeroTextureVideoImage =
+ new Texture(mImplementation.get(), {0}, TextureType::VideoImage);
+ mZeroTextures[TextureType::VideoImage].set(this, zeroTextureVideoImage);
+ }
+
+ mState.initializeZeroTextures(this, mZeroTextures);
+
+ ANGLE_CONTEXT_TRY(mImplementation->initialize());
+
+ // Add context into the share group
+ mState.getShareGroup()->addSharedContext(this);
+
+ bindVertexArray({0});
+
+ if (getClientVersion() >= Version(3, 0))
+ {
+ // [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
+ // a transform feedback object with a name of zero. That object is bound any time
+ // BindTransformFeedback is called with id of zero
+ bindTransformFeedback(GL_TRANSFORM_FEEDBACK, {0});
+ }
+
+ for (auto type : angle::AllEnums<BufferBinding>())
+ {
+ bindBuffer(type, {0});
+ }
+
+ bindRenderbuffer(GL_RENDERBUFFER, {0});
+
+ for (int i = 0; i < mState.mCaps.maxUniformBufferBindings; i++)
+ {
+ bindBufferRange(BufferBinding::Uniform, i, {0}, 0, -1);
+ }
+
+ // Initialize GLES1 renderer if appropriate.
+ if (getClientVersion() < Version(2, 0))
+ {
+ mGLES1Renderer.reset(new GLES1Renderer());
+ }
+
+ // Initialize dirty bit masks
+ mAllDirtyBits.set();
+
+ mDrawDirtyObjects.set(State::DIRTY_OBJECT_ACTIVE_TEXTURES);
+ mDrawDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
+ mDrawDirtyObjects.set(State::DIRTY_OBJECT_VERTEX_ARRAY);
+ mDrawDirtyObjects.set(State::DIRTY_OBJECT_TEXTURES);
+ mDrawDirtyObjects.set(State::DIRTY_OBJECT_PROGRAM);
+ mDrawDirtyObjects.set(State::DIRTY_OBJECT_PROGRAM_PIPELINE_OBJECT);
+ mDrawDirtyObjects.set(State::DIRTY_OBJECT_SAMPLERS);
+ mDrawDirtyObjects.set(State::DIRTY_OBJECT_IMAGES);
+
+ mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_STATE);
+ mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
+ mTexImageDirtyBits.set(State::DIRTY_BIT_EXTENDED);
+ // No dirty objects.
+
+ // Readpixels uses the pack state and read FBO
+ mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_STATE);
+ mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
+ mReadPixelsDirtyBits.set(State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
+ mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
+
+ mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
+ mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
+ mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
+ mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
+ mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
+ mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
+ mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
+ mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
+ mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
+ mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
+ mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
+ mClearDirtyBits.set(State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
+ mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
+
+ // We sync the draw Framebuffer manually in prepareForClear to allow the clear calls to do
+ // more custom handling for robust resource init.
+
+ mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
+ mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
+ mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB_WRITE_CONTROL_MODE);
+ mBlitDirtyBits.set(State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
+ mBlitDirtyBits.set(State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
+ mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
+ mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
+
+ mComputeDirtyBits.set(State::DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING);
+ mComputeDirtyBits.set(State::DIRTY_BIT_UNIFORM_BUFFER_BINDINGS);
+ mComputeDirtyBits.set(State::DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING);
+ mComputeDirtyBits.set(State::DIRTY_BIT_PROGRAM_BINDING);
+ mComputeDirtyBits.set(State::DIRTY_BIT_PROGRAM_EXECUTABLE);
+ mComputeDirtyBits.set(State::DIRTY_BIT_TEXTURE_BINDINGS);
+ mComputeDirtyBits.set(State::DIRTY_BIT_SAMPLER_BINDINGS);
+ mComputeDirtyBits.set(State::DIRTY_BIT_IMAGE_BINDINGS);
+ mComputeDirtyBits.set(State::DIRTY_BIT_DISPATCH_INDIRECT_BUFFER_BINDING);
+ mComputeDirtyObjects.set(State::DIRTY_OBJECT_ACTIVE_TEXTURES);
+ mComputeDirtyObjects.set(State::DIRTY_OBJECT_TEXTURES);
+ mComputeDirtyObjects.set(State::DIRTY_OBJECT_PROGRAM);
+ mComputeDirtyObjects.set(State::DIRTY_OBJECT_PROGRAM_PIPELINE_OBJECT);
+ mComputeDirtyObjects.set(State::DIRTY_OBJECT_IMAGES);
+ mComputeDirtyObjects.set(State::DIRTY_OBJECT_SAMPLERS);
+
+ mCopyImageDirtyBits.set(State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
+ mCopyImageDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
+
+ mReadInvalidateDirtyBits.set(State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
+ mDrawInvalidateDirtyBits.set(State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
+
+ mOverlay.init();
+}
+
+egl::Error Context::onDestroy(const egl::Display *display)
+{
+ if (!mHasBeenCurrent)
+ {
+ // The context is never current, so default resources are not allocated.
+ return egl::NoError();
+ }
+
+ // eglDestoryContext() must have been called for this Context and there must not be any Threads
+ // that still have it current.
+ ASSERT(mIsDestroyed == true && mRefCount == 0);
+
+ // Dump frame capture if enabled.
+ getShareGroup()->getFrameCaptureShared()->onDestroyContext(this);
+
+ // Remove context from the capture share group
+ getShareGroup()->removeSharedContext(this);
+
+ if (mGLES1Renderer)
+ {
+ mGLES1Renderer->onDestroy(this, &mState);
+ }
+
+ ANGLE_TRY(unMakeCurrent(display));
+
+ mDefaultFramebuffer->onDestroy(this);
+ mDefaultFramebuffer.reset();
+
+ for (auto fence : mFenceNVMap)
+ {
+ if (fence.second)
+ {
+ fence.second->onDestroy(this);
+ }
+ SafeDelete(fence.second);
+ }
+ mFenceNVMap.clear();
+
+ for (auto query : mQueryMap)
+ {
+ if (query.second != nullptr)
+ {
+ query.second->release(this);
+ }
+ }
+ mQueryMap.clear();
+
+ for (auto vertexArray : mVertexArrayMap)
+ {
+ if (vertexArray.second)
+ {
+ vertexArray.second->onDestroy(this);
+ }
+ }
+ mVertexArrayMap.clear();
+
+ for (auto transformFeedback : mTransformFeedbackMap)
+ {
+ if (transformFeedback.second != nullptr)
+ {
+ transformFeedback.second->release(this);
+ }
+ }
+ mTransformFeedbackMap.clear();
+
+ for (BindingPointer<Texture> &zeroTexture : mZeroTextures)
+ {
+ if (zeroTexture.get() != nullptr)
+ {
+ zeroTexture.set(this, nullptr);
+ }
+ }
+
+ releaseShaderCompiler();
+
+ mState.reset(this);
+
+ mState.mBufferManager->release(this);
+ // mProgramPipelineManager must be before mShaderProgramManager to give each
+ // PPO the chance to release any references they have to the Programs that
+ // are bound to them before the Programs are released()'ed.
+ mState.mProgramPipelineManager->release(this);
+ mState.mShaderProgramManager->release(this);
+ mState.mTextureManager->release(this);
+ mState.mRenderbufferManager->release(this);
+ mState.mSamplerManager->release(this);
+ mState.mSyncManager->release(this);
+ mState.mFramebufferManager->release(this);
+ mState.mMemoryObjectManager->release(this);
+ mState.mSemaphoreManager->release(this);
+
+ mSingleThreadPool.reset();
+ mMultiThreadPool.reset();
+
+ mImplementation->onDestroy(this);
+
+ // Backend requires implementation to be destroyed first to close down all the objects
+ mState.mShareGroup->release(display);
+
+ mOverlay.destroy(this);
+
+ return egl::NoError();
+}
+
+Context::~Context() {}
+
+void Context::setLabel(EGLLabelKHR label)
+{
+ mLabel = label;
+}
+
+EGLLabelKHR Context::getLabel() const
+{
+ return mLabel;
+}
+
+egl::Error Context::makeCurrent(egl::Display *display,
+ egl::Surface *drawSurface,
+ egl::Surface *readSurface)
+{
+ mDisplay = display;
+
+ if (!mHasBeenCurrent)
+ {
+ initializeDefaultResources();
+ initRendererString();
+ initVersionStrings();
+ initExtensionStrings();
+
+ int width = 0;
+ int height = 0;
+ if (drawSurface != nullptr)
+ {
+ width = drawSurface->getWidth();
+ height = drawSurface->getHeight();
+ }
+
+ mState.setViewportParams(0, 0, width, height);
+ mState.setScissorParams(0, 0, width, height);
+
+ mHasBeenCurrent = true;
+ }
+
+ ANGLE_TRY(unsetDefaultFramebuffer());
+
+ getShareGroup()->getFrameCaptureShared()->onMakeCurrent(this, drawSurface);
+
+ // TODO(jmadill): Rework this when we support ContextImpl
+ mState.setAllDirtyBits();
+ mState.setAllDirtyObjects();
+
+ ANGLE_TRY(setDefaultFramebuffer(drawSurface, readSurface));
+
+ // Notify the renderer of a context switch.
+ angle::Result implResult = mImplementation->onMakeCurrent(this);
+
+ // If the implementation fails onMakeCurrent, unset the default framebuffer.
+ if (implResult != angle::Result::Continue)
+ {
+ ANGLE_TRY(unsetDefaultFramebuffer());
+ return angle::ResultToEGL(implResult);
+ }
+
+ return egl::NoError();
+}
+
+egl::Error Context::unMakeCurrent(const egl::Display *display)
+{
+ ANGLE_TRY(angle::ResultToEGL(mImplementation->onUnMakeCurrent(this)));
+
+ ANGLE_TRY(unsetDefaultFramebuffer());
+
+ // Return the scratch buffers to the display so they can be shared with other contexts while
+ // this one is not current.
+ if (mScratchBuffer.valid())
+ {
+ mDisplay->returnScratchBuffer(mScratchBuffer.release());
+ }
+ if (mZeroFilledBuffer.valid())
+ {
+ mDisplay->returnZeroFilledBuffer(mZeroFilledBuffer.release());
+ }
+
+ return egl::NoError();
+}
+
+BufferID Context::createBuffer()
+{
+ return mState.mBufferManager->createBuffer();
+}
+
+GLuint Context::createProgram()
+{
+ return mState.mShaderProgramManager->createProgram(mImplementation.get()).value;
+}
+
+GLuint Context::createShader(ShaderType type)
+{
+ return mState.mShaderProgramManager
+ ->createShader(mImplementation.get(), mState.mLimitations, type)
+ .value;
+}
+
+TextureID Context::createTexture()
+{
+ return mState.mTextureManager->createTexture();
+}
+
+RenderbufferID Context::createRenderbuffer()
+{
+ return mState.mRenderbufferManager->createRenderbuffer();
+}
+
+// Returns an unused framebuffer name
+FramebufferID Context::createFramebuffer()
+{
+ return mState.mFramebufferManager->createFramebuffer();
+}
+
+void Context::genFencesNV(GLsizei n, FenceNVID *fences)
+{
+ for (int i = 0; i < n; i++)
+ {
+ GLuint handle = mFenceNVHandleAllocator.allocate();
+ mFenceNVMap.assign({handle}, new FenceNV(mImplementation.get()));
+ fences[i] = {handle};
+ }
+}
+
+ProgramPipelineID Context::createProgramPipeline()
+{
+ return mState.mProgramPipelineManager->createProgramPipeline();
+}
+
+GLuint Context::createShaderProgramv(ShaderType type, GLsizei count, const GLchar *const *strings)
+{
+ const ShaderProgramID shaderID = PackParam<ShaderProgramID>(createShader(type));
+ if (shaderID.value)
+ {
+ Shader *shaderObject = getShader(shaderID);
+ ASSERT(shaderObject);
+ shaderObject->setSource(count, strings, nullptr);
+ shaderObject->compile(this);
+ const ShaderProgramID programID = PackParam<ShaderProgramID>(createProgram());
+ if (programID.value)
+ {
+ gl::Program *programObject = getProgramNoResolveLink(programID);
+ ASSERT(programObject);
+
+ if (shaderObject->isCompiled(this))
+ {
+ // As per Khronos issue 2261:
+ // https://gitlab.khronos.org/Tracker/vk-gl-cts/issues/2261
+ // We must wait to mark the program separable until it's successfully compiled.
+ programObject->setSeparable(true);
+
+ programObject->attachShader(shaderObject);
+
+ if (programObject->link(this) != angle::Result::Continue)
+ {
+ deleteShader(shaderID);
+ deleteProgram(programID);
+ return 0u;
+ }
+ if (onProgramLink(programObject) != angle::Result::Continue)
+ {
+ deleteShader(shaderID);
+ deleteProgram(programID);
+ return 0u;
+ }
+
+ programObject->detachShader(this, shaderObject);
+ }
+
+ InfoLog &programInfoLog = programObject->getExecutable().getInfoLog();
+ programInfoLog << shaderObject->getInfoLogString();
+ }
+
+ deleteShader(shaderID);
+
+ return programID.value;
+ }
+
+ return 0u;
+}
+
+MemoryObjectID Context::createMemoryObject()
+{
+ return mState.mMemoryObjectManager->createMemoryObject(mImplementation.get());
+}
+
+SemaphoreID Context::createSemaphore()
+{
+ return mState.mSemaphoreManager->createSemaphore(mImplementation.get());
+}
+
+void Context::deleteBuffer(BufferID bufferName)
+{
+ Buffer *buffer = mState.mBufferManager->getBuffer(bufferName);
+ if (buffer)
+ {
+ detachBuffer(buffer);
+ }
+
+ mState.mBufferManager->deleteObject(this, bufferName);
+}
+
+void Context::deleteShader(ShaderProgramID shader)
+{
+ mState.mShaderProgramManager->deleteShader(this, shader);
+}
+
+void Context::deleteProgram(ShaderProgramID program)
+{
+ mState.mShaderProgramManager->deleteProgram(this, program);
+}
+
+void Context::deleteTexture(TextureID texture)
+{
+ if (mState.mTextureManager->getTexture(texture))
+ {
+ detachTexture(texture);
+ }
+
+ mState.mTextureManager->deleteObject(this, texture);
+}
+
+void Context::deleteRenderbuffer(RenderbufferID renderbuffer)
+{
+ if (mState.mRenderbufferManager->getRenderbuffer(renderbuffer))
+ {
+ detachRenderbuffer(renderbuffer);
+ }
+
+ mState.mRenderbufferManager->deleteObject(this, renderbuffer);
+}
+
+void Context::deleteSync(GLsync sync)
+{
+ // The spec specifies the underlying Fence object is not deleted until all current
+ // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
+ // and since our API is currently designed for being called from a single thread, we can delete
+ // the fence immediately.
+ mState.mSyncManager->deleteObject(this, static_cast<GLuint>(reinterpret_cast<uintptr_t>(sync)));
+}
+
+void Context::deleteProgramPipeline(ProgramPipelineID pipelineID)
+{
+ ProgramPipeline *pipeline = mState.mProgramPipelineManager->getProgramPipeline(pipelineID);
+ if (pipeline)
+ {
+ detachProgramPipeline(pipelineID);
+ }
+
+ mState.mProgramPipelineManager->deleteObject(this, pipelineID);
+}
+
+void Context::deleteMemoryObject(MemoryObjectID memoryObject)
+{
+ mState.mMemoryObjectManager->deleteMemoryObject(this, memoryObject);
+}
+
+void Context::deleteSemaphore(SemaphoreID semaphore)
+{
+ mState.mSemaphoreManager->deleteSemaphore(this, semaphore);
+}
+
+// GL_CHROMIUM_lose_context
+void Context::loseContext(GraphicsResetStatus current, GraphicsResetStatus other)
+{
+ // TODO(geofflang): mark the rest of the share group lost. Requires access to the entire share
+ // group from a context. http://anglebug.com/3379
+ markContextLost(current);
+}
+
+void Context::deleteFramebuffer(FramebufferID framebufferID)
+{
+ // We are responsible for deleting the GL objects from the Framebuffer's pixel local storage.
+ std::unique_ptr<PixelLocalStorage> plsToDelete;
+
+ Framebuffer *framebuffer = mState.mFramebufferManager->getFramebuffer(framebufferID);
+ if (framebuffer)
+ {
+ plsToDelete = framebuffer->detachPixelLocalStorage();
+ detachFramebuffer(framebufferID);
+ }
+
+ mState.mFramebufferManager->deleteObject(this, framebufferID);
+
+ // Delete the pixel local storage GL objects after the framebuffer, in order to avoid any
+ // potential trickyness with orphaning.
+ if (plsToDelete)
+ {
+ plsToDelete->deleteContextObjects(this);
+ }
+}
+
+void Context::deleteFencesNV(GLsizei n, const FenceNVID *fences)
+{
+ for (int i = 0; i < n; i++)
+ {
+ FenceNVID fence = fences[i];
+
+ FenceNV *fenceObject = nullptr;
+ if (mFenceNVMap.erase(fence, &fenceObject))
+ {
+ mFenceNVHandleAllocator.release(fence.value);
+ if (fenceObject)
+ {
+ fenceObject->onDestroy(this);
+ }
+ delete fenceObject;
+ }
+ }
+}
+
+Buffer *Context::getBuffer(BufferID handle) const
+{
+ return mState.mBufferManager->getBuffer(handle);
+}
+
+Renderbuffer *Context::getRenderbuffer(RenderbufferID handle) const
+{
+ return mState.mRenderbufferManager->getRenderbuffer(handle);
+}
+
+EGLenum Context::getContextPriority() const
+{
+ return egl::ToEGLenum(mImplementation->getContextPriority());
+}
+
+Sync *Context::getSync(GLsync handle) const
+{
+ return mState.mSyncManager->getSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
+}
+
+VertexArray *Context::getVertexArray(VertexArrayID handle) const
+{
+ return mVertexArrayMap.query(handle);
+}
+
+Sampler *Context::getSampler(SamplerID handle) const
+{
+ return mState.mSamplerManager->getSampler(handle);
+}
+
+TransformFeedback *Context::getTransformFeedback(TransformFeedbackID handle) const
+{
+ return mTransformFeedbackMap.query(handle);
+}
+
+ProgramPipeline *Context::getProgramPipeline(ProgramPipelineID handle) const
+{
+ return mState.mProgramPipelineManager->getProgramPipeline(handle);
+}
+
+gl::LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
+{
+ switch (identifier)
+ {
+ case GL_BUFFER:
+ case GL_BUFFER_OBJECT_EXT:
+ return getBuffer({name});
+ case GL_SHADER:
+ case GL_SHADER_OBJECT_EXT:
+ return getShader({name});
+ case GL_PROGRAM:
+ case GL_PROGRAM_OBJECT_EXT:
+ return getProgramNoResolveLink({name});
+ case GL_VERTEX_ARRAY:
+ case GL_VERTEX_ARRAY_OBJECT_EXT:
+ return getVertexArray({name});
+ case GL_QUERY:
+ case GL_QUERY_OBJECT_EXT:
+ return getQuery({name});
+ case GL_TRANSFORM_FEEDBACK:
+ return getTransformFeedback({name});
+ case GL_SAMPLER:
+ return getSampler({name});
+ case GL_TEXTURE:
+ return getTexture({name});
+ case GL_RENDERBUFFER:
+ return getRenderbuffer({name});
+ case GL_FRAMEBUFFER:
+ return getFramebuffer({name});
+ case GL_PROGRAM_PIPELINE:
+ case GL_PROGRAM_PIPELINE_OBJECT_EXT:
+ return getProgramPipeline({name});
+ default:
+ UNREACHABLE();
+ return nullptr;
+ }
+}
+
+gl::LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
+{
+ return getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
+}
+
+void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
+{
+ gl::LabeledObject *object = getLabeledObject(identifier, name);
+ ASSERT(object != nullptr);
+
+ std::string labelName = GetObjectLabelFromPointer(length, label);
+ ANGLE_CONTEXT_TRY(object->setLabel(this, labelName));
+
+ // TODO(jmadill): Determine if the object is dirty based on 'name'. Conservatively assume the
+ // specified object is active until we do this.
+ mState.setObjectDirty(identifier);
+}
+
+void Context::labelObject(GLenum type, GLuint object, GLsizei length, const GLchar *label)
+{
+ gl::LabeledObject *obj = getLabeledObject(type, object);
+ ASSERT(obj != nullptr);
+
+ std::string labelName = "";
+ if (label != nullptr)
+ {
+ size_t labelLength = length == 0 ? strlen(label) : length;
+ labelName = std::string(label, labelLength);
+ }
+ ANGLE_CONTEXT_TRY(obj->setLabel(this, labelName));
+ mState.setObjectDirty(type);
+}
+
+void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
+{
+ gl::LabeledObject *object = getLabeledObjectFromPtr(ptr);
+ ASSERT(object != nullptr);
+
+ std::string labelName = GetObjectLabelFromPointer(length, label);
+ ANGLE_CONTEXT_TRY(object->setLabel(this, labelName));
+}
+
+void Context::getObjectLabel(GLenum identifier,
+ GLuint name,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *label)
+{
+ gl::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)
+{
+ gl::LabeledObject *object = getLabeledObjectFromPtr(ptr);
+ ASSERT(object != nullptr);
+
+ const std::string &objectLabel = object->getLabel();
+ GetObjectLabelBase(objectLabel, bufSize, length, label);
+}
+
+GLboolean Context::isSampler(SamplerID samplerName) const
+{
+ return mState.mSamplerManager->isSampler(samplerName);
+}
+
+void Context::bindTexture(TextureType target, TextureID handle)
+{
+ // Some apps enable KHR_create_context_no_error but pass in an invalid texture type.
+ // Workaround this by silently returning in such situations.
+ if (target == TextureType::InvalidEnum)
+ {
+ return;
+ }
+
+ Texture *texture = nullptr;
+ if (handle.value == 0)
+ {
+ texture = mZeroTextures[target].get();
+ }
+ else
+ {
+ texture =
+ mState.mTextureManager->checkTextureAllocation(mImplementation.get(), handle, target);
+ }
+
+ ASSERT(texture);
+ // Early return if rebinding the same texture
+ if (texture == mState.getTargetTexture(target))
+ {
+ return;
+ }
+
+ mState.setSamplerTexture(this, target, texture);
+ mStateCache.onActiveTextureChange(this);
+}
+
+void Context::bindReadFramebuffer(FramebufferID framebufferHandle)
+{
+ Framebuffer *framebuffer = mState.mFramebufferManager->checkFramebufferAllocation(
+ mImplementation.get(), this, framebufferHandle);
+ mState.setReadFramebufferBinding(framebuffer);
+ mReadFramebufferObserverBinding.bind(framebuffer);
+}
+
+void Context::bindDrawFramebuffer(FramebufferID framebufferHandle)
+{
+ Framebuffer *framebuffer = mState.mFramebufferManager->checkFramebufferAllocation(
+ mImplementation.get(), this, framebufferHandle);
+ mState.setDrawFramebufferBinding(framebuffer);
+ mDrawFramebufferObserverBinding.bind(framebuffer);
+ mStateCache.onDrawFramebufferChange(this);
+}
+
+void Context::bindVertexArray(VertexArrayID vertexArrayHandle)
+{
+ VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
+ mState.setVertexArrayBinding(this, vertexArray);
+ mVertexArrayObserverBinding.bind(vertexArray);
+ mStateCache.onVertexArrayBindingChange(this);
+}
+
+void Context::bindVertexBuffer(GLuint bindingIndex,
+ BufferID bufferHandle,
+ GLintptr offset,
+ GLsizei stride)
+{
+ Buffer *buffer =
+ mState.mBufferManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
+ mState.bindVertexBuffer(this, bindingIndex, buffer, offset, stride);
+ mStateCache.onVertexArrayStateChange(this);
+}
+
+void Context::bindSampler(GLuint textureUnit, SamplerID samplerHandle)
+{
+ ASSERT(textureUnit < static_cast<GLuint>(mState.mCaps.maxCombinedTextureImageUnits));
+ Sampler *sampler =
+ mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), samplerHandle);
+
+ // Early return if rebinding the same sampler
+ if (sampler == mState.getSampler(textureUnit))
+ {
+ return;
+ }
+
+ mState.setSamplerBinding(this, textureUnit, sampler);
+ mSamplerObserverBindings[textureUnit].bind(sampler);
+ mStateCache.onActiveTextureChange(this);
+}
+
+void Context::bindImageTexture(GLuint unit,
+ TextureID texture,
+ GLint level,
+ GLboolean layered,
+ GLint layer,
+ GLenum access,
+ GLenum format)
+{
+ Texture *tex = mState.mTextureManager->getTexture(texture);
+ mState.setImageUnit(this, unit, tex, level, layered, layer, access, format);
+ mImageObserverBindings[unit].bind(tex);
+}
+
+void Context::useProgram(ShaderProgramID program)
+{
+ ANGLE_CONTEXT_TRY(mState.setProgram(this, getProgramResolveLink(program)));
+ mStateCache.onProgramExecutableChange(this);
+}
+
+void Context::useProgramStages(ProgramPipelineID pipeline,
+ GLbitfield stages,
+ ShaderProgramID program)
+{
+ Program *shaderProgram = getProgramNoResolveLink(program);
+ ProgramPipeline *programPipeline =
+ mState.mProgramPipelineManager->checkProgramPipelineAllocation(mImplementation.get(),
+ pipeline);
+
+ ASSERT(programPipeline);
+ ANGLE_CONTEXT_TRY(programPipeline->useProgramStages(this, stages, shaderProgram));
+}
+
+void Context::bindTransformFeedback(GLenum target, TransformFeedbackID transformFeedbackHandle)
+{
+ ASSERT(target == GL_TRANSFORM_FEEDBACK);
+ TransformFeedback *transformFeedback =
+ checkTransformFeedbackAllocation(transformFeedbackHandle);
+ mState.setTransformFeedbackBinding(this, transformFeedback);
+ mStateCache.onActiveTransformFeedbackChange(this);
+}
+
+void Context::bindProgramPipeline(ProgramPipelineID pipelineHandle)
+{
+ ProgramPipeline *pipeline = mState.mProgramPipelineManager->checkProgramPipelineAllocation(
+ mImplementation.get(), pipelineHandle);
+ ANGLE_CONTEXT_TRY(mState.setProgramPipelineBinding(this, pipeline));
+ mStateCache.onProgramExecutableChange(this);
+ mProgramPipelineObserverBinding.bind(pipeline);
+}
+
+void Context::beginQuery(QueryType target, QueryID query)
+{
+ Query *queryObject = getOrCreateQuery(query, target);
+ ASSERT(queryObject);
+
+ // begin query
+ ANGLE_CONTEXT_TRY(queryObject->begin(this));
+
+ // set query as active for specified target only if begin succeeded
+ mState.setActiveQuery(this, target, queryObject);
+ mStateCache.onQueryChange(this);
+}
+
+void Context::endQuery(QueryType target)
+{
+ Query *queryObject = mState.getActiveQuery(target);
+ ASSERT(queryObject);
+
+ // Intentionally don't call try here. We don't want an early return.
+ (void)(queryObject->end(this));
+
+ // Always unbind the query, even if there was an error. This may delete the query object.
+ mState.setActiveQuery(this, target, nullptr);
+ mStateCache.onQueryChange(this);
+}
+
+void Context::queryCounter(QueryID id, QueryType target)
+{
+ ASSERT(target == QueryType::Timestamp);
+
+ Query *queryObject = getOrCreateQuery(id, target);
+ ASSERT(queryObject);
+
+ ANGLE_CONTEXT_TRY(queryObject->queryCounter(this));
+}
+
+void Context::getQueryiv(QueryType target, GLenum pname, GLint *params)
+{
+ switch (pname)
+ {
+ case GL_CURRENT_QUERY_EXT:
+ params[0] = mState.getActiveQueryId(target).value;
+ break;
+ case GL_QUERY_COUNTER_BITS_EXT:
+ switch (target)
+ {
+ case QueryType::TimeElapsed:
+ params[0] = getCaps().queryCounterBitsTimeElapsed;
+ break;
+ case QueryType::Timestamp:
+ params[0] = getCaps().queryCounterBitsTimestamp;
+ break;
+ default:
+ UNREACHABLE();
+ params[0] = 0;
+ break;
+ }
+ break;
+ default:
+ UNREACHABLE();
+ return;
+ }
+}
+
+void Context::getQueryivRobust(QueryType target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ getQueryiv(target, pname, params);
+}
+
+void Context::getUnsignedBytev(GLenum pname, GLubyte *data)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getUnsignedBytei_v(GLenum target, GLuint index, GLubyte *data)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getQueryObjectiv(QueryID id, GLenum pname, GLint *params)
+{
+ ANGLE_CONTEXT_TRY(GetQueryObjectParameter(this, getQuery(id), pname, params));
+}
+
+void Context::getQueryObjectivRobust(QueryID id,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ getQueryObjectiv(id, pname, params);
+}
+
+void Context::getQueryObjectuiv(QueryID id, GLenum pname, GLuint *params)
+{
+ ANGLE_CONTEXT_TRY(GetQueryObjectParameter(this, getQuery(id), pname, params));
+}
+
+void Context::getQueryObjectuivRobust(QueryID id,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint *params)
+{
+ getQueryObjectuiv(id, pname, params);
+}
+
+void Context::getQueryObjecti64v(QueryID id, GLenum pname, GLint64 *params)
+{
+ ANGLE_CONTEXT_TRY(GetQueryObjectParameter(this, getQuery(id), pname, params));
+}
+
+void Context::getQueryObjecti64vRobust(QueryID id,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint64 *params)
+{
+ getQueryObjecti64v(id, pname, params);
+}
+
+void Context::getQueryObjectui64v(QueryID id, GLenum pname, GLuint64 *params)
+{
+ ANGLE_CONTEXT_TRY(GetQueryObjectParameter(this, getQuery(id), pname, params));
+}
+
+void Context::getQueryObjectui64vRobust(QueryID id,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint64 *params)
+{
+ getQueryObjectui64v(id, pname, params);
+}
+
+Framebuffer *Context::getFramebuffer(FramebufferID handle) const
+{
+ return mState.mFramebufferManager->getFramebuffer(handle);
+}
+
+FenceNV *Context::getFenceNV(FenceNVID handle) const
+{
+ return mFenceNVMap.query(handle);
+}
+
+Query *Context::getOrCreateQuery(QueryID handle, QueryType type)
+{
+ if (!mQueryMap.contains(handle))
+ {
+ return nullptr;
+ }
+
+ Query *query = mQueryMap.query(handle);
+ if (!query)
+ {
+ ASSERT(type != QueryType::InvalidEnum);
+ query = new Query(mImplementation.get(), type, handle);
+ query->addRef();
+ mQueryMap.assign(handle, query);
+ }
+ return query;
+}
+
+Query *Context::getQuery(QueryID handle) const
+{
+ return mQueryMap.query(handle);
+}
+
+Texture *Context::getTextureByType(TextureType type) const
+{
+ ASSERT(ValidTextureTarget(this, type) || ValidTextureExternalTarget(this, type));
+ return mState.getTargetTexture(type);
+}
+
+Texture *Context::getTextureByTarget(TextureTarget target) const
+{
+ return getTextureByType(TextureTargetToType(target));
+}
+
+Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type) const
+{
+ return mState.getSamplerTexture(sampler, type);
+}
+
+Compiler *Context::getCompiler() const
+{
+ if (mCompiler.get() == nullptr)
+ {
+ mCompiler.set(this, new Compiler(mImplementation.get(), mState, mDisplay));
+ }
+ return mCompiler.get();
+}
+
+void Context::getBooleanvImpl(GLenum pname, GLboolean *params) const
+{
+ switch (pname)
+ {
+ case GL_SHADER_COMPILER:
+ *params = GL_TRUE;
+ break;
+ case GL_CONTEXT_ROBUST_ACCESS_EXT:
+ *params = ConvertToGLBoolean(mState.hasRobustAccess());
+ break;
+
+ default:
+ mState.getBooleanv(pname, params);
+ break;
+ }
+}
+
+void Context::getFloatvImpl(GLenum pname, GLfloat *params) const
+{
+ // Queries about context capabilities and maximums are answered by Context.
+ // Queries about current GL state values are answered by State.
+ switch (pname)
+ {
+ case GL_ALIASED_LINE_WIDTH_RANGE:
+ params[0] = mState.mCaps.minAliasedLineWidth;
+ params[1] = mState.mCaps.maxAliasedLineWidth;
+ break;
+ case GL_ALIASED_POINT_SIZE_RANGE:
+ params[0] = mState.mCaps.minAliasedPointSize;
+ params[1] = mState.mCaps.maxAliasedPointSize;
+ break;
+ case GL_SMOOTH_POINT_SIZE_RANGE:
+ params[0] = mState.mCaps.minSmoothPointSize;
+ params[1] = mState.mCaps.maxSmoothPointSize;
+ break;
+ case GL_SMOOTH_LINE_WIDTH_RANGE:
+ params[0] = mState.mCaps.minSmoothLineWidth;
+ params[1] = mState.mCaps.maxSmoothLineWidth;
+ break;
+ case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
+ ASSERT(mState.mExtensions.textureFilterAnisotropicEXT);
+ *params = mState.mCaps.maxTextureAnisotropy;
+ break;
+ case GL_MAX_TEXTURE_LOD_BIAS:
+ *params = mState.mCaps.maxLODBias;
+ break;
+ case GL_MIN_FRAGMENT_INTERPOLATION_OFFSET:
+ *params = mState.mCaps.minInterpolationOffset;
+ break;
+ case GL_MAX_FRAGMENT_INTERPOLATION_OFFSET:
+ *params = mState.mCaps.maxInterpolationOffset;
+ break;
+ case GL_PRIMITIVE_BOUNDING_BOX:
+ params[0] = mState.mBoundingBoxMinX;
+ params[1] = mState.mBoundingBoxMinY;
+ params[2] = mState.mBoundingBoxMinZ;
+ params[3] = mState.mBoundingBoxMinW;
+ params[4] = mState.mBoundingBoxMaxX;
+ params[5] = mState.mBoundingBoxMaxY;
+ params[6] = mState.mBoundingBoxMaxZ;
+ params[7] = mState.mBoundingBoxMaxW;
+ break;
+ default:
+ mState.getFloatv(pname, params);
+ break;
+ }
+}
+
+void Context::getIntegervImpl(GLenum pname, GLint *params) const
+{
+ // Queries about context capabilities and maximums are answered by Context.
+ // Queries about current GL state values are answered by State.
+
+ switch (pname)
+ {
+ case GL_MAX_VERTEX_ATTRIBS:
+ *params = mState.mCaps.maxVertexAttributes;
+ break;
+ case GL_MAX_VERTEX_UNIFORM_VECTORS:
+ *params = mState.mCaps.maxVertexUniformVectors;
+ break;
+ case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
+ *params = mState.mCaps.maxShaderUniformComponents[ShaderType::Vertex];
+ break;
+ case GL_MAX_VARYING_VECTORS:
+ *params = mState.mCaps.maxVaryingVectors;
+ break;
+ case GL_MAX_VARYING_COMPONENTS:
+ *params = mState.mCaps.maxVaryingVectors * 4;
+ break;
+ case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
+ *params = mState.mCaps.maxCombinedTextureImageUnits;
+ break;
+ case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
+ *params = mState.mCaps.maxShaderTextureImageUnits[ShaderType::Vertex];
+ break;
+ case GL_MAX_TEXTURE_IMAGE_UNITS:
+ *params = mState.mCaps.maxShaderTextureImageUnits[ShaderType::Fragment];
+ break;
+ case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
+ *params = mState.mCaps.maxFragmentUniformVectors;
+ break;
+ case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
+ *params = mState.mCaps.maxShaderUniformComponents[ShaderType::Fragment];
+ break;
+ case GL_MAX_RENDERBUFFER_SIZE:
+ *params = mState.mCaps.maxRenderbufferSize;
+ break;
+ case GL_MAX_COLOR_ATTACHMENTS_EXT:
+ *params = mState.mCaps.maxColorAttachments;
+ break;
+ case GL_MAX_DRAW_BUFFERS_EXT:
+ *params = mState.mCaps.maxDrawBuffers;
+ break;
+ case GL_SUBPIXEL_BITS:
+ *params = mState.mCaps.subPixelBits;
+ break;
+ case GL_MAX_TEXTURE_SIZE:
+ *params = mState.mCaps.max2DTextureSize;
+ break;
+ case GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE:
+ *params = mState.mCaps.maxRectangleTextureSize;
+ break;
+ case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
+ *params = mState.mCaps.maxCubeMapTextureSize;
+ break;
+ case GL_MAX_3D_TEXTURE_SIZE:
+ *params = mState.mCaps.max3DTextureSize;
+ break;
+ case GL_MAX_ARRAY_TEXTURE_LAYERS:
+ *params = mState.mCaps.maxArrayTextureLayers;
+ break;
+ case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
+ *params = mState.mCaps.uniformBufferOffsetAlignment;
+ break;
+ case GL_MAX_UNIFORM_BUFFER_BINDINGS:
+ *params = mState.mCaps.maxUniformBufferBindings;
+ break;
+ case GL_MAX_VERTEX_UNIFORM_BLOCKS:
+ *params = mState.mCaps.maxShaderUniformBlocks[ShaderType::Vertex];
+ break;
+ case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
+ *params = mState.mCaps.maxShaderUniformBlocks[ShaderType::Fragment];
+ break;
+ case GL_MAX_COMBINED_UNIFORM_BLOCKS:
+ *params = mState.mCaps.maxCombinedUniformBlocks;
+ break;
+ case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
+ *params = mState.mCaps.maxVertexOutputComponents;
+ break;
+ case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
+ *params = mState.mCaps.maxFragmentInputComponents;
+ break;
+ case GL_MIN_PROGRAM_TEXEL_OFFSET:
+ *params = mState.mCaps.minProgramTexelOffset;
+ break;
+ case GL_MAX_PROGRAM_TEXEL_OFFSET:
+ *params = mState.mCaps.maxProgramTexelOffset;
+ break;
+ case GL_MAJOR_VERSION:
+ *params = getClientVersion().major;
+ break;
+ case GL_MINOR_VERSION:
+ *params = getClientVersion().minor;
+ break;
+ case GL_MAX_ELEMENTS_INDICES:
+ *params = mState.mCaps.maxElementsIndices;
+ break;
+ case GL_MAX_ELEMENTS_VERTICES:
+ *params = mState.mCaps.maxElementsVertices;
+ break;
+ case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
+ *params = mState.mCaps.maxTransformFeedbackInterleavedComponents;
+ break;
+ case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
+ *params = mState.mCaps.maxTransformFeedbackSeparateAttributes;
+ break;
+ case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
+ *params = mState.mCaps.maxTransformFeedbackSeparateComponents;
+ break;
+ case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
+ *params = static_cast<GLint>(mState.mCaps.compressedTextureFormats.size());
+ break;
+ case GL_MAX_SAMPLES_ANGLE:
+ *params = mState.mCaps.maxSamples;
+ break;
+ case GL_MAX_VIEWPORT_DIMS:
+ {
+ params[0] = mState.mCaps.maxViewportWidth;
+ params[1] = mState.mCaps.maxViewportHeight;
+ }
+ break;
+ case GL_COMPRESSED_TEXTURE_FORMATS:
+ std::copy(mState.mCaps.compressedTextureFormats.begin(),
+ mState.mCaps.compressedTextureFormats.end(), params);
+ break;
+ case GL_RESET_NOTIFICATION_STRATEGY_EXT:
+ *params = mResetStrategy;
+ break;
+ case GL_NUM_SHADER_BINARY_FORMATS:
+ *params = static_cast<GLint>(mState.mCaps.shaderBinaryFormats.size());
+ break;
+ case GL_SHADER_BINARY_FORMATS:
+ std::copy(mState.mCaps.shaderBinaryFormats.begin(),
+ mState.mCaps.shaderBinaryFormats.end(), params);
+ break;
+ case GL_NUM_PROGRAM_BINARY_FORMATS:
+ *params = static_cast<GLint>(mState.mCaps.programBinaryFormats.size());
+ break;
+ case GL_PROGRAM_BINARY_FORMATS:
+ std::copy(mState.mCaps.programBinaryFormats.begin(),
+ mState.mCaps.programBinaryFormats.end(), params);
+ break;
+ case GL_NUM_EXTENSIONS:
+ *params = static_cast<GLint>(mExtensionStrings.size());
+ break;
+
+ // Desktop client flags
+ case GL_CONTEXT_FLAGS:
+ {
+ GLint contextFlags = 0;
+ if (mState.hasProtectedContent())
+ {
+ contextFlags |= GL_CONTEXT_FLAG_PROTECTED_CONTENT_BIT_EXT;
+ }
+
+ if (mState.isDebugContext())
+ {
+ contextFlags |= GL_CONTEXT_FLAG_DEBUG_BIT_KHR;
+ }
+
+ if (mState.hasRobustAccess())
+ {
+ contextFlags |= GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT;
+ }
+ *params = contextFlags;
+ }
+ break;
+ case GL_CONTEXT_PROFILE_MASK:
+ ASSERT(getClientType() == EGL_OPENGL_API);
+ *params = mState.getProfileMask();
+ break;
+
+ // GL_ANGLE_request_extension
+ case GL_NUM_REQUESTABLE_EXTENSIONS_ANGLE:
+ *params = static_cast<GLint>(mRequestableExtensionStrings.size());
+ break;
+
+ // GL_KHR_debug
+ case GL_MAX_DEBUG_MESSAGE_LENGTH:
+ *params = mState.mCaps.maxDebugMessageLength;
+ break;
+ case GL_MAX_DEBUG_LOGGED_MESSAGES:
+ *params = mState.mCaps.maxDebugLoggedMessages;
+ break;
+ case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
+ *params = mState.mCaps.maxDebugGroupStackDepth;
+ break;
+ case GL_MAX_LABEL_LENGTH:
+ *params = mState.mCaps.maxLabelLength;
+ break;
+
+ // GL_OVR_multiview2
+ case GL_MAX_VIEWS_OVR:
+ *params = mState.mCaps.maxViews;
+ break;
+
+ // GL_EXT_disjoint_timer_query
+ case GL_GPU_DISJOINT_EXT:
+ *params = mImplementation->getGPUDisjoint();
+ break;
+ case GL_MAX_FRAMEBUFFER_WIDTH:
+ *params = mState.mCaps.maxFramebufferWidth;
+ break;
+ case GL_MAX_FRAMEBUFFER_HEIGHT:
+ *params = mState.mCaps.maxFramebufferHeight;
+ break;
+ case GL_MAX_FRAMEBUFFER_SAMPLES:
+ *params = mState.mCaps.maxFramebufferSamples;
+ break;
+ case GL_MAX_SAMPLE_MASK_WORDS:
+ *params = mState.mCaps.maxSampleMaskWords;
+ break;
+ case GL_MAX_COLOR_TEXTURE_SAMPLES:
+ *params = mState.mCaps.maxColorTextureSamples;
+ break;
+ case GL_MAX_DEPTH_TEXTURE_SAMPLES:
+ *params = mState.mCaps.maxDepthTextureSamples;
+ break;
+ case GL_MAX_INTEGER_SAMPLES:
+ *params = mState.mCaps.maxIntegerSamples;
+ break;
+ case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
+ *params = mState.mCaps.maxVertexAttribRelativeOffset;
+ break;
+ case GL_MAX_VERTEX_ATTRIB_BINDINGS:
+ *params = mState.mCaps.maxVertexAttribBindings;
+ break;
+ case GL_MAX_VERTEX_ATTRIB_STRIDE:
+ *params = mState.mCaps.maxVertexAttribStride;
+ break;
+ case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
+ *params = mState.mCaps.maxShaderAtomicCounterBuffers[ShaderType::Vertex];
+ break;
+ case GL_MAX_VERTEX_ATOMIC_COUNTERS:
+ *params = mState.mCaps.maxShaderAtomicCounters[ShaderType::Vertex];
+ break;
+ case GL_MAX_VERTEX_IMAGE_UNIFORMS:
+ *params = mState.mCaps.maxShaderImageUniforms[ShaderType::Vertex];
+ break;
+ case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
+ *params = mState.mCaps.maxShaderStorageBlocks[ShaderType::Vertex];
+ break;
+ case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
+ *params = mState.mCaps.maxShaderAtomicCounterBuffers[ShaderType::Fragment];
+ break;
+ case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
+ *params = mState.mCaps.maxShaderAtomicCounters[ShaderType::Fragment];
+ break;
+ case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
+ *params = mState.mCaps.maxShaderImageUniforms[ShaderType::Fragment];
+ break;
+ case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
+ *params = mState.mCaps.maxShaderStorageBlocks[ShaderType::Fragment];
+ break;
+ case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
+ *params = mState.mCaps.minProgramTextureGatherOffset;
+ break;
+ case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
+ *params = mState.mCaps.maxProgramTextureGatherOffset;
+ break;
+ case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
+ *params = mState.mCaps.maxComputeWorkGroupInvocations;
+ break;
+ case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
+ *params = mState.mCaps.maxShaderUniformBlocks[ShaderType::Compute];
+ break;
+ case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
+ *params = mState.mCaps.maxShaderTextureImageUnits[ShaderType::Compute];
+ break;
+ case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
+ *params = mState.mCaps.maxComputeSharedMemorySize;
+ break;
+ case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
+ *params = mState.mCaps.maxShaderUniformComponents[ShaderType::Compute];
+ break;
+ case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
+ *params = mState.mCaps.maxShaderAtomicCounterBuffers[ShaderType::Compute];
+ break;
+ case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
+ *params = mState.mCaps.maxShaderAtomicCounters[ShaderType::Compute];
+ break;
+ case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
+ *params = mState.mCaps.maxShaderImageUniforms[ShaderType::Compute];
+ break;
+ case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
+ *params = static_cast<GLint>(
+ mState.mCaps.maxCombinedShaderUniformComponents[ShaderType::Compute]);
+ break;
+ case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
+ *params = mState.mCaps.maxShaderStorageBlocks[ShaderType::Compute];
+ break;
+ case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
+ *params = mState.mCaps.maxCombinedShaderOutputResources;
+ break;
+ case GL_MAX_UNIFORM_LOCATIONS:
+ *params = mState.mCaps.maxUniformLocations;
+ break;
+ case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
+ *params = mState.mCaps.maxAtomicCounterBufferBindings;
+ break;
+ case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
+ *params = mState.mCaps.maxAtomicCounterBufferSize;
+ break;
+ case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
+ *params = mState.mCaps.maxCombinedAtomicCounterBuffers;
+ break;
+ case GL_MAX_COMBINED_ATOMIC_COUNTERS:
+ *params = mState.mCaps.maxCombinedAtomicCounters;
+ break;
+ case GL_MAX_IMAGE_UNITS:
+ *params = mState.mCaps.maxImageUnits;
+ break;
+ case GL_MAX_COMBINED_IMAGE_UNIFORMS:
+ *params = mState.mCaps.maxCombinedImageUniforms;
+ break;
+ case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
+ *params = mState.mCaps.maxShaderStorageBufferBindings;
+ break;
+ case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
+ *params = mState.mCaps.maxCombinedShaderStorageBlocks;
+ break;
+ case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
+ *params = mState.mCaps.shaderStorageBufferOffsetAlignment;
+ break;
+
+ // GL_EXT_geometry_shader
+ case GL_MAX_FRAMEBUFFER_LAYERS_EXT:
+ *params = mState.mCaps.maxFramebufferLayers;
+ break;
+ case GL_LAYER_PROVOKING_VERTEX_EXT:
+ *params = mState.mCaps.layerProvokingVertex;
+ break;
+ case GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT:
+ *params = mState.mCaps.maxShaderUniformComponents[ShaderType::Geometry];
+ break;
+ case GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT:
+ *params = mState.mCaps.maxShaderUniformBlocks[ShaderType::Geometry];
+ break;
+ case GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT:
+ *params = static_cast<GLint>(
+ mState.mCaps.maxCombinedShaderUniformComponents[ShaderType::Geometry]);
+ break;
+ case GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT:
+ *params = mState.mCaps.maxGeometryInputComponents;
+ break;
+ case GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT:
+ *params = mState.mCaps.maxGeometryOutputComponents;
+ break;
+ case GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT:
+ *params = mState.mCaps.maxGeometryOutputVertices;
+ break;
+ case GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT:
+ *params = mState.mCaps.maxGeometryTotalOutputComponents;
+ break;
+ case GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT:
+ *params = mState.mCaps.maxGeometryShaderInvocations;
+ break;
+ case GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT:
+ *params = mState.mCaps.maxShaderTextureImageUnits[ShaderType::Geometry];
+ break;
+ case GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT:
+ *params = mState.mCaps.maxShaderAtomicCounterBuffers[ShaderType::Geometry];
+ break;
+ case GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT:
+ *params = mState.mCaps.maxShaderAtomicCounters[ShaderType::Geometry];
+ break;
+ case GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT:
+ *params = mState.mCaps.maxShaderImageUniforms[ShaderType::Geometry];
+ break;
+ case GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT:
+ *params = mState.mCaps.maxShaderStorageBlocks[ShaderType::Geometry];
+ break;
+ // GL_EXT_tessellation_shader
+ case GL_MAX_PATCH_VERTICES_EXT:
+ *params = mState.mCaps.maxPatchVertices;
+ break;
+ case GL_MAX_TESS_GEN_LEVEL_EXT:
+ *params = mState.mCaps.maxTessGenLevel;
+ break;
+ case GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS_EXT:
+ *params = mState.mCaps.maxShaderUniformComponents[ShaderType::TessControl];
+ break;
+ case GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT:
+ *params = mState.mCaps.maxShaderUniformComponents[ShaderType::TessEvaluation];
+ break;
+ case GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_EXT:
+ *params = mState.mCaps.maxShaderTextureImageUnits[ShaderType::TessControl];
+ break;
+ case GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_EXT:
+ *params = mState.mCaps.maxShaderTextureImageUnits[ShaderType::TessEvaluation];
+ break;
+ case GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_EXT:
+ *params = mState.mCaps.maxTessControlOutputComponents;
+ break;
+ case GL_MAX_TESS_PATCH_COMPONENTS_EXT:
+ *params = mState.mCaps.maxTessPatchComponents;
+ break;
+ case GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_EXT:
+ *params = mState.mCaps.maxTessControlTotalOutputComponents;
+ break;
+ case GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_EXT:
+ *params = mState.mCaps.maxTessEvaluationOutputComponents;
+ break;
+ case GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS_EXT:
+ *params = mState.mCaps.maxShaderUniformBlocks[ShaderType::TessControl];
+ break;
+ case GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS_EXT:
+ *params = mState.mCaps.maxShaderUniformBlocks[ShaderType::TessEvaluation];
+ break;
+ case GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_EXT:
+ *params = mState.mCaps.maxTessControlInputComponents;
+ break;
+ case GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_EXT:
+ *params = mState.mCaps.maxTessEvaluationInputComponents;
+ break;
+ case GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_EXT:
+ *params = static_cast<GLint>(
+ mState.mCaps.maxCombinedShaderUniformComponents[ShaderType::TessControl]);
+ break;
+ case GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT:
+ *params = static_cast<GLint>(
+ mState.mCaps.maxCombinedShaderUniformComponents[ShaderType::TessEvaluation]);
+ break;
+ case GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_EXT:
+ *params = mState.mCaps.maxShaderAtomicCounterBuffers[ShaderType::TessControl];
+ break;
+ case GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_EXT:
+ *params = mState.mCaps.maxShaderAtomicCounterBuffers[ShaderType::TessEvaluation];
+ break;
+ case GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS_EXT:
+ *params = mState.mCaps.maxShaderAtomicCounters[ShaderType::TessControl];
+ break;
+ case GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS_EXT:
+ *params = mState.mCaps.maxShaderAtomicCounters[ShaderType::TessEvaluation];
+ break;
+ case GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_EXT:
+ *params = mState.mCaps.maxShaderImageUniforms[ShaderType::TessControl];
+ break;
+ case GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS_EXT:
+ *params = mState.mCaps.maxShaderImageUniforms[ShaderType::TessEvaluation];
+ break;
+ case GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_EXT:
+ *params = mState.mCaps.maxShaderStorageBlocks[ShaderType::TessControl];
+ break;
+ case GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_EXT:
+ *params = mState.mCaps.maxShaderStorageBlocks[ShaderType::TessEvaluation];
+ break;
+ // GLES1 emulation: Caps queries
+ case GL_MAX_TEXTURE_UNITS:
+ *params = mState.mCaps.maxMultitextureUnits;
+ break;
+ case GL_MAX_MODELVIEW_STACK_DEPTH:
+ *params = mState.mCaps.maxModelviewMatrixStackDepth;
+ break;
+ case GL_MAX_PROJECTION_STACK_DEPTH:
+ *params = mState.mCaps.maxProjectionMatrixStackDepth;
+ break;
+ case GL_MAX_TEXTURE_STACK_DEPTH:
+ *params = mState.mCaps.maxTextureMatrixStackDepth;
+ break;
+ case GL_MAX_LIGHTS:
+ *params = mState.mCaps.maxLights;
+ break;
+
+ // case GL_MAX_CLIP_DISTANCES_EXT: Conflict enum value
+ case GL_MAX_CLIP_PLANES:
+ if (getClientVersion().major >= 2)
+ {
+ // GL_APPLE_clip_distance/GL_EXT_clip_cull_distance
+ *params = mState.mCaps.maxClipDistances;
+ }
+ else
+ {
+ *params = mState.mCaps.maxClipPlanes;
+ }
+ break;
+ case GL_MAX_CULL_DISTANCES_EXT:
+ *params = mState.mCaps.maxCullDistances;
+ break;
+ case GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES_EXT:
+ *params = mState.mCaps.maxCombinedClipAndCullDistances;
+ break;
+ // GLES1 emulation: Vertex attribute queries
+ case GL_VERTEX_ARRAY_BUFFER_BINDING:
+ case GL_NORMAL_ARRAY_BUFFER_BINDING:
+ case GL_COLOR_ARRAY_BUFFER_BINDING:
+ case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
+ case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
+ getIntegerVertexAttribImpl(pname, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, params);
+ break;
+ case GL_VERTEX_ARRAY_STRIDE:
+ case GL_NORMAL_ARRAY_STRIDE:
+ case GL_COLOR_ARRAY_STRIDE:
+ case GL_POINT_SIZE_ARRAY_STRIDE_OES:
+ case GL_TEXTURE_COORD_ARRAY_STRIDE:
+ getIntegerVertexAttribImpl(pname, GL_VERTEX_ATTRIB_ARRAY_STRIDE, params);
+ break;
+ case GL_VERTEX_ARRAY_SIZE:
+ case GL_COLOR_ARRAY_SIZE:
+ case GL_TEXTURE_COORD_ARRAY_SIZE:
+ getIntegerVertexAttribImpl(pname, GL_VERTEX_ATTRIB_ARRAY_SIZE, params);
+ break;
+ case GL_VERTEX_ARRAY_TYPE:
+ case GL_COLOR_ARRAY_TYPE:
+ case GL_NORMAL_ARRAY_TYPE:
+ case GL_POINT_SIZE_ARRAY_TYPE_OES:
+ case GL_TEXTURE_COORD_ARRAY_TYPE:
+ getIntegerVertexAttribImpl(pname, GL_VERTEX_ATTRIB_ARRAY_TYPE, params);
+ break;
+
+ // GL_KHR_parallel_shader_compile
+ case GL_MAX_SHADER_COMPILER_THREADS_KHR:
+ *params = mState.getMaxShaderCompilerThreads();
+ break;
+
+ // GL_EXT_blend_func_extended
+ case GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT:
+ *params = mState.mCaps.maxDualSourceDrawBuffers;
+ break;
+
+ // OES_shader_multisample_interpolation
+ case GL_FRAGMENT_INTERPOLATION_OFFSET_BITS_OES:
+ *params = mState.mCaps.subPixelInterpolationOffsetBits;
+ break;
+
+ // GL_OES_texture_buffer
+ case GL_MAX_TEXTURE_BUFFER_SIZE:
+ *params = mState.mCaps.maxTextureBufferSize;
+ break;
+ case GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
+ *params = mState.mCaps.textureBufferOffsetAlignment;
+ break;
+
+ // GL_EXT_clip_control
+ case GL_CLIP_ORIGIN_EXT:
+ *params = mState.mClipControlOrigin;
+ break;
+ case GL_CLIP_DEPTH_MODE_EXT:
+ *params = mState.mClipControlDepth;
+ break;
+
+ // ANGLE_shader_pixel_local_storage
+ case GL_MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE:
+ *params = mState.mCaps.maxPixelLocalStoragePlanes;
+ break;
+ case GL_MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE_ANGLE:
+ *params = mState.mCaps.maxColorAttachmentsWithActivePixelLocalStorage;
+ break;
+ case GL_MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES_ANGLE:
+ *params = mState.mCaps.maxCombinedDrawBuffersAndPixelLocalStoragePlanes;
+ break;
+
+ default:
+ ANGLE_CONTEXT_TRY(mState.getIntegerv(this, pname, params));
+ break;
+ }
+}
+
+void Context::getIntegerVertexAttribImpl(GLenum pname, GLenum attribpname, GLint *params) const
+{
+ getVertexAttribivImpl(static_cast<GLuint>(vertexArrayIndex(ParamToVertexArrayType(pname))),
+ attribpname, params);
+}
+
+void Context::getInteger64vImpl(GLenum pname, GLint64 *params) const
+{
+ // Queries about context capabilities and maximums are answered by Context.
+ // Queries about current GL state values are answered by State.
+ switch (pname)
+ {
+ case GL_MAX_ELEMENT_INDEX:
+ *params = mState.mCaps.maxElementIndex;
+ break;
+ case GL_MAX_UNIFORM_BLOCK_SIZE:
+ *params = mState.mCaps.maxUniformBlockSize;
+ break;
+ case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
+ *params = mState.mCaps.maxCombinedShaderUniformComponents[ShaderType::Vertex];
+ break;
+ case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
+ *params = mState.mCaps.maxCombinedShaderUniformComponents[ShaderType::Fragment];
+ break;
+ case GL_MAX_SERVER_WAIT_TIMEOUT:
+ *params = mState.mCaps.maxServerWaitTimeout;
+ break;
+
+ // GL_EXT_disjoint_timer_query
+ case GL_TIMESTAMP_EXT:
+ *params = mImplementation->getTimestamp();
+ break;
+
+ case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
+ *params = mState.mCaps.maxShaderStorageBlockSize;
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+void Context::getPointerv(GLenum pname, void **params)
+{
+ mState.getPointerv(this, pname, params);
+}
+
+void Context::getPointervRobustANGLERobust(GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ void **params)
+{
+ UNIMPLEMENTED();
+}
+
+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.
+
+ GLenum nativeType;
+ unsigned int numParams;
+ bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
+ ASSERT(queryStatus);
+
+ if (nativeType == GL_INT)
+ {
+ switch (target)
+ {
+ case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
+ ASSERT(index < 3u);
+ *data = mState.mCaps.maxComputeWorkGroupCount[index];
+ break;
+ case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
+ ASSERT(index < 3u);
+ *data = mState.mCaps.maxComputeWorkGroupSize[index];
+ break;
+ default:
+ mState.getIntegeri_v(this, target, index, data);
+ }
+ }
+ else
+ {
+ CastIndexedStateValues(this, nativeType, target, index, numParams, data);
+ }
+}
+
+void Context::getIntegeri_vRobust(GLenum target,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *data)
+{
+ getIntegeri_v(target, index, 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.
+
+ GLenum nativeType;
+ unsigned int numParams;
+ bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
+ ASSERT(queryStatus);
+
+ if (nativeType == GL_INT_64_ANGLEX)
+ {
+ mState.getInteger64i_v(target, index, data);
+ }
+ else
+ {
+ CastIndexedStateValues(this, nativeType, target, index, numParams, data);
+ }
+}
+
+void Context::getInteger64i_vRobust(GLenum target,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint64 *data)
+{
+ getInteger64i_v(target, index, 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);
+ ASSERT(queryStatus);
+
+ if (nativeType == GL_BOOL)
+ {
+ mState.getBooleani_v(target, index, data);
+ }
+ else
+ {
+ CastIndexedStateValues(this, nativeType, target, index, numParams, data);
+ }
+}
+
+void Context::getBooleani_vRobust(GLenum target,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLboolean *data)
+{
+ getBooleani_v(target, index, data);
+}
+
+void Context::getBufferParameteriv(BufferBinding target, GLenum pname, GLint *params)
+{
+ Buffer *buffer = mState.getTargetBuffer(target);
+ QueryBufferParameteriv(buffer, pname, params);
+}
+
+void Context::getBufferParameterivRobust(BufferBinding target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ getBufferParameteriv(target, pname, params);
+}
+
+void Context::getFramebufferAttachmentParameteriv(GLenum target,
+ GLenum attachment,
+ GLenum pname,
+ GLint *params)
+{
+ const Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
+ QueryFramebufferAttachmentParameteriv(this, framebuffer, attachment, pname, params);
+}
+
+void Context::getFramebufferAttachmentParameterivRobust(GLenum target,
+ GLenum attachment,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ getFramebufferAttachmentParameteriv(target, attachment, pname, params);
+}
+
+void Context::getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
+{
+ Renderbuffer *renderbuffer = mState.getCurrentRenderbuffer();
+ QueryRenderbufferiv(this, renderbuffer, pname, params);
+}
+
+void Context::getRenderbufferParameterivRobust(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ getRenderbufferParameteriv(target, pname, params);
+}
+
+void Context::texBuffer(TextureType target, GLenum internalformat, BufferID buffer)
+{
+ ASSERT(target == TextureType::Buffer);
+
+ Texture *texture = getTextureByType(target);
+ Buffer *bufferObj = mState.mBufferManager->getBuffer(buffer);
+ ANGLE_CONTEXT_TRY(texture->setBuffer(this, bufferObj, internalformat));
+}
+
+void Context::texBufferRange(TextureType target,
+ GLenum internalformat,
+ BufferID buffer,
+ GLintptr offset,
+ GLsizeiptr size)
+{
+ ASSERT(target == TextureType::Buffer);
+
+ Texture *texture = getTextureByType(target);
+ Buffer *bufferObj = mState.mBufferManager->getBuffer(buffer);
+ ANGLE_CONTEXT_TRY(texture->setBufferRange(this, bufferObj, internalformat, offset, size));
+}
+
+void Context::getTexParameterfv(TextureType target, GLenum pname, GLfloat *params)
+{
+ const Texture *const texture = getTextureByType(target);
+ QueryTexParameterfv(this, texture, pname, params);
+}
+
+void Context::getTexParameterfvRobust(TextureType target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params)
+{
+ getTexParameterfv(target, pname, params);
+}
+
+void Context::getTexParameteriv(TextureType target, GLenum pname, GLint *params)
+{
+ const Texture *const texture = getTextureByType(target);
+ QueryTexParameteriv(this, texture, pname, params);
+}
+
+void Context::getTexParameterIiv(TextureType target, GLenum pname, GLint *params)
+{
+ const Texture *const texture = getTextureByType(target);
+ QueryTexParameterIiv(this, texture, pname, params);
+}
+
+void Context::getTexParameterIuiv(TextureType target, GLenum pname, GLuint *params)
+{
+ const Texture *const texture = getTextureByType(target);
+ QueryTexParameterIuiv(this, texture, pname, params);
+}
+
+void Context::getTexParameterivRobust(TextureType target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ getTexParameteriv(target, pname, params);
+}
+
+void Context::getTexParameterIivRobust(TextureType target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getTexParameterIuivRobust(TextureType target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getTexLevelParameteriv(TextureTarget target, GLint level, GLenum pname, GLint *params)
+{
+ Texture *texture = getTextureByTarget(target);
+ QueryTexLevelParameteriv(texture, target, level, pname, params);
+}
+
+void Context::getTexLevelParameterivRobust(TextureTarget target,
+ GLint level,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getTexLevelParameterfv(TextureTarget target,
+ GLint level,
+ GLenum pname,
+ GLfloat *params)
+{
+ Texture *texture = getTextureByTarget(target);
+ QueryTexLevelParameterfv(texture, target, level, pname, params);
+}
+
+void Context::getTexLevelParameterfvRobust(TextureTarget target,
+ GLint level,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texParameterf(TextureType target, GLenum pname, GLfloat param)
+{
+ Texture *const texture = getTextureByType(target);
+ SetTexParameterf(this, texture, pname, param);
+}
+
+void Context::texParameterfv(TextureType target, GLenum pname, const GLfloat *params)
+{
+ Texture *const texture = getTextureByType(target);
+ SetTexParameterfv(this, texture, pname, params);
+}
+
+void Context::texParameterfvRobust(TextureType target,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLfloat *params)
+{
+ texParameterfv(target, pname, params);
+}
+
+void Context::texParameteri(TextureType target, GLenum pname, GLint param)
+{
+ // Some apps enable KHR_create_context_no_error but pass in an invalid texture type.
+ // Workaround this by silently returning in such situations.
+ if (target == TextureType::InvalidEnum)
+ {
+ return;
+ }
+
+ Texture *const texture = getTextureByType(target);
+ SetTexParameteri(this, texture, pname, param);
+}
+
+void Context::texParameteriv(TextureType target, GLenum pname, const GLint *params)
+{
+ Texture *const texture = getTextureByType(target);
+ SetTexParameteriv(this, texture, pname, params);
+}
+
+void Context::texParameterIiv(TextureType target, GLenum pname, const GLint *params)
+{
+ Texture *const texture = getTextureByType(target);
+ SetTexParameterIiv(this, texture, pname, params);
+}
+
+void Context::texParameterIuiv(TextureType target, GLenum pname, const GLuint *params)
+{
+ Texture *const texture = getTextureByType(target);
+ SetTexParameterIuiv(this, texture, pname, params);
+}
+
+void Context::texParameterivRobust(TextureType target,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLint *params)
+{
+ texParameteriv(target, pname, params);
+}
+
+void Context::texParameterIivRobust(TextureType target,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLint *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texParameterIuivRobust(TextureType target,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLuint *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::drawArraysInstanced(PrimitiveMode mode,
+ GLint first,
+ GLsizei count,
+ GLsizei instanceCount)
+{
+ // No-op if count draws no primitives for given mode
+ if (noopDrawInstanced(mode, count, instanceCount))
+ {
+ ANGLE_CONTEXT_TRY(mImplementation->handleNoopDrawEvent());
+ return;
+ }
+
+ ANGLE_CONTEXT_TRY(prepareForDraw(mode));
+ ANGLE_CONTEXT_TRY(
+ mImplementation->drawArraysInstanced(this, mode, first, count, instanceCount));
+ MarkTransformFeedbackBufferUsage(this, count, instanceCount);
+ MarkShaderStorageUsage(this);
+}
+
+void Context::drawElementsInstanced(PrimitiveMode mode,
+ GLsizei count,
+ DrawElementsType type,
+ const void *indices,
+ GLsizei instances)
+{
+ // No-op if count draws no primitives for given mode
+ if (noopDrawInstanced(mode, count, instances))
+ {
+ ANGLE_CONTEXT_TRY(mImplementation->handleNoopDrawEvent());
+ return;
+ }
+
+ ANGLE_CONTEXT_TRY(prepareForDraw(mode));
+ ANGLE_CONTEXT_TRY(
+ mImplementation->drawElementsInstanced(this, mode, count, type, indices, instances));
+ MarkShaderStorageUsage(this);
+}
+
+void Context::drawElementsBaseVertex(PrimitiveMode mode,
+ GLsizei count,
+ DrawElementsType type,
+ const void *indices,
+ GLint basevertex)
+{
+ // No-op if count draws no primitives for given mode
+ if (noopDraw(mode, count))
+ {
+ ANGLE_CONTEXT_TRY(mImplementation->handleNoopDrawEvent());
+ return;
+ }
+
+ ANGLE_CONTEXT_TRY(prepareForDraw(mode));
+ ANGLE_CONTEXT_TRY(
+ mImplementation->drawElementsBaseVertex(this, mode, count, type, indices, basevertex));
+ MarkShaderStorageUsage(this);
+}
+
+void Context::drawElementsInstancedBaseVertex(PrimitiveMode mode,
+ GLsizei count,
+ DrawElementsType type,
+ const void *indices,
+ GLsizei instancecount,
+ GLint basevertex)
+{
+ // No-op if count draws no primitives for given mode
+ if (noopDrawInstanced(mode, count, instancecount))
+ {
+ ANGLE_CONTEXT_TRY(mImplementation->handleNoopDrawEvent());
+ return;
+ }
+
+ ANGLE_CONTEXT_TRY(prepareForDraw(mode));
+ ANGLE_CONTEXT_TRY(mImplementation->drawElementsInstancedBaseVertex(
+ this, mode, count, type, indices, instancecount, basevertex));
+ MarkShaderStorageUsage(this);
+}
+
+void Context::drawRangeElements(PrimitiveMode mode,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ DrawElementsType type,
+ const void *indices)
+{
+ // No-op if count draws no primitives for given mode
+ if (noopDraw(mode, count))
+ {
+ ANGLE_CONTEXT_TRY(mImplementation->handleNoopDrawEvent());
+ return;
+ }
+
+ ANGLE_CONTEXT_TRY(prepareForDraw(mode));
+ ANGLE_CONTEXT_TRY(
+ mImplementation->drawRangeElements(this, mode, start, end, count, type, indices));
+ MarkShaderStorageUsage(this);
+}
+
+void Context::drawRangeElementsBaseVertex(PrimitiveMode mode,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ DrawElementsType type,
+ const void *indices,
+ GLint basevertex)
+{
+ // No-op if count draws no primitives for given mode
+ if (noopDraw(mode, count))
+ {
+ ANGLE_CONTEXT_TRY(mImplementation->handleNoopDrawEvent());
+ return;
+ }
+
+ ANGLE_CONTEXT_TRY(prepareForDraw(mode));
+ ANGLE_CONTEXT_TRY(mImplementation->drawRangeElementsBaseVertex(this, mode, start, end, count,
+ type, indices, basevertex));
+ MarkShaderStorageUsage(this);
+}
+
+void Context::drawArraysIndirect(PrimitiveMode mode, const void *indirect)
+{
+ ANGLE_CONTEXT_TRY(prepareForDraw(mode));
+ ANGLE_CONTEXT_TRY(mImplementation->drawArraysIndirect(this, mode, indirect));
+ MarkShaderStorageUsage(this);
+}
+
+void Context::drawElementsIndirect(PrimitiveMode mode, DrawElementsType type, const void *indirect)
+{
+ ANGLE_CONTEXT_TRY(prepareForDraw(mode));
+ ANGLE_CONTEXT_TRY(mImplementation->drawElementsIndirect(this, mode, type, indirect));
+ MarkShaderStorageUsage(this);
+}
+
+void Context::flush()
+{
+ ANGLE_CONTEXT_TRY(mImplementation->flush(this));
+}
+
+void Context::finish()
+{
+ ANGLE_CONTEXT_TRY(mImplementation->finish(this));
+}
+
+void Context::insertEventMarker(GLsizei length, const char *marker)
+{
+ ASSERT(mImplementation);
+ ANGLE_CONTEXT_TRY(mImplementation->insertEventMarker(length, marker));
+}
+
+void Context::pushGroupMarker(GLsizei length, const char *marker)
+{
+ ASSERT(mImplementation);
+
+ if (marker == nullptr)
+ {
+ // From the EXT_debug_marker spec,
+ // "If <marker> is null then an empty string is pushed on the stack."
+ ANGLE_CONTEXT_TRY(mImplementation->pushGroupMarker(length, ""));
+ }
+ else
+ {
+ ANGLE_CONTEXT_TRY(mImplementation->pushGroupMarker(length, marker));
+ }
+}
+
+void Context::popGroupMarker()
+{
+ ASSERT(mImplementation);
+ ANGLE_CONTEXT_TRY(mImplementation->popGroupMarker());
+}
+
+void Context::bindUniformLocation(ShaderProgramID program,
+ UniformLocation location,
+ const GLchar *name)
+{
+ Program *programObject = getProgramResolveLink(program);
+ ASSERT(programObject);
+
+ programObject->bindUniformLocation(location, name);
+}
+
+void Context::coverageModulation(GLenum components)
+{
+ mState.setCoverageModulation(components);
+}
+
+GLuint Context::getProgramResourceIndex(ShaderProgramID program,
+ GLenum programInterface,
+ const GLchar *name)
+{
+ const Program *programObject = getProgramResolveLink(program);
+ return QueryProgramResourceIndex(programObject, programInterface, name);
+}
+
+void Context::getProgramResourceName(ShaderProgramID program,
+ GLenum programInterface,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *name)
+{
+ const Program *programObject = getProgramResolveLink(program);
+ QueryProgramResourceName(this, programObject, programInterface, index, bufSize, length, name);
+}
+
+GLint Context::getProgramResourceLocation(ShaderProgramID program,
+ GLenum programInterface,
+ const GLchar *name)
+{
+ const Program *programObject = getProgramResolveLink(program);
+ return QueryProgramResourceLocation(programObject, programInterface, name);
+}
+
+void Context::getProgramResourceiv(ShaderProgramID program,
+ GLenum programInterface,
+ GLuint index,
+ GLsizei propCount,
+ const GLenum *props,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ const Program *programObject = getProgramResolveLink(program);
+ QueryProgramResourceiv(programObject, programInterface, {index}, propCount, props, bufSize,
+ length, params);
+}
+
+void Context::getProgramInterfaceiv(ShaderProgramID program,
+ GLenum programInterface,
+ GLenum pname,
+ GLint *params)
+{
+ const Program *programObject = getProgramResolveLink(program);
+ QueryProgramInterfaceiv(programObject, programInterface, pname, params);
+}
+
+void Context::getProgramInterfaceivRobust(ShaderProgramID program,
+ GLenum programInterface,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::handleError(GLenum errorCode,
+ const char *message,
+ const char *file,
+ const char *function,
+ unsigned int line)
+{
+ mErrors.handleError(errorCode, message, file, function, line);
+}
+
+void Context::validationError(angle::EntryPoint entryPoint,
+ GLenum errorCode,
+ const char *message) const
+{
+ const_cast<Context *>(this)->mErrors.validationError(entryPoint, errorCode, message);
+}
+
+void Context::validationErrorF(angle::EntryPoint entryPoint,
+ GLenum errorCode,
+ const char *format,
+ ...) const
+{
+ va_list vargs;
+ va_start(vargs, format);
+ constexpr size_t kMessageSize = 256;
+ char message[kMessageSize];
+ int r = vsnprintf(message, kMessageSize, format, vargs);
+ va_end(vargs);
+
+ if (r > 0)
+ {
+ validationError(entryPoint, errorCode, message);
+ }
+ else
+ {
+ validationError(entryPoint, errorCode, format);
+ }
+}
+
+// Get one of the recorded errors and clear its flag, if any.
+// [OpenGL ES 2.0.24] section 2.5 page 13.
+GLenum Context::getError()
+{
+ if (mErrors.empty())
+ {
+ return GL_NO_ERROR;
+ }
+ else
+ {
+ return mErrors.popError();
+ }
+}
+
+// NOTE: this function should not assume that this context is current!
+void Context::markContextLost(GraphicsResetStatus status)
+{
+ ASSERT(status != GraphicsResetStatus::NoError);
+ if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
+ {
+ mResetStatus = status;
+ mContextLostForced = true;
+ }
+ setContextLost();
+}
+
+void Context::setContextLost()
+{
+ mContextLost = true;
+
+ // Stop skipping validation, since many implementation entrypoint assume they can't
+ // be called when lost, or with null object arguments, etc.
+ mSkipValidation = false;
+
+ // Make sure we update TLS.
+#if defined(ANGLE_PLATFORM_APPLE)
+ SetCurrentValidContextTLS(nullptr);
+#else
+ gCurrentValidContext = nullptr;
+#endif
+}
+
+GLenum Context::getGraphicsResetStatus()
+{
+ // 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)
+ {
+ if (!isContextLost() && mImplementation->getResetStatus() != GraphicsResetStatus::NoError)
+ {
+ setContextLost();
+ }
+
+ // 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;
+ }
+
+ // 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 (!isContextLost())
+ {
+ ASSERT(mResetStatus == GraphicsResetStatus::NoError);
+ mResetStatus = mImplementation->getResetStatus();
+
+ if (mResetStatus != GraphicsResetStatus::NoError)
+ {
+ setContextLost();
+ }
+ }
+ else if (!mContextLostForced && mResetStatus != GraphicsResetStatus::NoError)
+ {
+ // 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 ToGLenum(mResetStatus);
+}
+
+bool Context::isResetNotificationEnabled() const
+{
+ return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
+}
+
+bool Context::isRobustnessEnabled() const
+{
+ return mState.hasRobustAccess();
+}
+
+const egl::Config *Context::getConfig() const
+{
+ return mConfig;
+}
+
+EGLenum Context::getClientType() const
+{
+ return mState.getClientType();
+}
+
+EGLenum Context::getRenderBuffer() const
+{
+ const Framebuffer *framebuffer =
+ mState.mFramebufferManager->getFramebuffer(Framebuffer::kDefaultDrawFramebufferHandle);
+ if (framebuffer == nullptr)
+ {
+ return EGL_NONE;
+ }
+
+ const FramebufferAttachment *backAttachment = framebuffer->getAttachment(this, GL_BACK);
+ ASSERT(backAttachment != nullptr);
+ return backAttachment->getSurface()->getRenderBuffer();
+}
+
+VertexArray *Context::checkVertexArrayAllocation(VertexArrayID vertexArrayHandle)
+{
+ // Only called after a prior call to Gen.
+ VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
+ if (!vertexArray)
+ {
+ vertexArray =
+ new VertexArray(mImplementation.get(), vertexArrayHandle,
+ mState.mCaps.maxVertexAttributes, mState.mCaps.maxVertexAttribBindings);
+ vertexArray->setBufferAccessValidationEnabled(mBufferAccessValidationEnabled);
+
+ mVertexArrayMap.assign(vertexArrayHandle, vertexArray);
+ }
+
+ return vertexArray;
+}
+
+TransformFeedback *Context::checkTransformFeedbackAllocation(
+ TransformFeedbackID transformFeedbackHandle)
+{
+ // Only called after a prior call to Gen.
+ TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
+ if (!transformFeedback)
+ {
+ transformFeedback =
+ new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mState.mCaps);
+ transformFeedback->addRef();
+ mTransformFeedbackMap.assign(transformFeedbackHandle, transformFeedback);
+ }
+
+ return transformFeedback;
+}
+
+bool Context::isVertexArrayGenerated(VertexArrayID vertexArray) const
+{
+ ASSERT(mVertexArrayMap.contains({0}));
+ return mVertexArrayMap.contains(vertexArray);
+}
+
+bool Context::isTransformFeedbackGenerated(TransformFeedbackID transformFeedback) const
+{
+ ASSERT(mTransformFeedbackMap.contains({0}));
+ return mTransformFeedbackMap.contains(transformFeedback);
+}
+
+void Context::detachTexture(TextureID texture)
+{
+ // The State cannot unbind image observers itself, they are owned by the Context
+ Texture *tex = mState.mTextureManager->getTexture(texture);
+ for (auto &imageBinding : mImageObserverBindings)
+ {
+ if (imageBinding.getSubject() == tex)
+ {
+ imageBinding.reset();
+ }
+ }
+
+ // Simple pass-through to State's detachTexture method, as textures do not require
+ // allocation map management either here or in the resource manager at detach time.
+ // Zero textures are held by the Context, and we don't attempt to request them from
+ // the State.
+ mState.detachTexture(this, mZeroTextures, texture);
+}
+
+void Context::detachBuffer(Buffer *buffer)
+{
+ // Simple pass-through to State's detachBuffer method, since
+ // only buffer attachments to container objects that are bound to the current context
+ // should be detached. And all those are available in State.
+
+ // [OpenGL ES 3.2] section 5.1.2 page 45:
+ // Attachments to unbound container objects, such as
+ // deletion of a buffer attached to a vertex array object which is not bound to the context,
+ // are not affected and continue to act as references on the deleted object
+ ANGLE_CONTEXT_TRY(mState.detachBuffer(this, buffer));
+}
+
+void Context::detachFramebuffer(FramebufferID framebuffer)
+{
+ // Framebuffer detachment is handled by Context, because 0 is a valid
+ // Framebuffer object, and a pointer to it must be passed from Context
+ // to State at binding time.
+
+ // [OpenGL ES 2.0.24] section 4.4 page 107:
+ // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as
+ // though BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of
+ // zero.
+
+ if (mState.removeReadFramebufferBinding(framebuffer) && framebuffer.value != 0)
+ {
+ bindReadFramebuffer({0});
+ }
+
+ if (mState.removeDrawFramebufferBinding(framebuffer) && framebuffer.value != 0)
+ {
+ bindDrawFramebuffer({0});
+ }
+}
+
+void Context::detachRenderbuffer(RenderbufferID renderbuffer)
+{
+ mState.detachRenderbuffer(this, renderbuffer);
+}
+
+void Context::detachVertexArray(VertexArrayID vertexArray)
+{
+ // Vertex array detachment is handled by Context, because 0 is a valid
+ // VAO, and a pointer to it must be passed from Context to State at
+ // binding time.
+
+ // [OpenGL ES 3.0.2] section 2.10 page 43:
+ // If a vertex array object that is currently bound is deleted, the binding
+ // for that object reverts to zero and the default vertex array becomes current.
+ if (mState.removeVertexArrayBinding(this, vertexArray))
+ {
+ bindVertexArray({0});
+ }
+}
+
+void Context::detachTransformFeedback(TransformFeedbackID transformFeedback)
+{
+ // Transform feedback detachment is handled by Context, because 0 is a valid
+ // transform feedback, and a pointer to it must be passed from Context to State at
+ // binding time.
+
+ // The OpenGL specification doesn't mention what should happen when the currently bound
+ // transform feedback object is deleted. Since it is a container object, we treat it like
+ // VAOs and FBOs and set the current bound transform feedback back to 0.
+ if (mState.removeTransformFeedbackBinding(this, transformFeedback))
+ {
+ bindTransformFeedback(GL_TRANSFORM_FEEDBACK, {0});
+ mStateCache.onActiveTransformFeedbackChange(this);
+ }
+}
+
+void Context::detachSampler(SamplerID sampler)
+{
+ mState.detachSampler(this, sampler);
+}
+
+void Context::detachProgramPipeline(ProgramPipelineID pipeline)
+{
+ mState.detachProgramPipeline(this, pipeline);
+}
+
+void Context::vertexAttribDivisor(GLuint index, GLuint divisor)
+{
+ mState.setVertexAttribDivisor(this, index, divisor);
+ mStateCache.onVertexArrayStateChange(this);
+}
+
+void Context::samplerParameteri(SamplerID sampler, GLenum pname, GLint param)
+{
+ Sampler *const samplerObject =
+ mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler);
+ SetSamplerParameteri(this, samplerObject, pname, param);
+}
+
+void Context::samplerParameteriv(SamplerID sampler, GLenum pname, const GLint *param)
+{
+ Sampler *const samplerObject =
+ mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler);
+ SetSamplerParameteriv(this, samplerObject, pname, param);
+}
+
+void Context::samplerParameterIiv(SamplerID sampler, GLenum pname, const GLint *param)
+{
+ Sampler *const samplerObject =
+ mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler);
+ SetSamplerParameterIiv(this, samplerObject, pname, param);
+}
+
+void Context::samplerParameterIuiv(SamplerID sampler, GLenum pname, const GLuint *param)
+{
+ Sampler *const samplerObject =
+ mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler);
+ SetSamplerParameterIuiv(this, samplerObject, pname, param);
+}
+
+void Context::samplerParameterivRobust(SamplerID sampler,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLint *param)
+{
+ samplerParameteriv(sampler, pname, param);
+}
+
+void Context::samplerParameterIivRobust(SamplerID sampler,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLint *param)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::samplerParameterIuivRobust(SamplerID sampler,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLuint *param)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::samplerParameterf(SamplerID sampler, GLenum pname, GLfloat param)
+{
+ Sampler *const samplerObject =
+ mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler);
+ SetSamplerParameterf(this, samplerObject, pname, param);
+}
+
+void Context::samplerParameterfv(SamplerID sampler, GLenum pname, const GLfloat *param)
+{
+ Sampler *const samplerObject =
+ mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler);
+ SetSamplerParameterfv(this, samplerObject, pname, param);
+}
+
+void Context::samplerParameterfvRobust(SamplerID sampler,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLfloat *param)
+{
+ samplerParameterfv(sampler, pname, param);
+}
+
+void Context::getSamplerParameteriv(SamplerID sampler, GLenum pname, GLint *params)
+{
+ const Sampler *const samplerObject =
+ mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler);
+ QuerySamplerParameteriv(samplerObject, pname, params);
+}
+
+void Context::getSamplerParameterIiv(SamplerID sampler, GLenum pname, GLint *params)
+{
+ const Sampler *const samplerObject =
+ mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler);
+ QuerySamplerParameterIiv(samplerObject, pname, params);
+}
+
+void Context::getSamplerParameterIuiv(SamplerID sampler, GLenum pname, GLuint *params)
+{
+ const Sampler *const samplerObject =
+ mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler);
+ QuerySamplerParameterIuiv(samplerObject, pname, params);
+}
+
+void Context::getSamplerParameterivRobust(SamplerID sampler,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ getSamplerParameteriv(sampler, pname, params);
+}
+
+void Context::getSamplerParameterIivRobust(SamplerID sampler,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getSamplerParameterIuivRobust(SamplerID sampler,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getSamplerParameterfv(SamplerID sampler, GLenum pname, GLfloat *params)
+{
+ const Sampler *const samplerObject =
+ mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler);
+ QuerySamplerParameterfv(samplerObject, pname, params);
+}
+
+void Context::getSamplerParameterfvRobust(SamplerID sampler,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params)
+{
+ getSamplerParameterfv(sampler, pname, params);
+}
+
+void Context::programParameteri(ShaderProgramID program, GLenum pname, GLint value)
+{
+ gl::Program *programObject = getProgramResolveLink(program);
+ SetProgramParameteri(programObject, pname, value);
+}
+
+void Context::initRendererString()
+{
+ std::ostringstream frontendRendererString;
+ std::string vendorString(mDisplay->getBackendVendorString());
+ std::string rendererString(mDisplay->getBackendRendererDescription());
+ std::string versionString(mDisplay->getBackendVersionString(!isWebGL()));
+ // Commas are used as a separator in ANGLE's renderer string, so remove commas from each
+ // element.
+ vendorString.erase(std::remove(vendorString.begin(), vendorString.end(), ','),
+ vendorString.end());
+ rendererString.erase(std::remove(rendererString.begin(), rendererString.end(), ','),
+ rendererString.end());
+ versionString.erase(std::remove(versionString.begin(), versionString.end(), ','),
+ versionString.end());
+ frontendRendererString << "ANGLE (";
+ frontendRendererString << vendorString;
+ frontendRendererString << ", ";
+ frontendRendererString << rendererString;
+ frontendRendererString << ", ";
+ frontendRendererString << versionString;
+ frontendRendererString << ")";
+
+ mRendererString = MakeStaticString(frontendRendererString.str());
+}
+
+void Context::initVersionStrings()
+{
+ const Version &clientVersion = getClientVersion();
+
+ std::ostringstream versionString;
+ if (getClientType() == EGL_OPENGL_ES_API)
+ {
+ versionString << "OpenGL ES ";
+ }
+ versionString << clientVersion.major << "." << clientVersion.minor << ".0 (ANGLE "
+ << angle::GetANGLEVersionString() << ")";
+ mVersionString = MakeStaticString(versionString.str());
+
+ std::ostringstream shadingLanguageVersionString;
+ if (getClientType() == EGL_OPENGL_ES_API)
+ {
+ shadingLanguageVersionString << "OpenGL ES GLSL ES ";
+ }
+ else
+ {
+ ASSERT(getClientType() == EGL_OPENGL_API);
+ shadingLanguageVersionString << "OpenGL GLSL ";
+ }
+ shadingLanguageVersionString << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
+ << clientVersion.minor << "0 (ANGLE "
+ << angle::GetANGLEVersionString() << ")";
+ mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
+}
+
+void Context::initExtensionStrings()
+{
+ auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
+ std::ostringstream combinedStringStream;
+ std::copy(strings.begin(), strings.end(),
+ std::ostream_iterator<const char *>(combinedStringStream, " "));
+ return MakeStaticString(combinedStringStream.str());
+ };
+
+ mExtensionStrings.clear();
+ for (const auto &extensionString : mState.mExtensions.getStrings())
+ {
+ mExtensionStrings.push_back(MakeStaticString(extensionString));
+ }
+ mExtensionString = mergeExtensionStrings(mExtensionStrings);
+
+ mRequestableExtensionStrings.clear();
+ for (const auto &extensionInfo : GetExtensionInfoMap())
+ {
+ if (extensionInfo.second.Requestable &&
+ !(mState.mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
+ mSupportedExtensions.*(extensionInfo.second.ExtensionsMember))
+ {
+ mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
+ }
+ }
+ mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
+}
+
+const GLubyte *Context::getString(GLenum name)
+{
+ return static_cast<const Context *>(this)->getString(name);
+}
+
+const GLubyte *Context::getStringi(GLenum name, GLuint index)
+{
+ return static_cast<const Context *>(this)->getStringi(name, index);
+}
+
+const GLubyte *Context::getString(GLenum name) const
+{
+ switch (name)
+ {
+ case GL_VENDOR:
+ return reinterpret_cast<const GLubyte *>(mDisplay->getVendorString().c_str());
+
+ case GL_RENDERER:
+ return reinterpret_cast<const GLubyte *>(mRendererString);
+
+ case GL_VERSION:
+ return reinterpret_cast<const GLubyte *>(mVersionString);
+
+ case GL_SHADING_LANGUAGE_VERSION:
+ return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
+
+ case GL_EXTENSIONS:
+ return reinterpret_cast<const GLubyte *>(mExtensionString);
+
+ case GL_REQUESTABLE_EXTENSIONS_ANGLE:
+ return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
+
+ case GL_SERIALIZED_CONTEXT_STRING_ANGLE:
+ if (angle::SerializeContextToString(this, &mCachedSerializedStateString) ==
+ angle::Result::Continue)
+ {
+ return reinterpret_cast<const GLubyte *>(mCachedSerializedStateString.c_str());
+ }
+ else
+ {
+ return nullptr;
+ }
+
+ default:
+ UNREACHABLE();
+ return nullptr;
+ }
+}
+
+const GLubyte *Context::getStringi(GLenum name, GLuint index) const
+{
+ switch (name)
+ {
+ case GL_EXTENSIONS:
+ return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
+
+ case GL_REQUESTABLE_EXTENSIONS_ANGLE:
+ return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
+
+ default:
+ UNREACHABLE();
+ return nullptr;
+ }
+}
+
+size_t Context::getExtensionStringCount() const
+{
+ return mExtensionStrings.size();
+}
+
+bool Context::isExtensionRequestable(const char *name) const
+{
+ const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
+ auto extension = extensionInfos.find(name);
+
+ return extension != extensionInfos.end() && extension->second.Requestable &&
+ mSupportedExtensions.*(extension->second.ExtensionsMember);
+}
+
+bool Context::isExtensionDisablable(const char *name) const
+{
+ const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
+ auto extension = extensionInfos.find(name);
+
+ return extension != extensionInfos.end() && extension->second.Disablable &&
+ mSupportedExtensions.*(extension->second.ExtensionsMember);
+}
+
+void Context::requestExtension(const char *name)
+{
+ setExtensionEnabled(name, true);
+}
+void Context::disableExtension(const char *name)
+{
+ setExtensionEnabled(name, false);
+}
+
+void Context::setExtensionEnabled(const char *name, bool enabled)
+{
+ // OVR_multiview is implicitly enabled when OVR_multiview2 is enabled
+ if (strcmp(name, "GL_OVR_multiview2") == 0)
+ {
+ setExtensionEnabled("GL_OVR_multiview", enabled);
+ }
+ const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
+ ASSERT(extensionInfos.find(name) != extensionInfos.end());
+ const auto &extension = extensionInfos.at(name);
+ ASSERT(extension.Requestable);
+ ASSERT(isExtensionRequestable(name));
+
+ if (mState.mExtensions.*(extension.ExtensionsMember) == enabled)
+ {
+ // No change
+ return;
+ }
+
+ mState.mExtensions.*(extension.ExtensionsMember) = enabled;
+
+ reinitializeAfterExtensionsChanged();
+}
+
+void Context::reinitializeAfterExtensionsChanged()
+{
+ updateCaps();
+ initExtensionStrings();
+
+ // Release the shader compiler so it will be re-created with the requested extensions enabled.
+ releaseShaderCompiler();
+
+ // Invalidate all textures and framebuffer. Some extensions make new formats renderable or
+ // sampleable.
+ mState.mTextureManager->signalAllTexturesDirty();
+ for (auto &zeroTexture : mZeroTextures)
+ {
+ if (zeroTexture.get() != nullptr)
+ {
+ zeroTexture->signalDirtyStorage(InitState::Initialized);
+ }
+ }
+
+ mState.mFramebufferManager->invalidateFramebufferCompletenessCache();
+}
+
+size_t Context::getRequestableExtensionStringCount() const
+{
+ return mRequestableExtensionStrings.size();
+}
+
+void Context::beginTransformFeedback(PrimitiveMode primitiveMode)
+{
+ TransformFeedback *transformFeedback = mState.getCurrentTransformFeedback();
+ ASSERT(transformFeedback != nullptr);
+ ASSERT(!transformFeedback->isPaused());
+
+ // TODO: http://anglebug.com/7232: Handle PPOs
+ ANGLE_CONTEXT_TRY(transformFeedback->begin(this, primitiveMode, mState.getProgram()));
+ mStateCache.onActiveTransformFeedbackChange(this);
+}
+
+bool Context::hasActiveTransformFeedback(ShaderProgramID program) const
+{
+ for (auto pair : mTransformFeedbackMap)
+ {
+ if (pair.second != nullptr && pair.second->hasBoundProgram(program))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+Extensions Context::generateSupportedExtensions() const
+{
+ Extensions supportedExtensions = mImplementation->getNativeExtensions();
+
+ if (getClientVersion() < ES_2_0)
+ {
+ // Default extensions for GLES1
+ supportedExtensions.pointSizeArrayOES = true;
+ supportedExtensions.textureCubeMapOES = true;
+ supportedExtensions.pointSpriteOES = true;
+ supportedExtensions.drawTextureOES = true;
+ supportedExtensions.framebufferObjectOES = true;
+ supportedExtensions.parallelShaderCompileKHR = false;
+ supportedExtensions.texture3DOES = false;
+ supportedExtensions.clipDistanceAPPLE = false;
+ }
+
+ if (getClientVersion() < ES_3_0)
+ {
+ // Disable ES3+ extensions
+ supportedExtensions.colorBufferFloatEXT = false;
+ supportedExtensions.EGLImageExternalEssl3OES = false;
+ supportedExtensions.multiviewOVR = false;
+ supportedExtensions.multiview2OVR = false;
+ supportedExtensions.multiviewMultisampleANGLE = false;
+ supportedExtensions.copyTexture3dANGLE = false;
+ supportedExtensions.textureMultisampleANGLE = false;
+ supportedExtensions.drawBuffersIndexedEXT = false;
+ supportedExtensions.drawBuffersIndexedOES = false;
+ supportedExtensions.EGLImageArrayEXT = false;
+ supportedExtensions.textureFormatSRGBOverrideEXT = false;
+
+ // Support GL_EXT_texture_norm16 on non-WebGL ES2 contexts. This is needed for R16/RG16
+ // texturing for HDR video playback in Chromium which uses ES2 for compositor contexts.
+ // Remove this workaround after Chromium migrates to ES3 for compositor contexts.
+ if (mWebGLContext || getClientVersion() < ES_2_0)
+ {
+ supportedExtensions.textureNorm16EXT = false;
+ }
+
+ // Requires immutable textures
+ supportedExtensions.yuvInternalFormatANGLE = false;
+
+ // Require ESSL 3.0
+ supportedExtensions.shaderMultisampleInterpolationOES = false;
+ supportedExtensions.shaderNoperspectiveInterpolationNV = false;
+ supportedExtensions.sampleVariablesOES = false;
+
+ // Require ES 3.1 but could likely be exposed on 3.0
+ supportedExtensions.textureCubeMapArrayEXT = false;
+ supportedExtensions.textureCubeMapArrayOES = false;
+
+ // Require RED and RG formats
+ supportedExtensions.textureSRGBR8EXT = false;
+ supportedExtensions.textureSRGBRG8EXT = false;
+
+ // Requires glCompressedTexImage3D
+ supportedExtensions.textureCompressionAstcOES = false;
+
+ // Don't expose GL_EXT_texture_sRGB_decode without sRGB texture support
+ if (!supportedExtensions.sRGBEXT)
+ {
+ supportedExtensions.textureSRGBDecodeEXT = false;
+ }
+
+ // Don't expose GL_OES_texture_float_linear without full legacy float texture support
+ // The renderer may report OES_texture_float_linear without OES_texture_float
+ // This is valid in a GLES 3.0 context, but not in a GLES 2.0 context
+ if (!(supportedExtensions.textureFloatOES && supportedExtensions.textureHalfFloatOES))
+ {
+ supportedExtensions.textureFloatLinearOES = false;
+ supportedExtensions.textureHalfFloatLinearOES = false;
+ }
+
+ // Because of the difference in the SNORM to FLOAT conversion formula
+ // between GLES 2.0 and 3.0, vertex type 10_10_10_2 is disabled
+ // when the context version is lower than 3.0
+ supportedExtensions.vertexType1010102OES = false;
+
+ // GL_EXT_EGL_image_storage requires ESSL3
+ supportedExtensions.EGLImageStorageEXT = false;
+
+ // GL_EXT_YUV_target requires ESSL3
+ supportedExtensions.YUVTargetEXT = false;
+
+ // GL_EXT_clip_cull_distance requires ESSL3
+ supportedExtensions.clipCullDistanceEXT = false;
+
+ // ANGLE_shader_pixel_local_storage requires ES3
+ supportedExtensions.shaderPixelLocalStorageANGLE = false;
+ supportedExtensions.shaderPixelLocalStorageCoherentANGLE = false;
+ }
+
+ if (getClientVersion() < ES_3_1)
+ {
+ // Disable ES3.1+ extensions
+ supportedExtensions.geometryShaderEXT = false;
+ supportedExtensions.geometryShaderOES = false;
+ supportedExtensions.gpuShader5EXT = false;
+ supportedExtensions.primitiveBoundingBoxEXT = false;
+ supportedExtensions.shaderImageAtomicOES = false;
+ supportedExtensions.shaderIoBlocksEXT = false;
+ supportedExtensions.shaderIoBlocksOES = false;
+ supportedExtensions.tessellationShaderEXT = false;
+ supportedExtensions.textureBufferEXT = false;
+ supportedExtensions.textureBufferOES = false;
+
+ // TODO(http://anglebug.com/2775): Multisample arrays could be supported on ES 3.0 as well
+ // once 2D multisample texture extension is exposed there.
+ supportedExtensions.textureStorageMultisample2dArrayOES = false;
+ }
+
+ if (getClientVersion() > ES_2_0)
+ {
+ // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
+ // supportedExtensions.sRGB = false;
+
+ // If colorBufferFloatEXT is disabled but colorBufferHalfFloatEXT is enabled, then we will
+ // expose some floating-point formats as color buffer targets but reject blits between
+ // fixed-point and floating-point formats (this behavior is only enabled in
+ // colorBufferFloatEXT, and must be rejected if only colorBufferHalfFloatEXT is enabled).
+ // dEQP does not check for this, and will assume that floating-point and fixed-point formats
+ // can be blit onto each other if the format is available.
+ // We require colorBufferFloatEXT to be present in order to enable colorBufferHalfFloatEXT,
+ // so that blitting is always allowed if the requested formats are exposed and have the
+ // correct feature capabilities. WebGL 2 wants to support colorBufferHalfFloatEXT without
+ // colorBufferFloatEXT.
+ if (!supportedExtensions.colorBufferFloatEXT && !mWebGLContext)
+ {
+ supportedExtensions.colorBufferHalfFloatEXT = false;
+ }
+
+ // Disable support for CHROMIUM_color_buffer_float_rgb[a] in ES 3.0+, these extensions are
+ // non-conformant in ES 3.0 and superseded by EXT_color_buffer_float.
+ supportedExtensions.colorBufferFloatRgbCHROMIUM = false;
+ supportedExtensions.colorBufferFloatRgbaCHROMIUM = false;
+ }
+
+ if (getFrontendFeatures().disableDrawBuffersIndexed.enabled)
+ {
+ supportedExtensions.drawBuffersIndexedEXT = false;
+ supportedExtensions.drawBuffersIndexedOES = false;
+ }
+
+ if (getFrontendFeatures().disableAnisotropicFiltering.enabled)
+ {
+ supportedExtensions.textureFilterAnisotropicEXT = false;
+ }
+
+ if (!getFrontendFeatures().emulatePixelLocalStorage.enabled)
+ {
+ supportedExtensions.shaderPixelLocalStorageANGLE = false;
+ supportedExtensions.shaderPixelLocalStorageCoherentANGLE = false;
+ }
+
+ // Some extensions are always available because they are implemented in the GL layer.
+ supportedExtensions.bindUniformLocationCHROMIUM = true;
+ supportedExtensions.vertexArrayObjectOES = true;
+ supportedExtensions.bindGeneratesResourceCHROMIUM = true;
+ supportedExtensions.clientArraysANGLE = true;
+ supportedExtensions.requestExtensionANGLE = true;
+ supportedExtensions.multiDrawANGLE = true;
+
+ // Enable the no error extension if the context was created with the flag.
+ supportedExtensions.noErrorKHR = mSkipValidation;
+
+ // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
+ supportedExtensions.surfacelessContextOES = mSurfacelessSupported;
+
+ // Explicitly enable GL_KHR_debug
+ supportedExtensions.debugKHR = true;
+
+ // Explicitly enable GL_EXT_debug_label
+ supportedExtensions.debugLabelEXT = true;
+
+ // Explicitly enable GL_ANGLE_robust_client_memory if the context supports validation.
+ supportedExtensions.robustClientMemoryANGLE = !mSkipValidation;
+
+ // Determine robust resource init availability from EGL.
+ supportedExtensions.robustResourceInitializationANGLE = mState.isRobustResourceInitEnabled();
+
+ // mState.mExtensions.robustBufferAccessBehaviorKHR is true only if robust access is true and
+ // the backend supports it.
+ supportedExtensions.robustBufferAccessBehaviorKHR =
+ mState.hasRobustAccess() && supportedExtensions.robustBufferAccessBehaviorKHR;
+
+ // Enable the cache control query unconditionally.
+ supportedExtensions.programCacheControlANGLE = true;
+
+ // If EGL_KHR_fence_sync is not enabled, don't expose GL_OES_EGL_sync.
+ ASSERT(mDisplay);
+ if (!mDisplay->getExtensions().fenceSync)
+ {
+ supportedExtensions.EGLSyncOES = false;
+ }
+
+ if (mDisplay->getExtensions().robustnessVideoMemoryPurgeNV)
+ {
+ supportedExtensions.robustnessVideoMemoryPurgeNV = true;
+ }
+
+ supportedExtensions.memorySizeANGLE = true;
+
+ // GL_CHROMIUM_lose_context is implemented in the frontend
+ supportedExtensions.loseContextCHROMIUM = true;
+
+ // The ASTC texture extensions have dependency requirements.
+ if (supportedExtensions.textureCompressionAstcHdrKHR ||
+ supportedExtensions.textureCompressionAstcSliced3dKHR)
+ {
+ // GL_KHR_texture_compression_astc_hdr cannot be exposed without also exposing
+ // GL_KHR_texture_compression_astc_ldr
+ ASSERT(supportedExtensions.textureCompressionAstcLdrKHR);
+ }
+
+ if (supportedExtensions.textureCompressionAstcOES)
+ {
+ // GL_OES_texture_compression_astc cannot be exposed without also exposing
+ // GL_KHR_texture_compression_astc_ldr and GL_KHR_texture_compression_astc_hdr
+ ASSERT(supportedExtensions.textureCompressionAstcLdrKHR);
+ ASSERT(supportedExtensions.textureCompressionAstcHdrKHR);
+ }
+
+ // GL_KHR_protected_textures
+ // If EGL_KHR_protected_content is not supported then GL_EXT_protected_texture
+ // can not be supported.
+ if (!mDisplay->getExtensions().protectedContentEXT)
+ {
+ supportedExtensions.protectedTexturesEXT = false;
+ }
+
+ // GL_ANGLE_get_tex_level_parameter is implemented in the front-end
+ supportedExtensions.getTexLevelParameterANGLE = true;
+
+ // Always enabled. Will return a default string if capture is not enabled.
+ supportedExtensions.getSerializedContextStringANGLE = true;
+
+ // Performance counter queries are always supported. Different groups exist on each back-end.
+ supportedExtensions.performanceMonitorAMD = true;
+
+ // GL_ANDROID_extension_pack_es31a
+ supportedExtensions.extensionPackEs31aANDROID =
+ CanSupportAEP(getClientVersion(), supportedExtensions);
+
+ return supportedExtensions;
+}
+
+void Context::initCaps()
+{
+ mState.mCaps = mImplementation->getNativeCaps();
+
+ // TODO (http://anglebug.com/6010): mSupportedExtensions should not be modified here
+ mSupportedExtensions = generateSupportedExtensions();
+
+ if (!mDisplay->getFrontendFeatures().allowCompressedFormats.enabled)
+ {
+ INFO() << "Limiting compressed format support.\n";
+
+ mSupportedExtensions.compressedEACR11SignedTextureOES = false;
+ mSupportedExtensions.compressedEACR11UnsignedTextureOES = false;
+ mSupportedExtensions.compressedEACRG11SignedTextureOES = false;
+ mSupportedExtensions.compressedEACRG11UnsignedTextureOES = false;
+ mSupportedExtensions.compressedETC1RGB8SubTextureEXT = false;
+ mSupportedExtensions.compressedETC1RGB8TextureOES = false;
+ mSupportedExtensions.compressedETC2PunchthroughARGBA8TextureOES = false;
+ mSupportedExtensions.compressedETC2PunchthroughASRGB8AlphaTextureOES = false;
+ mSupportedExtensions.compressedETC2RGB8TextureOES = false;
+ mSupportedExtensions.compressedETC2RGBA8TextureOES = false;
+ mSupportedExtensions.compressedETC2SRGB8Alpha8TextureOES = false;
+ mSupportedExtensions.compressedETC2SRGB8TextureOES = false;
+ mSupportedExtensions.compressedTextureEtcANGLE = false;
+ mSupportedExtensions.textureCompressionPvrtcIMG = false;
+ mSupportedExtensions.pvrtcSRGBEXT = false;
+ mSupportedExtensions.copyCompressedTextureCHROMIUM = false;
+ mSupportedExtensions.textureCompressionAstcHdrKHR = false;
+ mSupportedExtensions.textureCompressionAstcLdrKHR = false;
+ mSupportedExtensions.textureCompressionAstcOES = false;
+ mSupportedExtensions.textureCompressionBptcEXT = false;
+ mSupportedExtensions.textureCompressionDxt1EXT = false;
+ mSupportedExtensions.textureCompressionDxt3ANGLE = false;
+ mSupportedExtensions.textureCompressionDxt5ANGLE = false;
+ mSupportedExtensions.textureCompressionRgtcEXT = false;
+ mSupportedExtensions.textureCompressionS3tcSrgbEXT = false;
+ mSupportedExtensions.textureCompressionAstcSliced3dKHR = false;
+ mSupportedExtensions.textureFilteringHintCHROMIUM = false;
+
+ mState.mCaps.compressedTextureFormats.clear();
+ }
+
+ mState.mExtensions = mSupportedExtensions;
+
+ mState.mLimitations = mImplementation->getNativeLimitations();
+
+ // GLES1 emulation: Initialize caps (Table 6.20 / 6.22 in the ES 1.1 spec)
+ if (getClientType() == EGL_OPENGL_API || getClientVersion() < Version(2, 0))
+ {
+ mState.mCaps.maxMultitextureUnits = 4;
+ mState.mCaps.maxClipPlanes = 6;
+ mState.mCaps.maxLights = 8;
+ mState.mCaps.maxModelviewMatrixStackDepth = Caps::GlobalMatrixStackDepth;
+ mState.mCaps.maxProjectionMatrixStackDepth = Caps::GlobalMatrixStackDepth;
+ mState.mCaps.maxTextureMatrixStackDepth = Caps::GlobalMatrixStackDepth;
+ mState.mCaps.minSmoothPointSize = 1.0f;
+ mState.mCaps.maxSmoothPointSize = 1.0f;
+ mState.mCaps.minSmoothLineWidth = 1.0f;
+ mState.mCaps.maxSmoothLineWidth = 1.0f;
+ }
+
+ mState.mCaps.maxDebugMessageLength = 1024;
+ mState.mCaps.maxDebugLoggedMessages = 1024;
+ mState.mCaps.maxDebugGroupStackDepth = 1024;
+ mState.mCaps.maxLabelLength = 1024;
+
+ if (getClientVersion() < Version(3, 0))
+ {
+ mState.mCaps.maxViews = 1u;
+ }
+
+#if 0
+// This logging can generate a lot of spam in test suites that create many contexts
+# define ANGLE_LOG_LIMITED_CAP(cap, limit) \
+ INFO() << "Limiting " << #cap << " to implementation limit " << (limit) << " (was " \
+ << (cap) << ")."
+#else
+# define ANGLE_LOG_LIMITED_CAP(cap, limit)
+#endif
+
+#define ANGLE_LIMIT_CAP(cap, limit) \
+ do \
+ { \
+ if ((cap) > (limit)) \
+ { \
+ ANGLE_LOG_LIMITED_CAP(cap, limit); \
+ (cap) = (limit); \
+ } \
+ } while (0)
+
+ // Apply/Verify implementation limits
+ ANGLE_LIMIT_CAP(mState.mCaps.maxDrawBuffers, IMPLEMENTATION_MAX_DRAW_BUFFERS);
+ ANGLE_LIMIT_CAP(mState.mCaps.maxColorAttachments, IMPLEMENTATION_MAX_DRAW_BUFFERS);
+ ANGLE_LIMIT_CAP(mState.mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
+ ANGLE_LIMIT_CAP(mState.mCaps.maxVertexAttribStride,
+ static_cast<GLint>(limits::kMaxVertexAttribStride));
+
+ ASSERT(mState.mCaps.minAliasedPointSize >= 1.0f);
+
+ if (getClientVersion() < ES_3_1)
+ {
+ mState.mCaps.maxVertexAttribBindings = mState.mCaps.maxVertexAttributes;
+ }
+ else
+ {
+ ANGLE_LIMIT_CAP(mState.mCaps.maxVertexAttribBindings, MAX_VERTEX_ATTRIB_BINDINGS);
+ }
+
+ if (mWebGLContext && getLimitations().limitWebglMaxTextureSizeTo4096)
+ {
+ constexpr GLint kMaxTextureSize = 4096;
+ ANGLE_LIMIT_CAP(mState.mCaps.max2DTextureSize, kMaxTextureSize);
+ ANGLE_LIMIT_CAP(mState.mCaps.max3DTextureSize, kMaxTextureSize);
+ ANGLE_LIMIT_CAP(mState.mCaps.maxCubeMapTextureSize, kMaxTextureSize);
+ ANGLE_LIMIT_CAP(mState.mCaps.maxArrayTextureLayers, kMaxTextureSize);
+ ANGLE_LIMIT_CAP(mState.mCaps.maxRectangleTextureSize, kMaxTextureSize);
+ }
+
+ ANGLE_LIMIT_CAP(mState.mCaps.max2DTextureSize, IMPLEMENTATION_MAX_2D_TEXTURE_SIZE);
+ ANGLE_LIMIT_CAP(mState.mCaps.maxCubeMapTextureSize, IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE);
+ ANGLE_LIMIT_CAP(mState.mCaps.max3DTextureSize, IMPLEMENTATION_MAX_3D_TEXTURE_SIZE);
+ ANGLE_LIMIT_CAP(mState.mCaps.maxArrayTextureLayers, IMPLEMENTATION_MAX_2D_ARRAY_TEXTURE_LAYERS);
+ ANGLE_LIMIT_CAP(mState.mCaps.maxRectangleTextureSize, IMPLEMENTATION_MAX_2D_TEXTURE_SIZE);
+
+ ANGLE_LIMIT_CAP(mState.mCaps.maxShaderUniformBlocks[ShaderType::Vertex],
+ IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
+ ANGLE_LIMIT_CAP(mState.mCaps.maxShaderUniformBlocks[ShaderType::Geometry],
+ IMPLEMENTATION_MAX_GEOMETRY_SHADER_UNIFORM_BUFFERS);
+ ANGLE_LIMIT_CAP(mState.mCaps.maxShaderUniformBlocks[ShaderType::Fragment],
+ IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS);
+ ANGLE_LIMIT_CAP(mState.mCaps.maxShaderUniformBlocks[ShaderType::Compute],
+ IMPLEMENTATION_MAX_COMPUTE_SHADER_UNIFORM_BUFFERS);
+ ANGLE_LIMIT_CAP(mState.mCaps.maxCombinedUniformBlocks,
+ IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS);
+ ANGLE_LIMIT_CAP(mState.mCaps.maxUniformBufferBindings,
+ IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS);
+
+ ANGLE_LIMIT_CAP(mState.mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
+ ANGLE_LIMIT_CAP(mState.mCaps.maxFragmentInputComponents,
+ IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
+
+ ANGLE_LIMIT_CAP(mState.mCaps.maxTransformFeedbackInterleavedComponents,
+ IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS);
+ ANGLE_LIMIT_CAP(mState.mCaps.maxTransformFeedbackSeparateAttributes,
+ IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS);
+ ANGLE_LIMIT_CAP(mState.mCaps.maxTransformFeedbackSeparateComponents,
+ IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS);
+
+ if (getClientVersion() < ES_3_2 && !mState.mExtensions.tessellationShaderEXT)
+ {
+ ANGLE_LIMIT_CAP(mState.mCaps.maxCombinedTextureImageUnits,
+ IMPLEMENTATION_MAX_ES31_ACTIVE_TEXTURES);
+ }
+ else
+ {
+ ANGLE_LIMIT_CAP(mState.mCaps.maxCombinedTextureImageUnits,
+ IMPLEMENTATION_MAX_ACTIVE_TEXTURES);
+ }
+
+ for (ShaderType shaderType : AllShaderTypes())
+ {
+ ANGLE_LIMIT_CAP(mState.mCaps.maxShaderTextureImageUnits[shaderType],
+ IMPLEMENTATION_MAX_SHADER_TEXTURES);
+ }
+
+ ANGLE_LIMIT_CAP(mState.mCaps.maxImageUnits, IMPLEMENTATION_MAX_IMAGE_UNITS);
+ ANGLE_LIMIT_CAP(mState.mCaps.maxCombinedImageUniforms, IMPLEMENTATION_MAX_IMAGE_UNITS);
+ for (ShaderType shaderType : AllShaderTypes())
+ {
+ ANGLE_LIMIT_CAP(mState.mCaps.maxShaderImageUniforms[shaderType],
+ IMPLEMENTATION_MAX_IMAGE_UNITS);
+ }
+
+ for (ShaderType shaderType : AllShaderTypes())
+ {
+ ANGLE_LIMIT_CAP(mState.mCaps.maxShaderAtomicCounterBuffers[shaderType],
+ IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS);
+ }
+ ANGLE_LIMIT_CAP(mState.mCaps.maxAtomicCounterBufferBindings,
+ IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS);
+ ANGLE_LIMIT_CAP(mState.mCaps.maxCombinedAtomicCounterBuffers,
+ IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS);
+
+ for (ShaderType shaderType : AllShaderTypes())
+ {
+ ANGLE_LIMIT_CAP(mState.mCaps.maxShaderStorageBlocks[shaderType],
+ IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS);
+ }
+ ANGLE_LIMIT_CAP(mState.mCaps.maxShaderStorageBufferBindings,
+ IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS);
+ ANGLE_LIMIT_CAP(mState.mCaps.maxCombinedShaderStorageBlocks,
+ IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS);
+
+ ANGLE_LIMIT_CAP(mState.mCaps.maxClipDistances, IMPLEMENTATION_MAX_CLIP_DISTANCES);
+
+ ANGLE_LIMIT_CAP(mState.mCaps.maxFramebufferLayers, IMPLEMENTATION_MAX_FRAMEBUFFER_LAYERS);
+
+ ANGLE_LIMIT_CAP(mState.mCaps.maxSampleMaskWords, IMPLEMENTATION_MAX_SAMPLE_MASK_WORDS);
+ ANGLE_LIMIT_CAP(mState.mCaps.maxSamples, IMPLEMENTATION_MAX_SAMPLES);
+ ANGLE_LIMIT_CAP(mState.mCaps.maxFramebufferSamples, IMPLEMENTATION_MAX_SAMPLES);
+ ANGLE_LIMIT_CAP(mState.mCaps.maxColorTextureSamples, IMPLEMENTATION_MAX_SAMPLES);
+ ANGLE_LIMIT_CAP(mState.mCaps.maxDepthTextureSamples, IMPLEMENTATION_MAX_SAMPLES);
+ ANGLE_LIMIT_CAP(mState.mCaps.maxIntegerSamples, IMPLEMENTATION_MAX_SAMPLES);
+
+ ANGLE_LIMIT_CAP(mState.mCaps.maxViews, IMPLEMENTATION_ANGLE_MULTIVIEW_MAX_VIEWS);
+
+ ANGLE_LIMIT_CAP(mState.mCaps.maxDualSourceDrawBuffers,
+ IMPLEMENTATION_MAX_DUAL_SOURCE_DRAW_BUFFERS);
+
+ // WebGL compatibility
+ mState.mExtensions.webglCompatibilityANGLE = mWebGLContext;
+ for (const auto &extensionInfo : GetExtensionInfoMap())
+ {
+ // If the user has requested that extensions start disabled and they are requestable,
+ // disable them.
+ if (!mExtensionsEnabled && extensionInfo.second.Requestable)
+ {
+ mState.mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
+ }
+ }
+
+ // Hide emulated ETC1 extension from WebGL contexts.
+ if (mWebGLContext && getLimitations().emulatedEtc1)
+ {
+ mSupportedExtensions.compressedETC1RGB8SubTextureEXT = false;
+ mSupportedExtensions.compressedETC1RGB8TextureOES = false;
+ }
+
+ if (getLimitations().emulatedAstc)
+ {
+ // Hide emulated ASTC extension from WebGL contexts.
+ if (mWebGLContext)
+ {
+ mSupportedExtensions.textureCompressionAstcLdrKHR = false;
+ mState.mExtensions.textureCompressionAstcLdrKHR = false;
+ }
+#if !defined(ANGLE_HAS_ASTCENC)
+ // Don't expose emulated ASTC when it's not built.
+ mSupportedExtensions.textureCompressionAstcLdrKHR = false;
+ mState.mExtensions.textureCompressionAstcLdrKHR = false;
+#endif
+ }
+
+ // If we're capturing application calls for replay, apply some feature limits to increase
+ // portability of the trace.
+ if (getShareGroup()->getFrameCaptureShared()->enabled() ||
+ getFrontendFeatures().enableCaptureLimits.enabled)
+ {
+ INFO() << "Limit some features because "
+ << (getShareGroup()->getFrameCaptureShared()->enabled()
+ ? "FrameCapture is enabled"
+ : "FrameCapture limits were forced")
+ << std::endl;
+
+ if (!getFrontendFeatures().enableProgramBinaryForCapture.enabled)
+ {
+ // Some apps insist on being able to use glProgramBinary. For those, we'll allow the
+ // extension to remain on. Otherwise, force the extension off.
+ INFO() << "Disabling GL_OES_get_program_binary for trace portability";
+ mDisplay->overrideFrontendFeatures({"disable_program_binary"}, true);
+ }
+
+ // Set to the most common limit per gpuinfo.org. Required for several platforms we test.
+ constexpr GLint maxImageUnits = 8;
+ INFO() << "Limiting image unit count to " << maxImageUnits;
+ ANGLE_LIMIT_CAP(mState.mCaps.maxImageUnits, maxImageUnits);
+ for (ShaderType shaderType : AllShaderTypes())
+ {
+ ANGLE_LIMIT_CAP(mState.mCaps.maxShaderImageUniforms[shaderType], maxImageUnits);
+ }
+
+ // Set a large uniform buffer offset alignment that works on multiple platforms.
+ // The offset used by the trace needs to be divisible by the device's actual value.
+ // Values seen during development: ARM (16), Intel (32), Qualcomm (128), Nvidia (256)
+ constexpr GLint uniformBufferOffsetAlignment = 256;
+ ASSERT(uniformBufferOffsetAlignment % mState.mCaps.uniformBufferOffsetAlignment == 0);
+ INFO() << "Setting uniform buffer offset alignment to " << uniformBufferOffsetAlignment;
+ mState.mCaps.uniformBufferOffsetAlignment = uniformBufferOffsetAlignment;
+
+ // Also limit texture buffer offset alignment, if enabled
+ if (mState.mExtensions.textureBufferAny())
+ {
+ constexpr GLint textureBufferOffsetAlignment =
+ gl::limits::kMinTextureBufferOffsetAlignment;
+ ASSERT(textureBufferOffsetAlignment % mState.mCaps.textureBufferOffsetAlignment == 0);
+ INFO() << "Setting texture buffer offset alignment to " << textureBufferOffsetAlignment;
+ mState.mCaps.textureBufferOffsetAlignment = textureBufferOffsetAlignment;
+ }
+
+ INFO() << "Disabling GL_EXT_map_buffer_range and GL_OES_mapbuffer during capture, which "
+ "are not supported on some native drivers";
+ mState.mExtensions.mapBufferRangeEXT = false;
+ mState.mExtensions.mapbufferOES = false;
+
+ INFO() << "Disabling GL_CHROMIUM_bind_uniform_location during capture, which is not "
+ "supported on native drivers";
+ mState.mExtensions.bindUniformLocationCHROMIUM = false;
+
+ INFO() << "Disabling GL_NV_shader_noperspective_interpolation during capture, which is not "
+ "supported on some native drivers";
+ mState.mExtensions.shaderNoperspectiveInterpolationNV = false;
+
+ INFO() << "Disabling GL_NV_framebuffer_blit during capture, which is not "
+ "supported on some native drivers";
+ mState.mExtensions.framebufferBlitNV = false;
+
+ // NVIDIA's Vulkan driver only supports 4 draw buffers
+ constexpr GLint maxDrawBuffers = 4;
+ INFO() << "Limiting draw buffer count to " << maxDrawBuffers;
+ ANGLE_LIMIT_CAP(mState.mCaps.maxDrawBuffers, maxDrawBuffers);
+
+ // Unity based applications are sending down GL streams with undefined behavior.
+ // Disabling EGL_KHR_create_context_no_error (which enables a new EGL attrib) prevents that,
+ // but we don't have the infrastructure for disabling EGL extensions yet.
+ // Instead, disable GL_KHR_no_error (which disables exposing the GL extension), which
+ // prevents writing invalid calls to the capture.
+ INFO() << "Enabling validation to prevent invalid calls from being captured. This "
+ "effectively disables GL_KHR_no_error and enables GL_ANGLE_robust_client_memory.";
+ mSkipValidation = false;
+ mState.mExtensions.noErrorKHR = mSkipValidation;
+ mState.mExtensions.robustClientMemoryANGLE = !mSkipValidation;
+
+ INFO() << "Disabling GL_OES_depth32 during capture, which is not widely supported on "
+ "mobile";
+ mState.mExtensions.depth32OES = false;
+
+ // Pixel 4 (Qualcomm) only supports 6 atomic counter buffer bindings.
+ constexpr GLint maxAtomicCounterBufferBindings = 6;
+ INFO() << "Limiting max atomic counter buffer bindings to "
+ << maxAtomicCounterBufferBindings;
+ ANGLE_LIMIT_CAP(mState.mCaps.maxAtomicCounterBufferBindings,
+ maxAtomicCounterBufferBindings);
+ for (gl::ShaderType shaderType : gl::AllShaderTypes())
+ {
+ ANGLE_LIMIT_CAP(mState.mCaps.maxShaderAtomicCounterBuffers[shaderType],
+ maxAtomicCounterBufferBindings);
+ }
+
+ // SwiftShader only supports 12 shader storage buffer bindings.
+ constexpr GLint maxShaderStorageBufferBindings = 12;
+ INFO() << "Limiting max shader storage buffer bindings to "
+ << maxShaderStorageBufferBindings;
+ ANGLE_LIMIT_CAP(mState.mCaps.maxShaderStorageBufferBindings,
+ maxShaderStorageBufferBindings);
+ for (gl::ShaderType shaderType : gl::AllShaderTypes())
+ {
+ ANGLE_LIMIT_CAP(mState.mCaps.maxShaderStorageBlocks[shaderType],
+ maxShaderStorageBufferBindings);
+ }
+
+ // Pixel 4 only supports GL_MAX_SAMPLES of 4
+ constexpr GLint maxSamples = 4;
+ INFO() << "Limiting GL_MAX_SAMPLES to " << maxSamples;
+ ANGLE_LIMIT_CAP(mState.mCaps.maxSamples, maxSamples);
+ }
+
+ // Disable support for OES_get_program_binary
+ if (mDisplay->getFrontendFeatures().disableProgramBinary.enabled)
+ {
+ mState.mExtensions.getProgramBinaryOES = false;
+ mState.mCaps.shaderBinaryFormats.clear();
+ mState.mCaps.programBinaryFormats.clear();
+ mMemoryProgramCache = nullptr;
+ }
+
+ if (mSupportedExtensions.shaderPixelLocalStorageANGLE)
+ {
+ int maxDrawableAttachments =
+ std::min(mState.mCaps.maxDrawBuffers, mState.mCaps.maxColorAttachments);
+ ShPixelLocalStorageType plsType = mImplementation->getNativePixelLocalStorageType();
+ if (ShPixelLocalStorageTypeUsesImages(plsType))
+ {
+ mState.mCaps.maxPixelLocalStoragePlanes =
+ mState.mCaps.maxShaderImageUniforms[ShaderType::Fragment];
+ ANGLE_LIMIT_CAP(mState.mCaps.maxPixelLocalStoragePlanes,
+ IMPLEMENTATION_MAX_PIXEL_LOCAL_STORAGE_PLANES);
+ mState.mCaps.maxColorAttachmentsWithActivePixelLocalStorage =
+ mState.mCaps.maxColorAttachments;
+ mState.mCaps.maxCombinedDrawBuffersAndPixelLocalStoragePlanes = std::min<GLint>(
+ mState.mCaps.maxPixelLocalStoragePlanes +
+ std::min(mState.mCaps.maxDrawBuffers, mState.mCaps.maxColorAttachments),
+ mState.mCaps.maxCombinedShaderOutputResources);
+ }
+ else
+ {
+ ASSERT(plsType == ShPixelLocalStorageType::FramebufferFetch);
+ mState.mCaps.maxPixelLocalStoragePlanes = maxDrawableAttachments;
+ ANGLE_LIMIT_CAP(mState.mCaps.maxPixelLocalStoragePlanes,
+ IMPLEMENTATION_MAX_PIXEL_LOCAL_STORAGE_PLANES);
+ if (!mSupportedExtensions.drawBuffersIndexedAny())
+ {
+ // When pixel local storage is implemented as framebuffer attachments, we need to
+ // disable color masks and blending to its attachments. If the backend context
+ // doesn't have indexed blend and color mask support, then we will have have to
+ // disable them globally. This also means the application can't have its own draw
+ // buffers while PLS is active.
+ mState.mCaps.maxColorAttachmentsWithActivePixelLocalStorage = 0;
+ }
+ else
+ {
+ mState.mCaps.maxColorAttachmentsWithActivePixelLocalStorage =
+ maxDrawableAttachments - 1;
+ }
+ mState.mCaps.maxCombinedDrawBuffersAndPixelLocalStoragePlanes = maxDrawableAttachments;
+ }
+ }
+
+#undef ANGLE_LIMIT_CAP
+#undef ANGLE_LOG_CAP_LIMIT
+
+ // Generate texture caps
+ updateCaps();
+}
+
+void Context::updateCaps()
+{
+ mState.mCaps.compressedTextureFormats.clear();
+ mState.mTextureCaps.clear();
+
+ for (GLenum sizedInternalFormat : GetAllSizedInternalFormats())
+ {
+ TextureCaps formatCaps = mImplementation->getNativeTextureCaps().get(sizedInternalFormat);
+ const InternalFormat &formatInfo = GetSizedInternalFormatInfo(sizedInternalFormat);
+
+ // Update the format caps based on the client version and extensions.
+ // Caps are AND'd with the renderer caps because some core formats are still unsupported in
+ // ES3.
+ formatCaps.texturable = formatCaps.texturable &&
+ formatInfo.textureSupport(getClientVersion(), mState.mExtensions);
+ formatCaps.filterable = formatCaps.filterable &&
+ formatInfo.filterSupport(getClientVersion(), mState.mExtensions);
+ formatCaps.textureAttachment =
+ formatCaps.textureAttachment &&
+ formatInfo.textureAttachmentSupport(getClientVersion(), mState.mExtensions);
+ formatCaps.renderbuffer =
+ formatCaps.renderbuffer &&
+ formatInfo.renderbufferSupport(getClientVersion(), mState.mExtensions);
+ formatCaps.blendable =
+ formatCaps.blendable && formatInfo.blendSupport(getClientVersion(), mState.mExtensions);
+
+ // OpenGL ES does not support multisampling with non-rendererable formats
+ // OpenGL ES 3.0 or prior does not support multisampling with integer formats
+ if (!formatCaps.renderbuffer ||
+ (getClientVersion() < ES_3_1 && !mState.mExtensions.textureMultisampleANGLE &&
+ formatInfo.isInt()))
+ {
+ formatCaps.sampleCounts.clear();
+ }
+ else
+ {
+ // We may have limited the max samples for some required renderbuffer formats due to
+ // non-conformant formats. In this case MAX_SAMPLES needs to be lowered accordingly.
+ GLuint formatMaxSamples = formatCaps.getMaxSamples();
+
+ // GLES 3.0.5 section 4.4.2.2: "Implementations must support creation of renderbuffers
+ // in these required formats with up to the value of MAX_SAMPLES multisamples, with the
+ // exception of signed and unsigned integer formats."
+ if (!formatInfo.isInt() && formatInfo.isRequiredRenderbufferFormat(getClientVersion()))
+ {
+ ASSERT(getClientVersion() < ES_3_0 || formatMaxSamples >= 4);
+ mState.mCaps.maxSamples =
+ std::min(static_cast<GLuint>(mState.mCaps.maxSamples), formatMaxSamples);
+ }
+
+ // Handle GLES 3.1 MAX_*_SAMPLES values similarly to MAX_SAMPLES.
+ if (getClientVersion() >= ES_3_1 || mState.mExtensions.textureMultisampleANGLE)
+ {
+ // GLES 3.1 section 9.2.5: "Implementations must support creation of renderbuffers
+ // in these required formats with up to the value of MAX_SAMPLES multisamples, with
+ // the exception that the signed and unsigned integer formats are required only to
+ // support creation of renderbuffers with up to the value of MAX_INTEGER_SAMPLES
+ // multisamples, which must be at least one."
+ if (formatInfo.isInt())
+ {
+ mState.mCaps.maxIntegerSamples = std::min(
+ static_cast<GLuint>(mState.mCaps.maxIntegerSamples), formatMaxSamples);
+ }
+
+ // GLES 3.1 section 19.3.1.
+ if (formatCaps.texturable)
+ {
+ if (formatInfo.depthBits > 0)
+ {
+ mState.mCaps.maxDepthTextureSamples =
+ std::min(static_cast<GLuint>(mState.mCaps.maxDepthTextureSamples),
+ formatMaxSamples);
+ }
+ else if (formatInfo.redBits > 0)
+ {
+ mState.mCaps.maxColorTextureSamples =
+ std::min(static_cast<GLuint>(mState.mCaps.maxColorTextureSamples),
+ formatMaxSamples);
+ }
+ }
+ }
+ }
+
+ if (formatCaps.texturable && (formatInfo.compressed || formatInfo.paletted))
+ {
+ mState.mCaps.compressedTextureFormats.push_back(sizedInternalFormat);
+ }
+
+ mState.mTextureCaps.insert(sizedInternalFormat, formatCaps);
+ }
+
+ // If program binary is disabled, blank out the memory cache pointer.
+ if (!mSupportedExtensions.getProgramBinaryOES)
+ {
+ mMemoryProgramCache = nullptr;
+ }
+
+ // Compute which buffer types are allowed
+ mValidBufferBindings.reset();
+ mValidBufferBindings.set(BufferBinding::ElementArray);
+ mValidBufferBindings.set(BufferBinding::Array);
+
+ if (mState.mExtensions.pixelBufferObjectNV || getClientVersion() >= ES_3_0)
+ {
+ mValidBufferBindings.set(BufferBinding::PixelPack);
+ mValidBufferBindings.set(BufferBinding::PixelUnpack);
+ }
+
+ if (getClientVersion() >= ES_3_0)
+ {
+ mValidBufferBindings.set(BufferBinding::CopyRead);
+ mValidBufferBindings.set(BufferBinding::CopyWrite);
+ mValidBufferBindings.set(BufferBinding::TransformFeedback);
+ mValidBufferBindings.set(BufferBinding::Uniform);
+ }
+
+ if (getClientVersion() >= ES_3_1)
+ {
+ mValidBufferBindings.set(BufferBinding::AtomicCounter);
+ mValidBufferBindings.set(BufferBinding::ShaderStorage);
+ mValidBufferBindings.set(BufferBinding::DrawIndirect);
+ mValidBufferBindings.set(BufferBinding::DispatchIndirect);
+ }
+
+ if (getClientVersion() >= ES_3_2 || mState.mExtensions.textureBufferAny())
+ {
+ mValidBufferBindings.set(BufferBinding::Texture);
+ }
+
+ if (!mState.mExtensions.parallelShaderCompileKHR)
+ {
+ mSingleThreadPool = angle::WorkerThreadPool::Create(false);
+ }
+ mMultiThreadPool = angle::WorkerThreadPool::Create(
+ mState.mExtensions.parallelShaderCompileKHR ||
+ getFrontendFeatures().enableCompressingPipelineCacheInThreadPool.enabled);
+
+ // Reinitialize some dirty bits that depend on extensions.
+ if (mState.isRobustResourceInitEnabled())
+ {
+ mDrawDirtyObjects.set(State::DIRTY_OBJECT_DRAW_ATTACHMENTS);
+ mDrawDirtyObjects.set(State::DIRTY_OBJECT_TEXTURES_INIT);
+ mDrawDirtyObjects.set(State::DIRTY_OBJECT_IMAGES_INIT);
+ mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_ATTACHMENTS);
+ mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_ATTACHMENTS);
+ mComputeDirtyObjects.set(State::DIRTY_OBJECT_TEXTURES_INIT);
+ mComputeDirtyObjects.set(State::DIRTY_OBJECT_IMAGES_INIT);
+ mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_ATTACHMENTS);
+ mCopyImageDirtyBits.set(State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
+ mCopyImageDirtyObjects.set(State::DIRTY_OBJECT_READ_ATTACHMENTS);
+ }
+
+ // We need to validate buffer bounds if we are in a WebGL or robust access context and the
+ // back-end does not support robust buffer access behaviour.
+ mBufferAccessValidationEnabled = (!mSupportedExtensions.robustBufferAccessBehaviorKHR &&
+ (mState.isWebGL() || mState.hasRobustAccess()));
+
+ // Cache this in the VertexArrays. They need to check it in state change notifications.
+ for (auto vaoIter : mVertexArrayMap)
+ {
+ VertexArray *vao = vaoIter.second;
+ vao->setBufferAccessValidationEnabled(mBufferAccessValidationEnabled);
+ }
+
+ // Reinitialize state cache after extension changes.
+ mStateCache.initialize(this);
+}
+
+bool Context::noopDrawInstanced(PrimitiveMode mode, GLsizei count, GLsizei instanceCount) const
+{
+ return (instanceCount == 0) || noopDraw(mode, count);
+}
+
+angle::Result Context::prepareForClear(GLbitfield mask)
+{
+ // Sync the draw framebuffer manually after the clear attachments.
+ ANGLE_TRY(mState.getDrawFramebuffer()->ensureClearAttachmentsInitialized(this, mask));
+ return syncStateForClear();
+}
+
+angle::Result Context::prepareForClearBuffer(GLenum buffer, GLint drawbuffer)
+{
+ // Sync the draw framebuffer manually after the clear attachments.
+ ANGLE_TRY(mState.getDrawFramebuffer()->ensureClearBufferAttachmentsInitialized(this, buffer,
+ drawbuffer));
+ return syncStateForClear();
+}
+
+ANGLE_INLINE angle::Result Context::prepareForCopyImage()
+{
+ ANGLE_TRY(syncDirtyObjects(mCopyImageDirtyObjects, Command::CopyImage));
+ return syncDirtyBits(mCopyImageDirtyBits, Command::CopyImage);
+}
+
+ANGLE_INLINE angle::Result Context::prepareForDispatch()
+{
+ // Converting a PPO from graphics to compute requires re-linking it.
+ // The compute shader must have successfully linked before being included in the PPO, so no link
+ // errors that would have been caught during validation should be possible when re-linking the
+ // PPO with the compute shader.
+ Program *program = mState.getProgram();
+ ProgramPipeline *pipeline = mState.getProgramPipeline();
+ if (!program && pipeline)
+ {
+ // Linking the PPO can't fail due to a validation error within the compute program,
+ // since it successfully linked already in order to become part of the PPO in the first
+ // place.
+ pipeline->resolveLink(this);
+ ANGLE_CHECK(this, pipeline->isLinked(), "Program pipeline link failed",
+ GL_INVALID_OPERATION);
+ }
+
+ ANGLE_TRY(syncDirtyObjects(mComputeDirtyObjects, Command::Dispatch));
+ return syncDirtyBits(mComputeDirtyBits, Command::Dispatch);
+}
+
+angle::Result Context::prepareForInvalidate(GLenum target)
+{
+ // Only sync the FBO that's being invalidated. Per the GLES3 spec, GL_FRAMEBUFFER is equivalent
+ // to GL_DRAW_FRAMEBUFFER for the purposes of invalidation.
+ GLenum effectiveTarget = target;
+ if (effectiveTarget == GL_FRAMEBUFFER)
+ {
+ effectiveTarget = GL_DRAW_FRAMEBUFFER;
+ }
+ ANGLE_TRY(mState.syncDirtyObject(this, effectiveTarget));
+ return syncDirtyBits(effectiveTarget == GL_READ_FRAMEBUFFER ? mReadInvalidateDirtyBits
+ : mDrawInvalidateDirtyBits,
+ Command::Invalidate);
+}
+
+angle::Result Context::syncState(const State::DirtyBits &bitMask,
+ const State::DirtyObjects &objectMask,
+ Command command)
+{
+ ANGLE_TRY(syncDirtyObjects(objectMask, command));
+ ANGLE_TRY(syncDirtyBits(bitMask, command));
+ return angle::Result::Continue;
+}
+
+void Context::blitFramebuffer(GLint srcX0,
+ GLint srcY0,
+ GLint srcX1,
+ GLint srcY1,
+ GLint dstX0,
+ GLint dstY0,
+ GLint dstX1,
+ GLint dstY1,
+ GLbitfield mask,
+ GLenum filter)
+{
+ if (mask == 0)
+ {
+ // ES3.0 spec, section 4.3.2 specifies that a mask of zero is valid and no
+ // buffers are copied.
+ return;
+ }
+
+ Framebuffer *drawFramebuffer = mState.getDrawFramebuffer();
+ ASSERT(drawFramebuffer);
+
+ // Note that blitting is called against draw framebuffer.
+ // See the code in gl::Context::blitFramebuffer.
+ if ((mask & GL_COLOR_BUFFER_BIT) && !drawFramebuffer->hasEnabledDrawBuffer())
+ {
+ mask &= ~GL_COLOR_BUFFER_BIT;
+ }
+
+ if ((mask & GL_STENCIL_BUFFER_BIT) &&
+ drawFramebuffer->getState().getStencilAttachment() == nullptr)
+ {
+ mask &= ~GL_STENCIL_BUFFER_BIT;
+ }
+
+ if ((mask & GL_DEPTH_BUFFER_BIT) && drawFramebuffer->getState().getDepthAttachment() == nullptr)
+ {
+ mask &= ~GL_DEPTH_BUFFER_BIT;
+ }
+
+ // Early out if none of the specified attachments exist or are enabled.
+ if (mask == 0)
+ {
+ ANGLE_PERF_WARNING(mState.getDebug(), GL_DEBUG_SEVERITY_LOW,
+ "BlitFramebuffer called for non-existing buffers");
+ return;
+ }
+
+ Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
+ Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
+
+ if (dstArea.width == 0 || dstArea.height == 0)
+ {
+ return;
+ }
+
+ ANGLE_CONTEXT_TRY(syncStateForBlit(mask));
+ ANGLE_CONTEXT_TRY(drawFramebuffer->blit(this, srcArea, dstArea, mask, filter));
+}
+
+void Context::blitFramebufferNV(GLint srcX0,
+ GLint srcY0,
+ GLint srcX1,
+ GLint srcY1,
+ GLint dstX0,
+ GLint dstY0,
+ GLint dstX1,
+ GLint dstY1,
+ GLbitfield mask,
+ GLenum filter)
+{
+ blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
+}
+
+void Context::clear(GLbitfield mask)
+{
+ if (mState.isRasterizerDiscardEnabled())
+ {
+ return;
+ }
+
+ // Noop empty scissors.
+ if (IsEmptyScissor(mState))
+ {
+ return;
+ }
+
+ // Remove clear bits that are ineffective. An effective clear changes at least one fragment. If
+ // color/depth/stencil masks make the clear ineffective we skip it altogether.
+
+ // If all color channels in all draw buffers are masked, don't attempt to clear color.
+ if (mState.allActiveDrawBufferChannelsMasked())
+ {
+ mask &= ~GL_COLOR_BUFFER_BIT;
+ }
+
+ // If depth write is disabled, don't attempt to clear depth.
+ if (mState.getDrawFramebuffer()->getDepthAttachment() == nullptr ||
+ !mState.getDepthStencilState().depthMask)
+ {
+ mask &= ~GL_DEPTH_BUFFER_BIT;
+ }
+
+ // If all stencil bits are masked, don't attempt to clear stencil.
+ if (mState.getDrawFramebuffer()->getStencilAttachment() == nullptr ||
+ (angle::BitMask<uint32_t>(
+ mState.getDrawFramebuffer()->getStencilAttachment()->getStencilSize()) &
+ mState.getDepthStencilState().stencilWritemask) == 0)
+ {
+ mask &= ~GL_STENCIL_BUFFER_BIT;
+ }
+
+ if (mask == 0)
+ {
+ ANGLE_PERF_WARNING(mState.getDebug(), GL_DEBUG_SEVERITY_LOW,
+ "Clear called for non-existing buffers");
+ return;
+ }
+
+ ANGLE_CONTEXT_TRY(prepareForClear(mask));
+ ANGLE_CONTEXT_TRY(mState.getDrawFramebuffer()->clear(this, mask));
+}
+
+bool Context::isClearBufferMaskedOut(GLenum buffer, GLint drawbuffer) const
+{
+ switch (buffer)
+ {
+ case GL_COLOR:
+ return IsColorMaskedOut(mState.getBlendStateExt(), drawbuffer);
+ case GL_DEPTH:
+ return mState.getDepthStencilState().isDepthMaskedOut();
+ case GL_STENCIL:
+ return mState.getDepthStencilState().isStencilMaskedOut();
+ case GL_DEPTH_STENCIL:
+ return mState.getDepthStencilState().isDepthMaskedOut() &&
+ mState.getDepthStencilState().isStencilMaskedOut();
+ default:
+ UNREACHABLE();
+ return true;
+ }
+}
+
+bool Context::noopClearBuffer(GLenum buffer, GLint drawbuffer) const
+{
+ Framebuffer *framebufferObject = mState.getDrawFramebuffer();
+
+ return !IsClearBufferEnabled(framebufferObject->getState(), buffer, drawbuffer) ||
+ mState.isRasterizerDiscardEnabled() || isClearBufferMaskedOut(buffer, drawbuffer) ||
+ IsEmptyScissor(mState);
+}
+
+void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
+{
+ if (noopClearBuffer(buffer, drawbuffer))
+ {
+ return;
+ }
+
+ Framebuffer *framebufferObject = mState.getDrawFramebuffer();
+ const FramebufferAttachment *attachment = nullptr;
+ if (buffer == GL_DEPTH)
+ {
+ attachment = framebufferObject->getDepthAttachment();
+ }
+ else if (buffer == GL_COLOR &&
+ static_cast<size_t>(drawbuffer) < framebufferObject->getNumColorAttachments())
+ {
+ attachment = framebufferObject->getColorAttachment(drawbuffer);
+ }
+ // It's not an error to try to clear a non-existent buffer, but it's a no-op. We early out so
+ // that the backend doesn't need to take this case into account.
+ if (!attachment)
+ {
+ return;
+ }
+ ANGLE_CONTEXT_TRY(prepareForClearBuffer(buffer, drawbuffer));
+ ANGLE_CONTEXT_TRY(framebufferObject->clearBufferfv(this, buffer, drawbuffer, values));
+}
+
+void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
+{
+ if (noopClearBuffer(buffer, drawbuffer))
+ {
+ return;
+ }
+
+ Framebuffer *framebufferObject = mState.getDrawFramebuffer();
+ const FramebufferAttachment *attachment = nullptr;
+ if (buffer == GL_COLOR &&
+ static_cast<size_t>(drawbuffer) < framebufferObject->getNumColorAttachments())
+ {
+ attachment = framebufferObject->getColorAttachment(drawbuffer);
+ }
+ // It's not an error to try to clear a non-existent buffer, but it's a no-op. We early out so
+ // that the backend doesn't need to take this case into account.
+ if (!attachment)
+ {
+ return;
+ }
+ ANGLE_CONTEXT_TRY(prepareForClearBuffer(buffer, drawbuffer));
+ ANGLE_CONTEXT_TRY(framebufferObject->clearBufferuiv(this, buffer, drawbuffer, values));
+}
+
+void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
+{
+ if (noopClearBuffer(buffer, drawbuffer))
+ {
+ return;
+ }
+
+ Framebuffer *framebufferObject = mState.getDrawFramebuffer();
+ const FramebufferAttachment *attachment = nullptr;
+ if (buffer == GL_STENCIL)
+ {
+ attachment = framebufferObject->getStencilAttachment();
+ }
+ else if (buffer == GL_COLOR &&
+ static_cast<size_t>(drawbuffer) < framebufferObject->getNumColorAttachments())
+ {
+ attachment = framebufferObject->getColorAttachment(drawbuffer);
+ }
+ // It's not an error to try to clear a non-existent buffer, but it's a no-op. We early out so
+ // that the backend doesn't need to take this case into account.
+ if (!attachment)
+ {
+ return;
+ }
+ ANGLE_CONTEXT_TRY(prepareForClearBuffer(buffer, drawbuffer));
+ ANGLE_CONTEXT_TRY(framebufferObject->clearBufferiv(this, buffer, drawbuffer, values));
+}
+
+void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
+{
+ if (noopClearBuffer(buffer, drawbuffer))
+ {
+ return;
+ }
+
+ Framebuffer *framebufferObject = mState.getDrawFramebuffer();
+ ASSERT(framebufferObject);
+
+ // If a buffer is not present, the clear has no effect
+ if (framebufferObject->getDepthAttachment() == nullptr &&
+ framebufferObject->getStencilAttachment() == nullptr)
+ {
+ return;
+ }
+
+ ANGLE_CONTEXT_TRY(prepareForClearBuffer(buffer, drawbuffer));
+ ANGLE_CONTEXT_TRY(framebufferObject->clearBufferfi(this, buffer, drawbuffer, depth, stencil));
+}
+
+void Context::readPixels(GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ void *pixels)
+{
+ if (width == 0 || height == 0)
+ {
+ return;
+ }
+
+ ANGLE_CONTEXT_TRY(syncStateForReadPixels());
+
+ Framebuffer *readFBO = mState.getReadFramebuffer();
+ ASSERT(readFBO);
+
+ Rectangle area(x, y, width, height);
+ PixelPackState packState = mState.getPackState();
+ Buffer *packBuffer = mState.getTargetBuffer(gl::BufferBinding::PixelPack);
+ ANGLE_CONTEXT_TRY(readFBO->readPixels(this, area, format, type, packState, packBuffer, pixels));
+}
+
+void Context::readPixelsRobust(GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLsizei *columns,
+ GLsizei *rows,
+ void *pixels)
+{
+ readPixels(x, y, width, height, format, type, pixels);
+}
+
+void Context::readnPixelsRobust(GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLsizei *columns,
+ GLsizei *rows,
+ void *data)
+{
+ readPixels(x, y, width, height, format, type, data);
+}
+
+void Context::copyTexImage2D(TextureTarget target,
+ GLint level,
+ GLenum internalformat,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLint border)
+{
+ ANGLE_CONTEXT_TRY(prepareForCopyImage());
+
+ Rectangle sourceArea(x, y, width, height);
+
+ Framebuffer *framebuffer = mState.getReadFramebuffer();
+ Texture *texture = getTextureByTarget(target);
+ ANGLE_CONTEXT_TRY(
+ texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
+}
+
+void Context::copyTexSubImage2D(TextureTarget target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height)
+{
+ if (width == 0 || height == 0)
+ {
+ return;
+ }
+
+ ANGLE_CONTEXT_TRY(prepareForCopyImage());
+
+ Offset destOffset(xoffset, yoffset, 0);
+ Rectangle sourceArea(x, y, width, height);
+
+ ImageIndex index = ImageIndex::MakeFromTarget(target, level, 1);
+
+ Framebuffer *framebuffer = mState.getReadFramebuffer();
+ Texture *texture = getTextureByTarget(target);
+ ANGLE_CONTEXT_TRY(texture->copySubImage(this, index, destOffset, sourceArea, framebuffer));
+}
+
+void Context::copyTexSubImage3D(TextureTarget target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height)
+{
+ if (width == 0 || height == 0)
+ {
+ return;
+ }
+
+ ANGLE_CONTEXT_TRY(prepareForCopyImage());
+
+ Offset destOffset(xoffset, yoffset, zoffset);
+ Rectangle sourceArea(x, y, width, height);
+
+ ImageIndex index = ImageIndex::MakeFromType(TextureTargetToType(target), level, zoffset);
+
+ Framebuffer *framebuffer = mState.getReadFramebuffer();
+ Texture *texture = getTextureByTarget(target);
+ ANGLE_CONTEXT_TRY(texture->copySubImage(this, index, destOffset, sourceArea, framebuffer));
+}
+
+void Context::copyImageSubData(GLuint srcName,
+ GLenum srcTarget,
+ GLint srcLevel,
+ GLint srcX,
+ GLint srcY,
+ GLint srcZ,
+ GLuint dstName,
+ GLenum dstTarget,
+ GLint dstLevel,
+ GLint dstX,
+ GLint dstY,
+ GLint dstZ,
+ GLsizei srcWidth,
+ GLsizei srcHeight,
+ GLsizei srcDepth)
+{
+ // if copy region is zero, the copy is a successful no-op
+ if ((srcWidth == 0) || (srcHeight == 0) || (srcDepth == 0))
+ {
+ return;
+ }
+
+ if (srcTarget == GL_RENDERBUFFER)
+ {
+ // Source target is a Renderbuffer
+ Renderbuffer *readBuffer = getRenderbuffer(PackParam<RenderbufferID>(srcName));
+ if (dstTarget == GL_RENDERBUFFER)
+ {
+ // Destination target is a Renderbuffer
+ Renderbuffer *writeBuffer = getRenderbuffer(PackParam<RenderbufferID>(dstName));
+
+ // Copy Renderbuffer to Renderbuffer
+ ANGLE_CONTEXT_TRY(writeBuffer->copyRenderbufferSubData(
+ this, readBuffer, srcLevel, srcX, srcY, srcZ, dstLevel, dstX, dstY, dstZ, srcWidth,
+ srcHeight, srcDepth));
+ }
+ else
+ {
+ // Destination target is a Texture
+ ASSERT(dstTarget == GL_TEXTURE_2D || dstTarget == GL_TEXTURE_2D_ARRAY ||
+ dstTarget == GL_TEXTURE_3D || dstTarget == GL_TEXTURE_CUBE_MAP);
+
+ Texture *writeTexture = getTexture(PackParam<TextureID>(dstName));
+ ANGLE_CONTEXT_TRY(syncTextureForCopy(writeTexture));
+
+ // Copy Renderbuffer to Texture
+ ANGLE_CONTEXT_TRY(writeTexture->copyRenderbufferSubData(
+ this, readBuffer, srcLevel, srcX, srcY, srcZ, dstLevel, dstX, dstY, dstZ, srcWidth,
+ srcHeight, srcDepth));
+ }
+ }
+ else
+ {
+ // Source target is a Texture
+ ASSERT(srcTarget == GL_TEXTURE_2D || srcTarget == GL_TEXTURE_2D_ARRAY ||
+ srcTarget == GL_TEXTURE_3D || srcTarget == GL_TEXTURE_CUBE_MAP);
+
+ Texture *readTexture = getTexture(PackParam<TextureID>(srcName));
+ ANGLE_CONTEXT_TRY(syncTextureForCopy(readTexture));
+
+ if (dstTarget == GL_RENDERBUFFER)
+ {
+ // Destination target is a Renderbuffer
+ Renderbuffer *writeBuffer = getRenderbuffer(PackParam<RenderbufferID>(dstName));
+
+ // Copy Texture to Renderbuffer
+ ANGLE_CONTEXT_TRY(writeBuffer->copyTextureSubData(this, readTexture, srcLevel, srcX,
+ srcY, srcZ, dstLevel, dstX, dstY,
+ dstZ, srcWidth, srcHeight, srcDepth));
+ }
+ else
+ {
+ // Destination target is a Texture
+ ASSERT(dstTarget == GL_TEXTURE_2D || dstTarget == GL_TEXTURE_2D_ARRAY ||
+ dstTarget == GL_TEXTURE_3D || dstTarget == GL_TEXTURE_CUBE_MAP);
+
+ Texture *writeTexture = getTexture(PackParam<TextureID>(dstName));
+ ANGLE_CONTEXT_TRY(syncTextureForCopy(writeTexture));
+
+ // Copy Texture to Texture
+ ANGLE_CONTEXT_TRY(writeTexture->copyTextureSubData(
+ this, readTexture, srcLevel, srcX, srcY, srcZ, dstLevel, dstX, dstY, dstZ, srcWidth,
+ srcHeight, srcDepth));
+ }
+ }
+}
+
+void Context::framebufferTexture2D(GLenum target,
+ GLenum attachment,
+ TextureTarget textarget,
+ TextureID texture,
+ GLint level)
+{
+ Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
+ ASSERT(framebuffer);
+
+ if (texture.value != 0)
+ {
+ Texture *textureObj = getTexture(texture);
+ ImageIndex index = ImageIndex::MakeFromTarget(textarget, level, 1);
+ framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
+ }
+ else
+ {
+ framebuffer->resetAttachment(this, attachment);
+ }
+
+ mState.setObjectDirty(target);
+}
+
+void Context::framebufferTexture3D(GLenum target,
+ GLenum attachment,
+ TextureTarget textargetPacked,
+ TextureID texture,
+ GLint level,
+ GLint zoffset)
+{
+ Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
+ ASSERT(framebuffer);
+
+ if (texture.value != 0)
+ {
+ Texture *textureObj = getTexture(texture);
+ ImageIndex index = ImageIndex::Make3D(level, zoffset);
+ framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
+ }
+ else
+ {
+ framebuffer->resetAttachment(this, attachment);
+ }
+
+ mState.setObjectDirty(target);
+}
+
+void Context::framebufferRenderbuffer(GLenum target,
+ GLenum attachment,
+ GLenum renderbuffertarget,
+ RenderbufferID renderbuffer)
+{
+ Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
+ ASSERT(framebuffer);
+
+ if (renderbuffer.value != 0)
+ {
+ Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
+ GLsizei rbSamples = renderbufferObject->getState().getSamples();
+
+ framebuffer->setAttachmentMultisample(this, GL_RENDERBUFFER, attachment, gl::ImageIndex(),
+ renderbufferObject, rbSamples);
+ }
+ else
+ {
+ framebuffer->resetAttachment(this, attachment);
+ }
+
+ mState.setObjectDirty(target);
+}
+
+void Context::framebufferTextureLayer(GLenum target,
+ GLenum attachment,
+ TextureID texture,
+ GLint level,
+ GLint layer)
+{
+ Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
+ ASSERT(framebuffer);
+
+ if (texture.value != 0)
+ {
+ Texture *textureObject = getTexture(texture);
+ ImageIndex index = ImageIndex::MakeFromType(textureObject->getType(), level, layer);
+ framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObject);
+ }
+ else
+ {
+ framebuffer->resetAttachment(this, attachment);
+ }
+
+ mState.setObjectDirty(target);
+}
+
+void Context::framebufferTextureMultiview(GLenum target,
+ GLenum attachment,
+ TextureID texture,
+ GLint level,
+ GLint baseViewIndex,
+ GLsizei numViews)
+{
+ Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
+ ASSERT(framebuffer);
+
+ if (texture.value != 0)
+ {
+ Texture *textureObj = getTexture(texture);
+
+ ImageIndex index;
+ if (textureObj->getType() == TextureType::_2DArray)
+ {
+ index = ImageIndex::Make2DArrayRange(level, baseViewIndex, numViews);
+ }
+ else
+ {
+ ASSERT(textureObj->getType() == TextureType::_2DMultisampleArray);
+ ASSERT(level == 0);
+ index = ImageIndex::Make2DMultisampleArrayRange(baseViewIndex, numViews);
+ }
+ framebuffer->setAttachmentMultiview(this, GL_TEXTURE, attachment, index, textureObj,
+ numViews, baseViewIndex);
+ }
+ else
+ {
+ framebuffer->resetAttachment(this, attachment);
+ }
+
+ mState.setObjectDirty(target);
+}
+
+void Context::framebufferTexture(GLenum target, GLenum attachment, TextureID texture, GLint level)
+{
+ Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
+ ASSERT(framebuffer);
+
+ if (texture.value != 0)
+ {
+ Texture *textureObj = getTexture(texture);
+
+ ImageIndex index = ImageIndex::MakeFromType(
+ textureObj->getType(), level, ImageIndex::kEntireLevel, ImageIndex::kEntireLevel);
+ framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
+ }
+ else
+ {
+ framebuffer->resetAttachment(this, attachment);
+ }
+
+ mState.setObjectDirty(target);
+}
+
+void Context::drawBuffers(GLsizei n, const GLenum *bufs)
+{
+ Framebuffer *framebuffer = mState.getDrawFramebuffer();
+ ASSERT(framebuffer);
+ framebuffer->setDrawBuffers(n, bufs);
+ mState.setDrawFramebufferDirty();
+ mStateCache.onDrawFramebufferChange(this);
+}
+
+void Context::readBuffer(GLenum mode)
+{
+ Framebuffer *readFBO = mState.getReadFramebuffer();
+ readFBO->setReadBuffer(mode);
+ mState.setObjectDirty(GL_READ_FRAMEBUFFER);
+}
+
+void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
+{
+ // The specification isn't clear what should be done when the framebuffer isn't complete.
+ // We threat it the same way as GLES3 glInvalidateFramebuffer.
+ invalidateFramebuffer(target, numAttachments, attachments);
+}
+
+void Context::invalidateFramebuffer(GLenum target,
+ GLsizei numAttachments,
+ const GLenum *attachments)
+{
+ Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
+ ASSERT(framebuffer);
+
+ // No-op incomplete FBOs.
+ if (!framebuffer->isComplete(this))
+ {
+ return;
+ }
+
+ ANGLE_CONTEXT_TRY(prepareForInvalidate(target));
+ ANGLE_CONTEXT_TRY(framebuffer->invalidate(this, numAttachments, attachments));
+}
+
+void Context::invalidateSubFramebuffer(GLenum target,
+ GLsizei numAttachments,
+ const GLenum *attachments,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height)
+{
+ Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
+ ASSERT(framebuffer);
+
+ if (!framebuffer->isComplete(this))
+ {
+ return;
+ }
+
+ Rectangle area(x, y, width, height);
+ ANGLE_CONTEXT_TRY(prepareForInvalidate(target));
+ ANGLE_CONTEXT_TRY(framebuffer->invalidateSub(this, numAttachments, attachments, area));
+}
+
+void Context::texImage2D(TextureTarget target,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ ANGLE_CONTEXT_TRY(syncStateForTexImage());
+
+ gl::Buffer *unpackBuffer = mState.getTargetBuffer(gl::BufferBinding::PixelUnpack);
+
+ Extents size(width, height, 1);
+ Texture *texture = getTextureByTarget(target);
+ ANGLE_CONTEXT_TRY(texture->setImage(this, mState.getUnpackState(), unpackBuffer, target, level,
+ internalformat, size, format, type,
+ static_cast<const uint8_t *>(pixels)));
+}
+
+void Context::texImage2DRobust(TextureTarget target,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *pixels)
+{
+ texImage2D(target, level, internalformat, width, height, border, format, type, pixels);
+}
+
+void Context::texImage3D(TextureTarget target,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ ANGLE_CONTEXT_TRY(syncStateForTexImage());
+
+ gl::Buffer *unpackBuffer = mState.getTargetBuffer(gl::BufferBinding::PixelUnpack);
+
+ Extents size(width, height, depth);
+ Texture *texture = getTextureByTarget(target);
+ ANGLE_CONTEXT_TRY(texture->setImage(this, mState.getUnpackState(), unpackBuffer, target, level,
+ internalformat, size, format, type,
+ static_cast<const uint8_t *>(pixels)));
+}
+
+void Context::texImage3DRobust(TextureTarget target,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *pixels)
+{
+ texImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
+}
+
+void Context::texSubImage2D(TextureTarget target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ // Zero sized uploads are valid but no-ops
+ if (width == 0 || height == 0)
+ {
+ return;
+ }
+
+ ANGLE_CONTEXT_TRY(syncStateForTexImage());
+
+ Box area(xoffset, yoffset, 0, width, height, 1);
+ Texture *texture = getTextureByTarget(target);
+
+ gl::Buffer *unpackBuffer = mState.getTargetBuffer(gl::BufferBinding::PixelUnpack);
+
+ ANGLE_CONTEXT_TRY(texture->setSubImage(this, mState.getUnpackState(), unpackBuffer, target,
+ level, area, format, type,
+ static_cast<const uint8_t *>(pixels)));
+}
+
+void Context::texSubImage2DRobust(TextureTarget target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *pixels)
+{
+ texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
+}
+
+void Context::texSubImage3D(TextureTarget target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ // Zero sized uploads are valid but no-ops
+ if (width == 0 || height == 0 || depth == 0)
+ {
+ return;
+ }
+
+ ANGLE_CONTEXT_TRY(syncStateForTexImage());
+
+ Box area(xoffset, yoffset, zoffset, width, height, depth);
+ Texture *texture = getTextureByTarget(target);
+
+ gl::Buffer *unpackBuffer = mState.getTargetBuffer(gl::BufferBinding::PixelUnpack);
+
+ ANGLE_CONTEXT_TRY(texture->setSubImage(this, mState.getUnpackState(), unpackBuffer, target,
+ level, area, format, type,
+ static_cast<const uint8_t *>(pixels)));
+}
+
+void Context::texSubImage3DRobust(TextureTarget target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *pixels)
+{
+ texSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type,
+ pixels);
+}
+
+void Context::compressedTexImage2D(TextureTarget target,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLsizei imageSize,
+ const void *data)
+{
+ ANGLE_CONTEXT_TRY(syncStateForTexImage());
+
+ Extents size(width, height, 1);
+ Texture *texture = getTextureByTarget(target);
+ // From OpenGL ES 3 spec: All pixel storage modes are ignored when decoding a compressed texture
+ // image. So we use an empty PixelUnpackState.
+ ANGLE_CONTEXT_TRY(texture->setCompressedImage(this, PixelUnpackState(), target, level,
+ internalformat, size, imageSize,
+ static_cast<const uint8_t *>(data)));
+}
+
+void Context::compressedTexImage2DRobust(TextureTarget target,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLsizei imageSize,
+ GLsizei dataSize,
+ const GLvoid *data)
+{
+ compressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);
+}
+
+void Context::compressedTexImage3D(TextureTarget target,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLsizei imageSize,
+ const void *data)
+{
+ ANGLE_CONTEXT_TRY(syncStateForTexImage());
+
+ Extents size(width, height, depth);
+ Texture *texture = getTextureByTarget(target);
+ // From OpenGL ES 3 spec: All pixel storage modes are ignored when decoding a compressed texture
+ // image. So we use an empty PixelUnpackState.
+ ANGLE_CONTEXT_TRY(texture->setCompressedImage(this, PixelUnpackState(), target, level,
+ internalformat, size, imageSize,
+ static_cast<const uint8_t *>(data)));
+}
+
+void Context::compressedTexImage3DRobust(TextureTarget target,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLsizei imageSize,
+ GLsizei dataSize,
+ const GLvoid *data)
+{
+ compressedTexImage3D(target, level, internalformat, width, height, depth, border, imageSize,
+ data);
+}
+
+void Context::compressedTexSubImage2D(TextureTarget target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data)
+{
+ ANGLE_CONTEXT_TRY(syncStateForTexImage());
+
+ Box area(xoffset, yoffset, 0, width, height, 1);
+ Texture *texture = getTextureByTarget(target);
+ // From OpenGL ES 3 spec: All pixel storage modes are ignored when decoding a compressed texture
+ // image. So we use an empty PixelUnpackState.
+ ANGLE_CONTEXT_TRY(texture->setCompressedSubImage(this, PixelUnpackState(), target, level, area,
+ format, imageSize,
+ static_cast<const uint8_t *>(data)));
+}
+
+void Context::compressedTexSubImage2DRobust(TextureTarget target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLsizei imageSize,
+ GLsizei dataSize,
+ const GLvoid *data)
+{
+ compressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize,
+ data);
+}
+
+void Context::compressedTexSubImage3D(TextureTarget target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data)
+{
+ // Zero sized uploads are valid but no-ops
+ if (width == 0 || height == 0)
+ {
+ return;
+ }
+
+ ANGLE_CONTEXT_TRY(syncStateForTexImage());
+
+ Box area(xoffset, yoffset, zoffset, width, height, depth);
+ Texture *texture = getTextureByTarget(target);
+ // From OpenGL ES 3 spec: All pixel storage modes are ignored when decoding a compressed texture
+ // image. So we use an empty PixelUnpackState.
+ ANGLE_CONTEXT_TRY(texture->setCompressedSubImage(this, PixelUnpackState(), target, level, area,
+ format, imageSize,
+ static_cast<const uint8_t *>(data)));
+}
+
+void Context::compressedTexSubImage3DRobust(TextureTarget target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLsizei imageSize,
+ GLsizei dataSize,
+ const GLvoid *data)
+{
+ compressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format,
+ imageSize, data);
+}
+
+void Context::generateMipmap(TextureType target)
+{
+ Texture *texture = getTextureByType(target);
+ ANGLE_CONTEXT_TRY(texture->generateMipmap(this));
+}
+
+void Context::copyTexture(TextureID sourceId,
+ GLint sourceLevel,
+ TextureTarget destTarget,
+ TextureID destId,
+ GLint destLevel,
+ GLint internalFormat,
+ GLenum destType,
+ GLboolean unpackFlipY,
+ GLboolean unpackPremultiplyAlpha,
+ GLboolean unpackUnmultiplyAlpha)
+{
+ ANGLE_CONTEXT_TRY(syncStateForTexImage());
+
+ gl::Texture *sourceTexture = getTexture(sourceId);
+ gl::Texture *destTexture = getTexture(destId);
+ ANGLE_CONTEXT_TRY(
+ destTexture->copyTexture(this, destTarget, destLevel, internalFormat, destType, sourceLevel,
+ ConvertToBool(unpackFlipY), ConvertToBool(unpackPremultiplyAlpha),
+ ConvertToBool(unpackUnmultiplyAlpha), sourceTexture));
+}
+
+void Context::copySubTexture(TextureID sourceId,
+ GLint sourceLevel,
+ TextureTarget destTarget,
+ TextureID destId,
+ GLint destLevel,
+ 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;
+ }
+
+ ANGLE_CONTEXT_TRY(syncStateForTexImage());
+
+ gl::Texture *sourceTexture = getTexture(sourceId);
+ gl::Texture *destTexture = getTexture(destId);
+ Offset offset(xoffset, yoffset, 0);
+ Box box(x, y, 0, width, height, 1);
+ ANGLE_CONTEXT_TRY(destTexture->copySubTexture(
+ this, destTarget, destLevel, offset, sourceLevel, box, ConvertToBool(unpackFlipY),
+ ConvertToBool(unpackPremultiplyAlpha), ConvertToBool(unpackUnmultiplyAlpha),
+ sourceTexture));
+}
+
+void Context::copyTexture3D(TextureID sourceId,
+ GLint sourceLevel,
+ TextureTarget destTarget,
+ TextureID destId,
+ GLint destLevel,
+ GLint internalFormat,
+ GLenum destType,
+ GLboolean unpackFlipY,
+ GLboolean unpackPremultiplyAlpha,
+ GLboolean unpackUnmultiplyAlpha)
+{
+ ANGLE_CONTEXT_TRY(syncStateForTexImage());
+
+ Texture *sourceTexture = getTexture(sourceId);
+ Texture *destTexture = getTexture(destId);
+ ANGLE_CONTEXT_TRY(
+ destTexture->copyTexture(this, destTarget, destLevel, internalFormat, destType, sourceLevel,
+ ConvertToBool(unpackFlipY), ConvertToBool(unpackPremultiplyAlpha),
+ ConvertToBool(unpackUnmultiplyAlpha), sourceTexture));
+}
+
+void Context::copySubTexture3D(TextureID sourceId,
+ GLint sourceLevel,
+ TextureTarget destTarget,
+ TextureID destId,
+ GLint destLevel,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLint x,
+ GLint y,
+ GLint z,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean unpackFlipY,
+ GLboolean unpackPremultiplyAlpha,
+ GLboolean unpackUnmultiplyAlpha)
+{
+ // Zero sized copies are valid but no-ops
+ if (width == 0 || height == 0 || depth == 0)
+ {
+ return;
+ }
+
+ ANGLE_CONTEXT_TRY(syncStateForTexImage());
+
+ Texture *sourceTexture = getTexture(sourceId);
+ Texture *destTexture = getTexture(destId);
+ Offset offset(xoffset, yoffset, zoffset);
+ Box box(x, y, z, width, height, depth);
+ ANGLE_CONTEXT_TRY(destTexture->copySubTexture(
+ this, destTarget, destLevel, offset, sourceLevel, box, ConvertToBool(unpackFlipY),
+ ConvertToBool(unpackPremultiplyAlpha), ConvertToBool(unpackUnmultiplyAlpha),
+ sourceTexture));
+}
+
+void Context::compressedCopyTexture(TextureID sourceId, TextureID destId)
+{
+ ANGLE_CONTEXT_TRY(syncStateForTexImage());
+
+ gl::Texture *sourceTexture = getTexture(sourceId);
+ gl::Texture *destTexture = getTexture(destId);
+ ANGLE_CONTEXT_TRY(destTexture->copyCompressedTexture(this, sourceTexture));
+}
+
+void Context::getBufferPointerv(BufferBinding target, GLenum pname, void **params)
+{
+ Buffer *buffer = mState.getTargetBuffer(target);
+ ASSERT(buffer);
+
+ QueryBufferPointerv(buffer, pname, params);
+}
+
+void Context::getBufferPointervRobust(BufferBinding target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ void **params)
+{
+ getBufferPointerv(target, pname, params);
+}
+
+void *Context::mapBuffer(BufferBinding target, GLenum access)
+{
+ Buffer *buffer = mState.getTargetBuffer(target);
+ ASSERT(buffer);
+
+ if (buffer->map(this, access) == angle::Result::Stop)
+ {
+ return nullptr;
+ }
+
+ return buffer->getMapPointer();
+}
+
+GLboolean Context::unmapBuffer(BufferBinding target)
+{
+ Buffer *buffer = mState.getTargetBuffer(target);
+ ASSERT(buffer);
+
+ GLboolean result;
+ if (buffer->unmap(this, &result) == angle::Result::Stop)
+ {
+ return GL_FALSE;
+ }
+
+ return result;
+}
+
+void *Context::mapBufferRange(BufferBinding target,
+ GLintptr offset,
+ GLsizeiptr length,
+ GLbitfield access)
+{
+ Buffer *buffer = mState.getTargetBuffer(target);
+ ASSERT(buffer);
+
+ if (buffer->mapRange(this, offset, length, access) == angle::Result::Stop)
+ {
+ return nullptr;
+ }
+
+ return buffer->getMapPointer();
+}
+
+void Context::flushMappedBufferRange(BufferBinding /*target*/,
+ GLintptr /*offset*/,
+ GLsizeiptr /*length*/)
+{
+ // We do not currently support a non-trivial implementation of FlushMappedBufferRange
+}
+
+angle::Result Context::syncStateForReadPixels()
+{
+ return syncState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects, Command::ReadPixels);
+}
+
+angle::Result Context::syncStateForTexImage()
+{
+ return syncState(mTexImageDirtyBits, mTexImageDirtyObjects, Command::TexImage);
+}
+
+angle::Result Context::syncStateForBlit(GLbitfield mask)
+{
+ uint32_t commandMask = 0;
+ if ((mask & GL_COLOR_BUFFER_BIT) != 0)
+ {
+ commandMask |= CommandBlitBufferColor;
+ }
+ if ((mask & GL_DEPTH_BUFFER_BIT) != 0)
+ {
+ commandMask |= CommandBlitBufferDepth;
+ }
+ if ((mask & GL_STENCIL_BUFFER_BIT) != 0)
+ {
+ commandMask |= CommandBlitBufferStencil;
+ }
+
+ Command command = static_cast<Command>(static_cast<uint32_t>(Command::Blit) + commandMask);
+
+ return syncState(mBlitDirtyBits, mBlitDirtyObjects, command);
+}
+
+angle::Result Context::syncStateForClear()
+{
+ return syncState(mClearDirtyBits, mClearDirtyObjects, Command::Clear);
+}
+
+angle::Result Context::syncTextureForCopy(Texture *texture)
+{
+ ASSERT(texture);
+ // Sync texture not active but scheduled for a copy
+ if (texture->hasAnyDirtyBit())
+ {
+ return texture->syncState(this, Command::Other);
+ }
+
+ return angle::Result::Continue;
+}
+
+void Context::activeShaderProgram(ProgramPipelineID pipeline, ShaderProgramID program)
+{
+ Program *shaderProgram = getProgramNoResolveLink(program);
+ ProgramPipeline *programPipeline =
+ mState.mProgramPipelineManager->checkProgramPipelineAllocation(mImplementation.get(),
+ pipeline);
+ ASSERT(programPipeline);
+
+ programPipeline->activeShaderProgram(shaderProgram);
+}
+
+void Context::activeTexture(GLenum texture)
+{
+ mState.setActiveSampler(texture - GL_TEXTURE0);
+}
+
+void Context::blendBarrier()
+{
+ mImplementation->blendBarrier();
+}
+
+void Context::blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+ mState.setBlendColor(red, green, blue, alpha);
+}
+
+void Context::blendEquation(GLenum mode)
+{
+ mState.setBlendEquation(mode, mode);
+
+ mStateCache.onBlendEquationChange(this);
+}
+
+void Context::blendEquationi(GLuint buf, GLenum mode)
+{
+ mState.setBlendEquationIndexed(mode, mode, buf);
+
+ mStateCache.onBlendEquationChange(this);
+}
+
+void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
+{
+ mState.setBlendEquation(modeRGB, modeAlpha);
+}
+
+void Context::blendEquationSeparatei(GLuint buf, GLenum modeRGB, GLenum modeAlpha)
+{
+ mState.setBlendEquationIndexed(modeRGB, modeAlpha, buf);
+}
+
+void Context::blendFunc(GLenum sfactor, GLenum dfactor)
+{
+ mState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
+}
+
+void Context::blendFunci(GLuint buf, GLenum src, GLenum dst)
+{
+ mState.setBlendFactorsIndexed(src, dst, src, dst, buf);
+
+ if (mState.noSimultaneousConstantColorAndAlphaBlendFunc())
+ {
+ mStateCache.onBlendFuncIndexedChange(this);
+ }
+}
+
+void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+{
+ mState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
+}
+
+void Context::blendFuncSeparatei(GLuint buf,
+ GLenum srcRGB,
+ GLenum dstRGB,
+ GLenum srcAlpha,
+ GLenum dstAlpha)
+{
+ mState.setBlendFactorsIndexed(srcRGB, dstRGB, srcAlpha, dstAlpha, buf);
+
+ if (mState.noSimultaneousConstantColorAndAlphaBlendFunc())
+ {
+ mStateCache.onBlendFuncIndexedChange(this);
+ }
+}
+
+void Context::clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+ mState.setColorClearValue(red, green, blue, alpha);
+}
+
+void Context::clearDepthf(GLfloat depth)
+{
+ mState.setDepthClearValue(clamp01(depth));
+}
+
+void Context::clearStencil(GLint s)
+{
+ mState.setStencilClearValue(s);
+}
+
+void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
+{
+ mState.setColorMask(ConvertToBool(red), ConvertToBool(green), ConvertToBool(blue),
+ ConvertToBool(alpha));
+ mStateCache.onColorMaskChange(this);
+}
+
+void Context::colorMaski(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a)
+{
+ mState.setColorMaskIndexed(ConvertToBool(r), ConvertToBool(g), ConvertToBool(b),
+ ConvertToBool(a), index);
+ mStateCache.onColorMaskChange(this);
+}
+
+void Context::cullFace(CullFaceMode mode)
+{
+ mState.setCullMode(mode);
+}
+
+void Context::depthFunc(GLenum func)
+{
+ mState.setDepthFunc(func);
+}
+
+void Context::depthMask(GLboolean flag)
+{
+ mState.setDepthMask(ConvertToBool(flag));
+}
+
+void Context::depthRangef(GLfloat zNear, GLfloat zFar)
+{
+ mState.setDepthRange(clamp01(zNear), clamp01(zFar));
+}
+
+void Context::clipControl(GLenum origin, GLenum depth)
+{
+ mState.setClipControl(origin, depth);
+}
+
+void Context::disable(GLenum cap)
+{
+ mState.setEnableFeature(cap, false);
+ mStateCache.onContextCapChange(this);
+}
+
+void Context::disablei(GLenum target, GLuint index)
+{
+ mState.setEnableFeatureIndexed(target, false, index);
+ mStateCache.onContextCapChange(this);
+}
+
+void Context::disableVertexAttribArray(GLuint index)
+{
+ mState.setEnableVertexAttribArray(index, false);
+ mStateCache.onVertexArrayStateChange(this);
+}
+
+void Context::enable(GLenum cap)
+{
+ mState.setEnableFeature(cap, true);
+ mStateCache.onContextCapChange(this);
+}
+
+void Context::enablei(GLenum target, GLuint index)
+{
+ mState.setEnableFeatureIndexed(target, true, index);
+ mStateCache.onContextCapChange(this);
+}
+
+void Context::enableVertexAttribArray(GLuint index)
+{
+ mState.setEnableVertexAttribArray(index, true);
+ mStateCache.onVertexArrayStateChange(this);
+}
+
+void Context::frontFace(GLenum mode)
+{
+ mState.setFrontFace(mode);
+}
+
+void Context::hint(GLenum target, GLenum mode)
+{
+ switch (target)
+ {
+ case GL_GENERATE_MIPMAP_HINT:
+ mState.setGenerateMipmapHint(mode);
+ break;
+
+ case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
+ mState.setFragmentShaderDerivativeHint(mode);
+ break;
+
+ case GL_PERSPECTIVE_CORRECTION_HINT:
+ case GL_POINT_SMOOTH_HINT:
+ case GL_LINE_SMOOTH_HINT:
+ case GL_FOG_HINT:
+ mState.gles1().setHint(target, mode);
+ break;
+ case GL_TEXTURE_FILTERING_HINT_CHROMIUM:
+ mState.setTextureFilteringHint(mode);
+ break;
+ default:
+ UNREACHABLE();
+ return;
+ }
+}
+
+void Context::lineWidth(GLfloat width)
+{
+ mState.setLineWidth(width);
+}
+
+void Context::pixelStorei(GLenum pname, GLint param)
+{
+ switch (pname)
+ {
+ case GL_UNPACK_ALIGNMENT:
+ mState.setUnpackAlignment(param);
+ break;
+
+ case GL_PACK_ALIGNMENT:
+ mState.setPackAlignment(param);
+ break;
+
+ case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
+ mState.setPackReverseRowOrder(param != 0);
+ break;
+
+ case GL_UNPACK_ROW_LENGTH:
+ ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimageEXT);
+ mState.setUnpackRowLength(param);
+ break;
+
+ case GL_UNPACK_IMAGE_HEIGHT:
+ ASSERT(getClientMajorVersion() >= 3);
+ mState.setUnpackImageHeight(param);
+ break;
+
+ case GL_UNPACK_SKIP_IMAGES:
+ ASSERT(getClientMajorVersion() >= 3);
+ mState.setUnpackSkipImages(param);
+ break;
+
+ case GL_UNPACK_SKIP_ROWS:
+ ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimageEXT);
+ mState.setUnpackSkipRows(param);
+ break;
+
+ case GL_UNPACK_SKIP_PIXELS:
+ ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimageEXT);
+ mState.setUnpackSkipPixels(param);
+ break;
+
+ case GL_PACK_ROW_LENGTH:
+ ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimageNV);
+ mState.setPackRowLength(param);
+ break;
+
+ case GL_PACK_SKIP_ROWS:
+ ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimageNV);
+ mState.setPackSkipRows(param);
+ break;
+
+ case GL_PACK_SKIP_PIXELS:
+ ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimageNV);
+ mState.setPackSkipPixels(param);
+ break;
+
+ default:
+ UNREACHABLE();
+ return;
+ }
+}
+
+void Context::polygonOffset(GLfloat factor, GLfloat units)
+{
+ mState.setPolygonOffsetParams(factor, units);
+}
+
+void Context::sampleCoverage(GLfloat value, GLboolean invert)
+{
+ mState.setSampleCoverageParams(clamp01(value), ConvertToBool(invert));
+}
+
+void Context::sampleMaski(GLuint maskNumber, GLbitfield mask)
+{
+ mState.setSampleMaskParams(maskNumber, mask);
+}
+
+void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ mState.setScissorParams(x, y, width, height);
+}
+
+void Context::shadingRateQCOM(GLenum rate)
+{
+ mState.setShadingRate(rate);
+}
+
+void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
+{
+ GLint clampedRef = gl::clamp(ref, 0, std::numeric_limits<uint8_t>::max());
+ if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
+ {
+ mState.setStencilParams(func, clampedRef, mask);
+ }
+
+ if (face == GL_BACK || face == GL_FRONT_AND_BACK)
+ {
+ mState.setStencilBackParams(func, clampedRef, mask);
+ }
+
+ mStateCache.onStencilStateChange(this);
+}
+
+void Context::stencilMaskSeparate(GLenum face, GLuint mask)
+{
+ if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
+ {
+ mState.setStencilWritemask(mask);
+ }
+
+ if (face == GL_BACK || face == GL_FRONT_AND_BACK)
+ {
+ mState.setStencilBackWritemask(mask);
+ }
+
+ mStateCache.onStencilStateChange(this);
+}
+
+void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
+{
+ if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
+ {
+ mState.setStencilOperations(fail, zfail, zpass);
+ }
+
+ if (face == GL_BACK || face == GL_FRONT_AND_BACK)
+ {
+ mState.setStencilBackOperations(fail, zfail, zpass);
+ }
+}
+
+void Context::vertexAttrib1f(GLuint index, GLfloat x)
+{
+ GLfloat vals[4] = {x, 0, 0, 1};
+ mState.setVertexAttribf(index, vals);
+ mStateCache.onDefaultVertexAttributeChange(this);
+}
+
+void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
+{
+ GLfloat vals[4] = {values[0], 0, 0, 1};
+ mState.setVertexAttribf(index, vals);
+ mStateCache.onDefaultVertexAttributeChange(this);
+}
+
+void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
+{
+ GLfloat vals[4] = {x, y, 0, 1};
+ mState.setVertexAttribf(index, vals);
+ mStateCache.onDefaultVertexAttributeChange(this);
+}
+
+void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
+{
+ GLfloat vals[4] = {values[0], values[1], 0, 1};
+ mState.setVertexAttribf(index, vals);
+ mStateCache.onDefaultVertexAttributeChange(this);
+}
+
+void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
+{
+ GLfloat vals[4] = {x, y, z, 1};
+ mState.setVertexAttribf(index, vals);
+ mStateCache.onDefaultVertexAttributeChange(this);
+}
+
+void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
+{
+ GLfloat vals[4] = {values[0], values[1], values[2], 1};
+ mState.setVertexAttribf(index, vals);
+ mStateCache.onDefaultVertexAttributeChange(this);
+}
+
+void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ GLfloat vals[4] = {x, y, z, w};
+ mState.setVertexAttribf(index, vals);
+ mStateCache.onDefaultVertexAttributeChange(this);
+}
+
+void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
+{
+ mState.setVertexAttribf(index, values);
+ mStateCache.onDefaultVertexAttributeChange(this);
+}
+
+void Context::vertexAttribPointer(GLuint index,
+ GLint size,
+ VertexAttribType type,
+ GLboolean normalized,
+ GLsizei stride,
+ const void *ptr)
+{
+ mState.setVertexAttribPointer(this, index, mState.getTargetBuffer(BufferBinding::Array), size,
+ type, ConvertToBool(normalized), stride, ptr);
+ mStateCache.onVertexArrayStateChange(this);
+}
+
+void Context::vertexAttribFormat(GLuint attribIndex,
+ GLint size,
+ VertexAttribType type,
+ GLboolean normalized,
+ GLuint relativeOffset)
+{
+ mState.setVertexAttribFormat(attribIndex, size, type, ConvertToBool(normalized), false,
+ relativeOffset);
+ mStateCache.onVertexArrayFormatChange(this);
+}
+
+void Context::vertexAttribIFormat(GLuint attribIndex,
+ GLint size,
+ VertexAttribType type,
+ GLuint relativeOffset)
+{
+ mState.setVertexAttribFormat(attribIndex, size, type, false, true, relativeOffset);
+ mStateCache.onVertexArrayFormatChange(this);
+}
+
+void Context::vertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
+{
+ mState.setVertexAttribBinding(this, attribIndex, bindingIndex);
+ mStateCache.onVertexArrayStateChange(this);
+}
+
+void Context::vertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
+{
+ mState.setVertexBindingDivisor(this, bindingIndex, divisor);
+ mStateCache.onVertexArrayFormatChange(this);
+}
+
+void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ mState.setViewportParams(x, y, width, height);
+}
+
+void Context::vertexAttribIPointer(GLuint index,
+ GLint size,
+ VertexAttribType type,
+ GLsizei stride,
+ const void *pointer)
+{
+ mState.setVertexAttribIPointer(this, index, mState.getTargetBuffer(BufferBinding::Array), size,
+ type, stride, pointer);
+ mStateCache.onVertexArrayStateChange(this);
+}
+
+void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
+{
+ GLint vals[4] = {x, y, z, w};
+ mState.setVertexAttribi(index, vals);
+ mStateCache.onDefaultVertexAttributeChange(this);
+}
+
+void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
+{
+ GLuint vals[4] = {x, y, z, w};
+ mState.setVertexAttribu(index, vals);
+ mStateCache.onDefaultVertexAttributeChange(this);
+}
+
+void Context::vertexAttribI4iv(GLuint index, const GLint *v)
+{
+ mState.setVertexAttribi(index, v);
+ mStateCache.onDefaultVertexAttributeChange(this);
+}
+
+void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
+{
+ mState.setVertexAttribu(index, v);
+ mStateCache.onDefaultVertexAttributeChange(this);
+}
+
+void Context::getVertexAttribivImpl(GLuint index, GLenum pname, GLint *params) const
+{
+ const VertexAttribCurrentValueData &currentValues =
+ getState().getVertexAttribCurrentValue(index);
+ const VertexArray *vao = getState().getVertexArray();
+ QueryVertexAttribiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
+ currentValues, pname, params);
+}
+
+void Context::getVertexAttribiv(GLuint index, GLenum pname, GLint *params)
+{
+ return getVertexAttribivImpl(index, pname, params);
+}
+
+void Context::getVertexAttribivRobust(GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ getVertexAttribiv(index, pname, params);
+}
+
+void Context::getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
+{
+ const VertexAttribCurrentValueData &currentValues =
+ getState().getVertexAttribCurrentValue(index);
+ const VertexArray *vao = getState().getVertexArray();
+ QueryVertexAttribfv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
+ currentValues, pname, params);
+}
+
+void Context::getVertexAttribfvRobust(GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params)
+{
+ getVertexAttribfv(index, pname, params);
+}
+
+void Context::getVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
+{
+ const VertexAttribCurrentValueData &currentValues =
+ getState().getVertexAttribCurrentValue(index);
+ const VertexArray *vao = getState().getVertexArray();
+ QueryVertexAttribIiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
+ currentValues, pname, params);
+}
+
+void Context::getVertexAttribIivRobust(GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ getVertexAttribIiv(index, pname, params);
+}
+
+void Context::getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
+{
+ const VertexAttribCurrentValueData &currentValues =
+ getState().getVertexAttribCurrentValue(index);
+ const VertexArray *vao = getState().getVertexArray();
+ QueryVertexAttribIuiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
+ currentValues, pname, params);
+}
+
+void Context::getVertexAttribIuivRobust(GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint *params)
+{
+ getVertexAttribIuiv(index, pname, params);
+}
+
+void Context::getVertexAttribPointerv(GLuint index, GLenum pname, void **pointer)
+{
+ const VertexAttribute &attrib = getState().getVertexArray()->getVertexAttribute(index);
+ QueryVertexAttribPointerv(attrib, pname, pointer);
+}
+
+void Context::getVertexAttribPointervRobust(GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ void **pointer)
+{
+ getVertexAttribPointerv(index, pname, pointer);
+}
+
+void Context::debugMessageControl(GLenum source,
+ GLenum type,
+ GLenum severity,
+ GLsizei count,
+ const GLuint *ids,
+ GLboolean enabled)
+{
+ std::vector<GLuint> idVector(ids, ids + count);
+ mState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
+ ConvertToBool(enabled));
+}
+
+void Context::debugMessageInsert(GLenum source,
+ GLenum type,
+ GLuint id,
+ GLenum severity,
+ GLsizei length,
+ const GLchar *buf)
+{
+ std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
+ mState.getDebug().insertMessage(source, type, id, severity, std::move(msg), gl::LOG_INFO,
+ angle::EntryPoint::GLDebugMessageInsert);
+}
+
+void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
+{
+ mState.getDebug().setCallback(callback, userParam);
+}
+
+GLuint Context::getDebugMessageLog(GLuint count,
+ GLsizei bufSize,
+ GLenum *sources,
+ GLenum *types,
+ GLuint *ids,
+ GLenum *severities,
+ GLsizei *lengths,
+ GLchar *messageLog)
+{
+ return static_cast<GLuint>(mState.getDebug().getMessages(count, bufSize, sources, types, ids,
+ severities, lengths, messageLog));
+}
+
+void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
+{
+ std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
+ ANGLE_CONTEXT_TRY(mImplementation->pushDebugGroup(this, source, id, msg));
+ mState.getDebug().pushGroup(source, id, std::move(msg));
+}
+
+angle::Result Context::handleNoopDrawEvent()
+{
+ return (mImplementation->handleNoopDrawEvent());
+}
+
+void Context::popDebugGroup()
+{
+ mState.getDebug().popGroup();
+ ANGLE_CONTEXT_TRY(mImplementation->popDebugGroup(this));
+}
+
+void Context::primitiveBoundingBox(GLfloat minX,
+ GLfloat minY,
+ GLfloat minZ,
+ GLfloat minW,
+ GLfloat maxX,
+ GLfloat maxY,
+ GLfloat maxZ,
+ GLfloat maxW)
+{
+ mState.mBoundingBoxMinX = minX;
+ mState.mBoundingBoxMinY = minY;
+ mState.mBoundingBoxMinZ = minZ;
+ mState.mBoundingBoxMinW = minW;
+ mState.mBoundingBoxMaxX = maxX;
+ mState.mBoundingBoxMaxY = maxY;
+ mState.mBoundingBoxMaxZ = maxZ;
+ mState.mBoundingBoxMaxW = maxW;
+}
+
+void Context::bufferStorage(BufferBinding target,
+ GLsizeiptr size,
+ const void *data,
+ GLbitfield flags)
+{
+ Buffer *buffer = mState.getTargetBuffer(target);
+ ASSERT(buffer);
+ ANGLE_CONTEXT_TRY(buffer->bufferStorage(this, target, size, data, flags));
+}
+
+void Context::bufferStorageExternal(BufferBinding target,
+ GLintptr offset,
+ GLsizeiptr size,
+ GLeglClientBufferEXT clientBuffer,
+ GLbitfield flags)
+{
+ Buffer *buffer = mState.getTargetBuffer(target);
+ ASSERT(buffer);
+
+ ANGLE_CONTEXT_TRY(buffer->bufferStorageExternal(this, target, size, clientBuffer, flags));
+}
+
+void Context::namedBufferStorageExternal(GLuint buffer,
+ GLintptr offset,
+ GLsizeiptr size,
+ GLeglClientBufferEXT clientBuffer,
+ GLbitfield flags)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::bufferData(BufferBinding target, GLsizeiptr size, const void *data, BufferUsage usage)
+{
+ Buffer *buffer = mState.getTargetBuffer(target);
+ ASSERT(buffer);
+ ANGLE_CONTEXT_TRY(buffer->bufferData(this, target, data, size, usage));
+}
+
+void Context::bufferSubData(BufferBinding target,
+ GLintptr offset,
+ GLsizeiptr size,
+ const void *data)
+{
+ if (data == nullptr || size == 0)
+ {
+ return;
+ }
+
+ Buffer *buffer = mState.getTargetBuffer(target);
+ ASSERT(buffer);
+ ANGLE_CONTEXT_TRY(buffer->bufferSubData(this, target, data, size, offset));
+}
+
+void Context::attachShader(ShaderProgramID program, ShaderProgramID shader)
+{
+ Program *programObject = mState.mShaderProgramManager->getProgram(program);
+ Shader *shaderObject = mState.mShaderProgramManager->getShader(shader);
+ ASSERT(programObject && shaderObject);
+ programObject->attachShader(shaderObject);
+}
+
+void Context::copyBufferSubData(BufferBinding readTarget,
+ BufferBinding writeTarget,
+ GLintptr readOffset,
+ GLintptr writeOffset,
+ GLsizeiptr size)
+{
+ // if size is zero, the copy is a successful no-op
+ if (size == 0)
+ {
+ return;
+ }
+
+ // TODO(jmadill): cache these.
+ Buffer *readBuffer = mState.getTargetBuffer(readTarget);
+ Buffer *writeBuffer = mState.getTargetBuffer(writeTarget);
+
+ ANGLE_CONTEXT_TRY(
+ writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
+}
+
+void Context::bindAttribLocation(ShaderProgramID program, GLuint index, const GLchar *name)
+{
+ // Ideally we could share the program query with the validation layer if possible.
+ Program *programObject = getProgramResolveLink(program);
+ ASSERT(programObject);
+ programObject->bindAttributeLocation(index, name);
+}
+
+void Context::bindBufferBase(BufferBinding target, GLuint index, BufferID buffer)
+{
+ bindBufferRange(target, index, buffer, 0, 0);
+}
+
+void Context::bindBufferRange(BufferBinding target,
+ GLuint index,
+ BufferID buffer,
+ GLintptr offset,
+ GLsizeiptr size)
+{
+ Buffer *object = mState.mBufferManager->checkBufferAllocation(mImplementation.get(), buffer);
+ ANGLE_CONTEXT_TRY(mState.setIndexedBufferBinding(this, target, index, object, offset, size));
+ if (target == BufferBinding::Uniform)
+ {
+ mUniformBufferObserverBindings[index].bind(object);
+ mStateCache.onUniformBufferStateChange(this);
+ }
+ else if (target == BufferBinding::AtomicCounter)
+ {
+ mAtomicCounterBufferObserverBindings[index].bind(object);
+ mStateCache.onAtomicCounterBufferStateChange(this);
+ }
+ else if (target == BufferBinding::ShaderStorage)
+ {
+ mShaderStorageBufferObserverBindings[index].bind(object);
+ mStateCache.onShaderStorageBufferStateChange(this);
+ }
+ else
+ {
+ mStateCache.onBufferBindingChange(this);
+ }
+}
+
+void Context::bindFramebuffer(GLenum target, FramebufferID framebuffer)
+{
+ if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
+ {
+ bindReadFramebuffer(framebuffer);
+ }
+
+ if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
+ {
+ bindDrawFramebuffer(framebuffer);
+ }
+}
+
+void Context::bindRenderbuffer(GLenum target, RenderbufferID renderbuffer)
+{
+ ASSERT(target == GL_RENDERBUFFER);
+ Renderbuffer *object = mState.mRenderbufferManager->checkRenderbufferAllocation(
+ mImplementation.get(), renderbuffer);
+ mState.setRenderbufferBinding(this, object);
+}
+
+void Context::texStorage2DMultisample(TextureType target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedsamplelocations)
+{
+ Extents size(width, height, 1);
+ Texture *texture = getTextureByType(target);
+ ANGLE_CONTEXT_TRY(texture->setStorageMultisample(this, target, samples, internalformat, size,
+ ConvertToBool(fixedsamplelocations)));
+}
+
+void Context::texStorage3DMultisample(TextureType target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean fixedsamplelocations)
+{
+ Extents size(width, height, depth);
+ Texture *texture = getTextureByType(target);
+ ANGLE_CONTEXT_TRY(texture->setStorageMultisample(this, target, samples, internalformat, size,
+ ConvertToBool(fixedsamplelocations)));
+}
+
+void Context::texImage2DExternal(TextureTarget target,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLenum format,
+ GLenum type)
+{
+ Extents size(width, height, 1);
+ Texture *texture = getTextureByTarget(target);
+ ANGLE_CONTEXT_TRY(
+ texture->setImageExternal(this, target, level, internalformat, size, format, type));
+}
+
+void Context::invalidateTexture(TextureType target)
+{
+ mImplementation->invalidateTexture(target);
+ mState.invalidateTextureBindings(target);
+}
+
+void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
+{
+ // According to spec 3.1 Table 20.49: Framebuffer Dependent Values,
+ // the sample position should be queried by DRAW_FRAMEBUFFER.
+ ANGLE_CONTEXT_TRY(mState.syncDirtyObject(this, GL_DRAW_FRAMEBUFFER));
+ const Framebuffer *framebuffer = mState.getDrawFramebuffer();
+
+ switch (pname)
+ {
+ case GL_SAMPLE_POSITION:
+ ANGLE_CONTEXT_TRY(framebuffer->getSamplePosition(this, index, val));
+ break;
+ default:
+ UNREACHABLE();
+ }
+}
+
+void Context::getMultisamplefvRobust(GLenum pname,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *val)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::renderbufferStorage(GLenum target,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height)
+{
+ // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
+ GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
+
+ Renderbuffer *renderbuffer = mState.getCurrentRenderbuffer();
+ ANGLE_CONTEXT_TRY(renderbuffer->setStorage(this, convertedInternalFormat, width, height));
+}
+
+void Context::renderbufferStorageMultisample(GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height)
+{
+ renderbufferStorageMultisampleImpl(target, samples, internalformat, width, height,
+ MultisamplingMode::Regular);
+}
+
+void Context::renderbufferStorageMultisampleEXT(GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height)
+{
+ renderbufferStorageMultisampleImpl(target, samples, internalformat, width, height,
+ MultisamplingMode::MultisampledRenderToTexture);
+}
+
+void Context::renderbufferStorageMultisampleImpl(GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ MultisamplingMode mode)
+{
+ // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
+ GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
+
+ Renderbuffer *renderbuffer = mState.getCurrentRenderbuffer();
+ ANGLE_CONTEXT_TRY(renderbuffer->setStorageMultisample(this, samples, convertedInternalFormat,
+ width, height, mode));
+}
+
+void Context::framebufferTexture2DMultisample(GLenum target,
+ GLenum attachment,
+ TextureTarget textarget,
+ TextureID texture,
+ GLint level,
+ GLsizei samples)
+{
+ Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
+ ASSERT(framebuffer);
+
+ if (texture.value != 0)
+ {
+ Texture *textureObj = getTexture(texture);
+ ImageIndex index = ImageIndex::MakeFromTarget(textarget, level, 1);
+ framebuffer->setAttachmentMultisample(this, GL_TEXTURE, attachment, index, textureObj,
+ samples);
+ }
+ else
+ {
+ framebuffer->resetAttachment(this, attachment);
+ }
+
+ mState.setObjectDirty(target);
+}
+
+void Context::getSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)
+{
+ const Sync *syncObject = nullptr;
+ if (!isContextLost())
+ {
+ syncObject = getSync(sync);
+ }
+ ANGLE_CONTEXT_TRY(QuerySynciv(this, syncObject, pname, bufSize, length, values));
+}
+
+void Context::getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
+{
+ Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
+ QueryFramebufferParameteriv(framebuffer, pname, params);
+}
+
+void Context::getFramebufferParameterivRobust(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::framebufferParameteri(GLenum target, GLenum pname, GLint param)
+{
+ Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
+ SetFramebufferParameteri(this, framebuffer, pname, param);
+}
+
+bool Context::getScratchBuffer(size_t requstedSizeBytes,
+ angle::MemoryBuffer **scratchBufferOut) const
+{
+ if (!mScratchBuffer.valid())
+ {
+ mScratchBuffer = mDisplay->requestScratchBuffer();
+ }
+
+ ASSERT(mScratchBuffer.valid());
+ return mScratchBuffer.value().get(requstedSizeBytes, scratchBufferOut);
+}
+
+angle::ScratchBuffer *Context::getScratchBuffer() const
+{
+ if (!mScratchBuffer.valid())
+ {
+ mScratchBuffer = mDisplay->requestScratchBuffer();
+ }
+
+ ASSERT(mScratchBuffer.valid());
+ return &mScratchBuffer.value();
+}
+
+bool Context::getZeroFilledBuffer(size_t requstedSizeBytes,
+ angle::MemoryBuffer **zeroBufferOut) const
+{
+ if (!mZeroFilledBuffer.valid())
+ {
+ mZeroFilledBuffer = mDisplay->requestZeroFilledBuffer();
+ }
+
+ ASSERT(mZeroFilledBuffer.valid());
+ return mZeroFilledBuffer.value().getInitialized(requstedSizeBytes, zeroBufferOut, 0);
+}
+
+void Context::dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ)
+{
+ if (numGroupsX == 0u || numGroupsY == 0u || numGroupsZ == 0u)
+ {
+ return;
+ }
+
+ ANGLE_CONTEXT_TRY(prepareForDispatch());
+
+ angle::Result result =
+ mImplementation->dispatchCompute(this, numGroupsX, numGroupsY, numGroupsZ);
+
+ // This must be called before convertPpoToComputeOrDraw() so it uses the PPO's compute values
+ // before convertPpoToComputeOrDraw() reverts the PPO back to graphics.
+ MarkShaderStorageUsage(this);
+
+ if (ANGLE_UNLIKELY(IsError(result)))
+ {
+ return;
+ }
+}
+
+void Context::dispatchComputeIndirect(GLintptr indirect)
+{
+ ANGLE_CONTEXT_TRY(prepareForDispatch());
+ ANGLE_CONTEXT_TRY(mImplementation->dispatchComputeIndirect(this, indirect));
+
+ MarkShaderStorageUsage(this);
+}
+
+void Context::texStorage2D(TextureType target,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height)
+{
+ Extents size(width, height, 1);
+ Texture *texture = getTextureByType(target);
+ ANGLE_CONTEXT_TRY(texture->setStorage(this, target, levels, internalFormat, size));
+}
+
+void Context::texStorage3D(TextureType target,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth)
+{
+ Extents size(width, height, depth);
+ Texture *texture = getTextureByType(target);
+ ANGLE_CONTEXT_TRY(texture->setStorage(this, target, levels, internalFormat, size));
+}
+
+void Context::memoryBarrier(GLbitfield barriers)
+{
+ ANGLE_CONTEXT_TRY(mImplementation->memoryBarrier(this, barriers));
+}
+
+void Context::memoryBarrierByRegion(GLbitfield barriers)
+{
+ ANGLE_CONTEXT_TRY(mImplementation->memoryBarrierByRegion(this, barriers));
+}
+
+void Context::multiDrawArrays(PrimitiveMode mode,
+ const GLint *firsts,
+ const GLsizei *counts,
+ GLsizei drawcount)
+{
+ ANGLE_CONTEXT_TRY(prepareForDraw(mode));
+ ANGLE_CONTEXT_TRY(mImplementation->multiDrawArrays(this, mode, firsts, counts, drawcount));
+}
+
+void Context::multiDrawArraysInstanced(PrimitiveMode mode,
+ const GLint *firsts,
+ const GLsizei *counts,
+ const GLsizei *instanceCounts,
+ GLsizei drawcount)
+{
+ ANGLE_CONTEXT_TRY(prepareForDraw(mode));
+ ANGLE_CONTEXT_TRY(mImplementation->multiDrawArraysInstanced(this, mode, firsts, counts,
+ instanceCounts, drawcount));
+}
+
+void Context::multiDrawArraysIndirect(PrimitiveMode mode,
+ const void *indirect,
+ GLsizei drawcount,
+ GLsizei stride)
+{
+ ANGLE_CONTEXT_TRY(prepareForDraw(mode));
+ ANGLE_CONTEXT_TRY(
+ mImplementation->multiDrawArraysIndirect(this, mode, indirect, drawcount, stride));
+ MarkShaderStorageUsage(this);
+}
+
+void Context::multiDrawElements(PrimitiveMode mode,
+ const GLsizei *counts,
+ DrawElementsType type,
+ const GLvoid *const *indices,
+ GLsizei drawcount)
+{
+ ANGLE_CONTEXT_TRY(prepareForDraw(mode));
+ ANGLE_CONTEXT_TRY(
+ mImplementation->multiDrawElements(this, mode, counts, type, indices, drawcount));
+}
+
+void Context::multiDrawElementsInstanced(PrimitiveMode mode,
+ const GLsizei *counts,
+ DrawElementsType type,
+ const GLvoid *const *indices,
+ const GLsizei *instanceCounts,
+ GLsizei drawcount)
+{
+ ANGLE_CONTEXT_TRY(prepareForDraw(mode));
+ ANGLE_CONTEXT_TRY(mImplementation->multiDrawElementsInstanced(this, mode, counts, type, indices,
+ instanceCounts, drawcount));
+}
+
+void Context::multiDrawElementsIndirect(PrimitiveMode mode,
+ DrawElementsType type,
+ const void *indirect,
+ GLsizei drawcount,
+ GLsizei stride)
+{
+ ANGLE_CONTEXT_TRY(prepareForDraw(mode));
+ ANGLE_CONTEXT_TRY(
+ mImplementation->multiDrawElementsIndirect(this, mode, type, indirect, drawcount, stride));
+ MarkShaderStorageUsage(this);
+}
+
+void Context::drawArraysInstancedBaseInstance(PrimitiveMode mode,
+ GLint first,
+ GLsizei count,
+ GLsizei instanceCount,
+ GLuint baseInstance)
+{
+ if (noopDrawInstanced(mode, count, instanceCount))
+ {
+ ANGLE_CONTEXT_TRY(mImplementation->handleNoopDrawEvent());
+ return;
+ }
+
+ ANGLE_CONTEXT_TRY(prepareForDraw(mode));
+ Program *programObject = mState.getLinkedProgram(this);
+
+ const bool hasBaseInstance = programObject && programObject->hasBaseInstanceUniform();
+ if (hasBaseInstance)
+ {
+ programObject->setBaseInstanceUniform(baseInstance);
+ }
+
+ rx::ResetBaseVertexBaseInstance resetUniforms(programObject, false, hasBaseInstance);
+
+ // The input gl_InstanceID does not follow the baseinstance. gl_InstanceID always falls on
+ // the half-open range [0, instancecount). No need to set other stuff. Except for Vulkan.
+
+ ANGLE_CONTEXT_TRY(mImplementation->drawArraysInstancedBaseInstance(
+ this, mode, first, count, instanceCount, baseInstance));
+ MarkTransformFeedbackBufferUsage(this, count, 1);
+}
+
+void Context::drawArraysInstancedBaseInstanceANGLE(PrimitiveMode mode,
+ GLint first,
+ GLsizei count,
+ GLsizei instanceCount,
+ GLuint baseInstance)
+{
+ drawArraysInstancedBaseInstance(mode, first, count, instanceCount, baseInstance);
+}
+
+void Context::drawElementsInstancedBaseInstance(PrimitiveMode mode,
+ GLsizei count,
+ DrawElementsType type,
+ const void *indices,
+ GLsizei instanceCount,
+ GLuint baseInstance)
+{
+ drawElementsInstancedBaseVertexBaseInstance(mode, count, type, indices, instanceCount, 0,
+ baseInstance);
+}
+
+void Context::drawElementsInstancedBaseVertexBaseInstance(PrimitiveMode mode,
+ GLsizei count,
+ DrawElementsType type,
+ const GLvoid *indices,
+ GLsizei instanceCount,
+ GLint baseVertex,
+ GLuint baseInstance)
+{
+ if (noopDrawInstanced(mode, count, instanceCount))
+ {
+ ANGLE_CONTEXT_TRY(mImplementation->handleNoopDrawEvent());
+ return;
+ }
+
+ ANGLE_CONTEXT_TRY(prepareForDraw(mode));
+ Program *programObject = mState.getLinkedProgram(this);
+
+ const bool hasBaseVertex = programObject && programObject->hasBaseVertexUniform();
+ if (hasBaseVertex)
+ {
+ programObject->setBaseVertexUniform(baseVertex);
+ }
+
+ const bool hasBaseInstance = programObject && programObject->hasBaseInstanceUniform();
+ if (hasBaseInstance)
+ {
+ programObject->setBaseInstanceUniform(baseInstance);
+ }
+
+ rx::ResetBaseVertexBaseInstance resetUniforms(programObject, hasBaseVertex, hasBaseInstance);
+
+ ANGLE_CONTEXT_TRY(mImplementation->drawElementsInstancedBaseVertexBaseInstance(
+ this, mode, count, type, indices, instanceCount, baseVertex, baseInstance));
+}
+
+void Context::drawElementsInstancedBaseVertexBaseInstanceANGLE(PrimitiveMode mode,
+ GLsizei count,
+ DrawElementsType type,
+ const GLvoid *indices,
+ GLsizei instanceCount,
+ GLint baseVertex,
+ GLuint baseInstance)
+{
+ drawElementsInstancedBaseVertexBaseInstance(mode, count, type, indices, instanceCount,
+ baseVertex, baseInstance);
+}
+
+void Context::multiDrawArraysInstancedBaseInstance(PrimitiveMode mode,
+ const GLint *firsts,
+ const GLsizei *counts,
+ const GLsizei *instanceCounts,
+ const GLuint *baseInstances,
+ GLsizei drawcount)
+{
+ ANGLE_CONTEXT_TRY(prepareForDraw(mode));
+ ANGLE_CONTEXT_TRY(mImplementation->multiDrawArraysInstancedBaseInstance(
+ this, mode, firsts, counts, instanceCounts, baseInstances, drawcount));
+}
+
+void Context::multiDrawElementsInstancedBaseVertexBaseInstance(PrimitiveMode mode,
+ const GLsizei *counts,
+ DrawElementsType type,
+ const GLvoid *const *indices,
+ const GLsizei *instanceCounts,
+ const GLint *baseVertices,
+ const GLuint *baseInstances,
+ GLsizei drawcount)
+{
+ ANGLE_CONTEXT_TRY(prepareForDraw(mode));
+ ANGLE_CONTEXT_TRY(mImplementation->multiDrawElementsInstancedBaseVertexBaseInstance(
+ this, mode, counts, type, indices, instanceCounts, baseVertices, baseInstances, drawcount));
+}
+
+void Context::provokingVertex(ProvokingVertexConvention provokeMode)
+{
+ mState.setProvokingVertex(provokeMode);
+}
+
+GLenum Context::checkFramebufferStatus(GLenum target)
+{
+ Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
+ ASSERT(framebuffer);
+ return framebuffer->checkStatus(this).status;
+}
+
+void Context::compileShader(ShaderProgramID shader)
+{
+ Shader *shaderObject = GetValidShader(this, angle::EntryPoint::GLCompileShader, shader);
+ if (!shaderObject)
+ {
+ return;
+ }
+ shaderObject->compile(this);
+}
+
+void Context::deleteBuffers(GLsizei n, const BufferID *buffers)
+{
+ for (int i = 0; i < n; i++)
+ {
+ deleteBuffer(buffers[i]);
+ }
+}
+
+void Context::deleteFramebuffers(GLsizei n, const FramebufferID *framebuffers)
+{
+ for (int i = 0; i < n; i++)
+ {
+ if (framebuffers[i].value != 0)
+ {
+ deleteFramebuffer(framebuffers[i]);
+ }
+ }
+}
+
+void Context::deleteRenderbuffers(GLsizei n, const RenderbufferID *renderbuffers)
+{
+ for (int i = 0; i < n; i++)
+ {
+ deleteRenderbuffer(renderbuffers[i]);
+ }
+}
+
+void Context::deleteTextures(GLsizei n, const TextureID *textures)
+{
+ for (int i = 0; i < n; i++)
+ {
+ if (textures[i].value != 0)
+ {
+ deleteTexture(textures[i]);
+ }
+ }
+}
+
+void Context::detachShader(ShaderProgramID program, ShaderProgramID shader)
+{
+ Program *programObject = getProgramNoResolveLink(program);
+ ASSERT(programObject);
+
+ Shader *shaderObject = getShader(shader);
+ ASSERT(shaderObject);
+
+ programObject->detachShader(this, shaderObject);
+}
+
+void Context::genBuffers(GLsizei n, BufferID *buffers)
+{
+ for (int i = 0; i < n; i++)
+ {
+ buffers[i] = createBuffer();
+ }
+}
+
+void Context::genFramebuffers(GLsizei n, FramebufferID *framebuffers)
+{
+ for (int i = 0; i < n; i++)
+ {
+ framebuffers[i] = createFramebuffer();
+ }
+}
+
+void Context::genRenderbuffers(GLsizei n, RenderbufferID *renderbuffers)
+{
+ for (int i = 0; i < n; i++)
+ {
+ renderbuffers[i] = createRenderbuffer();
+ }
+}
+
+void Context::genTextures(GLsizei n, TextureID *textures)
+{
+ for (int i = 0; i < n; i++)
+ {
+ textures[i] = createTexture();
+ }
+}
+
+void Context::getActiveAttrib(ShaderProgramID program,
+ GLuint index,
+ GLsizei bufsize,
+ GLsizei *length,
+ GLint *size,
+ GLenum *type,
+ GLchar *name)
+{
+ Program *programObject = getProgramResolveLink(program);
+ ASSERT(programObject);
+ programObject->getActiveAttribute(index, bufsize, length, size, type, name);
+}
+
+void Context::getActiveUniform(ShaderProgramID program,
+ GLuint index,
+ GLsizei bufsize,
+ GLsizei *length,
+ GLint *size,
+ GLenum *type,
+ GLchar *name)
+{
+ Program *programObject = getProgramResolveLink(program);
+ ASSERT(programObject);
+ programObject->getActiveUniform(index, bufsize, length, size, type, name);
+}
+
+void Context::getAttachedShaders(ShaderProgramID program,
+ GLsizei maxcount,
+ GLsizei *count,
+ ShaderProgramID *shaders)
+{
+ Program *programObject = getProgramNoResolveLink(program);
+ ASSERT(programObject);
+ programObject->getAttachedShaders(maxcount, count, shaders);
+}
+
+GLint Context::getAttribLocation(ShaderProgramID program, const GLchar *name)
+{
+ Program *programObject = getProgramResolveLink(program);
+ ASSERT(programObject);
+ return programObject->getAttributeLocation(name);
+}
+
+void Context::getBooleanv(GLenum pname, GLboolean *params)
+{
+ GLenum nativeType;
+ unsigned int numParams = 0;
+ getQueryParameterInfo(pname, &nativeType, &numParams);
+
+ if (nativeType == GL_BOOL)
+ {
+ getBooleanvImpl(pname, params);
+ }
+ else
+ {
+ CastStateValues(this, nativeType, pname, numParams, params);
+ }
+}
+
+void Context::getBooleanvRobust(GLenum pname, GLsizei bufSize, GLsizei *length, GLboolean *params)
+{
+ getBooleanv(pname, params);
+}
+
+void Context::getFloatv(GLenum pname, GLfloat *params)
+{
+ GLenum nativeType;
+ unsigned int numParams = 0;
+ getQueryParameterInfo(pname, &nativeType, &numParams);
+
+ if (nativeType == GL_FLOAT)
+ {
+ getFloatvImpl(pname, params);
+ }
+ else
+ {
+ CastStateValues(this, nativeType, pname, numParams, params);
+ }
+}
+
+void Context::getFloatvRobust(GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params)
+{
+ getFloatv(pname, params);
+}
+
+void Context::getIntegerv(GLenum pname, GLint *params)
+{
+ GLenum nativeType = GL_NONE;
+ unsigned int numParams = 0;
+ getQueryParameterInfo(pname, &nativeType, &numParams);
+
+ if (nativeType == GL_INT)
+ {
+ getIntegervImpl(pname, params);
+ }
+ else
+ {
+ CastStateValues(this, nativeType, pname, numParams, params);
+ }
+}
+
+void Context::getIntegervRobust(GLenum pname, GLsizei bufSize, GLsizei *length, GLint *data)
+{
+ getIntegerv(pname, data);
+}
+
+void Context::getProgramiv(ShaderProgramID program, GLenum pname, GLint *params)
+{
+ // Don't resolve link if checking the link completion status.
+ Program *programObject = getProgramNoResolveLink(program);
+ if (!isContextLost() && pname != GL_COMPLETION_STATUS_KHR)
+ {
+ programObject = getProgramResolveLink(program);
+ }
+ ASSERT(programObject);
+ QueryProgramiv(this, programObject, pname, params);
+}
+
+void Context::getProgramivRobust(ShaderProgramID program,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ getProgramiv(program, pname, params);
+}
+
+void Context::getProgramPipelineiv(ProgramPipelineID pipeline, GLenum pname, GLint *params)
+{
+ ProgramPipeline *programPipeline = nullptr;
+ if (!mContextLost)
+ {
+ programPipeline = getProgramPipeline(pipeline);
+ }
+ QueryProgramPipelineiv(this, programPipeline, pname, params);
+}
+
+MemoryObject *Context::getMemoryObject(MemoryObjectID handle) const
+{
+ return mState.mMemoryObjectManager->getMemoryObject(handle);
+}
+
+Semaphore *Context::getSemaphore(SemaphoreID handle) const
+{
+ return mState.mSemaphoreManager->getSemaphore(handle);
+}
+
+void Context::getProgramInfoLog(ShaderProgramID program,
+ GLsizei bufsize,
+ GLsizei *length,
+ GLchar *infolog)
+{
+ Program *programObject = getProgramResolveLink(program);
+ ASSERT(programObject);
+ programObject->getExecutable().getInfoLog(bufsize, length, infolog);
+}
+
+void Context::getProgramPipelineInfoLog(ProgramPipelineID pipeline,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *infoLog)
+{
+ ProgramPipeline *programPipeline = getProgramPipeline(pipeline);
+ if (programPipeline)
+ {
+ programPipeline->getExecutable().getInfoLog(bufSize, length, infoLog);
+ }
+ else
+ {
+ *length = 0;
+ *infoLog = '\0';
+ }
+}
+
+void Context::getShaderiv(ShaderProgramID shader, GLenum pname, GLint *params)
+{
+ Shader *shaderObject = nullptr;
+ if (!isContextLost())
+ {
+ shaderObject = getShader(shader);
+ ASSERT(shaderObject);
+ }
+ QueryShaderiv(this, shaderObject, pname, params);
+}
+
+void Context::getShaderivRobust(ShaderProgramID shader,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ getShaderiv(shader, pname, params);
+}
+
+void Context::getShaderInfoLog(ShaderProgramID shader,
+ GLsizei bufsize,
+ GLsizei *length,
+ GLchar *infolog)
+{
+ Shader *shaderObject = getShader(shader);
+ ASSERT(shaderObject);
+ shaderObject->getInfoLog(this, bufsize, length, infolog);
+}
+
+void Context::getShaderPrecisionFormat(GLenum shadertype,
+ GLenum precisiontype,
+ GLint *range,
+ GLint *precision)
+{
+ // TODO(jmadill): Compute shaders.
+
+ switch (shadertype)
+ {
+ case GL_VERTEX_SHADER:
+ switch (precisiontype)
+ {
+ case GL_LOW_FLOAT:
+ mState.mCaps.vertexLowpFloat.get(range, precision);
+ break;
+ case GL_MEDIUM_FLOAT:
+ mState.mCaps.vertexMediumpFloat.get(range, precision);
+ break;
+ case GL_HIGH_FLOAT:
+ mState.mCaps.vertexHighpFloat.get(range, precision);
+ break;
+
+ case GL_LOW_INT:
+ mState.mCaps.vertexLowpInt.get(range, precision);
+ break;
+ case GL_MEDIUM_INT:
+ mState.mCaps.vertexMediumpInt.get(range, precision);
+ break;
+ case GL_HIGH_INT:
+ mState.mCaps.vertexHighpInt.get(range, precision);
+ break;
+
+ default:
+ UNREACHABLE();
+ return;
+ }
+ break;
+
+ case GL_FRAGMENT_SHADER:
+ switch (precisiontype)
+ {
+ case GL_LOW_FLOAT:
+ mState.mCaps.fragmentLowpFloat.get(range, precision);
+ break;
+ case GL_MEDIUM_FLOAT:
+ mState.mCaps.fragmentMediumpFloat.get(range, precision);
+ break;
+ case GL_HIGH_FLOAT:
+ mState.mCaps.fragmentHighpFloat.get(range, precision);
+ break;
+
+ case GL_LOW_INT:
+ mState.mCaps.fragmentLowpInt.get(range, precision);
+ break;
+ case GL_MEDIUM_INT:
+ mState.mCaps.fragmentMediumpInt.get(range, precision);
+ break;
+ case GL_HIGH_INT:
+ mState.mCaps.fragmentHighpInt.get(range, precision);
+ break;
+
+ default:
+ UNREACHABLE();
+ return;
+ }
+ break;
+
+ default:
+ UNREACHABLE();
+ return;
+ }
+}
+
+void Context::getShaderSource(ShaderProgramID shader,
+ GLsizei bufsize,
+ GLsizei *length,
+ GLchar *source)
+{
+ Shader *shaderObject = getShader(shader);
+ ASSERT(shaderObject);
+ shaderObject->getSource(bufsize, length, source);
+}
+
+void Context::getUniformfv(ShaderProgramID program, UniformLocation location, GLfloat *params)
+{
+ Program *programObject = getProgramResolveLink(program);
+ ASSERT(programObject);
+ programObject->getUniformfv(this, location, params);
+}
+
+void Context::getUniformfvRobust(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params)
+{
+ getUniformfv(program, location, params);
+}
+
+void Context::getUniformiv(ShaderProgramID program, UniformLocation location, GLint *params)
+{
+ Program *programObject = getProgramResolveLink(program);
+ ASSERT(programObject);
+ programObject->getUniformiv(this, location, params);
+}
+
+void Context::getUniformivRobust(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ getUniformiv(program, location, params);
+}
+
+GLint Context::getUniformLocation(ShaderProgramID program, const GLchar *name)
+{
+ Program *programObject = getProgramResolveLink(program);
+ ASSERT(programObject);
+ return programObject->getUniformLocation(name).value;
+}
+
+GLboolean Context::isBuffer(BufferID buffer) const
+{
+ if (buffer.value == 0)
+ {
+ return GL_FALSE;
+ }
+
+ return ConvertToGLBoolean(getBuffer(buffer));
+}
+
+GLboolean Context::isEnabled(GLenum cap) const
+{
+ return mState.getEnableFeature(cap);
+}
+
+GLboolean Context::isEnabledi(GLenum target, GLuint index) const
+{
+ return mState.getEnableFeatureIndexed(target, index);
+}
+
+GLboolean Context::isFramebuffer(FramebufferID framebuffer) const
+{
+ if (framebuffer.value == 0)
+ {
+ return GL_FALSE;
+ }
+
+ return ConvertToGLBoolean(getFramebuffer(framebuffer));
+}
+
+GLboolean Context::isProgram(ShaderProgramID program) const
+{
+ if (program.value == 0)
+ {
+ return GL_FALSE;
+ }
+
+ return ConvertToGLBoolean(getProgramNoResolveLink(program));
+}
+
+GLboolean Context::isRenderbuffer(RenderbufferID renderbuffer) const
+{
+ if (renderbuffer.value == 0)
+ {
+ return GL_FALSE;
+ }
+
+ return ConvertToGLBoolean(getRenderbuffer(renderbuffer));
+}
+
+GLboolean Context::isShader(ShaderProgramID shader) const
+{
+ if (shader.value == 0)
+ {
+ return GL_FALSE;
+ }
+
+ return ConvertToGLBoolean(getShader(shader));
+}
+
+GLboolean Context::isTexture(TextureID texture) const
+{
+ if (texture.value == 0)
+ {
+ return GL_FALSE;
+ }
+
+ return ConvertToGLBoolean(getTexture(texture));
+}
+
+void Context::linkProgram(ShaderProgramID program)
+{
+ Program *programObject = getProgramNoResolveLink(program);
+ ASSERT(programObject);
+ ANGLE_CONTEXT_TRY(programObject->link(this));
+ ANGLE_CONTEXT_TRY(onProgramLink(programObject));
+}
+
+void Context::releaseShaderCompiler()
+{
+ mCompiler.set(this, nullptr);
+}
+
+void Context::shaderBinary(GLsizei n,
+ const ShaderProgramID *shaders,
+ GLenum binaryformat,
+ const void *binary,
+ GLsizei length)
+{
+ // No binary shader formats are supported.
+ UNIMPLEMENTED();
+}
+
+void Context::bindFragDataLocationIndexed(ShaderProgramID program,
+ GLuint colorNumber,
+ GLuint index,
+ const char *name)
+{
+ Program *programObject = getProgramNoResolveLink(program);
+ programObject->bindFragmentOutputLocation(colorNumber, name);
+ programObject->bindFragmentOutputIndex(index, name);
+}
+
+void Context::bindFragDataLocation(ShaderProgramID program, GLuint colorNumber, const char *name)
+{
+ bindFragDataLocationIndexed(program, colorNumber, 0u, name);
+}
+
+int Context::getFragDataIndex(ShaderProgramID program, const char *name)
+{
+ Program *programObject = getProgramResolveLink(program);
+ return programObject->getFragDataIndex(name);
+}
+
+int Context::getProgramResourceLocationIndex(ShaderProgramID program,
+ GLenum programInterface,
+ const char *name)
+{
+ Program *programObject = getProgramResolveLink(program);
+ ASSERT(programInterface == GL_PROGRAM_OUTPUT);
+ return programObject->getFragDataIndex(name);
+}
+
+void Context::shaderSource(ShaderProgramID shader,
+ GLsizei count,
+ const GLchar *const *string,
+ const GLint *length)
+{
+ Shader *shaderObject = getShader(shader);
+ ASSERT(shaderObject);
+ shaderObject->setSource(count, string, length);
+}
+
+void Context::stencilFunc(GLenum func, GLint ref, GLuint mask)
+{
+ stencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
+}
+
+void Context::stencilMask(GLuint mask)
+{
+ stencilMaskSeparate(GL_FRONT_AND_BACK, mask);
+}
+
+void Context::stencilOp(GLenum fail, GLenum zfail, GLenum zpass)
+{
+ stencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
+}
+
+void Context::patchParameteri(GLenum pname, GLint value)
+{
+ switch (pname)
+ {
+ case GL_PATCH_VERTICES:
+ mState.setPatchVertices(value);
+ break;
+ default:
+ break;
+ }
+}
+
+Program *Context::getActiveLinkedProgram() const
+{
+ Program *program = mState.getLinkedProgram(this);
+ if (!program)
+ {
+ ProgramPipeline *programPipelineObject = mState.getProgramPipeline();
+ if (programPipelineObject)
+ {
+ program = programPipelineObject->getLinkedActiveShaderProgram(this);
+ }
+ }
+
+ return program;
+}
+
+void Context::uniform1f(UniformLocation location, GLfloat x)
+{
+ Program *program = getActiveLinkedProgram();
+ program->setUniform1fv(location, 1, &x);
+}
+
+void Context::uniform1fv(UniformLocation location, GLsizei count, const GLfloat *v)
+{
+ Program *program = getActiveLinkedProgram();
+ program->setUniform1fv(location, count, v);
+}
+
+void Context::setUniform1iImpl(Program *program,
+ UniformLocation location,
+ GLsizei count,
+ const GLint *v)
+{
+ program->setUniform1iv(this, location, count, v);
+}
+
+void Context::onSamplerUniformChange(size_t textureUnitIndex)
+{
+ mState.onActiveTextureChange(this, textureUnitIndex);
+ mStateCache.onActiveTextureChange(this);
+}
+
+void Context::uniform1i(UniformLocation location, GLint x)
+{
+ Program *program = getActiveLinkedProgram();
+ setUniform1iImpl(program, location, 1, &x);
+}
+
+void Context::uniform1iv(UniformLocation location, GLsizei count, const GLint *v)
+{
+ Program *program = getActiveLinkedProgram();
+ setUniform1iImpl(program, location, count, v);
+}
+
+void Context::uniform2f(UniformLocation location, GLfloat x, GLfloat y)
+{
+ GLfloat xy[2] = {x, y};
+ Program *program = getActiveLinkedProgram();
+ program->setUniform2fv(location, 1, xy);
+}
+
+void Context::uniform2fv(UniformLocation location, GLsizei count, const GLfloat *v)
+{
+ Program *program = getActiveLinkedProgram();
+ program->setUniform2fv(location, count, v);
+}
+
+void Context::uniform2i(UniformLocation location, GLint x, GLint y)
+{
+ GLint xy[2] = {x, y};
+ Program *program = getActiveLinkedProgram();
+ program->setUniform2iv(location, 1, xy);
+}
+
+void Context::uniform2iv(UniformLocation location, GLsizei count, const GLint *v)
+{
+ Program *program = getActiveLinkedProgram();
+ program->setUniform2iv(location, count, v);
+}
+
+void Context::uniform3f(UniformLocation location, GLfloat x, GLfloat y, GLfloat z)
+{
+ GLfloat xyz[3] = {x, y, z};
+ Program *program = getActiveLinkedProgram();
+ program->setUniform3fv(location, 1, xyz);
+}
+
+void Context::uniform3fv(UniformLocation location, GLsizei count, const GLfloat *v)
+{
+ Program *program = getActiveLinkedProgram();
+ program->setUniform3fv(location, count, v);
+}
+
+void Context::uniform3i(UniformLocation location, GLint x, GLint y, GLint z)
+{
+ GLint xyz[3] = {x, y, z};
+ Program *program = getActiveLinkedProgram();
+ program->setUniform3iv(location, 1, xyz);
+}
+
+void Context::uniform3iv(UniformLocation location, GLsizei count, const GLint *v)
+{
+ Program *program = getActiveLinkedProgram();
+ program->setUniform3iv(location, count, v);
+}
+
+void Context::uniform4f(UniformLocation location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ GLfloat xyzw[4] = {x, y, z, w};
+ Program *program = getActiveLinkedProgram();
+ program->setUniform4fv(location, 1, xyzw);
+}
+
+void Context::uniform4fv(UniformLocation location, GLsizei count, const GLfloat *v)
+{
+ Program *program = getActiveLinkedProgram();
+ program->setUniform4fv(location, count, v);
+}
+
+void Context::uniform4i(UniformLocation location, GLint x, GLint y, GLint z, GLint w)
+{
+ GLint xyzw[4] = {x, y, z, w};
+ Program *program = getActiveLinkedProgram();
+ program->setUniform4iv(location, 1, xyzw);
+}
+
+void Context::uniform4iv(UniformLocation location, GLsizei count, const GLint *v)
+{
+ Program *program = getActiveLinkedProgram();
+ program->setUniform4iv(location, count, v);
+}
+
+void Context::uniformMatrix2fv(UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Program *program = getActiveLinkedProgram();
+ program->setUniformMatrix2fv(location, count, transpose, value);
+}
+
+void Context::uniformMatrix3fv(UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Program *program = getActiveLinkedProgram();
+ program->setUniformMatrix3fv(location, count, transpose, value);
+}
+
+void Context::uniformMatrix4fv(UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Program *program = getActiveLinkedProgram();
+ program->setUniformMatrix4fv(location, count, transpose, value);
+}
+
+void Context::validateProgram(ShaderProgramID program)
+{
+ Program *programObject = getProgramResolveLink(program);
+ ASSERT(programObject);
+ programObject->validate(mState.mCaps);
+}
+
+void Context::validateProgramPipeline(ProgramPipelineID pipeline)
+{
+ // GLES spec 3.2, Section 7.4 "Program Pipeline Objects"
+ // If pipeline is a name that has been generated (without subsequent deletion) by
+ // GenProgramPipelines, but refers to a program pipeline object that has not been
+ // previously bound, the GL first creates a new state vector in the same manner as
+ // when BindProgramPipeline creates a new program pipeline object.
+ //
+ // void BindProgramPipeline( uint pipeline );
+ // pipeline is the program pipeline object name. The resulting program pipeline
+ // object is a new state vector, comprising all the state and with the same initial values
+ // listed in table 21.20.
+ //
+ // If we do not have a pipeline object that's been created with glBindProgramPipeline, we leave
+ // VALIDATE_STATUS at it's default false value without generating a pipeline object.
+ if (!getProgramPipeline(pipeline))
+ {
+ return;
+ }
+
+ ProgramPipeline *programPipeline =
+ mState.mProgramPipelineManager->checkProgramPipelineAllocation(mImplementation.get(),
+ pipeline);
+ ASSERT(programPipeline);
+
+ programPipeline->validate(this);
+}
+
+void Context::getProgramBinary(ShaderProgramID program,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLenum *binaryFormat,
+ void *binary)
+{
+ Program *programObject = getProgramResolveLink(program);
+ ASSERT(programObject != nullptr);
+
+ ANGLE_CONTEXT_TRY(programObject->saveBinary(this, binaryFormat, binary, bufSize, length));
+}
+
+void Context::programBinary(ShaderProgramID program,
+ GLenum binaryFormat,
+ const void *binary,
+ GLsizei length)
+{
+ Program *programObject = getProgramResolveLink(program);
+ ASSERT(programObject != nullptr);
+
+ ANGLE_CONTEXT_TRY(programObject->loadBinary(this, binaryFormat, binary, length));
+ ANGLE_CONTEXT_TRY(onProgramLink(programObject));
+}
+
+void Context::uniform1ui(UniformLocation location, GLuint v0)
+{
+ Program *program = getActiveLinkedProgram();
+ program->setUniform1uiv(location, 1, &v0);
+}
+
+void Context::uniform2ui(UniformLocation location, GLuint v0, GLuint v1)
+{
+ Program *program = getActiveLinkedProgram();
+ const GLuint xy[] = {v0, v1};
+ program->setUniform2uiv(location, 1, xy);
+}
+
+void Context::uniform3ui(UniformLocation location, GLuint v0, GLuint v1, GLuint v2)
+{
+ Program *program = getActiveLinkedProgram();
+ const GLuint xyz[] = {v0, v1, v2};
+ program->setUniform3uiv(location, 1, xyz);
+}
+
+void Context::uniform4ui(UniformLocation location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
+{
+ Program *program = getActiveLinkedProgram();
+ const GLuint xyzw[] = {v0, v1, v2, v3};
+ program->setUniform4uiv(location, 1, xyzw);
+}
+
+void Context::uniform1uiv(UniformLocation location, GLsizei count, const GLuint *value)
+{
+ Program *program = getActiveLinkedProgram();
+ program->setUniform1uiv(location, count, value);
+}
+void Context::uniform2uiv(UniformLocation location, GLsizei count, const GLuint *value)
+{
+ Program *program = getActiveLinkedProgram();
+ program->setUniform2uiv(location, count, value);
+}
+
+void Context::uniform3uiv(UniformLocation location, GLsizei count, const GLuint *value)
+{
+ Program *program = getActiveLinkedProgram();
+ program->setUniform3uiv(location, count, value);
+}
+
+void Context::uniform4uiv(UniformLocation location, GLsizei count, const GLuint *value)
+{
+ Program *program = getActiveLinkedProgram();
+ program->setUniform4uiv(location, count, value);
+}
+
+void Context::genQueries(GLsizei n, QueryID *ids)
+{
+ for (GLsizei i = 0; i < n; i++)
+ {
+ QueryID handle = QueryID{mQueryHandleAllocator.allocate()};
+ mQueryMap.assign(handle, nullptr);
+ ids[i] = handle;
+ }
+}
+
+void Context::deleteQueries(GLsizei n, const QueryID *ids)
+{
+ for (int i = 0; i < n; i++)
+ {
+ QueryID query = ids[i];
+
+ Query *queryObject = nullptr;
+ if (mQueryMap.erase(query, &queryObject))
+ {
+ mQueryHandleAllocator.release(query.value);
+ if (queryObject)
+ {
+ queryObject->release(this);
+ }
+ }
+ }
+}
+
+bool Context::isQueryGenerated(QueryID query) const
+{
+ return mQueryMap.contains(query);
+}
+
+GLboolean Context::isQuery(QueryID id) const
+{
+ return ConvertToGLBoolean(getQuery(id) != nullptr);
+}
+
+void Context::uniformMatrix2x3fv(UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Program *program = getActiveLinkedProgram();
+ program->setUniformMatrix2x3fv(location, count, transpose, value);
+}
+
+void Context::uniformMatrix3x2fv(UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Program *program = getActiveLinkedProgram();
+ program->setUniformMatrix3x2fv(location, count, transpose, value);
+}
+
+void Context::uniformMatrix2x4fv(UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Program *program = getActiveLinkedProgram();
+ program->setUniformMatrix2x4fv(location, count, transpose, value);
+}
+
+void Context::uniformMatrix4x2fv(UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Program *program = getActiveLinkedProgram();
+ program->setUniformMatrix4x2fv(location, count, transpose, value);
+}
+
+void Context::uniformMatrix3x4fv(UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Program *program = getActiveLinkedProgram();
+ program->setUniformMatrix3x4fv(location, count, transpose, value);
+}
+
+void Context::uniformMatrix4x3fv(UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Program *program = getActiveLinkedProgram();
+ program->setUniformMatrix4x3fv(location, count, transpose, value);
+}
+
+void Context::deleteVertexArrays(GLsizei n, const VertexArrayID *arrays)
+{
+ for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
+ {
+ VertexArrayID vertexArray = arrays[arrayIndex];
+
+ if (arrays[arrayIndex].value != 0)
+ {
+ VertexArray *vertexArrayObject = nullptr;
+ if (mVertexArrayMap.erase(vertexArray, &vertexArrayObject))
+ {
+ if (vertexArrayObject != nullptr)
+ {
+ detachVertexArray(vertexArray);
+ vertexArrayObject->onDestroy(this);
+ }
+
+ mVertexArrayHandleAllocator.release(vertexArray.value);
+ }
+ }
+ }
+}
+
+void Context::genVertexArrays(GLsizei n, VertexArrayID *arrays)
+{
+ for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
+ {
+ VertexArrayID vertexArray = {mVertexArrayHandleAllocator.allocate()};
+ mVertexArrayMap.assign(vertexArray, nullptr);
+ arrays[arrayIndex] = vertexArray;
+ }
+}
+
+GLboolean Context::isVertexArray(VertexArrayID array) const
+{
+ if (array.value == 0)
+ {
+ return GL_FALSE;
+ }
+
+ VertexArray *vao = getVertexArray(array);
+ return ConvertToGLBoolean(vao != nullptr);
+}
+
+void Context::endTransformFeedback()
+{
+ TransformFeedback *transformFeedback = mState.getCurrentTransformFeedback();
+ ANGLE_CONTEXT_TRY(transformFeedback->end(this));
+ mStateCache.onActiveTransformFeedbackChange(this);
+}
+
+void Context::transformFeedbackVaryings(ShaderProgramID program,
+ GLsizei count,
+ const GLchar *const *varyings,
+ GLenum bufferMode)
+{
+ Program *programObject = getProgramResolveLink(program);
+ ASSERT(programObject);
+ programObject->setTransformFeedbackVaryings(count, varyings, bufferMode);
+}
+
+void Context::getTransformFeedbackVarying(ShaderProgramID program,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLsizei *size,
+ GLenum *type,
+ GLchar *name)
+{
+ Program *programObject = getProgramResolveLink(program);
+ ASSERT(programObject);
+ programObject->getTransformFeedbackVarying(index, bufSize, length, size, type, name);
+}
+
+void Context::deleteTransformFeedbacks(GLsizei n, const TransformFeedbackID *ids)
+{
+ for (int i = 0; i < n; i++)
+ {
+ TransformFeedbackID transformFeedback = ids[i];
+ if (transformFeedback.value == 0)
+ {
+ continue;
+ }
+
+ TransformFeedback *transformFeedbackObject = nullptr;
+ if (mTransformFeedbackMap.erase(transformFeedback, &transformFeedbackObject))
+ {
+ if (transformFeedbackObject != nullptr)
+ {
+ detachTransformFeedback(transformFeedback);
+ transformFeedbackObject->release(this);
+ }
+
+ mTransformFeedbackHandleAllocator.release(transformFeedback.value);
+ }
+ }
+}
+
+void Context::genTransformFeedbacks(GLsizei n, TransformFeedbackID *ids)
+{
+ for (int i = 0; i < n; i++)
+ {
+ TransformFeedbackID transformFeedback = {mTransformFeedbackHandleAllocator.allocate()};
+ mTransformFeedbackMap.assign(transformFeedback, nullptr);
+ ids[i] = transformFeedback;
+ }
+}
+
+GLboolean Context::isTransformFeedback(TransformFeedbackID id) const
+{
+ if (id.value == 0)
+ {
+ // The 3.0.4 spec [section 6.1.11] states that if ID is zero, IsTransformFeedback
+ // returns FALSE
+ return GL_FALSE;
+ }
+
+ const TransformFeedback *transformFeedback = getTransformFeedback(id);
+ return ConvertToGLBoolean(transformFeedback != nullptr);
+}
+
+void Context::pauseTransformFeedback()
+{
+ TransformFeedback *transformFeedback = mState.getCurrentTransformFeedback();
+ ANGLE_CONTEXT_TRY(transformFeedback->pause(this));
+ mStateCache.onActiveTransformFeedbackChange(this);
+}
+
+void Context::resumeTransformFeedback()
+{
+ TransformFeedback *transformFeedback = mState.getCurrentTransformFeedback();
+ ANGLE_CONTEXT_TRY(transformFeedback->resume(this));
+ mStateCache.onActiveTransformFeedbackChange(this);
+}
+
+void Context::getUniformuiv(ShaderProgramID program, UniformLocation location, GLuint *params)
+{
+ const Program *programObject = getProgramResolveLink(program);
+ programObject->getUniformuiv(this, location, params);
+}
+
+void Context::getUniformuivRobust(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint *params)
+{
+ getUniformuiv(program, location, params);
+}
+
+GLint Context::getFragDataLocation(ShaderProgramID program, const GLchar *name)
+{
+ const Program *programObject = getProgramResolveLink(program);
+ return programObject->getFragDataLocation(name);
+}
+
+void Context::getUniformIndices(ShaderProgramID program,
+ GLsizei uniformCount,
+ const GLchar *const *uniformNames,
+ GLuint *uniformIndices)
+{
+ const Program *programObject = getProgramResolveLink(program);
+ if (!programObject->isLinked())
+ {
+ for (int uniformId = 0; uniformId < uniformCount; uniformId++)
+ {
+ uniformIndices[uniformId] = GL_INVALID_INDEX;
+ }
+ }
+ else
+ {
+ for (int uniformId = 0; uniformId < uniformCount; uniformId++)
+ {
+ uniformIndices[uniformId] = programObject->getUniformIndex(uniformNames[uniformId]);
+ }
+ }
+}
+
+void Context::getActiveUniformsiv(ShaderProgramID program,
+ GLsizei uniformCount,
+ const GLuint *uniformIndices,
+ GLenum pname,
+ GLint *params)
+{
+ const Program *programObject = getProgramResolveLink(program);
+ for (int uniformId = 0; uniformId < uniformCount; uniformId++)
+ {
+ const GLuint index = uniformIndices[uniformId];
+ params[uniformId] = GetUniformResourceProperty(programObject, index, pname);
+ }
+}
+
+GLuint Context::getUniformBlockIndex(ShaderProgramID program, const GLchar *uniformBlockName)
+{
+ const Program *programObject = getProgramResolveLink(program);
+ return programObject->getUniformBlockIndex(uniformBlockName);
+}
+
+void Context::getActiveUniformBlockiv(ShaderProgramID program,
+ UniformBlockIndex uniformBlockIndex,
+ GLenum pname,
+ GLint *params)
+{
+ const Program *programObject = getProgramResolveLink(program);
+ QueryActiveUniformBlockiv(programObject, uniformBlockIndex, pname, params);
+}
+
+void Context::getActiveUniformBlockivRobust(ShaderProgramID program,
+ UniformBlockIndex uniformBlockIndex,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ getActiveUniformBlockiv(program, uniformBlockIndex, pname, params);
+}
+
+void Context::getActiveUniformBlockName(ShaderProgramID program,
+ UniformBlockIndex uniformBlockIndex,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *uniformBlockName)
+{
+ const Program *programObject = getProgramResolveLink(program);
+ programObject->getActiveUniformBlockName(this, uniformBlockIndex, bufSize, length,
+ uniformBlockName);
+}
+
+void Context::uniformBlockBinding(ShaderProgramID program,
+ UniformBlockIndex uniformBlockIndex,
+ GLuint uniformBlockBinding)
+{
+ Program *programObject = getProgramResolveLink(program);
+ programObject->bindUniformBlock(uniformBlockIndex, uniformBlockBinding);
+
+ // Note: If the Program is shared between Contexts we would be better using Observer/Subject.
+ if (programObject->isInUse())
+ {
+ mState.setObjectDirty(GL_PROGRAM);
+ mStateCache.onUniformBufferStateChange(this);
+ }
+}
+
+GLsync Context::fenceSync(GLenum condition, GLbitfield flags)
+{
+ GLuint handle = mState.mSyncManager->createSync(mImplementation.get());
+ GLsync syncHandle = reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
+
+ Sync *syncObject = getSync(syncHandle);
+ if (syncObject->set(this, condition, flags) == angle::Result::Stop)
+ {
+ deleteSync(syncHandle);
+ return nullptr;
+ }
+
+ return syncHandle;
+}
+
+GLboolean Context::isSync(GLsync sync) const
+{
+ return (getSync(sync) != nullptr);
+}
+
+GLenum Context::clientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
+{
+ Sync *syncObject = getSync(sync);
+
+ GLenum result = GL_WAIT_FAILED;
+ if (syncObject->clientWait(this, flags, timeout, &result) == angle::Result::Stop)
+ {
+ return GL_WAIT_FAILED;
+ }
+ return result;
+}
+
+void Context::waitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
+{
+ Sync *syncObject = getSync(sync);
+ ANGLE_CONTEXT_TRY(syncObject->serverWait(this, flags, timeout));
+}
+
+void Context::getInteger64v(GLenum pname, GLint64 *params)
+{
+ GLenum nativeType = GL_NONE;
+ unsigned int numParams = 0;
+ getQueryParameterInfo(pname, &nativeType, &numParams);
+
+ if (nativeType == GL_INT_64_ANGLEX)
+ {
+ getInteger64vImpl(pname, params);
+ }
+ else
+ {
+ CastStateValues(this, nativeType, pname, numParams, params);
+ }
+}
+
+void Context::getInteger64vRobust(GLenum pname, GLsizei bufSize, GLsizei *length, GLint64 *data)
+{
+ getInteger64v(pname, data);
+}
+
+void Context::getBufferParameteri64v(BufferBinding target, GLenum pname, GLint64 *params)
+{
+ Buffer *buffer = mState.getTargetBuffer(target);
+ QueryBufferParameteri64v(buffer, pname, params);
+}
+
+void Context::getBufferParameteri64vRobust(BufferBinding target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint64 *params)
+{
+ getBufferParameteri64v(target, pname, params);
+}
+
+void Context::genSamplers(GLsizei count, SamplerID *samplers)
+{
+ for (int i = 0; i < count; i++)
+ {
+ samplers[i] = mState.mSamplerManager->createSampler();
+ }
+}
+
+void Context::deleteSamplers(GLsizei count, const SamplerID *samplers)
+{
+ for (int i = 0; i < count; i++)
+ {
+ SamplerID sampler = samplers[i];
+
+ if (mState.mSamplerManager->getSampler(sampler))
+ {
+ detachSampler(sampler);
+ }
+
+ mState.mSamplerManager->deleteObject(this, sampler);
+ }
+}
+
+void Context::minSampleShading(GLfloat value)
+{
+ mState.setMinSampleShading(value);
+}
+
+void Context::getInternalformativ(GLenum target,
+ GLenum internalformat,
+ GLenum pname,
+ GLsizei bufSize,
+ GLint *params)
+{
+ const TextureCaps &formatCaps = mState.mTextureCaps.get(internalformat);
+ QueryInternalFormativ(formatCaps, pname, bufSize, params);
+}
+
+void Context::getInternalformativRobust(GLenum target,
+ GLenum internalformat,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ getInternalformativ(target, internalformat, pname, bufSize, params);
+}
+
+void Context::programUniform1i(ShaderProgramID program, UniformLocation location, GLint v0)
+{
+ programUniform1iv(program, location, 1, &v0);
+}
+
+void Context::programUniform2i(ShaderProgramID program,
+ UniformLocation location,
+ GLint v0,
+ GLint v1)
+{
+ GLint xy[2] = {v0, v1};
+ programUniform2iv(program, location, 1, xy);
+}
+
+void Context::programUniform3i(ShaderProgramID program,
+ UniformLocation location,
+ GLint v0,
+ GLint v1,
+ GLint v2)
+{
+ GLint xyz[3] = {v0, v1, v2};
+ programUniform3iv(program, location, 1, xyz);
+}
+
+void Context::programUniform4i(ShaderProgramID program,
+ UniformLocation location,
+ GLint v0,
+ GLint v1,
+ GLint v2,
+ GLint v3)
+{
+ GLint xyzw[4] = {v0, v1, v2, v3};
+ programUniform4iv(program, location, 1, xyzw);
+}
+
+void Context::programUniform1ui(ShaderProgramID program, UniformLocation location, GLuint v0)
+{
+ programUniform1uiv(program, location, 1, &v0);
+}
+
+void Context::programUniform2ui(ShaderProgramID program,
+ UniformLocation location,
+ GLuint v0,
+ GLuint v1)
+{
+ GLuint xy[2] = {v0, v1};
+ programUniform2uiv(program, location, 1, xy);
+}
+
+void Context::programUniform3ui(ShaderProgramID program,
+ UniformLocation location,
+ GLuint v0,
+ GLuint v1,
+ GLuint v2)
+{
+ GLuint xyz[3] = {v0, v1, v2};
+ programUniform3uiv(program, location, 1, xyz);
+}
+
+void Context::programUniform4ui(ShaderProgramID program,
+ UniformLocation location,
+ GLuint v0,
+ GLuint v1,
+ GLuint v2,
+ GLuint v3)
+{
+ GLuint xyzw[4] = {v0, v1, v2, v3};
+ programUniform4uiv(program, location, 1, xyzw);
+}
+
+void Context::programUniform1f(ShaderProgramID program, UniformLocation location, GLfloat v0)
+{
+ programUniform1fv(program, location, 1, &v0);
+}
+
+void Context::programUniform2f(ShaderProgramID program,
+ UniformLocation location,
+ GLfloat v0,
+ GLfloat v1)
+{
+ GLfloat xy[2] = {v0, v1};
+ programUniform2fv(program, location, 1, xy);
+}
+
+void Context::programUniform3f(ShaderProgramID program,
+ UniformLocation location,
+ GLfloat v0,
+ GLfloat v1,
+ GLfloat v2)
+{
+ GLfloat xyz[3] = {v0, v1, v2};
+ programUniform3fv(program, location, 1, xyz);
+}
+
+void Context::programUniform4f(ShaderProgramID program,
+ UniformLocation location,
+ GLfloat v0,
+ GLfloat v1,
+ GLfloat v2,
+ GLfloat v3)
+{
+ GLfloat xyzw[4] = {v0, v1, v2, v3};
+ programUniform4fv(program, location, 1, xyzw);
+}
+
+void Context::programUniform1iv(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ const GLint *value)
+{
+ Program *programObject = getProgramResolveLink(program);
+ ASSERT(programObject);
+ setUniform1iImpl(programObject, location, count, value);
+}
+
+void Context::programUniform2iv(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ const GLint *value)
+{
+ Program *programObject = getProgramResolveLink(program);
+ ASSERT(programObject);
+ programObject->setUniform2iv(location, count, value);
+}
+
+void Context::programUniform3iv(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ const GLint *value)
+{
+ Program *programObject = getProgramResolveLink(program);
+ ASSERT(programObject);
+ programObject->setUniform3iv(location, count, value);
+}
+
+void Context::programUniform4iv(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ const GLint *value)
+{
+ Program *programObject = getProgramResolveLink(program);
+ ASSERT(programObject);
+ programObject->setUniform4iv(location, count, value);
+}
+
+void Context::programUniform1uiv(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ const GLuint *value)
+{
+ Program *programObject = getProgramResolveLink(program);
+ ASSERT(programObject);
+ programObject->setUniform1uiv(location, count, value);
+}
+
+void Context::programUniform2uiv(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ const GLuint *value)
+{
+ Program *programObject = getProgramResolveLink(program);
+ ASSERT(programObject);
+ programObject->setUniform2uiv(location, count, value);
+}
+
+void Context::programUniform3uiv(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ const GLuint *value)
+{
+ Program *programObject = getProgramResolveLink(program);
+ ASSERT(programObject);
+ programObject->setUniform3uiv(location, count, value);
+}
+
+void Context::programUniform4uiv(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ const GLuint *value)
+{
+ Program *programObject = getProgramResolveLink(program);
+ ASSERT(programObject);
+ programObject->setUniform4uiv(location, count, value);
+}
+
+void Context::programUniform1fv(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ const GLfloat *value)
+{
+ Program *programObject = getProgramResolveLink(program);
+ ASSERT(programObject);
+ programObject->setUniform1fv(location, count, value);
+}
+
+void Context::programUniform2fv(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ const GLfloat *value)
+{
+ Program *programObject = getProgramResolveLink(program);
+ ASSERT(programObject);
+ programObject->setUniform2fv(location, count, value);
+}
+
+void Context::programUniform3fv(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ const GLfloat *value)
+{
+ Program *programObject = getProgramResolveLink(program);
+ ASSERT(programObject);
+ programObject->setUniform3fv(location, count, value);
+}
+
+void Context::programUniform4fv(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ const GLfloat *value)
+{
+ Program *programObject = getProgramResolveLink(program);
+ ASSERT(programObject);
+ programObject->setUniform4fv(location, count, value);
+}
+
+void Context::programUniformMatrix2fv(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Program *programObject = getProgramResolveLink(program);
+ ASSERT(programObject);
+ programObject->setUniformMatrix2fv(location, count, transpose, value);
+}
+
+void Context::programUniformMatrix3fv(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Program *programObject = getProgramResolveLink(program);
+ ASSERT(programObject);
+ programObject->setUniformMatrix3fv(location, count, transpose, value);
+}
+
+void Context::programUniformMatrix4fv(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Program *programObject = getProgramResolveLink(program);
+ ASSERT(programObject);
+ programObject->setUniformMatrix4fv(location, count, transpose, value);
+}
+
+void Context::programUniformMatrix2x3fv(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Program *programObject = getProgramResolveLink(program);
+ ASSERT(programObject);
+ programObject->setUniformMatrix2x3fv(location, count, transpose, value);
+}
+
+void Context::programUniformMatrix3x2fv(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Program *programObject = getProgramResolveLink(program);
+ ASSERT(programObject);
+ programObject->setUniformMatrix3x2fv(location, count, transpose, value);
+}
+
+void Context::programUniformMatrix2x4fv(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Program *programObject = getProgramResolveLink(program);
+ ASSERT(programObject);
+ programObject->setUniformMatrix2x4fv(location, count, transpose, value);
+}
+
+void Context::programUniformMatrix4x2fv(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Program *programObject = getProgramResolveLink(program);
+ ASSERT(programObject);
+ programObject->setUniformMatrix4x2fv(location, count, transpose, value);
+}
+
+void Context::programUniformMatrix3x4fv(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Program *programObject = getProgramResolveLink(program);
+ ASSERT(programObject);
+ programObject->setUniformMatrix3x4fv(location, count, transpose, value);
+}
+
+void Context::programUniformMatrix4x3fv(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Program *programObject = getProgramResolveLink(program);
+ ASSERT(programObject);
+ programObject->setUniformMatrix4x3fv(location, count, transpose, value);
+}
+
+bool Context::isCurrentTransformFeedback(const TransformFeedback *tf) const
+{
+ return mState.isCurrentTransformFeedback(tf);
+}
+
+void Context::genProgramPipelines(GLsizei count, ProgramPipelineID *pipelines)
+{
+ for (int i = 0; i < count; i++)
+ {
+ pipelines[i] = createProgramPipeline();
+ }
+}
+
+void Context::deleteProgramPipelines(GLsizei count, const ProgramPipelineID *pipelines)
+{
+ for (int i = 0; i < count; i++)
+ {
+ if (pipelines[i].value != 0)
+ {
+ deleteProgramPipeline(pipelines[i]);
+ }
+ }
+}
+
+GLboolean Context::isProgramPipeline(ProgramPipelineID pipeline) const
+{
+ if (pipeline.value == 0)
+ {
+ return GL_FALSE;
+ }
+
+ if (getProgramPipeline(pipeline))
+ {
+ return GL_TRUE;
+ }
+
+ return GL_FALSE;
+}
+
+void Context::finishFenceNV(FenceNVID fence)
+{
+ FenceNV *fenceObject = getFenceNV(fence);
+
+ ASSERT(fenceObject && fenceObject->isSet());
+ ANGLE_CONTEXT_TRY(fenceObject->finish(this));
+}
+
+void Context::getFenceivNV(FenceNVID fence, GLenum pname, GLint *params)
+{
+ FenceNV *fenceObject = getFenceNV(fence);
+
+ ASSERT(fenceObject && fenceObject->isSet());
+
+ switch (pname)
+ {
+ case GL_FENCE_STATUS_NV:
+ {
+ // GL_NV_fence spec:
+ // Once the status of a fence has been finished (via FinishFenceNV) or tested and
+ // the returned status is TRUE (via either TestFenceNV or GetFenceivNV querying the
+ // FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence.
+ GLboolean status = GL_TRUE;
+ if (fenceObject->getStatus() != GL_TRUE)
+ {
+ ANGLE_CONTEXT_TRY(fenceObject->test(this, &status));
+ }
+ *params = status;
+ break;
+ }
+
+ case GL_FENCE_CONDITION_NV:
+ {
+ *params = static_cast<GLint>(fenceObject->getCondition());
+ break;
+ }
+
+ default:
+ UNREACHABLE();
+ }
+}
+
+void Context::getTranslatedShaderSource(ShaderProgramID shader,
+ GLsizei bufsize,
+ GLsizei *length,
+ GLchar *source)
+{
+ Shader *shaderObject = getShader(shader);
+ ASSERT(shaderObject);
+ shaderObject->getTranslatedSourceWithDebugInfo(this, bufsize, length, source);
+}
+
+void Context::getnUniformfv(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei bufSize,
+ GLfloat *params)
+{
+ Program *programObject = getProgramResolveLink(program);
+ ASSERT(programObject);
+
+ programObject->getUniformfv(this, location, params);
+}
+
+void Context::getnUniformfvRobust(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getnUniformiv(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei bufSize,
+ GLint *params)
+{
+ Program *programObject = getProgramResolveLink(program);
+ ASSERT(programObject);
+
+ programObject->getUniformiv(this, location, params);
+}
+
+void Context::getnUniformuiv(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei bufSize,
+ GLuint *params)
+{
+ Program *programObject = getProgramResolveLink(program);
+ ASSERT(programObject);
+
+ programObject->getUniformuiv(this, location, params);
+}
+
+void Context::getnUniformivRobust(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getnUniformuivRobust(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint *params)
+{
+ UNIMPLEMENTED();
+}
+
+GLboolean Context::isFenceNV(FenceNVID fence) const
+{
+ FenceNV *fenceObject = getFenceNV(fence);
+
+ if (fenceObject == nullptr)
+ {
+ return GL_FALSE;
+ }
+
+ // GL_NV_fence spec:
+ // A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an
+ // existing fence.
+ return fenceObject->isSet();
+}
+
+void Context::readnPixels(GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ void *data)
+{
+ return readPixels(x, y, width, height, format, type, data);
+}
+
+void Context::setFenceNV(FenceNVID fence, GLenum condition)
+{
+ ASSERT(condition == GL_ALL_COMPLETED_NV);
+
+ FenceNV *fenceObject = getFenceNV(fence);
+ ASSERT(fenceObject != nullptr);
+ ANGLE_CONTEXT_TRY(fenceObject->set(this, condition));
+}
+
+GLboolean Context::testFenceNV(FenceNVID fence)
+{
+ FenceNV *fenceObject = getFenceNV(fence);
+
+ ASSERT(fenceObject != nullptr);
+ ASSERT(fenceObject->isSet() == GL_TRUE);
+
+ GLboolean result = GL_TRUE;
+ if (fenceObject->test(this, &result) == angle::Result::Stop)
+ {
+ return GL_TRUE;
+ }
+
+ return result;
+}
+
+void Context::deleteMemoryObjects(GLsizei n, const MemoryObjectID *memoryObjects)
+{
+ for (int i = 0; i < n; i++)
+ {
+ deleteMemoryObject(memoryObjects[i]);
+ }
+}
+
+GLboolean Context::isMemoryObject(MemoryObjectID memoryObject) const
+{
+ if (memoryObject.value == 0)
+ {
+ return GL_FALSE;
+ }
+
+ return ConvertToGLBoolean(getMemoryObject(memoryObject));
+}
+
+void Context::createMemoryObjects(GLsizei n, MemoryObjectID *memoryObjects)
+{
+ for (int i = 0; i < n; i++)
+ {
+ memoryObjects[i] = createMemoryObject();
+ }
+}
+
+void Context::memoryObjectParameteriv(MemoryObjectID memory, GLenum pname, const GLint *params)
+{
+ MemoryObject *memoryObject = getMemoryObject(memory);
+ ASSERT(memoryObject);
+ ANGLE_CONTEXT_TRY(SetMemoryObjectParameteriv(this, memoryObject, pname, params));
+}
+
+void Context::getMemoryObjectParameteriv(MemoryObjectID memory, GLenum pname, GLint *params)
+{
+ const MemoryObject *memoryObject = getMemoryObject(memory);
+ ASSERT(memoryObject);
+ QueryMemoryObjectParameteriv(memoryObject, pname, params);
+}
+
+void Context::texStorageMem2D(TextureType target,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ MemoryObjectID memory,
+ GLuint64 offset)
+{
+ texStorageMemFlags2D(target, levels, internalFormat, width, height, memory, offset, 0,
+ std::numeric_limits<uint32_t>::max(), nullptr);
+}
+
+void Context::texStorageMem2DMultisample(TextureType target,
+ GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedSampleLocations,
+ MemoryObjectID memory,
+ GLuint64 offset)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texStorageMem3D(TextureType target,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ MemoryObjectID memory,
+ GLuint64 offset)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texStorageMem3DMultisample(TextureType target,
+ GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean fixedSampleLocations,
+ MemoryObjectID memory,
+ GLuint64 offset)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::bufferStorageMem(TextureType target,
+ GLsizeiptr size,
+ MemoryObjectID memory,
+ GLuint64 offset)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::importMemoryFd(MemoryObjectID memory, GLuint64 size, HandleType handleType, GLint fd)
+{
+ MemoryObject *memoryObject = getMemoryObject(memory);
+ ASSERT(memoryObject != nullptr);
+ ANGLE_CONTEXT_TRY(memoryObject->importFd(this, size, handleType, fd));
+}
+
+void Context::texStorageMemFlags2D(TextureType target,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ MemoryObjectID memory,
+ GLuint64 offset,
+ GLbitfield createFlags,
+ GLbitfield usageFlags,
+ const void *imageCreateInfoPNext)
+{
+ MemoryObject *memoryObject = getMemoryObject(memory);
+ ASSERT(memoryObject);
+ Extents size(width, height, 1);
+ Texture *texture = getTextureByType(target);
+ ANGLE_CONTEXT_TRY(texture->setStorageExternalMemory(this, target, levels, internalFormat, size,
+ memoryObject, offset, createFlags,
+ usageFlags, imageCreateInfoPNext));
+}
+
+void Context::texStorageMemFlags2DMultisample(TextureType target,
+ GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedSampleLocations,
+ MemoryObjectID memory,
+ GLuint64 offset,
+ GLbitfield createFlags,
+ GLbitfield usageFlags,
+ const void *imageCreateInfoPNext)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texStorageMemFlags3D(TextureType target,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ MemoryObjectID memory,
+ GLuint64 offset,
+ GLbitfield createFlags,
+ GLbitfield usageFlags,
+ const void *imageCreateInfoPNext)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texStorageMemFlags3DMultisample(TextureType target,
+ GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean fixedSampleLocations,
+ MemoryObjectID memory,
+ GLuint64 offset,
+ GLbitfield createFlags,
+ GLbitfield usageFlags,
+ const void *imageCreateInfoPNext)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::importMemoryZirconHandle(MemoryObjectID memory,
+ GLuint64 size,
+ HandleType handleType,
+ GLuint handle)
+{
+ MemoryObject *memoryObject = getMemoryObject(memory);
+ ASSERT(memoryObject != nullptr);
+ ANGLE_CONTEXT_TRY(memoryObject->importZirconHandle(this, size, handleType, handle));
+}
+
+void Context::genSemaphores(GLsizei n, SemaphoreID *semaphores)
+{
+ for (int i = 0; i < n; i++)
+ {
+ semaphores[i] = createSemaphore();
+ }
+}
+
+void Context::deleteSemaphores(GLsizei n, const SemaphoreID *semaphores)
+{
+ for (int i = 0; i < n; i++)
+ {
+ deleteSemaphore(semaphores[i]);
+ }
+}
+
+GLboolean Context::isSemaphore(SemaphoreID semaphore) const
+{
+ if (semaphore.value == 0)
+ {
+ return GL_FALSE;
+ }
+
+ return ConvertToGLBoolean(getSemaphore(semaphore));
+}
+
+void Context::semaphoreParameterui64v(SemaphoreID semaphore, GLenum pname, const GLuint64 *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getSemaphoreParameterui64v(SemaphoreID semaphore, GLenum pname, GLuint64 *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::acquireTextures(GLuint numTextures,
+ const TextureID *textureIds,
+ const GLenum *layouts)
+{
+ TextureBarrierVector textureBarriers(numTextures);
+ for (size_t i = 0; i < numTextures; i++)
+ {
+ textureBarriers[i].texture = getTexture(textureIds[i]);
+ textureBarriers[i].layout = layouts[i];
+ }
+ ANGLE_CONTEXT_TRY(mImplementation->acquireTextures(this, textureBarriers));
+}
+
+void Context::releaseTextures(GLuint numTextures, const TextureID *textureIds, GLenum *layouts)
+{
+ TextureBarrierVector textureBarriers(numTextures);
+ for (size_t i = 0; i < numTextures; i++)
+ {
+ textureBarriers[i].texture = getTexture(textureIds[i]);
+ }
+ ANGLE_CONTEXT_TRY(mImplementation->releaseTextures(this, &textureBarriers));
+ for (size_t i = 0; i < numTextures; i++)
+ {
+ layouts[i] = textureBarriers[i].layout;
+ }
+}
+
+void Context::waitSemaphore(SemaphoreID semaphoreHandle,
+ GLuint numBufferBarriers,
+ const BufferID *buffers,
+ GLuint numTextureBarriers,
+ const TextureID *textures,
+ const GLenum *srcLayouts)
+{
+ Semaphore *semaphore = getSemaphore(semaphoreHandle);
+ ASSERT(semaphore);
+
+ BufferBarrierVector bufferBarriers(numBufferBarriers);
+ for (GLuint bufferBarrierIdx = 0; bufferBarrierIdx < numBufferBarriers; bufferBarrierIdx++)
+ {
+ bufferBarriers[bufferBarrierIdx] = getBuffer(buffers[bufferBarrierIdx]);
+ }
+
+ TextureBarrierVector textureBarriers(numTextureBarriers);
+ for (GLuint textureBarrierIdx = 0; textureBarrierIdx < numTextureBarriers; textureBarrierIdx++)
+ {
+ textureBarriers[textureBarrierIdx].texture = getTexture(textures[textureBarrierIdx]);
+ textureBarriers[textureBarrierIdx].layout = srcLayouts[textureBarrierIdx];
+ }
+
+ ANGLE_CONTEXT_TRY(semaphore->wait(this, bufferBarriers, textureBarriers));
+}
+
+void Context::signalSemaphore(SemaphoreID semaphoreHandle,
+ GLuint numBufferBarriers,
+ const BufferID *buffers,
+ GLuint numTextureBarriers,
+ const TextureID *textures,
+ const GLenum *dstLayouts)
+{
+ Semaphore *semaphore = getSemaphore(semaphoreHandle);
+ ASSERT(semaphore);
+
+ BufferBarrierVector bufferBarriers(numBufferBarriers);
+ for (GLuint bufferBarrierIdx = 0; bufferBarrierIdx < numBufferBarriers; bufferBarrierIdx++)
+ {
+ bufferBarriers[bufferBarrierIdx] = getBuffer(buffers[bufferBarrierIdx]);
+ }
+
+ TextureBarrierVector textureBarriers(numTextureBarriers);
+ for (GLuint textureBarrierIdx = 0; textureBarrierIdx < numTextureBarriers; textureBarrierIdx++)
+ {
+ textureBarriers[textureBarrierIdx].texture = getTexture(textures[textureBarrierIdx]);
+ textureBarriers[textureBarrierIdx].layout = dstLayouts[textureBarrierIdx];
+ }
+
+ ANGLE_CONTEXT_TRY(semaphore->signal(this, bufferBarriers, textureBarriers));
+}
+
+void Context::importSemaphoreFd(SemaphoreID semaphore, HandleType handleType, GLint fd)
+{
+ Semaphore *semaphoreObject = getSemaphore(semaphore);
+ ASSERT(semaphoreObject != nullptr);
+ ANGLE_CONTEXT_TRY(semaphoreObject->importFd(this, handleType, fd));
+}
+
+void Context::importSemaphoreZirconHandle(SemaphoreID semaphore,
+ HandleType handleType,
+ GLuint handle)
+{
+ Semaphore *semaphoreObject = getSemaphore(semaphore);
+ ASSERT(semaphoreObject != nullptr);
+ ANGLE_CONTEXT_TRY(semaphoreObject->importZirconHandle(this, handleType, handle));
+}
+
+void Context::framebufferMemorylessPixelLocalStorage(GLint plane, GLenum internalformat)
+{
+ Framebuffer *framebuffer = mState.getDrawFramebuffer();
+ ASSERT(framebuffer);
+ PixelLocalStorage &pls = framebuffer->getPixelLocalStorage(this);
+
+ if (internalformat == GL_NONE)
+ {
+ pls.deinitialize(this, plane);
+ }
+ else
+ {
+ pls.setMemoryless(this, plane, internalformat);
+ }
+}
+
+void Context::framebufferTexturePixelLocalStorage(GLint plane,
+ TextureID backingtexture,
+ GLint level,
+ GLint layer)
+{
+ Framebuffer *framebuffer = mState.getDrawFramebuffer();
+ ASSERT(framebuffer);
+ PixelLocalStorage &pls = framebuffer->getPixelLocalStorage(this);
+
+ if (backingtexture.value == 0)
+ {
+ pls.deinitialize(this, plane);
+ }
+ else
+ {
+ Texture *tex = getTexture(backingtexture);
+ ASSERT(tex); // Validation guarantees this.
+ pls.setTextureBacked(this, plane, tex, level, layer);
+ }
+}
+
+void Context::beginPixelLocalStorage(GLsizei planes, const GLenum loadops[], const void *cleardata)
+{
+ Framebuffer *framebuffer = mState.getDrawFramebuffer();
+ ASSERT(framebuffer);
+ PixelLocalStorage &pls = framebuffer->getPixelLocalStorage(this);
+
+ pls.begin(this, planes, loadops, cleardata);
+ mState.setPixelLocalStorageActive(true);
+}
+
+void Context::endPixelLocalStorage()
+{
+ Framebuffer *framebuffer = mState.getDrawFramebuffer();
+ ASSERT(framebuffer);
+ PixelLocalStorage &pls = framebuffer->getPixelLocalStorage(this);
+
+ pls.end(this);
+ mState.setPixelLocalStorageActive(false);
+}
+
+void Context::pixelLocalStorageBarrier()
+{
+ if (getExtensions().shaderPixelLocalStorageCoherentANGLE)
+ {
+ return;
+ }
+
+ Framebuffer *framebuffer = mState.getDrawFramebuffer();
+ ASSERT(framebuffer);
+ PixelLocalStorage &pls = framebuffer->getPixelLocalStorage(this);
+
+ pls.barrier(this);
+}
+
+void Context::eGLImageTargetTexStorage(GLenum target, GLeglImageOES image, const GLint *attrib_list)
+{
+ Texture *texture = getTextureByType(FromGLenum<TextureType>(target));
+ egl::Image *imageObject = static_cast<egl::Image *>(image);
+ ANGLE_CONTEXT_TRY(texture->setStorageEGLImageTarget(this, FromGLenum<TextureType>(target),
+ imageObject, attrib_list));
+}
+
+void Context::eGLImageTargetTextureStorage(GLuint texture,
+ GLeglImageOES image,
+ const GLint *attrib_list)
+{
+ return;
+}
+
+void Context::eGLImageTargetTexture2D(TextureType target, GLeglImageOES image)
+{
+ Texture *texture = getTextureByType(target);
+ egl::Image *imageObject = static_cast<egl::Image *>(image);
+ ANGLE_CONTEXT_TRY(texture->setEGLImageTarget(this, target, imageObject));
+}
+
+void Context::eGLImageTargetRenderbufferStorage(GLenum target, GLeglImageOES image)
+{
+ Renderbuffer *renderbuffer = mState.getCurrentRenderbuffer();
+ egl::Image *imageObject = static_cast<egl::Image *>(image);
+ ANGLE_CONTEXT_TRY(renderbuffer->setStorageEGLImageTarget(this, imageObject));
+}
+
+void Context::framebufferFetchBarrier()
+{
+ mImplementation->framebufferFetchBarrier();
+}
+
+void Context::texStorage1D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width)
+{
+ UNIMPLEMENTED();
+}
+
+bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams) const
+{
+ return GetQueryParameterInfo(mState, pname, type, numParams);
+}
+
+bool Context::getIndexedQueryParameterInfo(GLenum target,
+ GLenum *type,
+ unsigned int *numParams) const
+{
+ if (getClientVersion() < Version(3, 0))
+ {
+ return false;
+ }
+
+ switch (target)
+ {
+ case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
+ case GL_UNIFORM_BUFFER_BINDING:
+ {
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ }
+ case GL_TRANSFORM_FEEDBACK_BUFFER_START:
+ case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
+ case GL_UNIFORM_BUFFER_START:
+ case GL_UNIFORM_BUFFER_SIZE:
+ {
+ *type = GL_INT_64_ANGLEX;
+ *numParams = 1;
+ return true;
+ }
+ }
+
+ if (mSupportedExtensions.drawBuffersIndexedAny())
+ {
+ switch (target)
+ {
+ case GL_BLEND_SRC_RGB:
+ case GL_BLEND_SRC_ALPHA:
+ case GL_BLEND_DST_RGB:
+ case GL_BLEND_DST_ALPHA:
+ case GL_BLEND_EQUATION_RGB:
+ case GL_BLEND_EQUATION_ALPHA:
+ {
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ }
+ case GL_COLOR_WRITEMASK:
+ {
+ *type = GL_BOOL;
+ *numParams = 4;
+ return true;
+ }
+ }
+ }
+
+ if (mSupportedExtensions.shaderPixelLocalStorageANGLE)
+ {
+ switch (target)
+ {
+ case GL_PIXEL_LOCAL_FORMAT_ANGLE:
+ case GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE:
+ case GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE:
+ case GL_PIXEL_LOCAL_TEXTURE_LAYER_ANGLE:
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ }
+ }
+
+ if (getClientVersion() < Version(3, 1))
+ {
+ return false;
+ }
+
+ switch (target)
+ {
+ case GL_IMAGE_BINDING_LAYERED:
+ {
+ *type = GL_BOOL;
+ *numParams = 1;
+ return true;
+ }
+ case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
+ case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
+ case GL_ATOMIC_COUNTER_BUFFER_BINDING:
+ case GL_SHADER_STORAGE_BUFFER_BINDING:
+ case GL_VERTEX_BINDING_BUFFER:
+ case GL_VERTEX_BINDING_DIVISOR:
+ case GL_VERTEX_BINDING_OFFSET:
+ case GL_VERTEX_BINDING_STRIDE:
+ case GL_SAMPLE_MASK_VALUE:
+ case GL_IMAGE_BINDING_NAME:
+ case GL_IMAGE_BINDING_LEVEL:
+ case GL_IMAGE_BINDING_LAYER:
+ case GL_IMAGE_BINDING_ACCESS:
+ case GL_IMAGE_BINDING_FORMAT:
+ {
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ }
+ case GL_ATOMIC_COUNTER_BUFFER_START:
+ case GL_ATOMIC_COUNTER_BUFFER_SIZE:
+ case GL_SHADER_STORAGE_BUFFER_START:
+ case GL_SHADER_STORAGE_BUFFER_SIZE:
+ {
+ *type = GL_INT_64_ANGLEX;
+ *numParams = 1;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+Program *Context::getProgramNoResolveLink(ShaderProgramID handle) const
+{
+ return mState.mShaderProgramManager->getProgram(handle);
+}
+
+Shader *Context::getShader(ShaderProgramID handle) const
+{
+ return mState.mShaderProgramManager->getShader(handle);
+}
+
+const angle::FrontendFeatures &Context::getFrontendFeatures() const
+{
+ return mDisplay->getFrontendFeatures();
+}
+
+bool Context::isRenderbufferGenerated(RenderbufferID renderbuffer) const
+{
+ return mState.mRenderbufferManager->isHandleGenerated(renderbuffer);
+}
+
+bool Context::isFramebufferGenerated(FramebufferID framebuffer) const
+{
+ return mState.mFramebufferManager->isHandleGenerated(framebuffer);
+}
+
+bool Context::isProgramPipelineGenerated(ProgramPipelineID pipeline) const
+{
+ return mState.mProgramPipelineManager->isHandleGenerated(pipeline);
+}
+
+bool Context::usingDisplayTextureShareGroup() const
+{
+ return mDisplayTextureShareGroup;
+}
+
+bool Context::usingDisplaySemaphoreShareGroup() const
+{
+ return mDisplaySemaphoreShareGroup;
+}
+
+GLenum Context::getConvertedRenderbufferFormat(GLenum internalformat) const
+{
+ if (isWebGL() && mState.mClientVersion.major == 2 && internalformat == GL_DEPTH_STENCIL)
+ {
+ return GL_DEPTH24_STENCIL8;
+ }
+ if (getClientType() == EGL_OPENGL_API && internalformat == GL_DEPTH_COMPONENT)
+ {
+ return GL_DEPTH_COMPONENT24;
+ }
+ return internalformat;
+}
+
+void Context::maxShaderCompilerThreads(GLuint count)
+{
+ GLuint oldCount = mState.getMaxShaderCompilerThreads();
+ mState.setMaxShaderCompilerThreads(count);
+ // A count of zero specifies a request for no parallel compiling or linking.
+ if ((oldCount == 0 || count == 0) && (oldCount != 0 || count != 0))
+ {
+ mMultiThreadPool = angle::WorkerThreadPool::Create(count > 0);
+ }
+ mMultiThreadPool->setMaxThreads(count);
+ mImplementation->setMaxShaderCompilerThreads(count);
+}
+
+void Context::framebufferParameteriMESA(GLenum target, GLenum pname, GLint param)
+{
+ framebufferParameteri(target, pname, param);
+}
+
+void Context::getFramebufferParameterivMESA(GLenum target, GLenum pname, GLint *params)
+{
+ getFramebufferParameteriv(target, pname, params);
+}
+
+bool Context::isGLES1() const
+{
+ return mState.isGLES1();
+}
+
+void Context::onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message)
+{
+ switch (index)
+ {
+ case kVertexArraySubjectIndex:
+ switch (message)
+ {
+ case angle::SubjectMessage::ContentsChanged:
+ mState.setObjectDirty(GL_VERTEX_ARRAY);
+ mStateCache.onVertexArrayBufferContentsChange(this);
+ break;
+ case angle::SubjectMessage::SubjectMapped:
+ case angle::SubjectMessage::SubjectUnmapped:
+ case angle::SubjectMessage::BindingChanged:
+ mStateCache.onVertexArrayBufferStateChange(this);
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case kReadFramebufferSubjectIndex:
+ switch (message)
+ {
+ case angle::SubjectMessage::DirtyBitsFlagged:
+ mState.setReadFramebufferDirty();
+ break;
+ case angle::SubjectMessage::SurfaceChanged:
+ mState.setReadFramebufferBindingDirty();
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ break;
+
+ case kDrawFramebufferSubjectIndex:
+ switch (message)
+ {
+ case angle::SubjectMessage::DirtyBitsFlagged:
+ mState.setDrawFramebufferDirty();
+ mStateCache.onDrawFramebufferChange(this);
+ break;
+ case angle::SubjectMessage::SurfaceChanged:
+ mState.setDrawFramebufferBindingDirty();
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ break;
+
+ case kProgramPipelineSubjectIndex:
+ switch (message)
+ {
+ case angle::SubjectMessage::SubjectChanged:
+ ANGLE_CONTEXT_TRY(mState.onProgramPipelineExecutableChange(this));
+ mStateCache.onProgramExecutableChange(this);
+ break;
+ case angle::SubjectMessage::ProgramRelinked:
+ ANGLE_CONTEXT_TRY(mState.mProgramPipeline->link(this));
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ break;
+
+ default:
+ if (index < kTextureMaxSubjectIndex)
+ {
+ if (message != angle::SubjectMessage::ContentsChanged &&
+ message != angle::SubjectMessage::BindingChanged)
+ {
+ mState.onActiveTextureStateChange(this, index);
+ mStateCache.onActiveTextureChange(this);
+ }
+ }
+ else if (index < kImageMaxSubjectIndex)
+ {
+ mState.onImageStateChange(this, index - kImage0SubjectIndex);
+ if (message == angle::SubjectMessage::ContentsChanged)
+ {
+ mState.mDirtyBits.set(State::DirtyBitType::DIRTY_BIT_IMAGE_BINDINGS);
+ }
+ }
+ else if (index < kUniformBufferMaxSubjectIndex)
+ {
+ mState.onUniformBufferStateChange(index - kUniformBuffer0SubjectIndex);
+ mStateCache.onUniformBufferStateChange(this);
+ }
+ else if (index < kAtomicCounterBufferMaxSubjectIndex)
+ {
+ mState.onAtomicCounterBufferStateChange(index - kAtomicCounterBuffer0SubjectIndex);
+ mStateCache.onAtomicCounterBufferStateChange(this);
+ }
+ else if (index < kShaderStorageBufferMaxSubjectIndex)
+ {
+ mState.onShaderStorageBufferStateChange(index - kShaderStorageBuffer0SubjectIndex);
+ mStateCache.onShaderStorageBufferStateChange(this);
+ }
+ else
+ {
+ ASSERT(index < kSamplerMaxSubjectIndex);
+ mState.setSamplerDirty(index - kSampler0SubjectIndex);
+ mState.onActiveTextureStateChange(this, index - kSampler0SubjectIndex);
+ }
+ break;
+ }
+}
+
+angle::Result Context::onProgramLink(Program *programObject)
+{
+ // Don't parallel link a program which is active in any GL contexts. With this assumption, we
+ // don't need to worry that:
+ // 1. Draw calls after link use the new executable code or the old one depending on the link
+ // result.
+ // 2. When a backend program, e.g., ProgramD3D is linking, other backend classes like
+ // StateManager11, Renderer11, etc., may have a chance to make unexpected calls to
+ // ProgramD3D.
+ if (programObject->isInUse())
+ {
+ programObject->resolveLink(this);
+ if (programObject->isLinked())
+ {
+ ANGLE_TRY(mState.onProgramExecutableChange(this, programObject));
+ programObject->onStateChange(angle::SubjectMessage::ProgramRelinked);
+ }
+ mStateCache.onProgramExecutableChange(this);
+ }
+
+ return angle::Result::Continue;
+}
+
+egl::Error Context::setDefaultFramebuffer(egl::Surface *drawSurface, egl::Surface *readSurface)
+{
+ ASSERT(mCurrentDrawSurface == nullptr);
+ ASSERT(mCurrentReadSurface == nullptr);
+
+ mCurrentDrawSurface = drawSurface;
+ mCurrentReadSurface = readSurface;
+
+ if (drawSurface != nullptr)
+ {
+ ANGLE_TRY(drawSurface->makeCurrent(this));
+ }
+
+ ANGLE_TRY(mDefaultFramebuffer->setSurfaces(this, drawSurface, readSurface));
+
+ if (readSurface && (drawSurface != readSurface))
+ {
+ ANGLE_TRY(readSurface->makeCurrent(this));
+ }
+
+ // Update default framebuffer, the binding of the previous default
+ // framebuffer (or lack of) will have a nullptr.
+ mState.mFramebufferManager->setDefaultFramebuffer(mDefaultFramebuffer.get());
+ if (mState.getDrawFramebuffer() == nullptr)
+ {
+ bindDrawFramebuffer(mDefaultFramebuffer->id());
+ }
+ if (mState.getReadFramebuffer() == nullptr)
+ {
+ bindReadFramebuffer(mDefaultFramebuffer->id());
+ }
+
+ return egl::NoError();
+}
+
+egl::Error Context::unsetDefaultFramebuffer()
+{
+ Framebuffer *defaultFramebuffer =
+ mState.mFramebufferManager->getFramebuffer(Framebuffer::kDefaultDrawFramebufferHandle);
+
+ if (defaultFramebuffer)
+ {
+ // Remove the default framebuffer
+ if (defaultFramebuffer == mState.getReadFramebuffer())
+ {
+ mState.setReadFramebufferBinding(nullptr);
+ mReadFramebufferObserverBinding.bind(nullptr);
+ }
+
+ if (defaultFramebuffer == mState.getDrawFramebuffer())
+ {
+ mState.setDrawFramebufferBinding(nullptr);
+ mDrawFramebufferObserverBinding.bind(nullptr);
+ }
+
+ ANGLE_TRY(defaultFramebuffer->unsetSurfaces(this));
+ mState.mFramebufferManager->setDefaultFramebuffer(nullptr);
+ }
+
+ // Always unset the current surface, even if setIsCurrent fails.
+ egl::Surface *drawSurface = mCurrentDrawSurface;
+ egl::Surface *readSurface = mCurrentReadSurface;
+ mCurrentDrawSurface = nullptr;
+ mCurrentReadSurface = nullptr;
+ if (drawSurface)
+ {
+ ANGLE_TRY(drawSurface->unMakeCurrent(this));
+ }
+ if (drawSurface != readSurface)
+ {
+ ANGLE_TRY(readSurface->unMakeCurrent(this));
+ }
+
+ return egl::NoError();
+}
+
+void Context::onPreSwap() const
+{
+ // Dump frame capture if enabled.
+ getShareGroup()->getFrameCaptureShared()->onEndFrame(this);
+}
+
+void Context::getTexImage(TextureTarget target,
+ GLint level,
+ GLenum format,
+ GLenum type,
+ void *pixels)
+{
+ Texture *texture = getTextureByTarget(target);
+ Buffer *packBuffer = mState.getTargetBuffer(BufferBinding::PixelPack);
+ ANGLE_CONTEXT_TRY(texture->getTexImage(this, mState.getPackState(), packBuffer, target, level,
+ format, type, pixels));
+}
+
+void Context::getCompressedTexImage(TextureTarget target, GLint level, void *pixels)
+{
+ Texture *texture = getTextureByTarget(target);
+ Buffer *packBuffer = mState.getTargetBuffer(BufferBinding::PixelPack);
+ ANGLE_CONTEXT_TRY(texture->getCompressedTexImage(this, mState.getPackState(), packBuffer,
+ target, level, pixels));
+}
+
+void Context::getRenderbufferImage(GLenum target, GLenum format, GLenum type, void *pixels)
+{
+ Renderbuffer *renderbuffer = mState.getCurrentRenderbuffer();
+ Buffer *packBuffer = mState.getTargetBuffer(BufferBinding::PixelPack);
+ ANGLE_CONTEXT_TRY(renderbuffer->getRenderbufferImage(this, mState.getPackState(), packBuffer,
+ format, type, pixels));
+}
+
+void Context::logicOpANGLE(LogicalOperation opcodePacked)
+{
+ mState.setLogicOp(opcodePacked);
+}
+
+egl::Error Context::releaseHighPowerGPU()
+{
+ return mImplementation->releaseHighPowerGPU(this);
+}
+
+egl::Error Context::reacquireHighPowerGPU()
+{
+ return mImplementation->reacquireHighPowerGPU(this);
+}
+
+void Context::onGPUSwitch()
+{
+ // Re-initialize the renderer string, which just changed, and
+ // which must be visible to applications.
+ initRendererString();
+}
+
+std::mutex &Context::getProgramCacheMutex() const
+{
+ return mDisplay->getProgramCacheMutex();
+}
+
+bool Context::supportsGeometryOrTesselation() const
+{
+ return mState.getClientVersion() == ES_3_2 || mState.getExtensions().geometryShaderAny() ||
+ mState.getExtensions().tessellationShaderEXT;
+}
+
+void Context::dirtyAllState()
+{
+ mState.setAllDirtyBits();
+ mState.setAllDirtyObjects();
+ mState.gles1().setAllDirty();
+}
+
+void Context::finishImmutable() const
+{
+ ANGLE_CONTEXT_TRY(mImplementation->finish(this));
+}
+
+void Context::beginPerfMonitor(GLuint monitor) {}
+
+void Context::deletePerfMonitors(GLsizei n, GLuint *monitors) {}
+
+void Context::endPerfMonitor(GLuint monitor) {}
+
+void Context::genPerfMonitors(GLsizei n, GLuint *monitors)
+{
+ for (GLsizei monitorIndex = 0; monitorIndex < n; ++monitorIndex)
+ {
+ monitors[n] = static_cast<GLuint>(monitorIndex);
+ }
+}
+
+void Context::getPerfMonitorCounterData(GLuint monitor,
+ GLenum pname,
+ GLsizei dataSize,
+ GLuint *data,
+ GLint *bytesWritten)
+{
+ using namespace angle;
+ const PerfMonitorCounterGroups &perfMonitorGroups = mImplementation->getPerfMonitorCounters();
+ GLint byteCount = 0;
+ switch (pname)
+ {
+ case GL_PERFMON_RESULT_AVAILABLE_AMD:
+ {
+ *data = GL_TRUE;
+ byteCount += sizeof(GLuint);
+ break;
+ }
+ case GL_PERFMON_RESULT_SIZE_AMD:
+ {
+ GLuint resultSize = 0;
+ for (const PerfMonitorCounterGroup &group : perfMonitorGroups)
+ {
+ resultSize += sizeof(PerfMonitorTriplet) * group.counters.size();
+ }
+ *data = resultSize;
+ byteCount += sizeof(GLuint);
+ break;
+ }
+ case GL_PERFMON_RESULT_AMD:
+ {
+ PerfMonitorTriplet *resultsOut = reinterpret_cast<PerfMonitorTriplet *>(data);
+ GLsizei maxResults = dataSize / (3 * sizeof(GLuint));
+ GLsizei resultCount = 0;
+ for (size_t groupIndex = 0;
+ groupIndex < perfMonitorGroups.size() && resultCount < maxResults; ++groupIndex)
+ {
+ const PerfMonitorCounterGroup &group = perfMonitorGroups[groupIndex];
+ for (size_t counterIndex = 0;
+ counterIndex < group.counters.size() && resultCount < maxResults;
+ ++counterIndex)
+ {
+ const PerfMonitorCounter &counter = group.counters[counterIndex];
+ PerfMonitorTriplet &triplet = resultsOut[resultCount++];
+ triplet.counter = static_cast<GLuint>(counterIndex);
+ triplet.group = static_cast<GLuint>(groupIndex);
+ triplet.value = counter.value;
+ }
+ }
+ byteCount += sizeof(PerfMonitorTriplet) * resultCount;
+ break;
+ }
+ default:
+ UNREACHABLE();
+ }
+
+ if (bytesWritten)
+ {
+ *bytesWritten = byteCount;
+ }
+}
+
+void Context::getPerfMonitorCounterInfo(GLuint group, GLuint counter, GLenum pname, void *data)
+{
+ using namespace angle;
+ const PerfMonitorCounterGroups &perfMonitorGroups = mImplementation->getPerfMonitorCounters();
+ ASSERT(group < perfMonitorGroups.size());
+ const PerfMonitorCounters &counters = perfMonitorGroups[group].counters;
+ ASSERT(counter < counters.size());
+
+ switch (pname)
+ {
+ case GL_COUNTER_TYPE_AMD:
+ {
+ GLenum *dataOut = reinterpret_cast<GLenum *>(data);
+ *dataOut = GL_UNSIGNED_INT;
+ break;
+ }
+ case GL_COUNTER_RANGE_AMD:
+ {
+ GLuint *dataOut = reinterpret_cast<GLuint *>(data);
+ dataOut[0] = 0;
+ dataOut[1] = std::numeric_limits<GLuint>::max();
+ break;
+ }
+ default:
+ UNREACHABLE();
+ }
+}
+
+void Context::getPerfMonitorCounterString(GLuint group,
+ GLuint counter,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *counterString)
+{
+ using namespace angle;
+ const PerfMonitorCounterGroups &perfMonitorGroups = mImplementation->getPerfMonitorCounters();
+ ASSERT(group < perfMonitorGroups.size());
+ const PerfMonitorCounters &counters = perfMonitorGroups[group].counters;
+ ASSERT(counter < counters.size());
+ GetPerfMonitorString(counters[counter].name, bufSize, length, counterString);
+}
+
+void Context::getPerfMonitorCounters(GLuint group,
+ GLint *numCounters,
+ GLint *maxActiveCounters,
+ GLsizei counterSize,
+ GLuint *counters)
+{
+ using namespace angle;
+ const PerfMonitorCounterGroups &perfMonitorGroups = mImplementation->getPerfMonitorCounters();
+ ASSERT(group < perfMonitorGroups.size());
+ const PerfMonitorCounters &groupCounters = perfMonitorGroups[group].counters;
+
+ if (numCounters)
+ {
+ *numCounters = static_cast<GLint>(groupCounters.size());
+ }
+
+ if (maxActiveCounters)
+ {
+ *maxActiveCounters = static_cast<GLint>(groupCounters.size());
+ }
+
+ if (counters)
+ {
+ GLsizei maxCounterIndex = std::min(counterSize, static_cast<GLsizei>(groupCounters.size()));
+ for (GLsizei counterIndex = 0; counterIndex < maxCounterIndex; ++counterIndex)
+ {
+ counters[counterIndex] = static_cast<GLuint>(counterIndex);
+ }
+ }
+}
+
+void Context::getPerfMonitorGroupString(GLuint group,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *groupString)
+{
+ using namespace angle;
+ const PerfMonitorCounterGroups &perfMonitorGroups = mImplementation->getPerfMonitorCounters();
+ ASSERT(group < perfMonitorGroups.size());
+ GetPerfMonitorString(perfMonitorGroups[group].name, bufSize, length, groupString);
+}
+
+void Context::getPerfMonitorGroups(GLint *numGroups, GLsizei groupsSize, GLuint *groups)
+{
+ using namespace angle;
+ const PerfMonitorCounterGroups &perfMonitorGroups = mImplementation->getPerfMonitorCounters();
+
+ if (numGroups)
+ {
+ *numGroups = static_cast<GLint>(perfMonitorGroups.size());
+ }
+
+ GLuint maxGroupIndex =
+ std::min<GLuint>(groupsSize, static_cast<GLuint>(perfMonitorGroups.size()));
+ for (GLuint groupIndex = 0; groupIndex < maxGroupIndex; ++groupIndex)
+ {
+ groups[groupIndex] = groupIndex;
+ }
+}
+
+void Context::selectPerfMonitorCounters(GLuint monitor,
+ GLboolean enable,
+ GLuint group,
+ GLint numCounters,
+ GLuint *counterList)
+{}
+
+const angle::PerfMonitorCounterGroups &Context::getPerfMonitorCounterGroups() const
+{
+ return mImplementation->getPerfMonitorCounters();
+}
+
+// ErrorSet implementation.
+ErrorSet::ErrorSet(Context *context) : mContext(context) {}
+
+ErrorSet::~ErrorSet() = default;
+
+void ErrorSet::handleError(GLenum errorCode,
+ const char *message,
+ const char *file,
+ const char *function,
+ unsigned int line)
+{
+ if (errorCode == GL_OUT_OF_MEMORY &&
+ mContext->getGraphicsResetStrategy() == GL_LOSE_CONTEXT_ON_RESET_EXT &&
+ mContext->getDisplay()->getFrontendFeatures().loseContextOnOutOfMemory.enabled)
+ {
+ mContext->markContextLost(GraphicsResetStatus::UnknownContextReset);
+ }
+
+ std::stringstream errorStream;
+ errorStream << "Error: " << gl::FmtHex(errorCode) << ", in " << file << ", " << function << ":"
+ << line << ". " << message;
+
+ std::string formattedMessage = errorStream.str();
+
+ // Process the error, but log it with WARN severity so it shows up in logs.
+ ASSERT(errorCode != GL_NO_ERROR);
+ mErrors.insert(errorCode);
+
+ mContext->getState().getDebug().insertMessage(
+ GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, errorCode, GL_DEBUG_SEVERITY_HIGH,
+ std::move(formattedMessage), gl::LOG_WARN, angle::EntryPoint::GLInvalid);
+}
+
+void ErrorSet::validationError(angle::EntryPoint entryPoint, GLenum errorCode, const char *message)
+{
+ ASSERT(errorCode != GL_NO_ERROR);
+ mErrors.insert(errorCode);
+
+ mContext->getState().getDebug().insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR,
+ errorCode, GL_DEBUG_SEVERITY_HIGH, message,
+ gl::LOG_INFO, entryPoint);
+}
+
+bool ErrorSet::empty() const
+{
+ return mErrors.empty();
+}
+
+GLenum ErrorSet::popError()
+{
+ ASSERT(!empty());
+ GLenum error = *mErrors.begin();
+ mErrors.erase(mErrors.begin());
+ return error;
+}
+
+// StateCache implementation.
+StateCache::StateCache()
+ : mCachedHasAnyEnabledClientAttrib(false),
+ mCachedNonInstancedVertexElementLimit(0),
+ mCachedInstancedVertexElementLimit(0),
+ mCachedBasicDrawStatesError(kInvalidPointer),
+ mCachedBasicDrawElementsError(kInvalidPointer),
+ mCachedProgramPipelineError(kInvalidPointer),
+ mCachedTransformFeedbackActiveUnpaused(false),
+ mCachedCanDraw(false)
+{
+ mCachedValidDrawModes.fill(false);
+}
+
+StateCache::~StateCache() = default;
+
+ANGLE_INLINE void StateCache::updateVertexElementLimits(Context *context)
+{
+ if (context->isBufferAccessValidationEnabled())
+ {
+ updateVertexElementLimitsImpl(context);
+ }
+}
+
+void StateCache::initialize(Context *context)
+{
+ updateValidDrawModes(context);
+ updateValidBindTextureTypes(context);
+ updateValidDrawElementsTypes(context);
+ updateBasicDrawStatesError();
+ updateBasicDrawElementsError();
+ updateVertexAttribTypesValidation(context);
+ updateCanDraw(context);
+}
+
+void StateCache::updateActiveAttribsMask(Context *context)
+{
+ bool isGLES1 = context->isGLES1();
+ const State &glState = context->getState();
+
+ if (!isGLES1 && !glState.getProgramExecutable())
+ {
+ mCachedActiveBufferedAttribsMask = AttributesMask();
+ mCachedActiveClientAttribsMask = AttributesMask();
+ mCachedActiveDefaultAttribsMask = AttributesMask();
+ return;
+ }
+
+ AttributesMask activeAttribs =
+ isGLES1 ? glState.gles1().getActiveAttributesMask()
+ : glState.getProgramExecutable()->getActiveAttribLocationsMask();
+
+ const VertexArray *vao = glState.getVertexArray();
+ ASSERT(vao);
+
+ const AttributesMask &clientAttribs = vao->getClientAttribsMask();
+ const AttributesMask &enabledAttribs = vao->getEnabledAttributesMask();
+ const AttributesMask &activeEnabled = activeAttribs & enabledAttribs;
+
+ mCachedActiveClientAttribsMask = activeEnabled & clientAttribs;
+ mCachedActiveBufferedAttribsMask = activeEnabled & ~clientAttribs;
+ mCachedActiveDefaultAttribsMask = activeAttribs & ~enabledAttribs;
+ mCachedHasAnyEnabledClientAttrib = (clientAttribs & enabledAttribs).any();
+}
+
+void StateCache::updateVertexElementLimitsImpl(Context *context)
+{
+ ASSERT(context->isBufferAccessValidationEnabled());
+
+ const VertexArray *vao = context->getState().getVertexArray();
+
+ mCachedNonInstancedVertexElementLimit = std::numeric_limits<GLint64>::max();
+ mCachedInstancedVertexElementLimit = std::numeric_limits<GLint64>::max();
+
+ // VAO can be null on Context startup. If we make this computation lazier we could ASSERT.
+ // If there are no buffered attributes then we should not limit the draw call count.
+ if (!vao || !mCachedActiveBufferedAttribsMask.any())
+ {
+ return;
+ }
+
+ const auto &vertexAttribs = vao->getVertexAttributes();
+ const auto &vertexBindings = vao->getVertexBindings();
+
+ for (size_t attributeIndex : mCachedActiveBufferedAttribsMask)
+ {
+ const VertexAttribute &attrib = vertexAttribs[attributeIndex];
+
+ const VertexBinding &binding = vertexBindings[attrib.bindingIndex];
+ ASSERT(context->isGLES1() ||
+ context->getState().getProgramExecutable()->isAttribLocationActive(attributeIndex));
+
+ GLint64 limit = attrib.getCachedElementLimit();
+ if (binding.getDivisor() > 0)
+ {
+ mCachedInstancedVertexElementLimit =
+ std::min(mCachedInstancedVertexElementLimit, limit);
+ }
+ else
+ {
+ mCachedNonInstancedVertexElementLimit =
+ std::min(mCachedNonInstancedVertexElementLimit, limit);
+ }
+ }
+}
+
+void StateCache::updateBasicDrawStatesError()
+{
+ mCachedBasicDrawStatesError = kInvalidPointer;
+}
+
+void StateCache::updateProgramPipelineError()
+{
+ mCachedProgramPipelineError = kInvalidPointer;
+}
+
+void StateCache::updateBasicDrawElementsError()
+{
+ mCachedBasicDrawElementsError = kInvalidPointer;
+}
+
+intptr_t StateCache::getBasicDrawStatesErrorImpl(const Context *context) const
+{
+ ASSERT(mCachedBasicDrawStatesError == kInvalidPointer);
+ mCachedBasicDrawStatesError = reinterpret_cast<intptr_t>(ValidateDrawStates(context));
+ return mCachedBasicDrawStatesError;
+}
+
+intptr_t StateCache::getProgramPipelineErrorImpl(const Context *context) const
+{
+ ASSERT(mCachedProgramPipelineError == kInvalidPointer);
+ mCachedProgramPipelineError = reinterpret_cast<intptr_t>(ValidateProgramPipeline(context));
+ return mCachedProgramPipelineError;
+}
+
+intptr_t StateCache::getBasicDrawElementsErrorImpl(const Context *context) const
+{
+ ASSERT(mCachedBasicDrawElementsError == kInvalidPointer);
+ mCachedBasicDrawElementsError = reinterpret_cast<intptr_t>(ValidateDrawElementsStates(context));
+ return mCachedBasicDrawElementsError;
+}
+
+void StateCache::onVertexArrayBindingChange(Context *context)
+{
+ updateActiveAttribsMask(context);
+ updateVertexElementLimits(context);
+ updateBasicDrawStatesError();
+ updateBasicDrawElementsError();
+}
+
+void StateCache::onProgramExecutableChange(Context *context)
+{
+ updateActiveAttribsMask(context);
+ updateVertexElementLimits(context);
+ updateBasicDrawStatesError();
+ updateProgramPipelineError();
+ updateValidDrawModes(context);
+ updateActiveShaderStorageBufferIndices(context);
+ updateActiveImageUnitIndices(context);
+ updateCanDraw(context);
+}
+
+void StateCache::onVertexArrayFormatChange(Context *context)
+{
+ updateVertexElementLimits(context);
+}
+
+void StateCache::onVertexArrayBufferContentsChange(Context *context)
+{
+ updateVertexElementLimits(context);
+ updateBasicDrawStatesError();
+}
+
+void StateCache::onVertexArrayStateChange(Context *context)
+{
+ updateActiveAttribsMask(context);
+ updateVertexElementLimits(context);
+ updateBasicDrawStatesError();
+ updateBasicDrawElementsError();
+}
+
+void StateCache::onVertexArrayBufferStateChange(Context *context)
+{
+ updateBasicDrawStatesError();
+ updateBasicDrawElementsError();
+}
+
+void StateCache::onGLES1ClientStateChange(Context *context)
+{
+ updateActiveAttribsMask(context);
+}
+
+void StateCache::onDrawFramebufferChange(Context *context)
+{
+ updateBasicDrawStatesError();
+}
+
+void StateCache::onContextCapChange(Context *context)
+{
+ updateBasicDrawStatesError();
+}
+
+void StateCache::onStencilStateChange(Context *context)
+{
+ updateBasicDrawStatesError();
+}
+
+void StateCache::onDefaultVertexAttributeChange(Context *context)
+{
+ updateBasicDrawStatesError();
+}
+
+void StateCache::onActiveTextureChange(Context *context)
+{
+ updateBasicDrawStatesError();
+}
+
+void StateCache::onQueryChange(Context *context)
+{
+ updateBasicDrawStatesError();
+}
+
+void StateCache::onActiveTransformFeedbackChange(Context *context)
+{
+ updateTransformFeedbackActiveUnpaused(context);
+ updateBasicDrawStatesError();
+ updateBasicDrawElementsError();
+ updateValidDrawModes(context);
+}
+
+void StateCache::onUniformBufferStateChange(Context *context)
+{
+ updateBasicDrawStatesError();
+}
+
+void StateCache::onAtomicCounterBufferStateChange(Context *context)
+{
+ updateBasicDrawStatesError();
+}
+
+void StateCache::onShaderStorageBufferStateChange(Context *context)
+{
+ updateBasicDrawStatesError();
+}
+
+void StateCache::onColorMaskChange(Context *context)
+{
+ updateBasicDrawStatesError();
+}
+
+void StateCache::onBlendFuncIndexedChange(Context *context)
+{
+ updateBasicDrawStatesError();
+}
+
+void StateCache::onBlendEquationChange(Context *context)
+{
+ updateBasicDrawStatesError();
+}
+
+void StateCache::setValidDrawModes(bool pointsOK,
+ bool linesOK,
+ bool trisOK,
+ bool lineAdjOK,
+ bool triAdjOK,
+ bool patchOK)
+{
+ mCachedValidDrawModes[PrimitiveMode::Points] = pointsOK;
+ mCachedValidDrawModes[PrimitiveMode::Lines] = linesOK;
+ mCachedValidDrawModes[PrimitiveMode::LineLoop] = linesOK;
+ mCachedValidDrawModes[PrimitiveMode::LineStrip] = linesOK;
+ mCachedValidDrawModes[PrimitiveMode::Triangles] = trisOK;
+ mCachedValidDrawModes[PrimitiveMode::TriangleStrip] = trisOK;
+ mCachedValidDrawModes[PrimitiveMode::TriangleFan] = trisOK;
+ mCachedValidDrawModes[PrimitiveMode::LinesAdjacency] = lineAdjOK;
+ mCachedValidDrawModes[PrimitiveMode::LineStripAdjacency] = lineAdjOK;
+ mCachedValidDrawModes[PrimitiveMode::TrianglesAdjacency] = triAdjOK;
+ mCachedValidDrawModes[PrimitiveMode::TriangleStripAdjacency] = triAdjOK;
+ mCachedValidDrawModes[PrimitiveMode::Patches] = patchOK;
+}
+
+void StateCache::updateValidDrawModes(Context *context)
+{
+ const State &state = context->getState();
+
+ const ProgramExecutable *programExecutable = context->getState().getProgramExecutable();
+
+ // If tessellation is active primitive mode must be GL_PATCHES.
+ if (programExecutable && programExecutable->hasLinkedTessellationShader())
+ {
+ setValidDrawModes(false, false, false, false, false, true);
+ return;
+ }
+
+ if (mCachedTransformFeedbackActiveUnpaused)
+ {
+ TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
+
+ // ES Spec 3.0 validation text:
+ // When transform feedback is active and not paused, all geometric primitives generated must
+ // match the value of primitiveMode passed to BeginTransformFeedback. The error
+ // INVALID_OPERATION is generated by DrawArrays and DrawArraysInstanced if mode is not
+ // identical to primitiveMode. The error INVALID_OPERATION is also generated by
+ // DrawElements, DrawElementsInstanced, and DrawRangeElements while transform feedback is
+ // active and not paused, regardless of mode. Any primitive type may be used while transform
+ // feedback is paused.
+ if (!context->getExtensions().geometryShaderAny() &&
+ !context->getExtensions().tessellationShaderEXT && context->getClientVersion() < ES_3_2)
+ {
+ mCachedValidDrawModes.fill(false);
+ mCachedValidDrawModes[curTransformFeedback->getPrimitiveMode()] = true;
+ return;
+ }
+ }
+
+ if (!programExecutable || !programExecutable->hasLinkedShaderStage(ShaderType::Geometry))
+ {
+ // All draw modes are valid, since drawing without a program does not generate an error and
+ // and operations requiring a GS will trigger other validation errors.
+ // `patchOK = false` due to checking above already enabling it if a TS is present.
+ setValidDrawModes(true, true, true, true, true, false);
+ return;
+ }
+
+ PrimitiveMode gsMode = programExecutable->getGeometryShaderInputPrimitiveType();
+ bool pointsOK = gsMode == PrimitiveMode::Points;
+ bool linesOK = gsMode == PrimitiveMode::Lines;
+ bool trisOK = gsMode == PrimitiveMode::Triangles;
+ bool lineAdjOK = gsMode == PrimitiveMode::LinesAdjacency;
+ bool triAdjOK = gsMode == PrimitiveMode::TrianglesAdjacency;
+
+ setValidDrawModes(pointsOK, linesOK, trisOK, lineAdjOK, triAdjOK, false);
+}
+
+void StateCache::updateValidBindTextureTypes(Context *context)
+{
+ const Extensions &exts = context->getExtensions();
+ bool isGLES3 = context->getClientMajorVersion() >= 3;
+ bool isGLES31 = context->getClientVersion() >= Version(3, 1);
+
+ mCachedValidBindTextureTypes = {{
+ {TextureType::_2D, true},
+ {TextureType::_2DArray, isGLES3},
+ {TextureType::_2DMultisample, isGLES31 || exts.textureMultisampleANGLE},
+ {TextureType::_2DMultisampleArray, exts.textureStorageMultisample2dArrayOES},
+ {TextureType::_3D, isGLES3 || exts.texture3DOES},
+ {TextureType::External, exts.EGLImageExternalOES || exts.EGLStreamConsumerExternalNV},
+ {TextureType::Rectangle, exts.textureRectangleANGLE},
+ {TextureType::CubeMap, true},
+ {TextureType::CubeMapArray, exts.textureCubeMapArrayAny()},
+ {TextureType::VideoImage, exts.videoTextureWEBGL},
+ {TextureType::Buffer, exts.textureBufferAny()},
+ }};
+}
+
+void StateCache::updateValidDrawElementsTypes(Context *context)
+{
+ bool supportsUint =
+ (context->getClientMajorVersion() >= 3 || context->getExtensions().elementIndexUintOES);
+
+ mCachedValidDrawElementsTypes = {{
+ {DrawElementsType::UnsignedByte, true},
+ {DrawElementsType::UnsignedShort, true},
+ {DrawElementsType::UnsignedInt, supportsUint},
+ }};
+}
+
+void StateCache::updateTransformFeedbackActiveUnpaused(Context *context)
+{
+ TransformFeedback *xfb = context->getState().getCurrentTransformFeedback();
+ mCachedTransformFeedbackActiveUnpaused = xfb && xfb->isActive() && !xfb->isPaused();
+}
+
+void StateCache::updateVertexAttribTypesValidation(Context *context)
+{
+ VertexAttribTypeCase halfFloatValidity = (context->getExtensions().vertexHalfFloatOES)
+ ? VertexAttribTypeCase::Valid
+ : VertexAttribTypeCase::Invalid;
+
+ VertexAttribTypeCase vertexType1010102Validity = (context->getExtensions().vertexType1010102OES)
+ ? VertexAttribTypeCase::ValidSize3or4
+ : VertexAttribTypeCase::Invalid;
+
+ if (context->getClientMajorVersion() <= 2)
+ {
+ mCachedVertexAttribTypesValidation = {{
+ {VertexAttribType::Byte, VertexAttribTypeCase::Valid},
+ {VertexAttribType::Short, VertexAttribTypeCase::Valid},
+ {VertexAttribType::UnsignedByte, VertexAttribTypeCase::Valid},
+ {VertexAttribType::UnsignedShort, VertexAttribTypeCase::Valid},
+ {VertexAttribType::Float, VertexAttribTypeCase::Valid},
+ {VertexAttribType::Fixed, VertexAttribTypeCase::Valid},
+ {VertexAttribType::HalfFloatOES, halfFloatValidity},
+ }};
+ }
+ else
+ {
+ mCachedVertexAttribTypesValidation = {{
+ {VertexAttribType::Byte, VertexAttribTypeCase::Valid},
+ {VertexAttribType::Short, VertexAttribTypeCase::Valid},
+ {VertexAttribType::Int, VertexAttribTypeCase::Valid},
+ {VertexAttribType::UnsignedByte, VertexAttribTypeCase::Valid},
+ {VertexAttribType::UnsignedShort, VertexAttribTypeCase::Valid},
+ {VertexAttribType::UnsignedInt, VertexAttribTypeCase::Valid},
+ {VertexAttribType::Float, VertexAttribTypeCase::Valid},
+ {VertexAttribType::HalfFloat, VertexAttribTypeCase::Valid},
+ {VertexAttribType::Fixed, VertexAttribTypeCase::Valid},
+ {VertexAttribType::Int2101010, VertexAttribTypeCase::ValidSize4Only},
+ {VertexAttribType::HalfFloatOES, halfFloatValidity},
+ {VertexAttribType::UnsignedInt2101010, VertexAttribTypeCase::ValidSize4Only},
+ {VertexAttribType::Int1010102, vertexType1010102Validity},
+ {VertexAttribType::UnsignedInt1010102, vertexType1010102Validity},
+ }};
+
+ mCachedIntegerVertexAttribTypesValidation = {{
+ {VertexAttribType::Byte, VertexAttribTypeCase::Valid},
+ {VertexAttribType::Short, VertexAttribTypeCase::Valid},
+ {VertexAttribType::Int, VertexAttribTypeCase::Valid},
+ {VertexAttribType::UnsignedByte, VertexAttribTypeCase::Valid},
+ {VertexAttribType::UnsignedShort, VertexAttribTypeCase::Valid},
+ {VertexAttribType::UnsignedInt, VertexAttribTypeCase::Valid},
+ }};
+ }
+}
+
+void StateCache::updateActiveShaderStorageBufferIndices(Context *context)
+{
+ mCachedActiveShaderStorageBufferIndices.reset();
+ const ProgramExecutable *executable = context->getState().getProgramExecutable();
+ if (executable)
+ {
+ for (const InterfaceBlock &block : executable->getShaderStorageBlocks())
+ {
+ mCachedActiveShaderStorageBufferIndices.set(block.binding);
+ }
+ }
+}
+
+void StateCache::updateActiveImageUnitIndices(Context *context)
+{
+ mCachedActiveImageUnitIndices.reset();
+ const ProgramExecutable *executable = context->getState().getProgramExecutable();
+ if (executable)
+ {
+ for (const ImageBinding &imageBinding : executable->getImageBindings())
+ {
+ for (GLuint binding : imageBinding.boundImageUnits)
+ {
+ mCachedActiveImageUnitIndices.set(binding);
+ }
+ }
+ }
+}
+
+void StateCache::updateCanDraw(Context *context)
+{
+ mCachedCanDraw =
+ (context->isGLES1() || (context->getState().getProgramExecutable() &&
+ context->getState().getProgramExecutable()->hasVertexShader()));
+}
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/Context.h b/gfx/angle/checkout/src/libANGLE/Context.h
new file mode 100644
index 0000000000..fec6a6653c
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Context.h
@@ -0,0 +1,901 @@
+//
+// Copyright 2002 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.
+//
+
+// Context.h: Defines the gl::Context class, managing all GL state and performing
+// rendering operations. It is the GLES2 specific implementation of EGLContext.
+
+#ifndef LIBANGLE_CONTEXT_H_
+#define LIBANGLE_CONTEXT_H_
+
+#include <mutex>
+#include <set>
+#include <string>
+
+#include "angle_gl.h"
+#include "common/MemoryBuffer.h"
+#include "common/PackedEnums.h"
+#include "common/angleutils.h"
+#include "libANGLE/Caps.h"
+#include "libANGLE/Constants.h"
+#include "libANGLE/Context_gl_1_autogen.h"
+#include "libANGLE/Context_gl_2_autogen.h"
+#include "libANGLE/Context_gl_3_autogen.h"
+#include "libANGLE/Context_gl_4_autogen.h"
+#include "libANGLE/Context_gles_1_0_autogen.h"
+#include "libANGLE/Context_gles_2_0_autogen.h"
+#include "libANGLE/Context_gles_3_0_autogen.h"
+#include "libANGLE/Context_gles_3_1_autogen.h"
+#include "libANGLE/Context_gles_3_2_autogen.h"
+#include "libANGLE/Context_gles_ext_autogen.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/HandleAllocator.h"
+#include "libANGLE/RefCountObject.h"
+#include "libANGLE/ResourceManager.h"
+#include "libANGLE/ResourceMap.h"
+#include "libANGLE/State.h"
+#include "libANGLE/VertexAttribute.h"
+#include "libANGLE/WorkerThread.h"
+#include "libANGLE/angletypes.h"
+
+namespace angle
+{
+class FrameCapture;
+class FrameCaptureShared;
+struct FrontendFeatures;
+} // namespace angle
+
+namespace rx
+{
+class ContextImpl;
+class EGLImplFactory;
+} // namespace rx
+
+namespace egl
+{
+class AttributeMap;
+class Surface;
+struct Config;
+class Thread;
+} // namespace egl
+
+namespace gl
+{
+class Buffer;
+class Compiler;
+class FenceNV;
+class GLES1Renderer;
+class MemoryProgramCache;
+class MemoryShaderCache;
+class MemoryObject;
+class Program;
+class ProgramPipeline;
+class Query;
+class Renderbuffer;
+class Sampler;
+class Semaphore;
+class Shader;
+class Sync;
+class Texture;
+class TransformFeedback;
+class VertexArray;
+struct VertexAttribute;
+
+class ErrorSet : angle::NonCopyable
+{
+ public:
+ explicit ErrorSet(Context *context);
+ ~ErrorSet();
+
+ bool empty() const;
+ GLenum popError();
+
+ void handleError(GLenum errorCode,
+ const char *message,
+ const char *file,
+ const char *function,
+ unsigned int line);
+
+ void validationError(angle::EntryPoint entryPoint, GLenum errorCode, const char *message);
+
+ private:
+ Context *mContext;
+ std::set<GLenum> mErrors;
+};
+
+enum class VertexAttribTypeCase
+{
+ Invalid = 0,
+ Valid = 1,
+ ValidSize4Only = 2,
+ ValidSize3or4 = 3,
+};
+
+// Helper class for managing cache variables and state changes.
+class StateCache final : angle::NonCopyable
+{
+ public:
+ StateCache();
+ ~StateCache();
+
+ void initialize(Context *context);
+
+ // Places that can trigger updateActiveAttribsMask:
+ // 1. onVertexArrayBindingChange.
+ // 2. onProgramExecutableChange.
+ // 3. onVertexArrayStateChange.
+ // 4. onGLES1ClientStateChange.
+ AttributesMask getActiveBufferedAttribsMask() const { return mCachedActiveBufferedAttribsMask; }
+ AttributesMask getActiveClientAttribsMask() const { return mCachedActiveClientAttribsMask; }
+ AttributesMask getActiveDefaultAttribsMask() const { return mCachedActiveDefaultAttribsMask; }
+ bool hasAnyEnabledClientAttrib() const { return mCachedHasAnyEnabledClientAttrib; }
+ bool hasAnyActiveClientAttrib() const { return mCachedActiveClientAttribsMask.any(); }
+
+ // Places that can trigger updateVertexElementLimits:
+ // 1. onVertexArrayBindingChange.
+ // 2. onProgramExecutableChange.
+ // 3. onVertexArrayFormatChange.
+ // 4. onVertexArrayBufferChange.
+ // 5. onVertexArrayStateChange.
+ GLint64 getNonInstancedVertexElementLimit() const
+ {
+ return mCachedNonInstancedVertexElementLimit;
+ }
+ GLint64 getInstancedVertexElementLimit() const { return mCachedInstancedVertexElementLimit; }
+
+ // Places that can trigger updateBasicDrawStatesError:
+ // 1. onVertexArrayBindingChange.
+ // 2. onProgramExecutableChange.
+ // 3. onVertexArrayBufferContentsChange.
+ // 4. onVertexArrayStateChange.
+ // 5. onVertexArrayBufferStateChange.
+ // 6. onDrawFramebufferChange.
+ // 7. onContextCapChange.
+ // 8. onStencilStateChange.
+ // 9. onDefaultVertexAttributeChange.
+ // 10. onActiveTextureChange.
+ // 11. onQueryChange.
+ // 12. onActiveTransformFeedbackChange.
+ // 13. onUniformBufferStateChange.
+ // 14. onColorMaskChange.
+ // 15. onBufferBindingChange.
+ // 16. onBlendFuncIndexedChange.
+ bool hasBasicDrawStatesError(Context *context) const
+ {
+ if (mCachedBasicDrawStatesError == 0)
+ {
+ return false;
+ }
+ if (mCachedBasicDrawStatesError != kInvalidPointer)
+ {
+ return true;
+ }
+ return getBasicDrawStatesErrorImpl(context) != 0;
+ }
+
+ intptr_t getBasicDrawStatesError(const Context *context) const
+ {
+ if (mCachedBasicDrawStatesError != kInvalidPointer)
+ {
+ return mCachedBasicDrawStatesError;
+ }
+
+ return getBasicDrawStatesErrorImpl(context);
+ }
+
+ // Places that can trigger updateProgramPipelineError:
+ // 1. onProgramExecutableChange.
+ intptr_t getProgramPipelineError(const Context *context) const
+ {
+ if (mCachedProgramPipelineError != kInvalidPointer)
+ {
+ return mCachedProgramPipelineError;
+ }
+
+ return getProgramPipelineErrorImpl(context);
+ }
+
+ // Places that can trigger updateBasicDrawElementsError:
+ // 1. onActiveTransformFeedbackChange.
+ // 2. onVertexArrayBufferStateChange.
+ // 3. onBufferBindingChange.
+ // 4. onVertexArrayStateChange.
+ // 5. onVertexArrayBindingStateChange.
+ intptr_t getBasicDrawElementsError(const Context *context) const
+ {
+ if (mCachedBasicDrawElementsError != kInvalidPointer)
+ {
+ return mCachedBasicDrawElementsError;
+ }
+
+ return getBasicDrawElementsErrorImpl(context);
+ }
+
+ // Places that can trigger updateValidDrawModes:
+ // 1. onProgramExecutableChange.
+ // 2. onActiveTransformFeedbackChange.
+ bool isValidDrawMode(PrimitiveMode primitiveMode) const
+ {
+ return mCachedValidDrawModes[primitiveMode];
+ }
+
+ // Cannot change except on Context/Extension init.
+ bool isValidBindTextureType(TextureType type) const
+ {
+ return mCachedValidBindTextureTypes[type];
+ }
+
+ // Cannot change except on Context/Extension init.
+ bool isValidDrawElementsType(DrawElementsType type) const
+ {
+ return mCachedValidDrawElementsTypes[type];
+ }
+
+ // Places that can trigger updateTransformFeedbackActiveUnpaused:
+ // 1. onActiveTransformFeedbackChange.
+ bool isTransformFeedbackActiveUnpaused() const
+ {
+ return mCachedTransformFeedbackActiveUnpaused;
+ }
+
+ // Cannot change except on Context/Extension init.
+ VertexAttribTypeCase getVertexAttribTypeValidation(VertexAttribType type) const
+ {
+ return mCachedVertexAttribTypesValidation[type];
+ }
+
+ VertexAttribTypeCase getIntegerVertexAttribTypeValidation(VertexAttribType type) const
+ {
+ return mCachedIntegerVertexAttribTypesValidation[type];
+ }
+
+ // Places that can trigger updateActiveShaderStorageBufferIndices:
+ // 1. onProgramExecutableChange.
+ StorageBuffersMask getActiveShaderStorageBufferIndices() const
+ {
+ return mCachedActiveShaderStorageBufferIndices;
+ }
+
+ // Places that can trigger updateActiveImageUnitIndices:
+ // 1. onProgramExecutableChange.
+ const ImageUnitMask &getActiveImageUnitIndices() const { return mCachedActiveImageUnitIndices; }
+
+ // Places that can trigger updateCanDraw:
+ // 1. onProgramExecutableChange.
+ bool getCanDraw() const { return mCachedCanDraw; }
+
+ // State change notifications.
+ void onVertexArrayBindingChange(Context *context);
+ void onProgramExecutableChange(Context *context);
+ void onVertexArrayFormatChange(Context *context);
+ void onVertexArrayBufferContentsChange(Context *context);
+ void onVertexArrayStateChange(Context *context);
+ void onVertexArrayBufferStateChange(Context *context);
+ void onGLES1ClientStateChange(Context *context);
+ void onDrawFramebufferChange(Context *context);
+ void onContextCapChange(Context *context);
+ void onStencilStateChange(Context *context);
+ void onDefaultVertexAttributeChange(Context *context);
+ void onActiveTextureChange(Context *context);
+ void onQueryChange(Context *context);
+ void onActiveTransformFeedbackChange(Context *context);
+ void onUniformBufferStateChange(Context *context);
+ void onAtomicCounterBufferStateChange(Context *context);
+ void onShaderStorageBufferStateChange(Context *context);
+ void onColorMaskChange(Context *context);
+ void onBufferBindingChange(Context *context);
+ void onBlendFuncIndexedChange(Context *context);
+ void onBlendEquationChange(Context *context);
+
+ private:
+ // Cache update functions.
+ void updateActiveAttribsMask(Context *context);
+ void updateVertexElementLimits(Context *context);
+ void updateVertexElementLimitsImpl(Context *context);
+ void updateValidDrawModes(Context *context);
+ void updateValidBindTextureTypes(Context *context);
+ void updateValidDrawElementsTypes(Context *context);
+ void updateBasicDrawStatesError();
+ void updateProgramPipelineError();
+ void updateBasicDrawElementsError();
+ void updateTransformFeedbackActiveUnpaused(Context *context);
+ void updateVertexAttribTypesValidation(Context *context);
+ void updateActiveShaderStorageBufferIndices(Context *context);
+ void updateActiveImageUnitIndices(Context *context);
+ void updateCanDraw(Context *context);
+
+ void setValidDrawModes(bool pointsOK,
+ bool linesOK,
+ bool trisOK,
+ bool lineAdjOK,
+ bool triAdjOK,
+ bool patchOK);
+
+ intptr_t getBasicDrawStatesErrorImpl(const Context *context) const;
+ intptr_t getProgramPipelineErrorImpl(const Context *context) const;
+ intptr_t getBasicDrawElementsErrorImpl(const Context *context) const;
+
+ static constexpr intptr_t kInvalidPointer = 1;
+
+ AttributesMask mCachedActiveBufferedAttribsMask;
+ AttributesMask mCachedActiveClientAttribsMask;
+ AttributesMask mCachedActiveDefaultAttribsMask;
+ bool mCachedHasAnyEnabledClientAttrib;
+ GLint64 mCachedNonInstancedVertexElementLimit;
+ GLint64 mCachedInstancedVertexElementLimit;
+ mutable intptr_t mCachedBasicDrawStatesError;
+ mutable intptr_t mCachedBasicDrawElementsError;
+ // mCachedProgramPipelineError checks only the
+ // current-program-exists subset of mCachedBasicDrawStatesError.
+ // Therefore, mCachedProgramPipelineError follows
+ // mCachedBasicDrawStatesError in that if mCachedBasicDrawStatesError is
+ // no-error, so is mCachedProgramPipelineError. Otherwise, if
+ // mCachedBasicDrawStatesError is in error, the state of
+ // mCachedProgramPipelineError can be no-error or also in error, or
+ // unknown due to early exiting.
+ mutable intptr_t mCachedProgramPipelineError;
+ bool mCachedTransformFeedbackActiveUnpaused;
+ StorageBuffersMask mCachedActiveShaderStorageBufferIndices;
+ ImageUnitMask mCachedActiveImageUnitIndices;
+
+ // Reserve an extra slot at the end of these maps for invalid enum.
+ angle::PackedEnumMap<PrimitiveMode, bool, angle::EnumSize<PrimitiveMode>() + 1>
+ mCachedValidDrawModes;
+ angle::PackedEnumMap<TextureType, bool, angle::EnumSize<TextureType>() + 1>
+ mCachedValidBindTextureTypes;
+ angle::PackedEnumMap<DrawElementsType, bool, angle::EnumSize<DrawElementsType>() + 1>
+ mCachedValidDrawElementsTypes;
+ angle::PackedEnumMap<VertexAttribType,
+ VertexAttribTypeCase,
+ angle::EnumSize<VertexAttribType>() + 1>
+ mCachedVertexAttribTypesValidation;
+ angle::PackedEnumMap<VertexAttribType,
+ VertexAttribTypeCase,
+ angle::EnumSize<VertexAttribType>() + 1>
+ mCachedIntegerVertexAttribTypesValidation;
+
+ bool mCachedCanDraw;
+};
+
+using VertexArrayMap = ResourceMap<VertexArray, VertexArrayID>;
+using QueryMap = ResourceMap<Query, QueryID>;
+using TransformFeedbackMap = ResourceMap<TransformFeedback, TransformFeedbackID>;
+
+class Context final : public egl::LabeledObject, angle::NonCopyable, public angle::ObserverInterface
+{
+ public:
+ Context(egl::Display *display,
+ const egl::Config *config,
+ const Context *shareContext,
+ TextureManager *shareTextures,
+ SemaphoreManager *shareSemaphores,
+ MemoryProgramCache *memoryProgramCache,
+ MemoryShaderCache *memoryShaderCache,
+ const EGLenum clientType,
+ const egl::AttributeMap &attribs,
+ const egl::DisplayExtensions &displayExtensions,
+ const egl::ClientExtensions &clientExtensions);
+
+ // Use for debugging.
+ ContextID id() const { return mState.getContextID(); }
+
+ egl::Error initialize();
+
+ egl::Error onDestroy(const egl::Display *display);
+ ~Context() override;
+
+ void setLabel(EGLLabelKHR label) override;
+ EGLLabelKHR getLabel() const override;
+
+ egl::Error makeCurrent(egl::Display *display,
+ egl::Surface *drawSurface,
+ egl::Surface *readSurface);
+ egl::Error unMakeCurrent(const egl::Display *display);
+
+ // These create and destroy methods pass through to ResourceManager, which owns these objects.
+ BufferID createBuffer();
+ TextureID createTexture();
+ RenderbufferID createRenderbuffer();
+ ProgramPipelineID createProgramPipeline();
+ MemoryObjectID createMemoryObject();
+ SemaphoreID createSemaphore();
+
+ void deleteBuffer(BufferID buffer);
+ void deleteTexture(TextureID texture);
+ void deleteRenderbuffer(RenderbufferID renderbuffer);
+ void deleteProgramPipeline(ProgramPipelineID pipeline);
+ void deleteMemoryObject(MemoryObjectID memoryObject);
+ void deleteSemaphore(SemaphoreID semaphore);
+
+ void bindReadFramebuffer(FramebufferID framebufferHandle);
+ void bindDrawFramebuffer(FramebufferID framebufferHandle);
+
+ Buffer *getBuffer(BufferID handle) const;
+ FenceNV *getFenceNV(FenceNVID handle) const;
+ Sync *getSync(GLsync handle) const;
+ ANGLE_INLINE Texture *getTexture(TextureID handle) const
+ {
+ return mState.mTextureManager->getTexture(handle);
+ }
+
+ Framebuffer *getFramebuffer(FramebufferID handle) const;
+ Renderbuffer *getRenderbuffer(RenderbufferID handle) const;
+ VertexArray *getVertexArray(VertexArrayID handle) const;
+ Sampler *getSampler(SamplerID handle) const;
+ Query *getOrCreateQuery(QueryID handle, QueryType type);
+ Query *getQuery(QueryID handle) const;
+ TransformFeedback *getTransformFeedback(TransformFeedbackID handle) const;
+ ProgramPipeline *getProgramPipeline(ProgramPipelineID handle) const;
+ MemoryObject *getMemoryObject(MemoryObjectID handle) const;
+ Semaphore *getSemaphore(SemaphoreID handle) const;
+
+ Texture *getTextureByType(TextureType type) const;
+ Texture *getTextureByTarget(TextureTarget target) const;
+ Texture *getSamplerTexture(unsigned int sampler, TextureType type) const;
+
+ Compiler *getCompiler() const;
+
+ bool isVertexArrayGenerated(VertexArrayID vertexArray) const;
+ bool isTransformFeedbackGenerated(TransformFeedbackID transformFeedback) const;
+
+ bool isExternal() const { return mIsExternal; }
+ bool saveAndRestoreState() const { return mSaveAndRestoreState; }
+
+ void getBooleanvImpl(GLenum pname, GLboolean *params) const;
+ void getFloatvImpl(GLenum pname, GLfloat *params) const;
+ void getIntegervImpl(GLenum pname, GLint *params) const;
+ void getInteger64vImpl(GLenum pname, GLint64 *params) const;
+ void getIntegerVertexAttribImpl(GLenum pname, GLenum attribpname, GLint *params) const;
+ void getVertexAttribivImpl(GLuint index, GLenum pname, GLint *params) const;
+
+ // Framebuffers are owned by the Context, so these methods do not pass through
+ FramebufferID createFramebuffer();
+ void deleteFramebuffer(FramebufferID framebuffer);
+
+ bool hasActiveTransformFeedback(ShaderProgramID program) const;
+
+ // Desktop GL entry point interface
+ ANGLE_GL_1_CONTEXT_API
+ ANGLE_GL_2_CONTEXT_API
+ ANGLE_GL_3_CONTEXT_API
+ ANGLE_GL_4_CONTEXT_API
+
+ // GLES entry point interface
+ ANGLE_GLES_1_0_CONTEXT_API
+ ANGLE_GLES_2_0_CONTEXT_API
+ ANGLE_GLES_3_0_CONTEXT_API
+ ANGLE_GLES_3_1_CONTEXT_API
+ ANGLE_GLES_3_2_CONTEXT_API
+ ANGLE_GLES_EXT_CONTEXT_API
+
+ angle::Result handleNoopDrawEvent();
+
+ // Consumes an error.
+ void handleError(GLenum errorCode,
+ const char *message,
+ const char *file,
+ const char *function,
+ unsigned int line);
+
+ void validationError(angle::EntryPoint entryPoint, GLenum errorCode, const char *message) const;
+ ANGLE_FORMAT_PRINTF(4, 5)
+ void validationErrorF(angle::EntryPoint entryPoint,
+ GLenum errorCode,
+ const char *format,
+ ...) const;
+
+ void markContextLost(GraphicsResetStatus status);
+
+ bool isContextLost() const { return mContextLost; }
+ void setContextLost();
+
+ GLenum getGraphicsResetStrategy() const { return mResetStrategy; }
+ bool isResetNotificationEnabled() const;
+
+ bool isRobustnessEnabled() const;
+
+ const egl::Config *getConfig() const;
+ EGLenum getClientType() const;
+ EGLenum getRenderBuffer() const;
+ EGLenum getContextPriority() const;
+
+ const GLubyte *getString(GLenum name) const;
+ const GLubyte *getStringi(GLenum name, GLuint index) const;
+
+ size_t getExtensionStringCount() const;
+
+ bool isExtensionRequestable(const char *name) const;
+ bool isExtensionDisablable(const char *name) const;
+ size_t getRequestableExtensionStringCount() const;
+ void setExtensionEnabled(const char *name, bool enabled);
+ void reinitializeAfterExtensionsChanged();
+
+ rx::ContextImpl *getImplementation() const { return mImplementation.get(); }
+
+ [[nodiscard]] bool getScratchBuffer(size_t requestedSizeBytes,
+ angle::MemoryBuffer **scratchBufferOut) const;
+ [[nodiscard]] bool getZeroFilledBuffer(size_t requstedSizeBytes,
+ angle::MemoryBuffer **zeroBufferOut) const;
+ angle::ScratchBuffer *getScratchBuffer() const;
+
+ angle::Result prepareForCopyImage();
+ angle::Result prepareForDispatch();
+ angle::Result prepareForInvalidate(GLenum target);
+
+ MemoryProgramCache *getMemoryProgramCache() const { return mMemoryProgramCache; }
+ MemoryShaderCache *getMemoryShaderCache() const { return mMemoryShaderCache; }
+
+ std::mutex &getProgramCacheMutex() const;
+
+ bool hasBeenCurrent() const { return mHasBeenCurrent; }
+ egl::Display *getDisplay() const { return mDisplay; }
+ egl::Surface *getCurrentDrawSurface() const { return mCurrentDrawSurface; }
+ egl::Surface *getCurrentReadSurface() const { return mCurrentReadSurface; }
+
+ bool isRobustResourceInitEnabled() const { return mState.isRobustResourceInitEnabled(); }
+
+ bool isCurrentTransformFeedback(const TransformFeedback *tf) const;
+
+ bool isCurrentVertexArray(const VertexArray *va) const
+ {
+ return mState.isCurrentVertexArray(va);
+ }
+
+ ANGLE_INLINE bool isShared() const { return mShared; }
+ // Once a context is setShared() it cannot be undone
+ void setShared() { mShared = true; }
+
+ const State &getState() const { return mState; }
+ GLint getClientMajorVersion() const { return mState.getClientMajorVersion(); }
+ GLint getClientMinorVersion() const { return mState.getClientMinorVersion(); }
+ const Version &getClientVersion() const { return mState.getClientVersion(); }
+ const Caps &getCaps() const { return mState.getCaps(); }
+ const TextureCapsMap &getTextureCaps() const { return mState.getTextureCaps(); }
+ const Extensions &getExtensions() const { return mState.getExtensions(); }
+ const Limitations &getLimitations() const { return mState.getLimitations(); }
+ bool isGLES1() const;
+
+ bool skipValidation() const
+ {
+ // Ensure we don't skip validation when context becomes lost, since implementations
+ // generally assume a non-lost context, non-null objects, etc.
+ ASSERT(!isContextLost() || !mSkipValidation);
+ return mSkipValidation;
+ }
+
+ // Specific methods needed for validation.
+ bool getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams) const;
+ bool getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams) const;
+
+ ANGLE_INLINE Program *getProgramResolveLink(ShaderProgramID handle) const
+ {
+ Program *program = mState.mShaderProgramManager->getProgram(handle);
+ if (program)
+ {
+ program->resolveLink(this);
+ }
+ return program;
+ }
+
+ Program *getProgramNoResolveLink(ShaderProgramID handle) const;
+ Shader *getShader(ShaderProgramID handle) const;
+
+ ANGLE_INLINE bool isTextureGenerated(TextureID texture) const
+ {
+ return mState.mTextureManager->isHandleGenerated(texture);
+ }
+
+ ANGLE_INLINE bool isBufferGenerated(BufferID buffer) const
+ {
+ return mState.mBufferManager->isHandleGenerated(buffer);
+ }
+
+ bool isRenderbufferGenerated(RenderbufferID renderbuffer) const;
+ bool isFramebufferGenerated(FramebufferID framebuffer) const;
+ bool isProgramPipelineGenerated(ProgramPipelineID pipeline) const;
+ bool isQueryGenerated(QueryID query) const;
+
+ bool usingDisplayTextureShareGroup() const;
+ bool usingDisplaySemaphoreShareGroup() const;
+
+ // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
+ GLenum getConvertedRenderbufferFormat(GLenum internalformat) const;
+
+ bool isWebGL() const { return mState.isWebGL(); }
+ bool isWebGL1() const { return mState.isWebGL1(); }
+
+ bool isValidBufferBinding(BufferBinding binding) const { return mValidBufferBindings[binding]; }
+
+ // GLES1 emulation: Renderer level (for validation)
+ int vertexArrayIndex(ClientVertexArrayType type) const;
+ static int TexCoordArrayIndex(unsigned int unit);
+
+ // GL_KHR_parallel_shader_compile
+ std::shared_ptr<angle::WorkerThreadPool> getShaderCompileThreadPool() const
+ {
+ if (mState.mExtensions.parallelShaderCompileKHR)
+ {
+ return mMultiThreadPool;
+ }
+ return mSingleThreadPool;
+ }
+
+ // Generic multithread pool.
+ std::shared_ptr<angle::WorkerThreadPool> getWorkerThreadPool() const
+ {
+ return mMultiThreadPool;
+ }
+
+ const StateCache &getStateCache() const { return mStateCache; }
+ StateCache &getStateCache() { return mStateCache; }
+
+ void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override;
+
+ void onSamplerUniformChange(size_t textureUnitIndex);
+
+ bool isBufferAccessValidationEnabled() const { return mBufferAccessValidationEnabled; }
+
+ const angle::FrontendFeatures &getFrontendFeatures() const;
+
+ angle::FrameCapture *getFrameCapture() const { return mFrameCapture.get(); }
+
+ const VertexArrayMap &getVertexArraysForCapture() const { return mVertexArrayMap; }
+ const QueryMap &getQueriesForCapture() const { return mQueryMap; }
+ const TransformFeedbackMap &getTransformFeedbacksForCapture() const
+ {
+ return mTransformFeedbackMap;
+ }
+
+ void onPreSwap() const;
+
+ Program *getActiveLinkedProgram() const;
+
+ // EGL_ANGLE_power_preference implementation.
+ egl::Error releaseHighPowerGPU();
+ egl::Error reacquireHighPowerGPU();
+ void onGPUSwitch();
+
+ bool noopDraw(PrimitiveMode mode, GLsizei count) const;
+ bool noopDrawInstanced(PrimitiveMode mode, GLsizei count, GLsizei instanceCount) const;
+
+ bool isClearBufferMaskedOut(GLenum buffer, GLint drawbuffer) const;
+ bool noopClearBuffer(GLenum buffer, GLint drawbuffer) const;
+
+ void addRef() const { mRefCount++; }
+ void release() const { mRefCount--; }
+ size_t getRefCount() const { return mRefCount; }
+
+ egl::ShareGroup *getShareGroup() const { return mState.getShareGroup(); }
+
+ bool supportsGeometryOrTesselation() const;
+ void dirtyAllState();
+
+ bool isDestroyed() const { return mIsDestroyed; }
+ void setIsDestroyed() { mIsDestroyed = true; }
+
+ void setLogicOpEnabled(bool enabled) { mState.setLogicOpEnabled(enabled); }
+ void setLogicOp(LogicalOperation opcode) { mState.setLogicOp(opcode); }
+
+ // Needed by capture serialization logic that works with a "const" Context pointer.
+ void finishImmutable() const;
+
+ const angle::PerfMonitorCounterGroups &getPerfMonitorCounterGroups() const;
+
+ private:
+ void initializeDefaultResources();
+
+ angle::Result prepareForDraw(PrimitiveMode mode);
+ angle::Result prepareForClear(GLbitfield mask);
+ angle::Result prepareForClearBuffer(GLenum buffer, GLint drawbuffer);
+ angle::Result syncState(const State::DirtyBits &bitMask,
+ const State::DirtyObjects &objectMask,
+ Command command);
+ angle::Result syncDirtyBits(Command command);
+ angle::Result syncDirtyBits(const State::DirtyBits &bitMask, Command command);
+ angle::Result syncDirtyObjects(const State::DirtyObjects &objectMask, Command command);
+ angle::Result syncStateForReadPixels();
+ angle::Result syncStateForTexImage();
+ angle::Result syncStateForBlit(GLbitfield mask);
+ angle::Result syncStateForClear();
+ angle::Result syncTextureForCopy(Texture *texture);
+
+ VertexArray *checkVertexArrayAllocation(VertexArrayID vertexArrayHandle);
+ TransformFeedback *checkTransformFeedbackAllocation(TransformFeedbackID transformFeedback);
+
+ angle::Result onProgramLink(Program *programObject);
+
+ void detachBuffer(Buffer *buffer);
+ void detachTexture(TextureID texture);
+ void detachFramebuffer(FramebufferID framebuffer);
+ void detachRenderbuffer(RenderbufferID renderbuffer);
+ void detachVertexArray(VertexArrayID vertexArray);
+ void detachTransformFeedback(TransformFeedbackID transformFeedback);
+ void detachSampler(SamplerID sampler);
+ void detachProgramPipeline(ProgramPipelineID pipeline);
+
+ egl::Error setDefaultFramebuffer(egl::Surface *drawSurface, egl::Surface *readSurface);
+ egl::Error unsetDefaultFramebuffer();
+
+ void initRendererString();
+ void initVersionStrings();
+ void initExtensionStrings();
+
+ Extensions generateSupportedExtensions() const;
+ void initCaps();
+ void updateCaps();
+
+ gl::LabeledObject *getLabeledObject(GLenum identifier, GLuint name) const;
+ gl::LabeledObject *getLabeledObjectFromPtr(const void *ptr) const;
+
+ void setUniform1iImpl(Program *program,
+ UniformLocation location,
+ GLsizei count,
+ const GLint *v);
+ void renderbufferStorageMultisampleImpl(GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ MultisamplingMode mode);
+
+ State mState;
+ bool mShared;
+ bool mSkipValidation;
+ bool mDisplayTextureShareGroup;
+ bool mDisplaySemaphoreShareGroup;
+
+ // Recorded errors
+ ErrorSet mErrors;
+
+ // Stores for each buffer binding type whether is it allowed to be used in this context.
+ angle::PackedEnumBitSet<BufferBinding> mValidBufferBindings;
+
+ std::unique_ptr<rx::ContextImpl> mImplementation;
+
+ EGLLabelKHR mLabel;
+
+ // Extensions supported by the implementation plus extensions that are implemented entirely
+ // within the frontend.
+ Extensions mSupportedExtensions;
+
+ // Shader compiler. Lazily initialized hence the mutable value.
+ mutable BindingPointer<Compiler> mCompiler;
+
+ const egl::Config *mConfig;
+
+ TextureMap mZeroTextures;
+
+ ResourceMap<FenceNV, FenceNVID> mFenceNVMap;
+ HandleAllocator mFenceNVHandleAllocator;
+
+ QueryMap mQueryMap;
+ HandleAllocator mQueryHandleAllocator;
+
+ VertexArrayMap mVertexArrayMap;
+ HandleAllocator mVertexArrayHandleAllocator;
+
+ TransformFeedbackMap mTransformFeedbackMap;
+ HandleAllocator mTransformFeedbackHandleAllocator;
+
+ const char *mVersionString;
+ const char *mShadingLanguageString;
+ const char *mRendererString;
+ const char *mExtensionString;
+ std::vector<const char *> mExtensionStrings;
+ const char *mRequestableExtensionString;
+ std::vector<const char *> mRequestableExtensionStrings;
+
+ // GLES1 renderer state
+ std::unique_ptr<GLES1Renderer> mGLES1Renderer;
+
+ // Current/lost context flags
+ bool mHasBeenCurrent;
+ bool mContextLost; // Set with setContextLost so that we also set mSkipValidation=false.
+ GraphicsResetStatus mResetStatus;
+ bool mContextLostForced;
+ GLenum mResetStrategy;
+ const bool mSurfacelessSupported;
+ egl::Surface *mCurrentDrawSurface;
+ egl::Surface *mCurrentReadSurface;
+ egl::Display *mDisplay;
+ const bool mWebGLContext;
+ bool mBufferAccessValidationEnabled;
+ const bool mExtensionsEnabled;
+ MemoryProgramCache *mMemoryProgramCache;
+ MemoryShaderCache *mMemoryShaderCache;
+
+ State::DirtyObjects mDrawDirtyObjects;
+
+ StateCache mStateCache;
+
+ State::DirtyBits mAllDirtyBits;
+ State::DirtyBits mTexImageDirtyBits;
+ State::DirtyObjects mTexImageDirtyObjects;
+ State::DirtyBits mReadPixelsDirtyBits;
+ State::DirtyObjects mReadPixelsDirtyObjects;
+ State::DirtyBits mClearDirtyBits;
+ State::DirtyObjects mClearDirtyObjects;
+ State::DirtyBits mBlitDirtyBits;
+ State::DirtyObjects mBlitDirtyObjects;
+ State::DirtyBits mComputeDirtyBits;
+ State::DirtyObjects mComputeDirtyObjects;
+ State::DirtyBits mCopyImageDirtyBits;
+ State::DirtyObjects mCopyImageDirtyObjects;
+ State::DirtyBits mReadInvalidateDirtyBits;
+ State::DirtyBits mDrawInvalidateDirtyBits;
+
+ // Binding to container objects that use dependent state updates.
+ angle::ObserverBinding mVertexArrayObserverBinding;
+ angle::ObserverBinding mDrawFramebufferObserverBinding;
+ angle::ObserverBinding mReadFramebufferObserverBinding;
+ angle::ObserverBinding mProgramPipelineObserverBinding;
+ std::vector<angle::ObserverBinding> mUniformBufferObserverBindings;
+ std::vector<angle::ObserverBinding> mAtomicCounterBufferObserverBindings;
+ std::vector<angle::ObserverBinding> mShaderStorageBufferObserverBindings;
+ std::vector<angle::ObserverBinding> mSamplerObserverBindings;
+ std::vector<angle::ObserverBinding> mImageObserverBindings;
+
+ // Not really a property of context state. The size and contexts change per-api-call.
+ mutable Optional<angle::ScratchBuffer> mScratchBuffer;
+ mutable Optional<angle::ScratchBuffer> mZeroFilledBuffer;
+
+ // Single-threaded pool may not always be initialized. It currently depends on the extension
+ // GL_KHR_parallel_shader_compile being disabled.
+ std::shared_ptr<angle::WorkerThreadPool> mSingleThreadPool;
+ // Multithreaded pool will always be initialized so it can be used for more generic work.
+ std::shared_ptr<angle::WorkerThreadPool> mMultiThreadPool;
+
+ // Note: we use a raw pointer here so we can exclude frame capture sources from the build.
+ std::unique_ptr<angle::FrameCapture> mFrameCapture;
+
+ // Cache representation of the serialized context string.
+ mutable std::string mCachedSerializedStateString;
+
+ mutable size_t mRefCount;
+
+ OverlayType mOverlay;
+
+ const bool mIsExternal;
+ const bool mSaveAndRestoreState;
+
+ bool mIsDestroyed;
+
+ std::unique_ptr<Framebuffer> mDefaultFramebuffer;
+};
+
+class [[nodiscard]] ScopedContextRef
+{
+ public:
+ ScopedContextRef(Context *context) : mContext(context)
+ {
+ if (mContext)
+ {
+ mContext->addRef();
+ }
+ }
+ ~ScopedContextRef()
+ {
+ if (mContext)
+ {
+ mContext->release();
+ }
+ }
+
+ private:
+ Context *const mContext;
+};
+
+// Thread-local current valid context bound to the thread.
+#if defined(ANGLE_PLATFORM_APPLE)
+extern Context *GetCurrentValidContextTLS();
+extern void SetCurrentValidContextTLS(Context *context);
+#else
+extern thread_local Context *gCurrentValidContext;
+#endif
+
+} // namespace gl
+
+#endif // LIBANGLE_CONTEXT_H_
diff --git a/gfx/angle/checkout/src/libANGLE/Context.inl.h b/gfx/angle/checkout/src/libANGLE/Context.inl.h
new file mode 100644
index 0000000000..3a0573d307
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Context.inl.h
@@ -0,0 +1,176 @@
+//
+// Copyright 2018 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.
+//
+
+// Context.inl.h: Defines inline functions of gl::Context class
+// Has to be included after libANGLE/Context.h when using one
+// of the defined functions
+
+#ifndef LIBANGLE_CONTEXT_INL_H_
+#define LIBANGLE_CONTEXT_INL_H_
+
+#include "libANGLE/Context.h"
+#include "libANGLE/GLES1Renderer.h"
+#include "libANGLE/renderer/ContextImpl.h"
+
+#define ANGLE_HANDLE_ERR(X) \
+ (void)(X); \
+ return;
+#define ANGLE_CONTEXT_TRY(EXPR) ANGLE_TRY_TEMPLATE(EXPR, ANGLE_HANDLE_ERR)
+
+namespace gl
+{
+constexpr angle::PackedEnumMap<PrimitiveMode, GLsizei> kMinimumPrimitiveCounts = {{
+ {PrimitiveMode::Points, 1},
+ {PrimitiveMode::Lines, 2},
+ {PrimitiveMode::LineLoop, 2},
+ {PrimitiveMode::LineStrip, 2},
+ {PrimitiveMode::Triangles, 3},
+ {PrimitiveMode::TriangleStrip, 3},
+ {PrimitiveMode::TriangleFan, 3},
+ {PrimitiveMode::LinesAdjacency, 2},
+ {PrimitiveMode::LineStripAdjacency, 2},
+ {PrimitiveMode::TrianglesAdjacency, 3},
+ {PrimitiveMode::TriangleStripAdjacency, 3},
+}};
+
+ANGLE_INLINE void MarkTransformFeedbackBufferUsage(const Context *context,
+ GLsizei count,
+ GLsizei instanceCount)
+{
+ if (context->getStateCache().isTransformFeedbackActiveUnpaused())
+ {
+ TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
+ transformFeedback->onVerticesDrawn(context, count, instanceCount);
+ }
+}
+
+ANGLE_INLINE void MarkShaderStorageUsage(const Context *context)
+{
+ for (size_t index : context->getStateCache().getActiveShaderStorageBufferIndices())
+ {
+ Buffer *buffer = context->getState().getIndexedShaderStorageBuffer(index).get();
+ if (buffer)
+ {
+ buffer->onDataChanged();
+ }
+ }
+
+ for (size_t index : context->getStateCache().getActiveImageUnitIndices())
+ {
+ const ImageUnit &imageUnit = context->getState().getImageUnit(index);
+ const Texture *texture = imageUnit.texture.get();
+ if (texture)
+ {
+ texture->onStateChange(angle::SubjectMessage::ContentsChanged);
+ }
+ }
+}
+
+// Return true if the draw is a no-op, else return false.
+// If there is no active program for the vertex or fragment shader stages, the results of vertex
+// and fragment shader execution will respectively be undefined. However, this is not
+// an error. ANGLE will treat this as a no-op.
+// A no-op draw occurs if the count of vertices is less than the minimum required to
+// have a valid primitive for this mode (0 for points, 0-1 for lines, 0-2 for tris).
+ANGLE_INLINE bool Context::noopDraw(PrimitiveMode mode, GLsizei count) const
+{
+ if (!mStateCache.getCanDraw())
+ {
+ return true;
+ }
+
+ return count < kMinimumPrimitiveCounts[mode];
+}
+
+ANGLE_INLINE angle::Result Context::syncDirtyBits(Command command)
+{
+ const State::DirtyBits &dirtyBits = mState.getDirtyBits();
+ ANGLE_TRY(mImplementation->syncState(this, dirtyBits, mAllDirtyBits, command));
+ mState.clearDirtyBits();
+ return angle::Result::Continue;
+}
+
+ANGLE_INLINE angle::Result Context::syncDirtyBits(const State::DirtyBits &bitMask, Command command)
+{
+ const State::DirtyBits &dirtyBits = (mState.getDirtyBits() & bitMask);
+ ANGLE_TRY(mImplementation->syncState(this, dirtyBits, bitMask, command));
+ mState.clearDirtyBits(dirtyBits);
+ return angle::Result::Continue;
+}
+
+ANGLE_INLINE angle::Result Context::syncDirtyObjects(const State::DirtyObjects &objectMask,
+ Command command)
+{
+ return mState.syncDirtyObjects(this, objectMask, command);
+}
+
+ANGLE_INLINE angle::Result Context::prepareForDraw(PrimitiveMode mode)
+{
+ if (mGLES1Renderer)
+ {
+ ANGLE_TRY(mGLES1Renderer->prepareForDraw(mode, this, &mState));
+ }
+
+ ANGLE_TRY(syncDirtyObjects(mDrawDirtyObjects, Command::Draw));
+ ASSERT(!isRobustResourceInitEnabled() ||
+ !mState.getDrawFramebuffer()->hasResourceThatNeedsInit());
+ return syncDirtyBits(Command::Draw);
+}
+
+ANGLE_INLINE void Context::drawArrays(PrimitiveMode mode, GLint first, GLsizei count)
+{
+ // No-op if count draws no primitives for given mode
+ if (noopDraw(mode, count))
+ {
+ ANGLE_CONTEXT_TRY(mImplementation->handleNoopDrawEvent());
+ return;
+ }
+
+ ANGLE_CONTEXT_TRY(prepareForDraw(mode));
+ ANGLE_CONTEXT_TRY(mImplementation->drawArrays(this, mode, first, count));
+ MarkTransformFeedbackBufferUsage(this, count, 1);
+}
+
+ANGLE_INLINE void Context::drawElements(PrimitiveMode mode,
+ GLsizei count,
+ DrawElementsType type,
+ const void *indices)
+{
+ // No-op if count draws no primitives for given mode
+ if (noopDraw(mode, count))
+ {
+ ANGLE_CONTEXT_TRY(mImplementation->handleNoopDrawEvent());
+ return;
+ }
+
+ ANGLE_CONTEXT_TRY(prepareForDraw(mode));
+ ANGLE_CONTEXT_TRY(mImplementation->drawElements(this, mode, count, type, indices));
+}
+
+ANGLE_INLINE void StateCache::onBufferBindingChange(Context *context)
+{
+ updateBasicDrawStatesError();
+ updateBasicDrawElementsError();
+}
+
+ANGLE_INLINE void Context::bindBuffer(BufferBinding target, BufferID buffer)
+{
+ Buffer *bufferObject =
+ mState.mBufferManager->checkBufferAllocation(mImplementation.get(), buffer);
+
+ // Early return if rebinding the same buffer
+ if (bufferObject == mState.getTargetBuffer(target))
+ {
+ return;
+ }
+
+ mState.setBufferBinding(this, target, bufferObject);
+ mStateCache.onBufferBindingChange(this);
+}
+
+} // namespace gl
+
+#endif // LIBANGLE_CONTEXT_INL_H_
diff --git a/gfx/angle/checkout/src/libANGLE/Context_gl.cpp b/gfx/angle/checkout/src/libANGLE/Context_gl.cpp
new file mode 100644
index 0000000000..28f3685a20
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Context_gl.cpp
@@ -0,0 +1,3706 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml.
+//
+// Copyright 2019 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.
+//
+// Context_gl.cpp: Implements the GL specific parts of Context.
+
+#include "Context.h"
+#include "common/debug.h"
+
+namespace gl
+{
+
+void Context::compressedTexImage1D(GLenum target,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLint border,
+ GLsizei imageSize,
+ const void *data)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::compressedTexSubImage1D(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLsizei width,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::loadTransposeMatrixd(const GLdouble *m)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::loadTransposeMatrixf(const GLfloat *m)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multTransposeMatrixd(const GLdouble *m)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multTransposeMatrixf(const GLfloat *m)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multiTexCoord1d(GLenum target, GLdouble s)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multiTexCoord1dv(GLenum target, const GLdouble *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multiTexCoord1f(GLenum target, GLfloat s)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multiTexCoord1fv(GLenum target, const GLfloat *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multiTexCoord1i(GLenum target, GLint s)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multiTexCoord1iv(GLenum target, const GLint *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multiTexCoord1s(GLenum target, GLshort s)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multiTexCoord1sv(GLenum target, const GLshort *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multiTexCoord2d(GLenum target, GLdouble s, GLdouble t)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multiTexCoord2dv(GLenum target, const GLdouble *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multiTexCoord2f(GLenum target, GLfloat s, GLfloat t)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multiTexCoord2fv(GLenum target, const GLfloat *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multiTexCoord2i(GLenum target, GLint s, GLint t)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multiTexCoord2iv(GLenum target, const GLint *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multiTexCoord2s(GLenum target, GLshort s, GLshort t)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multiTexCoord2sv(GLenum target, const GLshort *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multiTexCoord3d(GLenum target, GLdouble s, GLdouble t, GLdouble r)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multiTexCoord3dv(GLenum target, const GLdouble *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multiTexCoord3f(GLenum target, GLfloat s, GLfloat t, GLfloat r)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multiTexCoord3fv(GLenum target, const GLfloat *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multiTexCoord3i(GLenum target, GLint s, GLint t, GLint r)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multiTexCoord3iv(GLenum target, const GLint *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multiTexCoord3s(GLenum target, GLshort s, GLshort t, GLshort r)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multiTexCoord3sv(GLenum target, const GLshort *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multiTexCoord4d(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multiTexCoord4dv(GLenum target, const GLdouble *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multiTexCoord4fv(GLenum target, const GLfloat *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multiTexCoord4i(GLenum target, GLint s, GLint t, GLint r, GLint q)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multiTexCoord4iv(GLenum target, const GLint *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multiTexCoord4s(GLenum target, GLshort s, GLshort t, GLshort r, GLshort q)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multiTexCoord4sv(GLenum target, const GLshort *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getVertexAttribdv(GLuint index, GLenum pname, GLdouble *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttrib1d(GLuint index, GLdouble x)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttrib1dv(GLuint index, const GLdouble *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttrib1s(GLuint index, GLshort x)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttrib1sv(GLuint index, const GLshort *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttrib2d(GLuint index, GLdouble x, GLdouble y)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttrib2dv(GLuint index, const GLdouble *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttrib2s(GLuint index, GLshort x, GLshort y)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttrib2sv(GLuint index, const GLshort *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttrib3d(GLuint index, GLdouble x, GLdouble y, GLdouble z)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttrib3dv(GLuint index, const GLdouble *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttrib3s(GLuint index, GLshort x, GLshort y, GLshort z)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttrib3sv(GLuint index, const GLshort *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttrib4Nbv(GLuint index, const GLbyte *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttrib4Niv(GLuint index, const GLint *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttrib4Nsv(GLuint index, const GLshort *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttrib4Nub(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttrib4Nubv(GLuint index, const GLubyte *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttrib4Nuiv(GLuint index, const GLuint *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttrib4Nusv(GLuint index, const GLushort *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttrib4bv(GLuint index, const GLbyte *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttrib4d(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttrib4dv(GLuint index, const GLdouble *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttrib4iv(GLuint index, const GLint *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttrib4s(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttrib4sv(GLuint index, const GLshort *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttrib4ubv(GLuint index, const GLubyte *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttrib4uiv(GLuint index, const GLuint *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttrib4usv(GLuint index, const GLushort *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::beginConditionalRender(GLuint id, GLenum mode)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::clampColor(GLenum target, GLenum clamp)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::endConditionalRender()
+{
+ UNIMPLEMENTED();
+}
+
+void Context::framebufferTexture1D(GLenum target,
+ GLenum attachment,
+ TextureTarget textarget,
+ TextureID texture,
+ GLint level)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttribI1i(GLuint index, GLint x)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttribI1iv(GLuint index, const GLint *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttribI1ui(GLuint index, GLuint x)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttribI1uiv(GLuint index, const GLuint *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttribI2i(GLuint index, GLint x, GLint y)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttribI2iv(GLuint index, const GLint *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttribI2ui(GLuint index, GLuint x, GLuint y)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttribI2uiv(GLuint index, const GLuint *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttribI3i(GLuint index, GLint x, GLint y, GLint z)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttribI3iv(GLuint index, const GLint *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttribI3ui(GLuint index, GLuint x, GLuint y, GLuint z)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttribI3uiv(GLuint index, const GLuint *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttribI4bv(GLuint index, const GLbyte *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttribI4sv(GLuint index, const GLshort *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttribI4ubv(GLuint index, const GLubyte *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttribI4usv(GLuint index, const GLushort *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getActiveUniformName(ShaderProgramID program,
+ GLuint uniformIndex,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *uniformName)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::primitiveRestartIndex(GLuint index)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::fogCoordPointer(GLenum type, GLsizei stride, const void *pointer)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::fogCoordd(GLdouble coord)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::fogCoorddv(const GLdouble *coord)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::fogCoordf(GLfloat coord)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::fogCoordfv(const GLfloat *coord)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::pointParameteri(GLenum pname, GLint param)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::pointParameteriv(GLenum pname, const GLint *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::secondaryColor3b(GLbyte red, GLbyte green, GLbyte blue)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::secondaryColor3bv(const GLbyte *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::secondaryColor3d(GLdouble red, GLdouble green, GLdouble blue)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::secondaryColor3dv(const GLdouble *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::secondaryColor3f(GLfloat red, GLfloat green, GLfloat blue)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::secondaryColor3fv(const GLfloat *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::secondaryColor3i(GLint red, GLint green, GLint blue)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::secondaryColor3iv(const GLint *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::secondaryColor3s(GLshort red, GLshort green, GLshort blue)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::secondaryColor3sv(const GLshort *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::secondaryColor3ub(GLubyte red, GLubyte green, GLubyte blue)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::secondaryColor3ubv(const GLubyte *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::secondaryColor3ui(GLuint red, GLuint green, GLuint blue)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::secondaryColor3uiv(const GLuint *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::secondaryColor3us(GLushort red, GLushort green, GLushort blue)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::secondaryColor3usv(const GLushort *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::secondaryColorPointer(GLint size, GLenum type, GLsizei stride, const void *pointer)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::windowPos2d(GLdouble x, GLdouble y)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::windowPos2dv(const GLdouble *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::windowPos2f(GLfloat x, GLfloat y)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::windowPos2fv(const GLfloat *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::windowPos2i(GLint x, GLint y)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::windowPos2iv(const GLint *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::windowPos2s(GLshort x, GLshort y)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::windowPos2sv(const GLshort *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::windowPos3d(GLdouble x, GLdouble y, GLdouble z)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::windowPos3dv(const GLdouble *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::windowPos3f(GLfloat x, GLfloat y, GLfloat z)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::windowPos3fv(const GLfloat *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::windowPos3i(GLint x, GLint y, GLint z)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::windowPos3iv(const GLint *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::windowPos3s(GLshort x, GLshort y, GLshort z)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::windowPos3sv(const GLshort *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, void *data)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::accum(GLenum op, GLfloat value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::begin(GLenum mode)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::bitmap(GLsizei width,
+ GLsizei height,
+ GLfloat xorig,
+ GLfloat yorig,
+ GLfloat xmove,
+ GLfloat ymove,
+ const GLubyte *bitmap)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::callList(GLuint list)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::callLists(GLsizei n, GLenum type, const void *lists)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::clearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::clearDepth(GLdouble depth)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::clearIndex(GLfloat c)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::clipPlane(GLenum plane, const GLdouble *equation)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::color3b(GLbyte red, GLbyte green, GLbyte blue)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::color3bv(const GLbyte *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::color3d(GLdouble red, GLdouble green, GLdouble blue)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::color3dv(const GLdouble *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::color3f(GLfloat red, GLfloat green, GLfloat blue)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::color3fv(const GLfloat *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::color3i(GLint red, GLint green, GLint blue)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::color3iv(const GLint *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::color3s(GLshort red, GLshort green, GLshort blue)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::color3sv(const GLshort *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::color3ub(GLubyte red, GLubyte green, GLubyte blue)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::color3ubv(const GLubyte *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::color3ui(GLuint red, GLuint green, GLuint blue)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::color3uiv(const GLuint *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::color3us(GLushort red, GLushort green, GLushort blue)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::color3usv(const GLushort *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::color4b(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::color4bv(const GLbyte *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::color4d(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::color4dv(const GLdouble *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::color4fv(const GLfloat *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::color4i(GLint red, GLint green, GLint blue, GLint alpha)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::color4iv(const GLint *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::color4s(GLshort red, GLshort green, GLshort blue, GLshort alpha)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::color4sv(const GLshort *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::color4ubv(const GLubyte *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::color4ui(GLuint red, GLuint green, GLuint blue, GLuint alpha)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::color4uiv(const GLuint *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::color4us(GLushort red, GLushort green, GLushort blue, GLushort alpha)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::color4usv(const GLushort *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::colorMaterial(GLenum face, GLenum mode)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::copyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::deleteLists(GLuint list, GLsizei range)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::depthRange(GLdouble n, GLdouble f)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::drawBuffer(GLenum buf)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::drawPixels(GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::edgeFlag(GLboolean flag)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::edgeFlagv(const GLboolean *flag)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::end()
+{
+ UNIMPLEMENTED();
+}
+
+void Context::endList()
+{
+ UNIMPLEMENTED();
+}
+
+void Context::evalCoord1d(GLdouble u)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::evalCoord1dv(const GLdouble *u)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::evalCoord1f(GLfloat u)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::evalCoord1fv(const GLfloat *u)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::evalCoord2d(GLdouble u, GLdouble v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::evalCoord2dv(const GLdouble *u)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::evalCoord2f(GLfloat u, GLfloat v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::evalCoord2fv(const GLfloat *u)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::evalMesh1(GLenum mode, GLint i1, GLint i2)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::evalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::evalPoint1(GLint i)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::evalPoint2(GLint i, GLint j)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::feedbackBuffer(GLsizei size, GLenum type, GLfloat *buffer)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::fogi(GLenum pname, GLint param)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::fogiv(GLenum pname, const GLint *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::frustum(GLdouble left,
+ GLdouble right,
+ GLdouble bottom,
+ GLdouble top,
+ GLdouble zNear,
+ GLdouble zFar)
+{
+ UNIMPLEMENTED();
+}
+
+GLuint Context::genLists(GLsizei range)
+{
+ UNIMPLEMENTED();
+ return 0;
+}
+
+void Context::getClipPlane(GLenum plane, GLdouble *equation)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getDoublev(GLenum pname, GLdouble *data)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getLightiv(GLenum light, GLenum pname, GLint *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getMapdv(GLenum target, GLenum query, GLdouble *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getMapfv(GLenum target, GLenum query, GLfloat *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getMapiv(GLenum target, GLenum query, GLint *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getMaterialiv(GLenum face, GLenum pname, GLint *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getPixelMapfv(GLenum map, GLfloat *values)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getPixelMapuiv(GLenum map, GLuint *values)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getPixelMapusv(GLenum map, GLushort *values)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getPolygonStipple(GLubyte *mask)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getTexGendv(GLenum coord, GLenum pname, GLdouble *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::indexMask(GLuint mask)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::indexd(GLdouble c)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::indexdv(const GLdouble *c)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::indexf(GLfloat c)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::indexfv(const GLfloat *c)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::indexi(GLint c)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::indexiv(const GLint *c)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::indexs(GLshort c)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::indexsv(const GLshort *c)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::initNames()
+{
+ UNIMPLEMENTED();
+}
+
+GLboolean Context::isList(GLuint list) const
+{
+ UNIMPLEMENTED();
+ return false;
+}
+
+void Context::lightModeli(GLenum pname, GLint param)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::lightModeliv(GLenum pname, const GLint *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::lighti(GLenum light, GLenum pname, GLint param)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::lightiv(GLenum light, GLenum pname, const GLint *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::lineStipple(GLint factor, GLushort pattern)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::listBase(GLuint base)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::loadMatrixd(const GLdouble *m)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::loadName(GLuint name)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::map1d(GLenum target,
+ GLdouble u1,
+ GLdouble u2,
+ GLint stride,
+ GLint order,
+ const GLdouble *points)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::map1f(GLenum target,
+ GLfloat u1,
+ GLfloat u2,
+ GLint stride,
+ GLint order,
+ const GLfloat *points)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::map2d(GLenum target,
+ GLdouble u1,
+ GLdouble u2,
+ GLint ustride,
+ GLint uorder,
+ GLdouble v1,
+ GLdouble v2,
+ GLint vstride,
+ GLint vorder,
+ const GLdouble *points)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::map2f(GLenum target,
+ GLfloat u1,
+ GLfloat u2,
+ GLint ustride,
+ GLint uorder,
+ GLfloat v1,
+ GLfloat v2,
+ GLint vstride,
+ GLint vorder,
+ const GLfloat *points)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::mapGrid1d(GLint un, GLdouble u1, GLdouble u2)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::mapGrid1f(GLint un, GLfloat u1, GLfloat u2)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::mapGrid2d(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::mapGrid2f(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::materiali(GLenum face, GLenum pname, GLint param)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::materialiv(GLenum face, GLenum pname, const GLint *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multMatrixd(const GLdouble *m)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::newList(GLuint list, GLenum mode)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::normal3b(GLbyte nx, GLbyte ny, GLbyte nz)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::normal3bv(const GLbyte *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::normal3d(GLdouble nx, GLdouble ny, GLdouble nz)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::normal3dv(const GLdouble *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::normal3fv(const GLfloat *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::normal3i(GLint nx, GLint ny, GLint nz)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::normal3iv(const GLint *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::normal3s(GLshort nx, GLshort ny, GLshort nz)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::normal3sv(const GLshort *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::ortho(GLdouble left,
+ GLdouble right,
+ GLdouble bottom,
+ GLdouble top,
+ GLdouble zNear,
+ GLdouble zFar)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::passThrough(GLfloat token)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::pixelMapfv(GLenum map, GLsizei mapsize, const GLfloat *values)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::pixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::pixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::pixelStoref(GLenum pname, GLfloat param)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::pixelTransferf(GLenum pname, GLfloat param)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::pixelTransferi(GLenum pname, GLint param)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::pixelZoom(GLfloat xfactor, GLfloat yfactor)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::polygonMode(GLenum face, GLenum mode)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::polygonStipple(const GLubyte *mask)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::popAttrib()
+{
+ UNIMPLEMENTED();
+}
+
+void Context::popName()
+{
+ UNIMPLEMENTED();
+}
+
+void Context::pushAttrib(GLbitfield mask)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::pushName(GLuint name)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::rasterPos2d(GLdouble x, GLdouble y)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::rasterPos2dv(const GLdouble *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::rasterPos2f(GLfloat x, GLfloat y)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::rasterPos2fv(const GLfloat *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::rasterPos2i(GLint x, GLint y)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::rasterPos2iv(const GLint *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::rasterPos2s(GLshort x, GLshort y)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::rasterPos2sv(const GLshort *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::rasterPos3d(GLdouble x, GLdouble y, GLdouble z)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::rasterPos3dv(const GLdouble *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::rasterPos3f(GLfloat x, GLfloat y, GLfloat z)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::rasterPos3fv(const GLfloat *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::rasterPos3i(GLint x, GLint y, GLint z)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::rasterPos3iv(const GLint *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::rasterPos3s(GLshort x, GLshort y, GLshort z)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::rasterPos3sv(const GLshort *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::rasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::rasterPos4dv(const GLdouble *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::rasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::rasterPos4fv(const GLfloat *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::rasterPos4i(GLint x, GLint y, GLint z, GLint w)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::rasterPos4iv(const GLint *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::rasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::rasterPos4sv(const GLshort *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::rectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::rectdv(const GLdouble *v1, const GLdouble *v2)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::rectfv(const GLfloat *v1, const GLfloat *v2)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::recti(GLint x1, GLint y1, GLint x2, GLint y2)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::rectiv(const GLint *v1, const GLint *v2)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::rects(GLshort x1, GLshort y1, GLshort x2, GLshort y2)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::rectsv(const GLshort *v1, const GLshort *v2)
+{
+ UNIMPLEMENTED();
+}
+
+GLint Context::renderMode(GLenum mode)
+{
+ UNIMPLEMENTED();
+ return 0;
+}
+
+void Context::rotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::scaled(GLdouble x, GLdouble y, GLdouble z)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::selectBuffer(GLsizei size, GLuint *buffer)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texCoord1d(GLdouble s)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texCoord1dv(const GLdouble *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texCoord1f(GLfloat s)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texCoord1fv(const GLfloat *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texCoord1i(GLint s)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texCoord1iv(const GLint *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texCoord1s(GLshort s)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texCoord1sv(const GLshort *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texCoord2d(GLdouble s, GLdouble t)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texCoord2dv(const GLdouble *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texCoord2f(GLfloat s, GLfloat t)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texCoord2fv(const GLfloat *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texCoord2i(GLint s, GLint t)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texCoord2iv(const GLint *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texCoord2s(GLshort s, GLshort t)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texCoord2sv(const GLshort *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texCoord3d(GLdouble s, GLdouble t, GLdouble r)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texCoord3dv(const GLdouble *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texCoord3f(GLfloat s, GLfloat t, GLfloat r)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texCoord3fv(const GLfloat *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texCoord3i(GLint s, GLint t, GLint r)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texCoord3iv(const GLint *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texCoord3s(GLshort s, GLshort t, GLshort r)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texCoord3sv(const GLshort *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texCoord4d(GLdouble s, GLdouble t, GLdouble r, GLdouble q)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texCoord4dv(const GLdouble *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texCoord4fv(const GLfloat *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texCoord4i(GLint s, GLint t, GLint r, GLint q)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texCoord4iv(const GLint *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texCoord4s(GLshort s, GLshort t, GLshort r, GLshort q)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texCoord4sv(const GLshort *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texGend(GLenum coord, GLenum pname, GLdouble param)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texGendv(GLenum coord, GLenum pname, const GLdouble *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texImage1D(GLenum target,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::translated(GLdouble x, GLdouble y, GLdouble z)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertex2d(GLdouble x, GLdouble y)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertex2dv(const GLdouble *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertex2f(GLfloat x, GLfloat y)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertex2fv(const GLfloat *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertex2i(GLint x, GLint y)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertex2iv(const GLint *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertex2s(GLshort x, GLshort y)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertex2sv(const GLshort *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertex3d(GLdouble x, GLdouble y, GLdouble z)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertex3dv(const GLdouble *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertex3f(GLfloat x, GLfloat y, GLfloat z)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertex3fv(const GLfloat *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertex3i(GLint x, GLint y, GLint z)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertex3iv(const GLint *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertex3s(GLshort x, GLshort y, GLshort z)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertex3sv(const GLshort *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertex4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertex4dv(const GLdouble *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertex4fv(const GLfloat *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertex4i(GLint x, GLint y, GLint z, GLint w)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertex4iv(const GLint *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertex4s(GLshort x, GLshort y, GLshort z, GLshort w)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertex4sv(const GLshort *v)
+{
+ UNIMPLEMENTED();
+}
+
+GLboolean Context::areTexturesResident(GLsizei n, const GLuint *textures, GLboolean *residences)
+{
+ UNIMPLEMENTED();
+ return false;
+}
+
+void Context::arrayElement(GLint i)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::copyTexImage1D(GLenum target,
+ GLint level,
+ GLenum internalformat,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLint border)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::copyTexSubImage1D(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint x,
+ GLint y,
+ GLsizei width)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::edgeFlagPointer(GLsizei stride, const void *pointer)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::indexPointer(GLenum type, GLsizei stride, const void *pointer)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::indexub(GLubyte c)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::indexubv(const GLubyte *c)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::interleavedArrays(GLenum format, GLsizei stride, const void *pointer)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::popClientAttrib()
+{
+ UNIMPLEMENTED();
+}
+
+void Context::prioritizeTextures(GLsizei n, const GLuint *textures, const GLfloat *priorities)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::pushClientAttrib(GLbitfield mask)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texSubImage1D(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLsizei width,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multiDrawElementsBaseVertex(PrimitiveMode mode,
+ const GLsizei *count,
+ DrawElementsType type,
+ const void *const *indices,
+ GLsizei drawcount,
+ const GLint *basevertex)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texImage2DMultisample(GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedsamplelocations)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texImage3DMultisample(GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean fixedsamplelocations)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::colorP3ui(GLenum type, GLuint color)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::colorP3uiv(GLenum type, const GLuint *color)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::colorP4ui(GLenum type, GLuint color)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::colorP4uiv(GLenum type, const GLuint *color)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multiTexCoordP1ui(GLenum texture, GLenum type, GLuint coords)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multiTexCoordP1uiv(GLenum texture, GLenum type, const GLuint *coords)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multiTexCoordP2ui(GLenum texture, GLenum type, GLuint coords)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multiTexCoordP2uiv(GLenum texture, GLenum type, const GLuint *coords)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multiTexCoordP3ui(GLenum texture, GLenum type, GLuint coords)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multiTexCoordP3uiv(GLenum texture, GLenum type, const GLuint *coords)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multiTexCoordP4ui(GLenum texture, GLenum type, GLuint coords)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multiTexCoordP4uiv(GLenum texture, GLenum type, const GLuint *coords)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::normalP3ui(GLenum type, GLuint coords)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::normalP3uiv(GLenum type, const GLuint *coords)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::secondaryColorP3ui(GLenum type, GLuint color)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::secondaryColorP3uiv(GLenum type, const GLuint *color)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texCoordP1ui(GLenum type, GLuint coords)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texCoordP1uiv(GLenum type, const GLuint *coords)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texCoordP2ui(GLenum type, GLuint coords)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texCoordP2uiv(GLenum type, const GLuint *coords)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texCoordP3ui(GLenum type, GLuint coords)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texCoordP3uiv(GLenum type, const GLuint *coords)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texCoordP4ui(GLenum type, GLuint coords)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texCoordP4uiv(GLenum type, const GLuint *coords)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttribP1ui(GLuint index, GLenum type, GLboolean normalized, GLuint value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttribP1uiv(GLuint index,
+ GLenum type,
+ GLboolean normalized,
+ const GLuint *value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttribP2ui(GLuint index, GLenum type, GLboolean normalized, GLuint value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttribP2uiv(GLuint index,
+ GLenum type,
+ GLboolean normalized,
+ const GLuint *value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttribP3ui(GLuint index, GLenum type, GLboolean normalized, GLuint value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttribP3uiv(GLuint index,
+ GLenum type,
+ GLboolean normalized,
+ const GLuint *value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttribP4ui(GLuint index, GLenum type, GLboolean normalized, GLuint value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttribP4uiv(GLuint index,
+ GLenum type,
+ GLboolean normalized,
+ const GLuint *value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexP2ui(GLenum type, GLuint value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexP2uiv(GLenum type, const GLuint *value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexP3ui(GLenum type, GLuint value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexP3uiv(GLenum type, const GLuint *value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexP4ui(GLenum type, GLuint value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexP4uiv(GLenum type, const GLuint *value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::beginQueryIndexed(GLenum target, GLuint index, QueryID id)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::drawTransformFeedback(GLenum mode, TransformFeedbackID id)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::drawTransformFeedbackStream(GLenum mode, TransformFeedbackID id, GLuint stream)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::endQueryIndexed(GLenum target, GLuint index)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getActiveSubroutineName(ShaderProgramID program,
+ GLenum shadertype,
+ GLuint index,
+ GLsizei bufsize,
+ GLsizei *length,
+ GLchar *name)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getActiveSubroutineUniformName(ShaderProgramID program,
+ GLenum shadertype,
+ GLuint index,
+ GLsizei bufsize,
+ GLsizei *length,
+ GLchar *name)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getActiveSubroutineUniformiv(ShaderProgramID program,
+ GLenum shadertype,
+ GLuint index,
+ GLenum pname,
+ GLint *values)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getProgramStageiv(ShaderProgramID program,
+ GLenum shadertype,
+ GLenum pname,
+ GLint *values)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getQueryIndexediv(GLenum target, GLuint index, GLenum pname, GLint *params)
+{
+ UNIMPLEMENTED();
+}
+
+GLuint Context::getSubroutineIndex(ShaderProgramID program, GLenum shadertype, const GLchar *name)
+{
+ UNIMPLEMENTED();
+ return 0;
+}
+
+GLint Context::getSubroutineUniformLocation(ShaderProgramID program,
+ GLenum shadertype,
+ const GLchar *name)
+{
+ UNIMPLEMENTED();
+ return 0;
+}
+
+void Context::getUniformSubroutineuiv(GLenum shadertype, GLint location, GLuint *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getUniformdv(ShaderProgramID program, UniformLocation location, GLdouble *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::patchParameterfv(GLenum pname, const GLfloat *values)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::uniform1d(UniformLocation location, GLdouble x)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::uniform1dv(UniformLocation location, GLsizei count, const GLdouble *value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::uniform2d(UniformLocation location, GLdouble x, GLdouble y)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::uniform2dv(UniformLocation location, GLsizei count, const GLdouble *value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::uniform3d(UniformLocation location, GLdouble x, GLdouble y, GLdouble z)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::uniform3dv(UniformLocation location, GLsizei count, const GLdouble *value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::uniform4d(UniformLocation location, GLdouble x, GLdouble y, GLdouble z, GLdouble w)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::uniform4dv(UniformLocation location, GLsizei count, const GLdouble *value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::uniformMatrix2dv(UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::uniformMatrix2x3dv(UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::uniformMatrix2x4dv(UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::uniformMatrix3dv(UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::uniformMatrix3x2dv(UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::uniformMatrix3x4dv(UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::uniformMatrix4dv(UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::uniformMatrix4x2dv(UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::uniformMatrix4x3dv(UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::uniformSubroutinesuiv(GLenum shadertype, GLsizei count, const GLuint *indices)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::depthRangeArrayv(GLuint first, GLsizei count, const GLdouble *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::depthRangeIndexed(GLuint index, GLdouble n, GLdouble f)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getDoublei_v(GLenum target, GLuint index, GLdouble *data)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getFloati_v(GLenum target, GLuint index, GLfloat *data)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getVertexAttribLdv(GLuint index, GLenum pname, GLdouble *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::programUniform1d(ShaderProgramID program, UniformLocation location, GLdouble v0)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::programUniform1dv(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ const GLdouble *value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::programUniform2d(ShaderProgramID program,
+ UniformLocation location,
+ GLdouble v0,
+ GLdouble v1)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::programUniform2dv(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ const GLdouble *value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::programUniform3d(ShaderProgramID program,
+ UniformLocation location,
+ GLdouble v0,
+ GLdouble v1,
+ GLdouble v2)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::programUniform3dv(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ const GLdouble *value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::programUniform4d(ShaderProgramID program,
+ UniformLocation location,
+ GLdouble v0,
+ GLdouble v1,
+ GLdouble v2,
+ GLdouble v3)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::programUniform4dv(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ const GLdouble *value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::programUniformMatrix2dv(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::programUniformMatrix2x3dv(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::programUniformMatrix2x4dv(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::programUniformMatrix3dv(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::programUniformMatrix3x2dv(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::programUniformMatrix3x4dv(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::programUniformMatrix4dv(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::programUniformMatrix4x2dv(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::programUniformMatrix4x3dv(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::scissorArrayv(GLuint first, GLsizei count, const GLint *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::scissorIndexed(GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::scissorIndexedv(GLuint index, const GLint *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttribL1d(GLuint index, GLdouble x)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttribL1dv(GLuint index, const GLdouble *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttribL2d(GLuint index, GLdouble x, GLdouble y)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttribL2dv(GLuint index, const GLdouble *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttribL3d(GLuint index, GLdouble x, GLdouble y, GLdouble z)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttribL3dv(GLuint index, const GLdouble *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttribL4d(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttribL4dv(GLuint index, const GLdouble *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttribLPointer(GLuint index,
+ GLint size,
+ GLenum type,
+ GLsizei stride,
+ const void *pointer)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::viewportArrayv(GLuint first, GLsizei count, const GLfloat *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::viewportIndexedf(GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::viewportIndexedfv(GLuint index, const GLfloat *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::drawTransformFeedbackInstanced(GLenum mode,
+ TransformFeedbackID id,
+ GLsizei instancecount)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::drawTransformFeedbackStreamInstanced(GLenum mode,
+ TransformFeedbackID id,
+ GLuint stream,
+ GLsizei instancecount)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getActiveAtomicCounterBufferiv(ShaderProgramID program,
+ GLuint bufferIndex,
+ GLenum pname,
+ GLint *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::clearBufferData(GLenum target,
+ GLenum internalformat,
+ GLenum format,
+ GLenum type,
+ const void *data)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::clearBufferSubData(GLenum target,
+ GLenum internalformat,
+ GLintptr offset,
+ GLsizeiptr size,
+ GLenum format,
+ GLenum type,
+ const void *data)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getInternalformati64v(GLenum target,
+ GLenum internalformat,
+ GLenum pname,
+ GLsizei bufSize,
+ GLint64 *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::invalidateBufferData(BufferID buffer)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::invalidateBufferSubData(BufferID buffer, GLintptr offset, GLsizeiptr length)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::invalidateTexImage(TextureID texture, GLint level)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::invalidateTexSubImage(TextureID texture,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::shaderStorageBlockBinding(ShaderProgramID program,
+ GLuint storageBlockIndex,
+ GLuint storageBlockBinding)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::textureView(TextureID texture,
+ GLenum target,
+ GLuint origtexture,
+ GLenum internalformat,
+ GLuint minlevel,
+ GLuint numlevels,
+ GLuint minlayer,
+ GLuint numlayers)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexAttribLFormat(GLuint attribindex,
+ GLint size,
+ GLenum type,
+ GLuint relativeoffset)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::bindBuffersBase(GLenum target, GLuint first, GLsizei count, const BufferID *buffers)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::bindBuffersRange(GLenum target,
+ GLuint first,
+ GLsizei count,
+ const BufferID *buffers,
+ const GLintptr *offsets,
+ const GLsizeiptr *sizes)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::bindImageTextures(GLuint first, GLsizei count, const GLuint *textures)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::bindSamplers(GLuint first, GLsizei count, const GLuint *samplers)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::bindTextures(GLuint first, GLsizei count, const GLuint *textures)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::bindVertexBuffers(GLuint first,
+ GLsizei count,
+ const BufferID *buffers,
+ const GLintptr *offsets,
+ const GLsizei *strides)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::clearTexImage(TextureID texture,
+ GLint level,
+ GLenum format,
+ GLenum type,
+ const void *data)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::clearTexSubImage(TextureID texture,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ const void *data)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::bindTextureUnit(GLuint unit, TextureID texture)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::blitNamedFramebuffer(GLuint readFramebuffer,
+ GLuint drawFramebuffer,
+ GLint srcX0,
+ GLint srcY0,
+ GLint srcX1,
+ GLint srcY1,
+ GLint dstX0,
+ GLint dstY0,
+ GLint dstX1,
+ GLint dstY1,
+ GLbitfield mask,
+ GLenum filter)
+{
+ UNIMPLEMENTED();
+}
+
+GLenum Context::checkNamedFramebufferStatus(FramebufferID framebuffer, GLenum target)
+{
+ UNIMPLEMENTED();
+ return 0;
+}
+
+void Context::clearNamedBufferData(BufferID buffer,
+ GLenum internalformat,
+ GLenum format,
+ GLenum type,
+ const void *data)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::clearNamedBufferSubData(BufferID buffer,
+ GLenum internalformat,
+ GLintptr offset,
+ GLsizeiptr size,
+ GLenum format,
+ GLenum type,
+ const void *data)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::clearNamedFramebufferfi(FramebufferID framebuffer,
+ GLenum buffer,
+ GLint drawbuffer,
+ GLfloat depth,
+ GLint stencil)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::clearNamedFramebufferfv(FramebufferID framebuffer,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLfloat *value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::clearNamedFramebufferiv(FramebufferID framebuffer,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLint *value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::clearNamedFramebufferuiv(FramebufferID framebuffer,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLuint *value)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::compressedTextureSubImage1D(TextureID texture,
+ GLint level,
+ GLint xoffset,
+ GLsizei width,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::compressedTextureSubImage2D(TextureID texture,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::compressedTextureSubImage3D(TextureID texture,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::copyNamedBufferSubData(GLuint readBuffer,
+ GLuint writeBuffer,
+ GLintptr readOffset,
+ GLintptr writeOffset,
+ GLsizeiptr size)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::copyTextureSubImage1D(TextureID texture,
+ GLint level,
+ GLint xoffset,
+ GLint x,
+ GLint y,
+ GLsizei width)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::copyTextureSubImage2D(TextureID texture,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::copyTextureSubImage3D(TextureID texture,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::createBuffers(GLsizei n, BufferID *buffers)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::createFramebuffers(GLsizei n, GLuint *framebuffers)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::createProgramPipelines(GLsizei n, GLuint *pipelines)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::createQueries(GLenum target, GLsizei n, GLuint *ids)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::createRenderbuffers(GLsizei n, RenderbufferID *renderbuffers)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::createSamplers(GLsizei n, GLuint *samplers)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::createTextures(GLenum target, GLsizei n, GLuint *textures)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::createTransformFeedbacks(GLsizei n, GLuint *ids)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::createVertexArrays(GLsizei n, VertexArrayID *arrays)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::disableVertexArrayAttrib(VertexArrayID vaobj, GLuint index)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::enableVertexArrayAttrib(VertexArrayID vaobj, GLuint index)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::flushMappedNamedBufferRange(BufferID buffer, GLintptr offset, GLsizeiptr length)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::generateTextureMipmap(TextureID texture)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getCompressedTextureImage(TextureID texture,
+ GLint level,
+ GLsizei bufSize,
+ void *pixels)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getCompressedTextureSubImage(TextureID texture,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLsizei bufSize,
+ void *pixels)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getNamedBufferParameteri64v(BufferID buffer, GLenum pname, GLint64 *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getNamedBufferParameteriv(BufferID buffer, GLenum pname, GLint *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getNamedBufferPointerv(BufferID buffer, GLenum pname, void **params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getNamedBufferSubData(BufferID buffer, GLintptr offset, GLsizeiptr size, void *data)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getNamedFramebufferAttachmentParameteriv(FramebufferID framebuffer,
+ GLenum attachment,
+ GLenum pname,
+ GLint *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getNamedFramebufferParameteriv(FramebufferID framebuffer, GLenum pname, GLint *param)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getNamedRenderbufferParameteriv(RenderbufferID renderbuffer,
+ GLenum pname,
+ GLint *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getQueryBufferObjecti64v(GLuint id, BufferID buffer, GLenum pname, GLintptr offset)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getQueryBufferObjectiv(GLuint id, BufferID buffer, GLenum pname, GLintptr offset)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getQueryBufferObjectui64v(GLuint id, BufferID buffer, GLenum pname, GLintptr offset)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getQueryBufferObjectuiv(GLuint id, BufferID buffer, GLenum pname, GLintptr offset)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getTextureImage(TextureID texture,
+ GLint level,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ void *pixels)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getTextureLevelParameterfv(TextureID texture,
+ GLint level,
+ GLenum pname,
+ GLfloat *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getTextureLevelParameteriv(TextureID texture,
+ GLint level,
+ GLenum pname,
+ GLint *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getTextureParameterIiv(TextureID texture, GLenum pname, GLint *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getTextureParameterIuiv(TextureID texture, GLenum pname, GLuint *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getTextureParameterfv(TextureID texture, GLenum pname, GLfloat *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getTextureParameteriv(TextureID texture, GLenum pname, GLint *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getTextureSubImage(TextureID texture,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ void *pixels)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getTransformFeedbacki64_v(GLuint xfb, GLenum pname, GLuint index, GLint64 *param)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getTransformFeedbacki_v(GLuint xfb, GLenum pname, GLuint index, GLint *param)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getTransformFeedbackiv(GLuint xfb, GLenum pname, GLint *param)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getVertexArrayIndexed64iv(VertexArrayID vaobj,
+ GLuint index,
+ GLenum pname,
+ GLint64 *param)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getVertexArrayIndexediv(VertexArrayID vaobj, GLuint index, GLenum pname, GLint *param)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getVertexArrayiv(VertexArrayID vaobj, GLenum pname, GLint *param)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getnColorTable(GLenum target,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ void *table)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getnCompressedTexImage(GLenum target, GLint lod, GLsizei bufSize, void *pixels)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getnConvolutionFilter(GLenum target,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ void *image)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getnHistogram(GLenum target,
+ GLboolean reset,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ void *values)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getnMapdv(GLenum target, GLenum query, GLsizei bufSize, GLdouble *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getnMapfv(GLenum target, GLenum query, GLsizei bufSize, GLfloat *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getnMapiv(GLenum target, GLenum query, GLsizei bufSize, GLint *v)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getnMinmax(GLenum target,
+ GLboolean reset,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ void *values)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getnPixelMapfv(GLenum map, GLsizei bufSize, GLfloat *values)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getnPixelMapuiv(GLenum map, GLsizei bufSize, GLuint *values)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getnPixelMapusv(GLenum map, GLsizei bufSize, GLushort *values)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getnPolygonStipple(GLsizei bufSize, GLubyte *pattern)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getnSeparableFilter(GLenum target,
+ GLenum format,
+ GLenum type,
+ GLsizei rowBufSize,
+ void *row,
+ GLsizei columnBufSize,
+ void *column,
+ void *span)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getnTexImage(GLenum target,
+ GLint level,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ void *pixels)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getnUniformdv(ShaderProgramID program,
+ UniformLocation location,
+ GLsizei bufSize,
+ GLdouble *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::invalidateNamedFramebufferData(FramebufferID framebuffer,
+ GLsizei numAttachments,
+ const GLenum *attachments)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::invalidateNamedFramebufferSubData(FramebufferID framebuffer,
+ GLsizei numAttachments,
+ const GLenum *attachments,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height)
+{
+ UNIMPLEMENTED();
+}
+
+void *Context::mapNamedBuffer(BufferID buffer, GLenum access)
+{
+ UNIMPLEMENTED();
+ return nullptr;
+}
+
+void *Context::mapNamedBufferRange(BufferID buffer,
+ GLintptr offset,
+ GLsizeiptr length,
+ GLbitfield access)
+{
+ UNIMPLEMENTED();
+ return nullptr;
+}
+
+void Context::namedBufferData(BufferID buffer, GLsizeiptr size, const void *data, GLenum usage)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::namedBufferStorage(BufferID buffer,
+ GLsizeiptr size,
+ const void *data,
+ GLbitfield flags)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::namedBufferSubData(BufferID buffer,
+ GLintptr offset,
+ GLsizeiptr size,
+ const void *data)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::namedFramebufferDrawBuffer(FramebufferID framebuffer, GLenum buf)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::namedFramebufferDrawBuffers(FramebufferID framebuffer, GLsizei n, const GLenum *bufs)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::namedFramebufferParameteri(FramebufferID framebuffer, GLenum pname, GLint param)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::namedFramebufferReadBuffer(FramebufferID framebuffer, GLenum src)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::namedFramebufferRenderbuffer(FramebufferID framebuffer,
+ GLenum attachment,
+ GLenum renderbuffertarget,
+ RenderbufferID renderbuffer)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::namedFramebufferTexture(FramebufferID framebuffer,
+ GLenum attachment,
+ TextureID texture,
+ GLint level)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::namedFramebufferTextureLayer(FramebufferID framebuffer,
+ GLenum attachment,
+ TextureID texture,
+ GLint level,
+ GLint layer)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::namedRenderbufferStorage(RenderbufferID renderbuffer,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::namedRenderbufferStorageMultisample(RenderbufferID renderbuffer,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::textureBarrier()
+{
+ UNIMPLEMENTED();
+}
+
+void Context::textureBuffer(TextureID texture, GLenum internalformat, BufferID buffer)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::textureBufferRange(TextureID texture,
+ GLenum internalformat,
+ BufferID buffer,
+ GLintptr offset,
+ GLsizeiptr size)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::textureParameterIiv(TextureID texture, GLenum pname, const GLint *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::textureParameterIuiv(TextureID texture, GLenum pname, const GLuint *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::textureParameterf(TextureID texture, GLenum pname, GLfloat param)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::textureParameterfv(TextureID texture, GLenum pname, const GLfloat *param)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::textureParameteri(TextureID texture, GLenum pname, GLint param)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::textureParameteriv(TextureID texture, GLenum pname, const GLint *param)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::textureStorage1D(TextureID texture,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::textureStorage2D(TextureID texture,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::textureStorage2DMultisample(TextureID texture,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedsamplelocations)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::textureStorage3D(TextureID texture,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::textureStorage3DMultisample(TextureID texture,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean fixedsamplelocations)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::textureSubImage1D(TextureID texture,
+ GLint level,
+ GLint xoffset,
+ GLsizei width,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::textureSubImage2D(TextureID texture,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::textureSubImage3D(TextureID texture,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::transformFeedbackBufferBase(GLuint xfb, GLuint index, BufferID buffer)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::transformFeedbackBufferRange(GLuint xfb,
+ GLuint index,
+ BufferID buffer,
+ GLintptr offset,
+ GLsizeiptr size)
+{
+ UNIMPLEMENTED();
+}
+
+GLboolean Context::unmapNamedBuffer(BufferID buffer)
+{
+ UNIMPLEMENTED();
+ return false;
+}
+
+void Context::vertexArrayAttribBinding(VertexArrayID vaobj, GLuint attribindex, GLuint bindingindex)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexArrayAttribFormat(VertexArrayID vaobj,
+ GLuint attribindex,
+ GLint size,
+ GLenum type,
+ GLboolean normalized,
+ GLuint relativeoffset)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexArrayAttribIFormat(VertexArrayID vaobj,
+ GLuint attribindex,
+ GLint size,
+ GLenum type,
+ GLuint relativeoffset)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexArrayAttribLFormat(VertexArrayID vaobj,
+ GLuint attribindex,
+ GLint size,
+ GLenum type,
+ GLuint relativeoffset)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexArrayBindingDivisor(VertexArrayID vaobj, GLuint bindingindex, GLuint divisor)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexArrayElementBuffer(VertexArrayID vaobj, BufferID buffer)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexArrayVertexBuffer(VertexArrayID vaobj,
+ GLuint bindingindex,
+ BufferID buffer,
+ GLintptr offset,
+ GLsizei stride)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::vertexArrayVertexBuffers(VertexArrayID vaobj,
+ GLuint first,
+ GLsizei count,
+ const BufferID *buffers,
+ const GLintptr *offsets,
+ const GLsizei *strides)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multiDrawArraysIndirectCount(GLenum mode,
+ const void *indirect,
+ GLintptr drawcount,
+ GLsizei maxdrawcount,
+ GLsizei stride)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::multiDrawElementsIndirectCount(GLenum mode,
+ GLenum type,
+ const void *indirect,
+ GLintptr drawcount,
+ GLsizei maxdrawcount,
+ GLsizei stride)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::polygonOffsetClamp(GLfloat factor, GLfloat units, GLfloat clamp)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::specializeShader(GLuint shader,
+ const GLchar *pEntryPoint,
+ GLuint numSpecializationConstants,
+ const GLuint *pConstantIndex,
+ const GLuint *pConstantValue)
+{
+ UNIMPLEMENTED();
+}
+
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/Context_gl_1_autogen.h b/gfx/angle/checkout/src/libANGLE/Context_gl_1_autogen.h
new file mode 100644
index 0000000000..7bddff4c34
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Context_gl_1_autogen.h
@@ -0,0 +1,349 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml.
+//
+// Copyright 2020 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.
+//
+// Context_gl_1_autogen.h: Creates a macro for interfaces in Context.
+
+#ifndef ANGLE_CONTEXT_GL_1_AUTOGEN_H_
+#define ANGLE_CONTEXT_GL_1_AUTOGEN_H_
+
+#define ANGLE_GL_1_CONTEXT_API \
+ void accum(GLenum op, GLfloat value); \
+ void begin(GLenum mode); \
+ void bitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, \
+ GLfloat ymove, const GLubyte *bitmap); \
+ void callList(GLuint list); \
+ void callLists(GLsizei n, GLenum type, const void *lists); \
+ void clearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); \
+ void clearDepth(GLdouble depth); \
+ void clearIndex(GLfloat c); \
+ void clipPlane(GLenum plane, const GLdouble *equation); \
+ void color3b(GLbyte red, GLbyte green, GLbyte blue); \
+ void color3bv(const GLbyte *v); \
+ void color3d(GLdouble red, GLdouble green, GLdouble blue); \
+ void color3dv(const GLdouble *v); \
+ void color3f(GLfloat red, GLfloat green, GLfloat blue); \
+ void color3fv(const GLfloat *v); \
+ void color3i(GLint red, GLint green, GLint blue); \
+ void color3iv(const GLint *v); \
+ void color3s(GLshort red, GLshort green, GLshort blue); \
+ void color3sv(const GLshort *v); \
+ void color3ub(GLubyte red, GLubyte green, GLubyte blue); \
+ void color3ubv(const GLubyte *v); \
+ void color3ui(GLuint red, GLuint green, GLuint blue); \
+ void color3uiv(const GLuint *v); \
+ void color3us(GLushort red, GLushort green, GLushort blue); \
+ void color3usv(const GLushort *v); \
+ void color4b(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); \
+ void color4bv(const GLbyte *v); \
+ void color4d(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); \
+ void color4dv(const GLdouble *v); \
+ void color4fv(const GLfloat *v); \
+ void color4i(GLint red, GLint green, GLint blue, GLint alpha); \
+ void color4iv(const GLint *v); \
+ void color4s(GLshort red, GLshort green, GLshort blue, GLshort alpha); \
+ void color4sv(const GLshort *v); \
+ void color4ubv(const GLubyte *v); \
+ void color4ui(GLuint red, GLuint green, GLuint blue, GLuint alpha); \
+ void color4uiv(const GLuint *v); \
+ void color4us(GLushort red, GLushort green, GLushort blue, GLushort alpha); \
+ void color4usv(const GLushort *v); \
+ void colorMaterial(GLenum face, GLenum mode); \
+ void copyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); \
+ void deleteLists(GLuint list, GLsizei range); \
+ void depthRange(GLdouble n, GLdouble f); \
+ void drawBuffer(GLenum buf); \
+ void drawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, \
+ const void *pixels); \
+ void edgeFlag(GLboolean flag); \
+ void edgeFlagv(const GLboolean *flag); \
+ void end(); \
+ void endList(); \
+ void evalCoord1d(GLdouble u); \
+ void evalCoord1dv(const GLdouble *u); \
+ void evalCoord1f(GLfloat u); \
+ void evalCoord1fv(const GLfloat *u); \
+ void evalCoord2d(GLdouble u, GLdouble v); \
+ void evalCoord2dv(const GLdouble *u); \
+ void evalCoord2f(GLfloat u, GLfloat v); \
+ void evalCoord2fv(const GLfloat *u); \
+ void evalMesh1(GLenum mode, GLint i1, GLint i2); \
+ void evalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); \
+ void evalPoint1(GLint i); \
+ void evalPoint2(GLint i, GLint j); \
+ void feedbackBuffer(GLsizei size, GLenum type, GLfloat *buffer); \
+ void fogi(GLenum pname, GLint param); \
+ void fogiv(GLenum pname, const GLint *params); \
+ void frustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, \
+ GLdouble zFar); \
+ GLuint genLists(GLsizei range); \
+ void getClipPlane(GLenum plane, GLdouble *equation); \
+ void getDoublev(GLenum pname, GLdouble *data); \
+ void getLightiv(GLenum light, GLenum pname, GLint *params); \
+ void getMapdv(GLenum target, GLenum query, GLdouble *v); \
+ void getMapfv(GLenum target, GLenum query, GLfloat *v); \
+ void getMapiv(GLenum target, GLenum query, GLint *v); \
+ void getMaterialiv(GLenum face, GLenum pname, GLint *params); \
+ void getPixelMapfv(GLenum map, GLfloat *values); \
+ void getPixelMapuiv(GLenum map, GLuint *values); \
+ void getPixelMapusv(GLenum map, GLushort *values); \
+ void getPolygonStipple(GLubyte *mask); \
+ void getTexGendv(GLenum coord, GLenum pname, GLdouble *params); \
+ void indexMask(GLuint mask); \
+ void indexd(GLdouble c); \
+ void indexdv(const GLdouble *c); \
+ void indexf(GLfloat c); \
+ void indexfv(const GLfloat *c); \
+ void indexi(GLint c); \
+ void indexiv(const GLint *c); \
+ void indexs(GLshort c); \
+ void indexsv(const GLshort *c); \
+ void initNames(); \
+ GLboolean isList(GLuint list) const; \
+ void lightModeli(GLenum pname, GLint param); \
+ void lightModeliv(GLenum pname, const GLint *params); \
+ void lighti(GLenum light, GLenum pname, GLint param); \
+ void lightiv(GLenum light, GLenum pname, const GLint *params); \
+ void lineStipple(GLint factor, GLushort pattern); \
+ void listBase(GLuint base); \
+ void loadMatrixd(const GLdouble *m); \
+ void loadName(GLuint name); \
+ void map1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, \
+ const GLdouble *points); \
+ void map1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, \
+ const GLfloat *points); \
+ void map2d(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, \
+ GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); \
+ void map2f(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, \
+ GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); \
+ void mapGrid1d(GLint un, GLdouble u1, GLdouble u2); \
+ void mapGrid1f(GLint un, GLfloat u1, GLfloat u2); \
+ void mapGrid2d(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); \
+ void mapGrid2f(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); \
+ void materiali(GLenum face, GLenum pname, GLint param); \
+ void materialiv(GLenum face, GLenum pname, const GLint *params); \
+ void multMatrixd(const GLdouble *m); \
+ void newList(GLuint list, GLenum mode); \
+ void normal3b(GLbyte nx, GLbyte ny, GLbyte nz); \
+ void normal3bv(const GLbyte *v); \
+ void normal3d(GLdouble nx, GLdouble ny, GLdouble nz); \
+ void normal3dv(const GLdouble *v); \
+ void normal3fv(const GLfloat *v); \
+ void normal3i(GLint nx, GLint ny, GLint nz); \
+ void normal3iv(const GLint *v); \
+ void normal3s(GLshort nx, GLshort ny, GLshort nz); \
+ void normal3sv(const GLshort *v); \
+ void ortho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, \
+ GLdouble zFar); \
+ void passThrough(GLfloat token); \
+ void pixelMapfv(GLenum map, GLsizei mapsize, const GLfloat *values); \
+ void pixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values); \
+ void pixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values); \
+ void pixelStoref(GLenum pname, GLfloat param); \
+ void pixelTransferf(GLenum pname, GLfloat param); \
+ void pixelTransferi(GLenum pname, GLint param); \
+ void pixelZoom(GLfloat xfactor, GLfloat yfactor); \
+ void polygonMode(GLenum face, GLenum mode); \
+ void polygonStipple(const GLubyte *mask); \
+ void popAttrib(); \
+ void popName(); \
+ void pushAttrib(GLbitfield mask); \
+ void pushName(GLuint name); \
+ void rasterPos2d(GLdouble x, GLdouble y); \
+ void rasterPos2dv(const GLdouble *v); \
+ void rasterPos2f(GLfloat x, GLfloat y); \
+ void rasterPos2fv(const GLfloat *v); \
+ void rasterPos2i(GLint x, GLint y); \
+ void rasterPos2iv(const GLint *v); \
+ void rasterPos2s(GLshort x, GLshort y); \
+ void rasterPos2sv(const GLshort *v); \
+ void rasterPos3d(GLdouble x, GLdouble y, GLdouble z); \
+ void rasterPos3dv(const GLdouble *v); \
+ void rasterPos3f(GLfloat x, GLfloat y, GLfloat z); \
+ void rasterPos3fv(const GLfloat *v); \
+ void rasterPos3i(GLint x, GLint y, GLint z); \
+ void rasterPos3iv(const GLint *v); \
+ void rasterPos3s(GLshort x, GLshort y, GLshort z); \
+ void rasterPos3sv(const GLshort *v); \
+ void rasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w); \
+ void rasterPos4dv(const GLdouble *v); \
+ void rasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w); \
+ void rasterPos4fv(const GLfloat *v); \
+ void rasterPos4i(GLint x, GLint y, GLint z, GLint w); \
+ void rasterPos4iv(const GLint *v); \
+ void rasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w); \
+ void rasterPos4sv(const GLshort *v); \
+ void rectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); \
+ void rectdv(const GLdouble *v1, const GLdouble *v2); \
+ void rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); \
+ void rectfv(const GLfloat *v1, const GLfloat *v2); \
+ void recti(GLint x1, GLint y1, GLint x2, GLint y2); \
+ void rectiv(const GLint *v1, const GLint *v2); \
+ void rects(GLshort x1, GLshort y1, GLshort x2, GLshort y2); \
+ void rectsv(const GLshort *v1, const GLshort *v2); \
+ GLint renderMode(GLenum mode); \
+ void rotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z); \
+ void scaled(GLdouble x, GLdouble y, GLdouble z); \
+ void selectBuffer(GLsizei size, GLuint *buffer); \
+ void texCoord1d(GLdouble s); \
+ void texCoord1dv(const GLdouble *v); \
+ void texCoord1f(GLfloat s); \
+ void texCoord1fv(const GLfloat *v); \
+ void texCoord1i(GLint s); \
+ void texCoord1iv(const GLint *v); \
+ void texCoord1s(GLshort s); \
+ void texCoord1sv(const GLshort *v); \
+ void texCoord2d(GLdouble s, GLdouble t); \
+ void texCoord2dv(const GLdouble *v); \
+ void texCoord2f(GLfloat s, GLfloat t); \
+ void texCoord2fv(const GLfloat *v); \
+ void texCoord2i(GLint s, GLint t); \
+ void texCoord2iv(const GLint *v); \
+ void texCoord2s(GLshort s, GLshort t); \
+ void texCoord2sv(const GLshort *v); \
+ void texCoord3d(GLdouble s, GLdouble t, GLdouble r); \
+ void texCoord3dv(const GLdouble *v); \
+ void texCoord3f(GLfloat s, GLfloat t, GLfloat r); \
+ void texCoord3fv(const GLfloat *v); \
+ void texCoord3i(GLint s, GLint t, GLint r); \
+ void texCoord3iv(const GLint *v); \
+ void texCoord3s(GLshort s, GLshort t, GLshort r); \
+ void texCoord3sv(const GLshort *v); \
+ void texCoord4d(GLdouble s, GLdouble t, GLdouble r, GLdouble q); \
+ void texCoord4dv(const GLdouble *v); \
+ void texCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q); \
+ void texCoord4fv(const GLfloat *v); \
+ void texCoord4i(GLint s, GLint t, GLint r, GLint q); \
+ void texCoord4iv(const GLint *v); \
+ void texCoord4s(GLshort s, GLshort t, GLshort r, GLshort q); \
+ void texCoord4sv(const GLshort *v); \
+ void texGend(GLenum coord, GLenum pname, GLdouble param); \
+ void texGendv(GLenum coord, GLenum pname, const GLdouble *params); \
+ void texImage1D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, \
+ GLenum format, GLenum type, const void *pixels); \
+ void translated(GLdouble x, GLdouble y, GLdouble z); \
+ void vertex2d(GLdouble x, GLdouble y); \
+ void vertex2dv(const GLdouble *v); \
+ void vertex2f(GLfloat x, GLfloat y); \
+ void vertex2fv(const GLfloat *v); \
+ void vertex2i(GLint x, GLint y); \
+ void vertex2iv(const GLint *v); \
+ void vertex2s(GLshort x, GLshort y); \
+ void vertex2sv(const GLshort *v); \
+ void vertex3d(GLdouble x, GLdouble y, GLdouble z); \
+ void vertex3dv(const GLdouble *v); \
+ void vertex3f(GLfloat x, GLfloat y, GLfloat z); \
+ void vertex3fv(const GLfloat *v); \
+ void vertex3i(GLint x, GLint y, GLint z); \
+ void vertex3iv(const GLint *v); \
+ void vertex3s(GLshort x, GLshort y, GLshort z); \
+ void vertex3sv(const GLshort *v); \
+ void vertex4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w); \
+ void vertex4dv(const GLdouble *v); \
+ void vertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w); \
+ void vertex4fv(const GLfloat *v); \
+ void vertex4i(GLint x, GLint y, GLint z, GLint w); \
+ void vertex4iv(const GLint *v); \
+ void vertex4s(GLshort x, GLshort y, GLshort z, GLshort w); \
+ void vertex4sv(const GLshort *v); \
+ GLboolean areTexturesResident(GLsizei n, const GLuint *textures, GLboolean *residences); \
+ void arrayElement(GLint i); \
+ void copyTexImage1D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, \
+ GLsizei width, GLint border); \
+ void copyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, \
+ GLsizei width); \
+ void edgeFlagPointer(GLsizei stride, const void *pointer); \
+ void indexPointer(GLenum type, GLsizei stride, const void *pointer); \
+ void indexub(GLubyte c); \
+ void indexubv(const GLubyte *c); \
+ void interleavedArrays(GLenum format, GLsizei stride, const void *pointer); \
+ void popClientAttrib(); \
+ void prioritizeTextures(GLsizei n, const GLuint *textures, const GLfloat *priorities); \
+ void pushClientAttrib(GLbitfield mask); \
+ void texSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, \
+ GLenum type, const void *pixels); \
+ void compressedTexImage1D(GLenum target, GLint level, GLenum internalformat, GLsizei width, \
+ GLint border, GLsizei imageSize, const void *data); \
+ void compressedTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, \
+ GLenum format, GLsizei imageSize, const void *data); \
+ void loadTransposeMatrixd(const GLdouble *m); \
+ void loadTransposeMatrixf(const GLfloat *m); \
+ void multTransposeMatrixd(const GLdouble *m); \
+ void multTransposeMatrixf(const GLfloat *m); \
+ void multiTexCoord1d(GLenum target, GLdouble s); \
+ void multiTexCoord1dv(GLenum target, const GLdouble *v); \
+ void multiTexCoord1f(GLenum target, GLfloat s); \
+ void multiTexCoord1fv(GLenum target, const GLfloat *v); \
+ void multiTexCoord1i(GLenum target, GLint s); \
+ void multiTexCoord1iv(GLenum target, const GLint *v); \
+ void multiTexCoord1s(GLenum target, GLshort s); \
+ void multiTexCoord1sv(GLenum target, const GLshort *v); \
+ void multiTexCoord2d(GLenum target, GLdouble s, GLdouble t); \
+ void multiTexCoord2dv(GLenum target, const GLdouble *v); \
+ void multiTexCoord2f(GLenum target, GLfloat s, GLfloat t); \
+ void multiTexCoord2fv(GLenum target, const GLfloat *v); \
+ void multiTexCoord2i(GLenum target, GLint s, GLint t); \
+ void multiTexCoord2iv(GLenum target, const GLint *v); \
+ void multiTexCoord2s(GLenum target, GLshort s, GLshort t); \
+ void multiTexCoord2sv(GLenum target, const GLshort *v); \
+ void multiTexCoord3d(GLenum target, GLdouble s, GLdouble t, GLdouble r); \
+ void multiTexCoord3dv(GLenum target, const GLdouble *v); \
+ void multiTexCoord3f(GLenum target, GLfloat s, GLfloat t, GLfloat r); \
+ void multiTexCoord3fv(GLenum target, const GLfloat *v); \
+ void multiTexCoord3i(GLenum target, GLint s, GLint t, GLint r); \
+ void multiTexCoord3iv(GLenum target, const GLint *v); \
+ void multiTexCoord3s(GLenum target, GLshort s, GLshort t, GLshort r); \
+ void multiTexCoord3sv(GLenum target, const GLshort *v); \
+ void multiTexCoord4d(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); \
+ void multiTexCoord4dv(GLenum target, const GLdouble *v); \
+ void multiTexCoord4fv(GLenum target, const GLfloat *v); \
+ void multiTexCoord4i(GLenum target, GLint s, GLint t, GLint r, GLint q); \
+ void multiTexCoord4iv(GLenum target, const GLint *v); \
+ void multiTexCoord4s(GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); \
+ void multiTexCoord4sv(GLenum target, const GLshort *v); \
+ void fogCoordPointer(GLenum type, GLsizei stride, const void *pointer); \
+ void fogCoordd(GLdouble coord); \
+ void fogCoorddv(const GLdouble *coord); \
+ void fogCoordf(GLfloat coord); \
+ void fogCoordfv(const GLfloat *coord); \
+ void pointParameteri(GLenum pname, GLint param); \
+ void pointParameteriv(GLenum pname, const GLint *params); \
+ void secondaryColor3b(GLbyte red, GLbyte green, GLbyte blue); \
+ void secondaryColor3bv(const GLbyte *v); \
+ void secondaryColor3d(GLdouble red, GLdouble green, GLdouble blue); \
+ void secondaryColor3dv(const GLdouble *v); \
+ void secondaryColor3f(GLfloat red, GLfloat green, GLfloat blue); \
+ void secondaryColor3fv(const GLfloat *v); \
+ void secondaryColor3i(GLint red, GLint green, GLint blue); \
+ void secondaryColor3iv(const GLint *v); \
+ void secondaryColor3s(GLshort red, GLshort green, GLshort blue); \
+ void secondaryColor3sv(const GLshort *v); \
+ void secondaryColor3ub(GLubyte red, GLubyte green, GLubyte blue); \
+ void secondaryColor3ubv(const GLubyte *v); \
+ void secondaryColor3ui(GLuint red, GLuint green, GLuint blue); \
+ void secondaryColor3uiv(const GLuint *v); \
+ void secondaryColor3us(GLushort red, GLushort green, GLushort blue); \
+ void secondaryColor3usv(const GLushort *v); \
+ void secondaryColorPointer(GLint size, GLenum type, GLsizei stride, const void *pointer); \
+ void windowPos2d(GLdouble x, GLdouble y); \
+ void windowPos2dv(const GLdouble *v); \
+ void windowPos2f(GLfloat x, GLfloat y); \
+ void windowPos2fv(const GLfloat *v); \
+ void windowPos2i(GLint x, GLint y); \
+ void windowPos2iv(const GLint *v); \
+ void windowPos2s(GLshort x, GLshort y); \
+ void windowPos2sv(const GLshort *v); \
+ void windowPos3d(GLdouble x, GLdouble y, GLdouble z); \
+ void windowPos3dv(const GLdouble *v); \
+ void windowPos3f(GLfloat x, GLfloat y, GLfloat z); \
+ void windowPos3fv(const GLfloat *v); \
+ void windowPos3i(GLint x, GLint y, GLint z); \
+ void windowPos3iv(const GLint *v); \
+ void windowPos3s(GLshort x, GLshort y, GLshort z); \
+ void windowPos3sv(const GLshort *v); \
+ void getBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, void *data);
+
+#endif // ANGLE_CONTEXT_API_1_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libANGLE/Context_gl_2_autogen.h b/gfx/angle/checkout/src/libANGLE/Context_gl_2_autogen.h
new file mode 100644
index 0000000000..92e17d1d6e
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Context_gl_2_autogen.h
@@ -0,0 +1,44 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml.
+//
+// Copyright 2020 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.
+//
+// Context_gl_2_autogen.h: Creates a macro for interfaces in Context.
+
+#ifndef ANGLE_CONTEXT_GL_2_AUTOGEN_H_
+#define ANGLE_CONTEXT_GL_2_AUTOGEN_H_
+
+#define ANGLE_GL_2_CONTEXT_API \
+ void getVertexAttribdv(GLuint index, GLenum pname, GLdouble *params); \
+ void vertexAttrib1d(GLuint index, GLdouble x); \
+ void vertexAttrib1dv(GLuint index, const GLdouble *v); \
+ void vertexAttrib1s(GLuint index, GLshort x); \
+ void vertexAttrib1sv(GLuint index, const GLshort *v); \
+ void vertexAttrib2d(GLuint index, GLdouble x, GLdouble y); \
+ void vertexAttrib2dv(GLuint index, const GLdouble *v); \
+ void vertexAttrib2s(GLuint index, GLshort x, GLshort y); \
+ void vertexAttrib2sv(GLuint index, const GLshort *v); \
+ void vertexAttrib3d(GLuint index, GLdouble x, GLdouble y, GLdouble z); \
+ void vertexAttrib3dv(GLuint index, const GLdouble *v); \
+ void vertexAttrib3s(GLuint index, GLshort x, GLshort y, GLshort z); \
+ void vertexAttrib3sv(GLuint index, const GLshort *v); \
+ void vertexAttrib4Nbv(GLuint index, const GLbyte *v); \
+ void vertexAttrib4Niv(GLuint index, const GLint *v); \
+ void vertexAttrib4Nsv(GLuint index, const GLshort *v); \
+ void vertexAttrib4Nub(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); \
+ void vertexAttrib4Nubv(GLuint index, const GLubyte *v); \
+ void vertexAttrib4Nuiv(GLuint index, const GLuint *v); \
+ void vertexAttrib4Nusv(GLuint index, const GLushort *v); \
+ void vertexAttrib4bv(GLuint index, const GLbyte *v); \
+ void vertexAttrib4d(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); \
+ void vertexAttrib4dv(GLuint index, const GLdouble *v); \
+ void vertexAttrib4iv(GLuint index, const GLint *v); \
+ void vertexAttrib4s(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); \
+ void vertexAttrib4sv(GLuint index, const GLshort *v); \
+ void vertexAttrib4ubv(GLuint index, const GLubyte *v); \
+ void vertexAttrib4uiv(GLuint index, const GLuint *v); \
+ void vertexAttrib4usv(GLuint index, const GLushort *v);
+
+#endif // ANGLE_CONTEXT_API_2_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libANGLE/Context_gl_3_autogen.h b/gfx/angle/checkout/src/libANGLE/Context_gl_3_autogen.h
new file mode 100644
index 0000000000..598a9055ef
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Context_gl_3_autogen.h
@@ -0,0 +1,82 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml.
+//
+// Copyright 2020 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.
+//
+// Context_gl_3_autogen.h: Creates a macro for interfaces in Context.
+
+#ifndef ANGLE_CONTEXT_GL_3_AUTOGEN_H_
+#define ANGLE_CONTEXT_GL_3_AUTOGEN_H_
+
+#define ANGLE_GL_3_CONTEXT_API \
+ void beginConditionalRender(GLuint id, GLenum mode); \
+ void clampColor(GLenum target, GLenum clamp); \
+ void endConditionalRender(); \
+ void framebufferTexture1D(GLenum target, GLenum attachment, TextureTarget textargetPacked, \
+ TextureID texturePacked, GLint level); \
+ void vertexAttribI1i(GLuint index, GLint x); \
+ void vertexAttribI1iv(GLuint index, const GLint *v); \
+ void vertexAttribI1ui(GLuint index, GLuint x); \
+ void vertexAttribI1uiv(GLuint index, const GLuint *v); \
+ void vertexAttribI2i(GLuint index, GLint x, GLint y); \
+ void vertexAttribI2iv(GLuint index, const GLint *v); \
+ void vertexAttribI2ui(GLuint index, GLuint x, GLuint y); \
+ void vertexAttribI2uiv(GLuint index, const GLuint *v); \
+ void vertexAttribI3i(GLuint index, GLint x, GLint y, GLint z); \
+ void vertexAttribI3iv(GLuint index, const GLint *v); \
+ void vertexAttribI3ui(GLuint index, GLuint x, GLuint y, GLuint z); \
+ void vertexAttribI3uiv(GLuint index, const GLuint *v); \
+ void vertexAttribI4bv(GLuint index, const GLbyte *v); \
+ void vertexAttribI4sv(GLuint index, const GLshort *v); \
+ void vertexAttribI4ubv(GLuint index, const GLubyte *v); \
+ void vertexAttribI4usv(GLuint index, const GLushort *v); \
+ void getActiveUniformName(ShaderProgramID programPacked, GLuint uniformIndex, GLsizei bufSize, \
+ GLsizei *length, GLchar *uniformName); \
+ void primitiveRestartIndex(GLuint index); \
+ void texImage2DMultisample(GLenum target, GLsizei samples, GLenum internalformat, \
+ GLsizei width, GLsizei height, GLboolean fixedsamplelocations); \
+ void texImage3DMultisample(GLenum target, GLsizei samples, GLenum internalformat, \
+ GLsizei width, GLsizei height, GLsizei depth, \
+ GLboolean fixedsamplelocations); \
+ void colorP3ui(GLenum type, GLuint color); \
+ void colorP3uiv(GLenum type, const GLuint *color); \
+ void colorP4ui(GLenum type, GLuint color); \
+ void colorP4uiv(GLenum type, const GLuint *color); \
+ void multiTexCoordP1ui(GLenum texture, GLenum type, GLuint coords); \
+ void multiTexCoordP1uiv(GLenum texture, GLenum type, const GLuint *coords); \
+ void multiTexCoordP2ui(GLenum texture, GLenum type, GLuint coords); \
+ void multiTexCoordP2uiv(GLenum texture, GLenum type, const GLuint *coords); \
+ void multiTexCoordP3ui(GLenum texture, GLenum type, GLuint coords); \
+ void multiTexCoordP3uiv(GLenum texture, GLenum type, const GLuint *coords); \
+ void multiTexCoordP4ui(GLenum texture, GLenum type, GLuint coords); \
+ void multiTexCoordP4uiv(GLenum texture, GLenum type, const GLuint *coords); \
+ void normalP3ui(GLenum type, GLuint coords); \
+ void normalP3uiv(GLenum type, const GLuint *coords); \
+ void secondaryColorP3ui(GLenum type, GLuint color); \
+ void secondaryColorP3uiv(GLenum type, const GLuint *color); \
+ void texCoordP1ui(GLenum type, GLuint coords); \
+ void texCoordP1uiv(GLenum type, const GLuint *coords); \
+ void texCoordP2ui(GLenum type, GLuint coords); \
+ void texCoordP2uiv(GLenum type, const GLuint *coords); \
+ void texCoordP3ui(GLenum type, GLuint coords); \
+ void texCoordP3uiv(GLenum type, const GLuint *coords); \
+ void texCoordP4ui(GLenum type, GLuint coords); \
+ void texCoordP4uiv(GLenum type, const GLuint *coords); \
+ void vertexAttribP1ui(GLuint index, GLenum type, GLboolean normalized, GLuint value); \
+ void vertexAttribP1uiv(GLuint index, GLenum type, GLboolean normalized, const GLuint *value); \
+ void vertexAttribP2ui(GLuint index, GLenum type, GLboolean normalized, GLuint value); \
+ void vertexAttribP2uiv(GLuint index, GLenum type, GLboolean normalized, const GLuint *value); \
+ void vertexAttribP3ui(GLuint index, GLenum type, GLboolean normalized, GLuint value); \
+ void vertexAttribP3uiv(GLuint index, GLenum type, GLboolean normalized, const GLuint *value); \
+ void vertexAttribP4ui(GLuint index, GLenum type, GLboolean normalized, GLuint value); \
+ void vertexAttribP4uiv(GLuint index, GLenum type, GLboolean normalized, const GLuint *value); \
+ void vertexP2ui(GLenum type, GLuint value); \
+ void vertexP2uiv(GLenum type, const GLuint *value); \
+ void vertexP3ui(GLenum type, GLuint value); \
+ void vertexP3uiv(GLenum type, const GLuint *value); \
+ void vertexP4ui(GLenum type, GLuint value); \
+ void vertexP4uiv(GLenum type, const GLuint *value);
+
+#endif // ANGLE_CONTEXT_API_3_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libANGLE/Context_gl_4_autogen.h b/gfx/angle/checkout/src/libANGLE/Context_gl_4_autogen.h
new file mode 100644
index 0000000000..2c5570149e
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Context_gl_4_autogen.h
@@ -0,0 +1,358 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml.
+//
+// Copyright 2020 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.
+//
+// Context_gl_4_autogen.h: Creates a macro for interfaces in Context.
+
+#ifndef ANGLE_CONTEXT_GL_4_AUTOGEN_H_
+#define ANGLE_CONTEXT_GL_4_AUTOGEN_H_
+
+#define ANGLE_GL_4_CONTEXT_API \
+ void beginQueryIndexed(GLenum target, GLuint index, QueryID idPacked); \
+ void drawTransformFeedback(GLenum mode, TransformFeedbackID idPacked); \
+ void drawTransformFeedbackStream(GLenum mode, TransformFeedbackID idPacked, GLuint stream); \
+ void endQueryIndexed(GLenum target, GLuint index); \
+ void getActiveSubroutineName(ShaderProgramID programPacked, GLenum shadertype, GLuint index, \
+ GLsizei bufSize, GLsizei *length, GLchar *name); \
+ void getActiveSubroutineUniformName(ShaderProgramID programPacked, GLenum shadertype, \
+ GLuint index, GLsizei bufSize, GLsizei *length, \
+ GLchar *name); \
+ void getActiveSubroutineUniformiv(ShaderProgramID programPacked, GLenum shadertype, \
+ GLuint index, GLenum pname, GLint *values); \
+ void getProgramStageiv(ShaderProgramID programPacked, GLenum shadertype, GLenum pname, \
+ GLint *values); \
+ void getQueryIndexediv(GLenum target, GLuint index, GLenum pname, GLint *params); \
+ GLuint getSubroutineIndex(ShaderProgramID programPacked, GLenum shadertype, \
+ const GLchar *name); \
+ GLint getSubroutineUniformLocation(ShaderProgramID programPacked, GLenum shadertype, \
+ const GLchar *name); \
+ void getUniformSubroutineuiv(GLenum shadertype, GLint location, GLuint *params); \
+ void getUniformdv(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLdouble *params); \
+ void patchParameterfv(GLenum pname, const GLfloat *values); \
+ void uniform1d(UniformLocation locationPacked, GLdouble x); \
+ void uniform1dv(UniformLocation locationPacked, GLsizei count, const GLdouble *value); \
+ void uniform2d(UniformLocation locationPacked, GLdouble x, GLdouble y); \
+ void uniform2dv(UniformLocation locationPacked, GLsizei count, const GLdouble *value); \
+ void uniform3d(UniformLocation locationPacked, GLdouble x, GLdouble y, GLdouble z); \
+ void uniform3dv(UniformLocation locationPacked, GLsizei count, const GLdouble *value); \
+ void uniform4d(UniformLocation locationPacked, GLdouble x, GLdouble y, GLdouble z, \
+ GLdouble w); \
+ void uniform4dv(UniformLocation locationPacked, GLsizei count, const GLdouble *value); \
+ void uniformMatrix2dv(UniformLocation locationPacked, GLsizei count, GLboolean transpose, \
+ const GLdouble *value); \
+ void uniformMatrix2x3dv(UniformLocation locationPacked, GLsizei count, GLboolean transpose, \
+ const GLdouble *value); \
+ void uniformMatrix2x4dv(UniformLocation locationPacked, GLsizei count, GLboolean transpose, \
+ const GLdouble *value); \
+ void uniformMatrix3dv(UniformLocation locationPacked, GLsizei count, GLboolean transpose, \
+ const GLdouble *value); \
+ void uniformMatrix3x2dv(UniformLocation locationPacked, GLsizei count, GLboolean transpose, \
+ const GLdouble *value); \
+ void uniformMatrix3x4dv(UniformLocation locationPacked, GLsizei count, GLboolean transpose, \
+ const GLdouble *value); \
+ void uniformMatrix4dv(UniformLocation locationPacked, GLsizei count, GLboolean transpose, \
+ const GLdouble *value); \
+ void uniformMatrix4x2dv(UniformLocation locationPacked, GLsizei count, GLboolean transpose, \
+ const GLdouble *value); \
+ void uniformMatrix4x3dv(UniformLocation locationPacked, GLsizei count, GLboolean transpose, \
+ const GLdouble *value); \
+ void uniformSubroutinesuiv(GLenum shadertype, GLsizei count, const GLuint *indices); \
+ void depthRangeArrayv(GLuint first, GLsizei count, const GLdouble *v); \
+ void depthRangeIndexed(GLuint index, GLdouble n, GLdouble f); \
+ void getDoublei_v(GLenum target, GLuint index, GLdouble *data); \
+ void getFloati_v(GLenum target, GLuint index, GLfloat *data); \
+ void getVertexAttribLdv(GLuint index, GLenum pname, GLdouble *params); \
+ void programUniform1d(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLdouble v0); \
+ void programUniform1dv(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei count, const GLdouble *value); \
+ void programUniform2d(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLdouble v0, GLdouble v1); \
+ void programUniform2dv(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei count, const GLdouble *value); \
+ void programUniform3d(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLdouble v0, GLdouble v1, GLdouble v2); \
+ void programUniform3dv(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei count, const GLdouble *value); \
+ void programUniform4d(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3); \
+ void programUniform4dv(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei count, const GLdouble *value); \
+ void programUniformMatrix2dv(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei count, GLboolean transpose, const GLdouble *value); \
+ void programUniformMatrix2x3dv(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei count, GLboolean transpose, const GLdouble *value); \
+ void programUniformMatrix2x4dv(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei count, GLboolean transpose, const GLdouble *value); \
+ void programUniformMatrix3dv(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei count, GLboolean transpose, const GLdouble *value); \
+ void programUniformMatrix3x2dv(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei count, GLboolean transpose, const GLdouble *value); \
+ void programUniformMatrix3x4dv(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei count, GLboolean transpose, const GLdouble *value); \
+ void programUniformMatrix4dv(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei count, GLboolean transpose, const GLdouble *value); \
+ void programUniformMatrix4x2dv(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei count, GLboolean transpose, const GLdouble *value); \
+ void programUniformMatrix4x3dv(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei count, GLboolean transpose, const GLdouble *value); \
+ void scissorArrayv(GLuint first, GLsizei count, const GLint *v); \
+ void scissorIndexed(GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); \
+ void scissorIndexedv(GLuint index, const GLint *v); \
+ void vertexAttribL1d(GLuint index, GLdouble x); \
+ void vertexAttribL1dv(GLuint index, const GLdouble *v); \
+ void vertexAttribL2d(GLuint index, GLdouble x, GLdouble y); \
+ void vertexAttribL2dv(GLuint index, const GLdouble *v); \
+ void vertexAttribL3d(GLuint index, GLdouble x, GLdouble y, GLdouble z); \
+ void vertexAttribL3dv(GLuint index, const GLdouble *v); \
+ void vertexAttribL4d(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); \
+ void vertexAttribL4dv(GLuint index, const GLdouble *v); \
+ void vertexAttribLPointer(GLuint index, GLint size, GLenum type, GLsizei stride, \
+ const void *pointer); \
+ void viewportArrayv(GLuint first, GLsizei count, const GLfloat *v); \
+ void viewportIndexedf(GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); \
+ void viewportIndexedfv(GLuint index, const GLfloat *v); \
+ void drawTransformFeedbackInstanced(GLenum mode, TransformFeedbackID idPacked, \
+ GLsizei instancecount); \
+ void drawTransformFeedbackStreamInstanced(GLenum mode, TransformFeedbackID idPacked, \
+ GLuint stream, GLsizei instancecount); \
+ void getActiveAtomicCounterBufferiv(ShaderProgramID programPacked, GLuint bufferIndex, \
+ GLenum pname, GLint *params); \
+ void clearBufferData(GLenum target, GLenum internalformat, GLenum format, GLenum type, \
+ const void *data); \
+ void clearBufferSubData(GLenum target, GLenum internalformat, GLintptr offset, \
+ GLsizeiptr size, GLenum format, GLenum type, const void *data); \
+ void getInternalformati64v(GLenum target, GLenum internalformat, GLenum pname, GLsizei count, \
+ GLint64 *params); \
+ void invalidateBufferData(BufferID bufferPacked); \
+ void invalidateBufferSubData(BufferID bufferPacked, GLintptr offset, GLsizeiptr length); \
+ void invalidateTexImage(TextureID texturePacked, GLint level); \
+ void invalidateTexSubImage(TextureID texturePacked, GLint level, GLint xoffset, GLint yoffset, \
+ GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); \
+ void shaderStorageBlockBinding(ShaderProgramID programPacked, GLuint storageBlockIndex, \
+ GLuint storageBlockBinding); \
+ void textureView(TextureID texturePacked, GLenum target, GLuint origtexture, \
+ GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, \
+ GLuint numlayers); \
+ void vertexAttribLFormat(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); \
+ void bindBuffersBase(GLenum target, GLuint first, GLsizei count, \
+ const BufferID *buffersPacked); \
+ void bindBuffersRange(GLenum target, GLuint first, GLsizei count, \
+ const BufferID *buffersPacked, const GLintptr *offsets, \
+ const GLsizeiptr *sizes); \
+ void bindImageTextures(GLuint first, GLsizei count, const GLuint *textures); \
+ void bindSamplers(GLuint first, GLsizei count, const GLuint *samplers); \
+ void bindTextures(GLuint first, GLsizei count, const GLuint *textures); \
+ void bindVertexBuffers(GLuint first, GLsizei count, const BufferID *buffersPacked, \
+ const GLintptr *offsets, const GLsizei *strides); \
+ void clearTexImage(TextureID texturePacked, GLint level, GLenum format, GLenum type, \
+ const void *data); \
+ void clearTexSubImage(TextureID texturePacked, GLint level, GLint xoffset, GLint yoffset, \
+ GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, \
+ GLenum format, GLenum type, const void *data); \
+ void bindTextureUnit(GLuint unit, TextureID texturePacked); \
+ void blitNamedFramebuffer(GLuint readFramebuffer, GLuint drawFramebuffer, GLint srcX0, \
+ GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, \
+ GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); \
+ GLenum checkNamedFramebufferStatus(FramebufferID framebufferPacked, GLenum target); \
+ void clearNamedBufferData(BufferID bufferPacked, GLenum internalformat, GLenum format, \
+ GLenum type, const void *data); \
+ void clearNamedBufferSubData(BufferID bufferPacked, GLenum internalformat, GLintptr offset, \
+ GLsizeiptr size, GLenum format, GLenum type, const void *data); \
+ void clearNamedFramebufferfi(FramebufferID framebufferPacked, GLenum buffer, GLint drawbuffer, \
+ GLfloat depth, GLint stencil); \
+ void clearNamedFramebufferfv(FramebufferID framebufferPacked, GLenum buffer, GLint drawbuffer, \
+ const GLfloat *value); \
+ void clearNamedFramebufferiv(FramebufferID framebufferPacked, GLenum buffer, GLint drawbuffer, \
+ const GLint *value); \
+ void clearNamedFramebufferuiv(FramebufferID framebufferPacked, GLenum buffer, \
+ GLint drawbuffer, const GLuint *value); \
+ void compressedTextureSubImage1D(TextureID texturePacked, GLint level, GLint xoffset, \
+ GLsizei width, GLenum format, GLsizei imageSize, \
+ const void *data); \
+ void compressedTextureSubImage2D(TextureID texturePacked, GLint level, GLint xoffset, \
+ GLint yoffset, GLsizei width, GLsizei height, GLenum format, \
+ GLsizei imageSize, const void *data); \
+ void compressedTextureSubImage3D(TextureID texturePacked, GLint level, GLint xoffset, \
+ GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, \
+ GLsizei depth, GLenum format, GLsizei imageSize, \
+ const void *data); \
+ void copyNamedBufferSubData(GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, \
+ GLintptr writeOffset, GLsizeiptr size); \
+ void copyTextureSubImage1D(TextureID texturePacked, GLint level, GLint xoffset, GLint x, \
+ GLint y, GLsizei width); \
+ void copyTextureSubImage2D(TextureID texturePacked, GLint level, GLint xoffset, GLint yoffset, \
+ GLint x, GLint y, GLsizei width, GLsizei height); \
+ void copyTextureSubImage3D(TextureID texturePacked, GLint level, GLint xoffset, GLint yoffset, \
+ GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); \
+ void createBuffers(GLsizei n, BufferID *buffersPacked); \
+ void createFramebuffers(GLsizei n, GLuint *framebuffers); \
+ void createProgramPipelines(GLsizei n, GLuint *pipelines); \
+ void createQueries(GLenum target, GLsizei n, GLuint *ids); \
+ void createRenderbuffers(GLsizei n, RenderbufferID *renderbuffersPacked); \
+ void createSamplers(GLsizei n, GLuint *samplers); \
+ void createTextures(GLenum target, GLsizei n, GLuint *textures); \
+ void createTransformFeedbacks(GLsizei n, GLuint *ids); \
+ void createVertexArrays(GLsizei n, VertexArrayID *arraysPacked); \
+ void disableVertexArrayAttrib(VertexArrayID vaobjPacked, GLuint index); \
+ void enableVertexArrayAttrib(VertexArrayID vaobjPacked, GLuint index); \
+ void flushMappedNamedBufferRange(BufferID bufferPacked, GLintptr offset, GLsizeiptr length); \
+ void generateTextureMipmap(TextureID texturePacked); \
+ void getCompressedTextureImage(TextureID texturePacked, GLint level, GLsizei bufSize, \
+ void *pixels); \
+ void getCompressedTextureSubImage(TextureID texturePacked, GLint level, GLint xoffset, \
+ GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, \
+ GLsizei depth, GLsizei bufSize, void *pixels); \
+ void getNamedBufferParameteri64v(BufferID bufferPacked, GLenum pname, GLint64 *params); \
+ void getNamedBufferParameteriv(BufferID bufferPacked, GLenum pname, GLint *params); \
+ void getNamedBufferPointerv(BufferID bufferPacked, GLenum pname, void **params); \
+ void getNamedBufferSubData(BufferID bufferPacked, GLintptr offset, GLsizeiptr size, \
+ void *data); \
+ void getNamedFramebufferAttachmentParameteriv(FramebufferID framebufferPacked, \
+ GLenum attachment, GLenum pname, GLint *params); \
+ void getNamedFramebufferParameteriv(FramebufferID framebufferPacked, GLenum pname, \
+ GLint *param); \
+ void getNamedRenderbufferParameteriv(RenderbufferID renderbufferPacked, GLenum pname, \
+ GLint *params); \
+ void getQueryBufferObjecti64v(GLuint id, BufferID bufferPacked, GLenum pname, \
+ GLintptr offset); \
+ void getQueryBufferObjectiv(GLuint id, BufferID bufferPacked, GLenum pname, GLintptr offset); \
+ void getQueryBufferObjectui64v(GLuint id, BufferID bufferPacked, GLenum pname, \
+ GLintptr offset); \
+ void getQueryBufferObjectuiv(GLuint id, BufferID bufferPacked, GLenum pname, GLintptr offset); \
+ void getTextureImage(TextureID texturePacked, GLint level, GLenum format, GLenum type, \
+ GLsizei bufSize, void *pixels); \
+ void getTextureLevelParameterfv(TextureID texturePacked, GLint level, GLenum pname, \
+ GLfloat *params); \
+ void getTextureLevelParameteriv(TextureID texturePacked, GLint level, GLenum pname, \
+ GLint *params); \
+ void getTextureParameterIiv(TextureID texturePacked, GLenum pname, GLint *params); \
+ void getTextureParameterIuiv(TextureID texturePacked, GLenum pname, GLuint *params); \
+ void getTextureParameterfv(TextureID texturePacked, GLenum pname, GLfloat *params); \
+ void getTextureParameteriv(TextureID texturePacked, GLenum pname, GLint *params); \
+ void getTextureSubImage(TextureID texturePacked, GLint level, GLint xoffset, GLint yoffset, \
+ GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, \
+ GLenum format, GLenum type, GLsizei bufSize, void *pixels); \
+ void getTransformFeedbacki64_v(GLuint xfb, GLenum pname, GLuint index, GLint64 *param); \
+ void getTransformFeedbacki_v(GLuint xfb, GLenum pname, GLuint index, GLint *param); \
+ void getTransformFeedbackiv(GLuint xfb, GLenum pname, GLint *param); \
+ void getVertexArrayIndexed64iv(VertexArrayID vaobjPacked, GLuint index, GLenum pname, \
+ GLint64 *param); \
+ void getVertexArrayIndexediv(VertexArrayID vaobjPacked, GLuint index, GLenum pname, \
+ GLint *param); \
+ void getVertexArrayiv(VertexArrayID vaobjPacked, GLenum pname, GLint *param); \
+ void getnColorTable(GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *table); \
+ void getnCompressedTexImage(GLenum target, GLint lod, GLsizei bufSize, void *pixels); \
+ void getnConvolutionFilter(GLenum target, GLenum format, GLenum type, GLsizei bufSize, \
+ void *image); \
+ void getnHistogram(GLenum target, GLboolean reset, GLenum format, GLenum type, \
+ GLsizei bufSize, void *values); \
+ void getnMapdv(GLenum target, GLenum query, GLsizei bufSize, GLdouble *v); \
+ void getnMapfv(GLenum target, GLenum query, GLsizei bufSize, GLfloat *v); \
+ void getnMapiv(GLenum target, GLenum query, GLsizei bufSize, GLint *v); \
+ void getnMinmax(GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, \
+ void *values); \
+ void getnPixelMapfv(GLenum map, GLsizei bufSize, GLfloat *values); \
+ void getnPixelMapuiv(GLenum map, GLsizei bufSize, GLuint *values); \
+ void getnPixelMapusv(GLenum map, GLsizei bufSize, GLushort *values); \
+ void getnPolygonStipple(GLsizei bufSize, GLubyte *pattern); \
+ void getnSeparableFilter(GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, \
+ void *row, GLsizei columnBufSize, void *column, void *span); \
+ void getnTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, \
+ void *pixels); \
+ void getnUniformdv(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei bufSize, GLdouble *params); \
+ void invalidateNamedFramebufferData(FramebufferID framebufferPacked, GLsizei numAttachments, \
+ const GLenum *attachments); \
+ void invalidateNamedFramebufferSubData(FramebufferID framebufferPacked, \
+ GLsizei numAttachments, const GLenum *attachments, \
+ GLint x, GLint y, GLsizei width, GLsizei height); \
+ void *mapNamedBuffer(BufferID bufferPacked, GLenum access); \
+ void *mapNamedBufferRange(BufferID bufferPacked, GLintptr offset, GLsizeiptr length, \
+ GLbitfield access); \
+ void namedBufferData(BufferID bufferPacked, GLsizeiptr size, const void *data, GLenum usage); \
+ void namedBufferStorage(BufferID bufferPacked, GLsizeiptr size, const void *data, \
+ GLbitfield flags); \
+ void namedBufferSubData(BufferID bufferPacked, GLintptr offset, GLsizeiptr size, \
+ const void *data); \
+ void namedFramebufferDrawBuffer(FramebufferID framebufferPacked, GLenum buf); \
+ void namedFramebufferDrawBuffers(FramebufferID framebufferPacked, GLsizei n, \
+ const GLenum *bufs); \
+ void namedFramebufferParameteri(FramebufferID framebufferPacked, GLenum pname, GLint param); \
+ void namedFramebufferReadBuffer(FramebufferID framebufferPacked, GLenum src); \
+ void namedFramebufferRenderbuffer(FramebufferID framebufferPacked, GLenum attachment, \
+ GLenum renderbuffertarget, \
+ RenderbufferID renderbufferPacked); \
+ void namedFramebufferTexture(FramebufferID framebufferPacked, GLenum attachment, \
+ TextureID texturePacked, GLint level); \
+ void namedFramebufferTextureLayer(FramebufferID framebufferPacked, GLenum attachment, \
+ TextureID texturePacked, GLint level, GLint layer); \
+ void namedRenderbufferStorage(RenderbufferID renderbufferPacked, GLenum internalformat, \
+ GLsizei width, GLsizei height); \
+ void namedRenderbufferStorageMultisample(RenderbufferID renderbufferPacked, GLsizei samples, \
+ GLenum internalformat, GLsizei width, \
+ GLsizei height); \
+ void textureBarrier(); \
+ void textureBuffer(TextureID texturePacked, GLenum internalformat, BufferID bufferPacked); \
+ void textureBufferRange(TextureID texturePacked, GLenum internalformat, BufferID bufferPacked, \
+ GLintptr offset, GLsizeiptr size); \
+ void textureParameterIiv(TextureID texturePacked, GLenum pname, const GLint *params); \
+ void textureParameterIuiv(TextureID texturePacked, GLenum pname, const GLuint *params); \
+ void textureParameterf(TextureID texturePacked, GLenum pname, GLfloat param); \
+ void textureParameterfv(TextureID texturePacked, GLenum pname, const GLfloat *param); \
+ void textureParameteri(TextureID texturePacked, GLenum pname, GLint param); \
+ void textureParameteriv(TextureID texturePacked, GLenum pname, const GLint *param); \
+ void textureStorage1D(TextureID texturePacked, GLsizei levels, GLenum internalformat, \
+ GLsizei width); \
+ void textureStorage2D(TextureID texturePacked, GLsizei levels, GLenum internalformat, \
+ GLsizei width, GLsizei height); \
+ void textureStorage2DMultisample(TextureID texturePacked, GLsizei samples, \
+ GLenum internalformat, GLsizei width, GLsizei height, \
+ GLboolean fixedsamplelocations); \
+ void textureStorage3D(TextureID texturePacked, GLsizei levels, GLenum internalformat, \
+ GLsizei width, GLsizei height, GLsizei depth); \
+ void textureStorage3DMultisample(TextureID texturePacked, GLsizei samples, \
+ GLenum internalformat, GLsizei width, GLsizei height, \
+ GLsizei depth, GLboolean fixedsamplelocations); \
+ void textureSubImage1D(TextureID texturePacked, GLint level, GLint xoffset, GLsizei width, \
+ GLenum format, GLenum type, const void *pixels); \
+ void textureSubImage2D(TextureID texturePacked, GLint level, GLint xoffset, GLint yoffset, \
+ GLsizei width, GLsizei height, GLenum format, GLenum type, \
+ const void *pixels); \
+ void textureSubImage3D(TextureID texturePacked, GLint level, GLint xoffset, GLint yoffset, \
+ GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, \
+ GLenum format, GLenum type, const void *pixels); \
+ void transformFeedbackBufferBase(GLuint xfb, GLuint index, BufferID bufferPacked); \
+ void transformFeedbackBufferRange(GLuint xfb, GLuint index, BufferID bufferPacked, \
+ GLintptr offset, GLsizeiptr size); \
+ GLboolean unmapNamedBuffer(BufferID bufferPacked); \
+ void vertexArrayAttribBinding(VertexArrayID vaobjPacked, GLuint attribindex, \
+ GLuint bindingindex); \
+ void vertexArrayAttribFormat(VertexArrayID vaobjPacked, GLuint attribindex, GLint size, \
+ GLenum type, GLboolean normalized, GLuint relativeoffset); \
+ void vertexArrayAttribIFormat(VertexArrayID vaobjPacked, GLuint attribindex, GLint size, \
+ GLenum type, GLuint relativeoffset); \
+ void vertexArrayAttribLFormat(VertexArrayID vaobjPacked, GLuint attribindex, GLint size, \
+ GLenum type, GLuint relativeoffset); \
+ void vertexArrayBindingDivisor(VertexArrayID vaobjPacked, GLuint bindingindex, \
+ GLuint divisor); \
+ void vertexArrayElementBuffer(VertexArrayID vaobjPacked, BufferID bufferPacked); \
+ void vertexArrayVertexBuffer(VertexArrayID vaobjPacked, GLuint bindingindex, \
+ BufferID bufferPacked, GLintptr offset, GLsizei stride); \
+ void vertexArrayVertexBuffers(VertexArrayID vaobjPacked, GLuint first, GLsizei count, \
+ const BufferID *buffersPacked, const GLintptr *offsets, \
+ const GLsizei *strides); \
+ void multiDrawArraysIndirectCount(GLenum mode, const void *indirect, GLintptr drawcount, \
+ GLsizei maxdrawcount, GLsizei stride); \
+ void multiDrawElementsIndirectCount(GLenum mode, GLenum type, const void *indirect, \
+ GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); \
+ void polygonOffsetClamp(GLfloat factor, GLfloat units, GLfloat clamp); \
+ void specializeShader(GLuint shader, const GLchar *pEntryPoint, \
+ GLuint numSpecializationConstants, const GLuint *pConstantIndex, \
+ const GLuint *pConstantValue);
+
+#endif // ANGLE_CONTEXT_API_4_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libANGLE/Context_gles_1_0.cpp b/gfx/angle/checkout/src/libANGLE/Context_gles_1_0.cpp
new file mode 100644
index 0000000000..611085cfae
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Context_gles_1_0.cpp
@@ -0,0 +1,746 @@
+//
+// Copyright 2018 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.
+//
+
+// Context_gles_1_0.cpp: Implements the GLES1-specific parts of Context.
+
+#include "libANGLE/Context.h"
+
+#include "common/mathutil.h"
+#include "common/utilities.h"
+
+#include "libANGLE/GLES1Renderer.h"
+#include "libANGLE/queryconversions.h"
+#include "libANGLE/queryutils.h"
+
+namespace
+{
+
+angle::Mat4 FixedMatrixToMat4(const GLfixed *m)
+{
+ angle::Mat4 matrixAsFloat;
+ GLfloat *floatData = matrixAsFloat.data();
+
+ for (int i = 0; i < 16; i++)
+ {
+ floatData[i] = gl::ConvertFixedToFloat(m[i]);
+ }
+
+ return matrixAsFloat;
+}
+
+} // namespace
+
+namespace gl
+{
+
+void Context::alphaFunc(AlphaTestFunc func, GLfloat ref)
+{
+ mState.gles1().setAlphaFunc(func, ref);
+}
+
+void Context::alphaFuncx(AlphaTestFunc func, GLfixed ref)
+{
+ mState.gles1().setAlphaFunc(func, ConvertFixedToFloat(ref));
+}
+
+void Context::clearColorx(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)
+{
+ mState.setColorClearValue(ConvertFixedToFloat(red), ConvertFixedToFloat(green),
+ ConvertFixedToFloat(blue), ConvertFixedToFloat(alpha));
+}
+
+void Context::clearDepthx(GLfixed depth)
+{
+ mState.setDepthClearValue(clamp01(ConvertFixedToFloat(depth)));
+}
+
+void Context::clientActiveTexture(GLenum texture)
+{
+ mState.gles1().setClientTextureUnit(texture - GL_TEXTURE0);
+ mStateCache.onGLES1ClientStateChange(this);
+}
+
+void Context::clipPlanef(GLenum p, const GLfloat *eqn)
+{
+ mState.gles1().setClipPlane(p - GL_CLIP_PLANE0, eqn);
+}
+
+void Context::clipPlanex(GLenum plane, const GLfixed *equation)
+{
+ const GLfloat equationf[4] = {
+ ConvertFixedToFloat(equation[0]),
+ ConvertFixedToFloat(equation[1]),
+ ConvertFixedToFloat(equation[2]),
+ ConvertFixedToFloat(equation[3]),
+ };
+
+ mState.gles1().setClipPlane(plane - GL_CLIP_PLANE0, equationf);
+}
+
+void Context::color4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+ mState.gles1().setCurrentColor({red, green, blue, alpha});
+}
+
+void Context::color4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
+{
+ mState.gles1().setCurrentColor(
+ {normalizedToFloat<uint8_t>(red), normalizedToFloat<uint8_t>(green),
+ normalizedToFloat<uint8_t>(blue), normalizedToFloat<uint8_t>(alpha)});
+}
+
+void Context::color4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)
+{
+ mState.gles1().setCurrentColor({ConvertFixedToFloat(red), ConvertFixedToFloat(green),
+ ConvertFixedToFloat(blue), ConvertFixedToFloat(alpha)});
+}
+
+void Context::colorPointer(GLint size, VertexAttribType type, GLsizei stride, const void *ptr)
+{
+ // Note that we normalize data for UnsignedByte types. This is to match the behavior
+ // of current native GLES drivers.
+ vertexAttribPointer(vertexArrayIndex(ClientVertexArrayType::Color), size, type,
+ type == VertexAttribType::UnsignedByte, stride, ptr);
+}
+
+void Context::depthRangex(GLfixed n, GLfixed f)
+{
+ mState.setDepthRange(clamp01(ConvertFixedToFloat(n)), clamp01(ConvertFixedToFloat(f)));
+}
+
+void Context::disableClientState(ClientVertexArrayType clientState)
+{
+ mState.gles1().setClientStateEnabled(clientState, false);
+ disableVertexAttribArray(vertexArrayIndex(clientState));
+ mStateCache.onGLES1ClientStateChange(this);
+}
+
+void Context::enableClientState(ClientVertexArrayType clientState)
+{
+ mState.gles1().setClientStateEnabled(clientState, true);
+ enableVertexAttribArray(vertexArrayIndex(clientState));
+ mStateCache.onGLES1ClientStateChange(this);
+}
+
+void Context::fogf(GLenum pname, GLfloat param)
+{
+ SetFogParameters(&mState.gles1(), pname, &param);
+}
+
+void Context::fogfv(GLenum pname, const GLfloat *params)
+{
+ SetFogParameters(&mState.gles1(), pname, params);
+}
+
+void Context::fogx(GLenum pname, GLfixed param)
+{
+ if (GetFogParameterCount(pname) == 1)
+ {
+ GLfloat paramf = pname == GL_FOG_MODE ? ConvertToGLenum(param) : ConvertFixedToFloat(param);
+ fogf(pname, paramf);
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+}
+
+void Context::fogxv(GLenum pname, const GLfixed *params)
+{
+ int paramCount = GetFogParameterCount(pname);
+
+ if (paramCount > 0)
+ {
+ GLfloat paramsf[4];
+ for (int i = 0; i < paramCount; i++)
+ {
+ paramsf[i] =
+ pname == GL_FOG_MODE ? ConvertToGLenum(params[i]) : ConvertFixedToFloat(params[i]);
+ }
+ fogfv(pname, paramsf);
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+}
+
+void Context::frustumf(GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f)
+{
+ mState.gles1().multMatrix(angle::Mat4::Frustum(l, r, b, t, n, f));
+}
+
+void Context::frustumx(GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f)
+{
+ mState.gles1().multMatrix(angle::Mat4::Frustum(ConvertFixedToFloat(l), ConvertFixedToFloat(r),
+ ConvertFixedToFloat(b), ConvertFixedToFloat(t),
+ ConvertFixedToFloat(n), ConvertFixedToFloat(f)));
+}
+
+void Context::getClipPlanef(GLenum plane, GLfloat *equation)
+{
+ mState.gles1().getClipPlane(plane - GL_CLIP_PLANE0, equation);
+}
+
+void Context::getClipPlanex(GLenum plane, GLfixed *equation)
+{
+ GLfloat equationf[4] = {};
+
+ mState.gles1().getClipPlane(plane - GL_CLIP_PLANE0, equationf);
+
+ for (int i = 0; i < 4; i++)
+ {
+ equation[i] = ConvertFloatToFixed(equationf[i]);
+ }
+}
+
+void Context::getFixedv(GLenum pname, GLfixed *params)
+{
+ GLenum nativeType;
+ unsigned int numParams = 0;
+
+ getQueryParameterInfo(pname, &nativeType, &numParams);
+
+ std::vector<GLfloat> paramsf(numParams, 0);
+ CastStateValues(this, nativeType, pname, numParams, paramsf.data());
+
+ for (unsigned int i = 0; i < numParams; i++)
+ {
+ params[i] = ConvertFloatToFixed(paramsf[i]);
+ }
+}
+
+void Context::getLightfv(GLenum light, LightParameter pname, GLfloat *params)
+{
+ GetLightParameters(&mState.gles1(), light, pname, params);
+}
+
+void Context::getLightxv(GLenum light, LightParameter pname, GLfixed *params)
+{
+ GLfloat paramsf[4];
+ getLightfv(light, pname, paramsf);
+
+ for (unsigned int i = 0; i < GetLightParameterCount(pname); i++)
+ {
+ params[i] = ConvertFloatToFixed(paramsf[i]);
+ }
+}
+
+void Context::getMaterialfv(GLenum face, MaterialParameter pname, GLfloat *params)
+{
+ GetMaterialParameters(&mState.gles1(), face, pname, params);
+}
+
+void Context::getMaterialxv(GLenum face, MaterialParameter pname, GLfixed *params)
+{
+ GLfloat paramsf[4];
+ getMaterialfv(face, pname, paramsf);
+
+ for (unsigned int i = 0; i < GetMaterialParameterCount(pname); i++)
+ {
+ params[i] = ConvertFloatToFixed(paramsf[i]);
+ }
+}
+
+void Context::getTexEnvfv(TextureEnvTarget target, TextureEnvParameter pname, GLfloat *params)
+{
+ GetTextureEnv(mState.getActiveSampler(), &mState.gles1(), target, pname, params);
+}
+
+void Context::getTexEnviv(TextureEnvTarget target, TextureEnvParameter pname, GLint *params)
+{
+ GLfloat paramsf[4];
+ GetTextureEnv(mState.getActiveSampler(), &mState.gles1(), target, pname, paramsf);
+ ConvertTextureEnvToInt(pname, paramsf, params);
+}
+
+void Context::getTexEnvxv(TextureEnvTarget target, TextureEnvParameter pname, GLfixed *params)
+{
+ GLfloat paramsf[4];
+ GetTextureEnv(mState.getActiveSampler(), &mState.gles1(), target, pname, paramsf);
+ ConvertTextureEnvToFixed(pname, paramsf, params);
+}
+
+void Context::getTexParameterxv(TextureType target, GLenum pname, GLfixed *params)
+{
+ const Texture *const texture = getTextureByType(target);
+ QueryTexParameterxv(this, texture, pname, params);
+}
+
+void Context::lightModelf(GLenum pname, GLfloat param)
+{
+ SetLightModelParameters(&mState.gles1(), pname, &param);
+}
+
+void Context::lightModelfv(GLenum pname, const GLfloat *params)
+{
+ SetLightModelParameters(&mState.gles1(), pname, params);
+}
+
+void Context::lightModelx(GLenum pname, GLfixed param)
+{
+ lightModelf(pname, ConvertFixedToFloat(param));
+}
+
+void Context::lightModelxv(GLenum pname, const GLfixed *param)
+{
+ GLfloat paramsf[4];
+
+ for (unsigned int i = 0; i < GetLightModelParameterCount(pname); i++)
+ {
+ paramsf[i] = ConvertFixedToFloat(param[i]);
+ }
+
+ lightModelfv(pname, paramsf);
+}
+
+void Context::lightf(GLenum light, LightParameter pname, GLfloat param)
+{
+ SetLightParameters(&mState.gles1(), light, pname, &param);
+}
+
+void Context::lightfv(GLenum light, LightParameter pname, const GLfloat *params)
+{
+ SetLightParameters(&mState.gles1(), light, pname, params);
+}
+
+void Context::lightx(GLenum light, LightParameter pname, GLfixed param)
+{
+ lightf(light, pname, ConvertFixedToFloat(param));
+}
+
+void Context::lightxv(GLenum light, LightParameter pname, const GLfixed *params)
+{
+ GLfloat paramsf[4];
+
+ for (unsigned int i = 0; i < GetLightParameterCount(pname); i++)
+ {
+ paramsf[i] = ConvertFixedToFloat(params[i]);
+ }
+
+ lightfv(light, pname, paramsf);
+}
+
+void Context::lineWidthx(GLfixed width)
+{
+ mState.setLineWidth(ConvertFixedToFloat(width));
+}
+
+void Context::loadIdentity()
+{
+ mState.gles1().loadMatrix(angle::Mat4());
+}
+
+void Context::loadMatrixf(const GLfloat *m)
+{
+ mState.gles1().loadMatrix(angle::Mat4(m));
+}
+
+void Context::loadMatrixx(const GLfixed *m)
+{
+ mState.gles1().loadMatrix(FixedMatrixToMat4(m));
+}
+
+void Context::logicOp(LogicalOperation opcodePacked)
+{
+ mState.gles1().setLogicOp(opcodePacked);
+}
+
+void Context::materialf(GLenum face, MaterialParameter pname, GLfloat param)
+{
+ SetMaterialParameters(&mState.gles1(), face, pname, &param);
+}
+
+void Context::materialfv(GLenum face, MaterialParameter pname, const GLfloat *params)
+{
+ SetMaterialParameters(&mState.gles1(), face, pname, params);
+}
+
+void Context::materialx(GLenum face, MaterialParameter pname, GLfixed param)
+{
+ materialf(face, pname, ConvertFixedToFloat(param));
+}
+
+void Context::materialxv(GLenum face, MaterialParameter pname, const GLfixed *param)
+{
+ GLfloat paramsf[4];
+
+ for (unsigned int i = 0; i < GetMaterialParameterCount(pname); i++)
+ {
+ paramsf[i] = ConvertFixedToFloat(param[i]);
+ }
+
+ materialfv(face, pname, paramsf);
+}
+
+void Context::matrixMode(MatrixType mode)
+{
+ mState.gles1().setMatrixMode(mode);
+}
+
+void Context::multMatrixf(const GLfloat *m)
+{
+ mState.gles1().multMatrix(angle::Mat4(m));
+}
+
+void Context::multMatrixx(const GLfixed *m)
+{
+ mState.gles1().multMatrix(FixedMatrixToMat4(m));
+}
+
+void Context::multiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
+{
+ unsigned int unit = target - GL_TEXTURE0;
+ ASSERT(target >= GL_TEXTURE0 && unit < getCaps().maxMultitextureUnits);
+ mState.gles1().setCurrentTextureCoords(unit, {s, t, r, q});
+}
+
+void Context::multiTexCoord4x(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
+{
+ unsigned int unit = target - GL_TEXTURE0;
+ ASSERT(target >= GL_TEXTURE0 && unit < getCaps().maxMultitextureUnits);
+ mState.gles1().setCurrentTextureCoords(unit, {ConvertFixedToFloat(s), ConvertFixedToFloat(t),
+ ConvertFixedToFloat(r), ConvertFixedToFloat(q)});
+}
+
+void Context::normal3f(GLfloat nx, GLfloat ny, GLfloat nz)
+{
+ mState.gles1().setCurrentNormal({nx, ny, nz});
+}
+
+void Context::normal3x(GLfixed nx, GLfixed ny, GLfixed nz)
+{
+ mState.gles1().setCurrentNormal(
+ {ConvertFixedToFloat(nx), ConvertFixedToFloat(ny), ConvertFixedToFloat(nz)});
+}
+
+void Context::normalPointer(VertexAttribType type, GLsizei stride, const void *ptr)
+{
+ vertexAttribPointer(vertexArrayIndex(ClientVertexArrayType::Normal), 3, type, GL_FALSE, stride,
+ ptr);
+}
+
+void Context::orthof(GLfloat left,
+ GLfloat right,
+ GLfloat bottom,
+ GLfloat top,
+ GLfloat zNear,
+ GLfloat zFar)
+{
+ mState.gles1().multMatrix(angle::Mat4::Ortho(left, right, bottom, top, zNear, zFar));
+}
+
+void Context::orthox(GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f)
+{
+ mState.gles1().multMatrix(angle::Mat4::Ortho(ConvertFixedToFloat(l), ConvertFixedToFloat(r),
+ ConvertFixedToFloat(b), ConvertFixedToFloat(t),
+ ConvertFixedToFloat(n), ConvertFixedToFloat(f)));
+}
+
+void Context::pointParameterf(PointParameter pname, GLfloat param)
+{
+ SetPointParameter(&mState.gles1(), pname, &param);
+}
+
+void Context::pointParameterfv(PointParameter pname, const GLfloat *params)
+{
+ SetPointParameter(&mState.gles1(), pname, params);
+}
+
+void Context::pointParameterx(PointParameter pname, GLfixed param)
+{
+ GLfloat paramf = ConvertFixedToFloat(param);
+ SetPointParameter(&mState.gles1(), pname, &paramf);
+}
+
+void Context::pointParameterxv(PointParameter pname, const GLfixed *params)
+{
+ GLfloat paramsf[4] = {};
+ for (unsigned int i = 0; i < GetPointParameterCount(pname); i++)
+ {
+ paramsf[i] = ConvertFixedToFloat(params[i]);
+ }
+ SetPointParameter(&mState.gles1(), pname, paramsf);
+}
+
+void Context::pointSize(GLfloat size)
+{
+ SetPointSize(&mState.gles1(), size);
+}
+
+void Context::pointSizex(GLfixed size)
+{
+ SetPointSize(&mState.gles1(), ConvertFixedToFloat(size));
+}
+
+void Context::polygonOffsetx(GLfixed factor, GLfixed units)
+{
+ mState.setPolygonOffsetParams(ConvertFixedToFloat(factor), ConvertFixedToFloat(units));
+}
+
+void Context::popMatrix()
+{
+ mState.gles1().popMatrix();
+}
+
+void Context::pushMatrix()
+{
+ mState.gles1().pushMatrix();
+}
+
+void Context::rotatef(float angle, float x, float y, float z)
+{
+ mState.gles1().multMatrix(angle::Mat4::Rotate(angle, angle::Vector3(x, y, z)));
+}
+
+void Context::rotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z)
+{
+ mState.gles1().multMatrix(angle::Mat4::Rotate(
+ ConvertFixedToFloat(angle),
+ angle::Vector3(ConvertFixedToFloat(x), ConvertFixedToFloat(y), ConvertFixedToFloat(z))));
+}
+
+void Context::sampleCoveragex(GLclampx value, GLboolean invert)
+{
+ GLclampf valuef = ConvertFixedToFloat(value);
+ mState.setSampleCoverageParams(clamp01(valuef), ConvertToBool(invert));
+}
+
+void Context::scalef(float x, float y, float z)
+{
+ mState.gles1().multMatrix(angle::Mat4::Scale(angle::Vector3(x, y, z)));
+}
+
+void Context::scalex(GLfixed x, GLfixed y, GLfixed z)
+{
+ mState.gles1().multMatrix(angle::Mat4::Scale(
+ angle::Vector3(ConvertFixedToFloat(x), ConvertFixedToFloat(y), ConvertFixedToFloat(z))));
+}
+
+void Context::shadeModel(ShadingModel model)
+{
+ mState.gles1().setShadeModel(model);
+}
+
+void Context::texCoordPointer(GLint size, VertexAttribType type, GLsizei stride, const void *ptr)
+{
+ vertexAttribPointer(vertexArrayIndex(ClientVertexArrayType::TextureCoord), size, type, GL_FALSE,
+ stride, ptr);
+}
+
+void Context::texEnvf(TextureEnvTarget target, TextureEnvParameter pname, GLfloat param)
+{
+ SetTextureEnv(mState.getActiveSampler(), &mState.gles1(), target, pname, &param);
+}
+
+void Context::texEnvfv(TextureEnvTarget target, TextureEnvParameter pname, const GLfloat *params)
+{
+ SetTextureEnv(mState.getActiveSampler(), &mState.gles1(), target, pname, params);
+}
+
+void Context::texEnvi(TextureEnvTarget target, TextureEnvParameter pname, GLint param)
+{
+ GLfloat paramsf[4] = {};
+ ConvertTextureEnvFromInt(pname, &param, paramsf);
+ SetTextureEnv(mState.getActiveSampler(), &mState.gles1(), target, pname, paramsf);
+}
+
+void Context::texEnviv(TextureEnvTarget target, TextureEnvParameter pname, const GLint *params)
+{
+ GLfloat paramsf[4] = {};
+ ConvertTextureEnvFromInt(pname, params, paramsf);
+ SetTextureEnv(mState.getActiveSampler(), &mState.gles1(), target, pname, paramsf);
+}
+
+void Context::texEnvx(TextureEnvTarget target, TextureEnvParameter pname, GLfixed param)
+{
+ GLfloat paramsf[4] = {};
+ ConvertTextureEnvFromFixed(pname, &param, paramsf);
+ SetTextureEnv(mState.getActiveSampler(), &mState.gles1(), target, pname, paramsf);
+}
+
+void Context::texEnvxv(TextureEnvTarget target, TextureEnvParameter pname, const GLfixed *params)
+{
+ GLfloat paramsf[4] = {};
+ ConvertTextureEnvFromFixed(pname, params, paramsf);
+ SetTextureEnv(mState.getActiveSampler(), &mState.gles1(), target, pname, paramsf);
+}
+
+void Context::texParameterx(TextureType target, GLenum pname, GLfixed param)
+{
+ Texture *const texture = getTextureByType(target);
+ SetTexParameterx(this, texture, pname, param);
+}
+
+void Context::texParameterxv(TextureType target, GLenum pname, const GLfixed *params)
+{
+ Texture *const texture = getTextureByType(target);
+ SetTexParameterxv(this, texture, pname, params);
+}
+
+void Context::translatef(float x, float y, float z)
+{
+ mState.gles1().multMatrix(angle::Mat4::Translate(angle::Vector3(x, y, z)));
+}
+
+void Context::translatex(GLfixed x, GLfixed y, GLfixed z)
+{
+ mState.gles1().multMatrix(angle::Mat4::Translate(
+ angle::Vector3(ConvertFixedToFloat(x), ConvertFixedToFloat(y), ConvertFixedToFloat(z))));
+}
+
+void Context::vertexPointer(GLint size, VertexAttribType type, GLsizei stride, const void *ptr)
+{
+ vertexAttribPointer(vertexArrayIndex(ClientVertexArrayType::Vertex), size, type, GL_FALSE,
+ stride, ptr);
+}
+
+// GL_OES_draw_texture
+void Context::drawTexf(float x, float y, float z, float width, float height)
+{
+ mGLES1Renderer->drawTexture(this, &mState, x, y, z, width, height);
+}
+
+void Context::drawTexfv(const GLfloat *coords)
+{
+ mGLES1Renderer->drawTexture(this, &mState, coords[0], coords[1], coords[2], coords[3],
+ coords[4]);
+}
+
+void Context::drawTexi(GLint x, GLint y, GLint z, GLint width, GLint height)
+{
+ mGLES1Renderer->drawTexture(this, &mState, static_cast<GLfloat>(x), static_cast<GLfloat>(y),
+ static_cast<GLfloat>(z), static_cast<GLfloat>(width),
+ static_cast<GLfloat>(height));
+}
+
+void Context::drawTexiv(const GLint *coords)
+{
+ mGLES1Renderer->drawTexture(this, &mState, static_cast<GLfloat>(coords[0]),
+ static_cast<GLfloat>(coords[1]), static_cast<GLfloat>(coords[2]),
+ static_cast<GLfloat>(coords[3]), static_cast<GLfloat>(coords[4]));
+}
+
+void Context::drawTexs(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height)
+{
+ mGLES1Renderer->drawTexture(this, &mState, static_cast<GLfloat>(x), static_cast<GLfloat>(y),
+ static_cast<GLfloat>(z), static_cast<GLfloat>(width),
+ static_cast<GLfloat>(height));
+}
+
+void Context::drawTexsv(const GLshort *coords)
+{
+ mGLES1Renderer->drawTexture(this, &mState, static_cast<GLfloat>(coords[0]),
+ static_cast<GLfloat>(coords[1]), static_cast<GLfloat>(coords[2]),
+ static_cast<GLfloat>(coords[3]), static_cast<GLfloat>(coords[4]));
+}
+
+void Context::drawTexx(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height)
+{
+ mGLES1Renderer->drawTexture(this, &mState, ConvertFixedToFloat(x), ConvertFixedToFloat(y),
+ ConvertFixedToFloat(z), ConvertFixedToFloat(width),
+ ConvertFixedToFloat(height));
+}
+
+void Context::drawTexxv(const GLfixed *coords)
+{
+ mGLES1Renderer->drawTexture(this, &mState, ConvertFixedToFloat(coords[0]),
+ ConvertFixedToFloat(coords[1]), ConvertFixedToFloat(coords[2]),
+ ConvertFixedToFloat(coords[3]), ConvertFixedToFloat(coords[4]));
+}
+
+// GL_OES_matrix_palette
+void Context::currentPaletteMatrix(GLuint matrixpaletteindex)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::loadPaletteFromModelViewMatrix()
+{
+ UNIMPLEMENTED();
+}
+
+void Context::matrixIndexPointer(GLint size, GLenum type, GLsizei stride, const void *pointer)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::weightPointer(GLint size, GLenum type, GLsizei stride, const void *pointer)
+{
+ UNIMPLEMENTED();
+}
+
+// GL_OES_point_size_array
+void Context::pointSizePointer(VertexAttribType type, GLsizei stride, const void *ptr)
+{
+ vertexAttribPointer(vertexArrayIndex(ClientVertexArrayType::PointSize), 1, type, GL_FALSE,
+ stride, ptr);
+}
+
+// GL_OES_query_matrix
+GLbitfield Context::queryMatrixx(GLfixed *mantissa, GLint *exponent)
+{
+ UNIMPLEMENTED();
+ return 0;
+}
+
+// GL_OES_texture_cube_map
+void Context::getTexGenfv(GLenum coord, GLenum pname, GLfloat *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getTexGeniv(GLenum coord, GLenum pname, GLint *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::getTexGenxv(GLenum coord, GLenum pname, GLfixed *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texGenf(GLenum coord, GLenum pname, GLfloat param)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texGenfv(GLenum coord, GLenum pname, const GLfloat *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texGeni(GLenum coord, GLenum pname, GLint param)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texGeniv(GLenum coord, GLenum pname, const GLint *params)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texGenx(GLenum coord, GLenum pname, GLfixed param)
+{
+ UNIMPLEMENTED();
+}
+
+void Context::texGenxv(GLenum coord, GLenum pname, const GLint *params)
+{
+ UNIMPLEMENTED();
+}
+
+int Context::vertexArrayIndex(ClientVertexArrayType type) const
+{
+ return GLES1Renderer::VertexArrayIndex(type, mState.gles1());
+}
+
+// static
+int Context::TexCoordArrayIndex(unsigned int unit)
+{
+ return GLES1Renderer::TexCoordArrayIndex(unit);
+}
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/Context_gles_1_0_autogen.h b/gfx/angle/checkout/src/libANGLE/Context_gles_1_0_autogen.h
new file mode 100644
index 0000000000..77f1a9afce
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Context_gles_1_0_autogen.h
@@ -0,0 +1,109 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml.
+//
+// Copyright 2020 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.
+//
+// Context_gles_1_0_autogen.h: Creates a macro for interfaces in Context.
+
+#ifndef ANGLE_CONTEXT_GLES_1_0_AUTOGEN_H_
+#define ANGLE_CONTEXT_GLES_1_0_AUTOGEN_H_
+
+#define ANGLE_GLES_1_0_CONTEXT_API \
+ void alphaFunc(AlphaTestFunc funcPacked, GLfloat ref); \
+ void alphaFuncx(AlphaTestFunc funcPacked, GLfixed ref); \
+ void clearColorx(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); \
+ void clearDepthx(GLfixed depth); \
+ void clientActiveTexture(GLenum texture); \
+ void clipPlanef(GLenum p, const GLfloat *eqn); \
+ void clipPlanex(GLenum plane, const GLfixed *equation); \
+ void color4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); \
+ void color4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); \
+ void color4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); \
+ void colorPointer(GLint size, VertexAttribType typePacked, GLsizei stride, \
+ const void *pointer); \
+ void depthRangex(GLfixed n, GLfixed f); \
+ void disableClientState(ClientVertexArrayType arrayPacked); \
+ void enableClientState(ClientVertexArrayType arrayPacked); \
+ void fogf(GLenum pname, GLfloat param); \
+ void fogfv(GLenum pname, const GLfloat *params); \
+ void fogx(GLenum pname, GLfixed param); \
+ void fogxv(GLenum pname, const GLfixed *param); \
+ void frustumf(GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); \
+ void frustumx(GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f); \
+ void getClipPlanef(GLenum plane, GLfloat *equation); \
+ void getClipPlanex(GLenum plane, GLfixed *equation); \
+ void getFixedv(GLenum pname, GLfixed *params); \
+ void getLightfv(GLenum light, LightParameter pnamePacked, GLfloat *params); \
+ void getLightxv(GLenum light, LightParameter pnamePacked, GLfixed *params); \
+ void getMaterialfv(GLenum face, MaterialParameter pnamePacked, GLfloat *params); \
+ void getMaterialxv(GLenum face, MaterialParameter pnamePacked, GLfixed *params); \
+ void getTexEnvfv(TextureEnvTarget targetPacked, TextureEnvParameter pnamePacked, \
+ GLfloat *params); \
+ void getTexEnviv(TextureEnvTarget targetPacked, TextureEnvParameter pnamePacked, \
+ GLint *params); \
+ void getTexEnvxv(TextureEnvTarget targetPacked, TextureEnvParameter pnamePacked, \
+ GLfixed *params); \
+ void getTexParameterxv(TextureType targetPacked, GLenum pname, GLfixed *params); \
+ void lightModelf(GLenum pname, GLfloat param); \
+ void lightModelfv(GLenum pname, const GLfloat *params); \
+ void lightModelx(GLenum pname, GLfixed param); \
+ void lightModelxv(GLenum pname, const GLfixed *param); \
+ void lightf(GLenum light, LightParameter pnamePacked, GLfloat param); \
+ void lightfv(GLenum light, LightParameter pnamePacked, const GLfloat *params); \
+ void lightx(GLenum light, LightParameter pnamePacked, GLfixed param); \
+ void lightxv(GLenum light, LightParameter pnamePacked, const GLfixed *params); \
+ void lineWidthx(GLfixed width); \
+ void loadIdentity(); \
+ void loadMatrixf(const GLfloat *m); \
+ void loadMatrixx(const GLfixed *m); \
+ void logicOp(LogicalOperation opcodePacked); \
+ void materialf(GLenum face, MaterialParameter pnamePacked, GLfloat param); \
+ void materialfv(GLenum face, MaterialParameter pnamePacked, const GLfloat *params); \
+ void materialx(GLenum face, MaterialParameter pnamePacked, GLfixed param); \
+ void materialxv(GLenum face, MaterialParameter pnamePacked, const GLfixed *param); \
+ void matrixMode(MatrixType modePacked); \
+ void multMatrixf(const GLfloat *m); \
+ void multMatrixx(const GLfixed *m); \
+ void multiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); \
+ void multiTexCoord4x(GLenum texture, GLfixed s, GLfixed t, GLfixed r, GLfixed q); \
+ void normal3f(GLfloat nx, GLfloat ny, GLfloat nz); \
+ void normal3x(GLfixed nx, GLfixed ny, GLfixed nz); \
+ void normalPointer(VertexAttribType typePacked, GLsizei stride, const void *pointer); \
+ void orthof(GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f); \
+ void orthox(GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f); \
+ void pointParameterf(PointParameter pnamePacked, GLfloat param); \
+ void pointParameterfv(PointParameter pnamePacked, const GLfloat *params); \
+ void pointParameterx(PointParameter pnamePacked, GLfixed param); \
+ void pointParameterxv(PointParameter pnamePacked, const GLfixed *params); \
+ void pointSize(GLfloat size); \
+ void pointSizex(GLfixed size); \
+ void polygonOffsetx(GLfixed factor, GLfixed units); \
+ void popMatrix(); \
+ void pushMatrix(); \
+ void rotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); \
+ void rotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z); \
+ void sampleCoveragex(GLclampx value, GLboolean invert); \
+ void scalef(GLfloat x, GLfloat y, GLfloat z); \
+ void scalex(GLfixed x, GLfixed y, GLfixed z); \
+ void shadeModel(ShadingModel modePacked); \
+ void texCoordPointer(GLint size, VertexAttribType typePacked, GLsizei stride, \
+ const void *pointer); \
+ void texEnvf(TextureEnvTarget targetPacked, TextureEnvParameter pnamePacked, GLfloat param); \
+ void texEnvfv(TextureEnvTarget targetPacked, TextureEnvParameter pnamePacked, \
+ const GLfloat *params); \
+ void texEnvi(TextureEnvTarget targetPacked, TextureEnvParameter pnamePacked, GLint param); \
+ void texEnviv(TextureEnvTarget targetPacked, TextureEnvParameter pnamePacked, \
+ const GLint *params); \
+ void texEnvx(TextureEnvTarget targetPacked, TextureEnvParameter pnamePacked, GLfixed param); \
+ void texEnvxv(TextureEnvTarget targetPacked, TextureEnvParameter pnamePacked, \
+ const GLfixed *params); \
+ void texParameterx(TextureType targetPacked, GLenum pname, GLfixed param); \
+ void texParameterxv(TextureType targetPacked, GLenum pname, const GLfixed *params); \
+ void translatef(GLfloat x, GLfloat y, GLfloat z); \
+ void translatex(GLfixed x, GLfixed y, GLfixed z); \
+ void vertexPointer(GLint size, VertexAttribType typePacked, GLsizei stride, \
+ const void *pointer);
+
+#endif // ANGLE_CONTEXT_API_1_0_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libANGLE/Context_gles_2_0_autogen.h b/gfx/angle/checkout/src/libANGLE/Context_gles_2_0_autogen.h
new file mode 100644
index 0000000000..1c0501eaf3
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Context_gles_2_0_autogen.h
@@ -0,0 +1,190 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml.
+//
+// Copyright 2020 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.
+//
+// Context_gles_2_0_autogen.h: Creates a macro for interfaces in Context.
+
+#ifndef ANGLE_CONTEXT_GLES_2_0_AUTOGEN_H_
+#define ANGLE_CONTEXT_GLES_2_0_AUTOGEN_H_
+
+#define ANGLE_GLES_2_0_CONTEXT_API \
+ void activeTexture(GLenum texture); \
+ void attachShader(ShaderProgramID programPacked, ShaderProgramID shaderPacked); \
+ void bindAttribLocation(ShaderProgramID programPacked, GLuint index, const GLchar *name); \
+ void bindBuffer(BufferBinding targetPacked, BufferID bufferPacked); \
+ void bindFramebuffer(GLenum target, FramebufferID framebufferPacked); \
+ void bindRenderbuffer(GLenum target, RenderbufferID renderbufferPacked); \
+ void bindTexture(TextureType targetPacked, TextureID texturePacked); \
+ void blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); \
+ void blendEquation(GLenum mode); \
+ void blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha); \
+ void blendFunc(GLenum sfactor, GLenum dfactor); \
+ void blendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, \
+ GLenum dfactorAlpha); \
+ void bufferData(BufferBinding targetPacked, GLsizeiptr size, const void *data, \
+ BufferUsage usagePacked); \
+ void bufferSubData(BufferBinding targetPacked, GLintptr offset, GLsizeiptr size, \
+ const void *data); \
+ GLenum checkFramebufferStatus(GLenum target); \
+ void clear(GLbitfield mask); \
+ void clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); \
+ void clearDepthf(GLfloat d); \
+ void clearStencil(GLint s); \
+ void colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); \
+ void compileShader(ShaderProgramID shaderPacked); \
+ void compressedTexImage2D(TextureTarget targetPacked, GLint level, GLenum internalformat, \
+ GLsizei width, GLsizei height, GLint border, GLsizei imageSize, \
+ const void *data); \
+ void compressedTexSubImage2D(TextureTarget targetPacked, GLint level, GLint xoffset, \
+ GLint yoffset, GLsizei width, GLsizei height, GLenum format, \
+ GLsizei imageSize, const void *data); \
+ void copyTexImage2D(TextureTarget targetPacked, GLint level, GLenum internalformat, GLint x, \
+ GLint y, GLsizei width, GLsizei height, GLint border); \
+ void copyTexSubImage2D(TextureTarget targetPacked, GLint level, GLint xoffset, GLint yoffset, \
+ GLint x, GLint y, GLsizei width, GLsizei height); \
+ GLuint createProgram(); \
+ GLuint createShader(ShaderType typePacked); \
+ void cullFace(CullFaceMode modePacked); \
+ void deleteBuffers(GLsizei n, const BufferID *buffersPacked); \
+ void deleteFramebuffers(GLsizei n, const FramebufferID *framebuffersPacked); \
+ void deleteProgram(ShaderProgramID programPacked); \
+ void deleteRenderbuffers(GLsizei n, const RenderbufferID *renderbuffersPacked); \
+ void deleteShader(ShaderProgramID shaderPacked); \
+ void deleteTextures(GLsizei n, const TextureID *texturesPacked); \
+ void depthFunc(GLenum func); \
+ void depthMask(GLboolean flag); \
+ void depthRangef(GLfloat n, GLfloat f); \
+ void detachShader(ShaderProgramID programPacked, ShaderProgramID shaderPacked); \
+ void disable(GLenum cap); \
+ void disableVertexAttribArray(GLuint index); \
+ void drawArrays(PrimitiveMode modePacked, GLint first, GLsizei count); \
+ void drawElements(PrimitiveMode modePacked, GLsizei count, DrawElementsType typePacked, \
+ const void *indices); \
+ void enable(GLenum cap); \
+ void enableVertexAttribArray(GLuint index); \
+ void finish(); \
+ void flush(); \
+ void framebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, \
+ RenderbufferID renderbufferPacked); \
+ void framebufferTexture2D(GLenum target, GLenum attachment, TextureTarget textargetPacked, \
+ TextureID texturePacked, GLint level); \
+ void frontFace(GLenum mode); \
+ void genBuffers(GLsizei n, BufferID *buffersPacked); \
+ void genFramebuffers(GLsizei n, FramebufferID *framebuffersPacked); \
+ void genRenderbuffers(GLsizei n, RenderbufferID *renderbuffersPacked); \
+ void genTextures(GLsizei n, TextureID *texturesPacked); \
+ void generateMipmap(TextureType targetPacked); \
+ void getActiveAttrib(ShaderProgramID programPacked, GLuint index, GLsizei bufSize, \
+ GLsizei *length, GLint *size, GLenum *type, GLchar *name); \
+ void getActiveUniform(ShaderProgramID programPacked, GLuint index, GLsizei bufSize, \
+ GLsizei *length, GLint *size, GLenum *type, GLchar *name); \
+ void getAttachedShaders(ShaderProgramID programPacked, GLsizei maxCount, GLsizei *count, \
+ ShaderProgramID *shadersPacked); \
+ GLint getAttribLocation(ShaderProgramID programPacked, const GLchar *name); \
+ void getBooleanv(GLenum pname, GLboolean *data); \
+ void getBufferParameteriv(BufferBinding targetPacked, GLenum pname, GLint *params); \
+ GLenum getError(); \
+ void getFloatv(GLenum pname, GLfloat *data); \
+ void getFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, \
+ GLint *params); \
+ void getIntegerv(GLenum pname, GLint *data); \
+ void getProgramInfoLog(ShaderProgramID programPacked, GLsizei bufSize, GLsizei *length, \
+ GLchar *infoLog); \
+ void getProgramiv(ShaderProgramID programPacked, GLenum pname, GLint *params); \
+ void getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params); \
+ void getShaderInfoLog(ShaderProgramID shaderPacked, GLsizei bufSize, GLsizei *length, \
+ GLchar *infoLog); \
+ void getShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint *range, \
+ GLint *precision); \
+ void getShaderSource(ShaderProgramID shaderPacked, GLsizei bufSize, GLsizei *length, \
+ GLchar *source); \
+ void getShaderiv(ShaderProgramID shaderPacked, GLenum pname, GLint *params); \
+ const GLubyte *getString(GLenum name); \
+ void getTexParameterfv(TextureType targetPacked, GLenum pname, GLfloat *params); \
+ void getTexParameteriv(TextureType targetPacked, GLenum pname, GLint *params); \
+ GLint getUniformLocation(ShaderProgramID programPacked, const GLchar *name); \
+ void getUniformfv(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLfloat *params); \
+ void getUniformiv(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLint *params); \
+ void getVertexAttribPointerv(GLuint index, GLenum pname, void **pointer); \
+ void getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params); \
+ void getVertexAttribiv(GLuint index, GLenum pname, GLint *params); \
+ void hint(GLenum target, GLenum mode); \
+ GLboolean isBuffer(BufferID bufferPacked) const; \
+ GLboolean isEnabled(GLenum cap) const; \
+ GLboolean isFramebuffer(FramebufferID framebufferPacked) const; \
+ GLboolean isProgram(ShaderProgramID programPacked) const; \
+ GLboolean isRenderbuffer(RenderbufferID renderbufferPacked) const; \
+ GLboolean isShader(ShaderProgramID shaderPacked) const; \
+ GLboolean isTexture(TextureID texturePacked) const; \
+ void lineWidth(GLfloat width); \
+ void linkProgram(ShaderProgramID programPacked); \
+ void pixelStorei(GLenum pname, GLint param); \
+ void polygonOffset(GLfloat factor, GLfloat units); \
+ void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, \
+ void *pixels); \
+ void releaseShaderCompiler(); \
+ void renderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); \
+ void sampleCoverage(GLfloat value, GLboolean invert); \
+ void scissor(GLint x, GLint y, GLsizei width, GLsizei height); \
+ void shaderBinary(GLsizei count, const ShaderProgramID *shadersPacked, GLenum binaryFormat, \
+ const void *binary, GLsizei length); \
+ void shaderSource(ShaderProgramID shaderPacked, GLsizei count, const GLchar *const *string, \
+ const GLint *length); \
+ void stencilFunc(GLenum func, GLint ref, GLuint mask); \
+ void stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask); \
+ void stencilMask(GLuint mask); \
+ void stencilMaskSeparate(GLenum face, GLuint mask); \
+ void stencilOp(GLenum fail, GLenum zfail, GLenum zpass); \
+ void stencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); \
+ void texImage2D(TextureTarget targetPacked, GLint level, GLint internalformat, GLsizei width, \
+ GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); \
+ void texParameterf(TextureType targetPacked, GLenum pname, GLfloat param); \
+ void texParameterfv(TextureType targetPacked, GLenum pname, const GLfloat *params); \
+ void texParameteri(TextureType targetPacked, GLenum pname, GLint param); \
+ void texParameteriv(TextureType targetPacked, GLenum pname, const GLint *params); \
+ void texSubImage2D(TextureTarget targetPacked, GLint level, GLint xoffset, GLint yoffset, \
+ GLsizei width, GLsizei height, GLenum format, GLenum type, \
+ const void *pixels); \
+ void uniform1f(UniformLocation locationPacked, GLfloat v0); \
+ void uniform1fv(UniformLocation locationPacked, GLsizei count, const GLfloat *value); \
+ void uniform1i(UniformLocation locationPacked, GLint v0); \
+ void uniform1iv(UniformLocation locationPacked, GLsizei count, const GLint *value); \
+ void uniform2f(UniformLocation locationPacked, GLfloat v0, GLfloat v1); \
+ void uniform2fv(UniformLocation locationPacked, GLsizei count, const GLfloat *value); \
+ void uniform2i(UniformLocation locationPacked, GLint v0, GLint v1); \
+ void uniform2iv(UniformLocation locationPacked, GLsizei count, const GLint *value); \
+ void uniform3f(UniformLocation locationPacked, GLfloat v0, GLfloat v1, GLfloat v2); \
+ void uniform3fv(UniformLocation locationPacked, GLsizei count, const GLfloat *value); \
+ void uniform3i(UniformLocation locationPacked, GLint v0, GLint v1, GLint v2); \
+ void uniform3iv(UniformLocation locationPacked, GLsizei count, const GLint *value); \
+ void uniform4f(UniformLocation locationPacked, GLfloat v0, GLfloat v1, GLfloat v2, \
+ GLfloat v3); \
+ void uniform4fv(UniformLocation locationPacked, GLsizei count, const GLfloat *value); \
+ void uniform4i(UniformLocation locationPacked, GLint v0, GLint v1, GLint v2, GLint v3); \
+ void uniform4iv(UniformLocation locationPacked, GLsizei count, const GLint *value); \
+ void uniformMatrix2fv(UniformLocation locationPacked, GLsizei count, GLboolean transpose, \
+ const GLfloat *value); \
+ void uniformMatrix3fv(UniformLocation locationPacked, GLsizei count, GLboolean transpose, \
+ const GLfloat *value); \
+ void uniformMatrix4fv(UniformLocation locationPacked, GLsizei count, GLboolean transpose, \
+ const GLfloat *value); \
+ void useProgram(ShaderProgramID programPacked); \
+ void validateProgram(ShaderProgramID programPacked); \
+ void vertexAttrib1f(GLuint index, GLfloat x); \
+ void vertexAttrib1fv(GLuint index, const GLfloat *v); \
+ void vertexAttrib2f(GLuint index, GLfloat x, GLfloat y); \
+ void vertexAttrib2fv(GLuint index, const GLfloat *v); \
+ void vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z); \
+ void vertexAttrib3fv(GLuint index, const GLfloat *v); \
+ void vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); \
+ void vertexAttrib4fv(GLuint index, const GLfloat *v); \
+ void vertexAttribPointer(GLuint index, GLint size, VertexAttribType typePacked, \
+ GLboolean normalized, GLsizei stride, const void *pointer); \
+ void viewport(GLint x, GLint y, GLsizei width, GLsizei height);
+
+#endif // ANGLE_CONTEXT_API_2_0_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libANGLE/Context_gles_3_0_autogen.h b/gfx/angle/checkout/src/libANGLE/Context_gles_3_0_autogen.h
new file mode 100644
index 0000000000..f87f49f43d
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Context_gles_3_0_autogen.h
@@ -0,0 +1,164 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml.
+//
+// Copyright 2020 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.
+//
+// Context_gles_3_0_autogen.h: Creates a macro for interfaces in Context.
+
+#ifndef ANGLE_CONTEXT_GLES_3_0_AUTOGEN_H_
+#define ANGLE_CONTEXT_GLES_3_0_AUTOGEN_H_
+
+#define ANGLE_GLES_3_0_CONTEXT_API \
+ void beginQuery(QueryType targetPacked, QueryID idPacked); \
+ void beginTransformFeedback(PrimitiveMode primitiveModePacked); \
+ void bindBufferBase(BufferBinding targetPacked, GLuint index, BufferID bufferPacked); \
+ void bindBufferRange(BufferBinding targetPacked, GLuint index, BufferID bufferPacked, \
+ GLintptr offset, GLsizeiptr size); \
+ void bindSampler(GLuint unit, SamplerID samplerPacked); \
+ void bindTransformFeedback(GLenum target, TransformFeedbackID idPacked); \
+ void bindVertexArray(VertexArrayID arrayPacked); \
+ void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, \
+ GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); \
+ void clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); \
+ void clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value); \
+ void clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value); \
+ void clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value); \
+ GLenum clientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout); \
+ void compressedTexImage3D(TextureTarget targetPacked, GLint level, GLenum internalformat, \
+ GLsizei width, GLsizei height, GLsizei depth, GLint border, \
+ GLsizei imageSize, const void *data); \
+ void compressedTexSubImage3D(TextureTarget targetPacked, GLint level, GLint xoffset, \
+ GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, \
+ GLsizei depth, GLenum format, GLsizei imageSize, \
+ const void *data); \
+ void copyBufferSubData(BufferBinding readTargetPacked, BufferBinding writeTargetPacked, \
+ GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); \
+ void copyTexSubImage3D(TextureTarget targetPacked, GLint level, GLint xoffset, GLint yoffset, \
+ GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); \
+ void deleteQueries(GLsizei n, const QueryID *idsPacked); \
+ void deleteSamplers(GLsizei count, const SamplerID *samplersPacked); \
+ void deleteSync(GLsync sync); \
+ void deleteTransformFeedbacks(GLsizei n, const TransformFeedbackID *idsPacked); \
+ void deleteVertexArrays(GLsizei n, const VertexArrayID *arraysPacked); \
+ void drawArraysInstanced(PrimitiveMode modePacked, GLint first, GLsizei count, \
+ GLsizei instancecount); \
+ void drawBuffers(GLsizei n, const GLenum *bufs); \
+ void drawElementsInstanced(PrimitiveMode modePacked, GLsizei count, \
+ DrawElementsType typePacked, const void *indices, \
+ GLsizei instancecount); \
+ void drawRangeElements(PrimitiveMode modePacked, GLuint start, GLuint end, GLsizei count, \
+ DrawElementsType typePacked, const void *indices); \
+ void endQuery(QueryType targetPacked); \
+ void endTransformFeedback(); \
+ GLsync fenceSync(GLenum condition, GLbitfield flags); \
+ void flushMappedBufferRange(BufferBinding targetPacked, GLintptr offset, GLsizeiptr length); \
+ void framebufferTextureLayer(GLenum target, GLenum attachment, TextureID texturePacked, \
+ GLint level, GLint layer); \
+ void genQueries(GLsizei n, QueryID *idsPacked); \
+ void genSamplers(GLsizei count, SamplerID *samplersPacked); \
+ void genTransformFeedbacks(GLsizei n, TransformFeedbackID *idsPacked); \
+ void genVertexArrays(GLsizei n, VertexArrayID *arraysPacked); \
+ void getActiveUniformBlockName(ShaderProgramID programPacked, \
+ UniformBlockIndex uniformBlockIndexPacked, GLsizei bufSize, \
+ GLsizei *length, GLchar *uniformBlockName); \
+ void getActiveUniformBlockiv(ShaderProgramID programPacked, \
+ UniformBlockIndex uniformBlockIndexPacked, GLenum pname, \
+ GLint *params); \
+ void getActiveUniformsiv(ShaderProgramID programPacked, GLsizei uniformCount, \
+ const GLuint *uniformIndices, GLenum pname, GLint *params); \
+ void getBufferParameteri64v(BufferBinding targetPacked, GLenum pname, GLint64 *params); \
+ void getBufferPointerv(BufferBinding targetPacked, GLenum pname, void **params); \
+ GLint getFragDataLocation(ShaderProgramID programPacked, const GLchar *name); \
+ void getInteger64i_v(GLenum target, GLuint index, GLint64 *data); \
+ void getInteger64v(GLenum pname, GLint64 *data); \
+ void getIntegeri_v(GLenum target, GLuint index, GLint *data); \
+ void getInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei count, \
+ GLint *params); \
+ void getProgramBinary(ShaderProgramID programPacked, GLsizei bufSize, GLsizei *length, \
+ GLenum *binaryFormat, void *binary); \
+ void getQueryObjectuiv(QueryID idPacked, GLenum pname, GLuint *params); \
+ void getQueryiv(QueryType targetPacked, GLenum pname, GLint *params); \
+ void getSamplerParameterfv(SamplerID samplerPacked, GLenum pname, GLfloat *params); \
+ void getSamplerParameteriv(SamplerID samplerPacked, GLenum pname, GLint *params); \
+ const GLubyte *getStringi(GLenum name, GLuint index); \
+ void getSynciv(GLsync sync, GLenum pname, GLsizei count, GLsizei *length, GLint *values); \
+ void getTransformFeedbackVarying(ShaderProgramID programPacked, GLuint index, GLsizei bufSize, \
+ GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); \
+ GLuint getUniformBlockIndex(ShaderProgramID programPacked, const GLchar *uniformBlockName); \
+ void getUniformIndices(ShaderProgramID programPacked, GLsizei uniformCount, \
+ const GLchar *const *uniformNames, GLuint *uniformIndices); \
+ void getUniformuiv(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLuint *params); \
+ void getVertexAttribIiv(GLuint index, GLenum pname, GLint *params); \
+ void getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params); \
+ void invalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments); \
+ void invalidateSubFramebuffer(GLenum target, GLsizei numAttachments, \
+ const GLenum *attachments, GLint x, GLint y, GLsizei width, \
+ GLsizei height); \
+ GLboolean isQuery(QueryID idPacked) const; \
+ GLboolean isSampler(SamplerID samplerPacked) const; \
+ GLboolean isSync(GLsync sync) const; \
+ GLboolean isTransformFeedback(TransformFeedbackID idPacked) const; \
+ GLboolean isVertexArray(VertexArrayID arrayPacked) const; \
+ void *mapBufferRange(BufferBinding targetPacked, GLintptr offset, GLsizeiptr length, \
+ GLbitfield access); \
+ void pauseTransformFeedback(); \
+ void programBinary(ShaderProgramID programPacked, GLenum binaryFormat, const void *binary, \
+ GLsizei length); \
+ void programParameteri(ShaderProgramID programPacked, GLenum pname, GLint value); \
+ void readBuffer(GLenum src); \
+ void renderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, \
+ GLsizei width, GLsizei height); \
+ void resumeTransformFeedback(); \
+ void samplerParameterf(SamplerID samplerPacked, GLenum pname, GLfloat param); \
+ void samplerParameterfv(SamplerID samplerPacked, GLenum pname, const GLfloat *param); \
+ void samplerParameteri(SamplerID samplerPacked, GLenum pname, GLint param); \
+ void samplerParameteriv(SamplerID samplerPacked, GLenum pname, const GLint *param); \
+ void texImage3D(TextureTarget targetPacked, GLint level, GLint internalformat, GLsizei width, \
+ GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, \
+ const void *pixels); \
+ void texStorage2D(TextureType targetPacked, GLsizei levels, GLenum internalformat, \
+ GLsizei width, GLsizei height); \
+ void texStorage3D(TextureType targetPacked, GLsizei levels, GLenum internalformat, \
+ GLsizei width, GLsizei height, GLsizei depth); \
+ void texSubImage3D(TextureTarget targetPacked, GLint level, GLint xoffset, GLint yoffset, \
+ GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, \
+ GLenum type, const void *pixels); \
+ void transformFeedbackVaryings(ShaderProgramID programPacked, GLsizei count, \
+ const GLchar *const *varyings, GLenum bufferMode); \
+ void uniform1ui(UniformLocation locationPacked, GLuint v0); \
+ void uniform1uiv(UniformLocation locationPacked, GLsizei count, const GLuint *value); \
+ void uniform2ui(UniformLocation locationPacked, GLuint v0, GLuint v1); \
+ void uniform2uiv(UniformLocation locationPacked, GLsizei count, const GLuint *value); \
+ void uniform3ui(UniformLocation locationPacked, GLuint v0, GLuint v1, GLuint v2); \
+ void uniform3uiv(UniformLocation locationPacked, GLsizei count, const GLuint *value); \
+ void uniform4ui(UniformLocation locationPacked, GLuint v0, GLuint v1, GLuint v2, GLuint v3); \
+ void uniform4uiv(UniformLocation locationPacked, GLsizei count, const GLuint *value); \
+ void uniformBlockBinding(ShaderProgramID programPacked, \
+ UniformBlockIndex uniformBlockIndexPacked, \
+ GLuint uniformBlockBinding); \
+ void uniformMatrix2x3fv(UniformLocation locationPacked, GLsizei count, GLboolean transpose, \
+ const GLfloat *value); \
+ void uniformMatrix2x4fv(UniformLocation locationPacked, GLsizei count, GLboolean transpose, \
+ const GLfloat *value); \
+ void uniformMatrix3x2fv(UniformLocation locationPacked, GLsizei count, GLboolean transpose, \
+ const GLfloat *value); \
+ void uniformMatrix3x4fv(UniformLocation locationPacked, GLsizei count, GLboolean transpose, \
+ const GLfloat *value); \
+ void uniformMatrix4x2fv(UniformLocation locationPacked, GLsizei count, GLboolean transpose, \
+ const GLfloat *value); \
+ void uniformMatrix4x3fv(UniformLocation locationPacked, GLsizei count, GLboolean transpose, \
+ const GLfloat *value); \
+ GLboolean unmapBuffer(BufferBinding targetPacked); \
+ void vertexAttribDivisor(GLuint index, GLuint divisor); \
+ void vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w); \
+ void vertexAttribI4iv(GLuint index, const GLint *v); \
+ void vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); \
+ void vertexAttribI4uiv(GLuint index, const GLuint *v); \
+ void vertexAttribIPointer(GLuint index, GLint size, VertexAttribType typePacked, \
+ GLsizei stride, const void *pointer); \
+ void waitSync(GLsync sync, GLbitfield flags, GLuint64 timeout);
+
+#endif // ANGLE_CONTEXT_API_3_0_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libANGLE/Context_gles_3_1_autogen.h b/gfx/angle/checkout/src/libANGLE/Context_gles_3_1_autogen.h
new file mode 100644
index 0000000000..0d8c5dcabd
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Context_gles_3_1_autogen.h
@@ -0,0 +1,133 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml.
+//
+// Copyright 2020 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.
+//
+// Context_gles_3_1_autogen.h: Creates a macro for interfaces in Context.
+
+#ifndef ANGLE_CONTEXT_GLES_3_1_AUTOGEN_H_
+#define ANGLE_CONTEXT_GLES_3_1_AUTOGEN_H_
+
+#define ANGLE_GLES_3_1_CONTEXT_API \
+ void activeShaderProgram(ProgramPipelineID pipelinePacked, ShaderProgramID programPacked); \
+ void bindImageTexture(GLuint unit, TextureID texturePacked, GLint level, GLboolean layered, \
+ GLint layer, GLenum access, GLenum format); \
+ void bindProgramPipeline(ProgramPipelineID pipelinePacked); \
+ void bindVertexBuffer(GLuint bindingindex, BufferID bufferPacked, GLintptr offset, \
+ GLsizei stride); \
+ GLuint createShaderProgramv(ShaderType typePacked, GLsizei count, \
+ const GLchar *const *strings); \
+ void deleteProgramPipelines(GLsizei n, const ProgramPipelineID *pipelinesPacked); \
+ void dispatchCompute(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); \
+ void dispatchComputeIndirect(GLintptr indirect); \
+ void drawArraysIndirect(PrimitiveMode modePacked, const void *indirect); \
+ void drawElementsIndirect(PrimitiveMode modePacked, DrawElementsType typePacked, \
+ const void *indirect); \
+ void framebufferParameteri(GLenum target, GLenum pname, GLint param); \
+ void genProgramPipelines(GLsizei n, ProgramPipelineID *pipelinesPacked); \
+ void getBooleani_v(GLenum target, GLuint index, GLboolean *data); \
+ void getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params); \
+ void getMultisamplefv(GLenum pname, GLuint index, GLfloat *val); \
+ void getProgramInterfaceiv(ShaderProgramID programPacked, GLenum programInterface, \
+ GLenum pname, GLint *params); \
+ void getProgramPipelineInfoLog(ProgramPipelineID pipelinePacked, GLsizei bufSize, \
+ GLsizei *length, GLchar *infoLog); \
+ void getProgramPipelineiv(ProgramPipelineID pipelinePacked, GLenum pname, GLint *params); \
+ GLuint getProgramResourceIndex(ShaderProgramID programPacked, GLenum programInterface, \
+ const GLchar *name); \
+ GLint getProgramResourceLocation(ShaderProgramID programPacked, GLenum programInterface, \
+ const GLchar *name); \
+ void getProgramResourceName(ShaderProgramID programPacked, GLenum programInterface, \
+ GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); \
+ void getProgramResourceiv(ShaderProgramID programPacked, GLenum programInterface, \
+ GLuint index, GLsizei propCount, const GLenum *props, GLsizei count, \
+ GLsizei *length, GLint *params); \
+ void getTexLevelParameterfv(TextureTarget targetPacked, GLint level, GLenum pname, \
+ GLfloat *params); \
+ void getTexLevelParameteriv(TextureTarget targetPacked, GLint level, GLenum pname, \
+ GLint *params); \
+ GLboolean isProgramPipeline(ProgramPipelineID pipelinePacked) const; \
+ void memoryBarrier(GLbitfield barriers); \
+ void memoryBarrierByRegion(GLbitfield barriers); \
+ void programUniform1f(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLfloat v0); \
+ void programUniform1fv(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei count, const GLfloat *value); \
+ void programUniform1i(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLint v0); \
+ void programUniform1iv(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei count, const GLint *value); \
+ void programUniform1ui(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLuint v0); \
+ void programUniform1uiv(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei count, const GLuint *value); \
+ void programUniform2f(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLfloat v0, GLfloat v1); \
+ void programUniform2fv(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei count, const GLfloat *value); \
+ void programUniform2i(ShaderProgramID programPacked, UniformLocation locationPacked, GLint v0, \
+ GLint v1); \
+ void programUniform2iv(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei count, const GLint *value); \
+ void programUniform2ui(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLuint v0, GLuint v1); \
+ void programUniform2uiv(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei count, const GLuint *value); \
+ void programUniform3f(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLfloat v0, GLfloat v1, GLfloat v2); \
+ void programUniform3fv(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei count, const GLfloat *value); \
+ void programUniform3i(ShaderProgramID programPacked, UniformLocation locationPacked, GLint v0, \
+ GLint v1, GLint v2); \
+ void programUniform3iv(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei count, const GLint *value); \
+ void programUniform3ui(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLuint v0, GLuint v1, GLuint v2); \
+ void programUniform3uiv(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei count, const GLuint *value); \
+ void programUniform4f(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); \
+ void programUniform4fv(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei count, const GLfloat *value); \
+ void programUniform4i(ShaderProgramID programPacked, UniformLocation locationPacked, GLint v0, \
+ GLint v1, GLint v2, GLint v3); \
+ void programUniform4iv(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei count, const GLint *value); \
+ void programUniform4ui(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLuint v0, GLuint v1, GLuint v2, GLuint v3); \
+ void programUniform4uiv(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei count, const GLuint *value); \
+ void programUniformMatrix2fv(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei count, GLboolean transpose, const GLfloat *value); \
+ void programUniformMatrix2x3fv(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei count, GLboolean transpose, const GLfloat *value); \
+ void programUniformMatrix2x4fv(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei count, GLboolean transpose, const GLfloat *value); \
+ void programUniformMatrix3fv(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei count, GLboolean transpose, const GLfloat *value); \
+ void programUniformMatrix3x2fv(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei count, GLboolean transpose, const GLfloat *value); \
+ void programUniformMatrix3x4fv(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei count, GLboolean transpose, const GLfloat *value); \
+ void programUniformMatrix4fv(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei count, GLboolean transpose, const GLfloat *value); \
+ void programUniformMatrix4x2fv(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei count, GLboolean transpose, const GLfloat *value); \
+ void programUniformMatrix4x3fv(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei count, GLboolean transpose, const GLfloat *value); \
+ void sampleMaski(GLuint maskNumber, GLbitfield mask); \
+ void texStorage2DMultisample(TextureType targetPacked, GLsizei samples, GLenum internalformat, \
+ GLsizei width, GLsizei height, GLboolean fixedsamplelocations); \
+ void useProgramStages(ProgramPipelineID pipelinePacked, GLbitfield stages, \
+ ShaderProgramID programPacked); \
+ void validateProgramPipeline(ProgramPipelineID pipelinePacked); \
+ void vertexAttribBinding(GLuint attribindex, GLuint bindingindex); \
+ void vertexAttribFormat(GLuint attribindex, GLint size, VertexAttribType typePacked, \
+ GLboolean normalized, GLuint relativeoffset); \
+ void vertexAttribIFormat(GLuint attribindex, GLint size, VertexAttribType typePacked, \
+ GLuint relativeoffset); \
+ void vertexBindingDivisor(GLuint bindingindex, GLuint divisor);
+
+#endif // ANGLE_CONTEXT_API_3_1_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libANGLE/Context_gles_3_2_autogen.h b/gfx/angle/checkout/src/libANGLE/Context_gles_3_2_autogen.h
new file mode 100644
index 0000000000..520b86c130
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Context_gles_3_2_autogen.h
@@ -0,0 +1,83 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml.
+//
+// Copyright 2020 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.
+//
+// Context_gles_3_2_autogen.h: Creates a macro for interfaces in Context.
+
+#ifndef ANGLE_CONTEXT_GLES_3_2_AUTOGEN_H_
+#define ANGLE_CONTEXT_GLES_3_2_AUTOGEN_H_
+
+#define ANGLE_GLES_3_2_CONTEXT_API \
+ void blendBarrier(); \
+ void blendEquationSeparatei(GLuint buf, GLenum modeRGB, GLenum modeAlpha); \
+ void blendEquationi(GLuint buf, GLenum mode); \
+ void blendFuncSeparatei(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, \
+ GLenum dstAlpha); \
+ void blendFunci(GLuint buf, GLenum src, GLenum dst); \
+ void colorMaski(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); \
+ void copyImageSubData(GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, \
+ GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, \
+ GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, \
+ GLsizei srcHeight, GLsizei srcDepth); \
+ void debugMessageCallback(GLDEBUGPROC callback, const void *userParam); \
+ void debugMessageControl(GLenum source, GLenum type, GLenum severity, GLsizei count, \
+ const GLuint *ids, GLboolean enabled); \
+ void debugMessageInsert(GLenum source, GLenum type, GLuint id, GLenum severity, \
+ GLsizei length, const GLchar *buf); \
+ void disablei(GLenum target, GLuint index); \
+ void drawElementsBaseVertex(PrimitiveMode modePacked, GLsizei count, \
+ DrawElementsType typePacked, const void *indices, \
+ GLint basevertex); \
+ void drawElementsInstancedBaseVertex(PrimitiveMode modePacked, GLsizei count, \
+ DrawElementsType typePacked, const void *indices, \
+ GLsizei instancecount, GLint basevertex); \
+ void drawRangeElementsBaseVertex(PrimitiveMode modePacked, GLuint start, GLuint end, \
+ GLsizei count, DrawElementsType typePacked, \
+ const void *indices, GLint basevertex); \
+ void enablei(GLenum target, GLuint index); \
+ void framebufferTexture(GLenum target, GLenum attachment, TextureID texturePacked, \
+ GLint level); \
+ GLuint getDebugMessageLog(GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, \
+ GLuint *ids, GLenum *severities, GLsizei *lengths, \
+ GLchar *messageLog); \
+ GLenum getGraphicsResetStatus(); \
+ void getObjectLabel(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, \
+ GLchar *label); \
+ void getObjectPtrLabel(const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); \
+ void getPointerv(GLenum pname, void **params); \
+ void getSamplerParameterIiv(SamplerID samplerPacked, GLenum pname, GLint *params); \
+ void getSamplerParameterIuiv(SamplerID samplerPacked, GLenum pname, GLuint *params); \
+ void getTexParameterIiv(TextureType targetPacked, GLenum pname, GLint *params); \
+ void getTexParameterIuiv(TextureType targetPacked, GLenum pname, GLuint *params); \
+ void getnUniformfv(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei bufSize, GLfloat *params); \
+ void getnUniformiv(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei bufSize, GLint *params); \
+ void getnUniformuiv(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei bufSize, GLuint *params); \
+ GLboolean isEnabledi(GLenum target, GLuint index) const; \
+ void minSampleShading(GLfloat value); \
+ void objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label); \
+ void objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label); \
+ void patchParameteri(GLenum pname, GLint value); \
+ void popDebugGroup(); \
+ void primitiveBoundingBox(GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, \
+ GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW); \
+ void pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message); \
+ void readnPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, \
+ GLsizei bufSize, void *data); \
+ void samplerParameterIiv(SamplerID samplerPacked, GLenum pname, const GLint *param); \
+ void samplerParameterIuiv(SamplerID samplerPacked, GLenum pname, const GLuint *param); \
+ void texBuffer(TextureType targetPacked, GLenum internalformat, BufferID bufferPacked); \
+ void texBufferRange(TextureType targetPacked, GLenum internalformat, BufferID bufferPacked, \
+ GLintptr offset, GLsizeiptr size); \
+ void texParameterIiv(TextureType targetPacked, GLenum pname, const GLint *params); \
+ void texParameterIuiv(TextureType targetPacked, GLenum pname, const GLuint *params); \
+ void texStorage3DMultisample(TextureType targetPacked, GLsizei samples, GLenum internalformat, \
+ GLsizei width, GLsizei height, GLsizei depth, \
+ GLboolean fixedsamplelocations);
+
+#endif // ANGLE_CONTEXT_API_3_2_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libANGLE/Context_gles_ext_autogen.h b/gfx/angle/checkout/src/libANGLE/Context_gles_ext_autogen.h
new file mode 100644
index 0000000000..286a5061e2
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Context_gles_ext_autogen.h
@@ -0,0 +1,616 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml.
+//
+// Copyright 2020 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.
+//
+// Context_gles_ext_autogen.h: Creates a macro for interfaces in Context.
+
+#ifndef ANGLE_CONTEXT_GLES_EXT_AUTOGEN_H_
+#define ANGLE_CONTEXT_GLES_EXT_AUTOGEN_H_
+
+#define ANGLE_GLES_EXT_CONTEXT_API \
+ \
+ /* GLES1 Extensions */ \
+ \
+ /* GL_OES_draw_texture */ \
+ void drawTexf(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height); \
+ void drawTexfv(const GLfloat *coords); \
+ void drawTexi(GLint x, GLint y, GLint z, GLint width, GLint height); \
+ void drawTexiv(const GLint *coords); \
+ void drawTexs(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height); \
+ void drawTexsv(const GLshort *coords); \
+ void drawTexx(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height); \
+ void drawTexxv(const GLfixed *coords); \
+ /* GL_OES_framebuffer_object */ \
+ /* GL_OES_matrix_palette */ \
+ void currentPaletteMatrix(GLuint matrixpaletteindex); \
+ void loadPaletteFromModelViewMatrix(); \
+ void matrixIndexPointer(GLint size, GLenum type, GLsizei stride, const void *pointer); \
+ void weightPointer(GLint size, GLenum type, GLsizei stride, const void *pointer); \
+ /* GL_OES_point_size_array */ \
+ void pointSizePointer(VertexAttribType typePacked, GLsizei stride, const void *pointer); \
+ /* GL_OES_point_sprite */ \
+ /* GL_OES_query_matrix */ \
+ GLbitfield queryMatrixx(GLfixed *mantissa, GLint *exponent); \
+ /* GL_OES_texture_cube_map */ \
+ void getTexGenfv(GLenum coord, GLenum pname, GLfloat *params); \
+ void getTexGeniv(GLenum coord, GLenum pname, GLint *params); \
+ void getTexGenxv(GLenum coord, GLenum pname, GLfixed *params); \
+ void texGenf(GLenum coord, GLenum pname, GLfloat param); \
+ void texGenfv(GLenum coord, GLenum pname, const GLfloat *params); \
+ void texGeni(GLenum coord, GLenum pname, GLint param); \
+ void texGeniv(GLenum coord, GLenum pname, const GLint *params); \
+ void texGenx(GLenum coord, GLenum pname, GLfixed param); \
+ void texGenxv(GLenum coord, GLenum pname, const GLfixed *params); \
+ \
+ /* GLES2+ Extensions */ \
+ \
+ /* GL_AMD_performance_monitor */ \
+ void beginPerfMonitor(GLuint monitor); \
+ void deletePerfMonitors(GLsizei n, GLuint *monitors); \
+ void endPerfMonitor(GLuint monitor); \
+ void genPerfMonitors(GLsizei n, GLuint *monitors); \
+ void getPerfMonitorCounterData(GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, \
+ GLint *bytesWritten); \
+ void getPerfMonitorCounterInfo(GLuint group, GLuint counter, GLenum pname, void *data); \
+ void getPerfMonitorCounterString(GLuint group, GLuint counter, GLsizei bufSize, \
+ GLsizei *length, GLchar *counterString); \
+ void getPerfMonitorCounters(GLuint group, GLint *numCounters, GLint *maxActiveCounters, \
+ GLsizei counterSize, GLuint *counters); \
+ void getPerfMonitorGroupString(GLuint group, GLsizei bufSize, GLsizei *length, \
+ GLchar *groupString); \
+ void getPerfMonitorGroups(GLint *numGroups, GLsizei groupsSize, GLuint *groups); \
+ void selectPerfMonitorCounters(GLuint monitor, GLboolean enable, GLuint group, \
+ GLint numCounters, GLuint *counterList); \
+ /* GL_ANDROID_extension_pack_es31a */ \
+ /* GL_ANGLE_depth_texture */ \
+ /* GL_ANGLE_framebuffer_blit */ \
+ /* GL_ANGLE_instanced_arrays */ \
+ /* GL_ANGLE_pack_reverse_row_order */ \
+ /* GL_ANGLE_texture_usage */ \
+ /* GL_ANGLE_translated_shader_source */ \
+ void getTranslatedShaderSource(ShaderProgramID shaderPacked, GLsizei bufSize, GLsizei *length, \
+ GLchar *source); \
+ /* GL_APPLE_clip_distance */ \
+ /* GL_ARB_sync */ \
+ /* GL_EXT_EGL_image_array */ \
+ /* GL_EXT_EGL_image_external_wrap_modes */ \
+ /* GL_EXT_EGL_image_storage */ \
+ void eGLImageTargetTexStorage(GLenum target, GLeglImageOES image, const GLint *attrib_list); \
+ void eGLImageTargetTextureStorage(GLuint texture, GLeglImageOES image, \
+ const GLint *attrib_list); \
+ /* GL_EXT_YUV_target */ \
+ /* GL_EXT_base_instance */ \
+ void drawArraysInstancedBaseInstance(PrimitiveMode modePacked, GLint first, GLsizei count, \
+ GLsizei instancecount, GLuint baseinstance); \
+ void drawElementsInstancedBaseInstance(PrimitiveMode modePacked, GLsizei count, \
+ DrawElementsType typePacked, const void *indices, \
+ GLsizei instancecount, GLuint baseinstance); \
+ void drawElementsInstancedBaseVertexBaseInstance( \
+ PrimitiveMode modePacked, GLsizei count, DrawElementsType typePacked, const void *indices, \
+ GLsizei instancecount, GLint basevertex, GLuint baseinstance); \
+ /* GL_EXT_blend_func_extended */ \
+ void bindFragDataLocation(ShaderProgramID programPacked, GLuint color, const GLchar *name); \
+ void bindFragDataLocationIndexed(ShaderProgramID programPacked, GLuint colorNumber, \
+ GLuint index, const GLchar *name); \
+ GLint getFragDataIndex(ShaderProgramID programPacked, const GLchar *name); \
+ GLint getProgramResourceLocationIndex(ShaderProgramID programPacked, GLenum programInterface, \
+ const GLchar *name); \
+ /* GL_EXT_blend_minmax */ \
+ /* GL_EXT_buffer_storage */ \
+ void bufferStorage(BufferBinding targetPacked, GLsizeiptr size, const void *data, \
+ GLbitfield flags); \
+ /* GL_EXT_clip_control */ \
+ void clipControl(GLenum origin, GLenum depth); \
+ /* GL_EXT_clip_cull_distance */ \
+ /* GL_EXT_color_buffer_float */ \
+ /* GL_EXT_color_buffer_half_float */ \
+ /* GL_EXT_compressed_ETC1_RGB8_sub_texture */ \
+ /* GL_EXT_copy_image */ \
+ /* GL_EXT_debug_label */ \
+ void labelObject(GLenum type, GLuint object, GLsizei length, const GLchar *label); \
+ /* GL_EXT_debug_marker */ \
+ void insertEventMarker(GLsizei length, const GLchar *marker); \
+ void popGroupMarker(); \
+ void pushGroupMarker(GLsizei length, const GLchar *marker); \
+ /* GL_EXT_discard_framebuffer */ \
+ void discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments); \
+ /* GL_EXT_disjoint_timer_query */ \
+ void getQueryObjecti64v(QueryID idPacked, GLenum pname, GLint64 *params); \
+ void getQueryObjectiv(QueryID idPacked, GLenum pname, GLint *params); \
+ void getQueryObjectui64v(QueryID idPacked, GLenum pname, GLuint64 *params); \
+ void queryCounter(QueryID idPacked, QueryType targetPacked); \
+ /* GL_EXT_draw_buffers */ \
+ /* GL_EXT_draw_buffers_indexed */ \
+ /* GL_EXT_draw_elements_base_vertex */ \
+ void multiDrawElementsBaseVertex(PrimitiveMode modePacked, const GLsizei *count, \
+ DrawElementsType typePacked, const void *const *indices, \
+ GLsizei drawcount, const GLint *basevertex); \
+ /* GL_EXT_external_buffer */ \
+ void bufferStorageExternal(BufferBinding targetPacked, GLintptr offset, GLsizeiptr size, \
+ GLeglClientBufferEXT clientBuffer, GLbitfield flags); \
+ void namedBufferStorageExternal(GLuint buffer, GLintptr offset, GLsizeiptr size, \
+ GLeglClientBufferEXT clientBuffer, GLbitfield flags); \
+ /* GL_EXT_float_blend */ \
+ /* GL_EXT_frag_depth */ \
+ /* GL_EXT_geometry_shader */ \
+ /* GL_EXT_gpu_shader5 */ \
+ /* GL_EXT_instanced_arrays */ \
+ /* GL_EXT_map_buffer_range */ \
+ /* GL_EXT_memory_object */ \
+ void bufferStorageMem(TextureType targetPacked, GLsizeiptr size, MemoryObjectID memoryPacked, \
+ GLuint64 offset); \
+ void createMemoryObjects(GLsizei n, MemoryObjectID *memoryObjectsPacked); \
+ void deleteMemoryObjects(GLsizei n, const MemoryObjectID *memoryObjectsPacked); \
+ void getMemoryObjectParameteriv(MemoryObjectID memoryObjectPacked, GLenum pname, \
+ GLint *params); \
+ void getUnsignedBytev(GLenum pname, GLubyte *data); \
+ void getUnsignedBytei_v(GLenum target, GLuint index, GLubyte *data); \
+ GLboolean isMemoryObject(MemoryObjectID memoryObjectPacked) const; \
+ void memoryObjectParameteriv(MemoryObjectID memoryObjectPacked, GLenum pname, \
+ const GLint *params); \
+ void texStorageMem2D(TextureType targetPacked, GLsizei levels, GLenum internalFormat, \
+ GLsizei width, GLsizei height, MemoryObjectID memoryPacked, \
+ GLuint64 offset); \
+ void texStorageMem2DMultisample(TextureType targetPacked, GLsizei samples, \
+ GLenum internalFormat, GLsizei width, GLsizei height, \
+ GLboolean fixedSampleLocations, MemoryObjectID memoryPacked, \
+ GLuint64 offset); \
+ void texStorageMem3D(TextureType targetPacked, GLsizei levels, GLenum internalFormat, \
+ GLsizei width, GLsizei height, GLsizei depth, \
+ MemoryObjectID memoryPacked, GLuint64 offset); \
+ void texStorageMem3DMultisample(TextureType targetPacked, GLsizei samples, \
+ GLenum internalFormat, GLsizei width, GLsizei height, \
+ GLsizei depth, GLboolean fixedSampleLocations, \
+ MemoryObjectID memoryPacked, GLuint64 offset); \
+ /* GL_EXT_memory_object_fd */ \
+ void importMemoryFd(MemoryObjectID memoryPacked, GLuint64 size, HandleType handleTypePacked, \
+ GLint fd); \
+ /* GL_EXT_multi_draw_indirect */ \
+ void multiDrawArraysIndirect(PrimitiveMode modePacked, const void *indirect, \
+ GLsizei drawcount, GLsizei stride); \
+ void multiDrawElementsIndirect(PrimitiveMode modePacked, DrawElementsType typePacked, \
+ const void *indirect, GLsizei drawcount, GLsizei stride); \
+ /* GL_EXT_multisample_compatibility */ \
+ /* GL_EXT_multisampled_render_to_texture */ \
+ void framebufferTexture2DMultisample(GLenum target, GLenum attachment, \
+ TextureTarget textargetPacked, TextureID texturePacked, \
+ GLint level, GLsizei samples); \
+ void renderbufferStorageMultisampleEXT(GLenum target, GLsizei samples, GLenum internalformat, \
+ GLsizei width, GLsizei height); \
+ /* GL_EXT_multisampled_render_to_texture2 */ \
+ /* GL_EXT_occlusion_query_boolean */ \
+ /* GL_EXT_primitive_bounding_box */ \
+ /* GL_EXT_protected_textures */ \
+ /* GL_EXT_pvrtc_sRGB */ \
+ /* GL_EXT_read_format_bgra */ \
+ /* GL_EXT_robustness */ \
+ /* GL_EXT_sRGB */ \
+ /* GL_EXT_sRGB_write_control */ \
+ /* GL_EXT_semaphore */ \
+ void deleteSemaphores(GLsizei n, const SemaphoreID *semaphoresPacked); \
+ void genSemaphores(GLsizei n, SemaphoreID *semaphoresPacked); \
+ void getSemaphoreParameterui64v(SemaphoreID semaphorePacked, GLenum pname, GLuint64 *params); \
+ GLboolean isSemaphore(SemaphoreID semaphorePacked) const; \
+ void semaphoreParameterui64v(SemaphoreID semaphorePacked, GLenum pname, \
+ const GLuint64 *params); \
+ void signalSemaphore(SemaphoreID semaphorePacked, GLuint numBufferBarriers, \
+ const BufferID *buffersPacked, GLuint numTextureBarriers, \
+ const TextureID *texturesPacked, const GLenum *dstLayouts); \
+ void waitSemaphore(SemaphoreID semaphorePacked, GLuint numBufferBarriers, \
+ const BufferID *buffersPacked, GLuint numTextureBarriers, \
+ const TextureID *texturesPacked, const GLenum *srcLayouts); \
+ /* GL_EXT_semaphore_fd */ \
+ void importSemaphoreFd(SemaphoreID semaphorePacked, HandleType handleTypePacked, GLint fd); \
+ /* GL_EXT_separate_shader_objects */ \
+ /* GL_EXT_shader_framebuffer_fetch */ \
+ /* GL_EXT_shader_framebuffer_fetch_non_coherent */ \
+ void framebufferFetchBarrier(); \
+ /* GL_EXT_shader_io_blocks */ \
+ /* GL_EXT_shader_non_constant_global_initializers */ \
+ /* GL_EXT_shader_texture_lod */ \
+ /* GL_EXT_shadow_samplers */ \
+ /* GL_EXT_tessellation_shader */ \
+ /* GL_EXT_texture_border_clamp */ \
+ /* GL_EXT_texture_buffer */ \
+ /* GL_EXT_texture_compression_bptc */ \
+ /* GL_EXT_texture_compression_dxt1 */ \
+ /* GL_EXT_texture_compression_rgtc */ \
+ /* GL_EXT_texture_compression_s3tc */ \
+ /* GL_EXT_texture_compression_s3tc_srgb */ \
+ /* GL_EXT_texture_cube_map_array */ \
+ /* GL_EXT_texture_filter_anisotropic */ \
+ /* GL_EXT_texture_format_BGRA8888 */ \
+ /* GL_EXT_texture_format_sRGB_override */ \
+ /* GL_EXT_texture_norm16 */ \
+ /* GL_EXT_texture_rg */ \
+ /* GL_EXT_texture_sRGB_R8 */ \
+ /* GL_EXT_texture_sRGB_RG8 */ \
+ /* GL_EXT_texture_sRGB_decode */ \
+ /* GL_EXT_texture_storage */ \
+ void texStorage1D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); \
+ /* GL_EXT_texture_type_2_10_10_10_REV */ \
+ /* GL_EXT_unpack_subimage */ \
+ /* GL_IMG_texture_compression_pvrtc */ \
+ /* GL_IMG_texture_compression_pvrtc2 */ \
+ /* GL_KHR_blend_equation_advanced */ \
+ /* GL_KHR_debug */ \
+ /* GL_KHR_no_error */ \
+ /* GL_KHR_parallel_shader_compile */ \
+ void maxShaderCompilerThreads(GLuint count); \
+ /* GL_KHR_robust_buffer_access_behavior */ \
+ /* GL_KHR_texture_compression_astc_hdr */ \
+ /* GL_KHR_texture_compression_astc_ldr */ \
+ /* GL_KHR_texture_compression_astc_sliced_3d */ \
+ /* GL_MESA_framebuffer_flip_y */ \
+ void framebufferParameteriMESA(GLenum target, GLenum pname, GLint param); \
+ void getFramebufferParameterivMESA(GLenum target, GLenum pname, GLint *params); \
+ /* GL_NV_EGL_stream_consumer_external */ \
+ /* GL_NV_depth_buffer_float2 */ \
+ /* GL_NV_fence */ \
+ void deleteFencesNV(GLsizei n, const FenceNVID *fencesPacked); \
+ void finishFenceNV(FenceNVID fencePacked); \
+ void genFencesNV(GLsizei n, FenceNVID *fencesPacked); \
+ void getFenceivNV(FenceNVID fencePacked, GLenum pname, GLint *params); \
+ GLboolean isFenceNV(FenceNVID fencePacked) const; \
+ void setFenceNV(FenceNVID fencePacked, GLenum condition); \
+ GLboolean testFenceNV(FenceNVID fencePacked); \
+ /* GL_NV_framebuffer_blit */ \
+ void blitFramebufferNV(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, \
+ GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); \
+ /* GL_NV_pack_subimage */ \
+ /* GL_NV_pixel_buffer_object */ \
+ /* GL_NV_read_depth */ \
+ /* GL_NV_read_depth_stencil */ \
+ /* GL_NV_read_stencil */ \
+ /* GL_NV_robustness_video_memory_purge */ \
+ /* GL_NV_shader_noperspective_interpolation */ \
+ /* GL_OES_EGL_image */ \
+ void eGLImageTargetRenderbufferStorage(GLenum target, GLeglImageOES image); \
+ void eGLImageTargetTexture2D(TextureType targetPacked, GLeglImageOES image); \
+ /* GL_OES_EGL_image_external */ \
+ /* GL_OES_EGL_image_external_essl3 */ \
+ /* GL_OES_EGL_sync */ \
+ /* GL_OES_compressed_EAC_R11_signed_texture */ \
+ /* GL_OES_compressed_EAC_R11_unsigned_texture */ \
+ /* GL_OES_compressed_EAC_RG11_signed_texture */ \
+ /* GL_OES_compressed_EAC_RG11_unsigned_texture */ \
+ /* GL_OES_compressed_ETC1_RGB8_texture */ \
+ /* GL_OES_compressed_ETC2_RGB8_texture */ \
+ /* GL_OES_compressed_ETC2_RGBA8_texture */ \
+ /* GL_OES_compressed_ETC2_punchthroughA_RGBA8_texture */ \
+ /* GL_OES_compressed_ETC2_punchthroughA_sRGB8_alpha_texture */ \
+ /* GL_OES_compressed_ETC2_sRGB8_alpha8_texture */ \
+ /* GL_OES_compressed_ETC2_sRGB8_texture */ \
+ /* GL_OES_compressed_paletted_texture */ \
+ /* GL_OES_copy_image */ \
+ /* GL_OES_depth24 */ \
+ /* GL_OES_depth32 */ \
+ /* GL_OES_depth_texture */ \
+ /* GL_OES_depth_texture_cube_map */ \
+ /* GL_OES_draw_buffers_indexed */ \
+ /* GL_OES_draw_elements_base_vertex */ \
+ /* GL_OES_element_index_uint */ \
+ /* GL_OES_fbo_render_mipmap */ \
+ /* GL_OES_geometry_shader */ \
+ /* GL_OES_get_program_binary */ \
+ /* GL_OES_mapbuffer */ \
+ void *mapBuffer(BufferBinding targetPacked, GLenum access); \
+ /* GL_OES_packed_depth_stencil */ \
+ /* GL_OES_primitive_bounding_box */ \
+ /* GL_OES_rgb8_rgba8 */ \
+ /* GL_OES_sample_shading */ \
+ /* GL_OES_sample_variables */ \
+ /* GL_OES_shader_image_atomic */ \
+ /* GL_OES_shader_io_blocks */ \
+ /* GL_OES_shader_multisample_interpolation */ \
+ /* GL_OES_standard_derivatives */ \
+ /* GL_OES_surfaceless_context */ \
+ /* GL_OES_texture_3D */ \
+ void framebufferTexture3D(GLenum target, GLenum attachment, TextureTarget textargetPacked, \
+ TextureID texturePacked, GLint level, GLint zoffset); \
+ /* GL_OES_texture_border_clamp */ \
+ /* GL_OES_texture_buffer */ \
+ /* GL_OES_texture_compression_astc */ \
+ /* GL_OES_texture_cube_map_array */ \
+ /* GL_OES_texture_float */ \
+ /* GL_OES_texture_float_linear */ \
+ /* GL_OES_texture_half_float */ \
+ /* GL_OES_texture_half_float_linear */ \
+ /* GL_OES_texture_npot */ \
+ /* GL_OES_texture_stencil8 */ \
+ /* GL_OES_texture_storage_multisample_2d_array */ \
+ /* GL_OES_vertex_array_object */ \
+ /* GL_OES_vertex_half_float */ \
+ /* GL_OES_vertex_type_10_10_10_2 */ \
+ /* GL_OVR_multiview */ \
+ void framebufferTextureMultiview(GLenum target, GLenum attachment, TextureID texturePacked, \
+ GLint level, GLint baseViewIndex, GLsizei numViews); \
+ /* GL_OVR_multiview2 */ \
+ /* GL_QCOM_shading_rate */ \
+ void shadingRateQCOM(GLenum rate); \
+ /* GL_WEBGL_video_texture */ \
+ \
+ /* ANGLE Extensions */ \
+ \
+ /* GL_ANGLE_base_vertex_base_instance */ \
+ void drawArraysInstancedBaseInstanceANGLE(PrimitiveMode modePacked, GLint first, \
+ GLsizei count, GLsizei instanceCount, \
+ GLuint baseInstance); \
+ void drawElementsInstancedBaseVertexBaseInstanceANGLE( \
+ PrimitiveMode modePacked, GLsizei count, DrawElementsType typePacked, \
+ const GLvoid *indices, GLsizei instanceCount, GLint baseVertex, GLuint baseInstance); \
+ void multiDrawArraysInstancedBaseInstance( \
+ PrimitiveMode modePacked, const GLint *firsts, const GLsizei *counts, \
+ const GLsizei *instanceCounts, const GLuint *baseInstances, GLsizei drawcount); \
+ void multiDrawElementsInstancedBaseVertexBaseInstance( \
+ PrimitiveMode modePacked, const GLsizei *counts, DrawElementsType typePacked, \
+ const GLvoid *const *indices, const GLsizei *instanceCounts, const GLint *baseVertices, \
+ const GLuint *baseInstances, GLsizei drawcount); \
+ /* GL_ANGLE_base_vertex_base_instance_shader_builtin */ \
+ /* GL_ANGLE_client_arrays */ \
+ /* GL_ANGLE_compressed_texture_etc */ \
+ /* GL_ANGLE_copy_texture_3d */ \
+ void copyTexture3D(TextureID sourceIdPacked, GLint sourceLevel, \
+ TextureTarget destTargetPacked, TextureID destIdPacked, GLint destLevel, \
+ GLint internalFormat, GLenum destType, GLboolean unpackFlipY, \
+ GLboolean unpackPremultiplyAlpha, GLboolean unpackUnmultiplyAlpha); \
+ void copySubTexture3D(TextureID sourceIdPacked, GLint sourceLevel, \
+ TextureTarget destTargetPacked, TextureID destIdPacked, GLint destLevel, \
+ GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLint z, \
+ GLint width, GLint height, GLint depth, GLboolean unpackFlipY, \
+ GLboolean unpackPremultiplyAlpha, GLboolean unpackUnmultiplyAlpha); \
+ /* GL_ANGLE_framebuffer_multisample */ \
+ /* GL_ANGLE_get_image */ \
+ void getTexImage(TextureTarget targetPacked, GLint level, GLenum format, GLenum type, \
+ void *pixels); \
+ void getCompressedTexImage(TextureTarget targetPacked, GLint level, void *pixels); \
+ void getRenderbufferImage(GLenum target, GLenum format, GLenum type, void *pixels); \
+ /* GL_ANGLE_get_serialized_context_string */ \
+ /* GL_ANGLE_get_tex_level_parameter */ \
+ /* GL_ANGLE_logic_op */ \
+ void logicOpANGLE(LogicalOperation opcodePacked); \
+ /* GL_ANGLE_lossy_etc_decode */ \
+ /* GL_ANGLE_memory_object_flags */ \
+ void texStorageMemFlags2D(TextureType targetPacked, GLsizei levels, GLenum internalFormat, \
+ GLsizei width, GLsizei height, MemoryObjectID memoryPacked, \
+ GLuint64 offset, GLbitfield createFlags, GLbitfield usageFlags, \
+ const void *imageCreateInfoPNext); \
+ void texStorageMemFlags2DMultisample( \
+ TextureType targetPacked, GLsizei samples, GLenum internalFormat, GLsizei width, \
+ GLsizei height, GLboolean fixedSampleLocations, MemoryObjectID memoryPacked, \
+ GLuint64 offset, GLbitfield createFlags, GLbitfield usageFlags, \
+ const void *imageCreateInfoPNext); \
+ void texStorageMemFlags3D( \
+ TextureType targetPacked, GLsizei levels, GLenum internalFormat, GLsizei width, \
+ GLsizei height, GLsizei depth, MemoryObjectID memoryPacked, GLuint64 offset, \
+ GLbitfield createFlags, GLbitfield usageFlags, const void *imageCreateInfoPNext); \
+ void texStorageMemFlags3DMultisample( \
+ TextureType targetPacked, GLsizei samples, GLenum internalFormat, GLsizei width, \
+ GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, \
+ MemoryObjectID memoryPacked, GLuint64 offset, GLbitfield createFlags, \
+ GLbitfield usageFlags, const void *imageCreateInfoPNext); \
+ /* GL_ANGLE_memory_object_fuchsia */ \
+ void importMemoryZirconHandle(MemoryObjectID memoryPacked, GLuint64 size, \
+ HandleType handleTypePacked, GLuint handle); \
+ /* GL_ANGLE_memory_size */ \
+ /* GL_ANGLE_multi_draw */ \
+ void multiDrawArrays(PrimitiveMode modePacked, const GLint *firsts, const GLsizei *counts, \
+ GLsizei drawcount); \
+ void multiDrawArraysInstanced(PrimitiveMode modePacked, const GLint *firsts, \
+ const GLsizei *counts, const GLsizei *instanceCounts, \
+ GLsizei drawcount); \
+ void multiDrawElements(PrimitiveMode modePacked, const GLsizei *counts, \
+ DrawElementsType typePacked, const GLvoid *const *indices, \
+ GLsizei drawcount); \
+ void multiDrawElementsInstanced(PrimitiveMode modePacked, const GLsizei *counts, \
+ DrawElementsType typePacked, const GLvoid *const *indices, \
+ const GLsizei *instanceCounts, GLsizei drawcount); \
+ /* GL_ANGLE_multiview_multisample */ \
+ /* GL_ANGLE_program_binary */ \
+ /* GL_ANGLE_program_cache_control */ \
+ /* GL_ANGLE_provoking_vertex */ \
+ void provokingVertex(ProvokingVertexConvention modePacked); \
+ /* GL_ANGLE_read_only_depth_stencil_feedback_loops */ \
+ /* GL_ANGLE_relaxed_vertex_attribute_type */ \
+ /* GL_ANGLE_request_extension */ \
+ void requestExtension(const GLchar *name); \
+ void disableExtension(const GLchar *name); \
+ /* GL_ANGLE_rgbx_internal_format */ \
+ /* GL_ANGLE_robust_client_memory */ \
+ void getBooleanvRobust(GLenum pname, GLsizei bufSize, GLsizei *length, GLboolean *params); \
+ void getBufferParameterivRobust(BufferBinding targetPacked, GLenum pname, GLsizei bufSize, \
+ GLsizei *length, GLint *params); \
+ void getFloatvRobust(GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params); \
+ void getFramebufferAttachmentParameterivRobust(GLenum target, GLenum attachment, GLenum pname, \
+ GLsizei bufSize, GLsizei *length, \
+ GLint *params); \
+ void getIntegervRobust(GLenum pname, GLsizei bufSize, GLsizei *length, GLint *data); \
+ void getProgramivRobust(ShaderProgramID programPacked, GLenum pname, GLsizei bufSize, \
+ GLsizei *length, GLint *params); \
+ void getRenderbufferParameterivRobust(GLenum target, GLenum pname, GLsizei bufSize, \
+ GLsizei *length, GLint *params); \
+ void getShaderivRobust(ShaderProgramID shaderPacked, GLenum pname, GLsizei bufSize, \
+ GLsizei *length, GLint *params); \
+ void getTexParameterfvRobust(TextureType targetPacked, GLenum pname, GLsizei bufSize, \
+ GLsizei *length, GLfloat *params); \
+ void getTexParameterivRobust(TextureType targetPacked, GLenum pname, GLsizei bufSize, \
+ GLsizei *length, GLint *params); \
+ void getUniformfvRobust(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei bufSize, GLsizei *length, GLfloat *params); \
+ void getUniformivRobust(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei bufSize, GLsizei *length, GLint *params); \
+ void getVertexAttribfvRobust(GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, \
+ GLfloat *params); \
+ void getVertexAttribivRobust(GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, \
+ GLint *params); \
+ void getVertexAttribPointervRobust(GLuint index, GLenum pname, GLsizei bufSize, \
+ GLsizei *length, void **pointer); \
+ void readPixelsRobust(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, \
+ GLenum type, GLsizei bufSize, GLsizei *length, GLsizei *columns, \
+ GLsizei *rows, void *pixels); \
+ void texImage2DRobust(TextureTarget targetPacked, GLint level, GLint internalformat, \
+ GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, \
+ GLsizei bufSize, const void *pixels); \
+ void texParameterfvRobust(TextureType targetPacked, GLenum pname, GLsizei bufSize, \
+ const GLfloat *params); \
+ void texParameterivRobust(TextureType targetPacked, GLenum pname, GLsizei bufSize, \
+ const GLint *params); \
+ void texSubImage2DRobust(TextureTarget targetPacked, GLint level, GLint xoffset, \
+ GLint yoffset, GLsizei width, GLsizei height, GLenum format, \
+ GLenum type, GLsizei bufSize, const void *pixels); \
+ void texImage3DRobust(TextureTarget targetPacked, GLint level, GLint internalformat, \
+ GLsizei width, GLsizei height, GLsizei depth, GLint border, \
+ GLenum format, GLenum type, GLsizei bufSize, const void *pixels); \
+ void texSubImage3DRobust(TextureTarget targetPacked, GLint level, GLint xoffset, \
+ GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, \
+ GLsizei depth, GLenum format, GLenum type, GLsizei bufSize, \
+ const void *pixels); \
+ void compressedTexImage2DRobust( \
+ TextureTarget targetPacked, GLint level, GLenum internalformat, GLsizei width, \
+ GLsizei height, GLint border, GLsizei imageSize, GLsizei dataSize, const GLvoid *data); \
+ void compressedTexSubImage2DRobust( \
+ TextureTarget targetPacked, GLint level, GLsizei xoffset, GLsizei yoffset, GLsizei width, \
+ GLsizei height, GLenum format, GLsizei imageSize, GLsizei dataSize, const GLvoid *data); \
+ void compressedTexImage3DRobust(TextureTarget targetPacked, GLint level, \
+ GLenum internalformat, GLsizei width, GLsizei height, \
+ GLsizei depth, GLint border, GLsizei imageSize, \
+ GLsizei dataSize, const GLvoid *data); \
+ void compressedTexSubImage3DRobust(TextureTarget targetPacked, GLint level, GLint xoffset, \
+ GLint yoffset, GLint zoffset, GLsizei width, \
+ GLsizei height, GLsizei depth, GLenum format, \
+ GLsizei imageSize, GLsizei dataSize, const GLvoid *data); \
+ void getQueryivRobust(QueryType targetPacked, GLenum pname, GLsizei bufSize, GLsizei *length, \
+ GLint *params); \
+ void getQueryObjectuivRobust(QueryID idPacked, GLenum pname, GLsizei bufSize, GLsizei *length, \
+ GLuint *params); \
+ void getBufferPointervRobust(BufferBinding targetPacked, GLenum pname, GLsizei bufSize, \
+ GLsizei *length, void **params); \
+ void getIntegeri_vRobust(GLenum target, GLuint index, GLsizei bufSize, GLsizei *length, \
+ GLint *data); \
+ void getInternalformativRobust(GLenum target, GLenum internalformat, GLenum pname, \
+ GLsizei bufSize, GLsizei *length, GLint *params); \
+ void getVertexAttribIivRobust(GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, \
+ GLint *params); \
+ void getVertexAttribIuivRobust(GLuint index, GLenum pname, GLsizei bufSize, GLsizei *length, \
+ GLuint *params); \
+ void getUniformuivRobust(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei bufSize, GLsizei *length, GLuint *params); \
+ void getActiveUniformBlockivRobust(ShaderProgramID programPacked, \
+ UniformBlockIndex uniformBlockIndexPacked, GLenum pname, \
+ GLsizei bufSize, GLsizei *length, GLint *params); \
+ void getInteger64vRobust(GLenum pname, GLsizei bufSize, GLsizei *length, GLint64 *data); \
+ void getInteger64i_vRobust(GLenum target, GLuint index, GLsizei bufSize, GLsizei *length, \
+ GLint64 *data); \
+ void getBufferParameteri64vRobust(BufferBinding targetPacked, GLenum pname, GLsizei bufSize, \
+ GLsizei *length, GLint64 *params); \
+ void samplerParameterivRobust(SamplerID samplerPacked, GLuint pname, GLsizei bufSize, \
+ const GLint *param); \
+ void samplerParameterfvRobust(SamplerID samplerPacked, GLenum pname, GLsizei bufSize, \
+ const GLfloat *param); \
+ void getSamplerParameterivRobust(SamplerID samplerPacked, GLenum pname, GLsizei bufSize, \
+ GLsizei *length, GLint *params); \
+ void getSamplerParameterfvRobust(SamplerID samplerPacked, GLenum pname, GLsizei bufSize, \
+ GLsizei *length, GLfloat *params); \
+ void getFramebufferParameterivRobust(GLenum target, GLenum pname, GLsizei bufSize, \
+ GLsizei *length, GLint *params); \
+ void getProgramInterfaceivRobust(ShaderProgramID programPacked, GLenum programInterface, \
+ GLenum pname, GLsizei bufSize, GLsizei *length, \
+ GLint *params); \
+ void getBooleani_vRobust(GLenum target, GLuint index, GLsizei bufSize, GLsizei *length, \
+ GLboolean *data); \
+ void getMultisamplefvRobust(GLenum pname, GLuint index, GLsizei bufSize, GLsizei *length, \
+ GLfloat *val); \
+ void getTexLevelParameterivRobust(TextureTarget targetPacked, GLint level, GLenum pname, \
+ GLsizei bufSize, GLsizei *length, GLint *params); \
+ void getTexLevelParameterfvRobust(TextureTarget targetPacked, GLint level, GLenum pname, \
+ GLsizei bufSize, GLsizei *length, GLfloat *params); \
+ void getPointervRobustANGLERobust(GLenum pname, GLsizei bufSize, GLsizei *length, \
+ void **params); \
+ void readnPixelsRobust(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, \
+ GLenum type, GLsizei bufSize, GLsizei *length, GLsizei *columns, \
+ GLsizei *rows, void *data); \
+ void getnUniformfvRobust(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei bufSize, GLsizei *length, GLfloat *params); \
+ void getnUniformivRobust(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei bufSize, GLsizei *length, GLint *params); \
+ void getnUniformuivRobust(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ GLsizei bufSize, GLsizei *length, GLuint *params); \
+ void texParameterIivRobust(TextureType targetPacked, GLenum pname, GLsizei bufSize, \
+ const GLint *params); \
+ void texParameterIuivRobust(TextureType targetPacked, GLenum pname, GLsizei bufSize, \
+ const GLuint *params); \
+ void getTexParameterIivRobust(TextureType targetPacked, GLenum pname, GLsizei bufSize, \
+ GLsizei *length, GLint *params); \
+ void getTexParameterIuivRobust(TextureType targetPacked, GLenum pname, GLsizei bufSize, \
+ GLsizei *length, GLuint *params); \
+ void samplerParameterIivRobust(SamplerID samplerPacked, GLenum pname, GLsizei bufSize, \
+ const GLint *param); \
+ void samplerParameterIuivRobust(SamplerID samplerPacked, GLenum pname, GLsizei bufSize, \
+ const GLuint *param); \
+ void getSamplerParameterIivRobust(SamplerID samplerPacked, GLenum pname, GLsizei bufSize, \
+ GLsizei *length, GLint *params); \
+ void getSamplerParameterIuivRobust(SamplerID samplerPacked, GLenum pname, GLsizei bufSize, \
+ GLsizei *length, GLuint *params); \
+ void getQueryObjectivRobust(QueryID idPacked, GLenum pname, GLsizei bufSize, GLsizei *length, \
+ GLint *params); \
+ void getQueryObjecti64vRobust(QueryID idPacked, GLenum pname, GLsizei bufSize, \
+ GLsizei *length, GLint64 *params); \
+ void getQueryObjectui64vRobust(QueryID idPacked, GLenum pname, GLsizei bufSize, \
+ GLsizei *length, GLuint64 *params); \
+ /* GL_ANGLE_robust_fragment_shader_output */ \
+ /* GL_ANGLE_robust_resource_initialization */ \
+ /* GL_ANGLE_semaphore_fuchsia */ \
+ void importSemaphoreZirconHandle(SemaphoreID semaphorePacked, HandleType handleTypePacked, \
+ GLuint handle); \
+ /* GL_ANGLE_shader_pixel_local_storage */ \
+ void framebufferMemorylessPixelLocalStorage(GLint plane, GLenum internalformat); \
+ void framebufferTexturePixelLocalStorage(GLint plane, TextureID backingtexturePacked, \
+ GLint level, GLint layer); \
+ void beginPixelLocalStorage(GLsizei planes, const GLenum *loadops, const void *cleardata); \
+ void endPixelLocalStorage(); \
+ void pixelLocalStorageBarrier(); \
+ /* GL_ANGLE_shader_pixel_local_storage_coherent */ \
+ /* GL_ANGLE_texture_compression_dxt3 */ \
+ /* GL_ANGLE_texture_compression_dxt5 */ \
+ /* GL_ANGLE_texture_external_update */ \
+ void texImage2DExternal(TextureTarget targetPacked, GLint level, GLint internalformat, \
+ GLsizei width, GLsizei height, GLint border, GLenum format, \
+ GLenum type); \
+ void invalidateTexture(TextureType targetPacked); \
+ /* GL_ANGLE_texture_multisample */ \
+ /* GL_ANGLE_texture_rectangle */ \
+ /* GL_ANGLE_vulkan_image */ \
+ void acquireTextures(GLuint numTextures, const TextureID *texturesPacked, \
+ const GLenum *layouts); \
+ void releaseTextures(GLuint numTextures, const TextureID *texturesPacked, GLenum *layouts); \
+ /* GL_ANGLE_webgl_compatibility */ \
+ /* GL_ANGLE_yuv_internal_format */ \
+ /* GL_CHROMIUM_bind_generates_resource */ \
+ /* GL_CHROMIUM_bind_uniform_location */ \
+ void bindUniformLocation(ShaderProgramID programPacked, UniformLocation locationPacked, \
+ const GLchar *name); \
+ /* GL_CHROMIUM_color_buffer_float_rgb */ \
+ /* GL_CHROMIUM_color_buffer_float_rgba */ \
+ /* GL_CHROMIUM_copy_compressed_texture */ \
+ void compressedCopyTexture(TextureID sourceIdPacked, TextureID destIdPacked); \
+ /* GL_CHROMIUM_copy_texture */ \
+ void copyTexture(TextureID sourceIdPacked, GLint sourceLevel, TextureTarget destTargetPacked, \
+ TextureID destIdPacked, GLint destLevel, GLint internalFormat, \
+ GLenum destType, GLboolean unpackFlipY, GLboolean unpackPremultiplyAlpha, \
+ GLboolean unpackUnmultiplyAlpha); \
+ void copySubTexture(TextureID sourceIdPacked, GLint sourceLevel, \
+ TextureTarget destTargetPacked, TextureID destIdPacked, GLint destLevel, \
+ GLint xoffset, GLint yoffset, GLint x, GLint y, GLint width, GLint height, \
+ GLboolean unpackFlipY, GLboolean unpackPremultiplyAlpha, \
+ GLboolean unpackUnmultiplyAlpha); \
+ /* GL_CHROMIUM_framebuffer_mixed_samples */ \
+ void coverageModulation(GLenum components); \
+ /* GL_CHROMIUM_lose_context */ \
+ void loseContext(GraphicsResetStatus currentPacked, GraphicsResetStatus otherPacked); \
+ /* GL_CHROMIUM_sync_query */ \
+ /* GL_CHROMIUM_texture_filtering_hint */
+
+#endif // ANGLE_CONTEXT_API_EXT_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libANGLE/Debug.cpp b/gfx/angle/checkout/src/libANGLE/Debug.cpp
new file mode 100644
index 0000000000..da97ae9d9e
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Debug.cpp
@@ -0,0 +1,507 @@
+//
+// 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.
+//
+
+// Debug.cpp: Defines debug state used for GL_KHR_debug
+
+#include "libANGLE/Debug.h"
+
+#include "common/debug.h"
+
+#include <algorithm>
+#include <tuple>
+
+namespace
+{
+const char *GLSeverityToString(GLenum severity)
+{
+ switch (severity)
+ {
+ case GL_DEBUG_SEVERITY_HIGH:
+ return "HIGH";
+ case GL_DEBUG_SEVERITY_MEDIUM:
+ return "MEDIUM";
+ case GL_DEBUG_SEVERITY_LOW:
+ return "LOW";
+ case GL_DEBUG_SEVERITY_NOTIFICATION:
+ default:
+ return "NOTIFICATION";
+ }
+}
+
+const char *EGLMessageTypeToString(egl::MessageType messageType)
+{
+ switch (messageType)
+ {
+ case egl::MessageType::Critical:
+ return "CRITICAL";
+ case egl::MessageType::Error:
+ return "ERROR";
+ case egl::MessageType::Warn:
+ return "WARNING";
+ case egl::MessageType::Info:
+ default:
+ return "INFO";
+ }
+}
+
+const char *GLMessageTypeToString(GLenum type)
+{
+ switch (type)
+ {
+ case GL_DEBUG_TYPE_ERROR:
+ return "error";
+ case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
+ return "deprecated behavior";
+ case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
+ return "undefined behavior";
+ case GL_DEBUG_TYPE_PORTABILITY:
+ return "portability";
+ case GL_DEBUG_TYPE_PERFORMANCE:
+ return "performance";
+ case GL_DEBUG_TYPE_MARKER:
+ return "marker";
+ case GL_DEBUG_TYPE_PUSH_GROUP:
+ return "start of group";
+ case GL_DEBUG_TYPE_POP_GROUP:
+ return "end of group";
+ case GL_DEBUG_TYPE_OTHER:
+ default:
+ return "other message";
+ }
+}
+} // namespace
+
+namespace gl
+{
+
+Debug::Control::Control() {}
+
+Debug::Control::~Control() {}
+
+Debug::Control::Control(const Control &other) = default;
+
+Debug::Group::Group() {}
+
+Debug::Group::~Group() {}
+
+Debug::Group::Group(const Group &other) = default;
+
+Debug::Debug(bool initialDebugState)
+ : mOutputEnabled(initialDebugState),
+ mCallbackFunction(nullptr),
+ mCallbackUserParam(nullptr),
+ mMessages(),
+ mMaxLoggedMessages(0),
+ mOutputSynchronous(false),
+ mGroups()
+{
+ pushDefaultGroup();
+}
+
+Debug::~Debug() {}
+
+void Debug::setMaxLoggedMessages(GLuint maxLoggedMessages)
+{
+ mMaxLoggedMessages = maxLoggedMessages;
+}
+
+void Debug::setOutputEnabled(bool enabled)
+{
+ mOutputEnabled = enabled;
+}
+
+bool Debug::isOutputEnabled() const
+{
+ return mOutputEnabled;
+}
+
+void Debug::setOutputSynchronous(bool synchronous)
+{
+ mOutputSynchronous = synchronous;
+}
+
+bool Debug::isOutputSynchronous() const
+{
+ return mOutputSynchronous;
+}
+
+void Debug::setCallback(GLDEBUGPROCKHR callback, const void *userParam)
+{
+ mCallbackFunction = callback;
+ mCallbackUserParam = userParam;
+}
+
+GLDEBUGPROCKHR Debug::getCallback() const
+{
+ return mCallbackFunction;
+}
+
+const void *Debug::getUserParam() const
+{
+ return mCallbackUserParam;
+}
+
+void Debug::insertMessage(GLenum source,
+ GLenum type,
+ GLuint id,
+ GLenum severity,
+ const std::string &message,
+ gl::LogSeverity logSeverity,
+ angle::EntryPoint entryPoint) const
+{
+ std::string messageCopy(message);
+ insertMessage(source, type, id, severity, std::move(messageCopy), logSeverity, entryPoint);
+}
+
+void Debug::insertMessage(GLenum source,
+ GLenum type,
+ GLuint id,
+ GLenum severity,
+ std::string &&message,
+ gl::LogSeverity logSeverity,
+ angle::EntryPoint entryPoint) const
+{
+ {
+ // output all messages to the debug log
+ const char *messageTypeString = GLMessageTypeToString(type);
+ const char *severityString = GLSeverityToString(severity);
+ std::ostringstream messageStream;
+ if (entryPoint != angle::EntryPoint::GLInvalid)
+ {
+ messageStream << GetEntryPointName(entryPoint) << ": ";
+ }
+ messageStream << "GL " << messageTypeString << ": " << severityString << ": " << message;
+ switch (logSeverity)
+ {
+ case gl::LOG_FATAL:
+ FATAL() << messageStream.str();
+ break;
+ case gl::LOG_ERR:
+ ERR() << messageStream.str();
+ break;
+ case gl::LOG_WARN:
+ WARN() << messageStream.str();
+ break;
+ case gl::LOG_INFO:
+ INFO() << messageStream.str();
+ break;
+ case gl::LOG_EVENT:
+ ANGLE_LOG(EVENT) << messageStream.str();
+ break;
+ }
+ }
+
+ if (!isMessageEnabled(source, type, id, severity))
+ {
+ return;
+ }
+
+ if (mCallbackFunction != nullptr)
+ {
+ // TODO(geofflang) Check the synchronous flag and potentially flush messages from another
+ // thread.
+ mCallbackFunction(source, type, id, severity, static_cast<GLsizei>(message.length()),
+ message.c_str(), mCallbackUserParam);
+ }
+ else
+ {
+ if (mMessages.size() >= mMaxLoggedMessages)
+ {
+ // Drop messages over the limit
+ return;
+ }
+
+ Message m;
+ m.source = source;
+ m.type = type;
+ m.id = id;
+ m.severity = severity;
+ m.message = std::move(message);
+
+ mMessages.push_back(std::move(m));
+ }
+}
+
+size_t Debug::getMessages(GLuint count,
+ GLsizei bufSize,
+ GLenum *sources,
+ GLenum *types,
+ GLuint *ids,
+ GLenum *severities,
+ GLsizei *lengths,
+ GLchar *messageLog)
+{
+ size_t messageCount = 0;
+ size_t messageStringIndex = 0;
+ while (messageCount <= count && !mMessages.empty())
+ {
+ const Message &m = mMessages.front();
+
+ if (messageLog != nullptr)
+ {
+ // Check that this message can fit in the message buffer
+ if (messageStringIndex + m.message.length() + 1 > static_cast<size_t>(bufSize))
+ {
+ break;
+ }
+
+ std::copy(m.message.begin(), m.message.end(), messageLog + messageStringIndex);
+ messageStringIndex += m.message.length();
+
+ messageLog[messageStringIndex] = '\0';
+ messageStringIndex += 1;
+ }
+
+ if (sources != nullptr)
+ {
+ sources[messageCount] = m.source;
+ }
+
+ if (types != nullptr)
+ {
+ types[messageCount] = m.type;
+ }
+
+ if (ids != nullptr)
+ {
+ ids[messageCount] = m.id;
+ }
+
+ if (severities != nullptr)
+ {
+ severities[messageCount] = m.severity;
+ }
+
+ if (lengths != nullptr)
+ {
+ lengths[messageCount] = static_cast<GLsizei>(m.message.length()) + 1;
+ }
+
+ mMessages.pop_front();
+
+ messageCount++;
+ }
+
+ return messageCount;
+}
+
+size_t Debug::getNextMessageLength() const
+{
+ return mMessages.empty() ? 0 : mMessages.front().message.length() + 1;
+}
+
+size_t Debug::getMessageCount() const
+{
+ return mMessages.size();
+}
+
+void Debug::setMessageControl(GLenum source,
+ GLenum type,
+ GLenum severity,
+ std::vector<GLuint> &&ids,
+ bool enabled)
+{
+ Control c;
+ c.source = source;
+ c.type = type;
+ c.severity = severity;
+ c.ids = std::move(ids);
+ c.enabled = enabled;
+
+ auto &controls = mGroups.back().controls;
+ controls.push_back(std::move(c));
+}
+
+void Debug::pushGroup(GLenum source, GLuint id, std::string &&message)
+{
+ insertMessage(source, GL_DEBUG_TYPE_PUSH_GROUP, id, GL_DEBUG_SEVERITY_NOTIFICATION,
+ std::string(message), gl::LOG_INFO, angle::EntryPoint::GLPushDebugGroup);
+
+ Group g;
+ g.source = source;
+ g.id = id;
+ g.message = std::move(message);
+ mGroups.push_back(std::move(g));
+}
+
+void Debug::popGroup()
+{
+ // Make sure the default group is not about to be popped
+ ASSERT(mGroups.size() > 1);
+
+ Group g = mGroups.back();
+ mGroups.pop_back();
+
+ insertMessage(g.source, GL_DEBUG_TYPE_POP_GROUP, g.id, GL_DEBUG_SEVERITY_NOTIFICATION,
+ g.message, gl::LOG_INFO, angle::EntryPoint::GLPopDebugGroup);
+}
+
+size_t Debug::getGroupStackDepth() const
+{
+ return mGroups.size();
+}
+
+void Debug::insertPerfWarning(GLenum severity, const char *message, uint32_t *repeatCount) const
+{
+ bool repeatLast;
+
+ {
+ constexpr uint32_t kMaxRepeat = 4;
+ std::lock_guard<std::mutex> lock(GetDebugMutex());
+
+ if (*repeatCount >= kMaxRepeat)
+ {
+ return;
+ }
+
+ ++*repeatCount;
+ repeatLast = (*repeatCount == kMaxRepeat);
+ }
+
+ std::string msg = message;
+ if (repeatLast)
+ {
+ msg += " (this message will no longer repeat)";
+ }
+
+ // Release the lock before we call insertMessage. It will re-acquire the lock.
+ insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_PERFORMANCE, 0, severity, std::move(msg),
+ gl::LOG_INFO, angle::EntryPoint::GLInvalid);
+}
+
+bool Debug::isMessageEnabled(GLenum source, GLenum type, GLuint id, GLenum severity) const
+{
+ if (!mOutputEnabled)
+ {
+ return false;
+ }
+
+ for (auto groupIter = mGroups.rbegin(); groupIter != mGroups.rend(); groupIter++)
+ {
+ const auto &controls = groupIter->controls;
+ for (auto controlIter = controls.rbegin(); controlIter != controls.rend(); controlIter++)
+ {
+ const auto &control = *controlIter;
+
+ if (control.source != GL_DONT_CARE && control.source != source)
+ {
+ continue;
+ }
+
+ if (control.type != GL_DONT_CARE && control.type != type)
+ {
+ continue;
+ }
+
+ if (control.severity != GL_DONT_CARE && control.severity != severity)
+ {
+ continue;
+ }
+
+ if (!control.ids.empty() &&
+ std::find(control.ids.begin(), control.ids.end(), id) == control.ids.end())
+ {
+ continue;
+ }
+
+ return control.enabled;
+ }
+ }
+
+ return true;
+}
+
+void Debug::pushDefaultGroup()
+{
+ Group g;
+ g.source = GL_NONE;
+ g.id = 0;
+ g.message = "";
+
+ Control c0;
+ c0.source = GL_DONT_CARE;
+ c0.type = GL_DONT_CARE;
+ c0.severity = GL_DONT_CARE;
+ c0.enabled = true;
+ g.controls.push_back(std::move(c0));
+
+ Control c1;
+ c1.source = GL_DONT_CARE;
+ c1.type = GL_DONT_CARE;
+ c1.severity = GL_DEBUG_SEVERITY_LOW;
+ c1.enabled = false;
+ g.controls.push_back(std::move(c1));
+
+ mGroups.push_back(std::move(g));
+}
+} // namespace gl
+
+namespace egl
+{
+
+namespace
+{
+angle::PackedEnumBitSet<MessageType> GetDefaultMessageTypeBits()
+{
+ angle::PackedEnumBitSet<MessageType> result;
+ result.set(MessageType::Critical);
+ result.set(MessageType::Error);
+ return result;
+}
+} // anonymous namespace
+
+Debug::Debug() : mCallback(nullptr), mEnabledMessageTypes(GetDefaultMessageTypeBits()) {}
+
+void Debug::setCallback(EGLDEBUGPROCKHR callback, const AttributeMap &attribs)
+{
+ mCallback = callback;
+
+ const angle::PackedEnumBitSet<MessageType> defaultMessageTypes = GetDefaultMessageTypeBits();
+ if (mCallback != nullptr)
+ {
+ for (MessageType messageType : angle::AllEnums<MessageType>())
+ {
+ mEnabledMessageTypes[messageType] =
+ (attribs.getAsInt(egl::ToEGLenum(messageType), defaultMessageTypes[messageType]) ==
+ EGL_TRUE);
+ }
+ }
+}
+
+EGLDEBUGPROCKHR Debug::getCallback() const
+{
+ return mCallback;
+}
+
+bool Debug::isMessageTypeEnabled(MessageType type) const
+{
+ return mEnabledMessageTypes[type];
+}
+
+void Debug::insertMessage(EGLenum error,
+ const char *command,
+ MessageType messageType,
+ EGLLabelKHR threadLabel,
+ EGLLabelKHR objectLabel,
+ const std::string &message) const
+{
+ {
+ // output all messages to the debug log
+ const char *messageTypeString = EGLMessageTypeToString(messageType);
+ std::ostringstream messageStream;
+ messageStream << "EGL " << messageTypeString << ": " << command << ": " << message;
+ INFO() << messageStream.str();
+ }
+
+ // TODO(geofflang): Lock before checking the callback. http://anglebug.com/2464
+ if (mCallback && isMessageTypeEnabled(messageType))
+ {
+ mCallback(error, command, egl::ToEGLenum(messageType), threadLabel, objectLabel,
+ message.c_str());
+ }
+}
+
+} // namespace egl
diff --git a/gfx/angle/checkout/src/libANGLE/Debug.h b/gfx/angle/checkout/src/libANGLE/Debug.h
new file mode 100644
index 0000000000..873a60df6f
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Debug.h
@@ -0,0 +1,180 @@
+//
+// 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.
+//
+
+// Debug.h: Defines debug state used for GL_KHR_debug
+
+#ifndef LIBANGLE_DEBUG_H_
+#define LIBANGLE_DEBUG_H_
+
+#include "angle_gl.h"
+#include "common/PackedEnums.h"
+#include "common/angleutils.h"
+#include "libANGLE/AttributeMap.h"
+#include "libANGLE/Error.h"
+
+#include <deque>
+#include <string>
+#include <vector>
+
+namespace gl
+{
+class Context;
+
+class LabeledObject
+{
+ public:
+ virtual ~LabeledObject() {}
+ virtual angle::Result setLabel(const Context *context, const std::string &label) = 0;
+ virtual const std::string &getLabel() const = 0;
+};
+
+class Debug : angle::NonCopyable
+{
+ public:
+ Debug(bool initialDebugState);
+ ~Debug();
+
+ void setMaxLoggedMessages(GLuint maxLoggedMessages);
+
+ void setOutputEnabled(bool enabled);
+ bool isOutputEnabled() const;
+
+ void setOutputSynchronous(bool synchronous);
+ bool isOutputSynchronous() const;
+
+ void setCallback(GLDEBUGPROCKHR callback, const void *userParam);
+ GLDEBUGPROCKHR getCallback() const;
+ const void *getUserParam() const;
+
+ void insertMessage(GLenum source,
+ GLenum type,
+ GLuint id,
+ GLenum severity,
+ const std::string &message,
+ gl::LogSeverity logSeverity,
+ angle::EntryPoint entryPoint) const;
+ void insertMessage(GLenum source,
+ GLenum type,
+ GLuint id,
+ GLenum severity,
+ std::string &&message,
+ gl::LogSeverity logSeverity,
+ angle::EntryPoint entryPoint) const;
+
+ void setMessageControl(GLenum source,
+ GLenum type,
+ GLenum severity,
+ std::vector<GLuint> &&ids,
+ bool enabled);
+ size_t getMessages(GLuint count,
+ GLsizei bufSize,
+ GLenum *sources,
+ GLenum *types,
+ GLuint *ids,
+ GLenum *severities,
+ GLsizei *lengths,
+ GLchar *messageLog);
+ size_t getNextMessageLength() const;
+ size_t getMessageCount() const;
+
+ void pushGroup(GLenum source, GLuint id, std::string &&message);
+ void popGroup();
+ size_t getGroupStackDepth() const;
+
+ // Helper for ANGLE_PERF_WARNING
+ void insertPerfWarning(GLenum severity, const char *message, uint32_t *repeatCount) const;
+
+ private:
+ bool isMessageEnabled(GLenum source, GLenum type, GLuint id, GLenum severity) const;
+
+ void pushDefaultGroup();
+
+ struct Message
+ {
+ GLenum source;
+ GLenum type;
+ GLuint id;
+ GLenum severity;
+ std::string message;
+ };
+
+ struct Control
+ {
+ Control();
+ ~Control();
+ Control(const Control &other);
+
+ GLenum source;
+ GLenum type;
+ GLenum severity;
+ std::vector<GLuint> ids;
+ bool enabled;
+ };
+
+ struct Group
+ {
+ Group();
+ ~Group();
+ Group(const Group &other);
+
+ GLenum source;
+ GLuint id;
+ std::string message;
+
+ std::vector<Control> controls;
+ };
+
+ bool mOutputEnabled;
+ GLDEBUGPROCKHR mCallbackFunction;
+ const void *mCallbackUserParam;
+ mutable std::deque<Message> mMessages;
+ GLuint mMaxLoggedMessages;
+ bool mOutputSynchronous;
+ std::vector<Group> mGroups;
+};
+} // namespace gl
+
+namespace egl
+{
+class LabeledObject
+{
+ public:
+ virtual ~LabeledObject() {}
+ virtual void setLabel(EGLLabelKHR label) = 0;
+ virtual EGLLabelKHR getLabel() const = 0;
+};
+
+class Debug : angle::NonCopyable
+{
+ public:
+ Debug();
+
+ void setCallback(EGLDEBUGPROCKHR callback, const AttributeMap &attribs);
+ EGLDEBUGPROCKHR getCallback() const;
+ bool isMessageTypeEnabled(MessageType type) const;
+
+ void insertMessage(EGLenum error,
+ const char *command,
+ MessageType messageType,
+ EGLLabelKHR threadLabel,
+ EGLLabelKHR objectLabel,
+ const std::string &message) const;
+
+ private:
+ EGLDEBUGPROCKHR mCallback;
+ angle::PackedEnumBitSet<MessageType> mEnabledMessageTypes;
+};
+} // namespace egl
+
+// Generate a perf warning. Only outputs the same message a few times to avoid spamming the logs.
+#define ANGLE_PERF_WARNING(debug, severity, message) \
+ do \
+ { \
+ static uint32_t sRepeatCount = 0; \
+ (debug).insertPerfWarning(severity, message, &sRepeatCount); \
+ } while (0)
+
+#endif // LIBANGLE_DEBUG_H_
diff --git a/gfx/angle/checkout/src/libANGLE/Device.cpp b/gfx/angle/checkout/src/libANGLE/Device.cpp
new file mode 100644
index 0000000000..550708fd13
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Device.cpp
@@ -0,0 +1,133 @@
+//
+// 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.
+//
+
+// Device.cpp: Implements the egl::Device class, representing the abstract
+// device. Implements EGLDevice.
+
+#include "libANGLE/Device.h"
+
+#include <iterator>
+
+#include <EGL/eglext.h>
+#include <platform/PlatformMethods.h>
+
+#include "anglebase/no_destructor.h"
+#include "common/debug.h"
+#include "common/platform.h"
+#include "libANGLE/renderer/DeviceImpl.h"
+
+#if defined(ANGLE_ENABLE_D3D11)
+# include "libANGLE/renderer/d3d/DeviceD3D.h"
+#endif
+
+namespace egl
+{
+
+template <typename T>
+static std::string GenerateExtensionsString(const T &extensions)
+{
+ std::vector<std::string> extensionsVector = extensions.getStrings();
+
+ std::ostringstream stream;
+ std::copy(extensionsVector.begin(), extensionsVector.end(),
+ std::ostream_iterator<std::string>(stream, " "));
+ return stream.str();
+}
+
+typedef std::set<egl::Device *> DeviceSet;
+static DeviceSet *GetDeviceSet()
+{
+ static angle::base::NoDestructor<DeviceSet> devices;
+ return devices.get();
+}
+
+// Static factory methods
+egl::Error Device::CreateDevice(EGLint deviceType, void *nativeDevice, Device **outDevice)
+{
+ *outDevice = nullptr;
+
+ std::unique_ptr<rx::DeviceImpl> newDeviceImpl;
+
+#if defined(ANGLE_ENABLE_D3D11)
+ if (deviceType == EGL_D3D11_DEVICE_ANGLE)
+ {
+ newDeviceImpl.reset(new rx::DeviceD3D(deviceType, nativeDevice));
+ }
+#endif
+
+ // Note that creating an EGL device from inputted D3D9 parameters isn't currently supported
+
+ if (newDeviceImpl == nullptr)
+ {
+ return EglBadAttribute();
+ }
+
+ ANGLE_TRY(newDeviceImpl->initialize());
+ *outDevice = new Device(nullptr, newDeviceImpl.release());
+
+ return NoError();
+}
+
+bool Device::IsValidDevice(const Device *device)
+{
+ const DeviceSet *deviceSet = GetDeviceSet();
+ return deviceSet->find(const_cast<Device *>(device)) != deviceSet->end();
+}
+
+Device::Device(Display *owningDisplay, rx::DeviceImpl *impl)
+ : mLabel(nullptr), mOwningDisplay(owningDisplay), mImplementation(impl)
+{
+ ASSERT(GetDeviceSet()->find(this) == GetDeviceSet()->end());
+ GetDeviceSet()->insert(this);
+ initDeviceExtensions();
+}
+
+Device::~Device()
+{
+ ASSERT(GetDeviceSet()->find(this) != GetDeviceSet()->end());
+ GetDeviceSet()->erase(this);
+}
+
+void Device::setLabel(EGLLabelKHR label)
+{
+ mLabel = label;
+}
+
+EGLLabelKHR Device::getLabel() const
+{
+ return mLabel;
+}
+
+Error Device::getAttribute(EGLint attribute, EGLAttrib *value)
+{
+ void *nativeAttribute = nullptr;
+ egl::Error error =
+ getImplementation()->getAttribute(getOwningDisplay(), attribute, &nativeAttribute);
+ *value = reinterpret_cast<EGLAttrib>(nativeAttribute);
+ return error;
+}
+
+EGLint Device::getType() const
+{
+ return mImplementation.get()->getType();
+}
+
+void Device::initDeviceExtensions()
+{
+ mImplementation->generateExtensions(&mDeviceExtensions);
+ mDeviceExtensionString = GenerateExtensionsString(mDeviceExtensions);
+}
+
+const DeviceExtensions &Device::getExtensions() const
+{
+ return mDeviceExtensions;
+}
+
+const std::string &Device::getExtensionString() const
+{
+ return mDeviceExtensionString;
+}
+} // namespace egl
diff --git a/gfx/angle/checkout/src/libANGLE/Device.h b/gfx/angle/checkout/src/libANGLE/Device.h
new file mode 100644
index 0000000000..8fbdf72e68
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Device.h
@@ -0,0 +1,60 @@
+//
+// 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.
+//
+
+// Device.h: Implements the egl::Device class, representing the abstract
+// device. Implements EGLDevice.
+
+#ifndef LIBANGLE_DEVICE_H_
+#define LIBANGLE_DEVICE_H_
+
+#include "common/angleutils.h"
+#include "libANGLE/Display.h"
+#include "libANGLE/Error.h"
+
+#include <memory>
+
+namespace rx
+{
+class DeviceImpl;
+} // namespace rx
+
+namespace egl
+{
+class Device final : public LabeledObject, angle::NonCopyable
+{
+ public:
+ Device(Display *owningDisplay, rx::DeviceImpl *impl);
+ ~Device() override;
+
+ void setLabel(EGLLabelKHR label) override;
+ EGLLabelKHR getLabel() const override;
+
+ Error getAttribute(EGLint attribute, EGLAttrib *value);
+ Display *getOwningDisplay() const { return mOwningDisplay; }
+ EGLint getType() const;
+
+ const DeviceExtensions &getExtensions() const;
+ const std::string &getExtensionString() const;
+
+ rx::DeviceImpl *getImplementation() { return mImplementation.get(); }
+
+ static egl::Error CreateDevice(EGLint deviceType, void *nativeDevice, Device **outDevice);
+ static bool IsValidDevice(const Device *device);
+
+ private:
+ void initDeviceExtensions();
+
+ EGLLabelKHR mLabel;
+
+ Display *mOwningDisplay;
+ std::unique_ptr<rx::DeviceImpl> mImplementation;
+
+ DeviceExtensions mDeviceExtensions;
+ std::string mDeviceExtensionString;
+};
+} // namespace egl
+
+#endif // LIBANGLE_DEVICE_H_
diff --git a/gfx/angle/checkout/src/libANGLE/Display.cpp b/gfx/angle/checkout/src/libANGLE/Display.cpp
new file mode 100644
index 0000000000..4b7ced36fb
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Display.cpp
@@ -0,0 +1,2506 @@
+//
+// Copyright 2002 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.
+//
+
+// Display.cpp: Implements the egl::Display class, representing the abstract
+// display on which graphics are drawn. Implements EGLDisplay.
+// [EGL 1.4] section 2.1.2 page 3.
+
+#include "libANGLE/Display.h"
+
+#include <algorithm>
+#include <iterator>
+#include <sstream>
+#include <vector>
+
+#include <EGL/eglext.h>
+#include <platform/PlatformMethods.h>
+
+#include "anglebase/no_destructor.h"
+#include "common/android_util.h"
+#include "common/debug.h"
+#include "common/mathutil.h"
+#include "common/platform.h"
+#include "common/string_utils.h"
+#include "common/system_utils.h"
+#include "common/tls.h"
+#include "common/utilities.h"
+#include "gpu_info_util/SystemInfo.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Device.h"
+#include "libANGLE/EGLSync.h"
+#include "libANGLE/Image.h"
+#include "libANGLE/ResourceManager.h"
+#include "libANGLE/Stream.h"
+#include "libANGLE/Surface.h"
+#include "libANGLE/Thread.h"
+#include "libANGLE/capture/FrameCapture.h"
+#include "libANGLE/histogram_macros.h"
+#include "libANGLE/renderer/DeviceImpl.h"
+#include "libANGLE/renderer/DisplayImpl.h"
+#include "libANGLE/renderer/ImageImpl.h"
+#include "libANGLE/trace.h"
+
+#if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11)
+# include <versionhelpers.h>
+
+# include "libANGLE/renderer/d3d/DisplayD3D.h"
+#endif
+
+#if defined(ANGLE_ENABLE_OPENGL)
+# if defined(ANGLE_PLATFORM_WINDOWS)
+# include "libANGLE/renderer/gl/wgl/DisplayWGL.h"
+# elif defined(ANGLE_PLATFORM_MACOS) || defined(ANGLE_PLATFORM_IOS)
+# include "libANGLE/renderer/gl/apple/DisplayApple_api.h"
+# elif defined(ANGLE_PLATFORM_LINUX)
+# include "libANGLE/renderer/gl/egl/DisplayEGL.h"
+# if defined(ANGLE_USE_GBM)
+# include "libANGLE/renderer/gl/egl/gbm/DisplayGbm.h"
+# endif
+# if defined(ANGLE_USE_X11)
+# include "libANGLE/renderer/gl/glx/DisplayGLX.h"
+# endif
+# elif defined(ANGLE_PLATFORM_ANDROID)
+# include "libANGLE/renderer/gl/egl/android/DisplayAndroid.h"
+# else
+# error Unsupported OpenGL platform.
+# endif
+#endif
+
+#if defined(ANGLE_ENABLE_NULL)
+# include "libANGLE/renderer/null/DisplayNULL.h"
+#endif // defined(ANGLE_ENABLE_NULL)
+
+#if defined(ANGLE_ENABLE_VULKAN)
+# include "libANGLE/renderer/vulkan/DisplayVk_api.h"
+#endif // defined(ANGLE_ENABLE_VULKAN)
+
+#if defined(ANGLE_ENABLE_METAL)
+# include "libANGLE/renderer/metal/DisplayMtl_api.h"
+#endif // defined(ANGLE_ENABLE_METAL)
+
+namespace egl
+{
+
+namespace
+{
+
+constexpr angle::SubjectIndex kGPUSwitchedSubjectIndex = 0;
+
+static constexpr size_t kWindowSurfaceMapSize = 32;
+typedef angle::FlatUnorderedMap<EGLNativeWindowType, Surface *, kWindowSurfaceMapSize>
+ WindowSurfaceMap;
+// Get a map of all EGL window surfaces to validate that no window has more than one EGL surface
+// associated with it.
+static WindowSurfaceMap *GetWindowSurfaces()
+{
+ static angle::base::NoDestructor<WindowSurfaceMap> windowSurfaces;
+ return windowSurfaces.get();
+}
+
+struct ANGLEPlatformDisplay
+{
+ ANGLEPlatformDisplay() = default;
+
+ ANGLEPlatformDisplay(EGLNativeDisplayType nativeDisplayType)
+ : nativeDisplayType(nativeDisplayType)
+ {}
+
+ ANGLEPlatformDisplay(EGLNativeDisplayType nativeDisplayType,
+ EGLAttrib powerPreference,
+ EGLAttrib platformANGLEType,
+ EGLAttrib deviceIdHigh,
+ EGLAttrib deviceIdLow)
+ : nativeDisplayType(nativeDisplayType),
+ powerPreference(powerPreference),
+ platformANGLEType(platformANGLEType),
+ deviceIdHigh(deviceIdHigh),
+ deviceIdLow(deviceIdLow)
+ {}
+
+ auto tie() const
+ {
+ return std::tie(nativeDisplayType, powerPreference, platformANGLEType, deviceIdHigh,
+ deviceIdLow);
+ }
+
+ EGLNativeDisplayType nativeDisplayType{EGL_DEFAULT_DISPLAY};
+ EGLAttrib powerPreference{EGL_LOW_POWER_ANGLE};
+ EGLAttrib platformANGLEType{EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE};
+ EGLAttrib deviceIdHigh{0};
+ EGLAttrib deviceIdLow{0};
+};
+
+inline bool operator==(const ANGLEPlatformDisplay &a, const ANGLEPlatformDisplay &b)
+{
+ return a.tie() == b.tie();
+}
+
+static constexpr size_t kANGLEPlatformDisplayMapSize = 9;
+typedef angle::FlatUnorderedMap<ANGLEPlatformDisplay, Display *, kANGLEPlatformDisplayMapSize>
+ ANGLEPlatformDisplayMap;
+static ANGLEPlatformDisplayMap *GetANGLEPlatformDisplayMap()
+{
+ static angle::base::NoDestructor<ANGLEPlatformDisplayMap> displays;
+ return displays.get();
+}
+
+static constexpr size_t kDevicePlatformDisplayMapSize = 8;
+typedef angle::FlatUnorderedMap<Device *, Display *, kDevicePlatformDisplayMapSize>
+ DevicePlatformDisplayMap;
+static DevicePlatformDisplayMap *GetDevicePlatformDisplayMap()
+{
+ static angle::base::NoDestructor<DevicePlatformDisplayMap> displays;
+ return displays.get();
+}
+
+rx::DisplayImpl *CreateDisplayFromDevice(Device *eglDevice, const DisplayState &state)
+{
+ rx::DisplayImpl *impl = nullptr;
+
+ switch (eglDevice->getType())
+ {
+#if defined(ANGLE_ENABLE_D3D11)
+ case EGL_D3D11_DEVICE_ANGLE:
+ impl = new rx::DisplayD3D(state);
+ break;
+#endif
+#if defined(ANGLE_ENABLE_D3D9)
+ case EGL_D3D9_DEVICE_ANGLE:
+ // Currently the only way to get EGLDeviceEXT representing a D3D9 device
+ // is to retrieve one from an already-existing EGLDisplay.
+ // When eglGetPlatformDisplayEXT is called with a D3D9 EGLDeviceEXT,
+ // the already-existing display should be returned.
+ // Therefore this codepath to create a new display from the device
+ // should never be hit.
+ UNREACHABLE();
+ break;
+#endif
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ ASSERT(impl != nullptr);
+ return impl;
+}
+
+// On platforms with support for multiple back-ends, allow an environment variable to control
+// the default. This is useful to run angle with benchmarks without having to modify the
+// benchmark source. Possible values for this environment variable (ANGLE_DEFAULT_PLATFORM)
+// are: vulkan, gl, d3d11, null.
+EGLAttrib GetDisplayTypeFromEnvironment()
+{
+ std::string angleDefaultEnv = angle::GetEnvironmentVar("ANGLE_DEFAULT_PLATFORM");
+ angle::ToLower(&angleDefaultEnv);
+
+#if defined(ANGLE_ENABLE_VULKAN)
+ if ((angleDefaultEnv == "vulkan") || (angleDefaultEnv == "vulkan-null") ||
+ (angleDefaultEnv == "swiftshader"))
+ {
+ return EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE;
+ }
+#endif
+
+#if defined(ANGLE_ENABLE_OPENGL)
+ if (angleDefaultEnv == "gl")
+ {
+ return EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE;
+ }
+#endif
+
+#if defined(ANGLE_ENABLE_D3D11)
+ if (angleDefaultEnv == "d3d11")
+ {
+ return EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE;
+ }
+#endif
+
+#if defined(ANGLE_ENABLE_METAL)
+ if (angleDefaultEnv == "metal")
+ {
+ return EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE;
+ }
+#endif
+
+#if defined(ANGLE_ENABLE_NULL)
+ if (angleDefaultEnv == "null")
+ {
+ return EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE;
+ }
+#endif
+#if defined(ANGLE_ENABLE_METAL)
+ if (angleDefaultEnv == "metal")
+ {
+ return EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE;
+ }
+
+#endif
+#if defined(ANGLE_ENABLE_D3D11)
+ return EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE;
+#elif defined(ANGLE_ENABLE_D3D9)
+ return EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE;
+#elif defined(ANGLE_ENABLE_VULKAN) && defined(ANGLE_PLATFORM_ANDROID)
+ return EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE;
+#elif defined(ANGLE_ENABLE_OPENGL)
+# if defined(ANGLE_PLATFORM_ANDROID) || defined(ANGLE_USE_GBM)
+ return EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE;
+# else
+ return EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE;
+# endif
+#elif defined(ANGLE_ENABLE_METAL)
+ return EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE;
+#elif defined(ANGLE_ENABLE_VULKAN)
+ return EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE;
+#elif defined(ANGLE_ENABLE_NULL)
+ return EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE;
+#else
+# error No default ANGLE platform type
+#endif
+}
+
+EGLAttrib GetDeviceTypeFromEnvironment()
+{
+ std::string angleDefaultEnv = angle::GetEnvironmentVar("ANGLE_DEFAULT_PLATFORM");
+ angle::ToLower(&angleDefaultEnv);
+
+#if defined(ANGLE_ENABLE_VULKAN)
+ if (angleDefaultEnv == "vulkan-null")
+ {
+ return EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE;
+ }
+ else if (angleDefaultEnv == "swiftshader")
+ {
+ return EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE;
+ }
+#endif
+ return EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE;
+}
+
+EGLAttrib GetPlatformTypeFromEnvironment()
+{
+#if defined(ANGLE_USE_OZONE)
+ return 0;
+#elif defined(ANGLE_USE_X11)
+ return EGL_PLATFORM_X11_EXT;
+#elif defined(ANGLE_USE_WAYLAND)
+ return EGL_PLATFORM_WAYLAND_EXT;
+#elif defined(ANGLE_USE_VULKAN_DISPLAY) && defined(ANGLE_VULKAN_DISPLAY_MODE_SIMPLE)
+ return EGL_PLATFORM_VULKAN_DISPLAY_MODE_SIMPLE_ANGLE;
+#elif defined(ANGLE_USE_VULKAN_DISPLAY) && defined(ANGLE_VULKAN_DISPLAY_MODE_HEADLESS)
+ return EGL_PLATFORM_VULKAN_DISPLAY_MODE_HEADLESS_ANGLE;
+#else
+ return 0;
+#endif // defined(ANGLE_USE_OZONE)
+}
+
+rx::DisplayImpl *CreateDisplayFromAttribs(EGLAttrib displayType,
+ EGLAttrib deviceType,
+ EGLAttrib platformType,
+ const DisplayState &state)
+{
+ ASSERT(displayType != EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE);
+ rx::DisplayImpl *impl = nullptr;
+
+ switch (displayType)
+ {
+ case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE:
+ UNREACHABLE();
+ break;
+
+ case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE:
+ case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE:
+#if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11)
+ impl = new rx::DisplayD3D(state);
+ break;
+#else
+ // A D3D display was requested on a platform that doesn't support it
+ UNREACHABLE();
+ break;
+#endif
+
+ case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE:
+#if defined(ANGLE_ENABLE_OPENGL)
+# if defined(ANGLE_PLATFORM_WINDOWS)
+ impl = new rx::DisplayWGL(state);
+ break;
+
+# elif defined(ANGLE_PLATFORM_MACOS) || defined(ANGLE_PLATFORM_IOS)
+ impl = rx::CreateDisplayCGLOrEAGL(state);
+ break;
+
+# elif defined(ANGLE_PLATFORM_LINUX)
+# if defined(ANGLE_USE_GBM)
+ if (platformType == 0)
+ {
+ // If platformType is unknown, use DisplayGbm now. In the future, it should use
+ // DisplayEGL letting native EGL decide what display to use.
+ impl = new rx::DisplayGbm(state);
+ break;
+ }
+# endif
+ if (deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_EGL_ANGLE)
+ {
+ impl = new rx::DisplayEGL(state);
+ break;
+ }
+# if defined(ANGLE_USE_X11)
+ if (platformType == EGL_PLATFORM_X11_EXT)
+ {
+ impl = new rx::DisplayGLX(state);
+ break;
+ }
+# endif
+ break;
+
+# elif defined(ANGLE_PLATFORM_ANDROID)
+ // No GL support on this platform, fail display creation.
+ impl = nullptr;
+ break;
+
+# else
+# error Unsupported OpenGL platform.
+# endif
+#else
+ // No display available
+ UNREACHABLE();
+ break;
+
+#endif // defined(ANGLE_ENABLE_OPENGL)
+
+ case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE:
+#if defined(ANGLE_ENABLE_OPENGL)
+# if defined(ANGLE_PLATFORM_WINDOWS)
+ impl = new rx::DisplayWGL(state);
+# elif defined(ANGLE_PLATFORM_LINUX)
+# if defined(ANGLE_USE_GBM)
+ if (platformType == 0 ||
+ platformType == EGL_PLATFORM_VULKAN_DISPLAY_MODE_HEADLESS_ANGLE)
+ {
+ // If platformType is unknown, use DisplayGbm now. In the future, it should use
+ // DisplayEGL letting native EGL decide what display to use.
+ // platformType == EGL_PLATFORM_VULKAN_DISPLAY_MODE_HEADLESS_ANGLE is a hack,
+ // to allow ChromeOS GLES backend to continue functioning when Vulkan is enabled.
+ impl = new rx::DisplayGbm(state);
+ break;
+ }
+# endif
+ if (deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_EGL_ANGLE)
+ {
+ impl = new rx::DisplayEGL(state);
+ break;
+ }
+ else
+ {
+# if defined(ANGLE_USE_X11)
+ if (platformType == EGL_PLATFORM_X11_EXT)
+ {
+ impl = new rx::DisplayGLX(state);
+ break;
+ }
+# endif
+ }
+# elif defined(ANGLE_PLATFORM_ANDROID)
+ impl = new rx::DisplayAndroid(state);
+# else
+ // No GLES support on this platform, fail display creation.
+ impl = nullptr;
+# endif
+#endif // defined(ANGLE_ENABLE_OPENGL)
+ break;
+
+ case EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE:
+#if defined(ANGLE_ENABLE_VULKAN)
+# if defined(ANGLE_USE_VULKAN_NULL_DISPLAY)
+ if (rx::IsVulkanNullDisplayAvailable())
+ {
+ impl = rx::CreateVulkanNullDisplay(state);
+ }
+ break;
+# elif defined(ANGLE_PLATFORM_WINDOWS)
+ if (rx::IsVulkanWin32DisplayAvailable())
+ {
+ impl = rx::CreateVulkanWin32Display(state);
+ }
+ break;
+# elif defined(ANGLE_PLATFORM_LINUX)
+# if defined(ANGLE_USE_GBM)
+ if (platformType == EGL_PLATFORM_GBM_KHR && rx::IsVulkanGbmDisplayAvailable())
+ {
+ impl = rx::CreateVulkanGbmDisplay(state);
+ break;
+ }
+# endif
+# if defined(ANGLE_USE_X11)
+ if (platformType == EGL_PLATFORM_X11_EXT && rx::IsVulkanXcbDisplayAvailable())
+ {
+ impl = rx::CreateVulkanXcbDisplay(state);
+ break;
+ }
+# endif
+# if defined(ANGLE_USE_WAYLAND)
+ if (platformType == EGL_PLATFORM_WAYLAND_EXT && rx::IsVulkanWaylandDisplayAvailable())
+ {
+ impl = rx::CreateVulkanWaylandDisplay(state);
+ break;
+ }
+# endif
+# if defined(ANGLE_USE_VULKAN_DISPLAY)
+ if (platformType == EGL_PLATFORM_VULKAN_DISPLAY_MODE_SIMPLE_ANGLE &&
+ rx::IsVulkanSimpleDisplayAvailable())
+ {
+ impl = rx::CreateVulkanSimpleDisplay(state);
+ }
+ else if (platformType == EGL_PLATFORM_VULKAN_DISPLAY_MODE_HEADLESS_ANGLE &&
+ rx::IsVulkanHeadlessDisplayAvailable())
+ {
+ impl = rx::CreateVulkanHeadlessDisplay(state);
+ }
+ else
+ {
+ // Not supported creation type on vulkan display, fail display creation.
+ impl = nullptr;
+ }
+# endif
+ break;
+# elif defined(ANGLE_PLATFORM_ANDROID)
+ if (rx::IsVulkanAndroidDisplayAvailable())
+ {
+ impl = rx::CreateVulkanAndroidDisplay(state);
+ }
+ break;
+# elif defined(ANGLE_PLATFORM_FUCHSIA)
+ if (rx::IsVulkanFuchsiaDisplayAvailable())
+ {
+ impl = rx::CreateVulkanFuchsiaDisplay(state);
+ }
+ break;
+# elif defined(ANGLE_PLATFORM_GGP)
+ if (rx::IsVulkanGGPDisplayAvailable())
+ {
+ impl = rx::CreateVulkanGGPDisplay(state);
+ }
+ break;
+# elif defined(ANGLE_PLATFORM_APPLE)
+ if (rx::IsVulkanMacDisplayAvailable())
+ {
+ impl = rx::CreateVulkanMacDisplay(state);
+ }
+ break;
+# else
+# error Unsupported Vulkan platform.
+# endif
+#else
+ // No display available
+ UNREACHABLE();
+ break;
+#endif // defined(ANGLE_ENABLE_VULKAN)
+
+ case EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE:
+#if defined(ANGLE_ENABLE_METAL)
+ if (rx::IsMetalDisplayAvailable())
+ {
+ impl = rx::CreateMetalDisplay(state);
+ break;
+ }
+#endif
+ // No display available
+ UNREACHABLE();
+ break;
+
+ case EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE:
+#if defined(ANGLE_ENABLE_NULL)
+ impl = new rx::DisplayNULL(state);
+ break;
+#else
+ // No display available
+ UNREACHABLE();
+ break;
+#endif // defined(ANGLE_ENABLE_NULL)
+
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ return impl;
+}
+
+void Display_logError(angle::PlatformMethods *platform, const char *errorMessage)
+{
+ gl::Trace(gl::LOG_ERR, errorMessage);
+}
+
+void Display_logWarning(angle::PlatformMethods *platform, const char *warningMessage)
+{
+ gl::Trace(gl::LOG_WARN, warningMessage);
+}
+
+void Display_logInfo(angle::PlatformMethods *platform, const char *infoMessage)
+{
+ // Uncomment to get info spam
+#if defined(ANGLE_ENABLE_DEBUG_TRACE)
+ gl::Trace(gl::LOG_INFO, infoMessage);
+#endif
+}
+
+const std::vector<std::string> EGLStringArrayToStringVector(const char **ary)
+{
+ std::vector<std::string> vec;
+ if (ary != nullptr)
+ {
+ for (; *ary != nullptr; ary++)
+ {
+ vec.push_back(std::string(*ary));
+ }
+ }
+ return vec;
+}
+
+void ANGLESetDefaultDisplayPlatform(angle::EGLDisplayType display)
+{
+ angle::PlatformMethods *platformMethods = ANGLEPlatformCurrent();
+
+ ANGLEResetDisplayPlatform(display);
+ platformMethods->logError = Display_logError;
+ platformMethods->logWarning = Display_logWarning;
+ platformMethods->logInfo = Display_logInfo;
+}
+
+void UpdateAttribsFromEnvironment(AttributeMap &attribMap)
+{
+ EGLAttrib displayType =
+ attribMap.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE);
+ if (displayType == EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE)
+ {
+ displayType = GetDisplayTypeFromEnvironment();
+ attribMap.insert(EGL_PLATFORM_ANGLE_TYPE_ANGLE, displayType);
+ }
+ EGLAttrib deviceType = attribMap.get(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, 0);
+ if (deviceType == 0)
+ {
+ deviceType = GetDeviceTypeFromEnvironment();
+ attribMap.insert(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, deviceType);
+ }
+ EGLAttrib platformType = attribMap.get(EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE, 0);
+ if (platformType == 0)
+ {
+ platformType = GetPlatformTypeFromEnvironment();
+ attribMap.insert(EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE, platformType);
+ }
+}
+
+static constexpr uint32_t kScratchBufferLifetime = 64u;
+
+} // anonymous namespace
+
+// ShareGroup
+ShareGroup::ShareGroup(rx::EGLImplFactory *factory)
+ : mRefCount(1),
+ mImplementation(factory->createShareGroup()),
+ mFrameCaptureShared(new angle::FrameCaptureShared)
+{}
+
+void ShareGroup::finishAllContexts()
+{
+ for (gl::Context *shareContext : mContexts)
+ {
+ if (shareContext->hasBeenCurrent() && !shareContext->isDestroyed())
+ {
+ shareContext->finish();
+ }
+ }
+}
+
+void ShareGroup::addSharedContext(gl::Context *context)
+{
+ mContexts.insert(context);
+
+ if (context->isRobustnessEnabled())
+ {
+ mImplementation->onRobustContextAdd();
+ }
+}
+
+void ShareGroup::removeSharedContext(gl::Context *context)
+{
+ mContexts.erase(context);
+}
+
+ShareGroup::~ShareGroup()
+{
+ SafeDelete(mImplementation);
+}
+
+void ShareGroup::addRef()
+{
+ // This is protected by global lock, so no atomic is required
+ mRefCount++;
+}
+
+void ShareGroup::release(const Display *display)
+{
+ if (--mRefCount == 0)
+ {
+ if (mImplementation)
+ {
+ mImplementation->onDestroy(display);
+ }
+ delete this;
+ }
+}
+
+// DisplayState
+DisplayState::DisplayState(EGLNativeDisplayType nativeDisplayId)
+ : label(nullptr), featuresAllDisabled(false), displayId(nativeDisplayId)
+{}
+
+DisplayState::~DisplayState() {}
+
+// Note that ANGLE support on Ozone platform is limited. Our preferred support Matrix for
+// EGL_ANGLE_platform_angle on Linux and Ozone/Linux/Fuchsia platforms should be the following:
+//
+// |--------------------------------------------------------|
+// | ANGLE type | DEVICE type | PLATFORM type | Display |
+// |--------------------------------------------------------|
+// | OPENGL | EGL | ANY | EGL |
+// | OPENGL | HARDWARE | X11_EXT | GLX |
+// | OPENGLES | HARDWARE | X11_EXT | GLX |
+// | OPENGLES | EGL | ANY | EGL |
+// | VULKAN | HARDWARE | X11_EXT | VkXcb |
+// | VULKAN | SWIFTSHADER | X11_EXT | VkXcb |
+// | OPENGLES | HARDWARE | SURFACELESS_MESA | EGL* |
+// | OPENGLES | HARDWARE | DEVICE_EXT | EGL |
+// | VULKAN | HARDWARE | SURFACELESS_MESA | VkBase** |
+// | VULKAN | SWIFTSHADER | SURFACELESS_MESA | VkBase** |
+// |--------------------------------------------------------|
+//
+// * No surfaceless support yet.
+// ** Not implemented yet.
+//
+// |-----------------------------------------------|
+// | OS | BUILD type | Default PLATFORM type |
+// |-----------------------------------------------|
+// | Linux | X11 | X11_EXT |
+// | Linux | Ozone | SURFACELESS_MESA |
+// | Fuchsia | Ozone | FUCHSIA*** |
+// |-----------------------------------------------|
+//
+// *** Chosen implicitly. No EGLAttrib available.
+//
+// For more details, please refer to
+// https://docs.google.com/document/d/1XjHiDZQISq1AMrg_l1TX1_kIKvDpU76hidn9i4cAjl8/edit?disco=AAAAJl9V_YY
+//
+// static
+Display *Display::GetDisplayFromNativeDisplay(EGLenum platform,
+ EGLNativeDisplayType nativeDisplay,
+ const AttributeMap &attribMap)
+{
+ Display *display = nullptr;
+
+ AttributeMap updatedAttribMap(attribMap);
+ UpdateAttribsFromEnvironment(updatedAttribMap);
+
+ EGLAttrib powerPreference =
+ updatedAttribMap.get(EGL_POWER_PREFERENCE_ANGLE, EGL_LOW_POWER_ANGLE);
+ EGLAttrib platformANGLEType =
+ updatedAttribMap.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE);
+ EGLAttrib deviceIdHigh = updatedAttribMap.get(EGL_PLATFORM_ANGLE_DEVICE_ID_HIGH_ANGLE, 0);
+ EGLAttrib deviceIdLow = updatedAttribMap.get(EGL_PLATFORM_ANGLE_DEVICE_ID_LOW_ANGLE, 0);
+ ANGLEPlatformDisplayMap *displays = GetANGLEPlatformDisplayMap();
+ ANGLEPlatformDisplay displayKey(nativeDisplay, powerPreference, platformANGLEType, deviceIdHigh,
+ deviceIdLow);
+ const auto &iter = displays->find(displayKey);
+ if (iter != displays->end())
+ {
+ display = iter->second;
+ }
+
+ if (display == nullptr)
+ {
+ // Validate the native display
+ if (!Display::isValidNativeDisplay(nativeDisplay))
+ {
+ return nullptr;
+ }
+
+ display = new Display(platform, nativeDisplay, nullptr);
+ displays->insert(std::make_pair(displayKey, display));
+ }
+ // Apply new attributes if the display is not initialized yet.
+ if (!display->isInitialized())
+ {
+ display->setAttributes(updatedAttribMap);
+
+ EGLAttrib displayType = display->mAttributeMap.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE);
+ EGLAttrib deviceType = display->mAttributeMap.get(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE);
+ EGLAttrib platformType = platform;
+ if (platform == EGL_PLATFORM_ANGLE_ANGLE)
+ {
+ platformType =
+ display->mAttributeMap.get(EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE);
+ }
+ rx::DisplayImpl *impl =
+ CreateDisplayFromAttribs(displayType, deviceType, platformType, display->getState());
+ if (impl == nullptr)
+ {
+ // No valid display implementation for these attributes
+ return nullptr;
+ }
+
+#if defined(ANGLE_USE_ANDROID_TLS_SLOT)
+ angle::gUseAndroidOpenGLTlsSlot = displayType == EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE;
+#endif // defined(ANGLE_PLATFORM_ANDROID)
+
+ display->setupDisplayPlatform(impl);
+ }
+
+ return display;
+}
+
+// static
+Display *Display::GetExistingDisplayFromNativeDisplay(EGLNativeDisplayType nativeDisplay)
+{
+ ANGLEPlatformDisplayMap *displays = GetANGLEPlatformDisplayMap();
+ const auto &iter = displays->find(nativeDisplay);
+
+ // Check that there is a matching display
+ if (iter == displays->end())
+ {
+ return nullptr;
+ }
+
+ return iter->second;
+}
+
+// static
+Display *Display::GetDisplayFromDevice(Device *device, const AttributeMap &attribMap)
+{
+ Display *display = nullptr;
+
+ ASSERT(Device::IsValidDevice(device));
+
+ ANGLEPlatformDisplayMap *anglePlatformDisplays = GetANGLEPlatformDisplayMap();
+ DevicePlatformDisplayMap *devicePlatformDisplays = GetDevicePlatformDisplayMap();
+
+ // First see if this eglDevice is in use by a Display created using ANGLE platform
+ for (auto &displayMapEntry : *anglePlatformDisplays)
+ {
+ egl::Display *iterDisplay = displayMapEntry.second;
+ if (iterDisplay->getDevice() == device)
+ {
+ display = iterDisplay;
+ }
+ }
+
+ if (display == nullptr)
+ {
+ // See if the eglDevice is in use by a Display created using the DEVICE platform
+ const auto &iter = devicePlatformDisplays->find(device);
+ if (iter != devicePlatformDisplays->end())
+ {
+ display = iter->second;
+ }
+ }
+
+ if (display == nullptr)
+ {
+ // Otherwise create a new Display
+ display = new Display(EGL_PLATFORM_DEVICE_EXT, 0, device);
+ devicePlatformDisplays->insert(std::make_pair(device, display));
+ }
+
+ // Apply new attributes if the display is not initialized yet.
+ if (!display->isInitialized())
+ {
+ display->setAttributes(attribMap);
+ rx::DisplayImpl *impl = CreateDisplayFromDevice(device, display->getState());
+ display->setupDisplayPlatform(impl);
+ }
+
+ return display;
+}
+
+// static
+Display::EglDisplaySet Display::GetEglDisplaySet()
+{
+ Display::EglDisplaySet displays;
+
+ ANGLEPlatformDisplayMap *anglePlatformDisplays = GetANGLEPlatformDisplayMap();
+ DevicePlatformDisplayMap *devicePlatformDisplays = GetDevicePlatformDisplayMap();
+
+ for (auto anglePlatformDisplayMapEntry : *anglePlatformDisplays)
+ {
+ displays.insert(anglePlatformDisplayMapEntry.second);
+ }
+
+ for (auto devicePlatformDisplayMapEntry : *devicePlatformDisplays)
+ {
+ displays.insert(devicePlatformDisplayMapEntry.second);
+ }
+
+ return displays;
+}
+
+Display::Display(EGLenum platform, EGLNativeDisplayType displayId, Device *eglDevice)
+ : mState(displayId),
+ mImplementation(nullptr),
+ mGPUSwitchedBinding(this, kGPUSwitchedSubjectIndex),
+ mAttributeMap(),
+ mConfigSet(),
+ mStreamSet(),
+ mInvalidContextSet(),
+ mInvalidImageSet(),
+ mInvalidStreamSet(),
+ mInvalidSurfaceSet(),
+ mInvalidSyncSet(),
+ mInitialized(false),
+ mDeviceLost(false),
+ mCaps(),
+ mDisplayExtensions(),
+ mDisplayExtensionString(),
+ mVendorString(),
+ mVersionString(),
+ mDevice(eglDevice),
+ mSurface(nullptr),
+ mPlatform(platform),
+ mTextureManager(nullptr),
+ mSemaphoreManager(nullptr),
+ mBlobCache(gl::kDefaultMaxProgramCacheMemoryBytes),
+ mMemoryProgramCache(mBlobCache),
+ mMemoryShaderCache(mBlobCache),
+ mGlobalTextureShareGroupUsers(0),
+ mGlobalSemaphoreShareGroupUsers(0),
+ mTerminatedByApi(false),
+ mActiveThreads()
+{}
+
+Display::~Display()
+{
+ switch (mPlatform)
+ {
+ case EGL_PLATFORM_ANGLE_ANGLE:
+ case EGL_PLATFORM_GBM_KHR:
+ case EGL_PLATFORM_WAYLAND_EXT:
+ {
+ ANGLEPlatformDisplayMap *displays = GetANGLEPlatformDisplayMap();
+ ANGLEPlatformDisplayMap::iterator iter = displays->find(ANGLEPlatformDisplay(
+ mState.displayId,
+ mAttributeMap.get(EGL_POWER_PREFERENCE_ANGLE, EGL_LOW_POWER_ANGLE),
+ mAttributeMap.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE,
+ EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE),
+ mAttributeMap.get(EGL_PLATFORM_ANGLE_DEVICE_ID_HIGH_ANGLE, 0),
+ mAttributeMap.get(EGL_PLATFORM_ANGLE_DEVICE_ID_LOW_ANGLE, 0)));
+ if (iter != displays->end())
+ {
+ displays->erase(iter);
+ }
+ break;
+ }
+ case EGL_PLATFORM_DEVICE_EXT:
+ {
+ DevicePlatformDisplayMap *displays = GetDevicePlatformDisplayMap();
+ DevicePlatformDisplayMap::iterator iter = displays->find(mDevice);
+ if (iter != displays->end())
+ {
+ displays->erase(iter);
+ }
+ break;
+ }
+ default:
+ {
+ UNREACHABLE();
+ }
+ }
+
+ SafeDelete(mDevice);
+ SafeDelete(mImplementation);
+}
+
+void Display::setLabel(EGLLabelKHR label)
+{
+ mState.label = label;
+}
+
+EGLLabelKHR Display::getLabel() const
+{
+ return mState.label;
+}
+
+void Display::onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message)
+{
+ ASSERT(index == kGPUSwitchedSubjectIndex);
+ ASSERT(message == angle::SubjectMessage::SubjectChanged);
+ for (gl::Context *context : mState.contextSet)
+ {
+ context->onGPUSwitch();
+ }
+}
+
+void Display::setupDisplayPlatform(rx::DisplayImpl *impl)
+{
+ ASSERT(!mInitialized);
+
+ ASSERT(impl != nullptr);
+ SafeDelete(mImplementation);
+ mImplementation = impl;
+
+ // TODO(anglebug.com/7365): Remove PlatformMethods.
+ const angle::PlatformMethods *platformMethods =
+ reinterpret_cast<const angle::PlatformMethods *>(
+ mAttributeMap.get(EGL_PLATFORM_ANGLE_PLATFORM_METHODS_ANGLEX, 0));
+ if (platformMethods != nullptr)
+ {
+ *ANGLEPlatformCurrent() = *platformMethods;
+ }
+ else
+ {
+ ANGLESetDefaultDisplayPlatform(this);
+ }
+
+ const char **featuresForceEnabled =
+ reinterpret_cast<const char **>(mAttributeMap.get(EGL_FEATURE_OVERRIDES_ENABLED_ANGLE, 0));
+ const char **featuresForceDisabled =
+ reinterpret_cast<const char **>(mAttributeMap.get(EGL_FEATURE_OVERRIDES_DISABLED_ANGLE, 0));
+ mState.featureOverridesEnabled = EGLStringArrayToStringVector(featuresForceEnabled);
+ mState.featureOverridesDisabled = EGLStringArrayToStringVector(featuresForceDisabled);
+ mState.featuresAllDisabled =
+ static_cast<bool>(mAttributeMap.get(EGL_FEATURE_ALL_DISABLED_ANGLE, 0));
+ mImplementation->addObserver(&mGPUSwitchedBinding);
+}
+
+Error Display::initialize()
+{
+ mTerminatedByApi = false;
+
+ ASSERT(mImplementation != nullptr);
+ mImplementation->setBlobCache(&mBlobCache);
+
+ // Enable shader caching if debug layers are turned on. This allows us to test that shaders are
+ // properly saved & restored on all platforms. The cache won't allocate space until it's used
+ // and will be ignored entirely if the application / system sets it's own cache functions.
+ if (rx::ShouldUseDebugLayers(mAttributeMap))
+ {
+ mBlobCache.resize(1024 * 1024);
+ }
+
+ setGlobalDebugAnnotator();
+
+ gl::InitializeDebugMutexIfNeeded();
+
+ ANGLE_TRACE_EVENT0("gpu.angle", "egl::Display::initialize");
+
+ if (isInitialized())
+ {
+ return NoError();
+ }
+
+ Error error = mImplementation->initialize(this);
+ if (error.isError())
+ {
+ // Log extended error message here
+ ERR() << "ANGLE Display::initialize error " << error.getID() << ": " << error.getMessage();
+ return error;
+ }
+
+ mCaps = mImplementation->getCaps();
+
+ mConfigSet = mImplementation->generateConfigs();
+ if (mConfigSet.size() == 0)
+ {
+ mImplementation->terminate();
+ return EglNotInitialized() << "No configs were generated.";
+ }
+
+ // OpenGL ES1 is implemented in the frontend, explicitly add ES1 support to all configs
+ for (auto &config : mConfigSet)
+ {
+ // TODO(geofflang): Enable the conformant bit once we pass enough tests
+ // config.second.conformant |= EGL_OPENGL_ES_BIT;
+
+ config.second.renderableType |= EGL_OPENGL_ES_BIT;
+
+ // If we aren't using desktop GL entry points, remove desktop GL support from all configs
+#if !defined(ANGLE_ENABLE_GL_DESKTOP_FRONTEND)
+ config.second.renderableType &= ~EGL_OPENGL_BIT;
+#endif
+ }
+
+ if (!mState.featuresAllDisabled)
+ {
+ initializeFrontendFeatures();
+ }
+
+ mFeatures.clear();
+ mFrontendFeatures.populateFeatureList(&mFeatures);
+ mImplementation->populateFeatureList(&mFeatures);
+
+ initDisplayExtensions();
+ initVendorString();
+ initVersionString();
+ initClientAPIString();
+
+ // Populate the Display's EGLDeviceEXT if the Display wasn't created using one
+ if (mPlatform == EGL_PLATFORM_DEVICE_EXT)
+ {
+ // For EGL_PLATFORM_DEVICE_EXT, mDevice should always be populated using
+ // an external device
+ ASSERT(mDevice != nullptr);
+ }
+ else if (GetClientExtensions().deviceQueryEXT)
+ {
+ std::unique_ptr<rx::DeviceImpl> impl(mImplementation->createDevice());
+ ASSERT(impl);
+ error = impl->initialize();
+ if (error.isError())
+ {
+ ERR() << "Failed to initialize display because device creation failed: "
+ << error.getMessage();
+ mImplementation->terminate();
+ return error;
+ }
+ // Don't leak Device memory.
+ ASSERT(mDevice == nullptr);
+ mDevice = new Device(this, impl.release());
+ }
+ else
+ {
+ mDevice = nullptr;
+ }
+
+ mInitialized = true;
+
+ return NoError();
+}
+
+Error Display::destroyInvalidEglObjects()
+{
+ // Destroy invalid EGL objects
+ while (!mInvalidContextSet.empty())
+ {
+ gl::Context *context = *mInvalidContextSet.begin();
+ context->setIsDestroyed();
+ ANGLE_TRY(releaseContextImpl(context, &mInvalidContextSet));
+ }
+
+ while (!mInvalidImageSet.empty())
+ {
+ destroyImageImpl(*mInvalidImageSet.begin(), &mInvalidImageSet);
+ }
+
+ while (!mInvalidStreamSet.empty())
+ {
+ destroyStreamImpl(*mInvalidStreamSet.begin(), &mInvalidStreamSet);
+ }
+
+ while (!mInvalidSurfaceSet.empty())
+ {
+ ANGLE_TRY(destroySurfaceImpl(*mInvalidSurfaceSet.begin(), &mInvalidSurfaceSet));
+ }
+
+ while (!mInvalidSyncSet.empty())
+ {
+ destroySyncImpl(*mInvalidSyncSet.begin(), &mInvalidSyncSet);
+ }
+
+ return NoError();
+}
+
+Error Display::terminate(Thread *thread, TerminateReason terminateReason)
+{
+ if (terminateReason == TerminateReason::Api)
+ {
+ mTerminatedByApi = true;
+ }
+
+ // All subsequent calls assume the display to be valid and terminated by app.
+ // If it is not terminated or if it isn't even initialized, early return.
+ if (!mTerminatedByApi || !mInitialized)
+ {
+ return NoError();
+ }
+
+ // EGL 1.5 Specification
+ // 3.2 Initialization
+ // Termination marks all EGL-specific resources, such as contexts and surfaces, associated
+ // with the specified display for deletion. Handles to all such resources are invalid as soon
+ // as eglTerminate returns. Cache EGL objects that are no longer valid.
+ //
+ // It is fairly common for apps to call eglTerminate while some contexts and/or surfaces are
+ // still current on some thread. Since objects are refCounted, trying to destroy them right away
+ // would only result in a decRef. We instead cache such invalid objects and use other EGL
+ // entrypoints like eglReleaseThread or thread exit events (on the Android platform) to
+ // perform the necessary cleanup.
+ mInvalidImageSet.insert(mImageSet.begin(), mImageSet.end());
+ mImageSet.clear();
+
+ mInvalidStreamSet.insert(mStreamSet.begin(), mStreamSet.end());
+ mStreamSet.clear();
+
+ mInvalidSurfaceSet.insert(mState.surfaceSet.begin(), mState.surfaceSet.end());
+ mState.surfaceSet.clear();
+
+ mInvalidSyncSet.insert(mSyncSet.begin(), mSyncSet.end());
+ mSyncSet.clear();
+
+ // Cache total number of contexts before invalidation. This is used as a check to verify that
+ // no context is "lost" while being moved between the various sets.
+ size_t contextSetSizeBeforeInvalidation = mState.contextSet.size() + mInvalidContextSet.size();
+
+ // If app called eglTerminate and no active threads remain,
+ // force realease any context that is still current.
+ ContextSet contextsStillCurrent = {};
+ for (gl::Context *context : mState.contextSet)
+ {
+ if (context->getRefCount() > 0)
+ {
+ if (terminateReason == TerminateReason::NoActiveThreads)
+ {
+ ASSERT(mTerminatedByApi);
+ context->release();
+ (void)context->unMakeCurrent(this);
+ }
+ else
+ {
+ contextsStillCurrent.emplace(context);
+ continue;
+ }
+ }
+
+ // Add context that is not current to mInvalidContextSet for cleanup.
+ mInvalidContextSet.emplace(context);
+ }
+
+ // There are many methods that require contexts that are still current to be present in
+ // display's contextSet like during context release or to notify of state changes in a subject.
+ // So as to not interrupt this flow, do not remove contexts that are still current on some
+ // thread from display's contextSet even though eglTerminate marks such contexts as invalid.
+ //
+ // "mState.contextSet" will now contain only those contexts that are still current on some
+ // thread.
+ mState.contextSet = std::move(contextsStillCurrent);
+
+ // Assert that the total number of contexts is the same before and after context invalidation.
+ ASSERT(contextSetSizeBeforeInvalidation ==
+ mState.contextSet.size() + mInvalidContextSet.size());
+
+ if (!mState.contextSet.empty())
+ {
+ // There was atleast 1 context that was current on some thread, early return.
+ return NoError();
+ }
+
+ mMemoryProgramCache.clear();
+ mMemoryShaderCache.clear();
+ mBlobCache.setBlobCacheFuncs(nullptr, nullptr);
+
+ // The global texture and semaphore managers should be deleted with the last context that uses
+ // it.
+ ASSERT(mGlobalTextureShareGroupUsers == 0 && mTextureManager == nullptr);
+ ASSERT(mGlobalSemaphoreShareGroupUsers == 0 && mSemaphoreManager == nullptr);
+
+ // Clean up all invalid objects
+ ANGLE_TRY(destroyInvalidEglObjects());
+
+ mConfigSet.clear();
+
+ if (mDevice != nullptr && mDevice->getOwningDisplay() != nullptr)
+ {
+ // Don't delete the device if it was created externally using eglCreateDeviceANGLE
+ // We also shouldn't set it to null in case eglInitialize() is called again later
+ SafeDelete(mDevice);
+ }
+
+ mImplementation->terminate();
+
+ mDeviceLost = false;
+
+ mInitialized = false;
+
+ gl::UninitializeDebugAnnotations();
+
+ // TODO(jmadill): Store Platform in Display and deinit here.
+ ANGLEResetDisplayPlatform(this);
+
+ return NoError();
+}
+
+Error Display::prepareForCall()
+{
+ return mImplementation->prepareForCall();
+}
+
+Error Display::releaseThread()
+{
+ ANGLE_TRY(mImplementation->releaseThread());
+ return destroyInvalidEglObjects();
+}
+
+void Display::addActiveThread(Thread *thread)
+{
+ mActiveThreads.insert(thread);
+}
+
+void Display::threadCleanup(Thread *thread)
+{
+ mActiveThreads.erase(thread);
+ const bool noActiveThreads = mActiveThreads.size() == 0;
+
+ (void)terminate(thread, noActiveThreads ? TerminateReason::NoActiveThreads
+ : TerminateReason::InternalCleanup);
+}
+
+std::vector<const Config *> Display::getConfigs(const egl::AttributeMap &attribs) const
+{
+ return mConfigSet.filter(attribs);
+}
+
+std::vector<const Config *> Display::chooseConfig(const egl::AttributeMap &attribs) const
+{
+ egl::AttributeMap attribsWithDefaults = AttributeMap();
+
+ // Insert default values for attributes that have either an Exact or Mask selection criteria,
+ // and a default value that matters (e.g. isn't EGL_DONT_CARE):
+ attribsWithDefaults.insert(EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER);
+ attribsWithDefaults.insert(EGL_LEVEL, 0);
+ attribsWithDefaults.insert(EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT);
+ attribsWithDefaults.insert(EGL_SURFACE_TYPE, EGL_WINDOW_BIT);
+ attribsWithDefaults.insert(EGL_TRANSPARENT_TYPE, EGL_NONE);
+ if (getExtensions().pixelFormatFloat)
+ {
+ attribsWithDefaults.insert(EGL_COLOR_COMPONENT_TYPE_EXT,
+ EGL_COLOR_COMPONENT_TYPE_FIXED_EXT);
+ }
+
+ // Add the caller-specified values (Note: the poorly-named insert() method will replace any
+ // of the default values from above):
+ for (auto attribIter = attribs.begin(); attribIter != attribs.end(); attribIter++)
+ {
+ attribsWithDefaults.insert(attribIter->first, attribIter->second);
+ }
+
+ return mConfigSet.filter(attribsWithDefaults);
+}
+
+Error Display::createWindowSurface(const Config *configuration,
+ EGLNativeWindowType window,
+ const AttributeMap &attribs,
+ Surface **outSurface)
+{
+ if (mImplementation->testDeviceLost())
+ {
+ ANGLE_TRY(restoreLostDevice());
+ }
+
+ SurfacePointer surface(new WindowSurface(mImplementation, configuration, window, attribs,
+ mFrontendFeatures.forceRobustResourceInit.enabled),
+ this);
+ ANGLE_TRY(surface->initialize(this));
+
+ ASSERT(outSurface != nullptr);
+ *outSurface = surface.release();
+ mState.surfaceSet.insert(*outSurface);
+
+ WindowSurfaceMap *windowSurfaces = GetWindowSurfaces();
+ ASSERT(windowSurfaces && windowSurfaces->find(window) == windowSurfaces->end());
+ windowSurfaces->insert(std::make_pair(window, *outSurface));
+
+ mSurface = *outSurface;
+
+ return NoError();
+}
+
+Error Display::createPbufferSurface(const Config *configuration,
+ const AttributeMap &attribs,
+ Surface **outSurface)
+{
+ ASSERT(isInitialized());
+
+ if (mImplementation->testDeviceLost())
+ {
+ ANGLE_TRY(restoreLostDevice());
+ }
+
+ SurfacePointer surface(new PbufferSurface(mImplementation, configuration, attribs,
+ mFrontendFeatures.forceRobustResourceInit.enabled),
+ this);
+ ANGLE_TRY(surface->initialize(this));
+
+ ASSERT(outSurface != nullptr);
+ *outSurface = surface.release();
+ mState.surfaceSet.insert(*outSurface);
+
+ return NoError();
+}
+
+Error Display::createPbufferFromClientBuffer(const Config *configuration,
+ EGLenum buftype,
+ EGLClientBuffer clientBuffer,
+ const AttributeMap &attribs,
+ Surface **outSurface)
+{
+ ASSERT(isInitialized());
+
+ if (mImplementation->testDeviceLost())
+ {
+ ANGLE_TRY(restoreLostDevice());
+ }
+
+ SurfacePointer surface(
+ new PbufferSurface(mImplementation, configuration, buftype, clientBuffer, attribs,
+ mFrontendFeatures.forceRobustResourceInit.enabled),
+ this);
+ ANGLE_TRY(surface->initialize(this));
+
+ ASSERT(outSurface != nullptr);
+ *outSurface = surface.release();
+ mState.surfaceSet.insert(*outSurface);
+
+ return NoError();
+}
+
+Error Display::createPixmapSurface(const Config *configuration,
+ NativePixmapType nativePixmap,
+ const AttributeMap &attribs,
+ Surface **outSurface)
+{
+ ASSERT(isInitialized());
+
+ if (mImplementation->testDeviceLost())
+ {
+ ANGLE_TRY(restoreLostDevice());
+ }
+
+ SurfacePointer surface(new PixmapSurface(mImplementation, configuration, nativePixmap, attribs,
+ mFrontendFeatures.forceRobustResourceInit.enabled),
+ this);
+ ANGLE_TRY(surface->initialize(this));
+
+ ASSERT(outSurface != nullptr);
+ *outSurface = surface.release();
+ mState.surfaceSet.insert(*outSurface);
+
+ return NoError();
+}
+
+Error Display::createImage(const gl::Context *context,
+ EGLenum target,
+ EGLClientBuffer buffer,
+ const AttributeMap &attribs,
+ Image **outImage)
+{
+ ASSERT(isInitialized());
+
+ if (mImplementation->testDeviceLost())
+ {
+ ANGLE_TRY(restoreLostDevice());
+ }
+
+ egl::ImageSibling *sibling = nullptr;
+ if (IsTextureTarget(target))
+ {
+ sibling = context->getTexture({egl_gl::EGLClientBufferToGLObjectHandle(buffer)});
+ }
+ else if (IsRenderbufferTarget(target))
+ {
+ sibling = context->getRenderbuffer({egl_gl::EGLClientBufferToGLObjectHandle(buffer)});
+ }
+ else if (IsExternalImageTarget(target))
+ {
+ sibling = new ExternalImageSibling(mImplementation, context, target, buffer, attribs);
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+ ASSERT(sibling != nullptr);
+
+ angle::UniqueObjectPointer<Image, Display> imagePtr(
+ new Image(mImplementation, context, target, sibling, attribs), this);
+ ANGLE_TRY(imagePtr->initialize(this));
+
+ Image *image = imagePtr.release();
+
+ ASSERT(outImage != nullptr);
+ *outImage = image;
+
+ // Add this image to the list of all images and hold a ref to it.
+ image->addRef();
+ mImageSet.insert(image);
+
+ return NoError();
+}
+
+Error Display::createStream(const AttributeMap &attribs, Stream **outStream)
+{
+ ASSERT(isInitialized());
+
+ Stream *stream = new Stream(this, attribs);
+
+ ASSERT(stream != nullptr);
+ mStreamSet.insert(stream);
+
+ ASSERT(outStream != nullptr);
+ *outStream = stream;
+
+ return NoError();
+}
+
+Error Display::createContext(const Config *configuration,
+ gl::Context *shareContext,
+ EGLenum clientType,
+ const AttributeMap &attribs,
+ gl::Context **outContext)
+{
+ ASSERT(!mTerminatedByApi);
+ ASSERT(isInitialized());
+
+ if (mImplementation->testDeviceLost())
+ {
+ ANGLE_TRY(restoreLostDevice());
+ }
+
+ // This display texture sharing will allow the first context to create the texture share group.
+ bool usingDisplayTextureShareGroup =
+ attribs.get(EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE, EGL_FALSE) == EGL_TRUE;
+ gl::TextureManager *shareTextures = nullptr;
+
+ if (usingDisplayTextureShareGroup)
+ {
+ ASSERT((mTextureManager == nullptr) == (mGlobalTextureShareGroupUsers == 0));
+ if (mTextureManager == nullptr)
+ {
+ mTextureManager = new gl::TextureManager();
+ }
+
+ mGlobalTextureShareGroupUsers++;
+ shareTextures = mTextureManager;
+ }
+
+ // This display semaphore sharing will allow the first context to create the semaphore share
+ // group.
+ bool usingDisplaySemaphoreShareGroup =
+ attribs.get(EGL_DISPLAY_SEMAPHORE_SHARE_GROUP_ANGLE, EGL_FALSE) == EGL_TRUE;
+ gl::SemaphoreManager *shareSemaphores = nullptr;
+ if (usingDisplaySemaphoreShareGroup)
+ {
+ ASSERT((mSemaphoreManager == nullptr) == (mGlobalSemaphoreShareGroupUsers == 0));
+ if (mSemaphoreManager == nullptr)
+ {
+ mSemaphoreManager = new gl::SemaphoreManager();
+ }
+
+ mGlobalSemaphoreShareGroupUsers++;
+ shareSemaphores = mSemaphoreManager;
+ }
+
+ gl::MemoryProgramCache *programCachePointer = &mMemoryProgramCache;
+ // Check context creation attributes to see if we are using EGL_ANGLE_program_cache_control.
+ // If not, keep caching enabled for EGL_ANDROID_blob_cache, which can have its callbacks set
+ // at any time.
+ bool usesProgramCacheControl = attribs.contains(EGL_CONTEXT_PROGRAM_BINARY_CACHE_ENABLED_ANGLE);
+ if (usesProgramCacheControl)
+ {
+ bool programCacheControlEnabled =
+ (attribs.get(EGL_CONTEXT_PROGRAM_BINARY_CACHE_ENABLED_ANGLE, GL_FALSE) == GL_TRUE);
+ // A program cache size of zero indicates it should be disabled.
+ if (!programCacheControlEnabled || mMemoryProgramCache.maxSize() == 0)
+ {
+ programCachePointer = nullptr;
+ }
+ }
+
+ gl::MemoryShaderCache *shaderCachePointer = &mMemoryShaderCache;
+ // Check if shader caching frontend feature is enabled.
+ if (!mFrontendFeatures.cacheCompiledShader.enabled)
+ {
+ shaderCachePointer = nullptr;
+ }
+
+ gl::Context *context = new gl::Context(
+ this, configuration, shareContext, shareTextures, shareSemaphores, programCachePointer,
+ shaderCachePointer, clientType, attribs, mDisplayExtensions, GetClientExtensions());
+ Error error = context->initialize();
+ if (error.isError())
+ {
+ delete context;
+ return error;
+ }
+
+ if (shareContext != nullptr)
+ {
+ shareContext->setShared();
+ }
+
+ ASSERT(context != nullptr);
+ mState.contextSet.insert(context);
+
+ ASSERT(outContext != nullptr);
+ *outContext = context;
+ return NoError();
+}
+
+Error Display::createSync(const gl::Context *currentContext,
+ EGLenum type,
+ const AttributeMap &attribs,
+ Sync **outSync)
+{
+ ASSERT(isInitialized());
+
+ if (mImplementation->testDeviceLost())
+ {
+ ANGLE_TRY(restoreLostDevice());
+ }
+
+ angle::UniqueObjectPointer<egl::Sync, Display> syncPtr(new Sync(mImplementation, type, attribs),
+ this);
+
+ ANGLE_TRY(syncPtr->initialize(this, currentContext));
+
+ Sync *sync = syncPtr.release();
+
+ sync->addRef();
+ mSyncSet.insert(sync);
+
+ *outSync = sync;
+ return NoError();
+}
+
+Error Display::makeCurrent(Thread *thread,
+ gl::Context *previousContext,
+ egl::Surface *drawSurface,
+ egl::Surface *readSurface,
+ gl::Context *context)
+{
+ if (!mInitialized)
+ {
+ return NoError();
+ }
+
+ bool contextChanged = context != previousContext;
+ if (previousContext != nullptr && contextChanged)
+ {
+ previousContext->release();
+ thread->setCurrent(nullptr);
+
+ auto error = previousContext->unMakeCurrent(this);
+ if (previousContext->getRefCount() == 0 && previousContext->isDestroyed())
+ {
+ // The previous Context may have been created with a different Display.
+ Display *previousDisplay = previousContext->getDisplay();
+ ANGLE_TRY(previousDisplay->releaseContext(previousContext, thread));
+ }
+ ANGLE_TRY(error);
+ }
+
+ thread->setCurrent(context);
+
+ ANGLE_TRY(mImplementation->makeCurrent(this, drawSurface, readSurface, context));
+
+ if (context != nullptr)
+ {
+ ANGLE_TRY(context->makeCurrent(this, drawSurface, readSurface));
+ if (contextChanged)
+ {
+ context->addRef();
+ }
+ }
+
+ // Tick all the scratch buffers to make sure they get cleaned up eventually if they stop being
+ // used.
+ {
+ std::lock_guard<std::mutex> lock(mScratchBufferMutex);
+
+ for (angle::ScratchBuffer &scatchBuffer : mScratchBuffers)
+ {
+ scatchBuffer.tick();
+ }
+ for (angle::ScratchBuffer &zeroFilledBuffer : mZeroFilledBuffers)
+ {
+ zeroFilledBuffer.tick();
+ }
+ }
+
+ return NoError();
+}
+
+Error Display::restoreLostDevice()
+{
+ for (ContextSet::iterator ctx = mState.contextSet.begin(); ctx != mState.contextSet.end();
+ ctx++)
+ {
+ if ((*ctx)->isResetNotificationEnabled())
+ {
+ // If reset notifications have been requested, application must delete all contexts
+ // first
+ return EglContextLost();
+ }
+ }
+
+ return mImplementation->restoreLostDevice(this);
+}
+
+Error Display::destroySurfaceImpl(Surface *surface, SurfaceSet *surfaces)
+{
+ if (surface->getType() == EGL_WINDOW_BIT)
+ {
+ WindowSurfaceMap *windowSurfaces = GetWindowSurfaces();
+ ASSERT(windowSurfaces);
+
+ bool surfaceRemoved = false;
+ for (WindowSurfaceMap::iterator iter = windowSurfaces->begin();
+ iter != windowSurfaces->end(); iter++)
+ {
+ if (iter->second == surface)
+ {
+ windowSurfaces->erase(iter);
+ surfaceRemoved = true;
+ break;
+ }
+ }
+
+ ASSERT(surfaceRemoved);
+ }
+
+ auto iter = surfaces->find(surface);
+ ASSERT(iter != surfaces->end());
+ surfaces->erase(iter);
+ ANGLE_TRY(surface->onDestroy(this));
+ return NoError();
+}
+
+void Display::destroyImageImpl(Image *image, ImageSet *images)
+{
+ auto iter = images->find(image);
+ ASSERT(iter != images->end());
+ (*iter)->release(this);
+ images->erase(iter);
+}
+
+void Display::destroyStreamImpl(Stream *stream, StreamSet *streams)
+{
+ streams->erase(stream);
+ SafeDelete(stream);
+}
+
+// releaseContext must be called with the context being deleted as current.
+// To do that we can only call this in two places, Display::makeCurrent at the point where this
+// context is being made uncurrent and in Display::destroyContext where we make the context current
+// as part of destruction.
+Error Display::releaseContext(gl::Context *context, Thread *thread)
+{
+ return releaseContextImpl(context, &mState.contextSet);
+}
+
+Error Display::releaseContextImpl(gl::Context *context, ContextSet *contexts)
+{
+ ASSERT(context->getRefCount() == 0);
+
+ // Use scoped_ptr to make sure the context is always freed.
+ std::unique_ptr<gl::Context> unique_context(context);
+ ASSERT(contexts->find(context) != contexts->end());
+ contexts->erase(context);
+
+ if (context->usingDisplayTextureShareGroup())
+ {
+ ASSERT(mGlobalTextureShareGroupUsers >= 1 && mTextureManager != nullptr);
+ if (mGlobalTextureShareGroupUsers == 1)
+ {
+ // If this is the last context using the global share group, destroy the global
+ // texture manager so that the textures can be destroyed while a context still
+ // exists
+ mTextureManager->release(context);
+ mTextureManager = nullptr;
+ }
+ mGlobalTextureShareGroupUsers--;
+ }
+
+ if (context->usingDisplaySemaphoreShareGroup())
+ {
+ ASSERT(mGlobalSemaphoreShareGroupUsers >= 1 && mSemaphoreManager != nullptr);
+ if (mGlobalSemaphoreShareGroupUsers == 1)
+ {
+ // If this is the last context using the global share group, destroy the global
+ // semaphore manager so that the semaphores can be destroyed while a context still
+ // exists
+ mSemaphoreManager->release(context);
+ mSemaphoreManager = nullptr;
+ }
+ mGlobalSemaphoreShareGroupUsers--;
+ }
+
+ ANGLE_TRY(context->onDestroy(this));
+
+ return NoError();
+}
+
+Error Display::destroyContext(Thread *thread, gl::Context *context)
+{
+ auto *currentContext = thread->getContext();
+ auto *currentDrawSurface = thread->getCurrentDrawSurface();
+ auto *currentReadSurface = thread->getCurrentReadSurface();
+
+ context->setIsDestroyed();
+
+ // If the context is still current on at least 1 thread, just return since it'll be released
+ // once no threads have it current anymore.
+ if (context->getRefCount() > 0)
+ {
+ return NoError();
+ }
+
+ // For external context, we cannot change the current native context, and the API user should
+ // make sure the native context is current.
+ if (context->isExternal())
+ {
+ ANGLE_TRY(releaseContext(context, thread));
+ }
+ else
+ {
+ // Keep |currentContext| alive, while releasing |context|.
+ gl::ScopedContextRef scopedContextRef(currentContext);
+
+ // keep |currentDrawSurface| and |currentReadSurface| alive as well
+ // while releasing |context|.
+ ScopedSurfaceRef drawSurfaceRef(currentDrawSurface);
+ ScopedSurfaceRef readSurfaceRef(
+ currentReadSurface == currentDrawSurface ? nullptr : currentReadSurface);
+
+ // Make the context current, so we can release resources belong to the context, and then
+ // when context is released from the current, it will be destroyed.
+ // TODO(http://www.anglebug.com/6322): Don't require a Context to be current in order to
+ // destroy it.
+ ANGLE_TRY(makeCurrent(thread, currentContext, nullptr, nullptr, context));
+ ANGLE_TRY(
+ makeCurrent(thread, context, currentDrawSurface, currentReadSurface, currentContext));
+ }
+
+ // If eglTerminate() has previously been called and this is the last Context the Display owns,
+ // we can now fully terminate the display and release all of its resources.
+ if (mTerminatedByApi)
+ {
+ for (const gl::Context *ctx : mState.contextSet)
+ {
+ if (ctx->getRefCount() > 0)
+ {
+ return NoError();
+ }
+ }
+
+ return terminate(thread, TerminateReason::InternalCleanup);
+ }
+
+ return NoError();
+}
+
+void Display::destroySyncImpl(Sync *sync, SyncSet *syncs)
+{
+ auto iter = syncs->find(sync);
+ ASSERT(iter != syncs->end());
+ (*iter)->release(this);
+ syncs->erase(iter);
+}
+
+void Display::destroyImage(Image *image)
+{
+ return destroyImageImpl(image, &mImageSet);
+}
+
+void Display::destroyStream(Stream *stream)
+{
+ return destroyStreamImpl(stream, &mStreamSet);
+}
+
+Error Display::destroySurface(Surface *surface)
+{
+ return destroySurfaceImpl(surface, &mState.surfaceSet);
+}
+
+void Display::destroySync(Sync *sync)
+{
+ return destroySyncImpl(sync, &mSyncSet);
+}
+
+bool Display::isDeviceLost() const
+{
+ ASSERT(isInitialized());
+ return mDeviceLost;
+}
+
+bool Display::testDeviceLost()
+{
+ ASSERT(isInitialized());
+
+ if (!mDeviceLost && mImplementation->testDeviceLost())
+ {
+ notifyDeviceLost();
+ }
+
+ return mDeviceLost;
+}
+
+void Display::notifyDeviceLost()
+{
+ if (mDeviceLost)
+ {
+ return;
+ }
+
+ for (ContextSet::iterator context = mState.contextSet.begin();
+ context != mState.contextSet.end(); context++)
+ {
+ (*context)->markContextLost(gl::GraphicsResetStatus::UnknownContextReset);
+ }
+
+ mDeviceLost = true;
+}
+
+void Display::setBlobCacheFuncs(EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get)
+{
+ mBlobCache.setBlobCacheFuncs(set, get);
+ mImplementation->setBlobCacheFuncs(set, get);
+}
+
+// static
+EGLClientBuffer Display::GetNativeClientBuffer(const AHardwareBuffer *buffer)
+{
+ return angle::android::AHardwareBufferToClientBuffer(buffer);
+}
+
+// static
+Error Display::CreateNativeClientBuffer(const egl::AttributeMap &attribMap,
+ EGLClientBuffer *eglClientBuffer)
+{
+ int androidHardwareBufferFormat = gl::GetAndroidHardwareBufferFormatFromChannelSizes(attribMap);
+ int width = attribMap.getAsInt(EGL_WIDTH, 0);
+ int height = attribMap.getAsInt(EGL_HEIGHT, 0);
+ int usage = attribMap.getAsInt(EGL_NATIVE_BUFFER_USAGE_ANDROID, 0);
+
+ // https://developer.android.com/ndk/reference/group/a-hardware-buffer#ahardwarebuffer_lock
+ // for AHardwareBuffer_lock()
+ // The passed AHardwareBuffer must have one layer, otherwise the call will fail.
+ constexpr int kLayerCount = 1;
+
+ *eglClientBuffer = angle::android::CreateEGLClientBufferFromAHardwareBuffer(
+ width, height, kLayerCount, androidHardwareBufferFormat, usage);
+
+ return (*eglClientBuffer == nullptr)
+ ? egl::EglBadParameter() << "native client buffer allocation failed."
+ : NoError();
+}
+
+Error Display::waitClient(const gl::Context *context)
+{
+ return mImplementation->waitClient(context);
+}
+
+Error Display::waitNative(const gl::Context *context, EGLint engine)
+{
+ return mImplementation->waitNative(context, engine);
+}
+
+const Caps &Display::getCaps() const
+{
+ return mCaps;
+}
+
+bool Display::isInitialized() const
+{
+ return mInitialized;
+}
+
+bool Display::isValidConfig(const Config *config) const
+{
+ return mConfigSet.contains(config);
+}
+
+bool Display::isValidContext(const gl::Context *context) const
+{
+ return mState.contextSet.find(const_cast<gl::Context *>(context)) != mState.contextSet.end();
+}
+
+bool Display::isValidSurface(const Surface *surface) const
+{
+ return mState.surfaceSet.find(const_cast<Surface *>(surface)) != mState.surfaceSet.end();
+}
+
+bool Display::isValidImage(const Image *image) const
+{
+ return mImageSet.find(const_cast<Image *>(image)) != mImageSet.end();
+}
+
+bool Display::isValidStream(const Stream *stream) const
+{
+ return mStreamSet.find(const_cast<Stream *>(stream)) != mStreamSet.end();
+}
+
+bool Display::isValidSync(const Sync *sync) const
+{
+ return mSyncSet.find(const_cast<Sync *>(sync)) != mSyncSet.end();
+}
+
+bool Display::hasExistingWindowSurface(EGLNativeWindowType window)
+{
+ WindowSurfaceMap *windowSurfaces = GetWindowSurfaces();
+ ASSERT(windowSurfaces);
+
+ return windowSurfaces->find(window) != windowSurfaces->end();
+}
+
+static ClientExtensions GenerateClientExtensions()
+{
+ ClientExtensions extensions;
+
+ extensions.clientExtensions = true;
+ extensions.platformBase = true;
+ extensions.platformANGLE = true;
+
+#if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11)
+ extensions.platformANGLED3D = true;
+ extensions.platformDevice = true;
+#endif
+
+#if defined(ANGLE_USE_GBM)
+ extensions.platformGbmKHR = true;
+#endif
+
+#if defined(ANGLE_USE_WAYLAND)
+ extensions.platformWaylandEXT = true;
+#endif
+
+#if defined(ANGLE_ENABLE_D3D11)
+# if defined(ANGLE_ENABLE_WINDOWS_UWP)
+ extensions.platformANGLED3D11ON12 = true;
+# else
+ extensions.platformANGLED3D11ON12 = IsWindows10OrGreater();
+# endif
+ extensions.platformANGLEDeviceId = true;
+#endif
+
+#if defined(ANGLE_ENABLE_OPENGL)
+ extensions.platformANGLEOpenGL = true;
+#endif
+
+#if defined(ANGLE_ENABLE_NULL)
+ extensions.platformANGLENULL = true;
+#endif
+
+#if defined(ANGLE_ENABLE_D3D11)
+ extensions.deviceCreation = true;
+ extensions.deviceCreationD3D11 = true;
+ extensions.experimentalPresentPath = true;
+#endif
+
+#if defined(ANGLE_ENABLE_VULKAN)
+ extensions.platformANGLEVulkan = true;
+ extensions.platformANGLEDeviceId = true;
+#endif
+
+#if defined(ANGLE_ENABLE_SWIFTSHADER)
+ extensions.platformANGLEDeviceTypeSwiftShader = true;
+#endif
+
+#if defined(ANGLE_ENABLE_METAL)
+ extensions.platformANGLEMetal = true;
+ extensions.platformANGLEDeviceId = true;
+#endif
+
+#if defined(ANGLE_USE_X11)
+ extensions.x11Visual = true;
+#endif
+
+#if defined(ANGLE_PLATFORM_LINUX)
+ extensions.platformANGLEDeviceTypeEGLANGLE = true;
+#endif
+
+#if (defined(ANGLE_PLATFORM_IOS) && !defined(ANGLE_PLATFORM_MACCATALYST)) || \
+ (defined(ANGLE_PLATFORM_MACCATALYST) && defined(ANGLE_CPU_ARM64))
+ extensions.platformANGLEDeviceContextVolatileEagl = true;
+#endif
+
+#if defined(ANGLE_PLATFORM_MACOS) || defined(ANGLE_PLATFORM_MACCATALYST)
+ extensions.platformANGLEDeviceContextVolatileCgl = true;
+#endif
+
+#if defined(ANGLE_ENABLE_METAL)
+ extensions.displayPowerPreferenceANGLE = true;
+#endif
+
+ extensions.clientGetAllProcAddresses = true;
+ extensions.debug = true;
+ extensions.featureControlANGLE = true;
+ extensions.deviceQueryEXT = true;
+
+ return extensions;
+}
+
+template <typename T>
+static std::string GenerateExtensionsString(const T &extensions)
+{
+ std::vector<std::string> extensionsVector = extensions.getStrings();
+
+ std::ostringstream stream;
+ std::copy(extensionsVector.begin(), extensionsVector.end(),
+ std::ostream_iterator<std::string>(stream, " "));
+ return stream.str();
+}
+
+// static
+const ClientExtensions &Display::GetClientExtensions()
+{
+ static const ClientExtensions clientExtensions = GenerateClientExtensions();
+ return clientExtensions;
+}
+
+// static
+const std::string &Display::GetClientExtensionString()
+{
+ static const angle::base::NoDestructor<std::string> clientExtensionsString(
+ GenerateExtensionsString(GetClientExtensions()));
+ return *clientExtensionsString;
+}
+
+void Display::initDisplayExtensions()
+{
+ mDisplayExtensions = mImplementation->getExtensions();
+
+ // Some extensions are always available because they are implemented in the EGL layer.
+ mDisplayExtensions.createContext = true;
+ mDisplayExtensions.createContextNoError = !mFrontendFeatures.forceGlErrorChecking.enabled;
+ mDisplayExtensions.createContextWebGLCompatibility = true;
+ mDisplayExtensions.createContextBindGeneratesResource = true;
+ mDisplayExtensions.createContextClientArrays = true;
+ mDisplayExtensions.pixelFormatFloat = true;
+ mDisplayExtensions.reusableSyncKHR = true;
+
+ // Force EGL_KHR_get_all_proc_addresses on.
+ mDisplayExtensions.getAllProcAddresses = true;
+
+ // Enable program cache control since it is not back-end dependent.
+ mDisplayExtensions.programCacheControlANGLE = true;
+
+ // Request extension is implemented in the ANGLE frontend
+ mDisplayExtensions.createContextExtensionsEnabled = true;
+
+ // Blob cache extension is provided by the ANGLE frontend
+ mDisplayExtensions.blobCache = true;
+
+ // The EGL_ANDROID_recordable extension is provided by the ANGLE frontend, and will always
+ // say that ANativeWindow is not recordable.
+ mDisplayExtensions.recordable = true;
+
+ // All backends support specific context versions
+ mDisplayExtensions.createContextBackwardsCompatible = true;
+
+ mDisplayExtensionString = GenerateExtensionsString(mDisplayExtensions);
+}
+
+bool Display::isValidNativeWindow(EGLNativeWindowType window) const
+{
+ return mImplementation->isValidNativeWindow(window);
+}
+
+Error Display::validateClientBuffer(const Config *configuration,
+ EGLenum buftype,
+ EGLClientBuffer clientBuffer,
+ const AttributeMap &attribs) const
+{
+ return mImplementation->validateClientBuffer(configuration, buftype, clientBuffer, attribs);
+}
+
+Error Display::validateImageClientBuffer(const gl::Context *context,
+ EGLenum target,
+ EGLClientBuffer clientBuffer,
+ const egl::AttributeMap &attribs) const
+{
+ return mImplementation->validateImageClientBuffer(context, target, clientBuffer, attribs);
+}
+
+Error Display::valdiatePixmap(const Config *config,
+ EGLNativePixmapType pixmap,
+ const AttributeMap &attributes) const
+{
+ return mImplementation->validatePixmap(config, pixmap, attributes);
+}
+
+bool Display::isValidDisplay(const egl::Display *display)
+{
+ const ANGLEPlatformDisplayMap *anglePlatformDisplayMap = GetANGLEPlatformDisplayMap();
+ for (const auto &displayPair : *anglePlatformDisplayMap)
+ {
+ if (displayPair.second == display)
+ {
+ return true;
+ }
+ }
+
+ const DevicePlatformDisplayMap *devicePlatformDisplayMap = GetDevicePlatformDisplayMap();
+ for (const auto &displayPair : *devicePlatformDisplayMap)
+ {
+ if (displayPair.second == display)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool Display::isValidNativeDisplay(EGLNativeDisplayType display)
+{
+ // TODO(jmadill): handle this properly
+ if (display == EGL_DEFAULT_DISPLAY)
+ {
+ return true;
+ }
+
+#if defined(ANGLE_PLATFORM_WINDOWS) && !defined(ANGLE_ENABLE_WINDOWS_UWP)
+ if (display == EGL_SOFTWARE_DISPLAY_ANGLE || display == EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE ||
+ display == EGL_D3D11_ONLY_DISPLAY_ANGLE)
+ {
+ return true;
+ }
+ return (WindowFromDC(display) != nullptr);
+#else
+ return true;
+#endif
+}
+
+void Display::initVendorString()
+{
+ mVendorString = "Google Inc.";
+ std::string vendorStringImpl = mImplementation->getVendorString();
+ if (!vendorStringImpl.empty())
+ {
+ mVendorString += " (" + vendorStringImpl + ")";
+ }
+}
+
+void Display::initVersionString()
+{
+ mVersionString = mImplementation->getVersionString(true);
+}
+
+void Display::initClientAPIString()
+{
+ // If the max supported desktop version is not None, we support a desktop GL frontend.
+ if (mImplementation->getMaxSupportedDesktopVersion().valid())
+ {
+ mClientAPIString = "OpenGL_ES OpenGL";
+ }
+ else
+ {
+ mClientAPIString = "OpenGL_ES";
+ }
+}
+
+void Display::initializeFrontendFeatures()
+{
+ // Enable on all Impls
+ ANGLE_FEATURE_CONDITION((&mFrontendFeatures), loseContextOnOutOfMemory, true);
+ ANGLE_FEATURE_CONDITION((&mFrontendFeatures), allowCompressedFormats, true);
+
+ // No longer enable this on any Impl - crbug.com/1165751
+ ANGLE_FEATURE_CONDITION((&mFrontendFeatures), scalarizeVecAndMatConstructorArgs, false);
+
+ // Disabled by default. To reduce the risk, create a feature to enable
+ // compressing pipeline cache in multi-thread pool.
+ ANGLE_FEATURE_CONDITION(&mFrontendFeatures, enableCompressingPipelineCacheInThreadPool, false);
+
+ // Disabled by default until work on the extension is complete - anglebug.com/7279.
+ ANGLE_FEATURE_CONDITION(&mFrontendFeatures, emulatePixelLocalStorage, false);
+
+ mImplementation->initializeFrontendFeatures(&mFrontendFeatures);
+
+ rx::ApplyFeatureOverrides(&mFrontendFeatures, mState);
+}
+
+const DisplayExtensions &Display::getExtensions() const
+{
+ return mDisplayExtensions;
+}
+
+const std::string &Display::getExtensionString() const
+{
+ return mDisplayExtensionString;
+}
+
+const std::string &Display::getVendorString() const
+{
+ return mVendorString;
+}
+
+const std::string &Display::getVersionString() const
+{
+ return mVersionString;
+}
+
+const std::string &Display::getClientAPIString() const
+{
+ return mClientAPIString;
+}
+
+std::string Display::getBackendRendererDescription() const
+{
+ return mImplementation->getRendererDescription();
+}
+
+std::string Display::getBackendVendorString() const
+{
+ return mImplementation->getVendorString();
+}
+
+std::string Display::getBackendVersionString(bool includeFullVersion) const
+{
+ return mImplementation->getVersionString(includeFullVersion);
+}
+
+Device *Display::getDevice() const
+{
+ return mDevice;
+}
+
+Surface *Display::getWGLSurface() const
+{
+ return mSurface;
+}
+
+gl::Version Display::getMaxSupportedESVersion() const
+{
+ return mImplementation->getMaxSupportedESVersion();
+}
+
+EGLint Display::programCacheGetAttrib(EGLenum attrib) const
+{
+ switch (attrib)
+ {
+ case EGL_PROGRAM_CACHE_KEY_LENGTH_ANGLE:
+ return static_cast<EGLint>(BlobCache::kKeyLength);
+
+ case EGL_PROGRAM_CACHE_SIZE_ANGLE:
+ return static_cast<EGLint>(mMemoryProgramCache.entryCount());
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+Error Display::programCacheQuery(EGLint index,
+ void *key,
+ EGLint *keysize,
+ void *binary,
+ EGLint *binarysize)
+{
+ ASSERT(index >= 0 && index < static_cast<EGLint>(mMemoryProgramCache.entryCount()));
+
+ const BlobCache::Key *programHash = nullptr;
+ BlobCache::Value programBinary;
+ // TODO(jmadill): Make this thread-safe.
+ bool result =
+ mMemoryProgramCache.getAt(static_cast<size_t>(index), &programHash, &programBinary);
+ if (!result)
+ {
+ return EglBadAccess() << "Program binary not accessible.";
+ }
+
+ ASSERT(keysize && binarysize);
+
+ if (key)
+ {
+ ASSERT(*keysize == static_cast<EGLint>(BlobCache::kKeyLength));
+ memcpy(key, programHash->data(), BlobCache::kKeyLength);
+ }
+
+ if (binary)
+ {
+ // Note: we check the size here instead of in the validation code, since we need to
+ // access the cache as atomically as possible. It's possible that the cache contents
+ // could change between the validation size check and the retrieval.
+ if (programBinary.size() > static_cast<size_t>(*binarysize))
+ {
+ return EglBadAccess() << "Program binary too large or changed during access.";
+ }
+
+ memcpy(binary, programBinary.data(), programBinary.size());
+ }
+
+ *binarysize = static_cast<EGLint>(programBinary.size());
+ *keysize = static_cast<EGLint>(BlobCache::kKeyLength);
+
+ return NoError();
+}
+
+Error Display::programCachePopulate(const void *key,
+ EGLint keysize,
+ const void *binary,
+ EGLint binarysize)
+{
+ ASSERT(keysize == static_cast<EGLint>(BlobCache::kKeyLength));
+
+ BlobCache::Key programHash;
+ memcpy(programHash.data(), key, BlobCache::kKeyLength);
+
+ if (!mMemoryProgramCache.putBinary(programHash, reinterpret_cast<const uint8_t *>(binary),
+ static_cast<size_t>(binarysize)))
+ {
+ return EglBadAccess() << "Failed to copy program binary into the cache.";
+ }
+
+ return NoError();
+}
+
+EGLint Display::programCacheResize(EGLint limit, EGLenum mode)
+{
+ switch (mode)
+ {
+ case EGL_PROGRAM_CACHE_RESIZE_ANGLE:
+ {
+ size_t initialSize = mMemoryProgramCache.size();
+ mMemoryProgramCache.resize(static_cast<size_t>(limit));
+ return static_cast<EGLint>(initialSize);
+ }
+
+ case EGL_PROGRAM_CACHE_TRIM_ANGLE:
+ return static_cast<EGLint>(mMemoryProgramCache.trim(static_cast<size_t>(limit)));
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+void Display::overrideFrontendFeatures(const std::vector<std::string> &featureNames, bool enabled)
+{
+ mFrontendFeatures.overrideFeatures(featureNames, enabled);
+}
+
+const char *Display::queryStringi(const EGLint name, const EGLint index)
+{
+ const char *result = nullptr;
+ switch (name)
+ {
+ case EGL_FEATURE_NAME_ANGLE:
+ result = mFeatures[index]->name;
+ break;
+ case EGL_FEATURE_CATEGORY_ANGLE:
+ result = angle::FeatureCategoryToString(mFeatures[index]->category);
+ break;
+ case EGL_FEATURE_DESCRIPTION_ANGLE:
+ result = mFeatures[index]->description;
+ break;
+ case EGL_FEATURE_BUG_ANGLE:
+ result = mFeatures[index]->bug;
+ break;
+ case EGL_FEATURE_STATUS_ANGLE:
+ result = angle::FeatureStatusToString(mFeatures[index]->enabled);
+ break;
+ case EGL_FEATURE_CONDITION_ANGLE:
+ result = mFeatures[index]->condition;
+ break;
+ default:
+ UNREACHABLE();
+ return nullptr;
+ }
+ return result;
+}
+
+EGLAttrib Display::queryAttrib(const EGLint attribute)
+{
+ EGLAttrib value = 0;
+ switch (attribute)
+ {
+ case EGL_DEVICE_EXT:
+ value = reinterpret_cast<EGLAttrib>(mDevice);
+ break;
+
+ case EGL_FEATURE_COUNT_ANGLE:
+ value = mFeatures.size();
+ break;
+
+ default:
+ UNREACHABLE();
+ }
+ return value;
+}
+
+angle::ScratchBuffer Display::requestScratchBuffer()
+{
+ return requestScratchBufferImpl(&mScratchBuffers);
+}
+
+void Display::returnScratchBuffer(angle::ScratchBuffer scratchBuffer)
+{
+ returnScratchBufferImpl(std::move(scratchBuffer), &mScratchBuffers);
+}
+
+angle::ScratchBuffer Display::requestZeroFilledBuffer()
+{
+ return requestScratchBufferImpl(&mZeroFilledBuffers);
+}
+
+void Display::returnZeroFilledBuffer(angle::ScratchBuffer zeroFilledBuffer)
+{
+ returnScratchBufferImpl(std::move(zeroFilledBuffer), &mZeroFilledBuffers);
+}
+
+angle::ScratchBuffer Display::requestScratchBufferImpl(
+ std::vector<angle::ScratchBuffer> *bufferVector)
+{
+ std::lock_guard<std::mutex> lock(mScratchBufferMutex);
+ if (!bufferVector->empty())
+ {
+ angle::ScratchBuffer buffer = std::move(bufferVector->back());
+ bufferVector->pop_back();
+ return buffer;
+ }
+
+ return angle::ScratchBuffer(kScratchBufferLifetime);
+}
+
+void Display::returnScratchBufferImpl(angle::ScratchBuffer scratchBuffer,
+ std::vector<angle::ScratchBuffer> *bufferVector)
+{
+ std::lock_guard<std::mutex> lock(mScratchBufferMutex);
+ bufferVector->push_back(std::move(scratchBuffer));
+}
+
+Error Display::handleGPUSwitch()
+{
+ ANGLE_TRY(mImplementation->handleGPUSwitch());
+ initVendorString();
+ return NoError();
+}
+
+Error Display::forceGPUSwitch(EGLint gpuIDHigh, EGLint gpuIDLow)
+{
+ ANGLE_TRY(mImplementation->forceGPUSwitch(gpuIDHigh, gpuIDLow));
+ initVendorString();
+ return NoError();
+}
+
+bool Display::supportsDmaBufFormat(EGLint format) const
+{
+ return mImplementation->supportsDmaBufFormat(format);
+}
+
+Error Display::queryDmaBufFormats(EGLint max_formats, EGLint *formats, EGLint *num_formats)
+{
+ ANGLE_TRY(mImplementation->queryDmaBufFormats(max_formats, formats, num_formats));
+ return NoError();
+}
+
+Error Display::queryDmaBufModifiers(EGLint format,
+ EGLint max_modifiers,
+ EGLuint64KHR *modifiers,
+ EGLBoolean *external_only,
+ EGLint *num_modifiers)
+{
+ ANGLE_TRY(mImplementation->queryDmaBufModifiers(format, max_modifiers, modifiers, external_only,
+ num_modifiers));
+ return NoError();
+}
+
+} // namespace egl
diff --git a/gfx/angle/checkout/src/libANGLE/Display.h b/gfx/angle/checkout/src/libANGLE/Display.h
new file mode 100644
index 0000000000..da00026e7b
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Display.h
@@ -0,0 +1,427 @@
+//
+// Copyright 2002 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.
+//
+
+// Display.h: Defines the egl::Display class, representing the abstract
+// display on which graphics are drawn. Implements EGLDisplay.
+// [EGL 1.4] section 2.1.2 page 3.
+
+#ifndef LIBANGLE_DISPLAY_H_
+#define LIBANGLE_DISPLAY_H_
+
+#include <mutex>
+#include <set>
+#include <vector>
+
+#include "libANGLE/AttributeMap.h"
+#include "libANGLE/BlobCache.h"
+#include "libANGLE/Caps.h"
+#include "libANGLE/Config.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Debug.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/LoggingAnnotator.h"
+#include "libANGLE/MemoryProgramCache.h"
+#include "libANGLE/MemoryShaderCache.h"
+#include "libANGLE/Observer.h"
+#include "libANGLE/Version.h"
+#include "platform/Feature.h"
+#include "platform/FrontendFeatures_autogen.h"
+
+namespace angle
+{
+class FrameCaptureShared;
+} // namespace angle
+
+namespace gl
+{
+class Context;
+class TextureManager;
+class SemaphoreManager;
+} // namespace gl
+
+namespace rx
+{
+class DisplayImpl;
+class EGLImplFactory;
+class ShareGroupImpl;
+} // namespace rx
+
+namespace egl
+{
+class Device;
+class Image;
+class Stream;
+class Surface;
+class Sync;
+class Thread;
+
+using ContextSet = angle::HashSet<gl::Context *>;
+using SurfaceSet = angle::HashSet<Surface *>;
+using ThreadSet = angle::HashSet<Thread *>;
+
+struct DisplayState final : private angle::NonCopyable
+{
+ DisplayState(EGLNativeDisplayType nativeDisplayId);
+ ~DisplayState();
+
+ EGLLabelKHR label;
+ ContextSet contextSet;
+ SurfaceSet surfaceSet;
+ std::vector<std::string> featureOverridesEnabled;
+ std::vector<std::string> featureOverridesDisabled;
+ bool featuresAllDisabled;
+ EGLNativeDisplayType displayId;
+};
+
+class ShareGroup final : angle::NonCopyable
+{
+ public:
+ ShareGroup(rx::EGLImplFactory *factory);
+
+ void addRef();
+
+ void release(const egl::Display *display);
+
+ rx::ShareGroupImpl *getImplementation() const { return mImplementation; }
+
+ rx::Serial generateFramebufferSerial() { return mFramebufferSerialFactory.generate(); }
+
+ angle::FrameCaptureShared *getFrameCaptureShared() { return mFrameCaptureShared.get(); }
+
+ void finishAllContexts();
+
+ const ContextSet &getContexts() const { return mContexts; }
+ void addSharedContext(gl::Context *context);
+ void removeSharedContext(gl::Context *context);
+
+ size_t getShareGroupContextCount() const { return mContexts.size(); }
+
+ protected:
+ ~ShareGroup();
+
+ private:
+ size_t mRefCount;
+ rx::ShareGroupImpl *mImplementation;
+ rx::SerialFactory mFramebufferSerialFactory;
+
+ // Note: we use a raw pointer here so we can exclude frame capture sources from the build.
+ std::unique_ptr<angle::FrameCaptureShared> mFrameCaptureShared;
+
+ // The list of contexts within the share group
+ ContextSet mContexts;
+};
+
+// Constant coded here as a reasonable limit.
+constexpr EGLAttrib kProgramCacheSizeAbsoluteMax = 0x4000000;
+
+class Display final : public LabeledObject,
+ public angle::ObserverInterface,
+ public angle::NonCopyable
+{
+ public:
+ ~Display() override;
+
+ void setLabel(EGLLabelKHR label) override;
+ EGLLabelKHR getLabel() const override;
+
+ // Observer implementation.
+ void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override;
+
+ Error initialize();
+
+ enum class TerminateReason
+ {
+ Api,
+ InternalCleanup,
+ NoActiveThreads,
+
+ InvalidEnum,
+ EnumCount = InvalidEnum,
+ };
+ Error terminate(Thread *thread, TerminateReason terminateReason);
+ // Called before all display state dependent EGL functions. Backends can set up, for example,
+ // thread-specific backend state through this function. Not called for functions that do not
+ // need the state.
+ Error prepareForCall();
+ // Called on eglReleaseThread. Backends can tear down thread-specific backend state through
+ // this function.
+ Error releaseThread();
+
+ // Helpers to maintain active thread set to assist with freeing invalid EGL objects.
+ void addActiveThread(Thread *thread);
+ void threadCleanup(Thread *thread);
+
+ static Display *GetDisplayFromDevice(Device *device, const AttributeMap &attribMap);
+ static Display *GetDisplayFromNativeDisplay(EGLenum platform,
+ EGLNativeDisplayType nativeDisplay,
+ const AttributeMap &attribMap);
+ static Display *GetExistingDisplayFromNativeDisplay(EGLNativeDisplayType nativeDisplay);
+
+ using EglDisplaySet = angle::HashSet<Display *>;
+ static EglDisplaySet GetEglDisplaySet();
+
+ static const ClientExtensions &GetClientExtensions();
+ static const std::string &GetClientExtensionString();
+
+ std::vector<const Config *> getConfigs(const AttributeMap &attribs) const;
+ std::vector<const Config *> chooseConfig(const AttributeMap &attribs) const;
+
+ Error createWindowSurface(const Config *configuration,
+ EGLNativeWindowType window,
+ const AttributeMap &attribs,
+ Surface **outSurface);
+ Error createPbufferSurface(const Config *configuration,
+ const AttributeMap &attribs,
+ Surface **outSurface);
+ Error createPbufferFromClientBuffer(const Config *configuration,
+ EGLenum buftype,
+ EGLClientBuffer clientBuffer,
+ const AttributeMap &attribs,
+ Surface **outSurface);
+ Error createPixmapSurface(const Config *configuration,
+ NativePixmapType nativePixmap,
+ const AttributeMap &attribs,
+ Surface **outSurface);
+
+ Error createImage(const gl::Context *context,
+ EGLenum target,
+ EGLClientBuffer buffer,
+ const AttributeMap &attribs,
+ Image **outImage);
+
+ Error createStream(const AttributeMap &attribs, Stream **outStream);
+
+ Error createContext(const Config *configuration,
+ gl::Context *shareContext,
+ const EGLenum clientType,
+ const AttributeMap &attribs,
+ gl::Context **outContext);
+
+ Error createSync(const gl::Context *currentContext,
+ EGLenum type,
+ const AttributeMap &attribs,
+ Sync **outSync);
+
+ Error makeCurrent(Thread *thread,
+ gl::Context *previousContext,
+ Surface *drawSurface,
+ Surface *readSurface,
+ gl::Context *context);
+
+ Error destroySurface(Surface *surface);
+ void destroyImage(Image *image);
+ void destroyStream(Stream *stream);
+ Error destroyContext(Thread *thread, gl::Context *context);
+
+ void destroySync(Sync *sync);
+
+ bool isInitialized() const;
+ bool isValidConfig(const Config *config) const;
+ bool isValidContext(const gl::Context *context) const;
+ bool isValidSurface(const Surface *surface) const;
+ bool isValidImage(const Image *image) const;
+ bool isValidStream(const Stream *stream) const;
+ bool isValidSync(const Sync *sync) const;
+ bool isValidNativeWindow(EGLNativeWindowType window) const;
+
+ Error validateClientBuffer(const Config *configuration,
+ EGLenum buftype,
+ EGLClientBuffer clientBuffer,
+ const AttributeMap &attribs) const;
+ Error validateImageClientBuffer(const gl::Context *context,
+ EGLenum target,
+ EGLClientBuffer clientBuffer,
+ const egl::AttributeMap &attribs) const;
+ Error valdiatePixmap(const Config *config,
+ EGLNativePixmapType pixmap,
+ const AttributeMap &attributes) const;
+
+ static bool isValidDisplay(const Display *display);
+ static bool isValidNativeDisplay(EGLNativeDisplayType display);
+ static bool hasExistingWindowSurface(EGLNativeWindowType window);
+
+ bool isDeviceLost() const;
+ bool testDeviceLost();
+ void notifyDeviceLost();
+
+ void setBlobCacheFuncs(EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get);
+ bool areBlobCacheFuncsSet() const { return mBlobCache.areBlobCacheFuncsSet(); }
+ BlobCache &getBlobCache() { return mBlobCache; }
+
+ static EGLClientBuffer GetNativeClientBuffer(const struct AHardwareBuffer *buffer);
+ static Error CreateNativeClientBuffer(const egl::AttributeMap &attribMap,
+ EGLClientBuffer *eglClientBuffer);
+
+ Error waitClient(const gl::Context *context);
+ Error waitNative(const gl::Context *context, EGLint engine);
+
+ const Caps &getCaps() const;
+
+ const DisplayExtensions &getExtensions() const;
+ const std::string &getExtensionString() const;
+ const std::string &getVendorString() const;
+ const std::string &getVersionString() const;
+ const std::string &getClientAPIString() const;
+
+ std::string getBackendRendererDescription() const;
+ std::string getBackendVendorString() const;
+ std::string getBackendVersionString(bool includeFullVersion) const;
+
+ EGLint programCacheGetAttrib(EGLenum attrib) const;
+ Error programCacheQuery(EGLint index,
+ void *key,
+ EGLint *keysize,
+ void *binary,
+ EGLint *binarysize);
+ Error programCachePopulate(const void *key,
+ EGLint keysize,
+ const void *binary,
+ EGLint binarysize);
+ EGLint programCacheResize(EGLint limit, EGLenum mode);
+
+ const AttributeMap &getAttributeMap() const { return mAttributeMap; }
+ EGLNativeDisplayType getNativeDisplayId() const { return mState.displayId; }
+
+ rx::DisplayImpl *getImplementation() const { return mImplementation; }
+ Device *getDevice() const;
+ Surface *getWGLSurface() const;
+ EGLenum getPlatform() const { return mPlatform; }
+
+ gl::Version getMaxSupportedESVersion() const;
+
+ const DisplayState &getState() const { return mState; }
+
+ const angle::FrontendFeatures &getFrontendFeatures() { return mFrontendFeatures; }
+ void overrideFrontendFeatures(const std::vector<std::string> &featureNames, bool enabled);
+
+ const angle::FeatureList &getFeatures() const { return mFeatures; }
+
+ const char *queryStringi(const EGLint name, const EGLint index);
+
+ EGLAttrib queryAttrib(const EGLint attribute);
+
+ angle::ScratchBuffer requestScratchBuffer();
+ void returnScratchBuffer(angle::ScratchBuffer scratchBuffer);
+
+ angle::ScratchBuffer requestZeroFilledBuffer();
+ void returnZeroFilledBuffer(angle::ScratchBuffer zeroFilledBuffer);
+
+ egl::Error handleGPUSwitch();
+ egl::Error forceGPUSwitch(EGLint gpuIDHigh, EGLint gpuIDLow);
+
+ std::mutex &getDisplayGlobalMutex() { return mDisplayGlobalMutex; }
+ std::mutex &getProgramCacheMutex() { return mProgramCacheMutex; }
+
+ gl::MemoryShaderCache *getMemoryShaderCache() { return &mMemoryShaderCache; }
+
+ // Installs LoggingAnnotator as the global DebugAnnotator, for back-ends that do not implement
+ // their own DebugAnnotator.
+ void setGlobalDebugAnnotator() { gl::InitializeDebugAnnotations(&mAnnotator); }
+
+ bool supportsDmaBufFormat(EGLint format) const;
+ Error queryDmaBufFormats(EGLint max_formats, EGLint *formats, EGLint *num_formats);
+ Error queryDmaBufModifiers(EGLint format,
+ EGLint max_modifiers,
+ EGLuint64KHR *modifiers,
+ EGLBoolean *external_only,
+ EGLint *num_modifiers);
+
+ private:
+ Display(EGLenum platform, EGLNativeDisplayType displayId, Device *eglDevice);
+
+ void setAttributes(const AttributeMap &attribMap) { mAttributeMap = attribMap; }
+
+ void setupDisplayPlatform(rx::DisplayImpl *impl);
+
+ void updateAttribsFromEnvironment(const AttributeMap &attribMap);
+
+ Error restoreLostDevice();
+ Error releaseContext(gl::Context *context, Thread *thread);
+ Error releaseContextImpl(gl::Context *context, ContextSet *contexts);
+
+ void initDisplayExtensions();
+ void initVendorString();
+ void initVersionString();
+ void initClientAPIString();
+ void initializeFrontendFeatures();
+
+ angle::ScratchBuffer requestScratchBufferImpl(std::vector<angle::ScratchBuffer> *bufferVector);
+ void returnScratchBufferImpl(angle::ScratchBuffer scratchBuffer,
+ std::vector<angle::ScratchBuffer> *bufferVector);
+
+ Error destroyInvalidEglObjects();
+
+ DisplayState mState;
+ rx::DisplayImpl *mImplementation;
+ angle::ObserverBinding mGPUSwitchedBinding;
+
+ AttributeMap mAttributeMap;
+
+ ConfigSet mConfigSet;
+
+ typedef angle::HashSet<Image *> ImageSet;
+ ImageSet mImageSet;
+
+ typedef angle::HashSet<Stream *> StreamSet;
+ StreamSet mStreamSet;
+
+ typedef angle::HashSet<Sync *> SyncSet;
+ SyncSet mSyncSet;
+
+ void destroyImageImpl(Image *image, ImageSet *images);
+ void destroyStreamImpl(Stream *stream, StreamSet *streams);
+ Error destroySurfaceImpl(Surface *surface, SurfaceSet *surfaces);
+ void destroySyncImpl(Sync *sync, SyncSet *syncs);
+
+ ContextSet mInvalidContextSet;
+ ImageSet mInvalidImageSet;
+ StreamSet mInvalidStreamSet;
+ SurfaceSet mInvalidSurfaceSet;
+ SyncSet mInvalidSyncSet;
+
+ bool mInitialized;
+ bool mDeviceLost;
+
+ Caps mCaps;
+
+ DisplayExtensions mDisplayExtensions;
+ std::string mDisplayExtensionString;
+
+ std::string mVendorString;
+ std::string mVersionString;
+ std::string mClientAPIString;
+
+ Device *mDevice;
+ Surface *mSurface;
+ EGLenum mPlatform;
+ angle::LoggingAnnotator mAnnotator;
+
+ gl::TextureManager *mTextureManager;
+ gl::SemaphoreManager *mSemaphoreManager;
+ BlobCache mBlobCache;
+ gl::MemoryProgramCache mMemoryProgramCache;
+ gl::MemoryShaderCache mMemoryShaderCache;
+ size_t mGlobalTextureShareGroupUsers;
+ size_t mGlobalSemaphoreShareGroupUsers;
+
+ angle::FrontendFeatures mFrontendFeatures;
+
+ angle::FeatureList mFeatures;
+
+ std::mutex mScratchBufferMutex;
+ std::vector<angle::ScratchBuffer> mScratchBuffers;
+ std::vector<angle::ScratchBuffer> mZeroFilledBuffers;
+
+ std::mutex mDisplayGlobalMutex;
+ std::mutex mProgramCacheMutex;
+
+ bool mTerminatedByApi;
+ ThreadSet mActiveThreads;
+};
+
+} // namespace egl
+
+#endif // LIBANGLE_DISPLAY_H_
diff --git a/gfx/angle/checkout/src/libANGLE/EGLSync.cpp b/gfx/angle/checkout/src/libANGLE/EGLSync.cpp
new file mode 100644
index 0000000000..ddca5de902
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/EGLSync.cpp
@@ -0,0 +1,114 @@
+//
+// Copyright 2002 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.
+//
+
+// EGLSync.cpp: Implements the egl::Sync class.
+
+#include "libANGLE/EGLSync.h"
+
+#include "angle_gl.h"
+
+#include "common/utilities.h"
+#include "libANGLE/renderer/EGLImplFactory.h"
+#include "libANGLE/renderer/EGLReusableSync.h"
+#include "libANGLE/renderer/EGLSyncImpl.h"
+
+namespace egl
+{
+
+Sync::Sync(rx::EGLImplFactory *factory, EGLenum type, const AttributeMap &attribs)
+ : mLabel(nullptr),
+ mType(type),
+ mCondition(EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR),
+ mNativeFenceFD(
+ attribs.getAsInt(EGL_SYNC_NATIVE_FENCE_FD_ANDROID, EGL_NO_NATIVE_FENCE_FD_ANDROID))
+{
+ switch (type)
+ {
+ case EGL_SYNC_FENCE:
+ case EGL_SYNC_NATIVE_FENCE_ANDROID:
+ case EGL_SYNC_METAL_SHARED_EVENT_ANGLE:
+ mFence = std::unique_ptr<rx::EGLSyncImpl>(factory->createSync(attribs));
+ break;
+
+ case EGL_SYNC_REUSABLE_KHR:
+ mFence = std::unique_ptr<rx::EGLSyncImpl>(new rx::ReusableSync(attribs));
+ break;
+
+ default:
+ UNREACHABLE();
+ }
+
+ // Per extension spec: Signaling Condition.
+ // "If the EGL_SYNC_NATIVE_FENCE_FD_ANDROID attribute is not
+ // EGL_NO_NATIVE_FENCE_FD_ANDROID then the EGL_SYNC_CONDITION_KHR attribute
+ // is set to EGL_SYNC_NATIVE_FENCE_SIGNALED_ANDROID and the EGL_SYNC_STATUS_KHR
+ // attribute is set to reflect the signal status of the native fence object.
+ if ((mType == EGL_SYNC_NATIVE_FENCE_ANDROID) &&
+ (mNativeFenceFD != EGL_NO_NATIVE_FENCE_FD_ANDROID))
+ {
+ mCondition = EGL_SYNC_NATIVE_FENCE_SIGNALED_ANDROID;
+ }
+}
+
+void Sync::onDestroy(const Display *display)
+{
+ ASSERT(mFence);
+ mFence->onDestroy(display);
+ mFence.reset();
+}
+
+Sync::~Sync() {}
+
+Error Sync::initialize(const Display *display, const gl::Context *context)
+{
+ return mFence->initialize(display, context, mType);
+}
+
+void Sync::setLabel(EGLLabelKHR label)
+{
+ mLabel = label;
+}
+
+EGLLabelKHR Sync::getLabel() const
+{
+ return mLabel;
+}
+
+Error Sync::clientWait(const Display *display,
+ const gl::Context *context,
+ EGLint flags,
+ EGLTime timeout,
+ EGLint *outResult)
+{
+ return mFence->clientWait(display, context, flags, timeout, outResult);
+}
+
+Error Sync::serverWait(const Display *display, const gl::Context *context, EGLint flags)
+{
+ return mFence->serverWait(display, context, flags);
+}
+
+Error Sync::signal(const Display *display, const gl::Context *context, EGLint mode)
+{
+ return mFence->signal(display, context, mode);
+}
+
+Error Sync::getStatus(const Display *display, EGLint *outStatus) const
+{
+ return mFence->getStatus(display, outStatus);
+}
+
+Error Sync::copyMetalSharedEventANGLE(const Display *display, void **result) const
+{
+ return mFence->copyMetalSharedEventANGLE(display, result);
+}
+
+Error Sync::dupNativeFenceFD(const Display *display, EGLint *result) const
+{
+ return mFence->dupNativeFenceFD(display, result);
+}
+
+} // namespace egl
diff --git a/gfx/angle/checkout/src/libANGLE/EGLSync.h b/gfx/angle/checkout/src/libANGLE/EGLSync.h
new file mode 100644
index 0000000000..2f97e9c3da
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/EGLSync.h
@@ -0,0 +1,72 @@
+//
+// Copyright 2019 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.
+//
+
+// EGLSync.h: Defines the egl::Sync classes, which support the EGL_KHR_fence_sync,
+// EGL_KHR_wait_sync and EGL 1.5 sync objects.
+
+#ifndef LIBANGLE_EGLSYNC_H_
+#define LIBANGLE_EGLSYNC_H_
+
+#include "libANGLE/Debug.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/RefCountObject.h"
+
+#include "common/angleutils.h"
+
+namespace rx
+{
+class EGLImplFactory;
+class EGLSyncImpl;
+} // namespace rx
+
+namespace gl
+{
+class Context;
+} // namespace gl
+
+namespace egl
+{
+class Sync final : public angle::RefCountObject<Display, angle::Result>, public LabeledObject
+{
+ public:
+ Sync(rx::EGLImplFactory *factory, EGLenum type, const AttributeMap &attribs);
+ ~Sync() override;
+
+ void setLabel(EGLLabelKHR label) override;
+ EGLLabelKHR getLabel() const override;
+
+ void onDestroy(const Display *display) override;
+
+ Error initialize(const Display *display, const gl::Context *context);
+ Error clientWait(const Display *display,
+ const gl::Context *context,
+ EGLint flags,
+ EGLTime timeout,
+ EGLint *outResult);
+ Error serverWait(const Display *display, const gl::Context *context, EGLint flags);
+ Error signal(const Display *display, const gl::Context *context, EGLint mode);
+ Error getStatus(const Display *display, EGLint *outStatus) const;
+
+ Error copyMetalSharedEventANGLE(const Display *display, void **result) const;
+ Error dupNativeFenceFD(const Display *display, EGLint *result) const;
+
+ EGLenum getType() const { return mType; }
+ EGLint getCondition() const { return mCondition; }
+ EGLint getNativeFenceFD() const { return mNativeFenceFD; }
+
+ private:
+ std::unique_ptr<rx::EGLSyncImpl> mFence;
+
+ EGLLabelKHR mLabel;
+
+ EGLenum mType;
+ EGLint mCondition;
+ EGLint mNativeFenceFD;
+};
+
+} // namespace egl
+
+#endif // LIBANGLE_FENCE_H_
diff --git a/gfx/angle/checkout/src/libANGLE/Error.cpp b/gfx/angle/checkout/src/libANGLE/Error.cpp
new file mode 100644
index 0000000000..977e8d66e0
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Error.cpp
@@ -0,0 +1,67 @@
+//
+// 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.
+//
+
+// Error.cpp: Implements the egl::Error and gl::Error classes which encapsulate API errors
+// and optional error messages.
+
+#include "libANGLE/Error.h"
+
+#include "common/angleutils.h"
+#include "common/debug.h"
+#include "common/utilities.h"
+
+#include <cstdarg>
+
+namespace
+{
+std::unique_ptr<std::string> EmplaceErrorString(std::string &&message)
+{
+ return message.empty() ? std::unique_ptr<std::string>()
+ : std::unique_ptr<std::string>(new std::string(std::move(message)));
+}
+} // anonymous namespace
+
+namespace egl
+{
+
+Error::Error(EGLint errorCode, std::string &&message)
+ : mCode(errorCode), mID(errorCode), mMessage(EmplaceErrorString(std::move(message)))
+{}
+
+Error::Error(EGLint errorCode, EGLint id, std::string &&message)
+ : mCode(errorCode), mID(id), mMessage(EmplaceErrorString(std::move(message)))
+{}
+
+void Error::createMessageString() const
+{
+ if (!mMessage)
+ {
+ mMessage.reset(new std::string(GetGenericErrorMessage(mCode)));
+ }
+}
+
+const std::string &Error::getMessage() const
+{
+ createMessageString();
+ return *mMessage;
+}
+
+std::ostream &operator<<(std::ostream &os, const Error &err)
+{
+ return gl::FmtHex(os, err.getCode());
+}
+} // namespace egl
+
+namespace angle
+{
+egl::Error ResultToEGL(Result result)
+{
+ if (result == Result::Continue)
+ return egl::NoError();
+
+ return egl::Error(EGL_BAD_ACCESS);
+}
+} // namespace angle
diff --git a/gfx/angle/checkout/src/libANGLE/Error.h b/gfx/angle/checkout/src/libANGLE/Error.h
new file mode 100644
index 0000000000..7f075352cc
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Error.h
@@ -0,0 +1,206 @@
+//
+// 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.
+
+// Error.h: Defines the egl::Error and gl::Error classes which encapsulate API errors
+// and optional error messages.
+
+#ifndef LIBANGLE_ERROR_H_
+#define LIBANGLE_ERROR_H_
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include "angle_gl.h"
+#include "common/angleutils.h"
+#include "common/debug.h"
+
+#include <memory>
+#include <ostream>
+#include <string>
+
+namespace angle
+{
+template <typename ErrorT, typename ErrorBaseT, ErrorBaseT NoErrorVal, typename CodeT, CodeT EnumT>
+class ErrorStreamBase : angle::NonCopyable
+{
+ public:
+ ErrorStreamBase() : mID(EnumT) {}
+ ErrorStreamBase(GLuint id) : mID(id) {}
+
+ template <typename T>
+ ErrorStreamBase &operator<<(T value)
+ {
+ mErrorStream << value;
+ return *this;
+ }
+
+ operator ErrorT() { return ErrorT(EnumT, mID, mErrorStream.str()); }
+
+ private:
+ GLuint mID;
+ std::ostringstream mErrorStream;
+};
+} // namespace angle
+
+namespace egl
+{
+class Error;
+} // namespace egl
+
+namespace egl
+{
+
+class [[nodiscard]] Error final
+{
+ public:
+ explicit inline Error(EGLint errorCode);
+ Error(EGLint errorCode, std::string &&message);
+ Error(EGLint errorCode, EGLint id, std::string &&message);
+ inline Error(const Error &other);
+ inline Error(Error &&other);
+ inline ~Error() = default;
+
+ inline Error &operator=(const Error &other);
+ inline Error &operator=(Error &&other);
+
+ inline EGLint getCode() const;
+ inline EGLint getID() const;
+ inline bool isError() const;
+
+ const std::string &getMessage() const;
+
+ static inline Error NoError();
+
+ private:
+ void createMessageString() const;
+
+ friend std::ostream &operator<<(std::ostream &os, const Error &err);
+
+ EGLint mCode;
+ EGLint mID;
+ mutable std::unique_ptr<std::string> mMessage;
+};
+
+namespace priv
+{
+
+template <EGLint EnumT>
+using ErrorStream = angle::ErrorStreamBase<Error, EGLint, EGL_SUCCESS, EGLint, EnumT>;
+
+} // namespace priv
+
+using EglBadAccess = priv::ErrorStream<EGL_BAD_ACCESS>;
+using EglBadAlloc = priv::ErrorStream<EGL_BAD_ALLOC>;
+using EglBadAttribute = priv::ErrorStream<EGL_BAD_ATTRIBUTE>;
+using EglBadConfig = priv::ErrorStream<EGL_BAD_CONFIG>;
+using EglBadContext = priv::ErrorStream<EGL_BAD_CONTEXT>;
+using EglBadCurrentSurface = priv::ErrorStream<EGL_BAD_CURRENT_SURFACE>;
+using EglBadDevice = priv::ErrorStream<EGL_BAD_DEVICE_EXT>;
+using EglBadDisplay = priv::ErrorStream<EGL_BAD_DISPLAY>;
+using EglBadMatch = priv::ErrorStream<EGL_BAD_MATCH>;
+using EglBadNativeWindow = priv::ErrorStream<EGL_BAD_NATIVE_WINDOW>;
+using EglBadNativePixmap = priv::ErrorStream<EGL_BAD_NATIVE_PIXMAP>;
+using EglBadParameter = priv::ErrorStream<EGL_BAD_PARAMETER>;
+using EglBadState = priv::ErrorStream<EGL_BAD_STATE_KHR>;
+using EglBadStream = priv::ErrorStream<EGL_BAD_STREAM_KHR>;
+using EglBadSurface = priv::ErrorStream<EGL_BAD_SURFACE>;
+using EglContextLost = priv::ErrorStream<EGL_CONTEXT_LOST>;
+using EglNotInitialized = priv::ErrorStream<EGL_NOT_INITIALIZED>;
+
+inline Error NoError()
+{
+ return Error::NoError();
+}
+
+} // namespace egl
+
+#define ANGLE_CONCAT1(x, y) x##y
+#define ANGLE_CONCAT2(x, y) ANGLE_CONCAT1(x, y)
+#define ANGLE_LOCAL_VAR ANGLE_CONCAT2(_localVar, __LINE__)
+
+#define ANGLE_TRY_TEMPLATE(EXPR, FUNC) \
+ do \
+ { \
+ auto ANGLE_LOCAL_VAR = EXPR; \
+ if (ANGLE_UNLIKELY(IsError(ANGLE_LOCAL_VAR))) \
+ { \
+ FUNC(ANGLE_LOCAL_VAR); \
+ } \
+ } while (0)
+
+#define ANGLE_RETURN(X) return X;
+#define ANGLE_TRY(EXPR) ANGLE_TRY_TEMPLATE(EXPR, ANGLE_RETURN)
+
+// TODO(jmadill): Remove after EGL error refactor. http://anglebug.com/3041
+#define ANGLE_SWALLOW_ERR(EXPR) \
+ do \
+ { \
+ auto ANGLE_LOCAL_VAR = EXPR; \
+ if (ANGLE_UNLIKELY(IsError(ANGLE_LOCAL_VAR))) \
+ { \
+ ERR() << "Unhandled internal error: " << ANGLE_LOCAL_VAR; \
+ } \
+ } while (0)
+
+#undef ANGLE_LOCAL_VAR
+#undef ANGLE_CONCAT2
+#undef ANGLE_CONCAT1
+
+#define ANGLE_CHECK(CONTEXT, EXPR, MESSAGE, ERROR) \
+ do \
+ { \
+ if (ANGLE_UNLIKELY(!(EXPR))) \
+ { \
+ CONTEXT->handleError(ERROR, MESSAGE, __FILE__, ANGLE_FUNCTION, __LINE__); \
+ return angle::Result::Stop; \
+ } \
+ } while (0)
+
+namespace angle
+{
+// Result signals if calling code should continue running or early exit. A value of Stop can
+// either indicate an Error or a non-Error early exit condition such as a detected no-op.
+// Incomplete signals special cases that are neither success nor failure but require
+// special attention.
+enum class [[nodiscard]] Result{
+ Continue,
+ Stop,
+ Incomplete,
+};
+
+// TODO(jmadill): Remove this when refactor is complete. http://anglebug.com/3041
+egl::Error ResultToEGL(Result result);
+} // namespace angle
+
+// TODO(jmadill): Remove this when refactor is complete. http://anglebug.com/3041
+inline bool IsError(angle::Result result)
+{
+ return result == angle::Result::Stop;
+}
+
+// TODO(jmadill): Remove this when refactor is complete. http://anglebug.com/3041
+inline bool IsError(const egl::Error &err)
+{
+ return err.isError();
+}
+
+// TODO(jmadill): Remove this when refactor is complete. http://anglebug.com/3041
+inline bool IsError(bool value)
+{
+ return !value;
+}
+
+// Utility macro for handling implementation methods inside Validation.
+#define ANGLE_HANDLE_VALIDATION_ERR(X) \
+ do \
+ { \
+ (void)(X); \
+ return false; \
+ } while (0)
+
+#define ANGLE_VALIDATION_TRY(EXPR) ANGLE_TRY_TEMPLATE(EXPR, ANGLE_HANDLE_VALIDATION_ERR)
+
+#include "Error.inc"
+
+#endif // LIBANGLE_ERROR_H_
diff --git a/gfx/angle/checkout/src/libANGLE/Error.inc b/gfx/angle/checkout/src/libANGLE/Error.inc
new file mode 100644
index 0000000000..e6a8032895
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Error.inc
@@ -0,0 +1,91 @@
+//
+// 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.
+
+// Error.inc: Inline definitions of egl::Error and gl::Error classes which encapsulate API errors
+// and optional error messages.
+
+#include "common/angleutils.h"
+
+#include <cstdarg>
+
+namespace egl
+{
+
+Error::Error(EGLint errorCode)
+ : mCode(errorCode),
+ mID(0)
+{
+}
+
+Error::Error(const Error &other)
+ : mCode(other.mCode),
+ mID(other.mID)
+{
+ if (other.mMessage)
+ {
+ createMessageString();
+ *mMessage = *(other.mMessage);
+ }
+}
+
+Error::Error(Error &&other)
+ : mCode(other.mCode),
+ mID(other.mID),
+ mMessage(std::move(other.mMessage))
+{
+}
+
+Error &Error::operator=(const Error &other)
+{
+ mCode = other.mCode;
+ mID = other.mID;
+
+ if (other.mMessage)
+ {
+ createMessageString();
+ *mMessage = *(other.mMessage);
+ }
+ else
+ {
+ mMessage.reset();
+ }
+
+ return *this;
+}
+
+Error &Error::operator=(Error &&other)
+{
+ if (this != &other)
+ {
+ mCode = other.mCode;
+ mID = other.mID;
+ mMessage = std::move(other.mMessage);
+ }
+
+ return *this;
+}
+
+EGLint Error::getCode() const
+{
+ return mCode;
+}
+
+EGLint Error::getID() const
+{
+ return mID;
+}
+
+bool Error::isError() const
+{
+ return (mCode != EGL_SUCCESS);
+}
+
+// Static
+Error Error::NoError()
+{
+ return Error(EGL_SUCCESS);
+}
+
+}
diff --git a/gfx/angle/checkout/src/libANGLE/ErrorStrings.h b/gfx/angle/checkout/src/libANGLE/ErrorStrings.h
new file mode 100644
index 0000000000..df352b8114
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/ErrorStrings.h
@@ -0,0 +1,627 @@
+//
+// Copyright 2017 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.
+//
+
+// ErrorStrings.h: Contains mapping of commonly used error messages
+
+#ifndef LIBANGLE_ERRORSTRINGS_H_
+#define LIBANGLE_ERRORSTRINGS_H_
+
+namespace gl
+{
+namespace err
+{
+#define MSG constexpr const char *
+
+// clang-format off
+MSG k3DDepthStencil = "Format cannot be GL_DEPTH_COMPONENT or GL_DEPTH_STENCIL if target is GL_TEXTURE_3D";
+MSG kANGLECopyTexture3DUnavailable = "GL_ANGLE_copy_texture_3d extension not available.";
+MSG kANGLECopyTextureMissingRequiredExtension = "Copy*TextureCHROMIUM from EXTERNAL_OES to integer format requires OES_EGL_image_external_essl3";
+MSG kAdvancedBlendEquationWithMRT = "Advanced blend equation can only be used when only one draw buffer is not NONE";
+MSG kAdvancedBlendExtensionNotEnabled = "GL_KHR_blend_equation_advanced extension not enabled.";
+MSG kAtomicCounterResourceName = "Active atomic counter resources are not assigned name strings.";
+MSG kAttributeListNotNull = "Attribute list must be NULL or GL_NONE";
+MSG kAttributeZeroRequiresDivisorLimitation = "The current context doesn't support setting a non-zero divisor on the attribute with index zero. Please reorder the attributes in your vertex shader so that attribute zero can have a zero divisor.";
+MSG kBaseLevelNegative = "Base level must be at least 0.";
+MSG kBaseLevelNonZero = "Base level must be 0.";
+MSG kBaseLevelOutOfRange = "Texture base level out of range";
+MSG kBlendEquationNotEnabled = "Active fragment shader does not include the layout qualifier matching the blend equation";
+MSG kBlitDepthOrStencilFormatMismatch = "Depth/stencil buffer format combination not allowed for blit.";
+MSG kBlitDimensionsOutOfRange = "BlitFramebuffer dimensions out of 32-bit integer range.";
+MSG kBlitExtensionDepthStencilWholeBufferBlit = "Only whole-buffer depth and stencil blits are supported by this extension.";
+MSG kBlitExtensionFormatMismatch = "Attempting to blit and the read and draw buffer formats don't match. read: 0x%04X draw: 0x%04X";
+MSG kBlitExtensionFromInvalidAttachmentType = "Blits are only supported from 2D texture, renderbuffer or default framebuffer attachments in this extension.";
+MSG kBlitExtensionLinear = "Linear blit not supported in this extension.";
+MSG kBlitExtensionMultisampledDepthOrStencil = "Multisampled depth/stencil blit is not supported by this extension.";
+MSG kBlitExtensionMultisampledWholeBufferBlit = "Only whole-buffer blit is supported from a multisampled read buffer in this extension.";
+MSG kBlitExtensionNotAvailable = "Blit extension not available.";
+MSG kBlitExtensionScaleOrFlip = "Scaling and flipping in BlitFramebufferANGLE not supported by this implementation.";
+MSG kBlitExtensionToInvalidAttachmentType = "Blits are only supported to 2D texture, renderbuffer or default framebuffer attachments in this extension.";
+MSG kBlitFeedbackLoop = "Blit feedback loop: the read and draw framebuffers are the same.";
+MSG kBlitFramebufferMissing = "Read and draw framebuffers must both exist for a blit to succeed.";
+MSG kBlitFromMultiview = "Attempt to read from a multi-view framebuffer.";
+MSG kBlitIntegerWithLinearFilter = "Cannot use GL_LINEAR filter when blitting a integer framebuffer.";
+MSG kBlitInvalidFilter = "Invalid blit filter.";
+MSG kBlitInvalidMask = "Invalid blit mask.";
+MSG kBlitMissingColor = "Attempt to read from a missing color attachment of a complete framebuffer.";
+MSG kBlitMissingDepthOrStencil = "Attempt to read from a missing depth/stencil attachment of a complete framebuffer.";
+MSG kBlitMultisampledBoundsMismatch = "Attempt to blit from a multisampled framebuffer and the bounds don't match with the draw framebuffer.";
+MSG kBlitMultisampledFormatOrBoundsMismatch = "Attempt to blit from a multisampled framebuffer and the bounds or format of the color buffer don't match with the draw framebuffer.";
+MSG kBlitOnlyNearestForNonColor = "Only nearest filtering can be used when blitting buffers other than the color buffer.";
+MSG kBlitSameImageColor = "Read and write color attachments cannot be the same image.";
+MSG kBlitSameImageDepthOrStencil = "Read and write depth stencil attachments cannot be the same image.";
+MSG kBlitToMultiview = "Attempt to write to a multi-view framebuffer.";
+MSG kBlitTypeMismatchFixedOrFloat = "If the read buffer contains fixed-point or floating-point values, the draw buffer must as well.";
+MSG kBlitTypeMismatchFixedPoint = "If the read buffer contains fixed-point values, the draw buffer must as well.";
+MSG kBlitTypeMismatchSignedInteger = "If the read buffer contains signed integer values the draw buffer must as well.";
+MSG kBlitTypeMismatchUnsignedInteger = "If the read buffer contains unsigned integer values the draw buffer must as well.";
+MSG kBlitYUVFramebuffer = "Blitting to or from a YUV framebuffer is disallowed.";
+MSG kBufferAlreadyMapped = "Buffer is already mapped.";
+MSG kBufferBoundForTransformFeedback = "Buffer is bound for transform feedback.";
+MSG kBufferImmutable = "Buffer is immutable.";
+MSG kBufferMapped = "An active buffer is mapped";
+MSG kBufferNotBound = "A buffer must be bound.";
+MSG kBufferNotMappable = "Attempted to map buffer object zero.";
+MSG kBufferNotMapped = "Buffer is not mapped.";
+MSG kBufferNotUpdatable = "Buffer is not updatable.";
+MSG kBufferOffsetOverflow = "Buffer offset overflow.";
+MSG kBufferPointerNotAvailable = "Can not get pointer for reserved buffer name zero.";
+MSG kCannotPopDefaultDebugGroup = "Cannot pop the default debug group.";
+MSG kClientBufferInvalid = "Size must not exceed the size of clientbuffer";
+MSG kClientDataInVertexArray = "Client data cannot be used with a non-default vertex array object.";
+MSG kColorNumberGreaterThanMaxDrawBuffers = "Color number for primary color greater than or equal to MAX_DRAW_BUFFERS";
+MSG kColorNumberGreaterThanMaxDualSourceDrawBuffers = "Color number for secondary color greater than or equal to MAX_DUAL_SOURCE_DRAW_BUFFERS";
+MSG kCompressedDataSizeTooSmall = "dataSize is too small";
+MSG kCompressedMismatch = "Compressed data is valid if-and-only-if the texture is compressed.";
+MSG kCompressedTextureDimensionsMustMatchData = "Compressed texture dimensions must exactly match the dimensions of the data passed in.";
+MSG kCompressedTexturesNotAttachable = "Compressed textures cannot be attached to a framebuffer.";
+MSG kConstantColorAlphaLimitation = "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR as color factors is not supported by this implementation.";
+MSG kContextLost = "Context has been lost.";
+MSG kCopyAlias = "The read and write copy regions alias memory.";
+MSG kCopyFromYUVFramebuffer = "Copying from a YUV framebuffer is disallowed.";
+MSG kCubemapFacesEqualDimensions = "Each cubemap face must have equal width and height.";
+MSG kCubemapIncomplete = "Texture is not cubemap complete. All cubemaps faces must be defined and be the same size.";
+MSG kCubemapInvalidDepth = "The cubemap depth must be a multiple of 6.";
+MSG kDataTypeNotAligned = "Data is not evenly divisible into the number of bytes needed to store in memory a datum indicated by type.";
+MSG kDefaultFramebuffer = "Default framebuffer is bound.";
+MSG kDefaultFramebufferAttachmentOnUserFBO = "Invalid attachment when a user framebuffer is bound.";
+MSG kDefaultFramebufferInvalidAttachment = "Invalid attachment when the default framebuffer is bound.";
+MSG kDefaultFramebufferInvalidDrawBuffer = "Only NONE or BACK are valid draw buffers for the default framebuffer";
+MSG kDefaultFramebufferTarget = "It is invalid to change default FBO's attachments";
+MSG kDefaultVertexArray = "Default vertex array object is bound.";
+MSG kDestinationImmutable = "Destination texture cannot be immutable.";
+MSG kDestinationLevelNotDefined = "The destination level of the destination texture must be defined.";
+MSG kDestinationTextureTooSmall = "Destination texture too small.";
+MSG kDimensionsMustBePow2 = "Texture dimensions must be power-of-two.";
+MSG kDispatchIndirectBufferNotBound = "Dispatch indirect buffer must be bound.";
+MSG kDrawBufferMaskMismatch = "Active draw buffers with missing fragment shader outputs.";
+MSG kDrawBuffersIndexedExtensionNotAvailable = "EXT/OES_draw_buffers_indexed is not available.";
+MSG kES31OrDrawBuffersIndexedExtensionNotAvailable = "EXT/OES_draw_buffers_indexed or ES 3.1 are required but not available.";
+MSG kDrawBufferTypeMismatch = "Fragment shader output type does not match the bound framebuffer attachment type.";
+MSG kDrawFramebufferIncomplete = "Draw framebuffer is incomplete";
+MSG kDrawIndirectBufferNotBound = "Draw indirect buffer must be bound.";
+MSG kEGLImageCannotCreate2DMultisampled = "Cannot create a 2D texture from a multisampled EGL image.";
+MSG kEGLImageRenderbufferFormatNotSupported = "EGL image internal format is not supported as a renderbuffer.";
+MSG kEGLImageTextureFormatNotSupported = "EGL image internal format is not supported as a texture.";
+MSG kEGLImageTextureTargetMismatch = "The source EGL image is incompatible with the target texture type.";
+MSG kElementArrayBufferBoundForTransformFeedback = "It is undefined behavior to use an element array buffer that is bound for transform feedback.";
+MSG kElementArrayNoBufferOrPointer = "No element array buffer and no pointer.";
+MSG kEnumInvalid = "Invalid enum provided.";
+MSG kEnumNotSupported = "Enum 0x%04X is currently not supported.";
+MSG kEnumRequiresGLES30 = "Enum requires GLES 3.0";
+MSG kEnumRequiresGLES31 = "Enum requires GLES 3.1";
+MSG kES1or32Required = "OpenGL ES 1.x or 3.2 Required";
+MSG kES31Required = "OpenGL ES 3.1 Required";
+MSG kES32Required = "OpenGL ES 3.2 Required";
+MSG kES3Required = "OpenGL ES 3.0 Required.";
+MSG kExceedsComputeWorkGroupCountX = "num_groups_x cannot be greater than MAX_COMPUTE_WORK_GROUP_COUNT[0]";
+MSG kExceedsComputeWorkGroupCountY = "num_groups_y cannot be greater than MAX_COMPUTE_WORK_GROUP_COUNT[1]";
+MSG kExceedsComputeWorkGroupCountZ = "num_groups_z cannot be greater than MAX_COMPUTE_WORK_GROUP_COUNT[2]";
+MSG kExceedsElementRange = "Element value exceeds element range.";
+MSG kExceedsFramebufferHeight = "Params less than 0 or greater than GL_MAX_FRAMEBUFFER_HEIGHT.";
+MSG kExceedsFramebufferSamples = "Params less than 0 or greater than GL_MAX_FRAMEBUFFER_SAMPLES.";
+MSG kExceedsFramebufferWidth = "Params less than 0 or greater than GL_MAX_FRAMEBUFFER_WIDTH.";
+MSG kExceedsMaxColorAttachments = "Index is greater than the maximum supported color attachments";
+MSG kExceedsMaxDebugGroupStackDepth = "Cannot push more than GL_MAX_DEBUG_GROUP_STACK_DEPTH debug groups.";
+MSG kExceedsMaxDebugMessageLength = "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.";
+MSG kExceedsMaxDrawBuffers = "Draw buffer greater than MAX_DRAW_BUFFERS.";
+MSG kExceedsMaxElement = "Element value exceeds maximum element index.";
+MSG kExceedsMaxImageUnits = "Index must be within [0, MAX_IMAGE_UNITS).";
+MSG kExceedsMaxLabelLength = "Label length is larger than GL_MAX_LABEL_LENGTH.";
+MSG kExceedsMaxShaderStorageBufferBindings = "Index must be within [0, MAX_SHADER_STORAGE_BUFFER_BINDINGS).";
+MSG kExceedsMaxVertexAttribBindings = "Index must be within [0, MAX_VERTEX_ATTRIB_BINDINGS).";
+MSG kExceedsMaxVertexAttribStride = "Stride must be within [0, MAX_VERTEX_ATTRIB_STRIDE).";
+MSG kExceedsNumExtensions = "Index must be within [0, NUM_EXTENSIONS).";
+MSG kExceedsNumRequestableExtensions = "Index must be within [0, NUM_REQUESTABLE_EXTENSIONS_ANGLE).";
+MSG kExpectedProgramName = "Expected a program name, but found a shader name.";
+MSG kExpectedShaderName = "Expected a shader name, but found a program name.";
+MSG kExtensionNotEnabled = "Extension is not enabled.";
+MSG kExtensionNotDisablable = "Extension is not disablable.";
+MSG kExtensionNotRequestable = "Extension is not requestable.";
+MSG kExternalBufferInvalidOffset = "Offset must be zero for external buffers";
+MSG kExternalTextureAttachmentNotYUV = "External texture attached to framebuffer is not YUV.";
+MSG kExternalTextureNotSupported = "External texture extension not enabled";
+MSG kFeedbackLoop = "Feedback loop formed between Framebuffer and active Texture.";
+MSG kFixedNotInWebGL = "GL_FIXED is not supported in WebGL.";
+MSG kFormatNotRenderable = "Internal format is not renderable.";
+MSG kFragDataBindingIndexOutOfRange = "Fragment output color index must be zero or one.";
+MSG kFragmentInputTypeNotFloatingPoint = "Fragment input type is not a floating point scalar or vector.";
+MSG kFramebufferFetchNonCoherentExtensionNotEnabled = "GL_EXT_shader_framebuffer_fetch_non_coherent not enabled.";
+MSG kFramebufferIncomplete = "Framebuffer is incomplete.";
+MSG kFramebufferIncompleteAttachment = "Attachment type must be compatible with attachment object.";
+MSG kFramebufferIncompleteAttachmentDepthGreaterThanMaxLayers = "Framebuffer is incomplete: Attachment depth is greater than MAX_FRAMEBUFFER_LAYERS.";
+MSG kFramebufferIncompleteAttachmentInconsistantBitPlanes = "Framebuffer is incomplete: Attachments have inconsistent bit plane counts.";
+MSG kFramebufferIncompleteAttachmentLayerGreaterThanDepth = "Framebuffer is incomplete: Attachment layer is greater than texture layer count.";
+MSG kFramebufferIncompleteAttachmentLevelNotBaseLevelForIncompleteMipTexture = "Framebuffer is incomplete: Attachment level not equal to the base level and the texture is not mipmap complete.";
+MSG kFramebufferIncompleteAttachmentLevelOutOfBaseMaxLevelRange = "Framebuffer is incomplete: Attachment level is not in the [base level, max level] range.";
+MSG kFramebufferIncompleteAttachmentNoDepthBitsInDepthBuffer = "Framebuffer is incomplete: Depth attachment has no depth bits.";
+MSG kFramebufferIncompleteAttachmentNoStencilBitsInStencilBuffer = "Framebuffer is incomplete: Stencil attachment has no stencil bits.";
+MSG kFramebufferIncompleteAttachmentNotCubeComplete = "Framebuffer is incomplete: Attachment is an incomplete cube map.";
+MSG kFramebufferIncompleteAttachmentNotRenderable = "Framebuffer is incomplete: Attachment is not renderable.";
+MSG kFramebufferIncompleteAttachmentSamplesGreaterThanMaxSupportedSamples = "Framebuffer is incomplete: Attachment samples are greater than the maximum supported samples for this format.";
+MSG kFramebufferIncompleteAttachmentsNotUnique = "Framebuffer is incomplete: All attachments must be unique.";
+MSG kFramebufferIncompleteAttachmentWebGLDepthBufferHasStencilBits = "Framebuffer is incomplete: Stencil attachment has depth bits.";
+MSG kFramebufferIncompleteAttachmentWebGLDepthStencilNoDepthOrStencilBits = "Framebuffer is incomplete: Depth stencil attachment has no depth bits or no stencil bits.";
+MSG kFramebufferIncompleteAttachmentWebGLStencilBufferHasDepthBits = "Framebuffer is incomplete: Stencil attachment has depth bits.";
+MSG kFramebufferIncompleteAttachmentZeroSize = "Framebuffer is incomplete: Attachment has zero size.";
+MSG kFramebufferIncompleteColorBitsUsedExceedsMaxColorBitsSupported = "Framebuffer is incomplete: The total number of color bits exceeds the number of output bits supported.";
+MSG kFramebufferIncompleteDefaultZeroSize = "Framebuffer is incomplete: No attachments and default size is zero.";
+MSG kFramebufferIncompleteDepthAndStencilBuffersNotTheSame = "Framebuffer is incomplete: Depth and stencil attachments are not the same.";
+MSG kFramebufferIncompleteDepthStencilInColorBuffer = "Framebuffer is incomplete: Depth stencil texture in color attachment.";
+MSG kFramebufferIncompleteDriverUnsupported = "Framebuffer is incomplete: Driver does not support this framebuffer configuration.";
+MSG kFramebufferIncompleteInconsistantAttachmentSizes = "Framebuffer is incomplete: Attachments are not all the same size.";
+MSG kFramebufferIncompleteInternalError = "Framebuffer is incomplete: Internal error.";
+MSG kFramebufferIncompleteMismatchedLayeredAttachments = "Framebuffer is incomplete: If one attachment is layered, all must be layered.";
+MSG kFramebufferIncompleteMismatchedLayeredTexturetypes = "Framebuffer is incomplete: If an attachments are layered, they must all be the same texture type.";
+MSG kFramebufferIncompleteMultisampleDepthStencilSampleCountDivisibleByColorSampleCount = "Framebuffer is incomplete: Depth stencil sample count must be divisible by the color sample count.";
+MSG kFramebufferIncompleteMultisampleInconsistentFixedSampleLocations = "Framebuffer is incomplete: Attachments have inconsistent fixed sample locations.";
+MSG kFramebufferIncompleteMultisampleInconsistentSampleCounts = "Framebuffer is incomplete: Attachments have different sample counts.";
+MSG kFramebufferIncompleteMultisampleNonFixedSamplesWithRenderbuffers = "Framebuffer is incomplete: All textures must have fixed samples if paired with multisample renderbuffers.";
+MSG kFramebufferIncompleteMultiviewBaseViewMismatch = "Framebuffer is incomplete: Attachments have inconsistent multiview base view.";
+MSG kFramebufferIncompleteMultiviewMismatch = "Framebuffer is incomplete: Attachments have inconsistent multiview enabled state.";
+MSG kFramebufferIncompleteMultiviewViewsMismatch = "Framebuffer is incomplete: Attachments have inconsistent multiview view counts.";
+MSG kFramebufferIncompleteSurfaceless = "Framebuffer is incomplete: Framebuffer is surfaceless.";
+MSG kFramebufferIncompleteUnsupportedMissmatchedDimensions = "Framebuffer is incomplete: Mismatched attachment sizes are unsupported.";
+MSG kFramebufferIncompleteUnsupportedNonUniqueAttachments = "Framebuffer is incomplete: Non-unique attachments are unsupported.";
+MSG kFramebufferIncompleteUnsupportedSeparateDepthStencilBuffers = "Framebuffer is incomplete: Separate depth and stencil buffers are unsupported.";
+MSG kFramebufferIncompleteWebGLDepthStencilInconsistant = "Framebuffer is incomplete: WebGL depth stencil state is inconsistent.";
+MSG kFramebufferTextureInvalidLayer = "Layer invalid for framebuffer texture attachment.";
+MSG kFramebufferTextureInvalidMipLevel = "Mip level invalid for framebuffer texture attachment.";
+MSG kFramebufferTextureLayerIncorrectTextureType = "Texture is not a three-dimensional, two-dimensional array, two-dimensional multisample array, cube map, or cube map array texture.";
+MSG kGenerateMipmapNotAllowed = "Texture format does not support mipmap generation.";
+MSG kGenerateMipmapZeroSize = "Cannot generate mipmaps for a zero-size texture in a WebGL context.";
+MSG kGeometryShaderExtensionNotEnabled = "GL_EXT_geometry_shader or GL_OES_geometry_shader extension not enabled.";
+MSG kGetImageExtensionNotEnabled = "GL_ANGLE_get_image extension not enabled.";
+MSG kGetImageCompressed = "Texture is compressed, call GetCompressedTexImage instead.";
+MSG kGetImageNotCompressed = "Texture is not compressed, call GetTexImage instead.";
+MSG kGLES1Only = "GLES1-only function.";
+MSG kImageSizeMustBeZero = "imageSize must be 0 if no texture data is provided.";
+MSG kImageSizeTooSmall = "imageSize is too small.";
+MSG kImmutableMemoryObject = "The memory object is immutable.";
+MSG kImmutableTextureBound = "The value of TEXTURE_IMMUTABLE_FORMAT for the texture currently bound to target on the active texture unit is true.";
+MSG kIncompatibleDrawModeAgainstGeometryShader = "Primitive mode is incompatible with the input primitive type of the geometry shader.";
+MSG kIncompatibleDrawModeWithTessellationShader = "When tessellation is active the primitive mode must be GL_PATCHES.";
+MSG kIncompatibleDrawModeWithoutTessellationShader = "When tessellation is not active the primitive mode must not be GL_PATCHES.";
+MSG kIncompatibleTextures = "Texture formats are not compatible";
+MSG kIndexExceedsActiveUniformBlockCount = "Index exceeds active uniform block count.";
+MSG kIndexExceedsMaxActiveUniform = "Index must be less than program active uniform count.";
+MSG kIndexExceedsMaxActiveUniformBlock = "Index must be less than program active uniform block count.";
+MSG kIndexExceedsMaxAtomicCounterBufferBindings = "Index must be less than MAX_ATOMIC_COUNTER_BUFFER_BINDINGS.";
+MSG kIndexExceedsMaxDrawBuffer = "Index must be less than MAX_DRAW_BUFFERS.";
+MSG kIndexExceedsMaxTransformFeedbackAttribs = "Index must be less than MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS.";
+MSG kIndexExceedsMaxUniformBufferBindings = "Index must be less than MAX_UNIFORM_BUFFER_BINDINGS.";
+MSG kIndexExceedsMaxVertexAttribute = "Index must be less than MAX_VERTEX_ATTRIBS.";
+MSG kIndexExceedsMaxWorkgroupDimensions = "Index must be less than the number of workgroup dimensions (3).";
+MSG kIndexExceedsSamples = "Index must be less than the value of SAMPLES.";
+MSG kIndexExceedsTransformFeedbackBufferBindings = "Index is greater than or equal to the number of TRANSFORM_FEEDBACK_BUFFER indexed binding points.";
+MSG kInsufficientBufferSize = "Insufficient buffer size.";
+MSG kInsufficientParams = "More parameters are required than were provided.";
+MSG kInsufficientVertexBufferSize = "Vertex buffer is not big enough for the draw call";
+MSG kIntegerOverflow = "Integer overflow.";
+MSG kInternalFormatRequiresTexture2D = "internalformat is an ETC1 or PVRTC1 format.";
+MSG kInternalFormatRequiresTexture2DArray = "internalformat is an ETC2/EAC format and target is not GL_TEXTURE_2D_ARRAY.";
+MSG kInternalFormatRequiresTexture2DArrayS3TC = "internalformat is an S3TC format and target is not GL_TEXTURE_2D_ARRAY.";
+MSG kInternalFormatRequiresTexture2DArrayRGTC = "internalformat is an RGTC format and target is not GL_TEXTURE_2D_ARRAY.";
+MSG kInternalFormatRequiresTexture2DArrayBPTC = "internalformat is a BPTC format and target is not GL_TEXTURE_2D_ARRAY.";
+MSG kInternalFormatRequiresTexture2DArrayASTC = "internalformat is an ASTC format and target is not GL_TEXTURE_2D_ARRAY.";
+MSG kInvalidAccessBits = "Invalid access bits.";
+MSG kInvalidAccessBitsFlush = "The explicit flushing bit may only be set if the buffer is mapped for writing.";
+MSG kInvalidAccessBitsRead = "Invalid access bits when mapping buffer for reading";
+MSG kInvalidAccessBitsReadWrite = "Need to map buffer for either reading or writing.";
+MSG kInvalidAttachment = "Invalid Attachment Type.";
+MSG kInvalidBindBufferSize = "Invalid buffer binding size.";
+MSG kInvalidBindUniformLocation = "Location must be less than (MAX_VERTEX_UNIFORM_VECTORS + MAX_FRAGMENT_UNIFORM_VECTORS) * 4";
+MSG kInvalidBlendEquation = "Invalid blend equation.";
+MSG kInvalidBlendFunction = "Invalid blend function.";
+MSG kInvalidBlendStateForYUV = "Blending must be disabled when writing to YUV framebuffers.";
+MSG kInvalidBooleanValue = "Invalid boolean value. Must be GL_FALSE or GL_TRUE.";
+MSG kInvalidBorder = "Border must be 0.";
+MSG kInvalidBufferName = "name is not a valid buffer.";
+MSG kInvalidBufferTypes = "Invalid buffer target.";
+MSG kInvalidBufferUsage = "Invalid buffer usage enum.";
+MSG kInvalidBufferUsageFlags = "Invalid buffer usage flags.";
+MSG kInvalidClearMask = "Invalid mask bits.";
+MSG kInvalidClientState = "Invalid client vertex array type.";
+MSG kInvalidClipPlane = "Invalid clip plane.";
+MSG kInvalidColorMaskForYUV = "Red, green and blue color writes must be enabled when writing to YUV framebuffers.";
+MSG kInvalidCombinedImageUnit = "Specified unit must be in [GL_TEXTURE0, GL_TEXTURE0 + GL_MAX_COMBINED_IMAGE_UNITS)";
+MSG kInvalidComponents = "Invalid components.";
+MSG kInvalidCompressedFormat = "Not a valid compressed texture format.";
+MSG kInvalidCompressedImageSize = "Invalid compressed image size.";
+MSG kInvalidCompressedRegionSize = "Invalid region for compressed texture format.";
+MSG kInvalidConstantColor = "CONSTANT_COLOR (or ONE_MINUS_CONSTANT_COLOR) and CONSTANT_ALPHA (or ONE_MINUS_CONSTANT_ALPHA) cannot be used together as source and destination color factors in the blend function.";
+MSG kInvalidCopyCombination = "Invalid copy texture format combination.";
+MSG kInvalidCoverageComponents = "components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE.";
+MSG kInvalidCoverMode = "Invalid cover mode.";
+MSG kInvalidExternalCreateFlags = "Create flags must only include bits defined by GL_ANGLE_external_objects_flags";
+MSG kInvalidCullMode = "Cull mode not recognized.";
+MSG kInvalidDebugSeverity = "Invalid debug severity.";
+MSG kInvalidDebugSource = "Invalid debug source.";
+MSG kInvalidDebugSourceType = "If count is greater than zero, source and type cannot be GL_DONT_CARE.";
+MSG kInvalidDebugType = "Invalid debug type.";
+MSG kInvalidDefaultReadBuffer = "Read buffer must be GL_NONE or GL_BACK when reading from the default framebuffer.";
+MSG kInvalidDepthEnum = "Invalid depth enum.";
+MSG kInvalidDepthRange = "Near value cannot be greater than far.";
+MSG kInvalidDepthStencilDrawBuffer = "Draw buffer must be zero when using depth or stencil.";
+MSG kInvalidDestinationTexture = "Destination texture is not a valid texture object.";
+MSG kInvalidDestinationTextureType = "Invalid destination texture type.";
+MSG kInvalidDrawBuffer = "Invalid draw buffer.";
+MSG kInvalidDrawBufferCountForDefault = "The default framebuffer must have exactly one draw buffer.";
+MSG kInvalidDrawBufferValue = "Ith value does not match COLOR_ATTACHMENTi or NONE.";
+MSG kInvalidDrawMode = "Invalid draw mode.";
+MSG kInvalidDrawModeTransformFeedback = "Draw mode must match current transform feedback object's draw mode.";
+MSG kInvalidEGLImage = "EGL image is not valid.";
+MSG kInvalidElementRange = "Invalid element range.";
+MSG kInvalidEmulatedFormat = "Implementation format is emulated.";
+MSG kInvalidFence = "Invalid fence object.";
+MSG kInvalidFenceCondition = "Invalid value for condition.";
+MSG kInvalidFenceState = "Fence must be set.";
+MSG kInvalidFillMode = "Invalid fill mode.";
+MSG kInvalidFilterTexture = "Texture only supports NEAREST and LINEAR filtering.";
+MSG kInvalidFlags = "Invalid value for flags.";
+MSG kInvalidFlushOutOfRange = "Flushed range does not fit into buffer mapping dimensions.";
+MSG kInvalidFlushTarget = "Attempted to flush a buffer not mapped for explicit flushing.";
+MSG kInvalidFlushZero = "Attempted to flush buffer object zero.";
+MSG kInvalidFogDensity = "Invalid fog density (must be nonnegative).";
+MSG kInvalidFogMode = "Invalid fog mode.";
+MSG kInvalidFogParameter = "Invalid fog parameter.";
+MSG kInvalidFormat = "Invalid format.";
+MSG kInvalidFormatCombination = "Invalid combination of format, type and internalFormat.";
+MSG kInvalidFragmentInputBinding = "No such binding.";
+MSG kInvalidFramebufferAttachmentParameter = "Invalid parameter name for framebuffer attachment.";
+MSG kInvalidFramebufferLayer = "Framebuffer layer cannot be less than 0 or greater than GL_MAX_FRAMEBUFFER_LAYERS_EXT.";
+MSG kInvalidFramebufferName = "name is not a valid framebuffer.";
+MSG kInvalidFramebufferTarget = "Invalid framebuffer target.";
+MSG kInvalidFramebufferTextureLevel = "Mipmap level must be 0 when attaching a texture.";
+MSG kInvalidHandleType = "Invalid handle type.";
+MSG kInvalidImageAccess = "access is not one of the supported tokens.";
+MSG kInvalidImageLayout = "Invalid image layout.";
+MSG kInvalidImageFormat = "format is not one of supported image unit formats.";
+MSG kInvalidIndentifier = "Invalid identifier.";
+MSG kInvalidIndirectOffset = "indirect must be a multiple of the size of uint in basic machine units.";
+MSG kInvalidInternalFormat = "Invalid internal format 0x%04X.";
+MSG kInvalidLight = "Invalid light.";
+MSG kInvalidLightModelParameter = "Invalid light model parameter.";
+MSG kInvalidLightParameter = "Invalid light parameter.";
+MSG kInvalidLogicOp = "Invalid logical operation.";
+MSG kInvalidMapPointerQuery = "GL_BUFFER_MAP_POINTER can only be queried with GetBufferPointerv.";
+MSG kInvalidMaterialFace = "Invalid material face.";
+MSG kInvalidMaterialParameter = "Invalid material parameter.";
+MSG kInvalidMatrixMode = "Invalid matrix mode.";
+MSG kInvalidMemoryBarrierBit = "Invalid memory barrier bit.";
+MSG kInvalidMemoryObject = "Invalid memory object.";
+MSG kInvalidMemoryObjectParameter = "Invalid memory object parameter.";
+MSG kInvalidMipLevel = "Level of detail outside of range.";
+MSG kInvalidMipLevels = "Invalid level count.";
+MSG kInvalidMultisampledFramebufferOperation = "Invalid operation on multisampled framebuffer";
+MSG kInvalidMultitextureUnit = "Specified unit must be in [GL_TEXTURE0, GL_TEXTURE0 + GL_MAX_TEXTURE_UNITS)";
+MSG kInvalidName = "Invalid name.";
+MSG kInvalidNameCharacters = "Name contains invalid characters.";
+MSG kInvalidOriginEnum = "Invalid origin enum.";
+MSG kInvalidPackParametersForWebGL = "Invalid combination of pack parameters for WebGL.";
+MSG kInvalidPerfMonitor = "Invalid perf monitor.";
+MSG kInvalidPerfMonitorCounter = "Invalid perf monitor counter.";
+MSG kInvalidPerfMonitorGroup = "Invalid perf monitor counter group.";
+MSG kInvalidPname = "Invalid pname.";
+MSG kInvalidPointerQuery = "Invalid pointer query.";
+MSG kInvalidPointParameter = "Invalid point parameter.";
+MSG kInvalidPointParameterValue = "Invalid point parameter value (must be non-negative).";
+MSG kInvalidPointSizeValue = "Invalid point size (must be positive).";
+MSG kInvalidPrecision = "Invalid or unsupported precision type.";
+MSG kInvalidPrimitiveMode = "Invalid primitive mode.";
+MSG kInvalidProgramBinaryFormat = "Program binary format is not valid.";
+MSG kInvalidProgramInterface = "Invalid program interface.";
+MSG kInvalidProgramName = "Program object expected.";
+MSG kInvalidProgramPipelineName = "name is not a valid program pipeline.";
+MSG kInvalidProgramResourceIndex = "Invalid program resource index.";
+MSG kInvalidProgramResourceProperty = "Invalid program resource property.";
+MSG kInvalidProjectionMatrix = "Invalid projection matrix. Left/right, top/bottom, near/far intervals cannot be zero, and near/far cannot be less than zero.";
+MSG kInvalidPropCount = "Invalid propCount.";
+MSG kInvalidPropertyForProgramInterface = "Not an allowed program resource property for this program interface";
+MSG kInvalidProvokingVertex = "Invalid provoking vertex.";
+MSG kInvalidQueryId = "Invalid query Id.";
+MSG kInvalidQueryName = "name is not a valid query.";
+MSG kInvalidQueryTarget = "Invalid query target.";
+MSG kInvalidQueryType = "Invalid query type.";
+MSG kInvalidRange = "Invalid range.";
+MSG kInvalidReadBuffer = "Invalid read buffer";
+MSG kInvalidRenderbufferInternalFormat = "Invalid renderbuffer internalformat.";
+MSG kInvalidRenderbufferName = "name is not a valid renderbuffer.";
+MSG kInvalidRenderbufferTarget = "Invalid renderbuffer target.";
+MSG kInvalidRenderbufferTextureParameter = "Invalid parameter name for renderbuffer attachment.";
+MSG kInvalidRenderbufferWidthHeight = "Renderbuffer width and height cannot be negative and cannot exceed maximum texture size.";
+MSG kInvalidResetStatus = "Reset status is not valid";
+MSG kInvalidSampleMaskNumber = "MaskNumber cannot be greater than or equal to the value of MAX_SAMPLE_MASK_WORDS.";
+MSG kInvalidSampler = "Sampler is not valid";
+MSG kInvalidSamplerName = "name is not a valid sampler.";
+MSG kInvalidShaderBinaryFormat = "Invalid shader binary format.";
+MSG kInvalidShaderName = "Shader object expected.";
+MSG kInvalidShaderType = "Invalid shader type.";
+MSG kInvalidShadingModel = "Invalid shading model.";
+MSG kInvalidShadingRate = "Invalid shading rate.";
+MSG kInvalidSourceTexture = "Source texture is not a valid texture object.";
+MSG kInvalidSourceTextureInternalFormat = "Source texture internal format is invalid.";
+MSG kInvalidSourceTextureLevel = "Invalid source texture level.";
+MSG kInvalidSourceTextureSize = "Invalid source texture height or width.";
+MSG kInvalidSourceTextureType = "Source texture must be a valid texture type.";
+MSG kInvalidStencil = "Invalid stencil.";
+MSG kInvalidStencilBitMask = "Invalid stencil bit mask.";
+MSG kInvalidSyncPointer = "Not a valid sync pointer.";
+MSG kInvalidTarget = "Invalid target.";
+MSG kInvalidTextureCombine = "Invalid texture combine mode.";
+MSG kInvalidTextureCombineOp = "Invalid texture combine operand.";
+MSG kInvalidTextureCombineSrc = "Invalid texture combine source.";
+MSG kInvalidTextureEnvMode = "Invalid texture environment mode.";
+MSG kInvalidTextureEnvParameter = "Invalid texture environment parameter.";
+MSG kInvalidTextureEnvScale = "Invalid texture environment scale.";
+MSG kInvalidTextureEnvTarget = "Invalid texture environment target.";
+MSG kInvalidTextureFilterParam = "Texture filter not recognized.";
+MSG kInvalidTextureLevel = "Texture level does not exist.";
+MSG kInvalidTextureName = "Not a valid texture object name.";
+MSG kInvalidTextureRange = "Cannot be less than 0 or greater than maximum number of textures.";
+MSG kInvalidTextureTarget = "Invalid or unsupported texture target.";
+MSG kInvalidTextureType = "Texture has incompatible target.";
+MSG kInvalidTextureWrap = "Texture wrap mode not recognized.";
+MSG kInvalidTimeout = "Invalid value for timeout.";
+MSG kInvalidTransformation = "Invalid transformation.";
+MSG kInvalidTransformFeedbackAttribsCount = "Count exceeds MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS.";
+MSG kInvalidTransformFeedbackName = "name is not a valid transform feedback.";
+MSG kInvalidType = "Invalid type.";
+MSG kInvalidUniformCount = "Only array uniforms may have count > 1.";
+MSG kInvalidUniformLocation = "Invalid uniform location";
+MSG kInvalidUnpackAlignment = "Unpack alignment must be 1, 2, 4 or 8.";
+MSG kInvalidUnpackParametersForWebGL = "Invalid combination of unpack parameters for WebGL.";
+MSG kInvalidExternalUsageFlags = "Usage flags must only include bits defined by GL_ANGLE_external_objects_flags";
+MSG kInvalidValueExceedsMaxPatchSize = "Value must be less than or equal to MAX_PATCH_SIZE.";
+MSG kInvalidValueNonPositive = "Value must be greater than zero.";
+MSG kInvalidVaryingLocation = "Location exceeds max varying.";
+MSG kInvalidVertexArray = "Vertex array does not exist.";
+MSG kInvalidVertexArrayName = "name is not a valid vertex array.";
+MSG kInvalidVertexAttribSize2101010 = "Type is INT_2_10_10_10_REV or UNSIGNED_INT_2_10_10_10_REV and size is not 4.";
+MSG kInvalidVertexAttribSize1010102 = "Type is INT_10_10_10_2_OES or UNSIGNED_INT_10_10_10_2_OES and size is not 3 or 4.";
+MSG kInvalidVertexAttrSize = "Vertex attribute size must be 1, 2, 3, or 4.";
+MSG kInvalidVertexPointerSize = "Size for built-in vertex attribute is outside allowed range.";
+MSG kInvalidVertexPointerStride = "Invalid stride for built-in vertex attribute.";
+MSG kInvalidVertexPointerType = "Invalid type for built-in vertex attribute.";
+MSG kInvalidWidth = "Invalid width.";
+MSG kInvalidWrapModeTexture = "Invalid wrap mode for texture type.";
+MSG kInvalidZOffset = "zoffset is larger than MAX_3D_TEXTURE_SIZE-1";
+MSG kLengthZero = "Length must not be zero.";
+MSG kLevelNotZero = "Texture level must be zero.";
+MSG kLightParameterOutOfRange = "Light parameter out of range.";
+MSG kMapOutOfRange = "Mapped range does not fit into buffer dimensions.";
+MSG kMaterialParameterOutOfRange = "Material parameter out of range.";
+MSG kMatrixStackOverflow = "Current matrix stack is full.";
+MSG kMatrixStackUnderflow = "Current matrix stack has only a single matrix.";
+MSG kMaxActiveVariablesInterface = "MAX_NUM_ACTIVE_VARIABLES requires a buffer or block interface.";
+MSG kMismatchedFormat = "Format must match internal format.";
+MSG kMismatchedTargetAndFormat = "Invalid texture target and format combination.";
+MSG kMismatchedTypeAndFormat = "Invalid format and type combination.";
+MSG kMismatchedVariableProgram = "Variable is not part of the current program.";
+MSG kMissingName = "No name given.";
+MSG kMissingReadAttachment = "Missing read attachment.";
+MSG kMissingTexture = "No Texture is bound to the specified target.";
+MSG kMissingTextureName = "texture is not the name of an existing texture object.";
+MSG kMultisampleArrayExtensionRequired = "GL_ANGLE_texture_multisample_array not enabled.";
+MSG kMultisampleTextureExtensionOrES31Required = "GL_ANGLE_texture_multisample or GLES 3.1 required.";
+MSG kMultisampleTextureExtensionOrGetTexLevelParameterExtensionOrES31Required = "GL_ANGLE_texture_multisample, GL_ANGLE_get_tex_level_parameter or GLES 3.1 required.";
+MSG kMultiviewActive = "The number of views in the active draw framebuffer is greater than 1.";
+MSG kMultiviewMismatch = "The number of views in the active program and draw framebuffer does not match.";
+MSG kMultiviewNotAvailable = "ANGLE_multiview is not available.";
+MSG kMultiviewReadFramebuffer = "The active read framebuffer object has multiview attachments.";
+MSG kMultiviewTimerQuery = "There is an active query for target GL_TIME_ELAPSED_EXT when the number of views in the active draw framebuffer is greater than 1.";
+MSG kMultiviewTransformFeedback = "There is an active transform feedback object when the number of views in the active draw framebuffer is greater than 1.";
+MSG kMultiviewViewsTooLarge = "numViews cannot be greater than GL_MAX_VIEWS_ANGLE.";
+MSG kMultiviewViewsTooSmall = "numViews cannot be less than 1.";
+MSG kMustHaveElementArrayBinding = "Must have element array buffer bound.";
+MSG kNameBeginsWithGL = "Attributes that begin with 'gl_' are not allowed.";
+MSG kNegativeAttachments = "Negative number of attachments.";
+MSG kNegativeBaseViewIndex = "Negative baseViewIndex.";
+MSG kNegativeBufferSize = "Negative buffer size.";
+MSG kNegativeBufSize = "Invalid bufSize.";
+MSG kNegativeCount = "Negative count.";
+MSG kNegativeHeightWidthDepth = "Cannot have negative height, width, or depth.";
+MSG kNegativeLayer = "Negative layer.";
+MSG kNegativeLength = "Negative length.";
+MSG kNegativeLevel = "Level is negative.";
+MSG kNegativeLocation = "Location cannot be less than 0.";
+MSG kNegativeMaxCount = "Negative maxcount.";
+MSG kNegativeOffset = "Negative offset.";
+MSG kNegativeParam = "param is negative.";
+MSG kNegativePrimcount = "Primcount must be greater than or equal to zero.";
+MSG kNegativeSize = "Negative size.";
+MSG kNegativeStart = "Cannot have negative start.";
+MSG kNegativeStride = "Cannot have negative stride.";
+MSG kNegativeXYZ = "x = y = or z cannot be negative.";
+MSG kNoActiveComputeShaderStage = "No active compute shader stage in this program.";
+MSG kNoActiveGeometryShaderStage = "No active geometry shader stage in this program.";
+MSG kNoActiveGraphicsShaderStage = "It is a undefined behaviour to render without vertex shader stage or fragment shader stage.";
+MSG kNoActiveProgramWithComputeShader = "No active program for the compute shader stage.";
+MSG kNoDefinedClearConversion = "No defined conversion between clear value and attachment format.";
+MSG kNonPositiveDrawTextureDimension = "Both width and height argument of drawn texture must be positive.";
+MSG kNonPositiveSize = "Size must be greater than 0";
+MSG kNoProgramBinaryFormats = "No program binary formats supported.";
+MSG kNoReadFramebuffer = "No active read framebuffer.";
+MSG kNoSampleAlphaToCoveragesLimitation = "Current renderer doesn't support alpha-to-coverage.";
+MSG kNotTextureComplete = "The texture is not complete.";
+MSG kNoTransformArray = "No transform array given.";
+MSG kNoTransformFeedbackOutputVariables = "The active program has specified no output variables to record.";
+MSG kNoZeroDivisor = "At least one enabled attribute must have a divisor of zero.";
+MSG kNVFenceNotSupported = "GL_NV_fence is not supported";
+MSG kObjectNotGenerated = "Object cannot be used because it has not been generated.";
+MSG kOffsetAlignment = "offset must be a multiple of 4.";
+MSG kOffsetAndSizeAlignment = "Offset and size must be multiple of 4.";
+MSG kOffsetMustBeMultipleOfType = "Offset must be a multiple of the passed in datatype.";
+MSG kOffsetMustBeMultipleOfUint = "Offset must be a multiple of sizeof(uint) in basic machine units.";
+MSG kOffsetOverflow = "Offset overflows texture dimensions.";
+MSG kOtherQueryActive = "Other query is active.";
+MSG kOutsideOfBounds = "Parameter outside of bounds.";
+MSG kParamOverflow = "The provided parameters overflow with the provided buffer.";
+MSG kPixelDataNotNull = "Pixel data must be null.";
+MSG kPixelDataNull = "Pixel data cannot be null.";
+MSG kPixelPackBufferBoundForTransformFeedback = "It is undefined behavior to use a pixel pack buffer that is bound for transform feedback.";
+MSG kPixelUnpackBufferBoundForTransformFeedback = "It is undefined behavior to use a pixel unpack buffer that is bound for transform feedback.";
+MSG kPLSActive = "Operation not permitted while pixel local storage is active.";
+MSG kPLSDefaultFramebufferBound = "Default framebuffer object name 0 does not support pixel local storage.";
+MSG kPLSDitherEnabled = "Attempted to begin pixel local storage with GL_DITHER enabled.";
+MSG kPLSDimensionsDontMatchRenderingArea = "Pixel local storage backing texture dimensions not equal to the rendering area.";
+MSG kPLSEnablingDeinitializedPlane = "Attempted to enable a pixel local storage plane that is in a deinitialized state.";
+MSG kPLSExtensionNotEnabled = "GL_ANGLE_shader_pixel_local_storage not enabled.";
+MSG kPLSInactive = "Pixel local storage is not active.";
+MSG kPLSInvalidInternalformat = "Invalid pixel local storage internal format.";
+MSG kPLSInvalidLoadOperation = "Invalid pixel local storage Load Operation.";
+MSG kPLSInvalidTextureType = "Invalid pixel local storage texture type.";
+MSG kPLSKeepingMemorylessPlane = "Load Operation GL_KEEP is invalid for memoryless planes.";
+MSG kPLSMaxColorAttachmentsExceded = "Framebuffer cannot have images attached to color attachment points on or after COLOR_ATTACHMENT0 + MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE_ANGLE.";
+MSG kPLSMaxCombinedDrawBuffersAndPlanesExceded = "Framebuffer cannot have images attached to color attachment points on or after COLOR_ATTACHMENT0 + MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES_ANGLE - <planes>.";
+MSG kPLSMismatchedBackingTextureSizes = "Mismatched pixel local storage backing texture sizes.";
+MSG kPLSMultisamplingEnabled = "Attempted to begin pixel local storage with a multisampled framebuffer.";
+MSG kPLSNoAttachmentsNoTextureBacked = "Draw framebuffer has no attachments and no enabled, texture-backed pixel local storage planes.";
+MSG kPLSNullClearData = "cleardata cannot null if Load Operation GL_CLEAR_ANGLE is specified.";
+MSG kPLSNullLoadOps = "loadops cannot null.";
+MSG kPLSPlaneLessThanZero = "Plane cannot be less than 0.";
+MSG kPLSPlaneOutOfRange = "Plane must be less than GL_MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE.";
+MSG kPLSPlanesLessThanOne = "Planes must be greater than 0.";
+MSG kPLSPlanesOutOfRange = "Planes must be less than or equal to GL_MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE.";
+MSG kPLSRasterizerDiscardEnabled = "Attempted to begin pixel local storage with GL_RASTERIZER_DISCARD enabled.";
+MSG kPLSReservedDrawBufferInUse = "When beginning pixel local storage, glDrawBuffers must all be GL_NONE at indices greater than or equal to: min(GL_MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PLS_ANGLE, GL_MAX_COMBINED_DRAW_BUFFERS_AND_PLS_PLANES_ANGLE - <planes>).";
+MSG kPLSSampleAlphaToCoverageEnabled = "Attempted to begin pixel local storage with GL_SAMPLE_ALPHA_TO_COVERAGE enabled.";
+MSG kPLSSampleCoverageEnabled = "Attempted to begin pixel local storage with GL_SAMPLE_COVERAGE enabled.";
+MSG kPointSizeArrayExtensionNotEnabled = "GL_OES_point_size_array not enabled.";
+MSG kProgramDoesNotExist = "Program doesn't exist.";
+MSG kProgramInterfaceMustBeProgramOutput = "programInterface must be set to GL_PROGRAM_OUTPUT.";
+MSG kProgramNotBound = "A program must be bound.";
+MSG kProgramNotLinked = "Program not linked.";
+MSG kQueryActive = "Query is active.";
+MSG kQueryExtensionNotEnabled = "Query extension not enabled.";
+MSG kQueryInactive = "Query is not active.";
+MSG kQueryTargetMismatch = "Query type does not match target.";
+MSG kReadBufferNone = "Read buffer is GL_NONE.";
+MSG kReadBufferNotAttached = "Read buffer has no attachment.";
+MSG kRectangleTextureCompressed = "Rectangle texture cannot have a compressed format.";
+MSG kRelativeOffsetTooLarge = "relativeOffset cannot be greater than MAX_VERTEX_ATTRIB_RELATIVE_OFFSET.";
+MSG kRenderableInternalFormat = "SizedInternalformat must be color-renderable, depth-renderable, or stencil-renderable.";
+MSG kRenderbufferNotBound = "A renderbuffer must be bound.";
+MSG kResourceMaxRenderbufferSize = "Desired resource size is greater than max renderbuffer size.";
+MSG kResourceMaxTextureSize = "Desired resource size is greater than max texture size.";
+MSG kRobustResourceInitializationExtensionRequired = "EGL_ANGLE_robust_resource_initialization not enabled.";
+MSG kSamplerFormatMismatch = "Mismatch between texture format and sampler type (signed/unsigned/float/shadow).";
+MSG kSamplerUniformValueOutOfRange = "Sampler uniform value out of range.";
+MSG kSamplesOutOfRange = "Samples must not be greater than maximum supported value for the format.";
+MSG kSamplesZero = "Samples may not be zero.";
+MSG kShaderAttachmentHasShader = "Shader attachment already has a shader.";
+MSG kShaderSourceInvalidCharacters = "Shader source contains invalid characters.";
+MSG kShaderStorageBufferOffsetAlignment = "Offset must be multiple of value of SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT.";
+MSG kShaderToDetachMustBeAttached = "Shader to be detached must be currently attached to the program.";
+MSG kShadingRateExtensionNotAvailable = "GL_QCOM_shading_rate extension not available.";
+MSG kSourceLevelNotDefined = "The source level of the source texture must be defined.";
+MSG kSourceTextureLevelZeroDefined = "Source texture must level 0 defined.";
+MSG kSourceTextureMustBeCompressed = "Source texture must have a compressed internal format.";
+MSG kSourceTextureTooSmall = "The specified dimensions are outside of the bounds of the texture.";
+MSG kStencilReferenceMaskOrMismatch = "Stencil reference and mask values must be the same for front facing and back facing triangles.";
+MSG kStrideExceedsWebGLLimit = "Stride is over the maximum stride allowed by WebGL.";
+MSG kStrideMustBeMultipleOfType = "Stride must be a multiple of the passed in datatype.";
+MSG kSyncMissing = "Sync object does not exist.";
+MSG kTargetMustBeTexture2DMultisampleArrayOES = "Target must be TEXTURE_2D_MULTISAMPLE_ARRAY_OES.";
+MSG kTessellationShaderExtensionNotEnabled = "GL_EXT_tessellation_shader extension not enabled.";
+MSG kTessellationShaderRequiresBothControlAndEvaluation = "Tessellation requires both control and evaluation shaders.";
+MSG kTessellationShaderRequiresVertexShader = "Any command that transfers vertices to the GL requires a vertex shader if the current program uses a tessellation shader.";
+MSG kTextureBufferExtensionNotAvailable = "Texture buffer extension not available.";
+MSG kTextureBufferOffsetAlignment = "Offset must be multiple of value of TEXTURE_BUFFER_OFFSET_ALIGNMENT.";
+MSG kTextureBufferSize = "Texture buffer size must be a positive integer.";
+MSG kTextureBufferSizeOffset = "Texture buffer offset + size must be less than or equal to BUFFER_SIZE.";
+MSG kTextureBufferTarget = "Target must be TEXTURE_BUFFER.";
+MSG kTextureBufferInternalFormat = "Internal format is not an accepted sized internal format.";
+MSG kTextureBufferInvalidBuffer = "If buffer is nonzero, it must match the name of an existing buffer object.";
+MSG kTextureFormatMismatch = "Passed in texture target and format must match the one originally used to define the texture.";
+MSG kTextureIsImmutable = "Texture is immutable.";
+MSG kTextureIsNotImmutable = "Texture is not immutable.";
+MSG kTextureIsNeitherImmutableNorTextureBuffer = "Texture is not the name of an immutable texture object or a buffer texture.";
+MSG kTextureLayerOutOfRange = "Layer is larger than texture depth.";
+MSG kTextureLevelOutOfRange = "Level is larger than texture level count.";
+MSG kTextureNotBound = "A texture must be bound.";
+MSG kTextureNotPow2 = "The texture is a non-power-of-two texture.";
+MSG kTextureRectangleNotSupported = "Context does not support GL_ANGLE_texture_rectangle";
+MSG kTextureSizeTooSmall = "Texture dimensions must all be greater than zero.";
+MSG kTextureTargetMismatch = "Textarget must match the texture target type.";
+MSG kTextureTargetMismatchWithLabel = "Textarget must match the texture target type. Requested: %d Texture's: %d label: %s";
+MSG kTextureTargetRequiresES31 = "Texture target requires at least OpenGL ES 3.1.";
+MSG kTextureTypeConflict = "Two textures of different types use the same sampler location.";
+MSG kTextureTypeMismatch = "Passed in texture type must match the one originally used to define the texture.";
+MSG kTextureWidthOrHeightOutOfRange = "Width and height must be less than or equal to GL_MAX_TEXTURE_SIZE.";
+MSG kTextureDepthOutOfRange = "Depth must be less than or equal to MAX_ARRAY_TEXTURE_LAYERS";
+MSG kTransfomFeedbackAlreadyActive = "Transform feedback is already active.";
+MSG kTransformFeedbackActiveDelete = "Attempt to delete an active transform feedback.";
+MSG kTransformFeedbackActiveDuringLink = "Cannot link program while program is associated with an active transform feedback object.";
+MSG kTransformFeedbackBufferDoubleBound = "A transform feedback buffer that would be written to is also bound to a non-transform-feedback target, which would cause undefined behavior.";
+MSG kTransformFeedbackBufferMissing = "Every binding point used in transform feedback mode must have a buffer object bound.";
+MSG kTransformFeedbackBufferMultipleOutputs = "Transform feedback has a buffer bound to multiple outputs.";
+MSG kTransformFeedbackBufferTooSmall = "Not enough space in bound transform feedback buffers.";
+MSG kTransformFeedbackDoesNotExist = "Transform feedback object that does not exist.";
+MSG kTransformFeedbackNotActive = "No Transform Feedback object is active.";
+MSG kTransformFeedbackNotPaused = "The active Transform Feedback object is not paused.";
+MSG kTransformFeedbackPaused = "The active Transform Feedback object is paused.";
+MSG kTransformFeedbackProgramBinary = "Cannot change program binary while program is associated with an active transform feedback object.";
+MSG kTransformFeedbackTargetActive = "Target is TRANSFORM_FEEDBACK_BUFFER and transform feedback is currently active.";
+MSG kTransformFeedbackUseProgram = "Cannot change active program while transform feedback is unpaused.";
+MSG kTransformFeedbackVaryingIndexOutOfRange = "Index must be less than the transform feedback varying count in the program.";
+MSG kTypeNotUnsignedShortByte = "Only UNSIGNED_SHORT and UNSIGNED_BYTE types are supported.";
+MSG kUniformBufferBoundForTransformFeedback = "It is undefined behavior to use an uniform buffer that is bound for transform feedback.";
+MSG kUniformBufferOffsetAlignment = "Offset must be multiple of value of UNIFORM_BUFFER_OFFSET_ALIGNMENT.";
+MSG kUniformBufferTooSmall = "It is undefined behaviour to use a uniform buffer that is too small.";
+MSG kUniformBufferUnbound = "It is undefined behaviour to have a used but unbound uniform buffer.";
+MSG kUniformSizeMismatch = "Uniform size does not match uniform method.";
+MSG kUniformTypeMismatch = "Uniform type does not match uniform method.";
+MSG kUnimplementedComputeShaderPrecision = "Compute shader precision not yet implemented.";
+MSG kUnknownParameter = "Unknown parameter value.";
+MSG kUnsizedInternalFormatUnsupported = "Internalformat is one of the unsupported unsized base internalformats.";
+MSG kUnsupportedDrawModeForTransformFeedback = "The draw command is unsupported when transform feedback is active and not paused.";
+MSG kUnsupportedFloatBlending = "GL_BLEND with floating-point color attachments requires the EXT_float_blend extension.";
+MSG kVertexArrayNoBuffer = "An enabled vertex array has no buffer.";
+MSG kVertexArrayNoBufferPointer = "An enabled vertex array has no buffer and no pointer.";
+MSG kVertexBufferBoundForTransformFeedback = "It is undefined behavior to use a vertex buffer that is bound for transform feedback.";
+MSG kVertexShaderTypeMismatch = "Vertex shader input type does not match the type of the bound vertex attribute.";
+MSG kViewportNegativeSize = "Viewport size cannot be negative.";
+MSG kViewsExceedMaxArrayLayers = "baseViewIndex+numViews cannot be greater than GL_MAX_ARRAY_TEXTURE_LAYERS.";
+MSG kWebgl2NameLengthLimitExceeded = "Location lengths must not be greater than 1024 characters.";
+MSG kWebglBindAttribLocationReservedPrefix = "Attributes that begin with 'webgl_', or '_webgl_' are not allowed.";
+MSG kWebglNameLengthLimitExceeded = "Location name lengths must not be greater than 256 characters.";
+MSG kYUVOutputMissmatch = "Program and framebuffer YUV output state does not match.";
+MSG kYUVTargetExtensionRequired = "GL_EXT_YUV_target not enabled.";
+MSG kZeroBoundToTarget = "Zero is bound to target.";
+MSG kUnrecognizedShaderStageBit = "Unrecognized shader stage bit.";
+MSG kProgramNotSeparable = "Program object was not linked with its PROGRAM_SEPARABLE status set.";
+MSG kProgramPipelineDoesNotExist = "Program pipeline does not exist.";
+MSG kNotAllStagesOfSeparableProgramUsed = "A program object is active for at least one, but not all of the shader stages that were present when the program was linked.";
+MSG kNoExecutableCodeInstalled = "There is no current program object specified by UseProgram, there is a current program pipeline object, and that object is empty (no executable code is installed for any stage).";
+MSG kProgramPipelineLinkFailed = "Program pipeline link failed";
+MSG kProtectedTexturesExtensionRequired = "GL_EXT_protected_textures not enabled.";
+
+// clang-format on
+
+#undef MSG
+} // namespace err
+} // namespace gl
+#endif // LIBANGLE_ERRORSTRINGS_H_
diff --git a/gfx/angle/checkout/src/libANGLE/Fence.cpp b/gfx/angle/checkout/src/libANGLE/Fence.cpp
new file mode 100644
index 0000000000..af173dff29
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Fence.cpp
@@ -0,0 +1,124 @@
+//
+// Copyright 2002 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.
+//
+
+// Fence.cpp: Implements the gl::FenceNV and gl::Sync classes.
+
+#include "libANGLE/Fence.h"
+
+#include "angle_gl.h"
+
+#include "common/utilities.h"
+#include "libANGLE/renderer/FenceNVImpl.h"
+#include "libANGLE/renderer/GLImplFactory.h"
+#include "libANGLE/renderer/SyncImpl.h"
+
+namespace gl
+{
+
+FenceNV::FenceNV(rx::GLImplFactory *factory)
+ : mFence(factory->createFenceNV()), mIsSet(false), mStatus(GL_FALSE), mCondition(GL_NONE)
+{}
+
+FenceNV::~FenceNV()
+{
+ SafeDelete(mFence);
+}
+
+void FenceNV::onDestroy(const gl::Context *context)
+{
+ mFence->onDestroy(context);
+}
+
+angle::Result FenceNV::set(const Context *context, GLenum condition)
+{
+ ANGLE_TRY(mFence->set(context, condition));
+
+ mCondition = condition;
+ mStatus = GL_FALSE;
+ mIsSet = true;
+
+ return angle::Result::Continue;
+}
+
+angle::Result FenceNV::test(const Context *context, GLboolean *outResult)
+{
+ // Flush the command buffer by default
+ ANGLE_TRY(mFence->test(context, &mStatus));
+
+ *outResult = mStatus;
+ return angle::Result::Continue;
+}
+
+angle::Result FenceNV::finish(const Context *context)
+{
+ ASSERT(mIsSet);
+
+ ANGLE_TRY(mFence->finish(context));
+
+ mStatus = GL_TRUE;
+
+ return angle::Result::Continue;
+}
+
+Sync::Sync(rx::GLImplFactory *factory, GLuint id)
+ : RefCountObject(factory->generateSerial(), id),
+ mFence(factory->createSync()),
+ mLabel(),
+ mCondition(GL_SYNC_GPU_COMMANDS_COMPLETE),
+ mFlags(0)
+{}
+
+void Sync::onDestroy(const Context *context)
+{
+ ASSERT(mFence);
+ mFence->onDestroy(context);
+}
+
+Sync::~Sync()
+{
+ SafeDelete(mFence);
+}
+
+angle::Result Sync::setLabel(const Context *context, const std::string &label)
+{
+ mLabel = label;
+ return angle::Result::Continue;
+}
+
+const std::string &Sync::getLabel() const
+{
+ return mLabel;
+}
+
+angle::Result Sync::set(const Context *context, GLenum condition, GLbitfield flags)
+{
+ ANGLE_TRY(mFence->set(context, condition, flags));
+
+ mCondition = condition;
+ mFlags = flags;
+ return angle::Result::Continue;
+}
+
+angle::Result Sync::clientWait(const Context *context,
+ GLbitfield flags,
+ GLuint64 timeout,
+ GLenum *outResult)
+{
+ ASSERT(mCondition != GL_NONE);
+ return mFence->clientWait(context, flags, timeout, outResult);
+}
+
+angle::Result Sync::serverWait(const Context *context, GLbitfield flags, GLuint64 timeout)
+{
+ return mFence->serverWait(context, flags, timeout);
+}
+
+angle::Result Sync::getStatus(const Context *context, GLint *outResult) const
+{
+ return mFence->getStatus(context, outResult);
+}
+
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/Fence.h b/gfx/angle/checkout/src/libANGLE/Fence.h
new file mode 100644
index 0000000000..2852b328fd
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Fence.h
@@ -0,0 +1,88 @@
+//
+// Copyright 2002 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.
+//
+
+// Fence.h: Defines the gl::FenceNV and gl::Sync classes, which support the GL_NV_fence
+// extension and GLES3 sync objects.
+
+#ifndef LIBANGLE_FENCE_H_
+#define LIBANGLE_FENCE_H_
+
+#include "libANGLE/Debug.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/RefCountObject.h"
+
+#include "common/angleutils.h"
+
+namespace rx
+{
+class GLImplFactory;
+class FenceNVImpl;
+class SyncImpl;
+} // namespace rx
+
+namespace gl
+{
+
+class FenceNV final : angle::NonCopyable
+{
+ public:
+ explicit FenceNV(rx::GLImplFactory *factory);
+ virtual ~FenceNV();
+
+ void onDestroy(const gl::Context *context);
+ angle::Result set(const Context *context, GLenum condition);
+ angle::Result test(const Context *context, GLboolean *outResult);
+ angle::Result finish(const Context *context);
+
+ bool isSet() const { return mIsSet; }
+ GLboolean getStatus() const { return mStatus; }
+ GLenum getCondition() const { return mCondition; }
+
+ private:
+ rx::FenceNVImpl *mFence;
+
+ bool mIsSet;
+
+ GLboolean mStatus;
+ GLenum mCondition;
+};
+
+class Sync final : public RefCountObject<GLuint>, public LabeledObject
+{
+ public:
+ Sync(rx::GLImplFactory *factory, GLuint id);
+ ~Sync() override;
+
+ void onDestroy(const Context *context) override;
+
+ angle::Result setLabel(const Context *context, const std::string &label) override;
+ const std::string &getLabel() const override;
+
+ angle::Result set(const Context *context, GLenum condition, GLbitfield flags);
+ angle::Result clientWait(const Context *context,
+ GLbitfield flags,
+ GLuint64 timeout,
+ GLenum *outResult);
+ angle::Result serverWait(const Context *context, GLbitfield flags, GLuint64 timeout);
+ angle::Result getStatus(const Context *context, GLint *outResult) const;
+
+ GLenum getCondition() const { return mCondition; }
+ GLbitfield getFlags() const { return mFlags; }
+
+ rx::SyncImpl *getImplementation() const { return mFence; }
+
+ private:
+ rx::SyncImpl *mFence;
+
+ std::string mLabel;
+
+ GLenum mCondition;
+ GLbitfield mFlags;
+};
+
+} // namespace gl
+
+#endif // LIBANGLE_FENCE_H_
diff --git a/gfx/angle/checkout/src/libANGLE/Framebuffer.cpp b/gfx/angle/checkout/src/libANGLE/Framebuffer.cpp
new file mode 100644
index 0000000000..08250b0b2d
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Framebuffer.cpp
@@ -0,0 +1,2727 @@
+//
+// Copyright 2002 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.
+//
+
+// Framebuffer.cpp: Implements the gl::Framebuffer class. Implements GL framebuffer
+// objects and related functionality. [OpenGL ES 2.0.24] section 4.4 page 105.
+
+#include "libANGLE/Framebuffer.h"
+
+#include "common/Optional.h"
+#include "common/bitset_utils.h"
+#include "common/utilities.h"
+#include "libANGLE/Config.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Display.h"
+#include "libANGLE/ErrorStrings.h"
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/PixelLocalStorage.h"
+#include "libANGLE/Renderbuffer.h"
+#include "libANGLE/Surface.h"
+#include "libANGLE/Texture.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/ContextImpl.h"
+#include "libANGLE/renderer/FramebufferImpl.h"
+#include "libANGLE/renderer/GLImplFactory.h"
+#include "libANGLE/renderer/RenderbufferImpl.h"
+#include "libANGLE/renderer/SurfaceImpl.h"
+
+using namespace angle;
+
+namespace gl
+{
+
+namespace
+{
+
+// Check the |checkAttachment| in reference to |firstAttachment| for the sake of multiview
+// framebuffer completeness.
+FramebufferStatus CheckMultiviewStateMatchesForCompleteness(
+ const FramebufferAttachment *firstAttachment,
+ const FramebufferAttachment *checkAttachment)
+{
+ ASSERT(firstAttachment && checkAttachment);
+ ASSERT(firstAttachment->isAttached() && checkAttachment->isAttached());
+
+ if (firstAttachment->isMultiview() != checkAttachment->isMultiview())
+ {
+ return FramebufferStatus::Incomplete(GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR,
+ err::kFramebufferIncompleteMultiviewMismatch);
+ }
+ if (firstAttachment->getNumViews() != checkAttachment->getNumViews())
+ {
+ return FramebufferStatus::Incomplete(GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR,
+ err::kFramebufferIncompleteMultiviewViewsMismatch);
+ }
+ if (checkAttachment->getBaseViewIndex() + checkAttachment->getNumViews() >
+ checkAttachment->getSize().depth)
+ {
+ return FramebufferStatus::Incomplete(GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR,
+ err::kFramebufferIncompleteMultiviewBaseViewMismatch);
+ }
+
+ return FramebufferStatus::Complete();
+}
+
+FramebufferStatus CheckAttachmentCompleteness(const Context *context,
+ const FramebufferAttachment &attachment)
+{
+ ASSERT(attachment.isAttached());
+
+ const Extents &size = attachment.getSize();
+ if (size.width == 0 || size.height == 0)
+ {
+ return FramebufferStatus::Incomplete(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
+ err::kFramebufferIncompleteAttachmentZeroSize);
+ }
+
+ if (!attachment.isRenderable(context))
+ {
+ return FramebufferStatus::Incomplete(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
+ err::kFramebufferIncompleteAttachmentNotRenderable);
+ }
+
+ if (attachment.type() == GL_TEXTURE)
+ {
+ // [EXT_geometry_shader] Section 9.4.1, "Framebuffer Completeness"
+ // If <image> is a three-dimensional texture or a two-dimensional array texture and the
+ // attachment is not layered, the selected layer is less than the depth or layer count,
+ // respectively, of the texture.
+ if (!attachment.isLayered())
+ {
+ if (attachment.layer() >= size.depth)
+ {
+ return FramebufferStatus::Incomplete(
+ GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
+ err::kFramebufferIncompleteAttachmentLayerGreaterThanDepth);
+ }
+ }
+ // If <image> is a three-dimensional texture or a two-dimensional array texture and the
+ // attachment is layered, the depth or layer count, respectively, of the texture is less
+ // than or equal to the value of MAX_FRAMEBUFFER_LAYERS_EXT.
+ else
+ {
+ if (size.depth >= context->getCaps().maxFramebufferLayers)
+ {
+ return FramebufferStatus::Incomplete(
+ GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
+ err::kFramebufferIncompleteAttachmentDepthGreaterThanMaxLayers);
+ }
+ }
+
+ // ES3 specifies that cube map texture attachments must be cube complete.
+ // This language is missing from the ES2 spec, but we enforce it here because some
+ // desktop OpenGL drivers also enforce this validation.
+ // TODO(jmadill): Check if OpenGL ES2 drivers enforce cube completeness.
+ const Texture *texture = attachment.getTexture();
+ ASSERT(texture);
+ if (texture->getType() == TextureType::CubeMap &&
+ !texture->getTextureState().isCubeComplete())
+ {
+ return FramebufferStatus::Incomplete(
+ GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
+ err::kFramebufferIncompleteAttachmentNotCubeComplete);
+ }
+
+ if (!texture->getImmutableFormat())
+ {
+ GLuint attachmentMipLevel = static_cast<GLuint>(attachment.mipLevel());
+
+ // From the ES 3.0 spec, pg 213:
+ // If the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is TEXTURE and the value of
+ // FRAMEBUFFER_ATTACHMENT_OBJECT_NAME does not name an immutable-format texture,
+ // then the value of FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL must be in the
+ // range[levelbase, q], where levelbase is the value of TEXTURE_BASE_LEVEL and q is
+ // the effective maximum texture level defined in the Mipmapping discussion of
+ // section 3.8.10.4.
+ if (attachmentMipLevel < texture->getBaseLevel() ||
+ attachmentMipLevel > texture->getMipmapMaxLevel())
+ {
+ return FramebufferStatus::Incomplete(
+ GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
+ err::kFramebufferIncompleteAttachmentLevelOutOfBaseMaxLevelRange);
+ }
+
+ // Form the ES 3.0 spec, pg 213/214:
+ // If the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is TEXTURE and the value of
+ // FRAMEBUFFER_ATTACHMENT_OBJECT_NAME does not name an immutable-format texture and
+ // the value of FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL is not levelbase, then the
+ // texture must be mipmap complete, and if FRAMEBUFFER_ATTACHMENT_OBJECT_NAME names
+ // a cubemap texture, the texture must also be cube complete.
+ if (attachmentMipLevel != texture->getBaseLevel() && !texture->isMipmapComplete())
+ {
+ return FramebufferStatus::Incomplete(
+ GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
+ err::kFramebufferIncompleteAttachmentLevelNotBaseLevelForIncompleteMipTexture);
+ }
+ }
+ }
+
+ return FramebufferStatus::Complete();
+}
+
+FramebufferStatus CheckAttachmentSampleCounts(const Context *context,
+ GLsizei currAttachmentSamples,
+ GLsizei samples,
+ bool colorAttachment)
+{
+ if (currAttachmentSamples != samples)
+ {
+ if (colorAttachment)
+ {
+ // APPLE_framebuffer_multisample, which EXT_draw_buffers refers to, requires that
+ // all color attachments have the same number of samples for the FBO to be complete.
+ return FramebufferStatus::Incomplete(
+ GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,
+ err::kFramebufferIncompleteMultisampleInconsistentSampleCounts);
+ }
+ else
+ {
+ // CHROMIUM_framebuffer_mixed_samples allows a framebuffer to be considered complete
+ // when its depth or stencil samples are a multiple of the number of color samples.
+ if (!context->getExtensions().framebufferMixedSamplesCHROMIUM)
+ {
+ return FramebufferStatus::Incomplete(
+ GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,
+ err::kFramebufferIncompleteMultisampleInconsistentSampleCounts);
+ }
+
+ if ((currAttachmentSamples % std::max(samples, 1)) != 0)
+ {
+ return FramebufferStatus::Incomplete(
+ GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,
+ err::
+ kFramebufferIncompleteMultisampleDepthStencilSampleCountDivisibleByColorSampleCount);
+ }
+ }
+ }
+
+ return FramebufferStatus::Complete();
+}
+
+FramebufferStatus CheckAttachmentSampleCompleteness(const Context *context,
+ const FramebufferAttachment &attachment,
+ bool colorAttachment,
+ Optional<int> *samples,
+ Optional<bool> *fixedSampleLocations,
+ Optional<int> *renderToTextureSamples)
+{
+ ASSERT(attachment.isAttached());
+
+ if (attachment.type() == GL_TEXTURE)
+ {
+ const Texture *texture = attachment.getTexture();
+ ASSERT(texture);
+ GLenum sizedInternalFormat = attachment.getFormat().info->sizedInternalFormat;
+ const TextureCaps &formatCaps = context->getTextureCaps().get(sizedInternalFormat);
+ if (static_cast<GLuint>(attachment.getSamples()) > formatCaps.getMaxSamples())
+ {
+ return FramebufferStatus::Incomplete(
+ GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,
+ err::kFramebufferIncompleteAttachmentSamplesGreaterThanMaxSupportedSamples);
+ }
+
+ const ImageIndex &attachmentImageIndex = attachment.getTextureImageIndex();
+ bool fixedSampleloc = texture->getAttachmentFixedSampleLocations(attachmentImageIndex);
+ if (fixedSampleLocations->valid() && fixedSampleloc != fixedSampleLocations->value())
+ {
+ return FramebufferStatus::Incomplete(
+ GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,
+ err::kFramebufferIncompleteMultisampleInconsistentFixedSampleLocations);
+ }
+ else
+ {
+ *fixedSampleLocations = fixedSampleloc;
+ }
+ }
+
+ if (renderToTextureSamples->valid())
+ {
+ // Only check against RenderToTextureSamples if they actually exist.
+ if (renderToTextureSamples->value() !=
+ FramebufferAttachment::kDefaultRenderToTextureSamples)
+ {
+ FramebufferStatus sampleCountStatus =
+ CheckAttachmentSampleCounts(context, attachment.getRenderToTextureSamples(),
+ renderToTextureSamples->value(), colorAttachment);
+ if (!sampleCountStatus.isComplete())
+ {
+ return sampleCountStatus;
+ }
+ }
+ }
+ else
+ {
+ *renderToTextureSamples = attachment.getRenderToTextureSamples();
+ }
+
+ if (samples->valid())
+ {
+ // RenderToTextureSamples takes precedence if they exist.
+ if (renderToTextureSamples->value() ==
+ FramebufferAttachment::kDefaultRenderToTextureSamples)
+ {
+
+ FramebufferStatus sampleCountStatus = CheckAttachmentSampleCounts(
+ context, attachment.getSamples(), samples->value(), colorAttachment);
+ if (!sampleCountStatus.isComplete())
+ {
+ return sampleCountStatus;
+ }
+ }
+ }
+ else
+ {
+ *samples = attachment.getSamples();
+ }
+
+ return FramebufferStatus::Complete();
+}
+
+// Needed to index into the attachment arrays/bitsets.
+static_assert(static_cast<size_t>(IMPLEMENTATION_MAX_DRAW_BUFFERS) ==
+ Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_MAX,
+ "Framebuffer Dirty bit mismatch");
+static_assert(static_cast<size_t>(IMPLEMENTATION_MAX_DRAW_BUFFERS) ==
+ Framebuffer::DIRTY_BIT_DEPTH_ATTACHMENT,
+ "Framebuffer Dirty bit mismatch");
+static_assert(static_cast<size_t>(IMPLEMENTATION_MAX_DRAW_BUFFERS + 1) ==
+ Framebuffer::DIRTY_BIT_STENCIL_ATTACHMENT,
+ "Framebuffer Dirty bit mismatch");
+
+angle::Result InitAttachment(const Context *context, FramebufferAttachment *attachment)
+{
+ ASSERT(attachment->isAttached());
+ if (attachment->initState() == InitState::MayNeedInit)
+ {
+ ANGLE_TRY(attachment->initializeContents(context));
+ }
+ return angle::Result::Continue;
+}
+
+bool AttachmentOverlapsWithTexture(const FramebufferAttachment &attachment,
+ const Texture *texture,
+ const Sampler *sampler)
+{
+ if (!attachment.isTextureWithId(texture->id()))
+ {
+ return false;
+ }
+
+ const gl::ImageIndex &index = attachment.getTextureImageIndex();
+ GLuint attachmentLevel = static_cast<GLuint>(index.getLevelIndex());
+ GLuint textureEffectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
+ GLuint textureMaxLevel = textureEffectiveBaseLevel;
+ if ((sampler && IsMipmapFiltered(sampler->getSamplerState().getMinFilter())) ||
+ IsMipmapFiltered(texture->getSamplerState().getMinFilter()))
+ {
+ textureMaxLevel = texture->getMipmapMaxLevel();
+ }
+
+ return attachmentLevel >= textureEffectiveBaseLevel && attachmentLevel <= textureMaxLevel;
+}
+
+} // anonymous namespace
+
+bool FramebufferStatus::isComplete() const
+{
+ return status == GL_FRAMEBUFFER_COMPLETE;
+}
+
+FramebufferStatus FramebufferStatus::Complete()
+{
+ FramebufferStatus result;
+ result.status = GL_FRAMEBUFFER_COMPLETE;
+ result.reason = nullptr;
+ return result;
+}
+
+FramebufferStatus FramebufferStatus::Incomplete(GLenum status, const char *reason)
+{
+ ASSERT(status != GL_FRAMEBUFFER_COMPLETE);
+
+ FramebufferStatus result;
+ result.status = status;
+ result.reason = reason;
+ return result;
+}
+
+// This constructor is only used for default framebuffers.
+FramebufferState::FramebufferState(rx::Serial serial)
+ : mId(Framebuffer::kDefaultDrawFramebufferHandle),
+ mFramebufferSerial(serial),
+ mLabel(),
+ mColorAttachments(1),
+ mColorAttachmentsMask(0),
+ mDrawBufferStates(1, GL_BACK),
+ mReadBufferState(GL_BACK),
+ mDrawBufferTypeMask(),
+ mDefaultWidth(0),
+ mDefaultHeight(0),
+ mDefaultSamples(0),
+ mDefaultFixedSampleLocations(GL_FALSE),
+ mDefaultLayers(0),
+ mFlipY(GL_FALSE),
+ mWebGLDepthStencilConsistent(true),
+ mDefaultFramebufferReadAttachmentInitialized(false),
+ mSrgbWriteControlMode(SrgbWriteControlMode::Default)
+{
+ ASSERT(mDrawBufferStates.size() > 0);
+ mEnabledDrawBuffers.set(0);
+}
+
+FramebufferState::FramebufferState(const Caps &caps, FramebufferID id, rx::Serial serial)
+ : mId(id),
+ mFramebufferSerial(serial),
+ mLabel(),
+ mColorAttachments(caps.maxColorAttachments),
+ mColorAttachmentsMask(0),
+ mDrawBufferStates(caps.maxDrawBuffers, GL_NONE),
+ mReadBufferState(GL_COLOR_ATTACHMENT0_EXT),
+ mDrawBufferTypeMask(),
+ mDefaultWidth(0),
+ mDefaultHeight(0),
+ mDefaultSamples(0),
+ mDefaultFixedSampleLocations(GL_FALSE),
+ mDefaultLayers(0),
+ mFlipY(GL_FALSE),
+ mWebGLDepthStencilConsistent(true),
+ mDefaultFramebufferReadAttachmentInitialized(false),
+ mSrgbWriteControlMode(SrgbWriteControlMode::Default)
+{
+ ASSERT(mId != Framebuffer::kDefaultDrawFramebufferHandle);
+ ASSERT(mDrawBufferStates.size() > 0);
+ mDrawBufferStates[0] = GL_COLOR_ATTACHMENT0_EXT;
+}
+
+FramebufferState::~FramebufferState() {}
+
+const std::string &FramebufferState::getLabel() const
+{
+ return mLabel;
+}
+
+const FramebufferAttachment *FramebufferState::getAttachment(const Context *context,
+ GLenum attachment) const
+{
+ if (attachment >= GL_COLOR_ATTACHMENT0 && attachment <= GL_COLOR_ATTACHMENT15)
+ {
+ return getColorAttachment(attachment - GL_COLOR_ATTACHMENT0);
+ }
+
+ // WebGL1 allows a developer to query for attachment parameters even when "inconsistant" (i.e.
+ // multiple conflicting attachment points) and requires us to return the framebuffer attachment
+ // associated with WebGL.
+ switch (attachment)
+ {
+ case GL_COLOR:
+ case GL_BACK:
+ return getColorAttachment(0);
+ case GL_DEPTH:
+ case GL_DEPTH_ATTACHMENT:
+ if (context->isWebGL1())
+ {
+ return getWebGLDepthAttachment();
+ }
+ else
+ {
+ return getDepthAttachment();
+ }
+ case GL_STENCIL:
+ case GL_STENCIL_ATTACHMENT:
+ if (context->isWebGL1())
+ {
+ return getWebGLStencilAttachment();
+ }
+ else
+ {
+ return getStencilAttachment();
+ }
+ case GL_DEPTH_STENCIL:
+ case GL_DEPTH_STENCIL_ATTACHMENT:
+ if (context->isWebGL1())
+ {
+ return getWebGLDepthStencilAttachment();
+ }
+ else
+ {
+ return getDepthStencilAttachment();
+ }
+ default:
+ UNREACHABLE();
+ return nullptr;
+ }
+}
+
+uint32_t FramebufferState::getReadIndex() const
+{
+ ASSERT(mReadBufferState == GL_BACK ||
+ (mReadBufferState >= GL_COLOR_ATTACHMENT0 && mReadBufferState <= GL_COLOR_ATTACHMENT15));
+ uint32_t readIndex = mReadBufferState == GL_BACK ? 0 : mReadBufferState - GL_COLOR_ATTACHMENT0;
+ ASSERT(readIndex < mColorAttachments.size());
+ return readIndex;
+}
+
+const FramebufferAttachment *FramebufferState::getReadAttachment() const
+{
+ if (mReadBufferState == GL_NONE)
+ {
+ return nullptr;
+ }
+
+ uint32_t readIndex = getReadIndex();
+ const gl::FramebufferAttachment &framebufferAttachment =
+ isDefault() ? mDefaultFramebufferReadAttachment : mColorAttachments[readIndex];
+
+ return framebufferAttachment.isAttached() ? &framebufferAttachment : nullptr;
+}
+
+const FramebufferAttachment *FramebufferState::getReadPixelsAttachment(GLenum readFormat) const
+{
+ switch (readFormat)
+ {
+ case GL_DEPTH_COMPONENT:
+ return getDepthAttachment();
+ case GL_STENCIL_INDEX_OES:
+ return getStencilOrDepthStencilAttachment();
+ case GL_DEPTH_STENCIL_OES:
+ return getDepthStencilAttachment();
+ default:
+ return getReadAttachment();
+ }
+}
+
+const FramebufferAttachment *FramebufferState::getFirstNonNullAttachment() const
+{
+ auto *colorAttachment = getFirstColorAttachment();
+ if (colorAttachment)
+ {
+ return colorAttachment;
+ }
+ return getDepthOrStencilAttachment();
+}
+
+const FramebufferAttachment *FramebufferState::getFirstColorAttachment() const
+{
+ for (const FramebufferAttachment &colorAttachment : mColorAttachments)
+ {
+ if (colorAttachment.isAttached())
+ {
+ return &colorAttachment;
+ }
+ }
+
+ return nullptr;
+}
+
+const FramebufferAttachment *FramebufferState::getDepthOrStencilAttachment() const
+{
+ if (mDepthAttachment.isAttached())
+ {
+ return &mDepthAttachment;
+ }
+ if (mStencilAttachment.isAttached())
+ {
+ return &mStencilAttachment;
+ }
+ return nullptr;
+}
+
+const FramebufferAttachment *FramebufferState::getStencilOrDepthStencilAttachment() const
+{
+ if (mStencilAttachment.isAttached())
+ {
+ return &mStencilAttachment;
+ }
+ return getDepthStencilAttachment();
+}
+
+const FramebufferAttachment *FramebufferState::getColorAttachment(size_t colorAttachment) const
+{
+ ASSERT(colorAttachment < mColorAttachments.size());
+ return mColorAttachments[colorAttachment].isAttached() ? &mColorAttachments[colorAttachment]
+ : nullptr;
+}
+
+const FramebufferAttachment *FramebufferState::getDepthAttachment() const
+{
+ return mDepthAttachment.isAttached() ? &mDepthAttachment : nullptr;
+}
+
+const FramebufferAttachment *FramebufferState::getWebGLDepthAttachment() const
+{
+ return mWebGLDepthAttachment.isAttached() ? &mWebGLDepthAttachment : nullptr;
+}
+
+const FramebufferAttachment *FramebufferState::getWebGLDepthStencilAttachment() const
+{
+ return mWebGLDepthStencilAttachment.isAttached() ? &mWebGLDepthStencilAttachment : nullptr;
+}
+
+const FramebufferAttachment *FramebufferState::getStencilAttachment() const
+{
+ return mStencilAttachment.isAttached() ? &mStencilAttachment : nullptr;
+}
+
+const FramebufferAttachment *FramebufferState::getWebGLStencilAttachment() const
+{
+ return mWebGLStencilAttachment.isAttached() ? &mWebGLStencilAttachment : nullptr;
+}
+
+const FramebufferAttachment *FramebufferState::getDepthStencilAttachment() const
+{
+ // A valid depth-stencil attachment has the same resource bound to both the
+ // depth and stencil attachment points.
+ if (mDepthAttachment.isAttached() && mStencilAttachment.isAttached() &&
+ mDepthAttachment == mStencilAttachment)
+ {
+ return &mDepthAttachment;
+ }
+
+ return nullptr;
+}
+
+const Extents FramebufferState::getAttachmentExtentsIntersection() const
+{
+ int32_t width = std::numeric_limits<int32_t>::max();
+ int32_t height = std::numeric_limits<int32_t>::max();
+ for (const FramebufferAttachment &attachment : mColorAttachments)
+ {
+ if (attachment.isAttached())
+ {
+ width = std::min(width, attachment.getSize().width);
+ height = std::min(height, attachment.getSize().height);
+ }
+ }
+
+ if (mDepthAttachment.isAttached())
+ {
+ width = std::min(width, mDepthAttachment.getSize().width);
+ height = std::min(height, mDepthAttachment.getSize().height);
+ }
+
+ if (mStencilAttachment.isAttached())
+ {
+ width = std::min(width, mStencilAttachment.getSize().width);
+ height = std::min(height, mStencilAttachment.getSize().height);
+ }
+
+ return Extents(width, height, 0);
+}
+
+bool FramebufferState::attachmentsHaveSameDimensions() const
+{
+ Optional<Extents> attachmentSize;
+
+ auto hasMismatchedSize = [&attachmentSize](const FramebufferAttachment &attachment) {
+ if (!attachment.isAttached())
+ {
+ return false;
+ }
+
+ if (!attachmentSize.valid())
+ {
+ attachmentSize = attachment.getSize();
+ return false;
+ }
+
+ const auto &prevSize = attachmentSize.value();
+ const auto &curSize = attachment.getSize();
+ return (curSize.width != prevSize.width || curSize.height != prevSize.height);
+ };
+
+ for (const auto &attachment : mColorAttachments)
+ {
+ if (hasMismatchedSize(attachment))
+ {
+ return false;
+ }
+ }
+
+ if (hasMismatchedSize(mDepthAttachment))
+ {
+ return false;
+ }
+
+ return !hasMismatchedSize(mStencilAttachment);
+}
+
+bool FramebufferState::hasSeparateDepthAndStencilAttachments() const
+{
+ // if we have both a depth and stencil buffer, they must refer to the same object
+ // since we only support packed_depth_stencil and not separate depth and stencil
+ return (getDepthAttachment() != nullptr && getStencilAttachment() != nullptr &&
+ getDepthStencilAttachment() == nullptr);
+}
+
+const FramebufferAttachment *FramebufferState::getDrawBuffer(size_t drawBufferIdx) const
+{
+ ASSERT(drawBufferIdx < mDrawBufferStates.size());
+ if (mDrawBufferStates[drawBufferIdx] != GL_NONE)
+ {
+ // ES3 spec: "If the GL is bound to a draw framebuffer object, the ith buffer listed in bufs
+ // must be COLOR_ATTACHMENTi or NONE"
+ ASSERT(mDrawBufferStates[drawBufferIdx] == GL_COLOR_ATTACHMENT0 + drawBufferIdx ||
+ (drawBufferIdx == 0 && mDrawBufferStates[drawBufferIdx] == GL_BACK));
+
+ if (mDrawBufferStates[drawBufferIdx] == GL_BACK)
+ {
+ return getColorAttachment(0);
+ }
+ else
+ {
+ return getColorAttachment(mDrawBufferStates[drawBufferIdx] - GL_COLOR_ATTACHMENT0);
+ }
+ }
+ else
+ {
+ return nullptr;
+ }
+}
+
+size_t FramebufferState::getDrawBufferCount() const
+{
+ return mDrawBufferStates.size();
+}
+
+bool FramebufferState::colorAttachmentsAreUniqueImages() const
+{
+ for (size_t firstAttachmentIdx = 0; firstAttachmentIdx < mColorAttachments.size();
+ firstAttachmentIdx++)
+ {
+ const FramebufferAttachment &firstAttachment = mColorAttachments[firstAttachmentIdx];
+ if (!firstAttachment.isAttached())
+ {
+ continue;
+ }
+
+ for (size_t secondAttachmentIdx = firstAttachmentIdx + 1;
+ secondAttachmentIdx < mColorAttachments.size(); secondAttachmentIdx++)
+ {
+ const FramebufferAttachment &secondAttachment = mColorAttachments[secondAttachmentIdx];
+ if (!secondAttachment.isAttached())
+ {
+ continue;
+ }
+
+ if (firstAttachment == secondAttachment)
+ {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+bool FramebufferState::hasDepth() const
+{
+ return (mDepthAttachment.isAttached() && mDepthAttachment.getDepthSize() > 0);
+}
+
+bool FramebufferState::hasStencil() const
+{
+ return (mStencilAttachment.isAttached() && mStencilAttachment.getStencilSize() > 0);
+}
+
+bool FramebufferState::hasExternalTextureAttachment() const
+{
+ // External textures can only be bound to color attachment 0
+ return (mColorAttachments[0].isAttached() && mColorAttachments[0].isExternalTexture());
+}
+
+bool FramebufferState::hasYUVAttachment() const
+{
+ // The only attachments that can be YUV are external textures and surfaces, both are attached at
+ // color attachment 0.
+ return (mColorAttachments[0].isAttached() && mColorAttachments[0].isYUV());
+}
+
+bool FramebufferState::isMultiview() const
+{
+ const FramebufferAttachment *attachment = getFirstNonNullAttachment();
+ if (attachment == nullptr)
+ {
+ return false;
+ }
+ return attachment->isMultiview();
+}
+
+int FramebufferState::getBaseViewIndex() const
+{
+ const FramebufferAttachment *attachment = getFirstNonNullAttachment();
+ if (attachment == nullptr)
+ {
+ return GL_NONE;
+ }
+ return attachment->getBaseViewIndex();
+}
+
+Box FramebufferState::getDimensions() const
+{
+ Extents extents = getExtents();
+ return Box(0, 0, 0, extents.width, extents.height, extents.depth);
+}
+
+Extents FramebufferState::getExtents() const
+{
+ // OpenGLES3.0 (https://www.khronos.org/registry/OpenGL/specs/es/3.0/es_spec_3.0.pdf
+ // section 4.4.4.2) allows attachments have unequal size.
+ const FramebufferAttachment *first = getFirstNonNullAttachment();
+ if (first)
+ {
+ return getAttachmentExtentsIntersection();
+ }
+ return Extents(getDefaultWidth(), getDefaultHeight(), 0);
+}
+
+bool FramebufferState::isDefault() const
+{
+ return mId == Framebuffer::kDefaultDrawFramebufferHandle;
+}
+
+bool FramebufferState::isBoundAsDrawFramebuffer(const Context *context) const
+{
+ return context->getState().getDrawFramebuffer()->id() == mId;
+}
+
+const FramebufferID Framebuffer::kDefaultDrawFramebufferHandle = {0};
+
+Framebuffer::Framebuffer(const Context *context, rx::GLImplFactory *factory)
+ : mState(context->getShareGroup()->generateFramebufferSerial()),
+ mImpl(factory->createFramebuffer(mState)),
+ mCachedStatus(FramebufferStatus::Incomplete(GL_FRAMEBUFFER_UNDEFINED_OES,
+ err::kFramebufferIncompleteSurfaceless)),
+ mDirtyDepthAttachmentBinding(this, DIRTY_BIT_DEPTH_ATTACHMENT),
+ mDirtyStencilAttachmentBinding(this, DIRTY_BIT_STENCIL_ATTACHMENT)
+{
+ mDirtyColorAttachmentBindings.emplace_back(this, DIRTY_BIT_COLOR_ATTACHMENT_0);
+ SetComponentTypeMask(getDrawbufferWriteType(0), 0, &mState.mDrawBufferTypeMask);
+}
+
+Framebuffer::Framebuffer(const Context *context, rx::GLImplFactory *factory, FramebufferID id)
+ : mState(context->getCaps(), id, context->getShareGroup()->generateFramebufferSerial()),
+ mImpl(factory->createFramebuffer(mState)),
+ mCachedStatus(),
+ mDirtyDepthAttachmentBinding(this, DIRTY_BIT_DEPTH_ATTACHMENT),
+ mDirtyStencilAttachmentBinding(this, DIRTY_BIT_STENCIL_ATTACHMENT)
+{
+ ASSERT(mImpl != nullptr);
+ ASSERT(mState.mColorAttachments.size() ==
+ static_cast<size_t>(context->getCaps().maxColorAttachments));
+
+ for (uint32_t colorIndex = 0;
+ colorIndex < static_cast<uint32_t>(mState.mColorAttachments.size()); ++colorIndex)
+ {
+ mDirtyColorAttachmentBindings.emplace_back(this, DIRTY_BIT_COLOR_ATTACHMENT_0 + colorIndex);
+ }
+ if (context->getClientVersion() >= ES_3_0)
+ {
+ mDirtyBits.set(DIRTY_BIT_READ_BUFFER);
+ }
+}
+
+Framebuffer::~Framebuffer()
+{
+ SafeDelete(mImpl);
+}
+
+void Framebuffer::onDestroy(const Context *context)
+{
+ if (isDefault())
+ {
+ std::ignore = unsetSurfaces(context);
+ }
+
+ for (auto &attachment : mState.mColorAttachments)
+ {
+ attachment.detach(context, mState.mFramebufferSerial);
+ }
+ mState.mDepthAttachment.detach(context, mState.mFramebufferSerial);
+ mState.mStencilAttachment.detach(context, mState.mFramebufferSerial);
+ mState.mWebGLDepthAttachment.detach(context, mState.mFramebufferSerial);
+ mState.mWebGLStencilAttachment.detach(context, mState.mFramebufferSerial);
+ mState.mWebGLDepthStencilAttachment.detach(context, mState.mFramebufferSerial);
+
+ if (mPixelLocalStorage)
+ {
+ mPixelLocalStorage->onFramebufferDestroyed(context);
+ }
+
+ mImpl->destroy(context);
+}
+
+egl::Error Framebuffer::setSurfaces(const Context *context,
+ egl::Surface *surface,
+ egl::Surface *readSurface)
+{
+ // This has to be a default framebuffer.
+ ASSERT(isDefault());
+ ASSERT(mDirtyColorAttachmentBindings.size() == 1);
+ ASSERT(mDirtyColorAttachmentBindings[0].getSubjectIndex() == DIRTY_BIT_COLOR_ATTACHMENT_0);
+
+ ASSERT(!mState.mColorAttachments[0].isAttached());
+ ASSERT(!mState.mDepthAttachment.isAttached());
+ ASSERT(!mState.mStencilAttachment.isAttached());
+
+ if (surface)
+ {
+ setAttachmentImpl(context, GL_FRAMEBUFFER_DEFAULT, GL_BACK, ImageIndex(), surface,
+ FramebufferAttachment::kDefaultNumViews,
+ FramebufferAttachment::kDefaultBaseViewIndex, false,
+ FramebufferAttachment::kDefaultRenderToTextureSamples);
+ mDirtyBits.set(DIRTY_BIT_COLOR_ATTACHMENT_0);
+
+ if (surface->getConfig()->depthSize > 0)
+ {
+ setAttachmentImpl(context, GL_FRAMEBUFFER_DEFAULT, GL_DEPTH, ImageIndex(), surface,
+ FramebufferAttachment::kDefaultNumViews,
+ FramebufferAttachment::kDefaultBaseViewIndex, false,
+ FramebufferAttachment::kDefaultRenderToTextureSamples);
+ mDirtyBits.set(DIRTY_BIT_DEPTH_ATTACHMENT);
+ }
+
+ if (surface->getConfig()->stencilSize > 0)
+ {
+ setAttachmentImpl(context, GL_FRAMEBUFFER_DEFAULT, GL_STENCIL, ImageIndex(), surface,
+ FramebufferAttachment::kDefaultNumViews,
+ FramebufferAttachment::kDefaultBaseViewIndex, false,
+ FramebufferAttachment::kDefaultRenderToTextureSamples);
+ mDirtyBits.set(DIRTY_BIT_STENCIL_ATTACHMENT);
+ }
+
+ mState.mSurfaceTextureOffset = surface->getTextureOffset();
+
+ // Ensure the backend has a chance to synchronize its content for a new backbuffer.
+ mDirtyBits.set(DIRTY_BIT_COLOR_BUFFER_CONTENTS_0);
+ }
+
+ setReadSurface(context, readSurface);
+
+ SetComponentTypeMask(getDrawbufferWriteType(0), 0, &mState.mDrawBufferTypeMask);
+
+ ASSERT(mCachedStatus.value().status == GL_FRAMEBUFFER_UNDEFINED_OES);
+ ASSERT(mCachedStatus.value().reason == err::kFramebufferIncompleteSurfaceless);
+ if (surface)
+ {
+ mCachedStatus = FramebufferStatus::Complete();
+ ANGLE_TRY(surface->getImplementation()->attachToFramebuffer(context, this));
+ }
+
+ return egl::NoError();
+}
+
+void Framebuffer::setReadSurface(const Context *context, egl::Surface *readSurface)
+{
+ // This has to be a default framebuffer.
+ ASSERT(isDefault());
+ ASSERT(mDirtyColorAttachmentBindings.size() == 1);
+ ASSERT(mDirtyColorAttachmentBindings[0].getSubjectIndex() == DIRTY_BIT_COLOR_ATTACHMENT_0);
+
+ // Read surface is not attached.
+ ASSERT(!mState.mDefaultFramebufferReadAttachment.isAttached());
+
+ // updateAttachment() without mState.mResourceNeedsInit.set()
+ mState.mDefaultFramebufferReadAttachment.attach(
+ context, GL_FRAMEBUFFER_DEFAULT, GL_BACK, ImageIndex(), readSurface,
+ FramebufferAttachment::kDefaultNumViews, FramebufferAttachment::kDefaultBaseViewIndex,
+ false, FramebufferAttachment::kDefaultRenderToTextureSamples, mState.mFramebufferSerial);
+
+ if (context->getClientVersion() >= ES_3_0)
+ {
+ mDirtyBits.set(DIRTY_BIT_READ_BUFFER);
+ }
+}
+
+egl::Error Framebuffer::unsetSurfaces(const Context *context)
+{
+ // This has to be a default framebuffer.
+ ASSERT(isDefault());
+ ASSERT(mDirtyColorAttachmentBindings.size() == 1);
+ ASSERT(mDirtyColorAttachmentBindings[0].getSubjectIndex() == DIRTY_BIT_COLOR_ATTACHMENT_0);
+
+ if (mState.mColorAttachments[0].isAttached())
+ {
+ const egl::Surface *surface = mState.mColorAttachments[0].getSurface();
+ mState.mColorAttachments[0].detach(context, mState.mFramebufferSerial);
+ mDirtyBits.set(DIRTY_BIT_COLOR_ATTACHMENT_0);
+
+ if (mState.mDepthAttachment.isAttached())
+ {
+ mState.mDepthAttachment.detach(context, mState.mFramebufferSerial);
+ mDirtyBits.set(DIRTY_BIT_DEPTH_ATTACHMENT);
+ }
+
+ if (mState.mStencilAttachment.isAttached())
+ {
+ mState.mStencilAttachment.detach(context, mState.mFramebufferSerial);
+ mDirtyBits.set(DIRTY_BIT_STENCIL_ATTACHMENT);
+ }
+
+ ANGLE_TRY(surface->getImplementation()->detachFromFramebuffer(context, this));
+
+ ASSERT(mCachedStatus.value().status == GL_FRAMEBUFFER_COMPLETE);
+ mCachedStatus = FramebufferStatus::Incomplete(GL_FRAMEBUFFER_UNDEFINED_OES,
+ err::kFramebufferIncompleteSurfaceless);
+ }
+ else
+ {
+ ASSERT(!mState.mDepthAttachment.isAttached());
+ ASSERT(!mState.mStencilAttachment.isAttached());
+ ASSERT(mCachedStatus.value().status == GL_FRAMEBUFFER_UNDEFINED_OES);
+ ASSERT(mCachedStatus.value().reason == err::kFramebufferIncompleteSurfaceless);
+ }
+
+ mState.mDefaultFramebufferReadAttachment.detach(context, mState.mFramebufferSerial);
+ mState.mDefaultFramebufferReadAttachmentInitialized = false;
+ return egl::NoError();
+}
+
+angle::Result Framebuffer::setLabel(const Context *context, const std::string &label)
+{
+ mState.mLabel = label;
+
+ if (mImpl)
+ {
+ return mImpl->onLabelUpdate(context);
+ }
+ return angle::Result::Continue;
+}
+
+const std::string &Framebuffer::getLabel() const
+{
+ return mState.mLabel;
+}
+
+bool Framebuffer::detachTexture(const Context *context, TextureID textureId)
+{
+ return detachResourceById(context, GL_TEXTURE, textureId.value);
+}
+
+bool Framebuffer::detachRenderbuffer(const Context *context, RenderbufferID renderbufferId)
+{
+ return detachResourceById(context, GL_RENDERBUFFER, renderbufferId.value);
+}
+
+bool Framebuffer::detachResourceById(const Context *context, GLenum resourceType, GLuint resourceId)
+{
+ bool found = false;
+
+ for (size_t colorIndex = 0; colorIndex < mState.mColorAttachments.size(); ++colorIndex)
+ {
+ if (detachMatchingAttachment(context, &mState.mColorAttachments[colorIndex], resourceType,
+ resourceId))
+ {
+ found = true;
+ }
+ }
+
+ if (context->isWebGL1())
+ {
+ const std::array<FramebufferAttachment *, 3> attachments = {
+ {&mState.mWebGLDepthStencilAttachment, &mState.mWebGLDepthAttachment,
+ &mState.mWebGLStencilAttachment}};
+ for (FramebufferAttachment *attachment : attachments)
+ {
+ if (detachMatchingAttachment(context, attachment, resourceType, resourceId))
+ {
+ found = true;
+ }
+ }
+ }
+ else
+ {
+ if (detachMatchingAttachment(context, &mState.mDepthAttachment, resourceType, resourceId))
+ {
+ found = true;
+ }
+ if (detachMatchingAttachment(context, &mState.mStencilAttachment, resourceType, resourceId))
+ {
+ found = true;
+ }
+ }
+
+ return found;
+}
+
+bool Framebuffer::detachMatchingAttachment(const Context *context,
+ FramebufferAttachment *attachment,
+ GLenum matchType,
+ GLuint matchId)
+{
+ if (attachment->isAttached() && attachment->type() == matchType && attachment->id() == matchId)
+ {
+ // We go through resetAttachment to make sure that all the required bookkeeping will be done
+ // such as updating enabled draw buffer state.
+ resetAttachment(context, attachment->getBinding());
+ return true;
+ }
+
+ return false;
+}
+
+const FramebufferAttachment *Framebuffer::getColorAttachment(size_t colorAttachment) const
+{
+ return mState.getColorAttachment(colorAttachment);
+}
+
+const FramebufferAttachment *Framebuffer::getDepthAttachment() const
+{
+ return mState.getDepthAttachment();
+}
+
+const FramebufferAttachment *Framebuffer::getStencilAttachment() const
+{
+ return mState.getStencilAttachment();
+}
+
+const FramebufferAttachment *Framebuffer::getDepthStencilAttachment() const
+{
+ return mState.getDepthStencilAttachment();
+}
+
+const FramebufferAttachment *Framebuffer::getDepthOrStencilAttachment() const
+{
+ return mState.getDepthOrStencilAttachment();
+}
+
+const FramebufferAttachment *Framebuffer::getStencilOrDepthStencilAttachment() const
+{
+ return mState.getStencilOrDepthStencilAttachment();
+}
+
+const FramebufferAttachment *Framebuffer::getReadColorAttachment() const
+{
+ return mState.getReadAttachment();
+}
+
+GLenum Framebuffer::getReadColorAttachmentType() const
+{
+ const FramebufferAttachment *readAttachment = mState.getReadAttachment();
+ return (readAttachment != nullptr ? readAttachment->type() : GL_NONE);
+}
+
+const FramebufferAttachment *Framebuffer::getFirstColorAttachment() const
+{
+ return mState.getFirstColorAttachment();
+}
+
+const FramebufferAttachment *Framebuffer::getFirstNonNullAttachment() const
+{
+ return mState.getFirstNonNullAttachment();
+}
+
+const FramebufferAttachment *Framebuffer::getAttachment(const Context *context,
+ GLenum attachment) const
+{
+ return mState.getAttachment(context, attachment);
+}
+
+size_t Framebuffer::getDrawbufferStateCount() const
+{
+ return mState.mDrawBufferStates.size();
+}
+
+GLenum Framebuffer::getDrawBufferState(size_t drawBuffer) const
+{
+ ASSERT(drawBuffer < mState.mDrawBufferStates.size());
+ return mState.mDrawBufferStates[drawBuffer];
+}
+
+const DrawBuffersVector<GLenum> &Framebuffer::getDrawBufferStates() const
+{
+ return mState.getDrawBufferStates();
+}
+
+void Framebuffer::setDrawBuffers(size_t count, const GLenum *buffers)
+{
+ auto &drawStates = mState.mDrawBufferStates;
+
+ ASSERT(count <= drawStates.size());
+ std::copy(buffers, buffers + count, drawStates.begin());
+ std::fill(drawStates.begin() + count, drawStates.end(), GL_NONE);
+ mDirtyBits.set(DIRTY_BIT_DRAW_BUFFERS);
+
+ mState.mEnabledDrawBuffers.reset();
+ mState.mDrawBufferTypeMask.reset();
+
+ for (size_t index = 0; index < count; ++index)
+ {
+ SetComponentTypeMask(getDrawbufferWriteType(index), index, &mState.mDrawBufferTypeMask);
+
+ if (drawStates[index] != GL_NONE && mState.mColorAttachments[index].isAttached())
+ {
+ mState.mEnabledDrawBuffers.set(index);
+ }
+ }
+}
+
+const FramebufferAttachment *Framebuffer::getDrawBuffer(size_t drawBuffer) const
+{
+ return mState.getDrawBuffer(drawBuffer);
+}
+
+ComponentType Framebuffer::getDrawbufferWriteType(size_t drawBuffer) const
+{
+ const FramebufferAttachment *attachment = mState.getDrawBuffer(drawBuffer);
+ if (attachment == nullptr)
+ {
+ return ComponentType::NoType;
+ }
+
+ GLenum componentType = attachment->getFormat().info->componentType;
+ switch (componentType)
+ {
+ case GL_INT:
+ return ComponentType::Int;
+ case GL_UNSIGNED_INT:
+ return ComponentType::UnsignedInt;
+
+ default:
+ return ComponentType::Float;
+ }
+}
+
+ComponentTypeMask Framebuffer::getDrawBufferTypeMask() const
+{
+ return mState.mDrawBufferTypeMask;
+}
+
+DrawBufferMask Framebuffer::getDrawBufferMask() const
+{
+ return mState.mEnabledDrawBuffers;
+}
+
+bool Framebuffer::hasEnabledDrawBuffer() const
+{
+ for (size_t drawbufferIdx = 0; drawbufferIdx < mState.mDrawBufferStates.size(); ++drawbufferIdx)
+ {
+ if (getDrawBuffer(drawbufferIdx) != nullptr)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+GLenum Framebuffer::getReadBufferState() const
+{
+ return mState.mReadBufferState;
+}
+
+void Framebuffer::setReadBuffer(GLenum buffer)
+{
+ ASSERT(buffer == GL_BACK || buffer == GL_NONE ||
+ (buffer >= GL_COLOR_ATTACHMENT0 &&
+ (buffer - GL_COLOR_ATTACHMENT0) < mState.mColorAttachments.size()));
+ if (mState.mReadBufferState != buffer)
+ {
+ mState.mReadBufferState = buffer;
+ mDirtyBits.set(DIRTY_BIT_READ_BUFFER);
+ }
+}
+
+size_t Framebuffer::getNumColorAttachments() const
+{
+ return mState.mColorAttachments.size();
+}
+
+bool Framebuffer::hasDepth() const
+{
+ return mState.hasDepth();
+}
+
+bool Framebuffer::hasStencil() const
+{
+ return mState.hasStencil();
+}
+
+bool Framebuffer::hasExternalTextureAttachment() const
+{
+ return mState.hasExternalTextureAttachment();
+}
+
+bool Framebuffer::hasYUVAttachment() const
+{
+ return mState.hasYUVAttachment();
+}
+
+bool Framebuffer::usingExtendedDrawBuffers() const
+{
+ for (size_t drawbufferIdx = 1; drawbufferIdx < mState.mDrawBufferStates.size(); ++drawbufferIdx)
+ {
+ if (getDrawBuffer(drawbufferIdx) != nullptr)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void Framebuffer::invalidateCompletenessCache()
+{
+ if (!isDefault())
+ {
+ mCachedStatus.reset();
+ }
+ onStateChange(angle::SubjectMessage::DirtyBitsFlagged);
+}
+
+const FramebufferStatus &Framebuffer::checkStatusImpl(const Context *context) const
+{
+ ASSERT(!isDefault());
+ ASSERT(hasAnyDirtyBit() || !mCachedStatus.valid());
+
+ mCachedStatus = checkStatusWithGLFrontEnd(context);
+
+ if (mCachedStatus.value().isComplete())
+ {
+ // We can skip syncState on several back-ends.
+ if (mImpl->shouldSyncStateBeforeCheckStatus())
+ {
+ // This binding is not totally correct. It is ok because the parameter isn't used in
+ // the GL back-end and the GL back-end is the only user of syncStateBeforeCheckStatus.
+ angle::Result err = syncState(context, GL_FRAMEBUFFER, Command::Other);
+ if (err != angle::Result::Continue)
+ {
+ mCachedStatus =
+ FramebufferStatus::Incomplete(0, err::kFramebufferIncompleteInternalError);
+ return mCachedStatus.value();
+ }
+ }
+
+ mCachedStatus = mImpl->checkStatus(context);
+ }
+
+ return mCachedStatus.value();
+}
+
+FramebufferStatus Framebuffer::checkStatusWithGLFrontEnd(const Context *context) const
+{
+ const State &state = context->getState();
+
+ ASSERT(!isDefault());
+
+ bool hasAttachments = false;
+ Optional<unsigned int> colorbufferSize;
+ Optional<int> samples;
+ Optional<bool> fixedSampleLocations;
+ bool hasRenderbuffer = false;
+ Optional<int> renderToTextureSamples;
+
+ const FramebufferAttachment *firstAttachment = getFirstNonNullAttachment();
+
+ Optional<bool> isLayered;
+ Optional<TextureType> colorAttachmentsTextureType;
+
+ for (const FramebufferAttachment &colorAttachment : mState.mColorAttachments)
+ {
+ if (colorAttachment.isAttached())
+ {
+ FramebufferStatus attachmentCompleteness =
+ CheckAttachmentCompleteness(context, colorAttachment);
+ if (!attachmentCompleteness.isComplete())
+ {
+ return attachmentCompleteness;
+ }
+
+ const InternalFormat &format = *colorAttachment.getFormat().info;
+ if (format.depthBits > 0 || format.stencilBits > 0)
+ {
+ return FramebufferStatus::Incomplete(
+ GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
+ err::kFramebufferIncompleteDepthStencilInColorBuffer);
+ }
+
+ FramebufferStatus attachmentSampleCompleteness =
+ CheckAttachmentSampleCompleteness(context, colorAttachment, true, &samples,
+ &fixedSampleLocations, &renderToTextureSamples);
+ if (!attachmentSampleCompleteness.isComplete())
+ {
+ return attachmentSampleCompleteness;
+ }
+
+ // 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.getClientMajorVersion() < 3)
+ {
+ if (colorbufferSize.valid())
+ {
+ if (format.pixelBytes != colorbufferSize.value())
+ {
+ return FramebufferStatus::Incomplete(
+ GL_FRAMEBUFFER_UNSUPPORTED,
+ err::kFramebufferIncompleteAttachmentInconsistantBitPlanes);
+ }
+ }
+ else
+ {
+ colorbufferSize = format.pixelBytes;
+ }
+ }
+
+ FramebufferStatus attachmentMultiviewCompleteness =
+ CheckMultiviewStateMatchesForCompleteness(firstAttachment, &colorAttachment);
+ if (!attachmentMultiviewCompleteness.isComplete())
+ {
+ return attachmentMultiviewCompleteness;
+ }
+
+ hasRenderbuffer = hasRenderbuffer || (colorAttachment.type() == GL_RENDERBUFFER);
+
+ if (!hasAttachments)
+ {
+ isLayered = colorAttachment.isLayered();
+ if (isLayered.value())
+ {
+ colorAttachmentsTextureType = colorAttachment.getTextureImageIndex().getType();
+ }
+ hasAttachments = true;
+ }
+ else
+ {
+ // [EXT_geometry_shader] section 9.4.1, "Framebuffer Completeness"
+ // If any framebuffer attachment is layered, all populated attachments
+ // must be layered. Additionally, all populated color attachments must
+ // be from textures of the same target. {FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT }
+ ASSERT(isLayered.valid());
+ if (isLayered.value() != colorAttachment.isLayered())
+ {
+ return FramebufferStatus::Incomplete(
+ GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT,
+ err::kFramebufferIncompleteMismatchedLayeredAttachments);
+ }
+ else if (isLayered.value())
+ {
+ ASSERT(colorAttachmentsTextureType.valid());
+ if (colorAttachmentsTextureType.value() !=
+ colorAttachment.getTextureImageIndex().getType())
+ {
+ return FramebufferStatus::Incomplete(
+ GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT,
+ err::kFramebufferIncompleteMismatchedLayeredTexturetypes);
+ }
+ }
+ }
+ }
+ }
+
+ const FramebufferAttachment &depthAttachment = mState.mDepthAttachment;
+ if (depthAttachment.isAttached())
+ {
+ FramebufferStatus attachmentCompleteness =
+ CheckAttachmentCompleteness(context, depthAttachment);
+ if (!attachmentCompleteness.isComplete())
+ {
+ return attachmentCompleteness;
+ }
+
+ const InternalFormat &format = *depthAttachment.getFormat().info;
+ if (format.depthBits == 0)
+ {
+ return FramebufferStatus::Incomplete(
+ GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
+ err::kFramebufferIncompleteAttachmentNoDepthBitsInDepthBuffer);
+ }
+
+ FramebufferStatus attachmentSampleCompleteness =
+ CheckAttachmentSampleCompleteness(context, depthAttachment, false, &samples,
+ &fixedSampleLocations, &renderToTextureSamples);
+ if (!attachmentSampleCompleteness.isComplete())
+ {
+ return attachmentSampleCompleteness;
+ }
+
+ FramebufferStatus attachmentMultiviewCompleteness =
+ CheckMultiviewStateMatchesForCompleteness(firstAttachment, &depthAttachment);
+ if (!attachmentMultiviewCompleteness.isComplete())
+ {
+ return attachmentMultiviewCompleteness;
+ }
+
+ hasRenderbuffer = hasRenderbuffer || (depthAttachment.type() == GL_RENDERBUFFER);
+
+ if (!hasAttachments)
+ {
+ isLayered = depthAttachment.isLayered();
+ hasAttachments = true;
+ }
+ else
+ {
+ // [EXT_geometry_shader] section 9.4.1, "Framebuffer Completeness"
+ // If any framebuffer attachment is layered, all populated attachments
+ // must be layered. {FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT }
+ ASSERT(isLayered.valid());
+ if (isLayered.value() != depthAttachment.isLayered())
+ {
+ return FramebufferStatus::Incomplete(
+ GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT,
+ err::kFramebufferIncompleteMismatchedLayeredAttachments);
+ }
+ }
+ }
+
+ const FramebufferAttachment &stencilAttachment = mState.mStencilAttachment;
+ if (stencilAttachment.isAttached())
+ {
+ FramebufferStatus attachmentCompleteness =
+ CheckAttachmentCompleteness(context, stencilAttachment);
+ if (!attachmentCompleteness.isComplete())
+ {
+ return attachmentCompleteness;
+ }
+
+ const InternalFormat &format = *stencilAttachment.getFormat().info;
+ if (format.stencilBits == 0)
+ {
+ return FramebufferStatus::Incomplete(
+ GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
+ err::kFramebufferIncompleteAttachmentNoStencilBitsInStencilBuffer);
+ }
+
+ FramebufferStatus attachmentSampleCompleteness =
+ CheckAttachmentSampleCompleteness(context, stencilAttachment, false, &samples,
+ &fixedSampleLocations, &renderToTextureSamples);
+ if (!attachmentSampleCompleteness.isComplete())
+ {
+ return attachmentSampleCompleteness;
+ }
+
+ FramebufferStatus attachmentMultiviewCompleteness =
+ CheckMultiviewStateMatchesForCompleteness(firstAttachment, &stencilAttachment);
+ if (!attachmentMultiviewCompleteness.isComplete())
+ {
+ return attachmentMultiviewCompleteness;
+ }
+
+ hasRenderbuffer = hasRenderbuffer || (stencilAttachment.type() == GL_RENDERBUFFER);
+
+ if (!hasAttachments)
+ {
+ hasAttachments = true;
+ }
+ else
+ {
+ // [EXT_geometry_shader] section 9.4.1, "Framebuffer Completeness"
+ // If any framebuffer attachment is layered, all populated attachments
+ // must be layered.
+ // {FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT }
+ ASSERT(isLayered.valid());
+ if (isLayered.value() != stencilAttachment.isLayered())
+ {
+ return FramebufferStatus::Incomplete(
+ GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT,
+ err::kFramebufferIncompleteMismatchedLayeredAttachments);
+ }
+ }
+ }
+
+ // Starting from ES 3.0 stencil and depth, if present, should be the same image
+ if (state.getClientMajorVersion() >= 3 && depthAttachment.isAttached() &&
+ stencilAttachment.isAttached() && stencilAttachment != depthAttachment)
+ {
+ return FramebufferStatus::Incomplete(
+ GL_FRAMEBUFFER_UNSUPPORTED,
+ err::kFramebufferIncompleteDepthAndStencilBuffersNotTheSame);
+ }
+
+ // Special additional validation for WebGL 1 DEPTH/STENCIL/DEPTH_STENCIL.
+ if (state.isWebGL1())
+ {
+ if (!mState.mWebGLDepthStencilConsistent)
+ {
+ return FramebufferStatus::Incomplete(
+ GL_FRAMEBUFFER_UNSUPPORTED,
+ err::kFramebufferIncompleteWebGLDepthStencilInconsistant);
+ }
+
+ if (mState.mWebGLDepthStencilAttachment.isAttached())
+ {
+ if (mState.mWebGLDepthStencilAttachment.getDepthSize() == 0 ||
+ mState.mWebGLDepthStencilAttachment.getStencilSize() == 0)
+ {
+ return FramebufferStatus::Incomplete(
+ GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
+ err::kFramebufferIncompleteAttachmentWebGLDepthStencilNoDepthOrStencilBits);
+ }
+
+ FramebufferStatus attachmentMultiviewCompleteness =
+ CheckMultiviewStateMatchesForCompleteness(firstAttachment,
+ &mState.mWebGLDepthStencilAttachment);
+ if (!attachmentMultiviewCompleteness.isComplete())
+ {
+ return attachmentMultiviewCompleteness;
+ }
+ }
+ else if (mState.mStencilAttachment.isAttached() &&
+ mState.mStencilAttachment.getDepthSize() > 0)
+ {
+ return FramebufferStatus::Incomplete(
+ GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
+ err::kFramebufferIncompleteAttachmentWebGLStencilBufferHasDepthBits);
+ }
+ else if (mState.mDepthAttachment.isAttached() &&
+ mState.mDepthAttachment.getStencilSize() > 0)
+ {
+ return FramebufferStatus::Incomplete(
+ GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
+ err::kFramebufferIncompleteAttachmentWebGLDepthBufferHasStencilBits);
+ }
+ }
+
+ // ES3.1(section 9.4) requires that if no image is attached to the framebuffer, and either the
+ // value of the framebuffer's FRAMEBUFFER_DEFAULT_WIDTH or FRAMEBUFFER_DEFAULT_HEIGHT parameters
+ // is zero, the framebuffer is considered incomplete.
+ GLint defaultWidth = mState.getDefaultWidth();
+ GLint defaultHeight = mState.getDefaultHeight();
+ if (!hasAttachments && (defaultWidth == 0 || defaultHeight == 0))
+ {
+ return FramebufferStatus::Incomplete(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT,
+ err::kFramebufferIncompleteDefaultZeroSize);
+ }
+
+ // In ES 2.0 and WebGL, all color attachments must have the same width and height.
+ // In ES 3.0, there is no such restriction.
+ if ((state.getClientMajorVersion() < 3 || state.getExtensions().webglCompatibilityANGLE) &&
+ !mState.attachmentsHaveSameDimensions())
+ {
+ return FramebufferStatus::Incomplete(
+ GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS,
+ err::kFramebufferIncompleteInconsistantAttachmentSizes);
+ }
+
+ // ES3.1(section 9.4) requires that if the attached images are a mix of renderbuffers and
+ // textures, the value of TEXTURE_FIXED_SAMPLE_LOCATIONS must be TRUE for all attached textures.
+ if (fixedSampleLocations.valid() && hasRenderbuffer && !fixedSampleLocations.value())
+ {
+ return FramebufferStatus::Incomplete(
+ GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,
+ err::kFramebufferIncompleteMultisampleNonFixedSamplesWithRenderbuffers);
+ }
+
+ // The WebGL conformance tests implicitly define that all framebuffer
+ // attachments must be unique. For example, the same level of a texture can
+ // not be attached to two different color attachments.
+ if (state.getExtensions().webglCompatibilityANGLE)
+ {
+ if (!mState.colorAttachmentsAreUniqueImages())
+ {
+ return FramebufferStatus::Incomplete(GL_FRAMEBUFFER_UNSUPPORTED,
+ err::kFramebufferIncompleteAttachmentsNotUnique);
+ }
+ }
+
+ return FramebufferStatus::Complete();
+}
+
+angle::Result Framebuffer::discard(const Context *context, size_t count, const GLenum *attachments)
+{
+ // Back-ends might make the contents of the FBO undefined. In WebGL 2.0, invalidate operations
+ // can be no-ops, so we should probably do that to ensure consistency.
+ // TODO(jmadill): WebGL behaviour, and robust resource init behaviour without WebGL.
+
+ return mImpl->discard(context, count, attachments);
+}
+
+angle::Result Framebuffer::invalidate(const Context *context,
+ size_t count,
+ const GLenum *attachments)
+{
+ // Back-ends might make the contents of the FBO undefined. In WebGL 2.0, invalidate operations
+ // can be no-ops, so we should probably do that to ensure consistency.
+ // TODO(jmadill): WebGL behaviour, and robust resource init behaviour without WebGL.
+
+ return mImpl->invalidate(context, count, attachments);
+}
+
+bool Framebuffer::partialClearNeedsInit(const Context *context,
+ bool color,
+ bool depth,
+ bool stencil)
+{
+ const auto &glState = context->getState();
+
+ if (!glState.isRobustResourceInitEnabled())
+ {
+ return false;
+ }
+
+ if (depth && context->getFrontendFeatures().forceDepthAttachmentInitOnClear.enabled)
+ {
+ return true;
+ }
+
+ // Scissors can affect clearing.
+ // TODO(jmadill): Check for complete scissor overlap.
+ if (glState.isScissorTestEnabled())
+ {
+ return true;
+ }
+
+ // If colors masked, we must clear before we clear. Do a simple check.
+ // TODO(jmadill): Filter out unused color channels from the test.
+ if (color && glState.anyActiveDrawBufferChannelMasked())
+ {
+ return true;
+ }
+
+ const auto &depthStencil = glState.getDepthStencilState();
+ if (stencil && (depthStencil.stencilMask != depthStencil.stencilWritemask ||
+ depthStencil.stencilBackMask != depthStencil.stencilBackWritemask))
+ {
+ return true;
+ }
+
+ return false;
+}
+
+angle::Result Framebuffer::invalidateSub(const Context *context,
+ size_t count,
+ const GLenum *attachments,
+ const Rectangle &area)
+{
+ // Back-ends might make the contents of the FBO undefined. In WebGL 2.0, invalidate operations
+ // can be no-ops, so we should probably do that to ensure consistency.
+ // TODO(jmadill): Make a invalidate no-op in WebGL 2.0.
+
+ return mImpl->invalidateSub(context, count, attachments, area);
+}
+
+angle::Result Framebuffer::clear(const Context *context, GLbitfield mask)
+{
+ ASSERT(mask && !context->getState().isRasterizerDiscardEnabled());
+
+ return mImpl->clear(context, mask);
+}
+
+angle::Result Framebuffer::clearBufferfv(const Context *context,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLfloat *values)
+{
+ return mImpl->clearBufferfv(context, buffer, drawbuffer, values);
+}
+
+angle::Result Framebuffer::clearBufferuiv(const Context *context,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLuint *values)
+{
+ return mImpl->clearBufferuiv(context, buffer, drawbuffer, values);
+}
+
+angle::Result Framebuffer::clearBufferiv(const Context *context,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLint *values)
+{
+ return mImpl->clearBufferiv(context, buffer, drawbuffer, values);
+}
+
+angle::Result Framebuffer::clearBufferfi(const Context *context,
+ GLenum buffer,
+ GLint drawbuffer,
+ GLfloat depth,
+ GLint stencil)
+{
+ const bool clearDepth =
+ getDepthAttachment() != nullptr && context->getState().getDepthStencilState().depthMask;
+ const bool clearStencil = getStencilAttachment() != nullptr &&
+ context->getState().getDepthStencilState().stencilWritemask != 0;
+
+ if (clearDepth && clearStencil)
+ {
+ ASSERT(buffer == GL_DEPTH_STENCIL);
+ ANGLE_TRY(mImpl->clearBufferfi(context, GL_DEPTH_STENCIL, drawbuffer, depth, stencil));
+ }
+ else if (clearDepth && !clearStencil)
+ {
+ ANGLE_TRY(mImpl->clearBufferfv(context, GL_DEPTH, drawbuffer, &depth));
+ }
+ else if (!clearDepth && clearStencil)
+ {
+ ANGLE_TRY(mImpl->clearBufferiv(context, GL_STENCIL, drawbuffer, &stencil));
+ }
+
+ return angle::Result::Continue;
+}
+
+GLenum Framebuffer::getImplementationColorReadFormat(const Context *context)
+{
+ const gl::InternalFormat &format = mImpl->getImplementationColorReadFormat(context);
+ return format.getReadPixelsFormat(context->getExtensions());
+}
+
+GLenum Framebuffer::getImplementationColorReadType(const Context *context)
+{
+ const gl::InternalFormat &format = mImpl->getImplementationColorReadFormat(context);
+ return format.getReadPixelsType(context->getClientVersion());
+}
+
+angle::Result Framebuffer::readPixels(const Context *context,
+ const Rectangle &area,
+ GLenum format,
+ GLenum type,
+ const PixelPackState &pack,
+ Buffer *packBuffer,
+ void *pixels)
+{
+ ANGLE_TRY(mImpl->readPixels(context, area, format, type, pack, packBuffer, pixels));
+
+ if (packBuffer)
+ {
+ packBuffer->onDataChanged();
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result Framebuffer::blit(const Context *context,
+ const Rectangle &sourceArea,
+ const Rectangle &destArea,
+ GLbitfield mask,
+ GLenum filter)
+{
+ ASSERT(mask != 0);
+
+ ANGLE_TRY(mImpl->blit(context, sourceArea, destArea, mask, filter));
+
+ // Mark the contents of the attachments dirty
+ if ((mask & GL_COLOR_BUFFER_BIT) != 0)
+ {
+ for (size_t colorIndex : mState.mEnabledDrawBuffers)
+ {
+ mDirtyBits.set(DIRTY_BIT_COLOR_BUFFER_CONTENTS_0 + colorIndex);
+ }
+ }
+ if ((mask & GL_DEPTH_BUFFER_BIT) != 0)
+ {
+ mDirtyBits.set(DIRTY_BIT_DEPTH_BUFFER_CONTENTS);
+ }
+ if ((mask & GL_STENCIL_BUFFER_BIT) != 0)
+ {
+ mDirtyBits.set(DIRTY_BIT_STENCIL_BUFFER_CONTENTS);
+ }
+ onStateChange(angle::SubjectMessage::DirtyBitsFlagged);
+
+ return angle::Result::Continue;
+}
+
+int Framebuffer::getSamples(const Context *context) const
+{
+ if (!isComplete(context))
+ {
+ return 0;
+ }
+
+ ASSERT(mCachedStatus.valid() && mCachedStatus.value().isComplete());
+
+ // For a complete framebuffer, all attachments must have the same sample count.
+ // In this case return the first nonzero sample size.
+ const FramebufferAttachment *firstNonNullAttachment = mState.getFirstNonNullAttachment();
+ ASSERT(firstNonNullAttachment == nullptr || firstNonNullAttachment->isAttached());
+
+ return firstNonNullAttachment ? firstNonNullAttachment->getSamples() : 0;
+}
+
+int Framebuffer::getReadBufferResourceSamples(const Context *context) const
+{
+ if (!isComplete(context))
+ {
+ return 0;
+ }
+
+ ASSERT(mCachedStatus.valid() && mCachedStatus.value().isComplete());
+
+ const FramebufferAttachment *readAttachment = mState.getReadAttachment();
+ ASSERT(readAttachment == nullptr || readAttachment->isAttached());
+
+ return readAttachment ? readAttachment->getResourceSamples() : 0;
+}
+
+angle::Result Framebuffer::getSamplePosition(const Context *context,
+ size_t index,
+ GLfloat *xy) const
+{
+ ANGLE_TRY(mImpl->getSamplePosition(context, index, xy));
+ return angle::Result::Continue;
+}
+
+bool Framebuffer::hasValidDepthStencil() const
+{
+ return mState.getDepthStencilAttachment() != nullptr;
+}
+
+const gl::Offset &Framebuffer::getSurfaceTextureOffset() const
+{
+ return mState.getSurfaceTextureOffset();
+}
+
+void Framebuffer::setAttachment(const Context *context,
+ GLenum type,
+ GLenum binding,
+ const ImageIndex &textureIndex,
+ FramebufferAttachmentObject *resource)
+{
+ setAttachment(context, type, binding, textureIndex, resource,
+ FramebufferAttachment::kDefaultNumViews,
+ FramebufferAttachment::kDefaultBaseViewIndex, false,
+ FramebufferAttachment::kDefaultRenderToTextureSamples);
+}
+
+void Framebuffer::setAttachmentMultisample(const Context *context,
+ GLenum type,
+ GLenum binding,
+ const ImageIndex &textureIndex,
+ FramebufferAttachmentObject *resource,
+ GLsizei samples)
+{
+ setAttachment(context, type, binding, textureIndex, resource,
+ FramebufferAttachment::kDefaultNumViews,
+ FramebufferAttachment::kDefaultBaseViewIndex, false, samples);
+}
+
+void Framebuffer::setAttachment(const Context *context,
+ GLenum type,
+ GLenum binding,
+ const ImageIndex &textureIndex,
+ FramebufferAttachmentObject *resource,
+ GLsizei numViews,
+ GLuint baseViewIndex,
+ bool isMultiview,
+ GLsizei samplesIn)
+{
+ GLsizei samples = samplesIn;
+ // Match the sample count to the attachment's sample count.
+ if (resource)
+ {
+ const InternalFormat *info = resource->getAttachmentFormat(binding, textureIndex).info;
+ ASSERT(info);
+ GLenum sizedInternalFormat = info->sizedInternalFormat;
+ const TextureCaps &formatCaps = context->getTextureCaps().get(sizedInternalFormat);
+ samples = formatCaps.getNearestSamples(samples);
+ }
+
+ // Context may be null in unit tests.
+ if (!context || !context->isWebGL1())
+ {
+ setAttachmentImpl(context, type, binding, textureIndex, resource, numViews, baseViewIndex,
+ isMultiview, samples);
+ return;
+ }
+
+ switch (binding)
+ {
+ case GL_DEPTH_STENCIL:
+ case GL_DEPTH_STENCIL_ATTACHMENT:
+ mState.mWebGLDepthStencilAttachment.attach(
+ context, type, binding, textureIndex, resource, numViews, baseViewIndex,
+ isMultiview, samples, mState.mFramebufferSerial);
+ break;
+ case GL_DEPTH:
+ case GL_DEPTH_ATTACHMENT:
+ mState.mWebGLDepthAttachment.attach(context, type, binding, textureIndex, resource,
+ numViews, baseViewIndex, isMultiview, samples,
+ mState.mFramebufferSerial);
+ break;
+ case GL_STENCIL:
+ case GL_STENCIL_ATTACHMENT:
+ mState.mWebGLStencilAttachment.attach(context, type, binding, textureIndex, resource,
+ numViews, baseViewIndex, isMultiview, samples,
+ mState.mFramebufferSerial);
+ break;
+ default:
+ setAttachmentImpl(context, type, binding, textureIndex, resource, numViews,
+ baseViewIndex, isMultiview, samples);
+ return;
+ }
+
+ commitWebGL1DepthStencilIfConsistent(context, numViews, baseViewIndex, isMultiview, samples);
+}
+
+void Framebuffer::setAttachmentMultiview(const Context *context,
+ GLenum type,
+ GLenum binding,
+ const ImageIndex &textureIndex,
+ FramebufferAttachmentObject *resource,
+ GLsizei numViews,
+ GLint baseViewIndex)
+{
+ setAttachment(context, type, binding, textureIndex, resource, numViews, baseViewIndex, true,
+ FramebufferAttachment::kDefaultRenderToTextureSamples);
+}
+
+void Framebuffer::commitWebGL1DepthStencilIfConsistent(const Context *context,
+ GLsizei numViews,
+ GLuint baseViewIndex,
+ bool isMultiview,
+ GLsizei samples)
+{
+ int count = 0;
+
+ std::array<FramebufferAttachment *, 3> attachments = {{&mState.mWebGLDepthStencilAttachment,
+ &mState.mWebGLDepthAttachment,
+ &mState.mWebGLStencilAttachment}};
+ for (FramebufferAttachment *attachment : attachments)
+ {
+ if (attachment->isAttached())
+ {
+ count++;
+ }
+ }
+
+ mState.mWebGLDepthStencilConsistent = (count <= 1);
+ if (!mState.mWebGLDepthStencilConsistent)
+ {
+ // Inconsistent.
+ return;
+ }
+
+ auto getImageIndexIfTextureAttachment = [](const FramebufferAttachment &attachment) {
+ if (attachment.type() == GL_TEXTURE)
+ {
+ return attachment.getTextureImageIndex();
+ }
+ else
+ {
+ return ImageIndex();
+ }
+ };
+
+ if (mState.mWebGLDepthAttachment.isAttached())
+ {
+ const auto &depth = mState.mWebGLDepthAttachment;
+ setAttachmentImpl(context, depth.type(), GL_DEPTH_ATTACHMENT,
+ getImageIndexIfTextureAttachment(depth), depth.getResource(), numViews,
+ baseViewIndex, isMultiview, samples);
+ setAttachmentImpl(context, GL_NONE, GL_STENCIL_ATTACHMENT, ImageIndex(), nullptr, numViews,
+ baseViewIndex, isMultiview, samples);
+ }
+ else if (mState.mWebGLStencilAttachment.isAttached())
+ {
+ const auto &stencil = mState.mWebGLStencilAttachment;
+ setAttachmentImpl(context, GL_NONE, GL_DEPTH_ATTACHMENT, ImageIndex(), nullptr, numViews,
+ baseViewIndex, isMultiview, samples);
+ setAttachmentImpl(context, stencil.type(), GL_STENCIL_ATTACHMENT,
+ getImageIndexIfTextureAttachment(stencil), stencil.getResource(),
+ numViews, baseViewIndex, isMultiview, samples);
+ }
+ else if (mState.mWebGLDepthStencilAttachment.isAttached())
+ {
+ const auto &depthStencil = mState.mWebGLDepthStencilAttachment;
+ setAttachmentImpl(context, depthStencil.type(), GL_DEPTH_ATTACHMENT,
+ getImageIndexIfTextureAttachment(depthStencil),
+ depthStencil.getResource(), numViews, baseViewIndex, isMultiview,
+ samples);
+ setAttachmentImpl(context, depthStencil.type(), GL_STENCIL_ATTACHMENT,
+ getImageIndexIfTextureAttachment(depthStencil),
+ depthStencil.getResource(), numViews, baseViewIndex, isMultiview,
+ samples);
+ }
+ else
+ {
+ setAttachmentImpl(context, GL_NONE, GL_DEPTH_ATTACHMENT, ImageIndex(), nullptr, numViews,
+ baseViewIndex, isMultiview, samples);
+ setAttachmentImpl(context, GL_NONE, GL_STENCIL_ATTACHMENT, ImageIndex(), nullptr, numViews,
+ baseViewIndex, isMultiview, samples);
+ }
+}
+
+void Framebuffer::setAttachmentImpl(const Context *context,
+ GLenum type,
+ GLenum binding,
+ const ImageIndex &textureIndex,
+ FramebufferAttachmentObject *resource,
+ GLsizei numViews,
+ GLuint baseViewIndex,
+ bool isMultiview,
+ GLsizei samples)
+{
+ switch (binding)
+ {
+ case GL_DEPTH_STENCIL:
+ case GL_DEPTH_STENCIL_ATTACHMENT:
+ updateAttachment(context, &mState.mDepthAttachment, DIRTY_BIT_DEPTH_ATTACHMENT,
+ &mDirtyDepthAttachmentBinding, type, binding, textureIndex, resource,
+ numViews, baseViewIndex, isMultiview, samples);
+ updateAttachment(context, &mState.mStencilAttachment, DIRTY_BIT_STENCIL_ATTACHMENT,
+ &mDirtyStencilAttachmentBinding, type, binding, textureIndex, resource,
+ numViews, baseViewIndex, isMultiview, samples);
+ break;
+
+ case GL_DEPTH:
+ case GL_DEPTH_ATTACHMENT:
+ updateAttachment(context, &mState.mDepthAttachment, DIRTY_BIT_DEPTH_ATTACHMENT,
+ &mDirtyDepthAttachmentBinding, type, binding, textureIndex, resource,
+ numViews, baseViewIndex, isMultiview, samples);
+ break;
+
+ case GL_STENCIL:
+ case GL_STENCIL_ATTACHMENT:
+ updateAttachment(context, &mState.mStencilAttachment, DIRTY_BIT_STENCIL_ATTACHMENT,
+ &mDirtyStencilAttachmentBinding, type, binding, textureIndex, resource,
+ numViews, baseViewIndex, isMultiview, samples);
+ break;
+
+ case GL_BACK:
+ updateAttachment(context, &mState.mColorAttachments[0], DIRTY_BIT_COLOR_ATTACHMENT_0,
+ &mDirtyColorAttachmentBindings[0], type, binding, textureIndex,
+ resource, numViews, baseViewIndex, isMultiview, samples);
+ mState.mColorAttachmentsMask.set(0);
+
+ break;
+
+ default:
+ {
+ size_t colorIndex = binding - GL_COLOR_ATTACHMENT0;
+ ASSERT(colorIndex < mState.mColorAttachments.size());
+ size_t dirtyBit = DIRTY_BIT_COLOR_ATTACHMENT_0 + colorIndex;
+ updateAttachment(context, &mState.mColorAttachments[colorIndex], dirtyBit,
+ &mDirtyColorAttachmentBindings[colorIndex], type, binding,
+ textureIndex, resource, numViews, baseViewIndex, isMultiview, samples);
+
+ if (!resource)
+ {
+ mFloat32ColorAttachmentBits.reset(colorIndex);
+ mState.mColorAttachmentsMask.reset(colorIndex);
+ }
+ else
+ {
+ updateFloat32ColorAttachmentBits(
+ colorIndex, resource->getAttachmentFormat(binding, textureIndex).info);
+ mState.mColorAttachmentsMask.set(colorIndex);
+ }
+
+ bool enabled = (type != GL_NONE && getDrawBufferState(colorIndex) != GL_NONE);
+ mState.mEnabledDrawBuffers.set(colorIndex, enabled);
+ SetComponentTypeMask(getDrawbufferWriteType(colorIndex), colorIndex,
+ &mState.mDrawBufferTypeMask);
+ }
+ break;
+ }
+}
+
+void Framebuffer::updateAttachment(const Context *context,
+ FramebufferAttachment *attachment,
+ size_t dirtyBit,
+ angle::ObserverBinding *onDirtyBinding,
+ GLenum type,
+ GLenum binding,
+ const ImageIndex &textureIndex,
+ FramebufferAttachmentObject *resource,
+ GLsizei numViews,
+ GLuint baseViewIndex,
+ bool isMultiview,
+ GLsizei samples)
+{
+ attachment->attach(context, type, binding, textureIndex, resource, numViews, baseViewIndex,
+ isMultiview, samples, mState.mFramebufferSerial);
+ mDirtyBits.set(dirtyBit);
+ mState.mResourceNeedsInit.set(dirtyBit, attachment->initState() == InitState::MayNeedInit);
+ onDirtyBinding->bind(resource);
+
+ invalidateCompletenessCache();
+}
+
+void Framebuffer::resetAttachment(const Context *context, GLenum binding)
+{
+ setAttachment(context, GL_NONE, binding, ImageIndex(), nullptr);
+}
+
+void Framebuffer::setWriteControlMode(SrgbWriteControlMode srgbWriteControlMode)
+{
+ if (srgbWriteControlMode != mState.getWriteControlMode())
+ {
+ mState.mSrgbWriteControlMode = srgbWriteControlMode;
+ mDirtyBits.set(DIRTY_BIT_FRAMEBUFFER_SRGB_WRITE_CONTROL_MODE);
+ }
+}
+
+angle::Result Framebuffer::syncState(const Context *context,
+ GLenum framebufferBinding,
+ Command command) const
+{
+ if (mDirtyBits.any())
+ {
+ mDirtyBitsGuard = mDirtyBits;
+ ANGLE_TRY(mImpl->syncState(context, framebufferBinding, mDirtyBits, command));
+ mDirtyBits.reset();
+ mDirtyBitsGuard.reset();
+ }
+ return angle::Result::Continue;
+}
+
+void Framebuffer::onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message)
+{
+ if (message != angle::SubjectMessage::SubjectChanged)
+ {
+ // This can be triggered by SubImage calls for Textures.
+ if (message == angle::SubjectMessage::ContentsChanged)
+ {
+ mDirtyBits.set(DIRTY_BIT_COLOR_BUFFER_CONTENTS_0 + index);
+ onStateChange(angle::SubjectMessage::DirtyBitsFlagged);
+ return;
+ }
+
+ // Swapchain changes should only result in color buffer changes.
+ if (message == angle::SubjectMessage::SwapchainImageChanged)
+ {
+ if (index < DIRTY_BIT_COLOR_ATTACHMENT_MAX)
+ {
+ mDirtyBits.set(DIRTY_BIT_COLOR_BUFFER_CONTENTS_0 + index);
+ onStateChange(angle::SubjectMessage::DirtyBitsFlagged);
+ }
+ return;
+ }
+
+ ASSERT(message != angle::SubjectMessage::BindingChanged);
+
+ // This can be triggered by external changes to the default framebuffer.
+ if (message == angle::SubjectMessage::SurfaceChanged)
+ {
+ onStateChange(angle::SubjectMessage::SurfaceChanged);
+ return;
+ }
+
+ // This can be triggered by freeing TextureStorage in D3D back-end.
+ if (message == angle::SubjectMessage::StorageReleased)
+ {
+ mDirtyBits.set(index);
+ invalidateCompletenessCache();
+ return;
+ }
+
+ // This can be triggered by the GL back-end TextureGL class.
+ ASSERT(message == angle::SubjectMessage::DirtyBitsFlagged);
+ return;
+ }
+
+ ASSERT(!mDirtyBitsGuard.valid() || mDirtyBitsGuard.value().test(index));
+ mDirtyBits.set(index);
+
+ invalidateCompletenessCache();
+
+ FramebufferAttachment *attachment = getAttachmentFromSubjectIndex(index);
+
+ // Mark the appropriate init flag.
+ mState.mResourceNeedsInit.set(index, attachment->initState() == InitState::MayNeedInit);
+
+ // Update mFloat32ColorAttachmentBits Cache
+ if (index < DIRTY_BIT_COLOR_ATTACHMENT_MAX)
+ {
+ ASSERT(index != DIRTY_BIT_DEPTH_ATTACHMENT);
+ ASSERT(index != DIRTY_BIT_STENCIL_ATTACHMENT);
+ updateFloat32ColorAttachmentBits(index - DIRTY_BIT_COLOR_ATTACHMENT_0,
+ attachment->getFormat().info);
+ }
+}
+
+FramebufferAttachment *Framebuffer::getAttachmentFromSubjectIndex(angle::SubjectIndex index)
+{
+ switch (index)
+ {
+ case DIRTY_BIT_DEPTH_ATTACHMENT:
+ return &mState.mDepthAttachment;
+ case DIRTY_BIT_STENCIL_ATTACHMENT:
+ return &mState.mStencilAttachment;
+ default:
+ size_t colorIndex = (index - DIRTY_BIT_COLOR_ATTACHMENT_0);
+ ASSERT(colorIndex < mState.mColorAttachments.size());
+ return &mState.mColorAttachments[colorIndex];
+ }
+}
+
+bool Framebuffer::formsRenderingFeedbackLoopWith(const Context *context) const
+{
+ const State &glState = context->getState();
+ const ProgramExecutable *executable = glState.getLinkedProgramExecutable(context);
+
+ // In some error cases there may be no bound program or executable.
+ if (!executable)
+ return false;
+
+ const ActiveTextureMask &activeTextures = executable->getActiveSamplersMask();
+ const ActiveTextureTypeArray &textureTypes = executable->getActiveSamplerTypes();
+
+ for (size_t textureIndex : activeTextures)
+ {
+ unsigned int uintIndex = static_cast<unsigned int>(textureIndex);
+ Texture *texture = glState.getSamplerTexture(uintIndex, textureTypes[textureIndex]);
+ const Sampler *sampler = glState.getSampler(uintIndex);
+ if (texture && texture->isSamplerComplete(context, sampler) &&
+ texture->isBoundToFramebuffer(mState.mFramebufferSerial))
+ {
+ // Check for level overlap.
+ for (const FramebufferAttachment &attachment : mState.mColorAttachments)
+ {
+ if (AttachmentOverlapsWithTexture(attachment, texture, sampler))
+ {
+ return true;
+ }
+ }
+
+ if (AttachmentOverlapsWithTexture(mState.mDepthAttachment, texture, sampler))
+ {
+ return true;
+ }
+
+ if (AttachmentOverlapsWithTexture(mState.mStencilAttachment, texture, sampler))
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+bool Framebuffer::formsCopyingFeedbackLoopWith(TextureID copyTextureID,
+ GLint copyTextureLevel,
+ GLint copyTextureLayer) const
+{
+ if (mState.isDefault())
+ {
+ // It seems impossible to form a texture copying feedback loop with the default FBO.
+ return false;
+ }
+
+ const FramebufferAttachment *readAttachment = getReadColorAttachment();
+ ASSERT(readAttachment);
+
+ if (readAttachment->isTextureWithId(copyTextureID))
+ {
+ const auto &imageIndex = readAttachment->getTextureImageIndex();
+ if (imageIndex.getLevelIndex() == copyTextureLevel)
+ {
+ // Check 3D/Array texture layers.
+ return !imageIndex.hasLayer() || copyTextureLayer == ImageIndex::kEntireLevel ||
+ imageIndex.getLayerIndex() == copyTextureLayer;
+ }
+ }
+ return false;
+}
+
+GLint Framebuffer::getDefaultWidth() const
+{
+ return mState.getDefaultWidth();
+}
+
+GLint Framebuffer::getDefaultHeight() const
+{
+ return mState.getDefaultHeight();
+}
+
+GLint Framebuffer::getDefaultSamples() const
+{
+ return mState.getDefaultSamples();
+}
+
+bool Framebuffer::getDefaultFixedSampleLocations() const
+{
+ return mState.getDefaultFixedSampleLocations();
+}
+
+GLint Framebuffer::getDefaultLayers() const
+{
+ return mState.getDefaultLayers();
+}
+
+bool Framebuffer::getFlipY() const
+{
+ return mState.getFlipY();
+}
+
+void Framebuffer::setDefaultWidth(const Context *context, GLint defaultWidth)
+{
+ mState.mDefaultWidth = defaultWidth;
+ mDirtyBits.set(DIRTY_BIT_DEFAULT_WIDTH);
+ invalidateCompletenessCache();
+}
+
+void Framebuffer::setDefaultHeight(const Context *context, GLint defaultHeight)
+{
+ mState.mDefaultHeight = defaultHeight;
+ mDirtyBits.set(DIRTY_BIT_DEFAULT_HEIGHT);
+ invalidateCompletenessCache();
+}
+
+void Framebuffer::setDefaultSamples(const Context *context, GLint defaultSamples)
+{
+ mState.mDefaultSamples = defaultSamples;
+ mDirtyBits.set(DIRTY_BIT_DEFAULT_SAMPLES);
+ invalidateCompletenessCache();
+}
+
+void Framebuffer::setDefaultFixedSampleLocations(const Context *context,
+ bool defaultFixedSampleLocations)
+{
+ mState.mDefaultFixedSampleLocations = defaultFixedSampleLocations;
+ mDirtyBits.set(DIRTY_BIT_DEFAULT_FIXED_SAMPLE_LOCATIONS);
+ invalidateCompletenessCache();
+}
+
+void Framebuffer::setDefaultLayers(GLint defaultLayers)
+{
+ mState.mDefaultLayers = defaultLayers;
+ mDirtyBits.set(DIRTY_BIT_DEFAULT_LAYERS);
+}
+
+void Framebuffer::setFlipY(bool flipY)
+{
+ mState.mFlipY = flipY;
+ mDirtyBits.set(DIRTY_BIT_FLIP_Y);
+ invalidateCompletenessCache();
+}
+
+GLsizei Framebuffer::getNumViews() const
+{
+ return mState.getNumViews();
+}
+
+GLint Framebuffer::getBaseViewIndex() const
+{
+ return mState.getBaseViewIndex();
+}
+
+bool Framebuffer::isMultiview() const
+{
+ return mState.isMultiview();
+}
+
+bool Framebuffer::readDisallowedByMultiview() const
+{
+ return (mState.isMultiview() && mState.getNumViews() > 1);
+}
+
+angle::Result Framebuffer::ensureClearAttachmentsInitialized(const Context *context,
+ GLbitfield mask)
+{
+ const auto &glState = context->getState();
+ if (!context->isRobustResourceInitEnabled() || glState.isRasterizerDiscardEnabled())
+ {
+ return angle::Result::Continue;
+ }
+
+ const DepthStencilState &depthStencil = glState.getDepthStencilState();
+
+ bool color = (mask & GL_COLOR_BUFFER_BIT) != 0 && !glState.allActiveDrawBufferChannelsMasked();
+ bool depth = (mask & GL_DEPTH_BUFFER_BIT) != 0 && !depthStencil.isDepthMaskedOut();
+ bool stencil = (mask & GL_STENCIL_BUFFER_BIT) != 0 && !depthStencil.isStencilMaskedOut();
+
+ if (!color && !depth && !stencil)
+ {
+ return angle::Result::Continue;
+ }
+
+ if (partialClearNeedsInit(context, color, depth, stencil))
+ {
+ ANGLE_TRY(ensureDrawAttachmentsInitialized(context));
+ }
+
+ // If the impl encounters an error during a a full (non-partial) clear, the attachments will
+ // still be marked initialized. This simplifies design, allowing this method to be called before
+ // the clear.
+ markDrawAttachmentsInitialized(color, depth, stencil);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Framebuffer::ensureClearBufferAttachmentsInitialized(const Context *context,
+ GLenum buffer,
+ GLint drawbuffer)
+{
+ if (!context->isRobustResourceInitEnabled() ||
+ context->getState().isRasterizerDiscardEnabled() ||
+ context->isClearBufferMaskedOut(buffer, drawbuffer))
+ {
+ return angle::Result::Continue;
+ }
+
+ if (partialBufferClearNeedsInit(context, buffer))
+ {
+ ANGLE_TRY(ensureBufferInitialized(context, buffer, drawbuffer));
+ }
+
+ // If the impl encounters an error during a a full (non-partial) clear, the attachments will
+ // still be marked initialized. This simplifies design, allowing this method to be called before
+ // the clear.
+ markBufferInitialized(buffer, drawbuffer);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Framebuffer::ensureDrawAttachmentsInitialized(const Context *context)
+{
+ if (!context->isRobustResourceInitEnabled())
+ {
+ return angle::Result::Continue;
+ }
+
+ // Note: we don't actually filter by the draw attachment enum. Just init everything.
+ for (size_t bit : mState.mResourceNeedsInit)
+ {
+ switch (bit)
+ {
+ case DIRTY_BIT_DEPTH_ATTACHMENT:
+ ANGLE_TRY(InitAttachment(context, &mState.mDepthAttachment));
+ break;
+ case DIRTY_BIT_STENCIL_ATTACHMENT:
+ ANGLE_TRY(InitAttachment(context, &mState.mStencilAttachment));
+ break;
+ default:
+ ANGLE_TRY(InitAttachment(context, &mState.mColorAttachments[bit]));
+ break;
+ }
+ }
+
+ mState.mResourceNeedsInit.reset();
+ return angle::Result::Continue;
+}
+
+angle::Result Framebuffer::ensureReadAttachmentsInitialized(const Context *context)
+{
+ ASSERT(context->isRobustResourceInitEnabled());
+
+ if (mState.mResourceNeedsInit.none())
+ {
+ return angle::Result::Continue;
+ }
+
+ if (mState.mReadBufferState != GL_NONE)
+ {
+ if (isDefault())
+ {
+ if (!mState.mDefaultFramebufferReadAttachmentInitialized)
+ {
+ ANGLE_TRY(InitAttachment(context, &mState.mDefaultFramebufferReadAttachment));
+ mState.mDefaultFramebufferReadAttachmentInitialized = true;
+ }
+ }
+ else
+ {
+ size_t readIndex = mState.getReadIndex();
+ if (mState.mResourceNeedsInit[readIndex])
+ {
+ ANGLE_TRY(InitAttachment(context, &mState.mColorAttachments[readIndex]));
+ mState.mResourceNeedsInit.reset(readIndex);
+ }
+ }
+ }
+
+ // Conservatively init depth since it can be read by BlitFramebuffer.
+ if (hasDepth())
+ {
+ if (mState.mResourceNeedsInit[DIRTY_BIT_DEPTH_ATTACHMENT])
+ {
+ ANGLE_TRY(InitAttachment(context, &mState.mDepthAttachment));
+ mState.mResourceNeedsInit.reset(DIRTY_BIT_DEPTH_ATTACHMENT);
+ }
+ }
+
+ // Conservatively init stencil since it can be read by BlitFramebuffer.
+ if (hasStencil())
+ {
+ if (mState.mResourceNeedsInit[DIRTY_BIT_STENCIL_ATTACHMENT])
+ {
+ ANGLE_TRY(InitAttachment(context, &mState.mStencilAttachment));
+ mState.mResourceNeedsInit.reset(DIRTY_BIT_STENCIL_ATTACHMENT);
+ }
+ }
+
+ return angle::Result::Continue;
+}
+
+void Framebuffer::markDrawAttachmentsInitialized(bool color, bool depth, bool stencil)
+{
+ // Mark attachments as initialized.
+ if (color)
+ {
+ for (auto colorIndex : mState.mEnabledDrawBuffers)
+ {
+ auto &colorAttachment = mState.mColorAttachments[colorIndex];
+ ASSERT(colorAttachment.isAttached());
+ colorAttachment.setInitState(InitState::Initialized);
+ mState.mResourceNeedsInit.reset(colorIndex);
+ }
+ }
+
+ if (depth && mState.mDepthAttachment.isAttached())
+ {
+ mState.mDepthAttachment.setInitState(InitState::Initialized);
+ mState.mResourceNeedsInit.reset(DIRTY_BIT_DEPTH_ATTACHMENT);
+ }
+
+ if (stencil && mState.mStencilAttachment.isAttached())
+ {
+ mState.mStencilAttachment.setInitState(InitState::Initialized);
+ mState.mResourceNeedsInit.reset(DIRTY_BIT_STENCIL_ATTACHMENT);
+ }
+}
+
+void Framebuffer::markBufferInitialized(GLenum bufferType, GLint bufferIndex)
+{
+ switch (bufferType)
+ {
+ case GL_COLOR:
+ {
+ ASSERT(bufferIndex < static_cast<GLint>(mState.mColorAttachments.size()));
+ if (mState.mColorAttachments[bufferIndex].isAttached())
+ {
+ mState.mColorAttachments[bufferIndex].setInitState(InitState::Initialized);
+ mState.mResourceNeedsInit.reset(bufferIndex);
+ }
+ break;
+ }
+ case GL_DEPTH:
+ {
+ if (mState.mDepthAttachment.isAttached())
+ {
+ mState.mDepthAttachment.setInitState(InitState::Initialized);
+ mState.mResourceNeedsInit.reset(DIRTY_BIT_DEPTH_ATTACHMENT);
+ }
+ break;
+ }
+ case GL_STENCIL:
+ {
+ if (mState.mStencilAttachment.isAttached())
+ {
+ mState.mStencilAttachment.setInitState(InitState::Initialized);
+ mState.mResourceNeedsInit.reset(DIRTY_BIT_STENCIL_ATTACHMENT);
+ }
+ break;
+ }
+ case GL_DEPTH_STENCIL:
+ {
+ if (mState.mDepthAttachment.isAttached())
+ {
+ mState.mDepthAttachment.setInitState(InitState::Initialized);
+ mState.mResourceNeedsInit.reset(DIRTY_BIT_DEPTH_ATTACHMENT);
+ }
+ if (mState.mStencilAttachment.isAttached())
+ {
+ mState.mStencilAttachment.setInitState(InitState::Initialized);
+ mState.mResourceNeedsInit.reset(DIRTY_BIT_STENCIL_ATTACHMENT);
+ }
+ break;
+ }
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+Box Framebuffer::getDimensions() const
+{
+ return mState.getDimensions();
+}
+
+Extents Framebuffer::getExtents() const
+{
+ return mState.getExtents();
+}
+
+angle::Result Framebuffer::ensureBufferInitialized(const Context *context,
+ GLenum bufferType,
+ GLint bufferIndex)
+{
+ ASSERT(context->isRobustResourceInitEnabled());
+
+ if (mState.mResourceNeedsInit.none())
+ {
+ return angle::Result::Continue;
+ }
+
+ switch (bufferType)
+ {
+ case GL_COLOR:
+ {
+ ASSERT(bufferIndex < static_cast<GLint>(mState.mColorAttachments.size()));
+ if (mState.mResourceNeedsInit[bufferIndex])
+ {
+ ANGLE_TRY(InitAttachment(context, &mState.mColorAttachments[bufferIndex]));
+ mState.mResourceNeedsInit.reset(bufferIndex);
+ }
+ break;
+ }
+ case GL_DEPTH:
+ {
+ if (mState.mResourceNeedsInit[DIRTY_BIT_DEPTH_ATTACHMENT])
+ {
+ ANGLE_TRY(InitAttachment(context, &mState.mDepthAttachment));
+ mState.mResourceNeedsInit.reset(DIRTY_BIT_DEPTH_ATTACHMENT);
+ }
+ break;
+ }
+ case GL_STENCIL:
+ {
+ if (mState.mResourceNeedsInit[DIRTY_BIT_STENCIL_ATTACHMENT])
+ {
+ ANGLE_TRY(InitAttachment(context, &mState.mStencilAttachment));
+ mState.mResourceNeedsInit.reset(DIRTY_BIT_STENCIL_ATTACHMENT);
+ }
+ break;
+ }
+ case GL_DEPTH_STENCIL:
+ {
+ if (mState.mResourceNeedsInit[DIRTY_BIT_DEPTH_ATTACHMENT])
+ {
+ ANGLE_TRY(InitAttachment(context, &mState.mDepthAttachment));
+ mState.mResourceNeedsInit.reset(DIRTY_BIT_DEPTH_ATTACHMENT);
+ }
+ if (mState.mResourceNeedsInit[DIRTY_BIT_STENCIL_ATTACHMENT])
+ {
+ ANGLE_TRY(InitAttachment(context, &mState.mStencilAttachment));
+ mState.mResourceNeedsInit.reset(DIRTY_BIT_STENCIL_ATTACHMENT);
+ }
+ break;
+ }
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ return angle::Result::Continue;
+}
+
+bool Framebuffer::partialBufferClearNeedsInit(const Context *context, GLenum bufferType)
+{
+ if (!context->isRobustResourceInitEnabled() || mState.mResourceNeedsInit.none())
+ {
+ return false;
+ }
+
+ switch (bufferType)
+ {
+ case GL_COLOR:
+ return partialClearNeedsInit(context, true, false, false);
+ case GL_DEPTH:
+ return partialClearNeedsInit(context, false, true, false);
+ case GL_STENCIL:
+ return partialClearNeedsInit(context, false, false, true);
+ case GL_DEPTH_STENCIL:
+ return partialClearNeedsInit(context, false, true, true);
+ default:
+ UNREACHABLE();
+ return false;
+ }
+}
+
+PixelLocalStorage &Framebuffer::getPixelLocalStorage(const Context *context)
+{
+ if (!mPixelLocalStorage)
+ {
+ mPixelLocalStorage = PixelLocalStorage::Make(context);
+ }
+ return *mPixelLocalStorage.get();
+}
+
+std::unique_ptr<PixelLocalStorage> Framebuffer::detachPixelLocalStorage()
+{
+ return std::move(mPixelLocalStorage);
+}
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/Framebuffer.h b/gfx/angle/checkout/src/libANGLE/Framebuffer.h
new file mode 100644
index 0000000000..024ad49687
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Framebuffer.h
@@ -0,0 +1,538 @@
+//
+// Copyright 2002 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.
+//
+
+// Framebuffer.h: Defines the gl::Framebuffer class. Implements GL framebuffer
+// objects and related functionality. [OpenGL ES 2.0.24] section 4.4 page 105.
+
+#ifndef LIBANGLE_FRAMEBUFFER_H_
+#define LIBANGLE_FRAMEBUFFER_H_
+
+#include <vector>
+
+#include "common/FixedVector.h"
+#include "common/Optional.h"
+#include "common/angleutils.h"
+#include "libANGLE/Constants.h"
+#include "libANGLE/Debug.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/Observer.h"
+#include "libANGLE/RefCountObject.h"
+#include "libANGLE/State.h"
+#include "libANGLE/angletypes.h"
+
+namespace rx
+{
+class GLImplFactory;
+class FramebufferImpl;
+class RenderbufferImpl;
+class SurfaceImpl;
+} // namespace rx
+
+namespace egl
+{
+class Display;
+class Surface;
+} // namespace egl
+
+namespace gl
+{
+struct Caps;
+class Context;
+struct Extensions;
+class Framebuffer;
+class ImageIndex;
+class PixelLocalStorage;
+class Renderbuffer;
+class TextureCapsMap;
+
+struct FramebufferStatus
+{
+ bool isComplete() const;
+
+ static FramebufferStatus Complete();
+ static FramebufferStatus Incomplete(GLenum status, const char *reason);
+
+ GLenum status = GL_FRAMEBUFFER_COMPLETE;
+ const char *reason = nullptr;
+};
+
+class FramebufferState final : angle::NonCopyable
+{
+ public:
+ explicit FramebufferState(rx::Serial serial);
+ FramebufferState(const Caps &caps, FramebufferID id, rx::Serial serial);
+ ~FramebufferState();
+
+ const std::string &getLabel() const;
+ uint32_t getReadIndex() const;
+
+ const FramebufferAttachment *getAttachment(const Context *context, GLenum attachment) const;
+ const FramebufferAttachment *getReadAttachment() const;
+ const FramebufferAttachment *getFirstNonNullAttachment() const;
+ const FramebufferAttachment *getFirstColorAttachment() const;
+ const FramebufferAttachment *getDepthOrStencilAttachment() const;
+ const FramebufferAttachment *getStencilOrDepthStencilAttachment() const;
+ const FramebufferAttachment *getColorAttachment(size_t colorAttachment) const;
+ const FramebufferAttachment *getDepthAttachment() const;
+ const FramebufferAttachment *getStencilAttachment() const;
+ const FramebufferAttachment *getDepthStencilAttachment() const;
+ const FramebufferAttachment *getReadPixelsAttachment(GLenum readFormat) const;
+
+ const DrawBuffersVector<GLenum> &getDrawBufferStates() const { return mDrawBufferStates; }
+ DrawBufferMask getEnabledDrawBuffers() const { return mEnabledDrawBuffers; }
+ GLenum getReadBufferState() const { return mReadBufferState; }
+
+ const DrawBuffersVector<FramebufferAttachment> &getColorAttachments() const
+ {
+ return mColorAttachments;
+ }
+ const DrawBufferMask getColorAttachmentsMask() const { return mColorAttachmentsMask; }
+
+ const Extents getAttachmentExtentsIntersection() const;
+ bool attachmentsHaveSameDimensions() const;
+ bool hasSeparateDepthAndStencilAttachments() const;
+ bool colorAttachmentsAreUniqueImages() const;
+ Box getDimensions() const;
+ Extents getExtents() const;
+
+ const FramebufferAttachment *getDrawBuffer(size_t drawBufferIdx) const;
+ size_t getDrawBufferCount() const;
+
+ GLint getDefaultWidth() const { return mDefaultWidth; }
+ GLint getDefaultHeight() const { return mDefaultHeight; }
+ GLint getDefaultSamples() const { return mDefaultSamples; }
+ bool getDefaultFixedSampleLocations() const { return mDefaultFixedSampleLocations; }
+ GLint getDefaultLayers() const { return mDefaultLayers; }
+ bool getFlipY() const { return mFlipY; }
+
+ bool hasDepth() const;
+ bool hasStencil() const;
+
+ bool hasExternalTextureAttachment() const;
+ bool hasYUVAttachment() const;
+
+ bool isMultiview() const;
+
+ ANGLE_INLINE GLsizei getNumViews() const
+ {
+ const FramebufferAttachment *attachment = getFirstNonNullAttachment();
+ if (attachment == nullptr)
+ {
+ return FramebufferAttachment::kDefaultNumViews;
+ }
+ return attachment->getNumViews();
+ }
+
+ GLint getBaseViewIndex() const;
+
+ SrgbWriteControlMode getWriteControlMode() const { return mSrgbWriteControlMode; }
+
+ FramebufferID id() const { return mId; }
+
+ bool isDefault() const;
+
+ const Offset &getSurfaceTextureOffset() const { return mSurfaceTextureOffset; }
+
+ rx::Serial getFramebufferSerial() const { return mFramebufferSerial; }
+
+ bool isBoundAsDrawFramebuffer(const Context *context) const;
+
+ private:
+ const FramebufferAttachment *getWebGLDepthStencilAttachment() const;
+ const FramebufferAttachment *getWebGLDepthAttachment() const;
+ const FramebufferAttachment *getWebGLStencilAttachment() const;
+
+ friend class Framebuffer;
+
+ // The Framebuffer ID is unique to a Context.
+ // The Framebuffer Serial is unique to a Share Group.
+ FramebufferID mId;
+ rx::Serial mFramebufferSerial;
+ std::string mLabel;
+
+ DrawBuffersVector<FramebufferAttachment> mColorAttachments;
+ FramebufferAttachment mDepthAttachment;
+ FramebufferAttachment mStencilAttachment;
+
+ // Tracks all the color buffers attached to this FramebufferDesc
+ DrawBufferMask mColorAttachmentsMask;
+
+ DrawBuffersVector<GLenum> mDrawBufferStates;
+ GLenum mReadBufferState;
+ DrawBufferMask mEnabledDrawBuffers;
+ ComponentTypeMask mDrawBufferTypeMask;
+
+ GLint mDefaultWidth;
+ GLint mDefaultHeight;
+ GLint mDefaultSamples;
+ bool mDefaultFixedSampleLocations;
+ GLint mDefaultLayers;
+ bool mFlipY;
+
+ // It's necessary to store all this extra state so we can restore attachments
+ // when DEPTH_STENCIL/DEPTH/STENCIL is unbound in WebGL 1.
+ FramebufferAttachment mWebGLDepthStencilAttachment;
+ FramebufferAttachment mWebGLDepthAttachment;
+ FramebufferAttachment mWebGLStencilAttachment;
+ bool mWebGLDepthStencilConsistent;
+
+ // Tracks if we need to initialize the resources for each attachment.
+ angle::BitSet<IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS + 2> mResourceNeedsInit;
+
+ bool mDefaultFramebufferReadAttachmentInitialized;
+ FramebufferAttachment mDefaultFramebufferReadAttachment;
+
+ // EXT_sRGB_write_control
+ SrgbWriteControlMode mSrgbWriteControlMode;
+
+ Offset mSurfaceTextureOffset;
+};
+
+class Framebuffer final : public angle::ObserverInterface,
+ public LabeledObject,
+ public angle::Subject
+{
+ public:
+ // Constructor to build default framebuffers.
+ Framebuffer(const Context *context, rx::GLImplFactory *factory);
+ // Constructor to build application-defined framebuffers
+ Framebuffer(const Context *context, rx::GLImplFactory *factory, FramebufferID id);
+
+ ~Framebuffer() override;
+ void onDestroy(const Context *context);
+
+ egl::Error setSurfaces(const Context *context,
+ egl::Surface *surface,
+ egl::Surface *readSurface);
+ void setReadSurface(const Context *context, egl::Surface *readSurface);
+ egl::Error unsetSurfaces(const Context *context);
+ angle::Result setLabel(const Context *context, const std::string &label) override;
+ const std::string &getLabel() const override;
+
+ rx::FramebufferImpl *getImplementation() const { return mImpl; }
+
+ FramebufferID id() const { return mState.mId; }
+
+ void setAttachment(const Context *context,
+ GLenum type,
+ GLenum binding,
+ const ImageIndex &textureIndex,
+ FramebufferAttachmentObject *resource);
+ void setAttachmentMultisample(const Context *context,
+ GLenum type,
+ GLenum binding,
+ const ImageIndex &textureIndex,
+ FramebufferAttachmentObject *resource,
+ GLsizei samples);
+ void setAttachmentMultiview(const Context *context,
+ GLenum type,
+ GLenum binding,
+ const ImageIndex &textureIndex,
+ FramebufferAttachmentObject *resource,
+ GLsizei numViews,
+ GLint baseViewIndex);
+ void resetAttachment(const Context *context, GLenum binding);
+
+ bool detachTexture(const Context *context, TextureID texture);
+ bool detachRenderbuffer(const Context *context, RenderbufferID renderbuffer);
+
+ const FramebufferAttachment *getColorAttachment(size_t colorAttachment) const;
+ const FramebufferAttachment *getDepthAttachment() const;
+ const FramebufferAttachment *getStencilAttachment() const;
+ const FramebufferAttachment *getDepthStencilAttachment() const;
+ const FramebufferAttachment *getDepthOrStencilAttachment() const;
+ const FramebufferAttachment *getStencilOrDepthStencilAttachment() const;
+ const FramebufferAttachment *getReadColorAttachment() const;
+ GLenum getReadColorAttachmentType() const;
+ const FramebufferAttachment *getFirstColorAttachment() const;
+ const FramebufferAttachment *getFirstNonNullAttachment() const;
+
+ const DrawBuffersVector<FramebufferAttachment> &getColorAttachments() const
+ {
+ return mState.mColorAttachments;
+ }
+
+ const FramebufferState &getState() const { return mState; }
+
+ const FramebufferAttachment *getAttachment(const Context *context, GLenum attachment) const;
+ bool isMultiview() const;
+ bool readDisallowedByMultiview() const;
+ GLsizei getNumViews() const;
+ GLint getBaseViewIndex() const;
+ Extents getExtents() const;
+
+ size_t getDrawbufferStateCount() const;
+ GLenum getDrawBufferState(size_t drawBuffer) const;
+ const DrawBuffersVector<GLenum> &getDrawBufferStates() const;
+ void setDrawBuffers(size_t count, const GLenum *buffers);
+ const FramebufferAttachment *getDrawBuffer(size_t drawBuffer) const;
+ ComponentType getDrawbufferWriteType(size_t drawBuffer) const;
+ ComponentTypeMask getDrawBufferTypeMask() const;
+ DrawBufferMask getDrawBufferMask() const;
+ bool hasEnabledDrawBuffer() const;
+
+ GLenum getReadBufferState() const;
+ void setReadBuffer(GLenum buffer);
+
+ size_t getNumColorAttachments() const;
+ bool hasDepth() const;
+ bool hasStencil() const;
+
+ bool hasExternalTextureAttachment() const;
+ bool hasYUVAttachment() const;
+
+ bool usingExtendedDrawBuffers() const;
+
+ // This method calls checkStatus.
+ int getSamples(const Context *context) const;
+ int getReadBufferResourceSamples(const Context *context) const;
+
+ angle::Result getSamplePosition(const Context *context, size_t index, GLfloat *xy) const;
+
+ GLint getDefaultWidth() const;
+ GLint getDefaultHeight() const;
+ GLint getDefaultSamples() const;
+ bool getDefaultFixedSampleLocations() const;
+ GLint getDefaultLayers() const;
+ bool getFlipY() const;
+ void setDefaultWidth(const Context *context, GLint defaultWidth);
+ void setDefaultHeight(const Context *context, GLint defaultHeight);
+ void setDefaultSamples(const Context *context, GLint defaultSamples);
+ void setDefaultFixedSampleLocations(const Context *context, bool defaultFixedSampleLocations);
+ void setDefaultLayers(GLint defaultLayers);
+ void setFlipY(bool flipY);
+
+ void invalidateCompletenessCache();
+ ANGLE_INLINE bool cachedStatusValid() { return mCachedStatus.valid(); }
+
+ ANGLE_INLINE const FramebufferStatus &checkStatus(const Context *context) const
+ {
+ // The default framebuffer is always complete except when it is surfaceless in which
+ // case it is always unsupported.
+ ASSERT(!isDefault() || mCachedStatus.valid());
+ if (isDefault() || (!hasAnyDirtyBit() && mCachedStatus.valid()))
+ {
+ return mCachedStatus.value();
+ }
+
+ return checkStatusImpl(context);
+ }
+
+ // Helper for checkStatus == GL_FRAMEBUFFER_COMPLETE.
+ ANGLE_INLINE bool isComplete(const Context *context) const
+ {
+ return checkStatus(context).isComplete();
+ }
+
+ bool hasValidDepthStencil() const;
+
+ // Returns the offset into the texture backing the default framebuffer's surface if any. Returns
+ // zero offset otherwise. The renderer will apply the offset to scissor and viewport rects used
+ // for draws, clears, and blits.
+ const Offset &getSurfaceTextureOffset() const;
+
+ angle::Result discard(const Context *context, size_t count, const GLenum *attachments);
+ angle::Result invalidate(const Context *context, size_t count, const GLenum *attachments);
+ angle::Result invalidateSub(const Context *context,
+ size_t count,
+ const GLenum *attachments,
+ const Rectangle &area);
+
+ angle::Result clear(const Context *context, GLbitfield mask);
+ angle::Result clearBufferfv(const Context *context,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLfloat *values);
+ angle::Result clearBufferuiv(const Context *context,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLuint *values);
+ angle::Result clearBufferiv(const Context *context,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLint *values);
+ angle::Result clearBufferfi(const Context *context,
+ GLenum buffer,
+ GLint drawbuffer,
+ GLfloat depth,
+ GLint stencil);
+
+ GLenum getImplementationColorReadFormat(const Context *context);
+ GLenum getImplementationColorReadType(const Context *context);
+
+ angle::Result readPixels(const Context *context,
+ const Rectangle &area,
+ GLenum format,
+ GLenum type,
+ const PixelPackState &pack,
+ Buffer *packBuffer,
+ void *pixels);
+
+ angle::Result blit(const Context *context,
+ const Rectangle &sourceArea,
+ const Rectangle &destArea,
+ GLbitfield mask,
+ GLenum filter);
+ bool isDefault() const { return mState.isDefault(); }
+
+ enum DirtyBitType : size_t
+ {
+ DIRTY_BIT_COLOR_ATTACHMENT_0,
+ DIRTY_BIT_COLOR_ATTACHMENT_MAX =
+ DIRTY_BIT_COLOR_ATTACHMENT_0 + IMPLEMENTATION_MAX_DRAW_BUFFERS,
+ DIRTY_BIT_DEPTH_ATTACHMENT = DIRTY_BIT_COLOR_ATTACHMENT_MAX,
+ DIRTY_BIT_STENCIL_ATTACHMENT,
+ DIRTY_BIT_COLOR_BUFFER_CONTENTS_0,
+ DIRTY_BIT_COLOR_BUFFER_CONTENTS_MAX =
+ DIRTY_BIT_COLOR_BUFFER_CONTENTS_0 + IMPLEMENTATION_MAX_DRAW_BUFFERS,
+ DIRTY_BIT_DEPTH_BUFFER_CONTENTS = DIRTY_BIT_COLOR_BUFFER_CONTENTS_MAX,
+ DIRTY_BIT_STENCIL_BUFFER_CONTENTS,
+ DIRTY_BIT_DRAW_BUFFERS,
+ DIRTY_BIT_READ_BUFFER,
+ DIRTY_BIT_DEFAULT_WIDTH,
+ DIRTY_BIT_DEFAULT_HEIGHT,
+ DIRTY_BIT_DEFAULT_SAMPLES,
+ DIRTY_BIT_DEFAULT_FIXED_SAMPLE_LOCATIONS,
+ DIRTY_BIT_DEFAULT_LAYERS,
+ DIRTY_BIT_FRAMEBUFFER_SRGB_WRITE_CONTROL_MODE,
+ DIRTY_BIT_FLIP_Y,
+ DIRTY_BIT_UNKNOWN,
+ DIRTY_BIT_MAX = DIRTY_BIT_UNKNOWN
+ };
+
+ using DirtyBits = angle::BitSet<DIRTY_BIT_MAX>;
+ bool hasAnyDirtyBit() const { return mDirtyBits.any(); }
+
+ DrawBufferMask getActiveFloat32ColorAttachmentDrawBufferMask() const
+ {
+ return mFloat32ColorAttachmentBits & getDrawBufferMask();
+ }
+
+ bool hasResourceThatNeedsInit() const { return mState.mResourceNeedsInit.any(); }
+
+ angle::Result syncState(const Context *context,
+ GLenum framebufferBinding,
+ Command command) const;
+
+ void setWriteControlMode(SrgbWriteControlMode srgbWriteControlMode);
+
+ // Observer implementation
+ void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override;
+
+ bool formsRenderingFeedbackLoopWith(const Context *context) const;
+ bool formsCopyingFeedbackLoopWith(TextureID copyTextureID,
+ GLint copyTextureLevel,
+ GLint copyTextureLayer) const;
+
+ angle::Result ensureClearAttachmentsInitialized(const Context *context, GLbitfield mask);
+ angle::Result ensureClearBufferAttachmentsInitialized(const Context *context,
+ GLenum buffer,
+ GLint drawbuffer);
+ angle::Result ensureDrawAttachmentsInitialized(const Context *context);
+
+ // Conservatively initializes both read color and depth. Blit can access the depth buffer.
+ angle::Result ensureReadAttachmentsInitialized(const Context *context);
+ Box getDimensions() const;
+
+ // ANGLE_shader_pixel_local_storage.
+ // Lazily creates a PixelLocalStorage object for this Framebuffer.
+ PixelLocalStorage &getPixelLocalStorage(const Context *);
+ // Returns nullptr if the pixel local storage object has not been created yet.
+ const PixelLocalStorage *peekPixelLocalStorage() const { return mPixelLocalStorage.get(); }
+ // Detaches the the pixel local storage object so the Context can call deleteContextObjects().
+ std::unique_ptr<PixelLocalStorage> detachPixelLocalStorage();
+
+ static const FramebufferID kDefaultDrawFramebufferHandle;
+
+ private:
+ bool detachResourceById(const Context *context, GLenum resourceType, GLuint resourceId);
+ bool detachMatchingAttachment(const Context *context,
+ FramebufferAttachment *attachment,
+ GLenum matchType,
+ GLuint matchId);
+ FramebufferStatus checkStatusWithGLFrontEnd(const Context *context) const;
+ const FramebufferStatus &checkStatusImpl(const Context *context) const;
+ void setAttachment(const Context *context,
+ GLenum type,
+ GLenum binding,
+ const ImageIndex &textureIndex,
+ FramebufferAttachmentObject *resource,
+ GLsizei numViews,
+ GLuint baseViewIndex,
+ bool isMultiview,
+ GLsizei samplesIn);
+ void commitWebGL1DepthStencilIfConsistent(const Context *context,
+ GLsizei numViews,
+ GLuint baseViewIndex,
+ bool isMultiview,
+ GLsizei samples);
+ void setAttachmentImpl(const Context *context,
+ GLenum type,
+ GLenum binding,
+ const ImageIndex &textureIndex,
+ FramebufferAttachmentObject *resource,
+ GLsizei numViews,
+ GLuint baseViewIndex,
+ bool isMultiview,
+ GLsizei samples);
+ void updateAttachment(const Context *context,
+ FramebufferAttachment *attachment,
+ size_t dirtyBit,
+ angle::ObserverBinding *onDirtyBinding,
+ GLenum type,
+ GLenum binding,
+ const ImageIndex &textureIndex,
+ FramebufferAttachmentObject *resource,
+ GLsizei numViews,
+ GLuint baseViewIndex,
+ bool isMultiview,
+ GLsizei samples);
+
+ void markDrawAttachmentsInitialized(bool color, bool depth, bool stencil);
+ void markBufferInitialized(GLenum bufferType, GLint bufferIndex);
+ angle::Result ensureBufferInitialized(const Context *context,
+ GLenum bufferType,
+ GLint bufferIndex);
+
+ // Checks that we have a partially masked clear:
+ // * some color channels are masked out
+ // * some stencil values are masked out
+ // * scissor test partially overlaps the framebuffer
+ bool partialClearNeedsInit(const Context *context, bool color, bool depth, bool stencil);
+ bool partialBufferClearNeedsInit(const Context *context, GLenum bufferType);
+
+ FramebufferAttachment *getAttachmentFromSubjectIndex(angle::SubjectIndex index);
+
+ ANGLE_INLINE void updateFloat32ColorAttachmentBits(size_t index, const InternalFormat *format)
+ {
+ mFloat32ColorAttachmentBits.set(index, format->type == GL_FLOAT);
+ }
+
+ FramebufferState mState;
+ rx::FramebufferImpl *mImpl;
+
+ mutable Optional<FramebufferStatus> mCachedStatus;
+ DrawBuffersVector<angle::ObserverBinding> mDirtyColorAttachmentBindings;
+ angle::ObserverBinding mDirtyDepthAttachmentBinding;
+ angle::ObserverBinding mDirtyStencilAttachmentBinding;
+
+ mutable DirtyBits mDirtyBits;
+ DrawBufferMask mFloat32ColorAttachmentBits;
+
+ // The dirty bits guard is checked when we get a dependent state change message. We verify that
+ // we don't set a dirty bit that isn't already set, when inside the dirty bits syncState.
+ mutable Optional<DirtyBits> mDirtyBitsGuard;
+
+ // ANGLE_shader_pixel_local_storage
+ std::unique_ptr<PixelLocalStorage> mPixelLocalStorage;
+};
+
+using UniqueFramebufferPointer = angle::UniqueObjectPointer<Framebuffer, Context>;
+
+} // namespace gl
+
+#endif // LIBANGLE_FRAMEBUFFER_H_
diff --git a/gfx/angle/checkout/src/libANGLE/FramebufferAttachment.cpp b/gfx/angle/checkout/src/libANGLE/FramebufferAttachment.cpp
new file mode 100644
index 0000000000..6a3e88051f
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/FramebufferAttachment.cpp
@@ -0,0 +1,350 @@
+//
+// 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.
+//
+
+// FramebufferAttachment.cpp: the gl::FramebufferAttachment class and its derived classes
+// objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108.
+
+#include "libANGLE/FramebufferAttachment.h"
+
+#include "common/utilities.h"
+#include "libANGLE/Config.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Renderbuffer.h"
+#include "libANGLE/Surface.h"
+#include "libANGLE/Texture.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/FramebufferAttachmentObjectImpl.h"
+#include "libANGLE/renderer/FramebufferImpl.h"
+
+namespace gl
+{
+
+////// FramebufferAttachment::Target Implementation //////
+
+const GLsizei FramebufferAttachment::kDefaultNumViews = 1;
+const GLint FramebufferAttachment::kDefaultBaseViewIndex = 0;
+const GLint FramebufferAttachment::kDefaultRenderToTextureSamples = 0;
+
+FramebufferAttachment::Target::Target() : mBinding(GL_NONE), mTextureIndex() {}
+
+FramebufferAttachment::Target::Target(GLenum binding, const ImageIndex &imageIndex)
+ : mBinding(binding), mTextureIndex(imageIndex)
+{}
+
+FramebufferAttachment::Target::Target(const Target &other)
+ : mBinding(other.mBinding), mTextureIndex(other.mTextureIndex)
+{}
+
+FramebufferAttachment::Target &FramebufferAttachment::Target::operator=(const Target &other)
+{
+ this->mBinding = other.mBinding;
+ this->mTextureIndex = other.mTextureIndex;
+ return *this;
+}
+
+////// FramebufferAttachment Implementation //////
+
+FramebufferAttachment::FramebufferAttachment()
+ : mType(GL_NONE),
+ mResource(nullptr),
+ mNumViews(kDefaultNumViews),
+ mIsMultiview(false),
+ mBaseViewIndex(kDefaultBaseViewIndex),
+ mRenderToTextureSamples(kDefaultRenderToTextureSamples)
+{}
+
+FramebufferAttachment::FramebufferAttachment(const Context *context,
+ GLenum type,
+ GLenum binding,
+ const ImageIndex &textureIndex,
+ FramebufferAttachmentObject *resource,
+ rx::Serial framebufferSerial)
+ : mResource(nullptr)
+{
+ attach(context, type, binding, textureIndex, resource, kDefaultNumViews, kDefaultBaseViewIndex,
+ false, kDefaultRenderToTextureSamples, framebufferSerial);
+}
+
+FramebufferAttachment::FramebufferAttachment(FramebufferAttachment &&other)
+ : FramebufferAttachment()
+{
+ *this = std::move(other);
+}
+
+FramebufferAttachment &FramebufferAttachment::operator=(FramebufferAttachment &&other)
+{
+ std::swap(mType, other.mType);
+ std::swap(mTarget, other.mTarget);
+ std::swap(mResource, other.mResource);
+ std::swap(mNumViews, other.mNumViews);
+ std::swap(mIsMultiview, other.mIsMultiview);
+ std::swap(mBaseViewIndex, other.mBaseViewIndex);
+ std::swap(mRenderToTextureSamples, other.mRenderToTextureSamples);
+ return *this;
+}
+
+FramebufferAttachment::~FramebufferAttachment()
+{
+ ASSERT(!isAttached());
+}
+
+void FramebufferAttachment::detach(const Context *context, rx::Serial framebufferSerial)
+{
+ mType = GL_NONE;
+ if (mResource != nullptr)
+ {
+ mResource->onDetach(context, framebufferSerial);
+ mResource = nullptr;
+ }
+ mNumViews = kDefaultNumViews;
+ mIsMultiview = false;
+ mBaseViewIndex = kDefaultBaseViewIndex;
+
+ // not technically necessary, could omit for performance
+ mTarget = Target();
+}
+
+void FramebufferAttachment::attach(const Context *context,
+ GLenum type,
+ GLenum binding,
+ const ImageIndex &textureIndex,
+ FramebufferAttachmentObject *resource,
+ GLsizei numViews,
+ GLuint baseViewIndex,
+ bool isMultiview,
+ GLsizei samples,
+ rx::Serial framebufferSerial)
+{
+ if (resource == nullptr)
+ {
+ detach(context, framebufferSerial);
+ return;
+ }
+
+ mType = type;
+ mTarget = Target(binding, textureIndex);
+ mNumViews = numViews;
+ mBaseViewIndex = baseViewIndex;
+ mIsMultiview = isMultiview;
+ mRenderToTextureSamples = type == GL_RENDERBUFFER ? kDefaultRenderToTextureSamples : samples;
+ resource->onAttach(context, framebufferSerial);
+
+ if (mResource != nullptr)
+ {
+ mResource->onDetach(context, framebufferSerial);
+ }
+
+ mResource = resource;
+}
+
+GLuint FramebufferAttachment::getRedSize() const
+{
+ return getSize().empty() ? 0 : getFormat().info->redBits;
+}
+
+GLuint FramebufferAttachment::getGreenSize() const
+{
+ return getSize().empty() ? 0 : getFormat().info->greenBits;
+}
+
+GLuint FramebufferAttachment::getBlueSize() const
+{
+ return getSize().empty() ? 0 : getFormat().info->blueBits;
+}
+
+GLuint FramebufferAttachment::getAlphaSize() const
+{
+ return getSize().empty() ? 0 : getFormat().info->alphaBits;
+}
+
+GLuint FramebufferAttachment::getDepthSize() const
+{
+ return getSize().empty() ? 0 : getFormat().info->depthBits;
+}
+
+GLuint FramebufferAttachment::getStencilSize() const
+{
+ return getSize().empty() ? 0 : getFormat().info->stencilBits;
+}
+
+GLenum FramebufferAttachment::getComponentType() const
+{
+ return getFormat().info->componentType;
+}
+
+GLenum FramebufferAttachment::getColorEncoding() const
+{
+ return getFormat().info->colorEncoding;
+}
+
+GLuint FramebufferAttachment::id() const
+{
+ return mResource->getId();
+}
+
+TextureTarget FramebufferAttachment::cubeMapFace() const
+{
+ ASSERT(mType == GL_TEXTURE);
+
+ const auto &index = mTarget.textureIndex();
+ return index.getType() == TextureType::CubeMap ? index.getTarget() : TextureTarget::InvalidEnum;
+}
+
+GLint FramebufferAttachment::mipLevel() const
+{
+ ASSERT(type() == GL_TEXTURE);
+ return mTarget.textureIndex().getLevelIndex();
+}
+
+GLint FramebufferAttachment::layer() const
+{
+ ASSERT(mType == GL_TEXTURE);
+
+ const gl::ImageIndex &index = mTarget.textureIndex();
+ return (index.has3DLayer() ? index.getLayerIndex() : 0);
+}
+
+bool FramebufferAttachment::isLayered() const
+{
+ return mTarget.textureIndex().isLayered();
+}
+
+bool FramebufferAttachment::isMultiview() const
+{
+ return mIsMultiview;
+}
+
+GLint FramebufferAttachment::getBaseViewIndex() const
+{
+ return mBaseViewIndex;
+}
+
+bool FramebufferAttachment::isRenderToTexture() const
+{
+ ASSERT(mRenderToTextureSamples == kDefaultRenderToTextureSamples || mType == GL_TEXTURE);
+
+ if (mType == GL_RENDERBUFFER)
+ {
+ return getRenderbuffer()->getMultisamplingMode() ==
+ MultisamplingMode::MultisampledRenderToTexture;
+ }
+ return mRenderToTextureSamples != kDefaultRenderToTextureSamples;
+}
+
+GLsizei FramebufferAttachment::getRenderToTextureSamples() const
+{
+ ASSERT(mRenderToTextureSamples == kDefaultRenderToTextureSamples || mType == GL_TEXTURE);
+
+ if (mType == GL_RENDERBUFFER)
+ {
+ return getRenderbuffer()->getState().getSamples();
+ }
+ return mRenderToTextureSamples;
+}
+
+Texture *FramebufferAttachment::getTexture() const
+{
+ return rx::GetAs<Texture>(mResource);
+}
+
+Renderbuffer *FramebufferAttachment::getRenderbuffer() const
+{
+ return rx::GetAs<Renderbuffer>(mResource);
+}
+
+const egl::Surface *FramebufferAttachment::getSurface() const
+{
+ return rx::GetAs<egl::Surface>(mResource);
+}
+
+FramebufferAttachmentObject *FramebufferAttachment::getResource() const
+{
+ return mResource;
+}
+
+bool FramebufferAttachment::operator==(const FramebufferAttachment &other) const
+{
+ if (mResource != other.mResource || mType != other.mType || mNumViews != other.mNumViews ||
+ mIsMultiview != other.mIsMultiview || mBaseViewIndex != other.mBaseViewIndex ||
+ mRenderToTextureSamples != other.mRenderToTextureSamples)
+ {
+ return false;
+ }
+
+ if (mType == GL_TEXTURE && getTextureImageIndex() != other.getTextureImageIndex())
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool FramebufferAttachment::operator!=(const FramebufferAttachment &other) const
+{
+ return !(*this == other);
+}
+
+InitState FramebufferAttachment::initState() const
+{
+ return mResource ? mResource->initState(mTarget.binding(), mTarget.textureIndex())
+ : InitState::Initialized;
+}
+
+angle::Result FramebufferAttachment::initializeContents(const Context *context)
+{
+ ASSERT(mResource);
+ ANGLE_TRY(mResource->initializeContents(context, mTarget.binding(), mTarget.textureIndex()));
+ setInitState(InitState::Initialized);
+ return angle::Result::Continue;
+}
+
+void FramebufferAttachment::setInitState(InitState initState) const
+{
+ ASSERT(mResource);
+ mResource->setInitState(mTarget.binding(), mTarget.textureIndex(), initState);
+}
+
+////// FramebufferAttachmentObject Implementation //////
+
+FramebufferAttachmentObject::FramebufferAttachmentObject() {}
+
+FramebufferAttachmentObject::~FramebufferAttachmentObject() {}
+
+angle::Result FramebufferAttachmentObject::getAttachmentRenderTarget(
+ const Context *context,
+ GLenum binding,
+ const ImageIndex &imageIndex,
+ GLsizei samples,
+ rx::FramebufferAttachmentRenderTarget **rtOut) const
+{
+ return getAttachmentImpl()->getAttachmentRenderTarget(context, binding, imageIndex, samples,
+ rtOut);
+}
+
+angle::Result FramebufferAttachmentObject::initializeContents(const Context *context,
+ GLenum binding,
+ const ImageIndex &imageIndex)
+{
+ ASSERT(context->isRobustResourceInitEnabled());
+
+ // Because gl::Texture cannot support tracking individual layer dirtiness, we only handle
+ // initializing entire mip levels for textures with layers
+ if (imageIndex.usesTex3D() && imageIndex.hasLayer())
+ {
+ // Compute the layer count so we get a correct layer index.
+ const gl::Extents &size = getAttachmentSize(imageIndex);
+
+ ImageIndex fullMipIndex = ImageIndex::MakeFromType(
+ imageIndex.getType(), imageIndex.getLevelIndex(), ImageIndex::kEntireLevel, size.depth);
+ return getAttachmentImpl()->initializeContents(context, binding, fullMipIndex);
+ }
+ else
+ {
+ return getAttachmentImpl()->initializeContents(context, binding, imageIndex);
+ }
+}
+
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/FramebufferAttachment.h b/gfx/angle/checkout/src/libANGLE/FramebufferAttachment.h
new file mode 100644
index 0000000000..8b4f04ae0b
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/FramebufferAttachment.h
@@ -0,0 +1,307 @@
+//
+// 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.
+//
+
+// FramebufferAttachment.h: Defines the wrapper class gl::FramebufferAttachment, as well as the
+// objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108.
+
+#ifndef LIBANGLE_FRAMEBUFFERATTACHMENT_H_
+#define LIBANGLE_FRAMEBUFFERATTACHMENT_H_
+
+#include "angle_gl.h"
+#include "common/angleutils.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/ImageIndex.h"
+#include "libANGLE/Observer.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/FramebufferAttachmentObjectImpl.h"
+
+namespace egl
+{
+class Surface;
+}
+
+namespace rx
+{
+// An implementation-specific object associated with an attachment.
+
+class FramebufferAttachmentRenderTarget : angle::NonCopyable
+{
+ public:
+ FramebufferAttachmentRenderTarget() {}
+ virtual ~FramebufferAttachmentRenderTarget() {}
+};
+
+class FramebufferAttachmentObjectImpl;
+} // namespace rx
+
+namespace gl
+{
+class FramebufferAttachmentObject;
+class Renderbuffer;
+class Texture;
+
+// FramebufferAttachment implements a GL framebuffer attachment.
+// Attachments are "light" containers, which store pointers to ref-counted GL objects.
+// We support GL texture (2D/3D/Cube/2D array) and renderbuffer object attachments.
+// Note: Our old naming scheme used the term "Renderbuffer" for both GL renderbuffers and for
+// framebuffer attachments, which confused their usage.
+
+class FramebufferAttachment final
+{
+ public:
+ FramebufferAttachment();
+
+ FramebufferAttachment(const Context *context,
+ GLenum type,
+ GLenum binding,
+ const ImageIndex &textureIndex,
+ FramebufferAttachmentObject *resource,
+ rx::Serial framebufferSerial);
+
+ FramebufferAttachment(FramebufferAttachment &&other);
+ FramebufferAttachment &operator=(FramebufferAttachment &&other);
+
+ ~FramebufferAttachment();
+
+ void detach(const Context *context, rx::Serial framebufferSerial);
+ void attach(const Context *context,
+ GLenum type,
+ GLenum binding,
+ const ImageIndex &textureIndex,
+ FramebufferAttachmentObject *resource,
+ GLsizei numViews,
+ GLuint baseViewIndex,
+ bool isMultiview,
+ GLsizei samples,
+ rx::Serial framebufferSerial);
+
+ // Helper methods
+ GLuint getRedSize() const;
+ GLuint getGreenSize() const;
+ GLuint getBlueSize() const;
+ GLuint getAlphaSize() const;
+ GLuint getDepthSize() const;
+ GLuint getStencilSize() const;
+ GLenum getComponentType() const;
+ GLenum getColorEncoding() const;
+
+ bool isTextureWithId(TextureID textureId) const
+ {
+ return mType == GL_TEXTURE && id() == textureId.value;
+ }
+ bool isExternalTexture() const
+ {
+ return mType == GL_TEXTURE && getTextureImageIndex().getType() == gl::TextureType::External;
+ }
+ bool isRenderbufferWithId(GLuint renderbufferId) const
+ {
+ return mType == GL_RENDERBUFFER && id() == renderbufferId;
+ }
+
+ GLenum getBinding() const { return mTarget.binding(); }
+ GLuint id() const;
+
+ // These methods are only legal to call on Texture attachments
+ const ImageIndex &getTextureImageIndex() const;
+ TextureTarget cubeMapFace() const;
+ GLint mipLevel() const;
+ GLint layer() const;
+ bool isLayered() const;
+
+ GLsizei getNumViews() const { return mNumViews; }
+
+ bool isMultiview() const;
+ GLint getBaseViewIndex() const;
+
+ bool isRenderToTexture() const;
+ GLsizei getRenderToTextureSamples() const;
+
+ // The size of the underlying resource the attachment points to. The 'depth' value will
+ // 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;
+ Format getFormat() const;
+ GLsizei getSamples() const;
+ // This will always return the actual sample count of the attachment even if
+ // render_to_texture extension is active on this FBattachment object.
+ GLsizei getResourceSamples() const;
+ GLenum type() const { return mType; }
+ bool isAttached() const { return mType != GL_NONE; }
+ bool isRenderable(const Context *context) const;
+ bool isYUV() const;
+ bool isCreatedWithAHB() const;
+
+ Renderbuffer *getRenderbuffer() const;
+ Texture *getTexture() const;
+ const egl::Surface *getSurface() const;
+ FramebufferAttachmentObject *getResource() const;
+ InitState initState() const;
+ angle::Result initializeContents(const Context *context);
+ void setInitState(InitState initState) const;
+
+ // "T" must be static_castable from FramebufferAttachmentRenderTarget
+ template <typename T>
+ angle::Result getRenderTarget(const Context *context, GLsizei samples, T **rtOut) const
+ {
+ static_assert(std::is_base_of<rx::FramebufferAttachmentRenderTarget, T>(),
+ "Invalid RenderTarget class.");
+ return getRenderTargetImpl(
+ context, samples, reinterpret_cast<rx::FramebufferAttachmentRenderTarget **>(rtOut));
+ }
+
+ bool operator==(const FramebufferAttachment &other) const;
+ bool operator!=(const FramebufferAttachment &other) const;
+
+ static const GLsizei kDefaultNumViews;
+ static const GLint kDefaultBaseViewIndex;
+ static const GLint kDefaultRenderToTextureSamples;
+
+ private:
+ angle::Result getRenderTargetImpl(const Context *context,
+ GLsizei samples,
+ rx::FramebufferAttachmentRenderTarget **rtOut) const;
+
+ // A framebuffer attachment points to one of three types of resources: Renderbuffers,
+ // Textures and egl::Surface. The "Target" struct indicates which part of the
+ // object an attachment references. For the three types:
+ // - a Renderbuffer has a unique renderable target, and needs no target index
+ // - a Texture has targets for every image and uses an ImageIndex
+ // - a Surface has targets for Color and Depth/Stencil, and uses the attachment binding
+ class Target
+ {
+ public:
+ Target();
+ Target(GLenum binding, const ImageIndex &imageIndex);
+ Target(const Target &other);
+ Target &operator=(const Target &other);
+
+ GLenum binding() const { return mBinding; }
+ const ImageIndex &textureIndex() const { return mTextureIndex; }
+
+ private:
+ GLenum mBinding;
+ ImageIndex mTextureIndex;
+ };
+
+ GLenum mType;
+ Target mTarget;
+ FramebufferAttachmentObject *mResource;
+ GLsizei mNumViews;
+ bool mIsMultiview;
+ GLint mBaseViewIndex;
+ // A single-sampled texture can be attached to a framebuffer either as single-sampled or as
+ // multisampled-render-to-texture. In the latter case, |mRenderToTextureSamples| will contain
+ // the number of samples. For renderbuffers, the number of samples is inherited from the
+ // renderbuffer itself.
+ //
+ // Note that textures cannot change storage between single and multisample once attached to a
+ // framebuffer. Renderbuffers instead can, and caching the number of renderbuffer samples here
+ // can lead to stale data.
+ GLsizei mRenderToTextureSamples;
+};
+
+// A base class for objects that FBO Attachments may point to.
+class FramebufferAttachmentObject : public angle::Subject, public angle::ObserverInterface
+{
+ public:
+ FramebufferAttachmentObject();
+ ~FramebufferAttachmentObject() override;
+
+ virtual Extents getAttachmentSize(const ImageIndex &imageIndex) const = 0;
+ virtual Format getAttachmentFormat(GLenum binding, const ImageIndex &imageIndex) const = 0;
+ virtual GLsizei getAttachmentSamples(const ImageIndex &imageIndex) const = 0;
+ virtual bool isRenderable(const Context *context,
+ GLenum binding,
+ const ImageIndex &imageIndex) const = 0;
+ virtual bool isYUV() const = 0;
+ virtual bool isCreatedWithAHB() const = 0;
+ virtual bool hasProtectedContent() const = 0;
+
+ virtual void onAttach(const Context *context, rx::Serial framebufferSerial) = 0;
+ virtual void onDetach(const Context *context, rx::Serial framebufferSerial) = 0;
+ virtual GLuint getId() const = 0;
+
+ // These are used for robust resource initialization.
+ virtual InitState initState(GLenum binding, const ImageIndex &imageIndex) const = 0;
+ virtual void setInitState(GLenum binding,
+ const ImageIndex &imageIndex,
+ InitState initState) = 0;
+
+ angle::Result getAttachmentRenderTarget(const Context *context,
+ GLenum binding,
+ const ImageIndex &imageIndex,
+ GLsizei samples,
+ rx::FramebufferAttachmentRenderTarget **rtOut) const;
+
+ angle::Result initializeContents(const Context *context,
+ GLenum binding,
+ const ImageIndex &imageIndex);
+
+ protected:
+ virtual rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const = 0;
+};
+
+inline const ImageIndex &FramebufferAttachment::getTextureImageIndex() const
+{
+ ASSERT(type() == GL_TEXTURE);
+ return mTarget.textureIndex();
+}
+
+inline Extents FramebufferAttachment::getSize() const
+{
+ ASSERT(mResource);
+ return mResource->getAttachmentSize(mTarget.textureIndex());
+}
+
+inline Format FramebufferAttachment::getFormat() const
+{
+ ASSERT(mResource);
+ return mResource->getAttachmentFormat(mTarget.binding(), mTarget.textureIndex());
+}
+
+inline GLsizei FramebufferAttachment::getSamples() const
+{
+ return isRenderToTexture() ? getRenderToTextureSamples() : getResourceSamples();
+}
+
+inline GLsizei FramebufferAttachment::getResourceSamples() const
+{
+ ASSERT(mResource);
+ return mResource->getAttachmentSamples(mTarget.textureIndex());
+}
+
+inline angle::Result FramebufferAttachment::getRenderTargetImpl(
+ const Context *context,
+ GLsizei samples,
+ rx::FramebufferAttachmentRenderTarget **rtOut) const
+{
+ ASSERT(mResource);
+ return mResource->getAttachmentRenderTarget(context, mTarget.binding(), mTarget.textureIndex(),
+ samples, rtOut);
+}
+
+inline bool FramebufferAttachment::isRenderable(const Context *context) const
+{
+ ASSERT(mResource);
+ return mResource->isRenderable(context, mTarget.binding(), mTarget.textureIndex());
+}
+
+inline bool FramebufferAttachment::isYUV() const
+{
+ ASSERT(mResource);
+ return mResource->isYUV();
+}
+
+inline bool FramebufferAttachment::isCreatedWithAHB() const
+{
+ ASSERT(mResource);
+ return mResource->isCreatedWithAHB();
+}
+
+} // namespace gl
+
+#endif // LIBANGLE_FRAMEBUFFERATTACHMENT_H_
diff --git a/gfx/angle/checkout/src/libANGLE/GLES1Renderer.cpp b/gfx/angle/checkout/src/libANGLE/GLES1Renderer.cpp
new file mode 100644
index 0000000000..4ca3d47189
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/GLES1Renderer.cpp
@@ -0,0 +1,1197 @@
+//
+// Copyright 2018 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.
+//
+
+// GLES1Renderer.cpp: Implements the GLES1Renderer renderer.
+
+#include "libANGLE/GLES1Renderer.h"
+
+#include <string.h>
+#include <iterator>
+#include <sstream>
+#include <vector>
+
+#include "common/hash_utils.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Context.inl.h"
+#include "libANGLE/Program.h"
+#include "libANGLE/ResourceManager.h"
+#include "libANGLE/Shader.h"
+#include "libANGLE/State.h"
+#include "libANGLE/renderer/ContextImpl.h"
+
+namespace
+{
+#include "libANGLE/GLES1Shaders.inc"
+
+uint32_t GetLogicOpUniform(const gl::FramebufferAttachment *color, gl::LogicalOperation logicOp)
+{
+ const uint32_t red = color->getRedSize();
+ const uint32_t green = color->getGreenSize();
+ const uint32_t blue = color->getBlueSize();
+ const uint32_t alpha = color->getAlphaSize();
+
+ ASSERT(red <= 8 && green <= 8 && blue <= 8 && alpha <= 8);
+
+ return red | green << 4 | blue << 8 | alpha << 12 | static_cast<uint32_t>(logicOp) << 16;
+}
+} // anonymous namespace
+
+namespace gl
+{
+GLES1ShaderState::GLES1ShaderState() = default;
+GLES1ShaderState::~GLES1ShaderState() = default;
+GLES1ShaderState::GLES1ShaderState(const GLES1ShaderState &other)
+{
+ memcpy(this, &other, sizeof(GLES1ShaderState));
+}
+
+bool operator==(const GLES1ShaderState &a, const GLES1ShaderState &b)
+{
+ return memcmp(&a, &b, sizeof(GLES1ShaderState)) == 0;
+}
+bool operator!=(const GLES1ShaderState &a, const GLES1ShaderState &b)
+{
+ return !(a == b);
+}
+
+size_t GLES1ShaderState::hash() const
+{
+ return angle::ComputeGenericHash(*this);
+}
+
+GLES1Renderer::GLES1Renderer() : mRendererProgramInitialized(false) {}
+
+void GLES1Renderer::onDestroy(Context *context, State *state)
+{
+ if (mRendererProgramInitialized)
+ {
+ (void)state->setProgram(context, 0);
+
+ for (const auto &iter : mUberShaderState)
+ {
+ const GLES1UberShaderState &UberShaderState = iter.second;
+ mShaderPrograms->deleteProgram(context, {UberShaderState.programState.program});
+ }
+ mShaderPrograms->release(context);
+ mShaderPrograms = nullptr;
+ mRendererProgramInitialized = false;
+ }
+}
+
+GLES1Renderer::~GLES1Renderer() = default;
+
+angle::Result GLES1Renderer::prepareForDraw(PrimitiveMode mode, Context *context, State *glState)
+{
+ GLES1State &gles1State = glState->gles1();
+
+ GLES1ShaderState::BoolTexArray &tex2DEnables = mShaderState.tex2DEnables;
+ GLES1ShaderState::BoolTexArray &texCubeEnables = mShaderState.texCubeEnables;
+ GLES1ShaderState::IntTexArray &tex2DFormats = mShaderState.tex2DFormats;
+
+ for (int i = 0; i < kTexUnitCount; i++)
+ {
+ // GL_OES_cube_map allows only one of TEXTURE_2D / TEXTURE_CUBE_MAP
+ // to be enabled per unit, thankfully. From the extension text:
+ //
+ // -- Section 3.8.10 "Texture Application"
+ //
+ // Replace the beginning sentences of the first paragraph (page 138)
+ // with:
+ //
+ // "Texturing is enabled or disabled using the generic Enable
+ // and Disable commands, respectively, with the symbolic constants
+ // TEXTURE_2D or TEXTURE_CUBE_MAP_OES to enable the two-dimensional or cube
+ // map texturing respectively. If the cube map texture and the two-
+ // dimensional texture are enabled, then cube map texturing is used. If
+ // texturing is disabled, a rasterized fragment is passed on unaltered to the
+ // next stage of the GL (although its texture coordinates may be discarded).
+ // Otherwise, a texture value is found according to the parameter values of
+ // the currently bound texture image of the appropriate dimensionality.
+
+ texCubeEnables[i] = gles1State.isTextureTargetEnabled(i, TextureType::CubeMap);
+ tex2DEnables[i] =
+ !texCubeEnables[i] && gles1State.isTextureTargetEnabled(i, TextureType::_2D);
+
+ Texture *curr2DTexture = glState->getSamplerTexture(i, TextureType::_2D);
+ if (curr2DTexture)
+ {
+ tex2DFormats[i] = gl::GetUnsizedFormat(
+ curr2DTexture->getFormat(TextureTarget::_2D, 0).info->internalFormat);
+ }
+
+ Texture *currCubeTexture = glState->getSamplerTexture(i, TextureType::CubeMap);
+
+ // > If texturing is enabled for a texture unit at the time a primitive is rasterized, if
+ // > TEXTURE MIN FILTER is one that requires a mipmap, and if the texture image bound to the
+ // > enabled texture target is not complete, then it is as if texture mapping were disabled
+ // > for that texture unit.
+ if (tex2DEnables[i] && curr2DTexture && IsMipmapFiltered(curr2DTexture->getMinFilter()))
+ {
+ tex2DEnables[i] = curr2DTexture->isMipmapComplete();
+ }
+ if (texCubeEnables[i] && currCubeTexture &&
+ IsMipmapFiltered(currCubeTexture->getMinFilter()))
+ {
+ texCubeEnables[i] = curr2DTexture->isMipmapComplete();
+ }
+ }
+
+ GLES1ShaderState::IntTexArray &texEnvModes = mShaderState.texEnvModes;
+ GLES1ShaderState::IntTexArray &texCombineRgbs = mShaderState.texCombineRgbs;
+ GLES1ShaderState::IntTexArray &texCombineAlphas = mShaderState.texCombineAlphas;
+ GLES1ShaderState::IntTexArray &texCombineSrc0Rgbs = mShaderState.texCombineSrc0Rgbs;
+ GLES1ShaderState::IntTexArray &texCombineSrc0Alphas = mShaderState.texCombineSrc0Alphas;
+ GLES1ShaderState::IntTexArray &texCombineSrc1Rgbs = mShaderState.texCombineSrc1Rgbs;
+ GLES1ShaderState::IntTexArray &texCombineSrc1Alphas = mShaderState.texCombineSrc1Alphas;
+ GLES1ShaderState::IntTexArray &texCombineSrc2Rgbs = mShaderState.texCombineSrc2Rgbs;
+ GLES1ShaderState::IntTexArray &texCombineSrc2Alphas = mShaderState.texCombineSrc2Alphas;
+ GLES1ShaderState::IntTexArray &texCombineOp0Rgbs = mShaderState.texCombineOp0Rgbs;
+ GLES1ShaderState::IntTexArray &texCombineOp0Alphas = mShaderState.texCombineOp0Alphas;
+ GLES1ShaderState::IntTexArray &texCombineOp1Rgbs = mShaderState.texCombineOp1Rgbs;
+ GLES1ShaderState::IntTexArray &texCombineOp1Alphas = mShaderState.texCombineOp1Alphas;
+ GLES1ShaderState::IntTexArray &texCombineOp2Rgbs = mShaderState.texCombineOp2Rgbs;
+ GLES1ShaderState::IntTexArray &texCombineOp2Alphas = mShaderState.texCombineOp2Alphas;
+
+ if (gles1State.isDirty(GLES1State::DIRTY_GLES1_TEXTURE_ENVIRONMENT))
+ {
+ for (int i = 0; i < kTexUnitCount; i++)
+ {
+ const auto &env = gles1State.textureEnvironment(i);
+ texEnvModes[i] = ToGLenum(env.mode);
+ texCombineRgbs[i] = ToGLenum(env.combineRgb);
+ texCombineAlphas[i] = ToGLenum(env.combineAlpha);
+ texCombineSrc0Rgbs[i] = ToGLenum(env.src0Rgb);
+ texCombineSrc0Alphas[i] = ToGLenum(env.src0Alpha);
+ texCombineSrc1Rgbs[i] = ToGLenum(env.src1Rgb);
+ texCombineSrc1Alphas[i] = ToGLenum(env.src1Alpha);
+ texCombineSrc2Rgbs[i] = ToGLenum(env.src2Rgb);
+ texCombineSrc2Alphas[i] = ToGLenum(env.src2Alpha);
+ texCombineOp0Rgbs[i] = ToGLenum(env.op0Rgb);
+ texCombineOp0Alphas[i] = ToGLenum(env.op0Alpha);
+ texCombineOp1Rgbs[i] = ToGLenum(env.op1Rgb);
+ texCombineOp1Alphas[i] = ToGLenum(env.op1Alpha);
+ texCombineOp2Rgbs[i] = ToGLenum(env.op2Rgb);
+ texCombineOp2Alphas[i] = ToGLenum(env.op2Alpha);
+ }
+ }
+
+ bool enableClipPlanes = false;
+ GLES1ShaderState::BoolClipPlaneArray &clipPlaneEnables = mShaderState.clipPlaneEnables;
+ for (int i = 0; i < kClipPlaneCount; i++)
+ {
+ clipPlaneEnables[i] = glState->getEnableFeature(GL_CLIP_PLANE0 + i);
+ enableClipPlanes = enableClipPlanes || clipPlaneEnables[i];
+ }
+
+ mShaderState.mGLES1StateEnabled[GLES1StateEnables::ClipPlanes] = enableClipPlanes;
+ mShaderState.mGLES1StateEnabled[GLES1StateEnables::DrawTexture] = mDrawTextureEnabled;
+ mShaderState.mGLES1StateEnabled[GLES1StateEnables::PointRasterization] =
+ mode == PrimitiveMode::Points;
+ mShaderState.mGLES1StateEnabled[GLES1StateEnables::ShadeModelFlat] =
+ gles1State.mShadeModel == ShadingModel::Flat;
+ mShaderState.mGLES1StateEnabled[GLES1StateEnables::AlphaTest] =
+ glState->getEnableFeature(GL_ALPHA_TEST);
+ mShaderState.mGLES1StateEnabled[GLES1StateEnables::Lighting] =
+ glState->getEnableFeature(GL_LIGHTING);
+ mShaderState.mGLES1StateEnabled[GLES1StateEnables::RescaleNormal] =
+ glState->getEnableFeature(GL_RESCALE_NORMAL);
+ mShaderState.mGLES1StateEnabled[GLES1StateEnables::Normalize] =
+ glState->getEnableFeature(GL_NORMALIZE);
+ mShaderState.mGLES1StateEnabled[GLES1StateEnables::Fog] = glState->getEnableFeature(GL_FOG);
+ mShaderState.mGLES1StateEnabled[GLES1StateEnables::PointSprite] =
+ glState->getEnableFeature(GL_POINT_SPRITE_OES);
+ mShaderState.mGLES1StateEnabled[GLES1StateEnables::ColorMaterial] =
+ glState->getEnableFeature(GL_COLOR_MATERIAL);
+
+ // TODO (lfy@google.com): Implement two-sided lighting model (lightModel.twoSided)
+ mShaderState.mGLES1StateEnabled[GLES1StateEnables::LightModelTwoSided] = false;
+
+ GLES1ShaderState::BoolTexArray &pointSpriteCoordReplaces =
+ mShaderState.pointSpriteCoordReplaces;
+ for (int i = 0; i < kTexUnitCount; i++)
+ {
+ const auto &env = gles1State.textureEnvironment(i);
+ pointSpriteCoordReplaces[i] = env.pointSpriteCoordReplace;
+ }
+
+ GLES1ShaderState::BoolLightArray &lightEnables = mShaderState.lightEnables;
+ for (int i = 0; i < kLightCount; i++)
+ {
+ const auto &light = gles1State.mLights[i];
+ lightEnables[i] = light.enabled;
+ }
+
+ mShaderState.alphaTestFunc = gles1State.mAlphaTestFunc;
+ mShaderState.fogMode = gles1State.fogParameters().mode;
+
+ const bool hasLogicOpANGLE = context->getExtensions().logicOpANGLE;
+ const bool hasFramebufferFetch = context->getExtensions().shaderFramebufferFetchEXT ||
+ context->getExtensions().shaderFramebufferFetchNonCoherentEXT;
+
+ if (!hasLogicOpANGLE && hasFramebufferFetch)
+ {
+ mShaderState.mGLES1StateEnabled[GLES1StateEnables::LogicOpThroughFramebufferFetch] =
+ gles1State.mLogicOpEnabled;
+ }
+
+ // All the states set before this spot affect ubershader creation
+
+ ANGLE_TRY(initializeRendererProgram(context, glState));
+
+ GLES1UberShaderState UberShaderState = getUberShaderState();
+
+ const GLES1ProgramState &programState = UberShaderState.programState;
+ GLES1UniformBuffers &uniformBuffers = UberShaderState.uniformBuffers;
+
+ Program *programObject = getProgram(programState.program);
+
+ // If anything is dirty in gles1 or the common parts of gles1/2, just redo these parts
+ // completely for now.
+
+ // Feature enables
+
+ // Texture unit enables and format info
+ std::array<Vec4Uniform, kTexUnitCount> texCropRects;
+ Vec4Uniform *cropRectBuffer = texCropRects.data();
+ for (int i = 0; i < kTexUnitCount; i++)
+ {
+ Texture *curr2DTexture = glState->getSamplerTexture(i, TextureType::_2D);
+ if (curr2DTexture)
+ {
+ const gl::Rectangle &cropRect = curr2DTexture->getCrop();
+
+ GLfloat textureWidth =
+ static_cast<GLfloat>(curr2DTexture->getWidth(TextureTarget::_2D, 0));
+ GLfloat textureHeight =
+ static_cast<GLfloat>(curr2DTexture->getHeight(TextureTarget::_2D, 0));
+
+ if (textureWidth > 0.0f && textureHeight > 0.0f)
+ {
+ cropRectBuffer[i][0] = cropRect.x / textureWidth;
+ cropRectBuffer[i][1] = cropRect.y / textureHeight;
+ cropRectBuffer[i][2] = cropRect.width / textureWidth;
+ cropRectBuffer[i][3] = cropRect.height / textureHeight;
+ }
+ }
+ }
+ setUniform4fv(programObject, programState.drawTextureNormalizedCropRectLoc, kTexUnitCount,
+ reinterpret_cast<GLfloat *>(cropRectBuffer));
+
+ if (gles1State.isDirty(GLES1State::DIRTY_GLES1_LOGIC_OP) && hasLogicOpANGLE)
+ {
+ context->setLogicOpEnabled(gles1State.mLogicOpEnabled);
+ context->setLogicOp(gles1State.mLogicOp);
+ }
+ else if (hasFramebufferFetch)
+ {
+ const Framebuffer *drawFramebuffer = glState->getDrawFramebuffer();
+ const FramebufferAttachment *colorAttachment = drawFramebuffer->getColorAttachment(0);
+
+ if (gles1State.mLogicOpEnabled)
+ {
+ if (gles1State.isDirty(GLES1State::DIRTY_GLES1_LOGIC_OP))
+ {
+ // Set up uniform value for logic op
+ setUniform1ui(programObject, programState.logicOpLoc,
+ GetLogicOpUniform(colorAttachment, gles1State.mLogicOp));
+ }
+
+ // Issue a framebuffer fetch barrier if non-coherent
+ if (!context->getExtensions().shaderFramebufferFetchEXT)
+ {
+ context->framebufferFetchBarrier();
+ }
+ }
+ }
+
+ // Client state / current vector enables
+ if (gles1State.isDirty(GLES1State::DIRTY_GLES1_CLIENT_STATE_ENABLE) ||
+ gles1State.isDirty(GLES1State::DIRTY_GLES1_CURRENT_VECTOR))
+ {
+ if (!gles1State.isClientStateEnabled(ClientVertexArrayType::Normal))
+ {
+ const angle::Vector3 normal = gles1State.getCurrentNormal();
+ context->vertexAttrib3f(kNormalAttribIndex, normal.x(), normal.y(), normal.z());
+ }
+
+ if (!gles1State.isClientStateEnabled(ClientVertexArrayType::Color))
+ {
+ const ColorF color = gles1State.getCurrentColor();
+ context->vertexAttrib4f(kColorAttribIndex, color.red, color.green, color.blue,
+ color.alpha);
+ }
+
+ if (!gles1State.isClientStateEnabled(ClientVertexArrayType::PointSize))
+ {
+ GLfloat pointSize = gles1State.mPointParameters.pointSize;
+ context->vertexAttrib1f(kPointSizeAttribIndex, pointSize);
+ }
+
+ for (int i = 0; i < kTexUnitCount; i++)
+ {
+ if (!gles1State.mTexCoordArrayEnabled[i])
+ {
+ const TextureCoordF texcoord = gles1State.getCurrentTextureCoords(i);
+ context->vertexAttrib4f(kTextureCoordAttribIndexBase + i, texcoord.s, texcoord.t,
+ texcoord.r, texcoord.q);
+ }
+ }
+ }
+
+ // Matrices
+ if (gles1State.isDirty(GLES1State::DIRTY_GLES1_MATRICES))
+ {
+ angle::Mat4 proj = gles1State.mProjectionMatrices.back();
+ setUniformMatrix4fv(programObject, programState.projMatrixLoc, 1, GL_FALSE, proj.data());
+
+ angle::Mat4 modelview = gles1State.mModelviewMatrices.back();
+ setUniformMatrix4fv(programObject, programState.modelviewMatrixLoc, 1, GL_FALSE,
+ modelview.data());
+
+ angle::Mat4 modelviewInvTr = modelview.transpose().inverse();
+ setUniformMatrix4fv(programObject, programState.modelviewInvTrLoc, 1, GL_FALSE,
+ modelviewInvTr.data());
+
+ Mat4Uniform *textureMatrixBuffer = uniformBuffers.textureMatrices.data();
+
+ for (int i = 0; i < kTexUnitCount; i++)
+ {
+ angle::Mat4 textureMatrix = gles1State.mTextureMatrices[i].back();
+ memcpy(textureMatrixBuffer + i, textureMatrix.data(), sizeof(Mat4Uniform));
+ }
+
+ setUniformMatrix4fv(programObject, programState.textureMatrixLoc, kTexUnitCount, GL_FALSE,
+ reinterpret_cast<float *>(uniformBuffers.textureMatrices.data()));
+ }
+
+ if (gles1State.isDirty(GLES1State::DIRTY_GLES1_TEXTURE_ENVIRONMENT))
+ {
+ for (int i = 0; i < kTexUnitCount; i++)
+ {
+ const auto &env = gles1State.textureEnvironment(i);
+
+ uniformBuffers.texEnvColors[i][0] = env.color.red;
+ uniformBuffers.texEnvColors[i][1] = env.color.green;
+ uniformBuffers.texEnvColors[i][2] = env.color.blue;
+ uniformBuffers.texEnvColors[i][3] = env.color.alpha;
+
+ uniformBuffers.texEnvRgbScales[i] = env.rgbScale;
+ uniformBuffers.texEnvAlphaScales[i] = env.alphaScale;
+ }
+
+ setUniform4fv(programObject, programState.textureEnvColorLoc, kTexUnitCount,
+ reinterpret_cast<float *>(uniformBuffers.texEnvColors.data()));
+ setUniform1fv(programObject, programState.rgbScaleLoc, kTexUnitCount,
+ uniformBuffers.texEnvRgbScales.data());
+ setUniform1fv(programObject, programState.alphaScaleLoc, kTexUnitCount,
+ uniformBuffers.texEnvAlphaScales.data());
+ }
+
+ // Alpha test
+ if (gles1State.isDirty(GLES1State::DIRTY_GLES1_ALPHA_TEST))
+ {
+ setUniform1f(programObject, programState.alphaTestRefLoc, gles1State.mAlphaTestRef);
+ }
+
+ // Shading, materials, and lighting
+ if (gles1State.isDirty(GLES1State::DIRTY_GLES1_MATERIAL))
+ {
+ const auto &material = gles1State.mMaterial;
+
+ setUniform4fv(programObject, programState.materialAmbientLoc, 1, material.ambient.data());
+ setUniform4fv(programObject, programState.materialDiffuseLoc, 1, material.diffuse.data());
+ setUniform4fv(programObject, programState.materialSpecularLoc, 1, material.specular.data());
+ setUniform4fv(programObject, programState.materialEmissiveLoc, 1, material.emissive.data());
+ setUniform1f(programObject, programState.materialSpecularExponentLoc,
+ material.specularExponent);
+ }
+
+ if (gles1State.isDirty(GLES1State::DIRTY_GLES1_LIGHTS))
+ {
+ const auto &lightModel = gles1State.mLightModel;
+
+ setUniform4fv(programObject, programState.lightModelSceneAmbientLoc, 1,
+ lightModel.color.data());
+
+ for (int i = 0; i < kLightCount; i++)
+ {
+ const auto &light = gles1State.mLights[i];
+ memcpy(uniformBuffers.lightAmbients.data() + i, light.ambient.data(),
+ sizeof(Vec4Uniform));
+ memcpy(uniformBuffers.lightDiffuses.data() + i, light.diffuse.data(),
+ sizeof(Vec4Uniform));
+ memcpy(uniformBuffers.lightSpeculars.data() + i, light.specular.data(),
+ sizeof(Vec4Uniform));
+ memcpy(uniformBuffers.lightPositions.data() + i, light.position.data(),
+ sizeof(Vec4Uniform));
+ memcpy(uniformBuffers.lightDirections.data() + i, light.direction.data(),
+ sizeof(Vec3Uniform));
+ uniformBuffers.spotlightExponents[i] = light.spotlightExponent;
+ uniformBuffers.spotlightCutoffAngles[i] = light.spotlightCutoffAngle;
+ uniformBuffers.attenuationConsts[i] = light.attenuationConst;
+ uniformBuffers.attenuationLinears[i] = light.attenuationLinear;
+ uniformBuffers.attenuationQuadratics[i] = light.attenuationQuadratic;
+ }
+
+ setUniform4fv(programObject, programState.lightAmbientsLoc, kLightCount,
+ reinterpret_cast<float *>(uniformBuffers.lightAmbients.data()));
+ setUniform4fv(programObject, programState.lightDiffusesLoc, kLightCount,
+ reinterpret_cast<float *>(uniformBuffers.lightDiffuses.data()));
+ setUniform4fv(programObject, programState.lightSpecularsLoc, kLightCount,
+ reinterpret_cast<float *>(uniformBuffers.lightSpeculars.data()));
+ setUniform4fv(programObject, programState.lightPositionsLoc, kLightCount,
+ reinterpret_cast<float *>(uniformBuffers.lightPositions.data()));
+ setUniform3fv(programObject, programState.lightDirectionsLoc, kLightCount,
+ reinterpret_cast<float *>(uniformBuffers.lightDirections.data()));
+ setUniform1fv(programObject, programState.lightSpotlightExponentsLoc, kLightCount,
+ reinterpret_cast<float *>(uniformBuffers.spotlightExponents.data()));
+ setUniform1fv(programObject, programState.lightSpotlightCutoffAnglesLoc, kLightCount,
+ reinterpret_cast<float *>(uniformBuffers.spotlightCutoffAngles.data()));
+ setUniform1fv(programObject, programState.lightAttenuationConstsLoc, kLightCount,
+ reinterpret_cast<float *>(uniformBuffers.attenuationConsts.data()));
+ setUniform1fv(programObject, programState.lightAttenuationLinearsLoc, kLightCount,
+ reinterpret_cast<float *>(uniformBuffers.attenuationLinears.data()));
+ setUniform1fv(programObject, programState.lightAttenuationQuadraticsLoc, kLightCount,
+ reinterpret_cast<float *>(uniformBuffers.attenuationQuadratics.data()));
+ }
+
+ if (gles1State.isDirty(GLES1State::DIRTY_GLES1_FOG))
+ {
+ const FogParameters &fog = gles1State.fogParameters();
+ setUniform1f(programObject, programState.fogDensityLoc, fog.density);
+ setUniform1f(programObject, programState.fogStartLoc, fog.start);
+ setUniform1f(programObject, programState.fogEndLoc, fog.end);
+ setUniform4fv(programObject, programState.fogColorLoc, 1, fog.color.data());
+ }
+
+ // Clip planes
+ if (gles1State.isDirty(GLES1State::DIRTY_GLES1_CLIP_PLANES))
+ {
+ for (int i = 0; i < kClipPlaneCount; i++)
+ {
+ gles1State.getClipPlane(
+ i, reinterpret_cast<float *>(uniformBuffers.clipPlanes.data() + i));
+ }
+
+ setUniform4fv(programObject, programState.clipPlanesLoc, kClipPlaneCount,
+ reinterpret_cast<float *>(uniformBuffers.clipPlanes.data()));
+ }
+
+ // Point rasterization
+ {
+ const PointParameters &pointParams = gles1State.mPointParameters;
+
+ setUniform1f(programObject, programState.pointSizeMinLoc, pointParams.pointSizeMin);
+ setUniform1f(programObject, programState.pointSizeMaxLoc, pointParams.pointSizeMax);
+ setUniform3fv(programObject, programState.pointDistanceAttenuationLoc, 1,
+ pointParams.pointDistanceAttenuation.data());
+ }
+
+ // Draw texture
+ {
+ setUniform4fv(programObject, programState.drawTextureCoordsLoc, 1, mDrawTextureCoords);
+ setUniform2fv(programObject, programState.drawTextureDimsLoc, 1, mDrawTextureDims);
+ }
+
+ gles1State.clearDirty();
+
+ // None of those are changes in sampler, so there is no need to set the GL_PROGRAM dirty.
+ // Otherwise, put the dirtying here.
+
+ return angle::Result::Continue;
+}
+
+// static
+int GLES1Renderer::VertexArrayIndex(ClientVertexArrayType type, const GLES1State &gles1)
+{
+ switch (type)
+ {
+ case ClientVertexArrayType::Vertex:
+ return kVertexAttribIndex;
+ case ClientVertexArrayType::Normal:
+ return kNormalAttribIndex;
+ case ClientVertexArrayType::Color:
+ return kColorAttribIndex;
+ case ClientVertexArrayType::PointSize:
+ return kPointSizeAttribIndex;
+ case ClientVertexArrayType::TextureCoord:
+ return kTextureCoordAttribIndexBase + gles1.getClientTextureUnit();
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+// static
+ClientVertexArrayType GLES1Renderer::VertexArrayType(int attribIndex)
+{
+ switch (attribIndex)
+ {
+ case kVertexAttribIndex:
+ return ClientVertexArrayType::Vertex;
+ case kNormalAttribIndex:
+ return ClientVertexArrayType::Normal;
+ case kColorAttribIndex:
+ return ClientVertexArrayType::Color;
+ case kPointSizeAttribIndex:
+ return ClientVertexArrayType::PointSize;
+ default:
+ if (attribIndex < kTextureCoordAttribIndexBase + kTexUnitCount)
+ {
+ return ClientVertexArrayType::TextureCoord;
+ }
+ UNREACHABLE();
+ return ClientVertexArrayType::InvalidEnum;
+ }
+}
+
+// static
+int GLES1Renderer::TexCoordArrayIndex(unsigned int unit)
+{
+ return kTextureCoordAttribIndexBase + unit;
+}
+
+void GLES1Renderer::drawTexture(Context *context,
+ State *glState,
+ float x,
+ float y,
+ float z,
+ float width,
+ float height)
+{
+
+ // get viewport
+ const gl::Rectangle &viewport = glState->getViewport();
+
+ // Translate from viewport to NDC for feeding the shader.
+ // Recenter, rescale. (e.g., [0, 0, 1080, 1920] -> [-1, -1, 1, 1])
+ float xNdc = scaleScreenCoordinateToNdc(x, static_cast<GLfloat>(viewport.width));
+ float yNdc = scaleScreenCoordinateToNdc(y, static_cast<GLfloat>(viewport.height));
+ float wNdc = scaleScreenDimensionToNdc(width, static_cast<GLfloat>(viewport.width));
+ float hNdc = scaleScreenDimensionToNdc(height, static_cast<GLfloat>(viewport.height));
+
+ float zNdc = 2.0f * clamp(z, 0.0f, 1.0f) - 1.0f;
+
+ mDrawTextureCoords[0] = xNdc;
+ mDrawTextureCoords[1] = yNdc;
+ mDrawTextureCoords[2] = zNdc;
+
+ mDrawTextureDims[0] = wNdc;
+ mDrawTextureDims[1] = hNdc;
+
+ mDrawTextureEnabled = true;
+
+ AttributesMask prevAttributesMask = glState->gles1().getVertexArraysAttributeMask();
+
+ setAttributesEnabled(context, glState, AttributesMask());
+
+ glState->gles1().setAllDirty();
+
+ context->drawArrays(PrimitiveMode::Triangles, 0, 6);
+
+ setAttributesEnabled(context, glState, prevAttributesMask);
+
+ mDrawTextureEnabled = false;
+}
+
+Shader *GLES1Renderer::getShader(ShaderProgramID handle) const
+{
+ return mShaderPrograms->getShader(handle);
+}
+
+Program *GLES1Renderer::getProgram(ShaderProgramID handle) const
+{
+ return mShaderPrograms->getProgram(handle);
+}
+
+angle::Result GLES1Renderer::compileShader(Context *context,
+ ShaderType shaderType,
+ const char *src,
+ ShaderProgramID *shaderOut)
+{
+ rx::ContextImpl *implementation = context->getImplementation();
+ const Limitations &limitations = implementation->getNativeLimitations();
+
+ ShaderProgramID shader = mShaderPrograms->createShader(implementation, limitations, shaderType);
+
+ Shader *shaderObject = getShader(shader);
+ ANGLE_CHECK(context, shaderObject, "Missing shader object", GL_INVALID_OPERATION);
+
+ shaderObject->setSource(1, &src, nullptr);
+ shaderObject->compile(context);
+
+ *shaderOut = shader;
+
+ if (!shaderObject->isCompiled(context))
+ {
+ GLint infoLogLength = shaderObject->getInfoLogLength(context);
+ std::vector<char> infoLog(infoLogLength, 0);
+ shaderObject->getInfoLog(context, infoLogLength - 1, nullptr, infoLog.data());
+
+ ERR() << "Internal GLES 1 shader compile failed. Info log: " << infoLog.data();
+ ANGLE_CHECK(context, false, "GLES1Renderer shader compile failed.", GL_INVALID_OPERATION);
+ return angle::Result::Stop;
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result GLES1Renderer::linkProgram(Context *context,
+ State *glState,
+ ShaderProgramID vertexShader,
+ ShaderProgramID fragmentShader,
+ const angle::HashMap<GLint, std::string> &attribLocs,
+ ShaderProgramID *programOut)
+{
+ ShaderProgramID program = mShaderPrograms->createProgram(context->getImplementation());
+
+ Program *programObject = getProgram(program);
+ ANGLE_CHECK(context, programObject, "Missing program object", GL_INVALID_OPERATION);
+
+ *programOut = program;
+
+ programObject->attachShader(getShader(vertexShader));
+ programObject->attachShader(getShader(fragmentShader));
+
+ for (auto it : attribLocs)
+ {
+ GLint index = it.first;
+ const std::string &name = it.second;
+ programObject->bindAttributeLocation(index, name.c_str());
+ }
+
+ ANGLE_TRY(programObject->link(context));
+ programObject->resolveLink(context);
+
+ ANGLE_TRY(glState->onProgramExecutableChange(context, programObject));
+
+ if (!programObject->isLinked())
+ {
+ GLint infoLogLength = programObject->getExecutable().getInfoLogLength();
+ std::vector<char> infoLog(infoLogLength, 0);
+ programObject->getExecutable().getInfoLog(infoLogLength - 1, nullptr, infoLog.data());
+
+ ERR() << "Internal GLES 1 shader link failed. Info log: " << infoLog.data();
+ ANGLE_CHECK(context, false, "GLES1Renderer program link failed.", GL_INVALID_OPERATION);
+ return angle::Result::Stop;
+ }
+
+ programObject->detachShader(context, getShader(vertexShader));
+ programObject->detachShader(context, getShader(fragmentShader));
+
+ return angle::Result::Continue;
+}
+
+const char *GLES1Renderer::getShaderBool(GLES1StateEnables state)
+{
+ if (mShaderState.mGLES1StateEnabled[state])
+ {
+ return "true";
+ }
+ else
+ {
+ return "false";
+ }
+}
+
+void GLES1Renderer::addShaderDefine(std::stringstream &outStream,
+ GLES1StateEnables state,
+ const char *enableString)
+{
+ outStream << "\n";
+ outStream << "#define " << enableString << " " << getShaderBool(state);
+}
+
+void GLES1Renderer::addShaderInt(std::stringstream &outStream, const char *name, int value)
+{
+ outStream << "\n";
+ outStream << "const int " << name << " = " << value << ";";
+}
+
+void GLES1Renderer::addShaderIntTexArray(std::stringstream &outStream,
+ const char *texString,
+ GLES1ShaderState::IntTexArray &texState)
+{
+ outStream << "\n";
+ outStream << "const int " << texString << "[kMaxTexUnits] = int[kMaxTexUnits](";
+ for (int i = 0; i < kTexUnitCount; i++)
+ {
+ if (i != 0)
+ {
+ outStream << ", ";
+ }
+ outStream << texState[i];
+ }
+ outStream << ");";
+}
+
+void GLES1Renderer::addShaderBoolTexArray(std::stringstream &outStream,
+ const char *name,
+ GLES1ShaderState::BoolTexArray &value)
+{
+ outStream << std::boolalpha;
+ outStream << "\n";
+ outStream << "bool " << name << "[kMaxTexUnits] = bool[kMaxTexUnits](";
+ for (int i = 0; i < kTexUnitCount; i++)
+ {
+ if (i != 0)
+ {
+ outStream << ", ";
+ }
+ outStream << value[i];
+ }
+ outStream << ");";
+}
+
+void GLES1Renderer::addShaderBoolLightArray(std::stringstream &outStream,
+ const char *name,
+ GLES1ShaderState::BoolLightArray &value)
+{
+ outStream << std::boolalpha;
+ outStream << "\n";
+ outStream << "bool " << name << "[kMaxLights] = bool[kMaxLights](";
+ for (int i = 0; i < kLightCount; i++)
+ {
+ if (i != 0)
+ {
+ outStream << ", ";
+ }
+ outStream << value[i];
+ }
+ outStream << ");";
+}
+
+void GLES1Renderer::addShaderBoolClipPlaneArray(std::stringstream &outStream,
+ const char *name,
+ GLES1ShaderState::BoolClipPlaneArray &value)
+{
+ outStream << std::boolalpha;
+ outStream << "\n";
+ outStream << "bool " << name << "[kMaxClipPlanes] = bool[kMaxClipPlanes](";
+ for (int i = 0; i < kClipPlaneCount; i++)
+ {
+ if (i != 0)
+ {
+ outStream << ", ";
+ }
+ outStream << value[i];
+ }
+ outStream << ");";
+}
+
+void GLES1Renderer::addVertexShaderDefs(std::stringstream &outStream)
+{
+ addShaderDefine(outStream, GLES1StateEnables::Lighting, "enable_lighting");
+ addShaderDefine(outStream, GLES1StateEnables::ColorMaterial, "enable_color_material");
+ addShaderDefine(outStream, GLES1StateEnables::DrawTexture, "enable_draw_texture");
+ addShaderDefine(outStream, GLES1StateEnables::PointRasterization, "point_rasterization");
+ addShaderDefine(outStream, GLES1StateEnables::RescaleNormal, "enable_rescale_normal");
+ addShaderDefine(outStream, GLES1StateEnables::Normalize, "enable_normalize");
+ addShaderDefine(outStream, GLES1StateEnables::LightModelTwoSided, "light_model_two_sided");
+
+ // bool light_enables[kMaxLights] = bool[kMaxLights](...);
+ addShaderBoolLightArray(outStream, "light_enables", mShaderState.lightEnables);
+}
+
+void GLES1Renderer::addFragmentShaderDefs(std::stringstream &outStream)
+{
+ addShaderDefine(outStream, GLES1StateEnables::Fog, "enable_fog");
+ addShaderDefine(outStream, GLES1StateEnables::ClipPlanes, "enable_clip_planes");
+ addShaderDefine(outStream, GLES1StateEnables::DrawTexture, "enable_draw_texture");
+ addShaderDefine(outStream, GLES1StateEnables::PointRasterization, "point_rasterization");
+ addShaderDefine(outStream, GLES1StateEnables::PointSprite, "point_sprite_enabled");
+ addShaderDefine(outStream, GLES1StateEnables::AlphaTest, "enable_alpha_test");
+ addShaderDefine(outStream, GLES1StateEnables::ShadeModelFlat, "shade_model_flat");
+
+ // bool enable_texture_2d[kMaxTexUnits] = bool[kMaxTexUnits](...);
+ addShaderBoolTexArray(outStream, "enable_texture_2d", mShaderState.tex2DEnables);
+
+ // bool enable_texture_cube_map[kMaxTexUnits] = bool[kMaxTexUnits](...);
+ addShaderBoolTexArray(outStream, "enable_texture_cube_map", mShaderState.texCubeEnables);
+
+ // int texture_format[kMaxTexUnits] = int[kMaxTexUnits](...);
+ addShaderIntTexArray(outStream, "texture_format", mShaderState.tex2DFormats);
+
+ // bool point_sprite_coord_replace[kMaxTexUnits] = bool[kMaxTexUnits](...);
+ addShaderBoolTexArray(outStream, "point_sprite_coord_replace",
+ mShaderState.pointSpriteCoordReplaces);
+
+ // bool clip_plane_enables[kMaxClipPlanes] = bool[kMaxClipPlanes](...);
+ addShaderBoolClipPlaneArray(outStream, "clip_plane_enables", mShaderState.clipPlaneEnables);
+
+ // int texture_format[kMaxTexUnits] = int[kMaxTexUnits](...);
+ addShaderIntTexArray(outStream, "texture_env_mode", mShaderState.texEnvModes);
+
+ // int combine_rgb[kMaxTexUnits];
+ addShaderIntTexArray(outStream, "combine_rgb", mShaderState.texCombineRgbs);
+
+ // int combine_alpha[kMaxTexUnits];
+ addShaderIntTexArray(outStream, "combine_alpha", mShaderState.texCombineAlphas);
+
+ // int src0_rgb[kMaxTexUnits];
+ addShaderIntTexArray(outStream, "src0_rgb", mShaderState.texCombineSrc0Rgbs);
+
+ // int src0_alpha[kMaxTexUnits];
+ addShaderIntTexArray(outStream, "src0_alpha", mShaderState.texCombineSrc0Alphas);
+
+ // int src1_rgb[kMaxTexUnits];
+ addShaderIntTexArray(outStream, "src1_rgb", mShaderState.texCombineSrc1Rgbs);
+
+ // int src1_alpha[kMaxTexUnits];
+ addShaderIntTexArray(outStream, "src1_alpha", mShaderState.texCombineSrc1Alphas);
+
+ // int src2_rgb[kMaxTexUnits];
+ addShaderIntTexArray(outStream, "src2_rgb", mShaderState.texCombineSrc2Rgbs);
+
+ // int src2_alpha[kMaxTexUnits];
+ addShaderIntTexArray(outStream, "src2_alpha", mShaderState.texCombineSrc2Alphas);
+
+ // int op0_rgb[kMaxTexUnits];
+ addShaderIntTexArray(outStream, "op0_rgb", mShaderState.texCombineOp0Rgbs);
+
+ // int op0_alpha[kMaxTexUnits];
+ addShaderIntTexArray(outStream, "op0_alpha", mShaderState.texCombineOp0Alphas);
+
+ // int op1_rgb[kMaxTexUnits];
+ addShaderIntTexArray(outStream, "op1_rgb", mShaderState.texCombineOp1Rgbs);
+
+ // int op1_alpha[kMaxTexUnits];
+ addShaderIntTexArray(outStream, "op1_alpha", mShaderState.texCombineOp1Alphas);
+
+ // int op2_rgb[kMaxTexUnits];
+ addShaderIntTexArray(outStream, "op2_rgb", mShaderState.texCombineOp2Rgbs);
+
+ // int op2_alpha[kMaxTexUnits];
+ addShaderIntTexArray(outStream, "op2_alpha", mShaderState.texCombineOp2Alphas);
+
+ // int alpha_func;
+ addShaderInt(outStream, "alpha_func", ToGLenum(mShaderState.alphaTestFunc));
+
+ // int fog_mode;
+ addShaderInt(outStream, "fog_mode", ToGLenum(mShaderState.fogMode));
+}
+
+angle::Result GLES1Renderer::initializeRendererProgram(Context *context, State *glState)
+{
+ // See if we have the shader for this combination of states
+ if (mUberShaderState.find(mShaderState) != mUberShaderState.end())
+ {
+ Program *programObject = getProgram(getUberShaderState().programState.program);
+
+ // If this is different than the current program, we need to sync everything
+ // TODO: This could be optimized to only dirty state that differs between the two programs
+ if (glState->getProgram()->id() != programObject->id())
+ {
+ glState->gles1().setAllDirty();
+ }
+
+ ANGLE_TRY(glState->setProgram(context, programObject));
+ return angle::Result::Continue;
+ }
+
+ if (!mRendererProgramInitialized)
+ {
+ mShaderPrograms = new ShaderProgramManager();
+ }
+
+ // If we get here, we don't have a shader for this state, need to create it
+ GLES1ProgramState &programState = mUberShaderState[mShaderState].programState;
+
+ ShaderProgramID vertexShader;
+ ShaderProgramID fragmentShader;
+
+ std::stringstream GLES1DrawVShaderStateDefs;
+ addVertexShaderDefs(GLES1DrawVShaderStateDefs);
+
+ std::stringstream vertexStream;
+ vertexStream << kGLES1DrawVShaderHeader;
+ vertexStream << GLES1DrawVShaderStateDefs.str();
+ vertexStream << kGLES1DrawVShader;
+
+ ANGLE_TRY(
+ compileShader(context, ShaderType::Vertex, vertexStream.str().c_str(), &vertexShader));
+
+ std::stringstream GLES1DrawFShaderStateDefs;
+ addFragmentShaderDefs(GLES1DrawFShaderStateDefs);
+
+ std::stringstream fragmentStream;
+ fragmentStream << kGLES1DrawFShaderVersion;
+ if (mShaderState.mGLES1StateEnabled[GLES1StateEnables::LogicOpThroughFramebufferFetch])
+ {
+ if (context->getExtensions().shaderFramebufferFetchEXT)
+ {
+ fragmentStream << "#extension GL_EXT_shader_framebuffer_fetch : require\n";
+ }
+ else
+ {
+ fragmentStream << "#extension GL_EXT_shader_framebuffer_fetch_non_coherent : require\n";
+ }
+ }
+ fragmentStream << kGLES1DrawFShaderHeader;
+ fragmentStream << GLES1DrawFShaderStateDefs.str();
+ fragmentStream << kGLES1DrawFShaderUniformDefs;
+ if (mShaderState.mGLES1StateEnabled[GLES1StateEnables::LogicOpThroughFramebufferFetch])
+ {
+ if (context->getExtensions().shaderFramebufferFetchEXT)
+ {
+ fragmentStream << kGLES1DrawFShaderFramebufferFetchOutputDef;
+ }
+ else
+ {
+ fragmentStream << kGLES1DrawFShaderFramebufferFetchNonCoherentOutputDef;
+ }
+ fragmentStream << kGLES1DrawFShaderLogicOpFramebufferFetchEnabled;
+ }
+ else
+ {
+ fragmentStream << kGLES1DrawFShaderOutputDef;
+ fragmentStream << kGLES1DrawFShaderLogicOpFramebufferFetchDisabled;
+ }
+ fragmentStream << kGLES1DrawFShaderFunctions;
+ fragmentStream << kGLES1DrawFShaderMultitexturing;
+ fragmentStream << kGLES1DrawFShaderMain;
+
+ ANGLE_TRY(compileShader(context, ShaderType::Fragment, fragmentStream.str().c_str(),
+ &fragmentShader));
+
+ angle::HashMap<GLint, std::string> attribLocs;
+
+ attribLocs[(GLint)kVertexAttribIndex] = "pos";
+ attribLocs[(GLint)kNormalAttribIndex] = "normal";
+ attribLocs[(GLint)kColorAttribIndex] = "color";
+ attribLocs[(GLint)kPointSizeAttribIndex] = "pointsize";
+
+ for (int i = 0; i < kTexUnitCount; i++)
+ {
+ std::stringstream ss;
+ ss << "texcoord" << i;
+ attribLocs[kTextureCoordAttribIndexBase + i] = ss.str();
+ }
+
+ ANGLE_TRY(linkProgram(context, glState, vertexShader, fragmentShader, attribLocs,
+ &programState.program));
+
+ mShaderPrograms->deleteShader(context, vertexShader);
+ mShaderPrograms->deleteShader(context, fragmentShader);
+
+ Program *programObject = getProgram(programState.program);
+
+ programState.projMatrixLoc = programObject->getUniformLocation("projection");
+ programState.modelviewMatrixLoc = programObject->getUniformLocation("modelview");
+ programState.textureMatrixLoc = programObject->getUniformLocation("texture_matrix");
+ programState.modelviewInvTrLoc = programObject->getUniformLocation("modelview_invtr");
+
+ for (int i = 0; i < kTexUnitCount; i++)
+ {
+ std::stringstream ss2d;
+ std::stringstream sscube;
+
+ ss2d << "tex_sampler" << i;
+ sscube << "tex_cube_sampler" << i;
+
+ programState.tex2DSamplerLocs[i] = programObject->getUniformLocation(ss2d.str().c_str());
+ programState.texCubeSamplerLocs[i] =
+ programObject->getUniformLocation(sscube.str().c_str());
+ }
+
+ programState.textureEnvColorLoc = programObject->getUniformLocation("texture_env_color");
+ programState.rgbScaleLoc = programObject->getUniformLocation("texture_env_rgb_scale");
+ programState.alphaScaleLoc = programObject->getUniformLocation("texture_env_alpha_scale");
+
+ programState.alphaTestRefLoc = programObject->getUniformLocation("alpha_test_ref");
+
+ programState.materialAmbientLoc = programObject->getUniformLocation("material_ambient");
+ programState.materialDiffuseLoc = programObject->getUniformLocation("material_diffuse");
+ programState.materialSpecularLoc = programObject->getUniformLocation("material_specular");
+ programState.materialEmissiveLoc = programObject->getUniformLocation("material_emissive");
+ programState.materialSpecularExponentLoc =
+ programObject->getUniformLocation("material_specular_exponent");
+
+ programState.lightModelSceneAmbientLoc =
+ programObject->getUniformLocation("light_model_scene_ambient");
+
+ programState.lightAmbientsLoc = programObject->getUniformLocation("light_ambients");
+ programState.lightDiffusesLoc = programObject->getUniformLocation("light_diffuses");
+ programState.lightSpecularsLoc = programObject->getUniformLocation("light_speculars");
+ programState.lightPositionsLoc = programObject->getUniformLocation("light_positions");
+ programState.lightDirectionsLoc = programObject->getUniformLocation("light_directions");
+ programState.lightSpotlightExponentsLoc =
+ programObject->getUniformLocation("light_spotlight_exponents");
+ programState.lightSpotlightCutoffAnglesLoc =
+ programObject->getUniformLocation("light_spotlight_cutoff_angles");
+ programState.lightAttenuationConstsLoc =
+ programObject->getUniformLocation("light_attenuation_consts");
+ programState.lightAttenuationLinearsLoc =
+ programObject->getUniformLocation("light_attenuation_linears");
+ programState.lightAttenuationQuadraticsLoc =
+ programObject->getUniformLocation("light_attenuation_quadratics");
+
+ programState.fogDensityLoc = programObject->getUniformLocation("fog_density");
+ programState.fogStartLoc = programObject->getUniformLocation("fog_start");
+ programState.fogEndLoc = programObject->getUniformLocation("fog_end");
+ programState.fogColorLoc = programObject->getUniformLocation("fog_color");
+
+ programState.clipPlanesLoc = programObject->getUniformLocation("clip_planes");
+
+ programState.logicOpLoc = programObject->getUniformLocation("logic_op");
+
+ programState.pointSizeMinLoc = programObject->getUniformLocation("point_size_min");
+ programState.pointSizeMaxLoc = programObject->getUniformLocation("point_size_max");
+ programState.pointDistanceAttenuationLoc =
+ programObject->getUniformLocation("point_distance_attenuation");
+
+ programState.drawTextureCoordsLoc = programObject->getUniformLocation("draw_texture_coords");
+ programState.drawTextureDimsLoc = programObject->getUniformLocation("draw_texture_dims");
+ programState.drawTextureNormalizedCropRectLoc =
+ programObject->getUniformLocation("draw_texture_normalized_crop_rect");
+
+ ANGLE_TRY(glState->setProgram(context, programObject));
+
+ for (int i = 0; i < kTexUnitCount; i++)
+ {
+ setUniform1i(context, programObject, programState.tex2DSamplerLocs[i], i);
+ setUniform1i(context, programObject, programState.texCubeSamplerLocs[i], i + kTexUnitCount);
+ }
+ glState->setObjectDirty(GL_PROGRAM);
+
+ // We just created a new program, we need to sync everything
+ glState->gles1().setAllDirty();
+
+ mRendererProgramInitialized = true;
+ return angle::Result::Continue;
+}
+
+void GLES1Renderer::setUniform1i(Context *context,
+ Program *programObject,
+ UniformLocation location,
+ GLint value)
+{
+ if (location.value == -1)
+ return;
+ programObject->setUniform1iv(context, location, 1, &value);
+}
+
+void GLES1Renderer::setUniform1ui(Program *programObject, UniformLocation location, GLuint value)
+{
+ if (location.value == -1)
+ return;
+ programObject->setUniform1uiv(location, 1, &value);
+}
+
+void GLES1Renderer::setUniform1iv(Context *context,
+ Program *programObject,
+ UniformLocation location,
+ GLint count,
+ const GLint *value)
+{
+ if (location.value == -1)
+ return;
+ programObject->setUniform1iv(context, location, count, value);
+}
+
+void GLES1Renderer::setUniformMatrix4fv(Program *programObject,
+ UniformLocation location,
+ GLint count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ if (location.value == -1)
+ return;
+ programObject->setUniformMatrix4fv(location, count, transpose, value);
+}
+
+void GLES1Renderer::setUniform4fv(Program *programObject,
+ UniformLocation location,
+ GLint count,
+ const GLfloat *value)
+{
+ if (location.value == -1)
+ return;
+ programObject->setUniform4fv(location, count, value);
+}
+
+void GLES1Renderer::setUniform3fv(Program *programObject,
+ UniformLocation location,
+ GLint count,
+ const GLfloat *value)
+{
+ if (location.value == -1)
+ return;
+ programObject->setUniform3fv(location, count, value);
+}
+
+void GLES1Renderer::setUniform2fv(Program *programObject,
+ UniformLocation location,
+ GLint count,
+ const GLfloat *value)
+{
+ if (location.value == -1)
+ return;
+ programObject->setUniform2fv(location, count, value);
+}
+
+void GLES1Renderer::setUniform1f(Program *programObject, UniformLocation location, GLfloat value)
+{
+ if (location.value == -1)
+ return;
+ programObject->setUniform1fv(location, 1, &value);
+}
+
+void GLES1Renderer::setUniform1fv(Program *programObject,
+ UniformLocation location,
+ GLint count,
+ const GLfloat *value)
+{
+ if (location.value == -1)
+ return;
+ programObject->setUniform1fv(location, count, value);
+}
+
+void GLES1Renderer::setAttributesEnabled(Context *context, State *glState, AttributesMask mask)
+{
+ GLES1State &gles1 = glState->gles1();
+
+ ClientVertexArrayType nonTexcoordArrays[] = {
+ ClientVertexArrayType::Vertex,
+ ClientVertexArrayType::Normal,
+ ClientVertexArrayType::Color,
+ ClientVertexArrayType::PointSize,
+ };
+
+ for (const ClientVertexArrayType attrib : nonTexcoordArrays)
+ {
+ int index = VertexArrayIndex(attrib, glState->gles1());
+
+ if (mask.test(index))
+ {
+ gles1.setClientStateEnabled(attrib, true);
+ context->enableVertexAttribArray(index);
+ }
+ else
+ {
+ gles1.setClientStateEnabled(attrib, false);
+ context->disableVertexAttribArray(index);
+ }
+ }
+
+ for (unsigned int i = 0; i < kTexUnitCount; i++)
+ {
+ int index = TexCoordArrayIndex(i);
+
+ if (mask.test(index))
+ {
+ gles1.setTexCoordArrayEnabled(i, true);
+ context->enableVertexAttribArray(index);
+ }
+ else
+ {
+ gles1.setTexCoordArrayEnabled(i, false);
+ context->disableVertexAttribArray(index);
+ }
+ }
+}
+
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/GLES1Renderer.h b/gfx/angle/checkout/src/libANGLE/GLES1Renderer.h
new file mode 100644
index 0000000000..5694b79752
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/GLES1Renderer.h
@@ -0,0 +1,340 @@
+//
+// Copyright 2018 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.
+//
+
+// GLES1Renderer.h: Defines GLES1 emulation rendering operations on top of a GLES3
+// context. Used by Context.h.
+
+#ifndef LIBANGLE_GLES1_RENDERER_H_
+#define LIBANGLE_GLES1_RENDERER_H_
+
+#include "GLES1State.h"
+#include "angle_gl.h"
+#include "common/angleutils.h"
+#include "libANGLE/angletypes.h"
+
+#include <memory>
+#include <string>
+#include <unordered_map>
+
+namespace gl
+{
+class Context;
+class GLES1State;
+class Program;
+class State;
+class Shader;
+class ShaderProgramManager;
+
+enum class GLES1StateEnables : uint64_t
+{
+ Lighting = 0,
+ Fog = 1,
+ ClipPlanes = 2,
+ DrawTexture = 3,
+ PointRasterization = 4,
+ PointSprite = 5,
+ RescaleNormal = 6,
+ Normalize = 7,
+ AlphaTest = 8,
+ ShadeModelFlat = 9,
+ ColorMaterial = 10,
+ LightModelTwoSided = 11,
+ LogicOpThroughFramebufferFetch = 12,
+
+ InvalidEnum = 13,
+ EnumCount = 13,
+};
+
+constexpr int kClipPlaneCount = 6;
+constexpr int kTexUnitCount = 4;
+constexpr int kLightCount = 8;
+
+using GLES1StateEnabledBitSet = angle::PackedEnumBitSet<GLES1StateEnables, uint64_t>;
+
+struct GLES1ShaderState
+{
+ GLES1ShaderState();
+ ~GLES1ShaderState();
+ GLES1ShaderState(const GLES1ShaderState &other);
+
+ size_t hash() const;
+
+ GLES1StateEnabledBitSet mGLES1StateEnabled;
+
+ using BoolLightArray = bool[kLightCount];
+ using BoolTexArray = bool[kTexUnitCount];
+ using BoolClipPlaneArray = bool[kClipPlaneCount];
+ using IntTexArray = int[kTexUnitCount];
+
+ BoolTexArray tex2DEnables = {false, false, false, false};
+ BoolTexArray texCubeEnables = {false, false, false, false};
+
+ IntTexArray tex2DFormats = {GL_RGBA, GL_RGBA, GL_RGBA, GL_RGBA};
+
+ IntTexArray texEnvModes = {};
+ IntTexArray texCombineRgbs = {};
+ IntTexArray texCombineAlphas = {};
+ IntTexArray texCombineSrc0Rgbs = {};
+ IntTexArray texCombineSrc0Alphas = {};
+ IntTexArray texCombineSrc1Rgbs = {};
+ IntTexArray texCombineSrc1Alphas = {};
+ IntTexArray texCombineSrc2Rgbs = {};
+ IntTexArray texCombineSrc2Alphas = {};
+ IntTexArray texCombineOp0Rgbs = {};
+ IntTexArray texCombineOp0Alphas = {};
+ IntTexArray texCombineOp1Rgbs = {};
+ IntTexArray texCombineOp1Alphas = {};
+ IntTexArray texCombineOp2Rgbs = {};
+ IntTexArray texCombineOp2Alphas = {};
+
+ BoolTexArray pointSpriteCoordReplaces = {};
+
+ BoolLightArray lightEnables = {};
+
+ BoolClipPlaneArray clipPlaneEnables = {};
+
+ AlphaTestFunc alphaTestFunc = {};
+
+ FogMode fogMode = {};
+};
+
+bool operator==(const GLES1ShaderState &a, const GLES1ShaderState &b);
+bool operator!=(const GLES1ShaderState &a, const GLES1ShaderState &b);
+
+} // namespace gl
+
+namespace std
+{
+template <>
+struct hash<gl::GLES1ShaderState>
+{
+ size_t operator()(const gl::GLES1ShaderState &key) const { return key.hash(); }
+};
+} // namespace std
+
+namespace gl
+{
+
+class GLES1Renderer final : angle::NonCopyable
+{
+ public:
+ GLES1Renderer();
+ ~GLES1Renderer();
+
+ void onDestroy(Context *context, State *state);
+
+ angle::Result prepareForDraw(PrimitiveMode mode, Context *context, State *glState);
+
+ static int VertexArrayIndex(ClientVertexArrayType type, const GLES1State &gles1);
+ static ClientVertexArrayType VertexArrayType(int attribIndex);
+ static int TexCoordArrayIndex(unsigned int unit);
+
+ void drawTexture(Context *context,
+ State *glState,
+ float x,
+ float y,
+ float z,
+ float width,
+ float height);
+
+ private:
+ using Mat4Uniform = float[16];
+ using Vec4Uniform = float[4];
+ using Vec3Uniform = float[3];
+
+ Shader *getShader(ShaderProgramID handle) const;
+ Program *getProgram(ShaderProgramID handle) const;
+
+ angle::Result compileShader(Context *context,
+ ShaderType shaderType,
+ const char *src,
+ ShaderProgramID *shaderOut);
+ angle::Result linkProgram(Context *context,
+ State *glState,
+ ShaderProgramID vshader,
+ ShaderProgramID fshader,
+ const angle::HashMap<GLint, std::string> &attribLocs,
+ ShaderProgramID *programOut);
+ angle::Result initializeRendererProgram(Context *context, State *glState);
+
+ void setUniform1i(Context *context,
+ Program *programObject,
+ UniformLocation location,
+ GLint value);
+ void setUniform1ui(Program *programObject, UniformLocation location, GLuint value);
+ void setUniform1iv(Context *context,
+ Program *programObject,
+ UniformLocation location,
+ GLint count,
+ const GLint *value);
+ void setUniformMatrix4fv(Program *programObject,
+ UniformLocation location,
+ GLint count,
+ GLboolean transpose,
+ const GLfloat *value);
+ void setUniform4fv(Program *programObject,
+ UniformLocation location,
+ GLint count,
+ const GLfloat *value);
+ void setUniform3fv(Program *programObject,
+ UniformLocation location,
+ GLint count,
+ const GLfloat *value);
+ void setUniform2fv(Program *programObject,
+ UniformLocation location,
+ GLint count,
+ const GLfloat *value);
+ void setUniform1f(Program *programObject, UniformLocation location, GLfloat value);
+ void setUniform1fv(Program *programObject,
+ UniformLocation location,
+ GLint count,
+ const GLfloat *value);
+
+ void setAttributesEnabled(Context *context, State *glState, AttributesMask mask);
+
+ static constexpr int kVertexAttribIndex = 0;
+ static constexpr int kNormalAttribIndex = 1;
+ static constexpr int kColorAttribIndex = 2;
+ static constexpr int kPointSizeAttribIndex = 3;
+ static constexpr int kTextureCoordAttribIndexBase = 4;
+
+ bool mRendererProgramInitialized;
+ ShaderProgramManager *mShaderPrograms;
+
+ GLES1ShaderState mShaderState = {};
+
+ const char *getShaderBool(GLES1StateEnables state);
+ void addShaderDefine(std::stringstream &outStream,
+ GLES1StateEnables state,
+ const char *enableString);
+ void addShaderInt(std::stringstream &outStream, const char *name, int value);
+ void addShaderIntTexArray(std::stringstream &outStream,
+ const char *texString,
+ GLES1ShaderState::IntTexArray &texState);
+ void addShaderBoolTexArray(std::stringstream &outStream,
+ const char *texString,
+ GLES1ShaderState::BoolTexArray &texState);
+ void addShaderBoolLightArray(std::stringstream &outStream,
+ const char *name,
+ GLES1ShaderState::BoolLightArray &value);
+ void addShaderBoolClipPlaneArray(std::stringstream &outStream,
+ const char *name,
+ GLES1ShaderState::BoolClipPlaneArray &value);
+ void addVertexShaderDefs(std::stringstream &outStream);
+ void addFragmentShaderDefs(std::stringstream &outStream);
+
+ struct GLES1ProgramState
+ {
+ ShaderProgramID program;
+
+ UniformLocation projMatrixLoc;
+ UniformLocation modelviewMatrixLoc;
+ UniformLocation textureMatrixLoc;
+ UniformLocation modelviewInvTrLoc;
+
+ // Texturing
+ std::array<UniformLocation, kTexUnitCount> tex2DSamplerLocs;
+ std::array<UniformLocation, kTexUnitCount> texCubeSamplerLocs;
+
+ UniformLocation textureEnvColorLoc;
+ UniformLocation rgbScaleLoc;
+ UniformLocation alphaScaleLoc;
+
+ // Alpha test
+ UniformLocation alphaTestRefLoc;
+
+ // Shading, materials, and lighting
+ UniformLocation materialAmbientLoc;
+ UniformLocation materialDiffuseLoc;
+ UniformLocation materialSpecularLoc;
+ UniformLocation materialEmissiveLoc;
+ UniformLocation materialSpecularExponentLoc;
+
+ UniformLocation lightModelSceneAmbientLoc;
+
+ UniformLocation lightAmbientsLoc;
+ UniformLocation lightDiffusesLoc;
+ UniformLocation lightSpecularsLoc;
+ UniformLocation lightPositionsLoc;
+ UniformLocation lightDirectionsLoc;
+ UniformLocation lightSpotlightExponentsLoc;
+ UniformLocation lightSpotlightCutoffAnglesLoc;
+ UniformLocation lightAttenuationConstsLoc;
+ UniformLocation lightAttenuationLinearsLoc;
+ UniformLocation lightAttenuationQuadraticsLoc;
+
+ // Fog
+ UniformLocation fogDensityLoc;
+ UniformLocation fogStartLoc;
+ UniformLocation fogEndLoc;
+ UniformLocation fogColorLoc;
+
+ // Clip planes
+ UniformLocation clipPlanesLoc;
+
+ // Logic op
+ UniformLocation logicOpLoc;
+
+ // Point rasterization
+ UniformLocation pointSizeMinLoc;
+ UniformLocation pointSizeMaxLoc;
+ UniformLocation pointDistanceAttenuationLoc;
+
+ // Draw texture
+ UniformLocation drawTextureCoordsLoc;
+ UniformLocation drawTextureDimsLoc;
+ UniformLocation drawTextureNormalizedCropRectLoc;
+ };
+
+ struct GLES1UniformBuffers
+ {
+ std::array<Mat4Uniform, kTexUnitCount> textureMatrices;
+
+ std::array<Vec4Uniform, kTexUnitCount> texEnvColors;
+ std::array<GLfloat, kTexUnitCount> texEnvRgbScales;
+ std::array<GLfloat, kTexUnitCount> texEnvAlphaScales;
+
+ // Lighting
+ std::array<Vec4Uniform, kLightCount> lightAmbients;
+ std::array<Vec4Uniform, kLightCount> lightDiffuses;
+ std::array<Vec4Uniform, kLightCount> lightSpeculars;
+ std::array<Vec4Uniform, kLightCount> lightPositions;
+ std::array<Vec3Uniform, kLightCount> lightDirections;
+ std::array<GLfloat, kLightCount> spotlightExponents;
+ std::array<GLfloat, kLightCount> spotlightCutoffAngles;
+ std::array<GLfloat, kLightCount> attenuationConsts;
+ std::array<GLfloat, kLightCount> attenuationLinears;
+ std::array<GLfloat, kLightCount> attenuationQuadratics;
+
+ // Clip planes
+ std::array<Vec4Uniform, kClipPlaneCount> clipPlanes;
+
+ // Texture crop rectangles
+ std::array<Vec4Uniform, kTexUnitCount> texCropRects;
+ };
+
+ struct GLES1UberShaderState
+ {
+ GLES1UniformBuffers uniformBuffers;
+ GLES1ProgramState programState;
+ };
+
+ GLES1UberShaderState &getUberShaderState()
+ {
+ ASSERT(mUberShaderState.find(mShaderState) != mUberShaderState.end());
+ return mUberShaderState[mShaderState];
+ }
+
+ angle::HashMap<GLES1ShaderState, GLES1UberShaderState> mUberShaderState;
+
+ bool mDrawTextureEnabled = false;
+ GLfloat mDrawTextureCoords[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ GLfloat mDrawTextureDims[2] = {0.0f, 0.0f};
+};
+
+} // namespace gl
+
+#endif // LIBANGLE_GLES1_RENDERER_H_
diff --git a/gfx/angle/checkout/src/libANGLE/GLES1Shaders.inc b/gfx/angle/checkout/src/libANGLE/GLES1Shaders.inc
new file mode 100644
index 0000000000..1c1ff51927
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/GLES1Shaders.inc
@@ -0,0 +1,1218 @@
+//
+// Copyright 2018 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.
+//
+
+// GLES1Shaders.inc: Defines GLES1 emulation shader.
+
+// The following variables are added in GLES1Renderer::initializeRendererProgram
+// bool clip_plane_enables
+// bool enable_alpha_test
+// bool enable_clip_planes
+// bool enable_color_material
+// bool enable_draw_texture
+// bool enable_fog
+// bool enable_lighting
+// bool enable_normalize
+// bool enable_rescale_normal
+// bool enable_texture_2d[kMaxTexUnits]
+// bool enable_texture_cube_map[kMaxTexUnits]
+// bool light_enables[kMaxLights]
+// bool light_model_two_sided
+// bool point_rasterization
+// bool point_sprite_coord_replace
+// bool point_sprite_enabled
+// bool shade_model_flat
+// int texture_format[kMaxTexUnits];
+// int texture_env_mode[kMaxTexUnits];
+// int combine_rgb[kMaxTexUnits];
+// int combine_alpha[kMaxTexUnits];
+// int src0_rgb[kMaxTexUnits];
+// int src0_alpha[kMaxTexUnits];
+// int src1_rgb[kMaxTexUnits];
+// int src1_alpha[kMaxTexUnits];
+// int src2_rgb[kMaxTexUnits];
+// int src2_alpha[kMaxTexUnits];
+// int op0_rgb[kMaxTexUnits];
+// int op0_alpha[kMaxTexUnits];
+// int op1_rgb[kMaxTexUnits];
+// int op1_alpha[kMaxTexUnits];
+// int op2_rgb[kMaxTexUnits];
+// int op2_alpha[kMaxTexUnits];
+// int alpha_func;
+// int fog_mode;
+
+constexpr char kGLES1DrawVShaderHeader[] = R"(#version 300 es
+precision highp float;
+
+#define kMaxTexUnits 4
+#define kMaxLights 8
+)";
+
+constexpr char kGLES1DrawVShader[] = R"(
+
+in vec4 pos;
+in vec3 normal;
+in vec4 color;
+in float pointsize;
+in vec4 texcoord0;
+in vec4 texcoord1;
+in vec4 texcoord2;
+in vec4 texcoord3;
+
+uniform mat4 projection;
+uniform mat4 modelview;
+uniform mat4 modelview_invtr;
+uniform mat4 texture_matrix[kMaxTexUnits];
+
+// Point rasterization//////////////////////////////////////////////////////////
+
+uniform float point_size_min;
+uniform float point_size_max;
+uniform vec3 point_distance_attenuation;
+
+// Shading: flat shading, lighting, and materials///////////////////////////////
+
+uniform vec4 material_ambient;
+uniform vec4 material_diffuse;
+uniform vec4 material_specular;
+uniform vec4 material_emissive;
+uniform float material_specular_exponent;
+
+uniform vec4 light_model_scene_ambient;
+
+uniform vec4 light_ambients[kMaxLights];
+uniform vec4 light_diffuses[kMaxLights];
+uniform vec4 light_speculars[kMaxLights];
+uniform vec4 light_positions[kMaxLights];
+uniform vec3 light_directions[kMaxLights];
+uniform float light_spotlight_exponents[kMaxLights];
+uniform float light_spotlight_cutoff_angles[kMaxLights];
+uniform float light_attenuation_consts[kMaxLights];
+uniform float light_attenuation_linears[kMaxLights];
+uniform float light_attenuation_quadratics[kMaxLights];
+
+// GL_OES_draw_texture uniforms/////////////////////////////////////////////////
+
+uniform vec4 draw_texture_coords;
+uniform vec2 draw_texture_dims;
+uniform vec4 draw_texture_normalized_crop_rect[kMaxTexUnits];
+
+// Varyings/////////////////////////////////////////////////////////////////////
+
+out vec4 pos_varying;
+out vec3 normal_varying;
+out vec4 color_varying;
+flat out vec4 color_varying_flat;
+out vec4 texcoord0_varying;
+out vec4 texcoord1_varying;
+out vec4 texcoord2_varying;
+out vec4 texcoord3_varying;
+
+float posDot(vec3 a, vec3 b)
+{
+ return max(dot(a, b), 0.0);
+}
+
+vec4 doLighting(vec4 vertexColor)
+{
+ vec4 materialAmbientActual = material_ambient;
+ vec4 materialDiffuseActual = material_diffuse;
+
+ if (enable_color_material)
+ {
+ materialAmbientActual = vertexColor;
+ materialDiffuseActual = vertexColor;
+ }
+
+ vec4 lightingResult = material_emissive + materialAmbientActual * light_model_scene_ambient;
+
+ for (int i = 0; i < kMaxLights; i++)
+ {
+
+ if (!light_enables[i])
+ continue;
+
+ vec4 lightAmbient = light_ambients[i];
+ vec4 lightDiffuse = light_diffuses[i];
+ vec4 lightSpecular = light_speculars[i];
+ vec4 lightPos = light_positions[i];
+ vec3 lightDir = light_directions[i];
+ float attConst = light_attenuation_consts[i];
+ float attLinear = light_attenuation_linears[i];
+ float attQuadratic = light_attenuation_quadratics[i];
+ float spotAngle = light_spotlight_cutoff_angles[i];
+ float spotExponent = light_spotlight_exponents[i];
+
+ vec3 toLight;
+ if (lightPos.w == 0.0)
+ {
+ toLight = lightPos.xyz;
+ }
+ else
+ {
+ toLight = (lightPos.xyz / lightPos.w - pos_varying.xyz);
+ }
+
+ float lightDist = length(toLight);
+ vec3 h = normalize(toLight) + vec3(0.0, 0.0, 1.0);
+ float ndotL = posDot(normal_varying, normalize(toLight));
+ float ndoth = posDot(normal_varying, normalize(h));
+
+ float specAtt;
+
+ if (ndotL != 0.0)
+ {
+ specAtt = 1.0;
+ }
+ else
+ {
+ specAtt = 0.0;
+ }
+
+ float att;
+
+ if (lightPos.w != 0.0)
+ {
+ float attDenom =
+ (attConst + attLinear * lightDist + attQuadratic * lightDist * lightDist);
+ att = 1.0 / attDenom;
+ }
+ else
+ {
+ att = 1.0;
+ }
+
+ float spot;
+
+ float spotAngleCos = cos(radians(spotAngle));
+ vec3 toSurfaceDir = -normalize(toLight);
+ float spotDot = posDot(toSurfaceDir, normalize(lightDir));
+
+ if (spotAngle == 180.0 || lightPos.w == 0.0)
+ {
+ spot = 1.0;
+ }
+ else
+ {
+ if (spotDot < spotAngleCos)
+ {
+ spot = 0.0;
+ }
+ else
+ {
+ spot = pow(spotDot, spotExponent);
+ }
+ }
+
+ vec4 contrib = materialAmbientActual * lightAmbient;
+ contrib += ndotL * materialDiffuseActual * lightDiffuse;
+ if (ndoth > 0.0 && material_specular_exponent > 0.0)
+ {
+ contrib += specAtt * pow(ndoth, material_specular_exponent) * material_specular *
+ lightSpecular;
+ }
+ else
+ {
+ if (ndoth > 0.0)
+ {
+ contrib += specAtt * material_specular * lightSpecular;
+ }
+ }
+ contrib *= att * spot;
+ lightingResult += contrib;
+ }
+
+ return lightingResult;
+}
+
+const vec4 drawTextureVertices[6] = vec4[](
+ vec4(0.0, 0.0, 0.0, 1.0),
+ vec4(1.0, 0.0, 0.0, 1.0),
+ vec4(1.0, 1.0, 0.0, 1.0),
+ vec4(0.0, 0.0, 0.0, 1.0),
+ vec4(1.0, 1.0, 0.0, 1.0),
+ vec4(0.0, 1.0, 0.0, 1.0));
+
+vec4 drawTexturePosition(int vertexId)
+{
+
+ float drawTexX = draw_texture_coords[0];
+ float drawTexY = draw_texture_coords[1];
+ float drawTexZ = draw_texture_coords[2];
+ float drawTexW = draw_texture_dims[0];
+ float drawTexH = draw_texture_dims[1];
+
+ return vec4(drawTexX, drawTexY, drawTexZ, 0.0) +
+ drawTextureVertices[vertexId] *
+ vec4(drawTexW, drawTexH, 1.0, 1.0);
+}
+
+vec4 drawTextureTexCoord(int vertexId, int textureUnit)
+{
+ float texCropU = draw_texture_normalized_crop_rect[textureUnit].x;
+ float texCropV = draw_texture_normalized_crop_rect[textureUnit].y;
+ float texCropW = draw_texture_normalized_crop_rect[textureUnit].z;
+ float texCropH = draw_texture_normalized_crop_rect[textureUnit].w;
+
+ return vec4(texCropU, texCropV, 0.0, 0.0) +
+ drawTextureVertices[vertexId] *
+ vec4(texCropW, texCropH, 0.0, 0.0);
+}
+
+vec4 calcWorldPosition(vec4 posInput)
+{
+ return modelview * posInput;
+}
+
+vec4 calcNdcFromWorldPosition(vec4 worldPos)
+{
+ return projection * worldPos;
+}
+
+float calcPointSize(vec4 ndcPos)
+{
+ float dist = length(ndcPos.z);
+ float attConst = point_distance_attenuation[0];
+ float attLinear = point_distance_attenuation[1];
+ float attQuad = point_distance_attenuation[2];
+ float attPart = attConst + attLinear * dist + attQuad * dist * dist;
+ float attPointSize = pointsize / pow(attPart, 0.5);
+
+ return clamp(attPointSize, point_size_min, point_size_max);
+}
+
+vec3 calcNormal(vec3 normalInput)
+{
+ mat3 mvInvTr3 = mat3(modelview_invtr);
+ vec3 result = mvInvTr3 * normalInput;
+
+ if (enable_rescale_normal)
+ {
+ float rescale = 1.0;
+ vec3 rescaleVec = vec3(mvInvTr3[2]);
+ float len = length(rescaleVec);
+ if (len > 0.0)
+ {
+ rescale = 1.0 / len;
+ }
+ result *= rescale;
+ }
+
+ if (enable_normalize)
+ {
+ result = normalize(result);
+ }
+
+ return result;
+}
+
+void main()
+{
+ if (enable_draw_texture)
+ {
+ int vertexId = gl_VertexID;
+ vec4 posDrawTexture = drawTexturePosition(vertexId);
+
+ gl_Position = posDrawTexture;
+ pos_varying = posDrawTexture;
+
+ normal_varying = normal;
+
+ gl_PointSize = pointsize;
+
+ texcoord0_varying = drawTextureTexCoord(vertexId, 0);
+ texcoord1_varying = drawTextureTexCoord(vertexId, 1);
+ texcoord2_varying = drawTextureTexCoord(vertexId, 2);
+ texcoord3_varying = drawTextureTexCoord(vertexId, 3);
+ }
+ else
+ {
+ vec4 worldPos = calcWorldPosition(pos);
+ vec4 ndcPos = calcNdcFromWorldPosition(worldPos);
+
+ gl_Position = ndcPos;
+ pos_varying = worldPos;
+
+ normal_varying = calcNormal(normal);
+
+ // Avoid calculating point size stuff
+ // if we are not rendering points.
+ if (point_rasterization)
+ {
+ gl_PointSize = calcPointSize(ndcPos);
+ }
+ else
+ {
+ gl_PointSize = pointsize;
+ }
+
+ texcoord0_varying = texture_matrix[0] * texcoord0;
+ texcoord1_varying = texture_matrix[1] * texcoord1;
+ texcoord2_varying = texture_matrix[2] * texcoord2;
+ texcoord3_varying = texture_matrix[3] * texcoord3;
+ }
+
+ vec4 vertex_color = color;
+
+ if (enable_lighting)
+ {
+ vertex_color = doLighting(color);
+ }
+
+ vertex_color = clamp(vertex_color, vec4(0), vec4(1));
+
+ color_varying = vertex_color;
+ color_varying_flat = vertex_color;
+}
+)";
+
+constexpr char kGLES1DrawFShaderVersion[] = R"(#version 300 es
+)";
+
+constexpr char kGLES1DrawFShaderHeader[] = R"(precision highp float;
+
+// Defines for GL constants
+#define kMaxTexUnits 4
+#define kMaxClipPlanes 6
+
+#define kModulate 0x2100
+#define kDecal 0x2101
+#define kCombine 0x8570
+#define kReplace 0x1E01
+#define kBlend 0x0BE2
+#define kAdd 0x0104
+
+#define kAddSigned 0x8574
+#define kInterpolate 0x8575
+#define kSubtract 0x84E7
+#define kDot3Rgb 0x86AE
+#define kDot3Rgba 0x86AF
+
+#define kAlpha 0x1906
+#define kRGB 0x1907
+#define kRGBA 0x1908
+#define kLuminance 0x1909
+#define kLuminanceAlpha 0x190A
+
+#define kTexture 0x1702
+#define kConstant 0x8576
+#define kPrimaryColor 0x8577
+#define kPrevious 0x8578
+
+#define kSrcColor 0x0300
+#define kOneMinusSrcColor 0x0301
+#define kSrcAlpha 0x0302
+#define kOneMinusSrcAlpha 0x0303
+
+#define kLinear 0x2601
+#define kExp 0x0800
+#define kExp2 0x0801
+
+#define kNever 0x0200
+#define kLess 0x0201
+#define kEqual 0x0202
+#define kLequal 0x0203
+#define kGreater 0x0204
+#define kNotequal 0x0205
+#define kGequal 0x0206
+#define kAlways 0x0207
+#define kZero 0x0
+#define kOne 0x1
+
+#define kAnd 0u
+#define kAndInverted 1u
+#define kAndReverse 2u
+#define kClear 3u
+#define kCopy 4u
+#define kCopyInverted 5u
+#define kEquiv 6u
+#define kInvert 7u
+#define kNand 8u
+#define kNoop 9u
+#define kNor 10u
+#define kOr 11u
+#define kOrInverted 12u
+#define kOrReverse 13u
+#define kSet 14u
+#define kXor 15u
+)";
+
+constexpr char kGLES1DrawFShaderUniformDefs[] = R"(
+
+// Texture units ///////////////////////////////////////////////////////////////
+
+// These are not arrays because hw support for arrays
+// of samplers is rather lacking.
+
+uniform sampler2D tex_sampler0;
+uniform samplerCube tex_cube_sampler0;
+
+uniform sampler2D tex_sampler1;
+uniform samplerCube tex_cube_sampler1;
+
+uniform sampler2D tex_sampler2;
+uniform samplerCube tex_cube_sampler2;
+
+uniform sampler2D tex_sampler3;
+uniform samplerCube tex_cube_sampler3;
+
+uniform vec4 texture_env_color[kMaxTexUnits];
+uniform float texture_env_rgb_scale[kMaxTexUnits];
+uniform float texture_env_alpha_scale[kMaxTexUnits];
+
+// Vertex attributes////////////////////////////////////////////////////////////
+
+in vec4 pos_varying;
+in vec3 normal_varying;
+in vec4 color_varying;
+flat in vec4 color_varying_flat;
+in vec4 texcoord0_varying;
+in vec4 texcoord1_varying;
+in vec4 texcoord2_varying;
+in vec4 texcoord3_varying;
+
+// Alpha test///////////////////////////////////////////////////////////////////
+
+uniform float alpha_test_ref;
+
+// Fog /////////////////////////////////////////////////////////////////////////
+
+uniform float fog_density;
+uniform float fog_start;
+uniform float fog_end;
+uniform vec4 fog_color;
+
+// User clip plane /////////////////////////////////////////////////////////////
+
+uniform vec4 clip_planes[kMaxClipPlanes];
+
+// Logic Op ////////////////////////////////////////////////////////////////////
+
+// Format is:
+// - 4x4 bits depicting the bit width of each channel of color output
+// - 4 bits for the op based on LogicalOperation's packing
+uniform highp uint logic_op;
+
+// Point rasterization//////////////////////////////////////////////////////////
+
+// GL_OES_draw_texture//////////////////////////////////////////////////////////
+)";
+
+constexpr char kGLES1DrawFShaderOutputDef[] = R"(
+out vec4 frag_color;
+)";
+
+constexpr char kGLES1DrawFShaderFramebufferFetchOutputDef[] = R"(
+inout vec4 frag_color;
+)";
+
+constexpr char kGLES1DrawFShaderFramebufferFetchNonCoherentOutputDef[] = R"(
+layout(noncoherent) inout vec4 frag_color;
+)";
+
+constexpr char kGLES1DrawFShaderFunctions[] = R"(
+
+bool doAlphaTest(vec4 currentFragment)
+{
+ bool shouldPassAlpha = false;
+ float incAlpha = currentFragment.a;
+
+ switch (alpha_func)
+ {
+ case kNever:
+ shouldPassAlpha = false;
+ break;
+ case kLess:
+ shouldPassAlpha = incAlpha < alpha_test_ref;
+ break;
+ case kLequal:
+ shouldPassAlpha = incAlpha <= alpha_test_ref;
+ break;
+ case kEqual:
+ shouldPassAlpha = incAlpha == alpha_test_ref;
+ break;
+ case kGequal:
+ shouldPassAlpha = incAlpha >= alpha_test_ref;
+ break;
+ case kGreater:
+ shouldPassAlpha = incAlpha > alpha_test_ref;
+ break;
+ case kNotequal:
+ shouldPassAlpha = incAlpha != alpha_test_ref;
+ break;
+ case kAlways:
+ default:
+ shouldPassAlpha = true;
+ break;
+ }
+
+ return shouldPassAlpha;
+}
+
+bool doClipPlaneTest()
+{
+ bool res = true;
+
+ for (int i = 0; i < kMaxClipPlanes; i++)
+ {
+ if (clip_plane_enables[i])
+ {
+ float dist = dot(clip_planes[i].xyz, pos_varying.xyz) + clip_planes[i].w * pos_varying.w;
+ res = res && (dist >= 0.0);
+ }
+ }
+
+ return res;
+}
+
+vec4 doFog(vec4 currentFragment)
+{
+
+ float eyeDist = -pos_varying.z / pos_varying.w;
+ float f = 1.0;
+ switch (fog_mode)
+ {
+ case kExp:
+ f = exp(-fog_density * eyeDist);
+ break;
+ case kExp2:
+ f = exp(-(pow(fog_density * eyeDist, 2.0)));
+ break;
+ case kLinear:
+ f = (fog_end - eyeDist) / (fog_end - fog_start);
+ break;
+ default:
+ break;
+ }
+
+ f = clamp(f, 0.0, 1.0);
+ vec4 result = vec4(f * currentFragment.rgb + (1.0 - f) * fog_color.rgb, currentFragment.a);
+ return result;
+}
+)";
+
+constexpr char kGLES1DrawFShaderLogicOpFramebufferFetchDisabled[] = R"(
+vec4 applyLogicOp(vec4 currentFragment)
+{
+ return currentFragment;
+}
+)";
+
+// applyLogicOp takes logic-op information from a packed uniform and applies it to the color
+// attachment using framebuffer fetch. See the description of logic_op above for the format of the
+// uniform.
+//
+// In particular, 4 bits in logic_op (at offset 16) contain the packed logical operation (of
+// LogicalOperation type). Based on the selected operation, the formula specified in the spec is
+// applied (applied as bitwise operations on unorm values).
+constexpr char kGLES1DrawFShaderLogicOpFramebufferFetchEnabled[] = R"(
+vec4 applyLogicOp(vec4 currentFragment)
+{
+ vec4 previousFragment = frag_color;
+
+ mediump uvec4 channelWidths = uvec4(logic_op & 0xFu,
+ logic_op >> 4u & 0xFu,
+ logic_op >> 8u & 0xFu,
+ logic_op >> 12u & 0xFu);
+
+ mediump uvec4 channelMasks = (uvec4(1) << channelWidths) - 1u;
+
+ mediump uvec4 src = uvec4(round(currentFragment * vec4(channelMasks)));
+ mediump uvec4 dst = uvec4(round(previousFragment * vec4(channelMasks)));
+ mediump uvec4 result;
+
+ switch (logic_op >> 16u & 0xFu)
+ {
+ case kAnd:
+ result = src & dst;
+ break;
+ case kAndInverted:
+ result = ~src & dst;
+ break;
+ case kAndReverse:
+ result = src & ~dst;
+ break;
+ case kClear:
+ result = uvec4(0);
+ break;
+ case kCopy:
+ result = src;
+ break;
+ case kCopyInverted:
+ result = ~src;
+ break;
+ case kEquiv:
+ result = ~(src ^ dst);
+ break;
+ case kInvert:
+ result = ~dst;
+ break;
+ case kNand:
+ result = ~(src & dst);
+ break;
+ case kNoop:
+ result = dst;
+ break;
+ case kNor:
+ result = ~(src | dst);
+ break;
+ case kOr:
+ result = src | dst;
+ break;
+ case kOrInverted:
+ result = ~src | dst;
+ break;
+ case kOrReverse:
+ result = src | ~dst;
+ break;
+ case kSet:
+ result = channelMasks;
+ break;
+ case kXor:
+ result = src ^ dst;
+ break;
+ }
+
+ result &= channelMasks;
+
+ // Avoid division by zero for formats without alpha
+ channelMasks.a = max(channelMasks.a, 1u);
+
+ return vec4(result) / vec4(channelMasks);
+}
+)";
+
+constexpr char kGLES1DrawFShaderMultitexturing[] = R"(
+
+bool isTextureUnitEnabled(int unit)
+{
+ return enable_texture_2d[unit] || enable_texture_cube_map[unit];
+}
+
+vec4 getTextureColor(int unit)
+{
+ vec4 res;
+
+ switch (unit)
+ {
+ case 0:
+ if (enable_texture_2d[0])
+ {
+ res = texture(tex_sampler0, texcoord0_varying.xy);
+ }
+ else if (enable_texture_cube_map[0])
+ {
+ res = texture(tex_cube_sampler0, texcoord0_varying.xyz);
+ }
+ break;
+ case 1:
+ if (enable_texture_2d[1])
+ {
+ res = texture(tex_sampler1, texcoord1_varying.xy);
+ }
+ else if (enable_texture_cube_map[1])
+ {
+ res = texture(tex_cube_sampler1, texcoord1_varying.xyz);
+ }
+ break;
+ case 2:
+ if (enable_texture_2d[2])
+ {
+ res = texture(tex_sampler2, texcoord2_varying.xy);
+ }
+ else if (enable_texture_cube_map[2])
+ {
+ res = texture(tex_cube_sampler2, texcoord2_varying.xyz);
+ }
+ break;
+ case 3:
+ if (enable_texture_2d[3])
+ {
+ res = texture(tex_sampler3, texcoord3_varying.xy);
+ }
+ else if (enable_texture_cube_map[3])
+ {
+ // TODO: Weird stuff happens
+ // res = texture(tex_cube_sampler3, texcoord3_varying.xyz);
+ }
+ break;
+ default:
+ break;
+ }
+
+ return res;
+}
+
+vec4 getPointSpriteTextureColor(int unit)
+{
+ vec4 res;
+
+ switch (unit)
+ {
+ case 0:
+ if (enable_texture_2d[0])
+ {
+ res = texture(tex_sampler0, gl_PointCoord.xy);
+ }
+ break;
+ case 1:
+ if (enable_texture_2d[1])
+ {
+ res = texture(tex_sampler1, gl_PointCoord.xy);
+ }
+ break;
+ case 2:
+ if (enable_texture_2d[2])
+ {
+ res = texture(tex_sampler2, gl_PointCoord.xy);
+ }
+ break;
+ case 3:
+ if (enable_texture_2d[3])
+ {
+ res = texture(tex_sampler3, gl_PointCoord.xy);
+ }
+ break;
+ default:
+ break;
+ }
+
+ return res;
+}
+
+vec3 textureCombineSrcnOpnRgb(int srcnRgb,
+ int opnRgb,
+ vec4 textureEnvColor,
+ vec4 vertexColor,
+ vec4 texturePrevColor,
+ vec4 textureColor)
+{
+ vec3 res;
+ vec4 op;
+
+ switch (srcnRgb)
+ {
+ case kTexture:
+ op = textureColor;
+ break;
+ case kConstant:
+ op = textureEnvColor;
+ break;
+ case kPrimaryColor:
+ op = vertexColor;
+ break;
+ case kPrevious:
+ op = texturePrevColor;
+ break;
+ default:
+ op = texturePrevColor;
+ break;
+ }
+
+ switch (opnRgb)
+ {
+ case kSrcColor:
+ res = op.rgb;
+ break;
+ case kOneMinusSrcColor:
+ res = 1.0 - op.rgb;
+ break;
+ case kSrcAlpha:
+ res = vec3(op.a, op.a, op.a);
+ break;
+ case kOneMinusSrcAlpha:
+ res = vec3(1.0 - op.a, 1.0 - op.a, 1.0 - op.a);
+ break;
+ default:
+ break;
+ }
+
+ return res;
+}
+
+float textureCombineSrcnOpnAlpha(int srcn,
+ int opn,
+ vec4 textureEnvColor,
+ vec4 vertexColor,
+ vec4 texturePrevColor,
+ vec4 textureColor)
+{
+ float res;
+ vec4 op;
+
+ switch (srcn)
+ {
+ case kTexture:
+ op = textureColor;
+ break;
+ case kConstant:
+ op = textureEnvColor;
+ break;
+ case kPrimaryColor:
+ op = vertexColor;
+ break;
+ case kPrevious:
+ op = texturePrevColor;
+ break;
+ default:
+ op = texturePrevColor;
+ break;
+ }
+
+ switch (opn)
+ {
+ case kSrcAlpha:
+ res = op.a;
+ break;
+ case kOneMinusSrcAlpha:
+ res = 1.0 - op.a;
+ break;
+ default:
+ break;
+ }
+
+ return res;
+}
+
+vec4 textureCombine(int combineRgb,
+ int combineAlpha,
+ int src0Rgb,
+ int src0Alpha,
+ int src1Rgb,
+ int src1Alpha,
+ int src2Rgb,
+ int src2Alpha,
+ int op0Rgb,
+ int op0Alpha,
+ int op1Rgb,
+ int op1Alpha,
+ int op2Rgb,
+ int op2Alpha,
+ vec4 textureEnvColor,
+ float rgbScale,
+ float alphaScale,
+ vec4 vertexColor,
+ vec4 texturePrevColor,
+ vec4 textureColor)
+{
+
+ vec3 resRgb;
+ float resAlpha;
+
+ vec3 arg0Rgb;
+ float arg0Alpha;
+ vec3 arg1Rgb;
+ float arg1Alpha;
+ vec3 arg2Rgb;
+ float arg2Alpha;
+ float dotVal;
+
+ arg0Rgb = textureCombineSrcnOpnRgb(src0Rgb, op0Rgb, textureEnvColor, vertexColor,
+ texturePrevColor, textureColor);
+ arg0Alpha = textureCombineSrcnOpnAlpha(src0Alpha, op0Alpha, textureEnvColor, vertexColor,
+ texturePrevColor, textureColor);
+
+ if (combineRgb != kReplace)
+ {
+ arg1Rgb = textureCombineSrcnOpnRgb(src1Rgb, op1Rgb, textureEnvColor, vertexColor,
+ texturePrevColor, textureColor);
+ }
+
+ if (combineAlpha != kReplace)
+ {
+ arg1Alpha = textureCombineSrcnOpnAlpha(src1Alpha, op1Alpha, textureEnvColor, vertexColor,
+ texturePrevColor, textureColor);
+ }
+
+ if (combineRgb == kInterpolate)
+ {
+ arg2Rgb = textureCombineSrcnOpnRgb(src2Rgb, op2Rgb, textureEnvColor, vertexColor,
+ texturePrevColor, textureColor);
+ }
+
+ if (combineAlpha == kInterpolate)
+ {
+ arg2Alpha = textureCombineSrcnOpnAlpha(src2Alpha, op2Alpha, textureEnvColor, vertexColor,
+ texturePrevColor, textureColor);
+ }
+
+ switch (combineRgb)
+ {
+ case kReplace:
+ resRgb = arg0Rgb;
+ break;
+ case kModulate:
+ resRgb = arg0Rgb * arg1Rgb;
+ break;
+ case kAdd:
+ resRgb = arg0Rgb + arg1Rgb;
+ break;
+ case kAddSigned:
+ resRgb = arg0Rgb + arg1Rgb - 0.5;
+ break;
+ case kInterpolate:
+ resRgb = arg0Rgb * arg2Rgb + arg1Rgb * (1.0 - arg2Rgb);
+ break;
+ case kSubtract:
+ resRgb = arg0Rgb - arg1Rgb;
+ break;
+ default:
+ break;
+ }
+
+ switch (combineAlpha)
+ {
+ case kReplace:
+ resAlpha = arg0Alpha;
+ break;
+ case kModulate:
+ resAlpha = arg0Alpha * arg1Alpha;
+ break;
+ case kAdd:
+ resAlpha = arg0Alpha + arg1Alpha;
+ break;
+ case kAddSigned:
+ resAlpha = arg0Alpha + arg1Alpha - 0.5;
+ break;
+ case kInterpolate:
+ resAlpha = arg0Alpha * arg2Alpha + arg1Alpha * (1.0 - arg2Alpha);
+ break;
+ case kSubtract:
+ resAlpha = arg0Alpha - arg1Alpha;
+ break;
+ default:
+ break;
+ }
+
+ if (combineRgb == kDot3Rgb || combineRgb == kDot3Rgba)
+ {
+ dotVal = 4.0 * dot(arg0Rgb - 0.5, arg1Rgb - 0.5);
+
+ if (combineRgb == kDot3Rgb)
+ {
+ return vec4(dotVal, dotVal, dotVal, resAlpha);
+ }
+ else
+ {
+ return vec4(dotVal, dotVal, dotVal, dotVal);
+ }
+ }
+ else
+ {
+ return vec4(resRgb, resAlpha);
+ }
+}
+
+vec4 textureFunction(int unit,
+ int texFormat,
+ int envMode,
+ int combineRgb,
+ int combineAlpha,
+ int src0Rgb,
+ int src0Alpha,
+ int src1Rgb,
+ int src1Alpha,
+ int src2Rgb,
+ int src2Alpha,
+ int op0Rgb,
+ int op0Alpha,
+ int op1Rgb,
+ int op1Alpha,
+ int op2Rgb,
+ int op2Alpha,
+ vec4 textureEnvColor,
+ float rgbScale,
+ float alphaScale,
+ vec4 vertexColor,
+ vec4 texturePrevColor,
+ vec4 textureColor)
+{
+
+ if (!isTextureUnitEnabled(unit))
+ {
+ return texturePrevColor;
+ }
+
+ vec4 res;
+
+ switch (envMode)
+ {
+ case kReplace:
+ switch (texFormat)
+ {
+ case kAlpha:
+ res.rgb = texturePrevColor.rgb;
+ res.a = textureColor.a;
+ break;
+ case kRGBA:
+ case kLuminanceAlpha:
+ res.rgba = textureColor.rgba;
+ break;
+ case kRGB:
+ case kLuminance:
+ default:
+ res.rgb = textureColor.rgb;
+ res.a = texturePrevColor.a;
+ break;
+ }
+ break;
+ case kModulate:
+ switch (texFormat)
+ {
+ case kAlpha:
+ res.rgb = texturePrevColor.rgb;
+ res.a = texturePrevColor.a * textureColor.a;
+ break;
+ case kRGBA:
+ case kLuminanceAlpha:
+ res.rgba = texturePrevColor.rgba * textureColor.rgba;
+ break;
+ case kRGB:
+ case kLuminance:
+ default:
+ res.rgb = texturePrevColor.rgb * textureColor.rgb;
+ res.a = texturePrevColor.a;
+ break;
+ }
+ break;
+ case kDecal:
+ switch (texFormat)
+ {
+ case kRGB:
+ res.rgb = textureColor.rgb;
+ res.a = texturePrevColor.a;
+ break;
+ case kRGBA:
+ res.rgb = texturePrevColor.rgb * (1.0 - textureColor.a) +
+ textureColor.rgb * textureColor.a;
+ res.a = texturePrevColor.a;
+ break;
+ case kAlpha:
+ case kLuminance:
+ case kLuminanceAlpha:
+ default:
+ res.rgb = texturePrevColor.rgb * textureColor.rgb;
+ res.a = texturePrevColor.a;
+ break;
+ }
+ break;
+ case kBlend:
+ switch (texFormat)
+ {
+ case kAlpha:
+ res.rgb = texturePrevColor.rgb;
+ res.a = textureColor.a * texturePrevColor.a;
+ break;
+ case kLuminance:
+ case kRGB:
+ res.rgb = texturePrevColor.rgb * (1.0 - textureColor.rgb) +
+ textureEnvColor.rgb * textureColor.rgb;
+ res.a = texturePrevColor.a;
+ break;
+ case kLuminanceAlpha:
+ case kRGBA:
+ default:
+ res.rgb = texturePrevColor.rgb * (1.0 - textureColor.rgb) +
+ textureEnvColor.rgb * textureColor.rgb;
+ res.a = textureColor.a * texturePrevColor.a;
+ break;
+ }
+ break;
+ case kAdd:
+ switch (texFormat)
+ {
+ case kAlpha:
+ res.rgb = texturePrevColor.rgb;
+ res.a = textureColor.a * texturePrevColor.a;
+ break;
+ case kLuminance:
+ case kRGB:
+ res.rgb = texturePrevColor.rgb + textureColor.rgb;
+ res.a = texturePrevColor.a;
+ break;
+ case kLuminanceAlpha:
+ case kRGBA:
+ default:
+ res.rgb = texturePrevColor.rgb + textureColor.rgb;
+ res.a = textureColor.a * texturePrevColor.a;
+ break;
+ }
+ break;
+ case kCombine:
+ res = textureCombine(combineRgb, combineAlpha, src0Rgb, src0Alpha, src1Rgb, src1Alpha,
+ src2Rgb, src2Alpha, op0Rgb, op0Alpha, op1Rgb, op1Alpha, op2Rgb,
+ op2Alpha, textureEnvColor, rgbScale, alphaScale, vertexColor,
+ texturePrevColor, textureColor);
+ res.rgb *= rgbScale;
+ res.a *= alphaScale;
+ break;
+ default:
+ break;
+ }
+
+ return clamp(res, 0.0, 1.0);
+}
+)";
+
+constexpr char kGLES1DrawFShaderMain[] = R"(
+void main()
+{
+ if (enable_clip_planes && !enable_draw_texture)
+ {
+ if (!doClipPlaneTest())
+ {
+ discard;
+ }
+ }
+
+ vec4 vertex_color;
+
+ if (shade_model_flat)
+ {
+ vertex_color = color_varying_flat;
+ }
+ else
+ {
+ vertex_color = color_varying;
+ }
+
+ vec4 currentFragment = vertex_color;
+
+ vec4 texturePrevColor = currentFragment;
+
+ for (int i = 0; i < kMaxTexUnits; i++)
+ {
+ vec4 textureColor;
+
+ if (point_rasterization && point_sprite_enabled &&
+ point_sprite_coord_replace[i]) {
+ textureColor = getPointSpriteTextureColor(i);
+ } else {
+ textureColor = getTextureColor(i);
+ }
+
+ currentFragment = textureFunction(
+ i, texture_format[i], texture_env_mode[i], combine_rgb[i], combine_alpha[i],
+ src0_rgb[i], src0_alpha[i], src1_rgb[i], src1_alpha[i], src2_rgb[i], src2_alpha[i],
+ op0_rgb[i], op0_alpha[i], op1_rgb[i], op1_alpha[i], op2_rgb[i], op2_alpha[i],
+ texture_env_color[i], texture_env_rgb_scale[i], texture_env_alpha_scale[i],
+ vertex_color, texturePrevColor, textureColor);
+
+ texturePrevColor = currentFragment;
+ }
+
+ if (enable_fog)
+ {
+ currentFragment = doFog(currentFragment);
+ }
+
+ if (enable_alpha_test && !doAlphaTest(currentFragment))
+ {
+ discard;
+ }
+
+ frag_color = applyLogicOp(currentFragment);
+}
+)";
diff --git a/gfx/angle/checkout/src/libANGLE/GLES1State.cpp b/gfx/angle/checkout/src/libANGLE/GLES1State.cpp
new file mode 100644
index 0000000000..17ad0de3ad
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/GLES1State.cpp
@@ -0,0 +1,609 @@
+//
+// Copyright 2018 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.
+//
+
+// GLES1State.cpp: Implements the GLES1State class, tracking state
+// for GLES1 contexts.
+
+#include "libANGLE/GLES1State.h"
+
+#include "libANGLE/Context.h"
+#include "libANGLE/GLES1Renderer.h"
+
+namespace gl
+{
+
+TextureCoordF::TextureCoordF() = default;
+
+TextureCoordF::TextureCoordF(float _s, float _t, float _r, float _q) : s(_s), t(_t), r(_r), q(_q) {}
+
+bool TextureCoordF::operator==(const TextureCoordF &other) const
+{
+ return s == other.s && t == other.t && r == other.r && q == other.q;
+}
+
+MaterialParameters::MaterialParameters() = default;
+
+LightModelParameters::LightModelParameters() = default;
+
+LightParameters::LightParameters() = default;
+
+LightParameters::LightParameters(const LightParameters &other) = default;
+
+FogParameters::FogParameters() = default;
+
+TextureEnvironmentParameters::TextureEnvironmentParameters() = default;
+
+TextureEnvironmentParameters::TextureEnvironmentParameters(
+ const TextureEnvironmentParameters &other) = default;
+
+PointParameters::PointParameters() = default;
+
+PointParameters::PointParameters(const PointParameters &other) = default;
+
+ClipPlaneParameters::ClipPlaneParameters() = default;
+
+ClipPlaneParameters::ClipPlaneParameters(bool enabled, const angle::Vector4 &equation)
+ : enabled(enabled), equation(equation)
+{}
+
+ClipPlaneParameters::ClipPlaneParameters(const ClipPlaneParameters &other) = default;
+
+ClipPlaneParameters &ClipPlaneParameters::operator=(const ClipPlaneParameters &other) = default;
+
+GLES1State::GLES1State()
+ : mGLState(nullptr),
+ mVertexArrayEnabled(false),
+ mNormalArrayEnabled(false),
+ mColorArrayEnabled(false),
+ mPointSizeArrayEnabled(false),
+ mLineSmoothEnabled(false),
+ mPointSmoothEnabled(false),
+ mPointSpriteEnabled(false),
+ mAlphaTestEnabled(false),
+ mLogicOpEnabled(false),
+ mLightingEnabled(false),
+ mFogEnabled(false),
+ mRescaleNormalEnabled(false),
+ mNormalizeEnabled(false),
+ mColorMaterialEnabled(false),
+ mReflectionMapEnabled(false),
+ mCurrentColor({0.0f, 0.0f, 0.0f, 0.0f}),
+ mCurrentNormal({0.0f, 0.0f, 0.0f}),
+ mClientActiveTexture(0),
+ mMatrixMode(MatrixType::Modelview),
+ mShadeModel(ShadingModel::Smooth),
+ mAlphaTestFunc(AlphaTestFunc::AlwaysPass),
+ mAlphaTestRef(0.0f),
+ mLogicOp(LogicalOperation::Copy),
+ mLineSmoothHint(HintSetting::DontCare),
+ mPointSmoothHint(HintSetting::DontCare),
+ mPerspectiveCorrectionHint(HintSetting::DontCare),
+ mFogHint(HintSetting::DontCare)
+{}
+
+GLES1State::~GLES1State() = default;
+
+// Taken from the GLES 1.x spec which specifies all initial state values.
+void GLES1State::initialize(const Context *context, const State *state)
+{
+ mGLState = state;
+
+ const Caps &caps = context->getCaps();
+
+ mTexUnitEnables.resize(caps.maxMultitextureUnits);
+ for (auto &enables : mTexUnitEnables)
+ {
+ enables.reset();
+ }
+
+ mVertexArrayEnabled = false;
+ mNormalArrayEnabled = false;
+ mColorArrayEnabled = false;
+ mPointSizeArrayEnabled = false;
+ mTexCoordArrayEnabled.resize(caps.maxMultitextureUnits, false);
+
+ mLineSmoothEnabled = false;
+ mPointSmoothEnabled = false;
+ mPointSpriteEnabled = false;
+ mLogicOpEnabled = false;
+ mAlphaTestEnabled = false;
+ mLightingEnabled = false;
+ mFogEnabled = false;
+ mRescaleNormalEnabled = false;
+ mNormalizeEnabled = false;
+ mColorMaterialEnabled = false;
+ mReflectionMapEnabled = false;
+
+ mMatrixMode = MatrixType::Modelview;
+
+ mCurrentColor = {1.0f, 1.0f, 1.0f, 1.0f};
+ mCurrentNormal = {0.0f, 0.0f, 1.0f};
+ mCurrentTextureCoords.resize(caps.maxMultitextureUnits);
+ mClientActiveTexture = 0;
+
+ mTextureEnvironments.resize(caps.maxMultitextureUnits);
+
+ mModelviewMatrices.push_back(angle::Mat4());
+ mProjectionMatrices.push_back(angle::Mat4());
+ mTextureMatrices.resize(caps.maxMultitextureUnits);
+ for (auto &stack : mTextureMatrices)
+ {
+ stack.push_back(angle::Mat4());
+ }
+
+ mMaterial.ambient = {0.2f, 0.2f, 0.2f, 1.0f};
+ mMaterial.diffuse = {0.8f, 0.8f, 0.8f, 1.0f};
+ mMaterial.specular = {0.0f, 0.0f, 0.0f, 1.0f};
+ mMaterial.emissive = {0.0f, 0.0f, 0.0f, 1.0f};
+
+ mMaterial.specularExponent = 0.0f;
+
+ mLightModel.color = {0.2f, 0.2f, 0.2f, 1.0f};
+ mLightModel.twoSided = false;
+
+ mLights.resize(caps.maxLights);
+
+ // GL_LIGHT0 is special and has default state that avoids all-black renderings.
+ mLights[0].diffuse = {1.0f, 1.0f, 1.0f, 1.0f};
+ mLights[0].specular = {1.0f, 1.0f, 1.0f, 1.0f};
+
+ mFog.mode = FogMode::Exp;
+ mFog.density = 1.0f;
+ mFog.start = 0.0f;
+ mFog.end = 1.0f;
+
+ mFog.color = {0.0f, 0.0f, 0.0f, 0.0f};
+
+ mShadeModel = ShadingModel::Smooth;
+
+ mAlphaTestFunc = AlphaTestFunc::AlwaysPass;
+ mAlphaTestRef = 0.0f;
+
+ mLogicOp = LogicalOperation::Copy;
+
+ mClipPlanes.resize(caps.maxClipPlanes,
+ ClipPlaneParameters(false, angle::Vector4(0.0f, 0.0f, 0.0f, 0.0f)));
+
+ mLineSmoothHint = HintSetting::DontCare;
+ mPointSmoothHint = HintSetting::DontCare;
+ mPerspectiveCorrectionHint = HintSetting::DontCare;
+ mFogHint = HintSetting::DontCare;
+
+ // The user-specified point size, GL_POINT_SIZE_MAX,
+ // is initially equal to the implementation maximum.
+ mPointParameters.pointSizeMax = caps.maxAliasedPointSize;
+
+ mDirtyBits.set();
+}
+
+void GLES1State::setAlphaFunc(AlphaTestFunc func, GLfloat ref)
+{
+ setDirty(DIRTY_GLES1_ALPHA_TEST);
+ mAlphaTestFunc = func;
+ mAlphaTestRef = ref;
+}
+
+void GLES1State::setClientTextureUnit(unsigned int unit)
+{
+ setDirty(DIRTY_GLES1_CLIENT_ACTIVE_TEXTURE);
+ mClientActiveTexture = unit;
+}
+
+unsigned int GLES1State::getClientTextureUnit() const
+{
+ return mClientActiveTexture;
+}
+
+void GLES1State::setCurrentColor(const ColorF &color)
+{
+ setDirty(DIRTY_GLES1_CURRENT_VECTOR);
+ mCurrentColor = color;
+
+ // > When enabled, both the ambient (acm) and diffuse (dcm) properties of both the front and
+ // > back material are immediately set to the value of the current color, and will track changes
+ // > to the current color resulting from either the Color commands or drawing vertex arrays with
+ // > the color array enabled.
+ // > The replacements made to material properties are permanent; the replaced values remain
+ // > until changed by either sending a new color or by setting a new material value when
+ // > COLOR_MATERIAL is not currently enabled, to override that particular value.
+ if (isColorMaterialEnabled())
+ {
+ mMaterial.ambient = color;
+ mMaterial.diffuse = color;
+ }
+}
+
+const ColorF &GLES1State::getCurrentColor() const
+{
+ return mCurrentColor;
+}
+
+void GLES1State::setCurrentNormal(const angle::Vector3 &normal)
+{
+ setDirty(DIRTY_GLES1_CURRENT_VECTOR);
+ mCurrentNormal = normal;
+}
+
+const angle::Vector3 &GLES1State::getCurrentNormal() const
+{
+ return mCurrentNormal;
+}
+
+bool GLES1State::shouldHandleDirtyProgram()
+{
+ bool ret = isDirty(DIRTY_GLES1_PROGRAM);
+ clearDirtyBits(DIRTY_GLES1_PROGRAM);
+ return ret;
+}
+
+void GLES1State::setCurrentTextureCoords(unsigned int unit, const TextureCoordF &coords)
+{
+ setDirty(DIRTY_GLES1_CURRENT_VECTOR);
+ mCurrentTextureCoords[unit] = coords;
+}
+
+const TextureCoordF &GLES1State::getCurrentTextureCoords(unsigned int unit) const
+{
+ return mCurrentTextureCoords[unit];
+}
+
+void GLES1State::setMatrixMode(MatrixType mode)
+{
+ setDirty(DIRTY_GLES1_MATRICES);
+ mMatrixMode = mode;
+}
+
+MatrixType GLES1State::getMatrixMode() const
+{
+ return mMatrixMode;
+}
+
+GLint GLES1State::getCurrentMatrixStackDepth(GLenum queryType) const
+{
+ switch (queryType)
+ {
+ case GL_MODELVIEW_STACK_DEPTH:
+ return clampCast<GLint>(mModelviewMatrices.size());
+ case GL_PROJECTION_STACK_DEPTH:
+ return clampCast<GLint>(mProjectionMatrices.size());
+ case GL_TEXTURE_STACK_DEPTH:
+ return clampCast<GLint>(mTextureMatrices[mGLState->getActiveSampler()].size());
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+void GLES1State::pushMatrix()
+{
+ setDirty(DIRTY_GLES1_MATRICES);
+ auto &stack = currentMatrixStack();
+ stack.push_back(stack.back());
+}
+
+void GLES1State::popMatrix()
+{
+ setDirty(DIRTY_GLES1_MATRICES);
+ auto &stack = currentMatrixStack();
+ stack.pop_back();
+}
+
+GLES1State::MatrixStack &GLES1State::currentMatrixStack()
+{
+ setDirty(DIRTY_GLES1_MATRICES);
+ switch (mMatrixMode)
+ {
+ case MatrixType::Modelview:
+ return mModelviewMatrices;
+ case MatrixType::Projection:
+ return mProjectionMatrices;
+ case MatrixType::Texture:
+ return mTextureMatrices[mGLState->getActiveSampler()];
+ default:
+ UNREACHABLE();
+ return mModelviewMatrices;
+ }
+}
+
+const angle::Mat4 &GLES1State::getModelviewMatrix() const
+{
+ return mModelviewMatrices.back();
+}
+
+const GLES1State::MatrixStack &GLES1State::getMatrixStack(MatrixType mode) const
+{
+ switch (mode)
+ {
+ case MatrixType::Modelview:
+ return mModelviewMatrices;
+ case MatrixType::Projection:
+ return mProjectionMatrices;
+ case MatrixType::Texture:
+ return mTextureMatrices[mGLState->getActiveSampler()];
+ default:
+ UNREACHABLE();
+ return mModelviewMatrices;
+ }
+}
+
+const GLES1State::MatrixStack &GLES1State::currentMatrixStack() const
+{
+ return getMatrixStack(mMatrixMode);
+}
+
+void GLES1State::loadMatrix(const angle::Mat4 &m)
+{
+ setDirty(DIRTY_GLES1_MATRICES);
+ currentMatrixStack().back() = m;
+}
+
+void GLES1State::multMatrix(const angle::Mat4 &m)
+{
+ setDirty(DIRTY_GLES1_MATRICES);
+ angle::Mat4 currentMatrix = currentMatrixStack().back();
+ currentMatrixStack().back() = currentMatrix.product(m);
+}
+
+void GLES1State::setLogicOpEnabled(bool enabled)
+{
+ setDirty(DIRTY_GLES1_LOGIC_OP);
+ mLogicOpEnabled = enabled;
+}
+
+void GLES1State::setLogicOp(LogicalOperation opcodePacked)
+{
+ setDirty(DIRTY_GLES1_LOGIC_OP);
+ mLogicOp = opcodePacked;
+}
+
+void GLES1State::setClientStateEnabled(ClientVertexArrayType clientState, bool enable)
+{
+ setDirty(DIRTY_GLES1_CLIENT_STATE_ENABLE);
+ switch (clientState)
+ {
+ case ClientVertexArrayType::Vertex:
+ mVertexArrayEnabled = enable;
+ break;
+ case ClientVertexArrayType::Normal:
+ mNormalArrayEnabled = enable;
+ break;
+ case ClientVertexArrayType::Color:
+ mColorArrayEnabled = enable;
+ break;
+ case ClientVertexArrayType::PointSize:
+ mPointSizeArrayEnabled = enable;
+ break;
+ case ClientVertexArrayType::TextureCoord:
+ mTexCoordArrayEnabled[mClientActiveTexture] = enable;
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+void GLES1State::setTexCoordArrayEnabled(unsigned int unit, bool enable)
+{
+ setDirty(DIRTY_GLES1_CLIENT_STATE_ENABLE);
+ mTexCoordArrayEnabled[unit] = enable;
+}
+
+bool GLES1State::isClientStateEnabled(ClientVertexArrayType clientState) const
+{
+ switch (clientState)
+ {
+ case ClientVertexArrayType::Vertex:
+ return mVertexArrayEnabled;
+ case ClientVertexArrayType::Normal:
+ return mNormalArrayEnabled;
+ case ClientVertexArrayType::Color:
+ return mColorArrayEnabled;
+ case ClientVertexArrayType::PointSize:
+ return mPointSizeArrayEnabled;
+ case ClientVertexArrayType::TextureCoord:
+ return mTexCoordArrayEnabled[mClientActiveTexture];
+ default:
+ UNREACHABLE();
+ return false;
+ }
+}
+
+bool GLES1State::isTexCoordArrayEnabled(unsigned int unit) const
+{
+ ASSERT(unit < mTexCoordArrayEnabled.size());
+ return mTexCoordArrayEnabled[unit];
+}
+
+bool GLES1State::isTextureTargetEnabled(unsigned int unit, const TextureType type) const
+{
+ if (mTexUnitEnables.empty())
+ {
+ return false;
+ }
+ return mTexUnitEnables[unit].test(type);
+}
+
+LightModelParameters &GLES1State::lightModelParameters()
+{
+ setDirty(DIRTY_GLES1_LIGHTS);
+ return mLightModel;
+}
+
+const LightModelParameters &GLES1State::lightModelParameters() const
+{
+ return mLightModel;
+}
+
+LightParameters &GLES1State::lightParameters(unsigned int light)
+{
+ setDirty(DIRTY_GLES1_LIGHTS);
+ return mLights[light];
+}
+
+const LightParameters &GLES1State::lightParameters(unsigned int light) const
+{
+ return mLights[light];
+}
+
+MaterialParameters &GLES1State::materialParameters()
+{
+ setDirty(DIRTY_GLES1_MATERIAL);
+ return mMaterial;
+}
+
+const MaterialParameters &GLES1State::materialParameters() const
+{
+ return mMaterial;
+}
+
+bool GLES1State::isColorMaterialEnabled() const
+{
+ return mColorMaterialEnabled;
+}
+
+void GLES1State::setShadeModel(ShadingModel model)
+{
+ setDirty(DIRTY_GLES1_SHADE_MODEL);
+ mShadeModel = model;
+}
+
+void GLES1State::setClipPlane(unsigned int plane, const GLfloat *equation)
+{
+ setDirty(DIRTY_GLES1_CLIP_PLANES);
+ assert(plane < mClipPlanes.size());
+ mClipPlanes[plane].equation[0] = equation[0];
+ mClipPlanes[plane].equation[1] = equation[1];
+ mClipPlanes[plane].equation[2] = equation[2];
+ mClipPlanes[plane].equation[3] = equation[3];
+}
+
+void GLES1State::getClipPlane(unsigned int plane, GLfloat *equation) const
+{
+ assert(plane < mClipPlanes.size());
+ equation[0] = mClipPlanes[plane].equation[0];
+ equation[1] = mClipPlanes[plane].equation[1];
+ equation[2] = mClipPlanes[plane].equation[2];
+ equation[3] = mClipPlanes[plane].equation[3];
+}
+
+FogParameters &GLES1State::fogParameters()
+{
+ setDirty(DIRTY_GLES1_FOG);
+ return mFog;
+}
+
+const FogParameters &GLES1State::fogParameters() const
+{
+ return mFog;
+}
+
+TextureEnvironmentParameters &GLES1State::textureEnvironment(unsigned int unit)
+{
+ setDirty(DIRTY_GLES1_TEXTURE_ENVIRONMENT);
+ assert(unit < mTextureEnvironments.size());
+ return mTextureEnvironments[unit];
+}
+
+const TextureEnvironmentParameters &GLES1State::textureEnvironment(unsigned int unit) const
+{
+ assert(unit < mTextureEnvironments.size());
+ return mTextureEnvironments[unit];
+}
+
+bool operator==(const TextureEnvironmentParameters &a, const TextureEnvironmentParameters &b)
+{
+ return a.tie() == b.tie();
+}
+
+bool operator!=(const TextureEnvironmentParameters &a, const TextureEnvironmentParameters &b)
+{
+ return !(a == b);
+}
+
+PointParameters &GLES1State::pointParameters()
+{
+ setDirty(DIRTY_GLES1_POINT_PARAMETERS);
+ return mPointParameters;
+}
+
+const PointParameters &GLES1State::pointParameters() const
+{
+ return mPointParameters;
+}
+
+AttributesMask GLES1State::getVertexArraysAttributeMask() const
+{
+ AttributesMask attribsMask;
+
+ ClientVertexArrayType nonTexcoordArrays[] = {
+ ClientVertexArrayType::Vertex,
+ ClientVertexArrayType::Normal,
+ ClientVertexArrayType::Color,
+ ClientVertexArrayType::PointSize,
+ };
+
+ for (const ClientVertexArrayType attrib : nonTexcoordArrays)
+ {
+ attribsMask.set(GLES1Renderer::VertexArrayIndex(attrib, *this),
+ isClientStateEnabled(attrib));
+ }
+
+ for (unsigned int i = 0; i < kTexUnitCount; i++)
+ {
+ attribsMask.set(GLES1Renderer::TexCoordArrayIndex(i), isTexCoordArrayEnabled(i));
+ }
+
+ return attribsMask;
+}
+
+AttributesMask GLES1State::getActiveAttributesMask() const
+{
+ // The program always has 8 attributes enabled.
+ return AttributesMask(0xFF);
+}
+
+void GLES1State::setHint(GLenum target, GLenum mode)
+{
+ setDirty(DIRTY_GLES1_HINT_SETTING);
+ HintSetting setting = FromGLenum<HintSetting>(mode);
+ switch (target)
+ {
+ case GL_PERSPECTIVE_CORRECTION_HINT:
+ mPerspectiveCorrectionHint = setting;
+ break;
+ case GL_POINT_SMOOTH_HINT:
+ mPointSmoothHint = setting;
+ break;
+ case GL_LINE_SMOOTH_HINT:
+ mLineSmoothHint = setting;
+ break;
+ case GL_FOG_HINT:
+ mFogHint = setting;
+ break;
+ default:
+ UNREACHABLE();
+ }
+}
+
+GLenum GLES1State::getHint(GLenum target) const
+{
+ switch (target)
+ {
+ case GL_PERSPECTIVE_CORRECTION_HINT:
+ return ToGLenum(mPerspectiveCorrectionHint);
+ case GL_POINT_SMOOTH_HINT:
+ return ToGLenum(mPointSmoothHint);
+ case GL_LINE_SMOOTH_HINT:
+ return ToGLenum(mLineSmoothHint);
+ case GL_FOG_HINT:
+ return ToGLenum(mFogHint);
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/GLES1State.h b/gfx/angle/checkout/src/libANGLE/GLES1State.h
new file mode 100644
index 0000000000..e9c108b58b
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/GLES1State.h
@@ -0,0 +1,351 @@
+//
+// Copyright 2018 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.
+//
+
+// GLES1State.h: Defines the GLES1State class holding the state of
+// a GLES1 context.
+
+#ifndef LIBANGLE_GLES1STATE_H_
+#define LIBANGLE_GLES1STATE_H_
+
+#include <unordered_set>
+
+#include "common/FixedVector.h"
+#include "common/angleutils.h"
+#include "common/bitset_utils.h"
+#include "common/matrix_utils.h"
+#include "common/vector_utils.h"
+#include "libANGLE/Caps.h"
+#include "libANGLE/angletypes.h"
+
+namespace gl
+{
+
+// State types specific to GLES1 contexts, from the OpenGL ES 1.1 spec "State Tables" section
+struct TextureCoordF
+{
+ TextureCoordF();
+ TextureCoordF(float _s, float _t, float _r, float _q);
+ bool operator==(const TextureCoordF &other) const;
+
+ GLfloat s = 0.0f;
+ GLfloat t = 0.0f;
+ GLfloat r = 0.0f;
+ GLfloat q = 0.0f;
+};
+
+struct MaterialParameters
+{
+ MaterialParameters();
+
+ ColorF ambient;
+ ColorF diffuse;
+ ColorF specular;
+ ColorF emissive;
+ GLfloat specularExponent;
+};
+
+struct LightModelParameters
+{
+ LightModelParameters();
+
+ ColorF color;
+ bool twoSided;
+};
+
+struct LightParameters
+{
+ LightParameters();
+ LightParameters(const LightParameters &other);
+
+ bool enabled = false;
+ ColorF ambient = {0.0f, 0.0f, 0.0f, 1.0f};
+ ColorF diffuse = {0.0f, 0.0f, 0.0f, 1.0f};
+ ColorF specular = {0.0f, 0.0f, 0.0f, 1.0f};
+ angle::Vector4 position = {0.0f, 0.0f, 1.0f, 0.0f};
+ angle::Vector3 direction = {0.0f, 0.0f, -1.0f};
+ GLfloat spotlightExponent = 0.0f;
+ GLfloat spotlightCutoffAngle = 180.0f;
+ GLfloat attenuationConst = 1.0f;
+ GLfloat attenuationLinear = 0.0f;
+ GLfloat attenuationQuadratic = 0.0f;
+};
+
+struct FogParameters
+{
+ FogParameters();
+
+ FogMode mode;
+ GLfloat density;
+ GLfloat start;
+ GLfloat end;
+ ColorF color;
+};
+
+struct TextureEnvironmentParameters
+{
+ TextureEnvironmentParameters();
+ TextureEnvironmentParameters(const TextureEnvironmentParameters &other);
+
+ TextureEnvMode mode = TextureEnvMode::Modulate;
+ TextureCombine combineRgb = TextureCombine::Modulate;
+ TextureCombine combineAlpha = TextureCombine::Modulate;
+
+ TextureSrc src0Rgb = TextureSrc::Texture;
+ TextureSrc src0Alpha = TextureSrc::Texture;
+
+ TextureSrc src1Rgb = TextureSrc::Previous;
+ TextureSrc src1Alpha = TextureSrc::Previous;
+
+ TextureSrc src2Rgb = TextureSrc::Constant;
+ TextureSrc src2Alpha = TextureSrc::Constant;
+
+ TextureOp op0Rgb = TextureOp::SrcColor;
+ TextureOp op0Alpha = TextureOp::SrcAlpha;
+
+ TextureOp op1Rgb = TextureOp::SrcColor;
+ TextureOp op1Alpha = TextureOp::SrcAlpha;
+
+ TextureOp op2Rgb = TextureOp::SrcAlpha;
+ TextureOp op2Alpha = TextureOp::SrcAlpha;
+
+ ColorF color = {0.0f, 0.0f, 0.0f, 0.0f};
+ GLfloat rgbScale = 1.0f;
+ GLfloat alphaScale = 1.0f;
+
+ bool pointSpriteCoordReplace = false;
+
+ auto tie() const
+ {
+ return std::tie(mode, combineRgb, combineAlpha, src0Rgb, src0Alpha, src1Rgb, src1Alpha,
+ src2Rgb, src2Alpha, op0Rgb, op0Alpha, op1Rgb, op1Alpha, op2Rgb, op2Alpha,
+ color, rgbScale, alphaScale, pointSpriteCoordReplace);
+ }
+};
+
+bool operator==(const TextureEnvironmentParameters &a, const TextureEnvironmentParameters &b);
+bool operator!=(const TextureEnvironmentParameters &a, const TextureEnvironmentParameters &b);
+
+struct PointParameters
+{
+ PointParameters();
+ PointParameters(const PointParameters &other);
+
+ GLfloat pointSizeMin = 0.0f;
+ GLfloat pointSizeMax = 1.0f;
+ GLfloat pointFadeThresholdSize = 1.0f;
+ angle::Vector3 pointDistanceAttenuation = {1.0f, 0.0f, 0.0f};
+ GLfloat pointSize = 1.0f;
+};
+
+struct ClipPlaneParameters
+{
+ ClipPlaneParameters();
+ ClipPlaneParameters(bool enabled, const angle::Vector4 &equation);
+ ClipPlaneParameters(const ClipPlaneParameters &other);
+ ClipPlaneParameters &operator=(const ClipPlaneParameters &other);
+
+ bool enabled;
+ angle::Vector4 equation;
+};
+
+class Context;
+class GLES1Renderer;
+class State;
+
+class GLES1State final : angle::NonCopyable
+{
+ public:
+ GLES1State();
+ ~GLES1State();
+
+ void initialize(const Context *context, const State *state);
+
+ void setAlphaFunc(AlphaTestFunc func, GLfloat ref);
+ void setClientTextureUnit(unsigned int unit);
+ unsigned int getClientTextureUnit() const;
+
+ void setCurrentColor(const ColorF &color);
+ const ColorF &getCurrentColor() const;
+
+ void setCurrentNormal(const angle::Vector3 &normal);
+ const angle::Vector3 &getCurrentNormal() const;
+
+ void setCurrentTextureCoords(unsigned int unit, const TextureCoordF &coords);
+ const TextureCoordF &getCurrentTextureCoords(unsigned int unit) const;
+
+ void setMatrixMode(MatrixType mode);
+ MatrixType getMatrixMode() const;
+
+ GLint getCurrentMatrixStackDepth(GLenum param) const;
+
+ void pushMatrix();
+ void popMatrix();
+
+ using MatrixStack = angle::FixedVector<angle::Mat4, Caps::GlobalMatrixStackDepth>;
+ MatrixStack &currentMatrixStack();
+ const MatrixStack &currentMatrixStack() const;
+ const MatrixStack &getMatrixStack(MatrixType mode) const;
+
+ const angle::Mat4 &getModelviewMatrix() const;
+
+ void loadMatrix(const angle::Mat4 &m);
+ void multMatrix(const angle::Mat4 &m);
+
+ void setLogicOpEnabled(bool enabled);
+ void setLogicOp(LogicalOperation opcodePacked);
+
+ void setClientStateEnabled(ClientVertexArrayType clientState, bool enable);
+ void setTexCoordArrayEnabled(unsigned int unit, bool enable);
+ bool isClientStateEnabled(ClientVertexArrayType clientState) const;
+ bool isTexCoordArrayEnabled(unsigned int unit) const;
+ bool isTextureTargetEnabled(unsigned int unit, const TextureType type) const;
+
+ LightModelParameters &lightModelParameters();
+ const LightModelParameters &lightModelParameters() const;
+
+ LightParameters &lightParameters(unsigned int light);
+ const LightParameters &lightParameters(unsigned int light) const;
+
+ MaterialParameters &materialParameters();
+ const MaterialParameters &materialParameters() const;
+ bool isColorMaterialEnabled() const;
+
+ void setShadeModel(ShadingModel model);
+
+ void setClipPlane(unsigned int plane, const GLfloat *equation);
+ void getClipPlane(unsigned int plane, GLfloat *equation) const;
+
+ FogParameters &fogParameters();
+ const FogParameters &fogParameters() const;
+
+ TextureEnvironmentParameters &textureEnvironment(unsigned int unit);
+ const TextureEnvironmentParameters &textureEnvironment(unsigned int unit) const;
+
+ PointParameters &pointParameters();
+ const PointParameters &pointParameters() const;
+
+ AttributesMask getVertexArraysAttributeMask() const;
+ AttributesMask getActiveAttributesMask() const;
+
+ bool shouldHandleDirtyProgram();
+
+ void setHint(GLenum target, GLenum mode);
+ GLenum getHint(GLenum target) const;
+
+ enum DirtyGles1Type
+ {
+ DIRTY_GLES1_TEXTURE_UNIT_ENABLE = 0,
+ DIRTY_GLES1_CLIENT_STATE_ENABLE,
+ DIRTY_GLES1_FEATURE_ENABLE,
+ DIRTY_GLES1_CURRENT_VECTOR,
+ DIRTY_GLES1_CLIENT_ACTIVE_TEXTURE,
+ DIRTY_GLES1_MATRICES,
+ DIRTY_GLES1_TEXTURE_ENVIRONMENT,
+ DIRTY_GLES1_MATERIAL,
+ DIRTY_GLES1_LIGHTS,
+ DIRTY_GLES1_FOG,
+ DIRTY_GLES1_SHADE_MODEL,
+ DIRTY_GLES1_POINT_PARAMETERS,
+ DIRTY_GLES1_ALPHA_TEST,
+ DIRTY_GLES1_LOGIC_OP,
+ DIRTY_GLES1_CLIP_PLANES,
+ DIRTY_GLES1_HINT_SETTING,
+ DIRTY_GLES1_PROGRAM,
+ DIRTY_GLES1_MAX,
+ };
+
+ void setAllDirty() { mDirtyBits.set(); }
+
+ private:
+ friend class State;
+ friend class GLES1Renderer;
+
+ // Back pointer for reading from State.
+ const State *mGLState;
+
+ using DirtyBits = angle::BitSet<DIRTY_GLES1_MAX>;
+ DirtyBits mDirtyBits;
+
+ void setDirty(DirtyGles1Type type) { mDirtyBits.set(type); }
+ void clearDirty() { mDirtyBits.reset(); }
+ void clearDirtyBits(const DirtyGles1Type &bitset) { mDirtyBits &= ~bitset; }
+ bool isDirty(DirtyGles1Type type) const { return mDirtyBits.test(type); }
+
+ // All initial state values come from the
+ // OpenGL ES 1.1 spec.
+ std::vector<angle::PackedEnumBitSet<TextureType>> mTexUnitEnables;
+
+ // Table 6.4, 6.5 (IsEnabled)
+ bool mVertexArrayEnabled;
+ bool mNormalArrayEnabled;
+ bool mColorArrayEnabled;
+ bool mPointSizeArrayEnabled;
+ std::vector<bool> mTexCoordArrayEnabled;
+
+ // Table 6.7-6.16 (IsEnabled)
+ bool mLineSmoothEnabled;
+ bool mPointSmoothEnabled;
+ bool mPointSpriteEnabled;
+ bool mAlphaTestEnabled;
+ bool mLogicOpEnabled;
+ bool mLightingEnabled;
+ bool mFogEnabled;
+ bool mRescaleNormalEnabled;
+ bool mNormalizeEnabled;
+ bool mColorMaterialEnabled;
+ bool mReflectionMapEnabled;
+
+ // Table 6.3
+ ColorF mCurrentColor;
+ angle::Vector3 mCurrentNormal;
+ // Invariant: mCurrentTextureCoords size is == GL_MAX_TEXTURE_UNITS.
+ std::vector<TextureCoordF> mCurrentTextureCoords;
+
+ // Table 6.4
+ unsigned int mClientActiveTexture;
+
+ // Table 6.7
+ MatrixType mMatrixMode;
+ MatrixStack mProjectionMatrices;
+ MatrixStack mModelviewMatrices;
+ std::vector<MatrixStack> mTextureMatrices;
+
+ // Table 6.15
+ using TextureEnvironments = std::vector<TextureEnvironmentParameters>;
+ TextureEnvironments mTextureEnvironments;
+
+ // Table 6.9, 2.8
+ MaterialParameters mMaterial;
+ LightModelParameters mLightModel;
+
+ // Table 6.10
+ std::vector<LightParameters> mLights;
+
+ // Table 6.8
+ FogParameters mFog;
+ ShadingModel mShadeModel;
+
+ // Table 6.11
+ PointParameters mPointParameters;
+
+ // Table 6.16
+ AlphaTestFunc mAlphaTestFunc;
+ GLfloat mAlphaTestRef;
+ LogicalOperation mLogicOp;
+
+ // Table 6.7
+ std::vector<ClipPlaneParameters> mClipPlanes;
+
+ // Table 6.19
+ HintSetting mLineSmoothHint;
+ HintSetting mPointSmoothHint;
+ HintSetting mPerspectiveCorrectionHint;
+ HintSetting mFogHint;
+};
+
+} // namespace gl
+
+#endif // LIBANGLE_GLES1STATE_H_
diff --git a/gfx/angle/checkout/src/libANGLE/HandleAllocator.cpp b/gfx/angle/checkout/src/libANGLE/HandleAllocator.cpp
new file mode 100644
index 0000000000..ff49233e1d
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/HandleAllocator.cpp
@@ -0,0 +1,184 @@
+//
+// Copyright 2002 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.
+//
+
+// HandleAllocator.cpp: Implements the gl::HandleAllocator class, which is used
+// to allocate GL handles.
+
+#include "libANGLE/HandleAllocator.h"
+
+#include <algorithm>
+#include <functional>
+#include <limits>
+
+#include "common/debug.h"
+
+namespace gl
+{
+
+struct HandleAllocator::HandleRangeComparator
+{
+ bool operator()(const HandleRange &range, GLuint handle) const { return (range.end < handle); }
+};
+
+HandleAllocator::HandleAllocator() : mBaseValue(1), mNextValue(1), mLoggingEnabled(false)
+{
+ mUnallocatedList.push_back(HandleRange(1, std::numeric_limits<GLuint>::max()));
+}
+
+HandleAllocator::HandleAllocator(GLuint maximumHandleValue)
+ : mBaseValue(1), mNextValue(1), mLoggingEnabled(false)
+{
+ mUnallocatedList.push_back(HandleRange(1, maximumHandleValue));
+}
+
+HandleAllocator::~HandleAllocator() {}
+
+void HandleAllocator::setBaseHandle(GLuint value)
+{
+ ASSERT(mBaseValue == mNextValue);
+ mBaseValue = value;
+ mNextValue = value;
+}
+
+GLuint HandleAllocator::allocate()
+{
+ ASSERT(!mUnallocatedList.empty() || !mReleasedList.empty());
+
+ // Allocate from released list, logarithmic time for pop_heap.
+ if (!mReleasedList.empty())
+ {
+ std::pop_heap(mReleasedList.begin(), mReleasedList.end(), std::greater<GLuint>());
+ GLuint reusedHandle = mReleasedList.back();
+ mReleasedList.pop_back();
+
+ if (mLoggingEnabled)
+ {
+ WARN() << "HandleAllocator::allocate reusing " << reusedHandle << std::endl;
+ }
+
+ return reusedHandle;
+ }
+
+ // Allocate from unallocated list, constant time.
+ auto listIt = mUnallocatedList.begin();
+
+ GLuint freeListHandle = listIt->begin;
+ ASSERT(freeListHandle > 0);
+
+ if (listIt->begin == listIt->end)
+ {
+ mUnallocatedList.erase(listIt);
+ }
+ else
+ {
+ listIt->begin++;
+ }
+
+ if (mLoggingEnabled)
+ {
+ WARN() << "HandleAllocator::allocate allocating " << freeListHandle << std::endl;
+ }
+
+ return freeListHandle;
+}
+
+void HandleAllocator::release(GLuint handle)
+{
+ if (mLoggingEnabled)
+ {
+ WARN() << "HandleAllocator::release releasing " << handle << std::endl;
+ }
+
+ // Try consolidating the ranges first.
+ for (HandleRange &handleRange : mUnallocatedList)
+ {
+ if (handleRange.begin - 1 == handle)
+ {
+ handleRange.begin--;
+ return;
+ }
+
+ if (handleRange.end == handle - 1)
+ {
+ handleRange.end++;
+ return;
+ }
+ }
+
+ // Add to released list, logarithmic time for push_heap.
+ mReleasedList.push_back(handle);
+ std::push_heap(mReleasedList.begin(), mReleasedList.end(), std::greater<GLuint>());
+}
+
+void HandleAllocator::reserve(GLuint handle)
+{
+ if (mLoggingEnabled)
+ {
+ WARN() << "HandleAllocator::reserve reserving " << handle << std::endl;
+ }
+
+ // Clear from released list -- might be a slow operation.
+ if (!mReleasedList.empty())
+ {
+ auto releasedIt = std::find(mReleasedList.begin(), mReleasedList.end(), handle);
+ if (releasedIt != mReleasedList.end())
+ {
+ mReleasedList.erase(releasedIt);
+ std::make_heap(mReleasedList.begin(), mReleasedList.end(), std::greater<GLuint>());
+ return;
+ }
+ }
+
+ // Not in released list, reserve in the unallocated list.
+ auto boundIt = std::lower_bound(mUnallocatedList.begin(), mUnallocatedList.end(), handle,
+ HandleRangeComparator());
+
+ ASSERT(boundIt != mUnallocatedList.end());
+
+ GLuint begin = boundIt->begin;
+ GLuint end = boundIt->end;
+
+ if (handle == begin || handle == end)
+ {
+ if (begin == end)
+ {
+ mUnallocatedList.erase(boundIt);
+ }
+ else if (handle == begin)
+ {
+ boundIt->begin++;
+ }
+ else
+ {
+ ASSERT(handle == end);
+ boundIt->end--;
+ }
+ return;
+ }
+
+ ASSERT(begin < handle && handle < end);
+
+ // need to split the range
+ auto placementIt = mUnallocatedList.erase(boundIt);
+ placementIt = mUnallocatedList.insert(placementIt, HandleRange(handle + 1, end));
+ mUnallocatedList.insert(placementIt, HandleRange(begin, handle - 1));
+}
+
+void HandleAllocator::reset()
+{
+ mUnallocatedList.clear();
+ mUnallocatedList.push_back(HandleRange(1, std::numeric_limits<GLuint>::max()));
+ mReleasedList.clear();
+ mBaseValue = 1;
+ mNextValue = 1;
+}
+
+void HandleAllocator::enableLogging(bool enabled)
+{
+ mLoggingEnabled = enabled;
+}
+
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/HandleAllocator.h b/gfx/angle/checkout/src/libANGLE/HandleAllocator.h
new file mode 100644
index 0000000000..985d1adaba
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/HandleAllocator.h
@@ -0,0 +1,65 @@
+//
+// Copyright 2002 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.
+//
+
+// HandleAllocator.h: Defines the gl::HandleAllocator class, which is used to
+// allocate GL handles.
+
+#ifndef LIBANGLE_HANDLEALLOCATOR_H_
+#define LIBANGLE_HANDLEALLOCATOR_H_
+
+#include "common/angleutils.h"
+
+#include "angle_gl.h"
+
+namespace gl
+{
+
+class HandleAllocator final : angle::NonCopyable
+{
+ public:
+ // Maximum handle = MAX_UINT-1
+ HandleAllocator();
+ // Specify maximum handle value. Used for testing.
+ HandleAllocator(GLuint maximumHandleValue);
+
+ ~HandleAllocator();
+
+ void setBaseHandle(GLuint value);
+
+ GLuint allocate();
+ void release(GLuint handle);
+ void reserve(GLuint handle);
+ void reset();
+
+ void enableLogging(bool enabled);
+
+ private:
+ GLuint mBaseValue;
+ GLuint mNextValue;
+
+ // Represents an inclusive range [begin, end]
+ struct HandleRange
+ {
+ HandleRange(GLuint beginIn, GLuint endIn) : begin(beginIn), end(endIn) {}
+
+ GLuint begin;
+ GLuint end;
+ };
+
+ struct HandleRangeComparator;
+
+ // The freelist consists of never-allocated handles, stored
+ // as ranges, and handles that were previously allocated and
+ // released, stored in a heap.
+ std::vector<HandleRange> mUnallocatedList;
+ std::vector<GLuint> mReleasedList;
+
+ bool mLoggingEnabled;
+};
+
+} // namespace gl
+
+#endif // LIBANGLE_HANDLEALLOCATOR_H_
diff --git a/gfx/angle/checkout/src/libANGLE/Image.cpp b/gfx/angle/checkout/src/libANGLE/Image.cpp
new file mode 100644
index 0000000000..6292b5ee46
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Image.cpp
@@ -0,0 +1,581 @@
+//
+// 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.
+//
+
+// Image.cpp: Implements the egl::Image class representing the EGLimage object.
+
+#include "libANGLE/Image.h"
+
+#include "common/debug.h"
+#include "common/utilities.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Renderbuffer.h"
+#include "libANGLE/Texture.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/EGLImplFactory.h"
+#include "libANGLE/renderer/ImageImpl.h"
+
+namespace egl
+{
+
+namespace
+{
+gl::ImageIndex GetImageIndex(EGLenum eglTarget, const egl::AttributeMap &attribs)
+{
+ if (!IsTextureTarget(eglTarget))
+ {
+ return gl::ImageIndex();
+ }
+
+ gl::TextureTarget target = egl_gl::EGLImageTargetToTextureTarget(eglTarget);
+ GLint mip = static_cast<GLint>(attribs.get(EGL_GL_TEXTURE_LEVEL_KHR, 0));
+ GLint layer = static_cast<GLint>(attribs.get(EGL_GL_TEXTURE_ZOFFSET_KHR, 0));
+
+ if (target == gl::TextureTarget::_3D)
+ {
+ return gl::ImageIndex::Make3D(mip, layer);
+ }
+ else
+ {
+ ASSERT(layer == 0);
+ return gl::ImageIndex::MakeFromTarget(target, mip, 1);
+ }
+}
+
+const Display *DisplayFromContext(const gl::Context *context)
+{
+ return (context ? context->getDisplay() : nullptr);
+}
+
+angle::SubjectIndex kExternalImageImplSubjectIndex = 0;
+} // anonymous namespace
+
+ImageSibling::ImageSibling() : FramebufferAttachmentObject(), mSourcesOf(), mTargetOf() {}
+
+ImageSibling::~ImageSibling()
+{
+ // EGL images should hold a ref to their targets and siblings, a Texture should not be deletable
+ // while it is attached to an EGL image.
+ // Child class should orphan images before destruction.
+ ASSERT(mSourcesOf.empty());
+ ASSERT(mTargetOf.get() == nullptr);
+}
+
+void ImageSibling::setTargetImage(const gl::Context *context, egl::Image *imageTarget)
+{
+ ASSERT(imageTarget != nullptr);
+ mTargetOf.set(DisplayFromContext(context), imageTarget);
+ imageTarget->addTargetSibling(this);
+}
+
+angle::Result ImageSibling::orphanImages(const gl::Context *context,
+ RefCountObjectReleaser<Image> *outReleaseImage)
+{
+ ASSERT(outReleaseImage != nullptr);
+
+ if (mTargetOf.get() != nullptr)
+ {
+ // Can't be a target and have sources.
+ ASSERT(mSourcesOf.empty());
+
+ ANGLE_TRY(mTargetOf->orphanSibling(context, this));
+ *outReleaseImage = mTargetOf.set(DisplayFromContext(context), nullptr);
+ }
+ else
+ {
+ for (Image *sourceImage : mSourcesOf)
+ {
+ ANGLE_TRY(sourceImage->orphanSibling(context, this));
+ }
+ mSourcesOf.clear();
+ }
+
+ return angle::Result::Continue;
+}
+
+void ImageSibling::addImageSource(egl::Image *imageSource)
+{
+ ASSERT(imageSource != nullptr);
+ mSourcesOf.insert(imageSource);
+}
+
+void ImageSibling::removeImageSource(egl::Image *imageSource)
+{
+ ASSERT(mSourcesOf.find(imageSource) != mSourcesOf.end());
+ mSourcesOf.erase(imageSource);
+}
+
+bool ImageSibling::isEGLImageTarget() const
+{
+ return (mTargetOf.get() != nullptr);
+}
+
+gl::InitState ImageSibling::sourceEGLImageInitState() const
+{
+ ASSERT(isEGLImageTarget());
+ return mTargetOf->sourceInitState();
+}
+
+void ImageSibling::setSourceEGLImageInitState(gl::InitState initState) const
+{
+ ASSERT(isEGLImageTarget());
+ mTargetOf->setInitState(initState);
+}
+
+bool ImageSibling::isRenderable(const gl::Context *context,
+ GLenum binding,
+ const gl::ImageIndex &imageIndex) const
+{
+ ASSERT(isEGLImageTarget());
+ return mTargetOf->isRenderable(context);
+}
+
+bool ImageSibling::isYUV() const
+{
+ return mTargetOf.get() && mTargetOf->isYUV();
+}
+
+bool ImageSibling::isCreatedWithAHB() const
+{
+ return mTargetOf.get() && mTargetOf->isCreatedWithAHB();
+}
+
+bool ImageSibling::hasProtectedContent() const
+{
+ return mTargetOf.get() && mTargetOf->hasProtectedContent();
+}
+
+void ImageSibling::notifySiblings(angle::SubjectMessage message)
+{
+ if (mTargetOf.get())
+ {
+ mTargetOf->notifySiblings(this, message);
+ }
+ for (Image *source : mSourcesOf)
+ {
+ source->notifySiblings(this, message);
+ }
+}
+
+ExternalImageSibling::ExternalImageSibling(rx::EGLImplFactory *factory,
+ const gl::Context *context,
+ EGLenum target,
+ EGLClientBuffer buffer,
+ const AttributeMap &attribs)
+ : mImplementation(factory->createExternalImageSibling(context, target, buffer, attribs)),
+ mImplObserverBinding(this, kExternalImageImplSubjectIndex)
+{
+ mImplObserverBinding.bind(mImplementation.get());
+}
+
+ExternalImageSibling::~ExternalImageSibling() = default;
+
+void ExternalImageSibling::onDestroy(const egl::Display *display)
+{
+ mImplementation->onDestroy(display);
+}
+
+Error ExternalImageSibling::initialize(const egl::Display *display)
+{
+ return mImplementation->initialize(display);
+}
+
+gl::Extents ExternalImageSibling::getAttachmentSize(const gl::ImageIndex &imageIndex) const
+{
+ return mImplementation->getSize();
+}
+
+gl::Format ExternalImageSibling::getAttachmentFormat(GLenum binding,
+ const gl::ImageIndex &imageIndex) const
+{
+ return mImplementation->getFormat();
+}
+
+GLsizei ExternalImageSibling::getAttachmentSamples(const gl::ImageIndex &imageIndex) const
+{
+ return static_cast<GLsizei>(mImplementation->getSamples());
+}
+
+GLuint ExternalImageSibling::getLevelCount() const
+{
+ return static_cast<GLuint>(mImplementation->getLevelCount());
+}
+
+bool ExternalImageSibling::isRenderable(const gl::Context *context,
+ GLenum binding,
+ const gl::ImageIndex &imageIndex) const
+{
+ return mImplementation->isRenderable(context);
+}
+
+bool ExternalImageSibling::isTextureable(const gl::Context *context) const
+{
+ return mImplementation->isTexturable(context);
+}
+
+bool ExternalImageSibling::isYUV() const
+{
+ return mImplementation->isYUV();
+}
+
+bool ExternalImageSibling::isCubeMap() const
+{
+ return mImplementation->isCubeMap();
+}
+
+bool ExternalImageSibling::hasProtectedContent() const
+{
+ return mImplementation->hasProtectedContent();
+}
+
+void ExternalImageSibling::onAttach(const gl::Context *context, rx::Serial framebufferSerial) {}
+
+void ExternalImageSibling::onDetach(const gl::Context *context, rx::Serial framebufferSerial) {}
+
+GLuint ExternalImageSibling::getId() const
+{
+ UNREACHABLE();
+ return 0;
+}
+
+gl::InitState ExternalImageSibling::initState(GLenum binding,
+ const gl::ImageIndex &imageIndex) const
+{
+ return gl::InitState::Initialized;
+}
+
+void ExternalImageSibling::setInitState(GLenum binding,
+ const gl::ImageIndex &imageIndex,
+ gl::InitState initState)
+{}
+
+rx::ExternalImageSiblingImpl *ExternalImageSibling::getImplementation() const
+{
+ return mImplementation.get();
+}
+
+void ExternalImageSibling::onSubjectStateChange(angle::SubjectIndex index,
+ angle::SubjectMessage message)
+{
+ onStateChange(message);
+}
+
+rx::FramebufferAttachmentObjectImpl *ExternalImageSibling::getAttachmentImpl() const
+{
+ return mImplementation.get();
+}
+
+ImageState::ImageState(EGLenum target, ImageSibling *buffer, const AttributeMap &attribs)
+ : label(nullptr),
+ target(target),
+ imageIndex(GetImageIndex(target, attribs)),
+ source(buffer),
+ format(GL_NONE),
+ yuv(false),
+ cubeMap(false),
+ size(),
+ samples(),
+ levelCount(1),
+ sourceType(target),
+ colorspace(
+ static_cast<EGLenum>(attribs.get(EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_DEFAULT_EXT))),
+ hasProtectedContent(static_cast<bool>(attribs.get(EGL_PROTECTED_CONTENT_EXT, EGL_FALSE)))
+{}
+
+ImageState::~ImageState() {}
+
+Image::Image(rx::EGLImplFactory *factory,
+ const gl::Context *context,
+ EGLenum target,
+ ImageSibling *buffer,
+ const AttributeMap &attribs)
+ : mState(target, buffer, attribs),
+ mImplementation(factory->createImage(mState, context, target, attribs)),
+ mOrphanedAndNeedsInit(false)
+{
+ ASSERT(mImplementation != nullptr);
+ ASSERT(buffer != nullptr);
+
+ mState.source->addImageSource(this);
+}
+
+void Image::onDestroy(const Display *display)
+{
+ // All targets should hold a ref to the egl image and it should not be deleted until there are
+ // no siblings left.
+ ASSERT([&] {
+ std::unique_lock lock(mState.targetsLock);
+ return mState.targets.empty();
+ }());
+
+ // Make sure the implementation gets a chance to clean up before we delete the source.
+ mImplementation->onDestroy(display);
+
+ // Tell the source that it is no longer used by this image
+ if (mState.source != nullptr)
+ {
+ mState.source->removeImageSource(this);
+
+ // If the source is an external object, delete it
+ if (IsExternalImageTarget(mState.sourceType))
+ {
+ ExternalImageSibling *externalSibling = rx::GetAs<ExternalImageSibling>(mState.source);
+ externalSibling->onDestroy(display);
+ delete externalSibling;
+ }
+
+ mState.source = nullptr;
+ }
+}
+
+Image::~Image()
+{
+ SafeDelete(mImplementation);
+}
+
+void Image::setLabel(EGLLabelKHR label)
+{
+ mState.label = label;
+}
+
+EGLLabelKHR Image::getLabel() const
+{
+ return mState.label;
+}
+
+void Image::addTargetSibling(ImageSibling *sibling)
+{
+ std::unique_lock lock(mState.targetsLock);
+ mState.targets.insert(sibling);
+}
+
+angle::Result Image::orphanSibling(const gl::Context *context, ImageSibling *sibling)
+{
+ ASSERT(sibling != nullptr);
+
+ // notify impl
+ ANGLE_TRY(mImplementation->orphan(context, sibling));
+
+ if (mState.source == sibling)
+ {
+ // The external source of an image cannot be redefined so it cannot be orphaned.
+ ASSERT(!IsExternalImageTarget(mState.sourceType));
+
+ // If the sibling is the source, it cannot be a target.
+ ASSERT([&] {
+ std::unique_lock lock(mState.targetsLock);
+ return mState.targets.find(sibling) == mState.targets.end();
+ }());
+ mState.source = nullptr;
+ mOrphanedAndNeedsInit =
+ (sibling->initState(GL_NONE, mState.imageIndex) == gl::InitState::MayNeedInit);
+ }
+ else
+ {
+ std::unique_lock lock(mState.targetsLock);
+ mState.targets.erase(sibling);
+ }
+
+ return angle::Result::Continue;
+}
+
+const gl::Format &Image::getFormat() const
+{
+ return mState.format;
+}
+
+bool Image::isRenderable(const gl::Context *context) const
+{
+ if (IsTextureTarget(mState.sourceType))
+ {
+ return mState.format.info->textureAttachmentSupport(context->getClientVersion(),
+ context->getExtensions());
+ }
+ else if (IsRenderbufferTarget(mState.sourceType))
+ {
+ return mState.format.info->renderbufferSupport(context->getClientVersion(),
+ context->getExtensions());
+ }
+ else if (IsExternalImageTarget(mState.sourceType))
+ {
+ ASSERT(mState.source != nullptr);
+ return mState.source->isRenderable(context, GL_NONE, gl::ImageIndex());
+ }
+
+ UNREACHABLE();
+ return false;
+}
+
+bool Image::isTexturable(const gl::Context *context) const
+{
+ if (IsTextureTarget(mState.sourceType))
+ {
+ return mState.format.info->textureSupport(context->getClientVersion(),
+ context->getExtensions());
+ }
+ else if (IsRenderbufferTarget(mState.sourceType))
+ {
+ return true;
+ }
+ else if (IsExternalImageTarget(mState.sourceType))
+ {
+ ASSERT(mState.source != nullptr);
+ return rx::GetAs<ExternalImageSibling>(mState.source)->isTextureable(context);
+ }
+
+ UNREACHABLE();
+ return false;
+}
+
+bool Image::isYUV() const
+{
+ return mState.yuv;
+}
+
+bool Image::isCreatedWithAHB() const
+{
+ return mState.target == EGL_NATIVE_BUFFER_ANDROID;
+}
+
+bool Image::isCubeMap() const
+{
+ return mState.cubeMap;
+}
+
+size_t Image::getWidth() const
+{
+ return mState.size.width;
+}
+
+size_t Image::getHeight() const
+{
+ return mState.size.height;
+}
+
+const gl::Extents &Image::getExtents() const
+{
+ return mState.size;
+}
+
+bool Image::isLayered() const
+{
+ return mState.imageIndex.isLayered();
+}
+
+size_t Image::getSamples() const
+{
+ return mState.samples;
+}
+
+GLuint Image::getLevelCount() const
+{
+ return mState.levelCount;
+}
+
+bool Image::hasProtectedContent() const
+{
+ return mState.hasProtectedContent;
+}
+
+rx::ImageImpl *Image::getImplementation() const
+{
+ return mImplementation;
+}
+
+Error Image::initialize(const Display *display)
+{
+ if (IsExternalImageTarget(mState.sourceType))
+ {
+ ExternalImageSibling *externalSibling = rx::GetAs<ExternalImageSibling>(mState.source);
+ ANGLE_TRY(externalSibling->initialize(display));
+
+ mState.hasProtectedContent = externalSibling->hasProtectedContent();
+ mState.levelCount = externalSibling->getLevelCount();
+ mState.cubeMap = externalSibling->isCubeMap();
+
+ // External siblings can be YUV
+ mState.yuv = externalSibling->isYUV();
+ }
+
+ mState.format = mState.source->getAttachmentFormat(GL_NONE, mState.imageIndex);
+
+ if (mState.colorspace != EGL_GL_COLORSPACE_DEFAULT_EXT)
+ {
+ GLenum nonLinearFormat = mState.format.info->sizedInternalFormat;
+ if (!gl::ColorspaceFormatOverride(mState.colorspace, &nonLinearFormat))
+ {
+ // the colorspace format is not supported
+ return egl::EglBadMatch();
+ }
+ mState.format = gl::Format(nonLinearFormat);
+ }
+
+ if (!IsExternalImageTarget(mState.sourceType))
+ {
+ // Account for the fact that GL_ANGLE_yuv_internal_format extension maybe enabled,
+ // in which case the internal format itself could be YUV.
+ mState.yuv = gl::IsYuvFormat(mState.format.info->sizedInternalFormat);
+ }
+
+ mState.size = mState.source->getAttachmentSize(mState.imageIndex);
+ mState.samples = mState.source->getAttachmentSamples(mState.imageIndex);
+
+ if (IsTextureTarget(mState.sourceType))
+ {
+ mState.size.depth = 1;
+ }
+
+ return mImplementation->initialize(display);
+}
+
+bool Image::orphaned() const
+{
+ return (mState.source == nullptr);
+}
+
+gl::InitState Image::sourceInitState() const
+{
+ if (orphaned())
+ {
+ return mOrphanedAndNeedsInit ? gl::InitState::MayNeedInit : gl::InitState::Initialized;
+ }
+
+ return mState.source->initState(GL_NONE, mState.imageIndex);
+}
+
+void Image::setInitState(gl::InitState initState)
+{
+ if (orphaned())
+ {
+ mOrphanedAndNeedsInit = false;
+ }
+
+ return mState.source->setInitState(GL_NONE, mState.imageIndex, initState);
+}
+
+Error Image::exportVkImage(void *vkImage, void *vkImageCreateInfo)
+{
+ return mImplementation->exportVkImage(vkImage, vkImageCreateInfo);
+}
+
+void Image::notifySiblings(const ImageSibling *notifier, angle::SubjectMessage message)
+{
+ if (mState.source && mState.source != notifier)
+ {
+ mState.source->onSubjectStateChange(rx::kTextureImageSiblingMessageIndex, message);
+ }
+
+ std::unique_lock lock(mState.targetsLock);
+ for (ImageSibling *target : mState.targets)
+ {
+ if (target != notifier)
+ {
+ target->onSubjectStateChange(rx::kTextureImageSiblingMessageIndex, message);
+ }
+ }
+}
+
+} // namespace egl
diff --git a/gfx/angle/checkout/src/libANGLE/Image.h b/gfx/angle/checkout/src/libANGLE/Image.h
new file mode 100644
index 0000000000..7c1747f804
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Image.h
@@ -0,0 +1,216 @@
+//
+// 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.
+//
+
+// Image.h: Defines the egl::Image class representing the EGLimage object.
+
+#ifndef LIBANGLE_IMAGE_H_
+#define LIBANGLE_IMAGE_H_
+
+#include "common/FastVector.h"
+#include "common/angleutils.h"
+#include "libANGLE/AttributeMap.h"
+#include "libANGLE/Debug.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/RefCountObject.h"
+#include "libANGLE/formatutils.h"
+
+namespace rx
+{
+class EGLImplFactory;
+class ImageImpl;
+class ExternalImageSiblingImpl;
+
+// Used for distinguishing dirty bit messages from gl::Texture/rx::TexureImpl/gl::Image.
+constexpr size_t kTextureImageImplObserverMessageIndex = 0;
+constexpr size_t kTextureImageSiblingMessageIndex = 1;
+} // namespace rx
+
+namespace egl
+{
+class Image;
+class Display;
+
+// Only currently Renderbuffers and Textures can be bound with images. This makes the relationship
+// explicit, and also ensures that an image sibling can determine if it's been initialized or not,
+// which is important for the robust resource init extension with Textures and EGLImages.
+class ImageSibling : public gl::FramebufferAttachmentObject
+{
+ public:
+ ImageSibling();
+ ~ImageSibling() override;
+
+ bool isEGLImageTarget() const;
+ gl::InitState sourceEGLImageInitState() const;
+ void setSourceEGLImageInitState(gl::InitState initState) const;
+
+ bool isRenderable(const gl::Context *context,
+ GLenum binding,
+ const gl::ImageIndex &imageIndex) const override;
+ bool isYUV() const override;
+ bool isCreatedWithAHB() const override;
+ bool hasProtectedContent() const override;
+
+ protected:
+ // Set the image target of this sibling
+ void setTargetImage(const gl::Context *context, egl::Image *imageTarget);
+
+ // Orphan all EGL image sources and targets
+ angle::Result orphanImages(const gl::Context *context,
+ RefCountObjectReleaser<Image> *outReleaseImage);
+
+ void notifySiblings(angle::SubjectMessage message);
+
+ private:
+ friend class Image;
+
+ // Called from Image only to add a new source image
+ void addImageSource(egl::Image *imageSource);
+
+ // Called from Image only to remove a source image when the Image is being deleted
+ void removeImageSource(egl::Image *imageSource);
+
+ static constexpr size_t kSourcesOfSetSize = 2;
+ angle::FlatUnorderedSet<Image *, kSourcesOfSetSize> mSourcesOf;
+ BindingPointer<Image> mTargetOf;
+};
+
+// Wrapper for EGLImage sources that are not owned by ANGLE, these often have to do
+// platform-specific queries for format and size information.
+class ExternalImageSibling : public ImageSibling
+{
+ public:
+ ExternalImageSibling(rx::EGLImplFactory *factory,
+ const gl::Context *context,
+ EGLenum target,
+ EGLClientBuffer buffer,
+ const AttributeMap &attribs);
+ ~ExternalImageSibling() override;
+
+ void onDestroy(const egl::Display *display);
+
+ Error initialize(const Display *display);
+
+ gl::Extents getAttachmentSize(const gl::ImageIndex &imageIndex) const override;
+ gl::Format getAttachmentFormat(GLenum binding, const gl::ImageIndex &imageIndex) const override;
+ GLsizei getAttachmentSamples(const gl::ImageIndex &imageIndex) const override;
+ GLuint getLevelCount() const;
+ bool isRenderable(const gl::Context *context,
+ GLenum binding,
+ const gl::ImageIndex &imageIndex) const override;
+ bool isTextureable(const gl::Context *context) const;
+ bool isYUV() const override;
+ bool isCubeMap() const;
+ bool hasProtectedContent() const override;
+
+ void onAttach(const gl::Context *context, rx::Serial framebufferSerial) override;
+ void onDetach(const gl::Context *context, rx::Serial framebufferSerial) override;
+ GLuint getId() const override;
+
+ gl::InitState initState(GLenum binding, const gl::ImageIndex &imageIndex) const override;
+ void setInitState(GLenum binding,
+ const gl::ImageIndex &imageIndex,
+ gl::InitState initState) override;
+
+ rx::ExternalImageSiblingImpl *getImplementation() const;
+
+ protected:
+ rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override;
+
+ private:
+ // ObserverInterface implementation.
+ void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override;
+
+ std::unique_ptr<rx::ExternalImageSiblingImpl> mImplementation;
+ angle::ObserverBinding mImplObserverBinding;
+};
+
+struct ImageState : private angle::NonCopyable
+{
+ ImageState(EGLenum target, ImageSibling *buffer, const AttributeMap &attribs);
+ ~ImageState();
+
+ EGLLabelKHR label;
+ EGLenum target;
+ gl::ImageIndex imageIndex;
+ ImageSibling *source;
+
+ gl::Format format;
+ bool yuv;
+ bool cubeMap;
+ gl::Extents size;
+ size_t samples;
+ GLuint levelCount;
+ EGLenum sourceType;
+ EGLenum colorspace;
+ bool hasProtectedContent;
+
+ mutable std::mutex targetsLock;
+
+ static constexpr size_t kTargetsSetSize = 2;
+ angle::FlatUnorderedSet<ImageSibling *, kTargetsSetSize> targets;
+};
+
+class Image final : public RefCountObject, public LabeledObject
+{
+ public:
+ Image(rx::EGLImplFactory *factory,
+ const gl::Context *context,
+ EGLenum target,
+ ImageSibling *buffer,
+ const AttributeMap &attribs);
+
+ void onDestroy(const Display *display) override;
+ ~Image() override;
+
+ void setLabel(EGLLabelKHR label) override;
+ EGLLabelKHR getLabel() const override;
+
+ const gl::Format &getFormat() const;
+ bool isRenderable(const gl::Context *context) const;
+ bool isTexturable(const gl::Context *context) const;
+ bool isYUV() const;
+ bool isCreatedWithAHB() const;
+ // Returns true only if the eglImage contains a complete cubemap
+ bool isCubeMap() const;
+ size_t getWidth() const;
+ size_t getHeight() const;
+ const gl::Extents &getExtents() const;
+ bool isLayered() const;
+ size_t getSamples() const;
+ GLuint getLevelCount() const;
+ bool hasProtectedContent() const;
+
+ Error initialize(const Display *display);
+
+ rx::ImageImpl *getImplementation() const;
+
+ bool orphaned() const;
+ gl::InitState sourceInitState() const;
+ void setInitState(gl::InitState initState);
+
+ Error exportVkImage(void *vkImage, void *vkImageCreateInfo);
+
+ private:
+ friend class ImageSibling;
+
+ // Called from ImageSibling only notify the image that a new target sibling exists for state
+ // tracking.
+ void addTargetSibling(ImageSibling *sibling);
+
+ // Called from ImageSibling only to notify the image that a sibling (source or target) has
+ // been respecified and state tracking should be updated.
+ angle::Result orphanSibling(const gl::Context *context, ImageSibling *sibling);
+
+ void notifySiblings(const ImageSibling *notifier, angle::SubjectMessage message);
+
+ ImageState mState;
+ rx::ImageImpl *mImplementation;
+ bool mOrphanedAndNeedsInit;
+};
+} // namespace egl
+
+#endif // LIBANGLE_IMAGE_H_
diff --git a/gfx/angle/checkout/src/libANGLE/ImageIndex.cpp b/gfx/angle/checkout/src/libANGLE/ImageIndex.cpp
new file mode 100644
index 0000000000..55e0393fa4
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/ImageIndex.cpp
@@ -0,0 +1,388 @@
+//
+// 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.
+//
+
+// ImageIndex.cpp: Implementation for ImageIndex methods.
+
+#include "libANGLE/ImageIndex.h"
+
+#include "common/utilities.h"
+#include "libANGLE/Constants.h"
+#include "libANGLE/angletypes.h"
+
+#include <tuple>
+
+namespace gl
+{
+namespace
+{
+GLint TextureTargetToLayer(TextureTarget target)
+{
+ switch (target)
+ {
+ case TextureTarget::CubeMapPositiveX:
+ return 0;
+ case TextureTarget::CubeMapNegativeX:
+ return 1;
+ case TextureTarget::CubeMapPositiveY:
+ return 2;
+ case TextureTarget::CubeMapNegativeY:
+ return 3;
+ case TextureTarget::CubeMapPositiveZ:
+ return 4;
+ case TextureTarget::CubeMapNegativeZ:
+ return 5;
+ case TextureTarget::External:
+ case TextureTarget::Rectangle:
+ case TextureTarget::_2D:
+ case TextureTarget::VideoImage:
+ case TextureTarget::_2DArray:
+ case TextureTarget::_2DMultisample:
+ case TextureTarget::_2DMultisampleArray:
+ case TextureTarget::_3D:
+ case TextureTarget::Buffer:
+ case TextureTarget::CubeMapArray:
+ return ImageIndex::kEntireLevel;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+bool IsArrayTarget(TextureTarget target)
+{
+ switch (target)
+ {
+ case TextureTarget::_2DArray:
+ case TextureTarget::_2DMultisampleArray:
+ case TextureTarget::CubeMapArray:
+ return true;
+ default:
+ return false;
+ }
+}
+} // anonymous namespace
+
+TextureTarget TextureTypeToTarget(TextureType type, GLint layerIndex)
+{
+ if (type == TextureType::CubeMap)
+ {
+ // As GL_TEXTURE_CUBE_MAP cannot be a texture target in texImage*D APIs, so we don't allow
+ // an entire cube map to have a texture target.
+ ASSERT(layerIndex != ImageIndex::kEntireLevel);
+ return CubeFaceIndexToTextureTarget(layerIndex);
+ }
+ else
+ {
+ return NonCubeTextureTypeToTarget(type);
+ }
+}
+
+ImageIndex::ImageIndex()
+ : mType(TextureType::InvalidEnum), mLevelIndex(0), mLayerIndex(0), mLayerCount(kEntireLevel)
+{}
+
+ImageIndex::ImageIndex(const ImageIndex &other) = default;
+
+ImageIndex &ImageIndex::operator=(const ImageIndex &other) = default;
+
+bool ImageIndex::hasLayer() const
+{
+ return mLayerIndex != kEntireLevel;
+}
+
+bool ImageIndex::isLayered() const
+{
+ switch (mType)
+ {
+ case TextureType::_2DArray:
+ case TextureType::_2DMultisampleArray:
+ case TextureType::CubeMap:
+ case TextureType::_3D:
+ case TextureType::CubeMapArray:
+ return mLayerIndex == kEntireLevel;
+ default:
+ return false;
+ }
+}
+
+bool ImageIndex::has3DLayer() const
+{
+ // It's quicker to check != CubeMap than calling usesTex3D, which checks multiple types. This
+ // ASSERT validates the check gives the same result.
+ ASSERT(!hasLayer() || ((mType != TextureType::CubeMap) == usesTex3D()));
+ return (hasLayer() && mType != TextureType::CubeMap);
+}
+
+bool ImageIndex::usesTex3D() const
+{
+ return mType == TextureType::_3D || mType == TextureType::_2DArray ||
+ mType == TextureType::_2DMultisampleArray || mType == TextureType::CubeMapArray;
+}
+
+TextureTarget ImageIndex::getTarget() const
+{
+ return TextureTypeToTarget(mType, mLayerIndex);
+}
+
+gl::TextureTarget ImageIndex::getTargetOrFirstCubeFace() const
+{
+ if (isEntireLevelCubeMap())
+ {
+ return gl::kCubeMapTextureTargetMin;
+ }
+ else
+ {
+ return getTarget();
+ }
+}
+
+GLint ImageIndex::cubeMapFaceIndex() const
+{
+ ASSERT(mType == TextureType::CubeMap);
+ ASSERT(mLayerIndex == kEntireLevel || mLayerIndex < static_cast<GLint>(kCubeFaceCount));
+ return mLayerIndex;
+}
+
+bool ImageIndex::valid() const
+{
+ return mType != TextureType::InvalidEnum;
+}
+
+bool ImageIndex::isEntireLevelCubeMap() const
+{
+ return mType == TextureType::CubeMap && mLayerIndex == ImageIndex::kEntireLevel;
+}
+
+ImageIndex ImageIndex::Make2D(GLint levelIndex)
+{
+ return ImageIndex(TextureType::_2D, levelIndex, kEntireLevel, 1);
+}
+
+ImageIndex ImageIndex::MakeRectangle(GLint levelIndex)
+{
+ return ImageIndex(TextureType::Rectangle, levelIndex, kEntireLevel, 1);
+}
+
+ImageIndex ImageIndex::MakeCubeMapFace(TextureTarget target, GLint levelIndex)
+{
+ ASSERT(IsCubeMapFaceTarget(target));
+ return ImageIndex(TextureType::CubeMap, levelIndex, TextureTargetToLayer(target), 1);
+}
+
+ImageIndex ImageIndex::Make2DArray(GLint levelIndex, GLint layerIndex)
+{
+ return ImageIndex(TextureType::_2DArray, levelIndex, layerIndex, 1);
+}
+
+ImageIndex ImageIndex::Make2DArrayRange(GLint levelIndex, GLint layerIndex, GLint numLayers)
+{
+ return ImageIndex(TextureType::_2DArray, levelIndex, layerIndex, numLayers);
+}
+
+ImageIndex ImageIndex::Make3D(GLint levelIndex, GLint layerIndex)
+{
+ return ImageIndex(TextureType::_3D, levelIndex, layerIndex, 1);
+}
+
+ImageIndex ImageIndex::MakeFromTarget(TextureTarget target, GLint levelIndex, GLint depth)
+{
+ return ImageIndex(TextureTargetToType(target), levelIndex, TextureTargetToLayer(target),
+ IsArrayTarget(target) ? depth : 1);
+}
+
+ImageIndex ImageIndex::MakeFromType(TextureType type,
+ GLint levelIndex,
+ GLint layerIndex,
+ GLint layerCount)
+{
+ GLint overrideLayerCount =
+ (type == TextureType::CubeMap && layerIndex == kEntireLevel ? kCubeFaceCount : layerCount);
+ return ImageIndex(type, levelIndex, layerIndex, overrideLayerCount);
+}
+
+ImageIndex ImageIndex::MakeBuffer()
+{
+ return ImageIndex(TextureType::Buffer, 0, kEntireLevel, 1);
+}
+
+ImageIndex ImageIndex::Make2DMultisample()
+{
+ return ImageIndex(TextureType::_2DMultisample, 0, kEntireLevel, 1);
+}
+
+ImageIndex ImageIndex::Make2DMultisampleArray(GLint layerIndex)
+{
+ return ImageIndex(TextureType::_2DMultisampleArray, 0, layerIndex, 1);
+}
+
+ImageIndex ImageIndex::Make2DMultisampleArrayRange(GLint layerIndex, GLint numLayers)
+{
+ return ImageIndex(TextureType::_2DMultisampleArray, 0, layerIndex, numLayers);
+}
+
+bool ImageIndex::operator<(const ImageIndex &b) const
+{
+ return std::tie(mType, mLevelIndex, mLayerIndex, mLayerCount) <
+ std::tie(b.mType, b.mLevelIndex, b.mLayerIndex, b.mLayerCount);
+}
+
+bool ImageIndex::operator==(const ImageIndex &b) const
+{
+ return std::tie(mType, mLevelIndex, mLayerIndex, mLayerCount) ==
+ std::tie(b.mType, b.mLevelIndex, b.mLayerIndex, b.mLayerCount);
+}
+
+bool ImageIndex::operator!=(const ImageIndex &b) const
+{
+ return !(*this == b);
+}
+
+ImageIndex::ImageIndex(TextureType type, GLint levelIndex, GLint layerIndex, GLint layerCount)
+ : mType(type), mLevelIndex(levelIndex), mLayerIndex(layerIndex), mLayerCount(layerCount)
+{}
+
+ImageIndexIterator ImageIndex::getLayerIterator(GLint layerCount) const
+{
+ ASSERT(mType != TextureType::_2D && !hasLayer());
+ return ImageIndexIterator::MakeGeneric(mType, mLevelIndex, mLevelIndex + 1, 0, layerCount);
+}
+
+ImageIndexIterator::ImageIndexIterator(const ImageIndexIterator &other) = default;
+
+ImageIndexIterator ImageIndexIterator::Make2D(GLint minMip, GLint maxMip)
+{
+ return ImageIndexIterator(TextureType::_2D, Range<GLint>(minMip, maxMip),
+ Range<GLint>(ImageIndex::kEntireLevel, ImageIndex::kEntireLevel),
+ nullptr);
+}
+
+ImageIndexIterator ImageIndexIterator::MakeRectangle(GLint minMip, GLint maxMip)
+{
+ return ImageIndexIterator(TextureType::Rectangle, Range<GLint>(minMip, maxMip),
+ Range<GLint>(ImageIndex::kEntireLevel, ImageIndex::kEntireLevel),
+ nullptr);
+}
+
+ImageIndexIterator ImageIndexIterator::MakeCube(GLint minMip, GLint maxMip)
+{
+ return ImageIndexIterator(TextureType::CubeMap, Range<GLint>(minMip, maxMip),
+ Range<GLint>(0, 6), nullptr);
+}
+
+ImageIndexIterator ImageIndexIterator::Make3D(GLint minMip,
+ GLint maxMip,
+ GLint minLayer,
+ GLint maxLayer)
+{
+ return ImageIndexIterator(TextureType::_3D, Range<GLint>(minMip, maxMip),
+ Range<GLint>(minLayer, maxLayer), nullptr);
+}
+
+ImageIndexIterator ImageIndexIterator::Make2DArray(GLint minMip,
+ GLint maxMip,
+ const GLsizei *layerCounts)
+{
+ return ImageIndexIterator(TextureType::_2DArray, Range<GLint>(minMip, maxMip),
+ Range<GLint>(0, IMPLEMENTATION_MAX_2D_ARRAY_TEXTURE_LAYERS),
+ layerCounts);
+}
+
+ImageIndexIterator ImageIndexIterator::Make2DMultisample()
+{
+ return ImageIndexIterator(TextureType::_2DMultisample, Range<GLint>(0, 1),
+ Range<GLint>(ImageIndex::kEntireLevel, ImageIndex::kEntireLevel),
+ nullptr);
+}
+
+ImageIndexIterator ImageIndexIterator::MakeBuffer()
+{
+ return ImageIndexIterator(TextureType::Buffer, Range<GLint>(0, 1),
+ Range<GLint>(ImageIndex::kEntireLevel, ImageIndex::kEntireLevel),
+ nullptr);
+}
+
+ImageIndexIterator ImageIndexIterator::Make2DMultisampleArray(const GLsizei *layerCounts)
+{
+ return ImageIndexIterator(TextureType::_2DMultisampleArray, Range<GLint>(0, 1),
+ Range<GLint>(0, IMPLEMENTATION_MAX_2D_ARRAY_TEXTURE_LAYERS),
+ layerCounts);
+}
+
+ImageIndexIterator ImageIndexIterator::MakeGeneric(TextureType type,
+ GLint minMip,
+ GLint maxMip,
+ GLint minLayer,
+ GLint maxLayer)
+{
+ if (type == TextureType::CubeMap)
+ {
+ return MakeCube(minMip, maxMip);
+ }
+
+ return ImageIndexIterator(type, Range<GLint>(minMip, maxMip), Range<GLint>(minLayer, maxLayer),
+ nullptr);
+}
+
+ImageIndexIterator::ImageIndexIterator(TextureType type,
+ const Range<GLint> &mipRange,
+ const Range<GLint> &layerRange,
+ const GLsizei *layerCounts)
+ : mMipRange(mipRange),
+ mLayerRange(layerRange),
+ mLayerCounts(layerCounts),
+ mCurrentIndex(type, mipRange.low(), layerRange.low(), 1)
+{}
+
+GLint ImageIndexIterator::maxLayer() const
+{
+ if (mLayerCounts)
+ {
+ ASSERT(mCurrentIndex.hasLayer());
+ return (mCurrentIndex.getLevelIndex() < mMipRange.high())
+ ? mLayerCounts[mCurrentIndex.getLevelIndex()]
+ : 0;
+ }
+ return mLayerRange.high();
+}
+
+ImageIndex ImageIndexIterator::next()
+{
+ ASSERT(hasNext());
+
+ // Make a copy of the current index to return
+ ImageIndex previousIndex = mCurrentIndex;
+
+ // Iterate layers in the inner loop for now. We can add switchable
+ // layer or mip iteration if we need it.
+
+ if (mCurrentIndex.hasLayer() && mCurrentIndex.getLayerIndex() < maxLayer() - 1)
+ {
+ mCurrentIndex.mLayerIndex++;
+ }
+ else if (mCurrentIndex.mLevelIndex < mMipRange.high() - 1)
+ {
+ mCurrentIndex.mLayerIndex = mLayerRange.low();
+ mCurrentIndex.mLevelIndex++;
+ }
+ else
+ {
+ mCurrentIndex = ImageIndex();
+ }
+
+ return previousIndex;
+}
+
+ImageIndex ImageIndexIterator::current() const
+{
+ return mCurrentIndex;
+}
+
+bool ImageIndexIterator::hasNext() const
+{
+ return mCurrentIndex.valid();
+}
+
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/ImageIndex.h b/gfx/angle/checkout/src/libANGLE/ImageIndex.h
new file mode 100644
index 0000000000..4625d310d8
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/ImageIndex.h
@@ -0,0 +1,133 @@
+//
+// 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.
+//
+
+// ImageIndex.h: A helper struct for indexing into an Image array
+
+#ifndef LIBANGLE_IMAGE_INDEX_H_
+#define LIBANGLE_IMAGE_INDEX_H_
+
+#include "common/PackedEnums.h"
+#include "common/mathutil.h"
+
+#include "angle_gl.h"
+
+namespace gl
+{
+
+class ImageIndexIterator;
+
+class ImageIndex
+{
+ public:
+ ImageIndex();
+ ImageIndex(const ImageIndex &other);
+ ImageIndex &operator=(const ImageIndex &other);
+
+ TextureType getType() const { return mType; }
+ GLint getLevelIndex() const { return mLevelIndex; }
+ GLint getLayerIndex() const { return mLayerIndex; }
+ GLint getLayerCount() const { return mLayerCount; }
+
+ bool hasLayer() const;
+ bool has3DLayer() const;
+ bool usesTex3D() const;
+ GLint cubeMapFaceIndex() const;
+ bool valid() const;
+ // Note that you cannot use this function when the ImageIndex represents an entire level of cube
+ // map.
+ TextureTarget getTarget() const;
+
+ TextureTarget getTargetOrFirstCubeFace() const;
+
+ bool isLayered() const;
+ bool isEntireLevelCubeMap() const;
+
+ static ImageIndex MakeBuffer();
+ static ImageIndex Make2D(GLint levelIndex);
+ static ImageIndex MakeRectangle(GLint levelIndex);
+ static ImageIndex MakeCubeMapFace(TextureTarget target, GLint levelIndex);
+ static ImageIndex Make2DArray(GLint levelIndex, GLint layerIndex = kEntireLevel);
+ static ImageIndex Make2DArrayRange(GLint levelIndex, GLint layerIndex, GLint layerCount);
+ static ImageIndex Make3D(GLint levelIndex, GLint layerIndex = kEntireLevel);
+ static ImageIndex MakeFromTarget(TextureTarget target, GLint levelIndex, GLint depth = 0);
+ static ImageIndex MakeFromType(TextureType type,
+ GLint levelIndex,
+ GLint layerIndex = kEntireLevel,
+ GLint layerCount = 1);
+ static ImageIndex Make2DMultisample();
+ static ImageIndex Make2DMultisampleArray(GLint layerIndex = kEntireLevel);
+ static ImageIndex Make2DMultisampleArrayRange(GLint layerIndex, GLint layerCount);
+
+ static constexpr GLint kEntireLevel = static_cast<GLint>(-1);
+
+ bool operator<(const ImageIndex &b) const;
+ bool operator==(const ImageIndex &b) const;
+ bool operator!=(const ImageIndex &b) const;
+
+ // Only valid for 3D/Cube textures with layers.
+ ImageIndexIterator getLayerIterator(GLint layerCount) const;
+
+ private:
+ friend class ImageIndexIterator;
+
+ ImageIndex(TextureType type, GLint leveIndex, GLint layerIndex, GLint layerCount);
+
+ TextureType mType;
+ GLint mLevelIndex;
+ GLint mLayerIndex;
+ GLint mLayerCount;
+};
+
+// To be used like this:
+//
+// ImageIndexIterator it = ...;
+// while (it.hasNext())
+// {
+// ImageIndex current = it.next();
+// }
+class ImageIndexIterator
+{
+ public:
+ ImageIndexIterator(const ImageIndexIterator &other);
+
+ static ImageIndexIterator MakeBuffer();
+ static ImageIndexIterator Make2D(GLint minMip, GLint maxMip);
+ static ImageIndexIterator MakeRectangle(GLint minMip, GLint maxMip);
+ static ImageIndexIterator MakeCube(GLint minMip, GLint maxMip);
+ static ImageIndexIterator Make3D(GLint minMip, GLint maxMip, GLint minLayer, GLint maxLayer);
+ static ImageIndexIterator Make2DArray(GLint minMip, GLint maxMip, const GLsizei *layerCounts);
+ static ImageIndexIterator Make2DMultisample();
+ static ImageIndexIterator Make2DMultisampleArray(const GLsizei *layerCounts);
+ static ImageIndexIterator MakeGeneric(TextureType type,
+ GLint minMip,
+ GLint maxMip,
+ GLint minLayer,
+ GLint maxLayer);
+
+ ImageIndex next();
+ ImageIndex current() const;
+ bool hasNext() const;
+
+ private:
+ ImageIndexIterator(TextureType type,
+ const Range<GLint> &mipRange,
+ const Range<GLint> &layerRange,
+ const GLsizei *layerCounts);
+
+ GLint maxLayer() const;
+
+ const Range<GLint> mMipRange;
+ const Range<GLint> mLayerRange;
+ const GLsizei *const mLayerCounts;
+
+ ImageIndex mCurrentIndex;
+};
+
+TextureTarget TextureTypeToTarget(TextureType type, GLint layerIndex);
+
+} // namespace gl
+
+#endif // LIBANGLE_IMAGE_INDEX_H_
diff --git a/gfx/angle/checkout/src/libANGLE/IndexRangeCache.cpp b/gfx/angle/checkout/src/libANGLE/IndexRangeCache.cpp
new file mode 100644
index 0000000000..d16b2bd9c7
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/IndexRangeCache.cpp
@@ -0,0 +1,116 @@
+//
+// Copyright 2013 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.
+//
+
+// IndexRangeCache.cpp: Defines the gl::IndexRangeCache class which stores information about
+// ranges of indices.
+
+#include "libANGLE/IndexRangeCache.h"
+
+#include "common/debug.h"
+#include "libANGLE/formatutils.h"
+
+namespace gl
+{
+
+IndexRangeCache::IndexRangeCache() {}
+
+IndexRangeCache::~IndexRangeCache() {}
+
+void IndexRangeCache::addRange(DrawElementsType type,
+ size_t offset,
+ size_t count,
+ bool primitiveRestartEnabled,
+ const IndexRange &range)
+{
+ mIndexRangeCache[IndexRangeKey(type, offset, count, primitiveRestartEnabled)] = range;
+}
+
+bool IndexRangeCache::findRange(DrawElementsType type,
+ size_t offset,
+ size_t count,
+ bool primitiveRestartEnabled,
+ IndexRange *outRange) const
+{
+ auto i = mIndexRangeCache.find(IndexRangeKey(type, offset, count, primitiveRestartEnabled));
+ if (i != mIndexRangeCache.end())
+ {
+ if (outRange)
+ {
+ *outRange = i->second;
+ }
+ return true;
+ }
+ else
+ {
+ if (outRange)
+ {
+ *outRange = IndexRange();
+ }
+ return false;
+ }
+}
+
+void IndexRangeCache::invalidateRange(size_t offset, size_t size)
+{
+ size_t invalidateStart = offset;
+ size_t invalidateEnd = offset + size;
+
+ auto i = mIndexRangeCache.begin();
+ while (i != mIndexRangeCache.end())
+ {
+ size_t rangeStart = i->first.offset;
+ size_t rangeEnd =
+ i->first.offset + (GetDrawElementsTypeSize(i->first.type) * i->first.count);
+
+ if (invalidateEnd < rangeStart || invalidateStart > rangeEnd)
+ {
+ ++i;
+ }
+ else
+ {
+ mIndexRangeCache.erase(i++);
+ }
+ }
+}
+
+void IndexRangeCache::clear()
+{
+ mIndexRangeCache.clear();
+}
+
+IndexRangeCache::IndexRangeKey::IndexRangeKey()
+ : IndexRangeCache::IndexRangeKey(DrawElementsType::InvalidEnum, 0, 0, false)
+{}
+
+IndexRangeCache::IndexRangeKey::IndexRangeKey(DrawElementsType type_,
+ size_t offset_,
+ size_t count_,
+ bool primitiveRestartEnabled_)
+ : type(type_), offset(offset_), count(count_), primitiveRestartEnabled(primitiveRestartEnabled_)
+{}
+
+bool IndexRangeCache::IndexRangeKey::operator<(const IndexRangeKey &rhs) const
+{
+ if (type != rhs.type)
+ {
+ return type < rhs.type;
+ }
+ if (offset != rhs.offset)
+ {
+ return offset < rhs.offset;
+ }
+ if (count != rhs.count)
+ {
+ return count < rhs.count;
+ }
+ if (primitiveRestartEnabled != rhs.primitiveRestartEnabled)
+ {
+ return primitiveRestartEnabled;
+ }
+ return false;
+}
+
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/IndexRangeCache.h b/gfx/angle/checkout/src/libANGLE/IndexRangeCache.h
new file mode 100644
index 0000000000..0a0c22fe04
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/IndexRangeCache.h
@@ -0,0 +1,63 @@
+//
+// Copyright 2013 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.
+//
+
+// IndexRangeCache.h: Defines the gl::IndexRangeCache class which stores information about
+// ranges of indices.
+
+#ifndef LIBANGLE_INDEXRANGECACHE_H_
+#define LIBANGLE_INDEXRANGECACHE_H_
+
+#include "angle_gl.h"
+#include "common/PackedEnums.h"
+#include "common/angleutils.h"
+#include "common/mathutil.h"
+
+#include <map>
+
+namespace gl
+{
+
+class IndexRangeCache
+{
+ public:
+ IndexRangeCache();
+ ~IndexRangeCache();
+
+ void addRange(DrawElementsType type,
+ size_t offset,
+ size_t count,
+ bool primitiveRestartEnabled,
+ const IndexRange &range);
+ bool findRange(DrawElementsType type,
+ size_t offset,
+ size_t count,
+ bool primitiveRestartEnabled,
+ IndexRange *outRange) const;
+
+ void invalidateRange(size_t offset, size_t size);
+ void clear();
+
+ private:
+ struct IndexRangeKey
+ {
+ IndexRangeKey();
+ IndexRangeKey(DrawElementsType type, size_t offset, size_t count, bool primitiveRestart);
+
+ bool operator<(const IndexRangeKey &rhs) const;
+
+ DrawElementsType type;
+ size_t offset;
+ size_t count;
+ bool primitiveRestartEnabled;
+ };
+
+ typedef std::map<IndexRangeKey, IndexRange> IndexRangeMap;
+ IndexRangeMap mIndexRangeCache;
+};
+
+} // namespace gl
+
+#endif // LIBANGLE_INDEXRANGECACHE_H_
diff --git a/gfx/angle/checkout/src/libANGLE/InfoLog.h b/gfx/angle/checkout/src/libANGLE/InfoLog.h
new file mode 100644
index 0000000000..53333ea1aa
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/InfoLog.h
@@ -0,0 +1,90 @@
+//
+// Copyright 2020 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.
+//
+// InfoLog.h: Defines the gl::InfoLog class to handle the logs generated when
+// compiling/linking shaders so useful error messages can be returned to the caller.
+
+#ifndef LIBANGLE_INFOLOG_H_
+#define LIBANGLE_INFOLOG_H_
+
+namespace gl
+{
+
+class InfoLog : angle::NonCopyable
+{
+ public:
+ InfoLog();
+ ~InfoLog();
+
+ size_t getLength() const;
+ void getLog(GLsizei bufSize, GLsizei *length, char *infoLog) const;
+
+ void appendSanitized(const char *message);
+ void reset();
+
+ // This helper class ensures we append a newline after writing a line.
+ class StreamHelper : angle::NonCopyable
+ {
+ public:
+ StreamHelper(StreamHelper &&rhs) : mStream(rhs.mStream) { rhs.mStream = nullptr; }
+
+ StreamHelper &operator=(StreamHelper &&rhs)
+ {
+ std::swap(mStream, rhs.mStream);
+ return *this;
+ }
+
+ ~StreamHelper()
+ {
+ // Write newline when destroyed on the stack
+ if (mStream && !mStream->str().empty())
+ {
+ (*mStream) << std::endl;
+ }
+ }
+
+ template <typename T>
+ StreamHelper &operator<<(const T &value)
+ {
+ (*mStream) << value;
+ return *this;
+ }
+
+ private:
+ friend class InfoLog;
+
+ StreamHelper(std::stringstream *stream) : mStream(stream) { ASSERT(stream); }
+
+ std::stringstream *mStream;
+ };
+
+ template <typename T>
+ StreamHelper operator<<(const T &value)
+ {
+ ensureInitialized();
+ StreamHelper helper(mLazyStream.get());
+ helper << value;
+ return helper;
+ }
+
+ std::string str() const { return mLazyStream ? mLazyStream->str() : ""; }
+
+ bool empty() const;
+
+ private:
+ void ensureInitialized()
+ {
+ if (!mLazyStream)
+ {
+ mLazyStream.reset(new std::stringstream());
+ }
+ }
+
+ std::unique_ptr<std::stringstream> mLazyStream;
+};
+
+} // namespace gl
+
+#endif // LIBANGLE_INFOLOG_H_
diff --git a/gfx/angle/checkout/src/libANGLE/LoggingAnnotator.cpp b/gfx/angle/checkout/src/libANGLE/LoggingAnnotator.cpp
new file mode 100644
index 0000000000..4cf999c4a0
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/LoggingAnnotator.cpp
@@ -0,0 +1,63 @@
+//
+// Copyright 2017 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.
+//
+// LoggingAnnotator.cpp: DebugAnnotator implementing logging
+//
+
+#include "libANGLE/LoggingAnnotator.h"
+
+#include "libANGLE/trace.h"
+
+namespace angle
+{
+
+bool LoggingAnnotator::getStatus(const gl::Context *context)
+{
+ return false;
+}
+
+void LoggingAnnotator::beginEvent(gl::Context *context,
+ EntryPoint entryPoint,
+ const char *eventName,
+ const char *eventMessage)
+{
+ ANGLE_TRACE_EVENT_BEGIN0("gpu.angle", eventName);
+}
+
+void LoggingAnnotator::endEvent(gl::Context *context, const char *eventName, EntryPoint entryPoint)
+{
+ ANGLE_TRACE_EVENT_END0("gpu.angle", eventName);
+}
+
+void LoggingAnnotator::setMarker(gl::Context *context, const char *markerName)
+{
+ ANGLE_TRACE_EVENT_INSTANT0("gpu.angle", markerName);
+}
+
+void LoggingAnnotator::logMessage(const gl::LogMessage &msg) const
+{
+ auto *plat = ANGLEPlatformCurrent();
+ if (plat != nullptr)
+ {
+ switch (msg.getSeverity())
+ {
+ case gl::LOG_FATAL:
+ case gl::LOG_ERR:
+ plat->logError(plat, msg.getMessage().c_str());
+ break;
+ case gl::LOG_WARN:
+ plat->logWarning(plat, msg.getMessage().c_str());
+ break;
+ case gl::LOG_INFO:
+ plat->logInfo(plat, msg.getMessage().c_str());
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+ gl::Trace(msg.getSeverity(), msg.getMessage().c_str());
+}
+
+} // namespace angle
diff --git a/gfx/angle/checkout/src/libANGLE/LoggingAnnotator.h b/gfx/angle/checkout/src/libANGLE/LoggingAnnotator.h
new file mode 100644
index 0000000000..7a86d4e72f
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/LoggingAnnotator.h
@@ -0,0 +1,39 @@
+//
+// Copyright 2017 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.
+//
+// LoggingAnnotator.h: DebugAnnotator implementing logging
+//
+
+#ifndef LIBANGLE_LOGGINGANNOTATOR_H_
+#define LIBANGLE_LOGGINGANNOTATOR_H_
+
+#include "common/debug.h"
+
+namespace gl
+{
+class Context;
+} // namespace gl
+
+namespace angle
+{
+
+class LoggingAnnotator : public gl::DebugAnnotator
+{
+ public:
+ LoggingAnnotator() {}
+ ~LoggingAnnotator() override {}
+ void beginEvent(gl::Context *context,
+ EntryPoint entryPoint,
+ const char *eventName,
+ const char *eventMessage) override;
+ void endEvent(gl::Context *context, const char *eventName, EntryPoint entryPoint) override;
+ void setMarker(gl::Context *context, const char *markerName) override;
+ bool getStatus(const gl::Context *context) override;
+ void logMessage(const gl::LogMessage &msg) const override;
+};
+
+} // namespace angle
+
+#endif // LIBANGLE_LOGGINGANNOTATOR_H_
diff --git a/gfx/angle/checkout/src/libANGLE/MemoryObject.cpp b/gfx/angle/checkout/src/libANGLE/MemoryObject.cpp
new file mode 100644
index 0000000000..a137f265c5
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/MemoryObject.cpp
@@ -0,0 +1,66 @@
+//
+// Copyright 2019 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.
+//
+// MemoryObject.h: Implements the gl::MemoryObject class [EXT_external_objects]
+
+#include "libANGLE/MemoryObject.h"
+
+#include "common/angleutils.h"
+#include "libANGLE/renderer/GLImplFactory.h"
+#include "libANGLE/renderer/MemoryObjectImpl.h"
+
+namespace gl
+{
+
+MemoryObject::MemoryObject(rx::GLImplFactory *factory, MemoryObjectID id)
+ : RefCountObject(factory->generateSerial(), id),
+ mImplementation(factory->createMemoryObject()),
+ mImmutable(false),
+ mDedicatedMemory(false),
+ mProtectedMemory(false)
+{}
+
+MemoryObject::~MemoryObject() {}
+
+void MemoryObject::onDestroy(const Context *context)
+{
+ mImplementation->onDestroy(context);
+}
+
+angle::Result MemoryObject::setDedicatedMemory(const Context *context, bool dedicatedMemory)
+{
+ ANGLE_TRY(mImplementation->setDedicatedMemory(context, dedicatedMemory));
+ mDedicatedMemory = dedicatedMemory;
+ return angle::Result::Continue;
+}
+
+angle::Result MemoryObject::setProtectedMemory(const Context *context, bool protectedMemory)
+{
+ ANGLE_TRY(mImplementation->setProtectedMemory(context, protectedMemory));
+ mProtectedMemory = protectedMemory;
+ return angle::Result::Continue;
+}
+
+angle::Result MemoryObject::importFd(Context *context,
+ GLuint64 size,
+ HandleType handleType,
+ GLint fd)
+{
+ ANGLE_TRY(mImplementation->importFd(context, size, handleType, fd));
+ mImmutable = true;
+ return angle::Result::Continue;
+}
+
+angle::Result MemoryObject::importZirconHandle(Context *context,
+ GLuint64 size,
+ HandleType handleType,
+ GLuint handle)
+{
+ ANGLE_TRY(mImplementation->importZirconHandle(context, size, handleType, handle));
+ mImmutable = true;
+ return angle::Result::Continue;
+}
+
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/MemoryObject.h b/gfx/angle/checkout/src/libANGLE/MemoryObject.h
new file mode 100644
index 0000000000..0507f7e2c3
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/MemoryObject.h
@@ -0,0 +1,60 @@
+//
+// Copyright 2019 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.
+//
+// MemoryObject.h: Defines the gl::MemoryObject class [EXT_external_objects]
+
+#ifndef LIBANGLE_MEMORYOBJECT_H_
+#define LIBANGLE_MEMORYOBJECT_H_
+
+#include "angle_gl.h"
+#include "common/PackedEnums.h"
+#include "common/angleutils.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/RefCountObject.h"
+
+namespace rx
+{
+class GLImplFactory;
+class MemoryObjectImpl;
+} // namespace rx
+
+namespace gl
+{
+class Context;
+
+class MemoryObject final : public RefCountObject<MemoryObjectID>
+{
+ public:
+ MemoryObject(rx::GLImplFactory *factory, MemoryObjectID id);
+ ~MemoryObject() override;
+
+ void onDestroy(const Context *context) override;
+
+ rx::MemoryObjectImpl *getImplementation() const { return mImplementation.get(); }
+
+ bool isImmutable() const { return mImmutable; }
+
+ angle::Result setDedicatedMemory(const Context *context, bool dedicatedMemory);
+ bool isDedicatedMemory() const { return mDedicatedMemory; }
+ angle::Result setProtectedMemory(const Context *context, bool protectedMemory);
+ bool isProtectedMemory() const { return mProtectedMemory; }
+
+ angle::Result importFd(Context *context, GLuint64 size, HandleType handleType, GLint fd);
+ angle::Result importZirconHandle(Context *context,
+ GLuint64 size,
+ HandleType handleType,
+ GLuint handle);
+
+ private:
+ std::unique_ptr<rx::MemoryObjectImpl> mImplementation;
+
+ bool mImmutable;
+ bool mDedicatedMemory;
+ bool mProtectedMemory;
+};
+
+} // namespace gl
+
+#endif // LIBANGLE_MEMORYOBJECT_H_
diff --git a/gfx/angle/checkout/src/libANGLE/MemoryProgramCache.cpp b/gfx/angle/checkout/src/libANGLE/MemoryProgramCache.cpp
new file mode 100644
index 0000000000..35894913a6
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/MemoryProgramCache.cpp
@@ -0,0 +1,283 @@
+//
+// Copyright 2017 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.
+//
+// MemoryProgramCache: Stores compiled and linked programs in memory so they don't
+// always have to be re-compiled. Can be used in conjunction with the platform
+// layer to warm up the cache from disk.
+
+// Include zlib first, otherwise FAR gets defined elsewhere.
+#define USE_SYSTEM_ZLIB
+#include "compression_utils_portable.h"
+
+#include "libANGLE/MemoryProgramCache.h"
+
+#include <GLSLANG/ShaderVars.h>
+#include <anglebase/sha1.h>
+
+#include "common/angle_version_info.h"
+#include "common/utilities.h"
+#include "libANGLE/BinaryStream.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Debug.h"
+#include "libANGLE/Uniform.h"
+#include "libANGLE/capture/FrameCapture.h"
+#include "libANGLE/histogram_macros.h"
+#include "libANGLE/renderer/ProgramImpl.h"
+#include "platform/PlatformMethods.h"
+
+namespace gl
+{
+
+namespace
+{
+class HashStream final : angle::NonCopyable
+{
+ public:
+ std::string str() { return mStringStream.str(); }
+
+ template <typename T>
+ HashStream &operator<<(T value)
+ {
+ mStringStream << value << kSeparator;
+ return *this;
+ }
+
+ private:
+ static constexpr char kSeparator = ':';
+ std::ostringstream mStringStream;
+};
+
+HashStream &operator<<(HashStream &stream, Shader *shader)
+{
+ if (shader)
+ {
+ stream << shader->getSourceString().c_str() << shader->getSourceString().length()
+ << shader->getCompilerResourcesString().c_str();
+ }
+ return stream;
+}
+
+HashStream &operator<<(HashStream &stream, const ProgramBindings &bindings)
+{
+ for (const auto &binding : bindings.getStableIterationMap())
+ {
+ stream << binding.first << binding.second;
+ }
+ return stream;
+}
+
+HashStream &operator<<(HashStream &stream, const ProgramAliasedBindings &bindings)
+{
+ for (const auto &binding : bindings.getStableIterationMap())
+ {
+ stream << binding.first << binding.second.location;
+ }
+ return stream;
+}
+
+HashStream &operator<<(HashStream &stream, const std::vector<std::string> &strings)
+{
+ for (const auto &str : strings)
+ {
+ stream << str;
+ }
+ return stream;
+}
+
+HashStream &operator<<(HashStream &stream, const std::vector<gl::VariableLocation> &locations)
+{
+ for (const auto &loc : locations)
+ {
+ stream << loc.index << loc.arrayIndex << loc.ignored;
+ }
+ return stream;
+}
+
+} // anonymous namespace
+
+MemoryProgramCache::MemoryProgramCache(egl::BlobCache &blobCache) : mBlobCache(blobCache) {}
+
+MemoryProgramCache::~MemoryProgramCache() {}
+
+void MemoryProgramCache::ComputeHash(const Context *context,
+ const Program *program,
+ egl::BlobCache::Key *hashOut)
+{
+ // Compute the program hash. Start with the shader hashes and resource strings.
+ HashStream hashStream;
+ for (ShaderType shaderType : AllShaderTypes())
+ {
+ hashStream << program->getAttachedShader(shaderType);
+ }
+
+ // Add some ANGLE metadata and Context properties, such as version and back-end.
+ hashStream << angle::GetANGLECommitHash() << context->getClientMajorVersion()
+ << context->getClientMinorVersion() << context->getString(GL_RENDERER);
+
+ // Hash pre-link program properties.
+ hashStream << program->getAttributeBindings() << program->getUniformLocationBindings()
+ << program->getFragmentOutputLocations() << program->getFragmentOutputIndexes()
+ << program->getState().getTransformFeedbackVaryingNames()
+ << program->getState().getTransformFeedbackBufferMode()
+ << program->getState().getOutputLocations()
+ << program->getState().getSecondaryOutputLocations();
+
+ // Include the status of FrameCapture, which adds source strings to the binary
+ hashStream << context->getShareGroup()->getFrameCaptureShared()->enabled();
+
+ // Call the secure SHA hashing function.
+ const std::string &programKey = hashStream.str();
+ angle::base::SHA1HashBytes(reinterpret_cast<const unsigned char *>(programKey.c_str()),
+ programKey.length(), hashOut->data());
+}
+
+angle::Result MemoryProgramCache::getProgram(const Context *context,
+ Program *program,
+ egl::BlobCache::Key *hashOut)
+{
+ // If caching is effectively disabled, don't bother calculating the hash.
+ if (!mBlobCache.isCachingEnabled())
+ {
+ return angle::Result::Incomplete;
+ }
+
+ ComputeHash(context, program, hashOut);
+
+ angle::MemoryBuffer uncompressedData;
+ switch (mBlobCache.getAndDecompress(context->getScratchBuffer(), *hashOut, &uncompressedData))
+ {
+ case egl::BlobCache::GetAndDecompressResult::NotFound:
+ return angle::Result::Incomplete;
+
+ case egl::BlobCache::GetAndDecompressResult::DecompressFailure:
+ ANGLE_PERF_WARNING(context->getState().getDebug(), GL_DEBUG_SEVERITY_LOW,
+ "Error decompressing program binary data fetched from cache.");
+ return angle::Result::Incomplete;
+
+ case egl::BlobCache::GetAndDecompressResult::GetSuccess:
+ angle::Result result =
+ program->loadBinary(context, GL_PROGRAM_BINARY_ANGLE, uncompressedData.data(),
+ static_cast<int>(uncompressedData.size()));
+ ANGLE_TRY(result);
+
+ if (result == angle::Result::Continue)
+ return angle::Result::Continue;
+
+ // Cache load failed, evict
+ ANGLE_PERF_WARNING(context->getState().getDebug(), GL_DEBUG_SEVERITY_LOW,
+ "Failed to load program binary from cache.");
+ remove(*hashOut);
+
+ return angle::Result::Incomplete;
+ }
+
+ UNREACHABLE();
+ return angle::Result::Incomplete;
+}
+
+bool MemoryProgramCache::getAt(size_t index,
+ const egl::BlobCache::Key **hashOut,
+ egl::BlobCache::Value *programOut)
+{
+ return mBlobCache.getAt(index, hashOut, programOut);
+}
+
+void MemoryProgramCache::remove(const egl::BlobCache::Key &programHash)
+{
+ mBlobCache.remove(programHash);
+}
+
+angle::Result MemoryProgramCache::putProgram(const egl::BlobCache::Key &programHash,
+ const Context *context,
+ const Program *program)
+{
+ // If caching is effectively disabled, don't bother serializing the program.
+ if (!mBlobCache.isCachingEnabled())
+ {
+ return angle::Result::Incomplete;
+ }
+
+ angle::MemoryBuffer serializedProgram;
+ ANGLE_TRY(program->serialize(context, &serializedProgram));
+
+ angle::MemoryBuffer compressedData;
+ if (!egl::CompressBlobCacheData(serializedProgram.size(), serializedProgram.data(),
+ &compressedData))
+ {
+ ANGLE_PERF_WARNING(context->getState().getDebug(), GL_DEBUG_SEVERITY_LOW,
+ "Error compressing binary data.");
+ return angle::Result::Incomplete;
+ }
+
+ {
+ std::scoped_lock<std::mutex> lock(mBlobCache.getMutex());
+ // TODO: http://anglebug.com/7568
+ // This was a workaround for Chrome until it added support for EGL_ANDROID_blob_cache,
+ // tracked by http://anglebug.com/2516. This issue has since been closed, but removing this
+ // still causes a test failure.
+ auto *platform = ANGLEPlatformCurrent();
+ platform->cacheProgram(platform, programHash, compressedData.size(), compressedData.data());
+ }
+
+ mBlobCache.put(programHash, std::move(compressedData));
+ return angle::Result::Continue;
+}
+
+angle::Result MemoryProgramCache::updateProgram(const Context *context, const Program *program)
+{
+ egl::BlobCache::Key programHash;
+ ComputeHash(context, program, &programHash);
+ return putProgram(programHash, context, program);
+}
+
+bool MemoryProgramCache::putBinary(const egl::BlobCache::Key &programHash,
+ const uint8_t *binary,
+ size_t length)
+{
+ // Copy the binary.
+ angle::MemoryBuffer newEntry;
+ if (!newEntry.resize(length))
+ {
+ return false;
+ }
+ memcpy(newEntry.data(), binary, length);
+
+ // Store the binary.
+ mBlobCache.populate(programHash, std::move(newEntry));
+
+ return true;
+}
+
+void MemoryProgramCache::clear()
+{
+ mBlobCache.clear();
+}
+
+void MemoryProgramCache::resize(size_t maxCacheSizeBytes)
+{
+ mBlobCache.resize(maxCacheSizeBytes);
+}
+
+size_t MemoryProgramCache::entryCount() const
+{
+ return mBlobCache.entryCount();
+}
+
+size_t MemoryProgramCache::trim(size_t limit)
+{
+ return mBlobCache.trim(limit);
+}
+
+size_t MemoryProgramCache::size() const
+{
+ return mBlobCache.size();
+}
+
+size_t MemoryProgramCache::maxSize() const
+{
+ return mBlobCache.maxSize();
+}
+
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/MemoryProgramCache.h b/gfx/angle/checkout/src/libANGLE/MemoryProgramCache.h
new file mode 100644
index 0000000000..92f774ebed
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/MemoryProgramCache.h
@@ -0,0 +1,87 @@
+//
+// Copyright 2017 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.
+//
+// MemoryProgramCache: Stores compiled and linked programs in memory so they don't
+// always have to be re-compiled. Can be used in conjunction with the platform
+// layer to warm up the cache from disk.
+
+#ifndef LIBANGLE_MEMORY_PROGRAM_CACHE_H_
+#define LIBANGLE_MEMORY_PROGRAM_CACHE_H_
+
+#include <array>
+
+#include "common/MemoryBuffer.h"
+#include "libANGLE/BlobCache.h"
+#include "libANGLE/Error.h"
+
+namespace gl
+{
+class Context;
+class Program;
+class ProgramState;
+
+class MemoryProgramCache final : angle::NonCopyable
+{
+ public:
+ explicit MemoryProgramCache(egl::BlobCache &blobCache);
+ ~MemoryProgramCache();
+
+ static void ComputeHash(const Context *context,
+ const Program *program,
+ egl::BlobCache::Key *hashOut);
+
+ // For querying the contents of the cache.
+ bool getAt(size_t index,
+ const egl::BlobCache::Key **hashOut,
+ egl::BlobCache::Value *programOut);
+
+ // Evict a program from the binary cache.
+ void remove(const egl::BlobCache::Key &programHash);
+
+ // Helper method that serializes a program.
+ angle::Result putProgram(const egl::BlobCache::Key &programHash,
+ const Context *context,
+ const Program *program);
+
+ // Same as putProgram but computes the hash.
+ angle::Result updateProgram(const Context *context, const Program *program);
+
+ // Store a binary directly. TODO(syoussefi): deprecated. Will be removed once Chrome supports
+ // EGL_ANDROID_blob_cache. http://anglebug.com/2516
+ [[nodiscard]] bool putBinary(const egl::BlobCache::Key &programHash,
+ const uint8_t *binary,
+ size_t length);
+
+ // Check the cache, and deserialize and load the program if found. Evict existing hash if load
+ // fails.
+ angle::Result getProgram(const Context *context,
+ Program *program,
+ egl::BlobCache::Key *hashOut);
+
+ // Empty the cache.
+ void clear();
+
+ // Resize the cache. Discards current contents.
+ void resize(size_t maxCacheSizeBytes);
+
+ // Returns the number of entries in the cache.
+ size_t entryCount() const;
+
+ // Reduces the current cache size and returns the number of bytes freed.
+ size_t trim(size_t limit);
+
+ // Returns the current cache size in bytes.
+ size_t size() const;
+
+ // Returns the maximum cache size in bytes.
+ size_t maxSize() const;
+
+ private:
+ egl::BlobCache &mBlobCache;
+};
+
+} // namespace gl
+
+#endif // LIBANGLE_MEMORY_PROGRAM_CACHE_H_
diff --git a/gfx/angle/checkout/src/libANGLE/MemoryShaderCache.cpp b/gfx/angle/checkout/src/libANGLE/MemoryShaderCache.cpp
new file mode 100644
index 0000000000..2bd7baef5e
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/MemoryShaderCache.cpp
@@ -0,0 +1,155 @@
+//
+// Copyright 2022 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.
+//
+// MemoryShaderCache: Stores compiled shader in memory so they don't
+// always have to be re-compiled. Can be used in conjunction with the platform
+// layer to warm up the cache from disk.
+
+#include "libANGLE/MemoryShaderCache.h"
+
+#include <GLSLANG/ShaderVars.h>
+#include <anglebase/sha1.h>
+
+#include "common/angle_version_info.h"
+#include "common/utilities.h"
+#include "libANGLE/BinaryStream.h"
+#include "libANGLE/Compiler.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Debug.h"
+#include "libANGLE/Uniform.h"
+#include "libANGLE/histogram_macros.h"
+#include "libANGLE/renderer/ShaderImpl.h"
+#include "platform/PlatformMethods.h"
+
+namespace gl
+{
+
+namespace
+{
+void ComputeHash(const Context *context,
+ const Shader *shader,
+ const ShCompileOptions &compileOptions,
+ const ShCompilerInstance &compilerInstance,
+ egl::BlobCache::Key *hashOut)
+{
+ BinaryOutputStream hashStream;
+ // Compute the shader hash. Start with the shader hashes and resource strings.
+ hashStream.writeEnum(shader->getType());
+ hashStream.writeString(shader->getSourceString());
+
+ // Include the commit hash
+ hashStream.writeString(angle::GetANGLECommitHash());
+
+ hashStream.writeEnum(Compiler::SelectShaderSpec(context->getState()));
+ hashStream.writeEnum(compilerInstance.getShaderOutputType());
+ hashStream.writeBytes(reinterpret_cast<const uint8_t *>(&compileOptions),
+ sizeof(compileOptions));
+
+ // Include the ShBuiltInResources, which represent the extensions and constants used by the
+ // shader.
+ const ShBuiltInResources resources = compilerInstance.getBuiltInResources();
+ hashStream.writeBytes(reinterpret_cast<const uint8_t *>(&resources), sizeof(resources));
+
+ // Call the secure SHA hashing function.
+ const std::vector<uint8_t> &shaderKey = hashStream.getData();
+ angle::base::SHA1HashBytes(shaderKey.data(), shaderKey.size(), hashOut->data());
+}
+} // namespace
+
+MemoryShaderCache::MemoryShaderCache(egl::BlobCache &blobCache) : mBlobCache(blobCache) {}
+
+MemoryShaderCache::~MemoryShaderCache() {}
+
+angle::Result MemoryShaderCache::getShader(const Context *context,
+ Shader *shader,
+ const ShCompileOptions &compileOptions,
+ const ShCompilerInstance &compilerInstance,
+ egl::BlobCache::Key *hashOut)
+{
+ // If caching is effectively disabled, don't bother calculating the hash.
+ if (!mBlobCache.isCachingEnabled())
+ {
+ return angle::Result::Incomplete;
+ }
+
+ ComputeHash(context, shader, compileOptions, compilerInstance, hashOut);
+
+ angle::MemoryBuffer uncompressedData;
+ switch (mBlobCache.getAndDecompress(context->getScratchBuffer(), *hashOut, &uncompressedData))
+ {
+ case egl::BlobCache::GetAndDecompressResult::DecompressFailure:
+ ANGLE_PERF_WARNING(context->getState().getDebug(), GL_DEBUG_SEVERITY_LOW,
+ "Error decompressing shader binary data from cache.");
+ return angle::Result::Incomplete;
+
+ case egl::BlobCache::GetAndDecompressResult::NotFound:
+ return angle::Result::Incomplete;
+
+ case egl::BlobCache::GetAndDecompressResult::GetSuccess:
+ angle::Result result = shader->loadBinary(context, uncompressedData.data(),
+ static_cast<int>(uncompressedData.size()));
+
+ {
+ std::scoped_lock<std::mutex> lock(mHistogramMutex);
+ ANGLE_HISTOGRAM_BOOLEAN("GPU.ANGLE.ShaderCache.LoadBinarySuccess",
+ result == angle::Result::Continue);
+ }
+ ANGLE_TRY(result);
+
+ if (result == angle::Result::Continue)
+ return angle::Result::Continue;
+
+ // Cache load failed, evict.
+ ANGLE_PERF_WARNING(context->getState().getDebug(), GL_DEBUG_SEVERITY_LOW,
+ "Failed to load shader binary from cache.");
+ mBlobCache.remove(*hashOut);
+ return angle::Result::Incomplete;
+ }
+
+ UNREACHABLE();
+ return angle::Result::Incomplete;
+}
+
+angle::Result MemoryShaderCache::putShader(const Context *context,
+ const egl::BlobCache::Key &shaderHash,
+ const Shader *shader)
+{
+ // If caching is effectively disabled, don't bother serializing the shader.
+ if (!mBlobCache.isCachingEnabled())
+ {
+ return angle::Result::Incomplete;
+ }
+
+ angle::MemoryBuffer serializedShader;
+ ANGLE_TRY(shader->serialize(nullptr, &serializedShader));
+
+ size_t compressedSize;
+ if (!mBlobCache.compressAndPut(shaderHash, std::move(serializedShader), &compressedSize))
+ {
+ ANGLE_PERF_WARNING(context->getState().getDebug(), GL_DEBUG_SEVERITY_LOW,
+ "Error compressing shader binary data for insertion into cache.");
+ return angle::Result::Incomplete;
+ }
+
+ {
+ std::scoped_lock<std::mutex> lock(mHistogramMutex);
+ ANGLE_HISTOGRAM_COUNTS("GPU.ANGLE.ShaderCache.ShaderBinarySizeBytes",
+ static_cast<int>(compressedSize));
+ }
+
+ return angle::Result::Continue;
+}
+
+void MemoryShaderCache::clear()
+{
+ mBlobCache.clear();
+}
+
+size_t MemoryShaderCache::maxSize() const
+{
+ return mBlobCache.maxSize();
+}
+
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/MemoryShaderCache.h b/gfx/angle/checkout/src/libANGLE/MemoryShaderCache.h
new file mode 100644
index 0000000000..464201d4c7
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/MemoryShaderCache.h
@@ -0,0 +1,60 @@
+//
+// Copyright 2022 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.
+//
+// MemoryShaderCache: Stores compiled shaders in memory so they don't
+// always have to be re-compiled. Can be used in conjunction with the platform
+// layer to warm up the cache from disk.
+
+#ifndef LIBANGLE_MEMORY_SHADER_CACHE_H_
+#define LIBANGLE_MEMORY_SHADER_CACHE_H_
+
+#include <array>
+
+#include "GLSLANG/ShaderLang.h"
+#include "common/MemoryBuffer.h"
+#include "libANGLE/BlobCache.h"
+#include "libANGLE/Error.h"
+
+namespace gl
+{
+class Context;
+class Shader;
+class ShaderState;
+class ShCompilerInstance;
+
+class MemoryShaderCache final : angle::NonCopyable
+{
+ public:
+ explicit MemoryShaderCache(egl::BlobCache &blobCache);
+ ~MemoryShaderCache();
+
+ // Helper method that serializes a shader.
+ angle::Result putShader(const Context *context,
+ const egl::BlobCache::Key &shaderHash,
+ const Shader *shader);
+
+ // Check the cache, and deserialize and load the shader if found. Evict existing hash if load
+ // fails.
+ angle::Result getShader(const Context *context,
+ Shader *shader,
+ const ShCompileOptions &compileOptions,
+ const ShCompilerInstance &compilerInstance,
+ egl::BlobCache::Key *hashOut);
+
+ // Empty the cache.
+ void clear();
+
+ // Returns the maximum cache size in bytes.
+ size_t maxSize() const;
+
+ private:
+ egl::BlobCache &mBlobCache;
+
+ std::mutex mHistogramMutex;
+};
+
+} // namespace gl
+
+#endif // LIBANGLE_MEMORY_SHADER_CACHE_H_
diff --git a/gfx/angle/checkout/src/libANGLE/Observer.cpp b/gfx/angle/checkout/src/libANGLE/Observer.cpp
new file mode 100644
index 0000000000..75f51648a4
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Observer.cpp
@@ -0,0 +1,113 @@
+//
+// Copyright 2018 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.
+//
+// Observer:
+// Implements the Observer pattern for sending state change notifications
+// from Subject objects to dependent Observer objects.
+//
+// See design document:
+// https://docs.google.com/document/d/15Edfotqg6_l1skTEL8ADQudF_oIdNa7i8Po43k6jMd4/
+
+#include "libANGLE/Observer.h"
+
+#include <algorithm>
+
+#include "common/debug.h"
+
+namespace angle
+{
+namespace
+{} // anonymous namespace
+
+// Observer implementation.
+ObserverInterface::~ObserverInterface() = default;
+
+// Subject implementation.
+Subject::Subject() {}
+
+Subject::~Subject()
+{
+ resetObservers();
+}
+
+bool Subject::hasObservers() const
+{
+ return !mObservers.empty();
+}
+
+void Subject::onStateChange(SubjectMessage message) const
+{
+ if (mObservers.empty())
+ return;
+
+ for (const ObserverBindingBase *binding : mObservers)
+ {
+ binding->getObserver()->onSubjectStateChange(binding->getSubjectIndex(), message);
+ }
+}
+
+void Subject::resetObservers()
+{
+ for (angle::ObserverBindingBase *binding : mObservers)
+ {
+ binding->onSubjectReset();
+ }
+ mObservers.clear();
+}
+
+// ObserverBinding implementation.
+ObserverBinding::ObserverBinding() : ObserverBindingBase(nullptr, 0), mSubject(nullptr) {}
+
+ObserverBinding::ObserverBinding(ObserverInterface *observer, SubjectIndex index)
+ : ObserverBindingBase(observer, index), mSubject(nullptr)
+{
+ ASSERT(observer);
+}
+
+ObserverBinding::~ObserverBinding()
+{
+ reset();
+}
+
+ObserverBinding::ObserverBinding(const ObserverBinding &other)
+ : ObserverBindingBase(other), mSubject(nullptr)
+{
+ bind(other.mSubject);
+}
+
+ObserverBinding &ObserverBinding::operator=(const ObserverBinding &other)
+{
+ reset();
+ ObserverBindingBase::operator=(other);
+ bind(other.mSubject);
+ return *this;
+}
+
+void ObserverBinding::bind(Subject *subject)
+{
+ ASSERT(getObserver() || !subject);
+ if (mSubject)
+ {
+ mSubject->removeObserver(this);
+ }
+
+ mSubject = subject;
+
+ if (mSubject)
+ {
+ mSubject->addObserver(this);
+ }
+}
+
+void ObserverBinding::onStateChange(SubjectMessage message) const
+{
+ getObserver()->onSubjectStateChange(getSubjectIndex(), message);
+}
+
+void ObserverBinding::onSubjectReset()
+{
+ mSubject = nullptr;
+}
+} // namespace angle
diff --git a/gfx/angle/checkout/src/libANGLE/Observer.h b/gfx/angle/checkout/src/libANGLE/Observer.h
new file mode 100644
index 0000000000..a07a224b99
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Observer.h
@@ -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.
+//
+// Observer:
+// Implements the Observer pattern for sending state change notifications
+// from Subject objects to dependent Observer objects.
+//
+// See design document:
+// https://docs.google.com/document/d/15Edfotqg6_l1skTEL8ADQudF_oIdNa7i8Po43k6jMd4/
+
+#ifndef LIBANGLE_OBSERVER_H_
+#define LIBANGLE_OBSERVER_H_
+
+#include "common/FastVector.h"
+#include "common/angleutils.h"
+
+namespace angle
+{
+template <typename HaystackT, typename NeedleT>
+bool IsInContainer(const HaystackT &haystack, const NeedleT &needle)
+{
+ return std::find(haystack.begin(), haystack.end(), needle) != haystack.end();
+}
+
+using SubjectIndex = size_t;
+
+// Messages are used to distinguish different Subject events that get sent to a single Observer.
+// It could be possible to improve the handling by using different callback functions instead
+// of a single handler function. But in some cases we want to share a single binding between
+// Observer and Subject and handle different types of events.
+enum class SubjectMessage
+{
+ // Used by gl::VertexArray to notify gl::Context of a gl::Buffer binding count change. Triggers
+ // a validation cache update. Also used by gl::Texture to notify gl::Framebuffer of loops.
+ BindingChanged,
+
+ // Only the contents (pixels, bytes, etc) changed in this Subject. Distinct from the object
+ // storage.
+ ContentsChanged,
+
+ // Sent by gl::Sampler, gl::Texture, gl::Framebuffer and others to notifiy gl::Context. This
+ // flag indicates to call syncState before next use.
+ DirtyBitsFlagged,
+
+ // Generic state change message. Used in multiple places for different purposes.
+ SubjectChanged,
+
+ // Indicates a bound gl::Buffer is now mapped or unmapped. Passed from gl::Buffer, through
+ // gl::VertexArray, into gl::Context. Used to track validation.
+ SubjectMapped,
+ SubjectUnmapped,
+ // Indicates a bound buffer's storage was reallocated due to glBufferData call or optimizations
+ // to prevent having to flush pending commands and waiting for the GPU to become idle.
+ InternalMemoryAllocationChanged,
+
+ // Indicates an external change to the default framebuffer.
+ SurfaceChanged,
+ // Indicates the system framebuffer's swapchain changed, i.e. color buffer changed but no
+ // depth/stencil buffer change.
+ SwapchainImageChanged,
+
+ // Indicates a separable program's textures or images changed in the ProgramExecutable.
+ ProgramTextureOrImageBindingChanged,
+ // Indicates a separable program was successfully re-linked.
+ ProgramRelinked,
+ // Indicates a separable program's sampler uniforms were updated.
+ SamplerUniformsUpdated,
+ // Other types of uniform change.
+ ProgramUniformUpdated,
+
+ // Indicates a Storage of back-end in gl::Texture has been released.
+ StorageReleased,
+
+ // Indicates that all pending updates are complete in the subject.
+ InitializationComplete,
+};
+
+// The observing class inherits from this interface class.
+class ObserverInterface
+{
+ public:
+ virtual ~ObserverInterface();
+ virtual void onSubjectStateChange(SubjectIndex index, SubjectMessage message) = 0;
+};
+
+class ObserverBindingBase
+{
+ public:
+ ObserverBindingBase(ObserverInterface *observer, SubjectIndex subjectIndex)
+ : mObserver(observer), mIndex(subjectIndex)
+ {}
+ virtual ~ObserverBindingBase() {}
+
+ ObserverBindingBase(const ObserverBindingBase &other) = default;
+ ObserverBindingBase &operator=(const ObserverBindingBase &other) = default;
+
+ ObserverInterface *getObserver() const { return mObserver; }
+ SubjectIndex getSubjectIndex() const { return mIndex; }
+
+ virtual void onSubjectReset() {}
+
+ private:
+ ObserverInterface *mObserver;
+ SubjectIndex mIndex;
+};
+
+constexpr size_t kMaxFixedObservers = 8;
+
+// Maintains a list of observer bindings. Sends update messages to the observer.
+class Subject : NonCopyable
+{
+ public:
+ Subject();
+ virtual ~Subject();
+
+ void onStateChange(SubjectMessage message) const;
+ bool hasObservers() const;
+ void resetObservers();
+ ANGLE_INLINE size_t getObserversCount() const { return mObservers.size(); }
+
+ ANGLE_INLINE void addObserver(ObserverBindingBase *observer)
+ {
+ ASSERT(!IsInContainer(mObservers, observer));
+ mObservers.push_back(observer);
+ }
+ ANGLE_INLINE void removeObserver(ObserverBindingBase *observer)
+ {
+ ASSERT(IsInContainer(mObservers, observer));
+ mObservers.remove_and_permute(observer);
+ }
+
+ private:
+ // Keep a short list of observers so we can allocate/free them quickly. But since we support
+ // unlimited bindings, have a spill-over list of that uses dynamic allocation.
+ angle::FastVector<ObserverBindingBase *, kMaxFixedObservers> mObservers;
+};
+
+// Keeps a binding between a Subject and Observer, with a specific subject index.
+class ObserverBinding final : public ObserverBindingBase
+{
+ public:
+ ObserverBinding();
+ ObserverBinding(ObserverInterface *observer, SubjectIndex index);
+ ~ObserverBinding() override;
+ ObserverBinding(const ObserverBinding &other);
+ ObserverBinding &operator=(const ObserverBinding &other);
+
+ void bind(Subject *subject);
+
+ ANGLE_INLINE void reset() { bind(nullptr); }
+
+ void onStateChange(SubjectMessage message) const;
+ void onSubjectReset() override;
+
+ ANGLE_INLINE const Subject *getSubject() const { return mSubject; }
+
+ ANGLE_INLINE void assignSubject(Subject *subject) { mSubject = subject; }
+
+ private:
+ Subject *mSubject;
+};
+
+} // namespace angle
+
+#endif // LIBANGLE_OBSERVER_H_
diff --git a/gfx/angle/checkout/src/libANGLE/Overlay.cpp b/gfx/angle/checkout/src/libANGLE/Overlay.cpp
new file mode 100644
index 0000000000..e84b125361
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Overlay.cpp
@@ -0,0 +1,103 @@
+//
+// Copyright 2019 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.
+//
+// Overlay.cpp:
+// Implements the Overlay class.
+//
+
+#include "libANGLE/Overlay.h"
+
+#include "common/string_utils.h"
+#include "common/system_utils.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Overlay_font_autogen.h"
+#include "libANGLE/renderer/GLImplFactory.h"
+#include "libANGLE/renderer/OverlayImpl.h"
+
+#include <numeric>
+
+namespace gl
+{
+namespace
+{
+#define ANGLE_WIDGET_NAME_PROC(WIDGET_ID) {ANGLE_STRINGIFY(WIDGET_ID), WidgetId::WIDGET_ID},
+
+constexpr std::pair<const char *, WidgetId> kWidgetNames[] = {
+ ANGLE_WIDGET_ID_X(ANGLE_WIDGET_NAME_PROC)};
+} // namespace
+
+OverlayState::OverlayState() : mEnabledWidgetCount(0), mOverlayWidgets{} {}
+OverlayState::~OverlayState() = default;
+
+Overlay::Overlay(rx::GLImplFactory *factory)
+ : mLastPerSecondUpdate(0), mImplementation(factory->createOverlay(mState))
+{}
+Overlay::~Overlay() = default;
+
+void Overlay::init()
+{
+ initOverlayWidgets();
+ mLastPerSecondUpdate = angle::GetCurrentSystemTime();
+
+ ASSERT(std::all_of(
+ mState.mOverlayWidgets.begin(), mState.mOverlayWidgets.end(),
+ [](const std::unique_ptr<overlay::Widget> &widget) { return widget.get() != nullptr; }));
+
+ enableOverlayWidgetsFromEnvironment();
+}
+
+void Overlay::destroy(const gl::Context *context)
+{
+ ASSERT(mImplementation);
+ mImplementation->onDestroy(context);
+}
+
+void Overlay::enableOverlayWidgetsFromEnvironment()
+{
+ std::vector<std::string> enabledWidgets = angle::GetStringsFromEnvironmentVarOrAndroidProperty(
+ "ANGLE_OVERLAY", "debug.angle.overlay", ":");
+
+ for (const std::pair<const char *, WidgetId> &widgetName : kWidgetNames)
+ {
+ for (const std::string &enabledWidget : enabledWidgets)
+ {
+ if (angle::NamesMatchWithWildcard(enabledWidget.c_str(), widgetName.first))
+ {
+ mState.mOverlayWidgets[widgetName.second]->enabled = true;
+ ++mState.mEnabledWidgetCount;
+ break;
+ }
+ }
+ }
+}
+
+void Overlay::onSwap() const
+{
+ // Increment FPS counter.
+ getPerSecondWidget(WidgetId::FPS)->add(1);
+
+ // Update per second values every second.
+ double currentTime = angle::GetCurrentSystemTime();
+ double timeDiff = currentTime - mLastPerSecondUpdate;
+ if (timeDiff >= 1.0)
+ {
+ for (const std::unique_ptr<overlay::Widget> &widget : mState.mOverlayWidgets)
+ {
+ if (widget->type == WidgetType::PerSecond)
+ {
+ overlay::PerSecond *perSecond =
+ reinterpret_cast<overlay::PerSecond *>(widget.get());
+ perSecond->lastPerSecondCount = static_cast<size_t>(perSecond->count / timeDiff);
+ perSecond->count = 0;
+ }
+ }
+ mLastPerSecondUpdate += 1.0;
+ }
+}
+
+MockOverlay::MockOverlay(rx::GLImplFactory *implFactory) {}
+MockOverlay::~MockOverlay() = default;
+
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/Overlay.h b/gfx/angle/checkout/src/libANGLE/Overlay.h
new file mode 100644
index 0000000000..124e00d3e6
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Overlay.h
@@ -0,0 +1,154 @@
+//
+// Copyright 2019 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.
+//
+// Overlay.h:
+// Defines the Overlay class that handles overlay widgets.
+//
+
+#ifndef LIBANGLE_OVERLAY_H_
+#define LIBANGLE_OVERLAY_H_
+
+#include "common/PackedEnums.h"
+#include "common/angleutils.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/OverlayWidgets.h"
+#include "libANGLE/angletypes.h"
+
+namespace rx
+{
+class OverlayImpl;
+class GLImplFactory;
+} // namespace rx
+
+namespace gl
+{
+class Context;
+
+class OverlayState : angle::NonCopyable
+{
+ public:
+ OverlayState();
+ ~OverlayState();
+
+ size_t getWidgetCoordinatesBufferSize() const;
+ size_t getTextWidgetsBufferSize() const;
+ size_t getGraphWidgetsBufferSize() const;
+
+ const uint8_t *getFontData() const;
+ void fillWidgetData(const gl::Extents &imageExtents,
+ uint8_t *textData,
+ uint8_t *graphData,
+ uint32_t *activeTextWidgetCountOut,
+ uint32_t *activeGraphWidgetCountOut) const;
+
+ uint32_t getEnabledWidgetCount() const { return mEnabledWidgetCount; }
+
+ private:
+ friend class Overlay;
+
+ uint32_t mEnabledWidgetCount;
+
+ angle::PackedEnumMap<WidgetId, std::unique_ptr<overlay::Widget>> mOverlayWidgets;
+};
+
+class Overlay : angle::NonCopyable
+{
+ public:
+ Overlay(rx::GLImplFactory *implFactory);
+ ~Overlay();
+
+ void init();
+ void destroy(const gl::Context *context);
+
+ void onSwap() const;
+
+ overlay::Text *getTextWidget(WidgetId id) const
+ {
+ return getWidgetAs<overlay::Text, WidgetType::Text>(id);
+ }
+ overlay::Count *getCountWidget(WidgetId id) const
+ {
+ return getWidgetAs<overlay::Count, WidgetType::Count>(id);
+ }
+ overlay::PerSecond *getPerSecondWidget(WidgetId id) const
+ {
+ return getWidgetAs<overlay::PerSecond, WidgetType::PerSecond>(id);
+ }
+ overlay::RunningGraph *getRunningGraphWidget(WidgetId id) const
+ {
+ return getWidgetAs<overlay::RunningGraph, WidgetType::RunningGraph>(id);
+ }
+ overlay::RunningHistogram *getRunningHistogramWidget(WidgetId id) const
+ {
+ return getWidgetAs<overlay::RunningHistogram, WidgetType::RunningHistogram>(id);
+ }
+
+ rx::OverlayImpl *getImplementation() const { return mImplementation.get(); }
+
+ bool isEnabled() const
+ {
+ return mImplementation != nullptr && mState.getEnabledWidgetCount() > 0;
+ }
+
+ private:
+ template <typename Widget, WidgetType Type>
+ Widget *getWidgetAs(WidgetId id) const
+ {
+ ASSERT(mState.mOverlayWidgets[id] != nullptr);
+ ASSERT(mState.mOverlayWidgets[id]->type == Type);
+ return rx::GetAs<Widget>(mState.mOverlayWidgets[id].get());
+ }
+ void initOverlayWidgets();
+ void enableOverlayWidgetsFromEnvironment();
+
+ // Time tracking for PerSecond items.
+ mutable double mLastPerSecondUpdate;
+
+ OverlayState mState;
+ std::unique_ptr<rx::OverlayImpl> mImplementation;
+};
+
+class MockOverlay
+{
+ public:
+ MockOverlay(rx::GLImplFactory *implFactory);
+ ~MockOverlay();
+
+ void init() {}
+ void destroy(const Context *context) {}
+
+ void onSwap() const {}
+
+ const overlay::Mock *getTextWidget(WidgetId id) const { return &mMock; }
+ const overlay::Mock *getCountWidget(WidgetId id) const { return &mMock; }
+ const overlay::Mock *getPerSecondWidget(WidgetId id) const { return &mMock; }
+ const overlay::Mock *getRunningGraphWidget(WidgetId id) const { return &mMock; }
+ const overlay::Mock *getRunningHistogramWidget(WidgetId id) const { return &mMock; }
+
+ bool isEnabled() const { return false; }
+
+ private:
+ overlay::Mock mMock;
+};
+
+#if ANGLE_ENABLE_OVERLAY
+using OverlayType = Overlay;
+using CountWidget = overlay::Count;
+using PerSecondWidget = overlay::PerSecond;
+using RunningGraphWidget = overlay::RunningGraph;
+using RunningHistogramWidget = overlay::RunningHistogram;
+using TextWidget = overlay::Text;
+#else // !ANGLE_ENABLE_OVERLAY
+using OverlayType = MockOverlay;
+using CountWidget = const overlay::Mock;
+using PerSecondWidget = const overlay::Mock;
+using RunningGraphWidget = const overlay::Mock;
+using RunningHistogramWidget = const overlay::Mock;
+using TextWidget = const overlay::Mock;
+#endif // ANGLE_ENABLE_OVERLAY
+
+} // namespace gl
+
+#endif // LIBANGLE_OVERLAY_H_
diff --git a/gfx/angle/checkout/src/libANGLE/OverlayWidgets.cpp b/gfx/angle/checkout/src/libANGLE/OverlayWidgets.cpp
new file mode 100644
index 0000000000..f0581ce9d8
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/OverlayWidgets.cpp
@@ -0,0 +1,737 @@
+//
+// Copyright 2019 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.
+//
+// OverlayWidgets.cpp:
+// Implements functions that interpret widget data. Data formats and limits correspond to the
+// Vulkan implementation (as the only implementation). They are generic enough so other backends
+// could respect them too, if they implement the overlay.
+//
+
+#include "libANGLE/Overlay.h"
+#include "libANGLE/Overlay_font_autogen.h"
+
+#include <functional>
+
+namespace gl
+{
+namespace
+{
+// Internally, every widget is either Text or Graph.
+enum class WidgetInternalType
+{
+ Text,
+ Graph,
+
+ InvalidEnum,
+ EnumCount = InvalidEnum,
+};
+
+// A map that says how the API-facing widget types map to internal types.
+constexpr angle::PackedEnumMap<WidgetType, WidgetInternalType> kWidgetTypeToInternalMap = {
+ {WidgetType::Count, WidgetInternalType::Text},
+ {WidgetType::Text, WidgetInternalType::Text},
+ {WidgetType::PerSecond, WidgetInternalType::Text},
+ {WidgetType::RunningGraph, WidgetInternalType::Graph},
+ {WidgetType::RunningHistogram, WidgetInternalType::Graph},
+};
+
+// Structures and limits matching uniform buffers in vulkan/shaders/src/OverlayDraw.comp. The size
+// of text and graph widgets is chosen such that they could fit in uniform buffers with minimum
+// required Vulkan size.
+constexpr size_t kMaxRenderableTextWidgets = 32;
+constexpr size_t kMaxRenderableGraphWidgets = 32;
+constexpr size_t kMaxTextLength = 256;
+constexpr size_t kMaxGraphDataSize = 256;
+
+constexpr angle::PackedEnumMap<WidgetInternalType, size_t> kWidgetInternalTypeMaxWidgets = {
+ {WidgetInternalType::Text, kMaxRenderableTextWidgets},
+ {WidgetInternalType::Graph, kMaxRenderableGraphWidgets},
+};
+
+ANGLE_ENABLE_STRUCT_PADDING_WARNINGS
+
+// Structure matching buffer in vulkan/shaders/src/OverlayCull.comp.
+struct WidgetCoordinates
+{
+ uint32_t coordinates[kMaxRenderableTextWidgets + kMaxRenderableGraphWidgets][4];
+};
+
+// Structures matching buffers in vulkan/shaders/src/OverlayDraw.comp.
+struct TextWidgetData
+{
+ uint32_t coordinates[4];
+ float color[4];
+ uint32_t fontSize[3];
+ uint32_t padding;
+ uint8_t text[kMaxTextLength];
+};
+
+struct GraphWidgetData
+{
+ uint32_t coordinates[4];
+ float color[4];
+ uint32_t valueWidth;
+ uint32_t padding[3];
+ uint32_t values[kMaxGraphDataSize];
+};
+
+struct TextWidgets
+{
+ TextWidgetData widgets[kMaxRenderableTextWidgets];
+};
+
+struct GraphWidgets
+{
+ GraphWidgetData widgets[kMaxRenderableGraphWidgets];
+};
+
+ANGLE_DISABLE_STRUCT_PADDING_WARNINGS
+
+uint32_t GetWidgetCoord(int32_t src, uint32_t extent)
+{
+ int32_t dst = src < 0 ? extent + src : src;
+
+ return std::min<uint32_t>(std::max(dst, 0), extent - 1);
+}
+
+void GetWidgetCoordinates(const int32_t srcCoords[4],
+ const gl::Extents &imageExtent,
+ uint32_t dstCoordsOut[4])
+{
+ dstCoordsOut[0] = GetWidgetCoord(srcCoords[0], imageExtent.width);
+ dstCoordsOut[1] = GetWidgetCoord(srcCoords[1], imageExtent.height);
+ dstCoordsOut[2] = GetWidgetCoord(srcCoords[2], imageExtent.width);
+ dstCoordsOut[3] = GetWidgetCoord(srcCoords[3], imageExtent.height);
+}
+
+void GetWidgetColor(const float srcColor[4], float dstColor[4])
+{
+ memcpy(dstColor, srcColor, 4 * sizeof(dstColor[0]));
+}
+
+void GetTextFontSize(int srcFontSize, uint32_t dstFontSize[3])
+{
+ // .xy contains the font glyph width/height
+ dstFontSize[0] = overlay::kFontGlyphWidth >> srcFontSize;
+ dstFontSize[1] = overlay::kFontGlyphHeight >> srcFontSize;
+ // .z contains the mip
+ dstFontSize[2] = srcFontSize;
+}
+
+void GetGraphValueWidth(const int32_t srcCoords[4], size_t valueCount, uint32_t *dstValueWidth)
+{
+ const int32_t graphWidth = std::abs(srcCoords[2] - srcCoords[0]);
+
+ // If valueCount doesn't divide graphWidth, the graph bars won't fit well in its frame.
+ // Fix initOverlayWidgets() in that case.
+ ASSERT(graphWidth % valueCount == 0);
+
+ *dstValueWidth = graphWidth / valueCount;
+}
+
+void GetTextString(const std::string &src, uint8_t textOut[kMaxTextLength])
+{
+ for (size_t i = 0; i < src.length() && i < kMaxTextLength; ++i)
+ {
+ // The font image has 95 ASCII characters starting from ' '.
+ textOut[i] = src[i] - ' ';
+ }
+}
+
+void GetGraphValues(const std::vector<uint64_t> srcValues,
+ size_t startIndex,
+ float scale,
+ uint32_t valuesOut[kMaxGraphDataSize])
+{
+ ASSERT(srcValues.size() <= kMaxGraphDataSize);
+
+ for (size_t i = 0; i < srcValues.size(); ++i)
+ {
+ size_t index = (startIndex + i) % srcValues.size();
+ valuesOut[i] = static_cast<uint32_t>(srcValues[index] * scale);
+ }
+}
+
+std::vector<uint64_t> CreateHistogram(const std::vector<uint64_t> values)
+{
+ std::vector<uint64_t> histogram(values.size(), 0);
+
+ for (uint64_t rank : values)
+ {
+ ++histogram[static_cast<size_t>(rank)];
+ }
+
+ return histogram;
+}
+
+using OverlayWidgetCounts = angle::PackedEnumMap<WidgetInternalType, uint32_t>;
+using AppendWidgetDataFunc = void (*)(const overlay::Widget *widget,
+ const gl::Extents &imageExtent,
+ TextWidgetData *textWidget,
+ GraphWidgetData *graphWidget,
+ OverlayWidgetCounts *widgetCounts);
+} // namespace
+
+namespace overlay_impl
+{
+#define ANGLE_DECLARE_APPEND_WIDGET_PROC(WIDGET_ID) \
+ static void Append##WIDGET_ID(const overlay::Widget *widget, const gl::Extents &imageExtent, \
+ TextWidgetData *textWidget, GraphWidgetData *graphWidget, \
+ OverlayWidgetCounts *widgetCounts);
+
+// This class interprets the generic data collected in every element into a human-understandable
+// widget. This often means generating text specific to this item and scaling graph data to
+// something sensible.
+class AppendWidgetDataHelper
+{
+ public:
+ ANGLE_WIDGET_ID_X(ANGLE_DECLARE_APPEND_WIDGET_PROC)
+
+ private:
+ static std::ostream &OutputPerSecond(std::ostream &out, const overlay::PerSecond *perSecond);
+
+ static std::ostream &OutputText(std::ostream &out, const overlay::Text *text);
+
+ static std::ostream &OutputCount(std::ostream &out, const overlay::Count *count);
+
+ static void AppendTextCommon(const overlay::Widget *widget,
+ const gl::Extents &imageExtent,
+ const std::string &text,
+ TextWidgetData *textWidget,
+ OverlayWidgetCounts *widgetCounts);
+
+ using FormatGraphTitleFunc = std::function<std::string(uint64_t curValue, uint64_t maxValue)>;
+ static void AppendRunningGraphCommon(const overlay::Widget *widget,
+ const gl::Extents &imageExtent,
+ TextWidgetData *textWidget,
+ GraphWidgetData *graphWidget,
+ OverlayWidgetCounts *widgetCounts,
+ FormatGraphTitleFunc formatFunc);
+
+ using FormatHistogramTitleFunc =
+ std::function<std::string(size_t peakRange, size_t maxValueRange, size_t numRanges)>;
+ static void AppendRunningHistogramCommon(const overlay::Widget *widget,
+ const gl::Extents &imageExtent,
+ TextWidgetData *textWidget,
+ GraphWidgetData *graphWidget,
+ OverlayWidgetCounts *widgetCounts,
+ FormatHistogramTitleFunc formatFunc);
+
+ static void AppendGraphCommon(const overlay::Widget *widget,
+ const gl::Extents &imageExtent,
+ const std::vector<uint64_t> runningValues,
+ size_t startIndex,
+ float scale,
+ GraphWidgetData *graphWidget,
+ OverlayWidgetCounts *widgetCounts);
+};
+
+void AppendWidgetDataHelper::AppendTextCommon(const overlay::Widget *widget,
+ const gl::Extents &imageExtent,
+ const std::string &text,
+ TextWidgetData *textWidget,
+ OverlayWidgetCounts *widgetCounts)
+{
+ GetWidgetCoordinates(widget->coords, imageExtent, textWidget->coordinates);
+ GetWidgetColor(widget->color, textWidget->color);
+ GetTextFontSize(widget->fontSize, textWidget->fontSize);
+ GetTextString(text, textWidget->text);
+
+ ++(*widgetCounts)[WidgetInternalType::Text];
+}
+
+void AppendWidgetDataHelper::AppendGraphCommon(const overlay::Widget *widget,
+ const gl::Extents &imageExtent,
+ const std::vector<uint64_t> runningValues,
+ size_t startIndex,
+ float scale,
+ GraphWidgetData *graphWidget,
+ OverlayWidgetCounts *widgetCounts)
+{
+ const overlay::RunningGraph *widgetAsGraph = static_cast<const overlay::RunningGraph *>(widget);
+
+ GetWidgetCoordinates(widget->coords, imageExtent, graphWidget->coordinates);
+ GetWidgetColor(widget->color, graphWidget->color);
+ GetGraphValueWidth(widget->coords, widgetAsGraph->runningValues.size(),
+ &graphWidget->valueWidth);
+ GetGraphValues(runningValues, startIndex, scale, graphWidget->values);
+
+ ++(*widgetCounts)[WidgetInternalType::Graph];
+}
+
+void AppendWidgetDataHelper::AppendRunningGraphCommon(
+ const overlay::Widget *widget,
+ const gl::Extents &imageExtent,
+ TextWidgetData *textWidget,
+ GraphWidgetData *graphWidget,
+ OverlayWidgetCounts *widgetCounts,
+ AppendWidgetDataHelper::FormatGraphTitleFunc formatFunc)
+{
+ const overlay::RunningGraph *graph = static_cast<const overlay::RunningGraph *>(widget);
+ const overlay::Widget *matchToWidget = widget->matchToWidget;
+
+ if (matchToWidget == nullptr)
+ {
+ matchToWidget = widget;
+ }
+ const overlay::RunningGraph *matchToGraph =
+ static_cast<const overlay::RunningGraph *>(matchToWidget);
+
+ const uint64_t maxValue =
+ *std::max_element(graph->runningValues.begin(), graph->runningValues.end());
+ const uint64_t maxValueInMatchToGraph =
+ *std::max_element(matchToGraph->runningValues.begin(), matchToGraph->runningValues.end());
+ const int32_t graphHeight = std::abs(widget->coords[3] - widget->coords[1]);
+ const float graphScale = static_cast<float>(graphHeight) / maxValueInMatchToGraph;
+
+ const size_t graphSize = graph->runningValues.size();
+ const size_t currentIdx = graph->lastValueIndex - 1;
+
+ const uint64_t curValue = graph->runningValues[(graphSize + currentIdx) % graphSize];
+
+ AppendGraphCommon(widget, imageExtent, graph->runningValues, graph->lastValueIndex + 1,
+ graphScale, graphWidget, widgetCounts);
+
+ if ((*widgetCounts)[WidgetInternalType::Text] <
+ kWidgetInternalTypeMaxWidgets[WidgetInternalType::Text])
+ {
+ std::string text = formatFunc(curValue, maxValue);
+ AppendTextCommon(&graph->description, imageExtent, text, textWidget, widgetCounts);
+ }
+}
+
+// static
+void AppendWidgetDataHelper::AppendRunningHistogramCommon(const overlay::Widget *widget,
+ const gl::Extents &imageExtent,
+ TextWidgetData *textWidget,
+ GraphWidgetData *graphWidget,
+ OverlayWidgetCounts *widgetCounts,
+ FormatHistogramTitleFunc formatFunc)
+{
+ const overlay::RunningHistogram *runningHistogram =
+ static_cast<const overlay::RunningHistogram *>(widget);
+
+ std::vector<uint64_t> histogram = CreateHistogram(runningHistogram->runningValues);
+ auto peakRangeIt = std::max_element(histogram.rbegin(), histogram.rend());
+ const uint64_t peakRangeValue = *peakRangeIt;
+ const int32_t graphHeight = std::abs(widget->coords[3] - widget->coords[1]);
+ const float graphScale = static_cast<float>(graphHeight) / peakRangeValue;
+ auto maxValueIter = std::find_if(histogram.rbegin(), histogram.rend(),
+ [](uint64_t value) { return value != 0; });
+
+ AppendGraphCommon(widget, imageExtent, histogram, 0, graphScale, graphWidget, widgetCounts);
+
+ if ((*widgetCounts)[WidgetInternalType::Text] <
+ kWidgetInternalTypeMaxWidgets[WidgetInternalType::Text])
+ {
+ size_t peakRange = std::distance(peakRangeIt, histogram.rend() - 1);
+ size_t maxValueRange = std::distance(maxValueIter, histogram.rend() - 1);
+
+ std::string text = formatFunc(peakRange, maxValueRange, histogram.size());
+ AppendTextCommon(&runningHistogram->description, imageExtent, text, textWidget,
+ widgetCounts);
+ }
+}
+
+void AppendWidgetDataHelper::AppendFPS(const overlay::Widget *widget,
+ const gl::Extents &imageExtent,
+ TextWidgetData *textWidget,
+ GraphWidgetData *graphWidget,
+ OverlayWidgetCounts *widgetCounts)
+{
+ const overlay::PerSecond *fps = static_cast<const overlay::PerSecond *>(widget);
+ std::ostringstream text;
+ text << "FPS: ";
+ OutputPerSecond(text, fps);
+
+ AppendTextCommon(widget, imageExtent, text.str(), textWidget, widgetCounts);
+}
+
+void AppendWidgetDataHelper::AppendVulkanLastValidationMessage(const overlay::Widget *widget,
+ const gl::Extents &imageExtent,
+ TextWidgetData *textWidget,
+ GraphWidgetData *graphWidget,
+ OverlayWidgetCounts *widgetCounts)
+{
+ const overlay::Text *lastValidationMessage = static_cast<const overlay::Text *>(widget);
+ std::ostringstream text;
+ text << "Last VVL Message: ";
+ OutputText(text, lastValidationMessage);
+
+ AppendTextCommon(widget, imageExtent, text.str(), textWidget, widgetCounts);
+}
+
+void AppendWidgetDataHelper::AppendVulkanValidationMessageCount(const overlay::Widget *widget,
+ const gl::Extents &imageExtent,
+ TextWidgetData *textWidget,
+ GraphWidgetData *graphWidget,
+ OverlayWidgetCounts *widgetCounts)
+{
+ const overlay::Count *validationMessageCount = static_cast<const overlay::Count *>(widget);
+ std::ostringstream text;
+ text << "VVL Message Count: ";
+ OutputCount(text, validationMessageCount);
+
+ AppendTextCommon(widget, imageExtent, text.str(), textWidget, widgetCounts);
+}
+
+void AppendWidgetDataHelper::AppendVulkanRenderPassCount(const overlay::Widget *widget,
+ const gl::Extents &imageExtent,
+ TextWidgetData *textWidget,
+ GraphWidgetData *graphWidget,
+ OverlayWidgetCounts *widgetCounts)
+{
+ auto format = [](uint64_t curValue, uint64_t maxValue) {
+ std::ostringstream text;
+ text << "RenderPass Count: " << maxValue;
+ return text.str();
+ };
+
+ AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
+}
+
+void AppendWidgetDataHelper::AppendVulkanSecondaryCommandBufferPoolWaste(
+ const overlay::Widget *widget,
+ const gl::Extents &imageExtent,
+ TextWidgetData *textWidget,
+ GraphWidgetData *graphWidget,
+ OverlayWidgetCounts *widgetCounts)
+{
+ auto format = [](size_t peakRange, size_t maxValueRange, size_t numRanges) {
+ std::ostringstream text;
+ size_t peakPercent = (peakRange * 100 + 50) / numRanges;
+ text << "CB Pool Waste (Peak: " << peakPercent << "%)";
+ return text.str();
+ };
+
+ AppendRunningHistogramCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts,
+ format);
+}
+
+void AppendWidgetDataHelper::AppendVulkanRenderPassBufferCount(const overlay::Widget *widget,
+ const gl::Extents &imageExtent,
+ TextWidgetData *textWidget,
+ GraphWidgetData *graphWidget,
+ OverlayWidgetCounts *widgetCounts)
+{
+ auto format = [](uint64_t curValue, uint64_t maxValue) {
+ std::ostringstream text;
+ text << "RP VkBuffers (Max: " << maxValue << ")";
+ return text.str();
+ };
+
+ AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
+}
+
+void AppendWidgetDataHelper::AppendVulkanWriteDescriptorSetCount(const overlay::Widget *widget,
+ const gl::Extents &imageExtent,
+ TextWidgetData *textWidget,
+ GraphWidgetData *graphWidget,
+ OverlayWidgetCounts *widgetCounts)
+{
+ auto format = [](uint64_t curValue, uint64_t maxValue) {
+ std::ostringstream text;
+ text << "WriteDescriptorSet Count: " << maxValue;
+ return text.str();
+ };
+
+ AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
+}
+
+void AppendWidgetDataHelper::AppendVulkanDescriptorSetAllocations(const overlay::Widget *widget,
+ const gl::Extents &imageExtent,
+ TextWidgetData *textWidget,
+ GraphWidgetData *graphWidget,
+ OverlayWidgetCounts *widgetCounts)
+{
+ auto format = [](uint64_t curValue, uint64_t maxValue) {
+ std::ostringstream text;
+ text << "Descriptor Set Allocations: " << maxValue;
+ return text.str();
+ };
+
+ AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
+}
+
+void AppendWidgetDataHelper::AppendVulkanShaderResourceDSHitRate(const overlay::Widget *widget,
+ const gl::Extents &imageExtent,
+ TextWidgetData *textWidget,
+ GraphWidgetData *graphWidget,
+ OverlayWidgetCounts *widgetCounts)
+{
+ auto format = [](uint64_t curValue, uint64_t maxValue) {
+ std::ostringstream text;
+ text << "Shader Resource DS Hit Rate (Max: " << maxValue << "%)";
+ return text.str();
+ };
+
+ AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
+}
+
+void AppendWidgetDataHelper::AppendVulkanDynamicBufferAllocations(const overlay::Widget *widget,
+ const gl::Extents &imageExtent,
+ TextWidgetData *textWidget,
+ GraphWidgetData *graphWidget,
+ OverlayWidgetCounts *widgetCounts)
+{
+ auto format = [](uint64_t curValue, uint64_t maxValue) {
+ std::ostringstream text;
+ text << "DynamicBuffer Allocations (Max: " << maxValue << ")";
+ return text.str();
+ };
+
+ AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
+}
+
+void AppendWidgetDataHelper::AppendVulkanTextureDescriptorCacheSize(
+ const overlay::Widget *widget,
+ const gl::Extents &imageExtent,
+ TextWidgetData *textWidget,
+ GraphWidgetData *graphWidget,
+ OverlayWidgetCounts *widgetCounts)
+{
+ auto format = [](uint64_t curValue, uint64_t maxValue) {
+ std::ostringstream text;
+ text << "Total Texture Descriptor Cache Size: " << curValue;
+ return text.str();
+ };
+
+ AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
+}
+
+void AppendWidgetDataHelper::AppendVulkanUniformDescriptorCacheSize(
+ const overlay::Widget *widget,
+ const gl::Extents &imageExtent,
+ TextWidgetData *textWidget,
+ GraphWidgetData *graphWidget,
+ OverlayWidgetCounts *widgetCounts)
+{
+ auto format = [](uint64_t curValue, uint64_t maxValue) {
+ std::ostringstream text;
+ text << "Total Uniform Descriptor Cache Size: " << curValue;
+ return text.str();
+ };
+
+ AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
+}
+
+void AppendWidgetDataHelper::AppendVulkanDescriptorCacheSize(const overlay::Widget *widget,
+ const gl::Extents &imageExtent,
+ TextWidgetData *textWidget,
+ GraphWidgetData *graphWidget,
+ OverlayWidgetCounts *widgetCounts)
+{
+ auto format = [](uint64_t curValue, uint64_t maxValue) {
+ std::ostringstream text;
+ text << "Total Descriptor Cache Size: " << curValue;
+ return text.str();
+ };
+
+ AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
+}
+
+void AppendWidgetDataHelper::AppendVulkanDescriptorCacheKeySize(const overlay::Widget *widget,
+ const gl::Extents &imageExtent,
+ TextWidgetData *textWidget,
+ GraphWidgetData *graphWidget,
+ OverlayWidgetCounts *widgetCounts)
+{
+ const overlay::Count *countWidget = static_cast<const overlay::Count *>(widget);
+ std::ostringstream text;
+ double kb = static_cast<double>(countWidget->count) / 1000.0;
+ text << "DS Cache Key Size: " << std::fixed << std::setprecision(1) << kb << " kb";
+
+ AppendTextCommon(widget, imageExtent, text.str(), textWidget, widgetCounts);
+}
+
+void AppendWidgetDataHelper::AppendVulkanAttemptedSubmissions(const overlay::Widget *widget,
+ const gl::Extents &imageExtent,
+ TextWidgetData *textWidget,
+ GraphWidgetData *graphWidget,
+ OverlayWidgetCounts *widgetCounts)
+{
+ auto format = [](uint64_t curValue, uint64_t maxValue) {
+ std::ostringstream text;
+ text << "Attempted submissions (peak): " << maxValue;
+ return text.str();
+ };
+
+ AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
+}
+
+void AppendWidgetDataHelper::AppendVulkanActualSubmissions(const overlay::Widget *widget,
+ const gl::Extents &imageExtent,
+ TextWidgetData *textWidget,
+ GraphWidgetData *graphWidget,
+ OverlayWidgetCounts *widgetCounts)
+{
+ auto format = [](uint64_t curValue, uint64_t maxValue) {
+ std::ostringstream text;
+ text << "Actual submissions (peak): " << maxValue;
+ return text.str();
+ };
+
+ AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
+}
+
+void AppendWidgetDataHelper::AppendVulkanPipelineCacheLookups(const overlay::Widget *widget,
+ const gl::Extents &imageExtent,
+ TextWidgetData *textWidget,
+ GraphWidgetData *graphWidget,
+ OverlayWidgetCounts *widgetCounts)
+{
+ auto format = [](uint64_t curValue, uint64_t maxValue) {
+ std::ostringstream text;
+ text << "Pipeline Cache Lookups (peak): " << maxValue;
+ return text.str();
+ };
+
+ AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
+}
+
+void AppendWidgetDataHelper::AppendVulkanPipelineCacheMisses(const overlay::Widget *widget,
+ const gl::Extents &imageExtent,
+ TextWidgetData *textWidget,
+ GraphWidgetData *graphWidget,
+ OverlayWidgetCounts *widgetCounts)
+{
+ auto format = [](uint64_t curValue, uint64_t maxValue) {
+ std::ostringstream text;
+ text << "Pipeline Cache Misses (peak): " << maxValue;
+ return text.str();
+ };
+
+ AppendRunningGraphCommon(widget, imageExtent, textWidget, graphWidget, widgetCounts, format);
+}
+
+void AppendWidgetDataHelper::AppendVulkanTotalPipelineCacheHitTimeMs(
+ const overlay::Widget *widget,
+ const gl::Extents &imageExtent,
+ TextWidgetData *textWidget,
+ GraphWidgetData *graphWidget,
+ OverlayWidgetCounts *widgetCounts)
+{
+ const overlay::Count *totalTime = static_cast<const overlay::Count *>(widget);
+ std::ostringstream text;
+ text << "Total Pipeline Cache Hit Time: ";
+ OutputCount(text, totalTime);
+ text << "ms";
+
+ AppendTextCommon(widget, imageExtent, text.str(), textWidget, widgetCounts);
+}
+
+void AppendWidgetDataHelper::AppendVulkanTotalPipelineCacheMissTimeMs(
+ const overlay::Widget *widget,
+ const gl::Extents &imageExtent,
+ TextWidgetData *textWidget,
+ GraphWidgetData *graphWidget,
+ OverlayWidgetCounts *widgetCounts)
+{
+ const overlay::Count *totalTime = static_cast<const overlay::Count *>(widget);
+ std::ostringstream text;
+ text << "Total Pipeline Cache Miss Time: ";
+ OutputCount(text, totalTime);
+ text << "ms";
+
+ AppendTextCommon(widget, imageExtent, text.str(), textWidget, widgetCounts);
+}
+
+std::ostream &AppendWidgetDataHelper::OutputPerSecond(std::ostream &out,
+ const overlay::PerSecond *perSecond)
+{
+ return out << perSecond->lastPerSecondCount;
+}
+
+std::ostream &AppendWidgetDataHelper::OutputText(std::ostream &out, const overlay::Text *text)
+{
+ return out << text->text;
+}
+
+std::ostream &AppendWidgetDataHelper::OutputCount(std::ostream &out, const overlay::Count *count)
+{
+ return out << count->count;
+}
+} // namespace overlay_impl
+
+namespace
+{
+#define ANGLE_APPEND_WIDGET_MAP_PROC(WIDGET_ID) \
+ {WidgetId::WIDGET_ID, overlay_impl::AppendWidgetDataHelper::Append##WIDGET_ID},
+
+constexpr angle::PackedEnumMap<WidgetId, AppendWidgetDataFunc> kWidgetIdToAppendDataFuncMap = {
+ ANGLE_WIDGET_ID_X(ANGLE_APPEND_WIDGET_MAP_PROC)};
+} // namespace
+
+namespace overlay
+{
+const Text *Widget::getDescriptionWidget() const
+{
+ return nullptr;
+}
+RunningGraph::RunningGraph(size_t n) : runningValues(n, 0) {}
+RunningGraph::~RunningGraph() = default;
+const Text *RunningGraph::getDescriptionWidget() const
+{
+ return &description;
+}
+} // namespace overlay
+
+size_t OverlayState::getWidgetCoordinatesBufferSize() const
+{
+ return sizeof(WidgetCoordinates);
+}
+
+size_t OverlayState::getTextWidgetsBufferSize() const
+{
+ return sizeof(TextWidgets);
+}
+
+size_t OverlayState::getGraphWidgetsBufferSize() const
+{
+ return sizeof(GraphWidgets);
+}
+
+void OverlayState::fillWidgetData(const gl::Extents &imageExtents,
+ uint8_t *textData,
+ uint8_t *graphData,
+ uint32_t *activeTextWidgetCountOut,
+ uint32_t *activeGraphWidgetCountOut) const
+{
+ TextWidgets *textWidgets = reinterpret_cast<TextWidgets *>(textData);
+ GraphWidgets *graphWidgets = reinterpret_cast<GraphWidgets *>(graphData);
+
+ memset(textWidgets, overlay::kFontCharacters, sizeof(*textWidgets));
+ memset(graphWidgets, 0, sizeof(*graphWidgets));
+
+ OverlayWidgetCounts widgetCounts = {};
+
+ for (WidgetId id : angle::AllEnums<WidgetId>())
+ {
+ const std::unique_ptr<overlay::Widget> &widget = mOverlayWidgets[id];
+ if (!widget->enabled)
+ {
+ continue;
+ }
+
+ WidgetInternalType internalType = kWidgetTypeToInternalMap[widget->type];
+ ASSERT(internalType != WidgetInternalType::InvalidEnum);
+
+ if (widgetCounts[internalType] >= kWidgetInternalTypeMaxWidgets[internalType])
+ {
+ continue;
+ }
+
+ AppendWidgetDataFunc appendFunc = kWidgetIdToAppendDataFuncMap[id];
+ ASSERT(appendFunc);
+ appendFunc(widget.get(), imageExtents,
+ &textWidgets->widgets[widgetCounts[WidgetInternalType::Text]],
+ &graphWidgets->widgets[widgetCounts[WidgetInternalType::Graph]], &widgetCounts);
+ }
+
+ *activeTextWidgetCountOut = widgetCounts[WidgetInternalType::Text];
+ *activeGraphWidgetCountOut = widgetCounts[WidgetInternalType::Graph];
+}
+
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/OverlayWidgets.h b/gfx/angle/checkout/src/libANGLE/OverlayWidgets.h
new file mode 100644
index 0000000000..b8a5f01e52
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/OverlayWidgets.h
@@ -0,0 +1,201 @@
+//
+// Copyright 2019 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.
+//
+// OverlayWidgets.h:
+// Defines the Overlay* widget classes and corresponding enums.
+//
+
+#ifndef LIBANGLE_OVERLAYWIDGETS_H_
+#define LIBANGLE_OVERLAYWIDGETS_H_
+
+#include "common/angleutils.h"
+#include "libANGLE/Overlay_autogen.h"
+
+namespace gl
+{
+class Overlay;
+class OverlayState;
+
+namespace overlay_impl
+{
+class AppendWidgetDataHelper;
+} // namespace overlay_impl
+
+enum class WidgetType
+{
+ // Text types:
+
+ // A total count of some event.
+ Count,
+ // A single line of ASCII text. Retains content until changed.
+ Text,
+ // A per-second value.
+ PerSecond,
+
+ // Graph types:
+
+ // A graph of the last N values.
+ RunningGraph,
+ // A histogram of the last N values (values between 0 and 1).
+ RunningHistogram,
+
+ InvalidEnum,
+ EnumCount = InvalidEnum,
+};
+
+namespace overlay
+{
+class Text;
+class Widget
+{
+ public:
+ virtual ~Widget() {}
+
+ virtual const Text *getDescriptionWidget() const;
+
+ protected:
+ WidgetType type;
+ // Whether this item should be drawn.
+ bool enabled = false;
+
+ // For text items, size of the font. This is a value in [0, overlay::kFontMipCount) which
+ // determines the font size to use.
+ int fontSize;
+
+ // The area covered by the item, predetermined by the overlay class. Negative values
+ // indicate offset from the left/bottom of the image.
+ int32_t coords[4];
+ float color[4];
+
+ // In some cases, a widget may need to match its contents (e.g. graph height scaling) with
+ // another related widget. In such a case, this pointer will point to the widget it needs to
+ // match to.
+ Widget *matchToWidget;
+
+ friend class gl::Overlay;
+ friend class gl::OverlayState;
+ friend class overlay_impl::AppendWidgetDataHelper;
+};
+
+class Count : public Widget
+{
+ public:
+ ~Count() override {}
+ void add(uint64_t n) { count += n; }
+ void set(uint64_t n) { count = n; }
+ void reset() { count = 0; }
+
+ protected:
+ uint64_t count = 0;
+
+ friend class gl::Overlay;
+ friend class overlay_impl::AppendWidgetDataHelper;
+};
+
+class PerSecond : public Count
+{
+ public:
+ ~PerSecond() override {}
+
+ protected:
+ uint64_t lastPerSecondCount = 0;
+
+ friend class gl::Overlay;
+ friend class overlay_impl::AppendWidgetDataHelper;
+};
+
+class Text : public Widget
+{
+ public:
+ ~Text() override {}
+ void set(std::string &&str) { text = std::move(str); }
+
+ protected:
+ std::string text;
+
+ friend class overlay_impl::AppendWidgetDataHelper;
+};
+
+class RunningGraph : public Widget
+{
+ public:
+ // Out of line constructor to satisfy chromium-style.
+ RunningGraph(size_t n);
+ ~RunningGraph() override;
+
+ void add(uint64_t n)
+ {
+ if (!ignoreFirstValue)
+ {
+ runningValues[lastValueIndex] += n;
+ }
+ }
+
+ void next()
+ {
+ if (ignoreFirstValue)
+ {
+ ignoreFirstValue = false;
+ }
+ else
+ {
+ lastValueIndex = (lastValueIndex + 1) % runningValues.size();
+ runningValues[lastValueIndex] = 0;
+ }
+ }
+
+ const Text *getDescriptionWidget() const override;
+
+ protected:
+ std::vector<uint64_t> runningValues;
+ size_t lastValueIndex = 0;
+ Text description;
+ bool ignoreFirstValue = true;
+
+ friend class gl::Overlay;
+ friend class gl::OverlayState;
+ friend class overlay_impl::AppendWidgetDataHelper;
+};
+
+class RunningHistogram : public RunningGraph
+{
+ public:
+ RunningHistogram(size_t n) : RunningGraph(n) {}
+ ~RunningHistogram() override {}
+
+ void set(float n)
+ {
+ ASSERT(n >= 0.0f && n <= 1.0f);
+ uint64_t rank =
+ n == 1.0f ? runningValues.size() - 1 : static_cast<uint64_t>(n * runningValues.size());
+
+ runningValues[lastValueIndex] = rank;
+ }
+
+ private:
+ // Do not use the add() function from RunningGraph
+ using RunningGraph::add;
+};
+
+// If overlay is disabled, all the above classes would be replaced with Mock, turning them into
+// noop.
+class Mock
+{
+ public:
+ void reset() const {}
+ template <typename T>
+ void set(T) const
+ {}
+ template <typename T>
+ void add(T) const
+ {}
+ void next() const {}
+};
+
+} // namespace overlay
+
+} // namespace gl
+
+#endif // LIBANGLE_OVERLAYWIDGETS_H_
diff --git a/gfx/angle/checkout/src/libANGLE/Overlay_autogen.cpp b/gfx/angle/checkout/src/libANGLE/Overlay_autogen.cpp
new file mode 100644
index 0000000000..eb2a146188
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Overlay_autogen.cpp
@@ -0,0 +1,824 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_overlay_widgets.py using data from overlay_widgets.json.
+//
+// Copyright 2019 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.
+//
+// Overlay_autogen.cpp:
+// Autogenerated overlay widget declarations.
+
+#include "libANGLE/Overlay.h"
+#include "libANGLE/OverlayWidgets.h"
+#include "libANGLE/Overlay_font_autogen.h"
+#include "libANGLE/renderer/driver_utils.h"
+
+namespace gl
+{
+using namespace overlay;
+
+namespace
+{
+int GetFontSize(int fontSize, bool largeFont)
+{
+ if (largeFont && fontSize > 0)
+ {
+ return fontSize - 1;
+ }
+ return fontSize;
+}
+} // anonymous namespace
+
+void Overlay::initOverlayWidgets()
+{
+ const bool kLargeFont = rx::IsAndroid();
+
+ {
+ PerSecond *widget = new PerSecond;
+ {
+ const int32_t fontSize = GetFontSize(kFontMipLarge, kLargeFont);
+ const int32_t offsetX = 10;
+ const int32_t offsetY = 10;
+ const int32_t width = 12 * (kFontGlyphWidth >> fontSize);
+ const int32_t height = (kFontGlyphHeight >> fontSize);
+
+ widget->type = WidgetType::PerSecond;
+ widget->fontSize = fontSize;
+ widget->coords[0] = offsetX;
+ widget->coords[1] = offsetY;
+ widget->coords[2] = offsetX + width;
+ widget->coords[3] = offsetY + height;
+ widget->color[0] = 0.4980392156862745f;
+ widget->color[1] = 0.7490196078431373f;
+ widget->color[2] = 1.0f;
+ widget->color[3] = 1.0f;
+ widget->matchToWidget = nullptr;
+ }
+ mState.mOverlayWidgets[WidgetId::FPS].reset(widget);
+ }
+
+ {
+ Text *widget = new Text;
+ {
+ const int32_t fontSize = GetFontSize(kFontMipSmall, kLargeFont);
+ const int32_t offsetX = 10;
+ const int32_t offsetY = -10;
+ const int32_t width = 150 * (kFontGlyphWidth >> fontSize);
+ const int32_t height = (kFontGlyphHeight >> fontSize);
+
+ widget->type = WidgetType::Text;
+ widget->fontSize = fontSize;
+ widget->coords[0] = offsetX;
+ widget->coords[1] = offsetY - height;
+ widget->coords[2] = offsetX + width;
+ widget->coords[3] = offsetY;
+ widget->color[0] = 1.0f;
+ widget->color[1] = 0.0f;
+ widget->color[2] = 0.0f;
+ widget->color[3] = 1.0f;
+ widget->matchToWidget = nullptr;
+ }
+ mState.mOverlayWidgets[WidgetId::VulkanLastValidationMessage].reset(widget);
+ }
+
+ {
+ Count *widget = new Count;
+ {
+ const int32_t fontSize = GetFontSize(kFontMipSmall, kLargeFont);
+ const int32_t offsetX = 10;
+ const int32_t offsetY =
+ mState.mOverlayWidgets[WidgetId::VulkanLastValidationMessage]->coords[1];
+ const int32_t width = 25 * (kFontGlyphWidth >> fontSize);
+ const int32_t height = (kFontGlyphHeight >> fontSize);
+
+ widget->type = WidgetType::Count;
+ widget->fontSize = fontSize;
+ widget->coords[0] = offsetX;
+ widget->coords[1] = offsetY - height;
+ widget->coords[2] = offsetX + width;
+ widget->coords[3] = offsetY;
+ widget->color[0] = 1.0f;
+ widget->color[1] = 0.0f;
+ widget->color[2] = 0.0f;
+ widget->color[3] = 1.0f;
+ widget->matchToWidget = nullptr;
+ }
+ mState.mOverlayWidgets[WidgetId::VulkanValidationMessageCount].reset(widget);
+ }
+
+ {
+ RunningGraph *widget = new RunningGraph(60);
+ {
+ const int32_t fontSize = GetFontSize(0, kLargeFont);
+ const int32_t offsetX = 10;
+ const int32_t offsetY = 100;
+ const int32_t width = 5 * static_cast<uint32_t>(widget->runningValues.size());
+ const int32_t height = 100;
+
+ widget->type = WidgetType::RunningGraph;
+ widget->fontSize = fontSize;
+ widget->coords[0] = offsetX;
+ widget->coords[1] = offsetY;
+ widget->coords[2] = offsetX + width;
+ widget->coords[3] = offsetY + height;
+ widget->color[0] = 0.29411764705882354f;
+ widget->color[1] = 0.7843137254901961f;
+ widget->color[2] = 0.0f;
+ widget->color[3] = 0.7843137254901961f;
+ widget->matchToWidget = nullptr;
+ }
+ mState.mOverlayWidgets[WidgetId::VulkanRenderPassCount].reset(widget);
+ {
+ const int32_t fontSize = GetFontSize(kFontMipSmall, kLargeFont);
+ const int32_t offsetX =
+ mState.mOverlayWidgets[WidgetId::VulkanRenderPassCount]->coords[0];
+ const int32_t offsetY =
+ mState.mOverlayWidgets[WidgetId::VulkanRenderPassCount]->coords[1];
+ const int32_t width = 40 * (kFontGlyphWidth >> fontSize);
+ const int32_t height = (kFontGlyphHeight >> fontSize);
+
+ widget->description.type = WidgetType::Text;
+ widget->description.fontSize = fontSize;
+ widget->description.coords[0] = offsetX;
+ widget->description.coords[1] = std::max(offsetY - height, 1);
+ widget->description.coords[2] = offsetX + width;
+ widget->description.coords[3] = offsetY;
+ widget->description.color[0] = 0.29411764705882354f;
+ widget->description.color[1] = 0.7843137254901961f;
+ widget->description.color[2] = 0.0f;
+ widget->description.color[3] = 1.0f;
+ widget->description.matchToWidget = nullptr;
+ }
+ }
+
+ {
+ RunningGraph *widget = new RunningGraph(100);
+ {
+ const int32_t fontSize = GetFontSize(0, kLargeFont);
+ const int32_t offsetX = -50;
+ const int32_t offsetY = 100;
+ const int32_t width = 6 * static_cast<uint32_t>(widget->runningValues.size());
+ const int32_t height = 100;
+
+ widget->type = WidgetType::RunningGraph;
+ widget->fontSize = fontSize;
+ widget->coords[0] = offsetX - width;
+ widget->coords[1] = offsetY;
+ widget->coords[2] = offsetX;
+ widget->coords[3] = offsetY + height;
+ widget->color[0] = 1.0f;
+ widget->color[1] = 0.7843137254901961f;
+ widget->color[2] = 0.29411764705882354f;
+ widget->color[3] = 0.7843137254901961f;
+ widget->matchToWidget = nullptr;
+ }
+ mState.mOverlayWidgets[WidgetId::VulkanRenderPassBufferCount].reset(widget);
+ {
+ const int32_t fontSize = GetFontSize(kFontMipSmall, kLargeFont);
+ const int32_t offsetX =
+ mState.mOverlayWidgets[WidgetId::VulkanRenderPassBufferCount]->coords[0];
+ const int32_t offsetY =
+ mState.mOverlayWidgets[WidgetId::VulkanRenderPassBufferCount]->coords[1];
+ const int32_t width = 40 * (kFontGlyphWidth >> fontSize);
+ const int32_t height = (kFontGlyphHeight >> fontSize);
+
+ widget->description.type = WidgetType::Text;
+ widget->description.fontSize = fontSize;
+ widget->description.coords[0] = offsetX;
+ widget->description.coords[1] = std::max(offsetY - height, 1);
+ widget->description.coords[2] = std::min(offsetX + width, -1);
+ widget->description.coords[3] = offsetY;
+ widget->description.color[0] = 1.0f;
+ widget->description.color[1] = 0.7843137254901961f;
+ widget->description.color[2] = 0.29411764705882354f;
+ widget->description.color[3] = 1.0f;
+ widget->description.matchToWidget = nullptr;
+ }
+ }
+
+ {
+ RunningHistogram *widget = new RunningHistogram(50);
+ {
+ const int32_t fontSize = GetFontSize(0, kLargeFont);
+ const int32_t offsetX = -50;
+ const int32_t offsetY = 100;
+ const int32_t width = 6 * static_cast<uint32_t>(widget->runningValues.size());
+ const int32_t height = 100;
+
+ widget->type = WidgetType::RunningHistogram;
+ widget->fontSize = fontSize;
+ widget->coords[0] = offsetX - width;
+ widget->coords[1] = offsetY;
+ widget->coords[2] = offsetX;
+ widget->coords[3] = offsetY + height;
+ widget->color[0] = 1.0f;
+ widget->color[1] = 0.7843137254901961f;
+ widget->color[2] = 0.29411764705882354f;
+ widget->color[3] = 0.7843137254901961f;
+ widget->matchToWidget = nullptr;
+ }
+ mState.mOverlayWidgets[WidgetId::VulkanSecondaryCommandBufferPoolWaste].reset(widget);
+ {
+ const int32_t fontSize = GetFontSize(kFontMipSmall, kLargeFont);
+ const int32_t offsetX =
+ mState.mOverlayWidgets[WidgetId::VulkanSecondaryCommandBufferPoolWaste]->coords[0];
+ const int32_t offsetY =
+ mState.mOverlayWidgets[WidgetId::VulkanSecondaryCommandBufferPoolWaste]->coords[1];
+ const int32_t width = 40 * (kFontGlyphWidth >> fontSize);
+ const int32_t height = (kFontGlyphHeight >> fontSize);
+
+ widget->description.type = WidgetType::Text;
+ widget->description.fontSize = fontSize;
+ widget->description.coords[0] = offsetX;
+ widget->description.coords[1] = std::max(offsetY - height, 1);
+ widget->description.coords[2] = std::min(offsetX + width, -1);
+ widget->description.coords[3] = offsetY;
+ widget->description.color[0] = 1.0f;
+ widget->description.color[1] = 0.7843137254901961f;
+ widget->description.color[2] = 0.29411764705882354f;
+ widget->description.color[3] = 1.0f;
+ widget->description.matchToWidget = nullptr;
+ }
+ }
+
+ {
+ RunningGraph *widget = new RunningGraph(60);
+ {
+ const int32_t fontSize = GetFontSize(0, kLargeFont);
+ const int32_t offsetX = 10;
+ const int32_t offsetY = 220;
+ const int32_t width = 5 * static_cast<uint32_t>(widget->runningValues.size());
+ const int32_t height = 100;
+
+ widget->type = WidgetType::RunningGraph;
+ widget->fontSize = fontSize;
+ widget->coords[0] = offsetX;
+ widget->coords[1] = offsetY;
+ widget->coords[2] = offsetX + width;
+ widget->coords[3] = offsetY + height;
+ widget->color[0] = 0.29411764705882354f;
+ widget->color[1] = 0.7843137254901961f;
+ widget->color[2] = 0.0f;
+ widget->color[3] = 0.7843137254901961f;
+ widget->matchToWidget = nullptr;
+ }
+ mState.mOverlayWidgets[WidgetId::VulkanWriteDescriptorSetCount].reset(widget);
+ {
+ const int32_t fontSize = GetFontSize(kFontMipSmall, kLargeFont);
+ const int32_t offsetX =
+ mState.mOverlayWidgets[WidgetId::VulkanWriteDescriptorSetCount]->coords[0];
+ const int32_t offsetY =
+ mState.mOverlayWidgets[WidgetId::VulkanWriteDescriptorSetCount]->coords[1];
+ const int32_t width = 40 * (kFontGlyphWidth >> fontSize);
+ const int32_t height = (kFontGlyphHeight >> fontSize);
+
+ widget->description.type = WidgetType::Text;
+ widget->description.fontSize = fontSize;
+ widget->description.coords[0] = offsetX;
+ widget->description.coords[1] = std::max(offsetY - height, 1);
+ widget->description.coords[2] = offsetX + width;
+ widget->description.coords[3] = offsetY;
+ widget->description.color[0] = 0.29411764705882354f;
+ widget->description.color[1] = 0.7843137254901961f;
+ widget->description.color[2] = 0.0f;
+ widget->description.color[3] = 1.0f;
+ widget->description.matchToWidget = nullptr;
+ }
+ }
+
+ {
+ RunningGraph *widget = new RunningGraph(60);
+ {
+ const int32_t fontSize = GetFontSize(0, kLargeFont);
+ const int32_t offsetX = 0;
+ const int32_t offsetY = 250;
+ const int32_t width = 6 * static_cast<uint32_t>(widget->runningValues.size());
+ const int32_t height = 100;
+
+ widget->type = WidgetType::RunningGraph;
+ widget->fontSize = fontSize;
+ widget->coords[0] = offsetX;
+ widget->coords[1] = offsetY;
+ widget->coords[2] = offsetX + width;
+ widget->coords[3] = offsetY + height;
+ widget->color[0] = 1.0f;
+ widget->color[1] = 0.0f;
+ widget->color[2] = 0.29411764705882354f;
+ widget->color[3] = 0.7843137254901961f;
+ widget->matchToWidget = nullptr;
+ }
+ mState.mOverlayWidgets[WidgetId::VulkanDescriptorSetAllocations].reset(widget);
+ {
+ const int32_t fontSize = GetFontSize(kFontMipSmall, kLargeFont);
+ const int32_t offsetX =
+ mState.mOverlayWidgets[WidgetId::VulkanDescriptorSetAllocations]->coords[0];
+ const int32_t offsetY =
+ mState.mOverlayWidgets[WidgetId::VulkanDescriptorSetAllocations]->coords[1];
+ const int32_t width = 40 * (kFontGlyphWidth >> fontSize);
+ const int32_t height = (kFontGlyphHeight >> fontSize);
+
+ widget->description.type = WidgetType::Text;
+ widget->description.fontSize = fontSize;
+ widget->description.coords[0] = offsetX;
+ widget->description.coords[1] = std::max(offsetY - height, 1);
+ widget->description.coords[2] = offsetX + width;
+ widget->description.coords[3] = offsetY;
+ widget->description.color[0] = 1.0f;
+ widget->description.color[1] = 0.0f;
+ widget->description.color[2] = 0.29411764705882354f;
+ widget->description.color[3] = 1.0f;
+ widget->description.matchToWidget = nullptr;
+ }
+ }
+
+ {
+ RunningGraph *widget = new RunningGraph(60);
+ {
+ const int32_t fontSize = GetFontSize(0, kLargeFont);
+ const int32_t offsetX = -50;
+ const int32_t offsetY = 360;
+ const int32_t width = 6 * static_cast<uint32_t>(widget->runningValues.size());
+ const int32_t height = 100;
+
+ widget->type = WidgetType::RunningGraph;
+ widget->fontSize = fontSize;
+ widget->coords[0] = offsetX - width;
+ widget->coords[1] = offsetY;
+ widget->coords[2] = offsetX;
+ widget->coords[3] = offsetY + height;
+ widget->color[0] = 1.0f;
+ widget->color[1] = 0.0f;
+ widget->color[2] = 0.29411764705882354f;
+ widget->color[3] = 0.7843137254901961f;
+ widget->matchToWidget = nullptr;
+ }
+ mState.mOverlayWidgets[WidgetId::VulkanShaderResourceDSHitRate].reset(widget);
+ {
+ const int32_t fontSize = GetFontSize(kFontMipSmall, kLargeFont);
+ const int32_t offsetX =
+ mState.mOverlayWidgets[WidgetId::VulkanShaderResourceDSHitRate]->coords[0];
+ const int32_t offsetY =
+ mState.mOverlayWidgets[WidgetId::VulkanShaderResourceDSHitRate]->coords[1];
+ const int32_t width = 40 * (kFontGlyphWidth >> fontSize);
+ const int32_t height = (kFontGlyphHeight >> fontSize);
+
+ widget->description.type = WidgetType::Text;
+ widget->description.fontSize = fontSize;
+ widget->description.coords[0] = offsetX;
+ widget->description.coords[1] = std::max(offsetY - height, 1);
+ widget->description.coords[2] = std::min(offsetX + width, -1);
+ widget->description.coords[3] = offsetY;
+ widget->description.color[0] = 1.0f;
+ widget->description.color[1] = 0.0f;
+ widget->description.color[2] = 0.29411764705882354f;
+ widget->description.color[3] = 1.0f;
+ widget->description.matchToWidget = nullptr;
+ }
+ }
+
+ {
+ RunningGraph *widget = new RunningGraph(120);
+ {
+ const int32_t fontSize = GetFontSize(0, kLargeFont);
+ const int32_t offsetX = -50;
+ const int32_t offsetY = -50;
+ const int32_t width = 5 * static_cast<uint32_t>(widget->runningValues.size());
+ const int32_t height = 100;
+
+ widget->type = WidgetType::RunningGraph;
+ widget->fontSize = fontSize;
+ widget->coords[0] = offsetX - width;
+ widget->coords[1] = offsetY - height;
+ widget->coords[2] = offsetX;
+ widget->coords[3] = offsetY;
+ widget->color[0] = 0.0f;
+ widget->color[1] = 0.7843137254901961f;
+ widget->color[2] = 0.29411764705882354f;
+ widget->color[3] = 0.7843137254901961f;
+ widget->matchToWidget = nullptr;
+ }
+ mState.mOverlayWidgets[WidgetId::VulkanDynamicBufferAllocations].reset(widget);
+ {
+ const int32_t fontSize = GetFontSize(kFontMipSmall, kLargeFont);
+ const int32_t offsetX =
+ mState.mOverlayWidgets[WidgetId::VulkanDynamicBufferAllocations]->coords[2];
+ const int32_t offsetY =
+ mState.mOverlayWidgets[WidgetId::VulkanDynamicBufferAllocations]->coords[1];
+ const int32_t width = 40 * (kFontGlyphWidth >> fontSize);
+ const int32_t height = (kFontGlyphHeight >> fontSize);
+
+ widget->description.type = WidgetType::Text;
+ widget->description.fontSize = fontSize;
+ widget->description.coords[0] = offsetX - width;
+ widget->description.coords[1] = offsetY - height;
+ widget->description.coords[2] = offsetX;
+ widget->description.coords[3] = offsetY;
+ widget->description.color[0] = 0.0f;
+ widget->description.color[1] = 0.7843137254901961f;
+ widget->description.color[2] = 0.29411764705882354f;
+ widget->description.color[3] = 1.0f;
+ widget->description.matchToWidget = nullptr;
+ }
+ }
+
+ {
+ RunningGraph *widget = new RunningGraph(60);
+ {
+ const int32_t fontSize = GetFontSize(0, kLargeFont);
+ const int32_t offsetX = 0;
+ const int32_t offsetY = 450;
+ const int32_t width = 5 * static_cast<uint32_t>(widget->runningValues.size());
+ const int32_t height = 100;
+
+ widget->type = WidgetType::RunningGraph;
+ widget->fontSize = fontSize;
+ widget->coords[0] = offsetX;
+ widget->coords[1] = offsetY;
+ widget->coords[2] = offsetX + width;
+ widget->coords[3] = offsetY + height;
+ widget->color[0] = 0.0f;
+ widget->color[1] = 0.7843137254901961f;
+ widget->color[2] = 0.7254901960784313f;
+ widget->color[3] = 0.7843137254901961f;
+ widget->matchToWidget = nullptr;
+ }
+ mState.mOverlayWidgets[WidgetId::VulkanDescriptorCacheSize].reset(widget);
+ {
+ const int32_t fontSize = GetFontSize(kFontMipSmall, kLargeFont);
+ const int32_t offsetX =
+ mState.mOverlayWidgets[WidgetId::VulkanDescriptorCacheSize]->coords[0];
+ const int32_t offsetY =
+ mState.mOverlayWidgets[WidgetId::VulkanDescriptorCacheSize]->coords[1];
+ const int32_t width = 90 * (kFontGlyphWidth >> fontSize);
+ const int32_t height = (kFontGlyphHeight >> fontSize);
+
+ widget->description.type = WidgetType::Text;
+ widget->description.fontSize = fontSize;
+ widget->description.coords[0] = offsetX;
+ widget->description.coords[1] = std::max(offsetY - height, 1);
+ widget->description.coords[2] = offsetX + width;
+ widget->description.coords[3] = offsetY;
+ widget->description.color[0] = 0.0f;
+ widget->description.color[1] = 0.7843137254901961f;
+ widget->description.color[2] = 0.29411764705882354f;
+ widget->description.color[3] = 1.0f;
+ widget->description.matchToWidget = nullptr;
+ }
+ }
+
+ {
+ RunningGraph *widget = new RunningGraph(60);
+ {
+ const int32_t fontSize = GetFontSize(0, kLargeFont);
+ const int32_t offsetX = 0;
+ const int32_t offsetY = 450;
+ const int32_t width = 5 * static_cast<uint32_t>(widget->runningValues.size());
+ const int32_t height = 100;
+
+ widget->type = WidgetType::RunningGraph;
+ widget->fontSize = fontSize;
+ widget->coords[0] = offsetX;
+ widget->coords[1] = offsetY;
+ widget->coords[2] = offsetX + width;
+ widget->coords[3] = offsetY + height;
+ widget->color[0] = 0.0f;
+ widget->color[1] = 0.7843137254901961f;
+ widget->color[2] = 0.29411764705882354f;
+ widget->color[3] = 0.7843137254901961f;
+ widget->matchToWidget = nullptr;
+ }
+ mState.mOverlayWidgets[WidgetId::VulkanTextureDescriptorCacheSize].reset(widget);
+ {
+ const int32_t fontSize = GetFontSize(kFontMipSmall, kLargeFont);
+ const int32_t offsetX =
+ mState.mOverlayWidgets[WidgetId::VulkanTextureDescriptorCacheSize]->coords[0];
+ const int32_t offsetY =
+ mState.mOverlayWidgets[WidgetId::VulkanTextureDescriptorCacheSize]->coords[1];
+ const int32_t width = 90 * (kFontGlyphWidth >> fontSize);
+ const int32_t height = (kFontGlyphHeight >> fontSize);
+
+ widget->description.type = WidgetType::Text;
+ widget->description.fontSize = fontSize;
+ widget->description.coords[0] = offsetX;
+ widget->description.coords[1] = std::max(offsetY - height, 1);
+ widget->description.coords[2] = offsetX + width;
+ widget->description.coords[3] = offsetY;
+ widget->description.color[0] = 0.0f;
+ widget->description.color[1] = 0.7843137254901961f;
+ widget->description.color[2] = 0.29411764705882354f;
+ widget->description.color[3] = 1.0f;
+ widget->description.matchToWidget = nullptr;
+ }
+ }
+
+ {
+ RunningGraph *widget = new RunningGraph(60);
+ {
+ const int32_t fontSize = GetFontSize(0, kLargeFont);
+ const int32_t offsetX = 0;
+ const int32_t offsetY = 450;
+ const int32_t width = 5 * static_cast<uint32_t>(widget->runningValues.size());
+ const int32_t height = 100;
+
+ widget->type = WidgetType::RunningGraph;
+ widget->fontSize = fontSize;
+ widget->coords[0] = offsetX;
+ widget->coords[1] = offsetY;
+ widget->coords[2] = offsetX + width;
+ widget->coords[3] = offsetY + height;
+ widget->color[0] = 0.0f;
+ widget->color[1] = 0.7843137254901961f;
+ widget->color[2] = 1.0f;
+ widget->color[3] = 0.7843137254901961f;
+ widget->matchToWidget = nullptr;
+ }
+ mState.mOverlayWidgets[WidgetId::VulkanUniformDescriptorCacheSize].reset(widget);
+ {
+ const int32_t fontSize = GetFontSize(kFontMipSmall, kLargeFont);
+ const int32_t offsetX =
+ mState.mOverlayWidgets[WidgetId::VulkanUniformDescriptorCacheSize]->coords[0];
+ const int32_t offsetY =
+ mState.mOverlayWidgets[WidgetId::VulkanUniformDescriptorCacheSize]->coords[1];
+ const int32_t width = 90 * (kFontGlyphWidth >> fontSize);
+ const int32_t height = (kFontGlyphHeight >> fontSize);
+
+ widget->description.type = WidgetType::Text;
+ widget->description.fontSize = fontSize;
+ widget->description.coords[0] = offsetX;
+ widget->description.coords[1] = std::max(offsetY - height, 1);
+ widget->description.coords[2] = offsetX + width;
+ widget->description.coords[3] = offsetY;
+ widget->description.color[0] = 0.0f;
+ widget->description.color[1] = 0.7843137254901961f;
+ widget->description.color[2] = 0.29411764705882354f;
+ widget->description.color[3] = 1.0f;
+ widget->description.matchToWidget = nullptr;
+ }
+ }
+
+ {
+ Count *widget = new Count;
+ {
+ const int32_t fontSize = GetFontSize(kFontMipSmall, kLargeFont);
+ const int32_t offsetX = 10;
+ const int32_t offsetY = 100;
+ const int32_t width = 30 * (kFontGlyphWidth >> fontSize);
+ const int32_t height = (kFontGlyphHeight >> fontSize);
+
+ widget->type = WidgetType::Count;
+ widget->fontSize = fontSize;
+ widget->coords[0] = offsetX;
+ widget->coords[1] = offsetY;
+ widget->coords[2] = offsetX + width;
+ widget->coords[3] = offsetY + height;
+ widget->color[0] = 1.0f;
+ widget->color[1] = 1.0f;
+ widget->color[2] = 1.0f;
+ widget->color[3] = 1.0f;
+ widget->matchToWidget = nullptr;
+ }
+ mState.mOverlayWidgets[WidgetId::VulkanDescriptorCacheKeySize].reset(widget);
+ }
+
+ {
+ RunningGraph *widget = new RunningGraph(60);
+ {
+ const int32_t fontSize = GetFontSize(0, kLargeFont);
+ const int32_t offsetX = -50;
+ const int32_t offsetY = 50;
+ const int32_t width = 5 * static_cast<uint32_t>(widget->runningValues.size());
+ const int32_t height = 100;
+
+ widget->type = WidgetType::RunningGraph;
+ widget->fontSize = fontSize;
+ widget->coords[0] = offsetX - width;
+ widget->coords[1] = offsetY;
+ widget->coords[2] = offsetX;
+ widget->coords[3] = offsetY + height;
+ widget->color[0] = 1.0f;
+ widget->color[1] = 0.0f;
+ widget->color[2] = 0.0f;
+ widget->color[3] = 0.39215686274509803f;
+ widget->matchToWidget = nullptr;
+ }
+ mState.mOverlayWidgets[WidgetId::VulkanAttemptedSubmissions].reset(widget);
+ {
+ const int32_t fontSize = GetFontSize(kFontMipSmall, kLargeFont);
+ const int32_t offsetX =
+ mState.mOverlayWidgets[WidgetId::VulkanAttemptedSubmissions]->coords[0];
+ const int32_t offsetY =
+ mState.mOverlayWidgets[WidgetId::VulkanAttemptedSubmissions]->coords[1];
+ const int32_t width = 45 * (kFontGlyphWidth >> fontSize);
+ const int32_t height = (kFontGlyphHeight >> fontSize);
+
+ widget->description.type = WidgetType::Text;
+ widget->description.fontSize = fontSize;
+ widget->description.coords[0] = offsetX;
+ widget->description.coords[1] = std::max(offsetY - height, 1);
+ widget->description.coords[2] = std::min(offsetX + width, -1);
+ widget->description.coords[3] = offsetY;
+ widget->description.color[0] = 0.7843137254901961f;
+ widget->description.color[1] = 0.0f;
+ widget->description.color[2] = 0.29411764705882354f;
+ widget->description.color[3] = 1.0f;
+ widget->description.matchToWidget = nullptr;
+ }
+ }
+
+ {
+ RunningGraph *widget = new RunningGraph(60);
+ {
+ const int32_t fontSize = GetFontSize(0, kLargeFont);
+ const int32_t offsetX =
+ mState.mOverlayWidgets[WidgetId::VulkanAttemptedSubmissions]->coords[0];
+ const int32_t offsetY =
+ mState.mOverlayWidgets[WidgetId::VulkanAttemptedSubmissions]->coords[1];
+ const int32_t width = 5 * static_cast<uint32_t>(widget->runningValues.size());
+ const int32_t height = 100;
+
+ widget->type = WidgetType::RunningGraph;
+ widget->fontSize = fontSize;
+ widget->coords[0] = offsetX;
+ widget->coords[1] = offsetY;
+ widget->coords[2] = std::min(offsetX + width, -1);
+ widget->coords[3] = offsetY + height;
+ widget->color[0] = 0.0f;
+ widget->color[1] = 1.0f;
+ widget->color[2] = 0.0f;
+ widget->color[3] = 0.7843137254901961f;
+ widget->matchToWidget =
+ mState.mOverlayWidgets[WidgetId::VulkanAttemptedSubmissions].get();
+ }
+ mState.mOverlayWidgets[WidgetId::VulkanActualSubmissions].reset(widget);
+ {
+ const int32_t fontSize = GetFontSize(kFontMipSmall, kLargeFont);
+ const int32_t offsetX =
+ mState.mOverlayWidgets[WidgetId::VulkanActualSubmissions]->coords[0];
+ const int32_t offsetY =
+ mState.mOverlayWidgets[WidgetId::VulkanActualSubmissions]->coords[3];
+ const int32_t width = 45 * (kFontGlyphWidth >> fontSize);
+ const int32_t height = (kFontGlyphHeight >> fontSize);
+
+ widget->description.type = WidgetType::Text;
+ widget->description.fontSize = fontSize;
+ widget->description.coords[0] = offsetX;
+ widget->description.coords[1] = offsetY;
+ widget->description.coords[2] = std::min(offsetX + width, -1);
+ widget->description.coords[3] = offsetY + height;
+ widget->description.color[0] = 0.0f;
+ widget->description.color[1] = 0.7843137254901961f;
+ widget->description.color[2] = 0.29411764705882354f;
+ widget->description.color[3] = 1.0f;
+ widget->description.matchToWidget = nullptr;
+ }
+ }
+
+ {
+ RunningGraph *widget = new RunningGraph(60);
+ {
+ const int32_t fontSize = GetFontSize(0, kLargeFont);
+ const int32_t offsetX = -50;
+ const int32_t offsetY = -50;
+ const int32_t width = 5 * static_cast<uint32_t>(widget->runningValues.size());
+ const int32_t height = 100;
+
+ widget->type = WidgetType::RunningGraph;
+ widget->fontSize = fontSize;
+ widget->coords[0] = offsetX - width;
+ widget->coords[1] = offsetY - height;
+ widget->coords[2] = offsetX;
+ widget->coords[3] = offsetY;
+ widget->color[0] = 0.0f;
+ widget->color[1] = 1.0f;
+ widget->color[2] = 0.0f;
+ widget->color[3] = 0.39215686274509803f;
+ widget->matchToWidget = nullptr;
+ }
+ mState.mOverlayWidgets[WidgetId::VulkanPipelineCacheLookups].reset(widget);
+ {
+ const int32_t fontSize = GetFontSize(kFontMipSmall, kLargeFont);
+ const int32_t offsetX =
+ mState.mOverlayWidgets[WidgetId::VulkanPipelineCacheLookups]->coords[0];
+ const int32_t offsetY =
+ mState.mOverlayWidgets[WidgetId::VulkanPipelineCacheLookups]->coords[1];
+ const int32_t width = 45 * (kFontGlyphWidth >> fontSize);
+ const int32_t height = (kFontGlyphHeight >> fontSize);
+
+ widget->description.type = WidgetType::Text;
+ widget->description.fontSize = fontSize;
+ widget->description.coords[0] = offsetX;
+ widget->description.coords[1] = offsetY - height;
+ widget->description.coords[2] = std::min(offsetX + width, -1);
+ widget->description.coords[3] = offsetY;
+ widget->description.color[0] = 0.0f;
+ widget->description.color[1] = 0.7843137254901961f;
+ widget->description.color[2] = 0.29411764705882354f;
+ widget->description.color[3] = 1.0f;
+ widget->description.matchToWidget = nullptr;
+ }
+ }
+
+ {
+ RunningGraph *widget = new RunningGraph(60);
+ {
+ const int32_t fontSize = GetFontSize(0, kLargeFont);
+ const int32_t offsetX =
+ mState.mOverlayWidgets[WidgetId::VulkanPipelineCacheLookups]->coords[0];
+ const int32_t offsetY =
+ mState.mOverlayWidgets[WidgetId::VulkanPipelineCacheLookups]->coords[1];
+ const int32_t width = 5 * static_cast<uint32_t>(widget->runningValues.size());
+ const int32_t height = 100;
+
+ widget->type = WidgetType::RunningGraph;
+ widget->fontSize = fontSize;
+ widget->coords[0] = offsetX;
+ widget->coords[1] = offsetY;
+ widget->coords[2] = std::min(offsetX + width, -1);
+ widget->coords[3] = std::min(offsetY + height, -1);
+ widget->color[0] = 1.0f;
+ widget->color[1] = 0.0f;
+ widget->color[2] = 0.0f;
+ widget->color[3] = 0.7843137254901961f;
+ widget->matchToWidget =
+ mState.mOverlayWidgets[WidgetId::VulkanPipelineCacheLookups].get();
+ }
+ mState.mOverlayWidgets[WidgetId::VulkanPipelineCacheMisses].reset(widget);
+ {
+ const int32_t fontSize = GetFontSize(kFontMipSmall, kLargeFont);
+ const int32_t offsetX = mState.mOverlayWidgets[WidgetId::VulkanPipelineCacheLookups]
+ ->getDescriptionWidget()
+ ->coords[0];
+ const int32_t offsetY = mState.mOverlayWidgets[WidgetId::VulkanPipelineCacheLookups]
+ ->getDescriptionWidget()
+ ->coords[1];
+ const int32_t width = 45 * (kFontGlyphWidth >> fontSize);
+ const int32_t height = (kFontGlyphHeight >> fontSize);
+
+ widget->description.type = WidgetType::Text;
+ widget->description.fontSize = fontSize;
+ widget->description.coords[0] = offsetX;
+ widget->description.coords[1] = offsetY - height;
+ widget->description.coords[2] = std::min(offsetX + width, -1);
+ widget->description.coords[3] = offsetY;
+ widget->description.color[0] = 0.7843137254901961f;
+ widget->description.color[1] = 0.0f;
+ widget->description.color[2] = 0.29411764705882354f;
+ widget->description.color[3] = 1.0f;
+ widget->description.matchToWidget = nullptr;
+ }
+ }
+
+ {
+ Count *widget = new Count;
+ {
+ const int32_t fontSize = GetFontSize(kFontMipSmall, kLargeFont);
+ const int32_t offsetX =
+ mState.mOverlayWidgets[WidgetId::VulkanPipelineCacheMisses]->coords[0];
+ const int32_t offsetY =
+ mState.mOverlayWidgets[WidgetId::VulkanPipelineCacheMisses]->coords[3];
+ const int32_t width = 45 * (kFontGlyphWidth >> fontSize);
+ const int32_t height = (kFontGlyphHeight >> fontSize);
+
+ widget->type = WidgetType::Count;
+ widget->fontSize = fontSize;
+ widget->coords[0] = offsetX;
+ widget->coords[1] = offsetY;
+ widget->coords[2] = std::min(offsetX + width, -1);
+ widget->coords[3] = std::min(offsetY + height, -1);
+ widget->color[0] = 1.0f;
+ widget->color[1] = 0.0f;
+ widget->color[2] = 0.0f;
+ widget->color[3] = 1.0f;
+ widget->matchToWidget = nullptr;
+ }
+ mState.mOverlayWidgets[WidgetId::VulkanTotalPipelineCacheMissTimeMs].reset(widget);
+ }
+
+ {
+ Count *widget = new Count;
+ {
+ const int32_t fontSize = GetFontSize(kFontMipSmall, kLargeFont);
+ const int32_t offsetX =
+ mState.mOverlayWidgets[WidgetId::VulkanTotalPipelineCacheMissTimeMs]->coords[0];
+ const int32_t offsetY =
+ mState.mOverlayWidgets[WidgetId::VulkanTotalPipelineCacheMissTimeMs]->coords[3];
+ const int32_t width = 45 * (kFontGlyphWidth >> fontSize);
+ const int32_t height = (kFontGlyphHeight >> fontSize);
+
+ widget->type = WidgetType::Count;
+ widget->fontSize = fontSize;
+ widget->coords[0] = offsetX;
+ widget->coords[1] = offsetY;
+ widget->coords[2] = std::min(offsetX + width, -1);
+ widget->coords[3] = std::min(offsetY + height, -1);
+ widget->color[0] = 0.0f;
+ widget->color[1] = 1.0f;
+ widget->color[2] = 0.0f;
+ widget->color[3] = 1.0f;
+ widget->matchToWidget = nullptr;
+ }
+ mState.mOverlayWidgets[WidgetId::VulkanTotalPipelineCacheHitTimeMs].reset(widget);
+ }
+}
+
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/Overlay_autogen.h b/gfx/angle/checkout/src/libANGLE/Overlay_autogen.h
new file mode 100644
index 0000000000..32ddd88559
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Overlay_autogen.h
@@ -0,0 +1,83 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_overlay_widgets.py using data from overlay_widgets.json.
+//
+// Copyright 2019 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.
+//
+// Overlay_autogen.cpp:
+// Autogenerated overlay widget declarations.
+
+namespace gl
+{
+enum class WidgetId
+{
+ // Frames per second (Count/Second).
+ FPS,
+ // Last validation error (Text).
+ VulkanLastValidationMessage,
+ // Number of validation errors and warnings (Count).
+ VulkanValidationMessageCount,
+ // Number of RenderPasses in a frame (Count).
+ VulkanRenderPassCount,
+ // Number of buffers used in RenderPasses (Count).
+ VulkanRenderPassBufferCount,
+ // Secondary Command Buffer pool memory waste (Bytes).
+ VulkanSecondaryCommandBufferPoolWaste,
+ // Number of Descriptor Set writes in a frame (Count).
+ VulkanWriteDescriptorSetCount,
+ // Descriptor Set Allocations.
+ VulkanDescriptorSetAllocations,
+ // Shader Resource Descriptor Set Cache Hit Rate.
+ VulkanShaderResourceDSHitRate,
+ // Buffer Allocations Made By vk::DynamicBuffer.
+ VulkanDynamicBufferAllocations,
+ // Total size of all descriptor set caches
+ VulkanDescriptorCacheSize,
+ // Number of cached Texture descriptor sets
+ VulkanTextureDescriptorCacheSize,
+ // Number of cached default uniform descriptor sets
+ VulkanUniformDescriptorCacheSize,
+ // Total size of all keys in the descriptor set caches
+ VulkanDescriptorCacheKeySize,
+ // Number of times the Vulkan backend attempted to submit commands
+ VulkanAttemptedSubmissions,
+ // Number of times the Vulkan backend actually submitted commands
+ VulkanActualSubmissions,
+ // Number of times the Vulkan backend has looked up the pipeline cache
+ VulkanPipelineCacheLookups,
+ // Number of times the Vulkan backend has missed the pipeline cache
+ VulkanPipelineCacheMisses,
+ // Total time spent creating pipelines that missed the cache.
+ VulkanTotalPipelineCacheMissTimeMs,
+ // Total time spent creating pipelines that hit the cache.
+ VulkanTotalPipelineCacheHitTimeMs,
+
+ InvalidEnum,
+ EnumCount = InvalidEnum,
+};
+
+// We can use this "X" macro to generate multiple code patterns.
+#define ANGLE_WIDGET_ID_X(PROC) \
+ PROC(FPS) \
+ PROC(VulkanLastValidationMessage) \
+ PROC(VulkanValidationMessageCount) \
+ PROC(VulkanRenderPassCount) \
+ PROC(VulkanRenderPassBufferCount) \
+ PROC(VulkanSecondaryCommandBufferPoolWaste) \
+ PROC(VulkanWriteDescriptorSetCount) \
+ PROC(VulkanDescriptorSetAllocations) \
+ PROC(VulkanShaderResourceDSHitRate) \
+ PROC(VulkanDynamicBufferAllocations) \
+ PROC(VulkanDescriptorCacheSize) \
+ PROC(VulkanTextureDescriptorCacheSize) \
+ PROC(VulkanUniformDescriptorCacheSize) \
+ PROC(VulkanDescriptorCacheKeySize) \
+ PROC(VulkanAttemptedSubmissions) \
+ PROC(VulkanActualSubmissions) \
+ PROC(VulkanPipelineCacheLookups) \
+ PROC(VulkanPipelineCacheMisses) \
+ PROC(VulkanTotalPipelineCacheMissTimeMs) \
+ PROC(VulkanTotalPipelineCacheHitTimeMs)
+
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/Overlay_font_autogen.cpp b/gfx/angle/checkout/src/libANGLE/Overlay_font_autogen.cpp
new file mode 100644
index 0000000000..7df5893304
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Overlay_font_autogen.cpp
@@ -0,0 +1,5078 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_overlay_fonts.py using images from overlay/DejaVuSansMono-Bold.ttf.
+//
+// Copyright 2022 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.
+//
+// Overlay_font_autogen.cpp:
+// Autogenerated overlay font data.
+
+#include "libANGLE/Overlay_font_autogen.h"
+#include "libANGLE/Overlay.h"
+
+#include <numeric>
+
+namespace gl
+{
+using namespace overlay;
+
+// Save binary size if the font images are never to be used.
+#if ANGLE_ENABLE_OVERLAY
+namespace
+{
+constexpr uint8_t kFontData[67830] = {
+ // clang-format off
+// Large
+// ' '
+ 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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,0x28,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x28,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x28,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x28,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x28,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x28,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x28,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x28,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x28,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x1D,0xFF,0xFF,0xFF,0x95, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x05,0xFE,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xEB,0xFF,0xFF,0x64, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xD2,0xFF,0xFF,0x4C, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xB9,0xFF,0xFF,0x34, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x28,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x28,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x28,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x28,0xFF,0xFF,0xFF,0xA0, 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, 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, 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, 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, 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,0xBC,0xFF,0xFF,0xE4, 0, 0, 0,0x7C,0xFF,0xFF,0xFF,0x24, 0, 0,
+ 0, 0, 0,0xBC,0xFF,0xFF,0xE4, 0, 0, 0,0x7C,0xFF,0xFF,0xFF,0x24, 0, 0,
+ 0, 0, 0,0xBC,0xFF,0xFF,0xE4, 0, 0, 0,0x7C,0xFF,0xFF,0xFF,0x24, 0, 0,
+ 0, 0, 0,0xBC,0xFF,0xFF,0xE4, 0, 0, 0,0x7C,0xFF,0xFF,0xFF,0x24, 0, 0,
+ 0, 0, 0,0xBC,0xFF,0xFF,0xE4, 0, 0, 0,0x7C,0xFF,0xFF,0xFF,0x24, 0, 0,
+ 0, 0, 0,0xBC,0xFF,0xFF,0xE4, 0, 0, 0,0x7C,0xFF,0xFF,0xFF,0x24, 0, 0,
+ 0, 0, 0,0xBC,0xFF,0xFF,0xE4, 0, 0, 0,0x7C,0xFF,0xFF,0xFF,0x24, 0, 0,
+ 0, 0, 0,0xBC,0xFF,0xFF,0xE4, 0, 0, 0,0x7C,0xFF,0xFF,0xFF,0x24, 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, 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, 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, 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, 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, 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, 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, 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,
+ 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, 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,0x43,0xFF,0xFF,0xE1, 0, 0,0x43,0xFF,0xFF,0xE7, 0,
+ 0, 0, 0, 0, 0, 0,0x87,0xFF,0xFF,0x9C, 0, 0,0x87,0xFF,0xFF,0xA2, 0,
+ 0, 0, 0, 0, 0, 0,0xCC,0xFF,0xFF,0x57, 0, 0,0xCB,0xFF,0xFF,0x5B, 0,
+ 0, 0, 0, 0, 0,0x13,0xFD,0xFF,0xFE,0x14, 0,0x11,0xFD,0xFF,0xFE,0x16, 0,
+ 0, 0, 0, 0, 0,0x56,0xFF,0xFF,0xCE, 0, 0,0x52,0xFF,0xFF,0xCF, 0, 0,
+ 0,0x58,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0,0x58,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0,0x58,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0, 0, 0, 0,0x5F,0xFF,0xFF,0xC1, 0, 0,0x56,0xFF,0xFF,0xC9, 0, 0, 0,
+ 0, 0, 0, 0,0xA3,0xFF,0xFF,0x7E, 0, 0,0x99,0xFF,0xFF,0x86, 0, 0, 0,
+ 0, 0, 0, 0,0xE5,0xFF,0xFF,0x3B, 0, 0,0xDC,0xFF,0xFF,0x43, 0, 0, 0,
+ 0, 0, 0,0x2A,0xFF,0xFF,0xF4,0x05, 0,0x1E,0xFF,0xFF,0xF8,0x08, 0, 0, 0,
+0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC8, 0,
+0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC8, 0,
+0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC8, 0,
+ 0, 0,0x2F,0xFF,0xFF,0xF1,0x04, 0,0x27,0xFF,0xFF,0xF6,0x07, 0, 0, 0, 0,
+ 0, 0,0x73,0xFF,0xFF,0xB1, 0, 0,0x6B,0xFF,0xFF,0xB9, 0, 0, 0, 0, 0,
+ 0, 0,0xB7,0xFF,0xFF,0x6D, 0, 0,0xAF,0xFF,0xFF,0x75, 0, 0, 0, 0, 0,
+ 0,0x05,0xF4,0xFF,0xFF,0x29, 0,0x03,0xEF,0xFF,0xFF,0x31, 0, 0, 0, 0, 0,
+ 0,0x3E,0xFF,0xFF,0xE5, 0, 0,0x36,0xFF,0xFF,0xEC,0x01, 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, 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, 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,
+ 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, 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,0x2C,0xFF,0xD4, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x2C,0xFF,0xD5, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x2C,0xFF,0xD7, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,0x0E,0x79,0xCA,0xF4,0xFF,0xFF,0xE6,0xBF,0x81,0x32, 0, 0, 0,
+ 0, 0, 0,0x2A,0xE2,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x24, 0, 0,
+ 0, 0,0x05,0xDB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x24, 0, 0,
+ 0, 0,0x58,0xFF,0xFF,0xFF,0xB5,0x46,0xFF,0xD4,0x1F,0x63,0xD0,0xFF,0x24, 0, 0,
+ 0, 0,0x94,0xFF,0xFF,0xFF,0x2A,0x2C,0xFF,0xD4, 0, 0,0x02,0x7A,0x21, 0, 0,
+ 0, 0,0xA7,0xFF,0xFF,0xFF,0x1B,0x2C,0xFF,0xD4, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x96,0xFF,0xFF,0xFF,0x6B,0x2C,0xFF,0xD4, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x58,0xFF,0xFF,0xFF,0xFB,0xA8,0xFF,0xD5, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x05,0xD8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEA,0xA6,0x3F, 0, 0, 0, 0,
+ 0, 0, 0,0x25,0xDB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xA0,0x06, 0, 0,
+ 0, 0, 0, 0,0x09,0x76,0xDA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x91, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x43,0xFF,0xEF,0xD6,0xFF,0xFF,0xFF,0xFB,0x1A, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x2C,0xFF,0xD4,0x04,0xB8,0xFF,0xFF,0xFF,0x5A, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x2C,0xFF,0xD4, 0,0x59,0xFF,0xFF,0xFF,0x72, 0,
+ 0, 0,0x77,0x5F,0x02, 0, 0,0x2C,0xFF,0xD4, 0,0x6D,0xFF,0xFF,0xFF,0x62, 0,
+ 0, 0,0x90,0xFF,0xDB,0x76,0x2D,0x35,0xFF,0xD5,0x3C,0xE5,0xFF,0xFF,0xFF,0x24, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xA3, 0, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xB9,0x0A, 0, 0,
+ 0, 0,0x0A,0x46,0x88,0xBE,0xDC,0xF7,0xFF,0xFF,0xEC,0xB9,0x5A,0x02, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x30,0xFF,0xD6, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x2F,0xFF,0xD5, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x2E,0xFF,0xD4, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x2D,0xFF,0xD4, 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, 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, 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, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x40,0xBD,0xF4,0xF2,0xB9,0x39, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0x5E,0xFD,0xFF,0xFF,0xFF,0xFF,0xFB,0x53, 0, 0, 0, 0, 0, 0, 0, 0,
+0x18,0xF5,0xFF,0xCD,0x22,0x26,0xD4,0xFF,0xF2,0x14, 0, 0, 0, 0, 0, 0, 0,
+0x67,0xFF,0xFF,0x3E, 0, 0,0x47,0xFF,0xFF,0x61, 0, 0, 0, 0, 0, 0, 0,
+0x82,0xFF,0xFF,0x15, 0, 0,0x1D,0xFF,0xFF,0x7D, 0, 0, 0, 0, 0, 0, 0,
+0x68,0xFF,0xFF,0x3E, 0, 0,0x46,0xFF,0xFF,0x62, 0, 0, 0, 0, 0, 0, 0,
+0x19,0xF6,0xFF,0xCD,0x22,0x24,0xD2,0xFF,0xF2,0x14, 0, 0, 0, 0, 0,0x02, 0,
+ 0,0x60,0xFD,0xFF,0xFF,0xFF,0xFF,0xFC,0x57, 0, 0, 0, 0,0x19,0x7C,0xE1,0x45,
+ 0, 0,0x42,0xBE,0xF5,0xF3,0xBB,0x3C, 0, 0,0x01,0x47,0xAE,0xFB,0xD4,0x6F,0x11,
+ 0, 0, 0, 0, 0, 0, 0, 0,0x17,0x78,0xDE,0xF5,0xA0,0x3A, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x01,0x43,0xAA,0xFA,0xD0,0x6B,0x0F, 0, 0, 0, 0, 0,
+ 0, 0, 0,0x15,0x75,0xDB,0xF4,0x9C,0x37, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0x3A,0xA7,0xF9,0xCD,0x68,0x0D, 0, 0, 0,0x67,0xD1,0xF8,0xE9,0x9F,0x1C, 0,
+ 0,0x6F,0x99,0x32, 0, 0, 0, 0, 0,0x9A,0xFF,0xFF,0xFF,0xFF,0xFF,0xE9,0x25,
+ 0, 0, 0, 0, 0, 0, 0, 0,0x4D,0xFF,0xFF,0xA0,0x12,0x49,0xF3,0xFF,0xC6,
+ 0, 0, 0, 0, 0, 0, 0, 0,0xA7,0xFF,0xF3,0x0B, 0, 0,0x89,0xFF,0xFF,
+ 0, 0, 0, 0, 0, 0, 0, 0,0xC2,0xFF,0xD5, 0, 0, 0,0x5D,0xFF,0xFF,
+ 0, 0, 0, 0, 0, 0, 0, 0,0xA8,0xFF,0xF2,0x09, 0, 0,0x87,0xFF,0xFF,
+ 0, 0, 0, 0, 0, 0, 0, 0,0x4F,0xFF,0xFF,0x9B,0x11,0x46,0xF2,0xFF,0xC7,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,0x9E,0xFF,0xFF,0xFF,0xFF,0xFF,0xEB,0x27,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,0x01,0x69,0xD2,0xF9,0xEA,0xA1,0x1E, 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, 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, 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, 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,
+ 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,0x01,0x56,0xB0,0xE2,0xF7,0xF8,0xDA,0x95,0x36, 0, 0, 0, 0,
+ 0, 0, 0,0x07,0xB7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x14, 0, 0, 0,
+ 0, 0, 0,0x7B,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x14, 0, 0, 0,
+ 0, 0, 0,0xCF,0xFF,0xFF,0xFF,0x98,0x1B,0x08,0x26,0x5D,0xC4,0x13, 0, 0, 0,
+ 0, 0, 0,0xE1,0xFF,0xFF,0xFF,0x29, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0xB6,0xFF,0xFF,0xFF,0x75, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0x52,0xFF,0xFF,0xFF,0xF0,0x19, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,0xC3,0xFF,0xFF,0xFF,0xB8, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0x5D,0xF5,0xFF,0xFF,0xFF,0xFF,0x66, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x77,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF1,0x1D, 0, 0, 0, 0, 0, 0,
+ 0,0x45,0xFD,0xFF,0xFF,0xCB,0xA3,0xFF,0xFF,0xFF,0xB7, 0, 0,0x18,0xFF,0xFF,0xFF,
+ 0,0xCB,0xFF,0xFF,0xE9,0x14,0x0E,0xE6,0xFF,0xFF,0xFF,0x60, 0,0x0B,0xFF,0xFF,0xFF,
+0x2E,0xFF,0xFF,0xFF,0x89, 0, 0,0x55,0xFF,0xFF,0xFF,0xEF,0x19,0x1D,0xFF,0xFF,0xFF,
+0x59,0xFF,0xFF,0xFF,0x5F, 0, 0, 0,0xB5,0xFF,0xFF,0xFF,0xB1,0x48,0xFF,0xFF,0xEA,
+0x71,0xFF,0xFF,0xFF,0x6B, 0, 0, 0,0x20,0xF5,0xFF,0xFF,0xFF,0xDB,0xFF,0xFF,0xAF,
+0x5F,0xFF,0xFF,0xFF,0xB1, 0, 0, 0, 0,0x76,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x4F,
+0x25,0xFF,0xFF,0xFF,0xFE,0x46, 0, 0, 0,0x04,0xD1,0xFF,0xFF,0xFF,0xFF,0xC7,0x02,
+ 0,0xBE,0xFF,0xFF,0xFF,0xF5,0x6E,0x15,0x09,0x44,0xCB,0xFF,0xFF,0xFF,0xFF,0x5A, 0,
+ 0,0x27,0xEE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xD8,0x07,
+ 0, 0,0x31,0xDD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x85,
+ 0, 0, 0,0x09,0x69,0xBB,0xEA,0xFB,0xF3,0xD3,0x94,0x3C,0x55,0xFF,0xFF,0xFF,0xFA,
+ 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, 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, 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, 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, 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,0x1C,0xFF,0xFF,0xFF,0x84, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0x84, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0x84, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0x84, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0x84, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0x84, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0x84, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0x84, 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, 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, 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, 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, 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, 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, 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,
+ 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,0x77,0xFF,0xFF,0xD4,0x01, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,0x23,0xF6,0xFF,0xFF,0x5A, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,0xAE,0xFF,0xFF,0xDB,0x03, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x37,0xFF,0xFF,0xFF,0x69, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xB0,0xFF,0xFF,0xFA,0x13, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x1E,0xFD,0xFF,0xFF,0xB3, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x7C,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xCB,0xFF,0xFF,0xFF,0x1F, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x0F,0xFE,0xFF,0xFF,0xE8, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x42,0xFF,0xFF,0xFF,0xB2, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x68,0xFF,0xFF,0xFF,0x95, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x83,0xFF,0xFF,0xFF,0x82, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x8F,0xFF,0xFF,0xFF,0x70, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x8F,0xFF,0xFF,0xFF,0x71, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x83,0xFF,0xFF,0xFF,0x83, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x68,0xFF,0xFF,0xFF,0x95, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x41,0xFF,0xFF,0xFF,0xB4, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x0E,0xFE,0xFF,0xFF,0xE9, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xCA,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x7A,0xFF,0xFF,0xFF,0x5D, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x1D,0xFD,0xFF,0xFF,0xB5, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xAF,0xFF,0xFF,0xFB,0x14, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x35,0xFF,0xFF,0xFF,0x6B, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,0xAD,0xFF,0xFF,0xDC,0x03, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,0x22,0xF6,0xFF,0xFF,0x5A, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,0x76,0xFF,0xFF,0xD4,0x01, 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, 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, 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, 0, 0,0x62,0xFF,0xFF,0xE1,0x0C, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,0x05,0xE0,0xFF,0xFF,0x90, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x69,0xFF,0xFF,0xFB,0x28, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x07,0xEC,0xFF,0xFF,0xAC, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x97,0xFF,0xFF,0xFD,0x27, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x3D,0xFF,0xFF,0xFF,0x8F, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x01,0xE3,0xFF,0xFF,0xEB,0x03, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0x3E, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x71,0xFF,0xFF,0xFF,0x80, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x3B,0xFF,0xFF,0xFF,0xB6, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x1E,0xFF,0xFF,0xFF,0xDB, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x0B,0xFF,0xFF,0xFF,0xF6, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,0xF8,0xFF,0xFF,0xFF,0x03, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,0xF9,0xFF,0xFF,0xFF,0x02, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x0C,0xFF,0xFF,0xFF,0xF5, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x1E,0xFF,0xFF,0xFF,0xDA, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x3C,0xFF,0xFF,0xFF,0xB5, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x73,0xFF,0xFF,0xFF,0x7F, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xA9,0xFF,0xFF,0xFF,0x3C, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x01,0xE4,0xFF,0xFF,0xEA,0x03, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x3E,0xFF,0xFF,0xFF,0x8F, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x98,0xFF,0xFF,0xFD,0x27, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x07,0xEC,0xFF,0xFF,0xAB, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x6A,0xFF,0xFF,0xFB,0x27, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,0x05,0xE0,0xFF,0xFF,0x90, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,0x62,0xFF,0xFF,0xE1,0x0C, 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, 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, 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, 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,0x84,0xFF,0xE8, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x84,0xFF,0xE8, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x84,0xFF,0xE8, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x7E,0xA7,0x2A, 0, 0,0x84,0xFF,0xE8, 0, 0,0x0B,0x74,0xC7,0x09, 0,
+ 0,0x15,0xF6,0xFF,0xFD,0xAA,0x2D,0x84,0xFF,0xE8,0x0D,0x78,0xEB,0xFF,0xFF,0x73, 0,
+ 0, 0,0x2B,0xA2,0xFB,0xFF,0xFE,0xE8,0xFF,0xF9,0xED,0xFF,0xFF,0xD2,0x5B,0x03, 0,
+ 0, 0, 0, 0,0x1E,0x92,0xF5,0xFF,0xFF,0xFF,0xFF,0xC5,0x4D,0x01, 0, 0, 0,
+ 0, 0, 0, 0,0x1E,0x91,0xF5,0xFF,0xFF,0xFF,0xFF,0xC5,0x4C,0x01, 0, 0, 0,
+ 0, 0,0x2A,0xA1,0xFB,0xFF,0xFD,0xE4,0xFF,0xF8,0xE9,0xFF,0xFF,0xD2,0x5A,0x03, 0,
+ 0,0x15,0xF6,0xFF,0xFD,0xA7,0x28,0x84,0xFF,0xE8,0x0A,0x74,0xE9,0xFF,0xFF,0x73, 0,
+ 0, 0,0x7E,0xA7,0x28, 0, 0,0x84,0xFF,0xE8, 0, 0,0x0A,0x73,0xC8,0x09, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x84,0xFF,0xE8, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x84,0xFF,0xE8, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x84,0xFF,0xE8, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xF4,0xFF,0xFF,0x68, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xF4,0xFF,0xFF,0x68, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xF4,0xFF,0xFF,0x68, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xF4,0xFF,0xFF,0x68, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xF4,0xFF,0xFF,0x68, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xF4,0xFF,0xFF,0x68, 0, 0, 0, 0, 0, 0,
+0x10,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,
+0x10,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,
+0x10,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,
+ 0, 0, 0, 0, 0, 0, 0,0xF4,0xFF,0xFF,0x68, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xF4,0xFF,0xFF,0x68, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xF4,0xFF,0xFF,0x68, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xF4,0xFF,0xFF,0x68, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xF4,0xFF,0xFF,0x68, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xF4,0xFF,0xFF,0x68, 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, 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, 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, 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, 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, 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, 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,
+ 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, 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, 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, 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, 0, 0, 0, 0, 0,0x78,0xFF,0xFF,0xFF,0xF4, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x78,0xFF,0xFF,0xFF,0xF4, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x78,0xFF,0xFF,0xFF,0xF4, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x7A,0xFF,0xFF,0xFF,0xEF, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xAD,0xFF,0xFF,0xFF,0x8C, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x02,0xEE,0xFF,0xFF,0xF2,0x14, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x35,0xFF,0xFF,0xFF,0x7F, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x7A,0xFF,0xFF,0xEB,0x0D, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0xBE,0xFF,0xFF,0x73, 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, 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, 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, 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, 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, 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, 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, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,0xBC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x34, 0, 0, 0,
+ 0, 0, 0, 0,0xBC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x34, 0, 0, 0,
+ 0, 0, 0, 0,0xBC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x34, 0, 0, 0,
+ 0, 0, 0, 0,0xBC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x34, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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,
+ 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,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 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, 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, 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,
+ 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, 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, 0, 0, 0,0x80,0xFF,0xFF,0xA0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x0A,0xEB,0xFF,0xFE,0x2B, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x6D,0xFF,0xFF,0xB2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x04,0xDF,0xFF,0xFF,0x3C, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x5B,0xFF,0xFF,0xC5, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xD1,0xFF,0xFF,0x4E, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,0x49,0xFF,0xFF,0xD7,0x01, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,0xBF,0xFF,0xFF,0x61, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,0x36,0xFF,0xFF,0xE4,0x06, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,0xAD,0xFF,0xFF,0x74, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x26,0xFD,0xFF,0xF0,0x0D, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x9B,0xFF,0xFF,0x86, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x18,0xF8,0xFF,0xF8,0x18, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x88,0xFF,0xFF,0x99, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x0E,0xF0,0xFF,0xFD,0x25, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x76,0xFF,0xFF,0xAC, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,0x06,0xE6,0xFF,0xFF,0x36, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,0x64,0xFF,0xFF,0xBE, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0x02,0xD8,0xFF,0xFF,0x48, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0x51,0xFF,0xFF,0xD1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0xC8,0xFF,0xFF,0x5A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x3F,0xFF,0xFF,0xE0,0x04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xB6,0xFF,0xFF,0x6D, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0x2D,0xFF,0xFF,0xEC,0x0A, 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, 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, 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, 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,0x39,0xA2,0xE0,0xF8,0xEB,0xC5,0x6F,0x07, 0, 0, 0, 0,
+ 0, 0, 0, 0,0x81,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xD3,0x1C, 0, 0, 0,
+ 0, 0, 0,0x66,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xCF,0x06, 0, 0,
+ 0, 0,0x0E,0xED,0xFF,0xFF,0xFF,0x80,0x0D,0x33,0xE0,0xFF,0xFF,0xFF,0x6C, 0, 0,
+ 0, 0,0x69,0xFF,0xFF,0xFF,0xC2, 0, 0, 0,0x4D,0xFF,0xFF,0xFF,0xDA, 0, 0,
+ 0, 0,0xB5,0xFF,0xFF,0xFF,0x69, 0, 0, 0,0x04,0xF0,0xFF,0xFF,0xFF,0x28, 0,
+ 0, 0,0xEC,0xFF,0xFF,0xFF,0x36, 0, 0, 0, 0,0xC1,0xFF,0xFF,0xFF,0x5F, 0,
+ 0,0x14,0xFF,0xFF,0xFF,0xFF,0x15, 0, 0, 0, 0,0x9F,0xFF,0xFF,0xFF,0x86, 0,
+ 0,0x2E,0xFF,0xFF,0xFF,0xFE,0x03,0x61,0xEF,0xBE,0x0B,0x8B,0xFF,0xFF,0xFF,0xA0, 0,
+ 0,0x39,0xFF,0xFF,0xFF,0xF9, 0,0xEF,0xFF,0xFF,0x67,0x83,0xFF,0xFF,0xFF,0xAC, 0,
+ 0,0x41,0xFF,0xFF,0xFF,0xF5, 0,0xF0,0xFF,0xFF,0x68,0x7E,0xFF,0xFF,0xFF,0xB5, 0,
+ 0,0x39,0xFF,0xFF,0xFF,0xF9, 0,0x64,0xEF,0xBE,0x0C,0x83,0xFF,0xFF,0xFF,0xAC, 0,
+ 0,0x2E,0xFF,0xFF,0xFF,0xFE,0x03, 0, 0, 0, 0,0x8B,0xFF,0xFF,0xFF,0xA0, 0,
+ 0,0x14,0xFF,0xFF,0xFF,0xFF,0x15, 0, 0, 0, 0,0x9F,0xFF,0xFF,0xFF,0x86, 0,
+ 0, 0,0xEC,0xFF,0xFF,0xFF,0x36, 0, 0, 0, 0,0xC1,0xFF,0xFF,0xFF,0x5F, 0,
+ 0, 0,0xB5,0xFF,0xFF,0xFF,0x68, 0, 0, 0,0x04,0xF0,0xFF,0xFF,0xFF,0x28, 0,
+ 0, 0,0x69,0xFF,0xFF,0xFF,0xC0, 0, 0, 0,0x4C,0xFF,0xFF,0xFF,0xDB, 0, 0,
+ 0, 0,0x0E,0xED,0xFF,0xFF,0xFF,0x7E,0x0C,0x32,0xDF,0xFF,0xFF,0xFF,0x6D, 0, 0,
+ 0, 0, 0,0x66,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xD2,0x07, 0, 0,
+ 0, 0, 0, 0,0x81,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xD5,0x1D, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x39,0xA3,0xE0,0xF8,0xED,0xC6,0x70,0x07, 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, 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, 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, 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, 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,0x1D,0x58,0x92,0xCD,0xFC,0xFF,0xFF,0xFF,0x68, 0, 0, 0, 0, 0,
+ 0, 0,0x04,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x68, 0, 0, 0, 0, 0,
+ 0, 0,0x04,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x68, 0, 0, 0, 0, 0,
+ 0, 0,0x04,0xE2,0xA7,0x6C,0x31,0xAF,0xFF,0xFF,0xFF,0x68, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xAC,0xFF,0xFF,0xFF,0x68, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xAC,0xFF,0xFF,0xFF,0x68, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xAC,0xFF,0xFF,0xFF,0x68, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xAC,0xFF,0xFF,0xFF,0x68, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xAC,0xFF,0xFF,0xFF,0x68, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xAC,0xFF,0xFF,0xFF,0x68, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xAC,0xFF,0xFF,0xFF,0x68, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xAC,0xFF,0xFF,0xFF,0x68, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xAC,0xFF,0xFF,0xFF,0x68, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xAC,0xFF,0xFF,0xFF,0x68, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xAC,0xFF,0xFF,0xFF,0x68, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xAC,0xFF,0xFF,0xFF,0x68, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xAC,0xFF,0xFF,0xFF,0x68, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xAC,0xFF,0xFF,0xFF,0x68, 0, 0, 0, 0, 0,
+ 0, 0,0x58,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x14,
+ 0, 0,0x58,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x14,
+ 0, 0,0x58,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x14,
+ 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, 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, 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, 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, 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,0x1A,0x59,0x99,0xCC,0xEC,0xFB,0xF4,0xDE,0xAB,0x55,0x04, 0, 0, 0, 0,
+ 0, 0,0xEC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xCD,0x22, 0, 0, 0,
+ 0, 0,0xEC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE1,0x11, 0, 0,
+ 0, 0,0xEC,0xFF,0xBB,0x5E,0x1E,0x08,0x24,0x8C,0xFF,0xFF,0xFF,0xFF,0x89, 0, 0,
+ 0, 0,0xAD,0x32, 0, 0, 0, 0, 0, 0,0x9B,0xFF,0xFF,0xFF,0xDC, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x4C,0xFF,0xFF,0xFF,0xFC,0x02, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x42,0xFF,0xFF,0xFF,0xF9, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x81,0xFF,0xFF,0xFF,0xD0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,0x12,0xEC,0xFF,0xFF,0xFF,0x7A, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,0xAE,0xFF,0xFF,0xFF,0xE7,0x0E, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,0x7D,0xFF,0xFF,0xFF,0xFE,0x4B, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x5F,0xFF,0xFF,0xFF,0xFF,0x77, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x4A,0xFB,0xFF,0xFF,0xFF,0x89, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x38,0xF5,0xFF,0xFF,0xFF,0x93, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,0x2A,0xED,0xFF,0xFF,0xFF,0x98,0x01, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0x1E,0xE3,0xFF,0xFF,0xFF,0x9B,0x01, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x13,0xD7,0xFF,0xFF,0xFF,0x9D,0x01, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0x0B,0xC9,0xFF,0xFF,0xFF,0xA0,0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0x5F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x0C, 0,
+ 0,0x60,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x0C, 0,
+ 0,0x60,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x0C, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x0B,0x47,0x88,0xC2,0xE7,0xF9,0xF9,0xE8,0xBE,0x79,0x18, 0, 0, 0, 0,
+ 0, 0,0x98,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF3,0x5E, 0, 0, 0,
+ 0, 0,0x98,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x4A, 0, 0,
+ 0, 0,0x98,0xFF,0xD6,0x70,0x29,0x08,0x17,0x58,0xE4,0xFF,0xFF,0xFF,0xCB, 0, 0,
+ 0, 0,0x7D,0x59,0x01, 0, 0, 0, 0, 0,0x3E,0xFF,0xFF,0xFF,0xFE,0x05, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x04,0xFD,0xFF,0xFF,0xFF,0x0B, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x32,0xFF,0xFF,0xFF,0xD8, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,0x14,0x50,0xDC,0xFF,0xFF,0xFF,0x59, 0, 0,
+ 0, 0, 0, 0, 0,0x78,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEA,0x52, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x78,0xFF,0xFF,0xFF,0xFF,0xFF,0xB1,0x24, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x78,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0x90,0x03, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x01,0x1C,0x5A,0xE3,0xFF,0xFF,0xFF,0x97, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x23,0xF7,0xFF,0xFF,0xFE,0x27, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0x70, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x7D,0xFF,0xFF,0xFF,0x8D, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x93,0xFF,0xFF,0xFF,0x84, 0,
+ 0,0x37,0x89,0x0C, 0, 0, 0, 0, 0, 0,0x14,0xE6,0xFF,0xFF,0xFF,0x5E, 0,
+ 0,0x3C,0xFF,0xF0,0x92,0x4B,0x1B,0x07,0x16,0x4E,0xD5,0xFF,0xFF,0xFF,0xF5,0x14, 0,
+ 0,0x3C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x73, 0, 0,
+ 0,0x3C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF8,0x76, 0, 0, 0,
+ 0,0x01,0x30,0x70,0xAF,0xD0,0xE4,0xF7,0xF8,0xE7,0xBD,0x7C,0x1D, 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, 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, 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,
+// '4'
+ 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,0x08,0xD8,0xFF,0xFF,0xFF,0xD4, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,0x8B,0xFF,0xFF,0xFF,0xFF,0xD4, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x37,0xFC,0xFF,0xFF,0xFF,0xFF,0xD4, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x07,0xD6,0xFF,0xFF,0xFF,0xFF,0xFF,0xD4, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x88,0xFF,0xFF,0xF5,0xFF,0xFF,0xFF,0xD4, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x35,0xFC,0xFF,0xFF,0x73,0xFF,0xFF,0xFF,0xD4, 0, 0, 0,
+ 0, 0, 0, 0,0x06,0xD4,0xFF,0xFF,0xA3,0x2C,0xFF,0xFF,0xFF,0xD4, 0, 0, 0,
+ 0, 0, 0, 0,0x85,0xFF,0xFF,0xEB,0x14,0x2C,0xFF,0xFF,0xFF,0xD4, 0, 0, 0,
+ 0, 0, 0,0x32,0xFB,0xFF,0xFF,0x5C, 0,0x2C,0xFF,0xFF,0xFF,0xD4, 0, 0, 0,
+ 0, 0,0x05,0xD2,0xFF,0xFF,0xB8, 0, 0,0x2C,0xFF,0xFF,0xFF,0xD4, 0, 0, 0,
+ 0, 0,0x82,0xFF,0xFF,0xF4,0x20, 0, 0,0x2C,0xFF,0xFF,0xFF,0xD4, 0, 0, 0,
+ 0,0x30,0xFA,0xFF,0xFF,0x71, 0, 0, 0,0x2C,0xFF,0xFF,0xFF,0xD4, 0, 0, 0,
+ 0,0x8F,0xFF,0xFF,0xCA,0x03, 0, 0, 0,0x2C,0xFF,0xFF,0xFF,0xD4, 0, 0, 0,
+ 0,0x90,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x28,
+ 0,0x90,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x28,
+ 0,0x90,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x28,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,0x2C,0xFF,0xFF,0xFF,0xD4, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,0x2C,0xFF,0xFF,0xFF,0xD4, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,0x2C,0xFF,0xFF,0xFF,0xD4, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,0x2C,0xFF,0xFF,0xFF,0xD4, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,0x2C,0xFF,0xFF,0xFF,0xD4, 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, 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, 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,
+// '5'
+ 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x44,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x38, 0, 0,
+ 0, 0,0x44,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x38, 0, 0,
+ 0, 0,0x44,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x38, 0, 0,
+ 0, 0,0x44,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x44,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x44,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x44,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x44,0xFF,0xFF,0xFF,0xCC,0xEF,0xFA,0xE9,0xB9,0x65,0x05, 0, 0, 0, 0,
+ 0, 0,0x44,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xD5,0x25, 0, 0, 0,
+ 0, 0,0x44,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE4,0x18, 0, 0,
+ 0, 0,0x41,0xBF,0x6B,0x32,0x16,0x07,0x29,0x8E,0xFD,0xFF,0xFF,0xFF,0xA6, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x64,0xFF,0xFF,0xFF,0xFE,0x17, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xD6,0xFF,0xFF,0xFF,0x55, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x9F,0xFF,0xFF,0xFF,0x71, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x9F,0xFF,0xFF,0xFF,0x70, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xD1,0xFF,0xFF,0xFF,0x53, 0,
+ 0, 0,0x9F,0x0F, 0, 0, 0, 0, 0, 0,0x56,0xFF,0xFF,0xFF,0xFC,0x13, 0,
+ 0, 0,0xF8,0xEC,0x80,0x30,0x0A,0x08,0x2D,0x89,0xFA,0xFF,0xFF,0xFF,0x9B, 0, 0,
+ 0, 0,0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xD6,0x12, 0, 0,
+ 0, 0,0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xB8,0x17, 0, 0, 0,
+ 0, 0,0x20,0x64,0xA7,0xCF,0xE6,0xFA,0xF1,0xD5,0x9C,0x40, 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, 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, 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,
+// '6'
+ 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x3D,0x94,0xD3,0xEC,0xF8,0xDD,0xB4,0x60,0x0E, 0, 0,
+ 0, 0, 0, 0,0x0F,0xB0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x94, 0, 0,
+ 0, 0, 0,0x0C,0xCE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x94, 0, 0,
+ 0, 0, 0,0x91,0xFF,0xFF,0xFF,0xE3,0x62,0x19,0x07,0x2D,0x91,0xFA,0x94, 0, 0,
+ 0, 0,0x1A,0xFC,0xFF,0xFF,0xE7,0x1B, 0, 0, 0, 0, 0,0x30,0x72, 0, 0,
+ 0, 0,0x75,0xFF,0xFF,0xFF,0x66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xB9,0xFF,0xFF,0xFE,0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xE8,0xFF,0xFF,0xDF,0x18,0x90,0xDA,0xF7,0xF3,0xD0,0x81,0x0F, 0, 0, 0,
+ 0,0x08,0xFF,0xFF,0xFF,0xE5,0xE6,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0,0x24, 0, 0,
+ 0,0x17,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xD1,0x04, 0,
+ 0,0x21,0xFF,0xFF,0xFF,0xFF,0xFF,0x93,0x17,0x0C,0x6A,0xFC,0xFF,0xFF,0xFF,0x55, 0,
+ 0,0x19,0xFF,0xFF,0xFF,0xFF,0xD3, 0, 0, 0, 0,0x9B,0xFF,0xFF,0xFF,0xA2, 0,
+ 0,0x0E,0xFF,0xFF,0xFF,0xFF,0x7B, 0, 0, 0, 0,0x41,0xFF,0xFF,0xFF,0xCE, 0,
+ 0,0x01,0xF6,0xFF,0xFF,0xFF,0x5D, 0, 0, 0, 0,0x22,0xFF,0xFF,0xFF,0xDE, 0,
+ 0, 0,0xD2,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0,0x22,0xFF,0xFF,0xFF,0xD6, 0,
+ 0, 0,0xA1,0xFF,0xFF,0xFF,0x7B, 0, 0, 0, 0,0x41,0xFF,0xFF,0xFF,0xBD, 0,
+ 0, 0,0x55,0xFF,0xFF,0xFF,0xD3, 0, 0, 0, 0,0x9B,0xFF,0xFF,0xFF,0x85, 0,
+ 0, 0,0x09,0xE5,0xFF,0xFF,0xFF,0x92,0x15,0x0C,0x69,0xFC,0xFF,0xFF,0xFE,0x27, 0,
+ 0, 0, 0,0x5B,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x95, 0, 0,
+ 0, 0, 0, 0,0x73,0xFA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xA7,0x07, 0, 0,
+ 0, 0, 0, 0, 0,0x29,0x91,0xD6,0xF1,0xF9,0xE4,0xAC,0x49, 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, 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, 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,
+// '7'
+ 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0x18,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x48, 0,
+ 0,0x18,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x48, 0,
+ 0,0x18,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x47, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x75,0xFF,0xFF,0xFF,0xF9,0x15, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xD6,0xFF,0xFF,0xFF,0xA8, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,0x39,0xFF,0xFF,0xFF,0xFF,0x43, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,0x9B,0xFF,0xFF,0xFF,0xDC,0x01, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,0x0A,0xF1,0xFF,0xFF,0xFF,0x78, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,0x5E,0xFF,0xFF,0xFF,0xFA,0x17, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,0xC0,0xFF,0xFF,0xFF,0xAC, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x22,0xFE,0xFF,0xFF,0xFF,0x47, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x84,0xFF,0xFF,0xFF,0xDF,0x02, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x02,0xE2,0xFF,0xFF,0xFF,0x7B, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x47,0xFF,0xFF,0xFF,0xFB,0x1A, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xA9,0xFF,0xFF,0xFF,0xB0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x12,0xF8,0xFF,0xFF,0xFF,0x4A, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x6C,0xFF,0xFF,0xFF,0xE2,0x02, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0xCE,0xFF,0xFF,0xFF,0x7F, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,0x2F,0xFF,0xFF,0xFF,0xFC,0x1C, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,0x92,0xFF,0xFF,0xFF,0xB4, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0x06,0xEC,0xFF,0xFF,0xFF,0x4E, 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, 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, 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,
+// '8'
+ 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,0x09,0x6A,0xBC,0xE9,0xFA,0xF2,0xD3,0x94,0x2B, 0, 0, 0, 0,
+ 0, 0, 0,0x25,0xDA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0x74, 0, 0, 0,
+ 0, 0,0x08,0xDC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x56, 0, 0,
+ 0, 0,0x5F,0xFF,0xFF,0xFF,0xE0,0x47,0x0C,0x1F,0x99,0xFF,0xFF,0xFF,0xD1, 0, 0,
+ 0, 0,0x97,0xFF,0xFF,0xFF,0x49, 0, 0, 0,0x01,0xD0,0xFF,0xFF,0xFF,0x0A, 0,
+ 0, 0,0x9C,0xFF,0xFF,0xFF,0x1A, 0, 0, 0, 0,0xA3,0xFF,0xFF,0xFF,0x0F, 0,
+ 0, 0,0x72,0xFF,0xFF,0xFF,0x4B, 0, 0, 0,0x01,0xD1,0xFF,0xFF,0xE5, 0, 0,
+ 0, 0,0x11,0xEE,0xFF,0xFF,0xE0,0x46,0x0B,0x1F,0x98,0xFF,0xFF,0xFF,0x71, 0, 0,
+ 0, 0, 0,0x31,0xE1,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0x8A,0x01, 0, 0,
+ 0, 0, 0, 0,0x1C,0xD2,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x6E, 0, 0, 0, 0,
+ 0, 0, 0,0x56,0xF7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xBB,0x0A, 0, 0,
+ 0, 0,0x3D,0xFC,0xFF,0xFF,0xDF,0x49,0x0E,0x26,0x9B,0xFF,0xFF,0xFF,0xAF, 0, 0,
+ 0, 0,0xBE,0xFF,0xFF,0xFB,0x29, 0, 0, 0, 0,0xB1,0xFF,0xFF,0xFF,0x35, 0,
+ 0,0x06,0xFD,0xFF,0xFF,0xBE, 0, 0, 0, 0, 0,0x4B,0xFF,0xFF,0xFF,0x7A, 0,
+ 0,0x23,0xFF,0xFF,0xFF,0xA1, 0, 0, 0, 0, 0,0x2E,0xFF,0xFF,0xFF,0x9A, 0,
+ 0,0x1C,0xFF,0xFF,0xFF,0xBF, 0, 0, 0, 0, 0,0x4C,0xFF,0xFF,0xFF,0x92, 0,
+ 0,0x03,0xF0,0xFF,0xFF,0xFB,0x29, 0, 0, 0, 0,0xB5,0xFF,0xFF,0xFF,0x6A, 0,
+ 0, 0,0xA2,0xFF,0xFF,0xFF,0xDF,0x49,0x0E,0x25,0x9D,0xFF,0xFF,0xFF,0xFA,0x1E, 0,
+ 0, 0,0x23,0xF1,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8C, 0, 0,
+ 0, 0, 0,0x3E,0xE8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x9A,0x03, 0, 0,
+ 0, 0, 0, 0,0x10,0x74,0xC0,0xEB,0xFB,0xF3,0xD8,0x9E,0x3A, 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, 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, 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,
+// '9'
+ 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,0x17,0x86,0xCE,0xF0,0xF8,0xE4,0xB4,0x60,0x03, 0, 0, 0, 0,
+ 0, 0, 0,0x47,0xF1,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xCC,0x16, 0, 0, 0,
+ 0, 0,0x2B,0xF6,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xCD,0x04, 0, 0,
+ 0, 0,0xB2,0xFF,0xFF,0xFF,0xBC,0x26,0x07,0x49,0xEB,0xFF,0xFF,0xFF,0x66, 0, 0,
+ 0,0x11,0xFD,0xFF,0xFF,0xF7,0x14, 0, 0, 0,0x64,0xFF,0xFF,0xFF,0xCD, 0, 0,
+ 0,0x47,0xFF,0xFF,0xFF,0xB3, 0, 0, 0, 0,0x0C,0xFF,0xFF,0xFF,0xFF,0x1A, 0,
+ 0,0x60,0xFF,0xFF,0xFF,0x95, 0, 0, 0, 0, 0,0xED,0xFF,0xFF,0xFF,0x49, 0,
+ 0,0x67,0xFF,0xFF,0xFF,0x94, 0, 0, 0, 0, 0,0xEE,0xFF,0xFF,0xFF,0x70, 0,
+ 0,0x57,0xFF,0xFF,0xFF,0xB3, 0, 0, 0, 0,0x0C,0xFF,0xFF,0xFF,0xFF,0x85, 0,
+ 0,0x2B,0xFF,0xFF,0xFF,0xF7,0x14, 0, 0, 0,0x64,0xFF,0xFF,0xFF,0xFF,0x90, 0,
+ 0,0x01,0xDD,0xFF,0xFF,0xFF,0xBC,0x25,0x06,0x48,0xEB,0xFF,0xFF,0xFF,0xFF,0x98, 0,
+ 0, 0,0x60,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8D, 0,
+ 0, 0, 0,0x91,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xD4,0xFF,0xFF,0xFF,0x7F, 0,
+ 0, 0, 0, 0,0x49,0xB2,0xE9,0xFB,0xED,0xBC,0x56,0x69,0xFF,0xFF,0xFF,0x5E, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x97,0xFF,0xFF,0xFF,0x2F, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x06,0xE7,0xFF,0xFF,0xE7,0x03, 0,
+ 0, 0,0x1E,0x7E,0x01, 0, 0, 0, 0, 0,0x89,0xFF,0xFF,0xFF,0x8C, 0, 0,
+ 0, 0,0x20,0xFF,0xC9,0x4F,0x0F,0x0A,0x36,0xA4,0xFF,0xFF,0xFF,0xEE,0x17, 0, 0,
+ 0, 0,0x20,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0x53, 0, 0, 0,
+ 0, 0,0x20,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE7,0x4C, 0, 0, 0, 0,
+ 0, 0, 0,0x39,0x93,0xD0,0xEF,0xF6,0xE2,0xB5,0x6B,0x0B, 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, 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, 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,
+ 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, 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, 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, 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, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 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, 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, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 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, 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, 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,
+ 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, 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, 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, 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, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 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, 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, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xA4,0xFF,0xFF,0xFF,0xFF,0x14, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xA5,0xFF,0xFF,0xFF,0xFF,0x10, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xCE,0xFF,0xFF,0xFF,0xAC, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x08,0xFA,0xFF,0xFF,0xFC,0x28, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x3A,0xFF,0xFF,0xFF,0x9D, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x70,0xFF,0xFF,0xF8,0x1E, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0xA5,0xFF,0xFF,0x8F, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0,0x05,0x54,0xB8,0x35,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x28,0x8C,0xEA,0xFF,0xFF,0x38,
+ 0, 0, 0, 0, 0, 0, 0, 0,0x0A,0x60,0xC4,0xFF,0xFF,0xFF,0xFF,0xFF,0x38,
+ 0, 0, 0, 0, 0, 0,0x34,0x98,0xF1,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC5,0x1F,
+ 0, 0, 0,0x11,0x6C,0xD0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xD6,0x7B,0x21, 0, 0,
+ 0,0x39,0xA4,0xF7,0xFF,0xFF,0xFF,0xFF,0xFF,0xE4,0x8C,0x31, 0, 0, 0, 0, 0,
+ 0,0xC0,0xFF,0xFF,0xFF,0xFF,0xEF,0x9D,0x42,0x02, 0, 0, 0, 0, 0, 0, 0,
+ 0,0xC0,0xFF,0xFF,0xFF,0x9C,0x0C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0xC0,0xFF,0xFF,0xFF,0xFF,0xEA,0x95,0x3A, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0x3D,0xA9,0xF9,0xFF,0xFF,0xFF,0xFF,0xFF,0xDF,0x85,0x2A, 0, 0, 0, 0, 0,
+ 0, 0, 0,0x13,0x70,0xD3,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xD0,0x75,0x1C, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x38,0x9B,0xF2,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xC0,0x1E,
+ 0, 0, 0, 0, 0, 0, 0, 0,0x0B,0x63,0xC6,0xFF,0xFF,0xFF,0xFF,0xFF,0x38,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x2A,0x8E,0xEB,0xFF,0xFF,0x38,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x06,0x55,0xB9,0x35,
+ 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, 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, 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, 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, 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, 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, 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, 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,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x38,
+ 0,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x38,
+ 0,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x38,
+ 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, 0, 0, 0, 0,
+ 0,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x38,
+ 0,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x38,
+ 0,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x38,
+ 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, 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, 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, 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, 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, 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, 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, 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,0xA3,0x83,0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0xC0,0xFF,0xFE,0xBB,0x57,0x06, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0xC0,0xFF,0xFF,0xFF,0xFF,0xEC,0x8F,0x2B, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0x7C,0xEF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC7,0x63,0x0C, 0, 0, 0, 0, 0,
+ 0, 0,0x07,0x51,0xAC,0xF7,0xFF,0xFF,0xFF,0xFF,0xFF,0xF3,0x9B,0x37, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x0F,0x62,0xBD,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xD3,0x6F,0x0B,
+ 0, 0, 0, 0, 0, 0, 0, 0,0x1A,0x73,0xCE,0xFF,0xFF,0xFF,0xFF,0xFF,0x38,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x4B,0xE9,0xFF,0xFF,0xFF,0x38,
+ 0, 0, 0, 0, 0, 0, 0, 0,0x15,0x6B,0xC6,0xFF,0xFF,0xFF,0xFF,0xFF,0x38,
+ 0, 0, 0, 0, 0,0x0B,0x5B,0xB6,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xD7,0x74,0x0C,
+ 0, 0,0x05,0x4B,0xA6,0xF5,0xFF,0xFF,0xFF,0xFF,0xFF,0xF4,0x9F,0x3B, 0, 0, 0,
+ 0,0x79,0xEB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xCA,0x66,0x0D, 0, 0, 0, 0, 0,
+ 0,0xC0,0xFF,0xFF,0xFF,0xFF,0xED,0x91,0x2D, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0xC0,0xFF,0xFE,0xBC,0x59,0x07, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0xA4,0x84,0x21, 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,
+ 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, 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, 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, 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, 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,0x37,0x96,0xD7,0xF4,0xF7,0xE0,0xAB,0x4B, 0, 0, 0, 0,
+ 0, 0, 0,0x27,0xBB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xAA,0x06, 0, 0,
+ 0, 0, 0,0xB4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x82, 0, 0,
+ 0, 0, 0,0xB4,0xFF,0xB7,0x57,0x1A,0x06,0x23,0xA3,0xFF,0xFF,0xFF,0xE9, 0, 0,
+ 0, 0, 0,0x8A,0x3A, 0, 0, 0, 0, 0,0x0A,0xFD,0xFF,0xFF,0xFF,0x0C, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x17,0xFF,0xFF,0xFF,0xF4,0x01, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,0x01,0xA6,0xFF,0xFF,0xFF,0x98, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,0x01,0x95,0xFF,0xFF,0xFF,0xD7,0x0E, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x01,0x9E,0xFF,0xFF,0xFF,0xD8,0x19, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x90,0xFF,0xFF,0xFF,0xD1,0x16, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x3B,0xFF,0xFF,0xFF,0xD8,0x14, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x97,0xFF,0xFF,0xFF,0x45, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xBA,0xFF,0xFF,0xFF,0x10, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xC4,0xFF,0xFF,0xFF,0x04, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xC4,0xFF,0xFF,0xFF,0x04, 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,0xC4,0xFF,0xFF,0xFF,0x04, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xC4,0xFF,0xFF,0xFF,0x04, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xC4,0xFF,0xFF,0xFF,0x04, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xC4,0xFF,0xFF,0xFF,0x04, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x11,0x69,0xB9,0xE0,0xF8,0xEF,0xCA,0x7D,0x10, 0, 0, 0,
+ 0, 0, 0, 0,0x5E,0xEB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE9,0x37, 0, 0,
+ 0, 0, 0,0x82,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEE,0x1F, 0,
+ 0, 0,0x6C,0xFF,0xFF,0xFF,0xDA,0x67,0x1F,0x06,0x16,0x5A,0xE2,0xFF,0xFF,0xA6, 0,
+ 0,0x22,0xF5,0xFF,0xFF,0xAB,0x0A, 0, 0, 0, 0, 0,0x1C,0xEF,0xFF,0xFB,0x0D,
+ 0,0xA1,0xFF,0xFF,0xC4,0x06, 0, 0, 0, 0, 0, 0, 0,0x8F,0xFF,0xFF,0x43,
+0x11,0xF7,0xFF,0xFB,0x29, 0, 0,0x12,0x8C,0xDD,0xF8,0xE1,0x7E,0x68,0xFF,0xFF,0x5C,
+0x5B,0xFF,0xFF,0xAF, 0, 0,0x1A,0xDC,0xFF,0xFF,0xFF,0xFF,0xFF,0xDF,0xFF,0xFF,0x67,
+0x92,0xFF,0xFF,0x58, 0, 0,0xB5,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x68,
+0xC1,0xFF,0xFF,0x20, 0,0x28,0xFF,0xFF,0xFF,0x84,0x1A,0x13,0x6A,0xF9,0xFF,0xFF,0x68,
+0xD5,0xFF,0xFC, 0, 0,0x68,0xFF,0xFF,0xB7, 0, 0, 0, 0,0x8D,0xFF,0xFF,0x68,
+0xE4,0xFF,0xEE, 0, 0,0x84,0xFF,0xFF,0x75, 0, 0, 0, 0,0x4A,0xFF,0xFF,0x68,
+0xE2,0xFF,0xF1, 0, 0,0x83,0xFF,0xFF,0x75, 0, 0, 0, 0,0x4B,0xFF,0xFF,0x68,
+0xD0,0xFF,0xFF,0x04, 0,0x67,0xFF,0xFF,0xB7, 0, 0, 0, 0,0x8D,0xFF,0xFF,0x68,
+0xBA,0xFF,0xFF,0x2D, 0,0x26,0xFF,0xFF,0xFF,0x84,0x19,0x13,0x69,0xF9,0xFF,0xFF,0x68,
+0x85,0xFF,0xFF,0x6B, 0, 0,0xB2,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x68,
+0x48,0xFF,0xFF,0xCF, 0, 0,0x19,0xDB,0xFF,0xFF,0xFF,0xFF,0xFF,0xE7,0xFF,0xFF,0x68,
+0x05,0xE5,0xFF,0xFF,0x54, 0, 0,0x11,0x8B,0xDE,0xFA,0xE6,0x8C,0x63,0xFF,0xFF,0x68,
+ 0,0x79,0xFF,0xFF,0xEC,0x24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0x0A,0xD7,0xFF,0xFF,0xE8,0x3C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x2F,0xF4,0xFF,0xFF,0xFF,0xAD,0x54,0x1D,0x07,0x14,0x31,0x70,0xCE,0x4F, 0,
+ 0, 0, 0,0x35,0xEA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xDB,0x06,
+ 0, 0, 0, 0,0x1E,0xA6,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xCA,0x1A,
+ 0, 0, 0, 0, 0, 0,0x2B,0x7C,0xC1,0xE1,0xF6,0xF6,0xDD,0xA6,0x4D,0x02, 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, 0, 0, 0, 0, 0,
+// 'A'
+ 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x04,0xF2,0xFF,0xFF,0xFF,0xFF,0x6A, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x3D,0xFF,0xFF,0xFF,0xFF,0xFF,0xB0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x82,0xFF,0xFF,0xFF,0xFF,0xFF,0xF1,0x04, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0xC8,0xFF,0xFF,0xF9,0xFF,0xFF,0xFF,0x3B, 0, 0, 0, 0,
+ 0, 0, 0, 0,0x10,0xFC,0xFF,0xFF,0x9B,0xFF,0xFF,0xFF,0x81, 0, 0, 0, 0,
+ 0, 0, 0, 0,0x53,0xFF,0xFF,0xFF,0x49,0xD8,0xFF,0xFF,0xC7, 0, 0, 0, 0,
+ 0, 0, 0, 0,0x98,0xFF,0xFF,0xFD,0x0F,0x9B,0xFF,0xFF,0xFC,0x10, 0, 0, 0,
+ 0, 0, 0, 0,0xDD,0xFF,0xFF,0xD0, 0,0x5E,0xFF,0xFF,0xFF,0x52, 0, 0, 0,
+ 0, 0, 0,0x23,0xFF,0xFF,0xFF,0x93, 0,0x21,0xFF,0xFF,0xFF,0x98, 0, 0, 0,
+ 0, 0, 0,0x69,0xFF,0xFF,0xFF,0x57, 0, 0,0xE4,0xFF,0xFF,0xDE, 0, 0, 0,
+ 0, 0, 0,0xAE,0xFF,0xFF,0xFF,0x1A, 0, 0,0xA7,0xFF,0xFF,0xFF,0x23, 0, 0,
+ 0, 0,0x03,0xF0,0xFF,0xFF,0xDE, 0, 0, 0,0x6A,0xFF,0xFF,0xFF,0x69, 0, 0,
+ 0, 0,0x39,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xAF, 0, 0,
+ 0, 0,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF0,0x03, 0,
+ 0, 0,0xC4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3A, 0,
+ 0,0x0E,0xFB,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0,0x61,0xFF,0xFF,0xFF,0x80, 0,
+ 0,0x4F,0xFF,0xFF,0xFF,0x99, 0, 0, 0, 0, 0,0x29,0xFF,0xFF,0xFF,0xC6, 0,
+ 0,0x95,0xFF,0xFF,0xFF,0x62, 0, 0, 0, 0, 0,0x01,0xF0,0xFF,0xFF,0xFC,0x0F,
+ 0,0xDA,0xFF,0xFF,0xFF,0x2C, 0, 0, 0, 0, 0, 0,0xBB,0xFF,0xFF,0xFF,0x51,
+0x1F,0xFF,0xFF,0xFF,0xF3,0x02, 0, 0, 0, 0, 0, 0,0x83,0xFF,0xFF,0xFF,0x97,
+0x65,0xFF,0xFF,0xFF,0xBF, 0, 0, 0, 0, 0, 0, 0,0x4C,0xFF,0xFF,0xFF,0xDD,
+ 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, 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, 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,
+// 'B'
+ 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0x3C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xF3,0xDE,0xB2,0x66,0x09, 0, 0, 0,
+ 0,0x3C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE2,0x31, 0, 0,
+ 0,0x3C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE7,0x0F, 0,
+ 0,0x3C,0xFF,0xFF,0xFF,0xD0, 0, 0,0x02,0x1B,0x75,0xFE,0xFF,0xFF,0xFF,0x67, 0,
+ 0,0x3C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0,0xAD,0xFF,0xFF,0xFF,0x98, 0,
+ 0,0x3C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0,0x86,0xFF,0xFF,0xFF,0xA0, 0,
+ 0,0x3C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0,0xA9,0xFF,0xFF,0xFF,0x7A, 0,
+ 0,0x3C,0xFF,0xFF,0xFF,0xD0, 0, 0,0x02,0x18,0x6C,0xFD,0xFF,0xFF,0xF5,0x1E, 0,
+ 0,0x3C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0,0x40, 0, 0,
+ 0,0x3C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF5,0x9B,0x1C, 0, 0, 0,
+ 0,0x3C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,0x78, 0, 0,
+ 0,0x3C,0xFF,0xFF,0xFF,0xD0, 0, 0,0x01,0x14,0x56,0xE6,0xFF,0xFF,0xFF,0x70, 0,
+ 0,0x3C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0,0x3F,0xFF,0xFF,0xFF,0xEE,0x08,
+ 0,0x3C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,0xEE,0xFF,0xFF,0xFF,0x3F,
+ 0,0x3C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,0xD8,0xFF,0xFF,0xFF,0x5E,
+ 0,0x3C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,0xE7,0xFF,0xFF,0xFF,0x5F,
+ 0,0x3C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0,0x2A,0xFF,0xFF,0xFF,0xFF,0x45,
+ 0,0x3C,0xFF,0xFF,0xFF,0xD0, 0, 0,0x01,0x10,0x47,0xD5,0xFF,0xFF,0xFF,0xF7,0x0B,
+ 0,0x3C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x86, 0,
+ 0,0x3C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x9A,0x03, 0,
+ 0,0x3C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF6,0xE6,0xC1,0x89,0x30, 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, 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, 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,
+// 'C'
+ 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x0C,0x6A,0xB4,0xE0,0xF6,0xF0,0xD4,0xA5,0x4A,0x04, 0,
+ 0, 0, 0, 0, 0,0x51,0xE7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x50, 0,
+ 0, 0, 0, 0,0x5F,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x50, 0,
+ 0, 0, 0,0x26,0xF7,0xFF,0xFF,0xFF,0xDF,0x56,0x13,0x10,0x59,0xE1,0xFF,0x50, 0,
+ 0, 0, 0,0xB1,0xFF,0xFF,0xFF,0xE4,0x17, 0, 0, 0, 0,0x19,0xD6,0x50, 0,
+ 0, 0,0x1A,0xFC,0xFF,0xFF,0xFF,0x60, 0, 0, 0, 0, 0, 0,0x24,0x40, 0,
+ 0, 0,0x62,0xFF,0xFF,0xFF,0xF7,0x09, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x95,0xFF,0xFF,0xFF,0xC1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xBA,0xFF,0xFF,0xFF,0x9C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xC9,0xFF,0xFF,0xFF,0x8A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xD4,0xFF,0xFF,0xFF,0x82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xC9,0xFF,0xFF,0xFF,0x8A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xBA,0xFF,0xFF,0xFF,0x9C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x96,0xFF,0xFF,0xFF,0xC1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x62,0xFF,0xFF,0xFF,0xF7,0x09, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x1A,0xFC,0xFF,0xFF,0xFF,0x5F, 0, 0, 0, 0, 0, 0,0x24,0x40, 0,
+ 0, 0, 0,0xB2,0xFF,0xFF,0xFF,0xE4,0x17, 0, 0, 0, 0,0x19,0xD5,0x50, 0,
+ 0, 0, 0,0x28,0xF8,0xFF,0xFF,0xFF,0xDE,0x55,0x11,0x10,0x58,0xE1,0xFF,0x50, 0,
+ 0, 0, 0, 0,0x62,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x50, 0,
+ 0, 0, 0, 0, 0,0x54,0xE8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x50, 0,
+ 0, 0, 0, 0, 0, 0,0x0C,0x6C,0xB6,0xE2,0xF7,0xF1,0xD5,0xA6,0x4B,0x04, 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, 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, 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,
+// 'D'
+ 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0xFD,0xED,0xDC,0xB0,0x77,0x1D, 0, 0, 0, 0, 0,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0x9A,0x0A, 0, 0, 0,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xCE,0x0C, 0, 0,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20,0x07,0x29,0x8A,0xFC,0xFF,0xFF,0xFF,0x9B, 0, 0,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0,0x6B,0xFF,0xFF,0xFF,0xFD,0x1F, 0,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0,0x02,0xDE,0xFF,0xFF,0xFF,0x80, 0,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0x93,0xFF,0xFF,0xFF,0xBD, 0,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0x64,0xFF,0xFF,0xFF,0xEE, 0,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0x46,0xFF,0xFF,0xFF,0xFF,0x0B,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0x39,0xFF,0xFF,0xFF,0xFF,0x19,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0x32,0xFF,0xFF,0xFF,0xFF,0x24,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0x39,0xFF,0xFF,0xFF,0xFF,0x19,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0x46,0xFF,0xFF,0xFF,0xFF,0x0B,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0x64,0xFF,0xFF,0xFF,0xED, 0,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0x95,0xFF,0xFF,0xFF,0xBC, 0,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0,0x02,0xDE,0xFF,0xFF,0xFF,0x7E, 0,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0,0x6A,0xFF,0xFF,0xFF,0xFD,0x1E, 0,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20,0x06,0x28,0x8A,0xFC,0xFF,0xFF,0xFF,0x97, 0, 0,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xCB,0x0B, 0, 0,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFA,0x9A,0x09, 0, 0, 0,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0xFD,0xEF,0xDD,0xB2,0x77,0x1D, 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, 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, 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,
+// 'E'
+ 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xA0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8C, 0,
+ 0, 0,0xA0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8C, 0,
+ 0, 0,0xA0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8C, 0,
+ 0, 0,0xA0,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xA0,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xA0,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xA0,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xA0,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xA0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xB4, 0, 0,
+ 0, 0,0xA0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xB4, 0, 0,
+ 0, 0,0xA0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xB4, 0, 0,
+ 0, 0,0xA0,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xA0,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xA0,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xA0,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xA0,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xA0,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xA0,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xA0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8C, 0,
+ 0, 0,0xA0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8C, 0,
+ 0, 0,0xA0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8C, 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, 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, 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,
+// 'F'
+ 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x6C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0, 0,
+ 0, 0,0x6C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0, 0,
+ 0, 0,0x6C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0, 0,
+ 0, 0,0x6C,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x6C,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x6C,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x6C,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x6C,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x6C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF0, 0, 0,
+ 0, 0,0x6C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF0, 0, 0,
+ 0, 0,0x6C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF0, 0, 0,
+ 0, 0,0x6C,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x6C,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x6C,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x6C,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x6C,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x6C,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x6C,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x6C,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x6C,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x6C,0xFF,0xFF,0xFF,0xC0, 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, 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, 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,
+// 'G'
+ 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x37,0x8F,0xD0,0xEB,0xFB,0xF0,0xCD,0x8D,0x3C,0x02, 0,
+ 0, 0, 0, 0,0x0E,0xA8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x40, 0,
+ 0, 0, 0,0x0F,0xCC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x40, 0,
+ 0, 0, 0,0x9F,0xFF,0xFF,0xFF,0xFF,0x97,0x2D,0x08,0x1D,0x6A,0xE6,0xFF,0x40, 0,
+ 0, 0,0x31,0xFF,0xFF,0xFF,0xFF,0x77, 0, 0, 0, 0, 0,0x1B,0xD5,0x40, 0,
+ 0, 0,0x96,0xFF,0xFF,0xFF,0xD9,0x02, 0, 0, 0, 0, 0, 0,0x28,0x35, 0,
+ 0, 0,0xE2,0xFF,0xFF,0xFF,0x7D, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0x15,0xFF,0xFF,0xFF,0xFF,0x40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0x3A,0xFF,0xFF,0xFF,0xFF,0x1B, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0x49,0xFF,0xFF,0xFF,0xFF,0x0A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0x54,0xFF,0xFF,0xFF,0xFF,0x02, 0, 0,0x84,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0,
+ 0,0x49,0xFF,0xFF,0xFF,0xFF,0x0A, 0, 0,0x84,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0,
+ 0,0x3A,0xFF,0xFF,0xFF,0xFF,0x1C, 0, 0,0x84,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0,
+ 0,0x15,0xFF,0xFF,0xFF,0xFF,0x40, 0, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF, 0,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0x7D, 0, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF, 0,
+ 0, 0,0x93,0xFF,0xFF,0xFF,0xD8,0x01, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF, 0,
+ 0, 0,0x2F,0xFF,0xFF,0xFF,0xFF,0x6F, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF, 0,
+ 0, 0, 0,0x9C,0xFF,0xFF,0xFF,0xFD,0x89,0x21,0x06,0x27,0xCE,0xFF,0xFF,0xFF, 0,
+ 0, 0, 0,0x0E,0xCC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0,
+ 0, 0, 0, 0,0x0F,0xAD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0x9E, 0,
+ 0, 0, 0, 0, 0, 0,0x3D,0x97,0xD7,0xF0,0xFA,0xEA,0xC2,0x82,0x25, 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, 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, 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,
+// 'H'
+ 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0x84, 0,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0x84, 0,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0x84, 0,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0x84, 0,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0x84, 0,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0x84, 0,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0x84, 0,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0x84, 0,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x84, 0,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x84, 0,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x84, 0,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0x84, 0,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0x84, 0,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0x84, 0,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0x84, 0,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0x84, 0,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0x84, 0,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0x84, 0,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0x84, 0,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0x84, 0,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0x20, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0x84, 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, 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, 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,
+// 'I'
+ 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x08, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x08, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x08, 0,
+ 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x08, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x08, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x08, 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, 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, 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,
+// 'J'
+ 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,0x04,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x48, 0, 0,
+ 0, 0, 0, 0,0x04,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x48, 0, 0,
+ 0, 0, 0, 0,0x04,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x48, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xE8,0xFF,0xFF,0xFF,0x48, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xE8,0xFF,0xFF,0xFF,0x48, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xE8,0xFF,0xFF,0xFF,0x48, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xE8,0xFF,0xFF,0xFF,0x48, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xE8,0xFF,0xFF,0xFF,0x48, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xE8,0xFF,0xFF,0xFF,0x48, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xE8,0xFF,0xFF,0xFF,0x48, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xE8,0xFF,0xFF,0xFF,0x48, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xE8,0xFF,0xFF,0xFF,0x48, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xE8,0xFF,0xFF,0xFF,0x48, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xE8,0xFF,0xFF,0xFF,0x48, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xED,0xFF,0xFF,0xFF,0x41, 0, 0,
+ 0,0x58,0x23, 0, 0, 0, 0, 0, 0,0x0B,0xFE,0xFF,0xFF,0xFF,0x31, 0, 0,
+ 0,0x74,0xE3,0x3A, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xFD,0x0B, 0, 0,
+ 0,0x74,0xFF,0xFC,0x9E,0x3B,0x0E,0x18,0x60,0xF0,0xFF,0xFF,0xFF,0xC5, 0, 0, 0,
+ 0,0x74,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x4F, 0, 0, 0,
+ 0,0x74,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0x7D, 0, 0, 0, 0,
+ 0,0x06,0x3E,0x7F,0xBB,0xD7,0xEE,0xFB,0xEF,0xCE,0x94,0x30, 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, 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, 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,
+// 'K'
+ 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+0x58,0xFF,0xFF,0xFF,0xD4, 0, 0, 0, 0, 0,0x1C,0xE9,0xFF,0xFF,0xFF,0xB2,0x01,
+0x58,0xFF,0xFF,0xFF,0xD4, 0, 0, 0, 0,0x06,0xC8,0xFF,0xFF,0xFF,0xD7,0x0E, 0,
+0x58,0xFF,0xFF,0xFF,0xD4, 0, 0, 0, 0,0x9A,0xFF,0xFF,0xFF,0xF0,0x26, 0, 0,
+0x58,0xFF,0xFF,0xFF,0xD4, 0, 0, 0,0x63,0xFF,0xFF,0xFF,0xFD,0x4B, 0, 0, 0,
+0x58,0xFF,0xFF,0xFF,0xD4, 0, 0,0x35,0xF8,0xFF,0xFF,0xFF,0x79, 0, 0, 0, 0,
+0x58,0xFF,0xFF,0xFF,0xD4, 0,0x15,0xE2,0xFF,0xFF,0xFF,0xAA, 0, 0, 0, 0, 0,
+0x58,0xFF,0xFF,0xFF,0xD4,0x03,0xBD,0xFF,0xFF,0xFF,0xD1,0x0B, 0, 0, 0, 0, 0,
+0x58,0xFF,0xFF,0xFF,0xD4,0x8C,0xFF,0xFF,0xFF,0xEC,0x21, 0, 0, 0, 0, 0, 0,
+0x58,0xFF,0xFF,0xFF,0xF7,0xFF,0xFF,0xFF,0xFF,0x9C, 0, 0, 0, 0, 0, 0, 0,
+0x58,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF9,0x21, 0, 0, 0, 0, 0, 0,
+0x58,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xA5, 0, 0, 0, 0, 0, 0,
+0x58,0xFF,0xFF,0xFF,0xFF,0xFF,0xDD,0xFF,0xFF,0xFF,0xFE,0x32, 0, 0, 0, 0, 0,
+0x58,0xFF,0xFF,0xFF,0xFF,0xDC,0x12,0xCD,0xFF,0xFF,0xFF,0xBB, 0, 0, 0, 0, 0,
+0x58,0xFF,0xFF,0xFF,0xF5,0x2C, 0,0x47,0xFF,0xFF,0xFF,0xFF,0x46, 0, 0, 0, 0,
+0x58,0xFF,0xFF,0xFF,0xD4, 0, 0, 0,0xBF,0xFF,0xFF,0xFF,0xCF,0x01, 0, 0, 0,
+0x58,0xFF,0xFF,0xFF,0xD4, 0, 0, 0,0x37,0xFF,0xFF,0xFF,0xFF,0x5B, 0, 0, 0,
+0x58,0xFF,0xFF,0xFF,0xD4, 0, 0, 0, 0,0xB0,0xFF,0xFF,0xFF,0xDF,0x07, 0, 0,
+0x58,0xFF,0xFF,0xFF,0xD4, 0, 0, 0, 0,0x2A,0xFD,0xFF,0xFF,0xFF,0x71, 0, 0,
+0x58,0xFF,0xFF,0xFF,0xD4, 0, 0, 0, 0, 0,0xA0,0xFF,0xFF,0xFF,0xEC,0x0F, 0,
+0x58,0xFF,0xFF,0xFF,0xD4, 0, 0, 0, 0, 0,0x1F,0xF8,0xFF,0xFF,0xFF,0x87, 0,
+0x58,0xFF,0xFF,0xFF,0xD4, 0, 0, 0, 0, 0, 0,0x90,0xFF,0xFF,0xFF,0xF6,0x1B,
+ 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, 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, 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,
+// 'L'
+ 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x4C,
+ 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x4C,
+ 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x4C,
+ 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, 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, 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,
+// 'M'
+ 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0xC8,0xFF,0xFF,0xFF,0xFF,0x57, 0, 0, 0, 0,0xE7,0xFF,0xFF,0xFF,0xFF,0x3C,
+ 0,0xC8,0xFF,0xFF,0xFF,0xFF,0x9F, 0, 0, 0,0x30,0xFF,0xFF,0xFF,0xFF,0xFF,0x3C,
+ 0,0xC8,0xFF,0xFF,0xFF,0xFF,0xE6, 0, 0, 0,0x78,0xFF,0xFF,0xFF,0xFF,0xFF,0x3C,
+ 0,0xC8,0xFF,0xFF,0xFF,0xFF,0xFF,0x2F, 0, 0,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0x3C,
+ 0,0xC8,0xFF,0xFF,0xE4,0xFE,0xFF,0x77, 0,0x0D,0xFA,0xFF,0xE3,0xFF,0xFF,0xFF,0x3C,
+ 0,0xC8,0xFF,0xFF,0xD0,0xD3,0xFF,0xBE, 0,0x4F,0xFF,0xFF,0xA3,0xFF,0xFF,0xFF,0x3C,
+ 0,0xC8,0xFF,0xFF,0xD0,0x92,0xFF,0xF9,0x0C,0x97,0xFF,0xFB,0x68,0xFF,0xFF,0xFF,0x3C,
+ 0,0xC8,0xFF,0xFF,0xD0,0x51,0xFF,0xFF,0x4E,0xDE,0xFF,0xC7,0x5C,0xFF,0xFF,0xFF,0x3C,
+ 0,0xC8,0xFF,0xFF,0xD0,0x12,0xFE,0xFF,0xBC,0xFF,0xFF,0x87,0x5C,0xFF,0xFF,0xFF,0x3C,
+ 0,0xC8,0xFF,0xFF,0xD0, 0,0xCF,0xFF,0xFF,0xFF,0xFF,0x47,0x5C,0xFF,0xFF,0xFF,0x3C,
+ 0,0xC8,0xFF,0xFF,0xD0, 0,0x8E,0xFF,0xFF,0xFF,0xFB,0x0C,0x5C,0xFF,0xFF,0xFF,0x3C,
+ 0,0xC8,0xFF,0xFF,0xD0, 0,0x4D,0xFF,0xFF,0xFF,0xC7, 0,0x5C,0xFF,0xFF,0xFF,0x3C,
+ 0,0xC8,0xFF,0xFF,0xD0, 0,0x0F,0xFC,0xFF,0xFF,0x87, 0,0x5C,0xFF,0xFF,0xFF,0x3C,
+ 0,0xC8,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0x3C,
+ 0,0xC8,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0x3C,
+ 0,0xC8,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0x3C,
+ 0,0xC8,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0x3C,
+ 0,0xC8,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0x3C,
+ 0,0xC8,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0x3C,
+ 0,0xC8,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0x3C,
+ 0,0xC8,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0x3C,
+ 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, 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, 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,
+// 'N'
+ 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0x50,0xFF,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0, 0,0xF0,0xFF,0xFF,0xC0, 0,
+ 0,0x50,0xFF,0xFF,0xFF,0xFF,0xBF, 0, 0, 0, 0, 0,0xF0,0xFF,0xFF,0xC0, 0,
+ 0,0x50,0xFF,0xFF,0xFF,0xFF,0xFE,0x23, 0, 0, 0, 0,0xF0,0xFF,0xFF,0xC0, 0,
+ 0,0x50,0xFF,0xFF,0xFF,0xFF,0xFF,0x85, 0, 0, 0, 0,0xF0,0xFF,0xFF,0xC0, 0,
+ 0,0x50,0xFF,0xFF,0xFF,0xFF,0xFF,0xE5,0x03, 0, 0, 0,0xF0,0xFF,0xFF,0xC0, 0,
+ 0,0x50,0xFF,0xFF,0xFF,0xFC,0xFF,0xFF,0x4A, 0, 0, 0,0xF0,0xFF,0xFF,0xC0, 0,
+ 0,0x50,0xFF,0xFF,0xFF,0xB4,0xFF,0xFF,0xAD, 0, 0, 0,0xF0,0xFF,0xFF,0xC0, 0,
+ 0,0x50,0xFF,0xFF,0xFF,0x63,0xED,0xFF,0xFA,0x16, 0, 0,0xF0,0xFF,0xFF,0xC0, 0,
+ 0,0x50,0xFF,0xFF,0xFF,0x5C,0x92,0xFF,0xFF,0x73, 0, 0,0xF0,0xFF,0xFF,0xC0, 0,
+ 0,0x50,0xFF,0xFF,0xFF,0x5C,0x2E,0xFF,0xFF,0xD6, 0, 0,0xF0,0xFF,0xFF,0xC0, 0,
+ 0,0x50,0xFF,0xFF,0xFF,0x5C, 0,0xCB,0xFF,0xFF,0x38, 0,0xF0,0xFF,0xFF,0xC0, 0,
+ 0,0x50,0xFF,0xFF,0xFF,0x5C, 0,0x68,0xFF,0xFF,0x9B, 0,0xF0,0xFF,0xFF,0xC0, 0,
+ 0,0x50,0xFF,0xFF,0xFF,0x5C, 0,0x0E,0xF5,0xFF,0xF2,0x0B,0xF0,0xFF,0xFF,0xC0, 0,
+ 0,0x50,0xFF,0xFF,0xFF,0x5C, 0, 0,0xA1,0xFF,0xFF,0x61,0xF0,0xFF,0xFF,0xC0, 0,
+ 0,0x50,0xFF,0xFF,0xFF,0x5C, 0, 0,0x3E,0xFF,0xFF,0xC3,0xF0,0xFF,0xFF,0xC0, 0,
+ 0,0x50,0xFF,0xFF,0xFF,0x5C, 0, 0, 0,0xD9,0xFF,0xFF,0xFD,0xFF,0xFF,0xC0, 0,
+ 0,0x50,0xFF,0xFF,0xFF,0x5C, 0, 0, 0,0x77,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0, 0,
+ 0,0x50,0xFF,0xFF,0xFF,0x5C, 0, 0, 0,0x18,0xFB,0xFF,0xFF,0xFF,0xFF,0xC0, 0,
+ 0,0x50,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0,0xB0,0xFF,0xFF,0xFF,0xFF,0xC0, 0,
+ 0,0x50,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0,0x4D,0xFF,0xFF,0xFF,0xFF,0xC0, 0,
+ 0,0x50,0xFF,0xFF,0xFF,0x5C, 0, 0, 0, 0,0x03,0xE5,0xFF,0xFF,0xFF,0xC0, 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, 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, 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,
+// 'O'
+ 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x4B,0xAA,0xE1,0xF8,0xEC,0xCA,0x7B,0x12, 0, 0, 0, 0,
+ 0, 0, 0,0x07,0xAD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE8,0x3F, 0, 0, 0,
+ 0, 0, 0,0xAA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF1,0x2C, 0, 0,
+ 0, 0,0x4B,0xFF,0xFF,0xFF,0xFB,0x65,0x0C,0x2A,0xC7,0xFF,0xFF,0xFF,0xBE, 0, 0,
+ 0, 0,0xC3,0xFF,0xFF,0xFF,0x8C, 0, 0, 0,0x1C,0xF8,0xFF,0xFF,0xFF,0x36, 0,
+ 0,0x18,0xFD,0xFF,0xFF,0xFF,0x2A, 0, 0, 0, 0,0xB3,0xFF,0xFF,0xFF,0x8A, 0,
+ 0,0x54,0xFF,0xFF,0xFF,0xF0, 0, 0, 0, 0, 0,0x7A,0xFF,0xFF,0xFF,0xC7, 0,
+ 0,0x7E,0xFF,0xFF,0xFF,0xCD, 0, 0, 0, 0, 0,0x56,0xFF,0xFF,0xFF,0xF1, 0,
+ 0,0x9B,0xFF,0xFF,0xFF,0xB7, 0, 0, 0, 0, 0,0x40,0xFF,0xFF,0xFF,0xFF,0x0F,
+ 0,0xA8,0xFF,0xFF,0xFF,0xAD, 0, 0, 0, 0, 0,0x37,0xFF,0xFF,0xFF,0xFF,0x1B,
+ 0,0xB1,0xFF,0xFF,0xFF,0xA9, 0, 0, 0, 0, 0,0x32,0xFF,0xFF,0xFF,0xFF,0x24,
+ 0,0xA8,0xFF,0xFF,0xFF,0xAD, 0, 0, 0, 0, 0,0x37,0xFF,0xFF,0xFF,0xFF,0x1B,
+ 0,0x9B,0xFF,0xFF,0xFF,0xB7, 0, 0, 0, 0, 0,0x40,0xFF,0xFF,0xFF,0xFF,0x0F,
+ 0,0x7E,0xFF,0xFF,0xFF,0xCD, 0, 0, 0, 0, 0,0x56,0xFF,0xFF,0xFF,0xF1, 0,
+ 0,0x54,0xFF,0xFF,0xFF,0xF0, 0, 0, 0, 0, 0,0x7A,0xFF,0xFF,0xFF,0xC7, 0,
+ 0,0x19,0xFD,0xFF,0xFF,0xFF,0x28, 0, 0, 0, 0,0xB2,0xFF,0xFF,0xFF,0x8A, 0,
+ 0, 0,0xC3,0xFF,0xFF,0xFF,0x8A, 0, 0, 0,0x1B,0xF7,0xFF,0xFF,0xFF,0x37, 0,
+ 0, 0,0x4C,0xFF,0xFF,0xFF,0xFA,0x64,0x0B,0x28,0xC6,0xFF,0xFF,0xFF,0xBF, 0, 0,
+ 0, 0, 0,0xAA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF2,0x2C, 0, 0,
+ 0, 0, 0,0x08,0xAD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE8,0x40, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x4C,0xAC,0xE3,0xF9,0xED,0xCB,0x7C,0x12, 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, 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, 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,
+// 'P'
+ 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xB4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFA,0xED,0xD4,0xA9,0x5F,0x0C, 0, 0, 0,
+ 0, 0,0xB4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE6,0x47, 0, 0,
+ 0, 0,0xB4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,0x30, 0,
+ 0, 0,0xB4,0xFF,0xFF,0xFF,0x78, 0,0x04,0x1E,0x71,0xF7,0xFF,0xFF,0xFF,0xB3, 0,
+ 0, 0,0xB4,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0,0x7B,0xFF,0xFF,0xFF,0xF8,0x09,
+ 0, 0,0xB4,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0,0x32,0xFF,0xFF,0xFF,0xFF,0x28,
+ 0, 0,0xB4,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0,0x20,0xFF,0xFF,0xFF,0xFF,0x37,
+ 0, 0,0xB4,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0,0x32,0xFF,0xFF,0xFF,0xFF,0x28,
+ 0, 0,0xB4,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0,0x7B,0xFF,0xFF,0xFF,0xF8,0x09,
+ 0, 0,0xB4,0xFF,0xFF,0xFF,0x78, 0,0x04,0x1D,0x70,0xF7,0xFF,0xFF,0xFF,0xB4, 0,
+ 0, 0,0xB4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF8,0x31, 0,
+ 0, 0,0xB4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE7,0x47, 0, 0,
+ 0, 0,0xB4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFA,0xEF,0xD5,0xA9,0x61,0x0D, 0, 0, 0,
+ 0, 0,0xB4,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xB4,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xB4,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xB4,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xB4,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xB4,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xB4,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xB4,0xFF,0xFF,0xFF,0x78, 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, 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, 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,
+// 'Q'
+ 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x4B,0xAA,0xE1,0xF8,0xEC,0xCA,0x7A,0x11, 0, 0, 0, 0,
+ 0, 0, 0,0x07,0xAD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE6,0x3C, 0, 0, 0,
+ 0, 0, 0,0xAA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xEF,0x28, 0, 0,
+ 0, 0,0x4B,0xFF,0xFF,0xFF,0xFB,0x65,0x0C,0x2A,0xC7,0xFF,0xFF,0xFF,0xB9, 0, 0,
+ 0, 0,0xC3,0xFF,0xFF,0xFF,0x8C, 0, 0, 0,0x1C,0xF8,0xFF,0xFF,0xFF,0x32, 0,
+ 0,0x18,0xFD,0xFF,0xFF,0xFF,0x2A, 0, 0, 0, 0,0xB3,0xFF,0xFF,0xFF,0x86, 0,
+ 0,0x54,0xFF,0xFF,0xFF,0xF0, 0, 0, 0, 0, 0,0x7A,0xFF,0xFF,0xFF,0xC4, 0,
+ 0,0x7E,0xFF,0xFF,0xFF,0xCD, 0, 0, 0, 0, 0,0x56,0xFF,0xFF,0xFF,0xEE, 0,
+ 0,0x9B,0xFF,0xFF,0xFF,0xB7, 0, 0, 0, 0, 0,0x40,0xFF,0xFF,0xFF,0xFF,0x0D,
+ 0,0xA8,0xFF,0xFF,0xFF,0xAD, 0, 0, 0, 0, 0,0x37,0xFF,0xFF,0xFF,0xFF,0x1A,
+ 0,0xB1,0xFF,0xFF,0xFF,0xA9, 0, 0, 0, 0, 0,0x32,0xFF,0xFF,0xFF,0xFF,0x24,
+ 0,0xA8,0xFF,0xFF,0xFF,0xAD, 0, 0, 0, 0, 0,0x37,0xFF,0xFF,0xFF,0xFF,0x1F,
+ 0,0x9B,0xFF,0xFF,0xFF,0xB7, 0, 0, 0, 0, 0,0x40,0xFF,0xFF,0xFF,0xFF,0x13,
+ 0,0x7E,0xFF,0xFF,0xFF,0xCD, 0, 0, 0, 0, 0,0x56,0xFF,0xFF,0xFF,0xF8, 0,
+ 0,0x54,0xFF,0xFF,0xFF,0xF0, 0, 0, 0, 0, 0,0x7A,0xFF,0xFF,0xFF,0xD1, 0,
+ 0,0x19,0xFD,0xFF,0xFF,0xFF,0x28, 0, 0, 0, 0,0xB2,0xFF,0xFF,0xFF,0x99, 0,
+ 0, 0,0xC3,0xFF,0xFF,0xFF,0x8A, 0, 0, 0,0x1B,0xF7,0xFF,0xFF,0xFF,0x4A, 0,
+ 0, 0,0x4C,0xFF,0xFF,0xFF,0xFA,0x64,0x0B,0x28,0xC6,0xFF,0xFF,0xFF,0xDC,0x02, 0,
+ 0, 0, 0,0xAA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x4A, 0, 0,
+ 0, 0, 0,0x07,0xAC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0x6B, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x4C,0xAB,0xE3,0xFA,0xFF,0xFF,0xFF,0xEC,0x2E, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,0x50,0xFE,0xFF,0xFF,0xEE,0x35, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x86,0xFF,0xFF,0xFF,0xEF,0x16, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x02,0xB9,0xFF,0xF3,0x4F, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x12,0xBE,0x2D, 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, 0, 0, 0, 0, 0, 0, 0,
+// 'R'
+ 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+0x1C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF8,0xEB,0xC8,0x94,0x3B, 0, 0, 0, 0, 0,
+0x1C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xA7,0x06, 0, 0, 0,
+0x1C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x94, 0, 0, 0,
+0x1C,0xFF,0xFF,0xFF,0xFF,0x10, 0,0x10,0x42,0xD1,0xFF,0xFF,0xFF,0xFB,0x19, 0, 0,
+0x1C,0xFF,0xFF,0xFF,0xFF,0x10, 0, 0, 0,0x1E,0xFD,0xFF,0xFF,0xFF,0x5A, 0, 0,
+0x1C,0xFF,0xFF,0xFF,0xFF,0x10, 0, 0, 0, 0,0xD8,0xFF,0xFF,0xFF,0x7B, 0, 0,
+0x1C,0xFF,0xFF,0xFF,0xFF,0x10, 0, 0, 0, 0,0xC7,0xFF,0xFF,0xFF,0x87, 0, 0,
+0x1C,0xFF,0xFF,0xFF,0xFF,0x10, 0, 0, 0, 0,0xD9,0xFF,0xFF,0xFF,0x74, 0, 0,
+0x1C,0xFF,0xFF,0xFF,0xFF,0x10, 0, 0, 0,0x20,0xFD,0xFF,0xFF,0xFF,0x3C, 0, 0,
+0x1C,0xFF,0xFF,0xFF,0xFF,0x10, 0,0x10,0x42,0xD2,0xFF,0xFF,0xFF,0xCA,0x01, 0, 0,
+0x1C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xD5,0x1E, 0, 0, 0,
+0x1C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE9,0x60,0x06, 0, 0, 0, 0,
+0x1C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC7,0x07, 0, 0, 0, 0,
+0x1C,0xFF,0xFF,0xFF,0xFF,0x10,0x09,0x64,0xFB,0xFF,0xFF,0xFF,0x7F, 0, 0, 0, 0,
+0x1C,0xFF,0xFF,0xFF,0xFF,0x10, 0, 0,0x73,0xFF,0xFF,0xFF,0xF4,0x17, 0, 0, 0,
+0x1C,0xFF,0xFF,0xFF,0xFF,0x10, 0, 0,0x04,0xDA,0xFF,0xFF,0xFF,0x92, 0, 0, 0,
+0x1C,0xFF,0xFF,0xFF,0xFF,0x10, 0, 0, 0,0x5F,0xFF,0xFF,0xFF,0xF9,0x1F, 0, 0,
+0x1C,0xFF,0xFF,0xFF,0xFF,0x10, 0, 0, 0,0x03,0xDB,0xFF,0xFF,0xFF,0x9E, 0, 0,
+0x1C,0xFF,0xFF,0xFF,0xFF,0x10, 0, 0, 0, 0,0x5F,0xFF,0xFF,0xFF,0xFC,0x27, 0,
+0x1C,0xFF,0xFF,0xFF,0xFF,0x10, 0, 0, 0, 0,0x03,0xDB,0xFF,0xFF,0xFF,0xAA, 0,
+0x1C,0xFF,0xFF,0xFF,0xFF,0x10, 0, 0, 0, 0, 0,0x60,0xFF,0xFF,0xFF,0xFE,0x32,
+ 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, 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, 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,
+// 'S'
+ 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,0x10,0x73,0xBE,0xEA,0xFA,0xEE,0xD8,0xC0,0x86,0x44,0x09, 0, 0,
+ 0, 0, 0,0x42,0xE8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x88, 0, 0,
+ 0, 0,0x2C,0xF5,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x88, 0, 0,
+ 0, 0,0xB3,0xFF,0xFF,0xFF,0xD9,0x4A,0x12,0x10,0x40,0xA6,0xFE,0xFF,0x88, 0, 0,
+ 0,0x09,0xF9,0xFF,0xFF,0xFF,0x2F, 0, 0, 0, 0, 0,0x41,0xE4,0x88, 0, 0,
+ 0,0x22,0xFF,0xFF,0xFF,0xF6, 0, 0, 0, 0, 0, 0, 0,0x20,0x65, 0, 0,
+ 0,0x22,0xFF,0xFF,0xFF,0xFF,0x1F, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0x04,0xF4,0xFF,0xFF,0xFF,0xC4,0x1C, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x98,0xFF,0xFF,0xFF,0xFF,0xF6,0x94,0x35,0x01, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x0F,0xCB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE3,0x85,0x17, 0, 0, 0, 0,
+ 0, 0, 0,0x07,0x82,0xF4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF4,0x6A, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x14,0x77,0xD6,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x79, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,0x28,0x87,0xF5,0xFF,0xFF,0xFF,0xFC,0x26, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x37,0xFA,0xFF,0xFF,0xFF,0x81, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0xAC, 0,
+ 0,0x17,0x85,0x02, 0, 0, 0, 0, 0, 0, 0,0x92,0xFF,0xFF,0xFF,0xAE, 0,
+ 0,0x18,0xFF,0xBA,0x23, 0, 0, 0, 0, 0,0x04,0xD2,0xFF,0xFF,0xFF,0x91, 0,
+ 0,0x18,0xFF,0xFF,0xF8,0x9B,0x43,0x16,0x0A,0x32,0xB0,0xFF,0xFF,0xFF,0xFF,0x49, 0,
+ 0,0x18,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xBF, 0, 0,
+ 0,0x18,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xB8,0x10, 0, 0,
+ 0, 0,0x25,0x64,0xA3,0xCB,0xE0,0xF4,0xFA,0xEE,0xCE,0x99,0x42, 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, 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, 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,
+// 'T'
+ 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0xB8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x30,
+ 0,0xB8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x30,
+ 0,0xB8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x30,
+ 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 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, 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, 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,
+// 'U'
+ 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0x80,0xFF,0xFF,0xFF,0xAC, 0, 0, 0, 0, 0,0x3C,0xFF,0xFF,0xFF,0xF0, 0,
+ 0,0x80,0xFF,0xFF,0xFF,0xAC, 0, 0, 0, 0, 0,0x3C,0xFF,0xFF,0xFF,0xF0, 0,
+ 0,0x80,0xFF,0xFF,0xFF,0xAC, 0, 0, 0, 0, 0,0x3C,0xFF,0xFF,0xFF,0xF0, 0,
+ 0,0x80,0xFF,0xFF,0xFF,0xAC, 0, 0, 0, 0, 0,0x3C,0xFF,0xFF,0xFF,0xF0, 0,
+ 0,0x80,0xFF,0xFF,0xFF,0xAC, 0, 0, 0, 0, 0,0x3C,0xFF,0xFF,0xFF,0xF0, 0,
+ 0,0x80,0xFF,0xFF,0xFF,0xAC, 0, 0, 0, 0, 0,0x3C,0xFF,0xFF,0xFF,0xF0, 0,
+ 0,0x80,0xFF,0xFF,0xFF,0xAC, 0, 0, 0, 0, 0,0x3C,0xFF,0xFF,0xFF,0xF0, 0,
+ 0,0x80,0xFF,0xFF,0xFF,0xAC, 0, 0, 0, 0, 0,0x3C,0xFF,0xFF,0xFF,0xF0, 0,
+ 0,0x80,0xFF,0xFF,0xFF,0xAC, 0, 0, 0, 0, 0,0x3C,0xFF,0xFF,0xFF,0xF0, 0,
+ 0,0x80,0xFF,0xFF,0xFF,0xAC, 0, 0, 0, 0, 0,0x3C,0xFF,0xFF,0xFF,0xF0, 0,
+ 0,0x80,0xFF,0xFF,0xFF,0xAC, 0, 0, 0, 0, 0,0x3C,0xFF,0xFF,0xFF,0xF0, 0,
+ 0,0x80,0xFF,0xFF,0xFF,0xAC, 0, 0, 0, 0, 0,0x3C,0xFF,0xFF,0xFF,0xF0, 0,
+ 0,0x80,0xFF,0xFF,0xFF,0xAC, 0, 0, 0, 0, 0,0x3C,0xFF,0xFF,0xFF,0xF0, 0,
+ 0,0x7E,0xFF,0xFF,0xFF,0xAC, 0, 0, 0, 0, 0,0x3C,0xFF,0xFF,0xFF,0xEE, 0,
+ 0,0x72,0xFF,0xFF,0xFF,0xAF, 0, 0, 0, 0, 0,0x3F,0xFF,0xFF,0xFF,0xE0, 0,
+ 0,0x5A,0xFF,0xFF,0xFF,0xCC, 0, 0, 0, 0, 0,0x5E,0xFF,0xFF,0xFF,0xC9, 0,
+ 0,0x27,0xFF,0xFF,0xFF,0xFB,0x27, 0, 0, 0, 0,0xB6,0xFF,0xFF,0xFF,0x96, 0,
+ 0, 0,0xD2,0xFF,0xFF,0xFF,0xD9,0x43,0x0D,0x23,0x95,0xFF,0xFF,0xFF,0xFF,0x41, 0,
+ 0, 0,0x4E,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xBC, 0, 0,
+ 0, 0, 0,0x6E,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC4,0x15, 0, 0,
+ 0, 0, 0, 0,0x24,0x8B,0xCA,0xED,0xFB,0xF4,0xDE,0xAA,0x54,0x03, 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, 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, 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,
+// 'V'
+ 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+0x13,0xFE,0xFF,0xFF,0xFF,0x1E, 0, 0, 0, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0x88,
+ 0,0xD4,0xFF,0xFF,0xFF,0x55, 0, 0, 0, 0, 0, 0,0xDE,0xFF,0xFF,0xFF,0x4B,
+ 0,0x97,0xFF,0xFF,0xFF,0x8B, 0, 0, 0, 0, 0,0x14,0xFF,0xFF,0xFF,0xFD,0x10,
+ 0,0x5A,0xFF,0xFF,0xFF,0xC1, 0, 0, 0, 0, 0,0x4B,0xFF,0xFF,0xFF,0xD0, 0,
+ 0,0x1D,0xFF,0xFF,0xFF,0xF3,0x02, 0, 0, 0, 0,0x81,0xFF,0xFF,0xFF,0x93, 0,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0x2D, 0, 0, 0, 0,0xB8,0xFF,0xFF,0xFF,0x56, 0,
+ 0, 0,0xA3,0xFF,0xFF,0xFF,0x63, 0, 0, 0, 0,0xED,0xFF,0xFF,0xFF,0x19, 0,
+ 0, 0,0x66,0xFF,0xFF,0xFF,0x99, 0, 0, 0,0x25,0xFF,0xFF,0xFF,0xDB, 0, 0,
+ 0, 0,0x28,0xFF,0xFF,0xFF,0xCF, 0, 0, 0,0x5B,0xFF,0xFF,0xFF,0x9E, 0, 0,
+ 0, 0, 0,0xEA,0xFF,0xFF,0xFB,0x09, 0, 0,0x92,0xFF,0xFF,0xFF,0x60, 0, 0,
+ 0, 0, 0,0xAE,0xFF,0xFF,0xFF,0x3B, 0, 0,0xC8,0xFF,0xFF,0xFF,0x23, 0, 0,
+ 0, 0, 0,0x71,0xFF,0xFF,0xFF,0x71, 0,0x06,0xF8,0xFF,0xFF,0xE6, 0, 0, 0,
+ 0, 0, 0,0x34,0xFF,0xFF,0xFF,0xA7, 0,0x35,0xFF,0xFF,0xFF,0xA8, 0, 0, 0,
+ 0, 0, 0,0x03,0xF3,0xFF,0xFF,0xDD, 0,0x6C,0xFF,0xFF,0xFF,0x6B, 0, 0, 0,
+ 0, 0, 0, 0,0xBA,0xFF,0xFF,0xFF,0x13,0xA2,0xFF,0xFF,0xFF,0x2E, 0, 0, 0,
+ 0, 0, 0, 0,0x7C,0xFF,0xFF,0xFF,0x49,0xD9,0xFF,0xFF,0xEF,0x01, 0, 0, 0,
+ 0, 0, 0, 0,0x3F,0xFF,0xFF,0xFF,0x8F,0xFE,0xFF,0xFF,0xB3, 0, 0, 0, 0,
+ 0, 0, 0, 0,0x08,0xF9,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF,0x76, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0xC5,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x38, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x88,0xFF,0xFF,0xFF,0xFF,0xFF,0xF6,0x05, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x4B,0xFF,0xFF,0xFF,0xFF,0xFF,0xBE, 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, 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, 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,
+// 'W'
+ 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+0xF0,0xFF,0xFF,0xB4, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x42,0xFF,0xFF,0xFF,
+0xD1,0xFF,0xFF,0xCD, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x56,0xFF,0xFF,0xFF,
+0xB1,0xFF,0xFF,0xE7, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x6A,0xFF,0xFF,0xFF,
+0x91,0xFF,0xFF,0xFD,0x03, 0, 0, 0, 0, 0, 0, 0, 0,0x7E,0xFF,0xFF,0xFF,
+0x71,0xFF,0xFF,0xFF,0x1A, 0, 0, 0, 0, 0, 0, 0, 0,0x92,0xFF,0xFF,0xEE,
+0x51,0xFF,0xFF,0xFF,0x33, 0,0x16,0xFF,0xFF,0xFF,0x92, 0, 0,0xA6,0xFF,0xFF,0xD1,
+0x32,0xFF,0xFF,0xFF,0x4D, 0,0x45,0xFF,0xFF,0xFF,0xC7, 0, 0,0xBA,0xFF,0xFF,0xB3,
+0x12,0xFF,0xFF,0xFF,0x66, 0,0x72,0xFF,0xFF,0xFF,0xF7,0x04, 0,0xCE,0xFF,0xFF,0x96,
+ 0,0xF1,0xFF,0xFF,0x7F, 0,0xA0,0xFF,0xFF,0xFF,0xFF,0x31, 0,0xE2,0xFF,0xFF,0x78,
+ 0,0xD2,0xFF,0xFF,0x99, 0,0xCE,0xFF,0xF9,0xFF,0xFF,0x66, 0,0xF6,0xFF,0xFF,0x5B,
+ 0,0xB2,0xFF,0xFF,0xB2,0x03,0xF7,0xFF,0xA7,0xFF,0xFF,0x9B,0x09,0xFF,0xFF,0xFF,0x3D,
+ 0,0x93,0xFF,0xFF,0xCC,0x29,0xFF,0xFF,0x59,0xE4,0xFF,0xD0,0x1E,0xFF,0xFF,0xFF,0x20,
+ 0,0x73,0xFF,0xFF,0xE5,0x57,0xFF,0xFF,0x27,0xAE,0xFF,0xFB,0x3B,0xFF,0xFF,0xFD,0x05,
+ 0,0x53,0xFF,0xFF,0xFC,0x87,0xFF,0xF2,0x01,0x78,0xFF,0xFF,0x80,0xFF,0xFF,0xE5, 0,
+ 0,0x33,0xFF,0xFF,0xFF,0xCA,0xFF,0xC1, 0,0x41,0xFF,0xFF,0xC9,0xFF,0xFF,0xC7, 0,
+ 0,0x13,0xFF,0xFF,0xFF,0xFD,0xFF,0x8E, 0,0x0D,0xFD,0xFF,0xFD,0xFF,0xFF,0xAA, 0,
+ 0, 0,0xF3,0xFF,0xFF,0xFF,0xFF,0x5C, 0, 0,0xD5,0xFF,0xFF,0xFF,0xFF,0x8C, 0,
+ 0, 0,0xD4,0xFF,0xFF,0xFF,0xFF,0x29, 0, 0,0x9E,0xFF,0xFF,0xFF,0xFF,0x6F, 0,
+ 0, 0,0xB4,0xFF,0xFF,0xFF,0xF4,0x02, 0, 0,0x68,0xFF,0xFF,0xFF,0xFF,0x51, 0,
+ 0, 0,0x94,0xFF,0xFF,0xFF,0xC3, 0, 0, 0,0x32,0xFF,0xFF,0xFF,0xFF,0x34, 0,
+ 0, 0,0x74,0xFF,0xFF,0xFF,0x91, 0, 0, 0,0x04,0xF6,0xFF,0xFF,0xFF,0x16, 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, 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, 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,
+// 'X'
+ 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+0x2D,0xFC,0xFF,0xFF,0xFC,0x2C, 0, 0, 0, 0, 0, 0,0xB3,0xFF,0xFF,0xFF,0x9D,
+ 0,0x94,0xFF,0xFF,0xFF,0xBC, 0, 0, 0, 0, 0,0x46,0xFF,0xFF,0xFF,0xF1,0x17,
+ 0,0x12,0xEC,0xFF,0xFF,0xFF,0x4F, 0, 0, 0,0x04,0xD6,0xFF,0xFF,0xFF,0x74, 0,
+ 0, 0,0x6A,0xFF,0xFF,0xFF,0xDB,0x06, 0, 0,0x70,0xFF,0xFF,0xFF,0xDA,0x06, 0,
+ 0, 0,0x03,0xD1,0xFF,0xFF,0xFF,0x75, 0,0x14,0xEF,0xFF,0xFF,0xFF,0x4B, 0, 0,
+ 0, 0, 0,0x3F,0xFF,0xFF,0xFF,0xF1,0x17,0x98,0xFF,0xFF,0xFF,0xB7, 0, 0, 0,
+ 0, 0, 0, 0,0xAA,0xFF,0xFF,0xFF,0xBC,0xFD,0xFF,0xFF,0xFA,0x28, 0, 0, 0,
+ 0, 0, 0, 0,0x1E,0xF6,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8E, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xEA,0x0F, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x09,0xE1,0xFF,0xFF,0xFF,0xFF,0x65, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x95,0xFF,0xFF,0xFF,0xFC,0x14, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x20,0xF7,0xFF,0xFF,0xFF,0xFF,0x93, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0xAD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0x2B, 0, 0, 0, 0,
+ 0, 0, 0, 0,0x42,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xBB, 0, 0, 0, 0,
+ 0, 0, 0,0x03,0xD3,0xFF,0xFF,0xFF,0x89,0xEF,0xFF,0xFF,0xFF,0x50, 0, 0, 0,
+ 0, 0, 0,0x6C,0xFF,0xFF,0xFF,0xDA,0x06,0x6F,0xFF,0xFF,0xFF,0xDC,0x07, 0, 0,
+ 0, 0,0x13,0xEE,0xFF,0xFF,0xFF,0x4D, 0,0x04,0xD6,0xFF,0xFF,0xFF,0x78, 0, 0,
+ 0, 0,0x96,0xFF,0xFF,0xFF,0xB9, 0, 0, 0,0x45,0xFF,0xFF,0xFF,0xF3,0x19, 0,
+ 0,0x2E,0xFC,0xFF,0xFF,0xFB,0x2A, 0, 0, 0, 0,0xB0,0xFF,0xFF,0xFF,0xA1, 0,
+ 0,0xBF,0xFF,0xFF,0xFF,0x91, 0, 0, 0, 0, 0,0x23,0xF8,0xFF,0xFF,0xFE,0x36,
+0x55,0xFF,0xFF,0xFF,0xEC,0x11, 0, 0, 0, 0, 0, 0,0x86,0xFF,0xFF,0xFF,0xC8,
+ 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, 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, 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,
+// 'Y'
+ 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+0xA3,0xFF,0xFF,0xFF,0xD7,0x02, 0, 0, 0, 0, 0, 0,0x67,0xFF,0xFF,0xFF,0xF8,
+0x23,0xFB,0xFF,0xFF,0xFF,0x56, 0, 0, 0, 0, 0,0x04,0xDF,0xFF,0xFF,0xFF,0x92,
+ 0,0x9C,0xFF,0xFF,0xFF,0xD2,0x01, 0, 0, 0, 0,0x61,0xFF,0xFF,0xFF,0xF6,0x19,
+ 0,0x1F,0xF9,0xFF,0xFF,0xFF,0x50, 0, 0, 0,0x03,0xDA,0xFF,0xFF,0xFF,0x8C, 0,
+ 0, 0,0x95,0xFF,0xFF,0xFF,0xCC, 0, 0, 0,0x5B,0xFF,0xFF,0xFF,0xF3,0x15, 0,
+ 0, 0,0x1A,0xF7,0xFF,0xFF,0xFF,0x49, 0,0x02,0xD6,0xFF,0xFF,0xFF,0x85, 0, 0,
+ 0, 0, 0,0x8F,0xFF,0xFF,0xFF,0xC6, 0,0x56,0xFF,0xFF,0xFF,0xF0,0x11, 0, 0,
+ 0, 0, 0,0x16,0xF4,0xFF,0xFF,0xFF,0x43,0xD1,0xFF,0xFF,0xFF,0x7E, 0, 0, 0,
+ 0, 0, 0, 0,0x88,0xFF,0xFF,0xFF,0xE8,0xFF,0xFF,0xFF,0xED,0x0E, 0, 0, 0,
+ 0, 0, 0, 0,0x13,0xF2,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x82,0xFF,0xFF,0xFF,0xFF,0xFF,0xE9,0x0B, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x0F,0xEE,0xFF,0xFF,0xFF,0xFF,0x71, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x7F,0xFF,0xFF,0xFF,0xEA,0x08, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xD0, 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, 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, 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,
+// 'Z'
+ 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3C,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3C,
+ 0,0x10,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3C,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x37,0xFD,0xFF,0xFF,0xFF,0xFF,0x2C,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,0x07,0xD5,0xFF,0xFF,0xFF,0xFF,0x98, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,0x85,0xFF,0xFF,0xFF,0xFF,0xDE,0x0C, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,0x32,0xFB,0xFF,0xFF,0xFF,0xFE,0x3F, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x05,0xD0,0xFF,0xFF,0xFF,0xFF,0x8F, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x7F,0xFF,0xFF,0xFF,0xFF,0xD8,0x09, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x2D,0xF9,0xFF,0xFF,0xFF,0xFC,0x37, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x03,0xCB,0xFF,0xFF,0xFF,0xFF,0x86, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x78,0xFF,0xFF,0xFF,0xFF,0xD2,0x06, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,0x28,0xF8,0xFF,0xFF,0xFF,0xFA,0x31, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0x02,0xC6,0xFF,0xFF,0xFF,0xFF,0x7D, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0x71,0xFF,0xFF,0xFF,0xFF,0xCB,0x04, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x23,0xF5,0xFF,0xFF,0xFF,0xF8,0x2A, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0x01,0xC0,0xFF,0xFF,0xFF,0xFF,0x74, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0x50,0xFF,0xFF,0xFF,0xFF,0xC4,0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0x60,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x70,
+ 0,0x60,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x70,
+ 0,0x60,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x70,
+ 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x2C, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x2C, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x2C, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x2C, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x2C, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x08,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x2C, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0x31,0xFF,0xFF,0xEC,0x0A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xBA,0xFF,0xFF,0x6D, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x44,0xFF,0xFF,0xE0,0x04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0xCC,0xFF,0xFF,0x5A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0x56,0xFF,0xFF,0xD0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0x03,0xDC,0xFF,0xFF,0x48, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,0x69,0xFF,0xFF,0xBE, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,0x08,0xE9,0xFF,0xFF,0x35, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x7C,0xFF,0xFF,0xAC, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x11,0xF3,0xFF,0xFD,0x25, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x8E,0xFF,0xFF,0x99, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x1D,0xFA,0xFF,0xF8,0x17, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xA1,0xFF,0xFF,0x86, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x2B,0xFE,0xFF,0xEF,0x0D, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,0xB4,0xFF,0xFF,0x74, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,0x3D,0xFF,0xFF,0xE4,0x06, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,0xC6,0xFF,0xFF,0x61, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,0x50,0xFF,0xFF,0xD6,0x01, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,0x01,0xD7,0xFF,0xFF,0x4E, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x62,0xFF,0xFF,0xC5, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x06,0xE5,0xFF,0xFF,0x3C, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x75,0xFF,0xFF,0xB2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x0E,0xF0,0xFF,0xFE,0x2B, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x87,0xFF,0xFF,0xA0, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,0xB4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,0xB4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,0xB4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x48,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x48,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x48,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x48,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x48,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x48,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x48,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x48,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x48,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x48,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x48,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x48,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x48,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x48,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x48,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x48,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x48,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x48,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x48,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x48,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,0xB4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,0xB4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7C, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,0xB4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7C, 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, 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, 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,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x63,0xFF,0xFF,0xFF,0xD0,0x09, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x31,0xF7,0xFF,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,0x11,0xDE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x66, 0, 0, 0, 0,
+ 0, 0, 0,0x01,0xB3,0xFF,0xFF,0xFF,0xE3,0xFF,0xFF,0xFF,0xF8,0x33, 0, 0, 0,
+ 0, 0, 0,0x7C,0xFF,0xFF,0xFF,0xCA,0x11,0x6D,0xFE,0xFF,0xFF,0xDF,0x12, 0, 0,
+ 0, 0,0x44,0xFD,0xFF,0xFF,0xC4,0x0E, 0, 0,0x64,0xFD,0xFF,0xFF,0xB6,0x01, 0,
+ 0,0x1C,0xEA,0xFF,0xFF,0xBE,0x0B, 0, 0, 0, 0,0x5B,0xFC,0xFF,0xFF,0x7E, 0,
+0x05,0xC7,0xFF,0xFF,0xB7,0x09, 0, 0, 0, 0, 0, 0,0x53,0xFA,0xFF,0xFD,0x47,
+ 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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,
+ 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, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+// '`'
+ 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, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x04,0xA7,0xFF,0xFF,0xFA,0x3B, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0x02,0x9E,0xFF,0xFF,0xE7,0x1A, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,0x01,0x95,0xFF,0xFF,0xC8,0x07, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x8B,0xFF,0xFF,0x9C, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x82,0xFF,0xFF,0x69, 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, 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, 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, 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, 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, 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, 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,
+ 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+// 'a'
+ 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, 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, 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, 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, 0, 0,0x30,0x7C,0xB3,0xD0,0xE6,0xFA,0xF3,0xE0,0xB1,0x60,0x07, 0, 0, 0,
+ 0, 0,0x18,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xD0,0x1A, 0, 0,
+ 0, 0,0x18,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xB7, 0, 0,
+ 0, 0,0x17,0xD3,0x8A,0x51,0x31,0x1B,0x06,0x13,0x59,0xF0,0xFF,0xFF,0xFF,0x27, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x83,0xFF,0xFF,0xFF,0x69, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x70,0xFF,0xFF,0xFF,0x93, 0,
+ 0, 0, 0,0x0D,0x6A,0xB1,0xDB,0xF2,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xA3, 0,
+ 0, 0,0x40,0xEB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xAE, 0,
+ 0,0x18,0xF0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xB0, 0,
+ 0,0x75,0xFF,0xFF,0xFF,0xFF,0xAA,0x38,0x11,0x03, 0,0x7B,0xFF,0xFF,0xFF,0xB0, 0,
+ 0,0xA0,0xFF,0xFF,0xFF,0xE4,0x01, 0, 0, 0, 0,0xA0,0xFF,0xFF,0xFF,0xB0, 0,
+ 0,0xA2,0xFF,0xFF,0xFF,0xD5, 0, 0, 0, 0,0x19,0xF3,0xFF,0xFF,0xFF,0xB0, 0,
+ 0,0x77,0xFF,0xFF,0xFF,0xFF,0x7E,0x14,0x11,0x48,0xD7,0xFF,0xFF,0xFF,0xFF,0xB0, 0,
+ 0,0x1C,0xF7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0xFF,0xFF,0xFF,0xB0, 0,
+ 0, 0,0x57,0xF9,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xD6,0x87,0xFF,0xFF,0xFF,0xB0, 0,
+ 0, 0, 0,0x29,0x99,0xDB,0xF7,0xF4,0xCF,0x77,0x08,0x70,0xFF,0xFF,0xFF,0xB0, 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, 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, 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,
+// 'b'
+ 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, 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,0xE0,0xFF,0xFF,0xFF,0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0x44,0x1A,0x9B,0xE6,0xF8,0xDE,0x94,0x19, 0, 0, 0,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0x6B,0xEA,0xFF,0xFF,0xFF,0xFF,0xFF,0xED,0x2E, 0, 0,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0xF7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xDE,0x08, 0,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0xFF,0xB7,0x21,0x0E,0x7D,0xFF,0xFF,0xFF,0xFF,0x6A, 0,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0xEA,0x0C, 0, 0, 0,0xAB,0xFF,0xFF,0xFF,0xC1, 0,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0x92, 0, 0, 0, 0,0x47,0xFF,0xFF,0xFF,0xF5,0x02,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0x5E, 0, 0, 0, 0,0x13,0xFF,0xFF,0xFF,0xFF,0x1A,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0x49, 0, 0, 0, 0, 0,0xFD,0xFF,0xFF,0xFF,0x29,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0x48, 0, 0, 0, 0, 0,0xFD,0xFF,0xFF,0xFF,0x28,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0x5E, 0, 0, 0, 0,0x13,0xFF,0xFF,0xFF,0xFF,0x1B,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0x92, 0, 0, 0, 0,0x46,0xFF,0xFF,0xFF,0xF5,0x02,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0xEA,0x0C, 0, 0, 0,0xAB,0xFF,0xFF,0xFF,0xC2, 0,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0xFF,0xB7,0x20,0x0D,0x7C,0xFF,0xFF,0xFF,0xFF,0x6C, 0,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0xF3,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE1,0x09, 0,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0x6A,0xEB,0xFF,0xFF,0xFF,0xFF,0xFF,0xF0,0x33, 0, 0,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0x44,0x1D,0x9B,0xE3,0xF9,0xE3,0x9B,0x1E, 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, 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, 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,
+// 'c'
+ 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, 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, 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, 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, 0, 0, 0, 0, 0,0x3F,0x9C,0xD8,0xF1,0xF7,0xDE,0xC2,0x88,0x33, 0, 0,
+ 0, 0, 0, 0,0x0F,0xB2,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x08, 0,
+ 0, 0, 0,0x08,0xCD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x08, 0,
+ 0, 0, 0,0x8A,0xFF,0xFF,0xFF,0xFF,0xA0,0x2F,0x07,0x0B,0x2C,0x70,0xCF,0x07, 0,
+ 0, 0,0x0F,0xF4,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x50,0xFF,0xFF,0xFF,0xF4,0x0D, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x82,0xFF,0xFF,0xFF,0xB9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x97,0xFF,0xFF,0xFF,0x9B, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x97,0xFF,0xFF,0xFF,0x9A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x83,0xFF,0xFF,0xFF,0xB7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x52,0xFF,0xFF,0xFF,0xF2,0x0B, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x11,0xF6,0xFF,0xFF,0xFF,0x8A, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0x8F,0xFF,0xFF,0xFF,0xFF,0x9B,0x2D,0x06,0x13,0x30,0x6B,0xCC,0x07, 0,
+ 0, 0, 0,0x0A,0xD2,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x08, 0,
+ 0, 0, 0, 0,0x13,0xBA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x08, 0,
+ 0, 0, 0, 0, 0, 0,0x45,0xA0,0xDB,0xF3,0xF7,0xE0,0xC5,0x83,0x2E, 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, 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, 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,
+// 'd'
+ 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, 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, 0, 0,0xCC,0xFF,0xFF,0xFF,0x54, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xCC,0xFF,0xFF,0xFF,0x54, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xCC,0xFF,0xFF,0xFF,0x54, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xCC,0xFF,0xFF,0xFF,0x54, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xCC,0xFF,0xFF,0xFF,0x54, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xCC,0xFF,0xFF,0xFF,0x54, 0,
+ 0, 0, 0, 0,0x5D,0xC1,0xEF,0xF4,0xC6,0x55, 0,0xCC,0xFF,0xFF,0xFF,0x54, 0,
+ 0, 0,0x02,0xA5,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x88,0xCC,0xFF,0xFF,0xFF,0x54, 0,
+ 0, 0,0x72,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xFF,0xFF,0x54, 0,
+ 0,0x06,0xEE,0xFF,0xFF,0xFF,0xD0,0x2D,0x0A,0x62,0xFA,0xFF,0xFF,0xFF,0xFF,0x54, 0,
+ 0,0x4B,0xFF,0xFF,0xFF,0xFB,0x23, 0, 0, 0,0x83,0xFF,0xFF,0xFF,0xFF,0x54, 0,
+ 0,0x81,0xFF,0xFF,0xFF,0xBA, 0, 0, 0, 0,0x1D,0xFF,0xFF,0xFF,0xFF,0x54, 0,
+ 0,0xA3,0xFF,0xFF,0xFF,0x86, 0, 0, 0, 0, 0,0xE8,0xFF,0xFF,0xFF,0x54, 0,
+ 0,0xB1,0xFF,0xFF,0xFF,0x71, 0, 0, 0, 0, 0,0xD2,0xFF,0xFF,0xFF,0x54, 0,
+ 0,0xB2,0xFF,0xFF,0xFF,0x70, 0, 0, 0, 0, 0,0xD2,0xFF,0xFF,0xFF,0x54, 0,
+ 0,0xA3,0xFF,0xFF,0xFF,0x86, 0, 0, 0, 0, 0,0xE8,0xFF,0xFF,0xFF,0x54, 0,
+ 0,0x80,0xFF,0xFF,0xFF,0xBA, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0xFF,0x54, 0,
+ 0,0x4A,0xFF,0xFF,0xFF,0xFB,0x23, 0, 0, 0,0x83,0xFF,0xFF,0xFF,0xFF,0x54, 0,
+ 0,0x06,0xEE,0xFF,0xFF,0xFF,0xCF,0x2C,0x09,0x61,0xFA,0xFF,0xFF,0xFF,0xFF,0x54, 0,
+ 0, 0,0x73,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF4,0xFF,0xFF,0xFF,0x54, 0,
+ 0, 0,0x02,0xAA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x87,0xCC,0xFF,0xFF,0xFF,0x54, 0,
+ 0, 0, 0,0x01,0x64,0xC9,0xF3,0xF2,0xC5,0x57, 0,0xCC,0xFF,0xFF,0xFF,0x54, 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, 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, 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,
+// 'e'
+ 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, 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, 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, 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, 0, 0, 0,0x01,0x55,0xAC,0xE2,0xF8,0xF1,0xD5,0x94,0x2C, 0, 0, 0, 0,
+ 0, 0, 0,0x1A,0xC8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0x83, 0, 0, 0,
+ 0, 0,0x10,0xDD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x83, 0, 0,
+ 0, 0,0x9F,0xFF,0xFF,0xFF,0xEC,0x53,0x0A,0x13,0x6B,0xF9,0xFF,0xFF,0xFD,0x30, 0,
+ 0,0x1B,0xFB,0xFF,0xFF,0xFF,0x52, 0, 0, 0, 0,0x83,0xFF,0xFF,0xFF,0xA0, 0,
+ 0,0x64,0xFF,0xFF,0xFF,0xDE, 0, 0, 0, 0, 0,0x1D,0xFF,0xFF,0xFF,0xEB, 0,
+ 0,0x96,0xFF,0xFF,0xFF,0xA9, 0, 0, 0, 0, 0,0x01,0xF7,0xFF,0xFF,0xFF,0x1F,
+ 0,0xAA,0xFF,0xFF,0xFF,0xFE,0xFC,0xFC,0xFD,0xFE,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0x34,
+ 0,0xAB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x42,
+ 0,0x99,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x44,
+ 0,0x6B,0xFF,0xFF,0xFF,0x93, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0x24,0xFE,0xFF,0xFF,0xE2,0x0D, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xAC,0xFF,0xFF,0xFF,0xD2,0x56,0x19,0x04,0x0C,0x22,0x39,0x68,0xA9,0x8D, 0,
+ 0, 0,0x17,0xE2,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x9C, 0,
+ 0, 0, 0,0x1D,0xC5,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x9C, 0,
+ 0, 0, 0, 0, 0,0x46,0x9D,0xD6,0xEF,0xFB,0xEC,0xD8,0xC0,0x89,0x48,0x0C, 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, 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, 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,
+// 'f'
+ 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, 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,0x0D,0x7D,0xC7,0xEC,0xFA,0xFF,0xFF,0xFF,0x54, 0,
+ 0, 0, 0, 0, 0, 0,0x06,0xCF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x54, 0,
+ 0, 0, 0, 0, 0, 0,0x58,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x54, 0,
+ 0, 0, 0, 0, 0, 0,0x94,0xFF,0xFF,0xFF,0xC5,0x16, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xAA,0xFF,0xFF,0xFF,0x7E, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xB0,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x88,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x54, 0,
+ 0, 0,0x88,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x54, 0,
+ 0, 0,0x88,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x54, 0,
+ 0, 0, 0, 0, 0, 0,0xB0,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xB0,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xB0,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xB0,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xB0,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xB0,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xB0,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xB0,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xB0,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xB0,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xB0,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xB0,0xFF,0xFF,0xFF,0x78, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xB0,0xFF,0xFF,0xFF,0x78, 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, 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, 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,
+// 'g'
+ 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, 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, 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, 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, 0, 0, 0,0x36,0xAD,0xE9,0xF7,0xD9,0x86,0x0D,0xA0,0xFF,0xFF,0xFF,0x84, 0,
+ 0, 0, 0,0x60,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0xD8,0xB2,0xFF,0xFF,0xFF,0x84, 0,
+ 0, 0,0x33,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x84, 0,
+ 0, 0,0xBC,0xFF,0xFF,0xFF,0xE6,0x40,0x09,0x4F,0xF2,0xFF,0xFF,0xFF,0xFF,0x84, 0,
+ 0,0x1C,0xFE,0xFF,0xFF,0xFF,0x4C, 0, 0, 0,0x6A,0xFF,0xFF,0xFF,0xFF,0x84, 0,
+ 0,0x59,0xFF,0xFF,0xFF,0xE3,0x02, 0, 0, 0,0x0D,0xF4,0xFF,0xFF,0xFF,0x84, 0,
+ 0,0x82,0xFF,0xFF,0xFF,0xAC, 0, 0, 0, 0, 0,0xC7,0xFF,0xFF,0xFF,0x84, 0,
+ 0,0x93,0xFF,0xFF,0xFF,0x94, 0, 0, 0, 0, 0,0xAD,0xFF,0xFF,0xFF,0x84, 0,
+ 0,0x96,0xFF,0xFF,0xFF,0x93, 0, 0, 0, 0, 0,0xAD,0xFF,0xFF,0xFF,0x84, 0,
+ 0,0x88,0xFF,0xFF,0xFF,0xAC, 0, 0, 0, 0, 0,0xC6,0xFF,0xFF,0xFF,0x84, 0,
+ 0,0x63,0xFF,0xFF,0xFF,0xE3,0x02, 0, 0, 0,0x0C,0xF4,0xFF,0xFF,0xFF,0x84, 0,
+ 0,0x28,0xFF,0xFF,0xFF,0xFF,0x4C, 0, 0, 0,0x68,0xFF,0xFF,0xFF,0xFF,0x84, 0,
+ 0, 0,0xCB,0xFF,0xFF,0xFF,0xE5,0x3F,0x08,0x4E,0xF1,0xFF,0xFF,0xFF,0xFF,0x84, 0,
+ 0, 0,0x41,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x84, 0,
+ 0, 0, 0,0x70,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xDD,0xB2,0xFF,0xFF,0xFF,0x84, 0,
+ 0, 0, 0, 0,0x3C,0xB1,0xEB,0xF9,0xDF,0x92,0x12,0xA4,0xFF,0xFF,0xFF,0x7D, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xC2,0xFF,0xFF,0xFF,0x6B, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x1F,0xF6,0xFF,0xFF,0xFF,0x3F, 0,
+ 0, 0, 0,0xC7,0x7B,0x3E,0x22,0x0A,0x13,0x47,0xD3,0xFF,0xFF,0xFF,0xED,0x09, 0,
+ 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x76, 0, 0,
+ 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x93,0x01, 0, 0,
+ 0, 0, 0,0x28,0x7B,0xB9,0xD8,0xEF,0xFB,0xEE,0xCD,0x94,0x34, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+// 'h'
+ 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, 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,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0x90,0x0E,0x89,0xDC,0xF8,0xE9,0xA6,0x23, 0, 0, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0x97,0xD0,0xFF,0xFF,0xFF,0xFF,0xFF,0xEB,0x1F, 0, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0xF2,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xA1, 0, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0xFF,0xA6,0x15,0x1B,0xB5,0xFF,0xFF,0xFF,0xF1,0x01, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0xF3,0x0C, 0, 0,0x2C,0xFF,0xFF,0xFF,0xFF,0x1A, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0xB2, 0, 0, 0,0x04,0xFE,0xFF,0xFF,0xFF,0x29, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0x98, 0, 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0x2C, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0x2C, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0x2C, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0x2C, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0x2C, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0x2C, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0x2C, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0x2C, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0x2C, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0x2C, 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, 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, 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,
+// 'i'
+ 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, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x58, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x58, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x58, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x58, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x58, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0xE0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x58, 0, 0, 0, 0, 0,
+ 0, 0, 0,0xE0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x58, 0, 0, 0, 0, 0,
+ 0, 0, 0,0xE0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x58, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x58, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x58, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x58, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x58, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x58, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x58, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x58, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x58, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x58, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xD0,0xFF,0xFF,0xFF,0x58, 0, 0, 0, 0, 0,
+ 0, 0,0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,
+ 0, 0,0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,
+ 0, 0,0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,
+ 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, 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, 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,
+// 'j'
+ 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, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0xFF,0x08, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0xFF,0x08, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0xFF,0x08, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0xFF,0x08, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0xFF,0x08, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0x50,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x08, 0, 0, 0, 0,
+ 0, 0, 0,0x50,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x08, 0, 0, 0, 0,
+ 0, 0, 0,0x50,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x08, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0xFF,0x08, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0xFF,0x08, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0xFF,0x08, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0xFF,0x08, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0xFF,0x08, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0xFF,0x08, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0xFF,0x08, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0xFF,0x08, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0xFF,0x08, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0xFF,0x08, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0xFF,0x08, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0xFF,0x08, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x1D,0xFF,0xFF,0xFF,0xFF,0x05, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x2D,0xFF,0xFF,0xFF,0xFA, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x61,0xFF,0xFF,0xFF,0xE0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x09,0x42,0xE3,0xFF,0xFF,0xFF,0xAE, 0, 0, 0, 0, 0,
+ 0, 0,0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x53, 0, 0, 0, 0, 0,
+ 0, 0,0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xAE, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xF8,0xFF,0xFF,0xFF,0xFE,0xEE,0xC2,0x67,0x03, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+// 'k'
+ 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, 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,0x88,0xFF,0xFF,0xFF,0x9C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x88,0xFF,0xFF,0xFF,0x9C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x88,0xFF,0xFF,0xFF,0x9C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x88,0xFF,0xFF,0xFF,0x9C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x88,0xFF,0xFF,0xFF,0x9C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x88,0xFF,0xFF,0xFF,0x9C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x88,0xFF,0xFF,0xFF,0x9C, 0, 0, 0,0x0E,0xCF,0xFF,0xFF,0xFF,0xED,0x31,
+ 0, 0,0x88,0xFF,0xFF,0xFF,0x9C, 0, 0,0x07,0xBF,0xFF,0xFF,0xFF,0xED,0x30, 0,
+ 0, 0,0x88,0xFF,0xFF,0xFF,0x9C, 0,0x03,0xAF,0xFF,0xFF,0xFF,0xEC,0x30, 0, 0,
+ 0, 0,0x88,0xFF,0xFF,0xFF,0x9C, 0,0x9C,0xFF,0xFF,0xFF,0xEC,0x2F, 0, 0, 0,
+ 0, 0,0x88,0xFF,0xFF,0xFF,0x9C,0x88,0xFF,0xFF,0xFF,0xEB,0x2E, 0, 0, 0, 0,
+ 0, 0,0x88,0xFF,0xFF,0xFF,0xE9,0xFF,0xFF,0xFF,0xEB,0x2D, 0, 0, 0, 0, 0,
+ 0, 0,0x88,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE6,0x0F, 0, 0, 0, 0, 0,
+ 0, 0,0x88,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x97, 0, 0, 0, 0, 0,
+ 0, 0,0x88,0xFF,0xFF,0xFF,0xFF,0xE4,0xEB,0xFF,0xFF,0xFE,0x3B, 0, 0, 0, 0,
+ 0, 0,0x88,0xFF,0xFF,0xFF,0xE2,0x22,0x66,0xFF,0xFF,0xFF,0xD5,0x06, 0, 0, 0,
+ 0, 0,0x88,0xFF,0xFF,0xFF,0x9C, 0,0x02,0xCE,0xFF,0xFF,0xFF,0x7D, 0, 0, 0,
+ 0, 0,0x88,0xFF,0xFF,0xFF,0x9C, 0, 0,0x3D,0xFF,0xFF,0xFF,0xF8,0x26, 0, 0,
+ 0, 0,0x88,0xFF,0xFF,0xFF,0x9C, 0, 0, 0,0xA8,0xFF,0xFF,0xFF,0xBF, 0, 0,
+ 0, 0,0x88,0xFF,0xFF,0xFF,0x9C, 0, 0, 0,0x1D,0xF6,0xFF,0xFF,0xFF,0x63, 0,
+ 0, 0,0x88,0xFF,0xFF,0xFF,0x9C, 0, 0, 0, 0,0x7F,0xFF,0xFF,0xFF,0xEE,0x16,
+ 0, 0,0x88,0xFF,0xFF,0xFF,0x9C, 0, 0, 0, 0,0x09,0xE1,0xFF,0xFF,0xFF,0xA7,
+ 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, 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, 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,
+// 'l'
+ 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, 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,0xB8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0xB8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0xB8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x84,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x84,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x84,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x84,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x84,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x84,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x84,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x84,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x84,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x84,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x84,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x84,0xFF,0xFF,0xFF,0xA0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x82,0xFF,0xFF,0xFF,0xA1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x78,0xFF,0xFF,0xFF,0xAF, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x5F,0xFF,0xFF,0xFF,0xE1,0x01, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x2C,0xFF,0xFF,0xFF,0xFF,0x95,0x1C, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0xD2,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7C, 0,
+ 0, 0, 0, 0, 0, 0,0x38,0xF3,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7C, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x25,0x9A,0xDC,0xF7,0xFF,0xFF,0xFF,0xFF,0x7C, 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, 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, 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,
+// 'm'
+ 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, 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, 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, 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,0xD8,0xFF,0xFF,0x35,0x95,0xEC,0xEF,0x9D,0x0D,0x38,0xC6,0xF7,0xE9,0x96,0x0A, 0,
+ 0,0xD8,0xFF,0xFF,0xCC,0xFF,0xFF,0xFF,0xFF,0xB9,0xF1,0xFF,0xFF,0xFF,0xFF,0x93, 0,
+ 0,0xD8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF0,0x01,
+ 0,0xD8,0xFF,0xFF,0xE2,0x1B,0x5D,0xFF,0xFF,0xFF,0xD1,0x14,0x76,0xFF,0xFF,0xFF,0x24,
+ 0,0xD8,0xFF,0xFF,0xA2, 0,0x04,0xFC,0xFF,0xFF,0x83, 0,0x1F,0xFF,0xFF,0xFF,0x3F,
+ 0,0xD8,0xFF,0xFF,0x92, 0, 0,0xEE,0xFF,0xFF,0x72, 0,0x0E,0xFF,0xFF,0xFF,0x50,
+ 0,0xD8,0xFF,0xFF,0x90, 0, 0,0xEC,0xFF,0xFF,0x70, 0,0x0C,0xFF,0xFF,0xFF,0x57,
+ 0,0xD8,0xFF,0xFF,0x90, 0, 0,0xEC,0xFF,0xFF,0x70, 0,0x0C,0xFF,0xFF,0xFF,0x5B,
+ 0,0xD8,0xFF,0xFF,0x90, 0, 0,0xEC,0xFF,0xFF,0x70, 0,0x0C,0xFF,0xFF,0xFF,0x5C,
+ 0,0xD8,0xFF,0xFF,0x90, 0, 0,0xEC,0xFF,0xFF,0x70, 0,0x0C,0xFF,0xFF,0xFF,0x5C,
+ 0,0xD8,0xFF,0xFF,0x90, 0, 0,0xEC,0xFF,0xFF,0x70, 0,0x0C,0xFF,0xFF,0xFF,0x5C,
+ 0,0xD8,0xFF,0xFF,0x90, 0, 0,0xEC,0xFF,0xFF,0x70, 0,0x0C,0xFF,0xFF,0xFF,0x5C,
+ 0,0xD8,0xFF,0xFF,0x90, 0, 0,0xEC,0xFF,0xFF,0x70, 0,0x0C,0xFF,0xFF,0xFF,0x5C,
+ 0,0xD8,0xFF,0xFF,0x90, 0, 0,0xEC,0xFF,0xFF,0x70, 0,0x0C,0xFF,0xFF,0xFF,0x5C,
+ 0,0xD8,0xFF,0xFF,0x90, 0, 0,0xEC,0xFF,0xFF,0x70, 0,0x0C,0xFF,0xFF,0xFF,0x5C,
+ 0,0xD8,0xFF,0xFF,0x90, 0, 0,0xEC,0xFF,0xFF,0x70, 0,0x0C,0xFF,0xFF,0xFF,0x5C,
+ 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, 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, 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,
+// 'n'
+ 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, 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, 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, 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, 0,0x90,0xFF,0xFF,0xFF,0x90,0x10,0x8C,0xDD,0xF8,0xE9,0xA6,0x23, 0, 0, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0x99,0xD5,0xFF,0xFF,0xFF,0xFF,0xFF,0xEB,0x1E, 0, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0xF4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xA0, 0, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0xFF,0xA8,0x15,0x1B,0xB5,0xFF,0xFF,0xFF,0xF0,0x01, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0xF4,0x0E, 0, 0,0x2C,0xFF,0xFF,0xFF,0xFF,0x1A, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0xB3, 0, 0, 0,0x04,0xFF,0xFF,0xFF,0xFF,0x29, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0x98, 0, 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0x2C, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0x2C, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0x2C, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0x2C, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0x2C, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0x2C, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0x2C, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0x2C, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0x2C, 0,
+ 0, 0,0x90,0xFF,0xFF,0xFF,0x90, 0, 0, 0, 0,0xF4,0xFF,0xFF,0xFF,0x2C, 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, 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, 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,
+// 'o'
+ 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, 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, 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, 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, 0, 0, 0,0x01,0x55,0xAE,0xE4,0xF8,0xEF,0xCD,0x85,0x18, 0, 0, 0, 0,
+ 0, 0, 0,0x16,0xC4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF4,0x5A, 0, 0, 0,
+ 0, 0,0x0A,0xD5,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x55, 0, 0,
+ 0, 0,0x8E,0xFF,0xFF,0xFF,0xED,0x51,0x09,0x23,0xB0,0xFF,0xFF,0xFF,0xF0,0x12, 0,
+ 0,0x0F,0xF4,0xFF,0xFF,0xFF,0x4D, 0, 0, 0,0x06,0xD6,0xFF,0xFF,0xFF,0x7A, 0,
+ 0,0x4F,0xFF,0xFF,0xFF,0xDD, 0, 0, 0, 0, 0,0x6B,0xFF,0xFF,0xFF,0xC5, 0,
+ 0,0x80,0xFF,0xFF,0xFF,0xA4, 0, 0, 0, 0, 0,0x32,0xFF,0xFF,0xFF,0xF6, 0,
+ 0,0x93,0xFF,0xFF,0xFF,0x8D, 0, 0, 0, 0, 0,0x1A,0xFF,0xFF,0xFF,0xFF,0x0A,
+ 0,0x94,0xFF,0xFF,0xFF,0x8D, 0, 0, 0, 0, 0,0x1B,0xFF,0xFF,0xFF,0xFF,0x0A,
+ 0,0x80,0xFF,0xFF,0xFF,0xA4, 0, 0, 0, 0, 0,0x32,0xFF,0xFF,0xFF,0xF7, 0,
+ 0,0x4F,0xFF,0xFF,0xFF,0xDD, 0, 0, 0, 0, 0,0x6B,0xFF,0xFF,0xFF,0xC5, 0,
+ 0,0x0F,0xF4,0xFF,0xFF,0xFF,0x4B, 0, 0, 0,0x05,0xD5,0xFF,0xFF,0xFF,0x7A, 0,
+ 0, 0,0x8F,0xFF,0xFF,0xFF,0xEB,0x4F,0x08,0x22,0xAE,0xFF,0xFF,0xFF,0xF1,0x12, 0,
+ 0, 0,0x0B,0xD5,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x55, 0, 0,
+ 0, 0, 0,0x16,0xC5,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF5,0x5A, 0, 0, 0,
+ 0, 0, 0, 0,0x01,0x56,0xB0,0xE5,0xF9,0xF0,0xCE,0x86,0x19, 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, 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, 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,
+// 'p'
+ 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, 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, 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, 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, 0,0xE0,0xFF,0xFF,0xFF,0x44,0x1D,0x9A,0xE3,0xF8,0xE2,0x9A,0x1D, 0, 0, 0,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0x6A,0xEB,0xFF,0xFF,0xFF,0xFF,0xFF,0xF0,0x33, 0, 0,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0xF3,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE1,0x09, 0,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0xFF,0xB7,0x21,0x0E,0x7D,0xFF,0xFF,0xFF,0xFF,0x6B, 0,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0xEA,0x0C, 0, 0, 0,0xAB,0xFF,0xFF,0xFF,0xC2, 0,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0x92, 0, 0, 0, 0,0x47,0xFF,0xFF,0xFF,0xF5,0x02,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0x5E, 0, 0, 0, 0,0x13,0xFF,0xFF,0xFF,0xFF,0x1A,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0x49, 0, 0, 0, 0, 0,0xFD,0xFF,0xFF,0xFF,0x29,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0x48, 0, 0, 0, 0, 0,0xFD,0xFF,0xFF,0xFF,0x28,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0x5E, 0, 0, 0, 0,0x13,0xFF,0xFF,0xFF,0xFF,0x1A,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0x92, 0, 0, 0, 0,0x46,0xFF,0xFF,0xFF,0xF5,0x02,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0xEA,0x0C, 0, 0, 0,0xAB,0xFF,0xFF,0xFF,0xC2, 0,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0xFF,0xB7,0x20,0x0D,0x7C,0xFF,0xFF,0xFF,0xFF,0x6B, 0,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0xF6,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0,0x08, 0,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0x6A,0xEA,0xFF,0xFF,0xFF,0xFF,0xFF,0xEE,0x31, 0, 0,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0x44,0x1C,0x9E,0xE7,0xF9,0xDF,0x95,0x1A, 0, 0, 0,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0x44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xE0,0xFF,0xFF,0xFF,0x44, 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,
+// 'q'
+ 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, 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, 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, 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, 0, 0,0x01,0x63,0xC8,0xF2,0xF1,0xC4,0x56, 0,0xCC,0xFF,0xFF,0xFF,0x54, 0,
+ 0, 0,0x02,0xA9,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x87,0xCC,0xFF,0xFF,0xFF,0x54, 0,
+ 0, 0,0x72,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF4,0xFF,0xFF,0xFF,0x54, 0,
+ 0,0x06,0xED,0xFF,0xFF,0xFF,0xD0,0x2D,0x0A,0x62,0xFA,0xFF,0xFF,0xFF,0xFF,0x54, 0,
+ 0,0x4A,0xFF,0xFF,0xFF,0xFB,0x23, 0, 0, 0,0x83,0xFF,0xFF,0xFF,0xFF,0x54, 0,
+ 0,0x80,0xFF,0xFF,0xFF,0xBA, 0, 0, 0, 0,0x1D,0xFF,0xFF,0xFF,0xFF,0x54, 0,
+ 0,0xA3,0xFF,0xFF,0xFF,0x86, 0, 0, 0, 0, 0,0xE8,0xFF,0xFF,0xFF,0x54, 0,
+ 0,0xB1,0xFF,0xFF,0xFF,0x71, 0, 0, 0, 0, 0,0xD2,0xFF,0xFF,0xFF,0x54, 0,
+ 0,0xB2,0xFF,0xFF,0xFF,0x70, 0, 0, 0, 0, 0,0xD2,0xFF,0xFF,0xFF,0x54, 0,
+ 0,0xA3,0xFF,0xFF,0xFF,0x86, 0, 0, 0, 0, 0,0xE8,0xFF,0xFF,0xFF,0x54, 0,
+ 0,0x81,0xFF,0xFF,0xFF,0xBA, 0, 0, 0, 0,0x1C,0xFF,0xFF,0xFF,0xFF,0x54, 0,
+ 0,0x4B,0xFF,0xFF,0xFF,0xFB,0x23, 0, 0, 0,0x83,0xFF,0xFF,0xFF,0xFF,0x54, 0,
+ 0,0x07,0xEF,0xFF,0xFF,0xFF,0xCF,0x2C,0x09,0x61,0xFA,0xFF,0xFF,0xFF,0xFF,0x54, 0,
+ 0, 0,0x74,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF7,0xFF,0xFF,0xFF,0x54, 0,
+ 0, 0,0x02,0xA8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x87,0xCC,0xFF,0xFF,0xFF,0x54, 0,
+ 0, 0, 0, 0,0x5E,0xC3,0xF0,0xF5,0xC8,0x58, 0,0xCC,0xFF,0xFF,0xFF,0x54, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xCC,0xFF,0xFF,0xFF,0x54, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xCC,0xFF,0xFF,0xFF,0x54, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xCC,0xFF,0xFF,0xFF,0x54, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xCC,0xFF,0xFF,0xFF,0x54, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xCC,0xFF,0xFF,0xFF,0x54, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xCC,0xFF,0xFF,0xFF,0x54, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+// 'r'
+ 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, 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, 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, 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, 0, 0, 0,0xE0,0xFF,0xFF,0xFF,0x44,0x0B,0x79,0xCD,0xF0,0xF7,0xC9,0x60,0x05,
+ 0, 0, 0, 0,0xE0,0xFF,0xFF,0xFF,0x5B,0xD8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x4C,
+ 0, 0, 0, 0,0xE0,0xFF,0xFF,0xFF,0xE7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x4C,
+ 0, 0, 0, 0,0xE0,0xFF,0xFF,0xFF,0xFF,0xF8,0x80,0x27,0x08,0x1B,0x6F,0xF2,0x4C,
+ 0, 0, 0, 0,0xE0,0xFF,0xFF,0xFF,0xFC,0x42, 0, 0, 0, 0, 0,0x2F,0x3E,
+ 0, 0, 0, 0,0xE0,0xFF,0xFF,0xFF,0xA8, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,0xE0,0xFF,0xFF,0xFF,0x66, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,0xE0,0xFF,0xFF,0xFF,0x4E, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,0xE0,0xFF,0xFF,0xFF,0x46, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,0xE0,0xFF,0xFF,0xFF,0x44, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,0xE0,0xFF,0xFF,0xFF,0x44, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,0xE0,0xFF,0xFF,0xFF,0x44, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,0xE0,0xFF,0xFF,0xFF,0x44, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,0xE0,0xFF,0xFF,0xFF,0x44, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,0xE0,0xFF,0xFF,0xFF,0x44, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,0xE0,0xFF,0xFF,0xFF,0x44, 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, 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, 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,
+// 's'
+ 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, 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, 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, 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, 0, 0, 0,0x12,0x79,0xC3,0xEC,0xFB,0xEE,0xD6,0xB5,0x70,0x26, 0, 0, 0,
+ 0, 0, 0,0x3A,0xEB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x08, 0, 0,
+ 0, 0,0x10,0xEA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x08, 0, 0,
+ 0, 0,0x63,0xFF,0xFF,0xFF,0xD0,0x3A,0x0C,0x09,0x23,0x40,0x85,0xD6,0x07, 0, 0,
+ 0, 0,0x88,0xFF,0xFF,0xFF,0x73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x7F,0xFF,0xFF,0xFF,0xF3,0x7B,0x22, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x3D,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE1,0xA2,0x5B,0x0A, 0, 0, 0, 0,
+ 0, 0, 0,0xA6,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xED,0x5B, 0, 0, 0,
+ 0, 0, 0,0x03,0x78,0xEC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x52, 0, 0,
+ 0, 0, 0, 0, 0,0x06,0x46,0x88,0xC5,0xF9,0xFF,0xFF,0xFF,0xFF,0xD3, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,0x0C,0x6F,0xFE,0xFF,0xFF,0xFF,0x0C, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xDC,0xFF,0xFF,0xFF,0x14, 0,
+ 0, 0,0x4C,0xC7,0x83,0x44,0x27,0x10,0x05,0x1D,0x76,0xFE,0xFF,0xFF,0xF1,0x02, 0,
+ 0, 0,0x50,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x95, 0, 0,
+ 0, 0,0x50,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC1,0x0E, 0, 0,
+ 0, 0,0x03,0x33,0x72,0xAF,0xD1,0xE7,0xFA,0xF6,0xDE,0xAE,0x58,0x02, 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, 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, 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,
+// 't'
+ 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x60,0xFF,0xFF,0xFF,0xC4, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x60,0xFF,0xFF,0xFF,0xC4, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x60,0xFF,0xFF,0xFF,0xC4, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x60,0xFF,0xFF,0xFF,0xC4, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x60,0xFF,0xFF,0xFF,0xC4, 0, 0, 0, 0, 0, 0, 0,
+ 0,0x6C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x30, 0,
+ 0,0x6C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x30, 0,
+ 0,0x6C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x30, 0,
+ 0, 0, 0, 0, 0,0x60,0xFF,0xFF,0xFF,0xC4, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x60,0xFF,0xFF,0xFF,0xC4, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x60,0xFF,0xFF,0xFF,0xC4, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x60,0xFF,0xFF,0xFF,0xC4, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x60,0xFF,0xFF,0xFF,0xC4, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x60,0xFF,0xFF,0xFF,0xC4, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x60,0xFF,0xFF,0xFF,0xC4, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x5F,0xFF,0xFF,0xFF,0xC4, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x55,0xFF,0xFF,0xFF,0xD9, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x37,0xFF,0xFF,0xFF,0xFF,0x6A,0x0F, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x07,0xED,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x30, 0,
+ 0, 0, 0, 0, 0, 0,0x6A,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x30, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x41,0xA4,0xD8,0xF3,0xFD,0xFF,0xFF,0xFF,0x30, 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, 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, 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,
+// 'u'
+ 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, 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, 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, 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, 0,0xBC,0xFF,0xFF,0xFF,0x6C, 0, 0, 0,0x20,0xFF,0xFF,0xFF,0xFF,0x08, 0,
+ 0, 0,0xBC,0xFF,0xFF,0xFF,0x6C, 0, 0, 0,0x20,0xFF,0xFF,0xFF,0xFF,0x08, 0,
+ 0, 0,0xBC,0xFF,0xFF,0xFF,0x6C, 0, 0, 0,0x20,0xFF,0xFF,0xFF,0xFF,0x08, 0,
+ 0, 0,0xBC,0xFF,0xFF,0xFF,0x6C, 0, 0, 0,0x20,0xFF,0xFF,0xFF,0xFF,0x08, 0,
+ 0, 0,0xBC,0xFF,0xFF,0xFF,0x6C, 0, 0, 0,0x20,0xFF,0xFF,0xFF,0xFF,0x08, 0,
+ 0, 0,0xBC,0xFF,0xFF,0xFF,0x6C, 0, 0, 0,0x20,0xFF,0xFF,0xFF,0xFF,0x08, 0,
+ 0, 0,0xBC,0xFF,0xFF,0xFF,0x6C, 0, 0, 0,0x20,0xFF,0xFF,0xFF,0xFF,0x08, 0,
+ 0, 0,0xBC,0xFF,0xFF,0xFF,0x6C, 0, 0, 0,0x20,0xFF,0xFF,0xFF,0xFF,0x08, 0,
+ 0, 0,0xBC,0xFF,0xFF,0xFF,0x6C, 0, 0, 0,0x20,0xFF,0xFF,0xFF,0xFF,0x08, 0,
+ 0, 0,0xBC,0xFF,0xFF,0xFF,0x6C, 0, 0, 0,0x28,0xFF,0xFF,0xFF,0xFF,0x08, 0,
+ 0, 0,0xB9,0xFF,0xFF,0xFF,0x7A, 0, 0, 0,0x43,0xFF,0xFF,0xFF,0xFF,0x08, 0,
+ 0, 0,0xAC,0xFF,0xFF,0xFF,0xA3, 0, 0, 0,0x91,0xFF,0xFF,0xFF,0xFF,0x08, 0,
+ 0, 0,0x83,0xFF,0xFF,0xFF,0xF5,0x4A,0x0E,0x59,0xF8,0xFF,0xFF,0xFF,0xFF,0x08, 0,
+ 0, 0,0x32,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF6,0xFF,0xFF,0xFF,0xFF,0x08, 0,
+ 0, 0, 0,0x9B,0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0x75,0xFF,0xFF,0xFF,0xFF,0x08, 0,
+ 0, 0, 0,0x02,0x72,0xD4,0xF8,0xEE,0xBA,0x44,0x20,0xFF,0xFF,0xFF,0xFF,0x08, 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, 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, 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,
+// 'v'
+ 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, 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, 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, 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,0xB4,0xFF,0xFF,0xFF,0x7A, 0, 0, 0, 0, 0,0x0A,0xF8,0xFF,0xFF,0xFF,0x2B,
+ 0,0x64,0xFF,0xFF,0xFF,0xBF, 0, 0, 0, 0, 0,0x49,0xFF,0xFF,0xFF,0xDA, 0,
+ 0,0x16,0xFD,0xFF,0xFF,0xF9,0x0B, 0, 0, 0, 0,0x8F,0xFF,0xFF,0xFF,0x89, 0,
+ 0, 0,0xC3,0xFF,0xFF,0xFF,0x49, 0, 0, 0, 0,0xD5,0xFF,0xFF,0xFF,0x38, 0,
+ 0, 0,0x72,0xFF,0xFF,0xFF,0x8F, 0, 0, 0,0x1B,0xFF,0xFF,0xFF,0xE6,0x01, 0,
+ 0, 0,0x21,0xFF,0xFF,0xFF,0xD4, 0, 0, 0,0x61,0xFF,0xFF,0xFF,0x97, 0, 0,
+ 0, 0, 0,0xD1,0xFF,0xFF,0xFF,0x1A, 0, 0,0xA6,0xFF,0xFF,0xFF,0x46, 0, 0,
+ 0, 0, 0,0x81,0xFF,0xFF,0xFF,0x5E, 0,0x01,0xEA,0xFF,0xFF,0xF0,0x05, 0, 0,
+ 0, 0, 0,0x30,0xFF,0xFF,0xFF,0xA3, 0,0x32,0xFF,0xFF,0xFF,0xA5, 0, 0, 0,
+ 0, 0, 0, 0,0xDF,0xFF,0xFF,0xE7,0x01,0x78,0xFF,0xFF,0xFF,0x54, 0, 0, 0,
+ 0, 0, 0, 0,0x8F,0xFF,0xFF,0xFF,0x2E,0xBE,0xFF,0xFF,0xF7,0x0C, 0, 0, 0,
+ 0, 0, 0, 0,0x3F,0xFF,0xFF,0xFF,0x7E,0xF8,0xFF,0xFF,0xB2, 0, 0, 0, 0,
+ 0, 0, 0, 0,0x03,0xEA,0xFF,0xFF,0xEF,0xFF,0xFF,0xFF,0x62, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x9E,0xFF,0xFF,0xFF,0xFF,0xFF,0xFC,0x14, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x4D,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x08,0xF4,0xFF,0xFF,0xFF,0xFF,0x70, 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, 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, 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,
+// 'w'
+ 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, 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, 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, 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,
+0xE9,0xFF,0xFF,0x87, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x13,0xFF,0xFF,0xFF,
+0xBC,0xFF,0xFF,0xAF, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x3C,0xFF,0xFF,0xFF,
+0x8E,0xFF,0xFF,0xD6, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x64,0xFF,0xFF,0xFA,
+0x60,0xFF,0xFF,0xFA,0x04, 0, 0, 0, 0, 0, 0, 0, 0,0x8C,0xFF,0xFF,0xD2,
+0x32,0xFF,0xFF,0xFF,0x26, 0,0x10,0xFE,0xFF,0xFF,0x81, 0, 0,0xB4,0xFF,0xFF,0xA4,
+0x07,0xFB,0xFF,0xFF,0x4D, 0,0x44,0xFF,0xFF,0xFF,0xB6, 0, 0,0xDC,0xFF,0xFF,0x76,
+ 0,0xD6,0xFF,0xFF,0x75, 0,0x79,0xFF,0xFF,0xFF,0xEB, 0,0x07,0xFC,0xFF,0xFF,0x48,
+ 0,0xA8,0xFF,0xFF,0x9D, 0,0xAE,0xFF,0xF4,0xFF,0xFF,0x1F,0x2C,0xFF,0xFF,0xFF,0x1A,
+ 0,0x7A,0xFF,0xFF,0xC4, 0,0xE3,0xFF,0x93,0xFE,0xFF,0x54,0x54,0xFF,0xFF,0xEC, 0,
+ 0,0x4C,0xFF,0xFF,0xEC,0x18,0xFF,0xFF,0x47,0xD6,0xFF,0x89,0x7C,0xFF,0xFF,0xBE, 0,
+ 0,0x1E,0xFF,0xFF,0xFF,0x62,0xFF,0xFE,0x10,0x9B,0xFF,0xBD,0xA4,0xFF,0xFF,0x90, 0,
+ 0, 0,0xEF,0xFF,0xFF,0xBF,0xFF,0xD4, 0,0x61,0xFF,0xF1,0xCD,0xFF,0xFF,0x62, 0,
+ 0, 0,0xC2,0xFF,0xFF,0xFE,0xFF,0x9A, 0,0x26,0xFF,0xFF,0xFE,0xFF,0xFF,0x34, 0,
+ 0, 0,0x94,0xFF,0xFF,0xFF,0xFF,0x60, 0, 0,0xEA,0xFF,0xFF,0xFF,0xFD,0x09, 0,
+ 0, 0,0x66,0xFF,0xFF,0xFF,0xFF,0x26, 0, 0,0xB0,0xFF,0xFF,0xFF,0xD8, 0, 0,
+ 0, 0,0x37,0xFF,0xFF,0xFF,0xEC, 0, 0, 0,0x75,0xFF,0xFF,0xFF,0xAA, 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, 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, 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,
+// 'x'
+ 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, 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, 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, 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,0x66,0xFF,0xFF,0xFF,0xFF,0x5E, 0, 0, 0,0x07,0xDF,0xFF,0xFF,0xFF,0xD5,0x08,
+ 0, 0,0xB1,0xFF,0xFF,0xFF,0xE2,0x08, 0, 0,0x76,0xFF,0xFF,0xFF,0xFA,0x31, 0,
+ 0, 0,0x15,0xE8,0xFF,0xFF,0xFF,0x78, 0,0x14,0xF0,0xFF,0xFF,0xFF,0x78, 0, 0,
+ 0, 0, 0,0x4A,0xFF,0xFF,0xFF,0xF1,0x14,0x94,0xFF,0xFF,0xFF,0xC3,0x02, 0, 0,
+ 0, 0, 0, 0,0x95,0xFF,0xFF,0xFF,0xB1,0xFB,0xFF,0xFF,0xF2,0x21, 0, 0, 0,
+ 0, 0, 0, 0,0x09,0xD7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x60, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x32,0xFA,0xFF,0xFF,0xFF,0xFF,0xAE, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x8D,0xFF,0xFF,0xFF,0xFA,0x16, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x10,0xE2,0xFF,0xFF,0xFF,0xFF,0x76, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0xA7,0xFF,0xFF,0xFF,0xFF,0xFF,0xF9,0x2E, 0, 0, 0, 0,
+ 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xE9,0xFF,0xFF,0xFF,0xD3,0x07, 0, 0, 0,
+ 0, 0, 0,0x1E,0xF0,0xFF,0xFF,0xFE,0x37,0xC3,0xFF,0xFF,0xFF,0x8D, 0, 0, 0,
+ 0, 0,0x02,0xC0,0xFF,0xFF,0xFF,0xA1, 0,0x32,0xFD,0xFF,0xFF,0xFE,0x41, 0, 0,
+ 0, 0,0x77,0xFF,0xFF,0xFF,0xF4,0x1A, 0, 0,0x9B,0xFF,0xFF,0xFF,0xE1,0x0F, 0,
+ 0,0x30,0xF9,0xFF,0xFF,0xFF,0x7B, 0, 0, 0,0x16,0xF0,0xFF,0xFF,0xFF,0xA4, 0,
+0x08,0xD5,0xFF,0xFF,0xFF,0xE0,0x08, 0, 0, 0, 0,0x72,0xFF,0xFF,0xFF,0xFF,0x56,
+ 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, 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, 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,
+// 'y'
+ 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, 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, 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, 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,
+0x0A,0xF0,0xFF,0xFF,0xFF,0x60, 0, 0, 0, 0, 0, 0,0xDE,0xFF,0xFF,0xFF,0x78,
+ 0,0x97,0xFF,0xFF,0xFF,0xB9, 0, 0, 0, 0, 0,0x34,0xFF,0xFF,0xFF,0xFD,0x1C,
+ 0,0x34,0xFF,0xFF,0xFF,0xFC,0x16, 0, 0, 0, 0,0x8A,0xFF,0xFF,0xFF,0xBB, 0,
+ 0, 0,0xD0,0xFF,0xFF,0xFF,0x6C, 0, 0, 0, 0,0xDE,0xFF,0xFF,0xFF,0x5C, 0,
+ 0, 0,0x6D,0xFF,0xFF,0xFF,0xC5, 0, 0, 0,0x35,0xFF,0xFF,0xFF,0xF3,0x0A, 0,
+ 0, 0,0x11,0xF7,0xFF,0xFF,0xFE,0x1F, 0, 0,0x8A,0xFF,0xFF,0xFF,0x9F, 0, 0,
+ 0, 0, 0,0xA6,0xFF,0xFF,0xFF,0x78, 0, 0,0xDE,0xFF,0xFF,0xFF,0x40, 0, 0,
+ 0, 0, 0,0x43,0xFF,0xFF,0xFF,0xD1, 0,0x35,0xFF,0xFF,0xFF,0xE0,0x01, 0, 0,
+ 0, 0, 0,0x01,0xDE,0xFF,0xFF,0xFF,0x2A,0x8B,0xFF,0xFF,0xFF,0x83, 0, 0, 0,
+ 0, 0, 0, 0,0x7C,0xFF,0xFF,0xFF,0x84,0xDF,0xFF,0xFF,0xFF,0x25, 0, 0, 0,
+ 0, 0, 0, 0,0x1C,0xFC,0xFF,0xFF,0xF2,0xFF,0xFF,0xFF,0xC6, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0xB5,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x67, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x52,0xFF,0xFF,0xFF,0xFF,0xFF,0xF8,0x10, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x05,0xE9,0xFF,0xFF,0xFF,0xFF,0xAA, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x8B,0xFF,0xFF,0xFF,0xFF,0x4C, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x39,0xFF,0xFF,0xFF,0xE9,0x04, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x77,0xFF,0xFF,0xFF,0x8E, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x06,0xE0,0xFF,0xFF,0xFF,0x30, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0x03,0x21,0xA3,0xFF,0xFF,0xFF,0xC6, 0, 0, 0, 0, 0, 0, 0,
+ 0,0x34,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x44, 0, 0, 0, 0, 0, 0, 0,
+ 0,0x34,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8B, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0x34,0xFF,0xFF,0xFF,0xF3,0xC9,0x56, 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,
+// 'z'
+ 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, 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, 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, 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, 0,0x5C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x50, 0,
+ 0, 0,0x5C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x50, 0,
+ 0, 0,0x5C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x50, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,0x06,0xC0,0xFF,0xFF,0xFF,0xF3,0x26, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,0xA2,0xFF,0xFF,0xFF,0xFC,0x4A, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,0x80,0xFF,0xFF,0xFF,0xFF,0x6B, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x5C,0xFF,0xFF,0xFF,0xFF,0x8E, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x3E,0xF9,0xFF,0xFF,0xFF,0xB0,0x02, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x27,0xED,0xFF,0xFF,0xFF,0xCB,0x0A, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,0x14,0xDC,0xFF,0xFF,0xFF,0xE1,0x18, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0x08,0xC5,0xFF,0xFF,0xFF,0xF1,0x2C, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x01,0xA9,0xFF,0xFF,0xFF,0xFB,0x46, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x7D,0xFF,0xFF,0xFF,0xFF,0x66, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0xB4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x50, 0,
+ 0, 0,0xB4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x50, 0,
+ 0, 0,0xB4,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x50, 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, 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, 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, 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,
+ 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,0x31,0x9C,0xD3,0xF1,0xFC,0xFF,0xE8, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x40,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0xE8, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xBC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE8, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x02,0xF6,0xFF,0xFF,0xFF,0x6D,0x15, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x14,0xFF,0xFF,0xFF,0xD8, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x1E,0xFF,0xFF,0xFF,0xB9, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x20,0xFF,0xFF,0xFF,0xB4, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x20,0xFF,0xFF,0xFF,0xB4, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x22,0xFF,0xFF,0xFF,0xB3, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x36,0xFF,0xFF,0xFF,0xAD, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x77,0xFF,0xFF,0xFF,0x97, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0x02,0x17,0x63,0xF3,0xFF,0xFF,0xFF,0x5A, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x80,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xB6,0x04, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x80,0xFF,0xFF,0xFF,0xFF,0xF3,0x7E,0x01, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x80,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xB3,0x03, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0x02,0x18,0x66,0xF4,0xFF,0xFF,0xFF,0x56, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x79,0xFF,0xFF,0xFF,0x96, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x36,0xFF,0xFF,0xFF,0xAD, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x22,0xFF,0xFF,0xFF,0xB3, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x20,0xFF,0xFF,0xFF,0xB4, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x20,0xFF,0xFF,0xFF,0xB4, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x1E,0xFF,0xFF,0xFF,0xBA, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x14,0xFF,0xFF,0xFF,0xD8, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x02,0xF5,0xFF,0xFF,0xFF,0x6D,0x14, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xBB,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE8, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x40,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0xE8, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,0x32,0x9D,0xD5,0xF2,0xFC,0xFF,0xE8, 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, 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, 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,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0xE4,0xFF,0xFF,0x54, 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, 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,0x74,0xFF,0xFF,0xF6,0xE4,0xB9,0x66,0x03, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x74,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xA8, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x74,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x28, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,0x08,0x35,0xD4,0xFF,0xFF,0xFF,0x64, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x65,0xFF,0xFF,0xFF,0x7F, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x46,0xFF,0xFF,0xFF,0x8A, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x40,0xFF,0xFF,0xFF,0x8C, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x40,0xFF,0xFF,0xFF,0x8C, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x40,0xFF,0xFF,0xFF,0x8E, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x3B,0xFF,0xFF,0xFF,0xA1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x24,0xFF,0xFF,0xFF,0xE0,0x04, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x01,0xE6,0xFF,0xFF,0xFF,0xAA,0x30,0x08, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x54,0xF7,0xFF,0xFF,0xFF,0xFF,0xFF,0xF8, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,0x33,0xD0,0xFF,0xFF,0xFF,0xFF,0xF8, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,0x4F,0xF6,0xFF,0xFF,0xFF,0xFF,0xFF,0xF8, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x01,0xE4,0xFF,0xFF,0xFF,0xAD,0x32,0x09, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x23,0xFF,0xFF,0xFF,0xE1,0x04, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x3B,0xFF,0xFF,0xFF,0xA1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x40,0xFF,0xFF,0xFF,0x8E, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x40,0xFF,0xFF,0xFF,0x8C, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x40,0xFF,0xFF,0xFF,0x8C, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x47,0xFF,0xFF,0xFF,0x8A, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,0x67,0xFF,0xFF,0xFF,0x7F, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,0x08,0x34,0xD5,0xFF,0xFF,0xFF,0x63, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x74,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x27, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x74,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xA8, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x74,0xFF,0xFF,0xF7,0xE5,0xBA,0x68,0x03, 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, 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, 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, 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, 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, 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, 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,0x1B,0x93,0xDF,0xF8,0xE1,0xAA,0x46, 0, 0, 0, 0, 0, 0,0x65,0x34,
+ 0,0x50,0xF2,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xCC,0x5F,0x1D,0x09,0x3A,0xAD,0xFF,0x38,
+ 0,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x38,
+ 0,0xC0,0xE5,0x69,0x1C,0x08,0x28,0x6E,0xDA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xB3,0x0C,
+ 0,0x7C,0x0F, 0, 0, 0, 0, 0,0x02,0x51,0xB7,0xEC,0xF3,0xC3,0x5B,0x01, 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, 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, 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, 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,
+ 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,
+// Small
+// ' '
+ 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, 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, 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, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0xB4,0xFF,0x20, 0, 0,
+ 0, 0, 0,0xB4,0xFF,0x20, 0, 0,
+ 0, 0, 0,0xB4,0xFF,0x20, 0, 0,
+ 0, 0, 0,0xB4,0xFF,0x20, 0, 0,
+ 0, 0, 0,0xB1,0xFF,0x1D, 0, 0,
+ 0, 0, 0,0x9B,0xFF,0x09, 0, 0,
+ 0, 0, 0,0x81,0xF3, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0xB4,0xFF,0x20, 0, 0,
+ 0, 0, 0,0xB4,0xFF,0x20, 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, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0x6C,0xFF,0x54, 0,0xEC,0xD4, 0,
+ 0,0x6C,0xFF,0x54, 0,0xEC,0xD4, 0,
+ 0,0x6C,0xFF,0x54, 0,0xEC,0xD4, 0,
+ 0,0x6C,0xFF,0x54, 0,0xEC,0xD4, 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, 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, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0xCC,0xB8, 0,0xE4,0xA2,
+ 0, 0,0x08,0xFA,0x81,0x1A,0xFF,0x69,
+ 0, 0,0x39,0xFF,0x4B,0x51,0xFF,0x30,
+0x34,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0, 0,0xD5,0xAE,0x01,0xEB,0x97, 0,
+ 0,0x15,0xFE,0x6C,0x2C,0xFF,0x57, 0,
+0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x9C,
+ 0,0xB0,0xD4, 0,0xC4,0xBF, 0, 0,
+ 0,0xE6,0x9D,0x04,0xF5,0x87, 0, 0,
+0x1D,0xFF,0x67,0x31,0xFF,0x4F, 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, 0, 0, 0,
+ 0, 0, 0,0x38,0xC0, 0, 0, 0,
+ 0, 0, 0,0x38,0xC0, 0, 0, 0,
+ 0,0x18,0xAB,0xF0,0xFF,0xFF,0xD4, 0,
+ 0,0xAB,0xFD,0x66,0xC2,0x38,0x95, 0,
+ 0,0xD3,0xFD,0x55,0xC0, 0, 0, 0,
+ 0,0x81,0xFF,0xFB,0xE9,0x76,0x0E, 0,
+ 0, 0,0x56,0xBA,0xFF,0xFF,0xD7,0x09,
+ 0, 0, 0,0x38,0xC1,0xA5,0xFF,0x59,
+ 0,0x68, 0,0x38,0xC0,0x67,0xFF,0x6A,
+ 0,0xD4,0x95,0x4A,0xC3,0xAB,0xFB,0x29,
+ 0,0x2F,0xAC,0xEE,0xFE,0xD6,0x51, 0,
+ 0, 0, 0,0x38,0xC0, 0, 0, 0,
+ 0, 0, 0,0x38,0xC0, 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,
+0x20,0xC4,0xF4,0xAD,0x0B, 0, 0, 0,
+0xA9,0xAA,0x11,0xD3,0x79, 0, 0, 0,
+0xAA,0xA9,0x10,0xD2,0x79, 0, 0, 0,
+0x21,0xC6,0xF4,0xAF,0x0C,0x0A,0x6F,0x8F,
+ 0, 0, 0,0x0D,0x77,0x9D,0x37, 0,
+ 0,0x11,0x7D,0x99,0x2F, 0, 0, 0,
+0x2F,0x94,0x28, 0,0x47,0xDD,0xEE,0x7C,
+ 0, 0, 0, 0,0xE9,0x6A,0x2A,0xFB,
+ 0, 0, 0, 0,0xEA,0x68,0x28,0xFB,
+ 0, 0, 0, 0,0x49,0xDE,0xEF,0x80,
+ 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, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0x02,0x89,0xE4,0xF6,0x9A,0x09, 0,
+ 0,0x59,0xFF,0x9A,0x0C,0x5D,0x45, 0,
+ 0,0x6E,0xFF,0x9F, 0, 0, 0, 0,
+ 0,0x1B,0xF7,0xF7,0x1F, 0, 0, 0,
+ 0,0x8A,0xFF,0xFF,0xB2, 0, 0, 0,
+0x5B,0xFF,0xA9,0xBF,0xFF,0x55,0x45,0xFF,
+0xAF,0xFF,0x2E,0x2B,0xFB,0xE7,0x65,0xFF,
+0xA6,0xFF,0x36, 0,0x8D,0xFF,0xF7,0xEF,
+0x47,0xFE,0xC1,0x1C,0x2D,0xFC,0xFF,0x85,
+ 0,0x51,0xCD,0xF6,0xF1,0xC4,0xF5,0xE5,
+ 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, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0xAC,0xFF,0x14, 0, 0,
+ 0, 0, 0,0xAC,0xFF,0x14, 0, 0,
+ 0, 0, 0,0xAC,0xFF,0x14, 0, 0,
+ 0, 0, 0,0xAC,0xFF,0x14, 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, 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, 0, 0, 0, 0,
+ 0, 0, 0, 0,0x8D,0xF6,0x18, 0,
+ 0, 0, 0,0x2B,0xFC,0x92, 0, 0,
+ 0, 0, 0,0xA0,0xFF,0x2F, 0, 0,
+ 0, 0,0x06,0xF5,0xE1, 0, 0, 0,
+ 0, 0,0x39,0xFF,0xAD, 0, 0, 0,
+ 0, 0,0x55,0xFF,0x95, 0, 0, 0,
+ 0, 0,0x56,0xFF,0x95, 0, 0, 0,
+ 0, 0,0x3A,0xFF,0xAE, 0, 0, 0,
+ 0, 0,0x07,0xF7,0xE2, 0, 0, 0,
+ 0, 0, 0,0xA3,0xFF,0x30, 0, 0,
+ 0, 0, 0,0x2D,0xFC,0x93, 0, 0,
+ 0, 0, 0, 0,0x8D,0xF6,0x18, 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,0xA3,0xE9,0x12, 0, 0, 0,
+ 0, 0,0x25,0xFE,0x97, 0, 0, 0,
+ 0, 0, 0,0xC0,0xF8,0x17, 0, 0,
+ 0, 0, 0,0x72,0xFF,0x6B, 0, 0,
+ 0, 0, 0,0x3D,0xFF,0xA8, 0, 0,
+ 0, 0, 0,0x25,0xFF,0xC4, 0, 0,
+ 0, 0, 0,0x26,0xFF,0xC4, 0, 0,
+ 0, 0, 0,0x3E,0xFF,0xA8, 0, 0,
+ 0, 0, 0,0x73,0xFF,0x6B, 0, 0,
+ 0, 0, 0,0xC1,0xF8,0x17, 0, 0,
+ 0, 0,0x26,0xFE,0x98, 0, 0, 0,
+ 0, 0,0xA3,0xEA,0x12, 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, 0, 0, 0, 0,
+ 0, 0, 0,0x64,0xC8, 0, 0, 0,
+0x08,0xC9,0x68,0x69,0xC8,0x35,0xB6,0x55,
+ 0,0x38,0xB6,0xF9,0xFA,0xE1,0x6B,0x07,
+ 0,0x38,0xB5,0xF8,0xF9,0xE1,0x6A,0x07,
+0x08,0xC9,0x67,0x69,0xC8,0x33,0xB6,0x55,
+ 0, 0, 0,0x64,0xC8, 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, 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, 0, 0, 0, 0, 0,
+ 0, 0, 0,0x98,0xFF,0x08, 0, 0,
+ 0, 0, 0,0x98,0xFF,0x08, 0, 0,
+ 0, 0, 0,0x98,0xFF,0x08, 0, 0,
+0x8C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF8,
+0x8C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF8,
+ 0, 0, 0,0x98,0xFF,0x08, 0, 0,
+ 0, 0, 0,0x98,0xFF,0x08, 0, 0,
+ 0, 0, 0,0x98,0xFF,0x08, 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, 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, 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,0xD8,0xFF,0x4C, 0, 0,
+ 0, 0, 0,0xDC,0xFF,0x43, 0, 0,
+ 0, 0,0x18,0xFE,0xCD,0x02, 0, 0,
+ 0, 0,0x62,0xFF,0x3D, 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, 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,0xF0,0xFF,0xFF,0xFF,0x60, 0,
+ 0, 0,0xF0,0xFF,0xFF,0xFF,0x60, 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, 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, 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,0xF0,0xFF,0x58, 0, 0,
+ 0, 0, 0,0xF0,0xFF,0x58, 0, 0,
+ 0, 0, 0,0xF0,0xFF,0x58, 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, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x1B,0xFA,0x6E,
+ 0, 0, 0, 0, 0,0x88,0xEF,0x0C,
+ 0, 0, 0, 0,0x0C,0xEF,0x88, 0,
+ 0, 0, 0, 0,0x6E,0xFA,0x1B, 0,
+ 0, 0, 0,0x02,0xDD,0xA3, 0, 0,
+ 0, 0, 0,0x53,0xFF,0x31, 0, 0,
+ 0, 0, 0,0xC6,0xBE, 0, 0, 0,
+ 0, 0,0x38,0xFF,0x4B, 0, 0, 0,
+ 0, 0,0xAB,0xD7,0x01, 0, 0, 0,
+ 0,0x20,0xFC,0x66, 0, 0, 0, 0,
+ 0,0x90,0xEA,0x08, 0, 0, 0, 0,
+0x0F,0xF3,0x81, 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,0x01,0x81,0xE7,0xF7,0xBD,0x25, 0,
+ 0,0x6F,0xFF,0x80,0x26,0xF0,0xD9,0x04,
+ 0,0xD9,0xFF,0x10, 0,0xA3,0xFF,0x48,
+0x0D,0xFF,0xEE, 0, 0,0x80,0xFF,0x7C,
+0x22,0xFF,0xE2,0x6B,0xD3,0x74,0xFF,0x92,
+0x23,0xFF,0xE2,0x6D,0xD5,0x74,0xFF,0x91,
+0x0D,0xFF,0xEE, 0, 0,0x80,0xFF,0x7C,
+ 0,0xD9,0xFF,0x10, 0,0xA3,0xFF,0x49,
+ 0,0x6F,0xFF,0x80,0x26,0xF0,0xDB,0x05,
+ 0,0x01,0x82,0xE8,0xF8,0xBE,0x26, 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,
+// '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,0x13,0x80,0xED,0xFF,0x80, 0, 0,
+ 0,0x7C,0x7F,0x86,0xFF,0x80, 0, 0,
+ 0, 0, 0,0x74,0xFF,0x80, 0, 0,
+ 0, 0, 0,0x74,0xFF,0x80, 0, 0,
+ 0, 0, 0,0x74,0xFF,0x80, 0, 0,
+ 0, 0, 0,0x74,0xFF,0x80, 0, 0,
+ 0, 0, 0,0x74,0xFF,0x80, 0, 0,
+ 0, 0, 0,0x74,0xFF,0x80, 0, 0,
+ 0, 0, 0,0x74,0xFF,0x80, 0, 0,
+ 0,0xB8,0xFF,0xFF,0xFF,0xFF,0xFF,0xC4,
+ 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,
+// '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,0x41,0xBA,0xF6,0xE6,0xA2,0x1A, 0,
+ 0,0xBD,0x41,0x08,0x49,0xFC,0xCF,0x02,
+ 0, 0, 0, 0, 0,0xD8,0xFF,0x29,
+ 0, 0, 0, 0,0x0C,0xF8,0xFF,0x27,
+ 0, 0, 0, 0,0x8A,0xFF,0xD9,0x02,
+ 0, 0, 0,0x4D,0xFE,0xFA,0x3D, 0,
+ 0, 0,0x2B,0xF2,0xFD,0x59, 0, 0,
+ 0,0x13,0xDD,0xFF,0x67, 0, 0, 0,
+0x05,0xC1,0xFF,0x72, 0, 0, 0, 0,
+0x37,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x44,
+ 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,0x30,0xAF,0xF4,0xED,0xBB,0x38, 0,
+ 0,0xA7,0x4D,0x09,0x32,0xF0,0xF2,0x12,
+ 0, 0, 0, 0, 0,0xB6,0xFF,0x3B,
+ 0, 0, 0,0x01,0x2F,0xEC,0xDF,0x0C,
+ 0, 0,0x54,0xFF,0xFF,0xD7,0x29, 0,
+ 0, 0, 0,0x01,0x33,0xE7,0xE9,0x18,
+ 0, 0, 0, 0, 0,0x85,0xFF,0x6E,
+ 0, 0, 0, 0, 0,0x7B,0xFF,0x6E,
+0x22,0xA6,0x37,0x0D,0x2B,0xDF,0xF5,0x25,
+0x01,0x57,0xC5,0xF2,0xEC,0xBC,0x3E, 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,
+// '4'
+ 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,0x04,0xC8,0xFF,0xAC, 0,
+ 0, 0, 0,0x88,0xFF,0xFF,0xAC, 0,
+ 0, 0,0x44,0xFE,0xC0,0xFF,0xAC, 0,
+ 0,0x15,0xE7,0xD1,0x45,0xFF,0xAC, 0,
+0x01,0xB6,0xFB,0x31,0x40,0xFF,0xAC, 0,
+0x43,0xFF,0x81, 0,0x40,0xFF,0xAC, 0,
+0x4C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xCC,
+ 0, 0, 0, 0,0x40,0xFF,0xAC, 0,
+ 0, 0, 0, 0,0x40,0xFF,0xAC, 0,
+ 0, 0, 0, 0,0x40,0xFF,0xAC, 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,
+// '5'
+ 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,0xB0,0xFF,0xFF,0xFF,0xFF,0xDC, 0,
+ 0,0xB0,0xF4, 0, 0, 0, 0, 0,
+ 0,0xB0,0xF4, 0, 0, 0, 0, 0,
+ 0,0xB0,0xFE,0xF4,0xEC,0xAC,0x1C, 0,
+ 0,0x86,0x44,0x0E,0x5A,0xFC,0xD7,0x07,
+ 0, 0, 0, 0, 0,0xAA,0xFF,0x50,
+ 0, 0, 0, 0, 0,0x85,0xFF,0x73,
+ 0, 0, 0, 0, 0,0xA7,0xFF,0x57,
+0x03,0xAA,0x2D,0x0C,0x57,0xFA,0xDB,0x08,
+ 0,0x49,0xC2,0xF3,0xE1,0x9B,0x17, 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,
+// '6'
+ 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,0x43,0xC2,0xF4,0xE1,0x65, 0,
+ 0,0x3E,0xFB,0x9E,0x18,0x1E,0x9C,0x0B,
+ 0,0xBB,0xF3,0x09, 0, 0, 0, 0,
+0x03,0xF7,0xEB,0xC6,0xF5,0xDF,0x6D, 0,
+0x15,0xFF,0xFF,0x90,0x13,0xC1,0xFF,0x40,
+0x17,0xFF,0xFF,0x26, 0,0x5C,0xFF,0x8E,
+0x06,0xFD,0xFF,0x11, 0,0x45,0xFF,0xA2,
+ 0,0xD3,0xFF,0x26, 0,0x5B,0xFF,0x83,
+ 0,0x6F,0xFF,0x90,0x12,0xC0,0xFB,0x26,
+ 0,0x01,0x7E,0xE3,0xF7,0xCE,0x48, 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,
+// '7'
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+0x14,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x60,
+ 0, 0, 0, 0,0x0B,0xF4,0xFF,0x4D,
+ 0, 0, 0, 0,0x5E,0xFF,0xE9,0x05,
+ 0, 0, 0, 0,0xBD,0xFF,0x88, 0,
+ 0, 0, 0,0x1D,0xFD,0xFE,0x23, 0,
+ 0, 0, 0,0x7A,0xFF,0xBA, 0, 0,
+ 0, 0, 0,0xD8,0xFF,0x53, 0, 0,
+ 0, 0,0x38,0xFF,0xE7,0x05, 0, 0,
+ 0, 0,0x96,0xFF,0x85, 0, 0, 0,
+ 0,0x06,0xED,0xFE,0x21, 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,
+// '8'
+ 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,0x0D,0x99,0xE7,0xF4,0xC7,0x40, 0,
+ 0,0x9A,0xFF,0x4D,0x15,0xCD,0xF4,0x15,
+ 0,0xD1,0xF4, 0, 0,0x89,0xFF,0x40,
+ 0,0x8B,0xFF,0x4C,0x14,0xCE,0xEA,0x10,
+ 0,0x08,0xC3,0xFF,0xFF,0xF8,0x47, 0,
+ 0,0xA7,0xFC,0x46,0x15,0xC4,0xF2,0x22,
+0x0F,0xFF,0xC5, 0, 0,0x56,0xFF,0x7A,
+0x0B,0xFE,0xC5, 0, 0,0x57,0xFF,0x74,
+ 0,0xBB,0xFC,0x46,0x15,0xC6,0xFA,0x2B,
+ 0,0x18,0xA2,0xE7,0xF4,0xCA,0x4A, 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,
+// '9'
+ 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,0x13,0xA4,0xEA,0xF3,0xB4,0x21, 0,
+ 0,0xB5,0xFB,0x3B,0x32,0xF7,0xD5,0x03,
+0x15,0xFF,0xC6, 0, 0,0xBA,0xFF,0x3E,
+0x33,0xFF,0xB1, 0, 0,0xA5,0xFF,0x6E,
+0x1F,0xFF,0xC6, 0, 0,0xBA,0xFF,0x82,
+0x01,0xCE,0xFB,0x3A,0x31,0xF7,0xFF,0x80,
+ 0,0x26,0xBF,0xF5,0xE7,0xC8,0xFF,0x66,
+ 0, 0, 0, 0, 0,0x8D,0xFF,0x27,
+ 0,0x73,0x3F,0x0C,0x4B,0xF2,0xA5, 0,
+ 0,0x23,0xBC,0xF7,0xDF,0x85,0x06, 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, 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,0xF0,0xFF,0x58, 0, 0,
+ 0, 0, 0,0xF0,0xFF,0x58, 0, 0,
+ 0, 0, 0,0xF0,0xFF,0x58, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0xF0,0xFF,0x58, 0, 0,
+ 0, 0, 0,0xF0,0xFF,0x58, 0, 0,
+ 0, 0, 0,0xF0,0xFF,0x58, 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, 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,0xF0,0xFF,0x58, 0, 0,
+ 0, 0, 0,0xF0,0xFF,0x58, 0, 0,
+ 0, 0, 0,0xF0,0xFF,0x58, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0xF0,0xFF,0x58, 0, 0,
+ 0, 0, 0,0xF3,0xFF,0x4F, 0, 0,
+ 0, 0,0x21,0xFF,0xD7,0x04, 0, 0,
+ 0, 0,0x5B,0xFF,0x49, 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, 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,0x1F,0x7E,0xB2,
+ 0, 0,0x09,0x5B,0xBC,0xFE,0xFE,0xA6,
+0x21,0x99,0xF1,0xFF,0xCA,0x72,0x1B, 0,
+0x64,0xFF,0xDF,0x3F, 0, 0, 0, 0,
+0x23,0x9E,0xF3,0xFE,0xC4,0x6D,0x19, 0,
+ 0, 0,0x0B,0x5F,0xBF,0xFE,0xFD,0xA5,
+ 0, 0, 0, 0, 0,0x21,0x80,0xB3,
+ 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, 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,
+0x64,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xD4,
+0x64,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xD4,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+0x64,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xD4,
+0x64,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xD4,
+ 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, 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,
+0x5C,0xA9,0x48,0x02, 0, 0, 0, 0,
+0x46,0xED,0xFF,0xE4,0x86,0x26, 0, 0,
+ 0,0x05,0x4C,0xA4,0xF3,0xFF,0xC4,0x59,
+ 0, 0, 0, 0,0x10,0xA3,0xFF,0xD4,
+ 0,0x04,0x48,0x9F,0xEF,0xFF,0xC8,0x5C,
+0x46,0xEC,0xFF,0xE6,0x89,0x28, 0, 0,
+0x5C,0xAA,0x4A,0x03, 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, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0x0B,0x7F,0xD9,0xF6,0xD4,0x5A, 0,
+ 0,0x5B,0x79,0x1F,0x12,0xD2,0xFE,0x23,
+ 0, 0, 0, 0,0x06,0xDB,0xFF,0x29,
+ 0, 0, 0,0x04,0xAE,0xFF,0x86, 0,
+ 0, 0, 0,0x90,0xFF,0x83, 0, 0,
+ 0, 0, 0,0xE7,0xE9,0x01, 0, 0,
+ 0, 0, 0,0xFC,0xD4, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0xFC,0xD4, 0, 0, 0,
+ 0, 0, 0,0xFC,0xD4, 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, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,0x65,0xD1,0xF7,0xDD,0x75,0x01,
+ 0,0x8B,0xE9,0x4B,0x09,0x3F,0xEF,0x69,
+0x36,0xFE,0x45, 0, 0, 0,0x8D,0xC9,
+0x9B,0xD2, 0,0x4F,0xDE,0xEF,0xCF,0xE9,
+0xD4,0x91,0x16,0xF4,0x80,0x12,0xC5,0xEC,
+0xEC,0x74,0x4E,0xFF,0x1A, 0,0x66,0xEC,
+0xEB,0x6F,0x4E,0xFF,0x19, 0,0x67,0xEC,
+0xCF,0x8E,0x15,0xF4,0x80,0x12,0xC5,0xEC,
+0x8E,0xD6, 0,0x4F,0xDE,0xF2,0xD2,0xEC,
+0x24,0xF8,0x5F, 0, 0, 0, 0, 0,
+ 0,0x61,0xF6,0x74,0x16,0x13,0x72,0x71,
+ 0, 0,0x3C,0xB3,0xED,0xF8,0xDD,0x78,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+// 'A'
+ 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,0x28,0xFF,0xFF,0x96, 0, 0,
+ 0, 0,0x6E,0xFF,0xFE,0xDD, 0, 0,
+ 0, 0,0xB5,0xFE,0xB4,0xFF,0x23, 0,
+ 0,0x07,0xF5,0xD6,0x67,0xFF,0x6A, 0,
+ 0,0x43,0xFF,0x9B,0x2C,0xFF,0xB0, 0,
+ 0,0x8A,0xFF,0x61,0x01,0xEF,0xF1,0x04,
+ 0,0xD0,0xFF,0xFF,0xFF,0xFF,0xFF,0x3D,
+0x18,0xFE,0xC1, 0, 0,0x56,0xFF,0x83,
+0x5E,0xFF,0x8D, 0, 0,0x20,0xFF,0xCA,
+0xA5,0xFF,0x59, 0, 0, 0,0xEA,0xFD,
+ 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,
+// 'B'
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+0x24,0xFF,0xFF,0xFF,0xF6,0xD6,0x71, 0,
+0x24,0xFF,0xCC, 0,0x10,0xBD,0xFF,0x54,
+0x24,0xFF,0xCC, 0, 0,0x78,0xFF,0x84,
+0x24,0xFF,0xCC, 0,0x0E,0xB8,0xFE,0x45,
+0x24,0xFF,0xFF,0xFF,0xFF,0xF5,0x75, 0,
+0x24,0xFF,0xCC, 0,0x0E,0x9E,0xFF,0x6A,
+0x24,0xFF,0xCC, 0, 0,0x30,0xFF,0xD3,
+0x24,0xFF,0xCC, 0, 0,0x2C,0xFF,0xDC,
+0x24,0xFF,0xCC, 0,0x0C,0x93,0xFF,0x9A,
+0x24,0xFF,0xFF,0xFF,0xFC,0xE3,0x99,0x0D,
+ 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,
+// 'C'
+ 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,0x22,0xA9,0xEC,0xEF,0xA0,0x0E,
+ 0,0x17,0xE8,0xF1,0x3F,0x0F,0x5A,0x53,
+ 0,0x8B,0xFF,0x89, 0, 0, 0, 0,
+ 0,0xD0,0xFF,0x44, 0, 0, 0, 0,
+ 0,0xED,0xFF,0x2E, 0, 0, 0, 0,
+ 0,0xED,0xFF,0x2D, 0, 0, 0, 0,
+ 0,0xD0,0xFF,0x44, 0, 0, 0, 0,
+ 0,0x8B,0xFF,0x89, 0, 0, 0, 0,
+ 0,0x17,0xE9,0xF3,0x4A,0x10,0x57,0x52,
+ 0, 0,0x23,0xAA,0xED,0xF0,0x9F,0x0E,
+ 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,
+// 'D'
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+0x10,0xFF,0xFF,0xF9,0xDD,0x94,0x16, 0,
+0x10,0xFF,0xF4,0x07,0x51,0xF6,0xDB,0x0C,
+0x10,0xFF,0xF4, 0, 0,0x98,0xFF,0x6C,
+0x10,0xFF,0xF4, 0, 0,0x62,0xFF,0xAB,
+0x10,0xFF,0xF4, 0, 0,0x50,0xFF,0xC4,
+0x10,0xFF,0xF4, 0, 0,0x51,0xFF,0xC4,
+0x10,0xFF,0xF4, 0, 0,0x63,0xFF,0xAB,
+0x10,0xFF,0xF4, 0, 0,0x98,0xFF,0x6C,
+0x10,0xFF,0xF4,0x07,0x50,0xF6,0xDC,0x0C,
+0x10,0xFF,0xFF,0xF9,0xDE,0x95,0x17, 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,
+// 'E'
+ 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,0xD8,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,
+ 0,0xD8,0xFF,0x2C, 0, 0, 0, 0,
+ 0,0xD8,0xFF,0x2C, 0, 0, 0, 0,
+ 0,0xD8,0xFF,0x2C, 0, 0, 0, 0,
+ 0,0xD8,0xFF,0xFF,0xFF,0xFF,0xFF,0x18,
+ 0,0xD8,0xFF,0x2C, 0, 0, 0, 0,
+ 0,0xD8,0xFF,0x2C, 0, 0, 0, 0,
+ 0,0xD8,0xFF,0x2C, 0, 0, 0, 0,
+ 0,0xD8,0xFF,0x2C, 0, 0, 0, 0,
+ 0,0xD8,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,
+ 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,
+// 'F'
+ 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,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0x9C,
+ 0,0xC0,0xFF,0x44, 0, 0, 0, 0,
+ 0,0xC0,0xFF,0x44, 0, 0, 0, 0,
+ 0,0xC0,0xFF,0x44, 0, 0, 0, 0,
+ 0,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0x38,
+ 0,0xC0,0xFF,0x44, 0, 0, 0, 0,
+ 0,0xC0,0xFF,0x44, 0, 0, 0, 0,
+ 0,0xC0,0xFF,0x44, 0, 0, 0, 0,
+ 0,0xC0,0xFF,0x44, 0, 0, 0, 0,
+ 0,0xC0,0xFF,0x44, 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,
+// 'G'
+ 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,0x40,0xC0,0xF4,0xEF,0x8E,0x0A,
+ 0,0x41,0xFB,0xDA,0x2F,0x13,0x60,0x4F,
+ 0,0xC9,0xFF,0x43, 0, 0, 0, 0,
+0x10,0xFF,0xFD,0x06, 0, 0, 0, 0,
+0x2D,0xFF,0xEC, 0, 0, 0, 0, 0,
+0x2D,0xFF,0xF1, 0,0x6C,0xFF,0xFF,0xB8,
+0x10,0xFE,0xFF,0x09, 0,0x08,0xFF,0xB8,
+ 0,0xC8,0xFF,0x4B, 0,0x08,0xFF,0xB8,
+ 0,0x41,0xFB,0xCE,0x1F,0x20,0xFF,0xB8,
+ 0, 0,0x43,0xC4,0xF6,0xF3,0xD1,0x66,
+ 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,
+// 'H'
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+0x10,0xFF,0xF4, 0, 0,0x88,0xFF,0x80,
+0x10,0xFF,0xF4, 0, 0,0x88,0xFF,0x80,
+0x10,0xFF,0xF4, 0, 0,0x88,0xFF,0x80,
+0x10,0xFF,0xF4, 0, 0,0x88,0xFF,0x80,
+0x10,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,
+0x10,0xFF,0xF4, 0, 0,0x88,0xFF,0x80,
+0x10,0xFF,0xF4, 0, 0,0x88,0xFF,0x80,
+0x10,0xFF,0xF4, 0, 0,0x88,0xFF,0x80,
+0x10,0xFF,0xF4, 0, 0,0x88,0xFF,0x80,
+0x10,0xFF,0xF4, 0, 0,0x88,0xFF,0x80,
+ 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,
+// 'I'
+ 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,0xD4,0xFF,0xFF,0xFF,0xFF,0xFF,0x40,
+ 0, 0, 0,0xCC,0xFF,0x38, 0, 0,
+ 0, 0, 0,0xCC,0xFF,0x38, 0, 0,
+ 0, 0, 0,0xCC,0xFF,0x38, 0, 0,
+ 0, 0, 0,0xCC,0xFF,0x38, 0, 0,
+ 0, 0, 0,0xCC,0xFF,0x38, 0, 0,
+ 0, 0, 0,0xCC,0xFF,0x38, 0, 0,
+ 0, 0, 0,0xCC,0xFF,0x38, 0, 0,
+ 0, 0, 0,0xCC,0xFF,0x38, 0, 0,
+ 0,0xD4,0xFF,0xFF,0xFF,0xFF,0xFF,0x40,
+ 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,
+// 'J'
+ 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,0x98,0xFF,0xFF,0xFF,0xE4, 0,
+ 0, 0, 0, 0,0x20,0xFF,0xE4, 0,
+ 0, 0, 0, 0,0x20,0xFF,0xE4, 0,
+ 0, 0, 0, 0,0x20,0xFF,0xE4, 0,
+ 0, 0, 0, 0,0x20,0xFF,0xE4, 0,
+ 0, 0, 0, 0,0x20,0xFF,0xE4, 0,
+ 0, 0, 0, 0,0x20,0xFF,0xE4, 0,
+ 0, 0, 0, 0,0x25,0xFF,0xDD, 0,
+0x3B,0x8C,0x28,0x09,0x7E,0xFF,0xAD, 0,
+0x04,0x65,0xCE,0xF8,0xEF,0xB5,0x1D, 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,
+// 'K'
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+0x34,0xFF,0xD0, 0, 0,0x6B,0xFF,0xCF,
+0x34,0xFF,0xD0, 0,0x3D,0xFA,0xE9,0x1E,
+0x34,0xFF,0xD0,0x1C,0xE8,0xF9,0x3C, 0,
+0x34,0xFF,0xD7,0xCA,0xFF,0x64, 0, 0,
+0x34,0xFF,0xFF,0xFF,0xFF,0x57, 0, 0,
+0x34,0xFF,0xFF,0xD4,0xFF,0xDD,0x06, 0,
+0x34,0xFF,0xE7,0x0F,0xBF,0xFF,0x71, 0,
+0x34,0xFF,0xD0, 0,0x37,0xFF,0xED,0x10,
+0x34,0xFF,0xD0, 0, 0,0xAD,0xFF,0x8B,
+0x34,0xFF,0xD0, 0, 0,0x28,0xFC,0xF8,
+ 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,
+// 'L'
+ 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,0x78,0xFF,0x90, 0, 0, 0, 0,
+ 0,0x78,0xFF,0x90, 0, 0, 0, 0,
+ 0,0x78,0xFF,0x90, 0, 0, 0, 0,
+ 0,0x78,0xFF,0x90, 0, 0, 0, 0,
+ 0,0x78,0xFF,0x90, 0, 0, 0, 0,
+ 0,0x78,0xFF,0x90, 0, 0, 0, 0,
+ 0,0x78,0xFF,0x90, 0, 0, 0, 0,
+ 0,0x78,0xFF,0x90, 0, 0, 0, 0,
+ 0,0x78,0xFF,0x90, 0, 0, 0, 0,
+ 0,0x78,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0,
+ 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,
+// 'M'
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+0x68,0xFF,0xFF,0x25, 0,0xBA,0xFF,0xD8,
+0x68,0xFF,0xFF,0x70,0x0B,0xF8,0xFF,0xD8,
+0x68,0xFF,0xD6,0xBC,0x4E,0xEF,0xE6,0xD8,
+0x68,0xFF,0x92,0xFA,0xA6,0xAE,0xE4,0xD8,
+0x68,0xFF,0x59,0xF4,0xFE,0x6B,0xE4,0xD8,
+0x68,0xFF,0x54,0xB6,0xFF,0x29,0xE4,0xD8,
+0x68,0xFF,0x54, 0, 0, 0,0xE4,0xD8,
+0x68,0xFF,0x54, 0, 0, 0,0xE4,0xD8,
+0x68,0xFF,0x54, 0, 0, 0,0xE4,0xD8,
+0x68,0xFF,0x54, 0, 0, 0,0xE4,0xD8,
+ 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,
+// 'N'
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+0x30,0xFF,0xFF,0x2D, 0,0x2C,0xFF,0x9C,
+0x30,0xFF,0xFF,0x92, 0,0x2C,0xFF,0x9C,
+0x30,0xFF,0xFC,0xEE,0x08,0x2C,0xFF,0x9C,
+0x30,0xFF,0xB6,0xFD,0x5A,0x2C,0xFF,0x9C,
+0x30,0xFF,0x98,0xB6,0xBE,0x2C,0xFF,0x9C,
+0x30,0xFF,0x98,0x51,0xFE,0x50,0xFF,0x9C,
+0x30,0xFF,0x98,0x04,0xE8,0xB3,0xFF,0x9C,
+0x30,0xFF,0x98, 0,0x88,0xFC,0xFF,0x9C,
+0x30,0xFF,0x98, 0,0x24,0xFE,0xFF,0x9C,
+0x30,0xFF,0x98, 0, 0,0xBE,0xFF,0x9C,
+ 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,
+// 'O'
+ 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,0x07,0x90,0xE9,0xF6,0xC2,0x31, 0,
+ 0,0x96,0xFF,0x6D,0x1F,0xE4,0xED,0x14,
+0x0F,0xF9,0xEE,0x01, 0,0x83,0xFF,0x74,
+0x42,0xFF,0xCB, 0, 0,0x5D,0xFF,0xAD,
+0x5A,0xFF,0xBE, 0, 0,0x4F,0xFF,0xC5,
+0x5A,0xFF,0xBE, 0, 0,0x4F,0xFF,0xC5,
+0x43,0xFF,0xCB, 0, 0,0x5D,0xFF,0xAE,
+0x0F,0xFA,0xEE,0x01, 0,0x83,0xFF,0x75,
+ 0,0x96,0xFF,0x6B,0x1F,0xE2,0xED,0x14,
+ 0,0x07,0x91,0xEB,0xF8,0xC3,0x32, 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,
+// 'P'
+ 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,0xE4,0xFF,0xFF,0xF7,0xD8,0x81,0x02,
+ 0,0xE4,0xFF,0x20,0x15,0xB3,0xFF,0x78,
+ 0,0xE4,0xFF,0x20, 0,0x4D,0xFF,0xC2,
+ 0,0xE4,0xFF,0x20, 0,0x4E,0xFF,0xC1,
+ 0,0xE4,0xFF,0x20,0x14,0xB1,0xFF,0x78,
+ 0,0xE4,0xFF,0xFF,0xF8,0xD9,0x82,0x02,
+ 0,0xE4,0xFF,0x20, 0, 0, 0, 0,
+ 0,0xE4,0xFF,0x20, 0, 0, 0, 0,
+ 0,0xE4,0xFF,0x20, 0, 0, 0, 0,
+ 0,0xE4,0xFF,0x20, 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,
+// 'Q'
+ 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,0x07,0x90,0xE9,0xF6,0xC1,0x2E, 0,
+ 0,0x96,0xFF,0x6D,0x1F,0xE4,0xEA,0x11,
+0x0F,0xF9,0xEE,0x01, 0,0x83,0xFF,0x70,
+0x42,0xFF,0xCB, 0, 0,0x5D,0xFF,0xAA,
+0x5A,0xFF,0xBE, 0, 0,0x4F,0xFF,0xC3,
+0x5A,0xFF,0xBE, 0, 0,0x4F,0xFF,0xC4,
+0x43,0xFF,0xCB, 0, 0,0x5D,0xFF,0xB1,
+0x0F,0xFA,0xEE,0x01, 0,0x83,0xFF,0x7D,
+ 0,0x96,0xFF,0x6B,0x1F,0xE2,0xFA,0x22,
+ 0,0x07,0x91,0xEB,0xFF,0xFF,0x70, 0,
+ 0, 0, 0, 0,0x2C,0xF5,0xDF,0x1E,
+ 0, 0, 0, 0, 0,0x5E,0x95,0x03,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+// 'R'
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+0x18,0xFF,0xFF,0xFF,0xF5,0xCC,0x55, 0,
+0x18,0xFF,0xEC, 0,0x27,0xE7,0xFA,0x2A,
+0x18,0xFF,0xEC, 0, 0,0xA0,0xFF,0x6A,
+0x18,0xFF,0xEC, 0, 0,0xA1,0xFF,0x70,
+0x18,0xFF,0xEC, 0,0x26,0xE7,0xF6,0x23,
+0x18,0xFF,0xFF,0xFF,0xFF,0xEB,0x37, 0,
+0x18,0xFF,0xEC,0x05,0x99,0xFF,0xA2, 0,
+0x18,0xFF,0xEC, 0,0x0D,0xEE,0xFD,0x29,
+0x18,0xFF,0xEC, 0, 0,0x81,0xFF,0xA9,
+0x18,0xFF,0xEC, 0, 0,0x12,0xF3,0xFE,
+ 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,
+// 'S'
+ 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,0x15,0x9E,0xE6,0xF0,0xBD,0x46, 0,
+ 0,0xBA,0xFA,0x3D,0x07,0x38,0xB7,0x03,
+0x0C,0xFE,0xEA,0x02, 0, 0, 0, 0,
+0x0C,0xFE,0xFF,0xB1,0x2E, 0, 0, 0,
+ 0,0x9B,0xFF,0xFF,0xFF,0xBB,0x31, 0,
+ 0,0x01,0x5F,0xD4,0xFF,0xFF,0xF5,0x26,
+ 0, 0, 0, 0,0x4F,0xEB,0xFF,0x82,
+ 0, 0, 0, 0, 0,0x82,0xFF,0x83,
+0x13,0xB8,0x48,0x14,0x17,0xC4,0xFD,0x3B,
+ 0,0x4C,0xBD,0xEE,0xF0,0xC9,0x53, 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,
+// 'T'
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+0x64,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xD0,
+ 0, 0, 0,0xCC,0xFF,0x38, 0, 0,
+ 0, 0, 0,0xCC,0xFF,0x38, 0, 0,
+ 0, 0, 0,0xCC,0xFF,0x38, 0, 0,
+ 0, 0, 0,0xCC,0xFF,0x38, 0, 0,
+ 0, 0, 0,0xCC,0xFF,0x38, 0, 0,
+ 0, 0, 0,0xCC,0xFF,0x38, 0, 0,
+ 0, 0, 0,0xCC,0xFF,0x38, 0, 0,
+ 0, 0, 0,0xCC,0xFF,0x38, 0, 0,
+ 0, 0, 0,0xCC,0xFF,0x38, 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,
+// 'U'
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+0x48,0xFF,0xBC, 0, 0,0x50,0xFF,0xB4,
+0x48,0xFF,0xBC, 0, 0,0x50,0xFF,0xB4,
+0x48,0xFF,0xBC, 0, 0,0x50,0xFF,0xB4,
+0x48,0xFF,0xBC, 0, 0,0x50,0xFF,0xB4,
+0x48,0xFF,0xBC, 0, 0,0x50,0xFF,0xB4,
+0x48,0xFF,0xBC, 0, 0,0x50,0xFF,0xB4,
+0x47,0xFF,0xBC, 0, 0,0x50,0xFF,0xB2,
+0x2E,0xFF,0xC4, 0, 0,0x58,0xFF,0x99,
+0x06,0xDE,0xF9,0x3B,0x11,0xB9,0xFF,0x50,
+ 0,0x2D,0xB6,0xEA,0xFB,0xDC,0x77, 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,
+// 'V'
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+0x7E,0xFF,0x87, 0, 0,0x18,0xFF,0xEB,
+0x40,0xFF,0xBE, 0, 0,0x4F,0xFF,0xAE,
+0x08,0xF9,0xF2,0x02, 0,0x86,0xFF,0x6F,
+ 0,0xC4,0xFF,0x2C, 0,0xBD,0xFF,0x31,
+ 0,0x86,0xFF,0x63,0x02,0xF1,0xF0,0x02,
+ 0,0x48,0xFF,0x9A,0x2B,0xFF,0xB4, 0,
+ 0,0x0D,0xFC,0xD1,0x62,0xFF,0x76, 0,
+ 0, 0,0xCC,0xFC,0xA5,0xFF,0x37, 0,
+ 0, 0,0x8E,0xFF,0xF8,0xF4,0x04, 0,
+ 0, 0,0x4F,0xFF,0xFF,0xBB, 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,
+// 'W'
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+0xF0,0xD0, 0, 0, 0, 0,0x62,0xFF,
+0xD0,0xE9, 0, 0, 0, 0,0x76,0xFF,
+0xAF,0xFE,0x04, 0, 0, 0,0x8A,0xFF,
+0x8F,0xFF,0x1B,0xB9,0xFF,0x28,0x9E,0xFD,
+0x6F,0xFF,0x34,0xEA,0xFF,0x63,0xB1,0xE4,
+0x4E,0xFF,0x6A,0xFF,0xC9,0x9E,0xC5,0xC6,
+0x2E,0xFF,0xB5,0xE5,0x71,0xD9,0xD9,0xA8,
+0x0D,0xFF,0xF7,0xAC,0x35,0xFF,0xF7,0x8A,
+ 0,0xED,0xFF,0x74,0x04,0xF5,0xFF,0x6C,
+ 0,0xCC,0xFF,0x3C, 0,0xBE,0xFF,0x4E,
+ 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,
+// 'X'
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+0x71,0xFF,0xA6, 0, 0,0x38,0xFE,0xD7,
+0x04,0xD5,0xFF,0x3C,0x01,0xCA,0xFF,0x46,
+ 0,0x42,0xFF,0xCE,0x64,0xFF,0xAF, 0,
+ 0, 0,0xAB,0xFF,0xFA,0xF7,0x21, 0,
+ 0, 0,0x1E,0xF6,0xFF,0x84, 0, 0,
+ 0, 0,0x2E,0xFC,0xFF,0x9A, 0, 0,
+ 0, 0,0xC1,0xFF,0xF1,0xFD,0x33, 0,
+ 0,0x58,0xFF,0xBC,0x4F,0xFF,0xC6,0x01,
+0x0A,0xE3,0xFB,0x2A, 0,0xB8,0xFF,0x5E,
+0x85,0xFF,0x8F, 0, 0,0x28,0xFA,0xE6,
+ 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,
+// 'Y'
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+0xAE,0xFF,0x7A, 0, 0,0x15,0xF5,0xFA,
+0x2B,0xFD,0xEC,0x0C, 0,0x8A,0xFF,0x97,
+ 0,0xA5,0xFF,0x78,0x14,0xF4,0xF7,0x1B,
+ 0,0x24,0xFB,0xEB,0x92,0xFF,0x8D, 0,
+ 0, 0,0x9B,0xFF,0xFF,0xF3,0x14, 0,
+ 0, 0,0x1D,0xF8,0xFF,0x82, 0, 0,
+ 0, 0, 0,0xCC,0xFF,0x38, 0, 0,
+ 0, 0, 0,0xCC,0xFF,0x38, 0, 0,
+ 0, 0, 0,0xCC,0xFF,0x38, 0, 0,
+ 0, 0, 0,0xCC,0xFF,0x38, 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,
+// 'Z'
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+0x10,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xD8,
+ 0, 0, 0, 0,0x0D,0xE3,0xFF,0xD3,
+ 0, 0, 0, 0,0x94,0xFF,0xFF,0x5F,
+ 0, 0, 0,0x39,0xFD,0xFF,0xB7, 0,
+ 0, 0,0x05,0xD4,0xFF,0xF1,0x1D, 0,
+ 0, 0,0x7D,0xFF,0xFF,0x67, 0, 0,
+ 0,0x27,0xF8,0xFF,0xBE,0x01, 0, 0,
+0x01,0xC1,0xFF,0xF5,0x22, 0, 0, 0,
+0x34,0xFF,0xFF,0x6F, 0, 0, 0, 0,
+0x38,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF0,
+ 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, 0,
+ 0, 0,0x1C,0xFF,0xFF,0xFF,0x5C, 0,
+ 0, 0,0x1C,0xFF,0xB4, 0, 0, 0,
+ 0, 0,0x1C,0xFF,0xB4, 0, 0, 0,
+ 0, 0,0x1C,0xFF,0xB4, 0, 0, 0,
+ 0, 0,0x1C,0xFF,0xB4, 0, 0, 0,
+ 0, 0,0x1C,0xFF,0xB4, 0, 0, 0,
+ 0, 0,0x1C,0xFF,0xB4, 0, 0, 0,
+ 0, 0,0x1C,0xFF,0xB4, 0, 0, 0,
+ 0, 0,0x1C,0xFF,0xB4, 0, 0, 0,
+ 0, 0,0x1C,0xFF,0xB4, 0, 0, 0,
+ 0, 0,0x1C,0xFF,0xB4, 0, 0, 0,
+ 0, 0,0x1C,0xFF,0xFF,0xFF,0x5C, 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, 0, 0,
+0x10,0xF3,0x80, 0, 0, 0, 0, 0,
+ 0,0x91,0xEA,0x08, 0, 0, 0, 0,
+ 0,0x21,0xFC,0x66, 0, 0, 0, 0,
+ 0, 0,0xAC,0xD7,0x01, 0, 0, 0,
+ 0, 0,0x3A,0xFF,0x4B, 0, 0, 0,
+ 0, 0, 0,0xC7,0xBE, 0, 0, 0,
+ 0, 0, 0,0x55,0xFF,0x31, 0, 0,
+ 0, 0, 0,0x03,0xDF,0xA3, 0, 0,
+ 0, 0, 0, 0,0x71,0xFA,0x1B, 0,
+ 0, 0, 0, 0,0x0D,0xF0,0x88, 0,
+ 0, 0, 0, 0, 0,0x8C,0xEF,0x0C,
+ 0, 0, 0, 0, 0,0x1D,0xFB,0x6E,
+ 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,0xEC,0xFF,0xFF,0x8C, 0, 0,
+ 0, 0, 0,0x48,0xFF,0x8C, 0, 0,
+ 0, 0, 0,0x48,0xFF,0x8C, 0, 0,
+ 0, 0, 0,0x48,0xFF,0x8C, 0, 0,
+ 0, 0, 0,0x48,0xFF,0x8C, 0, 0,
+ 0, 0, 0,0x48,0xFF,0x8C, 0, 0,
+ 0, 0, 0,0x48,0xFF,0x8C, 0, 0,
+ 0, 0, 0,0x48,0xFF,0x8C, 0, 0,
+ 0, 0, 0,0x48,0xFF,0x8C, 0, 0,
+ 0, 0, 0,0x48,0xFF,0x8C, 0, 0,
+ 0, 0, 0,0x48,0xFF,0x8C, 0, 0,
+ 0, 0,0xEC,0xFF,0xFF,0x8C, 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, 0, 0, 0,
+ 0, 0,0x17,0xE8,0xFF,0x6E, 0, 0,
+ 0,0x02,0xBC,0xFF,0xF9,0xF9,0x34, 0,
+ 0,0x7E,0xFF,0x8E,0x32,0xED,0xDD,0x0F,
+0x3F,0xFC,0x8C, 0, 0,0x30,0xEC,0xAB,
+ 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, 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, 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, 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, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+// '`'
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0x3F,0xFA,0x9A, 0, 0, 0, 0,
+ 0, 0,0x62,0xFE,0x40, 0, 0, 0,
+ 0, 0, 0,0x8B,0xDB,0x09, 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, 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, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+// 'a'
+ 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,0x1D,0xA0,0xE1,0xF9,0xDB,0x6F, 0,
+ 0,0x7C,0x65,0x21,0x10,0xBA,0xFF,0x3F,
+ 0, 0, 0, 0, 0,0x6F,0xFF,0x80,
+ 0,0x4F,0xC6,0xEE,0xFF,0xFF,0xFF,0x92,
+0x23,0xFB,0xF8,0x44,0x07,0x74,0xFF,0x94,
+0x50,0xFF,0xD1, 0, 0,0x99,0xFF,0x94,
+0x26,0xFD,0xF3,0x25,0x35,0xF0,0xFF,0x94,
+ 0,0x60,0xDC,0xF6,0xCE,0xAD,0xFF,0x94,
+ 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,
+// 'b'
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0xF8,0xFF,0x04, 0, 0, 0, 0,
+ 0,0xF8,0xFF,0x04, 0, 0, 0, 0,
+ 0,0xF8,0xFF,0x04, 0, 0, 0, 0,
+ 0,0xF8,0xFF,0x91,0xEA,0xED,0x80, 0,
+ 0,0xF8,0xFF,0xA2,0x16,0xC5,0xFF,0x48,
+ 0,0xF8,0xFF,0x30, 0,0x5C,0xFF,0xA2,
+ 0,0xF8,0xFF,0x0D, 0,0x3A,0xFF,0xC2,
+ 0,0xF8,0xFF,0x0D, 0,0x3A,0xFF,0xC1,
+ 0,0xF8,0xFF,0x30, 0,0x5C,0xFF,0xA2,
+ 0,0xF8,0xFF,0xA2,0x16,0xC5,0xFF,0x46,
+ 0,0xF8,0xFF,0x92,0xEB,0xF0,0x82, 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,
+// 'c'
+ 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,0x3C,0xC2,0xF6,0xE0,0x87,0x06,
+ 0,0x22,0xF7,0xE0,0x32,0x0D,0x72,0x3A,
+ 0,0x98,0xFF,0x67, 0, 0, 0, 0,
+ 0,0xC5,0xFF,0x39, 0, 0, 0, 0,
+ 0,0xC5,0xFF,0x38, 0, 0, 0, 0,
+ 0,0x98,0xFF,0x66, 0, 0, 0, 0,
+ 0,0x22,0xF7,0xDF,0x30,0x13,0x70,0x39,
+ 0, 0,0x3D,0xC3,0xF7,0xE2,0x82,0x05,
+ 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,
+// 'd'
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,0x98,0xFF,0x68,
+ 0, 0, 0, 0, 0,0x98,0xFF,0x68,
+ 0, 0, 0, 0, 0,0x98,0xFF,0x68,
+ 0,0x34,0xD1,0xF6,0xC4,0xBE,0xFF,0x68,
+0x01,0xDA,0xFD,0x44,0x40,0xFC,0xFF,0x68,
+0x37,0xFF,0xCA, 0, 0,0xC4,0xFF,0x68,
+0x56,0xFF,0xA9, 0, 0,0xA2,0xFF,0x68,
+0x57,0xFF,0xA8, 0, 0,0xA2,0xFF,0x68,
+0x37,0xFF,0xCA, 0, 0,0xC4,0xFF,0x68,
+0x01,0xDB,0xFD,0x44,0x40,0xFC,0xFF,0x68,
+ 0,0x36,0xD4,0xF6,0xC5,0xBD,0xFF,0x68,
+ 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,
+// 'e'
+ 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,0x0B,0x94,0xE9,0xF4,0xCE,0x57, 0,
+ 0,0xA5,0xFE,0x50,0x0F,0xA7,0xFF,0x4D,
+0x21,0xFE,0xC9, 0, 0,0x39,0xFF,0xB4,
+0x4C,0xFF,0xFE,0xFC,0xFD,0xFF,0xFF,0xD7,
+0x57,0xFF,0xB8, 0, 0, 0, 0, 0,
+0x2B,0xFF,0xE2,0x02, 0, 0, 0, 0,
+ 0,0xB6,0xFF,0x83,0x10,0x1F,0x69,0x71,
+ 0,0x0B,0x8F,0xE3,0xF9,0xDA,0x8A,0x12,
+ 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,
+// 'f'
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0x4E,0xD8,0xF8,0xFF,0x68,
+ 0, 0, 0,0xD8,0xFF,0x2E, 0, 0,
+ 0, 0, 0,0xF2,0xFF,0x0C, 0, 0,
+ 0,0xD0,0xFF,0xFF,0xFF,0xFF,0xFF,0x68,
+ 0, 0, 0,0xF4,0xFF,0x0C, 0, 0,
+ 0, 0, 0,0xF4,0xFF,0x0C, 0, 0,
+ 0, 0, 0,0xF4,0xFF,0x0C, 0, 0,
+ 0, 0, 0,0xF4,0xFF,0x0C, 0, 0,
+ 0, 0, 0,0xF4,0xFF,0x0C, 0, 0,
+ 0, 0, 0,0xF4,0xFF,0x0C, 0, 0,
+ 0, 0, 0,0xF4,0xFF,0x0C, 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,
+// 'g'
+ 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,0x1F,0xC1,0xF7,0xD3,0xBF,0xFF,0x80,
+ 0,0xBC,0xFF,0x54,0x38,0xF9,0xFF,0x80,
+0x1F,0xFF,0xD9, 0, 0,0xB4,0xFF,0x80,
+0x43,0xFF,0xB5, 0, 0,0x8E,0xFF,0x80,
+0x47,0xFF,0xB5, 0, 0,0x8F,0xFF,0x80,
+0x25,0xFF,0xD9, 0, 0,0xB4,0xFF,0x80,
+ 0,0xC5,0xFF,0x54,0x37,0xF8,0xFF,0x80,
+ 0,0x24,0xC5,0xF8,0xD6,0xBF,0xFF,0x7E,
+ 0, 0, 0, 0, 0,0x97,0xFF,0x63,
+ 0,0x6B,0x52,0x11,0x2B,0xE8,0xF8,0x22,
+ 0,0x19,0xA3,0xE9,0xF8,0xCF,0x53, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+// 'h'
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0xD4,0xFF,0x2C, 0, 0, 0, 0,
+ 0,0xD4,0xFF,0x2C, 0, 0, 0, 0,
+ 0,0xD4,0xFF,0x2C, 0, 0, 0, 0,
+ 0,0xD4,0xFF,0xA4,0xE2,0xEF,0x89, 0,
+ 0,0xD4,0xFF,0x93,0x15,0xE1,0xFF,0x2E,
+ 0,0xD4,0xFF,0x39, 0,0xB1,0xFF,0x51,
+ 0,0xD4,0xFF,0x2C, 0,0xAC,0xFF,0x54,
+ 0,0xD4,0xFF,0x2C, 0,0xAC,0xFF,0x54,
+ 0,0xD4,0xFF,0x2C, 0,0xAC,0xFF,0x54,
+ 0,0xD4,0xFF,0x2C, 0,0xAC,0xFF,0x54,
+ 0,0xD4,0xFF,0x2C, 0,0xAC,0xFF,0x54,
+ 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,
+// 'i'
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0x88,0xFF,0x78, 0, 0,
+ 0, 0, 0,0x88,0xFF,0x78, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0x7C,0xFF,0xFF,0xFF,0x78, 0, 0,
+ 0, 0, 0,0x88,0xFF,0x78, 0, 0,
+ 0, 0, 0,0x88,0xFF,0x78, 0, 0,
+ 0, 0, 0,0x88,0xFF,0x78, 0, 0,
+ 0, 0, 0,0x88,0xFF,0x78, 0, 0,
+ 0, 0, 0,0x88,0xFF,0x78, 0, 0,
+ 0, 0, 0,0x88,0xFF,0x78, 0, 0,
+0x04,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF8,
+ 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,
+// 'j'
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0,0x30,0xFF,0xD0, 0, 0,
+ 0, 0, 0,0x30,0xFF,0xD0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,0x38,0xFF,0xFF,0xFF,0xD0, 0, 0,
+ 0, 0, 0,0x30,0xFF,0xD0, 0, 0,
+ 0, 0, 0,0x30,0xFF,0xD0, 0, 0,
+ 0, 0, 0,0x30,0xFF,0xD0, 0, 0,
+ 0, 0, 0,0x30,0xFF,0xD0, 0, 0,
+ 0, 0, 0,0x30,0xFF,0xD0, 0, 0,
+ 0, 0, 0,0x30,0xFF,0xD0, 0, 0,
+ 0, 0, 0,0x30,0xFF,0xD0, 0, 0,
+ 0, 0, 0,0x39,0xFF,0xC1, 0, 0,
+ 0, 0,0x04,0x8A,0xFF,0x91, 0, 0,
+0x04,0xFF,0xFF,0xF3,0xB6,0x18, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+// 'k'
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+0xD0,0xFF,0x30, 0, 0, 0, 0, 0,
+0xD0,0xFF,0x30, 0, 0, 0, 0, 0,
+0xD0,0xFF,0x30, 0, 0, 0, 0, 0,
+0xD0,0xFF,0x30,0x0C,0xCD,0xFF,0x8B, 0,
+0xD0,0xFF,0x34,0xB7,0xFF,0x91, 0, 0,
+0xD0,0xFF,0xC5,0xFF,0x97, 0, 0, 0,
+0xD0,0xFF,0xFF,0xFF,0x70, 0, 0, 0,
+0xD0,0xFF,0xA4,0xEC,0xF2,0x1A, 0, 0,
+0xD0,0xFF,0x30,0x6D,0xFF,0xA9, 0, 0,
+0xD0,0xFF,0x30,0x05,0xD9,0xFF,0x45, 0,
+0xD0,0xFF,0x30, 0,0x4F,0xFF,0xDA,0x07,
+ 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,
+// 'l'
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+0x64,0xFF,0xFF,0xFF,0xA8, 0, 0, 0,
+ 0, 0,0x5C,0xFF,0xA8, 0, 0, 0,
+ 0, 0,0x5C,0xFF,0xA8, 0, 0, 0,
+ 0, 0,0x5C,0xFF,0xA8, 0, 0, 0,
+ 0, 0,0x5C,0xFF,0xA8, 0, 0, 0,
+ 0, 0,0x5C,0xFF,0xA8, 0, 0, 0,
+ 0, 0,0x5C,0xFF,0xA8, 0, 0, 0,
+ 0, 0,0x5C,0xFF,0xA8, 0, 0, 0,
+ 0, 0,0x4E,0xFF,0xB1, 0, 0, 0,
+ 0, 0,0x21,0xFD,0xE8,0x1B, 0, 0,
+ 0, 0, 0,0x6C,0xE2,0xFE,0xFF,0x7C,
+ 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,
+// 'm'
+ 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,
+0x70,0xFF,0xBA,0xF2,0xAC,0xDE,0xED,0x56,
+0x70,0xFF,0x57,0xB7,0xFF,0x32,0xDF,0xC4,
+0x70,0xFF,0x35,0x96,0xFF,0x09,0xC2,0xDD,
+0x70,0xFF,0x34,0x94,0xFF,0x08,0xC0,0xE3,
+0x70,0xFF,0x34,0x94,0xFF,0x08,0xC0,0xE4,
+0x70,0xFF,0x34,0x94,0xFF,0x08,0xC0,0xE4,
+0x70,0xFF,0x34,0x94,0xFF,0x08,0xC0,0xE4,
+0x70,0xFF,0x34,0x94,0xFF,0x08,0xC0,0xE4,
+ 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,
+// 'n'
+ 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,0xD4,0xFF,0xA5,0xE2,0xEF,0x89, 0,
+ 0,0xD4,0xFF,0x97,0x15,0xE2,0xFF,0x2D,
+ 0,0xD4,0xFF,0x3A, 0,0xB1,0xFF,0x51,
+ 0,0xD4,0xFF,0x2C, 0,0xAC,0xFF,0x54,
+ 0,0xD4,0xFF,0x2C, 0,0xAC,0xFF,0x54,
+ 0,0xD4,0xFF,0x2C, 0,0xAC,0xFF,0x54,
+ 0,0xD4,0xFF,0x2C, 0,0xAC,0xFF,0x54,
+ 0,0xD4,0xFF,0x2C, 0,0xAC,0xFF,0x54,
+ 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,
+// 'o'
+ 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,0x09,0x93,0xE9,0xF8,0xC4,0x36, 0,
+ 0,0x9C,0xFF,0x5E,0x1D,0xDA,0xF1,0x17,
+0x18,0xFD,0xDB, 0, 0,0x70,0xFF,0x84,
+0x42,0xFF,0xB6, 0, 0,0x4A,0xFF,0xB1,
+0x42,0xFF,0xB5, 0, 0,0x4B,0xFF,0xB0,
+0x19,0xFD,0xDB, 0, 0,0x6F,0xFF,0x84,
+ 0,0x9C,0xFF,0x5C,0x1C,0xD8,0xF1,0x17,
+ 0,0x09,0x93,0xEB,0xF8,0xC5,0x37, 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,
+// 'p'
+ 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,0xF8,0xFF,0x90,0xE7,0xEF,0x81, 0,
+ 0,0xF8,0xFF,0xA2,0x16,0xC5,0xFF,0x46,
+ 0,0xF8,0xFF,0x30, 0,0x5C,0xFF,0xA2,
+ 0,0xF8,0xFF,0x0D, 0,0x3A,0xFF,0xC2,
+ 0,0xF8,0xFF,0x0D, 0,0x3A,0xFF,0xC1,
+ 0,0xF8,0xFF,0x30, 0,0x5C,0xFF,0xA2,
+ 0,0xF8,0xFF,0xA2,0x16,0xC5,0xFF,0x48,
+ 0,0xF8,0xFF,0x91,0xEB,0xEE,0x81, 0,
+ 0,0xF8,0xFF,0x04, 0, 0, 0, 0,
+ 0,0xF8,0xFF,0x04, 0, 0, 0, 0,
+ 0,0xF8,0xFF,0x04, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+// 'q'
+ 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,0x35,0xD3,0xF5,0xC1,0xBD,0xFF,0x68,
+0x01,0xDB,0xFD,0x44,0x40,0xFC,0xFF,0x68,
+0x37,0xFF,0xCA, 0, 0,0xC4,0xFF,0x68,
+0x56,0xFF,0xA9, 0, 0,0xA2,0xFF,0x68,
+0x57,0xFF,0xA8, 0, 0,0xA2,0xFF,0x68,
+0x37,0xFF,0xCA, 0, 0,0xC4,0xFF,0x68,
+0x01,0xDA,0xFD,0x44,0x40,0xFC,0xFF,0x68,
+ 0,0x34,0xD2,0xF7,0xC4,0xBE,0xFF,0x68,
+ 0, 0, 0, 0, 0,0x98,0xFF,0x68,
+ 0, 0, 0, 0, 0,0x98,0xFF,0x68,
+ 0, 0, 0, 0, 0,0x98,0xFF,0x68,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+// 'r'
+ 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,0x04,0xFF,0xFF,0x97,0xE1,0xFD,0xE0,
+ 0,0x04,0xFF,0xFF,0xC5,0x1E,0x18,0x81,
+ 0,0x04,0xFF,0xFF,0x2A, 0, 0, 0,
+ 0,0x04,0xFF,0xFF,0x04, 0, 0, 0,
+ 0,0x04,0xFF,0xFF, 0, 0, 0, 0,
+ 0,0x04,0xFF,0xFF, 0, 0, 0, 0,
+ 0,0x04,0xFF,0xFF, 0, 0, 0, 0,
+ 0,0x04,0xFF,0xFF, 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,
+// 's'
+ 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,0x11,0xA1,0xE9,0xEF,0xB4,0x2E, 0,
+ 0,0x9C,0xFF,0x4B,0x0B,0x41,0x95, 0,
+ 0,0xC8,0xFF,0x79,0x08, 0, 0, 0,
+ 0,0x84,0xFF,0xFF,0xF3,0xAE,0x32, 0,
+ 0,0x01,0x61,0xBA,0xF9,0xFF,0xF2,0x13,
+ 0, 0, 0, 0,0x14,0xCD,0xFF,0x40,
+ 0,0x90,0x59,0x16,0x12,0xC6,0xFB,0x1D,
+ 0,0x20,0x9B,0xE1,0xF6,0xD2,0x56, 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,
+// 't'
+ 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,0x48,0xFF,0xB8, 0, 0, 0,
+ 0, 0,0x48,0xFF,0xB8, 0, 0, 0,
+0x3C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x54,
+ 0, 0,0x48,0xFF,0xB8, 0, 0, 0,
+ 0, 0,0x48,0xFF,0xB8, 0, 0, 0,
+ 0, 0,0x48,0xFF,0xB8, 0, 0, 0,
+ 0, 0,0x48,0xFF,0xB8, 0, 0, 0,
+ 0, 0,0x45,0xFF,0xB8, 0, 0, 0,
+ 0, 0,0x27,0xFF,0xDF,0x11, 0, 0,
+ 0, 0, 0,0x89,0xE9,0xFE,0xFF,0x54,
+ 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,
+// 'u'
+ 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,0xE8,0xFF,0x18, 0,0xC0,0xFF,0x40,
+ 0,0xE8,0xFF,0x18, 0,0xC0,0xFF,0x40,
+ 0,0xE8,0xFF,0x18, 0,0xC0,0xFF,0x40,
+ 0,0xE8,0xFF,0x18, 0,0xC0,0xFF,0x40,
+ 0,0xE8,0xFF,0x18, 0,0xC0,0xFF,0x40,
+ 0,0xE5,0xFF,0x1C, 0,0xCE,0xFF,0x40,
+ 0,0xC3,0xFF,0x5D,0x30,0xFB,0xFF,0x40,
+ 0,0x3B,0xD9,0xF4,0xC1,0xD7,0xFF,0x40,
+ 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,
+// 'v'
+ 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,
+0x4E,0xFF,0xB5, 0, 0,0x46,0xFF,0xB8,
+0x09,0xF6,0xF3,0x05, 0,0x89,0xFF,0x6B,
+ 0,0xB2,0xFF,0x3B, 0,0xCC,0xFF,0x1E,
+ 0,0x64,0xFF,0x7E,0x11,0xFD,0xD0, 0,
+ 0,0x17,0xFE,0xC1,0x53,0xFF,0x82, 0,
+ 0, 0,0xC8,0xF9,0xA1,0xFF,0x35, 0,
+ 0, 0,0x7A,0xFF,0xFB,0xE6,0x01, 0,
+ 0, 0,0x2B,0xFF,0xFF,0x9A, 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,
+// 'w'
+ 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,
+0xEA,0xBE, 0, 0, 0, 0,0x50,0xFF,
+0xBE,0xE5, 0, 0, 0, 0,0x76,0xFF,
+0x91,0xFF,0x0B,0xB2,0xFF,0x20,0x9D,0xF9,
+0x65,0xFF,0x31,0xE6,0xFD,0x53,0xC4,0xD1,
+0x38,0xFF,0x70,0xFE,0xB0,0x86,0xEA,0xA5,
+0x0C,0xFE,0xCB,0xD5,0x68,0xCA,0xFF,0x79,
+ 0,0xDF,0xFF,0x9C,0x30,0xFF,0xFF,0x4D,
+ 0,0xB2,0xFF,0x64,0x03,0xF4,0xFF,0x21,
+ 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,
+// 'x'
+ 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,
+0x1D,0xF0,0xFF,0x35, 0,0xC7,0xFF,0x7D,
+ 0,0x60,0xFF,0xBD,0x50,0xFF,0xCC,0x04,
+ 0, 0,0xB2,0xFF,0xEB,0xF8,0x2B, 0,
+ 0, 0,0x18,0xF1,0xFF,0x7D, 0, 0,
+ 0, 0,0x42,0xFE,0xFF,0xB2, 0, 0,
+ 0,0x0D,0xE0,0xF9,0xC2,0xFF,0x5E, 0,
+ 0,0x9C,0xFF,0x8D,0x24,0xFA,0xEF,0x1A,
+0x49,0xFF,0xEE,0x11, 0,0x8F,0xFF,0xB5,
+ 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,
+// 'y'
+ 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,
+0x69,0xFF,0xAE, 0, 0,0x3A,0xFF,0xDF,
+0x11,0xF8,0xF7,0x0D, 0,0x8C,0xFF,0x89,
+ 0,0xAB,0xFF,0x5B, 0,0xDE,0xFF,0x32,
+ 0,0x4C,0xFF,0xB2,0x31,0xFF,0xDB, 0,
+ 0,0x04,0xE9,0xF8,0x93,0xFF,0x84, 0,
+ 0, 0,0x8E,0xFF,0xFD,0xFF,0x2D, 0,
+ 0, 0,0x30,0xFF,0xFF,0xD6, 0, 0,
+ 0, 0, 0,0xD2,0xFF,0x7F, 0, 0,
+ 0, 0,0x01,0xE4,0xFF,0x29, 0, 0,
+ 0,0x01,0x5D,0xFF,0xC5, 0, 0, 0,
+0x20,0xFF,0xFC,0xC9,0x23, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+// 'z'
+ 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,0xBC,0xFF,0xFF,0xFF,0xFF,0xFF,0x64,
+ 0, 0, 0, 0,0x42,0xFC,0xFF,0x5F,
+ 0, 0, 0,0x1B,0xE9,0xFF,0xCD,0x08,
+ 0, 0,0x05,0xC5,0xFF,0xEE,0x21, 0,
+ 0, 0,0x90,0xFF,0xFE,0x4C, 0, 0,
+ 0,0x56,0xFF,0xFF,0x84, 0, 0, 0,
+ 0,0xDF,0xFF,0xBC,0x02, 0, 0, 0,
+ 0,0xE4,0xFF,0xFF,0xFF,0xFF,0xFF,0x64,
+ 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, 0,
+ 0, 0, 0,0x26,0xCB,0xF7,0xFF,0x34,
+ 0, 0, 0,0x93,0xFF,0x6B,0x02, 0,
+ 0, 0, 0,0xAE,0xFF,0x30, 0, 0,
+ 0, 0, 0,0xB0,0xFF,0x2C, 0, 0,
+ 0, 0, 0,0xBD,0xFF,0x26, 0, 0,
+ 0,0x02,0x32,0xF4,0xF2,0x09, 0, 0,
+ 0,0xCC,0xFF,0xF6,0x58, 0, 0, 0,
+ 0,0x02,0x36,0xF6,0xEF,0x08, 0, 0,
+ 0, 0, 0,0xBE,0xFF,0x26, 0, 0,
+ 0, 0, 0,0xB0,0xFF,0x2C, 0, 0,
+ 0, 0, 0,0xAE,0xFF,0x30, 0, 0,
+ 0, 0, 0,0x93,0xFF,0x6A,0x02, 0,
+ 0, 0, 0,0x26,0xCC,0xF8,0xFF,0x34,
+ 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,0x90,0xFC, 0, 0, 0,
+ 0, 0, 0,0x90,0xFC, 0, 0, 0,
+ 0, 0, 0,0x90,0xFC, 0, 0, 0,
+ 0, 0, 0,0x90,0xFC, 0, 0, 0,
+ 0, 0, 0,0x90,0xFC, 0, 0, 0,
+ 0, 0, 0,0x90,0xFC, 0, 0, 0,
+ 0, 0, 0,0x90,0xFC, 0, 0, 0,
+ 0, 0, 0,0x90,0xFC, 0, 0, 0,
+ 0, 0, 0,0x90,0xFC, 0, 0, 0,
+ 0, 0, 0,0x90,0xFC, 0, 0, 0,
+ 0, 0, 0,0x90,0xFC, 0, 0, 0,
+ 0, 0, 0,0x90,0xFC, 0, 0, 0,
+ 0, 0, 0,0x90,0xFC, 0, 0, 0,
+ 0, 0, 0,0x90,0xFC, 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,0xC4,0xFC,0xE5,0x6E, 0, 0, 0,
+ 0, 0,0x17,0xE9,0xF8,0x02, 0, 0,
+ 0, 0, 0,0xC1,0xFF,0x16, 0, 0,
+ 0, 0, 0,0xBC,0xFF,0x18, 0, 0,
+ 0, 0, 0,0xB7,0xFF,0x24, 0, 0,
+ 0, 0, 0,0x8E,0xFF,0x89,0x0A, 0,
+ 0, 0, 0,0x11,0xD1,0xFF,0xFF,0x38,
+ 0, 0, 0,0x8B,0xFF,0x8C,0x0B, 0,
+ 0, 0, 0,0xB6,0xFF,0x25, 0, 0,
+ 0, 0, 0,0xBC,0xFF,0x18, 0, 0,
+ 0, 0, 0,0xC1,0xFF,0x16, 0, 0,
+ 0, 0,0x17,0xE9,0xF8,0x02, 0, 0,
+ 0,0xC4,0xFD,0xE6,0x6F, 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, 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,
+0x16,0xAC,0xF1,0xD8,0x72,0x14,0x28,0x8A,
+0x64,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xD4,
+0x51,0x53,0x0D,0x31,0x9D,0xF1,0xD7,0x4C,
+ 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, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ // clang-format on
+};
+} // anonymous namespace
+
+const uint8_t *OverlayState::getFontData() const
+{
+ return kFontData;
+}
+#else
+const uint8_t *OverlayState::getFontData() const
+{
+ return nullptr;
+}
+#endif
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/Overlay_font_autogen.h b/gfx/angle/checkout/src/libANGLE/Overlay_font_autogen.h
new file mode 100644
index 0000000000..333c0ee3c6
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Overlay_font_autogen.h
@@ -0,0 +1,27 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_overlay_fonts.py using overlay/DejaVuSansMono-Bold.ttf.
+//
+// Copyright 2022 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.
+//
+// Overlay_font_autogen.h:
+// Autogenerated overlay font data.
+
+#include "libANGLE/Overlay.h"
+
+namespace gl
+{
+namespace overlay
+{
+constexpr uint32_t kFontMipCount = 2;
+constexpr uint32_t kFontCharacters = 95;
+constexpr uint32_t kFontGlyphWidth = 17;
+constexpr uint32_t kFontGlyphHeight = 34;
+constexpr uint32_t kFontMipDataSize[kFontMipCount] = {54910, 12920};
+constexpr uint32_t kFontMipDataOffset[kFontMipCount] = {0, 54910};
+constexpr uint32_t kFontTotalDataSize = 67830;
+constexpr uint32_t kFontMipLarge = 0;
+constexpr uint32_t kFontMipSmall = 1;
+} // namespace overlay
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/PixelLocalStorage.cpp b/gfx/angle/checkout/src/libANGLE/PixelLocalStorage.cpp
new file mode 100644
index 0000000000..e5e560af5f
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/PixelLocalStorage.cpp
@@ -0,0 +1,826 @@
+//
+// Copyright 2022 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.
+//
+
+// PixelLocalStorage.cpp: Defines the renderer-agnostic container classes
+// gl::PixelLocalStorage and gl::PixelLocalStoragePlane for
+// ANGLE_shader_pixel_local_storage.
+
+#include "libANGLE/PixelLocalStorage.h"
+
+#include <numeric>
+#include "libANGLE/Context.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/Texture.h"
+#include "libANGLE/renderer/ContextImpl.h"
+
+namespace gl
+{
+// RAII utilities for working with GL state.
+namespace
+{
+class ScopedBindTexture2D
+{
+ public:
+ ScopedBindTexture2D(Context *context, TextureID texture)
+ : mContext(context),
+ mSavedTexBinding2D(
+ mContext->getState().getSamplerTextureId(mContext->getState().getActiveSampler(),
+ TextureType::_2D))
+ {
+ mContext->bindTexture(TextureType::_2D, texture);
+ }
+
+ ~ScopedBindTexture2D() { mContext->bindTexture(TextureType::_2D, mSavedTexBinding2D); }
+
+ private:
+ Context *const mContext;
+ TextureID mSavedTexBinding2D;
+};
+
+class ScopedRestoreDrawFramebuffer
+{
+ public:
+ ScopedRestoreDrawFramebuffer(Context *context)
+ : mContext(context), mSavedFramebuffer(mContext->getState().getDrawFramebuffer())
+ {
+ ASSERT(mSavedFramebuffer);
+ }
+
+ ~ScopedRestoreDrawFramebuffer() { mContext->bindDrawFramebuffer(mSavedFramebuffer->id()); }
+
+ private:
+ Context *const mContext;
+ Framebuffer *const mSavedFramebuffer;
+};
+
+class ScopedDisableScissor
+{
+ public:
+ ScopedDisableScissor(Context *context)
+ : mContext(context), mScissorTestEnabled(mContext->getState().isScissorTestEnabled())
+ {
+ if (mScissorTestEnabled)
+ {
+ mContext->disable(GL_SCISSOR_TEST);
+ }
+ }
+
+ ~ScopedDisableScissor()
+ {
+ if (mScissorTestEnabled)
+ {
+ mContext->enable(GL_SCISSOR_TEST);
+ }
+ }
+
+ private:
+ Context *const mContext;
+ const GLint mScissorTestEnabled;
+};
+} // namespace
+
+PixelLocalStoragePlane::~PixelLocalStoragePlane()
+{
+ // Call deinitialize or onContextObjectsLost first!
+ ASSERT(mMemorylessTextureID.value == 0);
+ // Call deinitialize or onFramebufferDestroyed first!
+ ASSERT(mTextureRef == nullptr);
+}
+
+void PixelLocalStoragePlane::onContextObjectsLost()
+{
+ // We normally call deleteTexture on the memoryless plane texture ID, since we own it, but in
+ // this case we can let it go.
+ mMemorylessTextureID = TextureID();
+}
+
+void PixelLocalStoragePlane::onFramebufferDestroyed(const Context *context)
+{
+ if (mTextureRef != nullptr)
+ {
+ mTextureRef->release(context);
+ mTextureRef = nullptr;
+ }
+}
+
+void PixelLocalStoragePlane::deinitialize(Context *context)
+{
+ mInternalformat = GL_NONE;
+ mMemoryless = false;
+ if (mMemorylessTextureID.value != 0)
+ {
+ // The app could have technically deleted mMemorylessTextureID by guessing its value and
+ // calling glDeleteTextures, but it seems unnecessary to worry about that here. (Worst case
+ // we delete one of their textures.) This also isn't a problem in WebGL.
+ context->deleteTexture(mMemorylessTextureID);
+ mMemorylessTextureID = TextureID();
+ }
+ if (mTextureRef != nullptr)
+ {
+ mTextureRef->release(context);
+ mTextureRef = nullptr;
+ }
+}
+
+void PixelLocalStoragePlane::setMemoryless(Context *context, GLenum internalformat)
+{
+ deinitialize(context);
+ mInternalformat = internalformat;
+ mMemoryless = true;
+ mTextureImageIndex = ImageIndex::MakeFromType(TextureType::_2D, 0, 0);
+ // The backing texture will get allocated lazily, once we know what dimensions it should be.
+ ASSERT(mMemorylessTextureID.value == 0);
+ ASSERT(mTextureRef == nullptr);
+}
+
+void PixelLocalStoragePlane::setTextureBacked(Context *context, Texture *tex, int level, int layer)
+{
+ deinitialize(context);
+ ASSERT(tex->getImmutableFormat());
+ mInternalformat = tex->getState().getBaseLevelDesc().format.info->internalFormat;
+ mMemoryless = false;
+ mTextureImageIndex = ImageIndex::MakeFromType(tex->getType(), level, layer);
+ mTextureRef = tex;
+ mTextureRef->addRef();
+}
+
+bool PixelLocalStoragePlane::isTextureIDDeleted(const Context *context) const
+{
+ // We can tell if the texture has been deleted by looking up mTextureRef's ID on the Context. If
+ // they don't match, it's been deleted.
+ ASSERT(!isDeinitialized() || mTextureRef == nullptr);
+ return mTextureRef != nullptr && context->getTexture(mTextureRef->id()) != mTextureRef;
+}
+
+GLint PixelLocalStoragePlane::getIntegeri(const Context *context, GLenum target, GLuint index) const
+{
+ if (!isDeinitialized())
+ {
+ bool memoryless = isMemoryless() || isTextureIDDeleted(context);
+ switch (target)
+ {
+ case GL_PIXEL_LOCAL_FORMAT_ANGLE:
+ return mInternalformat;
+ case GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE:
+ return memoryless ? 0 : mTextureRef->id().value;
+ case GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE:
+ return memoryless ? 0 : mTextureImageIndex.getLevelIndex();
+ case GL_PIXEL_LOCAL_TEXTURE_LAYER_ANGLE:
+ return memoryless ? 0 : mTextureImageIndex.getLayerIndex();
+ }
+ }
+ // Since GL_NONE == 0, PLS queries all return 0 when the plane is deinitialized.
+ static_assert(GL_NONE == 0, "Expecting GL_NONE to be zero.");
+ return 0;
+}
+
+bool PixelLocalStoragePlane::getTextureImageExtents(const Context *context, Extents *extents) const
+{
+ if (isDeinitialized() || isMemoryless() || isTextureIDDeleted(context))
+ {
+ return false;
+ }
+ ASSERT(mTextureRef != nullptr);
+ *extents =
+ mTextureRef->getExtents(mTextureImageIndex.getTarget(), mTextureImageIndex.getLevelIndex());
+ extents->depth = 0;
+ return true;
+}
+
+void PixelLocalStoragePlane::ensureBackingIfMemoryless(Context *context, Extents plsExtents)
+{
+ ASSERT(!isDeinitialized());
+ ASSERT(!isTextureIDDeleted(context)); // Convert to memoryless first in this case.
+ if (!isMemoryless())
+ {
+ ASSERT(mTextureRef != nullptr);
+ return;
+ }
+
+ // Internal textures backing memoryless planes are always 2D and not mipmapped.
+ ASSERT(mTextureImageIndex.getType() == TextureType::_2D);
+ ASSERT(mTextureImageIndex.getLevelIndex() == 0);
+ ASSERT(mTextureImageIndex.getLayerIndex() == 0);
+ const bool hasMemorylessTextureId = mMemorylessTextureID.value != 0;
+ const bool hasTextureRef = mTextureRef != nullptr;
+ ASSERT(hasMemorylessTextureId == hasTextureRef);
+
+ // Do we need to allocate a new backing texture?
+ if (mTextureRef == nullptr ||
+ static_cast<GLsizei>(mTextureRef->getWidth(TextureTarget::_2D, 0)) != plsExtents.width ||
+ static_cast<GLsizei>(mTextureRef->getHeight(TextureTarget::_2D, 0)) != plsExtents.height)
+ {
+ // Call setMemoryless() to release our current data.
+ setMemoryless(context, mInternalformat);
+ ASSERT(mTextureRef == nullptr);
+ ASSERT(mMemorylessTextureID.value == 0);
+
+ // Create a new texture that backs the memoryless plane.
+ context->genTextures(1, &mMemorylessTextureID);
+ {
+ ScopedBindTexture2D scopedBindTexture2D(context, mMemorylessTextureID);
+ context->bindTexture(TextureType::_2D, mMemorylessTextureID);
+ context->texStorage2D(TextureType::_2D, 1, mInternalformat, plsExtents.width,
+ plsExtents.height);
+ }
+
+ mTextureRef = context->getTexture(mMemorylessTextureID);
+ ASSERT(mTextureRef != nullptr);
+ ASSERT(mTextureRef->id() == mMemorylessTextureID);
+ mTextureRef->addRef();
+ }
+}
+
+void PixelLocalStoragePlane::attachToDrawFramebuffer(Context *context,
+ Extents plsExtents,
+ GLenum colorAttachment)
+{
+ ASSERT(!isDeinitialized());
+ ensureBackingIfMemoryless(context, plsExtents);
+ ASSERT(mTextureRef != nullptr);
+ if (mTextureImageIndex.usesTex3D()) // GL_TEXTURE_3D or GL_TEXTURE_2D_ARRAY.
+ {
+ context->framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, colorAttachment, mTextureRef->id(),
+ mTextureImageIndex.getLevelIndex(),
+ mTextureImageIndex.getLayerIndex());
+ }
+ else
+ {
+ context->framebufferTexture2D(GL_DRAW_FRAMEBUFFER, colorAttachment,
+ mTextureImageIndex.getTarget(), mTextureRef->id(),
+ mTextureImageIndex.getLevelIndex());
+ }
+}
+
+void PixelLocalStoragePlane::performLoadOperationClear(Context *context,
+ GLint drawBuffer,
+ GLenum loadop,
+ const void *data)
+{
+ // The GL scissor test must be disabled, since the intention is to clear the entire surface.
+ ASSERT(!context->getState().isScissorTestEnabled());
+ switch (mInternalformat)
+ {
+ case GL_RGBA8:
+ case GL_R32F:
+ {
+ GLfloat clearValue[4]{};
+ if (loadop == GL_CLEAR_ANGLE)
+ {
+ memcpy(clearValue, data, sizeof(clearValue));
+ }
+ context->clearBufferfv(GL_COLOR, drawBuffer, clearValue);
+ break;
+ }
+ case GL_RGBA8I:
+ {
+ GLint clearValue[4]{};
+ if (loadop == GL_CLEAR_ANGLE)
+ {
+ memcpy(clearValue, data, sizeof(clearValue));
+ }
+ context->clearBufferiv(GL_COLOR, drawBuffer, clearValue);
+ break;
+ }
+ case GL_RGBA8UI:
+ case GL_R32UI:
+ {
+ GLuint clearValue[4]{};
+ if (loadop == GL_CLEAR_ANGLE)
+ {
+ memcpy(clearValue, data, sizeof(clearValue));
+ }
+ context->clearBufferuiv(GL_COLOR, drawBuffer, clearValue);
+ break;
+ }
+ default:
+ // Invalid PLS internalformats should not have made it this far.
+ UNREACHABLE();
+ }
+}
+
+void PixelLocalStoragePlane::bindToImage(Context *context,
+ Extents plsExtents,
+ GLuint unit,
+ bool needsR32Packing)
+{
+ ASSERT(!isDeinitialized());
+ ensureBackingIfMemoryless(context, plsExtents);
+ ASSERT(mTextureRef != nullptr);
+ GLenum imageBindingFormat = mInternalformat;
+ if (needsR32Packing)
+ {
+ // D3D and ES require us to pack all PLS formats into r32f, r32i, or r32ui images.
+ switch (imageBindingFormat)
+ {
+ case GL_RGBA8:
+ case GL_RGBA8UI:
+ imageBindingFormat = GL_R32UI;
+ break;
+ case GL_RGBA8I:
+ imageBindingFormat = GL_R32I;
+ break;
+ }
+ }
+ if (mTextureRef->getType() != TextureType::_2D)
+ {
+ // TODO(anglebug.com/7279): Texture types other than GL_TEXTURE_2D will take a lot of
+ // consideration to support on all backends. Hold of on fully implementing them until the
+ // other backends are in place.
+ UNIMPLEMENTED();
+ }
+ context->bindImageTexture(unit, mTextureRef->id(), mTextureImageIndex.getLevelIndex(), GL_FALSE,
+ mTextureImageIndex.getLayerIndex(), GL_READ_WRITE,
+ imageBindingFormat);
+}
+
+PixelLocalStorage::PixelLocalStorage() {}
+PixelLocalStorage::~PixelLocalStorage() {}
+
+void PixelLocalStorage::onFramebufferDestroyed(const Context *context)
+{
+ if (context->getRefCount() == 0)
+ {
+ // If the Context's refcount is zero, we know it's in a teardown state and we can just let
+ // go of our GL objects -- they get cleaned up as part of context teardown. Otherwise, the
+ // Context should have called deleteContextObjects before reaching this point.
+ onContextObjectsLost();
+ for (PixelLocalStoragePlane &plane : mPlanes)
+ {
+ plane.onContextObjectsLost();
+ }
+ }
+ for (PixelLocalStoragePlane &plane : mPlanes)
+ {
+ plane.onFramebufferDestroyed(context);
+ }
+}
+
+void PixelLocalStorage::deleteContextObjects(Context *context)
+{
+ onDeleteContextObjects(context);
+ for (PixelLocalStoragePlane &plane : mPlanes)
+ {
+ plane.deinitialize(context);
+ }
+}
+
+void PixelLocalStorage::begin(Context *context,
+ GLsizei n,
+ const GLenum loadops[],
+ const void *cleardata)
+{
+ // Convert planes whose backing texture has been deleted to memoryless, and find the pixel local
+ // storage rendering dimensions.
+ Extents plsExtents;
+ bool hasPLSExtents = false;
+ for (int i = 0; i < n; ++i)
+ {
+ if (loadops[i] == GL_DISABLE_ANGLE)
+ {
+ continue;
+ }
+ PixelLocalStoragePlane &plane = mPlanes[i];
+ if (plane.isTextureIDDeleted(context))
+ {
+ // [ANGLE_shader_pixel_local_storage] Section 4.4.2.X "Configuring Pixel Local Storage
+ // on a Framebuffer": When a texture object is deleted, any pixel local storage plane to
+ // which it was bound is automatically converted to a memoryless plane of matching
+ // internalformat.
+ plane.setMemoryless(context, plane.getInternalformat());
+ }
+ if (!hasPLSExtents && plane.getTextureImageExtents(context, &plsExtents))
+ {
+ hasPLSExtents = true;
+ }
+ }
+ if (!hasPLSExtents)
+ {
+ // All PLS planes are memoryless. Use the rendering area of the framebuffer instead.
+ plsExtents =
+ context->getState().getDrawFramebuffer()->getState().getAttachmentExtentsIntersection();
+ ASSERT(plsExtents.depth == 0);
+ }
+
+ onBegin(context, n, loadops, reinterpret_cast<const char *>(cleardata), plsExtents);
+ mNumActivePLSPlanes = n;
+}
+
+void PixelLocalStorage::end(Context *context)
+{
+ onEnd(context, mNumActivePLSPlanes);
+ mNumActivePLSPlanes = 0;
+}
+
+void PixelLocalStorage::barrier(Context *context)
+{
+ ASSERT(!context->getExtensions().shaderPixelLocalStorageCoherentANGLE);
+ onBarrier(context);
+}
+
+namespace
+{
+// Implements pixel local storage with image load/store shader operations.
+class PixelLocalStorageImageLoadStore : public PixelLocalStorage
+{
+ public:
+ PixelLocalStorageImageLoadStore(bool needsR32Packing) : mNeedsR32Packing(needsR32Packing) {}
+
+ // Call deleteContextObjects or onContextObjectsLost first!
+ ~PixelLocalStorageImageLoadStore() override
+ {
+ ASSERT(mScratchFramebufferForClearing.value == 0);
+ }
+
+ void onContextObjectsLost() override
+ {
+ mScratchFramebufferForClearing = FramebufferID(); // Let go of GL objects.
+ }
+
+ void onDeleteContextObjects(Context *context) override
+ {
+ if (mScratchFramebufferForClearing.value != 0)
+ {
+ context->deleteFramebuffer(mScratchFramebufferForClearing);
+ mScratchFramebufferForClearing = FramebufferID();
+ }
+ }
+
+ void onBegin(Context *context,
+ GLsizei n,
+ const GLenum loadops[],
+ const char *cleardata,
+ Extents plsExtents) override
+ {
+ // Save the image bindings so we can restore them during onEnd().
+ const State &state = context->getState();
+ ASSERT(static_cast<size_t>(n) <= state.getImageUnits().size());
+ mSavedImageBindings.clear();
+ mSavedImageBindings.reserve(n);
+ for (int i = 0; i < n; ++i)
+ {
+ mSavedImageBindings.emplace_back(state.getImageUnit(i));
+ }
+
+ // Save the default framebuffer width/height so we can restore it during onEnd().
+ Framebuffer *framebuffer = state.getDrawFramebuffer();
+ mSavedFramebufferDefaultWidth = framebuffer->getDefaultWidth();
+ mSavedFramebufferDefaultHeight = framebuffer->getDefaultHeight();
+
+ // Specify the framebuffer width/height explicitly in case we end up rendering exclusively
+ // to shader images.
+ context->framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH,
+ plsExtents.width);
+ context->framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT,
+ plsExtents.height);
+
+ // Guard GL state and bind a scratch framebuffer in case we need to reallocate or clear any
+ // PLS planes.
+ const size_t maxDrawBuffers = context->getCaps().maxDrawBuffers;
+ ScopedRestoreDrawFramebuffer ScopedRestoreDrawFramebuffer(context);
+ if (mScratchFramebufferForClearing.value == 0)
+ {
+ context->genFramebuffers(1, &mScratchFramebufferForClearing);
+ context->bindFramebuffer(GL_DRAW_FRAMEBUFFER, mScratchFramebufferForClearing);
+ // Turn on all draw buffers on the scratch framebuffer for clearing.
+ DrawBuffersVector<GLenum> drawBuffers(maxDrawBuffers);
+ std::iota(drawBuffers.begin(), drawBuffers.end(), GL_COLOR_ATTACHMENT0);
+ context->drawBuffers(static_cast<int>(drawBuffers.size()), drawBuffers.data());
+ }
+ else
+ {
+ context->bindFramebuffer(GL_DRAW_FRAMEBUFFER, mScratchFramebufferForClearing);
+ }
+ ScopedDisableScissor scopedDisableScissor(context);
+
+ // Bind and clear the PLS planes.
+ size_t maxClearedAttachments = 0;
+ for (int i = 0; i < n;)
+ {
+ angle::FixedVector<int, IMPLEMENTATION_MAX_DRAW_BUFFERS> pendingClears;
+ for (; pendingClears.size() < maxDrawBuffers && i < n; ++i)
+ {
+ GLenum loadop = loadops[i];
+ if (loadop == GL_DISABLE_ANGLE)
+ {
+ continue;
+ }
+ PixelLocalStoragePlane &plane = getPlane(i);
+ ASSERT(!plane.isDeinitialized());
+ plane.bindToImage(context, plsExtents, i, mNeedsR32Packing);
+ if (loadop == GL_ZERO || loadop == GL_CLEAR_ANGLE)
+ {
+ plane.attachToDrawFramebuffer(
+ context, plsExtents,
+ GL_COLOR_ATTACHMENT0 + static_cast<GLenum>(pendingClears.size()));
+ pendingClears.push_back(i); // Defer the clear for later.
+ }
+ }
+ // Clear in batches to be more efficient with GL state.
+ for (size_t drawBufferIdx = 0; drawBufferIdx < pendingClears.size(); ++drawBufferIdx)
+ {
+ int plsIdx = pendingClears[drawBufferIdx];
+ getPlane(plsIdx).performLoadOperationClear(
+ context, static_cast<GLint>(drawBufferIdx), loadops[plsIdx],
+ cleardata + plsIdx * 4 * 4);
+ }
+ maxClearedAttachments = std::max(maxClearedAttachments, pendingClears.size());
+ }
+
+ // Detach the cleared PLS textures from the scratch framebuffer.
+ for (size_t i = 0; i < maxClearedAttachments; ++i)
+ {
+ context->framebufferTexture2D(GL_DRAW_FRAMEBUFFER,
+ GL_COLOR_ATTACHMENT0 + static_cast<GLenum>(i),
+ TextureTarget::_2D, TextureID(), 0);
+ }
+
+ // Unlike other barriers, GL_SHADER_IMAGE_ACCESS_BARRIER_BIT also synchronizes all types of
+ // memory accesses that happened before the barrier:
+ //
+ // SHADER_IMAGE_ACCESS_BARRIER_BIT: Memory accesses using shader built-in image load and
+ // store functions issued after the barrier will reflect data written by shaders prior to
+ // the barrier. Additionally, image stores issued after the barrier will not execute until
+ // all memory accesses (e.g., loads, stores, texture fetches, vertex fetches) initiated
+ // prior to the barrier complete.
+ //
+ // So we don't any barriers other than GL_SHADER_IMAGE_ACCESS_BARRIER_BIT during begin().
+ context->memoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
+ }
+
+ void onEnd(Context *context, GLsizei numActivePLSPlanes) override
+ {
+ // Restore the image bindings. Since glBindImageTexture and any commands that modify
+ // textures are banned while PLS is active, these will all still be alive and valid.
+ ASSERT(mSavedImageBindings.size() == static_cast<size_t>(numActivePLSPlanes));
+ for (GLuint unit = 0; unit < mSavedImageBindings.size(); ++unit)
+ {
+ ImageUnit &binding = mSavedImageBindings[unit];
+ context->bindImageTexture(unit, binding.texture.id(), binding.level, binding.layered,
+ binding.layer, binding.access, binding.format);
+
+ // BindingPointers have to be explicitly cleaned up.
+ binding.texture.set(context, nullptr);
+ }
+ mSavedImageBindings.clear();
+
+ // Restore the default framebuffer width/height.
+ context->framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH,
+ mSavedFramebufferDefaultWidth);
+ context->framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT,
+ mSavedFramebufferDefaultHeight);
+
+ // We need ALL_BARRIER_BITS during end() because GL_SHADER_IMAGE_ACCESS_BARRIER_BIT doesn't
+ // synchronize all types of memory accesses that can happen after the barrier.
+ context->memoryBarrier(GL_ALL_BARRIER_BITS);
+ }
+
+ void onBarrier(Context *context) override
+ {
+ context->memoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
+ }
+
+ private:
+ // D3D and ES require us to pack all PLS formats into r32f, r32i, or r32ui images.
+ const bool mNeedsR32Packing;
+ FramebufferID mScratchFramebufferForClearing{};
+
+ // Saved values to restore during onEnd().
+ GLint mSavedFramebufferDefaultWidth;
+ GLint mSavedFramebufferDefaultHeight;
+ std::vector<ImageUnit> mSavedImageBindings;
+};
+
+// Implements pixel local storage via framebuffer fetch.
+class PixelLocalStorageFramebufferFetch : public PixelLocalStorage
+{
+ public:
+ void onContextObjectsLost() override {}
+
+ void onDeleteContextObjects(Context *) override {}
+
+ void onBegin(Context *context,
+ GLsizei n,
+ const GLenum loadops[],
+ const char *cleardata,
+ Extents plsExtents) override
+ {
+ const State &state = context->getState();
+ const Caps &caps = context->getCaps();
+ Framebuffer *framebuffer = context->getState().getDrawFramebuffer();
+ const DrawBuffersVector<GLenum> &appDrawBuffers = framebuffer->getDrawBufferStates();
+
+ // Remember the current draw buffer state so we can restore it during onEnd().
+ mSavedDrawBuffers.resize(appDrawBuffers.size());
+ std::copy(appDrawBuffers.begin(), appDrawBuffers.end(), mSavedDrawBuffers.begin());
+
+ // Set up new draw buffers for PLS.
+ int firstPLSDrawBuffer = caps.maxCombinedDrawBuffersAndPixelLocalStoragePlanes - n;
+ int numAppDrawBuffers =
+ std::min(static_cast<int>(appDrawBuffers.size()), firstPLSDrawBuffer);
+ DrawBuffersArray<GLenum> plsDrawBuffers;
+ std::copy(appDrawBuffers.begin(), appDrawBuffers.begin() + numAppDrawBuffers,
+ plsDrawBuffers.begin());
+ std::fill(plsDrawBuffers.begin() + numAppDrawBuffers,
+ plsDrawBuffers.begin() + firstPLSDrawBuffer, GL_NONE);
+
+ mBlendsToReEnable.reset();
+ mColorMasksToRestore.reset();
+ mInvalidateList.clear();
+ bool needsClear = false;
+
+ bool hasIndexedBlendAndColorMask = context->getExtensions().drawBuffersIndexedAny();
+ if (!hasIndexedBlendAndColorMask)
+ {
+ // We don't have indexed blend and color mask control. Disable them globally. (This also
+ // means the app can't have its own draw buffers while PLS is active.)
+ ASSERT(caps.maxColorAttachmentsWithActivePixelLocalStorage == 0);
+ if (state.isBlendEnabled())
+ {
+ context->disable(GL_BLEND);
+ mBlendsToReEnable.set(0);
+ }
+ std::array<bool, 4> &mask = mSavedColorMasks[0];
+ state.getBlendStateExt().getColorMaskIndexed(0, &mask[0], &mask[1], &mask[2], &mask[3]);
+ if (!(mask[0] && mask[1] && mask[2] && mask[3]))
+ {
+ context->colorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ mColorMasksToRestore.set(0);
+ }
+ }
+
+ for (GLsizei i = 0; i < n; ++i)
+ {
+ GLuint drawBufferIdx = getDrawBufferIdx(caps, i);
+ GLenum loadop = loadops[i];
+ if (loadop == GL_DISABLE_ANGLE)
+ {
+ plsDrawBuffers[drawBufferIdx] = GL_NONE;
+ continue;
+ }
+
+ PixelLocalStoragePlane &plane = getPlane(i);
+ ASSERT(!plane.isDeinitialized());
+
+ // Attach our PLS texture to the framebuffer. Validation should have already ensured
+ // nothing else was attached at this point.
+ GLenum colorAttachment = GL_COLOR_ATTACHMENT0 + drawBufferIdx;
+ ASSERT(!framebuffer->getAttachment(context, colorAttachment));
+ plane.attachToDrawFramebuffer(context, plsExtents, colorAttachment);
+ plsDrawBuffers[drawBufferIdx] = colorAttachment;
+
+ if (hasIndexedBlendAndColorMask)
+ {
+ // Ensure blend and color mask are disabled for this draw buffer.
+ if (state.isBlendEnabledIndexed(drawBufferIdx))
+ {
+ context->disablei(GL_BLEND, drawBufferIdx);
+ mBlendsToReEnable.set(drawBufferIdx);
+ }
+ std::array<bool, 4> &mask = mSavedColorMasks[drawBufferIdx];
+ state.getBlendStateExt().getColorMaskIndexed(drawBufferIdx, &mask[0], &mask[1],
+ &mask[2], &mask[3]);
+ if (!(mask[0] && mask[1] && mask[2] && mask[3]))
+ {
+ context->colorMaski(drawBufferIdx, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ mColorMasksToRestore.set(drawBufferIdx);
+ }
+ }
+
+ if (plane.isMemoryless())
+ {
+ // Memoryless planes don't need to be preserved after glEndPixelLocalStorageANGLE().
+ mInvalidateList.push_back(colorAttachment);
+ }
+
+ needsClear = needsClear || (loadop != GL_KEEP);
+ }
+
+ // Turn on the PLS draw buffers.
+ context->drawBuffers(caps.maxCombinedDrawBuffersAndPixelLocalStoragePlanes,
+ plsDrawBuffers.data());
+
+ // Clear the non-KEEP PLS planes now that their draw buffers are turned on.
+ if (needsClear)
+ {
+ ScopedDisableScissor scopedDisableScissor(context);
+ for (GLsizei i = 0; i < n; ++i)
+ {
+ GLenum loadop = loadops[i];
+ if (loadop != GL_DISABLE_ANGLE && loadop != GL_KEEP)
+ {
+ GLuint drawBufferIdx = getDrawBufferIdx(caps, i);
+ getPlane(i).performLoadOperationClear(context, drawBufferIdx, loadop,
+ cleardata + i * 4 * 4);
+ }
+ }
+ }
+
+ if (!context->getExtensions().shaderPixelLocalStorageCoherentANGLE)
+ {
+ // Insert a barrier if we aren't coherent, since the textures may have been rendered to
+ // previously.
+ barrier(context);
+ }
+ }
+
+ void onEnd(Context *context, GLint numActivePLSPlanes) override
+ {
+
+ const Caps &caps = context->getCaps();
+
+ // Invalidate the memoryless PLS attachments.
+ if (!mInvalidateList.empty())
+ {
+ context->invalidateFramebuffer(GL_DRAW_FRAMEBUFFER,
+ static_cast<GLsizei>(mInvalidateList.size()),
+ mInvalidateList.data());
+ mInvalidateList.clear();
+ }
+
+ bool hasIndexedBlendAndColorMask = context->getExtensions().drawBuffersIndexedAny();
+ if (!hasIndexedBlendAndColorMask)
+ {
+ // Restore global blend and color mask. Validation should have ensured these didn't
+ // change while pixel local storage was active.
+ if (mBlendsToReEnable[0])
+ {
+ context->enable(GL_BLEND);
+ }
+ if (mColorMasksToRestore[0])
+ {
+ const std::array<bool, 4> &mask = mSavedColorMasks[0];
+ context->colorMask(mask[0], mask[1], mask[2], mask[3]);
+ }
+ }
+
+ for (GLsizei i = 0; i < numActivePLSPlanes; ++i)
+ {
+ // Reset color attachments where PLS was attached. Validation should have already
+ // ensured nothing was attached at these points when we activated pixel local storage,
+ // and that nothing got attached during.
+ GLuint drawBufferIdx = getDrawBufferIdx(caps, i);
+ GLenum colorAttachment = GL_COLOR_ATTACHMENT0 + drawBufferIdx;
+ context->framebufferTexture2D(GL_DRAW_FRAMEBUFFER, colorAttachment, TextureTarget::_2D,
+ TextureID(), 0);
+
+ if (hasIndexedBlendAndColorMask)
+ {
+ // Restore this draw buffer's blend and color mask. Validation should have ensured
+ // these did not change while pixel local storage was active.
+ if (mBlendsToReEnable[drawBufferIdx])
+ {
+ context->enablei(GL_BLEND, drawBufferIdx);
+ }
+ if (mColorMasksToRestore[drawBufferIdx])
+ {
+ const std::array<bool, 4> &mask = mSavedColorMasks[drawBufferIdx];
+ context->colorMaski(drawBufferIdx, mask[0], mask[1], mask[2], mask[3]);
+ }
+ }
+ }
+
+ // Restore the draw buffer state from before PLS was enabled.
+ context->drawBuffers(static_cast<GLsizei>(mSavedDrawBuffers.size()),
+ mSavedDrawBuffers.data());
+ mSavedDrawBuffers.clear();
+ }
+
+ void onBarrier(Context *context) override { context->framebufferFetchBarrier(); }
+
+ private:
+ GLuint getDrawBufferIdx(const Caps &caps, GLuint plsPlaneIdx)
+ {
+ // Bind the PLS attachments in reverse order from the rear. This way, the shader translator
+ // doesn't need to know how many planes are going to be active in order to figure out plane
+ // indices.
+ return caps.maxCombinedDrawBuffersAndPixelLocalStoragePlanes - plsPlaneIdx - 1;
+ }
+
+ DrawBuffersVector<GLenum> mSavedDrawBuffers;
+ DrawBufferMask mBlendsToReEnable;
+ DrawBufferMask mColorMasksToRestore;
+ DrawBuffersArray<std::array<bool, 4>> mSavedColorMasks;
+ DrawBuffersVector<GLenum> mInvalidateList;
+};
+} // namespace
+
+std::unique_ptr<PixelLocalStorage> PixelLocalStorage::Make(const Context *context)
+{
+ switch (context->getImplementation()->getNativePixelLocalStorageType())
+ {
+ case ShPixelLocalStorageType::ImageStoreR32PackedFormats:
+ return std::make_unique<PixelLocalStorageImageLoadStore>(true);
+ case ShPixelLocalStorageType::ImageStoreNativeFormats:
+ return std::make_unique<PixelLocalStorageImageLoadStore>(false);
+ case ShPixelLocalStorageType::FramebufferFetch:
+ return std::make_unique<PixelLocalStorageFramebufferFetch>();
+ default:
+ UNREACHABLE();
+ return nullptr;
+ }
+}
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/PixelLocalStorage.h b/gfx/angle/checkout/src/libANGLE/PixelLocalStorage.h
new file mode 100644
index 0000000000..f60ab7443d
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/PixelLocalStorage.h
@@ -0,0 +1,177 @@
+//
+// Copyright 2022 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.
+//
+
+// PixelLocalStorage.h: Defines the renderer-agnostic container classes
+// gl::PixelLocalStorage and gl::PixelLocalStoragePlane for
+// ANGLE_shader_pixel_local_storage.
+
+#ifndef LIBANGLE_PIXEL_LOCAL_STORAGE_H_
+#define LIBANGLE_PIXEL_LOCAL_STORAGE_H_
+
+#include "angle_gl.h"
+#include "libANGLE/ImageIndex.h"
+#include "libANGLE/angletypes.h"
+
+namespace gl
+{
+
+class Context;
+class Texture;
+
+// Holds the configuration of an ANGLE_shader_pixel_local_storage plane.
+//
+// Unlike normal framebuffer attachments, pixel local storage planes don't take effect until the
+// application calls glBeginPixelLocalStorageANGLE, and the manner in which they take effect is
+// highly dependent on the backend implementation. A PixelLocalStoragePlane is just a plain data
+// description what to set up later once PLS is enabled.
+class PixelLocalStoragePlane : angle::NonCopyable
+{
+ public:
+ ~PixelLocalStoragePlane();
+
+ // Called when the context is lost or destroyed. Causes this class to clear its GL object
+ // handles.
+ void onContextObjectsLost();
+
+ // Called when the owning framebuffer is being destroyed. Causes this class to release its
+ // texture object reference.
+ void onFramebufferDestroyed(const Context *);
+
+ void deinitialize(Context *);
+ void setMemoryless(Context *, GLenum internalformat);
+ void setTextureBacked(Context *, Texture *, int level, int layer);
+
+ bool isDeinitialized() const { return mInternalformat == GL_NONE; }
+
+ // Returns true if the texture ID bound to this plane has been deleted.
+ //
+ // [ANGLE_shader_pixel_local_storage] Section 4.4.2.X "Configuring Pixel Local Storage
+ // on a Framebuffer": When a texture object is deleted, any pixel local storage plane to
+ // which it was bound is automatically converted to a memoryless plane of matching
+ // internalformat.
+ bool isTextureIDDeleted(const Context *) const;
+
+ bool isMemoryless() const
+ {
+ // isMemoryless() should be false if the plane is deinitialized.
+ ASSERT(!(isDeinitialized() && mMemoryless));
+ return mMemoryless;
+ }
+
+ GLenum getInternalformat() const { return mInternalformat; }
+
+ // Implements glGetIntegeri_v() for GL_PIXEL_LOCAL_FORMAT_ANGLE,
+ // GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE, GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE, and
+ // GL_PIXEL_LOCAL_TEXTURE_LAYER_ANGLE
+ GLint getIntegeri(const Context *, GLenum target, GLuint index) const;
+
+ // If this plane is texture backed, stores the bound texture image's {width, height, 0} to
+ // Extents and returns true. Otherwise returns false, meaning the plane is either deinitialized
+ // or memoryless.
+ bool getTextureImageExtents(const Context *, Extents *extents) const;
+
+ // Attaches this plane to the specified color attachment point on the current draw framebuffer.
+ void attachToDrawFramebuffer(Context *, Extents plsExtents, GLenum colorAttachment);
+
+ // Clears the draw buffer at 0-based index 'drawbuffer' on the current framebuffer. Reads the
+ // clear value from 'data' if 'loadop' is GL_CLEAR_ANGLE, otherwise clears to zero.
+ //
+ // 'data' is interpereted as either 4 GLfloats, 4 GLints, or 4 GLuints, depending on
+ // mInternalFormat.
+ //
+ // The context must internally disable the scissor test before calling this method, since the
+ // intention is to clear the entire surface.
+ void performLoadOperationClear(Context *, GLint drawbuffer, GLenum loadop, const void *data);
+
+ // Binds this PLS plane to a texture image unit for image load/store shader operations.
+ void bindToImage(Context *, Extents plsExtents, GLuint unit, bool needsR32Packing);
+
+ private:
+ // Ensures we have an internal backing texture for memoryless planes. In GL, we need a backing
+ // texture even if the plane is memoryless; glInvalidateFramebuffer() will ideally prevent the
+ // driver from writing out data where possible.
+ void ensureBackingIfMemoryless(Context *, Extents plsSize);
+
+ GLenum mInternalformat = GL_NONE; // GL_NONE if this plane is in a deinitialized state.
+ bool mMemoryless = false;
+ TextureID mMemorylessTextureID{}; // We own memoryless backing textures and must delete them.
+ ImageIndex mTextureImageIndex;
+ Texture *mTextureRef = nullptr;
+};
+
+// Manages a collection of PixelLocalStoragePlanes and applies them to ANGLE's GL state.
+//
+// The main magic of ANGLE_shader_pixel_local_storage happens inside shaders, so we just emulate the
+// client API on top of ANGLE's OpenGL ES API for simplicity.
+class PixelLocalStorage
+{
+ public:
+ static std::unique_ptr<PixelLocalStorage> Make(const Context *);
+
+ PixelLocalStorage();
+ virtual ~PixelLocalStorage();
+
+ // Called when the owning framebuffer is being destroyed.
+ void onFramebufferDestroyed(const Context *);
+
+ // Deletes any GL objects that have been allocated for pixel local storage. These can't be
+ // cleaned up in the destructor because they require a non-const Context object.
+ void deleteContextObjects(Context *);
+
+ const PixelLocalStoragePlane &getPlane(GLint plane) const
+ {
+ ASSERT(0 <= plane && plane < IMPLEMENTATION_MAX_PIXEL_LOCAL_STORAGE_PLANES);
+ return mPlanes[plane];
+ }
+
+ PixelLocalStoragePlane &getPlane(GLint plane)
+ {
+ ASSERT(0 <= plane && plane < IMPLEMENTATION_MAX_PIXEL_LOCAL_STORAGE_PLANES);
+ return mPlanes[plane];
+ }
+
+ // ANGLE_shader_pixel_local_storage API.
+ void deinitialize(Context *context, GLint plane) { mPlanes[plane].deinitialize(context); }
+ void setMemoryless(Context *context, GLint plane, GLenum internalformat)
+ {
+ mPlanes[plane].setMemoryless(context, internalformat);
+ }
+ void setTextureBacked(Context *context, GLint plane, Texture *tex, int level, int layer)
+ {
+ mPlanes[plane].setTextureBacked(context, tex, level, layer);
+ }
+ void begin(Context *, GLsizei n, const GLenum loadops[], const void *cleardata);
+ void end(Context *);
+ void barrier(Context *);
+
+ protected:
+ // Called when the context is lost or destroyed. Causes the subclass to clear its GL object
+ // handles.
+ virtual void onContextObjectsLost() = 0;
+
+ // Called when the framebuffer is being destroyed. Causes the subclass to delete its frontend GL
+ // object handles.
+ virtual void onDeleteContextObjects(Context *) = 0;
+
+ // ANGLE_shader_pixel_local_storage API.
+ virtual void onBegin(Context *,
+ GLsizei n,
+ const GLenum loadops[],
+ const char *cleardata,
+ Extents plsSize) = 0;
+ virtual void onEnd(Context *, GLsizei numActivePLSPlanes) = 0;
+ virtual void onBarrier(Context *) = 0;
+
+ private:
+ std::array<PixelLocalStoragePlane, IMPLEMENTATION_MAX_PIXEL_LOCAL_STORAGE_PLANES> mPlanes;
+
+ // "n" from the last call to begin(), or 0 if pixel local storage is not active.
+ GLsizei mNumActivePLSPlanes = 0;
+};
+
+} // namespace gl
+
+#endif // LIBANGLE_PIXEL_LOCAL_STORAGE_H_
diff --git a/gfx/angle/checkout/src/libANGLE/Platform.cpp b/gfx/angle/checkout/src/libANGLE/Platform.cpp
new file mode 100644
index 0000000000..d798fd4e86
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Platform.cpp
@@ -0,0 +1,76 @@
+//
+// 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.
+//
+
+// Platform.cpp: Implementation methods for angle::Platform.
+
+#include <platform/PlatformMethods.h>
+
+#include <cstring>
+
+#include "common/debug.h"
+
+namespace
+{
+// TODO(jmadill): Make methods owned by egl::Display.
+angle::PlatformMethods &PlatformMethods()
+{
+ static angle::PlatformMethods platformMethods;
+ return platformMethods;
+}
+} // anonymous namespace
+
+angle::PlatformMethods *ANGLEPlatformCurrent()
+{
+ return &PlatformMethods();
+}
+
+bool ANGLE_APIENTRY ANGLEGetDisplayPlatform(angle::EGLDisplayType display,
+ const char *const methodNames[],
+ unsigned int methodNameCount,
+ void *context,
+ void *platformMethods)
+{
+ angle::PlatformMethods **platformMethodsOut =
+ reinterpret_cast<angle::PlatformMethods **>(platformMethods);
+
+ // We allow for a lower input count of impl platform methods if the subset is correct.
+ if (methodNameCount > angle::g_NumPlatformMethods)
+ {
+ ERR() << "Invalid platform method count: " << methodNameCount << ", expected "
+ << angle::g_NumPlatformMethods << ".";
+ return false;
+ }
+
+ for (unsigned int nameIndex = 0; nameIndex < methodNameCount; ++nameIndex)
+ {
+ const char *expectedName = angle::g_PlatformMethodNames[nameIndex];
+ const char *actualName = methodNames[nameIndex];
+
+ // Skip deprecated methods. The names of these methods start with |placeholder|.
+ constexpr char kPlaceholder[] = "placeholder";
+ if (strncmp(expectedName, kPlaceholder, sizeof(kPlaceholder) - 1) == 0)
+ {
+ continue;
+ }
+ if (strcmp(expectedName, actualName) != 0)
+ {
+ ERR() << "Invalid platform method name: " << actualName << ", expected " << expectedName
+ << ".";
+ return false;
+ }
+ }
+
+ // TODO(jmadill): Store platform methods in display.
+ PlatformMethods().context = context;
+ *platformMethodsOut = &PlatformMethods();
+ return true;
+}
+
+void ANGLE_APIENTRY ANGLEResetDisplayPlatform(angle::EGLDisplayType display)
+{
+ // TODO(jmadill): Store platform methods in display.
+ PlatformMethods() = angle::PlatformMethods();
+}
diff --git a/gfx/angle/checkout/src/libANGLE/Program.cpp b/gfx/angle/checkout/src/libANGLE/Program.cpp
new file mode 100644
index 0000000000..3191a43ff3
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Program.cpp
@@ -0,0 +1,3810 @@
+//
+// Copyright 2002 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.
+//
+
+// Program.cpp: Implements the gl::Program class. Implements GL program objects
+// and related functionality. [OpenGL ES 2.0.24] section 2.10.3 page 28.
+
+#include "libANGLE/Program.h"
+
+#include <algorithm>
+#include <utility>
+
+#include "common/angle_version_info.h"
+#include "common/bitset_utils.h"
+#include "common/debug.h"
+#include "common/platform.h"
+#include "common/string_utils.h"
+#include "common/utilities.h"
+#include "compiler/translator/blocklayout.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/ErrorStrings.h"
+#include "libANGLE/MemoryProgramCache.h"
+#include "libANGLE/ProgramLinkedResources.h"
+#include "libANGLE/ResourceManager.h"
+#include "libANGLE/Uniform.h"
+#include "libANGLE/VaryingPacking.h"
+#include "libANGLE/Version.h"
+#include "libANGLE/capture/FrameCapture.h"
+#include "libANGLE/features.h"
+#include "libANGLE/histogram_macros.h"
+#include "libANGLE/queryconversions.h"
+#include "libANGLE/renderer/GLImplFactory.h"
+#include "libANGLE/renderer/ProgramImpl.h"
+#include "platform/FrontendFeatures_autogen.h"
+#include "platform/PlatformMethods.h"
+
+namespace gl
+{
+
+namespace
+{
+
+// This simplified cast function doesn't need to worry about advanced concepts like
+// depth range values, or casting to bool.
+template <typename DestT, typename SrcT>
+DestT UniformStateQueryCast(SrcT value);
+
+// From-Float-To-Integer Casts
+template <>
+GLint UniformStateQueryCast(GLfloat value)
+{
+ return clampCast<GLint>(roundf(value));
+}
+
+template <>
+GLuint UniformStateQueryCast(GLfloat value)
+{
+ return clampCast<GLuint>(roundf(value));
+}
+
+// From-Integer-to-Integer Casts
+template <>
+GLint UniformStateQueryCast(GLuint value)
+{
+ return clampCast<GLint>(value);
+}
+
+template <>
+GLuint UniformStateQueryCast(GLint value)
+{
+ return clampCast<GLuint>(value);
+}
+
+// From-Boolean-to-Anything Casts
+template <>
+GLfloat UniformStateQueryCast(GLboolean value)
+{
+ return (ConvertToBool(value) ? 1.0f : 0.0f);
+}
+
+template <>
+GLint UniformStateQueryCast(GLboolean value)
+{
+ return (ConvertToBool(value) ? 1 : 0);
+}
+
+template <>
+GLuint UniformStateQueryCast(GLboolean value)
+{
+ return (ConvertToBool(value) ? 1u : 0u);
+}
+
+// Default to static_cast
+template <typename DestT, typename SrcT>
+DestT UniformStateQueryCast(SrcT value)
+{
+ return static_cast<DestT>(value);
+}
+
+template <typename SrcT, typename DestT>
+void UniformStateQueryCastLoop(DestT *dataOut, const uint8_t *srcPointer, int components)
+{
+ for (int comp = 0; comp < components; ++comp)
+ {
+ // We only work with strides of 4 bytes for uniform components. (GLfloat/GLint)
+ // Don't use SrcT stride directly since GLboolean has a stride of 1 byte.
+ size_t offset = comp * 4;
+ const SrcT *typedSrcPointer = reinterpret_cast<const SrcT *>(&srcPointer[offset]);
+ dataOut[comp] = UniformStateQueryCast<DestT>(*typedSrcPointer);
+ }
+}
+
+template <typename VarT>
+GLuint GetResourceIndexFromName(const std::vector<VarT> &list, const std::string &name)
+{
+ std::string nameAsArrayName = name + "[0]";
+ for (size_t index = 0; index < list.size(); index++)
+ {
+ const VarT &resource = list[index];
+ if (resource.name == name || (resource.isArray() && resource.name == nameAsArrayName))
+ {
+ return static_cast<GLuint>(index);
+ }
+ }
+
+ return GL_INVALID_INDEX;
+}
+
+GLint GetVariableLocation(const std::vector<sh::ShaderVariable> &list,
+ const std::vector<VariableLocation> &locationList,
+ const std::string &name)
+{
+ size_t nameLengthWithoutArrayIndex;
+ unsigned int arrayIndex = ParseArrayIndex(name, &nameLengthWithoutArrayIndex);
+
+ for (size_t location = 0u; location < locationList.size(); ++location)
+ {
+ const VariableLocation &variableLocation = locationList[location];
+ if (!variableLocation.used())
+ {
+ continue;
+ }
+
+ const sh::ShaderVariable &variable = list[variableLocation.index];
+
+ // Array output variables may be bound out of order, so we need to ensure we only pick the
+ // first element if given the base name.
+ if ((variable.name == name) && (variableLocation.arrayIndex == 0))
+ {
+ return static_cast<GLint>(location);
+ }
+ if (variable.isArray() && variableLocation.arrayIndex == arrayIndex &&
+ angle::BeginsWith(variable.name, name, nameLengthWithoutArrayIndex))
+ {
+ return static_cast<GLint>(location);
+ }
+ }
+
+ return -1;
+}
+
+GLint GetVariableLocation(const std::vector<LinkedUniform> &list,
+ const std::vector<VariableLocation> &locationList,
+ const std::string &name)
+{
+ size_t nameLengthWithoutArrayIndex;
+ unsigned int arrayIndex = ParseArrayIndex(name, &nameLengthWithoutArrayIndex);
+
+ for (size_t location = 0u; location < locationList.size(); ++location)
+ {
+ const VariableLocation &variableLocation = locationList[location];
+ if (!variableLocation.used())
+ {
+ continue;
+ }
+
+ const LinkedUniform &variable = list[variableLocation.index];
+
+ // Array output variables may be bound out of order, so we need to ensure we only pick the
+ // first element if given the base name. Uniforms don't allow this behavior and some code
+ // seemingly depends on the opposite behavior, so only enable it for output variables.
+ if (angle::BeginsWith(variable.name, name) && (variableLocation.arrayIndex == 0))
+ {
+ if (name.length() == variable.name.length())
+ {
+ ASSERT(name == variable.name);
+ // GLES 3.1 November 2016 page 87.
+ // The string exactly matches the name of the active variable.
+ return static_cast<GLint>(location);
+ }
+ if (name.length() + 3u == variable.name.length() && variable.isArray())
+ {
+ ASSERT(name + "[0]" == variable.name);
+ // 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.
+ return static_cast<GLint>(location);
+ }
+ }
+ if (variable.isArray() && variableLocation.arrayIndex == arrayIndex &&
+ nameLengthWithoutArrayIndex + 3u == variable.name.length() &&
+ angle::BeginsWith(variable.name, name, nameLengthWithoutArrayIndex))
+ {
+ ASSERT(name.substr(0u, nameLengthWithoutArrayIndex) + "[0]" == variable.name);
+ // The string identifies an active element of the array, where the string ends with the
+ // concatenation of the "[" character, an integer (with no "+" sign, extra leading
+ // zeroes, or whitespace) identifying an array element, and the "]" character, the
+ // integer is less than the number of active elements of the array variable, and where
+ // the string would exactly match the enumerated name of the array if the decimal
+ // integer were replaced with zero.
+ return static_cast<GLint>(location);
+ }
+ }
+
+ return -1;
+}
+
+void CopyStringToBuffer(GLchar *buffer,
+ const std::string &string,
+ GLsizei bufSize,
+ GLsizei *lengthOut)
+{
+ ASSERT(bufSize > 0);
+ size_t length = std::min<size_t>(bufSize - 1, string.length());
+ memcpy(buffer, string.c_str(), length);
+ buffer[length] = '\0';
+
+ if (lengthOut)
+ {
+ *lengthOut = static_cast<GLsizei>(length);
+ }
+}
+
+GLuint GetInterfaceBlockIndex(const std::vector<InterfaceBlock> &list, const std::string &name)
+{
+ std::vector<unsigned int> subscripts;
+ std::string baseName = ParseResourceName(name, &subscripts);
+
+ unsigned int numBlocks = static_cast<unsigned int>(list.size());
+ for (unsigned int blockIndex = 0; blockIndex < numBlocks; blockIndex++)
+ {
+ const auto &block = list[blockIndex];
+ if (block.name == baseName)
+ {
+ const bool arrayElementZero =
+ (subscripts.empty() && (!block.isArray || block.arrayElement == 0));
+ const bool arrayElementMatches =
+ (subscripts.size() == 1 && subscripts[0] == block.arrayElement);
+ if (arrayElementMatches || arrayElementZero)
+ {
+ return blockIndex;
+ }
+ }
+ }
+
+ return GL_INVALID_INDEX;
+}
+
+void GetInterfaceBlockName(const UniformBlockIndex index,
+ const std::vector<InterfaceBlock> &list,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *name)
+{
+ ASSERT(index.value < list.size());
+
+ const auto &block = list[index.value];
+
+ if (bufSize > 0)
+ {
+ std::string blockName = block.name;
+
+ if (block.isArray)
+ {
+ blockName += ArrayString(block.arrayElement);
+ }
+ CopyStringToBuffer(name, blockName, bufSize, length);
+ }
+}
+
+void InitUniformBlockLinker(const Context *context,
+ const ProgramState &state,
+ UniformBlockLinker *blockLinker)
+{
+ for (ShaderType shaderType : AllShaderTypes())
+ {
+ Shader *shader = state.getAttachedShader(shaderType);
+ if (shader)
+ {
+ blockLinker->addShaderBlocks(shaderType, &shader->getUniformBlocks(context));
+ }
+ }
+}
+
+void InitShaderStorageBlockLinker(const Context *context,
+ const ProgramState &state,
+ ShaderStorageBlockLinker *blockLinker)
+{
+ for (ShaderType shaderType : AllShaderTypes())
+ {
+ Shader *shader = state.getAttachedShader(shaderType);
+ if (shader != nullptr)
+ {
+ blockLinker->addShaderBlocks(shaderType, &shader->getShaderStorageBlocks(context));
+ }
+ }
+}
+} // anonymous namespace
+
+const char *GetLinkMismatchErrorString(LinkMismatchError linkError)
+{
+ switch (linkError)
+ {
+ case LinkMismatchError::TYPE_MISMATCH:
+ return "Type";
+ case LinkMismatchError::ARRAYNESS_MISMATCH:
+ return "Array-ness";
+ case LinkMismatchError::ARRAY_SIZE_MISMATCH:
+ return "Array size";
+ case LinkMismatchError::PRECISION_MISMATCH:
+ return "Precision";
+ case LinkMismatchError::STRUCT_NAME_MISMATCH:
+ return "Structure name";
+ case LinkMismatchError::FIELD_NUMBER_MISMATCH:
+ return "Field number";
+ case LinkMismatchError::FIELD_NAME_MISMATCH:
+ return "Field name";
+
+ case LinkMismatchError::INTERPOLATION_TYPE_MISMATCH:
+ return "Interpolation type";
+ case LinkMismatchError::INVARIANCE_MISMATCH:
+ return "Invariance";
+
+ case LinkMismatchError::BINDING_MISMATCH:
+ return "Binding layout qualifier";
+ case LinkMismatchError::LOCATION_MISMATCH:
+ return "Location layout qualifier";
+ case LinkMismatchError::OFFSET_MISMATCH:
+ return "Offset layout qualifier";
+ case LinkMismatchError::INSTANCE_NAME_MISMATCH:
+ return "Instance name qualifier";
+ case LinkMismatchError::FORMAT_MISMATCH:
+ return "Format qualifier";
+
+ case LinkMismatchError::LAYOUT_QUALIFIER_MISMATCH:
+ return "Layout qualifier";
+ case LinkMismatchError::MATRIX_PACKING_MISMATCH:
+ return "Matrix Packing";
+
+ case LinkMismatchError::FIELD_LOCATION_MISMATCH:
+ return "Field location";
+ case LinkMismatchError::FIELD_STRUCT_NAME_MISMATCH:
+ return "Field structure name";
+ default:
+ UNREACHABLE();
+ return "";
+ }
+}
+
+void UpdateInterfaceVariable(std::vector<sh::ShaderVariable> *block, const sh::ShaderVariable &var)
+{
+ if (!var.isStruct())
+ {
+ block->emplace_back(var);
+ block->back().resetEffectiveLocation();
+ }
+
+ for (const sh::ShaderVariable &field : var.fields)
+ {
+ ASSERT(!var.name.empty() || var.isShaderIOBlock);
+
+ // Shader I/O block naming is similar to UBOs and SSBOs:
+ //
+ // in Block
+ // {
+ // type field; // produces "field"
+ // };
+ //
+ // in Block2
+ // {
+ // type field; // produces "Block2.field"
+ // } block2;
+ //
+ const std::string &baseName = var.isShaderIOBlock ? var.structOrBlockName : var.name;
+ const std::string prefix = var.name.empty() ? "" : baseName + ".";
+
+ if (!field.isStruct())
+ {
+ sh::ShaderVariable fieldCopy = field;
+ fieldCopy.updateEffectiveLocation(var);
+ fieldCopy.name = prefix + field.name;
+ block->emplace_back(fieldCopy);
+ }
+
+ for (const sh::ShaderVariable &nested : field.fields)
+ {
+ sh::ShaderVariable nestedCopy = nested;
+ nestedCopy.updateEffectiveLocation(field);
+ nestedCopy.name = prefix + field.name + "." + nested.name;
+ block->emplace_back(nestedCopy);
+ }
+ }
+}
+
+void WriteShaderVariableBuffer(BinaryOutputStream *stream, const ShaderVariableBuffer &var)
+{
+ stream->writeInt(var.binding);
+ stream->writeInt(var.dataSize);
+
+ for (ShaderType shaderType : AllShaderTypes())
+ {
+ stream->writeBool(var.isActive(shaderType));
+ }
+
+ stream->writeInt(var.memberIndexes.size());
+ for (unsigned int memberCounterIndex : var.memberIndexes)
+ {
+ stream->writeInt(memberCounterIndex);
+ }
+}
+
+void LoadShaderVariableBuffer(BinaryInputStream *stream, ShaderVariableBuffer *var)
+{
+ var->binding = stream->readInt<int>();
+ var->dataSize = stream->readInt<unsigned int>();
+
+ for (ShaderType shaderType : AllShaderTypes())
+ {
+ var->setActive(shaderType, stream->readBool());
+ }
+
+ size_t numMembers = stream->readInt<size_t>();
+ for (size_t blockMemberIndex = 0; blockMemberIndex < numMembers; blockMemberIndex++)
+ {
+ var->memberIndexes.push_back(stream->readInt<unsigned int>());
+ }
+}
+
+void WriteBufferVariable(BinaryOutputStream *stream, const BufferVariable &var)
+{
+ WriteShaderVar(stream, var);
+
+ stream->writeInt(var.bufferIndex);
+ WriteBlockMemberInfo(stream, var.blockInfo);
+ stream->writeInt(var.topLevelArraySize);
+
+ for (ShaderType shaderType : AllShaderTypes())
+ {
+ stream->writeBool(var.isActive(shaderType));
+ }
+}
+
+void LoadBufferVariable(BinaryInputStream *stream, BufferVariable *var)
+{
+ LoadShaderVar(stream, var);
+
+ var->bufferIndex = stream->readInt<int>();
+ LoadBlockMemberInfo(stream, &var->blockInfo);
+ var->topLevelArraySize = stream->readInt<int>();
+
+ for (ShaderType shaderType : AllShaderTypes())
+ {
+ var->setActive(shaderType, stream->readBool());
+ }
+}
+
+void WriteInterfaceBlock(BinaryOutputStream *stream, const InterfaceBlock &block)
+{
+ stream->writeString(block.name);
+ stream->writeString(block.mappedName);
+ stream->writeBool(block.isArray);
+ stream->writeInt(block.arrayElement);
+
+ WriteShaderVariableBuffer(stream, block);
+}
+
+void LoadInterfaceBlock(BinaryInputStream *stream, InterfaceBlock *block)
+{
+ block->name = stream->readString();
+ block->mappedName = stream->readString();
+ block->isArray = stream->readBool();
+ block->arrayElement = stream->readInt<unsigned int>();
+
+ LoadShaderVariableBuffer(stream, block);
+}
+
+void WriteShInterfaceBlock(BinaryOutputStream *stream, const sh::InterfaceBlock &block)
+{
+ stream->writeString(block.name);
+ stream->writeString(block.mappedName);
+ stream->writeString(block.instanceName);
+ stream->writeInt(block.arraySize);
+ stream->writeEnum(block.layout);
+ stream->writeBool(block.isRowMajorLayout);
+ stream->writeInt(block.binding);
+ stream->writeBool(block.staticUse);
+ stream->writeBool(block.active);
+ stream->writeEnum(block.blockType);
+
+ stream->writeInt<size_t>(block.fields.size());
+ for (const sh::ShaderVariable &shaderVariable : block.fields)
+ {
+ WriteShaderVar(stream, shaderVariable);
+ }
+}
+
+void LoadShInterfaceBlock(BinaryInputStream *stream, sh::InterfaceBlock *block)
+{
+ block->name = stream->readString();
+ block->mappedName = stream->readString();
+ block->instanceName = stream->readString();
+ block->arraySize = stream->readInt<unsigned int>();
+ block->layout = stream->readEnum<sh::BlockLayoutType>();
+ block->isRowMajorLayout = stream->readBool();
+ block->binding = stream->readInt<int>();
+ block->staticUse = stream->readBool();
+ block->active = stream->readBool();
+ block->blockType = stream->readEnum<sh::BlockType>();
+
+ block->fields.resize(stream->readInt<size_t>());
+ for (sh::ShaderVariable &variable : block->fields)
+ {
+ LoadShaderVar(stream, &variable);
+ }
+}
+
+// Saves the linking context for later use in resolveLink().
+struct Program::LinkingState
+{
+ std::shared_ptr<ProgramExecutable> linkedExecutable;
+ ProgramLinkedResources resources;
+ egl::BlobCache::Key programHash;
+ std::unique_ptr<rx::LinkEvent> linkEvent;
+ bool linkingFromBinary;
+};
+
+const char *const g_fakepath = "C:\\fakepath";
+
+// InfoLog implementation.
+InfoLog::InfoLog() : mLazyStream(nullptr) {}
+
+InfoLog::~InfoLog() {}
+
+size_t InfoLog::getLength() const
+{
+ if (!mLazyStream)
+ {
+ return 0;
+ }
+
+ const std::string &logString = mLazyStream->str();
+ return logString.empty() ? 0 : logString.length() + 1;
+}
+
+void InfoLog::getLog(GLsizei bufSize, GLsizei *length, char *infoLog) const
+{
+ size_t index = 0;
+
+ if (bufSize > 0)
+ {
+ const std::string logString(str());
+
+ if (!logString.empty())
+ {
+ index = std::min(static_cast<size_t>(bufSize) - 1, logString.length());
+ memcpy(infoLog, logString.c_str(), index);
+ }
+
+ infoLog[index] = '\0';
+ }
+
+ if (length)
+ {
+ *length = static_cast<GLsizei>(index);
+ }
+}
+
+// append a sanitized message to the program info log.
+// 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)
+{
+ ensureInitialized();
+
+ std::string msg(message);
+
+ size_t found;
+ do
+ {
+ found = msg.find(g_fakepath);
+ if (found != std::string::npos)
+ {
+ msg.erase(found, strlen(g_fakepath));
+ }
+ } while (found != std::string::npos);
+
+ if (!msg.empty())
+ {
+ *mLazyStream << message << std::endl;
+ }
+}
+
+void InfoLog::reset()
+{
+ if (mLazyStream)
+ {
+ mLazyStream.reset(nullptr);
+ }
+}
+
+bool InfoLog::empty() const
+{
+ if (!mLazyStream)
+ {
+ return true;
+ }
+
+ return mLazyStream->rdbuf()->in_avail() == 0;
+}
+
+void LogLinkMismatch(InfoLog &infoLog,
+ const std::string &variableName,
+ const char *variableType,
+ LinkMismatchError linkError,
+ const std::string &mismatchedStructOrBlockFieldName,
+ ShaderType shaderType1,
+ ShaderType shaderType2)
+{
+ std::ostringstream stream;
+ stream << GetLinkMismatchErrorString(linkError) << "s of " << variableType << " '"
+ << variableName;
+
+ if (!mismatchedStructOrBlockFieldName.empty())
+ {
+ stream << "' member '" << variableName << "." << mismatchedStructOrBlockFieldName;
+ }
+
+ stream << "' differ between " << GetShaderTypeString(shaderType1) << " and "
+ << GetShaderTypeString(shaderType2) << " shaders.";
+
+ infoLog << stream.str();
+}
+
+bool IsActiveInterfaceBlock(const sh::InterfaceBlock &interfaceBlock)
+{
+ // Only 'packed' blocks are allowed to be considered inactive.
+ return interfaceBlock.active || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED;
+}
+
+void WriteBlockMemberInfo(BinaryOutputStream *stream, const sh::BlockMemberInfo &var)
+{
+ stream->writeInt(var.arrayStride);
+ stream->writeBool(var.isRowMajorMatrix);
+ stream->writeInt(var.matrixStride);
+ stream->writeInt(var.offset);
+ stream->writeInt(var.topLevelArrayStride);
+}
+
+void LoadBlockMemberInfo(BinaryInputStream *stream, sh::BlockMemberInfo *var)
+{
+ var->arrayStride = stream->readInt<int>();
+ var->isRowMajorMatrix = stream->readBool();
+ var->matrixStride = stream->readInt<int>();
+ var->offset = stream->readInt<int>();
+ var->topLevelArrayStride = stream->readInt<int>();
+}
+
+void WriteShaderVar(BinaryOutputStream *stream, const sh::ShaderVariable &var)
+{
+ stream->writeInt(var.type);
+ stream->writeInt(var.precision);
+ stream->writeString(var.name);
+ stream->writeString(var.mappedName);
+ stream->writeIntVector(var.arraySizes);
+ stream->writeBool(var.staticUse);
+ stream->writeBool(var.active);
+ stream->writeInt<size_t>(var.fields.size());
+ for (const sh::ShaderVariable &shaderVariable : var.fields)
+ {
+ WriteShaderVar(stream, shaderVariable);
+ }
+ stream->writeString(var.structOrBlockName);
+ stream->writeString(var.mappedStructOrBlockName);
+ stream->writeBool(var.isRowMajorLayout);
+ stream->writeInt(var.location);
+ stream->writeBool(var.hasImplicitLocation);
+ stream->writeInt(var.binding);
+ stream->writeInt(var.imageUnitFormat);
+ stream->writeInt(var.offset);
+ stream->writeBool(var.rasterOrdered);
+ stream->writeBool(var.readonly);
+ stream->writeBool(var.writeonly);
+ stream->writeBool(var.isFragmentInOut);
+ stream->writeInt(var.index);
+ stream->writeBool(var.yuv);
+ stream->writeEnum(var.interpolation);
+ stream->writeBool(var.isInvariant);
+ stream->writeBool(var.isShaderIOBlock);
+ stream->writeBool(var.isPatch);
+ stream->writeBool(var.texelFetchStaticUse);
+ stream->writeInt(var.getFlattenedOffsetInParentArrays());
+}
+
+void LoadShaderVar(gl::BinaryInputStream *stream, sh::ShaderVariable *var)
+{
+ var->type = stream->readInt<GLenum>();
+ var->precision = stream->readInt<GLenum>();
+ stream->readString(&var->name);
+ stream->readString(&var->mappedName);
+ stream->readIntVector<unsigned int>(&var->arraySizes);
+ var->staticUse = stream->readBool();
+ var->active = stream->readBool();
+ size_t elementCount = stream->readInt<size_t>();
+ var->fields.resize(elementCount);
+ for (sh::ShaderVariable &variable : var->fields)
+ {
+ LoadShaderVar(stream, &variable);
+ }
+ stream->readString(&var->structOrBlockName);
+ stream->readString(&var->mappedStructOrBlockName);
+ var->isRowMajorLayout = stream->readBool();
+ var->location = stream->readInt<int>();
+ var->hasImplicitLocation = stream->readBool();
+ var->binding = stream->readInt<int>();
+ var->imageUnitFormat = stream->readInt<GLenum>();
+ var->offset = stream->readInt<int>();
+ var->rasterOrdered = stream->readBool();
+ var->readonly = stream->readBool();
+ var->writeonly = stream->readBool();
+ var->isFragmentInOut = stream->readBool();
+ var->index = stream->readInt<int>();
+ var->yuv = stream->readBool();
+ var->interpolation = stream->readEnum<sh::InterpolationType>();
+ var->isInvariant = stream->readBool();
+ var->isShaderIOBlock = stream->readBool();
+ var->isPatch = stream->readBool();
+ var->texelFetchStaticUse = stream->readBool();
+ var->setParentArrayIndex(stream->readInt<int>());
+}
+
+// VariableLocation implementation.
+VariableLocation::VariableLocation() : arrayIndex(0), index(kUnused), ignored(false) {}
+
+VariableLocation::VariableLocation(unsigned int arrayIndex, unsigned int index)
+ : arrayIndex(arrayIndex), index(index), ignored(false)
+{
+ ASSERT(arrayIndex != GL_INVALID_INDEX);
+}
+
+// SamplerBindings implementation.
+SamplerBinding::SamplerBinding(TextureType textureTypeIn,
+ GLenum samplerTypeIn,
+ SamplerFormat formatIn,
+ size_t elementCount)
+ : textureType(textureTypeIn),
+ samplerType(samplerTypeIn),
+ format(formatIn),
+ boundTextureUnits(elementCount, 0)
+{}
+
+SamplerBinding::SamplerBinding(const SamplerBinding &other) = default;
+
+SamplerBinding::~SamplerBinding() = default;
+
+// ProgramBindings implementation.
+ProgramBindings::ProgramBindings() {}
+
+ProgramBindings::~ProgramBindings() {}
+
+void ProgramBindings::bindLocation(GLuint index, const std::string &name)
+{
+ mBindings[name] = index;
+}
+
+int ProgramBindings::getBindingByName(const std::string &name) const
+{
+ auto iter = mBindings.find(name);
+ return (iter != mBindings.end()) ? iter->second : -1;
+}
+
+int ProgramBindings::getBinding(const sh::ShaderVariable &variable) const
+{
+ return getBindingByName(variable.name);
+}
+
+ProgramBindings::const_iterator ProgramBindings::begin() const
+{
+ return mBindings.begin();
+}
+
+ProgramBindings::const_iterator ProgramBindings::end() const
+{
+ return mBindings.end();
+}
+
+std::map<std::string, GLuint> ProgramBindings::getStableIterationMap() const
+{
+ return std::map<std::string, GLuint>(mBindings.begin(), mBindings.end());
+}
+
+// ProgramAliasedBindings implementation.
+ProgramAliasedBindings::ProgramAliasedBindings() {}
+
+ProgramAliasedBindings::~ProgramAliasedBindings() {}
+
+void ProgramAliasedBindings::bindLocation(GLuint index, const std::string &name)
+{
+ mBindings[name] = ProgramBinding(index);
+
+ // EXT_blend_func_extended spec: "If it specifies the base name of an array,
+ // it identifies the resources associated with the first element of the array."
+ //
+ // Normalize array bindings so that "name" and "name[0]" map to the same entry.
+ // If this binding is of the form "name[0]", then mark the "name" binding as
+ // aliased but do not update it yet in case "name" is not actually an array.
+ size_t nameLengthWithoutArrayIndex;
+ unsigned int arrayIndex = ParseArrayIndex(name, &nameLengthWithoutArrayIndex);
+ if (arrayIndex == 0)
+ {
+ std::string baseName = name.substr(0u, nameLengthWithoutArrayIndex);
+ auto iter = mBindings.find(baseName);
+ if (iter != mBindings.end())
+ {
+ iter->second.aliased = true;
+ }
+ }
+}
+
+int ProgramAliasedBindings::getBindingByName(const std::string &name) const
+{
+ auto iter = mBindings.find(name);
+ return (iter != mBindings.end()) ? iter->second.location : -1;
+}
+
+int ProgramAliasedBindings::getBindingByLocation(GLuint location) const
+{
+ for (const auto &iter : mBindings)
+ {
+ if (iter.second.location == location)
+ {
+ return iter.second.location;
+ }
+ }
+ return -1;
+}
+
+int ProgramAliasedBindings::getBinding(const sh::ShaderVariable &variable) const
+{
+ const std::string &name = variable.name;
+
+ // Check with the normalized array name if applicable.
+ if (variable.isArray())
+ {
+ size_t nameLengthWithoutArrayIndex;
+ unsigned int arrayIndex = ParseArrayIndex(name, &nameLengthWithoutArrayIndex);
+ if (arrayIndex == 0)
+ {
+ std::string baseName = name.substr(0u, nameLengthWithoutArrayIndex);
+ auto iter = mBindings.find(baseName);
+ // If "name" exists and is not aliased, that means it was modified more
+ // recently than its "name[0]" form and should be used instead of that.
+ if (iter != mBindings.end() && !iter->second.aliased)
+ {
+ return iter->second.location;
+ }
+ }
+ else if (arrayIndex == GL_INVALID_INDEX)
+ {
+ auto iter = mBindings.find(variable.name);
+ // If "name" exists and is not aliased, that means it was modified more
+ // recently than its "name[0]" form and should be used instead of that.
+ if (iter != mBindings.end() && !iter->second.aliased)
+ {
+ return iter->second.location;
+ }
+ // The base name was aliased, so use the name with the array notation.
+ return getBindingByName(name + "[0]");
+ }
+ }
+
+ return getBindingByName(name);
+}
+
+ProgramAliasedBindings::const_iterator ProgramAliasedBindings::begin() const
+{
+ return mBindings.begin();
+}
+
+ProgramAliasedBindings::const_iterator ProgramAliasedBindings::end() const
+{
+ return mBindings.end();
+}
+
+std::map<std::string, ProgramBinding> ProgramAliasedBindings::getStableIterationMap() const
+{
+ return std::map<std::string, ProgramBinding>(mBindings.begin(), mBindings.end());
+}
+
+// ImageBinding implementation.
+ImageBinding::ImageBinding(size_t count, TextureType textureTypeIn)
+ : textureType(textureTypeIn), boundImageUnits(count, 0)
+{}
+ImageBinding::ImageBinding(GLuint imageUnit, size_t count, TextureType textureTypeIn)
+ : textureType(textureTypeIn)
+{
+ for (size_t index = 0; index < count; ++index)
+ {
+ boundImageUnits.push_back(imageUnit + static_cast<GLuint>(index));
+ }
+}
+
+ImageBinding::ImageBinding(const ImageBinding &other) = default;
+
+ImageBinding::~ImageBinding() = default;
+
+// ProgramState implementation.
+ProgramState::ProgramState()
+ : mLabel(),
+ mAttachedShaders{},
+ mLocationsUsedForXfbExtension(0),
+ mBinaryRetrieveableHint(false),
+ mSeparable(false),
+ mNumViews(-1),
+ mDrawIDLocation(-1),
+ mBaseVertexLocation(-1),
+ mBaseInstanceLocation(-1),
+ mCachedBaseVertex(0),
+ mCachedBaseInstance(0),
+ mExecutable(new ProgramExecutable())
+{
+ mComputeShaderLocalSize.fill(1);
+}
+
+ProgramState::~ProgramState()
+{
+ ASSERT(!hasAttachedShader());
+}
+
+const std::string &ProgramState::getLabel()
+{
+ return mLabel;
+}
+
+Shader *ProgramState::getAttachedShader(ShaderType shaderType) const
+{
+ ASSERT(shaderType != ShaderType::InvalidEnum);
+ return mAttachedShaders[shaderType];
+}
+
+GLuint ProgramState::getUniformIndexFromName(const std::string &name) const
+{
+ return GetResourceIndexFromName(mExecutable->mUniforms, name);
+}
+
+GLuint ProgramState::getBufferVariableIndexFromName(const std::string &name) const
+{
+ return GetResourceIndexFromName(mBufferVariables, name);
+}
+
+GLuint ProgramState::getUniformIndexFromLocation(UniformLocation location) const
+{
+ ASSERT(location.value >= 0 && static_cast<size_t>(location.value) < mUniformLocations.size());
+ return mUniformLocations[location.value].index;
+}
+
+Optional<GLuint> ProgramState::getSamplerIndex(UniformLocation location) const
+{
+ GLuint index = getUniformIndexFromLocation(location);
+ if (!isSamplerUniformIndex(index))
+ {
+ return Optional<GLuint>::Invalid();
+ }
+
+ return getSamplerIndexFromUniformIndex(index);
+}
+
+bool ProgramState::isSamplerUniformIndex(GLuint index) const
+{
+ return mExecutable->mSamplerUniformRange.contains(index);
+}
+
+GLuint ProgramState::getSamplerIndexFromUniformIndex(GLuint uniformIndex) const
+{
+ ASSERT(isSamplerUniformIndex(uniformIndex));
+ return uniformIndex - mExecutable->mSamplerUniformRange.low();
+}
+
+GLuint ProgramState::getUniformIndexFromSamplerIndex(GLuint samplerIndex) const
+{
+ return mExecutable->getUniformIndexFromSamplerIndex(samplerIndex);
+}
+
+bool ProgramState::isImageUniformIndex(GLuint index) const
+{
+ return mExecutable->mImageUniformRange.contains(index);
+}
+
+GLuint ProgramState::getImageIndexFromUniformIndex(GLuint uniformIndex) const
+{
+ ASSERT(isImageUniformIndex(uniformIndex));
+ return uniformIndex - mExecutable->mImageUniformRange.low();
+}
+
+GLuint ProgramState::getAttributeLocation(const std::string &name) const
+{
+ for (const sh::ShaderVariable &attribute : mExecutable->mProgramInputs)
+ {
+ if (attribute.name == name)
+ {
+ return attribute.location;
+ }
+ }
+
+ return static_cast<GLuint>(-1);
+}
+
+bool ProgramState::hasAttachedShader() const
+{
+ for (const Shader *shader : mAttachedShaders)
+ {
+ if (shader)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+ShaderType ProgramState::getFirstAttachedShaderStageType() const
+{
+ const ShaderBitSet linkedStages = mExecutable->getLinkedShaderStages();
+ if (linkedStages.none())
+ {
+ return ShaderType::InvalidEnum;
+ }
+
+ return linkedStages.first();
+}
+
+ShaderType ProgramState::getLastAttachedShaderStageType() const
+{
+ const ShaderBitSet linkedStages = mExecutable->getLinkedShaderStages();
+ if (linkedStages.none())
+ {
+ return ShaderType::InvalidEnum;
+ }
+
+ return linkedStages.last();
+}
+
+ShaderType ProgramState::getAttachedTransformFeedbackStage() const
+{
+ if (mAttachedShaders[ShaderType::Geometry])
+ {
+ return ShaderType::Geometry;
+ }
+ if (mAttachedShaders[ShaderType::TessEvaluation])
+ {
+ return ShaderType::TessEvaluation;
+ }
+ return ShaderType::Vertex;
+}
+
+Program::Program(rx::GLImplFactory *factory, ShaderProgramManager *manager, ShaderProgramID handle)
+ : mSerial(factory->generateSerial()),
+ mProgram(factory->createProgram(mState)),
+ mValidated(false),
+ mLinked(false),
+ mDeleteStatus(false),
+ mRefCount(0),
+ mResourceManager(manager),
+ mHandle(handle)
+{
+ ASSERT(mProgram);
+
+ unlink();
+}
+
+Program::~Program()
+{
+ ASSERT(!mProgram);
+}
+
+void Program::onDestroy(const Context *context)
+{
+ resolveLink(context);
+ for (ShaderType shaderType : AllShaderTypes())
+ {
+ if (mState.mAttachedShaders[shaderType])
+ {
+ mState.mAttachedShaders[shaderType]->release(context);
+ mState.mAttachedShaders[shaderType] = nullptr;
+ }
+ }
+
+ mProgram->destroy(context);
+
+ ASSERT(!mState.hasAttachedShader());
+ SafeDelete(mProgram);
+
+ delete this;
+}
+ShaderProgramID Program::id() const
+{
+ ASSERT(!mLinkingState);
+ return mHandle;
+}
+
+angle::Result Program::setLabel(const Context *context, const std::string &label)
+{
+ ASSERT(!mLinkingState);
+ mState.mLabel = label;
+
+ if (mProgram)
+ {
+ return mProgram->onLabelUpdate(context);
+ }
+ return angle::Result::Continue;
+}
+
+const std::string &Program::getLabel() const
+{
+ ASSERT(!mLinkingState);
+ return mState.mLabel;
+}
+
+void Program::attachShader(Shader *shader)
+{
+ ShaderType shaderType = shader->getType();
+ ASSERT(shaderType != ShaderType::InvalidEnum);
+
+ mState.mAttachedShaders[shaderType] = shader;
+ mState.mAttachedShaders[shaderType]->addRef();
+}
+
+void Program::detachShader(const Context *context, Shader *shader)
+{
+ resolveLink(context);
+ ShaderType shaderType = shader->getType();
+ ASSERT(shaderType != ShaderType::InvalidEnum);
+
+ ASSERT(mState.mAttachedShaders[shaderType] == shader);
+ shader->release(context);
+ mState.mAttachedShaders[shaderType] = nullptr;
+}
+
+int Program::getAttachedShadersCount() const
+{
+ ASSERT(!mLinkingState);
+ int numAttachedShaders = 0;
+ for (const Shader *shader : mState.mAttachedShaders)
+ {
+ if (shader)
+ {
+ ++numAttachedShaders;
+ }
+ }
+
+ return numAttachedShaders;
+}
+
+Shader *Program::getAttachedShader(ShaderType shaderType) const
+{
+ ASSERT(!mLinkingState);
+ return mState.getAttachedShader(shaderType);
+}
+
+void Program::bindAttributeLocation(GLuint index, const char *name)
+{
+ ASSERT(!mLinkingState);
+ mAttributeBindings.bindLocation(index, name);
+}
+
+void Program::bindUniformLocation(UniformLocation location, const char *name)
+{
+ ASSERT(!mLinkingState);
+ mState.mUniformLocationBindings.bindLocation(location.value, name);
+}
+
+void Program::bindFragmentOutputLocation(GLuint index, const char *name)
+{
+ mFragmentOutputLocations.bindLocation(index, name);
+}
+
+void Program::bindFragmentOutputIndex(GLuint index, const char *name)
+{
+ mFragmentOutputIndexes.bindLocation(index, name);
+}
+
+angle::Result Program::link(const Context *context)
+{
+ angle::Result result = linkImpl(context);
+
+ // Avoid having two ProgramExecutables if the link failed and the Program had successfully
+ // linked previously.
+ if (mLinkingState && mLinkingState->linkedExecutable)
+ {
+ mState.mExecutable = mLinkingState->linkedExecutable;
+ }
+
+ return result;
+}
+
+// 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.
+angle::Result Program::linkImpl(const Context *context)
+{
+ ASSERT(!mLinkingState);
+ // Don't make any local variables pointing to anything within the ProgramExecutable, since
+ // unlink() could make a new ProgramExecutable making any references/pointers invalid.
+ auto *platform = ANGLEPlatformCurrent();
+ double startTime = platform->currentTime(platform);
+
+ // Unlink the program, but do not clear the validation-related caching yet, since we can still
+ // use the previously linked program if linking the shaders fails.
+ mLinked = false;
+
+ mState.mExecutable->resetInfoLog();
+
+ // Validate we have properly attached shaders before checking the cache.
+ if (!linkValidateShaders(context, mState.mExecutable->getInfoLog()))
+ {
+ return angle::Result::Continue;
+ }
+
+ egl::BlobCache::Key programHash = {0};
+ MemoryProgramCache *cache = context->getMemoryProgramCache();
+
+ // TODO: http://anglebug.com/4530: Enable program caching for separable programs
+ if (cache && !isSeparable())
+ {
+ std::lock_guard<std::mutex> cacheLock(context->getProgramCacheMutex());
+ angle::Result cacheResult = cache->getProgram(context, this, &programHash);
+ ANGLE_TRY(cacheResult);
+
+ // Check explicitly for Continue, Incomplete means a cache miss
+ if (cacheResult == angle::Result::Continue)
+ {
+ std::scoped_lock lock(mHistogramMutex);
+ // Succeeded in loading the binaries in the front-end, back end may still be loading
+ // asynchronously
+ double delta = platform->currentTime(platform) - startTime;
+ int us = static_cast<int>(delta * 1000000.0);
+ ANGLE_HISTOGRAM_COUNTS("GPU.ANGLE.ProgramCache.ProgramCacheHitTimeUS", us);
+ return angle::Result::Continue;
+ }
+ }
+
+ // Cache load failed, fall through to normal linking.
+ unlink();
+ InfoLog &infoLog = mState.mExecutable->getInfoLog();
+
+ // Re-link shaders after the unlink call.
+ bool result = linkValidateShaders(context, infoLog);
+ ASSERT(result);
+
+ std::unique_ptr<LinkingState> linkingState(new LinkingState());
+ ProgramMergedVaryings mergedVaryings;
+ LinkingVariables linkingVariables(context, mState);
+ ProgramLinkedResources &resources = linkingState->resources;
+
+ resources.init(&mState.mExecutable->mUniformBlocks, &mState.mExecutable->mUniforms,
+ &mState.mExecutable->mShaderStorageBlocks, &mState.mBufferVariables,
+ &mState.mExecutable->mAtomicCounterBuffers);
+
+ // TODO: Fix incomplete linking. http://anglebug.com/6358
+ updateLinkedShaderStages();
+
+ InitUniformBlockLinker(context, mState, &resources.uniformBlockLinker);
+ InitShaderStorageBlockLinker(context, mState, &resources.shaderStorageBlockLinker);
+
+ if (mState.mAttachedShaders[ShaderType::Compute])
+ {
+ GLuint combinedImageUniforms = 0;
+ if (!linkUniforms(context, &resources.unusedUniforms, &combinedImageUniforms, infoLog))
+ {
+ return angle::Result::Continue;
+ }
+
+ GLuint combinedShaderStorageBlocks = 0u;
+ if (!LinkValidateProgramInterfaceBlocks(context,
+ mState.mExecutable->getLinkedShaderStages(),
+ resources, infoLog, &combinedShaderStorageBlocks))
+ {
+ return angle::Result::Continue;
+ }
+
+ // [OpenGL ES 3.1] Chapter 8.22 Page 203:
+ // A link error will be generated if the sum of the number of active image uniforms used in
+ // all shaders, the number of active shader storage blocks, and the number of active
+ // fragment shader outputs exceeds the implementation-dependent value of
+ // MAX_COMBINED_SHADER_OUTPUT_RESOURCES.
+ if (combinedImageUniforms + combinedShaderStorageBlocks >
+ static_cast<GLuint>(context->getCaps().maxCombinedShaderOutputResources))
+ {
+ infoLog
+ << "The sum of the number of active image uniforms, active shader storage blocks "
+ "and active fragment shader outputs exceeds "
+ "MAX_COMBINED_SHADER_OUTPUT_RESOURCES ("
+ << context->getCaps().maxCombinedShaderOutputResources << ")";
+ return angle::Result::Continue;
+ }
+ }
+ else
+ {
+ if (!linkAttributes(context, infoLog))
+ {
+ return angle::Result::Continue;
+ }
+
+ if (!linkVaryings(context, infoLog))
+ {
+ return angle::Result::Continue;
+ }
+
+ GLuint combinedImageUniforms = 0;
+ if (!linkUniforms(context, &resources.unusedUniforms, &combinedImageUniforms, infoLog))
+ {
+ return angle::Result::Continue;
+ }
+
+ GLuint combinedShaderStorageBlocks = 0u;
+ if (!LinkValidateProgramInterfaceBlocks(context,
+ mState.mExecutable->getLinkedShaderStages(),
+ resources, infoLog, &combinedShaderStorageBlocks))
+ {
+ return angle::Result::Continue;
+ }
+
+ if (!LinkValidateProgramGlobalNames(infoLog, getExecutable(), linkingVariables))
+ {
+ return angle::Result::Continue;
+ }
+
+ gl::Shader *vertexShader = mState.mAttachedShaders[ShaderType::Vertex];
+ if (vertexShader)
+ {
+ mState.mNumViews = vertexShader->getNumViews(context);
+ mState.mSpecConstUsageBits |= vertexShader->getSpecConstUsageBits();
+ }
+
+ gl::Shader *fragmentShader = mState.mAttachedShaders[ShaderType::Fragment];
+ if (fragmentShader)
+ {
+ if (!mState.mExecutable->linkValidateOutputVariables(
+ context->getCaps(), context->getExtensions(), context->getClientVersion(),
+ combinedImageUniforms, combinedShaderStorageBlocks,
+ fragmentShader->getActiveOutputVariables(context),
+ fragmentShader->getShaderVersion(context), mFragmentOutputLocations,
+ mFragmentOutputIndexes))
+ {
+ return angle::Result::Continue;
+ }
+
+ mState.mExecutable->mHasDiscard = fragmentShader->hasDiscard();
+ mState.mExecutable->mEnablesPerSampleShading =
+ fragmentShader->enablesPerSampleShading();
+ mState.mExecutable->mAdvancedBlendEquations =
+ fragmentShader->getAdvancedBlendEquations();
+ mState.mSpecConstUsageBits |= fragmentShader->getSpecConstUsageBits();
+ }
+
+ mergedVaryings = GetMergedVaryingsFromLinkingVariables(linkingVariables);
+ if (!mState.mExecutable->linkMergedVaryings(
+ context, mergedVaryings, mState.mTransformFeedbackVaryingNames, linkingVariables,
+ isSeparable(), &resources.varyingPacking))
+ {
+ return angle::Result::Continue;
+ }
+ }
+
+ mState.mExecutable->saveLinkedStateInfo(context, mState);
+
+ mLinkingState = std::move(linkingState);
+ mLinkingState->linkingFromBinary = false;
+ mLinkingState->programHash = programHash;
+ mLinkingState->linkEvent = mProgram->link(context, resources, infoLog, mergedVaryings);
+
+ // Must be after mProgram->link() to avoid misleading the linker about output variables.
+ mState.updateProgramInterfaceInputs(context);
+ mState.updateProgramInterfaceOutputs(context);
+
+ if (mState.mSeparable)
+ {
+ mLinkingState->linkedExecutable = mState.mExecutable;
+ }
+
+ return angle::Result::Continue;
+}
+
+bool Program::isLinking() const
+{
+ return (mLinkingState.get() && mLinkingState->linkEvent &&
+ mLinkingState->linkEvent->isLinking());
+}
+
+void Program::resolveLinkImpl(const Context *context)
+{
+ ASSERT(mLinkingState.get());
+
+ angle::Result result = mLinkingState->linkEvent->wait(context);
+
+ mLinked = result == angle::Result::Continue;
+ std::unique_ptr<LinkingState> linkingState = std::move(mLinkingState);
+ if (!mLinked)
+ {
+ mState.mExecutable->reset(false);
+ return;
+ }
+
+ if (linkingState->linkingFromBinary)
+ {
+ // All internal Program state is already loaded from the binary.
+ return;
+ }
+
+ initInterfaceBlockBindings();
+
+ // According to GLES 3.0/3.1 spec for LinkProgram and UseProgram,
+ // Only successfully linked program can replace the executables.
+ ASSERT(mLinked);
+
+ // Mark implementation-specific unreferenced uniforms as ignored.
+ std::vector<ImageBinding> *imageBindings = getExecutable().getImageBindings();
+ mProgram->markUnusedUniformLocations(&mState.mUniformLocations,
+ &mState.mExecutable->mSamplerBindings, imageBindings);
+
+ // Must be called after markUnusedUniformLocations.
+ postResolveLink(context);
+
+ // Save to the program cache.
+ std::lock_guard<std::mutex> cacheLock(context->getProgramCacheMutex());
+ MemoryProgramCache *cache = context->getMemoryProgramCache();
+ // TODO: http://anglebug.com/4530: Enable program caching for separable programs
+ if (cache && !isSeparable() &&
+ (mState.mExecutable->mLinkedTransformFeedbackVaryings.empty() ||
+ !context->getFrontendFeatures().disableProgramCachingForTransformFeedback.enabled))
+ {
+ if (cache->putProgram(linkingState->programHash, context, this) == angle::Result::Stop)
+ {
+ // Don't fail linking if putting the program binary into the cache fails, the program is
+ // still usable.
+ ANGLE_PERF_WARNING(context->getState().getDebug(), GL_DEBUG_SEVERITY_LOW,
+ "Failed to save linked program to memory program cache.");
+ }
+ }
+}
+
+void Program::updateLinkedShaderStages()
+{
+ mState.mExecutable->resetLinkedShaderStages();
+
+ for (const Shader *shader : mState.mAttachedShaders)
+ {
+ if (shader)
+ {
+ mState.mExecutable->setLinkedShaderStages(shader->getType());
+ }
+ }
+}
+
+void ProgramState::updateActiveSamplers()
+{
+ mExecutable->mActiveSamplerRefCounts.fill(0);
+ mExecutable->updateActiveSamplers(*this);
+}
+
+void ProgramState::updateProgramInterfaceInputs(const Context *context)
+{
+ const ShaderType firstAttachedShaderType = getFirstAttachedShaderStageType();
+
+ if (firstAttachedShaderType == ShaderType::Vertex)
+ {
+ // Vertex attributes are already what we need, so nothing to do
+ return;
+ }
+
+ Shader *shader = getAttachedShader(firstAttachedShaderType);
+ ASSERT(shader);
+
+ // Copy over each input varying, since the Shader could go away
+ if (shader->getType() == ShaderType::Compute)
+ {
+ for (const sh::ShaderVariable &attribute : shader->getAllAttributes(context))
+ {
+ // Compute Shaders have the following built-in input variables.
+ //
+ // in uvec3 gl_NumWorkGroups;
+ // in uvec3 gl_WorkGroupID;
+ // in uvec3 gl_LocalInvocationID;
+ // in uvec3 gl_GlobalInvocationID;
+ // in uint gl_LocalInvocationIndex;
+ // They are all vecs or uints, so no special handling is required.
+ mExecutable->mProgramInputs.emplace_back(attribute);
+ }
+ }
+ else
+ {
+ for (const sh::ShaderVariable &varying : shader->getInputVaryings(context))
+ {
+ UpdateInterfaceVariable(&mExecutable->mProgramInputs, varying);
+ }
+ }
+}
+
+void ProgramState::updateProgramInterfaceOutputs(const Context *context)
+{
+ const ShaderType lastAttachedShaderType = getLastAttachedShaderStageType();
+
+ if (lastAttachedShaderType == ShaderType::Fragment)
+ {
+ // Fragment outputs are already what we need, so nothing to do
+ return;
+ }
+ if (lastAttachedShaderType == ShaderType::Compute)
+ {
+ // If the program only contains a Compute Shader, then there are no user-defined outputs.
+ return;
+ }
+
+ Shader *shader = getAttachedShader(lastAttachedShaderType);
+ ASSERT(shader);
+
+ // Copy over each output varying, since the Shader could go away
+ for (const sh::ShaderVariable &varying : shader->getOutputVaryings(context))
+ {
+ UpdateInterfaceVariable(&mExecutable->mOutputVariables, varying);
+ }
+}
+
+// Returns the program object to an unlinked state, before re-linking, or at destruction
+void Program::unlink()
+{
+ if (mLinkingState && mLinkingState->linkedExecutable)
+ {
+ // The new ProgramExecutable that we'll attempt to link with needs to start from a copy of
+ // the last successfully linked ProgramExecutable, so we don't lose any state information.
+ mState.mExecutable.reset(new ProgramExecutable(*mLinkingState->linkedExecutable));
+ }
+ mState.mExecutable->reset(true);
+
+ mState.mUniformLocations.clear();
+ mState.mBufferVariables.clear();
+ mState.mComputeShaderLocalSize.fill(1);
+ mState.mNumViews = -1;
+ mState.mDrawIDLocation = -1;
+ mState.mBaseVertexLocation = -1;
+ mState.mBaseInstanceLocation = -1;
+ mState.mCachedBaseVertex = 0;
+ mState.mCachedBaseInstance = 0;
+ mState.mSpecConstUsageBits.reset();
+
+ mValidated = false;
+
+ mLinked = false;
+}
+
+angle::Result Program::loadBinary(const Context *context,
+ GLenum binaryFormat,
+ const void *binary,
+ GLsizei length)
+{
+ ASSERT(!mLinkingState);
+ unlink();
+ InfoLog &infoLog = mState.mExecutable->getInfoLog();
+
+ if (!angle::GetANGLEHasBinaryLoading())
+ {
+ return angle::Result::Incomplete;
+ }
+
+ ASSERT(binaryFormat == GL_PROGRAM_BINARY_ANGLE);
+ if (binaryFormat != GL_PROGRAM_BINARY_ANGLE)
+ {
+ infoLog << "Invalid program binary format.";
+ return angle::Result::Incomplete;
+ }
+
+ BinaryInputStream stream(binary, length);
+ ANGLE_TRY(deserialize(context, stream, infoLog));
+ // Currently we require the full shader text to compute the program hash.
+ // We could also store the binary in the internal program cache.
+
+ for (size_t uniformBlockIndex = 0;
+ uniformBlockIndex < mState.mExecutable->getActiveUniformBlockCount(); ++uniformBlockIndex)
+ {
+ mDirtyBits.set(uniformBlockIndex);
+ }
+
+ // The rx::LinkEvent returned from ProgramImpl::load is a base class with multiple
+ // implementations. In some implementations, a background thread is used to compile the
+ // shaders. Any calls to the LinkEvent object, therefore, are racy and may interfere with
+ // the operation.
+
+ // We do not want to call LinkEvent::wait because that will cause the background thread
+ // to finish its task before returning, thus defeating the purpose of background compilation.
+ // We need to defer waiting on background compilation until the very last minute when we
+ // absolutely need the results, such as when the developer binds the program or queries
+ // for the completion status.
+
+ // If load returns nullptr, we know for sure that the binary is not compatible with the backend.
+ // The loaded binary could have been read from the on-disk shader cache and be corrupted or
+ // serialized with different revision and subsystem id than the currently loaded backend.
+ // Returning 'Incomplete' to the caller results in link happening using the original shader
+ // sources.
+ angle::Result result;
+ std::unique_ptr<LinkingState> linkingState;
+ std::unique_ptr<rx::LinkEvent> linkEvent = mProgram->load(context, &stream, infoLog);
+ if (linkEvent)
+ {
+ linkingState = std::make_unique<LinkingState>();
+ linkingState->linkingFromBinary = true;
+ linkingState->linkEvent = std::move(linkEvent);
+ result = angle::Result::Continue;
+ }
+ else
+ {
+ result = angle::Result::Incomplete;
+ }
+ mLinkingState = std::move(linkingState);
+
+ return result;
+}
+
+angle::Result Program::saveBinary(Context *context,
+ GLenum *binaryFormat,
+ void *binary,
+ GLsizei bufSize,
+ GLsizei *length) const
+{
+ ASSERT(!mLinkingState);
+ if (binaryFormat)
+ {
+ *binaryFormat = GL_PROGRAM_BINARY_ANGLE;
+ }
+
+ angle::MemoryBuffer memoryBuf;
+ ANGLE_TRY(serialize(context, &memoryBuf));
+
+ GLsizei streamLength = static_cast<GLsizei>(memoryBuf.size());
+ const uint8_t *streamState = memoryBuf.data();
+
+ if (streamLength > bufSize)
+ {
+ if (length)
+ {
+ *length = 0;
+ }
+
+ // TODO: This should be moved to the validation layer but computing the size of the binary
+ // before saving it causes the save to happen twice. It may be possible to write the binary
+ // to a separate buffer, validate sizes and then copy it.
+ ANGLE_CHECK(context, false, "Insufficient buffer size", GL_INVALID_OPERATION);
+ }
+
+ if (binary)
+ {
+ char *ptr = reinterpret_cast<char *>(binary);
+
+ memcpy(ptr, streamState, streamLength);
+ ptr += streamLength;
+
+ ASSERT(ptr - streamLength == binary);
+ }
+
+ if (length)
+ {
+ *length = streamLength;
+ }
+
+ return angle::Result::Continue;
+}
+
+GLint Program::getBinaryLength(Context *context) const
+{
+ ASSERT(!mLinkingState);
+ if (!mLinked)
+ {
+ return 0;
+ }
+
+ GLint length;
+ angle::Result result =
+ saveBinary(context, nullptr, nullptr, std::numeric_limits<GLint>::max(), &length);
+ if (result != angle::Result::Continue)
+ {
+ return 0;
+ }
+
+ return length;
+}
+
+void Program::setBinaryRetrievableHint(bool retrievable)
+{
+ ASSERT(!mLinkingState);
+ // TODO(jmadill) : replace with dirty bits
+ mProgram->setBinaryRetrievableHint(retrievable);
+ mState.mBinaryRetrieveableHint = retrievable;
+}
+
+bool Program::getBinaryRetrievableHint() const
+{
+ ASSERT(!mLinkingState);
+ return mState.mBinaryRetrieveableHint;
+}
+
+void Program::setSeparable(bool separable)
+{
+ ASSERT(!mLinkingState);
+ // TODO(yunchao) : replace with dirty bits
+ if (mState.mSeparable != separable)
+ {
+ mProgram->setSeparable(separable);
+ mState.mSeparable = separable;
+ }
+}
+
+bool Program::isSeparable() const
+{
+ ASSERT(!mLinkingState);
+ return mState.mSeparable;
+}
+
+void Program::deleteSelf(const Context *context)
+{
+ ASSERT(mRefCount == 0 && mDeleteStatus);
+ mResourceManager->deleteProgram(context, mHandle);
+}
+
+unsigned int Program::getRefCount() const
+{
+ return mRefCount;
+}
+
+void Program::getAttachedShaders(GLsizei maxCount, GLsizei *count, ShaderProgramID *shaders) const
+{
+ ASSERT(!mLinkingState);
+ int total = 0;
+
+ for (const Shader *shader : mState.mAttachedShaders)
+ {
+ if (shader && (total < maxCount))
+ {
+ shaders[total] = shader->getHandle();
+ ++total;
+ }
+ }
+
+ if (count)
+ {
+ *count = total;
+ }
+}
+
+GLuint Program::getAttributeLocation(const std::string &name) const
+{
+ ASSERT(!mLinkingState);
+ return mState.getAttributeLocation(name);
+}
+
+void Program::getActiveAttribute(GLuint index,
+ GLsizei bufsize,
+ GLsizei *length,
+ GLint *size,
+ GLenum *type,
+ GLchar *name) const
+{
+ ASSERT(!mLinkingState);
+ if (!mLinked)
+ {
+ if (bufsize > 0)
+ {
+ name[0] = '\0';
+ }
+
+ if (length)
+ {
+ *length = 0;
+ }
+
+ *type = GL_NONE;
+ *size = 1;
+ return;
+ }
+
+ ASSERT(index < mState.mExecutable->getProgramInputs().size());
+ const sh::ShaderVariable &attrib = mState.mExecutable->getProgramInputs()[index];
+
+ if (bufsize > 0)
+ {
+ CopyStringToBuffer(name, attrib.name, bufsize, length);
+ }
+
+ // Always a single 'type' instance
+ *size = 1;
+ *type = attrib.type;
+}
+
+GLint Program::getActiveAttributeCount() const
+{
+ ASSERT(!mLinkingState);
+ if (!mLinked)
+ {
+ return 0;
+ }
+
+ return static_cast<GLint>(mState.mExecutable->getProgramInputs().size());
+}
+
+GLint Program::getActiveAttributeMaxLength() const
+{
+ ASSERT(!mLinkingState);
+ if (!mLinked)
+ {
+ return 0;
+ }
+
+ size_t maxLength = 0;
+
+ for (const sh::ShaderVariable &attrib : mState.mExecutable->getProgramInputs())
+ {
+ maxLength = std::max(attrib.name.length() + 1, maxLength);
+ }
+
+ return static_cast<GLint>(maxLength);
+}
+
+const std::vector<sh::ShaderVariable> &Program::getAttributes() const
+{
+ ASSERT(!mLinkingState);
+ return mState.mExecutable->getProgramInputs();
+}
+
+const sh::WorkGroupSize &Program::getComputeShaderLocalSize() const
+{
+ ASSERT(!mLinkingState);
+ return mState.mComputeShaderLocalSize;
+}
+
+PrimitiveMode Program::getGeometryShaderInputPrimitiveType() const
+{
+ ASSERT(!mLinkingState && mState.mExecutable);
+ return mState.mExecutable->getGeometryShaderInputPrimitiveType();
+}
+PrimitiveMode Program::getGeometryShaderOutputPrimitiveType() const
+{
+ ASSERT(!mLinkingState && mState.mExecutable);
+ return mState.mExecutable->getGeometryShaderOutputPrimitiveType();
+}
+GLint Program::getGeometryShaderInvocations() const
+{
+ ASSERT(!mLinkingState && mState.mExecutable);
+ return mState.mExecutable->getGeometryShaderInvocations();
+}
+GLint Program::getGeometryShaderMaxVertices() const
+{
+ ASSERT(!mLinkingState && mState.mExecutable);
+ return mState.mExecutable->getGeometryShaderMaxVertices();
+}
+
+GLint Program::getTessControlShaderVertices() const
+{
+ ASSERT(!mLinkingState && mState.mExecutable);
+ return mState.mExecutable->mTessControlShaderVertices;
+}
+
+GLenum Program::getTessGenMode() const
+{
+ ASSERT(!mLinkingState && mState.mExecutable);
+ return mState.mExecutable->mTessGenMode;
+}
+
+GLenum Program::getTessGenPointMode() const
+{
+ ASSERT(!mLinkingState && mState.mExecutable);
+ return mState.mExecutable->mTessGenPointMode;
+}
+
+GLenum Program::getTessGenSpacing() const
+{
+ ASSERT(!mLinkingState && mState.mExecutable);
+ return mState.mExecutable->mTessGenSpacing;
+}
+
+GLenum Program::getTessGenVertexOrder() const
+{
+ ASSERT(!mLinkingState && mState.mExecutable);
+ return mState.mExecutable->mTessGenVertexOrder;
+}
+
+const sh::ShaderVariable &Program::getInputResource(size_t index) const
+{
+ ASSERT(!mLinkingState);
+ ASSERT(index < mState.mExecutable->getProgramInputs().size());
+ return mState.mExecutable->getProgramInputs()[index];
+}
+
+GLuint Program::getInputResourceIndex(const GLchar *name) const
+{
+ ASSERT(!mLinkingState);
+ const std::string nameString = StripLastArrayIndex(name);
+
+ for (size_t index = 0; index < mState.mExecutable->getProgramInputs().size(); index++)
+ {
+ sh::ShaderVariable resource = getInputResource(index);
+ if (resource.name == nameString)
+ {
+ return static_cast<GLuint>(index);
+ }
+ }
+
+ return GL_INVALID_INDEX;
+}
+
+GLuint Program::getResourceMaxNameSize(const sh::ShaderVariable &resource, GLint max) const
+{
+ if (resource.isArray())
+ {
+ return std::max(max, clampCast<GLint>((resource.name + "[0]").size()));
+ }
+ else
+ {
+ return std::max(max, clampCast<GLint>((resource.name).size()));
+ }
+}
+
+GLuint Program::getInputResourceMaxNameSize() const
+{
+ GLint max = 0;
+
+ for (const sh::ShaderVariable &resource : mState.mExecutable->getProgramInputs())
+ {
+ max = getResourceMaxNameSize(resource, max);
+ }
+
+ return max;
+}
+
+GLuint Program::getOutputResourceMaxNameSize() const
+{
+ GLint max = 0;
+
+ for (const sh::ShaderVariable &resource : mState.mExecutable->getOutputVariables())
+ {
+ max = getResourceMaxNameSize(resource, max);
+ }
+
+ return max;
+}
+
+GLuint Program::getResourceLocation(const GLchar *name, const sh::ShaderVariable &variable) const
+{
+ if (variable.isBuiltIn())
+ {
+ return GL_INVALID_INDEX;
+ }
+
+ GLint location = variable.location;
+ if (variable.isArray())
+ {
+ size_t nameLengthWithoutArrayIndexOut;
+ size_t arrayIndex = ParseArrayIndex(name, &nameLengthWithoutArrayIndexOut);
+ // The 'name' string may not contain the array notation "[0]"
+ if (arrayIndex != GL_INVALID_INDEX)
+ {
+ location += arrayIndex;
+ }
+ }
+
+ return location;
+}
+
+GLuint Program::getInputResourceLocation(const GLchar *name) const
+{
+ const GLuint index = getInputResourceIndex(name);
+ if (index == GL_INVALID_INDEX)
+ {
+ return index;
+ }
+
+ const sh::ShaderVariable &variable = getInputResource(index);
+
+ return getResourceLocation(name, variable);
+}
+
+GLuint Program::getOutputResourceLocation(const GLchar *name) const
+{
+ const GLuint index = getOutputResourceIndex(name);
+ if (index == GL_INVALID_INDEX)
+ {
+ return index;
+ }
+
+ const sh::ShaderVariable &variable = getOutputResource(index);
+
+ return getResourceLocation(name, variable);
+}
+
+GLuint Program::getOutputResourceIndex(const GLchar *name) const
+{
+ ASSERT(!mLinkingState);
+ const std::string nameString = StripLastArrayIndex(name);
+
+ for (size_t index = 0; index < mState.mExecutable->getOutputVariables().size(); index++)
+ {
+ sh::ShaderVariable resource = getOutputResource(index);
+ if (resource.name == nameString)
+ {
+ return static_cast<GLuint>(index);
+ }
+ }
+
+ return GL_INVALID_INDEX;
+}
+
+size_t Program::getOutputResourceCount() const
+{
+ ASSERT(!mLinkingState);
+ return (mLinked ? mState.mExecutable->getOutputVariables().size() : 0);
+}
+
+void Program::getResourceName(const std::string name,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *dest) const
+{
+ if (length)
+ {
+ *length = 0;
+ }
+
+ if (!mLinked)
+ {
+ if (bufSize > 0)
+ {
+ dest[0] = '\0';
+ }
+ return;
+ }
+
+ if (bufSize > 0)
+ {
+ CopyStringToBuffer(dest, name, bufSize, length);
+ }
+}
+
+void Program::getInputResourceName(GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *name) const
+{
+ ASSERT(!mLinkingState);
+ getResourceName(getInputResourceName(index), bufSize, length, name);
+}
+
+void Program::getOutputResourceName(GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *name) const
+{
+ ASSERT(!mLinkingState);
+ getResourceName(getOutputResourceName(index), bufSize, length, name);
+}
+
+void Program::getUniformResourceName(GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *name) const
+{
+ ASSERT(!mLinkingState);
+ ASSERT(index < mState.mExecutable->getUniforms().size());
+ getResourceName(mState.mExecutable->getUniforms()[index].name, bufSize, length, name);
+}
+
+void Program::getBufferVariableResourceName(GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *name) const
+{
+ ASSERT(!mLinkingState);
+ ASSERT(index < mState.mBufferVariables.size());
+ getResourceName(mState.mBufferVariables[index].name, bufSize, length, name);
+}
+
+const std::string Program::getResourceName(const sh::ShaderVariable &resource) const
+{
+ std::string resourceName = resource.name;
+
+ if (resource.isArray())
+ {
+ resourceName += "[0]";
+ }
+
+ return resourceName;
+}
+
+const std::string Program::getInputResourceName(GLuint index) const
+{
+ ASSERT(!mLinkingState);
+ const sh::ShaderVariable &resource = getInputResource(index);
+
+ return getResourceName(resource);
+}
+
+const std::string Program::getOutputResourceName(GLuint index) const
+{
+ ASSERT(!mLinkingState);
+ const sh::ShaderVariable &resource = getOutputResource(index);
+
+ return getResourceName(resource);
+}
+
+const sh::ShaderVariable &Program::getOutputResource(size_t index) const
+{
+ ASSERT(!mLinkingState);
+ ASSERT(index < mState.mExecutable->getOutputVariables().size());
+ return mState.mExecutable->getOutputVariables()[index];
+}
+
+const ProgramBindings &Program::getAttributeBindings() const
+{
+ ASSERT(!mLinkingState);
+ return mAttributeBindings;
+}
+const ProgramAliasedBindings &Program::getUniformLocationBindings() const
+{
+ ASSERT(!mLinkingState);
+ return mState.mUniformLocationBindings;
+}
+
+const gl::ProgramAliasedBindings &Program::getFragmentOutputLocations() const
+{
+ ASSERT(!mLinkingState);
+ return mFragmentOutputLocations;
+}
+
+const gl::ProgramAliasedBindings &Program::getFragmentOutputIndexes() const
+{
+ ASSERT(!mLinkingState);
+ return mFragmentOutputIndexes;
+}
+
+const std::vector<GLsizei> &Program::getTransformFeedbackStrides() const
+{
+ ASSERT(!mLinkingState);
+ return mState.mExecutable->getTransformFeedbackStrides();
+}
+
+GLint Program::getFragDataLocation(const std::string &name) const
+{
+ ASSERT(!mLinkingState);
+ GLint primaryLocation = GetVariableLocation(mState.mExecutable->getOutputVariables(),
+ mState.mExecutable->getOutputLocations(), name);
+ if (primaryLocation != -1)
+ {
+ return primaryLocation;
+ }
+ return GetVariableLocation(mState.mExecutable->getOutputVariables(),
+ mState.mExecutable->getSecondaryOutputLocations(), name);
+}
+
+GLint Program::getFragDataIndex(const std::string &name) const
+{
+ ASSERT(!mLinkingState);
+ if (GetVariableLocation(mState.mExecutable->getOutputVariables(),
+ mState.mExecutable->getOutputLocations(), name) != -1)
+ {
+ return 0;
+ }
+ if (GetVariableLocation(mState.mExecutable->getOutputVariables(),
+ mState.mExecutable->getSecondaryOutputLocations(), name) != -1)
+ {
+ return 1;
+ }
+ return -1;
+}
+
+void Program::getActiveUniform(GLuint index,
+ GLsizei bufsize,
+ GLsizei *length,
+ GLint *size,
+ GLenum *type,
+ GLchar *name) const
+{
+ ASSERT(!mLinkingState);
+ if (mLinked)
+ {
+ // index must be smaller than getActiveUniformCount()
+ ASSERT(index < mState.mExecutable->getUniforms().size());
+ const LinkedUniform &uniform = mState.mExecutable->getUniforms()[index];
+
+ if (bufsize > 0)
+ {
+ std::string string = uniform.name;
+ CopyStringToBuffer(name, string, bufsize, length);
+ }
+
+ *size = clampCast<GLint>(uniform.getBasicTypeElementCount());
+ *type = uniform.type;
+ }
+ else
+ {
+ if (bufsize > 0)
+ {
+ name[0] = '\0';
+ }
+
+ if (length)
+ {
+ *length = 0;
+ }
+
+ *size = 0;
+ *type = GL_NONE;
+ }
+}
+
+GLint Program::getActiveUniformCount() const
+{
+ ASSERT(!mLinkingState);
+ if (mLinked)
+ {
+ return static_cast<GLint>(mState.mExecutable->getUniforms().size());
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+size_t Program::getActiveBufferVariableCount() const
+{
+ ASSERT(!mLinkingState);
+ return mLinked ? mState.mBufferVariables.size() : 0;
+}
+
+GLint Program::getActiveUniformMaxLength() const
+{
+ ASSERT(!mLinkingState);
+ size_t maxLength = 0;
+
+ if (mLinked)
+ {
+ for (const LinkedUniform &uniform : mState.mExecutable->getUniforms())
+ {
+ if (!uniform.name.empty())
+ {
+ size_t length = uniform.name.length() + 1u;
+ if (uniform.isArray())
+ {
+ length += 3; // Counting in "[0]".
+ }
+ maxLength = std::max(length, maxLength);
+ }
+ }
+ }
+
+ return static_cast<GLint>(maxLength);
+}
+
+bool Program::isValidUniformLocation(UniformLocation location) const
+{
+ ASSERT(!mLinkingState);
+ ASSERT(angle::IsValueInRangeForNumericType<GLint>(mState.mUniformLocations.size()));
+ return (location.value >= 0 &&
+ static_cast<size_t>(location.value) < mState.mUniformLocations.size() &&
+ mState.mUniformLocations[static_cast<size_t>(location.value)].used());
+}
+
+const LinkedUniform &Program::getUniformByLocation(UniformLocation location) const
+{
+ ASSERT(!mLinkingState);
+ ASSERT(location.value >= 0 &&
+ static_cast<size_t>(location.value) < mState.mUniformLocations.size());
+ return mState.mExecutable->getUniforms()[mState.getUniformIndexFromLocation(location)];
+}
+
+const VariableLocation &Program::getUniformLocation(UniformLocation location) const
+{
+ ASSERT(!mLinkingState);
+ ASSERT(location.value >= 0 &&
+ static_cast<size_t>(location.value) < mState.mUniformLocations.size());
+ return mState.mUniformLocations[location.value];
+}
+
+const BufferVariable &Program::getBufferVariableByIndex(GLuint index) const
+{
+ ASSERT(!mLinkingState);
+ ASSERT(index < static_cast<size_t>(mState.mBufferVariables.size()));
+ return mState.mBufferVariables[index];
+}
+
+UniformLocation Program::getUniformLocation(const std::string &name) const
+{
+ ASSERT(!mLinkingState);
+ return {GetVariableLocation(mState.mExecutable->getUniforms(), mState.mUniformLocations, name)};
+}
+
+GLuint Program::getUniformIndex(const std::string &name) const
+{
+ ASSERT(!mLinkingState);
+ return mState.getUniformIndexFromName(name);
+}
+
+bool Program::shouldIgnoreUniform(UniformLocation location) const
+{
+ if (location.value == -1)
+ {
+ return true;
+ }
+
+ if (mState.mUniformLocations[static_cast<size_t>(location.value)].ignored)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+template <typename UniformT,
+ GLint UniformSize,
+ void (rx::ProgramImpl::*SetUniformFunc)(GLint, GLsizei, const UniformT *)>
+void Program::setUniformGeneric(UniformLocation location, GLsizei count, const UniformT *v)
+{
+ ASSERT(!mLinkingState);
+ if (shouldIgnoreUniform(location))
+ {
+ return;
+ }
+
+ const VariableLocation &locationInfo = mState.mUniformLocations[location.value];
+ GLsizei clampedCount = clampUniformCount(locationInfo, count, UniformSize, v);
+ (mProgram->*SetUniformFunc)(location.value, clampedCount, v);
+ onStateChange(angle::SubjectMessage::ProgramUniformUpdated);
+}
+
+void Program::setUniform1fv(UniformLocation location, GLsizei count, const GLfloat *v)
+{
+ setUniformGeneric<GLfloat, 1, &rx::ProgramImpl::setUniform1fv>(location, count, v);
+}
+
+void Program::setUniform2fv(UniformLocation location, GLsizei count, const GLfloat *v)
+{
+ setUniformGeneric<GLfloat, 2, &rx::ProgramImpl::setUniform2fv>(location, count, v);
+}
+
+void Program::setUniform3fv(UniformLocation location, GLsizei count, const GLfloat *v)
+{
+ setUniformGeneric<GLfloat, 3, &rx::ProgramImpl::setUniform3fv>(location, count, v);
+}
+
+void Program::setUniform4fv(UniformLocation location, GLsizei count, const GLfloat *v)
+{
+ setUniformGeneric<GLfloat, 4, &rx::ProgramImpl::setUniform4fv>(location, count, v);
+}
+
+void Program::setUniform1iv(Context *context,
+ UniformLocation location,
+ GLsizei count,
+ const GLint *v)
+{
+ ASSERT(!mLinkingState);
+ if (shouldIgnoreUniform(location))
+ {
+ return;
+ }
+
+ const VariableLocation &locationInfo = mState.mUniformLocations[location.value];
+ GLsizei clampedCount = clampUniformCount(locationInfo, count, 1, v);
+
+ mProgram->setUniform1iv(location.value, clampedCount, v);
+
+ if (mState.isSamplerUniformIndex(locationInfo.index))
+ {
+ updateSamplerUniform(context, locationInfo, clampedCount, v);
+ }
+ else
+ {
+ onStateChange(angle::SubjectMessage::ProgramUniformUpdated);
+ }
+}
+
+void Program::setUniform2iv(UniformLocation location, GLsizei count, const GLint *v)
+{
+ setUniformGeneric<GLint, 2, &rx::ProgramImpl::setUniform2iv>(location, count, v);
+}
+
+void Program::setUniform3iv(UniformLocation location, GLsizei count, const GLint *v)
+{
+ setUniformGeneric<GLint, 3, &rx::ProgramImpl::setUniform3iv>(location, count, v);
+}
+
+void Program::setUniform4iv(UniformLocation location, GLsizei count, const GLint *v)
+{
+ setUniformGeneric<GLint, 4, &rx::ProgramImpl::setUniform4iv>(location, count, v);
+}
+
+void Program::setUniform1uiv(UniformLocation location, GLsizei count, const GLuint *v)
+{
+ setUniformGeneric<GLuint, 1, &rx::ProgramImpl::setUniform1uiv>(location, count, v);
+}
+
+void Program::setUniform2uiv(UniformLocation location, GLsizei count, const GLuint *v)
+{
+ setUniformGeneric<GLuint, 2, &rx::ProgramImpl::setUniform2uiv>(location, count, v);
+}
+
+void Program::setUniform3uiv(UniformLocation location, GLsizei count, const GLuint *v)
+{
+ setUniformGeneric<GLuint, 3, &rx::ProgramImpl::setUniform3uiv>(location, count, v);
+}
+
+void Program::setUniform4uiv(UniformLocation location, GLsizei count, const GLuint *v)
+{
+ setUniformGeneric<GLuint, 4, &rx::ProgramImpl::setUniform4uiv>(location, count, v);
+}
+
+template <
+ typename UniformT,
+ GLint MatrixC,
+ GLint MatrixR,
+ void (rx::ProgramImpl::*SetUniformMatrixFunc)(GLint, GLsizei, GLboolean, const UniformT *)>
+void Program::setUniformMatrixGeneric(UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const UniformT *v)
+{
+ ASSERT(!mLinkingState);
+ if (shouldIgnoreUniform(location))
+ {
+ return;
+ }
+
+ GLsizei clampedCount = clampMatrixUniformCount<MatrixC, MatrixR>(location, count, transpose, v);
+ (mProgram->*SetUniformMatrixFunc)(location.value, clampedCount, transpose, v);
+ onStateChange(angle::SubjectMessage::ProgramUniformUpdated);
+}
+
+void Program::setUniformMatrix2fv(UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *v)
+{
+ setUniformMatrixGeneric<GLfloat, 2, 2, &rx::ProgramImpl::setUniformMatrix2fv>(location, count,
+ transpose, v);
+}
+
+void Program::setUniformMatrix3fv(UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *v)
+{
+ setUniformMatrixGeneric<GLfloat, 3, 3, &rx::ProgramImpl::setUniformMatrix3fv>(location, count,
+ transpose, v);
+}
+
+void Program::setUniformMatrix4fv(UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *v)
+{
+ setUniformMatrixGeneric<GLfloat, 4, 4, &rx::ProgramImpl::setUniformMatrix4fv>(location, count,
+ transpose, v);
+}
+
+void Program::setUniformMatrix2x3fv(UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *v)
+{
+ setUniformMatrixGeneric<GLfloat, 2, 3, &rx::ProgramImpl::setUniformMatrix2x3fv>(location, count,
+ transpose, v);
+}
+
+void Program::setUniformMatrix2x4fv(UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *v)
+{
+ setUniformMatrixGeneric<GLfloat, 2, 4, &rx::ProgramImpl::setUniformMatrix2x4fv>(location, count,
+ transpose, v);
+}
+
+void Program::setUniformMatrix3x2fv(UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *v)
+{
+ setUniformMatrixGeneric<GLfloat, 3, 2, &rx::ProgramImpl::setUniformMatrix3x2fv>(location, count,
+ transpose, v);
+}
+
+void Program::setUniformMatrix3x4fv(UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *v)
+{
+ setUniformMatrixGeneric<GLfloat, 3, 4, &rx::ProgramImpl::setUniformMatrix3x4fv>(location, count,
+ transpose, v);
+}
+
+void Program::setUniformMatrix4x2fv(UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *v)
+{
+ setUniformMatrixGeneric<GLfloat, 4, 2, &rx::ProgramImpl::setUniformMatrix4x2fv>(location, count,
+ transpose, v);
+}
+
+void Program::setUniformMatrix4x3fv(UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *v)
+{
+ setUniformMatrixGeneric<GLfloat, 4, 3, &rx::ProgramImpl::setUniformMatrix4x3fv>(location, count,
+ transpose, v);
+}
+
+GLuint Program::getSamplerUniformBinding(const VariableLocation &uniformLocation) const
+{
+ ASSERT(!mLinkingState);
+ GLuint samplerIndex = mState.getSamplerIndexFromUniformIndex(uniformLocation.index);
+ const std::vector<GLuint> &boundTextureUnits =
+ mState.mExecutable->mSamplerBindings[samplerIndex].boundTextureUnits;
+ return (uniformLocation.arrayIndex < boundTextureUnits.size())
+ ? boundTextureUnits[uniformLocation.arrayIndex]
+ : 0;
+}
+
+GLuint Program::getImageUniformBinding(const VariableLocation &uniformLocation) const
+{
+ ASSERT(!mLinkingState);
+ GLuint imageIndex = mState.getImageIndexFromUniformIndex(uniformLocation.index);
+
+ const std::vector<ImageBinding> &imageBindings = getExecutable().getImageBindings();
+ const std::vector<GLuint> &boundImageUnits = imageBindings[imageIndex].boundImageUnits;
+ return boundImageUnits[uniformLocation.arrayIndex];
+}
+
+void Program::getUniformfv(const Context *context, UniformLocation location, GLfloat *v) const
+{
+ ASSERT(!mLinkingState);
+ const VariableLocation &uniformLocation = mState.getUniformLocations()[location.value];
+ const LinkedUniform &uniform = mState.getUniforms()[uniformLocation.index];
+
+ if (uniform.isSampler())
+ {
+ *v = static_cast<GLfloat>(getSamplerUniformBinding(uniformLocation));
+ return;
+ }
+ else if (uniform.isImage())
+ {
+ *v = static_cast<GLfloat>(getImageUniformBinding(uniformLocation));
+ return;
+ }
+
+ const GLenum nativeType = gl::VariableComponentType(uniform.type);
+ if (nativeType == GL_FLOAT)
+ {
+ mProgram->getUniformfv(context, location.value, v);
+ }
+ else
+ {
+ getUniformInternal(context, v, location, nativeType, VariableComponentCount(uniform.type));
+ }
+}
+
+void Program::getUniformiv(const Context *context, UniformLocation location, GLint *v) const
+{
+ ASSERT(!mLinkingState);
+ const VariableLocation &uniformLocation = mState.getUniformLocations()[location.value];
+ const LinkedUniform &uniform = mState.getUniforms()[uniformLocation.index];
+
+ if (uniform.isSampler())
+ {
+ *v = static_cast<GLint>(getSamplerUniformBinding(uniformLocation));
+ return;
+ }
+ else if (uniform.isImage())
+ {
+ *v = static_cast<GLint>(getImageUniformBinding(uniformLocation));
+ return;
+ }
+
+ const GLenum nativeType = gl::VariableComponentType(uniform.type);
+ if (nativeType == GL_INT || nativeType == GL_BOOL)
+ {
+ mProgram->getUniformiv(context, location.value, v);
+ }
+ else
+ {
+ getUniformInternal(context, v, location, nativeType, VariableComponentCount(uniform.type));
+ }
+}
+
+void Program::getUniformuiv(const Context *context, UniformLocation location, GLuint *v) const
+{
+ ASSERT(!mLinkingState);
+ const VariableLocation &uniformLocation = mState.getUniformLocations()[location.value];
+ const LinkedUniform &uniform = mState.getUniforms()[uniformLocation.index];
+
+ if (uniform.isSampler())
+ {
+ *v = getSamplerUniformBinding(uniformLocation);
+ return;
+ }
+ else if (uniform.isImage())
+ {
+ *v = getImageUniformBinding(uniformLocation);
+ return;
+ }
+
+ const GLenum nativeType = VariableComponentType(uniform.type);
+ if (nativeType == GL_UNSIGNED_INT)
+ {
+ mProgram->getUniformuiv(context, location.value, v);
+ }
+ else
+ {
+ getUniformInternal(context, v, location, nativeType, VariableComponentCount(uniform.type));
+ }
+}
+
+void Program::flagForDeletion()
+{
+ ASSERT(!mLinkingState);
+ mDeleteStatus = true;
+}
+
+bool Program::isFlaggedForDeletion() const
+{
+ ASSERT(!mLinkingState);
+ return mDeleteStatus;
+}
+
+void Program::validate(const Caps &caps)
+{
+ ASSERT(!mLinkingState);
+ mState.mExecutable->resetInfoLog();
+ InfoLog &infoLog = mState.mExecutable->getInfoLog();
+
+ if (mLinked)
+ {
+ mValidated = ConvertToBool(mProgram->validate(caps, &infoLog));
+ }
+ else
+ {
+ infoLog << "Program has not been successfully linked.";
+ }
+}
+
+bool Program::isValidated() const
+{
+ ASSERT(!mLinkingState);
+ return mValidated;
+}
+
+void Program::getActiveUniformBlockName(const Context *context,
+ const UniformBlockIndex blockIndex,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *blockName) const
+{
+ ASSERT(!mLinkingState);
+ GetInterfaceBlockName(blockIndex, mState.mExecutable->getUniformBlocks(), bufSize, length,
+ blockName);
+}
+
+void Program::getActiveShaderStorageBlockName(const GLuint blockIndex,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *blockName) const
+{
+ ASSERT(!mLinkingState);
+ GetInterfaceBlockName({blockIndex}, mState.mExecutable->getShaderStorageBlocks(), bufSize,
+ length, blockName);
+}
+
+template <typename T>
+GLint Program::getActiveInterfaceBlockMaxNameLength(const std::vector<T> &resources) const
+{
+ int maxLength = 0;
+
+ if (mLinked)
+ {
+ for (const T &resource : resources)
+ {
+ if (!resource.name.empty())
+ {
+ int length = static_cast<int>(resource.nameWithArrayIndex().length());
+ maxLength = std::max(length + 1, maxLength);
+ }
+ }
+ }
+
+ return maxLength;
+}
+
+GLint Program::getActiveUniformBlockMaxNameLength() const
+{
+ ASSERT(!mLinkingState);
+ return getActiveInterfaceBlockMaxNameLength(mState.mExecutable->getUniformBlocks());
+}
+
+GLint Program::getActiveShaderStorageBlockMaxNameLength() const
+{
+ ASSERT(!mLinkingState);
+ return getActiveInterfaceBlockMaxNameLength(mState.mExecutable->getShaderStorageBlocks());
+}
+
+GLuint Program::getUniformBlockIndex(const std::string &name) const
+{
+ ASSERT(!mLinkingState);
+ return GetInterfaceBlockIndex(mState.mExecutable->getUniformBlocks(), name);
+}
+
+GLuint Program::getShaderStorageBlockIndex(const std::string &name) const
+{
+ ASSERT(!mLinkingState);
+ return GetInterfaceBlockIndex(mState.mExecutable->getShaderStorageBlocks(), name);
+}
+
+const InterfaceBlock &Program::getUniformBlockByIndex(GLuint index) const
+{
+ ASSERT(!mLinkingState);
+ ASSERT(index < static_cast<GLuint>(mState.mExecutable->getActiveUniformBlockCount()));
+ return mState.mExecutable->getUniformBlocks()[index];
+}
+
+const InterfaceBlock &Program::getShaderStorageBlockByIndex(GLuint index) const
+{
+ ASSERT(!mLinkingState);
+ ASSERT(index < static_cast<GLuint>(mState.mExecutable->getActiveShaderStorageBlockCount()));
+ return mState.mExecutable->getShaderStorageBlocks()[index];
+}
+
+void Program::bindUniformBlock(UniformBlockIndex uniformBlockIndex, GLuint uniformBlockBinding)
+{
+ ASSERT(!mLinkingState);
+ mState.mExecutable->mUniformBlocks[uniformBlockIndex.value].binding = uniformBlockBinding;
+ mState.mExecutable->mActiveUniformBlockBindings.set(uniformBlockIndex.value,
+ uniformBlockBinding != 0);
+ mDirtyBits.set(DIRTY_BIT_UNIFORM_BLOCK_BINDING_0 + uniformBlockIndex.value);
+}
+
+GLuint Program::getUniformBlockBinding(GLuint uniformBlockIndex) const
+{
+ ASSERT(!mLinkingState);
+ return mState.getUniformBlockBinding(uniformBlockIndex);
+}
+
+GLuint Program::getShaderStorageBlockBinding(GLuint shaderStorageBlockIndex) const
+{
+ ASSERT(!mLinkingState);
+ return mState.getShaderStorageBlockBinding(shaderStorageBlockIndex);
+}
+
+void Program::setTransformFeedbackVaryings(GLsizei count,
+ const GLchar *const *varyings,
+ GLenum bufferMode)
+{
+ ASSERT(!mLinkingState);
+ mState.mTransformFeedbackVaryingNames.resize(count);
+ for (GLsizei i = 0; i < count; i++)
+ {
+ mState.mTransformFeedbackVaryingNames[i] = varyings[i];
+ }
+
+ mState.mExecutable->mTransformFeedbackBufferMode = bufferMode;
+}
+
+void Program::getTransformFeedbackVarying(GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLsizei *size,
+ GLenum *type,
+ GLchar *name) const
+{
+ ASSERT(!mLinkingState);
+ if (mLinked)
+ {
+ ASSERT(index < mState.mExecutable->mLinkedTransformFeedbackVaryings.size());
+ const auto &var = mState.mExecutable->mLinkedTransformFeedbackVaryings[index];
+ std::string varName = var.nameWithArrayIndex();
+ GLsizei lastNameIdx = std::min(bufSize - 1, static_cast<GLsizei>(varName.length()));
+ if (length)
+ {
+ *length = lastNameIdx;
+ }
+ if (size)
+ {
+ *size = var.size();
+ }
+ if (type)
+ {
+ *type = var.type;
+ }
+ if (name)
+ {
+ memcpy(name, varName.c_str(), lastNameIdx);
+ name[lastNameIdx] = '\0';
+ }
+ }
+}
+
+GLsizei Program::getTransformFeedbackVaryingCount() const
+{
+ ASSERT(!mLinkingState);
+ if (mLinked)
+ {
+ return static_cast<GLsizei>(mState.mExecutable->mLinkedTransformFeedbackVaryings.size());
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+GLsizei Program::getTransformFeedbackVaryingMaxLength() const
+{
+ ASSERT(!mLinkingState);
+ if (mLinked)
+ {
+ GLsizei maxSize = 0;
+ for (const auto &var : mState.mExecutable->mLinkedTransformFeedbackVaryings)
+ {
+ maxSize =
+ std::max(maxSize, static_cast<GLsizei>(var.nameWithArrayIndex().length() + 1));
+ }
+
+ return maxSize;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+GLenum Program::getTransformFeedbackBufferMode() const
+{
+ ASSERT(!mLinkingState);
+ return mState.mExecutable->getTransformFeedbackBufferMode();
+}
+
+bool Program::linkValidateShaders(const Context *context, InfoLog &infoLog)
+{
+ const ShaderMap<Shader *> &shaders = mState.mAttachedShaders;
+
+ bool isComputeShaderAttached = shaders[ShaderType::Compute] != nullptr;
+ bool isGraphicsShaderAttached = shaders[ShaderType::Vertex] ||
+ shaders[ShaderType::TessControl] ||
+ shaders[ShaderType::TessEvaluation] ||
+ shaders[ShaderType::Geometry] || shaders[ShaderType::Fragment];
+ // 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 && isGraphicsShaderAttached)
+ {
+ infoLog << "Both compute and graphics shaders are attached to the same program.";
+ return false;
+ }
+
+ Optional<int> version;
+ for (ShaderType shaderType : kAllGraphicsShaderTypes)
+ {
+ Shader *shader = shaders[shaderType];
+ ASSERT(!shader || shader->getType() == shaderType);
+ if (!shader)
+ {
+ continue;
+ }
+
+ if (!shader->isCompiled(context))
+ {
+ infoLog << ShaderTypeToString(shaderType) << " shader is not compiled.";
+ return false;
+ }
+
+ if (!version.valid())
+ {
+ version = shader->getShaderVersion(context);
+ }
+ else if (version != shader->getShaderVersion(context))
+ {
+ infoLog << ShaderTypeToString(shaderType)
+ << " shader version does not match other shader versions.";
+ return false;
+ }
+ }
+
+ if (isComputeShaderAttached)
+ {
+ ASSERT(shaders[ShaderType::Compute]->getType() == ShaderType::Compute);
+
+ mState.mComputeShaderLocalSize = shaders[ShaderType::Compute]->getWorkGroupSize(context);
+
+ // 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())
+ {
+ infoLog << "Work group size is not specified.";
+ return false;
+ }
+ }
+ else
+ {
+ if (!isGraphicsShaderAttached)
+ {
+ infoLog << "No compiled shaders.";
+ return false;
+ }
+
+ bool hasVertex = shaders[ShaderType::Vertex] != nullptr;
+ bool hasFragment = shaders[ShaderType::Fragment] != nullptr;
+ if (!isSeparable() && (!hasVertex || !hasFragment))
+ {
+ infoLog
+ << "The program must contain objects to form both a vertex and fragment shader.";
+ return false;
+ }
+
+ bool hasTessControl = shaders[ShaderType::TessControl] != nullptr;
+ bool hasTessEvaluation = shaders[ShaderType::TessEvaluation] != nullptr;
+ if (!isSeparable() && (hasTessControl != hasTessEvaluation))
+ {
+ infoLog << "Tessellation control and evaluation shaders must be specified together.";
+ return false;
+ }
+
+ Shader *geometryShader = shaders[ShaderType::Geometry];
+ if (shaders[ShaderType::Geometry])
+ {
+ // [GL_EXT_geometry_shader] Chapter 7
+ // Linking can fail for a variety of reasons as specified in the OpenGL ES Shading
+ // Language Specification, as well as any of the following reasons:
+ // * One or more of the shader objects attached to <program> are not compiled
+ // successfully.
+ // * The shaders do not use the same shader language version.
+ // * <program> contains objects to form a geometry shader, and
+ // - <program> is not separable and contains no objects to form a vertex shader; or
+ // - the input primitive type, output primitive type, or maximum output vertex count
+ // is not specified in the compiled geometry shader object.
+ ASSERT(geometryShader->getType() == ShaderType::Geometry);
+
+ Optional<PrimitiveMode> inputPrimitive =
+ geometryShader->getGeometryShaderInputPrimitiveType(context);
+ if (!inputPrimitive.valid())
+ {
+ infoLog << "Input primitive type is not specified in the geometry shader.";
+ return false;
+ }
+
+ Optional<PrimitiveMode> outputPrimitive =
+ geometryShader->getGeometryShaderOutputPrimitiveType(context);
+ if (!outputPrimitive.valid())
+ {
+ infoLog << "Output primitive type is not specified in the geometry shader.";
+ return false;
+ }
+
+ Optional<GLint> maxVertices = geometryShader->getGeometryShaderMaxVertices(context);
+ if (!maxVertices.valid())
+ {
+ infoLog << "'max_vertices' is not specified in the geometry shader.";
+ return false;
+ }
+
+ mState.mExecutable->mGeometryShaderInputPrimitiveType = inputPrimitive.value();
+ mState.mExecutable->mGeometryShaderOutputPrimitiveType = outputPrimitive.value();
+ mState.mExecutable->mGeometryShaderMaxVertices = maxVertices.value();
+ mState.mExecutable->mGeometryShaderInvocations =
+ geometryShader->getGeometryShaderInvocations(context);
+ }
+
+ Shader *tessControlShader = shaders[ShaderType::TessControl];
+ if (tessControlShader)
+ {
+ int tcsShaderVertices = tessControlShader->getTessControlShaderVertices(context);
+ if (tcsShaderVertices == 0)
+ {
+ // In tessellation control shader, output vertices should be specified at least
+ // once.
+ // > GLSL ES Version 3.20.6 spec:
+ // > 4.4.2. Output Layout Qualifiers
+ // > Tessellation Control Outputs
+ // > ...
+ // > There must be at least one layout qualifier specifying an output patch vertex
+ // > count in any program containing a tessellation control shader.
+ infoLog << "In Tessellation Control Shader, at least one layout qualifier "
+ "specifying an output patch vertex count must exist.";
+ return false;
+ }
+
+ mState.mExecutable->mTessControlShaderVertices = tcsShaderVertices;
+ }
+
+ Shader *tessEvaluationShader = shaders[ShaderType::TessEvaluation];
+ if (tessEvaluationShader)
+ {
+ GLenum tesPrimitiveMode = tessEvaluationShader->getTessGenMode(context);
+ if (tesPrimitiveMode == 0)
+ {
+ // In tessellation evaluation shader, a primitive mode should be specified at least
+ // once.
+ // > GLSL ES Version 3.20.6 spec:
+ // > 4.4.1. Input Layout Qualifiers
+ // > Tessellation Evaluation Inputs
+ // > ...
+ // > The tessellation evaluation shader object in a program must declare a primitive
+ // > mode in its input layout. Declaring vertex spacing, ordering, or point mode
+ // > identifiers is optional.
+ infoLog << "The Tessellation Evaluation Shader object in a program must declare a "
+ "primitive mode in its input layout.";
+ return false;
+ }
+
+ mState.mExecutable->mTessGenMode = tesPrimitiveMode;
+ mState.mExecutable->mTessGenSpacing = tessEvaluationShader->getTessGenSpacing(context);
+ mState.mExecutable->mTessGenVertexOrder =
+ tessEvaluationShader->getTessGenVertexOrder(context);
+ mState.mExecutable->mTessGenPointMode =
+ tessEvaluationShader->getTessGenPointMode(context);
+ }
+ }
+
+ return true;
+}
+
+GLuint Program::getTransformFeedbackVaryingResourceIndex(const GLchar *name) const
+{
+ ASSERT(!mLinkingState);
+ for (GLuint tfIndex = 0; tfIndex < mState.mExecutable->mLinkedTransformFeedbackVaryings.size();
+ ++tfIndex)
+ {
+ const auto &tf = mState.mExecutable->mLinkedTransformFeedbackVaryings[tfIndex];
+ if (tf.nameWithArrayIndex() == name)
+ {
+ return tfIndex;
+ }
+ }
+ return GL_INVALID_INDEX;
+}
+
+const TransformFeedbackVarying &Program::getTransformFeedbackVaryingResource(GLuint index) const
+{
+ ASSERT(!mLinkingState);
+ ASSERT(index < mState.mExecutable->mLinkedTransformFeedbackVaryings.size());
+ return mState.mExecutable->mLinkedTransformFeedbackVaryings[index];
+}
+
+bool Program::hasDrawIDUniform() const
+{
+ ASSERT(!mLinkingState);
+ return mState.mDrawIDLocation >= 0;
+}
+
+void Program::setDrawIDUniform(GLint drawid)
+{
+ ASSERT(!mLinkingState);
+ ASSERT(mState.mDrawIDLocation >= 0);
+ mProgram->setUniform1iv(mState.mDrawIDLocation, 1, &drawid);
+}
+
+bool Program::hasBaseVertexUniform() const
+{
+ ASSERT(!mLinkingState);
+ return mState.mBaseVertexLocation >= 0;
+}
+
+void Program::setBaseVertexUniform(GLint baseVertex)
+{
+ ASSERT(!mLinkingState);
+ ASSERT(mState.mBaseVertexLocation >= 0);
+ if (baseVertex == mState.mCachedBaseVertex)
+ {
+ return;
+ }
+ mState.mCachedBaseVertex = baseVertex;
+ mProgram->setUniform1iv(mState.mBaseVertexLocation, 1, &baseVertex);
+}
+
+bool Program::hasBaseInstanceUniform() const
+{
+ ASSERT(!mLinkingState);
+ return mState.mBaseInstanceLocation >= 0;
+}
+
+void Program::setBaseInstanceUniform(GLuint baseInstance)
+{
+ ASSERT(!mLinkingState);
+ ASSERT(mState.mBaseInstanceLocation >= 0);
+ if (baseInstance == mState.mCachedBaseInstance)
+ {
+ return;
+ }
+ mState.mCachedBaseInstance = baseInstance;
+ GLint baseInstanceInt = baseInstance;
+ mProgram->setUniform1iv(mState.mBaseInstanceLocation, 1, &baseInstanceInt);
+}
+
+bool Program::linkVaryings(const Context *context, InfoLog &infoLog) const
+{
+ ShaderType previousShaderType = ShaderType::InvalidEnum;
+ for (ShaderType shaderType : kAllGraphicsShaderTypes)
+ {
+ Shader *currentShader = mState.mAttachedShaders[shaderType];
+ if (!currentShader)
+ {
+ continue;
+ }
+
+ if (previousShaderType != ShaderType::InvalidEnum)
+ {
+ Shader *previousShader = mState.mAttachedShaders[previousShaderType];
+ const std::vector<sh::ShaderVariable> &outputVaryings =
+ previousShader->getOutputVaryings(context);
+
+ if (!LinkValidateShaderInterfaceMatching(
+ outputVaryings, currentShader->getInputVaryings(context), previousShaderType,
+ currentShader->getType(), previousShader->getShaderVersion(context),
+ currentShader->getShaderVersion(context), isSeparable(), infoLog))
+ {
+ return false;
+ }
+ }
+ previousShaderType = currentShader->getType();
+ }
+
+ // TODO: http://anglebug.com/3571 and http://anglebug.com/3572
+ // Need to move logic of validating builtin varyings inside the for-loop above.
+ // This is because the built-in symbols `gl_ClipDistance` and `gl_CullDistance`
+ // can be redeclared in Geometry or Tessellation shaders as well.
+ Shader *vertexShader = mState.mAttachedShaders[ShaderType::Vertex];
+ Shader *fragmentShader = mState.mAttachedShaders[ShaderType::Fragment];
+ if (vertexShader && fragmentShader &&
+ !LinkValidateBuiltInVaryings(vertexShader->getOutputVaryings(context),
+ fragmentShader->getInputVaryings(context),
+ vertexShader->getType(), fragmentShader->getType(),
+ vertexShader->getShaderVersion(context),
+ fragmentShader->getShaderVersion(context), infoLog))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool Program::linkUniforms(const Context *context,
+ std::vector<UnusedUniform> *unusedUniformsOutOrNull,
+ GLuint *combinedImageUniformsOut,
+ InfoLog &infoLog)
+{
+ // Initialize executable shader map.
+ ShaderMap<std::vector<sh::ShaderVariable>> shaderUniforms;
+ for (Shader *shader : mState.mAttachedShaders)
+ {
+ if (shader)
+ {
+ shaderUniforms[shader->getType()] = shader->getUniforms(context);
+ }
+ }
+
+ if (!mState.mExecutable->linkUniforms(context, shaderUniforms, infoLog,
+ mState.mUniformLocationBindings, combinedImageUniformsOut,
+ unusedUniformsOutOrNull, &mState.mUniformLocations))
+ {
+ return false;
+ }
+
+ if (context->getClientVersion() >= Version(3, 1))
+ {
+ GLint locationSize = static_cast<GLint>(mState.getUniformLocations().size());
+
+ if (locationSize > context->getCaps().maxUniformLocations)
+ {
+ infoLog << "Exceeded maximum uniform location size";
+ return false;
+ }
+ }
+
+ return true;
+}
+
+// Assigns locations to all attributes (except built-ins) from the bindings and program locations.
+bool Program::linkAttributes(const Context *context, InfoLog &infoLog)
+{
+ const Caps &caps = context->getCaps();
+ const Limitations &limitations = context->getLimitations();
+ bool webglCompatibility = context->isWebGL();
+ int shaderVersion = -1;
+ unsigned int usedLocations = 0;
+
+ Shader *vertexShader = mState.getAttachedShader(gl::ShaderType::Vertex);
+
+ if (!vertexShader)
+ {
+ // No vertex shader, so no attributes, so nothing to do
+ return true;
+ }
+
+ shaderVersion = vertexShader->getShaderVersion(context);
+ if (shaderVersion >= 300)
+ {
+ // In GLSL ES 3.00.6, aliasing checks should be done with all declared attributes -
+ // see GLSL ES 3.00.6 section 12.46. Inactive attributes will be pruned after
+ // aliasing checks.
+ mState.mExecutable->mProgramInputs = vertexShader->getAllAttributes(context);
+ }
+ else
+ {
+ // In GLSL ES 1.00.17 we only do aliasing checks for active attributes.
+ mState.mExecutable->mProgramInputs = vertexShader->getActiveAttributes(context);
+ }
+
+ GLuint maxAttribs = static_cast<GLuint>(caps.maxVertexAttributes);
+ std::vector<sh::ShaderVariable *> usedAttribMap(maxAttribs, nullptr);
+
+ // Assign locations to attributes that have a binding location and check for attribute aliasing.
+ for (sh::ShaderVariable &attribute : mState.mExecutable->mProgramInputs)
+ {
+ // GLSL ES 3.10 January 2016 section 4.3.4: Vertex shader inputs can't be arrays or
+ // structures, so we don't need to worry about adjusting their names or generating entries
+ // for each member/element (unlike uniforms for example).
+ ASSERT(!attribute.isArray() && !attribute.isStruct());
+
+ int bindingLocation = mAttributeBindings.getBinding(attribute);
+ if (attribute.location == -1 && bindingLocation != -1)
+ {
+ attribute.location = bindingLocation;
+ }
+
+ if (attribute.location != -1)
+ {
+ // Location is set by glBindAttribLocation or by location layout qualifier
+ const int regs = VariableRegisterCount(attribute.type);
+
+ if (static_cast<GLuint>(regs + attribute.location) > maxAttribs)
+ {
+ infoLog << "Attribute (" << attribute.name << ") at location " << attribute.location
+ << " is too big to fit";
+
+ return false;
+ }
+
+ for (int reg = 0; reg < regs; reg++)
+ {
+ const int regLocation = attribute.location + reg;
+ sh::ShaderVariable *linkedAttribute = usedAttribMap[regLocation];
+
+ // In GLSL ES 3.00.6 and in WebGL, attribute aliasing produces a link error.
+ // In non-WebGL GLSL ES 1.00.17, attribute aliasing is allowed with some
+ // restrictions - see GLSL ES 1.00.17 section 2.10.4, but ANGLE currently has a bug.
+ // In D3D 9 and 11, aliasing is not supported, so check a limitation.
+ if (linkedAttribute)
+ {
+ if (shaderVersion >= 300 || webglCompatibility ||
+ limitations.noVertexAttributeAliasing)
+ {
+ infoLog << "Attribute '" << attribute.name << "' aliases attribute '"
+ << linkedAttribute->name << "' at location " << regLocation;
+ return false;
+ }
+ }
+ else
+ {
+ usedAttribMap[regLocation] = &attribute;
+ }
+
+ usedLocations |= 1 << regLocation;
+ }
+ }
+ }
+
+ // Assign locations to attributes that don't have a binding location.
+ for (sh::ShaderVariable &attribute : mState.mExecutable->mProgramInputs)
+ {
+ // Not set by glBindAttribLocation or by location layout qualifier
+ if (attribute.location == -1)
+ {
+ int regs = VariableRegisterCount(attribute.type);
+ int availableIndex = AllocateFirstFreeBits(&usedLocations, regs, maxAttribs);
+
+ if (availableIndex == -1 || static_cast<GLuint>(availableIndex + regs) > maxAttribs)
+ {
+ infoLog << "Too many attributes (" << attribute.name << ")";
+ return false;
+ }
+
+ attribute.location = availableIndex;
+ }
+ }
+
+ ASSERT(mState.mExecutable->mAttributesTypeMask.none());
+ ASSERT(mState.mExecutable->mAttributesMask.none());
+
+ // Prune inactive attributes. This step is only needed on shaderVersion >= 300 since on earlier
+ // shader versions we're only processing active attributes to begin with.
+ if (shaderVersion >= 300)
+ {
+ for (auto attributeIter = mState.mExecutable->getProgramInputs().begin();
+ attributeIter != mState.mExecutable->getProgramInputs().end();)
+ {
+ if (attributeIter->active)
+ {
+ ++attributeIter;
+ }
+ else
+ {
+ attributeIter = mState.mExecutable->mProgramInputs.erase(attributeIter);
+ }
+ }
+ }
+
+ for (const sh::ShaderVariable &attribute : mState.mExecutable->getProgramInputs())
+ {
+ ASSERT(attribute.active);
+ ASSERT(attribute.location != -1);
+ unsigned int regs = static_cast<unsigned int>(VariableRegisterCount(attribute.type));
+
+ unsigned int location = static_cast<unsigned int>(attribute.location);
+ for (unsigned int r = 0; r < regs; r++)
+ {
+ // Built-in active program inputs don't have a bound attribute.
+ if (!attribute.isBuiltIn())
+ {
+ mState.mExecutable->mActiveAttribLocationsMask.set(location);
+ mState.mExecutable->mMaxActiveAttribLocation =
+ std::max(mState.mExecutable->mMaxActiveAttribLocation, location + 1);
+
+ ComponentType componentType =
+ GLenumToComponentType(VariableComponentType(attribute.type));
+
+ SetComponentTypeMask(componentType, location,
+ &mState.mExecutable->mAttributesTypeMask);
+ mState.mExecutable->mAttributesMask.set(location);
+
+ location++;
+ }
+ }
+ }
+
+ return true;
+}
+
+void Program::setUniformValuesFromBindingQualifiers()
+{
+ for (unsigned int samplerIndex : mState.mExecutable->getSamplerUniformRange())
+ {
+ const auto &samplerUniform = mState.mExecutable->getUniforms()[samplerIndex];
+ if (samplerUniform.binding != -1)
+ {
+ UniformLocation location = getUniformLocation(samplerUniform.name);
+ ASSERT(location.value != -1);
+ std::vector<GLint> boundTextureUnits;
+ for (unsigned int elementIndex = 0;
+ elementIndex < samplerUniform.getBasicTypeElementCount(); ++elementIndex)
+ {
+ boundTextureUnits.push_back(samplerUniform.binding + elementIndex);
+ }
+
+ // Here we pass nullptr to avoid a large chain of calls that need a non-const Context.
+ // We know it's safe not to notify the Context because this is only called after link.
+ setUniform1iv(nullptr, location, static_cast<GLsizei>(boundTextureUnits.size()),
+ boundTextureUnits.data());
+ }
+ }
+}
+
+void Program::initInterfaceBlockBindings()
+{
+ // Set initial bindings from shader.
+ for (unsigned int blockIndex = 0; blockIndex < mState.mExecutable->getActiveUniformBlockCount();
+ blockIndex++)
+ {
+ InterfaceBlock &uniformBlock = mState.mExecutable->mUniformBlocks[blockIndex];
+ bindUniformBlock({blockIndex}, uniformBlock.binding);
+ }
+}
+
+void Program::updateSamplerUniform(Context *context,
+ const VariableLocation &locationInfo,
+ GLsizei clampedCount,
+ const GLint *v)
+{
+ ASSERT(mState.isSamplerUniformIndex(locationInfo.index));
+ GLuint samplerIndex = mState.getSamplerIndexFromUniformIndex(locationInfo.index);
+ SamplerBinding &samplerBinding = mState.mExecutable->mSamplerBindings[samplerIndex];
+ std::vector<GLuint> &boundTextureUnits = samplerBinding.boundTextureUnits;
+
+ if (locationInfo.arrayIndex >= boundTextureUnits.size())
+ {
+ return;
+ }
+ GLsizei safeUniformCount = std::min(
+ clampedCount, static_cast<GLsizei>(boundTextureUnits.size() - locationInfo.arrayIndex));
+
+ // Update the sampler uniforms.
+ for (GLsizei arrayIndex = 0; arrayIndex < safeUniformCount; ++arrayIndex)
+ {
+ GLint oldTextureUnit = boundTextureUnits[arrayIndex + locationInfo.arrayIndex];
+ GLint newTextureUnit = v[arrayIndex];
+
+ if (oldTextureUnit == newTextureUnit)
+ {
+ continue;
+ }
+
+ // Update sampler's bound textureUnit
+ boundTextureUnits[arrayIndex + locationInfo.arrayIndex] = newTextureUnit;
+
+ // Update the reference counts.
+ uint32_t &oldRefCount = mState.mExecutable->mActiveSamplerRefCounts[oldTextureUnit];
+ uint32_t &newRefCount = mState.mExecutable->mActiveSamplerRefCounts[newTextureUnit];
+ ASSERT(oldRefCount > 0);
+ ASSERT(newRefCount < std::numeric_limits<uint32_t>::max());
+ oldRefCount--;
+ newRefCount++;
+
+ // Check for binding type change.
+ TextureType newSamplerType = mState.mExecutable->mActiveSamplerTypes[newTextureUnit];
+ TextureType oldSamplerType = mState.mExecutable->mActiveSamplerTypes[oldTextureUnit];
+ SamplerFormat newSamplerFormat = mState.mExecutable->mActiveSamplerFormats[newTextureUnit];
+ SamplerFormat oldSamplerFormat = mState.mExecutable->mActiveSamplerFormats[oldTextureUnit];
+ bool newSamplerYUV = mState.mExecutable->mActiveSamplerYUV.test(newTextureUnit);
+
+ if (newRefCount == 1)
+ {
+ mState.mExecutable->setActive(newTextureUnit, samplerBinding,
+ mState.mExecutable->getUniforms()[locationInfo.index]);
+ }
+ else
+ {
+ if (newSamplerType != samplerBinding.textureType ||
+ newSamplerYUV != IsSamplerYUVType(samplerBinding.samplerType))
+ {
+ mState.mExecutable->hasSamplerTypeConflict(newTextureUnit);
+ }
+
+ if (newSamplerFormat != samplerBinding.format)
+ {
+ mState.mExecutable->hasSamplerFormatConflict(newTextureUnit);
+ }
+ }
+
+ // Unset previously active sampler.
+ if (oldRefCount == 0)
+ {
+ mState.mExecutable->setInactive(oldTextureUnit);
+ }
+ else
+ {
+ if (oldSamplerType == TextureType::InvalidEnum ||
+ oldSamplerFormat == SamplerFormat::InvalidEnum)
+ {
+ // Previous conflict. Check if this new change fixed the conflict.
+ mState.setSamplerUniformTextureTypeAndFormat(oldTextureUnit);
+ }
+ }
+
+ // Update the observing PPO's executable, if any.
+ // Do this before any of the Context work, since that uses the current ProgramExecutable,
+ // which will be the PPO's if this Program is bound to it, rather than this Program's.
+ if (isSeparable())
+ {
+ onStateChange(angle::SubjectMessage::ProgramTextureOrImageBindingChanged);
+ }
+
+ // Notify context.
+ if (context)
+ {
+ context->onSamplerUniformChange(newTextureUnit);
+ context->onSamplerUniformChange(oldTextureUnit);
+ }
+ }
+
+ // Invalidate the validation cache.
+ getExecutable().resetCachedValidateSamplersResult();
+ // Inform any PPOs this Program may be bound to.
+ onStateChange(angle::SubjectMessage::SamplerUniformsUpdated);
+}
+
+void ProgramState::setSamplerUniformTextureTypeAndFormat(size_t textureUnitIndex)
+{
+ mExecutable->setSamplerUniformTextureTypeAndFormat(textureUnitIndex,
+ mExecutable->mSamplerBindings);
+}
+
+template <typename T>
+GLsizei Program::clampUniformCount(const VariableLocation &locationInfo,
+ GLsizei count,
+ int vectorSize,
+ const T *v)
+{
+ if (count == 1)
+ return 1;
+
+ const LinkedUniform &linkedUniform = mState.mExecutable->getUniforms()[locationInfo.index];
+
+ // OpenGL ES 3.0.4 spec pg 67: "Values for any array element that exceeds the highest array
+ // element index used, as reported by GetActiveUniform, will be ignored by the GL."
+ unsigned int remainingElements =
+ linkedUniform.getBasicTypeElementCount() - locationInfo.arrayIndex;
+ GLsizei maxElementCount =
+ static_cast<GLsizei>(remainingElements * linkedUniform.getElementComponents());
+
+ if (count * vectorSize > maxElementCount)
+ {
+ return maxElementCount / vectorSize;
+ }
+
+ return count;
+}
+
+template <size_t cols, size_t rows, typename T>
+GLsizei Program::clampMatrixUniformCount(UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const T *v)
+{
+ const VariableLocation &locationInfo = mState.mUniformLocations[location.value];
+
+ if (!transpose)
+ {
+ return clampUniformCount(locationInfo, count, cols * rows, v);
+ }
+
+ const LinkedUniform &linkedUniform = mState.mExecutable->getUniforms()[locationInfo.index];
+
+ // OpenGL ES 3.0.4 spec pg 67: "Values for any array element that exceeds the highest array
+ // element index used, as reported by GetActiveUniform, will be ignored by the GL."
+ unsigned int remainingElements =
+ linkedUniform.getBasicTypeElementCount() - locationInfo.arrayIndex;
+ return std::min(count, static_cast<GLsizei>(remainingElements));
+}
+
+// Driver differences mean that doing the uniform value cast ourselves gives consistent results.
+// EG: on NVIDIA drivers, it was observed that getUniformi for MAX_INT+1 returned MIN_INT.
+template <typename DestT>
+void Program::getUniformInternal(const Context *context,
+ DestT *dataOut,
+ UniformLocation location,
+ GLenum nativeType,
+ int components) const
+{
+ switch (nativeType)
+ {
+ case GL_BOOL:
+ {
+ GLint tempValue[16] = {0};
+ mProgram->getUniformiv(context, location.value, tempValue);
+ UniformStateQueryCastLoop<GLboolean>(
+ dataOut, reinterpret_cast<const uint8_t *>(tempValue), components);
+ break;
+ }
+ case GL_INT:
+ {
+ GLint tempValue[16] = {0};
+ mProgram->getUniformiv(context, location.value, tempValue);
+ UniformStateQueryCastLoop<GLint>(dataOut, reinterpret_cast<const uint8_t *>(tempValue),
+ components);
+ break;
+ }
+ case GL_UNSIGNED_INT:
+ {
+ GLuint tempValue[16] = {0};
+ mProgram->getUniformuiv(context, location.value, tempValue);
+ UniformStateQueryCastLoop<GLuint>(dataOut, reinterpret_cast<const uint8_t *>(tempValue),
+ components);
+ break;
+ }
+ case GL_FLOAT:
+ {
+ GLfloat tempValue[16] = {0};
+ mProgram->getUniformfv(context, location.value, tempValue);
+ UniformStateQueryCastLoop<GLfloat>(
+ dataOut, reinterpret_cast<const uint8_t *>(tempValue), components);
+ break;
+ }
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+angle::Result Program::syncState(const Context *context)
+{
+ if (mDirtyBits.any())
+ {
+ ASSERT(!mLinkingState);
+ ANGLE_TRY(mProgram->syncState(context, mDirtyBits));
+ mDirtyBits.reset();
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result Program::serialize(const Context *context, angle::MemoryBuffer *binaryOut) const
+{
+ BinaryOutputStream stream;
+
+ stream.writeBytes(reinterpret_cast<const unsigned char *>(angle::GetANGLECommitHash()),
+ angle::GetANGLECommitHashSize());
+
+ // nullptr context is supported when computing binary length.
+ if (context)
+ {
+ stream.writeInt(context->getClientVersion().major);
+ stream.writeInt(context->getClientVersion().minor);
+ }
+ else
+ {
+ stream.writeInt(2);
+ stream.writeInt(0);
+ }
+
+ // Must be before mExecutable->save(), since it uses the value.
+ stream.writeBool(mState.mSeparable);
+
+ mState.mExecutable->save(mState.mSeparable, &stream);
+
+ const auto &computeLocalSize = mState.getComputeShaderLocalSize();
+
+ stream.writeInt(computeLocalSize[0]);
+ stream.writeInt(computeLocalSize[1]);
+ stream.writeInt(computeLocalSize[2]);
+
+ stream.writeInt(mState.mNumViews);
+ stream.writeInt(mState.mSpecConstUsageBits.bits());
+
+ stream.writeInt(mState.getUniformLocations().size());
+ for (const auto &variable : mState.getUniformLocations())
+ {
+ stream.writeInt(variable.arrayIndex);
+ stream.writeIntOrNegOne(variable.index);
+ stream.writeBool(variable.ignored);
+ }
+
+ stream.writeInt(mState.getBufferVariables().size());
+ for (const BufferVariable &bufferVariable : mState.getBufferVariables())
+ {
+ WriteBufferVariable(&stream, bufferVariable);
+ }
+
+ // Warn the app layer if saving a binary with unsupported transform feedback.
+ if (!mState.getLinkedTransformFeedbackVaryings().empty() &&
+ context->getFrontendFeatures().disableProgramCachingForTransformFeedback.enabled)
+ {
+ ANGLE_PERF_WARNING(context->getState().getDebug(), GL_DEBUG_SEVERITY_LOW,
+ "Saving program binary with transform feedback, which is not supported "
+ "on this driver.");
+ }
+
+ if (context->getShareGroup()->getFrameCaptureShared()->enabled())
+ {
+ // Serialize the source for each stage for re-use during capture
+ for (ShaderType shaderType : mState.mExecutable->getLinkedShaderStages())
+ {
+ gl::Shader *shader = getAttachedShader(shaderType);
+ if (shader)
+ {
+ stream.writeString(shader->getSourceString());
+ }
+ else
+ {
+ // If we don't have an attached shader, which would occur if this program was
+ // created via glProgramBinary, pull from our cached copy
+ const angle::ProgramSources &cachedLinkedSources =
+ context->getShareGroup()->getFrameCaptureShared()->getProgramSources(id());
+ const std::string &cachedSourceString = cachedLinkedSources[shaderType];
+ ASSERT(!cachedSourceString.empty());
+ stream.writeString(cachedSourceString.c_str());
+ }
+ }
+ }
+
+ mProgram->save(context, &stream);
+
+ ASSERT(binaryOut);
+ if (!binaryOut->resize(stream.length()))
+ {
+ std::stringstream sstream;
+ sstream << "Failed to allocate enough memory to serialize a program. (" << stream.length()
+ << " bytes )";
+ ANGLE_PERF_WARNING(context->getState().getDebug(), GL_DEBUG_SEVERITY_LOW,
+ sstream.str().c_str());
+ return angle::Result::Incomplete;
+ }
+ memcpy(binaryOut->data(), stream.data(), stream.length());
+ return angle::Result::Continue;
+}
+
+angle::Result Program::deserialize(const Context *context,
+ BinaryInputStream &stream,
+ InfoLog &infoLog)
+{
+ std::vector<uint8_t> commitString(angle::GetANGLECommitHashSize(), 0);
+ stream.readBytes(commitString.data(), commitString.size());
+ if (memcmp(commitString.data(), angle::GetANGLECommitHash(), commitString.size()) != 0)
+ {
+ infoLog << "Invalid program binary version.";
+ return angle::Result::Stop;
+ }
+
+ int majorVersion = stream.readInt<int>();
+ int minorVersion = stream.readInt<int>();
+ if (majorVersion != context->getClientMajorVersion() ||
+ minorVersion != context->getClientMinorVersion())
+ {
+ infoLog << "Cannot load program binaries across different ES context versions.";
+ return angle::Result::Stop;
+ }
+
+ // Must be before mExecutable->load(), since it uses the value.
+ mState.mSeparable = stream.readBool();
+
+ mState.mExecutable->load(mState.mSeparable, &stream);
+
+ mState.mComputeShaderLocalSize[0] = stream.readInt<int>();
+ mState.mComputeShaderLocalSize[1] = stream.readInt<int>();
+ mState.mComputeShaderLocalSize[2] = stream.readInt<int>();
+
+ mState.mNumViews = stream.readInt<int>();
+
+ static_assert(sizeof(mState.mSpecConstUsageBits.bits()) == sizeof(uint32_t));
+ mState.mSpecConstUsageBits = rx::SpecConstUsageBits(stream.readInt<uint32_t>());
+
+ const size_t uniformIndexCount = stream.readInt<size_t>();
+ ASSERT(mState.mUniformLocations.empty());
+ for (size_t uniformIndexIndex = 0; uniformIndexIndex < uniformIndexCount; ++uniformIndexIndex)
+ {
+ VariableLocation variable;
+ stream.readInt(&variable.arrayIndex);
+ stream.readInt(&variable.index);
+ stream.readBool(&variable.ignored);
+
+ mState.mUniformLocations.push_back(variable);
+ }
+
+ size_t bufferVariableCount = stream.readInt<size_t>();
+ ASSERT(mState.mBufferVariables.empty());
+ for (size_t bufferVarIndex = 0; bufferVarIndex < bufferVariableCount; ++bufferVarIndex)
+ {
+ BufferVariable bufferVariable;
+ LoadBufferVariable(&stream, &bufferVariable);
+ mState.mBufferVariables.push_back(bufferVariable);
+ }
+
+ static_assert(static_cast<unsigned long>(ShaderType::EnumCount) <= sizeof(unsigned long) * 8,
+ "Too many shader types");
+
+ // Reject programs that use transform feedback varyings if the hardware cannot support them.
+ if (mState.mExecutable->getLinkedTransformFeedbackVaryings().size() > 0 &&
+ context->getFrontendFeatures().disableProgramCachingForTransformFeedback.enabled)
+ {
+ infoLog << "Current driver does not support transform feedback in binary programs.";
+ return angle::Result::Stop;
+ }
+
+ if (!mState.mAttachedShaders[ShaderType::Compute])
+ {
+ mState.mExecutable->updateTransformFeedbackStrides();
+ }
+
+ postResolveLink(context);
+ mState.mExecutable->updateCanDrawWith();
+
+ if (context->getShareGroup()->getFrameCaptureShared()->enabled())
+ {
+ // Extract the source for each stage from the program binary
+ angle::ProgramSources sources;
+
+ for (ShaderType shaderType : mState.mExecutable->getLinkedShaderStages())
+ {
+ std::string shaderSource = stream.readString();
+ ASSERT(shaderSource.length() > 0);
+ sources[shaderType] = std::move(shaderSource);
+ }
+
+ // Store it for use during mid-execution capture
+ context->getShareGroup()->getFrameCaptureShared()->setProgramSources(id(),
+ std::move(sources));
+ }
+
+ return angle::Result::Continue;
+}
+
+void Program::postResolveLink(const gl::Context *context)
+{
+ mState.updateActiveSamplers();
+ mState.mExecutable->mActiveImageShaderBits.fill({});
+ mState.mExecutable->updateActiveImages(getExecutable());
+
+ setUniformValuesFromBindingQualifiers();
+
+ if (context->getExtensions().multiDrawANGLE)
+ {
+ mState.mDrawIDLocation = getUniformLocation("gl_DrawID").value;
+ }
+
+ if (context->getExtensions().baseVertexBaseInstanceShaderBuiltinANGLE)
+ {
+ mState.mBaseVertexLocation = getUniformLocation("gl_BaseVertex").value;
+ mState.mBaseInstanceLocation = getUniformLocation("gl_BaseInstance").value;
+ }
+}
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/Program.h b/gfx/angle/checkout/src/libANGLE/Program.h
new file mode 100644
index 0000000000..0b7b62480b
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Program.h
@@ -0,0 +1,897 @@
+//
+// Copyright 2002 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.
+//
+
+// Program.h: Defines the gl::Program class. Implements GL program objects
+// and related functionality. [OpenGL ES 2.0.24] section 2.10.3 page 28.
+
+#ifndef LIBANGLE_PROGRAM_H_
+#define LIBANGLE_PROGRAM_H_
+
+#include <GLES2/gl2.h>
+#include <GLSLANG/ShaderVars.h>
+
+#include <array>
+#include <map>
+#include <set>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include "common/Optional.h"
+#include "common/angleutils.h"
+#include "common/mathutil.h"
+#include "common/utilities.h"
+
+#include "libANGLE/Constants.h"
+#include "libANGLE/Debug.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/InfoLog.h"
+#include "libANGLE/ProgramExecutable.h"
+#include "libANGLE/ProgramLinkedResources.h"
+#include "libANGLE/RefCountObject.h"
+#include "libANGLE/Uniform.h"
+#include "libANGLE/angletypes.h"
+
+namespace rx
+{
+class GLImplFactory;
+class ProgramImpl;
+struct TranslatedAttribute;
+} // namespace rx
+
+namespace gl
+{
+class Buffer;
+class BinaryInputStream;
+class BinaryOutputStream;
+struct Caps;
+class Context;
+struct Extensions;
+class Framebuffer;
+class ProgramExecutable;
+class Shader;
+class ShaderProgramManager;
+class State;
+struct UnusedUniform;
+struct Version;
+
+extern const char *const g_fakepath;
+
+enum class LinkMismatchError
+{
+ // Shared
+ NO_MISMATCH,
+ TYPE_MISMATCH,
+ ARRAYNESS_MISMATCH,
+ ARRAY_SIZE_MISMATCH,
+ PRECISION_MISMATCH,
+ STRUCT_NAME_MISMATCH,
+ FIELD_NUMBER_MISMATCH,
+ FIELD_NAME_MISMATCH,
+
+ // Varying specific
+ INTERPOLATION_TYPE_MISMATCH,
+ INVARIANCE_MISMATCH,
+
+ // Uniform specific
+ BINDING_MISMATCH,
+ LOCATION_MISMATCH,
+ OFFSET_MISMATCH,
+ INSTANCE_NAME_MISMATCH,
+ FORMAT_MISMATCH,
+
+ // Interface block specific
+ LAYOUT_QUALIFIER_MISMATCH,
+ MATRIX_PACKING_MISMATCH,
+
+ // I/O block specific
+ FIELD_LOCATION_MISMATCH,
+ FIELD_STRUCT_NAME_MISMATCH,
+};
+
+void LogLinkMismatch(InfoLog &infoLog,
+ const std::string &variableName,
+ const char *variableType,
+ LinkMismatchError linkError,
+ const std::string &mismatchedStructOrBlockFieldName,
+ ShaderType shaderType1,
+ ShaderType shaderType2);
+
+bool IsActiveInterfaceBlock(const sh::InterfaceBlock &interfaceBlock);
+
+void WriteBlockMemberInfo(BinaryOutputStream *stream, const sh::BlockMemberInfo &var);
+void LoadBlockMemberInfo(BinaryInputStream *stream, sh::BlockMemberInfo *var);
+
+void WriteShaderVar(BinaryOutputStream *stream, const sh::ShaderVariable &var);
+void LoadShaderVar(BinaryInputStream *stream, sh::ShaderVariable *var);
+
+void WriteInterfaceBlock(BinaryOutputStream *stream, const InterfaceBlock &block);
+void LoadInterfaceBlock(BinaryInputStream *stream, InterfaceBlock *block);
+
+void WriteShInterfaceBlock(BinaryOutputStream *stream, const sh::InterfaceBlock &block);
+void LoadShInterfaceBlock(BinaryInputStream *stream, sh::InterfaceBlock *block);
+
+void WriteShaderVariableBuffer(BinaryOutputStream *stream, const ShaderVariableBuffer &var);
+void LoadShaderVariableBuffer(BinaryInputStream *stream, ShaderVariableBuffer *var);
+
+// Struct used for correlating uniforms/elements of uniform arrays to handles
+struct VariableLocation
+{
+ static constexpr unsigned int kUnused = GL_INVALID_INDEX;
+
+ VariableLocation();
+ VariableLocation(unsigned int arrayIndex, unsigned int index);
+
+ // If used is false, it means this location is only used to fill an empty space in an array,
+ // and there is no corresponding uniform variable for this location. It can also mean the
+ // uniform was optimized out by the implementation.
+ bool used() const { return (index != kUnused); }
+ void markUnused() { index = kUnused; }
+ void markIgnored() { ignored = true; }
+
+ bool operator==(const VariableLocation &other) const
+ {
+ return arrayIndex == other.arrayIndex && index == other.index;
+ }
+
+ // "arrayIndex" stores the index of the innermost GLSL array. It's zero for non-arrays.
+ unsigned int arrayIndex;
+ // "index" is an index of the variable. The variable contains the indices for other than the
+ // innermost GLSL arrays.
+ unsigned int index;
+
+ // If this location was bound to an unreferenced uniform. Setting data on this uniform is a
+ // no-op.
+ 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;
+};
+
+struct ProgramBinding
+{
+ ProgramBinding() : location(GL_INVALID_INDEX), aliased(false) {}
+ ProgramBinding(GLuint index) : location(index), aliased(false) {}
+
+ GLuint location;
+ // Whether another binding was set that may potentially alias this.
+ bool aliased;
+};
+
+class ProgramBindings final : angle::NonCopyable
+{
+ public:
+ ProgramBindings();
+ ~ProgramBindings();
+
+ void bindLocation(GLuint index, const std::string &name);
+ int getBindingByName(const std::string &name) const;
+ int getBinding(const sh::ShaderVariable &variable) const;
+
+ using const_iterator = angle::HashMap<std::string, GLuint>::const_iterator;
+ const_iterator begin() const;
+ const_iterator end() const;
+
+ std::map<std::string, GLuint> getStableIterationMap() const;
+
+ private:
+ angle::HashMap<std::string, GLuint> mBindings;
+};
+
+// Uniforms and Fragment Outputs require special treatment due to array notation (e.g., "[0]")
+class ProgramAliasedBindings final : angle::NonCopyable
+{
+ public:
+ ProgramAliasedBindings();
+ ~ProgramAliasedBindings();
+
+ void bindLocation(GLuint index, const std::string &name);
+ int getBindingByName(const std::string &name) const;
+ int getBindingByLocation(GLuint location) const;
+ int getBinding(const sh::ShaderVariable &variable) const;
+
+ using const_iterator = angle::HashMap<std::string, ProgramBinding>::const_iterator;
+ const_iterator begin() const;
+ const_iterator end() const;
+
+ std::map<std::string, ProgramBinding> getStableIterationMap() const;
+
+ private:
+ angle::HashMap<std::string, ProgramBinding> mBindings;
+};
+
+class ProgramState final : angle::NonCopyable
+{
+ public:
+ ProgramState();
+ ~ProgramState();
+
+ const std::string &getLabel();
+
+ Shader *getAttachedShader(ShaderType shaderType) const;
+ const gl::ShaderMap<Shader *> &getAttachedShaders() const { return mAttachedShaders; }
+ const std::vector<std::string> &getTransformFeedbackVaryingNames() const
+ {
+ return mTransformFeedbackVaryingNames;
+ }
+ GLint getTransformFeedbackBufferMode() const
+ {
+ return mExecutable->getTransformFeedbackBufferMode();
+ }
+ GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const
+ {
+ return mExecutable->getUniformBlockBinding(uniformBlockIndex);
+ }
+ GLuint getShaderStorageBlockBinding(GLuint blockIndex) const
+ {
+ return mExecutable->getShaderStorageBlockBinding(blockIndex);
+ }
+ const UniformBlockBindingMask &getActiveUniformBlockBindingsMask() const
+ {
+ return mExecutable->getActiveUniformBlockBindings();
+ }
+ const std::vector<sh::ShaderVariable> &getProgramInputs() const
+ {
+ return mExecutable->getProgramInputs();
+ }
+ const std::vector<sh::ShaderVariable> &getOutputVariables() const
+ {
+ return mExecutable->getOutputVariables();
+ }
+ const std::vector<VariableLocation> &getOutputLocations() const
+ {
+ return mExecutable->getOutputLocations();
+ }
+ const std::vector<VariableLocation> &getSecondaryOutputLocations() const
+ {
+ return mExecutable->getSecondaryOutputLocations();
+ }
+ const std::vector<LinkedUniform> &getUniforms() const { return mExecutable->getUniforms(); }
+ const std::vector<VariableLocation> &getUniformLocations() const { return mUniformLocations; }
+ const std::vector<InterfaceBlock> &getUniformBlocks() const
+ {
+ return mExecutable->getUniformBlocks();
+ }
+ const std::vector<InterfaceBlock> &getShaderStorageBlocks() const
+ {
+ return mExecutable->getShaderStorageBlocks();
+ }
+ const std::vector<BufferVariable> &getBufferVariables() const { return mBufferVariables; }
+ const std::vector<SamplerBinding> &getSamplerBindings() const
+ {
+ return mExecutable->getSamplerBindings();
+ }
+ const std::vector<ImageBinding> &getImageBindings() const
+ {
+ return getExecutable().getImageBindings();
+ }
+ const sh::WorkGroupSize &getComputeShaderLocalSize() const { return mComputeShaderLocalSize; }
+ const RangeUI &getDefaultUniformRange() const { return mExecutable->getDefaultUniformRange(); }
+ const RangeUI &getSamplerUniformRange() const { return mExecutable->getSamplerUniformRange(); }
+ const RangeUI &getImageUniformRange() const { return mExecutable->getImageUniformRange(); }
+ const RangeUI &getAtomicCounterUniformRange() const
+ {
+ return mExecutable->getAtomicCounterUniformRange();
+ }
+ const RangeUI &getFragmentInoutRange() const { return mExecutable->getFragmentInoutRange(); }
+
+ const std::vector<TransformFeedbackVarying> &getLinkedTransformFeedbackVaryings() const
+ {
+ return mExecutable->getLinkedTransformFeedbackVaryings();
+ }
+ const std::vector<GLsizei> &getTransformFeedbackStrides() const
+ {
+ return mExecutable->getTransformFeedbackStrides();
+ }
+ const std::vector<AtomicCounterBuffer> &getAtomicCounterBuffers() const
+ {
+ return mExecutable->getAtomicCounterBuffers();
+ }
+
+ GLuint getUniformIndexFromName(const std::string &name) const;
+ GLuint getUniformIndexFromLocation(UniformLocation location) const;
+ Optional<GLuint> getSamplerIndex(UniformLocation location) const;
+ bool isSamplerUniformIndex(GLuint index) const;
+ GLuint getSamplerIndexFromUniformIndex(GLuint uniformIndex) const;
+ GLuint getUniformIndexFromSamplerIndex(GLuint samplerIndex) const;
+ bool isImageUniformIndex(GLuint index) const;
+ GLuint getImageIndexFromUniformIndex(GLuint uniformIndex) const;
+ GLuint getAttributeLocation(const std::string &name) const;
+
+ GLuint getBufferVariableIndexFromName(const std::string &name) const;
+
+ int getNumViews() const { return mNumViews; }
+ bool usesMultiview() const { return mNumViews != -1; }
+
+ bool hasAttachedShader() const;
+
+ ShaderType getFirstAttachedShaderStageType() const;
+ ShaderType getLastAttachedShaderStageType() const;
+
+ const ProgramAliasedBindings &getUniformLocationBindings() const
+ {
+ return mUniformLocationBindings;
+ }
+
+ const ProgramExecutable &getExecutable() const
+ {
+ ASSERT(mExecutable);
+ return *mExecutable;
+ }
+ ProgramExecutable &getExecutable()
+ {
+ ASSERT(mExecutable);
+ return *mExecutable;
+ }
+
+ bool hasImages() const { return !getImageBindings().empty(); }
+ rx::SpecConstUsageBits getSpecConstUsageBits() const { return mSpecConstUsageBits; }
+
+ // A Program can only either be graphics or compute, but never both, so it
+ // can answer isCompute() based on which shaders it has.
+ bool isCompute() const { return mExecutable->hasLinkedShaderStage(ShaderType::Compute); }
+
+ const std::string &getLabel() const { return mLabel; }
+
+ uint32_t getLocationsUsedForXfbExtension() const { return mLocationsUsedForXfbExtension; }
+
+ bool hasBinaryRetrieveableHint() const { return mBinaryRetrieveableHint; }
+
+ bool isSeparable() const { return mSeparable; }
+
+ int getDrawIDLocation() const { return mDrawIDLocation; }
+
+ int getBaseVertexLocation() const { return mBaseVertexLocation; }
+
+ int getBaseInstanceLocation() const { return mBaseInstanceLocation; }
+
+ ShaderType getAttachedTransformFeedbackStage() const;
+
+ private:
+ friend class MemoryProgramCache;
+ friend class Program;
+
+ void updateActiveSamplers();
+ void updateProgramInterfaceInputs(const Context *context);
+ void updateProgramInterfaceOutputs(const Context *context);
+
+ // Scans the sampler bindings for type conflicts with sampler 'textureUnitIndex'.
+ void setSamplerUniformTextureTypeAndFormat(size_t textureUnitIndex);
+
+ std::string mLabel;
+
+ sh::WorkGroupSize mComputeShaderLocalSize;
+
+ ShaderMap<Shader *> mAttachedShaders;
+
+ uint32_t mLocationsUsedForXfbExtension;
+ std::vector<std::string> mTransformFeedbackVaryingNames;
+
+ std::vector<VariableLocation> mUniformLocations;
+ std::vector<BufferVariable> mBufferVariables;
+
+ bool mBinaryRetrieveableHint;
+ bool mSeparable;
+ rx::SpecConstUsageBits mSpecConstUsageBits;
+
+ // ANGLE_multiview.
+ int mNumViews;
+
+ // GL_ANGLE_multi_draw
+ int mDrawIDLocation;
+
+ // GL_ANGLE_base_vertex_base_instance_shader_builtin
+ int mBaseVertexLocation;
+ int mBaseInstanceLocation;
+ // Cached value of base vertex and base instance
+ // need to reset them to zero if using non base vertex or base instance draw calls.
+ GLint mCachedBaseVertex;
+ GLuint mCachedBaseInstance;
+
+ // Note that this has nothing to do with binding layout qualifiers that can be set for some
+ // uniforms in GLES3.1+. It is used to pre-set the location of uniforms.
+ ProgramAliasedBindings mUniformLocationBindings;
+
+ std::shared_ptr<ProgramExecutable> mExecutable;
+};
+
+struct ProgramVaryingRef
+{
+ const sh::ShaderVariable *get(ShaderType stage) const
+ {
+ ASSERT(stage == frontShaderStage || stage == backShaderStage);
+ const sh::ShaderVariable *ref = stage == frontShaderStage ? frontShader : backShader;
+ ASSERT(ref);
+ return ref;
+ }
+
+ const sh::ShaderVariable *frontShader = nullptr;
+ const sh::ShaderVariable *backShader = nullptr;
+ ShaderType frontShaderStage = ShaderType::InvalidEnum;
+ ShaderType backShaderStage = ShaderType::InvalidEnum;
+};
+
+using ProgramMergedVaryings = std::vector<ProgramVaryingRef>;
+
+class Program final : public LabeledObject, public angle::Subject
+{
+ public:
+ Program(rx::GLImplFactory *factory, ShaderProgramManager *manager, ShaderProgramID handle);
+ void onDestroy(const Context *context);
+
+ ShaderProgramID id() const;
+
+ angle::Result setLabel(const Context *context, const std::string &label) override;
+ const std::string &getLabel() const override;
+
+ ANGLE_INLINE rx::ProgramImpl *getImplementation() const
+ {
+ ASSERT(!mLinkingState);
+ return mProgram;
+ }
+
+ void attachShader(Shader *shader);
+ void detachShader(const Context *context, Shader *shader);
+ int getAttachedShadersCount() const;
+
+ Shader *getAttachedShader(ShaderType shaderType) const;
+
+ void bindAttributeLocation(GLuint index, const char *name);
+ void bindUniformLocation(UniformLocation location, const char *name);
+
+ // EXT_blend_func_extended
+ void bindFragmentOutputLocation(GLuint index, const char *name);
+ void bindFragmentOutputIndex(GLuint index, const char *name);
+
+ // KHR_parallel_shader_compile
+ // Try to link the program asynchronously. As a result, background threads may be launched to
+ // execute the linking tasks concurrently.
+ angle::Result link(const Context *context);
+
+ // Peek whether there is any running linking tasks.
+ bool isLinking() const;
+ bool hasLinkingState() const { return mLinkingState != nullptr; }
+
+ bool isLinked() const
+ {
+ ASSERT(!mLinkingState);
+ return mLinked;
+ }
+
+ angle::Result loadBinary(const Context *context,
+ GLenum binaryFormat,
+ const void *binary,
+ GLsizei length);
+ angle::Result saveBinary(Context *context,
+ GLenum *binaryFormat,
+ void *binary,
+ GLsizei bufSize,
+ GLsizei *length) const;
+ GLint getBinaryLength(Context *context) const;
+ void setBinaryRetrievableHint(bool retrievable);
+ bool getBinaryRetrievableHint() const;
+
+ void setSeparable(bool separable);
+ bool isSeparable() const;
+
+ void getAttachedShaders(GLsizei maxCount, GLsizei *count, ShaderProgramID *shaders) const;
+
+ GLuint getAttributeLocation(const std::string &name) const;
+
+ void getActiveAttribute(GLuint index,
+ GLsizei bufsize,
+ GLsizei *length,
+ GLint *size,
+ GLenum *type,
+ GLchar *name) const;
+ GLint getActiveAttributeCount() const;
+ GLint getActiveAttributeMaxLength() const;
+ const std::vector<sh::ShaderVariable> &getAttributes() const;
+
+ GLint getFragDataLocation(const std::string &name) const;
+ size_t getOutputResourceCount() const;
+
+ // EXT_blend_func_extended
+ GLint getFragDataIndex(const std::string &name) const;
+
+ void getActiveUniform(GLuint index,
+ GLsizei bufsize,
+ GLsizei *length,
+ GLint *size,
+ GLenum *type,
+ GLchar *name) const;
+ GLint getActiveUniformCount() const;
+ size_t getActiveBufferVariableCount() const;
+ GLint getActiveUniformMaxLength() const;
+ bool isValidUniformLocation(UniformLocation location) const;
+ const LinkedUniform &getUniformByLocation(UniformLocation location) const;
+ const VariableLocation &getUniformLocation(UniformLocation location) const;
+
+ const std::vector<VariableLocation> &getUniformLocations() const
+ {
+ ASSERT(!mLinkingState);
+ return mState.mUniformLocations;
+ }
+
+ const LinkedUniform &getUniformByIndex(GLuint index) const
+ {
+ ASSERT(!mLinkingState);
+ return mState.mExecutable->getUniformByIndex(index);
+ }
+
+ const BufferVariable &getBufferVariableByIndex(GLuint index) const;
+
+ enum SetUniformResult
+ {
+ SamplerChanged,
+ NoSamplerChange,
+ };
+
+ UniformLocation getUniformLocation(const std::string &name) const;
+ GLuint getUniformIndex(const std::string &name) const;
+ void setUniform1fv(UniformLocation location, GLsizei count, const GLfloat *v);
+ void setUniform2fv(UniformLocation location, GLsizei count, const GLfloat *v);
+ void setUniform3fv(UniformLocation location, GLsizei count, const GLfloat *v);
+ void setUniform4fv(UniformLocation location, GLsizei count, const GLfloat *v);
+ void setUniform1iv(Context *context, UniformLocation location, GLsizei count, const GLint *v);
+ void setUniform2iv(UniformLocation location, GLsizei count, const GLint *v);
+ void setUniform3iv(UniformLocation location, GLsizei count, const GLint *v);
+ void setUniform4iv(UniformLocation location, GLsizei count, const GLint *v);
+ void setUniform1uiv(UniformLocation location, GLsizei count, const GLuint *v);
+ void setUniform2uiv(UniformLocation location, GLsizei count, const GLuint *v);
+ void setUniform3uiv(UniformLocation location, GLsizei count, const GLuint *v);
+ void setUniform4uiv(UniformLocation location, GLsizei count, const GLuint *v);
+ void setUniformMatrix2fv(UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+ void setUniformMatrix3fv(UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+ void setUniformMatrix4fv(UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+ void setUniformMatrix2x3fv(UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+ void setUniformMatrix3x2fv(UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+ void setUniformMatrix2x4fv(UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+ void setUniformMatrix4x2fv(UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+ void setUniformMatrix3x4fv(UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+ void setUniformMatrix4x3fv(UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+
+ void getUniformfv(const Context *context, UniformLocation location, GLfloat *params) const;
+ void getUniformiv(const Context *context, UniformLocation location, GLint *params) const;
+ void getUniformuiv(const Context *context, UniformLocation location, GLuint *params) const;
+
+ void getActiveUniformBlockName(const Context *context,
+ const UniformBlockIndex blockIndex,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *blockName) const;
+ void getActiveShaderStorageBlockName(const GLuint blockIndex,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *blockName) const;
+
+ ANGLE_INLINE GLuint getActiveUniformBlockCount() const
+ {
+ ASSERT(!mLinkingState);
+ return static_cast<GLuint>(mState.mExecutable->getActiveUniformBlockCount());
+ }
+
+ ANGLE_INLINE GLuint getActiveAtomicCounterBufferCount() const
+ {
+ ASSERT(!mLinkingState);
+ return static_cast<GLuint>(mState.mExecutable->getActiveAtomicCounterBufferCount());
+ }
+
+ ANGLE_INLINE GLuint getActiveShaderStorageBlockCount() const
+ {
+ ASSERT(!mLinkingState);
+ return static_cast<GLuint>(mState.mExecutable->getActiveShaderStorageBlockCount());
+ }
+
+ GLint getActiveUniformBlockMaxNameLength() const;
+ GLint getActiveShaderStorageBlockMaxNameLength() const;
+
+ const std::vector<LinkedUniform> &getUniforms() const { return mState.getUniforms(); }
+ GLuint getUniformBlockIndex(const std::string &name) const;
+ GLuint getShaderStorageBlockIndex(const std::string &name) const;
+
+ void bindUniformBlock(UniformBlockIndex uniformBlockIndex, GLuint uniformBlockBinding);
+ GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const;
+ GLuint getShaderStorageBlockBinding(GLuint shaderStorageBlockIndex) const;
+
+ const InterfaceBlock &getUniformBlockByIndex(GLuint index) const;
+ const InterfaceBlock &getShaderStorageBlockByIndex(GLuint index) const;
+
+ void setTransformFeedbackVaryings(GLsizei count,
+ const GLchar *const *varyings,
+ GLenum bufferMode);
+ void getTransformFeedbackVarying(GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLsizei *size,
+ GLenum *type,
+ GLchar *name) const;
+ GLsizei getTransformFeedbackVaryingCount() const;
+ GLsizei getTransformFeedbackVaryingMaxLength() const;
+ GLenum getTransformFeedbackBufferMode() const;
+ GLuint getTransformFeedbackVaryingResourceIndex(const GLchar *name) const;
+ const TransformFeedbackVarying &getTransformFeedbackVaryingResource(GLuint index) const;
+
+ bool hasDrawIDUniform() const;
+ void setDrawIDUniform(GLint drawid);
+
+ bool hasBaseVertexUniform() const;
+ void setBaseVertexUniform(GLint baseVertex);
+ bool hasBaseInstanceUniform() const;
+ void setBaseInstanceUniform(GLuint baseInstance);
+
+ ANGLE_INLINE void addRef()
+ {
+ ASSERT(!mLinkingState);
+ mRefCount++;
+ }
+
+ ANGLE_INLINE void release(const Context *context)
+ {
+ ASSERT(!mLinkingState);
+ mRefCount--;
+
+ if (mRefCount == 0 && mDeleteStatus)
+ {
+ deleteSelf(context);
+ }
+ }
+
+ unsigned int getRefCount() const;
+ bool isInUse() const { return getRefCount() != 0; }
+ void flagForDeletion();
+ bool isFlaggedForDeletion() const;
+
+ void validate(const Caps &caps);
+ bool isValidated() const;
+
+ const std::vector<ImageBinding> &getImageBindings() const
+ {
+ ASSERT(!mLinkingState);
+ return getExecutable().getImageBindings();
+ }
+ const sh::WorkGroupSize &getComputeShaderLocalSize() const;
+ PrimitiveMode getGeometryShaderInputPrimitiveType() const;
+ PrimitiveMode getGeometryShaderOutputPrimitiveType() const;
+ GLint getGeometryShaderInvocations() const;
+ GLint getGeometryShaderMaxVertices() const;
+
+ GLint getTessControlShaderVertices() const;
+ GLenum getTessGenMode() const;
+ GLenum getTessGenPointMode() const;
+ GLenum getTessGenSpacing() const;
+ GLenum getTessGenVertexOrder() const;
+
+ const ProgramState &getState() const
+ {
+ ASSERT(!mLinkingState);
+ return mState;
+ }
+
+ GLuint getInputResourceIndex(const GLchar *name) const;
+ GLuint getOutputResourceIndex(const GLchar *name) const;
+ void getInputResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const;
+ void getOutputResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const;
+ void getUniformResourceName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const;
+ void getBufferVariableResourceName(GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *name) const;
+ const sh::ShaderVariable &getInputResource(size_t index) const;
+ GLuint getResourceMaxNameSize(const sh::ShaderVariable &resource, GLint max) const;
+ GLuint getInputResourceMaxNameSize() const;
+ GLuint getOutputResourceMaxNameSize() const;
+ GLuint getResourceLocation(const GLchar *name, const sh::ShaderVariable &variable) const;
+ GLuint getInputResourceLocation(const GLchar *name) const;
+ GLuint getOutputResourceLocation(const GLchar *name) const;
+ const std::string getResourceName(const sh::ShaderVariable &resource) const;
+ const std::string getInputResourceName(GLuint index) const;
+ const std::string getOutputResourceName(GLuint index) const;
+ const sh::ShaderVariable &getOutputResource(size_t index) const;
+
+ const ProgramBindings &getAttributeBindings() const;
+ const ProgramAliasedBindings &getUniformLocationBindings() const;
+ const ProgramAliasedBindings &getFragmentOutputLocations() const;
+ const ProgramAliasedBindings &getFragmentOutputIndexes() const;
+
+ int getNumViews() const
+ {
+ ASSERT(!mLinkingState);
+ return mState.getNumViews();
+ }
+
+ bool usesMultiview() const { return mState.usesMultiview(); }
+
+ const std::vector<GLsizei> &getTransformFeedbackStrides() const;
+
+ // Program dirty bits.
+ enum DirtyBitType
+ {
+ DIRTY_BIT_UNIFORM_BLOCK_BINDING_0,
+ DIRTY_BIT_UNIFORM_BLOCK_BINDING_MAX =
+ DIRTY_BIT_UNIFORM_BLOCK_BINDING_0 + IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS,
+
+ DIRTY_BIT_COUNT = DIRTY_BIT_UNIFORM_BLOCK_BINDING_MAX,
+ };
+
+ using DirtyBits = angle::BitSet<DIRTY_BIT_COUNT>;
+
+ angle::Result syncState(const Context *context);
+
+ // Try to resolve linking. Inlined to make sure its overhead is as low as possible.
+ void resolveLink(const Context *context)
+ {
+ if (mLinkingState)
+ {
+ resolveLinkImpl(context);
+ }
+ }
+
+ ANGLE_INLINE bool hasAnyDirtyBit() const { return mDirtyBits.any(); }
+
+ // Writes a program's binary to the output memory buffer.
+ angle::Result serialize(const Context *context, angle::MemoryBuffer *binaryOut) const;
+
+ rx::Serial serial() const { return mSerial; }
+
+ const ProgramExecutable &getExecutable() const { return mState.getExecutable(); }
+ ProgramExecutable &getExecutable() { return mState.getExecutable(); }
+
+ private:
+ struct LinkingState;
+
+ ~Program() override;
+
+ // Loads program state according to the specified binary blob.
+ angle::Result deserialize(const Context *context, BinaryInputStream &stream, InfoLog &infoLog);
+
+ void unlink();
+ void deleteSelf(const Context *context);
+
+ angle::Result linkImpl(const Context *context);
+
+ bool linkValidateShaders(const Context *context, InfoLog &infoLog);
+ bool linkAttributes(const Context *context, InfoLog &infoLog);
+ bool linkVaryings(const Context *context, InfoLog &infoLog) const;
+
+ bool linkUniforms(const Context *context,
+ std::vector<UnusedUniform> *unusedUniformsOutOrNull,
+ GLuint *combinedImageUniformsOut,
+ InfoLog &infoLog);
+
+ void updateLinkedShaderStages();
+
+ void setUniformValuesFromBindingQualifiers();
+ bool shouldIgnoreUniform(UniformLocation location) const;
+
+ void initInterfaceBlockBindings();
+
+ // Both these function update the cached uniform values and return a modified "count"
+ // so that the uniform update doesn't overflow the uniform.
+ template <typename T>
+ GLsizei clampUniformCount(const VariableLocation &locationInfo,
+ GLsizei count,
+ int vectorSize,
+ const T *v);
+ template <size_t cols, size_t rows, typename T>
+ GLsizei clampMatrixUniformCount(UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const T *v);
+
+ void updateSamplerUniform(Context *context,
+ const VariableLocation &locationInfo,
+ GLsizei clampedCount,
+ const GLint *v);
+
+ template <typename DestT>
+ void getUniformInternal(const Context *context,
+ DestT *dataOut,
+ UniformLocation location,
+ GLenum nativeType,
+ int components) const;
+
+ void getResourceName(const std::string name,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *dest) const;
+
+ template <typename T>
+ GLint getActiveInterfaceBlockMaxNameLength(const std::vector<T> &resources) const;
+
+ GLuint getSamplerUniformBinding(const VariableLocation &uniformLocation) const;
+ GLuint getImageUniformBinding(const VariableLocation &uniformLocation) const;
+
+ // Block until linking is finished and resolve it.
+ void resolveLinkImpl(const gl::Context *context);
+
+ void postResolveLink(const gl::Context *context);
+
+ template <typename UniformT,
+ GLint UniformSize,
+ void (rx::ProgramImpl::*SetUniformFunc)(GLint, GLsizei, const UniformT *)>
+ void setUniformGeneric(UniformLocation location, GLsizei count, const UniformT *v);
+
+ template <
+ typename UniformT,
+ GLint MatrixC,
+ GLint MatrixR,
+ void (rx::ProgramImpl::*SetUniformMatrixFunc)(GLint, GLsizei, GLboolean, const UniformT *)>
+ void setUniformMatrixGeneric(UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const UniformT *v);
+
+ rx::Serial mSerial;
+ ProgramState mState;
+ rx::ProgramImpl *mProgram;
+
+ bool mValidated;
+
+ ProgramBindings mAttributeBindings;
+
+ // EXT_blend_func_extended
+ ProgramAliasedBindings mFragmentOutputLocations;
+ ProgramAliasedBindings mFragmentOutputIndexes;
+
+ bool mLinked;
+ std::unique_ptr<LinkingState> mLinkingState;
+ bool mDeleteStatus; // Flag to indicate that the program can be deleted when no longer in use
+
+ unsigned int mRefCount;
+
+ ShaderProgramManager *mResourceManager;
+ const ShaderProgramID mHandle;
+
+ DirtyBits mDirtyBits;
+
+ std::mutex mHistogramMutex;
+};
+} // namespace gl
+
+#endif // LIBANGLE_PROGRAM_H_
diff --git a/gfx/angle/checkout/src/libANGLE/ProgramExecutable.cpp b/gfx/angle/checkout/src/libANGLE/ProgramExecutable.cpp
new file mode 100644
index 0000000000..6005519347
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/ProgramExecutable.cpp
@@ -0,0 +1,1785 @@
+//
+// Copyright 2020 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.
+//
+// ProgramExecutable.cpp: Collects the interfaces common to both Programs and
+// ProgramPipelines in order to execute/draw with either.
+
+#include "libANGLE/ProgramExecutable.h"
+
+#include "common/string_utils.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Program.h"
+#include "libANGLE/Shader.h"
+
+namespace gl
+{
+namespace
+{
+bool IncludeSameArrayElement(const std::set<std::string> &nameSet, const std::string &name)
+{
+ std::vector<unsigned int> subscripts;
+ std::string baseName = ParseResourceName(name, &subscripts);
+ for (const std::string &nameInSet : nameSet)
+ {
+ std::vector<unsigned int> arrayIndices;
+ std::string arrayName = ParseResourceName(nameInSet, &arrayIndices);
+ if (baseName == arrayName &&
+ (subscripts.empty() || arrayIndices.empty() || subscripts == arrayIndices))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+// Find the matching varying or field by name.
+const sh::ShaderVariable *FindOutputVaryingOrField(const ProgramMergedVaryings &varyings,
+ ShaderType stage,
+ const std::string &name)
+{
+ const sh::ShaderVariable *var = nullptr;
+ for (const ProgramVaryingRef &ref : varyings)
+ {
+ if (ref.frontShaderStage != stage)
+ {
+ continue;
+ }
+
+ const sh::ShaderVariable *varying = ref.get(stage);
+ if (varying->name == name)
+ {
+ var = varying;
+ break;
+ }
+ GLuint fieldIndex = 0;
+ var = varying->findField(name, &fieldIndex);
+ if (var != nullptr)
+ {
+ break;
+ }
+ }
+ return var;
+}
+
+bool FindUsedOutputLocation(std::vector<VariableLocation> &outputLocations,
+ unsigned int baseLocation,
+ unsigned int elementCount,
+ const std::vector<VariableLocation> &reservedLocations,
+ unsigned int variableIndex)
+{
+ if (baseLocation + elementCount > outputLocations.size())
+ {
+ elementCount = baseLocation < outputLocations.size()
+ ? static_cast<unsigned int>(outputLocations.size() - baseLocation)
+ : 0;
+ }
+ for (unsigned int elementIndex = 0; elementIndex < elementCount; elementIndex++)
+ {
+ const unsigned int location = baseLocation + elementIndex;
+ if (outputLocations[location].used())
+ {
+ VariableLocation locationInfo(elementIndex, variableIndex);
+ if (std::find(reservedLocations.begin(), reservedLocations.end(), locationInfo) ==
+ reservedLocations.end())
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+void AssignOutputLocations(std::vector<VariableLocation> &outputLocations,
+ unsigned int baseLocation,
+ unsigned int elementCount,
+ const std::vector<VariableLocation> &reservedLocations,
+ unsigned int variableIndex,
+ sh::ShaderVariable &outputVariable)
+{
+ if (baseLocation + elementCount > outputLocations.size())
+ {
+ outputLocations.resize(baseLocation + elementCount);
+ }
+ for (unsigned int elementIndex = 0; elementIndex < elementCount; elementIndex++)
+ {
+ VariableLocation locationInfo(elementIndex, variableIndex);
+ if (std::find(reservedLocations.begin(), reservedLocations.end(), locationInfo) ==
+ reservedLocations.end())
+ {
+ outputVariable.location = baseLocation;
+ const unsigned int location = baseLocation + elementIndex;
+ outputLocations[location] = locationInfo;
+ }
+ }
+}
+
+int GetOutputLocationForLink(const ProgramAliasedBindings &fragmentOutputLocations,
+ const sh::ShaderVariable &outputVariable)
+{
+ if (outputVariable.location != -1)
+ {
+ return outputVariable.location;
+ }
+ int apiLocation = fragmentOutputLocations.getBinding(outputVariable);
+ if (apiLocation != -1)
+ {
+ return apiLocation;
+ }
+ return -1;
+}
+
+bool IsOutputSecondaryForLink(const ProgramAliasedBindings &fragmentOutputIndexes,
+ const sh::ShaderVariable &outputVariable)
+{
+ if (outputVariable.index != -1)
+ {
+ ASSERT(outputVariable.index == 0 || outputVariable.index == 1);
+ return (outputVariable.index == 1);
+ }
+ int apiIndex = fragmentOutputIndexes.getBinding(outputVariable);
+ if (apiIndex != -1)
+ {
+ // Index layout qualifier from the shader takes precedence, so the index from the API is
+ // checked only if the index was not set in the shader. This is not specified in the EXT
+ // spec, but is specified in desktop OpenGL specs.
+ return (apiIndex == 1);
+ }
+ // EXT_blend_func_extended: Outputs get index 0 by default.
+ return false;
+}
+
+RangeUI AddUniforms(const ShaderMap<Program *> &programs,
+ ShaderBitSet activeShaders,
+ std::vector<LinkedUniform> &outputUniforms,
+ const std::function<RangeUI(const ProgramState &)> &getRange)
+{
+ unsigned int startRange = static_cast<unsigned int>(outputUniforms.size());
+ for (ShaderType shaderType : activeShaders)
+ {
+ const ProgramState &programState = programs[shaderType]->getState();
+ const std::vector<LinkedUniform> &programUniforms = programState.getUniforms();
+ const RangeUI uniformRange = getRange(programState);
+
+ outputUniforms.insert(outputUniforms.end(), programUniforms.begin() + uniformRange.low(),
+ programUniforms.begin() + uniformRange.high());
+ }
+ return RangeUI(startRange, static_cast<unsigned int>(outputUniforms.size()));
+}
+
+template <typename BlockT>
+void AppendActiveBlocks(ShaderType shaderType,
+ const std::vector<BlockT> &blocksIn,
+ std::vector<BlockT> &blocksOut)
+{
+ for (const BlockT &block : blocksIn)
+ {
+ if (block.isActive(shaderType))
+ {
+ blocksOut.push_back(block);
+ }
+ }
+}
+} // anonymous namespace
+
+ProgramExecutable::ProgramExecutable()
+ : mMaxActiveAttribLocation(0),
+ mAttributesTypeMask(0),
+ mAttributesMask(0),
+ mActiveSamplerRefCounts{},
+ mCanDrawWith(false),
+ mYUVOutput(false),
+ mTransformFeedbackBufferMode(GL_INTERLEAVED_ATTRIBS),
+ mDefaultUniformRange(0, 0),
+ mSamplerUniformRange(0, 0),
+ mImageUniformRange(0, 0),
+ mAtomicCounterUniformRange(0, 0),
+ mFragmentInoutRange(0, 0),
+ mHasDiscard(false),
+ mEnablesPerSampleShading(false),
+ // [GL_EXT_geometry_shader] Table 20.22
+ mGeometryShaderInputPrimitiveType(PrimitiveMode::Triangles),
+ mGeometryShaderOutputPrimitiveType(PrimitiveMode::TriangleStrip),
+ mGeometryShaderInvocations(1),
+ mGeometryShaderMaxVertices(0),
+ mTessControlShaderVertices(0),
+ mTessGenMode(GL_NONE),
+ mTessGenSpacing(GL_NONE),
+ mTessGenVertexOrder(GL_NONE),
+ mTessGenPointMode(GL_NONE)
+{
+ reset(true);
+}
+
+ProgramExecutable::ProgramExecutable(const ProgramExecutable &other)
+ : mLinkedShaderStages(other.mLinkedShaderStages),
+ mActiveAttribLocationsMask(other.mActiveAttribLocationsMask),
+ mMaxActiveAttribLocation(other.mMaxActiveAttribLocation),
+ mAttributesTypeMask(other.mAttributesTypeMask),
+ mAttributesMask(other.mAttributesMask),
+ mActiveSamplersMask(other.mActiveSamplersMask),
+ mActiveSamplerRefCounts(other.mActiveSamplerRefCounts),
+ mActiveSamplerTypes(other.mActiveSamplerTypes),
+ mActiveSamplerYUV(other.mActiveSamplerYUV),
+ mActiveSamplerFormats(other.mActiveSamplerFormats),
+ mActiveSamplerShaderBits(other.mActiveSamplerShaderBits),
+ mActiveImagesMask(other.mActiveImagesMask),
+ mActiveImageShaderBits(other.mActiveImageShaderBits),
+ mCanDrawWith(other.mCanDrawWith),
+ mOutputVariables(other.mOutputVariables),
+ mOutputLocations(other.mOutputLocations),
+ mSecondaryOutputLocations(other.mSecondaryOutputLocations),
+ mYUVOutput(other.mYUVOutput),
+ mProgramInputs(other.mProgramInputs),
+ mLinkedTransformFeedbackVaryings(other.mLinkedTransformFeedbackVaryings),
+ mTransformFeedbackStrides(other.mTransformFeedbackStrides),
+ mTransformFeedbackBufferMode(other.mTransformFeedbackBufferMode),
+ mUniforms(other.mUniforms),
+ mDefaultUniformRange(other.mDefaultUniformRange),
+ mSamplerUniformRange(other.mSamplerUniformRange),
+ mImageUniformRange(other.mImageUniformRange),
+ mAtomicCounterUniformRange(other.mAtomicCounterUniformRange),
+ mUniformBlocks(other.mUniformBlocks),
+ mActiveUniformBlockBindings(other.mActiveUniformBlockBindings),
+ mAtomicCounterBuffers(other.mAtomicCounterBuffers),
+ mShaderStorageBlocks(other.mShaderStorageBlocks),
+ mFragmentInoutRange(other.mFragmentInoutRange),
+ mHasDiscard(other.mHasDiscard),
+ mEnablesPerSampleShading(other.mEnablesPerSampleShading),
+ mAdvancedBlendEquations(other.mAdvancedBlendEquations)
+{
+ reset(true);
+}
+
+ProgramExecutable::~ProgramExecutable() = default;
+
+void ProgramExecutable::reset(bool clearInfoLog)
+{
+ if (clearInfoLog)
+ {
+ resetInfoLog();
+ }
+ mActiveAttribLocationsMask.reset();
+ mAttributesTypeMask.reset();
+ mAttributesMask.reset();
+ mMaxActiveAttribLocation = 0;
+
+ mActiveSamplersMask.reset();
+ mActiveSamplerRefCounts = {};
+ mActiveSamplerTypes.fill(TextureType::InvalidEnum);
+ mActiveSamplerYUV.reset();
+ mActiveSamplerFormats.fill(SamplerFormat::InvalidEnum);
+
+ mActiveImagesMask.reset();
+
+ mProgramInputs.clear();
+ mLinkedTransformFeedbackVaryings.clear();
+ mTransformFeedbackStrides.clear();
+ mUniforms.clear();
+ mUniformBlocks.clear();
+ mActiveUniformBlockBindings.reset();
+ mShaderStorageBlocks.clear();
+ mAtomicCounterBuffers.clear();
+ mOutputVariables.clear();
+ mOutputLocations.clear();
+ mActiveOutputVariablesMask.reset();
+ mSecondaryOutputLocations.clear();
+ mYUVOutput = false;
+ mSamplerBindings.clear();
+ mImageBindings.clear();
+
+ mDefaultUniformRange = RangeUI(0, 0);
+ mSamplerUniformRange = RangeUI(0, 0);
+ mImageUniformRange = RangeUI(0, 0);
+ mAtomicCounterUniformRange = RangeUI(0, 0);
+
+ mFragmentInoutRange = RangeUI(0, 0);
+ mHasDiscard = false;
+ mEnablesPerSampleShading = false;
+ mAdvancedBlendEquations.reset();
+
+ mGeometryShaderInputPrimitiveType = PrimitiveMode::Triangles;
+ mGeometryShaderOutputPrimitiveType = PrimitiveMode::TriangleStrip;
+ mGeometryShaderInvocations = 1;
+ mGeometryShaderMaxVertices = 0;
+
+ mTessControlShaderVertices = 0;
+ mTessGenMode = GL_NONE;
+ mTessGenSpacing = GL_NONE;
+ mTessGenVertexOrder = GL_NONE;
+ mTessGenPointMode = GL_NONE;
+
+ mOutputVariableTypes.clear();
+ mDrawBufferTypeMask.reset();
+}
+
+void ProgramExecutable::load(bool isSeparable, gl::BinaryInputStream *stream)
+{
+ static_assert(MAX_VERTEX_ATTRIBS * 2 <= sizeof(uint32_t) * 8,
+ "Too many vertex attribs for mask: All bits of mAttributesTypeMask types and "
+ "mask fit into 32 bits each");
+ mAttributesTypeMask = gl::ComponentTypeMask(stream->readInt<uint32_t>());
+ mAttributesMask = gl::AttributesMask(stream->readInt<uint32_t>());
+ mActiveAttribLocationsMask = gl::AttributesMask(stream->readInt<uint32_t>());
+ mMaxActiveAttribLocation = stream->readInt<unsigned int>();
+
+ unsigned int fragmentInoutRangeLow = stream->readInt<uint32_t>();
+ unsigned int fragmentInoutRangeHigh = stream->readInt<uint32_t>();
+ mFragmentInoutRange = RangeUI(fragmentInoutRangeLow, fragmentInoutRangeHigh);
+
+ mHasDiscard = stream->readBool();
+ mEnablesPerSampleShading = stream->readBool();
+
+ static_assert(sizeof(mAdvancedBlendEquations.bits()) == sizeof(uint32_t));
+ mAdvancedBlendEquations = BlendEquationBitSet(stream->readInt<uint32_t>());
+
+ mLinkedShaderStages = ShaderBitSet(stream->readInt<uint8_t>());
+
+ mGeometryShaderInputPrimitiveType = stream->readEnum<PrimitiveMode>();
+ mGeometryShaderOutputPrimitiveType = stream->readEnum<PrimitiveMode>();
+ mGeometryShaderInvocations = stream->readInt<int>();
+ mGeometryShaderMaxVertices = stream->readInt<int>();
+
+ mTessControlShaderVertices = stream->readInt<int>();
+ mTessGenMode = stream->readInt<GLenum>();
+ mTessGenSpacing = stream->readInt<GLenum>();
+ mTessGenVertexOrder = stream->readInt<GLenum>();
+ mTessGenPointMode = stream->readInt<GLenum>();
+
+ size_t attribCount = stream->readInt<size_t>();
+ ASSERT(getProgramInputs().empty());
+ for (size_t attribIndex = 0; attribIndex < attribCount; ++attribIndex)
+ {
+ sh::ShaderVariable attrib;
+ LoadShaderVar(stream, &attrib);
+ attrib.location = stream->readInt<int>();
+ mProgramInputs.push_back(attrib);
+ }
+
+ size_t uniformCount = stream->readInt<size_t>();
+ ASSERT(getUniforms().empty());
+ for (size_t uniformIndex = 0; uniformIndex < uniformCount; ++uniformIndex)
+ {
+ LinkedUniform uniform;
+ LoadShaderVar(stream, &uniform);
+
+ uniform.bufferIndex = stream->readInt<int>();
+ LoadBlockMemberInfo(stream, &uniform.blockInfo);
+
+ stream->readIntVector<unsigned int>(&uniform.outerArraySizes);
+ uniform.outerArrayOffset = stream->readInt<unsigned int>();
+
+ uniform.typeInfo = &GetUniformTypeInfo(uniform.type);
+
+ // Active shader info
+ for (ShaderType shaderType : gl::AllShaderTypes())
+ {
+ uniform.setActive(shaderType, stream->readBool());
+ }
+
+ mUniforms.push_back(uniform);
+ }
+
+ size_t uniformBlockCount = stream->readInt<size_t>();
+ ASSERT(getUniformBlocks().empty());
+ for (size_t uniformBlockIndex = 0; uniformBlockIndex < uniformBlockCount; ++uniformBlockIndex)
+ {
+ InterfaceBlock uniformBlock;
+ LoadInterfaceBlock(stream, &uniformBlock);
+ mUniformBlocks.push_back(uniformBlock);
+
+ mActiveUniformBlockBindings.set(uniformBlockIndex, uniformBlock.binding != 0);
+ }
+
+ size_t shaderStorageBlockCount = stream->readInt<size_t>();
+ ASSERT(getShaderStorageBlocks().empty());
+ for (size_t shaderStorageBlockIndex = 0; shaderStorageBlockIndex < shaderStorageBlockCount;
+ ++shaderStorageBlockIndex)
+ {
+ InterfaceBlock shaderStorageBlock;
+ LoadInterfaceBlock(stream, &shaderStorageBlock);
+ mShaderStorageBlocks.push_back(shaderStorageBlock);
+ }
+
+ size_t atomicCounterBufferCount = stream->readInt<size_t>();
+ ASSERT(getAtomicCounterBuffers().empty());
+ for (size_t bufferIndex = 0; bufferIndex < atomicCounterBufferCount; ++bufferIndex)
+ {
+ AtomicCounterBuffer atomicCounterBuffer;
+ LoadShaderVariableBuffer(stream, &atomicCounterBuffer);
+
+ mAtomicCounterBuffers.push_back(atomicCounterBuffer);
+ }
+
+ size_t transformFeedbackVaryingCount = stream->readInt<size_t>();
+ ASSERT(mLinkedTransformFeedbackVaryings.empty());
+ for (size_t transformFeedbackVaryingIndex = 0;
+ transformFeedbackVaryingIndex < transformFeedbackVaryingCount;
+ ++transformFeedbackVaryingIndex)
+ {
+ sh::ShaderVariable varying;
+ stream->readIntVector<unsigned int>(&varying.arraySizes);
+ stream->readInt(&varying.type);
+ stream->readString(&varying.name);
+
+ GLuint arrayIndex = stream->readInt<GLuint>();
+
+ mLinkedTransformFeedbackVaryings.emplace_back(varying, arrayIndex);
+ }
+
+ mTransformFeedbackBufferMode = stream->readInt<GLint>();
+
+ size_t outputCount = stream->readInt<size_t>();
+ ASSERT(getOutputVariables().empty());
+ for (size_t outputIndex = 0; outputIndex < outputCount; ++outputIndex)
+ {
+ sh::ShaderVariable output;
+ LoadShaderVar(stream, &output);
+ output.location = stream->readInt<int>();
+ output.index = stream->readInt<int>();
+ mOutputVariables.push_back(output);
+ }
+
+ size_t outputVarCount = stream->readInt<size_t>();
+ ASSERT(getOutputLocations().empty());
+ for (size_t outputIndex = 0; outputIndex < outputVarCount; ++outputIndex)
+ {
+ VariableLocation locationData;
+ stream->readInt(&locationData.arrayIndex);
+ stream->readInt(&locationData.index);
+ stream->readBool(&locationData.ignored);
+ mOutputLocations.push_back(locationData);
+ }
+
+ mActiveOutputVariablesMask =
+ gl::DrawBufferMask(stream->readInt<gl::DrawBufferMask::value_type>());
+
+ size_t outputTypeCount = stream->readInt<size_t>();
+ for (size_t outputIndex = 0; outputIndex < outputTypeCount; ++outputIndex)
+ {
+ mOutputVariableTypes.push_back(stream->readInt<GLenum>());
+ }
+
+ static_assert(IMPLEMENTATION_MAX_DRAW_BUFFERS * 2 <= 8 * sizeof(uint32_t),
+ "All bits of mDrawBufferTypeMask and mActiveOutputVariables types and mask fit "
+ "into 32 bits each");
+ mDrawBufferTypeMask = gl::ComponentTypeMask(stream->readInt<uint32_t>());
+
+ stream->readBool(&mYUVOutput);
+
+ size_t secondaryOutputVarCount = stream->readInt<size_t>();
+ ASSERT(getSecondaryOutputLocations().empty());
+ for (size_t outputIndex = 0; outputIndex < secondaryOutputVarCount; ++outputIndex)
+ {
+ VariableLocation locationData;
+ stream->readInt(&locationData.arrayIndex);
+ stream->readInt(&locationData.index);
+ stream->readBool(&locationData.ignored);
+ mSecondaryOutputLocations.push_back(locationData);
+ }
+
+ unsigned int defaultUniformRangeLow = stream->readInt<unsigned int>();
+ unsigned int defaultUniformRangeHigh = stream->readInt<unsigned int>();
+ mDefaultUniformRange = RangeUI(defaultUniformRangeLow, defaultUniformRangeHigh);
+
+ unsigned int samplerRangeLow = stream->readInt<unsigned int>();
+ unsigned int samplerRangeHigh = stream->readInt<unsigned int>();
+ mSamplerUniformRange = RangeUI(samplerRangeLow, samplerRangeHigh);
+
+ size_t samplerCount = stream->readInt<size_t>();
+ for (size_t samplerIndex = 0; samplerIndex < samplerCount; ++samplerIndex)
+ {
+ TextureType textureType = stream->readEnum<TextureType>();
+ GLenum samplerType = stream->readInt<GLenum>();
+ SamplerFormat format = stream->readEnum<SamplerFormat>();
+ size_t bindingCount = stream->readInt<size_t>();
+ mSamplerBindings.emplace_back(textureType, samplerType, format, bindingCount);
+ }
+
+ unsigned int imageRangeLow = stream->readInt<unsigned int>();
+ unsigned int imageRangeHigh = stream->readInt<unsigned int>();
+ mImageUniformRange = RangeUI(imageRangeLow, imageRangeHigh);
+
+ size_t imageBindingCount = stream->readInt<size_t>();
+ for (size_t imageIndex = 0; imageIndex < imageBindingCount; ++imageIndex)
+ {
+ size_t elementCount = stream->readInt<size_t>();
+ TextureType textureType = static_cast<TextureType>(stream->readInt<unsigned int>());
+ ImageBinding imageBinding(elementCount, textureType);
+ for (size_t elementIndex = 0; elementIndex < elementCount; ++elementIndex)
+ {
+ imageBinding.boundImageUnits[elementIndex] = stream->readInt<unsigned int>();
+ }
+ mImageBindings.emplace_back(imageBinding);
+ }
+
+ unsigned int atomicCounterRangeLow = stream->readInt<unsigned int>();
+ unsigned int atomicCounterRangeHigh = stream->readInt<unsigned int>();
+ mAtomicCounterUniformRange = RangeUI(atomicCounterRangeLow, atomicCounterRangeHigh);
+
+ // These values are currently only used by PPOs, so only load them when the program is marked
+ // separable to save memory.
+ if (isSeparable)
+ {
+ for (ShaderType shaderType : mLinkedShaderStages)
+ {
+ mLinkedOutputVaryings[shaderType].resize(stream->readInt<size_t>());
+ for (sh::ShaderVariable &variable : mLinkedOutputVaryings[shaderType])
+ {
+ LoadShaderVar(stream, &variable);
+ }
+ mLinkedInputVaryings[shaderType].resize(stream->readInt<size_t>());
+ for (sh::ShaderVariable &variable : mLinkedInputVaryings[shaderType])
+ {
+ LoadShaderVar(stream, &variable);
+ }
+ mLinkedUniforms[shaderType].resize(stream->readInt<size_t>());
+ for (sh::ShaderVariable &variable : mLinkedUniforms[shaderType])
+ {
+ LoadShaderVar(stream, &variable);
+ }
+ mLinkedUniformBlocks[shaderType].resize(stream->readInt<size_t>());
+ for (sh::InterfaceBlock &shaderStorageBlock : mLinkedUniformBlocks[shaderType])
+ {
+ LoadShInterfaceBlock(stream, &shaderStorageBlock);
+ }
+ mLinkedShaderVersions[shaderType] = stream->readInt<int>();
+ }
+ }
+}
+
+void ProgramExecutable::save(bool isSeparable, gl::BinaryOutputStream *stream) const
+{
+ static_assert(MAX_VERTEX_ATTRIBS * 2 <= sizeof(uint32_t) * 8,
+ "All bits of mAttributesTypeMask types and mask fit into 32 bits each");
+ stream->writeInt(static_cast<uint32_t>(mAttributesTypeMask.to_ulong()));
+ stream->writeInt(static_cast<uint32_t>(mAttributesMask.to_ulong()));
+ stream->writeInt(static_cast<uint32_t>(mActiveAttribLocationsMask.to_ulong()));
+ stream->writeInt(mMaxActiveAttribLocation);
+
+ stream->writeInt(mFragmentInoutRange.low());
+ stream->writeInt(mFragmentInoutRange.high());
+
+ stream->writeBool(mHasDiscard);
+ stream->writeBool(mEnablesPerSampleShading);
+ stream->writeInt(mAdvancedBlendEquations.bits());
+
+ stream->writeInt(mLinkedShaderStages.bits());
+
+ ASSERT(mGeometryShaderInvocations >= 1 && mGeometryShaderMaxVertices >= 0);
+ stream->writeEnum(mGeometryShaderInputPrimitiveType);
+ stream->writeEnum(mGeometryShaderOutputPrimitiveType);
+ stream->writeInt(mGeometryShaderInvocations);
+ stream->writeInt(mGeometryShaderMaxVertices);
+
+ stream->writeInt(mTessControlShaderVertices);
+ stream->writeInt(mTessGenMode);
+ stream->writeInt(mTessGenSpacing);
+ stream->writeInt(mTessGenVertexOrder);
+ stream->writeInt(mTessGenPointMode);
+
+ stream->writeInt(getProgramInputs().size());
+ for (const sh::ShaderVariable &attrib : getProgramInputs())
+ {
+ WriteShaderVar(stream, attrib);
+ stream->writeInt(attrib.location);
+ }
+
+ stream->writeInt(getUniforms().size());
+ for (const LinkedUniform &uniform : getUniforms())
+ {
+ WriteShaderVar(stream, uniform);
+
+ stream->writeInt(uniform.bufferIndex);
+ WriteBlockMemberInfo(stream, uniform.blockInfo);
+
+ stream->writeIntVector(uniform.outerArraySizes);
+ stream->writeInt(uniform.outerArrayOffset);
+
+ // Active shader info
+ for (ShaderType shaderType : gl::AllShaderTypes())
+ {
+ stream->writeBool(uniform.isActive(shaderType));
+ }
+ }
+
+ stream->writeInt(getUniformBlocks().size());
+ for (const InterfaceBlock &uniformBlock : getUniformBlocks())
+ {
+ WriteInterfaceBlock(stream, uniformBlock);
+ }
+
+ stream->writeInt(getShaderStorageBlocks().size());
+ for (const InterfaceBlock &shaderStorageBlock : getShaderStorageBlocks())
+ {
+ WriteInterfaceBlock(stream, shaderStorageBlock);
+ }
+
+ stream->writeInt(mAtomicCounterBuffers.size());
+ for (const AtomicCounterBuffer &atomicCounterBuffer : getAtomicCounterBuffers())
+ {
+ WriteShaderVariableBuffer(stream, atomicCounterBuffer);
+ }
+
+ stream->writeInt(getLinkedTransformFeedbackVaryings().size());
+ for (const auto &var : getLinkedTransformFeedbackVaryings())
+ {
+ stream->writeIntVector(var.arraySizes);
+ stream->writeInt(var.type);
+ stream->writeString(var.name);
+
+ stream->writeIntOrNegOne(var.arrayIndex);
+ }
+
+ stream->writeInt(getTransformFeedbackBufferMode());
+
+ stream->writeInt(getOutputVariables().size());
+ for (const sh::ShaderVariable &output : getOutputVariables())
+ {
+ WriteShaderVar(stream, output);
+ stream->writeInt(output.location);
+ stream->writeInt(output.index);
+ }
+
+ stream->writeInt(getOutputLocations().size());
+ for (const auto &outputVar : getOutputLocations())
+ {
+ stream->writeInt(outputVar.arrayIndex);
+ stream->writeIntOrNegOne(outputVar.index);
+ stream->writeBool(outputVar.ignored);
+ }
+
+ stream->writeInt(static_cast<int>(mActiveOutputVariablesMask.to_ulong()));
+
+ stream->writeInt(mOutputVariableTypes.size());
+ for (const auto &outputVariableType : mOutputVariableTypes)
+ {
+ stream->writeInt(outputVariableType);
+ }
+
+ static_assert(
+ IMPLEMENTATION_MAX_DRAW_BUFFERS * 2 <= 8 * sizeof(uint32_t),
+ "All bits of mDrawBufferTypeMask and mActiveOutputVariables can be contained in 32 bits");
+ stream->writeInt(static_cast<int>(mDrawBufferTypeMask.to_ulong()));
+
+ stream->writeBool(mYUVOutput);
+
+ stream->writeInt(getSecondaryOutputLocations().size());
+ for (const auto &outputVar : getSecondaryOutputLocations())
+ {
+ stream->writeInt(outputVar.arrayIndex);
+ stream->writeIntOrNegOne(outputVar.index);
+ stream->writeBool(outputVar.ignored);
+ }
+
+ stream->writeInt(getDefaultUniformRange().low());
+ stream->writeInt(getDefaultUniformRange().high());
+
+ stream->writeInt(getSamplerUniformRange().low());
+ stream->writeInt(getSamplerUniformRange().high());
+
+ stream->writeInt(getSamplerBindings().size());
+ for (const auto &samplerBinding : getSamplerBindings())
+ {
+ stream->writeEnum(samplerBinding.textureType);
+ stream->writeInt(samplerBinding.samplerType);
+ stream->writeEnum(samplerBinding.format);
+ stream->writeInt(samplerBinding.boundTextureUnits.size());
+ }
+
+ stream->writeInt(getImageUniformRange().low());
+ stream->writeInt(getImageUniformRange().high());
+
+ stream->writeInt(getImageBindings().size());
+ for (const auto &imageBinding : getImageBindings())
+ {
+ stream->writeInt(imageBinding.boundImageUnits.size());
+ stream->writeInt(static_cast<unsigned int>(imageBinding.textureType));
+ for (size_t i = 0; i < imageBinding.boundImageUnits.size(); ++i)
+ {
+ stream->writeInt(imageBinding.boundImageUnits[i]);
+ }
+ }
+
+ stream->writeInt(getAtomicCounterUniformRange().low());
+ stream->writeInt(getAtomicCounterUniformRange().high());
+
+ // These values are currently only used by PPOs, so only save them when the program is marked
+ // separable to save memory.
+ if (isSeparable)
+ {
+ for (ShaderType shaderType : mLinkedShaderStages)
+ {
+ stream->writeInt(mLinkedOutputVaryings[shaderType].size());
+ for (const sh::ShaderVariable &shaderVariable : mLinkedOutputVaryings[shaderType])
+ {
+ WriteShaderVar(stream, shaderVariable);
+ }
+ stream->writeInt(mLinkedInputVaryings[shaderType].size());
+ for (const sh::ShaderVariable &shaderVariable : mLinkedInputVaryings[shaderType])
+ {
+ WriteShaderVar(stream, shaderVariable);
+ }
+ stream->writeInt(mLinkedUniforms[shaderType].size());
+ for (const sh::ShaderVariable &shaderVariable : mLinkedUniforms[shaderType])
+ {
+ WriteShaderVar(stream, shaderVariable);
+ }
+ stream->writeInt(mLinkedUniformBlocks[shaderType].size());
+ for (const sh::InterfaceBlock &shaderStorageBlock : mLinkedUniformBlocks[shaderType])
+ {
+ WriteShInterfaceBlock(stream, shaderStorageBlock);
+ }
+ stream->writeInt(mLinkedShaderVersions[shaderType]);
+ }
+ }
+}
+
+int ProgramExecutable::getInfoLogLength() const
+{
+ return static_cast<int>(mInfoLog.getLength());
+}
+
+void ProgramExecutable::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) const
+{
+ return mInfoLog.getLog(bufSize, length, infoLog);
+}
+
+std::string ProgramExecutable::getInfoLogString() const
+{
+ return mInfoLog.str();
+}
+
+bool ProgramExecutable::isAttribLocationActive(size_t attribLocation) const
+{
+ ASSERT(attribLocation < mActiveAttribLocationsMask.size());
+ return mActiveAttribLocationsMask[attribLocation];
+}
+
+AttributesMask ProgramExecutable::getAttributesMask() const
+{
+ return mAttributesMask;
+}
+
+bool ProgramExecutable::hasDefaultUniforms() const
+{
+ return !getDefaultUniformRange().empty();
+}
+
+bool ProgramExecutable::hasTextures() const
+{
+ return !getSamplerBindings().empty();
+}
+
+bool ProgramExecutable::hasUniformBuffers() const
+{
+ return !mUniformBlocks.empty();
+}
+
+bool ProgramExecutable::hasStorageBuffers() const
+{
+ return !mShaderStorageBlocks.empty();
+}
+
+bool ProgramExecutable::hasAtomicCounterBuffers() const
+{
+ return !mAtomicCounterBuffers.empty();
+}
+
+bool ProgramExecutable::hasImages() const
+{
+ return !mImageBindings.empty();
+}
+
+bool ProgramExecutable::usesFramebufferFetch() const
+{
+ return (mFragmentInoutRange.length() > 0);
+}
+
+GLuint ProgramExecutable::getUniformIndexFromImageIndex(GLuint imageIndex) const
+{
+ ASSERT(imageIndex < mImageUniformRange.length());
+ return imageIndex + mImageUniformRange.low();
+}
+
+GLuint ProgramExecutable::getUniformIndexFromSamplerIndex(GLuint samplerIndex) const
+{
+ ASSERT(samplerIndex < mSamplerUniformRange.length());
+ return samplerIndex + mSamplerUniformRange.low();
+}
+
+void ProgramExecutable::setActive(size_t textureUnit,
+ const SamplerBinding &samplerBinding,
+ const gl::LinkedUniform &samplerUniform)
+{
+ mActiveSamplersMask.set(textureUnit);
+ mActiveSamplerTypes[textureUnit] = samplerBinding.textureType;
+ mActiveSamplerYUV[textureUnit] = IsSamplerYUVType(samplerBinding.samplerType);
+ mActiveSamplerFormats[textureUnit] = samplerBinding.format;
+ mActiveSamplerShaderBits[textureUnit] = samplerUniform.activeShaders();
+}
+
+void ProgramExecutable::setInactive(size_t textureUnit)
+{
+ mActiveSamplersMask.reset(textureUnit);
+ mActiveSamplerTypes[textureUnit] = TextureType::InvalidEnum;
+ mActiveSamplerYUV.reset(textureUnit);
+ mActiveSamplerFormats[textureUnit] = SamplerFormat::InvalidEnum;
+ mActiveSamplerShaderBits[textureUnit].reset();
+}
+
+void ProgramExecutable::hasSamplerTypeConflict(size_t textureUnit)
+{
+ // Conflicts are marked with InvalidEnum
+ mActiveSamplerYUV.reset(textureUnit);
+ mActiveSamplerTypes[textureUnit] = TextureType::InvalidEnum;
+}
+
+void ProgramExecutable::hasSamplerFormatConflict(size_t textureUnit)
+{
+ // Conflicts are marked with InvalidEnum
+ mActiveSamplerFormats[textureUnit] = SamplerFormat::InvalidEnum;
+}
+
+void ProgramExecutable::updateActiveSamplers(const ProgramState &programState)
+{
+ const std::vector<SamplerBinding> &samplerBindings = programState.getSamplerBindings();
+
+ for (uint32_t samplerIndex = 0; samplerIndex < samplerBindings.size(); ++samplerIndex)
+ {
+ const SamplerBinding &samplerBinding = samplerBindings[samplerIndex];
+
+ for (GLint textureUnit : samplerBinding.boundTextureUnits)
+ {
+ if (++mActiveSamplerRefCounts[textureUnit] == 1)
+ {
+ uint32_t uniformIndex = programState.getUniformIndexFromSamplerIndex(samplerIndex);
+ setActive(textureUnit, samplerBinding, programState.getUniforms()[uniformIndex]);
+ }
+ else
+ {
+ if (mActiveSamplerTypes[textureUnit] != samplerBinding.textureType ||
+ mActiveSamplerYUV.test(textureUnit) !=
+ IsSamplerYUVType(samplerBinding.samplerType))
+ {
+ hasSamplerTypeConflict(textureUnit);
+ }
+
+ if (mActiveSamplerFormats[textureUnit] != samplerBinding.format)
+ {
+ hasSamplerFormatConflict(textureUnit);
+ }
+ }
+ mActiveSamplersMask.set(textureUnit);
+ }
+ }
+
+ // Invalidate the validation cache.
+ resetCachedValidateSamplersResult();
+}
+
+void ProgramExecutable::updateActiveImages(const ProgramExecutable &executable)
+{
+ const std::vector<ImageBinding> &imageBindings = executable.getImageBindings();
+ for (uint32_t imageIndex = 0; imageIndex < imageBindings.size(); ++imageIndex)
+ {
+ const gl::ImageBinding &imageBinding = imageBindings.at(imageIndex);
+
+ uint32_t uniformIndex = executable.getUniformIndexFromImageIndex(imageIndex);
+ const gl::LinkedUniform &imageUniform = executable.getUniforms()[uniformIndex];
+ const ShaderBitSet shaderBits = imageUniform.activeShaders();
+ for (GLint imageUnit : imageBinding.boundImageUnits)
+ {
+ mActiveImagesMask.set(imageUnit);
+ mActiveImageShaderBits[imageUnit] |= shaderBits;
+ }
+ }
+}
+
+void ProgramExecutable::setSamplerUniformTextureTypeAndFormat(
+ size_t textureUnitIndex,
+ std::vector<SamplerBinding> &samplerBindings)
+{
+ bool foundBinding = false;
+ TextureType foundType = TextureType::InvalidEnum;
+ bool foundYUV = false;
+ SamplerFormat foundFormat = SamplerFormat::InvalidEnum;
+
+ for (uint32_t samplerIndex = 0; samplerIndex < samplerBindings.size(); ++samplerIndex)
+ {
+ const SamplerBinding &binding = samplerBindings[samplerIndex];
+
+ // A conflict exists if samplers of different types are sourced by the same texture unit.
+ // We need to check all bound textures to detect this error case.
+ for (GLuint textureUnit : binding.boundTextureUnits)
+ {
+ if (textureUnit != textureUnitIndex)
+ {
+ continue;
+ }
+
+ if (!foundBinding)
+ {
+ foundBinding = true;
+ foundType = binding.textureType;
+ foundYUV = IsSamplerYUVType(binding.samplerType);
+ foundFormat = binding.format;
+ uint32_t uniformIndex = getUniformIndexFromSamplerIndex(samplerIndex);
+ setActive(textureUnit, binding, mUniforms[uniformIndex]);
+ }
+ else
+ {
+ if (foundType != binding.textureType ||
+ foundYUV != IsSamplerYUVType(binding.samplerType))
+ {
+ hasSamplerTypeConflict(textureUnit);
+ }
+
+ if (foundFormat != binding.format)
+ {
+ hasSamplerFormatConflict(textureUnit);
+ }
+ }
+ }
+ }
+}
+
+void ProgramExecutable::updateCanDrawWith()
+{
+ mCanDrawWith = hasLinkedShaderStage(ShaderType::Vertex);
+}
+
+void ProgramExecutable::saveLinkedStateInfo(const Context *context, const ProgramState &state)
+{
+ for (ShaderType shaderType : getLinkedShaderStages())
+ {
+ Shader *shader = state.getAttachedShader(shaderType);
+ ASSERT(shader);
+ mLinkedOutputVaryings[shaderType] = shader->getOutputVaryings(context);
+ mLinkedInputVaryings[shaderType] = shader->getInputVaryings(context);
+ mLinkedShaderVersions[shaderType] = shader->getShaderVersion(context);
+ mLinkedUniforms[shaderType] = shader->getUniforms(context);
+ mLinkedUniformBlocks[shaderType] = shader->getUniformBlocks(context);
+ }
+}
+
+bool ProgramExecutable::isYUVOutput() const
+{
+ return mYUVOutput;
+}
+
+ShaderType ProgramExecutable::getLinkedTransformFeedbackStage() const
+{
+ return GetLastPreFragmentStage(mLinkedShaderStages);
+}
+
+bool ProgramExecutable::linkMergedVaryings(
+ const Context *context,
+ const ProgramMergedVaryings &mergedVaryings,
+ const std::vector<std::string> &transformFeedbackVaryingNames,
+ const LinkingVariables &linkingVariables,
+ bool isSeparable,
+ ProgramVaryingPacking *varyingPacking)
+{
+ ShaderType tfStage = GetLastPreFragmentStage(linkingVariables.isShaderStageUsedBitset);
+
+ if (!linkValidateTransformFeedback(context, mergedVaryings, tfStage,
+ transformFeedbackVaryingNames))
+ {
+ return false;
+ }
+
+ // Map the varyings to the register file
+ // In WebGL, we use a slightly different handling for packing variables.
+ gl::PackMode packMode = PackMode::ANGLE_RELAXED;
+ if (context->getLimitations().noFlexibleVaryingPacking)
+ {
+ // D3D9 pack mode is strictly more strict than WebGL, so takes priority.
+ packMode = PackMode::ANGLE_NON_CONFORMANT_D3D9;
+ }
+ else if (context->isWebGL())
+ {
+ packMode = PackMode::WEBGL_STRICT;
+ }
+
+ // Build active shader stage map.
+ ShaderBitSet activeShadersMask;
+ for (ShaderType shaderType : kAllGraphicsShaderTypes)
+ {
+ // - Check for attached shaders to handle the case of a Program linking the currently
+ // attached shaders.
+ // - Check for linked shaders to handle the case of a PPO linking separable programs before
+ // drawing.
+ if (linkingVariables.isShaderStageUsedBitset[shaderType] ||
+ getLinkedShaderStages().test(shaderType))
+ {
+ activeShadersMask[shaderType] = true;
+ }
+ }
+
+ if (!varyingPacking->collectAndPackUserVaryings(mInfoLog, context->getCaps(), packMode,
+ activeShadersMask, mergedVaryings,
+ transformFeedbackVaryingNames, isSeparable))
+ {
+ return false;
+ }
+
+ gatherTransformFeedbackVaryings(mergedVaryings, tfStage, transformFeedbackVaryingNames);
+ updateTransformFeedbackStrides();
+
+ return true;
+}
+
+bool ProgramExecutable::linkValidateTransformFeedback(
+ const Context *context,
+ const ProgramMergedVaryings &varyings,
+ ShaderType stage,
+ const std::vector<std::string> &transformFeedbackVaryingNames)
+{
+ const Version &version = context->getClientVersion();
+
+ // Validate the tf names regardless of the actual program varyings.
+ std::set<std::string> uniqueNames;
+ for (const std::string &tfVaryingName : transformFeedbackVaryingNames)
+ {
+ if (version < Version(3, 1) && tfVaryingName.find('[') != std::string::npos)
+ {
+ mInfoLog << "Capture of array elements is undefined and not supported.";
+ return false;
+ }
+ if (version >= Version(3, 1))
+ {
+ if (IncludeSameArrayElement(uniqueNames, tfVaryingName))
+ {
+ mInfoLog << "Two transform feedback varyings include the same array element ("
+ << tfVaryingName << ").";
+ return false;
+ }
+ }
+ else
+ {
+ if (uniqueNames.count(tfVaryingName) > 0)
+ {
+ mInfoLog << "Two transform feedback varyings specify the same output variable ("
+ << tfVaryingName << ").";
+ return false;
+ }
+ }
+ uniqueNames.insert(tfVaryingName);
+ }
+
+ // From OpneGLES spec. 11.1.2.1: A program will fail to link if:
+ // the count specified by TransformFeedbackVaryings is non-zero, but the
+ // program object has no vertex, tessellation evaluation, or geometry shader
+ if (transformFeedbackVaryingNames.size() > 0 &&
+ !gl::ShaderTypeSupportsTransformFeedback(getLinkedTransformFeedbackStage()))
+ {
+ mInfoLog << "Linked transform feedback stage " << getLinkedTransformFeedbackStage()
+ << " does not support transform feedback varying.";
+ return false;
+ }
+
+ // Validate against program varyings.
+ size_t totalComponents = 0;
+ for (const std::string &tfVaryingName : transformFeedbackVaryingNames)
+ {
+ std::vector<unsigned int> subscripts;
+ std::string baseName = ParseResourceName(tfVaryingName, &subscripts);
+
+ const sh::ShaderVariable *var = FindOutputVaryingOrField(varyings, stage, baseName);
+ if (var == nullptr)
+ {
+ mInfoLog << "Transform feedback varying " << tfVaryingName
+ << " does not exist in the vertex shader.";
+ return false;
+ }
+
+ // Validate the matching variable.
+ if (var->isStruct())
+ {
+ mInfoLog << "Struct cannot be captured directly (" << baseName << ").";
+ return false;
+ }
+
+ size_t elementCount = 0;
+ size_t componentCount = 0;
+
+ if (var->isArray())
+ {
+ if (version < Version(3, 1))
+ {
+ mInfoLog << "Capture of arrays is undefined and not supported.";
+ return false;
+ }
+
+ // GLSL ES 3.10 section 4.3.6: A vertex output can't be an array of arrays.
+ ASSERT(!var->isArrayOfArrays());
+
+ if (!subscripts.empty() && subscripts[0] >= var->getOutermostArraySize())
+ {
+ mInfoLog << "Cannot capture outbound array element '" << tfVaryingName << "'.";
+ return false;
+ }
+ elementCount = (subscripts.empty() ? var->getOutermostArraySize() : 1);
+ }
+ else
+ {
+ if (!subscripts.empty())
+ {
+ mInfoLog << "Varying '" << baseName
+ << "' is not an array to be captured by element.";
+ return false;
+ }
+ elementCount = 1;
+ }
+
+ const Caps &caps = context->getCaps();
+
+ // TODO(jmadill): Investigate implementation limits on D3D11
+ componentCount = VariableComponentCount(var->type) * elementCount;
+ if (mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS &&
+ componentCount > static_cast<GLuint>(caps.maxTransformFeedbackSeparateComponents))
+ {
+ mInfoLog << "Transform feedback varying " << tfVaryingName << " components ("
+ << componentCount << ") exceed the maximum separate components ("
+ << caps.maxTransformFeedbackSeparateComponents << ").";
+ return false;
+ }
+
+ totalComponents += componentCount;
+ if (mTransformFeedbackBufferMode == GL_INTERLEAVED_ATTRIBS &&
+ totalComponents > static_cast<GLuint>(caps.maxTransformFeedbackInterleavedComponents))
+ {
+ mInfoLog << "Transform feedback varying total components (" << totalComponents
+ << ") exceed the maximum interleaved components ("
+ << caps.maxTransformFeedbackInterleavedComponents << ").";
+ return false;
+ }
+ }
+ return true;
+}
+
+void ProgramExecutable::gatherTransformFeedbackVaryings(
+ const ProgramMergedVaryings &varyings,
+ ShaderType stage,
+ const std::vector<std::string> &transformFeedbackVaryingNames)
+{
+ // Gather the linked varyings that are used for transform feedback, they should all exist.
+ mLinkedTransformFeedbackVaryings.clear();
+ for (const std::string &tfVaryingName : transformFeedbackVaryingNames)
+ {
+ std::vector<unsigned int> subscripts;
+ std::string baseName = ParseResourceName(tfVaryingName, &subscripts);
+ size_t subscript = GL_INVALID_INDEX;
+ if (!subscripts.empty())
+ {
+ subscript = subscripts.back();
+ }
+ for (const ProgramVaryingRef &ref : varyings)
+ {
+ if (ref.frontShaderStage != stage)
+ {
+ continue;
+ }
+
+ const sh::ShaderVariable *varying = ref.get(stage);
+ if (baseName == varying->name)
+ {
+ mLinkedTransformFeedbackVaryings.emplace_back(*varying,
+ static_cast<GLuint>(subscript));
+ break;
+ }
+ else if (varying->isStruct())
+ {
+ GLuint fieldIndex = 0;
+ const auto *field = varying->findField(tfVaryingName, &fieldIndex);
+ if (field != nullptr)
+ {
+ mLinkedTransformFeedbackVaryings.emplace_back(*field, *varying);
+ break;
+ }
+ }
+ }
+ }
+}
+
+void ProgramExecutable::updateTransformFeedbackStrides()
+{
+ if (mLinkedTransformFeedbackVaryings.empty())
+ {
+ return;
+ }
+
+ if (mTransformFeedbackBufferMode == GL_INTERLEAVED_ATTRIBS)
+ {
+ mTransformFeedbackStrides.resize(1);
+ size_t totalSize = 0;
+ for (const TransformFeedbackVarying &varying : mLinkedTransformFeedbackVaryings)
+ {
+ totalSize += varying.size() * VariableExternalSize(varying.type);
+ }
+ mTransformFeedbackStrides[0] = static_cast<GLsizei>(totalSize);
+ }
+ else
+ {
+ mTransformFeedbackStrides.resize(mLinkedTransformFeedbackVaryings.size());
+ for (size_t i = 0; i < mLinkedTransformFeedbackVaryings.size(); i++)
+ {
+ TransformFeedbackVarying &varying = mLinkedTransformFeedbackVaryings[i];
+ mTransformFeedbackStrides[i] =
+ static_cast<GLsizei>(varying.size() * VariableExternalSize(varying.type));
+ }
+ }
+}
+
+bool ProgramExecutable::validateSamplersImpl(InfoLog *infoLog, const Caps &caps) const
+{
+ // if any two active samplers in a program are of different types, but refer to the same
+ // texture image unit, and this is the current program, then ValidateProgram will fail, and
+ // DrawArrays and DrawElements will issue the INVALID_OPERATION error.
+ for (size_t textureUnit : mActiveSamplersMask)
+ {
+ if (mActiveSamplerTypes[textureUnit] == TextureType::InvalidEnum)
+ {
+ if (infoLog)
+ {
+ (*infoLog) << "Samplers of conflicting types refer to the same texture "
+ "image unit ("
+ << textureUnit << ").";
+ }
+
+ mCachedValidateSamplersResult = false;
+ return false;
+ }
+
+ if (mActiveSamplerFormats[textureUnit] == SamplerFormat::InvalidEnum)
+ {
+ if (infoLog)
+ {
+ (*infoLog) << "Samplers of conflicting formats refer to the same texture "
+ "image unit ("
+ << textureUnit << ").";
+ }
+
+ mCachedValidateSamplersResult = false;
+ return false;
+ }
+ }
+
+ mCachedValidateSamplersResult = true;
+ return true;
+}
+
+bool ProgramExecutable::linkValidateOutputVariables(
+ const Caps &caps,
+ const Extensions &extensions,
+ const Version &version,
+ GLuint combinedImageUniformsCount,
+ GLuint combinedShaderStorageBlocksCount,
+ const std::vector<sh::ShaderVariable> &outputVariables,
+ int fragmentShaderVersion,
+ const ProgramAliasedBindings &fragmentOutputLocations,
+ const ProgramAliasedBindings &fragmentOutputIndices)
+{
+ ASSERT(mOutputVariableTypes.empty());
+ ASSERT(mActiveOutputVariablesMask.none());
+ ASSERT(mDrawBufferTypeMask.none());
+ ASSERT(!mYUVOutput);
+
+ // Gather output variable types
+ for (const sh::ShaderVariable &outputVariable : outputVariables)
+ {
+ if (outputVariable.isBuiltIn() && outputVariable.name != "gl_FragColor" &&
+ outputVariable.name != "gl_FragData")
+ {
+ continue;
+ }
+
+ unsigned int baseLocation =
+ (outputVariable.location == -1 ? 0u
+ : static_cast<unsigned int>(outputVariable.location));
+
+ // GLSL ES 3.10 section 4.3.6: Output variables cannot be arrays of arrays or arrays of
+ // structures, so we may use getBasicTypeElementCount().
+ unsigned int elementCount = outputVariable.getBasicTypeElementCount();
+ for (unsigned int elementIndex = 0; elementIndex < elementCount; elementIndex++)
+ {
+ const unsigned int location = baseLocation + elementIndex;
+ if (location >= mOutputVariableTypes.size())
+ {
+ mOutputVariableTypes.resize(location + 1, GL_NONE);
+ }
+ ASSERT(location < mActiveOutputVariablesMask.size());
+ mActiveOutputVariablesMask.set(location);
+ mOutputVariableTypes[location] = VariableComponentType(outputVariable.type);
+ ComponentType componentType = GLenumToComponentType(mOutputVariableTypes[location]);
+ SetComponentTypeMask(componentType, location, &mDrawBufferTypeMask);
+ }
+
+ if (outputVariable.yuv)
+ {
+ ASSERT(outputVariables.size() == 1);
+ mYUVOutput = true;
+ }
+ }
+
+ if (version >= ES_3_1)
+ {
+ // [OpenGL ES 3.1] Chapter 8.22 Page 203:
+ // A link error will be generated if the sum of the number of active image uniforms used in
+ // all shaders, the number of active shader storage blocks, and the number of active
+ // fragment shader outputs exceeds the implementation-dependent value of
+ // MAX_COMBINED_SHADER_OUTPUT_RESOURCES.
+ if (combinedImageUniformsCount + combinedShaderStorageBlocksCount +
+ mActiveOutputVariablesMask.count() >
+ static_cast<GLuint>(caps.maxCombinedShaderOutputResources))
+ {
+ mInfoLog
+ << "The sum of the number of active image uniforms, active shader storage blocks "
+ "and active fragment shader outputs exceeds "
+ "MAX_COMBINED_SHADER_OUTPUT_RESOURCES ("
+ << caps.maxCombinedShaderOutputResources << ")";
+ return false;
+ }
+ }
+
+ mOutputVariables = outputVariables;
+
+ if (fragmentShaderVersion == 100)
+ {
+ return true;
+ }
+
+ // EXT_blend_func_extended doesn't specify anything related to binding specific elements of an
+ // output array in explicit terms.
+ //
+ // Assuming fragData is an output array, you can defend the position that:
+ // P1) you must support binding "fragData" because it's specified
+ // P2) you must support querying "fragData[x]" because it's specified
+ // P3) you must support binding "fragData[0]" because it's a frequently used pattern
+ //
+ // Then you can make the leap of faith:
+ // P4) you must support binding "fragData[x]" because you support "fragData[0]"
+ // P5) you must support binding "fragData[x]" because you support querying "fragData[x]"
+ //
+ // The spec brings in the "world of arrays" when it mentions binding the arrays and the
+ // automatic binding. Thus it must be interpreted that the thing is not undefined, rather you
+ // must infer the only possible interpretation (?). Note again: this need of interpretation
+ // might be completely off of what GL spec logic is.
+ //
+ // The other complexity is that unless you implement this feature, it's hard to understand what
+ // should happen when the client invokes the feature. You cannot add an additional error as it
+ // is not specified. One can ignore it, but obviously it creates the discrepancies...
+
+ std::vector<VariableLocation> reservedLocations;
+
+ // Process any output API bindings for arrays that don't alias to the first element.
+ for (const auto &bindingPair : fragmentOutputLocations)
+ {
+ const std::string &name = bindingPair.first;
+ const ProgramBinding &binding = bindingPair.second;
+
+ size_t nameLengthWithoutArrayIndex;
+ unsigned int arrayIndex = ParseArrayIndex(name, &nameLengthWithoutArrayIndex);
+ if (arrayIndex == 0 || arrayIndex == GL_INVALID_INDEX)
+ {
+ continue;
+ }
+ for (unsigned int outputVariableIndex = 0; outputVariableIndex < mOutputVariables.size();
+ outputVariableIndex++)
+ {
+ const sh::ShaderVariable &outputVariable = mOutputVariables[outputVariableIndex];
+ // Check that the binding corresponds to an output array and its array index fits.
+ if (outputVariable.isBuiltIn() || !outputVariable.isArray() ||
+ !angle::BeginsWith(outputVariable.name, name, nameLengthWithoutArrayIndex) ||
+ arrayIndex >= outputVariable.getOutermostArraySize())
+ {
+ continue;
+ }
+
+ // Get the API index that corresponds to this exact binding.
+ // This index may differ from the index used for the array's base.
+ std::vector<VariableLocation> &outputLocations =
+ fragmentOutputIndices.getBindingByName(name) == 1 ? mSecondaryOutputLocations
+ : mOutputLocations;
+ unsigned int location = binding.location;
+ VariableLocation locationInfo(arrayIndex, outputVariableIndex);
+ if (location >= outputLocations.size())
+ {
+ outputLocations.resize(location + 1);
+ }
+ if (outputLocations[location].used())
+ {
+ mInfoLog << "Location of variable " << outputVariable.name
+ << " conflicts with another variable.";
+ return false;
+ }
+ outputLocations[location] = locationInfo;
+
+ // Note the array binding location so that it can be skipped later.
+ reservedLocations.push_back(locationInfo);
+ }
+ }
+
+ // Reserve locations for output variables whose location is fixed in the shader or through the
+ // API. Otherwise, the remaining unallocated outputs will be processed later.
+ for (unsigned int outputVariableIndex = 0; outputVariableIndex < mOutputVariables.size();
+ outputVariableIndex++)
+ {
+ const sh::ShaderVariable &outputVariable = mOutputVariables[outputVariableIndex];
+
+ // Don't store outputs for gl_FragDepth, gl_FragColor, etc.
+ if (outputVariable.isBuiltIn())
+ continue;
+
+ int fixedLocation = GetOutputLocationForLink(fragmentOutputLocations, outputVariable);
+ if (fixedLocation == -1)
+ {
+ // Here we're only reserving locations for variables whose location is fixed.
+ continue;
+ }
+ unsigned int baseLocation = static_cast<unsigned int>(fixedLocation);
+
+ std::vector<VariableLocation> &outputLocations =
+ IsOutputSecondaryForLink(fragmentOutputIndices, outputVariable)
+ ? mSecondaryOutputLocations
+ : mOutputLocations;
+
+ // GLSL ES 3.10 section 4.3.6: Output variables cannot be arrays of arrays or arrays of
+ // structures, so we may use getBasicTypeElementCount().
+ unsigned int elementCount = outputVariable.getBasicTypeElementCount();
+ if (FindUsedOutputLocation(outputLocations, baseLocation, elementCount, reservedLocations,
+ outputVariableIndex))
+ {
+ mInfoLog << "Location of variable " << outputVariable.name
+ << " conflicts with another variable.";
+ return false;
+ }
+ AssignOutputLocations(outputLocations, baseLocation, elementCount, reservedLocations,
+ outputVariableIndex, mOutputVariables[outputVariableIndex]);
+ }
+
+ // Here we assign locations for the output variables that don't yet have them. Note that we're
+ // not necessarily able to fit the variables optimally, since then we might have to try
+ // different arrangements of output arrays. Now we just assign the locations in the order that
+ // we got the output variables. The spec isn't clear on what kind of algorithm is required for
+ // finding locations for the output variables, so this should be acceptable at least for now.
+ GLuint maxLocation = static_cast<GLuint>(caps.maxDrawBuffers);
+ if (!mSecondaryOutputLocations.empty())
+ {
+ // EXT_blend_func_extended: Program outputs will be validated against
+ // MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT if there's even one output with index one.
+ maxLocation = caps.maxDualSourceDrawBuffers;
+ }
+
+ for (unsigned int outputVariableIndex = 0; outputVariableIndex < mOutputVariables.size();
+ outputVariableIndex++)
+ {
+ const sh::ShaderVariable &outputVariable = mOutputVariables[outputVariableIndex];
+
+ // Don't store outputs for gl_FragDepth, gl_FragColor, etc.
+ if (outputVariable.isBuiltIn())
+ continue;
+
+ int fixedLocation = GetOutputLocationForLink(fragmentOutputLocations, outputVariable);
+ std::vector<VariableLocation> &outputLocations =
+ IsOutputSecondaryForLink(fragmentOutputIndices, outputVariable)
+ ? mSecondaryOutputLocations
+ : mOutputLocations;
+ unsigned int baseLocation = 0;
+ unsigned int elementCount = outputVariable.getBasicTypeElementCount();
+ if (fixedLocation != -1)
+ {
+ // Secondary inputs might have caused the max location to drop below what has already
+ // been explicitly assigned locations. Check for any fixed locations above the max
+ // that should cause linking to fail.
+ baseLocation = static_cast<unsigned int>(fixedLocation);
+ }
+ else
+ {
+ // No fixed location, so try to fit the output in unassigned locations.
+ // Try baseLocations starting from 0 one at a time and see if the variable fits.
+ while (FindUsedOutputLocation(outputLocations, baseLocation, elementCount,
+ reservedLocations, outputVariableIndex))
+ {
+ baseLocation++;
+ }
+ AssignOutputLocations(outputLocations, baseLocation, elementCount, reservedLocations,
+ outputVariableIndex, mOutputVariables[outputVariableIndex]);
+ }
+
+ // Check for any elements assigned above the max location that are actually used.
+ if (baseLocation + elementCount > maxLocation &&
+ (baseLocation >= maxLocation ||
+ FindUsedOutputLocation(outputLocations, maxLocation,
+ baseLocation + elementCount - maxLocation, reservedLocations,
+ outputVariableIndex)))
+ {
+ // EXT_blend_func_extended: Linking can fail:
+ // "if the explicit binding assignments do not leave enough space for the linker to
+ // automatically assign a location for a varying out array, which requires multiple
+ // contiguous locations."
+ mInfoLog << "Could not fit output variable into available locations: "
+ << outputVariable.name;
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ProgramExecutable::linkUniforms(
+ const Context *context,
+ const ShaderMap<std::vector<sh::ShaderVariable>> &shaderUniforms,
+ InfoLog &infoLog,
+ const ProgramAliasedBindings &uniformLocationBindings,
+ GLuint *combinedImageUniformsCountOut,
+ std::vector<UnusedUniform> *unusedUniformsOutOrNull,
+ std::vector<VariableLocation> *uniformLocationsOutOrNull)
+{
+ UniformLinker linker(mLinkedShaderStages, shaderUniforms);
+ if (!linker.link(context->getCaps(), infoLog, uniformLocationBindings))
+ {
+ return false;
+ }
+
+ linker.getResults(&mUniforms, unusedUniformsOutOrNull, uniformLocationsOutOrNull);
+
+ linkSamplerAndImageBindings(combinedImageUniformsCountOut);
+
+ if (!linkAtomicCounterBuffers(context, infoLog))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+void ProgramExecutable::linkSamplerAndImageBindings(GLuint *combinedImageUniforms)
+{
+ ASSERT(combinedImageUniforms);
+
+ // Iterate over mExecutable->mUniforms from the back, and find the range of subpass inputs,
+ // atomic counters, images and samplers in that order.
+ auto highIter = mUniforms.rbegin();
+ auto lowIter = highIter;
+
+ unsigned int high = static_cast<unsigned int>(mUniforms.size());
+ unsigned int low = high;
+
+ // Note that uniform block uniforms are not yet appended to this list.
+ ASSERT(mUniforms.empty() || highIter->isAtomicCounter() || highIter->isImage() ||
+ highIter->isSampler() || highIter->isInDefaultBlock() || highIter->isFragmentInOut);
+
+ for (; lowIter != mUniforms.rend() && lowIter->isFragmentInOut; ++lowIter)
+ {
+ --low;
+ }
+
+ mFragmentInoutRange = RangeUI(low, high);
+
+ highIter = lowIter;
+ high = low;
+
+ for (; lowIter != mUniforms.rend() && lowIter->isAtomicCounter(); ++lowIter)
+ {
+ --low;
+ }
+
+ mAtomicCounterUniformRange = RangeUI(low, high);
+
+ highIter = lowIter;
+ high = low;
+
+ for (; lowIter != mUniforms.rend() && lowIter->isImage(); ++lowIter)
+ {
+ --low;
+ }
+
+ mImageUniformRange = RangeUI(low, high);
+ *combinedImageUniforms = 0u;
+ // If uniform is a image type, insert it into the mImageBindings array.
+ for (unsigned int imageIndex : mImageUniformRange)
+ {
+ // ES3.1 (section 7.6.1) and GLSL ES3.1 (section 4.4.5), Uniform*i{v} commands
+ // cannot load values into a uniform defined as an image. if declare without a
+ // binding qualifier, any uniform image variable (include all elements of
+ // unbound image array) should be bound to unit zero.
+ auto &imageUniform = mUniforms[imageIndex];
+ TextureType textureType = ImageTypeToTextureType(imageUniform.type);
+ const GLuint arraySize = imageUniform.isArray() ? imageUniform.arraySizes[0] : 1u;
+
+ if (imageUniform.binding == -1)
+ {
+ mImageBindings.emplace_back(
+ ImageBinding(imageUniform.getBasicTypeElementCount(), textureType));
+ }
+ else
+ {
+ // The arrays of arrays are flattened to arrays, it needs to record the array offset for
+ // the correct binding image unit.
+ mImageBindings.emplace_back(
+ ImageBinding(imageUniform.binding + imageUniform.parentArrayIndex() * arraySize,
+ imageUniform.getBasicTypeElementCount(), textureType));
+ }
+
+ *combinedImageUniforms += imageUniform.activeShaderCount() * arraySize;
+ }
+
+ highIter = lowIter;
+ high = low;
+
+ for (; lowIter != mUniforms.rend() && lowIter->isSampler(); ++lowIter)
+ {
+ --low;
+ }
+
+ mSamplerUniformRange = RangeUI(low, high);
+
+ // If uniform is a sampler type, insert it into the mSamplerBindings array.
+ for (unsigned int samplerIndex : mSamplerUniformRange)
+ {
+ const auto &samplerUniform = mUniforms[samplerIndex];
+ TextureType textureType = SamplerTypeToTextureType(samplerUniform.type);
+ GLenum samplerType = samplerUniform.typeInfo->type;
+ unsigned int elementCount = samplerUniform.getBasicTypeElementCount();
+ SamplerFormat format = samplerUniform.typeInfo->samplerFormat;
+ mSamplerBindings.emplace_back(textureType, samplerType, format, elementCount);
+ }
+
+ // Whatever is left constitutes the default uniforms.
+ mDefaultUniformRange = RangeUI(0, low);
+}
+
+bool ProgramExecutable::linkAtomicCounterBuffers(const Context *context, InfoLog &infoLog)
+{
+ for (unsigned int index : mAtomicCounterUniformRange)
+ {
+ auto &uniform = mUniforms[index];
+ uniform.blockInfo.offset = uniform.offset;
+ uniform.blockInfo.arrayStride = (uniform.isArray() ? 4 : 0);
+ uniform.blockInfo.matrixStride = 0;
+ uniform.blockInfo.isRowMajorMatrix = false;
+
+ bool found = false;
+ for (unsigned int bufferIndex = 0; bufferIndex < getActiveAtomicCounterBufferCount();
+ ++bufferIndex)
+ {
+ auto &buffer = mAtomicCounterBuffers[bufferIndex];
+ if (buffer.binding == uniform.binding)
+ {
+ buffer.memberIndexes.push_back(index);
+ uniform.bufferIndex = bufferIndex;
+ found = true;
+ buffer.unionReferencesWith(uniform);
+ break;
+ }
+ }
+ if (!found)
+ {
+ AtomicCounterBuffer atomicCounterBuffer;
+ atomicCounterBuffer.binding = uniform.binding;
+ atomicCounterBuffer.memberIndexes.push_back(index);
+ atomicCounterBuffer.unionReferencesWith(uniform);
+ mAtomicCounterBuffers.push_back(atomicCounterBuffer);
+ uniform.bufferIndex = static_cast<int>(getActiveAtomicCounterBufferCount() - 1);
+ }
+ }
+
+ // Count each atomic counter buffer to validate against
+ // per-stage and combined gl_Max*AtomicCounterBuffers.
+ GLint combinedShaderACBCount = 0;
+ gl::ShaderMap<GLint> perShaderACBCount = {};
+ for (unsigned int bufferIndex = 0; bufferIndex < getActiveAtomicCounterBufferCount();
+ ++bufferIndex)
+ {
+ AtomicCounterBuffer &acb = mAtomicCounterBuffers[bufferIndex];
+ const ShaderBitSet shaderStages = acb.activeShaders();
+ for (gl::ShaderType shaderType : shaderStages)
+ {
+ ++perShaderACBCount[shaderType];
+ }
+ ++combinedShaderACBCount;
+ }
+ const Caps &caps = context->getCaps();
+ if (combinedShaderACBCount > caps.maxCombinedAtomicCounterBuffers)
+ {
+ infoLog << " combined AtomicCounterBuffers count exceeds limit";
+ return false;
+ }
+ for (gl::ShaderType stage : gl::AllShaderTypes())
+ {
+ if (perShaderACBCount[stage] > caps.maxShaderAtomicCounterBuffers[stage])
+ {
+ infoLog << GetShaderTypeString(stage)
+ << " shader AtomicCounterBuffers count exceeds limit";
+ return false;
+ }
+ }
+ return true;
+}
+
+void ProgramExecutable::copyInputsFromProgram(const ProgramState &programState)
+{
+ mProgramInputs = programState.getProgramInputs();
+}
+
+void ProgramExecutable::copyShaderBuffersFromProgram(const ProgramState &programState,
+ ShaderType shaderType)
+{
+ AppendActiveBlocks(shaderType, programState.getUniformBlocks(), mUniformBlocks);
+ AppendActiveBlocks(shaderType, programState.getShaderStorageBlocks(), mShaderStorageBlocks);
+ AppendActiveBlocks(shaderType, programState.getAtomicCounterBuffers(), mAtomicCounterBuffers);
+}
+
+void ProgramExecutable::clearSamplerBindings()
+{
+ mSamplerBindings.clear();
+}
+
+void ProgramExecutable::copySamplerBindingsFromProgram(const ProgramState &programState)
+{
+ const std::vector<SamplerBinding> &bindings = programState.getSamplerBindings();
+ mSamplerBindings.insert(mSamplerBindings.end(), bindings.begin(), bindings.end());
+}
+
+void ProgramExecutable::copyImageBindingsFromProgram(const ProgramState &programState)
+{
+ const std::vector<ImageBinding> &bindings = programState.getImageBindings();
+ mImageBindings.insert(mImageBindings.end(), bindings.begin(), bindings.end());
+}
+
+void ProgramExecutable::copyOutputsFromProgram(const ProgramState &programState)
+{
+ mOutputVariables = programState.getOutputVariables();
+ mOutputLocations = programState.getOutputLocations();
+ mSecondaryOutputLocations = programState.getSecondaryOutputLocations();
+}
+
+void ProgramExecutable::copyUniformsFromProgramMap(const ShaderMap<Program *> &programs)
+{
+ // Merge default uniforms.
+ auto getDefaultRange = [](const ProgramState &state) { return state.getDefaultUniformRange(); };
+ mDefaultUniformRange = AddUniforms(programs, mLinkedShaderStages, mUniforms, getDefaultRange);
+
+ // Merge sampler uniforms.
+ auto getSamplerRange = [](const ProgramState &state) { return state.getSamplerUniformRange(); };
+ mSamplerUniformRange = AddUniforms(programs, mLinkedShaderStages, mUniforms, getSamplerRange);
+
+ // Merge image uniforms.
+ auto getImageRange = [](const ProgramState &state) { return state.getImageUniformRange(); };
+ mImageUniformRange = AddUniforms(programs, mLinkedShaderStages, mUniforms, getImageRange);
+
+ // Merge atomic counter uniforms.
+ auto getAtomicRange = [](const ProgramState &state) {
+ return state.getAtomicCounterUniformRange();
+ };
+ mAtomicCounterUniformRange =
+ AddUniforms(programs, mLinkedShaderStages, mUniforms, getAtomicRange);
+
+ // Merge fragment in/out uniforms.
+ auto getInoutRange = [](const ProgramState &state) { return state.getFragmentInoutRange(); };
+ mFragmentInoutRange = AddUniforms(programs, mLinkedShaderStages, mUniforms, getInoutRange);
+}
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/ProgramExecutable.h b/gfx/angle/checkout/src/libANGLE/ProgramExecutable.h
new file mode 100644
index 0000000000..4344ef4b5a
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/ProgramExecutable.h
@@ -0,0 +1,517 @@
+//
+// Copyright 2020 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.
+//
+// ProgramExecutable.h: Collects the information and interfaces common to both Programs and
+// ProgramPipelines in order to execute/draw with either.
+
+#ifndef LIBANGLE_PROGRAMEXECUTABLE_H_
+#define LIBANGLE_PROGRAMEXECUTABLE_H_
+
+#include "BinaryStream.h"
+#include "libANGLE/Caps.h"
+#include "libANGLE/InfoLog.h"
+#include "libANGLE/ProgramLinkedResources.h"
+#include "libANGLE/Shader.h"
+#include "libANGLE/Uniform.h"
+#include "libANGLE/VaryingPacking.h"
+#include "libANGLE/angletypes.h"
+
+namespace gl
+{
+
+// This small structure encapsulates binding sampler uniforms to active GL textures.
+struct SamplerBinding
+{
+ SamplerBinding(TextureType textureTypeIn,
+ GLenum samplerTypeIn,
+ SamplerFormat formatIn,
+ size_t elementCount);
+ SamplerBinding(const SamplerBinding &other);
+ ~SamplerBinding();
+
+ // Necessary for retrieving active textures from the GL state.
+ TextureType textureType;
+
+ GLenum samplerType;
+
+ SamplerFormat format;
+
+ // List of all textures bound to this sampler, of type textureType.
+ // Cropped by the amount of unused elements reported by the driver.
+ std::vector<GLuint> boundTextureUnits;
+};
+
+struct ImageBinding
+{
+ ImageBinding(size_t count, TextureType textureTypeIn);
+ ImageBinding(GLuint imageUnit, size_t count, TextureType textureTypeIn);
+ ImageBinding(const ImageBinding &other);
+ ~ImageBinding();
+
+ // Necessary for distinguishing between textures with images and texture buffers.
+ TextureType textureType;
+
+ // List of all textures bound.
+ // Cropped by the amount of unused elements reported by the driver.
+ std::vector<GLuint> boundImageUnits;
+};
+
+// A varying with transform feedback enabled. If it's an array, either the whole array or one of its
+// elements specified by 'arrayIndex' can set to be enabled.
+struct TransformFeedbackVarying : public sh::ShaderVariable
+{
+ TransformFeedbackVarying(const sh::ShaderVariable &varyingIn, GLuint arrayIndexIn)
+ : sh::ShaderVariable(varyingIn), arrayIndex(arrayIndexIn)
+ {
+ ASSERT(!isArrayOfArrays());
+ }
+
+ TransformFeedbackVarying(const sh::ShaderVariable &field, const sh::ShaderVariable &parent)
+ : arrayIndex(GL_INVALID_INDEX)
+ {
+ sh::ShaderVariable *thisVar = this;
+ *thisVar = field;
+ interpolation = parent.interpolation;
+ isInvariant = parent.isInvariant;
+ ASSERT(parent.isShaderIOBlock || !parent.name.empty());
+ if (!parent.name.empty())
+ {
+ name = parent.name + "." + name;
+ mappedName = parent.mappedName + "." + mappedName;
+ }
+ structOrBlockName = parent.structOrBlockName;
+ mappedStructOrBlockName = parent.mappedStructOrBlockName;
+ }
+
+ std::string nameWithArrayIndex() const
+ {
+ std::stringstream fullNameStr;
+ fullNameStr << name;
+ if (arrayIndex != GL_INVALID_INDEX)
+ {
+ fullNameStr << "[" << arrayIndex << "]";
+ }
+ return fullNameStr.str();
+ }
+ GLsizei size() const
+ {
+ return (isArray() && arrayIndex == GL_INVALID_INDEX ? getOutermostArraySize() : 1);
+ }
+
+ GLuint arrayIndex;
+};
+
+class ProgramState;
+class ProgramPipelineState;
+
+class ProgramExecutable final : public angle::Subject
+{
+ public:
+ ProgramExecutable();
+ ProgramExecutable(const ProgramExecutable &other);
+ ~ProgramExecutable() override;
+
+ void reset(bool clearInfoLog);
+
+ void save(bool isSeparable, gl::BinaryOutputStream *stream) const;
+ void load(bool isSeparable, gl::BinaryInputStream *stream);
+
+ int getInfoLogLength() const;
+ InfoLog &getInfoLog() { return mInfoLog; }
+ void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) const;
+ std::string getInfoLogString() const;
+ void resetInfoLog() { mInfoLog.reset(); }
+
+ void resetLinkedShaderStages() { mLinkedShaderStages.reset(); }
+ const ShaderBitSet &getLinkedShaderStages() const { return mLinkedShaderStages; }
+ void setLinkedShaderStages(ShaderType shaderType)
+ {
+ mLinkedShaderStages.set(shaderType);
+ updateCanDrawWith();
+ }
+ bool hasLinkedShaderStage(ShaderType shaderType) const
+ {
+ ASSERT(shaderType != ShaderType::InvalidEnum);
+ return mLinkedShaderStages[shaderType];
+ }
+ size_t getLinkedShaderStageCount() const { return mLinkedShaderStages.count(); }
+ bool hasLinkedGraphicsShader() const
+ {
+ return mLinkedShaderStages.any() &&
+ mLinkedShaderStages != gl::ShaderBitSet{gl::ShaderType::Compute};
+ }
+ bool hasLinkedTessellationShader() const
+ {
+ return mLinkedShaderStages[ShaderType::TessEvaluation];
+ }
+
+ ShaderType getLinkedTransformFeedbackStage() const;
+
+ const AttributesMask &getActiveAttribLocationsMask() const
+ {
+ return mActiveAttribLocationsMask;
+ }
+ bool isAttribLocationActive(size_t attribLocation) const;
+ const AttributesMask &getNonBuiltinAttribLocationsMask() const { return mAttributesMask; }
+ unsigned int getMaxActiveAttribLocation() const { return mMaxActiveAttribLocation; }
+ const ComponentTypeMask &getAttributesTypeMask() const { return mAttributesTypeMask; }
+ AttributesMask getAttributesMask() const;
+
+ const ActiveTextureMask &getActiveSamplersMask() const { return mActiveSamplersMask; }
+ void setActiveTextureMask(ActiveTextureMask mask) { mActiveSamplersMask = mask; }
+ SamplerFormat getSamplerFormatForTextureUnitIndex(size_t textureUnitIndex) const
+ {
+ return mActiveSamplerFormats[textureUnitIndex];
+ }
+ const ShaderBitSet getSamplerShaderBitsForTextureUnitIndex(size_t textureUnitIndex) const
+ {
+ return mActiveSamplerShaderBits[textureUnitIndex];
+ }
+ const ActiveTextureMask &getActiveImagesMask() const { return mActiveImagesMask; }
+ void setActiveImagesMask(ActiveTextureMask mask) { mActiveImagesMask = mask; }
+ const ActiveTextureArray<ShaderBitSet> &getActiveImageShaderBits() const
+ {
+ return mActiveImageShaderBits;
+ }
+
+ const ActiveTextureMask &getActiveYUVSamplers() const { return mActiveSamplerYUV; }
+
+ const ActiveTextureArray<TextureType> &getActiveSamplerTypes() const
+ {
+ return mActiveSamplerTypes;
+ }
+
+ void setActive(size_t textureUnit,
+ const SamplerBinding &samplerBinding,
+ const gl::LinkedUniform &samplerUniform);
+ void setInactive(size_t textureUnit);
+ void hasSamplerTypeConflict(size_t textureUnit);
+ void hasSamplerFormatConflict(size_t textureUnit);
+
+ void updateActiveSamplers(const ProgramState &programState);
+
+ bool hasDefaultUniforms() const;
+ bool hasTextures() const;
+ bool hasUniformBuffers() const;
+ bool hasStorageBuffers() const;
+ bool hasAtomicCounterBuffers() const;
+ bool hasImages() const;
+ bool hasTransformFeedbackOutput() const
+ {
+ return !getLinkedTransformFeedbackVaryings().empty();
+ }
+ bool usesFramebufferFetch() const;
+
+ // Count the number of uniform and storage buffer declarations, counting arrays as one.
+ size_t getTransformFeedbackBufferCount() const { return mTransformFeedbackStrides.size(); }
+
+ void updateCanDrawWith();
+ bool hasVertexShader() const { return mCanDrawWith; }
+
+ const std::vector<sh::ShaderVariable> &getProgramInputs() const { return mProgramInputs; }
+ const std::vector<sh::ShaderVariable> &getOutputVariables() const { return mOutputVariables; }
+ const std::vector<VariableLocation> &getOutputLocations() const { return mOutputLocations; }
+ const std::vector<VariableLocation> &getSecondaryOutputLocations() const
+ {
+ return mSecondaryOutputLocations;
+ }
+ const std::vector<LinkedUniform> &getUniforms() const { return mUniforms; }
+ const std::vector<InterfaceBlock> &getUniformBlocks() const { return mUniformBlocks; }
+ const UniformBlockBindingMask &getActiveUniformBlockBindings() const
+ {
+ return mActiveUniformBlockBindings;
+ }
+ const std::vector<SamplerBinding> &getSamplerBindings() const { return mSamplerBindings; }
+ const std::vector<ImageBinding> &getImageBindings() const { return mImageBindings; }
+ std::vector<ImageBinding> *getImageBindings() { return &mImageBindings; }
+ const RangeUI &getDefaultUniformRange() const { return mDefaultUniformRange; }
+ const RangeUI &getSamplerUniformRange() const { return mSamplerUniformRange; }
+ const RangeUI &getImageUniformRange() const { return mImageUniformRange; }
+ const RangeUI &getAtomicCounterUniformRange() const { return mAtomicCounterUniformRange; }
+ const RangeUI &getFragmentInoutRange() const { return mFragmentInoutRange; }
+ bool hasDiscard() const { return mHasDiscard; }
+ bool enablesPerSampleShading() const { return mEnablesPerSampleShading; }
+ BlendEquationBitSet getAdvancedBlendEquations() const { return mAdvancedBlendEquations; }
+ const std::vector<TransformFeedbackVarying> &getLinkedTransformFeedbackVaryings() const
+ {
+ return mLinkedTransformFeedbackVaryings;
+ }
+ GLint getTransformFeedbackBufferMode() const { return mTransformFeedbackBufferMode; }
+ GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const
+ {
+ ASSERT(uniformBlockIndex < mUniformBlocks.size());
+ return mUniformBlocks[uniformBlockIndex].binding;
+ }
+ GLuint getShaderStorageBlockBinding(GLuint blockIndex) const
+ {
+ ASSERT(blockIndex < mShaderStorageBlocks.size());
+ return mShaderStorageBlocks[blockIndex].binding;
+ }
+ const std::vector<GLsizei> &getTransformFeedbackStrides() const
+ {
+ return mTransformFeedbackStrides;
+ }
+ const std::vector<AtomicCounterBuffer> &getAtomicCounterBuffers() const
+ {
+ return mAtomicCounterBuffers;
+ }
+ const std::vector<InterfaceBlock> &getShaderStorageBlocks() const
+ {
+ return mShaderStorageBlocks;
+ }
+ const LinkedUniform &getUniformByIndex(GLuint index) const
+ {
+ ASSERT(index < static_cast<size_t>(mUniforms.size()));
+ return mUniforms[index];
+ }
+
+ ANGLE_INLINE GLuint getActiveUniformBlockCount() const
+ {
+ return static_cast<GLuint>(mUniformBlocks.size());
+ }
+
+ ANGLE_INLINE GLuint getActiveAtomicCounterBufferCount() const
+ {
+ return static_cast<GLuint>(mAtomicCounterBuffers.size());
+ }
+
+ ANGLE_INLINE GLuint getActiveShaderStorageBlockCount() const
+ {
+ size_t shaderStorageBlocksSize = mShaderStorageBlocks.size();
+ return static_cast<GLuint>(shaderStorageBlocksSize);
+ }
+
+ GLuint getUniformIndexFromImageIndex(GLuint imageIndex) const;
+
+ GLuint getUniformIndexFromSamplerIndex(GLuint samplerIndex) const;
+
+ void saveLinkedStateInfo(const Context *context, const ProgramState &state);
+ const std::vector<sh::ShaderVariable> &getLinkedOutputVaryings(ShaderType shaderType) const
+ {
+ return mLinkedOutputVaryings[shaderType];
+ }
+ const std::vector<sh::ShaderVariable> &getLinkedInputVaryings(ShaderType shaderType) const
+ {
+ return mLinkedInputVaryings[shaderType];
+ }
+
+ const std::vector<sh::ShaderVariable> &getLinkedUniforms(ShaderType shaderType) const
+ {
+ return mLinkedUniforms[shaderType];
+ }
+
+ const std::vector<sh::InterfaceBlock> &getLinkedUniformBlocks(ShaderType shaderType) const
+ {
+ return mLinkedUniformBlocks[shaderType];
+ }
+
+ int getLinkedShaderVersion(ShaderType shaderType) const
+ {
+ return mLinkedShaderVersions[shaderType];
+ }
+
+ bool isYUVOutput() const;
+
+ PrimitiveMode getGeometryShaderInputPrimitiveType() const
+ {
+ return mGeometryShaderInputPrimitiveType;
+ }
+
+ PrimitiveMode getGeometryShaderOutputPrimitiveType() const
+ {
+ return mGeometryShaderOutputPrimitiveType;
+ }
+
+ int getGeometryShaderInvocations() const { return mGeometryShaderInvocations; }
+
+ int getGeometryShaderMaxVertices() const { return mGeometryShaderMaxVertices; }
+
+ GLenum getTessGenMode() const { return mTessGenMode; }
+
+ void resetCachedValidateSamplersResult() { mCachedValidateSamplersResult.reset(); }
+ bool validateSamplers(InfoLog *infoLog, const Caps &caps) const
+ {
+ // Use the cache if:
+ // - we aren't using an info log (which gives the full error).
+ // - The sample mapping hasn't changed and we've already validated.
+ if (infoLog == nullptr && mCachedValidateSamplersResult.valid())
+ {
+ return mCachedValidateSamplersResult.value();
+ }
+
+ return validateSamplersImpl(infoLog, caps);
+ }
+
+ ComponentTypeMask getFragmentOutputsTypeMask() const { return mDrawBufferTypeMask; }
+ DrawBufferMask getActiveOutputVariablesMask() const { return mActiveOutputVariablesMask; }
+
+ bool linkUniforms(const Context *context,
+ const ShaderMap<std::vector<sh::ShaderVariable>> &shaderUniforms,
+ InfoLog &infoLog,
+ const ProgramAliasedBindings &uniformLocationBindings,
+ GLuint *combinedImageUniformsCount,
+ std::vector<UnusedUniform> *unusedUniforms,
+ std::vector<VariableLocation> *uniformLocationsOutOrNull);
+
+ void copyInputsFromProgram(const ProgramState &programState);
+ void copyShaderBuffersFromProgram(const ProgramState &programState, ShaderType shaderType);
+ void clearSamplerBindings();
+ void copySamplerBindingsFromProgram(const ProgramState &programState);
+ void copyImageBindingsFromProgram(const ProgramState &programState);
+ void copyOutputsFromProgram(const ProgramState &programState);
+ void copyUniformsFromProgramMap(const ShaderMap<Program *> &programs);
+
+ private:
+ friend class Program;
+ friend class ProgramPipeline;
+ friend class ProgramState;
+
+ void updateActiveImages(const ProgramExecutable &executable);
+
+ // Scans the sampler bindings for type conflicts with sampler 'textureUnitIndex'.
+ void setSamplerUniformTextureTypeAndFormat(size_t textureUnitIndex,
+ std::vector<SamplerBinding> &samplerBindings);
+
+ bool linkMergedVaryings(const Context *context,
+ const ProgramMergedVaryings &mergedVaryings,
+ const std::vector<std::string> &transformFeedbackVaryingNames,
+ const LinkingVariables &linkingVariables,
+ bool isSeparable,
+ ProgramVaryingPacking *varyingPacking);
+
+ bool linkValidateTransformFeedback(
+ const Context *context,
+ const ProgramMergedVaryings &varyings,
+ ShaderType stage,
+ const std::vector<std::string> &transformFeedbackVaryingNames);
+
+ void gatherTransformFeedbackVaryings(
+ const ProgramMergedVaryings &varyings,
+ ShaderType stage,
+ const std::vector<std::string> &transformFeedbackVaryingNames);
+
+ void updateTransformFeedbackStrides();
+
+ bool validateSamplersImpl(InfoLog *infoLog, const Caps &caps) const;
+
+ bool linkValidateOutputVariables(const Caps &caps,
+ const Extensions &extensions,
+ const Version &version,
+ GLuint combinedImageUniformsCount,
+ GLuint combinedShaderStorageBlocksCount,
+ const std::vector<sh::ShaderVariable> &outputVariables,
+ int fragmentShaderVersion,
+ const ProgramAliasedBindings &fragmentOutputLocations,
+ const ProgramAliasedBindings &fragmentOutputIndices);
+
+ void linkSamplerAndImageBindings(GLuint *combinedImageUniformsCount);
+ bool linkAtomicCounterBuffers(const Context *context, InfoLog &infoLog);
+
+ InfoLog mInfoLog;
+
+ ShaderBitSet mLinkedShaderStages;
+
+ angle::BitSet<MAX_VERTEX_ATTRIBS> mActiveAttribLocationsMask;
+ unsigned int mMaxActiveAttribLocation;
+ ComponentTypeMask mAttributesTypeMask;
+ // mAttributesMask is identical to mActiveAttribLocationsMask with built-in attributes removed.
+ AttributesMask mAttributesMask;
+
+ // Cached mask of active samplers and sampler types.
+ ActiveTextureMask mActiveSamplersMask;
+ ActiveTextureArray<uint32_t> mActiveSamplerRefCounts;
+ ActiveTextureArray<TextureType> mActiveSamplerTypes;
+ ActiveTextureMask mActiveSamplerYUV;
+ ActiveTextureArray<SamplerFormat> mActiveSamplerFormats;
+ ActiveTextureArray<ShaderBitSet> mActiveSamplerShaderBits;
+
+ // Cached mask of active images.
+ ActiveTextureMask mActiveImagesMask;
+ ActiveTextureArray<ShaderBitSet> mActiveImageShaderBits;
+
+ bool mCanDrawWith;
+
+ // Names and mapped names of output variables that are arrays include [0] in the end, similarly
+ // to uniforms.
+ std::vector<sh::ShaderVariable> mOutputVariables;
+ std::vector<VariableLocation> mOutputLocations;
+ DrawBufferMask mActiveOutputVariablesMask;
+ // EXT_blend_func_extended secondary outputs (ones with index 1)
+ std::vector<VariableLocation> mSecondaryOutputLocations;
+ bool mYUVOutput;
+ // Vertex attributes, Fragment input varyings, etc.
+ std::vector<sh::ShaderVariable> mProgramInputs;
+ std::vector<TransformFeedbackVarying> mLinkedTransformFeedbackVaryings;
+ // The size of the data written to each transform feedback buffer per vertex.
+ std::vector<GLsizei> mTransformFeedbackStrides;
+ GLenum mTransformFeedbackBufferMode;
+ // Uniforms are sorted in order:
+ // 1. Non-opaque uniforms
+ // 2. Sampler uniforms
+ // 3. Image uniforms
+ // 4. Atomic counter uniforms
+ // 5. Subpass Input uniforms (Only for Vulkan)
+ // 6. Uniform block uniforms
+ // This makes opaque uniform validation easier, since we don't need a separate list.
+ // For generating the entries and naming them we follow the spec: GLES 3.1 November 2016 section
+ // 7.3.1.1 Naming Active Resources. There's a separate entry for each struct member and each
+ // inner array of an array of arrays. Names and mapped names of uniforms that are arrays include
+ // [0] in the end. This makes implementation of queries simpler.
+ std::vector<LinkedUniform> mUniforms;
+ RangeUI mDefaultUniformRange;
+ RangeUI mSamplerUniformRange;
+ RangeUI mImageUniformRange;
+ RangeUI mAtomicCounterUniformRange;
+ std::vector<InterfaceBlock> mUniformBlocks;
+
+ // For faster iteration on the blocks currently being bound.
+ UniformBlockBindingMask mActiveUniformBlockBindings;
+
+ std::vector<AtomicCounterBuffer> mAtomicCounterBuffers;
+ std::vector<InterfaceBlock> mShaderStorageBlocks;
+
+ RangeUI mFragmentInoutRange;
+ bool mHasDiscard;
+ bool mEnablesPerSampleShading;
+
+ // KHR_blend_equation_advanced supported equation list
+ BlendEquationBitSet mAdvancedBlendEquations;
+
+ // An array of the samplers that are used by the program
+ std::vector<SamplerBinding> mSamplerBindings;
+
+ // An array of the images that are used by the program
+ std::vector<ImageBinding> mImageBindings;
+
+ ShaderMap<std::vector<sh::ShaderVariable>> mLinkedOutputVaryings;
+ ShaderMap<std::vector<sh::ShaderVariable>> mLinkedInputVaryings;
+ ShaderMap<std::vector<sh::ShaderVariable>> mLinkedUniforms;
+ ShaderMap<std::vector<sh::InterfaceBlock>> mLinkedUniformBlocks;
+
+ ShaderMap<int> mLinkedShaderVersions;
+
+ // GL_EXT_geometry_shader.
+ PrimitiveMode mGeometryShaderInputPrimitiveType;
+ PrimitiveMode mGeometryShaderOutputPrimitiveType;
+ int mGeometryShaderInvocations;
+ int mGeometryShaderMaxVertices;
+
+ // GL_EXT_tessellation_shader
+ int mTessControlShaderVertices;
+ GLenum mTessGenMode;
+ GLenum mTessGenSpacing;
+ GLenum mTessGenVertexOrder;
+ GLenum mTessGenPointMode;
+
+ // Fragment output variable base types: FLOAT, INT, or UINT. Ordered by location.
+ std::vector<GLenum> mOutputVariableTypes;
+ ComponentTypeMask mDrawBufferTypeMask;
+
+ // Cache for sampler validation
+ mutable Optional<bool> mCachedValidateSamplersResult;
+};
+} // namespace gl
+
+#endif // LIBANGLE_PROGRAMEXECUTABLE_H_
diff --git a/gfx/angle/checkout/src/libANGLE/ProgramLinkedResources.cpp b/gfx/angle/checkout/src/libANGLE/ProgramLinkedResources.cpp
new file mode 100644
index 0000000000..11000fdabc
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/ProgramLinkedResources.cpp
@@ -0,0 +1,2377 @@
+//
+// Copyright 2017 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.
+//
+
+// ProgramLinkedResources.cpp: implements link-time checks for default block uniforms, and generates
+// uniform locations. Populates data structures related to uniforms so that they can be stored in
+// program state.
+
+#include "libANGLE/ProgramLinkedResources.h"
+
+#include "common/string_utils.h"
+#include "common/utilities.h"
+#include "libANGLE/Caps.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Shader.h"
+#include "libANGLE/features.h"
+
+namespace gl
+{
+namespace
+{
+LinkedUniform *FindUniform(std::vector<LinkedUniform> &list, const std::string &name)
+{
+ for (LinkedUniform &uniform : list)
+ {
+ if (uniform.name == name)
+ return &uniform;
+ }
+
+ return nullptr;
+}
+
+template <typename VarT>
+void SetActive(std::vector<VarT> *list, const std::string &name, ShaderType shaderType, bool active)
+{
+ for (auto &variable : *list)
+ {
+ if (variable.name == name)
+ {
+ variable.setActive(shaderType, active);
+ return;
+ }
+ }
+}
+
+// GLSL ES Spec 3.00.3, section 4.3.5.
+LinkMismatchError LinkValidateUniforms(const sh::ShaderVariable &uniform1,
+ const sh::ShaderVariable &uniform2,
+ std::string *mismatchedStructFieldName)
+{
+#if ANGLE_PROGRAM_LINK_VALIDATE_UNIFORM_PRECISION == ANGLE_ENABLED
+ const bool validatePrecisionFeature = true;
+#else
+ const bool validatePrecisionFeature = false;
+#endif
+
+ // Validate precision match of uniforms iff they are statically used
+ bool validatePrecision = uniform1.staticUse && uniform2.staticUse && validatePrecisionFeature;
+ LinkMismatchError linkError = LinkValidateProgramVariables(
+ uniform1, uniform2, validatePrecision, false, false, mismatchedStructFieldName);
+ if (linkError != LinkMismatchError::NO_MISMATCH)
+ {
+ return linkError;
+ }
+
+ // GLSL ES Spec 3.10.4, section 4.4.5.
+ if (uniform1.binding != -1 && uniform2.binding != -1 && uniform1.binding != uniform2.binding)
+ {
+ return LinkMismatchError::BINDING_MISMATCH;
+ }
+
+ // GLSL ES Spec 3.10.4, section 9.2.1.
+ if (uniform1.location != -1 && uniform2.location != -1 &&
+ uniform1.location != uniform2.location)
+ {
+ return LinkMismatchError::LOCATION_MISMATCH;
+ }
+ if (uniform1.offset != uniform2.offset)
+ {
+ return LinkMismatchError::OFFSET_MISMATCH;
+ }
+
+ return LinkMismatchError::NO_MISMATCH;
+}
+
+GLuint GetMaximumShaderUniformVectors(ShaderType shaderType, const Caps &caps)
+{
+ switch (shaderType)
+ {
+ case ShaderType::Vertex:
+ return static_cast<GLuint>(caps.maxVertexUniformVectors);
+ case ShaderType::Fragment:
+ return static_cast<GLuint>(caps.maxFragmentUniformVectors);
+
+ case ShaderType::Compute:
+ case ShaderType::Geometry:
+ case ShaderType::TessControl:
+ case ShaderType::TessEvaluation:
+ return static_cast<GLuint>(caps.maxShaderUniformComponents[shaderType]) / 4;
+
+ default:
+ UNREACHABLE();
+ return 0u;
+ }
+}
+
+enum class UniformType : uint8_t
+{
+ Variable = 0,
+ Sampler = 1,
+ Image = 2,
+ AtomicCounter = 3,
+
+ InvalidEnum = 4,
+ EnumCount = 4,
+};
+
+const char *GetUniformResourceNameString(UniformType uniformType)
+{
+ switch (uniformType)
+ {
+ case UniformType::Variable:
+ return "uniform";
+ case UniformType::Sampler:
+ return "texture image unit";
+ case UniformType::Image:
+ return "image uniform";
+ case UniformType::AtomicCounter:
+ return "atomic counter";
+ default:
+ UNREACHABLE();
+ return "";
+ }
+}
+
+std::string GetUniformResourceLimitName(ShaderType shaderType, UniformType uniformType)
+{
+ // Special case: MAX_TEXTURE_IMAGE_UNITS (no "MAX_FRAGMENT_TEXTURE_IMAGE_UNITS")
+ if (shaderType == ShaderType::Fragment && uniformType == UniformType::Sampler)
+ {
+ return "MAX_TEXTURE_IMAGE_UNITS";
+ }
+
+ std::ostringstream ostream;
+ ostream << "MAX_" << GetShaderTypeString(shaderType) << "_";
+
+ switch (uniformType)
+ {
+ case UniformType::Variable:
+ // For vertex and fragment shaders, ES 2.0 only defines MAX_VERTEX_UNIFORM_VECTORS and
+ // MAX_FRAGMENT_UNIFORM_VECTORS ([OpenGL ES 2.0] Table 6.20).
+ if (shaderType == ShaderType::Vertex || shaderType == ShaderType::Fragment)
+ {
+ ostream << "UNIFORM_VECTORS";
+ break;
+ }
+ // For compute and geometry shaders, there are no definitions on
+ // "MAX_COMPUTE_UNIFORM_VECTORS" or "MAX_GEOMETRY_UNIFORM_VECTORS_EXT"
+ // ([OpenGL ES 3.1] Table 20.45, [EXT_geometry_shader] Table 20.43gs).
+ else
+ {
+ ostream << "UNIFORM_COMPONENTS";
+ }
+ break;
+ case UniformType::Sampler:
+ ostream << "TEXTURE_IMAGE_UNITS";
+ break;
+ case UniformType::Image:
+ ostream << "IMAGE_UNIFORMS";
+ break;
+ case UniformType::AtomicCounter:
+ ostream << "ATOMIC_COUNTERS";
+ break;
+ default:
+ UNREACHABLE();
+ return "";
+ }
+
+ if (shaderType == ShaderType::Geometry)
+ {
+ ostream << "_EXT";
+ }
+
+ return ostream.str();
+}
+
+void LogUniformsExceedLimit(ShaderType shaderType,
+ UniformType uniformType,
+ GLuint limit,
+ InfoLog &infoLog)
+{
+ infoLog << GetShaderTypeString(shaderType) << " shader "
+ << GetUniformResourceNameString(uniformType) << "s count exceeds "
+ << GetUniformResourceLimitName(shaderType, uniformType) << "(" << limit << ")";
+}
+
+// The purpose of this visitor is to capture the uniforms in a uniform block. Each new uniform is
+// added to "uniformsOut".
+class UniformBlockEncodingVisitor : public sh::VariableNameVisitor
+{
+ public:
+ UniformBlockEncodingVisitor(const GetBlockMemberInfoFunc &getMemberInfo,
+ const std::string &namePrefix,
+ const std::string &mappedNamePrefix,
+ std::vector<LinkedUniform> *uniformsOut,
+ ShaderType shaderType,
+ int blockIndex)
+ : sh::VariableNameVisitor(namePrefix, mappedNamePrefix),
+ mGetMemberInfo(getMemberInfo),
+ mUniformsOut(uniformsOut),
+ mShaderType(shaderType),
+ mBlockIndex(blockIndex)
+ {}
+
+ void visitNamedVariable(const sh::ShaderVariable &variable,
+ bool isRowMajor,
+ const std::string &name,
+ const std::string &mappedName,
+ const std::vector<unsigned int> &arraySizes) override
+ {
+ // If getBlockMemberInfo returns false, the variable is optimized out.
+ sh::BlockMemberInfo variableInfo;
+ if (!mGetMemberInfo(name, mappedName, &variableInfo))
+ return;
+
+ std::string nameWithArrayIndex = name;
+ std::string mappedNameWithArrayIndex = mappedName;
+
+ if (variable.isArray())
+ {
+ nameWithArrayIndex += "[0]";
+ mappedNameWithArrayIndex += "[0]";
+ }
+
+ if (mBlockIndex == -1)
+ {
+ SetActive(mUniformsOut, nameWithArrayIndex, mShaderType, variable.active);
+ return;
+ }
+
+ LinkedUniform newUniform(variable.type, variable.precision, nameWithArrayIndex,
+ variable.arraySizes, -1, -1, -1, mBlockIndex, variableInfo);
+ newUniform.mappedName = mappedNameWithArrayIndex;
+ newUniform.setActive(mShaderType, variable.active);
+
+ // Since block uniforms have no location, we don't need to store them in the uniform
+ // locations list.
+ mUniformsOut->push_back(newUniform);
+ }
+
+ private:
+ const GetBlockMemberInfoFunc &mGetMemberInfo;
+ std::vector<LinkedUniform> *mUniformsOut;
+ const ShaderType mShaderType;
+ const int mBlockIndex;
+};
+
+// The purpose of this visitor is to capture the buffer variables in a shader storage block. Each
+// new buffer variable is stored in "bufferVariablesOut".
+class ShaderStorageBlockVisitor : public sh::BlockEncoderVisitor
+{
+ public:
+ ShaderStorageBlockVisitor(const GetBlockMemberInfoFunc &getMemberInfo,
+ const std::string &namePrefix,
+ const std::string &mappedNamePrefix,
+ std::vector<BufferVariable> *bufferVariablesOut,
+ ShaderType shaderType,
+ int blockIndex)
+ : sh::BlockEncoderVisitor(namePrefix, mappedNamePrefix, &mStubEncoder),
+ mGetMemberInfo(getMemberInfo),
+ mBufferVariablesOut(bufferVariablesOut),
+ mShaderType(shaderType),
+ mBlockIndex(blockIndex)
+ {}
+
+ void visitNamedVariable(const sh::ShaderVariable &variable,
+ bool isRowMajor,
+ const std::string &name,
+ const std::string &mappedName,
+ const std::vector<unsigned int> &arraySizes) override
+ {
+ if (mSkipEnabled)
+ return;
+
+ // If getBlockMemberInfo returns false, the variable is optimized out.
+ sh::BlockMemberInfo variableInfo;
+ if (!mGetMemberInfo(name, mappedName, &variableInfo))
+ return;
+
+ std::string nameWithArrayIndex = name;
+ std::string mappedNameWithArrayIndex = mappedName;
+
+ if (variable.isArray())
+ {
+ nameWithArrayIndex += "[0]";
+ mappedNameWithArrayIndex += "[0]";
+ }
+
+ if (mBlockIndex == -1)
+ {
+ SetActive(mBufferVariablesOut, nameWithArrayIndex, mShaderType, variable.active);
+ return;
+ }
+
+ BufferVariable newBufferVariable(variable.type, variable.precision, nameWithArrayIndex,
+ variable.arraySizes, mBlockIndex, variableInfo);
+ newBufferVariable.mappedName = mappedNameWithArrayIndex;
+ newBufferVariable.setActive(mShaderType, variable.active);
+
+ newBufferVariable.topLevelArraySize = mTopLevelArraySize;
+
+ mBufferVariablesOut->push_back(newBufferVariable);
+ }
+
+ private:
+ const GetBlockMemberInfoFunc &mGetMemberInfo;
+ std::vector<BufferVariable> *mBufferVariablesOut;
+ const ShaderType mShaderType;
+ const int mBlockIndex;
+ sh::StubBlockEncoder mStubEncoder;
+};
+
+struct ShaderUniformCount
+{
+ unsigned int vectorCount = 0;
+ unsigned int samplerCount = 0;
+ unsigned int imageCount = 0;
+ unsigned int atomicCounterCount = 0;
+ unsigned int fragmentInOutCount = 0;
+};
+
+ShaderUniformCount &operator+=(ShaderUniformCount &lhs, const ShaderUniformCount &rhs)
+{
+ lhs.vectorCount += rhs.vectorCount;
+ lhs.samplerCount += rhs.samplerCount;
+ lhs.imageCount += rhs.imageCount;
+ lhs.atomicCounterCount += rhs.atomicCounterCount;
+ lhs.fragmentInOutCount += rhs.fragmentInOutCount;
+ return lhs;
+}
+
+// The purpose of this visitor is to flatten struct and array uniforms into a list of singleton
+// uniforms. They are stored in separate lists by uniform type so they can be sorted in order.
+// Counts for each uniform category are stored and can be queried with "getCounts".
+class FlattenUniformVisitor : public sh::VariableNameVisitor
+{
+ public:
+ FlattenUniformVisitor(ShaderType shaderType,
+ const sh::ShaderVariable &uniform,
+ std::vector<LinkedUniform> *uniforms,
+ std::vector<LinkedUniform> *samplerUniforms,
+ std::vector<LinkedUniform> *imageUniforms,
+ std::vector<LinkedUniform> *atomicCounterUniforms,
+ std::vector<LinkedUniform> *inputAttachmentUniforms,
+ std::vector<UnusedUniform> *unusedUniforms)
+ : sh::VariableNameVisitor("", ""),
+ mShaderType(shaderType),
+ mMarkActive(uniform.active),
+ mMarkStaticUse(uniform.staticUse),
+ mBinding(uniform.binding),
+ mOffset(uniform.offset),
+ mLocation(uniform.location),
+ mUniforms(uniforms),
+ mSamplerUniforms(samplerUniforms),
+ mImageUniforms(imageUniforms),
+ mAtomicCounterUniforms(atomicCounterUniforms),
+ mInputAttachmentUniforms(inputAttachmentUniforms),
+ mUnusedUniforms(unusedUniforms)
+ {}
+
+ void visitNamedOpaqueObject(const sh::ShaderVariable &variable,
+ const std::string &name,
+ const std::string &mappedName,
+ const std::vector<unsigned int> &arraySizes) override
+ {
+ visitNamedVariable(variable, false, name, mappedName, arraySizes);
+ }
+
+ void visitNamedVariable(const sh::ShaderVariable &variable,
+ bool isRowMajor,
+ const std::string &name,
+ const std::string &mappedName,
+ const std::vector<unsigned int> &arraySizes) override
+ {
+ bool isSampler = IsSamplerType(variable.type);
+ bool isImage = IsImageType(variable.type);
+ bool isAtomicCounter = IsAtomicCounterType(variable.type);
+ bool isFragmentInOut = variable.isFragmentInOut;
+ std::vector<LinkedUniform> *uniformList = mUniforms;
+ if (isSampler)
+ {
+ uniformList = mSamplerUniforms;
+ }
+ else if (isImage)
+ {
+ uniformList = mImageUniforms;
+ }
+ else if (isAtomicCounter)
+ {
+ uniformList = mAtomicCounterUniforms;
+ }
+ else if (isFragmentInOut)
+ {
+ uniformList = mInputAttachmentUniforms;
+ }
+
+ std::string fullNameWithArrayIndex(name);
+ std::string fullMappedNameWithArrayIndex(mappedName);
+
+ if (variable.isArray())
+ {
+ // We're following the GLES 3.1 November 2016 spec section 7.3.1.1 Naming Active
+ // Resources and including [0] at the end of array variable names.
+ fullNameWithArrayIndex += "[0]";
+ fullMappedNameWithArrayIndex += "[0]";
+ }
+
+ LinkedUniform *existingUniform = FindUniform(*uniformList, fullNameWithArrayIndex);
+ if (existingUniform)
+ {
+ if (getBinding() != -1)
+ {
+ existingUniform->binding = getBinding();
+ }
+ if (getOffset() != -1)
+ {
+ existingUniform->offset = getOffset();
+ }
+ if (mLocation != -1)
+ {
+ existingUniform->location = mLocation;
+ }
+ if (mMarkActive)
+ {
+ existingUniform->active = true;
+ existingUniform->setActive(mShaderType, true);
+ }
+ if (mMarkStaticUse)
+ {
+ existingUniform->staticUse = true;
+ }
+ }
+ else
+ {
+ LinkedUniform linkedUniform(variable.type, variable.precision, fullNameWithArrayIndex,
+ variable.arraySizes, getBinding(), getOffset(), mLocation,
+ -1, sh::kDefaultBlockMemberInfo);
+ linkedUniform.mappedName = fullMappedNameWithArrayIndex;
+ linkedUniform.active = mMarkActive;
+ linkedUniform.staticUse = mMarkStaticUse;
+ linkedUniform.outerArraySizes = arraySizes;
+ linkedUniform.texelFetchStaticUse = variable.texelFetchStaticUse;
+ linkedUniform.imageUnitFormat = variable.imageUnitFormat;
+ linkedUniform.isFragmentInOut = variable.isFragmentInOut;
+ if (variable.hasParentArrayIndex())
+ {
+ linkedUniform.setParentArrayIndex(variable.parentArrayIndex());
+ }
+
+ std::vector<unsigned int> arrayDims = arraySizes;
+ ASSERT(variable.arraySizes.size() == 1 || variable.arraySizes.size() == 0);
+ arrayDims.push_back(variable.arraySizes.empty() ? 1 : variable.arraySizes[0]);
+
+ size_t numDimensions = arraySizes.size();
+ uint32_t arrayStride = 1;
+ for (size_t dimension = numDimensions; dimension > 0;)
+ {
+ --dimension;
+ arrayStride *= arrayDims[dimension + 1];
+ linkedUniform.outerArrayOffset += arrayStride * mArrayElementStack[dimension];
+ }
+
+ if (mMarkActive)
+ {
+ linkedUniform.setActive(mShaderType, true);
+ }
+ else
+ {
+ mUnusedUniforms->emplace_back(
+ linkedUniform.name, linkedUniform.isSampler(), linkedUniform.isImage(),
+ linkedUniform.isAtomicCounter(), linkedUniform.isFragmentInOut);
+ }
+
+ uniformList->push_back(linkedUniform);
+ }
+
+ unsigned int elementCount = variable.getBasicTypeElementCount();
+
+ // Samplers and images aren't "real" uniforms, so they don't count towards register usage.
+ // Likewise, don't count "real" uniforms towards opaque count.
+
+ if (!IsOpaqueType(variable.type) && !isFragmentInOut)
+ {
+ mUniformCount.vectorCount += VariableRegisterCount(variable.type) * elementCount;
+ }
+
+ mUniformCount.samplerCount += (isSampler ? elementCount : 0);
+ mUniformCount.imageCount += (isImage ? elementCount : 0);
+ mUniformCount.atomicCounterCount += (isAtomicCounter ? elementCount : 0);
+ mUniformCount.fragmentInOutCount += (isFragmentInOut ? elementCount : 0);
+
+ if (mLocation != -1)
+ {
+ mLocation += elementCount;
+ }
+ }
+
+ void enterStructAccess(const sh::ShaderVariable &structVar, bool isRowMajor) override
+ {
+ mStructStackSize++;
+ sh::VariableNameVisitor::enterStructAccess(structVar, isRowMajor);
+ }
+
+ void exitStructAccess(const sh::ShaderVariable &structVar, bool isRowMajor) override
+ {
+ mStructStackSize--;
+ sh::VariableNameVisitor::exitStructAccess(structVar, isRowMajor);
+ }
+
+ void enterArrayElement(const sh::ShaderVariable &arrayVar, unsigned int arrayElement) override
+ {
+ mArrayElementStack.push_back(arrayElement);
+ sh::VariableNameVisitor::enterArrayElement(arrayVar, arrayElement);
+ }
+
+ void exitArrayElement(const sh::ShaderVariable &arrayVar, unsigned int arrayElement) override
+ {
+ mArrayElementStack.pop_back();
+ sh::VariableNameVisitor::exitArrayElement(arrayVar, arrayElement);
+ }
+
+ ShaderUniformCount getCounts() const { return mUniformCount; }
+
+ private:
+ int getBinding() const { return mStructStackSize == 0 ? mBinding : -1; }
+ int getOffset() const { return mStructStackSize == 0 ? mOffset : -1; }
+
+ ShaderType mShaderType;
+
+ // Active and StaticUse are given separately because they are tracked at struct granularity.
+ bool mMarkActive;
+ bool mMarkStaticUse;
+ int mBinding;
+ int mOffset;
+ int mLocation;
+ std::vector<LinkedUniform> *mUniforms;
+ std::vector<LinkedUniform> *mSamplerUniforms;
+ std::vector<LinkedUniform> *mImageUniforms;
+ std::vector<LinkedUniform> *mAtomicCounterUniforms;
+ std::vector<LinkedUniform> *mInputAttachmentUniforms;
+ std::vector<UnusedUniform> *mUnusedUniforms;
+ std::vector<unsigned int> mArrayElementStack;
+ ShaderUniformCount mUniformCount;
+ unsigned int mStructStackSize = 0;
+};
+
+class InterfaceBlockInfo final : angle::NonCopyable
+{
+ public:
+ InterfaceBlockInfo(CustomBlockLayoutEncoderFactory *customEncoderFactory)
+ : mCustomEncoderFactory(customEncoderFactory)
+ {}
+
+ void getShaderBlockInfo(const std::vector<sh::InterfaceBlock> &interfaceBlocks);
+
+ bool getBlockSize(const std::string &name, const std::string &mappedName, size_t *sizeOut);
+ bool getBlockMemberInfo(const std::string &name,
+ const std::string &mappedName,
+ sh::BlockMemberInfo *infoOut);
+
+ private:
+ size_t getBlockInfo(const sh::InterfaceBlock &interfaceBlock);
+
+ std::map<std::string, size_t> mBlockSizes;
+ sh::BlockLayoutMap mBlockLayout;
+ // Based on the interface block layout, the std140 or std430 encoders are used. On some
+ // platforms (currently only D3D), there could be another non-standard encoder used.
+ CustomBlockLayoutEncoderFactory *mCustomEncoderFactory;
+};
+
+void InterfaceBlockInfo::getShaderBlockInfo(const std::vector<sh::InterfaceBlock> &interfaceBlocks)
+{
+ for (const sh::InterfaceBlock &interfaceBlock : interfaceBlocks)
+ {
+ if (!IsActiveInterfaceBlock(interfaceBlock))
+ continue;
+
+ if (mBlockSizes.count(interfaceBlock.name) > 0)
+ continue;
+
+ size_t dataSize = getBlockInfo(interfaceBlock);
+ mBlockSizes[interfaceBlock.name] = dataSize;
+ }
+}
+
+size_t InterfaceBlockInfo::getBlockInfo(const sh::InterfaceBlock &interfaceBlock)
+{
+ ASSERT(IsActiveInterfaceBlock(interfaceBlock));
+
+ // define member uniforms
+ sh::Std140BlockEncoder std140Encoder;
+ sh::Std430BlockEncoder std430Encoder;
+ sh::BlockLayoutEncoder *customEncoder = nullptr;
+ sh::BlockLayoutEncoder *encoder = nullptr;
+
+ if (interfaceBlock.layout == sh::BLOCKLAYOUT_STD140)
+ {
+ encoder = &std140Encoder;
+ }
+ else if (interfaceBlock.layout == sh::BLOCKLAYOUT_STD430)
+ {
+ encoder = &std430Encoder;
+ }
+ else if (mCustomEncoderFactory)
+ {
+ encoder = customEncoder = mCustomEncoderFactory->makeEncoder();
+ }
+ else
+ {
+ UNREACHABLE();
+ return 0;
+ }
+
+ sh::GetInterfaceBlockInfo(interfaceBlock.fields, interfaceBlock.fieldPrefix(), encoder,
+ &mBlockLayout);
+
+ size_t offset = encoder->getCurrentOffset();
+
+ SafeDelete(customEncoder);
+
+ return offset;
+}
+
+bool InterfaceBlockInfo::getBlockSize(const std::string &name,
+ const std::string &mappedName,
+ size_t *sizeOut)
+{
+ size_t nameLengthWithoutArrayIndex;
+ ParseArrayIndex(name, &nameLengthWithoutArrayIndex);
+ std::string baseName = name.substr(0u, nameLengthWithoutArrayIndex);
+ auto sizeIter = mBlockSizes.find(baseName);
+ if (sizeIter == mBlockSizes.end())
+ {
+ *sizeOut = 0;
+ return false;
+ }
+
+ *sizeOut = sizeIter->second;
+ return true;
+}
+
+bool InterfaceBlockInfo::getBlockMemberInfo(const std::string &name,
+ const std::string &mappedName,
+ sh::BlockMemberInfo *infoOut)
+{
+ auto infoIter = mBlockLayout.find(name);
+ if (infoIter == mBlockLayout.end())
+ {
+ *infoOut = sh::kDefaultBlockMemberInfo;
+ return false;
+ }
+
+ *infoOut = infoIter->second;
+ return true;
+}
+
+void GetFilteredVaryings(const std::vector<sh::ShaderVariable> &varyings,
+ std::vector<const sh::ShaderVariable *> *filteredVaryingsOut)
+{
+ for (const sh::ShaderVariable &varying : varyings)
+ {
+ // Built-in varyings obey special rules
+ if (varying.isBuiltIn())
+ {
+ continue;
+ }
+
+ filteredVaryingsOut->push_back(&varying);
+ }
+}
+
+LinkMismatchError LinkValidateVaryings(const sh::ShaderVariable &outputVarying,
+ const sh::ShaderVariable &inputVarying,
+ int shaderVersion,
+ ShaderType frontShaderType,
+ ShaderType backShaderType,
+ bool isSeparable,
+ std::string *mismatchedStructFieldName)
+{
+ // [ES 3.2 spec] 7.4.1 Shader Interface Matching:
+ // Tessellation control shader per-vertex output variables and blocks and tessellation control,
+ // tessellation evaluation, and geometry shader per-vertex input variables and blocks are
+ // required to be declared as arrays, with each element representing input or output values for
+ // a single vertex of a multi-vertex primitive. For the purposes of interface matching, such
+ // variables and blocks are treated as though they were not declared as arrays.
+ bool treatOutputAsNonArray =
+ (frontShaderType == ShaderType::TessControl && !outputVarying.isPatch);
+ bool treatInputAsNonArray =
+ ((backShaderType == ShaderType::TessControl ||
+ backShaderType == ShaderType::TessEvaluation || backShaderType == ShaderType::Geometry) &&
+ !inputVarying.isPatch);
+
+ // Skip the validation on the array sizes between a vertex output varying and a geometry input
+ // varying as it has been done before.
+ bool validatePrecision = isSeparable && (shaderVersion > 100);
+ LinkMismatchError linkError = LinkValidateProgramVariables(
+ outputVarying, inputVarying, validatePrecision, treatOutputAsNonArray, treatInputAsNonArray,
+ mismatchedStructFieldName);
+ if (linkError != LinkMismatchError::NO_MISMATCH)
+ {
+ return linkError;
+ }
+
+ // Explicit locations must match if the names match.
+ if (outputVarying.isSameNameAtLinkTime(inputVarying) &&
+ outputVarying.location != inputVarying.location)
+ {
+ return LinkMismatchError::LOCATION_MISMATCH;
+ }
+
+ if (!sh::InterpolationTypesMatch(outputVarying.interpolation, inputVarying.interpolation))
+ {
+ return LinkMismatchError::INTERPOLATION_TYPE_MISMATCH;
+ }
+
+ if (shaderVersion == 100 && outputVarying.isInvariant != inputVarying.isInvariant)
+ {
+ return LinkMismatchError::INVARIANCE_MISMATCH;
+ }
+
+ return LinkMismatchError::NO_MISMATCH;
+}
+
+bool DoShaderVariablesMatch(int frontShaderVersion,
+ ShaderType frontShaderType,
+ ShaderType backShaderType,
+ const sh::ShaderVariable &input,
+ const sh::ShaderVariable &output,
+ bool isSeparable,
+ gl::InfoLog &infoLog)
+{
+ bool namesMatch = input.isSameNameAtLinkTime(output);
+ bool locationsMatch = input.location != -1 && input.location == output.location;
+
+ // An output block is considered to match an input block in the subsequent
+ // shader if the two blocks have the same block name, and the members of the
+ // block match exactly in name, type, qualification, and declaration order.
+ //
+ // - For the purposes of shader interface matching, the gl_PointSize
+ // member of the intrinsically declared gl_PerVertex shader interface
+ // block is ignored.
+ // - Output blocks that do not match in name, but have a location and match
+ // in every other way listed above may be considered to match by some
+ // implementations, but not all - so this behaviour should not be relied
+ // upon.
+
+ // An output variable is considered to match an input variable in the subsequent
+ // shader if:
+ //
+ // - the two variables match in name, type, and qualification; or
+ // - the two variables are declared with the same location qualifier and
+ // match in type and qualification.
+
+ if (namesMatch || locationsMatch)
+ {
+ std::string mismatchedStructFieldName;
+ LinkMismatchError linkError =
+ LinkValidateVaryings(output, input, frontShaderVersion, frontShaderType, backShaderType,
+ isSeparable, &mismatchedStructFieldName);
+ if (linkError != LinkMismatchError::NO_MISMATCH)
+ {
+ LogLinkMismatch(infoLog, input.name, "varying", linkError, mismatchedStructFieldName,
+ frontShaderType, backShaderType);
+ return false;
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+const char *GetInterfaceBlockTypeString(sh::BlockType blockType)
+{
+ switch (blockType)
+ {
+ case sh::BlockType::BLOCK_UNIFORM:
+ return "uniform block";
+ case sh::BlockType::BLOCK_BUFFER:
+ return "shader storage block";
+ default:
+ UNREACHABLE();
+ return "";
+ }
+}
+
+std::string GetInterfaceBlockLimitName(ShaderType shaderType, sh::BlockType blockType)
+{
+ std::ostringstream stream;
+ stream << "GL_MAX_" << GetShaderTypeString(shaderType) << "_";
+
+ switch (blockType)
+ {
+ case sh::BlockType::BLOCK_UNIFORM:
+ stream << "UNIFORM_BUFFERS";
+ break;
+ case sh::BlockType::BLOCK_BUFFER:
+ stream << "SHADER_STORAGE_BLOCKS";
+ break;
+ default:
+ UNREACHABLE();
+ return "";
+ }
+
+ if (shaderType == ShaderType::Geometry)
+ {
+ stream << "_EXT";
+ }
+
+ return stream.str();
+}
+
+void LogInterfaceBlocksExceedLimit(InfoLog &infoLog,
+ ShaderType shaderType,
+ sh::BlockType blockType,
+ GLuint limit)
+{
+ infoLog << GetShaderTypeString(shaderType) << " shader "
+ << GetInterfaceBlockTypeString(blockType) << " count exceeds "
+ << GetInterfaceBlockLimitName(shaderType, blockType) << " (" << limit << ")";
+}
+
+bool ValidateInterfaceBlocksCount(GLuint maxInterfaceBlocks,
+ const std::vector<sh::InterfaceBlock> &interfaceBlocks,
+ ShaderType shaderType,
+ sh::BlockType blockType,
+ GLuint *combinedInterfaceBlocksCount,
+ InfoLog &infoLog)
+{
+ GLuint blockCount = 0;
+ for (const sh::InterfaceBlock &block : interfaceBlocks)
+ {
+ if (IsActiveInterfaceBlock(block))
+ {
+ blockCount += std::max(block.arraySize, 1u);
+ if (blockCount > maxInterfaceBlocks)
+ {
+ LogInterfaceBlocksExceedLimit(infoLog, shaderType, blockType, maxInterfaceBlocks);
+ return false;
+ }
+ }
+ }
+
+ // [OpenGL ES 3.1] Chapter 7.6.2 Page 105:
+ // If a uniform block is used by multiple shader stages, each such use counts separately
+ // against this combined limit.
+ // [OpenGL ES 3.1] Chapter 7.8 Page 111:
+ // If a shader storage block in a program is referenced by multiple shaders, each such
+ // reference counts separately against this combined limit.
+ if (combinedInterfaceBlocksCount)
+ {
+ *combinedInterfaceBlocksCount += blockCount;
+ }
+
+ return true;
+}
+} // anonymous namespace
+
+UniformLinker::UniformLinker(const ShaderBitSet &activeShaderStages,
+ const ShaderMap<std::vector<sh::ShaderVariable>> &shaderUniforms)
+ : mActiveShaderStages(activeShaderStages), mShaderUniforms(shaderUniforms)
+{}
+
+UniformLinker::~UniformLinker() = default;
+
+void UniformLinker::getResults(std::vector<LinkedUniform> *uniforms,
+ std::vector<UnusedUniform> *unusedUniformsOutOrNull,
+ std::vector<VariableLocation> *uniformLocationsOutOrNull)
+{
+ uniforms->swap(mUniforms);
+
+ if (unusedUniformsOutOrNull)
+ {
+ unusedUniformsOutOrNull->swap(mUnusedUniforms);
+ }
+
+ if (uniformLocationsOutOrNull)
+ {
+ uniformLocationsOutOrNull->swap(mUniformLocations);
+ }
+}
+
+bool UniformLinker::link(const Caps &caps,
+ InfoLog &infoLog,
+ const ProgramAliasedBindings &uniformLocationBindings)
+{
+ if (mActiveShaderStages[ShaderType::Vertex] && mActiveShaderStages[ShaderType::Fragment])
+ {
+ if (!validateGraphicsUniforms(infoLog))
+ {
+ return false;
+ }
+ }
+
+ // Flatten the uniforms list (nested fields) into a simple list (no nesting).
+ // Also check the maximum uniform vector and sampler counts.
+ if (!flattenUniformsAndCheckCaps(caps, infoLog))
+ {
+ return false;
+ }
+
+ if (!checkMaxCombinedAtomicCounters(caps, infoLog))
+ {
+ return false;
+ }
+
+ if (!indexUniforms(infoLog, uniformLocationBindings))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool UniformLinker::validateGraphicsUniforms(InfoLog &infoLog) const
+{
+ // Check that uniforms defined in the graphics shaders are identical
+ std::map<std::string, ShaderUniform> linkedUniforms;
+
+ for (const ShaderType shaderType : mActiveShaderStages)
+ {
+ if (shaderType == ShaderType::Vertex)
+ {
+ for (const sh::ShaderVariable &vertexUniform : mShaderUniforms[ShaderType::Vertex])
+ {
+ linkedUniforms[vertexUniform.name] =
+ std::make_pair(ShaderType::Vertex, &vertexUniform);
+ }
+ }
+ else
+ {
+ bool isLastShader = (shaderType == ShaderType::Fragment);
+ if (!validateGraphicsUniformsPerShader(shaderType, !isLastShader, &linkedUniforms,
+ infoLog))
+ {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+bool UniformLinker::validateGraphicsUniformsPerShader(
+ ShaderType shaderToLink,
+ bool extendLinkedUniforms,
+ std::map<std::string, ShaderUniform> *linkedUniforms,
+ InfoLog &infoLog) const
+{
+ ASSERT(mActiveShaderStages[shaderToLink] && linkedUniforms);
+
+ for (const sh::ShaderVariable &uniform : mShaderUniforms[shaderToLink])
+ {
+ const auto &entry = linkedUniforms->find(uniform.name);
+ if (entry != linkedUniforms->end())
+ {
+ const sh::ShaderVariable &linkedUniform = *(entry->second.second);
+ std::string mismatchedStructFieldName;
+ LinkMismatchError linkError =
+ LinkValidateUniforms(uniform, linkedUniform, &mismatchedStructFieldName);
+ if (linkError != LinkMismatchError::NO_MISMATCH)
+ {
+ LogLinkMismatch(infoLog, uniform.name, "uniform", linkError,
+ mismatchedStructFieldName, entry->second.first, shaderToLink);
+ return false;
+ }
+ }
+ else if (extendLinkedUniforms)
+ {
+ (*linkedUniforms)[uniform.name] = std::make_pair(shaderToLink, &uniform);
+ }
+ }
+
+ return true;
+}
+
+bool UniformLinker::indexUniforms(InfoLog &infoLog,
+ const ProgramAliasedBindings &uniformLocationBindings)
+{
+ // Locations which have been allocated for an unused uniform.
+ std::set<GLuint> ignoredLocations;
+
+ int maxUniformLocation = -1;
+
+ // Gather uniform locations that have been set either using the bindUniformLocationCHROMIUM API
+ // or by using a location layout qualifier and check conflicts between them.
+ if (!gatherUniformLocationsAndCheckConflicts(infoLog, uniformLocationBindings,
+ &ignoredLocations, &maxUniformLocation))
+ {
+ return false;
+ }
+
+ // Conflicts have been checked, now we can prune non-statically used uniforms. Code further down
+ // the line relies on only having statically used uniforms in mUniforms.
+ pruneUnusedUniforms();
+
+ // Gather uniforms that have their location pre-set and uniforms that don't yet have a location.
+ std::vector<VariableLocation> unlocatedUniforms;
+ std::map<GLuint, VariableLocation> preLocatedUniforms;
+
+ for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); uniformIndex++)
+ {
+ const LinkedUniform &uniform = mUniforms[uniformIndex];
+
+ if ((uniform.isBuiltIn() && !uniform.isEmulatedBuiltIn()) ||
+ IsAtomicCounterType(uniform.type) || uniform.isFragmentInOut)
+ {
+ continue;
+ }
+
+ int preSetLocation = uniformLocationBindings.getBinding(uniform);
+ int shaderLocation = uniform.location;
+
+ if (shaderLocation != -1)
+ {
+ preSetLocation = shaderLocation;
+ }
+
+ unsigned int elementCount = uniform.getBasicTypeElementCount();
+ for (unsigned int arrayIndex = 0; arrayIndex < elementCount; arrayIndex++)
+ {
+ VariableLocation location(arrayIndex, static_cast<unsigned int>(uniformIndex));
+
+ if ((arrayIndex == 0 && preSetLocation != -1) || shaderLocation != -1)
+ {
+ int elementLocation = preSetLocation + arrayIndex;
+ preLocatedUniforms[elementLocation] = location;
+ }
+ else
+ {
+ unlocatedUniforms.push_back(location);
+ }
+ }
+ }
+
+ // Make enough space for all uniforms, with pre-set locations or not.
+ mUniformLocations.resize(
+ std::max(unlocatedUniforms.size() + preLocatedUniforms.size() + ignoredLocations.size(),
+ static_cast<size_t>(maxUniformLocation + 1)));
+
+ // Assign uniforms with pre-set locations
+ for (const auto &uniform : preLocatedUniforms)
+ {
+ mUniformLocations[uniform.first] = uniform.second;
+ }
+
+ // Assign ignored uniforms
+ for (const auto &ignoredLocation : ignoredLocations)
+ {
+ mUniformLocations[ignoredLocation].markIgnored();
+ }
+
+ // Automatically assign locations for the rest of the uniforms
+ size_t nextUniformLocation = 0;
+ for (const auto &unlocatedUniform : unlocatedUniforms)
+ {
+ while (mUniformLocations[nextUniformLocation].used() ||
+ mUniformLocations[nextUniformLocation].ignored)
+ {
+ nextUniformLocation++;
+ }
+
+ ASSERT(nextUniformLocation < mUniformLocations.size());
+ mUniformLocations[nextUniformLocation] = unlocatedUniform;
+ nextUniformLocation++;
+ }
+
+ return true;
+}
+
+bool UniformLinker::gatherUniformLocationsAndCheckConflicts(
+ InfoLog &infoLog,
+ const ProgramAliasedBindings &uniformLocationBindings,
+ std::set<GLuint> *ignoredLocations,
+ int *maxUniformLocation)
+{
+ // All the locations where another uniform can't be located.
+ std::set<GLuint> reservedLocations;
+
+ for (const LinkedUniform &uniform : mUniforms)
+ {
+ if ((uniform.isBuiltIn() && !uniform.isEmulatedBuiltIn()) || uniform.isFragmentInOut)
+ {
+ // The uniform of the fragment inout is not a normal uniform type. So, in the case of
+ // the fragment inout, this routine should be skipped.
+ continue;
+ }
+
+ int apiBoundLocation = uniformLocationBindings.getBinding(uniform);
+ int shaderLocation = uniform.location;
+
+ if (shaderLocation != -1)
+ {
+ unsigned int elementCount = uniform.getBasicTypeElementCount();
+
+ for (unsigned int arrayIndex = 0; arrayIndex < elementCount; arrayIndex++)
+ {
+ // GLSL ES 3.10 section 4.4.3
+ int elementLocation = shaderLocation + arrayIndex;
+ *maxUniformLocation = std::max(*maxUniformLocation, elementLocation);
+ if (reservedLocations.find(elementLocation) != reservedLocations.end())
+ {
+ infoLog << "Multiple uniforms bound to location " << elementLocation << ".";
+ return false;
+ }
+ reservedLocations.insert(elementLocation);
+ if (!uniform.active)
+ {
+ ignoredLocations->insert(elementLocation);
+ }
+ }
+ }
+ else if (apiBoundLocation != -1 && uniform.staticUse)
+ {
+ // Only the first location is reserved even if the uniform is an array.
+ *maxUniformLocation = std::max(*maxUniformLocation, apiBoundLocation);
+ if (reservedLocations.find(apiBoundLocation) != reservedLocations.end())
+ {
+ infoLog << "Multiple uniforms bound to location " << apiBoundLocation << ".";
+ return false;
+ }
+ reservedLocations.insert(apiBoundLocation);
+ if (!uniform.active)
+ {
+ ignoredLocations->insert(apiBoundLocation);
+ }
+ }
+ }
+
+ // Record the uniform locations that were bound using the API for uniforms that were not found
+ // from the shader. Other uniforms should not be assigned to those locations.
+ for (const auto &locationBinding : uniformLocationBindings)
+ {
+ GLuint location = locationBinding.second.location;
+ if (reservedLocations.find(location) == reservedLocations.end())
+ {
+ ignoredLocations->insert(location);
+ *maxUniformLocation = std::max(*maxUniformLocation, static_cast<int>(location));
+ }
+ }
+
+ return true;
+}
+
+void UniformLinker::pruneUnusedUniforms()
+{
+ auto uniformIter = mUniforms.begin();
+ while (uniformIter != mUniforms.end())
+ {
+ if (uniformIter->active)
+ {
+ ++uniformIter;
+ }
+ else
+ {
+ mUnusedUniforms.emplace_back(uniformIter->name, uniformIter->isSampler(),
+ uniformIter->isImage(), uniformIter->isAtomicCounter(),
+ uniformIter->isFragmentInOut);
+ uniformIter = mUniforms.erase(uniformIter);
+ }
+ }
+}
+
+bool UniformLinker::flattenUniformsAndCheckCapsForShader(
+ ShaderType shaderType,
+ const Caps &caps,
+ std::vector<LinkedUniform> &samplerUniforms,
+ std::vector<LinkedUniform> &imageUniforms,
+ std::vector<LinkedUniform> &atomicCounterUniforms,
+ std::vector<LinkedUniform> &inputAttachmentUniforms,
+ std::vector<UnusedUniform> &unusedUniforms,
+ InfoLog &infoLog)
+{
+ ShaderUniformCount shaderUniformCount;
+ for (const sh::ShaderVariable &uniform : mShaderUniforms[shaderType])
+ {
+ FlattenUniformVisitor flattener(shaderType, uniform, &mUniforms, &samplerUniforms,
+ &imageUniforms, &atomicCounterUniforms,
+ &inputAttachmentUniforms, &unusedUniforms);
+ sh::TraverseShaderVariable(uniform, false, &flattener);
+
+ if (uniform.active)
+ {
+ shaderUniformCount += flattener.getCounts();
+ }
+ else
+ {
+ unusedUniforms.emplace_back(uniform.name, IsSamplerType(uniform.type),
+ IsImageType(uniform.type),
+ IsAtomicCounterType(uniform.type), uniform.isFragmentInOut);
+ }
+ }
+
+ // This code does not do fine-grained component counting.
+ GLuint maxUniformVectorsCount = GetMaximumShaderUniformVectors(shaderType, caps);
+ if (shaderUniformCount.vectorCount > maxUniformVectorsCount)
+ {
+ GLuint maxUniforms = 0u;
+
+ // See comments in GetUniformResourceLimitName()
+ if (shaderType == ShaderType::Vertex || shaderType == ShaderType::Fragment)
+ {
+ maxUniforms = maxUniformVectorsCount;
+ }
+ else
+ {
+ maxUniforms = maxUniformVectorsCount * 4;
+ }
+
+ LogUniformsExceedLimit(shaderType, UniformType::Variable, maxUniforms, infoLog);
+ return false;
+ }
+
+ if (shaderUniformCount.samplerCount >
+ static_cast<GLuint>(caps.maxShaderTextureImageUnits[shaderType]))
+ {
+ LogUniformsExceedLimit(shaderType, UniformType::Sampler,
+ caps.maxShaderTextureImageUnits[shaderType], infoLog);
+ return false;
+ }
+
+ if (shaderUniformCount.imageCount >
+ static_cast<GLuint>(caps.maxShaderImageUniforms[shaderType]))
+ {
+ LogUniformsExceedLimit(shaderType, UniformType::Image,
+ caps.maxShaderImageUniforms[shaderType], infoLog);
+ return false;
+ }
+
+ if (shaderUniformCount.atomicCounterCount >
+ static_cast<GLuint>(caps.maxShaderAtomicCounters[shaderType]))
+ {
+ LogUniformsExceedLimit(shaderType, UniformType::AtomicCounter,
+ caps.maxShaderAtomicCounters[shaderType], infoLog);
+ return false;
+ }
+
+ return true;
+}
+
+bool UniformLinker::flattenUniformsAndCheckCaps(const Caps &caps, InfoLog &infoLog)
+{
+ std::vector<LinkedUniform> samplerUniforms;
+ std::vector<LinkedUniform> imageUniforms;
+ std::vector<LinkedUniform> atomicCounterUniforms;
+ std::vector<LinkedUniform> inputAttachmentUniforms;
+ std::vector<UnusedUniform> unusedUniforms;
+
+ for (const ShaderType shaderType : mActiveShaderStages)
+ {
+ if (!flattenUniformsAndCheckCapsForShader(shaderType, caps, samplerUniforms, imageUniforms,
+ atomicCounterUniforms, inputAttachmentUniforms,
+ unusedUniforms, infoLog))
+ {
+ return false;
+ }
+ }
+
+ mUniforms.insert(mUniforms.end(), samplerUniforms.begin(), samplerUniforms.end());
+ mUniforms.insert(mUniforms.end(), imageUniforms.begin(), imageUniforms.end());
+ mUniforms.insert(mUniforms.end(), atomicCounterUniforms.begin(), atomicCounterUniforms.end());
+ mUniforms.insert(mUniforms.end(), inputAttachmentUniforms.begin(),
+ inputAttachmentUniforms.end());
+ mUnusedUniforms.insert(mUnusedUniforms.end(), unusedUniforms.begin(), unusedUniforms.end());
+ return true;
+}
+
+bool UniformLinker::checkMaxCombinedAtomicCounters(const Caps &caps, InfoLog &infoLog)
+{
+ unsigned int atomicCounterCount = 0;
+ for (const auto &uniform : mUniforms)
+ {
+ if (IsAtomicCounterType(uniform.type) && uniform.active)
+ {
+ atomicCounterCount += uniform.getBasicTypeElementCount();
+ if (atomicCounterCount > static_cast<GLuint>(caps.maxCombinedAtomicCounters))
+ {
+ infoLog << "atomic counter count exceeds MAX_COMBINED_ATOMIC_COUNTERS"
+ << caps.maxCombinedAtomicCounters << ").";
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+// InterfaceBlockLinker implementation.
+InterfaceBlockLinker::InterfaceBlockLinker() = default;
+
+InterfaceBlockLinker::~InterfaceBlockLinker() = default;
+
+void InterfaceBlockLinker::init(std::vector<InterfaceBlock> *blocksOut,
+ std::vector<std::string> *unusedInterfaceBlocksOut)
+{
+ mBlocksOut = blocksOut;
+ mUnusedInterfaceBlocksOut = unusedInterfaceBlocksOut;
+}
+
+void InterfaceBlockLinker::addShaderBlocks(ShaderType shaderType,
+ const std::vector<sh::InterfaceBlock> *blocks)
+{
+ mShaderBlocks[shaderType] = blocks;
+}
+
+void InterfaceBlockLinker::linkBlocks(const GetBlockSizeFunc &getBlockSize,
+ const GetBlockMemberInfoFunc &getMemberInfo) const
+{
+ ASSERT(mBlocksOut->empty());
+
+ std::set<std::string> visitedList;
+
+ for (const ShaderType shaderType : AllShaderTypes())
+ {
+ if (!mShaderBlocks[shaderType])
+ {
+ continue;
+ }
+
+ for (const sh::InterfaceBlock &block : *mShaderBlocks[shaderType])
+ {
+ if (!IsActiveInterfaceBlock(block))
+ {
+ mUnusedInterfaceBlocksOut->push_back(block.name);
+ continue;
+ }
+
+ if (visitedList.count(block.name) == 0)
+ {
+ defineInterfaceBlock(getBlockSize, getMemberInfo, block, shaderType);
+ visitedList.insert(block.name);
+ continue;
+ }
+
+ if (!block.active)
+ {
+ mUnusedInterfaceBlocksOut->push_back(block.name);
+ continue;
+ }
+
+ for (InterfaceBlock &priorBlock : *mBlocksOut)
+ {
+ if (block.name == priorBlock.name)
+ {
+ priorBlock.setActive(shaderType, true);
+
+ std::unique_ptr<sh::ShaderVariableVisitor> visitor(
+ getVisitor(getMemberInfo, block.fieldPrefix(), block.fieldMappedPrefix(),
+ shaderType, -1));
+
+ sh::TraverseShaderVariables(block.fields, false, visitor.get());
+ }
+ }
+ }
+ }
+}
+
+void InterfaceBlockLinker::defineInterfaceBlock(const GetBlockSizeFunc &getBlockSize,
+ const GetBlockMemberInfoFunc &getMemberInfo,
+ const sh::InterfaceBlock &interfaceBlock,
+ ShaderType shaderType) const
+{
+ size_t blockSize = 0;
+ std::vector<unsigned int> blockIndexes;
+
+ int blockIndex = static_cast<int>(mBlocksOut->size());
+ // Track the first and last block member index to determine the range of active block members in
+ // the block.
+ size_t firstBlockMemberIndex = getCurrentBlockMemberIndex();
+
+ std::unique_ptr<sh::ShaderVariableVisitor> visitor(
+ getVisitor(getMemberInfo, interfaceBlock.fieldPrefix(), interfaceBlock.fieldMappedPrefix(),
+ shaderType, blockIndex));
+ sh::TraverseShaderVariables(interfaceBlock.fields, false, visitor.get());
+
+ size_t lastBlockMemberIndex = getCurrentBlockMemberIndex();
+
+ for (size_t blockMemberIndex = firstBlockMemberIndex; blockMemberIndex < lastBlockMemberIndex;
+ ++blockMemberIndex)
+ {
+ blockIndexes.push_back(static_cast<unsigned int>(blockMemberIndex));
+ }
+
+ unsigned int firstFieldArraySize = interfaceBlock.fields[0].getArraySizeProduct();
+
+ for (unsigned int arrayElement = 0; arrayElement < interfaceBlock.elementCount();
+ ++arrayElement)
+ {
+ std::string blockArrayName = interfaceBlock.name;
+ std::string blockMappedArrayName = interfaceBlock.mappedName;
+ if (interfaceBlock.isArray())
+ {
+ blockArrayName += ArrayString(arrayElement);
+ blockMappedArrayName += ArrayString(arrayElement);
+ }
+
+ // Don't define this block at all if it's not active in the implementation.
+ if (!getBlockSize(blockArrayName, blockMappedArrayName, &blockSize))
+ {
+ continue;
+ }
+
+ // ESSL 3.10 section 4.4.4 page 58:
+ // Any uniform or shader storage block declared without a binding qualifier is initially
+ // assigned to block binding point zero.
+ int blockBinding =
+ (interfaceBlock.binding == -1 ? 0 : interfaceBlock.binding + arrayElement);
+ InterfaceBlock block(interfaceBlock.name, interfaceBlock.mappedName,
+ interfaceBlock.isArray(), arrayElement, firstFieldArraySize,
+ blockBinding);
+ block.memberIndexes = blockIndexes;
+ block.setActive(shaderType, interfaceBlock.active);
+
+ // Since all block elements in an array share the same active interface blocks, they
+ // will all be active once any block member is used. So, since interfaceBlock.name[0]
+ // was active, here we will add every block element in the array.
+ block.dataSize = static_cast<unsigned int>(blockSize);
+ mBlocksOut->push_back(block);
+ }
+}
+
+// UniformBlockLinker implementation.
+UniformBlockLinker::UniformBlockLinker() = default;
+
+UniformBlockLinker::~UniformBlockLinker() {}
+
+void UniformBlockLinker::init(std::vector<InterfaceBlock> *blocksOut,
+ std::vector<LinkedUniform> *uniformsOut,
+ std::vector<std::string> *unusedInterfaceBlocksOut)
+{
+ InterfaceBlockLinker::init(blocksOut, unusedInterfaceBlocksOut);
+ mUniformsOut = uniformsOut;
+}
+
+size_t UniformBlockLinker::getCurrentBlockMemberIndex() const
+{
+ return mUniformsOut->size();
+}
+
+sh::ShaderVariableVisitor *UniformBlockLinker::getVisitor(
+ const GetBlockMemberInfoFunc &getMemberInfo,
+ const std::string &namePrefix,
+ const std::string &mappedNamePrefix,
+ ShaderType shaderType,
+ int blockIndex) const
+{
+ return new UniformBlockEncodingVisitor(getMemberInfo, namePrefix, mappedNamePrefix,
+ mUniformsOut, shaderType, blockIndex);
+}
+
+// ShaderStorageBlockLinker implementation.
+ShaderStorageBlockLinker::ShaderStorageBlockLinker() = default;
+
+ShaderStorageBlockLinker::~ShaderStorageBlockLinker() = default;
+
+void ShaderStorageBlockLinker::init(std::vector<InterfaceBlock> *blocksOut,
+ std::vector<BufferVariable> *bufferVariablesOut,
+ std::vector<std::string> *unusedInterfaceBlocksOut)
+{
+ InterfaceBlockLinker::init(blocksOut, unusedInterfaceBlocksOut);
+ mBufferVariablesOut = bufferVariablesOut;
+}
+
+size_t ShaderStorageBlockLinker::getCurrentBlockMemberIndex() const
+{
+ return mBufferVariablesOut->size();
+}
+
+sh::ShaderVariableVisitor *ShaderStorageBlockLinker::getVisitor(
+ const GetBlockMemberInfoFunc &getMemberInfo,
+ const std::string &namePrefix,
+ const std::string &mappedNamePrefix,
+ ShaderType shaderType,
+ int blockIndex) const
+{
+ return new ShaderStorageBlockVisitor(getMemberInfo, namePrefix, mappedNamePrefix,
+ mBufferVariablesOut, shaderType, blockIndex);
+}
+
+// AtomicCounterBufferLinker implementation.
+AtomicCounterBufferLinker::AtomicCounterBufferLinker() = default;
+
+AtomicCounterBufferLinker::~AtomicCounterBufferLinker() = default;
+
+void AtomicCounterBufferLinker::init(std::vector<AtomicCounterBuffer> *atomicCounterBuffersOut)
+{
+ mAtomicCounterBuffersOut = atomicCounterBuffersOut;
+}
+
+void AtomicCounterBufferLinker::link(const std::map<int, unsigned int> &sizeMap) const
+{
+ for (auto &atomicCounterBuffer : *mAtomicCounterBuffersOut)
+ {
+ auto bufferSize = sizeMap.find(atomicCounterBuffer.binding);
+ ASSERT(bufferSize != sizeMap.end());
+ atomicCounterBuffer.dataSize = bufferSize->second;
+ }
+}
+
+ProgramLinkedResources::ProgramLinkedResources() = default;
+
+ProgramLinkedResources::~ProgramLinkedResources() = default;
+
+LinkingVariables::LinkingVariables(const Context *context, const ProgramState &state)
+{
+ for (ShaderType shaderType : kAllGraphicsShaderTypes)
+ {
+ Shader *shader = state.getAttachedShader(shaderType);
+ if (shader)
+ {
+ outputVaryings[shaderType] = shader->getOutputVaryings(context);
+ inputVaryings[shaderType] = shader->getInputVaryings(context);
+ uniforms[shaderType] = shader->getUniforms(context);
+ uniformBlocks[shaderType] = shader->getUniformBlocks(context);
+ isShaderStageUsedBitset.set(shaderType);
+ }
+ }
+}
+
+LinkingVariables::LinkingVariables(const ProgramPipelineState &state)
+{
+ for (ShaderType shaderType : state.getExecutable().getLinkedShaderStages())
+ {
+ const Program *program = state.getShaderProgram(shaderType);
+ ASSERT(program);
+ outputVaryings[shaderType] = program->getExecutable().getLinkedOutputVaryings(shaderType);
+ inputVaryings[shaderType] = program->getExecutable().getLinkedInputVaryings(shaderType);
+ uniforms[shaderType] = program->getState().getExecutable().getLinkedUniforms(shaderType);
+ uniformBlocks[shaderType] =
+ program->getState().getExecutable().getLinkedUniformBlocks(shaderType);
+ isShaderStageUsedBitset.set(shaderType);
+ }
+}
+
+LinkingVariables::~LinkingVariables() = default;
+
+void ProgramLinkedResources::init(std::vector<InterfaceBlock> *uniformBlocksOut,
+ std::vector<LinkedUniform> *uniformsOut,
+ std::vector<InterfaceBlock> *shaderStorageBlocksOut,
+ std::vector<BufferVariable> *bufferVariablesOut,
+ std::vector<AtomicCounterBuffer> *atomicCounterBuffersOut)
+{
+ uniformBlockLinker.init(uniformBlocksOut, uniformsOut, &unusedInterfaceBlocks);
+ shaderStorageBlockLinker.init(shaderStorageBlocksOut, bufferVariablesOut,
+ &unusedInterfaceBlocks);
+ atomicCounterBufferLinker.init(atomicCounterBuffersOut);
+}
+
+void ProgramLinkedResourcesLinker::linkResources(const Context *context,
+ const ProgramState &programState,
+ const ProgramLinkedResources &resources) const
+{
+ // Gather uniform interface block info.
+ InterfaceBlockInfo uniformBlockInfo(mCustomEncoderFactory);
+ for (const ShaderType shaderType : AllShaderTypes())
+ {
+ Shader *shader = programState.getAttachedShader(shaderType);
+ if (shader)
+ {
+ uniformBlockInfo.getShaderBlockInfo(shader->getUniformBlocks(context));
+ }
+ }
+
+ auto getUniformBlockSize = [&uniformBlockInfo](const std::string &name,
+ const std::string &mappedName, size_t *sizeOut) {
+ return uniformBlockInfo.getBlockSize(name, mappedName, sizeOut);
+ };
+
+ auto getUniformBlockMemberInfo = [&uniformBlockInfo](const std::string &name,
+ const std::string &mappedName,
+ sh::BlockMemberInfo *infoOut) {
+ return uniformBlockInfo.getBlockMemberInfo(name, mappedName, infoOut);
+ };
+
+ // Link uniform interface blocks.
+ resources.uniformBlockLinker.linkBlocks(getUniformBlockSize, getUniformBlockMemberInfo);
+
+ // Gather storage buffer interface block info.
+ InterfaceBlockInfo shaderStorageBlockInfo(mCustomEncoderFactory);
+ for (const ShaderType shaderType : AllShaderTypes())
+ {
+ Shader *shader = programState.getAttachedShader(shaderType);
+ if (shader)
+ {
+ shaderStorageBlockInfo.getShaderBlockInfo(shader->getShaderStorageBlocks(context));
+ }
+ }
+ auto getShaderStorageBlockSize = [&shaderStorageBlockInfo](const std::string &name,
+ const std::string &mappedName,
+ size_t *sizeOut) {
+ return shaderStorageBlockInfo.getBlockSize(name, mappedName, sizeOut);
+ };
+
+ auto getShaderStorageBlockMemberInfo = [&shaderStorageBlockInfo](const std::string &name,
+ const std::string &mappedName,
+ sh::BlockMemberInfo *infoOut) {
+ return shaderStorageBlockInfo.getBlockMemberInfo(name, mappedName, infoOut);
+ };
+
+ // Link storage buffer interface blocks.
+ resources.shaderStorageBlockLinker.linkBlocks(getShaderStorageBlockSize,
+ getShaderStorageBlockMemberInfo);
+
+ // Gather and link atomic counter buffer interface blocks.
+ std::map<int, unsigned int> sizeMap;
+ getAtomicCounterBufferSizeMap(programState, sizeMap);
+ resources.atomicCounterBufferLinker.link(sizeMap);
+}
+
+void ProgramLinkedResourcesLinker::getAtomicCounterBufferSizeMap(
+ const ProgramState &programState,
+ std::map<int, unsigned int> &sizeMapOut) const
+{
+ for (unsigned int index : programState.getAtomicCounterUniformRange())
+ {
+ const LinkedUniform &glUniform = programState.getUniforms()[index];
+
+ auto &bufferDataSize = sizeMapOut[glUniform.binding];
+
+ // Calculate the size of the buffer by finding the end of the last uniform with the same
+ // binding. The end of the uniform is calculated by finding the initial offset of the
+ // uniform and adding size of the uniform. For arrays, the size is the number of elements
+ // times the element size (should always by 4 for atomic_units).
+ unsigned dataOffset =
+ glUniform.offset + static_cast<unsigned int>(glUniform.getBasicTypeElementCount() *
+ glUniform.getElementSize());
+ if (dataOffset > bufferDataSize)
+ {
+ bufferDataSize = dataOffset;
+ }
+ }
+}
+
+bool LinkValidateProgramGlobalNames(InfoLog &infoLog,
+ const ProgramExecutable &executable,
+ const LinkingVariables &linkingVariables)
+{
+ angle::HashMap<std::string, const sh::ShaderVariable *> uniformMap;
+ using BlockAndFieldPair = std::pair<const sh::InterfaceBlock *, const sh::ShaderVariable *>;
+ angle::HashMap<std::string, std::vector<BlockAndFieldPair>> uniformBlockFieldMap;
+
+ for (ShaderType shaderType : kAllGraphicsShaderTypes)
+ {
+ if (!linkingVariables.isShaderStageUsedBitset[shaderType])
+ {
+ continue;
+ }
+
+ // Build a map of Uniforms
+ const std::vector<sh::ShaderVariable> &uniforms = linkingVariables.uniforms[shaderType];
+ for (const auto &uniform : uniforms)
+ {
+ uniformMap[uniform.name] = &uniform;
+ }
+
+ // Build a map of Uniform Blocks
+ // This will also detect any field name conflicts between Uniform Blocks without instance
+ // names
+ const std::vector<sh::InterfaceBlock> &uniformBlocks =
+ linkingVariables.uniformBlocks[shaderType];
+
+ for (const auto &uniformBlock : uniformBlocks)
+ {
+ // Only uniform blocks without an instance name can create a conflict with their field
+ // names
+ if (!uniformBlock.instanceName.empty())
+ {
+ continue;
+ }
+
+ for (const auto &field : uniformBlock.fields)
+ {
+ if (!uniformBlockFieldMap.count(field.name))
+ {
+ // First time we've seen this uniform block field name, so add the
+ // (Uniform Block, Field) pair immediately since there can't be a conflict yet
+ BlockAndFieldPair blockAndFieldPair(&uniformBlock, &field);
+ std::vector<BlockAndFieldPair> newUniformBlockList;
+ newUniformBlockList.push_back(blockAndFieldPair);
+ uniformBlockFieldMap[field.name] = newUniformBlockList;
+ continue;
+ }
+
+ // We've seen this name before.
+ // We need to check each of the uniform blocks that contain a field with this name
+ // to see if there's a conflict or not.
+ std::vector<BlockAndFieldPair> prevBlockFieldPairs =
+ uniformBlockFieldMap[field.name];
+ for (const auto &prevBlockFieldPair : prevBlockFieldPairs)
+ {
+ const sh::InterfaceBlock *prevUniformBlock = prevBlockFieldPair.first;
+ const sh::ShaderVariable *prevUniformBlockField = prevBlockFieldPair.second;
+
+ if (uniformBlock.isSameInterfaceBlockAtLinkTime(*prevUniformBlock))
+ {
+ // The same uniform block should, by definition, contain the same field name
+ continue;
+ }
+
+ // The uniform blocks don't match, so check if the necessary field properties
+ // also match
+ if ((field.name == prevUniformBlockField->name) &&
+ (field.type == prevUniformBlockField->type) &&
+ (field.precision == prevUniformBlockField->precision))
+ {
+ infoLog << "Name conflicts between uniform block field names: "
+ << field.name;
+ return false;
+ }
+ }
+
+ // No conflict, so record this pair
+ BlockAndFieldPair blockAndFieldPair(&uniformBlock, &field);
+ uniformBlockFieldMap[field.name].push_back(blockAndFieldPair);
+ }
+ }
+ }
+
+ // Validate no uniform names conflict with attribute names
+ if (linkingVariables.isShaderStageUsedBitset[ShaderType::Vertex])
+ {
+ // ESSL 3.00.6 section 4.3.5:
+ // If a uniform variable name is declared in one stage (e.g., a vertex shader)
+ // but not in another (e.g., a fragment shader), then that name is still
+ // available in the other stage for a different use.
+ std::unordered_set<std::string> uniforms;
+ for (const sh::ShaderVariable &uniform : linkingVariables.uniforms[ShaderType::Vertex])
+ {
+ uniforms.insert(uniform.name);
+ }
+ for (const auto &attrib : executable.getProgramInputs())
+ {
+ if (uniforms.count(attrib.name))
+ {
+ infoLog << "Name conflicts between a uniform and an attribute: " << attrib.name;
+ return false;
+ }
+ }
+ }
+
+ // Validate no Uniform Block fields conflict with other Uniforms
+ for (const auto &uniformBlockField : uniformBlockFieldMap)
+ {
+ const std::string &fieldName = uniformBlockField.first;
+ if (uniformMap.count(fieldName))
+ {
+ infoLog << "Name conflicts between a uniform and a uniform block field: " << fieldName;
+ return false;
+ }
+ }
+
+ return true;
+}
+
+// [OpenGL ES 3.2] Chapter 7.4.1 "Shader Interface Matching"
+bool LinkValidateShaderInterfaceMatching(const std::vector<sh::ShaderVariable> &outputVaryings,
+ const std::vector<sh::ShaderVariable> &inputVaryings,
+ ShaderType frontShaderType,
+ ShaderType backShaderType,
+ int frontShaderVersion,
+ int backShaderVersion,
+ bool isSeparable,
+ gl::InfoLog &infoLog)
+{
+ ASSERT(frontShaderVersion == backShaderVersion);
+
+ std::vector<const sh::ShaderVariable *> filteredInputVaryings;
+ std::vector<const sh::ShaderVariable *> filteredOutputVaryings;
+
+ GetFilteredVaryings(inputVaryings, &filteredInputVaryings);
+ GetFilteredVaryings(outputVaryings, &filteredOutputVaryings);
+
+ // Separable programs require the number of inputs and outputs match
+ if (isSeparable && filteredInputVaryings.size() < filteredOutputVaryings.size())
+ {
+ infoLog << GetShaderTypeString(backShaderType)
+ << " does not consume all varyings generated by "
+ << GetShaderTypeString(frontShaderType);
+ return false;
+ }
+ if (isSeparable && filteredInputVaryings.size() > filteredOutputVaryings.size())
+ {
+ infoLog << GetShaderTypeString(frontShaderType)
+ << " does not generate all varyings consumed by "
+ << GetShaderTypeString(backShaderType);
+ return false;
+ }
+
+ // All inputs must match all outputs
+ for (const sh::ShaderVariable *input : filteredInputVaryings)
+ {
+ bool match = false;
+ for (const sh::ShaderVariable *output : filteredOutputVaryings)
+ {
+ if (DoShaderVariablesMatch(frontShaderVersion, frontShaderType, backShaderType, *input,
+ *output, isSeparable, infoLog))
+ {
+ match = true;
+ break;
+ }
+ }
+
+ // We permit unmatched, unreferenced varyings. Note that this specifically depends on
+ // whether the input is statically used - a statically used input should fail this test even
+ // if it is not active. GLSL ES 3.00.6 section 4.3.10.
+ if (!match && input->staticUse)
+ {
+ const std::string &name =
+ input->isShaderIOBlock ? input->structOrBlockName : input->name;
+ infoLog << GetShaderTypeString(backShaderType) << " varying " << name
+ << " does not match any " << GetShaderTypeString(frontShaderType) << " varying";
+ return false;
+ }
+ }
+
+ return true;
+}
+
+LinkMismatchError LinkValidateProgramVariables(const sh::ShaderVariable &variable1,
+ const sh::ShaderVariable &variable2,
+ bool validatePrecision,
+ bool treatVariable1AsNonArray,
+ bool treatVariable2AsNonArray,
+ std::string *mismatchedStructOrBlockMemberName)
+{
+ if (variable1.type != variable2.type)
+ {
+ return LinkMismatchError::TYPE_MISMATCH;
+ }
+
+ bool variable1IsArray = variable1.isArray();
+ bool variable2IsArray = variable2.isArray();
+ if (treatVariable1AsNonArray)
+ {
+ ASSERT(variable1IsArray);
+ variable1IsArray = false;
+ }
+ if (treatVariable2AsNonArray)
+ {
+ ASSERT(variable2IsArray);
+ variable2IsArray = false;
+ }
+ // TODO(anglebug.com/5557): Investigate interactions with arrays-of-arrays.
+ if (variable1IsArray != variable2IsArray)
+ {
+ return LinkMismatchError::ARRAYNESS_MISMATCH;
+ }
+ if (!treatVariable1AsNonArray && !treatVariable2AsNonArray &&
+ variable1.arraySizes != variable2.arraySizes)
+ {
+ return LinkMismatchError::ARRAY_SIZE_MISMATCH;
+ }
+ if (validatePrecision && variable1.precision != variable2.precision)
+ {
+ return LinkMismatchError::PRECISION_MISMATCH;
+ }
+ if (!variable1.isShaderIOBlock && !variable2.isShaderIOBlock &&
+ variable1.structOrBlockName != variable2.structOrBlockName)
+ {
+ return LinkMismatchError::STRUCT_NAME_MISMATCH;
+ }
+ if (variable1.imageUnitFormat != variable2.imageUnitFormat)
+ {
+ return LinkMismatchError::FORMAT_MISMATCH;
+ }
+
+ if (variable1.fields.size() != variable2.fields.size())
+ {
+ return LinkMismatchError::FIELD_NUMBER_MISMATCH;
+ }
+ const unsigned int numMembers = static_cast<unsigned int>(variable1.fields.size());
+ for (unsigned int memberIndex = 0; memberIndex < numMembers; memberIndex++)
+ {
+ const sh::ShaderVariable &member1 = variable1.fields[memberIndex];
+ const sh::ShaderVariable &member2 = variable2.fields[memberIndex];
+
+ if (member1.name != member2.name)
+ {
+ return LinkMismatchError::FIELD_NAME_MISMATCH;
+ }
+
+ if (member1.interpolation != member2.interpolation)
+ {
+ return LinkMismatchError::INTERPOLATION_TYPE_MISMATCH;
+ }
+
+ if (variable1.isShaderIOBlock && variable2.isShaderIOBlock)
+ {
+ if (member1.location != member2.location)
+ {
+ return LinkMismatchError::FIELD_LOCATION_MISMATCH;
+ }
+
+ if (member1.structOrBlockName != member2.structOrBlockName)
+ {
+ return LinkMismatchError::FIELD_STRUCT_NAME_MISMATCH;
+ }
+ }
+
+ LinkMismatchError linkErrorOnField = LinkValidateProgramVariables(
+ member1, member2, validatePrecision, false, false, mismatchedStructOrBlockMemberName);
+ if (linkErrorOnField != LinkMismatchError::NO_MISMATCH)
+ {
+ AddProgramVariableParentPrefix(member1.name, mismatchedStructOrBlockMemberName);
+ return linkErrorOnField;
+ }
+ }
+
+ return LinkMismatchError::NO_MISMATCH;
+}
+
+void AddProgramVariableParentPrefix(const std::string &parentName, std::string *mismatchedFieldName)
+{
+ ASSERT(mismatchedFieldName);
+ if (mismatchedFieldName->empty())
+ {
+ *mismatchedFieldName = parentName;
+ }
+ else
+ {
+ std::ostringstream stream;
+ stream << parentName << "." << *mismatchedFieldName;
+ *mismatchedFieldName = stream.str();
+ }
+}
+
+bool LinkValidateBuiltInVaryingsInvariant(const std::vector<sh::ShaderVariable> &vertexVaryings,
+ const std::vector<sh::ShaderVariable> &fragmentVaryings,
+ int vertexShaderVersion,
+ InfoLog &infoLog)
+{
+ bool glPositionIsInvariant = false;
+ bool glPointSizeIsInvariant = false;
+ bool glFragCoordIsInvariant = false;
+ bool glPointCoordIsInvariant = false;
+
+ for (const sh::ShaderVariable &varying : vertexVaryings)
+ {
+ if (!varying.isBuiltIn())
+ {
+ continue;
+ }
+ if (varying.name.compare("gl_Position") == 0)
+ {
+ glPositionIsInvariant = varying.isInvariant;
+ }
+ else if (varying.name.compare("gl_PointSize") == 0)
+ {
+ glPointSizeIsInvariant = varying.isInvariant;
+ }
+ }
+
+ for (const sh::ShaderVariable &varying : fragmentVaryings)
+ {
+ if (!varying.isBuiltIn())
+ {
+ continue;
+ }
+ if (varying.name.compare("gl_FragCoord") == 0)
+ {
+ glFragCoordIsInvariant = varying.isInvariant;
+ }
+ else if (varying.name.compare("gl_PointCoord") == 0)
+ {
+ glPointCoordIsInvariant = varying.isInvariant;
+ }
+ }
+
+ // There is some ambiguity in ESSL 1.00.17 paragraph 4.6.4 interpretation,
+ // for example, https://cvs.khronos.org/bugzilla/show_bug.cgi?id=13842.
+ // Not requiring invariance to match is supported by:
+ // dEQP, WebGL CTS, Nexus 5X GLES
+ if (glFragCoordIsInvariant && !glPositionIsInvariant)
+ {
+ infoLog << "gl_FragCoord can only be declared invariant if and only if gl_Position is "
+ "declared invariant.";
+ return false;
+ }
+ if (glPointCoordIsInvariant && !glPointSizeIsInvariant)
+ {
+ infoLog << "gl_PointCoord can only be declared invariant if and only if gl_PointSize is "
+ "declared invariant.";
+ return false;
+ }
+
+ return true;
+}
+
+bool LinkValidateBuiltInVaryings(const std::vector<sh::ShaderVariable> &outputVaryings,
+ const std::vector<sh::ShaderVariable> &inputVaryings,
+ ShaderType outputShaderType,
+ ShaderType inputShaderType,
+ int outputShaderVersion,
+ int inputShaderVersion,
+ InfoLog &infoLog)
+{
+ ASSERT(outputShaderVersion == inputShaderVersion);
+
+ // Only ESSL 1.0 has restrictions on matching input and output invariance
+ if (inputShaderVersion == 100 && outputShaderType == ShaderType::Vertex &&
+ inputShaderType == ShaderType::Fragment)
+ {
+ return LinkValidateBuiltInVaryingsInvariant(outputVaryings, inputVaryings,
+ outputShaderVersion, infoLog);
+ }
+
+ uint32_t sizeClipDistance = 0;
+ uint32_t sizeCullDistance = 0;
+
+ for (const sh::ShaderVariable &varying : outputVaryings)
+ {
+ if (!varying.isBuiltIn())
+ {
+ continue;
+ }
+ if (varying.name.compare("gl_ClipDistance") == 0)
+ {
+ sizeClipDistance = varying.getOutermostArraySize();
+ }
+ else if (varying.name.compare("gl_CullDistance") == 0)
+ {
+ sizeCullDistance = varying.getOutermostArraySize();
+ }
+ }
+
+ for (const sh::ShaderVariable &varying : inputVaryings)
+ {
+ if (!varying.isBuiltIn())
+ {
+ continue;
+ }
+ if (varying.name.compare("gl_ClipDistance") == 0)
+ {
+ if (sizeClipDistance != varying.getOutermostArraySize())
+ {
+ infoLog << "If either shader redeclares the built-in arrays gl_ClipDistance[] the "
+ "array must have the same size in both shaders.";
+ return false;
+ }
+ }
+ else if (varying.name.compare("gl_CullDistance") == 0)
+ {
+ if (sizeCullDistance != varying.getOutermostArraySize())
+ {
+ infoLog << "If either shader redeclares the built-in arrays gl_CullDistance[] the "
+ "array must have the same size in both shaders.";
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+void LogAmbiguousFieldLinkMismatch(InfoLog &infoLog,
+ const std::string &blockName1,
+ const std::string &blockName2,
+ const std::string &fieldName,
+ ShaderType shaderType1,
+ ShaderType shaderType2)
+{
+ infoLog << "Ambiguous field '" << fieldName << "' in blocks '" << blockName1 << "' ("
+ << GetShaderTypeString(shaderType1) << " shader) and '" << blockName2 << "' ("
+ << GetShaderTypeString(shaderType2) << " shader) which don't have instance names.";
+}
+
+bool ValidateInstancelessGraphicsInterfaceBlocksPerShader(
+ const std::vector<sh::InterfaceBlock> &interfaceBlocks,
+ ShaderType shaderType,
+ InterfaceBlockMap *instancelessBlocksFields,
+ InfoLog &infoLog)
+{
+ ASSERT(instancelessBlocksFields);
+
+ for (const sh::InterfaceBlock &block : interfaceBlocks)
+ {
+ if (!block.instanceName.empty())
+ {
+ continue;
+ }
+
+ for (const sh::ShaderVariable &field : block.fields)
+ {
+ const auto &entry = instancelessBlocksFields->find(field.name);
+ if (entry != instancelessBlocksFields->end())
+ {
+ const sh::InterfaceBlock &linkedBlock = *(entry->second.second);
+ if (block.name != linkedBlock.name)
+ {
+ LogAmbiguousFieldLinkMismatch(infoLog, block.name, linkedBlock.name, field.name,
+ entry->second.first, shaderType);
+ return false;
+ }
+ }
+ else
+ {
+ (*instancelessBlocksFields)[field.name] = std::make_pair(shaderType, &block);
+ }
+ }
+ }
+
+ return true;
+}
+
+LinkMismatchError LinkValidateInterfaceBlockFields(const sh::ShaderVariable &blockField1,
+ const sh::ShaderVariable &blockField2,
+ bool webglCompatibility,
+ std::string *mismatchedBlockFieldName)
+{
+ if (blockField1.name != blockField2.name)
+ {
+ return LinkMismatchError::FIELD_NAME_MISMATCH;
+ }
+
+ // If webgl, validate precision of UBO fields, otherwise don't. See Khronos bug 10287.
+ LinkMismatchError linkError = LinkValidateProgramVariables(
+ blockField1, blockField2, webglCompatibility, false, false, mismatchedBlockFieldName);
+ if (linkError != LinkMismatchError::NO_MISMATCH)
+ {
+ AddProgramVariableParentPrefix(blockField1.name, mismatchedBlockFieldName);
+ return linkError;
+ }
+
+ if (blockField1.isRowMajorLayout != blockField2.isRowMajorLayout)
+ {
+ AddProgramVariableParentPrefix(blockField1.name, mismatchedBlockFieldName);
+ return LinkMismatchError::MATRIX_PACKING_MISMATCH;
+ }
+
+ return LinkMismatchError::NO_MISMATCH;
+}
+
+LinkMismatchError AreMatchingInterfaceBlocks(const sh::InterfaceBlock &interfaceBlock1,
+ const sh::InterfaceBlock &interfaceBlock2,
+ bool webglCompatibility,
+ std::string *mismatchedBlockFieldName)
+{
+ // validate blocks for the same member types
+ if (interfaceBlock1.fields.size() != interfaceBlock2.fields.size())
+ {
+ return LinkMismatchError::FIELD_NUMBER_MISMATCH;
+ }
+ if (interfaceBlock1.arraySize != interfaceBlock2.arraySize)
+ {
+ return LinkMismatchError::ARRAY_SIZE_MISMATCH;
+ }
+ if (interfaceBlock1.layout != interfaceBlock2.layout ||
+ interfaceBlock1.binding != interfaceBlock2.binding)
+ {
+ return LinkMismatchError::LAYOUT_QUALIFIER_MISMATCH;
+ }
+ if (interfaceBlock1.instanceName.empty() != interfaceBlock2.instanceName.empty())
+ {
+ return LinkMismatchError::INSTANCE_NAME_MISMATCH;
+ }
+ const unsigned int numBlockMembers = static_cast<unsigned int>(interfaceBlock1.fields.size());
+ for (unsigned int blockMemberIndex = 0; blockMemberIndex < numBlockMembers; blockMemberIndex++)
+ {
+ const sh::ShaderVariable &member1 = interfaceBlock1.fields[blockMemberIndex];
+ const sh::ShaderVariable &member2 = interfaceBlock2.fields[blockMemberIndex];
+
+ LinkMismatchError linkError = LinkValidateInterfaceBlockFields(
+ member1, member2, webglCompatibility, mismatchedBlockFieldName);
+ if (linkError != LinkMismatchError::NO_MISMATCH)
+ {
+ return linkError;
+ }
+ }
+ return LinkMismatchError::NO_MISMATCH;
+}
+
+void InitializeInterfaceBlockMap(const std::vector<sh::InterfaceBlock> &interfaceBlocks,
+ ShaderType shaderType,
+ InterfaceBlockMap *linkedInterfaceBlocks)
+{
+ ASSERT(linkedInterfaceBlocks);
+
+ for (const sh::InterfaceBlock &interfaceBlock : interfaceBlocks)
+ {
+ (*linkedInterfaceBlocks)[interfaceBlock.name] = std::make_pair(shaderType, &interfaceBlock);
+ }
+}
+
+bool ValidateGraphicsInterfaceBlocksPerShader(
+ const std::vector<sh::InterfaceBlock> &interfaceBlocksToLink,
+ ShaderType shaderType,
+ bool webglCompatibility,
+ InterfaceBlockMap *linkedBlocks,
+ InfoLog &infoLog)
+{
+ ASSERT(linkedBlocks);
+
+ for (const sh::InterfaceBlock &block : interfaceBlocksToLink)
+ {
+ const auto &entry = linkedBlocks->find(block.name);
+ if (entry != linkedBlocks->end())
+ {
+ const sh::InterfaceBlock &linkedBlock = *(entry->second.second);
+ std::string mismatchedStructFieldName;
+ LinkMismatchError linkError = AreMatchingInterfaceBlocks(
+ block, linkedBlock, webglCompatibility, &mismatchedStructFieldName);
+ if (linkError != LinkMismatchError::NO_MISMATCH)
+ {
+ LogLinkMismatch(infoLog, block.name, GetInterfaceBlockTypeString(block.blockType),
+ linkError, mismatchedStructFieldName, entry->second.first,
+ shaderType);
+ return false;
+ }
+ }
+ else
+ {
+ (*linkedBlocks)[block.name] = std::make_pair(shaderType, &block);
+ }
+ }
+
+ return true;
+}
+
+bool ValidateInterfaceBlocksMatch(
+ GLuint numShadersHasInterfaceBlocks,
+ const ShaderMap<const std::vector<sh::InterfaceBlock> *> &shaderInterfaceBlocks,
+ InfoLog &infoLog,
+ bool webglCompatibility,
+ InterfaceBlockMap *instancelessInterfaceBlocksFields)
+{
+ for (ShaderType shaderType : kAllGraphicsShaderTypes)
+ {
+ // Validate that instanceless blocks of different names don't have fields of the same name.
+ if (shaderInterfaceBlocks[shaderType] &&
+ !ValidateInstancelessGraphicsInterfaceBlocksPerShader(
+ *shaderInterfaceBlocks[shaderType], shaderType, instancelessInterfaceBlocksFields,
+ infoLog))
+ {
+ return false;
+ }
+ }
+
+ if (numShadersHasInterfaceBlocks < 2u)
+ {
+ return true;
+ }
+
+ ASSERT(!shaderInterfaceBlocks[ShaderType::Compute]);
+
+ // Check that interface blocks defined in the graphics shaders are identical
+
+ InterfaceBlockMap linkedInterfaceBlocks;
+
+ bool interfaceBlockMapInitialized = false;
+ for (ShaderType shaderType : kAllGraphicsShaderTypes)
+ {
+ if (!shaderInterfaceBlocks[shaderType])
+ {
+ continue;
+ }
+
+ if (!interfaceBlockMapInitialized)
+ {
+ InitializeInterfaceBlockMap(*shaderInterfaceBlocks[shaderType], shaderType,
+ &linkedInterfaceBlocks);
+ interfaceBlockMapInitialized = true;
+ }
+ else if (!ValidateGraphicsInterfaceBlocksPerShader(*shaderInterfaceBlocks[shaderType],
+ shaderType, webglCompatibility,
+ &linkedInterfaceBlocks, infoLog))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool LinkValidateProgramInterfaceBlocks(const Context *context,
+ ShaderBitSet activeProgramStages,
+ const ProgramLinkedResources &resources,
+ InfoLog &infoLog,
+ GLuint *combinedShaderStorageBlocksCountOut)
+{
+ ASSERT(combinedShaderStorageBlocksCountOut);
+
+ const Caps &caps = context->getCaps();
+ const bool webglCompatibility = context->isWebGL();
+ const Version &version = context->getClientVersion();
+
+ GLuint combinedUniformBlocksCount = 0u;
+ GLuint numShadersHasUniformBlocks = 0u;
+ ShaderMap<const std::vector<sh::InterfaceBlock> *> allShaderUniformBlocks = {};
+ InterfaceBlockMap instancelessInterfaceBlocksFields;
+
+ for (ShaderType shaderType : activeProgramStages)
+ {
+ const std::vector<sh::InterfaceBlock> &uniformBlocks =
+ resources.uniformBlockLinker.getShaderBlocks(shaderType);
+ if (!uniformBlocks.empty())
+ {
+ if (!ValidateInterfaceBlocksCount(
+ static_cast<GLuint>(caps.maxShaderUniformBlocks[shaderType]), uniformBlocks,
+ shaderType, sh::BlockType::BLOCK_UNIFORM, &combinedUniformBlocksCount, infoLog))
+ {
+ return false;
+ }
+
+ allShaderUniformBlocks[shaderType] = &uniformBlocks;
+ ++numShadersHasUniformBlocks;
+ }
+ }
+
+ if (combinedUniformBlocksCount > static_cast<GLuint>(caps.maxCombinedUniformBlocks))
+ {
+ infoLog << "The sum of the number of active uniform blocks exceeds "
+ "MAX_COMBINED_UNIFORM_BLOCKS ("
+ << caps.maxCombinedUniformBlocks << ").";
+ return false;
+ }
+
+ if (!ValidateInterfaceBlocksMatch(numShadersHasUniformBlocks, allShaderUniformBlocks, infoLog,
+ webglCompatibility, &instancelessInterfaceBlocksFields))
+ {
+ return false;
+ }
+
+ if (version >= Version(3, 1))
+ {
+ *combinedShaderStorageBlocksCountOut = 0u;
+ GLuint numShadersHasShaderStorageBlocks = 0u;
+ ShaderMap<const std::vector<sh::InterfaceBlock> *> allShaderStorageBlocks = {};
+ for (ShaderType shaderType : activeProgramStages)
+ {
+ const std::vector<sh::InterfaceBlock> &shaderStorageBlocks =
+ resources.shaderStorageBlockLinker.getShaderBlocks(shaderType);
+ if (!shaderStorageBlocks.empty())
+ {
+ if (!ValidateInterfaceBlocksCount(
+ static_cast<GLuint>(caps.maxShaderStorageBlocks[shaderType]),
+ shaderStorageBlocks, shaderType, sh::BlockType::BLOCK_BUFFER,
+ combinedShaderStorageBlocksCountOut, infoLog))
+ {
+ return false;
+ }
+
+ allShaderStorageBlocks[shaderType] = &shaderStorageBlocks;
+ ++numShadersHasShaderStorageBlocks;
+ }
+ }
+
+ if (*combinedShaderStorageBlocksCountOut >
+ static_cast<GLuint>(caps.maxCombinedShaderStorageBlocks))
+ {
+ infoLog << "The sum of the number of active shader storage blocks exceeds "
+ "MAX_COMBINED_SHADER_STORAGE_BLOCKS ("
+ << caps.maxCombinedShaderStorageBlocks << ").";
+ return false;
+ }
+
+ if (!ValidateInterfaceBlocksMatch(numShadersHasShaderStorageBlocks, allShaderStorageBlocks,
+ infoLog, webglCompatibility,
+ &instancelessInterfaceBlocksFields))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/ProgramLinkedResources.h b/gfx/angle/checkout/src/libANGLE/ProgramLinkedResources.h
new file mode 100644
index 0000000000..0bb6cbb96f
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/ProgramLinkedResources.h
@@ -0,0 +1,333 @@
+//
+// Copyright 2017 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.
+//
+
+// ProgramLinkedResources.h: implements link-time checks for default block uniforms, and generates
+// uniform locations. Populates data structures related to uniforms so that they can be stored in
+// program state.
+
+#ifndef LIBANGLE_UNIFORMLINKER_H_
+#define LIBANGLE_UNIFORMLINKER_H_
+
+#include "angle_gl.h"
+#include "common/PackedEnums.h"
+#include "common/angleutils.h"
+#include "libANGLE/VaryingPacking.h"
+
+#include <functional>
+
+namespace sh
+{
+class BlockLayoutEncoder;
+struct BlockMemberInfo;
+struct InterfaceBlock;
+struct ShaderVariable;
+class BlockEncoderVisitor;
+class ShaderVariableVisitor;
+struct ShaderVariable;
+} // namespace sh
+
+namespace gl
+{
+struct BufferVariable;
+struct Caps;
+class Context;
+class InfoLog;
+struct InterfaceBlock;
+enum class LinkMismatchError;
+struct LinkedUniform;
+class ProgramState;
+class ProgramPipelineState;
+class ProgramBindings;
+class ProgramAliasedBindings;
+class Shader;
+struct ShaderVariableBuffer;
+struct UnusedUniform;
+struct VariableLocation;
+
+using AtomicCounterBuffer = ShaderVariableBuffer;
+using ShaderUniform = std::pair<ShaderType, const sh::ShaderVariable *>;
+
+class UniformLinker final : angle::NonCopyable
+{
+ public:
+ UniformLinker(const ShaderBitSet &activeShaderStages,
+ const ShaderMap<std::vector<sh::ShaderVariable>> &shaderUniforms);
+ ~UniformLinker();
+
+ bool link(const Caps &caps,
+ InfoLog &infoLog,
+ const ProgramAliasedBindings &uniformLocationBindings);
+
+ void getResults(std::vector<LinkedUniform> *uniforms,
+ std::vector<UnusedUniform> *unusedUniformsOutOrNull,
+ std::vector<VariableLocation> *uniformLocationsOutOrNull);
+
+ private:
+ bool validateGraphicsUniforms(InfoLog &infoLog) const;
+ bool validateGraphicsUniformsPerShader(ShaderType shaderToLink,
+ bool extendLinkedUniforms,
+ std::map<std::string, ShaderUniform> *linkedUniforms,
+ InfoLog &infoLog) const;
+ bool flattenUniformsAndCheckCapsForShader(ShaderType shaderType,
+ const Caps &caps,
+ std::vector<LinkedUniform> &samplerUniforms,
+ std::vector<LinkedUniform> &imageUniforms,
+ std::vector<LinkedUniform> &atomicCounterUniforms,
+ std::vector<LinkedUniform> &inputAttachmentUniforms,
+ std::vector<UnusedUniform> &unusedUniforms,
+ InfoLog &infoLog);
+
+ bool flattenUniformsAndCheckCaps(const Caps &caps, InfoLog &infoLog);
+ bool checkMaxCombinedAtomicCounters(const Caps &caps, InfoLog &infoLog);
+
+ bool indexUniforms(InfoLog &infoLog, const ProgramAliasedBindings &uniformLocationBindings);
+ bool gatherUniformLocationsAndCheckConflicts(
+ InfoLog &infoLog,
+ const ProgramAliasedBindings &uniformLocationBindings,
+ std::set<GLuint> *ignoredLocations,
+ int *maxUniformLocation);
+ void pruneUnusedUniforms();
+
+ ShaderBitSet mActiveShaderStages;
+ const ShaderMap<std::vector<sh::ShaderVariable>> &mShaderUniforms;
+ std::vector<LinkedUniform> mUniforms;
+ std::vector<UnusedUniform> mUnusedUniforms;
+ std::vector<VariableLocation> mUniformLocations;
+};
+
+using GetBlockSizeFunc = std::function<
+ bool(const std::string &blockName, const std::string &blockMappedName, size_t *sizeOut)>;
+using GetBlockMemberInfoFunc = std::function<
+ bool(const std::string &name, const std::string &mappedName, sh::BlockMemberInfo *infoOut)>;
+
+// This class is intended to be used during the link step to store interface block information.
+// It is called by the Impl class during ProgramImpl::link so that it has access to the
+// real block size and layout.
+class InterfaceBlockLinker : angle::NonCopyable
+{
+ public:
+ virtual ~InterfaceBlockLinker();
+
+ // This is called once per shader stage. It stores a pointer to the block vector, so it's
+ // important that this class does not persist longer than the duration of Program::link.
+ void addShaderBlocks(ShaderType shader, const std::vector<sh::InterfaceBlock> *blocks);
+
+ // This is called once during a link operation, after all shader blocks are added.
+ void linkBlocks(const GetBlockSizeFunc &getBlockSize,
+ const GetBlockMemberInfoFunc &getMemberInfo) const;
+
+ const std::vector<sh::InterfaceBlock> &getShaderBlocks(ShaderType shaderType) const
+ {
+ ASSERT(mShaderBlocks[shaderType]);
+ return *mShaderBlocks[shaderType];
+ }
+
+ protected:
+ InterfaceBlockLinker();
+ void init(std::vector<InterfaceBlock> *blocksOut,
+ std::vector<std::string> *unusedInterfaceBlocksOut);
+ void defineInterfaceBlock(const GetBlockSizeFunc &getBlockSize,
+ const GetBlockMemberInfoFunc &getMemberInfo,
+ const sh::InterfaceBlock &interfaceBlock,
+ ShaderType shaderType) const;
+
+ virtual size_t getCurrentBlockMemberIndex() const = 0;
+
+ virtual sh::ShaderVariableVisitor *getVisitor(const GetBlockMemberInfoFunc &getMemberInfo,
+ const std::string &namePrefix,
+ const std::string &mappedNamePrefix,
+ ShaderType shaderType,
+ int blockIndex) const = 0;
+
+ ShaderMap<const std::vector<sh::InterfaceBlock> *> mShaderBlocks = {};
+
+ std::vector<InterfaceBlock> *mBlocksOut = nullptr;
+ std::vector<std::string> *mUnusedInterfaceBlocksOut = nullptr;
+};
+
+class UniformBlockLinker final : public InterfaceBlockLinker
+{
+ public:
+ UniformBlockLinker();
+ ~UniformBlockLinker() override;
+
+ void init(std::vector<InterfaceBlock> *blocksOut,
+ std::vector<LinkedUniform> *uniformsOut,
+ std::vector<std::string> *unusedInterfaceBlocksOut);
+
+ private:
+ size_t getCurrentBlockMemberIndex() const override;
+
+ sh::ShaderVariableVisitor *getVisitor(const GetBlockMemberInfoFunc &getMemberInfo,
+ const std::string &namePrefix,
+ const std::string &mappedNamePrefix,
+ ShaderType shaderType,
+ int blockIndex) const override;
+
+ std::vector<LinkedUniform> *mUniformsOut = nullptr;
+};
+
+class ShaderStorageBlockLinker final : public InterfaceBlockLinker
+{
+ public:
+ ShaderStorageBlockLinker();
+ ~ShaderStorageBlockLinker() override;
+
+ void init(std::vector<InterfaceBlock> *blocksOut,
+ std::vector<BufferVariable> *bufferVariablesOut,
+ std::vector<std::string> *unusedInterfaceBlocksOut);
+
+ private:
+ size_t getCurrentBlockMemberIndex() const override;
+
+ sh::ShaderVariableVisitor *getVisitor(const GetBlockMemberInfoFunc &getMemberInfo,
+ const std::string &namePrefix,
+ const std::string &mappedNamePrefix,
+ ShaderType shaderType,
+ int blockIndex) const override;
+
+ std::vector<BufferVariable> *mBufferVariablesOut = nullptr;
+};
+
+class AtomicCounterBufferLinker final : angle::NonCopyable
+{
+ public:
+ AtomicCounterBufferLinker();
+ ~AtomicCounterBufferLinker();
+
+ void init(std::vector<AtomicCounterBuffer> *atomicCounterBuffersOut);
+ void link(const std::map<int, unsigned int> &sizeMap) const;
+
+ private:
+ std::vector<AtomicCounterBuffer> *mAtomicCounterBuffersOut = nullptr;
+};
+
+// The link operation is responsible for finishing the link of uniform and interface blocks.
+// This way it can filter out unreferenced resources and still have access to the info.
+// TODO(jmadill): Integrate uniform linking/filtering as well as interface blocks.
+struct UnusedUniform
+{
+ UnusedUniform(std::string name,
+ bool isSampler,
+ bool isImage,
+ bool isAtomicCounter,
+ bool isFragmentInOut)
+ {
+ this->name = name;
+ this->isSampler = isSampler;
+ this->isImage = isImage;
+ this->isAtomicCounter = isAtomicCounter;
+ this->isFragmentInOut = isFragmentInOut;
+ }
+
+ std::string name;
+ bool isSampler;
+ bool isImage;
+ bool isAtomicCounter;
+ bool isFragmentInOut;
+};
+
+struct ProgramLinkedResources
+{
+ ProgramLinkedResources();
+ ~ProgramLinkedResources();
+
+ void init(std::vector<InterfaceBlock> *uniformBlocksOut,
+ std::vector<LinkedUniform> *uniformsOut,
+ std::vector<InterfaceBlock> *shaderStorageBlocksOut,
+ std::vector<BufferVariable> *bufferVariablesOut,
+ std::vector<AtomicCounterBuffer> *atomicCounterBuffersOut);
+
+ ProgramVaryingPacking varyingPacking;
+ UniformBlockLinker uniformBlockLinker;
+ ShaderStorageBlockLinker shaderStorageBlockLinker;
+ AtomicCounterBufferLinker atomicCounterBufferLinker;
+ std::vector<UnusedUniform> unusedUniforms;
+ std::vector<std::string> unusedInterfaceBlocks;
+};
+
+struct LinkingVariables final : private angle::NonCopyable
+{
+ LinkingVariables(const Context *context, const ProgramState &state);
+ LinkingVariables(const ProgramPipelineState &state);
+ ~LinkingVariables();
+
+ ShaderMap<std::vector<sh::ShaderVariable>> outputVaryings;
+ ShaderMap<std::vector<sh::ShaderVariable>> inputVaryings;
+ ShaderMap<std::vector<sh::ShaderVariable>> uniforms;
+ ShaderMap<std::vector<sh::InterfaceBlock>> uniformBlocks;
+ ShaderBitSet isShaderStageUsedBitset;
+};
+
+class CustomBlockLayoutEncoderFactory : angle::NonCopyable
+{
+ public:
+ virtual ~CustomBlockLayoutEncoderFactory() {}
+
+ virtual sh::BlockLayoutEncoder *makeEncoder() = 0;
+};
+
+// Used by the backends in Program*::linkResources to parse interface blocks and provide
+// information to ProgramLinkedResources' linkers.
+class ProgramLinkedResourcesLinker final : angle::NonCopyable
+{
+ public:
+ ProgramLinkedResourcesLinker(CustomBlockLayoutEncoderFactory *customEncoderFactory)
+ : mCustomEncoderFactory(customEncoderFactory)
+ {}
+
+ void linkResources(const Context *context,
+ const ProgramState &programState,
+ const ProgramLinkedResources &resources) const;
+
+ private:
+ void getAtomicCounterBufferSizeMap(const ProgramState &programState,
+ std::map<int, unsigned int> &sizeMapOut) const;
+
+ CustomBlockLayoutEncoderFactory *mCustomEncoderFactory;
+};
+
+using ShaderInterfaceBlock = std::pair<ShaderType, const sh::InterfaceBlock *>;
+using InterfaceBlockMap = std::map<std::string, ShaderInterfaceBlock>;
+
+bool LinkValidateProgramGlobalNames(InfoLog &infoLog,
+ const ProgramExecutable &executable,
+ const LinkingVariables &linkingVariables);
+bool LinkValidateShaderInterfaceMatching(const std::vector<sh::ShaderVariable> &outputVaryings,
+ const std::vector<sh::ShaderVariable> &inputVaryings,
+ ShaderType frontShaderType,
+ ShaderType backShaderType,
+ int frontShaderVersion,
+ int backShaderVersion,
+ bool isSeparable,
+ InfoLog &infoLog);
+bool LinkValidateBuiltInVaryingsInvariant(const std::vector<sh::ShaderVariable> &vertexVaryings,
+ const std::vector<sh::ShaderVariable> &fragmentVaryings,
+ int vertexShaderVersion,
+ InfoLog &infoLog);
+bool LinkValidateBuiltInVaryings(const std::vector<sh::ShaderVariable> &inputVaryings,
+ const std::vector<sh::ShaderVariable> &outputVaryings,
+ ShaderType inputShaderType,
+ ShaderType outputShaderType,
+ int inputShaderVersion,
+ int outputShaderVersion,
+ InfoLog &infoLog);
+LinkMismatchError LinkValidateProgramVariables(const sh::ShaderVariable &variable1,
+ const sh::ShaderVariable &variable2,
+ bool validatePrecision,
+ bool treatVariable1AsNonArray,
+ bool treatVariable2AsNonArray,
+ std::string *mismatchedStructOrBlockMemberName);
+void AddProgramVariableParentPrefix(const std::string &parentName,
+ std::string *mismatchedFieldName);
+bool LinkValidateProgramInterfaceBlocks(const Context *context,
+ ShaderBitSet activeProgramStages,
+ const ProgramLinkedResources &resources,
+ InfoLog &infoLog,
+ GLuint *combinedShaderStorageBlocksCountOut);
+} // namespace gl
+
+#endif // LIBANGLE_UNIFORMLINKER_H_
diff --git a/gfx/angle/checkout/src/libANGLE/ProgramPipeline.cpp b/gfx/angle/checkout/src/libANGLE/ProgramPipeline.cpp
new file mode 100644
index 0000000000..1675b06705
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/ProgramPipeline.cpp
@@ -0,0 +1,721 @@
+//
+// Copyright 2017 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.
+//
+
+// ProgramPipeline.cpp: Implements the gl::ProgramPipeline class.
+// Implements GL program pipeline objects and related functionality.
+// [OpenGL ES 3.1] section 7.4 page 105.
+
+#include "libANGLE/ProgramPipeline.h"
+
+#include <algorithm>
+
+#include "libANGLE/Context.h"
+#include "libANGLE/Program.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/renderer/GLImplFactory.h"
+#include "libANGLE/renderer/ProgramPipelineImpl.h"
+
+namespace gl
+{
+
+enum SubjectIndexes : angle::SubjectIndex
+{
+ kExecutableSubjectIndex = 0
+};
+
+ProgramPipelineState::ProgramPipelineState()
+ : mLabel(),
+ mActiveShaderProgram(nullptr),
+ mValid(false),
+ mExecutable(new ProgramExecutable()),
+ mIsLinked(false)
+{
+ for (const ShaderType shaderType : gl::AllShaderTypes())
+ {
+ mPrograms[shaderType] = nullptr;
+ }
+}
+
+ProgramPipelineState::~ProgramPipelineState()
+{
+ SafeDelete(mExecutable);
+}
+
+const std::string &ProgramPipelineState::getLabel() const
+{
+ return mLabel;
+}
+
+void ProgramPipelineState::activeShaderProgram(Program *shaderProgram)
+{
+ mActiveShaderProgram = shaderProgram;
+}
+
+void ProgramPipelineState::useProgramStage(const Context *context,
+ const ShaderType shaderType,
+ Program *shaderProgram,
+ angle::ObserverBinding *programObserverBindings)
+{
+ Program *oldProgram = mPrograms[shaderType];
+ if (oldProgram)
+ {
+ oldProgram->release(context);
+ }
+
+ // If program refers to a program object with a valid shader attached for the indicated shader
+ // stage, glUseProgramStages installs the executable code for that stage in the indicated
+ // program pipeline object pipeline.
+ if (shaderProgram && (shaderProgram->id().value != 0) &&
+ shaderProgram->getExecutable().hasLinkedShaderStage(shaderType))
+ {
+ mPrograms[shaderType] = shaderProgram;
+ shaderProgram->addRef();
+ }
+ else
+ {
+ // If program is zero, or refers to a program object with no valid shader executable for the
+ // given stage, it is as if the pipeline object has no programmable stage configured for the
+ // indicated shader stage.
+ mPrograms[shaderType] = nullptr;
+ }
+
+ Program *program = mPrograms[shaderType];
+ programObserverBindings->bind(program);
+}
+
+void ProgramPipelineState::useProgramStages(
+ const Context *context,
+ const gl::ShaderBitSet &shaderTypes,
+ Program *shaderProgram,
+ std::vector<angle::ObserverBinding> *programObserverBindings)
+{
+ for (ShaderType shaderType : shaderTypes)
+ {
+ useProgramStage(context, shaderType, shaderProgram,
+ &programObserverBindings->at(static_cast<size_t>(shaderType)));
+ }
+}
+
+bool ProgramPipelineState::usesShaderProgram(ShaderProgramID programId) const
+{
+ for (const Program *program : mPrograms)
+ {
+ if (program && (program->id() == programId))
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void ProgramPipelineState::updateExecutableTextures()
+{
+ for (const ShaderType shaderType : mExecutable->getLinkedShaderStages())
+ {
+ const Program *program = getShaderProgram(shaderType);
+ ASSERT(program);
+ mExecutable->setActiveTextureMask(mExecutable->getActiveSamplersMask() |
+ program->getExecutable().getActiveSamplersMask());
+ mExecutable->setActiveImagesMask(mExecutable->getActiveImagesMask() |
+ program->getExecutable().getActiveImagesMask());
+ // Updates mActiveSamplerRefCounts, mActiveSamplerTypes, and mActiveSamplerFormats
+ mExecutable->updateActiveSamplers(program->getState());
+ }
+}
+
+rx::SpecConstUsageBits ProgramPipelineState::getSpecConstUsageBits() const
+{
+ rx::SpecConstUsageBits specConstUsageBits;
+ for (const ShaderType shaderType : mExecutable->getLinkedShaderStages())
+ {
+ const Program *program = getShaderProgram(shaderType);
+ ASSERT(program);
+ specConstUsageBits |= program->getState().getSpecConstUsageBits();
+ }
+ return specConstUsageBits;
+}
+
+ProgramPipeline::ProgramPipeline(rx::GLImplFactory *factory, ProgramPipelineID handle)
+ : RefCountObject(factory->generateSerial(), handle),
+ mProgramPipelineImpl(factory->createProgramPipeline(mState)),
+ mExecutableObserverBinding(this, kExecutableSubjectIndex)
+{
+ ASSERT(mProgramPipelineImpl);
+
+ for (const ShaderType shaderType : gl::AllShaderTypes())
+ {
+ mProgramObserverBindings.emplace_back(this, static_cast<angle::SubjectIndex>(shaderType));
+ }
+ mExecutableObserverBinding.bind(mState.mExecutable);
+}
+
+ProgramPipeline::~ProgramPipeline()
+{
+ mProgramPipelineImpl.reset(nullptr);
+}
+
+void ProgramPipeline::onDestroy(const Context *context)
+{
+ for (Program *program : mState.mPrograms)
+ {
+ if (program)
+ {
+ ASSERT(program->getRefCount());
+ program->release(context);
+ }
+ }
+
+ getImplementation()->destroy(context);
+}
+
+angle::Result ProgramPipeline::setLabel(const Context *context, const std::string &label)
+{
+ mState.mLabel = label;
+
+ if (mProgramPipelineImpl)
+ {
+ return mProgramPipelineImpl->onLabelUpdate(context);
+ }
+ return angle::Result::Continue;
+}
+
+const std::string &ProgramPipeline::getLabel() const
+{
+ return mState.mLabel;
+}
+
+rx::ProgramPipelineImpl *ProgramPipeline::getImplementation() const
+{
+ return mProgramPipelineImpl.get();
+}
+
+void ProgramPipeline::activeShaderProgram(Program *shaderProgram)
+{
+ mState.activeShaderProgram(shaderProgram);
+}
+
+angle::Result ProgramPipeline::useProgramStages(const Context *context,
+ GLbitfield stages,
+ Program *shaderProgram)
+{
+ bool needToUpdatePipelineState = false;
+ gl::ShaderBitSet shaderTypes;
+ if (stages != GL_ALL_SHADER_BITS)
+ {
+ ASSERT(stages < 256u);
+ for (size_t singleShaderBit : angle::BitSet<8>(stages))
+ {
+ // Cast back to a bit after the iterator returns an index.
+ ShaderType shaderType = GetShaderTypeFromBitfield(angle::Bit<size_t>(singleShaderBit));
+ ASSERT(shaderType != ShaderType::InvalidEnum);
+ shaderTypes.set(shaderType);
+ }
+ }
+ else
+ {
+ shaderTypes.set();
+ }
+ ASSERT(shaderTypes.any());
+
+ for (ShaderType shaderType : shaderTypes)
+ {
+ if (mState.getShaderProgram(shaderType) != shaderProgram ||
+ (shaderProgram && shaderProgram->hasAnyDirtyBit()))
+ {
+ needToUpdatePipelineState = true;
+ break;
+ }
+ }
+
+ if (!needToUpdatePipelineState)
+ {
+ return angle::Result::Continue;
+ }
+
+ mState.useProgramStages(context, shaderTypes, shaderProgram, &mProgramObserverBindings);
+ updateLinkedShaderStages();
+
+ mState.mIsLinked = false;
+ onStateChange(angle::SubjectMessage::SubjectChanged);
+
+ return angle::Result::Continue;
+}
+
+void ProgramPipeline::updateLinkedShaderStages()
+{
+ mState.mExecutable->resetLinkedShaderStages();
+
+ for (const ShaderType shaderType : gl::AllShaderTypes())
+ {
+ Program *program = mState.mPrograms[shaderType];
+ if (program)
+ {
+ mState.mExecutable->setLinkedShaderStages(shaderType);
+ }
+ }
+
+ mState.mExecutable->updateCanDrawWith();
+}
+
+void ProgramPipeline::updateExecutableAttributes()
+{
+ Program *vertexProgram = getShaderProgram(gl::ShaderType::Vertex);
+
+ if (!vertexProgram)
+ {
+ return;
+ }
+
+ const ProgramExecutable &vertexExecutable = vertexProgram->getExecutable();
+ mState.mExecutable->mActiveAttribLocationsMask = vertexExecutable.mActiveAttribLocationsMask;
+ mState.mExecutable->mMaxActiveAttribLocation = vertexExecutable.mMaxActiveAttribLocation;
+ mState.mExecutable->mAttributesTypeMask = vertexExecutable.mAttributesTypeMask;
+ mState.mExecutable->mAttributesMask = vertexExecutable.mAttributesMask;
+ mState.mExecutable->mProgramInputs = vertexExecutable.mProgramInputs;
+}
+
+void ProgramPipeline::updateTransformFeedbackMembers()
+{
+ ShaderType lastVertexProcessingStage =
+ gl::GetLastPreFragmentStage(getExecutable().getLinkedShaderStages());
+ if (lastVertexProcessingStage == ShaderType::InvalidEnum)
+ {
+ return;
+ }
+
+ Program *shaderProgram = getShaderProgram(lastVertexProcessingStage);
+ ASSERT(shaderProgram);
+
+ const ProgramExecutable &lastPreFragmentExecutable = shaderProgram->getExecutable();
+ mState.mExecutable->mTransformFeedbackStrides =
+ lastPreFragmentExecutable.mTransformFeedbackStrides;
+ mState.mExecutable->mLinkedTransformFeedbackVaryings =
+ lastPreFragmentExecutable.mLinkedTransformFeedbackVaryings;
+}
+
+void ProgramPipeline::updateShaderStorageBlocks()
+{
+ mState.mExecutable->mShaderStorageBlocks.clear();
+
+ // Only copy the storage blocks from each Program in the PPO once, since each Program could
+ // contain multiple shader stages.
+ ShaderBitSet handledStages;
+
+ for (const gl::ShaderType shaderType : gl::AllShaderTypes())
+ {
+ const Program *shaderProgram = getShaderProgram(shaderType);
+ if (shaderProgram && !handledStages.test(shaderType))
+ {
+ // Only add each Program's blocks once.
+ handledStages |= shaderProgram->getExecutable().getLinkedShaderStages();
+
+ for (const InterfaceBlock &block :
+ shaderProgram->getExecutable().getShaderStorageBlocks())
+ {
+ mState.mExecutable->mShaderStorageBlocks.emplace_back(block);
+ }
+ }
+ }
+}
+
+void ProgramPipeline::updateImageBindings()
+{
+ mState.mExecutable->mImageBindings.clear();
+ mState.mExecutable->mActiveImageShaderBits.fill({});
+
+ // Only copy the storage blocks from each Program in the PPO once, since each Program could
+ // contain multiple shader stages.
+ ShaderBitSet handledStages;
+
+ for (const gl::ShaderType shaderType : gl::AllShaderTypes())
+ {
+ const Program *shaderProgram = getShaderProgram(shaderType);
+ if (shaderProgram && !handledStages.test(shaderType))
+ {
+ // Only add each Program's blocks once.
+ handledStages |= shaderProgram->getExecutable().getLinkedShaderStages();
+
+ for (const ImageBinding &imageBinding : shaderProgram->getState().getImageBindings())
+ {
+ mState.mExecutable->mImageBindings.emplace_back(imageBinding);
+ }
+
+ mState.mExecutable->updateActiveImages(shaderProgram->getExecutable());
+ }
+ }
+}
+
+void ProgramPipeline::updateExecutableGeometryProperties()
+{
+ Program *geometryProgram = getShaderProgram(gl::ShaderType::Geometry);
+
+ if (!geometryProgram)
+ {
+ return;
+ }
+
+ const ProgramExecutable &geometryExecutable = geometryProgram->getExecutable();
+ mState.mExecutable->mGeometryShaderInputPrimitiveType =
+ geometryExecutable.mGeometryShaderInputPrimitiveType;
+ mState.mExecutable->mGeometryShaderOutputPrimitiveType =
+ geometryExecutable.mGeometryShaderOutputPrimitiveType;
+ mState.mExecutable->mGeometryShaderInvocations = geometryExecutable.mGeometryShaderInvocations;
+ mState.mExecutable->mGeometryShaderMaxVertices = geometryExecutable.mGeometryShaderMaxVertices;
+}
+
+void ProgramPipeline::updateExecutableTessellationProperties()
+{
+ Program *tessControlProgram = getShaderProgram(gl::ShaderType::TessControl);
+ Program *tessEvalProgram = getShaderProgram(gl::ShaderType::TessEvaluation);
+
+ if (tessControlProgram)
+ {
+ const ProgramExecutable &tessControlExecutable = tessControlProgram->getExecutable();
+ mState.mExecutable->mTessControlShaderVertices =
+ tessControlExecutable.mTessControlShaderVertices;
+ }
+
+ if (tessEvalProgram)
+ {
+ const ProgramExecutable &tessEvalExecutable = tessEvalProgram->getExecutable();
+ mState.mExecutable->mTessGenMode = tessEvalExecutable.mTessGenMode;
+ mState.mExecutable->mTessGenSpacing = tessEvalExecutable.mTessGenSpacing;
+ mState.mExecutable->mTessGenVertexOrder = tessEvalExecutable.mTessGenVertexOrder;
+ mState.mExecutable->mTessGenPointMode = tessEvalExecutable.mTessGenPointMode;
+ }
+}
+
+void ProgramPipeline::updateFragmentInoutRangeAndEnablesPerSampleShading()
+{
+ Program *fragmentProgram = getShaderProgram(gl::ShaderType::Fragment);
+
+ if (!fragmentProgram)
+ {
+ return;
+ }
+
+ const ProgramExecutable &fragmentExecutable = fragmentProgram->getExecutable();
+ mState.mExecutable->mFragmentInoutRange = fragmentExecutable.mFragmentInoutRange;
+ mState.mExecutable->mHasDiscard = fragmentExecutable.mHasDiscard;
+ mState.mExecutable->mEnablesPerSampleShading = fragmentExecutable.mEnablesPerSampleShading;
+}
+
+void ProgramPipeline::updateLinkedVaryings()
+{
+ // Need to check all of the shader stages, not just linked, so we handle Compute correctly.
+ for (const gl::ShaderType shaderType : kAllGraphicsShaderTypes)
+ {
+ const Program *shaderProgram = getShaderProgram(shaderType);
+ if (shaderProgram && shaderProgram->isLinked())
+ {
+ const ProgramExecutable &executable = shaderProgram->getExecutable();
+ mState.mExecutable->mLinkedOutputVaryings[shaderType] =
+ executable.getLinkedOutputVaryings(shaderType);
+ mState.mExecutable->mLinkedInputVaryings[shaderType] =
+ executable.getLinkedInputVaryings(shaderType);
+ }
+ }
+
+ const Program *computeProgram = getShaderProgram(ShaderType::Compute);
+ if (computeProgram && computeProgram->isLinked())
+ {
+ const ProgramExecutable &executable = computeProgram->getExecutable();
+ mState.mExecutable->mLinkedOutputVaryings[ShaderType::Compute] =
+ executable.getLinkedOutputVaryings(ShaderType::Compute);
+ mState.mExecutable->mLinkedInputVaryings[ShaderType::Compute] =
+ executable.getLinkedInputVaryings(ShaderType::Compute);
+ }
+}
+
+void ProgramPipeline::updateExecutable()
+{
+ // Vertex Shader ProgramExecutable properties
+ updateExecutableAttributes();
+ updateTransformFeedbackMembers();
+ updateShaderStorageBlocks();
+ updateImageBindings();
+
+ // Geometry Shader ProgramExecutable properties
+ updateExecutableGeometryProperties();
+
+ // Tessellation Shaders ProgramExecutable properties
+ updateExecutableTessellationProperties();
+
+ // Fragment Shader ProgramExecutable properties
+ updateFragmentInoutRangeAndEnablesPerSampleShading();
+
+ // All Shader ProgramExecutable properties
+ mState.updateExecutableTextures();
+ updateLinkedVaryings();
+}
+
+// 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.
+angle::Result ProgramPipeline::link(const Context *context)
+{
+ ASSERT(!mState.mIsLinked);
+
+ ProgramMergedVaryings mergedVaryings;
+ ProgramVaryingPacking varyingPacking;
+ LinkingVariables linkingVariables(mState);
+
+ mState.mExecutable->reset(true);
+
+ InfoLog &infoLog = mState.mExecutable->getInfoLog();
+ infoLog.reset();
+
+ // Build shader variable uniforms map for gl::UniformLinker.
+ ShaderMap<std::vector<sh::ShaderVariable>> shaderUniforms;
+ for (ShaderType shaderType : mState.mExecutable->mLinkedShaderStages)
+ {
+ for (const LinkedUniform &uniform : mState.mPrograms[shaderType]->getUniforms())
+ {
+ shaderUniforms[shaderType].push_back(uniform);
+ }
+ }
+
+ if (mState.mExecutable->hasLinkedShaderStage(gl::ShaderType::Vertex))
+ {
+ if (!linkVaryings(infoLog))
+ {
+ return angle::Result::Stop;
+ }
+
+ if (!LinkValidateProgramGlobalNames(infoLog, getExecutable(), linkingVariables))
+ {
+ return angle::Result::Stop;
+ }
+
+ Program *fragmentShaderProgram = getShaderProgram(ShaderType::Fragment);
+ if (fragmentShaderProgram)
+ {
+ // We should also be validating SSBO and image uniform counts.
+ const GLuint combinedImageUniforms = 0;
+ const GLuint combinedShaderStorageBlocks = 0;
+ const ProgramExecutable &fragmentExecutable = fragmentShaderProgram->getExecutable();
+ if (!mState.mExecutable->linkValidateOutputVariables(
+ context->getCaps(), context->getExtensions(), context->getClientVersion(),
+ combinedImageUniforms, combinedShaderStorageBlocks,
+ fragmentExecutable.getOutputVariables(),
+ fragmentExecutable.getLinkedShaderVersion(ShaderType::Fragment),
+ ProgramAliasedBindings(), ProgramAliasedBindings()))
+ {
+ return angle::Result::Continue;
+ }
+ }
+ mergedVaryings = GetMergedVaryingsFromLinkingVariables(linkingVariables);
+ // If separable program objects are in use, the set of attributes captured is taken
+ // from the program object active on the last vertex processing stage.
+ ShaderType lastVertexProcessingStage =
+ gl::GetLastPreFragmentStage(getExecutable().getLinkedShaderStages());
+ if (lastVertexProcessingStage == ShaderType::InvalidEnum)
+ {
+ // If there is no active program for the vertex or fragment shader stages, the results
+ // of vertex and fragment shader execution will respectively be undefined. However,
+ // this is not an error.
+ return angle::Result::Continue;
+ }
+
+ Program *tfProgram = getShaderProgram(lastVertexProcessingStage);
+ ASSERT(tfProgram);
+
+ if (!tfProgram)
+ {
+ tfProgram = mState.mPrograms[ShaderType::Vertex];
+ }
+
+ const std::vector<std::string> &transformFeedbackVaryingNames =
+ tfProgram->getState().getTransformFeedbackVaryingNames();
+
+ if (!mState.mExecutable->linkMergedVaryings(context, mergedVaryings,
+ transformFeedbackVaryingNames, linkingVariables,
+ false, &varyingPacking))
+ {
+ return angle::Result::Stop;
+ }
+ }
+
+ // Merge uniforms.
+ mState.mExecutable->copyUniformsFromProgramMap(mState.mPrograms);
+
+ if (mState.mExecutable->hasLinkedShaderStage(gl::ShaderType::Vertex))
+ {
+ const ProgramState &programState = mState.mPrograms[gl::ShaderType::Vertex]->getState();
+ mState.mExecutable->copyInputsFromProgram(programState);
+ }
+
+ // Merge shader buffers (UBOs, SSBOs, and atomic counter buffers) into the executable.
+ // Also copy over image and sampler bindings.
+ for (ShaderType shaderType : mState.mExecutable->getLinkedShaderStages())
+ {
+ const ProgramState &programState = mState.mPrograms[shaderType]->getState();
+ mState.mExecutable->copyShaderBuffersFromProgram(programState, shaderType);
+ mState.mExecutable->copySamplerBindingsFromProgram(programState);
+ mState.mExecutable->copyImageBindingsFromProgram(programState);
+ }
+
+ if (mState.mExecutable->hasLinkedShaderStage(gl::ShaderType::Fragment))
+ {
+ const ProgramState &programState = mState.mPrograms[gl::ShaderType::Fragment]->getState();
+ mState.mExecutable->copyOutputsFromProgram(programState);
+ }
+
+ if (mState.mExecutable->hasLinkedShaderStage(gl::ShaderType::Vertex) ||
+ mState.mExecutable->hasLinkedShaderStage(gl::ShaderType::Compute))
+ {
+ ANGLE_TRY(getImplementation()->link(context, mergedVaryings, varyingPacking));
+ }
+
+ mState.mExecutable->mActiveSamplerRefCounts.fill(0);
+ updateExecutable();
+
+ mState.mIsLinked = true;
+ onStateChange(angle::SubjectMessage::SubjectChanged);
+
+ return angle::Result::Continue;
+}
+
+bool ProgramPipeline::linkVaryings(InfoLog &infoLog) const
+{
+ ShaderType previousShaderType = ShaderType::InvalidEnum;
+ for (ShaderType shaderType : kAllGraphicsShaderTypes)
+ {
+ Program *program = getShaderProgram(shaderType);
+ if (!program)
+ {
+ continue;
+ }
+ ProgramExecutable &executable = program->getExecutable();
+
+ if (previousShaderType != ShaderType::InvalidEnum)
+ {
+ Program *previousProgram = getShaderProgram(previousShaderType);
+ ASSERT(previousProgram);
+ const ProgramExecutable &previousExecutable = previousProgram->getExecutable();
+
+ if (!LinkValidateShaderInterfaceMatching(
+ previousExecutable.getLinkedOutputVaryings(previousShaderType),
+ executable.getLinkedInputVaryings(shaderType), previousShaderType, shaderType,
+ previousExecutable.getLinkedShaderVersion(previousShaderType),
+ executable.getLinkedShaderVersion(shaderType), true, infoLog))
+ {
+ return false;
+ }
+ }
+ previousShaderType = shaderType;
+ }
+
+ // TODO: http://anglebug.com/3571 and http://anglebug.com/3572
+ // Need to move logic of validating builtin varyings inside the for-loop above.
+ // This is because the built-in symbols `gl_ClipDistance` and `gl_CullDistance`
+ // can be redeclared in Geometry or Tessellation shaders as well.
+ Program *vertexProgram = mState.mPrograms[ShaderType::Vertex];
+ Program *fragmentProgram = mState.mPrograms[ShaderType::Fragment];
+ if (!vertexProgram || !fragmentProgram)
+ {
+ return true;
+ }
+ ProgramExecutable &vertexExecutable = vertexProgram->getExecutable();
+ ProgramExecutable &fragmentExecutable = fragmentProgram->getExecutable();
+ return LinkValidateBuiltInVaryings(
+ vertexExecutable.getLinkedOutputVaryings(ShaderType::Vertex),
+ fragmentExecutable.getLinkedInputVaryings(ShaderType::Fragment), ShaderType::Vertex,
+ ShaderType::Fragment, vertexExecutable.getLinkedShaderVersion(ShaderType::Vertex),
+ fragmentExecutable.getLinkedShaderVersion(ShaderType::Fragment), infoLog);
+}
+
+void ProgramPipeline::validate(const gl::Context *context)
+{
+ const Caps &caps = context->getCaps();
+ mState.mValid = true;
+ InfoLog &infoLog = mState.mExecutable->getInfoLog();
+ infoLog.reset();
+
+ for (const ShaderType shaderType : mState.mExecutable->getLinkedShaderStages())
+ {
+ Program *shaderProgram = mState.mPrograms[shaderType];
+ if (shaderProgram)
+ {
+ shaderProgram->resolveLink(context);
+ shaderProgram->validate(caps);
+ std::string shaderInfoString = shaderProgram->getExecutable().getInfoLogString();
+ if (shaderInfoString.length())
+ {
+ mState.mValid = false;
+ infoLog << shaderInfoString << "\n";
+ return;
+ }
+ if (!shaderProgram->isSeparable())
+ {
+ mState.mValid = false;
+ infoLog << GetShaderTypeString(shaderType) << " is not marked separable."
+ << "\n";
+ return;
+ }
+ }
+ }
+
+ intptr_t programPipelineError = context->getStateCache().getProgramPipelineError(context);
+ if (programPipelineError)
+ {
+ mState.mValid = false;
+ const char *errorMessage = reinterpret_cast<const char *>(programPipelineError);
+ infoLog << errorMessage << "\n";
+ return;
+ }
+
+ if (!linkVaryings(infoLog))
+ {
+ mState.mValid = false;
+
+ for (const ShaderType shaderType : mState.mExecutable->getLinkedShaderStages())
+ {
+ Program *shaderProgram = mState.mPrograms[shaderType];
+ ASSERT(shaderProgram);
+ shaderProgram->validate(caps);
+ std::string shaderInfoString = shaderProgram->getExecutable().getInfoLogString();
+ if (shaderInfoString.length())
+ {
+ infoLog << shaderInfoString << "\n";
+ }
+ }
+ }
+}
+
+void ProgramPipeline::onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message)
+{
+ switch (message)
+ {
+ case angle::SubjectMessage::ProgramTextureOrImageBindingChanged:
+ mState.mExecutable->mActiveSamplerRefCounts.fill(0);
+ mState.updateExecutableTextures();
+ break;
+
+ case angle::SubjectMessage::ProgramRelinked:
+ mState.mIsLinked = false;
+ onStateChange(angle::SubjectMessage::ProgramRelinked);
+ break;
+ case angle::SubjectMessage::SamplerUniformsUpdated:
+ mState.mExecutable->clearSamplerBindings();
+ for (ShaderType shaderType : mState.mExecutable->getLinkedShaderStages())
+ {
+ const ProgramState &programState = mState.mPrograms[shaderType]->getState();
+ mState.mExecutable->copySamplerBindingsFromProgram(programState);
+ }
+ mState.mExecutable->mActiveSamplerRefCounts.fill(0);
+ mState.updateExecutableTextures();
+ break;
+ case angle::SubjectMessage::ProgramUniformUpdated:
+ mProgramPipelineImpl->onProgramUniformUpdate(static_cast<ShaderType>(index));
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/ProgramPipeline.h b/gfx/angle/checkout/src/libANGLE/ProgramPipeline.h
new file mode 100644
index 0000000000..4b394ca3e7
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/ProgramPipeline.h
@@ -0,0 +1,176 @@
+//
+// Copyright 2017 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.
+//
+
+// ProgramPipeline.h: Defines the gl::ProgramPipeline class.
+// Implements GL program pipeline objects and related functionality.
+// [OpenGL ES 3.1] section 7.4 page 105.
+
+#ifndef LIBANGLE_PROGRAMPIPELINE_H_
+#define LIBANGLE_PROGRAMPIPELINE_H_
+
+#include <memory>
+
+#include "common/angleutils.h"
+#include "libANGLE/Debug.h"
+#include "libANGLE/Program.h"
+#include "libANGLE/ProgramExecutable.h"
+#include "libANGLE/RefCountObject.h"
+
+namespace rx
+{
+class GLImplFactory;
+class ProgramPipelineImpl;
+} // namespace rx
+
+namespace gl
+{
+class Context;
+class ProgramPipeline;
+
+class ProgramPipelineState final : angle::NonCopyable
+{
+ public:
+ ProgramPipelineState();
+ ~ProgramPipelineState();
+
+ const std::string &getLabel() const;
+
+ ProgramExecutable &getExecutable() const
+ {
+ ASSERT(mExecutable);
+ return *mExecutable;
+ }
+
+ void activeShaderProgram(Program *shaderProgram);
+ void useProgramStages(const Context *context,
+ const gl::ShaderBitSet &shaderTypes,
+ Program *shaderProgram,
+ std::vector<angle::ObserverBinding> *programObserverBindings);
+
+ Program *getActiveShaderProgram() { return mActiveShaderProgram; }
+
+ GLboolean isValid() const { return mValid; }
+
+ const Program *getShaderProgram(ShaderType shaderType) const { return mPrograms[shaderType]; }
+
+ bool usesShaderProgram(ShaderProgramID program) const;
+
+ void updateExecutableTextures();
+
+ rx::SpecConstUsageBits getSpecConstUsageBits() const;
+
+ private:
+ void useProgramStage(const Context *context,
+ ShaderType shaderType,
+ Program *shaderProgram,
+ angle::ObserverBinding *programObserverBindings);
+
+ friend class ProgramPipeline;
+
+ std::string mLabel;
+
+ // The active shader program
+ Program *mActiveShaderProgram;
+ // The shader programs for each stage.
+ ShaderMap<Program *> mPrograms;
+
+ GLboolean mValid;
+
+ ProgramExecutable *mExecutable;
+
+ bool mIsLinked;
+};
+
+class ProgramPipeline final : public RefCountObject<ProgramPipelineID>,
+ public LabeledObject,
+ public angle::ObserverInterface,
+ public angle::Subject
+{
+ public:
+ ProgramPipeline(rx::GLImplFactory *factory, ProgramPipelineID handle);
+ ~ProgramPipeline() override;
+
+ void onDestroy(const Context *context) override;
+
+ angle::Result setLabel(const Context *context, const std::string &label) override;
+ const std::string &getLabel() const override;
+
+ const ProgramPipelineState &getState() const { return mState; }
+ ProgramPipelineState &getState() { return mState; }
+
+ ProgramExecutable &getExecutable() const { return mState.getExecutable(); }
+
+ rx::ProgramPipelineImpl *getImplementation() const;
+
+ Program *getActiveShaderProgram() { return mState.getActiveShaderProgram(); }
+ void activeShaderProgram(Program *shaderProgram);
+ Program *getLinkedActiveShaderProgram(const Context *context)
+ {
+ Program *program = mState.getActiveShaderProgram();
+ if (program)
+ {
+ program->resolveLink(context);
+ }
+ return program;
+ }
+
+ angle::Result useProgramStages(const Context *context,
+ GLbitfield stages,
+ Program *shaderProgram);
+
+ Program *getShaderProgram(ShaderType shaderType) const { return mState.mPrograms[shaderType]; }
+
+ void resetIsLinked() { mState.mIsLinked = false; }
+ angle::Result link(const gl::Context *context);
+
+ // Ensure program pipeline is linked. Inlined to make sure its overhead is as low as possible.
+ void resolveLink(const Context *context)
+ {
+ if (mState.mIsLinked)
+ {
+ // Already linked, nothing to do.
+ return;
+ }
+
+ angle::Result linkResult = link(context);
+ if (linkResult != angle::Result::Continue)
+ {
+ // If the link failed then log a warning, swallow the error and move on.
+ WARN() << "ProgramPipeline link failed" << std::endl;
+ }
+ return;
+ }
+
+ void validate(const gl::Context *context);
+ GLboolean isValid() const { return mState.isValid(); }
+ bool isLinked() const { return mState.mIsLinked; }
+
+ // ObserverInterface implementation.
+ void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override;
+
+ private:
+ bool linkVaryings(InfoLog &infoLog) const;
+ void updateLinkedShaderStages();
+ void updateExecutableAttributes();
+ void updateTransformFeedbackMembers();
+ void updateShaderStorageBlocks();
+ void updateImageBindings();
+ void updateExecutableGeometryProperties();
+ void updateExecutableTessellationProperties();
+ void updateFragmentInoutRangeAndEnablesPerSampleShading();
+ void updateLinkedVaryings();
+ void updateExecutable();
+
+ std::unique_ptr<rx::ProgramPipelineImpl> mProgramPipelineImpl;
+
+ ProgramPipelineState mState;
+
+ std::vector<angle::ObserverBinding> mProgramObserverBindings;
+ angle::ObserverBinding mExecutableObserverBinding;
+};
+} // namespace gl
+
+#endif // LIBANGLE_PROGRAMPIPELINE_H_
diff --git a/gfx/angle/checkout/src/libANGLE/Query.cpp b/gfx/angle/checkout/src/libANGLE/Query.cpp
new file mode 100644
index 0000000000..1e56221077
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Query.cpp
@@ -0,0 +1,96 @@
+//
+// Copyright 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.
+//
+
+// Query.cpp: Implements the gl::Query class
+
+#include "libANGLE/Query.h"
+
+#include "libANGLE/renderer/GLImplFactory.h"
+#include "libANGLE/renderer/QueryImpl.h"
+
+namespace gl
+{
+Query::Query(rx::GLImplFactory *factory, QueryType type, QueryID id)
+ : RefCountObject(factory->generateSerial(), id), mQuery(factory->createQuery(type)), mLabel()
+{}
+
+Query::~Query()
+{
+ SafeDelete(mQuery);
+}
+
+void Query::onDestroy(const Context *context)
+{
+ ASSERT(mQuery);
+ mQuery->onDestroy(context);
+}
+
+angle::Result Query::setLabel(const Context *context, const std::string &label)
+{
+ mLabel = label;
+
+ if (mQuery)
+ {
+ return mQuery->onLabelUpdate(context);
+ }
+ return angle::Result::Continue;
+}
+
+const std::string &Query::getLabel() const
+{
+ return mLabel;
+}
+
+angle::Result Query::begin(const Context *context)
+{
+ return mQuery->begin(context);
+}
+
+angle::Result Query::end(const Context *context)
+{
+ return mQuery->end(context);
+}
+
+angle::Result Query::queryCounter(const Context *context)
+{
+ return mQuery->queryCounter(context);
+}
+
+angle::Result Query::getResult(const Context *context, GLint *params)
+{
+ return mQuery->getResult(context, params);
+}
+
+angle::Result Query::getResult(const Context *context, GLuint *params)
+{
+ return mQuery->getResult(context, params);
+}
+
+angle::Result Query::getResult(const Context *context, GLint64 *params)
+{
+ return mQuery->getResult(context, params);
+}
+
+angle::Result Query::getResult(const Context *context, GLuint64 *params)
+{
+ return mQuery->getResult(context, params);
+}
+
+angle::Result Query::isResultAvailable(const Context *context, bool *available)
+{
+ return mQuery->isResultAvailable(context, available);
+}
+
+QueryType Query::getType() const
+{
+ return mQuery->getType();
+}
+
+rx::QueryImpl *Query::getImplementation() const
+{
+ return mQuery;
+}
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/Query.h b/gfx/angle/checkout/src/libANGLE/Query.h
new file mode 100644
index 0000000000..8d8692b5e8
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Query.h
@@ -0,0 +1,60 @@
+//
+// Copyright 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.
+//
+
+// Query.h: Defines the gl::Query class
+
+#ifndef LIBANGLE_QUERY_H_
+#define LIBANGLE_QUERY_H_
+
+#include "common/PackedEnums.h"
+#include "libANGLE/Debug.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/RefCountObject.h"
+
+#include "common/angleutils.h"
+
+#include "angle_gl.h"
+
+namespace rx
+{
+class GLImplFactory;
+class QueryImpl;
+} // namespace rx
+
+namespace gl
+{
+
+class Query final : public RefCountObject<QueryID>, public LabeledObject
+{
+ public:
+ Query(rx::GLImplFactory *factory, QueryType type, QueryID id);
+ ~Query() override;
+ void onDestroy(const Context *context) override;
+
+ angle::Result setLabel(const Context *context, const std::string &label) override;
+ const std::string &getLabel() const override;
+
+ angle::Result begin(const Context *context);
+ angle::Result end(const Context *context);
+ angle::Result queryCounter(const Context *context);
+ angle::Result getResult(const Context *context, GLint *params);
+ angle::Result getResult(const Context *context, GLuint *params);
+ angle::Result getResult(const Context *context, GLint64 *params);
+ angle::Result getResult(const Context *context, GLuint64 *params);
+ angle::Result isResultAvailable(const Context *context, bool *available);
+
+ QueryType getType() const;
+
+ rx::QueryImpl *getImplementation() const;
+
+ private:
+ rx::QueryImpl *mQuery;
+
+ std::string mLabel;
+};
+} // namespace gl
+
+#endif // LIBANGLE_QUERY_H_
diff --git a/gfx/angle/checkout/src/libANGLE/RefCountObject.h b/gfx/angle/checkout/src/libANGLE/RefCountObject.h
new file mode 100644
index 0000000000..f19b8c434a
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/RefCountObject.h
@@ -0,0 +1,327 @@
+//
+// Copyright 2002 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.
+//
+
+// RefCountObject.h: Defines the gl::RefCountObject base class that provides
+// lifecycle support for GL objects using the traditional BindObject scheme, but
+// that need to be reference counted for correct cross-context deletion.
+// (Concretely, textures, buffers and renderbuffers.)
+
+#ifndef LIBANGLE_REFCOUNTOBJECT_H_
+#define LIBANGLE_REFCOUNTOBJECT_H_
+
+#include "angle_gl.h"
+#include "common/PackedEnums.h"
+#include "common/debug.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/Observer.h"
+#include "libANGLE/renderer/serial_utils.h"
+
+#include <cstddef>
+
+namespace angle
+{
+
+template <typename ContextT, typename ErrorT>
+class RefCountObject : angle::NonCopyable
+{
+ public:
+ using ContextType = ContextT;
+ using ErrorType = ErrorT;
+
+ RefCountObject() : mRefCount(0) {}
+
+ virtual void onDestroy(const ContextType *context) {}
+
+ void addRef() const { ++mRefCount; }
+
+ ANGLE_INLINE void release(const ContextType *context)
+ {
+ ASSERT(mRefCount > 0);
+ if (--mRefCount == 0)
+ {
+ onDestroy(context);
+ delete this;
+ }
+ }
+
+ size_t getRefCount() const { return mRefCount; }
+
+ protected:
+ virtual ~RefCountObject() { ASSERT(mRefCount == 0); }
+
+ mutable size_t mRefCount;
+};
+
+template <class ObjectType, typename ContextT, typename ErrorT = angle::Result>
+class RefCountObjectReleaser : angle::NonCopyable
+{
+ public:
+ using ContextType = ContextT;
+ using ErrorType = ErrorT;
+
+ RefCountObjectReleaser() {}
+ RefCountObjectReleaser(const ContextType *context, ObjectType *object)
+ : mContext(context), mObject(object)
+ {}
+
+ RefCountObjectReleaser(RefCountObjectReleaser &&other)
+ : mContext(other.mContext), mObject(other.mObject)
+ {
+ other.mContext = nullptr;
+ other.mObject = nullptr;
+ }
+
+ RefCountObjectReleaser &operator=(RefCountObjectReleaser &&other)
+ {
+ mContext = other.mContext;
+ mObject = other.mObject;
+
+ other.mContext = nullptr;
+ other.mObject = nullptr;
+
+ return *this;
+ }
+
+ ~RefCountObjectReleaser()
+ {
+ if (mObject)
+ {
+ reinterpret_cast<RefCountObject<ContextType, ErrorType> *>(mObject)->release(mContext);
+ mObject = nullptr;
+ }
+ }
+
+ private:
+ const ContextType *mContext = nullptr;
+ ObjectType *mObject = nullptr;
+};
+
+template <class ObjectType, typename ContextT, typename ErrorT = angle::Result>
+class BindingPointer
+{
+ public:
+ using ContextType = ContextT;
+ using ErrorType = ErrorT;
+
+ BindingPointer() : mObject(nullptr) {}
+
+ BindingPointer(ObjectType *object) : mObject(object)
+ {
+ if (mObject)
+ {
+ mObject->addRef();
+ }
+ }
+
+ BindingPointer(const BindingPointer &other) : mObject(other.mObject)
+ {
+ if (mObject)
+ {
+ mObject->addRef();
+ }
+ }
+
+ BindingPointer &operator=(BindingPointer &&other)
+ {
+ std::swap(mObject, other.mObject);
+ return *this;
+ }
+
+ virtual ~BindingPointer()
+ {
+ // Objects have to be released before the resource manager is destroyed, so they must be
+ // explicitly cleaned up.
+ ASSERT(mObject == nullptr);
+ }
+
+ RefCountObjectReleaser<ObjectType, ContextType, ErrorT> set(const ContextType *context,
+ ObjectType *newObject)
+ {
+ // addRef first in case newObject == mObject and this is the last reference to it.
+ if (newObject != nullptr)
+ {
+ reinterpret_cast<RefCountObject<ContextType, ErrorType> *>(newObject)->addRef();
+ }
+
+ // Store the old pointer in a temporary so we can set the pointer before calling release.
+ // Otherwise the object could still be referenced when its destructor is called.
+ ObjectType *oldObject = mObject;
+ mObject = newObject;
+ return RefCountObjectReleaser<ObjectType, ContextType, ErrorT>(context, oldObject);
+ }
+
+ void assign(ObjectType *object) { mObject = object; }
+
+ ObjectType *get() const { return mObject; }
+ ObjectType *operator->() const { return mObject; }
+
+ bool operator==(const BindingPointer &other) const { return mObject == other.mObject; }
+
+ bool operator!=(const BindingPointer &other) const { return !(*this == other); }
+
+ protected:
+ ANGLE_INLINE void setImpl(ObjectType *obj) { mObject = obj; }
+
+ private:
+ ObjectType *mObject;
+};
+} // namespace angle
+
+namespace gl
+{
+class Context;
+
+template <class ObjectType>
+class BindingPointer;
+
+using RefCountObjectNoID = angle::RefCountObject<Context, angle::Result>;
+
+template <typename IDType>
+class RefCountObject : public gl::RefCountObjectNoID
+{
+ public:
+ explicit RefCountObject(rx::Serial serial, IDType id) : mSerial(serial), mId(id) {}
+
+ rx::Serial serial() const { return mSerial; }
+ IDType id() const { return mId; }
+
+ protected:
+ ~RefCountObject() override {}
+
+ private:
+ // Unique serials are used to identify resources for frame capture.
+ rx::Serial mSerial;
+ IDType mId;
+};
+
+template <class ObjectType>
+class BindingPointer : public angle::BindingPointer<ObjectType, Context>
+{
+ public:
+ using ContextType = typename angle::BindingPointer<ObjectType, Context>::ContextType;
+ using ErrorType = typename angle::BindingPointer<ObjectType, Context>::ErrorType;
+
+ BindingPointer() {}
+
+ BindingPointer(ObjectType *object) : angle::BindingPointer<ObjectType, Context>(object) {}
+
+ typename ResourceTypeToID<ObjectType>::IDType id() const
+ {
+ ObjectType *obj = this->get();
+ if (obj)
+ return obj->id();
+ return {0};
+ }
+};
+
+template <class ObjectType>
+class OffsetBindingPointer : public BindingPointer<ObjectType>
+{
+ public:
+ using ContextType = typename BindingPointer<ObjectType>::ContextType;
+ using ErrorType = typename BindingPointer<ObjectType>::ErrorType;
+
+ OffsetBindingPointer() : mOffset(0), mSize(0) {}
+
+ void set(const ContextType *context, ObjectType *newObject, GLintptr offset, GLsizeiptr size)
+ {
+ set(context, newObject);
+ updateOffsetAndSize(newObject, offset, size);
+ }
+
+ GLintptr getOffset() const { return mOffset; }
+ GLsizeiptr getSize() const { return mSize; }
+
+ bool operator==(const OffsetBindingPointer<ObjectType> &other) const
+ {
+ return this->get() == other.get() && mOffset == other.mOffset && mSize == other.mSize;
+ }
+
+ bool operator!=(const OffsetBindingPointer<ObjectType> &other) const
+ {
+ return !(*this == other);
+ }
+
+ void assign(ObjectType *newObject, GLintptr offset, GLsizeiptr size)
+ {
+ assign(newObject);
+ updateOffsetAndSize(newObject, offset, size);
+ }
+
+ private:
+ ANGLE_INLINE void updateOffsetAndSize(ObjectType *newObject, GLintptr offset, GLsizeiptr size)
+ {
+ if (newObject)
+ {
+ mOffset = offset;
+ mSize = size;
+ }
+ else
+ {
+ mOffset = 0;
+ mSize = 0;
+ }
+ }
+
+ // Delete the unparameterized functions. This forces an explicit offset and size.
+ using BindingPointer<ObjectType>::set;
+ using BindingPointer<ObjectType>::assign;
+
+ GLintptr mOffset;
+ GLsizeiptr mSize;
+};
+
+template <typename SubjectT>
+class SubjectBindingPointer : protected BindingPointer<SubjectT>, public angle::ObserverBindingBase
+{
+ public:
+ SubjectBindingPointer(angle::ObserverInterface *observer, angle::SubjectIndex index)
+ : ObserverBindingBase(observer, index)
+ {}
+ ~SubjectBindingPointer() override {}
+ SubjectBindingPointer(const SubjectBindingPointer &other) = default;
+ SubjectBindingPointer &operator=(const SubjectBindingPointer &other) = default;
+
+ void bind(const Context *context, SubjectT *subject)
+ {
+ // AddRef first in case subject == get()
+ if (subject)
+ {
+ subject->addObserver(this);
+ subject->addRef();
+ }
+
+ if (get())
+ {
+ get()->removeObserver(this);
+ get()->release(context);
+ }
+
+ this->setImpl(subject);
+ }
+
+ using BindingPointer<SubjectT>::get;
+ using BindingPointer<SubjectT>::operator->;
+
+ friend class State;
+};
+} // namespace gl
+
+namespace egl
+{
+class Display;
+
+using RefCountObject = angle::RefCountObject<Display, Error>;
+
+template <class ObjectType>
+using RefCountObjectReleaser = angle::RefCountObjectReleaser<ObjectType, Display, Error>;
+
+template <class ObjectType>
+using BindingPointer = angle::BindingPointer<ObjectType, Display, Error>;
+
+} // namespace egl
+
+#endif // LIBANGLE_REFCOUNTOBJECT_H_
diff --git a/gfx/angle/checkout/src/libANGLE/Renderbuffer.cpp b/gfx/angle/checkout/src/libANGLE/Renderbuffer.cpp
new file mode 100644
index 0000000000..ce2445c31e
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Renderbuffer.cpp
@@ -0,0 +1,423 @@
+//
+// Copyright 2002 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.
+//
+
+// Renderbuffer.cpp: Implements the renderer-agnostic gl::Renderbuffer class,
+// GL renderbuffer objects and related functionality.
+// [OpenGL ES 2.0.24] section 4.4.3 page 108.
+
+#include "libANGLE/Renderbuffer.h"
+
+#include "common/utilities.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/Image.h"
+#include "libANGLE/Renderbuffer.h"
+#include "libANGLE/Texture.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/GLImplFactory.h"
+#include "libANGLE/renderer/d3d/RenderTargetD3D.h"
+
+namespace gl
+{
+namespace
+{
+angle::SubjectIndex kRenderbufferImplSubjectIndex = 0;
+
+InitState DetermineInitState(const Context *context)
+{
+ return (context && context->isRobustResourceInitEnabled()) ? InitState::MayNeedInit
+ : InitState::Initialized;
+}
+} // namespace
+
+// RenderbufferState implementation.
+RenderbufferState::RenderbufferState()
+ : mWidth(0),
+ mHeight(0),
+ mFormat(GL_RGBA4),
+ mSamples(0),
+ mMultisamplingMode(MultisamplingMode::Regular),
+ mHasProtectedContent(false),
+ mInitState(InitState::Initialized)
+{}
+
+RenderbufferState::~RenderbufferState() {}
+
+GLsizei RenderbufferState::getWidth() const
+{
+ return mWidth;
+}
+
+GLsizei RenderbufferState::getHeight() const
+{
+ return mHeight;
+}
+
+const Format &RenderbufferState::getFormat() const
+{
+ return mFormat;
+}
+
+GLsizei RenderbufferState::getSamples() const
+{
+ return mSamples;
+}
+
+MultisamplingMode RenderbufferState::getMultisamplingMode() const
+{
+ return mMultisamplingMode;
+}
+
+InitState RenderbufferState::getInitState() const
+{
+ return mInitState;
+}
+
+void RenderbufferState::update(GLsizei width,
+ GLsizei height,
+ const Format &format,
+ GLsizei samples,
+ MultisamplingMode multisamplingMode,
+ InitState initState)
+{
+ mWidth = width;
+ mHeight = height;
+ mFormat = format;
+ mSamples = samples;
+ mMultisamplingMode = multisamplingMode;
+ mInitState = initState;
+ mHasProtectedContent = false;
+}
+
+void RenderbufferState::setProtectedContent(bool hasProtectedContent)
+{
+ mHasProtectedContent = hasProtectedContent;
+}
+
+// Renderbuffer implementation.
+Renderbuffer::Renderbuffer(rx::GLImplFactory *implFactory, RenderbufferID id)
+ : RefCountObject(implFactory->generateSerial(), id),
+ mState(),
+ mImplementation(implFactory->createRenderbuffer(mState)),
+ mLabel(),
+ mImplObserverBinding(this, kRenderbufferImplSubjectIndex)
+{
+ mImplObserverBinding.bind(mImplementation.get());
+}
+
+void Renderbuffer::onDestroy(const Context *context)
+{
+ egl::RefCountObjectReleaser<egl::Image> releaseImage;
+ (void)orphanImages(context, &releaseImage);
+
+ if (mImplementation)
+ {
+ mImplementation->onDestroy(context);
+ }
+}
+
+Renderbuffer::~Renderbuffer() {}
+
+angle::Result Renderbuffer::setLabel(const Context *context, const std::string &label)
+{
+ mLabel = label;
+
+ if (mImplementation)
+ {
+ return mImplementation->onLabelUpdate(context);
+ }
+ return angle::Result::Continue;
+}
+
+const std::string &Renderbuffer::getLabel() const
+{
+ return mLabel;
+}
+
+angle::Result Renderbuffer::setStorage(const Context *context,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height)
+{
+
+ egl::RefCountObjectReleaser<egl::Image> releaseImage;
+ ANGLE_TRY(orphanImages(context, &releaseImage));
+
+ ANGLE_TRY(mImplementation->setStorage(context, internalformat, width, height));
+
+ mState.update(width, height, Format(internalformat), 0, MultisamplingMode::Regular,
+ DetermineInitState(context));
+ onStateChange(angle::SubjectMessage::SubjectChanged);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Renderbuffer::setStorageMultisample(const Context *context,
+ GLsizei samplesIn,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ MultisamplingMode mode)
+{
+ egl::RefCountObjectReleaser<egl::Image> releaseImage;
+ ANGLE_TRY(orphanImages(context, &releaseImage));
+
+ // Potentially adjust "samplesIn" to a supported value
+ const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
+ GLsizei samples = formatCaps.getNearestSamples(samplesIn);
+
+ ANGLE_TRY(mImplementation->setStorageMultisample(context, samples, internalformat, width,
+ height, mode));
+
+ mState.update(width, height, Format(internalformat), samples, mode,
+ DetermineInitState(context));
+ onStateChange(angle::SubjectMessage::SubjectChanged);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Renderbuffer::setStorageEGLImageTarget(const Context *context, egl::Image *image)
+{
+ egl::RefCountObjectReleaser<egl::Image> releaseImage;
+ ANGLE_TRY(orphanImages(context, &releaseImage));
+
+ ANGLE_TRY(mImplementation->setStorageEGLImageTarget(context, image));
+
+ setTargetImage(context, image);
+
+ mState.update(static_cast<GLsizei>(image->getWidth()), static_cast<GLsizei>(image->getHeight()),
+ Format(image->getFormat()), 0, MultisamplingMode::Regular,
+ image->sourceInitState());
+ mState.setProtectedContent(image->hasProtectedContent());
+
+ onStateChange(angle::SubjectMessage::SubjectChanged);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Renderbuffer::copyRenderbufferSubData(Context *context,
+ const gl::Renderbuffer *srcBuffer,
+ GLint srcLevel,
+ GLint srcX,
+ GLint srcY,
+ GLint srcZ,
+ GLint dstLevel,
+ GLint dstX,
+ GLint dstY,
+ GLint dstZ,
+ GLsizei srcWidth,
+ GLsizei srcHeight,
+ GLsizei srcDepth)
+{
+ ANGLE_TRY(mImplementation->copyRenderbufferSubData(context, srcBuffer, srcLevel, srcX, srcY,
+ srcZ, dstLevel, dstX, dstY, dstZ, srcWidth,
+ srcHeight, srcDepth));
+
+ return angle::Result::Continue;
+}
+
+angle::Result Renderbuffer::copyTextureSubData(Context *context,
+ const gl::Texture *srcTexture,
+ GLint srcLevel,
+ GLint srcX,
+ GLint srcY,
+ GLint srcZ,
+ GLint dstLevel,
+ GLint dstX,
+ GLint dstY,
+ GLint dstZ,
+ GLsizei srcWidth,
+ GLsizei srcHeight,
+ GLsizei srcDepth)
+{
+ ANGLE_TRY(mImplementation->copyTextureSubData(context, srcTexture, srcLevel, srcX, srcY, srcZ,
+ dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight,
+ srcDepth));
+
+ return angle::Result::Continue;
+}
+
+rx::RenderbufferImpl *Renderbuffer::getImplementation() const
+{
+ ASSERT(mImplementation);
+ return mImplementation.get();
+}
+
+GLsizei Renderbuffer::getWidth() const
+{
+ return mState.mWidth;
+}
+
+GLsizei Renderbuffer::getHeight() const
+{
+ return mState.mHeight;
+}
+
+const Format &Renderbuffer::getFormat() const
+{
+ return mState.mFormat;
+}
+
+GLsizei Renderbuffer::getSamples() const
+{
+ return mState.mMultisamplingMode == MultisamplingMode::Regular ? mState.mSamples : 0;
+}
+
+MultisamplingMode Renderbuffer::getMultisamplingMode() const
+{
+ return mState.mMultisamplingMode;
+}
+
+GLuint Renderbuffer::getRedSize() const
+{
+ return mState.mFormat.info->redBits;
+}
+
+GLuint Renderbuffer::getGreenSize() const
+{
+ return mState.mFormat.info->greenBits;
+}
+
+GLuint Renderbuffer::getBlueSize() const
+{
+ return mState.mFormat.info->blueBits;
+}
+
+GLuint Renderbuffer::getAlphaSize() const
+{
+ return mState.mFormat.info->alphaBits;
+}
+
+GLuint Renderbuffer::getDepthSize() const
+{
+ return mState.mFormat.info->depthBits;
+}
+
+GLuint Renderbuffer::getStencilSize() const
+{
+ return mState.mFormat.info->stencilBits;
+}
+
+const RenderbufferState &Renderbuffer::getState() const
+{
+ return mState;
+}
+
+GLint Renderbuffer::getMemorySize() const
+{
+ GLint implSize = mImplementation->getMemorySize();
+ if (implSize > 0)
+ {
+ return implSize;
+ }
+
+ // Assume allocated size is around width * height * samples * pixelBytes
+ angle::CheckedNumeric<GLint> size = 1;
+ size *= mState.mFormat.info->pixelBytes;
+ size *= mState.mWidth;
+ size *= mState.mHeight;
+ size *= std::max(mState.mSamples, 1);
+ return size.ValueOrDefault(std::numeric_limits<GLint>::max());
+}
+
+void Renderbuffer::onAttach(const Context *context, rx::Serial framebufferSerial)
+{
+ addRef();
+}
+
+void Renderbuffer::onDetach(const Context *context, rx::Serial framebufferSerial)
+{
+ release(context);
+}
+
+GLuint Renderbuffer::getId() const
+{
+ return id().value;
+}
+
+Extents Renderbuffer::getAttachmentSize(const gl::ImageIndex & /*imageIndex*/) const
+{
+ return Extents(mState.mWidth, mState.mHeight, 1);
+}
+
+Format Renderbuffer::getAttachmentFormat(GLenum /*binding*/,
+ const ImageIndex & /*imageIndex*/) const
+{
+ return getFormat();
+}
+GLsizei Renderbuffer::getAttachmentSamples(const ImageIndex & /*imageIndex*/) const
+{
+ return getSamples();
+}
+
+bool Renderbuffer::isRenderable(const Context *context,
+ GLenum binding,
+ const ImageIndex &imageIndex) const
+{
+ if (isEGLImageTarget())
+ {
+ return ImageSibling::isRenderable(context, binding, imageIndex);
+ }
+ return getFormat().info->renderbufferSupport(context->getClientVersion(),
+ context->getExtensions());
+}
+
+InitState Renderbuffer::initState(GLenum /*binding*/, const gl::ImageIndex & /*imageIndex*/) const
+{
+ if (isEGLImageTarget())
+ {
+ return sourceEGLImageInitState();
+ }
+
+ return mState.mInitState;
+}
+
+void Renderbuffer::setInitState(GLenum /*binding*/,
+ const gl::ImageIndex & /*imageIndex*/,
+ InitState initState)
+{
+ if (isEGLImageTarget())
+ {
+ setSourceEGLImageInitState(initState);
+ }
+ else
+ {
+ mState.mInitState = initState;
+ }
+}
+
+rx::FramebufferAttachmentObjectImpl *Renderbuffer::getAttachmentImpl() const
+{
+ return mImplementation.get();
+}
+
+GLenum Renderbuffer::getImplementationColorReadFormat(const Context *context) const
+{
+ return mImplementation->getColorReadFormat(context);
+}
+
+GLenum Renderbuffer::getImplementationColorReadType(const Context *context) const
+{
+ return mImplementation->getColorReadType(context);
+}
+
+angle::Result Renderbuffer::getRenderbufferImage(const Context *context,
+ const PixelPackState &packState,
+ Buffer *packBuffer,
+ GLenum format,
+ GLenum type,
+ void *pixels) const
+{
+ return mImplementation->getRenderbufferImage(context, packState, packBuffer, format, type,
+ pixels);
+}
+
+void Renderbuffer::onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message)
+{
+ ASSERT(message == angle::SubjectMessage::SubjectChanged);
+ onStateChange(angle::SubjectMessage::ContentsChanged);
+}
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/Renderbuffer.h b/gfx/angle/checkout/src/libANGLE/Renderbuffer.h
new file mode 100644
index 0000000000..1f85afc5e5
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Renderbuffer.h
@@ -0,0 +1,181 @@
+//
+// Copyright 2002 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.
+//
+
+// Renderbuffer.h: Defines the renderer-agnostic container class gl::Renderbuffer.
+// Implements GL renderbuffer objects and related functionality.
+// [OpenGL ES 2.0.24] section 4.4.3 page 108.
+
+#ifndef LIBANGLE_RENDERBUFFER_H_
+#define LIBANGLE_RENDERBUFFER_H_
+
+#include "angle_gl.h"
+#include "common/angleutils.h"
+#include "libANGLE/Debug.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/Image.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/RenderbufferImpl.h"
+
+namespace rx
+{
+class GLImplFactory;
+} // namespace rx
+
+namespace gl
+{
+// A GL renderbuffer object is usually used as a depth or stencil buffer attachment
+// for a framebuffer object. The renderbuffer itself is a distinct GL object, see
+// FramebufferAttachment and Framebuffer for how they are applied to an FBO via an
+// attachment point.
+
+class RenderbufferState final : angle::NonCopyable
+{
+ public:
+ RenderbufferState();
+ ~RenderbufferState();
+
+ GLsizei getWidth() const;
+ GLsizei getHeight() const;
+ const Format &getFormat() const;
+ GLsizei getSamples() const;
+ MultisamplingMode getMultisamplingMode() const;
+ InitState getInitState() const;
+ void setProtectedContent(bool hasProtectedContent);
+
+ private:
+ friend class Renderbuffer;
+
+ void update(GLsizei width,
+ GLsizei height,
+ const Format &format,
+ GLsizei samples,
+ MultisamplingMode multisamplingMode,
+ InitState initState);
+
+ GLsizei mWidth;
+ GLsizei mHeight;
+ Format mFormat;
+ GLsizei mSamples;
+ MultisamplingMode mMultisamplingMode;
+ bool mHasProtectedContent;
+
+ // For robust resource init.
+ InitState mInitState;
+};
+
+class Renderbuffer final : public RefCountObject<RenderbufferID>,
+ public egl::ImageSibling,
+ public LabeledObject
+{
+ public:
+ Renderbuffer(rx::GLImplFactory *implFactory, RenderbufferID id);
+ ~Renderbuffer() override;
+
+ void onDestroy(const Context *context) override;
+
+ angle::Result setLabel(const Context *context, const std::string &label) override;
+ const std::string &getLabel() const override;
+
+ angle::Result setStorage(const Context *context,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height);
+ angle::Result setStorageMultisample(const Context *context,
+ GLsizei samplesIn,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ MultisamplingMode mode);
+ angle::Result setStorageEGLImageTarget(const Context *context, egl::Image *imageTarget);
+
+ angle::Result copyRenderbufferSubData(Context *context,
+ const gl::Renderbuffer *srcBuffer,
+ GLint srcLevel,
+ GLint srcX,
+ GLint srcY,
+ GLint srcZ,
+ GLint dstLevel,
+ GLint dstX,
+ GLint dstY,
+ GLint dstZ,
+ GLsizei srcWidth,
+ GLsizei srcHeight,
+ GLsizei srcDepth);
+
+ angle::Result copyTextureSubData(Context *context,
+ const gl::Texture *srcTexture,
+ GLint srcLevel,
+ GLint srcX,
+ GLint srcY,
+ GLint srcZ,
+ GLint dstLevel,
+ GLint dstX,
+ GLint dstY,
+ GLint dstZ,
+ GLsizei srcWidth,
+ GLsizei srcHeight,
+ GLsizei srcDepth);
+
+ rx::RenderbufferImpl *getImplementation() const;
+
+ GLsizei getWidth() const;
+ GLsizei getHeight() const;
+ const Format &getFormat() const;
+ GLsizei getSamples() const;
+ MultisamplingMode getMultisamplingMode() const;
+ GLuint getRedSize() const;
+ GLuint getGreenSize() const;
+ GLuint getBlueSize() const;
+ GLuint getAlphaSize() const;
+ GLuint getDepthSize() const;
+ GLuint getStencilSize() const;
+ const RenderbufferState &getState() const;
+
+ GLint getMemorySize() const;
+
+ // FramebufferAttachmentObject Impl
+ Extents getAttachmentSize(const ImageIndex &imageIndex) const override;
+ Format getAttachmentFormat(GLenum binding, const ImageIndex &imageIndex) const override;
+ GLsizei getAttachmentSamples(const ImageIndex &imageIndex) const override;
+ bool isRenderable(const Context *context,
+ GLenum binding,
+ const ImageIndex &imageIndex) const override;
+
+ void onAttach(const Context *context, rx::Serial framebufferSerial) override;
+ void onDetach(const Context *context, rx::Serial framebufferSerial) override;
+ GLuint getId() const override;
+
+ InitState initState(GLenum binding, const ImageIndex &imageIndex) const override;
+ void setInitState(GLenum binding, const ImageIndex &imageIndex, InitState initState) override;
+
+ GLenum getImplementationColorReadFormat(const Context *context) const;
+ GLenum getImplementationColorReadType(const Context *context) const;
+
+ // We pass the pack buffer and state explicitly so they can be overridden during capture.
+ angle::Result getRenderbufferImage(const Context *context,
+ const PixelPackState &packState,
+ Buffer *packBuffer,
+ GLenum format,
+ GLenum type,
+ void *pixels) const;
+
+ private:
+ // ObserverInterface implementation.
+ void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override;
+
+ rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override;
+
+ RenderbufferState mState;
+ std::unique_ptr<rx::RenderbufferImpl> mImplementation;
+
+ std::string mLabel;
+ angle::ObserverBinding mImplObserverBinding;
+};
+
+} // namespace gl
+
+#endif // LIBANGLE_RENDERBUFFER_H_
diff --git a/gfx/angle/checkout/src/libANGLE/ResourceManager.cpp b/gfx/angle/checkout/src/libANGLE/ResourceManager.cpp
new file mode 100644
index 0000000000..d5efce2319
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/ResourceManager.cpp
@@ -0,0 +1,522 @@
+//
+// Copyright 2002 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.
+//
+
+// ResourceManager.cpp: Implements the the ResourceManager classes, which handle allocation and
+// lifetime of GL objects.
+
+#include "libANGLE/ResourceManager.h"
+
+#include "libANGLE/Buffer.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Fence.h"
+#include "libANGLE/MemoryObject.h"
+#include "libANGLE/Program.h"
+#include "libANGLE/ProgramPipeline.h"
+#include "libANGLE/Query.h"
+#include "libANGLE/Renderbuffer.h"
+#include "libANGLE/Sampler.h"
+#include "libANGLE/Semaphore.h"
+#include "libANGLE/Shader.h"
+#include "libANGLE/Texture.h"
+#include "libANGLE/renderer/ContextImpl.h"
+
+namespace gl
+{
+
+namespace
+{
+
+template <typename ResourceType, typename IDType>
+IDType AllocateEmptyObject(HandleAllocator *handleAllocator,
+ ResourceMap<ResourceType, IDType> *objectMap)
+{
+ IDType handle = PackParam<IDType>(handleAllocator->allocate());
+ objectMap->assign(handle, nullptr);
+ return handle;
+}
+
+} // anonymous namespace
+
+ResourceManagerBase::ResourceManagerBase() : mRefCount(1) {}
+
+ResourceManagerBase::~ResourceManagerBase() = default;
+
+void ResourceManagerBase::addRef()
+{
+ mRefCount++;
+}
+
+void ResourceManagerBase::release(const Context *context)
+{
+ if (--mRefCount == 0)
+ {
+ reset(context);
+ delete this;
+ }
+}
+
+template <typename ResourceType, typename ImplT, typename IDType>
+TypedResourceManager<ResourceType, ImplT, IDType>::~TypedResourceManager()
+{
+ ASSERT(mObjectMap.empty());
+}
+
+template <typename ResourceType, typename ImplT, typename IDType>
+void TypedResourceManager<ResourceType, ImplT, IDType>::reset(const Context *context)
+{
+ this->mHandleAllocator.reset();
+ for (const auto &resource : mObjectMap)
+ {
+ if (resource.second)
+ {
+ ImplT::DeleteObject(context, resource.second);
+ }
+ }
+ mObjectMap.clear();
+}
+
+template <typename ResourceType, typename ImplT, typename IDType>
+void TypedResourceManager<ResourceType, ImplT, IDType>::deleteObject(const Context *context,
+ IDType handle)
+{
+ ResourceType *resource = nullptr;
+ if (!mObjectMap.erase(handle, &resource))
+ {
+ return;
+ }
+
+ // Requires an explicit this-> because of C++ template rules.
+ this->mHandleAllocator.release(GetIDValue(handle));
+
+ if (resource)
+ {
+ ImplT::DeleteObject(context, resource);
+ }
+}
+
+template class TypedResourceManager<Buffer, BufferManager, BufferID>;
+template class TypedResourceManager<Texture, TextureManager, TextureID>;
+template class TypedResourceManager<Renderbuffer, RenderbufferManager, RenderbufferID>;
+template class TypedResourceManager<Sampler, SamplerManager, SamplerID>;
+template class TypedResourceManager<Sync, SyncManager, GLuint>;
+template class TypedResourceManager<Framebuffer, FramebufferManager, FramebufferID>;
+template class TypedResourceManager<ProgramPipeline, ProgramPipelineManager, ProgramPipelineID>;
+
+// BufferManager Implementation.
+BufferManager::~BufferManager() = default;
+
+// static
+Buffer *BufferManager::AllocateNewObject(rx::GLImplFactory *factory, BufferID handle)
+{
+ Buffer *buffer = new Buffer(factory, handle);
+ buffer->addRef();
+ return buffer;
+}
+
+// static
+void BufferManager::DeleteObject(const Context *context, Buffer *buffer)
+{
+ buffer->release(context);
+}
+
+BufferID BufferManager::createBuffer()
+{
+ return AllocateEmptyObject(&mHandleAllocator, &mObjectMap);
+}
+
+Buffer *BufferManager::getBuffer(BufferID handle) const
+{
+ return mObjectMap.query(handle);
+}
+
+// ShaderProgramManager Implementation.
+
+ShaderProgramManager::ShaderProgramManager() {}
+
+ShaderProgramManager::~ShaderProgramManager()
+{
+ ASSERT(mPrograms.empty());
+ ASSERT(mShaders.empty());
+}
+
+void ShaderProgramManager::reset(const Context *context)
+{
+ while (!mPrograms.empty())
+ {
+ deleteProgram(context, {mPrograms.begin()->first});
+ }
+ mPrograms.clear();
+ while (!mShaders.empty())
+ {
+ deleteShader(context, {mShaders.begin()->first});
+ }
+ mShaders.clear();
+}
+
+ShaderProgramID ShaderProgramManager::createShader(rx::GLImplFactory *factory,
+ const gl::Limitations &rendererLimitations,
+ ShaderType type)
+{
+ ASSERT(type != ShaderType::InvalidEnum);
+ ShaderProgramID handle = ShaderProgramID{mHandleAllocator.allocate()};
+ mShaders.assign(handle, new Shader(this, factory, rendererLimitations, type, handle));
+ return handle;
+}
+
+void ShaderProgramManager::deleteShader(const Context *context, ShaderProgramID shader)
+{
+ deleteObject(context, &mShaders, shader);
+}
+
+Shader *ShaderProgramManager::getShader(ShaderProgramID handle) const
+{
+ return mShaders.query(handle);
+}
+
+ShaderProgramID ShaderProgramManager::createProgram(rx::GLImplFactory *factory)
+{
+ ShaderProgramID handle = ShaderProgramID{mHandleAllocator.allocate()};
+ mPrograms.assign(handle, new Program(factory, this, handle));
+ return handle;
+}
+
+void ShaderProgramManager::deleteProgram(const gl::Context *context, ShaderProgramID program)
+{
+ deleteObject(context, &mPrograms, program);
+}
+
+template <typename ObjectType, typename IDType>
+void ShaderProgramManager::deleteObject(const Context *context,
+ ResourceMap<ObjectType, IDType> *objectMap,
+ IDType id)
+{
+ ObjectType *object = objectMap->query(id);
+ if (!object)
+ {
+ return;
+ }
+
+ if (object->getRefCount() == 0)
+ {
+ mHandleAllocator.release(id.value);
+ object->onDestroy(context);
+ objectMap->erase(id, &object);
+ }
+ else
+ {
+ object->flagForDeletion();
+ }
+}
+
+// TextureManager Implementation.
+
+TextureManager::~TextureManager() = default;
+
+// static
+Texture *TextureManager::AllocateNewObject(rx::GLImplFactory *factory,
+ TextureID handle,
+ TextureType type)
+{
+ Texture *texture = new Texture(factory, handle, type);
+ texture->addRef();
+ return texture;
+}
+
+// static
+void TextureManager::DeleteObject(const Context *context, Texture *texture)
+{
+ texture->release(context);
+}
+
+TextureID TextureManager::createTexture()
+{
+ return AllocateEmptyObject(&mHandleAllocator, &mObjectMap);
+}
+
+void TextureManager::signalAllTexturesDirty() const
+{
+ for (const auto &texture : mObjectMap)
+ {
+ if (texture.second)
+ {
+ // We don't know if the Texture needs init, but that's ok, since it will only force
+ // a re-check, and will not initialize the pixels if it's not needed.
+ texture.second->signalDirtyStorage(InitState::MayNeedInit);
+ }
+ }
+}
+
+void TextureManager::enableHandleAllocatorLogging()
+{
+ mHandleAllocator.enableLogging(true);
+}
+
+// RenderbufferManager Implementation.
+
+RenderbufferManager::~RenderbufferManager() = default;
+
+// static
+Renderbuffer *RenderbufferManager::AllocateNewObject(rx::GLImplFactory *factory,
+ RenderbufferID handle)
+{
+ Renderbuffer *renderbuffer = new Renderbuffer(factory, handle);
+ renderbuffer->addRef();
+ return renderbuffer;
+}
+
+// static
+void RenderbufferManager::DeleteObject(const Context *context, Renderbuffer *renderbuffer)
+{
+ renderbuffer->release(context);
+}
+
+RenderbufferID RenderbufferManager::createRenderbuffer()
+{
+ return {AllocateEmptyObject(&mHandleAllocator, &mObjectMap)};
+}
+
+Renderbuffer *RenderbufferManager::getRenderbuffer(RenderbufferID handle) const
+{
+ return mObjectMap.query(handle);
+}
+
+// SamplerManager Implementation.
+
+SamplerManager::~SamplerManager() = default;
+
+// static
+Sampler *SamplerManager::AllocateNewObject(rx::GLImplFactory *factory, SamplerID handle)
+{
+ Sampler *sampler = new Sampler(factory, handle);
+ sampler->addRef();
+ return sampler;
+}
+
+// static
+void SamplerManager::DeleteObject(const Context *context, Sampler *sampler)
+{
+ sampler->release(context);
+}
+
+SamplerID SamplerManager::createSampler()
+{
+ return AllocateEmptyObject(&mHandleAllocator, &mObjectMap);
+}
+
+Sampler *SamplerManager::getSampler(SamplerID handle) const
+{
+ return mObjectMap.query(handle);
+}
+
+bool SamplerManager::isSampler(SamplerID sampler) const
+{
+ return mObjectMap.contains(sampler);
+}
+
+// SyncManager Implementation.
+
+SyncManager::~SyncManager() = default;
+
+// static
+void SyncManager::DeleteObject(const Context *context, Sync *sync)
+{
+ sync->release(context);
+}
+
+GLuint SyncManager::createSync(rx::GLImplFactory *factory)
+{
+ GLuint handle = mHandleAllocator.allocate();
+ Sync *sync = new Sync(factory, handle);
+ sync->addRef();
+ mObjectMap.assign(handle, sync);
+ return handle;
+}
+
+Sync *SyncManager::getSync(GLuint handle) const
+{
+ return mObjectMap.query(handle);
+}
+
+// FramebufferManager Implementation.
+
+FramebufferManager::~FramebufferManager() = default;
+
+// static
+Framebuffer *FramebufferManager::AllocateNewObject(rx::GLImplFactory *factory,
+ FramebufferID handle,
+ const Context *context)
+{
+ // Make sure the caller isn't using a reserved handle.
+ ASSERT(handle != Framebuffer::kDefaultDrawFramebufferHandle);
+ return new Framebuffer(context, factory, handle);
+}
+
+// static
+void FramebufferManager::DeleteObject(const Context *context, Framebuffer *framebuffer)
+{
+ framebuffer->onDestroy(context);
+ delete framebuffer;
+}
+
+FramebufferID FramebufferManager::createFramebuffer()
+{
+ return AllocateEmptyObject(&mHandleAllocator, &mObjectMap);
+}
+
+Framebuffer *FramebufferManager::getFramebuffer(FramebufferID handle) const
+{
+ return mObjectMap.query(handle);
+}
+
+void FramebufferManager::setDefaultFramebuffer(Framebuffer *framebuffer)
+{
+ ASSERT(framebuffer == nullptr || framebuffer->isDefault());
+ mObjectMap.assign(Framebuffer::kDefaultDrawFramebufferHandle, framebuffer);
+}
+
+Framebuffer *FramebufferManager::getDefaultFramebuffer() const
+{
+ return getFramebuffer(Framebuffer::kDefaultDrawFramebufferHandle);
+}
+
+void FramebufferManager::invalidateFramebufferCompletenessCache() const
+{
+ for (const auto &framebuffer : mObjectMap)
+ {
+ if (framebuffer.second)
+ {
+ framebuffer.second->invalidateCompletenessCache();
+ }
+ }
+}
+
+// ProgramPipelineManager Implementation.
+
+ProgramPipelineManager::~ProgramPipelineManager() = default;
+
+// static
+ProgramPipeline *ProgramPipelineManager::AllocateNewObject(rx::GLImplFactory *factory,
+ ProgramPipelineID handle)
+{
+ ProgramPipeline *pipeline = new ProgramPipeline(factory, handle);
+ pipeline->addRef();
+ return pipeline;
+}
+
+// static
+void ProgramPipelineManager::DeleteObject(const Context *context, ProgramPipeline *pipeline)
+{
+ pipeline->release(context);
+}
+
+ProgramPipelineID ProgramPipelineManager::createProgramPipeline()
+{
+ return AllocateEmptyObject(&mHandleAllocator, &mObjectMap);
+}
+
+ProgramPipeline *ProgramPipelineManager::getProgramPipeline(ProgramPipelineID handle) const
+{
+ return mObjectMap.query(handle);
+}
+
+// MemoryObjectManager Implementation.
+
+MemoryObjectManager::MemoryObjectManager() {}
+
+MemoryObjectManager::~MemoryObjectManager()
+{
+ ASSERT(mMemoryObjects.empty());
+}
+
+void MemoryObjectManager::reset(const Context *context)
+{
+ while (!mMemoryObjects.empty())
+ {
+ deleteMemoryObject(context, {mMemoryObjects.begin()->first});
+ }
+ mMemoryObjects.clear();
+}
+
+MemoryObjectID MemoryObjectManager::createMemoryObject(rx::GLImplFactory *factory)
+{
+ MemoryObjectID handle = MemoryObjectID{mHandleAllocator.allocate()};
+ MemoryObject *memoryObject = new MemoryObject(factory, handle);
+ memoryObject->addRef();
+ mMemoryObjects.assign(handle, memoryObject);
+ return handle;
+}
+
+void MemoryObjectManager::deleteMemoryObject(const Context *context, MemoryObjectID handle)
+{
+ MemoryObject *memoryObject = nullptr;
+ if (!mMemoryObjects.erase(handle, &memoryObject))
+ {
+ return;
+ }
+
+ // Requires an explicit this-> because of C++ template rules.
+ this->mHandleAllocator.release(handle.value);
+
+ if (memoryObject)
+ {
+ memoryObject->release(context);
+ }
+}
+
+MemoryObject *MemoryObjectManager::getMemoryObject(MemoryObjectID handle) const
+{
+ return mMemoryObjects.query(handle);
+}
+
+// SemaphoreManager Implementation.
+
+SemaphoreManager::SemaphoreManager() {}
+
+SemaphoreManager::~SemaphoreManager()
+{
+ ASSERT(mSemaphores.empty());
+}
+
+void SemaphoreManager::reset(const Context *context)
+{
+ while (!mSemaphores.empty())
+ {
+ deleteSemaphore(context, {mSemaphores.begin()->first});
+ }
+ mSemaphores.clear();
+}
+
+SemaphoreID SemaphoreManager::createSemaphore(rx::GLImplFactory *factory)
+{
+ SemaphoreID handle = SemaphoreID{mHandleAllocator.allocate()};
+ Semaphore *semaphore = new Semaphore(factory, handle);
+ semaphore->addRef();
+ mSemaphores.assign(handle, semaphore);
+ return handle;
+}
+
+void SemaphoreManager::deleteSemaphore(const Context *context, SemaphoreID handle)
+{
+ Semaphore *semaphore = nullptr;
+ if (!mSemaphores.erase(handle, &semaphore))
+ {
+ return;
+ }
+
+ // Requires an explicit this-> because of C++ template rules.
+ this->mHandleAllocator.release(handle.value);
+
+ if (semaphore)
+ {
+ semaphore->release(context);
+ }
+}
+
+Semaphore *SemaphoreManager::getSemaphore(SemaphoreID handle) const
+{
+ return mSemaphores.query(handle);
+}
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/ResourceManager.h b/gfx/angle/checkout/src/libANGLE/ResourceManager.h
new file mode 100644
index 0000000000..0f8447ed24
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/ResourceManager.h
@@ -0,0 +1,353 @@
+//
+// Copyright 2002 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.
+//
+
+// ResourceManager.h : Defines the ResourceManager classes, which handle allocation and lifetime of
+// GL objects.
+
+#ifndef LIBANGLE_RESOURCEMANAGER_H_
+#define LIBANGLE_RESOURCEMANAGER_H_
+
+#include "angle_gl.h"
+#include "common/angleutils.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/HandleAllocator.h"
+#include "libANGLE/ResourceMap.h"
+
+namespace rx
+{
+class GLImplFactory;
+} // namespace rx
+
+namespace egl
+{
+class ShareGroup;
+} // namespace egl
+
+namespace gl
+{
+class Buffer;
+struct Caps;
+class Context;
+class Framebuffer;
+struct Limitations;
+class MemoryObject;
+class Path;
+class Program;
+class ProgramPipeline;
+class Renderbuffer;
+class Sampler;
+class Semaphore;
+class Shader;
+class Sync;
+class Texture;
+
+class ResourceManagerBase : angle::NonCopyable
+{
+ public:
+ ResourceManagerBase();
+
+ void addRef();
+ void release(const Context *context);
+
+ protected:
+ virtual void reset(const Context *context) = 0;
+ virtual ~ResourceManagerBase();
+
+ HandleAllocator mHandleAllocator;
+
+ private:
+ size_t mRefCount;
+};
+
+template <typename ResourceType, typename ImplT, typename IDType>
+class TypedResourceManager : public ResourceManagerBase
+{
+ public:
+ TypedResourceManager() {}
+
+ void deleteObject(const Context *context, IDType handle);
+ ANGLE_INLINE bool isHandleGenerated(IDType handle) const
+ {
+ // Zero is always assumed to have been generated implicitly.
+ return GetIDValue(handle) == 0 || mObjectMap.contains(handle);
+ }
+
+ typename ResourceMap<ResourceType, IDType>::Iterator begin() const
+ {
+ return mObjectMap.begin();
+ }
+ typename ResourceMap<ResourceType, IDType>::Iterator end() const { return mObjectMap.end(); }
+
+ protected:
+ ~TypedResourceManager() override;
+
+ // Inlined in the header for performance.
+ template <typename... ArgTypes>
+ ANGLE_INLINE ResourceType *checkObjectAllocation(rx::GLImplFactory *factory,
+ IDType handle,
+ ArgTypes... args)
+ {
+ ResourceType *value = mObjectMap.query(handle);
+ if (value)
+ {
+ return value;
+ }
+
+ if (GetIDValue(handle) == 0)
+ {
+ return nullptr;
+ }
+
+ return checkObjectAllocationImpl(factory, handle, args...);
+ }
+
+ void reset(const Context *context) override;
+
+ ResourceMap<ResourceType, IDType> mObjectMap;
+
+ private:
+ template <typename... ArgTypes>
+ ResourceType *checkObjectAllocationImpl(rx::GLImplFactory *factory,
+ IDType handle,
+ ArgTypes... args)
+ {
+ ResourceType *object = ImplT::AllocateNewObject(factory, handle, args...);
+
+ if (!mObjectMap.contains(handle))
+ {
+ this->mHandleAllocator.reserve(GetIDValue(handle));
+ }
+ mObjectMap.assign(handle, object);
+
+ return object;
+ }
+};
+
+class BufferManager : public TypedResourceManager<Buffer, BufferManager, BufferID>
+{
+ public:
+ BufferID createBuffer();
+ Buffer *getBuffer(BufferID handle) const;
+
+ ANGLE_INLINE Buffer *checkBufferAllocation(rx::GLImplFactory *factory, BufferID handle)
+ {
+ return checkObjectAllocation(factory, handle);
+ }
+
+ // TODO(jmadill): Investigate design which doesn't expose these methods publicly.
+ static Buffer *AllocateNewObject(rx::GLImplFactory *factory, BufferID handle);
+ static void DeleteObject(const Context *context, Buffer *buffer);
+
+ protected:
+ ~BufferManager() override;
+};
+
+class ShaderProgramManager : public ResourceManagerBase
+{
+ public:
+ ShaderProgramManager();
+
+ ShaderProgramID createShader(rx::GLImplFactory *factory,
+ const Limitations &rendererLimitations,
+ ShaderType type);
+ void deleteShader(const Context *context, ShaderProgramID shader);
+ Shader *getShader(ShaderProgramID handle) const;
+
+ ShaderProgramID createProgram(rx::GLImplFactory *factory);
+ void deleteProgram(const Context *context, ShaderProgramID program);
+
+ ANGLE_INLINE Program *getProgram(ShaderProgramID handle) const
+ {
+ return mPrograms.query(handle);
+ }
+
+ // For capture and performance counters only.
+ const ResourceMap<Shader, ShaderProgramID> &getShadersForCapture() const { return mShaders; }
+ const ResourceMap<Program, ShaderProgramID> &getProgramsForCaptureAndPerf() const
+ {
+ return mPrograms;
+ }
+
+ protected:
+ ~ShaderProgramManager() override;
+
+ private:
+ template <typename ObjectType, typename IDType>
+ void deleteObject(const Context *context,
+ ResourceMap<ObjectType, IDType> *objectMap,
+ IDType id);
+
+ void reset(const Context *context) override;
+
+ ResourceMap<Shader, ShaderProgramID> mShaders;
+ ResourceMap<Program, ShaderProgramID> mPrograms;
+};
+
+class TextureManager : public TypedResourceManager<Texture, TextureManager, TextureID>
+{
+ public:
+ TextureID createTexture();
+ ANGLE_INLINE Texture *getTexture(TextureID handle) const
+ {
+ ASSERT(mObjectMap.query({0}) == nullptr);
+ return mObjectMap.query(handle);
+ }
+
+ void signalAllTexturesDirty() const;
+
+ ANGLE_INLINE Texture *checkTextureAllocation(rx::GLImplFactory *factory,
+ TextureID handle,
+ TextureType type)
+ {
+ return checkObjectAllocation(factory, handle, type);
+ }
+
+ static Texture *AllocateNewObject(rx::GLImplFactory *factory,
+ TextureID handle,
+ TextureType type);
+ static void DeleteObject(const Context *context, Texture *texture);
+
+ void enableHandleAllocatorLogging();
+
+ protected:
+ ~TextureManager() override;
+};
+
+class RenderbufferManager
+ : public TypedResourceManager<Renderbuffer, RenderbufferManager, RenderbufferID>
+{
+ public:
+ RenderbufferID createRenderbuffer();
+ Renderbuffer *getRenderbuffer(RenderbufferID handle) const;
+
+ Renderbuffer *checkRenderbufferAllocation(rx::GLImplFactory *factory, RenderbufferID handle)
+ {
+ return checkObjectAllocation(factory, handle);
+ }
+
+ static Renderbuffer *AllocateNewObject(rx::GLImplFactory *factory, RenderbufferID handle);
+ static void DeleteObject(const Context *context, Renderbuffer *renderbuffer);
+
+ protected:
+ ~RenderbufferManager() override;
+};
+
+class SamplerManager : public TypedResourceManager<Sampler, SamplerManager, SamplerID>
+{
+ public:
+ SamplerID createSampler();
+ Sampler *getSampler(SamplerID handle) const;
+ bool isSampler(SamplerID sampler) const;
+
+ Sampler *checkSamplerAllocation(rx::GLImplFactory *factory, SamplerID handle)
+ {
+ return checkObjectAllocation(factory, handle);
+ }
+
+ static Sampler *AllocateNewObject(rx::GLImplFactory *factory, SamplerID handle);
+ static void DeleteObject(const Context *context, Sampler *sampler);
+
+ protected:
+ ~SamplerManager() override;
+};
+
+class SyncManager : public TypedResourceManager<Sync, SyncManager, GLuint>
+{
+ public:
+ GLuint createSync(rx::GLImplFactory *factory);
+ Sync *getSync(GLuint handle) const;
+
+ static void DeleteObject(const Context *context, Sync *sync);
+
+ protected:
+ ~SyncManager() override;
+};
+
+class FramebufferManager
+ : public TypedResourceManager<Framebuffer, FramebufferManager, FramebufferID>
+{
+ public:
+ FramebufferID createFramebuffer();
+ Framebuffer *getFramebuffer(FramebufferID handle) const;
+ void setDefaultFramebuffer(Framebuffer *framebuffer);
+ Framebuffer *getDefaultFramebuffer() const;
+
+ void invalidateFramebufferCompletenessCache() const;
+
+ Framebuffer *checkFramebufferAllocation(rx::GLImplFactory *factory,
+ const Context *context,
+ FramebufferID handle)
+ {
+ return checkObjectAllocation(factory, handle, context);
+ }
+
+ static Framebuffer *AllocateNewObject(rx::GLImplFactory *factory,
+ FramebufferID handle,
+ const Context *context);
+ static void DeleteObject(const Context *context, Framebuffer *framebuffer);
+
+ protected:
+ ~FramebufferManager() override;
+};
+
+class ProgramPipelineManager
+ : public TypedResourceManager<ProgramPipeline, ProgramPipelineManager, ProgramPipelineID>
+{
+ public:
+ ProgramPipelineID createProgramPipeline();
+ ProgramPipeline *getProgramPipeline(ProgramPipelineID handle) const;
+
+ ProgramPipeline *checkProgramPipelineAllocation(rx::GLImplFactory *factory,
+ ProgramPipelineID handle)
+ {
+ return checkObjectAllocation(factory, handle);
+ }
+
+ static ProgramPipeline *AllocateNewObject(rx::GLImplFactory *factory, ProgramPipelineID handle);
+ static void DeleteObject(const Context *context, ProgramPipeline *pipeline);
+
+ protected:
+ ~ProgramPipelineManager() override;
+};
+
+class MemoryObjectManager : public ResourceManagerBase
+{
+ public:
+ MemoryObjectManager();
+
+ MemoryObjectID createMemoryObject(rx::GLImplFactory *factory);
+ void deleteMemoryObject(const Context *context, MemoryObjectID handle);
+ MemoryObject *getMemoryObject(MemoryObjectID handle) const;
+
+ protected:
+ ~MemoryObjectManager() override;
+
+ private:
+ void reset(const Context *context) override;
+
+ ResourceMap<MemoryObject, MemoryObjectID> mMemoryObjects;
+};
+
+class SemaphoreManager : public ResourceManagerBase
+{
+ public:
+ SemaphoreManager();
+
+ SemaphoreID createSemaphore(rx::GLImplFactory *factory);
+ void deleteSemaphore(const Context *context, SemaphoreID handle);
+ Semaphore *getSemaphore(SemaphoreID handle) const;
+
+ protected:
+ ~SemaphoreManager() override;
+
+ private:
+ void reset(const Context *context) override;
+
+ ResourceMap<Semaphore, SemaphoreID> mSemaphores;
+};
+} // namespace gl
+
+#endif // LIBANGLE_RESOURCEMANAGER_H_
diff --git a/gfx/angle/checkout/src/libANGLE/ResourceMap.h b/gfx/angle/checkout/src/libANGLE/ResourceMap.h
new file mode 100644
index 0000000000..b24c1e6240
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/ResourceMap.h
@@ -0,0 +1,346 @@
+//
+// Copyright 2017 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.
+//
+// ResourceMap:
+// An optimized resource map which packs the first set of allocated objects into a
+// flat array, and then falls back to an unordered map for the higher handle values.
+//
+
+#ifndef LIBANGLE_RESOURCE_MAP_H_
+#define LIBANGLE_RESOURCE_MAP_H_
+
+#include "libANGLE/angletypes.h"
+
+namespace gl
+{
+
+template <typename ResourceType, typename IDType>
+class ResourceMap final : angle::NonCopyable
+{
+ public:
+ ResourceMap();
+ ~ResourceMap();
+
+ ANGLE_INLINE ResourceType *query(IDType id) const
+ {
+ GLuint handle = GetIDValue(id);
+ if (handle < mFlatResourcesSize)
+ {
+ ResourceType *value = mFlatResources[handle];
+ return (value == InvalidPointer() ? nullptr : value);
+ }
+ auto it = mHashedResources.find(handle);
+ return (it == mHashedResources.end() ? nullptr : it->second);
+ }
+
+ // Returns true if the handle was reserved. Not necessarily if the resource is created.
+ bool contains(IDType id) const;
+
+ // Returns the element that was at this location.
+ bool erase(IDType id, ResourceType **resourceOut);
+
+ void assign(IDType id, ResourceType *resource);
+
+ // Clears the map.
+ void clear();
+
+ using IndexAndResource = std::pair<GLuint, ResourceType *>;
+ using HashMap = angle::HashMap<GLuint, ResourceType *>;
+
+ class Iterator final
+ {
+ public:
+ bool operator==(const Iterator &other) const;
+ bool operator!=(const Iterator &other) const;
+ Iterator &operator++();
+ const IndexAndResource *operator->() const;
+ const IndexAndResource &operator*() const;
+
+ private:
+ friend class ResourceMap;
+ Iterator(const ResourceMap &origin,
+ GLuint flatIndex,
+ typename HashMap::const_iterator hashIndex,
+ bool skipNulls);
+ void updateValue();
+
+ const ResourceMap &mOrigin;
+ GLuint mFlatIndex;
+ typename HashMap::const_iterator mHashIndex;
+ IndexAndResource mValue;
+ bool mSkipNulls;
+ };
+
+ // null values represent reserved handles.
+ Iterator begin() const;
+ Iterator end() const;
+ Iterator find(IDType handle) const;
+
+ Iterator beginWithNull() const;
+ Iterator endWithNull() const;
+
+ // Not a constant-time operation, should only be used for verification.
+ bool empty() const;
+
+ private:
+ friend class Iterator;
+
+ GLuint nextResource(size_t flatIndex, bool skipNulls) const;
+
+ // constexpr methods cannot contain reinterpret_cast, so we need a static method.
+ static ResourceType *InvalidPointer();
+ static constexpr intptr_t kInvalidPointer = static_cast<intptr_t>(-1);
+
+ // Start with 32 maximum elements in the map, which can grow.
+ static constexpr size_t kInitialFlatResourcesSize = 0x20;
+
+ // Experimental testing suggests that 16k is a reasonable upper limit.
+ static constexpr size_t kFlatResourcesLimit = 0x4000;
+
+ // Size of one map element.
+ static constexpr size_t kElementSize = sizeof(ResourceType *);
+
+ size_t mFlatResourcesSize;
+ ResourceType **mFlatResources;
+
+ // A map of GL objects indexed by object ID.
+ HashMap mHashedResources;
+};
+
+template <typename ResourceType, typename IDType>
+ResourceMap<ResourceType, IDType>::ResourceMap()
+ : mFlatResourcesSize(kInitialFlatResourcesSize),
+ mFlatResources(new ResourceType *[kInitialFlatResourcesSize])
+{
+ memset(mFlatResources, kInvalidPointer, mFlatResourcesSize * kElementSize);
+}
+
+template <typename ResourceType, typename IDType>
+ResourceMap<ResourceType, IDType>::~ResourceMap()
+{
+ ASSERT(empty());
+ delete[] mFlatResources;
+}
+
+template <typename ResourceType, typename IDType>
+ANGLE_INLINE bool ResourceMap<ResourceType, IDType>::contains(IDType id) const
+{
+ GLuint handle = GetIDValue(id);
+ if (handle < mFlatResourcesSize)
+ {
+ return (mFlatResources[handle] != InvalidPointer());
+ }
+ return (mHashedResources.find(handle) != mHashedResources.end());
+}
+
+template <typename ResourceType, typename IDType>
+bool ResourceMap<ResourceType, IDType>::erase(IDType id, ResourceType **resourceOut)
+{
+ GLuint handle = GetIDValue(id);
+ if (handle < mFlatResourcesSize)
+ {
+ auto &value = mFlatResources[handle];
+ if (value == InvalidPointer())
+ {
+ return false;
+ }
+ *resourceOut = value;
+ value = InvalidPointer();
+ }
+ else
+ {
+ auto it = mHashedResources.find(handle);
+ if (it == mHashedResources.end())
+ {
+ return false;
+ }
+ *resourceOut = it->second;
+ mHashedResources.erase(it);
+ }
+ return true;
+}
+
+template <typename ResourceType, typename IDType>
+void ResourceMap<ResourceType, IDType>::assign(IDType id, ResourceType *resource)
+{
+ GLuint handle = GetIDValue(id);
+ if (handle < kFlatResourcesLimit)
+ {
+ if (handle >= mFlatResourcesSize)
+ {
+ // Use power-of-two.
+ size_t newSize = mFlatResourcesSize;
+ while (newSize <= handle)
+ {
+ newSize *= 2;
+ }
+
+ ResourceType **oldResources = mFlatResources;
+
+ mFlatResources = new ResourceType *[newSize];
+ memset(&mFlatResources[mFlatResourcesSize], kInvalidPointer,
+ (newSize - mFlatResourcesSize) * kElementSize);
+ memcpy(mFlatResources, oldResources, mFlatResourcesSize * kElementSize);
+ mFlatResourcesSize = newSize;
+ delete[] oldResources;
+ }
+ ASSERT(mFlatResourcesSize > handle);
+ mFlatResources[handle] = resource;
+ }
+ else
+ {
+ mHashedResources[handle] = resource;
+ }
+}
+
+template <typename ResourceType, typename IDType>
+typename ResourceMap<ResourceType, IDType>::Iterator ResourceMap<ResourceType, IDType>::begin()
+ const
+{
+ return Iterator(*this, nextResource(0, true), mHashedResources.begin(), true);
+}
+
+template <typename ResourceType, typename IDType>
+typename ResourceMap<ResourceType, IDType>::Iterator ResourceMap<ResourceType, IDType>::end() const
+{
+ return Iterator(*this, static_cast<GLuint>(mFlatResourcesSize), mHashedResources.end(), true);
+}
+
+template <typename ResourceType, typename IDType>
+typename ResourceMap<ResourceType, IDType>::Iterator
+ResourceMap<ResourceType, IDType>::beginWithNull() const
+{
+ return Iterator(*this, nextResource(0, false), mHashedResources.begin(), false);
+}
+
+template <typename ResourceType, typename IDType>
+typename ResourceMap<ResourceType, IDType>::Iterator
+ResourceMap<ResourceType, IDType>::endWithNull() const
+{
+ return Iterator(*this, static_cast<GLuint>(mFlatResourcesSize), mHashedResources.end(), false);
+}
+
+template <typename ResourceType, typename IDType>
+typename ResourceMap<ResourceType, IDType>::Iterator ResourceMap<ResourceType, IDType>::find(
+ IDType handle) const
+{
+ if (handle < mFlatResourcesSize)
+ {
+ return (mFlatResources[handle] != InvalidPointer()
+ ? Iterator(handle, mHashedResources.begin())
+ : end());
+ }
+ else
+ {
+ return mHashedResources.find(handle);
+ }
+}
+
+template <typename ResourceType, typename IDType>
+bool ResourceMap<ResourceType, IDType>::empty() const
+{
+ return (begin() == end());
+}
+
+template <typename ResourceType, typename IDType>
+void ResourceMap<ResourceType, IDType>::clear()
+{
+ memset(mFlatResources, kInvalidPointer, kInitialFlatResourcesSize * kElementSize);
+ mFlatResourcesSize = kInitialFlatResourcesSize;
+ mHashedResources.clear();
+}
+
+template <typename ResourceType, typename IDType>
+GLuint ResourceMap<ResourceType, IDType>::nextResource(size_t flatIndex, bool skipNulls) const
+{
+ for (size_t index = flatIndex; index < mFlatResourcesSize; index++)
+ {
+ if ((mFlatResources[index] != nullptr || !skipNulls) &&
+ mFlatResources[index] != InvalidPointer())
+ {
+ return static_cast<GLuint>(index);
+ }
+ }
+ return static_cast<GLuint>(mFlatResourcesSize);
+}
+
+template <typename ResourceType, typename IDType>
+// static
+ResourceType *ResourceMap<ResourceType, IDType>::InvalidPointer()
+{
+ return reinterpret_cast<ResourceType *>(kInvalidPointer);
+}
+
+template <typename ResourceType, typename IDType>
+ResourceMap<ResourceType, IDType>::Iterator::Iterator(
+ const ResourceMap &origin,
+ GLuint flatIndex,
+ typename ResourceMap<ResourceType, IDType>::HashMap::const_iterator hashIndex,
+ bool skipNulls)
+ : mOrigin(origin), mFlatIndex(flatIndex), mHashIndex(hashIndex), mSkipNulls(skipNulls)
+{
+ updateValue();
+}
+
+template <typename ResourceType, typename IDType>
+bool ResourceMap<ResourceType, IDType>::Iterator::operator==(const Iterator &other) const
+{
+ return (mFlatIndex == other.mFlatIndex && mHashIndex == other.mHashIndex);
+}
+
+template <typename ResourceType, typename IDType>
+bool ResourceMap<ResourceType, IDType>::Iterator::operator!=(const Iterator &other) const
+{
+ return !(*this == other);
+}
+
+template <typename ResourceType, typename IDType>
+typename ResourceMap<ResourceType, IDType>::Iterator &
+ResourceMap<ResourceType, IDType>::Iterator::operator++()
+{
+ if (mFlatIndex < static_cast<GLuint>(mOrigin.mFlatResourcesSize))
+ {
+ mFlatIndex = mOrigin.nextResource(mFlatIndex + 1, mSkipNulls);
+ }
+ else
+ {
+ mHashIndex++;
+ }
+ updateValue();
+ return *this;
+}
+
+template <typename ResourceType, typename IDType>
+const typename ResourceMap<ResourceType, IDType>::IndexAndResource *
+ResourceMap<ResourceType, IDType>::Iterator::operator->() const
+{
+ return &mValue;
+}
+
+template <typename ResourceType, typename IDType>
+const typename ResourceMap<ResourceType, IDType>::IndexAndResource &
+ResourceMap<ResourceType, IDType>::Iterator::operator*() const
+{
+ return mValue;
+}
+
+template <typename ResourceType, typename IDType>
+void ResourceMap<ResourceType, IDType>::Iterator::updateValue()
+{
+ if (mFlatIndex < static_cast<GLuint>(mOrigin.mFlatResourcesSize))
+ {
+ mValue.first = mFlatIndex;
+ mValue.second = mOrigin.mFlatResources[mFlatIndex];
+ }
+ else if (mHashIndex != mOrigin.mHashedResources.end())
+ {
+ mValue.first = mHashIndex->first;
+ mValue.second = mHashIndex->second;
+ }
+}
+
+} // namespace gl
+
+#endif // LIBANGLE_RESOURCE_MAP_H_
diff --git a/gfx/angle/checkout/src/libANGLE/Sampler.cpp b/gfx/angle/checkout/src/libANGLE/Sampler.cpp
new file mode 100644
index 0000000000..3cfdbbdf4f
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Sampler.cpp
@@ -0,0 +1,211 @@
+//
+// Copyright 2013 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.
+//
+
+// Sampler.cpp : Implements the Sampler class, which represents a GLES 3
+// sampler object. Sampler objects store some state needed to sample textures.
+
+#include "libANGLE/Sampler.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/renderer/GLImplFactory.h"
+#include "libANGLE/renderer/SamplerImpl.h"
+
+namespace gl
+{
+
+Sampler::Sampler(rx::GLImplFactory *factory, SamplerID id)
+ : RefCountObject(factory->generateSerial(), id),
+ mState(),
+ mDirty(true),
+ mSampler(factory->createSampler(mState)),
+ mLabel()
+{}
+
+Sampler::~Sampler()
+{
+ SafeDelete(mSampler);
+}
+
+void Sampler::onDestroy(const Context *context)
+{
+ if (mSampler)
+ {
+ mSampler->onDestroy(context);
+ }
+}
+
+angle::Result Sampler::setLabel(const Context *context, const std::string &label)
+{
+ mLabel = label;
+
+ if (mSampler)
+ {
+ return mSampler->onLabelUpdate(context);
+ }
+ return angle::Result::Continue;
+}
+
+const std::string &Sampler::getLabel() const
+{
+ return mLabel;
+}
+
+void Sampler::setMinFilter(const Context *context, GLenum minFilter)
+{
+ mState.setMinFilter(minFilter);
+ signalDirtyState();
+}
+
+GLenum Sampler::getMinFilter() const
+{
+ return mState.getMinFilter();
+}
+
+void Sampler::setMagFilter(const Context *context, GLenum magFilter)
+{
+ mState.setMagFilter(magFilter);
+ signalDirtyState();
+}
+
+GLenum Sampler::getMagFilter() const
+{
+ return mState.getMagFilter();
+}
+
+void Sampler::setWrapS(const Context *context, GLenum wrapS)
+{
+ mState.setWrapS(wrapS);
+ signalDirtyState();
+}
+
+GLenum Sampler::getWrapS() const
+{
+ return mState.getWrapS();
+}
+
+void Sampler::setWrapT(const Context *context, GLenum wrapT)
+{
+ mState.setWrapT(wrapT);
+ signalDirtyState();
+}
+
+GLenum Sampler::getWrapT() const
+{
+ return mState.getWrapT();
+}
+
+void Sampler::setWrapR(const Context *context, GLenum wrapR)
+{
+ mState.setWrapR(wrapR);
+ signalDirtyState();
+}
+
+GLenum Sampler::getWrapR() const
+{
+ return mState.getWrapR();
+}
+
+void Sampler::setMaxAnisotropy(const Context *context, float maxAnisotropy)
+{
+ mState.setMaxAnisotropy(maxAnisotropy);
+ signalDirtyState();
+}
+
+float Sampler::getMaxAnisotropy() const
+{
+ return mState.getMaxAnisotropy();
+}
+
+void Sampler::setMinLod(const Context *context, GLfloat minLod)
+{
+ mState.setMinLod(minLod);
+ signalDirtyState();
+}
+
+GLfloat Sampler::getMinLod() const
+{
+ return mState.getMinLod();
+}
+
+void Sampler::setMaxLod(const Context *context, GLfloat maxLod)
+{
+ mState.setMaxLod(maxLod);
+ signalDirtyState();
+}
+
+GLfloat Sampler::getMaxLod() const
+{
+ return mState.getMaxLod();
+}
+
+void Sampler::setCompareMode(const Context *context, GLenum compareMode)
+{
+ mState.setCompareMode(compareMode);
+ signalDirtyState();
+}
+
+GLenum Sampler::getCompareMode() const
+{
+ return mState.getCompareMode();
+}
+
+void Sampler::setCompareFunc(const Context *context, GLenum compareFunc)
+{
+ mState.setCompareFunc(compareFunc);
+ signalDirtyState();
+}
+
+GLenum Sampler::getCompareFunc() const
+{
+ return mState.getCompareFunc();
+}
+
+void Sampler::setSRGBDecode(const Context *context, GLenum sRGBDecode)
+{
+ mState.setSRGBDecode(sRGBDecode);
+ signalDirtyState();
+}
+
+GLenum Sampler::getSRGBDecode() const
+{
+ return mState.getSRGBDecode();
+}
+
+void Sampler::setBorderColor(const Context *context, const ColorGeneric &color)
+{
+ mState.setBorderColor(color);
+ signalDirtyState();
+}
+
+const ColorGeneric &Sampler::getBorderColor() const
+{
+ return mState.getBorderColor();
+}
+
+const SamplerState &Sampler::getSamplerState() const
+{
+ return mState;
+}
+
+rx::SamplerImpl *Sampler::getImplementation() const
+{
+ return mSampler;
+}
+
+angle::Result Sampler::syncState(const Context *context)
+{
+ ASSERT(isDirty());
+ angle::Result result = mSampler->syncState(context, mDirty);
+ mDirty = result != angle::Result::Continue;
+ return result;
+}
+
+void Sampler::signalDirtyState()
+{
+ mDirty = true;
+ onStateChange(angle::SubjectMessage::DirtyBitsFlagged);
+}
+
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/Sampler.h b/gfx/angle/checkout/src/libANGLE/Sampler.h
new file mode 100644
index 0000000000..b483593780
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Sampler.h
@@ -0,0 +1,92 @@
+//
+// Copyright 2013 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.
+//
+
+// Sampler.h : Defines the Sampler class, which represents a GLES 3
+// sampler object. Sampler objects store some state needed to sample textures.
+
+#ifndef LIBANGLE_SAMPLER_H_
+#define LIBANGLE_SAMPLER_H_
+
+#include "libANGLE/Debug.h"
+#include "libANGLE/Observer.h"
+#include "libANGLE/RefCountObject.h"
+#include "libANGLE/angletypes.h"
+
+namespace rx
+{
+class GLImplFactory;
+class SamplerImpl;
+} // namespace rx
+
+namespace gl
+{
+
+class Sampler final : public RefCountObject<SamplerID>, public LabeledObject, public angle::Subject
+{
+ public:
+ Sampler(rx::GLImplFactory *factory, SamplerID id);
+ ~Sampler() override;
+
+ void onDestroy(const Context *context) override;
+
+ angle::Result setLabel(const Context *context, const std::string &label) override;
+ const std::string &getLabel() const override;
+
+ void setMinFilter(const Context *context, GLenum minFilter);
+ GLenum getMinFilter() const;
+
+ void setMagFilter(const Context *context, GLenum magFilter);
+ GLenum getMagFilter() const;
+
+ void setWrapS(const Context *context, GLenum wrapS);
+ GLenum getWrapS() const;
+
+ void setWrapT(const Context *context, GLenum wrapT);
+ GLenum getWrapT() const;
+
+ void setWrapR(const Context *context, GLenum wrapR);
+ GLenum getWrapR() const;
+
+ void setMaxAnisotropy(const Context *context, float maxAnisotropy);
+ float getMaxAnisotropy() const;
+
+ void setMinLod(const Context *context, GLfloat minLod);
+ GLfloat getMinLod() const;
+
+ void setMaxLod(const Context *context, GLfloat maxLod);
+ GLfloat getMaxLod() const;
+
+ void setCompareMode(const Context *context, GLenum compareMode);
+ GLenum getCompareMode() const;
+
+ void setCompareFunc(const Context *context, GLenum compareFunc);
+ GLenum getCompareFunc() const;
+
+ void setSRGBDecode(const Context *context, GLenum sRGBDecode);
+ GLenum getSRGBDecode() const;
+
+ void setBorderColor(const Context *context, const ColorGeneric &color);
+ const ColorGeneric &getBorderColor() const;
+
+ const SamplerState &getSamplerState() const;
+
+ rx::SamplerImpl *getImplementation() const;
+
+ angle::Result syncState(const Context *context);
+ bool isDirty() const { return mDirty; }
+
+ private:
+ void signalDirtyState();
+ SamplerState mState;
+ bool mDirty;
+ rx::SamplerImpl *mSampler;
+
+ std::string mLabel;
+};
+
+} // namespace gl
+
+#endif // LIBANGLE_SAMPLER_H_
diff --git a/gfx/angle/checkout/src/libANGLE/Semaphore.cpp b/gfx/angle/checkout/src/libANGLE/Semaphore.cpp
new file mode 100644
index 0000000000..45621653e3
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Semaphore.cpp
@@ -0,0 +1,52 @@
+//
+// Copyright 2019 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.
+//
+// Semaphore.h: Implements the gl::Semaphore class [EXT_external_objects]
+
+#include "libANGLE/Semaphore.h"
+
+#include "common/angleutils.h"
+#include "libANGLE/renderer/GLImplFactory.h"
+#include "libANGLE/renderer/SemaphoreImpl.h"
+
+namespace gl
+{
+
+Semaphore::Semaphore(rx::GLImplFactory *factory, SemaphoreID id)
+ : RefCountObject(factory->generateSerial(), id), mImplementation(factory->createSemaphore())
+{}
+
+Semaphore::~Semaphore() {}
+
+void Semaphore::onDestroy(const Context *context)
+{
+ mImplementation->onDestroy(context);
+}
+
+angle::Result Semaphore::importFd(Context *context, HandleType handleType, GLint fd)
+{
+ return mImplementation->importFd(context, handleType, fd);
+}
+
+angle::Result Semaphore::importZirconHandle(Context *context, HandleType handleType, GLuint handle)
+{
+ return mImplementation->importZirconHandle(context, handleType, handle);
+}
+
+angle::Result Semaphore::wait(Context *context,
+ const BufferBarrierVector &bufferBarriers,
+ const TextureBarrierVector &textureBarriers)
+{
+ return mImplementation->wait(context, bufferBarriers, textureBarriers);
+}
+
+angle::Result Semaphore::signal(Context *context,
+ const BufferBarrierVector &bufferBarriers,
+ const TextureBarrierVector &textureBarriers)
+{
+ return mImplementation->signal(context, bufferBarriers, textureBarriers);
+}
+
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/Semaphore.h b/gfx/angle/checkout/src/libANGLE/Semaphore.h
new file mode 100644
index 0000000000..02bdabedca
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Semaphore.h
@@ -0,0 +1,57 @@
+//
+// Copyright 2019 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.
+//
+// Semaphore.h: Defines the gl::Semaphore class [EXT_external_objects]
+
+#ifndef LIBANGLE_SEMAPHORE_H_
+#define LIBANGLE_SEMAPHORE_H_
+
+#include <memory>
+
+#include "angle_gl.h"
+#include "common/PackedEnums.h"
+#include "common/angleutils.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/RefCountObject.h"
+#include "libANGLE/angletypes.h"
+
+namespace rx
+{
+class GLImplFactory;
+class SemaphoreImpl;
+} // namespace rx
+
+namespace gl
+{
+class Context;
+
+class Semaphore final : public RefCountObject<SemaphoreID>
+{
+ public:
+ Semaphore(rx::GLImplFactory *factory, SemaphoreID id);
+ ~Semaphore() override;
+
+ void onDestroy(const Context *context) override;
+
+ rx::SemaphoreImpl *getImplementation() const { return mImplementation.get(); }
+
+ angle::Result importFd(Context *context, HandleType handleType, GLint fd);
+ angle::Result importZirconHandle(Context *context, HandleType handleType, GLuint handle);
+
+ angle::Result wait(Context *context,
+ const BufferBarrierVector &bufferBarriers,
+ const TextureBarrierVector &textureBarriers);
+
+ angle::Result signal(Context *context,
+ const BufferBarrierVector &bufferBarriers,
+ const TextureBarrierVector &textureBarriers);
+
+ private:
+ std::unique_ptr<rx::SemaphoreImpl> mImplementation;
+};
+
+} // namespace gl
+
+#endif // LIBANGLE_SEMAPHORE_H_
diff --git a/gfx/angle/checkout/src/libANGLE/Shader.cpp b/gfx/angle/checkout/src/libANGLE/Shader.cpp
new file mode 100644
index 0000000000..b1a718131a
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Shader.cpp
@@ -0,0 +1,1331 @@
+//
+// Copyright 2002 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.
+//
+
+// Shader.cpp: Implements the gl::Shader class and its derived classes
+// VertexShader and FragmentShader. Implements GL shader objects and related
+// functionality. [OpenGL ES 2.0.24] section 2.10 page 24 and section 3.8 page 84.
+
+#include "libANGLE/Shader.h"
+
+#include <functional>
+#include <sstream>
+
+#include "GLSLANG/ShaderLang.h"
+#include "common/utilities.h"
+#include "libANGLE/Caps.h"
+#include "libANGLE/Compiler.h"
+#include "libANGLE/Constants.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Display.h"
+#include "libANGLE/MemoryShaderCache.h"
+#include "libANGLE/Program.h"
+#include "libANGLE/ResourceManager.h"
+#include "libANGLE/renderer/GLImplFactory.h"
+#include "libANGLE/renderer/ShaderImpl.h"
+#include "platform/FrontendFeatures_autogen.h"
+
+namespace gl
+{
+
+namespace
+{
+constexpr uint32_t kShaderCacheIdentifier = 0x12345678;
+
+template <typename VarT>
+std::vector<VarT> GetActiveShaderVariables(const std::vector<VarT> *variableList)
+{
+ ASSERT(variableList);
+ std::vector<VarT> result;
+ for (size_t varIndex = 0; varIndex < variableList->size(); varIndex++)
+ {
+ const VarT &var = variableList->at(varIndex);
+ if (var.active)
+ {
+ result.push_back(var);
+ }
+ }
+ return result;
+}
+
+template <typename VarT>
+const std::vector<VarT> &GetShaderVariables(const std::vector<VarT> *variableList)
+{
+ ASSERT(variableList);
+ return *variableList;
+}
+
+void WriteInterfaceBlock(gl::BinaryOutputStream *stream, const sh::InterfaceBlock &block)
+{
+ stream->writeString(block.name);
+ stream->writeString(block.mappedName);
+ stream->writeString(block.instanceName);
+ stream->writeInt(block.arraySize);
+ stream->writeEnum(block.layout);
+ stream->writeBool(block.isRowMajorLayout);
+ stream->writeInt(block.binding);
+ stream->writeBool(block.staticUse);
+ stream->writeBool(block.active);
+ stream->writeEnum(block.blockType);
+
+ stream->writeInt(block.fields.size());
+ for (const sh::ShaderVariable &shaderVariable : block.fields)
+ {
+ WriteShaderVar(stream, shaderVariable);
+ }
+}
+
+void LoadInterfaceBlock(gl::BinaryInputStream *stream, sh::InterfaceBlock &block)
+{
+ stream->readString(&block.name);
+ stream->readString(&block.mappedName);
+ stream->readString(&block.instanceName);
+ stream->readInt(&block.arraySize);
+ stream->readEnum(&block.layout);
+ stream->readBool(&block.isRowMajorLayout);
+ stream->readInt(&block.binding);
+ stream->readBool(&block.staticUse);
+ stream->readBool(&block.active);
+ stream->readEnum(&block.blockType);
+
+ size_t size = stream->readInt<size_t>();
+ block.fields.resize(size);
+ for (sh::ShaderVariable &shaderVariable : block.fields)
+ {
+ LoadShaderVar(stream, &shaderVariable);
+ }
+}
+} // anonymous namespace
+
+// true if varying x has a higher priority in packing than y
+bool CompareShaderVar(const sh::ShaderVariable &x, const sh::ShaderVariable &y)
+{
+ if (x.type == y.type)
+ {
+ return x.getArraySizeProduct() > y.getArraySizeProduct();
+ }
+
+ // Special case for handling structs: we sort these to the end of the list
+ if (x.type == GL_NONE)
+ {
+ return false;
+ }
+
+ if (y.type == GL_NONE)
+ {
+ return true;
+ }
+
+ return gl::VariableSortOrder(x.type) < gl::VariableSortOrder(y.type);
+}
+
+const char *GetShaderTypeString(ShaderType type)
+{
+ switch (type)
+ {
+ case ShaderType::Vertex:
+ return "VERTEX";
+
+ case ShaderType::Fragment:
+ return "FRAGMENT";
+
+ case ShaderType::Compute:
+ return "COMPUTE";
+
+ case ShaderType::Geometry:
+ return "GEOMETRY";
+
+ case ShaderType::TessControl:
+ return "TESS_CONTROL";
+
+ case ShaderType::TessEvaluation:
+ return "TESS_EVALUATION";
+
+ default:
+ UNREACHABLE();
+ return "";
+ }
+}
+
+class [[nodiscard]] ScopedExit final : angle::NonCopyable
+{
+ public:
+ ScopedExit(std::function<void()> exit) : mExit(exit) {}
+ ~ScopedExit() { mExit(); }
+
+ private:
+ std::function<void()> mExit;
+};
+
+struct Shader::CompilingState
+{
+ std::shared_ptr<rx::WaitableCompileEvent> compileEvent;
+ ShCompilerInstance shCompilerInstance;
+ egl::BlobCache::Key shaderHash;
+};
+
+ShaderState::ShaderState(ShaderType shaderType)
+ : mLabel(),
+ mShaderType(shaderType),
+ mShaderVersion(100),
+ mNumViews(-1),
+ mGeometryShaderInvocations(1),
+ mCompileStatus(CompileStatus::NOT_COMPILED)
+{
+ mLocalSize.fill(-1);
+}
+
+ShaderState::~ShaderState() {}
+
+Shader::Shader(ShaderProgramManager *manager,
+ rx::GLImplFactory *implFactory,
+ const gl::Limitations &rendererLimitations,
+ ShaderType type,
+ ShaderProgramID handle)
+ : mState(type),
+ mImplementation(implFactory->createShader(mState)),
+ mRendererLimitations(rendererLimitations),
+ mHandle(handle),
+ mType(type),
+ mRefCount(0),
+ mDeleteStatus(false),
+ mResourceManager(manager),
+ mCurrentMaxComputeWorkGroupInvocations(0u)
+{
+ ASSERT(mImplementation);
+}
+
+void Shader::onDestroy(const gl::Context *context)
+{
+ resolveCompile(context);
+ mImplementation->destroy();
+ mBoundCompiler.set(context, nullptr);
+ mImplementation.reset(nullptr);
+ delete this;
+}
+
+Shader::~Shader()
+{
+ ASSERT(!mImplementation);
+}
+
+angle::Result Shader::setLabel(const Context *context, const std::string &label)
+{
+ mState.mLabel = label;
+
+ if (mImplementation)
+ {
+ return mImplementation->onLabelUpdate(context);
+ }
+ return angle::Result::Continue;
+}
+
+const std::string &Shader::getLabel() const
+{
+ return mState.mLabel;
+}
+
+ShaderProgramID Shader::getHandle() const
+{
+ return mHandle;
+}
+
+void Shader::setSource(GLsizei count, const char *const *string, const GLint *length)
+{
+ std::ostringstream stream;
+
+ for (int i = 0; i < count; i++)
+ {
+ if (length == nullptr || length[i] < 0)
+ {
+ stream.write(string[i], strlen(string[i]));
+ }
+ else
+ {
+ stream.write(string[i], length[i]);
+ }
+ }
+
+ mState.mSource = stream.str();
+}
+
+int Shader::getInfoLogLength(const Context *context)
+{
+ resolveCompile(context);
+ if (mInfoLog.empty())
+ {
+ return 0;
+ }
+
+ return (static_cast<int>(mInfoLog.length()) + 1);
+}
+
+void Shader::getInfoLog(const Context *context, GLsizei bufSize, GLsizei *length, char *infoLog)
+{
+ resolveCompile(context);
+
+ int index = 0;
+
+ if (bufSize > 0)
+ {
+ index = std::min(bufSize - 1, static_cast<GLsizei>(mInfoLog.length()));
+ memcpy(infoLog, mInfoLog.c_str(), index);
+
+ infoLog[index] = '\0';
+ }
+
+ if (length)
+ {
+ *length = index;
+ }
+}
+
+int Shader::getSourceLength() const
+{
+ return mState.mSource.empty() ? 0 : (static_cast<int>(mState.mSource.length()) + 1);
+}
+
+int Shader::getTranslatedSourceLength(const Context *context)
+{
+ resolveCompile(context);
+
+ if (mState.mTranslatedSource.empty())
+ {
+ return 0;
+ }
+
+ return (static_cast<int>(mState.mTranslatedSource.length()) + 1);
+}
+
+int Shader::getTranslatedSourceWithDebugInfoLength(const Context *context)
+{
+ resolveCompile(context);
+
+ const std::string &debugInfo = mImplementation->getDebugInfo();
+ if (debugInfo.empty())
+ {
+ return 0;
+ }
+
+ return (static_cast<int>(debugInfo.length()) + 1);
+}
+
+// static
+void Shader::GetSourceImpl(const std::string &source,
+ GLsizei bufSize,
+ GLsizei *length,
+ char *buffer)
+{
+ int index = 0;
+
+ if (bufSize > 0)
+ {
+ index = std::min(bufSize - 1, static_cast<GLsizei>(source.length()));
+ memcpy(buffer, source.c_str(), index);
+
+ buffer[index] = '\0';
+ }
+
+ if (length)
+ {
+ *length = index;
+ }
+}
+
+void Shader::getSource(GLsizei bufSize, GLsizei *length, char *buffer) const
+{
+ GetSourceImpl(mState.mSource, bufSize, length, buffer);
+}
+
+void Shader::getTranslatedSource(const Context *context,
+ GLsizei bufSize,
+ GLsizei *length,
+ char *buffer)
+{
+ GetSourceImpl(getTranslatedSource(context), bufSize, length, buffer);
+}
+
+const std::string &Shader::getTranslatedSource(const Context *context)
+{
+ resolveCompile(context);
+ return mState.mTranslatedSource;
+}
+
+const sh::BinaryBlob &Shader::getCompiledBinary(const Context *context)
+{
+ resolveCompile(context);
+ return mState.mCompiledBinary;
+}
+
+void Shader::getTranslatedSourceWithDebugInfo(const Context *context,
+ GLsizei bufSize,
+ GLsizei *length,
+ char *buffer)
+{
+ resolveCompile(context);
+ const std::string &debugInfo = mImplementation->getDebugInfo();
+ GetSourceImpl(debugInfo, bufSize, length, buffer);
+}
+
+void Shader::compile(const Context *context)
+{
+ resolveCompile(context);
+
+ mState.mTranslatedSource.clear();
+ mState.mCompiledBinary.clear();
+ mInfoLog.clear();
+ mState.mShaderVersion = 100;
+ mState.mInputVaryings.clear();
+ mState.mOutputVaryings.clear();
+ mState.mUniforms.clear();
+ mState.mUniformBlocks.clear();
+ mState.mShaderStorageBlocks.clear();
+ mState.mActiveAttributes.clear();
+ mState.mActiveOutputVariables.clear();
+ mState.mNumViews = -1;
+ mState.mGeometryShaderInputPrimitiveType.reset();
+ mState.mGeometryShaderOutputPrimitiveType.reset();
+ mState.mGeometryShaderMaxVertices.reset();
+ mState.mGeometryShaderInvocations = 1;
+ mState.mTessControlShaderVertices = 0;
+ mState.mTessGenMode = 0;
+ mState.mTessGenSpacing = 0;
+ mState.mTessGenVertexOrder = 0;
+ mState.mTessGenPointMode = 0;
+ mState.mAdvancedBlendEquations.reset();
+ mState.mHasDiscard = false;
+ mState.mEnablesPerSampleShading = false;
+ mState.mSpecConstUsageBits.reset();
+
+ mCurrentMaxComputeWorkGroupInvocations =
+ static_cast<GLuint>(context->getCaps().maxComputeWorkGroupInvocations);
+ mMaxComputeSharedMemory = context->getCaps().maxComputeSharedMemorySize;
+
+ ShCompileOptions options = {};
+ options.objectCode = true;
+ options.variables = true;
+ options.emulateGLDrawID = true;
+
+ // Add default options to WebGL shaders to prevent unexpected behavior during
+ // compilation.
+ if (context->isWebGL())
+ {
+ options.initGLPosition = true;
+ options.limitCallStackDepth = true;
+ options.limitExpressionComplexity = true;
+ options.enforcePackingRestrictions = true;
+ options.initSharedVariables = true;
+ }
+ else
+ {
+ // Per https://github.com/KhronosGroup/WebGL/pull/3278 gl_BaseVertex/gl_BaseInstance are
+ // removed from WebGL
+ options.emulateGLBaseVertexBaseInstance = true;
+ }
+
+ // Some targets (e.g. 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 instruct the compiler to pre-validate.
+ if (mRendererLimitations.shadersRequireIndexedLoopValidation)
+ {
+ options.validateLoopIndexing = true;
+ }
+
+ if (context->getFrontendFeatures().scalarizeVecAndMatConstructorArgs.enabled)
+ {
+ options.scalarizeVecAndMatConstructorArgs = true;
+ }
+
+ if (context->getFrontendFeatures().forceInitShaderVariables.enabled)
+ {
+ options.initOutputVariables = true;
+ options.initializeUninitializedLocals = true;
+ }
+
+ mBoundCompiler.set(context, context->getCompiler());
+
+ ASSERT(mBoundCompiler.get());
+ ShCompilerInstance compilerInstance = mBoundCompiler->getInstance(mState.mShaderType);
+ ShHandle compilerHandle = compilerInstance.getHandle();
+ ASSERT(compilerHandle);
+ mCompilerResourcesString = compilerInstance.getBuiltinResourcesString();
+
+ // Find a shader in Blob Cache
+ egl::BlobCache::Key shaderHash = {0};
+ MemoryShaderCache *shaderCache = context->getMemoryShaderCache();
+ if (shaderCache)
+ {
+ angle::Result cacheResult =
+ shaderCache->getShader(context, this, options, compilerInstance, &shaderHash);
+
+ if (cacheResult == angle::Result::Continue)
+ {
+ compilerInstance.destroy();
+ return;
+ }
+ }
+
+ // Cache load failed, fall through normal compiling.
+ mState.mCompileStatus = CompileStatus::COMPILE_REQUESTED;
+ mCompilingState.reset(new CompilingState());
+ mCompilingState->shCompilerInstance = std::move(compilerInstance);
+ mCompilingState->shaderHash = shaderHash;
+ mCompilingState->compileEvent =
+ mImplementation->compile(context, &(mCompilingState->shCompilerInstance), &options);
+}
+
+void Shader::resolveCompile(const Context *context)
+{
+ if (!mState.compilePending())
+ {
+ return;
+ }
+
+ ASSERT(mCompilingState.get());
+
+ mCompilingState->compileEvent->wait();
+
+ mInfoLog += mCompilingState->compileEvent->getInfoLog();
+
+ ScopedExit exit([this]() {
+ mBoundCompiler->putInstance(std::move(mCompilingState->shCompilerInstance));
+ mCompilingState->compileEvent.reset();
+ mCompilingState.reset();
+ });
+
+ ShHandle compilerHandle = mCompilingState->shCompilerInstance.getHandle();
+ if (!mCompilingState->compileEvent->getResult())
+ {
+ mInfoLog += sh::GetInfoLog(compilerHandle);
+ INFO() << std::endl << mInfoLog;
+ mState.mCompileStatus = CompileStatus::NOT_COMPILED;
+ return;
+ }
+
+ const ShShaderOutput outputType = mCompilingState->shCompilerInstance.getShaderOutputType();
+ const bool isBinaryOutput =
+ outputType == SH_SPIRV_VULKAN_OUTPUT || outputType == SH_SPIRV_METAL_OUTPUT;
+
+ if (isBinaryOutput)
+ {
+ mState.mCompiledBinary = sh::GetObjectBinaryBlob(compilerHandle);
+ }
+ else
+ {
+ mState.mTranslatedSource = sh::GetObjectCode(compilerHandle);
+
+#if !defined(NDEBUG)
+ // Prefix translated shader with commented out un-translated shader.
+ // Useful in diagnostics tools which capture the shader source.
+ std::ostringstream shaderStream;
+ shaderStream << "// GLSL\n";
+ shaderStream << "//\n";
+
+ std::istringstream inputSourceStream(mState.mSource);
+ std::string line;
+ while (std::getline(inputSourceStream, line))
+ {
+ // Remove null characters from the source line
+ line.erase(std::remove(line.begin(), line.end(), '\0'), line.end());
+
+ shaderStream << "// " << line;
+
+ // glslang complains if a comment ends with backslash
+ if (!line.empty() && line.back() == '\\')
+ {
+ shaderStream << "\\";
+ }
+
+ shaderStream << std::endl;
+ }
+ shaderStream << "\n\n";
+ shaderStream << mState.mTranslatedSource;
+ mState.mTranslatedSource = shaderStream.str();
+#endif // !defined(NDEBUG)
+ }
+
+ // Gather the shader information
+ mState.mShaderVersion = sh::GetShaderVersion(compilerHandle);
+
+ mState.mUniforms = GetShaderVariables(sh::GetUniforms(compilerHandle));
+ mState.mUniformBlocks = GetShaderVariables(sh::GetUniformBlocks(compilerHandle));
+ mState.mShaderStorageBlocks = GetShaderVariables(sh::GetShaderStorageBlocks(compilerHandle));
+ mState.mSpecConstUsageBits =
+ rx::SpecConstUsageBits(sh::GetShaderSpecConstUsageBits(compilerHandle));
+
+ switch (mState.mShaderType)
+ {
+ case ShaderType::Compute:
+ {
+ mState.mAllAttributes = GetShaderVariables(sh::GetAttributes(compilerHandle));
+ mState.mActiveAttributes = GetActiveShaderVariables(&mState.mAllAttributes);
+ mState.mLocalSize = sh::GetComputeShaderLocalGroupSize(compilerHandle);
+ if (mState.mLocalSize.isDeclared())
+ {
+ angle::CheckedNumeric<uint32_t> checked_local_size_product(mState.mLocalSize[0]);
+ checked_local_size_product *= mState.mLocalSize[1];
+ checked_local_size_product *= mState.mLocalSize[2];
+
+ if (!checked_local_size_product.IsValid())
+ {
+ WARN() << std::endl
+ << "Integer overflow when computing the product of local_size_x, "
+ << "local_size_y and local_size_z.";
+ mState.mCompileStatus = CompileStatus::NOT_COMPILED;
+ return;
+ }
+ if (checked_local_size_product.ValueOrDie() >
+ mCurrentMaxComputeWorkGroupInvocations)
+ {
+ WARN() << std::endl
+ << "The total number of invocations within a work group exceeds "
+ << "MAX_COMPUTE_WORK_GROUP_INVOCATIONS.";
+ mState.mCompileStatus = CompileStatus::NOT_COMPILED;
+ return;
+ }
+ }
+
+ unsigned int sharedMemSize = sh::GetShaderSharedMemorySize(compilerHandle);
+ if (sharedMemSize > mMaxComputeSharedMemory)
+ {
+ WARN() << std::endl << "Exceeded maximum shared memory size";
+ mState.mCompileStatus = CompileStatus::NOT_COMPILED;
+ return;
+ }
+ break;
+ }
+ case ShaderType::Vertex:
+ {
+ mState.mOutputVaryings = GetShaderVariables(sh::GetOutputVaryings(compilerHandle));
+ mState.mAllAttributes = GetShaderVariables(sh::GetAttributes(compilerHandle));
+ mState.mActiveAttributes = GetActiveShaderVariables(&mState.mAllAttributes);
+ mState.mNumViews = sh::GetVertexShaderNumViews(compilerHandle);
+ break;
+ }
+ case ShaderType::Fragment:
+ {
+ mState.mAllAttributes = GetShaderVariables(sh::GetAttributes(compilerHandle));
+ mState.mActiveAttributes = GetActiveShaderVariables(&mState.mAllAttributes);
+ mState.mInputVaryings = GetShaderVariables(sh::GetInputVaryings(compilerHandle));
+ // TODO(jmadill): Figure out why we only sort in the FS, and if we need to.
+ std::sort(mState.mInputVaryings.begin(), mState.mInputVaryings.end(), CompareShaderVar);
+ mState.mActiveOutputVariables =
+ GetActiveShaderVariables(sh::GetOutputVariables(compilerHandle));
+ mState.mHasDiscard = sh::HasDiscardInFragmentShader(compilerHandle);
+ mState.mEnablesPerSampleShading = sh::EnablesPerSampleShading(compilerHandle);
+ mState.mAdvancedBlendEquations =
+ BlendEquationBitSet(sh::GetAdvancedBlendEquations(compilerHandle));
+ break;
+ }
+ case ShaderType::Geometry:
+ {
+ mState.mInputVaryings = GetShaderVariables(sh::GetInputVaryings(compilerHandle));
+ mState.mOutputVaryings = GetShaderVariables(sh::GetOutputVaryings(compilerHandle));
+
+ if (sh::HasValidGeometryShaderInputPrimitiveType(compilerHandle))
+ {
+ mState.mGeometryShaderInputPrimitiveType = FromGLenum<PrimitiveMode>(
+ sh::GetGeometryShaderInputPrimitiveType(compilerHandle));
+ }
+ if (sh::HasValidGeometryShaderOutputPrimitiveType(compilerHandle))
+ {
+ mState.mGeometryShaderOutputPrimitiveType = FromGLenum<PrimitiveMode>(
+ sh::GetGeometryShaderOutputPrimitiveType(compilerHandle));
+ }
+ if (sh::HasValidGeometryShaderMaxVertices(compilerHandle))
+ {
+ mState.mGeometryShaderMaxVertices =
+ sh::GetGeometryShaderMaxVertices(compilerHandle);
+ }
+ mState.mGeometryShaderInvocations = sh::GetGeometryShaderInvocations(compilerHandle);
+ break;
+ }
+ case ShaderType::TessControl:
+ {
+ mState.mInputVaryings = GetShaderVariables(sh::GetInputVaryings(compilerHandle));
+ mState.mOutputVaryings = GetShaderVariables(sh::GetOutputVaryings(compilerHandle));
+ mState.mTessControlShaderVertices = sh::GetTessControlShaderVertices(compilerHandle);
+ break;
+ }
+ case ShaderType::TessEvaluation:
+ {
+ mState.mInputVaryings = GetShaderVariables(sh::GetInputVaryings(compilerHandle));
+ mState.mOutputVaryings = GetShaderVariables(sh::GetOutputVaryings(compilerHandle));
+ if (sh::HasValidTessGenMode(compilerHandle))
+ {
+ mState.mTessGenMode = sh::GetTessGenMode(compilerHandle);
+ }
+ if (sh::HasValidTessGenSpacing(compilerHandle))
+ {
+ mState.mTessGenSpacing = sh::GetTessGenSpacing(compilerHandle);
+ }
+ if (sh::HasValidTessGenVertexOrder(compilerHandle))
+ {
+ mState.mTessGenVertexOrder = sh::GetTessGenVertexOrder(compilerHandle);
+ }
+ if (sh::HasValidTessGenPointMode(compilerHandle))
+ {
+ mState.mTessGenPointMode = sh::GetTessGenPointMode(compilerHandle);
+ }
+ break;
+ }
+
+ default:
+ UNREACHABLE();
+ }
+
+ ASSERT(!mState.mTranslatedSource.empty() || !mState.mCompiledBinary.empty());
+
+ bool success = mCompilingState->compileEvent->postTranslate(&mInfoLog);
+ mState.mCompileStatus = success ? CompileStatus::COMPILED : CompileStatus::NOT_COMPILED;
+
+ MemoryShaderCache *shaderCache = context->getMemoryShaderCache();
+ if (success && shaderCache)
+ {
+ // Save to the shader cache.
+ if (shaderCache->putShader(context, mCompilingState->shaderHash, this) !=
+ angle::Result::Continue)
+ {
+ ANGLE_PERF_WARNING(context->getState().getDebug(), GL_DEBUG_SEVERITY_LOW,
+ "Failed to save compiled shader to memory shader cache.");
+ }
+ }
+}
+
+void Shader::addRef()
+{
+ mRefCount++;
+}
+
+void Shader::release(const Context *context)
+{
+ mRefCount--;
+
+ if (mRefCount == 0 && mDeleteStatus)
+ {
+ mResourceManager->deleteShader(context, mHandle);
+ }
+}
+
+unsigned int Shader::getRefCount() const
+{
+ return mRefCount;
+}
+
+bool Shader::isFlaggedForDeletion() const
+{
+ return mDeleteStatus;
+}
+
+void Shader::flagForDeletion()
+{
+ mDeleteStatus = true;
+}
+
+bool Shader::isCompiled(const Context *context)
+{
+ resolveCompile(context);
+ return mState.mCompileStatus == CompileStatus::COMPILED;
+}
+
+bool Shader::isCompleted()
+{
+ return (!mState.compilePending() || mCompilingState->compileEvent->isReady());
+}
+
+int Shader::getShaderVersion(const Context *context)
+{
+ resolveCompile(context);
+ return mState.mShaderVersion;
+}
+
+const std::vector<sh::ShaderVariable> &Shader::getInputVaryings(const Context *context)
+{
+ resolveCompile(context);
+ return mState.getInputVaryings();
+}
+
+const std::vector<sh::ShaderVariable> &Shader::getOutputVaryings(const Context *context)
+{
+ resolveCompile(context);
+ return mState.getOutputVaryings();
+}
+
+const std::vector<sh::ShaderVariable> &Shader::getUniforms(const Context *context)
+{
+ resolveCompile(context);
+ return mState.getUniforms();
+}
+
+const std::vector<sh::InterfaceBlock> &Shader::getUniformBlocks(const Context *context)
+{
+ resolveCompile(context);
+ return mState.getUniformBlocks();
+}
+
+const std::vector<sh::InterfaceBlock> &Shader::getShaderStorageBlocks(const Context *context)
+{
+ resolveCompile(context);
+ return mState.getShaderStorageBlocks();
+}
+
+const std::vector<sh::ShaderVariable> &Shader::getActiveAttributes(const Context *context)
+{
+ resolveCompile(context);
+ return mState.getActiveAttributes();
+}
+
+const std::vector<sh::ShaderVariable> &Shader::getAllAttributes(const Context *context)
+{
+ resolveCompile(context);
+ return mState.getAllAttributes();
+}
+
+const std::vector<sh::ShaderVariable> &Shader::getActiveOutputVariables(const Context *context)
+{
+ resolveCompile(context);
+ return mState.getActiveOutputVariables();
+}
+
+std::string Shader::getTransformFeedbackVaryingMappedName(const Context *context,
+ const std::string &tfVaryingName)
+{
+ ASSERT(mState.getShaderType() != ShaderType::Fragment &&
+ mState.getShaderType() != ShaderType::Compute);
+ const auto &varyings = getOutputVaryings(context);
+ auto bracketPos = tfVaryingName.find("[");
+ if (bracketPos != std::string::npos)
+ {
+ auto tfVaryingBaseName = tfVaryingName.substr(0, bracketPos);
+ for (const auto &varying : varyings)
+ {
+ if (varying.name == tfVaryingBaseName)
+ {
+ std::string mappedNameWithArrayIndex =
+ varying.mappedName + tfVaryingName.substr(bracketPos);
+ return mappedNameWithArrayIndex;
+ }
+ }
+ }
+ else
+ {
+ for (const auto &varying : varyings)
+ {
+ if (varying.name == tfVaryingName)
+ {
+ return varying.mappedName;
+ }
+ else if (varying.isStruct())
+ {
+ GLuint fieldIndex = 0;
+ const auto *field = varying.findField(tfVaryingName, &fieldIndex);
+ if (field == nullptr)
+ {
+ continue;
+ }
+ ASSERT(field != nullptr && !field->isStruct() &&
+ (!field->isArray() || varying.isShaderIOBlock));
+ std::string mappedName;
+ // If it's an I/O block without an instance name, don't include the block name.
+ if (!varying.isShaderIOBlock || !varying.name.empty())
+ {
+ mappedName = varying.isShaderIOBlock ? varying.mappedStructOrBlockName
+ : varying.mappedName;
+ mappedName += '.';
+ }
+ return mappedName + field->mappedName;
+ }
+ }
+ }
+ UNREACHABLE();
+ return std::string();
+}
+
+const sh::WorkGroupSize &Shader::getWorkGroupSize(const Context *context)
+{
+ resolveCompile(context);
+ return mState.mLocalSize;
+}
+
+int Shader::getNumViews(const Context *context)
+{
+ resolveCompile(context);
+ return mState.mNumViews;
+}
+
+Optional<PrimitiveMode> Shader::getGeometryShaderInputPrimitiveType(const Context *context)
+{
+ resolveCompile(context);
+ return mState.mGeometryShaderInputPrimitiveType;
+}
+
+Optional<PrimitiveMode> Shader::getGeometryShaderOutputPrimitiveType(const Context *context)
+{
+ resolveCompile(context);
+ return mState.mGeometryShaderOutputPrimitiveType;
+}
+
+int Shader::getGeometryShaderInvocations(const Context *context)
+{
+ resolveCompile(context);
+ return mState.mGeometryShaderInvocations;
+}
+
+Optional<GLint> Shader::getGeometryShaderMaxVertices(const Context *context)
+{
+ resolveCompile(context);
+ return mState.mGeometryShaderMaxVertices;
+}
+
+int Shader::getTessControlShaderVertices(const Context *context)
+{
+ resolveCompile(context);
+ return mState.mTessControlShaderVertices;
+}
+
+GLenum Shader::getTessGenMode(const Context *context)
+{
+ resolveCompile(context);
+ return mState.mTessGenMode;
+}
+
+GLenum Shader::getTessGenSpacing(const Context *context)
+{
+ resolveCompile(context);
+ return mState.mTessGenSpacing;
+}
+
+GLenum Shader::getTessGenVertexOrder(const Context *context)
+{
+ resolveCompile(context);
+ return mState.mTessGenVertexOrder;
+}
+
+GLenum Shader::getTessGenPointMode(const Context *context)
+{
+ resolveCompile(context);
+ return mState.mTessGenPointMode;
+}
+
+const std::string &Shader::getCompilerResourcesString() const
+{
+ return mCompilerResourcesString;
+}
+
+angle::Result Shader::serialize(const Context *context, angle::MemoryBuffer *binaryOut) const
+{
+ BinaryOutputStream stream;
+
+ stream.writeInt(kShaderCacheIdentifier);
+ stream.writeString(mState.mLabel);
+ stream.writeInt(mState.mShaderVersion);
+ stream.writeString(mCompilerResourcesString);
+
+ stream.writeInt(mState.mUniforms.size());
+ for (const sh::ShaderVariable &shaderVariable : mState.mUniforms)
+ {
+ WriteShaderVar(&stream, shaderVariable);
+ }
+
+ stream.writeInt(mState.mUniformBlocks.size());
+ for (const sh::InterfaceBlock &interfaceBlock : mState.mUniformBlocks)
+ {
+ WriteInterfaceBlock(&stream, interfaceBlock);
+ }
+
+ stream.writeInt(mState.mShaderStorageBlocks.size());
+ for (const sh::InterfaceBlock &interfaceBlock : mState.mShaderStorageBlocks)
+ {
+ WriteInterfaceBlock(&stream, interfaceBlock);
+ }
+
+ stream.writeInt(mState.mSpecConstUsageBits.bits());
+
+ switch (mType)
+ {
+ case ShaderType::Compute:
+ {
+ stream.writeInt(mState.mAllAttributes.size());
+ for (const sh::ShaderVariable &shaderVariable : mState.mAllAttributes)
+ {
+ WriteShaderVar(&stream, shaderVariable);
+ }
+ stream.writeInt(mState.mActiveAttributes.size());
+ for (const sh::ShaderVariable &shaderVariable : mState.mActiveAttributes)
+ {
+ WriteShaderVar(&stream, shaderVariable);
+ }
+ stream.writeInt(mState.mLocalSize[0]);
+ stream.writeInt(mState.mLocalSize[1]);
+ stream.writeInt(mState.mLocalSize[2]);
+ break;
+ }
+
+ case ShaderType::Vertex:
+ {
+ stream.writeInt(mState.mOutputVaryings.size());
+ for (const sh::ShaderVariable &shaderVariable : mState.mOutputVaryings)
+ {
+ WriteShaderVar(&stream, shaderVariable);
+ }
+ stream.writeInt(mState.mAllAttributes.size());
+ for (const sh::ShaderVariable &shaderVariable : mState.mAllAttributes)
+ {
+ WriteShaderVar(&stream, shaderVariable);
+ }
+ stream.writeInt(mState.mActiveAttributes.size());
+ for (const sh::ShaderVariable &shaderVariable : mState.mActiveAttributes)
+ {
+ WriteShaderVar(&stream, shaderVariable);
+ }
+ stream.writeInt(mState.mNumViews);
+ break;
+ }
+ case ShaderType::Fragment:
+ {
+ stream.writeInt(mState.mInputVaryings.size());
+ for (const sh::ShaderVariable &shaderVariable : mState.mInputVaryings)
+ {
+ WriteShaderVar(&stream, shaderVariable);
+ }
+ stream.writeInt(mState.mActiveOutputVariables.size());
+ for (const sh::ShaderVariable &shaderVariable : mState.mActiveOutputVariables)
+ {
+ WriteShaderVar(&stream, shaderVariable);
+ }
+ stream.writeBool(mState.mEnablesPerSampleShading);
+ stream.writeInt(mState.mAdvancedBlendEquations.bits());
+ break;
+ }
+ case ShaderType::Geometry:
+ {
+ bool valid;
+
+ stream.writeInt(mState.mInputVaryings.size());
+ for (const sh::ShaderVariable &shaderVariable : mState.mInputVaryings)
+ {
+ WriteShaderVar(&stream, shaderVariable);
+ }
+ stream.writeInt(mState.mOutputVaryings.size());
+ for (const sh::ShaderVariable &shaderVariable : mState.mOutputVaryings)
+ {
+ WriteShaderVar(&stream, shaderVariable);
+ }
+
+ valid = (bool)mState.mGeometryShaderInputPrimitiveType.valid();
+ stream.writeBool(valid);
+ if (valid)
+ {
+ unsigned char value =
+ (unsigned char)mState.mGeometryShaderInputPrimitiveType.value();
+ stream.writeBytes(&value, 1);
+ }
+ valid = (bool)mState.mGeometryShaderOutputPrimitiveType.valid();
+ stream.writeBool(valid);
+ if (valid)
+ {
+ unsigned char value =
+ (unsigned char)mState.mGeometryShaderOutputPrimitiveType.value();
+ stream.writeBytes(&value, 1);
+ }
+ valid = mState.mGeometryShaderMaxVertices.valid();
+ stream.writeBool(valid);
+ if (valid)
+ {
+ int value = (int)mState.mGeometryShaderMaxVertices.value();
+ stream.writeInt(value);
+ }
+
+ stream.writeInt(mState.mGeometryShaderInvocations);
+ break;
+ }
+ case ShaderType::TessControl:
+ {
+ stream.writeInt(mState.mInputVaryings.size());
+ for (const sh::ShaderVariable &shaderVariable : mState.mInputVaryings)
+ {
+ WriteShaderVar(&stream, shaderVariable);
+ }
+ stream.writeInt(mState.mOutputVaryings.size());
+ for (const sh::ShaderVariable &shaderVariable : mState.mOutputVaryings)
+ {
+ WriteShaderVar(&stream, shaderVariable);
+ }
+ stream.writeInt(mState.mTessControlShaderVertices);
+ break;
+ }
+ case ShaderType::TessEvaluation:
+ {
+ unsigned int value;
+
+ stream.writeInt(mState.mInputVaryings.size());
+ for (const sh::ShaderVariable &shaderVariable : mState.mInputVaryings)
+ {
+ WriteShaderVar(&stream, shaderVariable);
+ }
+ stream.writeInt(mState.mOutputVaryings.size());
+ for (const sh::ShaderVariable &shaderVariable : mState.mOutputVaryings)
+ {
+ WriteShaderVar(&stream, shaderVariable);
+ }
+
+ value = (unsigned int)(mState.mTessGenMode);
+ stream.writeInt(value);
+
+ value = (unsigned int)mState.mTessGenSpacing;
+ stream.writeInt(value);
+
+ value = (unsigned int)mState.mTessGenVertexOrder;
+ stream.writeInt(value);
+
+ value = (unsigned int)mState.mTessGenPointMode;
+ stream.writeInt(value);
+ break;
+ }
+ default:
+ UNREACHABLE();
+ }
+
+ stream.writeIntVector(mState.mCompiledBinary);
+ stream.writeEnum(mState.mCompileStatus);
+
+ ASSERT(binaryOut);
+ if (!binaryOut->resize(stream.length()))
+ {
+ std::stringstream sstream;
+ sstream << "Failed to allocate enough memory to serialize a shader. (" << stream.length()
+ << " bytes )";
+ ANGLE_PERF_WARNING(context->getState().getDebug(), GL_DEBUG_SEVERITY_LOW,
+ sstream.str().c_str());
+ return angle::Result::Incomplete;
+ }
+
+ memcpy(binaryOut->data(), stream.data(), stream.length());
+
+ return angle::Result::Continue;
+}
+
+angle::Result Shader::deserialize(const Context *context, BinaryInputStream &stream)
+{
+ size_t size;
+
+ if (stream.readInt<uint32_t>() != kShaderCacheIdentifier)
+ {
+ return angle::Result::Stop;
+ }
+
+ stream.readString(&mState.mLabel);
+ stream.readInt(&mState.mShaderVersion);
+ stream.readString(&mCompilerResourcesString);
+
+ size = stream.readInt<size_t>();
+ mState.mUniforms.resize(size);
+ for (sh::ShaderVariable &shaderVariable : mState.mUniforms)
+ {
+ LoadShaderVar(&stream, &shaderVariable);
+ }
+
+ size = stream.readInt<size_t>();
+ mState.mUniformBlocks.resize(size);
+ for (sh::InterfaceBlock &interfaceBlock : mState.mUniformBlocks)
+ {
+ LoadInterfaceBlock(&stream, interfaceBlock);
+ }
+
+ size = stream.readInt<size_t>();
+ mState.mShaderStorageBlocks.resize(size);
+ for (sh::InterfaceBlock &interfaceBlock : mState.mShaderStorageBlocks)
+ {
+ LoadInterfaceBlock(&stream, interfaceBlock);
+ }
+
+ mState.mSpecConstUsageBits = rx::SpecConstUsageBits(stream.readInt<uint32_t>());
+
+ switch (mType)
+ {
+ case ShaderType::Compute:
+ {
+ size = stream.readInt<size_t>();
+ mState.mAllAttributes.resize(size);
+ for (sh::ShaderVariable &shaderVariable : mState.mAllAttributes)
+ {
+ LoadShaderVar(&stream, &shaderVariable);
+ }
+ size = stream.readInt<size_t>();
+ mState.mActiveAttributes.resize(size);
+ for (sh::ShaderVariable &shaderVariable : mState.mActiveAttributes)
+ {
+ LoadShaderVar(&stream, &shaderVariable);
+ }
+ stream.readInt(&mState.mLocalSize[0]);
+ stream.readInt(&mState.mLocalSize[1]);
+ stream.readInt(&mState.mLocalSize[2]);
+ break;
+ }
+ case ShaderType::Vertex:
+ {
+ size = stream.readInt<size_t>();
+ mState.mOutputVaryings.resize(size);
+ for (sh::ShaderVariable &shaderVariable : mState.mOutputVaryings)
+ {
+ LoadShaderVar(&stream, &shaderVariable);
+ }
+ size = stream.readInt<size_t>();
+ mState.mAllAttributes.resize(size);
+ for (sh::ShaderVariable &shaderVariable : mState.mAllAttributes)
+ {
+ LoadShaderVar(&stream, &shaderVariable);
+ }
+ size = stream.readInt<size_t>();
+ mState.mActiveAttributes.resize(size);
+ for (sh::ShaderVariable &shaderVariable : mState.mActiveAttributes)
+ {
+ LoadShaderVar(&stream, &shaderVariable);
+ }
+ stream.readInt(&mState.mNumViews);
+ break;
+ }
+ case ShaderType::Fragment:
+ {
+ size = stream.readInt<size_t>();
+ mState.mInputVaryings.resize(size);
+ for (sh::ShaderVariable &shaderVariable : mState.mInputVaryings)
+ {
+ LoadShaderVar(&stream, &shaderVariable);
+ }
+ size = stream.readInt<size_t>();
+ mState.mActiveOutputVariables.resize(size);
+ for (sh::ShaderVariable &shaderVariable : mState.mActiveOutputVariables)
+ {
+ LoadShaderVar(&stream, &shaderVariable);
+ }
+ stream.readBool(&mState.mEnablesPerSampleShading);
+ int advancedBlendEquationBits;
+ stream.readInt(&advancedBlendEquationBits);
+ mState.mAdvancedBlendEquations = BlendEquationBitSet(advancedBlendEquationBits);
+ break;
+ }
+ case ShaderType::Geometry:
+ {
+ bool valid;
+
+ size = stream.readInt<size_t>();
+ mState.mInputVaryings.resize(size);
+ for (sh::ShaderVariable &shaderVariable : mState.mInputVaryings)
+ {
+ LoadShaderVar(&stream, &shaderVariable);
+ }
+ size = stream.readInt<size_t>();
+ mState.mOutputVaryings.resize(size);
+ for (sh::ShaderVariable &shaderVariable : mState.mOutputVaryings)
+ {
+ LoadShaderVar(&stream, &shaderVariable);
+ }
+
+ stream.readBool(&valid);
+ if (valid)
+ {
+ unsigned char value;
+ stream.readBytes(&value, 1);
+ mState.mGeometryShaderInputPrimitiveType = static_cast<PrimitiveMode>(value);
+ }
+ else
+ {
+ mState.mGeometryShaderInputPrimitiveType.reset();
+ }
+
+ stream.readBool(&valid);
+ if (valid)
+ {
+ unsigned char value;
+ stream.readBytes(&value, 1);
+ mState.mGeometryShaderOutputPrimitiveType = static_cast<PrimitiveMode>(value);
+ }
+ else
+ {
+ mState.mGeometryShaderOutputPrimitiveType.reset();
+ }
+
+ stream.readBool(&valid);
+ if (valid)
+ {
+ int value;
+ stream.readInt(&value);
+ mState.mGeometryShaderMaxVertices = static_cast<GLint>(value);
+ }
+ else
+ {
+ mState.mGeometryShaderMaxVertices.reset();
+ }
+
+ stream.readInt(&mState.mGeometryShaderInvocations);
+ break;
+ }
+ case ShaderType::TessControl:
+ {
+ size = stream.readInt<size_t>();
+ mState.mInputVaryings.resize(size);
+ for (sh::ShaderVariable &shaderVariable : mState.mInputVaryings)
+ {
+ LoadShaderVar(&stream, &shaderVariable);
+ }
+ size = stream.readInt<size_t>();
+ mState.mOutputVaryings.resize(size);
+ for (sh::ShaderVariable &shaderVariable : mState.mOutputVaryings)
+ {
+ LoadShaderVar(&stream, &shaderVariable);
+ }
+ stream.readInt(&mState.mTessControlShaderVertices);
+ break;
+ }
+ case ShaderType::TessEvaluation:
+ {
+ unsigned int value;
+
+ size = stream.readInt<size_t>();
+ mState.mInputVaryings.resize(size);
+ for (sh::ShaderVariable &shaderVariable : mState.mInputVaryings)
+ {
+ LoadShaderVar(&stream, &shaderVariable);
+ }
+ size = stream.readInt<size_t>();
+ mState.mOutputVaryings.resize(size);
+ for (sh::ShaderVariable &shaderVariable : mState.mOutputVaryings)
+ {
+ LoadShaderVar(&stream, &shaderVariable);
+ }
+
+ stream.readInt(&value);
+ mState.mTessGenMode = (GLenum)value;
+
+ stream.readInt(&value);
+ mState.mTessGenSpacing = (GLenum)value;
+
+ stream.readInt(&value);
+ mState.mTessGenVertexOrder = (GLenum)value;
+
+ stream.readInt(&value);
+ mState.mTessGenPointMode = (GLenum)value;
+ break;
+ }
+ default:
+ UNREACHABLE();
+ }
+
+ stream.readIntVector<unsigned int>(&mState.mCompiledBinary);
+ mState.mCompileStatus = stream.readEnum<CompileStatus>();
+
+ return angle::Result::Continue;
+}
+
+angle::Result Shader::loadBinary(const Context *context, const void *binary, GLsizei length)
+{
+ BinaryInputStream stream(binary, length);
+ ANGLE_TRY(deserialize(context, stream));
+
+ return angle::Result::Continue;
+}
+
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/Shader.h b/gfx/angle/checkout/src/libANGLE/Shader.h
new file mode 100644
index 0000000000..59b1f3cc3e
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Shader.h
@@ -0,0 +1,305 @@
+//
+// Copyright 2002 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.
+//
+
+// Shader.h: Defines the abstract gl::Shader class and its concrete derived
+// classes VertexShader and FragmentShader. Implements GL shader objects and
+// related functionality. [OpenGL ES 2.0.24] section 2.10 page 24 and section
+// 3.8 page 84.
+
+#ifndef LIBANGLE_SHADER_H_
+#define LIBANGLE_SHADER_H_
+
+#include <list>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <GLSLANG/ShaderLang.h>
+#include "angle_gl.h"
+
+#include "common/MemoryBuffer.h"
+#include "common/Optional.h"
+#include "common/angleutils.h"
+#include "libANGLE/BinaryStream.h"
+#include "libANGLE/Caps.h"
+#include "libANGLE/Compiler.h"
+#include "libANGLE/Debug.h"
+#include "libANGLE/angletypes.h"
+
+namespace rx
+{
+class GLImplFactory;
+class ShaderImpl;
+class ShaderSh;
+class WaitableCompileEvent;
+} // namespace rx
+
+namespace angle
+{
+class WaitableEvent;
+class WorkerThreadPool;
+} // namespace angle
+
+namespace gl
+{
+class CompileTask;
+class Context;
+class ShaderProgramManager;
+class State;
+class BinaryInputStream;
+class BinaryOutputStream;
+
+// We defer the compile until link time, or until properties are queried.
+enum class CompileStatus
+{
+ NOT_COMPILED,
+ COMPILE_REQUESTED,
+ COMPILED,
+};
+
+class ShaderState final : angle::NonCopyable
+{
+ public:
+ ShaderState(ShaderType shaderType);
+ ~ShaderState();
+
+ const std::string &getLabel() const { return mLabel; }
+
+ const std::string &getSource() const { return mSource; }
+ bool isCompiledToBinary() const { return !mCompiledBinary.empty(); }
+ const std::string &getTranslatedSource() const { return mTranslatedSource; }
+ const sh::BinaryBlob &getCompiledBinary() const { return mCompiledBinary; }
+
+ ShaderType getShaderType() const { return mShaderType; }
+ int getShaderVersion() const { return mShaderVersion; }
+
+ const std::vector<sh::ShaderVariable> &getInputVaryings() const { return mInputVaryings; }
+ const std::vector<sh::ShaderVariable> &getOutputVaryings() const { return mOutputVaryings; }
+ const std::vector<sh::ShaderVariable> &getUniforms() const { return mUniforms; }
+ const std::vector<sh::InterfaceBlock> &getUniformBlocks() const { return mUniformBlocks; }
+ const std::vector<sh::InterfaceBlock> &getShaderStorageBlocks() const
+ {
+ return mShaderStorageBlocks;
+ }
+ const std::vector<sh::ShaderVariable> &getActiveAttributes() const { return mActiveAttributes; }
+ const std::vector<sh::ShaderVariable> &getAllAttributes() const { return mAllAttributes; }
+ const std::vector<sh::ShaderVariable> &getActiveOutputVariables() const
+ {
+ return mActiveOutputVariables;
+ }
+
+ bool compilePending() const { return mCompileStatus == CompileStatus::COMPILE_REQUESTED; }
+
+ const sh::WorkGroupSize &getLocalSize() const { return mLocalSize; }
+
+ bool hasDiscard() const { return mHasDiscard; }
+ bool enablesPerSampleShading() const { return mEnablesPerSampleShading; }
+ rx::SpecConstUsageBits getSpecConstUsageBits() const { return mSpecConstUsageBits; }
+
+ int getNumViews() const { return mNumViews; }
+
+ Optional<PrimitiveMode> getGeometryShaderInputPrimitiveType() const
+ {
+ return mGeometryShaderInputPrimitiveType;
+ }
+
+ Optional<PrimitiveMode> getGeometryShaderOutputPrimitiveType() const
+ {
+ return mGeometryShaderOutputPrimitiveType;
+ }
+
+ Optional<GLint> geoGeometryShaderMaxVertices() const { return mGeometryShaderMaxVertices; }
+
+ Optional<GLint> getGeometryShaderInvocations() const { return mGeometryShaderInvocations; }
+
+ CompileStatus getCompileStatus() const { return mCompileStatus; }
+
+ private:
+ friend class Shader;
+
+ std::string mLabel;
+
+ ShaderType mShaderType;
+ int mShaderVersion;
+ std::string mTranslatedSource;
+ sh::BinaryBlob mCompiledBinary;
+ std::string mSource;
+
+ sh::WorkGroupSize mLocalSize;
+
+ std::vector<sh::ShaderVariable> mInputVaryings;
+ std::vector<sh::ShaderVariable> mOutputVaryings;
+ std::vector<sh::ShaderVariable> mUniforms;
+ std::vector<sh::InterfaceBlock> mUniformBlocks;
+ std::vector<sh::InterfaceBlock> mShaderStorageBlocks;
+ std::vector<sh::ShaderVariable> mAllAttributes;
+ std::vector<sh::ShaderVariable> mActiveAttributes;
+ std::vector<sh::ShaderVariable> mActiveOutputVariables;
+
+ bool mHasDiscard;
+ bool mEnablesPerSampleShading;
+ BlendEquationBitSet mAdvancedBlendEquations;
+ rx::SpecConstUsageBits mSpecConstUsageBits;
+
+ // ANGLE_multiview.
+ int mNumViews;
+
+ // Geometry Shader.
+ Optional<PrimitiveMode> mGeometryShaderInputPrimitiveType;
+ Optional<PrimitiveMode> mGeometryShaderOutputPrimitiveType;
+ Optional<GLint> mGeometryShaderMaxVertices;
+ int mGeometryShaderInvocations;
+
+ // Tessellation Shader
+ int mTessControlShaderVertices;
+ GLenum mTessGenMode;
+ GLenum mTessGenSpacing;
+ GLenum mTessGenVertexOrder;
+ GLenum mTessGenPointMode;
+
+ // Indicates if this shader has been successfully compiled
+ CompileStatus mCompileStatus;
+};
+
+class Shader final : angle::NonCopyable, public LabeledObject
+{
+ public:
+ Shader(ShaderProgramManager *manager,
+ rx::GLImplFactory *implFactory,
+ const gl::Limitations &rendererLimitations,
+ ShaderType type,
+ ShaderProgramID handle);
+
+ void onDestroy(const Context *context);
+
+ angle::Result setLabel(const Context *context, const std::string &label) override;
+ const std::string &getLabel() const override;
+
+ ShaderType getType() const { return mType; }
+ ShaderProgramID getHandle() const;
+
+ rx::ShaderImpl *getImplementation() const { return mImplementation.get(); }
+
+ void setSource(GLsizei count, const char *const *string, const GLint *length);
+ int getInfoLogLength(const Context *context);
+ void getInfoLog(const Context *context, GLsizei bufSize, GLsizei *length, char *infoLog);
+ std::string getInfoLogString() const { return mInfoLog; }
+ int getSourceLength() const;
+ const std::string &getSourceString() const { return mState.getSource(); }
+ void getSource(GLsizei bufSize, GLsizei *length, char *buffer) const;
+ int getTranslatedSourceLength(const Context *context);
+ int getTranslatedSourceWithDebugInfoLength(const Context *context);
+ const std::string &getTranslatedSource(const Context *context);
+ void getTranslatedSource(const Context *context,
+ GLsizei bufSize,
+ GLsizei *length,
+ char *buffer);
+ void getTranslatedSourceWithDebugInfo(const Context *context,
+ GLsizei bufSize,
+ GLsizei *length,
+ char *buffer);
+ const sh::BinaryBlob &getCompiledBinary(const Context *context);
+
+ void compile(const Context *context);
+ bool isCompiled(const Context *context);
+ bool isCompleted();
+
+ void addRef();
+ void release(const Context *context);
+ unsigned int getRefCount() const;
+ bool isFlaggedForDeletion() const;
+ void flagForDeletion();
+ bool hasDiscard() const { return mState.mHasDiscard; }
+ bool enablesPerSampleShading() const { return mState.mEnablesPerSampleShading; }
+ BlendEquationBitSet getAdvancedBlendEquations() const { return mState.mAdvancedBlendEquations; }
+ rx::SpecConstUsageBits getSpecConstUsageBits() const { return mState.mSpecConstUsageBits; }
+
+ int getShaderVersion(const Context *context);
+
+ const std::vector<sh::ShaderVariable> &getInputVaryings(const Context *context);
+ const std::vector<sh::ShaderVariable> &getOutputVaryings(const Context *context);
+ const std::vector<sh::ShaderVariable> &getUniforms(const Context *context);
+ const std::vector<sh::InterfaceBlock> &getUniformBlocks(const Context *context);
+ const std::vector<sh::InterfaceBlock> &getShaderStorageBlocks(const Context *context);
+ const std::vector<sh::ShaderVariable> &getActiveAttributes(const Context *context);
+ const std::vector<sh::ShaderVariable> &getAllAttributes(const Context *context);
+ const std::vector<sh::ShaderVariable> &getActiveOutputVariables(const Context *context);
+
+ // Returns mapped name of a transform feedback varying. The original name may contain array
+ // brackets with an index inside, which will get copied to the mapped name. The varying must be
+ // known to be declared in the shader.
+ std::string getTransformFeedbackVaryingMappedName(const Context *context,
+ const std::string &tfVaryingName);
+
+ const sh::WorkGroupSize &getWorkGroupSize(const Context *context);
+
+ int getNumViews(const Context *context);
+
+ Optional<PrimitiveMode> getGeometryShaderInputPrimitiveType(const Context *context);
+ Optional<PrimitiveMode> getGeometryShaderOutputPrimitiveType(const Context *context);
+ int getGeometryShaderInvocations(const Context *context);
+ Optional<GLint> getGeometryShaderMaxVertices(const Context *context);
+ int getTessControlShaderVertices(const Context *context);
+ GLenum getTessGenMode(const Context *context);
+ GLenum getTessGenSpacing(const Context *context);
+ GLenum getTessGenVertexOrder(const Context *context);
+ GLenum getTessGenPointMode(const Context *context);
+
+ const std::string &getCompilerResourcesString() const;
+
+ const ShaderState &getState() const { return mState; }
+
+ GLuint getCurrentMaxComputeWorkGroupInvocations() const
+ {
+ return mCurrentMaxComputeWorkGroupInvocations;
+ }
+
+ unsigned int getMaxComputeSharedMemory() const { return mMaxComputeSharedMemory; }
+ bool hasBeenDeleted() const { return mDeleteStatus; }
+
+ // Block until compiling is finished and resolve it.
+ void resolveCompile(const Context *context);
+
+ // Writes a shader's binary to the output memory buffer.
+ angle::Result serialize(const Context *context, angle::MemoryBuffer *binaryOut) const;
+ angle::Result deserialize(const Context *context, BinaryInputStream &stream);
+ angle::Result loadBinary(const Context *context, const void *binary, GLsizei length);
+
+ private:
+ struct CompilingState;
+
+ ~Shader() override;
+ static void GetSourceImpl(const std::string &source,
+ GLsizei bufSize,
+ GLsizei *length,
+ char *buffer);
+
+ ShaderState mState;
+ std::unique_ptr<rx::ShaderImpl> mImplementation;
+ const gl::Limitations mRendererLimitations;
+ const ShaderProgramID mHandle;
+ const ShaderType mType;
+ unsigned int mRefCount; // Number of program objects this shader is attached to
+ bool mDeleteStatus; // Flag to indicate that the shader can be deleted when no longer in use
+ std::string mInfoLog;
+
+ // We keep a reference to the translator in order to defer compiles while preserving settings.
+ BindingPointer<Compiler> mBoundCompiler;
+ std::unique_ptr<CompilingState> mCompilingState;
+ std::string mCompilerResourcesString;
+
+ ShaderProgramManager *mResourceManager;
+
+ GLuint mCurrentMaxComputeWorkGroupInvocations;
+ unsigned int mMaxComputeSharedMemory;
+};
+
+bool CompareShaderVar(const sh::ShaderVariable &x, const sh::ShaderVariable &y);
+
+const char *GetShaderTypeString(ShaderType type);
+} // namespace gl
+
+#endif // LIBANGLE_SHADER_H_
diff --git a/gfx/angle/checkout/src/libANGLE/SizedMRUCache.h b/gfx/angle/checkout/src/libANGLE/SizedMRUCache.h
new file mode 100644
index 0000000000..b557e657ec
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/SizedMRUCache.h
@@ -0,0 +1,156 @@
+//
+// Copyright 2017 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.
+//
+// SizedMRUCache.h: A hashing map that stores blobs of sized, untyped data.
+
+#ifndef LIBANGLE_SIZED_MRU_CACHE_H_
+#define LIBANGLE_SIZED_MRU_CACHE_H_
+
+#include <anglebase/containers/mru_cache.h>
+
+namespace angle
+{
+
+template <typename Key, typename Value>
+class SizedMRUCache final : angle::NonCopyable
+{
+ public:
+ SizedMRUCache(size_t maximumTotalSize)
+ : mMaximumTotalSize(maximumTotalSize),
+ mCurrentSize(0),
+ mStore(SizedMRUCacheStore::NO_AUTO_EVICT)
+ {}
+
+ // Returns nullptr on failure.
+ const Value *put(const Key &key, Value &&value, size_t size)
+ {
+ if (size > mMaximumTotalSize)
+ {
+ return nullptr;
+ }
+
+ // Check for existing key.
+ eraseByKey(key);
+
+ auto retVal = mStore.Put(key, ValueAndSize(std::move(value), size));
+ mCurrentSize += size;
+
+ shrinkToSize(mMaximumTotalSize);
+
+ return &retVal->second.value;
+ }
+
+ bool get(const Key &key, const Value **valueOut)
+ {
+ const auto &iter = mStore.Get(key);
+ if (iter == mStore.end())
+ {
+ return false;
+ }
+ *valueOut = &iter->second.value;
+ return true;
+ }
+
+ bool getAt(size_t index, const Key **keyOut, const Value **valueOut)
+ {
+ if (index < mStore.size())
+ {
+ auto it = mStore.begin();
+ std::advance(it, index);
+ *keyOut = &it->first;
+ *valueOut = &it->second.value;
+ return true;
+ }
+ *valueOut = nullptr;
+ return false;
+ }
+
+ bool empty() const { return mStore.empty(); }
+
+ void clear()
+ {
+ mStore.Clear();
+ mCurrentSize = 0;
+ }
+
+ void eraseByKey(const Key &key)
+ {
+ // Check for existing key.
+ auto existing = mStore.Peek(key);
+ if (existing != mStore.end())
+ {
+ mCurrentSize -= existing->second.size;
+ mStore.Erase(existing);
+ }
+ }
+
+ size_t entryCount() const { return mStore.size(); }
+
+ size_t size() const { return mCurrentSize; }
+
+ // Also discards the cache contents.
+ void resize(size_t maximumTotalSize)
+ {
+ clear();
+ mMaximumTotalSize = maximumTotalSize;
+ }
+
+ // Reduce current memory usage.
+ size_t shrinkToSize(size_t limit)
+ {
+ size_t initialSize = mCurrentSize;
+
+ while (mCurrentSize > limit)
+ {
+ ASSERT(!mStore.empty());
+ auto iter = mStore.rbegin();
+ mCurrentSize -= iter->second.size;
+ mStore.Erase(iter);
+ }
+
+ return (initialSize - mCurrentSize);
+ }
+
+ size_t maxSize() const { return mMaximumTotalSize; }
+
+ private:
+ struct ValueAndSize
+ {
+ ValueAndSize() : value(), size(0) {}
+ ValueAndSize(Value &&value, size_t size) : value(std::move(value)), size(size) {}
+ ValueAndSize(ValueAndSize &&other) : ValueAndSize() { *this = std::move(other); }
+ ValueAndSize &operator=(ValueAndSize &&other)
+ {
+ std::swap(value, other.value);
+ std::swap(size, other.size);
+ return *this;
+ }
+
+ Value value;
+ size_t size;
+ };
+
+ using SizedMRUCacheStore = base::HashingMRUCache<Key, ValueAndSize>;
+
+ size_t mMaximumTotalSize;
+ size_t mCurrentSize;
+ SizedMRUCacheStore mStore;
+};
+
+// Helper function used in a few places.
+template <typename T>
+void TrimCache(size_t maxStates, size_t gcLimit, const char *name, T *cache)
+{
+ const size_t kGarbageCollectionLimit = maxStates / 2 + gcLimit;
+
+ if (cache->size() >= kGarbageCollectionLimit)
+ {
+ WARN() << "Overflowed the " << name << " cache limit of " << (maxStates / 2)
+ << " elements, removing the least recently used to make room.";
+ cache->ShrinkToSize(maxStates / 2);
+ }
+}
+} // namespace angle
+#endif // LIBANGLE_SIZED_MRU_CACHE_H_
diff --git a/gfx/angle/checkout/src/libANGLE/State.cpp b/gfx/angle/checkout/src/libANGLE/State.cpp
new file mode 100644
index 0000000000..8f99a238a6
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/State.cpp
@@ -0,0 +1,3866 @@
+//
+// 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.
+//
+
+// State.cpp: Implements the State class, encapsulating raw GL state.
+
+#include "libANGLE/State.h"
+
+#include <string.h>
+#include <limits>
+
+#include "common/bitset_utils.h"
+#include "common/mathutil.h"
+#include "common/matrix_utils.h"
+#include "libANGLE/Buffer.h"
+#include "libANGLE/Caps.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Debug.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/PixelLocalStorage.h"
+#include "libANGLE/Query.h"
+#include "libANGLE/VertexArray.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/queryconversions.h"
+#include "libANGLE/queryutils.h"
+#include "libANGLE/renderer/ContextImpl.h"
+#include "libANGLE/renderer/TextureImpl.h"
+
+namespace gl
+{
+
+namespace
+{
+bool GetAlternativeQueryType(QueryType type, QueryType *alternativeType)
+{
+ switch (type)
+ {
+ case QueryType::AnySamples:
+ *alternativeType = QueryType::AnySamplesConservative;
+ return true;
+ case QueryType::AnySamplesConservative:
+ *alternativeType = QueryType::AnySamples;
+ return true;
+ default:
+ return false;
+ }
+}
+
+// Mapping from a buffer binding type to a dirty bit type.
+constexpr angle::PackedEnumMap<BufferBinding, size_t> kBufferBindingDirtyBits = {{
+ {BufferBinding::AtomicCounter, State::DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING},
+ {BufferBinding::DispatchIndirect, State::DIRTY_BIT_DISPATCH_INDIRECT_BUFFER_BINDING},
+ {BufferBinding::DrawIndirect, State::DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING},
+ {BufferBinding::PixelPack, State::DIRTY_BIT_PACK_BUFFER_BINDING},
+ {BufferBinding::PixelUnpack, State::DIRTY_BIT_UNPACK_BUFFER_BINDING},
+ {BufferBinding::ShaderStorage, State::DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING},
+ {BufferBinding::Uniform, State::DIRTY_BIT_UNIFORM_BUFFER_BINDINGS},
+}};
+
+// Returns a buffer binding function depending on if a dirty bit is set.
+template <BufferBinding Target>
+constexpr std::pair<BufferBinding, State::BufferBindingSetter> GetBufferBindingSetter()
+{
+ return std::make_pair(Target, kBufferBindingDirtyBits[Target] != 0
+ ? &State::setGenericBufferBindingWithBit<Target>
+ : &State::setGenericBufferBinding<Target>);
+}
+
+template <typename T>
+using ContextStateMember = T *(State::*);
+
+template <typename T>
+T *AllocateOrGetSharedResourceManager(const State *shareContextState,
+ ContextStateMember<T> member,
+ T *shareResources = nullptr)
+{
+ if (shareContextState)
+ {
+ T *resourceManager = (*shareContextState).*member;
+ ASSERT(!resourceManager || resourceManager == shareResources || !shareResources);
+ resourceManager->addRef();
+ return resourceManager;
+ }
+ else if (shareResources)
+ {
+ shareResources->addRef();
+ return shareResources;
+ }
+ else
+ {
+ return new T();
+ }
+}
+
+// TODO(https://anglebug.com/3889): Remove this helper function after blink and chromium part
+// refactory done.
+bool IsTextureCompatibleWithSampler(TextureType texture, TextureType sampler)
+{
+ if (sampler == texture)
+ {
+ return true;
+ }
+
+ if (sampler == TextureType::VideoImage)
+ {
+ if (texture == TextureType::VideoImage || texture == TextureType::_2D)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+uint32_t gIDCounter = 1;
+} // namespace
+
+template <typename BindingT, typename... ArgsT>
+ANGLE_INLINE void UpdateNonTFBufferBindingWebGL(const Context *context,
+ BindingT *binding,
+ Buffer *buffer,
+ ArgsT... args)
+{
+ Buffer *oldBuffer = binding->get();
+ if (oldBuffer)
+ {
+ oldBuffer->onNonTFBindingChanged(-1);
+ oldBuffer->release(context);
+ }
+ binding->assign(buffer, args...);
+ if (buffer)
+ {
+ buffer->addRef();
+ buffer->onNonTFBindingChanged(1);
+ }
+}
+
+template <typename BindingT, typename... ArgsT>
+void UpdateTFBufferBindingWebGL(const Context *context,
+ BindingT *binding,
+ bool indexed,
+ ArgsT... args)
+{
+ if (binding->get())
+ (*binding)->onTFBindingChanged(context, false, indexed);
+ binding->set(context, args...);
+ if (binding->get())
+ (*binding)->onTFBindingChanged(context, true, indexed);
+}
+
+void UpdateBufferBinding(const Context *context,
+ BindingPointer<Buffer> *binding,
+ Buffer *buffer,
+ BufferBinding target)
+{
+ if (context->isWebGL())
+ {
+ if (target == BufferBinding::TransformFeedback)
+ {
+ UpdateTFBufferBindingWebGL(context, binding, false, buffer);
+ }
+ else
+ {
+ UpdateNonTFBufferBindingWebGL(context, binding, buffer);
+ }
+ }
+ else
+ {
+ binding->set(context, buffer);
+ }
+}
+
+void UpdateIndexedBufferBinding(const Context *context,
+ OffsetBindingPointer<Buffer> *binding,
+ Buffer *buffer,
+ BufferBinding target,
+ GLintptr offset,
+ GLsizeiptr size)
+{
+ if (context->isWebGL())
+ {
+ if (target == BufferBinding::TransformFeedback)
+ {
+ UpdateTFBufferBindingWebGL(context, binding, true, buffer, offset, size);
+ }
+ else
+ {
+ UpdateNonTFBufferBindingWebGL(context, binding, buffer, offset, size);
+ }
+ }
+ else
+ {
+ binding->set(context, buffer, offset, size);
+ }
+}
+
+// These template functions must be defined before they are instantiated in kBufferSetters.
+template <BufferBinding Target>
+void State::setGenericBufferBindingWithBit(const Context *context, Buffer *buffer)
+{
+ if (context->isWebGL())
+ {
+ UpdateNonTFBufferBindingWebGL(context, &mBoundBuffers[Target], buffer);
+ }
+ else
+ {
+ mBoundBuffers[Target].set(context, buffer);
+ }
+ mDirtyBits.set(kBufferBindingDirtyBits[Target]);
+}
+
+template <BufferBinding Target>
+void State::setGenericBufferBinding(const Context *context, Buffer *buffer)
+{
+ if (context->isWebGL())
+ {
+ UpdateNonTFBufferBindingWebGL(context, &mBoundBuffers[Target], buffer);
+ }
+ else
+ {
+ mBoundBuffers[Target].set(context, buffer);
+ }
+}
+
+template <>
+void State::setGenericBufferBinding<BufferBinding::TransformFeedback>(const Context *context,
+ Buffer *buffer)
+{
+ if (context->isWebGL())
+ {
+ UpdateTFBufferBindingWebGL(context, &mBoundBuffers[BufferBinding::TransformFeedback], false,
+ buffer);
+ }
+ else
+ {
+ mBoundBuffers[BufferBinding::TransformFeedback].set(context, buffer);
+ }
+}
+
+template <>
+void State::setGenericBufferBinding<BufferBinding::ElementArray>(const Context *context,
+ Buffer *buffer)
+{
+ Buffer *oldBuffer = mVertexArray->mState.mElementArrayBuffer.get();
+ if (oldBuffer)
+ {
+ oldBuffer->removeObserver(&mVertexArray->mState.mElementArrayBuffer);
+ oldBuffer->removeContentsObserver(mVertexArray, kElementArrayBufferIndex);
+ if (context->isWebGL())
+ {
+ oldBuffer->onNonTFBindingChanged(-1);
+ }
+ oldBuffer->release(context);
+ }
+ mVertexArray->mState.mElementArrayBuffer.assign(buffer);
+ if (buffer)
+ {
+ buffer->addObserver(&mVertexArray->mState.mElementArrayBuffer);
+ buffer->addContentsObserver(mVertexArray, kElementArrayBufferIndex);
+ if (context->isWebGL())
+ {
+ buffer->onNonTFBindingChanged(1);
+ }
+ buffer->addRef();
+ }
+ mVertexArray->mDirtyBits.set(VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER);
+ mVertexArray->mIndexRangeCache.invalidate();
+ mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
+}
+
+const angle::PackedEnumMap<BufferBinding, State::BufferBindingSetter> State::kBufferSetters = {{
+ GetBufferBindingSetter<BufferBinding::Array>(),
+ GetBufferBindingSetter<BufferBinding::AtomicCounter>(),
+ GetBufferBindingSetter<BufferBinding::CopyRead>(),
+ GetBufferBindingSetter<BufferBinding::CopyWrite>(),
+ GetBufferBindingSetter<BufferBinding::DispatchIndirect>(),
+ GetBufferBindingSetter<BufferBinding::DrawIndirect>(),
+ GetBufferBindingSetter<BufferBinding::ElementArray>(),
+ GetBufferBindingSetter<BufferBinding::PixelPack>(),
+ GetBufferBindingSetter<BufferBinding::PixelUnpack>(),
+ GetBufferBindingSetter<BufferBinding::ShaderStorage>(),
+ GetBufferBindingSetter<BufferBinding::Texture>(),
+ GetBufferBindingSetter<BufferBinding::TransformFeedback>(),
+ GetBufferBindingSetter<BufferBinding::Uniform>(),
+}};
+
+ActiveTexturesCache::ActiveTexturesCache() : mTextures{} {}
+
+ActiveTexturesCache::~ActiveTexturesCache()
+{
+ ASSERT(empty());
+}
+
+void ActiveTexturesCache::clear()
+{
+ for (size_t textureIndex = 0; textureIndex < mTextures.size(); ++textureIndex)
+ {
+ reset(textureIndex);
+ }
+}
+
+bool ActiveTexturesCache::empty() const
+{
+ for (Texture *texture : mTextures)
+ {
+ if (texture)
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+ANGLE_INLINE void ActiveTexturesCache::reset(size_t textureIndex)
+{
+ if (mTextures[textureIndex])
+ {
+ mTextures[textureIndex] = nullptr;
+ }
+}
+
+ANGLE_INLINE void ActiveTexturesCache::set(size_t textureIndex, Texture *texture)
+{
+ ASSERT(texture);
+ mTextures[textureIndex] = texture;
+}
+
+State::State(const State *shareContextState,
+ egl::ShareGroup *shareGroup,
+ TextureManager *shareTextures,
+ SemaphoreManager *shareSemaphores,
+ const OverlayType *overlay,
+ const EGLenum clientType,
+ const Version &clientVersion,
+ EGLint profileMask,
+ bool debug,
+ bool bindGeneratesResourceCHROMIUM,
+ bool clientArraysEnabled,
+ bool robustResourceInit,
+ bool programBinaryCacheEnabled,
+ EGLenum contextPriority,
+ bool hasRobustAccess,
+ bool hasProtectedContent)
+ : mID({gIDCounter++}),
+ mClientType(clientType),
+ mProfileMask(profileMask),
+ mContextPriority(contextPriority),
+ mHasRobustAccess(hasRobustAccess),
+ mHasProtectedContent(hasProtectedContent),
+ mIsDebugContext(debug),
+ mClientVersion(clientVersion),
+ mShareGroup(shareGroup),
+ mBufferManager(AllocateOrGetSharedResourceManager(shareContextState, &State::mBufferManager)),
+ mShaderProgramManager(
+ AllocateOrGetSharedResourceManager(shareContextState, &State::mShaderProgramManager)),
+ mTextureManager(AllocateOrGetSharedResourceManager(shareContextState,
+ &State::mTextureManager,
+ shareTextures)),
+ mRenderbufferManager(
+ AllocateOrGetSharedResourceManager(shareContextState, &State::mRenderbufferManager)),
+ mSamplerManager(
+ AllocateOrGetSharedResourceManager(shareContextState, &State::mSamplerManager)),
+ mSyncManager(AllocateOrGetSharedResourceManager(shareContextState, &State::mSyncManager)),
+ mFramebufferManager(new FramebufferManager()),
+ mProgramPipelineManager(new ProgramPipelineManager()),
+ mMemoryObjectManager(
+ AllocateOrGetSharedResourceManager(shareContextState, &State::mMemoryObjectManager)),
+ mSemaphoreManager(AllocateOrGetSharedResourceManager(shareContextState,
+ &State::mSemaphoreManager,
+ shareSemaphores)),
+ mDepthClearValue(0),
+ mStencilClearValue(0),
+ mScissorTest(false),
+ mSampleAlphaToCoverage(false),
+ mSampleCoverage(false),
+ mSampleCoverageValue(0),
+ mSampleCoverageInvert(false),
+ mSampleMask(false),
+ mMaxSampleMaskWords(0),
+ mIsSampleShadingEnabled(false),
+ mMinSampleShading(0.0f),
+ mStencilRef(0),
+ mStencilBackRef(0),
+ mLineWidth(0),
+ mGenerateMipmapHint(GL_NONE),
+ mTextureFilteringHint(GL_NONE),
+ mFragmentShaderDerivativeHint(GL_NONE),
+ mBindGeneratesResource(bindGeneratesResourceCHROMIUM),
+ mClientArraysEnabled(clientArraysEnabled),
+ mNearZ(0),
+ mFarZ(0),
+ mReadFramebuffer(nullptr),
+ mDrawFramebuffer(nullptr),
+ mProgram(nullptr),
+ mExecutable(nullptr),
+ mProvokingVertex(gl::ProvokingVertexConvention::LastVertexConvention),
+ mVertexArray(nullptr),
+ mActiveSampler(0),
+ mPrimitiveRestart(false),
+ mDebug(debug),
+ mMultiSampling(false),
+ mSampleAlphaToOne(false),
+ mFramebufferSRGB(true),
+ mRobustResourceInit(robustResourceInit),
+ mProgramBinaryCacheEnabled(programBinaryCacheEnabled),
+ mTextureRectangleEnabled(true),
+ mLogicOpEnabled(false),
+ mLogicOp(LogicalOperation::Copy),
+ mMaxShaderCompilerThreads(std::numeric_limits<GLuint>::max()),
+ mPatchVertices(3),
+ mPixelLocalStorageActive(false),
+ mOverlay(overlay),
+ mNoSimultaneousConstantColorAndAlphaBlendFunc(false),
+ mSetBlendIndexedInvoked(false),
+ mSetBlendFactorsIndexedInvoked(false),
+ mSetBlendEquationsIndexedInvoked(false),
+ mDisplayTextureShareGroup(shareTextures != nullptr),
+ mBoundingBoxMinX(-1.0f),
+ mBoundingBoxMinY(-1.0f),
+ mBoundingBoxMinZ(-1.0f),
+ mBoundingBoxMinW(1.0f),
+ mBoundingBoxMaxX(1.0f),
+ mBoundingBoxMaxY(1.0f),
+ mBoundingBoxMaxZ(1.0f),
+ mBoundingBoxMaxW(1.0f),
+ mShadingRatePreserveAspectRatio(false),
+ mShadingRate(ShadingRate::Undefined)
+{}
+
+State::~State() {}
+
+void State::initialize(Context *context)
+{
+ const Extensions &nativeExtensions = context->getImplementation()->getNativeExtensions();
+ const Version &clientVersion = context->getClientVersion();
+
+ mBlendStateExt = BlendStateExt(mCaps.maxDrawBuffers);
+
+ setColorClearValue(0.0f, 0.0f, 0.0f, 0.0f);
+
+ mDepthClearValue = 1.0f;
+ mStencilClearValue = 0;
+
+ mScissorTest = false;
+ mScissor.x = 0;
+ mScissor.y = 0;
+ mScissor.width = 0;
+ mScissor.height = 0;
+
+ mBlendColor.red = 0;
+ mBlendColor.green = 0;
+ mBlendColor.blue = 0;
+ mBlendColor.alpha = 0;
+
+ mStencilRef = 0;
+ mStencilBackRef = 0;
+
+ mSampleCoverage = false;
+ mSampleCoverageValue = 1.0f;
+ mSampleCoverageInvert = false;
+
+ mMaxSampleMaskWords = static_cast<GLuint>(mCaps.maxSampleMaskWords);
+ mSampleMask = false;
+ mSampleMaskValues.fill(~GLbitfield(0));
+
+ mGenerateMipmapHint = GL_DONT_CARE;
+ mTextureFilteringHint = GL_DONT_CARE;
+ mFragmentShaderDerivativeHint = GL_DONT_CARE;
+
+ mLineWidth = 1.0f;
+
+ mViewport.x = 0;
+ mViewport.y = 0;
+ mViewport.width = 0;
+ mViewport.height = 0;
+ mNearZ = 0.0f;
+ mFarZ = 1.0f;
+
+ mClipControlOrigin = GL_LOWER_LEFT_EXT;
+ mClipControlDepth = GL_NEGATIVE_ONE_TO_ONE_EXT;
+
+ mActiveSampler = 0;
+
+ mVertexAttribCurrentValues.resize(mCaps.maxVertexAttributes);
+
+ // Set all indexes in state attributes type mask to float (default)
+ for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+ {
+ SetComponentTypeMask(ComponentType::Float, i, &mCurrentValuesTypeMask);
+ }
+
+ mUniformBuffers.resize(mCaps.maxUniformBufferBindings);
+
+ mSamplerTextures[TextureType::_2D].resize(mCaps.maxCombinedTextureImageUnits);
+ mSamplerTextures[TextureType::CubeMap].resize(mCaps.maxCombinedTextureImageUnits);
+ if (clientVersion >= Version(3, 0) || nativeExtensions.texture3DOES)
+ {
+ mSamplerTextures[TextureType::_3D].resize(mCaps.maxCombinedTextureImageUnits);
+ }
+ if (clientVersion >= Version(3, 0))
+ {
+ mSamplerTextures[TextureType::_2DArray].resize(mCaps.maxCombinedTextureImageUnits);
+ }
+ if (clientVersion >= Version(3, 1) || nativeExtensions.textureMultisampleANGLE)
+ {
+ mSamplerTextures[TextureType::_2DMultisample].resize(mCaps.maxCombinedTextureImageUnits);
+ }
+ if (clientVersion >= Version(3, 1))
+ {
+ mSamplerTextures[TextureType::_2DMultisampleArray].resize(
+ mCaps.maxCombinedTextureImageUnits);
+
+ mAtomicCounterBuffers.resize(mCaps.maxAtomicCounterBufferBindings);
+ mShaderStorageBuffers.resize(mCaps.maxShaderStorageBufferBindings);
+ }
+ if (clientVersion >= Version(3, 1) ||
+ (mExtensions.shaderPixelLocalStorageANGLE &&
+ ShPixelLocalStorageTypeUsesImages(
+ context->getImplementation()->getNativePixelLocalStorageType())))
+ {
+ mImageUnits.resize(mCaps.maxImageUnits);
+ }
+ if (clientVersion >= Version(3, 2) || mExtensions.textureCubeMapArrayAny())
+ {
+ mSamplerTextures[TextureType::CubeMapArray].resize(mCaps.maxCombinedTextureImageUnits);
+ }
+ if (clientVersion >= Version(3, 2) || mExtensions.textureBufferAny())
+ {
+ mSamplerTextures[TextureType::Buffer].resize(mCaps.maxCombinedTextureImageUnits);
+ }
+ if (nativeExtensions.textureRectangleANGLE)
+ {
+ mSamplerTextures[TextureType::Rectangle].resize(mCaps.maxCombinedTextureImageUnits);
+ }
+ if (nativeExtensions.EGLImageExternalOES || nativeExtensions.EGLStreamConsumerExternalNV)
+ {
+ mSamplerTextures[TextureType::External].resize(mCaps.maxCombinedTextureImageUnits);
+ }
+ if (nativeExtensions.videoTextureWEBGL)
+ {
+ mSamplerTextures[TextureType::VideoImage].resize(mCaps.maxCombinedTextureImageUnits);
+ }
+ mCompleteTextureBindings.reserve(mCaps.maxCombinedTextureImageUnits);
+ for (int32_t textureIndex = 0; textureIndex < mCaps.maxCombinedTextureImageUnits;
+ ++textureIndex)
+ {
+ mCompleteTextureBindings.emplace_back(context, textureIndex);
+ }
+
+ mSamplers.resize(mCaps.maxCombinedTextureImageUnits);
+
+ for (QueryType type : angle::AllEnums<QueryType>())
+ {
+ mActiveQueries[type].set(context, nullptr);
+ }
+
+ mProgram = nullptr;
+ mExecutable = nullptr;
+
+ mReadFramebuffer = nullptr;
+ mDrawFramebuffer = nullptr;
+
+ mPrimitiveRestart = false;
+
+ mDebug.setMaxLoggedMessages(mCaps.maxDebugLoggedMessages);
+
+ mMultiSampling = true;
+ mSampleAlphaToOne = false;
+
+ mCoverageModulation = GL_NONE;
+
+ mNoSimultaneousConstantColorAndAlphaBlendFunc =
+ context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
+ context->getExtensions().webglCompatibilityANGLE;
+
+ mNoUnclampedBlendColor = context->getLimitations().noUnclampedBlendColor;
+
+ // GLES1 emulation: Initialize state for GLES1 if version applies
+ // TODO(http://anglebug.com/3745): When on desktop client only do this in compatibility profile
+ if (clientVersion < Version(2, 0) || mClientType == EGL_OPENGL_API)
+ {
+ mGLES1State.initialize(context, this);
+ }
+}
+
+void State::reset(const Context *context)
+{
+ // Force a sync so clear doesn't end up dereferencing stale pointers.
+ (void)syncActiveTextures(context, Command::Other);
+ mActiveTexturesCache.clear();
+
+ for (TextureBindingVector &bindingVec : mSamplerTextures)
+ {
+ for (BindingPointer<Texture> &texBinding : bindingVec)
+ {
+ texBinding.set(context, nullptr);
+ }
+ }
+ for (size_t samplerIdx = 0; samplerIdx < mSamplers.size(); samplerIdx++)
+ {
+ mSamplers[samplerIdx].set(context, nullptr);
+ }
+
+ for (ImageUnit &imageUnit : mImageUnits)
+ {
+ imageUnit.texture.set(context, nullptr);
+ imageUnit.level = 0;
+ imageUnit.layered = false;
+ imageUnit.layer = 0;
+ imageUnit.access = GL_READ_ONLY;
+ imageUnit.format = GL_R32UI;
+ }
+
+ mRenderbuffer.set(context, nullptr);
+
+ for (BufferBinding type : angle::AllEnums<BufferBinding>())
+ {
+ UpdateBufferBinding(context, &mBoundBuffers[type], nullptr, type);
+ }
+
+ if (mProgram)
+ {
+ mProgram->release(context);
+ }
+ mProgram = nullptr;
+ mProgramPipeline.set(context, nullptr);
+ mExecutable = nullptr;
+
+ if (mTransformFeedback.get())
+ {
+ mTransformFeedback->onBindingChanged(context, false);
+ }
+ mTransformFeedback.set(context, nullptr);
+
+ for (QueryType type : angle::AllEnums<QueryType>())
+ {
+ mActiveQueries[type].set(context, nullptr);
+ }
+
+ for (OffsetBindingPointer<Buffer> &buf : mUniformBuffers)
+ {
+ UpdateIndexedBufferBinding(context, &buf, nullptr, BufferBinding::Uniform, 0, 0);
+ }
+ mBoundUniformBuffersMask.reset();
+
+ for (OffsetBindingPointer<Buffer> &buf : mAtomicCounterBuffers)
+ {
+ UpdateIndexedBufferBinding(context, &buf, nullptr, BufferBinding::AtomicCounter, 0, 0);
+ }
+ mBoundAtomicCounterBuffersMask.reset();
+
+ for (OffsetBindingPointer<Buffer> &buf : mShaderStorageBuffers)
+ {
+ UpdateIndexedBufferBinding(context, &buf, nullptr, BufferBinding::ShaderStorage, 0, 0);
+ }
+ mBoundShaderStorageBuffersMask.reset();
+
+ mClipDistancesEnabled.reset();
+
+ setAllDirtyBits();
+}
+
+ANGLE_INLINE void State::unsetActiveTextures(const ActiveTextureMask &textureMask)
+{
+ // Unset any relevant bound textures.
+ for (size_t textureIndex : textureMask)
+ {
+ mActiveTexturesCache.reset(textureIndex);
+ mCompleteTextureBindings[textureIndex].reset();
+ }
+}
+
+ANGLE_INLINE void State::updateActiveTextureStateOnSync(const Context *context,
+ size_t textureIndex,
+ const Sampler *sampler,
+ Texture *texture)
+{
+ if (!texture || !texture->isSamplerComplete(context, sampler))
+ {
+ mActiveTexturesCache.reset(textureIndex);
+ }
+ else
+ {
+ mActiveTexturesCache.set(textureIndex, texture);
+ }
+
+ mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS);
+}
+
+ANGLE_INLINE void State::setActiveTextureDirty(size_t textureIndex, Texture *texture)
+{
+ mDirtyObjects.set(DIRTY_OBJECT_ACTIVE_TEXTURES);
+ mDirtyActiveTextures.set(textureIndex);
+
+ if (!texture)
+ {
+ return;
+ }
+
+ if (texture->hasAnyDirtyBit())
+ {
+ setTextureDirty(textureIndex);
+ }
+
+ if (mRobustResourceInit && texture->initState() == InitState::MayNeedInit)
+ {
+ mDirtyObjects.set(DIRTY_OBJECT_TEXTURES_INIT);
+ }
+
+ // This cache is updated immediately because we use the cache in the validation layer.
+ // If we defer the update until syncState it's too late and we've already passed validation.
+ if (texture && mExecutable)
+ {
+ // It is invalid to try to sample a non-yuv texture with a yuv sampler.
+ mTexturesIncompatibleWithSamplers[textureIndex] =
+ mExecutable->getActiveYUVSamplers().test(textureIndex) && !texture->isYUV();
+
+ if (isWebGL())
+ {
+ const Sampler *sampler = mSamplers[textureIndex].get();
+ const SamplerState &samplerState =
+ sampler ? sampler->getSamplerState() : texture->getSamplerState();
+ if (!texture->getTextureState().compatibleWithSamplerFormatForWebGL(
+ mExecutable->getSamplerFormatForTextureUnitIndex(textureIndex), samplerState))
+ {
+ mTexturesIncompatibleWithSamplers[textureIndex] = true;
+ }
+ }
+ }
+ else
+ {
+ mTexturesIncompatibleWithSamplers[textureIndex] = false;
+ }
+}
+
+ANGLE_INLINE void State::updateTextureBinding(const Context *context,
+ size_t textureIndex,
+ Texture *texture)
+{
+ mCompleteTextureBindings[textureIndex].bind(texture);
+ mActiveTexturesCache.reset(textureIndex);
+ setActiveTextureDirty(textureIndex, texture);
+}
+
+ANGLE_INLINE bool State::hasConstantColor(GLenum sourceRGB, GLenum destRGB) const
+{
+ return sourceRGB == GL_CONSTANT_COLOR || sourceRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
+ destRGB == GL_CONSTANT_COLOR || destRGB == GL_ONE_MINUS_CONSTANT_COLOR;
+}
+
+ANGLE_INLINE bool State::hasConstantAlpha(GLenum sourceRGB, GLenum destRGB) const
+{
+ return sourceRGB == GL_CONSTANT_ALPHA || sourceRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
+ destRGB == GL_CONSTANT_ALPHA || destRGB == GL_ONE_MINUS_CONSTANT_ALPHA;
+}
+
+const RasterizerState &State::getRasterizerState() const
+{
+ return mRasterizer;
+}
+
+const DepthStencilState &State::getDepthStencilState() const
+{
+ return mDepthStencil;
+}
+
+void State::setColorClearValue(float red, float green, float blue, float alpha)
+{
+ mColorClearValue.red = red;
+ mColorClearValue.green = green;
+ mColorClearValue.blue = blue;
+ mColorClearValue.alpha = alpha;
+ mDirtyBits.set(DIRTY_BIT_CLEAR_COLOR);
+}
+
+void State::setDepthClearValue(float depth)
+{
+ mDepthClearValue = depth;
+ mDirtyBits.set(DIRTY_BIT_CLEAR_DEPTH);
+}
+
+void State::setStencilClearValue(int stencil)
+{
+ mStencilClearValue = stencil;
+ mDirtyBits.set(DIRTY_BIT_CLEAR_STENCIL);
+}
+
+void State::setColorMask(bool red, bool green, bool blue, bool alpha)
+{
+ mBlendState.colorMaskRed = red;
+ mBlendState.colorMaskGreen = green;
+ mBlendState.colorMaskBlue = blue;
+ mBlendState.colorMaskAlpha = alpha;
+
+ mBlendStateExt.setColorMask(red, green, blue, alpha);
+ mDirtyBits.set(DIRTY_BIT_COLOR_MASK);
+}
+
+void State::setColorMaskIndexed(bool red, bool green, bool blue, bool alpha, GLuint index)
+{
+ mBlendStateExt.setColorMaskIndexed(index, red, green, blue, alpha);
+ mDirtyBits.set(DIRTY_BIT_COLOR_MASK);
+}
+
+bool State::allActiveDrawBufferChannelsMasked() const
+{
+ // Compare current color mask with all-disabled color mask, while ignoring disabled draw
+ // buffers.
+ return (mBlendStateExt.compareColorMask(0) & mDrawFramebuffer->getDrawBufferMask()).none();
+}
+
+bool State::anyActiveDrawBufferChannelMasked() const
+{
+ // Compare current color mask with all-enabled color mask, while ignoring disabled draw
+ // buffers.
+ return (mBlendStateExt.compareColorMask(mBlendStateExt.getAllColorMaskBits()) &
+ mDrawFramebuffer->getDrawBufferMask())
+ .any();
+}
+
+void State::setDepthMask(bool mask)
+{
+ if (mDepthStencil.depthMask != mask)
+ {
+ mDepthStencil.depthMask = mask;
+ mDirtyBits.set(DIRTY_BIT_DEPTH_MASK);
+ }
+}
+
+void State::setRasterizerDiscard(bool enabled)
+{
+ if (mRasterizer.rasterizerDiscard != enabled)
+ {
+ mRasterizer.rasterizerDiscard = enabled;
+ mDirtyBits.set(DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
+ }
+}
+
+void State::setCullFace(bool enabled)
+{
+ if (mRasterizer.cullFace != enabled)
+ {
+ mRasterizer.cullFace = enabled;
+ mDirtyBits.set(DIRTY_BIT_CULL_FACE_ENABLED);
+ }
+}
+
+void State::setCullMode(CullFaceMode mode)
+{
+ if (mRasterizer.cullMode != mode)
+ {
+ mRasterizer.cullMode = mode;
+ mDirtyBits.set(DIRTY_BIT_CULL_FACE);
+ }
+}
+
+void State::setFrontFace(GLenum front)
+{
+ if (mRasterizer.frontFace != front)
+ {
+ mRasterizer.frontFace = front;
+ mDirtyBits.set(DIRTY_BIT_FRONT_FACE);
+ }
+}
+
+void State::setDepthTest(bool enabled)
+{
+ if (mDepthStencil.depthTest != enabled)
+ {
+ mDepthStencil.depthTest = enabled;
+ mDirtyBits.set(DIRTY_BIT_DEPTH_TEST_ENABLED);
+ }
+}
+
+void State::setDepthFunc(GLenum depthFunc)
+{
+ if (mDepthStencil.depthFunc != depthFunc)
+ {
+ mDepthStencil.depthFunc = depthFunc;
+ mDirtyBits.set(DIRTY_BIT_DEPTH_FUNC);
+ }
+}
+
+void State::setDepthRange(float zNear, float zFar)
+{
+ if (mNearZ != zNear || mFarZ != zFar)
+ {
+ mNearZ = zNear;
+ mFarZ = zFar;
+ mDirtyBits.set(DIRTY_BIT_DEPTH_RANGE);
+ }
+}
+
+void State::setClipControl(GLenum origin, GLenum depth)
+{
+ bool updated = false;
+ if (mClipControlOrigin != origin)
+ {
+ mClipControlOrigin = origin;
+ updated = true;
+ }
+
+ if (mClipControlDepth != depth)
+ {
+ mClipControlDepth = depth;
+ updated = true;
+ }
+
+ if (updated)
+ {
+ mDirtyBits.set(DIRTY_BIT_EXTENDED);
+ mExtendedDirtyBits.set(EXTENDED_DIRTY_BIT_CLIP_CONTROL);
+ }
+}
+
+void State::setBlend(bool enabled)
+{
+ if (mSetBlendIndexedInvoked || mBlendState.blend != enabled)
+ {
+ mBlendState.blend = enabled;
+
+ mSetBlendIndexedInvoked = false;
+ mBlendStateExt.setEnabled(enabled);
+ mDirtyBits.set(DIRTY_BIT_BLEND_ENABLED);
+ }
+}
+
+void State::setBlendIndexed(bool enabled, GLuint index)
+{
+ mSetBlendIndexedInvoked = true;
+ mBlendStateExt.setEnabledIndexed(index, enabled);
+ mDirtyBits.set(DIRTY_BIT_BLEND_ENABLED);
+}
+
+void State::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
+{
+ if (!mSetBlendFactorsIndexedInvoked && mBlendState.sourceBlendRGB == sourceRGB &&
+ mBlendState.destBlendRGB == destRGB && mBlendState.sourceBlendAlpha == sourceAlpha &&
+ mBlendState.destBlendAlpha == destAlpha)
+ {
+ return;
+ }
+
+ mBlendState.sourceBlendRGB = sourceRGB;
+ mBlendState.destBlendRGB = destRGB;
+ mBlendState.sourceBlendAlpha = sourceAlpha;
+ mBlendState.destBlendAlpha = destAlpha;
+
+ if (mNoSimultaneousConstantColorAndAlphaBlendFunc)
+ {
+ if (hasConstantColor(sourceRGB, destRGB))
+ {
+ mBlendFuncConstantColorDrawBuffers.set();
+ }
+ else
+ {
+ mBlendFuncConstantColorDrawBuffers.reset();
+ }
+
+ if (hasConstantAlpha(sourceRGB, destRGB))
+ {
+ mBlendFuncConstantAlphaDrawBuffers.set();
+ }
+ else
+ {
+ mBlendFuncConstantAlphaDrawBuffers.reset();
+ }
+ }
+
+ mSetBlendFactorsIndexedInvoked = false;
+ mBlendStateExt.setFactors(sourceRGB, destRGB, sourceAlpha, destAlpha);
+ mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS);
+}
+
+void State::setBlendFactorsIndexed(GLenum sourceRGB,
+ GLenum destRGB,
+ GLenum sourceAlpha,
+ GLenum destAlpha,
+ GLuint index)
+{
+ if (mNoSimultaneousConstantColorAndAlphaBlendFunc)
+ {
+ mBlendFuncConstantColorDrawBuffers.set(index, hasConstantColor(sourceRGB, destRGB));
+ mBlendFuncConstantAlphaDrawBuffers.set(index, hasConstantAlpha(sourceRGB, destRGB));
+ }
+
+ mSetBlendFactorsIndexedInvoked = true;
+ mBlendStateExt.setFactorsIndexed(index, sourceRGB, destRGB, sourceAlpha, destAlpha);
+ mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS);
+}
+
+void State::setBlendColor(float red, float green, float blue, float alpha)
+{
+ // In ES2 without render-to-float extensions, BlendColor clamps to [0,1] on store.
+ // On ES3+, or with render-to-float exts enabled, it does not clamp on store.
+ const bool isES2 = mClientVersion.major == 2;
+ const bool hasFloatBlending =
+ mExtensions.colorBufferFloatEXT || mExtensions.colorBufferHalfFloatEXT ||
+ mExtensions.colorBufferFloatRgbCHROMIUM || mExtensions.colorBufferFloatRgbaCHROMIUM;
+ if ((isES2 && !hasFloatBlending) || mNoUnclampedBlendColor)
+ {
+ red = clamp01(red);
+ green = clamp01(green);
+ blue = clamp01(blue);
+ alpha = clamp01(alpha);
+ }
+
+ if (mBlendColor.red != red || mBlendColor.green != green || mBlendColor.blue != blue ||
+ mBlendColor.alpha != alpha)
+ {
+ mBlendColor.red = red;
+ mBlendColor.green = green;
+ mBlendColor.blue = blue;
+ mBlendColor.alpha = alpha;
+ mDirtyBits.set(DIRTY_BIT_BLEND_COLOR);
+ }
+}
+
+void State::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
+{
+ if (mSetBlendEquationsIndexedInvoked || mBlendState.blendEquationRGB != rgbEquation ||
+ mBlendState.blendEquationAlpha != alphaEquation)
+ {
+ mBlendState.blendEquationRGB = rgbEquation;
+ mBlendState.blendEquationAlpha = alphaEquation;
+
+ mSetBlendEquationsIndexedInvoked = false;
+ mBlendStateExt.setEquations(rgbEquation, alphaEquation);
+ mDirtyBits.set(DIRTY_BIT_BLEND_EQUATIONS);
+ }
+}
+
+void State::setBlendEquationIndexed(GLenum rgbEquation, GLenum alphaEquation, GLuint index)
+{
+ mSetBlendEquationsIndexedInvoked = true;
+ mBlendStateExt.setEquationsIndexed(index, rgbEquation, alphaEquation);
+ mDirtyBits.set(DIRTY_BIT_BLEND_EQUATIONS);
+}
+
+void State::setStencilTest(bool enabled)
+{
+ if (mDepthStencil.stencilTest != enabled)
+ {
+ mDepthStencil.stencilTest = enabled;
+ mDirtyBits.set(DIRTY_BIT_STENCIL_TEST_ENABLED);
+ }
+}
+
+void State::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
+{
+ if (mDepthStencil.stencilFunc != stencilFunc || mStencilRef != stencilRef ||
+ mDepthStencil.stencilMask != stencilMask)
+ {
+ mDepthStencil.stencilFunc = stencilFunc;
+ mStencilRef = stencilRef;
+ mDepthStencil.stencilMask = stencilMask;
+ mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_FRONT);
+ }
+}
+
+void State::setStencilBackParams(GLenum stencilBackFunc,
+ GLint stencilBackRef,
+ GLuint stencilBackMask)
+{
+ if (mDepthStencil.stencilBackFunc != stencilBackFunc || mStencilBackRef != stencilBackRef ||
+ mDepthStencil.stencilBackMask != stencilBackMask)
+ {
+ mDepthStencil.stencilBackFunc = stencilBackFunc;
+ mStencilBackRef = stencilBackRef;
+ mDepthStencil.stencilBackMask = stencilBackMask;
+ mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_BACK);
+ }
+}
+
+void State::setStencilWritemask(GLuint stencilWritemask)
+{
+ if (mDepthStencil.stencilWritemask != stencilWritemask)
+ {
+ mDepthStencil.stencilWritemask = stencilWritemask;
+ mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
+ }
+}
+
+void State::setStencilBackWritemask(GLuint stencilBackWritemask)
+{
+ if (mDepthStencil.stencilBackWritemask != stencilBackWritemask)
+ {
+ mDepthStencil.stencilBackWritemask = stencilBackWritemask;
+ mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK);
+ }
+}
+
+void State::setStencilOperations(GLenum stencilFail,
+ GLenum stencilPassDepthFail,
+ GLenum stencilPassDepthPass)
+{
+ if (mDepthStencil.stencilFail != stencilFail ||
+ mDepthStencil.stencilPassDepthFail != stencilPassDepthFail ||
+ mDepthStencil.stencilPassDepthPass != stencilPassDepthPass)
+ {
+ mDepthStencil.stencilFail = stencilFail;
+ mDepthStencil.stencilPassDepthFail = stencilPassDepthFail;
+ mDepthStencil.stencilPassDepthPass = stencilPassDepthPass;
+ mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_FRONT);
+ }
+}
+
+void State::setStencilBackOperations(GLenum stencilBackFail,
+ GLenum stencilBackPassDepthFail,
+ GLenum stencilBackPassDepthPass)
+{
+ if (mDepthStencil.stencilBackFail != stencilBackFail ||
+ mDepthStencil.stencilBackPassDepthFail != stencilBackPassDepthFail ||
+ mDepthStencil.stencilBackPassDepthPass != stencilBackPassDepthPass)
+ {
+ mDepthStencil.stencilBackFail = stencilBackFail;
+ mDepthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
+ mDepthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
+ mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_BACK);
+ }
+}
+
+void State::setPolygonOffsetFill(bool enabled)
+{
+ if (mRasterizer.polygonOffsetFill != enabled)
+ {
+ mRasterizer.polygonOffsetFill = enabled;
+ mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED);
+ }
+}
+
+void State::setPolygonOffsetParams(GLfloat factor, GLfloat units)
+{
+ // An application can pass NaN values here, so handle this gracefully
+ mRasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
+ mRasterizer.polygonOffsetUnits = units != units ? 0.0f : units;
+ mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET);
+}
+
+void State::setSampleAlphaToCoverage(bool enabled)
+{
+ if (mSampleAlphaToCoverage != enabled)
+ {
+ mSampleAlphaToCoverage = enabled;
+ mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED);
+ }
+}
+
+void State::setSampleCoverage(bool enabled)
+{
+ if (mSampleCoverage != enabled)
+ {
+ mSampleCoverage = enabled;
+ mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE_ENABLED);
+ }
+}
+
+void State::setSampleCoverageParams(GLclampf value, bool invert)
+{
+ mSampleCoverageValue = value;
+ mSampleCoverageInvert = invert;
+ mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE);
+}
+
+void State::setSampleMaskEnabled(bool enabled)
+{
+ if (mSampleMask != enabled)
+ {
+ mSampleMask = enabled;
+ mDirtyBits.set(DIRTY_BIT_SAMPLE_MASK_ENABLED);
+ }
+}
+
+void State::setSampleMaskParams(GLuint maskNumber, GLbitfield mask)
+{
+ ASSERT(maskNumber < mMaxSampleMaskWords);
+ mSampleMaskValues[maskNumber] = mask;
+ // TODO(jmadill): Use a child dirty bit if we ever use more than two words.
+ mDirtyBits.set(DIRTY_BIT_SAMPLE_MASK);
+}
+
+void State::setSampleAlphaToOne(bool enabled)
+{
+ if (mSampleAlphaToOne != enabled)
+ {
+ mSampleAlphaToOne = enabled;
+ mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_ONE);
+ }
+}
+
+void State::setMultisampling(bool enabled)
+{
+ if (mMultiSampling != enabled)
+ {
+ mMultiSampling = enabled;
+ mDirtyBits.set(DIRTY_BIT_MULTISAMPLING);
+ }
+}
+
+void State::setSampleShading(bool enabled)
+{
+ if (mIsSampleShadingEnabled != enabled)
+ {
+ mIsSampleShadingEnabled = enabled;
+ mMinSampleShading = (enabled) ? 1.0f : mMinSampleShading;
+ mDirtyBits.set(DIRTY_BIT_SAMPLE_SHADING);
+ }
+}
+
+void State::setMinSampleShading(float value)
+{
+ value = gl::clamp01(value);
+
+ if (mMinSampleShading != value)
+ {
+ mMinSampleShading = value;
+ mDirtyBits.set(DIRTY_BIT_SAMPLE_SHADING);
+ }
+}
+
+void State::setScissorTest(bool enabled)
+{
+ if (mScissorTest != enabled)
+ {
+ mScissorTest = enabled;
+ mDirtyBits.set(DIRTY_BIT_SCISSOR_TEST_ENABLED);
+ }
+}
+
+void State::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ // Skip if same scissor info
+ if (mScissor.x != x || mScissor.y != y || mScissor.width != width || mScissor.height != height)
+ {
+ mScissor.x = x;
+ mScissor.y = y;
+ mScissor.width = width;
+ mScissor.height = height;
+ mDirtyBits.set(DIRTY_BIT_SCISSOR);
+ }
+}
+
+void State::setDither(bool enabled)
+{
+ if (mRasterizer.dither != enabled)
+ {
+ mRasterizer.dither = enabled;
+ mDirtyBits.set(DIRTY_BIT_DITHER_ENABLED);
+ }
+}
+
+void State::setPrimitiveRestart(bool enabled)
+{
+ if (mPrimitiveRestart != enabled)
+ {
+ mPrimitiveRestart = enabled;
+ mDirtyBits.set(DIRTY_BIT_PRIMITIVE_RESTART_ENABLED);
+ }
+}
+
+void State::setClipDistanceEnable(int idx, bool enable)
+{
+ if (enable)
+ {
+ mClipDistancesEnabled.set(idx);
+ }
+ else
+ {
+ mClipDistancesEnabled.reset(idx);
+ }
+
+ mDirtyBits.set(DIRTY_BIT_EXTENDED);
+ mExtendedDirtyBits.set(EXTENDED_DIRTY_BIT_CLIP_DISTANCES);
+}
+
+void State::setEnableFeature(GLenum feature, bool enabled)
+{
+ switch (feature)
+ {
+ case GL_MULTISAMPLE_EXT:
+ setMultisampling(enabled);
+ return;
+ case GL_SAMPLE_ALPHA_TO_ONE_EXT:
+ setSampleAlphaToOne(enabled);
+ return;
+ case GL_CULL_FACE:
+ setCullFace(enabled);
+ return;
+ case GL_POLYGON_OFFSET_FILL:
+ setPolygonOffsetFill(enabled);
+ return;
+ case GL_SAMPLE_ALPHA_TO_COVERAGE:
+ setSampleAlphaToCoverage(enabled);
+ return;
+ case GL_SAMPLE_COVERAGE:
+ setSampleCoverage(enabled);
+ return;
+ case GL_SCISSOR_TEST:
+ setScissorTest(enabled);
+ return;
+ case GL_STENCIL_TEST:
+ setStencilTest(enabled);
+ return;
+ case GL_DEPTH_TEST:
+ setDepthTest(enabled);
+ return;
+ case GL_BLEND:
+ setBlend(enabled);
+ return;
+ case GL_DITHER:
+ setDither(enabled);
+ return;
+ case GL_COLOR_LOGIC_OP:
+ if (mClientVersion.major == 1)
+ {
+ // Handle logicOp in GLES1 through the GLES1 state management and emulation.
+ // Otherwise this state could be set as part of ANGLE_logic_op.
+ break;
+ }
+ setLogicOpEnabled(enabled);
+ return;
+ case GL_PRIMITIVE_RESTART_FIXED_INDEX:
+ setPrimitiveRestart(enabled);
+ return;
+ case GL_RASTERIZER_DISCARD:
+ setRasterizerDiscard(enabled);
+ return;
+ case GL_SAMPLE_MASK:
+ setSampleMaskEnabled(enabled);
+ return;
+ case GL_DEBUG_OUTPUT_SYNCHRONOUS:
+ mDebug.setOutputSynchronous(enabled);
+ return;
+ case GL_DEBUG_OUTPUT:
+ mDebug.setOutputEnabled(enabled);
+ return;
+ case GL_FRAMEBUFFER_SRGB_EXT:
+ setFramebufferSRGB(enabled);
+ return;
+ case GL_TEXTURE_RECTANGLE_ANGLE:
+ mTextureRectangleEnabled = enabled;
+ return;
+ case GL_SAMPLE_SHADING:
+ setSampleShading(enabled);
+ return;
+ // GL_APPLE_clip_distance/GL_EXT_clip_cull_distance
+ case GL_CLIP_DISTANCE0_EXT:
+ case GL_CLIP_DISTANCE1_EXT:
+ case GL_CLIP_DISTANCE2_EXT:
+ case GL_CLIP_DISTANCE3_EXT:
+ case GL_CLIP_DISTANCE4_EXT:
+ case GL_CLIP_DISTANCE5_EXT:
+ case GL_CLIP_DISTANCE6_EXT:
+ case GL_CLIP_DISTANCE7_EXT:
+ // NOTE(hqle): These enums are conflicted with GLES1's enums, need
+ // to do additional check here:
+ if (mClientVersion.major >= 2)
+ {
+ setClipDistanceEnable(feature - GL_CLIP_DISTANCE0_EXT, enabled);
+ return;
+ }
+ break;
+ case GL_SHADING_RATE_PRESERVE_ASPECT_RATIO_QCOM:
+ mShadingRatePreserveAspectRatio = enabled;
+ return;
+ }
+
+ ASSERT(mClientVersion.major == 1);
+
+ // GLES1 emulation. Need to separate from main switch due to conflict enum between
+ // GL_CLIP_DISTANCE0_EXT & GL_CLIP_PLANE0
+ switch (feature)
+ {
+ case GL_ALPHA_TEST:
+ mGLES1State.mAlphaTestEnabled = enabled;
+ break;
+ case GL_TEXTURE_2D:
+ mGLES1State.mTexUnitEnables[mActiveSampler].set(TextureType::_2D, enabled);
+ break;
+ case GL_TEXTURE_CUBE_MAP:
+ mGLES1State.mTexUnitEnables[mActiveSampler].set(TextureType::CubeMap, enabled);
+ break;
+ case GL_LIGHTING:
+ mGLES1State.mLightingEnabled = enabled;
+ break;
+ case GL_LIGHT0:
+ case GL_LIGHT1:
+ case GL_LIGHT2:
+ case GL_LIGHT3:
+ case GL_LIGHT4:
+ case GL_LIGHT5:
+ case GL_LIGHT6:
+ case GL_LIGHT7:
+ mGLES1State.mLights[feature - GL_LIGHT0].enabled = enabled;
+ break;
+ case GL_NORMALIZE:
+ mGLES1State.mNormalizeEnabled = enabled;
+ break;
+ case GL_RESCALE_NORMAL:
+ mGLES1State.mRescaleNormalEnabled = enabled;
+ break;
+ case GL_COLOR_MATERIAL:
+ mGLES1State.mColorMaterialEnabled = enabled;
+ break;
+ case GL_CLIP_PLANE0:
+ case GL_CLIP_PLANE1:
+ case GL_CLIP_PLANE2:
+ case GL_CLIP_PLANE3:
+ case GL_CLIP_PLANE4:
+ case GL_CLIP_PLANE5:
+ mGLES1State.mClipPlanes[feature - GL_CLIP_PLANE0].enabled = enabled;
+ break;
+ case GL_FOG:
+ mGLES1State.mFogEnabled = enabled;
+ break;
+ case GL_POINT_SMOOTH:
+ mGLES1State.mPointSmoothEnabled = enabled;
+ break;
+ case GL_LINE_SMOOTH:
+ mGLES1State.mLineSmoothEnabled = enabled;
+ break;
+ case GL_POINT_SPRITE_OES:
+ mGLES1State.mPointSpriteEnabled = enabled;
+ break;
+ case GL_COLOR_LOGIC_OP:
+ mGLES1State.setLogicOpEnabled(enabled);
+ break;
+ default:
+ UNREACHABLE();
+ }
+}
+
+void State::setEnableFeatureIndexed(GLenum feature, bool enabled, GLuint index)
+{
+ switch (feature)
+ {
+ case GL_BLEND:
+ setBlendIndexed(enabled, index);
+ break;
+ default:
+ UNREACHABLE();
+ }
+}
+
+bool State::getEnableFeature(GLenum feature) const
+{
+ switch (feature)
+ {
+ case GL_MULTISAMPLE_EXT:
+ return isMultisamplingEnabled();
+ case GL_SAMPLE_ALPHA_TO_ONE_EXT:
+ return isSampleAlphaToOneEnabled();
+ case GL_CULL_FACE:
+ return isCullFaceEnabled();
+ case GL_POLYGON_OFFSET_FILL:
+ return isPolygonOffsetFillEnabled();
+ case GL_SAMPLE_ALPHA_TO_COVERAGE:
+ return isSampleAlphaToCoverageEnabled();
+ case GL_SAMPLE_COVERAGE:
+ return isSampleCoverageEnabled();
+ case GL_SCISSOR_TEST:
+ return isScissorTestEnabled();
+ case GL_STENCIL_TEST:
+ return isStencilTestEnabled();
+ case GL_DEPTH_TEST:
+ return isDepthTestEnabled();
+ case GL_BLEND:
+ return isBlendEnabled();
+ case GL_DITHER:
+ return isDitherEnabled();
+ case GL_COLOR_LOGIC_OP:
+ if (mClientVersion.major == 1)
+ {
+ // Handle logicOp in GLES1 through the GLES1 state management and emulation.
+ break;
+ }
+ return isLogicOpEnabled();
+ case GL_PRIMITIVE_RESTART_FIXED_INDEX:
+ return isPrimitiveRestartEnabled();
+ case GL_RASTERIZER_DISCARD:
+ return isRasterizerDiscardEnabled();
+ case GL_SAMPLE_MASK:
+ return isSampleMaskEnabled();
+ case GL_DEBUG_OUTPUT_SYNCHRONOUS:
+ return mDebug.isOutputSynchronous();
+ case GL_DEBUG_OUTPUT:
+ return mDebug.isOutputEnabled();
+ case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
+ return isBindGeneratesResourceEnabled();
+ case GL_CLIENT_ARRAYS_ANGLE:
+ return areClientArraysEnabled();
+ case GL_FRAMEBUFFER_SRGB_EXT:
+ return getFramebufferSRGB();
+ case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
+ return mRobustResourceInit;
+ case GL_PROGRAM_CACHE_ENABLED_ANGLE:
+ return mProgramBinaryCacheEnabled;
+ case GL_TEXTURE_RECTANGLE_ANGLE:
+ return mTextureRectangleEnabled;
+ case GL_SAMPLE_SHADING:
+ return isSampleShadingEnabled();
+ // GL_APPLE_clip_distance/GL_EXT_clip_cull_distance
+ case GL_CLIP_DISTANCE0_EXT:
+ case GL_CLIP_DISTANCE1_EXT:
+ case GL_CLIP_DISTANCE2_EXT:
+ case GL_CLIP_DISTANCE3_EXT:
+ case GL_CLIP_DISTANCE4_EXT:
+ case GL_CLIP_DISTANCE5_EXT:
+ case GL_CLIP_DISTANCE6_EXT:
+ case GL_CLIP_DISTANCE7_EXT:
+ if (mClientVersion.major >= 2)
+ {
+ // If GLES version is 1, the GL_CLIP_DISTANCE0_EXT enum will be used as
+ // GL_CLIP_PLANE0 instead.
+ return mClipDistancesEnabled.test(feature - GL_CLIP_DISTANCE0_EXT);
+ }
+ break;
+ case GL_SHADING_RATE_PRESERVE_ASPECT_RATIO_QCOM:
+ return mShadingRatePreserveAspectRatio;
+ }
+
+ ASSERT(mClientVersion.major == 1);
+
+ switch (feature)
+ {
+ // GLES1 emulation
+ case GL_ALPHA_TEST:
+ return mGLES1State.mAlphaTestEnabled;
+ case GL_VERTEX_ARRAY:
+ return mGLES1State.mVertexArrayEnabled;
+ case GL_NORMAL_ARRAY:
+ return mGLES1State.mNormalArrayEnabled;
+ case GL_COLOR_ARRAY:
+ return mGLES1State.mColorArrayEnabled;
+ case GL_POINT_SIZE_ARRAY_OES:
+ return mGLES1State.mPointSizeArrayEnabled;
+ case GL_TEXTURE_COORD_ARRAY:
+ return mGLES1State.mTexCoordArrayEnabled[mGLES1State.mClientActiveTexture];
+ case GL_TEXTURE_2D:
+ return mGLES1State.isTextureTargetEnabled(getActiveSampler(), TextureType::_2D);
+ case GL_TEXTURE_CUBE_MAP:
+ return mGLES1State.isTextureTargetEnabled(getActiveSampler(), TextureType::CubeMap);
+ case GL_LIGHTING:
+ return mGLES1State.mLightingEnabled;
+ case GL_LIGHT0:
+ case GL_LIGHT1:
+ case GL_LIGHT2:
+ case GL_LIGHT3:
+ case GL_LIGHT4:
+ case GL_LIGHT5:
+ case GL_LIGHT6:
+ case GL_LIGHT7:
+ return mGLES1State.mLights[feature - GL_LIGHT0].enabled;
+ case GL_NORMALIZE:
+ return mGLES1State.mNormalizeEnabled;
+ case GL_RESCALE_NORMAL:
+ return mGLES1State.mRescaleNormalEnabled;
+ case GL_COLOR_MATERIAL:
+ return mGLES1State.mColorMaterialEnabled;
+ case GL_CLIP_PLANE0:
+ case GL_CLIP_PLANE1:
+ case GL_CLIP_PLANE2:
+ case GL_CLIP_PLANE3:
+ case GL_CLIP_PLANE4:
+ case GL_CLIP_PLANE5:
+ return mGLES1State.mClipPlanes[feature - GL_CLIP_PLANE0].enabled;
+ case GL_FOG:
+ return mGLES1State.mFogEnabled;
+ case GL_POINT_SMOOTH:
+ return mGLES1State.mPointSmoothEnabled;
+ case GL_LINE_SMOOTH:
+ return mGLES1State.mLineSmoothEnabled;
+ case GL_POINT_SPRITE_OES:
+ return mGLES1State.mPointSpriteEnabled;
+ case GL_COLOR_LOGIC_OP:
+ return mGLES1State.mLogicOpEnabled;
+ default:
+ UNREACHABLE();
+ return false;
+ }
+}
+
+bool State::getEnableFeatureIndexed(GLenum feature, GLuint index) const
+{
+ switch (feature)
+ {
+ case GL_BLEND:
+ return isBlendEnabledIndexed(index);
+ default:
+ UNREACHABLE();
+ return false;
+ }
+}
+
+void State::setLineWidth(GLfloat width)
+{
+ mLineWidth = width;
+ mDirtyBits.set(DIRTY_BIT_LINE_WIDTH);
+}
+
+void State::setGenerateMipmapHint(GLenum hint)
+{
+ mGenerateMipmapHint = hint;
+ mDirtyBits.set(DIRTY_BIT_EXTENDED);
+ mExtendedDirtyBits.set(EXTENDED_DIRTY_BIT_MIPMAP_GENERATION_HINT);
+}
+
+GLenum State::getGenerateMipmapHint() const
+{
+ return mGenerateMipmapHint;
+}
+
+void State::setTextureFilteringHint(GLenum hint)
+{
+ mTextureFilteringHint = hint;
+ // Note: we don't add a dirty bit for this flag as it's not expected to be toggled at
+ // runtime.
+}
+
+GLenum State::getTextureFilteringHint() const
+{
+ return mTextureFilteringHint;
+}
+
+void State::setFragmentShaderDerivativeHint(GLenum hint)
+{
+ mFragmentShaderDerivativeHint = hint;
+ mDirtyBits.set(DIRTY_BIT_EXTENDED);
+ mExtendedDirtyBits.set(EXTENDED_DIRTY_BIT_SHADER_DERIVATIVE_HINT);
+ // TODO: Propagate the hint to shader translator so we can write
+ // ddx, ddx_coarse, or ddx_fine depending on the hint.
+ // Ignore for now. It is valid for implementations to ignore hint.
+}
+
+void State::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ // [OpenGL ES 2.0.25] section 2.12.1 page 45:
+ // Viewport width and height are clamped to implementation-dependent maximums when specified.
+ width = std::min(width, mCaps.maxViewportWidth);
+ height = std::min(height, mCaps.maxViewportHeight);
+
+ // Skip if same viewport info
+ if (mViewport.x != x || mViewport.y != y || mViewport.width != width ||
+ mViewport.height != height)
+ {
+ mViewport.x = x;
+ mViewport.y = y;
+ mViewport.width = width;
+ mViewport.height = height;
+ mDirtyBits.set(DIRTY_BIT_VIEWPORT);
+ }
+}
+
+void State::setActiveSampler(unsigned int active)
+{
+ mActiveSampler = active;
+}
+
+void State::setSamplerTexture(const Context *context, TextureType type, Texture *texture)
+{
+ if (mExecutable && mExecutable->getActiveSamplersMask()[mActiveSampler] &&
+ IsTextureCompatibleWithSampler(type, mExecutable->getActiveSamplerTypes()[mActiveSampler]))
+ {
+ updateTextureBinding(context, mActiveSampler, texture);
+ }
+
+ mSamplerTextures[type][mActiveSampler].set(context, texture);
+
+ mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS);
+}
+
+Texture *State::getTargetTexture(TextureType type) const
+{
+ return getSamplerTexture(static_cast<unsigned int>(mActiveSampler), type);
+}
+
+TextureID State::getSamplerTextureId(unsigned int sampler, TextureType type) const
+{
+ ASSERT(sampler < mSamplerTextures[type].size());
+ return mSamplerTextures[type][sampler].id();
+}
+
+void State::detachTexture(const Context *context, const TextureMap &zeroTextures, TextureID texture)
+{
+ // Textures have a detach method on State rather than a simple
+ // removeBinding, because the zero/null texture objects are managed
+ // separately, and don't have to go through the Context's maps or
+ // the ResourceManager.
+
+ // [OpenGL ES 2.0.24] section 3.8 page 84:
+ // If a texture object is deleted, it is as if all texture units which are bound to that texture
+ // object are rebound to texture object zero
+
+ for (TextureType type : angle::AllEnums<TextureType>())
+ {
+ TextureBindingVector &textureVector = mSamplerTextures[type];
+
+ for (size_t bindingIndex = 0; bindingIndex < textureVector.size(); ++bindingIndex)
+ {
+ BindingPointer<Texture> &binding = textureVector[bindingIndex];
+ if (binding.id() == texture)
+ {
+ // Zero textures are the "default" textures instead of NULL
+ Texture *zeroTexture = zeroTextures[type].get();
+ ASSERT(zeroTexture != nullptr);
+ if (mCompleteTextureBindings[bindingIndex].getSubject() == binding.get())
+ {
+ updateTextureBinding(context, bindingIndex, zeroTexture);
+ }
+ binding.set(context, zeroTexture);
+ }
+ }
+ }
+
+ for (auto &bindingImageUnit : mImageUnits)
+ {
+ if (bindingImageUnit.texture.id() == texture)
+ {
+ bindingImageUnit.texture.set(context, nullptr);
+ bindingImageUnit.level = 0;
+ bindingImageUnit.layered = false;
+ bindingImageUnit.layer = 0;
+ bindingImageUnit.access = GL_READ_ONLY;
+ bindingImageUnit.format = GL_R32UI;
+ }
+ }
+
+ // [OpenGL ES 2.0.24] section 4.4 page 112:
+ // If a texture object is deleted while its image is attached to the currently bound
+ // framebuffer, then it is as if Texture2DAttachment had been called, with a texture of 0, for
+ // each attachment point to which this image was attached in the currently bound framebuffer.
+
+ if (mReadFramebuffer && mReadFramebuffer->detachTexture(context, texture))
+ {
+ mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
+ }
+
+ if (mDrawFramebuffer && mDrawFramebuffer->detachTexture(context, texture))
+ {
+ setDrawFramebufferDirty();
+ }
+}
+
+void State::initializeZeroTextures(const Context *context, const TextureMap &zeroTextures)
+{
+ for (TextureType type : angle::AllEnums<TextureType>())
+ {
+ for (size_t textureUnit = 0; textureUnit < mSamplerTextures[type].size(); ++textureUnit)
+ {
+ mSamplerTextures[type][textureUnit].set(context, zeroTextures[type].get());
+ }
+ }
+}
+
+void State::invalidateTextureBindings(TextureType type)
+{
+ mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS);
+}
+
+void State::setSamplerBinding(const Context *context, GLuint textureUnit, Sampler *sampler)
+{
+ if (mSamplers[textureUnit].get() == sampler)
+ {
+ return;
+ }
+
+ mSamplers[textureUnit].set(context, sampler);
+ mDirtyBits.set(DIRTY_BIT_SAMPLER_BINDINGS);
+ // This is overly conservative as it assumes the sampler has never been bound.
+ setSamplerDirty(textureUnit);
+ onActiveTextureChange(context, textureUnit);
+}
+
+void State::detachSampler(const Context *context, SamplerID sampler)
+{
+ // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
+ // If a sampler object that is currently bound to one or more texture units is
+ // deleted, it is as though BindSampler is called once for each texture unit to
+ // which the sampler is bound, with unit set to the texture unit and sampler set to zero.
+ for (size_t i = 0; i < mSamplers.size(); i++)
+ {
+ if (mSamplers[i].id() == sampler)
+ {
+ setSamplerBinding(context, static_cast<GLuint>(i), nullptr);
+ }
+ }
+}
+
+void State::setRenderbufferBinding(const Context *context, Renderbuffer *renderbuffer)
+{
+ mRenderbuffer.set(context, renderbuffer);
+ mDirtyBits.set(DIRTY_BIT_RENDERBUFFER_BINDING);
+}
+
+void State::detachRenderbuffer(const Context *context, RenderbufferID renderbuffer)
+{
+ // [OpenGL ES 2.0.24] section 4.4 page 109:
+ // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though
+ // BindRenderbuffer had been executed with the target RENDERBUFFER and name of zero.
+
+ if (mRenderbuffer.id() == renderbuffer)
+ {
+ setRenderbufferBinding(context, nullptr);
+ }
+
+ // [OpenGL ES 2.0.24] section 4.4 page 111:
+ // If a renderbuffer object is deleted while its image is attached to the currently bound
+ // framebuffer, then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of
+ // 0, for each attachment point to which this image was attached in the currently bound
+ // framebuffer.
+
+ Framebuffer *readFramebuffer = mReadFramebuffer;
+ Framebuffer *drawFramebuffer = mDrawFramebuffer;
+
+ if (readFramebuffer && readFramebuffer->detachRenderbuffer(context, renderbuffer))
+ {
+ mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
+ }
+
+ if (drawFramebuffer && drawFramebuffer != readFramebuffer)
+ {
+ if (drawFramebuffer->detachRenderbuffer(context, renderbuffer))
+ {
+ setDrawFramebufferDirty();
+ }
+ }
+}
+
+void State::setReadFramebufferBinding(Framebuffer *framebuffer)
+{
+ if (mReadFramebuffer == framebuffer)
+ return;
+
+ mReadFramebuffer = framebuffer;
+ mDirtyBits.set(DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
+
+ if (mReadFramebuffer && mReadFramebuffer->hasAnyDirtyBit())
+ {
+ mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
+ }
+}
+
+void State::setDrawFramebufferBinding(Framebuffer *framebuffer)
+{
+ if (mDrawFramebuffer == framebuffer)
+ return;
+
+ mDrawFramebuffer = framebuffer;
+ mDirtyBits.set(DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
+
+ if (mDrawFramebuffer)
+ {
+ mDrawFramebuffer->setWriteControlMode(getFramebufferSRGB() ? SrgbWriteControlMode::Default
+ : SrgbWriteControlMode::Linear);
+
+ if (mDrawFramebuffer->hasAnyDirtyBit())
+ {
+ mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
+ }
+
+ if (mRobustResourceInit && mDrawFramebuffer->hasResourceThatNeedsInit())
+ {
+ mDirtyObjects.set(DIRTY_OBJECT_DRAW_ATTACHMENTS);
+ }
+ }
+}
+
+Framebuffer *State::getTargetFramebuffer(GLenum target) const
+{
+ switch (target)
+ {
+ case GL_READ_FRAMEBUFFER_ANGLE:
+ return mReadFramebuffer;
+ case GL_DRAW_FRAMEBUFFER_ANGLE:
+ case GL_FRAMEBUFFER:
+ return mDrawFramebuffer;
+ default:
+ UNREACHABLE();
+ return nullptr;
+ }
+}
+
+Framebuffer *State::getDefaultFramebuffer() const
+{
+ return mFramebufferManager->getDefaultFramebuffer();
+}
+
+bool State::removeReadFramebufferBinding(FramebufferID framebuffer)
+{
+ if (mReadFramebuffer != nullptr && mReadFramebuffer->id() == framebuffer)
+ {
+ setReadFramebufferBinding(nullptr);
+ return true;
+ }
+
+ return false;
+}
+
+bool State::removeDrawFramebufferBinding(FramebufferID framebuffer)
+{
+ if (mReadFramebuffer != nullptr && mDrawFramebuffer->id() == framebuffer)
+ {
+ setDrawFramebufferBinding(nullptr);
+ return true;
+ }
+
+ return false;
+}
+
+void State::setVertexArrayBinding(const Context *context, VertexArray *vertexArray)
+{
+ if (mVertexArray == vertexArray)
+ {
+ return;
+ }
+
+ if (mVertexArray)
+ {
+ mVertexArray->onBindingChanged(context, -1);
+ }
+ if (vertexArray)
+ {
+ vertexArray->onBindingChanged(context, 1);
+ }
+
+ mVertexArray = vertexArray;
+ mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
+
+ if (mVertexArray && mVertexArray->hasAnyDirtyBit())
+ {
+ mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
+ }
+}
+
+bool State::removeVertexArrayBinding(const Context *context, VertexArrayID vertexArray)
+{
+ if (mVertexArray && mVertexArray->id().value == vertexArray.value)
+ {
+ mVertexArray->onBindingChanged(context, -1);
+ mVertexArray = nullptr;
+ mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
+ mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
+ return true;
+ }
+
+ return false;
+}
+
+VertexArrayID State::getVertexArrayId() const
+{
+ ASSERT(mVertexArray != nullptr);
+ return mVertexArray->id();
+}
+
+void State::bindVertexBuffer(const Context *context,
+ GLuint bindingIndex,
+ Buffer *boundBuffer,
+ GLintptr offset,
+ GLsizei stride)
+{
+ getVertexArray()->bindVertexBuffer(context, bindingIndex, boundBuffer, offset, stride);
+ mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
+}
+
+void State::setVertexAttribFormat(GLuint attribIndex,
+ GLint size,
+ VertexAttribType type,
+ bool normalized,
+ bool pureInteger,
+ GLuint relativeOffset)
+{
+ getVertexArray()->setVertexAttribFormat(attribIndex, size, type, normalized, pureInteger,
+ relativeOffset);
+ mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
+}
+
+void State::setVertexBindingDivisor(const Context *context, GLuint bindingIndex, GLuint divisor)
+{
+ getVertexArray()->setVertexBindingDivisor(context, bindingIndex, divisor);
+ mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
+}
+
+angle::Result State::setProgram(const Context *context, Program *newProgram)
+{
+ if (newProgram && !newProgram->isLinked())
+ {
+ // Protect against applications that disable validation and try to use a program that was
+ // not successfully linked.
+ WARN() << "Attempted to use a program that was not successfully linked";
+ return angle::Result::Continue;
+ }
+
+ if (mProgram != newProgram)
+ {
+ if (mProgram)
+ {
+ unsetActiveTextures(mExecutable->getActiveSamplersMask());
+ mProgram->release(context);
+ }
+
+ mProgram = newProgram;
+ mExecutable = nullptr;
+
+ if (mProgram)
+ {
+ mExecutable = &mProgram->getExecutable();
+ newProgram->addRef();
+ ANGLE_TRY(onProgramExecutableChange(context, newProgram));
+ }
+ else if (mProgramPipeline.get())
+ {
+ mExecutable = &mProgramPipeline->getExecutable();
+ ANGLE_TRY(onProgramPipelineExecutableChange(context));
+ }
+
+ // Note that rendering is undefined if glUseProgram(0) is called. But ANGLE will generate
+ // an error if the app tries to draw in this case.
+
+ mDirtyBits.set(DIRTY_BIT_PROGRAM_BINDING);
+ }
+
+ return angle::Result::Continue;
+}
+
+void State::setTransformFeedbackBinding(const Context *context,
+ TransformFeedback *transformFeedback)
+{
+ if (transformFeedback == mTransformFeedback.get())
+ return;
+ if (mTransformFeedback.get())
+ mTransformFeedback->onBindingChanged(context, false);
+ mTransformFeedback.set(context, transformFeedback);
+ if (mTransformFeedback.get())
+ mTransformFeedback->onBindingChanged(context, true);
+ mDirtyBits.set(DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING);
+}
+
+bool State::removeTransformFeedbackBinding(const Context *context,
+ TransformFeedbackID transformFeedback)
+{
+ if (mTransformFeedback.id() == transformFeedback)
+ {
+ if (mTransformFeedback.get())
+ mTransformFeedback->onBindingChanged(context, false);
+ mTransformFeedback.set(context, nullptr);
+ return true;
+ }
+
+ return false;
+}
+
+angle::Result State::setProgramPipelineBinding(const Context *context, ProgramPipeline *pipeline)
+{
+ if (mProgramPipeline.get() == pipeline)
+ {
+ return angle::Result::Continue;
+ }
+
+ if (mProgramPipeline.get())
+ {
+ unsetActiveTextures(mProgramPipeline->getExecutable().getActiveSamplersMask());
+ }
+
+ mProgramPipeline.set(context, pipeline);
+ mDirtyBits.set(DIRTY_BIT_PROGRAM_BINDING);
+
+ // A bound Program always overrides the ProgramPipeline, so only update the
+ // current ProgramExecutable if there isn't currently a Program bound.
+ if (!mProgram)
+ {
+ if (mProgramPipeline.get())
+ {
+ mExecutable = &mProgramPipeline->getExecutable();
+ ANGLE_TRY(onProgramPipelineExecutableChange(context));
+ }
+ else
+ {
+ mExecutable = nullptr;
+ }
+ }
+
+ return angle::Result::Continue;
+}
+
+void State::detachProgramPipeline(const Context *context, ProgramPipelineID pipeline)
+{
+ mProgramPipeline.set(context, nullptr);
+
+ // A bound Program always overrides the ProgramPipeline, so only update the
+ // current ProgramExecutable if there isn't currently a Program bound.
+ if (!mProgram)
+ {
+ mExecutable = nullptr;
+ }
+}
+
+bool State::isQueryActive(QueryType type) const
+{
+ const Query *query = mActiveQueries[type].get();
+ if (query != nullptr)
+ {
+ return true;
+ }
+
+ QueryType alternativeType;
+ if (GetAlternativeQueryType(type, &alternativeType))
+ {
+ query = mActiveQueries[alternativeType].get();
+ return query != nullptr;
+ }
+
+ return false;
+}
+
+bool State::isQueryActive(Query *query) const
+{
+ for (auto &queryPointer : mActiveQueries)
+ {
+ if (queryPointer.get() == query)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void State::setActiveQuery(const Context *context, QueryType type, Query *query)
+{
+ mActiveQueries[type].set(context, query);
+}
+
+QueryID State::getActiveQueryId(QueryType type) const
+{
+ const Query *query = getActiveQuery(type);
+ if (query)
+ {
+ return query->id();
+ }
+ return {0};
+}
+
+Query *State::getActiveQuery(QueryType type) const
+{
+ return mActiveQueries[type].get();
+}
+
+angle::Result State::setIndexedBufferBinding(const Context *context,
+ BufferBinding target,
+ GLuint index,
+ Buffer *buffer,
+ GLintptr offset,
+ GLsizeiptr size)
+{
+ setBufferBinding(context, target, buffer);
+
+ switch (target)
+ {
+ case BufferBinding::TransformFeedback:
+ ANGLE_TRY(mTransformFeedback->bindIndexedBuffer(context, index, buffer, offset, size));
+ setBufferBinding(context, target, buffer);
+ break;
+ case BufferBinding::Uniform:
+ mBoundUniformBuffersMask.set(index, buffer != nullptr);
+ UpdateIndexedBufferBinding(context, &mUniformBuffers[index], buffer, target, offset,
+ size);
+ break;
+ case BufferBinding::AtomicCounter:
+ mBoundAtomicCounterBuffersMask.set(index, buffer != nullptr);
+ UpdateIndexedBufferBinding(context, &mAtomicCounterBuffers[index], buffer, target,
+ offset, size);
+ break;
+ case BufferBinding::ShaderStorage:
+ mBoundShaderStorageBuffersMask.set(index, buffer != nullptr);
+ UpdateIndexedBufferBinding(context, &mShaderStorageBuffers[index], buffer, target,
+ offset, size);
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ return angle::Result::Continue;
+}
+
+const OffsetBindingPointer<Buffer> &State::getIndexedUniformBuffer(size_t index) const
+{
+ ASSERT(index < mUniformBuffers.size());
+ return mUniformBuffers[index];
+}
+
+const OffsetBindingPointer<Buffer> &State::getIndexedAtomicCounterBuffer(size_t index) const
+{
+ ASSERT(index < mAtomicCounterBuffers.size());
+ return mAtomicCounterBuffers[index];
+}
+
+const OffsetBindingPointer<Buffer> &State::getIndexedShaderStorageBuffer(size_t index) const
+{
+ ASSERT(index < mShaderStorageBuffers.size());
+ return mShaderStorageBuffers[index];
+}
+
+angle::Result State::detachBuffer(Context *context, const Buffer *buffer)
+{
+ BufferID bufferID = buffer->id();
+ for (gl::BufferBinding target : angle::AllEnums<BufferBinding>())
+ {
+ if (mBoundBuffers[target].id() == bufferID)
+ {
+ UpdateBufferBinding(context, &mBoundBuffers[target], nullptr, target);
+ }
+ }
+
+ TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
+ if (curTransformFeedback)
+ {
+ ANGLE_TRY(curTransformFeedback->detachBuffer(context, bufferID));
+ context->getStateCache().onActiveTransformFeedbackChange(context);
+ }
+
+ if (getVertexArray()->detachBuffer(context, bufferID))
+ {
+ mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
+ context->getStateCache().onVertexArrayStateChange(context);
+ }
+
+ for (size_t uniformBufferIndex : mBoundUniformBuffersMask)
+ {
+ OffsetBindingPointer<Buffer> &binding = mUniformBuffers[uniformBufferIndex];
+
+ if (binding.id() == bufferID)
+ {
+ UpdateIndexedBufferBinding(context, &binding, nullptr, BufferBinding::Uniform, 0, 0);
+ mBoundUniformBuffersMask.reset(uniformBufferIndex);
+ }
+ }
+
+ for (size_t atomicCounterBufferIndex : mBoundAtomicCounterBuffersMask)
+ {
+ OffsetBindingPointer<Buffer> &binding = mAtomicCounterBuffers[atomicCounterBufferIndex];
+
+ if (binding.id() == bufferID)
+ {
+ UpdateIndexedBufferBinding(context, &binding, nullptr, BufferBinding::AtomicCounter, 0,
+ 0);
+ mBoundAtomicCounterBuffersMask.reset(atomicCounterBufferIndex);
+ }
+ }
+
+ for (size_t shaderStorageBufferIndex : mBoundShaderStorageBuffersMask)
+ {
+ OffsetBindingPointer<Buffer> &binding = mShaderStorageBuffers[shaderStorageBufferIndex];
+
+ if (binding.id() == bufferID)
+ {
+ UpdateIndexedBufferBinding(context, &binding, nullptr, BufferBinding::ShaderStorage, 0,
+ 0);
+ mBoundShaderStorageBuffersMask.reset(shaderStorageBufferIndex);
+ }
+ }
+
+ return angle::Result::Continue;
+}
+
+void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
+{
+ getVertexArray()->enableAttribute(attribNum, enabled);
+ mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
+}
+
+void State::setVertexAttribf(GLuint index, const GLfloat values[4])
+{
+ ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
+ mVertexAttribCurrentValues[index].setFloatValues(values);
+ mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES);
+ mDirtyCurrentValues.set(index);
+ SetComponentTypeMask(ComponentType::Float, index, &mCurrentValuesTypeMask);
+}
+
+void State::setVertexAttribu(GLuint index, const GLuint values[4])
+{
+ ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
+ mVertexAttribCurrentValues[index].setUnsignedIntValues(values);
+ mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES);
+ mDirtyCurrentValues.set(index);
+ SetComponentTypeMask(ComponentType::UnsignedInt, index, &mCurrentValuesTypeMask);
+}
+
+void State::setVertexAttribi(GLuint index, const GLint values[4])
+{
+ ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
+ mVertexAttribCurrentValues[index].setIntValues(values);
+ mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES);
+ mDirtyCurrentValues.set(index);
+ SetComponentTypeMask(ComponentType::Int, index, &mCurrentValuesTypeMask);
+}
+
+void State::setVertexAttribDivisor(const Context *context, GLuint index, GLuint divisor)
+{
+ getVertexArray()->setVertexAttribDivisor(context, index, divisor);
+ mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
+}
+
+const void *State::getVertexAttribPointer(unsigned int attribNum) const
+{
+ return getVertexArray()->getVertexAttribute(attribNum).pointer;
+}
+
+void State::setPackAlignment(GLint alignment)
+{
+ mPack.alignment = alignment;
+ mDirtyBits.set(DIRTY_BIT_PACK_STATE);
+}
+
+void State::setPackReverseRowOrder(bool reverseRowOrder)
+{
+ mPack.reverseRowOrder = reverseRowOrder;
+ mDirtyBits.set(DIRTY_BIT_PACK_STATE);
+}
+
+void State::setPackRowLength(GLint rowLength)
+{
+ mPack.rowLength = rowLength;
+ mDirtyBits.set(DIRTY_BIT_PACK_STATE);
+}
+
+void State::setPackSkipRows(GLint skipRows)
+{
+ mPack.skipRows = skipRows;
+ mDirtyBits.set(DIRTY_BIT_PACK_STATE);
+}
+
+void State::setPackSkipPixels(GLint skipPixels)
+{
+ mPack.skipPixels = skipPixels;
+ mDirtyBits.set(DIRTY_BIT_PACK_STATE);
+}
+
+void State::setUnpackAlignment(GLint alignment)
+{
+ mUnpack.alignment = alignment;
+ mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
+}
+
+void State::setUnpackRowLength(GLint rowLength)
+{
+ mUnpack.rowLength = rowLength;
+ mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
+}
+
+void State::setUnpackImageHeight(GLint imageHeight)
+{
+ mUnpack.imageHeight = imageHeight;
+ mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
+}
+
+void State::setUnpackSkipImages(GLint skipImages)
+{
+ mUnpack.skipImages = skipImages;
+ mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
+}
+
+void State::setUnpackSkipRows(GLint skipRows)
+{
+ mUnpack.skipRows = skipRows;
+ mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
+}
+
+void State::setUnpackSkipPixels(GLint skipPixels)
+{
+ mUnpack.skipPixels = skipPixels;
+ mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
+}
+
+void State::setCoverageModulation(GLenum components)
+{
+ if (mCoverageModulation != components)
+ {
+ mCoverageModulation = components;
+ mDirtyBits.set(DIRTY_BIT_COVERAGE_MODULATION);
+ }
+}
+
+void State::setFramebufferSRGB(bool sRGB)
+{
+ if (mFramebufferSRGB != sRGB)
+ {
+ mFramebufferSRGB = sRGB;
+ mDirtyBits.set(DIRTY_BIT_FRAMEBUFFER_SRGB_WRITE_CONTROL_MODE);
+ setDrawFramebufferDirty();
+ }
+}
+
+void State::setMaxShaderCompilerThreads(GLuint count)
+{
+ mMaxShaderCompilerThreads = count;
+}
+
+void State::setPatchVertices(GLuint value)
+{
+ if (mPatchVertices != value)
+ {
+ mPatchVertices = value;
+ mDirtyBits.set(DIRTY_BIT_PATCH_VERTICES);
+ }
+}
+
+void State::setPixelLocalStorageActive(bool active)
+{
+ mPixelLocalStorageActive = active;
+}
+
+void State::setShadingRate(GLenum rate)
+{
+ mShadingRate = FromGLenum<ShadingRate>(rate);
+ mDirtyBits.set(DIRTY_BIT_EXTENDED);
+ mExtendedDirtyBits.set(EXTENDED_DIRTY_BIT_SHADING_RATE);
+}
+
+void State::getBooleanv(GLenum pname, GLboolean *params) const
+{
+ switch (pname)
+ {
+ case GL_SAMPLE_COVERAGE_INVERT:
+ *params = mSampleCoverageInvert;
+ break;
+ case GL_DEPTH_WRITEMASK:
+ *params = mDepthStencil.depthMask;
+ break;
+ case GL_COLOR_WRITEMASK:
+ {
+ // non-indexed get returns the state of draw buffer zero
+ bool r, g, b, a;
+ mBlendStateExt.getColorMaskIndexed(0, &r, &g, &b, &a);
+ params[0] = r;
+ params[1] = g;
+ params[2] = b;
+ params[3] = a;
+ break;
+ }
+ case GL_CULL_FACE:
+ *params = mRasterizer.cullFace;
+ break;
+ case GL_POLYGON_OFFSET_FILL:
+ *params = mRasterizer.polygonOffsetFill;
+ break;
+ case GL_SAMPLE_ALPHA_TO_COVERAGE:
+ *params = mSampleAlphaToCoverage;
+ break;
+ case GL_SAMPLE_COVERAGE:
+ *params = mSampleCoverage;
+ break;
+ case GL_SAMPLE_MASK:
+ *params = mSampleMask;
+ break;
+ case GL_SCISSOR_TEST:
+ *params = mScissorTest;
+ break;
+ case GL_STENCIL_TEST:
+ *params = mDepthStencil.stencilTest;
+ break;
+ case GL_DEPTH_TEST:
+ *params = mDepthStencil.depthTest;
+ break;
+ case GL_BLEND:
+ // non-indexed get returns the state of draw buffer zero
+ *params = mBlendStateExt.getEnabledMask().test(0);
+ break;
+ case GL_DITHER:
+ *params = mRasterizer.dither;
+ break;
+ case GL_COLOR_LOGIC_OP:
+ ASSERT(mClientVersion.major > 1);
+ *params = mLogicOpEnabled;
+ break;
+ case GL_TRANSFORM_FEEDBACK_ACTIVE:
+ *params = getCurrentTransformFeedback()->isActive() ? GL_TRUE : GL_FALSE;
+ break;
+ case GL_TRANSFORM_FEEDBACK_PAUSED:
+ *params = getCurrentTransformFeedback()->isPaused() ? GL_TRUE : GL_FALSE;
+ break;
+ case GL_PRIMITIVE_RESTART_FIXED_INDEX:
+ *params = mPrimitiveRestart;
+ break;
+ case GL_RASTERIZER_DISCARD:
+ *params = isRasterizerDiscardEnabled() ? GL_TRUE : GL_FALSE;
+ break;
+ case GL_DEBUG_OUTPUT_SYNCHRONOUS:
+ *params = mDebug.isOutputSynchronous() ? GL_TRUE : GL_FALSE;
+ break;
+ case GL_DEBUG_OUTPUT:
+ *params = mDebug.isOutputEnabled() ? GL_TRUE : GL_FALSE;
+ break;
+ case GL_MULTISAMPLE_EXT:
+ *params = mMultiSampling;
+ break;
+ case GL_SAMPLE_ALPHA_TO_ONE_EXT:
+ *params = mSampleAlphaToOne;
+ break;
+ case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
+ *params = isBindGeneratesResourceEnabled() ? GL_TRUE : GL_FALSE;
+ break;
+ case GL_CLIENT_ARRAYS_ANGLE:
+ *params = areClientArraysEnabled() ? GL_TRUE : GL_FALSE;
+ break;
+ case GL_FRAMEBUFFER_SRGB_EXT:
+ *params = getFramebufferSRGB() ? GL_TRUE : GL_FALSE;
+ break;
+ case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
+ *params = mRobustResourceInit ? GL_TRUE : GL_FALSE;
+ break;
+ case GL_PROGRAM_CACHE_ENABLED_ANGLE:
+ *params = mProgramBinaryCacheEnabled ? GL_TRUE : GL_FALSE;
+ break;
+ case GL_TEXTURE_RECTANGLE_ANGLE:
+ *params = mTextureRectangleEnabled ? GL_TRUE : GL_FALSE;
+ break;
+ case GL_LIGHT_MODEL_TWO_SIDE:
+ *params = IsLightModelTwoSided(&mGLES1State);
+ break;
+ case GL_SAMPLE_SHADING:
+ *params = mIsSampleShadingEnabled;
+ break;
+ case GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED:
+ *params = isPrimitiveRestartEnabled() && getExtensions().tessellationShaderEXT;
+ break;
+ // 2.2.2 Data Conversions For State Query Commands, in GLES 3.2 spec.
+ // If a command returning boolean data is called, such as GetBooleanv, a floating-point or
+ // integer value converts to FALSE if and only if it is zero. Otherwise it converts to TRUE.
+ // GL_EXT_clip_control
+ case GL_CLIP_ORIGIN_EXT:
+ *params = GL_TRUE;
+ break;
+ case GL_CLIP_DEPTH_MODE_EXT:
+ *params = GL_TRUE;
+ break;
+ case GL_ROBUST_FRAGMENT_SHADER_OUTPUT_ANGLE:
+ *params = mExtensions.robustFragmentShaderOutputANGLE ? GL_TRUE : GL_FALSE;
+ break;
+ // GL_ANGLE_shader_pixel_local_storage
+ case GL_PIXEL_LOCAL_STORAGE_ACTIVE_ANGLE:
+ *params = mPixelLocalStorageActive ? GL_TRUE : GL_FALSE;
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+void State::getFloatv(GLenum pname, GLfloat *params) const
+{
+ // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
+ // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
+ // GetIntegerv as its native query function. As it would require conversion in any
+ // case, this should make no difference to the calling application.
+ switch (pname)
+ {
+ case GL_LINE_WIDTH:
+ *params = mLineWidth;
+ break;
+ case GL_SAMPLE_COVERAGE_VALUE:
+ *params = mSampleCoverageValue;
+ break;
+ case GL_DEPTH_CLEAR_VALUE:
+ *params = mDepthClearValue;
+ break;
+ case GL_POLYGON_OFFSET_FACTOR:
+ *params = mRasterizer.polygonOffsetFactor;
+ break;
+ case GL_POLYGON_OFFSET_UNITS:
+ *params = mRasterizer.polygonOffsetUnits;
+ break;
+ case GL_DEPTH_RANGE:
+ params[0] = mNearZ;
+ params[1] = mFarZ;
+ break;
+ case GL_COLOR_CLEAR_VALUE:
+ params[0] = mColorClearValue.red;
+ params[1] = mColorClearValue.green;
+ params[2] = mColorClearValue.blue;
+ params[3] = mColorClearValue.alpha;
+ break;
+ case GL_BLEND_COLOR:
+ params[0] = mBlendColor.red;
+ params[1] = mBlendColor.green;
+ params[2] = mBlendColor.blue;
+ params[3] = mBlendColor.alpha;
+ break;
+ case GL_MULTISAMPLE_EXT:
+ *params = static_cast<GLfloat>(mMultiSampling);
+ break;
+ case GL_SAMPLE_ALPHA_TO_ONE_EXT:
+ *params = static_cast<GLfloat>(mSampleAlphaToOne);
+ break;
+ case GL_COVERAGE_MODULATION_CHROMIUM:
+ params[0] = static_cast<GLfloat>(mCoverageModulation);
+ break;
+ case GL_ALPHA_TEST_REF:
+ *params = mGLES1State.mAlphaTestRef;
+ break;
+ case GL_CURRENT_COLOR:
+ {
+ const auto &color = mGLES1State.mCurrentColor;
+ params[0] = color.red;
+ params[1] = color.green;
+ params[2] = color.blue;
+ params[3] = color.alpha;
+ break;
+ }
+ case GL_CURRENT_NORMAL:
+ {
+ const auto &normal = mGLES1State.mCurrentNormal;
+ params[0] = normal[0];
+ params[1] = normal[1];
+ params[2] = normal[2];
+ break;
+ }
+ case GL_CURRENT_TEXTURE_COORDS:
+ {
+ const auto &texcoord = mGLES1State.mCurrentTextureCoords[mActiveSampler];
+ params[0] = texcoord.s;
+ params[1] = texcoord.t;
+ params[2] = texcoord.r;
+ params[3] = texcoord.q;
+ break;
+ }
+ case GL_MODELVIEW_MATRIX:
+ memcpy(params, mGLES1State.mModelviewMatrices.back().constData(), 16 * sizeof(GLfloat));
+ break;
+ case GL_PROJECTION_MATRIX:
+ memcpy(params, mGLES1State.mProjectionMatrices.back().constData(),
+ 16 * sizeof(GLfloat));
+ break;
+ case GL_TEXTURE_MATRIX:
+ memcpy(params, mGLES1State.mTextureMatrices[mActiveSampler].back().constData(),
+ 16 * sizeof(GLfloat));
+ break;
+ case GL_LIGHT_MODEL_AMBIENT:
+ GetLightModelParameters(&mGLES1State, pname, params);
+ break;
+ case GL_FOG_MODE:
+ case GL_FOG_DENSITY:
+ case GL_FOG_START:
+ case GL_FOG_END:
+ case GL_FOG_COLOR:
+ GetFogParameters(&mGLES1State, pname, params);
+ break;
+ case GL_POINT_SIZE:
+ GetPointSize(&mGLES1State, params);
+ break;
+ case GL_POINT_SIZE_MIN:
+ case GL_POINT_SIZE_MAX:
+ case GL_POINT_FADE_THRESHOLD_SIZE:
+ case GL_POINT_DISTANCE_ATTENUATION:
+ GetPointParameter(&mGLES1State, FromGLenum<PointParameter>(pname), params);
+ break;
+ case GL_MIN_SAMPLE_SHADING_VALUE:
+ *params = mMinSampleShading;
+ break;
+ // 2.2.2 Data Conversions For State Query Commands, in GLES 3.2 spec.
+ // If a command returning floating-point data is called, such as GetFloatv, ... An integer
+ // value is coerced to floating-point.
+ case GL_CLIP_ORIGIN_EXT:
+ *params = static_cast<float>(mClipControlOrigin);
+ break;
+ case GL_CLIP_DEPTH_MODE_EXT:
+ *params = static_cast<float>(mClipControlDepth);
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+angle::Result State::getIntegerv(const Context *context, GLenum pname, GLint *params) const
+{
+ if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
+ {
+ size_t drawBuffer = (pname - GL_DRAW_BUFFER0_EXT);
+ ASSERT(drawBuffer < static_cast<size_t>(mCaps.maxDrawBuffers));
+ Framebuffer *framebuffer = mDrawFramebuffer;
+ // The default framebuffer may have fewer draw buffer states than a user-created one. The
+ // user is always allowed to query up to GL_MAX_DRAWBUFFERS so just return GL_NONE here if
+ // the draw buffer is out of range for this framebuffer.
+ *params = drawBuffer < framebuffer->getDrawbufferStateCount()
+ ? framebuffer->getDrawBufferState(drawBuffer)
+ : GL_NONE;
+ return angle::Result::Continue;
+ }
+
+ // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
+ // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
+ // GetIntegerv as its native query function. As it would require conversion in any
+ // case, this should make no difference to the calling application. You may find it in
+ // State::getFloatv.
+ switch (pname)
+ {
+ case GL_ARRAY_BUFFER_BINDING:
+ *params = mBoundBuffers[BufferBinding::Array].id().value;
+ break;
+ case GL_DRAW_INDIRECT_BUFFER_BINDING:
+ *params = mBoundBuffers[BufferBinding::DrawIndirect].id().value;
+ break;
+ case GL_ELEMENT_ARRAY_BUFFER_BINDING:
+ {
+ Buffer *elementArrayBuffer = getVertexArray()->getElementArrayBuffer();
+ *params = elementArrayBuffer ? elementArrayBuffer->id().value : 0;
+ break;
+ }
+ case GL_DRAW_FRAMEBUFFER_BINDING:
+ static_assert(GL_DRAW_FRAMEBUFFER_BINDING == GL_DRAW_FRAMEBUFFER_BINDING_ANGLE,
+ "Enum mismatch");
+ *params = mDrawFramebuffer->id().value;
+ break;
+ case GL_READ_FRAMEBUFFER_BINDING:
+ static_assert(GL_READ_FRAMEBUFFER_BINDING == GL_READ_FRAMEBUFFER_BINDING_ANGLE,
+ "Enum mismatch");
+ *params = mReadFramebuffer->id().value;
+ break;
+ case GL_RENDERBUFFER_BINDING:
+ *params = mRenderbuffer.id().value;
+ break;
+ case GL_VERTEX_ARRAY_BINDING:
+ *params = mVertexArray->id().value;
+ break;
+ case GL_CURRENT_PROGRAM:
+ *params = mProgram ? mProgram->id().value : 0;
+ break;
+ case GL_PACK_ALIGNMENT:
+ *params = mPack.alignment;
+ break;
+ case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
+ *params = mPack.reverseRowOrder;
+ break;
+ case GL_PACK_ROW_LENGTH:
+ *params = mPack.rowLength;
+ break;
+ case GL_PACK_SKIP_ROWS:
+ *params = mPack.skipRows;
+ break;
+ case GL_PACK_SKIP_PIXELS:
+ *params = mPack.skipPixels;
+ break;
+ case GL_UNPACK_ALIGNMENT:
+ *params = mUnpack.alignment;
+ break;
+ case GL_UNPACK_ROW_LENGTH:
+ *params = mUnpack.rowLength;
+ break;
+ case GL_UNPACK_IMAGE_HEIGHT:
+ *params = mUnpack.imageHeight;
+ break;
+ case GL_UNPACK_SKIP_IMAGES:
+ *params = mUnpack.skipImages;
+ break;
+ case GL_UNPACK_SKIP_ROWS:
+ *params = mUnpack.skipRows;
+ break;
+ case GL_UNPACK_SKIP_PIXELS:
+ *params = mUnpack.skipPixels;
+ break;
+ case GL_GENERATE_MIPMAP_HINT:
+ *params = mGenerateMipmapHint;
+ break;
+ case GL_TEXTURE_FILTERING_HINT_CHROMIUM:
+ *params = mTextureFilteringHint;
+ break;
+ case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
+ *params = mFragmentShaderDerivativeHint;
+ break;
+ case GL_ACTIVE_TEXTURE:
+ *params = (static_cast<GLint>(mActiveSampler) + GL_TEXTURE0);
+ break;
+ case GL_STENCIL_FUNC:
+ *params = mDepthStencil.stencilFunc;
+ break;
+ case GL_STENCIL_REF:
+ *params = mStencilRef;
+ break;
+ case GL_STENCIL_VALUE_MASK:
+ *params = CastMaskValue(mDepthStencil.stencilMask);
+ break;
+ case GL_STENCIL_BACK_FUNC:
+ *params = mDepthStencil.stencilBackFunc;
+ break;
+ case GL_STENCIL_BACK_REF:
+ *params = mStencilBackRef;
+ break;
+ case GL_STENCIL_BACK_VALUE_MASK:
+ *params = CastMaskValue(mDepthStencil.stencilBackMask);
+ break;
+ case GL_STENCIL_FAIL:
+ *params = mDepthStencil.stencilFail;
+ break;
+ case GL_STENCIL_PASS_DEPTH_FAIL:
+ *params = mDepthStencil.stencilPassDepthFail;
+ break;
+ case GL_STENCIL_PASS_DEPTH_PASS:
+ *params = mDepthStencil.stencilPassDepthPass;
+ break;
+ case GL_STENCIL_BACK_FAIL:
+ *params = mDepthStencil.stencilBackFail;
+ break;
+ case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
+ *params = mDepthStencil.stencilBackPassDepthFail;
+ break;
+ case GL_STENCIL_BACK_PASS_DEPTH_PASS:
+ *params = mDepthStencil.stencilBackPassDepthPass;
+ break;
+ case GL_DEPTH_FUNC:
+ *params = mDepthStencil.depthFunc;
+ break;
+ case GL_BLEND_SRC_RGB:
+ // non-indexed get returns the state of draw buffer zero
+ *params = mBlendStateExt.getSrcColorIndexed(0);
+ break;
+ case GL_BLEND_SRC_ALPHA:
+ *params = mBlendStateExt.getSrcAlphaIndexed(0);
+ break;
+ case GL_BLEND_DST_RGB:
+ *params = mBlendStateExt.getDstColorIndexed(0);
+ break;
+ case GL_BLEND_DST_ALPHA:
+ *params = mBlendStateExt.getDstAlphaIndexed(0);
+ break;
+ case GL_BLEND_EQUATION_RGB:
+ *params = mBlendStateExt.getEquationColorIndexed(0);
+ break;
+ case GL_BLEND_EQUATION_ALPHA:
+ *params = mBlendStateExt.getEquationAlphaIndexed(0);
+ break;
+ case GL_STENCIL_WRITEMASK:
+ *params = CastMaskValue(mDepthStencil.stencilWritemask);
+ break;
+ case GL_STENCIL_BACK_WRITEMASK:
+ *params = CastMaskValue(mDepthStencil.stencilBackWritemask);
+ break;
+ case GL_STENCIL_CLEAR_VALUE:
+ *params = mStencilClearValue;
+ break;
+ case GL_IMPLEMENTATION_COLOR_READ_TYPE:
+ *params = mReadFramebuffer->getImplementationColorReadType(context);
+ break;
+ case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
+ *params = mReadFramebuffer->getImplementationColorReadFormat(context);
+ break;
+ case GL_SAMPLE_BUFFERS:
+ case GL_SAMPLES:
+ {
+ Framebuffer *framebuffer = mDrawFramebuffer;
+ if (framebuffer->isComplete(context))
+ {
+ GLint samples = framebuffer->getSamples(context);
+ switch (pname)
+ {
+ case GL_SAMPLE_BUFFERS:
+ if (samples != 0)
+ {
+ *params = 1;
+ }
+ else
+ {
+ *params = 0;
+ }
+ break;
+ case GL_SAMPLES:
+ *params = samples;
+ break;
+ }
+ }
+ else
+ {
+ *params = 0;
+ }
+ }
+ break;
+ case GL_VIEWPORT:
+ params[0] = mViewport.x;
+ params[1] = mViewport.y;
+ params[2] = mViewport.width;
+ params[3] = mViewport.height;
+ break;
+ case GL_SCISSOR_BOX:
+ params[0] = mScissor.x;
+ params[1] = mScissor.y;
+ params[2] = mScissor.width;
+ params[3] = mScissor.height;
+ break;
+ case GL_CULL_FACE_MODE:
+ *params = ToGLenum(mRasterizer.cullMode);
+ break;
+ case GL_FRONT_FACE:
+ *params = mRasterizer.frontFace;
+ break;
+ case GL_RED_BITS:
+ case GL_GREEN_BITS:
+ case GL_BLUE_BITS:
+ case GL_ALPHA_BITS:
+ {
+ Framebuffer *framebuffer = getDrawFramebuffer();
+ const FramebufferAttachment *colorbuffer = framebuffer->getFirstColorAttachment();
+
+ if (colorbuffer)
+ {
+ switch (pname)
+ {
+ case GL_RED_BITS:
+ *params = colorbuffer->getRedSize();
+ break;
+ case GL_GREEN_BITS:
+ *params = colorbuffer->getGreenSize();
+ break;
+ case GL_BLUE_BITS:
+ *params = colorbuffer->getBlueSize();
+ break;
+ case GL_ALPHA_BITS:
+ *params = colorbuffer->getAlphaSize();
+ break;
+ }
+ }
+ else
+ {
+ *params = 0;
+ }
+ }
+ break;
+ case GL_DEPTH_BITS:
+ {
+ const Framebuffer *framebuffer = getDrawFramebuffer();
+ const FramebufferAttachment *depthbuffer = framebuffer->getDepthAttachment();
+
+ if (depthbuffer)
+ {
+ *params = depthbuffer->getDepthSize();
+ }
+ else
+ {
+ *params = 0;
+ }
+ }
+ break;
+ case GL_STENCIL_BITS:
+ {
+ const Framebuffer *framebuffer = getDrawFramebuffer();
+ const FramebufferAttachment *stencilbuffer = framebuffer->getStencilAttachment();
+
+ if (stencilbuffer)
+ {
+ *params = stencilbuffer->getStencilSize();
+ }
+ else
+ {
+ *params = 0;
+ }
+ }
+ break;
+ case GL_TEXTURE_BINDING_2D:
+ ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
+ *params =
+ getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), TextureType::_2D)
+ .value;
+ break;
+ case GL_TEXTURE_BINDING_RECTANGLE_ANGLE:
+ ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
+ *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
+ TextureType::Rectangle)
+ .value;
+ break;
+ case GL_TEXTURE_BINDING_CUBE_MAP:
+ ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
+ *params =
+ getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), TextureType::CubeMap)
+ .value;
+ break;
+ case GL_TEXTURE_BINDING_3D:
+ ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
+ *params =
+ getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), TextureType::_3D)
+ .value;
+ break;
+ case GL_TEXTURE_BINDING_2D_ARRAY:
+ ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
+ *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
+ TextureType::_2DArray)
+ .value;
+ break;
+ case GL_TEXTURE_BINDING_2D_MULTISAMPLE:
+ ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
+ *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
+ TextureType::_2DMultisample)
+ .value;
+ break;
+ case GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY:
+ ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
+ *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
+ TextureType::_2DMultisampleArray)
+ .value;
+ break;
+ case GL_TEXTURE_BINDING_CUBE_MAP_ARRAY:
+ ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
+ *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
+ TextureType::CubeMapArray)
+ .value;
+ break;
+ case GL_TEXTURE_BINDING_EXTERNAL_OES:
+ ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
+ *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
+ TextureType::External)
+ .value;
+ break;
+
+ // GL_OES_texture_buffer
+ case GL_TEXTURE_BINDING_BUFFER:
+ ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
+ *params =
+ getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), TextureType::Buffer)
+ .value;
+ break;
+ case GL_TEXTURE_BUFFER_BINDING:
+ *params = mBoundBuffers[BufferBinding::Texture].id().value;
+ break;
+
+ case GL_UNIFORM_BUFFER_BINDING:
+ *params = mBoundBuffers[BufferBinding::Uniform].id().value;
+ break;
+ case GL_TRANSFORM_FEEDBACK_BINDING:
+ *params = mTransformFeedback.id().value;
+ break;
+ case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
+ *params = mBoundBuffers[BufferBinding::TransformFeedback].id().value;
+ break;
+ case GL_COPY_READ_BUFFER_BINDING:
+ *params = mBoundBuffers[BufferBinding::CopyRead].id().value;
+ break;
+ case GL_COPY_WRITE_BUFFER_BINDING:
+ *params = mBoundBuffers[BufferBinding::CopyWrite].id().value;
+ break;
+ case GL_PIXEL_PACK_BUFFER_BINDING:
+ *params = mBoundBuffers[BufferBinding::PixelPack].id().value;
+ break;
+ case GL_PIXEL_UNPACK_BUFFER_BINDING:
+ *params = mBoundBuffers[BufferBinding::PixelUnpack].id().value;
+ break;
+
+ case GL_READ_BUFFER:
+ *params = mReadFramebuffer->getReadBufferState();
+ break;
+ case GL_SAMPLER_BINDING:
+ ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
+ *params = getSamplerId(static_cast<GLuint>(mActiveSampler)).value;
+ break;
+ case GL_DEBUG_LOGGED_MESSAGES:
+ *params = static_cast<GLint>(mDebug.getMessageCount());
+ break;
+ case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
+ *params = static_cast<GLint>(mDebug.getNextMessageLength());
+ break;
+ case GL_DEBUG_GROUP_STACK_DEPTH:
+ *params = static_cast<GLint>(mDebug.getGroupStackDepth());
+ break;
+ case GL_MULTISAMPLE_EXT:
+ *params = static_cast<GLint>(mMultiSampling);
+ break;
+ case GL_SAMPLE_ALPHA_TO_ONE_EXT:
+ *params = static_cast<GLint>(mSampleAlphaToOne);
+ break;
+ case GL_COVERAGE_MODULATION_CHROMIUM:
+ *params = static_cast<GLint>(mCoverageModulation);
+ break;
+ case GL_ATOMIC_COUNTER_BUFFER_BINDING:
+ *params = mBoundBuffers[BufferBinding::AtomicCounter].id().value;
+ break;
+ case GL_SHADER_STORAGE_BUFFER_BINDING:
+ *params = mBoundBuffers[BufferBinding::ShaderStorage].id().value;
+ break;
+ case GL_DISPATCH_INDIRECT_BUFFER_BINDING:
+ *params = mBoundBuffers[BufferBinding::DispatchIndirect].id().value;
+ break;
+ case GL_ALPHA_TEST_FUNC:
+ *params = ToGLenum(mGLES1State.mAlphaTestFunc);
+ break;
+ case GL_CLIENT_ACTIVE_TEXTURE:
+ *params = mGLES1State.mClientActiveTexture + GL_TEXTURE0;
+ break;
+ case GL_MATRIX_MODE:
+ *params = ToGLenum(mGLES1State.mMatrixMode);
+ break;
+ case GL_SHADE_MODEL:
+ *params = ToGLenum(mGLES1State.mShadeModel);
+ break;
+ case GL_MODELVIEW_STACK_DEPTH:
+ case GL_PROJECTION_STACK_DEPTH:
+ case GL_TEXTURE_STACK_DEPTH:
+ *params = mGLES1State.getCurrentMatrixStackDepth(pname);
+ break;
+ case GL_LOGIC_OP_MODE:
+ *params = ToGLenum(mGLES1State.mLogicOp);
+ break;
+ case GL_BLEND_SRC:
+ // non-indexed get returns the state of draw buffer zero
+ *params = mBlendStateExt.getSrcColorIndexed(0);
+ break;
+ case GL_BLEND_DST:
+ *params = mBlendStateExt.getDstColorIndexed(0);
+ break;
+ case GL_PERSPECTIVE_CORRECTION_HINT:
+ case GL_POINT_SMOOTH_HINT:
+ case GL_LINE_SMOOTH_HINT:
+ case GL_FOG_HINT:
+ *params = mGLES1State.getHint(pname);
+ break;
+
+ // GL_ANGLE_provoking_vertex
+ case GL_PROVOKING_VERTEX:
+ *params = ToGLenum(mProvokingVertex);
+ break;
+
+ case GL_PROGRAM_PIPELINE_BINDING:
+ {
+ ProgramPipeline *pipeline = getProgramPipeline();
+ if (pipeline)
+ {
+ *params = pipeline->id().value;
+ }
+ else
+ {
+ *params = 0;
+ }
+ break;
+ }
+ case GL_PATCH_VERTICES:
+ *params = mPatchVertices;
+ break;
+
+ // GL_EXT_clip_control
+ case GL_CLIP_ORIGIN_EXT:
+ *params = mClipControlOrigin;
+ break;
+ case GL_CLIP_DEPTH_MODE_EXT:
+ *params = mClipControlDepth;
+ break;
+
+ // GL_QCOM_shading_rate
+ case GL_SHADING_RATE_QCOM:
+ *params = ToGLenum(mShadingRate);
+ break;
+
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ return angle::Result::Continue;
+}
+
+void State::getPointerv(const Context *context, GLenum pname, void **params) const
+{
+ switch (pname)
+ {
+ case GL_DEBUG_CALLBACK_FUNCTION:
+ *params = reinterpret_cast<void *>(mDebug.getCallback());
+ break;
+ case GL_DEBUG_CALLBACK_USER_PARAM:
+ *params = const_cast<void *>(mDebug.getUserParam());
+ break;
+ case GL_VERTEX_ARRAY_POINTER:
+ case GL_NORMAL_ARRAY_POINTER:
+ case GL_COLOR_ARRAY_POINTER:
+ case GL_TEXTURE_COORD_ARRAY_POINTER:
+ case GL_POINT_SIZE_ARRAY_POINTER_OES:
+ QueryVertexAttribPointerv(getVertexArray()->getVertexAttribute(
+ context->vertexArrayIndex(ParamToVertexArrayType(pname))),
+ GL_VERTEX_ATTRIB_ARRAY_POINTER, params);
+ return;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+void State::getIntegeri_v(const Context *context, GLenum target, GLuint index, GLint *data) const
+{
+ switch (target)
+ {
+ case GL_BLEND_SRC_RGB:
+ ASSERT(static_cast<size_t>(index) < mBlendStateExt.getDrawBufferCount());
+ *data = mBlendStateExt.getSrcColorIndexed(index);
+ break;
+ case GL_BLEND_SRC_ALPHA:
+ ASSERT(static_cast<size_t>(index) < mBlendStateExt.getDrawBufferCount());
+ *data = mBlendStateExt.getSrcAlphaIndexed(index);
+ break;
+ case GL_BLEND_DST_RGB:
+ ASSERT(static_cast<size_t>(index) < mBlendStateExt.getDrawBufferCount());
+ *data = mBlendStateExt.getDstColorIndexed(index);
+ break;
+ case GL_BLEND_DST_ALPHA:
+ ASSERT(static_cast<size_t>(index) < mBlendStateExt.getDrawBufferCount());
+ *data = mBlendStateExt.getDstAlphaIndexed(index);
+ break;
+ case GL_BLEND_EQUATION_RGB:
+ ASSERT(static_cast<size_t>(index) < mBlendStateExt.getDrawBufferCount());
+ *data = mBlendStateExt.getEquationColorIndexed(index);
+ break;
+ case GL_BLEND_EQUATION_ALPHA:
+ ASSERT(static_cast<size_t>(index) < mBlendStateExt.getDrawBufferCount());
+ *data = mBlendStateExt.getEquationAlphaIndexed(index);
+ break;
+ case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
+ ASSERT(static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount());
+ *data = mTransformFeedback->getIndexedBuffer(index).id().value;
+ break;
+ case GL_UNIFORM_BUFFER_BINDING:
+ ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
+ *data = mUniformBuffers[index].id().value;
+ break;
+ case GL_ATOMIC_COUNTER_BUFFER_BINDING:
+ ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
+ *data = mAtomicCounterBuffers[index].id().value;
+ break;
+ case GL_SHADER_STORAGE_BUFFER_BINDING:
+ ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
+ *data = mShaderStorageBuffers[index].id().value;
+ break;
+ case GL_VERTEX_BINDING_BUFFER:
+ ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
+ *data = mVertexArray->getVertexBinding(index).getBuffer().id().value;
+ break;
+ case GL_VERTEX_BINDING_DIVISOR:
+ ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
+ *data = mVertexArray->getVertexBinding(index).getDivisor();
+ break;
+ case GL_VERTEX_BINDING_OFFSET:
+ ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
+ *data = static_cast<GLuint>(mVertexArray->getVertexBinding(index).getOffset());
+ break;
+ case GL_VERTEX_BINDING_STRIDE:
+ ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
+ *data = mVertexArray->getVertexBinding(index).getStride();
+ break;
+ case GL_SAMPLE_MASK_VALUE:
+ ASSERT(static_cast<size_t>(index) < mSampleMaskValues.size());
+ *data = mSampleMaskValues[index];
+ break;
+ case GL_IMAGE_BINDING_NAME:
+ ASSERT(static_cast<size_t>(index) < mImageUnits.size());
+ *data = mImageUnits[index].texture.id().value;
+ break;
+ case GL_IMAGE_BINDING_LEVEL:
+ ASSERT(static_cast<size_t>(index) < mImageUnits.size());
+ *data = mImageUnits[index].level;
+ break;
+ case GL_IMAGE_BINDING_LAYER:
+ ASSERT(static_cast<size_t>(index) < mImageUnits.size());
+ *data = mImageUnits[index].layer;
+ break;
+ case GL_IMAGE_BINDING_ACCESS:
+ ASSERT(static_cast<size_t>(index) < mImageUnits.size());
+ *data = mImageUnits[index].access;
+ break;
+ case GL_IMAGE_BINDING_FORMAT:
+ ASSERT(static_cast<size_t>(index) < mImageUnits.size());
+ *data = mImageUnits[index].format;
+ break;
+ // GL_ANGLE_shader_pixel_local_storage.
+ case GL_PIXEL_LOCAL_FORMAT_ANGLE:
+ case GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE:
+ case GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE:
+ case GL_PIXEL_LOCAL_TEXTURE_LAYER_ANGLE:
+ {
+ ASSERT(mDrawFramebuffer);
+ *data = mDrawFramebuffer->getPixelLocalStorage(context).getPlane(index).getIntegeri(
+ context, target, index);
+ break;
+ }
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+void State::getInteger64i_v(GLenum target, GLuint index, GLint64 *data) const
+{
+ switch (target)
+ {
+ case GL_TRANSFORM_FEEDBACK_BUFFER_START:
+ ASSERT(static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount());
+ *data = mTransformFeedback->getIndexedBuffer(index).getOffset();
+ break;
+ case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
+ ASSERT(static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount());
+ *data = mTransformFeedback->getIndexedBuffer(index).getSize();
+ break;
+ case GL_UNIFORM_BUFFER_START:
+ ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
+ *data = mUniformBuffers[index].getOffset();
+ break;
+ case GL_UNIFORM_BUFFER_SIZE:
+ ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
+ *data = mUniformBuffers[index].getSize();
+ break;
+ case GL_ATOMIC_COUNTER_BUFFER_START:
+ ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
+ *data = mAtomicCounterBuffers[index].getOffset();
+ break;
+ case GL_ATOMIC_COUNTER_BUFFER_SIZE:
+ ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
+ *data = mAtomicCounterBuffers[index].getSize();
+ break;
+ case GL_SHADER_STORAGE_BUFFER_START:
+ ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
+ *data = mShaderStorageBuffers[index].getOffset();
+ break;
+ case GL_SHADER_STORAGE_BUFFER_SIZE:
+ ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
+ *data = mShaderStorageBuffers[index].getSize();
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+void State::getBooleani_v(GLenum target, GLuint index, GLboolean *data) const
+{
+ switch (target)
+ {
+ case GL_COLOR_WRITEMASK:
+ {
+ ASSERT(static_cast<size_t>(index) < mBlendStateExt.getDrawBufferCount());
+ bool r, g, b, a;
+ mBlendStateExt.getColorMaskIndexed(index, &r, &g, &b, &a);
+ data[0] = r;
+ data[1] = g;
+ data[2] = b;
+ data[3] = a;
+ break;
+ }
+ case GL_IMAGE_BINDING_LAYERED:
+ ASSERT(static_cast<size_t>(index) < mImageUnits.size());
+ *data = mImageUnits[index].layered;
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+// TODO(http://anglebug.com/3889): Remove this helper function after blink and chromium part
+// refactor done.
+Texture *State::getTextureForActiveSampler(TextureType type, size_t index)
+{
+ if (type != TextureType::VideoImage)
+ {
+ return mSamplerTextures[type][index].get();
+ }
+
+ ASSERT(type == TextureType::VideoImage);
+
+ Texture *candidateTexture = mSamplerTextures[type][index].get();
+ if (candidateTexture->getWidth(TextureTarget::VideoImage, 0) == 0 ||
+ candidateTexture->getHeight(TextureTarget::VideoImage, 0) == 0 ||
+ candidateTexture->getDepth(TextureTarget::VideoImage, 0) == 0)
+ {
+ return mSamplerTextures[TextureType::_2D][index].get();
+ }
+
+ return mSamplerTextures[type][index].get();
+}
+
+angle::Result State::syncActiveTextures(const Context *context, Command command)
+{
+ if (mDirtyActiveTextures.none())
+ {
+ return angle::Result::Continue;
+ }
+
+ for (size_t textureUnit : mDirtyActiveTextures)
+ {
+ if (mExecutable)
+ {
+ TextureType type = mExecutable->getActiveSamplerTypes()[textureUnit];
+ Texture *activeTexture = (type != TextureType::InvalidEnum)
+ ? getTextureForActiveSampler(type, textureUnit)
+ : nullptr;
+ const Sampler *sampler = mSamplers[textureUnit].get();
+
+ updateActiveTextureStateOnSync(context, textureUnit, sampler, activeTexture);
+ }
+ }
+
+ mDirtyActiveTextures.reset();
+ return angle::Result::Continue;
+}
+
+angle::Result State::syncTexturesInit(const Context *context, Command command)
+{
+ ASSERT(mRobustResourceInit);
+
+ if (!mProgram)
+ return angle::Result::Continue;
+
+ for (size_t textureUnitIndex : mExecutable->getActiveSamplersMask())
+ {
+ Texture *texture = mActiveTexturesCache[textureUnitIndex];
+ if (texture)
+ {
+ ANGLE_TRY(texture->ensureInitialized(context));
+ }
+ }
+ return angle::Result::Continue;
+}
+
+angle::Result State::syncImagesInit(const Context *context, Command command)
+{
+ ASSERT(mRobustResourceInit);
+ ASSERT(mExecutable);
+ for (size_t imageUnitIndex : mExecutable->getActiveImagesMask())
+ {
+ Texture *texture = mImageUnits[imageUnitIndex].texture.get();
+ if (texture)
+ {
+ ANGLE_TRY(texture->ensureInitialized(context));
+ }
+ }
+ return angle::Result::Continue;
+}
+
+angle::Result State::syncReadAttachments(const Context *context, Command command)
+{
+ ASSERT(mReadFramebuffer);
+ ASSERT(mRobustResourceInit);
+ return mReadFramebuffer->ensureReadAttachmentsInitialized(context);
+}
+
+angle::Result State::syncDrawAttachments(const Context *context, Command command)
+{
+ ASSERT(mDrawFramebuffer);
+ ASSERT(mRobustResourceInit);
+ return mDrawFramebuffer->ensureDrawAttachmentsInitialized(context);
+}
+
+angle::Result State::syncReadFramebuffer(const Context *context, Command command)
+{
+ ASSERT(mReadFramebuffer);
+ return mReadFramebuffer->syncState(context, GL_READ_FRAMEBUFFER, command);
+}
+
+angle::Result State::syncDrawFramebuffer(const Context *context, Command command)
+{
+ ASSERT(mDrawFramebuffer);
+ mDrawFramebuffer->setWriteControlMode(context->getState().getFramebufferSRGB()
+ ? SrgbWriteControlMode::Default
+ : SrgbWriteControlMode::Linear);
+ return mDrawFramebuffer->syncState(context, GL_DRAW_FRAMEBUFFER, command);
+}
+
+angle::Result State::syncTextures(const Context *context, Command command)
+{
+ if (mDirtyTextures.none())
+ return angle::Result::Continue;
+
+ for (size_t textureIndex : mDirtyTextures)
+ {
+ Texture *texture = mActiveTexturesCache[textureIndex];
+ if (texture && texture->hasAnyDirtyBit())
+ {
+ ANGLE_TRY(texture->syncState(context, Command::Other));
+ }
+ }
+
+ mDirtyTextures.reset();
+ return angle::Result::Continue;
+}
+
+angle::Result State::syncImages(const Context *context, Command command)
+{
+ if (mDirtyImages.none())
+ return angle::Result::Continue;
+
+ for (size_t imageUnitIndex : mDirtyImages)
+ {
+ Texture *texture = mImageUnits[imageUnitIndex].texture.get();
+ if (texture && texture->hasAnyDirtyBit())
+ {
+ ANGLE_TRY(texture->syncState(context, Command::Other));
+ }
+ }
+
+ mDirtyImages.reset();
+ return angle::Result::Continue;
+}
+
+angle::Result State::syncSamplers(const Context *context, Command command)
+{
+ if (mDirtySamplers.none())
+ return angle::Result::Continue;
+
+ for (size_t samplerIndex : mDirtySamplers)
+ {
+ BindingPointer<Sampler> &sampler = mSamplers[samplerIndex];
+ if (sampler.get() && sampler->isDirty())
+ {
+ ANGLE_TRY(sampler->syncState(context));
+ }
+ }
+
+ mDirtySamplers.reset();
+
+ return angle::Result::Continue;
+}
+
+angle::Result State::syncVertexArray(const Context *context, Command command)
+{
+ ASSERT(mVertexArray);
+ return mVertexArray->syncState(context);
+}
+
+angle::Result State::syncProgram(const Context *context, Command command)
+{
+ // There may not be a program if the calling application only uses program pipelines.
+ if (mProgram)
+ {
+ return mProgram->syncState(context);
+ }
+ return angle::Result::Continue;
+}
+
+angle::Result State::syncProgramPipelineObject(const Context *context, Command command)
+{
+ // If a ProgramPipeline is bound, ensure it is linked.
+ if (mProgramPipeline.get())
+ {
+ mProgramPipeline->resolveLink(context);
+ }
+ return angle::Result::Continue;
+}
+
+angle::Result State::syncDirtyObject(const Context *context, GLenum target)
+{
+ DirtyObjects localSet;
+
+ switch (target)
+ {
+ case GL_READ_FRAMEBUFFER:
+ localSet.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
+ break;
+ case GL_DRAW_FRAMEBUFFER:
+ localSet.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
+ break;
+ case GL_FRAMEBUFFER:
+ localSet.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
+ localSet.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
+ break;
+ case GL_VERTEX_ARRAY:
+ localSet.set(DIRTY_OBJECT_VERTEX_ARRAY);
+ break;
+ case GL_TEXTURE:
+ localSet.set(DIRTY_OBJECT_TEXTURES);
+ break;
+ case GL_SAMPLER:
+ localSet.set(DIRTY_OBJECT_SAMPLERS);
+ break;
+ case GL_PROGRAM:
+ localSet.set(DIRTY_OBJECT_PROGRAM);
+ break;
+ }
+
+ return syncDirtyObjects(context, localSet, Command::Other);
+}
+
+void State::setObjectDirty(GLenum target)
+{
+ switch (target)
+ {
+ case GL_READ_FRAMEBUFFER:
+ mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
+ break;
+ case GL_DRAW_FRAMEBUFFER:
+ setDrawFramebufferDirty();
+ break;
+ case GL_FRAMEBUFFER:
+ mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
+ setDrawFramebufferDirty();
+ break;
+ case GL_VERTEX_ARRAY:
+ mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
+ break;
+ case GL_PROGRAM:
+ mDirtyObjects.set(DIRTY_OBJECT_PROGRAM);
+ break;
+ default:
+ break;
+ }
+}
+
+angle::Result State::onProgramExecutableChange(const Context *context, Program *program)
+{
+ // OpenGL Spec:
+ // "If LinkProgram or ProgramBinary successfully re-links a program object
+ // that was already in use as a result of a previous call to UseProgram, then the
+ // generated executable code will be installed as part of the current rendering state."
+ ASSERT(program->isLinked());
+
+ // If this Program is currently active, we need to update the State's pointer to the current
+ // ProgramExecutable if we just changed it.
+ if (mProgram == program)
+ {
+ mExecutable = &program->getExecutable();
+ }
+
+ mDirtyBits.set(DIRTY_BIT_PROGRAM_EXECUTABLE);
+
+ if (program->hasAnyDirtyBit())
+ {
+ mDirtyObjects.set(DIRTY_OBJECT_PROGRAM);
+ }
+
+ // Set any bound textures.
+ const ProgramExecutable &executable = program->getExecutable();
+ const ActiveTextureTypeArray &textureTypes = executable.getActiveSamplerTypes();
+ for (size_t textureIndex : executable.getActiveSamplersMask())
+ {
+ TextureType type = textureTypes[textureIndex];
+
+ // This can happen if there is a conflicting texture type.
+ if (type == TextureType::InvalidEnum)
+ continue;
+
+ Texture *texture = getTextureForActiveSampler(type, textureIndex);
+ updateTextureBinding(context, textureIndex, texture);
+ }
+
+ for (size_t imageUnitIndex : executable.getActiveImagesMask())
+ {
+ Texture *image = mImageUnits[imageUnitIndex].texture.get();
+ if (!image)
+ continue;
+
+ if (image->hasAnyDirtyBit())
+ {
+ ANGLE_TRY(image->syncState(context, Command::Other));
+ }
+
+ if (mRobustResourceInit && image->initState() == InitState::MayNeedInit)
+ {
+ mDirtyObjects.set(DIRTY_OBJECT_IMAGES_INIT);
+ }
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result State::onProgramPipelineExecutableChange(const Context *context)
+{
+ mDirtyBits.set(DIRTY_BIT_PROGRAM_EXECUTABLE);
+
+ if (!mProgramPipeline->isLinked())
+ {
+ mDirtyObjects.set(DIRTY_OBJECT_PROGRAM_PIPELINE_OBJECT);
+ }
+
+ // Set any bound textures.
+ const ProgramExecutable &executable = mProgramPipeline->getExecutable();
+ const ActiveTextureTypeArray &textureTypes = executable.getActiveSamplerTypes();
+
+ for (size_t textureIndex : executable.getActiveSamplersMask())
+ {
+ TextureType type = textureTypes[textureIndex];
+
+ // This can happen if there is a conflicting texture type.
+ if (type == TextureType::InvalidEnum)
+ continue;
+
+ Texture *texture = getTextureForActiveSampler(type, textureIndex);
+ updateTextureBinding(context, textureIndex, texture);
+ }
+
+ for (size_t imageUnitIndex : executable.getActiveImagesMask())
+ {
+ Texture *image = mImageUnits[imageUnitIndex].texture.get();
+ if (!image)
+ continue;
+
+ if (image->hasAnyDirtyBit())
+ {
+ ANGLE_TRY(image->syncState(context, Command::Other));
+ }
+
+ if (mRobustResourceInit && image->initState() == InitState::MayNeedInit)
+ {
+ mDirtyObjects.set(DIRTY_OBJECT_IMAGES_INIT);
+ }
+ }
+
+ return angle::Result::Continue;
+}
+
+void State::setTextureDirty(size_t textureUnitIndex)
+{
+ mDirtyObjects.set(DIRTY_OBJECT_TEXTURES);
+ mDirtyTextures.set(textureUnitIndex);
+}
+
+void State::setSamplerDirty(size_t samplerIndex)
+{
+ mDirtyObjects.set(DIRTY_OBJECT_SAMPLERS);
+ mDirtySamplers.set(samplerIndex);
+}
+
+void State::setImageUnit(const Context *context,
+ size_t unit,
+ Texture *texture,
+ GLint level,
+ GLboolean layered,
+ GLint layer,
+ GLenum access,
+ GLenum format)
+{
+ ASSERT(!mImageUnits.empty());
+
+ ImageUnit &imageUnit = mImageUnits[unit];
+
+ if (texture)
+ {
+ texture->onBindAsImageTexture();
+
+ // Using individual layers of a 3d image as 2d may require that the image be respecified in
+ // a compatible layout
+ if (!layered && texture->getType() == TextureType::_3D)
+ {
+ texture->onBind3DTextureAs2DImage();
+ }
+ }
+ imageUnit.texture.set(context, texture);
+ imageUnit.level = level;
+ imageUnit.layered = layered;
+ imageUnit.layer = layer;
+ imageUnit.access = access;
+ imageUnit.format = format;
+ mDirtyBits.set(DIRTY_BIT_IMAGE_BINDINGS);
+
+ onImageStateChange(context, unit);
+}
+
+// Handle a dirty texture event.
+void State::onActiveTextureChange(const Context *context, size_t textureUnit)
+{
+ if (mExecutable)
+ {
+ TextureType type = mExecutable->getActiveSamplerTypes()[textureUnit];
+ Texture *activeTexture = (type != TextureType::InvalidEnum)
+ ? getTextureForActiveSampler(type, textureUnit)
+ : nullptr;
+ updateTextureBinding(context, textureUnit, activeTexture);
+
+ mExecutable->onStateChange(angle::SubjectMessage::ProgramTextureOrImageBindingChanged);
+ }
+}
+
+void State::onActiveTextureStateChange(const Context *context, size_t textureUnit)
+{
+ if (mExecutable)
+ {
+ TextureType type = mExecutable->getActiveSamplerTypes()[textureUnit];
+ Texture *activeTexture = (type != TextureType::InvalidEnum)
+ ? getTextureForActiveSampler(type, textureUnit)
+ : nullptr;
+ setActiveTextureDirty(textureUnit, activeTexture);
+ }
+}
+
+void State::onImageStateChange(const Context *context, size_t unit)
+{
+ if (mExecutable)
+ {
+ const ImageUnit &image = mImageUnits[unit];
+
+ // Have nothing to do here if no texture bound
+ if (!image.texture.get())
+ return;
+
+ if (image.texture->hasAnyDirtyBit())
+ {
+ mDirtyImages.set(unit);
+ mDirtyObjects.set(DIRTY_OBJECT_IMAGES);
+ }
+
+ if (mRobustResourceInit && image.texture->initState() == InitState::MayNeedInit)
+ {
+ mDirtyObjects.set(DIRTY_OBJECT_IMAGES_INIT);
+ }
+
+ mExecutable->onStateChange(angle::SubjectMessage::ProgramTextureOrImageBindingChanged);
+ }
+}
+
+void State::onUniformBufferStateChange(size_t uniformBufferIndex)
+{
+ // This could be represented by a different dirty bit. Using the same one keeps it simple.
+ mDirtyBits.set(DIRTY_BIT_UNIFORM_BUFFER_BINDINGS);
+}
+
+void State::onAtomicCounterBufferStateChange(size_t atomicCounterBufferIndex)
+{
+ mDirtyBits.set(DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING);
+}
+
+void State::onShaderStorageBufferStateChange(size_t shaderStorageBufferIndex)
+{
+ mDirtyBits.set(DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING);
+}
+
+AttributesMask State::getAndResetDirtyCurrentValues() const
+{
+ AttributesMask retVal = mDirtyCurrentValues;
+ mDirtyCurrentValues.reset();
+ return retVal;
+}
+
+State::ExtendedDirtyBits State::getAndResetExtendedDirtyBits() const
+{
+ ExtendedDirtyBits retVal = mExtendedDirtyBits;
+ mExtendedDirtyBits.reset();
+ return retVal;
+}
+
+void State::initializeForCapture(const Context *context)
+{
+ mCaps = context->getCaps();
+ mExtensions = context->getExtensions();
+
+ // This little kludge gets around the frame capture "constness". It should be safe because
+ // nothing in the context is modified in a non-compatible way during capture.
+ Context *mutableContext = const_cast<Context *>(context);
+ initialize(mutableContext);
+}
+
+void State::setLogicOpEnabled(bool enabled)
+{
+ if (mLogicOpEnabled != enabled)
+ {
+ mLogicOpEnabled = enabled;
+ mDirtyBits.set(DIRTY_BIT_EXTENDED);
+ mExtendedDirtyBits.set(EXTENDED_DIRTY_BIT_LOGIC_OP_ENABLED);
+ }
+}
+
+void State::setLogicOp(LogicalOperation opcode)
+{
+ if (mLogicOp != opcode)
+ {
+ mLogicOp = opcode;
+ mDirtyBits.set(DIRTY_BIT_EXTENDED);
+ mExtendedDirtyBits.set(EXTENDED_DIRTY_BIT_LOGIC_OP);
+ }
+}
+
+constexpr State::DirtyObjectHandler State::kDirtyObjectHandlers[DIRTY_OBJECT_MAX];
+
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/State.h b/gfx/angle/checkout/src/libANGLE/State.h
new file mode 100644
index 0000000000..08098599e1
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/State.h
@@ -0,0 +1,1258 @@
+//
+// 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.
+//
+
+// State.h: Defines the State class, encapsulating raw GL state
+
+#ifndef LIBANGLE_STATE_H_
+#define LIBANGLE_STATE_H_
+
+#include <bitset>
+#include <memory>
+
+#include "common/Color.h"
+#include "common/angleutils.h"
+#include "common/bitset_utils.h"
+#include "libANGLE/Debug.h"
+#include "libANGLE/GLES1State.h"
+#include "libANGLE/Overlay.h"
+#include "libANGLE/Program.h"
+#include "libANGLE/ProgramExecutable.h"
+#include "libANGLE/ProgramPipeline.h"
+#include "libANGLE/RefCountObject.h"
+#include "libANGLE/Renderbuffer.h"
+#include "libANGLE/Sampler.h"
+#include "libANGLE/Texture.h"
+#include "libANGLE/TransformFeedback.h"
+#include "libANGLE/Version.h"
+#include "libANGLE/VertexArray.h"
+#include "libANGLE/angletypes.h"
+
+namespace egl
+{
+class ShareGroup;
+} // namespace egl
+
+namespace gl
+{
+class BufferManager;
+struct Caps;
+class Context;
+class FramebufferManager;
+class MemoryObjectManager;
+class ProgramPipelineManager;
+class Query;
+class RenderbufferManager;
+class SamplerManager;
+class SemaphoreManager;
+class ShaderProgramManager;
+class SyncManager;
+class TextureManager;
+class VertexArray;
+
+static constexpr Version ES_1_0 = Version(1, 0);
+static constexpr Version ES_1_1 = Version(1, 1);
+static constexpr Version ES_2_0 = Version(2, 0);
+static constexpr Version ES_3_0 = Version(3, 0);
+static constexpr Version ES_3_1 = Version(3, 1);
+static constexpr Version ES_3_2 = Version(3, 2);
+
+template <typename T>
+using BufferBindingMap = angle::PackedEnumMap<BufferBinding, T>;
+using BoundBufferMap = BufferBindingMap<BindingPointer<Buffer>>;
+using TextureBindingVector = std::vector<BindingPointer<Texture>>;
+using TextureBindingMap = angle::PackedEnumMap<TextureType, TextureBindingVector>;
+using ActiveQueryMap = angle::PackedEnumMap<QueryType, BindingPointer<Query>>;
+
+class ActiveTexturesCache final : angle::NonCopyable
+{
+ public:
+ ActiveTexturesCache();
+ ~ActiveTexturesCache();
+
+ Texture *operator[](size_t textureIndex) const { return mTextures[textureIndex]; }
+
+ void clear();
+ void set(size_t textureIndex, Texture *texture);
+ void reset(size_t textureIndex);
+ bool empty() const;
+ size_t size() const { return mTextures.size(); }
+
+ private:
+ ActiveTextureArray<Texture *> mTextures;
+};
+
+class State : angle::NonCopyable
+{
+ public:
+ State(const State *shareContextState,
+ egl::ShareGroup *shareGroup,
+ TextureManager *shareTextures,
+ SemaphoreManager *shareSemaphores,
+ const OverlayType *overlay,
+ const EGLenum clientType,
+ const Version &clientVersion,
+ EGLint profileMask,
+ bool debug,
+ bool bindGeneratesResourceCHROMIUM,
+ bool clientArraysEnabled,
+ bool robustResourceInit,
+ bool programBinaryCacheEnabled,
+ EGLenum contextPriority,
+ bool hasRobustAccess,
+ bool hasProtectedContent);
+ ~State();
+
+ void initialize(Context *context);
+ void reset(const Context *context);
+
+ // Getters
+ ContextID getContextID() const { return mID; }
+ EGLenum getClientType() const { return mClientType; }
+ EGLint getProfileMask() const { return mProfileMask; }
+ EGLenum getContextPriority() const { return mContextPriority; }
+ bool hasRobustAccess() const { return mHasRobustAccess; }
+ bool hasProtectedContent() const { return mHasProtectedContent; }
+ bool isDebugContext() const { return mIsDebugContext; }
+ GLint getClientMajorVersion() const { return mClientVersion.major; }
+ GLint getClientMinorVersion() const { return mClientVersion.minor; }
+ const Version &getClientVersion() const { return mClientVersion; }
+ const Caps &getCaps() const { return mCaps; }
+ const TextureCapsMap &getTextureCaps() const { return mTextureCaps; }
+ const Extensions &getExtensions() const { return mExtensions; }
+ const Limitations &getLimitations() const { return mLimitations; }
+ egl::ShareGroup *getShareGroup() const { return mShareGroup; }
+
+ bool isWebGL() const { return mExtensions.webglCompatibilityANGLE; }
+
+ bool isWebGL1() const { return (isWebGL() && mClientVersion.major == 2); }
+
+ bool isGLES1() const { return mClientVersion < ES_2_0; }
+
+ const TextureCaps &getTextureCap(GLenum internalFormat) const
+ {
+ return mTextureCaps.get(internalFormat);
+ }
+
+ // State chunk getters
+ bool allActiveDrawBufferChannelsMasked() const;
+ bool anyActiveDrawBufferChannelMasked() const;
+ const RasterizerState &getRasterizerState() const;
+ const BlendState &getBlendState() const { return mBlendState; }
+ const BlendStateExt &getBlendStateExt() const { return mBlendStateExt; }
+ const DepthStencilState &getDepthStencilState() const;
+
+ // Clear behavior setters & state parameter block generation function
+ void setColorClearValue(float red, float green, float blue, float alpha);
+ void setDepthClearValue(float depth);
+ void setStencilClearValue(int stencil);
+
+ const ColorF &getColorClearValue() const { return mColorClearValue; }
+ float getDepthClearValue() const { return mDepthClearValue; }
+ int getStencilClearValue() const { return mStencilClearValue; }
+
+ // Write mask manipulation
+ void setColorMask(bool red, bool green, bool blue, bool alpha);
+ void setColorMaskIndexed(bool red, bool green, bool blue, bool alpha, GLuint index);
+ void setDepthMask(bool mask);
+
+ // Discard toggle & query
+ bool isRasterizerDiscardEnabled() const { return mRasterizer.rasterizerDiscard; }
+ void setRasterizerDiscard(bool enabled);
+
+ // Primitive restart
+ bool isPrimitiveRestartEnabled() const { return mPrimitiveRestart; }
+ void setPrimitiveRestart(bool enabled);
+
+ // Face culling state manipulation
+ bool isCullFaceEnabled() const { return mRasterizer.cullFace; }
+ void setCullFace(bool enabled);
+ void setCullMode(CullFaceMode mode);
+ void setFrontFace(GLenum front);
+
+ // Depth test state manipulation
+ bool isDepthTestEnabled() const { return mDepthStencil.depthTest; }
+ bool isDepthWriteEnabled() const { return mDepthStencil.depthTest && mDepthStencil.depthMask; }
+ void setDepthTest(bool enabled);
+ void setDepthFunc(GLenum depthFunc);
+ void setDepthRange(float zNear, float zFar);
+ float getNearPlane() const { return mNearZ; }
+ float getFarPlane() const { return mFarZ; }
+
+ // Clip control extension
+ void setClipControl(GLenum origin, GLenum depth);
+ bool isClipControlDepthZeroToOne() const { return mClipControlDepth == GL_ZERO_TO_ONE_EXT; }
+ gl::ClipSpaceOrigin getClipSpaceOrigin() const
+ {
+ return mClipControlOrigin == GL_UPPER_LEFT_EXT ? ClipSpaceOrigin::UpperLeft
+ : ClipSpaceOrigin::LowerLeft;
+ }
+
+ // Blend state manipulation
+ bool isBlendEnabled() const { return mBlendStateExt.getEnabledMask().test(0); }
+ bool isBlendEnabledIndexed(GLuint index) const
+ {
+ ASSERT(static_cast<size_t>(index) < mBlendStateExt.getDrawBufferCount());
+ return mBlendStateExt.getEnabledMask().test(index);
+ }
+ DrawBufferMask getBlendEnabledDrawBufferMask() const { return mBlendStateExt.getEnabledMask(); }
+ void setBlend(bool enabled);
+ void setBlendIndexed(bool enabled, GLuint index);
+ void setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha);
+ void setBlendFactorsIndexed(GLenum sourceRGB,
+ GLenum destRGB,
+ GLenum sourceAlpha,
+ GLenum destAlpha,
+ GLuint index);
+ void setBlendColor(float red, float green, float blue, float alpha);
+ void setBlendEquation(GLenum rgbEquation, GLenum alphaEquation);
+ void setBlendEquationIndexed(GLenum rgbEquation, GLenum alphaEquation, GLuint index);
+ const ColorF &getBlendColor() const { return mBlendColor; }
+
+ // Stencil state maniupulation
+ bool isStencilTestEnabled() const { return mDepthStencil.stencilTest; }
+ void setStencilTest(bool enabled);
+ void setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask);
+ void setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask);
+ void setStencilWritemask(GLuint stencilWritemask);
+ void setStencilBackWritemask(GLuint stencilBackWritemask);
+ void setStencilOperations(GLenum stencilFail,
+ GLenum stencilPassDepthFail,
+ GLenum stencilPassDepthPass);
+ void setStencilBackOperations(GLenum stencilBackFail,
+ GLenum stencilBackPassDepthFail,
+ GLenum stencilBackPassDepthPass);
+ GLint getStencilRef() const { return mStencilRef; }
+ GLint getStencilBackRef() const { return mStencilBackRef; }
+
+ // Depth bias/polygon offset state manipulation
+ bool isPolygonOffsetFillEnabled() const { return mRasterizer.polygonOffsetFill; }
+ void setPolygonOffsetFill(bool enabled);
+ void setPolygonOffsetParams(GLfloat factor, GLfloat units);
+
+ // Multisample coverage state manipulation
+ bool isSampleAlphaToCoverageEnabled() const { return mSampleAlphaToCoverage; }
+ void setSampleAlphaToCoverage(bool enabled);
+ bool isSampleCoverageEnabled() const { return mSampleCoverage; }
+ void setSampleCoverage(bool enabled);
+ void setSampleCoverageParams(GLclampf value, bool invert);
+ GLclampf getSampleCoverageValue() const { return mSampleCoverageValue; }
+ bool getSampleCoverageInvert() const { return mSampleCoverageInvert; }
+
+ // Multisample mask state manipulation.
+ bool isSampleMaskEnabled() const { return mSampleMask; }
+ void setSampleMaskEnabled(bool enabled);
+ void setSampleMaskParams(GLuint maskNumber, GLbitfield mask);
+ GLbitfield getSampleMaskWord(GLuint maskNumber) const
+ {
+ ASSERT(maskNumber < mMaxSampleMaskWords);
+ return mSampleMaskValues[maskNumber];
+ }
+ SampleMaskArray<GLbitfield> getSampleMaskValues() const { return mSampleMaskValues; }
+ GLuint getMaxSampleMaskWords() const { return mMaxSampleMaskWords; }
+
+ // Multisampling/alpha to one manipulation.
+ void setSampleAlphaToOne(bool enabled);
+ bool isSampleAlphaToOneEnabled() const { return mSampleAlphaToOne; }
+ void setMultisampling(bool enabled);
+ bool isMultisamplingEnabled() const { return mMultiSampling; }
+
+ void setSampleShading(bool enabled);
+ bool isSampleShadingEnabled() const { return mIsSampleShadingEnabled; }
+ void setMinSampleShading(float value);
+ float getMinSampleShading() const { return mMinSampleShading; }
+
+ // Scissor test state toggle & query
+ bool isScissorTestEnabled() const { return mScissorTest; }
+ void setScissorTest(bool enabled);
+ void setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height);
+ const Rectangle &getScissor() const { return mScissor; }
+
+ // Dither state toggle & query
+ bool isDitherEnabled() const { return mRasterizer.dither; }
+ void setDither(bool enabled);
+
+ // Generic state toggle & query
+ void setEnableFeature(GLenum feature, bool enabled);
+ void setEnableFeatureIndexed(GLenum feature, bool enabled, GLuint index);
+ bool getEnableFeature(GLenum feature) const;
+ bool getEnableFeatureIndexed(GLenum feature, GLuint index) const;
+
+ // Line width state setter
+ void setLineWidth(GLfloat width);
+ float getLineWidth() const { return mLineWidth; }
+
+ // Hint setters
+ void setGenerateMipmapHint(GLenum hint);
+ GLenum getGenerateMipmapHint() const;
+ void setTextureFilteringHint(GLenum hint);
+ GLenum getTextureFilteringHint() const;
+ GLenum getFragmentShaderDerivativeHint() const { return mFragmentShaderDerivativeHint; }
+ void setFragmentShaderDerivativeHint(GLenum hint);
+
+ // GL_CHROMIUM_bind_generates_resource
+ bool isBindGeneratesResourceEnabled() const { return mBindGeneratesResource; }
+
+ // GL_ANGLE_client_arrays
+ bool areClientArraysEnabled() const { return mClientArraysEnabled; }
+
+ // Viewport state setter/getter
+ void setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height);
+ const Rectangle &getViewport() const { return mViewport; }
+
+ // Texture binding & active texture unit manipulation
+ void setActiveSampler(unsigned int active);
+ unsigned int getActiveSampler() const { return static_cast<unsigned int>(mActiveSampler); }
+
+ void setSamplerTexture(const Context *context, TextureType type, Texture *texture);
+ Texture *getTargetTexture(TextureType type) const;
+
+ Texture *getSamplerTexture(unsigned int sampler, TextureType type) const
+ {
+ ASSERT(sampler < mSamplerTextures[type].size());
+ return mSamplerTextures[type][sampler].get();
+ }
+
+ TextureID getSamplerTextureId(unsigned int sampler, TextureType type) const;
+ void detachTexture(const Context *context, const TextureMap &zeroTextures, TextureID texture);
+ void initializeZeroTextures(const Context *context, const TextureMap &zeroTextures);
+
+ void invalidateTextureBindings(TextureType type);
+
+ // Sampler object binding manipulation
+ void setSamplerBinding(const Context *context, GLuint textureUnit, Sampler *sampler);
+ SamplerID getSamplerId(GLuint textureUnit) const
+ {
+ ASSERT(textureUnit < mSamplers.size());
+ return mSamplers[textureUnit].id();
+ }
+
+ Sampler *getSampler(GLuint textureUnit) const { return mSamplers[textureUnit].get(); }
+
+ const SamplerBindingVector &getSamplers() const { return mSamplers; }
+
+ void detachSampler(const Context *context, SamplerID sampler);
+
+ // Renderbuffer binding manipulation
+ void setRenderbufferBinding(const Context *context, Renderbuffer *renderbuffer);
+ RenderbufferID getRenderbufferId() const { return mRenderbuffer.id(); }
+ Renderbuffer *getCurrentRenderbuffer() const { return mRenderbuffer.get(); }
+ void detachRenderbuffer(const Context *context, RenderbufferID renderbuffer);
+
+ // Framebuffer binding manipulation
+ void setReadFramebufferBinding(Framebuffer *framebuffer);
+ void setDrawFramebufferBinding(Framebuffer *framebuffer);
+ Framebuffer *getTargetFramebuffer(GLenum target) const;
+ Framebuffer *getReadFramebuffer() const { return mReadFramebuffer; }
+ Framebuffer *getDrawFramebuffer() const { return mDrawFramebuffer; }
+ Framebuffer *getDefaultFramebuffer() const;
+
+ bool removeReadFramebufferBinding(FramebufferID framebuffer);
+ bool removeDrawFramebufferBinding(FramebufferID framebuffer);
+
+ // Vertex array object binding manipulation
+ void setVertexArrayBinding(const Context *context, VertexArray *vertexArray);
+ bool removeVertexArrayBinding(const Context *context, VertexArrayID vertexArray);
+ VertexArrayID getVertexArrayId() const;
+
+ VertexArray *getVertexArray() const
+ {
+ ASSERT(mVertexArray != nullptr);
+ return mVertexArray;
+ }
+
+ // QCOM_shading_rate helpers
+ void setShadingRate(GLenum rate);
+ ShadingRate getShadingRate() const { return mShadingRate; }
+
+ // If both a Program and a ProgramPipeline are bound, the Program will
+ // always override the ProgramPipeline.
+ ProgramExecutable *getProgramExecutable() const { return mExecutable; }
+ ProgramExecutable *getLinkedProgramExecutable(const Context *context) const
+ {
+ if (mProgram)
+ {
+ mProgram->resolveLink(context);
+ }
+ else if (mProgramPipeline.get())
+ {
+ mProgramPipeline->resolveLink(context);
+ }
+ return mExecutable;
+ }
+
+ // Program binding manipulation
+ angle::Result setProgram(const Context *context, Program *newProgram);
+
+ Program *getProgram() const
+ {
+ ASSERT(!mProgram || !mProgram->isLinking());
+ return mProgram;
+ }
+
+ Program *getLinkedProgram(const Context *context) const
+ {
+ if (mProgram)
+ {
+ mProgram->resolveLink(context);
+ }
+ return mProgram;
+ }
+
+ ProgramPipeline *getProgramPipeline() const { return mProgramPipeline.get(); }
+
+ ProgramPipeline *getLinkedProgramPipeline(const Context *context) const
+ {
+ if (mProgramPipeline.get())
+ {
+ mProgramPipeline->resolveLink(context);
+ }
+ return mProgramPipeline.get();
+ }
+
+ // Transform feedback object (not buffer) binding manipulation
+ void setTransformFeedbackBinding(const Context *context, TransformFeedback *transformFeedback);
+ TransformFeedback *getCurrentTransformFeedback() const { return mTransformFeedback.get(); }
+
+ ANGLE_INLINE bool isTransformFeedbackActive() const
+ {
+ TransformFeedback *curTransformFeedback = mTransformFeedback.get();
+ return curTransformFeedback && curTransformFeedback->isActive();
+ }
+ ANGLE_INLINE bool isTransformFeedbackActiveUnpaused() const
+ {
+ TransformFeedback *curTransformFeedback = mTransformFeedback.get();
+ return curTransformFeedback && curTransformFeedback->isActive() &&
+ !curTransformFeedback->isPaused();
+ }
+
+ bool removeTransformFeedbackBinding(const Context *context,
+ TransformFeedbackID transformFeedback);
+
+ // Query binding manipulation
+ bool isQueryActive(QueryType type) const;
+ bool isQueryActive(Query *query) const;
+ void setActiveQuery(const Context *context, QueryType type, Query *query);
+ QueryID getActiveQueryId(QueryType type) const;
+ Query *getActiveQuery(QueryType type) const;
+
+ // Program Pipeline binding manipulation
+ angle::Result setProgramPipelineBinding(const Context *context, ProgramPipeline *pipeline);
+ void detachProgramPipeline(const Context *context, ProgramPipelineID pipeline);
+
+ //// Typed buffer binding point manipulation ////
+ ANGLE_INLINE void setBufferBinding(const Context *context, BufferBinding target, Buffer *buffer)
+ {
+ (this->*(kBufferSetters[target]))(context, buffer);
+ }
+
+ ANGLE_INLINE Buffer *getTargetBuffer(BufferBinding target) const
+ {
+ switch (target)
+ {
+ case BufferBinding::ElementArray:
+ return getVertexArray()->getElementArrayBuffer();
+ default:
+ return mBoundBuffers[target].get();
+ }
+ }
+
+ ANGLE_INLINE Buffer *getArrayBuffer() const { return getTargetBuffer(BufferBinding::Array); }
+
+ angle::Result setIndexedBufferBinding(const Context *context,
+ BufferBinding target,
+ GLuint index,
+ Buffer *buffer,
+ GLintptr offset,
+ GLsizeiptr size);
+
+ size_t getAtomicCounterBufferCount() const { return mAtomicCounterBuffers.size(); }
+
+ ANGLE_INLINE bool hasValidAtomicCounterBuffer() const
+ {
+ return mBoundAtomicCounterBuffersMask.any();
+ }
+
+ const OffsetBindingPointer<Buffer> &getIndexedUniformBuffer(size_t index) const;
+ const OffsetBindingPointer<Buffer> &getIndexedAtomicCounterBuffer(size_t index) const;
+ const OffsetBindingPointer<Buffer> &getIndexedShaderStorageBuffer(size_t index) const;
+
+ const angle::BitSet<gl::IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS> &getUniformBuffersMask()
+ const
+ {
+ return mBoundUniformBuffersMask;
+ }
+ const angle::BitSet<gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS>
+ &getAtomicCounterBuffersMask() const
+ {
+ return mBoundAtomicCounterBuffersMask;
+ }
+ const angle::BitSet<gl::IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS>
+ &getShaderStorageBuffersMask() const
+ {
+ return mBoundShaderStorageBuffersMask;
+ }
+
+ // Detach a buffer from all bindings
+ angle::Result detachBuffer(Context *context, const Buffer *buffer);
+
+ // Vertex attrib manipulation
+ void setEnableVertexAttribArray(unsigned int attribNum, bool enabled);
+ void setVertexAttribf(GLuint index, const GLfloat values[4]);
+ void setVertexAttribu(GLuint index, const GLuint values[4]);
+ void setVertexAttribi(GLuint index, const GLint values[4]);
+
+ ANGLE_INLINE void setVertexAttribPointer(const Context *context,
+ unsigned int attribNum,
+ Buffer *boundBuffer,
+ GLint size,
+ VertexAttribType type,
+ bool normalized,
+ GLsizei stride,
+ const void *pointer)
+ {
+ mVertexArray->setVertexAttribPointer(context, attribNum, boundBuffer, size, type,
+ normalized, stride, pointer);
+ mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
+ }
+
+ ANGLE_INLINE void setVertexAttribIPointer(const Context *context,
+ unsigned int attribNum,
+ Buffer *boundBuffer,
+ GLint size,
+ VertexAttribType type,
+ GLsizei stride,
+ const void *pointer)
+ {
+ mVertexArray->setVertexAttribIPointer(context, attribNum, boundBuffer, size, type, stride,
+ pointer);
+ mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
+ }
+
+ void setVertexAttribDivisor(const Context *context, GLuint index, GLuint divisor);
+ const VertexAttribCurrentValueData &getVertexAttribCurrentValue(size_t attribNum) const
+ {
+ ASSERT(attribNum < mVertexAttribCurrentValues.size());
+ return mVertexAttribCurrentValues[attribNum];
+ }
+
+ const std::vector<VertexAttribCurrentValueData> &getVertexAttribCurrentValues() const
+ {
+ return mVertexAttribCurrentValues;
+ }
+
+ const void *getVertexAttribPointer(unsigned int attribNum) const;
+
+ void bindVertexBuffer(const Context *context,
+ GLuint bindingIndex,
+ Buffer *boundBuffer,
+ GLintptr offset,
+ GLsizei stride);
+ void setVertexAttribFormat(GLuint attribIndex,
+ GLint size,
+ VertexAttribType type,
+ bool normalized,
+ bool pureInteger,
+ GLuint relativeOffset);
+
+ void setVertexAttribBinding(const Context *context, GLuint attribIndex, GLuint bindingIndex)
+ {
+ mVertexArray->setVertexAttribBinding(context, attribIndex, bindingIndex);
+ mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
+ }
+
+ void setVertexBindingDivisor(const Context *context, GLuint bindingIndex, GLuint divisor);
+
+ // Pixel pack state manipulation
+ void setPackAlignment(GLint alignment);
+ GLint getPackAlignment() const { return mPack.alignment; }
+ void setPackReverseRowOrder(bool reverseRowOrder);
+ bool getPackReverseRowOrder() const { return mPack.reverseRowOrder; }
+ void setPackRowLength(GLint rowLength);
+ GLint getPackRowLength() const { return mPack.rowLength; }
+ void setPackSkipRows(GLint skipRows);
+ GLint getPackSkipRows() const { return mPack.skipRows; }
+ void setPackSkipPixels(GLint skipPixels);
+ GLint getPackSkipPixels() const { return mPack.skipPixels; }
+ const PixelPackState &getPackState() const { return mPack; }
+ PixelPackState &getPackState() { return mPack; }
+
+ // Pixel unpack state manipulation
+ void setUnpackAlignment(GLint alignment);
+ GLint getUnpackAlignment() const { return mUnpack.alignment; }
+ void setUnpackRowLength(GLint rowLength);
+ GLint getUnpackRowLength() const { return mUnpack.rowLength; }
+ void setUnpackImageHeight(GLint imageHeight);
+ GLint getUnpackImageHeight() const { return mUnpack.imageHeight; }
+ void setUnpackSkipImages(GLint skipImages);
+ GLint getUnpackSkipImages() const { return mUnpack.skipImages; }
+ void setUnpackSkipRows(GLint skipRows);
+ GLint getUnpackSkipRows() const { return mUnpack.skipRows; }
+ void setUnpackSkipPixels(GLint skipPixels);
+ GLint getUnpackSkipPixels() const { return mUnpack.skipPixels; }
+ const PixelUnpackState &getUnpackState() const { return mUnpack; }
+ PixelUnpackState &getUnpackState() { return mUnpack; }
+
+ // Debug state
+ const Debug &getDebug() const { return mDebug; }
+ Debug &getDebug() { return mDebug; }
+
+ // CHROMIUM_framebuffer_mixed_samples coverage modulation
+ void setCoverageModulation(GLenum components);
+ GLenum getCoverageModulation() const { return mCoverageModulation; }
+
+ // GL_EXT_sRGB_write_control
+ void setFramebufferSRGB(bool sRGB);
+ bool getFramebufferSRGB() const { return mFramebufferSRGB; }
+
+ // GL_KHR_parallel_shader_compile
+ void setMaxShaderCompilerThreads(GLuint count);
+ GLuint getMaxShaderCompilerThreads() const { return mMaxShaderCompilerThreads; }
+
+ // GL_EXT_tessellation_shader
+ void setPatchVertices(GLuint value);
+ GLuint getPatchVertices() const { return mPatchVertices; }
+
+ // GL_ANGLE_shader_pixel_local_storage
+ void setPixelLocalStorageActive(bool active);
+ bool getPixelLocalStorageActive() const { return mPixelLocalStorageActive; }
+
+ // State query functions
+ void getBooleanv(GLenum pname, GLboolean *params) const;
+ void getFloatv(GLenum pname, GLfloat *params) const;
+ angle::Result getIntegerv(const Context *context, GLenum pname, GLint *params) const;
+ void getPointerv(const Context *context, GLenum pname, void **params) const;
+ void getIntegeri_v(const Context *context, GLenum target, GLuint index, GLint *data) const;
+ void getInteger64i_v(GLenum target, GLuint index, GLint64 *data) const;
+ void getBooleani_v(GLenum target, GLuint index, GLboolean *data) const;
+
+ bool isRobustResourceInitEnabled() const { return mRobustResourceInit; }
+
+ bool isDrawFramebufferBindingDirty() const
+ {
+ return mDirtyBits.test(DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
+ }
+
+ // Sets the dirty bit for the program executable.
+ angle::Result onProgramExecutableChange(const Context *context, Program *program);
+ // Sets the dirty bit for the program pipeline executable.
+ angle::Result onProgramPipelineExecutableChange(const Context *context);
+
+ enum DirtyBitType
+ {
+ // Note: process draw framebuffer binding first, so that other dirty bits whose effect
+ // depend on the current draw framebuffer are not processed while the old framebuffer is
+ // still bound.
+ DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING,
+ DIRTY_BIT_READ_FRAMEBUFFER_BINDING,
+ DIRTY_BIT_SCISSOR_TEST_ENABLED,
+ DIRTY_BIT_SCISSOR,
+ DIRTY_BIT_VIEWPORT,
+ DIRTY_BIT_DEPTH_RANGE,
+ DIRTY_BIT_BLEND_ENABLED,
+ DIRTY_BIT_BLEND_COLOR,
+ DIRTY_BIT_BLEND_FUNCS,
+ DIRTY_BIT_BLEND_EQUATIONS,
+ DIRTY_BIT_COLOR_MASK,
+ DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED,
+ DIRTY_BIT_SAMPLE_COVERAGE_ENABLED,
+ DIRTY_BIT_SAMPLE_COVERAGE,
+ DIRTY_BIT_SAMPLE_MASK_ENABLED,
+ DIRTY_BIT_SAMPLE_MASK,
+ DIRTY_BIT_DEPTH_TEST_ENABLED,
+ DIRTY_BIT_DEPTH_FUNC,
+ DIRTY_BIT_DEPTH_MASK,
+ DIRTY_BIT_STENCIL_TEST_ENABLED,
+ DIRTY_BIT_STENCIL_FUNCS_FRONT,
+ DIRTY_BIT_STENCIL_FUNCS_BACK,
+ DIRTY_BIT_STENCIL_OPS_FRONT,
+ DIRTY_BIT_STENCIL_OPS_BACK,
+ DIRTY_BIT_STENCIL_WRITEMASK_FRONT,
+ DIRTY_BIT_STENCIL_WRITEMASK_BACK,
+ DIRTY_BIT_CULL_FACE_ENABLED,
+ DIRTY_BIT_CULL_FACE,
+ DIRTY_BIT_FRONT_FACE,
+ DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED,
+ DIRTY_BIT_POLYGON_OFFSET,
+ DIRTY_BIT_RASTERIZER_DISCARD_ENABLED,
+ DIRTY_BIT_LINE_WIDTH,
+ DIRTY_BIT_PRIMITIVE_RESTART_ENABLED,
+ DIRTY_BIT_CLEAR_COLOR,
+ DIRTY_BIT_CLEAR_DEPTH,
+ DIRTY_BIT_CLEAR_STENCIL,
+ DIRTY_BIT_UNPACK_STATE,
+ DIRTY_BIT_UNPACK_BUFFER_BINDING,
+ DIRTY_BIT_PACK_STATE,
+ DIRTY_BIT_PACK_BUFFER_BINDING,
+ DIRTY_BIT_DITHER_ENABLED,
+ DIRTY_BIT_RENDERBUFFER_BINDING,
+ DIRTY_BIT_VERTEX_ARRAY_BINDING,
+ DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING,
+ DIRTY_BIT_DISPATCH_INDIRECT_BUFFER_BINDING,
+ // TODO(jmadill): Fine-grained dirty bits for each index.
+ DIRTY_BIT_PROGRAM_BINDING, // Must be before DIRTY_BIT_PROGRAM_EXECUTABLE
+ DIRTY_BIT_PROGRAM_EXECUTABLE,
+ // TODO(jmadill): Fine-grained dirty bits for each texture/sampler.
+ DIRTY_BIT_SAMPLER_BINDINGS,
+ DIRTY_BIT_TEXTURE_BINDINGS,
+ DIRTY_BIT_IMAGE_BINDINGS,
+ DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING,
+ DIRTY_BIT_UNIFORM_BUFFER_BINDINGS,
+ DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING,
+ DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING,
+ DIRTY_BIT_MULTISAMPLING,
+ DIRTY_BIT_SAMPLE_ALPHA_TO_ONE,
+ DIRTY_BIT_COVERAGE_MODULATION, // CHROMIUM_framebuffer_mixed_samples
+ DIRTY_BIT_FRAMEBUFFER_SRGB_WRITE_CONTROL_MODE, // GL_EXT_sRGB_write_control
+ DIRTY_BIT_CURRENT_VALUES,
+ DIRTY_BIT_PROVOKING_VERTEX,
+ DIRTY_BIT_SAMPLE_SHADING,
+ DIRTY_BIT_PATCH_VERTICES,
+ DIRTY_BIT_EXTENDED, // clip distances, mipmap generation hint, derivative hint,
+ // EXT_clip_control
+ DIRTY_BIT_INVALID,
+ DIRTY_BIT_MAX = DIRTY_BIT_INVALID,
+ };
+
+ static_assert(DIRTY_BIT_MAX <= 64, "State dirty bits must be capped at 64");
+
+ enum ExtendedDirtyBitType
+ {
+ EXTENDED_DIRTY_BIT_CLIP_CONTROL, // EXT_clip_control
+ EXTENDED_DIRTY_BIT_CLIP_DISTANCES, // clip distances
+ EXTENDED_DIRTY_BIT_MIPMAP_GENERATION_HINT, // mipmap generation hint
+ EXTENDED_DIRTY_BIT_SHADER_DERIVATIVE_HINT, // shader derivative hint
+ EXTENDED_DIRTY_BIT_SHADING_RATE, // QCOM_shading_rate
+ EXTENDED_DIRTY_BIT_LOGIC_OP_ENABLED, // ANGLE_logic_op
+ EXTENDED_DIRTY_BIT_LOGIC_OP, // ANGLE_logic_op
+ EXTENDED_DIRTY_BIT_INVALID,
+ EXTENDED_DIRTY_BIT_MAX = EXTENDED_DIRTY_BIT_INVALID,
+ };
+
+ static_assert(EXTENDED_DIRTY_BIT_MAX <= 32, "State extended dirty bits must be capped at 32");
+
+ // TODO(jmadill): Consider storing dirty objects in a list instead of by binding.
+ enum DirtyObjectType
+ {
+ DIRTY_OBJECT_ACTIVE_TEXTURES, // Top-level dirty bit. Also see mDirtyActiveTextures.
+ DIRTY_OBJECT_TEXTURES_INIT,
+ DIRTY_OBJECT_IMAGES_INIT,
+ DIRTY_OBJECT_READ_ATTACHMENTS,
+ DIRTY_OBJECT_DRAW_ATTACHMENTS,
+ DIRTY_OBJECT_READ_FRAMEBUFFER,
+ DIRTY_OBJECT_DRAW_FRAMEBUFFER,
+ DIRTY_OBJECT_VERTEX_ARRAY,
+ DIRTY_OBJECT_TEXTURES, // Top-level dirty bit. Also see mDirtyTextures.
+ DIRTY_OBJECT_IMAGES, // Top-level dirty bit. Also see mDirtyImages.
+ DIRTY_OBJECT_SAMPLERS, // Top-level dirty bit. Also see mDirtySamplers.
+ DIRTY_OBJECT_PROGRAM,
+ DIRTY_OBJECT_PROGRAM_PIPELINE_OBJECT,
+ DIRTY_OBJECT_UNKNOWN,
+ DIRTY_OBJECT_MAX = DIRTY_OBJECT_UNKNOWN,
+ };
+
+ using DirtyBits = angle::BitSet<DIRTY_BIT_MAX>;
+ const DirtyBits &getDirtyBits() const { return mDirtyBits; }
+ void clearDirtyBits() { mDirtyBits.reset(); }
+ void clearDirtyBits(const DirtyBits &bitset) { mDirtyBits &= ~bitset; }
+ void setAllDirtyBits()
+ {
+ mDirtyBits.set();
+ mExtendedDirtyBits.set();
+ mDirtyCurrentValues.set();
+ }
+
+ using ExtendedDirtyBits = angle::BitSet32<EXTENDED_DIRTY_BIT_MAX>;
+ const ExtendedDirtyBits &getExtendedDirtyBits() const { return mExtendedDirtyBits; }
+ // TODO(https://anglebug.com/5631): Handle extended dirty bits on non-vulkan backends
+ ExtendedDirtyBits getAndResetExtendedDirtyBits() const;
+ void clearExtendedDirtyBits() { mExtendedDirtyBits.reset(); }
+
+ using DirtyObjects = angle::BitSet<DIRTY_OBJECT_MAX>;
+ void clearDirtyObjects() { mDirtyObjects.reset(); }
+ void setAllDirtyObjects() { mDirtyObjects.set(); }
+ angle::Result syncDirtyObjects(const Context *context,
+ const DirtyObjects &bitset,
+ Command command);
+ angle::Result syncDirtyObject(const Context *context, GLenum target);
+ void setObjectDirty(GLenum target);
+ void setTextureDirty(size_t textureUnitIndex);
+ void setSamplerDirty(size_t samplerIndex);
+
+ ANGLE_INLINE void setReadFramebufferDirty()
+ {
+ mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
+ mDirtyObjects.set(DIRTY_OBJECT_READ_ATTACHMENTS);
+ }
+
+ ANGLE_INLINE void setDrawFramebufferDirty()
+ {
+ mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
+ mDirtyObjects.set(DIRTY_OBJECT_DRAW_ATTACHMENTS);
+ }
+
+ // This actually clears the current value dirty bits.
+ // TODO(jmadill): Pass mutable dirty bits into Impl.
+ AttributesMask getAndResetDirtyCurrentValues() const;
+
+ void setImageUnit(const Context *context,
+ size_t unit,
+ Texture *texture,
+ GLint level,
+ GLboolean layered,
+ GLint layer,
+ GLenum access,
+ GLenum format);
+
+ const ImageUnit &getImageUnit(size_t unit) const { return mImageUnits[unit]; }
+ const ActiveTexturesCache &getActiveTexturesCache() const { return mActiveTexturesCache; }
+ ComponentTypeMask getCurrentValuesTypeMask() const { return mCurrentValuesTypeMask; }
+
+ // "onActiveTextureChange" is called when a texture binding changes.
+ void onActiveTextureChange(const Context *context, size_t textureUnit);
+
+ // "onActiveTextureStateChange" is called when the Texture changed but the binding did not.
+ void onActiveTextureStateChange(const Context *context, size_t textureUnit);
+
+ void onImageStateChange(const Context *context, size_t unit);
+
+ void onUniformBufferStateChange(size_t uniformBufferIndex);
+ void onAtomicCounterBufferStateChange(size_t atomicCounterBufferIndex);
+ void onShaderStorageBufferStateChange(size_t shaderStorageBufferIndex);
+
+ bool isCurrentTransformFeedback(const TransformFeedback *tf) const
+ {
+ return tf == mTransformFeedback.get();
+ }
+ bool isCurrentVertexArray(const VertexArray *va) const { return va == mVertexArray; }
+
+ GLES1State &gles1() { return mGLES1State; }
+ const GLES1State &gles1() const { return mGLES1State; }
+
+ // Helpers for setting bound buffers. They should all have the same signature.
+ // Not meant to be called externally. Used for local helpers in State.cpp.
+ template <BufferBinding Target>
+ void setGenericBufferBindingWithBit(const Context *context, Buffer *buffer);
+
+ template <BufferBinding Target>
+ void setGenericBufferBinding(const Context *context, Buffer *buffer);
+
+ using BufferBindingSetter = void (State::*)(const Context *, Buffer *);
+
+ ANGLE_INLINE bool validateSamplerFormats() const
+ {
+ return (!mExecutable || !(mTexturesIncompatibleWithSamplers.intersects(
+ mExecutable->getActiveSamplersMask())));
+ }
+
+ ProvokingVertexConvention getProvokingVertex() const { return mProvokingVertex; }
+ void setProvokingVertex(ProvokingVertexConvention val)
+ {
+ mDirtyBits.set(State::DIRTY_BIT_PROVOKING_VERTEX);
+ mProvokingVertex = val;
+ }
+
+ ANGLE_INLINE void setReadFramebufferBindingDirty()
+ {
+ mDirtyBits.set(State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
+ }
+
+ ANGLE_INLINE void setDrawFramebufferBindingDirty()
+ {
+ mDirtyBits.set(State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
+ }
+
+ using ClipDistanceEnableBits = angle::BitSet32<IMPLEMENTATION_MAX_CLIP_DISTANCES>;
+ const ClipDistanceEnableBits &getEnabledClipDistances() const { return mClipDistancesEnabled; }
+ void setClipDistanceEnable(int idx, bool enable);
+
+ const OverlayType *getOverlay() const { return mOverlay; }
+
+ // Not for general use.
+ const BufferManager &getBufferManagerForCapture() const { return *mBufferManager; }
+ const BoundBufferMap &getBoundBuffersForCapture() const { return mBoundBuffers; }
+ const TextureManager &getTextureManagerForCapture() const { return *mTextureManager; }
+ const TextureBindingMap &getBoundTexturesForCapture() const { return mSamplerTextures; }
+ const RenderbufferManager &getRenderbufferManagerForCapture() const
+ {
+ return *mRenderbufferManager;
+ }
+ const FramebufferManager &getFramebufferManagerForCapture() const
+ {
+ return *mFramebufferManager;
+ }
+ const ShaderProgramManager &getShaderProgramManagerForCapture() const
+ {
+ return *mShaderProgramManager;
+ }
+ const SyncManager &getSyncManagerForCapture() const { return *mSyncManager; }
+ const SamplerManager &getSamplerManagerForCapture() const { return *mSamplerManager; }
+ const ProgramPipelineManager *getProgramPipelineManagerForCapture() const
+ {
+ return mProgramPipelineManager;
+ }
+ const SamplerBindingVector &getSamplerBindingsForCapture() const { return mSamplers; }
+ const ActiveQueryMap &getActiveQueriesForCapture() const { return mActiveQueries; }
+ void initializeForCapture(const Context *context);
+
+ bool hasConstantAlphaBlendFunc() const
+ {
+ return (mBlendFuncConstantAlphaDrawBuffers & mBlendStateExt.getEnabledMask()).any();
+ }
+
+ bool hasSimultaneousConstantColorAndAlphaBlendFunc() const
+ {
+ return (mBlendFuncConstantColorDrawBuffers & mBlendStateExt.getEnabledMask()).any() &&
+ hasConstantAlphaBlendFunc();
+ }
+
+ bool noSimultaneousConstantColorAndAlphaBlendFunc() const
+ {
+ return mNoSimultaneousConstantColorAndAlphaBlendFunc;
+ }
+
+ const BufferVector &getOffsetBindingPointerUniformBuffers() const { return mUniformBuffers; }
+
+ const BufferVector &getOffsetBindingPointerAtomicCounterBuffers() const
+ {
+ return mAtomicCounterBuffers;
+ }
+
+ const BufferVector &getOffsetBindingPointerShaderStorageBuffers() const
+ {
+ return mShaderStorageBuffers;
+ }
+
+ ActiveTextureMask getTexturesIncompatibleWithSamplers() const
+ {
+ return mTexturesIncompatibleWithSamplers;
+ }
+
+ bool isProgramBinaryCacheEnabled() const { return mProgramBinaryCacheEnabled; }
+
+ bool isTextureRectangleEnabled() const { return mTextureRectangleEnabled; }
+
+ DrawBufferMask getBlendFuncConstantAlphaDrawBuffers() const
+ {
+ return mBlendFuncConstantAlphaDrawBuffers;
+ }
+
+ DrawBufferMask getBlendFuncConstantColorDrawBuffers() const
+ {
+ return mBlendFuncConstantColorDrawBuffers;
+ }
+
+ const std::vector<ImageUnit> &getImageUnits() const { return mImageUnits; }
+
+ bool hasDisplayTextureShareGroup() const { return mDisplayTextureShareGroup; }
+
+ void setLogicOpEnabled(bool enabled);
+ bool isLogicOpEnabled() const { return mLogicOpEnabled; }
+
+ void setLogicOp(LogicalOperation opcode);
+ LogicalOperation getLogicOp() const { return mLogicOp; }
+
+ private:
+ friend class Context;
+
+ void unsetActiveTextures(const ActiveTextureMask &textureMask);
+ void setActiveTextureDirty(size_t textureIndex, Texture *texture);
+ void updateTextureBinding(const Context *context, size_t textureIndex, Texture *texture);
+ void updateActiveTextureStateOnSync(const Context *context,
+ size_t textureIndex,
+ const Sampler *sampler,
+ Texture *texture);
+ Texture *getTextureForActiveSampler(TextureType type, size_t index);
+
+ bool hasConstantColor(GLenum sourceRGB, GLenum destRGB) const;
+ bool hasConstantAlpha(GLenum sourceRGB, GLenum destRGB) const;
+
+ // Functions to synchronize dirty states
+ angle::Result syncActiveTextures(const Context *context, Command command);
+ angle::Result syncTexturesInit(const Context *context, Command command);
+ angle::Result syncImagesInit(const Context *context, Command command);
+ angle::Result syncReadAttachments(const Context *context, Command command);
+ angle::Result syncDrawAttachments(const Context *context, Command command);
+ angle::Result syncReadFramebuffer(const Context *context, Command command);
+ angle::Result syncDrawFramebuffer(const Context *context, Command command);
+ angle::Result syncVertexArray(const Context *context, Command command);
+ angle::Result syncTextures(const Context *context, Command command);
+ angle::Result syncImages(const Context *context, Command command);
+ angle::Result syncSamplers(const Context *context, Command command);
+ angle::Result syncProgram(const Context *context, Command command);
+ angle::Result syncProgramPipelineObject(const Context *context, Command command);
+
+ using DirtyObjectHandler = angle::Result (State::*)(const Context *context, Command command);
+
+ static constexpr DirtyObjectHandler kDirtyObjectHandlers[DIRTY_OBJECT_MAX] = {
+ &State::syncActiveTextures,
+ &State::syncTexturesInit,
+ &State::syncImagesInit,
+ &State::syncReadAttachments,
+ &State::syncDrawAttachments,
+ &State::syncReadFramebuffer,
+ &State::syncDrawFramebuffer,
+ &State::syncVertexArray,
+ &State::syncTextures,
+ &State::syncImages,
+ &State::syncSamplers,
+ &State::syncProgram,
+ &State::syncProgramPipelineObject};
+
+ // Robust init must happen before Framebuffer init for the Vulkan back-end.
+ static_assert(DIRTY_OBJECT_ACTIVE_TEXTURES < DIRTY_OBJECT_TEXTURES_INIT, "init order");
+ static_assert(DIRTY_OBJECT_TEXTURES_INIT < DIRTY_OBJECT_DRAW_FRAMEBUFFER, "init order");
+ static_assert(DIRTY_OBJECT_IMAGES_INIT < DIRTY_OBJECT_DRAW_FRAMEBUFFER, "init order");
+ static_assert(DIRTY_OBJECT_DRAW_ATTACHMENTS < DIRTY_OBJECT_DRAW_FRAMEBUFFER, "init order");
+ static_assert(DIRTY_OBJECT_READ_ATTACHMENTS < DIRTY_OBJECT_READ_FRAMEBUFFER, "init order");
+
+ static_assert(DIRTY_OBJECT_ACTIVE_TEXTURES == 0, "check DIRTY_OBJECT_ACTIVE_TEXTURES index");
+ static_assert(DIRTY_OBJECT_TEXTURES_INIT == 1, "check DIRTY_OBJECT_TEXTURES_INIT index");
+ static_assert(DIRTY_OBJECT_IMAGES_INIT == 2, "check DIRTY_OBJECT_IMAGES_INIT index");
+ static_assert(DIRTY_OBJECT_READ_ATTACHMENTS == 3, "check DIRTY_OBJECT_READ_ATTACHMENTS index");
+ static_assert(DIRTY_OBJECT_DRAW_ATTACHMENTS == 4, "check DIRTY_OBJECT_DRAW_ATTACHMENTS index");
+ static_assert(DIRTY_OBJECT_READ_FRAMEBUFFER == 5, "check DIRTY_OBJECT_READ_FRAMEBUFFER index");
+ static_assert(DIRTY_OBJECT_DRAW_FRAMEBUFFER == 6, "check DIRTY_OBJECT_DRAW_FRAMEBUFFER index");
+ static_assert(DIRTY_OBJECT_VERTEX_ARRAY == 7, "check DIRTY_OBJECT_VERTEX_ARRAY index");
+ static_assert(DIRTY_OBJECT_TEXTURES == 8, "check DIRTY_OBJECT_TEXTURES index");
+ static_assert(DIRTY_OBJECT_IMAGES == 9, "check DIRTY_OBJECT_IMAGES index");
+ static_assert(DIRTY_OBJECT_SAMPLERS == 10, "check DIRTY_OBJECT_SAMPLERS index");
+ static_assert(DIRTY_OBJECT_PROGRAM == 11, "check DIRTY_OBJECT_PROGRAM index");
+ static_assert(DIRTY_OBJECT_PROGRAM_PIPELINE_OBJECT == 12,
+ "check DIRTY_OBJECT_PROGRAM_PIPELINE_OBJECT index");
+
+ // Dispatch table for buffer update functions.
+ static const angle::PackedEnumMap<BufferBinding, BufferBindingSetter> kBufferSetters;
+
+ ContextID mID;
+
+ EGLenum mClientType;
+ EGLint mProfileMask;
+ EGLenum mContextPriority;
+ bool mHasRobustAccess;
+ bool mHasProtectedContent;
+ bool mIsDebugContext;
+ Version mClientVersion;
+
+ // Caps to use for validation
+ Caps mCaps;
+ TextureCapsMap mTextureCaps;
+ Extensions mExtensions;
+ Limitations mLimitations;
+
+ egl::ShareGroup *mShareGroup;
+
+ // Resource managers.
+ BufferManager *mBufferManager;
+ ShaderProgramManager *mShaderProgramManager;
+ TextureManager *mTextureManager;
+ RenderbufferManager *mRenderbufferManager;
+ SamplerManager *mSamplerManager;
+ SyncManager *mSyncManager;
+ FramebufferManager *mFramebufferManager;
+ ProgramPipelineManager *mProgramPipelineManager;
+ MemoryObjectManager *mMemoryObjectManager;
+ SemaphoreManager *mSemaphoreManager;
+
+ ColorF mColorClearValue;
+ GLfloat mDepthClearValue;
+ int mStencilClearValue;
+
+ RasterizerState mRasterizer;
+ bool mScissorTest;
+ Rectangle mScissor;
+
+ bool mNoUnclampedBlendColor;
+
+ BlendState mBlendState; // Buffer zero blend state legacy struct
+ BlendStateExt mBlendStateExt;
+ ColorF mBlendColor;
+ bool mSampleAlphaToCoverage;
+ bool mSampleCoverage;
+ GLfloat mSampleCoverageValue;
+ bool mSampleCoverageInvert;
+ bool mSampleMask;
+ GLuint mMaxSampleMaskWords;
+ SampleMaskArray<GLbitfield> mSampleMaskValues;
+ bool mIsSampleShadingEnabled;
+ float mMinSampleShading;
+
+ DepthStencilState mDepthStencil;
+ GLint mStencilRef;
+ GLint mStencilBackRef;
+
+ GLfloat mLineWidth;
+
+ GLenum mGenerateMipmapHint;
+ GLenum mTextureFilteringHint;
+ GLenum mFragmentShaderDerivativeHint;
+
+ const bool mBindGeneratesResource;
+ const bool mClientArraysEnabled;
+
+ Rectangle mViewport;
+ float mNearZ;
+ float mFarZ;
+
+ GLenum mClipControlOrigin;
+ GLenum mClipControlDepth;
+
+ Framebuffer *mReadFramebuffer;
+ Framebuffer *mDrawFramebuffer;
+ BindingPointer<Renderbuffer> mRenderbuffer;
+ Program *mProgram;
+ BindingPointer<ProgramPipeline> mProgramPipeline;
+ ProgramExecutable *mExecutable;
+
+ // GL_ANGLE_provoking_vertex
+ ProvokingVertexConvention mProvokingVertex;
+
+ using VertexAttribVector = std::vector<VertexAttribCurrentValueData>;
+ VertexAttribVector mVertexAttribCurrentValues; // From glVertexAttrib
+ VertexArray *mVertexArray;
+ ComponentTypeMask mCurrentValuesTypeMask;
+
+ // Texture and sampler bindings
+ GLint mActiveSampler; // Active texture unit selector - GL_TEXTURE0
+
+ TextureBindingMap mSamplerTextures;
+
+ // Active Textures Cache
+ // ---------------------
+ // The active textures cache gives ANGLE components access to a complete array of textures
+ // on a draw call. gl::State implements angle::Observer and watches gl::Texture for state
+ // changes via the onSubjectStateChange method above. We update the cache before draws.
+ // See Observer.h and the design doc linked there for more info on Subject/Observer events.
+ //
+ // On state change events (re-binding textures, samplers, programs etc) we clear the cache
+ // and flag dirty bits. nullptr indicates unbound or incomplete.
+ ActiveTexturesCache mActiveTexturesCache;
+ std::vector<angle::ObserverBinding> mCompleteTextureBindings;
+
+ ActiveTextureMask mTexturesIncompatibleWithSamplers;
+
+ SamplerBindingVector mSamplers;
+
+ // It would be nice to merge the image and observer binding. Same for textures.
+ std::vector<ImageUnit> mImageUnits;
+
+ ActiveQueryMap mActiveQueries;
+
+ // Stores the currently bound buffer for each binding point. It has an entry for the element
+ // array buffer but it should not be used. Instead this bind point is owned by the current
+ // vertex array object.
+ BoundBufferMap mBoundBuffers;
+
+ BufferVector mUniformBuffers;
+ BufferVector mAtomicCounterBuffers;
+ BufferVector mShaderStorageBuffers;
+
+ angle::BitSet<gl::IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS> mBoundUniformBuffersMask;
+ angle::BitSet<gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS>
+ mBoundAtomicCounterBuffersMask;
+ angle::BitSet<gl::IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS>
+ mBoundShaderStorageBuffersMask;
+
+ BindingPointer<TransformFeedback> mTransformFeedback;
+
+ PixelUnpackState mUnpack;
+ PixelPackState mPack;
+
+ bool mPrimitiveRestart;
+
+ Debug mDebug;
+
+ bool mMultiSampling;
+ bool mSampleAlphaToOne;
+
+ GLenum mCoverageModulation;
+
+ // GL_EXT_sRGB_write_control
+ bool mFramebufferSRGB;
+
+ // GL_ANGLE_robust_resource_initialization
+ const bool mRobustResourceInit;
+
+ // GL_ANGLE_program_cache_control
+ const bool mProgramBinaryCacheEnabled;
+
+ // GL_ANGLE_webgl_compatibility
+ bool mTextureRectangleEnabled;
+
+ // GL_ANGLE_logic_op
+ bool mLogicOpEnabled;
+ LogicalOperation mLogicOp;
+
+ // GL_KHR_parallel_shader_compile
+ GLuint mMaxShaderCompilerThreads;
+
+ // GL_APPLE_clip_distance/GL_EXT_clip_cull_distance
+ ClipDistanceEnableBits mClipDistancesEnabled;
+
+ // GL_EXT_tessellation_shader
+ GLuint mPatchVertices;
+
+ // GL_ANGLE_shader_pixel_local_storage
+ bool mPixelLocalStorageActive;
+
+ // GLES1 emulation: state specific to GLES1
+ GLES1State mGLES1State;
+
+ DirtyBits mDirtyBits;
+ mutable ExtendedDirtyBits mExtendedDirtyBits;
+ DirtyObjects mDirtyObjects;
+ mutable AttributesMask mDirtyCurrentValues;
+ ActiveTextureMask mDirtyActiveTextures;
+ ActiveTextureMask mDirtyTextures;
+ ActiveTextureMask mDirtySamplers;
+ ImageUnitMask mDirtyImages;
+
+ // The Overlay object, used by the backend to render the overlay.
+ const OverlayType *mOverlay;
+
+ // OES_draw_buffers_indexed
+ DrawBufferMask mBlendFuncConstantAlphaDrawBuffers;
+ DrawBufferMask mBlendFuncConstantColorDrawBuffers;
+ bool mNoSimultaneousConstantColorAndAlphaBlendFunc;
+ // Whether the indexed variants of setBlend* have been called. If so, the call to the
+ // non-indexed variants are not no-oped.
+ bool mSetBlendIndexedInvoked;
+ bool mSetBlendFactorsIndexedInvoked;
+ bool mSetBlendEquationsIndexedInvoked;
+ bool mDisplayTextureShareGroup;
+
+ // GL_EXT_primitive_bounding_box
+ GLfloat mBoundingBoxMinX;
+ GLfloat mBoundingBoxMinY;
+ GLfloat mBoundingBoxMinZ;
+ GLfloat mBoundingBoxMinW;
+ GLfloat mBoundingBoxMaxX;
+ GLfloat mBoundingBoxMaxY;
+ GLfloat mBoundingBoxMaxZ;
+ GLfloat mBoundingBoxMaxW;
+
+ // QCOM_shading_rate
+ bool mShadingRatePreserveAspectRatio;
+ ShadingRate mShadingRate;
+};
+
+ANGLE_INLINE angle::Result State::syncDirtyObjects(const Context *context,
+ const DirtyObjects &bitset,
+ Command command)
+{
+ const DirtyObjects &dirtyObjects = mDirtyObjects & bitset;
+
+ for (size_t dirtyObject : dirtyObjects)
+ {
+ ANGLE_TRY((this->*kDirtyObjectHandlers[dirtyObject])(context, command));
+ }
+
+ mDirtyObjects &= ~dirtyObjects;
+ return angle::Result::Continue;
+}
+
+} // namespace gl
+
+#endif // LIBANGLE_STATE_H_
diff --git a/gfx/angle/checkout/src/libANGLE/Stream.cpp b/gfx/angle/checkout/src/libANGLE/Stream.cpp
new file mode 100644
index 0000000000..8d2830287f
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Stream.cpp
@@ -0,0 +1,282 @@
+//
+// 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.
+//
+
+// Stream.cpp: Implements the egl::Stream class, representing the stream
+// where frames are streamed in. Implements EGLStreanKHR.
+
+#include "libANGLE/Stream.h"
+
+#include <EGL/eglext.h>
+#include <platform/PlatformMethods.h>
+
+#include "common/debug.h"
+#include "common/mathutil.h"
+#include "common/platform.h"
+#include "common/utilities.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Display.h"
+#include "libANGLE/renderer/DisplayImpl.h"
+#include "libANGLE/renderer/StreamProducerImpl.h"
+
+namespace egl
+{
+
+Stream::Stream(Display *display, const AttributeMap &attribs)
+ : mLabel(nullptr),
+ mDisplay(display),
+ mProducerImplementation(nullptr),
+ mState(EGL_STREAM_STATE_CREATED_KHR),
+ mProducerFrame(0),
+ mConsumerFrame(0),
+ mConsumerLatency(attribs.getAsInt(EGL_CONSUMER_LATENCY_USEC_KHR, 0)),
+ mConsumerAcquireTimeout(attribs.getAsInt(EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR, 0)),
+ mPlaneCount(0),
+ mConsumerType(ConsumerType::NoConsumer),
+ mProducerType(ProducerType::NoProducer)
+{
+ for (auto &plane : mPlanes)
+ {
+ plane.textureUnit = -1;
+ plane.texture = nullptr;
+ }
+}
+
+Stream::~Stream()
+{
+ SafeDelete(mProducerImplementation);
+ for (auto &plane : mPlanes)
+ {
+ if (plane.texture != nullptr)
+ {
+ plane.texture->releaseStream();
+ }
+ }
+}
+
+void Stream::setLabel(EGLLabelKHR label)
+{
+ mLabel = label;
+}
+
+EGLLabelKHR Stream::getLabel() const
+{
+ return mLabel;
+}
+
+void Stream::setConsumerLatency(EGLint latency)
+{
+ mConsumerLatency = latency;
+}
+
+EGLint Stream::getConsumerLatency() const
+{
+ return mConsumerLatency;
+}
+
+EGLuint64KHR Stream::getProducerFrame() const
+{
+ return mProducerFrame;
+}
+
+EGLuint64KHR Stream::getConsumerFrame() const
+{
+ return mConsumerFrame;
+}
+
+EGLenum Stream::getState() const
+{
+ return mState;
+}
+
+void Stream::setConsumerAcquireTimeout(EGLint timeout)
+{
+ mConsumerAcquireTimeout = timeout;
+}
+
+EGLint Stream::getConsumerAcquireTimeout() const
+{
+ return mConsumerAcquireTimeout;
+}
+
+Stream::ProducerType Stream::getProducerType() const
+{
+ return mProducerType;
+}
+
+Stream::ConsumerType Stream::getConsumerType() const
+{
+ return mConsumerType;
+}
+
+EGLint Stream::getPlaneCount() const
+{
+ return mPlaneCount;
+}
+
+rx::StreamProducerImpl *Stream::getImplementation()
+{
+ return mProducerImplementation;
+}
+
+Error Stream::createConsumerGLTextureExternal(const AttributeMap &attributes, gl::Context *context)
+{
+ ASSERT(mState == EGL_STREAM_STATE_CREATED_KHR);
+ ASSERT(mConsumerType == ConsumerType::NoConsumer);
+ ASSERT(mProducerType == ProducerType::NoProducer);
+ ASSERT(context != nullptr);
+
+ const auto &glState = context->getState();
+ EGLenum bufferType = attributes.getAsInt(EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER);
+ if (bufferType == EGL_RGB_BUFFER)
+ {
+ mPlanes[0].texture = glState.getTargetTexture(gl::TextureType::External);
+ ASSERT(mPlanes[0].texture != nullptr);
+ mPlanes[0].texture->bindStream(this);
+ mConsumerType = ConsumerType::GLTextureRGB;
+ mPlaneCount = 1;
+ }
+ else
+ {
+ mPlaneCount = attributes.getAsInt(EGL_YUV_NUMBER_OF_PLANES_EXT, 2);
+ ASSERT(mPlaneCount <= 3);
+ for (EGLint i = 0; i < mPlaneCount; i++)
+ {
+ // Fetch all the textures
+ mPlanes[i].textureUnit = attributes.getAsInt(EGL_YUV_PLANE0_TEXTURE_UNIT_NV + i, -1);
+ if (mPlanes[i].textureUnit != EGL_NONE)
+ {
+ mPlanes[i].texture =
+ glState.getSamplerTexture(mPlanes[i].textureUnit, gl::TextureType::External);
+ ASSERT(mPlanes[i].texture != nullptr);
+ }
+ }
+
+ // Bind them to the stream
+ for (EGLint i = 0; i < mPlaneCount; i++)
+ {
+ if (mPlanes[i].textureUnit != EGL_NONE)
+ {
+ mPlanes[i].texture->bindStream(this);
+ }
+ }
+ mConsumerType = ConsumerType::GLTextureYUV;
+ }
+
+ mContext = context;
+ mState = EGL_STREAM_STATE_CONNECTING_KHR;
+
+ return NoError();
+}
+
+Error Stream::createProducerD3D11Texture(const AttributeMap &attributes)
+{
+ ASSERT(mState == EGL_STREAM_STATE_CONNECTING_KHR);
+ ASSERT(mConsumerType == ConsumerType::GLTextureRGB ||
+ mConsumerType == ConsumerType::GLTextureYUV);
+ ASSERT(mProducerType == ProducerType::NoProducer);
+
+ mProducerImplementation =
+ mDisplay->getImplementation()->createStreamProducerD3DTexture(mConsumerType, attributes);
+ mProducerType = ProducerType::D3D11Texture;
+ mState = EGL_STREAM_STATE_EMPTY_KHR;
+
+ return NoError();
+}
+
+// Called when the consumer of this stream starts using the stream
+Error Stream::consumerAcquire(const gl::Context *context)
+{
+ ASSERT(mState == EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR ||
+ mState == EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR);
+ ASSERT(mConsumerType == ConsumerType::GLTextureRGB ||
+ mConsumerType == ConsumerType::GLTextureYUV);
+ ASSERT(mProducerType == ProducerType::D3D11Texture);
+
+ mState = EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR;
+ mConsumerFrame++;
+
+ // Bind the planes to the gl textures
+ for (int i = 0; i < mPlaneCount; i++)
+ {
+ if (mPlanes[i].texture != nullptr)
+ {
+ ANGLE_TRY(ResultToEGL(mPlanes[i].texture->acquireImageFromStream(
+ context, mProducerImplementation->getGLFrameDescription(i))));
+ }
+ }
+
+ return NoError();
+}
+
+Error Stream::consumerRelease(const gl::Context *context)
+{
+ ASSERT(mState == EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR ||
+ mState == EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR);
+ ASSERT(mConsumerType == ConsumerType::GLTextureRGB ||
+ mConsumerType == ConsumerType::GLTextureYUV);
+ ASSERT(mProducerType == ProducerType::D3D11Texture);
+
+ // Release the images
+ for (int i = 0; i < mPlaneCount; i++)
+ {
+ if (mPlanes[i].texture != nullptr)
+ {
+ ANGLE_TRY(ResultToEGL(mPlanes[i].texture->releaseImageFromStream(context)));
+ }
+ }
+
+ return NoError();
+}
+
+bool Stream::isConsumerBoundToContext(const gl::Context *context) const
+{
+ ASSERT(context != nullptr);
+ return (context == mContext);
+}
+
+Error Stream::validateD3D11Texture(const void *texture, const AttributeMap &attributes) const
+{
+ ASSERT(mConsumerType == ConsumerType::GLTextureRGB ||
+ mConsumerType == ConsumerType::GLTextureYUV);
+ ASSERT(mProducerType == ProducerType::D3D11Texture);
+ ASSERT(mProducerImplementation != nullptr);
+
+ return mProducerImplementation->validateD3DTexture(texture, attributes);
+}
+
+Error Stream::postD3D11Texture(void *texture, const AttributeMap &attributes)
+{
+ ASSERT(mConsumerType == ConsumerType::GLTextureRGB ||
+ mConsumerType == ConsumerType::GLTextureYUV);
+ ASSERT(mProducerType == ProducerType::D3D11Texture);
+
+ mProducerImplementation->postD3DTexture(texture, attributes);
+ mProducerFrame++;
+
+ mState = EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR;
+
+ return NoError();
+}
+
+// This is called when a texture object associated with this stream is destroyed. Even if multiple
+// textures are bound, one being destroyed invalidates the stream, so all the remaining textures
+// will be released and the stream will be invalidated.
+void Stream::releaseTextures()
+{
+ for (auto &plane : mPlanes)
+ {
+ if (plane.texture != nullptr)
+ {
+ plane.texture->releaseStream();
+ plane.texture = nullptr;
+ }
+ }
+ mConsumerType = ConsumerType::NoConsumer;
+ mProducerType = ProducerType::NoProducer;
+ mState = EGL_STREAM_STATE_DISCONNECTED_KHR;
+}
+
+} // namespace egl
diff --git a/gfx/angle/checkout/src/libANGLE/Stream.h b/gfx/angle/checkout/src/libANGLE/Stream.h
new file mode 100644
index 0000000000..b53c90b764
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Stream.h
@@ -0,0 +1,149 @@
+//
+// 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.
+//
+
+// Stream.h: Defines the egl::Stream class, representing the stream
+// where frames are streamed in. Implements EGLStreanKHR.
+
+#ifndef LIBANGLE_STREAM_H_
+#define LIBANGLE_STREAM_H_
+
+#include <array>
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include "common/angleutils.h"
+#include "libANGLE/AttributeMap.h"
+#include "libANGLE/Debug.h"
+
+namespace rx
+{
+class StreamProducerImpl;
+}
+
+namespace gl
+{
+class Context;
+class Texture;
+} // namespace gl
+
+namespace egl
+{
+class Display;
+class Error;
+class Thread;
+
+class Stream final : public LabeledObject, angle::NonCopyable
+{
+ public:
+ Stream(Display *display, const AttributeMap &attribs);
+ ~Stream() override;
+
+ void setLabel(EGLLabelKHR label) override;
+ EGLLabelKHR getLabel() const override;
+
+ enum class ConsumerType
+ {
+ NoConsumer,
+ GLTextureRGB,
+ GLTextureYUV,
+ };
+
+ enum class ProducerType
+ {
+ NoProducer,
+ D3D11Texture,
+ };
+
+ // A GL texture interpretation of a part of a producer frame. For use with GL texture consumers
+ struct GLTextureDescription
+ {
+ unsigned int width;
+ unsigned int height;
+ unsigned int internalFormat;
+ unsigned int mipLevels;
+ };
+
+ EGLenum getState() const;
+
+ void setConsumerLatency(EGLint latency);
+ EGLint getConsumerLatency() const;
+
+ EGLuint64KHR getProducerFrame() const;
+ EGLuint64KHR getConsumerFrame() const;
+
+ void setConsumerAcquireTimeout(EGLint timeout);
+ EGLint getConsumerAcquireTimeout() const;
+
+ ConsumerType getConsumerType() const;
+ ProducerType getProducerType() const;
+
+ EGLint getPlaneCount() const;
+
+ rx::StreamProducerImpl *getImplementation();
+
+ // Consumer creation methods
+ Error createConsumerGLTextureExternal(const AttributeMap &attributes, gl::Context *context);
+
+ // Producer creation methods
+ Error createProducerD3D11Texture(const AttributeMap &attributes);
+
+ // Consumer methods
+ Error consumerAcquire(const gl::Context *context);
+ Error consumerRelease(const gl::Context *context);
+
+ // Some consumers are bound to GL contexts. This validates that a given context is bound to the
+ // stream's consumer
+ bool isConsumerBoundToContext(const gl::Context *context) const;
+
+ // Producer methods
+ Error validateD3D11Texture(const void *texture, const AttributeMap &attributes) const;
+ Error postD3D11Texture(void *texture, const AttributeMap &attributes);
+
+ private:
+ EGLLabelKHR mLabel;
+
+ // Associated display
+ Display *mDisplay;
+
+ // Producer Implementation
+ rx::StreamProducerImpl *mProducerImplementation;
+
+ // Associated GL context. Note that this is a weak pointer used for validation purposes only,
+ // and should never be arbitrarily dereferenced without knowing the context still exists as it
+ // can become dangling at any time.
+ gl::Context *mContext;
+
+ // EGL defined attributes
+ EGLint mState;
+ EGLuint64KHR mProducerFrame;
+ EGLuint64KHR mConsumerFrame;
+ EGLint mConsumerLatency;
+
+ // EGL gltexture consumer attributes
+ EGLint mConsumerAcquireTimeout;
+
+ // EGL gltexture yuv consumer attributes
+ EGLint mPlaneCount;
+ struct PlaneTexture
+ {
+ EGLint textureUnit;
+ gl::Texture *texture;
+ };
+ // Texture units and textures for all the planes
+ std::array<PlaneTexture, 3> mPlanes;
+
+ // Consumer and producer types
+ ConsumerType mConsumerType;
+ ProducerType mProducerType;
+
+ // ANGLE-only method, used internally
+ friend class gl::Texture;
+ void releaseTextures();
+};
+} // namespace egl
+
+#endif // LIBANGLE_STREAM_H_
diff --git a/gfx/angle/checkout/src/libANGLE/Surface.cpp b/gfx/angle/checkout/src/libANGLE/Surface.cpp
new file mode 100644
index 0000000000..acb382dd10
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Surface.cpp
@@ -0,0 +1,941 @@
+//
+// Copyright 2002 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.
+//
+
+// Surface.cpp: Implements the egl::Surface class, representing a drawing surface
+// such as the client area of a window, including any back buffers.
+// Implements EGLSurface and related functionality. [EGL 1.4] section 2.2 page 3.
+
+#include "libANGLE/Surface.h"
+
+#include <EGL/eglext.h>
+
+#include "libANGLE/Config.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Display.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/Texture.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/EGLImplFactory.h"
+#include "libANGLE/trace.h"
+
+namespace egl
+{
+namespace
+{
+angle::SubjectIndex kSurfaceImplSubjectIndex = 0;
+} // namespace
+
+SurfaceState::SurfaceState(const egl::Config *configIn, const AttributeMap &attributesIn)
+ : label(nullptr),
+ config((configIn != nullptr) ? new egl::Config(*configIn) : nullptr),
+ attributes(attributesIn),
+ timestampsEnabled(false),
+ autoRefreshEnabled(false),
+ directComposition(false),
+ swapBehavior(EGL_NONE)
+{
+ directComposition = attributes.get(EGL_DIRECT_COMPOSITION_ANGLE, EGL_FALSE) == EGL_TRUE;
+}
+
+SurfaceState::~SurfaceState()
+{
+ delete config;
+}
+
+bool SurfaceState::isRobustResourceInitEnabled() const
+{
+ return attributes.get(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE, EGL_FALSE) == EGL_TRUE;
+}
+
+bool SurfaceState::hasProtectedContent() const
+{
+ return attributes.get(EGL_PROTECTED_CONTENT_EXT, EGL_FALSE) == EGL_TRUE;
+}
+
+EGLint SurfaceState::getPreferredSwapInterval() const
+{
+ return attributes.getAsInt(EGL_SWAP_INTERVAL_ANGLE, 1);
+}
+
+Surface::Surface(EGLint surfaceType,
+ GLuint serialId,
+ const egl::Config *config,
+ const AttributeMap &attributes,
+ bool forceRobustResourceInit,
+ EGLenum buftype)
+ : FramebufferAttachmentObject(),
+ mState(config, attributes),
+ mImplementation(nullptr),
+ mRefCount(0),
+ mDestroyed(false),
+ mType(surfaceType),
+ mBuftype(buftype),
+ mPostSubBufferRequested(false),
+ mLargestPbuffer(false),
+ mGLColorspace(EGL_GL_COLORSPACE_LINEAR),
+ mVGAlphaFormat(EGL_VG_ALPHA_FORMAT_NONPRE),
+ mVGColorspace(EGL_VG_COLORSPACE_sRGB),
+ mMipmapTexture(false),
+ mMipmapLevel(0),
+ mHorizontalResolution(EGL_UNKNOWN),
+ mVerticalResolution(EGL_UNKNOWN),
+ mMultisampleResolve(EGL_MULTISAMPLE_RESOLVE_DEFAULT),
+ mFixedSize(false),
+ mFixedWidth(0),
+ mFixedHeight(0),
+ mTextureFormat(TextureFormat::NoTexture),
+ mTextureTarget(EGL_NO_TEXTURE),
+ // FIXME: Determine actual pixel aspect ratio
+ mPixelAspectRatio(static_cast<EGLint>(1.0 * EGL_DISPLAY_SCALING)),
+ mRenderBuffer(EGL_BACK_BUFFER),
+ mOrientation(0),
+ mTexture(nullptr),
+ mColorFormat(config->renderTargetFormat),
+ mDSFormat(config->depthStencilFormat),
+ mIsCurrentOnAnyContext(false),
+ mLockBufferPtr(nullptr),
+ mLockBufferPitch(0),
+ mBufferAgeQueriedSinceLastSwap(false),
+ mIsDamageRegionSet(false),
+ mColorInitState(gl::InitState::Initialized),
+ mDepthStencilInitState(gl::InitState::Initialized),
+ mImplObserverBinding(this, kSurfaceImplSubjectIndex),
+ mSerialId(serialId)
+{
+ mPostSubBufferRequested =
+ (attributes.get(EGL_POST_SUB_BUFFER_SUPPORTED_NV, EGL_FALSE) == EGL_TRUE);
+
+ if (mType == EGL_PBUFFER_BIT)
+ {
+ mLargestPbuffer = (attributes.get(EGL_LARGEST_PBUFFER, EGL_FALSE) == EGL_TRUE);
+ }
+
+ if (mType == EGL_PIXMAP_BIT)
+ {
+ mRenderBuffer = EGL_SINGLE_BUFFER;
+ }
+
+ if (mType == EGL_WINDOW_BIT)
+ {
+ mRenderBuffer = mState.attributes.getAsInt(EGL_RENDER_BUFFER, EGL_BACK_BUFFER);
+ }
+
+ mGLColorspace =
+ static_cast<EGLenum>(attributes.get(EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_LINEAR));
+ mVGAlphaFormat =
+ static_cast<EGLenum>(attributes.get(EGL_VG_ALPHA_FORMAT, EGL_VG_ALPHA_FORMAT_NONPRE));
+ mVGColorspace = static_cast<EGLenum>(attributes.get(EGL_VG_COLORSPACE, EGL_VG_COLORSPACE_sRGB));
+ mMipmapTexture = (attributes.get(EGL_MIPMAP_TEXTURE, EGL_FALSE) == EGL_TRUE);
+
+ mRobustResourceInitialization =
+ forceRobustResourceInit ||
+ (attributes.get(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE, EGL_FALSE) == EGL_TRUE);
+ if (mRobustResourceInitialization)
+ {
+ mColorInitState = gl::InitState::MayNeedInit;
+ mDepthStencilInitState = gl::InitState::MayNeedInit;
+ }
+
+ mFixedSize = (attributes.get(EGL_FIXED_SIZE_ANGLE, EGL_FALSE) == EGL_TRUE);
+ if (mFixedSize)
+ {
+ mFixedWidth = static_cast<size_t>(attributes.get(EGL_WIDTH, 0));
+ mFixedHeight = static_cast<size_t>(attributes.get(EGL_HEIGHT, 0));
+ }
+
+ if (mType != EGL_WINDOW_BIT)
+ {
+ mTextureFormat = attributes.getAsPackedEnum(EGL_TEXTURE_FORMAT, TextureFormat::NoTexture);
+ mTextureTarget = static_cast<EGLenum>(attributes.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE));
+ }
+
+ mOrientation = static_cast<EGLint>(attributes.get(EGL_SURFACE_ORIENTATION_ANGLE, 0));
+
+ mTextureOffset.x = static_cast<int>(mState.attributes.get(EGL_TEXTURE_OFFSET_X_ANGLE, 0));
+ mTextureOffset.y = static_cast<int>(mState.attributes.get(EGL_TEXTURE_OFFSET_Y_ANGLE, 0));
+}
+
+Surface::~Surface() {}
+
+rx::FramebufferAttachmentObjectImpl *Surface::getAttachmentImpl() const
+{
+ return mImplementation;
+}
+
+Error Surface::destroyImpl(const Display *display)
+{
+ if (mImplementation)
+ {
+ mImplementation->destroy(display);
+ }
+
+ ASSERT(!mTexture);
+
+ SafeDelete(mImplementation);
+
+ delete this;
+ return NoError();
+}
+
+void Surface::postSwap(const gl::Context *context)
+{
+ if (mRobustResourceInitialization && mState.swapBehavior != EGL_BUFFER_PRESERVED)
+ {
+ mColorInitState = gl::InitState::MayNeedInit;
+ mDepthStencilInitState = gl::InitState::MayNeedInit;
+ onStateChange(angle::SubjectMessage::SubjectChanged);
+ }
+
+ mBufferAgeQueriedSinceLastSwap = false;
+
+ mIsDamageRegionSet = false;
+}
+
+Error Surface::initialize(const Display *display)
+{
+ GLenum overrideRenderTargetFormat = mState.config->renderTargetFormat;
+
+ // To account for color space differences, override the renderTargetFormat with the
+ // non-linear format. If no suitable non-linear format was found, return
+ // EGL_BAD_MATCH error
+ if (!gl::ColorspaceFormatOverride(mGLColorspace, &overrideRenderTargetFormat))
+ {
+ return egl::EglBadMatch();
+ }
+
+ // If an override is required update mState.config as well
+ if (mState.config->renderTargetFormat != overrideRenderTargetFormat)
+ {
+ egl::Config *overrideConfig = new egl::Config(*(mState.config));
+ overrideConfig->renderTargetFormat = overrideRenderTargetFormat;
+ delete mState.config;
+ mState.config = overrideConfig;
+
+ mColorFormat = gl::Format(mState.config->renderTargetFormat);
+ mDSFormat = gl::Format(mState.config->depthStencilFormat);
+ }
+
+ ANGLE_TRY(mImplementation->initialize(display));
+
+ // Initialized here since impl is nullptr in the constructor.
+ // Must happen after implementation initialize for Android.
+ mState.swapBehavior = mImplementation->getSwapBehavior();
+
+ if (mBuftype == EGL_IOSURFACE_ANGLE)
+ {
+ GLenum internalFormat =
+ static_cast<GLenum>(mState.attributes.get(EGL_TEXTURE_INTERNAL_FORMAT_ANGLE));
+ GLenum type = static_cast<GLenum>(mState.attributes.get(EGL_TEXTURE_TYPE_ANGLE));
+
+ // GL_RGBA + GL_HALF_FLOAT is not a valid format/type combination in GLES like it is in
+ // desktop GL. Adjust the frontend format to be sized RGBA16F.
+ if (internalFormat == GL_RGBA && type == GL_HALF_FLOAT)
+ {
+ internalFormat = GL_RGBA16F;
+ }
+ mColorFormat = gl::Format(internalFormat, type);
+ }
+ if (mBuftype == EGL_D3D_TEXTURE_ANGLE)
+ {
+ const angle::Format *colorFormat = mImplementation->getD3DTextureColorFormat();
+ ASSERT(colorFormat != nullptr);
+ GLenum internalFormat = colorFormat->fboImplementationInternalFormat;
+ mColorFormat = gl::Format(internalFormat, colorFormat->componentType);
+ mGLColorspace = EGL_GL_COLORSPACE_LINEAR;
+ if (mColorFormat.info->colorEncoding == GL_SRGB)
+ {
+ mGLColorspace = EGL_GL_COLORSPACE_SRGB;
+ }
+ }
+
+ if (mType == EGL_WINDOW_BIT && display->getExtensions().getFrameTimestamps)
+ {
+ mState.supportedCompositorTimings = mImplementation->getSupportedCompositorTimings();
+ mState.supportedTimestamps = mImplementation->getSupportedTimestamps();
+ }
+
+ mImplObserverBinding.bind(mImplementation);
+
+ return NoError();
+}
+
+Error Surface::makeCurrent(const gl::Context *context)
+{
+ if (isLocked())
+ {
+ return EglBadAccess();
+ }
+ ANGLE_TRY(mImplementation->makeCurrent(context));
+ mIsCurrentOnAnyContext = true;
+ addRef();
+ return NoError();
+}
+
+Error Surface::unMakeCurrent(const gl::Context *context)
+{
+ ANGLE_TRY(mImplementation->unMakeCurrent(context));
+ mIsCurrentOnAnyContext = false;
+ return releaseRef(context->getDisplay());
+}
+
+Error Surface::releaseRef(const Display *display)
+{
+ ASSERT(mRefCount > 0);
+ mRefCount--;
+ if (mRefCount == 0 && mDestroyed)
+ {
+ ASSERT(display);
+ return destroyImpl(display);
+ }
+
+ return NoError();
+}
+
+Error Surface::onDestroy(const Display *display)
+{
+ mDestroyed = true;
+ if (mRefCount == 0)
+ {
+ return destroyImpl(display);
+ }
+ return NoError();
+}
+
+void Surface::setLabel(EGLLabelKHR label)
+{
+ mState.label = label;
+}
+
+EGLLabelKHR Surface::getLabel() const
+{
+ return mState.label;
+}
+
+EGLint Surface::getType() const
+{
+ return mType;
+}
+
+Error Surface::prepareSwap(const gl::Context *context)
+{
+ ANGLE_TRACE_EVENT0("gpu.angle", "egl::Surface::prepareSwap");
+ return mImplementation->prepareSwap(context);
+}
+
+Error Surface::swap(const gl::Context *context)
+{
+ ANGLE_TRACE_EVENT0("gpu.angle", "egl::Surface::swap");
+ context->onPreSwap();
+
+ context->getState().getOverlay()->onSwap();
+
+ ANGLE_TRY(mImplementation->swap(context));
+ postSwap(context);
+ return NoError();
+}
+
+Error Surface::swapWithDamage(const gl::Context *context, const EGLint *rects, EGLint n_rects)
+{
+ ANGLE_TRACE_EVENT0("gpu.angle", "egl::Surface::swapWithDamage");
+ context->onPreSwap();
+
+ context->getState().getOverlay()->onSwap();
+
+ ANGLE_TRY(mImplementation->swapWithDamage(context, rects, n_rects));
+ postSwap(context);
+ return NoError();
+}
+
+Error Surface::swapWithFrameToken(const gl::Context *context, EGLFrameTokenANGLE frameToken)
+{
+ ANGLE_TRACE_EVENT0("gpu.angle", "egl::Surface::swapWithFrameToken");
+ context->onPreSwap();
+
+ context->getState().getOverlay()->onSwap();
+
+ ANGLE_TRY(mImplementation->swapWithFrameToken(context, frameToken));
+ postSwap(context);
+ return NoError();
+}
+
+Error Surface::postSubBuffer(const gl::Context *context,
+ EGLint x,
+ EGLint y,
+ EGLint width,
+ EGLint height)
+{
+ if (width == 0 || height == 0)
+ {
+ return egl::NoError();
+ }
+
+ context->getState().getOverlay()->onSwap();
+
+ ANGLE_TRY(mImplementation->postSubBuffer(context, x, y, width, height));
+ postSwap(context);
+ return NoError();
+}
+
+Error Surface::setPresentationTime(EGLnsecsANDROID time)
+{
+ return mImplementation->setPresentationTime(time);
+}
+
+Error Surface::querySurfacePointerANGLE(EGLint attribute, void **value)
+{
+ return mImplementation->querySurfacePointerANGLE(attribute, value);
+}
+
+EGLint Surface::isPostSubBufferSupported() const
+{
+ return mPostSubBufferRequested && mImplementation->isPostSubBufferSupported();
+}
+
+void Surface::setSwapInterval(EGLint interval)
+{
+ mImplementation->setSwapInterval(interval);
+}
+
+void Surface::setMipmapLevel(EGLint level)
+{
+ // Level is set but ignored
+ UNIMPLEMENTED();
+ mMipmapLevel = level;
+}
+
+void Surface::setMultisampleResolve(EGLenum resolve)
+{
+ // Behaviour is set but ignored
+ UNIMPLEMENTED();
+ mMultisampleResolve = resolve;
+}
+
+void Surface::setSwapBehavior(EGLenum behavior)
+{
+ // Behaviour is set but ignored
+ UNIMPLEMENTED();
+ mState.swapBehavior = behavior;
+}
+
+void Surface::setFixedWidth(EGLint width)
+{
+ mFixedWidth = width;
+ mImplementation->setFixedWidth(width);
+}
+
+void Surface::setFixedHeight(EGLint height)
+{
+ mFixedHeight = height;
+ mImplementation->setFixedHeight(height);
+}
+
+const Config *Surface::getConfig() const
+{
+ return mState.config;
+}
+
+EGLint Surface::getPixelAspectRatio() const
+{
+ return mPixelAspectRatio;
+}
+
+EGLenum Surface::getRenderBuffer() const
+{
+ return mRenderBuffer;
+}
+
+EGLenum Surface::getSwapBehavior() const
+{
+ return mState.swapBehavior;
+}
+
+TextureFormat Surface::getTextureFormat() const
+{
+ return mTextureFormat;
+}
+
+EGLenum Surface::getTextureTarget() const
+{
+ return mTextureTarget;
+}
+
+bool Surface::getLargestPbuffer() const
+{
+ return mLargestPbuffer;
+}
+
+EGLenum Surface::getGLColorspace() const
+{
+ return mGLColorspace;
+}
+
+EGLenum Surface::getVGAlphaFormat() const
+{
+ return mVGAlphaFormat;
+}
+
+EGLenum Surface::getVGColorspace() const
+{
+ return mVGColorspace;
+}
+
+bool Surface::getMipmapTexture() const
+{
+ return mMipmapTexture;
+}
+
+EGLint Surface::getMipmapLevel() const
+{
+ return mMipmapLevel;
+}
+
+EGLint Surface::getHorizontalResolution() const
+{
+ return mHorizontalResolution;
+}
+
+EGLint Surface::getVerticalResolution() const
+{
+ return mVerticalResolution;
+}
+
+EGLenum Surface::getMultisampleResolve() const
+{
+ return mMultisampleResolve;
+}
+
+EGLint Surface::isFixedSize() const
+{
+ return mFixedSize;
+}
+
+EGLint Surface::getWidth() const
+{
+ return mFixedSize ? static_cast<EGLint>(mFixedWidth) : mImplementation->getWidth();
+}
+
+EGLint Surface::getHeight() const
+{
+ return mFixedSize ? static_cast<EGLint>(mFixedHeight) : mImplementation->getHeight();
+}
+
+egl::Error Surface::getUserWidth(const egl::Display *display, EGLint *value) const
+{
+ if (mFixedSize)
+ {
+ *value = static_cast<EGLint>(mFixedWidth);
+ return NoError();
+ }
+ else
+ {
+ return mImplementation->getUserWidth(display, value);
+ }
+}
+
+egl::Error Surface::getUserHeight(const egl::Display *display, EGLint *value) const
+{
+ if (mFixedSize)
+ {
+ *value = static_cast<EGLint>(mFixedHeight);
+ return NoError();
+ }
+ else
+ {
+ return mImplementation->getUserHeight(display, value);
+ }
+}
+
+Error Surface::bindTexImage(gl::Context *context, gl::Texture *texture, EGLint buffer)
+{
+ ASSERT(!mTexture);
+ ANGLE_TRY(mImplementation->bindTexImage(context, texture, buffer));
+
+ if (texture->bindTexImageFromSurface(context, this) == angle::Result::Stop)
+ {
+ return Error(EGL_BAD_SURFACE);
+ }
+ mTexture = texture;
+ addRef();
+
+ return NoError();
+}
+
+Error Surface::releaseTexImage(const gl::Context *context, EGLint buffer)
+{
+ ASSERT(context);
+
+ ANGLE_TRY(mImplementation->releaseTexImage(context, buffer));
+
+ ASSERT(mTexture);
+ ANGLE_TRY(ResultToEGL(mTexture->releaseTexImageFromSurface(context)));
+
+ return releaseTexImageFromTexture(context);
+}
+
+Error Surface::getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc)
+{
+ return mImplementation->getSyncValues(ust, msc, sbc);
+}
+
+Error Surface::getMscRate(EGLint *numerator, EGLint *denominator)
+{
+ return mImplementation->getMscRate(numerator, denominator);
+}
+
+Error Surface::releaseTexImageFromTexture(const gl::Context *context)
+{
+ ASSERT(mTexture);
+ mTexture = nullptr;
+ return releaseRef(context->getDisplay());
+}
+
+gl::Extents Surface::getAttachmentSize(const gl::ImageIndex & /*target*/) const
+{
+ return gl::Extents(getWidth(), getHeight(), 1);
+}
+
+gl::Format Surface::getAttachmentFormat(GLenum binding, const gl::ImageIndex &target) const
+{
+ return (binding == GL_BACK ? mColorFormat : mDSFormat);
+}
+
+GLsizei Surface::getAttachmentSamples(const gl::ImageIndex &target) const
+{
+ return getConfig()->samples;
+}
+
+bool Surface::isRenderable(const gl::Context *context,
+ GLenum binding,
+ const gl::ImageIndex &imageIndex) const
+{
+ return true;
+}
+
+bool Surface::isYUV() const
+{
+ // EGL_EXT_yuv_surface is not implemented.
+ return false;
+}
+
+bool Surface::isCreatedWithAHB() const
+{
+ return false;
+}
+
+GLuint Surface::getId() const
+{
+ return mSerialId;
+}
+
+Error Surface::getBufferAgeImpl(const gl::Context *context, EGLint *age) const
+{
+ // When EGL_BUFFER_PRESERVED, the previous frame contents are copied to
+ // current frame, so the buffer age is always 1.
+ if (mState.swapBehavior == EGL_BUFFER_PRESERVED)
+ {
+ if (age != nullptr)
+ {
+ *age = 1;
+ }
+ return egl::NoError();
+ }
+ return mImplementation->getBufferAge(context, age);
+}
+
+Error Surface::getBufferAge(const gl::Context *context, EGLint *age)
+{
+ Error err = getBufferAgeImpl(context, age);
+ if (!err.isError())
+ {
+ mBufferAgeQueriedSinceLastSwap = true;
+ }
+ return err;
+}
+
+gl::InitState Surface::initState(GLenum binding, const gl::ImageIndex & /*imageIndex*/) const
+{
+ switch (binding)
+ {
+ case GL_BACK:
+ return mColorInitState;
+ case GL_DEPTH:
+ case GL_STENCIL:
+ return mDepthStencilInitState;
+ default:
+ UNREACHABLE();
+ return gl::InitState::Initialized;
+ }
+}
+
+void Surface::setInitState(GLenum binding,
+ const gl::ImageIndex & /*imageIndex*/,
+ gl::InitState initState)
+{
+ switch (binding)
+ {
+ case GL_BACK:
+ mColorInitState = initState;
+ break;
+ case GL_DEPTH:
+ case GL_STENCIL:
+ mDepthStencilInitState = initState;
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+void Surface::setTimestampsEnabled(bool enabled)
+{
+ mImplementation->setTimestampsEnabled(enabled);
+ mState.timestampsEnabled = enabled;
+}
+
+bool Surface::isTimestampsEnabled() const
+{
+ return mState.timestampsEnabled;
+}
+
+Error Surface::setAutoRefreshEnabled(bool enabled)
+{
+ ANGLE_TRY(mImplementation->setAutoRefreshEnabled(enabled));
+ mState.autoRefreshEnabled = enabled;
+ return NoError();
+}
+
+bool Surface::hasProtectedContent() const
+{
+ return mState.hasProtectedContent();
+}
+
+const SupportedCompositorTiming &Surface::getSupportedCompositorTimings() const
+{
+ return mState.supportedCompositorTimings;
+}
+
+Error Surface::getCompositorTiming(EGLint numTimestamps,
+ const EGLint *names,
+ EGLnsecsANDROID *values) const
+{
+ return mImplementation->getCompositorTiming(numTimestamps, names, values);
+}
+
+Error Surface::getNextFrameId(EGLuint64KHR *frameId) const
+{
+ return mImplementation->getNextFrameId(frameId);
+}
+
+const SupportedTimestamps &Surface::getSupportedTimestamps() const
+{
+ return mState.supportedTimestamps;
+}
+
+Error Surface::getFrameTimestamps(EGLuint64KHR frameId,
+ EGLint numTimestamps,
+ const EGLint *timestamps,
+ EGLnsecsANDROID *values) const
+{
+ return mImplementation->getFrameTimestamps(frameId, numTimestamps, timestamps, values);
+}
+
+void Surface::onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message)
+{
+ ASSERT(index == kSurfaceImplSubjectIndex);
+ switch (message)
+ {
+ case angle::SubjectMessage::SubjectChanged:
+ onStateChange(angle::SubjectMessage::ContentsChanged);
+ break;
+ case angle::SubjectMessage::SurfaceChanged:
+ onStateChange(angle::SubjectMessage::SurfaceChanged);
+ break;
+ case angle::SubjectMessage::SwapchainImageChanged:
+ onStateChange(angle::SubjectMessage::SwapchainImageChanged);
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+Error Surface::setRenderBuffer(EGLint renderBuffer)
+{
+ ANGLE_TRY(mImplementation->setRenderBuffer(renderBuffer));
+ mRenderBuffer = renderBuffer;
+ return NoError();
+}
+
+bool Surface::isLocked() const
+{
+ return (mLockBufferPtr != nullptr);
+}
+
+EGLint Surface::getBitmapPitch() const
+{
+ return mLockBufferPitch;
+}
+
+EGLint Surface::getBitmapOrigin() const
+{
+ return mImplementation->origin();
+}
+
+EGLint Surface::getRedOffset() const
+{
+ const gl::InternalFormat &format = *mColorFormat.info;
+ if (gl::IsBGRAFormat(format.internalFormat))
+ {
+ return format.blueBits + format.greenBits;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+EGLint Surface::getGreenOffset() const
+{
+ const gl::InternalFormat &format = *mColorFormat.info;
+ if (gl::IsBGRAFormat(format.internalFormat))
+ {
+ return format.blueBits;
+ }
+ else
+ {
+ return format.redBits;
+ }
+}
+
+EGLint Surface::getBlueOffset() const
+{
+ const gl::InternalFormat &format = *mColorFormat.info;
+ if (gl::IsBGRAFormat(format.internalFormat))
+ {
+ return 0;
+ }
+ else
+ {
+ return format.redBits + format.greenBits;
+ }
+}
+
+EGLint Surface::getAlphaOffset() const
+{
+ const gl::InternalFormat &format = *mColorFormat.info;
+ if (format.isLUMA())
+ {
+ return format.luminanceBits; // Luma always first, alpha optional
+ }
+ // For RGBA/BGRA alpha is last
+ return format.blueBits + format.greenBits + format.redBits;
+}
+
+EGLint Surface::getLuminanceOffset() const
+{
+ return 0;
+}
+
+EGLint Surface::getBitmapPixelSize() const
+{
+ constexpr EGLint kBitsPerByte = 8;
+ const gl::InternalFormat &format = *mColorFormat.info;
+ return (format.pixelBytes * kBitsPerByte);
+}
+
+EGLAttribKHR Surface::getBitmapPointer() const
+{
+ return static_cast<EGLAttribKHR>((intptr_t)mLockBufferPtr);
+}
+
+egl::Error Surface::lockSurfaceKHR(const egl::Display *display, const AttributeMap &attributes)
+{
+ EGLint lockBufferUsageHint = attributes.getAsInt(
+ EGL_LOCK_USAGE_HINT_KHR, (EGL_READ_SURFACE_BIT_KHR | EGL_WRITE_SURFACE_BIT_KHR));
+
+ bool preservePixels = ((attributes.getAsInt(EGL_MAP_PRESERVE_PIXELS_KHR, false) == EGL_TRUE) ||
+ (mState.swapBehavior == EGL_BUFFER_PRESERVED));
+
+ return mImplementation->lockSurface(display, lockBufferUsageHint, preservePixels,
+ &mLockBufferPtr, &mLockBufferPitch);
+}
+
+egl::Error Surface::unlockSurfaceKHR(const egl::Display *display)
+{
+ mLockBufferPtr = nullptr;
+ mLockBufferPitch = 0;
+ return mImplementation->unlockSurface(display, true);
+}
+
+WindowSurface::WindowSurface(rx::EGLImplFactory *implFactory,
+ const egl::Config *config,
+ EGLNativeWindowType window,
+ const AttributeMap &attribs,
+ bool robustResourceInit)
+ : Surface(EGL_WINDOW_BIT, implFactory->getNextSurfaceID(), config, attribs, robustResourceInit)
+{
+ mImplementation = implFactory->createWindowSurface(mState, window, attribs);
+}
+
+void Surface::setDamageRegion(const EGLint *rects, EGLint n_rects)
+{
+ mIsDamageRegionSet = true;
+}
+
+WindowSurface::~WindowSurface() {}
+
+PbufferSurface::PbufferSurface(rx::EGLImplFactory *implFactory,
+ const Config *config,
+ const AttributeMap &attribs,
+ bool robustResourceInit)
+ : Surface(EGL_PBUFFER_BIT, implFactory->getNextSurfaceID(), config, attribs, robustResourceInit)
+{
+ mImplementation = implFactory->createPbufferSurface(mState, attribs);
+}
+
+PbufferSurface::PbufferSurface(rx::EGLImplFactory *implFactory,
+ const Config *config,
+ EGLenum buftype,
+ EGLClientBuffer clientBuffer,
+ const AttributeMap &attribs,
+ bool robustResourceInit)
+ : Surface(EGL_PBUFFER_BIT,
+ implFactory->getNextSurfaceID(),
+ config,
+ attribs,
+ robustResourceInit,
+ buftype)
+{
+ mImplementation =
+ implFactory->createPbufferFromClientBuffer(mState, buftype, clientBuffer, attribs);
+}
+
+PbufferSurface::~PbufferSurface() {}
+
+PixmapSurface::PixmapSurface(rx::EGLImplFactory *implFactory,
+ const Config *config,
+ NativePixmapType nativePixmap,
+ const AttributeMap &attribs,
+ bool robustResourceInit)
+ : Surface(EGL_PIXMAP_BIT, implFactory->getNextSurfaceID(), config, attribs, robustResourceInit)
+{
+ mImplementation = implFactory->createPixmapSurface(mState, nativePixmap, attribs);
+}
+
+PixmapSurface::~PixmapSurface() {}
+
+// SurfaceDeleter implementation.
+
+SurfaceDeleter::SurfaceDeleter(const Display *display) : mDisplay(display) {}
+
+SurfaceDeleter::~SurfaceDeleter() {}
+
+void SurfaceDeleter::operator()(Surface *surface)
+{
+ ANGLE_SWALLOW_ERR(surface->onDestroy(mDisplay));
+}
+
+} // namespace egl
diff --git a/gfx/angle/checkout/src/libANGLE/Surface.h b/gfx/angle/checkout/src/libANGLE/Surface.h
new file mode 100644
index 0000000000..862d2f57b2
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Surface.h
@@ -0,0 +1,388 @@
+//
+// Copyright 2002 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.
+//
+
+// Surface.h: Defines the egl::Surface class, representing a drawing surface
+// such as the client area of a window, including any back buffers.
+// Implements EGLSurface and related functionality. [EGL 1.4] section 2.2 page 3.
+
+#ifndef LIBANGLE_SURFACE_H_
+#define LIBANGLE_SURFACE_H_
+
+#include <memory>
+
+#include <EGL/egl.h>
+
+#include "common/PackedEnums.h"
+#include "common/angleutils.h"
+#include "libANGLE/AttributeMap.h"
+#include "libANGLE/Debug.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/RefCountObject.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/SurfaceImpl.h"
+
+namespace gl
+{
+class Context;
+class Framebuffer;
+class Texture;
+} // namespace gl
+
+namespace rx
+{
+class EGLImplFactory;
+}
+
+namespace egl
+{
+class Display;
+struct Config;
+
+using SupportedCompositorTiming = angle::PackedEnumBitSet<CompositorTiming>;
+using SupportedTimestamps = angle::PackedEnumBitSet<Timestamp>;
+
+struct SurfaceState final : private angle::NonCopyable
+{
+ SurfaceState(const egl::Config *configIn, const AttributeMap &attributesIn);
+ ~SurfaceState();
+
+ bool isRobustResourceInitEnabled() const;
+ bool hasProtectedContent() const;
+ EGLint getPreferredSwapInterval() const;
+
+ EGLLabelKHR label;
+ const egl::Config *config;
+ AttributeMap attributes;
+
+ bool timestampsEnabled;
+ bool autoRefreshEnabled;
+ SupportedCompositorTiming supportedCompositorTimings;
+ SupportedTimestamps supportedTimestamps;
+ bool directComposition;
+ EGLenum swapBehavior;
+};
+
+class Surface : public LabeledObject, public gl::FramebufferAttachmentObject
+{
+ public:
+ rx::SurfaceImpl *getImplementation() const { return mImplementation; }
+
+ void setLabel(EGLLabelKHR label) override;
+ EGLLabelKHR getLabel() const override;
+
+ EGLint getType() const;
+
+ Error initialize(const Display *display);
+ Error makeCurrent(const gl::Context *context);
+ Error unMakeCurrent(const gl::Context *context);
+ Error prepareSwap(const gl::Context *context);
+ Error swap(const gl::Context *context);
+ Error swapWithDamage(const gl::Context *context, const EGLint *rects, EGLint n_rects);
+ Error swapWithFrameToken(const gl::Context *context, EGLFrameTokenANGLE frameToken);
+ Error postSubBuffer(const gl::Context *context,
+ EGLint x,
+ EGLint y,
+ EGLint width,
+ EGLint height);
+ Error setPresentationTime(EGLnsecsANDROID time);
+ Error querySurfacePointerANGLE(EGLint attribute, void **value);
+ Error bindTexImage(gl::Context *context, gl::Texture *texture, EGLint buffer);
+ Error releaseTexImage(const gl::Context *context, EGLint buffer);
+
+ Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc);
+ Error getMscRate(EGLint *numerator, EGLint *denominator);
+
+ EGLint isPostSubBufferSupported() const;
+
+ void setSwapInterval(EGLint interval);
+ Error onDestroy(const Display *display);
+
+ void setMipmapLevel(EGLint level);
+ void setMultisampleResolve(EGLenum resolve);
+ void setSwapBehavior(EGLenum behavior);
+
+ void setFixedWidth(EGLint width);
+ void setFixedHeight(EGLint height);
+
+ const Config *getConfig() const;
+
+ // width and height can change with client window resizing
+ EGLint getWidth() const;
+ EGLint getHeight() const;
+ // Note: windows cannot be resized on Android. The approach requires
+ // calling vkGetPhysicalDeviceSurfaceCapabilitiesKHR. However, that is
+ // expensive; and there are troublesome timing issues for other parts of
+ // ANGLE (which cause test failures and crashes). Therefore, a
+ // special-Android-only path is created just for the querying of EGL_WIDTH
+ // and EGL_HEIGHT.
+ // https://issuetracker.google.com/issues/153329980
+ egl::Error getUserWidth(const egl::Display *display, EGLint *value) const;
+ egl::Error getUserHeight(const egl::Display *display, EGLint *value) const;
+ EGLint getPixelAspectRatio() const;
+ EGLenum getRenderBuffer() const;
+ EGLenum getSwapBehavior() const;
+ TextureFormat getTextureFormat() const;
+ EGLenum getTextureTarget() const;
+ bool getLargestPbuffer() const;
+ EGLenum getGLColorspace() const;
+ EGLenum getVGAlphaFormat() const;
+ EGLenum getVGColorspace() const;
+ bool getMipmapTexture() const;
+ EGLint getMipmapLevel() const;
+ EGLint getHorizontalResolution() const;
+ EGLint getVerticalResolution() const;
+ EGLenum getMultisampleResolve() const;
+ bool hasProtectedContent() const override;
+
+ // For lock surface buffer
+ EGLint getBitmapPitch() const;
+ EGLint getBitmapOrigin() const;
+ EGLint getRedOffset() const;
+ EGLint getGreenOffset() const;
+ EGLint getBlueOffset() const;
+ EGLint getAlphaOffset() const;
+ EGLint getLuminanceOffset() const;
+ EGLint getBitmapPixelSize() const;
+ EGLAttribKHR getBitmapPointer() const;
+ egl::Error lockSurfaceKHR(const egl::Display *display, const AttributeMap &attributes);
+ egl::Error unlockSurfaceKHR(const egl::Display *display);
+
+ bool isLocked() const;
+ bool isCurrentOnAnyContext() const { return mIsCurrentOnAnyContext; }
+
+ gl::Texture *getBoundTexture() const { return mTexture; }
+
+ EGLint isFixedSize() const;
+
+ // FramebufferAttachmentObject implementation
+ gl::Extents getAttachmentSize(const gl::ImageIndex &imageIndex) const override;
+ gl::Format getAttachmentFormat(GLenum binding, const gl::ImageIndex &imageIndex) const override;
+ GLsizei getAttachmentSamples(const gl::ImageIndex &imageIndex) const override;
+ bool isRenderable(const gl::Context *context,
+ GLenum binding,
+ const gl::ImageIndex &imageIndex) const override;
+ bool isYUV() const override;
+ bool isCreatedWithAHB() const override;
+
+ void onAttach(const gl::Context *context, rx::Serial framebufferSerial) override {}
+ void onDetach(const gl::Context *context, rx::Serial framebufferSerial) override {}
+ GLuint getId() const override;
+
+ EGLint getOrientation() const { return mOrientation; }
+
+ bool directComposition() const { return mState.directComposition; }
+
+ gl::InitState initState(GLenum binding, const gl::ImageIndex &imageIndex) const override;
+ void setInitState(GLenum binding,
+ const gl::ImageIndex &imageIndex,
+ gl::InitState initState) override;
+
+ bool isRobustResourceInitEnabled() const { return mRobustResourceInitialization; }
+
+ const gl::Format &getBindTexImageFormat() const { return mColorFormat; }
+
+ // EGL_ANDROID_get_frame_timestamps entry points
+ void setTimestampsEnabled(bool enabled);
+ bool isTimestampsEnabled() const;
+
+ // EGL_ANDROID_front_buffer_auto_refresh entry points
+ Error setAutoRefreshEnabled(bool enabled);
+
+ const SupportedCompositorTiming &getSupportedCompositorTimings() const;
+ Error getCompositorTiming(EGLint numTimestamps,
+ const EGLint *names,
+ EGLnsecsANDROID *values) const;
+
+ Error getNextFrameId(EGLuint64KHR *frameId) const;
+ const SupportedTimestamps &getSupportedTimestamps() const;
+ Error getFrameTimestamps(EGLuint64KHR frameId,
+ EGLint numTimestamps,
+ const EGLint *timestamps,
+ EGLnsecsANDROID *values) const;
+
+ // Returns the offset into the texture backing the surface if specified via texture offset
+ // attributes (see EGL_ANGLE_d3d_texture_client_buffer extension). Returns zero offset
+ // otherwise.
+ const gl::Offset &getTextureOffset() const { return mTextureOffset; }
+
+ Error getBufferAge(const gl::Context *context, EGLint *age);
+
+ Error setRenderBuffer(EGLint renderBuffer);
+
+ bool bufferAgeQueriedSinceLastSwap() const { return mBufferAgeQueriedSinceLastSwap; }
+ void setDamageRegion(const EGLint *rects, EGLint n_rects);
+ bool isDamageRegionSet() const { return mIsDamageRegionSet; }
+
+ void addRef() { mRefCount++; }
+ void release()
+ {
+ ASSERT(mRefCount > 0);
+ mRefCount--;
+ }
+
+ protected:
+ Surface(EGLint surfaceType,
+ GLuint serialId,
+ const egl::Config *config,
+ const AttributeMap &attributes,
+ bool forceRobustResourceInit,
+ EGLenum buftype = EGL_NONE);
+ ~Surface() override;
+ rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override;
+
+ // ANGLE-only method, used internally
+ friend class gl::Texture;
+ Error releaseTexImageFromTexture(const gl::Context *context);
+
+ SurfaceState mState;
+ rx::SurfaceImpl *mImplementation;
+ int mRefCount;
+ bool mDestroyed;
+
+ EGLint mType;
+ EGLenum mBuftype;
+
+ bool mPostSubBufferRequested;
+
+ bool mLargestPbuffer;
+ EGLenum mGLColorspace;
+ EGLenum mVGAlphaFormat;
+ EGLenum mVGColorspace;
+ bool mMipmapTexture;
+ EGLint mMipmapLevel;
+ EGLint mHorizontalResolution;
+ EGLint mVerticalResolution;
+ EGLenum mMultisampleResolve;
+
+ bool mFixedSize;
+ size_t mFixedWidth;
+ size_t mFixedHeight;
+
+ bool mRobustResourceInitialization;
+
+ TextureFormat mTextureFormat;
+ EGLenum mTextureTarget;
+
+ EGLint mPixelAspectRatio; // Display aspect ratio
+ EGLenum mRenderBuffer; // Render buffer
+
+ EGLint mOrientation;
+
+ // We don't use a binding pointer here. We don't ever want to own an orphaned texture. If a
+ // Texture is deleted the Surface is unbound in onDestroy.
+ gl::Texture *mTexture;
+
+ gl::Format mColorFormat;
+ gl::Format mDSFormat;
+
+ gl::Offset mTextureOffset;
+
+ bool mIsCurrentOnAnyContext; // The surface is current to a context/client API
+ uint8_t *mLockBufferPtr; // Memory owned by backend.
+ EGLint mLockBufferPitch;
+
+ bool mBufferAgeQueriedSinceLastSwap;
+ bool mIsDamageRegionSet;
+
+ private:
+ Error getBufferAgeImpl(const gl::Context *context, EGLint *age) const;
+
+ Error destroyImpl(const Display *display);
+
+ void postSwap(const gl::Context *context);
+ Error releaseRef(const Display *display);
+
+ // ObserverInterface implementation.
+ void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override;
+
+ gl::InitState mColorInitState;
+ gl::InitState mDepthStencilInitState;
+ angle::ObserverBinding mImplObserverBinding;
+
+ GLuint mSerialId;
+};
+
+class WindowSurface final : public Surface
+{
+ public:
+ WindowSurface(rx::EGLImplFactory *implFactory,
+ const Config *config,
+ EGLNativeWindowType window,
+ const AttributeMap &attribs,
+ bool robustResourceInit);
+ ~WindowSurface() override;
+};
+
+class PbufferSurface final : public Surface
+{
+ public:
+ PbufferSurface(rx::EGLImplFactory *implFactory,
+ const Config *config,
+ const AttributeMap &attribs,
+ bool robustResourceInit);
+ PbufferSurface(rx::EGLImplFactory *implFactory,
+ const Config *config,
+ EGLenum buftype,
+ EGLClientBuffer clientBuffer,
+ const AttributeMap &attribs,
+ bool robustResourceInit);
+
+ protected:
+ ~PbufferSurface() override;
+};
+
+class PixmapSurface final : public Surface
+{
+ public:
+ PixmapSurface(rx::EGLImplFactory *implFactory,
+ const Config *config,
+ NativePixmapType nativePixmap,
+ const AttributeMap &attribs,
+ bool robustResourceInit);
+
+ protected:
+ ~PixmapSurface() override;
+};
+
+class [[nodiscard]] ScopedSurfaceRef
+{
+ public:
+ ScopedSurfaceRef(Surface *surface) : mSurface(surface)
+ {
+ if (mSurface)
+ {
+ mSurface->addRef();
+ }
+ }
+ ~ScopedSurfaceRef()
+ {
+ if (mSurface)
+ {
+ mSurface->release();
+ }
+ }
+
+ private:
+ Surface *const mSurface;
+};
+
+class SurfaceDeleter final
+{
+ public:
+ SurfaceDeleter(const Display *display);
+ ~SurfaceDeleter();
+ void operator()(Surface *surface);
+
+ private:
+ const Display *mDisplay;
+};
+
+using SurfacePointer = std::unique_ptr<Surface, SurfaceDeleter>;
+
+} // namespace egl
+
+#endif // LIBANGLE_SURFACE_H_
diff --git a/gfx/angle/checkout/src/libANGLE/Texture.cpp b/gfx/angle/checkout/src/libANGLE/Texture.cpp
new file mode 100644
index 0000000000..89930d1c29
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Texture.cpp
@@ -0,0 +1,2494 @@
+//
+// Copyright 2002 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.
+//
+
+// Texture.cpp: Implements the gl::Texture class. [OpenGL ES 2.0.24] section 3.7 page 63.
+
+#include "libANGLE/Texture.h"
+
+#include "common/mathutil.h"
+#include "common/utilities.h"
+#include "libANGLE/Config.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Image.h"
+#include "libANGLE/State.h"
+#include "libANGLE/Surface.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/GLImplFactory.h"
+#include "libANGLE/renderer/TextureImpl.h"
+
+namespace gl
+{
+
+namespace
+{
+constexpr angle::SubjectIndex kBufferSubjectIndex = 2;
+static_assert(kBufferSubjectIndex != rx::kTextureImageImplObserverMessageIndex, "Index collision");
+static_assert(kBufferSubjectIndex != rx::kTextureImageSiblingMessageIndex, "Index collision");
+
+bool IsPointSampled(const SamplerState &samplerState)
+{
+ return (samplerState.getMagFilter() == GL_NEAREST &&
+ (samplerState.getMinFilter() == GL_NEAREST ||
+ samplerState.getMinFilter() == GL_NEAREST_MIPMAP_NEAREST));
+}
+
+size_t GetImageDescIndex(TextureTarget target, size_t level)
+{
+ return IsCubeMapFaceTarget(target) ? (level * 6 + CubeMapTextureTargetToFaceIndex(target))
+ : level;
+}
+
+InitState DetermineInitState(const Context *context, Buffer *unpackBuffer, const uint8_t *pixels)
+{
+ // Can happen in tests.
+ if (!context || !context->isRobustResourceInitEnabled())
+ {
+ return InitState::Initialized;
+ }
+
+ return (!pixels && !unpackBuffer) ? InitState::MayNeedInit : InitState::Initialized;
+}
+} // namespace
+
+GLenum ConvertToNearestFilterMode(GLenum filterMode)
+{
+ switch (filterMode)
+ {
+ case GL_LINEAR:
+ return GL_NEAREST;
+ case GL_LINEAR_MIPMAP_NEAREST:
+ return GL_NEAREST_MIPMAP_NEAREST;
+ case GL_LINEAR_MIPMAP_LINEAR:
+ return GL_NEAREST_MIPMAP_LINEAR;
+ default:
+ return filterMode;
+ }
+}
+
+GLenum ConvertToNearestMipFilterMode(GLenum filterMode)
+{
+ switch (filterMode)
+ {
+ case GL_LINEAR_MIPMAP_LINEAR:
+ return GL_LINEAR_MIPMAP_NEAREST;
+ case GL_NEAREST_MIPMAP_LINEAR:
+ return GL_NEAREST_MIPMAP_NEAREST;
+ default:
+ return filterMode;
+ }
+}
+
+bool IsMipmapSupported(const TextureType &type)
+{
+ if (type == TextureType::_2DMultisample || type == TextureType::Buffer)
+ {
+ return false;
+ }
+ return true;
+}
+
+SwizzleState::SwizzleState()
+ : swizzleRed(GL_RED), swizzleGreen(GL_GREEN), swizzleBlue(GL_BLUE), swizzleAlpha(GL_ALPHA)
+{}
+
+SwizzleState::SwizzleState(GLenum red, GLenum green, GLenum blue, GLenum alpha)
+ : swizzleRed(red), swizzleGreen(green), swizzleBlue(blue), swizzleAlpha(alpha)
+{}
+
+bool SwizzleState::swizzleRequired() const
+{
+ return swizzleRed != GL_RED || swizzleGreen != GL_GREEN || swizzleBlue != GL_BLUE ||
+ swizzleAlpha != GL_ALPHA;
+}
+
+bool SwizzleState::operator==(const SwizzleState &other) const
+{
+ return swizzleRed == other.swizzleRed && swizzleGreen == other.swizzleGreen &&
+ swizzleBlue == other.swizzleBlue && swizzleAlpha == other.swizzleAlpha;
+}
+
+bool SwizzleState::operator!=(const SwizzleState &other) const
+{
+ return !(*this == other);
+}
+
+TextureState::TextureState(TextureType type)
+ : mType(type),
+ mSamplerState(SamplerState::CreateDefaultForTarget(type)),
+ mSrgbOverride(SrgbOverride::Default),
+ mBaseLevel(0),
+ mMaxLevel(kInitialMaxLevel),
+ mDepthStencilTextureMode(GL_DEPTH_COMPONENT),
+ mHasBeenBoundAsImage(false),
+ mIs3DAndHasBeenBoundAs2DImage(false),
+ mHasBeenBoundAsAttachment(false),
+ mImmutableFormat(false),
+ mImmutableLevels(0),
+ mUsage(GL_NONE),
+ mHasProtectedContent(false),
+ mImageDescs((IMPLEMENTATION_MAX_TEXTURE_LEVELS + 1) * (type == TextureType::CubeMap ? 6 : 1)),
+ mCropRect(0, 0, 0, 0),
+ mGenerateMipmapHint(GL_FALSE),
+ mInitState(InitState::Initialized),
+ mCachedSamplerFormat(SamplerFormat::InvalidEnum),
+ mCachedSamplerCompareMode(GL_NONE),
+ mCachedSamplerFormatValid(false)
+{}
+
+TextureState::~TextureState() {}
+
+bool TextureState::swizzleRequired() const
+{
+ return mSwizzleState.swizzleRequired();
+}
+
+GLuint TextureState::getEffectiveBaseLevel() const
+{
+ if (mImmutableFormat)
+ {
+ // GLES 3.0.4 section 3.8.10
+ return std::min(mBaseLevel, mImmutableLevels - 1);
+ }
+ // Some classes use the effective base level to index arrays with level data. By clamping the
+ // effective base level to max levels these arrays need just one extra item to store properties
+ // that should be returned for all out-of-range base level values, instead of needing special
+ // handling for out-of-range base levels.
+ return std::min(mBaseLevel, static_cast<GLuint>(IMPLEMENTATION_MAX_TEXTURE_LEVELS));
+}
+
+GLuint TextureState::getEffectiveMaxLevel() const
+{
+ if (mImmutableFormat)
+ {
+ // GLES 3.0.4 section 3.8.10
+ GLuint clampedMaxLevel = std::max(mMaxLevel, getEffectiveBaseLevel());
+ clampedMaxLevel = std::min(clampedMaxLevel, mImmutableLevels - 1);
+ return clampedMaxLevel;
+ }
+ return mMaxLevel;
+}
+
+GLuint TextureState::getMipmapMaxLevel() const
+{
+ const ImageDesc &baseImageDesc = getImageDesc(getBaseImageTarget(), getEffectiveBaseLevel());
+ GLuint expectedMipLevels = 0;
+ if (mType == TextureType::_3D)
+ {
+ const int maxDim = std::max(std::max(baseImageDesc.size.width, baseImageDesc.size.height),
+ baseImageDesc.size.depth);
+ expectedMipLevels = static_cast<GLuint>(log2(maxDim));
+ }
+ else
+ {
+ expectedMipLevels = static_cast<GLuint>(
+ log2(std::max(baseImageDesc.size.width, baseImageDesc.size.height)));
+ }
+
+ return std::min<GLuint>(getEffectiveBaseLevel() + expectedMipLevels, getEffectiveMaxLevel());
+}
+
+bool TextureState::setBaseLevel(GLuint baseLevel)
+{
+ if (mBaseLevel != baseLevel)
+ {
+ mBaseLevel = baseLevel;
+ return true;
+ }
+ return false;
+}
+
+bool TextureState::setMaxLevel(GLuint maxLevel)
+{
+ if (mMaxLevel != maxLevel)
+ {
+ mMaxLevel = maxLevel;
+ return true;
+ }
+
+ return false;
+}
+
+// Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
+// According to [OpenGL ES 3.0.5] section 3.8.13 Texture Completeness page 160 any
+// per-level checks begin at the base-level.
+// For OpenGL ES2 the base level is always zero.
+bool TextureState::isCubeComplete() const
+{
+ ASSERT(mType == TextureType::CubeMap);
+
+ angle::EnumIterator<TextureTarget> face = kCubeMapTextureTargetMin;
+ const ImageDesc &baseImageDesc = getImageDesc(*face, getEffectiveBaseLevel());
+ if (baseImageDesc.size.width == 0 || baseImageDesc.size.width != baseImageDesc.size.height)
+ {
+ return false;
+ }
+
+ ++face;
+
+ for (; face != kAfterCubeMapTextureTargetMax; ++face)
+ {
+ const ImageDesc &faceImageDesc = getImageDesc(*face, getEffectiveBaseLevel());
+ if (faceImageDesc.size.width != baseImageDesc.size.width ||
+ faceImageDesc.size.height != baseImageDesc.size.height ||
+ !Format::SameSized(faceImageDesc.format, baseImageDesc.format))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+const ImageDesc &TextureState::getBaseLevelDesc() const
+{
+ ASSERT(mType != TextureType::CubeMap || isCubeComplete());
+ return getImageDesc(getBaseImageTarget(), getEffectiveBaseLevel());
+}
+
+const ImageDesc &TextureState::getLevelZeroDesc() const
+{
+ ASSERT(mType != TextureType::CubeMap || isCubeComplete());
+ return getImageDesc(getBaseImageTarget(), 0);
+}
+
+void TextureState::setCrop(const Rectangle &rect)
+{
+ mCropRect = rect;
+}
+
+const Rectangle &TextureState::getCrop() const
+{
+ return mCropRect;
+}
+
+void TextureState::setGenerateMipmapHint(GLenum hint)
+{
+ mGenerateMipmapHint = hint;
+}
+
+GLenum TextureState::getGenerateMipmapHint() const
+{
+ return mGenerateMipmapHint;
+}
+
+SamplerFormat TextureState::computeRequiredSamplerFormat(const SamplerState &samplerState) const
+{
+ const ImageDesc &baseImageDesc = getImageDesc(getBaseImageTarget(), getEffectiveBaseLevel());
+ if ((baseImageDesc.format.info->format == GL_DEPTH_COMPONENT ||
+ baseImageDesc.format.info->format == GL_DEPTH_STENCIL) &&
+ samplerState.getCompareMode() != GL_NONE)
+ {
+ return SamplerFormat::Shadow;
+ }
+ else
+ {
+ switch (baseImageDesc.format.info->componentType)
+ {
+ case GL_UNSIGNED_NORMALIZED:
+ case GL_SIGNED_NORMALIZED:
+ case GL_FLOAT:
+ return SamplerFormat::Float;
+ case GL_INT:
+ return SamplerFormat::Signed;
+ case GL_UNSIGNED_INT:
+ return SamplerFormat::Unsigned;
+ default:
+ return SamplerFormat::InvalidEnum;
+ }
+ }
+}
+
+bool TextureState::computeSamplerCompleteness(const SamplerState &samplerState,
+ const State &state) const
+{
+ // Buffer textures cannot be incomplete.
+ if (mType == TextureType::Buffer)
+ {
+ return true;
+ }
+
+ // Check for all non-format-based completeness rules
+ if (!computeSamplerCompletenessForCopyImage(samplerState, state))
+ {
+ return false;
+ }
+
+ const ImageDesc &baseImageDesc = getImageDesc(getBaseImageTarget(), getEffectiveBaseLevel());
+
+ // According to es 3.1 spec, texture is justified as incomplete if sized internalformat is
+ // unfilterable(table 20.11) and filter is not GL_NEAREST(8.16). The default value of minFilter
+ // is NEAREST_MIPMAP_LINEAR and magFilter is LINEAR(table 20.11,). For multismaple texture,
+ // filter state of multisample texture is ignored(11.1.3.3). So it shouldn't be judged as
+ // incomplete texture. So, we ignore filtering for multisample texture completeness here.
+ if (!IsMultisampled(mType) &&
+ !baseImageDesc.format.info->filterSupport(state.getClientVersion(),
+ state.getExtensions()) &&
+ !IsPointSampled(samplerState))
+ {
+ return false;
+ }
+
+ // OpenGLES 3.0.2 spec section 3.8.13 states that a texture is not mipmap complete if:
+ // The internalformat specified for the texture arrays is a sized internal depth or
+ // 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.
+ if (!IsMultisampled(mType) && baseImageDesc.format.info->depthBits > 0 &&
+ state.getClientMajorVersion() >= 3)
+ {
+ // 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.getCompareMode() == GL_NONE && baseImageDesc.format.info->sized)
+ {
+ if ((samplerState.getMinFilter() != GL_NEAREST &&
+ samplerState.getMinFilter() != GL_NEAREST_MIPMAP_NEAREST) ||
+ samplerState.getMagFilter() != GL_NEAREST)
+ {
+ return false;
+ }
+ }
+ }
+
+ // OpenGLES 3.1 spec section 8.16 states that a texture is not mipmap complete if:
+ // The internalformat specified for the texture is DEPTH_STENCIL format, the value of
+ // DEPTH_STENCIL_TEXTURE_MODE is STENCIL_INDEX, and either the magnification filter is
+ // not NEAREST or the minification filter is neither NEAREST nor NEAREST_MIPMAP_NEAREST.
+ // However, the ES 3.1 spec differs from the statement above, because it is incorrect.
+ // See the issue at https://github.com/KhronosGroup/OpenGL-API/issues/33.
+ // For multismaple texture, filter state of multisample texture is ignored(11.1.3.3).
+ // So it shouldn't be judged as incomplete texture. So, we ignore filtering for multisample
+ // texture completeness here.
+ if (!IsMultisampled(mType) && baseImageDesc.format.info->depthBits > 0 &&
+ mDepthStencilTextureMode == GL_STENCIL_INDEX)
+ {
+ if ((samplerState.getMinFilter() != GL_NEAREST &&
+ samplerState.getMinFilter() != GL_NEAREST_MIPMAP_NEAREST) ||
+ samplerState.getMagFilter() != GL_NEAREST)
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+// CopyImageSubData has more lax rules for texture completeness: format-based completeness rules are
+// ignored, so a texture can still be considered complete even if it violates format-specific
+// conditions
+bool TextureState::computeSamplerCompletenessForCopyImage(const SamplerState &samplerState,
+ const State &state) const
+{
+ // Buffer textures cannot be incomplete.
+ if (mType == TextureType::Buffer)
+ {
+ return true;
+ }
+
+ if (!mImmutableFormat && mBaseLevel > mMaxLevel)
+ {
+ return false;
+ }
+ const ImageDesc &baseImageDesc = getImageDesc(getBaseImageTarget(), getEffectiveBaseLevel());
+ if (baseImageDesc.size.width == 0 || baseImageDesc.size.height == 0 ||
+ baseImageDesc.size.depth == 0)
+ {
+ return false;
+ }
+ // The cases where the texture is incomplete because base level is out of range should be
+ // handled by the above condition.
+ ASSERT(mBaseLevel < IMPLEMENTATION_MAX_TEXTURE_LEVELS || mImmutableFormat);
+
+ if (mType == TextureType::CubeMap && baseImageDesc.size.width != baseImageDesc.size.height)
+ {
+ return false;
+ }
+
+ bool npotSupport = state.getExtensions().textureNpotOES || state.getClientMajorVersion() >= 3;
+ if (!npotSupport)
+ {
+ if ((samplerState.getWrapS() != GL_CLAMP_TO_EDGE &&
+ samplerState.getWrapS() != GL_CLAMP_TO_BORDER && !isPow2(baseImageDesc.size.width)) ||
+ (samplerState.getWrapT() != GL_CLAMP_TO_EDGE &&
+ samplerState.getWrapT() != GL_CLAMP_TO_BORDER && !isPow2(baseImageDesc.size.height)))
+ {
+ return false;
+ }
+ }
+
+ if (IsMipmapSupported(mType) && IsMipmapFiltered(samplerState.getMinFilter()))
+ {
+ if (!npotSupport)
+ {
+ if (!isPow2(baseImageDesc.size.width) || !isPow2(baseImageDesc.size.height))
+ {
+ return false;
+ }
+ }
+
+ if (!computeMipmapCompleteness())
+ {
+ return false;
+ }
+ }
+ else
+ {
+ if (mType == TextureType::CubeMap && !isCubeComplete())
+ {
+ return false;
+ }
+ }
+
+ // From GL_OES_EGL_image_external_essl3: If state is present in a sampler object bound to a
+ // texture unit that would have been rejected by a call to TexParameter* for the texture bound
+ // to that unit, the behavior of the implementation is as if the texture were incomplete. For
+ // example, if TEXTURE_WRAP_S or TEXTURE_WRAP_T is set to anything but CLAMP_TO_EDGE on the
+ // sampler object bound to a texture unit and the texture bound to that unit is an external
+ // texture and EXT_EGL_image_external_wrap_modes is not enabled, the texture will be considered
+ // incomplete.
+ // Sampler object state which does not affect sampling for the type of texture bound
+ // to a texture unit, such as TEXTURE_WRAP_R for an external texture, does not affect
+ // completeness.
+ if (mType == TextureType::External)
+ {
+ if (!state.getExtensions().EGLImageExternalWrapModesEXT)
+ {
+ if (samplerState.getWrapS() != GL_CLAMP_TO_EDGE ||
+ samplerState.getWrapT() != GL_CLAMP_TO_EDGE)
+ {
+ return false;
+ }
+ }
+
+ if (samplerState.getMinFilter() != GL_LINEAR && samplerState.getMinFilter() != GL_NEAREST)
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool TextureState::computeMipmapCompleteness() const
+{
+ const GLuint maxLevel = getMipmapMaxLevel();
+
+ for (GLuint level = getEffectiveBaseLevel(); level <= maxLevel; level++)
+ {
+ if (mType == TextureType::CubeMap)
+ {
+ for (TextureTarget face : AllCubeFaceTextureTargets())
+ {
+ if (!computeLevelCompleteness(face, level))
+ {
+ return false;
+ }
+ }
+ }
+ else
+ {
+ if (!computeLevelCompleteness(NonCubeTextureTypeToTarget(mType), level))
+ {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+bool TextureState::computeLevelCompleteness(TextureTarget target, size_t level) const
+{
+ ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+
+ if (mImmutableFormat)
+ {
+ return true;
+ }
+
+ const ImageDesc &baseImageDesc = getImageDesc(getBaseImageTarget(), getEffectiveBaseLevel());
+ if (baseImageDesc.size.width == 0 || baseImageDesc.size.height == 0 ||
+ baseImageDesc.size.depth == 0)
+ {
+ return false;
+ }
+
+ const ImageDesc &levelImageDesc = getImageDesc(target, level);
+ if (levelImageDesc.size.width == 0 || levelImageDesc.size.height == 0 ||
+ levelImageDesc.size.depth == 0)
+ {
+ return false;
+ }
+
+ if (!Format::SameSized(levelImageDesc.format, baseImageDesc.format))
+ {
+ return false;
+ }
+
+ ASSERT(level >= getEffectiveBaseLevel());
+ const size_t relativeLevel = level - getEffectiveBaseLevel();
+ if (levelImageDesc.size.width != std::max(1, baseImageDesc.size.width >> relativeLevel))
+ {
+ return false;
+ }
+
+ if (levelImageDesc.size.height != std::max(1, baseImageDesc.size.height >> relativeLevel))
+ {
+ return false;
+ }
+
+ if (mType == TextureType::_3D)
+ {
+ if (levelImageDesc.size.depth != std::max(1, baseImageDesc.size.depth >> relativeLevel))
+ {
+ return false;
+ }
+ }
+ else if (IsArrayTextureType(mType))
+ {
+ if (levelImageDesc.size.depth != baseImageDesc.size.depth)
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+TextureTarget TextureState::getBaseImageTarget() const
+{
+ return mType == TextureType::CubeMap ? kCubeMapTextureTargetMin
+ : NonCubeTextureTypeToTarget(mType);
+}
+
+GLuint TextureState::getEnabledLevelCount() const
+{
+ GLuint levelCount = 0;
+ const GLuint baseLevel = getEffectiveBaseLevel();
+ const GLuint maxLevel = std::min(getEffectiveMaxLevel(), getMipmapMaxLevel());
+
+ // The mip chain will have either one or more sequential levels, or max levels,
+ // but not a sparse one.
+ Optional<Extents> expectedSize;
+ for (size_t enabledLevel = baseLevel; enabledLevel <= maxLevel; ++enabledLevel, ++levelCount)
+ {
+ // Note: for cube textures, we only check the first face.
+ TextureTarget target = TextureTypeToTarget(mType, 0);
+ size_t descIndex = GetImageDescIndex(target, enabledLevel);
+ const Extents &levelSize = mImageDescs[descIndex].size;
+
+ if (levelSize.empty())
+ {
+ break;
+ }
+ if (expectedSize.valid())
+ {
+ Extents newSize = expectedSize.value();
+ newSize.width = std::max(1, newSize.width >> 1);
+ newSize.height = std::max(1, newSize.height >> 1);
+
+ if (!IsArrayTextureType(mType))
+ {
+ newSize.depth = std::max(1, newSize.depth >> 1);
+ }
+
+ if (newSize != levelSize)
+ {
+ break;
+ }
+ }
+ expectedSize = levelSize;
+ }
+
+ return levelCount;
+}
+
+ImageDesc::ImageDesc()
+ : ImageDesc(Extents(0, 0, 0), Format::Invalid(), 0, GL_TRUE, InitState::Initialized)
+{}
+
+ImageDesc::ImageDesc(const Extents &size, const Format &format, const InitState initState)
+ : size(size), format(format), samples(0), fixedSampleLocations(GL_TRUE), initState(initState)
+{}
+
+ImageDesc::ImageDesc(const Extents &size,
+ const Format &format,
+ const GLsizei samples,
+ const bool fixedSampleLocations,
+ const InitState initState)
+ : size(size),
+ format(format),
+ samples(samples),
+ fixedSampleLocations(fixedSampleLocations),
+ initState(initState)
+{}
+
+GLint ImageDesc::getMemorySize() const
+{
+ // Assume allocated size is around width * height * depth * samples * pixelBytes
+ angle::CheckedNumeric<GLint> levelSize = 1;
+ levelSize *= format.info->pixelBytes;
+ levelSize *= size.width;
+ levelSize *= size.height;
+ levelSize *= size.depth;
+ levelSize *= std::max(samples, 1);
+ return levelSize.ValueOrDefault(std::numeric_limits<GLint>::max());
+}
+
+const ImageDesc &TextureState::getImageDesc(TextureTarget target, size_t level) const
+{
+ size_t descIndex = GetImageDescIndex(target, level);
+ ASSERT(descIndex < mImageDescs.size());
+ return mImageDescs[descIndex];
+}
+
+void TextureState::setImageDesc(TextureTarget target, size_t level, const ImageDesc &desc)
+{
+ size_t descIndex = GetImageDescIndex(target, level);
+ ASSERT(descIndex < mImageDescs.size());
+ mImageDescs[descIndex] = desc;
+ if (desc.initState == InitState::MayNeedInit)
+ {
+ mInitState = InitState::MayNeedInit;
+ }
+ else
+ {
+ // Scan for any uninitialized images. If there are none, set the init state of the entire
+ // texture to initialized. The cost of the scan is only paid after doing image
+ // initialization which is already very expensive.
+ bool allImagesInitialized = true;
+
+ for (const ImageDesc &initDesc : mImageDescs)
+ {
+ if (initDesc.initState == InitState::MayNeedInit)
+ {
+ allImagesInitialized = false;
+ break;
+ }
+ }
+
+ if (allImagesInitialized)
+ {
+ mInitState = InitState::Initialized;
+ }
+ }
+}
+
+// Note that an ImageIndex that represents an entire level of a cube map corresponds to 6
+// ImageDescs, so if the cube map is cube complete, we return the ImageDesc of the first cube
+// face, and we don't allow using this function when the cube map is not cube complete.
+const ImageDesc &TextureState::getImageDesc(const ImageIndex &imageIndex) const
+{
+ if (imageIndex.isEntireLevelCubeMap())
+ {
+ ASSERT(isCubeComplete());
+ const GLint levelIndex = imageIndex.getLevelIndex();
+ return getImageDesc(kCubeMapTextureTargetMin, levelIndex);
+ }
+
+ return getImageDesc(imageIndex.getTarget(), imageIndex.getLevelIndex());
+}
+
+void TextureState::setImageDescChain(GLuint baseLevel,
+ GLuint maxLevel,
+ Extents baseSize,
+ const Format &format,
+ InitState initState)
+{
+ for (GLuint level = baseLevel; level <= maxLevel; level++)
+ {
+ int relativeLevel = (level - baseLevel);
+ Extents levelSize(std::max<int>(baseSize.width >> relativeLevel, 1),
+ std::max<int>(baseSize.height >> relativeLevel, 1),
+ (IsArrayTextureType(mType))
+ ? baseSize.depth
+ : std::max<int>(baseSize.depth >> relativeLevel, 1));
+ ImageDesc levelInfo(levelSize, format, initState);
+
+ if (mType == TextureType::CubeMap)
+ {
+ for (TextureTarget face : AllCubeFaceTextureTargets())
+ {
+ setImageDesc(face, level, levelInfo);
+ }
+ }
+ else
+ {
+ setImageDesc(NonCubeTextureTypeToTarget(mType), level, levelInfo);
+ }
+ }
+}
+
+void TextureState::setImageDescChainMultisample(Extents baseSize,
+ const Format &format,
+ GLsizei samples,
+ bool fixedSampleLocations,
+ InitState initState)
+{
+ ASSERT(mType == TextureType::_2DMultisample || mType == TextureType::_2DMultisampleArray);
+ ImageDesc levelInfo(baseSize, format, samples, fixedSampleLocations, initState);
+ setImageDesc(NonCubeTextureTypeToTarget(mType), 0, levelInfo);
+}
+
+void TextureState::clearImageDesc(TextureTarget target, size_t level)
+{
+ setImageDesc(target, level, ImageDesc());
+}
+
+void TextureState::clearImageDescs()
+{
+ for (size_t descIndex = 0; descIndex < mImageDescs.size(); descIndex++)
+ {
+ mImageDescs[descIndex] = ImageDesc();
+ }
+}
+
+Texture::Texture(rx::GLImplFactory *factory, TextureID id, TextureType type)
+ : RefCountObject(factory->generateSerial(), id),
+ mState(type),
+ mTexture(factory->createTexture(mState)),
+ mImplObserver(this, rx::kTextureImageImplObserverMessageIndex),
+ mBufferObserver(this, kBufferSubjectIndex),
+ mBoundSurface(nullptr),
+ mBoundStream(nullptr)
+{
+ mImplObserver.bind(mTexture);
+
+ // Initially assume the implementation is dirty.
+ mDirtyBits.set(DIRTY_BIT_IMPLEMENTATION);
+}
+
+void Texture::onDestroy(const Context *context)
+{
+ if (mBoundSurface)
+ {
+ ANGLE_SWALLOW_ERR(mBoundSurface->releaseTexImage(context, EGL_BACK_BUFFER));
+ mBoundSurface = nullptr;
+ }
+ if (mBoundStream)
+ {
+ mBoundStream->releaseTextures();
+ mBoundStream = nullptr;
+ }
+
+ egl::RefCountObjectReleaser<egl::Image> releaseImage;
+ (void)orphanImages(context, &releaseImage);
+
+ mState.mBuffer.set(context, nullptr, 0, 0);
+
+ if (mTexture)
+ {
+ mTexture->onDestroy(context);
+ }
+}
+
+Texture::~Texture()
+{
+ SafeDelete(mTexture);
+}
+
+angle::Result Texture::setLabel(const Context *context, const std::string &label)
+{
+ mState.mLabel = label;
+ return mTexture->onLabelUpdate(context);
+}
+
+const std::string &Texture::getLabel() const
+{
+ return mState.mLabel;
+}
+
+void Texture::setSwizzleRed(const Context *context, GLenum swizzleRed)
+{
+ if (mState.mSwizzleState.swizzleRed != swizzleRed)
+ {
+ mState.mSwizzleState.swizzleRed = swizzleRed;
+ signalDirtyState(DIRTY_BIT_SWIZZLE_RED);
+ }
+}
+
+GLenum Texture::getSwizzleRed() const
+{
+ return mState.mSwizzleState.swizzleRed;
+}
+
+void Texture::setSwizzleGreen(const Context *context, GLenum swizzleGreen)
+{
+ if (mState.mSwizzleState.swizzleGreen != swizzleGreen)
+ {
+ mState.mSwizzleState.swizzleGreen = swizzleGreen;
+ signalDirtyState(DIRTY_BIT_SWIZZLE_GREEN);
+ }
+}
+
+GLenum Texture::getSwizzleGreen() const
+{
+ return mState.mSwizzleState.swizzleGreen;
+}
+
+void Texture::setSwizzleBlue(const Context *context, GLenum swizzleBlue)
+{
+ if (mState.mSwizzleState.swizzleBlue != swizzleBlue)
+ {
+ mState.mSwizzleState.swizzleBlue = swizzleBlue;
+ signalDirtyState(DIRTY_BIT_SWIZZLE_BLUE);
+ }
+}
+
+GLenum Texture::getSwizzleBlue() const
+{
+ return mState.mSwizzleState.swizzleBlue;
+}
+
+void Texture::setSwizzleAlpha(const Context *context, GLenum swizzleAlpha)
+{
+ if (mState.mSwizzleState.swizzleAlpha != swizzleAlpha)
+ {
+ mState.mSwizzleState.swizzleAlpha = swizzleAlpha;
+ signalDirtyState(DIRTY_BIT_SWIZZLE_ALPHA);
+ }
+}
+
+GLenum Texture::getSwizzleAlpha() const
+{
+ return mState.mSwizzleState.swizzleAlpha;
+}
+
+void Texture::setMinFilter(const Context *context, GLenum minFilter)
+{
+ if (mState.mSamplerState.setMinFilter(minFilter))
+ {
+ signalDirtyState(DIRTY_BIT_MIN_FILTER);
+ }
+}
+
+GLenum Texture::getMinFilter() const
+{
+ return mState.mSamplerState.getMinFilter();
+}
+
+void Texture::setMagFilter(const Context *context, GLenum magFilter)
+{
+ if (mState.mSamplerState.setMagFilter(magFilter))
+ {
+ signalDirtyState(DIRTY_BIT_MAG_FILTER);
+ }
+}
+
+GLenum Texture::getMagFilter() const
+{
+ return mState.mSamplerState.getMagFilter();
+}
+
+void Texture::setWrapS(const Context *context, GLenum wrapS)
+{
+ if (mState.mSamplerState.setWrapS(wrapS))
+ {
+ signalDirtyState(DIRTY_BIT_WRAP_S);
+ }
+}
+
+GLenum Texture::getWrapS() const
+{
+ return mState.mSamplerState.getWrapS();
+}
+
+void Texture::setWrapT(const Context *context, GLenum wrapT)
+{
+ if (mState.mSamplerState.getWrapT() == wrapT)
+ return;
+ if (mState.mSamplerState.setWrapT(wrapT))
+ {
+ signalDirtyState(DIRTY_BIT_WRAP_T);
+ }
+}
+
+GLenum Texture::getWrapT() const
+{
+ return mState.mSamplerState.getWrapT();
+}
+
+void Texture::setWrapR(const Context *context, GLenum wrapR)
+{
+ if (mState.mSamplerState.setWrapR(wrapR))
+ {
+ signalDirtyState(DIRTY_BIT_WRAP_R);
+ }
+}
+
+GLenum Texture::getWrapR() const
+{
+ return mState.mSamplerState.getWrapR();
+}
+
+void Texture::setMaxAnisotropy(const Context *context, float maxAnisotropy)
+{
+ if (mState.mSamplerState.setMaxAnisotropy(maxAnisotropy))
+ {
+ signalDirtyState(DIRTY_BIT_MAX_ANISOTROPY);
+ }
+}
+
+float Texture::getMaxAnisotropy() const
+{
+ return mState.mSamplerState.getMaxAnisotropy();
+}
+
+void Texture::setMinLod(const Context *context, GLfloat minLod)
+{
+ if (mState.mSamplerState.setMinLod(minLod))
+ {
+ signalDirtyState(DIRTY_BIT_MIN_LOD);
+ }
+}
+
+GLfloat Texture::getMinLod() const
+{
+ return mState.mSamplerState.getMinLod();
+}
+
+void Texture::setMaxLod(const Context *context, GLfloat maxLod)
+{
+ if (mState.mSamplerState.setMaxLod(maxLod))
+ {
+ signalDirtyState(DIRTY_BIT_MAX_LOD);
+ }
+}
+
+GLfloat Texture::getMaxLod() const
+{
+ return mState.mSamplerState.getMaxLod();
+}
+
+void Texture::setCompareMode(const Context *context, GLenum compareMode)
+{
+ if (mState.mSamplerState.setCompareMode(compareMode))
+ {
+ signalDirtyState(DIRTY_BIT_COMPARE_MODE);
+ }
+}
+
+GLenum Texture::getCompareMode() const
+{
+ return mState.mSamplerState.getCompareMode();
+}
+
+void Texture::setCompareFunc(const Context *context, GLenum compareFunc)
+{
+ if (mState.mSamplerState.setCompareFunc(compareFunc))
+ {
+ signalDirtyState(DIRTY_BIT_COMPARE_FUNC);
+ }
+}
+
+GLenum Texture::getCompareFunc() const
+{
+ return mState.mSamplerState.getCompareFunc();
+}
+
+void Texture::setSRGBDecode(const Context *context, GLenum sRGBDecode)
+{
+ if (mState.mSamplerState.setSRGBDecode(sRGBDecode))
+ {
+ signalDirtyState(DIRTY_BIT_SRGB_DECODE);
+ }
+}
+
+GLenum Texture::getSRGBDecode() const
+{
+ return mState.mSamplerState.getSRGBDecode();
+}
+
+void Texture::setSRGBOverride(const Context *context, GLenum sRGBOverride)
+{
+ SrgbOverride oldOverride = mState.mSrgbOverride;
+ mState.mSrgbOverride = (sRGBOverride == GL_SRGB) ? SrgbOverride::SRGB : SrgbOverride::Default;
+ if (mState.mSrgbOverride != oldOverride)
+ {
+ signalDirtyState(DIRTY_BIT_SRGB_OVERRIDE);
+ }
+}
+
+GLenum Texture::getSRGBOverride() const
+{
+ return (mState.mSrgbOverride == SrgbOverride::SRGB) ? GL_SRGB : GL_NONE;
+}
+
+const SamplerState &Texture::getSamplerState() const
+{
+ return mState.mSamplerState;
+}
+
+angle::Result Texture::setBaseLevel(const Context *context, GLuint baseLevel)
+{
+ if (mState.setBaseLevel(baseLevel))
+ {
+ ANGLE_TRY(mTexture->setBaseLevel(context, mState.getEffectiveBaseLevel()));
+ signalDirtyState(DIRTY_BIT_BASE_LEVEL);
+ }
+
+ return angle::Result::Continue;
+}
+
+GLuint Texture::getBaseLevel() const
+{
+ return mState.mBaseLevel;
+}
+
+void Texture::setMaxLevel(const Context *context, GLuint maxLevel)
+{
+ if (mState.setMaxLevel(maxLevel))
+ {
+ signalDirtyState(DIRTY_BIT_MAX_LEVEL);
+ }
+}
+
+GLuint Texture::getMaxLevel() const
+{
+ return mState.mMaxLevel;
+}
+
+void Texture::setDepthStencilTextureMode(const Context *context, GLenum mode)
+{
+ if (mState.mDepthStencilTextureMode != mode)
+ {
+ mState.mDepthStencilTextureMode = mode;
+ signalDirtyState(DIRTY_BIT_DEPTH_STENCIL_TEXTURE_MODE);
+ }
+}
+
+GLenum Texture::getDepthStencilTextureMode() const
+{
+ return mState.mDepthStencilTextureMode;
+}
+
+bool Texture::getImmutableFormat() const
+{
+ return mState.mImmutableFormat;
+}
+
+GLuint Texture::getImmutableLevels() const
+{
+ return mState.mImmutableLevels;
+}
+
+void Texture::setUsage(const Context *context, GLenum usage)
+{
+ mState.mUsage = usage;
+ signalDirtyState(DIRTY_BIT_USAGE);
+}
+
+GLenum Texture::getUsage() const
+{
+ return mState.mUsage;
+}
+
+void Texture::setProtectedContent(Context *context, bool hasProtectedContent)
+{
+ mState.mHasProtectedContent = hasProtectedContent;
+}
+
+bool Texture::hasProtectedContent() const
+{
+ return mState.mHasProtectedContent;
+}
+
+const TextureState &Texture::getTextureState() const
+{
+ return mState;
+}
+
+const Extents &Texture::getExtents(TextureTarget target, size_t level) const
+{
+ ASSERT(TextureTargetToType(target) == mState.mType);
+ return mState.getImageDesc(target, level).size;
+}
+
+size_t Texture::getWidth(TextureTarget target, size_t level) const
+{
+ ASSERT(TextureTargetToType(target) == mState.mType);
+ return mState.getImageDesc(target, level).size.width;
+}
+
+size_t Texture::getHeight(TextureTarget target, size_t level) const
+{
+ ASSERT(TextureTargetToType(target) == mState.mType);
+ return mState.getImageDesc(target, level).size.height;
+}
+
+size_t Texture::getDepth(TextureTarget target, size_t level) const
+{
+ ASSERT(TextureTargetToType(target) == mState.mType);
+ return mState.getImageDesc(target, level).size.depth;
+}
+
+const Format &Texture::getFormat(TextureTarget target, size_t level) const
+{
+ ASSERT(TextureTargetToType(target) == mState.mType);
+ return mState.getImageDesc(target, level).format;
+}
+
+GLsizei Texture::getSamples(TextureTarget target, size_t level) const
+{
+ ASSERT(TextureTargetToType(target) == mState.mType);
+ return mState.getImageDesc(target, level).samples;
+}
+
+bool Texture::getFixedSampleLocations(TextureTarget target, size_t level) const
+{
+ ASSERT(TextureTargetToType(target) == mState.mType);
+ return mState.getImageDesc(target, level).fixedSampleLocations;
+}
+
+GLuint Texture::getMipmapMaxLevel() const
+{
+ return mState.getMipmapMaxLevel();
+}
+
+bool Texture::isMipmapComplete() const
+{
+ return mState.computeMipmapCompleteness();
+}
+
+egl::Surface *Texture::getBoundSurface() const
+{
+ return mBoundSurface;
+}
+
+egl::Stream *Texture::getBoundStream() const
+{
+ return mBoundStream;
+}
+
+GLint Texture::getMemorySize() const
+{
+ GLint implSize = mTexture->getMemorySize();
+ if (implSize > 0)
+ {
+ return implSize;
+ }
+
+ angle::CheckedNumeric<GLint> size = 0;
+ for (const ImageDesc &imageDesc : mState.mImageDescs)
+ {
+ size += imageDesc.getMemorySize();
+ }
+ return size.ValueOrDefault(std::numeric_limits<GLint>::max());
+}
+
+GLint Texture::getLevelMemorySize(TextureTarget target, GLint level) const
+{
+ GLint implSize = mTexture->getLevelMemorySize(target, level);
+ if (implSize > 0)
+ {
+ return implSize;
+ }
+
+ return mState.getImageDesc(target, level).getMemorySize();
+}
+
+void Texture::signalDirtyStorage(InitState initState)
+{
+ mState.mInitState = initState;
+ invalidateCompletenessCache();
+ mState.mCachedSamplerFormatValid = false;
+ onStateChange(angle::SubjectMessage::SubjectChanged);
+}
+
+void Texture::signalDirtyState(size_t dirtyBit)
+{
+ mDirtyBits.set(dirtyBit);
+ invalidateCompletenessCache();
+ mState.mCachedSamplerFormatValid = false;
+
+ if (dirtyBit == DIRTY_BIT_BASE_LEVEL || dirtyBit == DIRTY_BIT_MAX_LEVEL)
+ {
+ onStateChange(angle::SubjectMessage::SubjectChanged);
+ }
+ else
+ {
+ onStateChange(angle::SubjectMessage::DirtyBitsFlagged);
+ }
+}
+
+angle::Result Texture::setImage(Context *context,
+ const PixelUnpackState &unpackState,
+ Buffer *unpackBuffer,
+ TextureTarget target,
+ GLint level,
+ GLenum internalFormat,
+ const Extents &size,
+ GLenum format,
+ GLenum type,
+ const uint8_t *pixels)
+{
+ ASSERT(TextureTargetToType(target) == mState.mType);
+
+ // Release from previous calls to eglBindTexImage, to avoid calling the Impl after
+ ANGLE_TRY(releaseTexImageInternal(context));
+
+ egl::RefCountObjectReleaser<egl::Image> releaseImage;
+ ANGLE_TRY(orphanImages(context, &releaseImage));
+
+ ImageIndex index = ImageIndex::MakeFromTarget(target, level, size.depth);
+
+ ANGLE_TRY(mTexture->setImage(context, index, internalFormat, size, format, type, unpackState,
+ unpackBuffer, pixels));
+
+ InitState initState = DetermineInitState(context, unpackBuffer, pixels);
+ mState.setImageDesc(target, level, ImageDesc(size, Format(internalFormat, type), initState));
+
+ ANGLE_TRY(handleMipmapGenerationHint(context, level));
+
+ signalDirtyStorage(initState);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Texture::setSubImage(Context *context,
+ const PixelUnpackState &unpackState,
+ Buffer *unpackBuffer,
+ TextureTarget target,
+ GLint level,
+ const Box &area,
+ GLenum format,
+ GLenum type,
+ const uint8_t *pixels)
+{
+ ASSERT(TextureTargetToType(target) == mState.mType);
+
+ ImageIndex index = ImageIndex::MakeFromTarget(target, level, area.depth);
+ ANGLE_TRY(ensureSubImageInitialized(context, index, area));
+
+ ANGLE_TRY(mTexture->setSubImage(context, index, area, format, type, unpackState, unpackBuffer,
+ pixels));
+
+ ANGLE_TRY(handleMipmapGenerationHint(context, level));
+
+ onStateChange(angle::SubjectMessage::ContentsChanged);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Texture::setCompressedImage(Context *context,
+ const PixelUnpackState &unpackState,
+ TextureTarget target,
+ GLint level,
+ GLenum internalFormat,
+ const Extents &size,
+ size_t imageSize,
+ const uint8_t *pixels)
+{
+ ASSERT(TextureTargetToType(target) == mState.mType);
+
+ // Release from previous calls to eglBindTexImage, to avoid calling the Impl after
+ ANGLE_TRY(releaseTexImageInternal(context));
+
+ egl::RefCountObjectReleaser<egl::Image> releaseImage;
+ ANGLE_TRY(orphanImages(context, &releaseImage));
+
+ ImageIndex index = ImageIndex::MakeFromTarget(target, level, size.depth);
+
+ ANGLE_TRY(mTexture->setCompressedImage(context, index, internalFormat, size, unpackState,
+ imageSize, pixels));
+
+ Buffer *unpackBuffer = context->getState().getTargetBuffer(BufferBinding::PixelUnpack);
+
+ InitState initState = DetermineInitState(context, unpackBuffer, pixels);
+ mState.setImageDesc(target, level, ImageDesc(size, Format(internalFormat), initState));
+ signalDirtyStorage(initState);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Texture::setCompressedSubImage(const Context *context,
+ const PixelUnpackState &unpackState,
+ TextureTarget target,
+ GLint level,
+ const Box &area,
+ GLenum format,
+ size_t imageSize,
+ const uint8_t *pixels)
+{
+ ASSERT(TextureTargetToType(target) == mState.mType);
+
+ ImageIndex index = ImageIndex::MakeFromTarget(target, level, area.depth);
+ ANGLE_TRY(ensureSubImageInitialized(context, index, area));
+
+ ANGLE_TRY(mTexture->setCompressedSubImage(context, index, area, format, unpackState, imageSize,
+ pixels));
+
+ onStateChange(angle::SubjectMessage::ContentsChanged);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Texture::copyImage(Context *context,
+ TextureTarget target,
+ GLint level,
+ const Rectangle &sourceArea,
+ GLenum internalFormat,
+ Framebuffer *source)
+{
+ ASSERT(TextureTargetToType(target) == mState.mType);
+
+ // Release from previous calls to eglBindTexImage, to avoid calling the Impl after
+ ANGLE_TRY(releaseTexImageInternal(context));
+
+ egl::RefCountObjectReleaser<egl::Image> releaseImage;
+ ANGLE_TRY(orphanImages(context, &releaseImage));
+
+ ImageIndex index = ImageIndex::MakeFromTarget(target, level, 1);
+
+ const InternalFormat &internalFormatInfo =
+ GetInternalFormatInfo(internalFormat, GL_UNSIGNED_BYTE);
+
+ // Most if not all renderers clip these copies to the size of the source framebuffer, leaving
+ // other pixels untouched. For safety in robust resource initialization, assume that that
+ // clipping is going to occur when computing the region for which to ensure initialization. If
+ // the copy lies entirely off the source framebuffer, initialize as though a zero-size box is
+ // going to be set during the copy operation.
+ Box destBox;
+ bool forceCopySubImage = false;
+ if (context->isRobustResourceInitEnabled())
+ {
+ const FramebufferAttachment *sourceReadAttachment = source->getReadColorAttachment();
+ Extents fbSize = sourceReadAttachment->getSize();
+ // Force using copySubImage when the source area is out of bounds AND
+ // we're not copying to and from the same texture
+ forceCopySubImage = ((sourceArea.x < 0) || (sourceArea.y < 0) ||
+ ((sourceArea.x + sourceArea.width) > fbSize.width) ||
+ ((sourceArea.y + sourceArea.height) > fbSize.height)) &&
+ (sourceReadAttachment->getResource() != this);
+ Rectangle clippedArea;
+ if (ClipRectangle(sourceArea, Rectangle(0, 0, fbSize.width, fbSize.height), &clippedArea))
+ {
+ const Offset clippedOffset(clippedArea.x - sourceArea.x, clippedArea.y - sourceArea.y,
+ 0);
+ destBox = Box(clippedOffset.x, clippedOffset.y, clippedOffset.z, clippedArea.width,
+ clippedArea.height, 1);
+ }
+ }
+
+ InitState initState = DetermineInitState(context, nullptr, nullptr);
+
+ // If we need to initialize the destination texture we split the call into a create call,
+ // an initializeContents call, and then a copySubImage call. This ensures the destination
+ // texture exists before we try to clear it.
+ Extents size(sourceArea.width, sourceArea.height, 1);
+ if (forceCopySubImage || doesSubImageNeedInit(context, index, destBox))
+ {
+ ANGLE_TRY(mTexture->setImage(context, index, internalFormat, size,
+ internalFormatInfo.format, internalFormatInfo.type,
+ PixelUnpackState(), nullptr, nullptr));
+ mState.setImageDesc(target, level, ImageDesc(size, Format(internalFormatInfo), initState));
+ ANGLE_TRY(ensureSubImageInitialized(context, index, destBox));
+ ANGLE_TRY(mTexture->copySubImage(context, index, Offset(), sourceArea, source));
+ }
+ else
+ {
+ ANGLE_TRY(mTexture->copyImage(context, index, sourceArea, internalFormat, source));
+ }
+
+ mState.setImageDesc(target, level,
+ ImageDesc(size, Format(internalFormatInfo), InitState::Initialized));
+
+ ANGLE_TRY(handleMipmapGenerationHint(context, level));
+
+ // Because this could affect the texture storage we might need to init other layers/levels.
+ signalDirtyStorage(initState);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Texture::copySubImage(Context *context,
+ const ImageIndex &index,
+ const Offset &destOffset,
+ const Rectangle &sourceArea,
+ Framebuffer *source)
+{
+ ASSERT(TextureTargetToType(index.getTarget()) == mState.mType);
+
+ // Most if not all renderers clip these copies to the size of the source framebuffer, leaving
+ // other pixels untouched. For safety in robust resource initialization, assume that that
+ // clipping is going to occur when computing the region for which to ensure initialization. If
+ // the copy lies entirely off the source framebuffer, initialize as though a zero-size box is
+ // going to be set during the copy operation. Note that this assumes that
+ // ensureSubImageInitialized ensures initialization of the entire destination texture, and not
+ // just a sub-region.
+ Box destBox;
+ if (context->isRobustResourceInitEnabled())
+ {
+ Extents fbSize = source->getReadColorAttachment()->getSize();
+ Rectangle clippedArea;
+ if (ClipRectangle(sourceArea, Rectangle(0, 0, fbSize.width, fbSize.height), &clippedArea))
+ {
+ const Offset clippedOffset(destOffset.x + clippedArea.x - sourceArea.x,
+ destOffset.y + clippedArea.y - sourceArea.y, 0);
+ destBox = Box(clippedOffset.x, clippedOffset.y, clippedOffset.z, clippedArea.width,
+ clippedArea.height, 1);
+ }
+ }
+
+ ANGLE_TRY(ensureSubImageInitialized(context, index, destBox));
+
+ ANGLE_TRY(mTexture->copySubImage(context, index, destOffset, sourceArea, source));
+ ANGLE_TRY(handleMipmapGenerationHint(context, index.getLevelIndex()));
+
+ onStateChange(angle::SubjectMessage::ContentsChanged);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Texture::copyRenderbufferSubData(Context *context,
+ const gl::Renderbuffer *srcBuffer,
+ GLint srcLevel,
+ GLint srcX,
+ GLint srcY,
+ GLint srcZ,
+ GLint dstLevel,
+ GLint dstX,
+ GLint dstY,
+ GLint dstZ,
+ GLsizei srcWidth,
+ GLsizei srcHeight,
+ GLsizei srcDepth)
+{
+ ANGLE_TRY(mTexture->copyRenderbufferSubData(context, srcBuffer, srcLevel, srcX, srcY, srcZ,
+ dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight,
+ srcDepth));
+
+ signalDirtyStorage(InitState::Initialized);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Texture::copyTextureSubData(Context *context,
+ const gl::Texture *srcTexture,
+ GLint srcLevel,
+ GLint srcX,
+ GLint srcY,
+ GLint srcZ,
+ GLint dstLevel,
+ GLint dstX,
+ GLint dstY,
+ GLint dstZ,
+ GLsizei srcWidth,
+ GLsizei srcHeight,
+ GLsizei srcDepth)
+{
+ ANGLE_TRY(mTexture->copyTextureSubData(context, srcTexture, srcLevel, srcX, srcY, srcZ,
+ dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight,
+ srcDepth));
+
+ signalDirtyStorage(InitState::Initialized);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Texture::copyTexture(Context *context,
+ TextureTarget target,
+ GLint level,
+ GLenum internalFormat,
+ GLenum type,
+ GLint sourceLevel,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha,
+ Texture *source)
+{
+ ASSERT(TextureTargetToType(target) == mState.mType);
+ ASSERT(source->getType() != TextureType::CubeMap);
+
+ // Release from previous calls to eglBindTexImage, to avoid calling the Impl after
+ ANGLE_TRY(releaseTexImageInternal(context));
+
+ egl::RefCountObjectReleaser<egl::Image> releaseImage;
+ ANGLE_TRY(orphanImages(context, &releaseImage));
+
+ // Initialize source texture.
+ // Note: we don't have a way to notify which portions of the image changed currently.
+ ANGLE_TRY(source->ensureInitialized(context));
+
+ ImageIndex index = ImageIndex::MakeFromTarget(target, level, ImageIndex::kEntireLevel);
+
+ ANGLE_TRY(mTexture->copyTexture(context, index, internalFormat, type, sourceLevel, unpackFlipY,
+ unpackPremultiplyAlpha, unpackUnmultiplyAlpha, source));
+
+ const auto &sourceDesc =
+ source->mState.getImageDesc(NonCubeTextureTypeToTarget(source->getType()), sourceLevel);
+ const InternalFormat &internalFormatInfo = GetInternalFormatInfo(internalFormat, type);
+ mState.setImageDesc(
+ target, level,
+ ImageDesc(sourceDesc.size, Format(internalFormatInfo), InitState::Initialized));
+
+ signalDirtyStorage(InitState::Initialized);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Texture::copySubTexture(const Context *context,
+ TextureTarget target,
+ GLint level,
+ const Offset &destOffset,
+ GLint sourceLevel,
+ const Box &sourceBox,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha,
+ Texture *source)
+{
+ ASSERT(TextureTargetToType(target) == mState.mType);
+
+ // Ensure source is initialized.
+ ANGLE_TRY(source->ensureInitialized(context));
+
+ Box destBox(destOffset.x, destOffset.y, destOffset.z, sourceBox.width, sourceBox.height,
+ sourceBox.depth);
+ ImageIndex index = ImageIndex::MakeFromTarget(target, level, sourceBox.depth);
+ ANGLE_TRY(ensureSubImageInitialized(context, index, destBox));
+
+ ANGLE_TRY(mTexture->copySubTexture(context, index, destOffset, sourceLevel, sourceBox,
+ unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha,
+ source));
+
+ onStateChange(angle::SubjectMessage::ContentsChanged);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Texture::copyCompressedTexture(Context *context, const Texture *source)
+{
+ // Release from previous calls to eglBindTexImage, to avoid calling the Impl after
+ ANGLE_TRY(releaseTexImageInternal(context));
+
+ egl::RefCountObjectReleaser<egl::Image> releaseImage;
+ ANGLE_TRY(orphanImages(context, &releaseImage));
+
+ ANGLE_TRY(mTexture->copyCompressedTexture(context, source));
+
+ ASSERT(source->getType() != TextureType::CubeMap && getType() != TextureType::CubeMap);
+ const auto &sourceDesc =
+ source->mState.getImageDesc(NonCubeTextureTypeToTarget(source->getType()), 0);
+ mState.setImageDesc(NonCubeTextureTypeToTarget(getType()), 0, sourceDesc);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Texture::setStorage(Context *context,
+ TextureType type,
+ GLsizei levels,
+ GLenum internalFormat,
+ const Extents &size)
+{
+ ASSERT(type == mState.mType);
+
+ // Release from previous calls to eglBindTexImage, to avoid calling the Impl after
+ ANGLE_TRY(releaseTexImageInternal(context));
+
+ egl::RefCountObjectReleaser<egl::Image> releaseImage;
+ ANGLE_TRY(orphanImages(context, &releaseImage));
+
+ mState.mImmutableFormat = true;
+ mState.mImmutableLevels = static_cast<GLuint>(levels);
+ mState.clearImageDescs();
+ InitState initState = DetermineInitState(context, nullptr, nullptr);
+ mState.setImageDescChain(0, static_cast<GLuint>(levels - 1), size, Format(internalFormat),
+ initState);
+
+ ANGLE_TRY(mTexture->setStorage(context, type, levels, internalFormat, size));
+
+ // Changing the texture to immutable can trigger a change in the base and max levels:
+ // GLES 3.0.4 section 3.8.10 pg 158:
+ // "For immutable-format textures, levelbase is clamped to the range[0;levels],levelmax is then
+ // clamped to the range[levelbase;levels].
+ mDirtyBits.set(DIRTY_BIT_BASE_LEVEL);
+ mDirtyBits.set(DIRTY_BIT_MAX_LEVEL);
+
+ signalDirtyStorage(initState);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Texture::setImageExternal(Context *context,
+ TextureTarget target,
+ GLint level,
+ GLenum internalFormat,
+ const Extents &size,
+ GLenum format,
+ GLenum type)
+{
+ ASSERT(TextureTargetToType(target) == mState.mType);
+
+ // Release from previous calls to eglBindTexImage, to avoid calling the Impl after
+ ANGLE_TRY(releaseTexImageInternal(context));
+
+ egl::RefCountObjectReleaser<egl::Image> releaseImage;
+ ANGLE_TRY(orphanImages(context, &releaseImage));
+
+ ImageIndex index = ImageIndex::MakeFromTarget(target, level, size.depth);
+
+ ANGLE_TRY(mTexture->setImageExternal(context, index, internalFormat, size, format, type));
+
+ InitState initState = InitState::Initialized;
+ mState.setImageDesc(target, level, ImageDesc(size, Format(internalFormat, type), initState));
+
+ ANGLE_TRY(handleMipmapGenerationHint(context, level));
+
+ signalDirtyStorage(initState);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Texture::setStorageMultisample(Context *context,
+ TextureType type,
+ GLsizei samplesIn,
+ GLint internalFormat,
+ const Extents &size,
+ bool fixedSampleLocations)
+{
+ ASSERT(type == mState.mType);
+
+ // Release from previous calls to eglBindTexImage, to avoid calling the Impl after
+ ANGLE_TRY(releaseTexImageInternal(context));
+
+ egl::RefCountObjectReleaser<egl::Image> releaseImage;
+ ANGLE_TRY(orphanImages(context, &releaseImage));
+
+ // Potentially adjust "samples" to a supported value
+ const TextureCaps &formatCaps = context->getTextureCaps().get(internalFormat);
+ GLsizei samples = formatCaps.getNearestSamples(samplesIn);
+
+ mState.mImmutableFormat = true;
+ mState.mImmutableLevels = static_cast<GLuint>(1);
+ mState.clearImageDescs();
+ InitState initState = DetermineInitState(context, nullptr, nullptr);
+ mState.setImageDescChainMultisample(size, Format(internalFormat), samples, fixedSampleLocations,
+ initState);
+
+ ANGLE_TRY(mTexture->setStorageMultisample(context, type, samples, internalFormat, size,
+ fixedSampleLocations));
+ signalDirtyStorage(initState);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Texture::setStorageExternalMemory(Context *context,
+ TextureType type,
+ GLsizei levels,
+ GLenum internalFormat,
+ const Extents &size,
+ MemoryObject *memoryObject,
+ GLuint64 offset,
+ GLbitfield createFlags,
+ GLbitfield usageFlags,
+ const void *imageCreateInfoPNext)
+{
+ ASSERT(type == mState.mType);
+
+ // Release from previous calls to eglBindTexImage, to avoid calling the Impl after
+ ANGLE_TRY(releaseTexImageInternal(context));
+
+ egl::RefCountObjectReleaser<egl::Image> releaseImage;
+ ANGLE_TRY(orphanImages(context, &releaseImage));
+
+ ANGLE_TRY(mTexture->setStorageExternalMemory(context, type, levels, internalFormat, size,
+ memoryObject, offset, createFlags, usageFlags,
+ imageCreateInfoPNext));
+
+ mState.mImmutableFormat = true;
+ mState.mImmutableLevels = static_cast<GLuint>(levels);
+ mState.clearImageDescs();
+ mState.setImageDescChain(0, static_cast<GLuint>(levels - 1), size, Format(internalFormat),
+ InitState::Initialized);
+
+ // Changing the texture to immutable can trigger a change in the base and max levels:
+ // GLES 3.0.4 section 3.8.10 pg 158:
+ // "For immutable-format textures, levelbase is clamped to the range[0;levels],levelmax is then
+ // clamped to the range[levelbase;levels].
+ mDirtyBits.set(DIRTY_BIT_BASE_LEVEL);
+ mDirtyBits.set(DIRTY_BIT_MAX_LEVEL);
+
+ signalDirtyStorage(InitState::Initialized);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Texture::generateMipmap(Context *context)
+{
+ // Release from previous calls to eglBindTexImage, to avoid calling the Impl after
+ ANGLE_TRY(releaseTexImageInternal(context));
+
+ // EGL_KHR_gl_image states that images are only orphaned when generating mipmaps if the texture
+ // is not mip complete.
+ egl::RefCountObjectReleaser<egl::Image> releaseImage;
+ if (!isMipmapComplete())
+ {
+ ANGLE_TRY(orphanImages(context, &releaseImage));
+ }
+
+ const GLuint baseLevel = mState.getEffectiveBaseLevel();
+ const GLuint maxLevel = mState.getMipmapMaxLevel();
+
+ if (maxLevel <= baseLevel)
+ {
+ return angle::Result::Continue;
+ }
+
+ // If any dimension is zero, this is a no-op:
+ //
+ // > Otherwise, if level_base is not defined, or if any dimension is zero, all mipmap levels are
+ // > left unchanged. This is not an error.
+ const ImageDesc &baseImageInfo = mState.getImageDesc(mState.getBaseImageTarget(), baseLevel);
+ if (baseImageInfo.size.empty())
+ {
+ return angle::Result::Continue;
+ }
+
+ // Clear the base image(s) immediately if needed
+ if (context->isRobustResourceInitEnabled())
+ {
+ ImageIndexIterator it =
+ ImageIndexIterator::MakeGeneric(mState.mType, baseLevel, baseLevel + 1,
+ ImageIndex::kEntireLevel, ImageIndex::kEntireLevel);
+ while (it.hasNext())
+ {
+ const ImageIndex index = it.next();
+ const ImageDesc &desc = mState.getImageDesc(index.getTarget(), index.getLevelIndex());
+
+ if (desc.initState == InitState::MayNeedInit)
+ {
+ ANGLE_TRY(initializeContents(context, GL_NONE, index));
+ }
+ }
+ }
+
+ ANGLE_TRY(syncState(context, Command::GenerateMipmap));
+ ANGLE_TRY(mTexture->generateMipmap(context));
+
+ // Propagate the format and size of the base mip to the smaller ones. Cube maps are guaranteed
+ // to have faces of the same size and format so any faces can be picked.
+ mState.setImageDescChain(baseLevel, maxLevel, baseImageInfo.size, baseImageInfo.format,
+ InitState::Initialized);
+
+ signalDirtyStorage(InitState::Initialized);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Texture::bindTexImageFromSurface(Context *context, egl::Surface *surface)
+{
+ ASSERT(surface);
+
+ if (mBoundSurface)
+ {
+ ANGLE_TRY(releaseTexImageFromSurface(context));
+ }
+
+ mBoundSurface = surface;
+
+ // Set the image info to the size and format of the surface
+ ASSERT(mState.mType == TextureType::_2D || mState.mType == TextureType::Rectangle);
+ Extents size(surface->getWidth(), surface->getHeight(), 1);
+ ImageDesc desc(size, surface->getBindTexImageFormat(), InitState::Initialized);
+ mState.setImageDesc(NonCubeTextureTypeToTarget(mState.mType), 0, desc);
+ mState.mHasProtectedContent = surface->hasProtectedContent();
+
+ ANGLE_TRY(mTexture->bindTexImage(context, surface));
+
+ signalDirtyStorage(InitState::Initialized);
+ return angle::Result::Continue;
+}
+
+angle::Result Texture::releaseTexImageFromSurface(const Context *context)
+{
+ ASSERT(mBoundSurface);
+ mBoundSurface = nullptr;
+ ANGLE_TRY(mTexture->releaseTexImage(context));
+
+ // Erase the image info for level 0
+ ASSERT(mState.mType == TextureType::_2D || mState.mType == TextureType::Rectangle);
+ mState.clearImageDesc(NonCubeTextureTypeToTarget(mState.mType), 0);
+ mState.mHasProtectedContent = false;
+ signalDirtyStorage(InitState::Initialized);
+ return angle::Result::Continue;
+}
+
+void Texture::bindStream(egl::Stream *stream)
+{
+ ASSERT(stream);
+
+ // It should not be possible to bind a texture already bound to another stream
+ ASSERT(mBoundStream == nullptr);
+
+ mBoundStream = stream;
+
+ ASSERT(mState.mType == TextureType::External);
+}
+
+void Texture::releaseStream()
+{
+ ASSERT(mBoundStream);
+ mBoundStream = nullptr;
+}
+
+angle::Result Texture::acquireImageFromStream(const Context *context,
+ const egl::Stream::GLTextureDescription &desc)
+{
+ ASSERT(mBoundStream != nullptr);
+ ANGLE_TRY(mTexture->setImageExternal(context, mState.mType, mBoundStream, desc));
+
+ Extents size(desc.width, desc.height, 1);
+ mState.setImageDesc(NonCubeTextureTypeToTarget(mState.mType), 0,
+ ImageDesc(size, Format(desc.internalFormat), InitState::Initialized));
+ signalDirtyStorage(InitState::Initialized);
+ return angle::Result::Continue;
+}
+
+angle::Result Texture::releaseImageFromStream(const Context *context)
+{
+ ASSERT(mBoundStream != nullptr);
+ ANGLE_TRY(mTexture->setImageExternal(context, mState.mType, nullptr,
+ egl::Stream::GLTextureDescription()));
+
+ // Set to incomplete
+ mState.clearImageDesc(NonCubeTextureTypeToTarget(mState.mType), 0);
+ signalDirtyStorage(InitState::Initialized);
+ return angle::Result::Continue;
+}
+
+angle::Result Texture::releaseTexImageInternal(Context *context)
+{
+ if (mBoundSurface)
+ {
+ // Notify the surface
+ egl::Error eglErr = mBoundSurface->releaseTexImageFromTexture(context);
+ // TODO(jmadill): Remove this once refactor is complete. http://anglebug.com/3041
+ if (eglErr.isError())
+ {
+ context->handleError(GL_INVALID_OPERATION, "Error releasing tex image from texture",
+ __FILE__, ANGLE_FUNCTION, __LINE__);
+ }
+
+ // Then, call the same method as from the surface
+ ANGLE_TRY(releaseTexImageFromSurface(context));
+ }
+ return angle::Result::Continue;
+}
+
+angle::Result Texture::setEGLImageTargetImpl(Context *context,
+ TextureType type,
+ GLuint levels,
+ egl::Image *imageTarget)
+{
+ ASSERT(type == mState.mType);
+
+ // Release from previous calls to eglBindTexImage, to avoid calling the Impl after
+ ANGLE_TRY(releaseTexImageInternal(context));
+
+ egl::RefCountObjectReleaser<egl::Image> releaseImage;
+ ANGLE_TRY(orphanImages(context, &releaseImage));
+
+ setTargetImage(context, imageTarget);
+
+ auto initState = imageTarget->sourceInitState();
+
+ mState.clearImageDescs();
+ mState.setImageDescChain(0, levels - 1, imageTarget->getExtents(), imageTarget->getFormat(),
+ initState);
+ mState.mHasProtectedContent = imageTarget->hasProtectedContent();
+
+ ANGLE_TRY(mTexture->setEGLImageTarget(context, type, imageTarget));
+
+ signalDirtyStorage(initState);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Texture::setEGLImageTarget(Context *context,
+ TextureType type,
+ egl::Image *imageTarget)
+{
+ ASSERT(type == TextureType::_2D || type == TextureType::External ||
+ type == TextureType::_2DArray);
+
+ return setEGLImageTargetImpl(context, type, 1u, imageTarget);
+}
+
+angle::Result Texture::setStorageEGLImageTarget(Context *context,
+ TextureType type,
+ egl::Image *imageTarget,
+ const GLint *attrib_list)
+{
+ ASSERT(type == TextureType::External || type == TextureType::_3D || type == TextureType::_2D ||
+ type == TextureType::_2DArray || type == TextureType::CubeMap ||
+ type == TextureType::CubeMapArray);
+
+ ANGLE_TRY(setEGLImageTargetImpl(context, type, imageTarget->getLevelCount(), imageTarget));
+
+ mState.mImmutableLevels = imageTarget->getLevelCount();
+ mState.mImmutableFormat = true;
+
+ // Changing the texture to immutable can trigger a change in the base and max levels:
+ // GLES 3.0.4 section 3.8.10 pg 158:
+ // "For immutable-format textures, levelbase is clamped to the range[0;levels],levelmax is then
+ // clamped to the range[levelbase;levels].
+ mDirtyBits.set(DIRTY_BIT_BASE_LEVEL);
+ mDirtyBits.set(DIRTY_BIT_MAX_LEVEL);
+
+ return angle::Result::Continue;
+}
+
+Extents Texture::getAttachmentSize(const ImageIndex &imageIndex) const
+{
+ // As an ImageIndex that represents an entire level of a cube map corresponds to 6 ImageDescs,
+ // we only allow querying ImageDesc on a complete cube map, and this ImageDesc is exactly the
+ // one that belongs to the first face of the cube map.
+ if (imageIndex.isEntireLevelCubeMap())
+ {
+ // A cube map texture is cube complete if the following conditions all hold true:
+ // - The levelbase arrays of each of the six texture images making up the cube map have
+ // identical, positive, and square dimensions.
+ if (!mState.isCubeComplete())
+ {
+ return Extents();
+ }
+ }
+
+ return mState.getImageDesc(imageIndex).size;
+}
+
+Format Texture::getAttachmentFormat(GLenum /*binding*/, const ImageIndex &imageIndex) const
+{
+ // As an ImageIndex that represents an entire level of a cube map corresponds to 6 ImageDescs,
+ // we only allow querying ImageDesc on a complete cube map, and this ImageDesc is exactly the
+ // one that belongs to the first face of the cube map.
+ if (imageIndex.isEntireLevelCubeMap())
+ {
+ // A cube map texture is cube complete if the following conditions all hold true:
+ // - The levelbase arrays were each specified with the same effective internal format.
+ if (!mState.isCubeComplete())
+ {
+ return Format::Invalid();
+ }
+ }
+ return mState.getImageDesc(imageIndex).format;
+}
+
+GLsizei Texture::getAttachmentSamples(const ImageIndex &imageIndex) const
+{
+ // We do not allow querying TextureTarget by an ImageIndex that represents an entire level of a
+ // cube map (See comments in function TextureTypeToTarget() in ImageIndex.cpp).
+ if (imageIndex.isEntireLevelCubeMap())
+ {
+ return 0;
+ }
+
+ return getSamples(imageIndex.getTarget(), imageIndex.getLevelIndex());
+}
+
+bool Texture::isRenderable(const Context *context,
+ GLenum binding,
+ const ImageIndex &imageIndex) const
+{
+ if (isEGLImageTarget())
+ {
+ return ImageSibling::isRenderable(context, binding, imageIndex);
+ }
+
+ // Surfaces bound to textures are always renderable. This avoids issues with surfaces with ES3+
+ // formats not being renderable when bound to textures in ES2 contexts.
+ if (mBoundSurface)
+ {
+ return true;
+ }
+
+ return getAttachmentFormat(binding, imageIndex)
+ .info->textureAttachmentSupport(context->getClientVersion(), context->getExtensions());
+}
+
+bool Texture::getAttachmentFixedSampleLocations(const ImageIndex &imageIndex) const
+{
+ // We do not allow querying TextureTarget by an ImageIndex that represents an entire level of a
+ // cube map (See comments in function TextureTypeToTarget() in ImageIndex.cpp).
+ if (imageIndex.isEntireLevelCubeMap())
+ {
+ return true;
+ }
+
+ // ES3.1 (section 9.4) requires that the value of TEXTURE_FIXED_SAMPLE_LOCATIONS should be
+ // the same for all attached textures.
+ return getFixedSampleLocations(imageIndex.getTarget(), imageIndex.getLevelIndex());
+}
+
+void Texture::setBorderColor(const Context *context, const ColorGeneric &color)
+{
+ mState.mSamplerState.setBorderColor(color);
+ signalDirtyState(DIRTY_BIT_BORDER_COLOR);
+}
+
+const ColorGeneric &Texture::getBorderColor() const
+{
+ return mState.mSamplerState.getBorderColor();
+}
+
+GLint Texture::getRequiredTextureImageUnits(const Context *context) const
+{
+ // Only external texture types can return non-1.
+ if (mState.mType != TextureType::External)
+ {
+ return 1;
+ }
+
+ return mTexture->getRequiredExternalTextureImageUnits(context);
+}
+
+void Texture::setCrop(const Rectangle &rect)
+{
+ mState.setCrop(rect);
+}
+
+const Rectangle &Texture::getCrop() const
+{
+ return mState.getCrop();
+}
+
+void Texture::setGenerateMipmapHint(GLenum hint)
+{
+ mState.setGenerateMipmapHint(hint);
+}
+
+GLenum Texture::getGenerateMipmapHint() const
+{
+ return mState.getGenerateMipmapHint();
+}
+
+angle::Result Texture::setBuffer(const gl::Context *context,
+ gl::Buffer *buffer,
+ GLenum internalFormat)
+{
+ // Use 0 to indicate that the size is taken from whatever size the buffer has when the texture
+ // buffer is used.
+ return setBufferRange(context, buffer, internalFormat, 0, 0);
+}
+
+angle::Result Texture::setBufferRange(const gl::Context *context,
+ gl::Buffer *buffer,
+ GLenum internalFormat,
+ GLintptr offset,
+ GLsizeiptr size)
+{
+ mState.mImmutableFormat = true;
+ mState.mBuffer.set(context, buffer, offset, size);
+ ANGLE_TRY(mTexture->setBuffer(context, internalFormat));
+
+ mState.clearImageDescs();
+ if (buffer == nullptr)
+ {
+ mBufferObserver.reset();
+ InitState initState = DetermineInitState(context, nullptr, nullptr);
+ signalDirtyStorage(initState);
+ return angle::Result::Continue;
+ }
+
+ size = GetBoundBufferAvailableSize(mState.mBuffer);
+
+ mState.mImmutableLevels = static_cast<GLuint>(1);
+ InternalFormat internalFormatInfo = GetSizedInternalFormatInfo(internalFormat);
+ Format format(internalFormat);
+ Extents extents(static_cast<GLuint>(size / internalFormatInfo.pixelBytes), 1, 1);
+ InitState initState = buffer->initState();
+ mState.setImageDesc(TextureTarget::Buffer, 0, ImageDesc(extents, format, initState));
+
+ signalDirtyStorage(initState);
+
+ // Observe modifications to the buffer, so that extents can be updated.
+ mBufferObserver.bind(buffer);
+
+ return angle::Result::Continue;
+}
+
+const OffsetBindingPointer<Buffer> &Texture::getBuffer() const
+{
+ return mState.mBuffer;
+}
+
+void Texture::onAttach(const Context *context, rx::Serial framebufferSerial)
+{
+ addRef();
+
+ // Duplicates allowed for multiple attachment points. See the comment in the header.
+ mBoundFramebufferSerials.push_back(framebufferSerial);
+
+ if (!mState.mHasBeenBoundAsAttachment)
+ {
+ mDirtyBits.set(DIRTY_BIT_BOUND_AS_ATTACHMENT);
+ mState.mHasBeenBoundAsAttachment = true;
+ }
+}
+
+void Texture::onDetach(const Context *context, rx::Serial framebufferSerial)
+{
+ // Erase first instance. If there are multiple bindings, leave the others.
+ ASSERT(isBoundToFramebuffer(framebufferSerial));
+ mBoundFramebufferSerials.remove_and_permute(framebufferSerial);
+
+ release(context);
+}
+
+GLuint Texture::getId() const
+{
+ return id().value;
+}
+
+GLuint Texture::getNativeID() const
+{
+ return mTexture->getNativeID();
+}
+
+angle::Result Texture::syncState(const Context *context, Command source)
+{
+ ASSERT(hasAnyDirtyBit() || source == Command::GenerateMipmap);
+ ANGLE_TRY(mTexture->syncState(context, mDirtyBits, source));
+ mDirtyBits.reset();
+ mState.mInitState = InitState::Initialized;
+ return angle::Result::Continue;
+}
+
+rx::FramebufferAttachmentObjectImpl *Texture::getAttachmentImpl() const
+{
+ return mTexture;
+}
+
+bool Texture::isSamplerComplete(const Context *context, const Sampler *optionalSampler)
+{
+ const auto &samplerState =
+ optionalSampler ? optionalSampler->getSamplerState() : mState.mSamplerState;
+ const auto &contextState = context->getState();
+
+ if (contextState.getContextID() != mCompletenessCache.context ||
+ !mCompletenessCache.samplerState.sameCompleteness(samplerState))
+ {
+ mCompletenessCache.context = context->getState().getContextID();
+ mCompletenessCache.samplerState = samplerState;
+ mCompletenessCache.samplerComplete =
+ mState.computeSamplerCompleteness(samplerState, contextState);
+ }
+
+ return mCompletenessCache.samplerComplete;
+}
+
+// CopyImageSubData requires that we ignore format-based completeness rules
+bool Texture::isSamplerCompleteForCopyImage(const Context *context,
+ const Sampler *optionalSampler) const
+{
+ const gl::SamplerState &samplerState =
+ optionalSampler ? optionalSampler->getSamplerState() : mState.mSamplerState;
+ const gl::State &contextState = context->getState();
+ return mState.computeSamplerCompletenessForCopyImage(samplerState, contextState);
+}
+
+Texture::SamplerCompletenessCache::SamplerCompletenessCache()
+ : context({0}), samplerState(), samplerComplete(false)
+{}
+
+void Texture::invalidateCompletenessCache() const
+{
+ mCompletenessCache.context = {0};
+}
+
+angle::Result Texture::ensureInitialized(const Context *context)
+{
+ if (!context->isRobustResourceInitEnabled() || mState.mInitState == InitState::Initialized)
+ {
+ return angle::Result::Continue;
+ }
+
+ bool anyDirty = false;
+
+ ImageIndexIterator it =
+ ImageIndexIterator::MakeGeneric(mState.mType, 0, IMPLEMENTATION_MAX_TEXTURE_LEVELS + 1,
+ ImageIndex::kEntireLevel, ImageIndex::kEntireLevel);
+ while (it.hasNext())
+ {
+ const ImageIndex index = it.next();
+ ImageDesc &desc =
+ mState.mImageDescs[GetImageDescIndex(index.getTarget(), index.getLevelIndex())];
+ if (desc.initState == InitState::MayNeedInit && !desc.size.empty())
+ {
+ ASSERT(mState.mInitState == InitState::MayNeedInit);
+ ANGLE_TRY(initializeContents(context, GL_NONE, index));
+ desc.initState = InitState::Initialized;
+ anyDirty = true;
+ }
+ }
+ if (anyDirty)
+ {
+ signalDirtyStorage(InitState::Initialized);
+ }
+ mState.mInitState = InitState::Initialized;
+
+ return angle::Result::Continue;
+}
+
+InitState Texture::initState(GLenum /*binding*/, const ImageIndex &imageIndex) const
+{
+ // As an ImageIndex that represents an entire level of a cube map corresponds to 6 ImageDescs,
+ // we need to check all the related ImageDescs.
+ if (imageIndex.isEntireLevelCubeMap())
+ {
+ const GLint levelIndex = imageIndex.getLevelIndex();
+ for (TextureTarget cubeFaceTarget : AllCubeFaceTextureTargets())
+ {
+ if (mState.getImageDesc(cubeFaceTarget, levelIndex).initState == InitState::MayNeedInit)
+ {
+ return InitState::MayNeedInit;
+ }
+ }
+ return InitState::Initialized;
+ }
+
+ return mState.getImageDesc(imageIndex).initState;
+}
+
+void Texture::setInitState(GLenum binding, const ImageIndex &imageIndex, InitState initState)
+{
+ // As an ImageIndex that represents an entire level of a cube map corresponds to 6 ImageDescs,
+ // we need to update all the related ImageDescs.
+ if (imageIndex.isEntireLevelCubeMap())
+ {
+ const GLint levelIndex = imageIndex.getLevelIndex();
+ for (TextureTarget cubeFaceTarget : AllCubeFaceTextureTargets())
+ {
+ setInitState(binding, ImageIndex::MakeCubeMapFace(cubeFaceTarget, levelIndex),
+ initState);
+ }
+ }
+ else
+ {
+ ImageDesc newDesc = mState.getImageDesc(imageIndex);
+ newDesc.initState = initState;
+ mState.setImageDesc(imageIndex.getTarget(), imageIndex.getLevelIndex(), newDesc);
+ }
+}
+
+void Texture::setInitState(InitState initState)
+{
+ for (ImageDesc &imageDesc : mState.mImageDescs)
+ {
+ // Only modify defined images, undefined images will remain in the initialized state
+ if (!imageDesc.size.empty())
+ {
+ imageDesc.initState = initState;
+ }
+ }
+ mState.mInitState = initState;
+}
+
+bool Texture::doesSubImageNeedInit(const Context *context,
+ const ImageIndex &imageIndex,
+ const Box &area) const
+{
+ if (!context->isRobustResourceInitEnabled() || mState.mInitState == InitState::Initialized)
+ {
+ return false;
+ }
+
+ // Pre-initialize the texture contents if necessary.
+ const ImageDesc &desc = mState.getImageDesc(imageIndex);
+ if (desc.initState != InitState::MayNeedInit)
+ {
+ return false;
+ }
+
+ ASSERT(mState.mInitState == InitState::MayNeedInit);
+ return !area.coversSameExtent(desc.size);
+}
+
+angle::Result Texture::ensureSubImageInitialized(const Context *context,
+ const ImageIndex &imageIndex,
+ const Box &area)
+{
+ if (doesSubImageNeedInit(context, imageIndex, area))
+ {
+ // NOTE: do not optimize this to only initialize the passed area of the texture, or the
+ // initialization logic in copySubImage will be incorrect.
+ ANGLE_TRY(initializeContents(context, GL_NONE, imageIndex));
+ }
+ // Note: binding is ignored for textures.
+ setInitState(GL_NONE, imageIndex, InitState::Initialized);
+ return angle::Result::Continue;
+}
+
+angle::Result Texture::handleMipmapGenerationHint(Context *context, int level)
+{
+ if (getGenerateMipmapHint() == GL_TRUE && level == 0)
+ {
+ ANGLE_TRY(generateMipmap(context));
+ }
+
+ return angle::Result::Continue;
+}
+
+void Texture::onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message)
+{
+ switch (message)
+ {
+ case angle::SubjectMessage::ContentsChanged:
+ if (index != kBufferSubjectIndex)
+ {
+ // ContentsChange originates from TextureStorage11::resolveAndReleaseTexture
+ // which resolves the underlying multisampled texture if it exists and so
+ // Texture will signal dirty storage to invalidate its own cache and the
+ // attached framebuffer's cache.
+ signalDirtyStorage(InitState::Initialized);
+ }
+ break;
+ case angle::SubjectMessage::DirtyBitsFlagged:
+ signalDirtyState(DIRTY_BIT_IMPLEMENTATION);
+
+ // Notify siblings that we are dirty.
+ if (index == rx::kTextureImageImplObserverMessageIndex)
+ {
+ notifySiblings(message);
+ }
+ break;
+ case angle::SubjectMessage::SubjectChanged:
+ mState.mInitState = InitState::MayNeedInit;
+ signalDirtyState(DIRTY_BIT_IMPLEMENTATION);
+ onStateChange(angle::SubjectMessage::ContentsChanged);
+
+ // Notify siblings that we are dirty.
+ if (index == rx::kTextureImageImplObserverMessageIndex)
+ {
+ notifySiblings(message);
+ }
+ else if (index == kBufferSubjectIndex)
+ {
+ const gl::Buffer *buffer = mState.mBuffer.get();
+ ASSERT(buffer != nullptr);
+
+ // Update cached image desc based on buffer size.
+ GLsizeiptr size = GetBoundBufferAvailableSize(mState.mBuffer);
+
+ ImageDesc desc = mState.getImageDesc(TextureTarget::Buffer, 0);
+ const GLuint pixelBytes = desc.format.info->pixelBytes;
+ desc.size.width = static_cast<GLuint>(size / pixelBytes);
+
+ mState.setImageDesc(TextureTarget::Buffer, 0, desc);
+ }
+ break;
+ case angle::SubjectMessage::StorageReleased:
+ // When the TextureStorage is released, it needs to update the
+ // RenderTargetCache of the Framebuffer attaching this Texture.
+ // This is currently only for D3D back-end. See http://crbug.com/1234829
+ if (index == rx::kTextureImageImplObserverMessageIndex)
+ {
+ onStateChange(angle::SubjectMessage::StorageReleased);
+ }
+ break;
+ case angle::SubjectMessage::SubjectMapped:
+ case angle::SubjectMessage::SubjectUnmapped:
+ case angle::SubjectMessage::BindingChanged:
+ ASSERT(index == kBufferSubjectIndex);
+ break;
+ case angle::SubjectMessage::InitializationComplete:
+ ASSERT(index == rx::kTextureImageImplObserverMessageIndex);
+ setInitState(InitState::Initialized);
+ break;
+ case angle::SubjectMessage::InternalMemoryAllocationChanged:
+ // Need to mark the texture dirty to give the back end a chance to handle the new
+ // buffer. For example, the Vulkan back end needs to create a new buffer view that
+ // points to the newly allocated buffer and update the texture descriptor set.
+ signalDirtyState(DIRTY_BIT_IMPLEMENTATION);
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+GLenum Texture::getImplementationColorReadFormat(const Context *context) const
+{
+ return mTexture->getColorReadFormat(context);
+}
+
+GLenum Texture::getImplementationColorReadType(const Context *context) const
+{
+ return mTexture->getColorReadType(context);
+}
+
+bool Texture::isCompressedFormatEmulated(const Context *context,
+ TextureTarget target,
+ GLint level) const
+{
+ if (!getFormat(target, level).info->compressed)
+ {
+ // If it isn't compressed, the remaining logic won't work
+ return false;
+ }
+
+ GLenum implFormat = getImplementationColorReadFormat(context);
+
+ // Check against the list of formats used to emulate compressed textures
+ return IsEmulatedCompressedFormat(implFormat);
+}
+
+angle::Result Texture::getTexImage(const Context *context,
+ const PixelPackState &packState,
+ Buffer *packBuffer,
+ TextureTarget target,
+ GLint level,
+ GLenum format,
+ GLenum type,
+ void *pixels)
+{
+ // No-op if the image level is empty.
+ if (getExtents(target, level).empty())
+ {
+ return angle::Result::Continue;
+ }
+
+ return mTexture->getTexImage(context, packState, packBuffer, target, level, format, type,
+ pixels);
+}
+
+angle::Result Texture::getCompressedTexImage(const Context *context,
+ const PixelPackState &packState,
+ Buffer *packBuffer,
+ TextureTarget target,
+ GLint level,
+ void *pixels)
+{
+ // No-op if the image level is empty.
+ if (getExtents(target, level).empty())
+ {
+ return angle::Result::Continue;
+ }
+
+ return mTexture->getCompressedTexImage(context, packState, packBuffer, target, level, pixels);
+}
+
+void Texture::onBindAsImageTexture()
+{
+ if (!mState.mHasBeenBoundAsImage)
+ {
+ mDirtyBits.set(DIRTY_BIT_BOUND_AS_IMAGE);
+ mState.mHasBeenBoundAsImage = true;
+ }
+}
+
+void Texture::onBind3DTextureAs2DImage()
+{
+ if (!mState.mIs3DAndHasBeenBoundAs2DImage)
+ {
+ mDirtyBits.set(DIRTY_BIT_BOUND_AS_IMAGE);
+ mState.mIs3DAndHasBeenBoundAs2DImage = true;
+ }
+}
+
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/Texture.h b/gfx/angle/checkout/src/libANGLE/Texture.h
new file mode 100644
index 0000000000..757f1a2e7e
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Texture.h
@@ -0,0 +1,738 @@
+//
+// Copyright 2002 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.
+//
+
+// Texture.h: Defines the gl::Texture class [OpenGL ES 2.0.24] section 3.7 page 63.
+
+#ifndef LIBANGLE_TEXTURE_H_
+#define LIBANGLE_TEXTURE_H_
+
+#include <map>
+#include <vector>
+
+#include "angle_gl.h"
+#include "common/Optional.h"
+#include "common/debug.h"
+#include "common/utilities.h"
+#include "libANGLE/Caps.h"
+#include "libANGLE/Constants.h"
+#include "libANGLE/Debug.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/Image.h"
+#include "libANGLE/Observer.h"
+#include "libANGLE/Stream.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/formatutils.h"
+
+namespace egl
+{
+class Surface;
+class Stream;
+} // namespace egl
+
+namespace rx
+{
+class GLImplFactory;
+class TextureImpl;
+class TextureGL;
+} // namespace rx
+
+namespace gl
+{
+class Framebuffer;
+class MemoryObject;
+class Sampler;
+class State;
+class Texture;
+
+constexpr GLuint kInitialMaxLevel = 1000;
+
+bool IsMipmapFiltered(GLenum minFilterMode);
+
+// Convert a given filter mode to nearest filtering.
+GLenum ConvertToNearestFilterMode(GLenum filterMode);
+
+// Convert a given filter mode to nearest mip filtering.
+GLenum ConvertToNearestMipFilterMode(GLenum filterMode);
+
+struct ImageDesc final
+{
+ ImageDesc();
+ ImageDesc(const Extents &size, const Format &format, const InitState initState);
+ ImageDesc(const Extents &size,
+ const Format &format,
+ const GLsizei samples,
+ const bool fixedSampleLocations,
+ const InitState initState);
+
+ ImageDesc(const ImageDesc &other) = default;
+ ImageDesc &operator=(const ImageDesc &other) = default;
+
+ GLint getMemorySize() const;
+
+ Extents size;
+ Format format;
+ GLsizei samples;
+ bool fixedSampleLocations;
+
+ // Needed for robust resource initialization.
+ InitState initState;
+};
+
+struct SwizzleState final
+{
+ SwizzleState();
+ SwizzleState(GLenum red, GLenum green, GLenum blue, GLenum alpha);
+ SwizzleState(const SwizzleState &other) = default;
+ SwizzleState &operator=(const SwizzleState &other) = default;
+
+ bool swizzleRequired() const;
+
+ bool operator==(const SwizzleState &other) const;
+ bool operator!=(const SwizzleState &other) const;
+
+ GLenum swizzleRed;
+ GLenum swizzleGreen;
+ GLenum swizzleBlue;
+ GLenum swizzleAlpha;
+};
+
+// State from Table 6.9 (state per texture object) in the OpenGL ES 3.0.2 spec.
+class TextureState final : private angle::NonCopyable
+{
+ public:
+ TextureState(TextureType type);
+ ~TextureState();
+
+ bool swizzleRequired() const;
+ GLuint getEffectiveBaseLevel() const;
+ GLuint getEffectiveMaxLevel() const;
+
+ // Returns the value called "q" in the GLES 3.0.4 spec section 3.8.10.
+ GLuint getMipmapMaxLevel() const;
+
+ // Returns true if base level changed.
+ bool setBaseLevel(GLuint baseLevel);
+ GLuint getBaseLevel() const { return mBaseLevel; }
+ bool setMaxLevel(GLuint maxLevel);
+ GLuint getMaxLevel() const { return mMaxLevel; }
+
+ bool isCubeComplete() const;
+
+ ANGLE_INLINE bool compatibleWithSamplerFormatForWebGL(SamplerFormat format,
+ const SamplerState &samplerState) const
+ {
+ if (!mCachedSamplerFormatValid ||
+ mCachedSamplerCompareMode != samplerState.getCompareMode())
+ {
+ mCachedSamplerFormat = computeRequiredSamplerFormat(samplerState);
+ mCachedSamplerCompareMode = samplerState.getCompareMode();
+ mCachedSamplerFormatValid = true;
+ }
+ // Incomplete textures are compatible with any sampler format.
+ return mCachedSamplerFormat == SamplerFormat::InvalidEnum || format == mCachedSamplerFormat;
+ }
+
+ const ImageDesc &getImageDesc(TextureTarget target, size_t level) const;
+ const ImageDesc &getImageDesc(const ImageIndex &imageIndex) const;
+
+ TextureType getType() const { return mType; }
+ const SwizzleState &getSwizzleState() const { return mSwizzleState; }
+ const SamplerState &getSamplerState() const { return mSamplerState; }
+ GLenum getUsage() const { return mUsage; }
+ bool hasProtectedContent() const { return mHasProtectedContent; }
+ GLenum getDepthStencilTextureMode() const { return mDepthStencilTextureMode; }
+ bool isStencilMode() const { return mDepthStencilTextureMode == GL_STENCIL_INDEX; }
+
+ bool hasBeenBoundAsImage() const { return mHasBeenBoundAsImage; }
+ bool is3DTextureAndHasBeenBoundAs2DImage() const { return mIs3DAndHasBeenBoundAs2DImage; }
+ bool hasBeenBoundAsAttachment() const { return mHasBeenBoundAsAttachment; }
+
+ gl::SrgbOverride getSRGBOverride() const { return mSrgbOverride; }
+
+ // Returns the desc of the base level. Only valid for cube-complete/mip-complete textures.
+ const ImageDesc &getBaseLevelDesc() const;
+ const ImageDesc &getLevelZeroDesc() const;
+
+ // GLES1 emulation: For GL_OES_draw_texture
+ void setCrop(const Rectangle &rect);
+ const Rectangle &getCrop() const;
+
+ // GLES1 emulation: Auto-mipmap generation is a texparameter
+ void setGenerateMipmapHint(GLenum hint);
+ GLenum getGenerateMipmapHint() const;
+
+ // Return the enabled mipmap level count.
+ GLuint getEnabledLevelCount() const;
+
+ bool getImmutableFormat() const { return mImmutableFormat; }
+ GLuint getImmutableLevels() const { return mImmutableLevels; }
+
+ const std::vector<ImageDesc> &getImageDescs() const { return mImageDescs; }
+
+ InitState getInitState() const { return mInitState; }
+
+ const OffsetBindingPointer<Buffer> &getBuffer() const { return mBuffer; }
+
+ const std::string &getLabel() const { return mLabel; }
+
+ private:
+ // Texture needs access to the ImageDesc functions.
+ friend class Texture;
+ friend bool operator==(const TextureState &a, const TextureState &b);
+
+ bool computeSamplerCompleteness(const SamplerState &samplerState, const State &state) const;
+ bool computeSamplerCompletenessForCopyImage(const SamplerState &samplerState,
+ const State &state) const;
+
+ bool computeMipmapCompleteness() const;
+ bool computeLevelCompleteness(TextureTarget target, size_t level) const;
+ SamplerFormat computeRequiredSamplerFormat(const SamplerState &samplerState) const;
+
+ TextureTarget getBaseImageTarget() const;
+
+ void setImageDesc(TextureTarget target, size_t level, const ImageDesc &desc);
+ void setImageDescChain(GLuint baselevel,
+ GLuint maxLevel,
+ Extents baseSize,
+ const Format &format,
+ InitState initState);
+ void setImageDescChainMultisample(Extents baseSize,
+ const Format &format,
+ GLsizei samples,
+ bool fixedSampleLocations,
+ InitState initState);
+
+ void clearImageDesc(TextureTarget target, size_t level);
+ void clearImageDescs();
+
+ const TextureType mType;
+
+ SwizzleState mSwizzleState;
+
+ SamplerState mSamplerState;
+
+ SrgbOverride mSrgbOverride;
+
+ GLuint mBaseLevel;
+ GLuint mMaxLevel;
+
+ GLenum mDepthStencilTextureMode;
+
+ bool mHasBeenBoundAsImage;
+ bool mIs3DAndHasBeenBoundAs2DImage;
+ bool mHasBeenBoundAsAttachment;
+
+ bool mImmutableFormat;
+ GLuint mImmutableLevels;
+
+ // From GL_ANGLE_texture_usage
+ GLenum mUsage;
+
+ // GL_EXT_protected_textures
+ bool mHasProtectedContent;
+
+ std::vector<ImageDesc> mImageDescs;
+
+ // GLES1 emulation: Texture crop rectangle
+ // For GL_OES_draw_texture
+ Rectangle mCropRect;
+
+ // GLES1 emulation: Generate-mipmap hint per texture
+ GLenum mGenerateMipmapHint;
+
+ // GL_OES_texture_buffer / GLES3.2
+ OffsetBindingPointer<Buffer> mBuffer;
+
+ InitState mInitState;
+
+ mutable SamplerFormat mCachedSamplerFormat;
+ mutable GLenum mCachedSamplerCompareMode;
+ mutable bool mCachedSamplerFormatValid;
+ std::string mLabel;
+};
+
+bool operator==(const TextureState &a, const TextureState &b);
+bool operator!=(const TextureState &a, const TextureState &b);
+
+class Texture final : public RefCountObject<TextureID>,
+ public egl::ImageSibling,
+ public LabeledObject
+{
+ public:
+ Texture(rx::GLImplFactory *factory, TextureID id, TextureType type);
+ ~Texture() override;
+
+ void onDestroy(const Context *context) override;
+
+ angle::Result setLabel(const Context *context, const std::string &label) override;
+
+ const std::string &getLabel() const override;
+
+ TextureType getType() const { return mState.mType; }
+
+ void setSwizzleRed(const Context *context, GLenum swizzleRed);
+ GLenum getSwizzleRed() const;
+
+ void setSwizzleGreen(const Context *context, GLenum swizzleGreen);
+ GLenum getSwizzleGreen() const;
+
+ void setSwizzleBlue(const Context *context, GLenum swizzleBlue);
+ GLenum getSwizzleBlue() const;
+
+ void setSwizzleAlpha(const Context *context, GLenum swizzleAlpha);
+ GLenum getSwizzleAlpha() const;
+
+ void setMinFilter(const Context *context, GLenum minFilter);
+ GLenum getMinFilter() const;
+
+ void setMagFilter(const Context *context, GLenum magFilter);
+ GLenum getMagFilter() const;
+
+ void setWrapS(const Context *context, GLenum wrapS);
+ GLenum getWrapS() const;
+
+ void setWrapT(const Context *context, GLenum wrapT);
+ GLenum getWrapT() const;
+
+ void setWrapR(const Context *context, GLenum wrapR);
+ GLenum getWrapR() const;
+
+ void setMaxAnisotropy(const Context *context, float maxAnisotropy);
+ float getMaxAnisotropy() const;
+
+ void setMinLod(const Context *context, GLfloat minLod);
+ GLfloat getMinLod() const;
+
+ void setMaxLod(const Context *context, GLfloat maxLod);
+ GLfloat getMaxLod() const;
+
+ void setCompareMode(const Context *context, GLenum compareMode);
+ GLenum getCompareMode() const;
+
+ void setCompareFunc(const Context *context, GLenum compareFunc);
+ GLenum getCompareFunc() const;
+
+ void setSRGBDecode(const Context *context, GLenum sRGBDecode);
+ GLenum getSRGBDecode() const;
+
+ void setSRGBOverride(const Context *context, GLenum sRGBOverride);
+ GLenum getSRGBOverride() const;
+
+ const SamplerState &getSamplerState() const;
+
+ angle::Result setBaseLevel(const Context *context, GLuint baseLevel);
+ GLuint getBaseLevel() const;
+
+ void setMaxLevel(const Context *context, GLuint maxLevel);
+ GLuint getMaxLevel() const;
+
+ void setDepthStencilTextureMode(const Context *context, GLenum mode);
+ GLenum getDepthStencilTextureMode() const;
+
+ bool getImmutableFormat() const;
+
+ GLuint getImmutableLevels() const;
+
+ void setUsage(const Context *context, GLenum usage);
+ GLenum getUsage() const;
+
+ void setProtectedContent(Context *context, bool hasProtectedContent);
+ bool hasProtectedContent() const override;
+
+ const TextureState &getState() const { return mState; }
+
+ void setBorderColor(const Context *context, const ColorGeneric &color);
+ const ColorGeneric &getBorderColor() const;
+
+ angle::Result setBuffer(const Context *context, gl::Buffer *buffer, GLenum internalFormat);
+ angle::Result setBufferRange(const Context *context,
+ gl::Buffer *buffer,
+ GLenum internalFormat,
+ GLintptr offset,
+ GLsizeiptr size);
+ const OffsetBindingPointer<Buffer> &getBuffer() const;
+
+ GLint getRequiredTextureImageUnits(const Context *context) const;
+
+ const TextureState &getTextureState() const;
+
+ const Extents &getExtents(TextureTarget target, size_t level) const;
+ size_t getWidth(TextureTarget target, size_t level) const;
+ size_t getHeight(TextureTarget target, size_t level) const;
+ size_t getDepth(TextureTarget target, size_t level) const;
+ GLsizei getSamples(TextureTarget target, size_t level) const;
+ bool getFixedSampleLocations(TextureTarget target, size_t level) const;
+ const Format &getFormat(TextureTarget target, size_t level) const;
+
+ // Returns the value called "q" in the GLES 3.0.4 spec section 3.8.10.
+ GLuint getMipmapMaxLevel() const;
+
+ bool isMipmapComplete() const;
+
+ angle::Result setImage(Context *context,
+ const PixelUnpackState &unpackState,
+ Buffer *unpackBuffer,
+ TextureTarget target,
+ GLint level,
+ GLenum internalFormat,
+ const Extents &size,
+ GLenum format,
+ GLenum type,
+ const uint8_t *pixels);
+ angle::Result setSubImage(Context *context,
+ const PixelUnpackState &unpackState,
+ Buffer *unpackBuffer,
+ TextureTarget target,
+ GLint level,
+ const Box &area,
+ GLenum format,
+ GLenum type,
+ const uint8_t *pixels);
+
+ angle::Result setCompressedImage(Context *context,
+ const PixelUnpackState &unpackState,
+ TextureTarget target,
+ GLint level,
+ GLenum internalFormat,
+ const Extents &size,
+ size_t imageSize,
+ const uint8_t *pixels);
+ angle::Result setCompressedSubImage(const Context *context,
+ const PixelUnpackState &unpackState,
+ TextureTarget target,
+ GLint level,
+ const Box &area,
+ GLenum format,
+ size_t imageSize,
+ const uint8_t *pixels);
+
+ angle::Result copyImage(Context *context,
+ TextureTarget target,
+ GLint level,
+ const Rectangle &sourceArea,
+ GLenum internalFormat,
+ Framebuffer *source);
+ angle::Result copySubImage(Context *context,
+ const ImageIndex &index,
+ const Offset &destOffset,
+ const Rectangle &sourceArea,
+ Framebuffer *source);
+
+ angle::Result copyRenderbufferSubData(Context *context,
+ const gl::Renderbuffer *srcBuffer,
+ GLint srcLevel,
+ GLint srcX,
+ GLint srcY,
+ GLint srcZ,
+ GLint dstLevel,
+ GLint dstX,
+ GLint dstY,
+ GLint dstZ,
+ GLsizei srcWidth,
+ GLsizei srcHeight,
+ GLsizei srcDepth);
+
+ angle::Result copyTextureSubData(Context *context,
+ const gl::Texture *srcTexture,
+ GLint srcLevel,
+ GLint srcX,
+ GLint srcY,
+ GLint srcZ,
+ GLint dstLevel,
+ GLint dstX,
+ GLint dstY,
+ GLint dstZ,
+ GLsizei srcWidth,
+ GLsizei srcHeight,
+ GLsizei srcDepth);
+
+ angle::Result copyTexture(Context *context,
+ TextureTarget target,
+ GLint level,
+ GLenum internalFormat,
+ GLenum type,
+ GLint sourceLevel,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha,
+ Texture *source);
+ angle::Result copySubTexture(const Context *context,
+ TextureTarget target,
+ GLint level,
+ const Offset &destOffset,
+ GLint sourceLevel,
+ const Box &sourceBox,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha,
+ Texture *source);
+ angle::Result copyCompressedTexture(Context *context, const Texture *source);
+
+ angle::Result setStorage(Context *context,
+ TextureType type,
+ GLsizei levels,
+ GLenum internalFormat,
+ const Extents &size);
+
+ angle::Result setStorageMultisample(Context *context,
+ TextureType type,
+ GLsizei samplesIn,
+ GLint internalformat,
+ const Extents &size,
+ bool fixedSampleLocations);
+
+ angle::Result setStorageExternalMemory(Context *context,
+ TextureType type,
+ GLsizei levels,
+ GLenum internalFormat,
+ const Extents &size,
+ MemoryObject *memoryObject,
+ GLuint64 offset,
+ GLbitfield createFlags,
+ GLbitfield usageFlags,
+ const void *imageCreateInfoPNext);
+
+ angle::Result setImageExternal(Context *context,
+ TextureTarget target,
+ GLint level,
+ GLenum internalFormat,
+ const Extents &size,
+ GLenum format,
+ GLenum type);
+
+ angle::Result setEGLImageTarget(Context *context, TextureType type, egl::Image *imageTarget);
+
+ angle::Result setStorageEGLImageTarget(Context *context,
+ TextureType type,
+ egl::Image *image,
+ const GLint *attrib_list);
+
+ angle::Result generateMipmap(Context *context);
+
+ void onBindAsImageTexture();
+ void onBind3DTextureAs2DImage();
+
+ egl::Surface *getBoundSurface() const;
+ egl::Stream *getBoundStream() const;
+
+ GLint getMemorySize() const;
+ GLint getLevelMemorySize(TextureTarget target, GLint level) const;
+
+ void signalDirtyStorage(InitState initState);
+
+ bool isSamplerComplete(const Context *context, const Sampler *optionalSampler);
+ bool isSamplerCompleteForCopyImage(const Context *context,
+ const Sampler *optionalSampler) const;
+
+ GLenum getImplementationColorReadFormat(const Context *context) const;
+ GLenum getImplementationColorReadType(const Context *context) const;
+
+ bool isCompressedFormatEmulated(const Context *context,
+ TextureTarget target,
+ GLint level) const;
+
+ // We pass the pack buffer and state explicitly so they can be overridden during capture.
+ angle::Result getTexImage(const Context *context,
+ const PixelPackState &packState,
+ Buffer *packBuffer,
+ TextureTarget target,
+ GLint level,
+ GLenum format,
+ GLenum type,
+ void *pixels);
+
+ angle::Result getCompressedTexImage(const Context *context,
+ const PixelPackState &packState,
+ Buffer *packBuffer,
+ TextureTarget target,
+ GLint level,
+ void *pixels);
+
+ rx::TextureImpl *getImplementation() const { return mTexture; }
+
+ // FramebufferAttachmentObject implementation
+ Extents getAttachmentSize(const ImageIndex &imageIndex) const override;
+ Format getAttachmentFormat(GLenum binding, const ImageIndex &imageIndex) const override;
+ GLsizei getAttachmentSamples(const ImageIndex &imageIndex) const override;
+ bool isRenderable(const Context *context,
+ GLenum binding,
+ const ImageIndex &imageIndex) const override;
+
+ bool getAttachmentFixedSampleLocations(const ImageIndex &imageIndex) const;
+
+ // GLES1 emulation
+ void setCrop(const Rectangle &rect);
+ const Rectangle &getCrop() const;
+ void setGenerateMipmapHint(GLenum generate);
+ GLenum getGenerateMipmapHint() const;
+
+ void onAttach(const Context *context, rx::Serial framebufferSerial) override;
+ void onDetach(const Context *context, rx::Serial framebufferSerial) override;
+
+ // Used specifically for FramebufferAttachmentObject.
+ GLuint getId() const override;
+
+ GLuint getNativeID() const;
+
+ // Needed for robust resource init.
+ angle::Result ensureInitialized(const Context *context);
+ InitState initState(GLenum binding, const ImageIndex &imageIndex) const override;
+ InitState initState() const { return mState.mInitState; }
+ void setInitState(GLenum binding, const ImageIndex &imageIndex, InitState initState) override;
+ void setInitState(InitState initState);
+
+ bool isBoundToFramebuffer(rx::Serial framebufferSerial) const
+ {
+ for (size_t index = 0; index < mBoundFramebufferSerials.size(); ++index)
+ {
+ if (mBoundFramebufferSerials[index] == framebufferSerial)
+ return true;
+ }
+
+ return false;
+ }
+
+ bool isDepthOrStencil() const
+ {
+ return mState.getBaseLevelDesc().format.info->isDepthOrStencil();
+ }
+
+ enum DirtyBitType
+ {
+ // Sampler state
+ DIRTY_BIT_MIN_FILTER,
+ DIRTY_BIT_MAG_FILTER,
+ DIRTY_BIT_WRAP_S,
+ DIRTY_BIT_WRAP_T,
+ DIRTY_BIT_WRAP_R,
+ DIRTY_BIT_MAX_ANISOTROPY,
+ DIRTY_BIT_MIN_LOD,
+ DIRTY_BIT_MAX_LOD,
+ DIRTY_BIT_COMPARE_MODE,
+ DIRTY_BIT_COMPARE_FUNC,
+ DIRTY_BIT_SRGB_DECODE,
+ DIRTY_BIT_SRGB_OVERRIDE,
+ DIRTY_BIT_BORDER_COLOR,
+
+ // Texture state
+ DIRTY_BIT_SWIZZLE_RED,
+ DIRTY_BIT_SWIZZLE_GREEN,
+ DIRTY_BIT_SWIZZLE_BLUE,
+ DIRTY_BIT_SWIZZLE_ALPHA,
+ DIRTY_BIT_BASE_LEVEL,
+ DIRTY_BIT_MAX_LEVEL,
+ DIRTY_BIT_DEPTH_STENCIL_TEXTURE_MODE,
+
+ // Image state
+ DIRTY_BIT_BOUND_AS_IMAGE,
+ DIRTY_BIT_BOUND_AS_ATTACHMENT,
+
+ // Misc
+ DIRTY_BIT_USAGE,
+ DIRTY_BIT_IMPLEMENTATION,
+
+ DIRTY_BIT_COUNT,
+ };
+ using DirtyBits = angle::BitSet<DIRTY_BIT_COUNT>;
+
+ angle::Result syncState(const Context *context, Command source);
+ bool hasAnyDirtyBit() const { return mDirtyBits.any(); }
+ bool hasAnyDirtyBitExcludingBoundAsAttachmentBit() const
+ {
+ static constexpr DirtyBits kBoundAsAttachment = DirtyBits({DIRTY_BIT_BOUND_AS_ATTACHMENT});
+ return mDirtyBits.any() && mDirtyBits != kBoundAsAttachment;
+ }
+
+ // ObserverInterface implementation.
+ void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override;
+
+ private:
+ rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override;
+
+ // ANGLE-only method, used internally
+ friend class egl::Surface;
+ angle::Result bindTexImageFromSurface(Context *context, egl::Surface *surface);
+ angle::Result releaseTexImageFromSurface(const Context *context);
+
+ // ANGLE-only methods, used internally
+ friend class egl::Stream;
+ void bindStream(egl::Stream *stream);
+ void releaseStream();
+ angle::Result acquireImageFromStream(const Context *context,
+ const egl::Stream::GLTextureDescription &desc);
+ angle::Result releaseImageFromStream(const Context *context);
+
+ void invalidateCompletenessCache() const;
+ angle::Result releaseTexImageInternal(Context *context);
+
+ bool doesSubImageNeedInit(const Context *context,
+ const ImageIndex &imageIndex,
+ const Box &area) const;
+ angle::Result ensureSubImageInitialized(const Context *context,
+ const ImageIndex &imageIndex,
+ const Box &area);
+
+ angle::Result handleMipmapGenerationHint(Context *context, int level);
+
+ angle::Result setEGLImageTargetImpl(Context *context,
+ TextureType type,
+ GLuint levels,
+ egl::Image *imageTarget);
+
+ void signalDirtyState(size_t dirtyBit);
+
+ TextureState mState;
+ DirtyBits mDirtyBits;
+ rx::TextureImpl *mTexture;
+ angle::ObserverBinding mImplObserver;
+ // For EXT_texture_buffer, observes buffer changes.
+ angle::ObserverBinding mBufferObserver;
+
+ egl::Surface *mBoundSurface;
+ egl::Stream *mBoundStream;
+
+ // We track all the serials of the Framebuffers this texture is attached to. Note that this
+ // allows duplicates because different ranges of a Texture can be bound to the same Framebuffer.
+ // For the purposes of depth-stencil loops, a simple "isBound" check works fine. For color
+ // attachment Feedback Loop checks we then need to check further to see when a Texture is bound
+ // to mulitple bindings that the bindings don't overlap.
+ static constexpr uint32_t kFastFramebufferSerialCount = 8;
+ angle::FastVector<rx::Serial, kFastFramebufferSerialCount> mBoundFramebufferSerials;
+
+ struct SamplerCompletenessCache
+ {
+ SamplerCompletenessCache();
+
+ // Context used to generate this cache entry
+ ContextID context;
+
+ // All values that affect sampler completeness that are not stored within
+ // the texture itself
+ SamplerState samplerState;
+
+ // Result of the sampler completeness with the above parameters
+ bool samplerComplete;
+ };
+
+ mutable SamplerCompletenessCache mCompletenessCache;
+};
+
+inline bool operator==(const TextureState &a, const TextureState &b)
+{
+ return a.mSwizzleState == b.mSwizzleState && a.mSamplerState == b.mSamplerState &&
+ a.mBaseLevel == b.mBaseLevel && a.mMaxLevel == b.mMaxLevel &&
+ a.mImmutableFormat == b.mImmutableFormat && a.mImmutableLevels == b.mImmutableLevels &&
+ a.mUsage == b.mUsage;
+}
+
+inline bool operator!=(const TextureState &a, const TextureState &b)
+{
+ return !(a == b);
+}
+} // namespace gl
+
+#endif // LIBANGLE_TEXTURE_H_
diff --git a/gfx/angle/checkout/src/libANGLE/Thread.cpp b/gfx/angle/checkout/src/libANGLE/Thread.cpp
new file mode 100644
index 0000000000..7f5f65fa3c
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Thread.cpp
@@ -0,0 +1,168 @@
+//
+// 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.
+//
+
+// Thread.cpp : Defines the Thread class which represents a global EGL thread.
+
+#include "libANGLE/Thread.h"
+
+#include "libANGLE/Context.h"
+#include "libANGLE/Debug.h"
+#include "libANGLE/Display.h"
+#include "libANGLE/Error.h"
+
+namespace angle
+{
+#if defined(ANGLE_USE_ANDROID_TLS_SLOT)
+bool gUseAndroidOpenGLTlsSlot;
+#endif
+
+void PthreadKeyDestructorCallback(void *ptr)
+{
+ egl::Thread *thread = static_cast<egl::Thread *>(ptr);
+ ASSERT(thread);
+
+ egl::Display::EglDisplaySet displays = egl::Display::GetEglDisplaySet();
+ for (egl::Display *display : displays)
+ {
+ ASSERT(display);
+ // Perform necessary cleanup.
+ display->threadCleanup(thread);
+ }
+}
+} // namespace angle
+
+namespace egl
+{
+namespace
+{
+Debug *sDebug = nullptr;
+} // namespace
+
+Thread::Thread()
+ : mLabel(nullptr),
+ mError(EGL_SUCCESS),
+ mAPI(EGL_OPENGL_ES_API),
+ mContext(static_cast<gl::Context *>(EGL_NO_CONTEXT))
+{}
+
+void Thread::setLabel(EGLLabelKHR label)
+{
+ mLabel = label;
+}
+
+EGLLabelKHR Thread::getLabel() const
+{
+ return mLabel;
+}
+
+void Thread::setSuccess()
+{
+ mError = EGL_SUCCESS;
+}
+
+void Thread::setError(EGLint error,
+ const char *command,
+ const LabeledObject *object,
+ const char *message)
+{
+ mError = error;
+ if (error != EGL_SUCCESS && message)
+ {
+ EnsureDebugAllocated();
+ sDebug->insertMessage(error, command, ErrorCodeToMessageType(error), getLabel(),
+ object ? object->getLabel() : nullptr, message);
+ }
+}
+
+void Thread::setError(const Error &error, const char *command, const LabeledObject *object)
+{
+ mError = error.getCode();
+ if (error.isError() && !error.getMessage().empty())
+ {
+ EnsureDebugAllocated();
+ sDebug->insertMessage(error.getCode(), command, ErrorCodeToMessageType(error.getCode()),
+ getLabel(), object ? object->getLabel() : nullptr,
+ error.getMessage());
+ }
+}
+
+EGLint Thread::getError() const
+{
+ return mError;
+}
+
+void Thread::setAPI(EGLenum api)
+{
+ mAPI = api;
+}
+
+EGLenum Thread::getAPI() const
+{
+ return mAPI;
+}
+
+void Thread::setCurrent(gl::Context *context)
+{
+ mContext = context;
+ if (mContext)
+ {
+ ASSERT(mContext->getDisplay());
+ mContext->getDisplay()->addActiveThread(this);
+ }
+}
+
+Surface *Thread::getCurrentDrawSurface() const
+{
+ if (mContext)
+ {
+ return mContext->getCurrentDrawSurface();
+ }
+ return nullptr;
+}
+
+Surface *Thread::getCurrentReadSurface() const
+{
+ if (mContext)
+ {
+ return mContext->getCurrentReadSurface();
+ }
+ return nullptr;
+}
+
+gl::Context *Thread::getContext() const
+{
+ return mContext;
+}
+
+Display *Thread::getDisplay() const
+{
+ if (mContext)
+ {
+ return mContext->getDisplay();
+ }
+ return nullptr;
+}
+
+void EnsureDebugAllocated()
+{
+ // All EGL calls use a global lock, this is thread safe
+ if (sDebug == nullptr)
+ {
+ sDebug = new Debug();
+ }
+}
+
+void DeallocateDebug()
+{
+ SafeDelete(sDebug);
+}
+
+Debug *GetDebug()
+{
+ EnsureDebugAllocated();
+ return sDebug;
+}
+} // namespace egl
diff --git a/gfx/angle/checkout/src/libANGLE/Thread.h b/gfx/angle/checkout/src/libANGLE/Thread.h
new file mode 100644
index 0000000000..415c09bf37
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Thread.h
@@ -0,0 +1,80 @@
+//
+// 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.
+//
+
+// Thread.h : Defines the Thread class which represents a global EGL thread.
+
+#ifndef LIBANGLE_THREAD_H_
+#define LIBANGLE_THREAD_H_
+
+#include <EGL/egl.h>
+
+#include "libANGLE/Debug.h"
+
+#include <atomic>
+
+namespace angle
+{
+#if defined(ANGLE_USE_ANDROID_TLS_SLOT)
+extern bool gUseAndroidOpenGLTlsSlot;
+#endif
+
+void PthreadKeyDestructorCallback(void *ptr);
+} // namespace angle
+
+namespace gl
+{
+class Context;
+} // namespace gl
+
+namespace egl
+{
+class Error;
+class Debug;
+class Display;
+class Surface;
+
+class Thread : public LabeledObject
+{
+ public:
+ Thread();
+
+ void setLabel(EGLLabelKHR label) override;
+ EGLLabelKHR getLabel() const override;
+
+ void setSuccess();
+
+ void setError(EGLint error,
+ const char *command,
+ const LabeledObject *object,
+ const char *message);
+
+ // TODO: Remove egl::Error. http://anglebug.com/3041
+ void setError(const Error &error, const char *command, const LabeledObject *object);
+ EGLint getError() const;
+
+ void setAPI(EGLenum api);
+ EGLenum getAPI() const;
+
+ void setCurrent(gl::Context *context);
+ Surface *getCurrentDrawSurface() const;
+ Surface *getCurrentReadSurface() const;
+ gl::Context *getContext() const;
+ Display *getDisplay() const;
+
+ private:
+ EGLLabelKHR mLabel;
+ EGLint mError;
+ EGLenum mAPI;
+ gl::Context *mContext;
+};
+
+void EnsureDebugAllocated();
+void DeallocateDebug();
+Debug *GetDebug();
+
+} // namespace egl
+
+#endif // LIBANGLE_THREAD_H_
diff --git a/gfx/angle/checkout/src/libANGLE/TransformFeedback.cpp b/gfx/angle/checkout/src/libANGLE/TransformFeedback.cpp
new file mode 100644
index 0000000000..af1875ac50
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/TransformFeedback.cpp
@@ -0,0 +1,347 @@
+//
+// 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.
+//
+
+#include "libANGLE/TransformFeedback.h"
+
+#include "common/mathutil.h"
+#include "libANGLE/Buffer.h"
+#include "libANGLE/Caps.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Program.h"
+#include "libANGLE/State.h"
+#include "libANGLE/renderer/GLImplFactory.h"
+#include "libANGLE/renderer/TransformFeedbackImpl.h"
+
+#include <limits>
+
+namespace gl
+{
+
+angle::CheckedNumeric<GLsizeiptr> GetVerticesNeededForDraw(PrimitiveMode primitiveMode,
+ GLsizei count,
+ GLsizei primcount)
+{
+ if (count < 0 || primcount < 0)
+ {
+ return 0;
+ }
+ // Transform feedback only outputs complete primitives, so we need to round down to the nearest
+ // complete primitive before multiplying by the number of instances.
+ angle::CheckedNumeric<GLsizeiptr> checkedCount = count;
+ angle::CheckedNumeric<GLsizeiptr> checkedPrimcount = primcount;
+ switch (primitiveMode)
+ {
+ case PrimitiveMode::Triangles:
+ return checkedPrimcount * (checkedCount - checkedCount % 3);
+ case PrimitiveMode::Lines:
+ return checkedPrimcount * (checkedCount - checkedCount % 2);
+ case PrimitiveMode::Points:
+ return checkedPrimcount * checkedCount;
+ default:
+ UNREACHABLE();
+ return checkedPrimcount * checkedCount;
+ }
+}
+
+TransformFeedbackState::TransformFeedbackState(size_t maxIndexedBuffers)
+ : mLabel(),
+ mActive(false),
+ mPrimitiveMode(PrimitiveMode::InvalidEnum),
+ mPaused(false),
+ mVerticesDrawn(0),
+ mVertexCapacity(0),
+ mProgram(nullptr),
+ mIndexedBuffers(maxIndexedBuffers)
+{}
+
+TransformFeedbackState::~TransformFeedbackState() {}
+
+const OffsetBindingPointer<Buffer> &TransformFeedbackState::getIndexedBuffer(size_t idx) const
+{
+ return mIndexedBuffers[idx];
+}
+
+const std::vector<OffsetBindingPointer<Buffer>> &TransformFeedbackState::getIndexedBuffers() const
+{
+ return mIndexedBuffers;
+}
+
+GLsizeiptr TransformFeedbackState::getPrimitivesDrawn() const
+{
+ switch (mPrimitiveMode)
+ {
+ case gl::PrimitiveMode::Points:
+ return mVerticesDrawn;
+ case gl::PrimitiveMode::Lines:
+ return mVerticesDrawn / 2;
+ case gl::PrimitiveMode::Triangles:
+ return mVerticesDrawn / 3;
+ default:
+ return 0;
+ }
+}
+
+TransformFeedback::TransformFeedback(rx::GLImplFactory *implFactory,
+ TransformFeedbackID id,
+ const Caps &caps)
+ : RefCountObject(implFactory->generateSerial(), id),
+ mState(caps.maxTransformFeedbackSeparateAttributes),
+ mImplementation(implFactory->createTransformFeedback(mState))
+{
+ ASSERT(mImplementation != nullptr);
+}
+
+void TransformFeedback::onDestroy(const Context *context)
+{
+ ASSERT(!context || !context->isCurrentTransformFeedback(this));
+ if (mState.mProgram)
+ {
+ mState.mProgram->release(context);
+ mState.mProgram = nullptr;
+ }
+
+ ASSERT(!mState.mProgram);
+ for (size_t i = 0; i < mState.mIndexedBuffers.size(); i++)
+ {
+ mState.mIndexedBuffers[i].set(context, nullptr, 0, 0);
+ }
+
+ if (mImplementation)
+ {
+ mImplementation->onDestroy(context);
+ }
+}
+
+TransformFeedback::~TransformFeedback()
+{
+ SafeDelete(mImplementation);
+}
+
+angle::Result TransformFeedback::setLabel(const Context *context, const std::string &label)
+{
+ mState.mLabel = label;
+
+ if (mImplementation)
+ {
+ return mImplementation->onLabelUpdate(context);
+ }
+ return angle::Result::Continue;
+}
+
+const std::string &TransformFeedback::getLabel() const
+{
+ return mState.mLabel;
+}
+
+angle::Result TransformFeedback::begin(const Context *context,
+ PrimitiveMode primitiveMode,
+ Program *program)
+{
+ // TODO: http://anglebug.com/5486: This method should take in as parameter a
+ // ProgramExecutable instead of a Program.
+
+ ANGLE_TRY(mImplementation->begin(context, primitiveMode));
+ mState.mActive = true;
+ mState.mPrimitiveMode = primitiveMode;
+ mState.mPaused = false;
+ mState.mVerticesDrawn = 0;
+ bindProgram(context, program);
+
+ // In one of the angle_unittests - "TransformFeedbackTest.SideEffectsOfStartAndStop"
+ // there is a code path where <context> is a nullptr, account for that possiblity.
+ const ProgramExecutable *programExecutable =
+ context ? context->getState().getLinkedProgramExecutable(context) : nullptr;
+ if (programExecutable)
+ {
+ // Compute the number of vertices we can draw before overflowing the bound buffers.
+ auto strides = programExecutable->getTransformFeedbackStrides();
+ ASSERT(strides.size() <= mState.mIndexedBuffers.size() && !strides.empty());
+ GLsizeiptr minCapacity = std::numeric_limits<GLsizeiptr>::max();
+ for (size_t index = 0; index < strides.size(); index++)
+ {
+ GLsizeiptr capacity =
+ GetBoundBufferAvailableSize(mState.mIndexedBuffers[index]) / strides[index];
+ minCapacity = std::min(minCapacity, capacity);
+ }
+ mState.mVertexCapacity = minCapacity;
+ }
+ else
+ {
+ mState.mVertexCapacity = 0;
+ }
+ return angle::Result::Continue;
+}
+
+angle::Result TransformFeedback::end(const Context *context)
+{
+ ANGLE_TRY(mImplementation->end(context));
+ mState.mActive = false;
+ mState.mPrimitiveMode = PrimitiveMode::InvalidEnum;
+ mState.mPaused = false;
+ mState.mVerticesDrawn = 0;
+ mState.mVertexCapacity = 0;
+ if (mState.mProgram)
+ {
+ mState.mProgram->release(context);
+ mState.mProgram = nullptr;
+ }
+ return angle::Result::Continue;
+}
+
+angle::Result TransformFeedback::pause(const Context *context)
+{
+ ANGLE_TRY(mImplementation->pause(context));
+ mState.mPaused = true;
+ return angle::Result::Continue;
+}
+
+angle::Result TransformFeedback::resume(const Context *context)
+{
+ ANGLE_TRY(mImplementation->resume(context));
+ mState.mPaused = false;
+ return angle::Result::Continue;
+}
+
+bool TransformFeedback::isPaused() const
+{
+ return mState.mPaused;
+}
+
+PrimitiveMode TransformFeedback::getPrimitiveMode() const
+{
+ return mState.mPrimitiveMode;
+}
+
+bool TransformFeedback::checkBufferSpaceForDraw(GLsizei count, GLsizei primcount) const
+{
+ auto vertices =
+ mState.mVerticesDrawn + GetVerticesNeededForDraw(mState.mPrimitiveMode, count, primcount);
+ return vertices.IsValid() && vertices.ValueOrDie() <= mState.mVertexCapacity;
+}
+
+void TransformFeedback::onVerticesDrawn(const Context *context, GLsizei count, GLsizei primcount)
+{
+ ASSERT(mState.mActive && !mState.mPaused);
+ // All draws should be validated with checkBufferSpaceForDraw so ValueOrDie should never fail.
+ mState.mVerticesDrawn =
+ (mState.mVerticesDrawn + GetVerticesNeededForDraw(mState.mPrimitiveMode, count, primcount))
+ .ValueOrDie();
+
+ for (auto &buffer : mState.mIndexedBuffers)
+ {
+ if (buffer.get() != nullptr)
+ {
+ buffer->onDataChanged();
+ }
+ }
+}
+
+void TransformFeedback::bindProgram(const Context *context, Program *program)
+{
+ if (mState.mProgram != program)
+ {
+ if (mState.mProgram != nullptr)
+ {
+ mState.mProgram->release(context);
+ }
+ mState.mProgram = program;
+ if (mState.mProgram != nullptr)
+ {
+ mState.mProgram->addRef();
+ }
+ }
+}
+
+bool TransformFeedback::hasBoundProgram(ShaderProgramID program) const
+{
+ return mState.mProgram != nullptr && mState.mProgram->id().value == program.value;
+}
+
+angle::Result TransformFeedback::detachBuffer(const Context *context, BufferID bufferID)
+{
+ bool isBound = context->isCurrentTransformFeedback(this);
+ for (size_t index = 0; index < mState.mIndexedBuffers.size(); index++)
+ {
+ if (mState.mIndexedBuffers[index].id() == bufferID)
+ {
+ if (isBound)
+ {
+ mState.mIndexedBuffers[index]->onTFBindingChanged(context, false, true);
+ }
+ mState.mIndexedBuffers[index].set(context, nullptr, 0, 0);
+ ANGLE_TRY(
+ mImplementation->bindIndexedBuffer(context, index, mState.mIndexedBuffers[index]));
+ }
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TransformFeedback::bindIndexedBuffer(const Context *context,
+ size_t index,
+ Buffer *buffer,
+ size_t offset,
+ size_t size)
+{
+ ASSERT(index < mState.mIndexedBuffers.size());
+ bool isBound = context && context->isCurrentTransformFeedback(this);
+ if (isBound && mState.mIndexedBuffers[index].get())
+ {
+ mState.mIndexedBuffers[index]->onTFBindingChanged(context, false, true);
+ }
+ mState.mIndexedBuffers[index].set(context, buffer, offset, size);
+ if (isBound && buffer)
+ {
+ buffer->onTFBindingChanged(context, true, true);
+ }
+
+ return mImplementation->bindIndexedBuffer(context, index, mState.mIndexedBuffers[index]);
+}
+
+const OffsetBindingPointer<Buffer> &TransformFeedback::getIndexedBuffer(size_t index) const
+{
+ ASSERT(index < mState.mIndexedBuffers.size());
+ return mState.mIndexedBuffers[index];
+}
+
+size_t TransformFeedback::getIndexedBufferCount() const
+{
+ return mState.mIndexedBuffers.size();
+}
+
+bool TransformFeedback::buffersBoundForOtherUseInWebGL() const
+{
+ for (auto &buffer : mState.mIndexedBuffers)
+ {
+ if (buffer.get() && buffer->hasWebGLXFBBindingConflict(true))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+rx::TransformFeedbackImpl *TransformFeedback::getImplementation() const
+{
+ return mImplementation;
+}
+
+void TransformFeedback::onBindingChanged(const Context *context, bool bound)
+{
+ for (auto &buffer : mState.mIndexedBuffers)
+ {
+ if (buffer.get())
+ {
+ buffer->onTFBindingChanged(context, bound, true);
+ }
+ }
+}
+
+const std::vector<OffsetBindingPointer<Buffer>> &TransformFeedback::getIndexedBuffers() const
+{
+ return mState.mIndexedBuffers;
+}
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/TransformFeedback.h b/gfx/angle/checkout/src/libANGLE/TransformFeedback.h
new file mode 100644
index 0000000000..e55d0054c1
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/TransformFeedback.h
@@ -0,0 +1,120 @@
+//
+// 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.
+//
+
+#ifndef LIBANGLE_TRANSFORM_FEEDBACK_H_
+#define LIBANGLE_TRANSFORM_FEEDBACK_H_
+
+#include "libANGLE/RefCountObject.h"
+
+#include "common/PackedEnums.h"
+#include "common/angleutils.h"
+#include "libANGLE/Debug.h"
+
+#include "angle_gl.h"
+
+namespace rx
+{
+class GLImplFactory;
+class TransformFeedbackImpl;
+class TransformFeedbackGL;
+} // namespace rx
+
+namespace gl
+{
+class Buffer;
+struct Caps;
+class Context;
+class Program;
+
+class TransformFeedbackState final : angle::NonCopyable
+{
+ public:
+ TransformFeedbackState(size_t maxIndexedBuffers);
+ ~TransformFeedbackState();
+
+ const OffsetBindingPointer<Buffer> &getIndexedBuffer(size_t idx) const;
+ const std::vector<OffsetBindingPointer<Buffer>> &getIndexedBuffers() const;
+ const Program *getBoundProgram() const { return mProgram; }
+ GLsizeiptr getVerticesDrawn() const { return mVerticesDrawn; }
+ GLsizeiptr getPrimitivesDrawn() const;
+
+ private:
+ friend class TransformFeedback;
+
+ std::string mLabel;
+
+ bool mActive;
+ PrimitiveMode mPrimitiveMode;
+ bool mPaused;
+ GLsizeiptr mVerticesDrawn;
+ GLsizeiptr mVertexCapacity;
+
+ Program *mProgram;
+
+ std::vector<OffsetBindingPointer<Buffer>> mIndexedBuffers;
+};
+
+class TransformFeedback final : public RefCountObject<TransformFeedbackID>, public LabeledObject
+{
+ public:
+ TransformFeedback(rx::GLImplFactory *implFactory, TransformFeedbackID id, const Caps &caps);
+ ~TransformFeedback() override;
+ void onDestroy(const Context *context) override;
+
+ angle::Result setLabel(const Context *context, const std::string &label) override;
+ const std::string &getLabel() const override;
+
+ angle::Result begin(const Context *context, PrimitiveMode primitiveMode, Program *program);
+ angle::Result end(const Context *context);
+ angle::Result pause(const Context *context);
+ angle::Result resume(const Context *context);
+
+ bool isActive() const { return mState.mActive; }
+
+ bool isPaused() const;
+ PrimitiveMode getPrimitiveMode() const;
+ // Validates that the vertices produced by a draw call will fit in the bound transform feedback
+ // buffers.
+ bool checkBufferSpaceForDraw(GLsizei count, GLsizei primcount) const;
+ // This must be called after each draw call when transform feedback is enabled to keep track of
+ // how many vertices have been written to the buffers. This information is needed by
+ // checkBufferSpaceForDraw because each draw call appends vertices to the buffers starting just
+ // after the last vertex of the previous draw call.
+ void onVerticesDrawn(const Context *context, GLsizei count, GLsizei primcount);
+
+ bool hasBoundProgram(ShaderProgramID program) const;
+
+ angle::Result bindIndexedBuffer(const Context *context,
+ size_t index,
+ Buffer *buffer,
+ size_t offset,
+ size_t size);
+ const OffsetBindingPointer<Buffer> &getIndexedBuffer(size_t index) const;
+ size_t getIndexedBufferCount() const;
+ const std::vector<OffsetBindingPointer<Buffer>> &getIndexedBuffers() const;
+
+ GLsizeiptr getVerticesDrawn() const { return mState.getVerticesDrawn(); }
+ GLsizeiptr getPrimitivesDrawn() const { return mState.getPrimitivesDrawn(); }
+
+ // Returns true if any buffer bound to this object is also bound to another target.
+ bool buffersBoundForOtherUseInWebGL() const;
+
+ angle::Result detachBuffer(const Context *context, BufferID bufferID);
+
+ rx::TransformFeedbackImpl *getImplementation() const;
+
+ void onBindingChanged(const Context *context, bool bound);
+
+ private:
+ void bindProgram(const Context *context, Program *program);
+
+ TransformFeedbackState mState;
+ rx::TransformFeedbackImpl *mImplementation;
+};
+
+} // namespace gl
+
+#endif // LIBANGLE_TRANSFORM_FEEDBACK_H_
diff --git a/gfx/angle/checkout/src/libANGLE/Uniform.cpp b/gfx/angle/checkout/src/libANGLE/Uniform.cpp
new file mode 100644
index 0000000000..d41ed5698a
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Uniform.cpp
@@ -0,0 +1,179 @@
+//
+// Copyright 2010 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 "libANGLE/Uniform.h"
+
+#include <cstring>
+
+namespace gl
+{
+
+ActiveVariable::ActiveVariable() {}
+
+ActiveVariable::~ActiveVariable() {}
+
+ActiveVariable::ActiveVariable(const ActiveVariable &rhs) = default;
+ActiveVariable &ActiveVariable::operator=(const ActiveVariable &rhs) = default;
+
+void ActiveVariable::setActive(ShaderType shaderType, bool used)
+{
+ ASSERT(shaderType != ShaderType::InvalidEnum);
+ mActiveUseBits.set(shaderType, used);
+}
+
+void ActiveVariable::unionReferencesWith(const ActiveVariable &other)
+{
+ mActiveUseBits |= other.mActiveUseBits;
+}
+
+ShaderType ActiveVariable::getFirstShaderTypeWhereActive() const
+{
+ return static_cast<ShaderType>(ScanForward(mActiveUseBits.bits()));
+}
+
+GLuint ActiveVariable::activeShaderCount() const
+{
+ return static_cast<GLuint>(mActiveUseBits.count());
+}
+
+LinkedUniform::LinkedUniform()
+ : typeInfo(nullptr),
+ bufferIndex(-1),
+ blockInfo(sh::kDefaultBlockMemberInfo),
+ outerArrayOffset(0)
+{}
+
+LinkedUniform::LinkedUniform(GLenum typeIn,
+ GLenum precisionIn,
+ const std::string &nameIn,
+ const std::vector<unsigned int> &arraySizesIn,
+ const int bindingIn,
+ const int offsetIn,
+ const int locationIn,
+ const int bufferIndexIn,
+ const sh::BlockMemberInfo &blockInfoIn)
+ : typeInfo(&GetUniformTypeInfo(typeIn)),
+ bufferIndex(bufferIndexIn),
+ blockInfo(blockInfoIn),
+ outerArrayOffset(0)
+{
+ type = typeIn;
+ precision = precisionIn;
+ name = nameIn;
+ arraySizes = arraySizesIn;
+ binding = bindingIn;
+ offset = offsetIn;
+ location = locationIn;
+ ASSERT(!isArrayOfArrays());
+ ASSERT(!isArray() || !isStruct());
+}
+
+LinkedUniform::LinkedUniform(const sh::ShaderVariable &uniform)
+ : sh::ShaderVariable(uniform),
+ typeInfo(&GetUniformTypeInfo(type)),
+ bufferIndex(-1),
+ blockInfo(sh::kDefaultBlockMemberInfo)
+{
+ ASSERT(!isArrayOfArrays());
+ ASSERT(!isArray() || !isStruct());
+}
+
+LinkedUniform::LinkedUniform(const LinkedUniform &uniform)
+ : sh::ShaderVariable(uniform),
+ ActiveVariable(uniform),
+ typeInfo(uniform.typeInfo),
+ bufferIndex(uniform.bufferIndex),
+ blockInfo(uniform.blockInfo),
+ outerArraySizes(uniform.outerArraySizes),
+ outerArrayOffset(uniform.outerArrayOffset)
+{}
+
+LinkedUniform &LinkedUniform::operator=(const LinkedUniform &uniform)
+{
+ sh::ShaderVariable::operator=(uniform);
+ ActiveVariable::operator =(uniform);
+ typeInfo = uniform.typeInfo;
+ bufferIndex = uniform.bufferIndex;
+ blockInfo = uniform.blockInfo;
+ outerArraySizes = uniform.outerArraySizes;
+ outerArrayOffset = uniform.outerArrayOffset;
+ return *this;
+}
+
+LinkedUniform::~LinkedUniform() {}
+
+BufferVariable::BufferVariable()
+ : bufferIndex(-1), blockInfo(sh::kDefaultBlockMemberInfo), topLevelArraySize(-1)
+{}
+
+BufferVariable::BufferVariable(GLenum typeIn,
+ GLenum precisionIn,
+ const std::string &nameIn,
+ const std::vector<unsigned int> &arraySizesIn,
+ const int bufferIndexIn,
+ const sh::BlockMemberInfo &blockInfoIn)
+ : bufferIndex(bufferIndexIn), blockInfo(blockInfoIn), topLevelArraySize(-1)
+{
+ type = typeIn;
+ precision = precisionIn;
+ name = nameIn;
+ arraySizes = arraySizesIn;
+}
+
+BufferVariable::~BufferVariable() {}
+
+ShaderVariableBuffer::ShaderVariableBuffer() : binding(0), dataSize(0) {}
+
+ShaderVariableBuffer::ShaderVariableBuffer(const ShaderVariableBuffer &other) = default;
+
+ShaderVariableBuffer::~ShaderVariableBuffer() {}
+
+int ShaderVariableBuffer::numActiveVariables() const
+{
+ return static_cast<int>(memberIndexes.size());
+}
+
+InterfaceBlock::InterfaceBlock() : isArray(false), arrayElement(0) {}
+
+InterfaceBlock::InterfaceBlock(const std::string &nameIn,
+ const std::string &mappedNameIn,
+ bool isArrayIn,
+ unsigned int arrayElementIn,
+ unsigned int firstFieldArraySizeIn,
+ int bindingIn)
+ : name(nameIn),
+ mappedName(mappedNameIn),
+ isArray(isArrayIn),
+ arrayElement(arrayElementIn),
+ firstFieldArraySize(firstFieldArraySizeIn)
+{
+ binding = bindingIn;
+}
+
+std::string InterfaceBlock::nameWithArrayIndex() const
+{
+ std::stringstream fullNameStr;
+ fullNameStr << name;
+ if (isArray)
+ {
+ fullNameStr << "[" << arrayElement << "]";
+ }
+
+ return fullNameStr.str();
+}
+
+std::string InterfaceBlock::mappedNameWithArrayIndex() const
+{
+ std::stringstream fullNameStr;
+ fullNameStr << mappedName;
+ if (isArray)
+ {
+ fullNameStr << "[" << arrayElement << "]";
+ }
+
+ return fullNameStr.str();
+}
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/Uniform.h b/gfx/angle/checkout/src/libANGLE/Uniform.h
new file mode 100644
index 0000000000..5c15906779
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Uniform.h
@@ -0,0 +1,138 @@
+//
+// Copyright 2010 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 LIBANGLE_UNIFORM_H_
+#define LIBANGLE_UNIFORM_H_
+
+#include <string>
+#include <vector>
+
+#include "angle_gl.h"
+#include "common/MemoryBuffer.h"
+#include "common/debug.h"
+#include "common/utilities.h"
+#include "compiler/translator/blocklayout.h"
+#include "libANGLE/angletypes.h"
+
+namespace gl
+{
+struct UniformTypeInfo;
+
+struct ActiveVariable
+{
+ ActiveVariable();
+ ActiveVariable(const ActiveVariable &rhs);
+ virtual ~ActiveVariable();
+
+ ActiveVariable &operator=(const ActiveVariable &rhs);
+
+ ShaderType getFirstShaderTypeWhereActive() const;
+ void setActive(ShaderType shaderType, bool used);
+ void unionReferencesWith(const ActiveVariable &other);
+ bool isActive(ShaderType shaderType) const
+ {
+ ASSERT(shaderType != ShaderType::InvalidEnum);
+ return mActiveUseBits[shaderType];
+ }
+ ShaderBitSet activeShaders() const { return mActiveUseBits; }
+ GLuint activeShaderCount() const;
+
+ private:
+ ShaderBitSet mActiveUseBits;
+};
+
+// Helper struct representing a single shader uniform
+struct LinkedUniform : public sh::ShaderVariable, public ActiveVariable
+{
+ LinkedUniform();
+ LinkedUniform(GLenum type,
+ GLenum precision,
+ const std::string &name,
+ const std::vector<unsigned int> &arraySizes,
+ const int binding,
+ const int offset,
+ const int location,
+ const int bufferIndex,
+ const sh::BlockMemberInfo &blockInfo);
+ LinkedUniform(const sh::ShaderVariable &uniform);
+ LinkedUniform(const LinkedUniform &uniform);
+ LinkedUniform &operator=(const LinkedUniform &uniform);
+ ~LinkedUniform() override;
+
+ bool isSampler() const { return typeInfo->isSampler; }
+ bool isImage() const { return typeInfo->isImageType; }
+ bool isAtomicCounter() const { return IsAtomicCounterType(type); }
+ bool isInDefaultBlock() const { return bufferIndex == -1; }
+ bool isField() const { return name.find('.') != std::string::npos; }
+ size_t getElementSize() const { return typeInfo->externalSize; }
+ size_t getElementComponents() const { return typeInfo->componentCount; }
+
+ const UniformTypeInfo *typeInfo;
+
+ // Identifies the containing buffer backed resource -- interface block or atomic counter buffer.
+ int bufferIndex;
+ sh::BlockMemberInfo blockInfo;
+ std::vector<unsigned int> outerArraySizes;
+ unsigned int outerArrayOffset;
+};
+
+struct BufferVariable : public sh::ShaderVariable, public ActiveVariable
+{
+ BufferVariable();
+ BufferVariable(GLenum type,
+ GLenum precision,
+ const std::string &name,
+ const std::vector<unsigned int> &arraySizes,
+ const int bufferIndex,
+ const sh::BlockMemberInfo &blockInfo);
+ ~BufferVariable() override;
+
+ int bufferIndex;
+ sh::BlockMemberInfo blockInfo;
+
+ int topLevelArraySize;
+};
+
+// Parent struct for atomic counter, uniform block, and shader storage block buffer, which all
+// contain a group of shader variables, and have a GL buffer backed.
+struct ShaderVariableBuffer : public ActiveVariable
+{
+ ShaderVariableBuffer();
+ ShaderVariableBuffer(const ShaderVariableBuffer &other);
+ ~ShaderVariableBuffer() override;
+ int numActiveVariables() const;
+
+ int binding;
+ unsigned int dataSize;
+ std::vector<unsigned int> memberIndexes;
+};
+
+using AtomicCounterBuffer = ShaderVariableBuffer;
+
+// Helper struct representing a single shader interface block
+struct InterfaceBlock : public ShaderVariableBuffer
+{
+ InterfaceBlock();
+ InterfaceBlock(const std::string &nameIn,
+ const std::string &mappedNameIn,
+ bool isArrayIn,
+ unsigned int arrayElementIn,
+ unsigned int firstFieldArraySizeIn,
+ int bindingIn);
+
+ std::string nameWithArrayIndex() const;
+ std::string mappedNameWithArrayIndex() const;
+
+ std::string name;
+ std::string mappedName;
+ bool isArray;
+ unsigned int arrayElement;
+ unsigned int firstFieldArraySize;
+};
+
+} // namespace gl
+
+#endif // LIBANGLE_UNIFORM_H_
diff --git a/gfx/angle/checkout/src/libANGLE/VaryingPacking.cpp b/gfx/angle/checkout/src/libANGLE/VaryingPacking.cpp
new file mode 100644
index 0000000000..7dbb0cc2b8
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/VaryingPacking.cpp
@@ -0,0 +1,1152 @@
+//
+// 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.
+//
+// VaryingPacking:
+// Class which describes a mapping from varyings to registers, according
+// to the spec, or using custom packing algorithms. We also keep a register
+// allocation list for the D3D renderer.
+//
+
+#include "libANGLE/VaryingPacking.h"
+
+#include "common/utilities.h"
+#include "libANGLE/Program.h"
+#include "libANGLE/ProgramExecutable.h"
+#include "libANGLE/Shader.h"
+
+namespace gl
+{
+
+namespace
+{
+
+// true if varying x has a higher priority in packing than y
+bool ComparePackedVarying(const PackedVarying &x, const PackedVarying &y)
+{
+ // If the PackedVarying 'x' or 'y' to be compared is an array element for transform feedback,
+ // this clones an equivalent non-array shader variable 'vx' or 'vy' for actual comparison
+ // instead. For I/O block arrays, the array index is used in the comparison.
+ sh::ShaderVariable vx, vy;
+ const sh::ShaderVariable *px, *py;
+
+ px = &x.varying();
+ py = &y.varying();
+
+ if (x.isTransformFeedbackArrayElement())
+ {
+ vx = *px;
+ vx.arraySizes.clear();
+ px = &vx;
+ }
+
+ if (y.isTransformFeedbackArrayElement())
+ {
+ vy = *py;
+ vy.arraySizes.clear();
+ py = &vy;
+ }
+
+ // Make sure struct fields end up together.
+ if (x.isStructField() != y.isStructField())
+ {
+ return x.isStructField();
+ }
+
+ if (x.isStructField())
+ {
+ ASSERT(y.isStructField());
+
+ if (x.getParentStructName() != y.getParentStructName())
+ {
+ return x.getParentStructName() < y.getParentStructName();
+ }
+ }
+
+ // For I/O block fields, order first by array index:
+ if (!x.isTransformFeedbackArrayElement() && !y.isTransformFeedbackArrayElement())
+ {
+ if (x.arrayIndex != y.arrayIndex)
+ {
+ return x.arrayIndex < y.arrayIndex;
+ }
+ }
+
+ // Then order by field index
+ if (x.fieldIndex != y.fieldIndex)
+ {
+ return x.fieldIndex < y.fieldIndex;
+ }
+
+ // Then order by secondary field index
+ if (x.secondaryFieldIndex != y.secondaryFieldIndex)
+ {
+ return x.secondaryFieldIndex < y.secondaryFieldIndex;
+ }
+
+ // Otherwise order by variable
+ return gl::CompareShaderVar(*px, *py);
+}
+
+bool InterfaceVariablesMatch(const sh::ShaderVariable &front, const sh::ShaderVariable &back)
+{
+ // Matching ruels from 7.4.1 Shader Interface Matching from the GLES 3.2 spec:
+ // - the two variables match in name, type, and qualification; or
+ // - the two variables are declared with the same location qualifier and match in type and
+ // qualification. Note that we use a more permissive check here thanks to front-end validation.
+ if (back.location != -1 && back.location == front.location)
+ {
+ return true;
+ }
+
+ if (front.isShaderIOBlock != back.isShaderIOBlock)
+ {
+ return false;
+ }
+
+ // Compare names, or if shader I/O blocks, block names.
+ const std::string &backName = back.isShaderIOBlock ? back.structOrBlockName : back.name;
+ const std::string &frontName = front.isShaderIOBlock ? front.structOrBlockName : front.name;
+ return backName == frontName;
+}
+
+GLint GetMaxShaderInputVectors(const Caps &caps, ShaderType shaderStage)
+{
+ switch (shaderStage)
+ {
+ case ShaderType::TessControl:
+ return caps.maxTessControlInputComponents / 4;
+ case ShaderType::TessEvaluation:
+ return caps.maxTessEvaluationInputComponents / 4;
+ case ShaderType::Geometry:
+ return caps.maxGeometryInputComponents / 4;
+ case ShaderType::Fragment:
+ return caps.maxFragmentInputComponents / 4;
+ default:
+ return std::numeric_limits<GLint>::max();
+ }
+}
+
+GLint GetMaxShaderOutputVectors(const Caps &caps, ShaderType shaderStage)
+{
+ switch (shaderStage)
+ {
+ case ShaderType::Vertex:
+ return caps.maxVertexOutputComponents / 4;
+ case ShaderType::TessControl:
+ return caps.maxTessControlOutputComponents / 4;
+ case ShaderType::TessEvaluation:
+ return caps.maxTessEvaluationOutputComponents / 4;
+ case ShaderType::Geometry:
+ return caps.maxGeometryOutputComponents / 4;
+ default:
+ return std::numeric_limits<GLint>::max();
+ }
+}
+
+bool ShouldSkipPackedVarying(const sh::ShaderVariable &varying, PackMode packMode)
+{
+ // Don't pack gl_Position. Also don't count gl_PointSize for D3D9.
+ return varying.name == "gl_Position" ||
+ (varying.name == "gl_PointSize" && packMode == PackMode::ANGLE_NON_CONFORMANT_D3D9);
+}
+
+std::vector<unsigned int> StripVaryingArrayDimension(const sh::ShaderVariable *frontVarying,
+ ShaderType frontShaderStage,
+ const sh::ShaderVariable *backVarying,
+ ShaderType backShaderStage,
+ bool isStructField)
+{
+ // "Geometry shader inputs, tessellation control shader inputs and outputs, and tessellation
+ // evaluation inputs all have an additional level of arrayness relative to other shader inputs
+ // and outputs. This outer array level is removed from the type before considering how many
+ // locations the type consumes."
+
+ if (backVarying && backVarying->isArray() && !backVarying->isPatch && !isStructField &&
+ (backShaderStage == ShaderType::Geometry || backShaderStage == ShaderType::TessEvaluation ||
+ backShaderStage == ShaderType::TessControl))
+ {
+ std::vector<unsigned int> arr = backVarying->arraySizes;
+ arr.pop_back();
+ return arr;
+ }
+
+ if (frontVarying && frontVarying->isArray() && !frontVarying->isPatch && !isStructField &&
+ frontShaderStage == ShaderType::TessControl)
+ {
+ std::vector<unsigned int> arr = frontVarying->arraySizes;
+ arr.pop_back();
+ return arr;
+ }
+
+ return frontVarying ? frontVarying->arraySizes : backVarying->arraySizes;
+}
+} // anonymous namespace
+
+// Implementation of VaryingInShaderRef
+VaryingInShaderRef::VaryingInShaderRef(ShaderType stageIn, const sh::ShaderVariable *varyingIn)
+ : varying(varyingIn), stage(stageIn)
+{}
+
+VaryingInShaderRef::~VaryingInShaderRef() = default;
+
+VaryingInShaderRef::VaryingInShaderRef(VaryingInShaderRef &&other)
+ : varying(other.varying),
+ stage(other.stage),
+ parentStructName(std::move(other.parentStructName)),
+ parentStructMappedName(std::move(other.parentStructMappedName))
+{}
+
+VaryingInShaderRef &VaryingInShaderRef::operator=(VaryingInShaderRef &&other)
+{
+ std::swap(varying, other.varying);
+ std::swap(stage, other.stage);
+ std::swap(parentStructName, other.parentStructName);
+ std::swap(parentStructMappedName, other.parentStructMappedName);
+
+ return *this;
+}
+
+// Implementation of PackedVarying
+PackedVarying::PackedVarying(VaryingInShaderRef &&frontVaryingIn,
+ VaryingInShaderRef &&backVaryingIn,
+ sh::InterpolationType interpolationIn)
+ : PackedVarying(std::move(frontVaryingIn),
+ std::move(backVaryingIn),
+ interpolationIn,
+ GL_INVALID_INDEX,
+ 0,
+ 0)
+{}
+
+PackedVarying::PackedVarying(VaryingInShaderRef &&frontVaryingIn,
+ VaryingInShaderRef &&backVaryingIn,
+ sh::InterpolationType interpolationIn,
+ GLuint arrayIndexIn,
+ GLuint fieldIndexIn,
+ GLuint secondaryFieldIndexIn)
+ : frontVarying(std::move(frontVaryingIn)),
+ backVarying(std::move(backVaryingIn)),
+ interpolation(interpolationIn),
+ arrayIndex(arrayIndexIn),
+ isTransformFeedback(false),
+ fieldIndex(fieldIndexIn),
+ secondaryFieldIndex(secondaryFieldIndexIn)
+{}
+
+PackedVarying::~PackedVarying() = default;
+
+PackedVarying::PackedVarying(PackedVarying &&other)
+ : frontVarying(std::move(other.frontVarying)),
+ backVarying(std::move(other.backVarying)),
+ interpolation(other.interpolation),
+ arrayIndex(other.arrayIndex),
+ isTransformFeedback(other.isTransformFeedback),
+ fieldIndex(other.fieldIndex),
+ secondaryFieldIndex(other.secondaryFieldIndex)
+{}
+
+PackedVarying &PackedVarying::operator=(PackedVarying &&other)
+{
+ std::swap(frontVarying, other.frontVarying);
+ std::swap(backVarying, other.backVarying);
+ std::swap(interpolation, other.interpolation);
+ std::swap(arrayIndex, other.arrayIndex);
+ std::swap(isTransformFeedback, other.isTransformFeedback);
+ std::swap(fieldIndex, other.fieldIndex);
+ std::swap(secondaryFieldIndex, other.secondaryFieldIndex);
+
+ return *this;
+}
+
+unsigned int PackedVarying::getBasicTypeElementCount() const
+{
+ // "Geometry shader inputs, tessellation control shader inputs and outputs, and tessellation
+ // evaluation inputs all have an additional level of arrayness relative to other shader inputs
+ // and outputs. This outer array level is removed from the type before considering how many
+ // locations the type consumes."
+ std::vector<unsigned int> arr =
+ StripVaryingArrayDimension(frontVarying.varying, frontVarying.stage, backVarying.varying,
+ backVarying.stage, isStructField());
+ return arr.empty() ? 1u : arr.back();
+}
+
+// Implementation of VaryingPacking
+VaryingPacking::VaryingPacking() = default;
+
+VaryingPacking::~VaryingPacking() = default;
+
+void VaryingPacking::reset()
+{
+ clearRegisterMap();
+ mRegisterList.clear();
+ mPackedVaryings.clear();
+
+ for (std::vector<std::string> &inactiveVaryingMappedNames : mInactiveVaryingMappedNames)
+ {
+ inactiveVaryingMappedNames.clear();
+ }
+
+ for (std::vector<std::string> &activeBuiltIns : mActiveOutputBuiltIns)
+ {
+ activeBuiltIns.clear();
+ }
+}
+
+void VaryingPacking::clearRegisterMap()
+{
+ std::fill(mRegisterMap.begin(), mRegisterMap.end(), Register());
+}
+
+// Packs varyings into generic varying registers, using the algorithm from
+// See [OpenGL ES Shading Language 1.00 rev. 17] appendix A section 7 page 111
+// Also [OpenGL ES Shading Language 3.00 rev. 4] Section 11 page 119
+// Returns false if unsuccessful.
+bool VaryingPacking::packVaryingIntoRegisterMap(PackMode packMode,
+ const PackedVarying &packedVarying)
+{
+ const sh::ShaderVariable &varying = packedVarying.varying();
+
+ // "Non - square matrices of type matCxR consume the same space as a square matrix of type matN
+ // where N is the greater of C and R."
+ // Here we are a bit more conservative and allow packing non-square matrices more tightly.
+ // Make sure we use transposed matrix types to count registers correctly.
+ ASSERT(!varying.isStruct());
+ GLenum transposedType = gl::TransposeMatrixType(varying.type);
+ unsigned int varyingRows = gl::VariableRowCount(transposedType);
+ unsigned int varyingColumns = gl::VariableColumnCount(transposedType);
+
+ // Special pack mode for D3D9. Each varying takes a full register, no sharing.
+ // TODO(jmadill): Implement more sophisticated component packing in D3D9.
+ if (packMode == PackMode::ANGLE_NON_CONFORMANT_D3D9)
+ {
+ varyingColumns = 4;
+ }
+
+ // "Variables of type mat2 occupies 2 complete rows."
+ // For non-WebGL contexts, we allow mat2 to occupy only two columns per row.
+ else if (packMode == PackMode::WEBGL_STRICT && varying.type == GL_FLOAT_MAT2)
+ {
+ varyingColumns = 4;
+ }
+
+ // "Arrays of size N are assumed to take N times the size of the base type"
+ // GLSL ES 3.10 section 4.3.6: Output variables cannot be arrays of arrays or arrays of
+ // structures, so we may use getBasicTypeElementCount().
+ const unsigned int elementCount = packedVarying.getBasicTypeElementCount();
+ varyingRows *= (packedVarying.isTransformFeedbackArrayElement() ? 1 : elementCount);
+
+ unsigned int maxVaryingVectors = static_cast<unsigned int>(mRegisterMap.size());
+
+ // Fail if we are packing a single over-large varying.
+ if (varyingRows > maxVaryingVectors)
+ {
+ return false;
+ }
+
+ // "For 2, 3 and 4 component variables packing is started using the 1st column of the 1st row.
+ // Variables are then allocated to successive rows, aligning them to the 1st column."
+ if (varyingColumns >= 2 && varyingColumns <= 4)
+ {
+ for (unsigned int row = 0; row <= maxVaryingVectors - varyingRows; ++row)
+ {
+ if (isRegisterRangeFree(row, 0, varyingRows, varyingColumns))
+ {
+ insertVaryingIntoRegisterMap(row, 0, varyingColumns, packedVarying);
+ return true;
+ }
+ }
+
+ // "For 2 component variables, when there are no spare rows, the strategy is switched to
+ // using the highest numbered row and the lowest numbered column where the variable will
+ // fit."
+ if (varyingColumns == 2)
+ {
+ for (unsigned int r = maxVaryingVectors - varyingRows + 1; r-- >= 1;)
+ {
+ if (isRegisterRangeFree(r, 2, varyingRows, 2))
+ {
+ insertVaryingIntoRegisterMap(r, 2, varyingColumns, packedVarying);
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ // "1 component variables have their own packing rule. They are packed in order of size, largest
+ // first. Each variable is placed in the column that leaves the least amount of space in the
+ // column and aligned to the lowest available rows within that column."
+ ASSERT(varyingColumns == 1);
+ unsigned int contiguousSpace[4] = {0};
+ unsigned int bestContiguousSpace[4] = {0};
+ unsigned int totalSpace[4] = {0};
+
+ for (unsigned int row = 0; row < maxVaryingVectors; ++row)
+ {
+ for (unsigned int column = 0; column < 4; ++column)
+ {
+ if (mRegisterMap[row][column])
+ {
+ contiguousSpace[column] = 0;
+ }
+ else
+ {
+ contiguousSpace[column]++;
+ totalSpace[column]++;
+
+ if (contiguousSpace[column] > bestContiguousSpace[column])
+ {
+ bestContiguousSpace[column] = contiguousSpace[column];
+ }
+ }
+ }
+ }
+
+ unsigned int bestColumn = 0;
+ for (unsigned int column = 1; column < 4; ++column)
+ {
+ if (bestContiguousSpace[column] >= varyingRows &&
+ (bestContiguousSpace[bestColumn] < varyingRows ||
+ totalSpace[column] < totalSpace[bestColumn]))
+ {
+ bestColumn = column;
+ }
+ }
+
+ if (bestContiguousSpace[bestColumn] >= varyingRows)
+ {
+ for (unsigned int row = 0; row < maxVaryingVectors; row++)
+ {
+ if (isRegisterRangeFree(row, bestColumn, varyingRows, 1))
+ {
+ for (unsigned int arrayIndex = 0; arrayIndex < varyingRows; ++arrayIndex)
+ {
+ // If varyingRows > 1, it must be an array.
+ PackedVaryingRegister registerInfo;
+ registerInfo.packedVarying = &packedVarying;
+ registerInfo.registerRow = row + arrayIndex;
+ registerInfo.registerColumn = bestColumn;
+ registerInfo.varyingArrayIndex =
+ (packedVarying.isTransformFeedbackArrayElement() ? packedVarying.arrayIndex
+ : arrayIndex);
+ registerInfo.varyingRowIndex = 0;
+ // Do not record register info for builtins.
+ // TODO(jmadill): Clean this up.
+ if (!varying.isBuiltIn())
+ {
+ mRegisterList.push_back(registerInfo);
+ }
+ mRegisterMap[row + arrayIndex][bestColumn] = true;
+ }
+ break;
+ }
+ }
+ return true;
+ }
+
+ return false;
+}
+
+bool VaryingPacking::isRegisterRangeFree(unsigned int registerRow,
+ unsigned int registerColumn,
+ unsigned int varyingRows,
+ unsigned int varyingColumns) const
+{
+ for (unsigned int row = 0; row < varyingRows; ++row)
+ {
+ ASSERT(registerRow + row < mRegisterMap.size());
+ for (unsigned int column = 0; column < varyingColumns; ++column)
+ {
+ ASSERT(registerColumn + column < 4);
+ if (mRegisterMap[registerRow + row][registerColumn + column])
+ {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+void VaryingPacking::insertVaryingIntoRegisterMap(unsigned int registerRow,
+ unsigned int registerColumn,
+ unsigned int varyingColumns,
+ const PackedVarying &packedVarying)
+{
+ unsigned int varyingRows = 0;
+
+ const sh::ShaderVariable &varying = packedVarying.varying();
+ ASSERT(!varying.isStruct());
+ GLenum transposedType = gl::TransposeMatrixType(varying.type);
+ varyingRows = gl::VariableRowCount(transposedType);
+
+ PackedVaryingRegister registerInfo;
+ registerInfo.packedVarying = &packedVarying;
+ registerInfo.registerColumn = registerColumn;
+
+ // GLSL ES 3.10 section 4.3.6: Output variables cannot be arrays of arrays or arrays of
+ // structures, so we may use getBasicTypeElementCount().
+ const unsigned int arrayElementCount = packedVarying.getBasicTypeElementCount();
+ for (unsigned int arrayElement = 0; arrayElement < arrayElementCount; ++arrayElement)
+ {
+ if (packedVarying.isTransformFeedbackArrayElement() &&
+ arrayElement != packedVarying.arrayIndex)
+ {
+ continue;
+ }
+ for (unsigned int varyingRow = 0; varyingRow < varyingRows; ++varyingRow)
+ {
+ registerInfo.registerRow = registerRow + (arrayElement * varyingRows) + varyingRow;
+ registerInfo.varyingRowIndex = varyingRow;
+ registerInfo.varyingArrayIndex = arrayElement;
+ // Do not record register info for builtins.
+ // TODO(jmadill): Clean this up.
+ if (!varying.isBuiltIn())
+ {
+ mRegisterList.push_back(registerInfo);
+ }
+
+ for (unsigned int columnIndex = 0; columnIndex < varyingColumns; ++columnIndex)
+ {
+ mRegisterMap[registerInfo.registerRow][registerColumn + columnIndex] = true;
+ }
+ }
+ }
+}
+
+void VaryingPacking::collectUserVarying(const ProgramVaryingRef &ref,
+ VaryingUniqueFullNames *uniqueFullNames)
+{
+ const sh::ShaderVariable *input = ref.frontShader;
+ const sh::ShaderVariable *output = ref.backShader;
+
+ // Will get the vertex shader interpolation by default.
+ sh::InterpolationType interpolation = input ? input->interpolation : output->interpolation;
+
+ VaryingInShaderRef frontVarying(ref.frontShaderStage, input);
+ VaryingInShaderRef backVarying(ref.backShaderStage, output);
+
+ mPackedVaryings.emplace_back(std::move(frontVarying), std::move(backVarying), interpolation);
+ if (input && !input->isBuiltIn())
+ {
+ (*uniqueFullNames)[ref.frontShaderStage].insert(
+ mPackedVaryings.back().fullName(ref.frontShaderStage));
+ }
+ if (output && !output->isBuiltIn())
+ {
+ (*uniqueFullNames)[ref.backShaderStage].insert(
+ mPackedVaryings.back().fullName(ref.backShaderStage));
+ }
+}
+
+void VaryingPacking::collectUserVaryingField(const ProgramVaryingRef &ref,
+ GLuint arrayIndex,
+ GLuint fieldIndex,
+ GLuint secondaryFieldIndex,
+ VaryingUniqueFullNames *uniqueFullNames)
+{
+ const sh::ShaderVariable *input = ref.frontShader;
+ const sh::ShaderVariable *output = ref.backShader;
+
+ // Will get the vertex shader interpolation by default.
+ sh::InterpolationType interpolation = input ? input->interpolation : output->interpolation;
+
+ const sh::ShaderVariable *frontField = input ? &input->fields[fieldIndex] : nullptr;
+ const sh::ShaderVariable *backField = output ? &output->fields[fieldIndex] : nullptr;
+
+ if (secondaryFieldIndex != GL_INVALID_INDEX)
+ {
+ frontField = frontField ? &frontField->fields[secondaryFieldIndex] : nullptr;
+ backField = backField ? &backField->fields[secondaryFieldIndex] : nullptr;
+ }
+
+ VaryingInShaderRef frontVarying(ref.frontShaderStage, frontField);
+ VaryingInShaderRef backVarying(ref.backShaderStage, backField);
+
+ if (input)
+ {
+ if (frontField->isShaderIOBlock)
+ {
+ frontVarying.parentStructName = input->structOrBlockName;
+ frontVarying.parentStructMappedName = input->mappedStructOrBlockName;
+ }
+ else
+ {
+ ASSERT(!frontField->isStruct() && !frontField->isArray());
+ frontVarying.parentStructName = input->name;
+ frontVarying.parentStructMappedName = input->mappedName;
+ }
+ }
+ if (output)
+ {
+ if (backField->isShaderIOBlock)
+ {
+ backVarying.parentStructName = output->structOrBlockName;
+ backVarying.parentStructMappedName = output->mappedStructOrBlockName;
+ }
+ else
+ {
+ ASSERT(!backField->isStruct() && !backField->isArray());
+ backVarying.parentStructName = output->name;
+ backVarying.parentStructMappedName = output->mappedName;
+ }
+ }
+
+ mPackedVaryings.emplace_back(std::move(frontVarying), std::move(backVarying), interpolation,
+ arrayIndex, fieldIndex,
+ secondaryFieldIndex == GL_INVALID_INDEX ? 0 : secondaryFieldIndex);
+
+ if (input)
+ {
+ (*uniqueFullNames)[ref.frontShaderStage].insert(
+ mPackedVaryings.back().fullName(ref.frontShaderStage));
+ }
+ if (output)
+ {
+ (*uniqueFullNames)[ref.backShaderStage].insert(
+ mPackedVaryings.back().fullName(ref.backShaderStage));
+ }
+}
+
+void VaryingPacking::collectUserVaryingTF(const ProgramVaryingRef &ref, size_t subscript)
+{
+ const sh::ShaderVariable *input = ref.frontShader;
+
+ VaryingInShaderRef frontVarying(ref.frontShaderStage, input);
+ VaryingInShaderRef backVarying(ref.backShaderStage, nullptr);
+
+ mPackedVaryings.emplace_back(std::move(frontVarying), std::move(backVarying),
+ input->interpolation);
+ mPackedVaryings.back().arrayIndex = static_cast<GLuint>(subscript);
+ mPackedVaryings.back().isTransformFeedback = true;
+}
+
+void VaryingPacking::collectUserVaryingFieldTF(const ProgramVaryingRef &ref,
+ const sh::ShaderVariable &field,
+ GLuint fieldIndex,
+ GLuint secondaryFieldIndex)
+{
+ const sh::ShaderVariable *input = ref.frontShader;
+
+ const sh::ShaderVariable *frontField = &field;
+ if (secondaryFieldIndex != GL_INVALID_INDEX)
+ {
+ frontField = &frontField->fields[secondaryFieldIndex];
+ }
+
+ VaryingInShaderRef frontVarying(ref.frontShaderStage, frontField);
+ VaryingInShaderRef backVarying(ref.backShaderStage, nullptr);
+
+ if (frontField->isShaderIOBlock)
+ {
+ frontVarying.parentStructName = input->structOrBlockName;
+ frontVarying.parentStructMappedName = input->mappedStructOrBlockName;
+ }
+ else
+ {
+ ASSERT(!frontField->isStruct() && !frontField->isArray());
+ frontVarying.parentStructName = input->name;
+ frontVarying.parentStructMappedName = input->mappedName;
+ }
+
+ mPackedVaryings.emplace_back(std::move(frontVarying), std::move(backVarying),
+ input->interpolation, GL_INVALID_INDEX, fieldIndex,
+ secondaryFieldIndex == GL_INVALID_INDEX ? 0 : secondaryFieldIndex);
+}
+
+void VaryingPacking::collectVarying(const sh::ShaderVariable &varying,
+ const ProgramVaryingRef &ref,
+ PackMode packMode,
+ VaryingUniqueFullNames *uniqueFullNames)
+{
+ const sh::ShaderVariable *input = ref.frontShader;
+ const sh::ShaderVariable *output = ref.backShader;
+
+ if (varying.isStruct())
+ {
+ std::vector<unsigned int> arraySizes = StripVaryingArrayDimension(
+ ref.frontShader, ref.frontShaderStage, ref.backShader, ref.backShaderStage, false);
+ const bool isArray = !arraySizes.empty();
+ const GLuint arraySize = isArray ? arraySizes[0] : 1;
+
+ for (GLuint arrayIndex = 0; arrayIndex < arraySize; ++arrayIndex)
+ {
+ const GLuint effectiveArrayIndex = isArray ? arrayIndex : GL_INVALID_INDEX;
+ for (GLuint fieldIndex = 0; fieldIndex < varying.fields.size(); ++fieldIndex)
+ {
+ const sh::ShaderVariable &fieldVarying = varying.fields[fieldIndex];
+ if (ShouldSkipPackedVarying(fieldVarying, packMode))
+ {
+ continue;
+ }
+
+ if (fieldVarying.isStruct())
+ {
+ if (fieldVarying.isArray())
+ {
+ unsigned int structFieldArraySize = fieldVarying.arraySizes[0];
+ for (unsigned int fieldArrayIndex = 0;
+ fieldArrayIndex < structFieldArraySize; ++fieldArrayIndex)
+ {
+ for (GLuint nestedIndex = 0; nestedIndex < fieldVarying.fields.size();
+ nestedIndex++)
+ {
+ collectUserVaryingField(ref, effectiveArrayIndex, fieldIndex,
+ nestedIndex, uniqueFullNames);
+ }
+ }
+ }
+ else
+ {
+ for (GLuint nestedIndex = 0; nestedIndex < fieldVarying.fields.size();
+ nestedIndex++)
+ {
+ collectUserVaryingField(ref, effectiveArrayIndex, fieldIndex,
+ nestedIndex, uniqueFullNames);
+ }
+ }
+ }
+ else
+ {
+ collectUserVaryingField(ref, effectiveArrayIndex, fieldIndex, GL_INVALID_INDEX,
+ uniqueFullNames);
+ }
+ }
+ }
+ if (input)
+ {
+ (*uniqueFullNames)[ref.frontShaderStage].insert(input->name);
+ if (input->isShaderIOBlock)
+ {
+ (*uniqueFullNames)[ref.frontShaderStage].insert(input->structOrBlockName);
+ }
+ }
+ if (output)
+ {
+ (*uniqueFullNames)[ref.backShaderStage].insert(output->name);
+ }
+ }
+ else
+ {
+ collectUserVarying(ref, uniqueFullNames);
+ }
+}
+
+void VaryingPacking::collectTFVarying(const std::string &tfVarying,
+ const ProgramVaryingRef &ref,
+ VaryingUniqueFullNames *uniqueFullNames)
+{
+ const sh::ShaderVariable *input = ref.frontShader;
+
+ std::vector<unsigned int> subscripts;
+ std::string baseName = ParseResourceName(tfVarying, &subscripts);
+
+ // Already packed as active varying.
+ if ((*uniqueFullNames)[ref.frontShaderStage].count(tfVarying) > 0 ||
+ (*uniqueFullNames)[ref.frontShaderStage].count(baseName) > 0 ||
+ (input->isShaderIOBlock &&
+ (*uniqueFullNames)[ref.frontShaderStage].count(input->structOrBlockName) > 0))
+ {
+ return;
+ }
+
+ if (input->isStruct())
+ {
+ GLuint fieldIndex = 0;
+ const sh::ShaderVariable *field = input->findField(tfVarying, &fieldIndex);
+ if (field != nullptr)
+ {
+ ASSERT(input->isShaderIOBlock || (!field->isStruct() && !field->isArray()));
+
+ // If it's an I/O block whose member is being captured, pack every member of the
+ // block. Currently, we pack either all or none of an I/O block.
+ if (input->isShaderIOBlock)
+ {
+ for (fieldIndex = 0; fieldIndex < input->fields.size(); ++fieldIndex)
+ {
+ if (input->fields[fieldIndex].isStruct())
+ {
+
+ for (GLuint nestedIndex = 0;
+ nestedIndex < input->fields[fieldIndex].fields.size(); nestedIndex++)
+ {
+ collectUserVaryingFieldTF(ref, input->fields[fieldIndex], fieldIndex,
+ nestedIndex);
+ }
+ }
+ else
+ {
+ collectUserVaryingFieldTF(ref, input->fields[fieldIndex], fieldIndex,
+ GL_INVALID_INDEX);
+ }
+ }
+
+ (*uniqueFullNames)[ref.frontShaderStage].insert(input->structOrBlockName);
+ }
+ else
+ {
+ collectUserVaryingFieldTF(ref, *field, fieldIndex, GL_INVALID_INDEX);
+ }
+ (*uniqueFullNames)[ref.frontShaderStage].insert(tfVarying);
+ (*uniqueFullNames)[ref.frontShaderStage].insert(input->name);
+ }
+ }
+ // Array as a whole and array element conflict has already been checked in
+ // linkValidateTransformFeedback.
+ else if (baseName == input->name)
+ {
+ size_t subscript = GL_INVALID_INDEX;
+ if (!subscripts.empty())
+ {
+ subscript = subscripts.back();
+ }
+
+ // only pack varyings that are not builtins.
+ if (tfVarying.compare(0, 3, "gl_") != 0)
+ {
+ collectUserVaryingTF(ref, subscript);
+ (*uniqueFullNames)[ref.frontShaderStage].insert(tfVarying);
+ }
+ }
+}
+
+bool VaryingPacking::collectAndPackUserVaryings(gl::InfoLog &infoLog,
+ GLint maxVaryingVectors,
+ PackMode packMode,
+ ShaderType frontShaderStage,
+ ShaderType backShaderStage,
+ const ProgramMergedVaryings &mergedVaryings,
+ const std::vector<std::string> &tfVaryings,
+ const bool isSeparableProgram)
+{
+ VaryingUniqueFullNames uniqueFullNames;
+
+ reset();
+
+ for (const ProgramVaryingRef &ref : mergedVaryings)
+ {
+ const sh::ShaderVariable *input = ref.frontShader;
+ const sh::ShaderVariable *output = ref.backShader;
+
+ if ((input && ref.frontShaderStage != frontShaderStage) ||
+ (output && ref.backShaderStage != backShaderStage))
+ {
+ continue;
+ }
+
+ const bool isActiveBuiltInInput = input && input->isBuiltIn() && input->active;
+ const bool isActiveBuiltInOutput = output && output->isBuiltIn() && output->active;
+
+ // Keep track of output builtins that are used by the shader, such as gl_Position,
+ // gl_PointSize etc.
+ if (isActiveBuiltInInput)
+ {
+ mActiveOutputBuiltIns[ref.frontShaderStage].push_back(input->name);
+ // Keep track of members of builtins, such as gl_out[].gl_Position, too.
+ for (sh::ShaderVariable field : input->fields)
+ {
+ mActiveOutputBuiltIns[ref.frontShaderStage].push_back(field.name);
+ }
+ }
+
+ // Only pack statically used varyings that have a matched input or output, plus special
+ // builtins. Note that we pack all statically used user-defined varyings even if they are
+ // not active. GLES specs are a bit vague on whether it's allowed to only pack active
+ // varyings, though GLES 3.1 spec section 11.1.2.1 says that "device-dependent
+ // optimizations" may be used to make vertex shader outputs fit.
+ //
+ // When separable programs are linked, varyings at the separable program's boundary are
+ // treated as active. See section 7.4.1 in
+ // https://www.khronos.org/registry/OpenGL/specs/es/3.2/es_spec_3.2.pdf
+ bool matchedInputOutputStaticUse = (input && output && output->staticUse);
+ bool activeBuiltIn = (isActiveBuiltInInput || isActiveBuiltInOutput);
+
+ // Output variable in TCS can be read as input in another invocation by barrier.
+ // See section 11.2.1.2.4 Tessellation Control Shader Execution Order in OpenGL ES 3.2.
+ bool staticUseInTCS =
+ (input && input->staticUse && ref.frontShaderStage == ShaderType::TessControl);
+
+ // Separable program requirements
+ bool separableActiveInput = (input && (input->active || !output));
+ bool separableActiveOutput = (output && (output->active || !input));
+ bool separableActiveVarying =
+ (isSeparableProgram && (separableActiveInput || separableActiveOutput));
+
+ if (matchedInputOutputStaticUse || activeBuiltIn || separableActiveVarying ||
+ staticUseInTCS)
+ {
+ const sh::ShaderVariable *varying = output ? output : input;
+
+ if (!ShouldSkipPackedVarying(*varying, packMode))
+ {
+ collectVarying(*varying, ref, packMode, &uniqueFullNames);
+ continue;
+ }
+ }
+
+ // If the varying is not used in the input, we know it is inactive, unless it's a separable
+ // program, in which case the input shader may not exist in this program.
+ if (!input && !isSeparableProgram)
+ {
+ if (!output->isBuiltIn())
+ {
+ mInactiveVaryingMappedNames[ref.backShaderStage].push_back(output->mappedName);
+ if (output->isShaderIOBlock)
+ {
+ mInactiveVaryingMappedNames[ref.backShaderStage].push_back(
+ output->mappedStructOrBlockName);
+ }
+ }
+ continue;
+ }
+
+ // Keep Transform FB varyings in the merged list always.
+ for (const std::string &tfVarying : tfVaryings)
+ {
+ collectTFVarying(tfVarying, ref, &uniqueFullNames);
+ }
+
+ if (input && !input->isBuiltIn() &&
+ uniqueFullNames[ref.frontShaderStage].count(input->name) == 0)
+ {
+ mInactiveVaryingMappedNames[ref.frontShaderStage].push_back(input->mappedName);
+ if (input->isShaderIOBlock)
+ {
+ mInactiveVaryingMappedNames[ref.frontShaderStage].push_back(
+ input->mappedStructOrBlockName);
+ }
+ }
+ if (output && !output->isBuiltIn() &&
+ uniqueFullNames[ref.backShaderStage].count(output->name) == 0)
+ {
+ mInactiveVaryingMappedNames[ref.backShaderStage].push_back(output->mappedName);
+ if (output->isShaderIOBlock)
+ {
+ mInactiveVaryingMappedNames[ref.backShaderStage].push_back(
+ output->mappedStructOrBlockName);
+ }
+ }
+ }
+
+ std::sort(mPackedVaryings.begin(), mPackedVaryings.end(), ComparePackedVarying);
+
+ return packUserVaryings(infoLog, maxVaryingVectors, packMode, mPackedVaryings);
+}
+
+// See comment on packVarying.
+bool VaryingPacking::packUserVaryings(gl::InfoLog &infoLog,
+ GLint maxVaryingVectors,
+ PackMode packMode,
+ const std::vector<PackedVarying> &packedVaryings)
+{
+ clearRegisterMap();
+ mRegisterMap.resize(maxVaryingVectors);
+
+ // "Variables are packed into the registers one at a time so that they each occupy a contiguous
+ // subrectangle. No splitting of variables is permitted."
+ for (const PackedVarying &packedVarying : packedVaryings)
+ {
+ if (!packVaryingIntoRegisterMap(packMode, packedVarying))
+ {
+ ShaderType eitherStage = packedVarying.frontVarying.varying
+ ? packedVarying.frontVarying.stage
+ : packedVarying.backVarying.stage;
+ infoLog << "Could not pack varying " << packedVarying.fullName(eitherStage);
+
+ // TODO(jmadill): Implement more sophisticated component packing in D3D9.
+ if (packMode == PackMode::ANGLE_NON_CONFORMANT_D3D9)
+ {
+ infoLog << "Note: Additional non-conformant packing restrictions are enforced on "
+ "D3D9.";
+ }
+
+ return false;
+ }
+ }
+
+ // Sort the packed register list
+ std::sort(mRegisterList.begin(), mRegisterList.end());
+
+ return true;
+}
+
+// ProgramVaryingPacking implementation.
+ProgramVaryingPacking::ProgramVaryingPacking() = default;
+
+ProgramVaryingPacking::~ProgramVaryingPacking() = default;
+
+const VaryingPacking &ProgramVaryingPacking::getInputPacking(ShaderType backShaderStage) const
+{
+ ShaderType frontShaderStage = mBackToFrontStageMap[backShaderStage];
+
+ // If there's a missing shader stage, return the compute shader packing which is always empty.
+ if (frontShaderStage == ShaderType::InvalidEnum)
+ {
+ ASSERT(mVaryingPackings[ShaderType::Compute].getMaxSemanticIndex() == 0);
+ return mVaryingPackings[ShaderType::Compute];
+ }
+
+ return mVaryingPackings[frontShaderStage];
+}
+
+const VaryingPacking &ProgramVaryingPacking::getOutputPacking(ShaderType frontShaderStage) const
+{
+ return mVaryingPackings[frontShaderStage];
+}
+
+bool ProgramVaryingPacking::collectAndPackUserVaryings(InfoLog &infoLog,
+ const Caps &caps,
+ PackMode packMode,
+ const ShaderBitSet &activeShadersMask,
+ const ProgramMergedVaryings &mergedVaryings,
+ const std::vector<std::string> &tfVaryings,
+ bool isSeparableProgram)
+{
+ mBackToFrontStageMap.fill(ShaderType::InvalidEnum);
+
+ ShaderBitSet activeShaders = activeShadersMask;
+
+ ASSERT(activeShaders.any());
+ ShaderType frontShaderStage = activeShaders.first();
+ activeShaders[frontShaderStage] = false;
+
+ // Special case for start-after-vertex.
+ if (frontShaderStage != ShaderType::Vertex)
+ {
+ ShaderType emulatedFrontShaderStage = ShaderType::Vertex;
+ ShaderType backShaderStage = frontShaderStage;
+
+ if (!mVaryingPackings[emulatedFrontShaderStage].collectAndPackUserVaryings(
+ infoLog, GetMaxShaderInputVectors(caps, backShaderStage), packMode,
+ ShaderType::InvalidEnum, backShaderStage, mergedVaryings, tfVaryings,
+ isSeparableProgram))
+ {
+ return false;
+ }
+ mBackToFrontStageMap[backShaderStage] = emulatedFrontShaderStage;
+ }
+
+ // Process input/output shader pairs.
+ for (ShaderType backShaderStage : activeShaders)
+ {
+ GLint maxVaryingVectors;
+ if (frontShaderStage == ShaderType::Vertex && backShaderStage == ShaderType::Fragment)
+ {
+ maxVaryingVectors = caps.maxVaryingVectors;
+ }
+ else
+ {
+ GLint outputVaryingsMax = GetMaxShaderOutputVectors(caps, frontShaderStage);
+ GLint inputVaryingsMax = GetMaxShaderInputVectors(caps, backShaderStage);
+ maxVaryingVectors = std::min(inputVaryingsMax, outputVaryingsMax);
+ }
+
+ ASSERT(maxVaryingVectors > 0 && maxVaryingVectors < std::numeric_limits<GLint>::max());
+
+ if (!mVaryingPackings[frontShaderStage].collectAndPackUserVaryings(
+ infoLog, maxVaryingVectors, packMode, frontShaderStage, backShaderStage,
+ mergedVaryings, tfVaryings, isSeparableProgram))
+ {
+ return false;
+ }
+
+ mBackToFrontStageMap[backShaderStage] = frontShaderStage;
+ frontShaderStage = backShaderStage;
+ }
+
+ // Special case for stop-before-fragment.
+ if (frontShaderStage != ShaderType::Fragment)
+ {
+ if (!mVaryingPackings[frontShaderStage].collectAndPackUserVaryings(
+ infoLog, GetMaxShaderOutputVectors(caps, frontShaderStage), packMode,
+ frontShaderStage, ShaderType::InvalidEnum, mergedVaryings, tfVaryings,
+ isSeparableProgram))
+ {
+ return false;
+ }
+
+ ShaderType emulatedBackShaderStage = ShaderType::Fragment;
+ mBackToFrontStageMap[emulatedBackShaderStage] = frontShaderStage;
+ }
+
+ return true;
+}
+
+ProgramMergedVaryings GetMergedVaryingsFromLinkingVariables(
+ const LinkingVariables &linkingVariables)
+{
+ ShaderType frontShaderType = ShaderType::InvalidEnum;
+ ProgramMergedVaryings merged;
+
+ for (ShaderType backShaderType : kAllGraphicsShaderTypes)
+ {
+ if (!linkingVariables.isShaderStageUsedBitset[backShaderType])
+ {
+ continue;
+ }
+ const std::vector<sh::ShaderVariable> &backShaderOutputVaryings =
+ linkingVariables.outputVaryings[backShaderType];
+ const std::vector<sh::ShaderVariable> &backShaderInputVaryings =
+ linkingVariables.inputVaryings[backShaderType];
+
+ // Add outputs. These are always unmatched since we walk shader stages sequentially.
+ for (const sh::ShaderVariable &frontVarying : backShaderOutputVaryings)
+ {
+ ProgramVaryingRef ref;
+ ref.frontShader = &frontVarying;
+ ref.frontShaderStage = backShaderType;
+ merged.push_back(ref);
+ }
+
+ if (frontShaderType == ShaderType::InvalidEnum)
+ {
+ // If this is our first shader stage, and not a VS, we might have unmatched inputs.
+ for (const sh::ShaderVariable &backVarying : backShaderInputVaryings)
+ {
+ ProgramVaryingRef ref;
+ ref.backShader = &backVarying;
+ ref.backShaderStage = backShaderType;
+ merged.push_back(ref);
+ }
+ }
+ else
+ {
+ // Match inputs with the prior shader stage outputs.
+ for (const sh::ShaderVariable &backVarying : backShaderInputVaryings)
+ {
+ bool found = false;
+ for (ProgramVaryingRef &ref : merged)
+ {
+ if (ref.frontShader && ref.frontShaderStage == frontShaderType &&
+ InterfaceVariablesMatch(*ref.frontShader, backVarying))
+ {
+ ASSERT(ref.backShader == nullptr);
+
+ ref.backShader = &backVarying;
+ ref.backShaderStage = backShaderType;
+ found = true;
+ break;
+ }
+ }
+
+ // Some outputs are never matched, e.g. some builtin variables.
+ if (!found)
+ {
+ ProgramVaryingRef ref;
+ ref.backShader = &backVarying;
+ ref.backShaderStage = backShaderType;
+ merged.push_back(ref);
+ }
+ }
+ }
+
+ // Save the current back shader to use as the next front shader.
+ frontShaderType = backShaderType;
+ }
+
+ return merged;
+}
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/VaryingPacking.h b/gfx/angle/checkout/src/libANGLE/VaryingPacking.h
new file mode 100644
index 0000000000..3edb9326be
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/VaryingPacking.h
@@ -0,0 +1,329 @@
+//
+// 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.
+//
+// VaryingPacking:
+// Class which describes a mapping from varyings to registers, according
+// to the spec, or using custom packing algorithms. We also keep a register
+// allocation list for the D3D renderer.
+//
+
+#ifndef LIBANGLE_VARYINGPACKING_H_
+#define LIBANGLE_VARYINGPACKING_H_
+
+#include <GLSLANG/ShaderVars.h>
+
+#include "angle_gl.h"
+#include "common/angleutils.h"
+#include "libANGLE/angletypes.h"
+
+#include <map>
+
+namespace gl
+{
+class InfoLog;
+class ProgramExecutable;
+struct Caps;
+struct LinkingVariables;
+struct ProgramVaryingRef;
+
+using ProgramMergedVaryings = std::vector<ProgramVaryingRef>;
+
+// A varying can have different names between stages if matched by the location layout qualifier.
+// Additionally, same name varyings could still be of two identical struct types with different
+// names. This struct contains information on the varying in one of the two stages. PackedVarying
+// will thus contain two copies of this along with common information, such as interpolation or
+// field index.
+struct VaryingInShaderRef : angle::NonCopyable
+{
+ VaryingInShaderRef(ShaderType stageIn, const sh::ShaderVariable *varyingIn);
+ VaryingInShaderRef(VaryingInShaderRef &&other);
+ ~VaryingInShaderRef();
+
+ VaryingInShaderRef &operator=(VaryingInShaderRef &&other);
+
+ const sh::ShaderVariable *varying;
+
+ ShaderType stage;
+
+ // Struct name
+ std::string parentStructName;
+ std::string parentStructMappedName;
+};
+
+struct PackedVarying : angle::NonCopyable
+{
+ // Throughout this file, the "front" stage refers to the stage that outputs the varying, and the
+ // "back" stage refers to the stage that takes the varying as input. Note that this struct
+ // contains linked varyings, which means both front and back stage varyings are valid, except
+ // for the following which may have only one valid stage.
+ //
+ // - transform-feedback-captured varyings
+ // - builtins
+ // - separable program stages,
+ //
+ PackedVarying(VaryingInShaderRef &&frontVaryingIn,
+ VaryingInShaderRef &&backVaryingIn,
+ sh::InterpolationType interpolationIn);
+ PackedVarying(VaryingInShaderRef &&frontVaryingIn,
+ VaryingInShaderRef &&backVaryingIn,
+ sh::InterpolationType interpolationIn,
+ GLuint arrayIndexIn,
+ GLuint fieldIndexIn,
+ GLuint secondaryFieldIndexIn);
+ PackedVarying(PackedVarying &&other);
+ ~PackedVarying();
+
+ PackedVarying &operator=(PackedVarying &&other);
+
+ bool isStructField() const
+ {
+ return frontVarying.varying ? !frontVarying.parentStructName.empty()
+ : !backVarying.parentStructName.empty();
+ }
+
+ bool isTransformFeedbackArrayElement() const
+ {
+ return isTransformFeedback && arrayIndex != GL_INVALID_INDEX;
+ }
+
+ // Return either front or back varying, whichever is available. Only used when the name of the
+ // varying is not important, but only the type is interesting.
+ const sh::ShaderVariable &varying() const
+ {
+ return frontVarying.varying ? *frontVarying.varying : *backVarying.varying;
+ }
+
+ const std::string &getParentStructName() const
+ {
+ ASSERT(isStructField());
+ return frontVarying.varying ? frontVarying.parentStructName : backVarying.parentStructName;
+ }
+
+ std::string fullName(ShaderType stage) const
+ {
+ ASSERT(stage == frontVarying.stage || stage == backVarying.stage);
+ const VaryingInShaderRef &varying =
+ stage == frontVarying.stage ? frontVarying : backVarying;
+
+ std::stringstream fullNameStr;
+ if (isStructField())
+ {
+ fullNameStr << varying.parentStructName << ".";
+ }
+
+ fullNameStr << varying.varying->name;
+ if (arrayIndex != GL_INVALID_INDEX)
+ {
+ fullNameStr << "[" << arrayIndex << "]";
+ }
+ return fullNameStr.str();
+ }
+
+ // Transform feedback varyings can be only referenced in the VS.
+ bool vertexOnly() const
+ {
+ return frontVarying.stage == ShaderType::Vertex && backVarying.varying == nullptr;
+ }
+
+ // Special handling for GS/TS array inputs.
+ unsigned int getBasicTypeElementCount() const;
+
+ VaryingInShaderRef frontVarying;
+ VaryingInShaderRef backVarying;
+
+ // Cached so we can store sh::ShaderVariable to point to varying fields.
+ sh::InterpolationType interpolation;
+
+ // Used by varyings that are captured with transform feedback, xor arrays of shader I/O blocks,
+ // distinguished by isTransformFeedback;
+ GLuint arrayIndex;
+ bool isTransformFeedback;
+
+ // Field index in the struct. In Vulkan, this is used to assign a
+ // struct-typed varying location to the location of its first field.
+ GLuint fieldIndex;
+ GLuint secondaryFieldIndex;
+};
+
+struct PackedVaryingRegister final
+{
+ PackedVaryingRegister()
+ : packedVarying(nullptr),
+ varyingArrayIndex(0),
+ varyingRowIndex(0),
+ registerRow(0),
+ registerColumn(0)
+ {}
+
+ PackedVaryingRegister(const PackedVaryingRegister &) = default;
+ PackedVaryingRegister &operator=(const PackedVaryingRegister &) = default;
+
+ bool operator<(const PackedVaryingRegister &other) const
+ {
+ return sortOrder() < other.sortOrder();
+ }
+
+ unsigned int sortOrder() const
+ {
+ // TODO(jmadill): Handle interpolation types
+ return registerRow * 4 + registerColumn;
+ }
+
+ std::string tfVaryingName() const
+ {
+ return packedVarying->fullName(packedVarying->frontVarying.stage);
+ }
+
+ // Index to the array of varyings.
+ const PackedVarying *packedVarying;
+
+ // The array element of the packed varying.
+ unsigned int varyingArrayIndex;
+
+ // The row of the array element of the packed varying.
+ unsigned int varyingRowIndex;
+
+ // The register row to which we've assigned this packed varying.
+ unsigned int registerRow;
+
+ // The column of the register row into which we've packed this varying.
+ unsigned int registerColumn;
+};
+
+// Supported packing modes:
+enum class PackMode
+{
+ // We treat mat2 arrays as taking two full rows.
+ WEBGL_STRICT,
+
+ // We allow mat2 to take a 2x2 chunk.
+ ANGLE_RELAXED,
+
+ // Each varying takes a separate register. No register sharing.
+ ANGLE_NON_CONFORMANT_D3D9,
+};
+
+class VaryingPacking final : angle::NonCopyable
+{
+ public:
+ VaryingPacking();
+ ~VaryingPacking();
+
+ [[nodiscard]] bool collectAndPackUserVaryings(InfoLog &infoLog,
+ GLint maxVaryingVectors,
+ PackMode packMode,
+ ShaderType frontShaderStage,
+ ShaderType backShaderStage,
+ const ProgramMergedVaryings &mergedVaryings,
+ const std::vector<std::string> &tfVaryings,
+ const bool isSeparableProgram);
+
+ struct Register
+ {
+ Register() { data[0] = data[1] = data[2] = data[3] = false; }
+
+ bool &operator[](unsigned int index) { return data[index]; }
+ bool operator[](unsigned int index) const { return data[index]; }
+
+ bool data[4];
+ };
+
+ Register &operator[](unsigned int index) { return mRegisterMap[index]; }
+ const Register &operator[](unsigned int index) const { return mRegisterMap[index]; }
+
+ const std::vector<PackedVaryingRegister> &getRegisterList() const { return mRegisterList; }
+ unsigned int getMaxSemanticIndex() const
+ {
+ return static_cast<unsigned int>(mRegisterList.size());
+ }
+
+ const ShaderMap<std::vector<std::string>> &getInactiveVaryingMappedNames() const
+ {
+ return mInactiveVaryingMappedNames;
+ }
+
+ const ShaderMap<std::vector<std::string>> &getActiveOutputBuiltInNames() const
+ {
+ return mActiveOutputBuiltIns;
+ }
+
+ void reset();
+
+ private:
+ using VaryingUniqueFullNames = ShaderMap<std::set<std::string>>;
+
+ // Register map functions.
+ bool packUserVaryings(InfoLog &infoLog,
+ GLint maxVaryingVectors,
+ PackMode packMode,
+ const std::vector<PackedVarying> &packedVaryings);
+ bool packVaryingIntoRegisterMap(PackMode packMode, const PackedVarying &packedVarying);
+ bool isRegisterRangeFree(unsigned int registerRow,
+ unsigned int registerColumn,
+ unsigned int varyingRows,
+ unsigned int varyingColumns) const;
+ void insertVaryingIntoRegisterMap(unsigned int registerRow,
+ unsigned int registerColumn,
+ unsigned int varyingColumns,
+ const PackedVarying &packedVarying);
+ void clearRegisterMap();
+
+ // Collection functions.
+ void collectUserVarying(const ProgramVaryingRef &ref, VaryingUniqueFullNames *uniqueFullNames);
+ void collectUserVaryingField(const ProgramVaryingRef &ref,
+ GLuint arrayIndex,
+ GLuint fieldIndex,
+ GLuint secondaryFieldIndex,
+ VaryingUniqueFullNames *uniqueFullNames);
+ void collectUserVaryingTF(const ProgramVaryingRef &ref, size_t subscript);
+ void collectUserVaryingFieldTF(const ProgramVaryingRef &ref,
+ const sh::ShaderVariable &field,
+ GLuint fieldIndex,
+ GLuint secondaryFieldIndex);
+ void collectVarying(const sh::ShaderVariable &varying,
+ const ProgramVaryingRef &ref,
+ PackMode packMode,
+ VaryingUniqueFullNames *uniqueFullNames);
+ void collectTFVarying(const std::string &tfVarying,
+ const ProgramVaryingRef &ref,
+ VaryingUniqueFullNames *uniqueFullNames);
+
+ std::vector<Register> mRegisterMap;
+ std::vector<PackedVaryingRegister> mRegisterList;
+ std::vector<PackedVarying> mPackedVaryings;
+ ShaderMap<std::vector<std::string>> mInactiveVaryingMappedNames;
+ ShaderMap<std::vector<std::string>> mActiveOutputBuiltIns;
+};
+
+class ProgramVaryingPacking final : angle::NonCopyable
+{
+ public:
+ ProgramVaryingPacking();
+ ~ProgramVaryingPacking();
+
+ const VaryingPacking &getInputPacking(ShaderType backShaderStage) const;
+ const VaryingPacking &getOutputPacking(ShaderType frontShaderStage) const;
+
+ [[nodiscard]] bool collectAndPackUserVaryings(InfoLog &infoLog,
+ const Caps &caps,
+ PackMode packMode,
+ const ShaderBitSet &activeShadersMask,
+ const ProgramMergedVaryings &mergedVaryings,
+ const std::vector<std::string> &tfVaryings,
+ bool isSeparableProgram);
+
+ private:
+ // Indexed by the front shader.
+ ShaderMap<VaryingPacking> mVaryingPackings;
+
+ // Looks up the front stage from the back stage.
+ ShaderMap<ShaderType> mBackToFrontStageMap;
+};
+
+ProgramMergedVaryings GetMergedVaryingsFromLinkingVariables(
+ const LinkingVariables &linkingVariables);
+} // namespace gl
+
+#endif // LIBANGLE_VARYINGPACKING_H_
diff --git a/gfx/angle/checkout/src/libANGLE/Version.h b/gfx/angle/checkout/src/libANGLE/Version.h
new file mode 100644
index 0000000000..0d3b502d21
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Version.h
@@ -0,0 +1,34 @@
+//
+// 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.
+//
+
+// Version.h: Encapsulation of a GL version.
+
+#ifndef LIBANGLE_VERSION_H_
+#define LIBANGLE_VERSION_H_
+
+namespace gl
+{
+
+struct Version
+{
+ constexpr Version();
+ constexpr Version(unsigned int major, unsigned int minor);
+
+ unsigned int major;
+ unsigned int minor;
+};
+
+bool operator==(const Version &a, const Version &b);
+bool operator!=(const Version &a, const Version &b);
+bool operator>=(const Version &a, const Version &b);
+bool operator<=(const Version &a, const Version &b);
+bool operator<(const Version &a, const Version &b);
+bool operator>(const Version &a, const Version &b);
+} // namespace gl
+
+#include "Version.inc"
+
+#endif // LIBANGLE_VERSION_H_
diff --git a/gfx/angle/checkout/src/libANGLE/Version.inc b/gfx/angle/checkout/src/libANGLE/Version.inc
new file mode 100644
index 0000000000..a2bab8dc1f
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Version.inc
@@ -0,0 +1,59 @@
+//
+// 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.
+//
+
+// Version.inc: Encapsulation of a GL version.
+
+#include <tuple>
+
+namespace gl
+{
+
+constexpr Version::Version()
+ : Version(0, 0)
+{
+}
+
+// Avoid conflicts with linux system defines
+#undef major
+#undef minor
+
+constexpr Version::Version(unsigned int major_, unsigned int minor_)
+ : major(major_),
+ minor(minor_)
+{
+}
+
+inline bool operator==(const Version &a, const Version &b)
+{
+ return std::tie(a.major, a.minor) == std::tie(b.major, b.minor);
+}
+
+inline bool operator!=(const Version &a, const Version &b)
+{
+ return std::tie(a.major, a.minor) != std::tie(b.major, b.minor);
+}
+
+inline bool operator>=(const Version &a, const Version &b)
+{
+ return std::tie(a.major, a.minor) >= std::tie(b.major, b.minor);
+}
+
+inline bool operator<=(const Version &a, const Version &b)
+{
+ return std::tie(a.major, a.minor) <= std::tie(b.major, b.minor);
+}
+
+inline bool operator<(const Version &a, const Version &b)
+{
+ return std::tie(a.major, a.minor) < std::tie(b.major, b.minor);
+}
+
+inline bool operator>(const Version &a, const Version &b)
+{
+ return std::tie(a.major, a.minor) > std::tie(b.major, b.minor);
+}
+
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/VertexArray.cpp b/gfx/angle/checkout/src/libANGLE/VertexArray.cpp
new file mode 100644
index 0000000000..2a9bcd7cc0
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/VertexArray.cpp
@@ -0,0 +1,906 @@
+//
+// Copyright 2013 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 state class for mananging GLES 3 Vertex Array Objects.
+//
+
+#include "libANGLE/VertexArray.h"
+
+#include "common/utilities.h"
+#include "libANGLE/Buffer.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/renderer/BufferImpl.h"
+#include "libANGLE/renderer/GLImplFactory.h"
+#include "libANGLE/renderer/VertexArrayImpl.h"
+
+namespace gl
+{
+namespace
+{
+constexpr size_t kMaxObserverCountToTriggerUnobserve = 20;
+
+bool IsElementArrayBufferSubjectIndex(angle::SubjectIndex subjectIndex)
+{
+ return (subjectIndex == kElementArrayBufferIndex);
+}
+} // namespace
+
+// VertexArrayState implementation.
+VertexArrayState::VertexArrayState(VertexArray *vertexArray,
+ size_t maxAttribs,
+ size_t maxAttribBindings)
+ : mElementArrayBuffer(vertexArray, kElementArrayBufferIndex)
+{
+ ASSERT(maxAttribs <= maxAttribBindings);
+
+ for (size_t i = 0; i < maxAttribs; i++)
+ {
+ mVertexAttributes.emplace_back(static_cast<GLuint>(i));
+ mVertexBindings.emplace_back(static_cast<GLuint>(i));
+ }
+
+ // Initially all attributes start as "client" with no buffer bound.
+ mClientMemoryAttribsMask.set();
+}
+
+VertexArrayState::~VertexArrayState() {}
+
+bool VertexArrayState::hasEnabledNullPointerClientArray() const
+{
+ return (mNullPointerClientMemoryAttribsMask & mEnabledAttributesMask).any();
+}
+
+AttributesMask VertexArrayState::getBindingToAttributesMask(GLuint bindingIndex) const
+{
+ ASSERT(bindingIndex < mVertexBindings.size());
+ return mVertexBindings[bindingIndex].getBoundAttributesMask();
+}
+
+// Set an attribute using a new binding.
+void VertexArrayState::setAttribBinding(const Context *context,
+ size_t attribIndex,
+ GLuint newBindingIndex)
+{
+ ASSERT(attribIndex < mVertexAttributes.size() && newBindingIndex < mVertexBindings.size());
+
+ VertexAttribute &attrib = mVertexAttributes[attribIndex];
+
+ // Update the binding-attribute map.
+ const GLuint oldBindingIndex = attrib.bindingIndex;
+ ASSERT(oldBindingIndex != newBindingIndex);
+
+ VertexBinding &oldBinding = mVertexBindings[oldBindingIndex];
+ VertexBinding &newBinding = mVertexBindings[newBindingIndex];
+
+ ASSERT(oldBinding.getBoundAttributesMask().test(attribIndex) &&
+ !newBinding.getBoundAttributesMask().test(attribIndex));
+
+ oldBinding.resetBoundAttribute(attribIndex);
+ newBinding.setBoundAttribute(attribIndex);
+
+ // Set the attribute using the new binding.
+ attrib.bindingIndex = newBindingIndex;
+
+ if (context->isBufferAccessValidationEnabled())
+ {
+ attrib.updateCachedElementLimit(newBinding);
+ }
+
+ bool isMapped = newBinding.getBuffer().get() && newBinding.getBuffer()->isMapped();
+ mCachedMappedArrayBuffers.set(attribIndex, isMapped);
+ mEnabledAttributesMask.set(attribIndex, attrib.enabled);
+ updateCachedMutableOrNonPersistentArrayBuffers(attribIndex);
+ mCachedInvalidMappedArrayBuffer = mCachedMappedArrayBuffers & mEnabledAttributesMask &
+ mCachedMutableOrImpersistentArrayBuffers;
+}
+
+void VertexArrayState::updateCachedMutableOrNonPersistentArrayBuffers(size_t index)
+{
+ const VertexBinding &vertexBinding = mVertexBindings[index];
+ const BindingPointer<Buffer> &buffer = vertexBinding.getBuffer();
+ bool isMutableOrImpersistentArrayBuffer =
+ buffer.get() &&
+ (!buffer->isImmutable() || (buffer->getAccessFlags() & GL_MAP_PERSISTENT_BIT_EXT) == 0);
+ mCachedMutableOrImpersistentArrayBuffers.set(index, isMutableOrImpersistentArrayBuffer);
+}
+
+// VertexArray implementation.
+VertexArray::VertexArray(rx::GLImplFactory *factory,
+ VertexArrayID id,
+ size_t maxAttribs,
+ size_t maxAttribBindings)
+ : mId(id),
+ mState(this, maxAttribs, maxAttribBindings),
+ mVertexArray(factory->createVertexArray(mState)),
+ mBufferAccessValidationEnabled(false),
+ mContentsObservers(this)
+{
+ for (size_t attribIndex = 0; attribIndex < maxAttribBindings; ++attribIndex)
+ {
+ mArrayBufferObserverBindings.emplace_back(this, attribIndex);
+ }
+
+ mVertexArray->setContentsObservers(&mContentsObservers);
+}
+
+void VertexArray::onDestroy(const Context *context)
+{
+ bool isBound = context->isCurrentVertexArray(this);
+ for (uint32_t bindingIndex = 0; bindingIndex < mState.mVertexBindings.size(); ++bindingIndex)
+ {
+ VertexBinding &binding = mState.mVertexBindings[bindingIndex];
+ Buffer *buffer = binding.getBuffer().get();
+ if (isBound)
+ {
+ if (buffer)
+ {
+ buffer->onNonTFBindingChanged(-1);
+ }
+ }
+ if (buffer)
+ {
+ // Note: the non-contents observer is unbound in the ObserverBinding destructor.
+ buffer->removeContentsObserver(this, bindingIndex);
+ }
+ binding.setBuffer(context, nullptr);
+ }
+ if (mState.mElementArrayBuffer.get())
+ {
+ if (isBound)
+ {
+ mState.mElementArrayBuffer->onNonTFBindingChanged(-1);
+ }
+ mState.mElementArrayBuffer->removeContentsObserver(this, kElementArrayBufferIndex);
+ }
+ mState.mElementArrayBuffer.bind(context, nullptr);
+
+ // If mDirtyObserverBindingBits is set, it means we have removed it from the buffer's observer
+ // list. We should unassign subject to avoid assertion.
+ for (size_t bindingIndex : mDirtyObserverBindingBits)
+ {
+ angle::ObserverBinding *observer = &mArrayBufferObserverBindings[bindingIndex];
+ observer->assignSubject(nullptr);
+ }
+
+ mVertexArray->destroy(context);
+ SafeDelete(mVertexArray);
+ delete this;
+}
+
+VertexArray::~VertexArray()
+{
+ ASSERT(!mVertexArray);
+}
+
+angle::Result VertexArray::setLabel(const Context *context, const std::string &label)
+{
+ mState.mLabel = label;
+
+ if (mVertexArray)
+ {
+ return mVertexArray->onLabelUpdate(context);
+ }
+ return angle::Result::Continue;
+}
+
+const std::string &VertexArray::getLabel() const
+{
+ return mState.mLabel;
+}
+
+bool VertexArray::detachBuffer(const Context *context, BufferID bufferID)
+{
+ bool isBound = context->isCurrentVertexArray(this);
+ bool anyBufferDetached = false;
+ for (uint32_t bindingIndex = 0; bindingIndex < mState.mVertexBindings.size(); ++bindingIndex)
+ {
+ VertexBinding &binding = mState.mVertexBindings[bindingIndex];
+ const BindingPointer<Buffer> &bufferBinding = binding.getBuffer();
+ if (bufferBinding.id() == bufferID)
+ {
+ if (isBound)
+ {
+ if (bufferBinding.get())
+ bufferBinding->onNonTFBindingChanged(-1);
+ }
+ bufferBinding->removeContentsObserver(this, bindingIndex);
+ binding.setBuffer(context, nullptr);
+ mArrayBufferObserverBindings[bindingIndex].reset();
+
+ if (context->getClientVersion() >= ES_3_1)
+ {
+ setDirtyBindingBit(bindingIndex, DIRTY_BINDING_BUFFER);
+ }
+ else
+ {
+ static_assert(gl::MAX_VERTEX_ATTRIB_BINDINGS < 8 * sizeof(uint32_t),
+ "Not enough bits in bindingIndex");
+ // The redundant uint32_t cast here is required to avoid a warning on MSVC.
+ ASSERT(binding.getBoundAttributesMask() ==
+ AttributesMask(static_cast<uint32_t>(1 << bindingIndex)));
+ setDirtyAttribBit(bindingIndex, DIRTY_ATTRIB_POINTER);
+ }
+
+ anyBufferDetached = true;
+ mState.mClientMemoryAttribsMask |= binding.getBoundAttributesMask();
+ }
+ }
+
+ if (mState.mElementArrayBuffer.get() && mState.mElementArrayBuffer->id() == bufferID)
+ {
+ if (isBound && mState.mElementArrayBuffer.get())
+ mState.mElementArrayBuffer->onNonTFBindingChanged(-1);
+ mState.mElementArrayBuffer->removeContentsObserver(this, kElementArrayBufferIndex);
+ mState.mElementArrayBuffer.bind(context, nullptr);
+ mDirtyBits.set(DIRTY_BIT_ELEMENT_ARRAY_BUFFER);
+ anyBufferDetached = true;
+ }
+
+ return anyBufferDetached;
+}
+
+const VertexAttribute &VertexArray::getVertexAttribute(size_t attribIndex) const
+{
+ ASSERT(attribIndex < getMaxAttribs());
+ return mState.mVertexAttributes[attribIndex];
+}
+
+const VertexBinding &VertexArray::getVertexBinding(size_t bindingIndex) const
+{
+ ASSERT(bindingIndex < getMaxBindings());
+ return mState.mVertexBindings[bindingIndex];
+}
+
+size_t VertexArray::GetVertexIndexFromDirtyBit(size_t dirtyBit)
+{
+ static_assert(gl::MAX_VERTEX_ATTRIBS == gl::MAX_VERTEX_ATTRIB_BINDINGS,
+ "The stride of vertex attributes should equal to that of vertex bindings.");
+ ASSERT(dirtyBit > DIRTY_BIT_ELEMENT_ARRAY_BUFFER);
+ return (dirtyBit - DIRTY_BIT_ATTRIB_0) % gl::MAX_VERTEX_ATTRIBS;
+}
+
+ANGLE_INLINE void VertexArray::setDirtyAttribBit(size_t attribIndex,
+ DirtyAttribBitType dirtyAttribBit)
+{
+ mDirtyBits.set(DIRTY_BIT_ATTRIB_0 + attribIndex);
+ mDirtyAttribBits[attribIndex].set(dirtyAttribBit);
+}
+
+ANGLE_INLINE void VertexArray::clearDirtyAttribBit(size_t attribIndex,
+ DirtyAttribBitType dirtyAttribBit)
+{
+ mDirtyAttribBits[attribIndex].set(dirtyAttribBit, false);
+ if (mDirtyAttribBits[attribIndex].any())
+ {
+ return;
+ }
+ mDirtyBits.set(DIRTY_BIT_ATTRIB_0 + attribIndex, false);
+}
+
+ANGLE_INLINE void VertexArray::setDirtyBindingBit(size_t bindingIndex,
+ DirtyBindingBitType dirtyBindingBit)
+{
+ mDirtyBits.set(DIRTY_BIT_BINDING_0 + bindingIndex);
+ mDirtyBindingBits[bindingIndex].set(dirtyBindingBit);
+}
+
+ANGLE_INLINE void VertexArray::updateCachedBufferBindingSize(VertexBinding *binding)
+{
+ if (!mBufferAccessValidationEnabled)
+ return;
+
+ for (size_t boundAttribute : binding->getBoundAttributesMask())
+ {
+ mState.mVertexAttributes[boundAttribute].updateCachedElementLimit(*binding);
+ }
+}
+
+ANGLE_INLINE void VertexArray::updateCachedArrayBuffersMasks(
+ bool isMapped,
+ bool isImmutable,
+ bool isPersistent,
+ const AttributesMask &boundAttributesMask)
+{
+ if (isMapped)
+ {
+ mState.mCachedMappedArrayBuffers |= boundAttributesMask;
+ }
+ else
+ {
+ mState.mCachedMappedArrayBuffers &= ~boundAttributesMask;
+ }
+
+ if (!isImmutable || !isPersistent)
+ {
+ mState.mCachedMutableOrImpersistentArrayBuffers |= boundAttributesMask;
+ }
+ else
+ {
+ mState.mCachedMutableOrImpersistentArrayBuffers &= ~boundAttributesMask;
+ }
+
+ mState.mCachedInvalidMappedArrayBuffer = mState.mCachedMappedArrayBuffers &
+ mState.mEnabledAttributesMask &
+ mState.mCachedMutableOrImpersistentArrayBuffers;
+}
+
+ANGLE_INLINE void VertexArray::updateCachedMappedArrayBuffersBinding(const VertexBinding &binding)
+{
+ const Buffer *buffer = binding.getBuffer().get();
+ bool isMapped = buffer && buffer->isMapped();
+ bool isImmutable = buffer && buffer->isImmutable();
+ bool isPersistent = buffer && (buffer->getAccessFlags() & GL_MAP_PERSISTENT_BIT_EXT) != 0;
+ return updateCachedArrayBuffersMasks(isMapped, isImmutable, isPersistent,
+ binding.getBoundAttributesMask());
+}
+
+ANGLE_INLINE void VertexArray::updateCachedTransformFeedbackBindingValidation(size_t bindingIndex,
+ const Buffer *buffer)
+{
+ const bool hasConflict = buffer && buffer->hasWebGLXFBBindingConflict(true);
+ mCachedTransformFeedbackConflictedBindingsMask.set(bindingIndex, hasConflict);
+}
+
+bool VertexArray::bindVertexBufferImpl(const Context *context,
+ size_t bindingIndex,
+ Buffer *boundBuffer,
+ GLintptr offset,
+ GLsizei stride)
+{
+ ASSERT(bindingIndex < getMaxBindings());
+ ASSERT(context->isCurrentVertexArray(this));
+
+ VertexBinding *binding = &mState.mVertexBindings[bindingIndex];
+
+ Buffer *oldBuffer = binding->getBuffer().get();
+
+ const bool sameBuffer = oldBuffer == boundBuffer;
+ const bool sameStride = static_cast<GLuint>(stride) == binding->getStride();
+ const bool sameOffset = offset == binding->getOffset();
+
+ if (sameBuffer && sameStride && sameOffset)
+ {
+ return false;
+ }
+
+ angle::ObserverBinding *observer = &mArrayBufferObserverBindings[bindingIndex];
+ observer->assignSubject(boundBuffer);
+
+ // Several nullptr checks are combined here for optimization purposes.
+ if (oldBuffer)
+ {
+ oldBuffer->onNonTFBindingChanged(-1);
+ oldBuffer->removeObserver(observer);
+ oldBuffer->removeContentsObserver(this, static_cast<uint32_t>(bindingIndex));
+ oldBuffer->release(context);
+ }
+
+ binding->assignBuffer(boundBuffer);
+ binding->setOffset(offset);
+ binding->setStride(stride);
+ updateCachedBufferBindingSize(binding);
+
+ // Update client memory attribute pointers. Affects all bound attributes.
+ if (boundBuffer)
+ {
+ boundBuffer->addRef();
+ boundBuffer->onNonTFBindingChanged(1);
+ boundBuffer->addObserver(observer);
+ if (context->isWebGL())
+ {
+ mCachedTransformFeedbackConflictedBindingsMask.set(
+ bindingIndex, boundBuffer->hasWebGLXFBBindingConflict(true));
+ }
+ mState.mClientMemoryAttribsMask &= ~binding->getBoundAttributesMask();
+
+ bool isMapped = boundBuffer->isMapped() == GL_TRUE;
+ bool isImmutable = boundBuffer->isImmutable() == GL_TRUE;
+ bool isPersistent = (boundBuffer->getAccessFlags() & GL_MAP_PERSISTENT_BIT_EXT) != 0;
+ updateCachedArrayBuffersMasks(isMapped, isImmutable, isPersistent,
+ binding->getBoundAttributesMask());
+ }
+ else
+ {
+ if (context->isWebGL())
+ {
+ mCachedTransformFeedbackConflictedBindingsMask.set(bindingIndex, false);
+ }
+ mState.mClientMemoryAttribsMask |= binding->getBoundAttributesMask();
+ updateCachedArrayBuffersMasks(false, false, false, binding->getBoundAttributesMask());
+ }
+
+ return true;
+}
+
+void VertexArray::bindVertexBuffer(const Context *context,
+ size_t bindingIndex,
+ Buffer *boundBuffer,
+ GLintptr offset,
+ GLsizei stride)
+{
+ if (bindVertexBufferImpl(context, bindingIndex, boundBuffer, offset, stride))
+ {
+ setDirtyBindingBit(bindingIndex, DIRTY_BINDING_BUFFER);
+ }
+}
+
+void VertexArray::setVertexAttribBinding(const Context *context,
+ size_t attribIndex,
+ GLuint bindingIndex)
+{
+ ASSERT(attribIndex < getMaxAttribs() && bindingIndex < getMaxBindings());
+
+ if (mState.mVertexAttributes[attribIndex].bindingIndex == bindingIndex)
+ {
+ return;
+ }
+
+ // In ES 3.0 contexts, the binding cannot change, hence the code below is unreachable.
+ ASSERT(context->getClientVersion() >= ES_3_1);
+
+ mState.setAttribBinding(context, attribIndex, bindingIndex);
+
+ setDirtyAttribBit(attribIndex, DIRTY_ATTRIB_BINDING);
+
+ // Update client attribs mask.
+ bool hasBuffer = mState.mVertexBindings[bindingIndex].getBuffer().get() != nullptr;
+ mState.mClientMemoryAttribsMask.set(attribIndex, !hasBuffer);
+}
+
+void VertexArray::setVertexBindingDivisor(const Context *context,
+ size_t bindingIndex,
+ GLuint divisor)
+{
+ ASSERT(bindingIndex < getMaxBindings());
+
+ VertexBinding &binding = mState.mVertexBindings[bindingIndex];
+
+ if (binding.getDivisor() == divisor)
+ {
+ return;
+ }
+
+ binding.setDivisor(divisor);
+ setDirtyBindingBit(bindingIndex, DIRTY_BINDING_DIVISOR);
+
+ // Trigger updates in all bound attributes.
+ if (context->isBufferAccessValidationEnabled())
+ {
+ for (size_t attribIndex : binding.getBoundAttributesMask())
+ {
+ mState.mVertexAttributes[attribIndex].updateCachedElementLimit(binding);
+ }
+ }
+}
+
+ANGLE_INLINE bool VertexArray::setVertexAttribFormatImpl(VertexAttribute *attrib,
+ GLint size,
+ VertexAttribType type,
+ bool normalized,
+ bool pureInteger,
+ GLuint relativeOffset)
+{
+ angle::FormatID formatID = gl::GetVertexFormatID(type, normalized, size, pureInteger);
+
+ if (formatID != attrib->format->id || attrib->relativeOffset != relativeOffset)
+ {
+ attrib->relativeOffset = relativeOffset;
+ attrib->format = &angle::Format::Get(formatID);
+ return true;
+ }
+
+ return false;
+}
+
+void VertexArray::setVertexAttribFormat(size_t attribIndex,
+ GLint size,
+ VertexAttribType type,
+ bool normalized,
+ bool pureInteger,
+ GLuint relativeOffset)
+{
+ VertexAttribute &attrib = mState.mVertexAttributes[attribIndex];
+
+ ComponentType componentType = GetVertexAttributeComponentType(pureInteger, type);
+ SetComponentTypeMask(componentType, attribIndex, &mState.mVertexAttributesTypeMask);
+
+ if (setVertexAttribFormatImpl(&attrib, size, type, normalized, pureInteger, relativeOffset))
+ {
+ setDirtyAttribBit(attribIndex, DIRTY_ATTRIB_FORMAT);
+ }
+
+ attrib.updateCachedElementLimit(mState.mVertexBindings[attrib.bindingIndex]);
+}
+
+void VertexArray::setVertexAttribDivisor(const Context *context, size_t attribIndex, GLuint divisor)
+{
+ ASSERT(attribIndex < getMaxAttribs());
+
+ setVertexAttribBinding(context, attribIndex, static_cast<GLuint>(attribIndex));
+ setVertexBindingDivisor(context, attribIndex, divisor);
+}
+
+void VertexArray::enableAttribute(size_t attribIndex, bool enabledState)
+{
+ ASSERT(attribIndex < getMaxAttribs());
+
+ VertexAttribute &attrib = mState.mVertexAttributes[attribIndex];
+
+ if (mState.mEnabledAttributesMask.test(attribIndex) == enabledState)
+ {
+ return;
+ }
+
+ attrib.enabled = enabledState;
+
+ // Update state cache
+ mState.mEnabledAttributesMask.set(attribIndex, enabledState);
+ bool enableChanged = (mState.mEnabledAttributesMask.test(attribIndex) !=
+ mState.mLastSyncedEnabledAttributesMask.test(attribIndex));
+
+ if (enableChanged)
+ {
+ setDirtyAttribBit(attribIndex, DIRTY_ATTRIB_ENABLED);
+ }
+ else
+ {
+ clearDirtyAttribBit(attribIndex, DIRTY_ATTRIB_ENABLED);
+ }
+
+ mState.updateCachedMutableOrNonPersistentArrayBuffers(attribIndex);
+ mState.mCachedInvalidMappedArrayBuffer = mState.mCachedMappedArrayBuffers &
+ mState.mEnabledAttributesMask &
+ mState.mCachedMutableOrImpersistentArrayBuffers;
+}
+
+ANGLE_INLINE void VertexArray::setVertexAttribPointerImpl(const Context *context,
+ ComponentType componentType,
+ bool pureInteger,
+ size_t attribIndex,
+ Buffer *boundBuffer,
+ GLint size,
+ VertexAttribType type,
+ bool normalized,
+ GLsizei stride,
+ const void *pointer)
+{
+ ASSERT(attribIndex < getMaxAttribs());
+
+ VertexAttribute &attrib = mState.mVertexAttributes[attribIndex];
+
+ SetComponentTypeMask(componentType, attribIndex, &mState.mVertexAttributesTypeMask);
+
+ bool attribDirty = setVertexAttribFormatImpl(&attrib, size, type, normalized, pureInteger, 0);
+
+ if (attrib.bindingIndex != attribIndex)
+ {
+ setVertexAttribBinding(context, attribIndex, static_cast<GLuint>(attribIndex));
+ }
+
+ GLsizei effectiveStride =
+ stride == 0 ? static_cast<GLsizei>(ComputeVertexAttributeTypeSize(attrib)) : stride;
+
+ if (attrib.vertexAttribArrayStride != static_cast<GLuint>(stride))
+ {
+ attribDirty = true;
+ }
+ attrib.vertexAttribArrayStride = stride;
+
+ // If we switch from an array buffer to a client pointer(or vice-versa), we set the whole
+ // attribute dirty. This notifies the Vulkan back-end to update all its caches.
+ const VertexBinding &binding = mState.mVertexBindings[attribIndex];
+ if ((boundBuffer == nullptr) != (binding.getBuffer().get() == nullptr))
+ {
+ attribDirty = true;
+ }
+
+ // Change of attrib.pointer is not part of attribDirty. Pointer is actually the buffer offset
+ // which is handled within bindVertexBufferImpl and reflected in bufferDirty.
+ attrib.pointer = pointer;
+ GLintptr offset = boundBuffer ? reinterpret_cast<GLintptr>(pointer) : 0;
+ const bool bufferDirty =
+ bindVertexBufferImpl(context, attribIndex, boundBuffer, offset, effectiveStride);
+
+ if (attribDirty)
+ {
+ setDirtyAttribBit(attribIndex, DIRTY_ATTRIB_POINTER);
+ }
+ else if (bufferDirty)
+ {
+ setDirtyAttribBit(attribIndex, DIRTY_ATTRIB_POINTER_BUFFER);
+ }
+
+ mState.mNullPointerClientMemoryAttribsMask.set(attribIndex,
+ boundBuffer == nullptr && pointer == nullptr);
+}
+
+void VertexArray::setVertexAttribPointer(const Context *context,
+ size_t attribIndex,
+ gl::Buffer *boundBuffer,
+ GLint size,
+ VertexAttribType type,
+ bool normalized,
+ GLsizei stride,
+ const void *pointer)
+{
+ setVertexAttribPointerImpl(context, ComponentType::Float, false, attribIndex, boundBuffer, size,
+ type, normalized, stride, pointer);
+}
+
+void VertexArray::setVertexAttribIPointer(const Context *context,
+ size_t attribIndex,
+ gl::Buffer *boundBuffer,
+ GLint size,
+ VertexAttribType type,
+ GLsizei stride,
+ const void *pointer)
+{
+ ComponentType componentType = GetVertexAttributeComponentType(true, type);
+ setVertexAttribPointerImpl(context, componentType, true, attribIndex, boundBuffer, size, type,
+ false, stride, pointer);
+}
+
+angle::Result VertexArray::syncState(const Context *context)
+{
+ if (mDirtyBits.any())
+ {
+ mDirtyBitsGuard = mDirtyBits;
+ ANGLE_TRY(
+ mVertexArray->syncState(context, mDirtyBits, &mDirtyAttribBits, &mDirtyBindingBits));
+ mDirtyBits.reset();
+ mDirtyBitsGuard.reset();
+
+ // The dirty bits should be reset in the back-end. To simplify ASSERTs only check attrib 0.
+ ASSERT(mDirtyAttribBits[0].none());
+ ASSERT(mDirtyBindingBits[0].none());
+ mState.mLastSyncedEnabledAttributesMask = mState.mEnabledAttributesMask;
+ }
+ return angle::Result::Continue;
+}
+
+// This becomes current vertex array on the context
+void VertexArray::onBind(const Context *context)
+{
+ if (mDirtyObserverBindingBits.none())
+ {
+ return;
+ }
+
+ // This vertex array becoming current. Some of the bindings we may have removed from buffer's
+ // observer list. We need to add it back to the buffer's observer list and update dirty bits
+ // that we may have missed while we were not observing.
+ for (size_t bindingIndex : mDirtyObserverBindingBits)
+ {
+ const gl::VertexBinding &binding = mState.getVertexBindings()[bindingIndex];
+ gl::Buffer *bufferGL = binding.getBuffer().get();
+ ASSERT(bufferGL != nullptr);
+
+ bufferGL->addObserver(&mArrayBufferObserverBindings[bindingIndex]);
+ updateCachedMappedArrayBuffersBinding(mState.mVertexBindings[bindingIndex]);
+
+ // Assume both data and internal storage has been dirtied.
+ mDirtyBits.set(DIRTY_BIT_BINDING_0 + bindingIndex);
+
+ if (mBufferAccessValidationEnabled)
+ {
+ for (size_t boundAttribute :
+ mState.mVertexBindings[bindingIndex].getBoundAttributesMask())
+ {
+ mState.mVertexAttributes[boundAttribute].updateCachedElementLimit(
+ mState.mVertexBindings[bindingIndex]);
+ }
+ }
+
+ if (context->isWebGL())
+ {
+ updateCachedTransformFeedbackBindingValidation(bindingIndex, bufferGL);
+ }
+ }
+ mDirtyObserverBindingBits.reset();
+
+ onStateChange(angle::SubjectMessage::ContentsChanged);
+}
+
+// This becomes non-current vertex array on the context
+void VertexArray::onUnbind(const Context *context)
+{
+ // This vertex array becoming non-current. For performance reason, if there are too many
+ // observers in the buffer, we remove it from the buffers' observer list so that the cost of
+ // buffer sending signal to observers will be too expensive.
+ for (uint32_t bindingIndex = 0; bindingIndex < mArrayBufferObserverBindings.size();
+ ++bindingIndex)
+ {
+ const gl::VertexBinding &binding = mState.getVertexBindings()[bindingIndex];
+ gl::Buffer *bufferGL = binding.getBuffer().get();
+ if (bufferGL && bufferGL->getObserversCount() > kMaxObserverCountToTriggerUnobserve)
+ {
+ bufferGL->removeObserver(&mArrayBufferObserverBindings[bindingIndex]);
+ mDirtyObserverBindingBits.set(bindingIndex);
+ }
+ }
+}
+
+void VertexArray::onBindingChanged(const Context *context, int incr)
+{
+ // When vertex array gets unbound, we remove it from bound buffers' observer list so that when
+ // buffer changes, it wont has to loop over all these non-current vertex arrays and set dirty
+ // bit on them. To compensate for that, when we bind a vertex array, we have to check against
+ // each bound buffers and see if they have changed and needs to update vertex array's dirty bits
+ // accordingly
+ ASSERT(incr == 1 || incr == -1);
+ if (incr < 0)
+ {
+ onUnbind(context);
+ }
+ else
+ {
+ onBind(context);
+ }
+
+ if (context->isWebGL())
+ {
+ if (mState.mElementArrayBuffer.get())
+ mState.mElementArrayBuffer->onNonTFBindingChanged(incr);
+ for (auto &binding : mState.mVertexBindings)
+ {
+ binding.onContainerBindingChanged(context, incr);
+ }
+ }
+}
+
+VertexArray::DirtyBitType VertexArray::getDirtyBitFromIndex(bool contentsChanged,
+ angle::SubjectIndex index) const
+{
+ if (IsElementArrayBufferSubjectIndex(index))
+ {
+ mIndexRangeCache.invalidate();
+ return contentsChanged ? DIRTY_BIT_ELEMENT_ARRAY_BUFFER_DATA
+ : DIRTY_BIT_ELEMENT_ARRAY_BUFFER;
+ }
+ else
+ {
+ // Note: this currently just gets the top-level dirty bit.
+ ASSERT(index < mArrayBufferObserverBindings.size());
+ return static_cast<DirtyBitType>(
+ (contentsChanged ? DIRTY_BIT_BUFFER_DATA_0 : DIRTY_BIT_BINDING_0) + index);
+ }
+}
+
+void VertexArray::onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message)
+{
+ switch (message)
+ {
+ case angle::SubjectMessage::SubjectChanged:
+ if (!IsElementArrayBufferSubjectIndex(index))
+ {
+ updateCachedBufferBindingSize(&mState.mVertexBindings[index]);
+ }
+ setDependentDirtyBit(false, index);
+ break;
+
+ case angle::SubjectMessage::BindingChanged:
+ if (!IsElementArrayBufferSubjectIndex(index))
+ {
+ const Buffer *buffer = mState.mVertexBindings[index].getBuffer().get();
+ updateCachedTransformFeedbackBindingValidation(index, buffer);
+ }
+ break;
+
+ case angle::SubjectMessage::SubjectMapped:
+ if (!IsElementArrayBufferSubjectIndex(index))
+ {
+ updateCachedMappedArrayBuffersBinding(mState.mVertexBindings[index]);
+ }
+ onStateChange(angle::SubjectMessage::SubjectMapped);
+ break;
+
+ case angle::SubjectMessage::SubjectUnmapped:
+ setDependentDirtyBit(true, index);
+
+ if (!IsElementArrayBufferSubjectIndex(index))
+ {
+ updateCachedMappedArrayBuffersBinding(mState.mVertexBindings[index]);
+ }
+ onStateChange(angle::SubjectMessage::SubjectUnmapped);
+ break;
+
+ case angle::SubjectMessage::InternalMemoryAllocationChanged:
+ setDependentDirtyBit(false, index);
+ break;
+
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+void VertexArray::setDependentDirtyBit(bool contentsChanged, angle::SubjectIndex index)
+{
+ DirtyBitType dirtyBit = getDirtyBitFromIndex(contentsChanged, index);
+ ASSERT(!mDirtyBitsGuard.valid() || mDirtyBitsGuard.value().test(dirtyBit));
+ mDirtyBits.set(dirtyBit);
+ onStateChange(angle::SubjectMessage::ContentsChanged);
+}
+
+bool VertexArray::hasTransformFeedbackBindingConflict(const gl::Context *context) const
+{
+ // Fast check first.
+ if (!mCachedTransformFeedbackConflictedBindingsMask.any())
+ {
+ return false;
+ }
+
+ const AttributesMask &activeAttribues = context->getStateCache().getActiveBufferedAttribsMask();
+
+ // Slow check. We must ensure that the conflicting attributes are enabled/active.
+ for (size_t attribIndex : activeAttribues)
+ {
+ const VertexAttribute &attrib = mState.mVertexAttributes[attribIndex];
+ if (mCachedTransformFeedbackConflictedBindingsMask[attrib.bindingIndex])
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+angle::Result VertexArray::getIndexRangeImpl(const Context *context,
+ DrawElementsType type,
+ GLsizei indexCount,
+ const void *indices,
+ IndexRange *indexRangeOut) const
+{
+ Buffer *elementArrayBuffer = mState.mElementArrayBuffer.get();
+ if (!elementArrayBuffer)
+ {
+ *indexRangeOut = ComputeIndexRange(type, indices, indexCount,
+ context->getState().isPrimitiveRestartEnabled());
+ return angle::Result::Continue;
+ }
+
+ size_t offset = reinterpret_cast<uintptr_t>(indices);
+ ANGLE_TRY(elementArrayBuffer->getIndexRange(context, type, offset, indexCount,
+ context->getState().isPrimitiveRestartEnabled(),
+ indexRangeOut));
+
+ mIndexRangeCache.put(type, indexCount, offset, *indexRangeOut);
+ return angle::Result::Continue;
+}
+
+VertexArray::IndexRangeCache::IndexRangeCache() = default;
+
+void VertexArray::IndexRangeCache::put(DrawElementsType type,
+ GLsizei indexCount,
+ size_t offset,
+ const IndexRange &indexRange)
+{
+ ASSERT(type != DrawElementsType::InvalidEnum);
+
+ mTypeKey = type;
+ mIndexCountKey = indexCount;
+ mOffsetKey = offset;
+ mPayload = indexRange;
+}
+
+void VertexArray::onBufferContentsChange(uint32_t bufferIndex)
+{
+ setDependentDirtyBit(true, bufferIndex);
+}
+
+VertexArrayBufferContentsObservers::VertexArrayBufferContentsObservers(VertexArray *vertexArray)
+ : mVertexArray(vertexArray)
+{}
+
+void VertexArrayBufferContentsObservers::enableForBuffer(Buffer *buffer, uint32_t bufferIndex)
+{
+ buffer->addContentsObserver(mVertexArray, bufferIndex);
+}
+
+void VertexArrayBufferContentsObservers::disableForBuffer(Buffer *buffer, uint32_t bufferIndex)
+{
+ buffer->removeContentsObserver(mVertexArray, bufferIndex);
+}
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/VertexArray.h b/gfx/angle/checkout/src/libANGLE/VertexArray.h
new file mode 100644
index 0000000000..16f036c86b
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/VertexArray.h
@@ -0,0 +1,436 @@
+//
+// Copyright 2013 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 class contains prototypes for representing GLES 3 Vertex Array Objects:
+//
+// The buffer objects that are to be used by the vertex stage of the GL are collected
+// together to form a vertex array object. All state related to the definition of data used
+// by the vertex processor is encapsulated in a vertex array object.
+//
+
+#ifndef LIBANGLE_VERTEXARRAY_H_
+#define LIBANGLE_VERTEXARRAY_H_
+
+#include "common/Optional.h"
+#include "libANGLE/Constants.h"
+#include "libANGLE/Debug.h"
+#include "libANGLE/Observer.h"
+#include "libANGLE/RefCountObject.h"
+#include "libANGLE/VertexAttribute.h"
+
+#include <vector>
+
+namespace rx
+{
+class GLImplFactory;
+class VertexArrayImpl;
+} // namespace rx
+
+namespace gl
+{
+class Buffer;
+
+constexpr uint32_t kElementArrayBufferIndex = MAX_VERTEX_ATTRIBS;
+
+class VertexArrayState final : angle::NonCopyable
+{
+ public:
+ VertexArrayState(VertexArray *vertexArray, size_t maxAttribs, size_t maxBindings);
+ ~VertexArrayState();
+
+ const std::string &getLabel() const { return mLabel; }
+
+ Buffer *getElementArrayBuffer() const { return mElementArrayBuffer.get(); }
+ size_t getMaxAttribs() const { return mVertexAttributes.size(); }
+ size_t getMaxBindings() const { return mVertexBindings.size(); }
+ const AttributesMask &getEnabledAttributesMask() const { return mEnabledAttributesMask; }
+ const std::vector<VertexAttribute> &getVertexAttributes() const { return mVertexAttributes; }
+ const VertexAttribute &getVertexAttribute(size_t attribIndex) const
+ {
+ return mVertexAttributes[attribIndex];
+ }
+ const std::vector<VertexBinding> &getVertexBindings() const { return mVertexBindings; }
+ const VertexBinding &getVertexBinding(size_t bindingIndex) const
+ {
+ return mVertexBindings[bindingIndex];
+ }
+ const VertexBinding &getBindingFromAttribIndex(size_t attribIndex) const
+ {
+ return mVertexBindings[mVertexAttributes[attribIndex].bindingIndex];
+ }
+ size_t getBindingIndexFromAttribIndex(size_t attribIndex) const
+ {
+ return mVertexAttributes[attribIndex].bindingIndex;
+ }
+
+ void setAttribBinding(const Context *context, size_t attribIndex, GLuint newBindingIndex);
+
+ // Extra validation performed on the Vertex Array.
+ bool hasEnabledNullPointerClientArray() const;
+
+ // Get all the attributes in an AttributesMask that are using the given binding.
+ AttributesMask getBindingToAttributesMask(GLuint bindingIndex) const;
+
+ ComponentTypeMask getVertexAttributesTypeMask() const { return mVertexAttributesTypeMask; }
+
+ AttributesMask getClientMemoryAttribsMask() const { return mClientMemoryAttribsMask; }
+
+ gl::AttributesMask getNullPointerClientMemoryAttribsMask() const
+ {
+ return mNullPointerClientMemoryAttribsMask;
+ }
+
+ private:
+ void updateCachedMutableOrNonPersistentArrayBuffers(size_t index);
+
+ friend class VertexArray;
+ std::string mLabel;
+ std::vector<VertexAttribute> mVertexAttributes;
+ SubjectBindingPointer<Buffer> mElementArrayBuffer;
+ std::vector<VertexBinding> mVertexBindings;
+ AttributesMask mEnabledAttributesMask;
+ ComponentTypeMask mVertexAttributesTypeMask;
+ AttributesMask mLastSyncedEnabledAttributesMask;
+
+ // This is a performance optimization for buffer binding. Allows element array buffer updates.
+ friend class State;
+
+ // From the GLES 3.1 spec:
+ // When a generic attribute array is sourced from client memory, the vertex attribute binding
+ // state is ignored. Thus we don't have to worry about binding state when using client memory
+ // attribs.
+ gl::AttributesMask mClientMemoryAttribsMask;
+ gl::AttributesMask mNullPointerClientMemoryAttribsMask;
+
+ // Used for validation cache. Indexed by attribute.
+ AttributesMask mCachedMappedArrayBuffers;
+ AttributesMask mCachedMutableOrImpersistentArrayBuffers;
+ AttributesMask mCachedInvalidMappedArrayBuffer;
+};
+
+class VertexArrayBufferContentsObservers final : angle::NonCopyable
+{
+ public:
+ VertexArrayBufferContentsObservers(VertexArray *vertexArray);
+ void enableForBuffer(Buffer *buffer, uint32_t bufferIndex);
+ void disableForBuffer(Buffer *buffer, uint32_t bufferIndex);
+
+ private:
+ VertexArray *mVertexArray;
+};
+
+class VertexArray final : public angle::ObserverInterface,
+ public LabeledObject,
+ public angle::Subject
+{
+ public:
+ // Dirty bits for VertexArrays use a hierarchical design. At the top level, each attribute
+ // has a single dirty bit. Then an array of MAX_ATTRIBS dirty bits each has a dirty bit for
+ // enabled/pointer/format/binding. Bindings are handled similarly. Note that because the
+ // total number of dirty bits is 33, it will not be as fast on a 32-bit machine, which
+ // can't support the advanced 64-bit scanning intrinsics. We could consider packing the
+ // binding and attribute bits together if this becomes a problem.
+ //
+ // Special note on "DIRTY_ATTRIB_POINTER_BUFFER": this is a special case when the app
+ // calls glVertexAttribPointer but only changes a VBO and/or offset binding. This allows
+ // the Vulkan back-end to skip performing a pipeline change for performance.
+ enum DirtyBitType
+ {
+ DIRTY_BIT_ELEMENT_ARRAY_BUFFER,
+ DIRTY_BIT_ELEMENT_ARRAY_BUFFER_DATA,
+
+ // Dirty bits for bindings.
+ DIRTY_BIT_BINDING_0,
+ DIRTY_BIT_BINDING_MAX = DIRTY_BIT_BINDING_0 + gl::MAX_VERTEX_ATTRIB_BINDINGS,
+
+ // We keep separate dirty bits for bound buffers whose data changed since last update.
+ DIRTY_BIT_BUFFER_DATA_0 = DIRTY_BIT_BINDING_MAX,
+ DIRTY_BIT_BUFFER_DATA_MAX = DIRTY_BIT_BUFFER_DATA_0 + gl::MAX_VERTEX_ATTRIB_BINDINGS,
+
+ // Dirty bits for attributes.
+ DIRTY_BIT_ATTRIB_0 = DIRTY_BIT_BUFFER_DATA_MAX,
+ DIRTY_BIT_ATTRIB_MAX = DIRTY_BIT_ATTRIB_0 + gl::MAX_VERTEX_ATTRIBS,
+
+ DIRTY_BIT_UNKNOWN = DIRTY_BIT_ATTRIB_MAX,
+ DIRTY_BIT_MAX = DIRTY_BIT_UNKNOWN,
+ };
+
+ // We want to keep the number of dirty bits within 64 to keep iteration times fast.
+ static_assert(DIRTY_BIT_MAX <= 64, "Too many vertex array dirty bits.");
+ // The dirty bit processing has the logic to avoid redundant processing by removing other dirty
+ // bits when it processes dirtyBits. This assertion ensures these dirty bit order matches what
+ // VertexArrayVk::syncState expects.
+ static_assert(DIRTY_BIT_BINDING_0 < DIRTY_BIT_BUFFER_DATA_0,
+ "BINDING dity bits should come before DATA.");
+ static_assert(DIRTY_BIT_BUFFER_DATA_0 < DIRTY_BIT_ATTRIB_0,
+ "DATA dity bits should come before ATTRIB.");
+
+ enum DirtyAttribBitType
+ {
+ DIRTY_ATTRIB_ENABLED,
+ DIRTY_ATTRIB_POINTER,
+ DIRTY_ATTRIB_FORMAT,
+ DIRTY_ATTRIB_BINDING,
+ DIRTY_ATTRIB_POINTER_BUFFER,
+ DIRTY_ATTRIB_UNKNOWN,
+ DIRTY_ATTRIB_MAX = DIRTY_ATTRIB_UNKNOWN,
+ };
+
+ enum DirtyBindingBitType
+ {
+ DIRTY_BINDING_BUFFER,
+ DIRTY_BINDING_DIVISOR,
+ DIRTY_BINDING_UNKNOWN,
+ DIRTY_BINDING_MAX = DIRTY_BINDING_UNKNOWN,
+ };
+
+ using DirtyBits = angle::BitSet<DIRTY_BIT_MAX>;
+ using DirtyAttribBits = angle::BitSet<DIRTY_ATTRIB_MAX>;
+ using DirtyBindingBits = angle::BitSet<DIRTY_BINDING_MAX>;
+ using DirtyAttribBitsArray = std::array<DirtyAttribBits, gl::MAX_VERTEX_ATTRIBS>;
+ using DirtyBindingBitsArray = std::array<DirtyBindingBits, gl::MAX_VERTEX_ATTRIB_BINDINGS>;
+ using DirtyObserverBindingBits = angle::BitSet<gl::MAX_VERTEX_ATTRIB_BINDINGS>;
+
+ VertexArray(rx::GLImplFactory *factory,
+ VertexArrayID id,
+ size_t maxAttribs,
+ size_t maxAttribBindings);
+
+ void onDestroy(const Context *context);
+
+ VertexArrayID id() const { return mId; }
+
+ angle::Result setLabel(const Context *context, const std::string &label) override;
+ const std::string &getLabel() const override;
+
+ const VertexBinding &getVertexBinding(size_t bindingIndex) const;
+ const VertexAttribute &getVertexAttribute(size_t attribIndex) const;
+ const VertexBinding &getBindingFromAttribIndex(size_t attribIndex) const
+ {
+ return mState.getBindingFromAttribIndex(attribIndex);
+ }
+
+ // Returns true if the function finds and detaches a bound buffer.
+ bool detachBuffer(const Context *context, BufferID bufferID);
+
+ void setVertexAttribDivisor(const Context *context, size_t index, GLuint divisor);
+ void enableAttribute(size_t attribIndex, bool enabledState);
+
+ void setVertexAttribPointer(const Context *context,
+ size_t attribIndex,
+ Buffer *boundBuffer,
+ GLint size,
+ VertexAttribType type,
+ bool normalized,
+ GLsizei stride,
+ const void *pointer);
+
+ void setVertexAttribIPointer(const Context *context,
+ size_t attribIndex,
+ Buffer *boundBuffer,
+ GLint size,
+ VertexAttribType type,
+ GLsizei stride,
+ const void *pointer);
+
+ void setVertexAttribFormat(size_t attribIndex,
+ GLint size,
+ VertexAttribType type,
+ bool normalized,
+ bool pureInteger,
+ GLuint relativeOffset);
+ void bindVertexBuffer(const Context *context,
+ size_t bindingIndex,
+ Buffer *boundBuffer,
+ GLintptr offset,
+ GLsizei stride);
+ void setVertexAttribBinding(const Context *context, size_t attribIndex, GLuint bindingIndex);
+ void setVertexBindingDivisor(const Context *context, size_t bindingIndex, GLuint divisor);
+
+ Buffer *getElementArrayBuffer() const { return mState.getElementArrayBuffer(); }
+ size_t getMaxAttribs() const { return mState.getMaxAttribs(); }
+ size_t getMaxBindings() const { return mState.getMaxBindings(); }
+
+ const std::vector<VertexAttribute> &getVertexAttributes() const
+ {
+ return mState.getVertexAttributes();
+ }
+ const std::vector<VertexBinding> &getVertexBindings() const
+ {
+ return mState.getVertexBindings();
+ }
+
+ rx::VertexArrayImpl *getImplementation() const { return mVertexArray; }
+
+ const AttributesMask &getEnabledAttributesMask() const
+ {
+ return mState.getEnabledAttributesMask();
+ }
+
+ gl::AttributesMask getClientAttribsMask() const { return mState.mClientMemoryAttribsMask; }
+
+ bool hasEnabledNullPointerClientArray() const
+ {
+ return mState.hasEnabledNullPointerClientArray();
+ }
+
+ bool hasInvalidMappedArrayBuffer() const
+ {
+ return mState.mCachedInvalidMappedArrayBuffer.any();
+ }
+
+ const VertexArrayState &getState() const { return mState; }
+
+ bool isBufferAccessValidationEnabled() const { return mBufferAccessValidationEnabled; }
+
+ // Observer implementation
+ void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override;
+ void onBufferContentsChange(uint32_t bufferIndex);
+
+ static size_t GetVertexIndexFromDirtyBit(size_t dirtyBit);
+
+ angle::Result syncState(const Context *context);
+ bool hasAnyDirtyBit() const { return mDirtyBits.any(); }
+
+ ComponentTypeMask getAttributesTypeMask() const { return mState.mVertexAttributesTypeMask; }
+ AttributesMask getAttributesMask() const { return mState.mEnabledAttributesMask; }
+
+ void onBindingChanged(const Context *context, int incr);
+ bool hasTransformFeedbackBindingConflict(const gl::Context *context) const;
+
+ ANGLE_INLINE angle::Result getIndexRange(const Context *context,
+ DrawElementsType type,
+ GLsizei indexCount,
+ const void *indices,
+ IndexRange *indexRangeOut) const
+ {
+ Buffer *elementArrayBuffer = mState.mElementArrayBuffer.get();
+ if (elementArrayBuffer && mIndexRangeCache.get(type, indexCount, indices, indexRangeOut))
+ {
+ return angle::Result::Continue;
+ }
+
+ return getIndexRangeImpl(context, type, indexCount, indices, indexRangeOut);
+ }
+
+ void setBufferAccessValidationEnabled(bool enabled)
+ {
+ mBufferAccessValidationEnabled = enabled;
+ }
+
+ private:
+ ~VertexArray() override;
+
+ // This is a performance optimization for buffer binding. Allows element array buffer updates.
+ friend class State;
+
+ void setDirtyAttribBit(size_t attribIndex, DirtyAttribBitType dirtyAttribBit);
+ void setDirtyBindingBit(size_t bindingIndex, DirtyBindingBitType dirtyBindingBit);
+ void clearDirtyAttribBit(size_t attribIndex, DirtyAttribBitType dirtyAttribBit);
+
+ DirtyBitType getDirtyBitFromIndex(bool contentsChanged, angle::SubjectIndex index) const;
+ void setDependentDirtyBit(bool contentsChanged, angle::SubjectIndex index);
+
+ // These are used to optimize draw call validation.
+ void updateCachedBufferBindingSize(VertexBinding *binding);
+ void updateCachedTransformFeedbackBindingValidation(size_t bindingIndex, const Buffer *buffer);
+ void updateCachedArrayBuffersMasks(bool isMapped,
+ bool isImmutable,
+ bool isPersistent,
+ const AttributesMask &boundAttributesMask);
+ void updateCachedMappedArrayBuffersBinding(const VertexBinding &binding);
+
+ angle::Result getIndexRangeImpl(const Context *context,
+ DrawElementsType type,
+ GLsizei indexCount,
+ const void *indices,
+ IndexRange *indexRangeOut) const;
+
+ void setVertexAttribPointerImpl(const Context *context,
+ ComponentType componentType,
+ bool pureInteger,
+ size_t attribIndex,
+ Buffer *boundBuffer,
+ GLint size,
+ VertexAttribType type,
+ bool normalized,
+ GLsizei stride,
+ const void *pointer);
+
+ // These two functions return true if the state was dirty.
+ bool setVertexAttribFormatImpl(VertexAttribute *attrib,
+ GLint size,
+ VertexAttribType type,
+ bool normalized,
+ bool pureInteger,
+ GLuint relativeOffset);
+ bool bindVertexBufferImpl(const Context *context,
+ size_t bindingIndex,
+ Buffer *boundBuffer,
+ GLintptr offset,
+ GLsizei stride);
+
+ void onBind(const Context *context);
+ void onUnbind(const Context *context);
+
+ VertexArrayID mId;
+
+ VertexArrayState mState;
+ DirtyBits mDirtyBits;
+ DirtyAttribBitsArray mDirtyAttribBits;
+ DirtyBindingBitsArray mDirtyBindingBits;
+ Optional<DirtyBits> mDirtyBitsGuard;
+
+ rx::VertexArrayImpl *mVertexArray;
+
+ std::vector<angle::ObserverBinding> mArrayBufferObserverBindings;
+ // Track which observer in mArrayBufferObserverBindings is not currently been removed from
+ // subject's observer list.
+ DirtyObserverBindingBits mDirtyObserverBindingBits;
+
+ AttributesMask mCachedTransformFeedbackConflictedBindingsMask;
+
+ class IndexRangeCache final : angle::NonCopyable
+ {
+ public:
+ IndexRangeCache();
+
+ void invalidate() { mTypeKey = DrawElementsType::InvalidEnum; }
+
+ bool get(DrawElementsType type,
+ GLsizei indexCount,
+ const void *indices,
+ IndexRange *indexRangeOut)
+ {
+ size_t offset = reinterpret_cast<uintptr_t>(indices);
+ if (mTypeKey == type && mIndexCountKey == indexCount && mOffsetKey == offset)
+ {
+ *indexRangeOut = mPayload;
+ return true;
+ }
+
+ return false;
+ }
+
+ void put(DrawElementsType type,
+ GLsizei indexCount,
+ size_t offset,
+ const IndexRange &indexRange);
+
+ private:
+ DrawElementsType mTypeKey;
+ GLsizei mIndexCountKey;
+ size_t mOffsetKey;
+ IndexRange mPayload;
+ };
+
+ mutable IndexRangeCache mIndexRangeCache;
+ bool mBufferAccessValidationEnabled;
+ VertexArrayBufferContentsObservers mContentsObservers;
+};
+
+} // namespace gl
+
+#endif // LIBANGLE_VERTEXARRAY_H_
diff --git a/gfx/angle/checkout/src/libANGLE/VertexAttribute.cpp b/gfx/angle/checkout/src/libANGLE/VertexAttribute.cpp
new file mode 100644
index 0000000000..f525addbba
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/VertexAttribute.cpp
@@ -0,0 +1,170 @@
+//
+// 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.
+//
+// Implementation of the state classes for mananging GLES 3.1 Vertex Array Objects.
+//
+
+#include "libANGLE/VertexAttribute.h"
+
+namespace gl
+{
+
+// [OpenGL ES 3.1] (November 3, 2016) Section 20 Page 361
+// Table 20.2: Vertex Array Object State
+VertexBinding::VertexBinding() : VertexBinding(0) {}
+
+VertexBinding::VertexBinding(GLuint boundAttribute) : mStride(16u), mDivisor(0), mOffset(0)
+{
+ mBoundAttributesMask.set(boundAttribute);
+}
+
+VertexBinding::VertexBinding(VertexBinding &&binding)
+{
+ *this = std::move(binding);
+}
+
+VertexBinding::~VertexBinding() {}
+
+VertexBinding &VertexBinding::operator=(VertexBinding &&binding)
+{
+ if (this != &binding)
+ {
+ mStride = binding.mStride;
+ mDivisor = binding.mDivisor;
+ mOffset = binding.mOffset;
+ mBoundAttributesMask = binding.mBoundAttributesMask;
+ std::swap(binding.mBuffer, mBuffer);
+ }
+ return *this;
+}
+
+void VertexBinding::onContainerBindingChanged(const Context *context, int incr) const
+{
+ if (mBuffer.get())
+ mBuffer->onNonTFBindingChanged(incr);
+}
+
+VertexAttribute::VertexAttribute(GLuint bindingIndex)
+ : enabled(false),
+ format(&angle::Format::Get(angle::FormatID::R32G32B32A32_FLOAT)),
+ pointer(nullptr),
+ relativeOffset(0),
+ vertexAttribArrayStride(0),
+ bindingIndex(bindingIndex),
+ mCachedElementLimit(0)
+{}
+
+VertexAttribute::VertexAttribute(VertexAttribute &&attrib)
+ : enabled(attrib.enabled),
+ format(attrib.format),
+ pointer(attrib.pointer),
+ relativeOffset(attrib.relativeOffset),
+ vertexAttribArrayStride(attrib.vertexAttribArrayStride),
+ bindingIndex(attrib.bindingIndex),
+ mCachedElementLimit(attrib.mCachedElementLimit)
+{}
+
+VertexAttribute &VertexAttribute::operator=(VertexAttribute &&attrib)
+{
+ if (this != &attrib)
+ {
+ enabled = attrib.enabled;
+ format = attrib.format;
+ pointer = attrib.pointer;
+ relativeOffset = attrib.relativeOffset;
+ vertexAttribArrayStride = attrib.vertexAttribArrayStride;
+ bindingIndex = attrib.bindingIndex;
+ mCachedElementLimit = attrib.mCachedElementLimit;
+ }
+ return *this;
+}
+
+void VertexAttribute::updateCachedElementLimit(const VertexBinding &binding)
+{
+ Buffer *buffer = binding.getBuffer().get();
+ if (!buffer)
+ {
+ mCachedElementLimit = 0;
+ return;
+ }
+
+ angle::CheckedNumeric<GLint64> bufferSize(buffer->getSize());
+ angle::CheckedNumeric<GLint64> bufferOffset(binding.getOffset());
+ angle::CheckedNumeric<GLint64> attribOffset(relativeOffset);
+ angle::CheckedNumeric<GLint64> attribSize(ComputeVertexAttributeTypeSize(*this));
+
+ // (buffer.size - buffer.offset - attrib.relativeOffset - attrib.size) / binding.stride
+ angle::CheckedNumeric<GLint64> elementLimit =
+ (bufferSize - bufferOffset - attribOffset - attribSize);
+
+ // Use the special integer overflow value if there was a math error.
+ if (!elementLimit.IsValid())
+ {
+ static_assert(kIntegerOverflow < 0, "Unexpected value");
+ mCachedElementLimit = kIntegerOverflow;
+ return;
+ }
+
+ mCachedElementLimit = elementLimit.ValueOrDie();
+ if (mCachedElementLimit < 0)
+ {
+ return;
+ }
+
+ if (binding.getStride() == 0)
+ {
+ // Special case for a zero stride. If we can fit one vertex we can fit infinite vertices.
+ mCachedElementLimit = std::numeric_limits<GLint64>::max();
+ return;
+ }
+
+ angle::CheckedNumeric<GLint64> bindingStride(binding.getStride());
+ elementLimit /= bindingStride;
+
+ if (binding.getDivisor() > 0)
+ {
+ // For instanced draws, the element count is floor(instanceCount - 1) / binding.divisor.
+ angle::CheckedNumeric<GLint64> bindingDivisor(binding.getDivisor());
+ elementLimit *= bindingDivisor;
+
+ // We account for the floor() part rounding by adding a rounding constant.
+ elementLimit += bindingDivisor - 1;
+ }
+
+ mCachedElementLimit = elementLimit.ValueOrDefault(kIntegerOverflow);
+}
+
+size_t ComputeVertexAttributeStride(const VertexAttribute &attrib, const VertexBinding &binding)
+{
+ // In ES 3.1, VertexAttribPointer will store the type size in the binding stride.
+ // Hence, rendering always uses the binding's stride.
+ return attrib.enabled ? binding.getStride() : 16u;
+}
+
+// Warning: you should ensure binding really matches attrib.bindingIndex before using this function.
+GLintptr ComputeVertexAttributeOffset(const VertexAttribute &attrib, const VertexBinding &binding)
+{
+ return attrib.relativeOffset + binding.getOffset();
+}
+
+size_t ComputeVertexBindingElementCount(GLuint divisor, size_t drawCount, size_t instanceCount)
+{
+ // For instanced rendering, we draw "instanceDrawCount" sets of "vertexDrawCount" vertices.
+ //
+ // A vertex attribute with a positive divisor loads one instanced vertex for every set of
+ // non-instanced vertices, and the instanced vertex index advances once every "mDivisor"
+ // instances.
+ if (instanceCount > 0 && divisor > 0)
+ {
+ // When instanceDrawCount is not a multiple attrib.divisor, the division must round up.
+ // For instance, with 5 non-instanced vertices and a divisor equal to 3, we need 2 instanced
+ // vertices.
+ return (instanceCount + divisor - 1u) / divisor;
+ }
+
+ return drawCount;
+}
+
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/VertexAttribute.h b/gfx/angle/checkout/src/libANGLE/VertexAttribute.h
new file mode 100644
index 0000000000..dd89228d2a
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/VertexAttribute.h
@@ -0,0 +1,139 @@
+//
+// Copyright 2013 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 structures about Generic Vertex Attribute.
+//
+
+#ifndef LIBANGLE_VERTEXATTRIBUTE_H_
+#define LIBANGLE_VERTEXATTRIBUTE_H_
+
+#include "libANGLE/Buffer.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/renderer/Format.h"
+
+namespace gl
+{
+class VertexArray;
+
+//
+// Implementation of Generic Vertex Attribute Bindings for ES3.1. The members are intentionally made
+// private in order to hide implementation details.
+//
+class VertexBinding final : angle::NonCopyable
+{
+ public:
+ VertexBinding();
+ explicit VertexBinding(GLuint boundAttribute);
+ VertexBinding(VertexBinding &&binding);
+ ~VertexBinding();
+ VertexBinding &operator=(VertexBinding &&binding);
+
+ GLuint getStride() const { return mStride; }
+ void setStride(GLuint strideIn) { mStride = strideIn; }
+
+ GLuint getDivisor() const { return mDivisor; }
+ void setDivisor(GLuint divisorIn) { mDivisor = divisorIn; }
+
+ GLintptr getOffset() const { return mOffset; }
+ void setOffset(GLintptr offsetIn) { mOffset = offsetIn; }
+
+ const BindingPointer<Buffer> &getBuffer() const { return mBuffer; }
+
+ ANGLE_INLINE void setBuffer(const gl::Context *context, Buffer *bufferIn)
+ {
+ mBuffer.set(context, bufferIn);
+ }
+
+ // Skips ref counting for better inlined performance.
+ ANGLE_INLINE void assignBuffer(Buffer *bufferIn) { mBuffer.assign(bufferIn); }
+
+ void onContainerBindingChanged(const Context *context, int incr) const;
+
+ const AttributesMask &getBoundAttributesMask() const { return mBoundAttributesMask; }
+
+ void setBoundAttribute(size_t index) { mBoundAttributesMask.set(index); }
+
+ void resetBoundAttribute(size_t index) { mBoundAttributesMask.reset(index); }
+
+ private:
+ GLuint mStride;
+ GLuint mDivisor;
+ GLintptr mOffset;
+
+ BindingPointer<Buffer> mBuffer;
+
+ // Mapping from this binding to all of the attributes that are using this binding.
+ AttributesMask mBoundAttributesMask;
+};
+
+//
+// Implementation of Generic Vertex Attributes for ES3.1
+//
+struct VertexAttribute final : private angle::NonCopyable
+{
+ explicit VertexAttribute(GLuint bindingIndex);
+ VertexAttribute(VertexAttribute &&attrib);
+ VertexAttribute &operator=(VertexAttribute &&attrib);
+
+ // Called from VertexArray.
+ void updateCachedElementLimit(const VertexBinding &binding);
+ GLint64 getCachedElementLimit() const { return mCachedElementLimit; }
+
+ bool enabled; // For glEnable/DisableVertexAttribArray
+ const angle::Format *format;
+
+ const void *pointer;
+ GLuint relativeOffset;
+
+ GLuint vertexAttribArrayStride; // ONLY for queries of VERTEX_ATTRIB_ARRAY_STRIDE
+ GLuint bindingIndex;
+
+ // Special value for the cached element limit on the integer overflow case.
+ static constexpr GLint64 kIntegerOverflow = std::numeric_limits<GLint64>::min();
+
+ private:
+ // This is kept in sync by the VertexArray. It is used to optimize draw call validation.
+ GLint64 mCachedElementLimit;
+};
+
+ANGLE_INLINE size_t ComputeVertexAttributeTypeSize(const VertexAttribute &attrib)
+{
+ ASSERT(attrib.format);
+ return attrib.format->pixelBytes;
+}
+
+// Warning: you should ensure binding really matches attrib.bindingIndex before using this function.
+size_t ComputeVertexAttributeStride(const VertexAttribute &attrib, const VertexBinding &binding);
+
+// Warning: you should ensure binding really matches attrib.bindingIndex before using this function.
+GLintptr ComputeVertexAttributeOffset(const VertexAttribute &attrib, const VertexBinding &binding);
+
+size_t ComputeVertexBindingElementCount(GLuint divisor, size_t drawCount, size_t instanceCount);
+
+struct VertexAttribCurrentValueData
+{
+ union
+ {
+ GLfloat FloatValues[4];
+ GLint IntValues[4];
+ GLuint UnsignedIntValues[4];
+ } Values;
+ VertexAttribType Type;
+
+ VertexAttribCurrentValueData();
+
+ void setFloatValues(const GLfloat floatValues[4]);
+ void setIntValues(const GLint intValues[4]);
+ void setUnsignedIntValues(const GLuint unsignedIntValues[4]);
+};
+
+bool operator==(const VertexAttribCurrentValueData &a, const VertexAttribCurrentValueData &b);
+bool operator!=(const VertexAttribCurrentValueData &a, const VertexAttribCurrentValueData &b);
+
+} // namespace gl
+
+#include "VertexAttribute.inc"
+
+#endif // LIBANGLE_VERTEXATTRIBUTE_H_
diff --git a/gfx/angle/checkout/src/libANGLE/VertexAttribute.inc b/gfx/angle/checkout/src/libANGLE/VertexAttribute.inc
new file mode 100644
index 0000000000..0c98f091b9
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/VertexAttribute.inc
@@ -0,0 +1,58 @@
+//
+// 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.
+//
+// VertexAttribute.inc: Inline vertex attribute methods
+//
+
+namespace gl
+{
+
+inline VertexAttribCurrentValueData::VertexAttribCurrentValueData()
+ : Type(gl::VertexAttribType::Float)
+{
+ Values.FloatValues[0] = 0.0f;
+ Values.FloatValues[1] = 0.0f;
+ Values.FloatValues[2] = 0.0f;
+ Values.FloatValues[3] = 1.0f;
+}
+
+inline void VertexAttribCurrentValueData::setFloatValues(const GLfloat floatValues[4])
+{
+ for (unsigned int valueIndex = 0; valueIndex < 4; valueIndex++)
+ {
+ Values.FloatValues[valueIndex] = floatValues[valueIndex];
+ }
+ Type = gl::VertexAttribType::Float;
+}
+
+inline void VertexAttribCurrentValueData::setIntValues(const GLint intValues[4])
+{
+ for (unsigned int valueIndex = 0; valueIndex < 4; valueIndex++)
+ {
+ Values.IntValues[valueIndex] = intValues[valueIndex];
+ }
+ Type = gl::VertexAttribType::Int;
+}
+
+inline void VertexAttribCurrentValueData::setUnsignedIntValues(const GLuint unsignedIntValues[4])
+{
+ for (unsigned int valueIndex = 0; valueIndex < 4; valueIndex++)
+ {
+ Values.UnsignedIntValues[valueIndex] = unsignedIntValues[valueIndex];
+ }
+ Type = gl::VertexAttribType::UnsignedInt;
+}
+
+inline bool operator==(const VertexAttribCurrentValueData &a, const VertexAttribCurrentValueData &b)
+{
+ return (a.Type == b.Type && memcmp(&a.Values, &b.Values, sizeof(VertexAttribCurrentValueData::Values)) == 0);
+}
+
+inline bool operator!=(const VertexAttribCurrentValueData &a, const VertexAttribCurrentValueData &b)
+{
+ return !(a == b);
+}
+
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/WorkerThread.cpp b/gfx/angle/checkout/src/libANGLE/WorkerThread.cpp
new file mode 100644
index 0000000000..30c454dd26
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/WorkerThread.cpp
@@ -0,0 +1,356 @@
+//
+// 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.
+//
+// WorkerThread:
+// Task running thread for ANGLE, similar to a TaskRunner in Chromium.
+// Might be implemented differently depending on platform.
+//
+
+#include "libANGLE/WorkerThread.h"
+
+#include "libANGLE/trace.h"
+
+#if (ANGLE_DELEGATE_WORKERS == ANGLE_ENABLED) || (ANGLE_STD_ASYNC_WORKERS == ANGLE_ENABLED)
+# include <condition_variable>
+# include <future>
+# include <mutex>
+# include <queue>
+# include <thread>
+#endif // (ANGLE_DELEGATE_WORKERS == ANGLE_ENABLED) || (ANGLE_STD_ASYNC_WORKERS == ANGLE_ENABLED)
+
+namespace angle
+{
+
+WaitableEvent::WaitableEvent() = default;
+WaitableEvent::~WaitableEvent() = default;
+
+void WaitableEventDone::wait() {}
+
+bool WaitableEventDone::isReady()
+{
+ return true;
+}
+
+WorkerThreadPool::WorkerThreadPool() = default;
+WorkerThreadPool::~WorkerThreadPool() = default;
+
+class SingleThreadedWaitableEvent final : public WaitableEvent
+{
+ public:
+ SingleThreadedWaitableEvent() = default;
+ ~SingleThreadedWaitableEvent() override = default;
+
+ void wait() override;
+ bool isReady() override;
+};
+
+void SingleThreadedWaitableEvent::wait() {}
+
+bool SingleThreadedWaitableEvent::isReady()
+{
+ return true;
+}
+
+class SingleThreadedWorkerPool final : public WorkerThreadPool
+{
+ public:
+ std::shared_ptr<WaitableEvent> postWorkerTask(std::shared_ptr<Closure> task) override;
+ void setMaxThreads(size_t maxThreads) override;
+ bool isAsync() override;
+};
+
+// SingleThreadedWorkerPool implementation.
+std::shared_ptr<WaitableEvent> SingleThreadedWorkerPool::postWorkerTask(
+ std::shared_ptr<Closure> task)
+{
+ (*task)();
+ return std::make_shared<SingleThreadedWaitableEvent>();
+}
+
+void SingleThreadedWorkerPool::setMaxThreads(size_t maxThreads) {}
+
+bool SingleThreadedWorkerPool::isAsync()
+{
+ return false;
+}
+
+#if (ANGLE_STD_ASYNC_WORKERS == ANGLE_ENABLED)
+class AsyncWaitableEvent final : public WaitableEvent
+{
+ public:
+ AsyncWaitableEvent() : mIsPending(true) {}
+ ~AsyncWaitableEvent() override = default;
+
+ void wait() override;
+ bool isReady() override;
+
+ private:
+ friend class AsyncWorkerPool;
+ void setFuture(std::future<void> &&future);
+
+ // To block wait() when the task is still in queue to be run.
+ // Also to protect the concurrent accesses from both main thread and
+ // background threads to the member fields.
+ std::mutex mMutex;
+
+ bool mIsPending;
+ std::condition_variable mCondition;
+ std::future<void> mFuture;
+};
+
+void AsyncWaitableEvent::setFuture(std::future<void> &&future)
+{
+ mFuture = std::move(future);
+}
+
+void AsyncWaitableEvent::wait()
+{
+ ANGLE_TRACE_EVENT0("gpu.angle", "AsyncWaitableEvent::wait");
+ {
+ std::unique_lock<std::mutex> lock(mMutex);
+ mCondition.wait(lock, [this] { return !mIsPending; });
+ }
+
+ ASSERT(mFuture.valid());
+ mFuture.wait();
+}
+
+bool AsyncWaitableEvent::isReady()
+{
+ std::lock_guard<std::mutex> lock(mMutex);
+ if (mIsPending)
+ {
+ return false;
+ }
+ ASSERT(mFuture.valid());
+ return mFuture.wait_for(std::chrono::seconds(0)) == std::future_status::ready;
+}
+
+class AsyncWorkerPool final : public WorkerThreadPool
+{
+ public:
+ AsyncWorkerPool(size_t maxThreads) : mMaxThreads(maxThreads), mRunningThreads(0) {}
+ ~AsyncWorkerPool() override = default;
+
+ std::shared_ptr<WaitableEvent> postWorkerTask(std::shared_ptr<Closure> task) override;
+ void setMaxThreads(size_t maxThreads) override;
+ bool isAsync() override;
+
+ private:
+ void checkToRunPendingTasks();
+
+ // To protect the concurrent accesses from both main thread and background
+ // threads to the member fields.
+ std::mutex mMutex;
+
+ size_t mMaxThreads;
+ size_t mRunningThreads;
+ std::queue<std::pair<std::shared_ptr<AsyncWaitableEvent>, std::shared_ptr<Closure>>> mTaskQueue;
+};
+
+// AsyncWorkerPool implementation.
+std::shared_ptr<WaitableEvent> AsyncWorkerPool::postWorkerTask(std::shared_ptr<Closure> task)
+{
+ ASSERT(mMaxThreads > 0);
+
+ auto waitable = std::make_shared<AsyncWaitableEvent>();
+ {
+ std::lock_guard<std::mutex> lock(mMutex);
+ mTaskQueue.push(std::make_pair(waitable, task));
+ }
+ checkToRunPendingTasks();
+ return std::move(waitable);
+}
+
+void AsyncWorkerPool::setMaxThreads(size_t maxThreads)
+{
+ {
+ std::lock_guard<std::mutex> lock(mMutex);
+ mMaxThreads = (maxThreads == 0xFFFFFFFF ? std::thread::hardware_concurrency() : maxThreads);
+ }
+ checkToRunPendingTasks();
+}
+
+bool AsyncWorkerPool::isAsync()
+{
+ return true;
+}
+
+void AsyncWorkerPool::checkToRunPendingTasks()
+{
+ std::lock_guard<std::mutex> lock(mMutex);
+ while (mRunningThreads < mMaxThreads && !mTaskQueue.empty())
+ {
+ auto task = mTaskQueue.front();
+ mTaskQueue.pop();
+ auto waitable = task.first;
+ auto closure = task.second;
+
+ auto future = std::async(std::launch::async, [closure, this] {
+ {
+ ANGLE_TRACE_EVENT0("gpu.angle", "AsyncWorkerPool::RunTask");
+ (*closure)();
+ }
+ {
+ std::lock_guard<std::mutex> lock(mMutex);
+ ASSERT(mRunningThreads != 0);
+ --mRunningThreads;
+ }
+ checkToRunPendingTasks();
+ });
+
+ ++mRunningThreads;
+
+ {
+ std::lock_guard<std::mutex> waitableLock(waitable->mMutex);
+ waitable->mIsPending = false;
+ waitable->setFuture(std::move(future));
+ }
+ waitable->mCondition.notify_all();
+ }
+}
+#endif // (ANGLE_STD_ASYNC_WORKERS == ANGLE_ENABLED)
+
+#if (ANGLE_DELEGATE_WORKERS == ANGLE_ENABLED)
+class DelegateWaitableEvent final : public WaitableEvent
+{
+ public:
+ DelegateWaitableEvent() = default;
+ ~DelegateWaitableEvent() override = default;
+
+ void wait() override;
+ bool isReady() override;
+
+ void markAsReady();
+
+ private:
+ // To protect the concurrent accesses from both main thread and background
+ // threads to the member fields.
+ std::mutex mMutex;
+
+ bool mIsReady = false;
+ std::condition_variable mCondition;
+};
+
+void DelegateWaitableEvent::markAsReady()
+{
+ std::lock_guard<std::mutex> lock(mMutex);
+ mIsReady = true;
+ mCondition.notify_all();
+}
+
+void DelegateWaitableEvent::wait()
+{
+ std::unique_lock<std::mutex> lock(mMutex);
+ mCondition.wait(lock, [this] { return mIsReady; });
+}
+
+bool DelegateWaitableEvent::isReady()
+{
+ std::lock_guard<std::mutex> lock(mMutex);
+ return mIsReady;
+}
+
+class DelegateWorkerPool final : public WorkerThreadPool
+{
+ public:
+ DelegateWorkerPool() = default;
+ ~DelegateWorkerPool() override = default;
+
+ std::shared_ptr<WaitableEvent> postWorkerTask(std::shared_ptr<Closure> task) override;
+
+ void setMaxThreads(size_t maxThreads) override;
+ bool isAsync() override;
+};
+
+// A function wrapper to execute the closure and to notify the waitable
+// event after the execution.
+class DelegateWorkerTask
+{
+ public:
+ DelegateWorkerTask(std::shared_ptr<Closure> task,
+ std::shared_ptr<DelegateWaitableEvent> waitable)
+ : mTask(task), mWaitable(waitable)
+ {}
+ DelegateWorkerTask() = delete;
+ DelegateWorkerTask(DelegateWorkerTask &) = delete;
+
+ static void RunTask(void *userData)
+ {
+ DelegateWorkerTask *workerTask = static_cast<DelegateWorkerTask *>(userData);
+ (*workerTask->mTask)();
+ workerTask->mWaitable->markAsReady();
+
+ // Delete the task after its execution.
+ delete workerTask;
+ }
+
+ private:
+ ~DelegateWorkerTask() = default;
+
+ std::shared_ptr<Closure> mTask;
+ std::shared_ptr<DelegateWaitableEvent> mWaitable;
+};
+
+std::shared_ptr<WaitableEvent> DelegateWorkerPool::postWorkerTask(std::shared_ptr<Closure> task)
+{
+ auto waitable = std::make_shared<DelegateWaitableEvent>();
+
+ // The task will be deleted by DelegateWorkerTask::RunTask(...) after its execution.
+ DelegateWorkerTask *workerTask = new DelegateWorkerTask(task, waitable);
+ auto *platform = ANGLEPlatformCurrent();
+ platform->postWorkerTask(platform, DelegateWorkerTask::RunTask, workerTask);
+
+ return std::move(waitable);
+}
+
+void DelegateWorkerPool::setMaxThreads(size_t maxThreads) {}
+
+bool DelegateWorkerPool::isAsync()
+{
+ return true;
+}
+#endif
+
+// static
+std::shared_ptr<WorkerThreadPool> WorkerThreadPool::Create(bool multithreaded)
+{
+ std::shared_ptr<WorkerThreadPool> pool(nullptr);
+
+#if (ANGLE_DELEGATE_WORKERS == ANGLE_ENABLED)
+ const bool hasPostWorkerTaskImpl = ANGLEPlatformCurrent()->postWorkerTask;
+ if (hasPostWorkerTaskImpl && multithreaded)
+ {
+ pool = std::shared_ptr<WorkerThreadPool>(new DelegateWorkerPool());
+ }
+#endif
+#if (ANGLE_STD_ASYNC_WORKERS == ANGLE_ENABLED)
+ if (!pool && multithreaded)
+ {
+ pool = std::shared_ptr<WorkerThreadPool>(
+ new AsyncWorkerPool(std::thread::hardware_concurrency()));
+ }
+#endif
+ if (!pool)
+ {
+ return std::shared_ptr<WorkerThreadPool>(new SingleThreadedWorkerPool());
+ }
+ return pool;
+}
+
+// static
+std::shared_ptr<WaitableEvent> WorkerThreadPool::PostWorkerTask(
+ std::shared_ptr<WorkerThreadPool> pool,
+ std::shared_ptr<Closure> task)
+{
+ std::shared_ptr<WaitableEvent> event = pool->postWorkerTask(task);
+ if (event.get())
+ {
+ event->setWorkerThreadPool(pool);
+ }
+ return event;
+}
+
+} // namespace angle
diff --git a/gfx/angle/checkout/src/libANGLE/WorkerThread.h b/gfx/angle/checkout/src/libANGLE/WorkerThread.h
new file mode 100644
index 0000000000..6ef94fcc5b
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/WorkerThread.h
@@ -0,0 +1,94 @@
+//
+// 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.
+//
+// WorkerThread:
+// Asychronous tasks/threads for ANGLE, similar to a TaskRunner in Chromium.
+// Can be implemented as different targets, depending on platform.
+//
+
+#ifndef LIBANGLE_WORKER_THREAD_H_
+#define LIBANGLE_WORKER_THREAD_H_
+
+#include <array>
+#include <memory>
+#include <vector>
+
+#include "common/debug.h"
+#include "libANGLE/features.h"
+
+namespace angle
+{
+
+class WorkerThreadPool;
+
+// A callback function with no return value and no arguments.
+class Closure
+{
+ public:
+ virtual ~Closure() = default;
+ virtual void operator()() = 0;
+};
+
+// An event that we can wait on, useful for joining worker threads.
+class WaitableEvent : angle::NonCopyable
+{
+ public:
+ WaitableEvent();
+ virtual ~WaitableEvent();
+
+ // Waits indefinitely for the event to be signaled.
+ virtual void wait() = 0;
+
+ // Peeks whether the event is ready. If ready, wait() will not block.
+ virtual bool isReady() = 0;
+ void setWorkerThreadPool(std::shared_ptr<WorkerThreadPool> pool) { mPool = pool; }
+
+ template <size_t Count>
+ static void WaitMany(std::array<std::shared_ptr<WaitableEvent>, Count> *waitables)
+ {
+ ASSERT(Count > 0);
+ for (size_t index = 0; index < Count; ++index)
+ {
+ (*waitables)[index]->wait();
+ }
+ }
+
+ private:
+ std::shared_ptr<WorkerThreadPool> mPool;
+};
+
+// A mock waitable event.
+class WaitableEventDone final : public WaitableEvent
+{
+ public:
+ void wait() override;
+ bool isReady() override;
+};
+
+// Request WorkerThreads from the WorkerThreadPool. Each pool can keep worker threads around so
+// we avoid the costly spin up and spin down time.
+class WorkerThreadPool : angle::NonCopyable
+{
+ public:
+ WorkerThreadPool();
+ virtual ~WorkerThreadPool();
+
+ static std::shared_ptr<WorkerThreadPool> Create(bool multithreaded);
+ static std::shared_ptr<WaitableEvent> PostWorkerTask(std::shared_ptr<WorkerThreadPool> pool,
+ std::shared_ptr<Closure> task);
+
+ virtual void setMaxThreads(size_t maxThreads) = 0;
+
+ virtual bool isAsync() = 0;
+
+ private:
+ // Returns an event to wait on for the task to finish.
+ // If the pool fails to create the task, returns null.
+ virtual std::shared_ptr<WaitableEvent> postWorkerTask(std::shared_ptr<Closure> task) = 0;
+};
+
+} // namespace angle
+
+#endif // LIBANGLE_WORKER_THREAD_H_
diff --git a/gfx/angle/checkout/src/libANGLE/angletypes.cpp b/gfx/angle/checkout/src/libANGLE/angletypes.cpp
new file mode 100644
index 0000000000..19f9a25441
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/angletypes.cpp
@@ -0,0 +1,1039 @@
+//
+// Copyright 2013 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.
+//
+
+// angletypes.h : Defines a variety of structures and enum types that are used throughout libGLESv2
+
+#include "libANGLE/angletypes.h"
+#include "libANGLE/Program.h"
+#include "libANGLE/State.h"
+#include "libANGLE/VertexArray.h"
+#include "libANGLE/VertexAttribute.h"
+
+#include <limits>
+
+namespace gl
+{
+namespace
+{
+bool IsStencilNoOp(GLenum stencilFunc,
+ GLenum stencilFail,
+ GLenum stencilPassDepthFail,
+ GLenum stencilPassDepthPass)
+{
+ const bool isNeverAndKeep = stencilFunc == GL_NEVER && stencilFail == GL_KEEP;
+ const bool isAlwaysAndKeepOrAllKeep = (stencilFunc == GL_ALWAYS || stencilFail == GL_KEEP) &&
+ stencilPassDepthFail == GL_KEEP &&
+ stencilPassDepthPass == GL_KEEP;
+
+ return isNeverAndKeep || isAlwaysAndKeepOrAllKeep;
+}
+
+// Calculate whether the range [outsideLow, outsideHigh] encloses the range [insideLow, insideHigh]
+bool EnclosesRange(int outsideLow, int outsideHigh, int insideLow, int insideHigh)
+{
+ return outsideLow <= insideLow && outsideHigh >= insideHigh;
+}
+
+bool IsAdvancedBlendEquation(gl::BlendEquationType blendEquation)
+{
+ return blendEquation >= gl::BlendEquationType::Multiply &&
+ blendEquation <= gl::BlendEquationType::HslLuminosity;
+}
+} // anonymous namespace
+
+RasterizerState::RasterizerState()
+{
+ memset(this, 0, sizeof(RasterizerState));
+
+ rasterizerDiscard = false;
+ cullFace = false;
+ cullMode = CullFaceMode::Back;
+ frontFace = GL_CCW;
+ polygonOffsetFill = false;
+ polygonOffsetFactor = 0.0f;
+ polygonOffsetUnits = 0.0f;
+ pointDrawMode = false;
+ multiSample = false;
+ dither = true;
+}
+
+RasterizerState::RasterizerState(const RasterizerState &other)
+{
+ memcpy(this, &other, sizeof(RasterizerState));
+}
+
+RasterizerState &RasterizerState::operator=(const RasterizerState &other)
+{
+ memcpy(this, &other, sizeof(RasterizerState));
+ return *this;
+}
+
+bool operator==(const RasterizerState &a, const RasterizerState &b)
+{
+ return memcmp(&a, &b, sizeof(RasterizerState)) == 0;
+}
+
+bool operator!=(const RasterizerState &a, const RasterizerState &b)
+{
+ return !(a == b);
+}
+
+BlendState::BlendState()
+{
+ memset(this, 0, sizeof(BlendState));
+
+ blend = false;
+ sourceBlendRGB = GL_ONE;
+ sourceBlendAlpha = GL_ONE;
+ destBlendRGB = GL_ZERO;
+ destBlendAlpha = GL_ZERO;
+ blendEquationRGB = GL_FUNC_ADD;
+ blendEquationAlpha = GL_FUNC_ADD;
+ colorMaskRed = true;
+ colorMaskGreen = true;
+ colorMaskBlue = true;
+ colorMaskAlpha = true;
+}
+
+BlendState::BlendState(const BlendState &other)
+{
+ memcpy(this, &other, sizeof(BlendState));
+}
+
+bool operator==(const BlendState &a, const BlendState &b)
+{
+ return memcmp(&a, &b, sizeof(BlendState)) == 0;
+}
+
+bool operator!=(const BlendState &a, const BlendState &b)
+{
+ return !(a == b);
+}
+
+DepthStencilState::DepthStencilState()
+{
+ memset(this, 0, sizeof(DepthStencilState));
+
+ depthTest = false;
+ depthFunc = GL_LESS;
+ depthMask = true;
+ stencilTest = false;
+ stencilFunc = GL_ALWAYS;
+ stencilMask = static_cast<GLuint>(-1);
+ stencilWritemask = static_cast<GLuint>(-1);
+ stencilBackFunc = GL_ALWAYS;
+ stencilBackMask = static_cast<GLuint>(-1);
+ stencilBackWritemask = static_cast<GLuint>(-1);
+ stencilFail = GL_KEEP;
+ stencilPassDepthFail = GL_KEEP;
+ stencilPassDepthPass = GL_KEEP;
+ stencilBackFail = GL_KEEP;
+ stencilBackPassDepthFail = GL_KEEP;
+ stencilBackPassDepthPass = GL_KEEP;
+}
+
+DepthStencilState::DepthStencilState(const DepthStencilState &other)
+{
+ memcpy(this, &other, sizeof(DepthStencilState));
+}
+
+DepthStencilState &DepthStencilState::operator=(const DepthStencilState &other)
+{
+ memcpy(this, &other, sizeof(DepthStencilState));
+ return *this;
+}
+
+bool DepthStencilState::isDepthMaskedOut() const
+{
+ return !depthMask;
+}
+
+bool DepthStencilState::isStencilMaskedOut() const
+{
+ return (stencilMask & stencilWritemask) == 0;
+}
+
+bool DepthStencilState::isStencilNoOp() const
+{
+ return isStencilMaskedOut() ||
+ IsStencilNoOp(stencilFunc, stencilFail, stencilPassDepthFail, stencilPassDepthPass);
+}
+
+bool DepthStencilState::isStencilBackNoOp() const
+{
+ const bool isStencilBackMaskedOut = (stencilBackMask & stencilBackWritemask) == 0;
+ return isStencilBackMaskedOut ||
+ IsStencilNoOp(stencilBackFunc, stencilBackFail, stencilBackPassDepthFail,
+ stencilBackPassDepthPass);
+}
+
+bool operator==(const DepthStencilState &a, const DepthStencilState &b)
+{
+ return memcmp(&a, &b, sizeof(DepthStencilState)) == 0;
+}
+
+bool operator!=(const DepthStencilState &a, const DepthStencilState &b)
+{
+ return !(a == b);
+}
+
+SamplerState::SamplerState()
+{
+ memset(this, 0, sizeof(SamplerState));
+
+ setMinFilter(GL_NEAREST_MIPMAP_LINEAR);
+ setMagFilter(GL_LINEAR);
+ setWrapS(GL_REPEAT);
+ setWrapT(GL_REPEAT);
+ setWrapR(GL_REPEAT);
+ setMaxAnisotropy(1.0f);
+ setMinLod(-1000.0f);
+ setMaxLod(1000.0f);
+ setCompareMode(GL_NONE);
+ setCompareFunc(GL_LEQUAL);
+ setSRGBDecode(GL_DECODE_EXT);
+}
+
+SamplerState::SamplerState(const SamplerState &other) = default;
+
+SamplerState &SamplerState::operator=(const SamplerState &other) = default;
+
+// static
+SamplerState SamplerState::CreateDefaultForTarget(TextureType type)
+{
+ SamplerState state;
+
+ // According to OES_EGL_image_external and ARB_texture_rectangle: For external textures, the
+ // default min filter is GL_LINEAR and the default s and t wrap modes are GL_CLAMP_TO_EDGE.
+ if (type == TextureType::External || type == TextureType::Rectangle)
+ {
+ state.mMinFilter = GL_LINEAR;
+ state.mWrapS = GL_CLAMP_TO_EDGE;
+ state.mWrapT = GL_CLAMP_TO_EDGE;
+ }
+
+ return state;
+}
+
+bool SamplerState::setMinFilter(GLenum minFilter)
+{
+ if (mMinFilter != minFilter)
+ {
+ mMinFilter = minFilter;
+ mCompleteness.typed.minFilter = static_cast<uint8_t>(FromGLenum<FilterMode>(minFilter));
+ return true;
+ }
+ return false;
+}
+
+bool SamplerState::setMagFilter(GLenum magFilter)
+{
+ if (mMagFilter != magFilter)
+ {
+ mMagFilter = magFilter;
+ mCompleteness.typed.magFilter = static_cast<uint8_t>(FromGLenum<FilterMode>(magFilter));
+ return true;
+ }
+ return false;
+}
+
+bool SamplerState::setWrapS(GLenum wrapS)
+{
+ if (mWrapS != wrapS)
+ {
+ mWrapS = wrapS;
+ mCompleteness.typed.wrapS = static_cast<uint8_t>(FromGLenum<WrapMode>(wrapS));
+ return true;
+ }
+ return false;
+}
+
+bool SamplerState::setWrapT(GLenum wrapT)
+{
+ if (mWrapT != wrapT)
+ {
+ mWrapT = wrapT;
+ updateWrapTCompareMode();
+ return true;
+ }
+ return false;
+}
+
+bool SamplerState::setWrapR(GLenum wrapR)
+{
+ if (mWrapR != wrapR)
+ {
+ mWrapR = wrapR;
+ return true;
+ }
+ return false;
+}
+
+bool SamplerState::setMaxAnisotropy(float maxAnisotropy)
+{
+ if (mMaxAnisotropy != maxAnisotropy)
+ {
+ mMaxAnisotropy = maxAnisotropy;
+ return true;
+ }
+ return false;
+}
+
+bool SamplerState::setMinLod(GLfloat minLod)
+{
+ if (mMinLod != minLod)
+ {
+ mMinLod = minLod;
+ return true;
+ }
+ return false;
+}
+
+bool SamplerState::setMaxLod(GLfloat maxLod)
+{
+ if (mMaxLod != maxLod)
+ {
+ mMaxLod = maxLod;
+ return true;
+ }
+ return false;
+}
+
+bool SamplerState::setCompareMode(GLenum compareMode)
+{
+ if (mCompareMode != compareMode)
+ {
+ mCompareMode = compareMode;
+ updateWrapTCompareMode();
+ return true;
+ }
+ return false;
+}
+
+bool SamplerState::setCompareFunc(GLenum compareFunc)
+{
+ if (mCompareFunc != compareFunc)
+ {
+ mCompareFunc = compareFunc;
+ return true;
+ }
+ return false;
+}
+
+bool SamplerState::setSRGBDecode(GLenum sRGBDecode)
+{
+ if (mSRGBDecode != sRGBDecode)
+ {
+ mSRGBDecode = sRGBDecode;
+ return true;
+ }
+ return false;
+}
+
+bool SamplerState::setBorderColor(const ColorGeneric &color)
+{
+ if (mBorderColor != color)
+ {
+ mBorderColor = color;
+ return true;
+ }
+ return false;
+}
+
+void SamplerState::updateWrapTCompareMode()
+{
+ uint8_t wrap = static_cast<uint8_t>(FromGLenum<WrapMode>(mWrapT));
+ uint8_t compare = static_cast<uint8_t>(mCompareMode == GL_NONE ? 0x10 : 0x00);
+ mCompleteness.typed.wrapTCompareMode = wrap | compare;
+}
+
+ImageUnit::ImageUnit()
+ : texture(), level(0), layered(false), layer(0), access(GL_READ_ONLY), format(GL_R32UI)
+{}
+
+ImageUnit::ImageUnit(const ImageUnit &other) = default;
+
+ImageUnit::~ImageUnit() = default;
+
+BlendStateExt::BlendStateExt(const size_t drawBufferCount)
+ : mParameterMask(FactorStorage::GetMask(drawBufferCount)),
+ mSrcColor(FactorStorage::GetReplicatedValue(BlendFactorType::One, mParameterMask)),
+ mDstColor(FactorStorage::GetReplicatedValue(BlendFactorType::Zero, mParameterMask)),
+ mSrcAlpha(FactorStorage::GetReplicatedValue(BlendFactorType::One, mParameterMask)),
+ mDstAlpha(FactorStorage::GetReplicatedValue(BlendFactorType::Zero, mParameterMask)),
+ mEquationColor(EquationStorage::GetReplicatedValue(BlendEquationType::Add, mParameterMask)),
+ mEquationAlpha(EquationStorage::GetReplicatedValue(BlendEquationType::Add, mParameterMask)),
+ mAllColorMask(
+ ColorMaskStorage::GetReplicatedValue(PackColorMask(true, true, true, true),
+ ColorMaskStorage::GetMask(drawBufferCount))),
+ mColorMask(mAllColorMask),
+ mAllEnabledMask(0xFF >> (8 - drawBufferCount)),
+ mDrawBufferCount(drawBufferCount)
+{}
+
+BlendStateExt::BlendStateExt(const BlendStateExt &other) = default;
+
+BlendStateExt &BlendStateExt::operator=(const BlendStateExt &other) = default;
+
+void BlendStateExt::setEnabled(const bool enabled)
+{
+ mEnabledMask = enabled ? mAllEnabledMask : DrawBufferMask::Zero();
+}
+
+void BlendStateExt::setEnabledIndexed(const size_t index, const bool enabled)
+{
+ ASSERT(index < mDrawBufferCount);
+ mEnabledMask.set(index, enabled);
+}
+
+BlendStateExt::ColorMaskStorage::Type BlendStateExt::expandColorMaskValue(const bool red,
+ const bool green,
+ const bool blue,
+ const bool alpha) const
+{
+ return BlendStateExt::ColorMaskStorage::GetReplicatedValue(
+ PackColorMask(red, green, blue, alpha), mAllColorMask);
+}
+
+BlendStateExt::ColorMaskStorage::Type BlendStateExt::expandColorMaskIndexed(
+ const size_t index) const
+{
+ return ColorMaskStorage::GetReplicatedValue(
+ ColorMaskStorage::GetValueIndexed(index, mColorMask), mAllColorMask);
+}
+
+void BlendStateExt::setColorMask(const bool red,
+ const bool green,
+ const bool blue,
+ const bool alpha)
+{
+ mColorMask = expandColorMaskValue(red, green, blue, alpha);
+}
+
+void BlendStateExt::setColorMaskIndexed(const size_t index, const uint8_t value)
+{
+ ASSERT(index < mDrawBufferCount);
+ ASSERT(value <= 0xF);
+ ColorMaskStorage::SetValueIndexed(index, value, &mColorMask);
+}
+
+void BlendStateExt::setColorMaskIndexed(const size_t index,
+ const bool red,
+ const bool green,
+ const bool blue,
+ const bool alpha)
+{
+ ASSERT(index < mDrawBufferCount);
+ ColorMaskStorage::SetValueIndexed(index, PackColorMask(red, green, blue, alpha), &mColorMask);
+}
+
+uint8_t BlendStateExt::getColorMaskIndexed(const size_t index) const
+{
+ ASSERT(index < mDrawBufferCount);
+ return ColorMaskStorage::GetValueIndexed(index, mColorMask);
+}
+
+void BlendStateExt::getColorMaskIndexed(const size_t index,
+ bool *red,
+ bool *green,
+ bool *blue,
+ bool *alpha) const
+{
+ ASSERT(index < mDrawBufferCount);
+ UnpackColorMask(ColorMaskStorage::GetValueIndexed(index, mColorMask), red, green, blue, alpha);
+}
+
+DrawBufferMask BlendStateExt::compareColorMask(ColorMaskStorage::Type other) const
+{
+ return ColorMaskStorage::GetDiffMask(mColorMask, other);
+}
+
+BlendStateExt::EquationStorage::Type BlendStateExt::expandEquationValue(const GLenum mode) const
+{
+ return EquationStorage::GetReplicatedValue(FromGLenum<BlendEquationType>(mode), mParameterMask);
+}
+
+BlendStateExt::EquationStorage::Type BlendStateExt::expandEquationValue(
+ const gl::BlendEquationType equation) const
+{
+ return EquationStorage::GetReplicatedValue(equation, mParameterMask);
+}
+
+BlendStateExt::EquationStorage::Type BlendStateExt::expandEquationColorIndexed(
+ const size_t index) const
+{
+ return EquationStorage::GetReplicatedValue(
+ EquationStorage::GetValueIndexed(index, mEquationColor), mParameterMask);
+}
+
+BlendStateExt::EquationStorage::Type BlendStateExt::expandEquationAlphaIndexed(
+ const size_t index) const
+{
+ return EquationStorage::GetReplicatedValue(
+ EquationStorage::GetValueIndexed(index, mEquationAlpha), mParameterMask);
+}
+
+void BlendStateExt::setEquations(const GLenum modeColor, const GLenum modeAlpha)
+{
+ const gl::BlendEquationType colorEquation = FromGLenum<BlendEquationType>(modeColor);
+ const gl::BlendEquationType alphaEquation = FromGLenum<BlendEquationType>(modeAlpha);
+
+ mEquationColor = expandEquationValue(colorEquation);
+ mEquationAlpha = expandEquationValue(alphaEquation);
+
+ // Note that advanced blend equations cannot be independently set for color and alpha, so only
+ // the color equation can be checked.
+ if (IsAdvancedBlendEquation(colorEquation))
+ {
+ mUsesAdvancedBlendEquationMask = mAllEnabledMask;
+ }
+ else
+ {
+ mUsesAdvancedBlendEquationMask.reset();
+ }
+}
+
+void BlendStateExt::setEquationsIndexed(const size_t index,
+ const GLenum modeColor,
+ const GLenum modeAlpha)
+{
+ ASSERT(index < mDrawBufferCount);
+
+ const gl::BlendEquationType colorEquation = FromGLenum<BlendEquationType>(modeColor);
+ const gl::BlendEquationType alphaEquation = FromGLenum<BlendEquationType>(modeAlpha);
+
+ EquationStorage::SetValueIndexed(index, colorEquation, &mEquationColor);
+ EquationStorage::SetValueIndexed(index, alphaEquation, &mEquationAlpha);
+
+ mUsesAdvancedBlendEquationMask.set(index, IsAdvancedBlendEquation(colorEquation));
+}
+
+void BlendStateExt::setEquationsIndexed(const size_t index,
+ const size_t sourceIndex,
+ const BlendStateExt &source)
+{
+ ASSERT(index < mDrawBufferCount);
+ ASSERT(sourceIndex < source.mDrawBufferCount);
+
+ const gl::BlendEquationType colorEquation =
+ EquationStorage::GetValueIndexed(sourceIndex, source.mEquationColor);
+ const gl::BlendEquationType alphaEquation =
+ EquationStorage::GetValueIndexed(sourceIndex, source.mEquationAlpha);
+
+ EquationStorage::SetValueIndexed(index, colorEquation, &mEquationColor);
+ EquationStorage::SetValueIndexed(index, alphaEquation, &mEquationAlpha);
+
+ mUsesAdvancedBlendEquationMask.set(index, IsAdvancedBlendEquation(colorEquation));
+}
+
+GLenum BlendStateExt::getEquationColorIndexed(size_t index) const
+{
+ ASSERT(index < mDrawBufferCount);
+ return ToGLenum(EquationStorage::GetValueIndexed(index, mEquationColor));
+}
+
+GLenum BlendStateExt::getEquationAlphaIndexed(size_t index) const
+{
+ ASSERT(index < mDrawBufferCount);
+ return ToGLenum(EquationStorage::GetValueIndexed(index, mEquationAlpha));
+}
+
+DrawBufferMask BlendStateExt::compareEquations(const EquationStorage::Type color,
+ const EquationStorage::Type alpha) const
+{
+ return EquationStorage::GetDiffMask(mEquationColor, color) |
+ EquationStorage::GetDiffMask(mEquationAlpha, alpha);
+}
+
+BlendStateExt::FactorStorage::Type BlendStateExt::expandFactorValue(const GLenum func) const
+{
+ return FactorStorage::GetReplicatedValue(FromGLenum<BlendFactorType>(func), mParameterMask);
+}
+
+BlendStateExt::FactorStorage::Type BlendStateExt::expandSrcColorIndexed(const size_t index) const
+{
+ ASSERT(index < mDrawBufferCount);
+ return FactorStorage::GetReplicatedValue(FactorStorage::GetValueIndexed(index, mSrcColor),
+ mParameterMask);
+}
+
+BlendStateExt::FactorStorage::Type BlendStateExt::expandDstColorIndexed(const size_t index) const
+{
+ ASSERT(index < mDrawBufferCount);
+ return FactorStorage::GetReplicatedValue(FactorStorage::GetValueIndexed(index, mDstColor),
+ mParameterMask);
+}
+
+BlendStateExt::FactorStorage::Type BlendStateExt::expandSrcAlphaIndexed(const size_t index) const
+{
+ ASSERT(index < mDrawBufferCount);
+ return FactorStorage::GetReplicatedValue(FactorStorage::GetValueIndexed(index, mSrcAlpha),
+ mParameterMask);
+}
+
+BlendStateExt::FactorStorage::Type BlendStateExt::expandDstAlphaIndexed(const size_t index) const
+{
+ ASSERT(index < mDrawBufferCount);
+ return FactorStorage::GetReplicatedValue(FactorStorage::GetValueIndexed(index, mDstAlpha),
+ mParameterMask);
+}
+
+void BlendStateExt::setFactors(const GLenum srcColor,
+ const GLenum dstColor,
+ const GLenum srcAlpha,
+ const GLenum dstAlpha)
+{
+ mSrcColor = expandFactorValue(srcColor);
+ mDstColor = expandFactorValue(dstColor);
+ mSrcAlpha = expandFactorValue(srcAlpha);
+ mDstAlpha = expandFactorValue(dstAlpha);
+}
+
+void BlendStateExt::setFactorsIndexed(const size_t index,
+ const GLenum srcColor,
+ const GLenum dstColor,
+ const GLenum srcAlpha,
+ const GLenum dstAlpha)
+{
+ ASSERT(index < mDrawBufferCount);
+ FactorStorage::SetValueIndexed(index, FromGLenum<BlendFactorType>(srcColor), &mSrcColor);
+ FactorStorage::SetValueIndexed(index, FromGLenum<BlendFactorType>(dstColor), &mDstColor);
+ FactorStorage::SetValueIndexed(index, FromGLenum<BlendFactorType>(srcAlpha), &mSrcAlpha);
+ FactorStorage::SetValueIndexed(index, FromGLenum<BlendFactorType>(dstAlpha), &mDstAlpha);
+}
+
+void BlendStateExt::setFactorsIndexed(const size_t index,
+ const size_t sourceIndex,
+ const BlendStateExt &source)
+{
+ ASSERT(index < mDrawBufferCount);
+ ASSERT(sourceIndex < source.mDrawBufferCount);
+ FactorStorage::SetValueIndexed(
+ index, FactorStorage::GetValueIndexed(sourceIndex, source.mSrcColor), &mSrcColor);
+ FactorStorage::SetValueIndexed(
+ index, FactorStorage::GetValueIndexed(sourceIndex, source.mDstColor), &mDstColor);
+ FactorStorage::SetValueIndexed(
+ index, FactorStorage::GetValueIndexed(sourceIndex, source.mSrcAlpha), &mSrcAlpha);
+ FactorStorage::SetValueIndexed(
+ index, FactorStorage::GetValueIndexed(sourceIndex, source.mDstAlpha), &mDstAlpha);
+}
+
+GLenum BlendStateExt::getSrcColorIndexed(size_t index) const
+{
+ ASSERT(index < mDrawBufferCount);
+ return ToGLenum(FactorStorage::GetValueIndexed(index, mSrcColor));
+}
+
+GLenum BlendStateExt::getDstColorIndexed(size_t index) const
+{
+ ASSERT(index < mDrawBufferCount);
+ return ToGLenum(FactorStorage::GetValueIndexed(index, mDstColor));
+}
+
+GLenum BlendStateExt::getSrcAlphaIndexed(size_t index) const
+{
+ ASSERT(index < mDrawBufferCount);
+ return ToGLenum(FactorStorage::GetValueIndexed(index, mSrcAlpha));
+}
+
+GLenum BlendStateExt::getDstAlphaIndexed(size_t index) const
+{
+ ASSERT(index < mDrawBufferCount);
+ return ToGLenum(FactorStorage::GetValueIndexed(index, mDstAlpha));
+}
+
+DrawBufferMask BlendStateExt::compareFactors(const FactorStorage::Type srcColor,
+ const FactorStorage::Type dstColor,
+ const FactorStorage::Type srcAlpha,
+ const FactorStorage::Type dstAlpha) const
+{
+ return FactorStorage::GetDiffMask(mSrcColor, srcColor) |
+ FactorStorage::GetDiffMask(mDstColor, dstColor) |
+ FactorStorage::GetDiffMask(mSrcAlpha, srcAlpha) |
+ FactorStorage::GetDiffMask(mDstAlpha, dstAlpha);
+}
+
+static void MinMax(int a, int b, int *minimum, int *maximum)
+{
+ if (a < b)
+ {
+ *minimum = a;
+ *maximum = b;
+ }
+ else
+ {
+ *minimum = b;
+ *maximum = a;
+ }
+}
+
+template <>
+bool RectangleImpl<int>::empty() const
+{
+ return width == 0 && height == 0;
+}
+
+template <>
+bool RectangleImpl<float>::empty() const
+{
+ return std::abs(width) < std::numeric_limits<float>::epsilon() &&
+ std::abs(height) < std::numeric_limits<float>::epsilon();
+}
+
+bool ClipRectangle(const Rectangle &source, const Rectangle &clip, Rectangle *intersection)
+{
+ angle::CheckedNumeric<int> sourceX2(source.x);
+ sourceX2 += source.width;
+ if (!sourceX2.IsValid())
+ {
+ return false;
+ }
+ angle::CheckedNumeric<int> sourceY2(source.y);
+ sourceY2 += source.height;
+ if (!sourceY2.IsValid())
+ {
+ return false;
+ }
+
+ int minSourceX, maxSourceX, minSourceY, maxSourceY;
+ MinMax(source.x, sourceX2.ValueOrDie(), &minSourceX, &maxSourceX);
+ MinMax(source.y, sourceY2.ValueOrDie(), &minSourceY, &maxSourceY);
+
+ angle::CheckedNumeric<int> clipX2(clip.x);
+ clipX2 += clip.width;
+ if (!clipX2.IsValid())
+ {
+ return false;
+ }
+ angle::CheckedNumeric<int> clipY2(clip.y);
+ clipY2 += clip.height;
+ if (!clipY2.IsValid())
+ {
+ return false;
+ }
+
+ int minClipX, maxClipX, minClipY, maxClipY;
+ MinMax(clip.x, clipX2.ValueOrDie(), &minClipX, &maxClipX);
+ MinMax(clip.y, clipY2.ValueOrDie(), &minClipY, &maxClipY);
+
+ if (minSourceX >= maxClipX || maxSourceX <= minClipX || minSourceY >= maxClipY ||
+ maxSourceY <= minClipY)
+ {
+ return false;
+ }
+
+ int x = std::max(minSourceX, minClipX);
+ int y = std::max(minSourceY, minClipY);
+ int width = std::min(maxSourceX, maxClipX) - x;
+ int height = std::min(maxSourceY, maxClipY) - y;
+
+ if (intersection)
+ {
+ intersection->x = x;
+ intersection->y = y;
+ intersection->width = width;
+ intersection->height = height;
+ }
+ return width != 0 && height != 0;
+}
+
+void GetEnclosingRectangle(const Rectangle &rect1, const Rectangle &rect2, Rectangle *rectUnion)
+{
+ // All callers use non-flipped framebuffer-size-clipped rectangles, so both flip and overflow
+ // are impossible.
+ ASSERT(!rect1.isReversedX() && !rect1.isReversedY());
+ ASSERT(!rect2.isReversedX() && !rect2.isReversedY());
+ ASSERT((angle::CheckedNumeric<int>(rect1.x) + rect1.width).IsValid());
+ ASSERT((angle::CheckedNumeric<int>(rect1.y) + rect1.height).IsValid());
+ ASSERT((angle::CheckedNumeric<int>(rect2.x) + rect2.width).IsValid());
+ ASSERT((angle::CheckedNumeric<int>(rect2.y) + rect2.height).IsValid());
+
+ // This function calculates a rectangle that covers both input rectangles:
+ //
+ // +---------+
+ // rect1 --> | |
+ // | +---+-----+
+ // | | | | <-- rect2
+ // +-----+---+ |
+ // | |
+ // +---------+
+ //
+ // xy0 = min(rect1.xy0, rect2.xy0)
+ // \
+ // +---------+-----+
+ // union --> | . |
+ // | + . + . . +
+ // | . . |
+ // + . . + . + |
+ // | . |
+ // +-----+---------+
+ // /
+ // xy1 = max(rect1.xy1, rect2.xy1)
+
+ int x0 = std::min(rect1.x0(), rect2.x0());
+ int y0 = std::min(rect1.y0(), rect2.y0());
+
+ int x1 = std::max(rect1.x1(), rect2.x1());
+ int y1 = std::max(rect1.y1(), rect2.y1());
+
+ rectUnion->x = x0;
+ rectUnion->y = y0;
+ rectUnion->width = x1 - x0;
+ rectUnion->height = y1 - y0;
+}
+
+void ExtendRectangle(const Rectangle &source, const Rectangle &extend, Rectangle *extended)
+{
+ // All callers use non-flipped framebuffer-size-clipped rectangles, so both flip and overflow
+ // are impossible.
+ ASSERT(!source.isReversedX() && !source.isReversedY());
+ ASSERT(!extend.isReversedX() && !extend.isReversedY());
+ ASSERT((angle::CheckedNumeric<int>(source.x) + source.width).IsValid());
+ ASSERT((angle::CheckedNumeric<int>(source.y) + source.height).IsValid());
+ ASSERT((angle::CheckedNumeric<int>(extend.x) + extend.width).IsValid());
+ ASSERT((angle::CheckedNumeric<int>(extend.y) + extend.height).IsValid());
+
+ int x0 = source.x0();
+ int x1 = source.x1();
+ int y0 = source.y0();
+ int y1 = source.y1();
+
+ const int extendX0 = extend.x0();
+ const int extendX1 = extend.x1();
+ const int extendY0 = extend.y0();
+ const int extendY1 = extend.y1();
+
+ // For each side of the rectangle, calculate whether it can be extended by the second rectangle.
+ // If so, extend it and continue for the next side with the new dimensions.
+
+ // Left: Reduce x0 if the second rectangle's vertical edge covers the source's:
+ //
+ // +--- - - - +--- - - -
+ // | |
+ // | +--------------+ +-----------------+
+ // | | source | --> | source |
+ // | +--------------+ +-----------------+
+ // | |
+ // +--- - - - +--- - - -
+ //
+ const bool enclosesHeight = EnclosesRange(extendY0, extendY1, y0, y1);
+ if (extendX0 < x0 && extendX1 >= x0 && enclosesHeight)
+ {
+ x0 = extendX0;
+ }
+
+ // Right: Increase x1 simiarly.
+ if (extendX0 <= x1 && extendX1 > x1 && enclosesHeight)
+ {
+ x1 = extendX1;
+ }
+
+ // Top: Reduce y0 if the second rectangle's horizontal edge covers the source's potentially
+ // extended edge.
+ const bool enclosesWidth = EnclosesRange(extendX0, extendX1, x0, x1);
+ if (extendY0 < y0 && extendY1 >= y0 && enclosesWidth)
+ {
+ y0 = extendY0;
+ }
+
+ // Right: Increase y1 simiarly.
+ if (extendY0 <= y1 && extendY1 > y1 && enclosesWidth)
+ {
+ y1 = extendY1;
+ }
+
+ extended->x = x0;
+ extended->y = y0;
+ extended->width = x1 - x0;
+ extended->height = y1 - y0;
+}
+
+bool Box::valid() const
+{
+ return width != 0 && height != 0 && depth != 0;
+}
+
+bool Box::operator==(const Box &other) const
+{
+ return (x == other.x && y == other.y && z == other.z && width == other.width &&
+ height == other.height && depth == other.depth);
+}
+
+bool Box::operator!=(const Box &other) const
+{
+ return !(*this == other);
+}
+
+Rectangle Box::toRect() const
+{
+ ASSERT(z == 0 && depth == 1);
+ return Rectangle(x, y, width, height);
+}
+
+bool Box::coversSameExtent(const Extents &size) const
+{
+ return x == 0 && y == 0 && z == 0 && width == size.width && height == size.height &&
+ depth == size.depth;
+}
+
+bool Box::contains(const Box &other) const
+{
+ return x <= other.x && y <= other.y && z <= other.z && x + width >= other.x + other.width &&
+ y + height >= other.y + other.height && z + depth >= other.z + other.depth;
+}
+
+size_t Box::volume() const
+{
+ return width * height * depth;
+}
+
+void Box::extend(const Box &other)
+{
+ // This extends the logic of "ExtendRectangle" to 3 dimensions
+
+ int x0 = x;
+ int x1 = x + width;
+ int y0 = y;
+ int y1 = y + height;
+ int z0 = z;
+ int z1 = z + depth;
+
+ const int otherx0 = other.x;
+ const int otherx1 = other.x + other.width;
+ const int othery0 = other.y;
+ const int othery1 = other.y + other.height;
+ const int otherz0 = other.z;
+ const int otherz1 = other.z + other.depth;
+
+ // For each side of the box, calculate whether it can be extended by the other box.
+ // If so, extend it and continue to the next side with the new dimensions.
+
+ const bool enclosesWidth = EnclosesRange(otherx0, otherx1, x0, x1);
+ const bool enclosesHeight = EnclosesRange(othery0, othery1, y0, y1);
+ const bool enclosesDepth = EnclosesRange(otherz0, otherz1, z0, z1);
+
+ // Left: Reduce x0 if the other box's Y and Z plane encloses the source
+ if (otherx0 < x0 && otherx1 >= x0 && enclosesHeight && enclosesDepth)
+ {
+ x0 = otherx0;
+ }
+
+ // Right: Increase x1 simiarly.
+ if (otherx0 <= x1 && otherx1 > x1 && enclosesHeight && enclosesDepth)
+ {
+ x1 = otherx1;
+ }
+
+ // Bottom: Reduce y0 if the other box's X and Z plane encloses the source
+ if (othery0 < y0 && othery1 >= y0 && enclosesWidth && enclosesDepth)
+ {
+ y0 = othery0;
+ }
+
+ // Top: Increase y1 simiarly.
+ if (othery0 <= y1 && othery1 > y1 && enclosesWidth && enclosesDepth)
+ {
+ y1 = othery1;
+ }
+
+ // Front: Reduce z0 if the other box's X and Y plane encloses the source
+ if (otherz0 < z0 && otherz1 >= z0 && enclosesWidth && enclosesHeight)
+ {
+ z0 = otherz0;
+ }
+
+ // Back: Increase z1 simiarly.
+ if (otherz0 <= z1 && otherz1 > z1 && enclosesWidth && enclosesHeight)
+ {
+ z1 = otherz1;
+ }
+
+ // Update member var with new dimensions
+ x = x0;
+ width = x1 - x0;
+ y = y0;
+ height = y1 - y0;
+ z = z0;
+ depth = z1 - z0;
+}
+
+bool operator==(const Offset &a, const Offset &b)
+{
+ return a.x == b.x && a.y == b.y && a.z == b.z;
+}
+
+bool operator!=(const Offset &a, const Offset &b)
+{
+ return !(a == b);
+}
+
+bool operator==(const Extents &lhs, const Extents &rhs)
+{
+ return lhs.width == rhs.width && lhs.height == rhs.height && lhs.depth == rhs.depth;
+}
+
+bool operator!=(const Extents &lhs, const Extents &rhs)
+{
+ return !(lhs == rhs);
+}
+
+bool ValidateComponentTypeMasks(unsigned long outputTypes,
+ unsigned long inputTypes,
+ unsigned long outputMask,
+ unsigned long inputMask)
+{
+ static_assert(IMPLEMENTATION_MAX_DRAW_BUFFERS <= kMaxComponentTypeMaskIndex,
+ "Output/input masks should fit into 16 bits - 1 bit per draw buffer. The "
+ "corresponding type masks should fit into 32 bits - 2 bits per draw buffer.");
+ static_assert(MAX_VERTEX_ATTRIBS <= kMaxComponentTypeMaskIndex,
+ "Output/input masks should fit into 16 bits - 1 bit per attrib. The "
+ "corresponding type masks should fit into 32 bits - 2 bits per attrib.");
+
+ // For performance reasons, draw buffer and attribute type validation is done using bit masks.
+ // We store two bits representing the type split, with the low bit in the lower 16 bits of the
+ // variable, and the high bit in the upper 16 bits of the variable. This is done so we can AND
+ // with the elswewhere used DrawBufferMask or AttributeMask.
+
+ // OR the masks with themselves, shifted 16 bits. This is to match our split type bits.
+ outputMask |= (outputMask << kMaxComponentTypeMaskIndex);
+ inputMask |= (inputMask << kMaxComponentTypeMaskIndex);
+
+ // To validate:
+ // 1. Remove any indexes that are not enabled in the input (& inputMask)
+ // 2. Remove any indexes that exist in output, but not in input (& outputMask)
+ // 3. Use == to verify equality
+ return (outputTypes & inputMask) == ((inputTypes & outputMask) & inputMask);
+}
+
+GLsizeiptr GetBoundBufferAvailableSize(const OffsetBindingPointer<Buffer> &binding)
+{
+ Buffer *buffer = binding.get();
+ if (buffer == nullptr)
+ {
+ return 0;
+ }
+
+ const GLsizeiptr bufferSize = static_cast<GLsizeiptr>(buffer->getSize());
+
+ if (binding.getSize() == 0)
+ {
+ return bufferSize;
+ }
+
+ const GLintptr offset = binding.getOffset();
+ const GLsizeiptr size = binding.getSize();
+
+ ASSERT(offset >= 0 && bufferSize >= 0);
+
+ if (bufferSize <= offset)
+ {
+ return 0;
+ }
+
+ return std::min(size, bufferSize - offset);
+}
+
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/angletypes.h b/gfx/angle/checkout/src/libANGLE/angletypes.h
new file mode 100644
index 0000000000..6ac65a5cf3
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/angletypes.h
@@ -0,0 +1,1203 @@
+//
+// Copyright 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.
+//
+
+// angletypes.h : Defines a variety of structures and enum types that are used throughout libGLESv2
+
+#ifndef LIBANGLE_ANGLETYPES_H_
+#define LIBANGLE_ANGLETYPES_H_
+
+#include "common/Color.h"
+#include "common/FixedVector.h"
+#include "common/PackedEnums.h"
+#include "common/bitset_utils.h"
+#include "common/vector_utils.h"
+#include "libANGLE/Constants.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/RefCountObject.h"
+
+#include <inttypes.h>
+#include <stdint.h>
+
+#include <bitset>
+#include <map>
+#include <memory>
+#include <unordered_map>
+
+namespace gl
+{
+class Buffer;
+class Texture;
+
+enum class Command
+{
+ // The Blit command carries the bitmask of which buffers are being blit. The command passed to
+ // the backends is:
+ //
+ // Blit + (Color?0x1) + (Depth?0x2) + (Stencil?0x4)
+ Blit,
+ BlitAll = Blit + 0x7,
+ Clear,
+ CopyImage,
+ Dispatch,
+ Draw,
+ GenerateMipmap,
+ Invalidate,
+ ReadPixels,
+ TexImage,
+ Other,
+};
+
+enum CommandBlitBuffer
+{
+ CommandBlitBufferColor = 0x1,
+ CommandBlitBufferDepth = 0x2,
+ CommandBlitBufferStencil = 0x4,
+};
+
+enum class InitState
+{
+ MayNeedInit,
+ Initialized,
+};
+
+template <typename T>
+struct RectangleImpl
+{
+ RectangleImpl() : x(T(0)), y(T(0)), width(T(0)), height(T(0)) {}
+ constexpr RectangleImpl(T x_in, T y_in, T width_in, T height_in)
+ : x(x_in), y(y_in), width(width_in), height(height_in)
+ {}
+ explicit constexpr RectangleImpl(const T corners[4])
+ : x(corners[0]),
+ y(corners[1]),
+ width(corners[2] - corners[0]),
+ height(corners[3] - corners[1])
+ {}
+ template <typename S>
+ explicit constexpr RectangleImpl(const RectangleImpl<S> rect)
+ : x(rect.x), y(rect.y), width(rect.width), height(rect.height)
+ {}
+
+ T x0() const { return x; }
+ T y0() const { return y; }
+ T x1() const { return x + width; }
+ T y1() const { return y + height; }
+
+ bool isReversedX() const { return width < T(0); }
+ bool isReversedY() const { return height < T(0); }
+
+ // Returns a rectangle with the same area but flipped in X, Y, neither or both.
+ RectangleImpl<T> flip(bool flipX, bool flipY) const
+ {
+ RectangleImpl flipped = *this;
+ if (flipX)
+ {
+ flipped.x = flipped.x + flipped.width;
+ flipped.width = -flipped.width;
+ }
+ if (flipY)
+ {
+ flipped.y = flipped.y + flipped.height;
+ flipped.height = -flipped.height;
+ }
+ return flipped;
+ }
+
+ // Returns a rectangle with the same area but with height and width guaranteed to be positive.
+ RectangleImpl<T> removeReversal() const { return flip(isReversedX(), isReversedY()); }
+
+ bool encloses(const RectangleImpl<T> &inside) const
+ {
+ return x0() <= inside.x0() && y0() <= inside.y0() && x1() >= inside.x1() &&
+ y1() >= inside.y1();
+ }
+
+ bool empty() const;
+
+ T x;
+ T y;
+ T width;
+ T height;
+};
+
+template <typename T>
+bool operator==(const RectangleImpl<T> &a, const RectangleImpl<T> &b);
+template <typename T>
+bool operator!=(const RectangleImpl<T> &a, const RectangleImpl<T> &b);
+
+using Rectangle = RectangleImpl<int>;
+
+enum class ClipSpaceOrigin
+{
+ LowerLeft = 0,
+ UpperLeft = 1
+};
+
+// Calculate the intersection of two rectangles. Returns false if the intersection is empty.
+[[nodiscard]] bool ClipRectangle(const Rectangle &source,
+ const Rectangle &clip,
+ Rectangle *intersection);
+// Calculate the smallest rectangle that covers both rectangles. This rectangle may cover areas
+// not covered by the two rectangles, for example in this situation:
+//
+// +--+ +----+
+// | ++-+ -> | |
+// +-++ | | |
+// +--+ +----+
+//
+void GetEnclosingRectangle(const Rectangle &rect1, const Rectangle &rect2, Rectangle *rectUnion);
+// Extend the source rectangle to cover parts (or all of) the second rectangle, in such a way that
+// no area is covered that isn't covered by both rectangles. For example:
+//
+// +--+ +--+
+// source --> | | | |
+// ++--+-+ -> | |
+// |+--+ | | |
+// +-----+ +--+
+//
+void ExtendRectangle(const Rectangle &source, const Rectangle &extend, Rectangle *extended);
+
+struct Offset
+{
+ constexpr Offset() : x(0), y(0), z(0) {}
+ constexpr Offset(int x_in, int y_in, int z_in) : x(x_in), y(y_in), z(z_in) {}
+
+ int x;
+ int y;
+ int z;
+};
+
+constexpr Offset kOffsetZero(0, 0, 0);
+
+bool operator==(const Offset &a, const Offset &b);
+bool operator!=(const Offset &a, const Offset &b);
+
+struct Extents
+{
+ Extents() : width(0), height(0), depth(0) {}
+ Extents(int width_, int height_, int depth_) : width(width_), height(height_), depth(depth_) {}
+
+ Extents(const Extents &other) = default;
+ Extents &operator=(const Extents &other) = default;
+
+ bool empty() const { return (width * height * depth) == 0; }
+
+ int width;
+ int height;
+ int depth;
+};
+
+bool operator==(const Extents &lhs, const Extents &rhs);
+bool operator!=(const Extents &lhs, const Extents &rhs);
+
+struct Box
+{
+ Box() : x(0), y(0), z(0), width(0), height(0), depth(0) {}
+ Box(int x_in, int y_in, int z_in, int width_in, int height_in, int depth_in)
+ : x(x_in), y(y_in), z(z_in), width(width_in), height(height_in), depth(depth_in)
+ {}
+ template <typename O, typename E>
+ Box(const O &offset, const E &size)
+ : x(offset.x),
+ y(offset.y),
+ z(offset.z),
+ width(size.width),
+ height(size.height),
+ depth(size.depth)
+ {}
+ bool valid() const;
+ bool operator==(const Box &other) const;
+ bool operator!=(const Box &other) const;
+ Rectangle toRect() const;
+
+ // Whether the Box has offset 0 and the same extents as argument.
+ bool coversSameExtent(const Extents &size) const;
+
+ bool contains(const Box &other) const;
+ size_t volume() const;
+ void extend(const Box &other);
+
+ int x;
+ int y;
+ int z;
+ int width;
+ int height;
+ int depth;
+};
+
+struct RasterizerState final
+{
+ // This will zero-initialize the struct, including padding.
+ RasterizerState();
+ RasterizerState(const RasterizerState &other);
+ RasterizerState &operator=(const RasterizerState &other);
+
+ bool cullFace;
+ CullFaceMode cullMode;
+ GLenum frontFace;
+
+ bool polygonOffsetFill;
+ GLfloat polygonOffsetFactor;
+ GLfloat polygonOffsetUnits;
+
+ // pointDrawMode/multiSample are only used in the D3D back-end right now.
+ bool pointDrawMode;
+ bool multiSample;
+
+ bool rasterizerDiscard;
+
+ bool dither;
+};
+
+bool operator==(const RasterizerState &a, const RasterizerState &b);
+bool operator!=(const RasterizerState &a, const RasterizerState &b);
+
+struct BlendState final
+{
+ // This will zero-initialize the struct, including padding.
+ BlendState();
+ BlendState(const BlendState &other);
+
+ bool blend;
+ GLenum sourceBlendRGB;
+ GLenum destBlendRGB;
+ GLenum sourceBlendAlpha;
+ GLenum destBlendAlpha;
+ GLenum blendEquationRGB;
+ GLenum blendEquationAlpha;
+
+ bool colorMaskRed;
+ bool colorMaskGreen;
+ bool colorMaskBlue;
+ bool colorMaskAlpha;
+};
+
+bool operator==(const BlendState &a, const BlendState &b);
+bool operator!=(const BlendState &a, const BlendState &b);
+
+struct DepthStencilState final
+{
+ // This will zero-initialize the struct, including padding.
+ DepthStencilState();
+ DepthStencilState(const DepthStencilState &other);
+ DepthStencilState &operator=(const DepthStencilState &other);
+
+ bool isDepthMaskedOut() const;
+ bool isStencilMaskedOut() const;
+ bool isStencilNoOp() const;
+ bool isStencilBackNoOp() const;
+
+ bool depthTest;
+ GLenum depthFunc;
+ bool depthMask;
+
+ bool stencilTest;
+ GLenum stencilFunc;
+ GLuint stencilMask;
+ GLenum stencilFail;
+ GLenum stencilPassDepthFail;
+ GLenum stencilPassDepthPass;
+ GLuint stencilWritemask;
+ GLenum stencilBackFunc;
+ GLuint stencilBackMask;
+ GLenum stencilBackFail;
+ GLenum stencilBackPassDepthFail;
+ GLenum stencilBackPassDepthPass;
+ GLuint stencilBackWritemask;
+};
+
+bool operator==(const DepthStencilState &a, const DepthStencilState &b);
+bool operator!=(const DepthStencilState &a, const DepthStencilState &b);
+
+// Packs a sampler state for completeness checks:
+// * minFilter: 5 values (3 bits)
+// * magFilter: 2 values (1 bit)
+// * wrapS: 3 values (2 bits)
+// * wrapT: 3 values (2 bits)
+// * compareMode: 1 bit (for == GL_NONE).
+// This makes a total of 9 bits. We can pack this easily into 32 bits:
+// * minFilter: 8 bits
+// * magFilter: 8 bits
+// * wrapS: 8 bits
+// * wrapT: 4 bits
+// * compareMode: 4 bits
+
+struct PackedSamplerCompleteness
+{
+ uint8_t minFilter;
+ uint8_t magFilter;
+ uint8_t wrapS;
+ uint8_t wrapTCompareMode;
+};
+
+static_assert(sizeof(PackedSamplerCompleteness) == sizeof(uint32_t), "Unexpected size");
+
+// State from Table 6.10 (state per sampler object)
+class SamplerState final
+{
+ public:
+ // This will zero-initialize the struct, including padding.
+ SamplerState();
+ SamplerState(const SamplerState &other);
+
+ SamplerState &operator=(const SamplerState &other);
+
+ static SamplerState CreateDefaultForTarget(TextureType type);
+
+ GLenum getMinFilter() const { return mMinFilter; }
+
+ bool setMinFilter(GLenum minFilter);
+
+ GLenum getMagFilter() const { return mMagFilter; }
+
+ bool setMagFilter(GLenum magFilter);
+
+ GLenum getWrapS() const { return mWrapS; }
+
+ bool setWrapS(GLenum wrapS);
+
+ GLenum getWrapT() const { return mWrapT; }
+
+ bool setWrapT(GLenum wrapT);
+
+ GLenum getWrapR() const { return mWrapR; }
+
+ bool setWrapR(GLenum wrapR);
+
+ float getMaxAnisotropy() const { return mMaxAnisotropy; }
+
+ bool setMaxAnisotropy(float maxAnisotropy);
+
+ GLfloat getMinLod() const { return mMinLod; }
+
+ bool setMinLod(GLfloat minLod);
+
+ GLfloat getMaxLod() const { return mMaxLod; }
+
+ bool setMaxLod(GLfloat maxLod);
+
+ GLenum getCompareMode() const { return mCompareMode; }
+
+ bool setCompareMode(GLenum compareMode);
+
+ GLenum getCompareFunc() const { return mCompareFunc; }
+
+ bool setCompareFunc(GLenum compareFunc);
+
+ GLenum getSRGBDecode() const { return mSRGBDecode; }
+
+ bool setSRGBDecode(GLenum sRGBDecode);
+
+ bool setBorderColor(const ColorGeneric &color);
+
+ const ColorGeneric &getBorderColor() const { return mBorderColor; }
+
+ bool sameCompleteness(const SamplerState &samplerState) const
+ {
+ return mCompleteness.packed == samplerState.mCompleteness.packed;
+ }
+
+ private:
+ void updateWrapTCompareMode();
+
+ GLenum mMinFilter;
+ GLenum mMagFilter;
+
+ GLenum mWrapS;
+ GLenum mWrapT;
+ GLenum mWrapR;
+
+ // From EXT_texture_filter_anisotropic
+ float mMaxAnisotropy;
+
+ GLfloat mMinLod;
+ GLfloat mMaxLod;
+
+ GLenum mCompareMode;
+ GLenum mCompareFunc;
+
+ GLenum mSRGBDecode;
+
+ ColorGeneric mBorderColor;
+
+ union Completeness
+ {
+ uint32_t packed;
+ PackedSamplerCompleteness typed;
+ };
+
+ Completeness mCompleteness;
+};
+
+bool operator==(const SamplerState &a, const SamplerState &b);
+bool operator!=(const SamplerState &a, const SamplerState &b);
+
+struct DrawArraysIndirectCommand
+{
+ GLuint count;
+ GLuint instanceCount;
+ GLuint first;
+ GLuint baseInstance;
+};
+static_assert(sizeof(DrawArraysIndirectCommand) == 16,
+ "Unexpected size of DrawArraysIndirectCommand");
+
+struct DrawElementsIndirectCommand
+{
+ GLuint count;
+ GLuint primCount;
+ GLuint firstIndex;
+ GLint baseVertex;
+ GLuint baseInstance;
+};
+static_assert(sizeof(DrawElementsIndirectCommand) == 20,
+ "Unexpected size of DrawElementsIndirectCommand");
+
+struct ImageUnit
+{
+ ImageUnit();
+ ImageUnit(const ImageUnit &other);
+ ~ImageUnit();
+
+ BindingPointer<Texture> texture;
+ GLint level;
+ GLboolean layered;
+ GLint layer;
+ GLenum access;
+ GLenum format;
+};
+
+using ImageUnitTextureTypeMap = std::map<unsigned int, gl::TextureType>;
+
+struct PixelStoreStateBase
+{
+ GLint alignment = 4;
+ GLint rowLength = 0;
+ GLint skipRows = 0;
+ GLint skipPixels = 0;
+ GLint imageHeight = 0;
+ GLint skipImages = 0;
+};
+
+struct PixelUnpackState : PixelStoreStateBase
+{};
+
+struct PixelPackState : PixelStoreStateBase
+{
+ bool reverseRowOrder = false;
+};
+
+// Used in Program and VertexArray.
+using AttributesMask = angle::BitSet<MAX_VERTEX_ATTRIBS>;
+
+// Used in Program
+using UniformBlockBindingMask = angle::BitSet<IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS>;
+
+// Used in Framebuffer / Program
+using DrawBufferMask = angle::BitSet8<IMPLEMENTATION_MAX_DRAW_BUFFERS>;
+
+class BlendStateExt final
+{
+ static_assert(IMPLEMENTATION_MAX_DRAW_BUFFERS == 8, "Only up to 8 draw buffers supported.");
+
+ public:
+ template <typename ElementType, size_t ElementCount>
+ struct StorageType final
+ {
+ static_assert(ElementCount <= 256, "ElementCount cannot exceed 256.");
+
+#if defined(ANGLE_IS_64_BIT_CPU)
+ // Always use uint64_t on 64-bit systems
+ static constexpr size_t kBits = 8;
+#else
+ static constexpr size_t kBits = ElementCount > 16 ? 8 : 4;
+#endif
+
+ using Type = typename std::conditional<kBits == 8, uint64_t, uint32_t>::type;
+
+ static constexpr Type kMaxValueMask = (kBits == 8) ? 0xFF : 0xF;
+
+ static constexpr Type GetMask(const size_t drawBuffers)
+ {
+ ASSERT(drawBuffers > 0);
+ ASSERT(drawBuffers <= IMPLEMENTATION_MAX_DRAW_BUFFERS);
+ return static_cast<Type>(0xFFFFFFFFFFFFFFFFull >> (64 - drawBuffers * kBits));
+ }
+
+ // A multiplier that is used to replicate 4- or 8-bit value 8 times.
+ static constexpr Type kReplicator = (kBits == 8) ? 0x0101010101010101ull : 0x11111111;
+
+ // Extract packed `Bits`-bit value of index `index`. `values` variable contains up to 8
+ // packed values.
+ static constexpr ElementType GetValueIndexed(const size_t index, const Type values)
+ {
+ ASSERT(index < IMPLEMENTATION_MAX_DRAW_BUFFERS);
+
+ return static_cast<ElementType>((values >> (index * kBits)) & kMaxValueMask);
+ }
+
+ // Replicate `Bits`-bit value 8 times and mask the result.
+ static constexpr Type GetReplicatedValue(const ElementType value, const Type mask)
+ {
+ ASSERT(static_cast<size_t>(value) <= kMaxValueMask);
+ return (static_cast<size_t>(value) * kReplicator) & mask;
+ }
+
+ // Replace `Bits`-bit value of index `index` in `target` with `value`.
+ static constexpr void SetValueIndexed(const size_t index,
+ const ElementType value,
+ Type *target)
+ {
+ ASSERT(static_cast<size_t>(value) <= kMaxValueMask);
+ ASSERT(index < IMPLEMENTATION_MAX_DRAW_BUFFERS);
+
+ // Bitmask with set bits that contain the value of index `index`.
+ const Type selector = kMaxValueMask << (index * kBits);
+
+ // Shift the new `value` to its position in the packed value.
+ const Type builtValue = static_cast<Type>(value) << (index * kBits);
+
+ // Mark differing bits of `target` and `builtValue`, then flip the bits on those
+ // positions in `target`.
+ // Taken from https://graphics.stanford.edu/~seander/bithacks.html#MaskedMerge
+ *target = *target ^ ((*target ^ builtValue) & selector);
+ }
+
+ // Compare two packed sets of eight 4-bit values and return an 8-bit diff mask.
+ static constexpr DrawBufferMask GetDiffMask(const uint32_t packedValue1,
+ const uint32_t packedValue2)
+ {
+ uint32_t diff = packedValue1 ^ packedValue2;
+
+ // For each 4-bit value that is different between inputs, set the msb to 1 and other
+ // bits to 0.
+ diff = (diff | ((diff & 0x77777777) + 0x77777777)) & 0x88888888;
+
+ // By this point, `diff` looks like a...b...c...d...e...f...g...h... (dots mean zeros).
+ // To get DrawBufferMask, we need to compress this 32-bit value to 8 bits, i.e. abcdefgh
+
+ // Multiplying the lower half of `diff` by 0x249 (0x200 + 0x40 + 0x8 + 0x1) produces:
+ // ................e...f...g...h... +
+ // .............e...f...g...h...... +
+ // ..........e...f...g...h......... +
+ // .......e...f...g...h............
+ // ________________________________ =
+ // .......e..ef.efgefghfgh.gh..h...
+ // ^^^^
+ // Similar operation is applied to the upper word.
+ // This calculation could be replaced with a single PEXT instruction from BMI2 set.
+ diff = ((((diff & 0xFFFF0000) * 0x249) >> 24) & 0xF0) | (((diff * 0x249) >> 12) & 0xF);
+
+ return DrawBufferMask(static_cast<uint8_t>(diff));
+ }
+
+ // Compare two packed sets of eight 8-bit values and return an 8-bit diff mask.
+ static constexpr DrawBufferMask GetDiffMask(const uint64_t packedValue1,
+ const uint64_t packedValue2)
+ {
+ uint64_t diff = packedValue1 ^ packedValue2;
+
+ // For each 8-bit value that is different between inputs, set the msb to 1 and other
+ // bits to 0.
+ diff = (diff | ((diff & 0x7F7F7F7F7F7F7F7F) + 0x7F7F7F7F7F7F7F7F)) & 0x8080808080808080;
+
+ // By this point, `diff` looks like (dots mean zeros):
+ // a.......b.......c.......d.......e.......f.......g.......h.......
+ // To get DrawBufferMask, we need to compress this 64-bit value to 8 bits, i.e. abcdefgh
+
+ // Multiplying `diff` by 0x0002040810204081 produces:
+ // a.......b.......c.......d.......e.......f.......g.......h....... +
+ // .b.......c.......d.......e.......f.......g.......h.............. +
+ // ..c.......d.......e.......f.......g.......h..................... +
+ // ...d.......e.......f.......g.......h............................ +
+ // ....e.......f.......g.......h................................... +
+ // .....f.......g.......h.......................................... +
+ // ......g.......h................................................. +
+ // .......h........................................................
+ // ________________________________________________________________ =
+ // abcdefghbcdefgh.cdefgh..defgh...efgh....fgh.....gh......h.......
+ // ^^^^^^^^
+ // This operation could be replaced with a single PEXT instruction from BMI2 set.
+ diff = 0x0002040810204081 * diff >> 56;
+
+ return DrawBufferMask(static_cast<uint8_t>(diff));
+ }
+ };
+
+ using FactorStorage = StorageType<BlendFactorType, angle::EnumSize<BlendFactorType>()>;
+ using EquationStorage = StorageType<BlendEquationType, angle::EnumSize<BlendEquationType>()>;
+ using ColorMaskStorage = StorageType<uint8_t, 16>;
+ static_assert(std::is_same<FactorStorage::Type, uint64_t>::value &&
+ std::is_same<EquationStorage::Type, uint64_t>::value,
+ "Factor and Equation storage must be 64-bit.");
+
+ BlendStateExt(const size_t drawBuffers = 1);
+
+ BlendStateExt(const BlendStateExt &other);
+ BlendStateExt &operator=(const BlendStateExt &other);
+
+ ///////// Blending Toggle /////////
+
+ void setEnabled(const bool enabled);
+ void setEnabledIndexed(const size_t index, const bool enabled);
+
+ ///////// Color Write Mask /////////
+
+ static constexpr size_t PackColorMask(const bool red,
+ const bool green,
+ const bool blue,
+ const bool alpha)
+ {
+ return (red ? 1 : 0) | (green ? 2 : 0) | (blue ? 4 : 0) | (alpha ? 8 : 0);
+ }
+
+ static constexpr void UnpackColorMask(const size_t value,
+ bool *red,
+ bool *green,
+ bool *blue,
+ bool *alpha)
+ {
+ *red = static_cast<bool>(value & 1);
+ *green = static_cast<bool>(value & 2);
+ *blue = static_cast<bool>(value & 4);
+ *alpha = static_cast<bool>(value & 8);
+ }
+
+ ColorMaskStorage::Type expandColorMaskValue(const bool red,
+ const bool green,
+ const bool blue,
+ const bool alpha) const;
+ ColorMaskStorage::Type expandColorMaskIndexed(const size_t index) const;
+ void setColorMask(const bool red, const bool green, const bool blue, const bool alpha);
+ void setColorMaskIndexed(const size_t index, const uint8_t value);
+ void setColorMaskIndexed(const size_t index,
+ const bool red,
+ const bool green,
+ const bool blue,
+ const bool alpha);
+ uint8_t getColorMaskIndexed(const size_t index) const;
+ void getColorMaskIndexed(const size_t index,
+ bool *red,
+ bool *green,
+ bool *blue,
+ bool *alpha) const;
+ DrawBufferMask compareColorMask(ColorMaskStorage::Type other) const;
+
+ ///////// Blend Equation /////////
+
+ EquationStorage::Type expandEquationValue(const GLenum mode) const;
+ EquationStorage::Type expandEquationValue(const gl::BlendEquationType equation) const;
+ EquationStorage::Type expandEquationColorIndexed(const size_t index) const;
+ EquationStorage::Type expandEquationAlphaIndexed(const size_t index) const;
+ void setEquations(const GLenum modeColor, const GLenum modeAlpha);
+ void setEquationsIndexed(const size_t index, const GLenum modeColor, const GLenum modeAlpha);
+ void setEquationsIndexed(const size_t index,
+ const size_t otherIndex,
+ const BlendStateExt &other);
+ GLenum getEquationColorIndexed(size_t index) const;
+ GLenum getEquationAlphaIndexed(size_t index) const;
+ DrawBufferMask compareEquations(const EquationStorage::Type color,
+ const EquationStorage::Type alpha) const;
+ DrawBufferMask compareEquations(const BlendStateExt &other) const
+ {
+ return compareEquations(other.mEquationColor, other.mEquationAlpha);
+ }
+
+ ///////// Blend Factors /////////
+
+ FactorStorage::Type expandFactorValue(const GLenum func) const;
+ FactorStorage::Type expandSrcColorIndexed(const size_t index) const;
+ FactorStorage::Type expandDstColorIndexed(const size_t index) const;
+ FactorStorage::Type expandSrcAlphaIndexed(const size_t index) const;
+ FactorStorage::Type expandDstAlphaIndexed(const size_t index) const;
+ void setFactors(const GLenum srcColor,
+ const GLenum dstColor,
+ const GLenum srcAlpha,
+ const GLenum dstAlpha);
+ void setFactorsIndexed(const size_t index,
+ const GLenum srcColor,
+ const GLenum dstColor,
+ const GLenum srcAlpha,
+ const GLenum dstAlpha);
+ void setFactorsIndexed(const size_t index, const size_t otherIndex, const BlendStateExt &other);
+ GLenum getSrcColorIndexed(size_t index) const;
+ GLenum getDstColorIndexed(size_t index) const;
+ GLenum getSrcAlphaIndexed(size_t index) const;
+ GLenum getDstAlphaIndexed(size_t index) const;
+ DrawBufferMask compareFactors(const FactorStorage::Type srcColor,
+ const FactorStorage::Type dstColor,
+ const FactorStorage::Type srcAlpha,
+ const FactorStorage::Type dstAlpha) const;
+ DrawBufferMask compareFactors(const BlendStateExt &other) const
+ {
+ return compareFactors(other.mSrcColor, other.mDstColor, other.mSrcAlpha, other.mDstAlpha);
+ }
+
+ constexpr FactorStorage::Type getSrcColorBits() const { return mSrcColor; }
+ constexpr FactorStorage::Type getSrcAlphaBits() const { return mSrcAlpha; }
+ constexpr FactorStorage::Type getDstColorBits() const { return mDstColor; }
+ constexpr FactorStorage::Type getDstAlphaBits() const { return mDstAlpha; }
+
+ constexpr EquationStorage::Type getEquationColorBits() const { return mEquationColor; }
+ constexpr EquationStorage::Type getEquationAlphaBits() const { return mEquationAlpha; }
+
+ constexpr ColorMaskStorage::Type getAllColorMaskBits() const { return mAllColorMask; }
+ constexpr ColorMaskStorage::Type getColorMaskBits() const { return mColorMask; }
+
+ constexpr DrawBufferMask getAllEnabledMask() const { return mAllEnabledMask; }
+ constexpr DrawBufferMask getEnabledMask() const { return mEnabledMask; }
+
+ constexpr DrawBufferMask getUsesAdvancedBlendEquationMask() const
+ {
+ return mUsesAdvancedBlendEquationMask;
+ }
+
+ constexpr uint8_t getDrawBufferCount() const { return mDrawBufferCount; }
+
+ constexpr void setSrcColorBits(const FactorStorage::Type srcColor) { mSrcColor = srcColor; }
+ constexpr void setSrcAlphaBits(const FactorStorage::Type srcAlpha) { mSrcAlpha = srcAlpha; }
+ constexpr void setDstColorBits(const FactorStorage::Type dstColor) { mDstColor = dstColor; }
+ constexpr void setDstAlphaBits(const FactorStorage::Type dstAlpha) { mDstAlpha = dstAlpha; }
+
+ constexpr void setEquationColorBits(const EquationStorage::Type equationColor)
+ {
+ mEquationColor = equationColor;
+ }
+ constexpr void setEquationAlphaBits(const EquationStorage::Type equationAlpha)
+ {
+ mEquationAlpha = equationAlpha;
+ }
+
+ constexpr void setColorMaskBits(const ColorMaskStorage::Type colorMask)
+ {
+ mColorMask = colorMask;
+ }
+
+ constexpr void setEnabledMask(const DrawBufferMask enabledMask) { mEnabledMask = enabledMask; }
+
+ ///////// Data Members /////////
+ private:
+ uint64_t mParameterMask;
+
+ FactorStorage::Type mSrcColor;
+ FactorStorage::Type mDstColor;
+ FactorStorage::Type mSrcAlpha;
+ FactorStorage::Type mDstAlpha;
+
+ EquationStorage::Type mEquationColor;
+ EquationStorage::Type mEquationAlpha;
+
+ ColorMaskStorage::Type mAllColorMask;
+ ColorMaskStorage::Type mColorMask;
+
+ DrawBufferMask mAllEnabledMask;
+ DrawBufferMask mEnabledMask;
+
+ // Cache of whether the blend equation for each index is from KHR_blend_equation_advanced.
+ DrawBufferMask mUsesAdvancedBlendEquationMask;
+
+ uint8_t mDrawBufferCount;
+
+ [[maybe_unused]] uint32_t kUnused = 0;
+};
+
+static_assert(sizeof(BlendStateExt) == sizeof(uint64_t) +
+ (sizeof(BlendStateExt::FactorStorage::Type) * 4 +
+ sizeof(BlendStateExt::EquationStorage::Type) * 2 +
+ sizeof(BlendStateExt::ColorMaskStorage::Type) * 2 +
+ sizeof(DrawBufferMask) * 3 + sizeof(uint8_t)) +
+ sizeof(uint32_t),
+ "The BlendStateExt class must not contain gaps.");
+
+// Used in StateCache
+using StorageBuffersMask = angle::BitSet<IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS>;
+
+template <typename T>
+using SampleMaskArray = std::array<T, IMPLEMENTATION_MAX_SAMPLE_MASK_WORDS>;
+
+template <typename T>
+using TexLevelArray = std::array<T, IMPLEMENTATION_MAX_TEXTURE_LEVELS>;
+
+using TexLevelMask = angle::BitSet<IMPLEMENTATION_MAX_TEXTURE_LEVELS>;
+
+enum class ComponentType
+{
+ Float = 0,
+ Int = 1,
+ UnsignedInt = 2,
+ NoType = 3,
+ EnumCount = 4,
+ InvalidEnum = 4,
+};
+
+constexpr ComponentType GLenumToComponentType(GLenum componentType)
+{
+ switch (componentType)
+ {
+ case GL_FLOAT:
+ return ComponentType::Float;
+ case GL_INT:
+ return ComponentType::Int;
+ case GL_UNSIGNED_INT:
+ return ComponentType::UnsignedInt;
+ case GL_NONE:
+ return ComponentType::NoType;
+ default:
+ return ComponentType::InvalidEnum;
+ }
+}
+
+constexpr angle::PackedEnumMap<ComponentType, uint32_t> kComponentMasks = {{
+ {ComponentType::Float, 0x10001},
+ {ComponentType::Int, 0x00001},
+ {ComponentType::UnsignedInt, 0x10000},
+}};
+
+constexpr size_t kMaxComponentTypeMaskIndex = 16;
+using ComponentTypeMask = angle::BitSet<kMaxComponentTypeMaskIndex * 2>;
+
+ANGLE_INLINE void SetComponentTypeMask(ComponentType type, size_t index, ComponentTypeMask *mask)
+{
+ ASSERT(index <= kMaxComponentTypeMaskIndex);
+ *mask &= ~(0x10001 << index);
+ *mask |= kComponentMasks[type] << index;
+}
+
+ANGLE_INLINE ComponentType GetComponentTypeMask(const ComponentTypeMask &mask, size_t index)
+{
+ ASSERT(index <= kMaxComponentTypeMaskIndex);
+ uint32_t mask_bits = static_cast<uint32_t>((mask.to_ulong() >> index) & 0x10001);
+ switch (mask_bits)
+ {
+ case 0x10001:
+ return ComponentType::Float;
+ case 0x00001:
+ return ComponentType::Int;
+ case 0x10000:
+ return ComponentType::UnsignedInt;
+ default:
+ return ComponentType::InvalidEnum;
+ }
+}
+
+bool ValidateComponentTypeMasks(unsigned long outputTypes,
+ unsigned long inputTypes,
+ unsigned long outputMask,
+ unsigned long inputMask);
+
+enum class RenderToTextureImageIndex
+{
+ // The default image of the texture, where data is expected to be.
+ Default = 0,
+
+ // Intermediate multisampled images for EXT_multisampled_render_to_texture.
+ // These values must match log2(SampleCount).
+ IntermediateImage2xMultisampled = 1,
+ IntermediateImage4xMultisampled = 2,
+ IntermediateImage8xMultisampled = 3,
+ IntermediateImage16xMultisampled = 4,
+
+ // We currently only support up to 16xMSAA in backends that use this enum.
+ InvalidEnum = 5,
+ EnumCount = 5,
+};
+
+template <typename T>
+using RenderToTextureImageMap = angle::PackedEnumMap<RenderToTextureImageIndex, T>;
+
+struct ContextID
+{
+ uint32_t value;
+};
+
+inline bool operator==(ContextID lhs, ContextID rhs)
+{
+ return lhs.value == rhs.value;
+}
+
+inline bool operator!=(ContextID lhs, ContextID rhs)
+{
+ return lhs.value != rhs.value;
+}
+
+inline bool operator<(ContextID lhs, ContextID rhs)
+{
+ return lhs.value < rhs.value;
+}
+
+constexpr size_t kCubeFaceCount = 6;
+
+template <typename T>
+using TextureTypeMap = angle::PackedEnumMap<TextureType, T>;
+using TextureMap = TextureTypeMap<BindingPointer<Texture>>;
+
+// ShaderVector can contain one item per shader. It differs from ShaderMap in that the values are
+// not indexed by ShaderType.
+template <typename T>
+using ShaderVector = angle::FixedVector<T, static_cast<size_t>(ShaderType::EnumCount)>;
+
+template <typename T>
+using AttachmentArray = std::array<T, IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS>;
+
+template <typename T>
+using AttachmentVector = angle::FixedVector<T, IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS>;
+
+using AttachmentsMask = angle::BitSet<IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS>;
+
+template <typename T>
+using DrawBuffersArray = std::array<T, IMPLEMENTATION_MAX_DRAW_BUFFERS>;
+
+template <typename T>
+using DrawBuffersVector = angle::FixedVector<T, IMPLEMENTATION_MAX_DRAW_BUFFERS>;
+
+template <typename T>
+using AttribArray = std::array<T, MAX_VERTEX_ATTRIBS>;
+
+using ActiveTextureMask = angle::BitSet<IMPLEMENTATION_MAX_ACTIVE_TEXTURES>;
+
+template <typename T>
+using ActiveTextureArray = std::array<T, IMPLEMENTATION_MAX_ACTIVE_TEXTURES>;
+
+using ActiveTextureTypeArray = ActiveTextureArray<TextureType>;
+
+template <typename T>
+using UniformBuffersArray = std::array<T, IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS>;
+template <typename T>
+using StorageBuffersArray = std::array<T, IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS>;
+template <typename T>
+using AtomicCounterBuffersArray = std::array<T, IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS>;
+using AtomicCounterBufferMask = angle::BitSet<IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS>;
+template <typename T>
+using ImagesArray = std::array<T, IMPLEMENTATION_MAX_IMAGE_UNITS>;
+
+using ImageUnitMask = angle::BitSet<IMPLEMENTATION_MAX_IMAGE_UNITS>;
+
+using SupportedSampleSet = std::set<GLuint>;
+
+template <typename T>
+using TransformFeedbackBuffersArray =
+ std::array<T, gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS>;
+
+template <typename T>
+using QueryTypeMap = angle::PackedEnumMap<QueryType, T>;
+
+constexpr size_t kBarrierVectorDefaultSize = 16;
+
+template <typename T>
+using BarrierVector = angle::FastVector<T, kBarrierVectorDefaultSize>;
+
+using BufferBarrierVector = BarrierVector<Buffer *>;
+
+using SamplerBindingVector = std::vector<BindingPointer<Sampler>>;
+using BufferVector = std::vector<OffsetBindingPointer<Buffer>>;
+
+struct TextureAndLayout
+{
+ Texture *texture;
+ GLenum layout;
+};
+using TextureBarrierVector = BarrierVector<TextureAndLayout>;
+
+// OffsetBindingPointer.getSize() returns the size specified by the user, which may be larger than
+// the size of the bound buffer. This function reduces the returned size to fit the bound buffer if
+// necessary. Returns 0 if no buffer is bound or if integer overflow occurs.
+GLsizeiptr GetBoundBufferAvailableSize(const OffsetBindingPointer<Buffer> &binding);
+
+// A texture level index.
+template <typename T>
+class LevelIndexWrapper
+{
+ public:
+ LevelIndexWrapper() = default;
+ explicit constexpr LevelIndexWrapper(T levelIndex) : mLevelIndex(levelIndex) {}
+ constexpr LevelIndexWrapper(const LevelIndexWrapper &other) = default;
+ constexpr LevelIndexWrapper &operator=(const LevelIndexWrapper &other) = default;
+
+ constexpr T get() const { return mLevelIndex; }
+
+ LevelIndexWrapper &operator++()
+ {
+ ++mLevelIndex;
+ return *this;
+ }
+ constexpr bool operator<(const LevelIndexWrapper &other) const
+ {
+ return mLevelIndex < other.mLevelIndex;
+ }
+ constexpr bool operator<=(const LevelIndexWrapper &other) const
+ {
+ return mLevelIndex <= other.mLevelIndex;
+ }
+ constexpr bool operator>(const LevelIndexWrapper &other) const
+ {
+ return mLevelIndex > other.mLevelIndex;
+ }
+ constexpr bool operator>=(const LevelIndexWrapper &other) const
+ {
+ return mLevelIndex >= other.mLevelIndex;
+ }
+ constexpr bool operator==(const LevelIndexWrapper &other) const
+ {
+ return mLevelIndex == other.mLevelIndex;
+ }
+ constexpr bool operator!=(const LevelIndexWrapper &other) const
+ {
+ return mLevelIndex != other.mLevelIndex;
+ }
+ constexpr LevelIndexWrapper operator+(T other) const
+ {
+ return LevelIndexWrapper(mLevelIndex + other);
+ }
+ constexpr LevelIndexWrapper operator-(T other) const
+ {
+ return LevelIndexWrapper(mLevelIndex - other);
+ }
+ constexpr T operator-(LevelIndexWrapper other) const { return mLevelIndex - other.mLevelIndex; }
+
+ private:
+ T mLevelIndex;
+};
+
+// A GL texture level index.
+using LevelIndex = LevelIndexWrapper<GLint>;
+
+enum class MultisamplingMode
+{
+ // Regular multisampling
+ Regular = 0,
+ // GL_EXT_multisampled_render_to_texture renderbuffer/texture attachments which perform implicit
+ // resolve of multisampled data.
+ MultisampledRenderToTexture,
+};
+} // namespace gl
+
+namespace rx
+{
+// A macro that determines whether an object has a given runtime type.
+#if defined(__clang__)
+# if __has_feature(cxx_rtti)
+# define ANGLE_HAS_DYNAMIC_CAST 1
+# endif
+#elif !defined(NDEBUG) && (!defined(_MSC_VER) || defined(_CPPRTTI)) && \
+ (!defined(__GNUC__) || __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3) || \
+ defined(__GXX_RTTI))
+# define ANGLE_HAS_DYNAMIC_CAST 1
+#endif
+
+#ifdef ANGLE_HAS_DYNAMIC_CAST
+# define ANGLE_HAS_DYNAMIC_TYPE(type, obj) (dynamic_cast<type>(obj) != nullptr)
+# undef ANGLE_HAS_DYNAMIC_CAST
+#else
+# define ANGLE_HAS_DYNAMIC_TYPE(type, obj) (obj != nullptr)
+#endif
+
+// Downcast a base implementation object (EG TextureImpl to TextureD3D)
+template <typename DestT, typename SrcT>
+inline DestT *GetAs(SrcT *src)
+{
+ ASSERT(ANGLE_HAS_DYNAMIC_TYPE(DestT *, src));
+ return static_cast<DestT *>(src);
+}
+
+template <typename DestT, typename SrcT>
+inline const DestT *GetAs(const SrcT *src)
+{
+ ASSERT(ANGLE_HAS_DYNAMIC_TYPE(const DestT *, src));
+ return static_cast<const DestT *>(src);
+}
+
+#undef ANGLE_HAS_DYNAMIC_TYPE
+
+// Downcast a GL object to an Impl (EG gl::Texture to rx::TextureD3D)
+template <typename DestT, typename SrcT>
+inline DestT *GetImplAs(SrcT *src)
+{
+ return GetAs<DestT>(src->getImplementation());
+}
+
+template <typename DestT, typename SrcT>
+inline DestT *SafeGetImplAs(SrcT *src)
+{
+ return src != nullptr ? GetAs<DestT>(src->getImplementation()) : nullptr;
+}
+
+} // namespace rx
+
+#include "angletypes.inc"
+
+namespace angle
+{
+// Zero-based for better array indexing
+enum FramebufferBinding
+{
+ FramebufferBindingRead = 0,
+ FramebufferBindingDraw,
+ FramebufferBindingSingletonMax,
+ FramebufferBindingBoth = FramebufferBindingSingletonMax,
+ FramebufferBindingMax,
+ FramebufferBindingUnknown = FramebufferBindingMax,
+};
+
+inline FramebufferBinding EnumToFramebufferBinding(GLenum enumValue)
+{
+ switch (enumValue)
+ {
+ case GL_READ_FRAMEBUFFER:
+ return FramebufferBindingRead;
+ case GL_DRAW_FRAMEBUFFER:
+ return FramebufferBindingDraw;
+ case GL_FRAMEBUFFER:
+ return FramebufferBindingBoth;
+ default:
+ UNREACHABLE();
+ return FramebufferBindingUnknown;
+ }
+}
+
+inline GLenum FramebufferBindingToEnum(FramebufferBinding binding)
+{
+ switch (binding)
+ {
+ case FramebufferBindingRead:
+ return GL_READ_FRAMEBUFFER;
+ case FramebufferBindingDraw:
+ return GL_DRAW_FRAMEBUFFER;
+ case FramebufferBindingBoth:
+ return GL_FRAMEBUFFER;
+ default:
+ UNREACHABLE();
+ return GL_NONE;
+ }
+}
+
+template <typename ObjT, typename ContextT>
+class DestroyThenDelete
+{
+ public:
+ DestroyThenDelete() = default;
+ DestroyThenDelete(const ContextT *context) : mContext(context) {}
+
+ void operator()(ObjT *obj)
+ {
+ (void)(obj->onDestroy(mContext));
+ delete obj;
+ }
+
+ private:
+ const ContextT *mContext = nullptr;
+};
+
+template <typename ObjT, typename ContextT>
+using UniqueObjectPointer = std::unique_ptr<ObjT, DestroyThenDelete<ObjT, ContextT>>;
+
+} // namespace angle
+
+namespace gl
+{
+class State;
+} // namespace gl
+
+#endif // LIBANGLE_ANGLETYPES_H_
diff --git a/gfx/angle/checkout/src/libANGLE/angletypes.inc b/gfx/angle/checkout/src/libANGLE/angletypes.inc
new file mode 100644
index 0000000000..862a3214a1
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/angletypes.inc
@@ -0,0 +1,35 @@
+//
+// Copyright 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.
+//
+
+// angletypes.inc : Inline definitions of some functions from angletypes.h
+
+namespace gl
+{
+
+inline bool operator==(const Rectangle &a, const Rectangle &b)
+{
+ return a.x == b.x &&
+ a.y == b.y &&
+ a.width == b.width &&
+ a.height == b.height;
+}
+
+inline bool operator!=(const Rectangle &a, const Rectangle &b)
+{
+ return !(a == b);
+}
+
+inline bool operator==(const SamplerState &a, const SamplerState &b)
+{
+ return memcmp(&a, &b, sizeof(SamplerState)) == 0;
+}
+
+inline bool operator!=(const SamplerState &a, const SamplerState &b)
+{
+ return !(a == b);
+}
+
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/capture/FrameCapture.h b/gfx/angle/checkout/src/libANGLE/capture/FrameCapture.h
new file mode 100644
index 0000000000..a9b0348b6a
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/capture/FrameCapture.h
@@ -0,0 +1,1208 @@
+//
+// Copyright 2019 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.
+//
+// FrameCapture.h:
+// ANGLE Frame capture interface.
+//
+
+#ifndef LIBANGLE_FRAME_CAPTURE_H_
+#define LIBANGLE_FRAME_CAPTURE_H_
+
+#include "common/PackedEnums.h"
+#include "common/system_utils.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/capture/frame_capture_utils_autogen.h"
+#include "libANGLE/entry_points_utils.h"
+
+namespace gl
+{
+enum class BigGLEnum;
+enum class GLESEnum;
+} // namespace gl
+
+namespace angle
+{
+
+using ParamData = std::vector<std::vector<uint8_t>>;
+struct ParamCapture : angle::NonCopyable
+{
+ ParamCapture();
+ ParamCapture(const char *nameIn, ParamType typeIn);
+ ~ParamCapture();
+
+ ParamCapture(ParamCapture &&other);
+ ParamCapture &operator=(ParamCapture &&other);
+
+ std::string name;
+ ParamType type;
+ ParamValue value;
+ gl::GLESEnum enumGroup; // only used for param type GLenum, GLboolean and GLbitfield
+ gl::BigGLEnum bigGLEnum; // only used for param type GLenum, GLboolean and GLbitfield
+ ParamData data;
+ int dataNElements = 0;
+ int arrayClientPointerIndex = -1;
+ size_t readBufferSizeBytes = 0;
+};
+
+class ParamBuffer final : angle::NonCopyable
+{
+ public:
+ ParamBuffer();
+ ~ParamBuffer();
+
+ ParamBuffer(ParamBuffer &&other);
+ ParamBuffer &operator=(ParamBuffer &&other);
+
+ template <typename T>
+ void addValueParam(const char *paramName, ParamType paramType, T paramValue);
+ template <typename T>
+ void setValueParamAtIndex(const char *paramName, ParamType paramType, T paramValue, int index);
+ template <typename T>
+ void addEnumParam(const char *paramName,
+ gl::GLESEnum enumGroup,
+ ParamType paramType,
+ T paramValue);
+ template <typename T>
+ void addEnumParam(const char *paramName,
+ gl::BigGLEnum enumGroup,
+ ParamType paramType,
+ T paramValue);
+
+ ParamCapture &getParam(const char *paramName, ParamType paramType, int index);
+ const ParamCapture &getParam(const char *paramName, ParamType paramType, int index) const;
+ ParamCapture &getParamFlexName(const char *paramName1,
+ const char *paramName2,
+ ParamType paramType,
+ int index);
+ const ParamCapture &getParamFlexName(const char *paramName1,
+ const char *paramName2,
+ ParamType paramType,
+ int index) const;
+ const ParamCapture &getReturnValue() const { return mReturnValueCapture; }
+
+ void addParam(ParamCapture &&param);
+ void addReturnValue(ParamCapture &&returnValue);
+ bool hasClientArrayData() const { return mClientArrayDataParam != -1; }
+ ParamCapture &getClientArrayPointerParameter();
+ size_t getReadBufferSize() const { return mReadBufferSize; }
+
+ const std::vector<ParamCapture> &getParamCaptures() const { return mParamCaptures; }
+
+ // These helpers allow us to track the ID of the buffer that was active when
+ // MapBufferRange was called. We'll use it during replay to track the
+ // buffer's contents, as they can be modified by the host.
+ void setMappedBufferID(gl::BufferID bufferID) { mMappedBufferID = bufferID; }
+ gl::BufferID getMappedBufferID() const { return mMappedBufferID; }
+
+ private:
+ std::vector<ParamCapture> mParamCaptures;
+ ParamCapture mReturnValueCapture;
+ int mClientArrayDataParam = -1;
+ size_t mReadBufferSize = 0;
+ gl::BufferID mMappedBufferID;
+};
+
+struct CallCapture
+{
+ CallCapture(EntryPoint entryPointIn, ParamBuffer &&paramsIn);
+ CallCapture(const std::string &customFunctionNameIn, ParamBuffer &&paramsIn);
+ ~CallCapture();
+
+ CallCapture(CallCapture &&other);
+ CallCapture &operator=(CallCapture &&other);
+
+ const char *name() const;
+
+ EntryPoint entryPoint;
+ std::string customFunctionName;
+ ParamBuffer params;
+ bool isActive = true;
+};
+
+class ReplayContext
+{
+ public:
+ ReplayContext(size_t readBufferSizebytes, const gl::AttribArray<size_t> &clientArraysSizebytes);
+ ~ReplayContext();
+
+ template <typename T>
+ T getReadBufferPointer(const ParamCapture &param)
+ {
+ ASSERT(param.readBufferSizeBytes > 0);
+ ASSERT(mReadBuffer.size() >= param.readBufferSizeBytes);
+ return reinterpret_cast<T>(mReadBuffer.data());
+ }
+ template <typename T>
+ T getAsConstPointer(const ParamCapture &param)
+ {
+ if (param.arrayClientPointerIndex != -1)
+ {
+ return reinterpret_cast<T>(mClientArraysBuffer[param.arrayClientPointerIndex].data());
+ }
+
+ if (!param.data.empty())
+ {
+ ASSERT(param.data.size() == 1);
+ return reinterpret_cast<T>(param.data[0].data());
+ }
+
+ return nullptr;
+ }
+
+ template <typename T>
+ T getAsPointerConstPointer(const ParamCapture &param)
+ {
+ static_assert(sizeof(typename std::remove_pointer<T>::type) == sizeof(uint8_t *),
+ "pointer size not match!");
+
+ ASSERT(!param.data.empty());
+ mPointersBuffer.clear();
+ mPointersBuffer.reserve(param.data.size());
+ for (const std::vector<uint8_t> &data : param.data)
+ {
+ mPointersBuffer.emplace_back(data.data());
+ }
+ return reinterpret_cast<T>(mPointersBuffer.data());
+ }
+
+ gl::AttribArray<std::vector<uint8_t>> &getClientArraysBuffer() { return mClientArraysBuffer; }
+
+ private:
+ std::vector<uint8_t> mReadBuffer;
+ std::vector<const uint8_t *> mPointersBuffer;
+ gl::AttribArray<std::vector<uint8_t>> mClientArraysBuffer;
+};
+
+// Helper to use unique IDs for each local data variable.
+class DataCounters final : angle::NonCopyable
+{
+ public:
+ DataCounters();
+ ~DataCounters();
+
+ int getAndIncrement(EntryPoint entryPoint, const std::string &paramName);
+
+ private:
+ // <CallName, ParamName>
+ using Counter = std::pair<EntryPoint, std::string>;
+ std::map<Counter, int> mData;
+};
+
+constexpr int kStringsNotFound = -1;
+class StringCounters final : angle::NonCopyable
+{
+ public:
+ StringCounters();
+ ~StringCounters();
+
+ int getStringCounter(const std::vector<std::string> &str);
+ void setStringCounter(const std::vector<std::string> &str, int &counter);
+
+ private:
+ std::map<std::vector<std::string>, int> mStringCounterMap;
+};
+
+class DataTracker final : angle::NonCopyable
+{
+ public:
+ DataTracker();
+ ~DataTracker();
+
+ DataCounters &getCounters() { return mCounters; }
+ StringCounters &getStringCounters() { return mStringCounters; }
+
+ private:
+ DataCounters mCounters;
+ StringCounters mStringCounters;
+};
+
+class ReplayWriter final : angle::NonCopyable
+{
+ public:
+ ReplayWriter();
+ ~ReplayWriter();
+
+ void setSourceFileSizeThreshold(size_t sourceFileSizeThreshold);
+ void setFilenamePattern(const std::string &pattern);
+ void setCaptureLabel(const std::string &label);
+ void setSourcePrologue(const std::string &prologue);
+ void setHeaderPrologue(const std::string &prologue);
+
+ void addPublicFunction(const std::string &functionProto,
+ const std::stringstream &headerStream,
+ const std::stringstream &bodyStream);
+ void addPrivateFunction(const std::string &functionProto,
+ const std::stringstream &headerStream,
+ const std::stringstream &bodyStream);
+ std::string getInlineVariableName(EntryPoint entryPoint, const std::string &paramName);
+
+ std::string getInlineStringSetVariableName(EntryPoint entryPoint,
+ const std::string &paramName,
+ const std::vector<std::string> &strings,
+ bool *isNewEntryOut);
+
+ void saveFrame();
+ void saveFrameIfFull();
+ void saveIndexFilesAndHeader();
+ void saveSetupFile();
+
+ std::vector<std::string> getAndResetWrittenFiles();
+
+ private:
+ static std::string GetVarName(EntryPoint entryPoint, const std::string &paramName, int counter);
+
+ void saveHeader();
+ void writeReplaySource(const std::string &filename);
+ void addWrittenFile(const std::string &filename);
+ size_t getStoredReplaySourceSize() const;
+
+ size_t mSourceFileSizeThreshold;
+ size_t mFrameIndex;
+
+ DataTracker mDataTracker;
+ std::string mFilenamePattern;
+ std::string mCaptureLabel;
+ std::string mSourcePrologue;
+ std::string mHeaderPrologue;
+
+ std::vector<std::string> mReplayHeaders;
+ std::vector<std::string> mGlobalVariableDeclarations;
+
+ std::vector<std::string> mPublicFunctionPrototypes;
+ std::vector<std::string> mPublicFunctions;
+
+ std::vector<std::string> mPrivateFunctionPrototypes;
+ std::vector<std::string> mPrivateFunctions;
+
+ std::vector<std::string> mWrittenFiles;
+};
+
+using BufferCalls = std::map<GLuint, std::vector<CallCapture>>;
+
+// true means mapped, false means unmapped
+using BufferMapStatusMap = std::map<GLuint, bool>;
+
+using FenceSyncSet = std::set<GLsync>;
+using FenceSyncCalls = std::map<GLsync, std::vector<CallCapture>>;
+
+// For default uniforms, we need to track which ones are dirty, and the series of calls to reset.
+// Each program has unique default uniforms, and each uniform has one or more locations in the
+// default buffer. For reset efficiency, we track only the uniforms dirty by location, per program.
+
+// A set of all default uniforms (per program) that were modified during the run
+using DefaultUniformLocationsSet = std::set<gl::UniformLocation>;
+using DefaultUniformLocationsPerProgramMap =
+ std::map<gl::ShaderProgramID, DefaultUniformLocationsSet>;
+
+// A map of programs which maps to locations and their reset calls
+using DefaultUniformCallsPerLocationMap = std::map<gl::UniformLocation, std::vector<CallCapture>>;
+using DefaultUniformCallsPerProgramMap =
+ std::map<gl::ShaderProgramID, DefaultUniformCallsPerLocationMap>;
+
+using DefaultUniformBaseLocationMap =
+ std::map<std::pair<gl::ShaderProgramID, gl::UniformLocation>, gl::UniformLocation>;
+
+using ResourceSet = std::set<GLuint>;
+using ResourceCalls = std::map<GLuint, std::vector<CallCapture>>;
+
+class TrackedResource final : angle::NonCopyable
+{
+ public:
+ TrackedResource();
+ ~TrackedResource();
+
+ const ResourceSet &getStartingResources() const { return mStartingResources; }
+ ResourceSet &getStartingResources() { return mStartingResources; }
+ const ResourceSet &getNewResources() const { return mNewResources; }
+ ResourceSet &getNewResources() { return mNewResources; }
+ const ResourceSet &getResourcesToRegen() const { return mResourcesToRegen; }
+ ResourceSet &getResourcesToRegen() { return mResourcesToRegen; }
+ const ResourceSet &getResourcesToRestore() const { return mResourcesToRestore; }
+ ResourceSet &getResourcesToRestore() { return mResourcesToRestore; }
+
+ void setGennedResource(GLuint id);
+ void setDeletedResource(GLuint id);
+ void setModifiedResource(GLuint id);
+ bool resourceIsGenerated(GLuint id);
+
+ ResourceCalls &getResourceRegenCalls() { return mResourceRegenCalls; }
+ ResourceCalls &getResourceRestoreCalls() { return mResourceRestoreCalls; }
+
+ private:
+ // Resource regen calls will gen a resource
+ ResourceCalls mResourceRegenCalls;
+ // Resource restore calls will restore the contents of a resource
+ ResourceCalls mResourceRestoreCalls;
+
+ // Resources created during startup
+ ResourceSet mStartingResources;
+
+ // Resources created during the run that need to be deleted
+ ResourceSet mNewResources;
+ // Resources deleted during the run that need to be recreated
+ ResourceSet mResourcesToRegen;
+ // Resources modified during the run that need to be restored
+ ResourceSet mResourcesToRestore;
+};
+
+using TrackedResourceArray =
+ std::array<TrackedResource, static_cast<uint32_t>(ResourceIDType::EnumCount)>;
+
+// Helper to track resource changes during the capture
+class ResourceTracker final : angle::NonCopyable
+{
+ public:
+ ResourceTracker();
+ ~ResourceTracker();
+
+ BufferCalls &getBufferMapCalls() { return mBufferMapCalls; }
+ BufferCalls &getBufferUnmapCalls() { return mBufferUnmapCalls; }
+
+ std::vector<CallCapture> &getBufferBindingCalls() { return mBufferBindingCalls; }
+
+ void setBufferMapped(gl::ContextID contextID, GLuint id);
+ void setBufferUnmapped(gl::ContextID contextID, GLuint id);
+
+ bool getStartingBuffersMappedCurrent(GLuint id) const;
+ bool getStartingBuffersMappedInitial(GLuint id) const;
+
+ void setStartingBufferMapped(GLuint id, bool mapped)
+ {
+ // Track the current state (which will change throughout the trace)
+ mStartingBuffersMappedCurrent[id] = mapped;
+
+ // And the initial state, to compare during frame loop reset
+ mStartingBuffersMappedInitial[id] = mapped;
+ }
+
+ void onShaderProgramAccess(gl::ShaderProgramID shaderProgramID);
+ uint32_t getMaxShaderPrograms() const { return mMaxShaderPrograms; }
+
+ FenceSyncSet &getStartingFenceSyncs() { return mStartingFenceSyncs; }
+ FenceSyncCalls &getFenceSyncRegenCalls() { return mFenceSyncRegenCalls; }
+ FenceSyncSet &getFenceSyncsToRegen() { return mFenceSyncsToRegen; }
+ void setDeletedFenceSync(GLsync sync);
+
+ DefaultUniformLocationsPerProgramMap &getDefaultUniformsToReset()
+ {
+ return mDefaultUniformsToReset;
+ }
+ DefaultUniformCallsPerLocationMap &getDefaultUniformResetCalls(gl::ShaderProgramID id)
+ {
+ return mDefaultUniformResetCalls[id];
+ }
+ void setModifiedDefaultUniform(gl::ShaderProgramID programID, gl::UniformLocation location);
+ void setDefaultUniformBaseLocation(gl::ShaderProgramID programID,
+ gl::UniformLocation location,
+ gl::UniformLocation baseLocation);
+ gl::UniformLocation getDefaultUniformBaseLocation(gl::ShaderProgramID programID,
+ gl::UniformLocation location)
+ {
+ ASSERT(mDefaultUniformBaseLocations.find({programID, location}) !=
+ mDefaultUniformBaseLocations.end());
+ return mDefaultUniformBaseLocations[{programID, location}];
+ }
+
+ TrackedResource &getTrackedResource(gl::ContextID contextID, ResourceIDType type);
+
+ void getContextIDs(std::set<gl::ContextID> &idsOut);
+
+ std::map<void *, egl::AttributeMap> &getImageToAttribTable() { return mMatchImageToAttribs; }
+
+ std::map<GLuint, void *> &getTextureIDToImageTable() { return mMatchTextureIDToImage; }
+
+ private:
+ // Buffer map calls will map a buffer with correct offset, length, and access flags
+ BufferCalls mBufferMapCalls;
+ // Buffer unmap calls will bind and unmap a given buffer
+ BufferCalls mBufferUnmapCalls;
+
+ // Buffer binding calls to restore bindings recorded during MEC
+ std::vector<CallCapture> mBufferBindingCalls;
+
+ // Whether a given buffer was mapped at the start of the trace
+ BufferMapStatusMap mStartingBuffersMappedInitial;
+ // The status of buffer mapping throughout the trace, modified with each Map/Unmap call
+ BufferMapStatusMap mStartingBuffersMappedCurrent;
+
+ // Maximum accessed shader program ID.
+ uint32_t mMaxShaderPrograms = 0;
+
+ // Fence sync objects created during MEC setup
+ FenceSyncSet mStartingFenceSyncs;
+ // Fence sync regen calls will create a fence sync objects
+ FenceSyncCalls mFenceSyncRegenCalls;
+ // Fence syncs to regen are a list of starting fence sync objects that were deleted and need to
+ // be regen'ed.
+ FenceSyncSet mFenceSyncsToRegen;
+
+ // Default uniforms that were modified during the run
+ DefaultUniformLocationsPerProgramMap mDefaultUniformsToReset;
+ // Calls per default uniform to return to original state
+ DefaultUniformCallsPerProgramMap mDefaultUniformResetCalls;
+
+ // Base location of arrayed uniforms
+ DefaultUniformBaseLocationMap mDefaultUniformBaseLocations;
+
+ // Tracked resources per context
+ TrackedResourceArray mTrackedResourcesShared;
+ std::map<gl::ContextID, TrackedResourceArray> mTrackedResourcesPerContext;
+
+ std::map<void *, egl::AttributeMap> mMatchImageToAttribs;
+ std::map<GLuint, void *> mMatchTextureIDToImage;
+};
+
+// Used by the CPP replay to filter out unnecessary code.
+using HasResourceTypeMap = angle::PackedEnumBitSet<ResourceIDType>;
+
+// Map of ResourceType to IDs and range of setup calls
+using ResourceIDToSetupCallsMap =
+ PackedEnumMap<ResourceIDType, std::map<GLuint, gl::Range<size_t>>>;
+
+// Map of buffer ID to offset and size used when mapped
+using BufferDataMap = std::map<gl::BufferID, std::pair<GLintptr, GLsizeiptr>>;
+
+// A dictionary of sources indexed by shader type.
+using ProgramSources = gl::ShaderMap<std::string>;
+
+// Maps from IDs to sources.
+using ShaderSourceMap = std::map<gl::ShaderProgramID, std::string>;
+using ProgramSourceMap = std::map<gl::ShaderProgramID, ProgramSources>;
+
+// Map from textureID to level and data
+using TextureLevels = std::map<GLint, std::vector<uint8_t>>;
+using TextureLevelDataMap = std::map<gl::TextureID, TextureLevels>;
+
+struct SurfaceParams
+{
+ gl::Extents extents;
+ egl::ColorSpace colorSpace;
+};
+
+// Map from ContextID to SurfaceParams
+using SurfaceParamsMap = std::map<gl::ContextID, SurfaceParams>;
+
+using CallVector = std::vector<std::vector<CallCapture> *>;
+
+// A map from API entry point to calls
+using CallResetMap = std::map<angle::EntryPoint, std::vector<CallCapture>>;
+
+// StateResetHelper provides a simple way to track whether an entry point has been called during the
+// trace, along with the reset calls to get it back to starting state. This is useful for things
+// that are one dimensional, like context bindings or context state.
+class StateResetHelper final : angle::NonCopyable
+{
+ public:
+ StateResetHelper();
+ ~StateResetHelper();
+
+ const std::set<angle::EntryPoint> &getDirtyEntryPoints() const { return mDirtyEntryPoints; }
+ void setEntryPointDirty(EntryPoint entryPoint) { mDirtyEntryPoints.insert(entryPoint); }
+
+ CallResetMap &getResetCalls() { return mResetCalls; }
+ const CallResetMap &getResetCalls() const { return mResetCalls; }
+
+ void setDefaultResetCalls(const gl::Context *context, angle::EntryPoint);
+
+ private:
+ // Dirty state per entry point
+ std::set<angle::EntryPoint> mDirtyEntryPoints;
+
+ // Reset calls per API entry point
+ CallResetMap mResetCalls;
+};
+
+class FrameCapture final : angle::NonCopyable
+{
+ public:
+ FrameCapture();
+ ~FrameCapture();
+
+ std::vector<CallCapture> &getSetupCalls() { return mSetupCalls; }
+ void clearSetupCalls() { mSetupCalls.clear(); }
+
+ StateResetHelper &getStateResetHelper() { return mStateResetHelper; }
+
+ void reset();
+
+ private:
+ std::vector<CallCapture> mSetupCalls;
+
+ StateResetHelper mStateResetHelper;
+};
+
+// Page range inside a coherent buffer
+struct PageRange
+{
+ PageRange(size_t start, size_t end);
+ ~PageRange();
+
+ // Relative start page
+ size_t start;
+
+ // First page after the relative end
+ size_t end;
+};
+
+// Memory address range defined by start and size
+struct AddressRange
+{
+ AddressRange();
+ AddressRange(uintptr_t start, size_t size);
+ ~AddressRange();
+
+ uintptr_t end();
+
+ uintptr_t start;
+ size_t size;
+};
+
+// Used to handle protection of buffers that overlap in pages.
+enum class PageSharingType
+{
+ NoneShared,
+ FirstShared,
+ LastShared,
+ FirstAndLastShared
+};
+
+class CoherentBuffer
+{
+ public:
+ CoherentBuffer(uintptr_t start, size_t size, size_t pageSize);
+ ~CoherentBuffer();
+
+ // Sets the a range in the buffer clean and protects a selected range
+ void protectPageRange(const PageRange &pageRange);
+
+ // Sets a page dirty state and sets it's protection
+ void setDirty(size_t relativePage, bool dirty);
+
+ // Removes protection
+ void removeProtection(PageSharingType sharingType);
+
+ bool contains(size_t page, size_t *relativePage);
+ bool isDirty();
+
+ // Returns dirty page ranges
+ std::vector<PageRange> getDirtyPageRanges();
+
+ // Calculates address range from page range
+ AddressRange getDirtyAddressRange(const PageRange &dirtyPageRange);
+ AddressRange getRange();
+
+ private:
+ // Actual buffer start and size
+ AddressRange mRange;
+
+ // Start and size of page aligned protected area
+ AddressRange mProtectionRange;
+
+ // Start and end of protection in relative pages, calculated from mProtectionRange.
+ size_t mProtectionStartPage;
+ size_t mProtectionEndPage;
+
+ size_t mPageCount;
+ size_t mPageSize;
+
+ // Clean pages are protected
+ std::vector<bool> mDirtyPages;
+};
+
+class CoherentBufferTracker final : angle::NonCopyable
+{
+ public:
+ CoherentBufferTracker();
+ ~CoherentBufferTracker();
+
+ bool isDirty(gl::BufferID id);
+ void addBuffer(gl::BufferID id, uintptr_t start, size_t size);
+ void removeBuffer(gl::BufferID id);
+ void disable();
+ void enable();
+ void onEndFrame();
+
+ private:
+ // Detect overlapping pages when removing protection
+ PageSharingType doesBufferSharePage(gl::BufferID id);
+
+ // Returns a map to found buffers and the corresponding pages for a given address.
+ // For addresses that are in a page shared by 2 buffers, 2 results are returned.
+ HashMap<std::shared_ptr<CoherentBuffer>, size_t> getBufferPagesForAddress(uintptr_t address);
+ PageFaultHandlerRangeType handleWrite(uintptr_t address);
+ bool haveBuffer(gl::BufferID id);
+
+ public:
+ std::mutex mMutex;
+ HashMap<GLuint, std::shared_ptr<CoherentBuffer>> mBuffers;
+
+ private:
+ bool mEnabled = false;
+ std::unique_ptr<PageFaultHandler> mPageFaultHandler;
+ size_t mPageSize;
+};
+
+// Shared class for any items that need to be tracked by FrameCapture across shared contexts
+class FrameCaptureShared final : angle::NonCopyable
+{
+ public:
+ FrameCaptureShared();
+ ~FrameCaptureShared();
+
+ void captureCall(const gl::Context *context, CallCapture &&call, bool isCallValid);
+ void checkForCaptureTrigger();
+ void onEndFrame(const gl::Context *context);
+ void onDestroyContext(const gl::Context *context);
+ void onMakeCurrent(const gl::Context *context, const egl::Surface *drawSurface);
+ bool enabled() const { return mEnabled; }
+
+ bool isCapturing() const;
+ void replay(gl::Context *context);
+ uint32_t getFrameCount() const;
+
+ // Returns a frame index starting from "1" as the first frame.
+ uint32_t getReplayFrameIndex() const;
+
+ void trackBufferMapping(const gl::Context *context,
+ CallCapture *call,
+ gl::BufferID id,
+ gl::Buffer *buffer,
+ GLintptr offset,
+ GLsizeiptr length,
+ bool writable,
+ bool coherent);
+
+ void trackTextureUpdate(const gl::Context *context, const CallCapture &call);
+ void trackDefaultUniformUpdate(const gl::Context *context, const CallCapture &call);
+ void trackVertexArrayUpdate(const gl::Context *context, const CallCapture &call);
+
+ const std::string &getShaderSource(gl::ShaderProgramID id) const;
+ void setShaderSource(gl::ShaderProgramID id, std::string sources);
+
+ const ProgramSources &getProgramSources(gl::ShaderProgramID id) const;
+ void setProgramSources(gl::ShaderProgramID id, ProgramSources sources);
+
+ // Load data from a previously stored texture level
+ const std::vector<uint8_t> &retrieveCachedTextureLevel(gl::TextureID id,
+ gl::TextureTarget target,
+ GLint level);
+
+ // Create new texture level data and copy the source into it
+ void copyCachedTextureLevel(const gl::Context *context,
+ gl::TextureID srcID,
+ GLint srcLevel,
+ gl::TextureID dstID,
+ GLint dstLevel,
+ const CallCapture &call);
+
+ // Create the location that should be used to cache texture level data
+ std::vector<uint8_t> &getCachedTextureLevelData(gl::Texture *texture,
+ gl::TextureTarget target,
+ GLint level,
+ EntryPoint entryPoint);
+
+ // Capture coherent buffer storages
+ void captureCoherentBufferSnapshot(const gl::Context *context, gl::BufferID bufferID);
+
+ // Remove any cached texture levels on deletion
+ void deleteCachedTextureLevelData(gl::TextureID id);
+
+ void eraseBufferDataMapEntry(const gl::BufferID bufferId)
+ {
+ const auto &bufferDataInfo = mBufferDataMap.find(bufferId);
+ if (bufferDataInfo != mBufferDataMap.end())
+ {
+ mBufferDataMap.erase(bufferDataInfo);
+ }
+ }
+
+ bool hasBufferData(gl::BufferID bufferID)
+ {
+ const auto &bufferDataInfo = mBufferDataMap.find(bufferID);
+ if (bufferDataInfo != mBufferDataMap.end())
+ {
+ return true;
+ }
+ return false;
+ }
+
+ std::pair<GLintptr, GLsizeiptr> getBufferDataOffsetAndLength(gl::BufferID bufferID)
+ {
+ const auto &bufferDataInfo = mBufferDataMap.find(bufferID);
+ ASSERT(bufferDataInfo != mBufferDataMap.end());
+ return bufferDataInfo->second;
+ }
+
+ void setCaptureActive() { mCaptureActive = true; }
+ void setCaptureInactive() { mCaptureActive = false; }
+ bool isCaptureActive() { return mCaptureActive; }
+ bool usesMidExecutionCapture() { return mCaptureStartFrame > 1; }
+
+ gl::ContextID getWindowSurfaceContextID() const { return mWindowSurfaceContextID; }
+
+ void markResourceSetupCallsInactive(std::vector<CallCapture> *setupCalls,
+ ResourceIDType type,
+ GLuint id,
+ gl::Range<size_t> range);
+
+ void updateReadBufferSize(size_t readBufferSize)
+ {
+ mReadBufferSize = std::max(mReadBufferSize, readBufferSize);
+ }
+
+ template <typename ResourceType>
+ void handleGennedResource(const gl::Context *context, ResourceType resourceID)
+ {
+ if (isCaptureActive())
+ {
+ ResourceIDType idType = GetResourceIDTypeFromType<ResourceType>::IDType;
+ TrackedResource &tracker = mResourceTracker.getTrackedResource(context->id(), idType);
+ tracker.setGennedResource(resourceID.value);
+ }
+ }
+
+ template <typename ResourceType>
+ bool resourceIsGenerated(const gl::Context *context, ResourceType resourceID)
+ {
+ ResourceIDType idType = GetResourceIDTypeFromType<ResourceType>::IDType;
+ TrackedResource &tracker = mResourceTracker.getTrackedResource(context->id(), idType);
+ return tracker.resourceIsGenerated(resourceID.value);
+ }
+
+ template <typename ResourceType>
+ void handleDeletedResource(const gl::Context *context, ResourceType resourceID)
+ {
+ if (isCaptureActive())
+ {
+ ResourceIDType idType = GetResourceIDTypeFromType<ResourceType>::IDType;
+ TrackedResource &tracker = mResourceTracker.getTrackedResource(context->id(), idType);
+ tracker.setDeletedResource(resourceID.value);
+ }
+ }
+
+ private:
+ void writeJSON(const gl::Context *context);
+ void writeCppReplayIndexFiles(const gl::Context *context, bool writeResetContextCall);
+ void writeMainContextCppReplay(const gl::Context *context,
+ const std::vector<CallCapture> &setupCalls,
+ StateResetHelper &StateResetHelper);
+
+ void captureClientArraySnapshot(const gl::Context *context,
+ size_t vertexCount,
+ size_t instanceCount);
+ void captureMappedBufferSnapshot(const gl::Context *context, const CallCapture &call);
+
+ void copyCompressedTextureData(const gl::Context *context, const CallCapture &call);
+ void captureCompressedTextureData(const gl::Context *context, const CallCapture &call);
+
+ void reset();
+ void maybeOverrideEntryPoint(const gl::Context *context,
+ CallCapture &call,
+ std::vector<CallCapture> &newCalls);
+ void maybeCapturePreCallUpdates(const gl::Context *context,
+ CallCapture &call,
+ std::vector<CallCapture> *shareGroupSetupCalls,
+ ResourceIDToSetupCallsMap *resourceIDToSetupCalls);
+ template <typename ParamValueType>
+ void maybeGenResourceOnBind(const gl::Context *context, CallCapture &call);
+ void maybeCapturePostCallUpdates(const gl::Context *context);
+ void maybeCaptureDrawArraysClientData(const gl::Context *context,
+ CallCapture &call,
+ size_t instanceCount);
+ void maybeCaptureDrawElementsClientData(const gl::Context *context,
+ CallCapture &call,
+ size_t instanceCount);
+ void maybeCaptureCoherentBuffers(const gl::Context *context);
+ void updateCopyImageSubData(CallCapture &call);
+ void overrideProgramBinary(const gl::Context *context,
+ CallCapture &call,
+ std::vector<CallCapture> &outCalls);
+ void updateResourceCountsFromParamCapture(const ParamCapture &param, ResourceIDType idType);
+ void updateResourceCountsFromCallCapture(const CallCapture &call);
+
+ void runMidExecutionCapture(const gl::Context *context);
+
+ void scanSetupCalls(const gl::Context *context, std::vector<CallCapture> &setupCalls);
+
+ static void ReplayCall(gl::Context *context,
+ ReplayContext *replayContext,
+ const CallCapture &call);
+
+ std::vector<CallCapture> mFrameCalls;
+ gl::ContextID mLastContextId;
+
+ // We save one large buffer of binary data for the whole CPP replay.
+ // This simplifies a lot of file management.
+ std::vector<uint8_t> mBinaryData;
+
+ bool mEnabled;
+ bool mSerializeStateEnabled;
+ std::string mOutDirectory;
+ std::string mCaptureLabel;
+ bool mCompression;
+ gl::AttribArray<int> mClientVertexArrayMap;
+ uint32_t mFrameIndex;
+ uint32_t mCaptureStartFrame;
+ uint32_t mCaptureEndFrame;
+ bool mIsFirstFrame = true;
+ bool mWroteIndexFile = false;
+ SurfaceParamsMap mDrawSurfaceParams;
+ gl::AttribArray<size_t> mClientArraySizes;
+ size_t mReadBufferSize;
+ HasResourceTypeMap mHasResourceType;
+ ResourceIDToSetupCallsMap mResourceIDToSetupCalls;
+ BufferDataMap mBufferDataMap;
+ bool mValidateSerializedState = false;
+ std::string mValidationExpression;
+ bool mTrimEnabled = true;
+ PackedEnumMap<ResourceIDType, uint32_t> mMaxAccessedResourceIDs;
+ CoherentBufferTracker mCoherentBufferTracker;
+
+ ResourceTracker mResourceTracker;
+ ReplayWriter mReplayWriter;
+
+ // If you don't know which frame you want to start capturing at, use the capture trigger.
+ // Initialize it to the number of frames you want to capture, and then clear the value to 0 when
+ // you reach the content you want to capture. Currently only available on Android.
+ uint32_t mCaptureTrigger;
+
+ bool mCaptureActive;
+ std::vector<uint32_t> mActiveFrameIndices;
+
+ // Cache most recently compiled and linked sources.
+ ShaderSourceMap mCachedShaderSource;
+ ProgramSourceMap mCachedProgramSources;
+
+ gl::ContextID mWindowSurfaceContextID;
+
+ std::vector<CallCapture> mShareGroupSetupCalls;
+};
+
+template <typename CaptureFuncT, typename... ArgsT>
+void CaptureCallToFrameCapture(CaptureFuncT captureFunc,
+ bool isCallValid,
+ gl::Context *context,
+ ArgsT... captureParams)
+{
+ FrameCaptureShared *frameCaptureShared = context->getShareGroup()->getFrameCaptureShared();
+ if (!frameCaptureShared->isCapturing())
+ {
+ return;
+ }
+
+ CallCapture call = captureFunc(context->getState(), isCallValid, captureParams...);
+
+ frameCaptureShared->captureCall(context, std::move(call), isCallValid);
+}
+
+template <typename T>
+void ParamBuffer::addValueParam(const char *paramName, ParamType paramType, T paramValue)
+{
+ ParamCapture capture(paramName, paramType);
+ InitParamValue(paramType, paramValue, &capture.value);
+ mParamCaptures.emplace_back(std::move(capture));
+}
+
+template <typename T>
+void ParamBuffer::setValueParamAtIndex(const char *paramName,
+ ParamType paramType,
+ T paramValue,
+ int index)
+{
+ ASSERT(mParamCaptures.size() > static_cast<size_t>(index));
+
+ ParamCapture capture(paramName, paramType);
+ InitParamValue(paramType, paramValue, &capture.value);
+ mParamCaptures[index] = std::move(capture);
+}
+
+template <typename T>
+void ParamBuffer::addEnumParam(const char *paramName,
+ gl::GLESEnum enumGroup,
+ ParamType paramType,
+ T paramValue)
+{
+ ParamCapture capture(paramName, paramType);
+ InitParamValue(paramType, paramValue, &capture.value);
+ capture.enumGroup = enumGroup;
+ mParamCaptures.emplace_back(std::move(capture));
+}
+
+template <typename T>
+void ParamBuffer::addEnumParam(const char *paramName,
+ gl::BigGLEnum enumGroup,
+ ParamType paramType,
+ T paramValue)
+{
+ ParamCapture capture(paramName, paramType);
+ InitParamValue(paramType, paramValue, &capture.value);
+ capture.bigGLEnum = enumGroup;
+ mParamCaptures.emplace_back(std::move(capture));
+}
+
+// Pointer capture helpers.
+void CaptureMemory(const void *source, size_t size, ParamCapture *paramCapture);
+void CaptureString(const GLchar *str, ParamCapture *paramCapture);
+void CaptureStringLimit(const GLchar *str, uint32_t limit, ParamCapture *paramCapture);
+void CaptureVertexPointerGLES1(const gl::State &glState,
+ gl::ClientVertexArrayType type,
+ const void *pointer,
+ ParamCapture *paramCapture);
+
+gl::Program *GetProgramForCapture(const gl::State &glState, gl::ShaderProgramID handle);
+
+// For GetIntegerv, GetFloatv, etc.
+void CaptureGetParameter(const gl::State &glState,
+ GLenum pname,
+ size_t typeSize,
+ ParamCapture *paramCapture);
+
+void CaptureGetActiveUniformBlockivParameters(const gl::State &glState,
+ gl::ShaderProgramID handle,
+ gl::UniformBlockIndex uniformBlockIndex,
+ GLenum pname,
+ ParamCapture *paramCapture);
+
+template <typename T>
+void CaptureClearBufferValue(GLenum buffer, const T *value, ParamCapture *paramCapture)
+{
+ // Per the spec, color buffers have a vec4, the rest a single value
+ uint32_t valueSize = (buffer == GL_COLOR) ? 4 : 1;
+ CaptureMemory(value, valueSize * sizeof(T), paramCapture);
+}
+
+void CaptureGenHandlesImpl(GLsizei n, GLuint *handles, ParamCapture *paramCapture);
+
+template <typename T>
+void CaptureGenHandles(GLsizei n, T *handles, ParamCapture *paramCapture)
+{
+ paramCapture->dataNElements = n;
+ CaptureGenHandlesImpl(n, reinterpret_cast<GLuint *>(handles), paramCapture);
+}
+
+template <typename T>
+void CaptureArray(T *elements, GLsizei n, ParamCapture *paramCapture)
+{
+ paramCapture->dataNElements = n;
+ CaptureMemory(elements, n * sizeof(T), paramCapture);
+}
+
+void CaptureShaderStrings(GLsizei count,
+ const GLchar *const *strings,
+ const GLint *length,
+ ParamCapture *paramCapture);
+
+template <ParamType ParamT, typename T>
+void WriteParamValueReplay(std::ostream &os, const CallCapture &call, T value);
+
+template <>
+void WriteParamValueReplay<ParamType::TGLboolean>(std::ostream &os,
+ const CallCapture &call,
+ GLboolean value);
+
+template <>
+void WriteParamValueReplay<ParamType::TGLbooleanPointer>(std::ostream &os,
+ const CallCapture &call,
+ GLboolean *value);
+
+template <>
+void WriteParamValueReplay<ParamType::TvoidConstPointer>(std::ostream &os,
+ const CallCapture &call,
+ const void *value);
+
+template <>
+void WriteParamValueReplay<ParamType::TvoidPointer>(std::ostream &os,
+ const CallCapture &call,
+ void *value);
+
+template <>
+void WriteParamValueReplay<ParamType::TGLfloatConstPointer>(std::ostream &os,
+ const CallCapture &call,
+ const GLfloat *value);
+
+template <>
+void WriteParamValueReplay<ParamType::TGLintConstPointer>(std::ostream &os,
+ const CallCapture &call,
+ const GLint *value);
+
+template <>
+void WriteParamValueReplay<ParamType::TGLsizeiPointer>(std::ostream &os,
+ const CallCapture &call,
+ GLsizei *value);
+
+template <>
+void WriteParamValueReplay<ParamType::TGLuintConstPointer>(std::ostream &os,
+ const CallCapture &call,
+ const GLuint *value);
+
+template <>
+void WriteParamValueReplay<ParamType::TGLDEBUGPROCKHR>(std::ostream &os,
+ const CallCapture &call,
+ GLDEBUGPROCKHR value);
+
+template <>
+void WriteParamValueReplay<ParamType::TGLDEBUGPROC>(std::ostream &os,
+ const CallCapture &call,
+ GLDEBUGPROC value);
+
+template <>
+void WriteParamValueReplay<ParamType::TBufferID>(std::ostream &os,
+ const CallCapture &call,
+ gl::BufferID value);
+
+template <>
+void WriteParamValueReplay<ParamType::TFenceNVID>(std::ostream &os,
+ const CallCapture &call,
+ gl::FenceNVID value);
+
+template <>
+void WriteParamValueReplay<ParamType::TFramebufferID>(std::ostream &os,
+ const CallCapture &call,
+ gl::FramebufferID value);
+
+template <>
+void WriteParamValueReplay<ParamType::TMemoryObjectID>(std::ostream &os,
+ const CallCapture &call,
+ gl::MemoryObjectID value);
+
+template <>
+void WriteParamValueReplay<ParamType::TProgramPipelineID>(std::ostream &os,
+ const CallCapture &call,
+ gl::ProgramPipelineID value);
+
+template <>
+void WriteParamValueReplay<ParamType::TQueryID>(std::ostream &os,
+ const CallCapture &call,
+ gl::QueryID value);
+
+template <>
+void WriteParamValueReplay<ParamType::TRenderbufferID>(std::ostream &os,
+ const CallCapture &call,
+ gl::RenderbufferID value);
+
+template <>
+void WriteParamValueReplay<ParamType::TSamplerID>(std::ostream &os,
+ const CallCapture &call,
+ gl::SamplerID value);
+
+template <>
+void WriteParamValueReplay<ParamType::TSemaphoreID>(std::ostream &os,
+ const CallCapture &call,
+ gl::SemaphoreID value);
+
+template <>
+void WriteParamValueReplay<ParamType::TShaderProgramID>(std::ostream &os,
+ const CallCapture &call,
+ gl::ShaderProgramID value);
+
+template <>
+void WriteParamValueReplay<ParamType::TTextureID>(std::ostream &os,
+ const CallCapture &call,
+ gl::TextureID value);
+
+template <>
+void WriteParamValueReplay<ParamType::TTransformFeedbackID>(std::ostream &os,
+ const CallCapture &call,
+ gl::TransformFeedbackID value);
+
+template <>
+void WriteParamValueReplay<ParamType::TVertexArrayID>(std::ostream &os,
+ const CallCapture &call,
+ gl::VertexArrayID value);
+
+template <>
+void WriteParamValueReplay<ParamType::TUniformLocation>(std::ostream &os,
+ const CallCapture &call,
+ gl::UniformLocation value);
+
+template <>
+void WriteParamValueReplay<ParamType::TUniformBlockIndex>(std::ostream &os,
+ const CallCapture &call,
+ gl::UniformBlockIndex value);
+
+template <>
+void WriteParamValueReplay<ParamType::TGLsync>(std::ostream &os,
+ const CallCapture &call,
+ GLsync value);
+
+template <>
+void WriteParamValueReplay<ParamType::TGLeglImageOES>(std::ostream &os,
+ const CallCapture &call,
+ GLeglImageOES value);
+
+template <>
+void WriteParamValueReplay<ParamType::TGLubyte>(std::ostream &os,
+ const CallCapture &call,
+ GLubyte value);
+
+template <>
+void WriteParamValueReplay<ParamType::TEGLContext>(std::ostream &os,
+ const CallCapture &call,
+ EGLContext value);
+
+template <>
+void WriteParamValueReplay<ParamType::TEGLDisplay>(std::ostream &os,
+ const CallCapture &call,
+ EGLContext value);
+
+template <>
+void WriteParamValueReplay<ParamType::TEGLSurface>(std::ostream &os,
+ const CallCapture &call,
+ EGLContext value);
+
+template <>
+void WriteParamValueReplay<ParamType::TEGLDEBUGPROCKHR>(std::ostream &os,
+ const CallCapture &call,
+ EGLDEBUGPROCKHR value);
+
+template <>
+void WriteParamValueReplay<ParamType::TEGLGetBlobFuncANDROID>(std::ostream &os,
+ const CallCapture &call,
+ EGLGetBlobFuncANDROID value);
+
+template <>
+void WriteParamValueReplay<ParamType::TEGLSetBlobFuncANDROID>(std::ostream &os,
+ const CallCapture &call,
+ EGLSetBlobFuncANDROID value);
+template <>
+void WriteParamValueReplay<ParamType::TEGLClientBuffer>(std::ostream &os,
+ const CallCapture &call,
+ EGLClientBuffer value);
+
+template <>
+void WriteParamValueReplay<ParamType::TEGLConfig>(std::ostream &os,
+ const CallCapture &call,
+ EGLConfig value);
+
+template <>
+void WriteParamValueReplay<ParamType::TEGLSurface>(std::ostream &os,
+ const CallCapture &call,
+ EGLSurface value);
+
+// General fallback for any unspecific type.
+template <ParamType ParamT, typename T>
+void WriteParamValueReplay(std::ostream &os, const CallCapture &call, T value)
+{
+ os << value;
+}
+} // namespace angle
+
+template <typename T>
+void CaptureTextureAndSamplerParameter_params(GLenum pname,
+ const T *param,
+ angle::ParamCapture *paramCapture)
+{
+ if (pname == GL_TEXTURE_BORDER_COLOR || pname == GL_TEXTURE_CROP_RECT_OES)
+ {
+ CaptureMemory(param, sizeof(T) * 4, paramCapture);
+ }
+ else
+ {
+ CaptureMemory(param, sizeof(T), paramCapture);
+ }
+}
+
+#endif // LIBANGLE_FRAME_CAPTURE_H_
diff --git a/gfx/angle/checkout/src/libANGLE/capture/FrameCapture_mock.cpp b/gfx/angle/checkout/src/libANGLE/capture/FrameCapture_mock.cpp
new file mode 100644
index 0000000000..dc9e44c5bb
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/capture/FrameCapture_mock.cpp
@@ -0,0 +1,55 @@
+//
+// Copyright 2019 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.
+//
+// FrameCapture_mock.cpp:
+// ANGLE mock Frame capture implementation.
+//
+
+#include "libANGLE/capture/FrameCapture.h"
+
+#if ANGLE_CAPTURE_ENABLED
+# error Frame capture must be disabled to include this file.
+#endif // ANGLE_CAPTURE_ENABLED
+
+namespace angle
+{
+CallCapture::~CallCapture() {}
+ParamBuffer::~ParamBuffer() {}
+ParamCapture::~ParamCapture() {}
+ResourceTracker::ResourceTracker() {}
+ResourceTracker::~ResourceTracker() {}
+TrackedResource::TrackedResource() {}
+TrackedResource::~TrackedResource() {}
+StateResetHelper::StateResetHelper() {}
+StateResetHelper::~StateResetHelper() {}
+DataTracker::DataTracker() {}
+DataTracker::~DataTracker() {}
+DataCounters::DataCounters() {}
+DataCounters::~DataCounters() {}
+StringCounters::StringCounters() {}
+StringCounters::~StringCounters() {}
+ReplayWriter::ReplayWriter() {}
+ReplayWriter::~ReplayWriter() {}
+
+FrameCapture::FrameCapture() {}
+FrameCapture::~FrameCapture() {}
+
+FrameCaptureShared::FrameCaptureShared() : mEnabled(false) {}
+FrameCaptureShared::~FrameCaptureShared() {}
+void FrameCaptureShared::onEndFrame(const gl::Context *context) {}
+void FrameCaptureShared::onMakeCurrent(const gl::Context *context, const egl::Surface *drawSurface)
+{}
+void FrameCaptureShared::onDestroyContext(const gl::Context *context) {}
+void FrameCaptureShared::replay(gl::Context *context) {}
+const ProgramSources &FrameCaptureShared::getProgramSources(gl::ShaderProgramID id) const
+{
+ const auto &foundSources = mCachedProgramSources.find(id);
+ return foundSources->second;
+}
+void FrameCaptureShared::setProgramSources(gl::ShaderProgramID id, ProgramSources sources) {}
+
+CoherentBufferTracker::CoherentBufferTracker() {}
+CoherentBufferTracker::~CoherentBufferTracker() {}
+} // namespace angle
diff --git a/gfx/angle/checkout/src/libANGLE/capture/capture_egl.h b/gfx/angle/checkout/src/libANGLE/capture/capture_egl.h
new file mode 100644
index 0000000000..f23bc1a2ce
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/capture/capture_egl.h
@@ -0,0 +1,69 @@
+//
+// Copyright 2022 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.
+//
+// capture_egl.h:
+// EGL capture functions
+//
+
+#ifndef LIBANGLE_CAPTURE_EGL_H_
+#define LIBANGLE_CAPTURE_EGL_H_
+
+#include "libANGLE/Context.h"
+#include "libANGLE/Thread.h"
+#include "libANGLE/capture/FrameCapture.h"
+
+namespace gl
+{
+enum class GLenumGroup;
+}
+
+namespace egl
+{
+
+template <typename CaptureFuncT, typename... ArgsT>
+void CaptureCallToCaptureEGL(CaptureFuncT captureFunc, egl::Thread *thread, ArgsT... captureParams)
+{
+ gl::Context *context = thread->getContext();
+ if (!context)
+ {
+ return;
+ }
+
+ angle::FrameCaptureShared *frameCaptureShared =
+ context->getShareGroup()->getFrameCaptureShared();
+ if (!frameCaptureShared->isCapturing())
+ {
+ return;
+ }
+
+ angle::CallCapture call = captureFunc(captureParams...);
+
+ frameCaptureShared->captureCall(context, std::move(call), true);
+}
+
+angle::CallCapture CaptureCreateNativeClientBufferANDROID(const egl::AttributeMap &attribMap,
+ EGLClientBuffer eglClientBuffer);
+angle::CallCapture CaptureEGLCreateImage(const gl::Context *context,
+ EGLenum target,
+ EGLClientBuffer buffer,
+ const egl::AttributeMap &attributes,
+ egl::Image *image);
+angle::CallCapture CaptureEGLDestroyImage(egl::Display *display, egl::Image *image);
+
+angle::CallCapture CaptureEGLCreatePbufferSurface(const AttributeMap &attrib_list,
+ egl::Surface *surface);
+
+angle::CallCapture CaptureEGLDestroySurface(Display *display, Surface *surface);
+
+angle::CallCapture CaptureEGLBindTexImage(egl::Surface *surface, EGLint buffer);
+
+angle::CallCapture CaptureEGLReleaseTexImage(egl::Surface *surface, EGLint buffer);
+
+angle::CallCapture CaptureEGLMakeCurrent(Surface *drawSurface,
+ Surface *readSurface,
+ gl::Context *context);
+} // namespace egl
+
+#endif // LIBANGLE_FRAME_CAPTURE_H_
diff --git a/gfx/angle/checkout/src/libANGLE/capture/capture_gl_1_autogen.h b/gfx/angle/checkout/src/libANGLE/capture/capture_gl_1_autogen.h
new file mode 100644
index 0000000000..7e4eea7af1
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/capture/capture_gl_1_autogen.h
@@ -0,0 +1,2072 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml and gl_angle_ext.xml.
+//
+// Copyright 2020 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.
+//
+// capture_gl_1_autogen.h:
+// Capture functions for the OpenGL ES Desktop GL 1.x entry points.
+
+#ifndef LIBANGLE_CAPTURE_GL_1_AUTOGEN_H_
+#define LIBANGLE_CAPTURE_GL_1_AUTOGEN_H_
+
+#include "common/PackedEnums.h"
+#include "libANGLE/capture/FrameCapture.h"
+
+namespace gl
+{
+
+// Method Captures
+
+// GL 1.0
+angle::CallCapture CaptureAccum(const State &glState, bool isCallValid, GLenum op, GLfloat value);
+angle::CallCapture CaptureBegin(const State &glState, bool isCallValid, GLenum mode);
+angle::CallCapture CaptureBitmap(const State &glState,
+ bool isCallValid,
+ GLsizei width,
+ GLsizei height,
+ GLfloat xorig,
+ GLfloat yorig,
+ GLfloat xmove,
+ GLfloat ymove,
+ const GLubyte *bitmap);
+angle::CallCapture CaptureCallList(const State &glState, bool isCallValid, GLuint list);
+angle::CallCapture CaptureCallLists(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ GLenum type,
+ const void *lists);
+angle::CallCapture CaptureClearAccum(const State &glState,
+ bool isCallValid,
+ GLfloat red,
+ GLfloat green,
+ GLfloat blue,
+ GLfloat alpha);
+angle::CallCapture CaptureClearDepth(const State &glState, bool isCallValid, GLdouble depth);
+angle::CallCapture CaptureClearIndex(const State &glState, bool isCallValid, GLfloat c);
+angle::CallCapture CaptureClipPlane(const State &glState,
+ bool isCallValid,
+ GLenum plane,
+ const GLdouble *equation);
+angle::CallCapture CaptureColor3b(const State &glState,
+ bool isCallValid,
+ GLbyte red,
+ GLbyte green,
+ GLbyte blue);
+angle::CallCapture CaptureColor3bv(const State &glState, bool isCallValid, const GLbyte *v);
+angle::CallCapture CaptureColor3d(const State &glState,
+ bool isCallValid,
+ GLdouble red,
+ GLdouble green,
+ GLdouble blue);
+angle::CallCapture CaptureColor3dv(const State &glState, bool isCallValid, const GLdouble *v);
+angle::CallCapture CaptureColor3f(const State &glState,
+ bool isCallValid,
+ GLfloat red,
+ GLfloat green,
+ GLfloat blue);
+angle::CallCapture CaptureColor3fv(const State &glState, bool isCallValid, const GLfloat *v);
+angle::CallCapture CaptureColor3i(const State &glState,
+ bool isCallValid,
+ GLint red,
+ GLint green,
+ GLint blue);
+angle::CallCapture CaptureColor3iv(const State &glState, bool isCallValid, const GLint *v);
+angle::CallCapture CaptureColor3s(const State &glState,
+ bool isCallValid,
+ GLshort red,
+ GLshort green,
+ GLshort blue);
+angle::CallCapture CaptureColor3sv(const State &glState, bool isCallValid, const GLshort *v);
+angle::CallCapture CaptureColor3ub(const State &glState,
+ bool isCallValid,
+ GLubyte red,
+ GLubyte green,
+ GLubyte blue);
+angle::CallCapture CaptureColor3ubv(const State &glState, bool isCallValid, const GLubyte *v);
+angle::CallCapture CaptureColor3ui(const State &glState,
+ bool isCallValid,
+ GLuint red,
+ GLuint green,
+ GLuint blue);
+angle::CallCapture CaptureColor3uiv(const State &glState, bool isCallValid, const GLuint *v);
+angle::CallCapture CaptureColor3us(const State &glState,
+ bool isCallValid,
+ GLushort red,
+ GLushort green,
+ GLushort blue);
+angle::CallCapture CaptureColor3usv(const State &glState, bool isCallValid, const GLushort *v);
+angle::CallCapture CaptureColor4b(const State &glState,
+ bool isCallValid,
+ GLbyte red,
+ GLbyte green,
+ GLbyte blue,
+ GLbyte alpha);
+angle::CallCapture CaptureColor4bv(const State &glState, bool isCallValid, const GLbyte *v);
+angle::CallCapture CaptureColor4d(const State &glState,
+ bool isCallValid,
+ GLdouble red,
+ GLdouble green,
+ GLdouble blue,
+ GLdouble alpha);
+angle::CallCapture CaptureColor4dv(const State &glState, bool isCallValid, const GLdouble *v);
+angle::CallCapture CaptureColor4fv(const State &glState, bool isCallValid, const GLfloat *v);
+angle::CallCapture CaptureColor4i(const State &glState,
+ bool isCallValid,
+ GLint red,
+ GLint green,
+ GLint blue,
+ GLint alpha);
+angle::CallCapture CaptureColor4iv(const State &glState, bool isCallValid, const GLint *v);
+angle::CallCapture CaptureColor4s(const State &glState,
+ bool isCallValid,
+ GLshort red,
+ GLshort green,
+ GLshort blue,
+ GLshort alpha);
+angle::CallCapture CaptureColor4sv(const State &glState, bool isCallValid, const GLshort *v);
+angle::CallCapture CaptureColor4ubv(const State &glState, bool isCallValid, const GLubyte *v);
+angle::CallCapture CaptureColor4ui(const State &glState,
+ bool isCallValid,
+ GLuint red,
+ GLuint green,
+ GLuint blue,
+ GLuint alpha);
+angle::CallCapture CaptureColor4uiv(const State &glState, bool isCallValid, const GLuint *v);
+angle::CallCapture CaptureColor4us(const State &glState,
+ bool isCallValid,
+ GLushort red,
+ GLushort green,
+ GLushort blue,
+ GLushort alpha);
+angle::CallCapture CaptureColor4usv(const State &glState, bool isCallValid, const GLushort *v);
+angle::CallCapture CaptureColorMaterial(const State &glState,
+ bool isCallValid,
+ GLenum face,
+ GLenum mode);
+angle::CallCapture CaptureCopyPixels(const State &glState,
+ bool isCallValid,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum type);
+angle::CallCapture CaptureDeleteLists(const State &glState,
+ bool isCallValid,
+ GLuint list,
+ GLsizei range);
+angle::CallCapture CaptureDepthRange(const State &glState,
+ bool isCallValid,
+ GLdouble n,
+ GLdouble f);
+angle::CallCapture CaptureDrawBuffer(const State &glState, bool isCallValid, GLenum buf);
+angle::CallCapture CaptureDrawPixels(const State &glState,
+ bool isCallValid,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ const void *pixels);
+angle::CallCapture CaptureEdgeFlag(const State &glState, bool isCallValid, GLboolean flag);
+angle::CallCapture CaptureEdgeFlagv(const State &glState, bool isCallValid, const GLboolean *flag);
+angle::CallCapture CaptureEnd(const State &glState, bool isCallValid);
+angle::CallCapture CaptureEndList(const State &glState, bool isCallValid);
+angle::CallCapture CaptureEvalCoord1d(const State &glState, bool isCallValid, GLdouble u);
+angle::CallCapture CaptureEvalCoord1dv(const State &glState, bool isCallValid, const GLdouble *u);
+angle::CallCapture CaptureEvalCoord1f(const State &glState, bool isCallValid, GLfloat u);
+angle::CallCapture CaptureEvalCoord1fv(const State &glState, bool isCallValid, const GLfloat *u);
+angle::CallCapture CaptureEvalCoord2d(const State &glState,
+ bool isCallValid,
+ GLdouble u,
+ GLdouble v);
+angle::CallCapture CaptureEvalCoord2dv(const State &glState, bool isCallValid, const GLdouble *u);
+angle::CallCapture CaptureEvalCoord2f(const State &glState, bool isCallValid, GLfloat u, GLfloat v);
+angle::CallCapture CaptureEvalCoord2fv(const State &glState, bool isCallValid, const GLfloat *u);
+angle::CallCapture CaptureEvalMesh1(const State &glState,
+ bool isCallValid,
+ GLenum mode,
+ GLint i1,
+ GLint i2);
+angle::CallCapture CaptureEvalMesh2(const State &glState,
+ bool isCallValid,
+ GLenum mode,
+ GLint i1,
+ GLint i2,
+ GLint j1,
+ GLint j2);
+angle::CallCapture CaptureEvalPoint1(const State &glState, bool isCallValid, GLint i);
+angle::CallCapture CaptureEvalPoint2(const State &glState, bool isCallValid, GLint i, GLint j);
+angle::CallCapture CaptureFeedbackBuffer(const State &glState,
+ bool isCallValid,
+ GLsizei size,
+ GLenum type,
+ GLfloat *buffer);
+angle::CallCapture CaptureFogi(const State &glState, bool isCallValid, GLenum pname, GLint param);
+angle::CallCapture CaptureFogiv(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ const GLint *params);
+angle::CallCapture CaptureFrustum(const State &glState,
+ bool isCallValid,
+ GLdouble left,
+ GLdouble right,
+ GLdouble bottom,
+ GLdouble top,
+ GLdouble zNear,
+ GLdouble zFar);
+angle::CallCapture CaptureGenLists(const State &glState,
+ bool isCallValid,
+ GLsizei range,
+ GLuint returnValue);
+angle::CallCapture CaptureGetClipPlane(const State &glState,
+ bool isCallValid,
+ GLenum plane,
+ GLdouble *equation);
+angle::CallCapture CaptureGetDoublev(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLdouble *data);
+angle::CallCapture CaptureGetLightiv(const State &glState,
+ bool isCallValid,
+ GLenum light,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureGetMapdv(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum query,
+ GLdouble *v);
+angle::CallCapture CaptureGetMapfv(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum query,
+ GLfloat *v);
+angle::CallCapture CaptureGetMapiv(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum query,
+ GLint *v);
+angle::CallCapture CaptureGetMaterialiv(const State &glState,
+ bool isCallValid,
+ GLenum face,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureGetPixelMapfv(const State &glState,
+ bool isCallValid,
+ GLenum map,
+ GLfloat *values);
+angle::CallCapture CaptureGetPixelMapuiv(const State &glState,
+ bool isCallValid,
+ GLenum map,
+ GLuint *values);
+angle::CallCapture CaptureGetPixelMapusv(const State &glState,
+ bool isCallValid,
+ GLenum map,
+ GLushort *values);
+angle::CallCapture CaptureGetPolygonStipple(const State &glState, bool isCallValid, GLubyte *mask);
+angle::CallCapture CaptureGetTexGendv(const State &glState,
+ bool isCallValid,
+ GLenum coord,
+ GLenum pname,
+ GLdouble *params);
+angle::CallCapture CaptureGetTexGenfv(const State &glState,
+ bool isCallValid,
+ GLenum coord,
+ GLenum pname,
+ GLfloat *params);
+angle::CallCapture CaptureGetTexGeniv(const State &glState,
+ bool isCallValid,
+ GLenum coord,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureGetTexImage(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum format,
+ GLenum type,
+ void *pixels);
+angle::CallCapture CaptureIndexMask(const State &glState, bool isCallValid, GLuint mask);
+angle::CallCapture CaptureIndexd(const State &glState, bool isCallValid, GLdouble c);
+angle::CallCapture CaptureIndexdv(const State &glState, bool isCallValid, const GLdouble *c);
+angle::CallCapture CaptureIndexf(const State &glState, bool isCallValid, GLfloat c);
+angle::CallCapture CaptureIndexfv(const State &glState, bool isCallValid, const GLfloat *c);
+angle::CallCapture CaptureIndexi(const State &glState, bool isCallValid, GLint c);
+angle::CallCapture CaptureIndexiv(const State &glState, bool isCallValid, const GLint *c);
+angle::CallCapture CaptureIndexs(const State &glState, bool isCallValid, GLshort c);
+angle::CallCapture CaptureIndexsv(const State &glState, bool isCallValid, const GLshort *c);
+angle::CallCapture CaptureInitNames(const State &glState, bool isCallValid);
+angle::CallCapture CaptureIsList(const State &glState,
+ bool isCallValid,
+ GLuint list,
+ GLboolean returnValue);
+angle::CallCapture CaptureLightModeli(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLint param);
+angle::CallCapture CaptureLightModeliv(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ const GLint *params);
+angle::CallCapture CaptureLighti(const State &glState,
+ bool isCallValid,
+ GLenum light,
+ GLenum pname,
+ GLint param);
+angle::CallCapture CaptureLightiv(const State &glState,
+ bool isCallValid,
+ GLenum light,
+ GLenum pname,
+ const GLint *params);
+angle::CallCapture CaptureLineStipple(const State &glState,
+ bool isCallValid,
+ GLint factor,
+ GLushort pattern);
+angle::CallCapture CaptureListBase(const State &glState, bool isCallValid, GLuint base);
+angle::CallCapture CaptureLoadMatrixd(const State &glState, bool isCallValid, const GLdouble *m);
+angle::CallCapture CaptureLoadName(const State &glState, bool isCallValid, GLuint name);
+angle::CallCapture CaptureMap1d(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLdouble u1,
+ GLdouble u2,
+ GLint stride,
+ GLint order,
+ const GLdouble *points);
+angle::CallCapture CaptureMap1f(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLfloat u1,
+ GLfloat u2,
+ GLint stride,
+ GLint order,
+ const GLfloat *points);
+angle::CallCapture CaptureMap2d(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLdouble u1,
+ GLdouble u2,
+ GLint ustride,
+ GLint uorder,
+ GLdouble v1,
+ GLdouble v2,
+ GLint vstride,
+ GLint vorder,
+ const GLdouble *points);
+angle::CallCapture CaptureMap2f(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLfloat u1,
+ GLfloat u2,
+ GLint ustride,
+ GLint uorder,
+ GLfloat v1,
+ GLfloat v2,
+ GLint vstride,
+ GLint vorder,
+ const GLfloat *points);
+angle::CallCapture CaptureMapGrid1d(const State &glState,
+ bool isCallValid,
+ GLint un,
+ GLdouble u1,
+ GLdouble u2);
+angle::CallCapture CaptureMapGrid1f(const State &glState,
+ bool isCallValid,
+ GLint un,
+ GLfloat u1,
+ GLfloat u2);
+angle::CallCapture CaptureMapGrid2d(const State &glState,
+ bool isCallValid,
+ GLint un,
+ GLdouble u1,
+ GLdouble u2,
+ GLint vn,
+ GLdouble v1,
+ GLdouble v2);
+angle::CallCapture CaptureMapGrid2f(const State &glState,
+ bool isCallValid,
+ GLint un,
+ GLfloat u1,
+ GLfloat u2,
+ GLint vn,
+ GLfloat v1,
+ GLfloat v2);
+angle::CallCapture CaptureMateriali(const State &glState,
+ bool isCallValid,
+ GLenum face,
+ GLenum pname,
+ GLint param);
+angle::CallCapture CaptureMaterialiv(const State &glState,
+ bool isCallValid,
+ GLenum face,
+ GLenum pname,
+ const GLint *params);
+angle::CallCapture CaptureMultMatrixd(const State &glState, bool isCallValid, const GLdouble *m);
+angle::CallCapture CaptureNewList(const State &glState, bool isCallValid, GLuint list, GLenum mode);
+angle::CallCapture CaptureNormal3b(const State &glState,
+ bool isCallValid,
+ GLbyte nx,
+ GLbyte ny,
+ GLbyte nz);
+angle::CallCapture CaptureNormal3bv(const State &glState, bool isCallValid, const GLbyte *v);
+angle::CallCapture CaptureNormal3d(const State &glState,
+ bool isCallValid,
+ GLdouble nx,
+ GLdouble ny,
+ GLdouble nz);
+angle::CallCapture CaptureNormal3dv(const State &glState, bool isCallValid, const GLdouble *v);
+angle::CallCapture CaptureNormal3fv(const State &glState, bool isCallValid, const GLfloat *v);
+angle::CallCapture CaptureNormal3i(const State &glState,
+ bool isCallValid,
+ GLint nx,
+ GLint ny,
+ GLint nz);
+angle::CallCapture CaptureNormal3iv(const State &glState, bool isCallValid, const GLint *v);
+angle::CallCapture CaptureNormal3s(const State &glState,
+ bool isCallValid,
+ GLshort nx,
+ GLshort ny,
+ GLshort nz);
+angle::CallCapture CaptureNormal3sv(const State &glState, bool isCallValid, const GLshort *v);
+angle::CallCapture CaptureOrtho(const State &glState,
+ bool isCallValid,
+ GLdouble left,
+ GLdouble right,
+ GLdouble bottom,
+ GLdouble top,
+ GLdouble zNear,
+ GLdouble zFar);
+angle::CallCapture CapturePassThrough(const State &glState, bool isCallValid, GLfloat token);
+angle::CallCapture CapturePixelMapfv(const State &glState,
+ bool isCallValid,
+ GLenum map,
+ GLsizei mapsize,
+ const GLfloat *values);
+angle::CallCapture CapturePixelMapuiv(const State &glState,
+ bool isCallValid,
+ GLenum map,
+ GLsizei mapsize,
+ const GLuint *values);
+angle::CallCapture CapturePixelMapusv(const State &glState,
+ bool isCallValid,
+ GLenum map,
+ GLsizei mapsize,
+ const GLushort *values);
+angle::CallCapture CapturePixelStoref(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLfloat param);
+angle::CallCapture CapturePixelTransferf(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLfloat param);
+angle::CallCapture CapturePixelTransferi(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLint param);
+angle::CallCapture CapturePixelZoom(const State &glState,
+ bool isCallValid,
+ GLfloat xfactor,
+ GLfloat yfactor);
+angle::CallCapture CapturePolygonMode(const State &glState,
+ bool isCallValid,
+ GLenum face,
+ GLenum mode);
+angle::CallCapture CapturePolygonStipple(const State &glState,
+ bool isCallValid,
+ const GLubyte *mask);
+angle::CallCapture CapturePopAttrib(const State &glState, bool isCallValid);
+angle::CallCapture CapturePopName(const State &glState, bool isCallValid);
+angle::CallCapture CapturePushAttrib(const State &glState, bool isCallValid, GLbitfield mask);
+angle::CallCapture CapturePushName(const State &glState, bool isCallValid, GLuint name);
+angle::CallCapture CaptureRasterPos2d(const State &glState,
+ bool isCallValid,
+ GLdouble x,
+ GLdouble y);
+angle::CallCapture CaptureRasterPos2dv(const State &glState, bool isCallValid, const GLdouble *v);
+angle::CallCapture CaptureRasterPos2f(const State &glState, bool isCallValid, GLfloat x, GLfloat y);
+angle::CallCapture CaptureRasterPos2fv(const State &glState, bool isCallValid, const GLfloat *v);
+angle::CallCapture CaptureRasterPos2i(const State &glState, bool isCallValid, GLint x, GLint y);
+angle::CallCapture CaptureRasterPos2iv(const State &glState, bool isCallValid, const GLint *v);
+angle::CallCapture CaptureRasterPos2s(const State &glState, bool isCallValid, GLshort x, GLshort y);
+angle::CallCapture CaptureRasterPos2sv(const State &glState, bool isCallValid, const GLshort *v);
+angle::CallCapture CaptureRasterPos3d(const State &glState,
+ bool isCallValid,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z);
+angle::CallCapture CaptureRasterPos3dv(const State &glState, bool isCallValid, const GLdouble *v);
+angle::CallCapture CaptureRasterPos3f(const State &glState,
+ bool isCallValid,
+ GLfloat x,
+ GLfloat y,
+ GLfloat z);
+angle::CallCapture CaptureRasterPos3fv(const State &glState, bool isCallValid, const GLfloat *v);
+angle::CallCapture CaptureRasterPos3i(const State &glState,
+ bool isCallValid,
+ GLint x,
+ GLint y,
+ GLint z);
+angle::CallCapture CaptureRasterPos3iv(const State &glState, bool isCallValid, const GLint *v);
+angle::CallCapture CaptureRasterPos3s(const State &glState,
+ bool isCallValid,
+ GLshort x,
+ GLshort y,
+ GLshort z);
+angle::CallCapture CaptureRasterPos3sv(const State &glState, bool isCallValid, const GLshort *v);
+angle::CallCapture CaptureRasterPos4d(const State &glState,
+ bool isCallValid,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z,
+ GLdouble w);
+angle::CallCapture CaptureRasterPos4dv(const State &glState, bool isCallValid, const GLdouble *v);
+angle::CallCapture CaptureRasterPos4f(const State &glState,
+ bool isCallValid,
+ GLfloat x,
+ GLfloat y,
+ GLfloat z,
+ GLfloat w);
+angle::CallCapture CaptureRasterPos4fv(const State &glState, bool isCallValid, const GLfloat *v);
+angle::CallCapture CaptureRasterPos4i(const State &glState,
+ bool isCallValid,
+ GLint x,
+ GLint y,
+ GLint z,
+ GLint w);
+angle::CallCapture CaptureRasterPos4iv(const State &glState, bool isCallValid, const GLint *v);
+angle::CallCapture CaptureRasterPos4s(const State &glState,
+ bool isCallValid,
+ GLshort x,
+ GLshort y,
+ GLshort z,
+ GLshort w);
+angle::CallCapture CaptureRasterPos4sv(const State &glState, bool isCallValid, const GLshort *v);
+angle::CallCapture CaptureRectd(const State &glState,
+ bool isCallValid,
+ GLdouble x1,
+ GLdouble y1,
+ GLdouble x2,
+ GLdouble y2);
+angle::CallCapture CaptureRectdv(const State &glState,
+ bool isCallValid,
+ const GLdouble *v1,
+ const GLdouble *v2);
+angle::CallCapture CaptureRectf(const State &glState,
+ bool isCallValid,
+ GLfloat x1,
+ GLfloat y1,
+ GLfloat x2,
+ GLfloat y2);
+angle::CallCapture CaptureRectfv(const State &glState,
+ bool isCallValid,
+ const GLfloat *v1,
+ const GLfloat *v2);
+angle::CallCapture CaptureRecti(const State &glState,
+ bool isCallValid,
+ GLint x1,
+ GLint y1,
+ GLint x2,
+ GLint y2);
+angle::CallCapture CaptureRectiv(const State &glState,
+ bool isCallValid,
+ const GLint *v1,
+ const GLint *v2);
+angle::CallCapture CaptureRects(const State &glState,
+ bool isCallValid,
+ GLshort x1,
+ GLshort y1,
+ GLshort x2,
+ GLshort y2);
+angle::CallCapture CaptureRectsv(const State &glState,
+ bool isCallValid,
+ const GLshort *v1,
+ const GLshort *v2);
+angle::CallCapture CaptureRenderMode(const State &glState,
+ bool isCallValid,
+ GLenum mode,
+ GLint returnValue);
+angle::CallCapture CaptureRotated(const State &glState,
+ bool isCallValid,
+ GLdouble angle,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z);
+angle::CallCapture CaptureScaled(const State &glState,
+ bool isCallValid,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z);
+angle::CallCapture CaptureSelectBuffer(const State &glState,
+ bool isCallValid,
+ GLsizei size,
+ GLuint *buffer);
+angle::CallCapture CaptureTexCoord1d(const State &glState, bool isCallValid, GLdouble s);
+angle::CallCapture CaptureTexCoord1dv(const State &glState, bool isCallValid, const GLdouble *v);
+angle::CallCapture CaptureTexCoord1f(const State &glState, bool isCallValid, GLfloat s);
+angle::CallCapture CaptureTexCoord1fv(const State &glState, bool isCallValid, const GLfloat *v);
+angle::CallCapture CaptureTexCoord1i(const State &glState, bool isCallValid, GLint s);
+angle::CallCapture CaptureTexCoord1iv(const State &glState, bool isCallValid, const GLint *v);
+angle::CallCapture CaptureTexCoord1s(const State &glState, bool isCallValid, GLshort s);
+angle::CallCapture CaptureTexCoord1sv(const State &glState, bool isCallValid, const GLshort *v);
+angle::CallCapture CaptureTexCoord2d(const State &glState,
+ bool isCallValid,
+ GLdouble s,
+ GLdouble t);
+angle::CallCapture CaptureTexCoord2dv(const State &glState, bool isCallValid, const GLdouble *v);
+angle::CallCapture CaptureTexCoord2f(const State &glState, bool isCallValid, GLfloat s, GLfloat t);
+angle::CallCapture CaptureTexCoord2fv(const State &glState, bool isCallValid, const GLfloat *v);
+angle::CallCapture CaptureTexCoord2i(const State &glState, bool isCallValid, GLint s, GLint t);
+angle::CallCapture CaptureTexCoord2iv(const State &glState, bool isCallValid, const GLint *v);
+angle::CallCapture CaptureTexCoord2s(const State &glState, bool isCallValid, GLshort s, GLshort t);
+angle::CallCapture CaptureTexCoord2sv(const State &glState, bool isCallValid, const GLshort *v);
+angle::CallCapture CaptureTexCoord3d(const State &glState,
+ bool isCallValid,
+ GLdouble s,
+ GLdouble t,
+ GLdouble r);
+angle::CallCapture CaptureTexCoord3dv(const State &glState, bool isCallValid, const GLdouble *v);
+angle::CallCapture CaptureTexCoord3f(const State &glState,
+ bool isCallValid,
+ GLfloat s,
+ GLfloat t,
+ GLfloat r);
+angle::CallCapture CaptureTexCoord3fv(const State &glState, bool isCallValid, const GLfloat *v);
+angle::CallCapture CaptureTexCoord3i(const State &glState,
+ bool isCallValid,
+ GLint s,
+ GLint t,
+ GLint r);
+angle::CallCapture CaptureTexCoord3iv(const State &glState, bool isCallValid, const GLint *v);
+angle::CallCapture CaptureTexCoord3s(const State &glState,
+ bool isCallValid,
+ GLshort s,
+ GLshort t,
+ GLshort r);
+angle::CallCapture CaptureTexCoord3sv(const State &glState, bool isCallValid, const GLshort *v);
+angle::CallCapture CaptureTexCoord4d(const State &glState,
+ bool isCallValid,
+ GLdouble s,
+ GLdouble t,
+ GLdouble r,
+ GLdouble q);
+angle::CallCapture CaptureTexCoord4dv(const State &glState, bool isCallValid, const GLdouble *v);
+angle::CallCapture CaptureTexCoord4f(const State &glState,
+ bool isCallValid,
+ GLfloat s,
+ GLfloat t,
+ GLfloat r,
+ GLfloat q);
+angle::CallCapture CaptureTexCoord4fv(const State &glState, bool isCallValid, const GLfloat *v);
+angle::CallCapture CaptureTexCoord4i(const State &glState,
+ bool isCallValid,
+ GLint s,
+ GLint t,
+ GLint r,
+ GLint q);
+angle::CallCapture CaptureTexCoord4iv(const State &glState, bool isCallValid, const GLint *v);
+angle::CallCapture CaptureTexCoord4s(const State &glState,
+ bool isCallValid,
+ GLshort s,
+ GLshort t,
+ GLshort r,
+ GLshort q);
+angle::CallCapture CaptureTexCoord4sv(const State &glState, bool isCallValid, const GLshort *v);
+angle::CallCapture CaptureTexGend(const State &glState,
+ bool isCallValid,
+ GLenum coord,
+ GLenum pname,
+ GLdouble param);
+angle::CallCapture CaptureTexGendv(const State &glState,
+ bool isCallValid,
+ GLenum coord,
+ GLenum pname,
+ const GLdouble *params);
+angle::CallCapture CaptureTexGenf(const State &glState,
+ bool isCallValid,
+ GLenum coord,
+ GLenum pname,
+ GLfloat param);
+angle::CallCapture CaptureTexGenfv(const State &glState,
+ bool isCallValid,
+ GLenum coord,
+ GLenum pname,
+ const GLfloat *params);
+angle::CallCapture CaptureTexGeni(const State &glState,
+ bool isCallValid,
+ GLenum coord,
+ GLenum pname,
+ GLint param);
+angle::CallCapture CaptureTexGeniv(const State &glState,
+ bool isCallValid,
+ GLenum coord,
+ GLenum pname,
+ const GLint *params);
+angle::CallCapture CaptureTexImage1D(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const void *pixels);
+angle::CallCapture CaptureTranslated(const State &glState,
+ bool isCallValid,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z);
+angle::CallCapture CaptureVertex2d(const State &glState, bool isCallValid, GLdouble x, GLdouble y);
+angle::CallCapture CaptureVertex2dv(const State &glState, bool isCallValid, const GLdouble *v);
+angle::CallCapture CaptureVertex2f(const State &glState, bool isCallValid, GLfloat x, GLfloat y);
+angle::CallCapture CaptureVertex2fv(const State &glState, bool isCallValid, const GLfloat *v);
+angle::CallCapture CaptureVertex2i(const State &glState, bool isCallValid, GLint x, GLint y);
+angle::CallCapture CaptureVertex2iv(const State &glState, bool isCallValid, const GLint *v);
+angle::CallCapture CaptureVertex2s(const State &glState, bool isCallValid, GLshort x, GLshort y);
+angle::CallCapture CaptureVertex2sv(const State &glState, bool isCallValid, const GLshort *v);
+angle::CallCapture CaptureVertex3d(const State &glState,
+ bool isCallValid,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z);
+angle::CallCapture CaptureVertex3dv(const State &glState, bool isCallValid, const GLdouble *v);
+angle::CallCapture CaptureVertex3f(const State &glState,
+ bool isCallValid,
+ GLfloat x,
+ GLfloat y,
+ GLfloat z);
+angle::CallCapture CaptureVertex3fv(const State &glState, bool isCallValid, const GLfloat *v);
+angle::CallCapture CaptureVertex3i(const State &glState,
+ bool isCallValid,
+ GLint x,
+ GLint y,
+ GLint z);
+angle::CallCapture CaptureVertex3iv(const State &glState, bool isCallValid, const GLint *v);
+angle::CallCapture CaptureVertex3s(const State &glState,
+ bool isCallValid,
+ GLshort x,
+ GLshort y,
+ GLshort z);
+angle::CallCapture CaptureVertex3sv(const State &glState, bool isCallValid, const GLshort *v);
+angle::CallCapture CaptureVertex4d(const State &glState,
+ bool isCallValid,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z,
+ GLdouble w);
+angle::CallCapture CaptureVertex4dv(const State &glState, bool isCallValid, const GLdouble *v);
+angle::CallCapture CaptureVertex4f(const State &glState,
+ bool isCallValid,
+ GLfloat x,
+ GLfloat y,
+ GLfloat z,
+ GLfloat w);
+angle::CallCapture CaptureVertex4fv(const State &glState, bool isCallValid, const GLfloat *v);
+angle::CallCapture CaptureVertex4i(const State &glState,
+ bool isCallValid,
+ GLint x,
+ GLint y,
+ GLint z,
+ GLint w);
+angle::CallCapture CaptureVertex4iv(const State &glState, bool isCallValid, const GLint *v);
+angle::CallCapture CaptureVertex4s(const State &glState,
+ bool isCallValid,
+ GLshort x,
+ GLshort y,
+ GLshort z,
+ GLshort w);
+angle::CallCapture CaptureVertex4sv(const State &glState, bool isCallValid, const GLshort *v);
+
+// GL 1.1
+angle::CallCapture CaptureAreTexturesResident(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ const GLuint *textures,
+ GLboolean *residences,
+ GLboolean returnValue);
+angle::CallCapture CaptureArrayElement(const State &glState, bool isCallValid, GLint i);
+angle::CallCapture CaptureCopyTexImage1D(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLint level,
+ GLenum internalformat,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLint border);
+angle::CallCapture CaptureCopyTexSubImage1D(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint x,
+ GLint y,
+ GLsizei width);
+angle::CallCapture CaptureEdgeFlagPointer(const State &glState,
+ bool isCallValid,
+ GLsizei stride,
+ const void *pointer);
+angle::CallCapture CaptureIndexPointer(const State &glState,
+ bool isCallValid,
+ GLenum type,
+ GLsizei stride,
+ const void *pointer);
+angle::CallCapture CaptureIndexub(const State &glState, bool isCallValid, GLubyte c);
+angle::CallCapture CaptureIndexubv(const State &glState, bool isCallValid, const GLubyte *c);
+angle::CallCapture CaptureInterleavedArrays(const State &glState,
+ bool isCallValid,
+ GLenum format,
+ GLsizei stride,
+ const void *pointer);
+angle::CallCapture CapturePopClientAttrib(const State &glState, bool isCallValid);
+angle::CallCapture CapturePrioritizeTextures(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ const GLuint *textures,
+ const GLfloat *priorities);
+angle::CallCapture CapturePushClientAttrib(const State &glState, bool isCallValid, GLbitfield mask);
+angle::CallCapture CaptureTexSubImage1D(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLsizei width,
+ GLenum format,
+ GLenum type,
+ const void *pixels);
+
+// GL 1.2
+
+// GL 1.3
+angle::CallCapture CaptureCompressedTexImage1D(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLint border,
+ GLsizei imageSize,
+ const void *data);
+angle::CallCapture CaptureCompressedTexSubImage1D(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLsizei width,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data);
+angle::CallCapture CaptureGetCompressedTexImage(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ void *img);
+angle::CallCapture CaptureLoadTransposeMatrixd(const State &glState,
+ bool isCallValid,
+ const GLdouble *m);
+angle::CallCapture CaptureLoadTransposeMatrixf(const State &glState,
+ bool isCallValid,
+ const GLfloat *m);
+angle::CallCapture CaptureMultTransposeMatrixd(const State &glState,
+ bool isCallValid,
+ const GLdouble *m);
+angle::CallCapture CaptureMultTransposeMatrixf(const State &glState,
+ bool isCallValid,
+ const GLfloat *m);
+angle::CallCapture CaptureMultiTexCoord1d(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLdouble s);
+angle::CallCapture CaptureMultiTexCoord1dv(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ const GLdouble *v);
+angle::CallCapture CaptureMultiTexCoord1f(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLfloat s);
+angle::CallCapture CaptureMultiTexCoord1fv(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ const GLfloat *v);
+angle::CallCapture CaptureMultiTexCoord1i(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLint s);
+angle::CallCapture CaptureMultiTexCoord1iv(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ const GLint *v);
+angle::CallCapture CaptureMultiTexCoord1s(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLshort s);
+angle::CallCapture CaptureMultiTexCoord1sv(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ const GLshort *v);
+angle::CallCapture CaptureMultiTexCoord2d(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLdouble s,
+ GLdouble t);
+angle::CallCapture CaptureMultiTexCoord2dv(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ const GLdouble *v);
+angle::CallCapture CaptureMultiTexCoord2f(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLfloat s,
+ GLfloat t);
+angle::CallCapture CaptureMultiTexCoord2fv(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ const GLfloat *v);
+angle::CallCapture CaptureMultiTexCoord2i(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLint s,
+ GLint t);
+angle::CallCapture CaptureMultiTexCoord2iv(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ const GLint *v);
+angle::CallCapture CaptureMultiTexCoord2s(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLshort s,
+ GLshort t);
+angle::CallCapture CaptureMultiTexCoord2sv(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ const GLshort *v);
+angle::CallCapture CaptureMultiTexCoord3d(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLdouble s,
+ GLdouble t,
+ GLdouble r);
+angle::CallCapture CaptureMultiTexCoord3dv(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ const GLdouble *v);
+angle::CallCapture CaptureMultiTexCoord3f(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLfloat s,
+ GLfloat t,
+ GLfloat r);
+angle::CallCapture CaptureMultiTexCoord3fv(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ const GLfloat *v);
+angle::CallCapture CaptureMultiTexCoord3i(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLint s,
+ GLint t,
+ GLint r);
+angle::CallCapture CaptureMultiTexCoord3iv(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ const GLint *v);
+angle::CallCapture CaptureMultiTexCoord3s(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLshort s,
+ GLshort t,
+ GLshort r);
+angle::CallCapture CaptureMultiTexCoord3sv(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ const GLshort *v);
+angle::CallCapture CaptureMultiTexCoord4d(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLdouble s,
+ GLdouble t,
+ GLdouble r,
+ GLdouble q);
+angle::CallCapture CaptureMultiTexCoord4dv(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ const GLdouble *v);
+angle::CallCapture CaptureMultiTexCoord4fv(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ const GLfloat *v);
+angle::CallCapture CaptureMultiTexCoord4i(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLint s,
+ GLint t,
+ GLint r,
+ GLint q);
+angle::CallCapture CaptureMultiTexCoord4iv(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ const GLint *v);
+angle::CallCapture CaptureMultiTexCoord4s(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLshort s,
+ GLshort t,
+ GLshort r,
+ GLshort q);
+angle::CallCapture CaptureMultiTexCoord4sv(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ const GLshort *v);
+
+// GL 1.4
+angle::CallCapture CaptureFogCoordPointer(const State &glState,
+ bool isCallValid,
+ GLenum type,
+ GLsizei stride,
+ const void *pointer);
+angle::CallCapture CaptureFogCoordd(const State &glState, bool isCallValid, GLdouble coord);
+angle::CallCapture CaptureFogCoorddv(const State &glState, bool isCallValid, const GLdouble *coord);
+angle::CallCapture CaptureFogCoordf(const State &glState, bool isCallValid, GLfloat coord);
+angle::CallCapture CaptureFogCoordfv(const State &glState, bool isCallValid, const GLfloat *coord);
+angle::CallCapture CaptureMultiDrawArrays(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const GLint *first,
+ const GLsizei *count,
+ GLsizei drawcount);
+angle::CallCapture CaptureMultiDrawElements(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const GLsizei *count,
+ DrawElementsType typePacked,
+ const void *const *indices,
+ GLsizei drawcount);
+angle::CallCapture CapturePointParameteri(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLint param);
+angle::CallCapture CapturePointParameteriv(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ const GLint *params);
+angle::CallCapture CaptureSecondaryColor3b(const State &glState,
+ bool isCallValid,
+ GLbyte red,
+ GLbyte green,
+ GLbyte blue);
+angle::CallCapture CaptureSecondaryColor3bv(const State &glState,
+ bool isCallValid,
+ const GLbyte *v);
+angle::CallCapture CaptureSecondaryColor3d(const State &glState,
+ bool isCallValid,
+ GLdouble red,
+ GLdouble green,
+ GLdouble blue);
+angle::CallCapture CaptureSecondaryColor3dv(const State &glState,
+ bool isCallValid,
+ const GLdouble *v);
+angle::CallCapture CaptureSecondaryColor3f(const State &glState,
+ bool isCallValid,
+ GLfloat red,
+ GLfloat green,
+ GLfloat blue);
+angle::CallCapture CaptureSecondaryColor3fv(const State &glState,
+ bool isCallValid,
+ const GLfloat *v);
+angle::CallCapture CaptureSecondaryColor3i(const State &glState,
+ bool isCallValid,
+ GLint red,
+ GLint green,
+ GLint blue);
+angle::CallCapture CaptureSecondaryColor3iv(const State &glState, bool isCallValid, const GLint *v);
+angle::CallCapture CaptureSecondaryColor3s(const State &glState,
+ bool isCallValid,
+ GLshort red,
+ GLshort green,
+ GLshort blue);
+angle::CallCapture CaptureSecondaryColor3sv(const State &glState,
+ bool isCallValid,
+ const GLshort *v);
+angle::CallCapture CaptureSecondaryColor3ub(const State &glState,
+ bool isCallValid,
+ GLubyte red,
+ GLubyte green,
+ GLubyte blue);
+angle::CallCapture CaptureSecondaryColor3ubv(const State &glState,
+ bool isCallValid,
+ const GLubyte *v);
+angle::CallCapture CaptureSecondaryColor3ui(const State &glState,
+ bool isCallValid,
+ GLuint red,
+ GLuint green,
+ GLuint blue);
+angle::CallCapture CaptureSecondaryColor3uiv(const State &glState,
+ bool isCallValid,
+ const GLuint *v);
+angle::CallCapture CaptureSecondaryColor3us(const State &glState,
+ bool isCallValid,
+ GLushort red,
+ GLushort green,
+ GLushort blue);
+angle::CallCapture CaptureSecondaryColor3usv(const State &glState,
+ bool isCallValid,
+ const GLushort *v);
+angle::CallCapture CaptureSecondaryColorPointer(const State &glState,
+ bool isCallValid,
+ GLint size,
+ GLenum type,
+ GLsizei stride,
+ const void *pointer);
+angle::CallCapture CaptureWindowPos2d(const State &glState,
+ bool isCallValid,
+ GLdouble x,
+ GLdouble y);
+angle::CallCapture CaptureWindowPos2dv(const State &glState, bool isCallValid, const GLdouble *v);
+angle::CallCapture CaptureWindowPos2f(const State &glState, bool isCallValid, GLfloat x, GLfloat y);
+angle::CallCapture CaptureWindowPos2fv(const State &glState, bool isCallValid, const GLfloat *v);
+angle::CallCapture CaptureWindowPos2i(const State &glState, bool isCallValid, GLint x, GLint y);
+angle::CallCapture CaptureWindowPos2iv(const State &glState, bool isCallValid, const GLint *v);
+angle::CallCapture CaptureWindowPos2s(const State &glState, bool isCallValid, GLshort x, GLshort y);
+angle::CallCapture CaptureWindowPos2sv(const State &glState, bool isCallValid, const GLshort *v);
+angle::CallCapture CaptureWindowPos3d(const State &glState,
+ bool isCallValid,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z);
+angle::CallCapture CaptureWindowPos3dv(const State &glState, bool isCallValid, const GLdouble *v);
+angle::CallCapture CaptureWindowPos3f(const State &glState,
+ bool isCallValid,
+ GLfloat x,
+ GLfloat y,
+ GLfloat z);
+angle::CallCapture CaptureWindowPos3fv(const State &glState, bool isCallValid, const GLfloat *v);
+angle::CallCapture CaptureWindowPos3i(const State &glState,
+ bool isCallValid,
+ GLint x,
+ GLint y,
+ GLint z);
+angle::CallCapture CaptureWindowPos3iv(const State &glState, bool isCallValid, const GLint *v);
+angle::CallCapture CaptureWindowPos3s(const State &glState,
+ bool isCallValid,
+ GLshort x,
+ GLshort y,
+ GLshort z);
+angle::CallCapture CaptureWindowPos3sv(const State &glState, bool isCallValid, const GLshort *v);
+
+// GL 1.5
+angle::CallCapture CaptureGetBufferSubData(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLintptr offset,
+ GLsizeiptr size,
+ void *data);
+angle::CallCapture CaptureGetQueryObjectiv(const State &glState,
+ bool isCallValid,
+ QueryID idPacked,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureMapBuffer(const State &glState,
+ bool isCallValid,
+ BufferBinding targetPacked,
+ GLenum access,
+ void *returnValue);
+
+// Parameter Captures
+
+// GL 1.0
+void CaptureBitmap_bitmap(const State &glState,
+ bool isCallValid,
+ GLsizei width,
+ GLsizei height,
+ GLfloat xorig,
+ GLfloat yorig,
+ GLfloat xmove,
+ GLfloat ymove,
+ const GLubyte *bitmap,
+ angle::ParamCapture *paramCapture);
+void CaptureCallLists_lists(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ GLenum type,
+ const void *lists,
+ angle::ParamCapture *paramCapture);
+void CaptureClipPlane_equation(const State &glState,
+ bool isCallValid,
+ GLenum plane,
+ const GLdouble *equation,
+ angle::ParamCapture *paramCapture);
+void CaptureColor3bv_v(const State &glState,
+ bool isCallValid,
+ const GLbyte *v,
+ angle::ParamCapture *paramCapture);
+void CaptureColor3dv_v(const State &glState,
+ bool isCallValid,
+ const GLdouble *v,
+ angle::ParamCapture *paramCapture);
+void CaptureColor3fv_v(const State &glState,
+ bool isCallValid,
+ const GLfloat *v,
+ angle::ParamCapture *paramCapture);
+void CaptureColor3iv_v(const State &glState,
+ bool isCallValid,
+ const GLint *v,
+ angle::ParamCapture *paramCapture);
+void CaptureColor3sv_v(const State &glState,
+ bool isCallValid,
+ const GLshort *v,
+ angle::ParamCapture *paramCapture);
+void CaptureColor3ubv_v(const State &glState,
+ bool isCallValid,
+ const GLubyte *v,
+ angle::ParamCapture *paramCapture);
+void CaptureColor3uiv_v(const State &glState,
+ bool isCallValid,
+ const GLuint *v,
+ angle::ParamCapture *paramCapture);
+void CaptureColor3usv_v(const State &glState,
+ bool isCallValid,
+ const GLushort *v,
+ angle::ParamCapture *paramCapture);
+void CaptureColor4bv_v(const State &glState,
+ bool isCallValid,
+ const GLbyte *v,
+ angle::ParamCapture *paramCapture);
+void CaptureColor4dv_v(const State &glState,
+ bool isCallValid,
+ const GLdouble *v,
+ angle::ParamCapture *paramCapture);
+void CaptureColor4fv_v(const State &glState,
+ bool isCallValid,
+ const GLfloat *v,
+ angle::ParamCapture *paramCapture);
+void CaptureColor4iv_v(const State &glState,
+ bool isCallValid,
+ const GLint *v,
+ angle::ParamCapture *paramCapture);
+void CaptureColor4sv_v(const State &glState,
+ bool isCallValid,
+ const GLshort *v,
+ angle::ParamCapture *paramCapture);
+void CaptureColor4ubv_v(const State &glState,
+ bool isCallValid,
+ const GLubyte *v,
+ angle::ParamCapture *paramCapture);
+void CaptureColor4uiv_v(const State &glState,
+ bool isCallValid,
+ const GLuint *v,
+ angle::ParamCapture *paramCapture);
+void CaptureColor4usv_v(const State &glState,
+ bool isCallValid,
+ const GLushort *v,
+ angle::ParamCapture *paramCapture);
+void CaptureDrawPixels_pixels(const State &glState,
+ bool isCallValid,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ const void *pixels,
+ angle::ParamCapture *paramCapture);
+void CaptureEdgeFlagv_flag(const State &glState,
+ bool isCallValid,
+ const GLboolean *flag,
+ angle::ParamCapture *paramCapture);
+void CaptureEvalCoord1dv_u(const State &glState,
+ bool isCallValid,
+ const GLdouble *u,
+ angle::ParamCapture *paramCapture);
+void CaptureEvalCoord1fv_u(const State &glState,
+ bool isCallValid,
+ const GLfloat *u,
+ angle::ParamCapture *paramCapture);
+void CaptureEvalCoord2dv_u(const State &glState,
+ bool isCallValid,
+ const GLdouble *u,
+ angle::ParamCapture *paramCapture);
+void CaptureEvalCoord2fv_u(const State &glState,
+ bool isCallValid,
+ const GLfloat *u,
+ angle::ParamCapture *paramCapture);
+void CaptureFeedbackBuffer_buffer(const State &glState,
+ bool isCallValid,
+ GLsizei size,
+ GLenum type,
+ GLfloat *buffer,
+ angle::ParamCapture *paramCapture);
+void CaptureFogiv_params(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ const GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetClipPlane_equation(const State &glState,
+ bool isCallValid,
+ GLenum plane,
+ GLdouble *equation,
+ angle::ParamCapture *paramCapture);
+void CaptureGetDoublev_data(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLdouble *data,
+ angle::ParamCapture *paramCapture);
+void CaptureGetLightiv_params(const State &glState,
+ bool isCallValid,
+ GLenum light,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetMapdv_v(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum query,
+ GLdouble *v,
+ angle::ParamCapture *paramCapture);
+void CaptureGetMapfv_v(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum query,
+ GLfloat *v,
+ angle::ParamCapture *paramCapture);
+void CaptureGetMapiv_v(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum query,
+ GLint *v,
+ angle::ParamCapture *paramCapture);
+void CaptureGetMaterialiv_params(const State &glState,
+ bool isCallValid,
+ GLenum face,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetPixelMapfv_values(const State &glState,
+ bool isCallValid,
+ GLenum map,
+ GLfloat *values,
+ angle::ParamCapture *paramCapture);
+void CaptureGetPixelMapuiv_values(const State &glState,
+ bool isCallValid,
+ GLenum map,
+ GLuint *values,
+ angle::ParamCapture *paramCapture);
+void CaptureGetPixelMapusv_values(const State &glState,
+ bool isCallValid,
+ GLenum map,
+ GLushort *values,
+ angle::ParamCapture *paramCapture);
+void CaptureGetPolygonStipple_mask(const State &glState,
+ bool isCallValid,
+ GLubyte *mask,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTexGendv_params(const State &glState,
+ bool isCallValid,
+ GLenum coord,
+ GLenum pname,
+ GLdouble *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTexGenfv_params(const State &glState,
+ bool isCallValid,
+ GLenum coord,
+ GLenum pname,
+ GLfloat *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTexGeniv_params(const State &glState,
+ bool isCallValid,
+ GLenum coord,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTexImage_pixels(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum format,
+ GLenum type,
+ void *pixels,
+ angle::ParamCapture *paramCapture);
+void CaptureIndexdv_c(const State &glState,
+ bool isCallValid,
+ const GLdouble *c,
+ angle::ParamCapture *paramCapture);
+void CaptureIndexfv_c(const State &glState,
+ bool isCallValid,
+ const GLfloat *c,
+ angle::ParamCapture *paramCapture);
+void CaptureIndexiv_c(const State &glState,
+ bool isCallValid,
+ const GLint *c,
+ angle::ParamCapture *paramCapture);
+void CaptureIndexsv_c(const State &glState,
+ bool isCallValid,
+ const GLshort *c,
+ angle::ParamCapture *paramCapture);
+void CaptureLightModeliv_params(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ const GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureLightiv_params(const State &glState,
+ bool isCallValid,
+ GLenum light,
+ GLenum pname,
+ const GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureLoadMatrixd_m(const State &glState,
+ bool isCallValid,
+ const GLdouble *m,
+ angle::ParamCapture *paramCapture);
+void CaptureMap1d_points(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLdouble u1,
+ GLdouble u2,
+ GLint stride,
+ GLint order,
+ const GLdouble *points,
+ angle::ParamCapture *paramCapture);
+void CaptureMap1f_points(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLfloat u1,
+ GLfloat u2,
+ GLint stride,
+ GLint order,
+ const GLfloat *points,
+ angle::ParamCapture *paramCapture);
+void CaptureMap2d_points(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLdouble u1,
+ GLdouble u2,
+ GLint ustride,
+ GLint uorder,
+ GLdouble v1,
+ GLdouble v2,
+ GLint vstride,
+ GLint vorder,
+ const GLdouble *points,
+ angle::ParamCapture *paramCapture);
+void CaptureMap2f_points(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLfloat u1,
+ GLfloat u2,
+ GLint ustride,
+ GLint uorder,
+ GLfloat v1,
+ GLfloat v2,
+ GLint vstride,
+ GLint vorder,
+ const GLfloat *points,
+ angle::ParamCapture *paramCapture);
+void CaptureMaterialiv_params(const State &glState,
+ bool isCallValid,
+ GLenum face,
+ GLenum pname,
+ const GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureMultMatrixd_m(const State &glState,
+ bool isCallValid,
+ const GLdouble *m,
+ angle::ParamCapture *paramCapture);
+void CaptureNormal3bv_v(const State &glState,
+ bool isCallValid,
+ const GLbyte *v,
+ angle::ParamCapture *paramCapture);
+void CaptureNormal3dv_v(const State &glState,
+ bool isCallValid,
+ const GLdouble *v,
+ angle::ParamCapture *paramCapture);
+void CaptureNormal3fv_v(const State &glState,
+ bool isCallValid,
+ const GLfloat *v,
+ angle::ParamCapture *paramCapture);
+void CaptureNormal3iv_v(const State &glState,
+ bool isCallValid,
+ const GLint *v,
+ angle::ParamCapture *paramCapture);
+void CaptureNormal3sv_v(const State &glState,
+ bool isCallValid,
+ const GLshort *v,
+ angle::ParamCapture *paramCapture);
+void CapturePixelMapfv_values(const State &glState,
+ bool isCallValid,
+ GLenum map,
+ GLsizei mapsize,
+ const GLfloat *values,
+ angle::ParamCapture *paramCapture);
+void CapturePixelMapuiv_values(const State &glState,
+ bool isCallValid,
+ GLenum map,
+ GLsizei mapsize,
+ const GLuint *values,
+ angle::ParamCapture *paramCapture);
+void CapturePixelMapusv_values(const State &glState,
+ bool isCallValid,
+ GLenum map,
+ GLsizei mapsize,
+ const GLushort *values,
+ angle::ParamCapture *paramCapture);
+void CapturePolygonStipple_mask(const State &glState,
+ bool isCallValid,
+ const GLubyte *mask,
+ angle::ParamCapture *paramCapture);
+void CaptureRasterPos2dv_v(const State &glState,
+ bool isCallValid,
+ const GLdouble *v,
+ angle::ParamCapture *paramCapture);
+void CaptureRasterPos2fv_v(const State &glState,
+ bool isCallValid,
+ const GLfloat *v,
+ angle::ParamCapture *paramCapture);
+void CaptureRasterPos2iv_v(const State &glState,
+ bool isCallValid,
+ const GLint *v,
+ angle::ParamCapture *paramCapture);
+void CaptureRasterPos2sv_v(const State &glState,
+ bool isCallValid,
+ const GLshort *v,
+ angle::ParamCapture *paramCapture);
+void CaptureRasterPos3dv_v(const State &glState,
+ bool isCallValid,
+ const GLdouble *v,
+ angle::ParamCapture *paramCapture);
+void CaptureRasterPos3fv_v(const State &glState,
+ bool isCallValid,
+ const GLfloat *v,
+ angle::ParamCapture *paramCapture);
+void CaptureRasterPos3iv_v(const State &glState,
+ bool isCallValid,
+ const GLint *v,
+ angle::ParamCapture *paramCapture);
+void CaptureRasterPos3sv_v(const State &glState,
+ bool isCallValid,
+ const GLshort *v,
+ angle::ParamCapture *paramCapture);
+void CaptureRasterPos4dv_v(const State &glState,
+ bool isCallValid,
+ const GLdouble *v,
+ angle::ParamCapture *paramCapture);
+void CaptureRasterPos4fv_v(const State &glState,
+ bool isCallValid,
+ const GLfloat *v,
+ angle::ParamCapture *paramCapture);
+void CaptureRasterPos4iv_v(const State &glState,
+ bool isCallValid,
+ const GLint *v,
+ angle::ParamCapture *paramCapture);
+void CaptureRasterPos4sv_v(const State &glState,
+ bool isCallValid,
+ const GLshort *v,
+ angle::ParamCapture *paramCapture);
+void CaptureRectdv_v1(const State &glState,
+ bool isCallValid,
+ const GLdouble *v1,
+ const GLdouble *v2,
+ angle::ParamCapture *paramCapture);
+void CaptureRectdv_v2(const State &glState,
+ bool isCallValid,
+ const GLdouble *v1,
+ const GLdouble *v2,
+ angle::ParamCapture *paramCapture);
+void CaptureRectfv_v1(const State &glState,
+ bool isCallValid,
+ const GLfloat *v1,
+ const GLfloat *v2,
+ angle::ParamCapture *paramCapture);
+void CaptureRectfv_v2(const State &glState,
+ bool isCallValid,
+ const GLfloat *v1,
+ const GLfloat *v2,
+ angle::ParamCapture *paramCapture);
+void CaptureRectiv_v1(const State &glState,
+ bool isCallValid,
+ const GLint *v1,
+ const GLint *v2,
+ angle::ParamCapture *paramCapture);
+void CaptureRectiv_v2(const State &glState,
+ bool isCallValid,
+ const GLint *v1,
+ const GLint *v2,
+ angle::ParamCapture *paramCapture);
+void CaptureRectsv_v1(const State &glState,
+ bool isCallValid,
+ const GLshort *v1,
+ const GLshort *v2,
+ angle::ParamCapture *paramCapture);
+void CaptureRectsv_v2(const State &glState,
+ bool isCallValid,
+ const GLshort *v1,
+ const GLshort *v2,
+ angle::ParamCapture *paramCapture);
+void CaptureSelectBuffer_buffer(const State &glState,
+ bool isCallValid,
+ GLsizei size,
+ GLuint *buffer,
+ angle::ParamCapture *paramCapture);
+void CaptureTexCoord1dv_v(const State &glState,
+ bool isCallValid,
+ const GLdouble *v,
+ angle::ParamCapture *paramCapture);
+void CaptureTexCoord1fv_v(const State &glState,
+ bool isCallValid,
+ const GLfloat *v,
+ angle::ParamCapture *paramCapture);
+void CaptureTexCoord1iv_v(const State &glState,
+ bool isCallValid,
+ const GLint *v,
+ angle::ParamCapture *paramCapture);
+void CaptureTexCoord1sv_v(const State &glState,
+ bool isCallValid,
+ const GLshort *v,
+ angle::ParamCapture *paramCapture);
+void CaptureTexCoord2dv_v(const State &glState,
+ bool isCallValid,
+ const GLdouble *v,
+ angle::ParamCapture *paramCapture);
+void CaptureTexCoord2fv_v(const State &glState,
+ bool isCallValid,
+ const GLfloat *v,
+ angle::ParamCapture *paramCapture);
+void CaptureTexCoord2iv_v(const State &glState,
+ bool isCallValid,
+ const GLint *v,
+ angle::ParamCapture *paramCapture);
+void CaptureTexCoord2sv_v(const State &glState,
+ bool isCallValid,
+ const GLshort *v,
+ angle::ParamCapture *paramCapture);
+void CaptureTexCoord3dv_v(const State &glState,
+ bool isCallValid,
+ const GLdouble *v,
+ angle::ParamCapture *paramCapture);
+void CaptureTexCoord3fv_v(const State &glState,
+ bool isCallValid,
+ const GLfloat *v,
+ angle::ParamCapture *paramCapture);
+void CaptureTexCoord3iv_v(const State &glState,
+ bool isCallValid,
+ const GLint *v,
+ angle::ParamCapture *paramCapture);
+void CaptureTexCoord3sv_v(const State &glState,
+ bool isCallValid,
+ const GLshort *v,
+ angle::ParamCapture *paramCapture);
+void CaptureTexCoord4dv_v(const State &glState,
+ bool isCallValid,
+ const GLdouble *v,
+ angle::ParamCapture *paramCapture);
+void CaptureTexCoord4fv_v(const State &glState,
+ bool isCallValid,
+ const GLfloat *v,
+ angle::ParamCapture *paramCapture);
+void CaptureTexCoord4iv_v(const State &glState,
+ bool isCallValid,
+ const GLint *v,
+ angle::ParamCapture *paramCapture);
+void CaptureTexCoord4sv_v(const State &glState,
+ bool isCallValid,
+ const GLshort *v,
+ angle::ParamCapture *paramCapture);
+void CaptureTexGendv_params(const State &glState,
+ bool isCallValid,
+ GLenum coord,
+ GLenum pname,
+ const GLdouble *params,
+ angle::ParamCapture *paramCapture);
+void CaptureTexGenfv_params(const State &glState,
+ bool isCallValid,
+ GLenum coord,
+ GLenum pname,
+ const GLfloat *params,
+ angle::ParamCapture *paramCapture);
+void CaptureTexGeniv_params(const State &glState,
+ bool isCallValid,
+ GLenum coord,
+ GLenum pname,
+ const GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureTexImage1D_pixels(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const void *pixels,
+ angle::ParamCapture *paramCapture);
+void CaptureVertex2dv_v(const State &glState,
+ bool isCallValid,
+ const GLdouble *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertex2fv_v(const State &glState,
+ bool isCallValid,
+ const GLfloat *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertex2iv_v(const State &glState,
+ bool isCallValid,
+ const GLint *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertex2sv_v(const State &glState,
+ bool isCallValid,
+ const GLshort *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertex3dv_v(const State &glState,
+ bool isCallValid,
+ const GLdouble *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertex3fv_v(const State &glState,
+ bool isCallValid,
+ const GLfloat *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertex3iv_v(const State &glState,
+ bool isCallValid,
+ const GLint *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertex3sv_v(const State &glState,
+ bool isCallValid,
+ const GLshort *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertex4dv_v(const State &glState,
+ bool isCallValid,
+ const GLdouble *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertex4fv_v(const State &glState,
+ bool isCallValid,
+ const GLfloat *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertex4iv_v(const State &glState,
+ bool isCallValid,
+ const GLint *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertex4sv_v(const State &glState,
+ bool isCallValid,
+ const GLshort *v,
+ angle::ParamCapture *paramCapture);
+
+// GL 1.1
+void CaptureAreTexturesResident_textures(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ const GLuint *textures,
+ GLboolean *residences,
+ angle::ParamCapture *paramCapture);
+void CaptureAreTexturesResident_residences(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ const GLuint *textures,
+ GLboolean *residences,
+ angle::ParamCapture *paramCapture);
+void CaptureEdgeFlagPointer_pointer(const State &glState,
+ bool isCallValid,
+ GLsizei stride,
+ const void *pointer,
+ angle::ParamCapture *paramCapture);
+void CaptureIndexPointer_pointer(const State &glState,
+ bool isCallValid,
+ GLenum type,
+ GLsizei stride,
+ const void *pointer,
+ angle::ParamCapture *paramCapture);
+void CaptureIndexubv_c(const State &glState,
+ bool isCallValid,
+ const GLubyte *c,
+ angle::ParamCapture *paramCapture);
+void CaptureInterleavedArrays_pointer(const State &glState,
+ bool isCallValid,
+ GLenum format,
+ GLsizei stride,
+ const void *pointer,
+ angle::ParamCapture *paramCapture);
+void CapturePrioritizeTextures_textures(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ const GLuint *textures,
+ const GLfloat *priorities,
+ angle::ParamCapture *paramCapture);
+void CapturePrioritizeTextures_priorities(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ const GLuint *textures,
+ const GLfloat *priorities,
+ angle::ParamCapture *paramCapture);
+void CaptureTexSubImage1D_pixels(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLsizei width,
+ GLenum format,
+ GLenum type,
+ const void *pixels,
+ angle::ParamCapture *paramCapture);
+
+// GL 1.2
+
+// GL 1.3
+void CaptureCompressedTexImage1D_data(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLint border,
+ GLsizei imageSize,
+ const void *data,
+ angle::ParamCapture *paramCapture);
+void CaptureCompressedTexSubImage1D_data(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLsizei width,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data,
+ angle::ParamCapture *paramCapture);
+void CaptureGetCompressedTexImage_img(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ void *img,
+ angle::ParamCapture *paramCapture);
+void CaptureLoadTransposeMatrixd_m(const State &glState,
+ bool isCallValid,
+ const GLdouble *m,
+ angle::ParamCapture *paramCapture);
+void CaptureLoadTransposeMatrixf_m(const State &glState,
+ bool isCallValid,
+ const GLfloat *m,
+ angle::ParamCapture *paramCapture);
+void CaptureMultTransposeMatrixd_m(const State &glState,
+ bool isCallValid,
+ const GLdouble *m,
+ angle::ParamCapture *paramCapture);
+void CaptureMultTransposeMatrixf_m(const State &glState,
+ bool isCallValid,
+ const GLfloat *m,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiTexCoord1dv_v(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ const GLdouble *v,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiTexCoord1fv_v(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ const GLfloat *v,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiTexCoord1iv_v(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ const GLint *v,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiTexCoord1sv_v(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ const GLshort *v,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiTexCoord2dv_v(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ const GLdouble *v,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiTexCoord2fv_v(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ const GLfloat *v,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiTexCoord2iv_v(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ const GLint *v,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiTexCoord2sv_v(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ const GLshort *v,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiTexCoord3dv_v(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ const GLdouble *v,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiTexCoord3fv_v(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ const GLfloat *v,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiTexCoord3iv_v(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ const GLint *v,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiTexCoord3sv_v(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ const GLshort *v,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiTexCoord4dv_v(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ const GLdouble *v,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiTexCoord4fv_v(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ const GLfloat *v,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiTexCoord4iv_v(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ const GLint *v,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiTexCoord4sv_v(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ const GLshort *v,
+ angle::ParamCapture *paramCapture);
+
+// GL 1.4
+void CaptureFogCoordPointer_pointer(const State &glState,
+ bool isCallValid,
+ GLenum type,
+ GLsizei stride,
+ const void *pointer,
+ angle::ParamCapture *paramCapture);
+void CaptureFogCoorddv_coord(const State &glState,
+ bool isCallValid,
+ const GLdouble *coord,
+ angle::ParamCapture *paramCapture);
+void CaptureFogCoordfv_coord(const State &glState,
+ bool isCallValid,
+ const GLfloat *coord,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiDrawArrays_first(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const GLint *first,
+ const GLsizei *count,
+ GLsizei drawcount,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiDrawArrays_count(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const GLint *first,
+ const GLsizei *count,
+ GLsizei drawcount,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiDrawElements_count(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const GLsizei *count,
+ DrawElementsType typePacked,
+ const void *const *indices,
+ GLsizei drawcount,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiDrawElements_indices(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const GLsizei *count,
+ DrawElementsType typePacked,
+ const void *const *indices,
+ GLsizei drawcount,
+ angle::ParamCapture *paramCapture);
+void CapturePointParameteriv_params(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ const GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureSecondaryColor3bv_v(const State &glState,
+ bool isCallValid,
+ const GLbyte *v,
+ angle::ParamCapture *paramCapture);
+void CaptureSecondaryColor3dv_v(const State &glState,
+ bool isCallValid,
+ const GLdouble *v,
+ angle::ParamCapture *paramCapture);
+void CaptureSecondaryColor3fv_v(const State &glState,
+ bool isCallValid,
+ const GLfloat *v,
+ angle::ParamCapture *paramCapture);
+void CaptureSecondaryColor3iv_v(const State &glState,
+ bool isCallValid,
+ const GLint *v,
+ angle::ParamCapture *paramCapture);
+void CaptureSecondaryColor3sv_v(const State &glState,
+ bool isCallValid,
+ const GLshort *v,
+ angle::ParamCapture *paramCapture);
+void CaptureSecondaryColor3ubv_v(const State &glState,
+ bool isCallValid,
+ const GLubyte *v,
+ angle::ParamCapture *paramCapture);
+void CaptureSecondaryColor3uiv_v(const State &glState,
+ bool isCallValid,
+ const GLuint *v,
+ angle::ParamCapture *paramCapture);
+void CaptureSecondaryColor3usv_v(const State &glState,
+ bool isCallValid,
+ const GLushort *v,
+ angle::ParamCapture *paramCapture);
+void CaptureSecondaryColorPointer_pointer(const State &glState,
+ bool isCallValid,
+ GLint size,
+ GLenum type,
+ GLsizei stride,
+ const void *pointer,
+ angle::ParamCapture *paramCapture);
+void CaptureWindowPos2dv_v(const State &glState,
+ bool isCallValid,
+ const GLdouble *v,
+ angle::ParamCapture *paramCapture);
+void CaptureWindowPos2fv_v(const State &glState,
+ bool isCallValid,
+ const GLfloat *v,
+ angle::ParamCapture *paramCapture);
+void CaptureWindowPos2iv_v(const State &glState,
+ bool isCallValid,
+ const GLint *v,
+ angle::ParamCapture *paramCapture);
+void CaptureWindowPos2sv_v(const State &glState,
+ bool isCallValid,
+ const GLshort *v,
+ angle::ParamCapture *paramCapture);
+void CaptureWindowPos3dv_v(const State &glState,
+ bool isCallValid,
+ const GLdouble *v,
+ angle::ParamCapture *paramCapture);
+void CaptureWindowPos3fv_v(const State &glState,
+ bool isCallValid,
+ const GLfloat *v,
+ angle::ParamCapture *paramCapture);
+void CaptureWindowPos3iv_v(const State &glState,
+ bool isCallValid,
+ const GLint *v,
+ angle::ParamCapture *paramCapture);
+void CaptureWindowPos3sv_v(const State &glState,
+ bool isCallValid,
+ const GLshort *v,
+ angle::ParamCapture *paramCapture);
+
+// GL 1.5
+void CaptureGetBufferSubData_data(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLintptr offset,
+ GLsizeiptr size,
+ void *data,
+ angle::ParamCapture *paramCapture);
+void CaptureGetQueryObjectiv_params(const State &glState,
+ bool isCallValid,
+ QueryID idPacked,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+} // namespace gl
+
+#endif // LIBANGLE_CAPTURE_GL_1_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libANGLE/capture/capture_gl_2_autogen.h b/gfx/angle/checkout/src/libANGLE/capture/capture_gl_2_autogen.h
new file mode 100644
index 0000000000..5ab30a6b9a
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/capture/capture_gl_2_autogen.h
@@ -0,0 +1,266 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml and gl_angle_ext.xml.
+//
+// Copyright 2020 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.
+//
+// capture_gl_2_autogen.h:
+// Capture functions for the OpenGL ES Desktop GL 2.x entry points.
+
+#ifndef LIBANGLE_CAPTURE_GL_2_AUTOGEN_H_
+#define LIBANGLE_CAPTURE_GL_2_AUTOGEN_H_
+
+#include "common/PackedEnums.h"
+#include "libANGLE/capture/FrameCapture.h"
+
+namespace gl
+{
+
+// Method Captures
+
+// GL 2.0
+angle::CallCapture CaptureGetVertexAttribdv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLenum pname,
+ GLdouble *params);
+angle::CallCapture CaptureVertexAttrib1d(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLdouble x);
+angle::CallCapture CaptureVertexAttrib1dv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLdouble *v);
+angle::CallCapture CaptureVertexAttrib1s(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLshort x);
+angle::CallCapture CaptureVertexAttrib1sv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLshort *v);
+angle::CallCapture CaptureVertexAttrib2d(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLdouble x,
+ GLdouble y);
+angle::CallCapture CaptureVertexAttrib2dv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLdouble *v);
+angle::CallCapture CaptureVertexAttrib2s(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLshort x,
+ GLshort y);
+angle::CallCapture CaptureVertexAttrib2sv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLshort *v);
+angle::CallCapture CaptureVertexAttrib3d(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z);
+angle::CallCapture CaptureVertexAttrib3dv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLdouble *v);
+angle::CallCapture CaptureVertexAttrib3s(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLshort x,
+ GLshort y,
+ GLshort z);
+angle::CallCapture CaptureVertexAttrib3sv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLshort *v);
+angle::CallCapture CaptureVertexAttrib4Nbv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLbyte *v);
+angle::CallCapture CaptureVertexAttrib4Niv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLint *v);
+angle::CallCapture CaptureVertexAttrib4Nsv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLshort *v);
+angle::CallCapture CaptureVertexAttrib4Nub(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLubyte x,
+ GLubyte y,
+ GLubyte z,
+ GLubyte w);
+angle::CallCapture CaptureVertexAttrib4Nubv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLubyte *v);
+angle::CallCapture CaptureVertexAttrib4Nuiv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLuint *v);
+angle::CallCapture CaptureVertexAttrib4Nusv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLushort *v);
+angle::CallCapture CaptureVertexAttrib4bv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLbyte *v);
+angle::CallCapture CaptureVertexAttrib4d(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z,
+ GLdouble w);
+angle::CallCapture CaptureVertexAttrib4dv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLdouble *v);
+angle::CallCapture CaptureVertexAttrib4iv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLint *v);
+angle::CallCapture CaptureVertexAttrib4s(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLshort x,
+ GLshort y,
+ GLshort z,
+ GLshort w);
+angle::CallCapture CaptureVertexAttrib4sv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLshort *v);
+angle::CallCapture CaptureVertexAttrib4ubv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLubyte *v);
+angle::CallCapture CaptureVertexAttrib4uiv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLuint *v);
+angle::CallCapture CaptureVertexAttrib4usv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLushort *v);
+
+// GL 2.1
+
+// Parameter Captures
+
+// GL 2.0
+void CaptureGetVertexAttribdv_params(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLenum pname,
+ GLdouble *params,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttrib1dv_v(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLdouble *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttrib1sv_v(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLshort *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttrib2dv_v(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLdouble *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttrib2sv_v(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLshort *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttrib3dv_v(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLdouble *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttrib3sv_v(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLshort *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttrib4Nbv_v(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLbyte *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttrib4Niv_v(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLint *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttrib4Nsv_v(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLshort *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttrib4Nubv_v(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLubyte *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttrib4Nuiv_v(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLuint *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttrib4Nusv_v(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLushort *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttrib4bv_v(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLbyte *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttrib4dv_v(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLdouble *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttrib4iv_v(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLint *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttrib4sv_v(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLshort *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttrib4ubv_v(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLubyte *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttrib4uiv_v(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLuint *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttrib4usv_v(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLushort *v,
+ angle::ParamCapture *paramCapture);
+
+// GL 2.1
+} // namespace gl
+
+#endif // LIBANGLE_CAPTURE_GL_2_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libANGLE/capture/capture_gl_3_autogen.h b/gfx/angle/checkout/src/libANGLE/capture/capture_gl_3_autogen.h
new file mode 100644
index 0000000000..b365fbec7c
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/capture/capture_gl_3_autogen.h
@@ -0,0 +1,609 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml and gl_angle_ext.xml.
+//
+// Copyright 2020 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.
+//
+// capture_gl_3_autogen.h:
+// Capture functions for the OpenGL ES Desktop GL 3.x entry points.
+
+#ifndef LIBANGLE_CAPTURE_GL_3_AUTOGEN_H_
+#define LIBANGLE_CAPTURE_GL_3_AUTOGEN_H_
+
+#include "common/PackedEnums.h"
+#include "libANGLE/capture/FrameCapture.h"
+
+namespace gl
+{
+
+// Method Captures
+
+// GL 3.0
+angle::CallCapture CaptureBeginConditionalRender(const State &glState,
+ bool isCallValid,
+ GLuint id,
+ GLenum mode);
+angle::CallCapture CaptureBindFragDataLocation(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLuint color,
+ const GLchar *name);
+angle::CallCapture CaptureClampColor(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum clamp);
+angle::CallCapture CaptureEndConditionalRender(const State &glState, bool isCallValid);
+angle::CallCapture CaptureFramebufferTexture1D(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum attachment,
+ TextureTarget textargetPacked,
+ TextureID texturePacked,
+ GLint level);
+angle::CallCapture CaptureFramebufferTexture3D(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum attachment,
+ TextureTarget textargetPacked,
+ TextureID texturePacked,
+ GLint level,
+ GLint zoffset);
+angle::CallCapture CaptureVertexAttribI1i(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLint x);
+angle::CallCapture CaptureVertexAttribI1iv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLint *v);
+angle::CallCapture CaptureVertexAttribI1ui(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLuint x);
+angle::CallCapture CaptureVertexAttribI1uiv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLuint *v);
+angle::CallCapture CaptureVertexAttribI2i(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLint x,
+ GLint y);
+angle::CallCapture CaptureVertexAttribI2iv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLint *v);
+angle::CallCapture CaptureVertexAttribI2ui(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLuint x,
+ GLuint y);
+angle::CallCapture CaptureVertexAttribI2uiv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLuint *v);
+angle::CallCapture CaptureVertexAttribI3i(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLint x,
+ GLint y,
+ GLint z);
+angle::CallCapture CaptureVertexAttribI3iv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLint *v);
+angle::CallCapture CaptureVertexAttribI3ui(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLuint x,
+ GLuint y,
+ GLuint z);
+angle::CallCapture CaptureVertexAttribI3uiv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLuint *v);
+angle::CallCapture CaptureVertexAttribI4bv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLbyte *v);
+angle::CallCapture CaptureVertexAttribI4sv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLshort *v);
+angle::CallCapture CaptureVertexAttribI4ubv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLubyte *v);
+angle::CallCapture CaptureVertexAttribI4usv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLushort *v);
+
+// GL 3.1
+angle::CallCapture CaptureGetActiveUniformName(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLuint uniformIndex,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *uniformName);
+angle::CallCapture CapturePrimitiveRestartIndex(const State &glState,
+ bool isCallValid,
+ GLuint index);
+
+// GL 3.2
+angle::CallCapture CaptureMultiDrawElementsBaseVertex(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const GLsizei *count,
+ DrawElementsType typePacked,
+ const void *const *indices,
+ GLsizei drawcount,
+ const GLint *basevertex);
+angle::CallCapture CaptureProvokingVertex(const State &glState,
+ bool isCallValid,
+ ProvokingVertexConvention modePacked);
+angle::CallCapture CaptureTexImage2DMultisample(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedsamplelocations);
+angle::CallCapture CaptureTexImage3DMultisample(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean fixedsamplelocations);
+
+// GL 3.3
+angle::CallCapture CaptureBindFragDataLocationIndexed(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLuint colorNumber,
+ GLuint index,
+ const GLchar *name);
+angle::CallCapture CaptureColorP3ui(const State &glState,
+ bool isCallValid,
+ GLenum type,
+ GLuint color);
+angle::CallCapture CaptureColorP3uiv(const State &glState,
+ bool isCallValid,
+ GLenum type,
+ const GLuint *color);
+angle::CallCapture CaptureColorP4ui(const State &glState,
+ bool isCallValid,
+ GLenum type,
+ GLuint color);
+angle::CallCapture CaptureColorP4uiv(const State &glState,
+ bool isCallValid,
+ GLenum type,
+ const GLuint *color);
+angle::CallCapture CaptureGetFragDataIndex(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ const GLchar *name,
+ GLint returnValue);
+angle::CallCapture CaptureGetQueryObjecti64v(const State &glState,
+ bool isCallValid,
+ QueryID idPacked,
+ GLenum pname,
+ GLint64 *params);
+angle::CallCapture CaptureGetQueryObjectui64v(const State &glState,
+ bool isCallValid,
+ QueryID idPacked,
+ GLenum pname,
+ GLuint64 *params);
+angle::CallCapture CaptureMultiTexCoordP1ui(const State &glState,
+ bool isCallValid,
+ GLenum texture,
+ GLenum type,
+ GLuint coords);
+angle::CallCapture CaptureMultiTexCoordP1uiv(const State &glState,
+ bool isCallValid,
+ GLenum texture,
+ GLenum type,
+ const GLuint *coords);
+angle::CallCapture CaptureMultiTexCoordP2ui(const State &glState,
+ bool isCallValid,
+ GLenum texture,
+ GLenum type,
+ GLuint coords);
+angle::CallCapture CaptureMultiTexCoordP2uiv(const State &glState,
+ bool isCallValid,
+ GLenum texture,
+ GLenum type,
+ const GLuint *coords);
+angle::CallCapture CaptureMultiTexCoordP3ui(const State &glState,
+ bool isCallValid,
+ GLenum texture,
+ GLenum type,
+ GLuint coords);
+angle::CallCapture CaptureMultiTexCoordP3uiv(const State &glState,
+ bool isCallValid,
+ GLenum texture,
+ GLenum type,
+ const GLuint *coords);
+angle::CallCapture CaptureMultiTexCoordP4ui(const State &glState,
+ bool isCallValid,
+ GLenum texture,
+ GLenum type,
+ GLuint coords);
+angle::CallCapture CaptureMultiTexCoordP4uiv(const State &glState,
+ bool isCallValid,
+ GLenum texture,
+ GLenum type,
+ const GLuint *coords);
+angle::CallCapture CaptureNormalP3ui(const State &glState,
+ bool isCallValid,
+ GLenum type,
+ GLuint coords);
+angle::CallCapture CaptureNormalP3uiv(const State &glState,
+ bool isCallValid,
+ GLenum type,
+ const GLuint *coords);
+angle::CallCapture CaptureQueryCounter(const State &glState,
+ bool isCallValid,
+ QueryID idPacked,
+ QueryType targetPacked);
+angle::CallCapture CaptureSecondaryColorP3ui(const State &glState,
+ bool isCallValid,
+ GLenum type,
+ GLuint color);
+angle::CallCapture CaptureSecondaryColorP3uiv(const State &glState,
+ bool isCallValid,
+ GLenum type,
+ const GLuint *color);
+angle::CallCapture CaptureTexCoordP1ui(const State &glState,
+ bool isCallValid,
+ GLenum type,
+ GLuint coords);
+angle::CallCapture CaptureTexCoordP1uiv(const State &glState,
+ bool isCallValid,
+ GLenum type,
+ const GLuint *coords);
+angle::CallCapture CaptureTexCoordP2ui(const State &glState,
+ bool isCallValid,
+ GLenum type,
+ GLuint coords);
+angle::CallCapture CaptureTexCoordP2uiv(const State &glState,
+ bool isCallValid,
+ GLenum type,
+ const GLuint *coords);
+angle::CallCapture CaptureTexCoordP3ui(const State &glState,
+ bool isCallValid,
+ GLenum type,
+ GLuint coords);
+angle::CallCapture CaptureTexCoordP3uiv(const State &glState,
+ bool isCallValid,
+ GLenum type,
+ const GLuint *coords);
+angle::CallCapture CaptureTexCoordP4ui(const State &glState,
+ bool isCallValid,
+ GLenum type,
+ GLuint coords);
+angle::CallCapture CaptureTexCoordP4uiv(const State &glState,
+ bool isCallValid,
+ GLenum type,
+ const GLuint *coords);
+angle::CallCapture CaptureVertexAttribP1ui(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLenum type,
+ GLboolean normalized,
+ GLuint value);
+angle::CallCapture CaptureVertexAttribP1uiv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLenum type,
+ GLboolean normalized,
+ const GLuint *value);
+angle::CallCapture CaptureVertexAttribP2ui(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLenum type,
+ GLboolean normalized,
+ GLuint value);
+angle::CallCapture CaptureVertexAttribP2uiv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLenum type,
+ GLboolean normalized,
+ const GLuint *value);
+angle::CallCapture CaptureVertexAttribP3ui(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLenum type,
+ GLboolean normalized,
+ GLuint value);
+angle::CallCapture CaptureVertexAttribP3uiv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLenum type,
+ GLboolean normalized,
+ const GLuint *value);
+angle::CallCapture CaptureVertexAttribP4ui(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLenum type,
+ GLboolean normalized,
+ GLuint value);
+angle::CallCapture CaptureVertexAttribP4uiv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLenum type,
+ GLboolean normalized,
+ const GLuint *value);
+angle::CallCapture CaptureVertexP2ui(const State &glState,
+ bool isCallValid,
+ GLenum type,
+ GLuint value);
+angle::CallCapture CaptureVertexP2uiv(const State &glState,
+ bool isCallValid,
+ GLenum type,
+ const GLuint *value);
+angle::CallCapture CaptureVertexP3ui(const State &glState,
+ bool isCallValid,
+ GLenum type,
+ GLuint value);
+angle::CallCapture CaptureVertexP3uiv(const State &glState,
+ bool isCallValid,
+ GLenum type,
+ const GLuint *value);
+angle::CallCapture CaptureVertexP4ui(const State &glState,
+ bool isCallValid,
+ GLenum type,
+ GLuint value);
+angle::CallCapture CaptureVertexP4uiv(const State &glState,
+ bool isCallValid,
+ GLenum type,
+ const GLuint *value);
+
+// Parameter Captures
+
+// GL 3.0
+void CaptureBindFragDataLocation_name(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLuint color,
+ const GLchar *name,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttribI1iv_v(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLint *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttribI1uiv_v(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLuint *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttribI2iv_v(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLint *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttribI2uiv_v(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLuint *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttribI3iv_v(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLint *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttribI3uiv_v(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLuint *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttribI4bv_v(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLbyte *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttribI4sv_v(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLshort *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttribI4ubv_v(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLubyte *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttribI4usv_v(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLushort *v,
+ angle::ParamCapture *paramCapture);
+
+// GL 3.1
+void CaptureGetActiveUniformName_length(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLuint uniformIndex,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *uniformName,
+ angle::ParamCapture *paramCapture);
+void CaptureGetActiveUniformName_uniformName(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLuint uniformIndex,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *uniformName,
+ angle::ParamCapture *paramCapture);
+
+// GL 3.2
+void CaptureMultiDrawElementsBaseVertex_count(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const GLsizei *count,
+ DrawElementsType typePacked,
+ const void *const *indices,
+ GLsizei drawcount,
+ const GLint *basevertex,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiDrawElementsBaseVertex_indices(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const GLsizei *count,
+ DrawElementsType typePacked,
+ const void *const *indices,
+ GLsizei drawcount,
+ const GLint *basevertex,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiDrawElementsBaseVertex_basevertex(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const GLsizei *count,
+ DrawElementsType typePacked,
+ const void *const *indices,
+ GLsizei drawcount,
+ const GLint *basevertex,
+ angle::ParamCapture *paramCapture);
+
+// GL 3.3
+void CaptureBindFragDataLocationIndexed_name(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLuint colorNumber,
+ GLuint index,
+ const GLchar *name,
+ angle::ParamCapture *paramCapture);
+void CaptureColorP3uiv_color(const State &glState,
+ bool isCallValid,
+ GLenum type,
+ const GLuint *color,
+ angle::ParamCapture *paramCapture);
+void CaptureColorP4uiv_color(const State &glState,
+ bool isCallValid,
+ GLenum type,
+ const GLuint *color,
+ angle::ParamCapture *paramCapture);
+void CaptureGetFragDataIndex_name(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ const GLchar *name,
+ angle::ParamCapture *paramCapture);
+void CaptureGetQueryObjecti64v_params(const State &glState,
+ bool isCallValid,
+ QueryID idPacked,
+ GLenum pname,
+ GLint64 *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetQueryObjectui64v_params(const State &glState,
+ bool isCallValid,
+ QueryID idPacked,
+ GLenum pname,
+ GLuint64 *params,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiTexCoordP1uiv_coords(const State &glState,
+ bool isCallValid,
+ GLenum texture,
+ GLenum type,
+ const GLuint *coords,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiTexCoordP2uiv_coords(const State &glState,
+ bool isCallValid,
+ GLenum texture,
+ GLenum type,
+ const GLuint *coords,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiTexCoordP3uiv_coords(const State &glState,
+ bool isCallValid,
+ GLenum texture,
+ GLenum type,
+ const GLuint *coords,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiTexCoordP4uiv_coords(const State &glState,
+ bool isCallValid,
+ GLenum texture,
+ GLenum type,
+ const GLuint *coords,
+ angle::ParamCapture *paramCapture);
+void CaptureNormalP3uiv_coords(const State &glState,
+ bool isCallValid,
+ GLenum type,
+ const GLuint *coords,
+ angle::ParamCapture *paramCapture);
+void CaptureSecondaryColorP3uiv_color(const State &glState,
+ bool isCallValid,
+ GLenum type,
+ const GLuint *color,
+ angle::ParamCapture *paramCapture);
+void CaptureTexCoordP1uiv_coords(const State &glState,
+ bool isCallValid,
+ GLenum type,
+ const GLuint *coords,
+ angle::ParamCapture *paramCapture);
+void CaptureTexCoordP2uiv_coords(const State &glState,
+ bool isCallValid,
+ GLenum type,
+ const GLuint *coords,
+ angle::ParamCapture *paramCapture);
+void CaptureTexCoordP3uiv_coords(const State &glState,
+ bool isCallValid,
+ GLenum type,
+ const GLuint *coords,
+ angle::ParamCapture *paramCapture);
+void CaptureTexCoordP4uiv_coords(const State &glState,
+ bool isCallValid,
+ GLenum type,
+ const GLuint *coords,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttribP1uiv_value(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLenum type,
+ GLboolean normalized,
+ const GLuint *value,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttribP2uiv_value(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLenum type,
+ GLboolean normalized,
+ const GLuint *value,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttribP3uiv_value(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLenum type,
+ GLboolean normalized,
+ const GLuint *value,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttribP4uiv_value(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLenum type,
+ GLboolean normalized,
+ const GLuint *value,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexP2uiv_value(const State &glState,
+ bool isCallValid,
+ GLenum type,
+ const GLuint *value,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexP3uiv_value(const State &glState,
+ bool isCallValid,
+ GLenum type,
+ const GLuint *value,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexP4uiv_value(const State &glState,
+ bool isCallValid,
+ GLenum type,
+ const GLuint *value,
+ angle::ParamCapture *paramCapture);
+} // namespace gl
+
+#endif // LIBANGLE_CAPTURE_GL_3_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libANGLE/capture/capture_gl_4_autogen.h b/gfx/angle/checkout/src/libANGLE/capture/capture_gl_4_autogen.h
new file mode 100644
index 0000000000..495bf4cb7f
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/capture/capture_gl_4_autogen.h
@@ -0,0 +1,2524 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml and gl_angle_ext.xml.
+//
+// Copyright 2020 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.
+//
+// capture_gl_4_autogen.h:
+// Capture functions for the OpenGL ES Desktop GL 4.x entry points.
+
+#ifndef LIBANGLE_CAPTURE_GL_4_AUTOGEN_H_
+#define LIBANGLE_CAPTURE_GL_4_AUTOGEN_H_
+
+#include "common/PackedEnums.h"
+#include "libANGLE/capture/FrameCapture.h"
+
+namespace gl
+{
+
+// Method Captures
+
+// GL 4.0
+angle::CallCapture CaptureBeginQueryIndexed(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLuint index,
+ QueryID idPacked);
+angle::CallCapture CaptureDrawTransformFeedback(const State &glState,
+ bool isCallValid,
+ GLenum mode,
+ TransformFeedbackID idPacked);
+angle::CallCapture CaptureDrawTransformFeedbackStream(const State &glState,
+ bool isCallValid,
+ GLenum mode,
+ TransformFeedbackID idPacked,
+ GLuint stream);
+angle::CallCapture CaptureEndQueryIndexed(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLuint index);
+angle::CallCapture CaptureGetActiveSubroutineName(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum shadertype,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *name);
+angle::CallCapture CaptureGetActiveSubroutineUniformName(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum shadertype,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *name);
+angle::CallCapture CaptureGetActiveSubroutineUniformiv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum shadertype,
+ GLuint index,
+ GLenum pname,
+ GLint *values);
+angle::CallCapture CaptureGetProgramStageiv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum shadertype,
+ GLenum pname,
+ GLint *values);
+angle::CallCapture CaptureGetQueryIndexediv(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLuint index,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureGetSubroutineIndex(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum shadertype,
+ const GLchar *name,
+ GLuint returnValue);
+angle::CallCapture CaptureGetSubroutineUniformLocation(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum shadertype,
+ const GLchar *name,
+ GLint returnValue);
+angle::CallCapture CaptureGetUniformSubroutineuiv(const State &glState,
+ bool isCallValid,
+ GLenum shadertype,
+ GLint location,
+ GLuint *params);
+angle::CallCapture CaptureGetUniformdv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLdouble *params);
+angle::CallCapture CapturePatchParameterfv(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ const GLfloat *values);
+angle::CallCapture CaptureUniform1d(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLdouble x);
+angle::CallCapture CaptureUniform1dv(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLdouble *value);
+angle::CallCapture CaptureUniform2d(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLdouble x,
+ GLdouble y);
+angle::CallCapture CaptureUniform2dv(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLdouble *value);
+angle::CallCapture CaptureUniform3d(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z);
+angle::CallCapture CaptureUniform3dv(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLdouble *value);
+angle::CallCapture CaptureUniform4d(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z,
+ GLdouble w);
+angle::CallCapture CaptureUniform4dv(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLdouble *value);
+angle::CallCapture CaptureUniformMatrix2dv(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value);
+angle::CallCapture CaptureUniformMatrix2x3dv(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value);
+angle::CallCapture CaptureUniformMatrix2x4dv(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value);
+angle::CallCapture CaptureUniformMatrix3dv(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value);
+angle::CallCapture CaptureUniformMatrix3x2dv(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value);
+angle::CallCapture CaptureUniformMatrix3x4dv(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value);
+angle::CallCapture CaptureUniformMatrix4dv(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value);
+angle::CallCapture CaptureUniformMatrix4x2dv(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value);
+angle::CallCapture CaptureUniformMatrix4x3dv(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value);
+angle::CallCapture CaptureUniformSubroutinesuiv(const State &glState,
+ bool isCallValid,
+ GLenum shadertype,
+ GLsizei count,
+ const GLuint *indices);
+
+// GL 4.1
+angle::CallCapture CaptureDepthRangeArrayv(const State &glState,
+ bool isCallValid,
+ GLuint first,
+ GLsizei count,
+ const GLdouble *v);
+angle::CallCapture CaptureDepthRangeIndexed(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLdouble n,
+ GLdouble f);
+angle::CallCapture CaptureGetDoublei_v(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLuint index,
+ GLdouble *data);
+angle::CallCapture CaptureGetFloati_v(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLuint index,
+ GLfloat *data);
+angle::CallCapture CaptureGetVertexAttribLdv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLenum pname,
+ GLdouble *params);
+angle::CallCapture CaptureProgramUniform1d(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLdouble v0);
+angle::CallCapture CaptureProgramUniform1dv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLdouble *value);
+angle::CallCapture CaptureProgramUniform2d(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLdouble v0,
+ GLdouble v1);
+angle::CallCapture CaptureProgramUniform2dv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLdouble *value);
+angle::CallCapture CaptureProgramUniform3d(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLdouble v0,
+ GLdouble v1,
+ GLdouble v2);
+angle::CallCapture CaptureProgramUniform3dv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLdouble *value);
+angle::CallCapture CaptureProgramUniform4d(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLdouble v0,
+ GLdouble v1,
+ GLdouble v2,
+ GLdouble v3);
+angle::CallCapture CaptureProgramUniform4dv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLdouble *value);
+angle::CallCapture CaptureProgramUniformMatrix2dv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value);
+angle::CallCapture CaptureProgramUniformMatrix2x3dv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value);
+angle::CallCapture CaptureProgramUniformMatrix2x4dv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value);
+angle::CallCapture CaptureProgramUniformMatrix3dv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value);
+angle::CallCapture CaptureProgramUniformMatrix3x2dv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value);
+angle::CallCapture CaptureProgramUniformMatrix3x4dv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value);
+angle::CallCapture CaptureProgramUniformMatrix4dv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value);
+angle::CallCapture CaptureProgramUniformMatrix4x2dv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value);
+angle::CallCapture CaptureProgramUniformMatrix4x3dv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value);
+angle::CallCapture CaptureScissorArrayv(const State &glState,
+ bool isCallValid,
+ GLuint first,
+ GLsizei count,
+ const GLint *v);
+angle::CallCapture CaptureScissorIndexed(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLint left,
+ GLint bottom,
+ GLsizei width,
+ GLsizei height);
+angle::CallCapture CaptureScissorIndexedv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLint *v);
+angle::CallCapture CaptureVertexAttribL1d(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLdouble x);
+angle::CallCapture CaptureVertexAttribL1dv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLdouble *v);
+angle::CallCapture CaptureVertexAttribL2d(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLdouble x,
+ GLdouble y);
+angle::CallCapture CaptureVertexAttribL2dv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLdouble *v);
+angle::CallCapture CaptureVertexAttribL3d(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z);
+angle::CallCapture CaptureVertexAttribL3dv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLdouble *v);
+angle::CallCapture CaptureVertexAttribL4d(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z,
+ GLdouble w);
+angle::CallCapture CaptureVertexAttribL4dv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLdouble *v);
+angle::CallCapture CaptureVertexAttribLPointer(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLint size,
+ GLenum type,
+ GLsizei stride,
+ const void *pointer);
+angle::CallCapture CaptureViewportArrayv(const State &glState,
+ bool isCallValid,
+ GLuint first,
+ GLsizei count,
+ const GLfloat *v);
+angle::CallCapture CaptureViewportIndexedf(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLfloat x,
+ GLfloat y,
+ GLfloat w,
+ GLfloat h);
+angle::CallCapture CaptureViewportIndexedfv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLfloat *v);
+
+// GL 4.2
+angle::CallCapture CaptureDrawArraysInstancedBaseInstance(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLint first,
+ GLsizei count,
+ GLsizei instancecount,
+ GLuint baseinstance);
+angle::CallCapture CaptureDrawElementsInstancedBaseInstance(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLsizei instancecount,
+ GLuint baseinstance);
+angle::CallCapture CaptureDrawElementsInstancedBaseVertexBaseInstance(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLsizei instancecount,
+ GLint basevertex,
+ GLuint baseinstance);
+angle::CallCapture CaptureDrawTransformFeedbackInstanced(const State &glState,
+ bool isCallValid,
+ GLenum mode,
+ TransformFeedbackID idPacked,
+ GLsizei instancecount);
+angle::CallCapture CaptureDrawTransformFeedbackStreamInstanced(const State &glState,
+ bool isCallValid,
+ GLenum mode,
+ TransformFeedbackID idPacked,
+ GLuint stream,
+ GLsizei instancecount);
+angle::CallCapture CaptureGetActiveAtomicCounterBufferiv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLuint bufferIndex,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureTexStorage1D(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width);
+
+// GL 4.3
+angle::CallCapture CaptureClearBufferData(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum internalformat,
+ GLenum format,
+ GLenum type,
+ const void *data);
+angle::CallCapture CaptureClearBufferSubData(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum internalformat,
+ GLintptr offset,
+ GLsizeiptr size,
+ GLenum format,
+ GLenum type,
+ const void *data);
+angle::CallCapture CaptureGetInternalformati64v(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum internalformat,
+ GLenum pname,
+ GLsizei count,
+ GLint64 *params);
+angle::CallCapture CaptureGetProgramResourceLocationIndex(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum programInterface,
+ const GLchar *name,
+ GLint returnValue);
+angle::CallCapture CaptureInvalidateBufferData(const State &glState,
+ bool isCallValid,
+ BufferID bufferPacked);
+angle::CallCapture CaptureInvalidateBufferSubData(const State &glState,
+ bool isCallValid,
+ BufferID bufferPacked,
+ GLintptr offset,
+ GLsizeiptr length);
+angle::CallCapture CaptureInvalidateTexImage(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLint level);
+angle::CallCapture CaptureInvalidateTexSubImage(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth);
+angle::CallCapture CaptureMultiDrawArraysIndirect(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const void *indirect,
+ GLsizei drawcount,
+ GLsizei stride);
+angle::CallCapture CaptureMultiDrawElementsIndirect(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ DrawElementsType typePacked,
+ const void *indirect,
+ GLsizei drawcount,
+ GLsizei stride);
+angle::CallCapture CaptureShaderStorageBlockBinding(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLuint storageBlockIndex,
+ GLuint storageBlockBinding);
+angle::CallCapture CaptureTextureView(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLenum target,
+ GLuint origtexture,
+ GLenum internalformat,
+ GLuint minlevel,
+ GLuint numlevels,
+ GLuint minlayer,
+ GLuint numlayers);
+angle::CallCapture CaptureVertexAttribLFormat(const State &glState,
+ bool isCallValid,
+ GLuint attribindex,
+ GLint size,
+ GLenum type,
+ GLuint relativeoffset);
+
+// GL 4.4
+angle::CallCapture CaptureBindBuffersBase(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLuint first,
+ GLsizei count,
+ const BufferID *buffersPacked);
+angle::CallCapture CaptureBindBuffersRange(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLuint first,
+ GLsizei count,
+ const BufferID *buffersPacked,
+ const GLintptr *offsets,
+ const GLsizeiptr *sizes);
+angle::CallCapture CaptureBindImageTextures(const State &glState,
+ bool isCallValid,
+ GLuint first,
+ GLsizei count,
+ const GLuint *textures);
+angle::CallCapture CaptureBindSamplers(const State &glState,
+ bool isCallValid,
+ GLuint first,
+ GLsizei count,
+ const GLuint *samplers);
+angle::CallCapture CaptureBindTextures(const State &glState,
+ bool isCallValid,
+ GLuint first,
+ GLsizei count,
+ const GLuint *textures);
+angle::CallCapture CaptureBindVertexBuffers(const State &glState,
+ bool isCallValid,
+ GLuint first,
+ GLsizei count,
+ const BufferID *buffersPacked,
+ const GLintptr *offsets,
+ const GLsizei *strides);
+angle::CallCapture CaptureBufferStorage(const State &glState,
+ bool isCallValid,
+ BufferBinding targetPacked,
+ GLsizeiptr size,
+ const void *data,
+ GLbitfield flags);
+angle::CallCapture CaptureClearTexImage(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLint level,
+ GLenum format,
+ GLenum type,
+ const void *data);
+angle::CallCapture CaptureClearTexSubImage(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ const void *data);
+
+// GL 4.5
+angle::CallCapture CaptureBindTextureUnit(const State &glState,
+ bool isCallValid,
+ GLuint unit,
+ TextureID texturePacked);
+angle::CallCapture CaptureBlitNamedFramebuffer(const State &glState,
+ bool isCallValid,
+ GLuint readFramebuffer,
+ GLuint drawFramebuffer,
+ GLint srcX0,
+ GLint srcY0,
+ GLint srcX1,
+ GLint srcY1,
+ GLint dstX0,
+ GLint dstY0,
+ GLint dstX1,
+ GLint dstY1,
+ GLbitfield mask,
+ GLenum filter);
+angle::CallCapture CaptureCheckNamedFramebufferStatus(const State &glState,
+ bool isCallValid,
+ FramebufferID framebufferPacked,
+ GLenum target,
+ GLenum returnValue);
+angle::CallCapture CaptureClearNamedBufferData(const State &glState,
+ bool isCallValid,
+ BufferID bufferPacked,
+ GLenum internalformat,
+ GLenum format,
+ GLenum type,
+ const void *data);
+angle::CallCapture CaptureClearNamedBufferSubData(const State &glState,
+ bool isCallValid,
+ BufferID bufferPacked,
+ GLenum internalformat,
+ GLintptr offset,
+ GLsizeiptr size,
+ GLenum format,
+ GLenum type,
+ const void *data);
+angle::CallCapture CaptureClearNamedFramebufferfi(const State &glState,
+ bool isCallValid,
+ FramebufferID framebufferPacked,
+ GLenum buffer,
+ GLint drawbuffer,
+ GLfloat depth,
+ GLint stencil);
+angle::CallCapture CaptureClearNamedFramebufferfv(const State &glState,
+ bool isCallValid,
+ FramebufferID framebufferPacked,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLfloat *value);
+angle::CallCapture CaptureClearNamedFramebufferiv(const State &glState,
+ bool isCallValid,
+ FramebufferID framebufferPacked,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLint *value);
+angle::CallCapture CaptureClearNamedFramebufferuiv(const State &glState,
+ bool isCallValid,
+ FramebufferID framebufferPacked,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLuint *value);
+angle::CallCapture CaptureClipControl(const State &glState,
+ bool isCallValid,
+ GLenum origin,
+ GLenum depth);
+angle::CallCapture CaptureCompressedTextureSubImage1D(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLint level,
+ GLint xoffset,
+ GLsizei width,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data);
+angle::CallCapture CaptureCompressedTextureSubImage2D(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data);
+angle::CallCapture CaptureCompressedTextureSubImage3D(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data);
+angle::CallCapture CaptureCopyNamedBufferSubData(const State &glState,
+ bool isCallValid,
+ GLuint readBuffer,
+ GLuint writeBuffer,
+ GLintptr readOffset,
+ GLintptr writeOffset,
+ GLsizeiptr size);
+angle::CallCapture CaptureCopyTextureSubImage1D(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLint level,
+ GLint xoffset,
+ GLint x,
+ GLint y,
+ GLsizei width);
+angle::CallCapture CaptureCopyTextureSubImage2D(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height);
+angle::CallCapture CaptureCopyTextureSubImage3D(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height);
+angle::CallCapture CaptureCreateBuffers(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ BufferID *buffersPacked);
+angle::CallCapture CaptureCreateFramebuffers(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ GLuint *framebuffers);
+angle::CallCapture CaptureCreateProgramPipelines(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ GLuint *pipelines);
+angle::CallCapture CaptureCreateQueries(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLsizei n,
+ GLuint *ids);
+angle::CallCapture CaptureCreateRenderbuffers(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ RenderbufferID *renderbuffersPacked);
+angle::CallCapture CaptureCreateSamplers(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ GLuint *samplers);
+angle::CallCapture CaptureCreateTextures(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLsizei n,
+ GLuint *textures);
+angle::CallCapture CaptureCreateTransformFeedbacks(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ GLuint *ids);
+angle::CallCapture CaptureCreateVertexArrays(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ VertexArrayID *arraysPacked);
+angle::CallCapture CaptureDisableVertexArrayAttrib(const State &glState,
+ bool isCallValid,
+ VertexArrayID vaobjPacked,
+ GLuint index);
+angle::CallCapture CaptureEnableVertexArrayAttrib(const State &glState,
+ bool isCallValid,
+ VertexArrayID vaobjPacked,
+ GLuint index);
+angle::CallCapture CaptureFlushMappedNamedBufferRange(const State &glState,
+ bool isCallValid,
+ BufferID bufferPacked,
+ GLintptr offset,
+ GLsizeiptr length);
+angle::CallCapture CaptureGenerateTextureMipmap(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked);
+angle::CallCapture CaptureGetCompressedTextureImage(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLint level,
+ GLsizei bufSize,
+ void *pixels);
+angle::CallCapture CaptureGetCompressedTextureSubImage(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLsizei bufSize,
+ void *pixels);
+angle::CallCapture CaptureGetNamedBufferParameteri64v(const State &glState,
+ bool isCallValid,
+ BufferID bufferPacked,
+ GLenum pname,
+ GLint64 *params);
+angle::CallCapture CaptureGetNamedBufferParameteriv(const State &glState,
+ bool isCallValid,
+ BufferID bufferPacked,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureGetNamedBufferPointerv(const State &glState,
+ bool isCallValid,
+ BufferID bufferPacked,
+ GLenum pname,
+ void **params);
+angle::CallCapture CaptureGetNamedBufferSubData(const State &glState,
+ bool isCallValid,
+ BufferID bufferPacked,
+ GLintptr offset,
+ GLsizeiptr size,
+ void *data);
+angle::CallCapture CaptureGetNamedFramebufferAttachmentParameteriv(const State &glState,
+ bool isCallValid,
+ FramebufferID framebufferPacked,
+ GLenum attachment,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureGetNamedFramebufferParameteriv(const State &glState,
+ bool isCallValid,
+ FramebufferID framebufferPacked,
+ GLenum pname,
+ GLint *param);
+angle::CallCapture CaptureGetNamedRenderbufferParameteriv(const State &glState,
+ bool isCallValid,
+ RenderbufferID renderbufferPacked,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureGetQueryBufferObjecti64v(const State &glState,
+ bool isCallValid,
+ GLuint id,
+ BufferID bufferPacked,
+ GLenum pname,
+ GLintptr offset);
+angle::CallCapture CaptureGetQueryBufferObjectiv(const State &glState,
+ bool isCallValid,
+ GLuint id,
+ BufferID bufferPacked,
+ GLenum pname,
+ GLintptr offset);
+angle::CallCapture CaptureGetQueryBufferObjectui64v(const State &glState,
+ bool isCallValid,
+ GLuint id,
+ BufferID bufferPacked,
+ GLenum pname,
+ GLintptr offset);
+angle::CallCapture CaptureGetQueryBufferObjectuiv(const State &glState,
+ bool isCallValid,
+ GLuint id,
+ BufferID bufferPacked,
+ GLenum pname,
+ GLintptr offset);
+angle::CallCapture CaptureGetTextureImage(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLint level,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ void *pixels);
+angle::CallCapture CaptureGetTextureLevelParameterfv(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLint level,
+ GLenum pname,
+ GLfloat *params);
+angle::CallCapture CaptureGetTextureLevelParameteriv(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLint level,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureGetTextureParameterIiv(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureGetTextureParameterIuiv(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLenum pname,
+ GLuint *params);
+angle::CallCapture CaptureGetTextureParameterfv(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLenum pname,
+ GLfloat *params);
+angle::CallCapture CaptureGetTextureParameteriv(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureGetTextureSubImage(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ void *pixels);
+angle::CallCapture CaptureGetTransformFeedbacki64_v(const State &glState,
+ bool isCallValid,
+ GLuint xfb,
+ GLenum pname,
+ GLuint index,
+ GLint64 *param);
+angle::CallCapture CaptureGetTransformFeedbacki_v(const State &glState,
+ bool isCallValid,
+ GLuint xfb,
+ GLenum pname,
+ GLuint index,
+ GLint *param);
+angle::CallCapture CaptureGetTransformFeedbackiv(const State &glState,
+ bool isCallValid,
+ GLuint xfb,
+ GLenum pname,
+ GLint *param);
+angle::CallCapture CaptureGetVertexArrayIndexed64iv(const State &glState,
+ bool isCallValid,
+ VertexArrayID vaobjPacked,
+ GLuint index,
+ GLenum pname,
+ GLint64 *param);
+angle::CallCapture CaptureGetVertexArrayIndexediv(const State &glState,
+ bool isCallValid,
+ VertexArrayID vaobjPacked,
+ GLuint index,
+ GLenum pname,
+ GLint *param);
+angle::CallCapture CaptureGetVertexArrayiv(const State &glState,
+ bool isCallValid,
+ VertexArrayID vaobjPacked,
+ GLenum pname,
+ GLint *param);
+angle::CallCapture CaptureGetnColorTable(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ void *table);
+angle::CallCapture CaptureGetnCompressedTexImage(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLint lod,
+ GLsizei bufSize,
+ void *pixels);
+angle::CallCapture CaptureGetnConvolutionFilter(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ void *image);
+angle::CallCapture CaptureGetnHistogram(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLboolean reset,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ void *values);
+angle::CallCapture CaptureGetnMapdv(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum query,
+ GLsizei bufSize,
+ GLdouble *v);
+angle::CallCapture CaptureGetnMapfv(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum query,
+ GLsizei bufSize,
+ GLfloat *v);
+angle::CallCapture CaptureGetnMapiv(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum query,
+ GLsizei bufSize,
+ GLint *v);
+angle::CallCapture CaptureGetnMinmax(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLboolean reset,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ void *values);
+angle::CallCapture CaptureGetnPixelMapfv(const State &glState,
+ bool isCallValid,
+ GLenum map,
+ GLsizei bufSize,
+ GLfloat *values);
+angle::CallCapture CaptureGetnPixelMapuiv(const State &glState,
+ bool isCallValid,
+ GLenum map,
+ GLsizei bufSize,
+ GLuint *values);
+angle::CallCapture CaptureGetnPixelMapusv(const State &glState,
+ bool isCallValid,
+ GLenum map,
+ GLsizei bufSize,
+ GLushort *values);
+angle::CallCapture CaptureGetnPolygonStipple(const State &glState,
+ bool isCallValid,
+ GLsizei bufSize,
+ GLubyte *pattern);
+angle::CallCapture CaptureGetnSeparableFilter(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum format,
+ GLenum type,
+ GLsizei rowBufSize,
+ void *row,
+ GLsizei columnBufSize,
+ void *column,
+ void *span);
+angle::CallCapture CaptureGetnTexImage(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLint level,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ void *pixels);
+angle::CallCapture CaptureGetnUniformdv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei bufSize,
+ GLdouble *params);
+angle::CallCapture CaptureInvalidateNamedFramebufferData(const State &glState,
+ bool isCallValid,
+ FramebufferID framebufferPacked,
+ GLsizei numAttachments,
+ const GLenum *attachments);
+angle::CallCapture CaptureInvalidateNamedFramebufferSubData(const State &glState,
+ bool isCallValid,
+ FramebufferID framebufferPacked,
+ GLsizei numAttachments,
+ const GLenum *attachments,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height);
+angle::CallCapture CaptureMapNamedBuffer(const State &glState,
+ bool isCallValid,
+ BufferID bufferPacked,
+ GLenum access,
+ void *returnValue);
+angle::CallCapture CaptureMapNamedBufferRange(const State &glState,
+ bool isCallValid,
+ BufferID bufferPacked,
+ GLintptr offset,
+ GLsizeiptr length,
+ GLbitfield access,
+ void *returnValue);
+angle::CallCapture CaptureNamedBufferData(const State &glState,
+ bool isCallValid,
+ BufferID bufferPacked,
+ GLsizeiptr size,
+ const void *data,
+ GLenum usage);
+angle::CallCapture CaptureNamedBufferStorage(const State &glState,
+ bool isCallValid,
+ BufferID bufferPacked,
+ GLsizeiptr size,
+ const void *data,
+ GLbitfield flags);
+angle::CallCapture CaptureNamedBufferSubData(const State &glState,
+ bool isCallValid,
+ BufferID bufferPacked,
+ GLintptr offset,
+ GLsizeiptr size,
+ const void *data);
+angle::CallCapture CaptureNamedFramebufferDrawBuffer(const State &glState,
+ bool isCallValid,
+ FramebufferID framebufferPacked,
+ GLenum buf);
+angle::CallCapture CaptureNamedFramebufferDrawBuffers(const State &glState,
+ bool isCallValid,
+ FramebufferID framebufferPacked,
+ GLsizei n,
+ const GLenum *bufs);
+angle::CallCapture CaptureNamedFramebufferParameteri(const State &glState,
+ bool isCallValid,
+ FramebufferID framebufferPacked,
+ GLenum pname,
+ GLint param);
+angle::CallCapture CaptureNamedFramebufferReadBuffer(const State &glState,
+ bool isCallValid,
+ FramebufferID framebufferPacked,
+ GLenum src);
+angle::CallCapture CaptureNamedFramebufferRenderbuffer(const State &glState,
+ bool isCallValid,
+ FramebufferID framebufferPacked,
+ GLenum attachment,
+ GLenum renderbuffertarget,
+ RenderbufferID renderbufferPacked);
+angle::CallCapture CaptureNamedFramebufferTexture(const State &glState,
+ bool isCallValid,
+ FramebufferID framebufferPacked,
+ GLenum attachment,
+ TextureID texturePacked,
+ GLint level);
+angle::CallCapture CaptureNamedFramebufferTextureLayer(const State &glState,
+ bool isCallValid,
+ FramebufferID framebufferPacked,
+ GLenum attachment,
+ TextureID texturePacked,
+ GLint level,
+ GLint layer);
+angle::CallCapture CaptureNamedRenderbufferStorage(const State &glState,
+ bool isCallValid,
+ RenderbufferID renderbufferPacked,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height);
+angle::CallCapture CaptureNamedRenderbufferStorageMultisample(const State &glState,
+ bool isCallValid,
+ RenderbufferID renderbufferPacked,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height);
+angle::CallCapture CaptureTextureBarrier(const State &glState, bool isCallValid);
+angle::CallCapture CaptureTextureBuffer(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLenum internalformat,
+ BufferID bufferPacked);
+angle::CallCapture CaptureTextureBufferRange(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLenum internalformat,
+ BufferID bufferPacked,
+ GLintptr offset,
+ GLsizeiptr size);
+angle::CallCapture CaptureTextureParameterIiv(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLenum pname,
+ const GLint *params);
+angle::CallCapture CaptureTextureParameterIuiv(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLenum pname,
+ const GLuint *params);
+angle::CallCapture CaptureTextureParameterf(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLenum pname,
+ GLfloat param);
+angle::CallCapture CaptureTextureParameterfv(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLenum pname,
+ const GLfloat *param);
+angle::CallCapture CaptureTextureParameteri(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLenum pname,
+ GLint param);
+angle::CallCapture CaptureTextureParameteriv(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLenum pname,
+ const GLint *param);
+angle::CallCapture CaptureTextureStorage1D(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width);
+angle::CallCapture CaptureTextureStorage2D(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height);
+angle::CallCapture CaptureTextureStorage2DMultisample(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedsamplelocations);
+angle::CallCapture CaptureTextureStorage3D(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth);
+angle::CallCapture CaptureTextureStorage3DMultisample(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean fixedsamplelocations);
+angle::CallCapture CaptureTextureSubImage1D(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLint level,
+ GLint xoffset,
+ GLsizei width,
+ GLenum format,
+ GLenum type,
+ const void *pixels);
+angle::CallCapture CaptureTextureSubImage2D(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ const void *pixels);
+angle::CallCapture CaptureTextureSubImage3D(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ const void *pixels);
+angle::CallCapture CaptureTransformFeedbackBufferBase(const State &glState,
+ bool isCallValid,
+ GLuint xfb,
+ GLuint index,
+ BufferID bufferPacked);
+angle::CallCapture CaptureTransformFeedbackBufferRange(const State &glState,
+ bool isCallValid,
+ GLuint xfb,
+ GLuint index,
+ BufferID bufferPacked,
+ GLintptr offset,
+ GLsizeiptr size);
+angle::CallCapture CaptureUnmapNamedBuffer(const State &glState,
+ bool isCallValid,
+ BufferID bufferPacked,
+ GLboolean returnValue);
+angle::CallCapture CaptureVertexArrayAttribBinding(const State &glState,
+ bool isCallValid,
+ VertexArrayID vaobjPacked,
+ GLuint attribindex,
+ GLuint bindingindex);
+angle::CallCapture CaptureVertexArrayAttribFormat(const State &glState,
+ bool isCallValid,
+ VertexArrayID vaobjPacked,
+ GLuint attribindex,
+ GLint size,
+ GLenum type,
+ GLboolean normalized,
+ GLuint relativeoffset);
+angle::CallCapture CaptureVertexArrayAttribIFormat(const State &glState,
+ bool isCallValid,
+ VertexArrayID vaobjPacked,
+ GLuint attribindex,
+ GLint size,
+ GLenum type,
+ GLuint relativeoffset);
+angle::CallCapture CaptureVertexArrayAttribLFormat(const State &glState,
+ bool isCallValid,
+ VertexArrayID vaobjPacked,
+ GLuint attribindex,
+ GLint size,
+ GLenum type,
+ GLuint relativeoffset);
+angle::CallCapture CaptureVertexArrayBindingDivisor(const State &glState,
+ bool isCallValid,
+ VertexArrayID vaobjPacked,
+ GLuint bindingindex,
+ GLuint divisor);
+angle::CallCapture CaptureVertexArrayElementBuffer(const State &glState,
+ bool isCallValid,
+ VertexArrayID vaobjPacked,
+ BufferID bufferPacked);
+angle::CallCapture CaptureVertexArrayVertexBuffer(const State &glState,
+ bool isCallValid,
+ VertexArrayID vaobjPacked,
+ GLuint bindingindex,
+ BufferID bufferPacked,
+ GLintptr offset,
+ GLsizei stride);
+angle::CallCapture CaptureVertexArrayVertexBuffers(const State &glState,
+ bool isCallValid,
+ VertexArrayID vaobjPacked,
+ GLuint first,
+ GLsizei count,
+ const BufferID *buffersPacked,
+ const GLintptr *offsets,
+ const GLsizei *strides);
+
+// GL 4.6
+angle::CallCapture CaptureMultiDrawArraysIndirectCount(const State &glState,
+ bool isCallValid,
+ GLenum mode,
+ const void *indirect,
+ GLintptr drawcount,
+ GLsizei maxdrawcount,
+ GLsizei stride);
+angle::CallCapture CaptureMultiDrawElementsIndirectCount(const State &glState,
+ bool isCallValid,
+ GLenum mode,
+ GLenum type,
+ const void *indirect,
+ GLintptr drawcount,
+ GLsizei maxdrawcount,
+ GLsizei stride);
+angle::CallCapture CapturePolygonOffsetClamp(const State &glState,
+ bool isCallValid,
+ GLfloat factor,
+ GLfloat units,
+ GLfloat clamp);
+angle::CallCapture CaptureSpecializeShader(const State &glState,
+ bool isCallValid,
+ GLuint shader,
+ const GLchar *pEntryPoint,
+ GLuint numSpecializationConstants,
+ const GLuint *pConstantIndex,
+ const GLuint *pConstantValue);
+
+// Parameter Captures
+
+// GL 4.0
+void CaptureGetActiveSubroutineName_length(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum shadertype,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *name,
+ angle::ParamCapture *paramCapture);
+void CaptureGetActiveSubroutineName_name(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum shadertype,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *name,
+ angle::ParamCapture *paramCapture);
+void CaptureGetActiveSubroutineUniformName_length(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum shadertype,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *name,
+ angle::ParamCapture *paramCapture);
+void CaptureGetActiveSubroutineUniformName_name(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum shadertype,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *name,
+ angle::ParamCapture *paramCapture);
+void CaptureGetActiveSubroutineUniformiv_values(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum shadertype,
+ GLuint index,
+ GLenum pname,
+ GLint *values,
+ angle::ParamCapture *paramCapture);
+void CaptureGetProgramStageiv_values(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum shadertype,
+ GLenum pname,
+ GLint *values,
+ angle::ParamCapture *paramCapture);
+void CaptureGetQueryIndexediv_params(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLuint index,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetSubroutineIndex_name(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum shadertype,
+ const GLchar *name,
+ angle::ParamCapture *paramCapture);
+void CaptureGetSubroutineUniformLocation_name(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum shadertype,
+ const GLchar *name,
+ angle::ParamCapture *paramCapture);
+void CaptureGetUniformSubroutineuiv_params(const State &glState,
+ bool isCallValid,
+ GLenum shadertype,
+ GLint location,
+ GLuint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetUniformdv_params(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLdouble *params,
+ angle::ParamCapture *paramCapture);
+void CapturePatchParameterfv_values(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ const GLfloat *values,
+ angle::ParamCapture *paramCapture);
+void CaptureUniform1dv_value(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLdouble *value,
+ angle::ParamCapture *paramCapture);
+void CaptureUniform2dv_value(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLdouble *value,
+ angle::ParamCapture *paramCapture);
+void CaptureUniform3dv_value(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLdouble *value,
+ angle::ParamCapture *paramCapture);
+void CaptureUniform4dv_value(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLdouble *value,
+ angle::ParamCapture *paramCapture);
+void CaptureUniformMatrix2dv_value(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value,
+ angle::ParamCapture *paramCapture);
+void CaptureUniformMatrix2x3dv_value(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value,
+ angle::ParamCapture *paramCapture);
+void CaptureUniformMatrix2x4dv_value(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value,
+ angle::ParamCapture *paramCapture);
+void CaptureUniformMatrix3dv_value(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value,
+ angle::ParamCapture *paramCapture);
+void CaptureUniformMatrix3x2dv_value(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value,
+ angle::ParamCapture *paramCapture);
+void CaptureUniformMatrix3x4dv_value(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value,
+ angle::ParamCapture *paramCapture);
+void CaptureUniformMatrix4dv_value(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value,
+ angle::ParamCapture *paramCapture);
+void CaptureUniformMatrix4x2dv_value(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value,
+ angle::ParamCapture *paramCapture);
+void CaptureUniformMatrix4x3dv_value(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value,
+ angle::ParamCapture *paramCapture);
+void CaptureUniformSubroutinesuiv_indices(const State &glState,
+ bool isCallValid,
+ GLenum shadertype,
+ GLsizei count,
+ const GLuint *indices,
+ angle::ParamCapture *paramCapture);
+
+// GL 4.1
+void CaptureDepthRangeArrayv_v(const State &glState,
+ bool isCallValid,
+ GLuint first,
+ GLsizei count,
+ const GLdouble *v,
+ angle::ParamCapture *paramCapture);
+void CaptureGetDoublei_v_data(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLuint index,
+ GLdouble *data,
+ angle::ParamCapture *paramCapture);
+void CaptureGetFloati_v_data(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLuint index,
+ GLfloat *data,
+ angle::ParamCapture *paramCapture);
+void CaptureGetVertexAttribLdv_params(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLenum pname,
+ GLdouble *params,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniform1dv_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLdouble *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniform2dv_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLdouble *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniform3dv_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLdouble *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniform4dv_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLdouble *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniformMatrix2dv_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniformMatrix2x3dv_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniformMatrix2x4dv_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniformMatrix3dv_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniformMatrix3x2dv_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniformMatrix3x4dv_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniformMatrix4dv_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniformMatrix4x2dv_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniformMatrix4x3dv_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value,
+ angle::ParamCapture *paramCapture);
+void CaptureScissorArrayv_v(const State &glState,
+ bool isCallValid,
+ GLuint first,
+ GLsizei count,
+ const GLint *v,
+ angle::ParamCapture *paramCapture);
+void CaptureScissorIndexedv_v(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLint *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttribL1dv_v(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLdouble *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttribL2dv_v(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLdouble *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttribL3dv_v(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLdouble *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttribL4dv_v(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLdouble *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttribLPointer_pointer(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLint size,
+ GLenum type,
+ GLsizei stride,
+ const void *pointer,
+ angle::ParamCapture *paramCapture);
+void CaptureViewportArrayv_v(const State &glState,
+ bool isCallValid,
+ GLuint first,
+ GLsizei count,
+ const GLfloat *v,
+ angle::ParamCapture *paramCapture);
+void CaptureViewportIndexedfv_v(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLfloat *v,
+ angle::ParamCapture *paramCapture);
+
+// GL 4.2
+void CaptureDrawElementsInstancedBaseInstance_indices(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLsizei instancecount,
+ GLuint baseinstance,
+ angle::ParamCapture *paramCapture);
+void CaptureDrawElementsInstancedBaseVertexBaseInstance_indices(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLsizei instancecount,
+ GLint basevertex,
+ GLuint baseinstance,
+ angle::ParamCapture *paramCapture);
+void CaptureGetActiveAtomicCounterBufferiv_params(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLuint bufferIndex,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+
+// GL 4.3
+void CaptureClearBufferData_data(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum internalformat,
+ GLenum format,
+ GLenum type,
+ const void *data,
+ angle::ParamCapture *paramCapture);
+void CaptureClearBufferSubData_data(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum internalformat,
+ GLintptr offset,
+ GLsizeiptr size,
+ GLenum format,
+ GLenum type,
+ const void *data,
+ angle::ParamCapture *paramCapture);
+void CaptureGetInternalformati64v_params(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum internalformat,
+ GLenum pname,
+ GLsizei count,
+ GLint64 *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetProgramResourceLocationIndex_name(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum programInterface,
+ const GLchar *name,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiDrawArraysIndirect_indirect(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const void *indirect,
+ GLsizei drawcount,
+ GLsizei stride,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiDrawElementsIndirect_indirect(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ DrawElementsType typePacked,
+ const void *indirect,
+ GLsizei drawcount,
+ GLsizei stride,
+ angle::ParamCapture *paramCapture);
+
+// GL 4.4
+void CaptureBindBuffersBase_buffersPacked(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLuint first,
+ GLsizei count,
+ const BufferID *buffersPacked,
+ angle::ParamCapture *paramCapture);
+void CaptureBindBuffersRange_buffersPacked(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLuint first,
+ GLsizei count,
+ const BufferID *buffersPacked,
+ const GLintptr *offsets,
+ const GLsizeiptr *sizes,
+ angle::ParamCapture *paramCapture);
+void CaptureBindBuffersRange_offsets(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLuint first,
+ GLsizei count,
+ const BufferID *buffersPacked,
+ const GLintptr *offsets,
+ const GLsizeiptr *sizes,
+ angle::ParamCapture *paramCapture);
+void CaptureBindBuffersRange_sizes(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLuint first,
+ GLsizei count,
+ const BufferID *buffersPacked,
+ const GLintptr *offsets,
+ const GLsizeiptr *sizes,
+ angle::ParamCapture *paramCapture);
+void CaptureBindImageTextures_textures(const State &glState,
+ bool isCallValid,
+ GLuint first,
+ GLsizei count,
+ const GLuint *textures,
+ angle::ParamCapture *paramCapture);
+void CaptureBindSamplers_samplers(const State &glState,
+ bool isCallValid,
+ GLuint first,
+ GLsizei count,
+ const GLuint *samplers,
+ angle::ParamCapture *paramCapture);
+void CaptureBindTextures_textures(const State &glState,
+ bool isCallValid,
+ GLuint first,
+ GLsizei count,
+ const GLuint *textures,
+ angle::ParamCapture *paramCapture);
+void CaptureBindVertexBuffers_buffersPacked(const State &glState,
+ bool isCallValid,
+ GLuint first,
+ GLsizei count,
+ const BufferID *buffersPacked,
+ const GLintptr *offsets,
+ const GLsizei *strides,
+ angle::ParamCapture *paramCapture);
+void CaptureBindVertexBuffers_offsets(const State &glState,
+ bool isCallValid,
+ GLuint first,
+ GLsizei count,
+ const BufferID *buffersPacked,
+ const GLintptr *offsets,
+ const GLsizei *strides,
+ angle::ParamCapture *paramCapture);
+void CaptureBindVertexBuffers_strides(const State &glState,
+ bool isCallValid,
+ GLuint first,
+ GLsizei count,
+ const BufferID *buffersPacked,
+ const GLintptr *offsets,
+ const GLsizei *strides,
+ angle::ParamCapture *paramCapture);
+void CaptureBufferStorage_data(const State &glState,
+ bool isCallValid,
+ BufferBinding targetPacked,
+ GLsizeiptr size,
+ const void *data,
+ GLbitfield flags,
+ angle::ParamCapture *paramCapture);
+void CaptureClearTexImage_data(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLint level,
+ GLenum format,
+ GLenum type,
+ const void *data,
+ angle::ParamCapture *paramCapture);
+void CaptureClearTexSubImage_data(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ const void *data,
+ angle::ParamCapture *paramCapture);
+
+// GL 4.5
+void CaptureClearNamedBufferData_data(const State &glState,
+ bool isCallValid,
+ BufferID bufferPacked,
+ GLenum internalformat,
+ GLenum format,
+ GLenum type,
+ const void *data,
+ angle::ParamCapture *paramCapture);
+void CaptureClearNamedBufferSubData_data(const State &glState,
+ bool isCallValid,
+ BufferID bufferPacked,
+ GLenum internalformat,
+ GLintptr offset,
+ GLsizeiptr size,
+ GLenum format,
+ GLenum type,
+ const void *data,
+ angle::ParamCapture *paramCapture);
+void CaptureClearNamedFramebufferfv_value(const State &glState,
+ bool isCallValid,
+ FramebufferID framebufferPacked,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLfloat *value,
+ angle::ParamCapture *paramCapture);
+void CaptureClearNamedFramebufferiv_value(const State &glState,
+ bool isCallValid,
+ FramebufferID framebufferPacked,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLint *value,
+ angle::ParamCapture *paramCapture);
+void CaptureClearNamedFramebufferuiv_value(const State &glState,
+ bool isCallValid,
+ FramebufferID framebufferPacked,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLuint *value,
+ angle::ParamCapture *paramCapture);
+void CaptureCompressedTextureSubImage1D_data(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLint level,
+ GLint xoffset,
+ GLsizei width,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data,
+ angle::ParamCapture *paramCapture);
+void CaptureCompressedTextureSubImage2D_data(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data,
+ angle::ParamCapture *paramCapture);
+void CaptureCompressedTextureSubImage3D_data(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data,
+ angle::ParamCapture *paramCapture);
+void CaptureCreateBuffers_buffersPacked(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ BufferID *buffersPacked,
+ angle::ParamCapture *paramCapture);
+void CaptureCreateFramebuffers_framebuffers(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ GLuint *framebuffers,
+ angle::ParamCapture *paramCapture);
+void CaptureCreateProgramPipelines_pipelines(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ GLuint *pipelines,
+ angle::ParamCapture *paramCapture);
+void CaptureCreateQueries_ids(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLsizei n,
+ GLuint *ids,
+ angle::ParamCapture *paramCapture);
+void CaptureCreateRenderbuffers_renderbuffersPacked(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ RenderbufferID *renderbuffersPacked,
+ angle::ParamCapture *paramCapture);
+void CaptureCreateSamplers_samplers(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ GLuint *samplers,
+ angle::ParamCapture *paramCapture);
+void CaptureCreateTextures_textures(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLsizei n,
+ GLuint *textures,
+ angle::ParamCapture *paramCapture);
+void CaptureCreateTransformFeedbacks_ids(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ GLuint *ids,
+ angle::ParamCapture *paramCapture);
+void CaptureCreateVertexArrays_arraysPacked(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ VertexArrayID *arraysPacked,
+ angle::ParamCapture *paramCapture);
+void CaptureGetCompressedTextureImage_pixels(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLint level,
+ GLsizei bufSize,
+ void *pixels,
+ angle::ParamCapture *paramCapture);
+void CaptureGetCompressedTextureSubImage_pixels(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLsizei bufSize,
+ void *pixels,
+ angle::ParamCapture *paramCapture);
+void CaptureGetNamedBufferParameteri64v_params(const State &glState,
+ bool isCallValid,
+ BufferID bufferPacked,
+ GLenum pname,
+ GLint64 *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetNamedBufferParameteriv_params(const State &glState,
+ bool isCallValid,
+ BufferID bufferPacked,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetNamedBufferPointerv_params(const State &glState,
+ bool isCallValid,
+ BufferID bufferPacked,
+ GLenum pname,
+ void **params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetNamedBufferSubData_data(const State &glState,
+ bool isCallValid,
+ BufferID bufferPacked,
+ GLintptr offset,
+ GLsizeiptr size,
+ void *data,
+ angle::ParamCapture *paramCapture);
+void CaptureGetNamedFramebufferAttachmentParameteriv_params(const State &glState,
+ bool isCallValid,
+ FramebufferID framebufferPacked,
+ GLenum attachment,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetNamedFramebufferParameteriv_param(const State &glState,
+ bool isCallValid,
+ FramebufferID framebufferPacked,
+ GLenum pname,
+ GLint *param,
+ angle::ParamCapture *paramCapture);
+void CaptureGetNamedRenderbufferParameteriv_params(const State &glState,
+ bool isCallValid,
+ RenderbufferID renderbufferPacked,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTextureImage_pixels(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLint level,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ void *pixels,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTextureLevelParameterfv_params(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLint level,
+ GLenum pname,
+ GLfloat *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTextureLevelParameteriv_params(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLint level,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTextureParameterIiv_params(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTextureParameterIuiv_params(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLenum pname,
+ GLuint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTextureParameterfv_params(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLenum pname,
+ GLfloat *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTextureParameteriv_params(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTextureSubImage_pixels(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ void *pixels,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTransformFeedbacki64_v_param(const State &glState,
+ bool isCallValid,
+ GLuint xfb,
+ GLenum pname,
+ GLuint index,
+ GLint64 *param,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTransformFeedbacki_v_param(const State &glState,
+ bool isCallValid,
+ GLuint xfb,
+ GLenum pname,
+ GLuint index,
+ GLint *param,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTransformFeedbackiv_param(const State &glState,
+ bool isCallValid,
+ GLuint xfb,
+ GLenum pname,
+ GLint *param,
+ angle::ParamCapture *paramCapture);
+void CaptureGetVertexArrayIndexed64iv_param(const State &glState,
+ bool isCallValid,
+ VertexArrayID vaobjPacked,
+ GLuint index,
+ GLenum pname,
+ GLint64 *param,
+ angle::ParamCapture *paramCapture);
+void CaptureGetVertexArrayIndexediv_param(const State &glState,
+ bool isCallValid,
+ VertexArrayID vaobjPacked,
+ GLuint index,
+ GLenum pname,
+ GLint *param,
+ angle::ParamCapture *paramCapture);
+void CaptureGetVertexArrayiv_param(const State &glState,
+ bool isCallValid,
+ VertexArrayID vaobjPacked,
+ GLenum pname,
+ GLint *param,
+ angle::ParamCapture *paramCapture);
+void CaptureGetnColorTable_table(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ void *table,
+ angle::ParamCapture *paramCapture);
+void CaptureGetnCompressedTexImage_pixels(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLint lod,
+ GLsizei bufSize,
+ void *pixels,
+ angle::ParamCapture *paramCapture);
+void CaptureGetnConvolutionFilter_image(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ void *image,
+ angle::ParamCapture *paramCapture);
+void CaptureGetnHistogram_values(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLboolean reset,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ void *values,
+ angle::ParamCapture *paramCapture);
+void CaptureGetnMapdv_v(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum query,
+ GLsizei bufSize,
+ GLdouble *v,
+ angle::ParamCapture *paramCapture);
+void CaptureGetnMapfv_v(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum query,
+ GLsizei bufSize,
+ GLfloat *v,
+ angle::ParamCapture *paramCapture);
+void CaptureGetnMapiv_v(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum query,
+ GLsizei bufSize,
+ GLint *v,
+ angle::ParamCapture *paramCapture);
+void CaptureGetnMinmax_values(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLboolean reset,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ void *values,
+ angle::ParamCapture *paramCapture);
+void CaptureGetnPixelMapfv_values(const State &glState,
+ bool isCallValid,
+ GLenum map,
+ GLsizei bufSize,
+ GLfloat *values,
+ angle::ParamCapture *paramCapture);
+void CaptureGetnPixelMapuiv_values(const State &glState,
+ bool isCallValid,
+ GLenum map,
+ GLsizei bufSize,
+ GLuint *values,
+ angle::ParamCapture *paramCapture);
+void CaptureGetnPixelMapusv_values(const State &glState,
+ bool isCallValid,
+ GLenum map,
+ GLsizei bufSize,
+ GLushort *values,
+ angle::ParamCapture *paramCapture);
+void CaptureGetnPolygonStipple_pattern(const State &glState,
+ bool isCallValid,
+ GLsizei bufSize,
+ GLubyte *pattern,
+ angle::ParamCapture *paramCapture);
+void CaptureGetnSeparableFilter_row(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum format,
+ GLenum type,
+ GLsizei rowBufSize,
+ void *row,
+ GLsizei columnBufSize,
+ void *column,
+ void *span,
+ angle::ParamCapture *paramCapture);
+void CaptureGetnSeparableFilter_column(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum format,
+ GLenum type,
+ GLsizei rowBufSize,
+ void *row,
+ GLsizei columnBufSize,
+ void *column,
+ void *span,
+ angle::ParamCapture *paramCapture);
+void CaptureGetnSeparableFilter_span(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum format,
+ GLenum type,
+ GLsizei rowBufSize,
+ void *row,
+ GLsizei columnBufSize,
+ void *column,
+ void *span,
+ angle::ParamCapture *paramCapture);
+void CaptureGetnTexImage_pixels(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLint level,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ void *pixels,
+ angle::ParamCapture *paramCapture);
+void CaptureGetnUniformdv_params(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei bufSize,
+ GLdouble *params,
+ angle::ParamCapture *paramCapture);
+void CaptureInvalidateNamedFramebufferData_attachments(const State &glState,
+ bool isCallValid,
+ FramebufferID framebufferPacked,
+ GLsizei numAttachments,
+ const GLenum *attachments,
+ angle::ParamCapture *paramCapture);
+void CaptureInvalidateNamedFramebufferSubData_attachments(const State &glState,
+ bool isCallValid,
+ FramebufferID framebufferPacked,
+ GLsizei numAttachments,
+ const GLenum *attachments,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ angle::ParamCapture *paramCapture);
+void CaptureNamedBufferData_data(const State &glState,
+ bool isCallValid,
+ BufferID bufferPacked,
+ GLsizeiptr size,
+ const void *data,
+ GLenum usage,
+ angle::ParamCapture *paramCapture);
+void CaptureNamedBufferStorage_data(const State &glState,
+ bool isCallValid,
+ BufferID bufferPacked,
+ GLsizeiptr size,
+ const void *data,
+ GLbitfield flags,
+ angle::ParamCapture *paramCapture);
+void CaptureNamedBufferSubData_data(const State &glState,
+ bool isCallValid,
+ BufferID bufferPacked,
+ GLintptr offset,
+ GLsizeiptr size,
+ const void *data,
+ angle::ParamCapture *paramCapture);
+void CaptureNamedFramebufferDrawBuffers_bufs(const State &glState,
+ bool isCallValid,
+ FramebufferID framebufferPacked,
+ GLsizei n,
+ const GLenum *bufs,
+ angle::ParamCapture *paramCapture);
+void CaptureTextureParameterIiv_params(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLenum pname,
+ const GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureTextureParameterIuiv_params(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLenum pname,
+ const GLuint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureTextureParameterfv_param(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLenum pname,
+ const GLfloat *param,
+ angle::ParamCapture *paramCapture);
+void CaptureTextureParameteriv_param(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLenum pname,
+ const GLint *param,
+ angle::ParamCapture *paramCapture);
+void CaptureTextureSubImage1D_pixels(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLint level,
+ GLint xoffset,
+ GLsizei width,
+ GLenum format,
+ GLenum type,
+ const void *pixels,
+ angle::ParamCapture *paramCapture);
+void CaptureTextureSubImage2D_pixels(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ const void *pixels,
+ angle::ParamCapture *paramCapture);
+void CaptureTextureSubImage3D_pixels(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ const void *pixels,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexArrayVertexBuffers_buffersPacked(const State &glState,
+ bool isCallValid,
+ VertexArrayID vaobjPacked,
+ GLuint first,
+ GLsizei count,
+ const BufferID *buffersPacked,
+ const GLintptr *offsets,
+ const GLsizei *strides,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexArrayVertexBuffers_offsets(const State &glState,
+ bool isCallValid,
+ VertexArrayID vaobjPacked,
+ GLuint first,
+ GLsizei count,
+ const BufferID *buffersPacked,
+ const GLintptr *offsets,
+ const GLsizei *strides,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexArrayVertexBuffers_strides(const State &glState,
+ bool isCallValid,
+ VertexArrayID vaobjPacked,
+ GLuint first,
+ GLsizei count,
+ const BufferID *buffersPacked,
+ const GLintptr *offsets,
+ const GLsizei *strides,
+ angle::ParamCapture *paramCapture);
+
+// GL 4.6
+void CaptureMultiDrawArraysIndirectCount_indirect(const State &glState,
+ bool isCallValid,
+ GLenum mode,
+ const void *indirect,
+ GLintptr drawcount,
+ GLsizei maxdrawcount,
+ GLsizei stride,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiDrawElementsIndirectCount_indirect(const State &glState,
+ bool isCallValid,
+ GLenum mode,
+ GLenum type,
+ const void *indirect,
+ GLintptr drawcount,
+ GLsizei maxdrawcount,
+ GLsizei stride,
+ angle::ParamCapture *paramCapture);
+void CaptureSpecializeShader_pEntryPoint(const State &glState,
+ bool isCallValid,
+ GLuint shader,
+ const GLchar *pEntryPoint,
+ GLuint numSpecializationConstants,
+ const GLuint *pConstantIndex,
+ const GLuint *pConstantValue,
+ angle::ParamCapture *paramCapture);
+void CaptureSpecializeShader_pConstantIndex(const State &glState,
+ bool isCallValid,
+ GLuint shader,
+ const GLchar *pEntryPoint,
+ GLuint numSpecializationConstants,
+ const GLuint *pConstantIndex,
+ const GLuint *pConstantValue,
+ angle::ParamCapture *paramCapture);
+void CaptureSpecializeShader_pConstantValue(const State &glState,
+ bool isCallValid,
+ GLuint shader,
+ const GLchar *pEntryPoint,
+ GLuint numSpecializationConstants,
+ const GLuint *pConstantIndex,
+ const GLuint *pConstantValue,
+ angle::ParamCapture *paramCapture);
+} // namespace gl
+
+#endif // LIBANGLE_CAPTURE_GL_4_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libANGLE/capture/capture_gles_1_0_autogen.h b/gfx/angle/checkout/src/libANGLE/capture/capture_gles_1_0_autogen.h
new file mode 100644
index 0000000000..009ddb9977
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/capture/capture_gles_1_0_autogen.h
@@ -0,0 +1,582 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml and gl_angle_ext.xml.
+//
+// Copyright 2020 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.
+//
+// capture_gles_1_0_autogen.h:
+// Capture functions for the OpenGL ES 1.0 entry points.
+
+#ifndef LIBANGLE_CAPTURE_GLES_1_0_AUTOGEN_H_
+#define LIBANGLE_CAPTURE_GLES_1_0_AUTOGEN_H_
+
+#include "common/PackedEnums.h"
+#include "libANGLE/capture/FrameCapture.h"
+
+namespace gl
+{
+
+// Method Captures
+
+angle::CallCapture CaptureAlphaFunc(const State &glState,
+ bool isCallValid,
+ AlphaTestFunc funcPacked,
+ GLfloat ref);
+angle::CallCapture CaptureAlphaFuncx(const State &glState,
+ bool isCallValid,
+ AlphaTestFunc funcPacked,
+ GLfixed ref);
+angle::CallCapture CaptureClearColorx(const State &glState,
+ bool isCallValid,
+ GLfixed red,
+ GLfixed green,
+ GLfixed blue,
+ GLfixed alpha);
+angle::CallCapture CaptureClearDepthx(const State &glState, bool isCallValid, GLfixed depth);
+angle::CallCapture CaptureClientActiveTexture(const State &glState,
+ bool isCallValid,
+ GLenum texture);
+angle::CallCapture CaptureClipPlanef(const State &glState,
+ bool isCallValid,
+ GLenum p,
+ const GLfloat *eqn);
+angle::CallCapture CaptureClipPlanex(const State &glState,
+ bool isCallValid,
+ GLenum plane,
+ const GLfixed *equation);
+angle::CallCapture CaptureColor4f(const State &glState,
+ bool isCallValid,
+ GLfloat red,
+ GLfloat green,
+ GLfloat blue,
+ GLfloat alpha);
+angle::CallCapture CaptureColor4ub(const State &glState,
+ bool isCallValid,
+ GLubyte red,
+ GLubyte green,
+ GLubyte blue,
+ GLubyte alpha);
+angle::CallCapture CaptureColor4x(const State &glState,
+ bool isCallValid,
+ GLfixed red,
+ GLfixed green,
+ GLfixed blue,
+ GLfixed alpha);
+angle::CallCapture CaptureColorPointer(const State &glState,
+ bool isCallValid,
+ GLint size,
+ VertexAttribType typePacked,
+ GLsizei stride,
+ const void *pointer);
+angle::CallCapture CaptureDepthRangex(const State &glState, bool isCallValid, GLfixed n, GLfixed f);
+angle::CallCapture CaptureDisableClientState(const State &glState,
+ bool isCallValid,
+ ClientVertexArrayType arrayPacked);
+angle::CallCapture CaptureEnableClientState(const State &glState,
+ bool isCallValid,
+ ClientVertexArrayType arrayPacked);
+angle::CallCapture CaptureFogf(const State &glState, bool isCallValid, GLenum pname, GLfloat param);
+angle::CallCapture CaptureFogfv(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ const GLfloat *params);
+angle::CallCapture CaptureFogx(const State &glState, bool isCallValid, GLenum pname, GLfixed param);
+angle::CallCapture CaptureFogxv(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ const GLfixed *param);
+angle::CallCapture CaptureFrustumf(const State &glState,
+ bool isCallValid,
+ GLfloat l,
+ GLfloat r,
+ GLfloat b,
+ GLfloat t,
+ GLfloat n,
+ GLfloat f);
+angle::CallCapture CaptureFrustumx(const State &glState,
+ bool isCallValid,
+ GLfixed l,
+ GLfixed r,
+ GLfixed b,
+ GLfixed t,
+ GLfixed n,
+ GLfixed f);
+angle::CallCapture CaptureGetClipPlanef(const State &glState,
+ bool isCallValid,
+ GLenum plane,
+ GLfloat *equation);
+angle::CallCapture CaptureGetClipPlanex(const State &glState,
+ bool isCallValid,
+ GLenum plane,
+ GLfixed *equation);
+angle::CallCapture CaptureGetFixedv(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLfixed *params);
+angle::CallCapture CaptureGetLightfv(const State &glState,
+ bool isCallValid,
+ GLenum light,
+ LightParameter pnamePacked,
+ GLfloat *params);
+angle::CallCapture CaptureGetLightxv(const State &glState,
+ bool isCallValid,
+ GLenum light,
+ LightParameter pnamePacked,
+ GLfixed *params);
+angle::CallCapture CaptureGetMaterialfv(const State &glState,
+ bool isCallValid,
+ GLenum face,
+ MaterialParameter pnamePacked,
+ GLfloat *params);
+angle::CallCapture CaptureGetMaterialxv(const State &glState,
+ bool isCallValid,
+ GLenum face,
+ MaterialParameter pnamePacked,
+ GLfixed *params);
+angle::CallCapture CaptureGetTexEnvfv(const State &glState,
+ bool isCallValid,
+ TextureEnvTarget targetPacked,
+ TextureEnvParameter pnamePacked,
+ GLfloat *params);
+angle::CallCapture CaptureGetTexEnviv(const State &glState,
+ bool isCallValid,
+ TextureEnvTarget targetPacked,
+ TextureEnvParameter pnamePacked,
+ GLint *params);
+angle::CallCapture CaptureGetTexEnvxv(const State &glState,
+ bool isCallValid,
+ TextureEnvTarget targetPacked,
+ TextureEnvParameter pnamePacked,
+ GLfixed *params);
+angle::CallCapture CaptureGetTexParameterxv(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ GLfixed *params);
+angle::CallCapture CaptureLightModelf(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLfloat param);
+angle::CallCapture CaptureLightModelfv(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ const GLfloat *params);
+angle::CallCapture CaptureLightModelx(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLfixed param);
+angle::CallCapture CaptureLightModelxv(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ const GLfixed *param);
+angle::CallCapture CaptureLightf(const State &glState,
+ bool isCallValid,
+ GLenum light,
+ LightParameter pnamePacked,
+ GLfloat param);
+angle::CallCapture CaptureLightfv(const State &glState,
+ bool isCallValid,
+ GLenum light,
+ LightParameter pnamePacked,
+ const GLfloat *params);
+angle::CallCapture CaptureLightx(const State &glState,
+ bool isCallValid,
+ GLenum light,
+ LightParameter pnamePacked,
+ GLfixed param);
+angle::CallCapture CaptureLightxv(const State &glState,
+ bool isCallValid,
+ GLenum light,
+ LightParameter pnamePacked,
+ const GLfixed *params);
+angle::CallCapture CaptureLineWidthx(const State &glState, bool isCallValid, GLfixed width);
+angle::CallCapture CaptureLoadIdentity(const State &glState, bool isCallValid);
+angle::CallCapture CaptureLoadMatrixf(const State &glState, bool isCallValid, const GLfloat *m);
+angle::CallCapture CaptureLoadMatrixx(const State &glState, bool isCallValid, const GLfixed *m);
+angle::CallCapture CaptureLogicOp(const State &glState,
+ bool isCallValid,
+ LogicalOperation opcodePacked);
+angle::CallCapture CaptureMaterialf(const State &glState,
+ bool isCallValid,
+ GLenum face,
+ MaterialParameter pnamePacked,
+ GLfloat param);
+angle::CallCapture CaptureMaterialfv(const State &glState,
+ bool isCallValid,
+ GLenum face,
+ MaterialParameter pnamePacked,
+ const GLfloat *params);
+angle::CallCapture CaptureMaterialx(const State &glState,
+ bool isCallValid,
+ GLenum face,
+ MaterialParameter pnamePacked,
+ GLfixed param);
+angle::CallCapture CaptureMaterialxv(const State &glState,
+ bool isCallValid,
+ GLenum face,
+ MaterialParameter pnamePacked,
+ const GLfixed *param);
+angle::CallCapture CaptureMatrixMode(const State &glState, bool isCallValid, MatrixType modePacked);
+angle::CallCapture CaptureMultMatrixf(const State &glState, bool isCallValid, const GLfloat *m);
+angle::CallCapture CaptureMultMatrixx(const State &glState, bool isCallValid, const GLfixed *m);
+angle::CallCapture CaptureMultiTexCoord4f(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLfloat s,
+ GLfloat t,
+ GLfloat r,
+ GLfloat q);
+angle::CallCapture CaptureMultiTexCoord4x(const State &glState,
+ bool isCallValid,
+ GLenum texture,
+ GLfixed s,
+ GLfixed t,
+ GLfixed r,
+ GLfixed q);
+angle::CallCapture CaptureNormal3f(const State &glState,
+ bool isCallValid,
+ GLfloat nx,
+ GLfloat ny,
+ GLfloat nz);
+angle::CallCapture CaptureNormal3x(const State &glState,
+ bool isCallValid,
+ GLfixed nx,
+ GLfixed ny,
+ GLfixed nz);
+angle::CallCapture CaptureNormalPointer(const State &glState,
+ bool isCallValid,
+ VertexAttribType typePacked,
+ GLsizei stride,
+ const void *pointer);
+angle::CallCapture CaptureOrthof(const State &glState,
+ bool isCallValid,
+ GLfloat l,
+ GLfloat r,
+ GLfloat b,
+ GLfloat t,
+ GLfloat n,
+ GLfloat f);
+angle::CallCapture CaptureOrthox(const State &glState,
+ bool isCallValid,
+ GLfixed l,
+ GLfixed r,
+ GLfixed b,
+ GLfixed t,
+ GLfixed n,
+ GLfixed f);
+angle::CallCapture CapturePointParameterf(const State &glState,
+ bool isCallValid,
+ PointParameter pnamePacked,
+ GLfloat param);
+angle::CallCapture CapturePointParameterfv(const State &glState,
+ bool isCallValid,
+ PointParameter pnamePacked,
+ const GLfloat *params);
+angle::CallCapture CapturePointParameterx(const State &glState,
+ bool isCallValid,
+ PointParameter pnamePacked,
+ GLfixed param);
+angle::CallCapture CapturePointParameterxv(const State &glState,
+ bool isCallValid,
+ PointParameter pnamePacked,
+ const GLfixed *params);
+angle::CallCapture CapturePointSize(const State &glState, bool isCallValid, GLfloat size);
+angle::CallCapture CapturePointSizex(const State &glState, bool isCallValid, GLfixed size);
+angle::CallCapture CapturePolygonOffsetx(const State &glState,
+ bool isCallValid,
+ GLfixed factor,
+ GLfixed units);
+angle::CallCapture CapturePopMatrix(const State &glState, bool isCallValid);
+angle::CallCapture CapturePushMatrix(const State &glState, bool isCallValid);
+angle::CallCapture CaptureRotatef(const State &glState,
+ bool isCallValid,
+ GLfloat angle,
+ GLfloat x,
+ GLfloat y,
+ GLfloat z);
+angle::CallCapture CaptureRotatex(const State &glState,
+ bool isCallValid,
+ GLfixed angle,
+ GLfixed x,
+ GLfixed y,
+ GLfixed z);
+angle::CallCapture CaptureSampleCoveragex(const State &glState,
+ bool isCallValid,
+ GLclampx value,
+ GLboolean invert);
+angle::CallCapture CaptureScalef(const State &glState,
+ bool isCallValid,
+ GLfloat x,
+ GLfloat y,
+ GLfloat z);
+angle::CallCapture CaptureScalex(const State &glState,
+ bool isCallValid,
+ GLfixed x,
+ GLfixed y,
+ GLfixed z);
+angle::CallCapture CaptureShadeModel(const State &glState,
+ bool isCallValid,
+ ShadingModel modePacked);
+angle::CallCapture CaptureTexCoordPointer(const State &glState,
+ bool isCallValid,
+ GLint size,
+ VertexAttribType typePacked,
+ GLsizei stride,
+ const void *pointer);
+angle::CallCapture CaptureTexEnvf(const State &glState,
+ bool isCallValid,
+ TextureEnvTarget targetPacked,
+ TextureEnvParameter pnamePacked,
+ GLfloat param);
+angle::CallCapture CaptureTexEnvfv(const State &glState,
+ bool isCallValid,
+ TextureEnvTarget targetPacked,
+ TextureEnvParameter pnamePacked,
+ const GLfloat *params);
+angle::CallCapture CaptureTexEnvi(const State &glState,
+ bool isCallValid,
+ TextureEnvTarget targetPacked,
+ TextureEnvParameter pnamePacked,
+ GLint param);
+angle::CallCapture CaptureTexEnviv(const State &glState,
+ bool isCallValid,
+ TextureEnvTarget targetPacked,
+ TextureEnvParameter pnamePacked,
+ const GLint *params);
+angle::CallCapture CaptureTexEnvx(const State &glState,
+ bool isCallValid,
+ TextureEnvTarget targetPacked,
+ TextureEnvParameter pnamePacked,
+ GLfixed param);
+angle::CallCapture CaptureTexEnvxv(const State &glState,
+ bool isCallValid,
+ TextureEnvTarget targetPacked,
+ TextureEnvParameter pnamePacked,
+ const GLfixed *params);
+angle::CallCapture CaptureTexParameterx(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ GLfixed param);
+angle::CallCapture CaptureTexParameterxv(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLfixed *params);
+angle::CallCapture CaptureTranslatef(const State &glState,
+ bool isCallValid,
+ GLfloat x,
+ GLfloat y,
+ GLfloat z);
+angle::CallCapture CaptureTranslatex(const State &glState,
+ bool isCallValid,
+ GLfixed x,
+ GLfixed y,
+ GLfixed z);
+angle::CallCapture CaptureVertexPointer(const State &glState,
+ bool isCallValid,
+ GLint size,
+ VertexAttribType typePacked,
+ GLsizei stride,
+ const void *pointer);
+
+// Parameter Captures
+
+void CaptureClipPlanef_eqn(const State &glState,
+ bool isCallValid,
+ GLenum p,
+ const GLfloat *eqn,
+ angle::ParamCapture *paramCapture);
+void CaptureClipPlanex_equation(const State &glState,
+ bool isCallValid,
+ GLenum plane,
+ const GLfixed *equation,
+ angle::ParamCapture *paramCapture);
+void CaptureColorPointer_pointer(const State &glState,
+ bool isCallValid,
+ GLint size,
+ VertexAttribType typePacked,
+ GLsizei stride,
+ const void *pointer,
+ angle::ParamCapture *paramCapture);
+void CaptureFogfv_params(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ const GLfloat *params,
+ angle::ParamCapture *paramCapture);
+void CaptureFogxv_param(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ const GLfixed *param,
+ angle::ParamCapture *paramCapture);
+void CaptureGetClipPlanef_equation(const State &glState,
+ bool isCallValid,
+ GLenum plane,
+ GLfloat *equation,
+ angle::ParamCapture *paramCapture);
+void CaptureGetClipPlanex_equation(const State &glState,
+ bool isCallValid,
+ GLenum plane,
+ GLfixed *equation,
+ angle::ParamCapture *paramCapture);
+void CaptureGetFixedv_params(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLfixed *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetLightfv_params(const State &glState,
+ bool isCallValid,
+ GLenum light,
+ LightParameter pnamePacked,
+ GLfloat *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetLightxv_params(const State &glState,
+ bool isCallValid,
+ GLenum light,
+ LightParameter pnamePacked,
+ GLfixed *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetMaterialfv_params(const State &glState,
+ bool isCallValid,
+ GLenum face,
+ MaterialParameter pnamePacked,
+ GLfloat *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetMaterialxv_params(const State &glState,
+ bool isCallValid,
+ GLenum face,
+ MaterialParameter pnamePacked,
+ GLfixed *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTexEnvfv_params(const State &glState,
+ bool isCallValid,
+ TextureEnvTarget targetPacked,
+ TextureEnvParameter pnamePacked,
+ GLfloat *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTexEnviv_params(const State &glState,
+ bool isCallValid,
+ TextureEnvTarget targetPacked,
+ TextureEnvParameter pnamePacked,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTexEnvxv_params(const State &glState,
+ bool isCallValid,
+ TextureEnvTarget targetPacked,
+ TextureEnvParameter pnamePacked,
+ GLfixed *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTexParameterxv_params(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ GLfixed *params,
+ angle::ParamCapture *paramCapture);
+void CaptureLightModelfv_params(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ const GLfloat *params,
+ angle::ParamCapture *paramCapture);
+void CaptureLightModelxv_param(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ const GLfixed *param,
+ angle::ParamCapture *paramCapture);
+void CaptureLightfv_params(const State &glState,
+ bool isCallValid,
+ GLenum light,
+ LightParameter pnamePacked,
+ const GLfloat *params,
+ angle::ParamCapture *paramCapture);
+void CaptureLightxv_params(const State &glState,
+ bool isCallValid,
+ GLenum light,
+ LightParameter pnamePacked,
+ const GLfixed *params,
+ angle::ParamCapture *paramCapture);
+void CaptureLoadMatrixf_m(const State &glState,
+ bool isCallValid,
+ const GLfloat *m,
+ angle::ParamCapture *paramCapture);
+void CaptureLoadMatrixx_m(const State &glState,
+ bool isCallValid,
+ const GLfixed *m,
+ angle::ParamCapture *paramCapture);
+void CaptureMaterialfv_params(const State &glState,
+ bool isCallValid,
+ GLenum face,
+ MaterialParameter pnamePacked,
+ const GLfloat *params,
+ angle::ParamCapture *paramCapture);
+void CaptureMaterialxv_param(const State &glState,
+ bool isCallValid,
+ GLenum face,
+ MaterialParameter pnamePacked,
+ const GLfixed *param,
+ angle::ParamCapture *paramCapture);
+void CaptureMultMatrixf_m(const State &glState,
+ bool isCallValid,
+ const GLfloat *m,
+ angle::ParamCapture *paramCapture);
+void CaptureMultMatrixx_m(const State &glState,
+ bool isCallValid,
+ const GLfixed *m,
+ angle::ParamCapture *paramCapture);
+void CaptureNormalPointer_pointer(const State &glState,
+ bool isCallValid,
+ VertexAttribType typePacked,
+ GLsizei stride,
+ const void *pointer,
+ angle::ParamCapture *paramCapture);
+void CapturePointParameterfv_params(const State &glState,
+ bool isCallValid,
+ PointParameter pnamePacked,
+ const GLfloat *params,
+ angle::ParamCapture *paramCapture);
+void CapturePointParameterxv_params(const State &glState,
+ bool isCallValid,
+ PointParameter pnamePacked,
+ const GLfixed *params,
+ angle::ParamCapture *paramCapture);
+void CaptureTexCoordPointer_pointer(const State &glState,
+ bool isCallValid,
+ GLint size,
+ VertexAttribType typePacked,
+ GLsizei stride,
+ const void *pointer,
+ angle::ParamCapture *paramCapture);
+void CaptureTexEnvfv_params(const State &glState,
+ bool isCallValid,
+ TextureEnvTarget targetPacked,
+ TextureEnvParameter pnamePacked,
+ const GLfloat *params,
+ angle::ParamCapture *paramCapture);
+void CaptureTexEnviv_params(const State &glState,
+ bool isCallValid,
+ TextureEnvTarget targetPacked,
+ TextureEnvParameter pnamePacked,
+ const GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureTexEnvxv_params(const State &glState,
+ bool isCallValid,
+ TextureEnvTarget targetPacked,
+ TextureEnvParameter pnamePacked,
+ const GLfixed *params,
+ angle::ParamCapture *paramCapture);
+void CaptureTexParameterxv_params(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLfixed *params,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexPointer_pointer(const State &glState,
+ bool isCallValid,
+ GLint size,
+ VertexAttribType typePacked,
+ GLsizei stride,
+ const void *pointer,
+ angle::ParamCapture *paramCapture);
+} // namespace gl
+
+#endif // LIBANGLE_CAPTURE_GLES_1_0_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libANGLE/capture/capture_gles_2_0_autogen.h b/gfx/angle/checkout/src/libANGLE/capture/capture_gles_2_0_autogen.h
new file mode 100644
index 0000000000..d4d1d978a2
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/capture/capture_gles_2_0_autogen.h
@@ -0,0 +1,1195 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml and gl_angle_ext.xml.
+//
+// Copyright 2020 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.
+//
+// capture_gles_2_0_autogen.h:
+// Capture functions for the OpenGL ES 2.0 entry points.
+
+#ifndef LIBANGLE_CAPTURE_GLES_2_0_AUTOGEN_H_
+#define LIBANGLE_CAPTURE_GLES_2_0_AUTOGEN_H_
+
+#include "common/PackedEnums.h"
+#include "libANGLE/capture/FrameCapture.h"
+
+namespace gl
+{
+
+// Method Captures
+
+angle::CallCapture CaptureActiveTexture(const State &glState, bool isCallValid, GLenum texture);
+angle::CallCapture CaptureAttachShader(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ ShaderProgramID shaderPacked);
+angle::CallCapture CaptureBindAttribLocation(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLuint index,
+ const GLchar *name);
+angle::CallCapture CaptureBindBuffer(const State &glState,
+ bool isCallValid,
+ BufferBinding targetPacked,
+ BufferID bufferPacked);
+angle::CallCapture CaptureBindFramebuffer(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ FramebufferID framebufferPacked);
+angle::CallCapture CaptureBindRenderbuffer(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ RenderbufferID renderbufferPacked);
+angle::CallCapture CaptureBindTexture(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ TextureID texturePacked);
+angle::CallCapture CaptureBlendColor(const State &glState,
+ bool isCallValid,
+ GLfloat red,
+ GLfloat green,
+ GLfloat blue,
+ GLfloat alpha);
+angle::CallCapture CaptureBlendEquation(const State &glState, bool isCallValid, GLenum mode);
+angle::CallCapture CaptureBlendEquationSeparate(const State &glState,
+ bool isCallValid,
+ GLenum modeRGB,
+ GLenum modeAlpha);
+angle::CallCapture CaptureBlendFunc(const State &glState,
+ bool isCallValid,
+ GLenum sfactor,
+ GLenum dfactor);
+angle::CallCapture CaptureBlendFuncSeparate(const State &glState,
+ bool isCallValid,
+ GLenum sfactorRGB,
+ GLenum dfactorRGB,
+ GLenum sfactorAlpha,
+ GLenum dfactorAlpha);
+angle::CallCapture CaptureBufferData(const State &glState,
+ bool isCallValid,
+ BufferBinding targetPacked,
+ GLsizeiptr size,
+ const void *data,
+ BufferUsage usagePacked);
+angle::CallCapture CaptureBufferSubData(const State &glState,
+ bool isCallValid,
+ BufferBinding targetPacked,
+ GLintptr offset,
+ GLsizeiptr size,
+ const void *data);
+angle::CallCapture CaptureCheckFramebufferStatus(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum returnValue);
+angle::CallCapture CaptureClear(const State &glState, bool isCallValid, GLbitfield mask);
+angle::CallCapture CaptureClearColor(const State &glState,
+ bool isCallValid,
+ GLfloat red,
+ GLfloat green,
+ GLfloat blue,
+ GLfloat alpha);
+angle::CallCapture CaptureClearDepthf(const State &glState, bool isCallValid, GLfloat d);
+angle::CallCapture CaptureClearStencil(const State &glState, bool isCallValid, GLint s);
+angle::CallCapture CaptureColorMask(const State &glState,
+ bool isCallValid,
+ GLboolean red,
+ GLboolean green,
+ GLboolean blue,
+ GLboolean alpha);
+angle::CallCapture CaptureCompileShader(const State &glState,
+ bool isCallValid,
+ ShaderProgramID shaderPacked);
+angle::CallCapture CaptureCompressedTexImage2D(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLsizei imageSize,
+ const void *data);
+angle::CallCapture CaptureCompressedTexSubImage2D(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data);
+angle::CallCapture CaptureCopyTexImage2D(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum internalformat,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLint border);
+angle::CallCapture CaptureCopyTexSubImage2D(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height);
+angle::CallCapture CaptureCreateProgram(const State &glState, bool isCallValid, GLuint returnValue);
+angle::CallCapture CaptureCreateShader(const State &glState,
+ bool isCallValid,
+ ShaderType typePacked,
+ GLuint returnValue);
+angle::CallCapture CaptureCullFace(const State &glState, bool isCallValid, CullFaceMode modePacked);
+angle::CallCapture CaptureDeleteBuffers(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ const BufferID *buffersPacked);
+angle::CallCapture CaptureDeleteFramebuffers(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ const FramebufferID *framebuffersPacked);
+angle::CallCapture CaptureDeleteProgram(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked);
+angle::CallCapture CaptureDeleteRenderbuffers(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ const RenderbufferID *renderbuffersPacked);
+angle::CallCapture CaptureDeleteShader(const State &glState,
+ bool isCallValid,
+ ShaderProgramID shaderPacked);
+angle::CallCapture CaptureDeleteTextures(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ const TextureID *texturesPacked);
+angle::CallCapture CaptureDepthFunc(const State &glState, bool isCallValid, GLenum func);
+angle::CallCapture CaptureDepthMask(const State &glState, bool isCallValid, GLboolean flag);
+angle::CallCapture CaptureDepthRangef(const State &glState, bool isCallValid, GLfloat n, GLfloat f);
+angle::CallCapture CaptureDetachShader(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ ShaderProgramID shaderPacked);
+angle::CallCapture CaptureDisable(const State &glState, bool isCallValid, GLenum cap);
+angle::CallCapture CaptureDisableVertexAttribArray(const State &glState,
+ bool isCallValid,
+ GLuint index);
+angle::CallCapture CaptureDrawArrays(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLint first,
+ GLsizei count);
+angle::CallCapture CaptureDrawElements(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices);
+angle::CallCapture CaptureEnable(const State &glState, bool isCallValid, GLenum cap);
+angle::CallCapture CaptureEnableVertexAttribArray(const State &glState,
+ bool isCallValid,
+ GLuint index);
+angle::CallCapture CaptureFinish(const State &glState, bool isCallValid);
+angle::CallCapture CaptureFlush(const State &glState, bool isCallValid);
+angle::CallCapture CaptureFramebufferRenderbuffer(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum attachment,
+ GLenum renderbuffertarget,
+ RenderbufferID renderbufferPacked);
+angle::CallCapture CaptureFramebufferTexture2D(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum attachment,
+ TextureTarget textargetPacked,
+ TextureID texturePacked,
+ GLint level);
+angle::CallCapture CaptureFrontFace(const State &glState, bool isCallValid, GLenum mode);
+angle::CallCapture CaptureGenBuffers(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ BufferID *buffersPacked);
+angle::CallCapture CaptureGenFramebuffers(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ FramebufferID *framebuffersPacked);
+angle::CallCapture CaptureGenRenderbuffers(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ RenderbufferID *renderbuffersPacked);
+angle::CallCapture CaptureGenTextures(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ TextureID *texturesPacked);
+angle::CallCapture CaptureGenerateMipmap(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked);
+angle::CallCapture CaptureGetActiveAttrib(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *size,
+ GLenum *type,
+ GLchar *name);
+angle::CallCapture CaptureGetActiveUniform(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *size,
+ GLenum *type,
+ GLchar *name);
+angle::CallCapture CaptureGetAttachedShaders(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLsizei maxCount,
+ GLsizei *count,
+ ShaderProgramID *shadersPacked);
+angle::CallCapture CaptureGetAttribLocation(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ const GLchar *name,
+ GLint returnValue);
+angle::CallCapture CaptureGetBooleanv(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLboolean *data);
+angle::CallCapture CaptureGetBufferParameteriv(const State &glState,
+ bool isCallValid,
+ BufferBinding targetPacked,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureGetError(const State &glState, bool isCallValid, GLenum returnValue);
+angle::CallCapture CaptureGetFloatv(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLfloat *data);
+angle::CallCapture CaptureGetFramebufferAttachmentParameteriv(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum attachment,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureGetIntegerv(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLint *data);
+angle::CallCapture CaptureGetProgramInfoLog(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *infoLog);
+angle::CallCapture CaptureGetProgramiv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureGetRenderbufferParameteriv(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureGetShaderInfoLog(const State &glState,
+ bool isCallValid,
+ ShaderProgramID shaderPacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *infoLog);
+angle::CallCapture CaptureGetShaderPrecisionFormat(const State &glState,
+ bool isCallValid,
+ GLenum shadertype,
+ GLenum precisiontype,
+ GLint *range,
+ GLint *precision);
+angle::CallCapture CaptureGetShaderSource(const State &glState,
+ bool isCallValid,
+ ShaderProgramID shaderPacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *source);
+angle::CallCapture CaptureGetShaderiv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID shaderPacked,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureGetString(const State &glState,
+ bool isCallValid,
+ GLenum name,
+ const GLubyte *returnValue);
+angle::CallCapture CaptureGetTexParameterfv(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ GLfloat *params);
+angle::CallCapture CaptureGetTexParameteriv(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureGetUniformLocation(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ const GLchar *name,
+ GLint returnValue);
+angle::CallCapture CaptureGetUniformfv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLfloat *params);
+angle::CallCapture CaptureGetUniformiv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLint *params);
+angle::CallCapture CaptureGetVertexAttribPointerv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLenum pname,
+ void **pointer);
+angle::CallCapture CaptureGetVertexAttribfv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLenum pname,
+ GLfloat *params);
+angle::CallCapture CaptureGetVertexAttribiv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureHint(const State &glState, bool isCallValid, GLenum target, GLenum mode);
+angle::CallCapture CaptureIsBuffer(const State &glState,
+ bool isCallValid,
+ BufferID bufferPacked,
+ GLboolean returnValue);
+angle::CallCapture CaptureIsEnabled(const State &glState,
+ bool isCallValid,
+ GLenum cap,
+ GLboolean returnValue);
+angle::CallCapture CaptureIsFramebuffer(const State &glState,
+ bool isCallValid,
+ FramebufferID framebufferPacked,
+ GLboolean returnValue);
+angle::CallCapture CaptureIsProgram(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLboolean returnValue);
+angle::CallCapture CaptureIsRenderbuffer(const State &glState,
+ bool isCallValid,
+ RenderbufferID renderbufferPacked,
+ GLboolean returnValue);
+angle::CallCapture CaptureIsShader(const State &glState,
+ bool isCallValid,
+ ShaderProgramID shaderPacked,
+ GLboolean returnValue);
+angle::CallCapture CaptureIsTexture(const State &glState,
+ bool isCallValid,
+ TextureID texturePacked,
+ GLboolean returnValue);
+angle::CallCapture CaptureLineWidth(const State &glState, bool isCallValid, GLfloat width);
+angle::CallCapture CaptureLinkProgram(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked);
+angle::CallCapture CapturePixelStorei(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLint param);
+angle::CallCapture CapturePolygonOffset(const State &glState,
+ bool isCallValid,
+ GLfloat factor,
+ GLfloat units);
+angle::CallCapture CaptureReadPixels(const State &glState,
+ bool isCallValid,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ void *pixels);
+angle::CallCapture CaptureReleaseShaderCompiler(const State &glState, bool isCallValid);
+angle::CallCapture CaptureRenderbufferStorage(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height);
+angle::CallCapture CaptureSampleCoverage(const State &glState,
+ bool isCallValid,
+ GLfloat value,
+ GLboolean invert);
+angle::CallCapture CaptureScissor(const State &glState,
+ bool isCallValid,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height);
+angle::CallCapture CaptureShaderBinary(const State &glState,
+ bool isCallValid,
+ GLsizei count,
+ const ShaderProgramID *shadersPacked,
+ GLenum binaryFormat,
+ const void *binary,
+ GLsizei length);
+angle::CallCapture CaptureShaderSource(const State &glState,
+ bool isCallValid,
+ ShaderProgramID shaderPacked,
+ GLsizei count,
+ const GLchar *const *string,
+ const GLint *length);
+angle::CallCapture CaptureStencilFunc(const State &glState,
+ bool isCallValid,
+ GLenum func,
+ GLint ref,
+ GLuint mask);
+angle::CallCapture CaptureStencilFuncSeparate(const State &glState,
+ bool isCallValid,
+ GLenum face,
+ GLenum func,
+ GLint ref,
+ GLuint mask);
+angle::CallCapture CaptureStencilMask(const State &glState, bool isCallValid, GLuint mask);
+angle::CallCapture CaptureStencilMaskSeparate(const State &glState,
+ bool isCallValid,
+ GLenum face,
+ GLuint mask);
+angle::CallCapture CaptureStencilOp(const State &glState,
+ bool isCallValid,
+ GLenum fail,
+ GLenum zfail,
+ GLenum zpass);
+angle::CallCapture CaptureStencilOpSeparate(const State &glState,
+ bool isCallValid,
+ GLenum face,
+ GLenum sfail,
+ GLenum dpfail,
+ GLenum dppass);
+angle::CallCapture CaptureTexImage2D(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const void *pixels);
+angle::CallCapture CaptureTexParameterf(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ GLfloat param);
+angle::CallCapture CaptureTexParameterfv(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLfloat *params);
+angle::CallCapture CaptureTexParameteri(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ GLint param);
+angle::CallCapture CaptureTexParameteriv(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLint *params);
+angle::CallCapture CaptureTexSubImage2D(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ const void *pixels);
+angle::CallCapture CaptureUniform1f(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLfloat v0);
+angle::CallCapture CaptureUniform1fv(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value);
+angle::CallCapture CaptureUniform1i(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLint v0);
+angle::CallCapture CaptureUniform1iv(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value);
+angle::CallCapture CaptureUniform2f(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLfloat v0,
+ GLfloat v1);
+angle::CallCapture CaptureUniform2fv(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value);
+angle::CallCapture CaptureUniform2i(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLint v0,
+ GLint v1);
+angle::CallCapture CaptureUniform2iv(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value);
+angle::CallCapture CaptureUniform3f(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLfloat v0,
+ GLfloat v1,
+ GLfloat v2);
+angle::CallCapture CaptureUniform3fv(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value);
+angle::CallCapture CaptureUniform3i(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLint v0,
+ GLint v1,
+ GLint v2);
+angle::CallCapture CaptureUniform3iv(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value);
+angle::CallCapture CaptureUniform4f(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLfloat v0,
+ GLfloat v1,
+ GLfloat v2,
+ GLfloat v3);
+angle::CallCapture CaptureUniform4fv(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value);
+angle::CallCapture CaptureUniform4i(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLint v0,
+ GLint v1,
+ GLint v2,
+ GLint v3);
+angle::CallCapture CaptureUniform4iv(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value);
+angle::CallCapture CaptureUniformMatrix2fv(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+angle::CallCapture CaptureUniformMatrix3fv(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+angle::CallCapture CaptureUniformMatrix4fv(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+angle::CallCapture CaptureUseProgram(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked);
+angle::CallCapture CaptureValidateProgram(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked);
+angle::CallCapture CaptureVertexAttrib1f(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLfloat x);
+angle::CallCapture CaptureVertexAttrib1fv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLfloat *v);
+angle::CallCapture CaptureVertexAttrib2f(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLfloat x,
+ GLfloat y);
+angle::CallCapture CaptureVertexAttrib2fv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLfloat *v);
+angle::CallCapture CaptureVertexAttrib3f(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLfloat x,
+ GLfloat y,
+ GLfloat z);
+angle::CallCapture CaptureVertexAttrib3fv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLfloat *v);
+angle::CallCapture CaptureVertexAttrib4f(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLfloat x,
+ GLfloat y,
+ GLfloat z,
+ GLfloat w);
+angle::CallCapture CaptureVertexAttrib4fv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLfloat *v);
+angle::CallCapture CaptureVertexAttribPointer(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLint size,
+ VertexAttribType typePacked,
+ GLboolean normalized,
+ GLsizei stride,
+ const void *pointer);
+angle::CallCapture CaptureViewport(const State &glState,
+ bool isCallValid,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height);
+
+// Parameter Captures
+
+void CaptureBindAttribLocation_name(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLuint index,
+ const GLchar *name,
+ angle::ParamCapture *paramCapture);
+void CaptureBufferData_data(const State &glState,
+ bool isCallValid,
+ BufferBinding targetPacked,
+ GLsizeiptr size,
+ const void *data,
+ BufferUsage usagePacked,
+ angle::ParamCapture *paramCapture);
+void CaptureBufferSubData_data(const State &glState,
+ bool isCallValid,
+ BufferBinding targetPacked,
+ GLintptr offset,
+ GLsizeiptr size,
+ const void *data,
+ angle::ParamCapture *paramCapture);
+void CaptureCompressedTexImage2D_data(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLsizei imageSize,
+ const void *data,
+ angle::ParamCapture *paramCapture);
+void CaptureCompressedTexSubImage2D_data(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data,
+ angle::ParamCapture *paramCapture);
+void CaptureDeleteBuffers_buffersPacked(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ const BufferID *buffersPacked,
+ angle::ParamCapture *paramCapture);
+void CaptureDeleteFramebuffers_framebuffersPacked(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ const FramebufferID *framebuffersPacked,
+ angle::ParamCapture *paramCapture);
+void CaptureDeleteRenderbuffers_renderbuffersPacked(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ const RenderbufferID *renderbuffersPacked,
+ angle::ParamCapture *paramCapture);
+void CaptureDeleteTextures_texturesPacked(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ const TextureID *texturesPacked,
+ angle::ParamCapture *paramCapture);
+void CaptureDrawElements_indices(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ angle::ParamCapture *paramCapture);
+void CaptureGenBuffers_buffersPacked(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ BufferID *buffersPacked,
+ angle::ParamCapture *paramCapture);
+void CaptureGenFramebuffers_framebuffersPacked(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ FramebufferID *framebuffersPacked,
+ angle::ParamCapture *paramCapture);
+void CaptureGenRenderbuffers_renderbuffersPacked(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ RenderbufferID *renderbuffersPacked,
+ angle::ParamCapture *paramCapture);
+void CaptureGenTextures_texturesPacked(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ TextureID *texturesPacked,
+ angle::ParamCapture *paramCapture);
+void CaptureGetActiveAttrib_length(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *size,
+ GLenum *type,
+ GLchar *name,
+ angle::ParamCapture *paramCapture);
+void CaptureGetActiveAttrib_size(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *size,
+ GLenum *type,
+ GLchar *name,
+ angle::ParamCapture *paramCapture);
+void CaptureGetActiveAttrib_type(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *size,
+ GLenum *type,
+ GLchar *name,
+ angle::ParamCapture *paramCapture);
+void CaptureGetActiveAttrib_name(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *size,
+ GLenum *type,
+ GLchar *name,
+ angle::ParamCapture *paramCapture);
+void CaptureGetActiveUniform_length(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *size,
+ GLenum *type,
+ GLchar *name,
+ angle::ParamCapture *paramCapture);
+void CaptureGetActiveUniform_size(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *size,
+ GLenum *type,
+ GLchar *name,
+ angle::ParamCapture *paramCapture);
+void CaptureGetActiveUniform_type(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *size,
+ GLenum *type,
+ GLchar *name,
+ angle::ParamCapture *paramCapture);
+void CaptureGetActiveUniform_name(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *size,
+ GLenum *type,
+ GLchar *name,
+ angle::ParamCapture *paramCapture);
+void CaptureGetAttachedShaders_count(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLsizei maxCount,
+ GLsizei *count,
+ ShaderProgramID *shadersPacked,
+ angle::ParamCapture *paramCapture);
+void CaptureGetAttachedShaders_shadersPacked(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLsizei maxCount,
+ GLsizei *count,
+ ShaderProgramID *shadersPacked,
+ angle::ParamCapture *paramCapture);
+void CaptureGetAttribLocation_name(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ const GLchar *name,
+ angle::ParamCapture *paramCapture);
+void CaptureGetBooleanv_data(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLboolean *data,
+ angle::ParamCapture *paramCapture);
+void CaptureGetBufferParameteriv_params(const State &glState,
+ bool isCallValid,
+ BufferBinding targetPacked,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetFloatv_data(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLfloat *data,
+ angle::ParamCapture *paramCapture);
+void CaptureGetFramebufferAttachmentParameteriv_params(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum attachment,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetIntegerv_data(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLint *data,
+ angle::ParamCapture *paramCapture);
+void CaptureGetProgramInfoLog_length(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *infoLog,
+ angle::ParamCapture *paramCapture);
+void CaptureGetProgramInfoLog_infoLog(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *infoLog,
+ angle::ParamCapture *paramCapture);
+void CaptureGetProgramiv_params(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetRenderbufferParameteriv_params(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetShaderInfoLog_length(const State &glState,
+ bool isCallValid,
+ ShaderProgramID shaderPacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *infoLog,
+ angle::ParamCapture *paramCapture);
+void CaptureGetShaderInfoLog_infoLog(const State &glState,
+ bool isCallValid,
+ ShaderProgramID shaderPacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *infoLog,
+ angle::ParamCapture *paramCapture);
+void CaptureGetShaderPrecisionFormat_range(const State &glState,
+ bool isCallValid,
+ GLenum shadertype,
+ GLenum precisiontype,
+ GLint *range,
+ GLint *precision,
+ angle::ParamCapture *paramCapture);
+void CaptureGetShaderPrecisionFormat_precision(const State &glState,
+ bool isCallValid,
+ GLenum shadertype,
+ GLenum precisiontype,
+ GLint *range,
+ GLint *precision,
+ angle::ParamCapture *paramCapture);
+void CaptureGetShaderSource_length(const State &glState,
+ bool isCallValid,
+ ShaderProgramID shaderPacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *source,
+ angle::ParamCapture *paramCapture);
+void CaptureGetShaderSource_source(const State &glState,
+ bool isCallValid,
+ ShaderProgramID shaderPacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *source,
+ angle::ParamCapture *paramCapture);
+void CaptureGetShaderiv_params(const State &glState,
+ bool isCallValid,
+ ShaderProgramID shaderPacked,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTexParameterfv_params(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ GLfloat *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTexParameteriv_params(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetUniformLocation_name(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ const GLchar *name,
+ angle::ParamCapture *paramCapture);
+void CaptureGetUniformfv_params(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLfloat *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetUniformiv_params(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetVertexAttribPointerv_pointer(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLenum pname,
+ void **pointer,
+ angle::ParamCapture *paramCapture);
+void CaptureGetVertexAttribfv_params(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLenum pname,
+ GLfloat *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetVertexAttribiv_params(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureReadPixels_pixels(const State &glState,
+ bool isCallValid,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ void *pixels,
+ angle::ParamCapture *paramCapture);
+void CaptureShaderBinary_shadersPacked(const State &glState,
+ bool isCallValid,
+ GLsizei count,
+ const ShaderProgramID *shadersPacked,
+ GLenum binaryFormat,
+ const void *binary,
+ GLsizei length,
+ angle::ParamCapture *paramCapture);
+void CaptureShaderBinary_binary(const State &glState,
+ bool isCallValid,
+ GLsizei count,
+ const ShaderProgramID *shadersPacked,
+ GLenum binaryFormat,
+ const void *binary,
+ GLsizei length,
+ angle::ParamCapture *paramCapture);
+void CaptureShaderSource_string(const State &glState,
+ bool isCallValid,
+ ShaderProgramID shaderPacked,
+ GLsizei count,
+ const GLchar *const *string,
+ const GLint *length,
+ angle::ParamCapture *paramCapture);
+void CaptureShaderSource_length(const State &glState,
+ bool isCallValid,
+ ShaderProgramID shaderPacked,
+ GLsizei count,
+ const GLchar *const *string,
+ const GLint *length,
+ angle::ParamCapture *paramCapture);
+void CaptureTexImage2D_pixels(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const void *pixels,
+ angle::ParamCapture *paramCapture);
+void CaptureTexParameterfv_params(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLfloat *params,
+ angle::ParamCapture *paramCapture);
+void CaptureTexParameteriv_params(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureTexSubImage2D_pixels(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ const void *pixels,
+ angle::ParamCapture *paramCapture);
+void CaptureUniform1fv_value(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value,
+ angle::ParamCapture *paramCapture);
+void CaptureUniform1iv_value(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value,
+ angle::ParamCapture *paramCapture);
+void CaptureUniform2fv_value(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value,
+ angle::ParamCapture *paramCapture);
+void CaptureUniform2iv_value(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value,
+ angle::ParamCapture *paramCapture);
+void CaptureUniform3fv_value(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value,
+ angle::ParamCapture *paramCapture);
+void CaptureUniform3iv_value(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value,
+ angle::ParamCapture *paramCapture);
+void CaptureUniform4fv_value(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value,
+ angle::ParamCapture *paramCapture);
+void CaptureUniform4iv_value(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value,
+ angle::ParamCapture *paramCapture);
+void CaptureUniformMatrix2fv_value(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value,
+ angle::ParamCapture *paramCapture);
+void CaptureUniformMatrix3fv_value(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value,
+ angle::ParamCapture *paramCapture);
+void CaptureUniformMatrix4fv_value(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttrib1fv_v(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLfloat *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttrib2fv_v(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLfloat *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttrib3fv_v(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLfloat *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttrib4fv_v(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLfloat *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttribPointer_pointer(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLint size,
+ VertexAttribType typePacked,
+ GLboolean normalized,
+ GLsizei stride,
+ const void *pointer,
+ angle::ParamCapture *paramCapture);
+} // namespace gl
+
+#endif // LIBANGLE_CAPTURE_GLES_2_0_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libANGLE/capture/capture_gles_3_0_autogen.h b/gfx/angle/checkout/src/libANGLE/capture/capture_gles_3_0_autogen.h
new file mode 100644
index 0000000000..83e2f441b4
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/capture/capture_gles_3_0_autogen.h
@@ -0,0 +1,1079 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml and gl_angle_ext.xml.
+//
+// Copyright 2020 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.
+//
+// capture_gles_3_0_autogen.h:
+// Capture functions for the OpenGL ES 3.0 entry points.
+
+#ifndef LIBANGLE_CAPTURE_GLES_3_0_AUTOGEN_H_
+#define LIBANGLE_CAPTURE_GLES_3_0_AUTOGEN_H_
+
+#include "common/PackedEnums.h"
+#include "libANGLE/capture/FrameCapture.h"
+
+namespace gl
+{
+
+// Method Captures
+
+angle::CallCapture CaptureBeginQuery(const State &glState,
+ bool isCallValid,
+ QueryType targetPacked,
+ QueryID idPacked);
+angle::CallCapture CaptureBeginTransformFeedback(const State &glState,
+ bool isCallValid,
+ PrimitiveMode primitiveModePacked);
+angle::CallCapture CaptureBindBufferBase(const State &glState,
+ bool isCallValid,
+ BufferBinding targetPacked,
+ GLuint index,
+ BufferID bufferPacked);
+angle::CallCapture CaptureBindBufferRange(const State &glState,
+ bool isCallValid,
+ BufferBinding targetPacked,
+ GLuint index,
+ BufferID bufferPacked,
+ GLintptr offset,
+ GLsizeiptr size);
+angle::CallCapture CaptureBindSampler(const State &glState,
+ bool isCallValid,
+ GLuint unit,
+ SamplerID samplerPacked);
+angle::CallCapture CaptureBindTransformFeedback(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ TransformFeedbackID idPacked);
+angle::CallCapture CaptureBindVertexArray(const State &glState,
+ bool isCallValid,
+ VertexArrayID arrayPacked);
+angle::CallCapture CaptureBlitFramebuffer(const State &glState,
+ bool isCallValid,
+ GLint srcX0,
+ GLint srcY0,
+ GLint srcX1,
+ GLint srcY1,
+ GLint dstX0,
+ GLint dstY0,
+ GLint dstX1,
+ GLint dstY1,
+ GLbitfield mask,
+ GLenum filter);
+angle::CallCapture CaptureClearBufferfi(const State &glState,
+ bool isCallValid,
+ GLenum buffer,
+ GLint drawbuffer,
+ GLfloat depth,
+ GLint stencil);
+angle::CallCapture CaptureClearBufferfv(const State &glState,
+ bool isCallValid,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLfloat *value);
+angle::CallCapture CaptureClearBufferiv(const State &glState,
+ bool isCallValid,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLint *value);
+angle::CallCapture CaptureClearBufferuiv(const State &glState,
+ bool isCallValid,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLuint *value);
+angle::CallCapture CaptureClientWaitSync(const State &glState,
+ bool isCallValid,
+ GLsync sync,
+ GLbitfield flags,
+ GLuint64 timeout,
+ GLenum returnValue);
+angle::CallCapture CaptureCompressedTexImage3D(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLsizei imageSize,
+ const void *data);
+angle::CallCapture CaptureCompressedTexSubImage3D(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data);
+angle::CallCapture CaptureCopyBufferSubData(const State &glState,
+ bool isCallValid,
+ BufferBinding readTargetPacked,
+ BufferBinding writeTargetPacked,
+ GLintptr readOffset,
+ GLintptr writeOffset,
+ GLsizeiptr size);
+angle::CallCapture CaptureCopyTexSubImage3D(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height);
+angle::CallCapture CaptureDeleteQueries(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ const QueryID *idsPacked);
+angle::CallCapture CaptureDeleteSamplers(const State &glState,
+ bool isCallValid,
+ GLsizei count,
+ const SamplerID *samplersPacked);
+angle::CallCapture CaptureDeleteSync(const State &glState, bool isCallValid, GLsync sync);
+angle::CallCapture CaptureDeleteTransformFeedbacks(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ const TransformFeedbackID *idsPacked);
+angle::CallCapture CaptureDeleteVertexArrays(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ const VertexArrayID *arraysPacked);
+angle::CallCapture CaptureDrawArraysInstanced(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLint first,
+ GLsizei count,
+ GLsizei instancecount);
+angle::CallCapture CaptureDrawBuffers(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ const GLenum *bufs);
+angle::CallCapture CaptureDrawElementsInstanced(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLsizei instancecount);
+angle::CallCapture CaptureDrawRangeElements(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices);
+angle::CallCapture CaptureEndQuery(const State &glState, bool isCallValid, QueryType targetPacked);
+angle::CallCapture CaptureEndTransformFeedback(const State &glState, bool isCallValid);
+angle::CallCapture CaptureFenceSync(const State &glState,
+ bool isCallValid,
+ GLenum condition,
+ GLbitfield flags,
+ GLsync returnValue);
+angle::CallCapture CaptureFlushMappedBufferRange(const State &glState,
+ bool isCallValid,
+ BufferBinding targetPacked,
+ GLintptr offset,
+ GLsizeiptr length);
+angle::CallCapture CaptureFramebufferTextureLayer(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum attachment,
+ TextureID texturePacked,
+ GLint level,
+ GLint layer);
+angle::CallCapture CaptureGenQueries(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ QueryID *idsPacked);
+angle::CallCapture CaptureGenSamplers(const State &glState,
+ bool isCallValid,
+ GLsizei count,
+ SamplerID *samplersPacked);
+angle::CallCapture CaptureGenTransformFeedbacks(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ TransformFeedbackID *idsPacked);
+angle::CallCapture CaptureGenVertexArrays(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ VertexArrayID *arraysPacked);
+angle::CallCapture CaptureGetActiveUniformBlockName(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformBlockIndex uniformBlockIndexPacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *uniformBlockName);
+angle::CallCapture CaptureGetActiveUniformBlockiv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformBlockIndex uniformBlockIndexPacked,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureGetActiveUniformsiv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLsizei uniformCount,
+ const GLuint *uniformIndices,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureGetBufferParameteri64v(const State &glState,
+ bool isCallValid,
+ BufferBinding targetPacked,
+ GLenum pname,
+ GLint64 *params);
+angle::CallCapture CaptureGetBufferPointerv(const State &glState,
+ bool isCallValid,
+ BufferBinding targetPacked,
+ GLenum pname,
+ void **params);
+angle::CallCapture CaptureGetFragDataLocation(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ const GLchar *name,
+ GLint returnValue);
+angle::CallCapture CaptureGetInteger64i_v(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLuint index,
+ GLint64 *data);
+angle::CallCapture CaptureGetInteger64v(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLint64 *data);
+angle::CallCapture CaptureGetIntegeri_v(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLuint index,
+ GLint *data);
+angle::CallCapture CaptureGetInternalformativ(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum internalformat,
+ GLenum pname,
+ GLsizei count,
+ GLint *params);
+angle::CallCapture CaptureGetProgramBinary(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLenum *binaryFormat,
+ void *binary);
+angle::CallCapture CaptureGetQueryObjectuiv(const State &glState,
+ bool isCallValid,
+ QueryID idPacked,
+ GLenum pname,
+ GLuint *params);
+angle::CallCapture CaptureGetQueryiv(const State &glState,
+ bool isCallValid,
+ QueryType targetPacked,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureGetSamplerParameterfv(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLfloat *params);
+angle::CallCapture CaptureGetSamplerParameteriv(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureGetStringi(const State &glState,
+ bool isCallValid,
+ GLenum name,
+ GLuint index,
+ const GLubyte *returnValue);
+angle::CallCapture CaptureGetSynciv(const State &glState,
+ bool isCallValid,
+ GLsync sync,
+ GLenum pname,
+ GLsizei count,
+ GLsizei *length,
+ GLint *values);
+angle::CallCapture CaptureGetTransformFeedbackVarying(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLsizei *size,
+ GLenum *type,
+ GLchar *name);
+angle::CallCapture CaptureGetUniformBlockIndex(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ const GLchar *uniformBlockName,
+ GLuint returnValue);
+angle::CallCapture CaptureGetUniformIndices(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLsizei uniformCount,
+ const GLchar *const *uniformNames,
+ GLuint *uniformIndices);
+angle::CallCapture CaptureGetUniformuiv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLuint *params);
+angle::CallCapture CaptureGetVertexAttribIiv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureGetVertexAttribIuiv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLenum pname,
+ GLuint *params);
+angle::CallCapture CaptureInvalidateFramebuffer(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLsizei numAttachments,
+ const GLenum *attachments);
+angle::CallCapture CaptureInvalidateSubFramebuffer(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLsizei numAttachments,
+ const GLenum *attachments,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height);
+angle::CallCapture CaptureIsQuery(const State &glState,
+ bool isCallValid,
+ QueryID idPacked,
+ GLboolean returnValue);
+angle::CallCapture CaptureIsSampler(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLboolean returnValue);
+angle::CallCapture CaptureIsSync(const State &glState,
+ bool isCallValid,
+ GLsync sync,
+ GLboolean returnValue);
+angle::CallCapture CaptureIsTransformFeedback(const State &glState,
+ bool isCallValid,
+ TransformFeedbackID idPacked,
+ GLboolean returnValue);
+angle::CallCapture CaptureIsVertexArray(const State &glState,
+ bool isCallValid,
+ VertexArrayID arrayPacked,
+ GLboolean returnValue);
+angle::CallCapture CaptureMapBufferRange(const State &glState,
+ bool isCallValid,
+ BufferBinding targetPacked,
+ GLintptr offset,
+ GLsizeiptr length,
+ GLbitfield access,
+ void *returnValue);
+angle::CallCapture CapturePauseTransformFeedback(const State &glState, bool isCallValid);
+angle::CallCapture CaptureProgramBinary(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum binaryFormat,
+ const void *binary,
+ GLsizei length);
+angle::CallCapture CaptureProgramParameteri(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum pname,
+ GLint value);
+angle::CallCapture CaptureReadBuffer(const State &glState, bool isCallValid, GLenum src);
+angle::CallCapture CaptureRenderbufferStorageMultisample(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height);
+angle::CallCapture CaptureResumeTransformFeedback(const State &glState, bool isCallValid);
+angle::CallCapture CaptureSamplerParameterf(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLfloat param);
+angle::CallCapture CaptureSamplerParameterfv(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ const GLfloat *param);
+angle::CallCapture CaptureSamplerParameteri(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLint param);
+angle::CallCapture CaptureSamplerParameteriv(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ const GLint *param);
+angle::CallCapture CaptureTexImage3D(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const void *pixels);
+angle::CallCapture CaptureTexStorage2D(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height);
+angle::CallCapture CaptureTexStorage3D(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth);
+angle::CallCapture CaptureTexSubImage3D(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ const void *pixels);
+angle::CallCapture CaptureTransformFeedbackVaryings(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLsizei count,
+ const GLchar *const *varyings,
+ GLenum bufferMode);
+angle::CallCapture CaptureUniform1ui(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLuint v0);
+angle::CallCapture CaptureUniform1uiv(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value);
+angle::CallCapture CaptureUniform2ui(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLuint v0,
+ GLuint v1);
+angle::CallCapture CaptureUniform2uiv(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value);
+angle::CallCapture CaptureUniform3ui(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLuint v0,
+ GLuint v1,
+ GLuint v2);
+angle::CallCapture CaptureUniform3uiv(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value);
+angle::CallCapture CaptureUniform4ui(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLuint v0,
+ GLuint v1,
+ GLuint v2,
+ GLuint v3);
+angle::CallCapture CaptureUniform4uiv(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value);
+angle::CallCapture CaptureUniformBlockBinding(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformBlockIndex uniformBlockIndexPacked,
+ GLuint uniformBlockBinding);
+angle::CallCapture CaptureUniformMatrix2x3fv(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+angle::CallCapture CaptureUniformMatrix2x4fv(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+angle::CallCapture CaptureUniformMatrix3x2fv(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+angle::CallCapture CaptureUniformMatrix3x4fv(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+angle::CallCapture CaptureUniformMatrix4x2fv(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+angle::CallCapture CaptureUniformMatrix4x3fv(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+angle::CallCapture CaptureUnmapBuffer(const State &glState,
+ bool isCallValid,
+ BufferBinding targetPacked,
+ GLboolean returnValue);
+angle::CallCapture CaptureVertexAttribDivisor(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLuint divisor);
+angle::CallCapture CaptureVertexAttribI4i(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLint x,
+ GLint y,
+ GLint z,
+ GLint w);
+angle::CallCapture CaptureVertexAttribI4iv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLint *v);
+angle::CallCapture CaptureVertexAttribI4ui(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLuint x,
+ GLuint y,
+ GLuint z,
+ GLuint w);
+angle::CallCapture CaptureVertexAttribI4uiv(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLuint *v);
+angle::CallCapture CaptureVertexAttribIPointer(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLint size,
+ VertexAttribType typePacked,
+ GLsizei stride,
+ const void *pointer);
+angle::CallCapture CaptureWaitSync(const State &glState,
+ bool isCallValid,
+ GLsync sync,
+ GLbitfield flags,
+ GLuint64 timeout);
+
+// Parameter Captures
+
+void CaptureClearBufferfv_value(const State &glState,
+ bool isCallValid,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLfloat *value,
+ angle::ParamCapture *paramCapture);
+void CaptureClearBufferiv_value(const State &glState,
+ bool isCallValid,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLint *value,
+ angle::ParamCapture *paramCapture);
+void CaptureClearBufferuiv_value(const State &glState,
+ bool isCallValid,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLuint *value,
+ angle::ParamCapture *paramCapture);
+void CaptureCompressedTexImage3D_data(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLsizei imageSize,
+ const void *data,
+ angle::ParamCapture *paramCapture);
+void CaptureCompressedTexSubImage3D_data(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data,
+ angle::ParamCapture *paramCapture);
+void CaptureDeleteQueries_idsPacked(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ const QueryID *idsPacked,
+ angle::ParamCapture *paramCapture);
+void CaptureDeleteSamplers_samplersPacked(const State &glState,
+ bool isCallValid,
+ GLsizei count,
+ const SamplerID *samplersPacked,
+ angle::ParamCapture *paramCapture);
+void CaptureDeleteTransformFeedbacks_idsPacked(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ const TransformFeedbackID *idsPacked,
+ angle::ParamCapture *paramCapture);
+void CaptureDeleteVertexArrays_arraysPacked(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ const VertexArrayID *arraysPacked,
+ angle::ParamCapture *paramCapture);
+void CaptureDrawBuffers_bufs(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ const GLenum *bufs,
+ angle::ParamCapture *paramCapture);
+void CaptureDrawElementsInstanced_indices(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLsizei instancecount,
+ angle::ParamCapture *paramCapture);
+void CaptureDrawRangeElements_indices(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ angle::ParamCapture *paramCapture);
+void CaptureGenQueries_idsPacked(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ QueryID *idsPacked,
+ angle::ParamCapture *paramCapture);
+void CaptureGenSamplers_samplersPacked(const State &glState,
+ bool isCallValid,
+ GLsizei count,
+ SamplerID *samplersPacked,
+ angle::ParamCapture *paramCapture);
+void CaptureGenTransformFeedbacks_idsPacked(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ TransformFeedbackID *idsPacked,
+ angle::ParamCapture *paramCapture);
+void CaptureGenVertexArrays_arraysPacked(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ VertexArrayID *arraysPacked,
+ angle::ParamCapture *paramCapture);
+void CaptureGetActiveUniformBlockName_length(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformBlockIndex uniformBlockIndexPacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *uniformBlockName,
+ angle::ParamCapture *paramCapture);
+void CaptureGetActiveUniformBlockName_uniformBlockName(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformBlockIndex uniformBlockIndexPacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *uniformBlockName,
+ angle::ParamCapture *paramCapture);
+void CaptureGetActiveUniformBlockiv_params(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformBlockIndex uniformBlockIndexPacked,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetActiveUniformsiv_uniformIndices(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLsizei uniformCount,
+ const GLuint *uniformIndices,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetActiveUniformsiv_params(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLsizei uniformCount,
+ const GLuint *uniformIndices,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetBufferParameteri64v_params(const State &glState,
+ bool isCallValid,
+ BufferBinding targetPacked,
+ GLenum pname,
+ GLint64 *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetBufferPointerv_params(const State &glState,
+ bool isCallValid,
+ BufferBinding targetPacked,
+ GLenum pname,
+ void **params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetFragDataLocation_name(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ const GLchar *name,
+ angle::ParamCapture *paramCapture);
+void CaptureGetInteger64i_v_data(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLuint index,
+ GLint64 *data,
+ angle::ParamCapture *paramCapture);
+void CaptureGetInteger64v_data(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLint64 *data,
+ angle::ParamCapture *paramCapture);
+void CaptureGetIntegeri_v_data(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLuint index,
+ GLint *data,
+ angle::ParamCapture *paramCapture);
+void CaptureGetInternalformativ_params(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum internalformat,
+ GLenum pname,
+ GLsizei count,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetProgramBinary_length(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLenum *binaryFormat,
+ void *binary,
+ angle::ParamCapture *paramCapture);
+void CaptureGetProgramBinary_binaryFormat(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLenum *binaryFormat,
+ void *binary,
+ angle::ParamCapture *paramCapture);
+void CaptureGetProgramBinary_binary(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLenum *binaryFormat,
+ void *binary,
+ angle::ParamCapture *paramCapture);
+void CaptureGetQueryObjectuiv_params(const State &glState,
+ bool isCallValid,
+ QueryID idPacked,
+ GLenum pname,
+ GLuint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetQueryiv_params(const State &glState,
+ bool isCallValid,
+ QueryType targetPacked,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetSamplerParameterfv_params(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLfloat *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetSamplerParameteriv_params(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetSynciv_length(const State &glState,
+ bool isCallValid,
+ GLsync sync,
+ GLenum pname,
+ GLsizei count,
+ GLsizei *length,
+ GLint *values,
+ angle::ParamCapture *paramCapture);
+void CaptureGetSynciv_values(const State &glState,
+ bool isCallValid,
+ GLsync sync,
+ GLenum pname,
+ GLsizei count,
+ GLsizei *length,
+ GLint *values,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTransformFeedbackVarying_length(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLsizei *size,
+ GLenum *type,
+ GLchar *name,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTransformFeedbackVarying_size(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLsizei *size,
+ GLenum *type,
+ GLchar *name,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTransformFeedbackVarying_type(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLsizei *size,
+ GLenum *type,
+ GLchar *name,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTransformFeedbackVarying_name(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLsizei *size,
+ GLenum *type,
+ GLchar *name,
+ angle::ParamCapture *paramCapture);
+void CaptureGetUniformBlockIndex_uniformBlockName(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ const GLchar *uniformBlockName,
+ angle::ParamCapture *paramCapture);
+void CaptureGetUniformIndices_uniformNames(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLsizei uniformCount,
+ const GLchar *const *uniformNames,
+ GLuint *uniformIndices,
+ angle::ParamCapture *paramCapture);
+void CaptureGetUniformIndices_uniformIndices(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLsizei uniformCount,
+ const GLchar *const *uniformNames,
+ GLuint *uniformIndices,
+ angle::ParamCapture *paramCapture);
+void CaptureGetUniformuiv_params(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLuint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetVertexAttribIiv_params(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetVertexAttribIuiv_params(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLenum pname,
+ GLuint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureInvalidateFramebuffer_attachments(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLsizei numAttachments,
+ const GLenum *attachments,
+ angle::ParamCapture *paramCapture);
+void CaptureInvalidateSubFramebuffer_attachments(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLsizei numAttachments,
+ const GLenum *attachments,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramBinary_binary(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum binaryFormat,
+ const void *binary,
+ GLsizei length,
+ angle::ParamCapture *paramCapture);
+void CaptureSamplerParameterfv_param(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ const GLfloat *param,
+ angle::ParamCapture *paramCapture);
+void CaptureSamplerParameteriv_param(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ const GLint *param,
+ angle::ParamCapture *paramCapture);
+void CaptureTexImage3D_pixels(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const void *pixels,
+ angle::ParamCapture *paramCapture);
+void CaptureTexSubImage3D_pixels(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ const void *pixels,
+ angle::ParamCapture *paramCapture);
+void CaptureTransformFeedbackVaryings_varyings(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLsizei count,
+ const GLchar *const *varyings,
+ GLenum bufferMode,
+ angle::ParamCapture *paramCapture);
+void CaptureUniform1uiv_value(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value,
+ angle::ParamCapture *paramCapture);
+void CaptureUniform2uiv_value(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value,
+ angle::ParamCapture *paramCapture);
+void CaptureUniform3uiv_value(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value,
+ angle::ParamCapture *paramCapture);
+void CaptureUniform4uiv_value(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value,
+ angle::ParamCapture *paramCapture);
+void CaptureUniformMatrix2x3fv_value(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value,
+ angle::ParamCapture *paramCapture);
+void CaptureUniformMatrix2x4fv_value(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value,
+ angle::ParamCapture *paramCapture);
+void CaptureUniformMatrix3x2fv_value(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value,
+ angle::ParamCapture *paramCapture);
+void CaptureUniformMatrix3x4fv_value(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value,
+ angle::ParamCapture *paramCapture);
+void CaptureUniformMatrix4x2fv_value(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value,
+ angle::ParamCapture *paramCapture);
+void CaptureUniformMatrix4x3fv_value(const State &glState,
+ bool isCallValid,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttribI4iv_v(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLint *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttribI4uiv_v(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ const GLuint *v,
+ angle::ParamCapture *paramCapture);
+void CaptureVertexAttribIPointer_pointer(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLint size,
+ VertexAttribType typePacked,
+ GLsizei stride,
+ const void *pointer,
+ angle::ParamCapture *paramCapture);
+} // namespace gl
+
+#endif // LIBANGLE_CAPTURE_GLES_3_0_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libANGLE/capture/capture_gles_3_1_autogen.h b/gfx/angle/checkout/src/libANGLE/capture/capture_gles_3_1_autogen.h
new file mode 100644
index 0000000000..ee594a1c79
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/capture/capture_gles_3_1_autogen.h
@@ -0,0 +1,728 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml and gl_angle_ext.xml.
+//
+// Copyright 2020 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.
+//
+// capture_gles_3_1_autogen.h:
+// Capture functions for the OpenGL ES 3.1 entry points.
+
+#ifndef LIBANGLE_CAPTURE_GLES_3_1_AUTOGEN_H_
+#define LIBANGLE_CAPTURE_GLES_3_1_AUTOGEN_H_
+
+#include "common/PackedEnums.h"
+#include "libANGLE/capture/FrameCapture.h"
+
+namespace gl
+{
+
+// Method Captures
+
+angle::CallCapture CaptureActiveShaderProgram(const State &glState,
+ bool isCallValid,
+ ProgramPipelineID pipelinePacked,
+ ShaderProgramID programPacked);
+angle::CallCapture CaptureBindImageTexture(const State &glState,
+ bool isCallValid,
+ GLuint unit,
+ TextureID texturePacked,
+ GLint level,
+ GLboolean layered,
+ GLint layer,
+ GLenum access,
+ GLenum format);
+angle::CallCapture CaptureBindProgramPipeline(const State &glState,
+ bool isCallValid,
+ ProgramPipelineID pipelinePacked);
+angle::CallCapture CaptureBindVertexBuffer(const State &glState,
+ bool isCallValid,
+ GLuint bindingindex,
+ BufferID bufferPacked,
+ GLintptr offset,
+ GLsizei stride);
+angle::CallCapture CaptureCreateShaderProgramv(const State &glState,
+ bool isCallValid,
+ ShaderType typePacked,
+ GLsizei count,
+ const GLchar *const *strings,
+ GLuint returnValue);
+angle::CallCapture CaptureDeleteProgramPipelines(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ const ProgramPipelineID *pipelinesPacked);
+angle::CallCapture CaptureDispatchCompute(const State &glState,
+ bool isCallValid,
+ GLuint num_groups_x,
+ GLuint num_groups_y,
+ GLuint num_groups_z);
+angle::CallCapture CaptureDispatchComputeIndirect(const State &glState,
+ bool isCallValid,
+ GLintptr indirect);
+angle::CallCapture CaptureDrawArraysIndirect(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const void *indirect);
+angle::CallCapture CaptureDrawElementsIndirect(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ DrawElementsType typePacked,
+ const void *indirect);
+angle::CallCapture CaptureFramebufferParameteri(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum pname,
+ GLint param);
+angle::CallCapture CaptureGenProgramPipelines(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ ProgramPipelineID *pipelinesPacked);
+angle::CallCapture CaptureGetBooleani_v(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLuint index,
+ GLboolean *data);
+angle::CallCapture CaptureGetFramebufferParameteriv(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureGetMultisamplefv(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLuint index,
+ GLfloat *val);
+angle::CallCapture CaptureGetProgramInterfaceiv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum programInterface,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureGetProgramPipelineInfoLog(const State &glState,
+ bool isCallValid,
+ ProgramPipelineID pipelinePacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *infoLog);
+angle::CallCapture CaptureGetProgramPipelineiv(const State &glState,
+ bool isCallValid,
+ ProgramPipelineID pipelinePacked,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureGetProgramResourceIndex(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum programInterface,
+ const GLchar *name,
+ GLuint returnValue);
+angle::CallCapture CaptureGetProgramResourceLocation(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum programInterface,
+ const GLchar *name,
+ GLint returnValue);
+angle::CallCapture CaptureGetProgramResourceName(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum programInterface,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *name);
+angle::CallCapture CaptureGetProgramResourceiv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum programInterface,
+ GLuint index,
+ GLsizei propCount,
+ const GLenum *props,
+ GLsizei count,
+ GLsizei *length,
+ GLint *params);
+angle::CallCapture CaptureGetTexLevelParameterfv(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum pname,
+ GLfloat *params);
+angle::CallCapture CaptureGetTexLevelParameteriv(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureIsProgramPipeline(const State &glState,
+ bool isCallValid,
+ ProgramPipelineID pipelinePacked,
+ GLboolean returnValue);
+angle::CallCapture CaptureMemoryBarrier(const State &glState,
+ bool isCallValid,
+ GLbitfield barriers);
+angle::CallCapture CaptureMemoryBarrierByRegion(const State &glState,
+ bool isCallValid,
+ GLbitfield barriers);
+angle::CallCapture CaptureProgramUniform1f(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLfloat v0);
+angle::CallCapture CaptureProgramUniform1fv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value);
+angle::CallCapture CaptureProgramUniform1i(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLint v0);
+angle::CallCapture CaptureProgramUniform1iv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value);
+angle::CallCapture CaptureProgramUniform1ui(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLuint v0);
+angle::CallCapture CaptureProgramUniform1uiv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value);
+angle::CallCapture CaptureProgramUniform2f(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLfloat v0,
+ GLfloat v1);
+angle::CallCapture CaptureProgramUniform2fv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value);
+angle::CallCapture CaptureProgramUniform2i(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLint v0,
+ GLint v1);
+angle::CallCapture CaptureProgramUniform2iv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value);
+angle::CallCapture CaptureProgramUniform2ui(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLuint v0,
+ GLuint v1);
+angle::CallCapture CaptureProgramUniform2uiv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value);
+angle::CallCapture CaptureProgramUniform3f(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLfloat v0,
+ GLfloat v1,
+ GLfloat v2);
+angle::CallCapture CaptureProgramUniform3fv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value);
+angle::CallCapture CaptureProgramUniform3i(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLint v0,
+ GLint v1,
+ GLint v2);
+angle::CallCapture CaptureProgramUniform3iv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value);
+angle::CallCapture CaptureProgramUniform3ui(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLuint v0,
+ GLuint v1,
+ GLuint v2);
+angle::CallCapture CaptureProgramUniform3uiv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value);
+angle::CallCapture CaptureProgramUniform4f(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLfloat v0,
+ GLfloat v1,
+ GLfloat v2,
+ GLfloat v3);
+angle::CallCapture CaptureProgramUniform4fv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value);
+angle::CallCapture CaptureProgramUniform4i(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLint v0,
+ GLint v1,
+ GLint v2,
+ GLint v3);
+angle::CallCapture CaptureProgramUniform4iv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value);
+angle::CallCapture CaptureProgramUniform4ui(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLuint v0,
+ GLuint v1,
+ GLuint v2,
+ GLuint v3);
+angle::CallCapture CaptureProgramUniform4uiv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value);
+angle::CallCapture CaptureProgramUniformMatrix2fv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+angle::CallCapture CaptureProgramUniformMatrix2x3fv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+angle::CallCapture CaptureProgramUniformMatrix2x4fv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+angle::CallCapture CaptureProgramUniformMatrix3fv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+angle::CallCapture CaptureProgramUniformMatrix3x2fv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+angle::CallCapture CaptureProgramUniformMatrix3x4fv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+angle::CallCapture CaptureProgramUniformMatrix4fv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+angle::CallCapture CaptureProgramUniformMatrix4x2fv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+angle::CallCapture CaptureProgramUniformMatrix4x3fv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+angle::CallCapture CaptureSampleMaski(const State &glState,
+ bool isCallValid,
+ GLuint maskNumber,
+ GLbitfield mask);
+angle::CallCapture CaptureTexStorage2DMultisample(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedsamplelocations);
+angle::CallCapture CaptureUseProgramStages(const State &glState,
+ bool isCallValid,
+ ProgramPipelineID pipelinePacked,
+ GLbitfield stages,
+ ShaderProgramID programPacked);
+angle::CallCapture CaptureValidateProgramPipeline(const State &glState,
+ bool isCallValid,
+ ProgramPipelineID pipelinePacked);
+angle::CallCapture CaptureVertexAttribBinding(const State &glState,
+ bool isCallValid,
+ GLuint attribindex,
+ GLuint bindingindex);
+angle::CallCapture CaptureVertexAttribFormat(const State &glState,
+ bool isCallValid,
+ GLuint attribindex,
+ GLint size,
+ VertexAttribType typePacked,
+ GLboolean normalized,
+ GLuint relativeoffset);
+angle::CallCapture CaptureVertexAttribIFormat(const State &glState,
+ bool isCallValid,
+ GLuint attribindex,
+ GLint size,
+ VertexAttribType typePacked,
+ GLuint relativeoffset);
+angle::CallCapture CaptureVertexBindingDivisor(const State &glState,
+ bool isCallValid,
+ GLuint bindingindex,
+ GLuint divisor);
+
+// Parameter Captures
+
+void CaptureCreateShaderProgramv_strings(const State &glState,
+ bool isCallValid,
+ ShaderType typePacked,
+ GLsizei count,
+ const GLchar *const *strings,
+ angle::ParamCapture *paramCapture);
+void CaptureDeleteProgramPipelines_pipelinesPacked(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ const ProgramPipelineID *pipelinesPacked,
+ angle::ParamCapture *paramCapture);
+void CaptureDrawArraysIndirect_indirect(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const void *indirect,
+ angle::ParamCapture *paramCapture);
+void CaptureDrawElementsIndirect_indirect(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ DrawElementsType typePacked,
+ const void *indirect,
+ angle::ParamCapture *paramCapture);
+void CaptureGenProgramPipelines_pipelinesPacked(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ ProgramPipelineID *pipelinesPacked,
+ angle::ParamCapture *paramCapture);
+void CaptureGetBooleani_v_data(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLuint index,
+ GLboolean *data,
+ angle::ParamCapture *paramCapture);
+void CaptureGetFramebufferParameteriv_params(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetMultisamplefv_val(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLuint index,
+ GLfloat *val,
+ angle::ParamCapture *paramCapture);
+void CaptureGetProgramInterfaceiv_params(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum programInterface,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetProgramPipelineInfoLog_length(const State &glState,
+ bool isCallValid,
+ ProgramPipelineID pipelinePacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *infoLog,
+ angle::ParamCapture *paramCapture);
+void CaptureGetProgramPipelineInfoLog_infoLog(const State &glState,
+ bool isCallValid,
+ ProgramPipelineID pipelinePacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *infoLog,
+ angle::ParamCapture *paramCapture);
+void CaptureGetProgramPipelineiv_params(const State &glState,
+ bool isCallValid,
+ ProgramPipelineID pipelinePacked,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetProgramResourceIndex_name(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum programInterface,
+ const GLchar *name,
+ angle::ParamCapture *paramCapture);
+void CaptureGetProgramResourceLocation_name(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum programInterface,
+ const GLchar *name,
+ angle::ParamCapture *paramCapture);
+void CaptureGetProgramResourceName_length(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum programInterface,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *name,
+ angle::ParamCapture *paramCapture);
+void CaptureGetProgramResourceName_name(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum programInterface,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *name,
+ angle::ParamCapture *paramCapture);
+void CaptureGetProgramResourceiv_props(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum programInterface,
+ GLuint index,
+ GLsizei propCount,
+ const GLenum *props,
+ GLsizei count,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetProgramResourceiv_length(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum programInterface,
+ GLuint index,
+ GLsizei propCount,
+ const GLenum *props,
+ GLsizei count,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetProgramResourceiv_params(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum programInterface,
+ GLuint index,
+ GLsizei propCount,
+ const GLenum *props,
+ GLsizei count,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTexLevelParameterfv_params(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum pname,
+ GLfloat *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTexLevelParameteriv_params(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniform1fv_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniform1iv_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniform1uiv_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniform2fv_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniform2iv_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniform2uiv_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniform3fv_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniform3iv_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniform3uiv_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniform4fv_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniform4iv_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniform4uiv_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniformMatrix2fv_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniformMatrix2x3fv_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniformMatrix2x4fv_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniformMatrix3fv_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniformMatrix3x2fv_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniformMatrix3x4fv_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniformMatrix4fv_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniformMatrix4x2fv_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniformMatrix4x3fv_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value,
+ angle::ParamCapture *paramCapture);
+} // namespace gl
+
+#endif // LIBANGLE_CAPTURE_GLES_3_1_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libANGLE/capture/capture_gles_3_2_autogen.h b/gfx/angle/checkout/src/libANGLE/capture/capture_gles_3_2_autogen.h
new file mode 100644
index 0000000000..80001a0348
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/capture/capture_gles_3_2_autogen.h
@@ -0,0 +1,553 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml and gl_angle_ext.xml.
+//
+// Copyright 2020 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.
+//
+// capture_gles_3_2_autogen.h:
+// Capture functions for the OpenGL ES 3.2 entry points.
+
+#ifndef LIBANGLE_CAPTURE_GLES_3_2_AUTOGEN_H_
+#define LIBANGLE_CAPTURE_GLES_3_2_AUTOGEN_H_
+
+#include "common/PackedEnums.h"
+#include "libANGLE/capture/FrameCapture.h"
+
+namespace gl
+{
+
+// Method Captures
+
+angle::CallCapture CaptureBlendBarrier(const State &glState, bool isCallValid);
+angle::CallCapture CaptureBlendEquationSeparatei(const State &glState,
+ bool isCallValid,
+ GLuint buf,
+ GLenum modeRGB,
+ GLenum modeAlpha);
+angle::CallCapture CaptureBlendEquationi(const State &glState,
+ bool isCallValid,
+ GLuint buf,
+ GLenum mode);
+angle::CallCapture CaptureBlendFuncSeparatei(const State &glState,
+ bool isCallValid,
+ GLuint buf,
+ GLenum srcRGB,
+ GLenum dstRGB,
+ GLenum srcAlpha,
+ GLenum dstAlpha);
+angle::CallCapture CaptureBlendFunci(const State &glState,
+ bool isCallValid,
+ GLuint buf,
+ GLenum src,
+ GLenum dst);
+angle::CallCapture CaptureColorMaski(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLboolean r,
+ GLboolean g,
+ GLboolean b,
+ GLboolean a);
+angle::CallCapture CaptureCopyImageSubData(const State &glState,
+ bool isCallValid,
+ GLuint srcName,
+ GLenum srcTarget,
+ GLint srcLevel,
+ GLint srcX,
+ GLint srcY,
+ GLint srcZ,
+ GLuint dstName,
+ GLenum dstTarget,
+ GLint dstLevel,
+ GLint dstX,
+ GLint dstY,
+ GLint dstZ,
+ GLsizei srcWidth,
+ GLsizei srcHeight,
+ GLsizei srcDepth);
+angle::CallCapture CaptureDebugMessageCallback(const State &glState,
+ bool isCallValid,
+ GLDEBUGPROC callback,
+ const void *userParam);
+angle::CallCapture CaptureDebugMessageControl(const State &glState,
+ bool isCallValid,
+ GLenum source,
+ GLenum type,
+ GLenum severity,
+ GLsizei count,
+ const GLuint *ids,
+ GLboolean enabled);
+angle::CallCapture CaptureDebugMessageInsert(const State &glState,
+ bool isCallValid,
+ GLenum source,
+ GLenum type,
+ GLuint id,
+ GLenum severity,
+ GLsizei length,
+ const GLchar *buf);
+angle::CallCapture CaptureDisablei(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLuint index);
+angle::CallCapture CaptureDrawElementsBaseVertex(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLint basevertex);
+angle::CallCapture CaptureDrawElementsInstancedBaseVertex(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLsizei instancecount,
+ GLint basevertex);
+angle::CallCapture CaptureDrawRangeElementsBaseVertex(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLint basevertex);
+angle::CallCapture CaptureEnablei(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLuint index);
+angle::CallCapture CaptureFramebufferTexture(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum attachment,
+ TextureID texturePacked,
+ GLint level);
+angle::CallCapture CaptureGetDebugMessageLog(const State &glState,
+ bool isCallValid,
+ GLuint count,
+ GLsizei bufSize,
+ GLenum *sources,
+ GLenum *types,
+ GLuint *ids,
+ GLenum *severities,
+ GLsizei *lengths,
+ GLchar *messageLog,
+ GLuint returnValue);
+angle::CallCapture CaptureGetGraphicsResetStatus(const State &glState,
+ bool isCallValid,
+ GLenum returnValue);
+angle::CallCapture CaptureGetObjectLabel(const State &glState,
+ bool isCallValid,
+ GLenum identifier,
+ GLuint name,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *label);
+angle::CallCapture CaptureGetObjectPtrLabel(const State &glState,
+ bool isCallValid,
+ const void *ptr,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *label);
+angle::CallCapture CaptureGetPointerv(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ void **params);
+angle::CallCapture CaptureGetSamplerParameterIiv(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureGetSamplerParameterIuiv(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLuint *params);
+angle::CallCapture CaptureGetTexParameterIiv(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureGetTexParameterIuiv(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ GLuint *params);
+angle::CallCapture CaptureGetnUniformfv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei bufSize,
+ GLfloat *params);
+angle::CallCapture CaptureGetnUniformiv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei bufSize,
+ GLint *params);
+angle::CallCapture CaptureGetnUniformuiv(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei bufSize,
+ GLuint *params);
+angle::CallCapture CaptureIsEnabledi(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLuint index,
+ GLboolean returnValue);
+angle::CallCapture CaptureMinSampleShading(const State &glState, bool isCallValid, GLfloat value);
+angle::CallCapture CaptureObjectLabel(const State &glState,
+ bool isCallValid,
+ GLenum identifier,
+ GLuint name,
+ GLsizei length,
+ const GLchar *label);
+angle::CallCapture CaptureObjectPtrLabel(const State &glState,
+ bool isCallValid,
+ const void *ptr,
+ GLsizei length,
+ const GLchar *label);
+angle::CallCapture CapturePatchParameteri(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLint value);
+angle::CallCapture CapturePopDebugGroup(const State &glState, bool isCallValid);
+angle::CallCapture CapturePrimitiveBoundingBox(const State &glState,
+ bool isCallValid,
+ GLfloat minX,
+ GLfloat minY,
+ GLfloat minZ,
+ GLfloat minW,
+ GLfloat maxX,
+ GLfloat maxY,
+ GLfloat maxZ,
+ GLfloat maxW);
+angle::CallCapture CapturePushDebugGroup(const State &glState,
+ bool isCallValid,
+ GLenum source,
+ GLuint id,
+ GLsizei length,
+ const GLchar *message);
+angle::CallCapture CaptureReadnPixels(const State &glState,
+ bool isCallValid,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ void *data);
+angle::CallCapture CaptureSamplerParameterIiv(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ const GLint *param);
+angle::CallCapture CaptureSamplerParameterIuiv(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ const GLuint *param);
+angle::CallCapture CaptureTexBuffer(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum internalformat,
+ BufferID bufferPacked);
+angle::CallCapture CaptureTexBufferRange(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum internalformat,
+ BufferID bufferPacked,
+ GLintptr offset,
+ GLsizeiptr size);
+angle::CallCapture CaptureTexParameterIiv(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLint *params);
+angle::CallCapture CaptureTexParameterIuiv(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLuint *params);
+angle::CallCapture CaptureTexStorage3DMultisample(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean fixedsamplelocations);
+
+// Parameter Captures
+
+void CaptureDebugMessageCallback_userParam(const State &glState,
+ bool isCallValid,
+ GLDEBUGPROC callback,
+ const void *userParam,
+ angle::ParamCapture *paramCapture);
+void CaptureDebugMessageControl_ids(const State &glState,
+ bool isCallValid,
+ GLenum source,
+ GLenum type,
+ GLenum severity,
+ GLsizei count,
+ const GLuint *ids,
+ GLboolean enabled,
+ angle::ParamCapture *paramCapture);
+void CaptureDebugMessageInsert_buf(const State &glState,
+ bool isCallValid,
+ GLenum source,
+ GLenum type,
+ GLuint id,
+ GLenum severity,
+ GLsizei length,
+ const GLchar *buf,
+ angle::ParamCapture *paramCapture);
+void CaptureDrawElementsBaseVertex_indices(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLint basevertex,
+ angle::ParamCapture *paramCapture);
+void CaptureDrawElementsInstancedBaseVertex_indices(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLsizei instancecount,
+ GLint basevertex,
+ angle::ParamCapture *paramCapture);
+void CaptureDrawRangeElementsBaseVertex_indices(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLint basevertex,
+ angle::ParamCapture *paramCapture);
+void CaptureGetDebugMessageLog_sources(const State &glState,
+ bool isCallValid,
+ GLuint count,
+ GLsizei bufSize,
+ GLenum *sources,
+ GLenum *types,
+ GLuint *ids,
+ GLenum *severities,
+ GLsizei *lengths,
+ GLchar *messageLog,
+ angle::ParamCapture *paramCapture);
+void CaptureGetDebugMessageLog_types(const State &glState,
+ bool isCallValid,
+ GLuint count,
+ GLsizei bufSize,
+ GLenum *sources,
+ GLenum *types,
+ GLuint *ids,
+ GLenum *severities,
+ GLsizei *lengths,
+ GLchar *messageLog,
+ angle::ParamCapture *paramCapture);
+void CaptureGetDebugMessageLog_ids(const State &glState,
+ bool isCallValid,
+ GLuint count,
+ GLsizei bufSize,
+ GLenum *sources,
+ GLenum *types,
+ GLuint *ids,
+ GLenum *severities,
+ GLsizei *lengths,
+ GLchar *messageLog,
+ angle::ParamCapture *paramCapture);
+void CaptureGetDebugMessageLog_severities(const State &glState,
+ bool isCallValid,
+ GLuint count,
+ GLsizei bufSize,
+ GLenum *sources,
+ GLenum *types,
+ GLuint *ids,
+ GLenum *severities,
+ GLsizei *lengths,
+ GLchar *messageLog,
+ angle::ParamCapture *paramCapture);
+void CaptureGetDebugMessageLog_lengths(const State &glState,
+ bool isCallValid,
+ GLuint count,
+ GLsizei bufSize,
+ GLenum *sources,
+ GLenum *types,
+ GLuint *ids,
+ GLenum *severities,
+ GLsizei *lengths,
+ GLchar *messageLog,
+ angle::ParamCapture *paramCapture);
+void CaptureGetDebugMessageLog_messageLog(const State &glState,
+ bool isCallValid,
+ GLuint count,
+ GLsizei bufSize,
+ GLenum *sources,
+ GLenum *types,
+ GLuint *ids,
+ GLenum *severities,
+ GLsizei *lengths,
+ GLchar *messageLog,
+ angle::ParamCapture *paramCapture);
+void CaptureGetObjectLabel_length(const State &glState,
+ bool isCallValid,
+ GLenum identifier,
+ GLuint name,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *label,
+ angle::ParamCapture *paramCapture);
+void CaptureGetObjectLabel_label(const State &glState,
+ bool isCallValid,
+ GLenum identifier,
+ GLuint name,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *label,
+ angle::ParamCapture *paramCapture);
+void CaptureGetObjectPtrLabel_ptr(const State &glState,
+ bool isCallValid,
+ const void *ptr,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *label,
+ angle::ParamCapture *paramCapture);
+void CaptureGetObjectPtrLabel_length(const State &glState,
+ bool isCallValid,
+ const void *ptr,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *label,
+ angle::ParamCapture *paramCapture);
+void CaptureGetObjectPtrLabel_label(const State &glState,
+ bool isCallValid,
+ const void *ptr,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *label,
+ angle::ParamCapture *paramCapture);
+void CaptureGetPointerv_params(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ void **params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetSamplerParameterIiv_params(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetSamplerParameterIuiv_params(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLuint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTexParameterIiv_params(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTexParameterIuiv_params(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ GLuint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetnUniformfv_params(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei bufSize,
+ GLfloat *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetnUniformiv_params(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei bufSize,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetnUniformuiv_params(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei bufSize,
+ GLuint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureObjectLabel_label(const State &glState,
+ bool isCallValid,
+ GLenum identifier,
+ GLuint name,
+ GLsizei length,
+ const GLchar *label,
+ angle::ParamCapture *paramCapture);
+void CaptureObjectPtrLabel_ptr(const State &glState,
+ bool isCallValid,
+ const void *ptr,
+ GLsizei length,
+ const GLchar *label,
+ angle::ParamCapture *paramCapture);
+void CaptureObjectPtrLabel_label(const State &glState,
+ bool isCallValid,
+ const void *ptr,
+ GLsizei length,
+ const GLchar *label,
+ angle::ParamCapture *paramCapture);
+void CapturePushDebugGroup_message(const State &glState,
+ bool isCallValid,
+ GLenum source,
+ GLuint id,
+ GLsizei length,
+ const GLchar *message,
+ angle::ParamCapture *paramCapture);
+void CaptureReadnPixels_data(const State &glState,
+ bool isCallValid,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ void *data,
+ angle::ParamCapture *paramCapture);
+void CaptureSamplerParameterIiv_param(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ const GLint *param,
+ angle::ParamCapture *paramCapture);
+void CaptureSamplerParameterIuiv_param(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ const GLuint *param,
+ angle::ParamCapture *paramCapture);
+void CaptureTexParameterIiv_params(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureTexParameterIuiv_params(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLuint *params,
+ angle::ParamCapture *paramCapture);
+} // namespace gl
+
+#endif // LIBANGLE_CAPTURE_GLES_3_2_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libANGLE/capture/capture_gles_ext_autogen.h b/gfx/angle/checkout/src/libANGLE/capture/capture_gles_ext_autogen.h
new file mode 100644
index 0000000000..03211ffeb9
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/capture/capture_gles_ext_autogen.h
@@ -0,0 +1,5231 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml and gl_angle_ext.xml.
+//
+// Copyright 2020 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.
+//
+// capture_gles_ext_autogen.h:
+// Capture functions for the OpenGL ES extension entry points.
+
+#ifndef LIBANGLE_CAPTURE_GLES_EXT_AUTOGEN_H_
+#define LIBANGLE_CAPTURE_GLES_EXT_AUTOGEN_H_
+
+#include "common/PackedEnums.h"
+#include "libANGLE/capture/FrameCapture.h"
+
+namespace gl
+{
+
+// Method Captures
+
+// GL_AMD_performance_monitor
+angle::CallCapture CaptureBeginPerfMonitorAMD(const State &glState,
+ bool isCallValid,
+ GLuint monitor);
+angle::CallCapture CaptureDeletePerfMonitorsAMD(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ GLuint *monitors);
+angle::CallCapture CaptureEndPerfMonitorAMD(const State &glState, bool isCallValid, GLuint monitor);
+angle::CallCapture CaptureGenPerfMonitorsAMD(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ GLuint *monitors);
+angle::CallCapture CaptureGetPerfMonitorCounterDataAMD(const State &glState,
+ bool isCallValid,
+ GLuint monitor,
+ GLenum pname,
+ GLsizei dataSize,
+ GLuint *data,
+ GLint *bytesWritten);
+angle::CallCapture CaptureGetPerfMonitorCounterInfoAMD(const State &glState,
+ bool isCallValid,
+ GLuint group,
+ GLuint counter,
+ GLenum pname,
+ void *data);
+angle::CallCapture CaptureGetPerfMonitorCounterStringAMD(const State &glState,
+ bool isCallValid,
+ GLuint group,
+ GLuint counter,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *counterString);
+angle::CallCapture CaptureGetPerfMonitorCountersAMD(const State &glState,
+ bool isCallValid,
+ GLuint group,
+ GLint *numCounters,
+ GLint *maxActiveCounters,
+ GLsizei counterSize,
+ GLuint *counters);
+angle::CallCapture CaptureGetPerfMonitorGroupStringAMD(const State &glState,
+ bool isCallValid,
+ GLuint group,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *groupString);
+angle::CallCapture CaptureGetPerfMonitorGroupsAMD(const State &glState,
+ bool isCallValid,
+ GLint *numGroups,
+ GLsizei groupsSize,
+ GLuint *groups);
+angle::CallCapture CaptureSelectPerfMonitorCountersAMD(const State &glState,
+ bool isCallValid,
+ GLuint monitor,
+ GLboolean enable,
+ GLuint group,
+ GLint numCounters,
+ GLuint *counterList);
+
+// GL_ANDROID_extension_pack_es31a
+
+// GL_ANGLE_base_vertex_base_instance
+angle::CallCapture CaptureDrawArraysInstancedBaseInstanceANGLE(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLint first,
+ GLsizei count,
+ GLsizei instanceCount,
+ GLuint baseInstance);
+angle::CallCapture CaptureDrawElementsInstancedBaseVertexBaseInstanceANGLE(
+ const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const GLvoid *indices,
+ GLsizei instanceCount,
+ GLint baseVertex,
+ GLuint baseInstance);
+angle::CallCapture CaptureMultiDrawArraysInstancedBaseInstanceANGLE(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const GLint *firsts,
+ const GLsizei *counts,
+ const GLsizei *instanceCounts,
+ const GLuint *baseInstances,
+ GLsizei drawcount);
+angle::CallCapture CaptureMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE(
+ const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const GLsizei *counts,
+ DrawElementsType typePacked,
+ const GLvoid *const *indices,
+ const GLsizei *instanceCounts,
+ const GLint *baseVertices,
+ const GLuint *baseInstances,
+ GLsizei drawcount);
+
+// GL_ANGLE_copy_texture_3d
+angle::CallCapture CaptureCopyTexture3DANGLE(const State &glState,
+ bool isCallValid,
+ TextureID sourceIdPacked,
+ GLint sourceLevel,
+ TextureTarget destTargetPacked,
+ TextureID destIdPacked,
+ GLint destLevel,
+ GLint internalFormat,
+ GLenum destType,
+ GLboolean unpackFlipY,
+ GLboolean unpackPremultiplyAlpha,
+ GLboolean unpackUnmultiplyAlpha);
+angle::CallCapture CaptureCopySubTexture3DANGLE(const State &glState,
+ bool isCallValid,
+ TextureID sourceIdPacked,
+ GLint sourceLevel,
+ TextureTarget destTargetPacked,
+ TextureID destIdPacked,
+ GLint destLevel,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLint x,
+ GLint y,
+ GLint z,
+ GLint width,
+ GLint height,
+ GLint depth,
+ GLboolean unpackFlipY,
+ GLboolean unpackPremultiplyAlpha,
+ GLboolean unpackUnmultiplyAlpha);
+
+// GL_ANGLE_depth_texture
+
+// GL_ANGLE_framebuffer_blit
+angle::CallCapture CaptureBlitFramebufferANGLE(const State &glState,
+ bool isCallValid,
+ GLint srcX0,
+ GLint srcY0,
+ GLint srcX1,
+ GLint srcY1,
+ GLint dstX0,
+ GLint dstY0,
+ GLint dstX1,
+ GLint dstY1,
+ GLbitfield mask,
+ GLenum filter);
+
+// GL_ANGLE_framebuffer_multisample
+angle::CallCapture CaptureRenderbufferStorageMultisampleANGLE(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height);
+
+// GL_ANGLE_get_image
+angle::CallCapture CaptureGetTexImageANGLE(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum format,
+ GLenum type,
+ void *pixels);
+angle::CallCapture CaptureGetCompressedTexImageANGLE(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ void *pixels);
+angle::CallCapture CaptureGetRenderbufferImageANGLE(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum format,
+ GLenum type,
+ void *pixels);
+
+// GL_ANGLE_get_tex_level_parameter
+angle::CallCapture CaptureGetTexLevelParameterivANGLE(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureGetTexLevelParameterfvANGLE(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum pname,
+ GLfloat *params);
+
+// GL_ANGLE_instanced_arrays
+angle::CallCapture CaptureDrawArraysInstancedANGLE(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLint first,
+ GLsizei count,
+ GLsizei primcount);
+angle::CallCapture CaptureDrawElementsInstancedANGLE(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLsizei primcount);
+angle::CallCapture CaptureVertexAttribDivisorANGLE(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLuint divisor);
+
+// GL_ANGLE_logic_op
+angle::CallCapture CaptureLogicOpANGLE(const State &glState,
+ bool isCallValid,
+ LogicalOperation opcodePacked);
+
+// GL_ANGLE_memory_object_flags
+angle::CallCapture CaptureTexStorageMemFlags2DANGLE(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ MemoryObjectID memoryPacked,
+ GLuint64 offset,
+ GLbitfield createFlags,
+ GLbitfield usageFlags,
+ const void *imageCreateInfoPNext);
+angle::CallCapture CaptureTexStorageMemFlags2DMultisampleANGLE(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedSampleLocations,
+ MemoryObjectID memoryPacked,
+ GLuint64 offset,
+ GLbitfield createFlags,
+ GLbitfield usageFlags,
+ const void *imageCreateInfoPNext);
+angle::CallCapture CaptureTexStorageMemFlags3DANGLE(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ MemoryObjectID memoryPacked,
+ GLuint64 offset,
+ GLbitfield createFlags,
+ GLbitfield usageFlags,
+ const void *imageCreateInfoPNext);
+angle::CallCapture CaptureTexStorageMemFlags3DMultisampleANGLE(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean fixedSampleLocations,
+ MemoryObjectID memoryPacked,
+ GLuint64 offset,
+ GLbitfield createFlags,
+ GLbitfield usageFlags,
+ const void *imageCreateInfoPNext);
+
+// GL_ANGLE_memory_object_fuchsia
+angle::CallCapture CaptureImportMemoryZirconHandleANGLE(const State &glState,
+ bool isCallValid,
+ MemoryObjectID memoryPacked,
+ GLuint64 size,
+ HandleType handleTypePacked,
+ GLuint handle);
+
+// GL_ANGLE_multi_draw
+angle::CallCapture CaptureMultiDrawArraysANGLE(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const GLint *firsts,
+ const GLsizei *counts,
+ GLsizei drawcount);
+angle::CallCapture CaptureMultiDrawArraysInstancedANGLE(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const GLint *firsts,
+ const GLsizei *counts,
+ const GLsizei *instanceCounts,
+ GLsizei drawcount);
+angle::CallCapture CaptureMultiDrawElementsANGLE(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const GLsizei *counts,
+ DrawElementsType typePacked,
+ const GLvoid *const *indices,
+ GLsizei drawcount);
+angle::CallCapture CaptureMultiDrawElementsInstancedANGLE(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const GLsizei *counts,
+ DrawElementsType typePacked,
+ const GLvoid *const *indices,
+ const GLsizei *instanceCounts,
+ GLsizei drawcount);
+
+// GL_ANGLE_pack_reverse_row_order
+
+// GL_ANGLE_program_binary
+
+// GL_ANGLE_provoking_vertex
+angle::CallCapture CaptureProvokingVertexANGLE(const State &glState,
+ bool isCallValid,
+ ProvokingVertexConvention modePacked);
+
+// GL_ANGLE_request_extension
+angle::CallCapture CaptureRequestExtensionANGLE(const State &glState,
+ bool isCallValid,
+ const GLchar *name);
+angle::CallCapture CaptureDisableExtensionANGLE(const State &glState,
+ bool isCallValid,
+ const GLchar *name);
+
+// GL_ANGLE_robust_client_memory
+angle::CallCapture CaptureGetBooleanvRobustANGLE(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLboolean *params);
+angle::CallCapture CaptureGetBufferParameterivRobustANGLE(const State &glState,
+ bool isCallValid,
+ BufferBinding targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+angle::CallCapture CaptureGetFloatvRobustANGLE(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params);
+angle::CallCapture CaptureGetFramebufferAttachmentParameterivRobustANGLE(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum attachment,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+angle::CallCapture CaptureGetIntegervRobustANGLE(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *data);
+angle::CallCapture CaptureGetProgramivRobustANGLE(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+angle::CallCapture CaptureGetRenderbufferParameterivRobustANGLE(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+angle::CallCapture CaptureGetShaderivRobustANGLE(const State &glState,
+ bool isCallValid,
+ ShaderProgramID shaderPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+angle::CallCapture CaptureGetTexParameterfvRobustANGLE(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params);
+angle::CallCapture CaptureGetTexParameterivRobustANGLE(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+angle::CallCapture CaptureGetUniformfvRobustANGLE(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params);
+angle::CallCapture CaptureGetUniformivRobustANGLE(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+angle::CallCapture CaptureGetVertexAttribfvRobustANGLE(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params);
+angle::CallCapture CaptureGetVertexAttribivRobustANGLE(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+angle::CallCapture CaptureGetVertexAttribPointervRobustANGLE(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ void **pointer);
+angle::CallCapture CaptureReadPixelsRobustANGLE(const State &glState,
+ bool isCallValid,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLsizei *columns,
+ GLsizei *rows,
+ void *pixels);
+angle::CallCapture CaptureTexImage2DRobustANGLE(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *pixels);
+angle::CallCapture CaptureTexParameterfvRobustANGLE(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLfloat *params);
+angle::CallCapture CaptureTexParameterivRobustANGLE(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLint *params);
+angle::CallCapture CaptureTexSubImage2DRobustANGLE(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *pixels);
+angle::CallCapture CaptureTexImage3DRobustANGLE(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *pixels);
+angle::CallCapture CaptureTexSubImage3DRobustANGLE(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *pixels);
+angle::CallCapture CaptureCompressedTexImage2DRobustANGLE(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLsizei imageSize,
+ GLsizei dataSize,
+ const GLvoid *data);
+angle::CallCapture CaptureCompressedTexSubImage2DRobustANGLE(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLsizei xoffset,
+ GLsizei yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLsizei imageSize,
+ GLsizei dataSize,
+ const GLvoid *data);
+angle::CallCapture CaptureCompressedTexImage3DRobustANGLE(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLsizei imageSize,
+ GLsizei dataSize,
+ const GLvoid *data);
+angle::CallCapture CaptureCompressedTexSubImage3DRobustANGLE(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLsizei imageSize,
+ GLsizei dataSize,
+ const GLvoid *data);
+angle::CallCapture CaptureGetQueryivRobustANGLE(const State &glState,
+ bool isCallValid,
+ QueryType targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+angle::CallCapture CaptureGetQueryObjectuivRobustANGLE(const State &glState,
+ bool isCallValid,
+ QueryID idPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint *params);
+angle::CallCapture CaptureGetBufferPointervRobustANGLE(const State &glState,
+ bool isCallValid,
+ BufferBinding targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ void **params);
+angle::CallCapture CaptureGetIntegeri_vRobustANGLE(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *data);
+angle::CallCapture CaptureGetInternalformativRobustANGLE(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum internalformat,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+angle::CallCapture CaptureGetVertexAttribIivRobustANGLE(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+angle::CallCapture CaptureGetVertexAttribIuivRobustANGLE(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint *params);
+angle::CallCapture CaptureGetUniformuivRobustANGLE(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint *params);
+angle::CallCapture CaptureGetActiveUniformBlockivRobustANGLE(
+ const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformBlockIndex uniformBlockIndexPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+angle::CallCapture CaptureGetInteger64vRobustANGLE(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint64 *data);
+angle::CallCapture CaptureGetInteger64i_vRobustANGLE(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint64 *data);
+angle::CallCapture CaptureGetBufferParameteri64vRobustANGLE(const State &glState,
+ bool isCallValid,
+ BufferBinding targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint64 *params);
+angle::CallCapture CaptureSamplerParameterivRobustANGLE(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLuint pname,
+ GLsizei bufSize,
+ const GLint *param);
+angle::CallCapture CaptureSamplerParameterfvRobustANGLE(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLfloat *param);
+angle::CallCapture CaptureGetSamplerParameterivRobustANGLE(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+angle::CallCapture CaptureGetSamplerParameterfvRobustANGLE(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params);
+angle::CallCapture CaptureGetFramebufferParameterivRobustANGLE(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+angle::CallCapture CaptureGetProgramInterfaceivRobustANGLE(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum programInterface,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+angle::CallCapture CaptureGetBooleani_vRobustANGLE(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLboolean *data);
+angle::CallCapture CaptureGetMultisamplefvRobustANGLE(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *val);
+angle::CallCapture CaptureGetTexLevelParameterivRobustANGLE(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+angle::CallCapture CaptureGetTexLevelParameterfvRobustANGLE(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params);
+angle::CallCapture CaptureGetPointervRobustANGLERobustANGLE(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ void **params);
+angle::CallCapture CaptureReadnPixelsRobustANGLE(const State &glState,
+ bool isCallValid,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLsizei *columns,
+ GLsizei *rows,
+ void *data);
+angle::CallCapture CaptureGetnUniformfvRobustANGLE(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params);
+angle::CallCapture CaptureGetnUniformivRobustANGLE(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+angle::CallCapture CaptureGetnUniformuivRobustANGLE(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint *params);
+angle::CallCapture CaptureTexParameterIivRobustANGLE(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLint *params);
+angle::CallCapture CaptureTexParameterIuivRobustANGLE(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLuint *params);
+angle::CallCapture CaptureGetTexParameterIivRobustANGLE(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+angle::CallCapture CaptureGetTexParameterIuivRobustANGLE(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint *params);
+angle::CallCapture CaptureSamplerParameterIivRobustANGLE(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLint *param);
+angle::CallCapture CaptureSamplerParameterIuivRobustANGLE(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLuint *param);
+angle::CallCapture CaptureGetSamplerParameterIivRobustANGLE(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+angle::CallCapture CaptureGetSamplerParameterIuivRobustANGLE(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint *params);
+angle::CallCapture CaptureGetQueryObjectivRobustANGLE(const State &glState,
+ bool isCallValid,
+ QueryID idPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+angle::CallCapture CaptureGetQueryObjecti64vRobustANGLE(const State &glState,
+ bool isCallValid,
+ QueryID idPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint64 *params);
+angle::CallCapture CaptureGetQueryObjectui64vRobustANGLE(const State &glState,
+ bool isCallValid,
+ QueryID idPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint64 *params);
+
+// GL_ANGLE_robust_resource_initialization
+
+// GL_ANGLE_semaphore_fuchsia
+angle::CallCapture CaptureImportSemaphoreZirconHandleANGLE(const State &glState,
+ bool isCallValid,
+ SemaphoreID semaphorePacked,
+ HandleType handleTypePacked,
+ GLuint handle);
+
+// GL_ANGLE_shader_pixel_local_storage
+angle::CallCapture CaptureFramebufferMemorylessPixelLocalStorageANGLE(const State &glState,
+ bool isCallValid,
+ GLint plane,
+ GLenum internalformat);
+angle::CallCapture CaptureFramebufferTexturePixelLocalStorageANGLE(const State &glState,
+ bool isCallValid,
+ GLint plane,
+ TextureID backingtexturePacked,
+ GLint level,
+ GLint layer);
+angle::CallCapture CaptureBeginPixelLocalStorageANGLE(const State &glState,
+ bool isCallValid,
+ GLsizei planes,
+ const GLenum *loadops,
+ const void *cleardata);
+angle::CallCapture CaptureEndPixelLocalStorageANGLE(const State &glState, bool isCallValid);
+angle::CallCapture CapturePixelLocalStorageBarrierANGLE(const State &glState, bool isCallValid);
+
+// GL_ANGLE_texture_compression_dxt3
+
+// GL_ANGLE_texture_compression_dxt5
+
+// GL_ANGLE_texture_external_update
+angle::CallCapture CaptureTexImage2DExternalANGLE(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLenum format,
+ GLenum type);
+angle::CallCapture CaptureInvalidateTextureANGLE(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked);
+
+// GL_ANGLE_texture_multisample
+angle::CallCapture CaptureTexStorage2DMultisampleANGLE(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedsamplelocations);
+angle::CallCapture CaptureGetMultisamplefvANGLE(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLuint index,
+ GLfloat *val);
+angle::CallCapture CaptureSampleMaskiANGLE(const State &glState,
+ bool isCallValid,
+ GLuint maskNumber,
+ GLbitfield mask);
+
+// GL_ANGLE_texture_usage
+
+// GL_ANGLE_translated_shader_source
+angle::CallCapture CaptureGetTranslatedShaderSourceANGLE(const State &glState,
+ bool isCallValid,
+ ShaderProgramID shaderPacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *source);
+
+// GL_ANGLE_vulkan_image
+angle::CallCapture CaptureAcquireTexturesANGLE(const State &glState,
+ bool isCallValid,
+ GLuint numTextures,
+ const TextureID *texturesPacked,
+ const GLenum *layouts);
+angle::CallCapture CaptureReleaseTexturesANGLE(const State &glState,
+ bool isCallValid,
+ GLuint numTextures,
+ const TextureID *texturesPacked,
+ GLenum *layouts);
+
+// GL_APPLE_clip_distance
+
+// GL_ARB_sync
+
+// GL_CHROMIUM_bind_uniform_location
+angle::CallCapture CaptureBindUniformLocationCHROMIUM(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ const GLchar *name);
+
+// GL_CHROMIUM_copy_compressed_texture
+angle::CallCapture CaptureCompressedCopyTextureCHROMIUM(const State &glState,
+ bool isCallValid,
+ TextureID sourceIdPacked,
+ TextureID destIdPacked);
+
+// GL_CHROMIUM_copy_texture
+angle::CallCapture CaptureCopyTextureCHROMIUM(const State &glState,
+ bool isCallValid,
+ TextureID sourceIdPacked,
+ GLint sourceLevel,
+ TextureTarget destTargetPacked,
+ TextureID destIdPacked,
+ GLint destLevel,
+ GLint internalFormat,
+ GLenum destType,
+ GLboolean unpackFlipY,
+ GLboolean unpackPremultiplyAlpha,
+ GLboolean unpackUnmultiplyAlpha);
+angle::CallCapture CaptureCopySubTextureCHROMIUM(const State &glState,
+ bool isCallValid,
+ TextureID sourceIdPacked,
+ GLint sourceLevel,
+ TextureTarget destTargetPacked,
+ TextureID destIdPacked,
+ GLint destLevel,
+ GLint xoffset,
+ GLint yoffset,
+ GLint x,
+ GLint y,
+ GLint width,
+ GLint height,
+ GLboolean unpackFlipY,
+ GLboolean unpackPremultiplyAlpha,
+ GLboolean unpackUnmultiplyAlpha);
+
+// GL_CHROMIUM_framebuffer_mixed_samples
+angle::CallCapture CaptureCoverageModulationCHROMIUM(const State &glState,
+ bool isCallValid,
+ GLenum components);
+
+// GL_CHROMIUM_lose_context
+angle::CallCapture CaptureLoseContextCHROMIUM(const State &glState,
+ bool isCallValid,
+ GraphicsResetStatus currentPacked,
+ GraphicsResetStatus otherPacked);
+
+// GL_EXT_EGL_image_array
+
+// GL_EXT_EGL_image_storage
+angle::CallCapture CaptureEGLImageTargetTexStorageEXT(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLeglImageOES image,
+ const GLint *attrib_list);
+angle::CallCapture CaptureEGLImageTargetTextureStorageEXT(const State &glState,
+ bool isCallValid,
+ GLuint texture,
+ GLeglImageOES image,
+ const GLint *attrib_list);
+
+// GL_EXT_YUV_target
+
+// GL_EXT_base_instance
+angle::CallCapture CaptureDrawArraysInstancedBaseInstanceEXT(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLint first,
+ GLsizei count,
+ GLsizei instancecount,
+ GLuint baseinstance);
+angle::CallCapture CaptureDrawElementsInstancedBaseInstanceEXT(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLsizei instancecount,
+ GLuint baseinstance);
+angle::CallCapture CaptureDrawElementsInstancedBaseVertexBaseInstanceEXT(
+ const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLsizei instancecount,
+ GLint basevertex,
+ GLuint baseinstance);
+
+// GL_EXT_blend_func_extended
+angle::CallCapture CaptureBindFragDataLocationEXT(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLuint color,
+ const GLchar *name);
+angle::CallCapture CaptureBindFragDataLocationIndexedEXT(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLuint colorNumber,
+ GLuint index,
+ const GLchar *name);
+angle::CallCapture CaptureGetFragDataIndexEXT(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ const GLchar *name,
+ GLint returnValue);
+angle::CallCapture CaptureGetProgramResourceLocationIndexEXT(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum programInterface,
+ const GLchar *name,
+ GLint returnValue);
+
+// GL_EXT_blend_minmax
+
+// GL_EXT_buffer_storage
+angle::CallCapture CaptureBufferStorageEXT(const State &glState,
+ bool isCallValid,
+ BufferBinding targetPacked,
+ GLsizeiptr size,
+ const void *data,
+ GLbitfield flags);
+
+// GL_EXT_clip_control
+angle::CallCapture CaptureClipControlEXT(const State &glState,
+ bool isCallValid,
+ GLenum origin,
+ GLenum depth);
+
+// GL_EXT_clip_cull_distance
+
+// GL_EXT_color_buffer_float
+
+// GL_EXT_color_buffer_half_float
+
+// GL_EXT_copy_image
+angle::CallCapture CaptureCopyImageSubDataEXT(const State &glState,
+ bool isCallValid,
+ GLuint srcName,
+ GLenum srcTarget,
+ GLint srcLevel,
+ GLint srcX,
+ GLint srcY,
+ GLint srcZ,
+ GLuint dstName,
+ GLenum dstTarget,
+ GLint dstLevel,
+ GLint dstX,
+ GLint dstY,
+ GLint dstZ,
+ GLsizei srcWidth,
+ GLsizei srcHeight,
+ GLsizei srcDepth);
+
+// GL_EXT_debug_label
+angle::CallCapture CaptureGetObjectLabelEXT(const State &glState,
+ bool isCallValid,
+ GLenum type,
+ GLuint object,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *label);
+angle::CallCapture CaptureLabelObjectEXT(const State &glState,
+ bool isCallValid,
+ GLenum type,
+ GLuint object,
+ GLsizei length,
+ const GLchar *label);
+
+// GL_EXT_debug_marker
+angle::CallCapture CaptureInsertEventMarkerEXT(const State &glState,
+ bool isCallValid,
+ GLsizei length,
+ const GLchar *marker);
+angle::CallCapture CapturePopGroupMarkerEXT(const State &glState, bool isCallValid);
+angle::CallCapture CapturePushGroupMarkerEXT(const State &glState,
+ bool isCallValid,
+ GLsizei length,
+ const GLchar *marker);
+
+// GL_EXT_discard_framebuffer
+angle::CallCapture CaptureDiscardFramebufferEXT(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLsizei numAttachments,
+ const GLenum *attachments);
+
+// GL_EXT_disjoint_timer_query
+angle::CallCapture CaptureBeginQueryEXT(const State &glState,
+ bool isCallValid,
+ QueryType targetPacked,
+ QueryID idPacked);
+angle::CallCapture CaptureDeleteQueriesEXT(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ const QueryID *idsPacked);
+angle::CallCapture CaptureEndQueryEXT(const State &glState,
+ bool isCallValid,
+ QueryType targetPacked);
+angle::CallCapture CaptureGenQueriesEXT(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ QueryID *idsPacked);
+angle::CallCapture CaptureGetInteger64vEXT(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLint64 *data);
+angle::CallCapture CaptureGetQueryObjecti64vEXT(const State &glState,
+ bool isCallValid,
+ QueryID idPacked,
+ GLenum pname,
+ GLint64 *params);
+angle::CallCapture CaptureGetQueryObjectivEXT(const State &glState,
+ bool isCallValid,
+ QueryID idPacked,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureGetQueryObjectui64vEXT(const State &glState,
+ bool isCallValid,
+ QueryID idPacked,
+ GLenum pname,
+ GLuint64 *params);
+angle::CallCapture CaptureGetQueryObjectuivEXT(const State &glState,
+ bool isCallValid,
+ QueryID idPacked,
+ GLenum pname,
+ GLuint *params);
+angle::CallCapture CaptureGetQueryivEXT(const State &glState,
+ bool isCallValid,
+ QueryType targetPacked,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureIsQueryEXT(const State &glState,
+ bool isCallValid,
+ QueryID idPacked,
+ GLboolean returnValue);
+angle::CallCapture CaptureQueryCounterEXT(const State &glState,
+ bool isCallValid,
+ QueryID idPacked,
+ QueryType targetPacked);
+
+// GL_EXT_draw_buffers
+angle::CallCapture CaptureDrawBuffersEXT(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ const GLenum *bufs);
+
+// GL_EXT_draw_buffers_indexed
+angle::CallCapture CaptureBlendEquationSeparateiEXT(const State &glState,
+ bool isCallValid,
+ GLuint buf,
+ GLenum modeRGB,
+ GLenum modeAlpha);
+angle::CallCapture CaptureBlendEquationiEXT(const State &glState,
+ bool isCallValid,
+ GLuint buf,
+ GLenum mode);
+angle::CallCapture CaptureBlendFuncSeparateiEXT(const State &glState,
+ bool isCallValid,
+ GLuint buf,
+ GLenum srcRGB,
+ GLenum dstRGB,
+ GLenum srcAlpha,
+ GLenum dstAlpha);
+angle::CallCapture CaptureBlendFunciEXT(const State &glState,
+ bool isCallValid,
+ GLuint buf,
+ GLenum src,
+ GLenum dst);
+angle::CallCapture CaptureColorMaskiEXT(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLboolean r,
+ GLboolean g,
+ GLboolean b,
+ GLboolean a);
+angle::CallCapture CaptureDisableiEXT(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLuint index);
+angle::CallCapture CaptureEnableiEXT(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLuint index);
+angle::CallCapture CaptureIsEnablediEXT(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLuint index,
+ GLboolean returnValue);
+
+// GL_EXT_draw_elements_base_vertex
+angle::CallCapture CaptureDrawElementsBaseVertexEXT(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLint basevertex);
+angle::CallCapture CaptureDrawElementsInstancedBaseVertexEXT(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLsizei instancecount,
+ GLint basevertex);
+angle::CallCapture CaptureDrawRangeElementsBaseVertexEXT(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLint basevertex);
+angle::CallCapture CaptureMultiDrawElementsBaseVertexEXT(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const GLsizei *count,
+ DrawElementsType typePacked,
+ const void *const *indices,
+ GLsizei drawcount,
+ const GLint *basevertex);
+
+// GL_EXT_external_buffer
+angle::CallCapture CaptureBufferStorageExternalEXT(const State &glState,
+ bool isCallValid,
+ BufferBinding targetPacked,
+ GLintptr offset,
+ GLsizeiptr size,
+ GLeglClientBufferEXT clientBuffer,
+ GLbitfield flags);
+angle::CallCapture CaptureNamedBufferStorageExternalEXT(const State &glState,
+ bool isCallValid,
+ GLuint buffer,
+ GLintptr offset,
+ GLsizeiptr size,
+ GLeglClientBufferEXT clientBuffer,
+ GLbitfield flags);
+
+// GL_EXT_float_blend
+
+// GL_EXT_geometry_shader
+angle::CallCapture CaptureFramebufferTextureEXT(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum attachment,
+ TextureID texturePacked,
+ GLint level);
+
+// GL_EXT_gpu_shader5
+
+// GL_EXT_instanced_arrays
+angle::CallCapture CaptureDrawArraysInstancedEXT(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLint start,
+ GLsizei count,
+ GLsizei primcount);
+angle::CallCapture CaptureDrawElementsInstancedEXT(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLsizei primcount);
+angle::CallCapture CaptureVertexAttribDivisorEXT(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLuint divisor);
+
+// GL_EXT_map_buffer_range
+angle::CallCapture CaptureFlushMappedBufferRangeEXT(const State &glState,
+ bool isCallValid,
+ BufferBinding targetPacked,
+ GLintptr offset,
+ GLsizeiptr length);
+angle::CallCapture CaptureMapBufferRangeEXT(const State &glState,
+ bool isCallValid,
+ BufferBinding targetPacked,
+ GLintptr offset,
+ GLsizeiptr length,
+ GLbitfield access,
+ void *returnValue);
+
+// GL_EXT_memory_object
+angle::CallCapture CaptureBufferStorageMemEXT(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLsizeiptr size,
+ MemoryObjectID memoryPacked,
+ GLuint64 offset);
+angle::CallCapture CaptureCreateMemoryObjectsEXT(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ MemoryObjectID *memoryObjectsPacked);
+angle::CallCapture CaptureDeleteMemoryObjectsEXT(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ const MemoryObjectID *memoryObjectsPacked);
+angle::CallCapture CaptureGetMemoryObjectParameterivEXT(const State &glState,
+ bool isCallValid,
+ MemoryObjectID memoryObjectPacked,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureGetUnsignedBytevEXT(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLubyte *data);
+angle::CallCapture CaptureGetUnsignedBytei_vEXT(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLuint index,
+ GLubyte *data);
+angle::CallCapture CaptureIsMemoryObjectEXT(const State &glState,
+ bool isCallValid,
+ MemoryObjectID memoryObjectPacked,
+ GLboolean returnValue);
+angle::CallCapture CaptureMemoryObjectParameterivEXT(const State &glState,
+ bool isCallValid,
+ MemoryObjectID memoryObjectPacked,
+ GLenum pname,
+ const GLint *params);
+angle::CallCapture CaptureTexStorageMem2DEXT(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ MemoryObjectID memoryPacked,
+ GLuint64 offset);
+angle::CallCapture CaptureTexStorageMem2DMultisampleEXT(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedSampleLocations,
+ MemoryObjectID memoryPacked,
+ GLuint64 offset);
+angle::CallCapture CaptureTexStorageMem3DEXT(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ MemoryObjectID memoryPacked,
+ GLuint64 offset);
+angle::CallCapture CaptureTexStorageMem3DMultisampleEXT(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean fixedSampleLocations,
+ MemoryObjectID memoryPacked,
+ GLuint64 offset);
+
+// GL_EXT_memory_object_fd
+angle::CallCapture CaptureImportMemoryFdEXT(const State &glState,
+ bool isCallValid,
+ MemoryObjectID memoryPacked,
+ GLuint64 size,
+ HandleType handleTypePacked,
+ GLint fd);
+
+// GL_EXT_multi_draw_indirect
+angle::CallCapture CaptureMultiDrawArraysIndirectEXT(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const void *indirect,
+ GLsizei drawcount,
+ GLsizei stride);
+angle::CallCapture CaptureMultiDrawElementsIndirectEXT(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ DrawElementsType typePacked,
+ const void *indirect,
+ GLsizei drawcount,
+ GLsizei stride);
+
+// GL_EXT_multisampled_render_to_texture
+angle::CallCapture CaptureFramebufferTexture2DMultisampleEXT(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum attachment,
+ TextureTarget textargetPacked,
+ TextureID texturePacked,
+ GLint level,
+ GLsizei samples);
+angle::CallCapture CaptureRenderbufferStorageMultisampleEXT(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height);
+
+// GL_EXT_multisampled_render_to_texture2
+
+// GL_EXT_occlusion_query_boolean
+
+// GL_EXT_primitive_bounding_box
+angle::CallCapture CapturePrimitiveBoundingBoxEXT(const State &glState,
+ bool isCallValid,
+ GLfloat minX,
+ GLfloat minY,
+ GLfloat minZ,
+ GLfloat minW,
+ GLfloat maxX,
+ GLfloat maxY,
+ GLfloat maxZ,
+ GLfloat maxW);
+
+// GL_EXT_protected_textures
+
+// GL_EXT_pvrtc_sRGB
+
+// GL_EXT_read_format_bgra
+
+// GL_EXT_robustness
+angle::CallCapture CaptureGetGraphicsResetStatusEXT(const State &glState,
+ bool isCallValid,
+ GLenum returnValue);
+angle::CallCapture CaptureGetnUniformfvEXT(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei bufSize,
+ GLfloat *params);
+angle::CallCapture CaptureGetnUniformivEXT(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei bufSize,
+ GLint *params);
+angle::CallCapture CaptureReadnPixelsEXT(const State &glState,
+ bool isCallValid,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ void *data);
+
+// GL_EXT_sRGB
+
+// GL_EXT_sRGB_write_control
+
+// GL_EXT_semaphore
+angle::CallCapture CaptureDeleteSemaphoresEXT(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ const SemaphoreID *semaphoresPacked);
+angle::CallCapture CaptureGenSemaphoresEXT(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ SemaphoreID *semaphoresPacked);
+angle::CallCapture CaptureGetSemaphoreParameterui64vEXT(const State &glState,
+ bool isCallValid,
+ SemaphoreID semaphorePacked,
+ GLenum pname,
+ GLuint64 *params);
+angle::CallCapture CaptureIsSemaphoreEXT(const State &glState,
+ bool isCallValid,
+ SemaphoreID semaphorePacked,
+ GLboolean returnValue);
+angle::CallCapture CaptureSemaphoreParameterui64vEXT(const State &glState,
+ bool isCallValid,
+ SemaphoreID semaphorePacked,
+ GLenum pname,
+ const GLuint64 *params);
+angle::CallCapture CaptureSignalSemaphoreEXT(const State &glState,
+ bool isCallValid,
+ SemaphoreID semaphorePacked,
+ GLuint numBufferBarriers,
+ const BufferID *buffersPacked,
+ GLuint numTextureBarriers,
+ const TextureID *texturesPacked,
+ const GLenum *dstLayouts);
+angle::CallCapture CaptureWaitSemaphoreEXT(const State &glState,
+ bool isCallValid,
+ SemaphoreID semaphorePacked,
+ GLuint numBufferBarriers,
+ const BufferID *buffersPacked,
+ GLuint numTextureBarriers,
+ const TextureID *texturesPacked,
+ const GLenum *srcLayouts);
+
+// GL_EXT_semaphore_fd
+angle::CallCapture CaptureImportSemaphoreFdEXT(const State &glState,
+ bool isCallValid,
+ SemaphoreID semaphorePacked,
+ HandleType handleTypePacked,
+ GLint fd);
+
+// GL_EXT_separate_shader_objects
+angle::CallCapture CaptureActiveShaderProgramEXT(const State &glState,
+ bool isCallValid,
+ ProgramPipelineID pipelinePacked,
+ ShaderProgramID programPacked);
+angle::CallCapture CaptureBindProgramPipelineEXT(const State &glState,
+ bool isCallValid,
+ ProgramPipelineID pipelinePacked);
+angle::CallCapture CaptureCreateShaderProgramvEXT(const State &glState,
+ bool isCallValid,
+ ShaderType typePacked,
+ GLsizei count,
+ const GLchar **strings,
+ GLuint returnValue);
+angle::CallCapture CaptureDeleteProgramPipelinesEXT(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ const ProgramPipelineID *pipelinesPacked);
+angle::CallCapture CaptureGenProgramPipelinesEXT(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ ProgramPipelineID *pipelinesPacked);
+angle::CallCapture CaptureGetProgramPipelineInfoLogEXT(const State &glState,
+ bool isCallValid,
+ ProgramPipelineID pipelinePacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *infoLog);
+angle::CallCapture CaptureGetProgramPipelineivEXT(const State &glState,
+ bool isCallValid,
+ ProgramPipelineID pipelinePacked,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureIsProgramPipelineEXT(const State &glState,
+ bool isCallValid,
+ ProgramPipelineID pipelinePacked,
+ GLboolean returnValue);
+angle::CallCapture CaptureProgramParameteriEXT(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum pname,
+ GLint value);
+angle::CallCapture CaptureProgramUniform1fEXT(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLfloat v0);
+angle::CallCapture CaptureProgramUniform1fvEXT(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value);
+angle::CallCapture CaptureProgramUniform1iEXT(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLint v0);
+angle::CallCapture CaptureProgramUniform1ivEXT(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value);
+angle::CallCapture CaptureProgramUniform1uiEXT(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLuint v0);
+angle::CallCapture CaptureProgramUniform1uivEXT(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value);
+angle::CallCapture CaptureProgramUniform2fEXT(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLfloat v0,
+ GLfloat v1);
+angle::CallCapture CaptureProgramUniform2fvEXT(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value);
+angle::CallCapture CaptureProgramUniform2iEXT(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLint v0,
+ GLint v1);
+angle::CallCapture CaptureProgramUniform2ivEXT(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value);
+angle::CallCapture CaptureProgramUniform2uiEXT(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLuint v0,
+ GLuint v1);
+angle::CallCapture CaptureProgramUniform2uivEXT(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value);
+angle::CallCapture CaptureProgramUniform3fEXT(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLfloat v0,
+ GLfloat v1,
+ GLfloat v2);
+angle::CallCapture CaptureProgramUniform3fvEXT(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value);
+angle::CallCapture CaptureProgramUniform3iEXT(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLint v0,
+ GLint v1,
+ GLint v2);
+angle::CallCapture CaptureProgramUniform3ivEXT(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value);
+angle::CallCapture CaptureProgramUniform3uiEXT(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLuint v0,
+ GLuint v1,
+ GLuint v2);
+angle::CallCapture CaptureProgramUniform3uivEXT(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value);
+angle::CallCapture CaptureProgramUniform4fEXT(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLfloat v0,
+ GLfloat v1,
+ GLfloat v2,
+ GLfloat v3);
+angle::CallCapture CaptureProgramUniform4fvEXT(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value);
+angle::CallCapture CaptureProgramUniform4iEXT(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLint v0,
+ GLint v1,
+ GLint v2,
+ GLint v3);
+angle::CallCapture CaptureProgramUniform4ivEXT(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value);
+angle::CallCapture CaptureProgramUniform4uiEXT(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLuint v0,
+ GLuint v1,
+ GLuint v2,
+ GLuint v3);
+angle::CallCapture CaptureProgramUniform4uivEXT(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value);
+angle::CallCapture CaptureProgramUniformMatrix2fvEXT(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+angle::CallCapture CaptureProgramUniformMatrix2x3fvEXT(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+angle::CallCapture CaptureProgramUniformMatrix2x4fvEXT(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+angle::CallCapture CaptureProgramUniformMatrix3fvEXT(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+angle::CallCapture CaptureProgramUniformMatrix3x2fvEXT(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+angle::CallCapture CaptureProgramUniformMatrix3x4fvEXT(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+angle::CallCapture CaptureProgramUniformMatrix4fvEXT(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+angle::CallCapture CaptureProgramUniformMatrix4x2fvEXT(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+angle::CallCapture CaptureProgramUniformMatrix4x3fvEXT(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+angle::CallCapture CaptureUseProgramStagesEXT(const State &glState,
+ bool isCallValid,
+ ProgramPipelineID pipelinePacked,
+ GLbitfield stages,
+ ShaderProgramID programPacked);
+angle::CallCapture CaptureValidateProgramPipelineEXT(const State &glState,
+ bool isCallValid,
+ ProgramPipelineID pipelinePacked);
+
+// GL_EXT_shader_framebuffer_fetch
+
+// GL_EXT_shader_framebuffer_fetch_non_coherent
+angle::CallCapture CaptureFramebufferFetchBarrierEXT(const State &glState, bool isCallValid);
+
+// GL_EXT_shader_io_blocks
+
+// GL_EXT_shader_non_constant_global_initializers
+
+// GL_EXT_shader_texture_lod
+
+// GL_EXT_shadow_samplers
+
+// GL_EXT_tessellation_shader
+angle::CallCapture CapturePatchParameteriEXT(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLint value);
+
+// GL_EXT_texture_border_clamp
+angle::CallCapture CaptureGetSamplerParameterIivEXT(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureGetSamplerParameterIuivEXT(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLuint *params);
+angle::CallCapture CaptureGetTexParameterIivEXT(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureGetTexParameterIuivEXT(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ GLuint *params);
+angle::CallCapture CaptureSamplerParameterIivEXT(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ const GLint *param);
+angle::CallCapture CaptureSamplerParameterIuivEXT(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ const GLuint *param);
+angle::CallCapture CaptureTexParameterIivEXT(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLint *params);
+angle::CallCapture CaptureTexParameterIuivEXT(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLuint *params);
+
+// GL_EXT_texture_buffer
+angle::CallCapture CaptureTexBufferEXT(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum internalformat,
+ BufferID bufferPacked);
+angle::CallCapture CaptureTexBufferRangeEXT(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum internalformat,
+ BufferID bufferPacked,
+ GLintptr offset,
+ GLsizeiptr size);
+
+// GL_EXT_texture_compression_bptc
+
+// GL_EXT_texture_compression_dxt1
+
+// GL_EXT_texture_compression_rgtc
+
+// GL_EXT_texture_compression_s3tc
+
+// GL_EXT_texture_compression_s3tc_srgb
+
+// GL_EXT_texture_cube_map_array
+
+// GL_EXT_texture_filter_anisotropic
+
+// GL_EXT_texture_format_BGRA8888
+
+// GL_EXT_texture_format_sRGB_override
+
+// GL_EXT_texture_norm16
+
+// GL_EXT_texture_rg
+
+// GL_EXT_texture_sRGB_R8
+
+// GL_EXT_texture_sRGB_RG8
+
+// GL_EXT_texture_sRGB_decode
+
+// GL_EXT_texture_storage
+angle::CallCapture CaptureTexStorage1DEXT(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width);
+angle::CallCapture CaptureTexStorage2DEXT(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height);
+angle::CallCapture CaptureTexStorage3DEXT(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth);
+
+// GL_EXT_texture_type_2_10_10_10_REV
+
+// GL_EXT_unpack_subimage
+
+// GL_IMG_texture_compression_pvrtc
+
+// GL_IMG_texture_compression_pvrtc2
+
+// GL_KHR_blend_equation_advanced
+angle::CallCapture CaptureBlendBarrierKHR(const State &glState, bool isCallValid);
+
+// GL_KHR_debug
+angle::CallCapture CaptureDebugMessageCallbackKHR(const State &glState,
+ bool isCallValid,
+ GLDEBUGPROCKHR callback,
+ const void *userParam);
+angle::CallCapture CaptureDebugMessageControlKHR(const State &glState,
+ bool isCallValid,
+ GLenum source,
+ GLenum type,
+ GLenum severity,
+ GLsizei count,
+ const GLuint *ids,
+ GLboolean enabled);
+angle::CallCapture CaptureDebugMessageInsertKHR(const State &glState,
+ bool isCallValid,
+ GLenum source,
+ GLenum type,
+ GLuint id,
+ GLenum severity,
+ GLsizei length,
+ const GLchar *buf);
+angle::CallCapture CaptureGetDebugMessageLogKHR(const State &glState,
+ bool isCallValid,
+ GLuint count,
+ GLsizei bufSize,
+ GLenum *sources,
+ GLenum *types,
+ GLuint *ids,
+ GLenum *severities,
+ GLsizei *lengths,
+ GLchar *messageLog,
+ GLuint returnValue);
+angle::CallCapture CaptureGetObjectLabelKHR(const State &glState,
+ bool isCallValid,
+ GLenum identifier,
+ GLuint name,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *label);
+angle::CallCapture CaptureGetObjectPtrLabelKHR(const State &glState,
+ bool isCallValid,
+ const void *ptr,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *label);
+angle::CallCapture CaptureGetPointervKHR(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ void **params);
+angle::CallCapture CaptureObjectLabelKHR(const State &glState,
+ bool isCallValid,
+ GLenum identifier,
+ GLuint name,
+ GLsizei length,
+ const GLchar *label);
+angle::CallCapture CaptureObjectPtrLabelKHR(const State &glState,
+ bool isCallValid,
+ const void *ptr,
+ GLsizei length,
+ const GLchar *label);
+angle::CallCapture CapturePopDebugGroupKHR(const State &glState, bool isCallValid);
+angle::CallCapture CapturePushDebugGroupKHR(const State &glState,
+ bool isCallValid,
+ GLenum source,
+ GLuint id,
+ GLsizei length,
+ const GLchar *message);
+
+// GL_KHR_no_error
+
+// GL_KHR_parallel_shader_compile
+angle::CallCapture CaptureMaxShaderCompilerThreadsKHR(const State &glState,
+ bool isCallValid,
+ GLuint count);
+
+// GL_KHR_robust_buffer_access_behavior
+
+// GL_KHR_texture_compression_astc_hdr
+
+// GL_KHR_texture_compression_astc_ldr
+
+// GL_KHR_texture_compression_astc_sliced_3d
+
+// GL_MESA_framebuffer_flip_y
+angle::CallCapture CaptureFramebufferParameteriMESA(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum pname,
+ GLint param);
+angle::CallCapture CaptureGetFramebufferParameterivMESA(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum pname,
+ GLint *params);
+
+// GL_NV_fence
+angle::CallCapture CaptureDeleteFencesNV(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ const FenceNVID *fencesPacked);
+angle::CallCapture CaptureFinishFenceNV(const State &glState,
+ bool isCallValid,
+ FenceNVID fencePacked);
+angle::CallCapture CaptureGenFencesNV(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ FenceNVID *fencesPacked);
+angle::CallCapture CaptureGetFenceivNV(const State &glState,
+ bool isCallValid,
+ FenceNVID fencePacked,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureIsFenceNV(const State &glState,
+ bool isCallValid,
+ FenceNVID fencePacked,
+ GLboolean returnValue);
+angle::CallCapture CaptureSetFenceNV(const State &glState,
+ bool isCallValid,
+ FenceNVID fencePacked,
+ GLenum condition);
+angle::CallCapture CaptureTestFenceNV(const State &glState,
+ bool isCallValid,
+ FenceNVID fencePacked,
+ GLboolean returnValue);
+
+// GL_NV_framebuffer_blit
+angle::CallCapture CaptureBlitFramebufferNV(const State &glState,
+ bool isCallValid,
+ GLint srcX0,
+ GLint srcY0,
+ GLint srcX1,
+ GLint srcY1,
+ GLint dstX0,
+ GLint dstY0,
+ GLint dstX1,
+ GLint dstY1,
+ GLbitfield mask,
+ GLenum filter);
+
+// GL_NV_pixel_buffer_object
+
+// GL_NV_read_depth
+
+// GL_NV_read_depth_stencil
+
+// GL_NV_read_stencil
+
+// GL_NV_robustness_video_memory_purge
+
+// GL_NV_shader_noperspective_interpolation
+
+// GL_OES_EGL_image
+angle::CallCapture CaptureEGLImageTargetRenderbufferStorageOES(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLeglImageOES image);
+angle::CallCapture CaptureEGLImageTargetTexture2DOES(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLeglImageOES image);
+
+// GL_OES_EGL_image_external
+
+// GL_OES_EGL_image_external_essl3
+
+// GL_OES_compressed_ETC1_RGB8_texture
+
+// GL_OES_compressed_paletted_texture
+
+// GL_OES_copy_image
+angle::CallCapture CaptureCopyImageSubDataOES(const State &glState,
+ bool isCallValid,
+ GLuint srcName,
+ GLenum srcTarget,
+ GLint srcLevel,
+ GLint srcX,
+ GLint srcY,
+ GLint srcZ,
+ GLuint dstName,
+ GLenum dstTarget,
+ GLint dstLevel,
+ GLint dstX,
+ GLint dstY,
+ GLint dstZ,
+ GLsizei srcWidth,
+ GLsizei srcHeight,
+ GLsizei srcDepth);
+
+// GL_OES_depth24
+
+// GL_OES_depth32
+
+// GL_OES_depth_texture
+
+// GL_OES_draw_buffers_indexed
+angle::CallCapture CaptureBlendEquationSeparateiOES(const State &glState,
+ bool isCallValid,
+ GLuint buf,
+ GLenum modeRGB,
+ GLenum modeAlpha);
+angle::CallCapture CaptureBlendEquationiOES(const State &glState,
+ bool isCallValid,
+ GLuint buf,
+ GLenum mode);
+angle::CallCapture CaptureBlendFuncSeparateiOES(const State &glState,
+ bool isCallValid,
+ GLuint buf,
+ GLenum srcRGB,
+ GLenum dstRGB,
+ GLenum srcAlpha,
+ GLenum dstAlpha);
+angle::CallCapture CaptureBlendFunciOES(const State &glState,
+ bool isCallValid,
+ GLuint buf,
+ GLenum src,
+ GLenum dst);
+angle::CallCapture CaptureColorMaskiOES(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLboolean r,
+ GLboolean g,
+ GLboolean b,
+ GLboolean a);
+angle::CallCapture CaptureDisableiOES(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLuint index);
+angle::CallCapture CaptureEnableiOES(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLuint index);
+angle::CallCapture CaptureIsEnablediOES(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLuint index,
+ GLboolean returnValue);
+
+// GL_OES_draw_elements_base_vertex
+angle::CallCapture CaptureDrawElementsBaseVertexOES(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLint basevertex);
+angle::CallCapture CaptureDrawElementsInstancedBaseVertexOES(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLsizei instancecount,
+ GLint basevertex);
+angle::CallCapture CaptureDrawRangeElementsBaseVertexOES(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLint basevertex);
+
+// GL_OES_draw_texture
+angle::CallCapture CaptureDrawTexfOES(const State &glState,
+ bool isCallValid,
+ GLfloat x,
+ GLfloat y,
+ GLfloat z,
+ GLfloat width,
+ GLfloat height);
+angle::CallCapture CaptureDrawTexfvOES(const State &glState,
+ bool isCallValid,
+ const GLfloat *coords);
+angle::CallCapture CaptureDrawTexiOES(const State &glState,
+ bool isCallValid,
+ GLint x,
+ GLint y,
+ GLint z,
+ GLint width,
+ GLint height);
+angle::CallCapture CaptureDrawTexivOES(const State &glState, bool isCallValid, const GLint *coords);
+angle::CallCapture CaptureDrawTexsOES(const State &glState,
+ bool isCallValid,
+ GLshort x,
+ GLshort y,
+ GLshort z,
+ GLshort width,
+ GLshort height);
+angle::CallCapture CaptureDrawTexsvOES(const State &glState,
+ bool isCallValid,
+ const GLshort *coords);
+angle::CallCapture CaptureDrawTexxOES(const State &glState,
+ bool isCallValid,
+ GLfixed x,
+ GLfixed y,
+ GLfixed z,
+ GLfixed width,
+ GLfixed height);
+angle::CallCapture CaptureDrawTexxvOES(const State &glState,
+ bool isCallValid,
+ const GLfixed *coords);
+
+// GL_OES_element_index_uint
+
+// GL_OES_fbo_render_mipmap
+
+// GL_OES_framebuffer_object
+angle::CallCapture CaptureBindFramebufferOES(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ FramebufferID framebufferPacked);
+angle::CallCapture CaptureBindRenderbufferOES(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ RenderbufferID renderbufferPacked);
+angle::CallCapture CaptureCheckFramebufferStatusOES(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum returnValue);
+angle::CallCapture CaptureDeleteFramebuffersOES(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ const FramebufferID *framebuffersPacked);
+angle::CallCapture CaptureDeleteRenderbuffersOES(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ const RenderbufferID *renderbuffersPacked);
+angle::CallCapture CaptureFramebufferRenderbufferOES(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum attachment,
+ GLenum renderbuffertarget,
+ RenderbufferID renderbufferPacked);
+angle::CallCapture CaptureFramebufferTexture2DOES(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum attachment,
+ TextureTarget textargetPacked,
+ TextureID texturePacked,
+ GLint level);
+angle::CallCapture CaptureGenFramebuffersOES(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ FramebufferID *framebuffersPacked);
+angle::CallCapture CaptureGenRenderbuffersOES(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ RenderbufferID *renderbuffersPacked);
+angle::CallCapture CaptureGenerateMipmapOES(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked);
+angle::CallCapture CaptureGetFramebufferAttachmentParameterivOES(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum attachment,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureGetRenderbufferParameterivOES(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureIsFramebufferOES(const State &glState,
+ bool isCallValid,
+ FramebufferID framebufferPacked,
+ GLboolean returnValue);
+angle::CallCapture CaptureIsRenderbufferOES(const State &glState,
+ bool isCallValid,
+ RenderbufferID renderbufferPacked,
+ GLboolean returnValue);
+angle::CallCapture CaptureRenderbufferStorageOES(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height);
+
+// GL_OES_geometry_shader
+angle::CallCapture CaptureFramebufferTextureOES(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum attachment,
+ TextureID texturePacked,
+ GLint level);
+
+// GL_OES_get_program_binary
+angle::CallCapture CaptureGetProgramBinaryOES(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLenum *binaryFormat,
+ void *binary);
+angle::CallCapture CaptureProgramBinaryOES(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum binaryFormat,
+ const void *binary,
+ GLint length);
+
+// GL_OES_mapbuffer
+angle::CallCapture CaptureGetBufferPointervOES(const State &glState,
+ bool isCallValid,
+ BufferBinding targetPacked,
+ GLenum pname,
+ void **params);
+angle::CallCapture CaptureMapBufferOES(const State &glState,
+ bool isCallValid,
+ BufferBinding targetPacked,
+ GLenum access,
+ void *returnValue);
+angle::CallCapture CaptureUnmapBufferOES(const State &glState,
+ bool isCallValid,
+ BufferBinding targetPacked,
+ GLboolean returnValue);
+
+// GL_OES_matrix_palette
+angle::CallCapture CaptureCurrentPaletteMatrixOES(const State &glState,
+ bool isCallValid,
+ GLuint matrixpaletteindex);
+angle::CallCapture CaptureLoadPaletteFromModelViewMatrixOES(const State &glState, bool isCallValid);
+angle::CallCapture CaptureMatrixIndexPointerOES(const State &glState,
+ bool isCallValid,
+ GLint size,
+ GLenum type,
+ GLsizei stride,
+ const void *pointer);
+angle::CallCapture CaptureWeightPointerOES(const State &glState,
+ bool isCallValid,
+ GLint size,
+ GLenum type,
+ GLsizei stride,
+ const void *pointer);
+
+// GL_OES_packed_depth_stencil
+
+// GL_OES_point_size_array
+angle::CallCapture CapturePointSizePointerOES(const State &glState,
+ bool isCallValid,
+ VertexAttribType typePacked,
+ GLsizei stride,
+ const void *pointer);
+
+// GL_OES_point_sprite
+
+// GL_OES_primitive_bounding_box
+angle::CallCapture CapturePrimitiveBoundingBoxOES(const State &glState,
+ bool isCallValid,
+ GLfloat minX,
+ GLfloat minY,
+ GLfloat minZ,
+ GLfloat minW,
+ GLfloat maxX,
+ GLfloat maxY,
+ GLfloat maxZ,
+ GLfloat maxW);
+
+// GL_OES_query_matrix
+angle::CallCapture CaptureQueryMatrixxOES(const State &glState,
+ bool isCallValid,
+ GLfixed *mantissa,
+ GLint *exponent,
+ GLbitfield returnValue);
+
+// GL_OES_rgb8_rgba8
+
+// GL_OES_sample_shading
+angle::CallCapture CaptureMinSampleShadingOES(const State &glState,
+ bool isCallValid,
+ GLfloat value);
+
+// GL_OES_sample_variables
+
+// GL_OES_shader_image_atomic
+
+// GL_OES_shader_io_blocks
+
+// GL_OES_shader_multisample_interpolation
+
+// GL_OES_standard_derivatives
+
+// GL_OES_surfaceless_context
+
+// GL_OES_texture_3D
+angle::CallCapture CaptureCompressedTexImage3DOES(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLsizei imageSize,
+ const void *data);
+angle::CallCapture CaptureCompressedTexSubImage3DOES(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data);
+angle::CallCapture CaptureCopyTexSubImage3DOES(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height);
+angle::CallCapture CaptureFramebufferTexture3DOES(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum attachment,
+ TextureTarget textargetPacked,
+ TextureID texturePacked,
+ GLint level,
+ GLint zoffset);
+angle::CallCapture CaptureTexImage3DOES(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const void *pixels);
+angle::CallCapture CaptureTexSubImage3DOES(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ const void *pixels);
+
+// GL_OES_texture_border_clamp
+angle::CallCapture CaptureGetSamplerParameterIivOES(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureGetSamplerParameterIuivOES(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLuint *params);
+angle::CallCapture CaptureGetTexParameterIivOES(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureGetTexParameterIuivOES(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ GLuint *params);
+angle::CallCapture CaptureSamplerParameterIivOES(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ const GLint *param);
+angle::CallCapture CaptureSamplerParameterIuivOES(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ const GLuint *param);
+angle::CallCapture CaptureTexParameterIivOES(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLint *params);
+angle::CallCapture CaptureTexParameterIuivOES(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLuint *params);
+
+// GL_OES_texture_buffer
+angle::CallCapture CaptureTexBufferOES(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum internalformat,
+ BufferID bufferPacked);
+angle::CallCapture CaptureTexBufferRangeOES(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum internalformat,
+ BufferID bufferPacked,
+ GLintptr offset,
+ GLsizeiptr size);
+
+// GL_OES_texture_compression_astc
+
+// GL_OES_texture_cube_map
+angle::CallCapture CaptureGetTexGenfvOES(const State &glState,
+ bool isCallValid,
+ GLenum coord,
+ GLenum pname,
+ GLfloat *params);
+angle::CallCapture CaptureGetTexGenivOES(const State &glState,
+ bool isCallValid,
+ GLenum coord,
+ GLenum pname,
+ GLint *params);
+angle::CallCapture CaptureGetTexGenxvOES(const State &glState,
+ bool isCallValid,
+ GLenum coord,
+ GLenum pname,
+ GLfixed *params);
+angle::CallCapture CaptureTexGenfOES(const State &glState,
+ bool isCallValid,
+ GLenum coord,
+ GLenum pname,
+ GLfloat param);
+angle::CallCapture CaptureTexGenfvOES(const State &glState,
+ bool isCallValid,
+ GLenum coord,
+ GLenum pname,
+ const GLfloat *params);
+angle::CallCapture CaptureTexGeniOES(const State &glState,
+ bool isCallValid,
+ GLenum coord,
+ GLenum pname,
+ GLint param);
+angle::CallCapture CaptureTexGenivOES(const State &glState,
+ bool isCallValid,
+ GLenum coord,
+ GLenum pname,
+ const GLint *params);
+angle::CallCapture CaptureTexGenxOES(const State &glState,
+ bool isCallValid,
+ GLenum coord,
+ GLenum pname,
+ GLfixed param);
+angle::CallCapture CaptureTexGenxvOES(const State &glState,
+ bool isCallValid,
+ GLenum coord,
+ GLenum pname,
+ const GLfixed *params);
+
+// GL_OES_texture_cube_map_array
+
+// GL_OES_texture_float
+
+// GL_OES_texture_float_linear
+
+// GL_OES_texture_half_float
+
+// GL_OES_texture_half_float_linear
+
+// GL_OES_texture_npot
+
+// GL_OES_texture_stencil8
+
+// GL_OES_texture_storage_multisample_2d_array
+angle::CallCapture CaptureTexStorage3DMultisampleOES(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean fixedsamplelocations);
+
+// GL_OES_vertex_array_object
+angle::CallCapture CaptureBindVertexArrayOES(const State &glState,
+ bool isCallValid,
+ VertexArrayID arrayPacked);
+angle::CallCapture CaptureDeleteVertexArraysOES(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ const VertexArrayID *arraysPacked);
+angle::CallCapture CaptureGenVertexArraysOES(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ VertexArrayID *arraysPacked);
+angle::CallCapture CaptureIsVertexArrayOES(const State &glState,
+ bool isCallValid,
+ VertexArrayID arrayPacked,
+ GLboolean returnValue);
+
+// GL_OES_vertex_half_float
+
+// GL_OES_vertex_type_10_10_10_2
+
+// GL_OVR_multiview
+angle::CallCapture CaptureFramebufferTextureMultiviewOVR(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum attachment,
+ TextureID texturePacked,
+ GLint level,
+ GLint baseViewIndex,
+ GLsizei numViews);
+
+// GL_OVR_multiview2
+
+// GL_QCOM_shading_rate
+angle::CallCapture CaptureShadingRateQCOM(const State &glState, bool isCallValid, GLenum rate);
+
+// Parameter Captures
+
+void CaptureDeletePerfMonitorsAMD_monitors(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ GLuint *monitors,
+ angle::ParamCapture *paramCapture);
+void CaptureGenPerfMonitorsAMD_monitors(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ GLuint *monitors,
+ angle::ParamCapture *paramCapture);
+void CaptureGetPerfMonitorCounterDataAMD_data(const State &glState,
+ bool isCallValid,
+ GLuint monitor,
+ GLenum pname,
+ GLsizei dataSize,
+ GLuint *data,
+ GLint *bytesWritten,
+ angle::ParamCapture *paramCapture);
+void CaptureGetPerfMonitorCounterDataAMD_bytesWritten(const State &glState,
+ bool isCallValid,
+ GLuint monitor,
+ GLenum pname,
+ GLsizei dataSize,
+ GLuint *data,
+ GLint *bytesWritten,
+ angle::ParamCapture *paramCapture);
+void CaptureGetPerfMonitorCounterInfoAMD_data(const State &glState,
+ bool isCallValid,
+ GLuint group,
+ GLuint counter,
+ GLenum pname,
+ void *data,
+ angle::ParamCapture *paramCapture);
+void CaptureGetPerfMonitorCounterStringAMD_length(const State &glState,
+ bool isCallValid,
+ GLuint group,
+ GLuint counter,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *counterString,
+ angle::ParamCapture *paramCapture);
+void CaptureGetPerfMonitorCounterStringAMD_counterString(const State &glState,
+ bool isCallValid,
+ GLuint group,
+ GLuint counter,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *counterString,
+ angle::ParamCapture *paramCapture);
+void CaptureGetPerfMonitorCountersAMD_numCounters(const State &glState,
+ bool isCallValid,
+ GLuint group,
+ GLint *numCounters,
+ GLint *maxActiveCounters,
+ GLsizei counterSize,
+ GLuint *counters,
+ angle::ParamCapture *paramCapture);
+void CaptureGetPerfMonitorCountersAMD_maxActiveCounters(const State &glState,
+ bool isCallValid,
+ GLuint group,
+ GLint *numCounters,
+ GLint *maxActiveCounters,
+ GLsizei counterSize,
+ GLuint *counters,
+ angle::ParamCapture *paramCapture);
+void CaptureGetPerfMonitorCountersAMD_counters(const State &glState,
+ bool isCallValid,
+ GLuint group,
+ GLint *numCounters,
+ GLint *maxActiveCounters,
+ GLsizei counterSize,
+ GLuint *counters,
+ angle::ParamCapture *paramCapture);
+void CaptureGetPerfMonitorGroupStringAMD_length(const State &glState,
+ bool isCallValid,
+ GLuint group,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *groupString,
+ angle::ParamCapture *paramCapture);
+void CaptureGetPerfMonitorGroupStringAMD_groupString(const State &glState,
+ bool isCallValid,
+ GLuint group,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *groupString,
+ angle::ParamCapture *paramCapture);
+void CaptureGetPerfMonitorGroupsAMD_numGroups(const State &glState,
+ bool isCallValid,
+ GLint *numGroups,
+ GLsizei groupsSize,
+ GLuint *groups,
+ angle::ParamCapture *paramCapture);
+void CaptureGetPerfMonitorGroupsAMD_groups(const State &glState,
+ bool isCallValid,
+ GLint *numGroups,
+ GLsizei groupsSize,
+ GLuint *groups,
+ angle::ParamCapture *paramCapture);
+void CaptureSelectPerfMonitorCountersAMD_counterList(const State &glState,
+ bool isCallValid,
+ GLuint monitor,
+ GLboolean enable,
+ GLuint group,
+ GLint numCounters,
+ GLuint *counterList,
+ angle::ParamCapture *paramCapture);
+void CaptureDrawElementsInstancedBaseVertexBaseInstanceANGLE_indices(
+ const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const GLvoid *indices,
+ GLsizei instanceCount,
+ GLint baseVertex,
+ GLuint baseInstance,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiDrawArraysInstancedBaseInstanceANGLE_firsts(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const GLint *firsts,
+ const GLsizei *counts,
+ const GLsizei *instanceCounts,
+ const GLuint *baseInstances,
+ GLsizei drawcount,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiDrawArraysInstancedBaseInstanceANGLE_counts(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const GLint *firsts,
+ const GLsizei *counts,
+ const GLsizei *instanceCounts,
+ const GLuint *baseInstances,
+ GLsizei drawcount,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiDrawArraysInstancedBaseInstanceANGLE_instanceCounts(
+ const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const GLint *firsts,
+ const GLsizei *counts,
+ const GLsizei *instanceCounts,
+ const GLuint *baseInstances,
+ GLsizei drawcount,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiDrawArraysInstancedBaseInstanceANGLE_baseInstances(
+ const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const GLint *firsts,
+ const GLsizei *counts,
+ const GLsizei *instanceCounts,
+ const GLuint *baseInstances,
+ GLsizei drawcount,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE_counts(
+ const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const GLsizei *counts,
+ DrawElementsType typePacked,
+ const GLvoid *const *indices,
+ const GLsizei *instanceCounts,
+ const GLint *baseVertices,
+ const GLuint *baseInstances,
+ GLsizei drawcount,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE_indices(
+ const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const GLsizei *counts,
+ DrawElementsType typePacked,
+ const GLvoid *const *indices,
+ const GLsizei *instanceCounts,
+ const GLint *baseVertices,
+ const GLuint *baseInstances,
+ GLsizei drawcount,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE_instanceCounts(
+ const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const GLsizei *counts,
+ DrawElementsType typePacked,
+ const GLvoid *const *indices,
+ const GLsizei *instanceCounts,
+ const GLint *baseVertices,
+ const GLuint *baseInstances,
+ GLsizei drawcount,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE_baseVertices(
+ const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const GLsizei *counts,
+ DrawElementsType typePacked,
+ const GLvoid *const *indices,
+ const GLsizei *instanceCounts,
+ const GLint *baseVertices,
+ const GLuint *baseInstances,
+ GLsizei drawcount,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE_baseInstances(
+ const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const GLsizei *counts,
+ DrawElementsType typePacked,
+ const GLvoid *const *indices,
+ const GLsizei *instanceCounts,
+ const GLint *baseVertices,
+ const GLuint *baseInstances,
+ GLsizei drawcount,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTexImageANGLE_pixels(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum format,
+ GLenum type,
+ void *pixels,
+ angle::ParamCapture *paramCapture);
+void CaptureGetCompressedTexImageANGLE_pixels(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ void *pixels,
+ angle::ParamCapture *paramCapture);
+void CaptureGetRenderbufferImageANGLE_pixels(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum format,
+ GLenum type,
+ void *pixels,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTexLevelParameterivANGLE_params(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTexLevelParameterfvANGLE_params(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum pname,
+ GLfloat *params,
+ angle::ParamCapture *paramCapture);
+void CaptureDrawElementsInstancedANGLE_indices(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLsizei primcount,
+ angle::ParamCapture *paramCapture);
+void CaptureTexStorageMemFlags2DANGLE_imageCreateInfoPNext(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ MemoryObjectID memoryPacked,
+ GLuint64 offset,
+ GLbitfield createFlags,
+ GLbitfield usageFlags,
+ const void *imageCreateInfoPNext,
+ angle::ParamCapture *paramCapture);
+void CaptureTexStorageMemFlags2DMultisampleANGLE_imageCreateInfoPNext(
+ const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedSampleLocations,
+ MemoryObjectID memoryPacked,
+ GLuint64 offset,
+ GLbitfield createFlags,
+ GLbitfield usageFlags,
+ const void *imageCreateInfoPNext,
+ angle::ParamCapture *paramCapture);
+void CaptureTexStorageMemFlags3DANGLE_imageCreateInfoPNext(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ MemoryObjectID memoryPacked,
+ GLuint64 offset,
+ GLbitfield createFlags,
+ GLbitfield usageFlags,
+ const void *imageCreateInfoPNext,
+ angle::ParamCapture *paramCapture);
+void CaptureTexStorageMemFlags3DMultisampleANGLE_imageCreateInfoPNext(
+ const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean fixedSampleLocations,
+ MemoryObjectID memoryPacked,
+ GLuint64 offset,
+ GLbitfield createFlags,
+ GLbitfield usageFlags,
+ const void *imageCreateInfoPNext,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiDrawArraysANGLE_firsts(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const GLint *firsts,
+ const GLsizei *counts,
+ GLsizei drawcount,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiDrawArraysANGLE_counts(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const GLint *firsts,
+ const GLsizei *counts,
+ GLsizei drawcount,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiDrawArraysInstancedANGLE_firsts(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const GLint *firsts,
+ const GLsizei *counts,
+ const GLsizei *instanceCounts,
+ GLsizei drawcount,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiDrawArraysInstancedANGLE_counts(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const GLint *firsts,
+ const GLsizei *counts,
+ const GLsizei *instanceCounts,
+ GLsizei drawcount,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiDrawArraysInstancedANGLE_instanceCounts(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const GLint *firsts,
+ const GLsizei *counts,
+ const GLsizei *instanceCounts,
+ GLsizei drawcount,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiDrawElementsANGLE_counts(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const GLsizei *counts,
+ DrawElementsType typePacked,
+ const GLvoid *const *indices,
+ GLsizei drawcount,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiDrawElementsANGLE_indices(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const GLsizei *counts,
+ DrawElementsType typePacked,
+ const GLvoid *const *indices,
+ GLsizei drawcount,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiDrawElementsInstancedANGLE_counts(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const GLsizei *counts,
+ DrawElementsType typePacked,
+ const GLvoid *const *indices,
+ const GLsizei *instanceCounts,
+ GLsizei drawcount,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiDrawElementsInstancedANGLE_indices(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const GLsizei *counts,
+ DrawElementsType typePacked,
+ const GLvoid *const *indices,
+ const GLsizei *instanceCounts,
+ GLsizei drawcount,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiDrawElementsInstancedANGLE_instanceCounts(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const GLsizei *counts,
+ DrawElementsType typePacked,
+ const GLvoid *const *indices,
+ const GLsizei *instanceCounts,
+ GLsizei drawcount,
+ angle::ParamCapture *paramCapture);
+void CaptureRequestExtensionANGLE_name(const State &glState,
+ bool isCallValid,
+ const GLchar *name,
+ angle::ParamCapture *paramCapture);
+void CaptureDisableExtensionANGLE_name(const State &glState,
+ bool isCallValid,
+ const GLchar *name,
+ angle::ParamCapture *paramCapture);
+void CaptureGetBooleanvRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLboolean *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetBooleanvRobustANGLE_params(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLboolean *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetBufferParameterivRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ BufferBinding targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetBufferParameterivRobustANGLE_params(const State &glState,
+ bool isCallValid,
+ BufferBinding targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetFloatvRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetFloatvRobustANGLE_params(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetFramebufferAttachmentParameterivRobustANGLE_length(
+ const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum attachment,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetFramebufferAttachmentParameterivRobustANGLE_params(
+ const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum attachment,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetIntegervRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *data,
+ angle::ParamCapture *paramCapture);
+void CaptureGetIntegervRobustANGLE_data(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *data,
+ angle::ParamCapture *paramCapture);
+void CaptureGetProgramivRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetProgramivRobustANGLE_params(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetRenderbufferParameterivRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetRenderbufferParameterivRobustANGLE_params(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetShaderivRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ ShaderProgramID shaderPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetShaderivRobustANGLE_params(const State &glState,
+ bool isCallValid,
+ ShaderProgramID shaderPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTexParameterfvRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTexParameterfvRobustANGLE_params(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTexParameterivRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTexParameterivRobustANGLE_params(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetUniformfvRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetUniformfvRobustANGLE_params(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetUniformivRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetUniformivRobustANGLE_params(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetVertexAttribfvRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetVertexAttribfvRobustANGLE_params(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetVertexAttribivRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetVertexAttribivRobustANGLE_params(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetVertexAttribPointervRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ void **pointer,
+ angle::ParamCapture *paramCapture);
+void CaptureGetVertexAttribPointervRobustANGLE_pointer(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ void **pointer,
+ angle::ParamCapture *paramCapture);
+void CaptureReadPixelsRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLsizei *columns,
+ GLsizei *rows,
+ void *pixels,
+ angle::ParamCapture *paramCapture);
+void CaptureReadPixelsRobustANGLE_columns(const State &glState,
+ bool isCallValid,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLsizei *columns,
+ GLsizei *rows,
+ void *pixels,
+ angle::ParamCapture *paramCapture);
+void CaptureReadPixelsRobustANGLE_rows(const State &glState,
+ bool isCallValid,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLsizei *columns,
+ GLsizei *rows,
+ void *pixels,
+ angle::ParamCapture *paramCapture);
+void CaptureReadPixelsRobustANGLE_pixels(const State &glState,
+ bool isCallValid,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLsizei *columns,
+ GLsizei *rows,
+ void *pixels,
+ angle::ParamCapture *paramCapture);
+void CaptureTexImage2DRobustANGLE_pixels(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *pixels,
+ angle::ParamCapture *paramCapture);
+void CaptureTexParameterfvRobustANGLE_params(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLfloat *params,
+ angle::ParamCapture *paramCapture);
+void CaptureTexParameterivRobustANGLE_params(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureTexSubImage2DRobustANGLE_pixels(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *pixels,
+ angle::ParamCapture *paramCapture);
+void CaptureTexImage3DRobustANGLE_pixels(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *pixels,
+ angle::ParamCapture *paramCapture);
+void CaptureTexSubImage3DRobustANGLE_pixels(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *pixels,
+ angle::ParamCapture *paramCapture);
+void CaptureCompressedTexImage2DRobustANGLE_data(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLsizei imageSize,
+ GLsizei dataSize,
+ const GLvoid *data,
+ angle::ParamCapture *paramCapture);
+void CaptureCompressedTexSubImage2DRobustANGLE_data(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLsizei xoffset,
+ GLsizei yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLsizei imageSize,
+ GLsizei dataSize,
+ const GLvoid *data,
+ angle::ParamCapture *paramCapture);
+void CaptureCompressedTexImage3DRobustANGLE_data(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLsizei imageSize,
+ GLsizei dataSize,
+ const GLvoid *data,
+ angle::ParamCapture *paramCapture);
+void CaptureCompressedTexSubImage3DRobustANGLE_data(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLsizei imageSize,
+ GLsizei dataSize,
+ const GLvoid *data,
+ angle::ParamCapture *paramCapture);
+void CaptureGetQueryivRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ QueryType targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetQueryivRobustANGLE_params(const State &glState,
+ bool isCallValid,
+ QueryType targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetQueryObjectuivRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ QueryID idPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetQueryObjectuivRobustANGLE_params(const State &glState,
+ bool isCallValid,
+ QueryID idPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetBufferPointervRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ BufferBinding targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ void **params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetBufferPointervRobustANGLE_params(const State &glState,
+ bool isCallValid,
+ BufferBinding targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ void **params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetIntegeri_vRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *data,
+ angle::ParamCapture *paramCapture);
+void CaptureGetIntegeri_vRobustANGLE_data(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *data,
+ angle::ParamCapture *paramCapture);
+void CaptureGetInternalformativRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum internalformat,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetInternalformativRobustANGLE_params(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum internalformat,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetVertexAttribIivRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetVertexAttribIivRobustANGLE_params(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetVertexAttribIuivRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetVertexAttribIuivRobustANGLE_params(const State &glState,
+ bool isCallValid,
+ GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetUniformuivRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetUniformuivRobustANGLE_params(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetActiveUniformBlockivRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformBlockIndex uniformBlockIndexPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetActiveUniformBlockivRobustANGLE_params(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformBlockIndex uniformBlockIndexPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetInteger64vRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint64 *data,
+ angle::ParamCapture *paramCapture);
+void CaptureGetInteger64vRobustANGLE_data(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint64 *data,
+ angle::ParamCapture *paramCapture);
+void CaptureGetInteger64i_vRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint64 *data,
+ angle::ParamCapture *paramCapture);
+void CaptureGetInteger64i_vRobustANGLE_data(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint64 *data,
+ angle::ParamCapture *paramCapture);
+void CaptureGetBufferParameteri64vRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ BufferBinding targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint64 *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetBufferParameteri64vRobustANGLE_params(const State &glState,
+ bool isCallValid,
+ BufferBinding targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint64 *params,
+ angle::ParamCapture *paramCapture);
+void CaptureSamplerParameterivRobustANGLE_param(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLuint pname,
+ GLsizei bufSize,
+ const GLint *param,
+ angle::ParamCapture *paramCapture);
+void CaptureSamplerParameterfvRobustANGLE_param(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLfloat *param,
+ angle::ParamCapture *paramCapture);
+void CaptureGetSamplerParameterivRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetSamplerParameterivRobustANGLE_params(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetSamplerParameterfvRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetSamplerParameterfvRobustANGLE_params(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetFramebufferParameterivRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetFramebufferParameterivRobustANGLE_params(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetProgramInterfaceivRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum programInterface,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetProgramInterfaceivRobustANGLE_params(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum programInterface,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetBooleani_vRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLboolean *data,
+ angle::ParamCapture *paramCapture);
+void CaptureGetBooleani_vRobustANGLE_data(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLboolean *data,
+ angle::ParamCapture *paramCapture);
+void CaptureGetMultisamplefvRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *val,
+ angle::ParamCapture *paramCapture);
+void CaptureGetMultisamplefvRobustANGLE_val(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *val,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTexLevelParameterivRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTexLevelParameterivRobustANGLE_params(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTexLevelParameterfvRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTexLevelParameterfvRobustANGLE_params(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetPointervRobustANGLERobustANGLE_length(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ void **params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetPointervRobustANGLERobustANGLE_params(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ void **params,
+ angle::ParamCapture *paramCapture);
+void CaptureReadnPixelsRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLsizei *columns,
+ GLsizei *rows,
+ void *data,
+ angle::ParamCapture *paramCapture);
+void CaptureReadnPixelsRobustANGLE_columns(const State &glState,
+ bool isCallValid,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLsizei *columns,
+ GLsizei *rows,
+ void *data,
+ angle::ParamCapture *paramCapture);
+void CaptureReadnPixelsRobustANGLE_rows(const State &glState,
+ bool isCallValid,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLsizei *columns,
+ GLsizei *rows,
+ void *data,
+ angle::ParamCapture *paramCapture);
+void CaptureReadnPixelsRobustANGLE_data(const State &glState,
+ bool isCallValid,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLsizei *columns,
+ GLsizei *rows,
+ void *data,
+ angle::ParamCapture *paramCapture);
+void CaptureGetnUniformfvRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetnUniformfvRobustANGLE_params(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetnUniformivRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetnUniformivRobustANGLE_params(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetnUniformuivRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetnUniformuivRobustANGLE_params(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureTexParameterIivRobustANGLE_params(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureTexParameterIuivRobustANGLE_params(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLuint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTexParameterIivRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTexParameterIivRobustANGLE_params(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTexParameterIuivRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTexParameterIuivRobustANGLE_params(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureSamplerParameterIivRobustANGLE_param(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLint *param,
+ angle::ParamCapture *paramCapture);
+void CaptureSamplerParameterIuivRobustANGLE_param(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLuint *param,
+ angle::ParamCapture *paramCapture);
+void CaptureGetSamplerParameterIivRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetSamplerParameterIivRobustANGLE_params(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetSamplerParameterIuivRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetSamplerParameterIuivRobustANGLE_params(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetQueryObjectivRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ QueryID idPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetQueryObjectivRobustANGLE_params(const State &glState,
+ bool isCallValid,
+ QueryID idPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetQueryObjecti64vRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ QueryID idPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint64 *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetQueryObjecti64vRobustANGLE_params(const State &glState,
+ bool isCallValid,
+ QueryID idPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint64 *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetQueryObjectui64vRobustANGLE_length(const State &glState,
+ bool isCallValid,
+ QueryID idPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint64 *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetQueryObjectui64vRobustANGLE_params(const State &glState,
+ bool isCallValid,
+ QueryID idPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint64 *params,
+ angle::ParamCapture *paramCapture);
+void CaptureBeginPixelLocalStorageANGLE_loadops(const State &glState,
+ bool isCallValid,
+ GLsizei planes,
+ const GLenum *loadops,
+ const void *cleardata,
+ angle::ParamCapture *paramCapture);
+void CaptureBeginPixelLocalStorageANGLE_cleardata(const State &glState,
+ bool isCallValid,
+ GLsizei planes,
+ const GLenum *loadops,
+ const void *cleardata,
+ angle::ParamCapture *paramCapture);
+void CaptureGetMultisamplefvANGLE_val(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLuint index,
+ GLfloat *val,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTranslatedShaderSourceANGLE_length(const State &glState,
+ bool isCallValid,
+ ShaderProgramID shaderPacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *source,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTranslatedShaderSourceANGLE_source(const State &glState,
+ bool isCallValid,
+ ShaderProgramID shaderPacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *source,
+ angle::ParamCapture *paramCapture);
+void CaptureAcquireTexturesANGLE_texturesPacked(const State &glState,
+ bool isCallValid,
+ GLuint numTextures,
+ const TextureID *texturesPacked,
+ const GLenum *layouts,
+ angle::ParamCapture *paramCapture);
+void CaptureAcquireTexturesANGLE_layouts(const State &glState,
+ bool isCallValid,
+ GLuint numTextures,
+ const TextureID *texturesPacked,
+ const GLenum *layouts,
+ angle::ParamCapture *paramCapture);
+void CaptureReleaseTexturesANGLE_texturesPacked(const State &glState,
+ bool isCallValid,
+ GLuint numTextures,
+ const TextureID *texturesPacked,
+ GLenum *layouts,
+ angle::ParamCapture *paramCapture);
+void CaptureReleaseTexturesANGLE_layouts(const State &glState,
+ bool isCallValid,
+ GLuint numTextures,
+ const TextureID *texturesPacked,
+ GLenum *layouts,
+ angle::ParamCapture *paramCapture);
+void CaptureBindUniformLocationCHROMIUM_name(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ const GLchar *name,
+ angle::ParamCapture *paramCapture);
+void CaptureEGLImageTargetTexStorageEXT_attrib_list(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLeglImageOES image,
+ const GLint *attrib_list,
+ angle::ParamCapture *paramCapture);
+void CaptureEGLImageTargetTextureStorageEXT_attrib_list(const State &glState,
+ bool isCallValid,
+ GLuint texture,
+ GLeglImageOES image,
+ const GLint *attrib_list,
+ angle::ParamCapture *paramCapture);
+void CaptureDrawElementsInstancedBaseInstanceEXT_indices(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLsizei instancecount,
+ GLuint baseinstance,
+ angle::ParamCapture *paramCapture);
+void CaptureDrawElementsInstancedBaseVertexBaseInstanceEXT_indices(
+ const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLsizei instancecount,
+ GLint basevertex,
+ GLuint baseinstance,
+ angle::ParamCapture *paramCapture);
+void CaptureBindFragDataLocationEXT_name(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLuint color,
+ const GLchar *name,
+ angle::ParamCapture *paramCapture);
+void CaptureBindFragDataLocationIndexedEXT_name(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLuint colorNumber,
+ GLuint index,
+ const GLchar *name,
+ angle::ParamCapture *paramCapture);
+void CaptureGetFragDataIndexEXT_name(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ const GLchar *name,
+ angle::ParamCapture *paramCapture);
+void CaptureGetProgramResourceLocationIndexEXT_name(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum programInterface,
+ const GLchar *name,
+ angle::ParamCapture *paramCapture);
+void CaptureBufferStorageEXT_data(const State &glState,
+ bool isCallValid,
+ BufferBinding targetPacked,
+ GLsizeiptr size,
+ const void *data,
+ GLbitfield flags,
+ angle::ParamCapture *paramCapture);
+void CaptureGetObjectLabelEXT_length(const State &glState,
+ bool isCallValid,
+ GLenum type,
+ GLuint object,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *label,
+ angle::ParamCapture *paramCapture);
+void CaptureGetObjectLabelEXT_label(const State &glState,
+ bool isCallValid,
+ GLenum type,
+ GLuint object,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *label,
+ angle::ParamCapture *paramCapture);
+void CaptureLabelObjectEXT_label(const State &glState,
+ bool isCallValid,
+ GLenum type,
+ GLuint object,
+ GLsizei length,
+ const GLchar *label,
+ angle::ParamCapture *paramCapture);
+void CaptureInsertEventMarkerEXT_marker(const State &glState,
+ bool isCallValid,
+ GLsizei length,
+ const GLchar *marker,
+ angle::ParamCapture *paramCapture);
+void CapturePushGroupMarkerEXT_marker(const State &glState,
+ bool isCallValid,
+ GLsizei length,
+ const GLchar *marker,
+ angle::ParamCapture *paramCapture);
+void CaptureDiscardFramebufferEXT_attachments(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLsizei numAttachments,
+ const GLenum *attachments,
+ angle::ParamCapture *paramCapture);
+void CaptureDeleteQueriesEXT_idsPacked(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ const QueryID *idsPacked,
+ angle::ParamCapture *paramCapture);
+void CaptureGenQueriesEXT_idsPacked(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ QueryID *idsPacked,
+ angle::ParamCapture *paramCapture);
+void CaptureGetInteger64vEXT_data(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLint64 *data,
+ angle::ParamCapture *paramCapture);
+void CaptureGetQueryObjecti64vEXT_params(const State &glState,
+ bool isCallValid,
+ QueryID idPacked,
+ GLenum pname,
+ GLint64 *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetQueryObjectivEXT_params(const State &glState,
+ bool isCallValid,
+ QueryID idPacked,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetQueryObjectui64vEXT_params(const State &glState,
+ bool isCallValid,
+ QueryID idPacked,
+ GLenum pname,
+ GLuint64 *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetQueryObjectuivEXT_params(const State &glState,
+ bool isCallValid,
+ QueryID idPacked,
+ GLenum pname,
+ GLuint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetQueryivEXT_params(const State &glState,
+ bool isCallValid,
+ QueryType targetPacked,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureDrawBuffersEXT_bufs(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ const GLenum *bufs,
+ angle::ParamCapture *paramCapture);
+void CaptureDrawElementsBaseVertexEXT_indices(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLint basevertex,
+ angle::ParamCapture *paramCapture);
+void CaptureDrawElementsInstancedBaseVertexEXT_indices(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLsizei instancecount,
+ GLint basevertex,
+ angle::ParamCapture *paramCapture);
+void CaptureDrawRangeElementsBaseVertexEXT_indices(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLint basevertex,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiDrawElementsBaseVertexEXT_count(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const GLsizei *count,
+ DrawElementsType typePacked,
+ const void *const *indices,
+ GLsizei drawcount,
+ const GLint *basevertex,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiDrawElementsBaseVertexEXT_indices(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const GLsizei *count,
+ DrawElementsType typePacked,
+ const void *const *indices,
+ GLsizei drawcount,
+ const GLint *basevertex,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiDrawElementsBaseVertexEXT_basevertex(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const GLsizei *count,
+ DrawElementsType typePacked,
+ const void *const *indices,
+ GLsizei drawcount,
+ const GLint *basevertex,
+ angle::ParamCapture *paramCapture);
+void CaptureDrawElementsInstancedEXT_indices(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLsizei primcount,
+ angle::ParamCapture *paramCapture);
+void CaptureCreateMemoryObjectsEXT_memoryObjectsPacked(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ MemoryObjectID *memoryObjectsPacked,
+ angle::ParamCapture *paramCapture);
+void CaptureDeleteMemoryObjectsEXT_memoryObjectsPacked(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ const MemoryObjectID *memoryObjectsPacked,
+ angle::ParamCapture *paramCapture);
+void CaptureGetMemoryObjectParameterivEXT_params(const State &glState,
+ bool isCallValid,
+ MemoryObjectID memoryObjectPacked,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetUnsignedBytevEXT_data(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ GLubyte *data,
+ angle::ParamCapture *paramCapture);
+void CaptureGetUnsignedBytei_vEXT_data(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLuint index,
+ GLubyte *data,
+ angle::ParamCapture *paramCapture);
+void CaptureMemoryObjectParameterivEXT_params(const State &glState,
+ bool isCallValid,
+ MemoryObjectID memoryObjectPacked,
+ GLenum pname,
+ const GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiDrawArraysIndirectEXT_indirect(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ const void *indirect,
+ GLsizei drawcount,
+ GLsizei stride,
+ angle::ParamCapture *paramCapture);
+void CaptureMultiDrawElementsIndirectEXT_indirect(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ DrawElementsType typePacked,
+ const void *indirect,
+ GLsizei drawcount,
+ GLsizei stride,
+ angle::ParamCapture *paramCapture);
+void CaptureGetnUniformfvEXT_params(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei bufSize,
+ GLfloat *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetnUniformivEXT_params(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei bufSize,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureReadnPixelsEXT_data(const State &glState,
+ bool isCallValid,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ void *data,
+ angle::ParamCapture *paramCapture);
+void CaptureDeleteSemaphoresEXT_semaphoresPacked(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ const SemaphoreID *semaphoresPacked,
+ angle::ParamCapture *paramCapture);
+void CaptureGenSemaphoresEXT_semaphoresPacked(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ SemaphoreID *semaphoresPacked,
+ angle::ParamCapture *paramCapture);
+void CaptureGetSemaphoreParameterui64vEXT_params(const State &glState,
+ bool isCallValid,
+ SemaphoreID semaphorePacked,
+ GLenum pname,
+ GLuint64 *params,
+ angle::ParamCapture *paramCapture);
+void CaptureSemaphoreParameterui64vEXT_params(const State &glState,
+ bool isCallValid,
+ SemaphoreID semaphorePacked,
+ GLenum pname,
+ const GLuint64 *params,
+ angle::ParamCapture *paramCapture);
+void CaptureSignalSemaphoreEXT_buffersPacked(const State &glState,
+ bool isCallValid,
+ SemaphoreID semaphorePacked,
+ GLuint numBufferBarriers,
+ const BufferID *buffersPacked,
+ GLuint numTextureBarriers,
+ const TextureID *texturesPacked,
+ const GLenum *dstLayouts,
+ angle::ParamCapture *paramCapture);
+void CaptureSignalSemaphoreEXT_texturesPacked(const State &glState,
+ bool isCallValid,
+ SemaphoreID semaphorePacked,
+ GLuint numBufferBarriers,
+ const BufferID *buffersPacked,
+ GLuint numTextureBarriers,
+ const TextureID *texturesPacked,
+ const GLenum *dstLayouts,
+ angle::ParamCapture *paramCapture);
+void CaptureSignalSemaphoreEXT_dstLayouts(const State &glState,
+ bool isCallValid,
+ SemaphoreID semaphorePacked,
+ GLuint numBufferBarriers,
+ const BufferID *buffersPacked,
+ GLuint numTextureBarriers,
+ const TextureID *texturesPacked,
+ const GLenum *dstLayouts,
+ angle::ParamCapture *paramCapture);
+void CaptureWaitSemaphoreEXT_buffersPacked(const State &glState,
+ bool isCallValid,
+ SemaphoreID semaphorePacked,
+ GLuint numBufferBarriers,
+ const BufferID *buffersPacked,
+ GLuint numTextureBarriers,
+ const TextureID *texturesPacked,
+ const GLenum *srcLayouts,
+ angle::ParamCapture *paramCapture);
+void CaptureWaitSemaphoreEXT_texturesPacked(const State &glState,
+ bool isCallValid,
+ SemaphoreID semaphorePacked,
+ GLuint numBufferBarriers,
+ const BufferID *buffersPacked,
+ GLuint numTextureBarriers,
+ const TextureID *texturesPacked,
+ const GLenum *srcLayouts,
+ angle::ParamCapture *paramCapture);
+void CaptureWaitSemaphoreEXT_srcLayouts(const State &glState,
+ bool isCallValid,
+ SemaphoreID semaphorePacked,
+ GLuint numBufferBarriers,
+ const BufferID *buffersPacked,
+ GLuint numTextureBarriers,
+ const TextureID *texturesPacked,
+ const GLenum *srcLayouts,
+ angle::ParamCapture *paramCapture);
+void CaptureCreateShaderProgramvEXT_strings(const State &glState,
+ bool isCallValid,
+ ShaderType typePacked,
+ GLsizei count,
+ const GLchar **strings,
+ angle::ParamCapture *paramCapture);
+void CaptureDeleteProgramPipelinesEXT_pipelinesPacked(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ const ProgramPipelineID *pipelinesPacked,
+ angle::ParamCapture *paramCapture);
+void CaptureGenProgramPipelinesEXT_pipelinesPacked(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ ProgramPipelineID *pipelinesPacked,
+ angle::ParamCapture *paramCapture);
+void CaptureGetProgramPipelineInfoLogEXT_length(const State &glState,
+ bool isCallValid,
+ ProgramPipelineID pipelinePacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *infoLog,
+ angle::ParamCapture *paramCapture);
+void CaptureGetProgramPipelineInfoLogEXT_infoLog(const State &glState,
+ bool isCallValid,
+ ProgramPipelineID pipelinePacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *infoLog,
+ angle::ParamCapture *paramCapture);
+void CaptureGetProgramPipelineivEXT_params(const State &glState,
+ bool isCallValid,
+ ProgramPipelineID pipelinePacked,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniform1fvEXT_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniform1ivEXT_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniform1uivEXT_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniform2fvEXT_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniform2ivEXT_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniform2uivEXT_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniform3fvEXT_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniform3ivEXT_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniform3uivEXT_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniform4fvEXT_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniform4ivEXT_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniform4uivEXT_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniformMatrix2fvEXT_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniformMatrix2x3fvEXT_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniformMatrix2x4fvEXT_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniformMatrix3fvEXT_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniformMatrix3x2fvEXT_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniformMatrix3x4fvEXT_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniformMatrix4fvEXT_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniformMatrix4x2fvEXT_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramUniformMatrix4x3fvEXT_value(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value,
+ angle::ParamCapture *paramCapture);
+void CaptureGetSamplerParameterIivEXT_params(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetSamplerParameterIuivEXT_params(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLuint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTexParameterIivEXT_params(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTexParameterIuivEXT_params(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ GLuint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureSamplerParameterIivEXT_param(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ const GLint *param,
+ angle::ParamCapture *paramCapture);
+void CaptureSamplerParameterIuivEXT_param(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ const GLuint *param,
+ angle::ParamCapture *paramCapture);
+void CaptureTexParameterIivEXT_params(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureTexParameterIuivEXT_params(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLuint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureDebugMessageCallbackKHR_userParam(const State &glState,
+ bool isCallValid,
+ GLDEBUGPROCKHR callback,
+ const void *userParam,
+ angle::ParamCapture *paramCapture);
+void CaptureDebugMessageControlKHR_ids(const State &glState,
+ bool isCallValid,
+ GLenum source,
+ GLenum type,
+ GLenum severity,
+ GLsizei count,
+ const GLuint *ids,
+ GLboolean enabled,
+ angle::ParamCapture *paramCapture);
+void CaptureDebugMessageInsertKHR_buf(const State &glState,
+ bool isCallValid,
+ GLenum source,
+ GLenum type,
+ GLuint id,
+ GLenum severity,
+ GLsizei length,
+ const GLchar *buf,
+ angle::ParamCapture *paramCapture);
+void CaptureGetDebugMessageLogKHR_sources(const State &glState,
+ bool isCallValid,
+ GLuint count,
+ GLsizei bufSize,
+ GLenum *sources,
+ GLenum *types,
+ GLuint *ids,
+ GLenum *severities,
+ GLsizei *lengths,
+ GLchar *messageLog,
+ angle::ParamCapture *paramCapture);
+void CaptureGetDebugMessageLogKHR_types(const State &glState,
+ bool isCallValid,
+ GLuint count,
+ GLsizei bufSize,
+ GLenum *sources,
+ GLenum *types,
+ GLuint *ids,
+ GLenum *severities,
+ GLsizei *lengths,
+ GLchar *messageLog,
+ angle::ParamCapture *paramCapture);
+void CaptureGetDebugMessageLogKHR_ids(const State &glState,
+ bool isCallValid,
+ GLuint count,
+ GLsizei bufSize,
+ GLenum *sources,
+ GLenum *types,
+ GLuint *ids,
+ GLenum *severities,
+ GLsizei *lengths,
+ GLchar *messageLog,
+ angle::ParamCapture *paramCapture);
+void CaptureGetDebugMessageLogKHR_severities(const State &glState,
+ bool isCallValid,
+ GLuint count,
+ GLsizei bufSize,
+ GLenum *sources,
+ GLenum *types,
+ GLuint *ids,
+ GLenum *severities,
+ GLsizei *lengths,
+ GLchar *messageLog,
+ angle::ParamCapture *paramCapture);
+void CaptureGetDebugMessageLogKHR_lengths(const State &glState,
+ bool isCallValid,
+ GLuint count,
+ GLsizei bufSize,
+ GLenum *sources,
+ GLenum *types,
+ GLuint *ids,
+ GLenum *severities,
+ GLsizei *lengths,
+ GLchar *messageLog,
+ angle::ParamCapture *paramCapture);
+void CaptureGetDebugMessageLogKHR_messageLog(const State &glState,
+ bool isCallValid,
+ GLuint count,
+ GLsizei bufSize,
+ GLenum *sources,
+ GLenum *types,
+ GLuint *ids,
+ GLenum *severities,
+ GLsizei *lengths,
+ GLchar *messageLog,
+ angle::ParamCapture *paramCapture);
+void CaptureGetObjectLabelKHR_length(const State &glState,
+ bool isCallValid,
+ GLenum identifier,
+ GLuint name,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *label,
+ angle::ParamCapture *paramCapture);
+void CaptureGetObjectLabelKHR_label(const State &glState,
+ bool isCallValid,
+ GLenum identifier,
+ GLuint name,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *label,
+ angle::ParamCapture *paramCapture);
+void CaptureGetObjectPtrLabelKHR_ptr(const State &glState,
+ bool isCallValid,
+ const void *ptr,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *label,
+ angle::ParamCapture *paramCapture);
+void CaptureGetObjectPtrLabelKHR_length(const State &glState,
+ bool isCallValid,
+ const void *ptr,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *label,
+ angle::ParamCapture *paramCapture);
+void CaptureGetObjectPtrLabelKHR_label(const State &glState,
+ bool isCallValid,
+ const void *ptr,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *label,
+ angle::ParamCapture *paramCapture);
+void CaptureGetPointervKHR_params(const State &glState,
+ bool isCallValid,
+ GLenum pname,
+ void **params,
+ angle::ParamCapture *paramCapture);
+void CaptureObjectLabelKHR_label(const State &glState,
+ bool isCallValid,
+ GLenum identifier,
+ GLuint name,
+ GLsizei length,
+ const GLchar *label,
+ angle::ParamCapture *paramCapture);
+void CaptureObjectPtrLabelKHR_ptr(const State &glState,
+ bool isCallValid,
+ const void *ptr,
+ GLsizei length,
+ const GLchar *label,
+ angle::ParamCapture *paramCapture);
+void CaptureObjectPtrLabelKHR_label(const State &glState,
+ bool isCallValid,
+ const void *ptr,
+ GLsizei length,
+ const GLchar *label,
+ angle::ParamCapture *paramCapture);
+void CapturePushDebugGroupKHR_message(const State &glState,
+ bool isCallValid,
+ GLenum source,
+ GLuint id,
+ GLsizei length,
+ const GLchar *message,
+ angle::ParamCapture *paramCapture);
+void CaptureGetFramebufferParameterivMESA_params(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureDeleteFencesNV_fencesPacked(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ const FenceNVID *fencesPacked,
+ angle::ParamCapture *paramCapture);
+void CaptureGenFencesNV_fencesPacked(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ FenceNVID *fencesPacked,
+ angle::ParamCapture *paramCapture);
+void CaptureGetFenceivNV_params(const State &glState,
+ bool isCallValid,
+ FenceNVID fencePacked,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureDrawElementsBaseVertexOES_indices(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLint basevertex,
+ angle::ParamCapture *paramCapture);
+void CaptureDrawElementsInstancedBaseVertexOES_indices(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLsizei instancecount,
+ GLint basevertex,
+ angle::ParamCapture *paramCapture);
+void CaptureDrawRangeElementsBaseVertexOES_indices(const State &glState,
+ bool isCallValid,
+ PrimitiveMode modePacked,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLint basevertex,
+ angle::ParamCapture *paramCapture);
+void CaptureDrawTexfvOES_coords(const State &glState,
+ bool isCallValid,
+ const GLfloat *coords,
+ angle::ParamCapture *paramCapture);
+void CaptureDrawTexivOES_coords(const State &glState,
+ bool isCallValid,
+ const GLint *coords,
+ angle::ParamCapture *paramCapture);
+void CaptureDrawTexsvOES_coords(const State &glState,
+ bool isCallValid,
+ const GLshort *coords,
+ angle::ParamCapture *paramCapture);
+void CaptureDrawTexxvOES_coords(const State &glState,
+ bool isCallValid,
+ const GLfixed *coords,
+ angle::ParamCapture *paramCapture);
+void CaptureDeleteFramebuffersOES_framebuffersPacked(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ const FramebufferID *framebuffersPacked,
+ angle::ParamCapture *paramCapture);
+void CaptureDeleteRenderbuffersOES_renderbuffersPacked(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ const RenderbufferID *renderbuffersPacked,
+ angle::ParamCapture *paramCapture);
+void CaptureGenFramebuffersOES_framebuffersPacked(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ FramebufferID *framebuffersPacked,
+ angle::ParamCapture *paramCapture);
+void CaptureGenRenderbuffersOES_renderbuffersPacked(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ RenderbufferID *renderbuffersPacked,
+ angle::ParamCapture *paramCapture);
+void CaptureGetFramebufferAttachmentParameterivOES_params(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum attachment,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetRenderbufferParameterivOES_params(const State &glState,
+ bool isCallValid,
+ GLenum target,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetProgramBinaryOES_length(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLenum *binaryFormat,
+ void *binary,
+ angle::ParamCapture *paramCapture);
+void CaptureGetProgramBinaryOES_binaryFormat(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLenum *binaryFormat,
+ void *binary,
+ angle::ParamCapture *paramCapture);
+void CaptureGetProgramBinaryOES_binary(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLenum *binaryFormat,
+ void *binary,
+ angle::ParamCapture *paramCapture);
+void CaptureProgramBinaryOES_binary(const State &glState,
+ bool isCallValid,
+ ShaderProgramID programPacked,
+ GLenum binaryFormat,
+ const void *binary,
+ GLint length,
+ angle::ParamCapture *paramCapture);
+void CaptureGetBufferPointervOES_params(const State &glState,
+ bool isCallValid,
+ BufferBinding targetPacked,
+ GLenum pname,
+ void **params,
+ angle::ParamCapture *paramCapture);
+void CaptureMatrixIndexPointerOES_pointer(const State &glState,
+ bool isCallValid,
+ GLint size,
+ GLenum type,
+ GLsizei stride,
+ const void *pointer,
+ angle::ParamCapture *paramCapture);
+void CaptureWeightPointerOES_pointer(const State &glState,
+ bool isCallValid,
+ GLint size,
+ GLenum type,
+ GLsizei stride,
+ const void *pointer,
+ angle::ParamCapture *paramCapture);
+void CapturePointSizePointerOES_pointer(const State &glState,
+ bool isCallValid,
+ VertexAttribType typePacked,
+ GLsizei stride,
+ const void *pointer,
+ angle::ParamCapture *paramCapture);
+void CaptureQueryMatrixxOES_mantissa(const State &glState,
+ bool isCallValid,
+ GLfixed *mantissa,
+ GLint *exponent,
+ angle::ParamCapture *paramCapture);
+void CaptureQueryMatrixxOES_exponent(const State &glState,
+ bool isCallValid,
+ GLfixed *mantissa,
+ GLint *exponent,
+ angle::ParamCapture *paramCapture);
+void CaptureCompressedTexImage3DOES_data(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLsizei imageSize,
+ const void *data,
+ angle::ParamCapture *paramCapture);
+void CaptureCompressedTexSubImage3DOES_data(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data,
+ angle::ParamCapture *paramCapture);
+void CaptureTexImage3DOES_pixels(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const void *pixels,
+ angle::ParamCapture *paramCapture);
+void CaptureTexSubImage3DOES_pixels(const State &glState,
+ bool isCallValid,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ const void *pixels,
+ angle::ParamCapture *paramCapture);
+void CaptureGetSamplerParameterIivOES_params(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetSamplerParameterIuivOES_params(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLuint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTexParameterIivOES_params(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTexParameterIuivOES_params(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ GLuint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureSamplerParameterIivOES_param(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ const GLint *param,
+ angle::ParamCapture *paramCapture);
+void CaptureSamplerParameterIuivOES_param(const State &glState,
+ bool isCallValid,
+ SamplerID samplerPacked,
+ GLenum pname,
+ const GLuint *param,
+ angle::ParamCapture *paramCapture);
+void CaptureTexParameterIivOES_params(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureTexParameterIuivOES_params(const State &glState,
+ bool isCallValid,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLuint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTexGenfvOES_params(const State &glState,
+ bool isCallValid,
+ GLenum coord,
+ GLenum pname,
+ GLfloat *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTexGenivOES_params(const State &glState,
+ bool isCallValid,
+ GLenum coord,
+ GLenum pname,
+ GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureGetTexGenxvOES_params(const State &glState,
+ bool isCallValid,
+ GLenum coord,
+ GLenum pname,
+ GLfixed *params,
+ angle::ParamCapture *paramCapture);
+void CaptureTexGenfvOES_params(const State &glState,
+ bool isCallValid,
+ GLenum coord,
+ GLenum pname,
+ const GLfloat *params,
+ angle::ParamCapture *paramCapture);
+void CaptureTexGenivOES_params(const State &glState,
+ bool isCallValid,
+ GLenum coord,
+ GLenum pname,
+ const GLint *params,
+ angle::ParamCapture *paramCapture);
+void CaptureTexGenxvOES_params(const State &glState,
+ bool isCallValid,
+ GLenum coord,
+ GLenum pname,
+ const GLfixed *params,
+ angle::ParamCapture *paramCapture);
+void CaptureDeleteVertexArraysOES_arraysPacked(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ const VertexArrayID *arraysPacked,
+ angle::ParamCapture *paramCapture);
+void CaptureGenVertexArraysOES_arraysPacked(const State &glState,
+ bool isCallValid,
+ GLsizei n,
+ VertexArrayID *arraysPacked,
+ angle::ParamCapture *paramCapture);
+} // namespace gl
+
+#endif // LIBANGLE_CAPTURE_GLES_EXT_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libANGLE/capture/frame_capture_utils.h b/gfx/angle/checkout/src/libANGLE/capture/frame_capture_utils.h
new file mode 100644
index 0000000000..18e2fe41cc
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/capture/frame_capture_utils.h
@@ -0,0 +1,23 @@
+//
+// Copyright 2020 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.
+//
+// frame_capture_utils.h:
+// ANGLE frame capture utils interface.
+//
+#ifndef FRAME_CAPTURE_UTILS_H_
+#define FRAME_CAPTURE_UTILS_H_
+
+#include "libANGLE/Error.h"
+
+namespace gl
+{
+class Context;
+} // namespace gl
+
+namespace angle
+{
+Result SerializeContextToString(const gl::Context *context, std::string *stringOut);
+} // namespace angle
+#endif // FRAME_CAPTURE_UTILS_H_
diff --git a/gfx/angle/checkout/src/libANGLE/capture/frame_capture_utils_autogen.h b/gfx/angle/checkout/src/libANGLE/capture/frame_capture_utils_autogen.h
new file mode 100644
index 0000000000..9c76c2fc15
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/capture/frame_capture_utils_autogen.h
@@ -0,0 +1,3257 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml and gl_angle_ext.xml.
+//
+// Copyright 2020 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.
+//
+// frame_capture_utils_autogen.h:
+// ANGLE Frame capture types and helper functions.
+
+#ifndef LIBANGLE_FRAME_CAPTURE_UTILS_AUTOGEN_H_
+#define LIBANGLE_FRAME_CAPTURE_UTILS_AUTOGEN_H_
+
+#include "common/PackedEnums.h"
+
+namespace angle
+{
+enum class ParamType
+{
+ TAHardwareBufferConstPointer,
+ TAlphaTestFunc,
+ TBufferBinding,
+ TBufferID,
+ TBufferIDConstPointer,
+ TBufferIDPointer,
+ TBufferUsage,
+ TClientVertexArrayType,
+ TCompositorTiming,
+ TCullFaceMode,
+ TDrawElementsType,
+ TEGLAttrib,
+ TEGLAttribKHR,
+ TEGLBoolean,
+ TEGLClientBuffer,
+ TEGLConfig,
+ TEGLContext,
+ TEGLDEBUGPROCKHR,
+ TEGLDeviceEXT,
+ TEGLDisplay,
+ TEGLFrameTokenANGLE,
+ TEGLGetBlobFuncANDROID,
+ TEGLImage,
+ TEGLLabelKHR,
+ TEGLNativeDisplayType,
+ TEGLNativePixmapType,
+ TEGLNativeWindowType,
+ TEGLObjectKHR,
+ TEGLSetBlobFuncANDROID,
+ TEGLStreamKHR,
+ TEGLSurface,
+ TEGLSync,
+ TEGLTime,
+ TEGLTimeKHR,
+ TEGLenum,
+ TEGLint,
+ TEGLnsecsANDROID,
+ TEGLuint64KHR,
+ TFenceNVID,
+ TFenceNVIDConstPointer,
+ TFenceNVIDPointer,
+ TFramebufferID,
+ TFramebufferIDConstPointer,
+ TFramebufferIDPointer,
+ TGLDEBUGPROC,
+ TGLDEBUGPROCKHR,
+ TGLbitfield,
+ TGLboolean,
+ TGLbooleanConstPointer,
+ TGLbooleanPointer,
+ TGLbyte,
+ TGLbyteConstPointer,
+ TGLcharConstPointer,
+ TGLcharConstPointerPointer,
+ TGLcharPointer,
+ TGLclampx,
+ TGLdouble,
+ TGLdoubleConstPointer,
+ TGLdoublePointer,
+ TGLeglClientBufferEXT,
+ TGLeglImageOES,
+ TGLenum,
+ TGLenumConstPointer,
+ TGLenumPointer,
+ TGLfixed,
+ TGLfixedConstPointer,
+ TGLfixedPointer,
+ TGLfloat,
+ TGLfloatConstPointer,
+ TGLfloatPointer,
+ TGLint,
+ TGLint64Pointer,
+ TGLintConstPointer,
+ TGLintPointer,
+ TGLintptr,
+ TGLintptrConstPointer,
+ TGLshort,
+ TGLshortConstPointer,
+ TGLsizei,
+ TGLsizeiConstPointer,
+ TGLsizeiPointer,
+ TGLsizeiptr,
+ TGLsizeiptrConstPointer,
+ TGLsync,
+ TGLubyte,
+ TGLubyteConstPointer,
+ TGLubytePointer,
+ TGLuint,
+ TGLuint64,
+ TGLuint64ConstPointer,
+ TGLuint64Pointer,
+ TGLuintConstPointer,
+ TGLuintPointer,
+ TGLushort,
+ TGLushortConstPointer,
+ TGLushortPointer,
+ TGLvoidConstPointer,
+ TGLvoidConstPointerPointer,
+ TGraphicsResetStatus,
+ THandleType,
+ TLightParameter,
+ TLogicalOperation,
+ TMaterialParameter,
+ TMatrixType,
+ TMemoryObjectID,
+ TMemoryObjectIDConstPointer,
+ TMemoryObjectIDPointer,
+ TObjectType,
+ TPointParameter,
+ TPrimitiveMode,
+ TProgramPipelineID,
+ TProgramPipelineIDConstPointer,
+ TProgramPipelineIDPointer,
+ TProvokingVertexConvention,
+ TQueryID,
+ TQueryIDConstPointer,
+ TQueryIDPointer,
+ TQueryType,
+ TRenderbufferID,
+ TRenderbufferIDConstPointer,
+ TRenderbufferIDPointer,
+ TSamplerID,
+ TSamplerIDConstPointer,
+ TSamplerIDPointer,
+ TSemaphoreID,
+ TSemaphoreIDConstPointer,
+ TSemaphoreIDPointer,
+ TShaderProgramID,
+ TShaderProgramIDConstPointer,
+ TShaderProgramIDPointer,
+ TShaderType,
+ TShadingModel,
+ TTextureEnvParameter,
+ TTextureEnvTarget,
+ TTextureID,
+ TTextureIDConstPointer,
+ TTextureIDPointer,
+ TTextureTarget,
+ TTextureType,
+ TTimestamp,
+ TTransformFeedbackID,
+ TTransformFeedbackIDConstPointer,
+ TTransformFeedbackIDPointer,
+ TUniformBlockIndex,
+ TUniformLocation,
+ TVertexArrayID,
+ TVertexArrayIDConstPointer,
+ TVertexArrayIDPointer,
+ TVertexAttribType,
+ TcharConstPointer,
+ TvoidConstPointer,
+ TvoidConstPointerPointer,
+ TvoidPointer,
+ TvoidPointerPointer,
+};
+
+constexpr uint32_t kParamTypeCount = 154;
+
+union ParamValue
+{
+ const AHardwareBuffer *AHardwareBufferConstPointerVal;
+ gl::AlphaTestFunc AlphaTestFuncVal;
+ gl::BufferBinding BufferBindingVal;
+ gl::BufferID BufferIDVal;
+ const gl::BufferID *BufferIDConstPointerVal;
+ gl::BufferID *BufferIDPointerVal;
+ gl::BufferUsage BufferUsageVal;
+ gl::ClientVertexArrayType ClientVertexArrayTypeVal;
+ egl::CompositorTiming CompositorTimingVal;
+ gl::CullFaceMode CullFaceModeVal;
+ gl::DrawElementsType DrawElementsTypeVal;
+ EGLAttrib EGLAttribVal;
+ EGLAttribKHR EGLAttribKHRVal;
+ EGLBoolean EGLBooleanVal;
+ EGLClientBuffer EGLClientBufferVal;
+ EGLConfig EGLConfigVal;
+ EGLContext EGLContextVal;
+ EGLDEBUGPROCKHR EGLDEBUGPROCKHRVal;
+ EGLDeviceEXT EGLDeviceEXTVal;
+ EGLDisplay EGLDisplayVal;
+ EGLFrameTokenANGLE EGLFrameTokenANGLEVal;
+ EGLGetBlobFuncANDROID EGLGetBlobFuncANDROIDVal;
+ EGLImage EGLImageVal;
+ EGLLabelKHR EGLLabelKHRVal;
+ EGLNativeDisplayType EGLNativeDisplayTypeVal;
+ EGLNativePixmapType EGLNativePixmapTypeVal;
+ EGLNativeWindowType EGLNativeWindowTypeVal;
+ EGLObjectKHR EGLObjectKHRVal;
+ EGLSetBlobFuncANDROID EGLSetBlobFuncANDROIDVal;
+ EGLStreamKHR EGLStreamKHRVal;
+ EGLSurface EGLSurfaceVal;
+ EGLSync EGLSyncVal;
+ EGLTime EGLTimeVal;
+ EGLTimeKHR EGLTimeKHRVal;
+ EGLenum EGLenumVal;
+ EGLint EGLintVal;
+ EGLnsecsANDROID EGLnsecsANDROIDVal;
+ EGLuint64KHR EGLuint64KHRVal;
+ gl::FenceNVID FenceNVIDVal;
+ const gl::FenceNVID *FenceNVIDConstPointerVal;
+ gl::FenceNVID *FenceNVIDPointerVal;
+ gl::FramebufferID FramebufferIDVal;
+ const gl::FramebufferID *FramebufferIDConstPointerVal;
+ gl::FramebufferID *FramebufferIDPointerVal;
+ GLDEBUGPROC GLDEBUGPROCVal;
+ GLDEBUGPROCKHR GLDEBUGPROCKHRVal;
+ GLbitfield GLbitfieldVal;
+ GLboolean GLbooleanVal;
+ const GLboolean *GLbooleanConstPointerVal;
+ GLboolean *GLbooleanPointerVal;
+ GLbyte GLbyteVal;
+ const GLbyte *GLbyteConstPointerVal;
+ const GLchar *GLcharConstPointerVal;
+ const GLchar *const *GLcharConstPointerPointerVal;
+ GLchar *GLcharPointerVal;
+ GLclampx GLclampxVal;
+ GLdouble GLdoubleVal;
+ const GLdouble *GLdoubleConstPointerVal;
+ GLdouble *GLdoublePointerVal;
+ GLeglClientBufferEXT GLeglClientBufferEXTVal;
+ GLeglImageOES GLeglImageOESVal;
+ GLenum GLenumVal;
+ const GLenum *GLenumConstPointerVal;
+ GLenum *GLenumPointerVal;
+ GLfixed GLfixedVal;
+ const GLfixed *GLfixedConstPointerVal;
+ GLfixed *GLfixedPointerVal;
+ GLfloat GLfloatVal;
+ const GLfloat *GLfloatConstPointerVal;
+ GLfloat *GLfloatPointerVal;
+ GLint GLintVal;
+ GLint64 *GLint64PointerVal;
+ const GLint *GLintConstPointerVal;
+ GLint *GLintPointerVal;
+ GLintptr GLintptrVal;
+ const GLintptr *GLintptrConstPointerVal;
+ GLshort GLshortVal;
+ const GLshort *GLshortConstPointerVal;
+ GLsizei GLsizeiVal;
+ const GLsizei *GLsizeiConstPointerVal;
+ GLsizei *GLsizeiPointerVal;
+ GLsizeiptr GLsizeiptrVal;
+ const GLsizeiptr *GLsizeiptrConstPointerVal;
+ GLsync GLsyncVal;
+ GLubyte GLubyteVal;
+ const GLubyte *GLubyteConstPointerVal;
+ GLubyte *GLubytePointerVal;
+ GLuint GLuintVal;
+ GLuint64 GLuint64Val;
+ const GLuint64 *GLuint64ConstPointerVal;
+ GLuint64 *GLuint64PointerVal;
+ const GLuint *GLuintConstPointerVal;
+ GLuint *GLuintPointerVal;
+ GLushort GLushortVal;
+ const GLushort *GLushortConstPointerVal;
+ GLushort *GLushortPointerVal;
+ const GLvoid *GLvoidConstPointerVal;
+ const GLvoid *const *GLvoidConstPointerPointerVal;
+ gl::GraphicsResetStatus GraphicsResetStatusVal;
+ gl::HandleType HandleTypeVal;
+ gl::LightParameter LightParameterVal;
+ gl::LogicalOperation LogicalOperationVal;
+ gl::MaterialParameter MaterialParameterVal;
+ gl::MatrixType MatrixTypeVal;
+ gl::MemoryObjectID MemoryObjectIDVal;
+ const gl::MemoryObjectID *MemoryObjectIDConstPointerVal;
+ gl::MemoryObjectID *MemoryObjectIDPointerVal;
+ egl::ObjectType ObjectTypeVal;
+ gl::PointParameter PointParameterVal;
+ gl::PrimitiveMode PrimitiveModeVal;
+ gl::ProgramPipelineID ProgramPipelineIDVal;
+ const gl::ProgramPipelineID *ProgramPipelineIDConstPointerVal;
+ gl::ProgramPipelineID *ProgramPipelineIDPointerVal;
+ gl::ProvokingVertexConvention ProvokingVertexConventionVal;
+ gl::QueryID QueryIDVal;
+ const gl::QueryID *QueryIDConstPointerVal;
+ gl::QueryID *QueryIDPointerVal;
+ gl::QueryType QueryTypeVal;
+ gl::RenderbufferID RenderbufferIDVal;
+ const gl::RenderbufferID *RenderbufferIDConstPointerVal;
+ gl::RenderbufferID *RenderbufferIDPointerVal;
+ gl::SamplerID SamplerIDVal;
+ const gl::SamplerID *SamplerIDConstPointerVal;
+ gl::SamplerID *SamplerIDPointerVal;
+ gl::SemaphoreID SemaphoreIDVal;
+ const gl::SemaphoreID *SemaphoreIDConstPointerVal;
+ gl::SemaphoreID *SemaphoreIDPointerVal;
+ gl::ShaderProgramID ShaderProgramIDVal;
+ const gl::ShaderProgramID *ShaderProgramIDConstPointerVal;
+ gl::ShaderProgramID *ShaderProgramIDPointerVal;
+ gl::ShaderType ShaderTypeVal;
+ gl::ShadingModel ShadingModelVal;
+ gl::TextureEnvParameter TextureEnvParameterVal;
+ gl::TextureEnvTarget TextureEnvTargetVal;
+ gl::TextureID TextureIDVal;
+ const gl::TextureID *TextureIDConstPointerVal;
+ gl::TextureID *TextureIDPointerVal;
+ gl::TextureTarget TextureTargetVal;
+ gl::TextureType TextureTypeVal;
+ egl::Timestamp TimestampVal;
+ gl::TransformFeedbackID TransformFeedbackIDVal;
+ const gl::TransformFeedbackID *TransformFeedbackIDConstPointerVal;
+ gl::TransformFeedbackID *TransformFeedbackIDPointerVal;
+ gl::UniformBlockIndex UniformBlockIndexVal;
+ gl::UniformLocation UniformLocationVal;
+ gl::VertexArrayID VertexArrayIDVal;
+ const gl::VertexArrayID *VertexArrayIDConstPointerVal;
+ gl::VertexArrayID *VertexArrayIDPointerVal;
+ gl::VertexAttribType VertexAttribTypeVal;
+ const char *charConstPointerVal;
+ const void *voidConstPointerVal;
+ const void *const *voidConstPointerPointerVal;
+ void *voidPointerVal;
+ void **voidPointerPointerVal;
+};
+
+template <ParamType PType, typename T>
+T GetParamVal(const ParamValue &value);
+
+template <>
+inline const AHardwareBuffer *GetParamVal<ParamType::TAHardwareBufferConstPointer,
+ const AHardwareBuffer *>(const ParamValue &value)
+{
+ return value.AHardwareBufferConstPointerVal;
+}
+
+template <>
+inline gl::AlphaTestFunc GetParamVal<ParamType::TAlphaTestFunc, gl::AlphaTestFunc>(
+ const ParamValue &value)
+{
+ return value.AlphaTestFuncVal;
+}
+
+template <>
+inline gl::BufferBinding GetParamVal<ParamType::TBufferBinding, gl::BufferBinding>(
+ const ParamValue &value)
+{
+ return value.BufferBindingVal;
+}
+
+template <>
+inline gl::BufferID GetParamVal<ParamType::TBufferID, gl::BufferID>(const ParamValue &value)
+{
+ return value.BufferIDVal;
+}
+
+template <>
+inline const gl::BufferID *GetParamVal<ParamType::TBufferIDConstPointer, const gl::BufferID *>(
+ const ParamValue &value)
+{
+ return value.BufferIDConstPointerVal;
+}
+
+template <>
+inline gl::BufferID *GetParamVal<ParamType::TBufferIDPointer, gl::BufferID *>(
+ const ParamValue &value)
+{
+ return value.BufferIDPointerVal;
+}
+
+template <>
+inline gl::BufferUsage GetParamVal<ParamType::TBufferUsage, gl::BufferUsage>(
+ const ParamValue &value)
+{
+ return value.BufferUsageVal;
+}
+
+template <>
+inline gl::ClientVertexArrayType
+GetParamVal<ParamType::TClientVertexArrayType, gl::ClientVertexArrayType>(const ParamValue &value)
+{
+ return value.ClientVertexArrayTypeVal;
+}
+
+template <>
+inline egl::CompositorTiming GetParamVal<ParamType::TCompositorTiming, egl::CompositorTiming>(
+ const ParamValue &value)
+{
+ return value.CompositorTimingVal;
+}
+
+template <>
+inline gl::CullFaceMode GetParamVal<ParamType::TCullFaceMode, gl::CullFaceMode>(
+ const ParamValue &value)
+{
+ return value.CullFaceModeVal;
+}
+
+template <>
+inline gl::DrawElementsType GetParamVal<ParamType::TDrawElementsType, gl::DrawElementsType>(
+ const ParamValue &value)
+{
+ return value.DrawElementsTypeVal;
+}
+
+template <>
+inline EGLAttrib GetParamVal<ParamType::TEGLAttrib, EGLAttrib>(const ParamValue &value)
+{
+ return value.EGLAttribVal;
+}
+
+template <>
+inline EGLAttribKHR GetParamVal<ParamType::TEGLAttribKHR, EGLAttribKHR>(const ParamValue &value)
+{
+ return value.EGLAttribKHRVal;
+}
+
+template <>
+inline EGLBoolean GetParamVal<ParamType::TEGLBoolean, EGLBoolean>(const ParamValue &value)
+{
+ return value.EGLBooleanVal;
+}
+
+template <>
+inline EGLClientBuffer GetParamVal<ParamType::TEGLClientBuffer, EGLClientBuffer>(
+ const ParamValue &value)
+{
+ return value.EGLClientBufferVal;
+}
+
+template <>
+inline EGLConfig GetParamVal<ParamType::TEGLConfig, EGLConfig>(const ParamValue &value)
+{
+ return value.EGLConfigVal;
+}
+
+template <>
+inline EGLContext GetParamVal<ParamType::TEGLContext, EGLContext>(const ParamValue &value)
+{
+ return value.EGLContextVal;
+}
+
+template <>
+inline EGLDEBUGPROCKHR GetParamVal<ParamType::TEGLDEBUGPROCKHR, EGLDEBUGPROCKHR>(
+ const ParamValue &value)
+{
+ return value.EGLDEBUGPROCKHRVal;
+}
+
+template <>
+inline EGLDeviceEXT GetParamVal<ParamType::TEGLDeviceEXT, EGLDeviceEXT>(const ParamValue &value)
+{
+ return value.EGLDeviceEXTVal;
+}
+
+template <>
+inline EGLDisplay GetParamVal<ParamType::TEGLDisplay, EGLDisplay>(const ParamValue &value)
+{
+ return value.EGLDisplayVal;
+}
+
+template <>
+inline EGLFrameTokenANGLE GetParamVal<ParamType::TEGLFrameTokenANGLE, EGLFrameTokenANGLE>(
+ const ParamValue &value)
+{
+ return value.EGLFrameTokenANGLEVal;
+}
+
+template <>
+inline EGLGetBlobFuncANDROID GetParamVal<ParamType::TEGLGetBlobFuncANDROID, EGLGetBlobFuncANDROID>(
+ const ParamValue &value)
+{
+ return value.EGLGetBlobFuncANDROIDVal;
+}
+
+template <>
+inline EGLImage GetParamVal<ParamType::TEGLImage, EGLImage>(const ParamValue &value)
+{
+ return value.EGLImageVal;
+}
+
+template <>
+inline EGLLabelKHR GetParamVal<ParamType::TEGLLabelKHR, EGLLabelKHR>(const ParamValue &value)
+{
+ return value.EGLLabelKHRVal;
+}
+
+template <>
+inline EGLNativeDisplayType GetParamVal<ParamType::TEGLNativeDisplayType, EGLNativeDisplayType>(
+ const ParamValue &value)
+{
+ return value.EGLNativeDisplayTypeVal;
+}
+
+template <>
+inline EGLNativePixmapType GetParamVal<ParamType::TEGLNativePixmapType, EGLNativePixmapType>(
+ const ParamValue &value)
+{
+ return value.EGLNativePixmapTypeVal;
+}
+
+template <>
+inline EGLNativeWindowType GetParamVal<ParamType::TEGLNativeWindowType, EGLNativeWindowType>(
+ const ParamValue &value)
+{
+ return value.EGLNativeWindowTypeVal;
+}
+
+template <>
+inline EGLObjectKHR GetParamVal<ParamType::TEGLObjectKHR, EGLObjectKHR>(const ParamValue &value)
+{
+ return value.EGLObjectKHRVal;
+}
+
+template <>
+inline EGLSetBlobFuncANDROID GetParamVal<ParamType::TEGLSetBlobFuncANDROID, EGLSetBlobFuncANDROID>(
+ const ParamValue &value)
+{
+ return value.EGLSetBlobFuncANDROIDVal;
+}
+
+template <>
+inline EGLStreamKHR GetParamVal<ParamType::TEGLStreamKHR, EGLStreamKHR>(const ParamValue &value)
+{
+ return value.EGLStreamKHRVal;
+}
+
+template <>
+inline EGLSurface GetParamVal<ParamType::TEGLSurface, EGLSurface>(const ParamValue &value)
+{
+ return value.EGLSurfaceVal;
+}
+
+template <>
+inline EGLSync GetParamVal<ParamType::TEGLSync, EGLSync>(const ParamValue &value)
+{
+ return value.EGLSyncVal;
+}
+
+template <>
+inline EGLTime GetParamVal<ParamType::TEGLTime, EGLTime>(const ParamValue &value)
+{
+ return value.EGLTimeVal;
+}
+
+template <>
+inline EGLTimeKHR GetParamVal<ParamType::TEGLTimeKHR, EGLTimeKHR>(const ParamValue &value)
+{
+ return value.EGLTimeKHRVal;
+}
+
+template <>
+inline EGLenum GetParamVal<ParamType::TEGLenum, EGLenum>(const ParamValue &value)
+{
+ return value.EGLenumVal;
+}
+
+template <>
+inline EGLint GetParamVal<ParamType::TEGLint, EGLint>(const ParamValue &value)
+{
+ return value.EGLintVal;
+}
+
+template <>
+inline EGLnsecsANDROID GetParamVal<ParamType::TEGLnsecsANDROID, EGLnsecsANDROID>(
+ const ParamValue &value)
+{
+ return value.EGLnsecsANDROIDVal;
+}
+
+template <>
+inline EGLuint64KHR GetParamVal<ParamType::TEGLuint64KHR, EGLuint64KHR>(const ParamValue &value)
+{
+ return value.EGLuint64KHRVal;
+}
+
+template <>
+inline gl::FenceNVID GetParamVal<ParamType::TFenceNVID, gl::FenceNVID>(const ParamValue &value)
+{
+ return value.FenceNVIDVal;
+}
+
+template <>
+inline const gl::FenceNVID *GetParamVal<ParamType::TFenceNVIDConstPointer, const gl::FenceNVID *>(
+ const ParamValue &value)
+{
+ return value.FenceNVIDConstPointerVal;
+}
+
+template <>
+inline gl::FenceNVID *GetParamVal<ParamType::TFenceNVIDPointer, gl::FenceNVID *>(
+ const ParamValue &value)
+{
+ return value.FenceNVIDPointerVal;
+}
+
+template <>
+inline gl::FramebufferID GetParamVal<ParamType::TFramebufferID, gl::FramebufferID>(
+ const ParamValue &value)
+{
+ return value.FramebufferIDVal;
+}
+
+template <>
+inline const gl::FramebufferID *GetParamVal<ParamType::TFramebufferIDConstPointer,
+ const gl::FramebufferID *>(const ParamValue &value)
+{
+ return value.FramebufferIDConstPointerVal;
+}
+
+template <>
+inline gl::FramebufferID *GetParamVal<ParamType::TFramebufferIDPointer, gl::FramebufferID *>(
+ const ParamValue &value)
+{
+ return value.FramebufferIDPointerVal;
+}
+
+template <>
+inline GLDEBUGPROC GetParamVal<ParamType::TGLDEBUGPROC, GLDEBUGPROC>(const ParamValue &value)
+{
+ return value.GLDEBUGPROCVal;
+}
+
+template <>
+inline GLDEBUGPROCKHR GetParamVal<ParamType::TGLDEBUGPROCKHR, GLDEBUGPROCKHR>(
+ const ParamValue &value)
+{
+ return value.GLDEBUGPROCKHRVal;
+}
+
+template <>
+inline GLbitfield GetParamVal<ParamType::TGLbitfield, GLbitfield>(const ParamValue &value)
+{
+ return value.GLbitfieldVal;
+}
+
+template <>
+inline GLboolean GetParamVal<ParamType::TGLboolean, GLboolean>(const ParamValue &value)
+{
+ return value.GLbooleanVal;
+}
+
+template <>
+inline const GLboolean *GetParamVal<ParamType::TGLbooleanConstPointer, const GLboolean *>(
+ const ParamValue &value)
+{
+ return value.GLbooleanConstPointerVal;
+}
+
+template <>
+inline GLboolean *GetParamVal<ParamType::TGLbooleanPointer, GLboolean *>(const ParamValue &value)
+{
+ return value.GLbooleanPointerVal;
+}
+
+template <>
+inline GLbyte GetParamVal<ParamType::TGLbyte, GLbyte>(const ParamValue &value)
+{
+ return value.GLbyteVal;
+}
+
+template <>
+inline const GLbyte *GetParamVal<ParamType::TGLbyteConstPointer, const GLbyte *>(
+ const ParamValue &value)
+{
+ return value.GLbyteConstPointerVal;
+}
+
+template <>
+inline const GLchar *GetParamVal<ParamType::TGLcharConstPointer, const GLchar *>(
+ const ParamValue &value)
+{
+ return value.GLcharConstPointerVal;
+}
+
+template <>
+inline const GLchar *const *
+GetParamVal<ParamType::TGLcharConstPointerPointer, const GLchar *const *>(const ParamValue &value)
+{
+ return value.GLcharConstPointerPointerVal;
+}
+
+template <>
+inline GLchar *GetParamVal<ParamType::TGLcharPointer, GLchar *>(const ParamValue &value)
+{
+ return value.GLcharPointerVal;
+}
+
+template <>
+inline GLclampx GetParamVal<ParamType::TGLclampx, GLclampx>(const ParamValue &value)
+{
+ return value.GLclampxVal;
+}
+
+template <>
+inline GLdouble GetParamVal<ParamType::TGLdouble, GLdouble>(const ParamValue &value)
+{
+ return value.GLdoubleVal;
+}
+
+template <>
+inline const GLdouble *GetParamVal<ParamType::TGLdoubleConstPointer, const GLdouble *>(
+ const ParamValue &value)
+{
+ return value.GLdoubleConstPointerVal;
+}
+
+template <>
+inline GLdouble *GetParamVal<ParamType::TGLdoublePointer, GLdouble *>(const ParamValue &value)
+{
+ return value.GLdoublePointerVal;
+}
+
+template <>
+inline GLeglClientBufferEXT GetParamVal<ParamType::TGLeglClientBufferEXT, GLeglClientBufferEXT>(
+ const ParamValue &value)
+{
+ return value.GLeglClientBufferEXTVal;
+}
+
+template <>
+inline GLeglImageOES GetParamVal<ParamType::TGLeglImageOES, GLeglImageOES>(const ParamValue &value)
+{
+ return value.GLeglImageOESVal;
+}
+
+template <>
+inline GLenum GetParamVal<ParamType::TGLenum, GLenum>(const ParamValue &value)
+{
+ return value.GLenumVal;
+}
+
+template <>
+inline const GLenum *GetParamVal<ParamType::TGLenumConstPointer, const GLenum *>(
+ const ParamValue &value)
+{
+ return value.GLenumConstPointerVal;
+}
+
+template <>
+inline GLenum *GetParamVal<ParamType::TGLenumPointer, GLenum *>(const ParamValue &value)
+{
+ return value.GLenumPointerVal;
+}
+
+template <>
+inline GLfixed GetParamVal<ParamType::TGLfixed, GLfixed>(const ParamValue &value)
+{
+ return value.GLfixedVal;
+}
+
+template <>
+inline const GLfixed *GetParamVal<ParamType::TGLfixedConstPointer, const GLfixed *>(
+ const ParamValue &value)
+{
+ return value.GLfixedConstPointerVal;
+}
+
+template <>
+inline GLfixed *GetParamVal<ParamType::TGLfixedPointer, GLfixed *>(const ParamValue &value)
+{
+ return value.GLfixedPointerVal;
+}
+
+template <>
+inline GLfloat GetParamVal<ParamType::TGLfloat, GLfloat>(const ParamValue &value)
+{
+ return value.GLfloatVal;
+}
+
+template <>
+inline const GLfloat *GetParamVal<ParamType::TGLfloatConstPointer, const GLfloat *>(
+ const ParamValue &value)
+{
+ return value.GLfloatConstPointerVal;
+}
+
+template <>
+inline GLfloat *GetParamVal<ParamType::TGLfloatPointer, GLfloat *>(const ParamValue &value)
+{
+ return value.GLfloatPointerVal;
+}
+
+template <>
+inline GLint GetParamVal<ParamType::TGLint, GLint>(const ParamValue &value)
+{
+ return value.GLintVal;
+}
+
+template <>
+inline GLint64 *GetParamVal<ParamType::TGLint64Pointer, GLint64 *>(const ParamValue &value)
+{
+ return value.GLint64PointerVal;
+}
+
+template <>
+inline const GLint *GetParamVal<ParamType::TGLintConstPointer, const GLint *>(
+ const ParamValue &value)
+{
+ return value.GLintConstPointerVal;
+}
+
+template <>
+inline GLint *GetParamVal<ParamType::TGLintPointer, GLint *>(const ParamValue &value)
+{
+ return value.GLintPointerVal;
+}
+
+template <>
+inline GLintptr GetParamVal<ParamType::TGLintptr, GLintptr>(const ParamValue &value)
+{
+ return value.GLintptrVal;
+}
+
+template <>
+inline const GLintptr *GetParamVal<ParamType::TGLintptrConstPointer, const GLintptr *>(
+ const ParamValue &value)
+{
+ return value.GLintptrConstPointerVal;
+}
+
+template <>
+inline GLshort GetParamVal<ParamType::TGLshort, GLshort>(const ParamValue &value)
+{
+ return value.GLshortVal;
+}
+
+template <>
+inline const GLshort *GetParamVal<ParamType::TGLshortConstPointer, const GLshort *>(
+ const ParamValue &value)
+{
+ return value.GLshortConstPointerVal;
+}
+
+template <>
+inline GLsizei GetParamVal<ParamType::TGLsizei, GLsizei>(const ParamValue &value)
+{
+ return value.GLsizeiVal;
+}
+
+template <>
+inline const GLsizei *GetParamVal<ParamType::TGLsizeiConstPointer, const GLsizei *>(
+ const ParamValue &value)
+{
+ return value.GLsizeiConstPointerVal;
+}
+
+template <>
+inline GLsizei *GetParamVal<ParamType::TGLsizeiPointer, GLsizei *>(const ParamValue &value)
+{
+ return value.GLsizeiPointerVal;
+}
+
+template <>
+inline GLsizeiptr GetParamVal<ParamType::TGLsizeiptr, GLsizeiptr>(const ParamValue &value)
+{
+ return value.GLsizeiptrVal;
+}
+
+template <>
+inline const GLsizeiptr *GetParamVal<ParamType::TGLsizeiptrConstPointer, const GLsizeiptr *>(
+ const ParamValue &value)
+{
+ return value.GLsizeiptrConstPointerVal;
+}
+
+template <>
+inline GLsync GetParamVal<ParamType::TGLsync, GLsync>(const ParamValue &value)
+{
+ return value.GLsyncVal;
+}
+
+template <>
+inline GLubyte GetParamVal<ParamType::TGLubyte, GLubyte>(const ParamValue &value)
+{
+ return value.GLubyteVal;
+}
+
+template <>
+inline const GLubyte *GetParamVal<ParamType::TGLubyteConstPointer, const GLubyte *>(
+ const ParamValue &value)
+{
+ return value.GLubyteConstPointerVal;
+}
+
+template <>
+inline GLubyte *GetParamVal<ParamType::TGLubytePointer, GLubyte *>(const ParamValue &value)
+{
+ return value.GLubytePointerVal;
+}
+
+template <>
+inline GLuint GetParamVal<ParamType::TGLuint, GLuint>(const ParamValue &value)
+{
+ return value.GLuintVal;
+}
+
+template <>
+inline GLuint64 GetParamVal<ParamType::TGLuint64, GLuint64>(const ParamValue &value)
+{
+ return value.GLuint64Val;
+}
+
+template <>
+inline const GLuint64 *GetParamVal<ParamType::TGLuint64ConstPointer, const GLuint64 *>(
+ const ParamValue &value)
+{
+ return value.GLuint64ConstPointerVal;
+}
+
+template <>
+inline GLuint64 *GetParamVal<ParamType::TGLuint64Pointer, GLuint64 *>(const ParamValue &value)
+{
+ return value.GLuint64PointerVal;
+}
+
+template <>
+inline const GLuint *GetParamVal<ParamType::TGLuintConstPointer, const GLuint *>(
+ const ParamValue &value)
+{
+ return value.GLuintConstPointerVal;
+}
+
+template <>
+inline GLuint *GetParamVal<ParamType::TGLuintPointer, GLuint *>(const ParamValue &value)
+{
+ return value.GLuintPointerVal;
+}
+
+template <>
+inline GLushort GetParamVal<ParamType::TGLushort, GLushort>(const ParamValue &value)
+{
+ return value.GLushortVal;
+}
+
+template <>
+inline const GLushort *GetParamVal<ParamType::TGLushortConstPointer, const GLushort *>(
+ const ParamValue &value)
+{
+ return value.GLushortConstPointerVal;
+}
+
+template <>
+inline GLushort *GetParamVal<ParamType::TGLushortPointer, GLushort *>(const ParamValue &value)
+{
+ return value.GLushortPointerVal;
+}
+
+template <>
+inline const GLvoid *GetParamVal<ParamType::TGLvoidConstPointer, const GLvoid *>(
+ const ParamValue &value)
+{
+ return value.GLvoidConstPointerVal;
+}
+
+template <>
+inline const GLvoid *const *
+GetParamVal<ParamType::TGLvoidConstPointerPointer, const GLvoid *const *>(const ParamValue &value)
+{
+ return value.GLvoidConstPointerPointerVal;
+}
+
+template <>
+inline gl::GraphicsResetStatus
+GetParamVal<ParamType::TGraphicsResetStatus, gl::GraphicsResetStatus>(const ParamValue &value)
+{
+ return value.GraphicsResetStatusVal;
+}
+
+template <>
+inline gl::HandleType GetParamVal<ParamType::THandleType, gl::HandleType>(const ParamValue &value)
+{
+ return value.HandleTypeVal;
+}
+
+template <>
+inline gl::LightParameter GetParamVal<ParamType::TLightParameter, gl::LightParameter>(
+ const ParamValue &value)
+{
+ return value.LightParameterVal;
+}
+
+template <>
+inline gl::LogicalOperation GetParamVal<ParamType::TLogicalOperation, gl::LogicalOperation>(
+ const ParamValue &value)
+{
+ return value.LogicalOperationVal;
+}
+
+template <>
+inline gl::MaterialParameter GetParamVal<ParamType::TMaterialParameter, gl::MaterialParameter>(
+ const ParamValue &value)
+{
+ return value.MaterialParameterVal;
+}
+
+template <>
+inline gl::MatrixType GetParamVal<ParamType::TMatrixType, gl::MatrixType>(const ParamValue &value)
+{
+ return value.MatrixTypeVal;
+}
+
+template <>
+inline gl::MemoryObjectID GetParamVal<ParamType::TMemoryObjectID, gl::MemoryObjectID>(
+ const ParamValue &value)
+{
+ return value.MemoryObjectIDVal;
+}
+
+template <>
+inline const gl::MemoryObjectID *GetParamVal<ParamType::TMemoryObjectIDConstPointer,
+ const gl::MemoryObjectID *>(const ParamValue &value)
+{
+ return value.MemoryObjectIDConstPointerVal;
+}
+
+template <>
+inline gl::MemoryObjectID *GetParamVal<ParamType::TMemoryObjectIDPointer, gl::MemoryObjectID *>(
+ const ParamValue &value)
+{
+ return value.MemoryObjectIDPointerVal;
+}
+
+template <>
+inline egl::ObjectType GetParamVal<ParamType::TObjectType, egl::ObjectType>(const ParamValue &value)
+{
+ return value.ObjectTypeVal;
+}
+
+template <>
+inline gl::PointParameter GetParamVal<ParamType::TPointParameter, gl::PointParameter>(
+ const ParamValue &value)
+{
+ return value.PointParameterVal;
+}
+
+template <>
+inline gl::PrimitiveMode GetParamVal<ParamType::TPrimitiveMode, gl::PrimitiveMode>(
+ const ParamValue &value)
+{
+ return value.PrimitiveModeVal;
+}
+
+template <>
+inline gl::ProgramPipelineID GetParamVal<ParamType::TProgramPipelineID, gl::ProgramPipelineID>(
+ const ParamValue &value)
+{
+ return value.ProgramPipelineIDVal;
+}
+
+template <>
+inline const gl::ProgramPipelineID *
+GetParamVal<ParamType::TProgramPipelineIDConstPointer, const gl::ProgramPipelineID *>(
+ const ParamValue &value)
+{
+ return value.ProgramPipelineIDConstPointerVal;
+}
+
+template <>
+inline gl::ProgramPipelineID *
+GetParamVal<ParamType::TProgramPipelineIDPointer, gl::ProgramPipelineID *>(const ParamValue &value)
+{
+ return value.ProgramPipelineIDPointerVal;
+}
+
+template <>
+inline gl::ProvokingVertexConvention
+GetParamVal<ParamType::TProvokingVertexConvention, gl::ProvokingVertexConvention>(
+ const ParamValue &value)
+{
+ return value.ProvokingVertexConventionVal;
+}
+
+template <>
+inline gl::QueryID GetParamVal<ParamType::TQueryID, gl::QueryID>(const ParamValue &value)
+{
+ return value.QueryIDVal;
+}
+
+template <>
+inline const gl::QueryID *GetParamVal<ParamType::TQueryIDConstPointer, const gl::QueryID *>(
+ const ParamValue &value)
+{
+ return value.QueryIDConstPointerVal;
+}
+
+template <>
+inline gl::QueryID *GetParamVal<ParamType::TQueryIDPointer, gl::QueryID *>(const ParamValue &value)
+{
+ return value.QueryIDPointerVal;
+}
+
+template <>
+inline gl::QueryType GetParamVal<ParamType::TQueryType, gl::QueryType>(const ParamValue &value)
+{
+ return value.QueryTypeVal;
+}
+
+template <>
+inline gl::RenderbufferID GetParamVal<ParamType::TRenderbufferID, gl::RenderbufferID>(
+ const ParamValue &value)
+{
+ return value.RenderbufferIDVal;
+}
+
+template <>
+inline const gl::RenderbufferID *GetParamVal<ParamType::TRenderbufferIDConstPointer,
+ const gl::RenderbufferID *>(const ParamValue &value)
+{
+ return value.RenderbufferIDConstPointerVal;
+}
+
+template <>
+inline gl::RenderbufferID *GetParamVal<ParamType::TRenderbufferIDPointer, gl::RenderbufferID *>(
+ const ParamValue &value)
+{
+ return value.RenderbufferIDPointerVal;
+}
+
+template <>
+inline gl::SamplerID GetParamVal<ParamType::TSamplerID, gl::SamplerID>(const ParamValue &value)
+{
+ return value.SamplerIDVal;
+}
+
+template <>
+inline const gl::SamplerID *GetParamVal<ParamType::TSamplerIDConstPointer, const gl::SamplerID *>(
+ const ParamValue &value)
+{
+ return value.SamplerIDConstPointerVal;
+}
+
+template <>
+inline gl::SamplerID *GetParamVal<ParamType::TSamplerIDPointer, gl::SamplerID *>(
+ const ParamValue &value)
+{
+ return value.SamplerIDPointerVal;
+}
+
+template <>
+inline gl::SemaphoreID GetParamVal<ParamType::TSemaphoreID, gl::SemaphoreID>(
+ const ParamValue &value)
+{
+ return value.SemaphoreIDVal;
+}
+
+template <>
+inline const gl::SemaphoreID *
+GetParamVal<ParamType::TSemaphoreIDConstPointer, const gl::SemaphoreID *>(const ParamValue &value)
+{
+ return value.SemaphoreIDConstPointerVal;
+}
+
+template <>
+inline gl::SemaphoreID *GetParamVal<ParamType::TSemaphoreIDPointer, gl::SemaphoreID *>(
+ const ParamValue &value)
+{
+ return value.SemaphoreIDPointerVal;
+}
+
+template <>
+inline gl::ShaderProgramID GetParamVal<ParamType::TShaderProgramID, gl::ShaderProgramID>(
+ const ParamValue &value)
+{
+ return value.ShaderProgramIDVal;
+}
+
+template <>
+inline const gl::ShaderProgramID *GetParamVal<ParamType::TShaderProgramIDConstPointer,
+ const gl::ShaderProgramID *>(const ParamValue &value)
+{
+ return value.ShaderProgramIDConstPointerVal;
+}
+
+template <>
+inline gl::ShaderProgramID *GetParamVal<ParamType::TShaderProgramIDPointer, gl::ShaderProgramID *>(
+ const ParamValue &value)
+{
+ return value.ShaderProgramIDPointerVal;
+}
+
+template <>
+inline gl::ShaderType GetParamVal<ParamType::TShaderType, gl::ShaderType>(const ParamValue &value)
+{
+ return value.ShaderTypeVal;
+}
+
+template <>
+inline gl::ShadingModel GetParamVal<ParamType::TShadingModel, gl::ShadingModel>(
+ const ParamValue &value)
+{
+ return value.ShadingModelVal;
+}
+
+template <>
+inline gl::TextureEnvParameter
+GetParamVal<ParamType::TTextureEnvParameter, gl::TextureEnvParameter>(const ParamValue &value)
+{
+ return value.TextureEnvParameterVal;
+}
+
+template <>
+inline gl::TextureEnvTarget GetParamVal<ParamType::TTextureEnvTarget, gl::TextureEnvTarget>(
+ const ParamValue &value)
+{
+ return value.TextureEnvTargetVal;
+}
+
+template <>
+inline gl::TextureID GetParamVal<ParamType::TTextureID, gl::TextureID>(const ParamValue &value)
+{
+ return value.TextureIDVal;
+}
+
+template <>
+inline const gl::TextureID *GetParamVal<ParamType::TTextureIDConstPointer, const gl::TextureID *>(
+ const ParamValue &value)
+{
+ return value.TextureIDConstPointerVal;
+}
+
+template <>
+inline gl::TextureID *GetParamVal<ParamType::TTextureIDPointer, gl::TextureID *>(
+ const ParamValue &value)
+{
+ return value.TextureIDPointerVal;
+}
+
+template <>
+inline gl::TextureTarget GetParamVal<ParamType::TTextureTarget, gl::TextureTarget>(
+ const ParamValue &value)
+{
+ return value.TextureTargetVal;
+}
+
+template <>
+inline gl::TextureType GetParamVal<ParamType::TTextureType, gl::TextureType>(
+ const ParamValue &value)
+{
+ return value.TextureTypeVal;
+}
+
+template <>
+inline egl::Timestamp GetParamVal<ParamType::TTimestamp, egl::Timestamp>(const ParamValue &value)
+{
+ return value.TimestampVal;
+}
+
+template <>
+inline gl::TransformFeedbackID
+GetParamVal<ParamType::TTransformFeedbackID, gl::TransformFeedbackID>(const ParamValue &value)
+{
+ return value.TransformFeedbackIDVal;
+}
+
+template <>
+inline const gl::TransformFeedbackID *
+GetParamVal<ParamType::TTransformFeedbackIDConstPointer, const gl::TransformFeedbackID *>(
+ const ParamValue &value)
+{
+ return value.TransformFeedbackIDConstPointerVal;
+}
+
+template <>
+inline gl::TransformFeedbackID *GetParamVal<ParamType::TTransformFeedbackIDPointer,
+ gl::TransformFeedbackID *>(const ParamValue &value)
+{
+ return value.TransformFeedbackIDPointerVal;
+}
+
+template <>
+inline gl::UniformBlockIndex GetParamVal<ParamType::TUniformBlockIndex, gl::UniformBlockIndex>(
+ const ParamValue &value)
+{
+ return value.UniformBlockIndexVal;
+}
+
+template <>
+inline gl::UniformLocation GetParamVal<ParamType::TUniformLocation, gl::UniformLocation>(
+ const ParamValue &value)
+{
+ return value.UniformLocationVal;
+}
+
+template <>
+inline gl::VertexArrayID GetParamVal<ParamType::TVertexArrayID, gl::VertexArrayID>(
+ const ParamValue &value)
+{
+ return value.VertexArrayIDVal;
+}
+
+template <>
+inline const gl::VertexArrayID *GetParamVal<ParamType::TVertexArrayIDConstPointer,
+ const gl::VertexArrayID *>(const ParamValue &value)
+{
+ return value.VertexArrayIDConstPointerVal;
+}
+
+template <>
+inline gl::VertexArrayID *GetParamVal<ParamType::TVertexArrayIDPointer, gl::VertexArrayID *>(
+ const ParamValue &value)
+{
+ return value.VertexArrayIDPointerVal;
+}
+
+template <>
+inline gl::VertexAttribType GetParamVal<ParamType::TVertexAttribType, gl::VertexAttribType>(
+ const ParamValue &value)
+{
+ return value.VertexAttribTypeVal;
+}
+
+template <>
+inline const char *GetParamVal<ParamType::TcharConstPointer, const char *>(const ParamValue &value)
+{
+ return value.charConstPointerVal;
+}
+
+template <>
+inline const void *GetParamVal<ParamType::TvoidConstPointer, const void *>(const ParamValue &value)
+{
+ return value.voidConstPointerVal;
+}
+
+template <>
+inline const void *const *GetParamVal<ParamType::TvoidConstPointerPointer, const void *const *>(
+ const ParamValue &value)
+{
+ return value.voidConstPointerPointerVal;
+}
+
+template <>
+inline void *GetParamVal<ParamType::TvoidPointer, void *>(const ParamValue &value)
+{
+ return value.voidPointerVal;
+}
+
+template <>
+inline void **GetParamVal<ParamType::TvoidPointerPointer, void **>(const ParamValue &value)
+{
+ return value.voidPointerPointerVal;
+}
+
+template <ParamType PType, typename T>
+T GetParamVal(const ParamValue &value)
+{
+ UNREACHABLE();
+ return T();
+}
+
+template <typename T>
+T AccessParamValue(ParamType paramType, const ParamValue &value)
+{
+ switch (paramType)
+ {
+ case ParamType::TAHardwareBufferConstPointer:
+ return GetParamVal<ParamType::TAHardwareBufferConstPointer, T>(value);
+ case ParamType::TAlphaTestFunc:
+ return GetParamVal<ParamType::TAlphaTestFunc, T>(value);
+ case ParamType::TBufferBinding:
+ return GetParamVal<ParamType::TBufferBinding, T>(value);
+ case ParamType::TBufferID:
+ return GetParamVal<ParamType::TBufferID, T>(value);
+ case ParamType::TBufferIDConstPointer:
+ return GetParamVal<ParamType::TBufferIDConstPointer, T>(value);
+ case ParamType::TBufferIDPointer:
+ return GetParamVal<ParamType::TBufferIDPointer, T>(value);
+ case ParamType::TBufferUsage:
+ return GetParamVal<ParamType::TBufferUsage, T>(value);
+ case ParamType::TClientVertexArrayType:
+ return GetParamVal<ParamType::TClientVertexArrayType, T>(value);
+ case ParamType::TCompositorTiming:
+ return GetParamVal<ParamType::TCompositorTiming, T>(value);
+ case ParamType::TCullFaceMode:
+ return GetParamVal<ParamType::TCullFaceMode, T>(value);
+ case ParamType::TDrawElementsType:
+ return GetParamVal<ParamType::TDrawElementsType, T>(value);
+ case ParamType::TEGLAttrib:
+ return GetParamVal<ParamType::TEGLAttrib, T>(value);
+ case ParamType::TEGLAttribKHR:
+ return GetParamVal<ParamType::TEGLAttribKHR, T>(value);
+ case ParamType::TEGLBoolean:
+ return GetParamVal<ParamType::TEGLBoolean, T>(value);
+ case ParamType::TEGLClientBuffer:
+ return GetParamVal<ParamType::TEGLClientBuffer, T>(value);
+ case ParamType::TEGLConfig:
+ return GetParamVal<ParamType::TEGLConfig, T>(value);
+ case ParamType::TEGLContext:
+ return GetParamVal<ParamType::TEGLContext, T>(value);
+ case ParamType::TEGLDEBUGPROCKHR:
+ return GetParamVal<ParamType::TEGLDEBUGPROCKHR, T>(value);
+ case ParamType::TEGLDeviceEXT:
+ return GetParamVal<ParamType::TEGLDeviceEXT, T>(value);
+ case ParamType::TEGLDisplay:
+ return GetParamVal<ParamType::TEGLDisplay, T>(value);
+ case ParamType::TEGLFrameTokenANGLE:
+ return GetParamVal<ParamType::TEGLFrameTokenANGLE, T>(value);
+ case ParamType::TEGLGetBlobFuncANDROID:
+ return GetParamVal<ParamType::TEGLGetBlobFuncANDROID, T>(value);
+ case ParamType::TEGLImage:
+ return GetParamVal<ParamType::TEGLImage, T>(value);
+ case ParamType::TEGLLabelKHR:
+ return GetParamVal<ParamType::TEGLLabelKHR, T>(value);
+ case ParamType::TEGLNativeDisplayType:
+ return GetParamVal<ParamType::TEGLNativeDisplayType, T>(value);
+ case ParamType::TEGLNativePixmapType:
+ return GetParamVal<ParamType::TEGLNativePixmapType, T>(value);
+ case ParamType::TEGLNativeWindowType:
+ return GetParamVal<ParamType::TEGLNativeWindowType, T>(value);
+ case ParamType::TEGLObjectKHR:
+ return GetParamVal<ParamType::TEGLObjectKHR, T>(value);
+ case ParamType::TEGLSetBlobFuncANDROID:
+ return GetParamVal<ParamType::TEGLSetBlobFuncANDROID, T>(value);
+ case ParamType::TEGLStreamKHR:
+ return GetParamVal<ParamType::TEGLStreamKHR, T>(value);
+ case ParamType::TEGLSurface:
+ return GetParamVal<ParamType::TEGLSurface, T>(value);
+ case ParamType::TEGLSync:
+ return GetParamVal<ParamType::TEGLSync, T>(value);
+ case ParamType::TEGLTime:
+ return GetParamVal<ParamType::TEGLTime, T>(value);
+ case ParamType::TEGLTimeKHR:
+ return GetParamVal<ParamType::TEGLTimeKHR, T>(value);
+ case ParamType::TEGLenum:
+ return GetParamVal<ParamType::TEGLenum, T>(value);
+ case ParamType::TEGLint:
+ return GetParamVal<ParamType::TEGLint, T>(value);
+ case ParamType::TEGLnsecsANDROID:
+ return GetParamVal<ParamType::TEGLnsecsANDROID, T>(value);
+ case ParamType::TEGLuint64KHR:
+ return GetParamVal<ParamType::TEGLuint64KHR, T>(value);
+ case ParamType::TFenceNVID:
+ return GetParamVal<ParamType::TFenceNVID, T>(value);
+ case ParamType::TFenceNVIDConstPointer:
+ return GetParamVal<ParamType::TFenceNVIDConstPointer, T>(value);
+ case ParamType::TFenceNVIDPointer:
+ return GetParamVal<ParamType::TFenceNVIDPointer, T>(value);
+ case ParamType::TFramebufferID:
+ return GetParamVal<ParamType::TFramebufferID, T>(value);
+ case ParamType::TFramebufferIDConstPointer:
+ return GetParamVal<ParamType::TFramebufferIDConstPointer, T>(value);
+ case ParamType::TFramebufferIDPointer:
+ return GetParamVal<ParamType::TFramebufferIDPointer, T>(value);
+ case ParamType::TGLDEBUGPROC:
+ return GetParamVal<ParamType::TGLDEBUGPROC, T>(value);
+ case ParamType::TGLDEBUGPROCKHR:
+ return GetParamVal<ParamType::TGLDEBUGPROCKHR, T>(value);
+ case ParamType::TGLbitfield:
+ return GetParamVal<ParamType::TGLbitfield, T>(value);
+ case ParamType::TGLboolean:
+ return GetParamVal<ParamType::TGLboolean, T>(value);
+ case ParamType::TGLbooleanConstPointer:
+ return GetParamVal<ParamType::TGLbooleanConstPointer, T>(value);
+ case ParamType::TGLbooleanPointer:
+ return GetParamVal<ParamType::TGLbooleanPointer, T>(value);
+ case ParamType::TGLbyte:
+ return GetParamVal<ParamType::TGLbyte, T>(value);
+ case ParamType::TGLbyteConstPointer:
+ return GetParamVal<ParamType::TGLbyteConstPointer, T>(value);
+ case ParamType::TGLcharConstPointer:
+ return GetParamVal<ParamType::TGLcharConstPointer, T>(value);
+ case ParamType::TGLcharConstPointerPointer:
+ return GetParamVal<ParamType::TGLcharConstPointerPointer, T>(value);
+ case ParamType::TGLcharPointer:
+ return GetParamVal<ParamType::TGLcharPointer, T>(value);
+ case ParamType::TGLclampx:
+ return GetParamVal<ParamType::TGLclampx, T>(value);
+ case ParamType::TGLdouble:
+ return GetParamVal<ParamType::TGLdouble, T>(value);
+ case ParamType::TGLdoubleConstPointer:
+ return GetParamVal<ParamType::TGLdoubleConstPointer, T>(value);
+ case ParamType::TGLdoublePointer:
+ return GetParamVal<ParamType::TGLdoublePointer, T>(value);
+ case ParamType::TGLeglClientBufferEXT:
+ return GetParamVal<ParamType::TGLeglClientBufferEXT, T>(value);
+ case ParamType::TGLeglImageOES:
+ return GetParamVal<ParamType::TGLeglImageOES, T>(value);
+ case ParamType::TGLenum:
+ return GetParamVal<ParamType::TGLenum, T>(value);
+ case ParamType::TGLenumConstPointer:
+ return GetParamVal<ParamType::TGLenumConstPointer, T>(value);
+ case ParamType::TGLenumPointer:
+ return GetParamVal<ParamType::TGLenumPointer, T>(value);
+ case ParamType::TGLfixed:
+ return GetParamVal<ParamType::TGLfixed, T>(value);
+ case ParamType::TGLfixedConstPointer:
+ return GetParamVal<ParamType::TGLfixedConstPointer, T>(value);
+ case ParamType::TGLfixedPointer:
+ return GetParamVal<ParamType::TGLfixedPointer, T>(value);
+ case ParamType::TGLfloat:
+ return GetParamVal<ParamType::TGLfloat, T>(value);
+ case ParamType::TGLfloatConstPointer:
+ return GetParamVal<ParamType::TGLfloatConstPointer, T>(value);
+ case ParamType::TGLfloatPointer:
+ return GetParamVal<ParamType::TGLfloatPointer, T>(value);
+ case ParamType::TGLint:
+ return GetParamVal<ParamType::TGLint, T>(value);
+ case ParamType::TGLint64Pointer:
+ return GetParamVal<ParamType::TGLint64Pointer, T>(value);
+ case ParamType::TGLintConstPointer:
+ return GetParamVal<ParamType::TGLintConstPointer, T>(value);
+ case ParamType::TGLintPointer:
+ return GetParamVal<ParamType::TGLintPointer, T>(value);
+ case ParamType::TGLintptr:
+ return GetParamVal<ParamType::TGLintptr, T>(value);
+ case ParamType::TGLintptrConstPointer:
+ return GetParamVal<ParamType::TGLintptrConstPointer, T>(value);
+ case ParamType::TGLshort:
+ return GetParamVal<ParamType::TGLshort, T>(value);
+ case ParamType::TGLshortConstPointer:
+ return GetParamVal<ParamType::TGLshortConstPointer, T>(value);
+ case ParamType::TGLsizei:
+ return GetParamVal<ParamType::TGLsizei, T>(value);
+ case ParamType::TGLsizeiConstPointer:
+ return GetParamVal<ParamType::TGLsizeiConstPointer, T>(value);
+ case ParamType::TGLsizeiPointer:
+ return GetParamVal<ParamType::TGLsizeiPointer, T>(value);
+ case ParamType::TGLsizeiptr:
+ return GetParamVal<ParamType::TGLsizeiptr, T>(value);
+ case ParamType::TGLsizeiptrConstPointer:
+ return GetParamVal<ParamType::TGLsizeiptrConstPointer, T>(value);
+ case ParamType::TGLsync:
+ return GetParamVal<ParamType::TGLsync, T>(value);
+ case ParamType::TGLubyte:
+ return GetParamVal<ParamType::TGLubyte, T>(value);
+ case ParamType::TGLubyteConstPointer:
+ return GetParamVal<ParamType::TGLubyteConstPointer, T>(value);
+ case ParamType::TGLubytePointer:
+ return GetParamVal<ParamType::TGLubytePointer, T>(value);
+ case ParamType::TGLuint:
+ return GetParamVal<ParamType::TGLuint, T>(value);
+ case ParamType::TGLuint64:
+ return GetParamVal<ParamType::TGLuint64, T>(value);
+ case ParamType::TGLuint64ConstPointer:
+ return GetParamVal<ParamType::TGLuint64ConstPointer, T>(value);
+ case ParamType::TGLuint64Pointer:
+ return GetParamVal<ParamType::TGLuint64Pointer, T>(value);
+ case ParamType::TGLuintConstPointer:
+ return GetParamVal<ParamType::TGLuintConstPointer, T>(value);
+ case ParamType::TGLuintPointer:
+ return GetParamVal<ParamType::TGLuintPointer, T>(value);
+ case ParamType::TGLushort:
+ return GetParamVal<ParamType::TGLushort, T>(value);
+ case ParamType::TGLushortConstPointer:
+ return GetParamVal<ParamType::TGLushortConstPointer, T>(value);
+ case ParamType::TGLushortPointer:
+ return GetParamVal<ParamType::TGLushortPointer, T>(value);
+ case ParamType::TGLvoidConstPointer:
+ return GetParamVal<ParamType::TGLvoidConstPointer, T>(value);
+ case ParamType::TGLvoidConstPointerPointer:
+ return GetParamVal<ParamType::TGLvoidConstPointerPointer, T>(value);
+ case ParamType::TGraphicsResetStatus:
+ return GetParamVal<ParamType::TGraphicsResetStatus, T>(value);
+ case ParamType::THandleType:
+ return GetParamVal<ParamType::THandleType, T>(value);
+ case ParamType::TLightParameter:
+ return GetParamVal<ParamType::TLightParameter, T>(value);
+ case ParamType::TLogicalOperation:
+ return GetParamVal<ParamType::TLogicalOperation, T>(value);
+ case ParamType::TMaterialParameter:
+ return GetParamVal<ParamType::TMaterialParameter, T>(value);
+ case ParamType::TMatrixType:
+ return GetParamVal<ParamType::TMatrixType, T>(value);
+ case ParamType::TMemoryObjectID:
+ return GetParamVal<ParamType::TMemoryObjectID, T>(value);
+ case ParamType::TMemoryObjectIDConstPointer:
+ return GetParamVal<ParamType::TMemoryObjectIDConstPointer, T>(value);
+ case ParamType::TMemoryObjectIDPointer:
+ return GetParamVal<ParamType::TMemoryObjectIDPointer, T>(value);
+ case ParamType::TObjectType:
+ return GetParamVal<ParamType::TObjectType, T>(value);
+ case ParamType::TPointParameter:
+ return GetParamVal<ParamType::TPointParameter, T>(value);
+ case ParamType::TPrimitiveMode:
+ return GetParamVal<ParamType::TPrimitiveMode, T>(value);
+ case ParamType::TProgramPipelineID:
+ return GetParamVal<ParamType::TProgramPipelineID, T>(value);
+ case ParamType::TProgramPipelineIDConstPointer:
+ return GetParamVal<ParamType::TProgramPipelineIDConstPointer, T>(value);
+ case ParamType::TProgramPipelineIDPointer:
+ return GetParamVal<ParamType::TProgramPipelineIDPointer, T>(value);
+ case ParamType::TProvokingVertexConvention:
+ return GetParamVal<ParamType::TProvokingVertexConvention, T>(value);
+ case ParamType::TQueryID:
+ return GetParamVal<ParamType::TQueryID, T>(value);
+ case ParamType::TQueryIDConstPointer:
+ return GetParamVal<ParamType::TQueryIDConstPointer, T>(value);
+ case ParamType::TQueryIDPointer:
+ return GetParamVal<ParamType::TQueryIDPointer, T>(value);
+ case ParamType::TQueryType:
+ return GetParamVal<ParamType::TQueryType, T>(value);
+ case ParamType::TRenderbufferID:
+ return GetParamVal<ParamType::TRenderbufferID, T>(value);
+ case ParamType::TRenderbufferIDConstPointer:
+ return GetParamVal<ParamType::TRenderbufferIDConstPointer, T>(value);
+ case ParamType::TRenderbufferIDPointer:
+ return GetParamVal<ParamType::TRenderbufferIDPointer, T>(value);
+ case ParamType::TSamplerID:
+ return GetParamVal<ParamType::TSamplerID, T>(value);
+ case ParamType::TSamplerIDConstPointer:
+ return GetParamVal<ParamType::TSamplerIDConstPointer, T>(value);
+ case ParamType::TSamplerIDPointer:
+ return GetParamVal<ParamType::TSamplerIDPointer, T>(value);
+ case ParamType::TSemaphoreID:
+ return GetParamVal<ParamType::TSemaphoreID, T>(value);
+ case ParamType::TSemaphoreIDConstPointer:
+ return GetParamVal<ParamType::TSemaphoreIDConstPointer, T>(value);
+ case ParamType::TSemaphoreIDPointer:
+ return GetParamVal<ParamType::TSemaphoreIDPointer, T>(value);
+ case ParamType::TShaderProgramID:
+ return GetParamVal<ParamType::TShaderProgramID, T>(value);
+ case ParamType::TShaderProgramIDConstPointer:
+ return GetParamVal<ParamType::TShaderProgramIDConstPointer, T>(value);
+ case ParamType::TShaderProgramIDPointer:
+ return GetParamVal<ParamType::TShaderProgramIDPointer, T>(value);
+ case ParamType::TShaderType:
+ return GetParamVal<ParamType::TShaderType, T>(value);
+ case ParamType::TShadingModel:
+ return GetParamVal<ParamType::TShadingModel, T>(value);
+ case ParamType::TTextureEnvParameter:
+ return GetParamVal<ParamType::TTextureEnvParameter, T>(value);
+ case ParamType::TTextureEnvTarget:
+ return GetParamVal<ParamType::TTextureEnvTarget, T>(value);
+ case ParamType::TTextureID:
+ return GetParamVal<ParamType::TTextureID, T>(value);
+ case ParamType::TTextureIDConstPointer:
+ return GetParamVal<ParamType::TTextureIDConstPointer, T>(value);
+ case ParamType::TTextureIDPointer:
+ return GetParamVal<ParamType::TTextureIDPointer, T>(value);
+ case ParamType::TTextureTarget:
+ return GetParamVal<ParamType::TTextureTarget, T>(value);
+ case ParamType::TTextureType:
+ return GetParamVal<ParamType::TTextureType, T>(value);
+ case ParamType::TTimestamp:
+ return GetParamVal<ParamType::TTimestamp, T>(value);
+ case ParamType::TTransformFeedbackID:
+ return GetParamVal<ParamType::TTransformFeedbackID, T>(value);
+ case ParamType::TTransformFeedbackIDConstPointer:
+ return GetParamVal<ParamType::TTransformFeedbackIDConstPointer, T>(value);
+ case ParamType::TTransformFeedbackIDPointer:
+ return GetParamVal<ParamType::TTransformFeedbackIDPointer, T>(value);
+ case ParamType::TUniformBlockIndex:
+ return GetParamVal<ParamType::TUniformBlockIndex, T>(value);
+ case ParamType::TUniformLocation:
+ return GetParamVal<ParamType::TUniformLocation, T>(value);
+ case ParamType::TVertexArrayID:
+ return GetParamVal<ParamType::TVertexArrayID, T>(value);
+ case ParamType::TVertexArrayIDConstPointer:
+ return GetParamVal<ParamType::TVertexArrayIDConstPointer, T>(value);
+ case ParamType::TVertexArrayIDPointer:
+ return GetParamVal<ParamType::TVertexArrayIDPointer, T>(value);
+ case ParamType::TVertexAttribType:
+ return GetParamVal<ParamType::TVertexAttribType, T>(value);
+ case ParamType::TcharConstPointer:
+ return GetParamVal<ParamType::TcharConstPointer, T>(value);
+ case ParamType::TvoidConstPointer:
+ return GetParamVal<ParamType::TvoidConstPointer, T>(value);
+ case ParamType::TvoidConstPointerPointer:
+ return GetParamVal<ParamType::TvoidConstPointerPointer, T>(value);
+ case ParamType::TvoidPointer:
+ return GetParamVal<ParamType::TvoidPointer, T>(value);
+ case ParamType::TvoidPointerPointer:
+ return GetParamVal<ParamType::TvoidPointerPointer, T>(value);
+ }
+ UNREACHABLE();
+ return T();
+}
+
+template <ParamType PType, typename T>
+void SetParamVal(T valueIn, ParamValue *valueOut);
+
+template <>
+inline void SetParamVal<ParamType::TAHardwareBufferConstPointer>(const AHardwareBuffer *valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->AHardwareBufferConstPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TAlphaTestFunc>(gl::AlphaTestFunc valueIn, ParamValue *valueOut)
+{
+ valueOut->AlphaTestFuncVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TBufferBinding>(gl::BufferBinding valueIn, ParamValue *valueOut)
+{
+ valueOut->BufferBindingVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TBufferID>(gl::BufferID valueIn, ParamValue *valueOut)
+{
+ valueOut->BufferIDVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TBufferIDConstPointer>(const gl::BufferID *valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->BufferIDConstPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TBufferIDPointer>(gl::BufferID *valueIn, ParamValue *valueOut)
+{
+ valueOut->BufferIDPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TBufferUsage>(gl::BufferUsage valueIn, ParamValue *valueOut)
+{
+ valueOut->BufferUsageVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TClientVertexArrayType>(gl::ClientVertexArrayType valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->ClientVertexArrayTypeVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TCompositorTiming>(egl::CompositorTiming valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->CompositorTimingVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TCullFaceMode>(gl::CullFaceMode valueIn, ParamValue *valueOut)
+{
+ valueOut->CullFaceModeVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TDrawElementsType>(gl::DrawElementsType valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->DrawElementsTypeVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TEGLAttrib>(EGLAttrib valueIn, ParamValue *valueOut)
+{
+ valueOut->EGLAttribVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TEGLAttribKHR>(EGLAttribKHR valueIn, ParamValue *valueOut)
+{
+ valueOut->EGLAttribKHRVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TEGLBoolean>(EGLBoolean valueIn, ParamValue *valueOut)
+{
+ valueOut->EGLBooleanVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TEGLClientBuffer>(EGLClientBuffer valueIn, ParamValue *valueOut)
+{
+ valueOut->EGLClientBufferVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TEGLConfig>(EGLConfig valueIn, ParamValue *valueOut)
+{
+ valueOut->EGLConfigVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TEGLContext>(EGLContext valueIn, ParamValue *valueOut)
+{
+ valueOut->EGLContextVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TEGLDEBUGPROCKHR>(EGLDEBUGPROCKHR valueIn, ParamValue *valueOut)
+{
+ valueOut->EGLDEBUGPROCKHRVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TEGLDeviceEXT>(EGLDeviceEXT valueIn, ParamValue *valueOut)
+{
+ valueOut->EGLDeviceEXTVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TEGLDisplay>(EGLDisplay valueIn, ParamValue *valueOut)
+{
+ valueOut->EGLDisplayVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TEGLFrameTokenANGLE>(EGLFrameTokenANGLE valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->EGLFrameTokenANGLEVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TEGLGetBlobFuncANDROID>(EGLGetBlobFuncANDROID valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->EGLGetBlobFuncANDROIDVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TEGLImage>(EGLImage valueIn, ParamValue *valueOut)
+{
+ valueOut->EGLImageVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TEGLLabelKHR>(EGLLabelKHR valueIn, ParamValue *valueOut)
+{
+ valueOut->EGLLabelKHRVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TEGLNativeDisplayType>(EGLNativeDisplayType valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->EGLNativeDisplayTypeVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TEGLNativePixmapType>(EGLNativePixmapType valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->EGLNativePixmapTypeVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TEGLNativeWindowType>(EGLNativeWindowType valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->EGLNativeWindowTypeVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TEGLObjectKHR>(EGLObjectKHR valueIn, ParamValue *valueOut)
+{
+ valueOut->EGLObjectKHRVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TEGLSetBlobFuncANDROID>(EGLSetBlobFuncANDROID valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->EGLSetBlobFuncANDROIDVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TEGLStreamKHR>(EGLStreamKHR valueIn, ParamValue *valueOut)
+{
+ valueOut->EGLStreamKHRVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TEGLSurface>(EGLSurface valueIn, ParamValue *valueOut)
+{
+ valueOut->EGLSurfaceVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TEGLSync>(EGLSync valueIn, ParamValue *valueOut)
+{
+ valueOut->EGLSyncVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TEGLTime>(EGLTime valueIn, ParamValue *valueOut)
+{
+ valueOut->EGLTimeVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TEGLTimeKHR>(EGLTimeKHR valueIn, ParamValue *valueOut)
+{
+ valueOut->EGLTimeKHRVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TEGLenum>(EGLenum valueIn, ParamValue *valueOut)
+{
+ valueOut->EGLenumVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TEGLint>(EGLint valueIn, ParamValue *valueOut)
+{
+ valueOut->EGLintVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TEGLnsecsANDROID>(EGLnsecsANDROID valueIn, ParamValue *valueOut)
+{
+ valueOut->EGLnsecsANDROIDVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TEGLuint64KHR>(EGLuint64KHR valueIn, ParamValue *valueOut)
+{
+ valueOut->EGLuint64KHRVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TFenceNVID>(gl::FenceNVID valueIn, ParamValue *valueOut)
+{
+ valueOut->FenceNVIDVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TFenceNVIDConstPointer>(const gl::FenceNVID *valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->FenceNVIDConstPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TFenceNVIDPointer>(gl::FenceNVID *valueIn, ParamValue *valueOut)
+{
+ valueOut->FenceNVIDPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TFramebufferID>(gl::FramebufferID valueIn, ParamValue *valueOut)
+{
+ valueOut->FramebufferIDVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TFramebufferIDConstPointer>(const gl::FramebufferID *valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->FramebufferIDConstPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TFramebufferIDPointer>(gl::FramebufferID *valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->FramebufferIDPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLDEBUGPROC>(GLDEBUGPROC valueIn, ParamValue *valueOut)
+{
+ valueOut->GLDEBUGPROCVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLDEBUGPROCKHR>(GLDEBUGPROCKHR valueIn, ParamValue *valueOut)
+{
+ valueOut->GLDEBUGPROCKHRVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLbitfield>(GLbitfield valueIn, ParamValue *valueOut)
+{
+ valueOut->GLbitfieldVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLboolean>(GLboolean valueIn, ParamValue *valueOut)
+{
+ valueOut->GLbooleanVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLbooleanConstPointer>(const GLboolean *valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->GLbooleanConstPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLbooleanPointer>(GLboolean *valueIn, ParamValue *valueOut)
+{
+ valueOut->GLbooleanPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLbyte>(GLbyte valueIn, ParamValue *valueOut)
+{
+ valueOut->GLbyteVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLbyteConstPointer>(const GLbyte *valueIn, ParamValue *valueOut)
+{
+ valueOut->GLbyteConstPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLcharConstPointer>(const GLchar *valueIn, ParamValue *valueOut)
+{
+ valueOut->GLcharConstPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLcharConstPointerPointer>(const GLchar *const *valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->GLcharConstPointerPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLcharPointer>(GLchar *valueIn, ParamValue *valueOut)
+{
+ valueOut->GLcharPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLclampx>(GLclampx valueIn, ParamValue *valueOut)
+{
+ valueOut->GLclampxVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLdouble>(GLdouble valueIn, ParamValue *valueOut)
+{
+ valueOut->GLdoubleVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLdoubleConstPointer>(const GLdouble *valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->GLdoubleConstPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLdoublePointer>(GLdouble *valueIn, ParamValue *valueOut)
+{
+ valueOut->GLdoublePointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLeglClientBufferEXT>(GLeglClientBufferEXT valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->GLeglClientBufferEXTVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLeglImageOES>(GLeglImageOES valueIn, ParamValue *valueOut)
+{
+ valueOut->GLeglImageOESVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLenum>(GLenum valueIn, ParamValue *valueOut)
+{
+ valueOut->GLenumVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLenumConstPointer>(const GLenum *valueIn, ParamValue *valueOut)
+{
+ valueOut->GLenumConstPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLenumPointer>(GLenum *valueIn, ParamValue *valueOut)
+{
+ valueOut->GLenumPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLfixed>(GLfixed valueIn, ParamValue *valueOut)
+{
+ valueOut->GLfixedVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLfixedConstPointer>(const GLfixed *valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->GLfixedConstPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLfixedPointer>(GLfixed *valueIn, ParamValue *valueOut)
+{
+ valueOut->GLfixedPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLfloat>(GLfloat valueIn, ParamValue *valueOut)
+{
+ valueOut->GLfloatVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLfloatConstPointer>(const GLfloat *valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->GLfloatConstPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLfloatPointer>(GLfloat *valueIn, ParamValue *valueOut)
+{
+ valueOut->GLfloatPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLint>(GLint valueIn, ParamValue *valueOut)
+{
+ valueOut->GLintVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLint64Pointer>(GLint64 *valueIn, ParamValue *valueOut)
+{
+ valueOut->GLint64PointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLintConstPointer>(const GLint *valueIn, ParamValue *valueOut)
+{
+ valueOut->GLintConstPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLintPointer>(GLint *valueIn, ParamValue *valueOut)
+{
+ valueOut->GLintPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLintptr>(GLintptr valueIn, ParamValue *valueOut)
+{
+ valueOut->GLintptrVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLintptrConstPointer>(const GLintptr *valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->GLintptrConstPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLshort>(GLshort valueIn, ParamValue *valueOut)
+{
+ valueOut->GLshortVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLshortConstPointer>(const GLshort *valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->GLshortConstPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLsizei>(GLsizei valueIn, ParamValue *valueOut)
+{
+ valueOut->GLsizeiVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLsizeiConstPointer>(const GLsizei *valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->GLsizeiConstPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLsizeiPointer>(GLsizei *valueIn, ParamValue *valueOut)
+{
+ valueOut->GLsizeiPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLsizeiptr>(GLsizeiptr valueIn, ParamValue *valueOut)
+{
+ valueOut->GLsizeiptrVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLsizeiptrConstPointer>(const GLsizeiptr *valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->GLsizeiptrConstPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLsync>(GLsync valueIn, ParamValue *valueOut)
+{
+ valueOut->GLsyncVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLubyte>(GLubyte valueIn, ParamValue *valueOut)
+{
+ valueOut->GLubyteVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLubyteConstPointer>(const GLubyte *valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->GLubyteConstPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLubytePointer>(GLubyte *valueIn, ParamValue *valueOut)
+{
+ valueOut->GLubytePointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLuint>(GLuint valueIn, ParamValue *valueOut)
+{
+ valueOut->GLuintVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLuint64>(GLuint64 valueIn, ParamValue *valueOut)
+{
+ valueOut->GLuint64Val = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLuint64ConstPointer>(const GLuint64 *valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->GLuint64ConstPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLuint64Pointer>(GLuint64 *valueIn, ParamValue *valueOut)
+{
+ valueOut->GLuint64PointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLuintConstPointer>(const GLuint *valueIn, ParamValue *valueOut)
+{
+ valueOut->GLuintConstPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLuintPointer>(GLuint *valueIn, ParamValue *valueOut)
+{
+ valueOut->GLuintPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLushort>(GLushort valueIn, ParamValue *valueOut)
+{
+ valueOut->GLushortVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLushortConstPointer>(const GLushort *valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->GLushortConstPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLushortPointer>(GLushort *valueIn, ParamValue *valueOut)
+{
+ valueOut->GLushortPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLvoidConstPointer>(const GLvoid *valueIn, ParamValue *valueOut)
+{
+ valueOut->GLvoidConstPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGLvoidConstPointerPointer>(const GLvoid *const *valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->GLvoidConstPointerPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TGraphicsResetStatus>(gl::GraphicsResetStatus valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->GraphicsResetStatusVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::THandleType>(gl::HandleType valueIn, ParamValue *valueOut)
+{
+ valueOut->HandleTypeVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TLightParameter>(gl::LightParameter valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->LightParameterVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TLogicalOperation>(gl::LogicalOperation valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->LogicalOperationVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TMaterialParameter>(gl::MaterialParameter valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->MaterialParameterVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TMatrixType>(gl::MatrixType valueIn, ParamValue *valueOut)
+{
+ valueOut->MatrixTypeVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TMemoryObjectID>(gl::MemoryObjectID valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->MemoryObjectIDVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TMemoryObjectIDConstPointer>(const gl::MemoryObjectID *valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->MemoryObjectIDConstPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TMemoryObjectIDPointer>(gl::MemoryObjectID *valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->MemoryObjectIDPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TObjectType>(egl::ObjectType valueIn, ParamValue *valueOut)
+{
+ valueOut->ObjectTypeVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TPointParameter>(gl::PointParameter valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->PointParameterVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TPrimitiveMode>(gl::PrimitiveMode valueIn, ParamValue *valueOut)
+{
+ valueOut->PrimitiveModeVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TProgramPipelineID>(gl::ProgramPipelineID valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->ProgramPipelineIDVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TProgramPipelineIDConstPointer>(
+ const gl::ProgramPipelineID *valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->ProgramPipelineIDConstPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TProgramPipelineIDPointer>(gl::ProgramPipelineID *valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->ProgramPipelineIDPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TProvokingVertexConvention>(
+ gl::ProvokingVertexConvention valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->ProvokingVertexConventionVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TQueryID>(gl::QueryID valueIn, ParamValue *valueOut)
+{
+ valueOut->QueryIDVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TQueryIDConstPointer>(const gl::QueryID *valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->QueryIDConstPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TQueryIDPointer>(gl::QueryID *valueIn, ParamValue *valueOut)
+{
+ valueOut->QueryIDPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TQueryType>(gl::QueryType valueIn, ParamValue *valueOut)
+{
+ valueOut->QueryTypeVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TRenderbufferID>(gl::RenderbufferID valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->RenderbufferIDVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TRenderbufferIDConstPointer>(const gl::RenderbufferID *valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->RenderbufferIDConstPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TRenderbufferIDPointer>(gl::RenderbufferID *valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->RenderbufferIDPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TSamplerID>(gl::SamplerID valueIn, ParamValue *valueOut)
+{
+ valueOut->SamplerIDVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TSamplerIDConstPointer>(const gl::SamplerID *valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->SamplerIDConstPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TSamplerIDPointer>(gl::SamplerID *valueIn, ParamValue *valueOut)
+{
+ valueOut->SamplerIDPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TSemaphoreID>(gl::SemaphoreID valueIn, ParamValue *valueOut)
+{
+ valueOut->SemaphoreIDVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TSemaphoreIDConstPointer>(const gl::SemaphoreID *valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->SemaphoreIDConstPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TSemaphoreIDPointer>(gl::SemaphoreID *valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->SemaphoreIDPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TShaderProgramID>(gl::ShaderProgramID valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->ShaderProgramIDVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TShaderProgramIDConstPointer>(const gl::ShaderProgramID *valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->ShaderProgramIDConstPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TShaderProgramIDPointer>(gl::ShaderProgramID *valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->ShaderProgramIDPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TShaderType>(gl::ShaderType valueIn, ParamValue *valueOut)
+{
+ valueOut->ShaderTypeVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TShadingModel>(gl::ShadingModel valueIn, ParamValue *valueOut)
+{
+ valueOut->ShadingModelVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TTextureEnvParameter>(gl::TextureEnvParameter valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->TextureEnvParameterVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TTextureEnvTarget>(gl::TextureEnvTarget valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->TextureEnvTargetVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TTextureID>(gl::TextureID valueIn, ParamValue *valueOut)
+{
+ valueOut->TextureIDVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TTextureIDConstPointer>(const gl::TextureID *valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->TextureIDConstPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TTextureIDPointer>(gl::TextureID *valueIn, ParamValue *valueOut)
+{
+ valueOut->TextureIDPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TTextureTarget>(gl::TextureTarget valueIn, ParamValue *valueOut)
+{
+ valueOut->TextureTargetVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TTextureType>(gl::TextureType valueIn, ParamValue *valueOut)
+{
+ valueOut->TextureTypeVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TTimestamp>(egl::Timestamp valueIn, ParamValue *valueOut)
+{
+ valueOut->TimestampVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TTransformFeedbackID>(gl::TransformFeedbackID valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->TransformFeedbackIDVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TTransformFeedbackIDConstPointer>(
+ const gl::TransformFeedbackID *valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->TransformFeedbackIDConstPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TTransformFeedbackIDPointer>(gl::TransformFeedbackID *valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->TransformFeedbackIDPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TUniformBlockIndex>(gl::UniformBlockIndex valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->UniformBlockIndexVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TUniformLocation>(gl::UniformLocation valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->UniformLocationVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TVertexArrayID>(gl::VertexArrayID valueIn, ParamValue *valueOut)
+{
+ valueOut->VertexArrayIDVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TVertexArrayIDConstPointer>(const gl::VertexArrayID *valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->VertexArrayIDConstPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TVertexArrayIDPointer>(gl::VertexArrayID *valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->VertexArrayIDPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TVertexAttribType>(gl::VertexAttribType valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->VertexAttribTypeVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TcharConstPointer>(const char *valueIn, ParamValue *valueOut)
+{
+ valueOut->charConstPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TvoidConstPointer>(const void *valueIn, ParamValue *valueOut)
+{
+ valueOut->voidConstPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TvoidConstPointerPointer>(const void *const *valueIn,
+ ParamValue *valueOut)
+{
+ valueOut->voidConstPointerPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TvoidPointer>(void *valueIn, ParamValue *valueOut)
+{
+ valueOut->voidPointerVal = valueIn;
+}
+
+template <>
+inline void SetParamVal<ParamType::TvoidPointerPointer>(void **valueIn, ParamValue *valueOut)
+{
+ valueOut->voidPointerPointerVal = valueIn;
+}
+
+template <ParamType PType, typename T>
+void SetParamVal(T valueIn, ParamValue *valueOut)
+{
+ UNREACHABLE();
+}
+
+template <typename T>
+void InitParamValue(ParamType paramType, T valueIn, ParamValue *valueOut)
+{
+ switch (paramType)
+ {
+ case ParamType::TAHardwareBufferConstPointer:
+ SetParamVal<ParamType::TAHardwareBufferConstPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TAlphaTestFunc:
+ SetParamVal<ParamType::TAlphaTestFunc>(valueIn, valueOut);
+ break;
+ case ParamType::TBufferBinding:
+ SetParamVal<ParamType::TBufferBinding>(valueIn, valueOut);
+ break;
+ case ParamType::TBufferID:
+ SetParamVal<ParamType::TBufferID>(valueIn, valueOut);
+ break;
+ case ParamType::TBufferIDConstPointer:
+ SetParamVal<ParamType::TBufferIDConstPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TBufferIDPointer:
+ SetParamVal<ParamType::TBufferIDPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TBufferUsage:
+ SetParamVal<ParamType::TBufferUsage>(valueIn, valueOut);
+ break;
+ case ParamType::TClientVertexArrayType:
+ SetParamVal<ParamType::TClientVertexArrayType>(valueIn, valueOut);
+ break;
+ case ParamType::TCompositorTiming:
+ SetParamVal<ParamType::TCompositorTiming>(valueIn, valueOut);
+ break;
+ case ParamType::TCullFaceMode:
+ SetParamVal<ParamType::TCullFaceMode>(valueIn, valueOut);
+ break;
+ case ParamType::TDrawElementsType:
+ SetParamVal<ParamType::TDrawElementsType>(valueIn, valueOut);
+ break;
+ case ParamType::TEGLAttrib:
+ SetParamVal<ParamType::TEGLAttrib>(valueIn, valueOut);
+ break;
+ case ParamType::TEGLAttribKHR:
+ SetParamVal<ParamType::TEGLAttribKHR>(valueIn, valueOut);
+ break;
+ case ParamType::TEGLBoolean:
+ SetParamVal<ParamType::TEGLBoolean>(valueIn, valueOut);
+ break;
+ case ParamType::TEGLClientBuffer:
+ SetParamVal<ParamType::TEGLClientBuffer>(valueIn, valueOut);
+ break;
+ case ParamType::TEGLConfig:
+ SetParamVal<ParamType::TEGLConfig>(valueIn, valueOut);
+ break;
+ case ParamType::TEGLContext:
+ SetParamVal<ParamType::TEGLContext>(valueIn, valueOut);
+ break;
+ case ParamType::TEGLDEBUGPROCKHR:
+ SetParamVal<ParamType::TEGLDEBUGPROCKHR>(valueIn, valueOut);
+ break;
+ case ParamType::TEGLDeviceEXT:
+ SetParamVal<ParamType::TEGLDeviceEXT>(valueIn, valueOut);
+ break;
+ case ParamType::TEGLDisplay:
+ SetParamVal<ParamType::TEGLDisplay>(valueIn, valueOut);
+ break;
+ case ParamType::TEGLFrameTokenANGLE:
+ SetParamVal<ParamType::TEGLFrameTokenANGLE>(valueIn, valueOut);
+ break;
+ case ParamType::TEGLGetBlobFuncANDROID:
+ SetParamVal<ParamType::TEGLGetBlobFuncANDROID>(valueIn, valueOut);
+ break;
+ case ParamType::TEGLImage:
+ SetParamVal<ParamType::TEGLImage>(valueIn, valueOut);
+ break;
+ case ParamType::TEGLLabelKHR:
+ SetParamVal<ParamType::TEGLLabelKHR>(valueIn, valueOut);
+ break;
+ case ParamType::TEGLNativeDisplayType:
+ SetParamVal<ParamType::TEGLNativeDisplayType>(valueIn, valueOut);
+ break;
+ case ParamType::TEGLNativePixmapType:
+ SetParamVal<ParamType::TEGLNativePixmapType>(valueIn, valueOut);
+ break;
+ case ParamType::TEGLNativeWindowType:
+ SetParamVal<ParamType::TEGLNativeWindowType>(valueIn, valueOut);
+ break;
+ case ParamType::TEGLObjectKHR:
+ SetParamVal<ParamType::TEGLObjectKHR>(valueIn, valueOut);
+ break;
+ case ParamType::TEGLSetBlobFuncANDROID:
+ SetParamVal<ParamType::TEGLSetBlobFuncANDROID>(valueIn, valueOut);
+ break;
+ case ParamType::TEGLStreamKHR:
+ SetParamVal<ParamType::TEGLStreamKHR>(valueIn, valueOut);
+ break;
+ case ParamType::TEGLSurface:
+ SetParamVal<ParamType::TEGLSurface>(valueIn, valueOut);
+ break;
+ case ParamType::TEGLSync:
+ SetParamVal<ParamType::TEGLSync>(valueIn, valueOut);
+ break;
+ case ParamType::TEGLTime:
+ SetParamVal<ParamType::TEGLTime>(valueIn, valueOut);
+ break;
+ case ParamType::TEGLTimeKHR:
+ SetParamVal<ParamType::TEGLTimeKHR>(valueIn, valueOut);
+ break;
+ case ParamType::TEGLenum:
+ SetParamVal<ParamType::TEGLenum>(valueIn, valueOut);
+ break;
+ case ParamType::TEGLint:
+ SetParamVal<ParamType::TEGLint>(valueIn, valueOut);
+ break;
+ case ParamType::TEGLnsecsANDROID:
+ SetParamVal<ParamType::TEGLnsecsANDROID>(valueIn, valueOut);
+ break;
+ case ParamType::TEGLuint64KHR:
+ SetParamVal<ParamType::TEGLuint64KHR>(valueIn, valueOut);
+ break;
+ case ParamType::TFenceNVID:
+ SetParamVal<ParamType::TFenceNVID>(valueIn, valueOut);
+ break;
+ case ParamType::TFenceNVIDConstPointer:
+ SetParamVal<ParamType::TFenceNVIDConstPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TFenceNVIDPointer:
+ SetParamVal<ParamType::TFenceNVIDPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TFramebufferID:
+ SetParamVal<ParamType::TFramebufferID>(valueIn, valueOut);
+ break;
+ case ParamType::TFramebufferIDConstPointer:
+ SetParamVal<ParamType::TFramebufferIDConstPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TFramebufferIDPointer:
+ SetParamVal<ParamType::TFramebufferIDPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TGLDEBUGPROC:
+ SetParamVal<ParamType::TGLDEBUGPROC>(valueIn, valueOut);
+ break;
+ case ParamType::TGLDEBUGPROCKHR:
+ SetParamVal<ParamType::TGLDEBUGPROCKHR>(valueIn, valueOut);
+ break;
+ case ParamType::TGLbitfield:
+ SetParamVal<ParamType::TGLbitfield>(valueIn, valueOut);
+ break;
+ case ParamType::TGLboolean:
+ SetParamVal<ParamType::TGLboolean>(valueIn, valueOut);
+ break;
+ case ParamType::TGLbooleanConstPointer:
+ SetParamVal<ParamType::TGLbooleanConstPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TGLbooleanPointer:
+ SetParamVal<ParamType::TGLbooleanPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TGLbyte:
+ SetParamVal<ParamType::TGLbyte>(valueIn, valueOut);
+ break;
+ case ParamType::TGLbyteConstPointer:
+ SetParamVal<ParamType::TGLbyteConstPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TGLcharConstPointer:
+ SetParamVal<ParamType::TGLcharConstPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TGLcharConstPointerPointer:
+ SetParamVal<ParamType::TGLcharConstPointerPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TGLcharPointer:
+ SetParamVal<ParamType::TGLcharPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TGLclampx:
+ SetParamVal<ParamType::TGLclampx>(valueIn, valueOut);
+ break;
+ case ParamType::TGLdouble:
+ SetParamVal<ParamType::TGLdouble>(valueIn, valueOut);
+ break;
+ case ParamType::TGLdoubleConstPointer:
+ SetParamVal<ParamType::TGLdoubleConstPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TGLdoublePointer:
+ SetParamVal<ParamType::TGLdoublePointer>(valueIn, valueOut);
+ break;
+ case ParamType::TGLeglClientBufferEXT:
+ SetParamVal<ParamType::TGLeglClientBufferEXT>(valueIn, valueOut);
+ break;
+ case ParamType::TGLeglImageOES:
+ SetParamVal<ParamType::TGLeglImageOES>(valueIn, valueOut);
+ break;
+ case ParamType::TGLenum:
+ SetParamVal<ParamType::TGLenum>(valueIn, valueOut);
+ break;
+ case ParamType::TGLenumConstPointer:
+ SetParamVal<ParamType::TGLenumConstPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TGLenumPointer:
+ SetParamVal<ParamType::TGLenumPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TGLfixed:
+ SetParamVal<ParamType::TGLfixed>(valueIn, valueOut);
+ break;
+ case ParamType::TGLfixedConstPointer:
+ SetParamVal<ParamType::TGLfixedConstPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TGLfixedPointer:
+ SetParamVal<ParamType::TGLfixedPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TGLfloat:
+ SetParamVal<ParamType::TGLfloat>(valueIn, valueOut);
+ break;
+ case ParamType::TGLfloatConstPointer:
+ SetParamVal<ParamType::TGLfloatConstPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TGLfloatPointer:
+ SetParamVal<ParamType::TGLfloatPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TGLint:
+ SetParamVal<ParamType::TGLint>(valueIn, valueOut);
+ break;
+ case ParamType::TGLint64Pointer:
+ SetParamVal<ParamType::TGLint64Pointer>(valueIn, valueOut);
+ break;
+ case ParamType::TGLintConstPointer:
+ SetParamVal<ParamType::TGLintConstPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TGLintPointer:
+ SetParamVal<ParamType::TGLintPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TGLintptr:
+ SetParamVal<ParamType::TGLintptr>(valueIn, valueOut);
+ break;
+ case ParamType::TGLintptrConstPointer:
+ SetParamVal<ParamType::TGLintptrConstPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TGLshort:
+ SetParamVal<ParamType::TGLshort>(valueIn, valueOut);
+ break;
+ case ParamType::TGLshortConstPointer:
+ SetParamVal<ParamType::TGLshortConstPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TGLsizei:
+ SetParamVal<ParamType::TGLsizei>(valueIn, valueOut);
+ break;
+ case ParamType::TGLsizeiConstPointer:
+ SetParamVal<ParamType::TGLsizeiConstPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TGLsizeiPointer:
+ SetParamVal<ParamType::TGLsizeiPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TGLsizeiptr:
+ SetParamVal<ParamType::TGLsizeiptr>(valueIn, valueOut);
+ break;
+ case ParamType::TGLsizeiptrConstPointer:
+ SetParamVal<ParamType::TGLsizeiptrConstPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TGLsync:
+ SetParamVal<ParamType::TGLsync>(valueIn, valueOut);
+ break;
+ case ParamType::TGLubyte:
+ SetParamVal<ParamType::TGLubyte>(valueIn, valueOut);
+ break;
+ case ParamType::TGLubyteConstPointer:
+ SetParamVal<ParamType::TGLubyteConstPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TGLubytePointer:
+ SetParamVal<ParamType::TGLubytePointer>(valueIn, valueOut);
+ break;
+ case ParamType::TGLuint:
+ SetParamVal<ParamType::TGLuint>(valueIn, valueOut);
+ break;
+ case ParamType::TGLuint64:
+ SetParamVal<ParamType::TGLuint64>(valueIn, valueOut);
+ break;
+ case ParamType::TGLuint64ConstPointer:
+ SetParamVal<ParamType::TGLuint64ConstPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TGLuint64Pointer:
+ SetParamVal<ParamType::TGLuint64Pointer>(valueIn, valueOut);
+ break;
+ case ParamType::TGLuintConstPointer:
+ SetParamVal<ParamType::TGLuintConstPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TGLuintPointer:
+ SetParamVal<ParamType::TGLuintPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TGLushort:
+ SetParamVal<ParamType::TGLushort>(valueIn, valueOut);
+ break;
+ case ParamType::TGLushortConstPointer:
+ SetParamVal<ParamType::TGLushortConstPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TGLushortPointer:
+ SetParamVal<ParamType::TGLushortPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TGLvoidConstPointer:
+ SetParamVal<ParamType::TGLvoidConstPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TGLvoidConstPointerPointer:
+ SetParamVal<ParamType::TGLvoidConstPointerPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TGraphicsResetStatus:
+ SetParamVal<ParamType::TGraphicsResetStatus>(valueIn, valueOut);
+ break;
+ case ParamType::THandleType:
+ SetParamVal<ParamType::THandleType>(valueIn, valueOut);
+ break;
+ case ParamType::TLightParameter:
+ SetParamVal<ParamType::TLightParameter>(valueIn, valueOut);
+ break;
+ case ParamType::TLogicalOperation:
+ SetParamVal<ParamType::TLogicalOperation>(valueIn, valueOut);
+ break;
+ case ParamType::TMaterialParameter:
+ SetParamVal<ParamType::TMaterialParameter>(valueIn, valueOut);
+ break;
+ case ParamType::TMatrixType:
+ SetParamVal<ParamType::TMatrixType>(valueIn, valueOut);
+ break;
+ case ParamType::TMemoryObjectID:
+ SetParamVal<ParamType::TMemoryObjectID>(valueIn, valueOut);
+ break;
+ case ParamType::TMemoryObjectIDConstPointer:
+ SetParamVal<ParamType::TMemoryObjectIDConstPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TMemoryObjectIDPointer:
+ SetParamVal<ParamType::TMemoryObjectIDPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TObjectType:
+ SetParamVal<ParamType::TObjectType>(valueIn, valueOut);
+ break;
+ case ParamType::TPointParameter:
+ SetParamVal<ParamType::TPointParameter>(valueIn, valueOut);
+ break;
+ case ParamType::TPrimitiveMode:
+ SetParamVal<ParamType::TPrimitiveMode>(valueIn, valueOut);
+ break;
+ case ParamType::TProgramPipelineID:
+ SetParamVal<ParamType::TProgramPipelineID>(valueIn, valueOut);
+ break;
+ case ParamType::TProgramPipelineIDConstPointer:
+ SetParamVal<ParamType::TProgramPipelineIDConstPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TProgramPipelineIDPointer:
+ SetParamVal<ParamType::TProgramPipelineIDPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TProvokingVertexConvention:
+ SetParamVal<ParamType::TProvokingVertexConvention>(valueIn, valueOut);
+ break;
+ case ParamType::TQueryID:
+ SetParamVal<ParamType::TQueryID>(valueIn, valueOut);
+ break;
+ case ParamType::TQueryIDConstPointer:
+ SetParamVal<ParamType::TQueryIDConstPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TQueryIDPointer:
+ SetParamVal<ParamType::TQueryIDPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TQueryType:
+ SetParamVal<ParamType::TQueryType>(valueIn, valueOut);
+ break;
+ case ParamType::TRenderbufferID:
+ SetParamVal<ParamType::TRenderbufferID>(valueIn, valueOut);
+ break;
+ case ParamType::TRenderbufferIDConstPointer:
+ SetParamVal<ParamType::TRenderbufferIDConstPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TRenderbufferIDPointer:
+ SetParamVal<ParamType::TRenderbufferIDPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TSamplerID:
+ SetParamVal<ParamType::TSamplerID>(valueIn, valueOut);
+ break;
+ case ParamType::TSamplerIDConstPointer:
+ SetParamVal<ParamType::TSamplerIDConstPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TSamplerIDPointer:
+ SetParamVal<ParamType::TSamplerIDPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TSemaphoreID:
+ SetParamVal<ParamType::TSemaphoreID>(valueIn, valueOut);
+ break;
+ case ParamType::TSemaphoreIDConstPointer:
+ SetParamVal<ParamType::TSemaphoreIDConstPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TSemaphoreIDPointer:
+ SetParamVal<ParamType::TSemaphoreIDPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TShaderProgramID:
+ SetParamVal<ParamType::TShaderProgramID>(valueIn, valueOut);
+ break;
+ case ParamType::TShaderProgramIDConstPointer:
+ SetParamVal<ParamType::TShaderProgramIDConstPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TShaderProgramIDPointer:
+ SetParamVal<ParamType::TShaderProgramIDPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TShaderType:
+ SetParamVal<ParamType::TShaderType>(valueIn, valueOut);
+ break;
+ case ParamType::TShadingModel:
+ SetParamVal<ParamType::TShadingModel>(valueIn, valueOut);
+ break;
+ case ParamType::TTextureEnvParameter:
+ SetParamVal<ParamType::TTextureEnvParameter>(valueIn, valueOut);
+ break;
+ case ParamType::TTextureEnvTarget:
+ SetParamVal<ParamType::TTextureEnvTarget>(valueIn, valueOut);
+ break;
+ case ParamType::TTextureID:
+ SetParamVal<ParamType::TTextureID>(valueIn, valueOut);
+ break;
+ case ParamType::TTextureIDConstPointer:
+ SetParamVal<ParamType::TTextureIDConstPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TTextureIDPointer:
+ SetParamVal<ParamType::TTextureIDPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TTextureTarget:
+ SetParamVal<ParamType::TTextureTarget>(valueIn, valueOut);
+ break;
+ case ParamType::TTextureType:
+ SetParamVal<ParamType::TTextureType>(valueIn, valueOut);
+ break;
+ case ParamType::TTimestamp:
+ SetParamVal<ParamType::TTimestamp>(valueIn, valueOut);
+ break;
+ case ParamType::TTransformFeedbackID:
+ SetParamVal<ParamType::TTransformFeedbackID>(valueIn, valueOut);
+ break;
+ case ParamType::TTransformFeedbackIDConstPointer:
+ SetParamVal<ParamType::TTransformFeedbackIDConstPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TTransformFeedbackIDPointer:
+ SetParamVal<ParamType::TTransformFeedbackIDPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TUniformBlockIndex:
+ SetParamVal<ParamType::TUniformBlockIndex>(valueIn, valueOut);
+ break;
+ case ParamType::TUniformLocation:
+ SetParamVal<ParamType::TUniformLocation>(valueIn, valueOut);
+ break;
+ case ParamType::TVertexArrayID:
+ SetParamVal<ParamType::TVertexArrayID>(valueIn, valueOut);
+ break;
+ case ParamType::TVertexArrayIDConstPointer:
+ SetParamVal<ParamType::TVertexArrayIDConstPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TVertexArrayIDPointer:
+ SetParamVal<ParamType::TVertexArrayIDPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TVertexAttribType:
+ SetParamVal<ParamType::TVertexAttribType>(valueIn, valueOut);
+ break;
+ case ParamType::TcharConstPointer:
+ SetParamVal<ParamType::TcharConstPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TvoidConstPointer:
+ SetParamVal<ParamType::TvoidConstPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TvoidConstPointerPointer:
+ SetParamVal<ParamType::TvoidConstPointerPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TvoidPointer:
+ SetParamVal<ParamType::TvoidPointer>(valueIn, valueOut);
+ break;
+ case ParamType::TvoidPointerPointer:
+ SetParamVal<ParamType::TvoidPointerPointer>(valueIn, valueOut);
+ break;
+ }
+}
+
+struct CallCapture;
+struct ParamCapture;
+
+void WriteParamCaptureReplay(std::ostream &os, const CallCapture &call, const ParamCapture &param);
+const char *ParamTypeToString(ParamType paramType);
+
+enum class ResourceIDType
+{
+ Buffer,
+ FenceNV,
+ Framebuffer,
+ MemoryObject,
+ ProgramPipeline,
+ Query,
+ Renderbuffer,
+ Sampler,
+ Semaphore,
+ ShaderProgram,
+ Texture,
+ TransformFeedback,
+ VertexArray,
+ EnumCount,
+ InvalidEnum = EnumCount
+};
+
+ResourceIDType GetResourceIDTypeFromParamType(ParamType paramType);
+const char *GetResourceIDTypeName(ResourceIDType resourceIDType);
+
+template <typename ResourceType>
+struct GetResourceIDTypeFromType;
+
+template <>
+struct GetResourceIDTypeFromType<gl::BufferID>
+{
+ static constexpr ResourceIDType IDType = ResourceIDType::Buffer;
+};
+
+template <>
+struct GetResourceIDTypeFromType<gl::FenceNVID>
+{
+ static constexpr ResourceIDType IDType = ResourceIDType::FenceNV;
+};
+
+template <>
+struct GetResourceIDTypeFromType<gl::FramebufferID>
+{
+ static constexpr ResourceIDType IDType = ResourceIDType::Framebuffer;
+};
+
+template <>
+struct GetResourceIDTypeFromType<gl::MemoryObjectID>
+{
+ static constexpr ResourceIDType IDType = ResourceIDType::MemoryObject;
+};
+
+template <>
+struct GetResourceIDTypeFromType<gl::ProgramPipelineID>
+{
+ static constexpr ResourceIDType IDType = ResourceIDType::ProgramPipeline;
+};
+
+template <>
+struct GetResourceIDTypeFromType<gl::QueryID>
+{
+ static constexpr ResourceIDType IDType = ResourceIDType::Query;
+};
+
+template <>
+struct GetResourceIDTypeFromType<gl::RenderbufferID>
+{
+ static constexpr ResourceIDType IDType = ResourceIDType::Renderbuffer;
+};
+
+template <>
+struct GetResourceIDTypeFromType<gl::SamplerID>
+{
+ static constexpr ResourceIDType IDType = ResourceIDType::Sampler;
+};
+
+template <>
+struct GetResourceIDTypeFromType<gl::SemaphoreID>
+{
+ static constexpr ResourceIDType IDType = ResourceIDType::Semaphore;
+};
+
+template <>
+struct GetResourceIDTypeFromType<gl::ShaderProgramID>
+{
+ static constexpr ResourceIDType IDType = ResourceIDType::ShaderProgram;
+};
+
+template <>
+struct GetResourceIDTypeFromType<gl::TextureID>
+{
+ static constexpr ResourceIDType IDType = ResourceIDType::Texture;
+};
+
+template <>
+struct GetResourceIDTypeFromType<gl::TransformFeedbackID>
+{
+ static constexpr ResourceIDType IDType = ResourceIDType::TransformFeedback;
+};
+
+template <>
+struct GetResourceIDTypeFromType<gl::VertexArrayID>
+{
+ static constexpr ResourceIDType IDType = ResourceIDType::VertexArray;
+};
+
+} // namespace angle
+
+#endif // LIBANGLE_FRAME_CAPTURE_UTILS_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libANGLE/capture/frame_capture_utils_mock.cpp b/gfx/angle/checkout/src/libANGLE/capture/frame_capture_utils_mock.cpp
new file mode 100644
index 0000000000..f136a3c17d
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/capture/frame_capture_utils_mock.cpp
@@ -0,0 +1,19 @@
+//
+// Copyright 2021 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.
+//
+// frame_capture_utils_mock.cpp:
+// ANGLE frame capture util stub implementation.
+//
+
+#include "libANGLE/capture/frame_capture_utils.h"
+
+namespace angle
+{
+Result SerializeContextToString(const gl::Context *context, std::string *stringOut)
+{
+ *stringOut = "SerializationNotAvailable";
+ return angle::Result::Continue;
+}
+} // namespace angle
diff --git a/gfx/angle/checkout/src/libANGLE/capture/gl_enum_utils.h b/gfx/angle/checkout/src/libANGLE/capture/gl_enum_utils.h
new file mode 100644
index 0000000000..1fac416138
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/capture/gl_enum_utils.h
@@ -0,0 +1,32 @@
+//
+// Copyright 2019 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_enum_utils.h:
+// Utility functions for converting GLenums to string.
+
+#ifndef LIBANGLE_GL_ENUM_UTILS_H_
+#define LIBANGLE_GL_ENUM_UTILS_H_
+
+#include <ostream>
+#include <string>
+
+#include "libANGLE/capture/gl_enum_utils_autogen.h"
+
+namespace gl
+{
+const char *GLbooleanToString(unsigned int value);
+const char *GLenumToString(GLESEnum enumGroup, unsigned int value);
+const char *GLenumToString(BigGLEnum enumGroup, unsigned int value);
+std::string GLbitfieldToString(GLESEnum enumGroup, unsigned int value);
+std::string GLbitfieldToString(BigGLEnum enumGroup, unsigned int value);
+void OutputGLenumString(std::ostream &out, GLESEnum enumGroup, unsigned int value);
+void OutputGLenumString(std::ostream &out, BigGLEnum enumGroup, unsigned int value);
+void OutputGLbitfieldString(std::ostream &out, GLESEnum enumGroup, unsigned int value);
+const char *GLinternalFormatToString(unsigned int format);
+
+extern const char kUnknownGLenumString[];
+} // namespace gl
+
+#endif // LIBANGLE_GL_ENUM_UTILS_H_
diff --git a/gfx/angle/checkout/src/libANGLE/capture/gl_enum_utils_autogen.h b/gfx/angle/checkout/src/libANGLE/capture/gl_enum_utils_autogen.h
new file mode 100644
index 0000000000..6d0fe3da3e
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/capture/gl_enum_utils_autogen.h
@@ -0,0 +1,419 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_gl_enum_utils.py using data from gl.xml and gl_angle_ext.xml.
+//
+// Copyright 2019 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_enum_utils_autogen.h:
+// mapping of GLenum value to string.
+
+#ifndef LIBANGLE_GL_ENUM_UTILS_AUTOGEN_H_
+#define LIBANGLE_GL_ENUM_UTILS_AUTOGEN_H_
+
+namespace gl
+{
+enum class GLESEnum
+{
+ AccumOp,
+ AllEnums,
+ AlphaFunction,
+ AtomicCounterBufferPName,
+ AttribMask,
+ AttributeType,
+ BindTransformFeedbackTarget,
+ BinormalPointerTypeEXT,
+ BlendEquationModeEXT,
+ BlendingFactor,
+ BlitFramebufferFilter,
+ Boolean,
+ Buffer,
+ BufferAccessARB,
+ BufferPNameARB,
+ BufferPointerNameARB,
+ BufferStorageMask,
+ BufferStorageTarget,
+ BufferTargetARB,
+ BufferUsageARB,
+ ClampColorModeARB,
+ ClearBufferMask,
+ ClipPlaneName,
+ ColorBuffer,
+ ColorMaterialParameter,
+ ColorPointerType,
+ CombinerBiasNV,
+ CombinerComponentUsageNV,
+ CombinerPortionNV,
+ CombinerScaleNV,
+ ContainerType,
+ ContextFlagMask,
+ CopyBufferSubDataTarget,
+ CopyImageSubDataTarget,
+ DebugSeverity,
+ DebugSource,
+ DebugType,
+ DepthFunction,
+ DepthStencilTextureMode,
+ DrawBufferMode,
+ DrawElementsType,
+ ElementPointerTypeATI,
+ EnableCap,
+ ErrorCode,
+ ExternalHandleType,
+ FenceConditionNV,
+ FenceParameterNameNV,
+ FogCoordinatePointerType,
+ FogMode,
+ FogPName,
+ FogParameter,
+ FogPointerTypeEXT,
+ FogPointerTypeIBM,
+ FragmentLightParameterSGIX,
+ FragmentShaderDestMaskATI,
+ FragmentShaderDestModMaskATI,
+ FragmentShaderGenericSourceATI,
+ FragmentShaderTextureSourceATI,
+ FragmentShaderValueRepATI,
+ FramebufferAttachment,
+ FramebufferAttachmentParameterName,
+ FramebufferParameterName,
+ FramebufferStatus,
+ FramebufferTarget,
+ FrontFaceDirection,
+ GetFramebufferParameter,
+ GetMultisamplePNameNV,
+ GetPName,
+ GetPointervPName,
+ GetTextureParameter,
+ GraphicsResetStatus,
+ HintMode,
+ HintTarget,
+ IndexFunctionEXT,
+ IndexPointerType,
+ InternalFormat,
+ InternalFormatPName,
+ InvalidateFramebufferAttachment,
+ LightEnvModeSGIX,
+ LightModelParameter,
+ LightName,
+ LightParameter,
+ ListNameType,
+ LogicOp,
+ MapBufferAccessMask,
+ MapTypeNV,
+ MaterialParameter,
+ MatrixIndexPointerTypeARB,
+ MatrixMode,
+ MemoryBarrierMask,
+ MemoryObjectParameterName,
+ NormalPointerType,
+ ObjectIdentifier,
+ PatchParameterName,
+ PathColor,
+ PathColorFormat,
+ PathFillMode,
+ PathFontStyle,
+ PathGenMode,
+ PathTransformType,
+ PipelineParameterName,
+ PixelCopyType,
+ PixelFormat,
+ PixelStoreParameter,
+ PixelTexGenModeSGIX,
+ PixelTransferParameter,
+ PixelType,
+ PointParameterNameARB,
+ PrecisionType,
+ PrimitiveType,
+ ProgramInterface,
+ ProgramInterfacePName,
+ ProgramParameterPName,
+ ProgramPropertyARB,
+ ProgramResourceProperty,
+ QueryCounterTarget,
+ QueryObjectParameterName,
+ QueryParameterName,
+ QueryTarget,
+ ReadBufferMode,
+ RenderbufferParameterName,
+ RenderbufferTarget,
+ ReplacementCodeTypeSUN,
+ SamplerParameterF,
+ SamplerParameterI,
+ ScalarType,
+ SecondaryColorPointerTypeIBM,
+ SemaphoreParameterName,
+ ShaderBinaryFormat,
+ ShaderParameterName,
+ ShaderType,
+ ShadingModel,
+ ShadingRateQCOM,
+ SizedInternalFormat,
+ StencilFunction,
+ StencilOp,
+ StringName,
+ SubroutineParameterName,
+ SyncBehaviorFlags,
+ SyncCondition,
+ SyncObjectMask,
+ SyncParameterName,
+ SyncStatus,
+ TangentPointerTypeEXT,
+ TexCoordPointerType,
+ TextureCompareMode,
+ TextureCoordName,
+ TextureEnvMode,
+ TextureEnvParameter,
+ TextureEnvTarget,
+ TextureGenParameter,
+ TextureLayout,
+ TextureMagFilter,
+ TextureMinFilter,
+ TextureParameterName,
+ TextureSwizzle,
+ TextureTarget,
+ TextureUnit,
+ TextureWrapMode,
+ TransformFeedbackBufferMode,
+ TransformFeedbackPName,
+ TriangleFace,
+ UniformBlockPName,
+ UniformPName,
+ UniformType,
+ UseProgramStageMask,
+ VertexArrayPName,
+ VertexAttribEnum,
+ VertexAttribIType,
+ VertexAttribPointerPropertyARB,
+ VertexAttribPointerType,
+ VertexAttribPropertyARB,
+ VertexAttribType,
+ VertexBufferObjectUsage,
+ VertexPointerType,
+ VertexProvokingMode,
+ VertexShaderTextureUnitParameter,
+ VertexShaderWriteMaskEXT,
+ VertexWeightPointerTypeEXT,
+ WeightPointerTypeARB
+};
+
+enum class BigGLEnum
+{
+ AccumOp,
+ AllEnums,
+ AlphaFunction,
+ AtomicCounterBufferPName,
+ AttribMask,
+ AttributeType,
+ BindTransformFeedbackTarget,
+ BinormalPointerTypeEXT,
+ BlendEquationModeEXT,
+ BlendingFactor,
+ BlitFramebufferFilter,
+ Boolean,
+ Buffer,
+ BufferAccessARB,
+ BufferPNameARB,
+ BufferPointerNameARB,
+ BufferStorageMask,
+ BufferStorageTarget,
+ BufferTargetARB,
+ BufferUsageARB,
+ ClampColorModeARB,
+ ClampColorTargetARB,
+ ClearBufferMask,
+ ClientAttribMask,
+ ClipControlDepth,
+ ClipControlOrigin,
+ ClipPlaneName,
+ ColorBuffer,
+ ColorMaterialParameter,
+ ColorPointerType,
+ ColorTableTarget,
+ ColorTableTargetSGI,
+ CombinerBiasNV,
+ CombinerComponentUsageNV,
+ CombinerPortionNV,
+ CombinerScaleNV,
+ ConditionalRenderMode,
+ ContainerType,
+ ContextFlagMask,
+ ContextProfileMask,
+ ConvolutionTarget,
+ ConvolutionTargetEXT,
+ CopyBufferSubDataTarget,
+ CopyImageSubDataTarget,
+ DebugSeverity,
+ DebugSource,
+ DebugType,
+ DepthFunction,
+ DepthStencilTextureMode,
+ DrawBufferMode,
+ DrawElementsType,
+ ElementPointerTypeATI,
+ EnableCap,
+ ErrorCode,
+ ExternalHandleType,
+ FeedBackToken,
+ FeedbackType,
+ FenceConditionNV,
+ FenceParameterNameNV,
+ FogCoordSrc,
+ FogCoordinatePointerType,
+ FogMode,
+ FogPName,
+ FogParameter,
+ FogPointerTypeEXT,
+ FogPointerTypeIBM,
+ FragmentLightParameterSGIX,
+ FragmentShaderDestMaskATI,
+ FragmentShaderDestModMaskATI,
+ FragmentShaderGenericSourceATI,
+ FragmentShaderTextureSourceATI,
+ FragmentShaderValueRepATI,
+ FramebufferAttachment,
+ FramebufferAttachmentParameterName,
+ FramebufferParameterName,
+ FramebufferStatus,
+ FramebufferTarget,
+ FrontFaceDirection,
+ GetFramebufferParameter,
+ GetMapQuery,
+ GetMultisamplePNameNV,
+ GetPName,
+ GetPointervPName,
+ GetTextureParameter,
+ GraphicsResetStatus,
+ HintMode,
+ HintTarget,
+ HistogramTarget,
+ HistogramTargetEXT,
+ IndexFunctionEXT,
+ IndexMaterialParameterEXT,
+ IndexPointerType,
+ InterleavedArrayFormat,
+ InternalFormat,
+ InternalFormatPName,
+ InvalidateFramebufferAttachment,
+ LightEnvModeSGIX,
+ LightModelColorControl,
+ LightModelParameter,
+ LightName,
+ LightParameter,
+ LightTextureModeEXT,
+ ListMode,
+ ListNameType,
+ LogicOp,
+ MapBufferAccessMask,
+ MapQuery,
+ MapTarget,
+ MapTypeNV,
+ MaterialParameter,
+ MatrixIndexPointerTypeARB,
+ MatrixMode,
+ MemoryBarrierMask,
+ MemoryObjectParameterName,
+ MeshMode1,
+ MeshMode2,
+ MinmaxTarget,
+ MinmaxTargetEXT,
+ NormalPointerType,
+ ObjectIdentifier,
+ PatchParameterName,
+ PathColor,
+ PathColorFormat,
+ PathFillMode,
+ PathFontStyle,
+ PathGenMode,
+ PathTransformType,
+ PipelineParameterName,
+ PixelCopyType,
+ PixelFormat,
+ PixelMap,
+ PixelStoreParameter,
+ PixelTexGenModeSGIX,
+ PixelTransferParameter,
+ PixelType,
+ PointParameterNameARB,
+ PolygonMode,
+ PrecisionType,
+ PrimitiveType,
+ ProgramInterface,
+ ProgramInterfacePName,
+ ProgramParameterPName,
+ ProgramPropertyARB,
+ ProgramResourceProperty,
+ ProgramStagePName,
+ QueryCounterTarget,
+ QueryObjectParameterName,
+ QueryParameterName,
+ QueryTarget,
+ ReadBufferMode,
+ RenderbufferParameterName,
+ RenderbufferTarget,
+ RenderingMode,
+ ReplacementCodeTypeSUN,
+ SamplerParameterF,
+ SamplerParameterI,
+ ScalarType,
+ SecondaryColorPointerTypeIBM,
+ SemaphoreParameterName,
+ SeparableTarget,
+ SeparableTargetEXT,
+ ShaderBinaryFormat,
+ ShaderParameterName,
+ ShaderType,
+ ShadingModel,
+ SizedInternalFormat,
+ StencilFunction,
+ StencilOp,
+ StringName,
+ SubroutineParameterName,
+ SyncBehaviorFlags,
+ SyncCondition,
+ SyncObjectMask,
+ SyncParameterName,
+ SyncStatus,
+ TangentPointerTypeEXT,
+ TexCoordPointerType,
+ TextureCompareMode,
+ TextureCoordName,
+ TextureEnvMode,
+ TextureEnvParameter,
+ TextureEnvTarget,
+ TextureGenMode,
+ TextureGenParameter,
+ TextureLayout,
+ TextureMagFilter,
+ TextureMinFilter,
+ TextureParameterName,
+ TextureSwizzle,
+ TextureTarget,
+ TextureUnit,
+ TextureWrapMode,
+ TransformFeedbackBufferMode,
+ TransformFeedbackPName,
+ TriangleFace,
+ UniformBlockPName,
+ UniformPName,
+ UniformType,
+ UseProgramStageMask,
+ VertexArrayPName,
+ VertexAttribEnum,
+ VertexAttribIType,
+ VertexAttribLType,
+ VertexAttribPointerPropertyARB,
+ VertexAttribPointerType,
+ VertexAttribPropertyARB,
+ VertexAttribType,
+ VertexBufferObjectUsage,
+ VertexPointerType,
+ VertexProvokingMode,
+ VertexShaderTextureUnitParameter,
+ VertexShaderWriteMaskEXT,
+ VertexWeightPointerTypeEXT,
+ WeightPointerTypeARB
+};
+} // namespace gl
+
+#endif // LIBANGLE_GL_ENUM_UTILS_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libANGLE/entry_points_utils.h b/gfx/angle/checkout/src/libANGLE/entry_points_utils.h
new file mode 100644
index 0000000000..c5a3178308
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/entry_points_utils.h
@@ -0,0 +1,127 @@
+//
+// Copyright 2018 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_point_utils:
+// These helpers are used in GL/GLES entry point routines.
+
+#ifndef LIBANGLE_ENTRY_POINT_UTILS_H_
+#define LIBANGLE_ENTRY_POINT_UTILS_H_
+
+#include "angle_gl.h"
+#include "common/Optional.h"
+#include "common/PackedEnums.h"
+#include "common/angleutils.h"
+#include "common/entry_points_enum_autogen.h"
+#include "common/mathutil.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Display.h"
+
+namespace gl
+{
+// A template struct for determining the default value to return for each entry point.
+template <angle::EntryPoint EP, typename ReturnType>
+struct DefaultReturnValue;
+
+// Default return values for each basic return type.
+template <angle::EntryPoint EP>
+struct DefaultReturnValue<EP, GLint>
+{
+ static constexpr GLint kValue = -1;
+};
+
+// This doubles as the GLenum return value.
+template <angle::EntryPoint EP>
+struct DefaultReturnValue<EP, GLuint>
+{
+ static constexpr GLuint kValue = 0;
+};
+
+template <angle::EntryPoint EP>
+struct DefaultReturnValue<EP, GLboolean>
+{
+ static constexpr GLboolean kValue = GL_FALSE;
+};
+
+template <angle::EntryPoint EP>
+struct DefaultReturnValue<EP, ShaderProgramID>
+{
+ static constexpr ShaderProgramID kValue = {0};
+};
+
+// Catch-all rules for pointer types.
+template <angle::EntryPoint EP, typename PointerType>
+struct DefaultReturnValue<EP, const PointerType *>
+{
+ static constexpr const PointerType *kValue = nullptr;
+};
+
+template <angle::EntryPoint EP, typename PointerType>
+struct DefaultReturnValue<EP, PointerType *>
+{
+ static constexpr PointerType *kValue = nullptr;
+};
+
+// Overloaded to return invalid index
+template <>
+struct DefaultReturnValue<angle::EntryPoint::GLGetUniformBlockIndex, GLuint>
+{
+ static constexpr GLuint kValue = GL_INVALID_INDEX;
+};
+
+// Specialized enum error value.
+template <>
+struct DefaultReturnValue<angle::EntryPoint::GLClientWaitSync, GLenum>
+{
+ static constexpr GLenum kValue = GL_WAIT_FAILED;
+};
+
+// glTestFenceNV should still return TRUE for an invalid fence.
+template <>
+struct DefaultReturnValue<angle::EntryPoint::GLTestFenceNV, GLboolean>
+{
+ static constexpr GLboolean kValue = GL_TRUE;
+};
+
+template <angle::EntryPoint EP, typename ReturnType>
+constexpr ANGLE_INLINE ReturnType GetDefaultReturnValue()
+{
+ return DefaultReturnValue<EP, ReturnType>::kValue;
+}
+
+#if ANGLE_CAPTURE_ENABLED
+# define ANGLE_CAPTURE_GL(Func, ...) CaptureCallToFrameCapture(Capture##Func, __VA_ARGS__)
+# define ANGLE_CAPTURE_EGL(Func, ...) CaptureCallToCaptureEGL(Capture##Func, __VA_ARGS__)
+#else
+# define ANGLE_CAPTURE_GL(...)
+# define ANGLE_CAPTURE_EGL(...)
+#endif // ANGLE_CAPTURE_ENABLED
+
+#define EGL_EVENT(EP, FMT, ...) EVENT(nullptr, EGL##EP, FMT, ##__VA_ARGS__)
+
+inline int CID(const Context *context)
+{
+ return context == nullptr ? 0 : static_cast<int>(context->id().value);
+}
+} // namespace gl
+
+namespace egl
+{
+inline int CID(EGLDisplay display, EGLContext context)
+{
+ auto *displayPtr = reinterpret_cast<const egl::Display *>(display);
+ if (!Display::isValidDisplay(displayPtr))
+ {
+ return -1;
+ }
+ auto *contextPtr = reinterpret_cast<const gl::Context *>(context);
+ if (!displayPtr->isValidContext(contextPtr))
+ {
+ return -1;
+ }
+ return gl::CID(contextPtr);
+}
+} // namespace egl
+
+#endif // LIBANGLE_ENTRY_POINT_UTILS_H_
diff --git a/gfx/angle/checkout/src/libANGLE/es3_copy_conversion_table_autogen.cpp b/gfx/angle/checkout/src/libANGLE/es3_copy_conversion_table_autogen.cpp
new file mode 100644
index 0000000000..3647445c50
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/es3_copy_conversion_table_autogen.cpp
@@ -0,0 +1,171 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_copy_conversion_table.py using data from es3_copy_conversion_formats.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.
+// Also check es3 format combinations for validity.
+
+#include "angle_gl.h"
+#include "common/debug.h"
+
+namespace gl
+{
+
+bool ValidES3CopyConversion(GLenum textureFormat, GLenum framebufferFormat)
+{
+ switch (textureFormat)
+ {
+ case GL_ALPHA:
+ switch (framebufferFormat)
+ {
+ case GL_BGRA_EXT:
+ case GL_RGBA:
+ return true;
+ default:
+ break;
+ }
+ break;
+
+ case GL_BGRA_EXT:
+ switch (framebufferFormat)
+ {
+ case GL_BGRA_EXT:
+ return true;
+ default:
+ break;
+ }
+ break;
+
+ case GL_LUMINANCE:
+ switch (framebufferFormat)
+ {
+ case GL_BGRA_EXT:
+ case GL_RED:
+ case GL_RG:
+ case GL_RGB:
+ case GL_RGBA:
+ return true;
+ default:
+ break;
+ }
+ break;
+
+ case GL_LUMINANCE_ALPHA:
+ switch (framebufferFormat)
+ {
+ case GL_BGRA_EXT:
+ case GL_RGBA:
+ return true;
+ default:
+ break;
+ }
+ break;
+
+ case GL_RED:
+ switch (framebufferFormat)
+ {
+ case GL_BGRA_EXT:
+ case GL_RED:
+ case GL_RG:
+ case GL_RGB:
+ case GL_RGBA:
+ return true;
+ default:
+ break;
+ }
+ break;
+
+ case GL_RED_INTEGER:
+ switch (framebufferFormat)
+ {
+ case GL_RED_INTEGER:
+ case GL_RGBA_INTEGER:
+ case GL_RGB_INTEGER:
+ case GL_RG_INTEGER:
+ return true;
+ default:
+ break;
+ }
+ break;
+
+ case GL_RG:
+ switch (framebufferFormat)
+ {
+ case GL_BGRA_EXT:
+ case GL_RG:
+ case GL_RGB:
+ case GL_RGBA:
+ return true;
+ default:
+ break;
+ }
+ break;
+
+ case GL_RGB:
+ switch (framebufferFormat)
+ {
+ case GL_BGRA_EXT:
+ case GL_RGB:
+ case GL_RGBA:
+ return true;
+ default:
+ break;
+ }
+ break;
+
+ case GL_RGBA:
+ switch (framebufferFormat)
+ {
+ case GL_BGRA_EXT:
+ case GL_RGBA:
+ return true;
+ default:
+ break;
+ }
+ break;
+
+ case GL_RGBA_INTEGER:
+ switch (framebufferFormat)
+ {
+ case GL_RGBA_INTEGER:
+ return true;
+ default:
+ break;
+ }
+ break;
+
+ case GL_RGB_INTEGER:
+ switch (framebufferFormat)
+ {
+ case GL_RGBA_INTEGER:
+ case GL_RGB_INTEGER:
+ return true;
+ default:
+ break;
+ }
+ break;
+
+ case GL_RG_INTEGER:
+ switch (framebufferFormat)
+ {
+ case GL_RGBA_INTEGER:
+ case GL_RGB_INTEGER:
+ case GL_RG_INTEGER:
+ return true;
+ default:
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return false;
+}
+
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/features.h b/gfx/angle/checkout/src/libANGLE/features.h
new file mode 100644
index 0000000000..0a8891e822
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/features.h
@@ -0,0 +1,56 @@
+//
+// 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.
+//
+
+#ifndef LIBANGLE_FEATURES_H_
+#define LIBANGLE_FEATURES_H_
+
+#include "common/platform.h"
+
+#define ANGLE_DISABLED 0
+#define ANGLE_ENABLED 1
+
+// Feature defaults
+
+// Direct3D9EX
+// The "Debug This Pixel..." feature in PIX often fails when using the
+// D3D9Ex interfaces. In order to get debug pixel to work on a Vista/Win 7
+// machine, define "ANGLE_D3D9EX=0" in your project file.
+#if !defined(ANGLE_D3D9EX)
+# define ANGLE_D3D9EX ANGLE_ENABLED
+#endif
+
+// Vsync
+// ENABLED allows Vsync to be configured at runtime
+// DISABLED disallows Vsync
+#if !defined(ANGLE_VSYNC)
+# define ANGLE_VSYNC ANGLE_ENABLED
+#endif
+
+// Append HLSL assembly to shader debug info. Defaults to enabled in Debug and off in Release.
+#if !defined(ANGLE_APPEND_ASSEMBLY_TO_SHADER_DEBUG_INFO)
+# if !defined(NDEBUG)
+# define ANGLE_APPEND_ASSEMBLY_TO_SHADER_DEBUG_INFO ANGLE_ENABLED
+# else
+# define ANGLE_APPEND_ASSEMBLY_TO_SHADER_DEBUG_INFO ANGLE_DISABLED
+# endif // !defined(NDEBUG)
+#endif // !defined(ANGLE_APPEND_ASSEMBLY_TO_SHADER_DEBUG_INFO)
+
+// Program link validation of precisions for uniforms. This feature was
+// requested by developers to allow non-conformant shaders to be used which
+// contain mismatched precisions.
+// ENABLED validate that precision for uniforms match between vertex and fragment shaders
+// DISABLED allow precision for uniforms to differ between vertex and fragment shaders
+#if !defined(ANGLE_PROGRAM_LINK_VALIDATE_UNIFORM_PRECISION)
+# define ANGLE_PROGRAM_LINK_VALIDATE_UNIFORM_PRECISION ANGLE_ENABLED
+#endif
+
+// Controls if our threading code uses std::async or falls back to single-threaded operations.
+// Note that we can't easily use std::async in UWPs due to UWP threading restrictions.
+#if !defined(ANGLE_STD_ASYNC_WORKERS) && !defined(ANGLE_ENABLE_WINDOWS_UWP)
+# define ANGLE_STD_ASYNC_WORKERS ANGLE_ENABLED
+#endif // !defined(ANGLE_STD_ASYNC_WORKERS) && & !defined(ANGLE_ENABLE_WINDOWS_UWP)
+
+#endif // LIBANGLE_FEATURES_H_
diff --git a/gfx/angle/checkout/src/libANGLE/format_map_autogen.cpp b/gfx/angle/checkout/src/libANGLE/format_map_autogen.cpp
new file mode 100644
index 0000000000..4685bb8931
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/format_map_autogen.cpp
@@ -0,0 +1,1781 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_format_map.py using data from format_map_data.json.
+// ES3 format info from es3_format_type_combinations.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.
+// Also check es3 format combinations for validity.
+
+#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_INT_2_10_10_10_REV:
+ return GL_BGR10_A2_ANGLEX;
+ 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_RED_GREEN_RGTC2_EXT:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return GL_COMPRESSED_RED_GREEN_RGTC2_EXT;
+ default:
+ break;
+ }
+ break;
+
+ case GL_COMPRESSED_RED_RGTC1_EXT:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return GL_COMPRESSED_RED_RGTC1_EXT;
+ default:
+ break;
+ }
+ break;
+
+ case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return GL_COMPRESSED_RGBA_BPTC_UNORM_EXT;
+ default:
+ break;
+ }
+ break;
+
+ case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
+ default:
+ break;
+ }
+ break;
+
+ case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
+ 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_BPTC_SIGNED_FLOAT_EXT:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT;
+ default:
+ break;
+ }
+ break;
+
+ case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT;
+ default:
+ break;
+ }
+ break;
+
+ case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
+ default:
+ break;
+ }
+ break;
+
+ case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
+ 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_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT;
+ default:
+ break;
+ }
+ break;
+
+ case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return GL_COMPRESSED_SIGNED_RED_RGTC1_EXT;
+ default:
+ break;
+ }
+ break;
+
+ case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT;
+ default:
+ break;
+ }
+ break;
+
+ case GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT;
+ default:
+ break;
+ }
+ break;
+
+ case GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT;
+ default:
+ break;
+ }
+ break;
+
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;
+ default:
+ break;
+ }
+ break;
+
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT;
+ default:
+ break;
+ }
+ break;
+
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;
+ default:
+ break;
+ }
+ break;
+
+ case GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT;
+ default:
+ break;
+ }
+ break;
+
+ case GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT;
+ default:
+ break;
+ }
+ break;
+
+ case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return GL_COMPRESSED_SRGB_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_INT_24_8:
+ return GL_DEPTH24_STENCIL8;
+ 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_2_10_10_10_REV:
+ return GL_RGB10_UNORM_ANGLEX;
+ 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_STENCIL_INDEX_OES:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return GL_STENCIL_INDEX8;
+ default:
+ break;
+ }
+ break;
+
+ case GL_NONE:
+ return GL_NONE;
+
+ default:
+ break;
+ }
+
+ return GL_NONE;
+}
+
+bool ValidES3Format(GLenum format)
+{
+ switch (format)
+ {
+ case GL_ALPHA:
+ case GL_BGRA_EXT:
+ case GL_DEPTH_COMPONENT:
+ case GL_DEPTH_STENCIL:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ case GL_RED:
+ case GL_RED_INTEGER:
+ case GL_RG:
+ case GL_RGB:
+ case GL_RGBA:
+ case GL_RGBA_INTEGER:
+ case GL_RGB_INTEGER:
+ case GL_RG_INTEGER:
+ case GL_SRGB_ALPHA_EXT:
+ case GL_SRGB_EXT:
+ case GL_STENCIL_INDEX:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+bool ValidES3Type(GLenum type)
+{
+ switch (type)
+ {
+ case GL_BYTE:
+ case GL_FLOAT:
+ case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
+ case GL_HALF_FLOAT:
+ case GL_HALF_FLOAT_OES:
+ case GL_INT:
+ case GL_SHORT:
+ case GL_UNSIGNED_BYTE:
+ case GL_UNSIGNED_INT:
+ case GL_UNSIGNED_INT_10F_11F_11F_REV:
+ case GL_UNSIGNED_INT_24_8:
+ case GL_UNSIGNED_INT_2_10_10_10_REV:
+ case GL_UNSIGNED_INT_5_9_9_9_REV:
+ case GL_UNSIGNED_SHORT:
+ case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ case GL_UNSIGNED_SHORT_5_6_5:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+bool ValidES3FormatCombination(GLenum format, GLenum type, GLenum internalFormat)
+{
+ ASSERT(ValidES3Format(format) && ValidES3Type(type));
+
+ switch (format)
+ {
+ case GL_ALPHA:
+ switch (type)
+ {
+ case GL_FLOAT:
+ {
+ switch (internalFormat)
+ {
+ case GL_ALPHA:
+ case GL_ALPHA32F_EXT:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_HALF_FLOAT:
+ {
+ switch (internalFormat)
+ {
+ case GL_ALPHA:
+ case GL_ALPHA16F_EXT:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_HALF_FLOAT_OES:
+ {
+ switch (internalFormat)
+ {
+ case GL_ALPHA:
+ case GL_ALPHA16F_EXT:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_UNSIGNED_BYTE:
+ {
+ switch (internalFormat)
+ {
+ case GL_ALPHA:
+ case GL_ALPHA8_EXT:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ break;
+
+ case GL_BGRA_EXT:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ {
+ switch (internalFormat)
+ {
+ case GL_BGRA_EXT:
+ case GL_BGRA8_EXT:
+ case GL_BGRA4_ANGLEX:
+ case GL_BGR5_A1_ANGLEX:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
+ {
+ switch (internalFormat)
+ {
+ case GL_BGR5_A1_ANGLEX:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
+ {
+ switch (internalFormat)
+ {
+ case GL_BGRA4_ANGLEX:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ break;
+
+ case GL_DEPTH_COMPONENT:
+ switch (type)
+ {
+ case GL_FLOAT:
+ {
+ switch (internalFormat)
+ {
+ case GL_DEPTH_COMPONENT32F:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_UNSIGNED_INT:
+ {
+ switch (internalFormat)
+ {
+ case GL_DEPTH_COMPONENT24:
+ case GL_DEPTH_COMPONENT16:
+ case GL_DEPTH_COMPONENT:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_UNSIGNED_INT_24_8:
+ {
+ switch (internalFormat)
+ {
+ case GL_DEPTH_COMPONENT32_OES:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_UNSIGNED_SHORT:
+ {
+ switch (internalFormat)
+ {
+ case GL_DEPTH_COMPONENT16:
+ case GL_DEPTH_COMPONENT:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ break;
+
+ case GL_DEPTH_STENCIL:
+ switch (type)
+ {
+ case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
+ {
+ switch (internalFormat)
+ {
+ case GL_DEPTH32F_STENCIL8:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_UNSIGNED_INT_24_8:
+ {
+ switch (internalFormat)
+ {
+ case GL_DEPTH_STENCIL:
+ case GL_DEPTH24_STENCIL8:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ break;
+
+ case GL_LUMINANCE:
+ switch (type)
+ {
+ case GL_FLOAT:
+ {
+ switch (internalFormat)
+ {
+ case GL_LUMINANCE:
+ case GL_LUMINANCE32F_EXT:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_HALF_FLOAT:
+ {
+ switch (internalFormat)
+ {
+ case GL_LUMINANCE:
+ case GL_LUMINANCE16F_EXT:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_HALF_FLOAT_OES:
+ {
+ switch (internalFormat)
+ {
+ case GL_LUMINANCE:
+ case GL_LUMINANCE16F_EXT:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_UNSIGNED_BYTE:
+ {
+ switch (internalFormat)
+ {
+ case GL_LUMINANCE:
+ case GL_LUMINANCE8_EXT:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ break;
+
+ case GL_LUMINANCE_ALPHA:
+ switch (type)
+ {
+ case GL_FLOAT:
+ {
+ switch (internalFormat)
+ {
+ case GL_LUMINANCE_ALPHA:
+ case GL_LUMINANCE_ALPHA32F_EXT:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_HALF_FLOAT:
+ {
+ switch (internalFormat)
+ {
+ case GL_LUMINANCE_ALPHA:
+ case GL_LUMINANCE_ALPHA16F_EXT:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_HALF_FLOAT_OES:
+ {
+ switch (internalFormat)
+ {
+ case GL_LUMINANCE_ALPHA:
+ case GL_LUMINANCE_ALPHA16F_EXT:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_UNSIGNED_BYTE:
+ {
+ switch (internalFormat)
+ {
+ case GL_LUMINANCE_ALPHA:
+ case GL_LUMINANCE8_ALPHA8_EXT:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ break;
+
+ case GL_RED:
+ switch (type)
+ {
+ case GL_BYTE:
+ {
+ switch (internalFormat)
+ {
+ case GL_R8_SNORM:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_FLOAT:
+ {
+ switch (internalFormat)
+ {
+ case GL_R32F:
+ case GL_R16F:
+ case GL_RED:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_HALF_FLOAT:
+ {
+ switch (internalFormat)
+ {
+ case GL_R16F:
+ case GL_RED:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_HALF_FLOAT_OES:
+ {
+ switch (internalFormat)
+ {
+ case GL_R16F:
+ case GL_RED:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_SHORT:
+ {
+ switch (internalFormat)
+ {
+ case GL_R16_SNORM_EXT:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_UNSIGNED_BYTE:
+ {
+ switch (internalFormat)
+ {
+ case GL_R8:
+ case GL_RED:
+ case GL_SR8_EXT:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_UNSIGNED_SHORT:
+ {
+ switch (internalFormat)
+ {
+ case GL_R16_EXT:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ break;
+
+ case GL_RED_INTEGER:
+ switch (type)
+ {
+ case GL_BYTE:
+ {
+ switch (internalFormat)
+ {
+ case GL_R8I:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_INT:
+ {
+ switch (internalFormat)
+ {
+ case GL_R32I:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_SHORT:
+ {
+ switch (internalFormat)
+ {
+ case GL_R16I:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_UNSIGNED_BYTE:
+ {
+ switch (internalFormat)
+ {
+ case GL_R8UI:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_UNSIGNED_INT:
+ {
+ switch (internalFormat)
+ {
+ case GL_R32UI:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_UNSIGNED_SHORT:
+ {
+ switch (internalFormat)
+ {
+ case GL_R16UI:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ break;
+
+ case GL_RG:
+ switch (type)
+ {
+ case GL_BYTE:
+ {
+ switch (internalFormat)
+ {
+ case GL_RG8_SNORM:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_FLOAT:
+ {
+ switch (internalFormat)
+ {
+ case GL_RG32F:
+ case GL_RG16F:
+ case GL_RG:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_HALF_FLOAT:
+ {
+ switch (internalFormat)
+ {
+ case GL_RG16F:
+ case GL_RG:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_HALF_FLOAT_OES:
+ {
+ switch (internalFormat)
+ {
+ case GL_RG16F:
+ case GL_RG:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_SHORT:
+ {
+ switch (internalFormat)
+ {
+ case GL_RG16_SNORM_EXT:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_UNSIGNED_BYTE:
+ {
+ switch (internalFormat)
+ {
+ case GL_RG8:
+ case GL_RG:
+ case GL_SRG8_EXT:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_UNSIGNED_SHORT:
+ {
+ switch (internalFormat)
+ {
+ case GL_RG16_EXT:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ break;
+
+ case GL_RGB:
+ switch (type)
+ {
+ case GL_BYTE:
+ {
+ switch (internalFormat)
+ {
+ case GL_RGB8_SNORM:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_FLOAT:
+ {
+ switch (internalFormat)
+ {
+ case GL_RGB32F:
+ case GL_RGB16F:
+ case GL_R11F_G11F_B10F:
+ case GL_RGB9_E5:
+ case GL_RGB:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_HALF_FLOAT:
+ {
+ switch (internalFormat)
+ {
+ case GL_RGB16F:
+ case GL_R11F_G11F_B10F:
+ case GL_RGB9_E5:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_HALF_FLOAT_OES:
+ {
+ switch (internalFormat)
+ {
+ case GL_RGB16F:
+ case GL_R11F_G11F_B10F:
+ case GL_RGB9_E5:
+ case GL_RGB:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_SHORT:
+ {
+ switch (internalFormat)
+ {
+ case GL_RGB16_SNORM_EXT:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_UNSIGNED_BYTE:
+ {
+ switch (internalFormat)
+ {
+ case GL_RGB8:
+ case GL_RGB565:
+ case GL_SRGB8:
+ case GL_RGB:
+ case GL_RGBX8_ANGLE:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_UNSIGNED_INT_10F_11F_11F_REV:
+ {
+ switch (internalFormat)
+ {
+ case GL_R11F_G11F_B10F:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_UNSIGNED_INT_2_10_10_10_REV:
+ {
+ switch (internalFormat)
+ {
+ case GL_RGB:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_UNSIGNED_INT_5_9_9_9_REV:
+ {
+ switch (internalFormat)
+ {
+ case GL_RGB9_E5:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_UNSIGNED_SHORT:
+ {
+ switch (internalFormat)
+ {
+ case GL_RGB16_EXT:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_UNSIGNED_SHORT_5_6_5:
+ {
+ switch (internalFormat)
+ {
+ case GL_RGB565:
+ case GL_RGB:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ break;
+
+ case GL_RGBA:
+ switch (type)
+ {
+ case GL_BYTE:
+ {
+ switch (internalFormat)
+ {
+ case GL_RGBA8_SNORM:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_FLOAT:
+ {
+ switch (internalFormat)
+ {
+ case GL_RGBA32F:
+ case GL_RGBA16F:
+ case GL_RGBA:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_HALF_FLOAT:
+ {
+ switch (internalFormat)
+ {
+ case GL_RGBA16F:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_HALF_FLOAT_OES:
+ {
+ switch (internalFormat)
+ {
+ case GL_RGBA16F:
+ case GL_RGBA:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_SHORT:
+ {
+ switch (internalFormat)
+ {
+ case GL_RGBA16_SNORM_EXT:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_UNSIGNED_BYTE:
+ {
+ switch (internalFormat)
+ {
+ case GL_RGBA8:
+ case GL_RGB5_A1:
+ case GL_RGBA4:
+ case GL_SRGB8_ALPHA8:
+ case GL_RGBA:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_UNSIGNED_INT_2_10_10_10_REV:
+ {
+ switch (internalFormat)
+ {
+ case GL_RGB10_A2:
+ case GL_RGB5_A1:
+ case GL_RGBA:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_UNSIGNED_SHORT:
+ {
+ switch (internalFormat)
+ {
+ case GL_RGBA16_EXT:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ {
+ switch (internalFormat)
+ {
+ case GL_RGBA4:
+ case GL_RGBA:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ {
+ switch (internalFormat)
+ {
+ case GL_RGB5_A1:
+ case GL_RGBA:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ break;
+
+ case GL_RGBA_INTEGER:
+ switch (type)
+ {
+ case GL_BYTE:
+ {
+ switch (internalFormat)
+ {
+ case GL_RGBA8I:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_INT:
+ {
+ switch (internalFormat)
+ {
+ case GL_RGBA32I:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_SHORT:
+ {
+ switch (internalFormat)
+ {
+ case GL_RGBA16I:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_UNSIGNED_BYTE:
+ {
+ switch (internalFormat)
+ {
+ case GL_RGBA8UI:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_UNSIGNED_INT:
+ {
+ switch (internalFormat)
+ {
+ case GL_RGBA32UI:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_UNSIGNED_INT_2_10_10_10_REV:
+ {
+ switch (internalFormat)
+ {
+ case GL_RGB10_A2UI:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_UNSIGNED_SHORT:
+ {
+ switch (internalFormat)
+ {
+ case GL_RGBA16UI:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ break;
+
+ case GL_RGB_INTEGER:
+ switch (type)
+ {
+ case GL_BYTE:
+ {
+ switch (internalFormat)
+ {
+ case GL_RGB8I:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_INT:
+ {
+ switch (internalFormat)
+ {
+ case GL_RGB32I:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_SHORT:
+ {
+ switch (internalFormat)
+ {
+ case GL_RGB16I:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_UNSIGNED_BYTE:
+ {
+ switch (internalFormat)
+ {
+ case GL_RGB8UI:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_UNSIGNED_INT:
+ {
+ switch (internalFormat)
+ {
+ case GL_RGB32UI:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_UNSIGNED_SHORT:
+ {
+ switch (internalFormat)
+ {
+ case GL_RGB16UI:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ break;
+
+ case GL_RG_INTEGER:
+ switch (type)
+ {
+ case GL_BYTE:
+ {
+ switch (internalFormat)
+ {
+ case GL_RG8I:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_INT:
+ {
+ switch (internalFormat)
+ {
+ case GL_RG32I:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_SHORT:
+ {
+ switch (internalFormat)
+ {
+ case GL_RG16I:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_UNSIGNED_BYTE:
+ {
+ switch (internalFormat)
+ {
+ case GL_RG8UI:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_UNSIGNED_INT:
+ {
+ switch (internalFormat)
+ {
+ case GL_RG32UI:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_UNSIGNED_SHORT:
+ {
+ switch (internalFormat)
+ {
+ case GL_RG16UI:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ break;
+
+ case GL_SRGB_ALPHA_EXT:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ {
+ switch (internalFormat)
+ {
+ case GL_SRGB_ALPHA_EXT:
+ case GL_SRGB8_ALPHA8_EXT:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ break;
+
+ case GL_SRGB_EXT:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ {
+ switch (internalFormat)
+ {
+ case GL_SRGB_EXT:
+ case GL_SRGB8:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ break;
+
+ case GL_STENCIL_INDEX:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ {
+ switch (internalFormat)
+ {
+ case GL_STENCIL_INDEX8:
+ return true;
+ default:
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ break;
+
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ return false;
+}
+
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/format_map_desktop.cpp b/gfx/angle/checkout/src/libANGLE/format_map_desktop.cpp
new file mode 100644
index 0000000000..17122af6a7
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/format_map_desktop.cpp
@@ -0,0 +1,128 @@
+// Copyright 2019 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_desktop:
+// Determining the sized internal format from a (format,type) pair.
+// Also check DesktopGL format combinations for validity.
+
+#include "angle_gl.h"
+#include "common/debug.h"
+#include "formatutils.h"
+#include "renderer/gl/functionsgl_enums.h"
+
+// TODO(http://anglebug.com/3730): switch ANGLE to generate its own GL enum types from gl.xml
+
+namespace gl
+{
+
+bool ValidDesktopFormat(GLenum format)
+{
+ switch (format)
+ {
+ case GL_STENCIL_INDEX:
+ case GL_DEPTH_COMPONENT:
+ case GL_DEPTH_STENCIL:
+ case GL_RED:
+ case GL_GREEN:
+ case GL_BLUE:
+ case GL_RG:
+ case GL_RGB:
+ case GL_RGBA:
+ case GL_BGR:
+ case GL_BGRA:
+ case GL_RED_INTEGER:
+ case GL_GREEN_INTEGER:
+ case GL_BLUE_INTEGER:
+ case GL_RG_INTEGER:
+ case GL_RGB_INTEGER:
+ case GL_RGBA_INTEGER:
+ case GL_BGR_INTEGER:
+ case GL_BGRA_INTEGER:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+bool ValidDesktopType(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ case GL_BYTE:
+ case GL_UNSIGNED_SHORT:
+ case GL_SHORT:
+ case GL_UNSIGNED_INT:
+ case GL_INT:
+ case GL_HALF_FLOAT:
+ case GL_FLOAT:
+ case GL_UNSIGNED_BYTE_3_3_2:
+ case GL_UNSIGNED_BYTE_2_3_3_REV:
+ case GL_UNSIGNED_SHORT_5_6_5:
+ case GL_UNSIGNED_SHORT_5_6_5_REV:
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ case GL_UNSIGNED_SHORT_4_4_4_4_REV:
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ case GL_UNSIGNED_SHORT_1_5_5_5_REV:
+ case GL_UNSIGNED_INT_10_10_10_2:
+ case GL_UNSIGNED_INT_2_10_10_10_REV:
+ case GL_UNSIGNED_INT_24_8:
+ case GL_UNSIGNED_INT_10F_11F_11F_REV:
+ case GL_UNSIGNED_INT_5_9_9_9_REV:
+ case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+// From OpenGL 4.6 spec section 8.4
+bool ValidDesktopFormatCombination(GLenum format, GLenum type, GLenum internalFormat)
+{
+ ASSERT(ValidDesktopFormat(format) && ValidDesktopType(type));
+ const InternalFormat &internalFormatInfo = GetInternalFormatInfo(internalFormat, type);
+ const InternalFormat &formatInfo = GetInternalFormatInfo(format, type);
+
+ switch (format)
+ {
+ case GL_RED_INTEGER:
+ case GL_GREEN_INTEGER:
+ case GL_BLUE_INTEGER:
+ case GL_RG_INTEGER:
+ case GL_RGB_INTEGER:
+ case GL_RGBA_INTEGER:
+ case GL_BGR_INTEGER:
+ case GL_BGRA_INTEGER:
+ switch (type)
+ {
+ case GL_HALF_FLOAT:
+ case GL_FLOAT:
+ case GL_UNSIGNED_INT_10F_11F_11F_REV:
+ case GL_UNSIGNED_INT_5_9_9_9_REV:
+ return false;
+ default:
+ break;
+ }
+ if (!internalFormatInfo.isInt())
+ return false;
+ break;
+ default:
+ // format is not an integer
+ if (internalFormatInfo.isInt())
+ return false;
+
+ if (formatInfo.isDepthOrStencil() != internalFormatInfo.isDepthOrStencil())
+ return false;
+
+ if (format == GL_STENCIL_INDEX && internalFormat != GL_STENCIL_INDEX)
+ return false;
+ break;
+ }
+
+ return true;
+}
+
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/formatutils.cpp b/gfx/angle/checkout/src/libANGLE/formatutils.cpp
new file mode 100644
index 0000000000..76273f3be3
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/formatutils.cpp
@@ -0,0 +1,3220 @@
+//
+// Copyright 2013 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.
+//
+
+// formatutils.cpp: Queries for GL image formats.
+
+#include "libANGLE/formatutils.h"
+
+#include "anglebase/no_destructor.h"
+#include "common/mathutil.h"
+#include "gpu_info_util/SystemInfo.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Framebuffer.h"
+
+using namespace angle;
+
+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);
+
+namespace
+{
+bool CheckedMathResult(const CheckedNumeric<GLuint> &value, GLuint *resultOut)
+{
+ if (!value.IsValid())
+ {
+ return false;
+ }
+ else
+ {
+ *resultOut = value.ValueOrDie();
+ return true;
+ }
+}
+
+constexpr uint32_t PackTypeInfo(GLuint bytes, bool specialized)
+{
+ // static_assert within constexpr requires c++17
+ // static_assert(isPow2(bytes));
+ return bytes | (rx::Log2(bytes) << 8) | (specialized << 16);
+}
+
+} // anonymous namespace
+
+FormatType::FormatType() : format(GL_NONE), type(GL_NONE) {}
+
+FormatType::FormatType(GLenum format_, GLenum type_) : format(format_), type(type_) {}
+
+bool FormatType::operator<(const FormatType &other) const
+{
+ if (format != other.format)
+ return format < other.format;
+ return type < other.type;
+}
+
+bool operator<(const Type &a, const Type &b)
+{
+ return memcmp(&a, &b, sizeof(Type)) < 0;
+}
+
+// Information about internal formats
+static bool AlwaysSupported(const Version &, const Extensions &)
+{
+ return true;
+}
+
+static bool NeverSupported(const Version &, const Extensions &)
+{
+ return false;
+}
+
+static bool RequireES1(const Version &clientVersion, const Extensions &extensions)
+{
+ return clientVersion.major == 1;
+}
+
+template <GLuint minCoreGLMajorVersion, GLuint minCoreGLMinorVersion>
+static bool RequireES(const Version &clientVersion, const Extensions &)
+{
+ return clientVersion >= Version(minCoreGLMajorVersion, minCoreGLMinorVersion);
+}
+
+// Check support for a single extension
+template <ExtensionBool bool1>
+static bool RequireExt(const Version &, const Extensions &extensions)
+{
+ return extensions.*bool1;
+}
+
+// Check for a minimum client version or a single extension
+template <GLuint minCoreGLMajorVersion, GLuint minCoreGLMinorVersion, ExtensionBool bool1>
+static bool RequireESOrExt(const Version &clientVersion, const Extensions &extensions)
+{
+ return clientVersion >= Version(minCoreGLMajorVersion, minCoreGLMinorVersion) ||
+ extensions.*bool1;
+}
+
+// Check for a minimum client version or two extensions
+template <GLuint minCoreGLMajorVersion,
+ GLuint minCoreGLMinorVersion,
+ ExtensionBool bool1,
+ ExtensionBool bool2>
+static bool RequireESOrExtAndExt(const Version &clientVersion, const Extensions &extensions)
+{
+ return clientVersion >= Version(minCoreGLMajorVersion, minCoreGLMinorVersion) ||
+ (extensions.*bool1 && extensions.*bool2);
+}
+
+// Check for a minimum client version or at least one of two extensions
+template <GLuint minCoreGLMajorVersion,
+ GLuint minCoreGLMinorVersion,
+ ExtensionBool bool1,
+ ExtensionBool bool2>
+static bool RequireESOrExtOrExt(const Version &clientVersion, const Extensions &extensions)
+{
+ return clientVersion >= Version(minCoreGLMajorVersion, minCoreGLMinorVersion) ||
+ extensions.*bool1 || extensions.*bool2;
+}
+
+// Check support for two extensions
+template <ExtensionBool bool1, ExtensionBool bool2>
+static bool RequireExtAndExt(const Version &, const Extensions &extensions)
+{
+ return extensions.*bool1 && extensions.*bool2;
+}
+
+// Check support for either of two extensions
+template <ExtensionBool bool1, ExtensionBool bool2>
+static bool RequireExtOrExt(const Version &, const Extensions &extensions)
+{
+ return extensions.*bool1 || extensions.*bool2;
+}
+
+// Check support for any of three extensions
+template <ExtensionBool bool1, ExtensionBool bool2, ExtensionBool bool3>
+static bool RequireExtOrExtOrExt(const Version &, const Extensions &extensions)
+{
+ return extensions.*bool1 || extensions.*bool2 || extensions.*bool3;
+}
+
+// R8, RG8
+static bool SizedRGSupport(const Version &clientVersion, const Extensions &extensions)
+{
+ return clientVersion >= Version(3, 0) ||
+ (extensions.textureStorageEXT && extensions.textureRgEXT);
+}
+
+// R16F, RG16F with HALF_FLOAT_OES type
+static bool SizedHalfFloatOESRGSupport(const Version &clientVersion, const Extensions &extensions)
+{
+ return extensions.textureStorageEXT && extensions.textureHalfFloatOES &&
+ extensions.textureRgEXT;
+}
+
+static bool SizedHalfFloatOESRGTextureAttachmentSupport(const Version &clientVersion,
+ const Extensions &extensions)
+{
+ return SizedHalfFloatOESRGSupport(clientVersion, extensions) &&
+ extensions.colorBufferHalfFloatEXT;
+}
+
+// R16F, RG16F with either HALF_FLOAT_OES or HALF_FLOAT types
+static bool SizedHalfFloatRGSupport(const Version &clientVersion, const Extensions &extensions)
+{
+ // HALF_FLOAT
+ if (clientVersion >= Version(3, 0))
+ {
+ return true;
+ }
+ // HALF_FLOAT_OES
+ else
+ {
+ return SizedHalfFloatOESRGSupport(clientVersion, extensions);
+ }
+}
+
+static bool SizedHalfFloatRGTextureAttachmentSupport(const Version &clientVersion,
+ const Extensions &extensions)
+{
+ // HALF_FLOAT
+ if (clientVersion >= Version(3, 0))
+ {
+ // WebGL 2 supports EXT_color_buffer_half_float.
+ return extensions.colorBufferFloatEXT ||
+ (extensions.webglCompatibilityANGLE && extensions.colorBufferHalfFloatEXT);
+ }
+ // HALF_FLOAT_OES
+ else
+ {
+ return SizedHalfFloatOESRGTextureAttachmentSupport(clientVersion, extensions);
+ }
+}
+
+static bool SizedHalfFloatRGRenderbufferSupport(const Version &clientVersion,
+ const Extensions &extensions)
+{
+ return (clientVersion >= Version(3, 0) ||
+ (extensions.textureHalfFloatOES && extensions.textureRgEXT)) &&
+ (extensions.colorBufferFloatEXT || extensions.colorBufferHalfFloatEXT);
+}
+
+// RGB16F, RGBA16F with HALF_FLOAT_OES type
+static bool SizedHalfFloatOESSupport(const Version &clientVersion, const Extensions &extensions)
+{
+ return extensions.textureStorageEXT && extensions.textureHalfFloatOES;
+}
+
+static bool SizedHalfFloatOESTextureAttachmentSupport(const Version &clientVersion,
+ const Extensions &extensions)
+{
+ return SizedHalfFloatOESSupport(clientVersion, extensions) &&
+ extensions.colorBufferHalfFloatEXT;
+}
+
+// RGB16F, RGBA16F with either HALF_FLOAT_OES or HALF_FLOAT types
+static bool SizedHalfFloatSupport(const Version &clientVersion, const Extensions &extensions)
+{
+ // HALF_FLOAT
+ if (clientVersion >= Version(3, 0))
+ {
+ return true;
+ }
+ // HALF_FLOAT_OES
+ else
+ {
+ return SizedHalfFloatOESSupport(clientVersion, extensions);
+ }
+}
+
+static bool SizedHalfFloatFilterSupport(const Version &clientVersion, const Extensions &extensions)
+{
+ // HALF_FLOAT
+ if (clientVersion >= Version(3, 0))
+ {
+ return true;
+ }
+ // HALF_FLOAT_OES
+ else
+ {
+ return extensions.textureHalfFloatLinearOES;
+ }
+}
+
+static bool SizedHalfFloatRGBTextureAttachmentSupport(const Version &clientVersion,
+ const Extensions &extensions)
+{
+ // HALF_FLOAT
+ if (clientVersion >= Version(3, 0))
+ {
+ // It is unclear how EXT_color_buffer_half_float applies to ES3.0 and above, however,
+ // dEQP GLES3 es3fFboColorbufferTests.cpp verifies that texture attachment of GL_RGB16F
+ // is possible, so assume that all GLES implementations support it.
+ // The WebGL version of the extension explicitly forbids RGB formats.
+ return extensions.colorBufferHalfFloatEXT && !extensions.webglCompatibilityANGLE;
+ }
+ // HALF_FLOAT_OES
+ else
+ {
+ return SizedHalfFloatOESTextureAttachmentSupport(clientVersion, extensions);
+ }
+}
+
+static bool SizedHalfFloatRGBRenderbufferSupport(const Version &clientVersion,
+ const Extensions &extensions)
+{
+ return !extensions.webglCompatibilityANGLE &&
+ ((clientVersion >= Version(3, 0) || extensions.textureHalfFloatOES) &&
+ extensions.colorBufferHalfFloatEXT);
+}
+
+static bool SizedHalfFloatRGBATextureAttachmentSupport(const Version &clientVersion,
+ const Extensions &extensions)
+{
+ // HALF_FLOAT
+ if (clientVersion >= Version(3, 0))
+ {
+ // WebGL 2 supports EXT_color_buffer_half_float.
+ return extensions.colorBufferFloatEXT ||
+ (extensions.webglCompatibilityANGLE && extensions.colorBufferHalfFloatEXT);
+ }
+ // HALF_FLOAT_OES
+ else
+ {
+ return SizedHalfFloatOESTextureAttachmentSupport(clientVersion, extensions);
+ }
+}
+
+static bool SizedHalfFloatRGBARenderbufferSupport(const Version &clientVersion,
+ const Extensions &extensions)
+{
+ return (clientVersion >= Version(3, 0) || extensions.textureHalfFloatOES) &&
+ (extensions.colorBufferFloatEXT || extensions.colorBufferHalfFloatEXT);
+}
+
+// R32F, RG32F
+static bool SizedFloatRGSupport(const Version &clientVersion, const Extensions &extensions)
+{
+ return clientVersion >= Version(3, 0) ||
+ (extensions.textureStorageEXT && extensions.textureFloatOES && extensions.textureRgEXT);
+}
+
+// RGB32F
+static bool SizedFloatRGBSupport(const Version &clientVersion, const Extensions &extensions)
+{
+ return clientVersion >= Version(3, 0) ||
+ (extensions.textureStorageEXT && extensions.textureFloatOES) ||
+ extensions.colorBufferFloatRgbCHROMIUM;
+}
+
+// RGBA32F
+static bool SizedFloatRGBASupport(const Version &clientVersion, const Extensions &extensions)
+{
+ return clientVersion >= Version(3, 0) ||
+ (extensions.textureStorageEXT && extensions.textureFloatOES) ||
+ extensions.colorBufferFloatRgbaCHROMIUM;
+}
+
+static bool SizedFloatRGBARenderableSupport(const Version &clientVersion,
+ const Extensions &extensions)
+{
+ // This logic is the same for both Renderbuffers and TextureAttachment.
+ return extensions.colorBufferFloatRgbaCHROMIUM || // ES2
+ extensions.colorBufferFloatEXT; // ES3
+}
+
+static bool Float32BlendableSupport(const Version &clientVersion, const Extensions &extensions)
+{
+ // EXT_float_blend may be exposed on ES2 client contexts. Ensure that RGBA32F is renderable.
+ return (extensions.colorBufferFloatRgbaCHROMIUM || extensions.colorBufferFloatEXT) &&
+ extensions.floatBlendEXT;
+}
+
+template <ExtensionBool bool1>
+static bool ETC2EACSupport(const Version &clientVersion, const Extensions &extensions)
+{
+ if (extensions.compressedTextureEtcANGLE)
+ {
+ return true;
+ }
+
+ // ETC2/EAC formats are always available in ES 3.0+ but require an extension (checked above)
+ // in WebGL. If that extension is not available, hide these formats from WebGL contexts.
+ return !extensions.webglCompatibilityANGLE &&
+ (clientVersion >= Version(3, 0) || extensions.*bool1);
+}
+
+InternalFormat::InternalFormat()
+ : internalFormat(GL_NONE),
+ sized(false),
+ sizedInternalFormat(GL_NONE),
+ redBits(0),
+ greenBits(0),
+ blueBits(0),
+ luminanceBits(0),
+ alphaBits(0),
+ sharedBits(0),
+ depthBits(0),
+ stencilBits(0),
+ pixelBytes(0),
+ componentCount(0),
+ compressed(false),
+ compressedBlockWidth(0),
+ compressedBlockHeight(0),
+ compressedBlockDepth(0),
+ paletted(false),
+ paletteBits(0),
+ format(GL_NONE),
+ type(GL_NONE),
+ componentType(GL_NONE),
+ colorEncoding(GL_NONE),
+ textureSupport(NeverSupported),
+ filterSupport(NeverSupported),
+ textureAttachmentSupport(NeverSupported),
+ renderbufferSupport(NeverSupported),
+ blendSupport(NeverSupported)
+{}
+
+InternalFormat::InternalFormat(const InternalFormat &other) = default;
+
+InternalFormat &InternalFormat::operator=(const InternalFormat &other) = default;
+
+bool InternalFormat::isLUMA() const
+{
+ return ((redBits + greenBits + blueBits + depthBits + stencilBits) == 0 &&
+ (luminanceBits + alphaBits) > 0);
+}
+
+GLenum InternalFormat::getReadPixelsFormat(const Extensions &extensions) const
+{
+ switch (format)
+ {
+ case GL_BGRA_EXT:
+ // BGRA textures may be enabled but calling glReadPixels with BGRA is disallowed without
+ // GL_EXT_texture_format_BGRA8888. Read as RGBA instead.
+ if (!extensions.readFormatBgraEXT)
+ {
+ return GL_RGBA;
+ }
+ return GL_BGRA_EXT;
+
+ default:
+ return format;
+ }
+}
+
+GLenum InternalFormat::getReadPixelsType(const Version &version) const
+{
+ switch (type)
+ {
+ case GL_HALF_FLOAT:
+ case GL_HALF_FLOAT_OES:
+ if (version < Version(3, 0))
+ {
+ // 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. HALF_FLOAT becomes core in ES3 and is acceptable to use
+ // as an IMPLEMENTATION_READ_TYPE.
+ return GL_HALF_FLOAT_OES;
+ }
+ return GL_HALF_FLOAT;
+
+ default:
+ return type;
+ }
+}
+
+bool InternalFormat::supportSubImage() const
+{
+ return !CompressedFormatRequiresWholeImage(internalFormat);
+}
+
+bool InternalFormat::isRequiredRenderbufferFormat(const Version &version) const
+{
+ // GLES 3.0.5 section 4.4.2.2:
+ // "Implementations are required to support the same internal formats for renderbuffers as the
+ // required formats for textures enumerated in section 3.8.3.1, with the exception of the color
+ // formats labelled "texture-only"."
+ if (!sized || compressed)
+ {
+ return false;
+ }
+
+ // Luma formats.
+ if (isLUMA())
+ {
+ return false;
+ }
+
+ // Depth/stencil formats.
+ if (depthBits > 0 || stencilBits > 0)
+ {
+ // GLES 2.0.25 table 4.5.
+ // GLES 3.0.5 section 3.8.3.1.
+ // GLES 3.1 table 8.14.
+
+ // Required formats in all versions.
+ switch (internalFormat)
+ {
+ case GL_DEPTH_COMPONENT16:
+ case GL_STENCIL_INDEX8:
+ // Note that STENCIL_INDEX8 is not mentioned in GLES 3.0.5 section 3.8.3.1, but it
+ // is in section 4.4.2.2.
+ return true;
+ default:
+ break;
+ }
+ if (version.major < 3)
+ {
+ return false;
+ }
+ // Required formats in GLES 3.0 and up.
+ switch (internalFormat)
+ {
+ case GL_DEPTH_COMPONENT32F:
+ case GL_DEPTH_COMPONENT24:
+ case GL_DEPTH32F_STENCIL8:
+ case GL_DEPTH24_STENCIL8:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ // RGBA formats.
+ // GLES 2.0.25 table 4.5.
+ // GLES 3.0.5 section 3.8.3.1.
+ // GLES 3.1 table 8.13.
+
+ // Required formats in all versions.
+ switch (internalFormat)
+ {
+ case GL_RGBA4:
+ case GL_RGB5_A1:
+ case GL_RGB565:
+ return true;
+ default:
+ break;
+ }
+ if (version.major < 3)
+ {
+ return false;
+ }
+
+ if (format == GL_BGRA_EXT)
+ {
+ return false;
+ }
+
+ switch (componentType)
+ {
+ case GL_SIGNED_NORMALIZED:
+ case GL_FLOAT:
+ return false;
+ case GL_UNSIGNED_INT:
+ case GL_INT:
+ // Integer RGB formats are not required renderbuffer formats.
+ if (alphaBits == 0 && blueBits != 0)
+ {
+ return false;
+ }
+ // All integer R and RG formats are required.
+ // Integer RGBA formats including RGB10_A2_UI are required.
+ return true;
+ case GL_UNSIGNED_NORMALIZED:
+ if (internalFormat == GL_SRGB8)
+ {
+ return false;
+ }
+ return true;
+ default:
+ UNREACHABLE();
+ return false;
+ }
+}
+
+bool InternalFormat::isInt() const
+{
+ return componentType == GL_INT || componentType == GL_UNSIGNED_INT;
+}
+
+bool InternalFormat::isDepthOrStencil() const
+{
+ return depthBits != 0 || stencilBits != 0;
+}
+
+Format::Format(GLenum internalFormat) : Format(GetSizedInternalFormatInfo(internalFormat)) {}
+
+Format::Format(const InternalFormat &internalFormat) : info(&internalFormat) {}
+
+Format::Format(GLenum internalFormat, GLenum type)
+ : info(&GetInternalFormatInfo(internalFormat, type))
+{}
+
+Format::Format(const Format &other) = default;
+Format &Format::operator=(const Format &other) = default;
+
+bool Format::valid() const
+{
+ return info->internalFormat != GL_NONE;
+}
+
+// static
+bool Format::SameSized(const Format &a, const Format &b)
+{
+ return a.info->sizedInternalFormat == b.info->sizedInternalFormat;
+}
+
+static GLenum EquivalentBlitInternalFormat(GLenum internalformat)
+{
+ // BlitFramebuffer works if the color channels are identically
+ // sized, even if there is a swizzle (for example, blitting from a
+ // multisampled RGBA8 renderbuffer to a BGRA8 texture). This could
+ // be expanded and/or autogenerated if that is found necessary.
+ if (internalformat == GL_BGRA8_EXT)
+ {
+ return GL_RGBA8;
+ }
+
+ // GL_ANGLE_rgbx_internal_format: Treat RGBX8 as RGB8, since the X channel is ignored.
+ if (internalformat == GL_RGBX8_ANGLE)
+ {
+ return GL_RGB8;
+ }
+
+ // Treat ANGLE's BGRX8 as RGB8 since it's swizzled and the X channel is ignored.
+ if (internalformat == GL_BGRX8_ANGLEX)
+ {
+ return GL_RGB8;
+ }
+
+ return internalformat;
+}
+
+// static
+bool Format::EquivalentForBlit(const Format &a, const Format &b)
+{
+ return (EquivalentBlitInternalFormat(a.info->sizedInternalFormat) ==
+ EquivalentBlitInternalFormat(b.info->sizedInternalFormat));
+}
+
+// static
+Format Format::Invalid()
+{
+ static Format invalid(GL_NONE, GL_NONE);
+ return invalid;
+}
+
+std::ostream &operator<<(std::ostream &os, const Format &fmt)
+{
+ // TODO(ynovikov): return string representation when available
+ return FmtHex(os, fmt.info->sizedInternalFormat);
+}
+
+bool InternalFormat::operator==(const InternalFormat &other) const
+{
+ // We assume all internal formats are unique if they have the same internal format and type
+ return internalFormat == other.internalFormat && type == other.type;
+}
+
+bool InternalFormat::operator!=(const InternalFormat &other) const
+{
+ return !(*this == other);
+}
+
+void InsertFormatInfo(InternalFormatInfoMap *map, const InternalFormat &formatInfo)
+{
+ ASSERT(!formatInfo.sized || (*map).count(formatInfo.internalFormat) == 0);
+ ASSERT((*map)[formatInfo.internalFormat].count(formatInfo.type) == 0);
+ (*map)[formatInfo.internalFormat][formatInfo.type] = formatInfo;
+}
+
+// YuvFormatInfo implementation
+YuvFormatInfo::YuvFormatInfo(GLenum internalFormat, const Extents &yPlaneExtent)
+{
+ ASSERT(gl::IsYuvFormat(internalFormat));
+ ASSERT((gl::GetPlaneCount(internalFormat) > 0) && (gl::GetPlaneCount(internalFormat) <= 3));
+
+ glInternalFormat = internalFormat;
+ planeCount = gl::GetPlaneCount(internalFormat);
+
+ // Chroma planes of a YUV format can be subsampled
+ int horizontalSubsampleFactor = 0;
+ int verticalSubsampleFactor = 0;
+ gl::GetSubSampleFactor(internalFormat, &horizontalSubsampleFactor, &verticalSubsampleFactor);
+
+ // Compute plane Bpp
+ planeBpp[0] = gl::GetYPlaneBpp(internalFormat);
+ planeBpp[1] = gl::GetChromaPlaneBpp(internalFormat);
+ planeBpp[2] = (planeCount > 2) ? planeBpp[1] : 0;
+
+ // Compute plane extent
+ planeExtent[0] = yPlaneExtent;
+ planeExtent[1] = {(yPlaneExtent.width / horizontalSubsampleFactor),
+ (yPlaneExtent.height / verticalSubsampleFactor), yPlaneExtent.depth};
+ planeExtent[2] = (planeCount > 2) ? planeExtent[1] : Extents();
+
+ // Compute plane pitch
+ planePitch[0] = planeExtent[0].width * planeBpp[0];
+ planePitch[1] = planeExtent[1].width * planeBpp[1];
+ planePitch[2] = planeExtent[2].width * planeBpp[2];
+
+ // Compute plane size
+ planeSize[0] = planePitch[0] * planeExtent[0].height;
+ planeSize[1] = planePitch[1] * planeExtent[1].height;
+ planeSize[2] = planePitch[2] * planeExtent[2].height;
+
+ // Compute plane offset
+ planeOffset[0] = 0;
+ planeOffset[1] = planeSize[0];
+ planeOffset[2] = planeSize[0] + planeSize[1];
+}
+
+// YUV format related helpers
+bool IsYuvFormat(GLenum format)
+{
+ switch (format)
+ {
+ case GL_G8_B8R8_2PLANE_420_UNORM_ANGLE:
+ case GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE:
+ case GL_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_ANGLE:
+ case GL_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_ANGLE:
+ case GL_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_ANGLE:
+ case GL_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_ANGLE:
+ case GL_G16_B16R16_2PLANE_420_UNORM_ANGLE:
+ case GL_G16_B16_R16_3PLANE_420_UNORM_ANGLE:
+ return true;
+ default:
+ return false;
+ }
+}
+
+uint32_t GetPlaneCount(GLenum format)
+{
+ switch (format)
+ {
+ case GL_G8_B8R8_2PLANE_420_UNORM_ANGLE:
+ case GL_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_ANGLE:
+ case GL_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_ANGLE:
+ case GL_G16_B16R16_2PLANE_420_UNORM_ANGLE:
+ return 2;
+ case GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE:
+ case GL_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_ANGLE:
+ case GL_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_ANGLE:
+ case GL_G16_B16_R16_3PLANE_420_UNORM_ANGLE:
+ return 3;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+uint32_t GetYPlaneBpp(GLenum format)
+{
+ switch (format)
+ {
+ case GL_G8_B8R8_2PLANE_420_UNORM_ANGLE:
+ case GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE:
+ return 1;
+ case GL_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_ANGLE:
+ case GL_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_ANGLE:
+ case GL_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_ANGLE:
+ case GL_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_ANGLE:
+ case GL_G16_B16R16_2PLANE_420_UNORM_ANGLE:
+ case GL_G16_B16_R16_3PLANE_420_UNORM_ANGLE:
+ return 2;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+uint32_t GetChromaPlaneBpp(GLenum format)
+{
+ // 2 plane 420 YUV formats have CbCr channels interleaved.
+ // 3 plane 420 YUV formats have separate Cb and Cr planes.
+ switch (format)
+ {
+ case GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE:
+ return 1;
+ case GL_G8_B8R8_2PLANE_420_UNORM_ANGLE:
+ case GL_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_ANGLE:
+ case GL_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_ANGLE:
+ case GL_G16_B16_R16_3PLANE_420_UNORM_ANGLE:
+ return 2;
+ case GL_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_ANGLE:
+ case GL_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_ANGLE:
+ case GL_G16_B16R16_2PLANE_420_UNORM_ANGLE:
+ return 4;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+void GetSubSampleFactor(GLenum format, int *horizontalSubsampleFactor, int *verticalSubsampleFactor)
+{
+ ASSERT(horizontalSubsampleFactor && verticalSubsampleFactor);
+
+ switch (format)
+ {
+ case GL_G8_B8R8_2PLANE_420_UNORM_ANGLE:
+ case GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE:
+ case GL_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_ANGLE:
+ case GL_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_ANGLE:
+ case GL_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_ANGLE:
+ case GL_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_ANGLE:
+ case GL_G16_B16R16_2PLANE_420_UNORM_ANGLE:
+ case GL_G16_B16_R16_3PLANE_420_UNORM_ANGLE:
+ *horizontalSubsampleFactor = 2;
+ *verticalSubsampleFactor = 2;
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+struct FormatBits
+{
+ constexpr GLuint pixelBytes() const
+ {
+ return (red + green + blue + alpha + shared + unused) / 8;
+ }
+ constexpr GLuint componentCount() const
+ {
+ return ((red > 0) ? 1 : 0) + ((green > 0) ? 1 : 0) + ((blue > 0) ? 1 : 0) +
+ ((alpha > 0) ? 1 : 0);
+ }
+ constexpr bool valid() const
+ {
+ return ((red + green + blue + alpha + shared + unused) % 8) == 0;
+ }
+
+ GLuint red;
+ GLuint green;
+ GLuint blue;
+ GLuint alpha;
+ GLuint unused;
+ GLuint shared;
+};
+
+template <GLuint red, GLuint green, GLuint blue, GLuint alpha, GLuint unused, GLuint shared>
+constexpr FormatBits FB()
+{
+ constexpr FormatBits formatBits = {red, green, blue, alpha, unused, shared};
+ static_assert(formatBits.valid(), "Invalid FormatBits");
+ return formatBits;
+}
+
+void AddRGBAXFormat(InternalFormatInfoMap *map,
+ GLenum internalFormat,
+ bool sized,
+ const FormatBits &formatBits,
+ GLenum format,
+ GLenum type,
+ GLenum componentType,
+ bool srgb,
+ InternalFormat::SupportCheckFunction textureSupport,
+ InternalFormat::SupportCheckFunction filterSupport,
+ InternalFormat::SupportCheckFunction textureAttachmentSupport,
+ InternalFormat::SupportCheckFunction renderbufferSupport,
+ InternalFormat::SupportCheckFunction blendSupport)
+{
+ ASSERT(formatBits.valid());
+
+ InternalFormat formatInfo;
+ formatInfo.internalFormat = internalFormat;
+ formatInfo.sized = sized;
+ formatInfo.sizedInternalFormat =
+ sized ? internalFormat : GetSizedFormatInternal(internalFormat, type);
+ formatInfo.redBits = formatBits.red;
+ formatInfo.greenBits = formatBits.green;
+ formatInfo.blueBits = formatBits.blue;
+ formatInfo.alphaBits = formatBits.alpha;
+ formatInfo.sharedBits = formatBits.shared;
+ formatInfo.pixelBytes = formatBits.pixelBytes();
+ formatInfo.componentCount = formatBits.componentCount();
+ formatInfo.format = format;
+ formatInfo.type = type;
+ formatInfo.componentType = componentType;
+ formatInfo.colorEncoding = (srgb ? GL_SRGB : GL_LINEAR);
+ formatInfo.textureSupport = textureSupport;
+ formatInfo.filterSupport = filterSupport;
+ formatInfo.textureAttachmentSupport = textureAttachmentSupport;
+ formatInfo.renderbufferSupport = renderbufferSupport;
+ formatInfo.blendSupport = blendSupport;
+
+ InsertFormatInfo(map, formatInfo);
+}
+
+void AddRGBAFormat(InternalFormatInfoMap *map,
+ GLenum internalFormat,
+ bool sized,
+ GLuint red,
+ GLuint green,
+ GLuint blue,
+ GLuint alpha,
+ GLuint shared,
+ GLenum format,
+ GLenum type,
+ GLenum componentType,
+ bool srgb,
+ InternalFormat::SupportCheckFunction textureSupport,
+ InternalFormat::SupportCheckFunction filterSupport,
+ InternalFormat::SupportCheckFunction textureAttachmentSupport,
+ InternalFormat::SupportCheckFunction renderbufferSupport,
+ InternalFormat::SupportCheckFunction blendSupport)
+{
+ return AddRGBAXFormat(map, internalFormat, sized, {red, green, blue, alpha, 0, shared}, format,
+ type, componentType, srgb, textureSupport, filterSupport,
+ textureAttachmentSupport, renderbufferSupport, blendSupport);
+}
+
+static void AddLUMAFormat(InternalFormatInfoMap *map,
+ GLenum internalFormat,
+ bool sized,
+ GLuint luminance,
+ GLuint alpha,
+ GLenum format,
+ GLenum type,
+ GLenum componentType,
+ InternalFormat::SupportCheckFunction textureSupport,
+ InternalFormat::SupportCheckFunction filterSupport,
+ InternalFormat::SupportCheckFunction textureAttachmentSupport,
+ InternalFormat::SupportCheckFunction renderbufferSupport,
+ InternalFormat::SupportCheckFunction blendSupport)
+{
+ InternalFormat formatInfo;
+ formatInfo.internalFormat = internalFormat;
+ formatInfo.sized = sized;
+ formatInfo.sizedInternalFormat =
+ sized ? internalFormat : GetSizedFormatInternal(internalFormat, type);
+ formatInfo.luminanceBits = luminance;
+ formatInfo.alphaBits = alpha;
+ formatInfo.pixelBytes = (luminance + alpha) / 8;
+ formatInfo.componentCount = ((luminance > 0) ? 1 : 0) + ((alpha > 0) ? 1 : 0);
+ formatInfo.format = format;
+ formatInfo.type = type;
+ formatInfo.componentType = componentType;
+ formatInfo.colorEncoding = GL_LINEAR;
+ formatInfo.textureSupport = textureSupport;
+ formatInfo.filterSupport = filterSupport;
+ formatInfo.textureAttachmentSupport = textureAttachmentSupport;
+ formatInfo.renderbufferSupport = renderbufferSupport;
+ formatInfo.blendSupport = blendSupport;
+
+ InsertFormatInfo(map, formatInfo);
+}
+
+void AddDepthStencilFormat(InternalFormatInfoMap *map,
+ GLenum internalFormat,
+ bool sized,
+ GLuint depthBits,
+ GLuint stencilBits,
+ GLuint unusedBits,
+ GLenum format,
+ GLenum type,
+ GLenum componentType,
+ InternalFormat::SupportCheckFunction textureSupport,
+ InternalFormat::SupportCheckFunction filterSupport,
+ InternalFormat::SupportCheckFunction textureAttachmentSupport,
+ InternalFormat::SupportCheckFunction renderbufferSupport,
+ InternalFormat::SupportCheckFunction blendSupport)
+{
+ InternalFormat formatInfo;
+ formatInfo.internalFormat = internalFormat;
+ formatInfo.sized = sized;
+ formatInfo.sizedInternalFormat =
+ sized ? internalFormat : GetSizedFormatInternal(internalFormat, type);
+ formatInfo.depthBits = depthBits;
+ formatInfo.stencilBits = stencilBits;
+ formatInfo.pixelBytes = (depthBits + stencilBits + unusedBits) / 8;
+ formatInfo.componentCount = ((depthBits > 0) ? 1 : 0) + ((stencilBits > 0) ? 1 : 0);
+ formatInfo.format = format;
+ formatInfo.type = type;
+ formatInfo.componentType = componentType;
+ formatInfo.colorEncoding = GL_LINEAR;
+ formatInfo.textureSupport = textureSupport;
+ formatInfo.filterSupport = filterSupport;
+ formatInfo.textureAttachmentSupport = textureAttachmentSupport;
+ formatInfo.renderbufferSupport = renderbufferSupport;
+ formatInfo.blendSupport = blendSupport;
+
+ InsertFormatInfo(map, formatInfo);
+}
+
+void AddCompressedFormat(InternalFormatInfoMap *map,
+ GLenum internalFormat,
+ GLuint compressedBlockWidth,
+ GLuint compressedBlockHeight,
+ GLuint compressedBlockDepth,
+ GLuint compressedBlockSize,
+ GLuint componentCount,
+ bool srgb,
+ InternalFormat::SupportCheckFunction textureSupport,
+ InternalFormat::SupportCheckFunction filterSupport,
+ InternalFormat::SupportCheckFunction textureAttachmentSupport,
+ InternalFormat::SupportCheckFunction renderbufferSupport,
+ InternalFormat::SupportCheckFunction blendSupport)
+{
+ InternalFormat formatInfo;
+ formatInfo.internalFormat = internalFormat;
+ formatInfo.sized = true;
+ formatInfo.sizedInternalFormat = internalFormat;
+ formatInfo.compressedBlockWidth = compressedBlockWidth;
+ formatInfo.compressedBlockHeight = compressedBlockHeight;
+ formatInfo.compressedBlockDepth = compressedBlockDepth;
+ formatInfo.pixelBytes = compressedBlockSize / 8;
+ formatInfo.componentCount = componentCount;
+ formatInfo.format = internalFormat;
+ formatInfo.type = GL_UNSIGNED_BYTE;
+ formatInfo.componentType = GL_UNSIGNED_NORMALIZED;
+ formatInfo.colorEncoding = (srgb ? GL_SRGB : GL_LINEAR);
+ formatInfo.compressed = true;
+ formatInfo.textureSupport = textureSupport;
+ formatInfo.filterSupport = filterSupport;
+ formatInfo.textureAttachmentSupport = textureAttachmentSupport;
+ formatInfo.renderbufferSupport = renderbufferSupport;
+ formatInfo.blendSupport = blendSupport;
+
+ InsertFormatInfo(map, formatInfo);
+}
+
+void AddPalettedFormat(InternalFormatInfoMap *map,
+ GLenum internalFormat,
+ GLuint paletteBits,
+ GLuint pixelBytes,
+ GLenum format,
+ GLuint componentCount,
+ InternalFormat::SupportCheckFunction textureSupport,
+ InternalFormat::SupportCheckFunction filterSupport,
+ InternalFormat::SupportCheckFunction textureAttachmentSupport,
+ InternalFormat::SupportCheckFunction renderbufferSupport,
+ InternalFormat::SupportCheckFunction blendSupport)
+{
+ InternalFormat formatInfo;
+ formatInfo.internalFormat = internalFormat;
+ formatInfo.sized = true;
+ formatInfo.sizedInternalFormat = internalFormat;
+ formatInfo.paletteBits = paletteBits;
+ formatInfo.pixelBytes = pixelBytes;
+ formatInfo.componentCount = componentCount;
+ formatInfo.format = format;
+ formatInfo.type = GL_UNSIGNED_BYTE;
+ formatInfo.componentType = GL_UNSIGNED_NORMALIZED;
+ formatInfo.colorEncoding = GL_LINEAR;
+ formatInfo.paletted = true;
+ formatInfo.textureSupport = textureSupport;
+ formatInfo.filterSupport = filterSupport;
+ formatInfo.textureAttachmentSupport = textureAttachmentSupport;
+ formatInfo.renderbufferSupport = renderbufferSupport;
+ formatInfo.blendSupport = blendSupport;
+
+ InsertFormatInfo(map, formatInfo);
+}
+
+void AddYUVFormat(InternalFormatInfoMap *map,
+ GLenum internalFormat,
+ bool sized,
+ GLuint cr,
+ GLuint y,
+ GLuint cb,
+ GLuint alpha,
+ GLuint shared,
+ GLenum format,
+ GLenum type,
+ GLenum componentType,
+ bool srgb,
+ InternalFormat::SupportCheckFunction textureSupport,
+ InternalFormat::SupportCheckFunction filterSupport,
+ InternalFormat::SupportCheckFunction textureAttachmentSupport,
+ InternalFormat::SupportCheckFunction renderbufferSupport,
+ InternalFormat::SupportCheckFunction blendSupport)
+{
+ ASSERT(sized);
+
+ InternalFormat formatInfo;
+ formatInfo.internalFormat = internalFormat;
+ formatInfo.sized = sized;
+ formatInfo.sizedInternalFormat = internalFormat;
+ formatInfo.redBits = cr;
+ formatInfo.greenBits = y;
+ formatInfo.blueBits = cb;
+ formatInfo.alphaBits = alpha;
+ formatInfo.sharedBits = shared;
+ formatInfo.pixelBytes = (cr + y + cb + alpha + shared) / 8;
+ formatInfo.componentCount =
+ ((cr > 0) ? 1 : 0) + ((y > 0) ? 1 : 0) + ((cb > 0) ? 1 : 0) + ((alpha > 0) ? 1 : 0);
+ formatInfo.format = format;
+ formatInfo.type = type;
+ formatInfo.componentType = componentType;
+ formatInfo.colorEncoding = (srgb ? GL_SRGB : GL_LINEAR);
+ formatInfo.textureSupport = textureSupport;
+ formatInfo.filterSupport = filterSupport;
+ formatInfo.textureAttachmentSupport = textureAttachmentSupport;
+ formatInfo.renderbufferSupport = renderbufferSupport;
+ formatInfo.blendSupport = blendSupport;
+
+ InsertFormatInfo(map, formatInfo);
+}
+
+// Notes:
+// 1. "Texture supported" includes all the means by which texture can be created, however,
+// GL_EXT_texture_storage in ES2 is a special case, when only glTexStorage* is allowed.
+// The assumption is that ES2 validation will not check textureSupport for sized formats.
+//
+// 2. Sized half float types are a combination of GL_HALF_FLOAT and GL_HALF_FLOAT_OES support,
+// due to a limitation that only one type for sized formats is allowed.
+//
+// TODO(ynovikov): http://anglebug.com/2846 Verify support fields of BGRA, depth, stencil
+// and compressed formats. Perform texturable check as part of filterable and attachment checks.
+static InternalFormatInfoMap BuildInternalFormatInfoMap()
+{
+ InternalFormatInfoMap map;
+
+ // From ES 3.0.1 spec, table 3.12
+ map[GL_NONE][GL_NONE] = InternalFormat();
+
+ // clang-format off
+
+ // | Internal format |sized| R | G | B | A |S | Format | Type | Component type | SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend
+ AddRGBAFormat(&map, GL_R8, true, 8, 0, 0, 0, 0, GL_RED, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, SizedRGSupport, AlwaysSupported, SizedRGSupport, RequireESOrExt<3, 0, &Extensions::textureRgEXT>, RequireESOrExt<3, 0, &Extensions::textureRgEXT>);
+ AddRGBAFormat(&map, GL_R8_SNORM, true, 8, 0, 0, 0, 0, GL_RED, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireES<3, 0>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RG8, true, 8, 8, 0, 0, 0, GL_RG, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, SizedRGSupport, AlwaysSupported, SizedRGSupport, RequireESOrExt<3, 0, &Extensions::textureRgEXT>, RequireESOrExt<3, 0, &Extensions::textureRgEXT>);
+ AddRGBAFormat(&map, GL_RG8_SNORM, true, 8, 8, 0, 0, 0, GL_RG, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireES<3, 0>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RGB8, true, 8, 8, 8, 0, 0, GL_RGB, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, 0, &Extensions::textureStorageEXT>, AlwaysSupported, RequireESOrExt<3, 0, &Extensions::textureStorageEXT>, RequireESOrExt<3, 0, &Extensions::rgb8Rgba8OES>, RequireESOrExt<3, 0, &Extensions::rgb8Rgba8OES>);
+ AddRGBAFormat(&map, GL_RGB8_SNORM, true, 8, 8, 8, 0, 0, GL_RGB, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireES<3, 0>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RGB565, true, 5, 6, 5, 0, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, 0, &Extensions::textureStorageEXT>, AlwaysSupported, RequireESOrExt<3, 0, &Extensions::textureStorageEXT>, RequireES<2, 0>, RequireES<2, 0>);
+ AddRGBAFormat(&map, GL_RGBA4, true, 4, 4, 4, 4, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, 0, &Extensions::textureStorageEXT>, AlwaysSupported, RequireESOrExt<3, 0, &Extensions::textureStorageEXT>, RequireES<2, 0>, RequireES<2, 0>);
+ AddRGBAFormat(&map, GL_RGB5_A1, true, 5, 5, 5, 1, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, 0, &Extensions::textureStorageEXT>, AlwaysSupported, RequireESOrExt<3, 0, &Extensions::textureStorageEXT>, RequireES<2, 0>, RequireES<2, 0>);
+ AddRGBAFormat(&map, GL_RGBA8, true, 8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireESOrExt<3, 0, &Extensions::textureStorageEXT>, AlwaysSupported, RequireESOrExt<3, 0, &Extensions::textureStorageEXT>, RequireESOrExt<3, 0, &Extensions::rgb8Rgba8OES>, RequireESOrExt<3, 0, &Extensions::rgb8Rgba8OES>);
+ AddRGBAFormat(&map, GL_RGBA8_SNORM, true, 8, 8, 8, 8, 0, GL_RGBA, GL_BYTE, GL_SIGNED_NORMALIZED, false, RequireES<3, 0>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RGB10_A2UI, true, 10, 10, 10, 2, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, RequireES<3, 0>, RequireES<3, 0>, NeverSupported);
+ AddRGBAFormat(&map, GL_SRGB8, true, 8, 8, 8, 0, 0, GL_RGB, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, true, RequireES<3, 0>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_SRGB8_ALPHA8, true, 8, 8, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, true, RequireESOrExt<3, 0, &Extensions::sRGBEXT>, AlwaysSupported, RequireES<3, 0>, RequireESOrExt<3, 0, &Extensions::sRGBEXT>, RequireESOrExt<3, 0, &Extensions::sRGBEXT>);
+ AddRGBAFormat(&map, GL_R11F_G11F_B10F, true, 11, 11, 10, 0, 0, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, GL_FLOAT, false, RequireES<3, 0>, AlwaysSupported, RequireExt<&Extensions::colorBufferFloatEXT>, RequireExt<&Extensions::colorBufferFloatEXT>, RequireExt<&Extensions::colorBufferFloatEXT>);
+ AddRGBAFormat(&map, GL_RGB9_E5, true, 9, 9, 9, 0, 5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, GL_FLOAT, false, RequireES<3, 0>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_R8I, true, 8, 0, 0, 0, 0, GL_RED_INTEGER, GL_BYTE, GL_INT, false, RequireES<3, 0>, NeverSupported, RequireES<3, 0>, RequireES<3, 0>, NeverSupported);
+ AddRGBAFormat(&map, GL_R8UI, true, 8, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, RequireES<3, 0>, RequireES<3, 0>, NeverSupported);
+ AddRGBAFormat(&map, GL_R16I, true, 16, 0, 0, 0, 0, GL_RED_INTEGER, GL_SHORT, GL_INT, false, RequireES<3, 0>, NeverSupported, RequireES<3, 0>, RequireES<3, 0>, NeverSupported);
+ AddRGBAFormat(&map, GL_R16UI, true, 16, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, RequireES<3, 0>, RequireES<3, 0>, NeverSupported);
+ AddRGBAFormat(&map, GL_R32I, true, 32, 0, 0, 0, 0, GL_RED_INTEGER, GL_INT, GL_INT, false, RequireES<3, 0>, NeverSupported, RequireES<3, 0>, RequireES<3, 0>, NeverSupported);
+ AddRGBAFormat(&map, GL_R32UI, true, 32, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, RequireES<3, 0>, RequireES<3, 0>, NeverSupported);
+ AddRGBAFormat(&map, GL_RG8I, true, 8, 8, 0, 0, 0, GL_RG_INTEGER, GL_BYTE, GL_INT, false, RequireES<3, 0>, NeverSupported, RequireES<3, 0>, RequireES<3, 0>, NeverSupported);
+ AddRGBAFormat(&map, GL_RG8UI, true, 8, 8, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, RequireES<3, 0>, RequireES<3, 0>, NeverSupported);
+ AddRGBAFormat(&map, GL_RG16I, true, 16, 16, 0, 0, 0, GL_RG_INTEGER, GL_SHORT, GL_INT, false, RequireES<3, 0>, NeverSupported, RequireES<3, 0>, RequireES<3, 0>, NeverSupported);
+ AddRGBAFormat(&map, GL_RG16UI, true, 16, 16, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, RequireES<3, 0>, RequireES<3, 0>, NeverSupported);
+ AddRGBAFormat(&map, GL_RG32I, true, 32, 32, 0, 0, 0, GL_RG_INTEGER, GL_INT, GL_INT, false, RequireES<3, 0>, NeverSupported, RequireES<3, 0>, RequireES<3, 0>, NeverSupported);
+ AddRGBAFormat(&map, GL_RG32UI, true, 32, 32, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, RequireES<3, 0>, RequireES<3, 0>, NeverSupported);
+ AddRGBAFormat(&map, GL_RGB8I, true, 8, 8, 8, 0, 0, GL_RGB_INTEGER, GL_BYTE, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RGB8UI, true, 8, 8, 8, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RGB16I, true, 16, 16, 16, 0, 0, GL_RGB_INTEGER, GL_SHORT, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RGB16UI, true, 16, 16, 16, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RGB32I, true, 32, 32, 32, 0, 0, GL_RGB_INTEGER, GL_INT, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RGB32UI, true, 32, 32, 32, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RGBA8I, true, 8, 8, 8, 8, 0, GL_RGBA_INTEGER, GL_BYTE, GL_INT, false, RequireES<3, 0>, NeverSupported, RequireES<3, 0>, RequireES<3, 0>, NeverSupported);
+ AddRGBAFormat(&map, GL_RGBA8UI, true, 8, 8, 8, 8, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, RequireES<3, 0>, RequireES<3, 0>, NeverSupported);
+ AddRGBAFormat(&map, GL_RGBA16I, true, 16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_SHORT, GL_INT, false, RequireES<3, 0>, NeverSupported, RequireES<3, 0>, RequireES<3, 0>, NeverSupported);
+ AddRGBAFormat(&map, GL_RGBA16UI, true, 16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, RequireES<3, 0>, RequireES<3, 0>, NeverSupported);
+ AddRGBAFormat(&map, GL_RGBA32I, true, 32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_INT, GL_INT, false, RequireES<3, 0>, NeverSupported, RequireES<3, 0>, RequireES<3, 0>, NeverSupported);
+ AddRGBAFormat(&map, GL_RGBA32UI, true, 32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, RequireES<3, 0>, RequireES<3, 0>, NeverSupported);
+
+ AddRGBAFormat(&map, GL_BGRA8_EXT, true, 8, 8, 8, 8, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureFormatBGRA8888EXT>, AlwaysSupported, RequireExt<&Extensions::textureFormatBGRA8888EXT>, RequireExt<&Extensions::textureFormatBGRA8888EXT>, RequireExt<&Extensions::textureFormatBGRA8888EXT>);
+ AddRGBAFormat(&map, GL_BGRA4_ANGLEX, true, 4, 4, 4, 4, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureFormatBGRA8888EXT>, AlwaysSupported, RequireExt<&Extensions::textureFormatBGRA8888EXT>, RequireExt<&Extensions::textureFormatBGRA8888EXT>, RequireExt<&Extensions::textureFormatBGRA8888EXT>);
+ AddRGBAFormat(&map, GL_BGR5_A1_ANGLEX, true, 5, 5, 5, 1, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureFormatBGRA8888EXT>, AlwaysSupported, RequireExt<&Extensions::textureFormatBGRA8888EXT>, RequireExt<&Extensions::textureFormatBGRA8888EXT>, RequireExt<&Extensions::textureFormatBGRA8888EXT>);
+
+ // Special format that is used for D3D textures that are used within ANGLE via the
+ // EGL_ANGLE_d3d_texture_client_buffer extension. We don't allow uploading texture images with
+ // this format, but textures in this format can be created from D3D textures, and filtering them
+ // and rendering to them is allowed.
+ AddRGBAFormat(&map, GL_BGRA8_SRGB_ANGLEX, true, 8, 8, 8, 8, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, true, NeverSupported, AlwaysSupported, AlwaysSupported, AlwaysSupported, AlwaysSupported);
+
+ // Special format which is not really supported, so always false for all supports.
+ AddRGBAFormat(&map, GL_BGR565_ANGLEX, true, 5, 6, 5, 0, 0, GL_BGRA_EXT, GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_NORMALIZED, false, NeverSupported, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_BGR10_A2_ANGLEX, true, 10, 10, 10, 2, 0, GL_BGRA_EXT, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_NORMALIZED, false, NeverSupported, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+
+ // Special format to emulate RGB8 with RGBA8 within ANGLE.
+ AddRGBAFormat(&map, GL_RGBX8_ANGLE, true, 8, 8, 8, 0, 0, GL_RGB, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, AlwaysSupported, AlwaysSupported, NeverSupported);
+
+ // Special format to emulate BGR8 with BGRA8 within ANGLE.
+ AddRGBAFormat(&map, GL_BGRX8_ANGLEX, true, 8, 8, 8, 0, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, NeverSupported, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+
+ // This format is supported on ES 2.0 with two extensions, so keep it out-of-line to not widen the table above even more.
+ // | Internal format |sized| R | G | B | A |S | Format | Type | Component type | SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend
+ AddRGBAFormat(&map, GL_RGB10_A2, true, 10, 10, 10, 2, 0, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_NORMALIZED, false, RequireESOrExtAndExt<3, 0, &Extensions::textureStorageEXT, &Extensions::textureType2101010REVEXT>, AlwaysSupported, RequireES<3, 0>, RequireES<3, 0>, RequireES<3, 0>);
+
+ // Floating point formats
+ // | Internal format |sized| R | G | B | A |S | Format | Type | Component type | SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend
+ // It's not possible to have two entries per sized format.
+ // E.g. for GL_RG16F, one with GL_HALF_FLOAT type and the other with GL_HALF_FLOAT_OES type.
+ // So, GL_HALF_FLOAT type formats conditions are merged with GL_HALF_FLOAT_OES type conditions.
+ AddRGBAFormat(&map, GL_R16F, true, 16, 0, 0, 0, 0, GL_RED, GL_HALF_FLOAT, GL_FLOAT, false, SizedHalfFloatRGSupport, SizedHalfFloatFilterSupport, SizedHalfFloatRGTextureAttachmentSupport, SizedHalfFloatRGRenderbufferSupport, SizedHalfFloatRGRenderbufferSupport);
+ AddRGBAFormat(&map, GL_RG16F, true, 16, 16, 0, 0, 0, GL_RG, GL_HALF_FLOAT, GL_FLOAT, false, SizedHalfFloatRGSupport, SizedHalfFloatFilterSupport, SizedHalfFloatRGTextureAttachmentSupport, SizedHalfFloatRGRenderbufferSupport, SizedHalfFloatRGRenderbufferSupport);
+ AddRGBAFormat(&map, GL_RGB16F, true, 16, 16, 16, 0, 0, GL_RGB, GL_HALF_FLOAT, GL_FLOAT, false, SizedHalfFloatSupport, SizedHalfFloatFilterSupport, SizedHalfFloatRGBTextureAttachmentSupport, SizedHalfFloatRGBRenderbufferSupport, SizedHalfFloatRGBRenderbufferSupport);
+ AddRGBAFormat(&map, GL_RGBA16F, true, 16, 16, 16, 16, 0, GL_RGBA, GL_HALF_FLOAT, GL_FLOAT, false, SizedHalfFloatSupport, SizedHalfFloatFilterSupport, SizedHalfFloatRGBATextureAttachmentSupport, SizedHalfFloatRGBARenderbufferSupport, SizedHalfFloatRGBARenderbufferSupport);
+ AddRGBAFormat(&map, GL_R32F, true, 32, 0, 0, 0, 0, GL_RED, GL_FLOAT, GL_FLOAT, false, SizedFloatRGSupport, RequireExt<&Extensions::textureFloatLinearOES>, RequireExt<&Extensions::colorBufferFloatEXT>, RequireExt<&Extensions::colorBufferFloatEXT>, Float32BlendableSupport);
+ AddRGBAFormat(&map, GL_RG32F, true, 32, 32, 0, 0, 0, GL_RG, GL_FLOAT, GL_FLOAT, false, SizedFloatRGSupport, RequireExt<&Extensions::textureFloatLinearOES>, RequireExt<&Extensions::colorBufferFloatEXT>, RequireExt<&Extensions::colorBufferFloatEXT>, Float32BlendableSupport);
+ AddRGBAFormat(&map, GL_RGB32F, true, 32, 32, 32, 0, 0, GL_RGB, GL_FLOAT, GL_FLOAT, false, SizedFloatRGBSupport, RequireExt<&Extensions::textureFloatLinearOES>, RequireExt<&Extensions::colorBufferFloatRgbCHROMIUM>, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RGBA32F, true, 32, 32, 32, 32, 0, GL_RGBA, GL_FLOAT, GL_FLOAT, false, SizedFloatRGBASupport, RequireExt<&Extensions::textureFloatLinearOES>, SizedFloatRGBARenderableSupport, SizedFloatRGBARenderableSupport, Float32BlendableSupport);
+
+ // ANGLE Depth stencil formats
+ // | Internal format |sized| D |S | X | Format | Type | Component type | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend
+ AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT16, true, 16, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, RequireESOrExtOrExt<3, 0, &Extensions::depthTextureANGLE, &Extensions::depthTextureOES>, RequireESOrExtOrExt<3, 0, &Extensions::depthTextureANGLE, &Extensions::depthTextureOES>, RequireES<1, 0>, RequireES<1, 0>, RequireES<1, 0>);
+ AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT24, true, 24, 0, 8, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_UNSIGNED_NORMALIZED, RequireES<3, 0>, RequireESOrExt<3, 0, &Extensions::depthTextureANGLE>, RequireES<3, 0>, RequireESOrExt<3, 0, &Extensions::depth24OES>, RequireESOrExt<3, 0, &Extensions::depth24OES>);
+ AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT32F, true, 32, 0, 0, GL_DEPTH_COMPONENT, GL_FLOAT, GL_FLOAT, RequireES<3, 0>, RequireESOrExt<3, 0, &Extensions::depthTextureANGLE>, RequireES<3, 0>, RequireES<3, 0>, RequireES<3, 0>);
+ AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT32_OES, true, 32, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_UNSIGNED_NORMALIZED, RequireExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES>, AlwaysSupported, RequireExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES>, RequireExtOrExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES, &Extensions::depth32OES>, RequireExtOrExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES, &Extensions::depth32OES>);
+ AddDepthStencilFormat(&map, GL_DEPTH24_STENCIL8, true, 24, 8, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_UNSIGNED_NORMALIZED, RequireESOrExtOrExt<3, 0, &Extensions::depthTextureANGLE, &Extensions::packedDepthStencilOES>, AlwaysSupported, RequireESOrExtOrExt<3, 0, &Extensions::depthTextureANGLE, &Extensions::packedDepthStencilOES>, RequireESOrExtOrExt<3, 0, &Extensions::depthTextureANGLE, &Extensions::packedDepthStencilOES>, RequireESOrExtOrExt<3, 0, &Extensions::depthTextureANGLE, &Extensions::packedDepthStencilOES>);
+ AddDepthStencilFormat(&map, GL_DEPTH32F_STENCIL8, true, 32, 8, 24, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_FLOAT, RequireESOrExt<3, 0, &Extensions::depthBufferFloat2NV>, AlwaysSupported, RequireESOrExt<3, 0, &Extensions::depthBufferFloat2NV>, RequireESOrExt<3, 0, &Extensions::depthBufferFloat2NV>, RequireESOrExt<3, 0, &Extensions::depthBufferFloat2NV>);
+ // STENCIL_INDEX8 is special-cased, see around the bottom of the list.
+
+ // Luminance alpha formats
+ // | Internal format |sized| L | A | Format | Type | Component type | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend
+ AddLUMAFormat(&map, GL_ALPHA8_EXT, true, 0, 8, GL_ALPHA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireExt<&Extensions::textureStorageEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddLUMAFormat(&map, GL_LUMINANCE8_EXT, true, 8, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireExt<&Extensions::textureStorageEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddLUMAFormat(&map, GL_LUMINANCE8_ALPHA8_EXT, true, 8, 8, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireExt<&Extensions::textureStorageEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddLUMAFormat(&map, GL_ALPHA16F_EXT, true, 0, 16, GL_ALPHA, GL_HALF_FLOAT_OES, GL_FLOAT, RequireExtAndExt<&Extensions::textureStorageEXT, &Extensions::textureHalfFloatOES>, RequireExt<&Extensions::textureHalfFloatLinearOES>, NeverSupported, NeverSupported, NeverSupported);
+ AddLUMAFormat(&map, GL_LUMINANCE16F_EXT, true, 16, 0, GL_LUMINANCE, GL_HALF_FLOAT_OES, GL_FLOAT, RequireExtAndExt<&Extensions::textureStorageEXT, &Extensions::textureHalfFloatOES>, RequireExt<&Extensions::textureHalfFloatLinearOES>, NeverSupported, NeverSupported, NeverSupported);
+ AddLUMAFormat(&map, GL_LUMINANCE_ALPHA16F_EXT, true, 16, 16, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES, GL_FLOAT, RequireExtAndExt<&Extensions::textureStorageEXT, &Extensions::textureHalfFloatOES>, RequireExt<&Extensions::textureHalfFloatLinearOES>, NeverSupported, NeverSupported, NeverSupported);
+ AddLUMAFormat(&map, GL_ALPHA32F_EXT, true, 0, 32, GL_ALPHA, GL_FLOAT, GL_FLOAT, RequireExtAndExt<&Extensions::textureStorageEXT, &Extensions::textureFloatOES>, RequireExt<&Extensions::textureFloatLinearOES>, NeverSupported, NeverSupported, NeverSupported);
+ AddLUMAFormat(&map, GL_LUMINANCE32F_EXT, true, 32, 0, GL_LUMINANCE, GL_FLOAT, GL_FLOAT, RequireExtAndExt<&Extensions::textureStorageEXT, &Extensions::textureFloatOES>, RequireExt<&Extensions::textureFloatLinearOES>, NeverSupported, NeverSupported, NeverSupported);
+ AddLUMAFormat(&map, GL_LUMINANCE_ALPHA32F_EXT, true, 32, 32, GL_LUMINANCE_ALPHA, GL_FLOAT, GL_FLOAT, RequireExtAndExt<&Extensions::textureStorageEXT, &Extensions::textureFloatOES>, RequireExt<&Extensions::textureFloatLinearOES>, NeverSupported, NeverSupported, NeverSupported);
+
+ // Compressed formats, From ES 3.0.1 spec, table 3.16
+ // | Internal format |W |H |D | BS |CC| SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend
+ AddCompressedFormat(&map, GL_COMPRESSED_R11_EAC, 4, 4, 1, 64, 1, false, ETC2EACSupport<&Extensions::compressedEACR11UnsignedTextureOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_SIGNED_R11_EAC, 4, 4, 1, 64, 1, false, ETC2EACSupport<&Extensions::compressedEACR11SignedTextureOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_RG11_EAC, 4, 4, 1, 128, 2, false, ETC2EACSupport<&Extensions::compressedEACRG11UnsignedTextureOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_SIGNED_RG11_EAC, 4, 4, 1, 128, 2, false, ETC2EACSupport<&Extensions::compressedEACRG11SignedTextureOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_RGB8_ETC2, 4, 4, 1, 64, 3, false, ETC2EACSupport<&Extensions::compressedETC2RGB8TextureOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ETC2, 4, 4, 1, 64, 3, true, ETC2EACSupport<&Extensions::compressedETC2SRGB8TextureOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, 4, 4, 1, 64, 4, false, ETC2EACSupport<&Extensions::compressedETC2PunchthroughARGBA8TextureOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, 4, 4, 1, 64, 4, true, ETC2EACSupport<&Extensions::compressedETC2PunchthroughASRGB8AlphaTextureOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_RGBA8_ETC2_EAC, 4, 4, 1, 128, 4, false, ETC2EACSupport<&Extensions::compressedETC2RGBA8TextureOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, 4, 4, 1, 128, 4, true, ETC2EACSupport<&Extensions::compressedETC2SRGB8Alpha8TextureOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+
+ // From GL_EXT_texture_compression_dxt1
+ // | Internal format |W |H |D | BS |CC| SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend
+ AddCompressedFormat(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4, 1, 64, 3, false, RequireExt<&Extensions::textureCompressionDxt1EXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 4, 4, 1, 64, 4, false, RequireExt<&Extensions::textureCompressionDxt1EXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+
+ // From GL_ANGLE_texture_compression_dxt3
+ AddCompressedFormat(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, 4, 4, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionDxt3ANGLE>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+
+ // From GL_ANGLE_texture_compression_dxt5
+ AddCompressedFormat(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, 4, 4, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionDxt5ANGLE>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+
+ // From GL_OES_compressed_ETC1_RGB8_texture
+ AddCompressedFormat(&map, GL_ETC1_RGB8_OES, 4, 4, 1, 64, 3, false, RequireExt<&Extensions::compressedETC1RGB8TextureOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+
+ // From GL_EXT_texture_compression_s3tc_srgb
+ // | Internal format |W |H |D | BS |CC|SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend
+ AddCompressedFormat(&map, GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, 4, 4, 1, 64, 3, true, RequireExt<&Extensions::textureCompressionS3tcSrgbEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 4, 4, 1, 64, 4, true, RequireExt<&Extensions::textureCompressionS3tcSrgbEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 4, 4, 1, 128, 4, true, RequireExt<&Extensions::textureCompressionS3tcSrgbEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 4, 4, 1, 128, 4, true, RequireExt<&Extensions::textureCompressionS3tcSrgbEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+
+ // From GL_KHR_texture_compression_astc_ldr and KHR_texture_compression_astc_hdr and GL_OES_texture_compression_astc
+ // | Internal format | W | H |D | BS |CC| SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend
+ AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_4x4_KHR, 4, 4, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_5x4_KHR, 5, 4, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_5x5_KHR, 5, 5, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_6x5_KHR, 6, 5, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_6x6_KHR, 6, 6, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_8x5_KHR, 8, 5, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_8x6_KHR, 8, 6, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_8x8_KHR, 8, 8, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_10x5_KHR, 10, 5, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_10x6_KHR, 10, 6, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_10x8_KHR, 10, 8, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_10x10_KHR, 10, 10, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_12x10_KHR, 12, 10, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_12x12_KHR, 12, 12, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+
+ AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, 4, 4, 1, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR, 5, 4, 1, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, 5, 5, 1, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR, 6, 5, 1, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, 6, 6, 1, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, 8, 5, 1, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, 8, 6, 1, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR, 8, 8, 1, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, 10, 5, 1, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR, 10, 6, 1, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, 10, 8, 1, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, 10, 10, 1, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, 12, 10, 1, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, 12, 12, 1, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcLdrKHR>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+
+ AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_3x3x3_OES, 3, 3, 3, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_4x3x3_OES, 4, 3, 3, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_4x4x3_OES, 4, 4, 3, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_4x4x4_OES, 4, 4, 4, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_5x4x4_OES, 5, 4, 4, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_5x5x4_OES, 5, 5, 4, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_5x5x5_OES, 5, 5, 5, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_6x5x5_OES, 6, 5, 5, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_6x6x5_OES, 6, 6, 5, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_RGBA_ASTC_6x6x6_OES, 6, 6, 6, 128, 4, false, RequireExt<&Extensions::textureCompressionAstcOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+
+ AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES, 3, 3, 3, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES, 4, 3, 3, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES, 4, 4, 3, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES, 4, 4, 4, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES, 5, 4, 4, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES, 5, 5, 4, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES, 5, 5, 5, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES, 6, 5, 5, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES, 6, 6, 5, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES, 6, 6, 6, 128, 4, true, RequireExt<&Extensions::textureCompressionAstcOES>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+
+ // From EXT_texture_compression_rgtc
+ // | Internal format | W | H |D | BS |CC| SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend
+ AddCompressedFormat(&map, GL_COMPRESSED_RED_RGTC1_EXT, 4, 4, 1, 64, 1, false, RequireExt<&Extensions::textureCompressionRgtcEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_SIGNED_RED_RGTC1_EXT, 4, 4, 1, 64, 1, false, RequireExt<&Extensions::textureCompressionRgtcEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_RED_GREEN_RGTC2_EXT, 4, 4, 1, 128, 2, false, RequireExt<&Extensions::textureCompressionRgtcEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT, 4, 4, 1, 128, 2, false, RequireExt<&Extensions::textureCompressionRgtcEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+
+ // From EXT_texture_compression_bptc
+ // | Internal format | W | H |D | BS |CC| SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend
+ AddCompressedFormat(&map, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, 4, 4, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionBptcEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT, 4, 4, 1, 128, 4, true, RequireExt<&Extensions::textureCompressionBptcEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT, 4, 4, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionBptcEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT, 4, 4, 1, 128, 4, false, RequireExt<&Extensions::textureCompressionBptcEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+
+ // Paletted formats
+ // | Internal format | | PS | Format | CC | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend
+ AddPalettedFormat(&map, GL_PALETTE4_RGB8_OES, 4, 3, GL_RGB, 3, RequireES1, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddPalettedFormat(&map, GL_PALETTE4_RGBA8_OES, 4, 4, GL_RGBA, 4, RequireES1, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddPalettedFormat(&map, GL_PALETTE4_R5_G6_B5_OES, 4, 2, GL_RGB, 3, RequireES1, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddPalettedFormat(&map, GL_PALETTE4_RGBA4_OES, 4, 2, GL_RGBA, 4, RequireES1, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddPalettedFormat(&map, GL_PALETTE4_RGB5_A1_OES, 4, 2, GL_RGBA, 4, RequireES1, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddPalettedFormat(&map, GL_PALETTE8_RGB8_OES, 8, 3, GL_RGB, 3, RequireES1, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddPalettedFormat(&map, GL_PALETTE8_RGBA8_OES, 8, 4, GL_RGBA, 4, RequireES1, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddPalettedFormat(&map, GL_PALETTE8_R5_G6_B5_OES, 8, 2, GL_RGB, 3, RequireES1, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddPalettedFormat(&map, GL_PALETTE8_RGBA4_OES, 8, 2, GL_RGBA, 4, RequireES1, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddPalettedFormat(&map, GL_PALETTE8_RGB5_A1_OES, 8, 2, GL_RGBA, 4, RequireES1, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+
+ // From GL_IMG_texture_compression_pvrtc
+ // | Internal format | W | H | D | BS |CC| SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend
+ AddCompressedFormat(&map, GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG, 4, 4, 1, 64, 3, false, RequireExt<&Extensions::textureCompressionPvrtcIMG>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG, 8, 4, 1, 64, 3, false, RequireExt<&Extensions::textureCompressionPvrtcIMG>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, 4, 4, 1, 64, 4, false, RequireExt<&Extensions::textureCompressionPvrtcIMG>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG, 8, 4, 1, 64, 4, false, RequireExt<&Extensions::textureCompressionPvrtcIMG>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+
+ // From GL_EXT_pvrtc_sRGB
+ // | Internal format | W | H | D | BS |CC| SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend
+ AddCompressedFormat(&map, GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT, 8, 4, 1, 64, 3, true, RequireExtAndExt<&Extensions::textureCompressionPvrtcIMG, &Extensions::pvrtcSRGBEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT, 4, 4, 1, 64, 3, true, RequireExtAndExt<&Extensions::textureCompressionPvrtcIMG, &Extensions::pvrtcSRGBEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT, 8, 4, 1, 64, 4, true, RequireExtAndExt<&Extensions::textureCompressionPvrtcIMG, &Extensions::pvrtcSRGBEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT, 4, 4, 1, 64, 4, true, RequireExtAndExt<&Extensions::textureCompressionPvrtcIMG, &Extensions::pvrtcSRGBEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+
+ // For STENCIL_INDEX8 we chose a normalized component type for the following reasons:
+ // - 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 |sized|D |S |X | Format | Type | Component type | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend
+ AddDepthStencilFormat(&map, GL_STENCIL_INDEX8, true, 0, 8, 0, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireESOrExt<1, 0, &Extensions::textureStencil8OES>, NeverSupported, RequireESOrExt<1, 0, &Extensions::textureStencil8OES>, RequireES<1, 0>, RequireES<1, 0>);
+
+ // From GL_ANGLE_lossy_etc_decode
+ // | Internal format |W |H |D |BS |CC| SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend
+ AddCompressedFormat(&map, GL_ETC1_RGB8_LOSSY_DECODE_ANGLE, 4, 4, 1, 64, 3, false, RequireExt<&Extensions::lossyEtcDecodeANGLE>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE, 4, 4, 1, 64, 3, false, RequireExt<&Extensions::lossyEtcDecodeANGLE>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE, 4, 4, 1, 64, 3, true, RequireExt<&Extensions::lossyEtcDecodeANGLE>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE, 4, 4, 1, 64, 3, false, RequireExt<&Extensions::lossyEtcDecodeANGLE>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddCompressedFormat(&map, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE, 4, 4, 1, 64, 3, true, RequireExt<&Extensions::lossyEtcDecodeANGLE>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+
+ // From GL_EXT_texture_norm16
+ // | Internal format |sized| R | G | B | A |S | Format | Type | Component type | SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend
+ AddRGBAFormat(&map, GL_R16_EXT, true, 16, 0, 0, 0, 0, GL_RED, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16EXT>, AlwaysSupported, RequireExt<&Extensions::textureNorm16EXT>, RequireExt<&Extensions::textureNorm16EXT>, RequireExt<&Extensions::textureNorm16EXT>);
+ AddRGBAFormat(&map, GL_R16_SNORM_EXT, true, 16, 0, 0, 0, 0, GL_RED, GL_SHORT, GL_SIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16EXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RG16_EXT, true, 16, 16, 0, 0, 0, GL_RG, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16EXT>, AlwaysSupported, RequireExt<&Extensions::textureNorm16EXT>, RequireExt<&Extensions::textureNorm16EXT>, RequireExt<&Extensions::textureNorm16EXT>);
+ AddRGBAFormat(&map, GL_RG16_SNORM_EXT, true, 16, 16, 0, 0, 0, GL_RG, GL_SHORT, GL_SIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16EXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RGB16_EXT, true, 16, 16, 16, 0, 0, GL_RGB, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16EXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RGB16_SNORM_EXT, true, 16, 16, 16, 0, 0, GL_RGB, GL_SHORT, GL_SIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16EXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RGBA16_EXT, true, 16, 16, 16, 16, 0, GL_RGBA, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16EXT>, AlwaysSupported, RequireExt<&Extensions::textureNorm16EXT>, RequireExt<&Extensions::textureNorm16EXT>, RequireExt<&Extensions::textureNorm16EXT>);
+ AddRGBAFormat(&map, GL_RGBA16_SNORM_EXT, true, 16, 16, 16, 16, 0, GL_RGBA, GL_SHORT, GL_SIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16EXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+
+ // From EXT_texture_sRGB_R8
+ // | Internal format |sized| R | G | B | A |S | Format | Type | Component type | SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend
+ AddRGBAFormat(&map, GL_SR8_EXT, true, 8, 0, 0, 0, 0, GL_RED, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, true, RequireExt<&Extensions::textureSRGBR8EXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+
+ // From EXT_texture_sRGB_RG8
+ // | Internal format |sized| R | G | B | A |S | Format | Type | Component type | SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend
+ AddRGBAFormat(&map, GL_SRG8_EXT, true, 8, 8, 0, 0, 0, GL_RG, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, true, RequireExt<&Extensions::textureSRGBRG8EXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+
+ // From GL_EXT_texture_type_2_10_10_10_REV
+ // GL_RGB10_UNORM_ANGLEX is never used directly but needs to be in the list of all sized internal formats so that the backends can determine support.
+ // | Internal format |sized| R | G | B | A |S |X | Format | Type | Component type | SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend
+ AddRGBAXFormat(&map, GL_RGB10_UNORM_ANGLEX, true, FB<10, 10, 10, 0, 0, 2>(), GL_RGB, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_NORMALIZED, false, NeverSupported, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+
+ // Unsized formats
+ // | Internal format |sized | R | G | B | A |S |X | Format | Type | Component type | SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend
+ AddRGBAXFormat(&map, GL_RED, false, FB< 8, 0, 0, 0, 0, 0>(), GL_RED, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureRgEXT>, AlwaysSupported, RequireExt<&Extensions::textureRgEXT>, NeverSupported, NeverSupported);
+ AddRGBAXFormat(&map, GL_RED, false, FB< 8, 0, 0, 0, 0, 0>(), GL_RED, GL_BYTE, GL_SIGNED_NORMALIZED, false, NeverSupported, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAXFormat(&map, GL_RED, false, FB<16, 0, 0, 0, 0, 0>(), GL_RED, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16EXT>, AlwaysSupported, RequireExt<&Extensions::textureNorm16EXT>, NeverSupported, NeverSupported);
+ AddRGBAXFormat(&map, GL_RG, false, FB< 8, 8, 0, 0, 0, 0>(), GL_RG, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureRgEXT>, AlwaysSupported, RequireExt<&Extensions::textureRgEXT>, NeverSupported, NeverSupported);
+ AddRGBAXFormat(&map, GL_RG, false, FB< 8, 8, 0, 0, 0, 0>(), GL_RG, GL_BYTE, GL_SIGNED_NORMALIZED, false, NeverSupported, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAXFormat(&map, GL_RG, false, FB<16, 16, 0, 0, 0, 0>(), GL_RG, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16EXT>, AlwaysSupported, RequireExt<&Extensions::textureNorm16EXT>, NeverSupported, NeverSupported);
+ AddRGBAXFormat(&map, GL_RGB, false, FB< 8, 8, 8, 0, 0, 0>(), GL_RGB, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, RequireESOrExt<2, 0, &Extensions::framebufferObjectOES>, NeverSupported, NeverSupported);
+ AddRGBAXFormat(&map, GL_RGB, false, FB< 5, 6, 5, 0, 0, 0>(), GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, RequireESOrExt<2, 0, &Extensions::framebufferObjectOES>, NeverSupported, NeverSupported);
+ AddRGBAXFormat(&map, GL_RGB, false, FB< 8, 8, 8, 0, 0, 0>(), GL_RGB, GL_BYTE, GL_SIGNED_NORMALIZED, false, NeverSupported, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAXFormat(&map, GL_RGB, false, FB<10, 10, 10, 0, 0, 2>(), GL_RGB, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureType2101010REVEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAXFormat(&map, GL_RGBA, false, FB< 4, 4, 4, 4, 0, 0>(), GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, RequireESOrExt<2, 0, &Extensions::framebufferObjectOES>, NeverSupported, NeverSupported);
+ AddRGBAXFormat(&map, GL_RGBA, false, FB< 5, 5, 5, 1, 0, 0>(), GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, RequireESOrExt<2, 0, &Extensions::framebufferObjectOES>, NeverSupported, NeverSupported);
+ AddRGBAXFormat(&map, GL_RGBA, false, FB< 8, 8, 8, 8, 0, 0>(), GL_RGBA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, AlwaysSupported, AlwaysSupported, RequireESOrExt<2, 0, &Extensions::framebufferObjectOES>, NeverSupported, NeverSupported);
+ AddRGBAXFormat(&map, GL_RGBA, false, FB<16, 16, 16, 16, 0, 0>(), GL_RGBA, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureNorm16EXT>, AlwaysSupported, RequireExt<&Extensions::textureNorm16EXT>, NeverSupported, NeverSupported);
+ AddRGBAXFormat(&map, GL_RGBA, false, FB<10, 10, 10, 2, 0, 0>(), GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureType2101010REVEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAXFormat(&map, GL_RGBA, false, FB< 8, 8, 8, 8, 0, 0>(), GL_RGBA, GL_BYTE, GL_SIGNED_NORMALIZED, false, NeverSupported, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAXFormat(&map, GL_SRGB, false, FB< 8, 8, 8, 0, 0, 0>(), GL_SRGB, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, true, RequireExt<&Extensions::sRGBEXT>, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAXFormat(&map, GL_SRGB_ALPHA_EXT, false, FB< 8, 8, 8, 8, 0, 0>(), GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, true, RequireExt<&Extensions::sRGBEXT>, AlwaysSupported, RequireExt<&Extensions::sRGBEXT>, NeverSupported, NeverSupported);
+#if (defined(ANGLE_PLATFORM_IOS) && !defined(ANGLE_PLATFORM_MACCATALYST)) || (defined(ANGLE_PLATFORM_MACCATALYST) && defined(ANGLE_CPU_ARM64))
+ angle::SystemInfo info;
+ if (angle::GetSystemInfo(&info))
+ {
+ if (info.needsEAGLOnMac)
+ {
+ // Using OpenGLES.framework.
+ AddRGBAFormat(&map, GL_BGRA_EXT, false, 8, 8, 8, 8, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireES<2, 0>, AlwaysSupported, RequireES<2, 0>, NeverSupported, NeverSupported);
+ }
+ else
+ {
+ // Using OpenGL.framework.
+ AddRGBAFormat(&map, GL_BGRA_EXT, false, 8, 8, 8, 8, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureFormatBGRA8888EXT>, AlwaysSupported, RequireExt<&Extensions::textureFormatBGRA8888EXT>, NeverSupported, NeverSupported);
+ }
+ }
+#else
+ AddRGBAFormat(&map, GL_BGRA_EXT, false, 8, 8, 8, 8, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::textureFormatBGRA8888EXT>, AlwaysSupported, RequireExt<&Extensions::textureFormatBGRA8888EXT>, NeverSupported, NeverSupported);
+#endif
+
+ // Unsized integer formats
+ // |Internal format |sized | R | G | B | A |S | Format | Type | Component type | SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend
+ AddRGBAFormat(&map, GL_RED_INTEGER, false, 8, 0, 0, 0, 0, GL_RED_INTEGER, GL_BYTE, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RED_INTEGER, false, 8, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RED_INTEGER, false, 16, 0, 0, 0, 0, GL_RED_INTEGER, GL_SHORT, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RED_INTEGER, false, 16, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RED_INTEGER, false, 32, 0, 0, 0, 0, GL_RED_INTEGER, GL_INT, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RED_INTEGER, false, 32, 0, 0, 0, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RG_INTEGER, false, 8, 8, 0, 0, 0, GL_RG_INTEGER, GL_BYTE, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RG_INTEGER, false, 8, 8, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RG_INTEGER, false, 16, 16, 0, 0, 0, GL_RG_INTEGER, GL_SHORT, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RG_INTEGER, false, 16, 16, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RG_INTEGER, false, 32, 32, 0, 0, 0, GL_RG_INTEGER, GL_INT, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RG_INTEGER, false, 32, 32, 0, 0, 0, GL_RG_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RGB_INTEGER, false, 8, 8, 8, 0, 0, GL_RGB_INTEGER, GL_BYTE, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RGB_INTEGER, false, 8, 8, 8, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RGB_INTEGER, false, 16, 16, 16, 0, 0, GL_RGB_INTEGER, GL_SHORT, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RGB_INTEGER, false, 16, 16, 16, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RGB_INTEGER, false, 32, 32, 32, 0, 0, GL_RGB_INTEGER, GL_INT, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RGB_INTEGER, false, 32, 32, 32, 0, 0, GL_RGB_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RGBA_INTEGER, false, 8, 8, 8, 8, 0, GL_RGBA_INTEGER, GL_BYTE, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RGBA_INTEGER, false, 8, 8, 8, 8, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RGBA_INTEGER, false, 16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_SHORT, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RGBA_INTEGER, false, 16, 16, 16, 16, 0, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RGBA_INTEGER, false, 32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_INT, GL_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RGBA_INTEGER, false, 32, 32, 32, 32, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RGBA_INTEGER, false, 10, 10, 10, 2, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_INT, false, RequireES<3, 0>, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+
+ // Unsized floating point formats
+ // |Internal format |sized | R | G | B | A |S | Format | Type | Comp | SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend
+ AddRGBAFormat(&map, GL_RED, false, 16, 0, 0, 0, 0, GL_RED, GL_HALF_FLOAT, GL_FLOAT, false, NeverSupported, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RG, false, 16, 16, 0, 0, 0, GL_RG, GL_HALF_FLOAT, GL_FLOAT, false, NeverSupported, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RGB, false, 16, 16, 16, 0, 0, GL_RGB, GL_HALF_FLOAT, GL_FLOAT, false, NeverSupported, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RGBA, false, 16, 16, 16, 16, 0, GL_RGBA, GL_HALF_FLOAT, GL_FLOAT, false, NeverSupported, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RED, false, 16, 0, 0, 0, 0, GL_RED, GL_HALF_FLOAT_OES, GL_FLOAT, false, RequireExtAndExt<&Extensions::textureHalfFloatOES, &Extensions::textureRgEXT>, RequireExt<&Extensions::textureHalfFloatLinearOES>, AlwaysSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RG, false, 16, 16, 0, 0, 0, GL_RG, GL_HALF_FLOAT_OES, GL_FLOAT, false, RequireExtAndExt<&Extensions::textureHalfFloatOES, &Extensions::textureRgEXT>, RequireExt<&Extensions::textureHalfFloatLinearOES>, AlwaysSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RGB, false, 16, 16, 16, 0, 0, GL_RGB, GL_HALF_FLOAT_OES, GL_FLOAT, false, RequireExt<&Extensions::textureHalfFloatOES>, RequireExt<&Extensions::textureHalfFloatLinearOES>, RequireExt<&Extensions::colorBufferHalfFloatEXT>, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RGBA, false, 16, 16, 16, 16, 0, GL_RGBA, GL_HALF_FLOAT_OES, GL_FLOAT, false, RequireExt<&Extensions::textureHalfFloatOES>, RequireExt<&Extensions::textureHalfFloatLinearOES>, RequireExt<&Extensions::colorBufferHalfFloatEXT>, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RED, false, 32, 0, 0, 0, 0, GL_RED, GL_FLOAT, GL_FLOAT, false, RequireExtAndExt<&Extensions::textureFloatOES, &Extensions::textureRgEXT>, RequireExt<&Extensions::textureFloatLinearOES>, AlwaysSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RG, false, 32, 32, 0, 0, 0, GL_RG, GL_FLOAT, GL_FLOAT, false, RequireExtAndExt<&Extensions::textureFloatOES, &Extensions::textureRgEXT>, RequireExt<&Extensions::textureFloatLinearOES>, AlwaysSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RGB, false, 32, 32, 32, 0, 0, GL_RGB, GL_FLOAT, GL_FLOAT, false, RequireExt<&Extensions::textureFloatOES>, RequireExt<&Extensions::textureFloatLinearOES>, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RGB, false, 9, 9, 9, 0, 5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, GL_FLOAT, false, NeverSupported, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RGB, false, 11, 11, 10, 0, 0, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, GL_FLOAT, false, NeverSupported, NeverSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddRGBAFormat(&map, GL_RGBA, false, 32, 32, 32, 32, 0, GL_RGBA, GL_FLOAT, GL_FLOAT, false, RequireExt<&Extensions::textureFloatOES>, RequireExt<&Extensions::textureFloatLinearOES>, NeverSupported, NeverSupported, NeverSupported);
+
+ // Unsized luminance alpha formats
+ // | Internal format |sized | L | A | Format | Type | Component type | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend
+ AddLUMAFormat(&map, GL_ALPHA, false, 0, 8, GL_ALPHA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, AlwaysSupported, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddLUMAFormat(&map, GL_LUMINANCE, false, 8, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, AlwaysSupported, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddLUMAFormat(&map, GL_LUMINANCE_ALPHA, false, 8, 8, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, AlwaysSupported, AlwaysSupported, NeverSupported, NeverSupported, NeverSupported);
+ AddLUMAFormat(&map, GL_ALPHA, false, 0, 16, GL_ALPHA, GL_HALF_FLOAT_OES, GL_FLOAT, RequireExt<&Extensions::textureHalfFloatOES>, RequireExt<&Extensions::textureHalfFloatLinearOES>, NeverSupported, NeverSupported, NeverSupported);
+ AddLUMAFormat(&map, GL_LUMINANCE, false, 16, 0, GL_LUMINANCE, GL_HALF_FLOAT_OES, GL_FLOAT, RequireExt<&Extensions::textureHalfFloatOES>, RequireExt<&Extensions::textureHalfFloatLinearOES>, NeverSupported, NeverSupported, NeverSupported);
+ AddLUMAFormat(&map, GL_LUMINANCE_ALPHA, false, 16, 16, GL_LUMINANCE_ALPHA, GL_HALF_FLOAT_OES, GL_FLOAT, RequireExt<&Extensions::textureHalfFloatOES>, RequireExt<&Extensions::textureHalfFloatLinearOES>, NeverSupported, NeverSupported, NeverSupported);
+ AddLUMAFormat(&map, GL_ALPHA, false, 0, 32, GL_ALPHA, GL_FLOAT, GL_FLOAT, RequireExt<&Extensions::textureFloatOES>, RequireExt<&Extensions::textureFloatLinearOES>, NeverSupported, NeverSupported, NeverSupported);
+ AddLUMAFormat(&map, GL_LUMINANCE, false, 32, 0, GL_LUMINANCE, GL_FLOAT, GL_FLOAT, RequireExt<&Extensions::textureFloatOES>, RequireExt<&Extensions::textureFloatLinearOES>, NeverSupported, NeverSupported, NeverSupported);
+ AddLUMAFormat(&map, GL_LUMINANCE_ALPHA, false, 32, 32, GL_LUMINANCE_ALPHA, GL_FLOAT, GL_FLOAT, RequireExt<&Extensions::textureFloatOES>, RequireExt<&Extensions::textureFloatLinearOES>, NeverSupported, NeverSupported, NeverSupported);
+
+ // Unsized depth stencil formats
+ // | Internal format |sized | D |S | X | Format | Type | Component type | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend
+ AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT, false, 16, 0, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, GL_UNSIGNED_NORMALIZED, RequireES<1, 0>, AlwaysSupported, RequireExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES>, RequireExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES>, RequireExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES>);
+ AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT, false, 24, 0, 8, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, GL_UNSIGNED_NORMALIZED, RequireES<1, 0>, AlwaysSupported, RequireExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES>, RequireExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES>, RequireExtOrExt<&Extensions::depthTextureANGLE, &Extensions::depthTextureOES>);
+ AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT, false, 32, 0, 0, GL_DEPTH_COMPONENT, GL_FLOAT, GL_FLOAT, RequireES<1, 0>, AlwaysSupported, RequireES<1, 0>, RequireES<1, 0>, RequireES<1, 0>);
+ AddDepthStencilFormat(&map, GL_DEPTH_COMPONENT, false, 24, 8, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT_24_8, GL_UNSIGNED_NORMALIZED, RequireESOrExt<3, 0, &Extensions::packedDepthStencilOES>, AlwaysSupported, RequireExtAndExt<&Extensions::packedDepthStencilOES, &Extensions::depthTextureANGLE>, RequireExtAndExt<&Extensions::packedDepthStencilOES, &Extensions::depthTextureANGLE>, RequireExtAndExt<&Extensions::packedDepthStencilOES, &Extensions::depthTextureANGLE>);
+ AddDepthStencilFormat(&map, GL_DEPTH_STENCIL, false, 24, 8, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, GL_UNSIGNED_NORMALIZED, RequireESOrExt<3, 0, &Extensions::packedDepthStencilOES>, AlwaysSupported, RequireExtAndExt<&Extensions::packedDepthStencilOES, &Extensions::depthTextureANGLE>, RequireExtAndExt<&Extensions::packedDepthStencilOES, &Extensions::depthTextureANGLE>, RequireExtAndExt<&Extensions::packedDepthStencilOES, &Extensions::depthTextureANGLE>);
+ AddDepthStencilFormat(&map, GL_DEPTH_STENCIL, false, 32, 8, 24, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_FLOAT, RequireESOrExt<3, 0, &Extensions::packedDepthStencilOES>, AlwaysSupported, RequireExt<&Extensions::packedDepthStencilOES>, RequireExt<&Extensions::packedDepthStencilOES>, RequireExt<&Extensions::packedDepthStencilOES>);
+ AddDepthStencilFormat(&map, GL_STENCIL, false, 0, 8, 0, GL_STENCIL, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireES<1, 0>, NeverSupported , RequireES<1, 0>, RequireES<1, 0>, RequireES<1, 0>);
+ AddDepthStencilFormat(&map, GL_STENCIL_INDEX, false, 0, 8, 0, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, RequireES<3, 1>, NeverSupported , RequireES<3, 1>, RequireES<3, 1>, RequireES<3, 1>);
+
+ // Non-standard YUV formats
+ // | Internal format | sized | Cr | Y | Cb | A | S | Format | Type | Comp | SRGB | Texture supported | Filterable | Texture attachment | Renderbuffer | Blend
+ AddYUVFormat(&map, GL_G8_B8R8_2PLANE_420_UNORM_ANGLE, true, 8, 8, 8, 0, 0, GL_G8_B8R8_2PLANE_420_UNORM_ANGLE, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::yuvInternalFormatANGLE>, RequireExt<&Extensions::yuvInternalFormatANGLE>, RequireExt<&Extensions::yuvInternalFormatANGLE>, NeverSupported, NeverSupported);
+ AddYUVFormat(&map, GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE, true, 8, 8, 8, 0, 0, GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE, GL_UNSIGNED_BYTE, GL_UNSIGNED_NORMALIZED, false, RequireExt<&Extensions::yuvInternalFormatANGLE>, RequireExt<&Extensions::yuvInternalFormatANGLE>, RequireExt<&Extensions::yuvInternalFormatANGLE>, NeverSupported, NeverSupported);
+
+#if defined(ANGLE_PLATFORM_LINUX)
+ // From GL_OES_required_internalformat
+ // The |shared| bit shouldn't be 2. But given this hits assertion when bits
+ // are checked, it's fine to have this bit set as 2 as a workaround.
+ AddRGBAFormat(&map, GL_RGB10_EXT, true, 10, 10, 10, 0, 2, GL_RGB, GL_UNSIGNED_INT_2_10_10_10_REV, GL_UNSIGNED_NORMALIZED, false, RequireES<1, 0>, NeverSupported, RequireES<1, 0>, RequireES<1, 0>, NeverSupported);
+#endif
+ // clang-format on
+
+ return map;
+}
+
+const InternalFormatInfoMap &GetInternalFormatMap()
+{
+ static const angle::base::NoDestructor<InternalFormatInfoMap> formatMap(
+ BuildInternalFormatInfoMap());
+ return *formatMap;
+}
+
+int GetAndroidHardwareBufferFormatFromChannelSizes(const egl::AttributeMap &attribMap)
+{
+ // Retrieve channel size from attribute map. The default value should be 0, per spec.
+ GLuint redSize = static_cast<GLuint>(attribMap.getAsInt(EGL_RED_SIZE, 0));
+ GLuint greenSize = static_cast<GLuint>(attribMap.getAsInt(EGL_GREEN_SIZE, 0));
+ GLuint blueSize = static_cast<GLuint>(attribMap.getAsInt(EGL_BLUE_SIZE, 0));
+ GLuint alphaSize = static_cast<GLuint>(attribMap.getAsInt(EGL_ALPHA_SIZE, 0));
+
+ GLenum glInternalFormat = 0;
+ for (GLenum sizedInternalFormat : angle::android::kSupportedSizedInternalFormats)
+ {
+ const gl::InternalFormat &internalFormat = GetSizedInternalFormatInfo(sizedInternalFormat);
+ ASSERT(internalFormat.internalFormat != GL_NONE && internalFormat.sized);
+
+ if (internalFormat.isChannelSizeCompatible(redSize, greenSize, blueSize, alphaSize))
+ {
+ glInternalFormat = sizedInternalFormat;
+ break;
+ }
+ }
+
+ return (glInternalFormat != 0)
+ ? angle::android::GLInternalFormatToNativePixelFormat(glInternalFormat)
+ : 0;
+}
+
+GLenum GetConfigColorBufferFormat(const egl::Config *config)
+{
+ GLenum componentType = GL_NONE;
+ switch (config->colorComponentType)
+ {
+ case EGL_COLOR_COMPONENT_TYPE_FIXED_EXT:
+ componentType = GL_UNSIGNED_NORMALIZED;
+ break;
+ case EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT:
+ componentType = GL_FLOAT;
+ break;
+ default:
+ UNREACHABLE();
+ return GL_NONE;
+ }
+
+ GLenum colorEncoding = GL_LINEAR;
+
+ for (GLenum sizedInternalFormat : GetAllSizedInternalFormats())
+ {
+ const gl::InternalFormat &internalFormat = GetSizedInternalFormatInfo(sizedInternalFormat);
+
+ if (internalFormat.componentType == componentType &&
+ internalFormat.colorEncoding == colorEncoding &&
+ internalFormat.isChannelSizeCompatible(config->redSize, config->greenSize,
+ config->blueSize, config->alphaSize))
+ {
+ return sizedInternalFormat;
+ }
+ }
+
+ // Only expect to get here if there is no color bits in the config
+ ASSERT(config->redSize == 0 && config->greenSize == 0 && config->blueSize == 0 &&
+ config->alphaSize == 0);
+ return GL_NONE;
+}
+
+GLenum GetConfigDepthStencilBufferFormat(const egl::Config *config)
+{
+ GLenum componentType = GL_UNSIGNED_NORMALIZED;
+
+ for (GLenum sizedInternalFormat : GetAllSizedInternalFormats())
+ {
+ const gl::InternalFormat &internalFormat = GetSizedInternalFormatInfo(sizedInternalFormat);
+
+ if (internalFormat.componentType == componentType &&
+ static_cast<EGLint>(internalFormat.depthBits) == config->depthSize &&
+ static_cast<EGLint>(internalFormat.stencilBits) == config->stencilSize)
+ {
+ return sizedInternalFormat;
+ }
+ }
+
+ // Only expect to get here if there is no depth or stencil bits in the config
+ ASSERT(config->depthSize == 0 && config->stencilSize == 0);
+ return GL_NONE;
+}
+
+static FormatSet BuildAllSizedInternalFormatSet()
+{
+ FormatSet result;
+
+ for (const auto &internalFormat : GetInternalFormatMap())
+ {
+ for (const auto &type : internalFormat.second)
+ {
+ if (type.second.sized)
+ {
+ // TODO(jmadill): Fix this hack.
+ if (internalFormat.first == GL_BGR565_ANGLEX)
+ continue;
+
+ result.insert(internalFormat.first);
+ }
+ }
+ }
+
+ return result;
+}
+
+uint32_t GetPackedTypeInfo(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ case GL_BYTE:
+ {
+ static constexpr uint32_t kPacked = PackTypeInfo(1, false);
+ return kPacked;
+ }
+ case GL_UNSIGNED_SHORT:
+ case GL_SHORT:
+ case GL_HALF_FLOAT:
+ case GL_HALF_FLOAT_OES:
+ {
+ static constexpr uint32_t kPacked = PackTypeInfo(2, false);
+ return kPacked;
+ }
+ case GL_UNSIGNED_INT:
+ case GL_INT:
+ case GL_FLOAT:
+ {
+ static constexpr uint32_t kPacked = PackTypeInfo(4, false);
+ return kPacked;
+ }
+ case GL_UNSIGNED_SHORT_5_6_5:
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
+ case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
+ {
+ static constexpr uint32_t kPacked = PackTypeInfo(2, true);
+ return kPacked;
+ }
+ case GL_UNSIGNED_INT_2_10_10_10_REV:
+ case GL_UNSIGNED_INT_24_8:
+ case GL_UNSIGNED_INT_10F_11F_11F_REV:
+ case GL_UNSIGNED_INT_5_9_9_9_REV:
+ {
+ ASSERT(GL_UNSIGNED_INT_24_8_OES == GL_UNSIGNED_INT_24_8);
+ static constexpr uint32_t kPacked = PackTypeInfo(4, true);
+ return kPacked;
+ }
+ case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
+ {
+ static constexpr uint32_t kPacked = PackTypeInfo(8, true);
+ return kPacked;
+ }
+ default:
+ {
+ return 0;
+ }
+ }
+}
+
+const InternalFormat &GetSizedInternalFormatInfo(GLenum internalFormat)
+{
+ static const InternalFormat defaultInternalFormat;
+ const InternalFormatInfoMap &formatMap = GetInternalFormatMap();
+ auto iter = formatMap.find(internalFormat);
+
+ // Sized internal formats only have one type per entry
+ if (iter == formatMap.end() || iter->second.size() != 1)
+ {
+ return defaultInternalFormat;
+ }
+
+ const InternalFormat &internalFormatInfo = iter->second.begin()->second;
+ if (!internalFormatInfo.sized)
+ {
+ return defaultInternalFormat;
+ }
+
+ return internalFormatInfo;
+}
+
+const InternalFormat &GetInternalFormatInfo(GLenum internalFormat, GLenum type)
+{
+ static const InternalFormat defaultInternalFormat;
+ const InternalFormatInfoMap &formatMap = GetInternalFormatMap();
+
+ auto internalFormatIter = formatMap.find(internalFormat);
+ if (internalFormatIter == formatMap.end())
+ {
+ return defaultInternalFormat;
+ }
+
+ // If the internal format is sized, simply return it without the type check.
+ if (internalFormatIter->second.size() == 1 && internalFormatIter->second.begin()->second.sized)
+ {
+ return internalFormatIter->second.begin()->second;
+ }
+
+ auto typeIter = internalFormatIter->second.find(type);
+ if (typeIter == internalFormatIter->second.end())
+ {
+ return defaultInternalFormat;
+ }
+
+ return typeIter->second;
+}
+
+GLuint InternalFormat::computePixelBytes(GLenum formatType) const
+{
+ const auto &typeInfo = GetTypeInfo(formatType);
+ GLuint components = typeInfo.specialInterpretation ? 1u : componentCount;
+ return components * typeInfo.bytes;
+}
+
+bool InternalFormat::computeBufferRowLength(uint32_t width, uint32_t *resultOut) const
+{
+ CheckedNumeric<GLuint> checkedWidth(width);
+
+ if (compressed)
+ {
+ angle::CheckedNumeric<uint32_t> checkedRowLength =
+ rx::CheckedRoundUp<uint32_t>(width, compressedBlockWidth);
+
+ return CheckedMathResult(checkedRowLength, resultOut);
+ }
+
+ return CheckedMathResult(checkedWidth, resultOut);
+}
+
+bool InternalFormat::computeBufferImageHeight(uint32_t height, uint32_t *resultOut) const
+{
+ CheckedNumeric<GLuint> checkedHeight(height);
+
+ if (compressed)
+ {
+ angle::CheckedNumeric<uint32_t> checkedImageHeight =
+ rx::CheckedRoundUp<uint32_t>(height, compressedBlockHeight);
+
+ return CheckedMathResult(checkedImageHeight, resultOut);
+ }
+
+ return CheckedMathResult(checkedHeight, resultOut);
+}
+
+bool InternalFormat::computePalettedImageRowPitch(GLsizei width, GLuint *resultOut) const
+{
+ ASSERT(paletted);
+ switch (paletteBits)
+ {
+ case 4:
+ *resultOut = (width + 1) / 2;
+ return true;
+ case 8:
+ *resultOut = width;
+ return true;
+ default:
+ UNREACHABLE();
+ return false;
+ }
+}
+
+bool InternalFormat::computeRowPitch(GLenum formatType,
+ GLsizei width,
+ GLint alignment,
+ GLint rowLength,
+ GLuint *resultOut) const
+{
+ if (paletted)
+ {
+ return computePalettedImageRowPitch(width, resultOut);
+ }
+
+ // Compressed images do not use pack/unpack parameters (rowLength).
+ if (compressed)
+ {
+ return computeCompressedImageSize(Extents(width, 1, 1), resultOut);
+ }
+
+ CheckedNumeric<GLuint> checkedWidth(rowLength > 0 ? rowLength : width);
+ CheckedNumeric<GLuint> checkedRowBytes = checkedWidth * computePixelBytes(formatType);
+
+ ASSERT(alignment > 0 && isPow2(alignment));
+ CheckedNumeric<GLuint> checkedAlignment(alignment);
+ auto aligned = rx::roundUp(checkedRowBytes, checkedAlignment);
+ return CheckedMathResult(aligned, resultOut);
+}
+
+bool InternalFormat::computeDepthPitch(GLsizei height,
+ GLint imageHeight,
+ GLuint rowPitch,
+ GLuint *resultOut) const
+{
+ // Compressed images do not use pack/unpack parameters (imageHeight).
+ CheckedNumeric<GLuint> pixelsHeight(!compressed && (imageHeight > 0)
+ ? static_cast<GLuint>(imageHeight)
+ : static_cast<GLuint>(height));
+
+ CheckedNumeric<GLuint> rowCount;
+ if (compressed)
+ {
+ CheckedNumeric<GLuint> checkedBlockHeight(compressedBlockHeight);
+ rowCount = (pixelsHeight + checkedBlockHeight - 1u) / checkedBlockHeight;
+ }
+ else
+ {
+ rowCount = pixelsHeight;
+ }
+
+ CheckedNumeric<GLuint> checkedRowPitch(rowPitch);
+
+ return CheckedMathResult(checkedRowPitch * rowCount, resultOut);
+}
+
+bool InternalFormat::computeDepthPitch(GLenum formatType,
+ GLsizei width,
+ GLsizei height,
+ GLint alignment,
+ GLint rowLength,
+ GLint imageHeight,
+ GLuint *resultOut) const
+{
+ GLuint rowPitch = 0;
+ if (!computeRowPitch(formatType, width, alignment, rowLength, &rowPitch))
+ {
+ return false;
+ }
+ return computeDepthPitch(height, imageHeight, rowPitch, resultOut);
+}
+
+bool InternalFormat::computeCompressedImageSize(const Extents &size, GLuint *resultOut) const
+{
+ CheckedNumeric<GLuint> checkedWidth(size.width);
+ CheckedNumeric<GLuint> checkedHeight(size.height);
+ CheckedNumeric<GLuint> checkedDepth(size.depth);
+
+ if (paletted)
+ {
+ ASSERT(!compressed);
+
+ GLuint paletteSize = 1 << paletteBits;
+ GLuint paletteBytes = paletteSize * pixelBytes;
+
+ GLuint rowPitch;
+ if (!computePalettedImageRowPitch(size.width, &rowPitch))
+ {
+ return false;
+ }
+
+ if (size.depth != 1)
+ {
+ return false;
+ }
+
+ CheckedNumeric<GLuint> checkedPaletteBytes(paletteBytes);
+ CheckedNumeric<GLuint> checkedRowPitch(rowPitch);
+
+ return CheckedMathResult(checkedPaletteBytes + checkedRowPitch * checkedHeight, resultOut);
+ }
+
+ CheckedNumeric<GLuint> checkedBlockWidth(compressedBlockWidth);
+ CheckedNumeric<GLuint> checkedBlockHeight(compressedBlockHeight);
+ GLuint minBlockWidth, minBlockHeight;
+ std::tie(minBlockWidth, minBlockHeight) = getCompressedImageMinBlocks();
+
+ ASSERT(compressed);
+ auto numBlocksWide = (checkedWidth + checkedBlockWidth - 1u) / checkedBlockWidth;
+ auto numBlocksHigh = (checkedHeight + checkedBlockHeight - 1u) / checkedBlockHeight;
+ if (numBlocksWide.IsValid() && numBlocksWide.ValueOrDie() < minBlockWidth)
+ numBlocksWide = minBlockWidth;
+ if (numBlocksHigh.IsValid() && numBlocksHigh.ValueOrDie() < minBlockHeight)
+ numBlocksHigh = minBlockHeight;
+ auto bytes = numBlocksWide * numBlocksHigh * pixelBytes * checkedDepth;
+ return CheckedMathResult(bytes, resultOut);
+}
+
+std::pair<GLuint, GLuint> InternalFormat::getCompressedImageMinBlocks() const
+{
+ GLuint minBlockWidth = 0;
+ GLuint minBlockHeight = 0;
+
+ // Per the specification, a PVRTC block needs information from the 3 nearest blocks.
+ // GL_IMG_texture_compression_pvrtc specifies the minimum size requirement in pixels, but
+ // ANGLE's texture tables are written in terms of blocks. The 4BPP formats use 4x4 blocks, and
+ // the 2BPP formats, 8x4 blocks. Therefore, both kinds of formats require a minimum of 2x2
+ // blocks.
+ switch (internalFormat)
+ {
+ case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
+ case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
+ case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
+ case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
+ case GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT:
+ case GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT:
+ minBlockWidth = 2;
+ minBlockHeight = 2;
+ break;
+
+ default:
+ break;
+ }
+
+ return std::make_pair(minBlockWidth, minBlockHeight);
+}
+
+bool InternalFormat::computeSkipBytes(GLenum formatType,
+ GLuint rowPitch,
+ GLuint depthPitch,
+ const PixelStoreStateBase &state,
+ bool is3D,
+ GLuint *resultOut) const
+{
+ CheckedNumeric<GLuint> checkedRowPitch(rowPitch);
+ CheckedNumeric<GLuint> checkedDepthPitch(depthPitch);
+ 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(computePixelBytes(formatType));
+ auto checkedSkipImagesBytes = checkedSkipImages * checkedDepthPitch;
+ if (!is3D)
+ {
+ checkedSkipImagesBytes = 0;
+ }
+ auto skipBytes = checkedSkipImagesBytes + checkedSkipRows * checkedRowPitch +
+ checkedSkipPixels * checkedPixelBytes;
+ return CheckedMathResult(skipBytes, resultOut);
+}
+
+bool InternalFormat::computePackUnpackEndByte(GLenum formatType,
+ const Extents &size,
+ const PixelStoreStateBase &state,
+ bool is3D,
+ GLuint *resultOut) const
+{
+ GLuint rowPitch = 0;
+ if (!computeRowPitch(formatType, size.width, state.alignment, state.rowLength, &rowPitch))
+ {
+ return false;
+ }
+
+ GLuint depthPitch = 0;
+ if (is3D && !computeDepthPitch(size.height, state.imageHeight, rowPitch, &depthPitch))
+ {
+ return false;
+ }
+
+ CheckedNumeric<GLuint> checkedCopyBytes(0);
+ if (compressed)
+ {
+ GLuint copyBytes = 0;
+ if (!computeCompressedImageSize(size, &copyBytes))
+ {
+ return false;
+ }
+ checkedCopyBytes = copyBytes;
+ }
+ else if (size.height != 0 && (!is3D || size.depth != 0))
+ {
+ CheckedNumeric<GLuint> bytes = computePixelBytes(formatType);
+ checkedCopyBytes += size.width * bytes;
+
+ CheckedNumeric<GLuint> heightMinusOne = size.height - 1;
+ checkedCopyBytes += heightMinusOne * rowPitch;
+
+ if (is3D)
+ {
+ CheckedNumeric<GLuint> depthMinusOne = size.depth - 1;
+ checkedCopyBytes += depthMinusOne * depthPitch;
+ }
+ }
+
+ GLuint skipBytes = 0;
+ if (!computeSkipBytes(formatType, rowPitch, depthPitch, state, is3D, &skipBytes))
+ {
+ return false;
+ }
+
+ CheckedNumeric<GLuint> endByte = checkedCopyBytes + CheckedNumeric<GLuint>(skipBytes);
+
+ return CheckedMathResult(endByte, resultOut);
+}
+
+GLenum GetUnsizedFormat(GLenum internalFormat)
+{
+ auto sizedFormatInfo = GetSizedInternalFormatInfo(internalFormat);
+ if (sizedFormatInfo.internalFormat != GL_NONE)
+ {
+ return sizedFormatInfo.format;
+ }
+
+ return internalFormat;
+}
+
+bool CompressedFormatRequiresWholeImage(GLenum internalFormat)
+{
+ // List of compressed texture format that require that the sub-image size is equal to texture's
+ // respective mip level's size
+ return IsPVRTC1Format(internalFormat);
+}
+
+void MaybeOverrideLuminance(GLenum &format, GLenum &type, GLenum actualFormat, GLenum actualType)
+{
+ gl::InternalFormat internalFormat = gl::GetInternalFormatInfo(format, type);
+ if (internalFormat.isLUMA())
+ {
+ // Ensure the format and type are compatible
+ ASSERT(internalFormat.pixelBytes ==
+ gl::GetInternalFormatInfo(actualFormat, actualType).pixelBytes);
+
+ // For Luminance formats, override with the internal format. Since this is not
+ // renderable, our pixel pack routines don't handle it correctly.
+ format = actualFormat;
+ type = actualType;
+ }
+}
+
+const FormatSet &GetAllSizedInternalFormats()
+{
+ static angle::base::NoDestructor<FormatSet> formatSet(BuildAllSizedInternalFormatSet());
+ return *formatSet;
+}
+
+AttributeType GetAttributeType(GLenum enumValue)
+{
+ switch (enumValue)
+ {
+ case GL_FLOAT:
+ return ATTRIBUTE_FLOAT;
+ case GL_FLOAT_VEC2:
+ return ATTRIBUTE_VEC2;
+ case GL_FLOAT_VEC3:
+ return ATTRIBUTE_VEC3;
+ case GL_FLOAT_VEC4:
+ return ATTRIBUTE_VEC4;
+ case GL_INT:
+ return ATTRIBUTE_INT;
+ case GL_INT_VEC2:
+ return ATTRIBUTE_IVEC2;
+ case GL_INT_VEC3:
+ return ATTRIBUTE_IVEC3;
+ case GL_INT_VEC4:
+ return ATTRIBUTE_IVEC4;
+ case GL_UNSIGNED_INT:
+ return ATTRIBUTE_UINT;
+ case GL_UNSIGNED_INT_VEC2:
+ return ATTRIBUTE_UVEC2;
+ case GL_UNSIGNED_INT_VEC3:
+ return ATTRIBUTE_UVEC3;
+ case GL_UNSIGNED_INT_VEC4:
+ return ATTRIBUTE_UVEC4;
+ case GL_FLOAT_MAT2:
+ return ATTRIBUTE_MAT2;
+ case GL_FLOAT_MAT3:
+ return ATTRIBUTE_MAT3;
+ case GL_FLOAT_MAT4:
+ return ATTRIBUTE_MAT4;
+ case GL_FLOAT_MAT2x3:
+ return ATTRIBUTE_MAT2x3;
+ case GL_FLOAT_MAT2x4:
+ return ATTRIBUTE_MAT2x4;
+ case GL_FLOAT_MAT3x2:
+ return ATTRIBUTE_MAT3x2;
+ case GL_FLOAT_MAT3x4:
+ return ATTRIBUTE_MAT3x4;
+ case GL_FLOAT_MAT4x2:
+ return ATTRIBUTE_MAT4x2;
+ case GL_FLOAT_MAT4x3:
+ return ATTRIBUTE_MAT4x3;
+ default:
+ UNREACHABLE();
+ return ATTRIBUTE_FLOAT;
+ }
+}
+
+angle::FormatID GetVertexFormatID(VertexAttribType type,
+ GLboolean normalized,
+ GLuint components,
+ bool pureInteger)
+{
+ switch (type)
+ {
+ case VertexAttribType::Byte:
+ switch (components)
+ {
+ case 1:
+ if (pureInteger)
+ return angle::FormatID::R8_SINT;
+ if (normalized)
+ return angle::FormatID::R8_SNORM;
+ return angle::FormatID::R8_SSCALED;
+ case 2:
+ if (pureInteger)
+ return angle::FormatID::R8G8_SINT;
+ if (normalized)
+ return angle::FormatID::R8G8_SNORM;
+ return angle::FormatID::R8G8_SSCALED;
+ case 3:
+ if (pureInteger)
+ return angle::FormatID::R8G8B8_SINT;
+ if (normalized)
+ return angle::FormatID::R8G8B8_SNORM;
+ return angle::FormatID::R8G8B8_SSCALED;
+ case 4:
+ if (pureInteger)
+ return angle::FormatID::R8G8B8A8_SINT;
+ if (normalized)
+ return angle::FormatID::R8G8B8A8_SNORM;
+ return angle::FormatID::R8G8B8A8_SSCALED;
+ default:
+ UNREACHABLE();
+ return angle::FormatID::NONE;
+ }
+ case VertexAttribType::UnsignedByte:
+ switch (components)
+ {
+ case 1:
+ if (pureInteger)
+ return angle::FormatID::R8_UINT;
+ if (normalized)
+ return angle::FormatID::R8_UNORM;
+ return angle::FormatID::R8_USCALED;
+ case 2:
+ if (pureInteger)
+ return angle::FormatID::R8G8_UINT;
+ if (normalized)
+ return angle::FormatID::R8G8_UNORM;
+ return angle::FormatID::R8G8_USCALED;
+ case 3:
+ if (pureInteger)
+ return angle::FormatID::R8G8B8_UINT;
+ if (normalized)
+ return angle::FormatID::R8G8B8_UNORM;
+ return angle::FormatID::R8G8B8_USCALED;
+ case 4:
+ if (pureInteger)
+ return angle::FormatID::R8G8B8A8_UINT;
+ if (normalized)
+ return angle::FormatID::R8G8B8A8_UNORM;
+ return angle::FormatID::R8G8B8A8_USCALED;
+ default:
+ UNREACHABLE();
+ return angle::FormatID::NONE;
+ }
+ case VertexAttribType::Short:
+ switch (components)
+ {
+ case 1:
+ if (pureInteger)
+ return angle::FormatID::R16_SINT;
+ if (normalized)
+ return angle::FormatID::R16_SNORM;
+ return angle::FormatID::R16_SSCALED;
+ case 2:
+ if (pureInteger)
+ return angle::FormatID::R16G16_SINT;
+ if (normalized)
+ return angle::FormatID::R16G16_SNORM;
+ return angle::FormatID::R16G16_SSCALED;
+ case 3:
+ if (pureInteger)
+ return angle::FormatID::R16G16B16_SINT;
+ if (normalized)
+ return angle::FormatID::R16G16B16_SNORM;
+ return angle::FormatID::R16G16B16_SSCALED;
+ case 4:
+ if (pureInteger)
+ return angle::FormatID::R16G16B16A16_SINT;
+ if (normalized)
+ return angle::FormatID::R16G16B16A16_SNORM;
+ return angle::FormatID::R16G16B16A16_SSCALED;
+ default:
+ UNREACHABLE();
+ return angle::FormatID::NONE;
+ }
+ case VertexAttribType::UnsignedShort:
+ switch (components)
+ {
+ case 1:
+ if (pureInteger)
+ return angle::FormatID::R16_UINT;
+ if (normalized)
+ return angle::FormatID::R16_UNORM;
+ return angle::FormatID::R16_USCALED;
+ case 2:
+ if (pureInteger)
+ return angle::FormatID::R16G16_UINT;
+ if (normalized)
+ return angle::FormatID::R16G16_UNORM;
+ return angle::FormatID::R16G16_USCALED;
+ case 3:
+ if (pureInteger)
+ return angle::FormatID::R16G16B16_UINT;
+ if (normalized)
+ return angle::FormatID::R16G16B16_UNORM;
+ return angle::FormatID::R16G16B16_USCALED;
+ case 4:
+ if (pureInteger)
+ return angle::FormatID::R16G16B16A16_UINT;
+ if (normalized)
+ return angle::FormatID::R16G16B16A16_UNORM;
+ return angle::FormatID::R16G16B16A16_USCALED;
+ default:
+ UNREACHABLE();
+ return angle::FormatID::NONE;
+ }
+ case VertexAttribType::Int:
+ switch (components)
+ {
+ case 1:
+ if (pureInteger)
+ return angle::FormatID::R32_SINT;
+ if (normalized)
+ return angle::FormatID::R32_SNORM;
+ return angle::FormatID::R32_SSCALED;
+ case 2:
+ if (pureInteger)
+ return angle::FormatID::R32G32_SINT;
+ if (normalized)
+ return angle::FormatID::R32G32_SNORM;
+ return angle::FormatID::R32G32_SSCALED;
+ case 3:
+ if (pureInteger)
+ return angle::FormatID::R32G32B32_SINT;
+ if (normalized)
+ return angle::FormatID::R32G32B32_SNORM;
+ return angle::FormatID::R32G32B32_SSCALED;
+ case 4:
+ if (pureInteger)
+ return angle::FormatID::R32G32B32A32_SINT;
+ if (normalized)
+ return angle::FormatID::R32G32B32A32_SNORM;
+ return angle::FormatID::R32G32B32A32_SSCALED;
+ default:
+ UNREACHABLE();
+ return angle::FormatID::NONE;
+ }
+ case VertexAttribType::UnsignedInt:
+ switch (components)
+ {
+ case 1:
+ if (pureInteger)
+ return angle::FormatID::R32_UINT;
+ if (normalized)
+ return angle::FormatID::R32_UNORM;
+ return angle::FormatID::R32_USCALED;
+ case 2:
+ if (pureInteger)
+ return angle::FormatID::R32G32_UINT;
+ if (normalized)
+ return angle::FormatID::R32G32_UNORM;
+ return angle::FormatID::R32G32_USCALED;
+ case 3:
+ if (pureInteger)
+ return angle::FormatID::R32G32B32_UINT;
+ if (normalized)
+ return angle::FormatID::R32G32B32_UNORM;
+ return angle::FormatID::R32G32B32_USCALED;
+ case 4:
+ if (pureInteger)
+ return angle::FormatID::R32G32B32A32_UINT;
+ if (normalized)
+ return angle::FormatID::R32G32B32A32_UNORM;
+ return angle::FormatID::R32G32B32A32_USCALED;
+ default:
+ UNREACHABLE();
+ return angle::FormatID::NONE;
+ }
+ case VertexAttribType::Float:
+ switch (components)
+ {
+ case 1:
+ return angle::FormatID::R32_FLOAT;
+ case 2:
+ return angle::FormatID::R32G32_FLOAT;
+ case 3:
+ return angle::FormatID::R32G32B32_FLOAT;
+ case 4:
+ return angle::FormatID::R32G32B32A32_FLOAT;
+ default:
+ UNREACHABLE();
+ return angle::FormatID::NONE;
+ }
+ case VertexAttribType::HalfFloat:
+ case VertexAttribType::HalfFloatOES:
+ switch (components)
+ {
+ case 1:
+ return angle::FormatID::R16_FLOAT;
+ case 2:
+ return angle::FormatID::R16G16_FLOAT;
+ case 3:
+ return angle::FormatID::R16G16B16_FLOAT;
+ case 4:
+ return angle::FormatID::R16G16B16A16_FLOAT;
+ default:
+ UNREACHABLE();
+ return angle::FormatID::NONE;
+ }
+ case VertexAttribType::Fixed:
+ switch (components)
+ {
+ case 1:
+ return angle::FormatID::R32_FIXED;
+ case 2:
+ return angle::FormatID::R32G32_FIXED;
+ case 3:
+ return angle::FormatID::R32G32B32_FIXED;
+ case 4:
+ return angle::FormatID::R32G32B32A32_FIXED;
+ default:
+ UNREACHABLE();
+ return angle::FormatID::NONE;
+ }
+ case VertexAttribType::Int2101010:
+ if (pureInteger)
+ return angle::FormatID::R10G10B10A2_SINT;
+ if (normalized)
+ return angle::FormatID::R10G10B10A2_SNORM;
+ return angle::FormatID::R10G10B10A2_SSCALED;
+ case VertexAttribType::UnsignedInt2101010:
+ if (pureInteger)
+ return angle::FormatID::R10G10B10A2_UINT;
+ if (normalized)
+ return angle::FormatID::R10G10B10A2_UNORM;
+ return angle::FormatID::R10G10B10A2_USCALED;
+ case VertexAttribType::Int1010102:
+ switch (components)
+ {
+ case 3:
+ if (pureInteger)
+ return angle::FormatID::X2R10G10B10_SINT_VERTEX;
+ if (normalized)
+ return angle::FormatID::X2R10G10B10_SNORM_VERTEX;
+ return angle::FormatID::X2R10G10B10_SSCALED_VERTEX;
+ case 4:
+ if (pureInteger)
+ return angle::FormatID::A2R10G10B10_SINT_VERTEX;
+ if (normalized)
+ return angle::FormatID::A2R10G10B10_SNORM_VERTEX;
+ return angle::FormatID::A2R10G10B10_SSCALED_VERTEX;
+ default:
+ UNREACHABLE();
+ return angle::FormatID::NONE;
+ }
+ case VertexAttribType::UnsignedInt1010102:
+ switch (components)
+ {
+ case 3:
+ if (pureInteger)
+ return angle::FormatID::X2R10G10B10_UINT_VERTEX;
+ if (normalized)
+ return angle::FormatID::X2R10G10B10_UNORM_VERTEX;
+ return angle::FormatID::X2R10G10B10_USCALED_VERTEX;
+
+ case 4:
+ if (pureInteger)
+ return angle::FormatID::A2R10G10B10_UINT_VERTEX;
+ if (normalized)
+ return angle::FormatID::A2R10G10B10_UNORM_VERTEX;
+ return angle::FormatID::A2R10G10B10_USCALED_VERTEX;
+ default:
+ UNREACHABLE();
+ return angle::FormatID::NONE;
+ }
+ default:
+ UNREACHABLE();
+ return angle::FormatID::NONE;
+ }
+}
+
+angle::FormatID GetVertexFormatID(const VertexAttribute &attrib, VertexAttribType currentValueType)
+{
+ if (!attrib.enabled)
+ {
+ return GetCurrentValueFormatID(currentValueType);
+ }
+ return attrib.format->id;
+}
+
+angle::FormatID GetCurrentValueFormatID(VertexAttribType currentValueType)
+{
+ switch (currentValueType)
+ {
+ case VertexAttribType::Float:
+ return angle::FormatID::R32G32B32A32_FLOAT;
+ case VertexAttribType::Int:
+ return angle::FormatID::R32G32B32A32_SINT;
+ case VertexAttribType::UnsignedInt:
+ return angle::FormatID::R32G32B32A32_UINT;
+ default:
+ UNREACHABLE();
+ return angle::FormatID::NONE;
+ }
+}
+
+const VertexFormat &GetVertexFormatFromID(angle::FormatID vertexFormatID)
+{
+ switch (vertexFormatID)
+ {
+ case angle::FormatID::R8_SSCALED:
+ {
+ static const VertexFormat format(GL_BYTE, GL_FALSE, 1, false);
+ return format;
+ }
+ case angle::FormatID::R8_SNORM:
+ {
+ static const VertexFormat format(GL_BYTE, GL_TRUE, 1, false);
+ return format;
+ }
+ case angle::FormatID::R8G8_SSCALED:
+ {
+ static const VertexFormat format(GL_BYTE, GL_FALSE, 2, false);
+ return format;
+ }
+ case angle::FormatID::R8G8_SNORM:
+ {
+ static const VertexFormat format(GL_BYTE, GL_TRUE, 2, false);
+ return format;
+ }
+ case angle::FormatID::R8G8B8_SSCALED:
+ {
+ static const VertexFormat format(GL_BYTE, GL_FALSE, 3, false);
+ return format;
+ }
+ case angle::FormatID::R8G8B8_SNORM:
+ {
+ static const VertexFormat format(GL_BYTE, GL_TRUE, 3, false);
+ return format;
+ }
+ case angle::FormatID::R8G8B8A8_SSCALED:
+ {
+ static const VertexFormat format(GL_BYTE, GL_FALSE, 4, false);
+ return format;
+ }
+ case angle::FormatID::R8G8B8A8_SNORM:
+ {
+ static const VertexFormat format(GL_BYTE, GL_TRUE, 4, false);
+ return format;
+ }
+ case angle::FormatID::R8_USCALED:
+ {
+ static const VertexFormat format(GL_UNSIGNED_BYTE, GL_FALSE, 1, false);
+ return format;
+ }
+ case angle::FormatID::R8_UNORM:
+ {
+ static const VertexFormat format(GL_UNSIGNED_BYTE, GL_TRUE, 1, false);
+ return format;
+ }
+ case angle::FormatID::R8G8_USCALED:
+ {
+ static const VertexFormat format(GL_UNSIGNED_BYTE, GL_FALSE, 2, false);
+ return format;
+ }
+ case angle::FormatID::R8G8_UNORM:
+ {
+ static const VertexFormat format(GL_UNSIGNED_BYTE, GL_TRUE, 2, false);
+ return format;
+ }
+ case angle::FormatID::R8G8B8_USCALED:
+ {
+ static const VertexFormat format(GL_UNSIGNED_BYTE, GL_FALSE, 3, false);
+ return format;
+ }
+ case angle::FormatID::R8G8B8_UNORM:
+ {
+ static const VertexFormat format(GL_UNSIGNED_BYTE, GL_TRUE, 3, false);
+ return format;
+ }
+ case angle::FormatID::R8G8B8A8_USCALED:
+ {
+ static const VertexFormat format(GL_UNSIGNED_BYTE, GL_FALSE, 4, false);
+ return format;
+ }
+ case angle::FormatID::R8G8B8A8_UNORM:
+ {
+ static const VertexFormat format(GL_UNSIGNED_BYTE, GL_TRUE, 4, false);
+ return format;
+ }
+ case angle::FormatID::R16_SSCALED:
+ {
+ static const VertexFormat format(GL_SHORT, GL_FALSE, 1, false);
+ return format;
+ }
+ case angle::FormatID::R16_SNORM:
+ {
+ static const VertexFormat format(GL_SHORT, GL_TRUE, 1, false);
+ return format;
+ }
+ case angle::FormatID::R16G16_SSCALED:
+ {
+ static const VertexFormat format(GL_SHORT, GL_FALSE, 2, false);
+ return format;
+ }
+ case angle::FormatID::R16G16_SNORM:
+ {
+ static const VertexFormat format(GL_SHORT, GL_TRUE, 2, false);
+ return format;
+ }
+ case angle::FormatID::R16G16B16_SSCALED:
+ {
+ static const VertexFormat format(GL_SHORT, GL_FALSE, 3, false);
+ return format;
+ }
+ case angle::FormatID::R16G16B16_SNORM:
+ {
+ static const VertexFormat format(GL_SHORT, GL_TRUE, 3, false);
+ return format;
+ }
+ case angle::FormatID::R16G16B16A16_SSCALED:
+ {
+ static const VertexFormat format(GL_SHORT, GL_FALSE, 4, false);
+ return format;
+ }
+ case angle::FormatID::R16G16B16A16_SNORM:
+ {
+ static const VertexFormat format(GL_SHORT, GL_TRUE, 4, false);
+ return format;
+ }
+ case angle::FormatID::R16_USCALED:
+ {
+ static const VertexFormat format(GL_UNSIGNED_SHORT, GL_FALSE, 1, false);
+ return format;
+ }
+ case angle::FormatID::R16_UNORM:
+ {
+ static const VertexFormat format(GL_UNSIGNED_SHORT, GL_TRUE, 1, false);
+ return format;
+ }
+ case angle::FormatID::R16G16_USCALED:
+ {
+ static const VertexFormat format(GL_UNSIGNED_SHORT, GL_FALSE, 2, false);
+ return format;
+ }
+ case angle::FormatID::R16G16_UNORM:
+ {
+ static const VertexFormat format(GL_UNSIGNED_SHORT, GL_TRUE, 2, false);
+ return format;
+ }
+ case angle::FormatID::R16G16B16_USCALED:
+ {
+ static const VertexFormat format(GL_UNSIGNED_SHORT, GL_FALSE, 3, false);
+ return format;
+ }
+ case angle::FormatID::R16G16B16_UNORM:
+ {
+ static const VertexFormat format(GL_UNSIGNED_SHORT, GL_TRUE, 3, false);
+ return format;
+ }
+ case angle::FormatID::R16G16B16A16_USCALED:
+ {
+ static const VertexFormat format(GL_UNSIGNED_SHORT, GL_FALSE, 4, false);
+ return format;
+ }
+ case angle::FormatID::R16G16B16A16_UNORM:
+ {
+ static const VertexFormat format(GL_UNSIGNED_SHORT, GL_TRUE, 4, false);
+ return format;
+ }
+ case angle::FormatID::R32_SSCALED:
+ {
+ static const VertexFormat format(GL_INT, GL_FALSE, 1, false);
+ return format;
+ }
+ case angle::FormatID::R32_SNORM:
+ {
+ static const VertexFormat format(GL_INT, GL_TRUE, 1, false);
+ return format;
+ }
+ case angle::FormatID::R32G32_SSCALED:
+ {
+ static const VertexFormat format(GL_INT, GL_FALSE, 2, false);
+ return format;
+ }
+ case angle::FormatID::R32G32_SNORM:
+ {
+ static const VertexFormat format(GL_INT, GL_TRUE, 2, false);
+ return format;
+ }
+ case angle::FormatID::R32G32B32_SSCALED:
+ {
+ static const VertexFormat format(GL_INT, GL_FALSE, 3, false);
+ return format;
+ }
+ case angle::FormatID::R32G32B32_SNORM:
+ {
+ static const VertexFormat format(GL_INT, GL_TRUE, 3, false);
+ return format;
+ }
+ case angle::FormatID::R32G32B32A32_SSCALED:
+ {
+ static const VertexFormat format(GL_INT, GL_FALSE, 4, false);
+ return format;
+ }
+ case angle::FormatID::R32G32B32A32_SNORM:
+ {
+ static const VertexFormat format(GL_INT, GL_TRUE, 4, false);
+ return format;
+ }
+ case angle::FormatID::R32_USCALED:
+ {
+ static const VertexFormat format(GL_UNSIGNED_INT, GL_FALSE, 1, false);
+ return format;
+ }
+ case angle::FormatID::R32_UNORM:
+ {
+ static const VertexFormat format(GL_UNSIGNED_INT, GL_TRUE, 1, false);
+ return format;
+ }
+ case angle::FormatID::R32G32_USCALED:
+ {
+ static const VertexFormat format(GL_UNSIGNED_INT, GL_FALSE, 2, false);
+ return format;
+ }
+ case angle::FormatID::R32G32_UNORM:
+ {
+ static const VertexFormat format(GL_UNSIGNED_INT, GL_TRUE, 2, false);
+ return format;
+ }
+ case angle::FormatID::R32G32B32_USCALED:
+ {
+ static const VertexFormat format(GL_UNSIGNED_INT, GL_FALSE, 3, false);
+ return format;
+ }
+ case angle::FormatID::R32G32B32_UNORM:
+ {
+ static const VertexFormat format(GL_UNSIGNED_INT, GL_TRUE, 3, false);
+ return format;
+ }
+ case angle::FormatID::R32G32B32A32_USCALED:
+ {
+ static const VertexFormat format(GL_UNSIGNED_INT, GL_FALSE, 4, false);
+ return format;
+ }
+ case angle::FormatID::R32G32B32A32_UNORM:
+ {
+ static const VertexFormat format(GL_UNSIGNED_INT, GL_TRUE, 4, false);
+ return format;
+ }
+ case angle::FormatID::R8_SINT:
+ {
+ static const VertexFormat format(GL_BYTE, GL_FALSE, 1, true);
+ return format;
+ }
+ case angle::FormatID::R8G8_SINT:
+ {
+ static const VertexFormat format(GL_BYTE, GL_FALSE, 2, true);
+ return format;
+ }
+ case angle::FormatID::R8G8B8_SINT:
+ {
+ static const VertexFormat format(GL_BYTE, GL_FALSE, 3, true);
+ return format;
+ }
+ case angle::FormatID::R8G8B8A8_SINT:
+ {
+ static const VertexFormat format(GL_BYTE, GL_FALSE, 4, true);
+ return format;
+ }
+ case angle::FormatID::R8_UINT:
+ {
+ static const VertexFormat format(GL_UNSIGNED_BYTE, GL_FALSE, 1, true);
+ return format;
+ }
+ case angle::FormatID::R8G8_UINT:
+ {
+ static const VertexFormat format(GL_UNSIGNED_BYTE, GL_FALSE, 2, true);
+ return format;
+ }
+ case angle::FormatID::R8G8B8_UINT:
+ {
+ static const VertexFormat format(GL_UNSIGNED_BYTE, GL_FALSE, 3, true);
+ return format;
+ }
+ case angle::FormatID::R8G8B8A8_UINT:
+ {
+ static const VertexFormat format(GL_UNSIGNED_BYTE, GL_FALSE, 4, true);
+ return format;
+ }
+ case angle::FormatID::R16_SINT:
+ {
+ static const VertexFormat format(GL_SHORT, GL_FALSE, 1, true);
+ return format;
+ }
+ case angle::FormatID::R16G16_SINT:
+ {
+ static const VertexFormat format(GL_SHORT, GL_FALSE, 2, true);
+ return format;
+ }
+ case angle::FormatID::R16G16B16_SINT:
+ {
+ static const VertexFormat format(GL_SHORT, GL_FALSE, 3, true);
+ return format;
+ }
+ case angle::FormatID::R16G16B16A16_SINT:
+ {
+ static const VertexFormat format(GL_SHORT, GL_FALSE, 4, true);
+ return format;
+ }
+ case angle::FormatID::R16_UINT:
+ {
+ static const VertexFormat format(GL_UNSIGNED_SHORT, GL_FALSE, 1, true);
+ return format;
+ }
+ case angle::FormatID::R16G16_UINT:
+ {
+ static const VertexFormat format(GL_UNSIGNED_SHORT, GL_FALSE, 2, true);
+ return format;
+ }
+ case angle::FormatID::R16G16B16_UINT:
+ {
+ static const VertexFormat format(GL_UNSIGNED_SHORT, GL_FALSE, 3, true);
+ return format;
+ }
+ case angle::FormatID::R16G16B16A16_UINT:
+ {
+ static const VertexFormat format(GL_UNSIGNED_SHORT, GL_FALSE, 4, true);
+ return format;
+ }
+ case angle::FormatID::R32_SINT:
+ {
+ static const VertexFormat format(GL_INT, GL_FALSE, 1, true);
+ return format;
+ }
+ case angle::FormatID::R32G32_SINT:
+ {
+ static const VertexFormat format(GL_INT, GL_FALSE, 2, true);
+ return format;
+ }
+ case angle::FormatID::R32G32B32_SINT:
+ {
+ static const VertexFormat format(GL_INT, GL_FALSE, 3, true);
+ return format;
+ }
+ case angle::FormatID::R32G32B32A32_SINT:
+ {
+ static const VertexFormat format(GL_INT, GL_FALSE, 4, true);
+ return format;
+ }
+ case angle::FormatID::R32_UINT:
+ {
+ static const VertexFormat format(GL_UNSIGNED_INT, GL_FALSE, 1, true);
+ return format;
+ }
+ case angle::FormatID::R32G32_UINT:
+ {
+ static const VertexFormat format(GL_UNSIGNED_INT, GL_FALSE, 2, true);
+ return format;
+ }
+ case angle::FormatID::R32G32B32_UINT:
+ {
+ static const VertexFormat format(GL_UNSIGNED_INT, GL_FALSE, 3, true);
+ return format;
+ }
+ case angle::FormatID::R32G32B32A32_UINT:
+ {
+ static const VertexFormat format(GL_UNSIGNED_INT, GL_FALSE, 4, true);
+ return format;
+ }
+ case angle::FormatID::R32_FIXED:
+ {
+ static const VertexFormat format(GL_FIXED, GL_FALSE, 1, false);
+ return format;
+ }
+ case angle::FormatID::R32G32_FIXED:
+ {
+ static const VertexFormat format(GL_FIXED, GL_FALSE, 2, false);
+ return format;
+ }
+ case angle::FormatID::R32G32B32_FIXED:
+ {
+ static const VertexFormat format(GL_FIXED, GL_FALSE, 3, false);
+ return format;
+ }
+ case angle::FormatID::R32G32B32A32_FIXED:
+ {
+ static const VertexFormat format(GL_FIXED, GL_FALSE, 4, false);
+ return format;
+ }
+ case angle::FormatID::R16_FLOAT:
+ {
+ static const VertexFormat format(GL_HALF_FLOAT, GL_FALSE, 1, false);
+ return format;
+ }
+ case angle::FormatID::R16G16_FLOAT:
+ {
+ static const VertexFormat format(GL_HALF_FLOAT, GL_FALSE, 2, false);
+ return format;
+ }
+ case angle::FormatID::R16G16B16_FLOAT:
+ {
+ static const VertexFormat format(GL_HALF_FLOAT, GL_FALSE, 3, false);
+ return format;
+ }
+ case angle::FormatID::R16G16B16A16_FLOAT:
+ {
+ static const VertexFormat format(GL_HALF_FLOAT, GL_FALSE, 4, false);
+ return format;
+ }
+ case angle::FormatID::R32_FLOAT:
+ {
+ static const VertexFormat format(GL_FLOAT, GL_FALSE, 1, false);
+ return format;
+ }
+ case angle::FormatID::R32G32_FLOAT:
+ {
+ static const VertexFormat format(GL_FLOAT, GL_FALSE, 2, false);
+ return format;
+ }
+ case angle::FormatID::R32G32B32_FLOAT:
+ {
+ static const VertexFormat format(GL_FLOAT, GL_FALSE, 3, false);
+ return format;
+ }
+ case angle::FormatID::R32G32B32A32_FLOAT:
+ {
+ static const VertexFormat format(GL_FLOAT, GL_FALSE, 4, false);
+ return format;
+ }
+ case angle::FormatID::R10G10B10A2_SSCALED:
+ {
+ static const VertexFormat format(GL_INT_2_10_10_10_REV, GL_FALSE, 4, false);
+ return format;
+ }
+ case angle::FormatID::R10G10B10A2_USCALED:
+ {
+ static const VertexFormat format(GL_UNSIGNED_INT_2_10_10_10_REV, GL_FALSE, 4, false);
+ return format;
+ }
+ case angle::FormatID::R10G10B10A2_SNORM:
+ {
+ static const VertexFormat format(GL_INT_2_10_10_10_REV, GL_TRUE, 4, false);
+ return format;
+ }
+ case angle::FormatID::R10G10B10A2_UNORM:
+ {
+ static const VertexFormat format(GL_UNSIGNED_INT_2_10_10_10_REV, GL_TRUE, 4, false);
+ return format;
+ }
+ case angle::FormatID::R10G10B10A2_SINT:
+ {
+ static const VertexFormat format(GL_INT_2_10_10_10_REV, GL_FALSE, 4, true);
+ return format;
+ }
+ case angle::FormatID::R10G10B10A2_UINT:
+ {
+ static const VertexFormat format(GL_UNSIGNED_INT_2_10_10_10_REV, GL_FALSE, 4, true);
+ return format;
+ }
+ case angle::FormatID::A2R10G10B10_SSCALED_VERTEX:
+ {
+ static const VertexFormat format(GL_INT_10_10_10_2_OES, GL_FALSE, 4, false);
+ return format;
+ }
+ case angle::FormatID::A2R10G10B10_USCALED_VERTEX:
+ {
+ static const VertexFormat format(GL_UNSIGNED_INT_10_10_10_2_OES, GL_FALSE, 4, false);
+ return format;
+ }
+ case angle::FormatID::A2R10G10B10_SNORM_VERTEX:
+ {
+ static const VertexFormat format(GL_INT_10_10_10_2_OES, GL_TRUE, 4, false);
+ return format;
+ }
+ case angle::FormatID::A2R10G10B10_UNORM_VERTEX:
+ {
+ static const VertexFormat format(GL_UNSIGNED_INT_10_10_10_2_OES, GL_TRUE, 4, false);
+ return format;
+ }
+ case angle::FormatID::A2R10G10B10_SINT_VERTEX:
+ {
+ static const VertexFormat format(GL_INT_10_10_10_2_OES, GL_FALSE, 4, true);
+ return format;
+ }
+ case angle::FormatID::A2R10G10B10_UINT_VERTEX:
+ {
+ static const VertexFormat format(GL_UNSIGNED_INT_10_10_10_2_OES, GL_FALSE, 4, true);
+ return format;
+ }
+ case angle::FormatID::X2R10G10B10_SSCALED_VERTEX:
+ {
+ static const VertexFormat format(GL_INT_10_10_10_2_OES, GL_FALSE, 4, false);
+ return format;
+ }
+ case angle::FormatID::X2R10G10B10_USCALED_VERTEX:
+ {
+ static const VertexFormat format(GL_UNSIGNED_INT_10_10_10_2_OES, GL_FALSE, 4, false);
+ return format;
+ }
+ case angle::FormatID::X2R10G10B10_SNORM_VERTEX:
+ {
+ static const VertexFormat format(GL_INT_10_10_10_2_OES, GL_TRUE, 4, false);
+ return format;
+ }
+ case angle::FormatID::X2R10G10B10_UNORM_VERTEX:
+ {
+ static const VertexFormat format(GL_UNSIGNED_INT_10_10_10_2_OES, GL_TRUE, 4, false);
+ return format;
+ }
+ case angle::FormatID::X2R10G10B10_SINT_VERTEX:
+ {
+ static const VertexFormat format(GL_INT_10_10_10_2_OES, GL_FALSE, 4, true);
+ return format;
+ }
+ default:
+ {
+ static const VertexFormat format(GL_NONE, GL_FALSE, 0, false);
+ return format;
+ }
+ }
+}
+
+size_t GetVertexFormatSize(angle::FormatID vertexFormatID)
+{
+ switch (vertexFormatID)
+ {
+ case angle::FormatID::R8_SSCALED:
+ case angle::FormatID::R8_SNORM:
+ case angle::FormatID::R8_USCALED:
+ case angle::FormatID::R8_UNORM:
+ case angle::FormatID::R8_SINT:
+ case angle::FormatID::R8_UINT:
+ return 1;
+
+ case angle::FormatID::R8G8_SSCALED:
+ case angle::FormatID::R8G8_SNORM:
+ case angle::FormatID::R8G8_USCALED:
+ case angle::FormatID::R8G8_UNORM:
+ case angle::FormatID::R8G8_SINT:
+ case angle::FormatID::R8G8_UINT:
+ case angle::FormatID::R16_SSCALED:
+ case angle::FormatID::R16_SNORM:
+ case angle::FormatID::R16_USCALED:
+ case angle::FormatID::R16_UNORM:
+ case angle::FormatID::R16_SINT:
+ case angle::FormatID::R16_UINT:
+ case angle::FormatID::R16_FLOAT:
+ return 2;
+
+ case angle::FormatID::R8G8B8_SSCALED:
+ case angle::FormatID::R8G8B8_SNORM:
+ case angle::FormatID::R8G8B8_USCALED:
+ case angle::FormatID::R8G8B8_UNORM:
+ case angle::FormatID::R8G8B8_SINT:
+ case angle::FormatID::R8G8B8_UINT:
+ return 3;
+
+ case angle::FormatID::R8G8B8A8_SSCALED:
+ case angle::FormatID::R8G8B8A8_SNORM:
+ case angle::FormatID::R8G8B8A8_USCALED:
+ case angle::FormatID::R8G8B8A8_UNORM:
+ case angle::FormatID::R8G8B8A8_SINT:
+ case angle::FormatID::R8G8B8A8_UINT:
+ case angle::FormatID::R16G16_SSCALED:
+ case angle::FormatID::R16G16_SNORM:
+ case angle::FormatID::R16G16_USCALED:
+ case angle::FormatID::R16G16_UNORM:
+ case angle::FormatID::R16G16_SINT:
+ case angle::FormatID::R16G16_UINT:
+ case angle::FormatID::R32_SSCALED:
+ case angle::FormatID::R32_SNORM:
+ case angle::FormatID::R32_USCALED:
+ case angle::FormatID::R32_UNORM:
+ case angle::FormatID::R32_SINT:
+ case angle::FormatID::R32_UINT:
+ case angle::FormatID::R16G16_FLOAT:
+ case angle::FormatID::R32_FIXED:
+ case angle::FormatID::R32_FLOAT:
+ case angle::FormatID::R10G10B10A2_SSCALED:
+ case angle::FormatID::R10G10B10A2_USCALED:
+ case angle::FormatID::R10G10B10A2_SNORM:
+ case angle::FormatID::R10G10B10A2_UNORM:
+ case angle::FormatID::R10G10B10A2_SINT:
+ case angle::FormatID::R10G10B10A2_UINT:
+ case angle::FormatID::A2R10G10B10_SSCALED_VERTEX:
+ case angle::FormatID::A2R10G10B10_USCALED_VERTEX:
+ case angle::FormatID::A2R10G10B10_SINT_VERTEX:
+ case angle::FormatID::A2R10G10B10_UINT_VERTEX:
+ case angle::FormatID::A2R10G10B10_SNORM_VERTEX:
+ case angle::FormatID::A2R10G10B10_UNORM_VERTEX:
+ case angle::FormatID::X2R10G10B10_SSCALED_VERTEX:
+ case angle::FormatID::X2R10G10B10_USCALED_VERTEX:
+ case angle::FormatID::X2R10G10B10_SINT_VERTEX:
+ case angle::FormatID::X2R10G10B10_UINT_VERTEX:
+ case angle::FormatID::X2R10G10B10_SNORM_VERTEX:
+ case angle::FormatID::X2R10G10B10_UNORM_VERTEX:
+ return 4;
+
+ case angle::FormatID::R16G16B16_SSCALED:
+ case angle::FormatID::R16G16B16_SNORM:
+ case angle::FormatID::R16G16B16_USCALED:
+ case angle::FormatID::R16G16B16_UNORM:
+ case angle::FormatID::R16G16B16_SINT:
+ case angle::FormatID::R16G16B16_UINT:
+ case angle::FormatID::R16G16B16_FLOAT:
+ return 6;
+
+ case angle::FormatID::R16G16B16A16_SSCALED:
+ case angle::FormatID::R16G16B16A16_SNORM:
+ case angle::FormatID::R16G16B16A16_USCALED:
+ case angle::FormatID::R16G16B16A16_UNORM:
+ case angle::FormatID::R16G16B16A16_SINT:
+ case angle::FormatID::R16G16B16A16_UINT:
+ case angle::FormatID::R32G32_SSCALED:
+ case angle::FormatID::R32G32_SNORM:
+ case angle::FormatID::R32G32_USCALED:
+ case angle::FormatID::R32G32_UNORM:
+ case angle::FormatID::R32G32_SINT:
+ case angle::FormatID::R32G32_UINT:
+ case angle::FormatID::R16G16B16A16_FLOAT:
+ case angle::FormatID::R32G32_FIXED:
+ case angle::FormatID::R32G32_FLOAT:
+ return 8;
+
+ case angle::FormatID::R32G32B32_SSCALED:
+ case angle::FormatID::R32G32B32_SNORM:
+ case angle::FormatID::R32G32B32_USCALED:
+ case angle::FormatID::R32G32B32_UNORM:
+ case angle::FormatID::R32G32B32_SINT:
+ case angle::FormatID::R32G32B32_UINT:
+ case angle::FormatID::R32G32B32_FIXED:
+ case angle::FormatID::R32G32B32_FLOAT:
+ return 12;
+
+ case angle::FormatID::R32G32B32A32_SSCALED:
+ case angle::FormatID::R32G32B32A32_SNORM:
+ case angle::FormatID::R32G32B32A32_USCALED:
+ case angle::FormatID::R32G32B32A32_UNORM:
+ case angle::FormatID::R32G32B32A32_SINT:
+ case angle::FormatID::R32G32B32A32_UINT:
+ case angle::FormatID::R32G32B32A32_FIXED:
+ case angle::FormatID::R32G32B32A32_FLOAT:
+ return 16;
+
+ case angle::FormatID::NONE:
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+angle::FormatID ConvertFormatSignedness(const angle::Format &format)
+{
+ switch (format.id)
+ {
+ // 1 byte signed to unsigned
+ case angle::FormatID::R8_SINT:
+ return angle::FormatID::R8_UINT;
+ case angle::FormatID::R8_SNORM:
+ return angle::FormatID::R8_UNORM;
+ case angle::FormatID::R8_SSCALED:
+ return angle::FormatID::R8_USCALED;
+ case angle::FormatID::R8G8_SINT:
+ return angle::FormatID::R8G8_UINT;
+ case angle::FormatID::R8G8_SNORM:
+ return angle::FormatID::R8G8_UNORM;
+ case angle::FormatID::R8G8_SSCALED:
+ return angle::FormatID::R8G8_USCALED;
+ case angle::FormatID::R8G8B8_SINT:
+ return angle::FormatID::R8G8B8_UINT;
+ case angle::FormatID::R8G8B8_SNORM:
+ return angle::FormatID::R8G8B8_UNORM;
+ case angle::FormatID::R8G8B8_SSCALED:
+ return angle::FormatID::R8G8B8_USCALED;
+ case angle::FormatID::R8G8B8A8_SINT:
+ return angle::FormatID::R8G8B8A8_UINT;
+ case angle::FormatID::R8G8B8A8_SNORM:
+ return angle::FormatID::R8G8B8A8_UNORM;
+ case angle::FormatID::R8G8B8A8_SSCALED:
+ return angle::FormatID::R8G8B8A8_USCALED;
+ // 1 byte unsigned to signed
+ case angle::FormatID::R8_UINT:
+ return angle::FormatID::R8_SINT;
+ case angle::FormatID::R8_UNORM:
+ return angle::FormatID::R8_SNORM;
+ case angle::FormatID::R8_USCALED:
+ return angle::FormatID::R8_SSCALED;
+ case angle::FormatID::R8G8_UINT:
+ return angle::FormatID::R8G8_SINT;
+ case angle::FormatID::R8G8_UNORM:
+ return angle::FormatID::R8G8_SNORM;
+ case angle::FormatID::R8G8_USCALED:
+ return angle::FormatID::R8G8_SSCALED;
+ case angle::FormatID::R8G8B8_UINT:
+ return angle::FormatID::R8G8B8_SINT;
+ case angle::FormatID::R8G8B8_UNORM:
+ return angle::FormatID::R8G8B8_SNORM;
+ case angle::FormatID::R8G8B8_USCALED:
+ return angle::FormatID::R8G8B8_SSCALED;
+ case angle::FormatID::R8G8B8A8_UINT:
+ return angle::FormatID::R8G8B8A8_SINT;
+ case angle::FormatID::R8G8B8A8_UNORM:
+ return angle::FormatID::R8G8B8A8_SNORM;
+ case angle::FormatID::R8G8B8A8_USCALED:
+ return angle::FormatID::R8G8B8A8_SSCALED;
+ // 2 byte signed to unsigned
+ case angle::FormatID::R16_SINT:
+ return angle::FormatID::R16_UINT;
+ case angle::FormatID::R16_SNORM:
+ return angle::FormatID::R16_UNORM;
+ case angle::FormatID::R16_SSCALED:
+ return angle::FormatID::R16_USCALED;
+ case angle::FormatID::R16G16_SINT:
+ return angle::FormatID::R16G16_UINT;
+ case angle::FormatID::R16G16_SNORM:
+ return angle::FormatID::R16G16_UNORM;
+ case angle::FormatID::R16G16_SSCALED:
+ return angle::FormatID::R16G16_USCALED;
+ case angle::FormatID::R16G16B16_SINT:
+ return angle::FormatID::R16G16B16_UINT;
+ case angle::FormatID::R16G16B16_SNORM:
+ return angle::FormatID::R16G16B16_UNORM;
+ case angle::FormatID::R16G16B16_SSCALED:
+ return angle::FormatID::R16G16B16_USCALED;
+ case angle::FormatID::R16G16B16A16_SINT:
+ return angle::FormatID::R16G16B16A16_UINT;
+ case angle::FormatID::R16G16B16A16_SNORM:
+ return angle::FormatID::R16G16B16A16_UNORM;
+ case angle::FormatID::R16G16B16A16_SSCALED:
+ return angle::FormatID::R16G16B16A16_USCALED;
+ // 2 byte unsigned to signed
+ case angle::FormatID::R16_UINT:
+ return angle::FormatID::R16_SINT;
+ case angle::FormatID::R16_UNORM:
+ return angle::FormatID::R16_SNORM;
+ case angle::FormatID::R16_USCALED:
+ return angle::FormatID::R16_SSCALED;
+ case angle::FormatID::R16G16_UINT:
+ return angle::FormatID::R16G16_SINT;
+ case angle::FormatID::R16G16_UNORM:
+ return angle::FormatID::R16G16_SNORM;
+ case angle::FormatID::R16G16_USCALED:
+ return angle::FormatID::R16G16_SSCALED;
+ case angle::FormatID::R16G16B16_UINT:
+ return angle::FormatID::R16G16B16_SINT;
+ case angle::FormatID::R16G16B16_UNORM:
+ return angle::FormatID::R16G16B16_SNORM;
+ case angle::FormatID::R16G16B16_USCALED:
+ return angle::FormatID::R16G16B16_SSCALED;
+ case angle::FormatID::R16G16B16A16_UINT:
+ return angle::FormatID::R16G16B16A16_SINT;
+ case angle::FormatID::R16G16B16A16_UNORM:
+ return angle::FormatID::R16G16B16A16_SNORM;
+ case angle::FormatID::R16G16B16A16_USCALED:
+ return angle::FormatID::R16G16B16A16_SSCALED;
+ // 4 byte signed to unsigned
+ case angle::FormatID::R32_SINT:
+ return angle::FormatID::R32_UINT;
+ case angle::FormatID::R32_SNORM:
+ return angle::FormatID::R32_UNORM;
+ case angle::FormatID::R32_SSCALED:
+ return angle::FormatID::R32_USCALED;
+ case angle::FormatID::R32G32_SINT:
+ return angle::FormatID::R32G32_UINT;
+ case angle::FormatID::R32G32_SNORM:
+ return angle::FormatID::R32G32_UNORM;
+ case angle::FormatID::R32G32_SSCALED:
+ return angle::FormatID::R32G32_USCALED;
+ case angle::FormatID::R32G32B32_SINT:
+ return angle::FormatID::R32G32B32_UINT;
+ case angle::FormatID::R32G32B32_SNORM:
+ return angle::FormatID::R32G32B32_UNORM;
+ case angle::FormatID::R32G32B32_SSCALED:
+ return angle::FormatID::R32G32B32_USCALED;
+ case angle::FormatID::R32G32B32A32_SINT:
+ return angle::FormatID::R32G32B32A32_UINT;
+ case angle::FormatID::R32G32B32A32_SNORM:
+ return angle::FormatID::R32G32B32A32_UNORM;
+ case angle::FormatID::R32G32B32A32_SSCALED:
+ return angle::FormatID::R32G32B32A32_USCALED;
+ // 4 byte unsigned to signed
+ case angle::FormatID::R32_UINT:
+ return angle::FormatID::R32_SINT;
+ case angle::FormatID::R32_UNORM:
+ return angle::FormatID::R32_SNORM;
+ case angle::FormatID::R32_USCALED:
+ return angle::FormatID::R32_SSCALED;
+ case angle::FormatID::R32G32_UINT:
+ return angle::FormatID::R32G32_SINT;
+ case angle::FormatID::R32G32_UNORM:
+ return angle::FormatID::R32G32_SNORM;
+ case angle::FormatID::R32G32_USCALED:
+ return angle::FormatID::R32G32_SSCALED;
+ case angle::FormatID::R32G32B32_UINT:
+ return angle::FormatID::R32G32B32_SINT;
+ case angle::FormatID::R32G32B32_UNORM:
+ return angle::FormatID::R32G32B32_SNORM;
+ case angle::FormatID::R32G32B32_USCALED:
+ return angle::FormatID::R32G32B32_SSCALED;
+ case angle::FormatID::R32G32B32A32_UINT:
+ return angle::FormatID::R32G32B32A32_SINT;
+ case angle::FormatID::R32G32B32A32_UNORM:
+ return angle::FormatID::R32G32B32A32_SNORM;
+ case angle::FormatID::R32G32B32A32_USCALED:
+ return angle::FormatID::R32G32B32A32_SSCALED;
+ // 1010102 signed to unsigned
+ case angle::FormatID::R10G10B10A2_SINT:
+ return angle::FormatID::R10G10B10A2_UINT;
+ case angle::FormatID::R10G10B10A2_SSCALED:
+ return angle::FormatID::R10G10B10A2_USCALED;
+ case angle::FormatID::R10G10B10A2_SNORM:
+ return angle::FormatID::R10G10B10A2_UNORM;
+ // 1010102 unsigned to signed
+ case angle::FormatID::R10G10B10A2_UINT:
+ return angle::FormatID::R10G10B10A2_SINT;
+ case angle::FormatID::R10G10B10A2_USCALED:
+ return angle::FormatID::R10G10B10A2_SSCALED;
+ case angle::FormatID::R10G10B10A2_UNORM:
+ return angle::FormatID::R10G10B10A2_SNORM;
+ default:
+ UNREACHABLE();
+ return angle::FormatID::NONE;
+ }
+}
+
+bool ValidES3InternalFormat(GLenum internalFormat)
+{
+ const InternalFormatInfoMap &formatMap = GetInternalFormatMap();
+ return internalFormat != GL_NONE && formatMap.find(internalFormat) != formatMap.end();
+}
+
+VertexFormat::VertexFormat(GLenum typeIn,
+ GLboolean normalizedIn,
+ GLuint componentsIn,
+ bool pureIntegerIn)
+ : type(typeIn), normalized(normalizedIn), components(componentsIn), pureInteger(pureIntegerIn)
+{
+ // float -> !normalized
+ ASSERT(!(type == GL_FLOAT || type == GL_HALF_FLOAT || type == GL_FIXED) ||
+ normalized == GL_FALSE);
+}
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/formatutils.h b/gfx/angle/checkout/src/libANGLE/formatutils.h
new file mode 100644
index 0000000000..64cc42ec1f
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/formatutils.h
@@ -0,0 +1,577 @@
+//
+// Copyright 2013 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.
+//
+
+// formatutils.h: Queries for GL image formats.
+
+#ifndef LIBANGLE_FORMATUTILS_H_
+#define LIBANGLE_FORMATUTILS_H_
+
+#include <stdint.h>
+#include <cstddef>
+#include <ostream>
+
+#include "angle_gl.h"
+#include "common/android_util.h"
+#include "libANGLE/Caps.h"
+#include "libANGLE/Config.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/Version.h"
+#include "libANGLE/VertexAttribute.h"
+#include "libANGLE/angletypes.h"
+
+namespace gl
+{
+struct VertexAttribute;
+
+struct FormatType final
+{
+ FormatType();
+ FormatType(GLenum format_, GLenum type_);
+ FormatType(const FormatType &other) = default;
+ FormatType &operator=(const FormatType &other) = default;
+
+ bool operator<(const FormatType &other) const;
+
+ GLenum format;
+ GLenum type;
+};
+
+struct Type
+{
+ Type() : bytes(0), bytesShift(0), specialInterpretation(0) {}
+
+ explicit Type(uint32_t packedTypeInfo)
+ : bytes(packedTypeInfo & 0xff),
+ bytesShift((packedTypeInfo >> 8) & 0xff),
+ specialInterpretation((packedTypeInfo >> 16) & 1)
+ {}
+
+ GLuint bytes;
+ GLuint bytesShift; // Bit shift by this value to effectively divide/multiply by "bytes" in a
+ // more optimal way
+ bool specialInterpretation;
+};
+
+uint32_t GetPackedTypeInfo(GLenum type);
+
+ANGLE_INLINE GLenum GetNonLinearFormat(const GLenum format)
+{
+ switch (format)
+ {
+ case GL_BGRA8_EXT:
+ return GL_BGRA8_SRGB_ANGLEX;
+ case GL_RGBA8:
+ return GL_SRGB8_ALPHA8;
+ case GL_RGB8:
+ case GL_BGRX8_ANGLEX:
+ case GL_RGBX8_ANGLE:
+ return GL_SRGB8;
+ case GL_RGBA16F:
+ return GL_RGBA16F;
+ default:
+ return GL_NONE;
+ }
+}
+
+ANGLE_INLINE bool ColorspaceFormatOverride(const EGLenum colorspace, GLenum *rendertargetformat)
+{
+ // Override the rendertargetformat based on colorpsace
+ switch (colorspace)
+ {
+ case EGL_GL_COLORSPACE_LINEAR: // linear colorspace no translation needed
+ case EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT: // linear colorspace no translation needed
+ case EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT: // linear colorspace no translation needed
+ case EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT: // App, not the HW, will specify the
+ // transfer function
+ case EGL_GL_COLORSPACE_SCRGB_EXT: // App, not the HW, will specify the transfer function
+ // No translation
+ return true;
+ case EGL_GL_COLORSPACE_SRGB_KHR:
+ case EGL_GL_COLORSPACE_DISPLAY_P3_EXT:
+ {
+ GLenum nonLinearFormat = GetNonLinearFormat(*rendertargetformat);
+ if (nonLinearFormat != GL_NONE)
+ {
+ *rendertargetformat = nonLinearFormat;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ break;
+ default:
+ UNREACHABLE();
+ return false;
+ }
+}
+
+ANGLE_INLINE const Type GetTypeInfo(GLenum type)
+{
+ return Type(GetPackedTypeInfo(type));
+}
+
+// This helpers use tricks based on the assumption that the type has certain values.
+static_assert(static_cast<GLuint>(DrawElementsType::UnsignedByte) == 0, "Please update this code.");
+static_assert(static_cast<GLuint>(DrawElementsType::UnsignedShort) == 1,
+ "Please update this code.");
+static_assert(static_cast<GLuint>(DrawElementsType::UnsignedInt) == 2, "Please update this code.");
+ANGLE_INLINE GLuint GetDrawElementsTypeSize(DrawElementsType type)
+{
+ return (1 << static_cast<GLuint>(type));
+}
+
+ANGLE_INLINE GLuint GetDrawElementsTypeShift(DrawElementsType type)
+{
+ return static_cast<GLuint>(type);
+}
+
+// Information about an OpenGL internal format. Can be keyed on the internalFormat and type
+// members.
+struct InternalFormat
+{
+ InternalFormat();
+ InternalFormat(const InternalFormat &other);
+ InternalFormat &operator=(const InternalFormat &other);
+
+ GLuint computePixelBytes(GLenum formatType) const;
+
+ [[nodiscard]] bool computeBufferRowLength(uint32_t width, uint32_t *resultOut) const;
+ [[nodiscard]] bool computeBufferImageHeight(uint32_t height, uint32_t *resultOut) const;
+
+ [[nodiscard]] bool computeRowPitch(GLenum formatType,
+ GLsizei width,
+ GLint alignment,
+ GLint rowLength,
+ GLuint *resultOut) const;
+ [[nodiscard]] bool computeDepthPitch(GLsizei height,
+ GLint imageHeight,
+ GLuint rowPitch,
+ GLuint *resultOut) const;
+ [[nodiscard]] bool computeDepthPitch(GLenum formatType,
+ GLsizei width,
+ GLsizei height,
+ GLint alignment,
+ GLint rowLength,
+ GLint imageHeight,
+ GLuint *resultOut) const;
+
+ [[nodiscard]] bool computePalettedImageRowPitch(GLsizei width, GLuint *resultOut) const;
+
+ [[nodiscard]] bool computeCompressedImageSize(const Extents &size, GLuint *resultOut) const;
+
+ [[nodiscard]] std::pair<GLuint, GLuint> getCompressedImageMinBlocks() const;
+
+ [[nodiscard]] bool computeSkipBytes(GLenum formatType,
+ GLuint rowPitch,
+ GLuint depthPitch,
+ const PixelStoreStateBase &state,
+ bool is3D,
+ GLuint *resultOut) const;
+
+ [[nodiscard]] bool computePackUnpackEndByte(GLenum formatType,
+ const Extents &size,
+ const PixelStoreStateBase &state,
+ bool is3D,
+ GLuint *resultOut) const;
+
+ bool isLUMA() const;
+ GLenum getReadPixelsFormat(const Extensions &extensions) const;
+ GLenum getReadPixelsType(const Version &version) const;
+
+ // Support upload a portion of image?
+ bool supportSubImage() const;
+
+ ANGLE_INLINE bool isChannelSizeCompatible(GLuint redSize,
+ GLuint greenSize,
+ GLuint blueSize,
+ GLuint alphaSize) const
+ {
+ // We only check for equality in all channel sizes
+ return ((redSize == redBits) && (greenSize == greenBits) && (blueSize == blueBits) &&
+ (alphaSize == alphaBits));
+ }
+
+ // Return true if the format is a required renderbuffer format in the given version of the core
+ // spec. Note that it isn't always clear whether all the rules that apply to core required
+ // renderbuffer formats also apply to additional formats added by extensions. Because of this
+ // extension formats are conservatively not included.
+ bool isRequiredRenderbufferFormat(const Version &version) const;
+
+ bool isInt() const;
+ bool isDepthOrStencil() const;
+
+ bool operator==(const InternalFormat &other) const;
+ bool operator!=(const InternalFormat &other) const;
+
+ GLenum internalFormat;
+
+ bool sized;
+ GLenum sizedInternalFormat;
+
+ GLuint redBits;
+ GLuint greenBits;
+ GLuint blueBits;
+
+ GLuint luminanceBits;
+
+ GLuint alphaBits;
+ GLuint sharedBits;
+
+ GLuint depthBits;
+ GLuint stencilBits;
+
+ GLuint pixelBytes;
+
+ GLuint componentCount;
+
+ bool compressed;
+ GLuint compressedBlockWidth;
+ GLuint compressedBlockHeight;
+ GLuint compressedBlockDepth;
+
+ bool paletted;
+ GLuint paletteBits;
+
+ GLenum format;
+ GLenum type;
+
+ GLenum componentType;
+ GLenum colorEncoding;
+
+ typedef bool (*SupportCheckFunction)(const Version &, const Extensions &);
+ SupportCheckFunction textureSupport;
+ SupportCheckFunction filterSupport;
+ SupportCheckFunction textureAttachmentSupport; // glFramebufferTexture2D
+ SupportCheckFunction renderbufferSupport; // glFramebufferRenderbuffer
+ SupportCheckFunction blendSupport;
+};
+
+// A "Format" wraps an InternalFormat struct, querying it from either a sized internal format or
+// unsized internal format and type.
+// TODO(geofflang): Remove this, it doesn't add any more information than the InternalFormat object.
+struct Format
+{
+ // Sized types only.
+ explicit Format(GLenum internalFormat);
+
+ // Sized or unsized types.
+ explicit Format(const InternalFormat &internalFormat);
+ Format(GLenum internalFormat, GLenum type);
+
+ Format(const Format &other);
+ Format &operator=(const Format &other);
+
+ bool valid() const;
+
+ static Format Invalid();
+ static bool SameSized(const Format &a, const Format &b);
+ static bool EquivalentForBlit(const Format &a, const Format &b);
+
+ friend std::ostream &operator<<(std::ostream &os, const Format &fmt);
+
+ // This is the sized info.
+ const InternalFormat *info;
+};
+
+const InternalFormat &GetSizedInternalFormatInfo(GLenum internalFormat);
+const InternalFormat &GetInternalFormatInfo(GLenum internalFormat, GLenum type);
+
+// Strip sizing information from an internal format. Doesn't necessarily validate that the internal
+// format is valid.
+GLenum GetUnsizedFormat(GLenum internalFormat);
+
+// Return whether the compressed format requires whole image/mip level to be uploaded to texture.
+bool CompressedFormatRequiresWholeImage(GLenum internalFormat);
+
+// In support of GetImage, check for LUMA formats and override with real format
+void MaybeOverrideLuminance(GLenum &format, GLenum &type, GLenum actualFormat, GLenum actualType);
+
+typedef std::set<GLenum> FormatSet;
+const FormatSet &GetAllSizedInternalFormats();
+
+typedef angle::HashMap<GLenum, angle::HashMap<GLenum, InternalFormat>> InternalFormatInfoMap;
+const InternalFormatInfoMap &GetInternalFormatMap();
+
+int GetAndroidHardwareBufferFormatFromChannelSizes(const egl::AttributeMap &attribMap);
+
+GLenum GetConfigColorBufferFormat(const egl::Config *config);
+GLenum GetConfigDepthStencilBufferFormat(const egl::Config *config);
+
+ANGLE_INLINE int GetNativeVisualID(const InternalFormat &internalFormat)
+{
+ int nativeVisualId = 0;
+#if defined(ANGLE_PLATFORM_ANDROID)
+ nativeVisualId =
+ angle::android::GLInternalFormatToNativePixelFormat(internalFormat.internalFormat);
+#endif
+#if defined(ANGLE_PLATFORM_LINUX) && defined(ANGLE_USES_GBM)
+ nativeVisualId = angle::GLInternalFormatToGbmFourCCFormat(internalFormat.internalFormat);
+#endif
+
+ return nativeVisualId;
+}
+
+// From the ESSL 3.00.4 spec:
+// Vertex shader inputs can only be float, floating-point vectors, matrices, signed and unsigned
+// integers and integer vectors. Vertex shader inputs cannot be arrays or structures.
+
+enum AttributeType
+{
+ ATTRIBUTE_FLOAT,
+ ATTRIBUTE_VEC2,
+ ATTRIBUTE_VEC3,
+ ATTRIBUTE_VEC4,
+ ATTRIBUTE_INT,
+ ATTRIBUTE_IVEC2,
+ ATTRIBUTE_IVEC3,
+ ATTRIBUTE_IVEC4,
+ ATTRIBUTE_UINT,
+ ATTRIBUTE_UVEC2,
+ ATTRIBUTE_UVEC3,
+ ATTRIBUTE_UVEC4,
+ ATTRIBUTE_MAT2,
+ ATTRIBUTE_MAT3,
+ ATTRIBUTE_MAT4,
+ ATTRIBUTE_MAT2x3,
+ ATTRIBUTE_MAT2x4,
+ ATTRIBUTE_MAT3x2,
+ ATTRIBUTE_MAT3x4,
+ ATTRIBUTE_MAT4x2,
+ ATTRIBUTE_MAT4x3,
+};
+
+AttributeType GetAttributeType(GLenum enumValue);
+
+typedef std::vector<angle::FormatID> InputLayout;
+
+struct VertexFormat : private angle::NonCopyable
+{
+ VertexFormat(GLenum typeIn, GLboolean normalizedIn, GLuint componentsIn, bool pureIntegerIn);
+
+ GLenum type;
+ GLboolean normalized;
+ GLuint components;
+ bool pureInteger;
+};
+
+angle::FormatID GetVertexFormatID(VertexAttribType type,
+ GLboolean normalized,
+ GLuint components,
+ bool pureInteger);
+
+angle::FormatID GetVertexFormatID(const VertexAttribute &attrib, VertexAttribType currentValueType);
+angle::FormatID GetCurrentValueFormatID(VertexAttribType currentValueType);
+const VertexFormat &GetVertexFormatFromID(angle::FormatID vertexFormatID);
+size_t GetVertexFormatSize(angle::FormatID vertexFormatID);
+angle::FormatID ConvertFormatSignedness(const angle::Format &format);
+
+ANGLE_INLINE bool IsS3TCFormat(const GLenum format)
+{
+ switch (format)
+ {
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+ case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+ANGLE_INLINE bool IsRGTCFormat(const GLenum format)
+{
+ switch (format)
+ {
+ case GL_COMPRESSED_RED_RGTC1_EXT:
+ case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:
+ case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
+ case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+ANGLE_INLINE bool IsBPTCFormat(const GLenum format)
+{
+ switch (format)
+ {
+ case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
+ case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
+ case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+ANGLE_INLINE bool IsASTC2DFormat(const GLenum format)
+{
+ if ((format >= GL_COMPRESSED_RGBA_ASTC_4x4_KHR &&
+ format <= GL_COMPRESSED_RGBA_ASTC_12x12_KHR) ||
+ (format >= GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR &&
+ format <= GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR))
+ {
+ return true;
+ }
+ return false;
+}
+
+ANGLE_INLINE bool IsETC1Format(const GLenum format)
+{
+ switch (format)
+ {
+ case GL_ETC1_RGB8_OES:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+ANGLE_INLINE bool IsETC2EACFormat(const GLenum format)
+{
+ // ES 3.1, Table 8.19
+ switch (format)
+ {
+ case GL_COMPRESSED_R11_EAC:
+ case GL_COMPRESSED_SIGNED_R11_EAC:
+ case GL_COMPRESSED_RG11_EAC:
+ case GL_COMPRESSED_SIGNED_RG11_EAC:
+ case GL_COMPRESSED_RGB8_ETC2:
+ case GL_COMPRESSED_SRGB8_ETC2:
+ case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+ case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+ case GL_COMPRESSED_RGBA8_ETC2_EAC:
+ case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+ANGLE_INLINE bool IsPVRTC1Format(const GLenum format)
+{
+ switch (format)
+ {
+ case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
+ case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
+ case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
+ case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
+ case GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT:
+ case GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+ANGLE_INLINE bool IsBGRAFormat(const GLenum internalFormat)
+{
+ switch (internalFormat)
+ {
+ case GL_BGRA8_EXT:
+ case GL_BGRA4_ANGLEX:
+ case GL_BGR5_A1_ANGLEX:
+ case GL_BGRA8_SRGB_ANGLEX:
+ case GL_BGRX8_ANGLEX:
+ case GL_RGBX8_ANGLE:
+ case GL_BGR565_ANGLEX:
+ case GL_BGR10_A2_ANGLEX:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+// Check if an internal format is ever valid in ES3. Makes no checks about support for a specific
+// context.
+bool ValidES3InternalFormat(GLenum internalFormat);
+
+// Implemented in format_map_autogen.cpp
+bool ValidES3Format(GLenum format);
+bool ValidES3Type(GLenum type);
+bool ValidES3FormatCombination(GLenum format, GLenum type, GLenum internalFormat);
+
+// Implemented in format_map_desktop.cpp
+bool ValidDesktopFormat(GLenum format);
+bool ValidDesktopType(GLenum type);
+bool ValidDesktopFormatCombination(GLenum format, GLenum type, GLenum internalFormat);
+
+// Implemented in es3_copy_conversion_table_autogen.cpp
+bool ValidES3CopyConversion(GLenum textureFormat, GLenum framebufferFormat);
+
+ANGLE_INLINE ComponentType GetVertexAttributeComponentType(bool pureInteger, VertexAttribType type)
+{
+ if (pureInteger)
+ {
+ switch (type)
+ {
+ case VertexAttribType::Byte:
+ case VertexAttribType::Short:
+ case VertexAttribType::Int:
+ return ComponentType::Int;
+
+ case VertexAttribType::UnsignedByte:
+ case VertexAttribType::UnsignedShort:
+ case VertexAttribType::UnsignedInt:
+ return ComponentType::UnsignedInt;
+
+ default:
+ UNREACHABLE();
+ return ComponentType::NoType;
+ }
+ }
+ else
+ {
+ return ComponentType::Float;
+ }
+}
+
+constexpr std::size_t kMaxYuvPlaneCount = 3;
+template <typename T>
+using YuvPlaneArray = std::array<T, kMaxYuvPlaneCount>;
+
+struct YuvFormatInfo
+{
+ // Sized types only.
+ YuvFormatInfo(GLenum internalFormat, const Extents &yPlaneExtent);
+
+ GLenum glInternalFormat;
+ uint32_t planeCount;
+ YuvPlaneArray<uint32_t> planeBpp;
+ YuvPlaneArray<Extents> planeExtent;
+ YuvPlaneArray<uint32_t> planePitch;
+ YuvPlaneArray<uint32_t> planeSize;
+ YuvPlaneArray<uint32_t> planeOffset;
+};
+
+bool IsYuvFormat(GLenum format);
+uint32_t GetPlaneCount(GLenum format);
+uint32_t GetYPlaneBpp(GLenum format);
+uint32_t GetChromaPlaneBpp(GLenum format);
+void GetSubSampleFactor(GLenum format,
+ int *horizontalSubsampleFactor,
+ int *verticalSubsampleFactor);
+} // namespace gl
+
+#endif // LIBANGLE_FORMATUTILS_H_
diff --git a/gfx/angle/checkout/src/libANGLE/gles_extensions_autogen.cpp b/gfx/angle/checkout/src/libANGLE/gles_extensions_autogen.cpp
new file mode 100644
index 0000000000..0caab7e0d9
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/gles_extensions_autogen.cpp
@@ -0,0 +1,278 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_extensions.py using data from registry_xml.py and gl.xml
+//
+// Copyright 2021 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.
+//
+// gles_extensions_autogen.h: GLES extension strings information.
+
+#include "anglebase/no_destructor.h"
+#include "libANGLE/Caps.h"
+
+namespace gl
+{
+const ExtensionInfoMap &GetExtensionInfoMap()
+{
+ auto buildExtensionInfoMap = []() {
+ auto enableableExtension = [](ExtensionBool member) {
+ ExtensionInfo info;
+ info.Requestable = true;
+ info.ExtensionsMember = member;
+ return info;
+ };
+
+ auto enableableDisablableExtension = [&](ExtensionBool member) {
+ ExtensionInfo info = enableableExtension(member);
+ info.Disablable = true;
+ return info;
+ };
+
+ auto esOnlyExtension = [](ExtensionBool member) {
+ ExtensionInfo info;
+ info.ExtensionsMember = member;
+ return info;
+ };
+
+ // clang-format off
+ ExtensionInfoMap map;
+
+ // GLES 2.0 extension strings
+ // --------------------------
+ map["GL_EXT_base_instance"] = enableableExtension(&Extensions::baseInstanceEXT);
+ map["GL_KHR_blend_equation_advanced"] = esOnlyExtension(&Extensions::blendEquationAdvancedKHR);
+ map["GL_EXT_blend_func_extended"] = enableableExtension(&Extensions::blendFuncExtendedEXT);
+ map["GL_EXT_blend_minmax"] = enableableExtension(&Extensions::blendMinmaxEXT);
+ map["GL_EXT_buffer_storage"] = enableableExtension(&Extensions::bufferStorageEXT);
+ map["GL_EXT_clip_control"] = enableableExtension(&Extensions::clipControlEXT);
+ map["GL_EXT_clip_cull_distance"] = enableableExtension(&Extensions::clipCullDistanceEXT);
+ map["GL_APPLE_clip_distance"] = enableableExtension(&Extensions::clipDistanceAPPLE);
+ map["GL_EXT_color_buffer_float"] = enableableExtension(&Extensions::colorBufferFloatEXT);
+ map["GL_EXT_color_buffer_half_float"] = enableableExtension(&Extensions::colorBufferHalfFloatEXT);
+ map["GL_OES_compressed_EAC_R11_signed_texture"] = enableableExtension(&Extensions::compressedEACR11SignedTextureOES);
+ map["GL_OES_compressed_EAC_R11_unsigned_texture"] = enableableExtension(&Extensions::compressedEACR11UnsignedTextureOES);
+ map["GL_OES_compressed_EAC_RG11_signed_texture"] = enableableExtension(&Extensions::compressedEACRG11SignedTextureOES);
+ map["GL_OES_compressed_EAC_RG11_unsigned_texture"] = enableableExtension(&Extensions::compressedEACRG11UnsignedTextureOES);
+ map["GL_EXT_compressed_ETC1_RGB8_sub_texture"] = enableableExtension(&Extensions::compressedETC1RGB8SubTextureEXT);
+ map["GL_OES_compressed_ETC1_RGB8_texture"] = enableableExtension(&Extensions::compressedETC1RGB8TextureOES);
+ map["GL_OES_compressed_ETC2_punchthroughA_RGBA8_texture"] = enableableExtension(&Extensions::compressedETC2PunchthroughARGBA8TextureOES);
+ map["GL_OES_compressed_ETC2_punchthroughA_sRGB8_alpha_texture"] = enableableExtension(&Extensions::compressedETC2PunchthroughASRGB8AlphaTextureOES);
+ map["GL_OES_compressed_ETC2_RGB8_texture"] = enableableExtension(&Extensions::compressedETC2RGB8TextureOES);
+ map["GL_OES_compressed_ETC2_RGBA8_texture"] = enableableExtension(&Extensions::compressedETC2RGBA8TextureOES);
+ map["GL_OES_compressed_ETC2_sRGB8_alpha8_texture"] = enableableExtension(&Extensions::compressedETC2SRGB8Alpha8TextureOES);
+ map["GL_OES_compressed_ETC2_sRGB8_texture"] = enableableExtension(&Extensions::compressedETC2SRGB8TextureOES);
+ map["GL_OES_compressed_paletted_texture"] = enableableExtension(&Extensions::compressedPalettedTextureOES);
+ map["GL_EXT_copy_image"] = enableableExtension(&Extensions::copyImageEXT);
+ map["GL_OES_copy_image"] = enableableExtension(&Extensions::copyImageOES);
+ map["GL_KHR_debug"] = esOnlyExtension(&Extensions::debugKHR);
+ map["GL_EXT_debug_label"] = esOnlyExtension(&Extensions::debugLabelEXT);
+ map["GL_EXT_debug_marker"] = esOnlyExtension(&Extensions::debugMarkerEXT);
+ map["GL_OES_depth24"] = esOnlyExtension(&Extensions::depth24OES);
+ map["GL_OES_depth32"] = esOnlyExtension(&Extensions::depth32OES);
+ map["GL_NV_depth_buffer_float2"] = enableableExtension(&Extensions::depthBufferFloat2NV);
+ map["GL_ANGLE_depth_texture"] = esOnlyExtension(&Extensions::depthTextureANGLE);
+ map["GL_OES_depth_texture"] = esOnlyExtension(&Extensions::depthTextureOES);
+ map["GL_OES_depth_texture_cube_map"] = enableableExtension(&Extensions::depthTextureCubeMapOES);
+ map["GL_EXT_discard_framebuffer"] = esOnlyExtension(&Extensions::discardFramebufferEXT);
+ map["GL_EXT_disjoint_timer_query"] = enableableExtension(&Extensions::disjointTimerQueryEXT);
+ map["GL_EXT_draw_buffers"] = enableableExtension(&Extensions::drawBuffersEXT);
+ map["GL_EXT_draw_buffers_indexed"] = enableableExtension(&Extensions::drawBuffersIndexedEXT);
+ map["GL_OES_draw_buffers_indexed"] = enableableExtension(&Extensions::drawBuffersIndexedOES);
+ map["GL_EXT_draw_elements_base_vertex"] = enableableExtension(&Extensions::drawElementsBaseVertexEXT);
+ map["GL_OES_draw_elements_base_vertex"] = enableableExtension(&Extensions::drawElementsBaseVertexOES);
+ map["GL_OES_EGL_image"] = enableableExtension(&Extensions::EGLImageOES);
+ map["GL_EXT_EGL_image_array"] = enableableExtension(&Extensions::EGLImageArrayEXT);
+ map["GL_OES_EGL_image_external"] = enableableExtension(&Extensions::EGLImageExternalOES);
+ map["GL_OES_EGL_image_external_essl3"] = enableableExtension(&Extensions::EGLImageExternalEssl3OES);
+ map["GL_EXT_EGL_image_external_wrap_modes"] = enableableExtension(&Extensions::EGLImageExternalWrapModesEXT);
+ map["GL_EXT_EGL_image_storage"] = enableableExtension(&Extensions::EGLImageStorageEXT);
+ map["GL_NV_EGL_stream_consumer_external"] = enableableExtension(&Extensions::EGLStreamConsumerExternalNV);
+ map["GL_OES_EGL_sync"] = esOnlyExtension(&Extensions::EGLSyncOES);
+ map["GL_OES_element_index_uint"] = enableableExtension(&Extensions::elementIndexUintOES);
+ map["GL_ANDROID_extension_pack_es31a"] = esOnlyExtension(&Extensions::extensionPackEs31aANDROID);
+ map["GL_EXT_external_buffer"] = enableableExtension(&Extensions::externalBufferEXT);
+ map["GL_OES_fbo_render_mipmap"] = enableableExtension(&Extensions::fboRenderMipmapOES);
+ map["GL_NV_fence"] = esOnlyExtension(&Extensions::fenceNV);
+ map["GL_EXT_float_blend"] = enableableExtension(&Extensions::floatBlendEXT);
+ map["GL_EXT_frag_depth"] = enableableExtension(&Extensions::fragDepthEXT);
+ map["GL_ANGLE_framebuffer_blit"] = enableableExtension(&Extensions::framebufferBlitANGLE);
+ map["GL_NV_framebuffer_blit"] = enableableExtension(&Extensions::framebufferBlitNV);
+ map["GL_MESA_framebuffer_flip_y"] = enableableExtension(&Extensions::framebufferFlipYMESA);
+ map["GL_EXT_geometry_shader"] = enableableExtension(&Extensions::geometryShaderEXT);
+ map["GL_OES_geometry_shader"] = enableableExtension(&Extensions::geometryShaderOES);
+ map["GL_OES_get_program_binary"] = enableableExtension(&Extensions::getProgramBinaryOES);
+ map["GL_EXT_gpu_shader5"] = enableableExtension(&Extensions::gpuShader5EXT);
+ map["GL_ANGLE_instanced_arrays"] = enableableExtension(&Extensions::instancedArraysANGLE);
+ map["GL_EXT_instanced_arrays"] = enableableExtension(&Extensions::instancedArraysEXT);
+ map["GL_OES_mapbuffer"] = enableableExtension(&Extensions::mapbufferOES);
+ map["GL_EXT_map_buffer_range"] = enableableExtension(&Extensions::mapBufferRangeEXT);
+ map["GL_EXT_memory_object"] = enableableExtension(&Extensions::memoryObjectEXT);
+ map["GL_EXT_memory_object_fd"] = enableableExtension(&Extensions::memoryObjectFdEXT);
+ map["GL_EXT_multi_draw_indirect"] = enableableExtension(&Extensions::multiDrawIndirectEXT);
+ map["GL_EXT_multisample_compatibility"] = esOnlyExtension(&Extensions::multisampleCompatibilityEXT);
+ map["GL_EXT_multisampled_render_to_texture"] = enableableExtension(&Extensions::multisampledRenderToTextureEXT);
+ map["GL_EXT_multisampled_render_to_texture2"] = enableableExtension(&Extensions::multisampledRenderToTexture2EXT);
+ map["GL_OVR_multiview"] = enableableExtension(&Extensions::multiviewOVR);
+ map["GL_OVR_multiview2"] = enableableExtension(&Extensions::multiview2OVR);
+ map["GL_KHR_no_error"] = esOnlyExtension(&Extensions::noErrorKHR);
+ map["GL_EXT_occlusion_query_boolean"] = enableableExtension(&Extensions::occlusionQueryBooleanEXT);
+ map["GL_OES_packed_depth_stencil"] = esOnlyExtension(&Extensions::packedDepthStencilOES);
+ map["GL_ANGLE_pack_reverse_row_order"] = enableableExtension(&Extensions::packReverseRowOrderANGLE);
+ map["GL_NV_pack_subimage"] = enableableExtension(&Extensions::packSubimageNV);
+ map["GL_KHR_parallel_shader_compile"] = enableableExtension(&Extensions::parallelShaderCompileKHR);
+ map["GL_AMD_performance_monitor"] = esOnlyExtension(&Extensions::performanceMonitorAMD);
+ map["GL_NV_pixel_buffer_object"] = enableableExtension(&Extensions::pixelBufferObjectNV);
+ map["GL_EXT_primitive_bounding_box"] = esOnlyExtension(&Extensions::primitiveBoundingBoxEXT);
+ map["GL_OES_primitive_bounding_box"] = esOnlyExtension(&Extensions::primitiveBoundingBoxOES);
+ map["GL_EXT_protected_textures"] = enableableExtension(&Extensions::protectedTexturesEXT);
+ map["GL_EXT_pvrtc_sRGB"] = enableableExtension(&Extensions::pvrtcSRGBEXT);
+ map["GL_NV_read_depth"] = enableableExtension(&Extensions::readDepthNV);
+ map["GL_NV_read_depth_stencil"] = enableableExtension(&Extensions::readDepthStencilNV);
+ map["GL_EXT_read_format_bgra"] = enableableExtension(&Extensions::readFormatBgraEXT);
+ map["GL_NV_read_stencil"] = enableableExtension(&Extensions::readStencilNV);
+ map["GL_OES_rgb8_rgba8"] = enableableExtension(&Extensions::rgb8Rgba8OES);
+ map["GL_KHR_robust_buffer_access_behavior"] = esOnlyExtension(&Extensions::robustBufferAccessBehaviorKHR);
+ map["GL_EXT_robustness"] = esOnlyExtension(&Extensions::robustnessEXT);
+ map["GL_NV_robustness_video_memory_purge"] = esOnlyExtension(&Extensions::robustnessVideoMemoryPurgeNV);
+ map["GL_OES_sample_shading"] = enableableExtension(&Extensions::sampleShadingOES);
+ map["GL_OES_sample_variables"] = enableableExtension(&Extensions::sampleVariablesOES);
+ map["GL_EXT_semaphore"] = enableableExtension(&Extensions::semaphoreEXT);
+ map["GL_EXT_semaphore_fd"] = enableableExtension(&Extensions::semaphoreFdEXT);
+ map["GL_EXT_separate_shader_objects"] = enableableExtension(&Extensions::separateShaderObjectsEXT);
+ map["GL_EXT_shader_framebuffer_fetch"] = enableableExtension(&Extensions::shaderFramebufferFetchEXT);
+ map["GL_EXT_shader_framebuffer_fetch_non_coherent"] = enableableExtension(&Extensions::shaderFramebufferFetchNonCoherentEXT);
+ map["GL_OES_shader_image_atomic"] = enableableExtension(&Extensions::shaderImageAtomicOES);
+ map["GL_EXT_shader_io_blocks"] = enableableExtension(&Extensions::shaderIoBlocksEXT);
+ map["GL_OES_shader_io_blocks"] = enableableExtension(&Extensions::shaderIoBlocksOES);
+ map["GL_OES_shader_multisample_interpolation"] = enableableExtension(&Extensions::shaderMultisampleInterpolationOES);
+ map["GL_EXT_shader_non_constant_global_initializers"] = enableableExtension(&Extensions::shaderNonConstantGlobalInitializersEXT);
+ map["GL_NV_shader_noperspective_interpolation"] = enableableExtension(&Extensions::shaderNoperspectiveInterpolationNV);
+ map["GL_EXT_shader_texture_lod"] = enableableExtension(&Extensions::shaderTextureLodEXT);
+ map["GL_QCOM_shading_rate"] = enableableExtension(&Extensions::shadingRateQCOM);
+ map["GL_EXT_shadow_samplers"] = enableableExtension(&Extensions::shadowSamplersEXT);
+ map["GL_EXT_sRGB"] = enableableExtension(&Extensions::sRGBEXT);
+ map["GL_EXT_sRGB_write_control"] = esOnlyExtension(&Extensions::sRGBWriteControlEXT);
+ map["GL_OES_standard_derivatives"] = enableableExtension(&Extensions::standardDerivativesOES);
+ map["GL_OES_surfaceless_context"] = esOnlyExtension(&Extensions::surfacelessContextOES);
+ map["GL_ARB_sync"] = enableableExtension(&Extensions::syncARB);
+ map["GL_EXT_tessellation_shader"] = enableableExtension(&Extensions::tessellationShaderEXT);
+ map["GL_OES_texture_3D"] = enableableExtension(&Extensions::texture3DOES);
+ map["GL_EXT_texture_border_clamp"] = enableableExtension(&Extensions::textureBorderClampEXT);
+ map["GL_OES_texture_border_clamp"] = enableableExtension(&Extensions::textureBorderClampOES);
+ map["GL_EXT_texture_buffer"] = enableableExtension(&Extensions::textureBufferEXT);
+ map["GL_OES_texture_buffer"] = enableableExtension(&Extensions::textureBufferOES);
+ map["GL_OES_texture_compression_astc"] = enableableExtension(&Extensions::textureCompressionAstcOES);
+ map["GL_KHR_texture_compression_astc_hdr"] = enableableExtension(&Extensions::textureCompressionAstcHdrKHR);
+ map["GL_KHR_texture_compression_astc_ldr"] = enableableExtension(&Extensions::textureCompressionAstcLdrKHR);
+ map["GL_KHR_texture_compression_astc_sliced_3d"] = enableableExtension(&Extensions::textureCompressionAstcSliced3dKHR);
+ map["GL_EXT_texture_compression_bptc"] = enableableExtension(&Extensions::textureCompressionBptcEXT);
+ map["GL_EXT_texture_compression_dxt1"] = enableableExtension(&Extensions::textureCompressionDxt1EXT);
+ map["GL_IMG_texture_compression_pvrtc"] = enableableExtension(&Extensions::textureCompressionPvrtcIMG);
+ map["GL_IMG_texture_compression_pvrtc2"] = enableableExtension(&Extensions::textureCompressionPvrtc2IMG);
+ map["GL_EXT_texture_compression_rgtc"] = enableableExtension(&Extensions::textureCompressionRgtcEXT);
+ map["GL_EXT_texture_compression_s3tc"] = enableableExtension(&Extensions::textureCompressionS3tcEXT);
+ map["GL_EXT_texture_compression_s3tc_srgb"] = enableableExtension(&Extensions::textureCompressionS3tcSrgbEXT);
+ map["GL_EXT_texture_cube_map_array"] = enableableExtension(&Extensions::textureCubeMapArrayEXT);
+ map["GL_OES_texture_cube_map_array"] = enableableExtension(&Extensions::textureCubeMapArrayOES);
+ map["GL_EXT_texture_filter_anisotropic"] = enableableExtension(&Extensions::textureFilterAnisotropicEXT);
+ map["GL_OES_texture_float"] = enableableExtension(&Extensions::textureFloatOES);
+ map["GL_OES_texture_float_linear"] = enableableExtension(&Extensions::textureFloatLinearOES);
+ map["GL_EXT_texture_format_BGRA8888"] = enableableExtension(&Extensions::textureFormatBGRA8888EXT);
+ map["GL_EXT_texture_format_sRGB_override"] = esOnlyExtension(&Extensions::textureFormatSRGBOverrideEXT);
+ map["GL_OES_texture_half_float"] = enableableExtension(&Extensions::textureHalfFloatOES);
+ map["GL_OES_texture_half_float_linear"] = enableableExtension(&Extensions::textureHalfFloatLinearOES);
+ map["GL_EXT_texture_norm16"] = enableableExtension(&Extensions::textureNorm16EXT);
+ map["GL_OES_texture_npot"] = enableableExtension(&Extensions::textureNpotOES);
+ map["GL_EXT_texture_rg"] = enableableExtension(&Extensions::textureRgEXT);
+ map["GL_EXT_texture_sRGB_decode"] = esOnlyExtension(&Extensions::textureSRGBDecodeEXT);
+ map["GL_EXT_texture_sRGB_R8"] = enableableExtension(&Extensions::textureSRGBR8EXT);
+ map["GL_EXT_texture_sRGB_RG8"] = enableableExtension(&Extensions::textureSRGBRG8EXT);
+ map["GL_OES_texture_stencil8"] = enableableExtension(&Extensions::textureStencil8OES);
+ map["GL_EXT_texture_storage"] = enableableExtension(&Extensions::textureStorageEXT);
+ map["GL_OES_texture_storage_multisample_2d_array"] = enableableExtension(&Extensions::textureStorageMultisample2dArrayOES);
+ map["GL_EXT_texture_type_2_10_10_10_REV"] = enableableExtension(&Extensions::textureType2101010REVEXT);
+ map["GL_ANGLE_texture_usage"] = enableableExtension(&Extensions::textureUsageANGLE);
+ map["GL_ANGLE_translated_shader_source"] = esOnlyExtension(&Extensions::translatedShaderSourceANGLE);
+ map["GL_EXT_unpack_subimage"] = enableableExtension(&Extensions::unpackSubimageEXT);
+ map["GL_OES_vertex_array_object"] = enableableExtension(&Extensions::vertexArrayObjectOES);
+ map["GL_OES_vertex_half_float"] = enableableExtension(&Extensions::vertexHalfFloatOES);
+ map["GL_OES_vertex_type_10_10_10_2"] = enableableExtension(&Extensions::vertexType1010102OES);
+ map["GL_WEBGL_video_texture"] = enableableExtension(&Extensions::videoTextureWEBGL);
+ map["GL_EXT_YUV_target"] = enableableExtension(&Extensions::YUVTargetEXT);
+
+ // ANGLE unofficial extension strings
+ // ----------------------------------
+ map["GL_ANGLE_base_vertex_base_instance"] = enableableExtension(&Extensions::baseVertexBaseInstanceANGLE);
+ map["GL_ANGLE_base_vertex_base_instance_shader_builtin"] = enableableExtension(&Extensions::baseVertexBaseInstanceShaderBuiltinANGLE);
+ map["GL_CHROMIUM_bind_generates_resource"] = esOnlyExtension(&Extensions::bindGeneratesResourceCHROMIUM);
+ map["GL_CHROMIUM_bind_uniform_location"] = esOnlyExtension(&Extensions::bindUniformLocationCHROMIUM);
+ map["GL_ANGLE_client_arrays"] = esOnlyExtension(&Extensions::clientArraysANGLE);
+ map["GL_CHROMIUM_color_buffer_float_rgb"] = enableableExtension(&Extensions::colorBufferFloatRgbCHROMIUM);
+ map["GL_CHROMIUM_color_buffer_float_rgba"] = enableableExtension(&Extensions::colorBufferFloatRgbaCHROMIUM);
+ map["GL_ANGLE_compressed_texture_etc"] = enableableExtension(&Extensions::compressedTextureEtcANGLE);
+ map["GL_CHROMIUM_copy_compressed_texture"] = esOnlyExtension(&Extensions::copyCompressedTextureCHROMIUM);
+ map["GL_CHROMIUM_copy_texture"] = esOnlyExtension(&Extensions::copyTextureCHROMIUM);
+ map["GL_ANGLE_copy_texture_3d"] = enableableExtension(&Extensions::copyTexture3dANGLE);
+ map["GL_CHROMIUM_framebuffer_mixed_samples"] = esOnlyExtension(&Extensions::framebufferMixedSamplesCHROMIUM);
+ map["GL_ANGLE_framebuffer_multisample"] = enableableExtension(&Extensions::framebufferMultisampleANGLE);
+ map["GL_ANGLE_get_image"] = enableableExtension(&Extensions::getImageANGLE);
+ map["GL_ANGLE_get_serialized_context_string"] = esOnlyExtension(&Extensions::getSerializedContextStringANGLE);
+ map["GL_ANGLE_get_tex_level_parameter"] = enableableExtension(&Extensions::getTexLevelParameterANGLE);
+ map["GL_ANGLE_logic_op"] = enableableExtension(&Extensions::logicOpANGLE);
+ map["GL_CHROMIUM_lose_context"] = enableableExtension(&Extensions::loseContextCHROMIUM);
+ map["GL_ANGLE_lossy_etc_decode"] = enableableExtension(&Extensions::lossyEtcDecodeANGLE);
+ map["GL_ANGLE_memory_object_flags"] = enableableExtension(&Extensions::memoryObjectFlagsANGLE);
+ map["GL_ANGLE_memory_object_fuchsia"] = enableableExtension(&Extensions::memoryObjectFuchsiaANGLE);
+ map["GL_ANGLE_memory_size"] = enableableExtension(&Extensions::memorySizeANGLE);
+ map["GL_ANGLE_multi_draw"] = enableableExtension(&Extensions::multiDrawANGLE);
+ map["GL_ANGLE_multiview_multisample"] = enableableExtension(&Extensions::multiviewMultisampleANGLE);
+ map["GL_ANGLE_program_binary"] = esOnlyExtension(&Extensions::programBinaryANGLE);
+ map["GL_ANGLE_program_cache_control"] = esOnlyExtension(&Extensions::programCacheControlANGLE);
+ map["GL_ANGLE_provoking_vertex"] = enableableExtension(&Extensions::provokingVertexANGLE);
+ map["GL_ANGLE_read_only_depth_stencil_feedback_loops"] = enableableExtension(&Extensions::readOnlyDepthStencilFeedbackLoopsANGLE);
+ map["GL_ANGLE_relaxed_vertex_attribute_type"] = esOnlyExtension(&Extensions::relaxedVertexAttributeTypeANGLE);
+ map["GL_ANGLE_request_extension"] = esOnlyExtension(&Extensions::requestExtensionANGLE);
+ map["GL_ANGLE_rgbx_internal_format"] = esOnlyExtension(&Extensions::rgbxInternalFormatANGLE);
+ map["GL_ANGLE_robust_client_memory"] = esOnlyExtension(&Extensions::robustClientMemoryANGLE);
+ map["GL_ANGLE_robust_fragment_shader_output"] = enableableExtension(&Extensions::robustFragmentShaderOutputANGLE);
+ map["GL_ANGLE_robust_resource_initialization"] = esOnlyExtension(&Extensions::robustResourceInitializationANGLE);
+ map["GL_ANGLE_semaphore_fuchsia"] = enableableExtension(&Extensions::semaphoreFuchsiaANGLE);
+ map["GL_ANGLE_shader_pixel_local_storage"] = esOnlyExtension(&Extensions::shaderPixelLocalStorageANGLE);
+ map["GL_ANGLE_shader_pixel_local_storage_coherent"] = esOnlyExtension(&Extensions::shaderPixelLocalStorageCoherentANGLE);
+ map["GL_CHROMIUM_sync_query"] = enableableExtension(&Extensions::syncQueryCHROMIUM);
+ map["GL_ANGLE_texture_compression_dxt3"] = enableableExtension(&Extensions::textureCompressionDxt3ANGLE);
+ map["GL_ANGLE_texture_compression_dxt5"] = enableableExtension(&Extensions::textureCompressionDxt5ANGLE);
+ map["GL_ANGLE_texture_external_update"] = enableableExtension(&Extensions::textureExternalUpdateANGLE);
+ map["GL_CHROMIUM_texture_filtering_hint"] = enableableExtension(&Extensions::textureFilteringHintCHROMIUM);
+ map["GL_ANGLE_texture_multisample"] = enableableExtension(&Extensions::textureMultisampleANGLE);
+ map["GL_ANGLE_texture_rectangle"] = enableableDisablableExtension(&Extensions::textureRectangleANGLE);
+ map["GL_ANGLE_vulkan_image"] = enableableExtension(&Extensions::vulkanImageANGLE);
+ map["GL_ANGLE_webgl_compatibility"] = esOnlyExtension(&Extensions::webglCompatibilityANGLE);
+ map["GL_ANGLE_yuv_internal_format"] = enableableExtension(&Extensions::yuvInternalFormatANGLE);
+
+ // GLES 1.0 and 1.1 extension strings
+ // ----------------------------------
+ map["GL_OES_draw_texture"] = enableableExtension(&Extensions::drawTextureOES);
+ map["GL_OES_framebuffer_object"] = enableableExtension(&Extensions::framebufferObjectOES);
+ map["GL_OES_matrix_palette"] = enableableExtension(&Extensions::matrixPaletteOES);
+ map["GL_OES_point_size_array"] = enableableExtension(&Extensions::pointSizeArrayOES);
+ map["GL_OES_point_sprite"] = enableableExtension(&Extensions::pointSpriteOES);
+ map["GL_OES_query_matrix"] = enableableExtension(&Extensions::queryMatrixOES);
+ map["GL_OES_texture_cube_map"] = enableableExtension(&Extensions::textureCubeMapOES);
+ // clang-format on
+
+#if defined(ANGLE_ENABLE_ASSERTS)
+ // Verify all extension strings start with GL_
+ for (const auto &extension : map)
+ {
+ ASSERT(extension.first.rfind("GL_", 0) == 0);
+ }
+#endif
+
+ return map;
+ };
+
+ static const angle::base::NoDestructor<ExtensionInfoMap> extensionInfo(buildExtensionInfoMap());
+ return *extensionInfo;
+}
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/gles_extensions_autogen.h b/gfx/angle/checkout/src/libANGLE/gles_extensions_autogen.h
new file mode 100644
index 0000000000..00994189a3
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/gles_extensions_autogen.h
@@ -0,0 +1,727 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_extensions.py using data from registry_xml.py and gl.xml
+//
+// Copyright 2021 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.
+//
+// gles_extensions_autogen.h: GLES extension information.
+
+#ifndef LIBANGLE_GLES_EXTENSIONS_AUTOGEN_H_
+#define LIBANGLE_GLES_EXTENSIONS_AUTOGEN_H_
+
+namespace gl
+{
+class TextureCapsMap;
+
+struct Extensions
+{
+ Extensions();
+ Extensions(const Extensions &other);
+
+ Extensions &operator=(const Extensions &other);
+
+ // Generate a vector of supported extension strings
+ std::vector<std::string> getStrings() const;
+
+ // Set all texture related extension support based on the supported textures.
+ // Determines support for:
+ // GL_OES_packed_depth_stencil
+ // GL_OES_rgb8_rgba8
+ // GL_EXT_texture_format_BGRA8888
+ // GL_EXT_color_buffer_half_float,
+ // GL_OES_texture_half_float, GL_OES_texture_half_float_linear
+ // GL_OES_texture_float, GL_OES_texture_float_linear
+ // GL_EXT_texture_rg
+ // GL_EXT_texture_type_2_10_10_10_REV
+ // GL_EXT_texture_compression_dxt1, GL_ANGLE_texture_compression_dxt3,
+ // GL_ANGLE_texture_compression_dxt5
+ // GL_KHR_texture_compression_astc_ldr, GL_OES_texture_compression_astc.
+ // NOTE: GL_KHR_texture_compression_astc_hdr must be enabled separately. Support for the
+ // HDR profile cannot be determined from the format enums alone.
+ // GL_OES_compressed_ETC1_RGB8_texture
+ // GL_EXT_sRGB
+ // GL_ANGLE_depth_texture, GL_OES_depth32
+ // GL_EXT_color_buffer_float
+ // GL_EXT_texture_norm16
+ // GL_EXT_texture_compression_bptc
+ // GL_EXT_texture_compression_rgtc
+ void setTextureExtensionSupport(const TextureCapsMap &textureCaps);
+
+ // Helper functions
+ bool copyImageAny() const { return (copyImageEXT || copyImageOES); }
+ bool depthTextureAny() const { return (depthTextureANGLE || depthTextureOES); }
+ bool drawBuffersIndexedAny() const { return (drawBuffersIndexedEXT || drawBuffersIndexedOES); }
+ bool drawElementsBaseVertexAny() const
+ {
+ return (drawElementsBaseVertexEXT || drawElementsBaseVertexOES);
+ }
+ bool framebufferBlitAny() const { return (framebufferBlitANGLE || framebufferBlitNV); }
+ bool geometryShaderAny() const { return (geometryShaderEXT || geometryShaderOES); }
+ bool instancedArraysAny() const { return (instancedArraysANGLE || instancedArraysEXT); }
+ bool primitiveBoundingBoxAny() const
+ {
+ return (primitiveBoundingBoxEXT || primitiveBoundingBoxOES);
+ }
+ bool shaderIoBlocksAny() const { return (shaderIoBlocksEXT || shaderIoBlocksOES); }
+ bool textureBorderClampAny() const { return (textureBorderClampEXT || textureBorderClampOES); }
+ bool textureBufferAny() const { return (textureBufferEXT || textureBufferOES); }
+ bool textureCubeMapArrayAny() const
+ {
+ return (textureCubeMapArrayEXT || textureCubeMapArrayOES);
+ }
+
+ // GLES 2.0+ extensions
+ // --------------------
+
+ // GL_EXT_base_instance
+ bool baseInstanceEXT = false;
+
+ // GL_KHR_blend_equation_advanced
+ bool blendEquationAdvancedKHR = false;
+
+ // GL_EXT_blend_func_extended
+ bool blendFuncExtendedEXT = false;
+
+ // GL_EXT_blend_minmax
+ bool blendMinmaxEXT = false;
+
+ // GL_EXT_buffer_storage
+ bool bufferStorageEXT = false;
+
+ // GL_EXT_clip_control
+ bool clipControlEXT = false;
+
+ // GL_EXT_clip_cull_distance
+ bool clipCullDistanceEXT = false;
+
+ // GL_APPLE_clip_distance
+ bool clipDistanceAPPLE = false;
+
+ // GL_EXT_color_buffer_float
+ bool colorBufferFloatEXT = false;
+
+ // GL_EXT_color_buffer_half_float
+ bool colorBufferHalfFloatEXT = false;
+
+ // GL_OES_compressed_EAC_R11_signed_texture
+ bool compressedEACR11SignedTextureOES = false;
+
+ // GL_OES_compressed_EAC_R11_unsigned_texture
+ bool compressedEACR11UnsignedTextureOES = false;
+
+ // GL_OES_compressed_EAC_RG11_signed_texture
+ bool compressedEACRG11SignedTextureOES = false;
+
+ // GL_OES_compressed_EAC_RG11_unsigned_texture
+ bool compressedEACRG11UnsignedTextureOES = false;
+
+ // GL_EXT_compressed_ETC1_RGB8_sub_texture
+ bool compressedETC1RGB8SubTextureEXT = false;
+
+ // GL_OES_compressed_ETC1_RGB8_texture
+ bool compressedETC1RGB8TextureOES = false;
+
+ // GL_OES_compressed_ETC2_punchthroughA_RGBA8_texture
+ bool compressedETC2PunchthroughARGBA8TextureOES = false;
+
+ // GL_OES_compressed_ETC2_punchthroughA_sRGB8_alpha_texture
+ bool compressedETC2PunchthroughASRGB8AlphaTextureOES = false;
+
+ // GL_OES_compressed_ETC2_RGB8_texture
+ bool compressedETC2RGB8TextureOES = false;
+
+ // GL_OES_compressed_ETC2_RGBA8_texture
+ bool compressedETC2RGBA8TextureOES = false;
+
+ // GL_OES_compressed_ETC2_sRGB8_alpha8_texture
+ bool compressedETC2SRGB8Alpha8TextureOES = false;
+
+ // GL_OES_compressed_ETC2_sRGB8_texture
+ bool compressedETC2SRGB8TextureOES = false;
+
+ // GL_OES_compressed_paletted_texture
+ bool compressedPalettedTextureOES = false;
+
+ // GL_EXT_copy_image
+ bool copyImageEXT = false;
+
+ // GL_OES_copy_image
+ bool copyImageOES = false;
+
+ // GL_KHR_debug
+ bool debugKHR = false;
+
+ // GL_EXT_debug_label
+ bool debugLabelEXT = false;
+
+ // GL_EXT_debug_marker
+ bool debugMarkerEXT = false;
+
+ // GL_OES_depth24
+ bool depth24OES = false;
+
+ // GL_OES_depth32
+ bool depth32OES = false;
+
+ // GL_NV_depth_buffer_float2
+ bool depthBufferFloat2NV = false;
+
+ // GL_ANGLE_depth_texture
+ bool depthTextureANGLE = false;
+
+ // GL_OES_depth_texture
+ bool depthTextureOES = false;
+
+ // GL_OES_depth_texture_cube_map
+ bool depthTextureCubeMapOES = false;
+
+ // GL_EXT_discard_framebuffer
+ bool discardFramebufferEXT = false;
+
+ // GL_EXT_disjoint_timer_query
+ bool disjointTimerQueryEXT = false;
+
+ // GL_EXT_draw_buffers
+ bool drawBuffersEXT = false;
+
+ // GL_EXT_draw_buffers_indexed
+ bool drawBuffersIndexedEXT = false;
+
+ // GL_OES_draw_buffers_indexed
+ bool drawBuffersIndexedOES = false;
+
+ // GL_EXT_draw_elements_base_vertex
+ bool drawElementsBaseVertexEXT = false;
+
+ // GL_OES_draw_elements_base_vertex
+ bool drawElementsBaseVertexOES = false;
+
+ // GL_OES_EGL_image
+ bool EGLImageOES = false;
+
+ // GL_EXT_EGL_image_array
+ bool EGLImageArrayEXT = false;
+
+ // GL_OES_EGL_image_external
+ bool EGLImageExternalOES = false;
+
+ // GL_OES_EGL_image_external_essl3
+ bool EGLImageExternalEssl3OES = false;
+
+ // GL_EXT_EGL_image_external_wrap_modes
+ bool EGLImageExternalWrapModesEXT = false;
+
+ // GL_EXT_EGL_image_storage
+ bool EGLImageStorageEXT = false;
+
+ // GL_NV_EGL_stream_consumer_external
+ bool EGLStreamConsumerExternalNV = false;
+
+ // GL_OES_EGL_sync
+ bool EGLSyncOES = false;
+
+ // GL_OES_element_index_uint
+ bool elementIndexUintOES = false;
+
+ // GL_ANDROID_extension_pack_es31a
+ bool extensionPackEs31aANDROID = false;
+
+ // GL_EXT_external_buffer
+ bool externalBufferEXT = false;
+
+ // GL_OES_fbo_render_mipmap
+ bool fboRenderMipmapOES = false;
+
+ // GL_NV_fence
+ bool fenceNV = false;
+
+ // GL_EXT_float_blend
+ bool floatBlendEXT = false;
+
+ // GL_EXT_frag_depth
+ bool fragDepthEXT = false;
+
+ // GL_ANGLE_framebuffer_blit
+ bool framebufferBlitANGLE = false;
+
+ // GL_NV_framebuffer_blit
+ bool framebufferBlitNV = false;
+
+ // GL_MESA_framebuffer_flip_y
+ bool framebufferFlipYMESA = false;
+
+ // GL_EXT_geometry_shader
+ bool geometryShaderEXT = false;
+
+ // GL_OES_geometry_shader
+ bool geometryShaderOES = false;
+
+ // GL_OES_get_program_binary
+ bool getProgramBinaryOES = false;
+
+ // GL_EXT_gpu_shader5
+ bool gpuShader5EXT = false;
+
+ // GL_ANGLE_instanced_arrays
+ bool instancedArraysANGLE = false;
+
+ // GL_EXT_instanced_arrays
+ bool instancedArraysEXT = false;
+
+ // GL_OES_mapbuffer
+ bool mapbufferOES = false;
+
+ // GL_EXT_map_buffer_range
+ bool mapBufferRangeEXT = false;
+
+ // GL_EXT_memory_object
+ bool memoryObjectEXT = false;
+
+ // GL_EXT_memory_object_fd
+ bool memoryObjectFdEXT = false;
+
+ // GL_EXT_multi_draw_indirect
+ bool multiDrawIndirectEXT = false;
+
+ // GL_EXT_multisample_compatibility
+ bool multisampleCompatibilityEXT = false;
+
+ // GL_EXT_multisampled_render_to_texture
+ bool multisampledRenderToTextureEXT = false;
+
+ // GL_EXT_multisampled_render_to_texture2
+ bool multisampledRenderToTexture2EXT = false;
+
+ // GL_OVR_multiview
+ bool multiviewOVR = false;
+
+ // GL_OVR_multiview2
+ bool multiview2OVR = false;
+
+ // GL_KHR_no_error
+ bool noErrorKHR = false;
+
+ // GL_EXT_occlusion_query_boolean
+ bool occlusionQueryBooleanEXT = false;
+
+ // GL_OES_packed_depth_stencil
+ bool packedDepthStencilOES = false;
+
+ // GL_ANGLE_pack_reverse_row_order
+ bool packReverseRowOrderANGLE = false;
+
+ // GL_NV_pack_subimage
+ bool packSubimageNV = false;
+
+ // GL_KHR_parallel_shader_compile
+ bool parallelShaderCompileKHR = false;
+
+ // GL_AMD_performance_monitor
+ bool performanceMonitorAMD = false;
+
+ // GL_NV_pixel_buffer_object
+ bool pixelBufferObjectNV = false;
+
+ // GL_EXT_primitive_bounding_box
+ bool primitiveBoundingBoxEXT = false;
+
+ // GL_OES_primitive_bounding_box
+ bool primitiveBoundingBoxOES = false;
+
+ // GL_EXT_protected_textures
+ bool protectedTexturesEXT = false;
+
+ // GL_EXT_pvrtc_sRGB
+ bool pvrtcSRGBEXT = false;
+
+ // GL_NV_read_depth
+ bool readDepthNV = false;
+
+ // GL_NV_read_depth_stencil
+ bool readDepthStencilNV = false;
+
+ // GL_EXT_read_format_bgra
+ bool readFormatBgraEXT = false;
+
+ // GL_NV_read_stencil
+ bool readStencilNV = false;
+
+ // GL_OES_rgb8_rgba8
+ bool rgb8Rgba8OES = false;
+
+ // GL_KHR_robust_buffer_access_behavior
+ bool robustBufferAccessBehaviorKHR = false;
+
+ // GL_EXT_robustness
+ bool robustnessEXT = false;
+
+ // GL_NV_robustness_video_memory_purge
+ bool robustnessVideoMemoryPurgeNV = false;
+
+ // GL_OES_sample_shading
+ bool sampleShadingOES = false;
+
+ // GL_OES_sample_variables
+ bool sampleVariablesOES = false;
+
+ // GL_EXT_semaphore
+ bool semaphoreEXT = false;
+
+ // GL_EXT_semaphore_fd
+ bool semaphoreFdEXT = false;
+
+ // GL_EXT_separate_shader_objects
+ bool separateShaderObjectsEXT = false;
+
+ // GL_EXT_shader_framebuffer_fetch
+ bool shaderFramebufferFetchEXT = false;
+
+ // GL_EXT_shader_framebuffer_fetch_non_coherent
+ bool shaderFramebufferFetchNonCoherentEXT = false;
+
+ // GL_OES_shader_image_atomic
+ bool shaderImageAtomicOES = false;
+
+ // GL_EXT_shader_io_blocks
+ bool shaderIoBlocksEXT = false;
+
+ // GL_OES_shader_io_blocks
+ bool shaderIoBlocksOES = false;
+
+ // GL_OES_shader_multisample_interpolation
+ bool shaderMultisampleInterpolationOES = false;
+
+ // GL_EXT_shader_non_constant_global_initializers
+ bool shaderNonConstantGlobalInitializersEXT = false;
+
+ // GL_NV_shader_noperspective_interpolation
+ bool shaderNoperspectiveInterpolationNV = false;
+
+ // GL_EXT_shader_texture_lod
+ bool shaderTextureLodEXT = false;
+
+ // GL_QCOM_shading_rate
+ bool shadingRateQCOM = false;
+
+ // GL_EXT_shadow_samplers
+ bool shadowSamplersEXT = false;
+
+ // GL_EXT_sRGB
+ bool sRGBEXT = false;
+
+ // GL_EXT_sRGB_write_control
+ bool sRGBWriteControlEXT = false;
+
+ // GL_OES_standard_derivatives
+ bool standardDerivativesOES = false;
+
+ // GL_OES_surfaceless_context
+ bool surfacelessContextOES = false;
+
+ // GL_ARB_sync
+ bool syncARB = false;
+
+ // GL_EXT_tessellation_shader
+ bool tessellationShaderEXT = false;
+
+ // GL_OES_texture_3D
+ bool texture3DOES = false;
+
+ // GL_EXT_texture_border_clamp
+ bool textureBorderClampEXT = false;
+
+ // GL_OES_texture_border_clamp
+ bool textureBorderClampOES = false;
+
+ // GL_EXT_texture_buffer
+ bool textureBufferEXT = false;
+
+ // GL_OES_texture_buffer
+ bool textureBufferOES = false;
+
+ // GL_OES_texture_compression_astc
+ bool textureCompressionAstcOES = false;
+
+ // GL_KHR_texture_compression_astc_hdr
+ bool textureCompressionAstcHdrKHR = false;
+
+ // GL_KHR_texture_compression_astc_ldr
+ bool textureCompressionAstcLdrKHR = false;
+
+ // GL_KHR_texture_compression_astc_sliced_3d
+ bool textureCompressionAstcSliced3dKHR = false;
+
+ // GL_EXT_texture_compression_bptc
+ bool textureCompressionBptcEXT = false;
+
+ // GL_EXT_texture_compression_dxt1
+ bool textureCompressionDxt1EXT = false;
+
+ // GL_IMG_texture_compression_pvrtc
+ bool textureCompressionPvrtcIMG = false;
+
+ // GL_IMG_texture_compression_pvrtc2
+ bool textureCompressionPvrtc2IMG = false;
+
+ // GL_EXT_texture_compression_rgtc
+ bool textureCompressionRgtcEXT = false;
+
+ // GL_EXT_texture_compression_s3tc
+ bool textureCompressionS3tcEXT = false;
+
+ // GL_EXT_texture_compression_s3tc_srgb
+ bool textureCompressionS3tcSrgbEXT = false;
+
+ // GL_EXT_texture_cube_map_array
+ bool textureCubeMapArrayEXT = false;
+
+ // GL_OES_texture_cube_map_array
+ bool textureCubeMapArrayOES = false;
+
+ // GL_EXT_texture_filter_anisotropic
+ bool textureFilterAnisotropicEXT = false;
+
+ // GL_OES_texture_float
+ bool textureFloatOES = false;
+
+ // GL_OES_texture_float_linear
+ bool textureFloatLinearOES = false;
+
+ // GL_EXT_texture_format_BGRA8888
+ bool textureFormatBGRA8888EXT = false;
+
+ // GL_EXT_texture_format_sRGB_override
+ bool textureFormatSRGBOverrideEXT = false;
+
+ // GL_OES_texture_half_float
+ bool textureHalfFloatOES = false;
+
+ // GL_OES_texture_half_float_linear
+ bool textureHalfFloatLinearOES = false;
+
+ // GL_EXT_texture_norm16
+ bool textureNorm16EXT = false;
+
+ // GL_OES_texture_npot
+ bool textureNpotOES = false;
+
+ // GL_EXT_texture_rg
+ bool textureRgEXT = false;
+
+ // GL_EXT_texture_sRGB_decode
+ bool textureSRGBDecodeEXT = false;
+
+ // GL_EXT_texture_sRGB_R8
+ bool textureSRGBR8EXT = false;
+
+ // GL_EXT_texture_sRGB_RG8
+ bool textureSRGBRG8EXT = false;
+
+ // GL_OES_texture_stencil8
+ bool textureStencil8OES = false;
+
+ // GL_EXT_texture_storage
+ bool textureStorageEXT = false;
+
+ // GL_OES_texture_storage_multisample_2d_array
+ bool textureStorageMultisample2dArrayOES = false;
+
+ // GL_EXT_texture_type_2_10_10_10_REV
+ bool textureType2101010REVEXT = false;
+
+ // GL_ANGLE_texture_usage
+ bool textureUsageANGLE = false;
+
+ // GL_ANGLE_translated_shader_source
+ bool translatedShaderSourceANGLE = false;
+
+ // GL_EXT_unpack_subimage
+ bool unpackSubimageEXT = false;
+
+ // GL_OES_vertex_array_object
+ bool vertexArrayObjectOES = false;
+
+ // GL_OES_vertex_half_float
+ bool vertexHalfFloatOES = false;
+
+ // GL_OES_vertex_type_10_10_10_2
+ bool vertexType1010102OES = false;
+
+ // GL_WEBGL_video_texture
+ bool videoTextureWEBGL = false;
+
+ // GL_EXT_YUV_target
+ bool YUVTargetEXT = false;
+
+ // ANGLE unofficial extensions
+ // ---------------------------
+
+ // GL_ANGLE_base_vertex_base_instance
+ bool baseVertexBaseInstanceANGLE = false;
+
+ // GL_ANGLE_base_vertex_base_instance_shader_builtin
+ bool baseVertexBaseInstanceShaderBuiltinANGLE = false;
+
+ // GL_CHROMIUM_bind_generates_resource
+ bool bindGeneratesResourceCHROMIUM = false;
+
+ // GL_CHROMIUM_bind_uniform_location
+ bool bindUniformLocationCHROMIUM = false;
+
+ // GL_ANGLE_client_arrays
+ bool clientArraysANGLE = false;
+
+ // GL_CHROMIUM_color_buffer_float_rgb
+ bool colorBufferFloatRgbCHROMIUM = false;
+
+ // GL_CHROMIUM_color_buffer_float_rgba
+ bool colorBufferFloatRgbaCHROMIUM = false;
+
+ // GL_ANGLE_compressed_texture_etc
+ bool compressedTextureEtcANGLE = false;
+
+ // GL_CHROMIUM_copy_compressed_texture
+ bool copyCompressedTextureCHROMIUM = false;
+
+ // GL_CHROMIUM_copy_texture
+ bool copyTextureCHROMIUM = false;
+
+ // GL_ANGLE_copy_texture_3d
+ bool copyTexture3dANGLE = false;
+
+ // GL_CHROMIUM_framebuffer_mixed_samples
+ bool framebufferMixedSamplesCHROMIUM = false;
+
+ // GL_ANGLE_framebuffer_multisample
+ bool framebufferMultisampleANGLE = false;
+
+ // GL_ANGLE_get_image
+ bool getImageANGLE = false;
+
+ // GL_ANGLE_get_serialized_context_string
+ bool getSerializedContextStringANGLE = false;
+
+ // GL_ANGLE_get_tex_level_parameter
+ bool getTexLevelParameterANGLE = false;
+
+ // GL_ANGLE_logic_op
+ bool logicOpANGLE = false;
+
+ // GL_CHROMIUM_lose_context
+ bool loseContextCHROMIUM = false;
+
+ // GL_ANGLE_lossy_etc_decode
+ bool lossyEtcDecodeANGLE = false;
+
+ // GL_ANGLE_memory_object_flags
+ bool memoryObjectFlagsANGLE = false;
+
+ // GL_ANGLE_memory_object_fuchsia
+ bool memoryObjectFuchsiaANGLE = false;
+
+ // GL_ANGLE_memory_size
+ bool memorySizeANGLE = false;
+
+ // GL_ANGLE_multi_draw
+ bool multiDrawANGLE = false;
+
+ // GL_ANGLE_multiview_multisample
+ bool multiviewMultisampleANGLE = false;
+
+ // GL_ANGLE_program_binary
+ bool programBinaryANGLE = false;
+
+ // GL_ANGLE_program_cache_control
+ bool programCacheControlANGLE = false;
+
+ // GL_ANGLE_provoking_vertex
+ bool provokingVertexANGLE = false;
+
+ // GL_ANGLE_read_only_depth_stencil_feedback_loops
+ bool readOnlyDepthStencilFeedbackLoopsANGLE = false;
+
+ // GL_ANGLE_relaxed_vertex_attribute_type
+ bool relaxedVertexAttributeTypeANGLE = false;
+
+ // GL_ANGLE_request_extension
+ bool requestExtensionANGLE = false;
+
+ // GL_ANGLE_rgbx_internal_format
+ bool rgbxInternalFormatANGLE = false;
+
+ // GL_ANGLE_robust_client_memory
+ bool robustClientMemoryANGLE = false;
+
+ // GL_ANGLE_robust_fragment_shader_output
+ bool robustFragmentShaderOutputANGLE = false;
+
+ // GL_ANGLE_robust_resource_initialization
+ bool robustResourceInitializationANGLE = false;
+
+ // GL_ANGLE_semaphore_fuchsia
+ bool semaphoreFuchsiaANGLE = false;
+
+ // GL_ANGLE_shader_pixel_local_storage
+ bool shaderPixelLocalStorageANGLE = false;
+
+ // GL_ANGLE_shader_pixel_local_storage_coherent
+ bool shaderPixelLocalStorageCoherentANGLE = false;
+
+ // GL_CHROMIUM_sync_query
+ bool syncQueryCHROMIUM = false;
+
+ // GL_ANGLE_texture_compression_dxt3
+ bool textureCompressionDxt3ANGLE = false;
+
+ // GL_ANGLE_texture_compression_dxt5
+ bool textureCompressionDxt5ANGLE = false;
+
+ // GL_ANGLE_texture_external_update
+ bool textureExternalUpdateANGLE = false;
+
+ // GL_CHROMIUM_texture_filtering_hint
+ bool textureFilteringHintCHROMIUM = false;
+
+ // GL_ANGLE_texture_multisample
+ bool textureMultisampleANGLE = false;
+
+ // GL_ANGLE_texture_rectangle
+ bool textureRectangleANGLE = false;
+
+ // GL_ANGLE_vulkan_image
+ bool vulkanImageANGLE = false;
+
+ // GL_ANGLE_webgl_compatibility
+ bool webglCompatibilityANGLE = false;
+
+ // GL_ANGLE_yuv_internal_format
+ bool yuvInternalFormatANGLE = false;
+
+ // GLES 1.0 and 1.1 extensions
+ // ---------------------------
+
+ // GL_OES_draw_texture
+ bool drawTextureOES = false;
+
+ // GL_OES_framebuffer_object
+ bool framebufferObjectOES = false;
+
+ // GL_OES_matrix_palette
+ bool matrixPaletteOES = false;
+
+ // GL_OES_point_size_array
+ bool pointSizeArrayOES = false;
+
+ // GL_OES_point_sprite
+ bool pointSpriteOES = false;
+
+ // GL_OES_query_matrix
+ bool queryMatrixOES = false;
+
+ // GL_OES_texture_cube_map
+ bool textureCubeMapOES = false;
+};
+} // namespace gl
+
+#endif // LIBANGLE_GLES_EXTENSIONS_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libANGLE/histogram_macros.h b/gfx/angle/checkout/src/libANGLE/histogram_macros.h
new file mode 100644
index 0000000000..cf27a895a1
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/histogram_macros.h
@@ -0,0 +1,110 @@
+//
+// 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.
+//
+// histogram_macros.h:
+// Helpers for making histograms, to keep consistency with Chromium's
+// histogram_macros.h.
+
+#ifndef LIBANGLE_HISTOGRAM_MACROS_H_
+#define LIBANGLE_HISTOGRAM_MACROS_H_
+
+#include <platform/PlatformMethods.h>
+
+#define ANGLE_HISTOGRAM_TIMES(name, sample) ANGLE_HISTOGRAM_CUSTOM_TIMES(name, sample, 1, 10000, 50)
+
+#define ANGLE_HISTOGRAM_MEDIUM_TIMES(name, sample) \
+ ANGLE_HISTOGRAM_CUSTOM_TIMES(name, sample, 10, 180000, 50)
+
+// Use this macro when times can routinely be much longer than 10 seconds.
+#define ANGLE_HISTOGRAM_LONG_TIMES(name, sample) \
+ ANGLE_HISTOGRAM_CUSTOM_TIMES(name, sample, 1, 3600000, 50)
+
+// Use this macro when times can routinely be much longer than 10 seconds and
+// you want 100 buckets.
+#define ANGLE_HISTOGRAM_LONG_TIMES_100(name, sample) \
+ ANGLE_HISTOGRAM_CUSTOM_TIMES(name, sample, 1, 3600000, 100)
+
+// For folks that need real specific times, use this to select a precise range
+// of times you want plotted, and the number of buckets you want used.
+#define ANGLE_HISTOGRAM_CUSTOM_TIMES(name, sample, min, max, bucket_count) \
+ ANGLE_HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count)
+
+#define ANGLE_HISTOGRAM_COUNTS(name, sample) \
+ ANGLE_HISTOGRAM_CUSTOM_COUNTS(name, sample, 1, 1000000, 50)
+
+#define ANGLE_HISTOGRAM_COUNTS_100(name, sample) \
+ ANGLE_HISTOGRAM_CUSTOM_COUNTS(name, sample, 1, 100, 50)
+
+#define ANGLE_HISTOGRAM_COUNTS_10000(name, sample) \
+ ANGLE_HISTOGRAM_CUSTOM_COUNTS(name, sample, 1, 10000, 50)
+
+#define ANGLE_HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count) \
+ ANGLEPlatformCurrent()->histogramCustomCounts(ANGLEPlatformCurrent(), name, sample, min, max, \
+ bucket_count)
+
+#define ANGLE_HISTOGRAM_PERCENTAGE(name, under_one_hundred) \
+ ANGLE_HISTOGRAM_ENUMERATION(name, under_one_hundred, 101)
+
+#define ANGLE_HISTOGRAM_BOOLEAN(name, sample) \
+ ANGLEPlatformCurrent()->histogramBoolean(ANGLEPlatformCurrent(), name, sample)
+
+#define ANGLE_HISTOGRAM_ENUMERATION(name, sample, boundary_value) \
+ ANGLEPlatformCurrent()->histogramEnumeration(ANGLEPlatformCurrent(), name, sample, \
+ boundary_value)
+
+#define ANGLE_HISTOGRAM_MEMORY_KB(name, sample) \
+ ANGLE_HISTOGRAM_CUSTOM_COUNTS(name, sample, 1000, 500000, 50)
+
+#define ANGLE_HISTOGRAM_MEMORY_MB(name, sample) \
+ ANGLE_HISTOGRAM_CUSTOM_COUNTS(name, sample, 1, 1000, 50)
+
+#define ANGLE_HISTOGRAM_SPARSE_SLOWLY(name, sample) \
+ ANGLEPlatformCurrent()->histogramSparse(ANGLEPlatformCurrent(), name, sample)
+
+// Scoped class which logs its time on this earth as a UMA statistic. This is
+// recommended for when you want a histogram which measures the time it takes
+// for a method to execute. This measures up to 10 seconds.
+#define SCOPED_ANGLE_HISTOGRAM_TIMER(name) \
+ SCOPED_ANGLE_HISTOGRAM_TIMER_EXPANDER(name, false, __COUNTER__)
+
+// Similar scoped histogram timer, but this uses ANGLE_HISTOGRAM_LONG_TIMES_100,
+// which measures up to an hour, and uses 100 buckets. This is more expensive
+// to store, so only use if this often takes >10 seconds.
+#define SCOPED_ANGLE_HISTOGRAM_LONG_TIMER(name) \
+ SCOPED_ANGLE_HISTOGRAM_TIMER_EXPANDER(name, true, __COUNTER__)
+
+// This nested macro is necessary to expand __COUNTER__ to an actual value.
+#define SCOPED_ANGLE_HISTOGRAM_TIMER_EXPANDER(name, is_long, key) \
+ SCOPED_ANGLE_HISTOGRAM_TIMER_UNIQUE(name, is_long, key)
+
+#define SCOPED_ANGLE_HISTOGRAM_TIMER_UNIQUE(name, is_long, key) \
+ class [[nodiscard]] ScopedHistogramTimer##key \
+ { \
+ public: \
+ ScopedHistogramTimer##key() \
+ : constructed_(ANGLEPlatformCurrent()->currentTime(ANGLEPlatformCurrent())) \
+ {} \
+ ~ScopedHistogramTimer##key() \
+ { \
+ if (constructed_ == 0) \
+ return; \
+ auto *platform = ANGLEPlatformCurrent(); \
+ double elapsed = platform->currentTime(platform) - constructed_; \
+ int elapsedMS = static_cast<int>(elapsed * 1000.0); \
+ if (is_long) \
+ { \
+ ANGLE_HISTOGRAM_LONG_TIMES_100(name, elapsedMS); \
+ } \
+ else \
+ { \
+ ANGLE_HISTOGRAM_TIMES(name, elapsedMS); \
+ } \
+ } \
+ \
+ private: \
+ double constructed_; \
+ } scoped_histogram_timer_##key
+
+#endif // LIBANGLE_HISTOGRAM_MACROS_H_
diff --git a/gfx/angle/checkout/src/libANGLE/queryconversions.cpp b/gfx/angle/checkout/src/libANGLE/queryconversions.cpp
new file mode 100644
index 0000000000..3c3ab45b7c
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/queryconversions.cpp
@@ -0,0 +1,315 @@
+//
+// 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.
+//
+
+// queryconversions.cpp: Implementation of state query cast conversions
+
+#include "libANGLE/queryconversions.h"
+
+#include <vector>
+
+#include "common/utilities.h"
+#include "libANGLE/Context.h"
+
+namespace gl
+{
+
+namespace
+{
+
+GLint64 ExpandFloatToInteger(GLfloat value)
+{
+ return static_cast<GLint64>((static_cast<double>(0xFFFFFFFFULL) * value - 1.0) / 2.0);
+}
+
+template <typename QueryT, typename NativeT>
+QueryT CastFromStateValueToInt(GLenum pname, NativeT value)
+{
+ GLenum nativeType = GLTypeToGLenum<NativeT>::value;
+
+ if (nativeType == GL_FLOAT)
+ {
+ // RGBA color values and DepthRangeF values are converted to integer using Equation 2.4 from
+ // Table 4.5
+ switch (pname)
+ {
+ case GL_DEPTH_RANGE:
+ case GL_COLOR_CLEAR_VALUE:
+ case GL_DEPTH_CLEAR_VALUE:
+ case GL_BLEND_COLOR:
+ // GLES1 emulation:
+ // Also, several GLES1.x values need to be converted to integer with
+ // ExpandFloatToInteger rather than rounding. See GLES 1.1 spec 6.1.2 "Data
+ // Conversions".
+ case GL_ALPHA_TEST_REF:
+ case GL_CURRENT_COLOR:
+ return clampCast<QueryT>(ExpandFloatToInteger(static_cast<GLfloat>(value)));
+ default:
+ return clampCast<QueryT>(std::round(value));
+ }
+ }
+
+ return clampCast<QueryT>(value);
+}
+
+template <typename NativeT, typename QueryT>
+NativeT CastQueryValueToInt(GLenum pname, QueryT value)
+{
+ GLenum queryType = GLTypeToGLenum<QueryT>::value;
+
+ if (queryType == GL_FLOAT)
+ {
+ // ARM devices cast float to uint differently than Intel.
+ // Basically, any negative floating point number becomes 0
+ // when converted to unsigned int. Instead, convert to a signed
+ // int and then convert to unsigned int to "preserve the value"
+ // E.g. common case for tests is to pass in -1 as an invalid query
+ // value. If cast to a unsigned int it becomes 0 (GL_NONE) and is now
+ // a valid enum and negative tests fail. But converting to int
+ // and then to final unsigned int gives us 4294967295 (0xffffffff)
+ // which is what we want.
+ return static_cast<NativeT>(static_cast<GLint64>(std::round(value)));
+ }
+
+ return static_cast<NativeT>(value);
+}
+
+} // anonymous namespace
+
+GLint CastMaskValue(GLuint value)
+{
+ return clampCast<GLint>(value);
+}
+
+template <typename QueryT, typename InternalT>
+QueryT CastFromGLintStateValue(GLenum pname, InternalT value)
+{
+ return CastFromStateValue<QueryT, GLint>(pname, clampCast<GLint, InternalT>(value));
+}
+
+template GLfloat CastFromGLintStateValue<GLfloat, GLenum>(GLenum pname, GLenum value);
+template GLint CastFromGLintStateValue<GLint, GLenum>(GLenum pname, GLenum value);
+template GLint64 CastFromGLintStateValue<GLint64, GLenum>(GLenum pname, GLenum value);
+template GLuint CastFromGLintStateValue<GLuint, GLenum>(GLenum pname, GLenum value);
+template GLuint CastFromGLintStateValue<GLuint, GLint>(GLenum pname, GLint value);
+template GLfloat CastFromGLintStateValue<GLfloat, GLint>(GLenum pname, GLint value);
+template GLint CastFromGLintStateValue<GLint, GLint>(GLenum pname, GLint value);
+template GLfloat CastFromGLintStateValue<GLfloat, bool>(GLenum pname, bool value);
+template GLuint CastFromGLintStateValue<GLuint, bool>(GLenum pname, bool value);
+template GLint CastFromGLintStateValue<GLint, bool>(GLenum pname, bool value);
+
+template <typename QueryT, typename NativeT>
+QueryT CastFromStateValue(GLenum pname, NativeT value)
+{
+ GLenum queryType = GLTypeToGLenum<QueryT>::value;
+
+ switch (queryType)
+ {
+ case GL_INT:
+ case GL_INT_64_ANGLEX:
+ case GL_UNSIGNED_INT:
+ case GL_UINT_64_ANGLEX:
+ return CastFromStateValueToInt<QueryT, NativeT>(pname, value);
+ case GL_FLOAT:
+ return static_cast<QueryT>(value);
+ case GL_BOOL:
+ return static_cast<QueryT>(value == static_cast<NativeT>(0) ? GL_FALSE : GL_TRUE);
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+template GLint CastFromStateValue<GLint, GLint>(GLenum pname, GLint value);
+template GLint CastFromStateValue<GLint, GLint64>(GLenum pname, GLint64 value);
+template GLint64 CastFromStateValue<GLint64, GLint>(GLenum pname, GLint value);
+template GLint64 CastFromStateValue<GLint64, GLint64>(GLenum pname, GLint64 value);
+template GLfloat CastFromStateValue<GLfloat, GLint>(GLenum pname, GLint value);
+template GLfloat CastFromStateValue<GLfloat, GLuint>(GLenum pname, GLuint value);
+template GLfloat CastFromStateValue<GLfloat, GLfloat>(GLenum pname, GLfloat value);
+template GLint CastFromStateValue<GLint, GLfloat>(GLenum pname, GLfloat value);
+template GLuint CastFromStateValue<GLuint, GLfloat>(GLenum pname, GLfloat value);
+template GLuint CastFromStateValue<GLuint, GLint>(GLenum pname, GLint value);
+template GLuint CastFromStateValue<GLuint, GLuint>(GLenum pname, GLuint value);
+template GLint CastFromStateValue<GLint, GLboolean>(GLenum pname, GLboolean value);
+template GLint64 CastFromStateValue<GLint64, GLboolean>(GLenum pname, GLboolean value);
+template GLint CastFromStateValue<GLint, GLuint>(GLenum pname, GLuint value);
+template GLint64 CastFromStateValue<GLint64, GLuint>(GLenum pname, GLuint value);
+template GLuint64 CastFromStateValue<GLuint64, GLuint>(GLenum pname, GLuint value);
+
+template <typename NativeT, typename QueryT>
+NativeT CastQueryValueTo(GLenum pname, QueryT value)
+{
+ GLenum nativeType = GLTypeToGLenum<NativeT>::value;
+
+ switch (nativeType)
+ {
+ case GL_INT:
+ case GL_INT_64_ANGLEX:
+ case GL_UNSIGNED_INT:
+ case GL_UINT_64_ANGLEX:
+ return CastQueryValueToInt<NativeT, QueryT>(pname, value);
+ case GL_FLOAT:
+ return static_cast<NativeT>(value);
+ case GL_BOOL:
+ return static_cast<NativeT>(value == static_cast<QueryT>(0) ? GL_FALSE : GL_TRUE);
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+template GLint CastQueryValueTo<GLint, GLfloat>(GLenum pname, GLfloat value);
+template GLboolean CastQueryValueTo<GLboolean, GLint>(GLenum pname, GLint value);
+template GLint CastQueryValueTo<GLint, GLint>(GLenum pname, GLint value);
+template GLint CastQueryValueTo<GLint, GLuint>(GLenum pname, GLuint value);
+template GLfloat CastQueryValueTo<GLfloat, GLint>(GLenum pname, GLint value);
+template GLfloat CastQueryValueTo<GLfloat, GLuint>(GLenum pname, GLuint value);
+template GLfloat CastQueryValueTo<GLfloat, GLfloat>(GLenum pname, GLfloat value);
+template GLuint CastQueryValueTo<GLuint, GLint>(GLenum pname, GLint value);
+template GLuint CastQueryValueTo<GLuint, GLuint>(GLenum pname, GLuint value);
+template GLuint CastQueryValueTo<GLuint, GLfloat>(GLenum pname, GLfloat value);
+
+template <typename QueryT>
+void CastStateValues(const Context *context,
+ GLenum nativeType,
+ GLenum pname,
+ unsigned int numParams,
+ QueryT *outParams)
+{
+ if (nativeType == GL_INT)
+ {
+ std::vector<GLint> intParams(numParams, 0);
+ context->getIntegervImpl(pname, intParams.data());
+
+ for (unsigned int i = 0; i < numParams; ++i)
+ {
+ outParams[i] = CastFromStateValue<QueryT>(pname, intParams[i]);
+ }
+ }
+ else if (nativeType == GL_BOOL)
+ {
+ std::vector<GLboolean> boolParams(numParams, GL_FALSE);
+ context->getBooleanvImpl(pname, 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_FLOAT)
+ {
+ std::vector<GLfloat> floatParams(numParams, 0.0f);
+ context->getFloatvImpl(pname, floatParams.data());
+
+ for (unsigned int i = 0; i < numParams; ++i)
+ {
+ outParams[i] = CastFromStateValue<QueryT>(pname, floatParams[i]);
+ }
+ }
+ else if (nativeType == GL_INT_64_ANGLEX)
+ {
+ std::vector<GLint64> int64Params(numParams, 0);
+ context->getInteger64vImpl(pname, int64Params.data());
+
+ for (unsigned int i = 0; i < numParams; ++i)
+ {
+ outParams[i] = CastFromStateValue<QueryT>(pname, int64Params[i]);
+ }
+ }
+ else
+ {
+ WARN() << "Application querying parameter that does not exist.";
+ }
+}
+
+// Explicit template instantiation (how we export template functions in different files)
+// The calls below will make CastStateValues successfully link with the GL state query types
+// The GL state query API types are: bool, int, uint, float, int64, uint64
+
+template void CastStateValues<GLboolean>(const Context *,
+ GLenum,
+ GLenum,
+ unsigned int,
+ GLboolean *);
+template void CastStateValues<GLint>(const Context *, GLenum, GLenum, unsigned int, GLint *);
+template void CastStateValues<GLuint>(const Context *, GLenum, GLenum, unsigned int, GLuint *);
+template void CastStateValues<GLfloat>(const Context *, GLenum, GLenum, unsigned int, GLfloat *);
+template void CastStateValues<GLint64>(const 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] = CastFromStateValue<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] = CastFromStateValue<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 *);
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/queryconversions.h b/gfx/angle/checkout/src/libANGLE/queryconversions.h
new file mode 100644
index 0000000000..7784c33e73
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/queryconversions.h
@@ -0,0 +1,138 @@
+//
+// 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.
+//
+
+// queryconversions.h: Declaration of state query cast conversions
+
+#ifndef LIBANGLE_QUERY_CONVERSIONS_H_
+#define LIBANGLE_QUERY_CONVERSIONS_H_
+
+#include "angle_gl.h"
+#include "common/angleutils.h"
+
+namespace gl
+{
+class Context;
+
+// Helper class for converting a GL type to a GLenum:
+// We can't use CastStateValueEnum generally, because of GLboolean + GLubyte overlap.
+// We restrict our use to CastFromStateValue and CastQueryValueTo, where it eliminates
+// duplicate parameters.
+
+template <typename GLType>
+struct GLTypeToGLenum
+{
+ // 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<GLuint64>
+{
+ static constexpr GLenum value = GL_UINT_64_ANGLEX;
+};
+template <>
+struct GLTypeToGLenum<GLfloat>
+{
+ static constexpr GLenum value = GL_FLOAT;
+};
+
+GLint CastMaskValue(GLuint value);
+
+template <typename QueryT, typename InternalT>
+QueryT CastFromGLintStateValue(GLenum pname, InternalT value);
+
+template <typename QueryT, typename NativeT>
+QueryT CastFromStateValue(GLenum pname, NativeT value);
+
+template <typename NativeT, typename QueryT>
+NativeT CastQueryValueTo(GLenum pname, QueryT value);
+
+template <typename ParamType>
+GLenum ConvertToGLenum(GLenum pname, ParamType param)
+{
+ return static_cast<GLenum>(CastQueryValueTo<GLuint>(pname, param));
+}
+
+template <typename ParamType>
+GLenum ConvertToGLenum(ParamType param)
+{
+ return ConvertToGLenum(GL_NONE, param);
+}
+
+template <typename OutType>
+OutType ConvertGLenum(GLenum param)
+{
+ return static_cast<OutType>(param);
+}
+
+template <typename InType, typename OutType>
+void ConvertGLenumValue(InType param, OutType *out)
+{
+ *out = ConvertGLenum<OutType>(static_cast<GLenum>(param));
+}
+
+template <typename PackedEnumType, typename OutType>
+void ConvertPackedEnum(PackedEnumType param, OutType *out)
+{
+ *out = static_cast<OutType>(ToGLenum(param));
+}
+
+template <typename ParamType>
+GLint ConvertToGLint(ParamType param)
+{
+ return CastQueryValueTo<GLint>(GL_NONE, param);
+}
+
+template <typename ParamType>
+bool ConvertToBool(ParamType param)
+{
+ return param != GL_FALSE;
+}
+
+template <typename ParamType>
+GLboolean ConvertToGLBoolean(ParamType param)
+{
+ return param ? GL_TRUE : GL_FALSE;
+}
+
+// The GL state query API types are: bool, int, uint, float, int64, uint64
+template <typename QueryT>
+void CastStateValues(const Context *context,
+ GLenum nativeType,
+ GLenum pname,
+ unsigned int numParams,
+ QueryT *outParams);
+
+// The GL state query API types are: bool, int, uint, float, int64, uint64
+template <typename QueryT>
+void CastIndexedStateValues(Context *context,
+ GLenum nativeType,
+ GLenum pname,
+ GLuint index,
+ unsigned int numParams,
+ QueryT *outParams);
+} // namespace gl
+
+#endif // LIBANGLE_QUERY_CONVERSIONS_H_
diff --git a/gfx/angle/checkout/src/libANGLE/queryutils.cpp b/gfx/angle/checkout/src/libANGLE/queryutils.cpp
new file mode 100644
index 0000000000..56600eae9d
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/queryutils.cpp
@@ -0,0 +1,4525 @@
+//
+// 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.
+//
+
+// queryutils.cpp: Utilities for querying values from GL objects
+
+#include "libANGLE/queryutils.h"
+
+#include <algorithm>
+
+#include "common/utilities.h"
+
+#include "libANGLE/Buffer.h"
+#include "libANGLE/Config.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Display.h"
+#include "libANGLE/EGLSync.h"
+#include "libANGLE/Fence.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/GLES1State.h"
+#include "libANGLE/MemoryObject.h"
+#include "libANGLE/Program.h"
+#include "libANGLE/Renderbuffer.h"
+#include "libANGLE/Sampler.h"
+#include "libANGLE/Shader.h"
+#include "libANGLE/Surface.h"
+#include "libANGLE/Texture.h"
+#include "libANGLE/Uniform.h"
+#include "libANGLE/VertexAttribute.h"
+#include "libANGLE/queryconversions.h"
+
+namespace gl
+{
+
+namespace
+{
+
+template <bool isPureInteger>
+ColorGeneric ConvertToColor(const GLfloat *params)
+{
+ if (isPureInteger)
+ {
+ UNREACHABLE();
+ return ColorGeneric(ColorI());
+ }
+ else
+ {
+ return ColorGeneric(ColorF::fromData(params));
+ }
+}
+
+template <bool isPureInteger>
+ColorGeneric ConvertToColor(const GLint *params)
+{
+ if (isPureInteger)
+ {
+ return ColorGeneric(ColorI(params[0], params[1], params[2], params[3]));
+ }
+ else
+ {
+ return ColorGeneric(ColorF(normalizedToFloat(params[0]), normalizedToFloat(params[1]),
+ normalizedToFloat(params[2]), normalizedToFloat(params[3])));
+ }
+}
+
+template <bool isPureInteger>
+ColorGeneric ConvertToColor(const GLuint *params)
+{
+ if (isPureInteger)
+ {
+ return ColorGeneric(ColorUI(params[0], params[1], params[2], params[3]));
+ }
+ else
+ {
+ UNREACHABLE();
+ return ColorGeneric(ColorF());
+ }
+}
+
+template <bool isPureInteger>
+void ConvertFromColor(const ColorGeneric &color, GLfloat *outParams)
+{
+ if (isPureInteger)
+ {
+ UNREACHABLE();
+ }
+ else
+ {
+ color.colorF.writeData(outParams);
+ }
+}
+
+template <bool isPureInteger>
+void ConvertFromColor(const ColorGeneric &color, GLint *outParams)
+{
+ if (isPureInteger)
+ {
+ outParams[0] = color.colorI.red;
+ outParams[1] = color.colorI.green;
+ outParams[2] = color.colorI.blue;
+ outParams[3] = color.colorI.alpha;
+ }
+ else
+ {
+ outParams[0] = floatToNormalized<GLint>(color.colorF.red);
+ outParams[1] = floatToNormalized<GLint>(color.colorF.green);
+ outParams[2] = floatToNormalized<GLint>(color.colorF.blue);
+ outParams[3] = floatToNormalized<GLint>(color.colorF.alpha);
+ }
+}
+
+template <bool isPureInteger>
+void ConvertFromColor(const ColorGeneric &color, GLuint *outParams)
+{
+ if (isPureInteger)
+ {
+ constexpr unsigned int kMinValue = 0;
+
+ outParams[0] = std::max(color.colorUI.red, kMinValue);
+ outParams[1] = std::max(color.colorUI.green, kMinValue);
+ outParams[2] = std::max(color.colorUI.blue, kMinValue);
+ outParams[3] = std::max(color.colorUI.alpha, kMinValue);
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+}
+
+template <typename ParamType>
+void QueryTexLevelParameterBase(const Texture *texture,
+ TextureTarget target,
+ GLint level,
+ GLenum pname,
+ ParamType *params)
+{
+ ASSERT(texture != nullptr);
+ const InternalFormat *info = texture->getTextureState().getImageDesc(target, level).format.info;
+
+ switch (pname)
+ {
+ case GL_TEXTURE_RED_TYPE:
+ *params = CastFromGLintStateValue<ParamType>(
+ pname, info->redBits ? info->componentType : GL_NONE);
+ break;
+ case GL_TEXTURE_GREEN_TYPE:
+ *params = CastFromGLintStateValue<ParamType>(
+ pname, info->greenBits ? info->componentType : GL_NONE);
+ break;
+ case GL_TEXTURE_BLUE_TYPE:
+ *params = CastFromGLintStateValue<ParamType>(
+ pname, info->blueBits ? info->componentType : GL_NONE);
+ break;
+ case GL_TEXTURE_ALPHA_TYPE:
+ *params = CastFromGLintStateValue<ParamType>(
+ pname, info->alphaBits ? info->componentType : GL_NONE);
+ break;
+ case GL_TEXTURE_DEPTH_TYPE:
+ *params = CastFromGLintStateValue<ParamType>(
+ pname, info->depthBits ? info->componentType : GL_NONE);
+ break;
+ case GL_TEXTURE_RED_SIZE:
+ *params = CastFromGLintStateValue<ParamType>(pname, info->redBits);
+ break;
+ case GL_TEXTURE_GREEN_SIZE:
+ *params = CastFromGLintStateValue<ParamType>(pname, info->greenBits);
+ break;
+ case GL_TEXTURE_BLUE_SIZE:
+ *params = CastFromGLintStateValue<ParamType>(pname, info->blueBits);
+ break;
+ case GL_TEXTURE_ALPHA_SIZE:
+ *params = CastFromGLintStateValue<ParamType>(pname, info->alphaBits);
+ break;
+ case GL_TEXTURE_DEPTH_SIZE:
+ *params = CastFromGLintStateValue<ParamType>(pname, info->depthBits);
+ break;
+ case GL_TEXTURE_STENCIL_SIZE:
+ *params = CastFromGLintStateValue<ParamType>(pname, info->stencilBits);
+ break;
+ case GL_TEXTURE_SHARED_SIZE:
+ *params = CastFromGLintStateValue<ParamType>(pname, info->sharedBits);
+ break;
+ case GL_TEXTURE_INTERNAL_FORMAT:
+ *params = CastFromGLintStateValue<ParamType>(
+ pname, info->internalFormat ? info->internalFormat : GL_RGBA);
+ break;
+ case GL_TEXTURE_WIDTH:
+ *params = CastFromGLintStateValue<ParamType>(
+ pname, static_cast<uint32_t>(texture->getWidth(target, level)));
+ break;
+ case GL_TEXTURE_HEIGHT:
+ *params = CastFromGLintStateValue<ParamType>(
+ pname, static_cast<uint32_t>(texture->getHeight(target, level)));
+ break;
+ case GL_TEXTURE_DEPTH:
+ *params = CastFromGLintStateValue<ParamType>(
+ pname, static_cast<uint32_t>(texture->getDepth(target, level)));
+ break;
+ case GL_TEXTURE_SAMPLES:
+ *params = CastFromStateValue<ParamType>(pname, texture->getSamples(target, level));
+ break;
+ case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
+ *params = CastFromStateValue<ParamType>(
+ pname, static_cast<GLint>(texture->getFixedSampleLocations(target, level)));
+ break;
+ case GL_TEXTURE_COMPRESSED:
+ *params = CastFromStateValue<ParamType>(pname, static_cast<GLint>(info->compressed));
+ break;
+ case GL_MEMORY_SIZE_ANGLE:
+ *params =
+ CastFromStateValue<ParamType>(pname, texture->getLevelMemorySize(target, level));
+ break;
+ case GL_RESOURCE_INITIALIZED_ANGLE:
+ *params = CastFromGLintStateValue<ParamType>(
+ pname, texture->initState(GL_NONE, ImageIndex::MakeFromTarget(target, level)) ==
+ InitState::Initialized);
+ break;
+ case GL_TEXTURE_BUFFER_DATA_STORE_BINDING:
+ *params = CastFromStateValue<ParamType>(
+ pname, static_cast<GLint>(texture->getBuffer().id().value));
+ break;
+ case GL_TEXTURE_BUFFER_OFFSET:
+ *params = CastFromStateValue<ParamType>(
+ pname, static_cast<GLint>(texture->getBuffer().getOffset()));
+ break;
+ case GL_TEXTURE_BUFFER_SIZE:
+ *params = CastFromStateValue<ParamType>(
+ pname, static_cast<GLint>(GetBoundBufferAvailableSize(texture->getBuffer())));
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+// This function is needed to handle fixed_point data.
+// It can be used when some pname need special conversion from int/float/bool to fixed_point.
+template <bool isGLfixed, typename QueryT, typename ParamType>
+QueryT CastFromSpecialValue(GLenum pname, const ParamType param)
+{
+ if (isGLfixed)
+ {
+ return static_cast<QueryT>(ConvertFloatToFixed(CastFromStateValue<GLfloat>(pname, param)));
+ }
+ else
+ {
+ return CastFromStateValue<QueryT>(pname, param);
+ }
+}
+
+template <bool isPureInteger, bool isGLfixed, typename ParamType>
+void QueryTexParameterBase(const Context *context,
+ const Texture *texture,
+ GLenum pname,
+ ParamType *params)
+{
+ ASSERT(texture != nullptr);
+
+ switch (pname)
+ {
+ case GL_TEXTURE_MAG_FILTER:
+ *params = CastFromGLintStateValue<ParamType>(pname, texture->getMagFilter());
+ break;
+ case GL_TEXTURE_MIN_FILTER:
+ *params = CastFromGLintStateValue<ParamType>(pname, texture->getMinFilter());
+ break;
+ case GL_TEXTURE_WRAP_S:
+ *params = CastFromGLintStateValue<ParamType>(pname, texture->getWrapS());
+ break;
+ case GL_TEXTURE_WRAP_T:
+ *params = CastFromGLintStateValue<ParamType>(pname, texture->getWrapT());
+ break;
+ case GL_TEXTURE_WRAP_R:
+ *params = CastFromGLintStateValue<ParamType>(pname, texture->getWrapR());
+ break;
+ case GL_TEXTURE_IMMUTABLE_FORMAT:
+ *params = CastFromGLintStateValue<ParamType>(pname, texture->getImmutableFormat());
+ break;
+ case GL_TEXTURE_IMMUTABLE_LEVELS:
+ *params = CastFromGLintStateValue<ParamType>(pname, texture->getImmutableLevels());
+ break;
+ case GL_TEXTURE_USAGE_ANGLE:
+ *params = CastFromGLintStateValue<ParamType>(pname, texture->getUsage());
+ break;
+ case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+ *params =
+ CastFromSpecialValue<isGLfixed, ParamType>(pname, texture->getMaxAnisotropy());
+ break;
+ case GL_TEXTURE_SWIZZLE_R:
+ *params = CastFromGLintStateValue<ParamType>(pname, texture->getSwizzleRed());
+ break;
+ case GL_TEXTURE_SWIZZLE_G:
+ *params = CastFromGLintStateValue<ParamType>(pname, texture->getSwizzleGreen());
+ break;
+ case GL_TEXTURE_SWIZZLE_B:
+ *params = CastFromGLintStateValue<ParamType>(pname, texture->getSwizzleBlue());
+ break;
+ case GL_TEXTURE_SWIZZLE_A:
+ *params = CastFromGLintStateValue<ParamType>(pname, texture->getSwizzleAlpha());
+ break;
+ case GL_TEXTURE_BASE_LEVEL:
+ *params = CastFromGLintStateValue<ParamType>(pname, texture->getBaseLevel());
+ break;
+ case GL_TEXTURE_MAX_LEVEL:
+ *params = CastFromGLintStateValue<ParamType>(pname, texture->getMaxLevel());
+ break;
+ case GL_TEXTURE_MIN_LOD:
+ *params = CastFromSpecialValue<isGLfixed, ParamType>(pname, texture->getMinLod());
+ break;
+ case GL_TEXTURE_MAX_LOD:
+ *params = CastFromSpecialValue<isGLfixed, ParamType>(pname, texture->getMaxLod());
+ break;
+ case GL_TEXTURE_COMPARE_MODE:
+ *params = CastFromGLintStateValue<ParamType>(pname, texture->getCompareMode());
+ break;
+ case GL_TEXTURE_COMPARE_FUNC:
+ *params = CastFromGLintStateValue<ParamType>(pname, texture->getCompareFunc());
+ break;
+ case GL_TEXTURE_SRGB_DECODE_EXT:
+ *params = CastFromGLintStateValue<ParamType>(pname, texture->getSRGBDecode());
+ break;
+ case GL_TEXTURE_FORMAT_SRGB_OVERRIDE_EXT:
+ *params = CastFromGLintStateValue<ParamType>(pname, texture->getSRGBOverride());
+ break;
+ case GL_DEPTH_STENCIL_TEXTURE_MODE:
+ *params =
+ CastFromGLintStateValue<ParamType>(pname, texture->getDepthStencilTextureMode());
+ break;
+ case GL_TEXTURE_CROP_RECT_OES:
+ {
+ const gl::Rectangle &crop = texture->getCrop();
+ params[0] = CastFromSpecialValue<isGLfixed, ParamType>(pname, crop.x);
+ params[1] = CastFromSpecialValue<isGLfixed, ParamType>(pname, crop.y);
+ params[2] = CastFromSpecialValue<isGLfixed, ParamType>(pname, crop.width);
+ params[3] = CastFromSpecialValue<isGLfixed, ParamType>(pname, crop.height);
+ break;
+ }
+ case GL_GENERATE_MIPMAP:
+ *params = CastFromGLintStateValue<ParamType>(pname, texture->getGenerateMipmapHint());
+ break;
+ case GL_MEMORY_SIZE_ANGLE:
+ *params = CastFromSpecialValue<isGLfixed, ParamType>(pname, texture->getMemorySize());
+ break;
+ case GL_TEXTURE_BORDER_COLOR:
+ ConvertFromColor<isPureInteger>(texture->getBorderColor(), params);
+ break;
+ case GL_TEXTURE_NATIVE_ID_ANGLE:
+ *params = CastFromSpecialValue<isGLfixed, ParamType>(pname, texture->getNativeID());
+ break;
+ case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
+ *params = CastFromGLintStateValue<ParamType>(
+ pname, texture->getImplementationColorReadFormat(context));
+ break;
+ case GL_IMPLEMENTATION_COLOR_READ_TYPE:
+ *params = CastFromGLintStateValue<ParamType>(
+ pname, texture->getImplementationColorReadType(context));
+ break;
+ case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE:
+ *params =
+ CastFromGLintStateValue<ParamType>(pname, GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE);
+ break;
+ case GL_RESOURCE_INITIALIZED_ANGLE:
+ *params = CastFromGLintStateValue<ParamType>(
+ pname, texture->initState() == InitState::Initialized);
+ break;
+ case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
+ *params = CastFromGLintStateValue<ParamType>(
+ pname, texture->getRequiredTextureImageUnits(context));
+ break;
+ case GL_TEXTURE_PROTECTED_EXT:
+ *params = CastFromGLintStateValue<ParamType>(pname, texture->hasProtectedContent());
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+// this function is needed to handle OES_FIXED_POINT.
+// Some pname values can take in GLfixed values and may need to be converted
+template <bool isGLfixed, typename ReturnType, typename ParamType>
+ReturnType ConvertTexParam(GLenum pname, const ParamType param)
+{
+ if (isGLfixed)
+ {
+ return CastQueryValueTo<ReturnType>(pname,
+ ConvertFixedToFloat(static_cast<GLfixed>(param)));
+ }
+ else
+ {
+ return CastQueryValueTo<ReturnType>(pname, param);
+ }
+}
+
+template <bool isPureInteger, bool isGLfixed, typename ParamType>
+void SetTexParameterBase(Context *context, Texture *texture, GLenum pname, const ParamType *params)
+{
+ ASSERT(texture != nullptr);
+
+ switch (pname)
+ {
+ case GL_TEXTURE_WRAP_S:
+ texture->setWrapS(context, ConvertToGLenum(pname, params[0]));
+ break;
+ case GL_TEXTURE_WRAP_T:
+ texture->setWrapT(context, ConvertToGLenum(pname, params[0]));
+ break;
+ case GL_TEXTURE_WRAP_R:
+ texture->setWrapR(context, ConvertToGLenum(pname, params[0]));
+ break;
+ case GL_TEXTURE_MIN_FILTER:
+ texture->setMinFilter(context, ConvertToGLenum(pname, params[0]));
+ break;
+ case GL_TEXTURE_MAG_FILTER:
+ texture->setMagFilter(context, ConvertToGLenum(pname, params[0]));
+ break;
+ case GL_TEXTURE_USAGE_ANGLE:
+ texture->setUsage(context, ConvertToGLenum(pname, params[0]));
+ break;
+ case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+ texture->setMaxAnisotropy(context,
+ ConvertTexParam<isGLfixed, GLfloat>(pname, params[0]));
+ break;
+ case GL_TEXTURE_COMPARE_MODE:
+ texture->setCompareMode(context, ConvertToGLenum(pname, params[0]));
+ break;
+ case GL_TEXTURE_COMPARE_FUNC:
+ texture->setCompareFunc(context, ConvertToGLenum(pname, params[0]));
+ break;
+ case GL_TEXTURE_SWIZZLE_R:
+ texture->setSwizzleRed(context, ConvertToGLenum(pname, params[0]));
+ break;
+ case GL_TEXTURE_SWIZZLE_G:
+ texture->setSwizzleGreen(context, ConvertToGLenum(pname, params[0]));
+ break;
+ case GL_TEXTURE_SWIZZLE_B:
+ texture->setSwizzleBlue(context, ConvertToGLenum(pname, params[0]));
+ break;
+ case GL_TEXTURE_SWIZZLE_A:
+ texture->setSwizzleAlpha(context, ConvertToGLenum(pname, params[0]));
+ break;
+ case GL_TEXTURE_BASE_LEVEL:
+ {
+ (void)(texture->setBaseLevel(
+ context, clampCast<GLuint>(CastQueryValueTo<GLint>(pname, params[0]))));
+ break;
+ }
+ case GL_TEXTURE_MAX_LEVEL:
+ texture->setMaxLevel(context,
+ clampCast<GLuint>(CastQueryValueTo<GLint>(pname, params[0])));
+ break;
+ case GL_TEXTURE_MIN_LOD:
+ texture->setMinLod(context, CastQueryValueTo<GLfloat>(pname, params[0]));
+ break;
+ case GL_TEXTURE_MAX_LOD:
+ texture->setMaxLod(context, CastQueryValueTo<GLfloat>(pname, params[0]));
+ break;
+ case GL_DEPTH_STENCIL_TEXTURE_MODE:
+ texture->setDepthStencilTextureMode(context, ConvertToGLenum(pname, params[0]));
+ break;
+ case GL_TEXTURE_SRGB_DECODE_EXT:
+ texture->setSRGBDecode(context, ConvertToGLenum(pname, params[0]));
+ break;
+ case GL_TEXTURE_FORMAT_SRGB_OVERRIDE_EXT:
+ texture->setSRGBOverride(context, ConvertToGLenum(pname, params[0]));
+ break;
+ case GL_TEXTURE_CROP_RECT_OES:
+ texture->setCrop(gl::Rectangle(ConvertTexParam<isGLfixed, GLint>(pname, params[0]),
+ ConvertTexParam<isGLfixed, GLint>(pname, params[1]),
+ ConvertTexParam<isGLfixed, GLint>(pname, params[2]),
+ ConvertTexParam<isGLfixed, GLint>(pname, params[3])));
+ break;
+ case GL_GENERATE_MIPMAP:
+ texture->setGenerateMipmapHint(ConvertToGLenum(params[0]));
+ break;
+ case GL_TEXTURE_BORDER_COLOR:
+ texture->setBorderColor(context, ConvertToColor<isPureInteger>(params));
+ break;
+ case GL_RESOURCE_INITIALIZED_ANGLE:
+ texture->setInitState(ConvertToBool(params[0]) ? InitState::Initialized
+ : InitState::MayNeedInit);
+ break;
+ case GL_TEXTURE_PROTECTED_EXT:
+ texture->setProtectedContent(context, (params[0] == GL_TRUE));
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+template <bool isPureInteger, typename ParamType>
+void QuerySamplerParameterBase(const Sampler *sampler, GLenum pname, ParamType *params)
+{
+ switch (pname)
+ {
+ case GL_TEXTURE_MIN_FILTER:
+ *params = CastFromGLintStateValue<ParamType>(pname, sampler->getMinFilter());
+ break;
+ case GL_TEXTURE_MAG_FILTER:
+ *params = CastFromGLintStateValue<ParamType>(pname, sampler->getMagFilter());
+ break;
+ case GL_TEXTURE_WRAP_S:
+ *params = CastFromGLintStateValue<ParamType>(pname, sampler->getWrapS());
+ break;
+ case GL_TEXTURE_WRAP_T:
+ *params = CastFromGLintStateValue<ParamType>(pname, sampler->getWrapT());
+ break;
+ case GL_TEXTURE_WRAP_R:
+ *params = CastFromGLintStateValue<ParamType>(pname, sampler->getWrapR());
+ break;
+ case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+ *params = CastFromStateValue<ParamType>(pname, sampler->getMaxAnisotropy());
+ break;
+ case GL_TEXTURE_MIN_LOD:
+ *params = CastFromStateValue<ParamType>(pname, sampler->getMinLod());
+ break;
+ case GL_TEXTURE_MAX_LOD:
+ *params = CastFromStateValue<ParamType>(pname, sampler->getMaxLod());
+ break;
+ case GL_TEXTURE_COMPARE_MODE:
+ *params = CastFromGLintStateValue<ParamType>(pname, sampler->getCompareMode());
+ break;
+ case GL_TEXTURE_COMPARE_FUNC:
+ *params = CastFromGLintStateValue<ParamType>(pname, sampler->getCompareFunc());
+ break;
+ case GL_TEXTURE_SRGB_DECODE_EXT:
+ *params = CastFromGLintStateValue<ParamType>(pname, sampler->getSRGBDecode());
+ break;
+ case GL_TEXTURE_BORDER_COLOR:
+ ConvertFromColor<isPureInteger>(sampler->getBorderColor(), params);
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+template <bool isPureInteger, typename ParamType>
+void SetSamplerParameterBase(Context *context,
+ Sampler *sampler,
+ GLenum pname,
+ const ParamType *params)
+{
+ switch (pname)
+ {
+ case GL_TEXTURE_WRAP_S:
+ sampler->setWrapS(context, ConvertToGLenum(pname, params[0]));
+ break;
+ case GL_TEXTURE_WRAP_T:
+ sampler->setWrapT(context, ConvertToGLenum(pname, params[0]));
+ break;
+ case GL_TEXTURE_WRAP_R:
+ sampler->setWrapR(context, ConvertToGLenum(pname, params[0]));
+ break;
+ case GL_TEXTURE_MIN_FILTER:
+ sampler->setMinFilter(context, ConvertToGLenum(pname, params[0]));
+ break;
+ case GL_TEXTURE_MAG_FILTER:
+ sampler->setMagFilter(context, ConvertToGLenum(pname, params[0]));
+ break;
+ case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+ sampler->setMaxAnisotropy(context, CastQueryValueTo<GLfloat>(pname, params[0]));
+ break;
+ case GL_TEXTURE_COMPARE_MODE:
+ sampler->setCompareMode(context, ConvertToGLenum(pname, params[0]));
+ break;
+ case GL_TEXTURE_COMPARE_FUNC:
+ sampler->setCompareFunc(context, ConvertToGLenum(pname, params[0]));
+ break;
+ case GL_TEXTURE_MIN_LOD:
+ sampler->setMinLod(context, CastQueryValueTo<GLfloat>(pname, params[0]));
+ break;
+ case GL_TEXTURE_MAX_LOD:
+ sampler->setMaxLod(context, CastQueryValueTo<GLfloat>(pname, params[0]));
+ break;
+ case GL_TEXTURE_SRGB_DECODE_EXT:
+ sampler->setSRGBDecode(context, ConvertToGLenum(pname, params[0]));
+ break;
+ case GL_TEXTURE_BORDER_COLOR:
+ sampler->setBorderColor(context, ConvertToColor<isPureInteger>(params));
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ sampler->onStateChange(angle::SubjectMessage::ContentsChanged);
+}
+
+// Warning: you should ensure binding really matches attrib.bindingIndex before using this function.
+template <typename ParamType, typename CurrentDataType, size_t CurrentValueCount>
+void QueryVertexAttribBase(const VertexAttribute &attrib,
+ const VertexBinding &binding,
+ const CurrentDataType (&currentValueData)[CurrentValueCount],
+ GLenum pname,
+ ParamType *params)
+{
+ switch (pname)
+ {
+ case GL_CURRENT_VERTEX_ATTRIB:
+ for (size_t i = 0; i < CurrentValueCount; ++i)
+ {
+ params[i] = CastFromStateValue<ParamType>(pname, currentValueData[i]);
+ }
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
+ *params = CastFromStateValue<ParamType>(pname, static_cast<GLint>(attrib.enabled));
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY_SIZE:
+ *params = CastFromGLintStateValue<ParamType>(pname, attrib.format->channelCount);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
+ *params = CastFromGLintStateValue<ParamType>(pname, attrib.vertexAttribArrayStride);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY_TYPE:
+ *params = CastFromGLintStateValue<ParamType>(
+ pname, gl::ToGLenum(attrib.format->vertexAttribType));
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
+ *params =
+ CastFromStateValue<ParamType>(pname, static_cast<GLint>(attrib.format->isNorm()));
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
+ *params = CastFromGLintStateValue<ParamType>(pname, binding.getBuffer().id().value);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
+ *params = CastFromStateValue<ParamType>(pname, binding.getDivisor());
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
+ *params = CastFromGLintStateValue<ParamType>(pname, attrib.format->isPureInt());
+ break;
+ case GL_VERTEX_ATTRIB_BINDING:
+ *params = CastFromGLintStateValue<ParamType>(pname, attrib.bindingIndex);
+ break;
+ case GL_VERTEX_ATTRIB_RELATIVE_OFFSET:
+ *params = CastFromGLintStateValue<ParamType>(pname, attrib.relativeOffset);
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+template <typename ParamType>
+void QueryBufferParameterBase(const Buffer *buffer, GLenum pname, ParamType *params)
+{
+ ASSERT(buffer != nullptr);
+
+ switch (pname)
+ {
+ case GL_BUFFER_USAGE:
+ *params = CastFromGLintStateValue<ParamType>(pname, ToGLenum(buffer->getUsage()));
+ break;
+ case GL_BUFFER_SIZE:
+ *params = CastFromStateValue<ParamType>(pname, buffer->getSize());
+ break;
+ case GL_BUFFER_ACCESS_FLAGS:
+ *params = CastFromGLintStateValue<ParamType>(pname, buffer->getAccessFlags());
+ break;
+ case GL_BUFFER_ACCESS_OES:
+ *params = CastFromGLintStateValue<ParamType>(pname, buffer->getAccess());
+ break;
+ case GL_BUFFER_MAPPED:
+ *params = CastFromStateValue<ParamType>(pname, buffer->isMapped());
+ break;
+ case GL_BUFFER_MAP_OFFSET:
+ *params = CastFromStateValue<ParamType>(pname, buffer->getMapOffset());
+ break;
+ case GL_BUFFER_MAP_LENGTH:
+ *params = CastFromStateValue<ParamType>(pname, buffer->getMapLength());
+ break;
+ case GL_MEMORY_SIZE_ANGLE:
+ *params = CastFromStateValue<ParamType>(pname, buffer->getMemorySize());
+ break;
+ case GL_BUFFER_IMMUTABLE_STORAGE_EXT:
+ *params = CastFromStateValue<ParamType>(pname, buffer->isImmutable());
+ break;
+ case GL_BUFFER_STORAGE_FLAGS_EXT:
+ *params = CastFromGLintStateValue<ParamType>(pname, buffer->getStorageExtUsageFlags());
+ break;
+ case GL_RESOURCE_INITIALIZED_ANGLE:
+ *params = CastFromStateValue<ParamType>(
+ pname, ConvertToGLBoolean(buffer->initState() == InitState::Initialized));
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+GLint GetCommonVariableProperty(const sh::ShaderVariable &var, GLenum prop)
+{
+ switch (prop)
+ {
+ case GL_TYPE:
+ return clampCast<GLint>(var.type);
+
+ case GL_ARRAY_SIZE:
+ // Queryable variables are guaranteed not to be arrays of arrays or arrays of structs,
+ // see GLES 3.1 spec section 7.3.1.1 page 77.
+ return clampCast<GLint>(var.getBasicTypeElementCount());
+
+ case GL_NAME_LENGTH:
+ // ES31 spec p84: This counts the terminating null char.
+ return clampCast<GLint>(var.name.size() + 1u);
+
+ default:
+ UNREACHABLE();
+ return GL_INVALID_VALUE;
+ }
+}
+
+GLint GetInputResourceProperty(const Program *program, GLuint index, GLenum prop)
+{
+ const sh::ShaderVariable &variable = program->getInputResource(index);
+
+ switch (prop)
+ {
+ case GL_TYPE:
+ case GL_ARRAY_SIZE:
+ return GetCommonVariableProperty(variable, prop);
+
+ case GL_NAME_LENGTH:
+ return clampCast<GLint>(program->getInputResourceName(index).size() + 1u);
+
+ case GL_LOCATION:
+ return variable.isBuiltIn() ? GL_INVALID_INDEX : variable.location;
+
+ // The query is targeted at the set of active input variables used by the first shader stage
+ // of program. If program contains multiple shader stages then input variables from any
+ // stage other than the first will not be enumerated. Since we found the variable to get
+ // this far, we know it exists in the first attached shader stage.
+ case GL_REFERENCED_BY_VERTEX_SHADER:
+ return program->getState().getFirstAttachedShaderStageType() == ShaderType::Vertex;
+ case GL_REFERENCED_BY_FRAGMENT_SHADER:
+ return program->getState().getFirstAttachedShaderStageType() == ShaderType::Fragment;
+ case GL_REFERENCED_BY_COMPUTE_SHADER:
+ return program->getState().getFirstAttachedShaderStageType() == ShaderType::Compute;
+ case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
+ return program->getState().getFirstAttachedShaderStageType() == ShaderType::Geometry;
+ case GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT:
+ return program->getState().getFirstAttachedShaderStageType() == ShaderType::TessControl;
+ case GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT:
+ return program->getState().getFirstAttachedShaderStageType() ==
+ ShaderType::TessEvaluation;
+ case GL_IS_PER_PATCH_EXT:
+ return variable.isPatch;
+
+ default:
+ UNREACHABLE();
+ return GL_INVALID_VALUE;
+ }
+}
+
+GLint GetOutputResourceProperty(const Program *program, GLuint index, const GLenum prop)
+{
+ const sh::ShaderVariable &outputVariable = program->getOutputResource(index);
+
+ switch (prop)
+ {
+ case GL_TYPE:
+ case GL_ARRAY_SIZE:
+ return GetCommonVariableProperty(outputVariable, prop);
+
+ case GL_NAME_LENGTH:
+ return clampCast<GLint>(program->getOutputResourceName(index).size() + 1u);
+
+ case GL_LOCATION:
+ return outputVariable.location;
+
+ case GL_LOCATION_INDEX_EXT:
+ // EXT_blend_func_extended
+ if (program->getState().getLastAttachedShaderStageType() == gl::ShaderType::Fragment)
+ {
+ return program->getFragDataIndex(outputVariable.name);
+ }
+ return GL_INVALID_INDEX;
+
+ // The set of active user-defined outputs from the final shader stage in this program. If
+ // the final stage is a Fragment Shader, then this represents the fragment outputs that get
+ // written to individual color buffers. If the program only contains a Compute Shader, then
+ // there are no user-defined outputs.
+ case GL_REFERENCED_BY_VERTEX_SHADER:
+ return program->getState().getLastAttachedShaderStageType() == ShaderType::Vertex;
+ case GL_REFERENCED_BY_FRAGMENT_SHADER:
+ return program->getState().getLastAttachedShaderStageType() == ShaderType::Fragment;
+ case GL_REFERENCED_BY_COMPUTE_SHADER:
+ return program->getState().getLastAttachedShaderStageType() == ShaderType::Compute;
+ case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
+ return program->getState().getLastAttachedShaderStageType() == ShaderType::Geometry;
+ case GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT:
+ return program->getState().getLastAttachedShaderStageType() == ShaderType::TessControl;
+ case GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT:
+ return program->getState().getLastAttachedShaderStageType() ==
+ ShaderType::TessEvaluation;
+ case GL_IS_PER_PATCH_EXT:
+ return outputVariable.isPatch;
+
+ default:
+ UNREACHABLE();
+ return GL_INVALID_VALUE;
+ }
+}
+
+GLint GetTransformFeedbackVaryingResourceProperty(const Program *program,
+ GLuint index,
+ const GLenum prop)
+{
+ const auto &tfVariable = program->getTransformFeedbackVaryingResource(index);
+ switch (prop)
+ {
+ case GL_TYPE:
+ return clampCast<GLint>(tfVariable.type);
+
+ case GL_ARRAY_SIZE:
+ return clampCast<GLint>(tfVariable.size());
+
+ case GL_NAME_LENGTH:
+ return clampCast<GLint>(tfVariable.nameWithArrayIndex().size() + 1);
+
+ default:
+ UNREACHABLE();
+ return GL_INVALID_VALUE;
+ }
+}
+
+GLint QueryProgramInterfaceActiveResources(const Program *program, GLenum programInterface)
+{
+ switch (programInterface)
+ {
+ case GL_PROGRAM_INPUT:
+ return clampCast<GLint>(program->getState().getProgramInputs().size());
+
+ case GL_PROGRAM_OUTPUT:
+ return clampCast<GLint>(program->getState().getOutputVariables().size());
+
+ case GL_UNIFORM:
+ return clampCast<GLint>(program->getState().getUniforms().size());
+
+ case GL_UNIFORM_BLOCK:
+ return clampCast<GLint>(program->getState().getUniformBlocks().size());
+
+ case GL_ATOMIC_COUNTER_BUFFER:
+ return clampCast<GLint>(program->getState().getAtomicCounterBuffers().size());
+
+ case GL_BUFFER_VARIABLE:
+ return clampCast<GLint>(program->getState().getBufferVariables().size());
+
+ case GL_SHADER_STORAGE_BLOCK:
+ return clampCast<GLint>(program->getState().getShaderStorageBlocks().size());
+
+ case GL_TRANSFORM_FEEDBACK_VARYING:
+ return clampCast<GLint>(program->getTransformFeedbackVaryingCount());
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+template <typename T, typename M>
+GLint FindMaxSize(const std::vector<T> &resources, M member)
+{
+ GLint max = 0;
+ for (const T &resource : resources)
+ {
+ max = std::max(max, clampCast<GLint>((resource.*member).size()));
+ }
+ return max;
+}
+
+GLint QueryProgramInterfaceMaxNameLength(const Program *program, GLenum programInterface)
+{
+ GLint maxNameLength = 0;
+ switch (programInterface)
+ {
+ case GL_PROGRAM_INPUT:
+ maxNameLength = program->getInputResourceMaxNameSize();
+ break;
+
+ case GL_PROGRAM_OUTPUT:
+ maxNameLength = program->getOutputResourceMaxNameSize();
+ break;
+
+ case GL_UNIFORM:
+ maxNameLength = FindMaxSize(program->getState().getUniforms(), &LinkedUniform::name);
+ break;
+
+ case GL_UNIFORM_BLOCK:
+ return program->getActiveUniformBlockMaxNameLength();
+
+ case GL_BUFFER_VARIABLE:
+ maxNameLength =
+ FindMaxSize(program->getState().getBufferVariables(), &BufferVariable::name);
+ break;
+
+ case GL_SHADER_STORAGE_BLOCK:
+ return program->getActiveShaderStorageBlockMaxNameLength();
+
+ case GL_TRANSFORM_FEEDBACK_VARYING:
+ return clampCast<GLint>(program->getTransformFeedbackVaryingMaxLength());
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+ // This length includes an extra character for the null terminator.
+ return (maxNameLength == 0 ? 0 : maxNameLength + 1);
+}
+
+GLint QueryProgramInterfaceMaxNumActiveVariables(const Program *program, GLenum programInterface)
+{
+ switch (programInterface)
+ {
+ case GL_UNIFORM_BLOCK:
+ return FindMaxSize(program->getState().getUniformBlocks(),
+ &InterfaceBlock::memberIndexes);
+ case GL_ATOMIC_COUNTER_BUFFER:
+ return FindMaxSize(program->getState().getAtomicCounterBuffers(),
+ &AtomicCounterBuffer::memberIndexes);
+
+ case GL_SHADER_STORAGE_BLOCK:
+ return FindMaxSize(program->getState().getShaderStorageBlocks(),
+ &InterfaceBlock::memberIndexes);
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+GLenum GetUniformPropertyEnum(GLenum prop)
+{
+ switch (prop)
+ {
+ case GL_UNIFORM_TYPE:
+ return GL_TYPE;
+ case GL_UNIFORM_SIZE:
+ return GL_ARRAY_SIZE;
+ case GL_UNIFORM_NAME_LENGTH:
+ return GL_NAME_LENGTH;
+ case GL_UNIFORM_BLOCK_INDEX:
+ return GL_BLOCK_INDEX;
+ case GL_UNIFORM_OFFSET:
+ return GL_OFFSET;
+ case GL_UNIFORM_ARRAY_STRIDE:
+ return GL_ARRAY_STRIDE;
+ case GL_UNIFORM_MATRIX_STRIDE:
+ return GL_MATRIX_STRIDE;
+ case GL_UNIFORM_IS_ROW_MAJOR:
+ return GL_IS_ROW_MAJOR;
+
+ default:
+ return prop;
+ }
+}
+
+GLenum GetUniformBlockPropertyEnum(GLenum prop)
+{
+ switch (prop)
+ {
+ case GL_UNIFORM_BLOCK_BINDING:
+ return GL_BUFFER_BINDING;
+
+ case GL_UNIFORM_BLOCK_DATA_SIZE:
+ return GL_BUFFER_DATA_SIZE;
+
+ case GL_UNIFORM_BLOCK_NAME_LENGTH:
+ return GL_NAME_LENGTH;
+
+ case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
+ return GL_NUM_ACTIVE_VARIABLES;
+
+ case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
+ return GL_ACTIVE_VARIABLES;
+
+ case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
+ return GL_REFERENCED_BY_VERTEX_SHADER;
+
+ case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
+ return GL_REFERENCED_BY_FRAGMENT_SHADER;
+
+ default:
+ return prop;
+ }
+}
+
+void GetShaderVariableBufferResourceProperty(const ShaderVariableBuffer &buffer,
+ GLenum pname,
+ GLint *params,
+ GLsizei bufSize,
+ GLsizei *outputPosition)
+
+{
+ switch (pname)
+ {
+ case GL_BUFFER_BINDING:
+ params[(*outputPosition)++] = buffer.binding;
+ break;
+ case GL_BUFFER_DATA_SIZE:
+ params[(*outputPosition)++] = clampCast<GLint>(buffer.dataSize);
+ break;
+ case GL_NUM_ACTIVE_VARIABLES:
+ params[(*outputPosition)++] = buffer.numActiveVariables();
+ break;
+ case GL_ACTIVE_VARIABLES:
+ for (size_t memberIndex = 0;
+ memberIndex < buffer.memberIndexes.size() && *outputPosition < bufSize;
+ ++memberIndex)
+ {
+ params[(*outputPosition)++] = clampCast<GLint>(buffer.memberIndexes[memberIndex]);
+ }
+ break;
+ case GL_REFERENCED_BY_VERTEX_SHADER:
+ params[(*outputPosition)++] = static_cast<GLint>(buffer.isActive(ShaderType::Vertex));
+ break;
+ case GL_REFERENCED_BY_FRAGMENT_SHADER:
+ params[(*outputPosition)++] = static_cast<GLint>(buffer.isActive(ShaderType::Fragment));
+ break;
+ case GL_REFERENCED_BY_COMPUTE_SHADER:
+ params[(*outputPosition)++] = static_cast<GLint>(buffer.isActive(ShaderType::Compute));
+ break;
+ case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
+ params[(*outputPosition)++] = static_cast<GLint>(buffer.isActive(ShaderType::Geometry));
+ break;
+ case GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT:
+ params[(*outputPosition)++] =
+ static_cast<GLint>(buffer.isActive(ShaderType::TessControl));
+ break;
+ case GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT:
+ params[(*outputPosition)++] =
+ static_cast<GLint>(buffer.isActive(ShaderType::TessEvaluation));
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+void GetInterfaceBlockResourceProperty(const InterfaceBlock &block,
+ GLenum pname,
+ GLint *params,
+ GLsizei bufSize,
+ GLsizei *outputPosition)
+{
+ if (pname == GL_NAME_LENGTH)
+ {
+ params[(*outputPosition)++] = clampCast<GLint>(block.nameWithArrayIndex().size() + 1);
+ return;
+ }
+ GetShaderVariableBufferResourceProperty(block, pname, params, bufSize, outputPosition);
+}
+
+void GetUniformBlockResourceProperty(const Program *program,
+ GLuint blockIndex,
+ GLenum pname,
+ GLint *params,
+ GLsizei bufSize,
+ GLsizei *outputPosition)
+
+{
+ ASSERT(*outputPosition < bufSize);
+ const auto &block = program->getUniformBlockByIndex(blockIndex);
+ GetInterfaceBlockResourceProperty(block, pname, params, bufSize, outputPosition);
+}
+
+void GetShaderStorageBlockResourceProperty(const Program *program,
+ GLuint blockIndex,
+ GLenum pname,
+ GLint *params,
+ GLsizei bufSize,
+ GLsizei *outputPosition)
+
+{
+ ASSERT(*outputPosition < bufSize);
+ const auto &block = program->getShaderStorageBlockByIndex(blockIndex);
+ GetInterfaceBlockResourceProperty(block, pname, params, bufSize, outputPosition);
+}
+
+void GetAtomicCounterBufferResourceProperty(const Program *program,
+ GLuint index,
+ GLenum pname,
+ GLint *params,
+ GLsizei bufSize,
+ GLsizei *outputPosition)
+
+{
+ ASSERT(*outputPosition < bufSize);
+ const auto &buffer = program->getState().getAtomicCounterBuffers()[index];
+ GetShaderVariableBufferResourceProperty(buffer, pname, params, bufSize, outputPosition);
+}
+
+bool IsTextureEnvEnumParameter(TextureEnvParameter pname)
+{
+ switch (pname)
+ {
+ case TextureEnvParameter::Mode:
+ case TextureEnvParameter::CombineRgb:
+ case TextureEnvParameter::CombineAlpha:
+ case TextureEnvParameter::Src0Rgb:
+ case TextureEnvParameter::Src1Rgb:
+ case TextureEnvParameter::Src2Rgb:
+ case TextureEnvParameter::Src0Alpha:
+ case TextureEnvParameter::Src1Alpha:
+ case TextureEnvParameter::Src2Alpha:
+ case TextureEnvParameter::Op0Rgb:
+ case TextureEnvParameter::Op1Rgb:
+ case TextureEnvParameter::Op2Rgb:
+ case TextureEnvParameter::Op0Alpha:
+ case TextureEnvParameter::Op1Alpha:
+ case TextureEnvParameter::Op2Alpha:
+ case TextureEnvParameter::PointCoordReplace:
+ return true;
+ default:
+ return false;
+ }
+}
+
+void GetShaderProgramId(ProgramPipeline *programPipeline, ShaderType shaderType, GLint *params)
+{
+ ASSERT(params);
+
+ *params = 0;
+ if (programPipeline)
+ {
+ const Program *program = programPipeline->getShaderProgram(shaderType);
+ if (program)
+ {
+ *params = program->id().value;
+ }
+ }
+}
+
+} // namespace
+
+void QueryFramebufferAttachmentParameteriv(const Context *context,
+ const Framebuffer *framebuffer,
+ GLenum attachment,
+ GLenum pname,
+ GLint *params)
+{
+ ASSERT(framebuffer);
+
+ const FramebufferAttachment *attachmentObject = framebuffer->getAttachment(context, 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:
+ {
+ TextureTarget face = attachmentObject->cubeMapFace();
+ if (face != TextureTarget::InvalidEnum)
+ {
+ *params = ToGLenum(attachmentObject->cubeMapFace());
+ }
+ else
+ {
+ // This happens when the attachment isn't a texture cube map face
+ *params = GL_NONE;
+ }
+ }
+ 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;
+
+ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR:
+ *params = attachmentObject->getNumViews();
+ break;
+
+ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR:
+ *params = attachmentObject->getBaseViewIndex();
+ break;
+
+ case GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT:
+ *params = attachmentObject->isLayered();
+ break;
+
+ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT:
+ if (attachmentObject->type() == GL_TEXTURE)
+ {
+ *params = attachmentObject->getSamples();
+ }
+ else
+ {
+ *params = 0;
+ }
+ break;
+
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+void QueryBufferParameteriv(const Buffer *buffer, GLenum pname, GLint *params)
+{
+ QueryBufferParameterBase(buffer, pname, params);
+}
+
+void QueryBufferParameteri64v(const Buffer *buffer, GLenum pname, GLint64 *params)
+{
+ QueryBufferParameterBase(buffer, pname, params);
+}
+
+void QueryBufferPointerv(const Buffer *buffer, GLenum pname, void **params)
+{
+ switch (pname)
+ {
+ case GL_BUFFER_MAP_POINTER:
+ *params = buffer->getMapPointer();
+ break;
+
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+void QueryProgramiv(Context *context, const Program *program, GLenum pname, GLint *params)
+{
+ ASSERT(program != nullptr || pname == GL_COMPLETION_STATUS_KHR);
+
+ switch (pname)
+ {
+ case GL_DELETE_STATUS:
+ *params = program->isFlaggedForDeletion();
+ return;
+ case GL_LINK_STATUS:
+ *params = program->isLinked();
+ return;
+ case GL_COMPLETION_STATUS_KHR:
+ if (context->isContextLost())
+ {
+ *params = GL_TRUE;
+ }
+ else
+ {
+ *params = program->isLinking() ? GL_FALSE : GL_TRUE;
+ }
+ return;
+ case GL_VALIDATE_STATUS:
+ *params = program->isValidated();
+ return;
+ case GL_INFO_LOG_LENGTH:
+ *params = program->getExecutable().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 = context->getCaps().programBinaryFormats.empty()
+ ? 0
+ : program->getBinaryLength(context);
+ return;
+ case GL_ACTIVE_UNIFORM_BLOCKS:
+ *params = program->getActiveUniformBlockCount();
+ return;
+ case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
+ *params = program->getActiveUniformBlockMaxNameLength();
+ break;
+ case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
+ *params = program->getTransformFeedbackBufferMode();
+ break;
+ case GL_TRANSFORM_FEEDBACK_VARYINGS:
+ *params = clampCast<GLint>(program->getTransformFeedbackVaryingCount());
+ break;
+ case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
+ *params = program->getTransformFeedbackVaryingMaxLength();
+ break;
+ case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
+ *params = program->getBinaryRetrievableHint();
+ break;
+ case GL_PROGRAM_SEPARABLE:
+ // From es31cSeparateShaderObjsTests.cpp:
+ // ProgramParameteri PROGRAM_SEPARABLE
+ // NOTE: The query for PROGRAM_SEPARABLE must query latched
+ // state. In other words, the state of the binary after
+ // it was linked. So in the tests below, the queries
+ // should return the default state GL_FALSE since the
+ // program has no linked binary.
+ *params = program->isSeparable() && program->isLinked();
+ break;
+ case GL_COMPUTE_WORK_GROUP_SIZE:
+ {
+ const sh::WorkGroupSize &localSize = program->getComputeShaderLocalSize();
+ params[0] = localSize[0];
+ params[1] = localSize[1];
+ params[2] = localSize[2];
+ }
+ break;
+ case GL_ACTIVE_ATOMIC_COUNTER_BUFFERS:
+ *params = program->getActiveAtomicCounterBufferCount();
+ break;
+ case GL_GEOMETRY_LINKED_INPUT_TYPE_EXT:
+ *params = ToGLenum(program->getGeometryShaderInputPrimitiveType());
+ break;
+ case GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT:
+ *params = ToGLenum(program->getGeometryShaderOutputPrimitiveType());
+ break;
+ case GL_GEOMETRY_LINKED_VERTICES_OUT_EXT:
+ *params = program->getGeometryShaderMaxVertices();
+ break;
+ case GL_GEOMETRY_SHADER_INVOCATIONS_EXT:
+ *params = program->getGeometryShaderInvocations();
+ break;
+ case GL_TESS_CONTROL_OUTPUT_VERTICES_EXT:
+ *params = program->getTessControlShaderVertices();
+ break;
+ case GL_TESS_GEN_MODE_EXT:
+ *params = program->getTessGenMode();
+ break;
+ case GL_TESS_GEN_SPACING_EXT:
+ *params = program->getTessGenSpacing() ? program->getTessGenSpacing() : GL_EQUAL;
+ break;
+ case GL_TESS_GEN_VERTEX_ORDER:
+ *params = program->getTessGenVertexOrder() ? program->getTessGenVertexOrder() : GL_CCW;
+ break;
+ case GL_TESS_GEN_POINT_MODE_EXT:
+ *params = program->getTessGenPointMode() ? GL_TRUE : GL_FALSE;
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+void QueryRenderbufferiv(const Context *context,
+ const Renderbuffer *renderbuffer,
+ GLenum pname,
+ GLint *params)
+{
+ ASSERT(renderbuffer != nullptr);
+
+ switch (pname)
+ {
+ case GL_RENDERBUFFER_WIDTH:
+ *params = renderbuffer->getWidth();
+ break;
+ case GL_RENDERBUFFER_HEIGHT:
+ *params = renderbuffer->getHeight();
+ break;
+ case GL_RENDERBUFFER_INTERNAL_FORMAT:
+ // Special case the WebGL 1 DEPTH_STENCIL format.
+ if (context->isWebGL1() &&
+ renderbuffer->getFormat().info->internalFormat == GL_DEPTH24_STENCIL8)
+ {
+ *params = GL_DEPTH_STENCIL;
+ }
+ else
+ {
+ *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:
+ *params = renderbuffer->getState().getSamples();
+ break;
+ case GL_MEMORY_SIZE_ANGLE:
+ *params = renderbuffer->getMemorySize();
+ break;
+ case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
+ *params = static_cast<GLint>(renderbuffer->getImplementationColorReadFormat(context));
+ break;
+ case GL_IMPLEMENTATION_COLOR_READ_TYPE:
+ *params = static_cast<GLint>(renderbuffer->getImplementationColorReadType(context));
+ break;
+ case GL_RESOURCE_INITIALIZED_ANGLE:
+ *params = (renderbuffer->initState(GL_NONE, ImageIndex()) == InitState::Initialized);
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+void QueryShaderiv(const Context *context, Shader *shader, GLenum pname, GLint *params)
+{
+ ASSERT(shader != nullptr || pname == GL_COMPLETION_STATUS_KHR);
+
+ switch (pname)
+ {
+ case GL_SHADER_TYPE:
+ *params = static_cast<GLint>(ToGLenum(shader->getType()));
+ return;
+ case GL_DELETE_STATUS:
+ *params = shader->isFlaggedForDeletion();
+ return;
+ case GL_COMPILE_STATUS:
+ *params = shader->isCompiled(context) ? GL_TRUE : GL_FALSE;
+ return;
+ case GL_COMPLETION_STATUS_KHR:
+ if (context->isContextLost())
+ {
+ *params = GL_TRUE;
+ }
+ else
+ {
+ *params = shader->isCompleted() ? GL_TRUE : GL_FALSE;
+ }
+ return;
+ case GL_INFO_LOG_LENGTH:
+ *params = shader->getInfoLogLength(context);
+ return;
+ case GL_SHADER_SOURCE_LENGTH:
+ *params = shader->getSourceLength();
+ return;
+ case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
+ *params = shader->getTranslatedSourceWithDebugInfoLength(context);
+ return;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+void QueryTexLevelParameterfv(const Texture *texture,
+ TextureTarget target,
+ GLint level,
+ GLenum pname,
+ GLfloat *params)
+{
+ QueryTexLevelParameterBase(texture, target, level, pname, params);
+}
+
+void QueryTexLevelParameteriv(const Texture *texture,
+ TextureTarget target,
+ GLint level,
+ GLenum pname,
+ GLint *params)
+{
+ QueryTexLevelParameterBase(texture, target, level, pname, params);
+}
+
+void QueryTexParameterfv(const Context *context,
+ const Texture *texture,
+ GLenum pname,
+ GLfloat *params)
+{
+ QueryTexParameterBase<false, false>(context, texture, pname, params);
+}
+
+void QueryTexParameterxv(const Context *context,
+ const Texture *texture,
+ GLenum pname,
+ GLfixed *params)
+{
+ QueryTexParameterBase<false, true>(context, texture, pname, params);
+}
+
+void QueryTexParameteriv(const Context *context,
+ const Texture *texture,
+ GLenum pname,
+ GLint *params)
+{
+ QueryTexParameterBase<false, false>(context, texture, pname, params);
+}
+
+void QueryTexParameterIiv(const Context *context,
+ const Texture *texture,
+ GLenum pname,
+ GLint *params)
+{
+ QueryTexParameterBase<true, false>(context, texture, pname, params);
+}
+
+void QueryTexParameterIuiv(const Context *context,
+ const Texture *texture,
+ GLenum pname,
+ GLuint *params)
+{
+ QueryTexParameterBase<true, false>(context, texture, pname, params);
+}
+
+void QuerySamplerParameterfv(const Sampler *sampler, GLenum pname, GLfloat *params)
+{
+ QuerySamplerParameterBase<false>(sampler, pname, params);
+}
+
+void QuerySamplerParameteriv(const Sampler *sampler, GLenum pname, GLint *params)
+{
+ QuerySamplerParameterBase<false>(sampler, pname, params);
+}
+
+void QuerySamplerParameterIiv(const Sampler *sampler, GLenum pname, GLint *params)
+{
+ QuerySamplerParameterBase<true>(sampler, pname, params);
+}
+
+void QuerySamplerParameterIuiv(const Sampler *sampler, GLenum pname, GLuint *params)
+{
+ QuerySamplerParameterBase<true>(sampler, pname, params);
+}
+
+void QueryVertexAttribfv(const VertexAttribute &attrib,
+ const VertexBinding &binding,
+ const VertexAttribCurrentValueData &currentValueData,
+ GLenum pname,
+ GLfloat *params)
+{
+ QueryVertexAttribBase(attrib, binding, currentValueData.Values.FloatValues, pname, params);
+}
+
+void QueryVertexAttribiv(const VertexAttribute &attrib,
+ const VertexBinding &binding,
+ const VertexAttribCurrentValueData &currentValueData,
+ GLenum pname,
+ GLint *params)
+{
+ QueryVertexAttribBase(attrib, binding, currentValueData.Values.FloatValues, pname, params);
+}
+
+void QueryVertexAttribPointerv(const VertexAttribute &attrib, GLenum pname, void **pointer)
+{
+ switch (pname)
+ {
+ case GL_VERTEX_ATTRIB_ARRAY_POINTER:
+ *pointer = const_cast<void *>(attrib.pointer);
+ break;
+
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+void QueryVertexAttribIiv(const VertexAttribute &attrib,
+ const VertexBinding &binding,
+ const VertexAttribCurrentValueData &currentValueData,
+ GLenum pname,
+ GLint *params)
+{
+ QueryVertexAttribBase(attrib, binding, currentValueData.Values.IntValues, pname, params);
+}
+
+void QueryVertexAttribIuiv(const VertexAttribute &attrib,
+ const VertexBinding &binding,
+ const VertexAttribCurrentValueData &currentValueData,
+ GLenum pname,
+ GLuint *params)
+{
+ QueryVertexAttribBase(attrib, binding, currentValueData.Values.UnsignedIntValues, pname,
+ params);
+}
+
+void QueryActiveUniformBlockiv(const Program *program,
+ UniformBlockIndex uniformBlockIndex,
+ GLenum pname,
+ GLint *params)
+{
+ GLenum prop = GetUniformBlockPropertyEnum(pname);
+ QueryProgramResourceiv(program, GL_UNIFORM_BLOCK, uniformBlockIndex, 1, &prop,
+ std::numeric_limits<GLsizei>::max(), nullptr, params);
+}
+
+void QueryInternalFormativ(const TextureCaps &format, GLenum pname, GLsizei bufSize, GLint *params)
+{
+ switch (pname)
+ {
+ case GL_NUM_SAMPLE_COUNTS:
+ if (bufSize != 0)
+ {
+ *params = clampCast<GLint>(format.sampleCounts.size());
+ }
+ break;
+
+ case GL_SAMPLES:
+ {
+ size_t returnCount = std::min<size_t>(bufSize, format.sampleCounts.size());
+ auto sampleReverseIt = format.sampleCounts.rbegin();
+ for (size_t sampleIndex = 0; sampleIndex < returnCount; ++sampleIndex)
+ {
+ params[sampleIndex] = *sampleReverseIt++;
+ }
+ }
+ break;
+
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+void QueryFramebufferParameteriv(const Framebuffer *framebuffer, GLenum pname, GLint *params)
+{
+ ASSERT(framebuffer);
+
+ switch (pname)
+ {
+ case GL_FRAMEBUFFER_DEFAULT_WIDTH:
+ *params = framebuffer->getDefaultWidth();
+ break;
+ case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
+ *params = framebuffer->getDefaultHeight();
+ break;
+ case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
+ *params = framebuffer->getDefaultSamples();
+ break;
+ case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
+ *params = ConvertToGLBoolean(framebuffer->getDefaultFixedSampleLocations());
+ break;
+ case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
+ *params = framebuffer->getDefaultLayers();
+ break;
+ case GL_FRAMEBUFFER_FLIP_Y_MESA:
+ *params = ConvertToGLBoolean(framebuffer->getFlipY());
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+angle::Result QuerySynciv(const Context *context,
+ const Sync *sync,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *values)
+{
+ ASSERT(sync != nullptr || pname == GL_SYNC_STATUS);
+
+ // All queries return one value, exit early if the buffer can't fit anything.
+ if (bufSize < 1)
+ {
+ if (length != nullptr)
+ {
+ *length = 0;
+ }
+ return angle::Result::Continue;
+ }
+
+ switch (pname)
+ {
+ case GL_OBJECT_TYPE:
+ *values = clampCast<GLint>(GL_SYNC_FENCE);
+ break;
+ case GL_SYNC_CONDITION:
+ *values = clampCast<GLint>(sync->getCondition());
+ break;
+ case GL_SYNC_FLAGS:
+ *values = clampCast<GLint>(sync->getFlags());
+ break;
+ case GL_SYNC_STATUS:
+ if (context->isContextLost())
+ {
+ *values = GL_SIGNALED;
+ }
+ else
+ {
+ ANGLE_TRY(sync->getStatus(context, values));
+ }
+ break;
+
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ if (length != nullptr)
+ {
+ *length = 1;
+ }
+
+ return angle::Result::Continue;
+}
+
+void SetTexParameterx(Context *context, Texture *texture, GLenum pname, GLfixed param)
+{
+ SetTexParameterBase<false, true>(context, texture, pname, &param);
+}
+
+void SetTexParameterxv(Context *context, Texture *texture, GLenum pname, const GLfixed *params)
+{
+ SetTexParameterBase<false, true>(context, texture, pname, params);
+}
+
+void SetTexParameterf(Context *context, Texture *texture, GLenum pname, GLfloat param)
+{
+ SetTexParameterBase<false, false>(context, texture, pname, &param);
+}
+
+void SetTexParameterfv(Context *context, Texture *texture, GLenum pname, const GLfloat *params)
+{
+ SetTexParameterBase<false, false>(context, texture, pname, params);
+}
+
+void SetTexParameteri(Context *context, Texture *texture, GLenum pname, GLint param)
+{
+ SetTexParameterBase<false, false>(context, texture, pname, &param);
+}
+
+void SetTexParameteriv(Context *context, Texture *texture, GLenum pname, const GLint *params)
+{
+ SetTexParameterBase<false, false>(context, texture, pname, params);
+}
+
+void SetTexParameterIiv(Context *context, Texture *texture, GLenum pname, const GLint *params)
+{
+ SetTexParameterBase<true, false>(context, texture, pname, params);
+}
+
+void SetTexParameterIuiv(Context *context, Texture *texture, GLenum pname, const GLuint *params)
+{
+ SetTexParameterBase<true, false>(context, texture, pname, params);
+}
+
+void SetSamplerParameterf(Context *context, Sampler *sampler, GLenum pname, GLfloat param)
+{
+ SetSamplerParameterBase<false>(context, sampler, pname, &param);
+}
+
+void SetSamplerParameterfv(Context *context, Sampler *sampler, GLenum pname, const GLfloat *params)
+{
+ SetSamplerParameterBase<false>(context, sampler, pname, params);
+}
+
+void SetSamplerParameteri(Context *context, Sampler *sampler, GLenum pname, GLint param)
+{
+ SetSamplerParameterBase<false>(context, sampler, pname, &param);
+}
+
+void SetSamplerParameteriv(Context *context, Sampler *sampler, GLenum pname, const GLint *params)
+{
+ SetSamplerParameterBase<false>(context, sampler, pname, params);
+}
+
+void SetSamplerParameterIiv(Context *context, Sampler *sampler, GLenum pname, const GLint *params)
+{
+ SetSamplerParameterBase<true>(context, sampler, pname, params);
+}
+
+void SetSamplerParameterIuiv(Context *context, Sampler *sampler, GLenum pname, const GLuint *params)
+{
+ SetSamplerParameterBase<true>(context, sampler, pname, params);
+}
+
+void SetFramebufferParameteri(const Context *context,
+ Framebuffer *framebuffer,
+ GLenum pname,
+ GLint param)
+{
+ ASSERT(framebuffer);
+
+ switch (pname)
+ {
+ case GL_FRAMEBUFFER_DEFAULT_WIDTH:
+ framebuffer->setDefaultWidth(context, param);
+ break;
+ case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
+ framebuffer->setDefaultHeight(context, param);
+ break;
+ case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
+ framebuffer->setDefaultSamples(context, param);
+ break;
+ case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
+ framebuffer->setDefaultFixedSampleLocations(context, ConvertToBool(param));
+ break;
+ case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
+ framebuffer->setDefaultLayers(param);
+ break;
+ case GL_FRAMEBUFFER_FLIP_Y_MESA:
+ framebuffer->setFlipY(ConvertToBool(param));
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+void SetProgramParameteri(Program *program, GLenum pname, GLint value)
+{
+ ASSERT(program);
+
+ switch (pname)
+ {
+ case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
+ program->setBinaryRetrievableHint(ConvertToBool(value));
+ break;
+ case GL_PROGRAM_SEPARABLE:
+ program->setSeparable(ConvertToBool(value));
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+GLint GetUniformResourceProperty(const Program *program, GLuint index, const GLenum prop)
+{
+ const auto &uniform = program->getUniformByIndex(index);
+ GLenum resourceProp = GetUniformPropertyEnum(prop);
+ switch (resourceProp)
+ {
+ case GL_TYPE:
+ case GL_ARRAY_SIZE:
+ case GL_NAME_LENGTH:
+ return GetCommonVariableProperty(uniform, resourceProp);
+
+ case GL_LOCATION:
+ return program->getUniformLocation(uniform.name).value;
+
+ case GL_BLOCK_INDEX:
+ return (uniform.isAtomicCounter() ? -1 : uniform.bufferIndex);
+
+ case GL_OFFSET:
+ return uniform.blockInfo.offset;
+
+ case GL_ARRAY_STRIDE:
+ return uniform.blockInfo.arrayStride;
+
+ case GL_MATRIX_STRIDE:
+ return uniform.blockInfo.matrixStride;
+
+ case GL_IS_ROW_MAJOR:
+ return static_cast<GLint>(uniform.blockInfo.isRowMajorMatrix);
+
+ case GL_REFERENCED_BY_VERTEX_SHADER:
+ return uniform.isActive(ShaderType::Vertex);
+
+ case GL_REFERENCED_BY_FRAGMENT_SHADER:
+ return uniform.isActive(ShaderType::Fragment);
+
+ case GL_REFERENCED_BY_COMPUTE_SHADER:
+ return uniform.isActive(ShaderType::Compute);
+
+ case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
+ return uniform.isActive(ShaderType::Geometry);
+
+ case GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT:
+ return uniform.isActive(ShaderType::TessControl);
+
+ case GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT:
+ return uniform.isActive(ShaderType::TessEvaluation);
+
+ case GL_ATOMIC_COUNTER_BUFFER_INDEX:
+ return (uniform.isAtomicCounter() ? uniform.bufferIndex : -1);
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+GLint GetBufferVariableResourceProperty(const Program *program, GLuint index, const GLenum prop)
+{
+ const BufferVariable &bufferVariable = program->getBufferVariableByIndex(index);
+ switch (prop)
+ {
+ case GL_TYPE:
+ case GL_ARRAY_SIZE:
+ case GL_NAME_LENGTH:
+ return GetCommonVariableProperty(bufferVariable, prop);
+
+ case GL_BLOCK_INDEX:
+ return bufferVariable.bufferIndex;
+
+ case GL_OFFSET:
+ return bufferVariable.blockInfo.offset;
+
+ case GL_ARRAY_STRIDE:
+ return bufferVariable.blockInfo.arrayStride;
+
+ case GL_MATRIX_STRIDE:
+ return bufferVariable.blockInfo.matrixStride;
+
+ case GL_IS_ROW_MAJOR:
+ return static_cast<GLint>(bufferVariable.blockInfo.isRowMajorMatrix);
+
+ case GL_REFERENCED_BY_VERTEX_SHADER:
+ return bufferVariable.isActive(ShaderType::Vertex);
+
+ case GL_REFERENCED_BY_FRAGMENT_SHADER:
+ return bufferVariable.isActive(ShaderType::Fragment);
+
+ case GL_REFERENCED_BY_COMPUTE_SHADER:
+ return bufferVariable.isActive(ShaderType::Compute);
+
+ case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
+ return bufferVariable.isActive(ShaderType::Geometry);
+
+ case GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT:
+ return bufferVariable.isActive(ShaderType::TessControl);
+
+ case GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT:
+ return bufferVariable.isActive(ShaderType::TessEvaluation);
+
+ case GL_TOP_LEVEL_ARRAY_SIZE:
+ return bufferVariable.topLevelArraySize;
+
+ case GL_TOP_LEVEL_ARRAY_STRIDE:
+ return bufferVariable.blockInfo.topLevelArrayStride;
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+GLuint QueryProgramResourceIndex(const Program *program,
+ GLenum programInterface,
+ const GLchar *name)
+{
+ switch (programInterface)
+ {
+ case GL_PROGRAM_INPUT:
+ return program->getInputResourceIndex(name);
+
+ case GL_PROGRAM_OUTPUT:
+ return program->getOutputResourceIndex(name);
+
+ case GL_UNIFORM:
+ return program->getState().getUniformIndexFromName(name);
+
+ case GL_BUFFER_VARIABLE:
+ return program->getState().getBufferVariableIndexFromName(name);
+
+ case GL_SHADER_STORAGE_BLOCK:
+ return program->getShaderStorageBlockIndex(name);
+
+ case GL_UNIFORM_BLOCK:
+ return program->getUniformBlockIndex(name);
+
+ case GL_TRANSFORM_FEEDBACK_VARYING:
+ return program->getTransformFeedbackVaryingResourceIndex(name);
+
+ default:
+ UNREACHABLE();
+ return GL_INVALID_INDEX;
+ }
+}
+
+void QueryProgramResourceName(const Context *context,
+ const Program *program,
+ GLenum programInterface,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *name)
+{
+ switch (programInterface)
+ {
+ case GL_PROGRAM_INPUT:
+ program->getInputResourceName(index, bufSize, length, name);
+ break;
+
+ case GL_PROGRAM_OUTPUT:
+ program->getOutputResourceName(index, bufSize, length, name);
+ break;
+
+ case GL_UNIFORM:
+ program->getUniformResourceName(index, bufSize, length, name);
+ break;
+
+ case GL_BUFFER_VARIABLE:
+ program->getBufferVariableResourceName(index, bufSize, length, name);
+ break;
+
+ case GL_SHADER_STORAGE_BLOCK:
+ program->getActiveShaderStorageBlockName(index, bufSize, length, name);
+ break;
+
+ case GL_UNIFORM_BLOCK:
+ program->getActiveUniformBlockName(context, {index}, bufSize, length, name);
+ break;
+
+ case GL_TRANSFORM_FEEDBACK_VARYING:
+ program->getTransformFeedbackVarying(index, bufSize, length, nullptr, nullptr, name);
+ break;
+
+ default:
+ UNREACHABLE();
+ }
+}
+
+GLint QueryProgramResourceLocation(const Program *program,
+ GLenum programInterface,
+ const GLchar *name)
+{
+ switch (programInterface)
+ {
+ case GL_PROGRAM_INPUT:
+ return program->getInputResourceLocation(name);
+
+ case GL_PROGRAM_OUTPUT:
+ return program->getOutputResourceLocation(name);
+
+ case GL_UNIFORM:
+ return program->getUniformLocation(name).value;
+
+ default:
+ UNREACHABLE();
+ return -1;
+ }
+}
+
+void QueryProgramResourceiv(const Program *program,
+ GLenum programInterface,
+ UniformBlockIndex index,
+ GLsizei propCount,
+ const GLenum *props,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ if (!program->isLinked())
+ {
+ return;
+ }
+
+ if (length != nullptr)
+ {
+ *length = 0;
+ }
+
+ if (bufSize == 0)
+ {
+ // No room to write the results
+ return;
+ }
+
+ GLsizei pos = 0;
+ for (GLsizei i = 0; i < propCount; i++)
+ {
+ switch (programInterface)
+ {
+ case GL_PROGRAM_INPUT:
+ params[i] = GetInputResourceProperty(program, index.value, props[i]);
+ ++pos;
+ break;
+
+ case GL_PROGRAM_OUTPUT:
+ params[i] = GetOutputResourceProperty(program, index.value, props[i]);
+ ++pos;
+ break;
+
+ case GL_UNIFORM:
+ params[i] = GetUniformResourceProperty(program, index.value, props[i]);
+ ++pos;
+ break;
+
+ case GL_BUFFER_VARIABLE:
+ params[i] = GetBufferVariableResourceProperty(program, index.value, props[i]);
+ ++pos;
+ break;
+
+ case GL_UNIFORM_BLOCK:
+ GetUniformBlockResourceProperty(program, index.value, props[i], params, bufSize,
+ &pos);
+ break;
+
+ case GL_SHADER_STORAGE_BLOCK:
+ GetShaderStorageBlockResourceProperty(program, index.value, props[i], params,
+ bufSize, &pos);
+ break;
+
+ case GL_ATOMIC_COUNTER_BUFFER:
+ GetAtomicCounterBufferResourceProperty(program, index.value, props[i], params,
+ bufSize, &pos);
+ break;
+
+ case GL_TRANSFORM_FEEDBACK_VARYING:
+ params[i] =
+ GetTransformFeedbackVaryingResourceProperty(program, index.value, props[i]);
+ ++pos;
+ break;
+
+ default:
+ UNREACHABLE();
+ params[i] = GL_INVALID_VALUE;
+ }
+ if (pos == bufSize)
+ {
+ // Most properties return one value, but GL_ACTIVE_VARIABLES returns an array of values.
+ // This checks not to break buffer bounds for such case.
+ break;
+ }
+ }
+
+ if (length != nullptr)
+ {
+ *length = pos;
+ }
+}
+
+void QueryProgramInterfaceiv(const Program *program,
+ GLenum programInterface,
+ GLenum pname,
+ GLint *params)
+{
+ switch (pname)
+ {
+ case GL_ACTIVE_RESOURCES:
+ *params = QueryProgramInterfaceActiveResources(program, programInterface);
+ break;
+
+ case GL_MAX_NAME_LENGTH:
+ *params = QueryProgramInterfaceMaxNameLength(program, programInterface);
+ break;
+
+ case GL_MAX_NUM_ACTIVE_VARIABLES:
+ *params = QueryProgramInterfaceMaxNumActiveVariables(program, programInterface);
+ break;
+
+ default:
+ UNREACHABLE();
+ }
+}
+
+angle::Result SetMemoryObjectParameteriv(const Context *context,
+ MemoryObject *memoryObject,
+ GLenum pname,
+ const GLint *params)
+{
+ switch (pname)
+ {
+ case GL_DEDICATED_MEMORY_OBJECT_EXT:
+ ANGLE_TRY(memoryObject->setDedicatedMemory(context, ConvertToBool(params[0])));
+ break;
+
+ case GL_PROTECTED_MEMORY_OBJECT_EXT:
+ ANGLE_TRY(memoryObject->setProtectedMemory(context, ConvertToBool(params[0])));
+ break;
+
+ default:
+ UNREACHABLE();
+ }
+
+ return angle::Result::Continue;
+}
+
+void QueryMemoryObjectParameteriv(const MemoryObject *memoryObject, GLenum pname, GLint *params)
+{
+ switch (pname)
+ {
+ case GL_DEDICATED_MEMORY_OBJECT_EXT:
+ *params = memoryObject->isDedicatedMemory();
+ break;
+
+ case GL_PROTECTED_MEMORY_OBJECT_EXT:
+ *params = memoryObject->isProtectedMemory();
+ break;
+
+ default:
+ UNREACHABLE();
+ }
+}
+
+ClientVertexArrayType ParamToVertexArrayType(GLenum param)
+{
+ switch (param)
+ {
+ case GL_VERTEX_ARRAY:
+ case GL_VERTEX_ARRAY_BUFFER_BINDING:
+ case GL_VERTEX_ARRAY_STRIDE:
+ case GL_VERTEX_ARRAY_SIZE:
+ case GL_VERTEX_ARRAY_TYPE:
+ case GL_VERTEX_ARRAY_POINTER:
+ return ClientVertexArrayType::Vertex;
+ case GL_NORMAL_ARRAY:
+ case GL_NORMAL_ARRAY_BUFFER_BINDING:
+ case GL_NORMAL_ARRAY_STRIDE:
+ case GL_NORMAL_ARRAY_TYPE:
+ case GL_NORMAL_ARRAY_POINTER:
+ return ClientVertexArrayType::Normal;
+ case GL_COLOR_ARRAY:
+ case GL_COLOR_ARRAY_BUFFER_BINDING:
+ case GL_COLOR_ARRAY_STRIDE:
+ case GL_COLOR_ARRAY_SIZE:
+ case GL_COLOR_ARRAY_TYPE:
+ case GL_COLOR_ARRAY_POINTER:
+ return ClientVertexArrayType::Color;
+ case GL_POINT_SIZE_ARRAY_OES:
+ case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
+ case GL_POINT_SIZE_ARRAY_STRIDE_OES:
+ case GL_POINT_SIZE_ARRAY_TYPE_OES:
+ case GL_POINT_SIZE_ARRAY_POINTER_OES:
+ return ClientVertexArrayType::PointSize;
+ case GL_TEXTURE_COORD_ARRAY:
+ case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
+ case GL_TEXTURE_COORD_ARRAY_STRIDE:
+ case GL_TEXTURE_COORD_ARRAY_SIZE:
+ case GL_TEXTURE_COORD_ARRAY_TYPE:
+ case GL_TEXTURE_COORD_ARRAY_POINTER:
+ return ClientVertexArrayType::TextureCoord;
+ default:
+ UNREACHABLE();
+ return ClientVertexArrayType::InvalidEnum;
+ }
+}
+
+void SetLightModelParameters(GLES1State *state, GLenum pname, const GLfloat *params)
+{
+ LightModelParameters &lightModel = state->lightModelParameters();
+
+ switch (pname)
+ {
+ case GL_LIGHT_MODEL_AMBIENT:
+ lightModel.color = ColorF::fromData(params);
+ break;
+ case GL_LIGHT_MODEL_TWO_SIDE:
+ lightModel.twoSided = *params == 1.0f ? true : false;
+ break;
+ default:
+ break;
+ }
+}
+
+void GetLightModelParameters(const GLES1State *state, GLenum pname, GLfloat *params)
+{
+ const LightModelParameters &lightModel = state->lightModelParameters();
+
+ switch (pname)
+ {
+ case GL_LIGHT_MODEL_TWO_SIDE:
+ *params = lightModel.twoSided ? 1.0f : 0.0f;
+ break;
+ case GL_LIGHT_MODEL_AMBIENT:
+ lightModel.color.writeData(params);
+ break;
+ default:
+ break;
+ }
+}
+
+bool IsLightModelTwoSided(const GLES1State *state)
+{
+ return state->lightModelParameters().twoSided;
+}
+
+void SetLightParameters(GLES1State *state,
+ GLenum light,
+ LightParameter pname,
+ const GLfloat *params)
+{
+ uint32_t lightIndex = light - GL_LIGHT0;
+
+ LightParameters &lightParams = state->lightParameters(lightIndex);
+
+ switch (pname)
+ {
+ case LightParameter::Ambient:
+ lightParams.ambient = ColorF::fromData(params);
+ break;
+ case LightParameter::Diffuse:
+ lightParams.diffuse = ColorF::fromData(params);
+ break;
+ case LightParameter::Specular:
+ lightParams.specular = ColorF::fromData(params);
+ break;
+ case LightParameter::Position:
+ {
+ angle::Mat4 mv = state->getModelviewMatrix();
+ angle::Vector4 transformedPos =
+ mv.product(angle::Vector4(params[0], params[1], params[2], params[3]));
+ lightParams.position[0] = transformedPos[0];
+ lightParams.position[1] = transformedPos[1];
+ lightParams.position[2] = transformedPos[2];
+ lightParams.position[3] = transformedPos[3];
+ }
+ break;
+ case LightParameter::SpotDirection:
+ {
+ angle::Mat4 mv = state->getModelviewMatrix();
+ angle::Vector4 transformedPos =
+ mv.product(angle::Vector4(params[0], params[1], params[2], 0.0f));
+ lightParams.direction[0] = transformedPos[0];
+ lightParams.direction[1] = transformedPos[1];
+ lightParams.direction[2] = transformedPos[2];
+ }
+ break;
+ case LightParameter::SpotExponent:
+ lightParams.spotlightExponent = *params;
+ break;
+ case LightParameter::SpotCutoff:
+ lightParams.spotlightCutoffAngle = *params;
+ break;
+ case LightParameter::ConstantAttenuation:
+ lightParams.attenuationConst = *params;
+ break;
+ case LightParameter::LinearAttenuation:
+ lightParams.attenuationLinear = *params;
+ break;
+ case LightParameter::QuadraticAttenuation:
+ lightParams.attenuationQuadratic = *params;
+ break;
+ default:
+ return;
+ }
+}
+
+void GetLightParameters(const GLES1State *state,
+ GLenum light,
+ LightParameter pname,
+ GLfloat *params)
+{
+ uint32_t lightIndex = light - GL_LIGHT0;
+ const LightParameters &lightParams = state->lightParameters(lightIndex);
+
+ switch (pname)
+ {
+ case LightParameter::Ambient:
+ lightParams.ambient.writeData(params);
+ break;
+ case LightParameter::Diffuse:
+ lightParams.diffuse.writeData(params);
+ break;
+ case LightParameter::Specular:
+ lightParams.specular.writeData(params);
+ break;
+ case LightParameter::Position:
+ memcpy(params, lightParams.position.data(), 4 * sizeof(GLfloat));
+ break;
+ case LightParameter::SpotDirection:
+ memcpy(params, lightParams.direction.data(), 3 * sizeof(GLfloat));
+ break;
+ case LightParameter::SpotExponent:
+ *params = lightParams.spotlightExponent;
+ break;
+ case LightParameter::SpotCutoff:
+ *params = lightParams.spotlightCutoffAngle;
+ break;
+ case LightParameter::ConstantAttenuation:
+ *params = lightParams.attenuationConst;
+ break;
+ case LightParameter::LinearAttenuation:
+ *params = lightParams.attenuationLinear;
+ break;
+ case LightParameter::QuadraticAttenuation:
+ *params = lightParams.attenuationQuadratic;
+ break;
+ default:
+ break;
+ }
+}
+
+void SetMaterialParameters(GLES1State *state,
+ GLenum face,
+ MaterialParameter pname,
+ const GLfloat *params)
+{
+ // Note: Ambient and diffuse colors are inherited from glColor when COLOR_MATERIAL is enabled,
+ // and can only be modified by this function if that is disabled:
+ //
+ // > the replaced values remain until changed by either sending a new color or by setting a
+ // > new material value when COLOR_MATERIAL is not currently enabled, to override that
+ // particular value.
+
+ MaterialParameters &material = state->materialParameters();
+ switch (pname)
+ {
+ case MaterialParameter::Ambient:
+ if (!state->isColorMaterialEnabled())
+ {
+ material.ambient = ColorF::fromData(params);
+ }
+ break;
+ case MaterialParameter::Diffuse:
+ if (!state->isColorMaterialEnabled())
+ {
+ material.diffuse = ColorF::fromData(params);
+ }
+ break;
+ case MaterialParameter::AmbientAndDiffuse:
+ if (!state->isColorMaterialEnabled())
+ {
+ material.ambient = ColorF::fromData(params);
+ material.diffuse = ColorF::fromData(params);
+ }
+ break;
+ case MaterialParameter::Specular:
+ material.specular = ColorF::fromData(params);
+ break;
+ case MaterialParameter::Emission:
+ material.emissive = ColorF::fromData(params);
+ break;
+ case MaterialParameter::Shininess:
+ material.specularExponent = *params;
+ break;
+ default:
+ return;
+ }
+}
+
+void GetMaterialParameters(const GLES1State *state,
+ GLenum face,
+ MaterialParameter pname,
+ GLfloat *params)
+{
+ const ColorF &currentColor = state->getCurrentColor();
+ const MaterialParameters &material = state->materialParameters();
+ const bool colorMaterialEnabled = state->isColorMaterialEnabled();
+
+ switch (pname)
+ {
+ case MaterialParameter::Ambient:
+ if (colorMaterialEnabled)
+ {
+ currentColor.writeData(params);
+ }
+ else
+ {
+ material.ambient.writeData(params);
+ }
+ break;
+ case MaterialParameter::Diffuse:
+ if (colorMaterialEnabled)
+ {
+ currentColor.writeData(params);
+ }
+ else
+ {
+ material.diffuse.writeData(params);
+ }
+ break;
+ case MaterialParameter::Specular:
+ material.specular.writeData(params);
+ break;
+ case MaterialParameter::Emission:
+ material.emissive.writeData(params);
+ break;
+ case MaterialParameter::Shininess:
+ *params = material.specularExponent;
+ break;
+ default:
+ return;
+ }
+}
+
+unsigned int GetLightModelParameterCount(GLenum pname)
+{
+ switch (pname)
+ {
+ case GL_LIGHT_MODEL_AMBIENT:
+ return 4;
+ case GL_LIGHT_MODEL_TWO_SIDE:
+ return 1;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+unsigned int GetLightParameterCount(LightParameter pname)
+{
+ switch (pname)
+ {
+ case LightParameter::Ambient:
+ case LightParameter::Diffuse:
+ case LightParameter::AmbientAndDiffuse:
+ case LightParameter::Specular:
+ case LightParameter::Position:
+ return 4;
+ case LightParameter::SpotDirection:
+ return 3;
+ case LightParameter::SpotExponent:
+ case LightParameter::SpotCutoff:
+ case LightParameter::ConstantAttenuation:
+ case LightParameter::LinearAttenuation:
+ case LightParameter::QuadraticAttenuation:
+ return 1;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+unsigned int GetMaterialParameterCount(MaterialParameter pname)
+{
+ switch (pname)
+ {
+ case MaterialParameter::Ambient:
+ case MaterialParameter::Diffuse:
+ case MaterialParameter::AmbientAndDiffuse:
+ case MaterialParameter::Specular:
+ case MaterialParameter::Emission:
+ return 4;
+ case MaterialParameter::Shininess:
+ return 1;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+void SetFogParameters(GLES1State *state, GLenum pname, const GLfloat *params)
+{
+ FogParameters &fog = state->fogParameters();
+ switch (pname)
+ {
+ case GL_FOG_MODE:
+ fog.mode = FromGLenum<FogMode>(static_cast<GLenum>(params[0]));
+ break;
+ case GL_FOG_DENSITY:
+ fog.density = params[0];
+ break;
+ case GL_FOG_START:
+ fog.start = params[0];
+ break;
+ case GL_FOG_END:
+ fog.end = params[0];
+ break;
+ case GL_FOG_COLOR:
+ fog.color = ColorF::fromData(params);
+ break;
+ default:
+ return;
+ }
+}
+
+void GetFogParameters(const GLES1State *state, GLenum pname, GLfloat *params)
+{
+ const FogParameters &fog = state->fogParameters();
+ switch (pname)
+ {
+ case GL_FOG_MODE:
+ params[0] = static_cast<GLfloat>(ToGLenum(fog.mode));
+ break;
+ case GL_FOG_DENSITY:
+ params[0] = fog.density;
+ break;
+ case GL_FOG_START:
+ params[0] = fog.start;
+ break;
+ case GL_FOG_END:
+ params[0] = fog.end;
+ break;
+ case GL_FOG_COLOR:
+ fog.color.writeData(params);
+ break;
+ default:
+ return;
+ }
+}
+
+unsigned int GetFogParameterCount(GLenum pname)
+{
+ switch (pname)
+ {
+ case GL_FOG_MODE:
+ case GL_FOG_DENSITY:
+ case GL_FOG_START:
+ case GL_FOG_END:
+ return 1;
+ case GL_FOG_COLOR:
+ return 4;
+ default:
+ return 0;
+ }
+}
+
+unsigned int GetTextureEnvParameterCount(TextureEnvParameter pname)
+{
+ switch (pname)
+ {
+ case TextureEnvParameter::Mode:
+ case TextureEnvParameter::CombineRgb:
+ case TextureEnvParameter::CombineAlpha:
+ case TextureEnvParameter::Src0Rgb:
+ case TextureEnvParameter::Src1Rgb:
+ case TextureEnvParameter::Src2Rgb:
+ case TextureEnvParameter::Src0Alpha:
+ case TextureEnvParameter::Src1Alpha:
+ case TextureEnvParameter::Src2Alpha:
+ case TextureEnvParameter::Op0Rgb:
+ case TextureEnvParameter::Op1Rgb:
+ case TextureEnvParameter::Op2Rgb:
+ case TextureEnvParameter::Op0Alpha:
+ case TextureEnvParameter::Op1Alpha:
+ case TextureEnvParameter::Op2Alpha:
+ case TextureEnvParameter::RgbScale:
+ case TextureEnvParameter::AlphaScale:
+ case TextureEnvParameter::PointCoordReplace:
+ return 1;
+ case TextureEnvParameter::Color:
+ return 4;
+ default:
+ return 0;
+ }
+}
+
+void ConvertTextureEnvFromInt(TextureEnvParameter pname, const GLint *input, GLfloat *output)
+{
+ if (IsTextureEnvEnumParameter(pname))
+ {
+ ConvertGLenumValue(input[0], output);
+ return;
+ }
+
+ switch (pname)
+ {
+ case TextureEnvParameter::RgbScale:
+ case TextureEnvParameter::AlphaScale:
+ output[0] = static_cast<GLfloat>(input[0]);
+ break;
+ case TextureEnvParameter::Color:
+ for (int i = 0; i < 4; i++)
+ {
+ output[i] = input[i] / 255.0f;
+ }
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+void ConvertTextureEnvFromFixed(TextureEnvParameter pname, const GLfixed *input, GLfloat *output)
+{
+ if (IsTextureEnvEnumParameter(pname))
+ {
+ ConvertGLenumValue(input[0], output);
+ return;
+ }
+
+ switch (pname)
+ {
+ case TextureEnvParameter::RgbScale:
+ case TextureEnvParameter::AlphaScale:
+ output[0] = ConvertFixedToFloat(input[0]);
+ break;
+ case TextureEnvParameter::Color:
+ for (int i = 0; i < 4; i++)
+ {
+ output[i] = ConvertFixedToFloat(input[i]);
+ }
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+void ConvertTextureEnvToInt(TextureEnvParameter pname, const GLfloat *input, GLint *output)
+{
+ if (IsTextureEnvEnumParameter(pname))
+ {
+ ConvertGLenumValue(input[0], output);
+ return;
+ }
+
+ switch (pname)
+ {
+ case TextureEnvParameter::RgbScale:
+ case TextureEnvParameter::AlphaScale:
+ output[0] = static_cast<GLint>(input[0]);
+ break;
+ case TextureEnvParameter::Color:
+ for (int i = 0; i < 4; i++)
+ {
+ output[i] = static_cast<GLint>(input[i] * 255.0f);
+ }
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+void ConvertTextureEnvToFixed(TextureEnvParameter pname, const GLfloat *input, GLfixed *output)
+{
+ if (IsTextureEnvEnumParameter(pname))
+ {
+ ConvertGLenumValue(input[0], output);
+ return;
+ }
+
+ switch (pname)
+ {
+ case TextureEnvParameter::RgbScale:
+ case TextureEnvParameter::AlphaScale:
+ output[0] = ConvertFloatToFixed(input[0]);
+ break;
+ case TextureEnvParameter::Color:
+ for (int i = 0; i < 4; i++)
+ {
+ output[i] = ConvertFloatToFixed(input[i]);
+ }
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+void SetTextureEnv(unsigned int unit,
+ GLES1State *state,
+ TextureEnvTarget target,
+ TextureEnvParameter pname,
+ const GLfloat *params)
+{
+ TextureEnvironmentParameters &env = state->textureEnvironment(unit);
+ GLenum asEnum = ConvertToGLenum(params[0]);
+
+ switch (target)
+ {
+ case TextureEnvTarget::Env:
+ switch (pname)
+ {
+ case TextureEnvParameter::Mode:
+ env.mode = FromGLenum<TextureEnvMode>(asEnum);
+ break;
+ case TextureEnvParameter::CombineRgb:
+ env.combineRgb = FromGLenum<TextureCombine>(asEnum);
+ break;
+ case TextureEnvParameter::CombineAlpha:
+ env.combineAlpha = FromGLenum<TextureCombine>(asEnum);
+ break;
+ case TextureEnvParameter::Src0Rgb:
+ env.src0Rgb = FromGLenum<TextureSrc>(asEnum);
+ break;
+ case TextureEnvParameter::Src1Rgb:
+ env.src1Rgb = FromGLenum<TextureSrc>(asEnum);
+ break;
+ case TextureEnvParameter::Src2Rgb:
+ env.src2Rgb = FromGLenum<TextureSrc>(asEnum);
+ break;
+ case TextureEnvParameter::Src0Alpha:
+ env.src0Alpha = FromGLenum<TextureSrc>(asEnum);
+ break;
+ case TextureEnvParameter::Src1Alpha:
+ env.src1Alpha = FromGLenum<TextureSrc>(asEnum);
+ break;
+ case TextureEnvParameter::Src2Alpha:
+ env.src2Alpha = FromGLenum<TextureSrc>(asEnum);
+ break;
+ case TextureEnvParameter::Op0Rgb:
+ env.op0Rgb = FromGLenum<TextureOp>(asEnum);
+ break;
+ case TextureEnvParameter::Op1Rgb:
+ env.op1Rgb = FromGLenum<TextureOp>(asEnum);
+ break;
+ case TextureEnvParameter::Op2Rgb:
+ env.op2Rgb = FromGLenum<TextureOp>(asEnum);
+ break;
+ case TextureEnvParameter::Op0Alpha:
+ env.op0Alpha = FromGLenum<TextureOp>(asEnum);
+ break;
+ case TextureEnvParameter::Op1Alpha:
+ env.op1Alpha = FromGLenum<TextureOp>(asEnum);
+ break;
+ case TextureEnvParameter::Op2Alpha:
+ env.op2Alpha = FromGLenum<TextureOp>(asEnum);
+ break;
+ case TextureEnvParameter::Color:
+ env.color = ColorF::fromData(params);
+ break;
+ case TextureEnvParameter::RgbScale:
+ env.rgbScale = params[0];
+ break;
+ case TextureEnvParameter::AlphaScale:
+ env.alphaScale = params[0];
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ break;
+ case TextureEnvTarget::PointSprite:
+ switch (pname)
+ {
+ case TextureEnvParameter::PointCoordReplace:
+ env.pointSpriteCoordReplace = static_cast<bool>(params[0]);
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+void GetTextureEnv(unsigned int unit,
+ const GLES1State *state,
+ TextureEnvTarget target,
+ TextureEnvParameter pname,
+ GLfloat *params)
+{
+ const TextureEnvironmentParameters &env = state->textureEnvironment(unit);
+
+ switch (target)
+ {
+ case TextureEnvTarget::Env:
+ switch (pname)
+ {
+ case TextureEnvParameter::Mode:
+ ConvertPackedEnum(env.mode, params);
+ break;
+ case TextureEnvParameter::CombineRgb:
+ ConvertPackedEnum(env.combineRgb, params);
+ break;
+ case TextureEnvParameter::CombineAlpha:
+ ConvertPackedEnum(env.combineAlpha, params);
+ break;
+ case TextureEnvParameter::Src0Rgb:
+ ConvertPackedEnum(env.src0Rgb, params);
+ break;
+ case TextureEnvParameter::Src1Rgb:
+ ConvertPackedEnum(env.src1Rgb, params);
+ break;
+ case TextureEnvParameter::Src2Rgb:
+ ConvertPackedEnum(env.src2Rgb, params);
+ break;
+ case TextureEnvParameter::Src0Alpha:
+ ConvertPackedEnum(env.src0Alpha, params);
+ break;
+ case TextureEnvParameter::Src1Alpha:
+ ConvertPackedEnum(env.src1Alpha, params);
+ break;
+ case TextureEnvParameter::Src2Alpha:
+ ConvertPackedEnum(env.src2Alpha, params);
+ break;
+ case TextureEnvParameter::Op0Rgb:
+ ConvertPackedEnum(env.op0Rgb, params);
+ break;
+ case TextureEnvParameter::Op1Rgb:
+ ConvertPackedEnum(env.op1Rgb, params);
+ break;
+ case TextureEnvParameter::Op2Rgb:
+ ConvertPackedEnum(env.op2Rgb, params);
+ break;
+ case TextureEnvParameter::Op0Alpha:
+ ConvertPackedEnum(env.op0Alpha, params);
+ break;
+ case TextureEnvParameter::Op1Alpha:
+ ConvertPackedEnum(env.op1Alpha, params);
+ break;
+ case TextureEnvParameter::Op2Alpha:
+ ConvertPackedEnum(env.op2Alpha, params);
+ break;
+ case TextureEnvParameter::Color:
+ env.color.writeData(params);
+ break;
+ case TextureEnvParameter::RgbScale:
+ *params = env.rgbScale;
+ break;
+ case TextureEnvParameter::AlphaScale:
+ *params = env.alphaScale;
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ break;
+ case TextureEnvTarget::PointSprite:
+ switch (pname)
+ {
+ case TextureEnvParameter::PointCoordReplace:
+ *params = static_cast<GLfloat>(env.pointSpriteCoordReplace);
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+unsigned int GetPointParameterCount(PointParameter pname)
+{
+ switch (pname)
+ {
+ case PointParameter::PointSizeMin:
+ case PointParameter::PointSizeMax:
+ case PointParameter::PointFadeThresholdSize:
+ return 1;
+ case PointParameter::PointDistanceAttenuation:
+ return 3;
+ default:
+ return 0;
+ }
+}
+
+void SetPointParameter(GLES1State *state, PointParameter pname, const GLfloat *params)
+{
+
+ PointParameters &pointParams = state->pointParameters();
+
+ switch (pname)
+ {
+ case PointParameter::PointSizeMin:
+ pointParams.pointSizeMin = params[0];
+ break;
+ case PointParameter::PointSizeMax:
+ pointParams.pointSizeMax = params[0];
+ break;
+ case PointParameter::PointFadeThresholdSize:
+ pointParams.pointFadeThresholdSize = params[0];
+ break;
+ case PointParameter::PointDistanceAttenuation:
+ for (unsigned int i = 0; i < 3; i++)
+ {
+ pointParams.pointDistanceAttenuation[i] = params[i];
+ }
+ break;
+ default:
+ UNREACHABLE();
+ }
+}
+
+void GetPointParameter(const GLES1State *state, PointParameter pname, GLfloat *params)
+{
+ const PointParameters &pointParams = state->pointParameters();
+
+ switch (pname)
+ {
+ case PointParameter::PointSizeMin:
+ params[0] = pointParams.pointSizeMin;
+ break;
+ case PointParameter::PointSizeMax:
+ params[0] = pointParams.pointSizeMax;
+ break;
+ case PointParameter::PointFadeThresholdSize:
+ params[0] = pointParams.pointFadeThresholdSize;
+ break;
+ case PointParameter::PointDistanceAttenuation:
+ for (unsigned int i = 0; i < 3; i++)
+ {
+ params[i] = pointParams.pointDistanceAttenuation[i];
+ }
+ break;
+ default:
+ UNREACHABLE();
+ }
+}
+
+void SetPointSize(GLES1State *state, GLfloat size)
+{
+ PointParameters &params = state->pointParameters();
+ params.pointSize = size;
+}
+
+void GetPointSize(const GLES1State *state, GLfloat *sizeOut)
+{
+ const PointParameters &params = state->pointParameters();
+ *sizeOut = params.pointSize;
+}
+
+unsigned int GetTexParameterCount(GLenum pname)
+{
+ switch (pname)
+ {
+ case GL_TEXTURE_CROP_RECT_OES:
+ case GL_TEXTURE_BORDER_COLOR:
+ return 4;
+ case GL_TEXTURE_MAG_FILTER:
+ case GL_TEXTURE_MIN_FILTER:
+ case GL_TEXTURE_WRAP_S:
+ case GL_TEXTURE_WRAP_T:
+ case GL_TEXTURE_USAGE_ANGLE:
+ case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+ case GL_TEXTURE_IMMUTABLE_FORMAT:
+ case GL_TEXTURE_WRAP_R:
+ case GL_TEXTURE_IMMUTABLE_LEVELS:
+ case GL_TEXTURE_SWIZZLE_R:
+ case GL_TEXTURE_SWIZZLE_G:
+ case GL_TEXTURE_SWIZZLE_B:
+ case GL_TEXTURE_SWIZZLE_A:
+ case GL_TEXTURE_BASE_LEVEL:
+ case GL_TEXTURE_MAX_LEVEL:
+ case GL_TEXTURE_MIN_LOD:
+ case GL_TEXTURE_MAX_LOD:
+ case GL_TEXTURE_COMPARE_MODE:
+ case GL_TEXTURE_COMPARE_FUNC:
+ case GL_TEXTURE_SRGB_DECODE_EXT:
+ case GL_DEPTH_STENCIL_TEXTURE_MODE:
+ case GL_TEXTURE_NATIVE_ID_ANGLE:
+ case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+bool GetQueryParameterInfo(const State &glState,
+ GLenum pname,
+ GLenum *type,
+ unsigned int *numParams)
+{
+ const Caps &caps = glState.getCaps();
+ const Extensions &extensions = glState.getExtensions();
+ GLint clientMajorVersion = glState.getClientMajorVersion();
+ EGLenum clientType = glState.getClientType();
+
+ // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
+ // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
+ // to the fact that it is stored internally as a float, and so would require conversion
+ // if returned from Context::getIntegerv. Since this conversion is already implemented
+ // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
+ // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
+ // application.
+ switch (pname)
+ {
+ case GL_COMPRESSED_TEXTURE_FORMATS:
+ {
+ *type = GL_INT;
+ *numParams = static_cast<unsigned int>(caps.compressedTextureFormats.size());
+ return true;
+ }
+ case GL_SHADER_BINARY_FORMATS:
+ {
+ *type = GL_INT;
+ *numParams = static_cast<unsigned int>(caps.shaderBinaryFormats.size());
+ return true;
+ }
+
+ case GL_MAX_VERTEX_ATTRIBS:
+ case GL_MAX_VERTEX_UNIFORM_VECTORS:
+ case GL_MAX_VARYING_VECTORS:
+ case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
+ case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
+ case GL_MAX_TEXTURE_IMAGE_UNITS:
+ case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
+ case GL_MAX_RENDERBUFFER_SIZE:
+ case GL_NUM_SHADER_BINARY_FORMATS:
+ case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
+ case GL_ARRAY_BUFFER_BINDING:
+ case GL_FRAMEBUFFER_BINDING: // GL_FRAMEBUFFER_BINDING now equivalent to
+ // GL_DRAW_FRAMEBUFFER_BINDING
+ case GL_RENDERBUFFER_BINDING:
+ case GL_CURRENT_PROGRAM:
+ case GL_PACK_ALIGNMENT:
+ case GL_UNPACK_ALIGNMENT:
+ case GL_GENERATE_MIPMAP_HINT:
+ case GL_TEXTURE_FILTERING_HINT_CHROMIUM:
+ case GL_RED_BITS:
+ case GL_GREEN_BITS:
+ case GL_BLUE_BITS:
+ case GL_ALPHA_BITS:
+ case GL_DEPTH_BITS:
+ case GL_STENCIL_BITS:
+ case GL_ELEMENT_ARRAY_BUFFER_BINDING:
+ case GL_CULL_FACE_MODE:
+ case GL_FRONT_FACE:
+ case GL_ACTIVE_TEXTURE:
+ case GL_STENCIL_FUNC:
+ case GL_STENCIL_VALUE_MASK:
+ case GL_STENCIL_REF:
+ case GL_STENCIL_FAIL:
+ case GL_STENCIL_PASS_DEPTH_FAIL:
+ case GL_STENCIL_PASS_DEPTH_PASS:
+ case GL_STENCIL_BACK_FUNC:
+ case GL_STENCIL_BACK_VALUE_MASK:
+ case GL_STENCIL_BACK_REF:
+ case GL_STENCIL_BACK_FAIL:
+ case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
+ case GL_STENCIL_BACK_PASS_DEPTH_PASS:
+ case GL_DEPTH_FUNC:
+ case GL_BLEND_SRC_RGB:
+ case GL_BLEND_SRC_ALPHA:
+ case GL_BLEND_DST_RGB:
+ case GL_BLEND_DST_ALPHA:
+ case GL_BLEND_EQUATION_RGB:
+ case GL_BLEND_EQUATION_ALPHA:
+ case GL_STENCIL_WRITEMASK:
+ case GL_STENCIL_BACK_WRITEMASK:
+ case GL_STENCIL_CLEAR_VALUE:
+ case GL_SUBPIXEL_BITS:
+ case GL_MAX_TEXTURE_SIZE:
+ case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
+ case GL_SAMPLE_BUFFERS:
+ case GL_SAMPLES:
+ case GL_IMPLEMENTATION_COLOR_READ_TYPE:
+ case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
+ case GL_TEXTURE_BINDING_2D:
+ case GL_TEXTURE_BINDING_CUBE_MAP:
+ case GL_RESET_NOTIFICATION_STRATEGY_EXT:
+ {
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ }
+ case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
+ {
+ if (!extensions.packReverseRowOrderANGLE)
+ {
+ return false;
+ }
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ }
+ case GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE:
+ case GL_TEXTURE_BINDING_RECTANGLE_ANGLE:
+ {
+ if (!extensions.textureRectangleANGLE)
+ {
+ return false;
+ }
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ }
+ case GL_MAX_DRAW_BUFFERS_EXT:
+ case GL_MAX_COLOR_ATTACHMENTS_EXT:
+ {
+ if ((clientMajorVersion < 3) && !extensions.drawBuffersEXT)
+ {
+ return false;
+ }
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ }
+ case GL_MAX_VIEWPORT_DIMS:
+ {
+ *type = GL_INT;
+ *numParams = 2;
+ return true;
+ }
+ case GL_VIEWPORT:
+ case GL_SCISSOR_BOX:
+ {
+ *type = GL_INT;
+ *numParams = 4;
+ return true;
+ }
+ case GL_SHADER_COMPILER:
+ case GL_SAMPLE_COVERAGE_INVERT:
+ case GL_DEPTH_WRITEMASK:
+ case GL_CULL_FACE: // CULL_FACE through DITHER are natural to IsEnabled,
+ case GL_POLYGON_OFFSET_FILL: // but can be retrieved through the Get{Type}v queries.
+ case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as
+ // bool-natural
+ case GL_SAMPLE_COVERAGE:
+ case GL_SCISSOR_TEST:
+ case GL_STENCIL_TEST:
+ case GL_DEPTH_TEST:
+ case GL_BLEND:
+ case GL_DITHER:
+ case GL_CONTEXT_ROBUST_ACCESS_EXT:
+ {
+ *type = GL_BOOL;
+ *numParams = 1;
+ return true;
+ }
+ case GL_COLOR_LOGIC_OP:
+ {
+ if (!extensions.logicOpANGLE)
+ {
+ return false;
+ }
+ *type = GL_BOOL;
+ *numParams = 1;
+ return true;
+ }
+ case GL_COLOR_WRITEMASK:
+ {
+ *type = GL_BOOL;
+ *numParams = 4;
+ return true;
+ }
+ case GL_POLYGON_OFFSET_FACTOR:
+ case GL_POLYGON_OFFSET_UNITS:
+ case GL_SAMPLE_COVERAGE_VALUE:
+ case GL_DEPTH_CLEAR_VALUE:
+ case GL_LINE_WIDTH:
+ {
+ *type = GL_FLOAT;
+ *numParams = 1;
+ return true;
+ }
+ case GL_ALIASED_LINE_WIDTH_RANGE:
+ case GL_ALIASED_POINT_SIZE_RANGE:
+ case GL_DEPTH_RANGE:
+ {
+ *type = GL_FLOAT;
+ *numParams = 2;
+ return true;
+ }
+ case GL_COLOR_CLEAR_VALUE:
+ case GL_BLEND_COLOR:
+ {
+ *type = GL_FLOAT;
+ *numParams = 4;
+ return true;
+ }
+ case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
+ if (!extensions.textureFilterAnisotropicEXT)
+ {
+ return false;
+ }
+ *type = GL_FLOAT;
+ *numParams = 1;
+ return true;
+ case GL_TIMESTAMP_EXT:
+ if (!extensions.disjointTimerQueryEXT)
+ {
+ return false;
+ }
+ *type = GL_INT_64_ANGLEX;
+ *numParams = 1;
+ return true;
+ case GL_GPU_DISJOINT_EXT:
+ if (!extensions.disjointTimerQueryEXT)
+ {
+ return false;
+ }
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ case GL_COVERAGE_MODULATION_CHROMIUM:
+ if (!extensions.framebufferMixedSamplesCHROMIUM)
+ {
+ return false;
+ }
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ case GL_TEXTURE_BINDING_EXTERNAL_OES:
+ if (!extensions.EGLStreamConsumerExternalNV && !extensions.EGLImageExternalOES)
+ {
+ return false;
+ }
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ case GL_MAX_CLIP_DISTANCES_EXT: // case GL_MAX_CLIP_PLANES
+ if (clientMajorVersion < 2)
+ {
+ break;
+ }
+ if (!extensions.clipDistanceAPPLE && !extensions.clipCullDistanceEXT)
+ {
+ // NOTE(hqle): if client version is 1. GL_MAX_CLIP_DISTANCES_EXT is equal
+ // to GL_MAX_CLIP_PLANES which is a valid enum.
+ return false;
+ }
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ case GL_MAX_CULL_DISTANCES_EXT:
+ case GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES_EXT:
+ if (!extensions.clipCullDistanceEXT)
+ {
+ return false;
+ }
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ case GL_CLIP_ORIGIN_EXT:
+ case GL_CLIP_DEPTH_MODE_EXT:
+ if (!extensions.clipControlEXT)
+ {
+ return false;
+ }
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ case GL_PRIMITIVE_BOUNDING_BOX:
+ if (!extensions.primitiveBoundingBoxAny())
+ {
+ return false;
+ }
+ *type = GL_FLOAT;
+ *numParams = 8;
+ return true;
+ case GL_SHADING_RATE_QCOM:
+ if (!extensions.shadingRateQCOM)
+ {
+ return false;
+ }
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ }
+
+ if (clientType == EGL_OPENGL_API ||
+ (clientType == EGL_OPENGL_ES_API && glState.getClientVersion() >= Version(3, 2)))
+ {
+ switch (pname)
+ {
+ case GL_CONTEXT_FLAGS:
+ {
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ }
+ }
+ }
+
+ if (clientType == EGL_OPENGL_API)
+ {
+ switch (pname)
+ {
+ case GL_CONTEXT_PROFILE_MASK:
+ {
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ }
+ }
+ }
+
+ if (extensions.debugKHR)
+ {
+ switch (pname)
+ {
+ case GL_DEBUG_LOGGED_MESSAGES:
+ case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
+ case GL_DEBUG_GROUP_STACK_DEPTH:
+ case GL_MAX_DEBUG_MESSAGE_LENGTH:
+ case GL_MAX_DEBUG_LOGGED_MESSAGES:
+ case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
+ case GL_MAX_LABEL_LENGTH:
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+
+ case GL_DEBUG_OUTPUT_SYNCHRONOUS:
+ case GL_DEBUG_OUTPUT:
+ *type = GL_BOOL;
+ *numParams = 1;
+ return true;
+ }
+ }
+
+ if (extensions.multisampleCompatibilityEXT)
+ {
+ switch (pname)
+ {
+ case GL_MULTISAMPLE_EXT:
+ case GL_SAMPLE_ALPHA_TO_ONE_EXT:
+ *type = GL_BOOL;
+ *numParams = 1;
+ return true;
+ }
+ }
+
+ if (extensions.bindGeneratesResourceCHROMIUM)
+ {
+ switch (pname)
+ {
+ case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
+ *type = GL_BOOL;
+ *numParams = 1;
+ return true;
+ }
+ }
+
+ if (extensions.clientArraysANGLE)
+ {
+ switch (pname)
+ {
+ case GL_CLIENT_ARRAYS_ANGLE:
+ *type = GL_BOOL;
+ *numParams = 1;
+ return true;
+ }
+ }
+
+ if (extensions.sRGBWriteControlEXT)
+ {
+ switch (pname)
+ {
+ case GL_FRAMEBUFFER_SRGB_EXT:
+ *type = GL_BOOL;
+ *numParams = 1;
+ return true;
+ }
+ }
+
+ if (extensions.robustResourceInitializationANGLE &&
+ pname == GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE)
+ {
+ *type = GL_BOOL;
+ *numParams = 1;
+ return true;
+ }
+
+ if (extensions.programCacheControlANGLE && pname == GL_PROGRAM_CACHE_ENABLED_ANGLE)
+ {
+ *type = GL_BOOL;
+ *numParams = 1;
+ return true;
+ }
+
+ if (extensions.parallelShaderCompileKHR && pname == GL_MAX_SHADER_COMPILER_THREADS_KHR)
+ {
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ }
+
+ if (extensions.blendFuncExtendedEXT && pname == GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT)
+ {
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ }
+
+ if (extensions.robustFragmentShaderOutputANGLE &&
+ pname == GL_ROBUST_FRAGMENT_SHADER_OUTPUT_ANGLE)
+ {
+ *type = GL_BOOL;
+ *numParams = 1;
+ return true;
+ }
+
+ // Check for ES3.0+ parameter names which are also exposed as ES2 extensions
+ switch (pname)
+ {
+ // GL_DRAW_FRAMEBUFFER_BINDING equivalent to GL_FRAMEBUFFER_BINDING
+ case GL_READ_FRAMEBUFFER_BINDING:
+ if ((clientMajorVersion < 3) && !extensions.framebufferBlitAny())
+ {
+ return false;
+ }
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+
+ case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
+ if ((clientMajorVersion < 3) && !extensions.getProgramBinaryOES)
+ {
+ return false;
+ }
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+
+ case GL_PROGRAM_BINARY_FORMATS_OES:
+ if ((clientMajorVersion < 3) && !extensions.getProgramBinaryOES)
+ {
+ return false;
+ }
+ *type = GL_INT;
+ *numParams = static_cast<unsigned int>(caps.programBinaryFormats.size());
+ return true;
+
+ case GL_PACK_ROW_LENGTH:
+ case GL_PACK_SKIP_ROWS:
+ case GL_PACK_SKIP_PIXELS:
+ if ((clientMajorVersion < 3) && !extensions.packSubimageNV)
+ {
+ return false;
+ }
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ case GL_UNPACK_ROW_LENGTH:
+ case GL_UNPACK_SKIP_ROWS:
+ case GL_UNPACK_SKIP_PIXELS:
+ if ((clientMajorVersion < 3) && !extensions.unpackSubimageEXT)
+ {
+ return false;
+ }
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ case GL_VERTEX_ARRAY_BINDING:
+ if ((clientMajorVersion < 3) && !extensions.vertexArrayObjectOES)
+ {
+ return false;
+ }
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ case GL_PIXEL_PACK_BUFFER_BINDING:
+ case GL_PIXEL_UNPACK_BUFFER_BINDING:
+ if ((clientMajorVersion < 3) && !extensions.pixelBufferObjectNV)
+ {
+ return false;
+ }
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ case GL_MAX_SAMPLES:
+ {
+ static_assert(GL_MAX_SAMPLES_ANGLE == GL_MAX_SAMPLES,
+ "GL_MAX_SAMPLES_ANGLE not equal to GL_MAX_SAMPLES");
+ if ((clientMajorVersion < 3) && !(extensions.framebufferMultisampleANGLE ||
+ extensions.multisampledRenderToTextureEXT))
+ {
+ return false;
+ }
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+
+ case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
+ if ((clientMajorVersion < 3) && !extensions.standardDerivativesOES)
+ {
+ return false;
+ }
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ }
+ case GL_TEXTURE_BINDING_3D:
+ if ((clientMajorVersion < 3) && !extensions.texture3DOES)
+ {
+ return false;
+ }
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ case GL_MAX_3D_TEXTURE_SIZE:
+ if ((clientMajorVersion < 3) && !extensions.texture3DOES)
+ {
+ return false;
+ }
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ }
+
+ if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
+ {
+ if ((glState.getClientVersion() < Version(3, 0)) && !extensions.drawBuffersEXT)
+ {
+ return false;
+ }
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ }
+
+ if ((extensions.multiview2OVR || extensions.multiviewOVR) && pname == GL_MAX_VIEWS_OVR)
+ {
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ }
+
+ if (extensions.provokingVertexANGLE && pname == GL_PROVOKING_VERTEX)
+ {
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ }
+
+ if (glState.getClientVersion() < Version(2, 0))
+ {
+ switch (pname)
+ {
+ case GL_ALPHA_TEST_FUNC:
+ case GL_CLIENT_ACTIVE_TEXTURE:
+ case GL_MATRIX_MODE:
+ case GL_MAX_TEXTURE_UNITS:
+ case GL_MAX_MODELVIEW_STACK_DEPTH:
+ case GL_MAX_PROJECTION_STACK_DEPTH:
+ case GL_MAX_TEXTURE_STACK_DEPTH:
+ case GL_MAX_LIGHTS:
+ case GL_MAX_CLIP_PLANES:
+ case GL_VERTEX_ARRAY_STRIDE:
+ case GL_NORMAL_ARRAY_STRIDE:
+ case GL_COLOR_ARRAY_STRIDE:
+ case GL_TEXTURE_COORD_ARRAY_STRIDE:
+ case GL_VERTEX_ARRAY_SIZE:
+ case GL_COLOR_ARRAY_SIZE:
+ case GL_TEXTURE_COORD_ARRAY_SIZE:
+ case GL_VERTEX_ARRAY_TYPE:
+ case GL_NORMAL_ARRAY_TYPE:
+ case GL_COLOR_ARRAY_TYPE:
+ case GL_TEXTURE_COORD_ARRAY_TYPE:
+ case GL_VERTEX_ARRAY_BUFFER_BINDING:
+ case GL_NORMAL_ARRAY_BUFFER_BINDING:
+ case GL_COLOR_ARRAY_BUFFER_BINDING:
+ case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
+ case GL_POINT_SIZE_ARRAY_STRIDE_OES:
+ case GL_POINT_SIZE_ARRAY_TYPE_OES:
+ case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
+ case GL_SHADE_MODEL:
+ case GL_MODELVIEW_STACK_DEPTH:
+ case GL_PROJECTION_STACK_DEPTH:
+ case GL_TEXTURE_STACK_DEPTH:
+ case GL_LOGIC_OP_MODE:
+ case GL_BLEND_SRC:
+ case GL_BLEND_DST:
+ case GL_PERSPECTIVE_CORRECTION_HINT:
+ case GL_POINT_SMOOTH_HINT:
+ case GL_LINE_SMOOTH_HINT:
+ case GL_FOG_HINT:
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ case GL_ALPHA_TEST_REF:
+ case GL_FOG_DENSITY:
+ case GL_FOG_START:
+ case GL_FOG_END:
+ case GL_FOG_MODE:
+ case GL_POINT_SIZE:
+ case GL_POINT_SIZE_MIN:
+ case GL_POINT_SIZE_MAX:
+ case GL_POINT_FADE_THRESHOLD_SIZE:
+ *type = GL_FLOAT;
+ *numParams = 1;
+ return true;
+ case GL_SMOOTH_POINT_SIZE_RANGE:
+ case GL_SMOOTH_LINE_WIDTH_RANGE:
+ *type = GL_FLOAT;
+ *numParams = 2;
+ return true;
+ case GL_CURRENT_COLOR:
+ case GL_CURRENT_TEXTURE_COORDS:
+ case GL_LIGHT_MODEL_AMBIENT:
+ case GL_FOG_COLOR:
+ *type = GL_FLOAT;
+ *numParams = 4;
+ return true;
+ case GL_CURRENT_NORMAL:
+ case GL_POINT_DISTANCE_ATTENUATION:
+ *type = GL_FLOAT;
+ *numParams = 3;
+ return true;
+ case GL_MODELVIEW_MATRIX:
+ case GL_PROJECTION_MATRIX:
+ case GL_TEXTURE_MATRIX:
+ *type = GL_FLOAT;
+ *numParams = 16;
+ return true;
+ case GL_LIGHT_MODEL_TWO_SIDE:
+ *type = GL_BOOL;
+ *numParams = 1;
+ return true;
+ }
+ }
+
+ if (glState.getClientVersion() < Version(3, 0))
+ {
+ return false;
+ }
+
+ // Check for ES3.0+ parameter names
+ switch (pname)
+ {
+ case GL_MAX_UNIFORM_BUFFER_BINDINGS:
+ case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
+ case GL_UNIFORM_BUFFER_BINDING:
+ case GL_TRANSFORM_FEEDBACK_BINDING:
+ case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
+ case GL_COPY_READ_BUFFER_BINDING:
+ case GL_COPY_WRITE_BUFFER_BINDING:
+ case GL_SAMPLER_BINDING:
+ case GL_READ_BUFFER:
+ case GL_TEXTURE_BINDING_3D:
+ case GL_TEXTURE_BINDING_2D_ARRAY:
+ case GL_MAX_ARRAY_TEXTURE_LAYERS:
+ case GL_MAX_VERTEX_UNIFORM_BLOCKS:
+ case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
+ case GL_MAX_COMBINED_UNIFORM_BLOCKS:
+ case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
+ case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
+ case GL_MAX_VARYING_COMPONENTS:
+ case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
+ case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
+ case GL_MIN_PROGRAM_TEXEL_OFFSET:
+ case GL_MAX_PROGRAM_TEXEL_OFFSET:
+ case GL_NUM_EXTENSIONS:
+ case GL_MAJOR_VERSION:
+ case GL_MINOR_VERSION:
+ case GL_MAX_ELEMENTS_INDICES:
+ case GL_MAX_ELEMENTS_VERTICES:
+ case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
+ case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
+ case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
+ case GL_UNPACK_IMAGE_HEIGHT:
+ case GL_UNPACK_SKIP_IMAGES:
+ case GL_FRAGMENT_INTERPOLATION_OFFSET_BITS_OES:
+ {
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ }
+
+ case GL_MAX_ELEMENT_INDEX:
+ case GL_MAX_UNIFORM_BLOCK_SIZE:
+ case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
+ case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
+ case GL_MAX_SERVER_WAIT_TIMEOUT:
+ {
+ *type = GL_INT_64_ANGLEX;
+ *numParams = 1;
+ return true;
+ }
+
+ case GL_TRANSFORM_FEEDBACK_ACTIVE:
+ case GL_TRANSFORM_FEEDBACK_PAUSED:
+ case GL_PRIMITIVE_RESTART_FIXED_INDEX:
+ case GL_RASTERIZER_DISCARD:
+ {
+ *type = GL_BOOL;
+ *numParams = 1;
+ return true;
+ }
+
+ case GL_MAX_TEXTURE_LOD_BIAS:
+ case GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_OES:
+ case GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_OES:
+ {
+ *type = GL_FLOAT;
+ *numParams = 1;
+ return true;
+ }
+ }
+
+ if (extensions.requestExtensionANGLE)
+ {
+ switch (pname)
+ {
+ case GL_NUM_REQUESTABLE_EXTENSIONS_ANGLE:
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ }
+ }
+
+ if (extensions.textureMultisampleANGLE)
+ {
+ switch (pname)
+ {
+ case GL_MAX_COLOR_TEXTURE_SAMPLES_ANGLE:
+ case GL_MAX_INTEGER_SAMPLES_ANGLE:
+ case GL_MAX_DEPTH_TEXTURE_SAMPLES_ANGLE:
+ case GL_TEXTURE_BINDING_2D_MULTISAMPLE_ANGLE:
+ case GL_MAX_SAMPLE_MASK_WORDS:
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ }
+ }
+
+ if (extensions.textureCubeMapArrayAny())
+ {
+ switch (pname)
+ {
+ case GL_TEXTURE_BINDING_CUBE_MAP_ARRAY:
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ }
+ }
+
+ if (extensions.textureBufferAny())
+ {
+ switch (pname)
+ {
+ case GL_TEXTURE_BUFFER_BINDING:
+ case GL_TEXTURE_BINDING_BUFFER:
+ case GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
+ case GL_MAX_TEXTURE_BUFFER_SIZE:
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ }
+ }
+
+ if (extensions.shaderPixelLocalStorageANGLE)
+ {
+ switch (pname)
+ {
+ case GL_MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE:
+ case GL_MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE_ANGLE:
+ case GL_MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES_ANGLE:
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ case GL_PIXEL_LOCAL_STORAGE_ACTIVE_ANGLE:
+ *type = GL_BOOL;
+ *numParams = 1;
+ return true;
+ }
+ }
+
+ if (glState.getClientVersion() < Version(3, 1))
+ {
+ return false;
+ }
+
+ // Check for ES3.1+ parameter names
+ switch (pname)
+ {
+ case GL_ATOMIC_COUNTER_BUFFER_BINDING:
+ case GL_DRAW_INDIRECT_BUFFER_BINDING:
+ case GL_DISPATCH_INDIRECT_BUFFER_BINDING:
+ 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_BINDING:
+ case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
+ case GL_TEXTURE_BINDING_2D_MULTISAMPLE:
+ case GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY:
+ case GL_PROGRAM_PIPELINE_BINDING:
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
+ *type = GL_INT_64_ANGLEX;
+ *numParams = 1;
+ return true;
+ case GL_SAMPLE_MASK:
+ case GL_SAMPLE_SHADING:
+ *type = GL_BOOL;
+ *numParams = 1;
+ return true;
+ case GL_MIN_SAMPLE_SHADING_VALUE:
+ *type = GL_FLOAT;
+ *numParams = 1;
+ return true;
+ }
+
+ if (extensions.geometryShaderAny())
+ {
+ switch (pname)
+ {
+ case GL_MAX_FRAMEBUFFER_LAYERS_EXT:
+ case GL_LAYER_PROVOKING_VERTEX_EXT:
+ case GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT:
+ case GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT:
+ case GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT:
+ case GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT:
+ case GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT:
+ case GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT:
+ case GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT:
+ case GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT:
+ case GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT:
+ case GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT:
+ case GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT:
+ case GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT:
+ case GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT:
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ }
+ }
+
+ if (extensions.tessellationShaderEXT)
+ {
+ switch (pname)
+ {
+ case GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED:
+ *type = GL_BOOL;
+ *numParams = 1;
+ return true;
+ case GL_PATCH_VERTICES:
+ case GL_MAX_PATCH_VERTICES_EXT:
+ case GL_MAX_TESS_GEN_LEVEL_EXT:
+ case GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS_EXT:
+ case GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT:
+ case GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_EXT:
+ case GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_EXT:
+ case GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_EXT:
+ case GL_MAX_TESS_PATCH_COMPONENTS_EXT:
+ case GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_EXT:
+ case GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_EXT:
+ case GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS_EXT:
+ case GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS_EXT:
+ case GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_EXT:
+ case GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_EXT:
+ case GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_EXT:
+ case GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT:
+ case GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_EXT:
+ case GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_EXT:
+ case GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS_EXT:
+ case GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS_EXT:
+ case GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_EXT:
+ case GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS_EXT:
+ case GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_EXT:
+ case GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_EXT:
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void QueryProgramPipelineiv(const Context *context,
+ ProgramPipeline *programPipeline,
+ GLenum pname,
+ GLint *params)
+{
+ if (!params)
+ {
+ // Can't write the result anywhere, so just return immediately.
+ return;
+ }
+
+ switch (pname)
+ {
+ case GL_ACTIVE_PROGRAM:
+ {
+ // the name of the active program object of the program pipeline object is returned in
+ // params
+ *params = 0;
+ if (programPipeline)
+ {
+ const Program *program = programPipeline->getActiveShaderProgram();
+ if (program)
+ {
+ *params = program->id().value;
+ }
+ }
+ break;
+ }
+
+ case GL_VERTEX_SHADER:
+ {
+ // the name of the current program object for the vertex shader type of the program
+ // pipeline object is returned in params
+ GetShaderProgramId(programPipeline, ShaderType::Vertex, params);
+ break;
+ }
+
+ case GL_FRAGMENT_SHADER:
+ {
+ // the name of the current program object for the fragment shader type of the program
+ // pipeline object is returned in params
+ GetShaderProgramId(programPipeline, ShaderType::Fragment, params);
+ break;
+ }
+
+ case GL_TESS_CONTROL_SHADER:
+ {
+ // the name of the current program object for the tessellation control shader type of
+ // the program pipeline object is returned in params
+ GetShaderProgramId(programPipeline, ShaderType::TessControl, params);
+ break;
+ }
+
+ case GL_TESS_EVALUATION_SHADER:
+ {
+ // the name of the current program object for the tessellation evaluation shader type of
+ // the program pipeline object is returned in params
+ GetShaderProgramId(programPipeline, ShaderType::TessEvaluation, params);
+ break;
+ }
+
+ case GL_COMPUTE_SHADER:
+ {
+ // the name of the current program object for the compute shader type of the program
+ // pipeline object is returned in params
+ GetShaderProgramId(programPipeline, ShaderType::Compute, params);
+ break;
+ }
+
+ case GL_GEOMETRY_SHADER:
+ {
+ // the name of the current program object for the geometry shader type of the program
+ // pipeline object is returned in params
+ GetShaderProgramId(programPipeline, ShaderType::Geometry, params);
+ break;
+ }
+
+ case GL_INFO_LOG_LENGTH:
+ {
+ // the length of the info log, including the null terminator, is returned in params. If
+ // there is no info log, zero is returned.
+ *params = 0;
+ if (programPipeline)
+ {
+ *params = programPipeline->getExecutable().getInfoLogLength();
+ }
+ break;
+ }
+
+ case GL_VALIDATE_STATUS:
+ {
+ // the validation status of pipeline, as determined by glValidateProgramPipeline, is
+ // returned in params
+ *params = 0;
+ if (programPipeline)
+ {
+ *params = programPipeline->isValid();
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+}
+
+} // namespace gl
+
+namespace egl
+{
+
+void QueryConfigAttrib(const Config *config, EGLint attribute, EGLint *value)
+{
+ ASSERT(config != nullptr);
+ switch (attribute)
+ {
+ case EGL_BUFFER_SIZE:
+ *value = config->bufferSize;
+ break;
+ case EGL_ALPHA_SIZE:
+ *value = config->alphaSize;
+ break;
+ case EGL_BLUE_SIZE:
+ *value = config->blueSize;
+ break;
+ case EGL_GREEN_SIZE:
+ *value = config->greenSize;
+ break;
+ case EGL_RED_SIZE:
+ *value = config->redSize;
+ break;
+ case EGL_DEPTH_SIZE:
+ *value = config->depthSize;
+ break;
+ case EGL_STENCIL_SIZE:
+ *value = config->stencilSize;
+ break;
+ case EGL_CONFIG_CAVEAT:
+ *value = config->configCaveat;
+ break;
+ case EGL_CONFIG_ID:
+ *value = config->configID;
+ break;
+ case EGL_LEVEL:
+ *value = config->level;
+ break;
+ case EGL_NATIVE_RENDERABLE:
+ *value = config->nativeRenderable;
+ break;
+ case EGL_NATIVE_VISUAL_ID:
+ *value = config->nativeVisualID;
+ break;
+ case EGL_NATIVE_VISUAL_TYPE:
+ *value = config->nativeVisualType;
+ break;
+ case EGL_SAMPLES:
+ *value = config->samples;
+ break;
+ case EGL_SAMPLE_BUFFERS:
+ *value = config->sampleBuffers;
+ break;
+ case EGL_SURFACE_TYPE:
+ *value = config->surfaceType;
+ break;
+ case EGL_BIND_TO_TEXTURE_TARGET_ANGLE:
+ *value = config->bindToTextureTarget;
+ break;
+ case EGL_TRANSPARENT_TYPE:
+ *value = config->transparentType;
+ break;
+ case EGL_TRANSPARENT_BLUE_VALUE:
+ *value = config->transparentBlueValue;
+ break;
+ case EGL_TRANSPARENT_GREEN_VALUE:
+ *value = config->transparentGreenValue;
+ break;
+ case EGL_TRANSPARENT_RED_VALUE:
+ *value = config->transparentRedValue;
+ break;
+ case EGL_BIND_TO_TEXTURE_RGB:
+ *value = config->bindToTextureRGB;
+ break;
+ case EGL_BIND_TO_TEXTURE_RGBA:
+ *value = config->bindToTextureRGBA;
+ break;
+ case EGL_MIN_SWAP_INTERVAL:
+ *value = config->minSwapInterval;
+ break;
+ case EGL_MAX_SWAP_INTERVAL:
+ *value = config->maxSwapInterval;
+ break;
+ case EGL_LUMINANCE_SIZE:
+ *value = config->luminanceSize;
+ break;
+ case EGL_ALPHA_MASK_SIZE:
+ *value = config->alphaMaskSize;
+ break;
+ case EGL_COLOR_BUFFER_TYPE:
+ *value = config->colorBufferType;
+ break;
+ case EGL_RENDERABLE_TYPE:
+ *value = config->renderableType;
+ break;
+ case EGL_MATCH_NATIVE_PIXMAP:
+ *value = false;
+ UNIMPLEMENTED();
+ break;
+ case EGL_CONFORMANT:
+ *value = config->conformant;
+ break;
+ case EGL_MAX_PBUFFER_WIDTH:
+ *value = config->maxPBufferWidth;
+ break;
+ case EGL_MAX_PBUFFER_HEIGHT:
+ *value = config->maxPBufferHeight;
+ break;
+ case EGL_MAX_PBUFFER_PIXELS:
+ *value = config->maxPBufferPixels;
+ break;
+ case EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE:
+ *value = config->optimalOrientation;
+ break;
+ case EGL_COLOR_COMPONENT_TYPE_EXT:
+ *value = config->colorComponentType;
+ break;
+ case EGL_RECORDABLE_ANDROID:
+ *value = config->recordable;
+ break;
+ case EGL_FRAMEBUFFER_TARGET_ANDROID:
+ *value = config->framebufferTarget;
+ break;
+ case EGL_MATCH_FORMAT_KHR:
+ *value = config->matchFormat;
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+void QueryContextAttrib(const gl::Context *context, EGLint attribute, EGLint *value)
+{
+ switch (attribute)
+ {
+ case EGL_CONFIG_ID:
+ if (context->getConfig() != EGL_NO_CONFIG_KHR)
+ {
+ *value = context->getConfig()->configID;
+ }
+ else
+ {
+ *value = 0;
+ }
+ break;
+ case EGL_CONTEXT_CLIENT_TYPE:
+ *value = context->getClientType();
+ break;
+ case EGL_CONTEXT_CLIENT_VERSION:
+ *value = context->getClientMajorVersion();
+ break;
+ case EGL_RENDER_BUFFER:
+ *value = context->getRenderBuffer();
+ break;
+ case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
+ *value = context->isRobustResourceInitEnabled();
+ break;
+ case EGL_CONTEXT_PRIORITY_LEVEL_IMG:
+ *value = static_cast<EGLint>(context->getContextPriority());
+ break;
+ case EGL_PROTECTED_CONTENT_EXT:
+ *value = context->getState().hasProtectedContent();
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+egl::Error QuerySurfaceAttrib(const Display *display,
+ const gl::Context *context,
+ Surface *surface,
+ EGLint attribute,
+ EGLint *value)
+{
+ switch (attribute)
+ {
+ case EGL_GL_COLORSPACE:
+ *value = surface->getGLColorspace();
+ break;
+ case EGL_VG_ALPHA_FORMAT:
+ *value = surface->getVGAlphaFormat();
+ break;
+ case EGL_VG_COLORSPACE:
+ *value = surface->getVGColorspace();
+ break;
+ case EGL_CONFIG_ID:
+ *value = surface->getConfig()->configID;
+ break;
+ case EGL_HEIGHT:
+ ANGLE_TRY(surface->getUserHeight(display, value));
+ break;
+ case EGL_HORIZONTAL_RESOLUTION:
+ *value = surface->getHorizontalResolution();
+ break;
+ case EGL_LARGEST_PBUFFER:
+ // The EGL spec states that value is not written if the surface is not a pbuffer
+ if (surface->getType() == EGL_PBUFFER_BIT)
+ {
+ *value = surface->getLargestPbuffer();
+ }
+ break;
+ case EGL_MIPMAP_TEXTURE:
+ // The EGL spec states that value is not written if the surface is not a pbuffer
+ if (surface->getType() == EGL_PBUFFER_BIT)
+ {
+ *value = surface->getMipmapTexture();
+ }
+ break;
+ case EGL_MIPMAP_LEVEL:
+ // The EGL spec states that value is not written if the surface is not a pbuffer
+ if (surface->getType() == EGL_PBUFFER_BIT)
+ {
+ *value = surface->getMipmapLevel();
+ }
+ break;
+ case EGL_MULTISAMPLE_RESOLVE:
+ *value = surface->getMultisampleResolve();
+ break;
+ case EGL_PIXEL_ASPECT_RATIO:
+ *value = surface->getPixelAspectRatio();
+ break;
+ case EGL_RENDER_BUFFER:
+ *value = surface->getRenderBuffer();
+ break;
+ case EGL_SWAP_BEHAVIOR:
+ *value = surface->getSwapBehavior();
+ break;
+ case EGL_TEXTURE_FORMAT:
+ // The EGL spec states that value is not written if the surface is not a pbuffer
+ if (surface->getType() == EGL_PBUFFER_BIT)
+ {
+ *value = ToEGLenum(surface->getTextureFormat());
+ }
+ break;
+ case EGL_TEXTURE_TARGET:
+ // The EGL spec states that value is not written if the surface is not a pbuffer
+ if (surface->getType() == EGL_PBUFFER_BIT)
+ {
+ *value = surface->getTextureTarget();
+ }
+ break;
+ case EGL_VERTICAL_RESOLUTION:
+ *value = surface->getVerticalResolution();
+ break;
+ case EGL_WIDTH:
+ ANGLE_TRY(surface->getUserWidth(display, value));
+ break;
+ case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
+ *value = surface->isPostSubBufferSupported();
+ break;
+ case EGL_FIXED_SIZE_ANGLE:
+ *value = surface->isFixedSize();
+ break;
+ case EGL_SURFACE_ORIENTATION_ANGLE:
+ *value = surface->getOrientation();
+ break;
+ case EGL_DIRECT_COMPOSITION_ANGLE:
+ *value = surface->directComposition();
+ break;
+ case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
+ *value = surface->isRobustResourceInitEnabled();
+ break;
+ case EGL_TIMESTAMPS_ANDROID:
+ *value = surface->isTimestampsEnabled();
+ break;
+ case EGL_BUFFER_AGE_EXT:
+ ANGLE_TRY(surface->getBufferAge(context, value));
+ break;
+ case EGL_BITMAP_PITCH_KHR:
+ *value = surface->getBitmapPitch();
+ break;
+ case EGL_BITMAP_ORIGIN_KHR:
+ *value = surface->getBitmapOrigin();
+ break;
+ case EGL_BITMAP_PIXEL_RED_OFFSET_KHR:
+ *value = surface->getRedOffset();
+ break;
+ case EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR:
+ *value = surface->getGreenOffset();
+ break;
+ case EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR:
+ *value = surface->getBlueOffset();
+ break;
+ case EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR:
+ *value = surface->getAlphaOffset();
+ break;
+ case EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR:
+ *value = surface->getLuminanceOffset();
+ break;
+ case EGL_BITMAP_PIXEL_SIZE_KHR:
+ *value = surface->getBitmapPixelSize();
+ break;
+ case EGL_PROTECTED_CONTENT_EXT:
+ *value = surface->hasProtectedContent();
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ return NoError();
+}
+
+egl::Error QuerySurfaceAttrib64KHR(const Display *display,
+ const gl::Context *context,
+ const Surface *surface,
+ EGLint attribute,
+ EGLAttribKHR *value)
+{
+ switch (attribute)
+ {
+ case EGL_BITMAP_PITCH_KHR:
+ *value = static_cast<EGLAttribKHR>(surface->getBitmapPitch());
+ break;
+ case EGL_BITMAP_ORIGIN_KHR:
+ *value = static_cast<EGLAttribKHR>(surface->getBitmapOrigin());
+ break;
+ case EGL_BITMAP_PIXEL_RED_OFFSET_KHR:
+ *value = static_cast<EGLAttribKHR>(surface->getRedOffset());
+ break;
+ case EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR:
+ *value = static_cast<EGLAttribKHR>(surface->getGreenOffset());
+ break;
+ case EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR:
+ *value = static_cast<EGLAttribKHR>(surface->getBlueOffset());
+ break;
+ case EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR:
+ *value = static_cast<EGLAttribKHR>(surface->getAlphaOffset());
+ break;
+ case EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR:
+ *value = static_cast<EGLAttribKHR>(surface->getLuminanceOffset());
+ break;
+ case EGL_BITMAP_PIXEL_SIZE_KHR:
+ *value = static_cast<EGLAttribKHR>(surface->getBitmapPixelSize());
+ break;
+ case EGL_BITMAP_POINTER_KHR:
+ *value = surface->getBitmapPointer();
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ return NoError();
+}
+
+egl::Error SetSurfaceAttrib(Surface *surface, EGLint attribute, EGLint value)
+{
+ switch (attribute)
+ {
+ case EGL_MIPMAP_LEVEL:
+ surface->setMipmapLevel(value);
+ break;
+ case EGL_MULTISAMPLE_RESOLVE:
+ surface->setMultisampleResolve(value);
+ break;
+ case EGL_SWAP_BEHAVIOR:
+ surface->setSwapBehavior(value);
+ break;
+ case EGL_WIDTH:
+ surface->setFixedWidth(value);
+ break;
+ case EGL_HEIGHT:
+ surface->setFixedHeight(value);
+ break;
+ case EGL_TIMESTAMPS_ANDROID:
+ surface->setTimestampsEnabled(value != EGL_FALSE);
+ break;
+ case EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID:
+ return surface->setAutoRefreshEnabled(value == EGL_TRUE);
+ case EGL_RENDER_BUFFER:
+ return surface->setRenderBuffer(value);
+ default:
+ UNREACHABLE();
+ break;
+ }
+ return NoError();
+}
+
+Error GetSyncAttrib(Display *display, Sync *sync, EGLint attribute, EGLint *value)
+{
+ switch (attribute)
+ {
+ case EGL_SYNC_TYPE_KHR:
+ *value = sync->getType();
+ return NoError();
+
+ case EGL_SYNC_STATUS_KHR:
+ return sync->getStatus(display, value);
+
+ case EGL_SYNC_CONDITION_KHR:
+ *value = sync->getCondition();
+ return NoError();
+
+ default:
+ break;
+ }
+
+ UNREACHABLE();
+ return NoError();
+}
+} // namespace egl
diff --git a/gfx/angle/checkout/src/libANGLE/queryutils.h b/gfx/angle/checkout/src/libANGLE/queryutils.h
new file mode 100644
index 0000000000..dfb3680e8c
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/queryutils.h
@@ -0,0 +1,293 @@
+//
+// 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.
+//
+
+// queryutils.h: Utilities for querying values from GL objects
+
+#ifndef LIBANGLE_QUERYUTILS_H_
+#define LIBANGLE_QUERYUTILS_H_
+
+#include "angle_gl.h"
+#include "common/PackedEnums.h"
+#include "common/angleutils.h"
+#include "libANGLE/Error.h"
+
+#include <EGL/egl.h>
+
+namespace gl
+{
+class Buffer;
+class Context;
+class Sync;
+class Framebuffer;
+class GLES1State;
+class Program;
+class Renderbuffer;
+class Sampler;
+class Shader;
+class State;
+class Texture;
+struct TextureCaps;
+struct UniformBlock;
+struct VertexAttribute;
+class VertexBinding;
+struct VertexAttribCurrentValueData;
+
+void QueryFramebufferAttachmentParameteriv(const Context *context,
+ const Framebuffer *framebuffer,
+ GLenum attachment,
+ GLenum pname,
+ GLint *params);
+void QueryBufferParameteriv(const Buffer *buffer, GLenum pname, GLint *params);
+void QueryBufferParameteri64v(const Buffer *buffer, GLenum pname, GLint64 *params);
+void QueryBufferPointerv(const Buffer *buffer, GLenum pname, void **params);
+void QueryProgramiv(Context *context, const Program *program, GLenum pname, GLint *params);
+void QueryRenderbufferiv(const Context *context,
+ const Renderbuffer *renderbuffer,
+ GLenum pname,
+ GLint *params);
+void QueryShaderiv(const Context *context, Shader *shader, GLenum pname, GLint *params);
+void QueryTexLevelParameterfv(const Texture *texture,
+ TextureTarget target,
+ GLint level,
+ GLenum pname,
+ GLfloat *params);
+void QueryTexLevelParameteriv(const Texture *texture,
+ TextureTarget target,
+ GLint level,
+ GLenum pname,
+ GLint *params);
+void QueryTexParameterfv(const Context *context,
+ const Texture *texture,
+ GLenum pname,
+ GLfloat *params);
+void QueryTexParameterxv(const Context *context,
+ const Texture *texture,
+ GLenum pname,
+ GLfixed *params);
+void QueryTexParameteriv(const Context *context,
+ const Texture *texture,
+ GLenum pname,
+ GLint *params);
+void QueryTexParameterIiv(const Context *context,
+ const Texture *texture,
+ GLenum pname,
+ GLint *params);
+void QueryTexParameterIuiv(const Context *context,
+ const Texture *texture,
+ GLenum pname,
+ GLuint *params);
+void QuerySamplerParameterfv(const Sampler *sampler, GLenum pname, GLfloat *params);
+void QuerySamplerParameteriv(const Sampler *sampler, GLenum pname, GLint *params);
+void QuerySamplerParameterIiv(const Sampler *sampler, GLenum pname, GLint *params);
+void QuerySamplerParameterIuiv(const Sampler *sampler, GLenum pname, GLuint *params);
+
+// Warning: you should ensure binding really matches attrib.bindingIndex before using the following
+// functions.
+void QueryVertexAttribfv(const VertexAttribute &attrib,
+ const VertexBinding &binding,
+ const VertexAttribCurrentValueData &currentValueData,
+ GLenum pname,
+ GLfloat *params);
+
+void QueryVertexAttribiv(const VertexAttribute &attrib,
+ const VertexBinding &binding,
+ const VertexAttribCurrentValueData &currentValueData,
+ GLenum pname,
+ GLint *params);
+
+void QueryVertexAttribPointerv(const VertexAttribute &attrib, GLenum pname, void **pointer);
+
+void QueryVertexAttribIiv(const VertexAttribute &attrib,
+ const VertexBinding &binding,
+ const VertexAttribCurrentValueData &currentValueData,
+ GLenum pname,
+ GLint *params);
+
+void QueryVertexAttribIuiv(const VertexAttribute &attrib,
+ const VertexBinding &binding,
+ const VertexAttribCurrentValueData &currentValueData,
+ GLenum pname,
+ GLuint *params);
+
+void QueryActiveUniformBlockiv(const Program *program,
+ UniformBlockIndex uniformBlockIndex,
+ GLenum pname,
+ GLint *params);
+
+void QueryInternalFormativ(const TextureCaps &format, GLenum pname, GLsizei bufSize, GLint *params);
+
+void QueryFramebufferParameteriv(const Framebuffer *framebuffer, GLenum pname, GLint *params);
+
+angle::Result QuerySynciv(const Context *context,
+ const Sync *sync,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *values);
+
+void SetTexParameterf(Context *context, Texture *texture, GLenum pname, GLfloat param);
+void SetTexParameterfv(Context *context, Texture *texture, GLenum pname, const GLfloat *params);
+void SetTexParameteri(Context *context, Texture *texture, GLenum pname, GLint param);
+void SetTexParameteriv(Context *context, Texture *texture, GLenum pname, const GLint *params);
+void SetTexParameterIiv(Context *context, Texture *texture, GLenum pname, const GLint *params);
+void SetTexParameterIuiv(Context *context, Texture *texture, GLenum pname, const GLuint *params);
+void SetTexParameterx(Context *context, Texture *texture, GLenum pname, GLfixed param);
+void SetTexParameterxv(Context *context, Texture *texture, GLenum pname, const GLfixed *params);
+
+void SetSamplerParameterf(Context *context, Sampler *sampler, GLenum pname, GLfloat param);
+void SetSamplerParameterfv(Context *context, Sampler *sampler, GLenum pname, const GLfloat *params);
+void SetSamplerParameteri(Context *context, Sampler *sampler, GLenum pname, GLint param);
+void SetSamplerParameteriv(Context *context, Sampler *sampler, GLenum pname, const GLint *params);
+void SetSamplerParameterIiv(Context *context, Sampler *sampler, GLenum pname, const GLint *params);
+void SetSamplerParameterIuiv(Context *context,
+ Sampler *sampler,
+ GLenum pname,
+ const GLuint *params);
+
+void SetFramebufferParameteri(const Context *context,
+ Framebuffer *framebuffer,
+ GLenum pname,
+ GLint param);
+
+void SetProgramParameteri(Program *program, GLenum pname, GLint value);
+
+GLint GetUniformResourceProperty(const Program *program, GLuint index, const GLenum prop);
+
+GLuint QueryProgramResourceIndex(const Program *program,
+ GLenum programInterface,
+ const GLchar *name);
+
+void QueryProgramResourceName(const Context *context,
+ const Program *program,
+ GLenum programInterface,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *name);
+
+GLint QueryProgramResourceLocation(const Program *program,
+ GLenum programInterface,
+ const GLchar *name);
+void QueryProgramResourceiv(const Program *program,
+ GLenum programInterface,
+ UniformBlockIndex index,
+ GLsizei propCount,
+ const GLenum *props,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+
+void QueryProgramInterfaceiv(const Program *program,
+ GLenum programInterface,
+ GLenum pname,
+ GLint *params);
+
+angle::Result SetMemoryObjectParameteriv(const Context *context,
+ MemoryObject *memoryObject,
+ GLenum pname,
+ const GLint *params);
+void QueryMemoryObjectParameteriv(const MemoryObject *memoryObject, GLenum pname, GLint *params);
+
+// GLES1 emulation
+
+ClientVertexArrayType ParamToVertexArrayType(GLenum param);
+
+void SetLightParameters(GLES1State *state,
+ GLenum light,
+ LightParameter pname,
+ const GLfloat *params);
+void GetLightParameters(const GLES1State *state,
+ GLenum light,
+ LightParameter pname,
+ GLfloat *params);
+
+void SetLightModelParameters(GLES1State *state, GLenum pname, const GLfloat *params);
+void GetLightModelParameters(const GLES1State *state, GLenum pname, GLfloat *params);
+bool IsLightModelTwoSided(const GLES1State *state);
+
+void SetMaterialParameters(GLES1State *state,
+ GLenum face,
+ MaterialParameter pname,
+ const GLfloat *params);
+void GetMaterialParameters(const GLES1State *state,
+ GLenum face,
+ MaterialParameter pname,
+ GLfloat *params);
+
+unsigned int GetLightModelParameterCount(GLenum pname);
+unsigned int GetLightParameterCount(LightParameter pname);
+unsigned int GetMaterialParameterCount(MaterialParameter pname);
+
+void SetFogParameters(GLES1State *state, GLenum pname, const GLfloat *params);
+void GetFogParameters(const GLES1State *state, GLenum pname, GLfloat *params);
+unsigned int GetFogParameterCount(GLenum pname);
+
+unsigned int GetTextureEnvParameterCount(TextureEnvParameter pname);
+
+void ConvertTextureEnvFromInt(TextureEnvParameter pname, const GLint *input, GLfloat *output);
+void ConvertTextureEnvFromFixed(TextureEnvParameter pname, const GLfixed *input, GLfloat *output);
+void ConvertTextureEnvToInt(TextureEnvParameter pname, const GLfloat *input, GLint *output);
+void ConvertTextureEnvToFixed(TextureEnvParameter pname, const GLfloat *input, GLfixed *output);
+
+void SetTextureEnv(unsigned int unit,
+ GLES1State *state,
+ TextureEnvTarget target,
+ TextureEnvParameter pname,
+ const GLfloat *params);
+void GetTextureEnv(unsigned int unit,
+ const GLES1State *state,
+ TextureEnvTarget target,
+ TextureEnvParameter pname,
+ GLfloat *params);
+
+unsigned int GetPointParameterCount(PointParameter pname);
+
+void SetPointParameter(GLES1State *state, PointParameter pname, const GLfloat *params);
+void GetPointParameter(const GLES1State *state, PointParameter pname, GLfloat *params);
+
+void SetPointSize(GLES1State *state, GLfloat size);
+void GetPointSize(const GLES1State *state, GLfloat *sizeOut);
+
+unsigned int GetTexParameterCount(GLenum pname);
+
+bool GetQueryParameterInfo(const State &glState,
+ GLenum pname,
+ GLenum *type,
+ unsigned int *numParams);
+
+void QueryProgramPipelineiv(const Context *context,
+ ProgramPipeline *programPipeline,
+ GLenum pname,
+ GLint *params);
+} // namespace gl
+
+namespace egl
+{
+struct Config;
+class Display;
+class Surface;
+class Sync;
+
+void QueryConfigAttrib(const Config *config, EGLint attribute, EGLint *value);
+
+void QueryContextAttrib(const gl::Context *context, EGLint attribute, EGLint *value);
+
+egl::Error QuerySurfaceAttrib(const Display *display,
+ const gl::Context *context,
+ Surface *surface,
+ EGLint attribute,
+ EGLint *value);
+egl::Error SetSurfaceAttrib(Surface *surface, EGLint attribute, EGLint value);
+Error GetSyncAttrib(Display *display, Sync *sync, EGLint attribute, EGLint *value);
+egl::Error QuerySurfaceAttrib64KHR(const Display *display,
+ const gl::Context *context,
+ const Surface *surface,
+ EGLint attribute,
+ EGLAttribKHR *value);
+
+} // namespace egl
+
+#endif // LIBANGLE_QUERYUTILS_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/BufferImpl.cpp b/gfx/angle/checkout/src/libANGLE/renderer/BufferImpl.cpp
new file mode 100644
index 0000000000..9cd3c5b6f6
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/BufferImpl.cpp
@@ -0,0 +1,39 @@
+//
+// Copyright 2020 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.
+//
+
+// BufferImpl.cpp: Implementation methods rx::BufferImpl class.
+
+#include "libANGLE/renderer/BufferImpl.h"
+
+namespace rx
+{
+
+angle::Result BufferImpl::getSubData(const gl::Context *context,
+ GLintptr offset,
+ GLsizeiptr size,
+ void *outData)
+{
+ UNREACHABLE();
+ return angle::Result::Stop;
+}
+
+angle::Result BufferImpl::setDataWithUsageFlags(const gl::Context *context,
+ gl::BufferBinding target,
+ GLeglClientBufferEXT clientBuffer,
+ const void *data,
+ size_t size,
+ gl::BufferUsage usage,
+ GLbitfield flags)
+{
+ return setData(context, target, data, size, usage);
+}
+
+angle::Result BufferImpl::onLabelUpdate(const gl::Context *context)
+{
+ return angle::Result::Continue;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/BufferImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/BufferImpl.h
new file mode 100644
index 0000000000..6238a4def3
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/BufferImpl.h
@@ -0,0 +1,98 @@
+//
+// 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.
+//
+
+// BufferImpl.h: Defines the abstract rx::BufferImpl class.
+
+#ifndef LIBANGLE_RENDERER_BUFFERIMPL_H_
+#define LIBANGLE_RENDERER_BUFFERIMPL_H_
+
+#include "common/PackedEnums.h"
+#include "common/angleutils.h"
+#include "common/mathutil.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/Observer.h"
+
+#include <stdint.h>
+
+namespace gl
+{
+class BufferState;
+class Context;
+} // namespace gl
+
+namespace rx
+{
+// We use two set of Subject messages. The CONTENTS_CHANGED message is signaled whenever data
+// changes, to trigger re-translation or other events. Some buffers only need to be updated when the
+// underlying driver object changes - this is notified via the STORAGE_CHANGED message.
+class BufferImpl : public angle::Subject
+{
+ public:
+ BufferImpl(const gl::BufferState &state) : mState(state) {}
+ ~BufferImpl() override {}
+ virtual void destroy(const gl::Context *context) {}
+
+ virtual angle::Result setDataWithUsageFlags(const gl::Context *context,
+ gl::BufferBinding target,
+ GLeglClientBufferEXT clientBuffer,
+ const void *data,
+ size_t size,
+ gl::BufferUsage usage,
+ GLbitfield flags);
+ virtual angle::Result setData(const gl::Context *context,
+ gl::BufferBinding target,
+ const void *data,
+ size_t size,
+ gl::BufferUsage usage) = 0;
+ virtual angle::Result setSubData(const gl::Context *context,
+ gl::BufferBinding target,
+ const void *data,
+ size_t size,
+ size_t offset) = 0;
+ virtual angle::Result copySubData(const gl::Context *context,
+ BufferImpl *source,
+ GLintptr sourceOffset,
+ GLintptr destOffset,
+ GLsizeiptr size) = 0;
+ virtual angle::Result map(const gl::Context *context, GLenum access, void **mapPtr) = 0;
+ virtual angle::Result mapRange(const gl::Context *context,
+ size_t offset,
+ size_t length,
+ GLbitfield access,
+ void **mapPtr) = 0;
+ virtual angle::Result unmap(const gl::Context *context, GLboolean *result) = 0;
+
+ virtual angle::Result getIndexRange(const gl::Context *context,
+ gl::DrawElementsType type,
+ size_t offset,
+ size_t count,
+ bool primitiveRestartEnabled,
+ gl::IndexRange *outRange) = 0;
+
+ virtual angle::Result getSubData(const gl::Context *context,
+ GLintptr offset,
+ GLsizeiptr size,
+ void *outData);
+
+ virtual angle::Result onLabelUpdate(const gl::Context *context);
+
+ // Override if accurate native memory size information is available
+ virtual GLint64 getMemorySize() const;
+
+ virtual void onDataChanged() {}
+
+ protected:
+ const gl::BufferState &mState;
+};
+
+inline GLint64 BufferImpl::getMemorySize() const
+{
+ return 0;
+}
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_BUFFERIMPL_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/CompilerImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/CompilerImpl.h
new file mode 100644
index 0000000000..0e8c5192f2
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/CompilerImpl.h
@@ -0,0 +1,32 @@
+//
+// 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.
+//
+
+// CompilerImpl.h: Defines the rx::CompilerImpl class, an implementation interface
+// for the gl::Compiler object.
+
+#include "GLSLANG/ShaderLang.h"
+#include "common/angleutils.h"
+#include "libANGLE/Error.h"
+
+#ifndef LIBANGLE_RENDERER_COMPILERIMPL_H_
+# define LIBANGLE_RENDERER_COMPILERIMPL_H_
+
+namespace rx
+{
+
+class CompilerImpl : angle::NonCopyable
+{
+ public:
+ CompilerImpl() {}
+ virtual ~CompilerImpl() {}
+
+ // TODO(jmadill): Expose translator built-in resources init method.
+ virtual ShShaderOutput getTranslatorOutputType() const = 0;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_COMPILERIMPL_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/ContextImpl.cpp b/gfx/angle/checkout/src/libANGLE/renderer/ContextImpl.cpp
new file mode 100644
index 0000000000..952d4ee37a
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/ContextImpl.cpp
@@ -0,0 +1,88 @@
+//
+// 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.
+//
+// ContextImpl:
+// Implementation-specific functionality associated with a GL Context.
+//
+
+#include "libANGLE/renderer/ContextImpl.h"
+
+#include "common/third_party/base/anglebase/no_destructor.h"
+#include "libANGLE/Context.h"
+
+namespace rx
+{
+ContextImpl::ContextImpl(const gl::State &state, gl::ErrorSet *errorSet)
+ : mState(state), mMemoryProgramCache(nullptr), mErrors(errorSet)
+{}
+
+ContextImpl::~ContextImpl() {}
+
+void ContextImpl::invalidateTexture(gl::TextureType target)
+{
+ UNREACHABLE();
+}
+
+angle::Result ContextImpl::onUnMakeCurrent(const gl::Context *context)
+{
+ return angle::Result::Continue;
+}
+
+angle::Result ContextImpl::handleNoopDrawEvent()
+{
+ return angle::Result::Continue;
+}
+
+void ContextImpl::setMemoryProgramCache(gl::MemoryProgramCache *memoryProgramCache)
+{
+ mMemoryProgramCache = memoryProgramCache;
+}
+
+void ContextImpl::handleError(GLenum errorCode,
+ const char *message,
+ const char *file,
+ const char *function,
+ unsigned int line)
+{
+ std::stringstream errorStream;
+ errorStream << "Internal error: " << gl::FmtHex(errorCode) << ": " << message;
+ mErrors->handleError(errorCode, errorStream.str().c_str(), file, function, line);
+}
+
+egl::ContextPriority ContextImpl::getContextPriority() const
+{
+ return egl::ContextPriority::Medium;
+}
+
+egl::Error ContextImpl::releaseHighPowerGPU(gl::Context *)
+{
+ return egl::NoError();
+}
+
+egl::Error ContextImpl::reacquireHighPowerGPU(gl::Context *)
+{
+ return egl::NoError();
+}
+
+angle::Result ContextImpl::acquireTextures(const gl::Context *context,
+ const gl::TextureBarrierVector &textureBarriers)
+{
+ UNREACHABLE();
+ return angle::Result::Stop;
+}
+
+angle::Result ContextImpl::releaseTextures(const gl::Context *context,
+ gl::TextureBarrierVector *textureBarriers)
+{
+ UNREACHABLE();
+ return angle::Result::Stop;
+}
+
+const angle::PerfMonitorCounterGroups &ContextImpl::getPerfMonitorCounters()
+{
+ static angle::base::NoDestructor<angle::PerfMonitorCounterGroups> sCounters;
+ return *sCounters;
+}
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/ContextImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/ContextImpl.h
new file mode 100644
index 0000000000..3b167fe8b6
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/ContextImpl.h
@@ -0,0 +1,274 @@
+//
+// 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.
+//
+// ContextImpl:
+// Implementation-specific functionality associated with a GL Context.
+//
+
+#ifndef LIBANGLE_RENDERER_CONTEXTIMPL_H_
+#define LIBANGLE_RENDERER_CONTEXTIMPL_H_
+
+#include <vector>
+
+#include "common/angleutils.h"
+#include "libANGLE/State.h"
+#include "libANGLE/renderer/GLImplFactory.h"
+
+namespace gl
+{
+class ErrorSet;
+class MemoryProgramCache;
+class Path;
+class Semaphore;
+struct Workarounds;
+} // namespace gl
+
+namespace rx
+{
+class ContextImpl : public GLImplFactory
+{
+ public:
+ ContextImpl(const gl::State &state, gl::ErrorSet *errorSet);
+ ~ContextImpl() override;
+
+ virtual void onDestroy(const gl::Context *context) {}
+
+ virtual angle::Result initialize() = 0;
+
+ // Flush and finish.
+ virtual angle::Result flush(const gl::Context *context) = 0;
+ virtual angle::Result finish(const gl::Context *context) = 0;
+
+ // Drawing methods.
+ virtual angle::Result drawArrays(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLint first,
+ GLsizei count) = 0;
+ virtual angle::Result drawArraysInstanced(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLint first,
+ GLsizei count,
+ GLsizei instanceCount) = 0;
+ // Necessary for Vulkan since gl_InstanceIndex includes baseInstance
+ virtual angle::Result drawArraysInstancedBaseInstance(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLint first,
+ GLsizei count,
+ GLsizei instanceCount,
+ GLuint baseInstance) = 0;
+
+ virtual angle::Result drawElements(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices) = 0;
+ virtual angle::Result drawElementsBaseVertex(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices,
+ GLint baseVertex) = 0;
+ virtual angle::Result drawElementsInstanced(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices,
+ GLsizei instances) = 0;
+ virtual angle::Result drawElementsInstancedBaseVertex(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices,
+ GLsizei instances,
+ GLint baseVertex) = 0;
+ virtual angle::Result drawElementsInstancedBaseVertexBaseInstance(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices,
+ GLsizei instances,
+ GLint baseVertex,
+ GLuint baseInstance) = 0;
+ virtual angle::Result drawRangeElements(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices) = 0;
+ virtual angle::Result drawRangeElementsBaseVertex(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices,
+ GLint baseVertex) = 0;
+
+ virtual angle::Result drawArraysIndirect(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const void *indirect) = 0;
+ virtual angle::Result drawElementsIndirect(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ gl::DrawElementsType type,
+ const void *indirect) = 0;
+
+ // MultiDraw* impl added as we need workaround for promoting dynamic attributes in D3D backend
+ virtual angle::Result multiDrawArrays(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const GLint *firsts,
+ const GLsizei *counts,
+ GLsizei drawcount) = 0;
+ virtual angle::Result multiDrawArraysIndirect(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const void *indirect,
+ GLsizei drawcount,
+ GLsizei stride) = 0;
+ virtual angle::Result multiDrawArraysInstanced(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const GLint *firsts,
+ const GLsizei *counts,
+ const GLsizei *instanceCounts,
+ GLsizei drawcount) = 0;
+ virtual angle::Result multiDrawElements(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const GLsizei *counts,
+ gl::DrawElementsType type,
+ const GLvoid *const *indices,
+ GLsizei drawcount) = 0;
+ virtual angle::Result multiDrawElementsInstanced(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const GLsizei *counts,
+ gl::DrawElementsType type,
+ const GLvoid *const *indices,
+ const GLsizei *instanceCounts,
+ GLsizei drawcount) = 0;
+ virtual angle::Result multiDrawElementsIndirect(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ gl::DrawElementsType type,
+ const void *indirect,
+ GLsizei drawcount,
+ GLsizei stride) = 0;
+ virtual angle::Result multiDrawArraysInstancedBaseInstance(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const GLint *firsts,
+ const GLsizei *counts,
+ const GLsizei *instanceCounts,
+ const GLuint *baseInstances,
+ GLsizei drawcount) = 0;
+ virtual angle::Result multiDrawElementsInstancedBaseVertexBaseInstance(
+ const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const GLsizei *counts,
+ gl::DrawElementsType type,
+ const GLvoid *const *indices,
+ const GLsizei *instanceCounts,
+ const GLint *baseVertices,
+ const GLuint *baseInstances,
+ GLsizei drawcount) = 0;
+
+ // Device loss
+ virtual gl::GraphicsResetStatus getResetStatus() = 0;
+
+ // EXT_debug_marker
+ virtual angle::Result insertEventMarker(GLsizei length, const char *marker) = 0;
+ virtual angle::Result pushGroupMarker(GLsizei length, const char *marker) = 0;
+ virtual angle::Result popGroupMarker() = 0;
+
+ // KHR_debug
+ virtual angle::Result pushDebugGroup(const gl::Context *context,
+ GLenum source,
+ GLuint id,
+ const std::string &message) = 0;
+ virtual angle::Result popDebugGroup(const gl::Context *context) = 0;
+ virtual angle::Result handleNoopDrawEvent();
+
+ // KHR_parallel_shader_compile
+ virtual void setMaxShaderCompilerThreads(GLuint count) {}
+
+ // GL_ANGLE_texture_storage_external
+ virtual void invalidateTexture(gl::TextureType target);
+
+ // EXT_shader_framebuffer_fetch_non_coherent
+ virtual void framebufferFetchBarrier() {}
+
+ // KHR_blend_equation_advanced
+ virtual void blendBarrier() {}
+
+ // State sync with dirty bits.
+ virtual angle::Result syncState(const gl::Context *context,
+ const gl::State::DirtyBits &dirtyBits,
+ const gl::State::DirtyBits &bitMask,
+ gl::Command command) = 0;
+
+ // Disjoint timer queries
+ virtual GLint getGPUDisjoint() = 0;
+ virtual GLint64 getTimestamp() = 0;
+
+ // Context switching
+ virtual angle::Result onMakeCurrent(const gl::Context *context) = 0;
+ virtual angle::Result onUnMakeCurrent(const gl::Context *context);
+
+ // Native capabilities, unmodified by gl::Context.
+ virtual gl::Caps getNativeCaps() const = 0;
+ virtual const gl::TextureCapsMap &getNativeTextureCaps() const = 0;
+ virtual const gl::Extensions &getNativeExtensions() const = 0;
+ virtual const gl::Limitations &getNativeLimitations() const = 0;
+ virtual ShPixelLocalStorageType getNativePixelLocalStorageType() const = 0;
+
+ virtual angle::Result dispatchCompute(const gl::Context *context,
+ GLuint numGroupsX,
+ GLuint numGroupsY,
+ GLuint numGroupsZ) = 0;
+ virtual angle::Result dispatchComputeIndirect(const gl::Context *context,
+ GLintptr indirect) = 0;
+
+ virtual angle::Result memoryBarrier(const gl::Context *context, GLbitfield barriers) = 0;
+ virtual angle::Result memoryBarrierByRegion(const gl::Context *context,
+ GLbitfield barriers) = 0;
+
+ const gl::State &getState() const { return mState; }
+ int getClientMajorVersion() const { return mState.getClientMajorVersion(); }
+ int getClientMinorVersion() const { return mState.getClientMinorVersion(); }
+ const gl::Caps &getCaps() const { return mState.getCaps(); }
+ const gl::TextureCapsMap &getTextureCaps() const { return mState.getTextureCaps(); }
+ const gl::Extensions &getExtensions() const { return mState.getExtensions(); }
+ const gl::Limitations &getLimitations() const { return mState.getLimitations(); }
+
+ // A common GL driver behaviour is to trigger dynamic shader recompilation on a draw call,
+ // based on the current render states. We store a mutable pointer to the program cache so
+ // on draw calls we can store the refreshed shaders in the cache.
+ void setMemoryProgramCache(gl::MemoryProgramCache *memoryProgramCache);
+
+ void handleError(GLenum errorCode,
+ const char *message,
+ const char *file,
+ const char *function,
+ unsigned int line);
+
+ virtual egl::ContextPriority getContextPriority() const;
+
+ // EGL_ANGLE_power_preference implementation.
+ virtual egl::Error releaseHighPowerGPU(gl::Context *context);
+ virtual egl::Error reacquireHighPowerGPU(gl::Context *context);
+
+ // GL_ANGLE_vulkan_image
+ virtual angle::Result acquireTextures(const gl::Context *context,
+ const gl::TextureBarrierVector &textureBarriers);
+ virtual angle::Result releaseTextures(const gl::Context *context,
+ gl::TextureBarrierVector *textureBarriers);
+
+ // AMD_performance_monitor
+ virtual const angle::PerfMonitorCounterGroups &getPerfMonitorCounters();
+
+ protected:
+ const gl::State &mState;
+ gl::MemoryProgramCache *mMemoryProgramCache;
+ gl::ErrorSet *mErrors;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_CONTEXTIMPL_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/DeviceImpl.cpp b/gfx/angle/checkout/src/libANGLE/renderer/DeviceImpl.cpp
new file mode 100644
index 0000000000..109fc48477
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/DeviceImpl.cpp
@@ -0,0 +1,18 @@
+//
+// 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.
+//
+
+// DeviceImpl.cpp: Implementation methods of egl::Device
+
+#include "libANGLE/renderer/DeviceImpl.h"
+
+namespace rx
+{
+
+DeviceImpl::DeviceImpl() {}
+
+DeviceImpl::~DeviceImpl() {}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/DeviceImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/DeviceImpl.h
new file mode 100644
index 0000000000..30cee7d514
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/DeviceImpl.h
@@ -0,0 +1,42 @@
+//
+// 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.
+//
+
+// DeviceImpl.h: Implementation methods of egl::Device
+
+#ifndef LIBANGLE_RENDERER_DEVICEIMPL_H_
+#define LIBANGLE_RENDERER_DEVICEIMPL_H_
+
+#include "common/angleutils.h"
+#include "libANGLE/Caps.h"
+#include "libANGLE/Error.h"
+
+namespace egl
+{
+class Display;
+}
+
+namespace rx
+{
+class DisplayImpl;
+
+class DeviceImpl : angle::NonCopyable
+{
+ public:
+ DeviceImpl();
+ virtual ~DeviceImpl();
+
+ virtual egl::Error initialize() = 0;
+
+ virtual egl::Error getAttribute(const egl::Display *display,
+ EGLint attribute,
+ void **outValue) = 0;
+ virtual EGLint getType() = 0;
+ virtual void generateExtensions(egl::DeviceExtensions *outExtensions) const = 0;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_DEVICEIMPL_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/DisplayImpl.cpp b/gfx/angle/checkout/src/libANGLE/renderer/DisplayImpl.cpp
new file mode 100644
index 0000000000..f07cd30517
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/DisplayImpl.cpp
@@ -0,0 +1,168 @@
+//
+// 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.
+//
+
+// DisplayImpl.cpp: Implementation methods of egl::Display
+
+#include "libANGLE/renderer/DisplayImpl.h"
+
+#include "libANGLE/Display.h"
+#include "libANGLE/Surface.h"
+#include "libANGLE/renderer/DeviceImpl.h"
+
+namespace rx
+{
+namespace
+{
+// For back-ends that do not implement EGLDevice.
+class MockDevice : public DeviceImpl
+{
+ public:
+ MockDevice() = default;
+ egl::Error initialize() override { return egl::NoError(); }
+ egl::Error getAttribute(const egl::Display *display, EGLint attribute, void **outValue) override
+ {
+ UNREACHABLE();
+ return egl::EglBadAttribute();
+ }
+ EGLint getType() override
+ {
+ UNREACHABLE();
+ return EGL_NONE;
+ }
+ void generateExtensions(egl::DeviceExtensions *outExtensions) const override
+ {
+ *outExtensions = egl::DeviceExtensions();
+ }
+};
+} // anonymous namespace
+
+DisplayImpl::DisplayImpl(const egl::DisplayState &state)
+ : mState(state), mExtensionsInitialized(false), mCapsInitialized(false), mBlobCache(nullptr)
+{}
+
+DisplayImpl::~DisplayImpl()
+{
+ ASSERT(mState.surfaceSet.empty());
+}
+
+egl::Error DisplayImpl::prepareForCall()
+{
+ return egl::NoError();
+}
+
+egl::Error DisplayImpl::releaseThread()
+{
+ return egl::NoError();
+}
+
+const egl::DisplayExtensions &DisplayImpl::getExtensions() const
+{
+ if (!mExtensionsInitialized)
+ {
+ generateExtensions(&mExtensions);
+ mExtensionsInitialized = true;
+ }
+
+ return mExtensions;
+}
+
+egl::Error DisplayImpl::handleGPUSwitch()
+{
+ return egl::NoError();
+}
+
+egl::Error DisplayImpl::forceGPUSwitch(EGLint gpuIDHigh, EGLint gpuIDLow)
+{
+ return egl::NoError();
+}
+
+egl::Error DisplayImpl::validateClientBuffer(const egl::Config *configuration,
+ EGLenum buftype,
+ EGLClientBuffer clientBuffer,
+ const egl::AttributeMap &attribs) const
+{
+ UNREACHABLE();
+ return egl::EglBadDisplay() << "DisplayImpl::validateClientBuffer unimplemented.";
+}
+
+egl::Error DisplayImpl::validateImageClientBuffer(const gl::Context *context,
+ EGLenum target,
+ EGLClientBuffer clientBuffer,
+ const egl::AttributeMap &attribs) const
+{
+ UNREACHABLE();
+ return egl::EglBadDisplay() << "DisplayImpl::validateImageClientBuffer unimplemented.";
+}
+
+egl::Error DisplayImpl::validatePixmap(const egl::Config *config,
+ EGLNativePixmapType pixmap,
+ const egl::AttributeMap &attributes) const
+{
+ UNREACHABLE();
+ return egl::EglBadDisplay() << "DisplayImpl::valdiatePixmap unimplemented.";
+}
+
+const egl::Caps &DisplayImpl::getCaps() const
+{
+ if (!mCapsInitialized)
+ {
+ generateCaps(&mCaps);
+ mCapsInitialized = true;
+ }
+
+ return mCaps;
+}
+
+DeviceImpl *DisplayImpl::createDevice()
+{
+ return new MockDevice();
+}
+
+bool DisplayImpl::isX11() const
+{
+ return false;
+}
+
+bool DisplayImpl::isWayland() const
+{
+ return false;
+}
+
+bool DisplayImpl::isGBM() const
+{
+ return false;
+}
+
+bool DisplayImpl::supportsDmaBufFormat(EGLint format) const
+{
+ UNREACHABLE();
+ return false;
+}
+
+egl::Error DisplayImpl::queryDmaBufFormats(EGLint max_formats, EGLint *formats, EGLint *num_formats)
+{
+ UNREACHABLE();
+ return egl::NoError();
+}
+
+egl::Error DisplayImpl::queryDmaBufModifiers(EGLint format,
+ EGLint max_modifiers,
+ EGLuint64KHR *modifiers,
+ EGLBoolean *external_only,
+ EGLint *num_modifiers)
+{
+ UNREACHABLE();
+ return egl::NoError();
+}
+
+GLuint DisplayImpl::getNextSurfaceID()
+{
+ uint64_t id = mNextSurfaceID.generate().getValue();
+ ASSERT(id <= 0xfffffffful);
+ return static_cast<GLuint>(id);
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/DisplayImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/DisplayImpl.h
new file mode 100644
index 0000000000..0dea083f9e
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/DisplayImpl.h
@@ -0,0 +1,169 @@
+//
+// 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.
+//
+
+// DisplayImpl.h: Implementation methods of egl::Display
+
+#ifndef LIBANGLE_RENDERER_DISPLAYIMPL_H_
+#define LIBANGLE_RENDERER_DISPLAYIMPL_H_
+
+#include "common/Optional.h"
+#include "common/angleutils.h"
+#include "libANGLE/Caps.h"
+#include "libANGLE/Config.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/Observer.h"
+#include "libANGLE/Stream.h"
+#include "libANGLE/Version.h"
+#include "libANGLE/renderer/EGLImplFactory.h"
+#include "platform/Feature.h"
+
+#include <set>
+#include <vector>
+
+namespace angle
+{
+struct FrontendFeatures;
+} // namespace angle
+
+namespace egl
+{
+class AttributeMap;
+class BlobCache;
+class Display;
+struct DisplayState;
+struct Config;
+class Surface;
+class ImageSibling;
+class Thread;
+} // namespace egl
+
+namespace gl
+{
+class Context;
+} // namespace gl
+
+namespace rx
+{
+class SurfaceImpl;
+class ImageImpl;
+struct ConfigDesc;
+class DeviceImpl;
+class StreamProducerImpl;
+
+class ShareGroupImpl : angle::NonCopyable
+{
+ public:
+ ShareGroupImpl() : mAnyContextWithRobustness(false) {}
+ virtual ~ShareGroupImpl() {}
+ virtual void onDestroy(const egl::Display *display) {}
+
+ void onRobustContextAdd() { mAnyContextWithRobustness = true; }
+ bool hasAnyContextWithRobustness() const { return mAnyContextWithRobustness; }
+
+ private:
+ // Whether any context in the share group has robustness enabled. If any context in the share
+ // group is robust, any program created in any context of the share group must have robustness
+ // enabled. This is because programs are shared between the share group contexts.
+ bool mAnyContextWithRobustness;
+};
+
+class DisplayImpl : public EGLImplFactory, public angle::Subject
+{
+ public:
+ DisplayImpl(const egl::DisplayState &state);
+ ~DisplayImpl() override;
+
+ virtual egl::Error initialize(egl::Display *display) = 0;
+ virtual void terminate() = 0;
+ virtual egl::Error prepareForCall();
+ virtual egl::Error releaseThread();
+
+ virtual egl::Error makeCurrent(egl::Display *display,
+ egl::Surface *drawSurface,
+ egl::Surface *readSurface,
+ gl::Context *context) = 0;
+
+ virtual egl::ConfigSet generateConfigs() = 0;
+
+ virtual bool testDeviceLost() = 0;
+ virtual egl::Error restoreLostDevice(const egl::Display *display) = 0;
+
+ virtual bool isValidNativeWindow(EGLNativeWindowType window) const = 0;
+ virtual egl::Error validateClientBuffer(const egl::Config *configuration,
+ EGLenum buftype,
+ EGLClientBuffer clientBuffer,
+ const egl::AttributeMap &attribs) const;
+ virtual egl::Error validateImageClientBuffer(const gl::Context *context,
+ EGLenum target,
+ EGLClientBuffer clientBuffer,
+ const egl::AttributeMap &attribs) const;
+ virtual egl::Error validatePixmap(const egl::Config *config,
+ EGLNativePixmapType pixmap,
+ const egl::AttributeMap &attributes) const;
+
+ virtual std::string getRendererDescription() = 0;
+ virtual std::string getVendorString() = 0;
+ virtual std::string getVersionString(bool includeFullVersion) = 0;
+
+ virtual DeviceImpl *createDevice();
+
+ virtual egl::Error waitClient(const gl::Context *context) = 0;
+ virtual egl::Error waitNative(const gl::Context *context, EGLint engine) = 0;
+ virtual gl::Version getMaxSupportedESVersion() const = 0;
+ virtual gl::Version getMaxConformantESVersion() const = 0;
+ // If desktop GL is not supported in any capacity for a given backend, this returns None.
+ virtual Optional<gl::Version> getMaxSupportedDesktopVersion() const = 0;
+ const egl::Caps &getCaps() const;
+
+ virtual void setBlobCacheFuncs(EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get) {}
+
+ const egl::DisplayExtensions &getExtensions() const;
+
+ void setBlobCache(egl::BlobCache *blobCache) { mBlobCache = blobCache; }
+ egl::BlobCache *getBlobCache() const { return mBlobCache; }
+
+ virtual void initializeFrontendFeatures(angle::FrontendFeatures *features) const {}
+
+ virtual void populateFeatureList(angle::FeatureList *features) = 0;
+
+ const egl::DisplayState &getState() const { return mState; }
+
+ virtual egl::Error handleGPUSwitch();
+ virtual egl::Error forceGPUSwitch(EGLint gpuIDHigh, EGLint gpuIDLow);
+
+ virtual bool isX11() const;
+ virtual bool isWayland() const;
+ virtual bool isGBM() const;
+
+ virtual bool supportsDmaBufFormat(EGLint format) const;
+ virtual egl::Error queryDmaBufFormats(EGLint max_formats, EGLint *formats, EGLint *num_formats);
+ virtual egl::Error queryDmaBufModifiers(EGLint format,
+ EGLint max_modifiers,
+ EGLuint64KHR *modifiers,
+ EGLBoolean *external_only,
+ EGLint *num_modifiers);
+ GLuint getNextSurfaceID() override;
+
+ protected:
+ const egl::DisplayState &mState;
+
+ private:
+ virtual void generateExtensions(egl::DisplayExtensions *outExtensions) const = 0;
+ virtual void generateCaps(egl::Caps *outCaps) const = 0;
+
+ mutable bool mExtensionsInitialized;
+ mutable egl::DisplayExtensions mExtensions;
+
+ mutable bool mCapsInitialized;
+ mutable egl::Caps mCaps;
+
+ egl::BlobCache *mBlobCache;
+ rx::AtomicSerialFactory mNextSurfaceID;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_DISPLAYIMPL_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/EGLImplFactory.h b/gfx/angle/checkout/src/libANGLE/renderer/EGLImplFactory.h
new file mode 100644
index 0000000000..4d5308dc0e
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/EGLImplFactory.h
@@ -0,0 +1,104 @@
+//
+// 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.
+//
+// EGLImplFactory.h:
+// Factory interface for EGL Impl objects.
+//
+
+#ifndef LIBANGLE_RENDERER_EGLIMPLFACTORY_H_
+#define LIBANGLE_RENDERER_EGLIMPLFACTORY_H_
+
+#include "libANGLE/Stream.h"
+
+namespace egl
+{
+class AttributeMap;
+struct Config;
+class ImageSibling;
+struct ImageState;
+struct SurfaceState;
+} // namespace egl
+
+namespace gl
+{
+class Context;
+class ErrorSet;
+class State;
+} // namespace gl
+
+namespace rx
+{
+class ContextImpl;
+class EGLSyncImpl;
+class ImageImpl;
+class ExternalImageSiblingImpl;
+class SurfaceImpl;
+class ShareGroupImpl;
+
+class EGLImplFactory : angle::NonCopyable
+{
+ public:
+ EGLImplFactory() {}
+ virtual ~EGLImplFactory() {}
+
+ virtual SurfaceImpl *createWindowSurface(const egl::SurfaceState &state,
+ EGLNativeWindowType window,
+ const egl::AttributeMap &attribs) = 0;
+ virtual SurfaceImpl *createPbufferSurface(const egl::SurfaceState &state,
+ const egl::AttributeMap &attribs) = 0;
+ virtual SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state,
+ EGLenum buftype,
+ EGLClientBuffer clientBuffer,
+ const egl::AttributeMap &attribs) = 0;
+ virtual SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state,
+ NativePixmapType nativePixmap,
+ const egl::AttributeMap &attribs) = 0;
+
+ virtual ImageImpl *createImage(const egl::ImageState &state,
+ const gl::Context *context,
+ EGLenum target,
+ const egl::AttributeMap &attribs) = 0;
+
+ virtual ContextImpl *createContext(const gl::State &state,
+ gl::ErrorSet *errorSet,
+ const egl::Config *configuration,
+ const gl::Context *shareContext,
+ const egl::AttributeMap &attribs) = 0;
+
+ virtual StreamProducerImpl *createStreamProducerD3DTexture(
+ egl::Stream::ConsumerType consumerType,
+ const egl::AttributeMap &attribs) = 0;
+
+ virtual ExternalImageSiblingImpl *createExternalImageSibling(const gl::Context *context,
+ EGLenum target,
+ EGLClientBuffer buffer,
+ const egl::AttributeMap &attribs);
+
+ virtual EGLSyncImpl *createSync(const egl::AttributeMap &attribs);
+
+ virtual ShareGroupImpl *createShareGroup() = 0;
+
+ virtual GLuint getNextSurfaceID() = 0;
+};
+
+inline ExternalImageSiblingImpl *EGLImplFactory::createExternalImageSibling(
+ const gl::Context *context,
+ EGLenum target,
+ EGLClientBuffer buffer,
+ const egl::AttributeMap &attribs)
+{
+ UNREACHABLE();
+ return nullptr;
+}
+
+inline EGLSyncImpl *EGLImplFactory::createSync(const egl::AttributeMap &attribs)
+{
+ UNREACHABLE();
+ return nullptr;
+}
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_EGLIMPLFACTORY_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/EGLReusableSync.cpp b/gfx/angle/checkout/src/libANGLE/renderer/EGLReusableSync.cpp
new file mode 100644
index 0000000000..8441b028da
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/EGLReusableSync.cpp
@@ -0,0 +1,116 @@
+//
+// Copyright 2020 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.
+//
+
+// EGLReusableSync.cpp: Implements the egl::ReusableSync class.
+
+#include "libANGLE/renderer/EGLReusableSync.h"
+
+#include "libANGLE/Context.h"
+#include "libANGLE/renderer/ContextImpl.h"
+
+namespace rx
+{
+
+ReusableSync::ReusableSync(const egl::AttributeMap &attribs)
+ : EGLSyncImpl(), mStatus(EGL_UNSIGNALED)
+{}
+
+void ReusableSync::onDestroy(const egl::Display *display) {}
+
+ReusableSync::~ReusableSync()
+{
+ // Release any waiting thread.
+ mCondVar.notify_all();
+}
+
+egl::Error ReusableSync::initialize(const egl::Display *display,
+ const gl::Context *context,
+ EGLenum type)
+{
+ return egl::NoError();
+}
+
+egl::Error ReusableSync::clientWait(const egl::Display *display,
+ const gl::Context *context,
+ EGLint flags,
+ EGLTime timeout,
+ EGLint *outResult)
+{
+ if (mStatus == EGL_SIGNALED)
+ {
+ *outResult = EGL_CONDITION_SATISFIED_KHR;
+ return egl::NoError();
+ }
+ if (((flags & EGL_SYNC_FLUSH_COMMANDS_BIT) != 0) && (context != nullptr))
+ {
+ angle::Result result = context->getImplementation()->flush(context);
+ if (result != angle::Result::Continue)
+ {
+ return ResultToEGL(result);
+ }
+ }
+ if (timeout == 0)
+ {
+ *outResult = EGL_TIMEOUT_EXPIRED_KHR;
+ return egl::NoError();
+ }
+
+ using NanoSeconds = std::chrono::duration<int64_t, std::nano>;
+ NanoSeconds duration = (timeout == EGL_FOREVER) ? NanoSeconds::max() : NanoSeconds(timeout);
+ std::cv_status waitStatus = std::cv_status::no_timeout;
+ mMutex.lock();
+ waitStatus = mCondVar.wait_for(mMutex, duration);
+ mMutex.unlock();
+
+ switch (waitStatus)
+ {
+ case std::cv_status::no_timeout: // Signaled.
+ *outResult = EGL_CONDITION_SATISFIED_KHR;
+ break;
+ case std::cv_status::timeout: // Timed-out.
+ *outResult = EGL_TIMEOUT_EXPIRED_KHR;
+ break;
+ default:
+ break;
+ }
+ return egl::NoError();
+}
+
+egl::Error ReusableSync::serverWait(const egl::Display *display,
+ const gl::Context *context,
+ EGLint flags)
+{
+ // Does not support server wait.
+ return egl::EglBadMatch();
+}
+
+egl::Error ReusableSync::signal(const egl::Display *display,
+ const gl::Context *context,
+ EGLint mode)
+{
+ if (mode == EGL_SIGNALED)
+ {
+ if (mStatus == EGL_UNSIGNALED)
+ {
+ // Release all threads.
+ mCondVar.notify_all();
+ }
+ mStatus = EGL_SIGNALED;
+ }
+ else
+ {
+ mStatus = EGL_UNSIGNALED;
+ }
+ return egl::NoError();
+}
+
+egl::Error ReusableSync::getStatus(const egl::Display *display, EGLint *outStatus)
+{
+ *outStatus = mStatus;
+ return egl::NoError();
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/EGLReusableSync.h b/gfx/angle/checkout/src/libANGLE/renderer/EGLReusableSync.h
new file mode 100644
index 0000000000..12c972565d
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/EGLReusableSync.h
@@ -0,0 +1,54 @@
+//
+// Copyright 2020 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.
+//
+
+// EGL_KHR_reusable_sync
+
+#ifndef LIBANGLE_RENDERER_EGLREUSABLESYNC_H_
+#define LIBANGLE_RENDERER_EGLREUSABLESYNC_H_
+
+#include "libANGLE/AttributeMap.h"
+#include "libANGLE/renderer/EGLSyncImpl.h"
+
+#include "common/angleutils.h"
+
+#include <condition_variable>
+
+namespace rx
+{
+
+class ReusableSync final : public EGLSyncImpl
+{
+ public:
+ ReusableSync(const egl::AttributeMap &attribs);
+ ~ReusableSync() override;
+
+ void onDestroy(const egl::Display *display) override;
+
+ egl::Error initialize(const egl::Display *display,
+ const gl::Context *context,
+ EGLenum type) override;
+ egl::Error clientWait(const egl::Display *display,
+ const gl::Context *context,
+ EGLint flags,
+ EGLTime timeout,
+ EGLint *outResult) override;
+ egl::Error serverWait(const egl::Display *display,
+ const gl::Context *context,
+ EGLint flags) override;
+ egl::Error signal(const egl::Display *display,
+ const gl::Context *context,
+ EGLint mode) override;
+ egl::Error getStatus(const egl::Display *display, EGLint *outStatus) override;
+
+ private:
+ EGLint mStatus;
+ std::condition_variable mCondVar;
+ std::unique_lock<std::mutex> mMutex;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_EGLREUSABLESYNC_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/EGLSyncImpl.cpp b/gfx/angle/checkout/src/libANGLE/renderer/EGLSyncImpl.cpp
new file mode 100644
index 0000000000..a62edce539
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/EGLSyncImpl.cpp
@@ -0,0 +1,37 @@
+//
+// Copyright 2020 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.
+//
+
+// EGLSyncImpl.cpp: Implements the rx::EGLSyncImpl class.
+
+#include "libANGLE/renderer/EGLReusableSync.h"
+
+#include "angle_gl.h"
+
+#include "common/utilities.h"
+
+namespace rx
+{
+
+egl::Error EGLSyncImpl::signal(const egl::Display *display, const gl::Context *context, EGLint mode)
+{
+ UNREACHABLE();
+ return egl::EglBadMatch();
+}
+
+egl::Error EGLSyncImpl::copyMetalSharedEventANGLE(const egl::Display *display,
+ void **eventOut) const
+{
+ UNREACHABLE();
+ return egl::EglBadMatch();
+}
+
+egl::Error EGLSyncImpl::dupNativeFenceFD(const egl::Display *display, EGLint *fdOut) const
+{
+ UNREACHABLE();
+ return egl::EglBadMatch();
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/EGLSyncImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/EGLSyncImpl.h
new file mode 100644
index 0000000000..1dee6d315b
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/EGLSyncImpl.h
@@ -0,0 +1,57 @@
+//
+// Copyright 2019 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.
+//
+
+// EGLSyncImpl.h: Defines the rx::EGLSyncImpl class.
+
+#ifndef LIBANGLE_RENDERER_EGLSYNCIMPL_H_
+#define LIBANGLE_RENDERER_EGLSYNCIMPL_H_
+
+#include "libANGLE/Error.h"
+
+#include "common/angleutils.h"
+
+#include "angle_gl.h"
+
+namespace egl
+{
+class Display;
+} // namespace egl
+
+namespace gl
+{
+class Context;
+} // namespace gl
+
+namespace rx
+{
+class EGLSyncImpl : angle::NonCopyable
+{
+ public:
+ EGLSyncImpl() {}
+ virtual ~EGLSyncImpl() {}
+
+ virtual void onDestroy(const egl::Display *display) {}
+
+ virtual egl::Error initialize(const egl::Display *display,
+ const gl::Context *context,
+ EGLenum type) = 0;
+ virtual egl::Error clientWait(const egl::Display *display,
+ const gl::Context *context,
+ EGLint flags,
+ EGLTime timeout,
+ EGLint *outResult) = 0;
+ virtual egl::Error serverWait(const egl::Display *display,
+ const gl::Context *context,
+ EGLint flags) = 0;
+ virtual egl::Error signal(const egl::Display *display, const gl::Context *context, EGLint mode);
+ virtual egl::Error getStatus(const egl::Display *display, EGLint *outStatus) = 0;
+ virtual egl::Error copyMetalSharedEventANGLE(const egl::Display *display,
+ void **outEvent) const;
+ virtual egl::Error dupNativeFenceFD(const egl::Display *display, EGLint *fdOut) const;
+};
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_EGLSYNCIMPL_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/FenceNVImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/FenceNVImpl.h
new file mode 100644
index 0000000000..99c002ad2e
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/FenceNVImpl.h
@@ -0,0 +1,38 @@
+//
+// 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.
+//
+
+// FenceNVImpl.h: Defines the rx::FenceNVImpl class.
+
+#ifndef LIBANGLE_RENDERER_FENCENVIMPL_H_
+#define LIBANGLE_RENDERER_FENCENVIMPL_H_
+
+#include "libANGLE/Error.h"
+
+#include "common/angleutils.h"
+
+#include "angle_gl.h"
+
+namespace gl
+{
+class Context;
+} // namespace gl
+
+namespace rx
+{
+class FenceNVImpl : angle::NonCopyable
+{
+ public:
+ FenceNVImpl() {}
+ virtual ~FenceNVImpl() {}
+
+ virtual void onDestroy(const gl::Context *context) = 0;
+ virtual angle::Result set(const gl::Context *context, GLenum condition) = 0;
+ virtual angle::Result test(const gl::Context *context, GLboolean *outFinished) = 0;
+ virtual angle::Result finish(const gl::Context *context) = 0;
+};
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_FENCENVIMPL_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/Format.h b/gfx/angle/checkout/src/libANGLE/renderer/Format.h
new file mode 100644
index 0000000000..1974381f53
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/Format.h
@@ -0,0 +1,238 @@
+//
+// 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/renderer/FormatID_autogen.h"
+#include "libANGLE/renderer/renderer_utils.h"
+
+namespace angle
+{
+enum class FormatID;
+
+extern const Format gFormatInfoTable[];
+
+struct Format final : private angle::NonCopyable
+{
+ inline constexpr Format(FormatID id,
+ GLenum glFormat,
+ GLenum fboFormat,
+ rx::MipGenerationFunction mipGen,
+ const rx::FastCopyFunctionMap &fastCopyFunctions,
+ rx::PixelReadFunction colorRead,
+ rx::PixelWriteFunction colorWrite,
+ GLenum componentType,
+ GLuint redBits,
+ GLuint greenBits,
+ GLuint blueBits,
+ GLuint alphaBits,
+ GLuint luminanceBits,
+ GLuint depthBits,
+ GLuint stencilBits,
+ GLuint pixelBytes,
+ GLuint componentAlignmentMask,
+ bool isBlock,
+ bool isFixed,
+ bool isScaled,
+ bool isSRGB,
+ bool isYUV,
+ gl::VertexAttribType vertexAttribType);
+
+ static const Format &Get(FormatID id) { return gFormatInfoTable[static_cast<int>(id)]; }
+
+ static FormatID InternalFormatToID(GLenum internalFormat);
+
+ constexpr bool hasDepthOrStencilBits() const;
+ constexpr bool isLUMA() const;
+ constexpr bool isBGRA() const;
+
+ constexpr bool isSint() const;
+ constexpr bool isUint() const;
+ constexpr bool isSnorm() const;
+ constexpr bool isUnorm() const;
+ constexpr bool isFloat() const;
+ constexpr bool isVertexTypeHalfFloat() const;
+
+ constexpr bool isInt() const { return isSint() || isUint(); }
+ constexpr bool isNorm() const { return isSnorm() || isUnorm(); }
+ constexpr bool isPureInt() const { return isInt() && !isScaled; }
+
+ bool operator==(const Format &other) const { return this->id == other.id; }
+
+ FormatID 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::PixelReadFunction pixelReadFunction;
+ rx::PixelWriteFunction pixelWriteFunction;
+
+ // A map from a gl::FormatType to a fast pixel copy function for this format.
+ const rx::FastCopyFunctionMap &fastCopyFunctions;
+
+ GLenum componentType;
+
+ GLuint redBits;
+ GLuint greenBits;
+ GLuint blueBits;
+ GLuint alphaBits;
+ GLuint luminanceBits;
+ GLuint depthBits;
+ GLuint stencilBits;
+
+ GLuint pixelBytes;
+
+ // For 1-byte components, is 0x0. For 2-byte, is 0x1. For 4-byte, is 0x3. For all others,
+ // MAX_UINT.
+ GLuint componentAlignmentMask;
+
+ GLuint channelCount;
+
+ bool isBlock;
+ bool isFixed;
+ bool isScaled;
+ bool isSRGB;
+ bool isYUV;
+
+ // For vertex formats only. Returns the "type" value for glVertexAttribPointer etc.
+ gl::VertexAttribType vertexAttribType;
+};
+
+constexpr GLuint GetChannelCount(GLuint redBits,
+ GLuint greenBits,
+ GLuint blueBits,
+ GLuint alphaBits,
+ GLuint luminanceBits,
+ GLuint depthBits,
+ GLuint stencilBits)
+{
+ return (redBits > 0 ? 1 : 0) + (greenBits > 0 ? 1 : 0) + (blueBits > 0 ? 1 : 0) +
+ (alphaBits > 0 ? 1 : 0) + (luminanceBits > 0 ? 1 : 0) + (depthBits > 0 ? 1 : 0) +
+ (stencilBits > 0 ? 1 : 0);
+}
+
+constexpr Format::Format(FormatID id,
+ GLenum glFormat,
+ GLenum fboFormat,
+ rx::MipGenerationFunction mipGen,
+ const rx::FastCopyFunctionMap &fastCopyFunctions,
+ rx::PixelReadFunction colorRead,
+ rx::PixelWriteFunction colorWrite,
+ GLenum componentType,
+ GLuint redBits,
+ GLuint greenBits,
+ GLuint blueBits,
+ GLuint alphaBits,
+ GLuint luminanceBits,
+ GLuint depthBits,
+ GLuint stencilBits,
+ GLuint pixelBytes,
+ GLuint componentAlignmentMask,
+ bool isBlock,
+ bool isFixed,
+ bool isScaled,
+ bool isSRGB,
+ bool isYUV,
+ gl::VertexAttribType vertexAttribType)
+ : id(id),
+ glInternalFormat(glFormat),
+ fboImplementationInternalFormat(fboFormat),
+ mipGenerationFunction(mipGen),
+ pixelReadFunction(colorRead),
+ pixelWriteFunction(colorWrite),
+ fastCopyFunctions(fastCopyFunctions),
+ componentType(componentType),
+ redBits(redBits),
+ greenBits(greenBits),
+ blueBits(blueBits),
+ alphaBits(alphaBits),
+ luminanceBits(luminanceBits),
+ depthBits(depthBits),
+ stencilBits(stencilBits),
+ pixelBytes(pixelBytes),
+ componentAlignmentMask(componentAlignmentMask),
+ channelCount(GetChannelCount(redBits,
+ greenBits,
+ blueBits,
+ alphaBits,
+ luminanceBits,
+ depthBits,
+ stencilBits)),
+ isBlock(isBlock),
+ isFixed(isFixed),
+ isScaled(isScaled),
+ isSRGB(isSRGB),
+ isYUV(isYUV),
+ vertexAttribType(vertexAttribType)
+{}
+
+constexpr bool Format::hasDepthOrStencilBits() const
+{
+ return depthBits > 0 || stencilBits > 0;
+}
+
+constexpr bool Format::isLUMA() const
+{
+ // There's no format with G or B without R
+ ASSERT(redBits > 0 || (greenBits == 0 && blueBits == 0));
+ return redBits == 0 && (luminanceBits > 0 || alphaBits > 0);
+}
+
+constexpr bool Format::isBGRA() const
+{
+ return id == FormatID::B8G8R8A8_UNORM || id == FormatID::B8G8R8A8_UNORM_SRGB ||
+ id == FormatID::B8G8R8A8_TYPELESS || id == FormatID::B8G8R8A8_TYPELESS_SRGB;
+}
+
+constexpr bool Format::isSint() const
+{
+ return componentType == GL_INT;
+}
+
+constexpr bool Format::isUint() const
+{
+ return componentType == GL_UNSIGNED_INT;
+}
+
+constexpr bool Format::isSnorm() const
+{
+ return componentType == GL_SIGNED_NORMALIZED;
+}
+
+constexpr bool Format::isUnorm() const
+{
+ return componentType == GL_UNSIGNED_NORMALIZED;
+}
+
+constexpr bool Format::isFloat() const
+{
+ return componentType == GL_FLOAT;
+}
+
+constexpr bool Format::isVertexTypeHalfFloat() const
+{
+ return vertexAttribType == gl::VertexAttribType::HalfFloat;
+}
+
+template <typename T>
+using FormatMap = PackedEnumMap<FormatID, T, kNumANGLEFormats>;
+
+} // namespace angle
+
+#endif // LIBANGLE_RENDERER_FORMAT_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/FormatID_autogen.h b/gfx/angle/checkout/src/libANGLE/renderer/FormatID_autogen.h
new file mode 100644
index 0000000000..1e6ded8001
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/FormatID_autogen.h
@@ -0,0 +1,264 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_angle_format_table.py using data from angle_format_data.json
+//
+// Copyright 2020 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.
+
+#ifndef LIBANGLE_RENDERER_FORMATID_H_
+#define LIBANGLE_RENDERER_FORMATID_H_
+
+#include <cstdint>
+
+namespace angle
+{
+
+enum class FormatID
+{
+ NONE,
+ D16_UNORM,
+ D24_UNORM_S8_UINT,
+ D24_UNORM_X8_UINT,
+ D32_FLOAT,
+ D32_FLOAT_S8X24_UINT,
+ D32_UNORM,
+ S8_UINT,
+ A16_FLOAT,
+ A1R5G5B5_UNORM,
+ A2R10G10B10_SINT_VERTEX,
+ A2R10G10B10_SNORM_VERTEX,
+ A2R10G10B10_SSCALED_VERTEX,
+ A2R10G10B10_UINT_VERTEX,
+ A2R10G10B10_UNORM_VERTEX,
+ A2R10G10B10_USCALED_VERTEX,
+ 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_3x3x3_UNORM_BLOCK,
+ ASTC_3x3x3_UNORM_SRGB_BLOCK,
+ ASTC_4x3x3_UNORM_BLOCK,
+ ASTC_4x3x3_UNORM_SRGB_BLOCK,
+ ASTC_4x4_SRGB_BLOCK,
+ ASTC_4x4_UNORM_BLOCK,
+ ASTC_4x4x3_UNORM_BLOCK,
+ ASTC_4x4x3_UNORM_SRGB_BLOCK,
+ ASTC_4x4x4_UNORM_BLOCK,
+ ASTC_4x4x4_UNORM_SRGB_BLOCK,
+ ASTC_5x4_SRGB_BLOCK,
+ ASTC_5x4_UNORM_BLOCK,
+ ASTC_5x4x4_UNORM_BLOCK,
+ ASTC_5x4x4_UNORM_SRGB_BLOCK,
+ ASTC_5x5_SRGB_BLOCK,
+ ASTC_5x5_UNORM_BLOCK,
+ ASTC_5x5x4_UNORM_BLOCK,
+ ASTC_5x5x4_UNORM_SRGB_BLOCK,
+ ASTC_5x5x5_UNORM_BLOCK,
+ ASTC_5x5x5_UNORM_SRGB_BLOCK,
+ ASTC_6x5_SRGB_BLOCK,
+ ASTC_6x5_UNORM_BLOCK,
+ ASTC_6x5x5_UNORM_BLOCK,
+ ASTC_6x5x5_UNORM_SRGB_BLOCK,
+ ASTC_6x6_SRGB_BLOCK,
+ ASTC_6x6_UNORM_BLOCK,
+ ASTC_6x6x5_UNORM_BLOCK,
+ ASTC_6x6x5_UNORM_SRGB_BLOCK,
+ ASTC_6x6x6_UNORM_BLOCK,
+ ASTC_6x6x6_UNORM_SRGB_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,
+ B10G10R10A2_UNORM,
+ B4G4R4A4_UNORM,
+ B5G5R5A1_UNORM,
+ B5G6R5_UNORM,
+ B8G8R8A8_TYPELESS,
+ B8G8R8A8_TYPELESS_SRGB,
+ B8G8R8A8_UNORM,
+ B8G8R8A8_UNORM_SRGB,
+ B8G8R8X8_UNORM,
+ BC1_RGBA_UNORM_BLOCK,
+ BC1_RGBA_UNORM_SRGB_BLOCK,
+ BC1_RGB_UNORM_BLOCK,
+ BC1_RGB_UNORM_SRGB_BLOCK,
+ BC2_RGBA_UNORM_BLOCK,
+ BC2_RGBA_UNORM_SRGB_BLOCK,
+ BC3_RGBA_UNORM_BLOCK,
+ BC3_RGBA_UNORM_SRGB_BLOCK,
+ BC4_RED_SNORM_BLOCK,
+ BC4_RED_UNORM_BLOCK,
+ BC5_RG_SNORM_BLOCK,
+ BC5_RG_UNORM_BLOCK,
+ BC6H_RGB_SFLOAT_BLOCK,
+ BC6H_RGB_UFLOAT_BLOCK,
+ BC7_RGBA_UNORM_BLOCK,
+ BC7_RGBA_UNORM_SRGB_BLOCK,
+ EAC_R11G11_SNORM_BLOCK,
+ EAC_R11G11_UNORM_BLOCK,
+ EAC_R11_SNORM_BLOCK,
+ EAC_R11_UNORM_BLOCK,
+ ETC1_LOSSY_DECODE_R8G8B8_UNORM_BLOCK,
+ ETC1_R8G8B8_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,
+ G8_B8R8_2PLANE_420_UNORM,
+ G8_B8_R8_3PLANE_420_UNORM,
+ L16A16_FLOAT,
+ L16_FLOAT,
+ L32A32_FLOAT,
+ L32_FLOAT,
+ L8A8_UNORM,
+ L8_UNORM,
+ PALETTE4_R4G4B4A4_UNORM,
+ PALETTE4_R5G5B5A1_UNORM,
+ PALETTE4_R5G6B5_UNORM,
+ PALETTE4_R8G8B8A8_UNORM,
+ PALETTE4_R8G8B8_UNORM,
+ PALETTE8_R4G4B4A4_UNORM,
+ PALETTE8_R5G5B5A1_UNORM,
+ PALETTE8_R5G6B5_UNORM,
+ PALETTE8_R8G8B8A8_UNORM,
+ PALETTE8_R8G8B8_UNORM,
+ PVRTC1_RGBA_2BPP_UNORM_BLOCK,
+ PVRTC1_RGBA_2BPP_UNORM_SRGB_BLOCK,
+ PVRTC1_RGBA_4BPP_UNORM_BLOCK,
+ PVRTC1_RGBA_4BPP_UNORM_SRGB_BLOCK,
+ PVRTC1_RGB_2BPP_UNORM_BLOCK,
+ PVRTC1_RGB_2BPP_UNORM_SRGB_BLOCK,
+ PVRTC1_RGB_4BPP_UNORM_BLOCK,
+ PVRTC1_RGB_4BPP_UNORM_SRGB_BLOCK,
+ R10G10B10A2_SINT,
+ R10G10B10A2_SNORM,
+ R10G10B10A2_SSCALED,
+ R10G10B10A2_UINT,
+ R10G10B10A2_UNORM,
+ R10G10B10A2_USCALED,
+ R10G10B10X2_UNORM,
+ R11G11B10_FLOAT,
+ R16G16B16A16_FLOAT,
+ R16G16B16A16_SINT,
+ R16G16B16A16_SNORM,
+ R16G16B16A16_SSCALED,
+ R16G16B16A16_UINT,
+ R16G16B16A16_UNORM,
+ R16G16B16A16_USCALED,
+ R16G16B16_FLOAT,
+ R16G16B16_SINT,
+ R16G16B16_SNORM,
+ R16G16B16_SSCALED,
+ R16G16B16_UINT,
+ R16G16B16_UNORM,
+ R16G16B16_USCALED,
+ R16G16_FLOAT,
+ R16G16_SINT,
+ R16G16_SNORM,
+ R16G16_SSCALED,
+ R16G16_UINT,
+ R16G16_UNORM,
+ R16G16_USCALED,
+ R16_FLOAT,
+ R16_SINT,
+ R16_SNORM,
+ R16_SSCALED,
+ R16_UINT,
+ R16_UNORM,
+ R16_USCALED,
+ R32G32B32A32_FIXED,
+ R32G32B32A32_FLOAT,
+ R32G32B32A32_SINT,
+ R32G32B32A32_SNORM,
+ R32G32B32A32_SSCALED,
+ R32G32B32A32_UINT,
+ R32G32B32A32_UNORM,
+ R32G32B32A32_USCALED,
+ R32G32B32_FIXED,
+ R32G32B32_FLOAT,
+ R32G32B32_SINT,
+ R32G32B32_SNORM,
+ R32G32B32_SSCALED,
+ R32G32B32_UINT,
+ R32G32B32_UNORM,
+ R32G32B32_USCALED,
+ R32G32_FIXED,
+ R32G32_FLOAT,
+ R32G32_SINT,
+ R32G32_SNORM,
+ R32G32_SSCALED,
+ R32G32_UINT,
+ R32G32_UNORM,
+ R32G32_USCALED,
+ R32_FIXED,
+ R32_FLOAT,
+ R32_SINT,
+ R32_SNORM,
+ R32_SSCALED,
+ R32_UINT,
+ R32_UNORM,
+ R32_USCALED,
+ R4G4B4A4_UNORM,
+ R5G5B5A1_UNORM,
+ R5G6B5_UNORM,
+ R8G8B8A8_SINT,
+ R8G8B8A8_SNORM,
+ R8G8B8A8_SSCALED,
+ R8G8B8A8_TYPELESS,
+ R8G8B8A8_TYPELESS_SRGB,
+ R8G8B8A8_UINT,
+ R8G8B8A8_UNORM,
+ R8G8B8A8_UNORM_SRGB,
+ R8G8B8A8_USCALED,
+ R8G8B8X8_UNORM,
+ R8G8B8_SINT,
+ R8G8B8_SNORM,
+ R8G8B8_SSCALED,
+ R8G8B8_UINT,
+ R8G8B8_UNORM,
+ R8G8B8_UNORM_SRGB,
+ R8G8B8_USCALED,
+ R8G8_SINT,
+ R8G8_SNORM,
+ R8G8_SSCALED,
+ R8G8_UINT,
+ R8G8_UNORM,
+ R8G8_UNORM_SRGB,
+ R8G8_USCALED,
+ R8_SINT,
+ R8_SNORM,
+ R8_SSCALED,
+ R8_UINT,
+ R8_UNORM,
+ R8_UNORM_SRGB,
+ R8_USCALED,
+ R9G9B9E5_SHAREDEXP,
+ X2R10G10B10_SINT_VERTEX,
+ X2R10G10B10_SNORM_VERTEX,
+ X2R10G10B10_SSCALED_VERTEX,
+ X2R10G10B10_UINT_VERTEX,
+ X2R10G10B10_UNORM_VERTEX,
+ X2R10G10B10_USCALED_VERTEX
+};
+
+constexpr uint32_t kNumANGLEFormats = 238;
+
+} // namespace angle
+
+#endif // LIBANGLE_RENDERER_FORMATID_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/Format_table_autogen.cpp b/gfx/angle/checkout/src/libANGLE/renderer/Format_table_autogen.cpp
new file mode 100644
index 0000000000..df700ab74f
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/Format_table_autogen.cpp
@@ -0,0 +1,762 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_angle_format_table.py using data from angle_format_data.json
+//
+// Copyright 2020 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 constexpr rx::FastCopyFunctionMap::Entry BGRAEntry = {angle::FormatID::R8G8B8A8_UNORM,
+ CopyBGRA8ToRGBA8};
+static constexpr rx::FastCopyFunctionMap BGRACopyFunctions = {&BGRAEntry, 1};
+static constexpr rx::FastCopyFunctionMap NoCopyFunctions;
+
+const Format gFormatInfoTable[] = {
+ // clang-format off
+ { FormatID::NONE, GL_NONE, GL_NONE, nullptr, NoCopyFunctions, nullptr, nullptr, GL_NONE, 0, 0, 0, 0, 0, 0, 0, 0, 0, false, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::D16_UNORM, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT16, nullptr, NoCopyFunctions, ReadDepthStencil<D16>, WriteDepthStencil<D16>, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 16, 0, 2, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::D24_UNORM_S8_UINT, GL_DEPTH24_STENCIL8, GL_DEPTH24_STENCIL8, nullptr, NoCopyFunctions, ReadDepthStencil<D24S8>, WriteDepthStencil<D24S8>, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 24, 8, 4, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::D24_UNORM_X8_UINT, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT24, nullptr, NoCopyFunctions, ReadDepthStencil<D24X8>, WriteDepthStencil<D24X8>, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 24, 0, 4, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::D32_FLOAT, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT32F, nullptr, NoCopyFunctions, ReadDepthStencil<D32F>, WriteDepthStencil<D32F>, GL_FLOAT, 0, 0, 0, 0, 0, 32, 0, 4, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::Float },
+ { FormatID::D32_FLOAT_S8X24_UINT, GL_DEPTH32F_STENCIL8, GL_DEPTH32F_STENCIL8, nullptr, NoCopyFunctions, ReadDepthStencil<D32FS8X24>, WriteDepthStencil<D32FS8X24>, GL_FLOAT, 0, 0, 0, 0, 0, 32, 8, 8, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::Float },
+ { FormatID::D32_UNORM, GL_DEPTH_COMPONENT32_OES, GL_DEPTH_COMPONENT32_OES, nullptr, NoCopyFunctions, ReadDepthStencil<D32>, WriteDepthStencil<D32>, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 32, 0, 4, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::S8_UINT, GL_STENCIL_INDEX8, GL_STENCIL_INDEX8, nullptr, NoCopyFunctions, ReadDepthStencil<S8>, WriteDepthStencil<S8>, GL_UNSIGNED_INT, 0, 0, 0, 0, 0, 0, 8, 1, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::A16_FLOAT, GL_ALPHA16F_EXT, GL_ALPHA16F_EXT, GenerateMip<A16F>, NoCopyFunctions, ReadColor<A16F, GLfloat>, WriteColor<A16F, GLfloat>, GL_FLOAT, 0, 0, 0, 16, 0, 0, 0, 2, 1, false, false, false, false, false, gl::VertexAttribType::Float },
+ { FormatID::A1R5G5B5_UNORM, GL_A1RGB5_ANGLEX, GL_A1RGB5_ANGLEX, GenerateMip<A1R5G5B5>, NoCopyFunctions, ReadColor<A1R5G5B5, GLfloat>, WriteColor<A1R5G5B5, GLfloat>, GL_UNSIGNED_NORMALIZED, 5, 5, 5, 1, 0, 0, 0, 2, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::A2R10G10B10_SINT_VERTEX, GL_INT_10_10_10_2_OES, GL_INT_10_10_10_2_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_INT, 10, 10, 10, 2, 0, 0, 0, 4, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::Int1010102 },
+ { FormatID::A2R10G10B10_SNORM_VERTEX, GL_A2_RGB10_SNORM_ANGLEX, GL_A2_RGB10_SNORM_ANGLEX, nullptr, NoCopyFunctions, nullptr, nullptr, GL_SIGNED_NORMALIZED, 10, 10, 10, 2, 0, 0, 0, 4, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::Int1010102 },
+ { FormatID::A2R10G10B10_SSCALED_VERTEX, GL_A2_RGB10_SSCALED_ANGLEX, GL_A2_RGB10_SSCALED_ANGLEX, nullptr, NoCopyFunctions, nullptr, nullptr, GL_INT, 10, 10, 10, 2, 0, 0, 0, 4, std::numeric_limits<GLuint>::max(), false, false, true, false, false, gl::VertexAttribType::Int1010102 },
+ { FormatID::A2R10G10B10_UINT_VERTEX, GL_UNSIGNED_INT_10_10_10_2_OES, GL_UNSIGNED_INT_10_10_10_2_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_INT, 10, 10, 10, 2, 0, 0, 0, 4, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::UnsignedInt1010102 },
+ { FormatID::A2R10G10B10_UNORM_VERTEX, GL_A2_RGB10_UNORM_ANGLEX, GL_A2_RGB10_UNORM_ANGLEX, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 10, 10, 10, 2, 0, 0, 0, 4, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::UnsignedInt1010102 },
+ { FormatID::A2R10G10B10_USCALED_VERTEX, GL_A2_RGB10_USCALED_ANGLEX, GL_A2_RGB10_USCALED_ANGLEX, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_INT, 10, 10, 10, 2, 0, 0, 0, 4, std::numeric_limits<GLuint>::max(), false, false, true, false, false, gl::VertexAttribType::UnsignedInt1010102 },
+ { FormatID::A32_FLOAT, GL_ALPHA32F_EXT, GL_ALPHA32F_EXT, GenerateMip<A32F>, NoCopyFunctions, ReadColor<A32F, GLfloat>, WriteColor<A32F, GLfloat>, GL_FLOAT, 0, 0, 0, 32, 0, 0, 0, 4, 3, false, false, false, false, false, gl::VertexAttribType::Float },
+ { FormatID::A8_UNORM, GL_ALPHA8_EXT, GL_ALPHA8_EXT, GenerateMip<A8>, NoCopyFunctions, ReadColor<A8, GLfloat>, WriteColor<A8, GLfloat>, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 8, 0, 0, 0, 1, 0, false, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_10x10_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_10x10_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_10x10_KHR, GL_COMPRESSED_RGBA_ASTC_10x10_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_10x5_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_10x5_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_10x5_KHR, GL_COMPRESSED_RGBA_ASTC_10x5_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_10x6_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_10x6_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_10x6_KHR, GL_COMPRESSED_RGBA_ASTC_10x6_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_10x8_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_10x8_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_10x8_KHR, GL_COMPRESSED_RGBA_ASTC_10x8_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_12x10_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_12x10_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_12x10_KHR, GL_COMPRESSED_RGBA_ASTC_12x10_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_12x12_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_12x12_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_12x12_KHR, GL_COMPRESSED_RGBA_ASTC_12x12_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_3x3x3_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_3x3x3_OES, GL_COMPRESSED_RGBA_ASTC_3x3x3_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_3x3x3_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_4x3x3_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_4x3x3_OES, GL_COMPRESSED_RGBA_ASTC_4x3x3_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_4x3x3_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_4x4_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_4x4_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_4x4_KHR, GL_COMPRESSED_RGBA_ASTC_4x4_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_4x4x3_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_4x4x3_OES, GL_COMPRESSED_RGBA_ASTC_4x4x3_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_4x4x3_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_4x4x4_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_4x4x4_OES, GL_COMPRESSED_RGBA_ASTC_4x4x4_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_4x4x4_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_5x4_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_5x4_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_5x4_KHR, GL_COMPRESSED_RGBA_ASTC_5x4_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_5x4x4_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_5x4x4_OES, GL_COMPRESSED_RGBA_ASTC_5x4x4_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_5x4x4_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_5x5_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_5x5_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_5x5_KHR, GL_COMPRESSED_RGBA_ASTC_5x5_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_5x5x4_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_5x5x4_OES, GL_COMPRESSED_RGBA_ASTC_5x5x4_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_5x5x4_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_5x5x5_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_5x5x5_OES, GL_COMPRESSED_RGBA_ASTC_5x5x5_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_5x5x5_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_6x5_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_6x5_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_6x5_KHR, GL_COMPRESSED_RGBA_ASTC_6x5_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_6x5x5_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_6x5x5_OES, GL_COMPRESSED_RGBA_ASTC_6x5x5_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_6x5x5_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_6x6_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_6x6_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_6x6_KHR, GL_COMPRESSED_RGBA_ASTC_6x6_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_6x6x5_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_6x6x5_OES, GL_COMPRESSED_RGBA_ASTC_6x6x5_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_6x6x5_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_6x6x6_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_6x6x6_OES, GL_COMPRESSED_RGBA_ASTC_6x6x6_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_6x6x6_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_8x5_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_8x5_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_8x5_KHR, GL_COMPRESSED_RGBA_ASTC_8x5_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_8x6_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_8x6_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_8x6_KHR, GL_COMPRESSED_RGBA_ASTC_8x6_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_8x8_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ASTC_8x8_UNORM_BLOCK, GL_COMPRESSED_RGBA_ASTC_8x8_KHR, GL_COMPRESSED_RGBA_ASTC_8x8_KHR, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::B10G10R10A2_UNORM, GL_BGR10_A2_ANGLEX, GL_BGR10_A2_ANGLEX, GenerateMip<B10G10R10A2>, NoCopyFunctions, ReadColor<B10G10R10A2, GLfloat>, WriteColor<B10G10R10A2, GLfloat>, GL_UNSIGNED_NORMALIZED, 10, 10, 10, 2, 0, 0, 0, 4, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::UnsignedInt2101010 },
+ { FormatID::B4G4R4A4_UNORM, GL_BGRA4_ANGLEX, GL_RGBA4, GenerateMip<A4R4G4B4>, NoCopyFunctions, ReadColor<A4R4G4B4, GLfloat>, WriteColor<A4R4G4B4, GLfloat>, GL_UNSIGNED_NORMALIZED, 4, 4, 4, 4, 0, 0, 0, 2, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::B5G5R5A1_UNORM, GL_BGR5_A1_ANGLEX, GL_RGB5_A1, GenerateMip<A1R5G5B5>, NoCopyFunctions, ReadColor<A1R5G5B5, GLfloat>, WriteColor<A1R5G5B5, GLfloat>, GL_UNSIGNED_NORMALIZED, 5, 5, 5, 1, 0, 0, 0, 2, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::B5G6R5_UNORM, GL_BGR565_ANGLEX, GL_RGB565, GenerateMip<B5G6R5>, NoCopyFunctions, ReadColor<B5G6R5, GLfloat>, WriteColor<B5G6R5, GLfloat>, GL_UNSIGNED_NORMALIZED, 5, 6, 5, 0, 0, 0, 0, 2, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::B8G8R8A8_TYPELESS, GL_BGRA8_EXT, GL_BGRA8_EXT, GenerateMip<B8G8R8A8>, NoCopyFunctions, ReadColor<B8G8R8A8, GLfloat>, WriteColor<B8G8R8A8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0, 0, 4, 0, false, false, false, false, false, gl::VertexAttribType::UnsignedByte },
+ { FormatID::B8G8R8A8_TYPELESS_SRGB, GL_BGRA8_SRGB_ANGLEX, GL_BGRA8_SRGB_ANGLEX, GenerateMip<B8G8R8A8>, NoCopyFunctions, ReadColor<B8G8R8A8, GLfloat>, WriteColor<B8G8R8A8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0, 0, 4, 0, false, false, false, true, false, gl::VertexAttribType::Byte },
+ { FormatID::B8G8R8A8_UNORM, GL_BGRA8_EXT, GL_BGRA8_EXT, GenerateMip<B8G8R8A8>, BGRACopyFunctions, ReadColor<B8G8R8A8, GLfloat>, WriteColor<B8G8R8A8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0, 0, 4, 0, false, false, false, false, false, gl::VertexAttribType::UnsignedByte },
+ { FormatID::B8G8R8A8_UNORM_SRGB, GL_BGRA8_SRGB_ANGLEX, GL_BGRA8_SRGB_ANGLEX, GenerateMip<B8G8R8A8>, NoCopyFunctions, ReadColor<B8G8R8A8, GLfloat>, WriteColor<B8G8R8A8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0, 0, 4, 0, false, false, false, true, false, gl::VertexAttribType::Byte },
+ { FormatID::B8G8R8X8_UNORM, GL_BGRA8_EXT, GL_BGRA8_EXT, GenerateMip<B8G8R8X8>, NoCopyFunctions, ReadColor<B8G8R8X8, GLfloat>, WriteColor<B8G8R8X8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0, 0, 4, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::UnsignedByte },
+ { FormatID::BC1_RGBA_UNORM_BLOCK, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 8, std::numeric_limits<GLuint>::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::BC1_RGBA_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 8, std::numeric_limits<GLuint>::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::BC1_RGB_UNORM_BLOCK, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 8, std::numeric_limits<GLuint>::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::BC1_RGB_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 8, std::numeric_limits<GLuint>::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::BC2_RGBA_UNORM_BLOCK, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::BC2_RGBA_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::BC3_RGBA_UNORM_BLOCK, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::BC3_RGBA_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::BC4_RED_SNORM_BLOCK, GL_COMPRESSED_SIGNED_RED_RGTC1_EXT, GL_COMPRESSED_SIGNED_RED_RGTC1_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_SIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 8, std::numeric_limits<GLuint>::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::BC4_RED_UNORM_BLOCK, GL_COMPRESSED_RED_RGTC1_EXT, GL_COMPRESSED_RED_RGTC1_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 8, std::numeric_limits<GLuint>::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::BC5_RG_SNORM_BLOCK, GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT, GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_SIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::BC5_RG_UNORM_BLOCK, GL_COMPRESSED_RED_GREEN_RGTC2_EXT, GL_COMPRESSED_RED_GREEN_RGTC2_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::BC6H_RGB_SFLOAT_BLOCK, GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT, GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_FLOAT, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::BC6H_RGB_UFLOAT_BLOCK, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_FLOAT, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::BC7_RGBA_UNORM_BLOCK, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::BC7_RGBA_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT, GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 16, std::numeric_limits<GLuint>::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::EAC_R11G11_SNORM_BLOCK, GL_COMPRESSED_SIGNED_RG11_EAC, GL_COMPRESSED_SIGNED_RG11_EAC, nullptr, NoCopyFunctions, nullptr, nullptr, GL_SIGNED_NORMALIZED, 11, 11, 0, 0, 0, 0, 0, 16, 0, true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::EAC_R11G11_UNORM_BLOCK, GL_COMPRESSED_RG11_EAC, GL_COMPRESSED_RG11_EAC, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 11, 11, 0, 0, 0, 0, 0, 16, 0, true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::EAC_R11_SNORM_BLOCK, GL_COMPRESSED_SIGNED_R11_EAC, GL_COMPRESSED_SIGNED_R11_EAC, nullptr, NoCopyFunctions, nullptr, nullptr, GL_SIGNED_NORMALIZED, 11, 0, 0, 0, 0, 0, 0, 8, 0, true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::EAC_R11_UNORM_BLOCK, GL_COMPRESSED_R11_EAC, GL_COMPRESSED_R11_EAC, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 11, 0, 0, 0, 0, 0, 0, 8, 0, true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::ETC1_LOSSY_DECODE_R8G8B8_UNORM_BLOCK, GL_ETC1_RGB8_LOSSY_DECODE_ANGLE, GL_ETC1_RGB8_LOSSY_DECODE_ANGLE, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0, 0, 8, 0, true, false, false, false, false, gl::VertexAttribType::UnsignedByte },
+ { FormatID::ETC1_R8G8B8_UNORM_BLOCK, GL_ETC1_RGB8_OES, GL_ETC1_RGB8_OES, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0, 0, 8, 0, true, false, false, false, false, gl::VertexAttribType::UnsignedByte },
+ { FormatID::ETC2_R8G8B8A1_SRGB_BLOCK, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 1, 0, 0, 0, 8, std::numeric_limits<GLuint>::max(), true, false, false, true, false, gl::VertexAttribType::Byte },
+ { FormatID::ETC2_R8G8B8A1_UNORM_BLOCK, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 1, 0, 0, 0, 8, std::numeric_limits<GLuint>::max(), true, false, false, false, false, gl::VertexAttribType::UnsignedByte },
+ { FormatID::ETC2_R8G8B8A8_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0, 0, 16, 0, true, false, false, true, false, gl::VertexAttribType::Byte },
+ { FormatID::ETC2_R8G8B8A8_UNORM_BLOCK, GL_COMPRESSED_RGBA8_ETC2_EAC, GL_COMPRESSED_RGBA8_ETC2_EAC, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0, 0, 16, 0, true, false, false, false, false, gl::VertexAttribType::UnsignedByte },
+ { FormatID::ETC2_R8G8B8_SRGB_BLOCK, GL_COMPRESSED_SRGB8_ETC2, GL_COMPRESSED_SRGB8_ETC2, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0, 0, 8, 0, true, false, false, true, false, gl::VertexAttribType::Byte },
+ { FormatID::ETC2_R8G8B8_UNORM_BLOCK, GL_COMPRESSED_RGB8_ETC2, GL_COMPRESSED_RGB8_ETC2, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0, 0, 8, 0, true, false, false, false, false, gl::VertexAttribType::UnsignedByte },
+ { FormatID::G8_B8R8_2PLANE_420_UNORM, GL_G8_B8R8_2PLANE_420_UNORM_ANGLE, GL_G8_B8R8_2PLANE_420_UNORM_ANGLE, GenerateMip<R8G8B8>, NoCopyFunctions, ReadColor<R8G8B8, GLfloat>, WriteColor<R8G8B8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0, 0, 3, 0, false, false, false, false, true, gl::VertexAttribType::UnsignedByte },
+ { FormatID::G8_B8_R8_3PLANE_420_UNORM, GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE, GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE, GenerateMip<R8G8B8>, NoCopyFunctions, ReadColor<R8G8B8, GLfloat>, WriteColor<R8G8B8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0, 0, 3, 0, false, false, false, false, true, gl::VertexAttribType::UnsignedByte },
+ { FormatID::L16A16_FLOAT, GL_LUMINANCE_ALPHA16F_EXT, GL_LUMINANCE_ALPHA16F_EXT, GenerateMip<L16A16F>, NoCopyFunctions, ReadColor<L16A16F, GLfloat>, WriteColor<L16A16F, GLfloat>, GL_FLOAT, 0, 0, 0, 16, 16, 0, 0, 4, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::Float },
+ { FormatID::L16_FLOAT, GL_LUMINANCE16F_EXT, GL_LUMINANCE16F_EXT, GenerateMip<L16F>, NoCopyFunctions, ReadColor<L16F, GLfloat>, WriteColor<L16F, GLfloat>, GL_FLOAT, 0, 0, 0, 0, 16, 0, 0, 2, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::Float },
+ { FormatID::L32A32_FLOAT, GL_LUMINANCE_ALPHA32F_EXT, GL_LUMINANCE_ALPHA32F_EXT, GenerateMip<L32A32F>, NoCopyFunctions, ReadColor<L32A32F, GLfloat>, WriteColor<L32A32F, GLfloat>, GL_FLOAT, 0, 0, 0, 32, 32, 0, 0, 8, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::Float },
+ { FormatID::L32_FLOAT, GL_LUMINANCE32F_EXT, GL_LUMINANCE32F_EXT, GenerateMip<L32F>, NoCopyFunctions, ReadColor<L32F, GLfloat>, WriteColor<L32F, GLfloat>, GL_FLOAT, 0, 0, 0, 0, 32, 0, 0, 4, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::Float },
+ { FormatID::L8A8_UNORM, GL_LUMINANCE8_ALPHA8_EXT, GL_LUMINANCE8_ALPHA8_EXT, GenerateMip<L8A8>, NoCopyFunctions, ReadColor<L8A8, GLfloat>, WriteColor<L8A8, GLfloat>, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 8, 8, 0, 0, 2, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::L8_UNORM, GL_LUMINANCE8_EXT, GL_LUMINANCE8_EXT, GenerateMip<L8>, NoCopyFunctions, ReadColor<L8, GLfloat>, WriteColor<L8, GLfloat>, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 8, 0, 0, 1, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::PALETTE4_R4G4B4A4_UNORM, GL_PALETTE4_RGBA4_OES, GL_PALETTE4_RGBA4_OES, GenerateMip<R4G4B4A4>, NoCopyFunctions, ReadColor<R4G4B4A4, GLfloat>, WriteColor<R4G4B4A4, GLfloat>, GL_UNSIGNED_NORMALIZED, 4, 4, 4, 4, 0, 0, 0, 3, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::PALETTE4_R5G5B5A1_UNORM, GL_PALETTE4_RGB5_A1_OES, GL_PALETTE4_RGB5_A1_OES, GenerateMip<R5G5B5A1>, NoCopyFunctions, ReadColor<R5G5B5A1, GLfloat>, WriteColor<R5G5B5A1, GLfloat>, GL_UNSIGNED_NORMALIZED, 5, 5, 5, 1, 0, 0, 0, 3, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::PALETTE4_R5G6B5_UNORM, GL_PALETTE4_R5_G6_B5_OES, GL_PALETTE4_R5_G6_B5_OES, GenerateMip<R5G6B5>, NoCopyFunctions, ReadColor<R5G6B5, GLfloat>, WriteColor<R5G6B5, GLfloat>, GL_UNSIGNED_NORMALIZED, 5, 6, 5, 0, 0, 0, 0, 3, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::PALETTE4_R8G8B8A8_UNORM, GL_PALETTE4_RGBA8_OES, GL_PALETTE4_RGBA8_OES, GenerateMip<R8G8B8A8>, NoCopyFunctions, ReadColor<R8G8B8A8, GLfloat>, WriteColor<R8G8B8A8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0, 0, 5, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::UnsignedByte },
+ { FormatID::PALETTE4_R8G8B8_UNORM, GL_PALETTE4_RGB8_OES, GL_PALETTE4_RGB8_OES, GenerateMip<R8G8B8>, NoCopyFunctions, ReadColor<R8G8B8, GLfloat>, WriteColor<R8G8B8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0, 0, 4, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::UnsignedByte },
+ { FormatID::PALETTE8_R4G4B4A4_UNORM, GL_PALETTE8_RGBA4_OES, GL_PALETTE8_RGBA4_OES, GenerateMip<R4G4B4A4>, NoCopyFunctions, ReadColor<R4G4B4A4, GLfloat>, WriteColor<R4G4B4A4, GLfloat>, GL_UNSIGNED_NORMALIZED, 4, 4, 4, 4, 0, 0, 0, 3, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::PALETTE8_R5G5B5A1_UNORM, GL_PALETTE8_RGB5_A1_OES, GL_PALETTE8_RGB5_A1_OES, GenerateMip<R5G5B5A1>, NoCopyFunctions, ReadColor<R5G5B5A1, GLfloat>, WriteColor<R5G5B5A1, GLfloat>, GL_UNSIGNED_NORMALIZED, 5, 5, 5, 1, 0, 0, 0, 3, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::PALETTE8_R5G6B5_UNORM, GL_PALETTE8_R5_G6_B5_OES, GL_PALETTE8_R5_G6_B5_OES, GenerateMip<R5G6B5>, NoCopyFunctions, ReadColor<R5G6B5, GLfloat>, WriteColor<R5G6B5, GLfloat>, GL_UNSIGNED_NORMALIZED, 5, 6, 5, 0, 0, 0, 0, 3, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::PALETTE8_R8G8B8A8_UNORM, GL_PALETTE8_RGBA8_OES, GL_PALETTE8_RGBA8_OES, GenerateMip<R8G8B8A8>, NoCopyFunctions, ReadColor<R8G8B8A8, GLfloat>, WriteColor<R8G8B8A8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0, 0, 5, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::UnsignedByte },
+ { FormatID::PALETTE8_R8G8B8_UNORM, GL_PALETTE8_RGB8_OES, GL_PALETTE8_RGB8_OES, GenerateMip<R8G8B8>, NoCopyFunctions, ReadColor<R8G8B8, GLfloat>, WriteColor<R8G8B8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0, 0, 4, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::UnsignedByte },
+ { FormatID::PVRTC1_RGBA_2BPP_UNORM_BLOCK, GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG, GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 8, std::numeric_limits<GLuint>::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::PVRTC1_RGBA_2BPP_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT, GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 8, std::numeric_limits<GLuint>::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::PVRTC1_RGBA_4BPP_UNORM_BLOCK, GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 8, std::numeric_limits<GLuint>::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::PVRTC1_RGBA_4BPP_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT, GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 8, std::numeric_limits<GLuint>::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::PVRTC1_RGB_2BPP_UNORM_BLOCK, GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG, GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 8, std::numeric_limits<GLuint>::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::PVRTC1_RGB_2BPP_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT, GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 8, std::numeric_limits<GLuint>::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::PVRTC1_RGB_4BPP_UNORM_BLOCK, GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG, GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 8, std::numeric_limits<GLuint>::max(), true, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::PVRTC1_RGB_4BPP_UNORM_SRGB_BLOCK, GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT, GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 0, 0, 0, 0, 0, 0, 0, 8, std::numeric_limits<GLuint>::max(), true, false, false, true, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::R10G10B10A2_SINT, GL_RGB10_A2_SINT_ANGLEX, GL_RGB10_A2_SINT_ANGLEX, GenerateMip<R10G10B10A2S>, NoCopyFunctions, ReadColor<R10G10B10A2S, GLint>, WriteColor<R10G10B10A2S, GLint>, GL_INT, 10, 10, 10, 2, 0, 0, 0, 4, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::Int2101010 },
+ { FormatID::R10G10B10A2_SNORM, GL_RGB10_A2_SNORM_ANGLEX, GL_RGB10_A2_SNORM_ANGLEX, GenerateMip<R10G10B10A2S>, NoCopyFunctions, ReadColor<R10G10B10A2S, GLfloat>, WriteColor<R10G10B10A2S, GLfloat>, GL_SIGNED_NORMALIZED, 10, 10, 10, 2, 0, 0, 0, 4, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::Int2101010 },
+ { FormatID::R10G10B10A2_SSCALED, GL_RGB10_A2_SSCALED_ANGLEX, GL_RGB10_A2_SSCALED_ANGLEX, GenerateMip<R10G10B10A2S>, NoCopyFunctions, ReadColor<R10G10B10A2S, GLint>, WriteColor<R10G10B10A2S, GLint>, GL_INT, 10, 10, 10, 2, 0, 0, 0, 4, std::numeric_limits<GLuint>::max(), false, false, true, false, false, gl::VertexAttribType::Int2101010 },
+ { FormatID::R10G10B10A2_UINT, GL_RGB10_A2UI, GL_RGB10_A2UI, GenerateMip<R10G10B10A2>, NoCopyFunctions, ReadColor<R10G10B10A2, GLuint>, WriteColor<R10G10B10A2, GLuint>, GL_UNSIGNED_INT, 10, 10, 10, 2, 0, 0, 0, 4, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::UnsignedInt2101010 },
+ { FormatID::R10G10B10A2_UNORM, GL_RGB10_A2, GL_RGB10_A2, GenerateMip<R10G10B10A2>, NoCopyFunctions, ReadColor<R10G10B10A2, GLfloat>, WriteColor<R10G10B10A2, GLfloat>, GL_UNSIGNED_NORMALIZED, 10, 10, 10, 2, 0, 0, 0, 4, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::UnsignedInt2101010 },
+ { FormatID::R10G10B10A2_USCALED, GL_RGB10_A2_USCALED_ANGLEX, GL_RGB10_A2_USCALED_ANGLEX, GenerateMip<R10G10B10A2>, NoCopyFunctions, ReadColor<R10G10B10A2, GLuint>, WriteColor<R10G10B10A2, GLuint>, GL_UNSIGNED_INT, 10, 10, 10, 2, 0, 0, 0, 4, std::numeric_limits<GLuint>::max(), false, false, true, false, false, gl::VertexAttribType::UnsignedInt2101010 },
+ { FormatID::R10G10B10X2_UNORM, GL_RGB10_UNORM_ANGLEX, GL_RGB10_UNORM_ANGLEX, GenerateMip<R10G10B10X2>, NoCopyFunctions, ReadColor<R10G10B10X2, GLfloat>, WriteColor<R10G10B10X2, GLfloat>, GL_UNSIGNED_NORMALIZED, 10, 10, 10, 0, 0, 0, 0, 4, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::UnsignedInt2101010 },
+ { FormatID::R11G11B10_FLOAT, GL_R11F_G11F_B10F, GL_R11F_G11F_B10F, GenerateMip<R11G11B10F>, NoCopyFunctions, ReadColor<R11G11B10F, GLfloat>, WriteColor<R11G11B10F, GLfloat>, GL_FLOAT, 11, 11, 10, 0, 0, 0, 0, 4, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::Float },
+ { FormatID::R16G16B16A16_FLOAT, GL_RGBA16F, GL_RGBA16F, GenerateMip<R16G16B16A16F>, NoCopyFunctions, ReadColor<R16G16B16A16F, GLfloat>, WriteColor<R16G16B16A16F, GLfloat>, GL_FLOAT, 16, 16, 16, 16, 0, 0, 0, 8, 1, false, false, false, false, false, gl::VertexAttribType::HalfFloat },
+ { FormatID::R16G16B16A16_SINT, GL_RGBA16I, GL_RGBA16I, GenerateMip<R16G16B16A16S>, NoCopyFunctions, ReadColor<R16G16B16A16S, GLint>, WriteColor<R16G16B16A16S, GLint>, GL_INT, 16, 16, 16, 16, 0, 0, 0, 8, 1, false, false, false, false, false, gl::VertexAttribType::Short },
+ { FormatID::R16G16B16A16_SNORM, GL_RGBA16_SNORM_EXT, GL_RGBA16_SNORM_EXT, GenerateMip<R16G16B16A16S>, NoCopyFunctions, ReadColor<R16G16B16A16S, GLfloat>, WriteColor<R16G16B16A16S, GLfloat>, GL_SIGNED_NORMALIZED, 16, 16, 16, 16, 0, 0, 0, 8, 1, false, false, false, false, false, gl::VertexAttribType::Short },
+ { FormatID::R16G16B16A16_SSCALED, GL_RGBA16_SSCALED_ANGLEX, GL_RGBA16_SSCALED_ANGLEX, GenerateMip<R16G16B16A16S>, NoCopyFunctions, ReadColor<R16G16B16A16S, GLint>, WriteColor<R16G16B16A16S, GLint>, GL_INT, 16, 16, 16, 16, 0, 0, 0, 8, 1, false, false, true, false, false, gl::VertexAttribType::Short },
+ { FormatID::R16G16B16A16_UINT, GL_RGBA16UI, GL_RGBA16UI, GenerateMip<R16G16B16A16>, NoCopyFunctions, ReadColor<R16G16B16A16, GLuint>, WriteColor<R16G16B16A16, GLuint>, GL_UNSIGNED_INT, 16, 16, 16, 16, 0, 0, 0, 8, 1, false, false, false, false, false, gl::VertexAttribType::UnsignedShort },
+ { FormatID::R16G16B16A16_UNORM, GL_RGBA16_EXT, GL_RGBA16_EXT, GenerateMip<R16G16B16A16>, NoCopyFunctions, ReadColor<R16G16B16A16, GLfloat>, WriteColor<R16G16B16A16, GLfloat>, GL_UNSIGNED_NORMALIZED, 16, 16, 16, 16, 0, 0, 0, 8, 1, false, false, false, false, false, gl::VertexAttribType::UnsignedShort },
+ { FormatID::R16G16B16A16_USCALED, GL_RGBA16_USCALED_ANGLEX, GL_RGBA16_USCALED_ANGLEX, GenerateMip<R16G16B16A16>, NoCopyFunctions, ReadColor<R16G16B16A16, GLuint>, WriteColor<R16G16B16A16, GLuint>, GL_UNSIGNED_INT, 16, 16, 16, 16, 0, 0, 0, 8, 1, false, false, true, false, false, gl::VertexAttribType::UnsignedShort },
+ { FormatID::R16G16B16_FLOAT, GL_RGB16F, GL_RGB16F, GenerateMip<R16G16B16F>, NoCopyFunctions, ReadColor<R16G16B16F, GLfloat>, WriteColor<R16G16B16F, GLfloat>, GL_FLOAT, 16, 16, 16, 0, 0, 0, 0, 6, 1, false, false, false, false, false, gl::VertexAttribType::HalfFloat },
+ { FormatID::R16G16B16_SINT, GL_RGB16I, GL_RGB16I, GenerateMip<R16G16B16S>, NoCopyFunctions, ReadColor<R16G16B16S, GLint>, WriteColor<R16G16B16S, GLint>, GL_INT, 16, 16, 16, 0, 0, 0, 0, 6, 1, false, false, false, false, false, gl::VertexAttribType::Short },
+ { FormatID::R16G16B16_SNORM, GL_RGB16_SNORM_EXT, GL_RGB16_SNORM_EXT, GenerateMip<R16G16B16S>, NoCopyFunctions, ReadColor<R16G16B16S, GLfloat>, WriteColor<R16G16B16S, GLfloat>, GL_SIGNED_NORMALIZED, 16, 16, 16, 0, 0, 0, 0, 6, 1, false, false, false, false, false, gl::VertexAttribType::Short },
+ { FormatID::R16G16B16_SSCALED, GL_RGB16_SSCALED_ANGLEX, GL_RGB16_SSCALED_ANGLEX, GenerateMip<R16G16B16S>, NoCopyFunctions, ReadColor<R16G16B16S, GLint>, WriteColor<R16G16B16S, GLint>, GL_INT, 16, 16, 16, 0, 0, 0, 0, 6, 1, false, false, true, false, false, gl::VertexAttribType::Short },
+ { FormatID::R16G16B16_UINT, GL_RGB16UI, GL_RGB16UI, GenerateMip<R16G16B16>, NoCopyFunctions, ReadColor<R16G16B16, GLuint>, WriteColor<R16G16B16, GLuint>, GL_UNSIGNED_INT, 16, 16, 16, 0, 0, 0, 0, 6, 1, false, false, false, false, false, gl::VertexAttribType::UnsignedShort },
+ { FormatID::R16G16B16_UNORM, GL_RGB16_EXT, GL_RGB16_EXT, GenerateMip<R16G16B16>, NoCopyFunctions, ReadColor<R16G16B16, GLfloat>, WriteColor<R16G16B16, GLfloat>, GL_UNSIGNED_NORMALIZED, 16, 16, 16, 0, 0, 0, 0, 6, 1, false, false, false, false, false, gl::VertexAttribType::UnsignedShort },
+ { FormatID::R16G16B16_USCALED, GL_RGB16_USCALED_ANGLEX, GL_RGB16_USCALED_ANGLEX, GenerateMip<R16G16B16>, NoCopyFunctions, ReadColor<R16G16B16, GLuint>, WriteColor<R16G16B16, GLuint>, GL_UNSIGNED_INT, 16, 16, 16, 0, 0, 0, 0, 6, 1, false, false, true, false, false, gl::VertexAttribType::UnsignedShort },
+ { FormatID::R16G16_FLOAT, GL_RG16F, GL_RG16F, GenerateMip<R16G16F>, NoCopyFunctions, ReadColor<R16G16F, GLfloat>, WriteColor<R16G16F, GLfloat>, GL_FLOAT, 16, 16, 0, 0, 0, 0, 0, 4, 1, false, false, false, false, false, gl::VertexAttribType::HalfFloat },
+ { FormatID::R16G16_SINT, GL_RG16I, GL_RG16I, GenerateMip<R16G16S>, NoCopyFunctions, ReadColor<R16G16S, GLint>, WriteColor<R16G16S, GLint>, GL_INT, 16, 16, 0, 0, 0, 0, 0, 4, 1, false, false, false, false, false, gl::VertexAttribType::Short },
+ { FormatID::R16G16_SNORM, GL_RG16_SNORM_EXT, GL_RG16_SNORM_EXT, GenerateMip<R16G16S>, NoCopyFunctions, ReadColor<R16G16S, GLfloat>, WriteColor<R16G16S, GLfloat>, GL_SIGNED_NORMALIZED, 16, 16, 0, 0, 0, 0, 0, 4, 1, false, false, false, false, false, gl::VertexAttribType::Short },
+ { FormatID::R16G16_SSCALED, GL_RG16_SSCALED_ANGLEX, GL_RG16_SSCALED_ANGLEX, GenerateMip<R16G16S>, NoCopyFunctions, ReadColor<R16G16S, GLint>, WriteColor<R16G16S, GLint>, GL_INT, 16, 16, 0, 0, 0, 0, 0, 4, 1, false, false, true, false, false, gl::VertexAttribType::Short },
+ { FormatID::R16G16_UINT, GL_RG16UI, GL_RG16UI, GenerateMip<R16G16>, NoCopyFunctions, ReadColor<R16G16, GLuint>, WriteColor<R16G16, GLuint>, GL_UNSIGNED_INT, 16, 16, 0, 0, 0, 0, 0, 4, 1, false, false, false, false, false, gl::VertexAttribType::UnsignedShort },
+ { FormatID::R16G16_UNORM, GL_RG16_EXT, GL_RG16_EXT, GenerateMip<R16G16>, NoCopyFunctions, ReadColor<R16G16, GLfloat>, WriteColor<R16G16, GLfloat>, GL_UNSIGNED_NORMALIZED, 16, 16, 0, 0, 0, 0, 0, 4, 1, false, false, false, false, false, gl::VertexAttribType::UnsignedShort },
+ { FormatID::R16G16_USCALED, GL_RG16_USCALED_ANGLEX, GL_RG16_USCALED_ANGLEX, GenerateMip<R16G16>, NoCopyFunctions, ReadColor<R16G16, GLuint>, WriteColor<R16G16, GLuint>, GL_UNSIGNED_INT, 16, 16, 0, 0, 0, 0, 0, 4, 1, false, false, true, false, false, gl::VertexAttribType::UnsignedShort },
+ { FormatID::R16_FLOAT, GL_R16F, GL_R16F, GenerateMip<R16F>, NoCopyFunctions, ReadColor<R16F, GLfloat>, WriteColor<R16F, GLfloat>, GL_FLOAT, 16, 0, 0, 0, 0, 0, 0, 2, 1, false, false, false, false, false, gl::VertexAttribType::HalfFloat },
+ { FormatID::R16_SINT, GL_R16I, GL_R16I, GenerateMip<R16S>, NoCopyFunctions, ReadColor<R16S, GLint>, WriteColor<R16S, GLint>, GL_INT, 16, 0, 0, 0, 0, 0, 0, 2, 1, false, false, false, false, false, gl::VertexAttribType::Short },
+ { FormatID::R16_SNORM, GL_R16_SNORM_EXT, GL_R16_SNORM_EXT, GenerateMip<R16S>, NoCopyFunctions, ReadColor<R16S, GLfloat>, WriteColor<R16S, GLfloat>, GL_SIGNED_NORMALIZED, 16, 0, 0, 0, 0, 0, 0, 2, 1, false, false, false, false, false, gl::VertexAttribType::Short },
+ { FormatID::R16_SSCALED, GL_R16_SSCALED_ANGLEX, GL_R16_SSCALED_ANGLEX, GenerateMip<R16S>, NoCopyFunctions, ReadColor<R16S, GLint>, WriteColor<R16S, GLint>, GL_INT, 16, 0, 0, 0, 0, 0, 0, 2, 1, false, false, true, false, false, gl::VertexAttribType::Short },
+ { FormatID::R16_UINT, GL_R16UI, GL_R16UI, GenerateMip<R16>, NoCopyFunctions, ReadColor<R16, GLuint>, WriteColor<R16, GLuint>, GL_UNSIGNED_INT, 16, 0, 0, 0, 0, 0, 0, 2, 1, false, false, false, false, false, gl::VertexAttribType::UnsignedShort },
+ { FormatID::R16_UNORM, GL_R16_EXT, GL_R16_EXT, GenerateMip<R16>, NoCopyFunctions, ReadColor<R16, GLfloat>, WriteColor<R16, GLfloat>, GL_UNSIGNED_NORMALIZED, 16, 0, 0, 0, 0, 0, 0, 2, 1, false, false, false, false, false, gl::VertexAttribType::UnsignedShort },
+ { FormatID::R16_USCALED, GL_R16_USCALED_ANGLEX, GL_R16_USCALED_ANGLEX, GenerateMip<R16>, NoCopyFunctions, ReadColor<R16, GLuint>, WriteColor<R16, GLuint>, GL_UNSIGNED_INT, 16, 0, 0, 0, 0, 0, 0, 2, 1, false, false, true, false, false, gl::VertexAttribType::UnsignedShort },
+ { FormatID::R32G32B32A32_FIXED, GL_RGBA32_FIXED_ANGLEX, GL_RGBA32_FIXED_ANGLEX, GenerateMip<R32G32B32A32F>, NoCopyFunctions, ReadColor<R32G32B32A32F, GLfloat>, WriteColor<R32G32B32A32F, GLfloat>, GL_FLOAT, 32, 32, 32, 32, 0, 0, 0, 16, 3, false, true, false, false, false, gl::VertexAttribType::Fixed },
+ { FormatID::R32G32B32A32_FLOAT, GL_RGBA32F, GL_RGBA32F, GenerateMip<R32G32B32A32F>, NoCopyFunctions, ReadColor<R32G32B32A32F, GLfloat>, WriteColor<R32G32B32A32F, GLfloat>, GL_FLOAT, 32, 32, 32, 32, 0, 0, 0, 16, 3, false, false, false, false, false, gl::VertexAttribType::Float },
+ { FormatID::R32G32B32A32_SINT, GL_RGBA32I, GL_RGBA32I, GenerateMip<R32G32B32A32S>, NoCopyFunctions, ReadColor<R32G32B32A32S, GLint>, WriteColor<R32G32B32A32S, GLint>, GL_INT, 32, 32, 32, 32, 0, 0, 0, 16, 3, false, false, false, false, false, gl::VertexAttribType::Int },
+ { FormatID::R32G32B32A32_SNORM, GL_RGBA32_SNORM_ANGLEX, GL_RGBA32_SNORM_ANGLEX, GenerateMip<R32G32B32A32S>, NoCopyFunctions, ReadColor<R32G32B32A32S, GLfloat>, WriteColor<R32G32B32A32S, GLfloat>, GL_SIGNED_NORMALIZED, 32, 32, 32, 32, 0, 0, 0, 16, 3, false, false, false, false, false, gl::VertexAttribType::Int },
+ { FormatID::R32G32B32A32_SSCALED, GL_RGBA32_SSCALED_ANGLEX, GL_RGBA32_SSCALED_ANGLEX, GenerateMip<R32G32B32A32S>, NoCopyFunctions, ReadColor<R32G32B32A32S, GLint>, WriteColor<R32G32B32A32S, GLint>, GL_INT, 32, 32, 32, 32, 0, 0, 0, 16, 3, false, false, true, false, false, gl::VertexAttribType::Int },
+ { FormatID::R32G32B32A32_UINT, GL_RGBA32UI, GL_RGBA32UI, GenerateMip<R32G32B32A32>, NoCopyFunctions, ReadColor<R32G32B32A32, GLuint>, WriteColor<R32G32B32A32, GLuint>, GL_UNSIGNED_INT, 32, 32, 32, 32, 0, 0, 0, 16, 3, false, false, false, false, false, gl::VertexAttribType::UnsignedInt },
+ { FormatID::R32G32B32A32_UNORM, GL_RGBA32_UNORM_ANGLEX, GL_RGBA32_UNORM_ANGLEX, GenerateMip<R32G32B32A32>, NoCopyFunctions, ReadColor<R32G32B32A32, GLfloat>, WriteColor<R32G32B32A32, GLfloat>, GL_UNSIGNED_NORMALIZED, 32, 32, 32, 32, 0, 0, 0, 16, 3, false, false, false, false, false, gl::VertexAttribType::UnsignedInt },
+ { FormatID::R32G32B32A32_USCALED, GL_RGBA32_USCALED_ANGLEX, GL_RGBA32_USCALED_ANGLEX, GenerateMip<R32G32B32A32>, NoCopyFunctions, ReadColor<R32G32B32A32, GLuint>, WriteColor<R32G32B32A32, GLuint>, GL_UNSIGNED_INT, 32, 32, 32, 32, 0, 0, 0, 16, 3, false, false, true, false, false, gl::VertexAttribType::UnsignedInt },
+ { FormatID::R32G32B32_FIXED, GL_RGB32_FIXED_ANGLEX, GL_RGB32_FIXED_ANGLEX, GenerateMip<R32G32B32F>, NoCopyFunctions, ReadColor<R32G32B32F, GLfloat>, WriteColor<R32G32B32F, GLfloat>, GL_FLOAT, 32, 32, 32, 0, 0, 0, 0, 12, 3, false, true, false, false, false, gl::VertexAttribType::Fixed },
+ { FormatID::R32G32B32_FLOAT, GL_RGB32F, GL_RGB32F, GenerateMip<R32G32B32F>, NoCopyFunctions, ReadColor<R32G32B32F, GLfloat>, WriteColor<R32G32B32F, GLfloat>, GL_FLOAT, 32, 32, 32, 0, 0, 0, 0, 12, 3, false, false, false, false, false, gl::VertexAttribType::Float },
+ { FormatID::R32G32B32_SINT, GL_RGB32I, GL_RGB32I, GenerateMip<R32G32B32S>, NoCopyFunctions, ReadColor<R32G32B32S, GLint>, WriteColor<R32G32B32S, GLint>, GL_INT, 32, 32, 32, 0, 0, 0, 0, 12, 3, false, false, false, false, false, gl::VertexAttribType::Int },
+ { FormatID::R32G32B32_SNORM, GL_RGB32_SNORM_ANGLEX, GL_RGB32_SNORM_ANGLEX, GenerateMip<R32G32B32S>, NoCopyFunctions, ReadColor<R32G32B32S, GLfloat>, WriteColor<R32G32B32S, GLfloat>, GL_SIGNED_NORMALIZED, 32, 32, 32, 0, 0, 0, 0, 12, 3, false, false, false, false, false, gl::VertexAttribType::Int },
+ { FormatID::R32G32B32_SSCALED, GL_RGB32_SSCALED_ANGLEX, GL_RGB32_SSCALED_ANGLEX, GenerateMip<R32G32B32S>, NoCopyFunctions, ReadColor<R32G32B32S, GLint>, WriteColor<R32G32B32S, GLint>, GL_INT, 32, 32, 32, 0, 0, 0, 0, 12, 3, false, false, true, false, false, gl::VertexAttribType::Int },
+ { FormatID::R32G32B32_UINT, GL_RGB32UI, GL_RGB32UI, GenerateMip<R32G32B32>, NoCopyFunctions, ReadColor<R32G32B32, GLuint>, WriteColor<R32G32B32, GLuint>, GL_UNSIGNED_INT, 32, 32, 32, 0, 0, 0, 0, 12, 3, false, false, false, false, false, gl::VertexAttribType::UnsignedInt },
+ { FormatID::R32G32B32_UNORM, GL_RGB32_UNORM_ANGLEX, GL_RGB32_UNORM_ANGLEX, GenerateMip<R32G32B32>, NoCopyFunctions, ReadColor<R32G32B32, GLfloat>, WriteColor<R32G32B32, GLfloat>, GL_UNSIGNED_NORMALIZED, 32, 32, 32, 0, 0, 0, 0, 12, 3, false, false, false, false, false, gl::VertexAttribType::UnsignedInt },
+ { FormatID::R32G32B32_USCALED, GL_RGB32_USCALED_ANGLEX, GL_RGB32_USCALED_ANGLEX, GenerateMip<R32G32B32>, NoCopyFunctions, ReadColor<R32G32B32, GLuint>, WriteColor<R32G32B32, GLuint>, GL_UNSIGNED_INT, 32, 32, 32, 0, 0, 0, 0, 12, 3, false, false, true, false, false, gl::VertexAttribType::UnsignedInt },
+ { FormatID::R32G32_FIXED, GL_RG32_FIXED_ANGLEX, GL_RG32_FIXED_ANGLEX, GenerateMip<R32G32F>, NoCopyFunctions, ReadColor<R32G32F, GLfloat>, WriteColor<R32G32F, GLfloat>, GL_FLOAT, 32, 32, 0, 0, 0, 0, 0, 8, 3, false, true, false, false, false, gl::VertexAttribType::Fixed },
+ { FormatID::R32G32_FLOAT, GL_RG32F, GL_RG32F, GenerateMip<R32G32F>, NoCopyFunctions, ReadColor<R32G32F, GLfloat>, WriteColor<R32G32F, GLfloat>, GL_FLOAT, 32, 32, 0, 0, 0, 0, 0, 8, 3, false, false, false, false, false, gl::VertexAttribType::Float },
+ { FormatID::R32G32_SINT, GL_RG32I, GL_RG32I, GenerateMip<R32G32S>, NoCopyFunctions, ReadColor<R32G32S, GLint>, WriteColor<R32G32S, GLint>, GL_INT, 32, 32, 0, 0, 0, 0, 0, 8, 3, false, false, false, false, false, gl::VertexAttribType::Int },
+ { FormatID::R32G32_SNORM, GL_RG32_SNORM_ANGLEX, GL_RG32_SNORM_ANGLEX, GenerateMip<R32G32S>, NoCopyFunctions, ReadColor<R32G32S, GLfloat>, WriteColor<R32G32S, GLfloat>, GL_SIGNED_NORMALIZED, 32, 32, 0, 0, 0, 0, 0, 8, 3, false, false, false, false, false, gl::VertexAttribType::Int },
+ { FormatID::R32G32_SSCALED, GL_RG32_SSCALED_ANGLEX, GL_RG32_SSCALED_ANGLEX, GenerateMip<R32G32S>, NoCopyFunctions, ReadColor<R32G32S, GLint>, WriteColor<R32G32S, GLint>, GL_INT, 32, 32, 0, 0, 0, 0, 0, 8, 3, false, false, true, false, false, gl::VertexAttribType::Int },
+ { FormatID::R32G32_UINT, GL_RG32UI, GL_RG32UI, GenerateMip<R32G32>, NoCopyFunctions, ReadColor<R32G32, GLuint>, WriteColor<R32G32, GLuint>, GL_UNSIGNED_INT, 32, 32, 0, 0, 0, 0, 0, 8, 3, false, false, false, false, false, gl::VertexAttribType::UnsignedInt },
+ { FormatID::R32G32_UNORM, GL_RG32_UNORM_ANGLEX, GL_RG32_UNORM_ANGLEX, GenerateMip<R32G32>, NoCopyFunctions, ReadColor<R32G32, GLfloat>, WriteColor<R32G32, GLfloat>, GL_UNSIGNED_NORMALIZED, 32, 32, 0, 0, 0, 0, 0, 8, 3, false, false, false, false, false, gl::VertexAttribType::UnsignedInt },
+ { FormatID::R32G32_USCALED, GL_RG32_USCALED_ANGLEX, GL_RG32_USCALED_ANGLEX, GenerateMip<R32G32>, NoCopyFunctions, ReadColor<R32G32, GLuint>, WriteColor<R32G32, GLuint>, GL_UNSIGNED_INT, 32, 32, 0, 0, 0, 0, 0, 8, 3, false, false, true, false, false, gl::VertexAttribType::UnsignedInt },
+ { FormatID::R32_FIXED, GL_R32_FIXED_ANGLEX, GL_R32_FIXED_ANGLEX, GenerateMip<R32F>, NoCopyFunctions, ReadColor<R32F, GLfloat>, WriteColor<R32F, GLfloat>, GL_FLOAT, 32, 0, 0, 0, 0, 0, 0, 4, 3, false, true, false, false, false, gl::VertexAttribType::Fixed },
+ { FormatID::R32_FLOAT, GL_R32F, GL_R32F, GenerateMip<R32F>, NoCopyFunctions, ReadColor<R32F, GLfloat>, WriteColor<R32F, GLfloat>, GL_FLOAT, 32, 0, 0, 0, 0, 0, 0, 4, 3, false, false, false, false, false, gl::VertexAttribType::Float },
+ { FormatID::R32_SINT, GL_R32I, GL_R32I, GenerateMip<R32S>, NoCopyFunctions, ReadColor<R32S, GLint>, WriteColor<R32S, GLint>, GL_INT, 32, 0, 0, 0, 0, 0, 0, 4, 3, false, false, false, false, false, gl::VertexAttribType::Int },
+ { FormatID::R32_SNORM, GL_R32_SNORM_ANGLEX, GL_R32_SNORM_ANGLEX, GenerateMip<R32S>, NoCopyFunctions, ReadColor<R32S, GLfloat>, WriteColor<R32S, GLfloat>, GL_SIGNED_NORMALIZED, 32, 0, 0, 0, 0, 0, 0, 4, 3, false, false, false, false, false, gl::VertexAttribType::Int },
+ { FormatID::R32_SSCALED, GL_R32_SSCALED_ANGLEX, GL_R32_SSCALED_ANGLEX, GenerateMip<R32S>, NoCopyFunctions, ReadColor<R32S, GLint>, WriteColor<R32S, GLint>, GL_INT, 32, 0, 0, 0, 0, 0, 0, 4, 3, false, false, true, false, false, gl::VertexAttribType::Int },
+ { FormatID::R32_UINT, GL_R32UI, GL_R32UI, GenerateMip<R32>, NoCopyFunctions, ReadColor<R32, GLuint>, WriteColor<R32, GLuint>, GL_UNSIGNED_INT, 32, 0, 0, 0, 0, 0, 0, 4, 3, false, false, false, false, false, gl::VertexAttribType::UnsignedInt },
+ { FormatID::R32_UNORM, GL_R32_UNORM_ANGLEX, GL_R32_UNORM_ANGLEX, GenerateMip<R32>, NoCopyFunctions, ReadColor<R32, GLfloat>, WriteColor<R32, GLfloat>, GL_UNSIGNED_NORMALIZED, 32, 0, 0, 0, 0, 0, 0, 4, 3, false, false, false, false, false, gl::VertexAttribType::UnsignedInt },
+ { FormatID::R32_USCALED, GL_R32_USCALED_ANGLEX, GL_R32_USCALED_ANGLEX, GenerateMip<R32>, NoCopyFunctions, ReadColor<R32, GLuint>, WriteColor<R32, GLuint>, GL_UNSIGNED_INT, 32, 0, 0, 0, 0, 0, 0, 4, 3, false, false, true, false, false, gl::VertexAttribType::UnsignedInt },
+ { FormatID::R4G4B4A4_UNORM, GL_RGBA4, GL_RGBA4, GenerateMip<R4G4B4A4>, NoCopyFunctions, ReadColor<R4G4B4A4, GLfloat>, WriteColor<R4G4B4A4, GLfloat>, GL_UNSIGNED_NORMALIZED, 4, 4, 4, 4, 0, 0, 0, 2, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::R5G5B5A1_UNORM, GL_RGB5_A1, GL_RGB5_A1, GenerateMip<R5G5B5A1>, NoCopyFunctions, ReadColor<R5G5B5A1, GLfloat>, WriteColor<R5G5B5A1, GLfloat>, GL_UNSIGNED_NORMALIZED, 5, 5, 5, 1, 0, 0, 0, 2, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::R5G6B5_UNORM, GL_RGB565, GL_RGB565, GenerateMip<R5G6B5>, NoCopyFunctions, ReadColor<R5G6B5, GLfloat>, WriteColor<R5G6B5, GLfloat>, GL_UNSIGNED_NORMALIZED, 5, 6, 5, 0, 0, 0, 0, 2, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::R8G8B8A8_SINT, GL_RGBA8I, GL_RGBA8I, GenerateMip<R8G8B8A8S>, NoCopyFunctions, ReadColor<R8G8B8A8S, GLint>, WriteColor<R8G8B8A8S, GLint>, GL_INT, 8, 8, 8, 8, 0, 0, 0, 4, 0, false, false, false, false, false, gl::VertexAttribType::Byte },
+ { FormatID::R8G8B8A8_SNORM, GL_RGBA8_SNORM, GL_RGBA8_SNORM, GenerateMip<R8G8B8A8S>, NoCopyFunctions, ReadColor<R8G8B8A8S, GLfloat>, WriteColor<R8G8B8A8S, GLfloat>, GL_SIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0, 0, 4, 0, false, false, false, false, false, gl::VertexAttribType::Byte },
+ { FormatID::R8G8B8A8_SSCALED, GL_RGBA8_SSCALED_ANGLEX, GL_RGBA8_SSCALED_ANGLEX, GenerateMip<R8G8B8A8S>, NoCopyFunctions, ReadColor<R8G8B8A8S, GLint>, WriteColor<R8G8B8A8S, GLint>, GL_INT, 8, 8, 8, 8, 0, 0, 0, 4, 0, false, false, true, false, false, gl::VertexAttribType::Byte },
+ { FormatID::R8G8B8A8_TYPELESS, GL_RGBA8, GL_RGBA8, GenerateMip<R8G8B8A8>, NoCopyFunctions, ReadColor<R8G8B8A8, GLfloat>, WriteColor<R8G8B8A8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0, 0, 4, 0, false, false, false, false, false, gl::VertexAttribType::UnsignedByte },
+ { FormatID::R8G8B8A8_TYPELESS_SRGB, GL_SRGB8_ALPHA8, GL_SRGB8_ALPHA8, GenerateMip<R8G8B8A8>, NoCopyFunctions, ReadColor<R8G8B8A8, GLfloat>, WriteColor<R8G8B8A8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0, 0, 4, 0, false, false, false, true, false, gl::VertexAttribType::Byte },
+ { FormatID::R8G8B8A8_UINT, GL_RGBA8UI, GL_RGBA8UI, GenerateMip<R8G8B8A8>, NoCopyFunctions, ReadColor<R8G8B8A8, GLuint>, WriteColor<R8G8B8A8, GLuint>, GL_UNSIGNED_INT, 8, 8, 8, 8, 0, 0, 0, 4, 0, false, false, false, false, false, gl::VertexAttribType::UnsignedByte },
+ { FormatID::R8G8B8A8_UNORM, GL_RGBA8, GL_RGBA8, GenerateMip<R8G8B8A8>, NoCopyFunctions, ReadColor<R8G8B8A8, GLfloat>, WriteColor<R8G8B8A8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0, 0, 4, 0, false, false, false, false, false, gl::VertexAttribType::UnsignedByte },
+ { FormatID::R8G8B8A8_UNORM_SRGB, GL_SRGB8_ALPHA8, GL_SRGB8_ALPHA8, GenerateMip<R8G8B8A8SRGB>, NoCopyFunctions, ReadColor<R8G8B8A8SRGB, GLfloat>, WriteColor<R8G8B8A8SRGB, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 8, 0, 0, 0, 4, 0, false, false, false, true, false, gl::VertexAttribType::Byte },
+ { FormatID::R8G8B8A8_USCALED, GL_RGBA8_USCALED_ANGLEX, GL_RGBA8_USCALED_ANGLEX, GenerateMip<R8G8B8A8>, NoCopyFunctions, ReadColor<R8G8B8A8, GLuint>, WriteColor<R8G8B8A8, GLuint>, GL_UNSIGNED_INT, 8, 8, 8, 8, 0, 0, 0, 4, 0, false, false, true, false, false, gl::VertexAttribType::UnsignedByte },
+ { FormatID::R8G8B8X8_UNORM, GL_RGBA8, GL_RGBA8, GenerateMip<R8G8B8X8>, NoCopyFunctions, ReadColor<R8G8B8X8, GLfloat>, WriteColor<R8G8B8X8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0, 0, 4, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::UnsignedByte },
+ { FormatID::R8G8B8_SINT, GL_RGB8I, GL_RGB8I, GenerateMip<R8G8B8S>, NoCopyFunctions, ReadColor<R8G8B8S, GLint>, WriteColor<R8G8B8S, GLint>, GL_INT, 8, 8, 8, 0, 0, 0, 0, 3, 0, false, false, false, false, false, gl::VertexAttribType::Byte },
+ { FormatID::R8G8B8_SNORM, GL_RGB8_SNORM, GL_RGB8_SNORM, GenerateMip<R8G8B8S>, NoCopyFunctions, ReadColor<R8G8B8S, GLfloat>, WriteColor<R8G8B8S, GLfloat>, GL_SIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0, 0, 3, 0, false, false, false, false, false, gl::VertexAttribType::Byte },
+ { FormatID::R8G8B8_SSCALED, GL_RGB8_SSCALED_ANGLEX, GL_RGB8_SSCALED_ANGLEX, GenerateMip<R8G8B8S>, NoCopyFunctions, ReadColor<R8G8B8S, GLint>, WriteColor<R8G8B8S, GLint>, GL_INT, 8, 8, 8, 0, 0, 0, 0, 3, 0, false, false, true, false, false, gl::VertexAttribType::Byte },
+ { FormatID::R8G8B8_UINT, GL_RGB8UI, GL_RGB8UI, GenerateMip<R8G8B8>, NoCopyFunctions, ReadColor<R8G8B8, GLuint>, WriteColor<R8G8B8, GLuint>, GL_UNSIGNED_INT, 8, 8, 8, 0, 0, 0, 0, 3, 0, false, false, false, false, false, gl::VertexAttribType::UnsignedByte },
+ { FormatID::R8G8B8_UNORM, GL_RGB8, GL_RGB8, GenerateMip<R8G8B8>, NoCopyFunctions, ReadColor<R8G8B8, GLfloat>, WriteColor<R8G8B8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0, 0, 3, 0, false, false, false, false, false, gl::VertexAttribType::UnsignedByte },
+ { FormatID::R8G8B8_UNORM_SRGB, GL_SRGB8, GL_SRGB8, GenerateMip<R8G8B8>, NoCopyFunctions, ReadColor<R8G8B8, GLfloat>, WriteColor<R8G8B8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 8, 0, 0, 0, 0, 3, 0, false, false, false, true, false, gl::VertexAttribType::Byte },
+ { FormatID::R8G8B8_USCALED, GL_RGB8_USCALED_ANGLEX, GL_RGB8_USCALED_ANGLEX, GenerateMip<R8G8B8>, NoCopyFunctions, ReadColor<R8G8B8, GLuint>, WriteColor<R8G8B8, GLuint>, GL_UNSIGNED_INT, 8, 8, 8, 0, 0, 0, 0, 3, 0, false, false, true, false, false, gl::VertexAttribType::UnsignedByte },
+ { FormatID::R8G8_SINT, GL_RG8I, GL_RG8I, GenerateMip<R8G8S>, NoCopyFunctions, ReadColor<R8G8S, GLint>, WriteColor<R8G8S, GLint>, GL_INT, 8, 8, 0, 0, 0, 0, 0, 2, 0, false, false, false, false, false, gl::VertexAttribType::Byte },
+ { FormatID::R8G8_SNORM, GL_RG8_SNORM, GL_RG8_SNORM, GenerateMip<R8G8S>, NoCopyFunctions, ReadColor<R8G8S, GLfloat>, WriteColor<R8G8S, GLfloat>, GL_SIGNED_NORMALIZED, 8, 8, 0, 0, 0, 0, 0, 2, 0, false, false, false, false, false, gl::VertexAttribType::Byte },
+ { FormatID::R8G8_SSCALED, GL_RG8_SSCALED_ANGLEX, GL_RG8_SSCALED_ANGLEX, GenerateMip<R8G8S>, NoCopyFunctions, ReadColor<R8G8S, GLint>, WriteColor<R8G8S, GLint>, GL_INT, 8, 8, 0, 0, 0, 0, 0, 2, 0, false, false, true, false, false, gl::VertexAttribType::Byte },
+ { FormatID::R8G8_UINT, GL_RG8UI, GL_RG8UI, GenerateMip<R8G8>, NoCopyFunctions, ReadColor<R8G8, GLuint>, WriteColor<R8G8, GLuint>, GL_UNSIGNED_INT, 8, 8, 0, 0, 0, 0, 0, 2, 0, false, false, false, false, false, gl::VertexAttribType::UnsignedByte },
+ { FormatID::R8G8_UNORM, GL_RG8, GL_RG8, GenerateMip<R8G8>, NoCopyFunctions, ReadColor<R8G8, GLfloat>, WriteColor<R8G8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 0, 0, 0, 0, 0, 2, 0, false, false, false, false, false, gl::VertexAttribType::UnsignedByte },
+ { FormatID::R8G8_UNORM_SRGB, GL_SRG8_EXT, GL_SRG8_EXT, GenerateMip<R8G8>, NoCopyFunctions, ReadColor<R8G8, GLfloat>, WriteColor<R8G8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 8, 0, 0, 0, 0, 0, 2, 0, false, false, false, true, false, gl::VertexAttribType::Byte },
+ { FormatID::R8G8_USCALED, GL_RG8_USCALED_ANGLEX, GL_RG8_USCALED_ANGLEX, GenerateMip<R8G8>, NoCopyFunctions, ReadColor<R8G8, GLuint>, WriteColor<R8G8, GLuint>, GL_UNSIGNED_INT, 8, 8, 0, 0, 0, 0, 0, 2, 0, false, false, true, false, false, gl::VertexAttribType::UnsignedByte },
+ { FormatID::R8_SINT, GL_R8I, GL_R8I, GenerateMip<R8S>, NoCopyFunctions, ReadColor<R8S, GLint>, WriteColor<R8S, GLint>, GL_INT, 8, 0, 0, 0, 0, 0, 0, 1, 0, false, false, false, false, false, gl::VertexAttribType::Byte },
+ { FormatID::R8_SNORM, GL_R8_SNORM, GL_R8_SNORM, GenerateMip<R8S>, NoCopyFunctions, ReadColor<R8S, GLfloat>, WriteColor<R8S, GLfloat>, GL_SIGNED_NORMALIZED, 8, 0, 0, 0, 0, 0, 0, 1, 0, false, false, false, false, false, gl::VertexAttribType::Byte },
+ { FormatID::R8_SSCALED, GL_R8_SSCALED_ANGLEX, GL_R8_SSCALED_ANGLEX, GenerateMip<R8S>, NoCopyFunctions, ReadColor<R8S, GLint>, WriteColor<R8S, GLint>, GL_INT, 8, 0, 0, 0, 0, 0, 0, 1, 0, false, false, true, false, false, gl::VertexAttribType::Byte },
+ { FormatID::R8_UINT, GL_R8UI, GL_R8UI, GenerateMip<R8>, NoCopyFunctions, ReadColor<R8, GLuint>, WriteColor<R8, GLuint>, GL_UNSIGNED_INT, 8, 0, 0, 0, 0, 0, 0, 1, 0, false, false, false, false, false, gl::VertexAttribType::UnsignedByte },
+ { FormatID::R8_UNORM, GL_R8, GL_R8, GenerateMip<R8>, NoCopyFunctions, ReadColor<R8, GLfloat>, WriteColor<R8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 0, 0, 0, 0, 0, 0, 1, 0, false, false, false, false, false, gl::VertexAttribType::UnsignedByte },
+ { FormatID::R8_UNORM_SRGB, GL_SR8_EXT, GL_SR8_EXT, GenerateMip<R8>, NoCopyFunctions, ReadColor<R8, GLfloat>, WriteColor<R8, GLfloat>, GL_UNSIGNED_NORMALIZED, 8, 0, 0, 0, 0, 0, 0, 1, 0, false, false, false, true, false, gl::VertexAttribType::Byte },
+ { FormatID::R8_USCALED, GL_R8_USCALED_ANGLEX, GL_R8_USCALED_ANGLEX, GenerateMip<R8>, NoCopyFunctions, ReadColor<R8, GLuint>, WriteColor<R8, GLuint>, GL_UNSIGNED_INT, 8, 0, 0, 0, 0, 0, 0, 1, 0, false, false, true, false, false, gl::VertexAttribType::UnsignedByte },
+ { FormatID::R9G9B9E5_SHAREDEXP, GL_RGB9_E5, GL_RGB9_E5, GenerateMip<R9G9B9E5>, NoCopyFunctions, ReadColor<R9G9B9E5, GLfloat>, WriteColor<R9G9B9E5, GLfloat>, GL_FLOAT, 9, 9, 9, 0, 0, 0, 0, 4, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::InvalidEnum },
+ { FormatID::X2R10G10B10_SINT_VERTEX, GL_X2_RGB10_SINT_ANGLEX, GL_X2_RGB10_SINT_ANGLEX, nullptr, NoCopyFunctions, nullptr, nullptr, GL_INT, 10, 10, 10, 0, 0, 0, 0, 4, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::Int1010102 },
+ { FormatID::X2R10G10B10_SNORM_VERTEX, GL_X2_RGB10_SNORM_ANGLEX, GL_X2_RGB10_SNORM_ANGLEX, nullptr, NoCopyFunctions, nullptr, nullptr, GL_SIGNED_NORMALIZED, 10, 10, 10, 0, 0, 0, 0, 4, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::Int1010102 },
+ { FormatID::X2R10G10B10_SSCALED_VERTEX, GL_X2_RGB10_SSCALED_ANGLEX, GL_X2_RGB10_SSCALED_ANGLEX, nullptr, NoCopyFunctions, nullptr, nullptr, GL_INT, 10, 10, 10, 0, 0, 0, 0, 4, std::numeric_limits<GLuint>::max(), false, false, true, false, false, gl::VertexAttribType::Int1010102 },
+ { FormatID::X2R10G10B10_UINT_VERTEX, GL_X2_RGB10_UINT_ANGLEX, GL_X2_RGB10_UINT_ANGLEX, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_INT, 10, 10, 10, 0, 0, 0, 0, 4, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::UnsignedInt1010102 },
+ { FormatID::X2R10G10B10_UNORM_VERTEX, GL_X2_RGB10_UNORM_ANGLEX, GL_X2_RGB10_UNORM_ANGLEX, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_NORMALIZED, 10, 10, 10, 0, 0, 0, 0, 4, std::numeric_limits<GLuint>::max(), false, false, false, false, false, gl::VertexAttribType::UnsignedInt1010102 },
+ { FormatID::X2R10G10B10_USCALED_VERTEX, GL_X2_RGB10_USCALED_ANGLEX, GL_X2_RGB10_USCALED_ANGLEX, nullptr, NoCopyFunctions, nullptr, nullptr, GL_UNSIGNED_INT, 10, 10, 10, 0, 0, 0, 0, 4, std::numeric_limits<GLuint>::max(), false, false, true, false, false, gl::VertexAttribType::UnsignedInt1010102 },
+ // clang-format on
+};
+
+// static
+FormatID Format::InternalFormatToID(GLenum internalFormat)
+{
+ switch (internalFormat)
+ {
+ case GL_A1RGB5_ANGLEX:
+ return FormatID::A1R5G5B5_UNORM;
+ case GL_A2_RGB10_SNORM_ANGLEX:
+ return FormatID::A2R10G10B10_SNORM_VERTEX;
+ case GL_A2_RGB10_SSCALED_ANGLEX:
+ return FormatID::A2R10G10B10_SSCALED_VERTEX;
+ case GL_A2_RGB10_UNORM_ANGLEX:
+ return FormatID::A2R10G10B10_UNORM_VERTEX;
+ case GL_A2_RGB10_USCALED_ANGLEX:
+ return FormatID::A2R10G10B10_USCALED_VERTEX;
+ case GL_ALPHA16F_EXT:
+ return FormatID::A16_FLOAT;
+ case GL_ALPHA32F_EXT:
+ return FormatID::A32_FLOAT;
+ case GL_ALPHA8_EXT:
+ return FormatID::A8_UNORM;
+ case GL_BGR10_A2_ANGLEX:
+ return FormatID::B10G10R10A2_UNORM;
+ case GL_BGR565_ANGLEX:
+ return FormatID::B5G6R5_UNORM;
+ case GL_BGR5_A1_ANGLEX:
+ return FormatID::B5G5R5A1_UNORM;
+ case GL_BGRA4_ANGLEX:
+ return FormatID::B4G4R4A4_UNORM;
+ case GL_BGRA8_EXT:
+ return FormatID::B8G8R8A8_UNORM;
+ case GL_BGRA8_SRGB_ANGLEX:
+ return FormatID::B8G8R8A8_UNORM_SRGB;
+ case GL_BGRA8_TYPELESS_ANGLEX:
+ return FormatID::B8G8R8A8_TYPELESS;
+ case GL_BGRA8_TYPELESS_SRGB_ANGLEX:
+ return FormatID::B8G8R8A8_TYPELESS_SRGB;
+ case GL_BGRX8_ANGLEX:
+ return FormatID::B8G8R8X8_UNORM;
+ case GL_COMPRESSED_R11_EAC:
+ return FormatID::EAC_R11_UNORM_BLOCK;
+ case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
+ return FormatID::BC5_RG_UNORM_BLOCK;
+ case GL_COMPRESSED_RED_RGTC1_EXT:
+ return FormatID::BC4_RED_UNORM_BLOCK;
+ case GL_COMPRESSED_RG11_EAC:
+ return FormatID::EAC_R11G11_UNORM_BLOCK;
+ case GL_COMPRESSED_RGB8_ETC2:
+ return FormatID::ETC2_R8G8B8_UNORM_BLOCK;
+ case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+ return FormatID::ETC2_R8G8B8A1_UNORM_BLOCK;
+ case GL_COMPRESSED_RGBA8_ETC2_EAC:
+ return FormatID::ETC2_R8G8B8A8_UNORM_BLOCK;
+ case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
+ return FormatID::ASTC_10x10_UNORM_BLOCK;
+ case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
+ return FormatID::ASTC_10x5_UNORM_BLOCK;
+ case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
+ return FormatID::ASTC_10x6_UNORM_BLOCK;
+ case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
+ return FormatID::ASTC_10x8_UNORM_BLOCK;
+ case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
+ return FormatID::ASTC_12x10_UNORM_BLOCK;
+ case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
+ return FormatID::ASTC_12x12_UNORM_BLOCK;
+ case GL_COMPRESSED_RGBA_ASTC_3x3x3_OES:
+ return FormatID::ASTC_3x3x3_UNORM_BLOCK;
+ case GL_COMPRESSED_RGBA_ASTC_4x3x3_OES:
+ return FormatID::ASTC_4x3x3_UNORM_BLOCK;
+ case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
+ return FormatID::ASTC_4x4_UNORM_BLOCK;
+ case GL_COMPRESSED_RGBA_ASTC_4x4x3_OES:
+ return FormatID::ASTC_4x4x3_UNORM_BLOCK;
+ case GL_COMPRESSED_RGBA_ASTC_4x4x4_OES:
+ return FormatID::ASTC_4x4x4_UNORM_BLOCK;
+ case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
+ return FormatID::ASTC_5x4_UNORM_BLOCK;
+ case GL_COMPRESSED_RGBA_ASTC_5x4x4_OES:
+ return FormatID::ASTC_5x4x4_UNORM_BLOCK;
+ case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
+ return FormatID::ASTC_5x5_UNORM_BLOCK;
+ case GL_COMPRESSED_RGBA_ASTC_5x5x4_OES:
+ return FormatID::ASTC_5x5x4_UNORM_BLOCK;
+ case GL_COMPRESSED_RGBA_ASTC_5x5x5_OES:
+ return FormatID::ASTC_5x5x5_UNORM_BLOCK;
+ case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
+ return FormatID::ASTC_6x5_UNORM_BLOCK;
+ case GL_COMPRESSED_RGBA_ASTC_6x5x5_OES:
+ return FormatID::ASTC_6x5x5_UNORM_BLOCK;
+ case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
+ return FormatID::ASTC_6x6_UNORM_BLOCK;
+ case GL_COMPRESSED_RGBA_ASTC_6x6x5_OES:
+ return FormatID::ASTC_6x6x5_UNORM_BLOCK;
+ case GL_COMPRESSED_RGBA_ASTC_6x6x6_OES:
+ return FormatID::ASTC_6x6x6_UNORM_BLOCK;
+ case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
+ return FormatID::ASTC_8x5_UNORM_BLOCK;
+ case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
+ return FormatID::ASTC_8x6_UNORM_BLOCK;
+ case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
+ return FormatID::ASTC_8x8_UNORM_BLOCK;
+ case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
+ return FormatID::BC7_RGBA_UNORM_BLOCK;
+ case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
+ return FormatID::PVRTC1_RGBA_2BPP_UNORM_BLOCK;
+ case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
+ return FormatID::PVRTC1_RGBA_4BPP_UNORM_BLOCK;
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ return FormatID::BC1_RGBA_UNORM_BLOCK;
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
+ return FormatID::BC2_RGBA_UNORM_BLOCK;
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
+ return FormatID::BC3_RGBA_UNORM_BLOCK;
+ case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
+ return FormatID::BC6H_RGB_SFLOAT_BLOCK;
+ case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
+ return FormatID::BC6H_RGB_UFLOAT_BLOCK;
+ case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
+ return FormatID::PVRTC1_RGB_2BPP_UNORM_BLOCK;
+ case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
+ return FormatID::PVRTC1_RGB_4BPP_UNORM_BLOCK;
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ return FormatID::BC1_RGB_UNORM_BLOCK;
+ case GL_COMPRESSED_SIGNED_R11_EAC:
+ return FormatID::EAC_R11_SNORM_BLOCK;
+ case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:
+ return FormatID::BC5_RG_SNORM_BLOCK;
+ case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:
+ return FormatID::BC4_RED_SNORM_BLOCK;
+ case GL_COMPRESSED_SIGNED_RG11_EAC:
+ return FormatID::EAC_R11G11_SNORM_BLOCK;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
+ return FormatID::ASTC_10x10_SRGB_BLOCK;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
+ return FormatID::ASTC_10x5_SRGB_BLOCK;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
+ return FormatID::ASTC_10x6_SRGB_BLOCK;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
+ return FormatID::ASTC_10x8_SRGB_BLOCK;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
+ return FormatID::ASTC_12x10_SRGB_BLOCK;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
+ return FormatID::ASTC_12x12_SRGB_BLOCK;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES:
+ return FormatID::ASTC_3x3x3_UNORM_SRGB_BLOCK;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES:
+ return FormatID::ASTC_4x3x3_UNORM_SRGB_BLOCK;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
+ return FormatID::ASTC_4x4_SRGB_BLOCK;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES:
+ return FormatID::ASTC_4x4x3_UNORM_SRGB_BLOCK;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES:
+ return FormatID::ASTC_4x4x4_UNORM_SRGB_BLOCK;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
+ return FormatID::ASTC_5x4_SRGB_BLOCK;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES:
+ return FormatID::ASTC_5x4x4_UNORM_SRGB_BLOCK;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
+ return FormatID::ASTC_5x5_SRGB_BLOCK;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES:
+ return FormatID::ASTC_5x5x4_UNORM_SRGB_BLOCK;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES:
+ return FormatID::ASTC_5x5x5_UNORM_SRGB_BLOCK;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
+ return FormatID::ASTC_6x5_SRGB_BLOCK;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES:
+ return FormatID::ASTC_6x5x5_UNORM_SRGB_BLOCK;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
+ return FormatID::ASTC_6x6_SRGB_BLOCK;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES:
+ return FormatID::ASTC_6x6x5_UNORM_SRGB_BLOCK;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES:
+ return FormatID::ASTC_6x6x6_UNORM_SRGB_BLOCK;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
+ return FormatID::ASTC_8x5_SRGB_BLOCK;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
+ return FormatID::ASTC_8x6_SRGB_BLOCK;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
+ return FormatID::ASTC_8x8_SRGB_BLOCK;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
+ return FormatID::ETC2_R8G8B8A8_SRGB_BLOCK;
+ case GL_COMPRESSED_SRGB8_ETC2:
+ return FormatID::ETC2_R8G8B8_SRGB_BLOCK;
+ case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+ return FormatID::ETC2_R8G8B8A1_SRGB_BLOCK;
+ case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
+ return FormatID::BC7_RGBA_UNORM_SRGB_BLOCK;
+ case GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT:
+ return FormatID::PVRTC1_RGBA_2BPP_UNORM_SRGB_BLOCK;
+ case GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT:
+ return FormatID::PVRTC1_RGBA_4BPP_UNORM_SRGB_BLOCK;
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
+ return FormatID::BC1_RGBA_UNORM_SRGB_BLOCK;
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
+ return FormatID::BC2_RGBA_UNORM_SRGB_BLOCK;
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
+ return FormatID::BC3_RGBA_UNORM_SRGB_BLOCK;
+ case GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT:
+ return FormatID::PVRTC1_RGB_2BPP_UNORM_SRGB_BLOCK;
+ case GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT:
+ return FormatID::PVRTC1_RGB_4BPP_UNORM_SRGB_BLOCK;
+ case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
+ return FormatID::BC1_RGB_UNORM_SRGB_BLOCK;
+ case GL_DEPTH24_STENCIL8:
+ return FormatID::D24_UNORM_S8_UINT;
+ case GL_DEPTH32F_STENCIL8:
+ return FormatID::D32_FLOAT_S8X24_UINT;
+ case GL_DEPTH_COMPONENT16:
+ return FormatID::D16_UNORM;
+ case GL_DEPTH_COMPONENT24:
+ return FormatID::D24_UNORM_X8_UINT;
+ case GL_DEPTH_COMPONENT32F:
+ return FormatID::D32_FLOAT;
+ case GL_DEPTH_COMPONENT32_OES:
+ return FormatID::D32_UNORM;
+ case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
+ return FormatID::ETC1_LOSSY_DECODE_R8G8B8_UNORM_BLOCK;
+ case GL_ETC1_RGB8_OES:
+ return FormatID::ETC1_R8G8B8_UNORM_BLOCK;
+ case GL_G8_B8R8_2PLANE_420_UNORM_ANGLE:
+ return FormatID::G8_B8R8_2PLANE_420_UNORM;
+ case GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE:
+ return FormatID::G8_B8_R8_3PLANE_420_UNORM;
+ case GL_INT_10_10_10_2_OES:
+ return FormatID::A2R10G10B10_SINT_VERTEX;
+ case GL_LUMINANCE16F_EXT:
+ return FormatID::L16_FLOAT;
+ case GL_LUMINANCE32F_EXT:
+ return FormatID::L32_FLOAT;
+ case GL_LUMINANCE8_ALPHA8_EXT:
+ return FormatID::L8A8_UNORM;
+ case GL_LUMINANCE8_EXT:
+ return FormatID::L8_UNORM;
+ case GL_LUMINANCE_ALPHA16F_EXT:
+ return FormatID::L16A16_FLOAT;
+ case GL_LUMINANCE_ALPHA32F_EXT:
+ return FormatID::L32A32_FLOAT;
+ case GL_NONE:
+ return FormatID::NONE;
+ case GL_PALETTE4_R5_G6_B5_OES:
+ return FormatID::PALETTE4_R5G6B5_UNORM;
+ case GL_PALETTE4_RGB5_A1_OES:
+ return FormatID::PALETTE4_R5G5B5A1_UNORM;
+ case GL_PALETTE4_RGB8_OES:
+ return FormatID::PALETTE4_R8G8B8_UNORM;
+ case GL_PALETTE4_RGBA4_OES:
+ return FormatID::PALETTE4_R4G4B4A4_UNORM;
+ case GL_PALETTE4_RGBA8_OES:
+ return FormatID::PALETTE4_R8G8B8A8_UNORM;
+ case GL_PALETTE8_R5_G6_B5_OES:
+ return FormatID::PALETTE8_R5G6B5_UNORM;
+ case GL_PALETTE8_RGB5_A1_OES:
+ return FormatID::PALETTE8_R5G5B5A1_UNORM;
+ case GL_PALETTE8_RGB8_OES:
+ return FormatID::PALETTE8_R8G8B8_UNORM;
+ case GL_PALETTE8_RGBA4_OES:
+ return FormatID::PALETTE8_R4G4B4A4_UNORM;
+ case GL_PALETTE8_RGBA8_OES:
+ return FormatID::PALETTE8_R8G8B8A8_UNORM;
+ case GL_R11F_G11F_B10F:
+ return FormatID::R11G11B10_FLOAT;
+ case GL_R16F:
+ return FormatID::R16_FLOAT;
+ case GL_R16I:
+ return FormatID::R16_SINT;
+ case GL_R16UI:
+ return FormatID::R16_UINT;
+ case GL_R16_EXT:
+ return FormatID::R16_UNORM;
+ case GL_R16_SNORM_EXT:
+ return FormatID::R16_SNORM;
+ case GL_R16_SSCALED_ANGLEX:
+ return FormatID::R16_SSCALED;
+ case GL_R16_USCALED_ANGLEX:
+ return FormatID::R16_USCALED;
+ case GL_R32F:
+ return FormatID::R32_FLOAT;
+ case GL_R32I:
+ return FormatID::R32_SINT;
+ case GL_R32UI:
+ return FormatID::R32_UINT;
+ case GL_R32_FIXED_ANGLEX:
+ return FormatID::R32_FIXED;
+ case GL_R32_SNORM_ANGLEX:
+ return FormatID::R32_SNORM;
+ case GL_R32_SSCALED_ANGLEX:
+ return FormatID::R32_SSCALED;
+ case GL_R32_UNORM_ANGLEX:
+ return FormatID::R32_UNORM;
+ case GL_R32_USCALED_ANGLEX:
+ return FormatID::R32_USCALED;
+ case GL_R8:
+ return FormatID::R8_UNORM;
+ case GL_R8I:
+ return FormatID::R8_SINT;
+ case GL_R8UI:
+ return FormatID::R8_UINT;
+ case GL_R8_SNORM:
+ return FormatID::R8_SNORM;
+ case GL_R8_SSCALED_ANGLEX:
+ return FormatID::R8_SSCALED;
+ case GL_R8_USCALED_ANGLEX:
+ return FormatID::R8_USCALED;
+ case GL_RG16F:
+ return FormatID::R16G16_FLOAT;
+ case GL_RG16I:
+ return FormatID::R16G16_SINT;
+ case GL_RG16UI:
+ return FormatID::R16G16_UINT;
+ case GL_RG16_EXT:
+ return FormatID::R16G16_UNORM;
+ case GL_RG16_SNORM_EXT:
+ return FormatID::R16G16_SNORM;
+ case GL_RG16_SSCALED_ANGLEX:
+ return FormatID::R16G16_SSCALED;
+ case GL_RG16_USCALED_ANGLEX:
+ return FormatID::R16G16_USCALED;
+ case GL_RG32F:
+ return FormatID::R32G32_FLOAT;
+ case GL_RG32I:
+ return FormatID::R32G32_SINT;
+ case GL_RG32UI:
+ return FormatID::R32G32_UINT;
+ case GL_RG32_FIXED_ANGLEX:
+ return FormatID::R32G32_FIXED;
+ case GL_RG32_SNORM_ANGLEX:
+ return FormatID::R32G32_SNORM;
+ case GL_RG32_SSCALED_ANGLEX:
+ return FormatID::R32G32_SSCALED;
+ case GL_RG32_UNORM_ANGLEX:
+ return FormatID::R32G32_UNORM;
+ case GL_RG32_USCALED_ANGLEX:
+ return FormatID::R32G32_USCALED;
+ case GL_RG8:
+ return FormatID::R8G8_UNORM;
+ case GL_RG8I:
+ return FormatID::R8G8_SINT;
+ case GL_RG8UI:
+ return FormatID::R8G8_UINT;
+ case GL_RG8_SNORM:
+ return FormatID::R8G8_SNORM;
+ case GL_RG8_SSCALED_ANGLEX:
+ return FormatID::R8G8_SSCALED;
+ case GL_RG8_USCALED_ANGLEX:
+ return FormatID::R8G8_USCALED;
+ case GL_RGB:
+ return FormatID::R8G8B8_UNORM;
+ case GL_RGB10_A2:
+ return FormatID::R10G10B10A2_UNORM;
+ case GL_RGB10_A2UI:
+ return FormatID::R10G10B10A2_UINT;
+ case GL_RGB10_A2_SINT_ANGLEX:
+ return FormatID::R10G10B10A2_SINT;
+ case GL_RGB10_A2_SNORM_ANGLEX:
+ return FormatID::R10G10B10A2_SNORM;
+ case GL_RGB10_A2_SSCALED_ANGLEX:
+ return FormatID::R10G10B10A2_SSCALED;
+ case GL_RGB10_A2_USCALED_ANGLEX:
+ return FormatID::R10G10B10A2_USCALED;
+ case GL_RGB10_UNORM_ANGLEX:
+ return FormatID::R10G10B10X2_UNORM;
+ case GL_RGB16F:
+ return FormatID::R16G16B16_FLOAT;
+ case GL_RGB16I:
+ return FormatID::R16G16B16_SINT;
+ case GL_RGB16UI:
+ return FormatID::R16G16B16_UINT;
+ case GL_RGB16_EXT:
+ return FormatID::R16G16B16_UNORM;
+ case GL_RGB16_SNORM_EXT:
+ return FormatID::R16G16B16_SNORM;
+ case GL_RGB16_SSCALED_ANGLEX:
+ return FormatID::R16G16B16_SSCALED;
+ case GL_RGB16_USCALED_ANGLEX:
+ return FormatID::R16G16B16_USCALED;
+ case GL_RGB32F:
+ return FormatID::R32G32B32_FLOAT;
+ case GL_RGB32I:
+ return FormatID::R32G32B32_SINT;
+ case GL_RGB32UI:
+ return FormatID::R32G32B32_UINT;
+ case GL_RGB32_FIXED_ANGLEX:
+ return FormatID::R32G32B32_FIXED;
+ case GL_RGB32_SNORM_ANGLEX:
+ return FormatID::R32G32B32_SNORM;
+ case GL_RGB32_SSCALED_ANGLEX:
+ return FormatID::R32G32B32_SSCALED;
+ case GL_RGB32_UNORM_ANGLEX:
+ return FormatID::R32G32B32_UNORM;
+ case GL_RGB32_USCALED_ANGLEX:
+ return FormatID::R32G32B32_USCALED;
+ case GL_RGB565:
+ return FormatID::R5G6B5_UNORM;
+ case GL_RGB5_A1:
+ return FormatID::R5G5B5A1_UNORM;
+ case GL_RGB8:
+ return FormatID::R8G8B8_UNORM;
+ case GL_RGB8I:
+ return FormatID::R8G8B8_SINT;
+ case GL_RGB8UI:
+ return FormatID::R8G8B8_UINT;
+ case GL_RGB8_SNORM:
+ return FormatID::R8G8B8_SNORM;
+ case GL_RGB8_SSCALED_ANGLEX:
+ return FormatID::R8G8B8_SSCALED;
+ case GL_RGB8_USCALED_ANGLEX:
+ return FormatID::R8G8B8_USCALED;
+ case GL_RGB9_E5:
+ return FormatID::R9G9B9E5_SHAREDEXP;
+ case GL_RGBA:
+ return FormatID::R8G8B8A8_UNORM;
+ case GL_RGBA16F:
+ return FormatID::R16G16B16A16_FLOAT;
+ case GL_RGBA16I:
+ return FormatID::R16G16B16A16_SINT;
+ case GL_RGBA16UI:
+ return FormatID::R16G16B16A16_UINT;
+ case GL_RGBA16_EXT:
+ return FormatID::R16G16B16A16_UNORM;
+ case GL_RGBA16_SNORM_EXT:
+ return FormatID::R16G16B16A16_SNORM;
+ case GL_RGBA16_SSCALED_ANGLEX:
+ return FormatID::R16G16B16A16_SSCALED;
+ case GL_RGBA16_USCALED_ANGLEX:
+ return FormatID::R16G16B16A16_USCALED;
+ case GL_RGBA32F:
+ return FormatID::R32G32B32A32_FLOAT;
+ case GL_RGBA32I:
+ return FormatID::R32G32B32A32_SINT;
+ case GL_RGBA32UI:
+ return FormatID::R32G32B32A32_UINT;
+ case GL_RGBA32_FIXED_ANGLEX:
+ return FormatID::R32G32B32A32_FIXED;
+ case GL_RGBA32_SNORM_ANGLEX:
+ return FormatID::R32G32B32A32_SNORM;
+ case GL_RGBA32_SSCALED_ANGLEX:
+ return FormatID::R32G32B32A32_SSCALED;
+ case GL_RGBA32_UNORM_ANGLEX:
+ return FormatID::R32G32B32A32_UNORM;
+ case GL_RGBA32_USCALED_ANGLEX:
+ return FormatID::R32G32B32A32_USCALED;
+ case GL_RGBA4:
+ return FormatID::R4G4B4A4_UNORM;
+ case GL_RGBA8:
+ return FormatID::R8G8B8A8_UNORM;
+ case GL_RGBA8I:
+ return FormatID::R8G8B8A8_SINT;
+ case GL_RGBA8UI:
+ return FormatID::R8G8B8A8_UINT;
+ case GL_RGBA8_SNORM:
+ return FormatID::R8G8B8A8_SNORM;
+ case GL_RGBA8_SSCALED_ANGLEX:
+ return FormatID::R8G8B8A8_SSCALED;
+ case GL_RGBA8_TYPELESS_ANGLEX:
+ return FormatID::R8G8B8A8_TYPELESS;
+ case GL_RGBA8_TYPELESS_SRGB_ANGLEX:
+ return FormatID::R8G8B8A8_TYPELESS_SRGB;
+ case GL_RGBA8_USCALED_ANGLEX:
+ return FormatID::R8G8B8A8_USCALED;
+ case GL_RGBX8_ANGLE:
+ return FormatID::R8G8B8X8_UNORM;
+ case GL_SR8_EXT:
+ return FormatID::R8_UNORM_SRGB;
+ case GL_SRG8_EXT:
+ return FormatID::R8G8_UNORM_SRGB;
+ case GL_SRGB8:
+ return FormatID::R8G8B8_UNORM_SRGB;
+ case GL_SRGB8_ALPHA8:
+ return FormatID::R8G8B8A8_UNORM_SRGB;
+ case GL_STENCIL_INDEX8:
+ return FormatID::S8_UINT;
+ case GL_UNSIGNED_INT_10_10_10_2_OES:
+ return FormatID::A2R10G10B10_UINT_VERTEX;
+ case GL_X2_RGB10_SINT_ANGLEX:
+ return FormatID::X2R10G10B10_SINT_VERTEX;
+ case GL_X2_RGB10_SNORM_ANGLEX:
+ return FormatID::X2R10G10B10_SNORM_VERTEX;
+ case GL_X2_RGB10_SSCALED_ANGLEX:
+ return FormatID::X2R10G10B10_SSCALED_VERTEX;
+ case GL_X2_RGB10_UINT_ANGLEX:
+ return FormatID::X2R10G10B10_UINT_VERTEX;
+ case GL_X2_RGB10_UNORM_ANGLEX:
+ return FormatID::X2R10G10B10_UNORM_VERTEX;
+ case GL_X2_RGB10_USCALED_ANGLEX:
+ return FormatID::X2R10G10B10_USCALED_VERTEX;
+ default:
+ return FormatID::NONE;
+ }
+}
+
+const Format *GetFormatInfoTable()
+{
+ return gFormatInfoTable;
+}
+} // namespace angle
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/FramebufferAttachmentObjectImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/FramebufferAttachmentObjectImpl.h
new file mode 100644
index 0000000000..0b5223ae5d
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/FramebufferAttachmentObjectImpl.h
@@ -0,0 +1,65 @@
+//
+// 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.
+//
+// FramebufferAttachmentObjectImpl.h:
+// Common ancenstor for all implementations of FBO attachable-objects.
+// This means Surfaces, Textures and Renderbuffers.
+//
+
+#ifndef LIBANGLE_RENDERER_FRAMEBUFFER_ATTACHMENT_OBJECT_IMPL_H_
+#define LIBANGLE_RENDERER_FRAMEBUFFER_ATTACHMENT_OBJECT_IMPL_H_
+
+#include "libANGLE/ImageIndex.h"
+#include "libANGLE/Observer.h"
+
+namespace gl
+{
+class Context;
+} // namespace gl
+
+namespace rx
+{
+class FramebufferAttachmentRenderTarget;
+
+class FramebufferAttachmentObjectImpl : public angle::Subject
+{
+ public:
+ FramebufferAttachmentObjectImpl() {}
+ ~FramebufferAttachmentObjectImpl() override {}
+
+ virtual angle::Result getAttachmentRenderTarget(const gl::Context *context,
+ GLenum binding,
+ const gl::ImageIndex &imageIndex,
+ GLsizei samples,
+ FramebufferAttachmentRenderTarget **rtOut);
+
+ virtual angle::Result initializeContents(const gl::Context *context,
+ GLenum binding,
+ const gl::ImageIndex &imageIndex);
+};
+
+inline angle::Result FramebufferAttachmentObjectImpl::getAttachmentRenderTarget(
+ const gl::Context *context,
+ GLenum binding,
+ const gl::ImageIndex &imageIndex,
+ GLsizei samples,
+ FramebufferAttachmentRenderTarget **rtOut)
+{
+ UNIMPLEMENTED();
+ return angle::Result::Stop;
+}
+
+inline angle::Result FramebufferAttachmentObjectImpl::initializeContents(
+ const gl::Context *context,
+ GLenum binding,
+ const gl::ImageIndex &imageIndex)
+{
+ UNIMPLEMENTED();
+ return angle::Result::Stop;
+}
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_FRAMEBUFFER_ATTACHMENT_OBJECT_IMPL_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/FramebufferImpl.cpp b/gfx/angle/checkout/src/libANGLE/renderer/FramebufferImpl.cpp
new file mode 100644
index 0000000000..1cef167d9d
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/FramebufferImpl.cpp
@@ -0,0 +1,18 @@
+//
+// Copyright 2022 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.
+//
+// FramebufferImpl.cpp: Implements the class methods for FramebufferImpl.
+
+#include "libANGLE/renderer/FramebufferImpl.h"
+
+namespace rx
+{
+
+angle::Result FramebufferImpl::onLabelUpdate(const gl::Context *context)
+{
+ return angle::Result::Continue;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/FramebufferImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/FramebufferImpl.h
new file mode 100644
index 0000000000..0ecfaba4f2
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/FramebufferImpl.h
@@ -0,0 +1,123 @@
+//
+// 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.
+//
+
+// FramebufferImpl.h: Defines the abstract rx::FramebufferImpl class.
+
+#ifndef LIBANGLE_RENDERER_FRAMEBUFFERIMPL_H_
+#define LIBANGLE_RENDERER_FRAMEBUFFERIMPL_H_
+
+#include "angle_gl.h"
+#include "common/angleutils.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/State.h"
+#include "libANGLE/angletypes.h"
+
+namespace gl
+{
+class Buffer;
+class Framebuffer;
+class FramebufferAttachment;
+struct PixelPackState;
+} // namespace gl
+
+namespace rx
+{
+class DisplayImpl;
+
+class FramebufferImpl : angle::NonCopyable
+{
+ public:
+ explicit FramebufferImpl(const gl::FramebufferState &state) : mState(state) {}
+ virtual ~FramebufferImpl() {}
+ virtual void destroy(const gl::Context *context) {}
+
+ virtual angle::Result discard(const gl::Context *context,
+ size_t count,
+ const GLenum *attachments) = 0;
+ virtual angle::Result invalidate(const gl::Context *context,
+ size_t count,
+ const GLenum *attachments) = 0;
+ virtual angle::Result invalidateSub(const gl::Context *context,
+ size_t count,
+ const GLenum *attachments,
+ const gl::Rectangle &area) = 0;
+
+ virtual angle::Result clear(const gl::Context *context, GLbitfield mask) = 0;
+ virtual angle::Result clearBufferfv(const gl::Context *context,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLfloat *values) = 0;
+ virtual angle::Result clearBufferuiv(const gl::Context *context,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLuint *values) = 0;
+ virtual angle::Result clearBufferiv(const gl::Context *context,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLint *values) = 0;
+ virtual angle::Result clearBufferfi(const gl::Context *context,
+ GLenum buffer,
+ GLint drawbuffer,
+ GLfloat depth,
+ GLint stencil) = 0;
+
+ virtual const gl::InternalFormat &getImplementationColorReadFormat(
+ const gl::Context *context) const;
+ virtual angle::Result readPixels(const gl::Context *context,
+ const gl::Rectangle &area,
+ GLenum format,
+ GLenum type,
+ const gl::PixelPackState &pack,
+ gl::Buffer *packBuffer,
+ void *pixels) = 0;
+
+ virtual angle::Result blit(const gl::Context *context,
+ const gl::Rectangle &sourceArea,
+ const gl::Rectangle &destArea,
+ GLbitfield mask,
+ GLenum filter) = 0;
+
+ virtual gl::FramebufferStatus checkStatus(const gl::Context *context) const = 0;
+
+ virtual angle::Result syncState(const gl::Context *context,
+ GLenum binding,
+ const gl::Framebuffer::DirtyBits &dirtyBits,
+ gl::Command command) = 0;
+
+ virtual angle::Result getSamplePosition(const gl::Context *context,
+ size_t index,
+ GLfloat *xy) const = 0;
+
+ // Special configuration option for checkStatus(). Some back-ends don't require a syncState
+ // before calling checkStatus. In practice the GL back-end is the only config that needs
+ // syncState because it depends on the behaviour of the driver. Allowing the Vulkan and
+ // D3D back-ends to skip syncState lets us do more work in the syncState call.
+ virtual bool shouldSyncStateBeforeCheckStatus() const;
+
+ virtual angle::Result onLabelUpdate(const gl::Context *context);
+
+ const gl::FramebufferState &getState() const { return mState; }
+
+ protected:
+ const gl::FramebufferState &mState;
+};
+
+inline bool FramebufferImpl::shouldSyncStateBeforeCheckStatus() const
+{
+ return false;
+}
+
+// Default implementation returns the format specified in the attachment.
+inline const gl::InternalFormat &FramebufferImpl::getImplementationColorReadFormat(
+ const gl::Context *context) const
+{
+ const gl::FramebufferAttachment *readAttachment = mState.getReadAttachment();
+ return *readAttachment->getFormat().info;
+}
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_FRAMEBUFFERIMPL_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/GLImplFactory.h b/gfx/angle/checkout/src/libANGLE/renderer/GLImplFactory.h
new file mode 100644
index 0000000000..1995197b06
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/GLImplFactory.h
@@ -0,0 +1,116 @@
+//
+// 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.
+//
+// GLImplFactory.h:
+// Factory interface for OpenGL ES Impl objects.
+//
+
+#ifndef LIBANGLE_RENDERER_GLIMPLFACTORY_H_
+#define LIBANGLE_RENDERER_GLIMPLFACTORY_H_
+
+#include <vector>
+
+#include "angle_gl.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/Overlay.h"
+#include "libANGLE/Program.h"
+#include "libANGLE/ProgramPipeline.h"
+#include "libANGLE/Renderbuffer.h"
+#include "libANGLE/Shader.h"
+#include "libANGLE/Texture.h"
+#include "libANGLE/TransformFeedback.h"
+#include "libANGLE/VertexArray.h"
+#include "libANGLE/renderer/serial_utils.h"
+
+namespace gl
+{
+class State;
+} // namespace gl
+
+namespace rx
+{
+class BufferImpl;
+class CompilerImpl;
+class ContextImpl;
+class FenceNVImpl;
+class SyncImpl;
+class FramebufferImpl;
+class MemoryObjectImpl;
+class OverlayImpl;
+class PathImpl;
+class ProgramImpl;
+class ProgramPipelineImpl;
+class QueryImpl;
+class RenderbufferImpl;
+class SamplerImpl;
+class SemaphoreImpl;
+class ShaderImpl;
+class TextureImpl;
+class TransformFeedbackImpl;
+class VertexArrayImpl;
+
+class GLImplFactory : angle::NonCopyable
+{
+ public:
+ GLImplFactory();
+ virtual ~GLImplFactory();
+
+ // Shader creation
+ virtual CompilerImpl *createCompiler() = 0;
+ virtual ShaderImpl *createShader(const gl::ShaderState &data) = 0;
+ virtual ProgramImpl *createProgram(const gl::ProgramState &data) = 0;
+
+ // Framebuffer creation
+ virtual FramebufferImpl *createFramebuffer(const gl::FramebufferState &data) = 0;
+
+ // Texture creation
+ virtual TextureImpl *createTexture(const gl::TextureState &state) = 0;
+
+ // Renderbuffer creation
+ virtual RenderbufferImpl *createRenderbuffer(const gl::RenderbufferState &state) = 0;
+
+ // Buffer creation
+ virtual BufferImpl *createBuffer(const gl::BufferState &state) = 0;
+
+ // Vertex Array creation
+ virtual VertexArrayImpl *createVertexArray(const gl::VertexArrayState &data) = 0;
+
+ // Query and Fence creation
+ virtual QueryImpl *createQuery(gl::QueryType type) = 0;
+ virtual FenceNVImpl *createFenceNV() = 0;
+ virtual SyncImpl *createSync() = 0;
+
+ // Transform Feedback creation
+ virtual TransformFeedbackImpl *createTransformFeedback(
+ const gl::TransformFeedbackState &state) = 0;
+
+ // Sampler object creation
+ virtual SamplerImpl *createSampler(const gl::SamplerState &state) = 0;
+
+ // Program Pipeline object creation
+ virtual ProgramPipelineImpl *createProgramPipeline(const gl::ProgramPipelineState &data) = 0;
+
+ // Memory object creation
+ virtual MemoryObjectImpl *createMemoryObject() = 0;
+
+ // Semaphore creation
+ virtual SemaphoreImpl *createSemaphore() = 0;
+
+ // Overlay creation
+ virtual OverlayImpl *createOverlay(const gl::OverlayState &state) = 0;
+
+ rx::Serial generateSerial() { return mSerialFactory.generate(); }
+
+ private:
+ rx::SerialFactory mSerialFactory;
+};
+
+inline GLImplFactory::GLImplFactory() = default;
+
+inline GLImplFactory::~GLImplFactory() = default;
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_GLIMPLFACTORY_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/ImageImpl.cpp b/gfx/angle/checkout/src/libANGLE/renderer/ImageImpl.cpp
new file mode 100644
index 0000000000..014b1d634d
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/ImageImpl.cpp
@@ -0,0 +1,30 @@
+//
+// Copyright 2021 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.
+//
+
+// ImageImpl.cpp: Defines the rx::ImageImpl class representing the EGLimage object.
+
+#include "libANGLE/renderer/ImageImpl.h"
+
+namespace rx
+{
+
+bool ExternalImageSiblingImpl::isCubeMap() const
+{
+ return false;
+}
+
+uint32_t ExternalImageSiblingImpl::getLevelCount() const
+{
+ return 1;
+}
+
+egl::Error ImageImpl::exportVkImage(void *vkImage, void *vkImageCreateInfo)
+{
+ UNIMPLEMENTED();
+ return egl::EglBadAccess();
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/ImageImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/ImageImpl.h
new file mode 100644
index 0000000000..2a316610b3
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/ImageImpl.h
@@ -0,0 +1,68 @@
+//
+// 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.
+//
+
+// ImageImpl.h: Defines the rx::ImageImpl class representing the EGLimage object.
+
+#ifndef LIBANGLE_RENDERER_IMAGEIMPL_H_
+#define LIBANGLE_RENDERER_IMAGEIMPL_H_
+
+#include "common/angleutils.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/FramebufferAttachmentObjectImpl.h"
+
+namespace gl
+{
+class Context;
+} // namespace gl
+
+namespace egl
+{
+class Display;
+class ImageSibling;
+struct ImageState;
+} // namespace egl
+
+namespace rx
+{
+class ExternalImageSiblingImpl : public FramebufferAttachmentObjectImpl
+{
+ public:
+ ~ExternalImageSiblingImpl() override {}
+
+ virtual egl::Error initialize(const egl::Display *display) = 0;
+ virtual void onDestroy(const egl::Display *display) {}
+
+ virtual gl::Format getFormat() const = 0;
+ virtual bool isRenderable(const gl::Context *context) const = 0;
+ virtual bool isTexturable(const gl::Context *context) const = 0;
+ virtual bool isYUV() const = 0;
+ virtual bool isCubeMap() const;
+ virtual bool hasProtectedContent() const = 0;
+ virtual gl::Extents getSize() const = 0;
+ virtual size_t getSamples() const = 0;
+ virtual uint32_t getLevelCount() const;
+};
+
+class ImageImpl : angle::NonCopyable
+{
+ public:
+ ImageImpl(const egl::ImageState &state) : mState(state) {}
+ virtual ~ImageImpl() {}
+ virtual void onDestroy(const egl::Display *display) {}
+
+ virtual egl::Error initialize(const egl::Display *display) = 0;
+
+ virtual angle::Result orphan(const gl::Context *context, egl::ImageSibling *sibling) = 0;
+
+ virtual egl::Error exportVkImage(void *vkImage, void *vkImageCreateInfo);
+
+ protected:
+ const egl::ImageState &mState;
+};
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_IMAGEIMPL_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/MemoryObjectImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/MemoryObjectImpl.h
new file mode 100644
index 0000000000..ce37dd3545
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/MemoryObjectImpl.h
@@ -0,0 +1,47 @@
+//
+// Copyright 2019 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.
+//
+// MemoryObjectImpl.h: Implements the rx::MemoryObjectImpl class [EXT_external_objects]
+
+#ifndef LIBANGLE_RENDERER_MEMORYOBJECTIMPL_H_
+#define LIBANGLE_RENDERER_MEMORYOBJECTIMPL_H_
+
+#include "angle_gl.h"
+#include "common/PackedEnums.h"
+#include "common/angleutils.h"
+#include "libANGLE/Error.h"
+
+namespace gl
+{
+class Context;
+class MemoryObject;
+} // namespace gl
+
+namespace rx
+{
+
+class MemoryObjectImpl : angle::NonCopyable
+{
+ public:
+ virtual ~MemoryObjectImpl() {}
+
+ virtual void onDestroy(const gl::Context *context) = 0;
+
+ virtual angle::Result setDedicatedMemory(const gl::Context *context, bool dedicatedMemory) = 0;
+ virtual angle::Result setProtectedMemory(const gl::Context *context, bool protectedMemory) = 0;
+
+ virtual angle::Result importFd(gl::Context *context,
+ GLuint64 size,
+ gl::HandleType handleType,
+ GLint fd) = 0;
+ virtual angle::Result importZirconHandle(gl::Context *context,
+ GLuint64 size,
+ gl::HandleType handleType,
+ GLuint handle) = 0;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_MEMORYOBJECTIMPL_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/OverlayImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/OverlayImpl.h
new file mode 100644
index 0000000000..fc1b1b0d58
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/OverlayImpl.h
@@ -0,0 +1,42 @@
+//
+// Copyright 2019 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.
+//
+
+// OverlayImpl.h: Defines the abstract rx::OverlayImpl class.
+
+#ifndef LIBANGLE_RENDERER_OVERLAYIMPL_H_
+#define LIBANGLE_RENDERER_OVERLAYIMPL_H_
+
+#include "common/PackedEnums.h"
+#include "common/angleutils.h"
+#include "common/mathutil.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/Observer.h"
+
+#include <stdint.h>
+
+namespace gl
+{
+class Context;
+class OverlayState;
+} // namespace gl
+
+namespace rx
+{
+class OverlayImpl : angle::NonCopyable
+{
+ public:
+ OverlayImpl(const gl::OverlayState &state) : mState(state) {}
+ virtual ~OverlayImpl() {}
+
+ virtual void onDestroy(const gl::Context *context) {}
+
+ protected:
+ const gl::OverlayState &mState;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_OVERLAYIMPL_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/ProgramImpl.cpp b/gfx/angle/checkout/src/libANGLE/renderer/ProgramImpl.cpp
new file mode 100644
index 0000000000..9ede4a882d
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/ProgramImpl.cpp
@@ -0,0 +1,18 @@
+//
+// Copyright 2022 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.
+//
+// ProgramImpl.cpp: Implements the class methods for ProgramImpl.
+
+#include "libANGLE/renderer/ProgramImpl.h"
+
+namespace rx
+{
+
+angle::Result ProgramImpl::onLabelUpdate(const gl::Context *context)
+{
+ return angle::Result::Continue;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/ProgramImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/ProgramImpl.h
new file mode 100644
index 0000000000..22bd304856
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/ProgramImpl.h
@@ -0,0 +1,176 @@
+//
+// 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.
+//
+
+// ProgramImpl.h: Defines the abstract rx::ProgramImpl class.
+
+#ifndef LIBANGLE_RENDERER_PROGRAMIMPL_H_
+#define LIBANGLE_RENDERER_PROGRAMIMPL_H_
+
+#include "common/angleutils.h"
+#include "libANGLE/BinaryStream.h"
+#include "libANGLE/Constants.h"
+#include "libANGLE/Program.h"
+#include "libANGLE/Shader.h"
+
+#include <map>
+
+namespace gl
+{
+class Context;
+struct ProgramLinkedResources;
+} // namespace gl
+
+namespace sh
+{
+struct BlockMemberInfo;
+}
+
+namespace rx
+{
+
+// Provides a mechanism to access the result of asynchronous linking.
+class LinkEvent : angle::NonCopyable
+{
+ public:
+ virtual ~LinkEvent() {}
+
+ // Please be aware that these methods may be called under a gl::Context other
+ // than the one where the LinkEvent was created.
+ //
+ // Waits until the linking is actually done. Returns true if the linking
+ // succeeded, false otherwise.
+ virtual angle::Result wait(const gl::Context *context) = 0;
+ // Peeks whether the linking is still ongoing.
+ virtual bool isLinking() = 0;
+};
+
+// Wraps an already done linking.
+class LinkEventDone final : public LinkEvent
+{
+ public:
+ LinkEventDone(angle::Result result) : mResult(result) {}
+ angle::Result wait(const gl::Context *context) override;
+ bool isLinking() override;
+
+ private:
+ angle::Result mResult;
+};
+
+inline angle::Result LinkEventDone::wait(const gl::Context *context)
+{
+ return mResult;
+}
+inline bool LinkEventDone::isLinking()
+{
+ return false;
+}
+
+class ProgramImpl : angle::NonCopyable
+{
+ public:
+ ProgramImpl(const gl::ProgramState &state) : mState(state) {}
+ virtual ~ProgramImpl() {}
+ virtual void destroy(const gl::Context *context) {}
+
+ virtual std::unique_ptr<LinkEvent> load(const gl::Context *context,
+ gl::BinaryInputStream *stream,
+ gl::InfoLog &infoLog) = 0;
+ virtual void save(const gl::Context *context, gl::BinaryOutputStream *stream) = 0;
+ virtual void setBinaryRetrievableHint(bool retrievable) = 0;
+ virtual void setSeparable(bool separable) = 0;
+
+ virtual std::unique_ptr<LinkEvent> link(const gl::Context *context,
+ const gl::ProgramLinkedResources &resources,
+ gl::InfoLog &infoLog,
+ const gl::ProgramMergedVaryings &mergedVaryings) = 0;
+ virtual GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) = 0;
+
+ virtual void setUniform1fv(GLint location, GLsizei count, const GLfloat *v) = 0;
+ virtual void setUniform2fv(GLint location, GLsizei count, const GLfloat *v) = 0;
+ virtual void setUniform3fv(GLint location, GLsizei count, const GLfloat *v) = 0;
+ virtual void setUniform4fv(GLint location, GLsizei count, const GLfloat *v) = 0;
+ virtual void setUniform1iv(GLint location, GLsizei count, const GLint *v) = 0;
+ virtual void setUniform2iv(GLint location, GLsizei count, const GLint *v) = 0;
+ virtual void setUniform3iv(GLint location, GLsizei count, const GLint *v) = 0;
+ virtual void setUniform4iv(GLint location, GLsizei count, const GLint *v) = 0;
+ virtual void setUniform1uiv(GLint location, GLsizei count, const GLuint *v) = 0;
+ virtual void setUniform2uiv(GLint location, GLsizei count, const GLuint *v) = 0;
+ virtual void setUniform3uiv(GLint location, GLsizei count, const GLuint *v) = 0;
+ virtual void setUniform4uiv(GLint location, GLsizei count, const GLuint *v) = 0;
+ virtual void setUniformMatrix2fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value) = 0;
+ virtual void setUniformMatrix3fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value) = 0;
+ virtual void setUniformMatrix4fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value) = 0;
+ virtual void setUniformMatrix2x3fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value) = 0;
+ virtual void setUniformMatrix3x2fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value) = 0;
+ virtual void setUniformMatrix2x4fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value) = 0;
+ virtual void setUniformMatrix4x2fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value) = 0;
+ virtual void setUniformMatrix3x4fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value) = 0;
+ virtual void setUniformMatrix4x3fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value) = 0;
+
+ // Done in the back-end to avoid having to keep a system copy of uniform data.
+ virtual void getUniformfv(const gl::Context *context,
+ GLint location,
+ GLfloat *params) const = 0;
+ virtual void getUniformiv(const gl::Context *context, GLint location, GLint *params) const = 0;
+ virtual void getUniformuiv(const gl::Context *context,
+ GLint location,
+ GLuint *params) const = 0;
+
+ // Implementation-specific method for ignoring unreferenced uniforms. Some implementations may
+ // perform more extensive analysis and ignore some locations that ANGLE doesn't detect as
+ // unreferenced. This method is not required to be overriden by a back-end.
+ virtual void markUnusedUniformLocations(std::vector<gl::VariableLocation> *uniformLocations,
+ std::vector<gl::SamplerBinding> *samplerBindings,
+ std::vector<gl::ImageBinding> *imageBindings)
+ {}
+
+ const gl::ProgramState &getState() const { return mState; }
+
+ virtual angle::Result syncState(const gl::Context *context,
+ const gl::Program::DirtyBits &dirtyBits);
+
+ virtual angle::Result onLabelUpdate(const gl::Context *context);
+
+ protected:
+ const gl::ProgramState &mState;
+};
+
+inline angle::Result ProgramImpl::syncState(const gl::Context *context,
+ const gl::Program::DirtyBits &dirtyBits)
+{
+ return angle::Result::Continue;
+}
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_PROGRAMIMPL_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/ProgramPipelineImpl.cpp b/gfx/angle/checkout/src/libANGLE/renderer/ProgramPipelineImpl.cpp
new file mode 100644
index 0000000000..c90fb11da0
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/ProgramPipelineImpl.cpp
@@ -0,0 +1,26 @@
+//
+// Copyright 2022 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.
+//
+
+// ProgramPipelineImpl.cpp: Defines the abstract rx::ProgramPipelineImpl class.
+
+#include "libANGLE/renderer/ProgramPipelineImpl.h"
+
+namespace rx
+{
+
+angle::Result ProgramPipelineImpl::link(const gl::Context *context,
+ const gl::ProgramMergedVaryings &mergedVaryings,
+ const gl::ProgramVaryingPacking &varyingPacking)
+{
+ return angle::Result::Continue;
+}
+
+angle::Result ProgramPipelineImpl::onLabelUpdate(const gl::Context *context)
+{
+ return angle::Result::Continue;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/ProgramPipelineImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/ProgramPipelineImpl.h
new file mode 100644
index 0000000000..7f69571a9f
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/ProgramPipelineImpl.h
@@ -0,0 +1,42 @@
+//
+// Copyright 2017 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.
+//
+
+// ProgramPipelineImpl.h: Defines the abstract rx::ProgramPipelineImpl class.
+
+#ifndef LIBANGLE_RENDERER_PROGRAMPIPELINEIMPL_H_
+#define LIBANGLE_RENDERER_PROGRAMPIPELINEIMPL_H_
+
+#include "common/angleutils.h"
+#include "libANGLE/ProgramPipeline.h"
+
+namespace rx
+{
+class ContextImpl;
+
+class ProgramPipelineImpl : public angle::NonCopyable
+{
+ public:
+ ProgramPipelineImpl(const gl::ProgramPipelineState &state) : mState(state) {}
+ virtual ~ProgramPipelineImpl() {}
+ virtual void destroy(const gl::Context *context) {}
+
+ virtual angle::Result link(const gl::Context *context,
+ const gl::ProgramMergedVaryings &mergedVaryings,
+ const gl::ProgramVaryingPacking &varyingPacking);
+
+ virtual void onProgramUniformUpdate(gl::ShaderType shaderType) {}
+
+ virtual angle::Result onLabelUpdate(const gl::Context *context);
+
+ const gl::ProgramPipelineState &getState() const { return mState; }
+
+ protected:
+ const gl::ProgramPipelineState &mState;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_PROGRAMPIPELINEIMPL_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/QueryImpl.cpp b/gfx/angle/checkout/src/libANGLE/renderer/QueryImpl.cpp
new file mode 100644
index 0000000000..ed9497e2a3
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/QueryImpl.cpp
@@ -0,0 +1,21 @@
+//
+// Copyright 2018 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.
+//
+
+// QueryImpl.cpp: Defines the abstract rx::QueryImpl classes.
+
+#include "libANGLE/renderer/QueryImpl.h"
+
+namespace rx
+{
+
+void QueryImpl::onDestroy(const gl::Context *context) {}
+
+angle::Result QueryImpl::onLabelUpdate(const gl::Context *context)
+{
+ return angle::Result::Continue;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/QueryImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/QueryImpl.h
new file mode 100644
index 0000000000..8e5e351418
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/QueryImpl.h
@@ -0,0 +1,49 @@
+//
+// Copyright 2013 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.
+//
+
+// QueryImpl.h: Defines the abstract rx::QueryImpl class.
+
+#ifndef LIBANGLE_RENDERER_QUERYIMPL_H_
+#define LIBANGLE_RENDERER_QUERYIMPL_H_
+
+#include "common/PackedEnums.h"
+#include "common/angleutils.h"
+#include "libANGLE/Error.h"
+
+namespace gl
+{
+class Context;
+} // namespace gl
+
+namespace rx
+{
+class QueryImpl : angle::NonCopyable
+{
+ public:
+ explicit QueryImpl(gl::QueryType type) : mType(type) {}
+ virtual ~QueryImpl() {}
+
+ virtual void onDestroy(const gl::Context *context);
+
+ virtual angle::Result begin(const gl::Context *context) = 0;
+ virtual angle::Result end(const gl::Context *context) = 0;
+ virtual angle::Result queryCounter(const gl::Context *context) = 0;
+ virtual angle::Result getResult(const gl::Context *context, GLint *params) = 0;
+ virtual angle::Result getResult(const gl::Context *context, GLuint *params) = 0;
+ virtual angle::Result getResult(const gl::Context *context, GLint64 *params) = 0;
+ virtual angle::Result getResult(const gl::Context *context, GLuint64 *params) = 0;
+ virtual angle::Result isResultAvailable(const gl::Context *context, bool *available) = 0;
+
+ virtual angle::Result onLabelUpdate(const gl::Context *context);
+
+ gl::QueryType getType() const { return mType; }
+
+ protected:
+ gl::QueryType mType;
+};
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_QUERYIMPL_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/RenderTargetCache.h b/gfx/angle/checkout/src/libANGLE/renderer/RenderTargetCache.h
new file mode 100644
index 0000000000..ffc2a04492
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/RenderTargetCache.h
@@ -0,0 +1,186 @@
+//
+// Copyright 2018 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.
+//
+// RenderTargetCache:
+// The RenderTargetCache pattern is used in the D3D9, D3D11 and Vulkan back-ends. It is a
+// cache of the various back-end objects (RenderTargets) associated with each Framebuffer
+// attachment, be they Textures, Renderbuffers, or Surfaces. The cache is updated in Framebuffer's
+// syncState method.
+//
+
+#ifndef LIBANGLE_RENDERER_RENDER_TARGET_CACHE_H_
+#define LIBANGLE_RENDERER_RENDER_TARGET_CACHE_H_
+
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/FramebufferAttachment.h"
+
+namespace rx
+{
+
+template <typename RenderTargetT>
+class RenderTargetCache final : angle::NonCopyable
+{
+ public:
+ RenderTargetCache();
+ ~RenderTargetCache();
+
+ // Update all RenderTargets from the dirty bits.
+ angle::Result update(const gl::Context *context,
+ const gl::FramebufferState &state,
+ const gl::Framebuffer::DirtyBits &dirtyBits);
+
+ // Update individual RenderTargets.
+ angle::Result updateReadColorRenderTarget(const gl::Context *context,
+ const gl::FramebufferState &state);
+ angle::Result updateColorRenderTarget(const gl::Context *context,
+ const gl::FramebufferState &state,
+ size_t colorIndex);
+ angle::Result updateDepthStencilRenderTarget(const gl::Context *context,
+ const gl::FramebufferState &state);
+
+ using RenderTargetArray = gl::AttachmentArray<RenderTargetT *>;
+
+ const RenderTargetArray &getColors() const;
+ RenderTargetT *getDepthStencil() const;
+
+ RenderTargetT *getColorDraw(const gl::FramebufferState &state, size_t colorIndex) const;
+ RenderTargetT *getColorRead(const gl::FramebufferState &state) const;
+
+ private:
+ angle::Result updateCachedRenderTarget(const gl::Context *context,
+ const gl::FramebufferAttachment *attachment,
+ RenderTargetT **cachedRenderTarget);
+
+ RenderTargetT *mReadRenderTarget = nullptr;
+ gl::AttachmentArray<RenderTargetT *> mColorRenderTargets = {};
+ // We only support a single Depth/Stencil RenderTarget currently.
+ RenderTargetT *mDepthStencilRenderTarget = nullptr;
+};
+
+template <typename RenderTargetT>
+RenderTargetCache<RenderTargetT>::RenderTargetCache() = default;
+
+template <typename RenderTargetT>
+RenderTargetCache<RenderTargetT>::~RenderTargetCache() = default;
+
+template <typename RenderTargetT>
+angle::Result RenderTargetCache<RenderTargetT>::update(const gl::Context *context,
+ const gl::FramebufferState &state,
+ const gl::Framebuffer::DirtyBits &dirtyBits)
+{
+ for (auto dirtyBit : dirtyBits)
+ {
+ switch (dirtyBit)
+ {
+ case gl::Framebuffer::DIRTY_BIT_DEPTH_ATTACHMENT:
+ case gl::Framebuffer::DIRTY_BIT_STENCIL_ATTACHMENT:
+ ANGLE_TRY(updateDepthStencilRenderTarget(context, state));
+ break;
+ case gl::Framebuffer::DIRTY_BIT_READ_BUFFER:
+ ANGLE_TRY(updateReadColorRenderTarget(context, state));
+ break;
+ case gl::Framebuffer::DIRTY_BIT_DRAW_BUFFERS:
+ case gl::Framebuffer::DIRTY_BIT_DEFAULT_WIDTH:
+ case gl::Framebuffer::DIRTY_BIT_DEFAULT_HEIGHT:
+ case gl::Framebuffer::DIRTY_BIT_DEFAULT_SAMPLES:
+ case gl::Framebuffer::DIRTY_BIT_DEFAULT_FIXED_SAMPLE_LOCATIONS:
+ break;
+ default:
+ {
+ static_assert(gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0 == 0, "FB dirty bits");
+ if (dirtyBit < gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_MAX)
+ {
+ size_t colorIndex = static_cast<size_t>(
+ dirtyBit - gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0);
+ ANGLE_TRY(updateColorRenderTarget(context, state, colorIndex));
+ }
+ break;
+ }
+ }
+ }
+
+ return angle::Result::Continue;
+}
+
+template <typename RenderTargetT>
+const gl::AttachmentArray<RenderTargetT *> &RenderTargetCache<RenderTargetT>::getColors() const
+{
+ return mColorRenderTargets;
+}
+
+template <typename RenderTargetT>
+RenderTargetT *RenderTargetCache<RenderTargetT>::getDepthStencil() const
+{
+ return mDepthStencilRenderTarget;
+}
+
+template <typename RenderTargetT>
+angle::Result RenderTargetCache<RenderTargetT>::updateReadColorRenderTarget(
+ const gl::Context *context,
+ const gl::FramebufferState &state)
+{
+ return updateCachedRenderTarget(context, state.getReadAttachment(), &mReadRenderTarget);
+}
+
+template <typename RenderTargetT>
+angle::Result RenderTargetCache<RenderTargetT>::updateColorRenderTarget(
+ const gl::Context *context,
+ const gl::FramebufferState &state,
+ size_t colorIndex)
+{
+ // If the color render target we're updating is also the read buffer, make sure we update the
+ // read render target also so it's not stale.
+ if (state.getReadBufferState() != GL_NONE && state.getReadIndex() == colorIndex)
+ {
+ ANGLE_TRY(updateReadColorRenderTarget(context, state));
+ }
+
+ return updateCachedRenderTarget(context, state.getColorAttachment(colorIndex),
+ &mColorRenderTargets[colorIndex]);
+}
+
+template <typename RenderTargetT>
+angle::Result RenderTargetCache<RenderTargetT>::updateDepthStencilRenderTarget(
+ const gl::Context *context,
+ const gl::FramebufferState &state)
+{
+ return updateCachedRenderTarget(context, state.getDepthOrStencilAttachment(),
+ &mDepthStencilRenderTarget);
+}
+
+template <typename RenderTargetT>
+angle::Result RenderTargetCache<RenderTargetT>::updateCachedRenderTarget(
+ const gl::Context *context,
+ const gl::FramebufferAttachment *attachment,
+ RenderTargetT **cachedRenderTarget)
+{
+ RenderTargetT *newRenderTarget = nullptr;
+ if (attachment)
+ {
+ ASSERT(attachment->isAttached());
+ ANGLE_TRY(attachment->getRenderTarget(context, attachment->getRenderToTextureSamples(),
+ &newRenderTarget));
+ }
+ *cachedRenderTarget = newRenderTarget;
+ return angle::Result::Continue;
+}
+
+template <typename RenderTargetT>
+RenderTargetT *RenderTargetCache<RenderTargetT>::getColorDraw(const gl::FramebufferState &state,
+ size_t colorIndex) const
+{
+ return mColorRenderTargets[colorIndex];
+}
+
+template <typename RenderTargetT>
+RenderTargetT *RenderTargetCache<RenderTargetT>::getColorRead(
+ const gl::FramebufferState &state) const
+{
+ return mReadRenderTarget;
+}
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_RENDER_TARGET_CACHE_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/RenderbufferImpl.cpp b/gfx/angle/checkout/src/libANGLE/renderer/RenderbufferImpl.cpp
new file mode 100644
index 0000000000..c25f87e13e
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/RenderbufferImpl.cpp
@@ -0,0 +1,19 @@
+//
+// Copyright 2022 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.
+//
+
+// RenderbufferImpl.cpp: Defines the abstract rx::RenderbufferImpl class.
+
+#include "libANGLE/renderer/RenderbufferImpl.h"
+
+namespace rx
+{
+
+angle::Result RenderbufferImpl::onLabelUpdate(const gl::Context *context)
+{
+ return angle::Result::Continue;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/RenderbufferImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/RenderbufferImpl.h
new file mode 100644
index 0000000000..94dd7b9da7
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/RenderbufferImpl.h
@@ -0,0 +1,164 @@
+//
+// 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.
+//
+
+// RenderbufferImpl.h: Defines the abstract class gl::RenderbufferImpl
+
+#ifndef LIBANGLE_RENDERER_RENDERBUFFERIMPL_H_
+#define LIBANGLE_RENDERER_RENDERBUFFERIMPL_H_
+
+#include "angle_gl.h"
+#include "common/angleutils.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/renderer/FramebufferAttachmentObjectImpl.h"
+
+namespace gl
+{
+struct PixelPackState;
+class RenderbufferState;
+} // namespace gl
+
+namespace egl
+{
+class Image;
+} // namespace egl
+
+namespace rx
+{
+
+class RenderbufferImpl : public FramebufferAttachmentObjectImpl
+{
+ public:
+ RenderbufferImpl(const gl::RenderbufferState &state) : mState(state) {}
+ ~RenderbufferImpl() override {}
+ virtual void onDestroy(const gl::Context *context) {}
+
+ virtual angle::Result setStorage(const gl::Context *context,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height) = 0;
+ virtual angle::Result setStorageMultisample(const gl::Context *context,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ gl::MultisamplingMode mode) = 0;
+ virtual angle::Result setStorageEGLImageTarget(const gl::Context *context,
+ egl::Image *image) = 0;
+
+ virtual angle::Result copyRenderbufferSubData(const gl::Context *context,
+ const gl::Renderbuffer *srcBuffer,
+ GLint srcLevel,
+ GLint srcX,
+ GLint srcY,
+ GLint srcZ,
+ GLint dstLevel,
+ GLint dstX,
+ GLint dstY,
+ GLint dstZ,
+ GLsizei srcWidth,
+ GLsizei srcHeight,
+ GLsizei srcDepth);
+
+ virtual angle::Result copyTextureSubData(const gl::Context *context,
+ const gl::Texture *srcTexture,
+ GLint srcLevel,
+ GLint srcX,
+ GLint srcY,
+ GLint srcZ,
+ GLint dstLevel,
+ GLint dstX,
+ GLint dstY,
+ GLint dstZ,
+ GLsizei srcWidth,
+ GLsizei srcHeight,
+ GLsizei srcDepth);
+
+ virtual GLenum getColorReadFormat(const gl::Context *context);
+ virtual GLenum getColorReadType(const gl::Context *context);
+
+ virtual angle::Result getRenderbufferImage(const gl::Context *context,
+ const gl::PixelPackState &packState,
+ gl::Buffer *packBuffer,
+ GLenum format,
+ GLenum type,
+ void *pixels);
+
+ // Override if accurate native memory size information is available
+ virtual GLint getMemorySize() const;
+
+ virtual angle::Result onLabelUpdate(const gl::Context *context);
+
+ protected:
+ const gl::RenderbufferState &mState;
+};
+
+inline angle::Result RenderbufferImpl::copyRenderbufferSubData(const gl::Context *context,
+ const gl::Renderbuffer *srcBuffer,
+ GLint srcLevel,
+ GLint srcX,
+ GLint srcY,
+ GLint srcZ,
+ GLint dstLevel,
+ GLint dstX,
+ GLint dstY,
+ GLint dstZ,
+ GLsizei srcWidth,
+ GLsizei srcHeight,
+ GLsizei srcDepth)
+{
+ UNREACHABLE();
+ return angle::Result::Stop;
+}
+
+inline angle::Result RenderbufferImpl::copyTextureSubData(const gl::Context *context,
+ const gl::Texture *srcTexture,
+ GLint srcLevel,
+ GLint srcX,
+ GLint srcY,
+ GLint srcZ,
+ GLint dstLevel,
+ GLint dstX,
+ GLint dstY,
+ GLint dstZ,
+ GLsizei srcWidth,
+ GLsizei srcHeight,
+ GLsizei srcDepth)
+{
+ UNREACHABLE();
+ return angle::Result::Stop;
+}
+
+inline GLint RenderbufferImpl::getMemorySize() const
+{
+ return 0;
+}
+
+inline GLenum RenderbufferImpl::getColorReadFormat(const gl::Context *context)
+{
+ UNREACHABLE();
+ return GL_NONE;
+}
+
+inline GLenum RenderbufferImpl::getColorReadType(const gl::Context *context)
+{
+ UNREACHABLE();
+ return GL_NONE;
+}
+
+inline angle::Result RenderbufferImpl::getRenderbufferImage(const gl::Context *context,
+ const gl::PixelPackState &packState,
+ gl::Buffer *packBuffer,
+ GLenum format,
+ GLenum type,
+ void *pixels)
+{
+ UNREACHABLE();
+ return angle::Result::Stop;
+}
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_RENDERBUFFERIMPL_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/SamplerImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/SamplerImpl.h
new file mode 100644
index 0000000000..2d0af8b0cc
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/SamplerImpl.h
@@ -0,0 +1,44 @@
+//
+// 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.
+//
+
+// SamplerImpl.h: Defines the abstract rx::SamplerImpl class.
+
+#ifndef LIBANGLE_RENDERER_SAMPLERIMPL_H_
+#define LIBANGLE_RENDERER_SAMPLERIMPL_H_
+
+#include "common/angleutils.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/Sampler.h"
+
+namespace gl
+{
+class Context;
+class SamplerState;
+} // namespace gl
+
+namespace rx
+{
+
+class SamplerImpl : angle::NonCopyable
+{
+ public:
+ SamplerImpl(const gl::SamplerState &state) : mState(state) {}
+ virtual ~SamplerImpl() {}
+
+ virtual void onDestroy(const gl::Context *context)
+ {
+ // Default implementation: no-op.
+ }
+ virtual angle::Result syncState(const gl::Context *context, const bool dirty) = 0;
+
+ angle::Result onLabelUpdate(const gl::Context *context) { return angle::Result::Continue; }
+
+ protected:
+ const gl::SamplerState &mState;
+};
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_SAMPLERIMPL_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/SemaphoreImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/SemaphoreImpl.h
new file mode 100644
index 0000000000..5beeba0d0a
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/SemaphoreImpl.h
@@ -0,0 +1,50 @@
+//
+// Copyright 2019 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.
+//
+// SemaphoreImpl.h: Implements the rx::SemaphoreImpl class [EXT_external_objects]
+
+#ifndef LIBANGLE_RENDERER_SEMAPHOREIMPL_H_
+#define LIBANGLE_RENDERER_SEMAPHOREIMPL_H_
+
+#include "angle_gl.h"
+#include "common/PackedEnums.h"
+#include "common/angleutils.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/angletypes.h"
+
+namespace gl
+{
+class Context;
+class Semaphore;
+} // namespace gl
+
+namespace rx
+{
+
+class SemaphoreImpl : angle::NonCopyable
+{
+ public:
+ virtual ~SemaphoreImpl() {}
+
+ virtual void onDestroy(const gl::Context *context) = 0;
+
+ virtual angle::Result importFd(gl::Context *context, gl::HandleType handleType, GLint fd) = 0;
+
+ virtual angle::Result importZirconHandle(gl::Context *context,
+ gl::HandleType handleType,
+ GLuint handle) = 0;
+
+ virtual angle::Result wait(gl::Context *context,
+ const gl::BufferBarrierVector &bufferBarriers,
+ const gl::TextureBarrierVector &textureBarriers) = 0;
+
+ virtual angle::Result signal(gl::Context *context,
+ const gl::BufferBarrierVector &bufferBarriers,
+ const gl::TextureBarrierVector &textureBarriers) = 0;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_SEMAPHOREIMPL_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/ShaderImpl.cpp b/gfx/angle/checkout/src/libANGLE/renderer/ShaderImpl.cpp
new file mode 100644
index 0000000000..eb20adcfde
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/ShaderImpl.cpp
@@ -0,0 +1,105 @@
+//
+// Copyright 2019 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.
+//
+
+// ShaderImpl.cpp: Implementation methods of ShaderImpl
+
+#include "libANGLE/renderer/ShaderImpl.h"
+
+#include "libANGLE/Context.h"
+#include "libANGLE/trace.h"
+
+namespace rx
+{
+
+WaitableCompileEvent::WaitableCompileEvent(std::shared_ptr<angle::WaitableEvent> waitableEvent)
+ : mWaitableEvent(waitableEvent)
+{}
+
+WaitableCompileEvent::~WaitableCompileEvent()
+{
+ mWaitableEvent.reset();
+}
+
+void WaitableCompileEvent::wait()
+{
+ mWaitableEvent->wait();
+}
+
+bool WaitableCompileEvent::isReady()
+{
+ return mWaitableEvent->isReady();
+}
+
+const std::string &WaitableCompileEvent::getInfoLog()
+{
+ return mInfoLog;
+}
+
+class TranslateTask : public angle::Closure
+{
+ public:
+ TranslateTask(ShHandle handle, const ShCompileOptions &options, const std::string &source)
+ : mHandle(handle), mOptions(options), mSource(source), mResult(false)
+ {}
+
+ void operator()() override
+ {
+ ANGLE_TRACE_EVENT1("gpu.angle", "TranslateTask::run", "source", mSource);
+ const char *source = mSource.c_str();
+ mResult = sh::Compile(mHandle, &source, 1, mOptions);
+ }
+
+ bool getResult() { return mResult; }
+
+ ShHandle getHandle() { return mHandle; }
+
+ private:
+ ShHandle mHandle;
+ ShCompileOptions mOptions;
+ std::string mSource;
+ bool mResult;
+};
+
+class WaitableCompileEventImpl final : public WaitableCompileEvent
+{
+ public:
+ WaitableCompileEventImpl(std::shared_ptr<angle::WaitableEvent> waitableEvent,
+ std::shared_ptr<TranslateTask> translateTask)
+ : WaitableCompileEvent(waitableEvent), mTranslateTask(translateTask)
+ {}
+
+ bool getResult() override { return mTranslateTask->getResult(); }
+
+ bool postTranslate(std::string *infoLog) override { return true; }
+
+ private:
+ std::shared_ptr<TranslateTask> mTranslateTask;
+};
+
+std::shared_ptr<WaitableCompileEvent> ShaderImpl::compileImpl(
+ const gl::Context *context,
+ gl::ShCompilerInstance *compilerInstance,
+ const std::string &source,
+ ShCompileOptions *compileOptions)
+{
+#if defined(ANGLE_ENABLE_ASSERTS)
+ compileOptions->validateAST = true;
+#endif
+
+ auto workerThreadPool = context->getShaderCompileThreadPool();
+ auto translateTask =
+ std::make_shared<TranslateTask>(compilerInstance->getHandle(), *compileOptions, source);
+
+ return std::make_shared<WaitableCompileEventImpl>(
+ angle::WorkerThreadPool::PostWorkerTask(workerThreadPool, translateTask), translateTask);
+}
+
+angle::Result ShaderImpl::onLabelUpdate(const gl::Context *context)
+{
+ return angle::Result::Continue;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/ShaderImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/ShaderImpl.h
new file mode 100644
index 0000000000..be50cc754b
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/ShaderImpl.h
@@ -0,0 +1,77 @@
+//
+// 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.
+//
+
+// ShaderImpl.h: Defines the abstract rx::ShaderImpl class.
+
+#ifndef LIBANGLE_RENDERER_SHADERIMPL_H_
+#define LIBANGLE_RENDERER_SHADERIMPL_H_
+
+#include <functional>
+
+#include "common/angleutils.h"
+#include "libANGLE/Shader.h"
+#include "libANGLE/WorkerThread.h"
+
+namespace gl
+{
+class ShCompilerInstance;
+} // namespace gl
+
+namespace rx
+{
+
+using UpdateShaderStateFunctor = std::function<void(bool compiled, ShHandle handle)>;
+class WaitableCompileEvent : public angle::WaitableEvent
+{
+ public:
+ WaitableCompileEvent(std::shared_ptr<angle::WaitableEvent> waitableEvent);
+ ~WaitableCompileEvent() override;
+
+ void wait() override;
+
+ bool isReady() override;
+
+ virtual bool getResult() = 0;
+
+ virtual bool postTranslate(std::string *infoLog) = 0;
+
+ const std::string &getInfoLog();
+
+ protected:
+ std::shared_ptr<angle::WaitableEvent> mWaitableEvent;
+ std::string mInfoLog;
+};
+
+class ShaderImpl : angle::NonCopyable
+{
+ public:
+ ShaderImpl(const gl::ShaderState &state) : mState(state) {}
+ virtual ~ShaderImpl() {}
+
+ virtual void destroy() {}
+
+ virtual std::shared_ptr<WaitableCompileEvent> compile(const gl::Context *context,
+ gl::ShCompilerInstance *compilerInstance,
+ ShCompileOptions *options) = 0;
+
+ virtual std::string getDebugInfo() const = 0;
+
+ const gl::ShaderState &getState() const { return mState; }
+
+ virtual angle::Result onLabelUpdate(const gl::Context *context);
+
+ protected:
+ std::shared_ptr<WaitableCompileEvent> compileImpl(const gl::Context *context,
+ gl::ShCompilerInstance *compilerInstance,
+ const std::string &source,
+ ShCompileOptions *compileOptions);
+
+ const gl::ShaderState &mState;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_SHADERIMPL_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/StreamProducerImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/StreamProducerImpl.h
new file mode 100644
index 0000000000..e4a65e2812
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/StreamProducerImpl.h
@@ -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.
+//
+
+// StreamProducerImpl.h: Defines the abstract rx::StreamProducerImpl class.
+
+#ifndef LIBANGLE_RENDERER_STREAMPRODUCERIMPL_H_
+#define LIBANGLE_RENDERER_STREAMPRODUCERIMPL_H_
+
+#include "common/angleutils.h"
+#include "libANGLE/Stream.h"
+
+namespace rx
+{
+
+class StreamProducerImpl : angle::NonCopyable
+{
+ public:
+ explicit StreamProducerImpl() {}
+ virtual ~StreamProducerImpl() {}
+
+ // Validates the ability for the producer to accept an arbitrary pointer to a frame. All
+ // pointers should be validated through this function before being used to produce a frame.
+ virtual egl::Error validateD3DTexture(const void *pointer,
+ const egl::AttributeMap &attributes) const = 0;
+
+ // Constructs a frame from an arbitrary external pointer that points to producer specific frame
+ // data. Replaces the internal frame with the new one.
+ virtual void postD3DTexture(void *pointer, const egl::AttributeMap &attributes) = 0;
+
+ // Returns an OpenGL texture interpretation of some frame attributes for the purpose of
+ // constructing an OpenGL texture from a frame. Depending on the producer and consumer, some
+ // frames may have multiple "planes" with different OpenGL texture representations.
+ virtual egl::Stream::GLTextureDescription getGLFrameDescription(int planeIndex) = 0;
+};
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_STREAMPRODUCERIMPL_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/SurfaceImpl.cpp b/gfx/angle/checkout/src/libANGLE/renderer/SurfaceImpl.cpp
new file mode 100644
index 0000000000..469ef6119f
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/SurfaceImpl.cpp
@@ -0,0 +1,158 @@
+//
+// Copyright 2002 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.
+//
+
+// SurfaceImpl.cpp: Implementation of Surface stub method class
+
+#include "libANGLE/renderer/SurfaceImpl.h"
+
+namespace rx
+{
+
+SurfaceImpl::SurfaceImpl(const egl::SurfaceState &state) : mState(state) {}
+
+SurfaceImpl::~SurfaceImpl() {}
+
+egl::Error SurfaceImpl::makeCurrent(const gl::Context *context)
+{
+ return egl::NoError();
+}
+
+egl::Error SurfaceImpl::unMakeCurrent(const gl::Context *context)
+{
+ return egl::NoError();
+}
+
+egl::Error SurfaceImpl::prepareSwap(const gl::Context *)
+{
+ return angle::ResultToEGL(angle::Result::Continue);
+}
+
+egl::Error SurfaceImpl::swapWithDamage(const gl::Context *context,
+ const EGLint *rects,
+ EGLint n_rects)
+{
+ UNREACHABLE();
+ return egl::EglBadSurface() << "swapWithDamage implementation missing.";
+}
+
+egl::Error SurfaceImpl::setPresentationTime(EGLnsecsANDROID time)
+{
+ UNREACHABLE();
+ return egl::EglBadSurface() << "setPresentationTime implementation missing.";
+}
+
+void SurfaceImpl::setFixedWidth(EGLint width)
+{
+ UNREACHABLE();
+}
+
+void SurfaceImpl::setFixedHeight(EGLint height)
+{
+ UNREACHABLE();
+}
+
+void SurfaceImpl::setTimestampsEnabled(bool enabled)
+{
+ UNREACHABLE();
+}
+
+const angle::Format *SurfaceImpl::getD3DTextureColorFormat() const
+{
+ UNREACHABLE();
+ return nullptr;
+}
+
+egl::SupportedCompositorTimings SurfaceImpl::getSupportedCompositorTimings() const
+{
+ UNREACHABLE();
+ return egl::SupportedCompositorTimings();
+}
+
+egl::Error SurfaceImpl::getCompositorTiming(EGLint numTimestamps,
+ const EGLint *names,
+ EGLnsecsANDROID *values) const
+{
+ UNREACHABLE();
+ return egl::EglBadDisplay();
+}
+
+egl::Error SurfaceImpl::getNextFrameId(EGLuint64KHR *frameId) const
+{
+ UNREACHABLE();
+ return egl::EglBadDisplay();
+}
+
+egl::SupportedTimestamps SurfaceImpl::getSupportedTimestamps() const
+{
+ UNREACHABLE();
+ return egl::SupportedTimestamps();
+}
+
+egl::Error SurfaceImpl::getFrameTimestamps(EGLuint64KHR frameId,
+ EGLint numTimestamps,
+ const EGLint *timestamps,
+ EGLnsecsANDROID *values) const
+{
+ UNREACHABLE();
+ return egl::EglBadDisplay();
+}
+
+egl::Error SurfaceImpl::swapWithFrameToken(const gl::Context *context,
+ EGLFrameTokenANGLE frameToken)
+{
+ UNREACHABLE();
+ return egl::EglBadDisplay();
+}
+
+egl::Error SurfaceImpl::getUserWidth(const egl::Display *display, EGLint *value) const
+{
+ *value = getWidth();
+ return egl::NoError();
+}
+
+egl::Error SurfaceImpl::getUserHeight(const egl::Display *display, EGLint *value) const
+{
+ *value = getHeight();
+ return egl::NoError();
+}
+
+egl::Error SurfaceImpl::getBufferAge(const gl::Context *context, EGLint *age)
+{
+ *age = 0;
+ return egl::NoError();
+}
+
+egl::Error SurfaceImpl::setAutoRefreshEnabled(bool enabled)
+{
+ return egl::EglBadMatch();
+}
+
+egl::Error SurfaceImpl::lockSurface(const egl::Display *display,
+ EGLint usageHint,
+ bool preservePixels,
+ uint8_t **bufferPtrOut,
+ EGLint *bufferPitchOut)
+{
+ UNREACHABLE();
+ return egl::EglBadMatch();
+}
+
+egl::Error SurfaceImpl::unlockSurface(const egl::Display *display, bool preservePixels)
+{
+ UNREACHABLE();
+ return egl::EglBadMatch();
+}
+
+EGLint SurfaceImpl::origin() const
+{
+ return EGL_LOWER_LEFT_KHR;
+}
+
+egl::Error SurfaceImpl::setRenderBuffer(EGLint renderBuffer)
+{
+ return egl::NoError();
+}
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/SurfaceImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/SurfaceImpl.h
new file mode 100644
index 0000000000..95952d096c
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/SurfaceImpl.h
@@ -0,0 +1,136 @@
+//
+// 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.
+//
+
+// SurfaceImpl.h: Implementation methods of egl::Surface
+
+#ifndef LIBANGLE_RENDERER_SURFACEIMPL_H_
+#define LIBANGLE_RENDERER_SURFACEIMPL_H_
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include "common/angleutils.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/renderer/FramebufferAttachmentObjectImpl.h"
+
+namespace angle
+{
+struct Format;
+}
+
+namespace gl
+{
+class Context;
+class FramebufferState;
+} // namespace gl
+
+namespace egl
+{
+class Display;
+struct Config;
+struct SurfaceState;
+class Thread;
+
+using SupportedTimestamps = angle::PackedEnumBitSet<Timestamp>;
+using SupportedCompositorTimings = angle::PackedEnumBitSet<CompositorTiming>;
+} // namespace egl
+
+namespace rx
+{
+class SurfaceImpl : public FramebufferAttachmentObjectImpl
+{
+ public:
+ SurfaceImpl(const egl::SurfaceState &surfaceState);
+ ~SurfaceImpl() override;
+ virtual void destroy(const egl::Display *display) {}
+
+ virtual egl::Error initialize(const egl::Display *display) = 0;
+ virtual egl::Error makeCurrent(const gl::Context *context);
+ virtual egl::Error unMakeCurrent(const gl::Context *context);
+ virtual egl::Error prepareSwap(const gl::Context *);
+ virtual egl::Error swap(const gl::Context *context) = 0;
+ virtual egl::Error swapWithDamage(const gl::Context *context,
+ const EGLint *rects,
+ EGLint n_rects);
+ virtual egl::Error swapWithFrameToken(const gl::Context *context,
+ EGLFrameTokenANGLE frameToken);
+ virtual egl::Error postSubBuffer(const gl::Context *context,
+ EGLint x,
+ EGLint y,
+ EGLint width,
+ EGLint height) = 0;
+ virtual egl::Error setPresentationTime(EGLnsecsANDROID time);
+ virtual egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) = 0;
+ virtual egl::Error bindTexImage(const gl::Context *context,
+ gl::Texture *texture,
+ EGLint buffer) = 0;
+ virtual egl::Error releaseTexImage(const gl::Context *context, EGLint buffer) = 0;
+ virtual egl::Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) = 0;
+ virtual egl::Error getMscRate(EGLint *numerator, EGLint *denominator) = 0;
+ virtual void setSwapInterval(EGLint interval) = 0;
+ virtual void setFixedWidth(EGLint width);
+ virtual void setFixedHeight(EGLint height);
+
+ // width and height can change with client window resizing
+ virtual EGLint getWidth() const = 0;
+ virtual EGLint getHeight() const = 0;
+ // Note: windows cannot be resized on Android. The approach requires
+ // calling vkGetPhysicalDeviceSurfaceCapabilitiesKHR. However, that is
+ // expensive; and there are troublesome timing issues for other parts of
+ // ANGLE (which cause test failures and crashes). Therefore, a
+ // special-Android-only path is created just for the querying of EGL_WIDTH
+ // and EGL_HEIGHT.
+ // https://issuetracker.google.com/issues/153329980
+ virtual egl::Error getUserWidth(const egl::Display *display, EGLint *value) const;
+ virtual egl::Error getUserHeight(const egl::Display *display, EGLint *value) const;
+
+ virtual EGLint isPostSubBufferSupported() const = 0;
+ virtual EGLint getSwapBehavior() const = 0;
+
+ virtual egl::Error attachToFramebuffer(const gl::Context *context,
+ gl::Framebuffer *framebuffer) = 0;
+ virtual egl::Error detachFromFramebuffer(const gl::Context *context,
+ gl::Framebuffer *framebuffer) = 0;
+
+ // Used to query color format from pbuffers created from D3D textures.
+ virtual const angle::Format *getD3DTextureColorFormat() const;
+
+ // EGL_ANDROID_get_frame_timestamps
+ virtual void setTimestampsEnabled(bool enabled);
+ virtual egl::SupportedCompositorTimings getSupportedCompositorTimings() const;
+ virtual egl::Error getCompositorTiming(EGLint numTimestamps,
+ const EGLint *names,
+ EGLnsecsANDROID *values) const;
+ virtual egl::Error getNextFrameId(EGLuint64KHR *frameId) const;
+ virtual egl::SupportedTimestamps getSupportedTimestamps() const;
+ virtual egl::Error getFrameTimestamps(EGLuint64KHR frameId,
+ EGLint numTimestamps,
+ const EGLint *timestamps,
+ EGLnsecsANDROID *values) const;
+ virtual egl::Error getBufferAge(const gl::Context *context, EGLint *age);
+
+ // EGL_ANDROID_front_buffer_auto_refresh
+ virtual egl::Error setAutoRefreshEnabled(bool enabled);
+
+ // EGL_KHR_lock_surface3
+ virtual egl::Error lockSurface(const egl::Display *display,
+ EGLint usageHint,
+ bool preservePixels,
+ uint8_t **bufferPtrOut,
+ EGLint *bufferPitchOut);
+ virtual egl::Error unlockSurface(const egl::Display *display, bool preservePixels);
+ virtual EGLint origin() const;
+
+ virtual egl::Error setRenderBuffer(EGLint renderBuffer);
+
+ protected:
+ const egl::SurfaceState &mState;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_SURFACEIMPL_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/SyncImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/SyncImpl.h
new file mode 100644
index 0000000000..59811a62d7
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/SyncImpl.h
@@ -0,0 +1,45 @@
+//
+// 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.
+//
+
+// SyncImpl.h: Defines the rx::SyncImpl class.
+
+#ifndef LIBANGLE_RENDERER_FENCESYNCIMPL_H_
+#define LIBANGLE_RENDERER_FENCESYNCIMPL_H_
+
+#include "libANGLE/Error.h"
+
+#include "common/angleutils.h"
+
+#include "angle_gl.h"
+
+namespace gl
+{
+class Context;
+} // namespace gl
+
+namespace rx
+{
+class SyncImpl : angle::NonCopyable
+{
+ public:
+ SyncImpl() {}
+ virtual ~SyncImpl() {}
+
+ virtual void onDestroy(const gl::Context *context) {}
+
+ virtual angle::Result set(const gl::Context *context, GLenum condition, GLbitfield flags) = 0;
+ virtual angle::Result clientWait(const gl::Context *context,
+ GLbitfield flags,
+ GLuint64 timeout,
+ GLenum *outResult) = 0;
+ virtual angle::Result serverWait(const gl::Context *context,
+ GLbitfield flags,
+ GLuint64 timeout) = 0;
+ virtual angle::Result getStatus(const gl::Context *context, GLint *outResult) = 0;
+};
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_FENCESYNCIMPL_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/TextureImpl.cpp b/gfx/angle/checkout/src/libANGLE/renderer/TextureImpl.cpp
new file mode 100644
index 0000000000..7e69330e27
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/TextureImpl.cpp
@@ -0,0 +1,200 @@
+//
+// 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() {}
+
+void TextureImpl::onDestroy(const gl::Context *context) {}
+
+angle::Result TextureImpl::copyTexture(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLenum internalFormat,
+ GLenum type,
+ GLint sourceLevel,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha,
+ const gl::Texture *source)
+{
+ UNREACHABLE();
+ return angle::Result::Stop;
+}
+
+angle::Result TextureImpl::copySubTexture(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Offset &destOffset,
+ GLint sourceLevel,
+ const gl::Box &sourceBox,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha,
+ const gl::Texture *source)
+{
+ UNREACHABLE();
+ return angle::Result::Stop;
+}
+
+angle::Result TextureImpl::copyRenderbufferSubData(const gl::Context *context,
+ const gl::Renderbuffer *srcBuffer,
+ GLint srcLevel,
+ GLint srcX,
+ GLint srcY,
+ GLint srcZ,
+ GLint dstLevel,
+ GLint dstX,
+ GLint dstY,
+ GLint dstZ,
+ GLsizei srcWidth,
+ GLsizei srcHeight,
+ GLsizei srcDepth)
+{
+ UNREACHABLE();
+ return angle::Result::Stop;
+}
+
+angle::Result TextureImpl::copyTextureSubData(const gl::Context *context,
+ const gl::Texture *srcTexture,
+ GLint srcLevel,
+ GLint srcX,
+ GLint srcY,
+ GLint srcZ,
+ GLint dstLevel,
+ GLint dstX,
+ GLint dstY,
+ GLint dstZ,
+ GLsizei srcWidth,
+ GLsizei srcHeight,
+ GLsizei srcDepth)
+{
+ UNREACHABLE();
+ return angle::Result::Stop;
+}
+
+angle::Result TextureImpl::copyCompressedTexture(const gl::Context *context,
+ const gl::Texture *source)
+{
+ UNREACHABLE();
+ return angle::Result::Stop;
+}
+
+angle::Result TextureImpl::copy3DTexture(const gl::Context *context,
+ gl::TextureTarget target,
+ GLenum internalFormat,
+ GLenum type,
+ GLint sourceLevel,
+ GLint destLevel,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha,
+ const gl::Texture *source)
+{
+ UNREACHABLE();
+ return angle::Result::Stop;
+}
+
+angle::Result TextureImpl::copy3DSubTexture(const gl::Context *context,
+ const gl::TextureTarget target,
+ const gl::Offset &destOffset,
+ GLint sourceLevel,
+ GLint destLevel,
+ const gl::Box &srcBox,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha,
+ const gl::Texture *source)
+{
+ UNREACHABLE();
+ return angle::Result::Stop;
+}
+
+angle::Result TextureImpl::setImageExternal(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLenum internalFormat,
+ const gl::Extents &size,
+ GLenum format,
+ GLenum type)
+{
+ UNREACHABLE();
+ return angle::Result::Stop;
+}
+
+angle::Result TextureImpl::setBuffer(const gl::Context *context, GLenum internalFormat)
+{
+ UNREACHABLE();
+ return angle::Result::Stop;
+}
+
+GLint TextureImpl::getMemorySize() const
+{
+ return 0;
+}
+
+GLint TextureImpl::getLevelMemorySize(gl::TextureTarget target, GLint level)
+{
+ return 0;
+}
+
+GLint TextureImpl::getNativeID() const
+{
+ UNREACHABLE();
+ return 0;
+}
+
+GLenum TextureImpl::getColorReadFormat(const gl::Context *context)
+{
+ UNREACHABLE();
+ return GL_NONE;
+}
+
+GLenum TextureImpl::getColorReadType(const gl::Context *context)
+{
+ UNREACHABLE();
+ return GL_NONE;
+}
+
+angle::Result TextureImpl::getTexImage(const gl::Context *context,
+ const gl::PixelPackState &packState,
+ gl::Buffer *packBuffer,
+ gl::TextureTarget target,
+ GLint level,
+ GLenum format,
+ GLenum type,
+ void *pixels)
+{
+ UNREACHABLE();
+ return angle::Result::Stop;
+}
+
+angle::Result TextureImpl::getCompressedTexImage(const gl::Context *context,
+ const gl::PixelPackState &packState,
+ gl::Buffer *packBuffer,
+ gl::TextureTarget target,
+ GLint level,
+ void *pixels)
+{
+ UNREACHABLE();
+ return angle::Result::Stop;
+}
+
+GLint TextureImpl::getRequiredExternalTextureImageUnits(const gl::Context *context)
+{
+ UNREACHABLE();
+ return 0;
+}
+
+angle::Result TextureImpl::onLabelUpdate(const gl::Context *context)
+{
+ return angle::Result::Continue;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/TextureImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/TextureImpl.h
new file mode 100644
index 0000000000..368fba09c5
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/TextureImpl.h
@@ -0,0 +1,254 @@
+//
+// 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.
+//
+
+// TextureImpl.h: Defines the abstract rx::TextureImpl classes.
+
+#ifndef LIBANGLE_RENDERER_TEXTUREIMPL_H_
+#define LIBANGLE_RENDERER_TEXTUREIMPL_H_
+
+#include <stdint.h>
+
+#include "angle_gl.h"
+#include "common/angleutils.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/ImageIndex.h"
+#include "libANGLE/Stream.h"
+#include "libANGLE/Texture.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/renderer/FramebufferAttachmentObjectImpl.h"
+
+namespace egl
+{
+class Surface;
+class Image;
+} // namespace egl
+
+namespace gl
+{
+class Framebuffer;
+class MemoryObject;
+struct PixelUnpackState;
+class TextureState;
+} // namespace gl
+
+namespace rx
+{
+class ContextImpl;
+
+class TextureImpl : public FramebufferAttachmentObjectImpl
+{
+ public:
+ TextureImpl(const gl::TextureState &state);
+ ~TextureImpl() override;
+
+ virtual void onDestroy(const gl::Context *context);
+
+ virtual angle::Result setImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLenum internalFormat,
+ const gl::Extents &size,
+ GLenum format,
+ GLenum type,
+ const gl::PixelUnpackState &unpack,
+ gl::Buffer *unpackBuffer,
+ const uint8_t *pixels) = 0;
+ virtual angle::Result setSubImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Box &area,
+ GLenum format,
+ GLenum type,
+ const gl::PixelUnpackState &unpack,
+ gl::Buffer *unpackBuffer,
+ const uint8_t *pixels) = 0;
+
+ virtual angle::Result setCompressedImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLenum internalFormat,
+ const gl::Extents &size,
+ const gl::PixelUnpackState &unpack,
+ size_t imageSize,
+ const uint8_t *pixels) = 0;
+ virtual angle::Result setCompressedSubImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Box &area,
+ GLenum format,
+ const gl::PixelUnpackState &unpack,
+ size_t imageSize,
+ const uint8_t *pixels) = 0;
+
+ virtual angle::Result copyImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Rectangle &sourceArea,
+ GLenum internalFormat,
+ gl::Framebuffer *source) = 0;
+ virtual angle::Result copySubImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Offset &destOffset,
+ const gl::Rectangle &sourceArea,
+ gl::Framebuffer *source) = 0;
+
+ virtual angle::Result copyTexture(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLenum internalFormat,
+ GLenum type,
+ GLint sourceLevel,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha,
+ const gl::Texture *source);
+ virtual angle::Result copySubTexture(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Offset &destOffset,
+ GLint sourceLevel,
+ const gl::Box &sourceBox,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha,
+ const gl::Texture *source);
+
+ virtual angle::Result copyRenderbufferSubData(const gl::Context *context,
+ const gl::Renderbuffer *srcBuffer,
+ GLint srcLevel,
+ GLint srcX,
+ GLint srcY,
+ GLint srcZ,
+ GLint dstLevel,
+ GLint dstX,
+ GLint dstY,
+ GLint dstZ,
+ GLsizei srcWidth,
+ GLsizei srcHeight,
+ GLsizei srcDepth);
+
+ virtual angle::Result copyTextureSubData(const gl::Context *context,
+ const gl::Texture *srcTexture,
+ GLint srcLevel,
+ GLint srcX,
+ GLint srcY,
+ GLint srcZ,
+ GLint dstLevel,
+ GLint dstX,
+ GLint dstY,
+ GLint dstZ,
+ GLsizei srcWidth,
+ GLsizei srcHeight,
+ GLsizei srcDepth);
+
+ virtual angle::Result copyCompressedTexture(const gl::Context *context,
+ const gl::Texture *source);
+
+ virtual angle::Result copy3DTexture(const gl::Context *context,
+ gl::TextureTarget target,
+ GLenum internalFormat,
+ GLenum type,
+ GLint sourceLevel,
+ GLint destLevel,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha,
+ const gl::Texture *source);
+ virtual angle::Result copy3DSubTexture(const gl::Context *context,
+ const gl::TextureTarget target,
+ const gl::Offset &destOffset,
+ GLint sourceLevel,
+ GLint destLevel,
+ const gl::Box &srcBox,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha,
+ const gl::Texture *source);
+
+ virtual angle::Result setStorage(const gl::Context *context,
+ gl::TextureType type,
+ size_t levels,
+ GLenum internalFormat,
+ const gl::Extents &size) = 0;
+
+ virtual angle::Result setStorageMultisample(const gl::Context *context,
+ gl::TextureType type,
+ GLsizei samples,
+ GLint internalformat,
+ const gl::Extents &size,
+ bool fixedSampleLocations) = 0;
+
+ virtual angle::Result setStorageExternalMemory(const gl::Context *context,
+ gl::TextureType type,
+ size_t levels,
+ GLenum internalFormat,
+ const gl::Extents &size,
+ gl::MemoryObject *memoryObject,
+ GLuint64 offset,
+ GLbitfield createFlags,
+ GLbitfield usageFlags,
+ const void *imageCreateInfoPNext) = 0;
+
+ virtual angle::Result setImageExternal(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLenum internalFormat,
+ const gl::Extents &size,
+ GLenum format,
+ GLenum type);
+
+ virtual angle::Result setEGLImageTarget(const gl::Context *context,
+ gl::TextureType type,
+ egl::Image *image) = 0;
+
+ virtual angle::Result setImageExternal(const gl::Context *context,
+ gl::TextureType type,
+ egl::Stream *stream,
+ const egl::Stream::GLTextureDescription &desc) = 0;
+
+ virtual angle::Result setBuffer(const gl::Context *context, GLenum internalFormat);
+
+ virtual angle::Result generateMipmap(const gl::Context *context) = 0;
+
+ virtual angle::Result setBaseLevel(const gl::Context *context, GLuint baseLevel) = 0;
+
+ virtual angle::Result bindTexImage(const gl::Context *context, egl::Surface *surface) = 0;
+ virtual angle::Result releaseTexImage(const gl::Context *context) = 0;
+
+ virtual angle::Result onLabelUpdate(const gl::Context *context);
+
+ // Override if accurate native memory size information is available
+ virtual GLint getMemorySize() const;
+ virtual GLint getLevelMemorySize(gl::TextureTarget target, GLint level);
+
+ virtual GLint getNativeID() const;
+
+ virtual angle::Result syncState(const gl::Context *context,
+ const gl::Texture::DirtyBits &dirtyBits,
+ gl::Command source) = 0;
+
+ virtual GLenum getColorReadFormat(const gl::Context *context);
+ virtual GLenum getColorReadType(const gl::Context *context);
+
+ virtual angle::Result getTexImage(const gl::Context *context,
+ const gl::PixelPackState &packState,
+ gl::Buffer *packBuffer,
+ gl::TextureTarget target,
+ GLint level,
+ GLenum format,
+ GLenum type,
+ void *pixels);
+
+ virtual angle::Result getCompressedTexImage(const gl::Context *context,
+ const gl::PixelPackState &packState,
+ gl::Buffer *packBuffer,
+ gl::TextureTarget target,
+ GLint level,
+ void *pixels);
+
+ virtual GLint getRequiredExternalTextureImageUnits(const gl::Context *context);
+
+ const gl::TextureState &getState() const { return mState; }
+
+ protected:
+ const gl::TextureState &mState;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_TEXTUREIMPL_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/TransformFeedbackImpl.cpp b/gfx/angle/checkout/src/libANGLE/renderer/TransformFeedbackImpl.cpp
new file mode 100644
index 0000000000..183c496025
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/TransformFeedbackImpl.cpp
@@ -0,0 +1,19 @@
+//
+// Copyright 2022 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.
+//
+
+// TransformFeedbackImpl.cpp: Defines the abstract rx::TransformFeedbackImpl class.
+
+#include "libANGLE/renderer/TransformFeedbackImpl.h"
+
+namespace rx
+{
+
+angle::Result TransformFeedbackImpl::onLabelUpdate(const gl::Context *context)
+{
+ return angle::Result::Continue;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/TransformFeedbackImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/TransformFeedbackImpl.h
new file mode 100644
index 0000000000..75ef6fdbf8
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/TransformFeedbackImpl.h
@@ -0,0 +1,42 @@
+//
+// 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.
+//
+
+// TransformFeedbackImpl.h: Defines the abstract rx::TransformFeedbackImpl class.
+
+#ifndef LIBANGLE_RENDERER_TRANSFORMFEEDBACKIMPL_H_
+#define LIBANGLE_RENDERER_TRANSFORMFEEDBACKIMPL_H_
+
+#include "common/angleutils.h"
+#include "libANGLE/TransformFeedback.h"
+
+namespace rx
+{
+
+class TransformFeedbackImpl : angle::NonCopyable
+{
+ public:
+ TransformFeedbackImpl(const gl::TransformFeedbackState &state) : mState(state) {}
+ virtual ~TransformFeedbackImpl() {}
+ virtual void onDestroy(const gl::Context *context) {}
+
+ virtual angle::Result begin(const gl::Context *context, gl::PrimitiveMode primitiveMode) = 0;
+ virtual angle::Result end(const gl::Context *context) = 0;
+ virtual angle::Result pause(const gl::Context *context) = 0;
+ virtual angle::Result resume(const gl::Context *context) = 0;
+
+ virtual angle::Result bindIndexedBuffer(
+ const gl::Context *context,
+ size_t index,
+ const gl::OffsetBindingPointer<gl::Buffer> &binding) = 0;
+
+ virtual angle::Result onLabelUpdate(const gl::Context *context);
+
+ protected:
+ const gl::TransformFeedbackState &mState;
+};
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_TRANSFORMFEEDBACKIMPL_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/VertexArrayImpl.cpp b/gfx/angle/checkout/src/libANGLE/renderer/VertexArrayImpl.cpp
new file mode 100644
index 0000000000..b7cac20f78
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/VertexArrayImpl.cpp
@@ -0,0 +1,18 @@
+//
+// Copyright 2022 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.
+//
+// VertexArrayImpl.cpp: Implements the class methods for VertexArrayImpl.
+
+#include "libANGLE/renderer/VertexArrayImpl.h"
+
+namespace rx
+{
+
+angle::Result VertexArrayImpl::onLabelUpdate(const gl::Context *context)
+{
+ return angle::Result::Continue;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/VertexArrayImpl.h b/gfx/angle/checkout/src/libANGLE/renderer/VertexArrayImpl.h
new file mode 100644
index 0000000000..8e33c901c2
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/VertexArrayImpl.h
@@ -0,0 +1,70 @@
+//
+// 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.
+//
+
+// VertexAttribImpl.h: Defines the abstract rx::VertexAttribImpl class.
+
+#ifndef LIBANGLE_RENDERER_VERTEXARRAYIMPL_H_
+#define LIBANGLE_RENDERER_VERTEXARRAYIMPL_H_
+
+#include "common/angleutils.h"
+#include "libANGLE/Buffer.h"
+#include "libANGLE/VertexArray.h"
+
+// This is a helper X macro for iterating over all dirty attribs/bindings. Useful for dirty bits.
+static_assert(gl::MAX_VERTEX_ATTRIBS == 16, "Invalid max vertex attribs");
+static_assert(gl::MAX_VERTEX_ATTRIB_BINDINGS == 16, "Invalid max vertex bindings");
+#define ANGLE_VERTEX_INDEX_CASES(FUNC) \
+ FUNC(0) \
+ FUNC(1) \
+ FUNC(2) \
+ FUNC(3) \
+ FUNC(4) \
+ FUNC(5) FUNC(6) FUNC(7) FUNC(8) FUNC(9) FUNC(10) FUNC(11) FUNC(12) FUNC(13) FUNC(14) FUNC(15)
+
+namespace rx
+{
+class ContextImpl;
+
+class VertexArrayImpl : angle::NonCopyable
+{
+ public:
+ VertexArrayImpl(const gl::VertexArrayState &state) : mState(state) {}
+
+ // It's up to the implementation to reset the attrib and binding dirty bits.
+ // This is faster than the front-end having to clear all the bits after they have been scanned.
+ virtual angle::Result syncState(const gl::Context *context,
+ const gl::VertexArray::DirtyBits &dirtyBits,
+ gl::VertexArray::DirtyAttribBitsArray *attribBits,
+ gl::VertexArray::DirtyBindingBitsArray *bindingBits);
+
+ virtual void destroy(const gl::Context *context) {}
+ virtual ~VertexArrayImpl() {}
+
+ const gl::VertexArrayState &getState() const { return mState; }
+
+ void setContentsObservers(gl::VertexArrayBufferContentsObservers *observers)
+ {
+ mContentsObservers = observers;
+ }
+
+ virtual angle::Result onLabelUpdate(const gl::Context *context);
+
+ protected:
+ const gl::VertexArrayState &mState;
+ gl::VertexArrayBufferContentsObservers *mContentsObservers = nullptr;
+};
+
+inline angle::Result VertexArrayImpl::syncState(const gl::Context *context,
+ const gl::VertexArray::DirtyBits &dirtyBits,
+ gl::VertexArray::DirtyAttribBitsArray *attribBits,
+ gl::VertexArray::DirtyBindingBitsArray *bindingBits)
+{
+ return angle::Result::Continue;
+}
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_VERTEXARRAYIMPL_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/copyvertex.h b/gfx/angle/checkout/src/libANGLE/renderer/copyvertex.h
new file mode 100644
index 0000000000..54624bb29b
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/copyvertex.h
@@ -0,0 +1,80 @@
+//
+// Copyright 2013 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.
+//
+
+// copyvertex.h: Defines vertex buffer copying and conversion functions
+
+#ifndef LIBANGLE_RENDERER_COPYVERTEX_H_
+#define LIBANGLE_RENDERER_COPYVERTEX_H_
+
+#include "common/mathutil.h"
+
+namespace rx
+{
+
+using VertexCopyFunction = void (*)(const uint8_t *input,
+ size_t stride,
+ size_t count,
+ uint8_t *output);
+
+// 'alphaDefaultValueBits' gives the default value for the alpha channel (4th component)
+template <typename T,
+ size_t inputComponentCount,
+ size_t outputComponentCount,
+ uint32_t alphaDefaultValueBits>
+void CopyNativeVertexData(const uint8_t *input, size_t stride, size_t count, uint8_t *output);
+
+template <size_t inputComponentCount, size_t outputComponentCount>
+void Copy8SintTo16SintVertexData(const uint8_t *input,
+ size_t stride,
+ size_t count,
+ uint8_t *output);
+
+template <size_t componentCount>
+void Copy8SnormTo16SnormVertexData(const uint8_t *input,
+ size_t stride,
+ size_t count,
+ uint8_t *output);
+
+template <size_t inputComponentCount, size_t outputComponentCount>
+void Copy32FixedTo32FVertexData(const uint8_t *input, size_t stride, size_t count, uint8_t *output);
+
+template <typename T,
+ size_t inputComponentCount,
+ size_t outputComponentCount,
+ bool normalized,
+ bool toHalf>
+void CopyToFloatVertexData(const uint8_t *input, size_t stride, size_t count, uint8_t *output);
+
+template <size_t inputComponentCount, size_t outputComponentCount>
+void Copy32FTo16FVertexData(const uint8_t *input, size_t stride, size_t count, uint8_t *output);
+
+void CopyXYZ32FToXYZ9E5(const uint8_t *input, size_t stride, size_t count, uint8_t *output);
+
+void CopyXYZ32FToX11Y11B10F(const uint8_t *input, size_t stride, size_t count, uint8_t *output);
+
+template <bool isSigned, bool normalized, bool toFloat, bool toHalf>
+void CopyXYZ10W2ToXYZWFloatVertexData(const uint8_t *input,
+ size_t stride,
+ size_t count,
+ uint8_t *output);
+
+template <bool isSigned, bool normalized, bool toHalf>
+void CopyXYZ10ToXYZWFloatVertexData(const uint8_t *input,
+ size_t stride,
+ size_t count,
+ uint8_t *output);
+
+template <bool isSigned, bool normalized, bool toHalf>
+void CopyW2XYZ10ToXYZWFloatVertexData(const uint8_t *input,
+ size_t stride,
+ size_t count,
+ uint8_t *output);
+
+} // namespace rx
+
+#include "copyvertex.inc.h"
+
+#endif // LIBANGLE_RENDERER_COPYVERTEX_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/copyvertex.inc.h b/gfx/angle/checkout/src/libANGLE/renderer/copyvertex.inc.h
new file mode 100644
index 0000000000..3f1844e91c
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/copyvertex.inc.h
@@ -0,0 +1,635 @@
+//
+// 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.
+//
+
+// copyvertex.inc.h: Implementation of vertex buffer copying and conversion functions
+
+namespace rx
+{
+
+// Returns an aligned buffer to read the input from
+template <typename T, size_t inputComponentCount>
+inline const T *GetAlignedOffsetInput(const T *offsetInput, T *alignedElement)
+{
+ if (reinterpret_cast<uintptr_t>(offsetInput) % sizeof(T) != 0)
+ {
+ // Applications may pass in arbitrarily aligned buffers as input.
+ // Certain architectures have restrictions regarding unaligned reads. Specifically, we crash
+ // on armeabi-v7a devices with a SIGBUS error when performing such operations. arm64 and
+ // x86-64 devices do not appear to have such issues.
+ //
+ // The workaround is to detect if the input buffer is unaligned and if so, perform a
+ // byte-wise copy of the unaligned portion and a memcpy of the rest of the buffer.
+ uint8_t *alignedBuffer = reinterpret_cast<uint8_t *>(&alignedElement[0]);
+ uintptr_t unalignedInputStartAddress = reinterpret_cast<uintptr_t>(offsetInput);
+ constexpr size_t kAlignmentMinusOne = sizeof(T) - 1;
+ uintptr_t alignedInputStartAddress =
+ (reinterpret_cast<uintptr_t>(offsetInput) + kAlignmentMinusOne) & ~(kAlignmentMinusOne);
+ ASSERT(alignedInputStartAddress >= unalignedInputStartAddress);
+
+ const size_t totalBytesToCopy = sizeof(T) * inputComponentCount;
+ const size_t unalignedBytesToCopy = alignedInputStartAddress - unalignedInputStartAddress;
+ ASSERT(totalBytesToCopy >= unalignedBytesToCopy);
+
+ // byte-wise copy of unaligned portion
+ for (size_t i = 0; i < unalignedBytesToCopy; i++)
+ {
+ alignedBuffer[i] = reinterpret_cast<const uint8_t *>(&offsetInput[0])[i];
+ }
+
+ // memcpy remaining buffer
+ memcpy(&alignedBuffer[unalignedBytesToCopy],
+ &reinterpret_cast<const uint8_t *>(&offsetInput[0])[unalignedBytesToCopy],
+ totalBytesToCopy - unalignedBytesToCopy);
+
+ return alignedElement;
+ }
+ else
+ {
+ return offsetInput;
+ }
+}
+
+template <typename T,
+ size_t inputComponentCount,
+ size_t outputComponentCount,
+ uint32_t alphaDefaultValueBits>
+inline void CopyNativeVertexData(const uint8_t *input, size_t stride, size_t count, uint8_t *output)
+{
+ const size_t attribSize = sizeof(T) * inputComponentCount;
+
+ if (attribSize == stride && inputComponentCount == outputComponentCount)
+ {
+ memcpy(output, input, count * attribSize);
+ return;
+ }
+
+ if (inputComponentCount == outputComponentCount)
+ {
+ for (size_t i = 0; i < count; i++)
+ {
+ const T *offsetInput = reinterpret_cast<const T *>(input + (i * stride));
+ T offsetInputAligned[inputComponentCount];
+ offsetInput =
+ GetAlignedOffsetInput<T, inputComponentCount>(offsetInput, &offsetInputAligned[0]);
+
+ T *offsetOutput = reinterpret_cast<T *>(output) + i * outputComponentCount;
+
+ memcpy(offsetOutput, offsetInput, attribSize);
+ }
+ return;
+ }
+
+ const T defaultAlphaValue = gl::bitCast<T>(alphaDefaultValueBits);
+ const size_t lastNonAlphaOutputComponent = std::min<size_t>(outputComponentCount, 3);
+
+ for (size_t i = 0; i < count; i++)
+ {
+ const T *offsetInput = reinterpret_cast<const T *>(input + (i * stride));
+ T offsetInputAligned[inputComponentCount];
+ ASSERT(sizeof(offsetInputAligned) == attribSize);
+ offsetInput =
+ GetAlignedOffsetInput<T, inputComponentCount>(offsetInput, &offsetInputAligned[0]);
+
+ T *offsetOutput = reinterpret_cast<T *>(output) + i * outputComponentCount;
+
+ memcpy(offsetOutput, offsetInput, attribSize);
+
+ if (inputComponentCount < lastNonAlphaOutputComponent)
+ {
+ // Set the remaining G/B channels to 0.
+ size_t numComponents = (lastNonAlphaOutputComponent - inputComponentCount);
+ memset(&offsetOutput[inputComponentCount], 0, numComponents * sizeof(T));
+ }
+
+ if (inputComponentCount < outputComponentCount && outputComponentCount == 4)
+ {
+ // Set the remaining alpha channel to the defaultAlphaValue.
+ offsetOutput[3] = defaultAlphaValue;
+ }
+ }
+}
+
+template <size_t inputComponentCount, size_t outputComponentCount>
+inline void Copy8SintTo16SintVertexData(const uint8_t *input,
+ size_t stride,
+ size_t count,
+ uint8_t *output)
+{
+ const size_t lastNonAlphaOutputComponent = std::min<size_t>(outputComponentCount, 3);
+
+ for (size_t i = 0; i < count; i++)
+ {
+ const GLbyte *offsetInput = reinterpret_cast<const GLbyte *>(input + i * stride);
+ GLshort *offsetOutput = reinterpret_cast<GLshort *>(output) + i * outputComponentCount;
+
+ for (size_t j = 0; j < inputComponentCount; j++)
+ {
+ offsetOutput[j] = static_cast<GLshort>(offsetInput[j]);
+ }
+
+ for (size_t j = inputComponentCount; j < lastNonAlphaOutputComponent; j++)
+ {
+ // Set remaining G/B channels to 0.
+ offsetOutput[j] = 0;
+ }
+
+ if (inputComponentCount < outputComponentCount && outputComponentCount == 4)
+ {
+ // On integer formats, we must set the Alpha channel to 1 if it's unused.
+ offsetOutput[3] = 1;
+ }
+ }
+}
+
+template <size_t inputComponentCount, size_t outputComponentCount>
+inline void Copy8SnormTo16SnormVertexData(const uint8_t *input,
+ size_t stride,
+ size_t count,
+ uint8_t *output)
+{
+ for (size_t i = 0; i < count; i++)
+ {
+ const GLbyte *offsetInput = reinterpret_cast<const GLbyte *>(input + i * stride);
+ GLshort *offsetOutput = reinterpret_cast<GLshort *>(output) + i * outputComponentCount;
+
+ for (size_t j = 0; j < inputComponentCount; j++)
+ {
+ // The original GLbyte value ranges from -128 to +127 (INT8_MAX).
+ // When converted to GLshort, the value must be scaled to between -32768 and +32767
+ // (INT16_MAX).
+ if (offsetInput[j] > 0)
+ {
+ offsetOutput[j] =
+ offsetInput[j] << 8 | offsetInput[j] << 1 | ((offsetInput[j] & 0x40) >> 6);
+ }
+ else
+ {
+ offsetOutput[j] = offsetInput[j] << 8;
+ }
+ }
+
+ for (size_t j = inputComponentCount; j < std::min<size_t>(outputComponentCount, 3); j++)
+ {
+ // Set remaining G/B channels to 0.
+ offsetOutput[j] = 0;
+ }
+
+ if (inputComponentCount < outputComponentCount && outputComponentCount == 4)
+ {
+ // On normalized formats, we must set the Alpha channel to the max value if it's unused.
+ offsetOutput[3] = INT16_MAX;
+ }
+ }
+}
+
+template <size_t inputComponentCount, size_t outputComponentCount>
+inline void Copy32FixedTo32FVertexData(const uint8_t *input,
+ size_t stride,
+ size_t count,
+ uint8_t *output)
+{
+ static const float divisor = 1.0f / (1 << 16);
+
+ for (size_t i = 0; i < count; i++)
+ {
+ const uint8_t *offsetInput = input + i * stride;
+ float *offsetOutput = reinterpret_cast<float *>(output) + i * outputComponentCount;
+
+ // GLfixed access must be 4-byte aligned on arm32, input and stride sometimes are not
+ if (reinterpret_cast<uintptr_t>(offsetInput) % sizeof(GLfixed) == 0)
+ {
+ for (size_t j = 0; j < inputComponentCount; j++)
+ {
+ offsetOutput[j] =
+ static_cast<float>(reinterpret_cast<const GLfixed *>(offsetInput)[j]) * divisor;
+ }
+ }
+ else
+ {
+ for (size_t j = 0; j < inputComponentCount; j++)
+ {
+ GLfixed alignedInput;
+ memcpy(&alignedInput, offsetInput + j * sizeof(GLfixed), sizeof(GLfixed));
+ offsetOutput[j] = static_cast<float>(alignedInput) * divisor;
+ }
+ }
+
+ // 4-component output formats would need special padding in the alpha channel.
+ static_assert(!(inputComponentCount < 4 && outputComponentCount == 4),
+ "An inputComponentCount less than 4 and an outputComponentCount equal to 4 "
+ "is not supported.");
+
+ for (size_t j = inputComponentCount; j < outputComponentCount; j++)
+ {
+ offsetOutput[j] = 0.0f;
+ }
+ }
+}
+
+template <typename T,
+ size_t inputComponentCount,
+ size_t outputComponentCount,
+ bool normalized,
+ bool toHalf>
+inline void CopyToFloatVertexData(const uint8_t *input,
+ size_t stride,
+ size_t count,
+ uint8_t *output)
+{
+ typedef std::numeric_limits<T> NL;
+ typedef typename std::conditional<toHalf, GLhalf, float>::type outputType;
+
+ for (size_t i = 0; i < count; i++)
+ {
+ const T *offsetInput = reinterpret_cast<const T *>(input + (stride * i));
+ outputType *offsetOutput =
+ reinterpret_cast<outputType *>(output) + i * outputComponentCount;
+
+ T offsetInputAligned[inputComponentCount];
+ offsetInput =
+ GetAlignedOffsetInput<T, inputComponentCount>(offsetInput, &offsetInputAligned[0]);
+
+ for (size_t j = 0; j < inputComponentCount; j++)
+ {
+ float result = 0;
+
+ if (normalized)
+ {
+ if (NL::is_signed)
+ {
+ result = static_cast<float>(offsetInput[j]) / static_cast<float>(NL::max());
+ result = result >= -1.0f ? result : -1.0f;
+ }
+ else
+ {
+ result = static_cast<float>(offsetInput[j]) / static_cast<float>(NL::max());
+ }
+ }
+ else
+ {
+ result = static_cast<float>(offsetInput[j]);
+ }
+
+ if (toHalf)
+ {
+ offsetOutput[j] = gl::float32ToFloat16(result);
+ }
+ else
+ {
+ offsetOutput[j] = static_cast<outputType>(result);
+ }
+ }
+
+ for (size_t j = inputComponentCount; j < outputComponentCount; j++)
+ {
+ offsetOutput[j] = 0;
+ }
+
+ if (inputComponentCount < 4 && outputComponentCount == 4)
+ {
+ if (toHalf)
+ {
+ offsetOutput[3] = gl::Float16One;
+ }
+ else
+ {
+ offsetOutput[3] = static_cast<outputType>(gl::Float32One);
+ }
+ }
+ }
+}
+
+template <size_t inputComponentCount, size_t outputComponentCount>
+void Copy32FTo16FVertexData(const uint8_t *input, size_t stride, size_t count, uint8_t *output)
+{
+ const unsigned short kZero = gl::float32ToFloat16(0.0f);
+ const unsigned short kOne = gl::float32ToFloat16(1.0f);
+
+ for (size_t i = 0; i < count; i++)
+ {
+ const float *offsetInput = reinterpret_cast<const float *>(input + (stride * i));
+ unsigned short *offsetOutput =
+ reinterpret_cast<unsigned short *>(output) + i * outputComponentCount;
+
+ for (size_t j = 0; j < inputComponentCount; j++)
+ {
+ offsetOutput[j] = gl::float32ToFloat16(offsetInput[j]);
+ }
+
+ for (size_t j = inputComponentCount; j < outputComponentCount; j++)
+ {
+ offsetOutput[j] = (j == 3) ? kOne : kZero;
+ }
+ }
+}
+
+inline void CopyXYZ32FToXYZ9E5(const uint8_t *input, size_t stride, size_t count, uint8_t *output)
+{
+ for (size_t i = 0; i < count; i++)
+ {
+ const float *offsetInput = reinterpret_cast<const float *>(input + (stride * i));
+ unsigned int *offsetOutput = reinterpret_cast<unsigned int *>(output) + i;
+
+ *offsetOutput = gl::convertRGBFloatsTo999E5(offsetInput[0], offsetInput[1], offsetInput[2]);
+ }
+}
+
+inline void CopyXYZ32FToX11Y11B10F(const uint8_t *input,
+ size_t stride,
+ size_t count,
+ uint8_t *output)
+{
+ for (size_t i = 0; i < count; i++)
+ {
+ const float *offsetInput = reinterpret_cast<const float *>(input + (stride * i));
+ unsigned int *offsetOutput = reinterpret_cast<unsigned int *>(output) + i;
+
+ *offsetOutput = gl::float32ToFloat11(offsetInput[0]) << 0 |
+ gl::float32ToFloat11(offsetInput[1]) << 11 |
+ gl::float32ToFloat10(offsetInput[2]) << 22;
+ }
+}
+
+namespace priv
+{
+
+template <bool isSigned, bool normalized, bool toFloat, bool toHalf>
+static inline void CopyPackedRGB(uint32_t data, uint8_t *output)
+{
+ const uint32_t rgbSignMask = 0x200; // 1 set at the 9 bit
+ const uint32_t negativeMask = 0xFFFFFC00; // All bits from 10 to 31 set to 1
+
+ if (toFloat || toHalf)
+ {
+ GLfloat finalValue = static_cast<GLfloat>(data);
+ if (isSigned)
+ {
+ if (data & rgbSignMask)
+ {
+ int negativeNumber = data | negativeMask;
+ finalValue = static_cast<GLfloat>(negativeNumber);
+ }
+
+ if (normalized)
+ {
+ const int32_t maxValue = 0x1FF; // 1 set in bits 0 through 8
+ const int32_t minValue = 0xFFFFFE01; // Inverse of maxValue
+
+ // A 10-bit two's complement number has the possibility of being minValue - 1 but
+ // OpenGL's normalization rules dictate that it should be clamped to minValue in
+ // this case.
+ if (finalValue < minValue)
+ {
+ finalValue = minValue;
+ }
+
+ const int32_t halfRange = (maxValue - minValue) >> 1;
+ finalValue = ((finalValue - minValue) / halfRange) - 1.0f;
+ }
+ }
+ else
+ {
+ if (normalized)
+ {
+ const uint32_t maxValue = 0x3FF; // 1 set in bits 0 through 9
+ finalValue /= static_cast<GLfloat>(maxValue);
+ }
+ }
+
+ if (toHalf)
+ {
+ *reinterpret_cast<GLhalf *>(output) = gl::float32ToFloat16(finalValue);
+ }
+ else
+ {
+ *reinterpret_cast<GLfloat *>(output) = finalValue;
+ }
+ }
+ else
+ {
+ if (isSigned)
+ {
+ GLshort *intOutput = reinterpret_cast<GLshort *>(output);
+
+ if (data & rgbSignMask)
+ {
+ *intOutput = static_cast<GLshort>(data | negativeMask);
+ }
+ else
+ {
+ *intOutput = static_cast<GLshort>(data);
+ }
+ }
+ else
+ {
+ GLushort *uintOutput = reinterpret_cast<GLushort *>(output);
+ *uintOutput = static_cast<GLushort>(data);
+ }
+ }
+}
+
+template <bool isSigned, bool normalized, bool toFloat, bool toHalf>
+inline void CopyPackedAlpha(uint32_t data, uint8_t *output)
+{
+ ASSERT(data >= 0 && data <= 3);
+
+ if (toFloat || toHalf)
+ {
+ GLfloat finalValue = 0;
+ if (isSigned)
+ {
+ if (normalized)
+ {
+ switch (data)
+ {
+ case 0x0:
+ finalValue = 0.0f;
+ break;
+ case 0x1:
+ finalValue = 1.0f;
+ break;
+ case 0x2:
+ finalValue = -1.0f;
+ break;
+ case 0x3:
+ finalValue = -1.0f;
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+ else
+ {
+ switch (data)
+ {
+ case 0x0:
+ finalValue = 0.0f;
+ break;
+ case 0x1:
+ finalValue = 1.0f;
+ break;
+ case 0x2:
+ finalValue = -2.0f;
+ break;
+ case 0x3:
+ finalValue = -1.0f;
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+ }
+ else
+ {
+ if (normalized)
+ {
+ finalValue = data / 3.0f;
+ }
+ else
+ {
+ finalValue = static_cast<float>(data);
+ }
+ }
+
+ if (toHalf)
+ {
+ *reinterpret_cast<GLhalf *>(output) = gl::float32ToFloat16(finalValue);
+ }
+ else
+ {
+ *reinterpret_cast<GLfloat *>(output) = finalValue;
+ }
+ }
+ else
+ {
+ if (isSigned)
+ {
+ GLshort *intOutput = reinterpret_cast<GLshort *>(output);
+ switch (data)
+ {
+ case 0x0:
+ *intOutput = 0;
+ break;
+ case 0x1:
+ *intOutput = 1;
+ break;
+ case 0x2:
+ *intOutput = -2;
+ break;
+ case 0x3:
+ *intOutput = -1;
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+ else
+ {
+ *reinterpret_cast<GLushort *>(output) = static_cast<GLushort>(data);
+ }
+ }
+}
+
+} // namespace priv
+
+template <bool isSigned, bool normalized, bool toFloat, bool toHalf>
+inline void CopyXYZ10W2ToXYZWFloatVertexData(const uint8_t *input,
+ size_t stride,
+ size_t count,
+ uint8_t *output)
+{
+ const size_t outputComponentSize = toFloat && !toHalf ? 4 : 2;
+ const size_t componentCount = 4;
+
+ const uint32_t rgbMask = 0x3FF; // 1 set in bits 0 through 9
+ const size_t redShift = 0; // red is bits 0 through 9
+ const size_t greenShift = 10; // green is bits 10 through 19
+ const size_t blueShift = 20; // blue is bits 20 through 29
+
+ const uint32_t alphaMask = 0x3; // 1 set in bits 0 and 1
+ const size_t alphaShift = 30; // Alpha is the 30 and 31 bits
+
+ for (size_t i = 0; i < count; i++)
+ {
+ GLuint packedValue = *reinterpret_cast<const GLuint *>(input + (i * stride));
+ uint8_t *offsetOutput = output + (i * outputComponentSize * componentCount);
+
+ priv::CopyPackedRGB<isSigned, normalized, toFloat, toHalf>(
+ (packedValue >> redShift) & rgbMask, offsetOutput + (0 * outputComponentSize));
+ priv::CopyPackedRGB<isSigned, normalized, toFloat, toHalf>(
+ (packedValue >> greenShift) & rgbMask, offsetOutput + (1 * outputComponentSize));
+ priv::CopyPackedRGB<isSigned, normalized, toFloat, toHalf>(
+ (packedValue >> blueShift) & rgbMask, offsetOutput + (2 * outputComponentSize));
+ priv::CopyPackedAlpha<isSigned, normalized, toFloat, toHalf>(
+ (packedValue >> alphaShift) & alphaMask, offsetOutput + (3 * outputComponentSize));
+ }
+}
+
+template <bool isSigned, bool normalized, bool toHalf>
+inline void CopyXYZ10ToXYZWFloatVertexData(const uint8_t *input,
+ size_t stride,
+ size_t count,
+ uint8_t *output)
+{
+ const size_t outputComponentSize = toHalf ? 2 : 4;
+ const size_t componentCount = 4;
+
+ const uint32_t rgbMask = 0x3FF; // 1 set in bits 0 through 9
+ const size_t redShift = 22; // red is bits 22 through 31
+ const size_t greenShift = 12; // green is bits 12 through 21
+ const size_t blueShift = 2; // blue is bits 2 through 11
+
+ const uint32_t alphaDefaultValueBits = normalized ? (isSigned ? 0x1 : 0x3) : 0x1;
+
+ for (size_t i = 0; i < count; i++)
+ {
+ GLuint packedValue = *reinterpret_cast<const GLuint *>(input + (i * stride));
+ uint8_t *offsetOutput = output + (i * outputComponentSize * componentCount);
+
+ priv::CopyPackedRGB<isSigned, normalized, true, toHalf>(
+ (packedValue >> redShift) & rgbMask, offsetOutput + (0 * outputComponentSize));
+ priv::CopyPackedRGB<isSigned, normalized, true, toHalf>(
+ (packedValue >> greenShift) & rgbMask, offsetOutput + (1 * outputComponentSize));
+ priv::CopyPackedRGB<isSigned, normalized, true, toHalf>(
+ (packedValue >> blueShift) & rgbMask, offsetOutput + (2 * outputComponentSize));
+ priv::CopyPackedAlpha<isSigned, normalized, true, toHalf>(
+ alphaDefaultValueBits, offsetOutput + (3 * outputComponentSize));
+ }
+}
+
+template <bool isSigned, bool normalized, bool toHalf>
+inline void CopyW2XYZ10ToXYZWFloatVertexData(const uint8_t *input,
+ size_t stride,
+ size_t count,
+ uint8_t *output)
+{
+ const size_t outputComponentSize = toHalf ? 2 : 4;
+ const size_t componentCount = 4;
+
+ const uint32_t rgbMask = 0x3FF; // 1 set in bits 0 through 9
+ const size_t redShift = 22; // red is bits 22 through 31
+ const size_t greenShift = 12; // green is bits 12 through 21
+ const size_t blueShift = 2; // blue is bits 2 through 11
+
+ const uint32_t alphaMask = 0x3; // 1 set in bits 0 and 1
+ const size_t alphaShift = 0; // Alpha is the 30 and 31 bits
+
+ for (size_t i = 0; i < count; i++)
+ {
+ GLuint packedValue = *reinterpret_cast<const GLuint *>(input + (i * stride));
+ uint8_t *offsetOutput = output + (i * outputComponentSize * componentCount);
+
+ priv::CopyPackedRGB<isSigned, normalized, true, toHalf>(
+ (packedValue >> redShift) & rgbMask, offsetOutput + (0 * outputComponentSize));
+ priv::CopyPackedRGB<isSigned, normalized, true, toHalf>(
+ (packedValue >> greenShift) & rgbMask, offsetOutput + (1 * outputComponentSize));
+ priv::CopyPackedRGB<isSigned, normalized, true, toHalf>(
+ (packedValue >> blueShift) & rgbMask, offsetOutput + (2 * outputComponentSize));
+ priv::CopyPackedAlpha<isSigned, normalized, true, toHalf>(
+ (packedValue >> alphaShift) & alphaMask, offsetOutput + (3 * outputComponentSize));
+ }
+}
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/BufferD3D.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/BufferD3D.cpp
new file mode 100644
index 0000000000..464bd6d4a8
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/BufferD3D.cpp
@@ -0,0 +1,191 @@
+//
+// 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.
+//
+
+// BufferD3D.cpp Defines common functionality between the Buffer9 and Buffer11 classes.
+
+#include "libANGLE/renderer/d3d/BufferD3D.h"
+
+#include "common/mathutil.h"
+#include "common/utilities.h"
+#include "libANGLE/renderer/d3d/IndexBuffer.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
+#include "libANGLE/renderer/d3d/VertexBuffer.h"
+
+namespace rx
+{
+
+unsigned int BufferD3D::mNextSerial = 1;
+
+BufferD3D::BufferD3D(const gl::BufferState &state, BufferFactoryD3D *factory)
+ : BufferImpl(state),
+ mFactory(factory),
+ mStaticIndexBuffer(nullptr),
+ mStaticBufferCacheTotalSize(0),
+ mStaticVertexBufferOutOfDate(false),
+ mUnmodifiedDataUse(0),
+ mUsage(D3DBufferUsage::STATIC)
+{
+ updateSerial();
+}
+
+BufferD3D::~BufferD3D()
+{
+ SafeDelete(mStaticIndexBuffer);
+}
+
+void BufferD3D::emptyStaticBufferCache()
+{
+ mStaticVertexBuffers.clear();
+ mStaticBufferCacheTotalSize = 0;
+}
+
+void BufferD3D::updateSerial()
+{
+ mSerial = mNextSerial++;
+}
+
+void BufferD3D::updateD3DBufferUsage(const gl::Context *context, gl::BufferUsage usage)
+{
+ switch (usage)
+ {
+ case gl::BufferUsage::StaticCopy:
+ case gl::BufferUsage::StaticDraw:
+ case gl::BufferUsage::StaticRead:
+ case gl::BufferUsage::DynamicCopy:
+ case gl::BufferUsage::DynamicRead:
+ case gl::BufferUsage::StreamCopy:
+ case gl::BufferUsage::StreamRead:
+ mUsage = D3DBufferUsage::STATIC;
+ initializeStaticData(context);
+ break;
+
+ case gl::BufferUsage::DynamicDraw:
+ case gl::BufferUsage::StreamDraw:
+ mUsage = D3DBufferUsage::DYNAMIC;
+ break;
+ default:
+ UNREACHABLE();
+ }
+}
+
+void BufferD3D::initializeStaticData(const gl::Context *context)
+{
+ if (mStaticVertexBuffers.empty())
+ {
+ StaticVertexBufferInterface *newStaticBuffer = new StaticVertexBufferInterface(mFactory);
+ mStaticVertexBuffers.push_back(
+ std::unique_ptr<StaticVertexBufferInterface>(newStaticBuffer));
+ }
+ if (!mStaticIndexBuffer)
+ {
+ mStaticIndexBuffer = new StaticIndexBufferInterface(mFactory);
+ }
+}
+
+StaticIndexBufferInterface *BufferD3D::getStaticIndexBuffer()
+{
+ return mStaticIndexBuffer;
+}
+
+StaticVertexBufferInterface *BufferD3D::getStaticVertexBuffer(const gl::VertexAttribute &attribute,
+ const gl::VertexBinding &binding)
+{
+ if (mStaticVertexBuffers.empty())
+ {
+ // Early out if there aren't any static buffers at all
+ return nullptr;
+ }
+
+ // Early out, the attribute can be added to mStaticVertexBuffer.
+ if (mStaticVertexBuffers.size() == 1 && mStaticVertexBuffers[0]->empty())
+ {
+ return mStaticVertexBuffers[0].get();
+ }
+
+ // Cache size limiting: track the total allocated buffer sizes.
+ size_t currentTotalSize = 0;
+
+ // At this point, see if any of the existing static buffers contains the attribute data
+ // If there is a cached static buffer that already contains the attribute, then return it
+ for (const auto &staticBuffer : mStaticVertexBuffers)
+ {
+ if (staticBuffer->matchesAttribute(attribute, binding))
+ {
+ return staticBuffer.get();
+ }
+
+ currentTotalSize += staticBuffer->getBufferSize();
+ }
+
+ // Cache size limiting: Clean-up threshold is four times the base buffer size, with a minimum.
+ ASSERT(getSize() < std::numeric_limits<size_t>::max() / 4u);
+ size_t sizeThreshold = std::max(getSize() * 4u, static_cast<size_t>(0x1000u));
+
+ // If we're past the threshold, clear the buffer cache. Note that this will release buffers
+ // that are currenly bound, and in an edge case can even translate the same attribute twice
+ // in the same draw call. It will not delete currently bound buffers, however, because they
+ // are ref counted.
+ if (currentTotalSize > sizeThreshold)
+ {
+ emptyStaticBufferCache();
+ }
+
+ // At this point, we must create a new static buffer for the attribute data.
+ StaticVertexBufferInterface *newStaticBuffer = new StaticVertexBufferInterface(mFactory);
+ newStaticBuffer->setAttribute(attribute, binding);
+ mStaticVertexBuffers.push_back(std::unique_ptr<StaticVertexBufferInterface>(newStaticBuffer));
+ return newStaticBuffer;
+}
+
+void BufferD3D::invalidateStaticData(const gl::Context *context)
+{
+ emptyStaticBufferCache();
+
+ if (mStaticIndexBuffer && mStaticIndexBuffer->getBufferSize() != 0)
+ {
+ SafeDelete(mStaticIndexBuffer);
+ }
+
+ // If the buffer was created with a static usage then we recreate the static
+ // buffers so that they are populated the next time we use this buffer.
+ if (mUsage == D3DBufferUsage::STATIC)
+ {
+ initializeStaticData(context);
+ }
+
+ mUnmodifiedDataUse = 0;
+}
+
+// Creates static buffers if sufficient used data has been left unmodified
+void BufferD3D::promoteStaticUsage(const gl::Context *context, size_t dataSize)
+{
+ if (mUsage == D3DBufferUsage::DYNAMIC)
+ {
+ // Note: This is not a safe math operation. 'dataSize' can come from the app.
+ mUnmodifiedDataUse += dataSize;
+
+ if (mUnmodifiedDataUse > 3 * getSize())
+ {
+ updateD3DBufferUsage(context, gl::BufferUsage::StaticDraw);
+ }
+ }
+}
+
+angle::Result BufferD3D::getIndexRange(const gl::Context *context,
+ gl::DrawElementsType type,
+ size_t offset,
+ size_t count,
+ bool primitiveRestartEnabled,
+ gl::IndexRange *outRange)
+{
+ const uint8_t *data = nullptr;
+ ANGLE_TRY(getData(context, &data));
+
+ *outRange = gl::ComputeIndexRange(type, data + offset, count, primitiveRestartEnabled);
+ return angle::Result::Continue;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/BufferD3D.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/BufferD3D.h
new file mode 100644
index 0000000000..19ea78c6eb
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/BufferD3D.h
@@ -0,0 +1,89 @@
+//
+// 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.
+//
+
+// BufferD3D.h: Defines the rx::BufferD3D class, an implementation of BufferImpl.
+
+#ifndef LIBANGLE_RENDERER_D3D_BUFFERD3D_H_
+#define LIBANGLE_RENDERER_D3D_BUFFERD3D_H_
+
+#include "libANGLE/angletypes.h"
+#include "libANGLE/renderer/BufferImpl.h"
+
+#include <stdint.h>
+#include <vector>
+
+namespace gl
+{
+struct VertexAttribute;
+class VertexBinding;
+} // namespace gl
+
+namespace rx
+{
+class BufferFactoryD3D;
+class StaticIndexBufferInterface;
+class StaticVertexBufferInterface;
+
+enum class D3DBufferUsage
+{
+ STATIC,
+ DYNAMIC,
+};
+
+class BufferD3D : public BufferImpl
+{
+ public:
+ BufferD3D(const gl::BufferState &state, BufferFactoryD3D *factory);
+ ~BufferD3D() override;
+
+ unsigned int getSerial() const { return mSerial; }
+
+ virtual size_t getSize() const = 0;
+ virtual bool supportsDirectBinding() const = 0;
+ virtual angle::Result markTransformFeedbackUsage(const gl::Context *context) = 0;
+ virtual angle::Result getData(const gl::Context *context, const uint8_t **outData) = 0;
+
+ // Warning: you should ensure binding really matches attrib.bindingIndex before using this
+ // function.
+ StaticVertexBufferInterface *getStaticVertexBuffer(const gl::VertexAttribute &attribute,
+ const gl::VertexBinding &binding);
+ StaticIndexBufferInterface *getStaticIndexBuffer();
+
+ virtual void initializeStaticData(const gl::Context *context);
+ virtual void invalidateStaticData(const gl::Context *context);
+
+ void promoteStaticUsage(const gl::Context *context, size_t dataSize);
+
+ angle::Result getIndexRange(const gl::Context *context,
+ gl::DrawElementsType type,
+ size_t offset,
+ size_t count,
+ bool primitiveRestartEnabled,
+ gl::IndexRange *outRange) override;
+
+ BufferFactoryD3D *getFactory() const { return mFactory; }
+ D3DBufferUsage getUsage() const { return mUsage; }
+
+ protected:
+ void updateSerial();
+ void updateD3DBufferUsage(const gl::Context *context, gl::BufferUsage usage);
+ void emptyStaticBufferCache();
+
+ BufferFactoryD3D *mFactory;
+ unsigned int mSerial;
+ static unsigned int mNextSerial;
+
+ std::vector<std::unique_ptr<StaticVertexBufferInterface>> mStaticVertexBuffers;
+ StaticIndexBufferInterface *mStaticIndexBuffer;
+ unsigned int mStaticBufferCacheTotalSize;
+ unsigned int mStaticVertexBufferOutOfDate;
+ size_t mUnmodifiedDataUse;
+ D3DBufferUsage mUsage;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_BUFFERD3D_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/CompilerD3D.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/CompilerD3D.cpp
new file mode 100644
index 0000000000..4656cf4d80
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/CompilerD3D.cpp
@@ -0,0 +1,24 @@
+//
+// 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.
+//
+// CompilerD3D:
+// Implementation of the D3D compiler methods.
+//
+
+#include "libANGLE/renderer/d3d/CompilerD3D.h"
+
+namespace rx
+{
+
+CompilerD3D::CompilerD3D(ShShaderOutput translatorOutputType)
+ : mTranslatorOutputType(translatorOutputType)
+{}
+
+ShShaderOutput CompilerD3D::getTranslatorOutputType() const
+{
+ return mTranslatorOutputType;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/CompilerD3D.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/CompilerD3D.h
new file mode 100644
index 0000000000..3e1d01a0b9
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/CompilerD3D.h
@@ -0,0 +1,32 @@
+//
+// 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.
+//
+
+// CompilerD3D.h: Defines the rx::CompilerD3D class, an implementation of rx::CompilerImpl.
+
+#ifndef LIBANGLE_RENDERER_COMPILERD3D_H_
+#define LIBANGLE_RENDERER_COMPILERD3D_H_
+
+#include "libANGLE/renderer/CompilerImpl.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
+
+namespace rx
+{
+
+class CompilerD3D : public CompilerImpl
+{
+ public:
+ CompilerD3D(ShShaderOutput translatorOutputType);
+ ~CompilerD3D() override {}
+
+ ShShaderOutput getTranslatorOutputType() const override;
+
+ private:
+ ShShaderOutput mTranslatorOutputType;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_COMPILERD3D_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/ContextD3D.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/ContextD3D.h
new file mode 100644
index 0000000000..d563672e67
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/ContextD3D.h
@@ -0,0 +1,24 @@
+//
+// Copyright 2018 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.
+//
+// ContextD3D: Shared common class for Context9 and Context11.
+
+#ifndef LIBANGLE_RENDERER_CONTEXTD3D_H_
+#define LIBANGLE_RENDERER_CONTEXTD3D_H_
+
+#include "libANGLE/renderer/ContextImpl.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
+
+namespace rx
+{
+class ContextD3D : public ContextImpl, public d3d::Context
+{
+ public:
+ ContextD3D(const gl::State &state, gl::ErrorSet *errorSet) : ContextImpl(state, errorSet) {}
+ ~ContextD3D() override {}
+};
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_CONTEXTD3D_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/DeviceD3D.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/DeviceD3D.cpp
new file mode 100644
index 0000000000..79dfb094e3
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/DeviceD3D.cpp
@@ -0,0 +1,84 @@
+//
+// 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.
+//
+
+// DeviceD3D.cpp: D3D implementation of egl::Device
+
+#include "libANGLE/renderer/d3d/DeviceD3D.h"
+
+#include "libANGLE/Device.h"
+#include "libANGLE/Display.h"
+
+#include <EGL/eglext.h>
+
+namespace rx
+{
+
+DeviceD3D::DeviceD3D(GLint deviceType, void *nativeDevice)
+ : mDevice(nativeDevice), mDeviceType(deviceType), mIsInitialized(false)
+{}
+
+DeviceD3D::~DeviceD3D()
+{
+#if defined(ANGLE_ENABLE_D3D11)
+ if (mIsInitialized && mDeviceType == EGL_D3D11_DEVICE_ANGLE)
+ {
+ // DeviceD3D holds a ref to an externally-sourced D3D11 device. We must release it.
+ ID3D11Device *device = static_cast<ID3D11Device *>(mDevice);
+ device->Release();
+ }
+#endif
+}
+
+egl::Error DeviceD3D::getAttribute(const egl::Display *display, EGLint attribute, void **outValue)
+{
+ ASSERT(mIsInitialized);
+ ANGLE_UNUSED_VARIABLE(display);
+ // Validated at higher levels.
+ ASSERT(getType() == attribute);
+ *outValue = mDevice;
+ return egl::NoError();
+}
+
+egl::Error DeviceD3D::initialize()
+{
+ ASSERT(!mIsInitialized);
+
+#if defined(ANGLE_ENABLE_D3D11)
+ if (mDeviceType == EGL_D3D11_DEVICE_ANGLE)
+ {
+ // Validate the device
+ IUnknown *iunknown = static_cast<IUnknown *>(mDevice);
+
+ ID3D11Device *d3dDevice = nullptr;
+ HRESULT hr =
+ iunknown->QueryInterface(__uuidof(ID3D11Device), reinterpret_cast<void **>(&d3dDevice));
+ if (FAILED(hr))
+ {
+ return egl::EglBadAttribute() << "Invalid D3D device passed into EGLDeviceEXT";
+ }
+
+ // The QI to ID3D11Device adds a ref to the D3D11 device.
+ // Deliberately don't release the ref here, so that the DeviceD3D holds a ref to the
+ // D3D11 device.
+ }
+#endif
+
+ mIsInitialized = true;
+
+ return egl::NoError();
+}
+
+EGLint DeviceD3D::getType()
+{
+ return mDeviceType;
+}
+
+void DeviceD3D::generateExtensions(egl::DeviceExtensions *outExtensions) const
+{
+ outExtensions->deviceD3D = true;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/DeviceD3D.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/DeviceD3D.h
new file mode 100644
index 0000000000..c169eb7de5
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/DeviceD3D.h
@@ -0,0 +1,39 @@
+//
+// 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.
+//
+
+// DeviceD3D.h: D3D implementation of egl::Device
+
+#ifndef LIBANGLE_RENDERER_D3D_DEVICED3D_H_
+#define LIBANGLE_RENDERER_D3D_DEVICED3D_H_
+
+#include "libANGLE/Device.h"
+#include "libANGLE/renderer/DeviceImpl.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
+
+namespace rx
+{
+class DeviceD3D : public DeviceImpl
+{
+ public:
+ DeviceD3D(EGLint deviceType, void *nativeDevice);
+ ~DeviceD3D() override;
+
+ egl::Error initialize() override;
+ egl::Error getAttribute(const egl::Display *display,
+ EGLint attribute,
+ void **outValue) override;
+ EGLint getType() override;
+ void generateExtensions(egl::DeviceExtensions *outExtensions) const override;
+
+ private:
+ void *mDevice;
+ EGLint mDeviceType;
+ bool mIsInitialized;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_DEVICED3D_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/DisplayD3D.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/DisplayD3D.cpp
new file mode 100644
index 0000000000..35216fd4d2
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/DisplayD3D.cpp
@@ -0,0 +1,462 @@
+//
+// 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.
+//
+
+// DisplayD3D.cpp: D3D implementation of egl::Display
+
+#include "libANGLE/renderer/d3d/DisplayD3D.h"
+
+#include <EGL/eglext.h>
+
+#include "libANGLE/Config.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Display.h"
+#include "libANGLE/Surface.h"
+#include "libANGLE/Thread.h"
+#include "libANGLE/histogram_macros.h"
+#include "libANGLE/renderer/d3d/DeviceD3D.h"
+#include "libANGLE/renderer/d3d/EGLImageD3D.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
+#include "libANGLE/renderer/d3d/SurfaceD3D.h"
+#include "libANGLE/renderer/d3d/SwapChainD3D.h"
+
+#if !defined(ANGLE_DEFAULT_D3D11)
+// Enables use of the Direct3D 11 API for a default display, when available
+# define ANGLE_DEFAULT_D3D11 1
+#endif
+
+namespace rx
+{
+
+using CreateRendererD3DFunction = RendererD3D *(*)(egl::Display *);
+
+egl::Error CreateRendererD3D(egl::Display *display, RendererD3D **outRenderer)
+{
+ ASSERT(outRenderer != nullptr);
+
+ std::vector<CreateRendererD3DFunction> rendererCreationFunctions;
+
+ if (display->getPlatform() == EGL_PLATFORM_ANGLE_ANGLE)
+ {
+ const auto &attribMap = display->getAttributeMap();
+ EGLNativeDisplayType nativeDisplay = display->getNativeDisplayId();
+
+ EGLint requestedDisplayType = static_cast<EGLint>(
+ attribMap.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE));
+
+#if defined(ANGLE_ENABLE_D3D11)
+ const auto addD3D11 = nativeDisplay == EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE ||
+ nativeDisplay == EGL_D3D11_ONLY_DISPLAY_ANGLE ||
+ requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE;
+#endif
+
+#if defined(ANGLE_ENABLE_D3D9)
+ const auto addD3D9 = nativeDisplay == EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE ||
+ requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE;
+#endif
+
+#if ANGLE_DEFAULT_D3D11
+# if defined(ANGLE_ENABLE_D3D11)
+ if (addD3D11)
+ {
+ rendererCreationFunctions.push_back(CreateRenderer11);
+ }
+# endif
+
+# if defined(ANGLE_ENABLE_D3D9)
+ if (addD3D9)
+ {
+ rendererCreationFunctions.push_back(CreateRenderer9);
+ }
+# endif
+#else
+# if defined(ANGLE_ENABLE_D3D9)
+ if (addD3D9)
+ {
+ rendererCreationFunctions.push_back(CreateRenderer9);
+ }
+# endif
+
+# if defined(ANGLE_ENABLE_D3D11)
+ if (addD3D11)
+ {
+ rendererCreationFunctions.push_back(CreateRenderer11);
+ }
+# endif
+#endif
+
+ if (nativeDisplay != EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE &&
+ nativeDisplay != EGL_D3D11_ONLY_DISPLAY_ANGLE &&
+ requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE)
+ {
+ // The default display is requested, try the D3D9 and D3D11 renderers, order them using
+ // the definition of ANGLE_DEFAULT_D3D11
+#if ANGLE_DEFAULT_D3D11
+# if defined(ANGLE_ENABLE_D3D11)
+ rendererCreationFunctions.push_back(CreateRenderer11);
+# endif
+# if defined(ANGLE_ENABLE_D3D9)
+ rendererCreationFunctions.push_back(CreateRenderer9);
+# endif
+#else
+# if defined(ANGLE_ENABLE_D3D9)
+ rendererCreationFunctions.push_back(CreateRenderer9);
+# endif
+# if defined(ANGLE_ENABLE_D3D11)
+ rendererCreationFunctions.push_back(CreateRenderer11);
+# endif
+#endif
+ }
+ }
+ else if (display->getPlatform() == EGL_PLATFORM_DEVICE_EXT)
+ {
+#if defined(ANGLE_ENABLE_D3D11)
+ if (display->getDevice()->getType() == EGL_D3D11_DEVICE_ANGLE)
+ {
+ rendererCreationFunctions.push_back(CreateRenderer11);
+ }
+#endif
+ }
+ else
+ {
+ UNIMPLEMENTED();
+ }
+
+ for (size_t i = 0; i < rendererCreationFunctions.size(); i++)
+ {
+ RendererD3D *renderer = rendererCreationFunctions[i](display);
+ egl::Error result = renderer->initialize();
+
+#if defined(ANGLE_ENABLE_D3D11)
+ if (renderer->getRendererClass() == RENDERER_D3D11)
+ {
+ ASSERT(result.getID() >= 0 && result.getID() < NUM_D3D11_INIT_ERRORS);
+ ANGLE_HISTOGRAM_ENUMERATION("GPU.ANGLE.D3D11InitializeResult", result.getID(),
+ NUM_D3D11_INIT_ERRORS);
+ }
+#endif
+
+#if defined(ANGLE_ENABLE_D3D9)
+ if (renderer->getRendererClass() == RENDERER_D3D9)
+ {
+ ASSERT(result.getID() >= 0 && result.getID() < NUM_D3D9_INIT_ERRORS);
+ ANGLE_HISTOGRAM_ENUMERATION("GPU.ANGLE.D3D9InitializeResult", result.getID(),
+ NUM_D3D9_INIT_ERRORS);
+ }
+#endif
+
+ if (!result.isError())
+ {
+ *outRenderer = renderer;
+ return result;
+ }
+
+ // Failed to create the renderer, try the next
+ SafeDelete(renderer);
+ ERR() << "Failed to create D3D renderer: " << result.getMessage();
+ }
+
+ return egl::EglNotInitialized() << "No available renderers.";
+}
+
+DisplayD3D::DisplayD3D(const egl::DisplayState &state) : DisplayImpl(state), mRenderer(nullptr) {}
+
+SurfaceImpl *DisplayD3D::createWindowSurface(const egl::SurfaceState &state,
+ EGLNativeWindowType window,
+ const egl::AttributeMap &attribs)
+{
+ ASSERT(mRenderer != nullptr);
+ return new WindowSurfaceD3D(state, mRenderer, mDisplay, window, attribs);
+}
+
+SurfaceImpl *DisplayD3D::createPbufferSurface(const egl::SurfaceState &state,
+ const egl::AttributeMap &attribs)
+{
+ ASSERT(mRenderer != nullptr);
+ return new PbufferSurfaceD3D(state, mRenderer, mDisplay, 0, nullptr, attribs);
+}
+
+SurfaceImpl *DisplayD3D::createPbufferFromClientBuffer(const egl::SurfaceState &state,
+ EGLenum buftype,
+ EGLClientBuffer clientBuffer,
+ const egl::AttributeMap &attribs)
+{
+ ASSERT(mRenderer != nullptr);
+ return new PbufferSurfaceD3D(state, mRenderer, mDisplay, buftype, clientBuffer, attribs);
+}
+
+SurfaceImpl *DisplayD3D::createPixmapSurface(const egl::SurfaceState &state,
+ NativePixmapType nativePixmap,
+ const egl::AttributeMap &attribs)
+{
+ UNIMPLEMENTED();
+ return nullptr;
+}
+
+ImageImpl *DisplayD3D::createImage(const egl::ImageState &state,
+ const gl::Context *context,
+ EGLenum target,
+ const egl::AttributeMap &attribs)
+{
+ return new EGLImageD3D(state, target, attribs, mRenderer);
+}
+
+DeviceImpl *DisplayD3D::createDevice()
+{
+ return mRenderer->createEGLDevice();
+}
+
+rx::ContextImpl *DisplayD3D::createContext(const gl::State &state,
+ gl::ErrorSet *errorSet,
+ const egl::Config *configuration,
+ const gl::Context *shareContext,
+ const egl::AttributeMap &attribs)
+{
+ ASSERT(mRenderer != nullptr);
+ return mRenderer->createContext(state, errorSet);
+}
+
+StreamProducerImpl *DisplayD3D::createStreamProducerD3DTexture(
+ egl::Stream::ConsumerType consumerType,
+ const egl::AttributeMap &attribs)
+{
+ ASSERT(mRenderer != nullptr);
+ return mRenderer->createStreamProducerD3DTexture(consumerType, attribs);
+}
+
+ExternalImageSiblingImpl *DisplayD3D::createExternalImageSibling(const gl::Context *context,
+ EGLenum target,
+ EGLClientBuffer buffer,
+ const egl::AttributeMap &attribs)
+{
+ ASSERT(mRenderer != nullptr);
+ return mRenderer->createExternalImageSibling(context, target, buffer, attribs);
+}
+
+ShareGroupImpl *DisplayD3D::createShareGroup()
+{
+ return new ShareGroupD3D();
+}
+
+egl::Error DisplayD3D::makeCurrent(egl::Display *display,
+ egl::Surface *drawSurface,
+ egl::Surface *readSurface,
+ gl::Context *context)
+{
+ // Ensure the appropriate global DebugAnnotator is used
+ ASSERT(mRenderer != nullptr);
+ mRenderer->setGlobalDebugAnnotator();
+
+ return egl::NoError();
+}
+
+egl::Error DisplayD3D::initialize(egl::Display *display)
+{
+ ASSERT(mRenderer == nullptr && display != nullptr);
+ mDisplay = display;
+ ANGLE_TRY(CreateRendererD3D(display, &mRenderer));
+ return egl::NoError();
+}
+
+void DisplayD3D::terminate()
+{
+ SafeDelete(mRenderer);
+}
+
+egl::ConfigSet DisplayD3D::generateConfigs()
+{
+ ASSERT(mRenderer != nullptr);
+ return mRenderer->generateConfigs();
+}
+
+bool DisplayD3D::testDeviceLost()
+{
+ ASSERT(mRenderer != nullptr);
+ return mRenderer->testDeviceLost();
+}
+
+egl::Error DisplayD3D::restoreLostDevice(const egl::Display *display)
+{
+ // Release surface resources to make the Reset() succeed
+ for (egl::Surface *surface : mState.surfaceSet)
+ {
+ ASSERT(!surface->getBoundTexture());
+ SurfaceD3D *surfaceD3D = GetImplAs<SurfaceD3D>(surface);
+ surfaceD3D->releaseSwapChain();
+ }
+
+ if (!mRenderer->resetDevice())
+ {
+ return egl::EglBadAlloc();
+ }
+
+ // Restore any surfaces that may have been lost
+ for (const egl::Surface *surface : mState.surfaceSet)
+ {
+ SurfaceD3D *surfaceD3D = GetImplAs<SurfaceD3D>(surface);
+
+ ANGLE_TRY(surfaceD3D->resetSwapChain(display));
+ }
+
+ return egl::NoError();
+}
+
+bool DisplayD3D::isValidNativeWindow(EGLNativeWindowType window) const
+{
+ return mRenderer->isValidNativeWindow(window);
+}
+
+egl::Error DisplayD3D::validateClientBuffer(const egl::Config *config,
+ EGLenum buftype,
+ EGLClientBuffer clientBuffer,
+ const egl::AttributeMap &attribs) const
+{
+ switch (buftype)
+ {
+ case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE:
+ return mRenderer->validateShareHandle(config, static_cast<HANDLE>(clientBuffer),
+ attribs);
+
+ case EGL_D3D_TEXTURE_ANGLE:
+ return mRenderer->getD3DTextureInfo(config, static_cast<IUnknown *>(clientBuffer),
+ attribs, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr);
+
+ default:
+ return DisplayImpl::validateClientBuffer(config, buftype, clientBuffer, attribs);
+ }
+}
+
+egl::Error DisplayD3D::validateImageClientBuffer(const gl::Context *context,
+ EGLenum target,
+ EGLClientBuffer clientBuffer,
+ const egl::AttributeMap &attribs) const
+{
+ switch (target)
+ {
+ case EGL_D3D11_TEXTURE_ANGLE:
+ {
+ return mRenderer->getD3DTextureInfo(nullptr, static_cast<IUnknown *>(clientBuffer),
+ attribs, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr);
+ }
+
+ default:
+ return DisplayImpl::validateImageClientBuffer(context, target, clientBuffer, attribs);
+ }
+}
+
+void DisplayD3D::generateExtensions(egl::DisplayExtensions *outExtensions) const
+{
+ mRenderer->generateDisplayExtensions(outExtensions);
+}
+
+std::string DisplayD3D::getRendererDescription()
+{
+ if (mRenderer)
+ {
+ return mRenderer->getRendererDescription();
+ }
+ return std::string();
+}
+
+std::string DisplayD3D::getVendorString()
+{
+ if (mRenderer)
+ {
+ return mRenderer->getVendorString();
+ }
+ return std::string();
+}
+
+std::string DisplayD3D::getVersionString(bool includeFullVersion)
+{
+ if (mRenderer)
+ {
+ return mRenderer->getVersionString(includeFullVersion);
+ }
+ return std::string();
+}
+
+void DisplayD3D::generateCaps(egl::Caps *outCaps) const
+{
+ // Display must be initialized to generate caps
+ ASSERT(mRenderer != nullptr);
+
+ outCaps->textureNPOT = mRenderer->getNativeExtensions().textureNpotOES;
+}
+
+egl::Error DisplayD3D::waitClient(const gl::Context *context)
+{
+ for (egl::Surface *surface : mState.surfaceSet)
+ {
+ SurfaceD3D *surfaceD3D = GetImplAs<SurfaceD3D>(surface);
+ ANGLE_TRY(surfaceD3D->checkForOutOfDateSwapChain(this));
+ }
+
+ return egl::NoError();
+}
+
+egl::Error DisplayD3D::waitNative(const gl::Context *context, EGLint engine)
+{
+ egl::Surface *drawSurface = context->getCurrentDrawSurface();
+ egl::Surface *readSurface = context->getCurrentReadSurface();
+
+ if (drawSurface != nullptr)
+ {
+ SurfaceD3D *drawSurfaceD3D = GetImplAs<SurfaceD3D>(drawSurface);
+ ANGLE_TRY(drawSurfaceD3D->checkForOutOfDateSwapChain(this));
+ }
+
+ if (readSurface != nullptr)
+ {
+ SurfaceD3D *readSurfaceD3D = GetImplAs<SurfaceD3D>(readSurface);
+ ANGLE_TRY(readSurfaceD3D->checkForOutOfDateSwapChain(this));
+ }
+
+ return egl::NoError();
+}
+
+gl::Version DisplayD3D::getMaxSupportedESVersion() const
+{
+ return mRenderer->getMaxSupportedESVersion();
+}
+
+gl::Version DisplayD3D::getMaxConformantESVersion() const
+{
+ return mRenderer->getMaxConformantESVersion();
+}
+
+Optional<gl::Version> DisplayD3D::getMaxSupportedDesktopVersion() const
+{
+ return Optional<gl::Version>::Invalid();
+}
+
+void DisplayD3D::handleResult(HRESULT hr,
+ const char *message,
+ const char *file,
+ const char *function,
+ unsigned int line)
+{
+ ASSERT(FAILED(hr));
+
+ std::stringstream errorStream;
+ errorStream << "Internal D3D11 error: " << gl::FmtHR(hr) << ", in " << file << ", " << function
+ << ":" << line << ". " << message;
+
+ mStoredErrorString = errorStream.str();
+}
+
+void DisplayD3D::initializeFrontendFeatures(angle::FrontendFeatures *features) const
+{
+ mRenderer->initializeFrontendFeatures(features);
+}
+
+void DisplayD3D::populateFeatureList(angle::FeatureList *features)
+{
+ mRenderer->getFeatures().populateFeatureList(features);
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/DisplayD3D.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/DisplayD3D.h
new file mode 100644
index 0000000000..890658f5ea
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/DisplayD3D.h
@@ -0,0 +1,179 @@
+//
+// 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.
+//
+
+// DisplayD3D.h: D3D implementation of egl::Display
+
+#ifndef LIBANGLE_RENDERER_D3D_DISPLAYD3D_H_
+#define LIBANGLE_RENDERER_D3D_DISPLAYD3D_H_
+
+#include "libANGLE/Device.h"
+#include "libANGLE/renderer/DisplayImpl.h"
+
+#include "libANGLE/renderer/d3d/RendererD3D.h"
+
+namespace rx
+{
+class ShareGroupD3D : public ShareGroupImpl
+{};
+
+class DisplayD3D : public DisplayImpl, public d3d::Context
+{
+ public:
+ DisplayD3D(const egl::DisplayState &state);
+
+ egl::Error initialize(egl::Display *display) override;
+ void terminate() override;
+
+ // Surface creation
+ SurfaceImpl *createWindowSurface(const egl::SurfaceState &state,
+ EGLNativeWindowType window,
+ const egl::AttributeMap &attribs) override;
+ SurfaceImpl *createPbufferSurface(const egl::SurfaceState &state,
+ const egl::AttributeMap &attribs) override;
+ SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state,
+ EGLenum buftype,
+ EGLClientBuffer clientBuffer,
+ const egl::AttributeMap &attribs) override;
+ SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state,
+ NativePixmapType nativePixmap,
+ const egl::AttributeMap &attribs) override;
+
+ ImageImpl *createImage(const egl::ImageState &state,
+ const gl::Context *context,
+ EGLenum target,
+ const egl::AttributeMap &attribs) override;
+
+ ContextImpl *createContext(const gl::State &state,
+ gl::ErrorSet *errorSet,
+ const egl::Config *configuration,
+ const gl::Context *shareContext,
+ const egl::AttributeMap &attribs) override;
+
+ StreamProducerImpl *createStreamProducerD3DTexture(egl::Stream::ConsumerType consumerType,
+ const egl::AttributeMap &attribs) override;
+
+ ExternalImageSiblingImpl *createExternalImageSibling(const gl::Context *context,
+ EGLenum target,
+ EGLClientBuffer buffer,
+ const egl::AttributeMap &attribs) override;
+
+ ShareGroupImpl *createShareGroup() override;
+
+ egl::Error makeCurrent(egl::Display *display,
+ egl::Surface *drawSurface,
+ egl::Surface *readSurface,
+ gl::Context *context) override;
+
+ egl::ConfigSet generateConfigs() override;
+
+ bool testDeviceLost() override;
+ egl::Error restoreLostDevice(const egl::Display *display) override;
+
+ bool isValidNativeWindow(EGLNativeWindowType window) const override;
+ egl::Error validateClientBuffer(const egl::Config *configuration,
+ EGLenum buftype,
+ EGLClientBuffer clientBuffer,
+ const egl::AttributeMap &attribs) const override;
+ egl::Error validateImageClientBuffer(const gl::Context *context,
+ EGLenum target,
+ EGLClientBuffer clientBuffer,
+ const egl::AttributeMap &attribs) const override;
+
+ DeviceImpl *createDevice() override;
+
+ std::string getRendererDescription() override;
+ std::string getVendorString() override;
+ std::string getVersionString(bool includeFullVersion) override;
+
+ egl::Error waitClient(const gl::Context *context) override;
+ egl::Error waitNative(const gl::Context *context, EGLint engine) override;
+ gl::Version getMaxSupportedESVersion() const override;
+ gl::Version getMaxConformantESVersion() const override;
+ Optional<gl::Version> getMaxSupportedDesktopVersion() const override;
+
+ void handleResult(HRESULT hr,
+ const char *message,
+ const char *file,
+ const char *function,
+ unsigned int line) override;
+
+ const std::string &getStoredErrorString() const { return mStoredErrorString; }
+
+ void initializeFrontendFeatures(angle::FrontendFeatures *features) const override;
+
+ void populateFeatureList(angle::FeatureList *features) override;
+
+ private:
+ void generateExtensions(egl::DisplayExtensions *outExtensions) const override;
+ void generateCaps(egl::Caps *outCaps) const override;
+
+ egl::Display *mDisplay;
+
+ rx::RendererD3D *mRenderer;
+ std::string mStoredErrorString;
+};
+
+// Possible reasons RendererD3D initialize can fail
+enum D3D11InitError
+{
+ // The renderer loaded successfully
+ D3D11_INIT_SUCCESS = 0,
+ // Failed to load the ANGLE & D3D compiler libraries
+ D3D11_INIT_COMPILER_ERROR,
+ // Failed to load a necessary DLL (non-compiler)
+ D3D11_INIT_MISSING_DEP,
+ // CreateDevice returned E_INVALIDARG
+ D3D11_INIT_CREATEDEVICE_INVALIDARG,
+ // CreateDevice failed with an error other than invalid arg
+ D3D11_INIT_CREATEDEVICE_ERROR,
+ // DXGI 1.2 required but not found
+ D3D11_INIT_INCOMPATIBLE_DXGI,
+ // Other initialization error
+ D3D11_INIT_OTHER_ERROR,
+ // CreateDevice returned E_FAIL
+ D3D11_INIT_CREATEDEVICE_FAIL,
+ // CreateDevice returned E_NOTIMPL
+ D3D11_INIT_CREATEDEVICE_NOTIMPL,
+ // CreateDevice returned E_OUTOFMEMORY
+ D3D11_INIT_CREATEDEVICE_OUTOFMEMORY,
+ // CreateDevice returned DXGI_ERROR_INVALID_CALL
+ D3D11_INIT_CREATEDEVICE_INVALIDCALL,
+ // CreateDevice returned DXGI_ERROR_SDK_COMPONENT_MISSING
+ D3D11_INIT_CREATEDEVICE_COMPONENTMISSING,
+ // CreateDevice returned DXGI_ERROR_WAS_STILL_DRAWING
+ D3D11_INIT_CREATEDEVICE_WASSTILLDRAWING,
+ // CreateDevice returned DXGI_ERROR_NOT_CURRENTLY_AVAILABLE
+ D3D11_INIT_CREATEDEVICE_NOTAVAILABLE,
+ // CreateDevice returned DXGI_ERROR_DEVICE_HUNG
+ D3D11_INIT_CREATEDEVICE_DEVICEHUNG,
+ // CreateDevice returned NULL
+ D3D11_INIT_CREATEDEVICE_NULL,
+ NUM_D3D11_INIT_ERRORS
+};
+
+enum D3D9InitError
+{
+ D3D9_INIT_SUCCESS = 0,
+ // Failed to load the D3D or ANGLE compiler
+ D3D9_INIT_COMPILER_ERROR,
+ // Failed to load a necessary DLL
+ D3D9_INIT_MISSING_DEP,
+ // Device creation error
+ D3D9_INIT_CREATE_DEVICE_ERROR,
+ // System does not meet minimum shader spec
+ D3D9_INIT_UNSUPPORTED_VERSION,
+ // System does not support stretchrect from textures
+ D3D9_INIT_UNSUPPORTED_STRETCHRECT,
+ // A call returned out of memory or device lost
+ D3D9_INIT_OUT_OF_MEMORY,
+ // Other unspecified error
+ D3D9_INIT_OTHER_ERROR,
+ NUM_D3D9_INIT_ERRORS
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_DISPLAYD3D_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/DynamicHLSL.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/DynamicHLSL.cpp
new file mode 100644
index 0000000000..b83c8bac6e
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/DynamicHLSL.cpp
@@ -0,0 +1,1537 @@
+//
+// 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.
+//
+// DynamicHLSL.cpp: Implementation for link and run-time HLSL generation
+//
+
+#include "libANGLE/renderer/d3d/DynamicHLSL.h"
+
+#include "common/string_utils.h"
+#include "common/utilities.h"
+#include "compiler/translator/blocklayoutHLSL.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Program.h"
+#include "libANGLE/Shader.h"
+#include "libANGLE/VaryingPacking.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/d3d/ProgramD3D.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
+#include "libANGLE/renderer/d3d/ShaderD3D.h"
+
+using namespace gl;
+
+namespace rx
+{
+
+namespace
+{
+
+// kShaderStorageDeclarationString must be the same as outputHLSL.
+constexpr const char kShaderStorageDeclarationString[] =
+ "// @@ SHADER STORAGE DECLARATION STRING @@";
+
+const char *HLSLComponentTypeString(GLenum componentType)
+{
+ switch (componentType)
+ {
+ case GL_UNSIGNED_INT:
+ return "uint";
+ case GL_INT:
+ return "int";
+ case GL_UNSIGNED_NORMALIZED:
+ case GL_SIGNED_NORMALIZED:
+ case GL_FLOAT:
+ return "float";
+ default:
+ UNREACHABLE();
+ return "not-component-type";
+ }
+}
+
+void HLSLComponentTypeString(std::ostringstream &ostream, GLenum componentType, int componentCount)
+{
+ ostream << HLSLComponentTypeString(componentType);
+ if (componentCount > 1)
+ {
+ ostream << componentCount;
+ }
+}
+
+const char *HLSLMatrixTypeString(GLenum type)
+{
+ switch (type)
+ {
+ case GL_FLOAT_MAT2:
+ return "float2x2";
+ case GL_FLOAT_MAT3:
+ return "float3x3";
+ case GL_FLOAT_MAT4:
+ return "float4x4";
+ case GL_FLOAT_MAT2x3:
+ return "float2x3";
+ case GL_FLOAT_MAT3x2:
+ return "float3x2";
+ case GL_FLOAT_MAT2x4:
+ return "float2x4";
+ case GL_FLOAT_MAT4x2:
+ return "float4x2";
+ case GL_FLOAT_MAT3x4:
+ return "float3x4";
+ case GL_FLOAT_MAT4x3:
+ return "float4x3";
+ default:
+ UNREACHABLE();
+ return "not-matrix-type";
+ }
+}
+
+void HLSLTypeString(std::ostringstream &ostream, GLenum type)
+{
+ if (gl::IsMatrixType(type))
+ {
+ ostream << HLSLMatrixTypeString(type);
+ return;
+ }
+
+ HLSLComponentTypeString(ostream, gl::VariableComponentType(type),
+ gl::VariableComponentCount(type));
+}
+
+const PixelShaderOutputVariable *FindOutputAtLocation(
+ const std::vector<PixelShaderOutputVariable> &outputVariables,
+ unsigned int location,
+ size_t index = 0)
+{
+ for (auto &outputVar : outputVariables)
+ {
+ if (outputVar.outputLocation == location && outputVar.outputIndex == index)
+ {
+ return &outputVar;
+ }
+ }
+
+ return nullptr;
+}
+
+void WriteArrayString(std::ostringstream &strstr, unsigned int i)
+{
+ static_assert(GL_INVALID_INDEX == UINT_MAX,
+ "GL_INVALID_INDEX must be equal to the max unsigned int.");
+ if (i == UINT_MAX)
+ {
+ return;
+ }
+
+ strstr << "[";
+ strstr << i;
+ strstr << "]";
+}
+
+bool ReplaceShaderStorageDeclaration(const std::vector<ShaderStorageBlock> &shaderStorageBlocks,
+ std::string *hlsl,
+ size_t baseUAVRegister,
+ gl::ShaderType shaderType)
+{
+ std::string ssboHeader;
+ std::ostringstream out(ssboHeader);
+ for (const ShaderStorageBlock &ssbo : shaderStorageBlocks)
+ {
+ size_t uavRegister = baseUAVRegister + ssbo.registerIndex;
+ std::string name = ssbo.name;
+ if (ssbo.arraySize > 0)
+ {
+ for (unsigned int arrayIndex = 0; arrayIndex < ssbo.arraySize; arrayIndex++)
+ {
+ out << "RWByteAddressBuffer "
+ << "dx_" << name << "_" << arrayIndex << ": register(u"
+ << uavRegister + arrayIndex << ");\n";
+ }
+ }
+ else
+ {
+ out << "RWByteAddressBuffer "
+ << "_" << name << ": register(u" << uavRegister << ");\n";
+ }
+ }
+ if (out.str().empty())
+ {
+ return true;
+ }
+ return angle::ReplaceSubstring(hlsl, kShaderStorageDeclarationString, out.str());
+}
+
+constexpr const char *VERTEX_ATTRIBUTE_STUB_STRING = "@@ VERTEX ATTRIBUTES @@";
+constexpr const char *VERTEX_OUTPUT_STUB_STRING = "@@ VERTEX OUTPUT @@";
+constexpr const char *PIXEL_OUTPUT_STUB_STRING = "@@ PIXEL OUTPUT @@";
+constexpr const char *PIXEL_MAIN_PARAMETERS_STUB_STRING = "@@ PIXEL MAIN PARAMETERS @@";
+constexpr const char *MAIN_PROLOGUE_STUB_STRING = "@@ MAIN PROLOGUE @@";
+} // anonymous namespace
+
+// BuiltinInfo implementation
+
+BuiltinInfo::BuiltinInfo() = default;
+BuiltinInfo::~BuiltinInfo() = default;
+
+// DynamicHLSL implementation
+
+DynamicHLSL::DynamicHLSL(RendererD3D *const renderer) : mRenderer(renderer) {}
+
+std::string DynamicHLSL::generateVertexShaderForInputLayout(
+ const std::string &sourceShader,
+ const InputLayout &inputLayout,
+ const std::vector<sh::ShaderVariable> &shaderAttributes,
+ const std::vector<rx::ShaderStorageBlock> &shaderStorageBlocks,
+ size_t baseUAVRegister) const
+{
+ std::ostringstream structStream;
+ std::ostringstream initStream;
+
+ structStream << "struct VS_INPUT\n"
+ << "{\n";
+
+ int semanticIndex = 0;
+ unsigned int inputIndex = 0;
+
+ // If gl_PointSize is used in the shader then pointsprites rendering is expected.
+ // If the renderer does not support Geometry shaders then Instanced PointSprite emulation
+ // must be used.
+ bool usesPointSize = sourceShader.find("GL_USES_POINT_SIZE") != std::string::npos;
+ bool useInstancedPointSpriteEmulation =
+ usesPointSize && mRenderer->getFeatures().useInstancedPointSpriteEmulation.enabled;
+
+ // Instanced PointSprite emulation requires additional entries in the
+ // VS_INPUT structure to support the vertices that make up the quad vertices.
+ // These values must be in sync with the cooresponding values added during inputlayout creation
+ // in InputLayoutCache::applyVertexBuffers().
+ //
+ // The additional entries must appear first in the VS_INPUT layout because
+ // Windows Phone 8 era devices require per vertex data to physically come
+ // before per instance data in the shader.
+ if (useInstancedPointSpriteEmulation)
+ {
+ structStream << " float3 spriteVertexPos : SPRITEPOSITION0;\n"
+ << " float2 spriteTexCoord : SPRITETEXCOORD0;\n";
+ }
+
+ for (size_t attributeIndex = 0; attributeIndex < shaderAttributes.size(); ++attributeIndex)
+ {
+ const sh::ShaderVariable &shaderAttribute = shaderAttributes[attributeIndex];
+ if (!shaderAttribute.name.empty())
+ {
+ ASSERT(inputIndex < MAX_VERTEX_ATTRIBS);
+ angle::FormatID vertexFormatID =
+ inputIndex < inputLayout.size() ? inputLayout[inputIndex] : angle::FormatID::NONE;
+
+ // HLSL code for input structure
+ if (IsMatrixType(shaderAttribute.type))
+ {
+ // Matrix types are always transposed
+ structStream << " "
+ << HLSLMatrixTypeString(TransposeMatrixType(shaderAttribute.type));
+ }
+ else
+ {
+ if (shaderAttribute.name == "gl_InstanceID" ||
+ shaderAttribute.name == "gl_VertexID")
+ {
+ // The input types of the instance ID and vertex ID in HLSL (uint) differs from
+ // the ones in ESSL (int).
+ structStream << " uint";
+ }
+ else
+ {
+ GLenum componentType = mRenderer->getVertexComponentType(vertexFormatID);
+
+ structStream << " ";
+ HLSLComponentTypeString(structStream, componentType,
+ VariableComponentCount(shaderAttribute.type));
+ }
+ }
+
+ structStream << " " << DecorateVariable(shaderAttribute.name) << " : ";
+
+ if (shaderAttribute.name == "gl_InstanceID")
+ {
+ structStream << "SV_InstanceID";
+ }
+ else if (shaderAttribute.name == "gl_VertexID")
+ {
+ structStream << "SV_VertexID";
+ }
+ else
+ {
+ structStream << "TEXCOORD" << semanticIndex;
+ semanticIndex += VariableRegisterCount(shaderAttribute.type);
+ }
+
+ structStream << ";\n";
+
+ // HLSL code for initialization
+ initStream << " " << DecorateVariable(shaderAttribute.name) << " = ";
+
+ // Mismatched vertex attribute to vertex input may result in an undefined
+ // data reinterpretation (eg for pure integer->float, float->pure integer)
+ // TODO: issue warning with gl debug info extension, when supported
+ if (IsMatrixType(shaderAttribute.type) ||
+ (mRenderer->getVertexConversionType(vertexFormatID) & VERTEX_CONVERT_GPU) != 0)
+ {
+ GenerateAttributeConversionHLSL(vertexFormatID, shaderAttribute, initStream);
+ }
+ else
+ {
+ initStream << "input." << DecorateVariable(shaderAttribute.name);
+ }
+
+ if (shaderAttribute.name == "gl_VertexID")
+ {
+ // dx_VertexID contains the firstVertex offset
+ initStream << " + dx_VertexID";
+ }
+
+ initStream << ";\n";
+
+ inputIndex += VariableRowCount(TransposeMatrixType(shaderAttribute.type));
+ }
+ }
+
+ structStream << "};\n"
+ "\n"
+ "void initAttributes(VS_INPUT input)\n"
+ "{\n"
+ << initStream.str() << "}\n";
+
+ std::string vertexHLSL(sourceShader);
+
+ bool success =
+ angle::ReplaceSubstring(&vertexHLSL, VERTEX_ATTRIBUTE_STUB_STRING, structStream.str());
+ ASSERT(success);
+
+ success = ReplaceShaderStorageDeclaration(shaderStorageBlocks, &vertexHLSL, baseUAVRegister,
+ gl::ShaderType::Vertex);
+ ASSERT(success);
+
+ return vertexHLSL;
+}
+
+std::string DynamicHLSL::generatePixelShaderForOutputSignature(
+ const std::string &sourceShader,
+ const std::vector<PixelShaderOutputVariable> &outputVariables,
+ bool usesFragDepth,
+ const std::vector<GLenum> &outputLayout,
+ const std::vector<ShaderStorageBlock> &shaderStorageBlocks,
+ size_t baseUAVRegister) const
+{
+ const int shaderModel = mRenderer->getMajorShaderModel();
+ std::string targetSemantic = (shaderModel >= 4) ? "SV_TARGET" : "COLOR";
+ std::string depthSemantic = (shaderModel >= 4) ? "SV_Depth" : "DEPTH";
+
+ std::ostringstream declarationStream;
+ std::ostringstream copyStream;
+
+ declarationStream << "struct PS_OUTPUT\n"
+ "{\n";
+
+ size_t numOutputs = outputLayout.size();
+
+ // Workaround for HLSL 3.x: We can't do a depth/stencil only render, the runtime will complain.
+ if (numOutputs == 0 && (shaderModel == 3 || !mRenderer->getShaderModelSuffix().empty()))
+ {
+ numOutputs = 1u;
+ }
+ const PixelShaderOutputVariable defaultOutput(GL_FLOAT_VEC4, "unused", "float4(0, 0, 0, 1)", 0,
+ 0);
+ size_t outputIndex = 0;
+
+ for (size_t layoutIndex = 0; layoutIndex < numOutputs; ++layoutIndex)
+ {
+ GLenum binding = outputLayout.empty() ? GL_COLOR_ATTACHMENT0 : outputLayout[layoutIndex];
+
+ if (binding != GL_NONE)
+ {
+ unsigned int location = (binding - GL_COLOR_ATTACHMENT0);
+ outputIndex =
+ layoutIndex > 0 && binding == outputLayout[layoutIndex - 1] ? outputIndex + 1 : 0;
+
+ const PixelShaderOutputVariable *outputVariable =
+ outputLayout.empty() ? &defaultOutput
+ : FindOutputAtLocation(outputVariables, location, outputIndex);
+
+ // OpenGL ES 3.0 spec $4.2.1
+ // If [...] not all user-defined output variables are written, the values of fragment
+ // colors corresponding to unwritten variables are similarly undefined.
+ if (outputVariable)
+ {
+ declarationStream << " ";
+ HLSLTypeString(declarationStream, outputVariable->type);
+ declarationStream << " " << outputVariable->name << " : " << targetSemantic
+ << static_cast<int>(layoutIndex) << ";\n";
+
+ copyStream << " output." << outputVariable->name << " = "
+ << outputVariable->source << ";\n";
+ }
+ }
+ }
+
+ if (usesFragDepth)
+ {
+ declarationStream << " float gl_Depth : " << depthSemantic << ";\n";
+ copyStream << " output.gl_Depth = gl_Depth; \n";
+ }
+
+ declarationStream << "};\n"
+ "\n"
+ "PS_OUTPUT generateOutput()\n"
+ "{\n"
+ " PS_OUTPUT output;\n"
+ << copyStream.str()
+ << " return output;\n"
+ "}\n";
+
+ std::string pixelHLSL(sourceShader);
+
+ bool success =
+ angle::ReplaceSubstring(&pixelHLSL, PIXEL_OUTPUT_STUB_STRING, declarationStream.str());
+ ASSERT(success);
+
+ success = ReplaceShaderStorageDeclaration(shaderStorageBlocks, &pixelHLSL, baseUAVRegister,
+ gl::ShaderType::Fragment);
+ ASSERT(success);
+
+ return pixelHLSL;
+}
+
+std::string DynamicHLSL::generateShaderForImage2DBindSignature(
+ ProgramD3D &programD3D,
+ const gl::ProgramState &programData,
+ gl::ShaderType shaderType,
+ const std::string &shaderHLSL,
+ std::vector<sh::ShaderVariable> &image2DUniforms,
+ const gl::ImageUnitTextureTypeMap &image2DBindLayout,
+ unsigned int baseUAVRegister) const
+{
+ if (image2DUniforms.empty())
+ {
+ return shaderHLSL;
+ }
+
+ return GenerateShaderForImage2DBindSignature(programD3D, programData, shaderType, shaderHLSL,
+ image2DUniforms, image2DBindLayout,
+ baseUAVRegister);
+}
+
+void DynamicHLSL::generateVaryingLinkHLSL(const VaryingPacking &varyingPacking,
+ const BuiltinInfo &builtins,
+ bool programUsesPointSize,
+ std::ostringstream &hlslStream) const
+{
+ ASSERT(builtins.dxPosition.enabled);
+ hlslStream << "{\n"
+ << " float4 dx_Position : " << builtins.dxPosition.str() << ";\n";
+
+ if (builtins.glPosition.enabled)
+ {
+ hlslStream << " float4 gl_Position : " << builtins.glPosition.str() << ";\n";
+ }
+
+ if (builtins.glFragCoord.enabled)
+ {
+ hlslStream << " float4 gl_FragCoord : " << builtins.glFragCoord.str() << ";\n";
+ }
+
+ if (builtins.glPointCoord.enabled)
+ {
+ hlslStream << " float2 gl_PointCoord : " << builtins.glPointCoord.str() << ";\n";
+ }
+
+ if (builtins.glPointSize.enabled)
+ {
+ hlslStream << " float gl_PointSize : " << builtins.glPointSize.str() << ";\n";
+ }
+
+ if (builtins.glViewIDOVR.enabled)
+ {
+ hlslStream << " nointerpolation uint gl_ViewID_OVR : " << builtins.glViewIDOVR.str()
+ << ";\n";
+ }
+
+ std::string varyingSemantic =
+ GetVaryingSemantic(mRenderer->getMajorShaderModel(), programUsesPointSize);
+
+ const auto &registerInfos = varyingPacking.getRegisterList();
+ for (GLuint registerIndex = 0u; registerIndex < registerInfos.size(); ++registerIndex)
+ {
+ const PackedVaryingRegister &registerInfo = registerInfos[registerIndex];
+ const auto &varying = registerInfo.packedVarying->varying();
+ ASSERT(!varying.isStruct());
+
+ // TODO: Add checks to ensure D3D interpolation modifiers don't result in too many
+ // registers being used.
+ // For example, if there are N registers, and we have N vec3 varyings and 1 float
+ // varying, then D3D will pack them into N registers.
+ // If the float varying has the 'nointerpolation' modifier on it then we would need
+ // N + 1 registers, and D3D compilation will fail.
+
+ switch (registerInfo.packedVarying->interpolation)
+ {
+ case sh::INTERPOLATION_SMOOTH:
+ hlslStream << " ";
+ break;
+ case sh::INTERPOLATION_FLAT:
+ hlslStream << " nointerpolation ";
+ break;
+ case sh::INTERPOLATION_CENTROID:
+ hlslStream << " centroid ";
+ break;
+ case sh::INTERPOLATION_SAMPLE:
+ hlslStream << " sample ";
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ GLenum transposedType = gl::TransposeMatrixType(varying.type);
+ GLenum componentType = gl::VariableComponentType(transposedType);
+ int columnCount = gl::VariableColumnCount(transposedType);
+ HLSLComponentTypeString(hlslStream, componentType, columnCount);
+ hlslStream << " v" << registerIndex << " : " << varyingSemantic << registerIndex << ";\n";
+ }
+
+ // Note that the following outputs need to be declared after the others. They are not included
+ // in pixel shader inputs even when they are in vertex/geometry shader outputs, and the pixel
+ // shader input struct must be a prefix of the vertex/geometry shader output struct.
+
+ if (builtins.glViewportIndex.enabled)
+ {
+ hlslStream << " nointerpolation uint gl_ViewportIndex : "
+ << builtins.glViewportIndex.str() << ";\n";
+ }
+
+ if (builtins.glLayer.enabled)
+ {
+ hlslStream << " nointerpolation uint gl_Layer : " << builtins.glLayer.str() << ";\n";
+ }
+
+ hlslStream << "};\n";
+}
+
+void DynamicHLSL::generateShaderLinkHLSL(const gl::Context *context,
+ const gl::Caps &caps,
+ const gl::ProgramState &programData,
+ const ProgramD3DMetadata &programMetadata,
+ const VaryingPacking &varyingPacking,
+ const BuiltinVaryingsD3D &builtinsD3D,
+ gl::ShaderMap<std::string> *shaderHLSL) const
+{
+ ASSERT(shaderHLSL);
+ ASSERT((*shaderHLSL)[gl::ShaderType::Vertex].empty() &&
+ (*shaderHLSL)[gl::ShaderType::Fragment].empty());
+
+ gl::Shader *vertexShaderGL = programData.getAttachedShader(ShaderType::Vertex);
+ gl::Shader *fragmentShaderGL = programData.getAttachedShader(ShaderType::Fragment);
+ const int shaderModel = mRenderer->getMajorShaderModel();
+
+ const ShaderD3D *fragmentShader = nullptr;
+ if (fragmentShaderGL)
+ {
+ fragmentShader = GetImplAs<ShaderD3D>(fragmentShaderGL);
+ }
+
+ // usesViewScale() isn't supported in the D3D9 renderer
+ ASSERT(shaderModel >= 4 || !programMetadata.usesViewScale());
+
+ bool useInstancedPointSpriteEmulation =
+ programMetadata.usesPointSize() &&
+ mRenderer->getFeatures().useInstancedPointSpriteEmulation.enabled;
+
+ // Validation done in the compiler
+ ASSERT(!fragmentShader || !fragmentShader->usesFragColor() || !fragmentShader->usesFragData());
+
+ std::ostringstream vertexStream;
+ vertexStream << "struct VS_OUTPUT\n";
+ const auto &vertexBuiltins = builtinsD3D[gl::ShaderType::Vertex];
+ generateVaryingLinkHLSL(varyingPacking, vertexBuiltins, builtinsD3D.usesPointSize(),
+ vertexStream);
+
+ // Instanced PointSprite emulation requires additional entries originally generated in the
+ // GeometryShader HLSL. These include pointsize clamp values.
+ if (useInstancedPointSpriteEmulation)
+ {
+ vertexStream << "static float minPointSize = " << static_cast<int>(caps.minAliasedPointSize)
+ << ".0f;\n"
+ << "static float maxPointSize = " << static_cast<int>(caps.maxAliasedPointSize)
+ << ".0f;\n";
+ }
+
+ std::ostringstream vertexGenerateOutput;
+ vertexGenerateOutput << "VS_OUTPUT generateOutput(VS_INPUT input)\n"
+ << "{\n"
+ << " VS_OUTPUT output;\n";
+
+ if (vertexBuiltins.glPosition.enabled)
+ {
+ vertexGenerateOutput << " output.gl_Position = gl_Position;\n";
+ }
+
+ if (vertexBuiltins.glViewIDOVR.enabled)
+ {
+ vertexGenerateOutput << " output.gl_ViewID_OVR = ViewID_OVR;\n";
+ }
+ if (programMetadata.hasANGLEMultiviewEnabled() && programMetadata.canSelectViewInVertexShader())
+ {
+ ASSERT(vertexBuiltins.glViewportIndex.enabled && vertexBuiltins.glLayer.enabled);
+ vertexGenerateOutput << " if (multiviewSelectViewportIndex)\n"
+ << " {\n"
+ << " output.gl_ViewportIndex = ViewID_OVR;\n"
+ << " } else {\n"
+ << " output.gl_ViewportIndex = 0;\n"
+ << " output.gl_Layer = ViewID_OVR;\n"
+ << " }\n";
+ }
+
+ // On D3D9 or D3D11 Feature Level 9, we need to emulate large viewports using dx_ViewAdjust.
+ if (shaderModel >= 4 && mRenderer->getShaderModelSuffix() == "")
+ {
+ vertexGenerateOutput << " output.dx_Position.x = gl_Position.x;\n";
+
+ if (programMetadata.usesViewScale())
+ {
+ // This code assumes that dx_ViewScale.y = -1.0f when rendering to texture, and +1.0f
+ // when rendering to the default framebuffer. No other values are valid.
+ vertexGenerateOutput << " output.dx_Position.y = dx_ViewScale.y * gl_Position.y;\n";
+ }
+ else
+ {
+ vertexGenerateOutput
+ << " output.dx_Position.y = clipControlOrigin * gl_Position.y;\n";
+ }
+
+ vertexGenerateOutput
+ << " if (clipControlZeroToOne)\n"
+ << " {\n"
+ << " output.dx_Position.z = gl_Position.z;\n"
+ << " } else {\n"
+ << " output.dx_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n"
+ << " }\n";
+
+ vertexGenerateOutput << " output.dx_Position.w = gl_Position.w;\n";
+ }
+ else
+ {
+ vertexGenerateOutput << " output.dx_Position.x = gl_Position.x * dx_ViewAdjust.z + "
+ "dx_ViewAdjust.x * gl_Position.w;\n";
+
+ // If usesViewScale() is true and we're using the D3D11 renderer via Feature Level 9_*,
+ // then we need to multiply the gl_Position.y by the viewScale.
+ // usesViewScale() isn't supported when using the D3D9 renderer.
+ if (programMetadata.usesViewScale() &&
+ (shaderModel >= 4 && mRenderer->getShaderModelSuffix() != ""))
+ {
+ vertexGenerateOutput << " output.dx_Position.y = dx_ViewScale.y * (gl_Position.y * "
+ "dx_ViewAdjust.w + dx_ViewAdjust.y * gl_Position.w);\n";
+ }
+ else
+ {
+ vertexGenerateOutput << " output.dx_Position.y = clipControlOrigin * (gl_Position.y "
+ "* dx_ViewAdjust.w + "
+ "dx_ViewAdjust.y * gl_Position.w);\n";
+ }
+
+ vertexGenerateOutput
+ << " if (clipControlZeroToOne)\n"
+ << " {\n"
+ << " output.dx_Position.z = gl_Position.z;\n"
+ << " } else {\n"
+ << " output.dx_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n"
+ << " }\n";
+
+ vertexGenerateOutput << " output.dx_Position.w = gl_Position.w;\n";
+ }
+
+ // We don't need to output gl_PointSize if we use are emulating point sprites via instancing.
+ if (vertexBuiltins.glPointSize.enabled)
+ {
+ vertexGenerateOutput << " output.gl_PointSize = gl_PointSize;\n";
+ }
+
+ if (vertexBuiltins.glFragCoord.enabled)
+ {
+ vertexGenerateOutput << " output.gl_FragCoord = gl_Position;\n";
+ }
+
+ const auto &registerInfos = varyingPacking.getRegisterList();
+ for (GLuint registerIndex = 0u; registerIndex < registerInfos.size(); ++registerIndex)
+ {
+ const PackedVaryingRegister &registerInfo = registerInfos[registerIndex];
+ const auto &packedVarying = *registerInfo.packedVarying;
+ const auto &varying = *packedVarying.frontVarying.varying;
+ ASSERT(!varying.isStruct());
+
+ vertexGenerateOutput << " output.v" << registerIndex << " = ";
+
+ if (packedVarying.isStructField())
+ {
+ vertexGenerateOutput << DecorateVariable(packedVarying.frontVarying.parentStructName)
+ << ".";
+ }
+
+ vertexGenerateOutput << DecorateVariable(varying.name);
+
+ if (varying.isArray())
+ {
+ WriteArrayString(vertexGenerateOutput, registerInfo.varyingArrayIndex);
+ }
+
+ if (VariableRowCount(varying.type) > 1)
+ {
+ WriteArrayString(vertexGenerateOutput, registerInfo.varyingRowIndex);
+ }
+
+ vertexGenerateOutput << ";\n";
+ }
+
+ // Instanced PointSprite emulation requires additional entries to calculate
+ // the final output vertex positions of the quad that represents each sprite.
+ if (useInstancedPointSpriteEmulation)
+ {
+ vertexGenerateOutput
+ << "\n"
+ << " gl_PointSize = clamp(gl_PointSize, minPointSize, maxPointSize);\n";
+
+ vertexGenerateOutput
+ << " output.dx_Position.x += (input.spriteVertexPos.x * gl_PointSize / "
+ "(dx_ViewCoords.x*2)) * output.dx_Position.w;";
+
+ if (programMetadata.usesViewScale())
+ {
+ // Multiply by ViewScale to invert the rendering when appropriate
+ vertexGenerateOutput
+ << " output.dx_Position.y += (-dx_ViewScale.y * "
+ "input.spriteVertexPos.y * gl_PointSize / (dx_ViewCoords.y*2)) * "
+ "output.dx_Position.w;";
+ }
+ else
+ {
+ vertexGenerateOutput
+ << " output.dx_Position.y += (input.spriteVertexPos.y * gl_PointSize / "
+ "(dx_ViewCoords.y*2)) * output.dx_Position.w;";
+ }
+
+ vertexGenerateOutput
+ << " output.dx_Position.z += input.spriteVertexPos.z * output.dx_Position.w;\n";
+
+ if (programMetadata.usesPointCoord())
+ {
+ vertexGenerateOutput << "\n"
+ << " output.gl_PointCoord = input.spriteTexCoord;\n";
+ }
+ }
+
+ // Renderers that enable instanced pointsprite emulation require the vertex shader output member
+ // gl_PointCoord to be set to a default value if used without gl_PointSize. 0.5,0.5 is the same
+ // default value used in the generated pixel shader.
+ if (programMetadata.usesInsertedPointCoordValue())
+ {
+ ASSERT(!useInstancedPointSpriteEmulation);
+ vertexGenerateOutput << "\n"
+ << " output.gl_PointCoord = float2(0.5, 0.5);\n";
+ }
+
+ vertexGenerateOutput << "\n"
+ << " return output;\n"
+ << "}";
+
+ if (vertexShaderGL)
+ {
+ std::string vertexSource = vertexShaderGL->getTranslatedSource(context);
+ angle::ReplaceSubstring(&vertexSource, std::string(MAIN_PROLOGUE_STUB_STRING),
+ " initAttributes(input);\n");
+ angle::ReplaceSubstring(&vertexSource, std::string(VERTEX_OUTPUT_STUB_STRING),
+ vertexGenerateOutput.str());
+ vertexStream << vertexSource;
+ }
+
+ const auto &pixelBuiltins = builtinsD3D[gl::ShaderType::Fragment];
+
+ std::ostringstream pixelStream;
+ pixelStream << "struct PS_INPUT\n";
+ generateVaryingLinkHLSL(varyingPacking, pixelBuiltins, builtinsD3D.usesPointSize(),
+ pixelStream);
+ pixelStream << "\n";
+
+ std::ostringstream pixelPrologue;
+ if (fragmentShader && fragmentShader->usesViewID())
+ {
+ ASSERT(pixelBuiltins.glViewIDOVR.enabled);
+ pixelPrologue << " ViewID_OVR = input.gl_ViewID_OVR;\n";
+ }
+
+ if (pixelBuiltins.glFragCoord.enabled)
+ {
+ pixelPrologue << " float rhw = 1.0 / input.gl_FragCoord.w;\n";
+
+ // Certain Shader Models (4_0+ and 3_0) allow reading from dx_Position in the pixel shader.
+ // Other Shader Models (4_0_level_9_3 and 2_x) don't support this, so we emulate it using
+ // dx_ViewCoords.
+ // DComp usually gives us an offset at (0, 0), but this is not always the case. It is
+ // valid for DComp to give us an offset into the texture atlas. In that scenario, we
+ // need to offset gl_FragCoord using dx_FragCoordOffset to point to the correct location
+ // of the pixel.
+ if (shaderModel >= 4 && mRenderer->getShaderModelSuffix() == "")
+ {
+ pixelPrologue << " gl_FragCoord.x = input.dx_Position.x - dx_FragCoordOffset.x;\n"
+ << " gl_FragCoord.y = input.dx_Position.y - dx_FragCoordOffset.y;\n";
+ }
+ else if (shaderModel == 3)
+ {
+ pixelPrologue
+ << " gl_FragCoord.x = input.dx_Position.x + 0.5 - dx_FragCoordOffset.x;\n"
+ << " gl_FragCoord.y = input.dx_Position.y + 0.5 - dx_FragCoordOffset.y;\n";
+ }
+ else
+ {
+ // dx_ViewCoords contains the viewport width/2, height/2, center.x and center.y. See
+ // Renderer::setViewport()
+ pixelPrologue
+ << " gl_FragCoord.x = (input.gl_FragCoord.x * rhw) * dx_ViewCoords.x + "
+ "dx_ViewCoords.z - dx_FragCoordOffset.x;\n"
+ << " gl_FragCoord.y = (input.gl_FragCoord.y * rhw) * dx_ViewCoords.y + "
+ "dx_ViewCoords.w - dx_FragCoordOffset.y;\n";
+ }
+
+ if (programMetadata.usesViewScale())
+ {
+ // For Feature Level 9_3 and below, we need to correct gl_FragCoord.y to account
+ // for dx_ViewScale. On Feature Level 10_0+, gl_FragCoord.y is calculated above using
+ // dx_ViewCoords and is always correct irrespective of dx_ViewScale's value.
+ // NOTE: usesViewScale() can only be true on D3D11 (i.e. Shader Model 4.0+).
+ if (shaderModel >= 4 && mRenderer->getShaderModelSuffix() == "")
+ {
+ // Some assumptions:
+ // - dx_ViewScale.y = -1.0f when rendering to texture
+ // - dx_ViewScale.y = +1.0f when rendering to the default framebuffer
+ // - gl_FragCoord.y has been set correctly above.
+ //
+ // When rendering to the backbuffer, the code inverts gl_FragCoord's y coordinate.
+ // This involves subtracting the y coordinate from the height of the area being
+ // rendered to.
+ //
+ // First we calculate the height of the area being rendered to:
+ // render_area_height = (2.0f / (1.0f - input.gl_FragCoord.y * rhw)) *
+ // gl_FragCoord.y
+ //
+ // Note that when we're rendering to default FB, we want our output to be
+ // equivalent to:
+ // "gl_FragCoord.y = render_area_height - gl_FragCoord.y"
+ //
+ // When we're rendering to a texture, we want our output to be equivalent to:
+ // "gl_FragCoord.y = gl_FragCoord.y;"
+ //
+ // If we set scale_factor = ((1.0f + dx_ViewScale.y) / 2.0f), then notice that
+ // - When rendering to default FB: scale_factor = 1.0f
+ // - When rendering to texture: scale_factor = 0.0f
+ //
+ // Therefore, we can get our desired output by setting:
+ // "gl_FragCoord.y = scale_factor * render_area_height - dx_ViewScale.y *
+ // gl_FragCoord.y"
+ //
+ // Simplifying, this becomes:
+ pixelPrologue
+ << " gl_FragCoord.y = (1.0f + dx_ViewScale.y) * gl_FragCoord.y /"
+ "(1.0f - input.gl_FragCoord.y * rhw) - dx_ViewScale.y * gl_FragCoord.y;\n";
+ }
+ }
+
+ pixelPrologue << " gl_FragCoord.z = (input.gl_FragCoord.z * rhw) * dx_DepthFront.x + "
+ "dx_DepthFront.y;\n"
+ << " gl_FragCoord.w = rhw;\n";
+ }
+
+ if (pixelBuiltins.glPointCoord.enabled && shaderModel >= 3)
+ {
+ pixelPrologue << " gl_PointCoord.x = input.gl_PointCoord.x;\n"
+ << " gl_PointCoord.y = 1.0 - input.gl_PointCoord.y;\n";
+ }
+
+ if (fragmentShader && fragmentShader->usesFrontFacing())
+ {
+ if (shaderModel <= 3)
+ {
+ pixelPrologue << " gl_FrontFacing = (vFace * dx_DepthFront.z >= 0.0);\n";
+ }
+ else
+ {
+ pixelPrologue << " gl_FrontFacing = isFrontFace;\n";
+ }
+ }
+
+ for (GLuint registerIndex = 0u; registerIndex < registerInfos.size(); ++registerIndex)
+ {
+ const PackedVaryingRegister &registerInfo = registerInfos[registerIndex];
+ const auto &packedVarying = *registerInfo.packedVarying;
+
+ // Don't reference VS-only transform feedback varyings in the PS.
+ if (packedVarying.vertexOnly())
+ {
+ continue;
+ }
+
+ const auto &varying = *packedVarying.backVarying.varying;
+ ASSERT(!varying.isBuiltIn() && !varying.isStruct());
+
+ // Note that we're relying on that the active flag is set according to usage in the fragment
+ // shader.
+ if (!varying.active)
+ {
+ continue;
+ }
+
+ pixelPrologue << " ";
+
+ if (packedVarying.isStructField())
+ {
+ pixelPrologue << DecorateVariable(packedVarying.backVarying.parentStructName) << ".";
+ }
+
+ pixelPrologue << DecorateVariable(varying.name);
+
+ if (varying.isArray())
+ {
+ WriteArrayString(pixelPrologue, registerInfo.varyingArrayIndex);
+ }
+
+ GLenum transposedType = TransposeMatrixType(varying.type);
+ if (VariableRowCount(transposedType) > 1)
+ {
+ WriteArrayString(pixelPrologue, registerInfo.varyingRowIndex);
+ }
+
+ pixelPrologue << " = input.v" << registerIndex;
+
+ switch (VariableColumnCount(transposedType))
+ {
+ case 1:
+ pixelPrologue << ".x";
+ break;
+ case 2:
+ pixelPrologue << ".xy";
+ break;
+ case 3:
+ pixelPrologue << ".xyz";
+ break;
+ case 4:
+ break;
+ default:
+ UNREACHABLE();
+ }
+ pixelPrologue << ";\n";
+ }
+
+ if (fragmentShaderGL)
+ {
+ std::string pixelSource = fragmentShaderGL->getTranslatedSource(context);
+
+ if (fragmentShader->usesFrontFacing())
+ {
+ if (shaderModel >= 4)
+ {
+ angle::ReplaceSubstring(&pixelSource,
+ std::string(PIXEL_MAIN_PARAMETERS_STUB_STRING),
+ "PS_INPUT input, bool isFrontFace : SV_IsFrontFace");
+ }
+ else
+ {
+ angle::ReplaceSubstring(&pixelSource,
+ std::string(PIXEL_MAIN_PARAMETERS_STUB_STRING),
+ "PS_INPUT input, float vFace : VFACE");
+ }
+ }
+ else
+ {
+ angle::ReplaceSubstring(&pixelSource, std::string(PIXEL_MAIN_PARAMETERS_STUB_STRING),
+ "PS_INPUT input");
+ }
+
+ angle::ReplaceSubstring(&pixelSource, std::string(MAIN_PROLOGUE_STUB_STRING),
+ pixelPrologue.str());
+ pixelStream << pixelSource;
+ }
+
+ (*shaderHLSL)[gl::ShaderType::Vertex] = vertexStream.str();
+ (*shaderHLSL)[gl::ShaderType::Fragment] = pixelStream.str();
+}
+
+std::string DynamicHLSL::generateGeometryShaderPreamble(const VaryingPacking &varyingPacking,
+ const BuiltinVaryingsD3D &builtinsD3D,
+ const bool hasANGLEMultiviewEnabled,
+ const bool selectViewInVS) const
+{
+ ASSERT(mRenderer->getMajorShaderModel() >= 4);
+
+ std::ostringstream preambleStream;
+
+ const auto &vertexBuiltins = builtinsD3D[gl::ShaderType::Vertex];
+
+ preambleStream << "struct GS_INPUT\n";
+ generateVaryingLinkHLSL(varyingPacking, vertexBuiltins, builtinsD3D.usesPointSize(),
+ preambleStream);
+ preambleStream << "\n"
+ << "struct GS_OUTPUT\n";
+ generateVaryingLinkHLSL(varyingPacking, builtinsD3D[gl::ShaderType::Geometry],
+ builtinsD3D.usesPointSize(), preambleStream);
+ preambleStream
+ << "\n"
+ << "void copyVertex(inout GS_OUTPUT output, GS_INPUT input, GS_INPUT flatinput)\n"
+ << "{\n"
+ << " output.gl_Position = input.gl_Position;\n";
+
+ if (vertexBuiltins.glPointSize.enabled)
+ {
+ preambleStream << " output.gl_PointSize = input.gl_PointSize;\n";
+ }
+
+ if (hasANGLEMultiviewEnabled)
+ {
+ preambleStream << " output.gl_ViewID_OVR = input.gl_ViewID_OVR;\n";
+ if (selectViewInVS)
+ {
+ ASSERT(builtinsD3D[gl::ShaderType::Geometry].glViewportIndex.enabled &&
+ builtinsD3D[gl::ShaderType::Geometry].glLayer.enabled);
+
+ // If the view is already selected in the VS, then we just pass the gl_ViewportIndex and
+ // gl_Layer to the output.
+ preambleStream << " output.gl_ViewportIndex = input.gl_ViewportIndex;\n"
+ << " output.gl_Layer = input.gl_Layer;\n";
+ }
+ }
+
+ const auto &registerInfos = varyingPacking.getRegisterList();
+ for (GLuint registerIndex = 0u; registerIndex < registerInfos.size(); ++registerIndex)
+ {
+ const PackedVaryingRegister &varyingRegister = registerInfos[registerIndex];
+ preambleStream << " output.v" << registerIndex << " = ";
+ if (varyingRegister.packedVarying->interpolation == sh::INTERPOLATION_FLAT)
+ {
+ preambleStream << "flat";
+ }
+ preambleStream << "input.v" << registerIndex << "; \n";
+ }
+
+ if (vertexBuiltins.glFragCoord.enabled)
+ {
+ preambleStream << " output.gl_FragCoord = input.gl_FragCoord;\n";
+ }
+
+ // Only write the dx_Position if we aren't using point sprites
+ preambleStream << "#ifndef ANGLE_POINT_SPRITE_SHADER\n"
+ << " output.dx_Position = input.dx_Position;\n"
+ << "#endif // ANGLE_POINT_SPRITE_SHADER\n"
+ << "}\n";
+
+ if (hasANGLEMultiviewEnabled && !selectViewInVS)
+ {
+ ASSERT(builtinsD3D[gl::ShaderType::Geometry].glViewportIndex.enabled &&
+ builtinsD3D[gl::ShaderType::Geometry].glLayer.enabled);
+
+ // According to the HLSL reference, using SV_RenderTargetArrayIndex is only valid if the
+ // render target is an array resource. Because of this we do not write to gl_Layer if we are
+ // taking the side-by-side code path. We still select the viewport index in the layered code
+ // path as that is always valid. See:
+ // https://msdn.microsoft.com/en-us/library/windows/desktop/bb509647(v=vs.85).aspx
+ preambleStream << "\n"
+ << "void selectView(inout GS_OUTPUT output, GS_INPUT input)\n"
+ << "{\n"
+ << " if (multiviewSelectViewportIndex)\n"
+ << " {\n"
+ << " output.gl_ViewportIndex = input.gl_ViewID_OVR;\n"
+ << " } else {\n"
+ << " output.gl_ViewportIndex = 0;\n"
+ << " output.gl_Layer = input.gl_ViewID_OVR;\n"
+ << " }\n"
+ << "}\n";
+ }
+
+ return preambleStream.str();
+}
+
+std::string DynamicHLSL::generateGeometryShaderHLSL(const gl::Caps &caps,
+ gl::PrimitiveMode primitiveType,
+ const gl::ProgramState &programData,
+ const bool useViewScale,
+ const bool hasANGLEMultiviewEnabled,
+ const bool selectViewInVS,
+ const bool pointSpriteEmulation,
+ const std::string &preambleString) const
+{
+ ASSERT(mRenderer->getMajorShaderModel() >= 4);
+
+ std::stringstream shaderStream;
+
+ const bool pointSprites = (primitiveType == gl::PrimitiveMode::Points) && pointSpriteEmulation;
+ const bool usesPointCoord = preambleString.find("gl_PointCoord") != std::string::npos;
+
+ const char *inputPT = nullptr;
+ const char *outputPT = nullptr;
+ int inputSize = 0;
+ int maxVertexOutput = 0;
+
+ switch (primitiveType)
+ {
+ case gl::PrimitiveMode::Points:
+ inputPT = "point";
+ inputSize = 1;
+
+ if (pointSprites)
+ {
+ outputPT = "Triangle";
+ maxVertexOutput = 4;
+ }
+ else
+ {
+ outputPT = "Point";
+ maxVertexOutput = 1;
+ }
+
+ break;
+
+ case gl::PrimitiveMode::Lines:
+ case gl::PrimitiveMode::LineStrip:
+ case gl::PrimitiveMode::LineLoop:
+ inputPT = "line";
+ outputPT = "Line";
+ inputSize = 2;
+ maxVertexOutput = 2;
+ break;
+
+ case gl::PrimitiveMode::Triangles:
+ case gl::PrimitiveMode::TriangleStrip:
+ case gl::PrimitiveMode::TriangleFan:
+ inputPT = "triangle";
+ outputPT = "Triangle";
+ inputSize = 3;
+ maxVertexOutput = 3;
+ break;
+
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ if (pointSprites || hasANGLEMultiviewEnabled)
+ {
+ shaderStream << "cbuffer DriverConstants : register(b0)\n"
+ "{\n";
+
+ if (pointSprites)
+ {
+ shaderStream << " float4 dx_ViewCoords : packoffset(c1);\n";
+ if (useViewScale)
+ {
+ shaderStream << " float2 dx_ViewScale : packoffset(c3.z);\n";
+ }
+ }
+
+ if (hasANGLEMultiviewEnabled)
+ {
+ // We have to add a value which we can use to keep track of which multi-view code path
+ // is to be selected in the GS.
+ shaderStream << " float multiviewSelectViewportIndex : packoffset(c4.x);\n";
+ }
+
+ shaderStream << "};\n\n";
+ }
+
+ if (pointSprites)
+ {
+ shaderStream << "#define ANGLE_POINT_SPRITE_SHADER\n"
+ "\n"
+ "static float2 pointSpriteCorners[] = \n"
+ "{\n"
+ " float2( 0.5f, -0.5f),\n"
+ " float2( 0.5f, 0.5f),\n"
+ " float2(-0.5f, -0.5f),\n"
+ " float2(-0.5f, 0.5f)\n"
+ "};\n"
+ "\n"
+ "static float2 pointSpriteTexcoords[] = \n"
+ "{\n"
+ " float2(1.0f, 1.0f),\n"
+ " float2(1.0f, 0.0f),\n"
+ " float2(0.0f, 1.0f),\n"
+ " float2(0.0f, 0.0f)\n"
+ "};\n"
+ "\n"
+ "static float minPointSize = "
+ << static_cast<int>(caps.minAliasedPointSize)
+ << ".0f;\n"
+ "static float maxPointSize = "
+ << static_cast<int>(caps.maxAliasedPointSize) << ".0f;\n"
+ << "\n";
+ }
+
+ shaderStream << preambleString << "\n"
+ << "[maxvertexcount(" << maxVertexOutput << ")]\n"
+ << "void main(" << inputPT << " GS_INPUT input[" << inputSize << "], ";
+
+ if (primitiveType == gl::PrimitiveMode::TriangleStrip)
+ {
+ shaderStream << "uint primitiveID : SV_PrimitiveID, ";
+ }
+
+ shaderStream << " inout " << outputPT << "Stream<GS_OUTPUT> outStream)\n"
+ << "{\n"
+ << " GS_OUTPUT output = (GS_OUTPUT)0;\n";
+
+ if (primitiveType == gl::PrimitiveMode::TriangleStrip)
+ {
+ shaderStream << " uint lastVertexIndex = (primitiveID % 2 == 0 ? 2 : 1);\n";
+ }
+ else
+ {
+ shaderStream << " uint lastVertexIndex = " << (inputSize - 1) << ";\n";
+ }
+
+ for (int vertexIndex = 0; vertexIndex < inputSize; ++vertexIndex)
+ {
+ shaderStream << " copyVertex(output, input[" << vertexIndex
+ << "], input[lastVertexIndex]);\n";
+ if (hasANGLEMultiviewEnabled && !selectViewInVS)
+ {
+ shaderStream << " selectView(output, input[" << vertexIndex << "]);\n";
+ }
+ if (!pointSprites)
+ {
+ ASSERT(inputSize == maxVertexOutput);
+ shaderStream << " outStream.Append(output);\n";
+ }
+ }
+
+ if (pointSprites)
+ {
+ shaderStream << "\n"
+ " float4 dx_Position = input[0].dx_Position;\n"
+ " float gl_PointSize = clamp(input[0].gl_PointSize, minPointSize, "
+ "maxPointSize);\n"
+ " float2 viewportScale = float2(1.0f / dx_ViewCoords.x, 1.0f / "
+ "dx_ViewCoords.y) * dx_Position.w;\n";
+
+ for (int corner = 0; corner < 4; corner++)
+ {
+ if (useViewScale)
+ {
+ shaderStream << " \n"
+ " output.dx_Position = dx_Position + float4(1.0f, "
+ "-dx_ViewScale.y, 1.0f, 1.0f)"
+ " * float4(pointSpriteCorners["
+ << corner << "] * viewportScale * gl_PointSize, 0.0f, 0.0f);\n";
+ }
+ else
+ {
+ shaderStream << "\n"
+ " output.dx_Position = dx_Position + float4(pointSpriteCorners["
+ << corner << "] * viewportScale * gl_PointSize, 0.0f, 0.0f);\n";
+ }
+
+ if (usesPointCoord)
+ {
+ shaderStream << " output.gl_PointCoord = pointSpriteTexcoords[" << corner
+ << "];\n";
+ }
+
+ shaderStream << " outStream.Append(output);\n";
+ }
+ }
+
+ shaderStream << " \n"
+ " outStream.RestartStrip();\n"
+ "}\n";
+
+ return shaderStream.str();
+}
+
+// static
+void DynamicHLSL::GenerateAttributeConversionHLSL(angle::FormatID vertexFormatID,
+ const sh::ShaderVariable &shaderAttrib,
+ std::ostringstream &outStream)
+{
+ // Matrix
+ if (IsMatrixType(shaderAttrib.type))
+ {
+ outStream << "transpose(input." << DecorateVariable(shaderAttrib.name) << ")";
+ return;
+ }
+
+ GLenum shaderComponentType = VariableComponentType(shaderAttrib.type);
+ int shaderComponentCount = VariableComponentCount(shaderAttrib.type);
+ const gl::VertexFormat &vertexFormat = gl::GetVertexFormatFromID(vertexFormatID);
+
+ // Perform integer to float conversion (if necessary)
+ if (shaderComponentType == GL_FLOAT && vertexFormat.type != GL_FLOAT)
+ {
+ // TODO: normalization for 32-bit integer formats
+ ASSERT(!vertexFormat.normalized && !vertexFormat.pureInteger);
+ outStream << "float" << shaderComponentCount << "(input."
+ << DecorateVariable(shaderAttrib.name) << ")";
+ return;
+ }
+
+ // No conversion necessary
+ outStream << "input." << DecorateVariable(shaderAttrib.name);
+}
+
+void DynamicHLSL::getPixelShaderOutputKey(const gl::State &data,
+ const gl::ProgramState &programData,
+ const ProgramD3DMetadata &metadata,
+ std::vector<PixelShaderOutputVariable> *outPixelShaderKey)
+{
+ // Two cases when writing to gl_FragColor and using ESSL 1.0:
+ // - with a 3.0 context, the output color is copied to channel 0
+ // - with a 2.0 context, the output color is broadcast to all channels
+ bool broadcast = metadata.usesBroadcast(data);
+ const unsigned int numRenderTargets =
+ (broadcast || metadata.usesMultipleFragmentOuts()
+ ? static_cast<unsigned int>(data.getCaps().maxDrawBuffers)
+ : 1);
+
+ if (!metadata.usesCustomOutVars())
+ {
+ for (unsigned int renderTargetIndex = 0; renderTargetIndex < numRenderTargets;
+ renderTargetIndex++)
+ {
+ PixelShaderOutputVariable outputKeyVariable;
+ outputKeyVariable.type = GL_FLOAT_VEC4;
+ outputKeyVariable.name = "gl_Color" + Str(renderTargetIndex);
+ outputKeyVariable.source =
+ broadcast ? "gl_Color[0]" : "gl_Color[" + Str(renderTargetIndex) + "]";
+ outputKeyVariable.outputLocation = renderTargetIndex;
+
+ outPixelShaderKey->push_back(outputKeyVariable);
+ }
+
+ if (metadata.usesSecondaryColor())
+ {
+ for (unsigned int secondaryIndex = 0;
+ secondaryIndex < data.getCaps().maxDualSourceDrawBuffers; secondaryIndex++)
+ {
+ PixelShaderOutputVariable outputKeyVariable;
+ outputKeyVariable.type = GL_FLOAT_VEC4;
+ outputKeyVariable.name = "gl_SecondaryColor" + Str(secondaryIndex);
+ outputKeyVariable.source = "gl_SecondaryColor[" + Str(secondaryIndex) + "]";
+ outputKeyVariable.outputLocation = secondaryIndex;
+ outputKeyVariable.outputIndex = 1;
+
+ outPixelShaderKey->push_back(outputKeyVariable);
+ }
+ }
+ }
+ else
+ {
+ const ShaderD3D *fragmentShader = metadata.getFragmentShader();
+
+ if (!fragmentShader)
+ {
+ return;
+ }
+
+ const auto &shaderOutputVars = fragmentShader->getState().getActiveOutputVariables();
+
+ for (size_t outputLocationIndex = 0u;
+ outputLocationIndex < programData.getOutputLocations().size(); ++outputLocationIndex)
+ {
+ const VariableLocation &outputLocation =
+ programData.getOutputLocations().at(outputLocationIndex);
+ if (!outputLocation.used())
+ {
+ continue;
+ }
+ const sh::ShaderVariable &outputVariable = shaderOutputVars[outputLocation.index];
+ const std::string &variableName = "out_" + outputVariable.name;
+
+ // Fragment outputs can't be arrays of arrays. ESSL 3.10 section 4.3.6.
+ const std::string &elementString =
+ (outputVariable.isArray() ? Str(outputLocation.arrayIndex) : "");
+
+ ASSERT(outputVariable.active);
+
+ PixelShaderOutputVariable outputKeyVariable;
+ outputKeyVariable.type = outputVariable.type;
+ outputKeyVariable.name = variableName + elementString;
+ outputKeyVariable.source =
+ variableName +
+ (outputVariable.isArray() ? ArrayString(outputLocation.arrayIndex) : "");
+ outputKeyVariable.outputLocation = outputLocationIndex;
+
+ outPixelShaderKey->push_back(outputKeyVariable);
+ }
+
+ // Now generate any secondary outputs...
+ for (size_t outputLocationIndex = 0u;
+ outputLocationIndex < programData.getSecondaryOutputLocations().size();
+ ++outputLocationIndex)
+ {
+ const VariableLocation &outputLocation =
+ programData.getSecondaryOutputLocations().at(outputLocationIndex);
+ if (!outputLocation.used())
+ {
+ continue;
+ }
+ const sh::ShaderVariable &outputVariable = shaderOutputVars[outputLocation.index];
+ const std::string &variableName = "out_" + outputVariable.name;
+
+ // Fragment outputs can't be arrays of arrays. ESSL 3.10 section 4.3.6.
+ const std::string &elementString =
+ (outputVariable.isArray() ? Str(outputLocation.arrayIndex) : "");
+
+ ASSERT(outputVariable.active);
+
+ PixelShaderOutputVariable outputKeyVariable;
+ outputKeyVariable.type = outputVariable.type;
+ outputKeyVariable.name = variableName + elementString;
+ outputKeyVariable.source =
+ variableName +
+ (outputVariable.isArray() ? ArrayString(outputLocation.arrayIndex) : "");
+ outputKeyVariable.outputLocation = outputLocationIndex;
+ outputKeyVariable.outputIndex = 1;
+
+ outPixelShaderKey->push_back(outputKeyVariable);
+ }
+ }
+}
+
+// BuiltinVarying Implementation.
+BuiltinVarying::BuiltinVarying() : enabled(false), index(0), systemValue(false) {}
+
+std::string BuiltinVarying::str() const
+{
+ return (systemValue ? semantic : (semantic + Str(index)));
+}
+
+void BuiltinVarying::enableSystem(const std::string &systemValueSemantic)
+{
+ enabled = true;
+ semantic = systemValueSemantic;
+ systemValue = true;
+}
+
+void BuiltinVarying::enable(const std::string &semanticVal, unsigned int indexVal)
+{
+ enabled = true;
+ semantic = semanticVal;
+ index = indexVal;
+}
+
+// BuiltinVaryingsD3D Implementation.
+BuiltinVaryingsD3D::BuiltinVaryingsD3D(const ProgramD3DMetadata &metadata,
+ const VaryingPacking &packing)
+{
+ updateBuiltins(gl::ShaderType::Vertex, metadata, packing);
+ updateBuiltins(gl::ShaderType::Fragment, metadata, packing);
+ int shaderModel = metadata.getRendererMajorShaderModel();
+ if (shaderModel >= 4)
+ {
+ updateBuiltins(gl::ShaderType::Geometry, metadata, packing);
+ }
+ // In shader model >= 4, some builtins need to be the same in vertex and pixel shaders - input
+ // struct needs to be a prefix of output struct.
+ ASSERT(shaderModel < 4 || mBuiltinInfo[gl::ShaderType::Vertex].glPosition.enabled ==
+ mBuiltinInfo[gl::ShaderType::Fragment].glPosition.enabled);
+ ASSERT(shaderModel < 4 || mBuiltinInfo[gl::ShaderType::Vertex].glFragCoord.enabled ==
+ mBuiltinInfo[gl::ShaderType::Fragment].glFragCoord.enabled);
+ ASSERT(shaderModel < 4 || mBuiltinInfo[gl::ShaderType::Vertex].glPointCoord.enabled ==
+ mBuiltinInfo[gl::ShaderType::Fragment].glPointCoord.enabled);
+ ASSERT(shaderModel < 4 || mBuiltinInfo[gl::ShaderType::Vertex].glPointSize.enabled ==
+ mBuiltinInfo[gl::ShaderType::Fragment].glPointSize.enabled);
+ ASSERT(shaderModel < 4 || mBuiltinInfo[gl::ShaderType::Vertex].glViewIDOVR.enabled ==
+ mBuiltinInfo[gl::ShaderType::Fragment].glViewIDOVR.enabled);
+}
+
+BuiltinVaryingsD3D::~BuiltinVaryingsD3D() = default;
+
+void BuiltinVaryingsD3D::updateBuiltins(gl::ShaderType shaderType,
+ const ProgramD3DMetadata &metadata,
+ const VaryingPacking &packing)
+{
+ const std::string &userSemantic = GetVaryingSemantic(metadata.getRendererMajorShaderModel(),
+ metadata.usesSystemValuePointSize());
+
+ // Note that when enabling builtins only for specific shader stages in shader model >= 4, the
+ // code needs to ensure that the input struct of the shader stage is a prefix of the output
+ // struct of the previous stage.
+
+ unsigned int reservedSemanticIndex = packing.getMaxSemanticIndex();
+
+ BuiltinInfo *builtins = &mBuiltinInfo[shaderType];
+
+ if (metadata.getRendererMajorShaderModel() >= 4)
+ {
+ builtins->dxPosition.enableSystem("SV_Position");
+ }
+ else if (shaderType == gl::ShaderType::Fragment)
+ {
+ builtins->dxPosition.enableSystem("VPOS");
+ }
+ else
+ {
+ builtins->dxPosition.enableSystem("POSITION");
+ }
+
+ if (metadata.usesTransformFeedbackGLPosition())
+ {
+ builtins->glPosition.enable(userSemantic, reservedSemanticIndex++);
+ }
+
+ if (metadata.usesFragCoord())
+ {
+ builtins->glFragCoord.enable(userSemantic, reservedSemanticIndex++);
+ }
+
+ if (shaderType == gl::ShaderType::Vertex ? metadata.addsPointCoordToVertexShader()
+ : metadata.usesPointCoord())
+ {
+ // SM3 reserves the TEXCOORD semantic for point sprite texcoords (gl_PointCoord)
+ // In D3D11 we manually compute gl_PointCoord in the GS.
+ if (metadata.getRendererMajorShaderModel() >= 4)
+ {
+ builtins->glPointCoord.enable(userSemantic, reservedSemanticIndex++);
+ }
+ else
+ {
+ builtins->glPointCoord.enable("TEXCOORD", 0);
+ }
+ }
+
+ if (metadata.hasANGLEMultiviewEnabled())
+ {
+ // Although it is possible to compute gl_ViewID_OVR from the value of
+ // SV_ViewportArrayIndex or SV_RenderTargetArrayIndex and the multi-view state in the
+ // driver constant buffer, it is easier and cleaner to always pass it as a varying.
+ builtins->glViewIDOVR.enable(userSemantic, reservedSemanticIndex++);
+
+ if (shaderType == gl::ShaderType::Vertex)
+ {
+ if (metadata.canSelectViewInVertexShader())
+ {
+ builtins->glViewportIndex.enableSystem("SV_ViewportArrayIndex");
+ builtins->glLayer.enableSystem("SV_RenderTargetArrayIndex");
+ }
+ }
+
+ if (shaderType == gl::ShaderType::Geometry)
+ {
+ // gl_Layer and gl_ViewportIndex are necessary so that we can write to either based on
+ // the multiview state in the driver constant buffer.
+ builtins->glViewportIndex.enableSystem("SV_ViewportArrayIndex");
+ builtins->glLayer.enableSystem("SV_RenderTargetArrayIndex");
+ }
+ }
+
+ // Special case: do not include PSIZE semantic in HLSL 3 pixel shaders
+ if (metadata.usesSystemValuePointSize() &&
+ (shaderType != gl::ShaderType::Fragment || metadata.getRendererMajorShaderModel() >= 4))
+ {
+ builtins->glPointSize.enableSystem("PSIZE");
+ }
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/DynamicHLSL.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/DynamicHLSL.h
new file mode 100644
index 0000000000..3398bae8d7
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/DynamicHLSL.h
@@ -0,0 +1,212 @@
+//
+// 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.
+//
+// DynamicHLSL.h: Interface for link and run-time HLSL generation
+//
+
+#ifndef LIBANGLE_RENDERER_D3D_DYNAMICHLSL_H_
+#define LIBANGLE_RENDERER_D3D_DYNAMICHLSL_H_
+
+#include <map>
+#include <vector>
+
+#include "angle_gl.h"
+#include "common/angleutils.h"
+#include "libANGLE/Constants.h"
+#include "libANGLE/Program.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/d3d/DynamicImage2DHLSL.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
+
+namespace sh
+{
+struct ShaderVariable;
+} // namespace sh
+
+namespace gl
+{
+class InfoLog;
+struct VariableLocation;
+class VaryingPacking;
+struct VertexAttribute;
+} // namespace gl
+
+namespace rx
+{
+class ProgramD3DMetadata;
+class ShaderD3D;
+struct ShaderStorageBlock;
+
+// This class needs to match OutputHLSL::decorate
+class DecorateVariable final : angle::NonCopyable
+{
+ public:
+ explicit DecorateVariable(const std::string &str) : mName(str) {}
+ const std::string &getName() const { return mName; }
+
+ private:
+ const std::string &mName;
+};
+
+inline std::ostream &operator<<(std::ostream &o, const DecorateVariable &dv)
+{
+ if (dv.getName().compare(0, 3, "gl_") != 0)
+ {
+ o << "_";
+ }
+ o << dv.getName();
+ return o;
+}
+
+struct PixelShaderOutputVariable
+{
+ PixelShaderOutputVariable() {}
+ PixelShaderOutputVariable(GLenum typeIn,
+ const std::string &nameIn,
+ const std::string &sourceIn,
+ size_t outputLocationIn,
+ size_t outputIndexIn)
+ : type(typeIn),
+ name(nameIn),
+ source(sourceIn),
+ outputLocation(outputLocationIn),
+ outputIndex(outputIndexIn)
+ {}
+
+ GLenum type = GL_NONE;
+ std::string name;
+ std::string source;
+ size_t outputLocation = 0;
+ size_t outputIndex = 0;
+};
+
+struct BuiltinVarying final : private angle::NonCopyable
+{
+ BuiltinVarying();
+
+ std::string str() const;
+ void enableSystem(const std::string &systemValueSemantic);
+ void enable(const std::string &semanticVal, unsigned int indexVal);
+
+ bool enabled;
+ std::string semantic;
+ unsigned int index;
+ bool systemValue;
+};
+
+struct BuiltinInfo
+{
+ BuiltinInfo();
+ ~BuiltinInfo();
+
+ BuiltinVarying dxPosition;
+ BuiltinVarying glPosition;
+ BuiltinVarying glFragCoord;
+ BuiltinVarying glPointCoord;
+ BuiltinVarying glPointSize;
+ BuiltinVarying glViewIDOVR;
+ BuiltinVarying glViewportIndex;
+ BuiltinVarying glLayer;
+};
+
+inline std::string GetVaryingSemantic(int majorShaderModel, bool programUsesPointSize)
+{
+ // SM3 reserves the TEXCOORD semantic for point sprite texcoords (gl_PointCoord)
+ // In D3D11 we manually compute gl_PointCoord in the GS.
+ return ((programUsesPointSize && majorShaderModel < 4) ? "COLOR" : "TEXCOORD");
+}
+
+class BuiltinVaryingsD3D
+{
+ public:
+ BuiltinVaryingsD3D(const ProgramD3DMetadata &metadata, const gl::VaryingPacking &packing);
+ ~BuiltinVaryingsD3D();
+
+ bool usesPointSize() const { return mBuiltinInfo[gl::ShaderType::Vertex].glPointSize.enabled; }
+
+ const BuiltinInfo &operator[](gl::ShaderType shaderType) const
+ {
+ return mBuiltinInfo[shaderType];
+ }
+ BuiltinInfo &operator[](gl::ShaderType shaderType) { return mBuiltinInfo[shaderType]; }
+
+ private:
+ void updateBuiltins(gl::ShaderType shaderType,
+ const ProgramD3DMetadata &metadata,
+ const gl::VaryingPacking &packing);
+
+ gl::ShaderMap<BuiltinInfo> mBuiltinInfo;
+};
+
+class DynamicHLSL : angle::NonCopyable
+{
+ public:
+ explicit DynamicHLSL(RendererD3D *const renderer);
+
+ std::string generateVertexShaderForInputLayout(
+ const std::string &sourceShader,
+ const gl::InputLayout &inputLayout,
+ const std::vector<sh::ShaderVariable> &shaderAttributes,
+ const std::vector<rx::ShaderStorageBlock> &shaderStorageBlocks,
+ size_t baseUAVRegister) const;
+ std::string generatePixelShaderForOutputSignature(
+ const std::string &sourceShader,
+ const std::vector<PixelShaderOutputVariable> &outputVariables,
+ bool usesFragDepth,
+ const std::vector<GLenum> &outputLayout,
+ const std::vector<rx::ShaderStorageBlock> &shaderStorageBlocks,
+ size_t baseUAVRegister) const;
+ std::string generateShaderForImage2DBindSignature(
+ ProgramD3D &programD3D,
+ const gl::ProgramState &programData,
+ gl::ShaderType shaderType,
+ const std::string &shaderHLSL,
+ std::vector<sh::ShaderVariable> &image2DUniforms,
+ const gl::ImageUnitTextureTypeMap &image2DBindLayout,
+ unsigned int baseUAVRegister) const;
+ void generateShaderLinkHLSL(const gl::Context *context,
+ const gl::Caps &caps,
+ const gl::ProgramState &programData,
+ const ProgramD3DMetadata &programMetadata,
+ const gl::VaryingPacking &varyingPacking,
+ const BuiltinVaryingsD3D &builtinsD3D,
+ gl::ShaderMap<std::string> *shaderHLSL) const;
+
+ std::string generateGeometryShaderPreamble(const gl::VaryingPacking &varyingPacking,
+ const BuiltinVaryingsD3D &builtinsD3D,
+ const bool hasANGLEMultiviewEnabled,
+ const bool selectViewInVS) const;
+
+ std::string generateGeometryShaderHLSL(const gl::Caps &caps,
+ gl::PrimitiveMode primitiveType,
+ const gl::ProgramState &programData,
+ const bool useViewScale,
+ const bool hasANGLEMultiviewEnabled,
+ const bool selectViewInVS,
+ const bool pointSpriteEmulation,
+ const std::string &preambleString) const;
+
+ void getPixelShaderOutputKey(const gl::State &data,
+ const gl::ProgramState &programData,
+ const ProgramD3DMetadata &metadata,
+ std::vector<PixelShaderOutputVariable> *outPixelShaderKey);
+
+ private:
+ RendererD3D *const mRenderer;
+
+ void generateVaryingLinkHLSL(const gl::VaryingPacking &varyingPacking,
+ const BuiltinInfo &builtins,
+ bool programUsesPointSize,
+ std::ostringstream &hlslStream) const;
+
+ static void GenerateAttributeConversionHLSL(angle::FormatID vertexFormatID,
+ const sh::ShaderVariable &shaderAttrib,
+ std::ostringstream &outStream);
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_DYNAMICHLSL_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/DynamicImage2DHLSL.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/DynamicImage2DHLSL.cpp
new file mode 100644
index 0000000000..cf775d0b46
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/DynamicImage2DHLSL.cpp
@@ -0,0 +1,919 @@
+//
+// Copyright 2019 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.
+//
+// DynamicImage2DHLSL.cpp: Implementation for link and run-time HLSL generation
+//
+
+#include "libANGLE/renderer/d3d/DynamicImage2DHLSL.h"
+
+#include "common/string_utils.h"
+#include "libANGLE/renderer/d3d/ProgramD3D.h"
+#include "libANGLE/renderer/d3d/ShaderD3D.h"
+
+using namespace gl;
+
+namespace rx
+{
+
+namespace
+{
+
+enum Image2DHLSLGroup
+{
+ IMAGE2D_R_FLOAT4,
+ IMAGE2D_MIN = IMAGE2D_R_FLOAT4,
+ IMAGE2D_R_UNORM,
+ IMAGE2D_R_SNORM,
+ IMAGE2D_R_UINT4,
+ IMAGE2D_R_INT4,
+ IMAGE2D_W_FLOAT4,
+ IMAGE2D_W_UNORM,
+ IMAGE2D_W_SNORM,
+ IMAGE2D_W_UINT4,
+ IMAGE2D_W_INT4,
+ IMAGE2D_UNKNOWN,
+ IMAGE2D_MAX = IMAGE2D_UNKNOWN
+};
+
+enum Image2DMethod
+{
+ IMAGE2DSIZE,
+ IMAGE2DLOAD,
+ IMAGE2DSTORE
+};
+
+Image2DHLSLGroup image2DHLSLGroup(const sh::ShaderVariable &uniform)
+{
+ GLenum format = uniform.imageUnitFormat;
+ bool readonly = uniform.readonly;
+ switch (uniform.type)
+ {
+ case GL_IMAGE_2D:
+ {
+ switch (format)
+ {
+ case GL_RGBA32F:
+ case GL_RGBA16F:
+ case GL_R32F:
+ return readonly ? IMAGE2D_R_FLOAT4 : IMAGE2D_W_FLOAT4;
+ case GL_RGBA8:
+ return readonly ? IMAGE2D_R_UNORM : IMAGE2D_W_UNORM;
+ case GL_RGBA8_SNORM:
+ return readonly ? IMAGE2D_R_SNORM : IMAGE2D_W_SNORM;
+ default:
+ UNREACHABLE();
+ return IMAGE2D_UNKNOWN;
+ }
+ }
+ case GL_INT_IMAGE_2D:
+ {
+ switch (format)
+ {
+ case GL_RGBA32I:
+ case GL_RGBA16I:
+ case GL_RGBA8I:
+ case GL_R32I:
+ return readonly ? IMAGE2D_R_INT4 : IMAGE2D_W_INT4;
+ default:
+ UNREACHABLE();
+ return IMAGE2D_UNKNOWN;
+ }
+ }
+ case GL_UNSIGNED_INT_IMAGE_2D:
+ {
+ switch (format)
+ {
+ case GL_RGBA32UI:
+ case GL_RGBA16UI:
+ case GL_RGBA8UI:
+ case GL_R32UI:
+ return readonly ? IMAGE2D_R_UINT4 : IMAGE2D_W_UINT4;
+ default:
+ UNREACHABLE();
+ return IMAGE2D_UNKNOWN;
+ }
+ }
+ default:
+ UNREACHABLE();
+ return IMAGE2D_UNKNOWN;
+ }
+}
+
+std::string Image2DHLSLGroupSuffix(Image2DHLSLGroup group)
+{
+ switch (group)
+ {
+ case IMAGE2D_R_FLOAT4:
+ return "2D";
+ case IMAGE2D_R_UNORM:
+ return "2D_unorm_float4_";
+ case IMAGE2D_R_SNORM:
+ return "2D_snorm_float4_";
+ case IMAGE2D_R_UINT4:
+ return "2D_uint4_";
+ case IMAGE2D_R_INT4:
+ return "2D_int4_";
+ case IMAGE2D_W_FLOAT4:
+ return "RW2D_float4_";
+ case IMAGE2D_W_UNORM:
+ return "RW2D_unorm_float4_";
+ case IMAGE2D_W_SNORM:
+ return "RW2D_snorm_float4_";
+ case IMAGE2D_W_UINT4:
+ return "RW2D_uint4_";
+ case IMAGE2D_W_INT4:
+ return "RW2D_int4_";
+ default:
+ UNREACHABLE();
+ }
+
+ return "<unknown group type>";
+}
+
+std::string Image2DHLSLTextureString(Image2DHLSLGroup group,
+ gl::TextureType type,
+ bool rasterOrdered)
+{
+ std::string textureString;
+ switch (group)
+ {
+ case IMAGE2D_R_FLOAT4:
+ case IMAGE2D_R_UNORM:
+ case IMAGE2D_R_SNORM:
+ case IMAGE2D_R_UINT4:
+ case IMAGE2D_R_INT4:
+ break;
+ case IMAGE2D_W_FLOAT4:
+ case IMAGE2D_W_UNORM:
+ case IMAGE2D_W_SNORM:
+ case IMAGE2D_W_UINT4:
+ case IMAGE2D_W_INT4:
+ textureString += rasterOrdered ? "RasterizerOrdered" : "RW";
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ textureString += "Texture";
+
+ switch (type)
+ {
+ case gl::TextureType::_2D:
+ textureString += "2D";
+ break;
+ case gl::TextureType::_3D:
+ textureString += "3D";
+ break;
+ case gl::TextureType::_2DArray:
+ textureString += "2DArray";
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ switch (group)
+ {
+ case IMAGE2D_R_FLOAT4:
+ case IMAGE2D_W_FLOAT4:
+ textureString += "<float4>";
+ break;
+ case IMAGE2D_R_UNORM:
+ case IMAGE2D_W_UNORM:
+ textureString += "<unorm float4>";
+ break;
+ case IMAGE2D_R_SNORM:
+ case IMAGE2D_W_SNORM:
+ textureString += "<snorm float4>";
+ break;
+ case IMAGE2D_R_UINT4:
+ case IMAGE2D_W_UINT4:
+ textureString += "<uint4>";
+ break;
+ case IMAGE2D_R_INT4:
+ case IMAGE2D_W_INT4:
+ textureString += "<int4>";
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ return textureString;
+}
+
+std::string Image2DHLSLGroupOffsetPrefix(Image2DHLSLGroup group)
+{
+ switch (group)
+ {
+ case IMAGE2D_R_FLOAT4:
+ case IMAGE2D_R_UNORM:
+ case IMAGE2D_R_SNORM:
+ case IMAGE2D_R_UINT4:
+ case IMAGE2D_R_INT4:
+ return "readonlyImageIndexOffset";
+ case IMAGE2D_W_FLOAT4:
+ case IMAGE2D_W_UNORM:
+ case IMAGE2D_W_SNORM:
+ case IMAGE2D_W_UINT4:
+ case IMAGE2D_W_INT4:
+ return "imageIndexOffset";
+ default:
+ UNREACHABLE();
+ }
+
+ return "<unknown group type>";
+}
+
+std::string Image2DHLSLGroupDeclarationPrefix(Image2DHLSLGroup group)
+{
+ switch (group)
+ {
+ case IMAGE2D_R_FLOAT4:
+ case IMAGE2D_R_UNORM:
+ case IMAGE2D_R_SNORM:
+ case IMAGE2D_R_UINT4:
+ case IMAGE2D_R_INT4:
+ return "readonlyImages";
+ case IMAGE2D_W_FLOAT4:
+ case IMAGE2D_W_UNORM:
+ case IMAGE2D_W_SNORM:
+ case IMAGE2D_W_UINT4:
+ case IMAGE2D_W_INT4:
+ return "images";
+ default:
+ UNREACHABLE();
+ }
+
+ return "<unknown group type>";
+}
+
+std::string Image2DHLSLGroupRegisterSuffix(Image2DHLSLGroup group)
+{
+ switch (group)
+ {
+ case IMAGE2D_R_FLOAT4:
+ case IMAGE2D_R_UNORM:
+ case IMAGE2D_R_SNORM:
+ case IMAGE2D_R_UINT4:
+ case IMAGE2D_R_INT4:
+ return "t";
+ case IMAGE2D_W_FLOAT4:
+ case IMAGE2D_W_UNORM:
+ case IMAGE2D_W_SNORM:
+ case IMAGE2D_W_UINT4:
+ case IMAGE2D_W_INT4:
+ return "u";
+ default:
+ UNREACHABLE();
+ }
+
+ return "<unknown group type>";
+}
+
+std::string Image2DHLSLGroupFunctionName(Image2DHLSLGroup group, Image2DMethod method)
+{
+ std::string name = "gl_image";
+ name += Image2DHLSLGroupSuffix(group);
+ switch (method)
+ {
+ case IMAGE2DSIZE:
+ name += "Size";
+ break;
+ case IMAGE2DLOAD:
+ name += "Load";
+ break;
+ case IMAGE2DSTORE:
+ name += "Store";
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ return name;
+}
+
+std::string getImage2DGroupReturnType(Image2DHLSLGroup group, Image2DMethod method)
+{
+ switch (method)
+ {
+ case IMAGE2DSIZE:
+ return "int2";
+ case IMAGE2DLOAD:
+ switch (group)
+ {
+ case IMAGE2D_R_FLOAT4:
+ case IMAGE2D_R_UNORM:
+ case IMAGE2D_R_SNORM:
+ case IMAGE2D_W_FLOAT4:
+ case IMAGE2D_W_UNORM:
+ case IMAGE2D_W_SNORM:
+ return "float4";
+ case IMAGE2D_R_UINT4:
+ case IMAGE2D_W_UINT4:
+ return "uint4";
+ case IMAGE2D_R_INT4:
+ case IMAGE2D_W_INT4:
+ return "int4";
+ default:
+ UNREACHABLE();
+ return "unknown group type";
+ }
+ case IMAGE2DSTORE:
+ return "void";
+ default:
+ UNREACHABLE();
+ return "unknown image method";
+ }
+}
+
+std::string getImageMetadata(Image2DHLSLGroup group)
+{
+ switch (group)
+ {
+ case IMAGE2D_R_FLOAT4:
+ case IMAGE2D_R_UNORM:
+ case IMAGE2D_R_SNORM:
+ case IMAGE2D_R_UINT4:
+ case IMAGE2D_R_INT4:
+ return "readonlyImageMetadata[imageIndex - readonlyImageIndexStart]";
+ case IMAGE2D_W_FLOAT4:
+ case IMAGE2D_W_UNORM:
+ case IMAGE2D_W_SNORM:
+ case IMAGE2D_W_UINT4:
+ case IMAGE2D_W_INT4:
+ return "imageMetadata[imageIndex - imageIndexStart]";
+ default:
+ UNREACHABLE();
+ return "unknown image method";
+ }
+}
+
+void OutputImage2DFunctionArgumentList(std::ostringstream &out,
+ Image2DHLSLGroup group,
+ Image2DMethod method)
+{
+ out << "uint imageIndex";
+
+ if (method == IMAGE2DLOAD || method == IMAGE2DSTORE)
+ {
+ out << ", int2 p";
+ if (method == IMAGE2DSTORE)
+ {
+ switch (group)
+ {
+ case IMAGE2D_R_FLOAT4:
+ case IMAGE2D_R_UNORM:
+ case IMAGE2D_R_SNORM:
+ case IMAGE2D_W_FLOAT4:
+ case IMAGE2D_W_UNORM:
+ case IMAGE2D_W_SNORM:
+ out << ", float4 data";
+ break;
+ case IMAGE2D_R_UINT4:
+ case IMAGE2D_W_UINT4:
+ out << ", uint4 data";
+ break;
+ case IMAGE2D_R_INT4:
+ case IMAGE2D_W_INT4:
+ out << ", int4 data";
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+ }
+}
+
+void OutputImage2DSizeFunction(std::ostringstream &out,
+ Image2DHLSLGroup textureGroup,
+ unsigned int totalCount,
+ unsigned int texture2DCount,
+ unsigned int texture3DCount,
+ unsigned int texture2DArrayCount,
+ const std::string &offsetStr,
+ const std::string &declarationStr)
+{
+ out << getImage2DGroupReturnType(textureGroup, IMAGE2DSIZE) << " "
+ << Image2DHLSLGroupFunctionName(textureGroup, IMAGE2DSIZE) << "(";
+ OutputImage2DFunctionArgumentList(out, textureGroup, IMAGE2DSIZE);
+ out << ")\n"
+ "{\n";
+ out << " uint width, height;\n";
+
+ if (texture2DCount > 0)
+ {
+ if (texture2DCount == totalCount)
+ {
+ out << " const uint index = imageIndex - " << offsetStr << "2D;\n";
+ out << " " << declarationStr << "2D[index].GetDimensions(width, height);\n";
+ }
+ else
+ {
+ out << " if (imageIndex >= " << offsetStr << "2D && imageIndex < " << offsetStr
+ << "2D + " << texture2DCount << ")\n";
+ out << " {\n";
+ out << " const uint index = imageIndex - " << offsetStr << "2D;\n";
+ out << " " << declarationStr << "2D[index].GetDimensions(width, height);\n";
+ out << " }\n";
+ }
+ }
+
+ if (texture3DCount > 0)
+ {
+ if (texture3DCount == totalCount)
+ {
+ out << " const uint index = imageIndex - " << offsetStr << "3D;\n";
+ out << " uint depth;\n";
+ out << " " << declarationStr << "3D[index].GetDimensions(width, height, depth);\n";
+ }
+ else
+ {
+ if (texture2DArrayCount == 0)
+ {
+ out << " else\n";
+ }
+ else
+ {
+ if (texture2DCount == 0)
+ {
+ out << " if ";
+ }
+ else
+ {
+ out << " else if";
+ }
+ out << "(imageIndex >= " << offsetStr << "3D && imageIndex < " << offsetStr
+ << "3D + " << texture3DCount << ")\n";
+ }
+ out << " {\n";
+ out << " const uint index = imageIndex - " << offsetStr << "3D;\n";
+ out << " uint depth;\n";
+ out << " " << declarationStr
+ << "3D[index].GetDimensions(width, height, depth);\n";
+ out << " }\n";
+ }
+ }
+
+ if (texture2DArrayCount > 0)
+ {
+ if (texture2DArrayCount == totalCount)
+ {
+ out << " const uint index = imageIndex - " << offsetStr << "2DArray;\n";
+ out << " uint depth;\n";
+ out << " " << declarationStr
+ << "2DArray[index].GetDimensions(width, height, depth);\n";
+ }
+ else
+ {
+ out << " else\n";
+ out << " {\n";
+ out << " const uint index = imageIndex - " << offsetStr << "2DArray;\n";
+ out << " uint depth;\n";
+ out << " " << declarationStr
+ << "2DArray[index].GetDimensions(width, height, depth);\n";
+ out << " }\n";
+ }
+ }
+ out << " return int2(width, height);\n";
+
+ out << "}\n";
+}
+
+void OutputImage2DLoadFunction(std::ostringstream &out,
+ Image2DHLSLGroup textureGroup,
+ unsigned int totalCount,
+ unsigned int texture2DCount,
+ unsigned int texture3DCount,
+ unsigned int texture2DArrayCount,
+ const std::string &offsetStr,
+ const std::string &declarationStr)
+{
+ out << getImage2DGroupReturnType(textureGroup, IMAGE2DLOAD) << " "
+ << Image2DHLSLGroupFunctionName(textureGroup, IMAGE2DLOAD) << "(";
+ OutputImage2DFunctionArgumentList(out, textureGroup, IMAGE2DLOAD);
+ out << ")\n"
+ "{\n";
+
+ out << " " << getImage2DGroupReturnType(textureGroup, IMAGE2DLOAD) << " result;\n";
+
+ if (texture2DCount > 0)
+ {
+ if (texture2DCount == totalCount)
+ {
+ out << " const uint index = imageIndex - " << offsetStr << "2D;\n";
+ out << " result = " << declarationStr << "2D[index][uint2(p.x, p.y)];\n";
+ }
+ else
+ {
+ out << " if (imageIndex >= " << offsetStr << "2D && imageIndex < " << offsetStr
+ << "2D + " << texture2DCount << ")\n";
+ out << " {\n";
+ out << " const uint index = imageIndex - " << offsetStr << "2D;\n";
+ out << " result = " << declarationStr << "2D[index][uint2(p.x, p.y)];\n";
+ out << " }\n";
+ }
+ }
+
+ if (texture3DCount > 0)
+ {
+ if (texture3DCount == totalCount)
+ {
+ out << " const uint index = imageIndex - " << offsetStr << "3D;\n";
+ out << " result = " << declarationStr << "3D[index][uint3(p.x, p.y, "
+ << getImageMetadata(textureGroup) << ".layer)];\n";
+ }
+ else
+ {
+ if (texture2DArrayCount == 0)
+ {
+ out << " else\n";
+ }
+ else
+ {
+ if (texture2DCount == 0)
+ {
+ out << " if ";
+ }
+ else
+ {
+ out << " else if";
+ }
+ out << "(imageIndex >= " << offsetStr << "3D && imageIndex < " << offsetStr
+ << "3D + " << texture3DCount << ")\n";
+ }
+ out << " {\n";
+ out << " const uint index = imageIndex - " << offsetStr << "3D;\n";
+ out << " result = " << declarationStr << "3D[index][uint3(p.x, p.y, "
+ << getImageMetadata(textureGroup) << ".layer)];\n";
+ out << " }\n";
+ }
+ }
+
+ if (texture2DArrayCount > 0)
+ {
+ if (texture2DArrayCount == totalCount)
+ {
+ out << " const uint index = imageIndex - " << offsetStr << "2DArray;\n";
+ out << " result = " << declarationStr << "2DArray[index][uint3(p.x, p.y, "
+ << getImageMetadata(textureGroup) << ".layer)];\n";
+ }
+ else
+ {
+ out << " else\n";
+ out << " {\n";
+ out << " const uint index = imageIndex - " << offsetStr << "2DArray;\n";
+ out << " result = " << declarationStr << "2DArray[index][uint3(p.x, p.y, "
+ << getImageMetadata(textureGroup) << ".layer)];\n";
+ out << " }\n";
+ }
+ }
+
+ out << " return result;\n";
+ out << "}\n";
+}
+
+void OutputImage2DStoreFunction(std::ostringstream &out,
+ Image2DHLSLGroup textureGroup,
+ unsigned int totalCount,
+ unsigned int texture2DCount,
+ unsigned int texture3DCount,
+ unsigned int texture2DArrayCount,
+ const std::string &offsetStr,
+ const std::string &declarationStr)
+{
+ out << getImage2DGroupReturnType(textureGroup, IMAGE2DSTORE) << " "
+ << Image2DHLSLGroupFunctionName(textureGroup, IMAGE2DSTORE) << "(";
+ OutputImage2DFunctionArgumentList(out, textureGroup, IMAGE2DSTORE);
+ out << ")\n"
+ "{\n";
+
+ if (texture2DCount > 0)
+ {
+ if (texture2DCount == totalCount)
+ {
+ out << " const uint index = imageIndex - " << offsetStr << "2D;\n";
+ out << " " << declarationStr << "2D[index][uint2(p.x, p.y)] = data;\n";
+ }
+ else
+ {
+ out << " if (imageIndex >= " << offsetStr << "2D && imageIndex < " << offsetStr
+ << "2D + " << texture2DCount << ")\n";
+ out << " {\n";
+ out << " const uint index = imageIndex - " << offsetStr << "2D;\n";
+ out << " " << declarationStr << "2D[index][uint2(p.x, p.y)] = data;\n";
+ out << " }\n";
+ }
+ }
+
+ if (texture3DCount > 0)
+ {
+ if (texture3DCount == totalCount)
+ {
+ out << " const uint index = imageIndex - " << offsetStr << "3D;\n";
+ out << " " << declarationStr << "3D[index][uint3(p.x, p.y, "
+ << getImageMetadata(textureGroup) << ".layer)] = data;\n";
+ }
+ else
+ {
+ if (texture2DArrayCount == 0)
+ {
+ out << " else\n";
+ }
+ else
+ {
+ if (texture2DCount == 0)
+ {
+ out << " if ";
+ }
+ else
+ {
+ out << " else if";
+ }
+ out << "(imageIndex >= " << offsetStr << "3D && imageIndex < " << offsetStr
+ << "3D + " << texture3DCount << ")\n";
+ }
+ out << " {\n";
+ out << " const uint index = imageIndex - " << offsetStr << "3D;\n";
+ out << " " << declarationStr << "3D[index][uint3(p.x, p.y, "
+ << getImageMetadata(textureGroup) << ".layer)] = data;\n";
+ out << " }\n";
+ }
+ }
+
+ if (texture2DArrayCount > 0)
+ {
+ if (texture2DArrayCount == totalCount)
+ {
+ out << " const uint index = imageIndex - " << offsetStr << "2DArray;\n";
+ out << " " << declarationStr << "2DArray[index][uint3(p.x, p.y, "
+ << getImageMetadata(textureGroup) << ".layer)] = data;\n";
+ }
+ else
+ {
+ out << " else\n";
+ out << " {\n";
+ out << " const uint index = imageIndex - " << offsetStr << "2DArray;\n";
+ out << " " << declarationStr << "2DArray[index][uint3(p.x, p.y, "
+ << getImageMetadata(textureGroup) << ".layer)] = data;\n";
+ out << " }\n";
+ }
+ }
+
+ out << "}\n";
+}
+
+unsigned int *GetImage2DRegisterIndex(Image2DHLSLGroup textureGroup,
+ unsigned int *groupTextureRegisterIndex,
+ unsigned int *groupRWTextureRegisterIndex)
+{
+ switch (textureGroup)
+ {
+ case IMAGE2D_R_FLOAT4:
+ case IMAGE2D_R_UNORM:
+ case IMAGE2D_R_SNORM:
+ case IMAGE2D_R_UINT4:
+ case IMAGE2D_R_INT4:
+ return groupTextureRegisterIndex;
+ case IMAGE2D_W_FLOAT4:
+ case IMAGE2D_W_UNORM:
+ case IMAGE2D_W_SNORM:
+ case IMAGE2D_W_UINT4:
+ case IMAGE2D_W_INT4:
+ return groupRWTextureRegisterIndex;
+ default:
+ UNREACHABLE();
+ return nullptr;
+ }
+}
+
+void OutputHLSLImage2DUniformGroup(ProgramD3D &programD3D,
+ const gl::ProgramState &programData,
+ gl::ShaderType shaderType,
+ std::ostringstream &out,
+ const Image2DHLSLGroup textureGroup,
+ const std::vector<sh::ShaderVariable> &group,
+ const gl::ImageUnitTextureTypeMap &image2DBindLayout,
+ unsigned int baseUAVRegister,
+ unsigned int *groupTextureRegisterIndex,
+ unsigned int *groupRWTextureRegisterIndex,
+ unsigned int *image2DTexture3D,
+ unsigned int *image2DTexture2DArray,
+ unsigned int *image2DTexture2D)
+{
+ if (group.empty())
+ {
+ return;
+ }
+
+ unsigned int texture2DCount = 0, texture3DCount = 0, texture2DArrayCount = 0;
+ bool texture2DRasterOrdered = false, texture3DRasterOrdered = false,
+ texture2DArrayRasterOrdered = false;
+ for (const sh::ShaderVariable &uniform : group)
+ {
+ if (!programD3D.hasNamedUniform(uniform.name))
+ {
+ continue;
+ }
+ for (unsigned int index = 0; index < uniform.getArraySizeProduct(); index++)
+ {
+ switch (image2DBindLayout.at(uniform.binding + index))
+ {
+ case gl::TextureType::_2D:
+ texture2DCount++;
+ texture2DRasterOrdered |= uniform.rasterOrdered;
+ break;
+ case gl::TextureType::_3D:
+ texture3DCount++;
+ texture3DRasterOrdered |= uniform.rasterOrdered;
+ break;
+ case gl::TextureType::_2DArray:
+ case gl::TextureType::CubeMap:
+ texture2DArrayCount++;
+ texture2DArrayRasterOrdered |= uniform.rasterOrdered;
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+ }
+
+ unsigned int totalCount = texture2DCount + texture3DCount + texture2DArrayCount;
+ unsigned int *image2DRegisterIndex = GetImage2DRegisterIndex(
+ textureGroup, groupTextureRegisterIndex, groupRWTextureRegisterIndex);
+ unsigned int texture2DRegisterIndex = *image2DRegisterIndex;
+ unsigned int texture3DRegisterIndex = texture2DRegisterIndex + texture2DCount;
+ unsigned int texture2DArrayRegisterIndex = texture3DRegisterIndex + texture3DCount;
+ *image2DRegisterIndex += totalCount;
+
+ std::string offsetStr =
+ Image2DHLSLGroupOffsetPrefix(textureGroup) + Image2DHLSLGroupSuffix(textureGroup);
+ std::string declarationStr =
+ Image2DHLSLGroupDeclarationPrefix(textureGroup) + Image2DHLSLGroupSuffix(textureGroup);
+ std::string registerStr = Image2DHLSLGroupRegisterSuffix(textureGroup);
+ if (texture2DCount > 0)
+ {
+ out << "static const uint " << offsetStr << "2D = " << texture2DRegisterIndex << ";\n";
+ out << "uniform "
+ << Image2DHLSLTextureString(textureGroup, gl::TextureType::_2D, texture2DRasterOrdered)
+ << " " << declarationStr << "2D[" << texture2DCount << "]"
+ << " : register(" << registerStr << baseUAVRegister + texture2DRegisterIndex << ");\n";
+ }
+ if (texture3DCount > 0)
+ {
+ out << "static const uint " << offsetStr << "3D = " << texture3DRegisterIndex << ";\n";
+ out << "uniform "
+ << Image2DHLSLTextureString(textureGroup, gl::TextureType::_3D, texture3DRasterOrdered)
+ << " " << declarationStr << "3D[" << texture3DCount << "]"
+ << " : register(" << registerStr << baseUAVRegister + texture3DRegisterIndex << ");\n";
+ }
+ if (texture2DArrayCount > 0)
+ {
+ out << "static const uint " << offsetStr << "2DArray = " << texture2DArrayRegisterIndex
+ << ";\n";
+ out << "uniform "
+ << Image2DHLSLTextureString(textureGroup, gl::TextureType::_2DArray,
+ texture2DArrayRasterOrdered)
+ << " " << declarationStr << "2DArray[" << texture2DArrayCount << "]"
+ << " : register(" << registerStr << baseUAVRegister + texture2DArrayRegisterIndex
+ << ");\n";
+ }
+ for (const sh::ShaderVariable &uniform : group)
+ {
+ if (!programD3D.hasNamedUniform(uniform.name))
+ {
+ continue;
+ }
+
+ out << "static const uint " << DecorateVariable(uniform.name)
+ << ArrayIndexString(uniform.arraySizes) << " = {";
+ for (unsigned int index = 0; index < uniform.getArraySizeProduct(); index++)
+ {
+ if (index > 0)
+ {
+ out << ", ";
+ }
+ switch (image2DBindLayout.at(uniform.binding + index))
+ {
+ case gl::TextureType::_2D:
+ {
+ out << texture2DRegisterIndex;
+ programD3D.assignImage2DRegisters(shaderType, texture2DRegisterIndex,
+ uniform.binding + index, uniform.readonly);
+ texture2DRegisterIndex++;
+ break;
+ }
+ case gl::TextureType::_3D:
+ {
+ out << texture3DRegisterIndex;
+ programD3D.assignImage2DRegisters(shaderType, texture3DRegisterIndex,
+ uniform.binding + index, uniform.readonly);
+ texture3DRegisterIndex++;
+ break;
+ }
+ case gl::TextureType::_2DArray:
+ case gl::TextureType::CubeMap:
+ {
+ out << texture2DArrayRegisterIndex;
+ programD3D.assignImage2DRegisters(shaderType, texture2DArrayRegisterIndex,
+ uniform.binding + index, uniform.readonly);
+ texture2DArrayRegisterIndex++;
+ break;
+ }
+ default:
+ UNREACHABLE();
+ }
+ }
+ out << "};\n";
+ }
+
+ gl::Shader *shaderGL = programData.getAttachedShader(shaderType);
+ const ShaderD3D *shaderD3D = GetImplAs<ShaderD3D>(shaderGL);
+
+ if (shaderD3D->useImage2DFunction(Image2DHLSLGroupFunctionName(textureGroup, IMAGE2DSIZE)))
+ {
+ OutputImage2DSizeFunction(out, textureGroup, totalCount, texture2DCount, texture3DCount,
+ texture2DArrayCount, offsetStr, declarationStr);
+ }
+ if (shaderD3D->useImage2DFunction(Image2DHLSLGroupFunctionName(textureGroup, IMAGE2DLOAD)))
+ {
+ OutputImage2DLoadFunction(out, textureGroup, totalCount, texture2DCount, texture3DCount,
+ texture2DArrayCount, offsetStr, declarationStr);
+ }
+ if (shaderD3D->useImage2DFunction(Image2DHLSLGroupFunctionName(textureGroup, IMAGE2DSTORE)))
+ {
+ OutputImage2DStoreFunction(out, textureGroup, totalCount, texture2DCount, texture3DCount,
+ texture2DArrayCount, offsetStr, declarationStr);
+ }
+}
+
+// kImage2DFunctionString must be the same as outputHLSL.
+constexpr const char kImage2DFunctionString[] = "// @@ IMAGE2D DECLARATION FUNCTION STRING @@";
+} // anonymous namespace
+
+std::string GenerateShaderForImage2DBindSignature(
+ ProgramD3D &programD3D,
+ const gl::ProgramState &programData,
+ gl::ShaderType shaderType,
+ const std::string &shaderHLSL,
+ std::vector<sh::ShaderVariable> &image2DUniforms,
+ const gl::ImageUnitTextureTypeMap &image2DBindLayout,
+ unsigned int baseUAVRegister)
+{
+ std::vector<std::vector<sh::ShaderVariable>> groupedImage2DUniforms(IMAGE2D_MAX + 1);
+ unsigned int image2DTexture3DCount = 0, image2DTexture2DArrayCount = 0;
+ for (sh::ShaderVariable &image2D : image2DUniforms)
+ {
+ for (unsigned int index = 0; index < image2D.getArraySizeProduct(); index++)
+ {
+ // Any image variable declared without a binding qualifier is initially bound to unit
+ // zero.
+ if (image2D.binding == -1)
+ {
+ image2D.binding = 0;
+ }
+ switch (image2DBindLayout.at(image2D.binding + index))
+ {
+ case gl::TextureType::_2D:
+ break;
+ case gl::TextureType::_3D:
+ image2DTexture3DCount++;
+ break;
+ case gl::TextureType::_2DArray:
+ case gl::TextureType::CubeMap:
+ image2DTexture2DArrayCount++;
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+ Image2DHLSLGroup group = image2DHLSLGroup(image2D);
+ groupedImage2DUniforms[group].push_back(image2D);
+ }
+
+ gl::Shader *shaderGL = programData.getAttachedShader(shaderType);
+ const ShaderD3D *shaderD3D = GetImplAs<ShaderD3D>(shaderGL);
+ unsigned int groupTextureRegisterIndex = shaderD3D->getReadonlyImage2DRegisterIndex();
+ unsigned int groupRWTextureRegisterIndex = shaderD3D->getImage2DRegisterIndex();
+ unsigned int image2DTexture3DIndex = 0;
+ unsigned int image2DTexture2DArrayIndex = image2DTexture3DCount;
+ unsigned int image2DTexture2DIndex = image2DTexture3DCount + image2DTexture2DArrayCount;
+ std::ostringstream out;
+
+ for (int groupId = IMAGE2D_MIN; groupId < IMAGE2D_MAX; ++groupId)
+ {
+ OutputHLSLImage2DUniformGroup(
+ programD3D, programData, shaderType, out, Image2DHLSLGroup(groupId),
+ groupedImage2DUniforms[groupId], image2DBindLayout, baseUAVRegister,
+ &groupTextureRegisterIndex, &groupRWTextureRegisterIndex, &image2DTexture3DIndex,
+ &image2DTexture2DArrayIndex, &image2DTexture2DIndex);
+ }
+
+ std::string result = shaderHLSL;
+ bool success = angle::ReplaceSubstring(&result, kImage2DFunctionString, out.str());
+ ASSERT(success);
+
+ return result;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/DynamicImage2DHLSL.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/DynamicImage2DHLSL.h
new file mode 100644
index 0000000000..6533c972f8
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/DynamicImage2DHLSL.h
@@ -0,0 +1,28 @@
+//
+// Copyright 2019 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.
+//
+// DynamicImage2DHLSL.h: Interface for link and run-time HLSL generation
+//
+
+#ifndef LIBANGLE_RENDERER_D3D_DYNAMICIMAGE2DHLSL_H_
+#define LIBANGLE_RENDERER_D3D_DYNAMICIMAGE2DHLSL_H_
+
+#include "common/angleutils.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
+
+namespace rx
+{
+std::string GenerateShaderForImage2DBindSignature(
+ ProgramD3D &programD3D,
+ const gl::ProgramState &programData,
+ gl::ShaderType shaderType,
+ const std::string &shaderHLSL,
+ std::vector<sh::ShaderVariable> &image2DUniforms,
+ const gl::ImageUnitTextureTypeMap &image2DBindLayout,
+ unsigned int baseUAVRegister);
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_DYNAMICHLSL_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/EGLImageD3D.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/EGLImageD3D.cpp
new file mode 100644
index 0000000000..c2ff39ba24
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/EGLImageD3D.cpp
@@ -0,0 +1,93 @@
+//
+// 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.
+//
+
+// EGLImageD3D.cpp: Implements the rx::EGLImageD3D class, the D3D implementation of EGL images
+
+#include "libANGLE/renderer/d3d/EGLImageD3D.h"
+
+#include "common/debug.h"
+#include "common/utilities.h"
+#include "libANGLE/AttributeMap.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Texture.h"
+#include "libANGLE/renderer/d3d/RenderTargetD3D.h"
+#include "libANGLE/renderer/d3d/RenderbufferD3D.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
+#include "libANGLE/renderer/d3d/TextureD3D.h"
+#include "libANGLE/renderer/d3d/TextureStorage.h"
+
+#include <EGL/eglext.h>
+
+namespace rx
+{
+
+EGLImageD3D::EGLImageD3D(const egl::ImageState &state,
+ EGLenum target,
+ const egl::AttributeMap &attribs,
+ RendererD3D *renderer)
+ : ImageImpl(state), mRenderer(renderer), mRenderTarget(nullptr)
+{
+ ASSERT(renderer != nullptr);
+}
+
+EGLImageD3D::~EGLImageD3D()
+{
+ SafeDelete(mRenderTarget);
+}
+
+egl::Error EGLImageD3D::initialize(const egl::Display *display)
+{
+ return egl::NoError();
+}
+
+angle::Result EGLImageD3D::orphan(const gl::Context *context, egl::ImageSibling *sibling)
+{
+ if (sibling == mState.source)
+ {
+ ANGLE_TRY(copyToLocalRendertarget(context));
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result EGLImageD3D::getRenderTarget(const gl::Context *context,
+ RenderTargetD3D **outRT) const
+{
+ if (mState.source != nullptr)
+ {
+ ASSERT(!mRenderTarget);
+ FramebufferAttachmentRenderTarget *rt = nullptr;
+ ANGLE_TRY(
+ mState.source->getAttachmentRenderTarget(context, GL_NONE, mState.imageIndex, 0, &rt));
+ *outRT = static_cast<RenderTargetD3D *>(rt);
+ return angle::Result::Continue;
+ }
+
+ ASSERT(mRenderTarget);
+ *outRT = mRenderTarget;
+ return angle::Result::Continue;
+}
+
+angle::Result EGLImageD3D::copyToLocalRendertarget(const gl::Context *context)
+{
+ ASSERT(mState.source != nullptr);
+ ASSERT(mRenderTarget == nullptr);
+
+ RenderTargetD3D *curRenderTarget = nullptr;
+ ANGLE_TRY(getRenderTarget(context, &curRenderTarget));
+
+ {
+ std::unique_lock lock(mState.targetsLock);
+ // Invalidate FBOs with this Image attached. Only currently applies to D3D11.
+ for (egl::ImageSibling *target : mState.targets)
+ {
+ target->onStateChange(angle::SubjectMessage::SubjectChanged);
+ }
+ }
+
+ return mRenderer->createRenderTargetCopy(context, curRenderTarget, &mRenderTarget);
+}
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/EGLImageD3D.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/EGLImageD3D.h
new file mode 100644
index 0000000000..53c18739af
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/EGLImageD3D.h
@@ -0,0 +1,55 @@
+//
+// 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.
+//
+
+// EGLImageD3D.h: Defines the rx::EGLImageD3D class, the D3D implementation of EGL images
+
+#ifndef LIBANGLE_RENDERER_D3D_EGLIMAGED3D_H_
+#define LIBANGLE_RENDERER_D3D_EGLIMAGED3D_H_
+
+#include "libANGLE/renderer/ImageImpl.h"
+
+namespace gl
+{
+class Context;
+}
+
+namespace egl
+{
+class AttributeMap;
+}
+
+namespace rx
+{
+class FramebufferAttachmentObjectImpl;
+class TextureD3D;
+class RenderbufferD3D;
+class RendererD3D;
+class RenderTargetD3D;
+
+class EGLImageD3D final : public ImageImpl
+{
+ public:
+ EGLImageD3D(const egl::ImageState &state,
+ EGLenum target,
+ const egl::AttributeMap &attribs,
+ RendererD3D *renderer);
+ ~EGLImageD3D() override;
+
+ egl::Error initialize(const egl::Display *display) override;
+
+ angle::Result orphan(const gl::Context *context, egl::ImageSibling *sibling) override;
+
+ angle::Result getRenderTarget(const gl::Context *context, RenderTargetD3D **outRT) const;
+
+ private:
+ angle::Result copyToLocalRendertarget(const gl::Context *context);
+
+ RendererD3D *mRenderer;
+ RenderTargetD3D *mRenderTarget;
+};
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_EGLIMAGED3D_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/FramebufferD3D.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
new file mode 100644
index 0000000000..5a8279a586
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
@@ -0,0 +1,402 @@
+//
+// 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.
+//
+
+// FramebufferD3D.cpp: Implements the DefaultAttachmentD3D and FramebufferD3D classes.
+
+#include "libANGLE/renderer/d3d/FramebufferD3D.h"
+
+#include "common/bitset_utils.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/ErrorStrings.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/Surface.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/ContextImpl.h"
+#include "libANGLE/renderer/d3d/ContextD3D.h"
+#include "libANGLE/renderer/d3d/RenderTargetD3D.h"
+#include "libANGLE/renderer/d3d/RenderbufferD3D.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
+#include "libANGLE/renderer/d3d/SurfaceD3D.h"
+#include "libANGLE/renderer/d3d/SwapChainD3D.h"
+#include "libANGLE/renderer/d3d/TextureD3D.h"
+
+namespace rx
+{
+
+namespace
+{
+
+ClearParameters GetClearParameters(const gl::State &state, GLbitfield mask)
+{
+ ClearParameters clearParams;
+ memset(&clearParams, 0, sizeof(ClearParameters));
+
+ clearParams.colorF = state.getColorClearValue();
+ clearParams.colorType = GL_FLOAT;
+ clearParams.clearDepth = false;
+ clearParams.depthValue = state.getDepthClearValue();
+ clearParams.clearStencil = false;
+ clearParams.stencilValue = state.getStencilClearValue();
+ clearParams.stencilWriteMask = state.getDepthStencilState().stencilWritemask;
+
+ const auto *framebufferObject = state.getDrawFramebuffer();
+ const gl::Extents &framebufferSize = framebufferObject->getFirstNonNullAttachment()->getSize();
+ const gl::Offset &surfaceTextureOffset = framebufferObject->getSurfaceTextureOffset();
+ if (state.isScissorTestEnabled())
+ {
+ clearParams.scissorEnabled = true;
+ clearParams.scissor = state.getScissor();
+ clearParams.scissor.x = clearParams.scissor.x + surfaceTextureOffset.x;
+ clearParams.scissor.y = clearParams.scissor.y + surfaceTextureOffset.y;
+ }
+ else if (surfaceTextureOffset != gl::kOffsetZero)
+ {
+ clearParams.scissorEnabled = true;
+ clearParams.scissor = gl::Rectangle(surfaceTextureOffset.x, surfaceTextureOffset.y,
+ framebufferSize.width, framebufferSize.height);
+ }
+
+ const bool clearColor =
+ (mask & GL_COLOR_BUFFER_BIT) && framebufferObject->hasEnabledDrawBuffer();
+ if (clearColor)
+ {
+ clearParams.clearColor.set();
+ }
+ else
+ {
+ clearParams.clearColor.reset();
+ }
+ clearParams.colorMask = state.getBlendStateExt().getColorMaskBits();
+
+ if (mask & GL_DEPTH_BUFFER_BIT)
+ {
+ if (state.getDepthStencilState().depthMask &&
+ framebufferObject->getDepthAttachment() != nullptr)
+ {
+ clearParams.clearDepth = true;
+ }
+ }
+
+ if (mask & GL_STENCIL_BUFFER_BIT)
+ {
+ if (framebufferObject->getStencilAttachment() != nullptr &&
+ framebufferObject->getStencilAttachment()->getStencilSize() > 0)
+ {
+ clearParams.clearStencil = true;
+ }
+ }
+
+ return clearParams;
+}
+} // namespace
+
+ClearParameters::ClearParameters() = default;
+
+ClearParameters::ClearParameters(const ClearParameters &other) = default;
+
+FramebufferD3D::FramebufferD3D(const gl::FramebufferState &data, RendererD3D *renderer)
+ : FramebufferImpl(data), mRenderer(renderer), mMockAttachment()
+{}
+
+FramebufferD3D::~FramebufferD3D() {}
+
+angle::Result FramebufferD3D::clear(const gl::Context *context, GLbitfield mask)
+{
+ ClearParameters clearParams = GetClearParameters(context->getState(), mask);
+ return clearImpl(context, clearParams);
+}
+
+angle::Result FramebufferD3D::clearBufferfv(const gl::Context *context,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLfloat *values)
+{
+ // glClearBufferfv can be called to clear the color buffer or depth buffer
+ ClearParameters clearParams = GetClearParameters(context->getState(), 0);
+
+ if (buffer == GL_COLOR)
+ {
+ for (unsigned int i = 0; i < clearParams.clearColor.size(); i++)
+ {
+ clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
+ }
+ clearParams.colorF = gl::ColorF(values[0], values[1], values[2], values[3]);
+ clearParams.colorType = GL_FLOAT;
+ }
+
+ if (buffer == GL_DEPTH)
+ {
+ clearParams.clearDepth = true;
+ clearParams.depthValue = values[0];
+ }
+
+ return clearImpl(context, clearParams);
+}
+
+angle::Result FramebufferD3D::clearBufferuiv(const gl::Context *context,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLuint *values)
+{
+ // glClearBufferuiv can only be called to clear a color buffer
+ ClearParameters clearParams = GetClearParameters(context->getState(), 0);
+ for (unsigned int i = 0; i < clearParams.clearColor.size(); i++)
+ {
+ clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
+ }
+ clearParams.colorUI = gl::ColorUI(values[0], values[1], values[2], values[3]);
+ clearParams.colorType = GL_UNSIGNED_INT;
+
+ return clearImpl(context, clearParams);
+}
+
+angle::Result FramebufferD3D::clearBufferiv(const gl::Context *context,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLint *values)
+{
+ // glClearBufferiv can be called to clear the color buffer or stencil buffer
+ ClearParameters clearParams = GetClearParameters(context->getState(), 0);
+
+ if (buffer == GL_COLOR)
+ {
+ for (unsigned int i = 0; i < clearParams.clearColor.size(); i++)
+ {
+ clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
+ }
+ clearParams.colorI = gl::ColorI(values[0], values[1], values[2], values[3]);
+ clearParams.colorType = GL_INT;
+ }
+
+ if (buffer == GL_STENCIL)
+ {
+ clearParams.clearStencil = true;
+ clearParams.stencilValue = values[0];
+ }
+
+ return clearImpl(context, clearParams);
+}
+
+angle::Result FramebufferD3D::clearBufferfi(const gl::Context *context,
+ GLenum buffer,
+ GLint drawbuffer,
+ GLfloat depth,
+ GLint stencil)
+{
+ // glClearBufferfi can only be called to clear a depth stencil buffer
+ ClearParameters clearParams = GetClearParameters(context->getState(), 0);
+ clearParams.clearDepth = true;
+ clearParams.depthValue = depth;
+ clearParams.clearStencil = true;
+ clearParams.stencilValue = stencil;
+
+ return clearImpl(context, clearParams);
+}
+
+angle::Result FramebufferD3D::readPixels(const gl::Context *context,
+ const gl::Rectangle &area,
+ GLenum format,
+ GLenum type,
+ const gl::PixelPackState &pack,
+ gl::Buffer *packBuffer,
+ void *pixels)
+{
+ // Clip read area to framebuffer.
+ const gl::Extents fbSize = getState().getReadPixelsAttachment(format)->getSize();
+ const gl::Rectangle fbRect(0, 0, fbSize.width, fbSize.height);
+ gl::Rectangle clippedArea;
+ if (!ClipRectangle(area, fbRect, &clippedArea))
+ {
+ // nothing to read
+ return angle::Result::Continue;
+ }
+
+ const gl::InternalFormat &sizedFormatInfo = gl::GetInternalFormatInfo(format, type);
+
+ ContextD3D *contextD3D = GetImplAs<ContextD3D>(context);
+
+ GLuint outputPitch = 0;
+ ANGLE_CHECK_GL_MATH(contextD3D,
+ sizedFormatInfo.computeRowPitch(type, area.width, pack.alignment,
+ pack.rowLength, &outputPitch));
+
+ GLuint outputSkipBytes = 0;
+ ANGLE_CHECK_GL_MATH(contextD3D, sizedFormatInfo.computeSkipBytes(type, outputPitch, 0, pack,
+ false, &outputSkipBytes));
+ outputSkipBytes += (clippedArea.x - area.x) * sizedFormatInfo.pixelBytes +
+ (clippedArea.y - area.y) * outputPitch;
+
+ return readPixelsImpl(context, clippedArea, format, type, outputPitch, pack, packBuffer,
+ static_cast<uint8_t *>(pixels) + outputSkipBytes);
+}
+
+angle::Result FramebufferD3D::blit(const gl::Context *context,
+ const gl::Rectangle &sourceArea,
+ const gl::Rectangle &destArea,
+ GLbitfield mask,
+ GLenum filter)
+{
+ const auto &glState = context->getState();
+ const gl::Framebuffer *sourceFramebuffer = glState.getReadFramebuffer();
+ const gl::Rectangle *scissor = glState.isScissorTestEnabled() ? &glState.getScissor() : nullptr;
+ ANGLE_TRY(blitImpl(context, sourceArea, destArea, scissor, (mask & GL_COLOR_BUFFER_BIT) != 0,
+ (mask & GL_DEPTH_BUFFER_BIT) != 0, (mask & GL_STENCIL_BUFFER_BIT) != 0,
+ filter, sourceFramebuffer));
+
+ return angle::Result::Continue;
+}
+
+gl::FramebufferStatus FramebufferD3D::checkStatus(const gl::Context *context) const
+{
+ // if we have both a depth and stencil buffer, they must refer to the same object
+ // since we only support packed_depth_stencil and not separate depth and stencil
+ if (mState.hasSeparateDepthAndStencilAttachments())
+ {
+ return gl::FramebufferStatus::Incomplete(
+ GL_FRAMEBUFFER_UNSUPPORTED,
+ gl::err::kFramebufferIncompleteUnsupportedSeparateDepthStencilBuffers);
+ }
+
+ // D3D11 does not allow for overlapping RenderTargetViews.
+ // If WebGL compatibility is enabled, this has already been checked at a higher level.
+ ASSERT(!context->isWebGL() || mState.colorAttachmentsAreUniqueImages());
+ if (!context->isWebGL())
+ {
+ if (!mState.colorAttachmentsAreUniqueImages())
+ {
+ return gl::FramebufferStatus::Incomplete(
+ GL_FRAMEBUFFER_UNSUPPORTED,
+ gl::err::kFramebufferIncompleteUnsupportedNonUniqueAttachments);
+ }
+ }
+
+ // D3D requires all render targets to have the same dimensions.
+ if (!mState.attachmentsHaveSameDimensions())
+ {
+ return gl::FramebufferStatus::Incomplete(
+ GL_FRAMEBUFFER_UNSUPPORTED,
+ gl::err::kFramebufferIncompleteUnsupportedMissmatchedDimensions);
+ }
+
+ return gl::FramebufferStatus::Complete();
+}
+
+angle::Result FramebufferD3D::syncState(const gl::Context *context,
+ GLenum binding,
+ const gl::Framebuffer::DirtyBits &dirtyBits,
+ gl::Command command)
+{
+ if (!mColorAttachmentsForRender.valid())
+ {
+ return angle::Result::Continue;
+ }
+
+ for (auto dirtyBit : dirtyBits)
+ {
+ if ((dirtyBit >= gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0 &&
+ dirtyBit < gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_MAX) ||
+ dirtyBit == gl::Framebuffer::DIRTY_BIT_DRAW_BUFFERS)
+ {
+ mColorAttachmentsForRender.reset();
+ }
+ }
+
+ return angle::Result::Continue;
+}
+
+const gl::AttachmentList &FramebufferD3D::getColorAttachmentsForRender(const gl::Context *context)
+{
+ gl::DrawBufferMask activeProgramOutputs =
+ context->getState().getProgram()->getExecutable().getActiveOutputVariablesMask();
+
+ if (mColorAttachmentsForRender.valid() && mCurrentActiveProgramOutputs == activeProgramOutputs)
+ {
+ return mColorAttachmentsForRender.value();
+ }
+
+ // Does not actually free memory
+ gl::AttachmentList colorAttachmentsForRender;
+ mColorAttachmentsForRenderMask.reset();
+
+ const auto &colorAttachments = mState.getColorAttachments();
+ const auto &drawBufferStates = mState.getDrawBufferStates();
+ const auto &features = mRenderer->getFeatures();
+
+ for (size_t attachmentIndex = 0; attachmentIndex < colorAttachments.size(); ++attachmentIndex)
+ {
+ GLenum drawBufferState = drawBufferStates[attachmentIndex];
+ const gl::FramebufferAttachment &colorAttachment = colorAttachments[attachmentIndex];
+
+ if (colorAttachment.isAttached() && drawBufferState != GL_NONE &&
+ activeProgramOutputs[attachmentIndex])
+ {
+ ASSERT(drawBufferState == GL_BACK ||
+ drawBufferState == (GL_COLOR_ATTACHMENT0_EXT + attachmentIndex));
+ colorAttachmentsForRender.push_back(&colorAttachment);
+ mColorAttachmentsForRenderMask.set(attachmentIndex);
+ }
+ else if (!features.mrtPerfWorkaround.enabled)
+ {
+ colorAttachmentsForRender.push_back(nullptr);
+ mColorAttachmentsForRenderMask.set(attachmentIndex);
+ }
+ }
+
+ // When rendering with no render target on D3D, two bugs lead to incorrect behavior on Intel
+ // drivers < 4815. The rendering samples always pass neglecting discard statements in pixel
+ // shader. We add a mock texture as render target in such case.
+ if (mRenderer->getFeatures().addMockTextureNoRenderTarget.enabled &&
+ colorAttachmentsForRender.empty() && activeProgramOutputs.any())
+ {
+ static_assert(static_cast<size_t>(activeProgramOutputs.size()) <= 32,
+ "Size of active program outputs should less or equal than 32.");
+ const GLuint activeProgramLocation = static_cast<GLuint>(
+ gl::ScanForward(static_cast<uint32_t>(activeProgramOutputs.bits())));
+
+ if (mMockAttachment.isAttached() &&
+ (mMockAttachment.getBinding() - GL_COLOR_ATTACHMENT0) == activeProgramLocation)
+ {
+ colorAttachmentsForRender.push_back(&mMockAttachment);
+ }
+ else
+ {
+ // Remove mock attachment to prevents us from leaking it, and the program may require
+ // it to be attached to a new binding point.
+ if (mMockAttachment.isAttached())
+ {
+ mMockAttachment.detach(context, Serial());
+ }
+
+ gl::Texture *mockTex = nullptr;
+ // TODO(jmadill): Handle error if mock texture can't be created.
+ (void)mRenderer->getIncompleteTexture(context, gl::TextureType::_2D, &mockTex);
+ if (mockTex)
+ {
+ gl::ImageIndex index = gl::ImageIndex::Make2D(0);
+ mMockAttachment = gl::FramebufferAttachment(
+ context, GL_TEXTURE, GL_COLOR_ATTACHMENT0_EXT + activeProgramLocation, index,
+ mockTex, Serial());
+ colorAttachmentsForRender.push_back(&mMockAttachment);
+ }
+ }
+ }
+
+ mColorAttachmentsForRender = std::move(colorAttachmentsForRender);
+ mCurrentActiveProgramOutputs = activeProgramOutputs;
+
+ return mColorAttachmentsForRender.value();
+}
+
+void FramebufferD3D::destroy(const gl::Context *context)
+{
+ if (mMockAttachment.isAttached())
+ {
+ mMockAttachment.detach(context, Serial());
+ }
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/FramebufferD3D.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/FramebufferD3D.h
new file mode 100644
index 0000000000..67e19bd4bc
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/FramebufferD3D.h
@@ -0,0 +1,143 @@
+//
+// 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.
+//
+
+// FramebufferD3D.h: Defines the DefaultAttachmentD3D and FramebufferD3D classes.
+
+#ifndef LIBANGLE_RENDERER_D3D_FRAMBUFFERD3D_H_
+#define LIBANGLE_RENDERER_D3D_FRAMBUFFERD3D_H_
+
+#include <cstdint>
+#include <vector>
+
+#include "common/Color.h"
+#include "common/Optional.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/renderer/FramebufferImpl.h"
+
+namespace gl
+{
+class FramebufferAttachment;
+struct PixelPackState;
+
+typedef std::vector<const FramebufferAttachment *> AttachmentList;
+} // namespace gl
+
+namespace rx
+{
+class RendererD3D;
+class RenderTargetD3D;
+
+struct ClearParameters
+{
+ ClearParameters();
+ ClearParameters(const ClearParameters &other);
+
+ gl::DrawBufferMask clearColor;
+ gl::ColorF colorF;
+ gl::ColorI colorI;
+ gl::ColorUI colorUI;
+ GLenum colorType;
+ gl::BlendStateExt::ColorMaskStorage::Type colorMask;
+
+ bool clearDepth;
+ float depthValue;
+
+ bool clearStencil;
+ GLint stencilValue;
+ GLuint stencilWriteMask;
+
+ bool scissorEnabled;
+ gl::Rectangle scissor;
+};
+
+class FramebufferD3D : public FramebufferImpl
+{
+ public:
+ FramebufferD3D(const gl::FramebufferState &data, RendererD3D *renderer);
+ ~FramebufferD3D() override;
+
+ angle::Result clear(const gl::Context *context, GLbitfield mask) override;
+ angle::Result clearBufferfv(const gl::Context *context,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLfloat *values) override;
+ angle::Result clearBufferuiv(const gl::Context *context,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLuint *values) override;
+ angle::Result clearBufferiv(const gl::Context *context,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLint *values) override;
+ angle::Result clearBufferfi(const gl::Context *context,
+ GLenum buffer,
+ GLint drawbuffer,
+ GLfloat depth,
+ GLint stencil) override;
+
+ angle::Result readPixels(const gl::Context *context,
+ const gl::Rectangle &area,
+ GLenum format,
+ GLenum type,
+ const gl::PixelPackState &pack,
+ gl::Buffer *packBuffer,
+ void *pixels) override;
+
+ angle::Result blit(const gl::Context *context,
+ const gl::Rectangle &sourceArea,
+ const gl::Rectangle &destArea,
+ GLbitfield mask,
+ GLenum filter) override;
+
+ gl::FramebufferStatus checkStatus(const gl::Context *context) const override;
+
+ angle::Result syncState(const gl::Context *context,
+ GLenum binding,
+ const gl::Framebuffer::DirtyBits &dirtyBits,
+ gl::Command command) override;
+
+ const gl::AttachmentList &getColorAttachmentsForRender(const gl::Context *context);
+
+ const gl::DrawBufferMask getLastColorAttachmentsForRenderMask() const
+ {
+ return mColorAttachmentsForRenderMask;
+ }
+
+ void destroy(const gl::Context *context) override;
+
+ private:
+ virtual angle::Result clearImpl(const gl::Context *context,
+ const ClearParameters &clearParams) = 0;
+
+ virtual angle::Result readPixelsImpl(const gl::Context *context,
+ const gl::Rectangle &area,
+ GLenum format,
+ GLenum type,
+ size_t outputPitch,
+ const gl::PixelPackState &pack,
+ gl::Buffer *packBuffer,
+ uint8_t *pixels) = 0;
+
+ virtual angle::Result blitImpl(const gl::Context *context,
+ const gl::Rectangle &sourceArea,
+ const gl::Rectangle &destArea,
+ const gl::Rectangle *scissor,
+ bool blitRenderTarget,
+ bool blitDepth,
+ bool blitStencil,
+ GLenum filter,
+ const gl::Framebuffer *sourceFramebuffer) = 0;
+
+ RendererD3D *mRenderer;
+ Optional<gl::AttachmentList> mColorAttachmentsForRender;
+ gl::DrawBufferMask mCurrentActiveProgramOutputs;
+ gl::DrawBufferMask mColorAttachmentsForRenderMask;
+
+ gl::FramebufferAttachment mMockAttachment;
+};
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_FRAMBUFFERD3D_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/HLSLCompiler.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/HLSLCompiler.cpp
new file mode 100644
index 0000000000..e7260e403a
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/HLSLCompiler.cpp
@@ -0,0 +1,387 @@
+//
+// 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.
+//
+
+#include "libANGLE/renderer/d3d/HLSLCompiler.h"
+
+#include <sstream>
+
+#include "common/system_utils.h"
+#include "common/utilities.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Program.h"
+#include "libANGLE/features.h"
+#include "libANGLE/histogram_macros.h"
+#include "libANGLE/renderer/d3d/ContextD3D.h"
+#include "libANGLE/trace.h"
+
+namespace
+{
+#if ANGLE_APPEND_ASSEMBLY_TO_SHADER_DEBUG_INFO == ANGLE_ENABLED
+# ifdef CREATE_COMPILER_FLAG_INFO
+# undef CREATE_COMPILER_FLAG_INFO
+# endif
+
+# define CREATE_COMPILER_FLAG_INFO(flag) \
+ { \
+ flag, #flag \
+ }
+
+struct CompilerFlagInfo
+{
+ UINT mFlag;
+ const char *mName;
+};
+
+CompilerFlagInfo CompilerFlagInfos[] = {
+ // NOTE: The data below is copied from d3dcompiler.h
+ // If something changes there it should be changed here as well
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_DEBUG), // (1 << 0)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_SKIP_VALIDATION), // (1 << 1)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_SKIP_OPTIMIZATION), // (1 << 2)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_PACK_MATRIX_ROW_MAJOR), // (1 << 3)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR), // (1 << 4)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_PARTIAL_PRECISION), // (1 << 5)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_FORCE_VS_SOFTWARE_NO_OPT), // (1 << 6)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_FORCE_PS_SOFTWARE_NO_OPT), // (1 << 7)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_NO_PRESHADER), // (1 << 8)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_AVOID_FLOW_CONTROL), // (1 << 9)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_PREFER_FLOW_CONTROL), // (1 << 10)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_ENABLE_STRICTNESS), // (1 << 11)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY), // (1 << 12)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_IEEE_STRICTNESS), // (1 << 13)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_OPTIMIZATION_LEVEL0), // (1 << 14)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_OPTIMIZATION_LEVEL1), // 0
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_OPTIMIZATION_LEVEL2), // ((1 << 14) | (1 << 15))
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_OPTIMIZATION_LEVEL3), // (1 << 15)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_RESERVED16), // (1 << 16)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_RESERVED17), // (1 << 17)
+ CREATE_COMPILER_FLAG_INFO(D3DCOMPILE_WARNINGS_ARE_ERRORS) // (1 << 18)
+};
+
+# undef CREATE_COMPILER_FLAG_INFO
+
+bool IsCompilerFlagSet(UINT mask, UINT flag)
+{
+ bool isFlagSet = IsMaskFlagSet(mask, flag);
+
+ switch (flag)
+ {
+ case D3DCOMPILE_OPTIMIZATION_LEVEL0:
+ return isFlagSet && !IsMaskFlagSet(mask, UINT(D3DCOMPILE_OPTIMIZATION_LEVEL3));
+
+ case D3DCOMPILE_OPTIMIZATION_LEVEL1:
+ return (mask & D3DCOMPILE_OPTIMIZATION_LEVEL2) == UINT(0);
+
+ case D3DCOMPILE_OPTIMIZATION_LEVEL3:
+ return isFlagSet && !IsMaskFlagSet(mask, UINT(D3DCOMPILE_OPTIMIZATION_LEVEL0));
+
+ default:
+ return isFlagSet;
+ }
+}
+#endif // ANGLE_APPEND_ASSEMBLY_TO_SHADER_DEBUG_INFO == ANGLE_ENABLED
+
+constexpr char kOldCompilerLibrary[] = "d3dcompiler_old.dll";
+
+enum D3DCompilerLoadLibraryResult
+{
+ D3DCompilerDefaultLibrarySuccess,
+ D3DCompilerOldLibrarySuccess,
+ D3DCompilerFailure,
+ D3DCompilerEnumBoundary,
+};
+} // anonymous namespace
+
+namespace rx
+{
+
+CompileConfig::CompileConfig() : flags(0), name() {}
+
+CompileConfig::CompileConfig(UINT flags, const std::string &name) : flags(flags), name(name) {}
+
+HLSLCompiler::HLSLCompiler()
+ : mInitialized(false),
+ mD3DCompilerModule(nullptr),
+ mD3DCompileFunc(nullptr),
+ mD3DDisassembleFunc(nullptr)
+{}
+
+HLSLCompiler::~HLSLCompiler()
+{
+ release();
+}
+
+angle::Result HLSLCompiler::ensureInitialized(d3d::Context *context)
+{
+ if (mInitialized)
+ {
+ return angle::Result::Continue;
+ }
+
+ ANGLE_TRACE_EVENT0("gpu.angle", "HLSLCompiler::initialize");
+#if !defined(ANGLE_ENABLE_WINDOWS_UWP)
+# if defined(ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES)
+ // Find a D3DCompiler module that had already been loaded based on a predefined list of
+ // versions.
+ static const char *d3dCompilerNames[] = ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES;
+
+ for (size_t i = 0; i < ArraySize(d3dCompilerNames); ++i)
+ {
+ if (GetModuleHandleExA(0, d3dCompilerNames[i], &mD3DCompilerModule))
+ {
+ break;
+ }
+ }
+# endif // ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES
+
+ if (!mD3DCompilerModule)
+ {
+ // Load the version of the D3DCompiler DLL associated with the Direct3D version ANGLE was
+ // built with.
+ mD3DCompilerModule = LoadLibraryA(D3DCOMPILER_DLL_A);
+
+ if (mD3DCompilerModule)
+ {
+ ANGLE_HISTOGRAM_ENUMERATION("GPU.ANGLE.D3DCompilerLoadLibraryResult",
+ D3DCompilerDefaultLibrarySuccess, D3DCompilerEnumBoundary);
+ }
+ else
+ {
+ WARN() << "Failed to load HLSL compiler library. Using 'old' DLL.";
+ mD3DCompilerModule = LoadLibraryA(kOldCompilerLibrary);
+ if (mD3DCompilerModule)
+ {
+ ANGLE_HISTOGRAM_ENUMERATION("GPU.ANGLE.D3DCompilerLoadLibraryResult",
+ D3DCompilerOldLibrarySuccess, D3DCompilerEnumBoundary);
+ }
+ }
+ }
+
+ if (!mD3DCompilerModule)
+ {
+ DWORD lastError = GetLastError();
+ ERR() << "D3D Compiler LoadLibrary failed. GetLastError=" << lastError;
+ ANGLE_HISTOGRAM_ENUMERATION("GPU.ANGLE.D3DCompilerLoadLibraryResult", D3DCompilerFailure,
+ D3DCompilerEnumBoundary);
+ ANGLE_TRY_HR(context, E_OUTOFMEMORY, "LoadLibrary failed to load D3D Compiler DLL.");
+ }
+
+ mD3DCompileFunc =
+ reinterpret_cast<pD3DCompile>(GetProcAddress(mD3DCompilerModule, "D3DCompile"));
+ ASSERT(mD3DCompileFunc);
+
+ mD3DDisassembleFunc =
+ reinterpret_cast<pD3DDisassemble>(GetProcAddress(mD3DCompilerModule, "D3DDisassemble"));
+ ASSERT(mD3DDisassembleFunc);
+
+#else
+ // D3D Shader compiler is linked already into this module, so the export
+ // can be directly assigned.
+ mD3DCompilerModule = nullptr;
+ mD3DCompileFunc = reinterpret_cast<pD3DCompile>(D3DCompile);
+ mD3DDisassembleFunc = reinterpret_cast<pD3DDisassemble>(D3DDisassemble);
+#endif
+
+ ANGLE_CHECK_HR(context, mD3DCompileFunc, "Error finding D3DCompile entry point.",
+ E_OUTOFMEMORY);
+
+ mInitialized = true;
+ return angle::Result::Continue;
+}
+
+void HLSLCompiler::release()
+{
+ if (mInitialized)
+ {
+ FreeLibrary(mD3DCompilerModule);
+ mD3DCompilerModule = nullptr;
+ mD3DCompileFunc = nullptr;
+ mD3DDisassembleFunc = nullptr;
+ mInitialized = false;
+ }
+}
+
+angle::Result HLSLCompiler::compileToBinary(d3d::Context *context,
+ gl::InfoLog &infoLog,
+ const std::string &hlsl,
+ const std::string &profile,
+ const std::vector<CompileConfig> &configs,
+ const D3D_SHADER_MACRO *overrideMacros,
+ ID3DBlob **outCompiledBlob,
+ std::string *outDebugInfo)
+{
+ ASSERT(mInitialized);
+
+#if !defined(ANGLE_ENABLE_WINDOWS_UWP)
+ ASSERT(mD3DCompilerModule);
+#endif
+ ASSERT(mD3DCompileFunc);
+
+#if !defined(ANGLE_ENABLE_WINDOWS_UWP) && defined(ANGLE_ENABLE_DEBUG_TRACE)
+ std::string sourcePath = angle::CreateTemporaryFile().value();
+ std::ostringstream stream;
+ stream << "#line 2 \"" << sourcePath << "\"\n\n" << hlsl;
+ std::string sourceText = stream.str();
+ writeFile(sourcePath.c_str(), sourceText.c_str(), sourceText.size());
+#endif
+
+ const D3D_SHADER_MACRO *macros = overrideMacros ? overrideMacros : nullptr;
+
+ for (size_t i = 0; i < configs.size(); ++i)
+ {
+ ID3DBlob *errorMessage = nullptr;
+ ID3DBlob *binary = nullptr;
+ HRESULT result = S_OK;
+
+ {
+ ANGLE_TRACE_EVENT1("gpu.angle", "D3DCompile", "source", hlsl);
+ result = mD3DCompileFunc(hlsl.c_str(), hlsl.length(), gl::g_fakepath, macros, nullptr,
+ "main", profile.c_str(), configs[i].flags, 0, &binary,
+ &errorMessage);
+ }
+
+ if (errorMessage)
+ {
+ std::string message = static_cast<const char *>(errorMessage->GetBufferPointer());
+ SafeRelease(errorMessage);
+ ANGLE_TRACE_EVENT1("gpu.angle", "D3DCompile::Error", "error", errorMessage);
+
+ infoLog.appendSanitized(message.c_str());
+
+ // This produces unbelievable amounts of spam in about:gpu.
+ // WARN() << std::endl << hlsl;
+
+ WARN() << std::endl << message;
+
+ if (macros != nullptr)
+ {
+ constexpr const char *kLoopRelatedErrors[] = {
+ // "can't unroll loops marked with loop attribute"
+ "error X3531:",
+
+ // "cannot have gradient operations inside loops with divergent flow control",
+ // even though it is counter-intuitive to disable unrolling for this error, some
+ // very long shaders have trouble deciding which loops to unroll and turning off
+ // forced unrolls allows them to compile properly.
+ "error X4014:",
+
+ // "array index out of bounds", loop unrolling can result in invalid array
+ // access if the indices become constant, causing loops that may never be
+ // executed to generate compilation errors
+ "error X3504:",
+ };
+
+ bool hasLoopRelatedError = false;
+ for (const char *errorType : kLoopRelatedErrors)
+ {
+ if (message.find(errorType) != std::string::npos)
+ {
+ hasLoopRelatedError = true;
+ break;
+ }
+ }
+
+ if (hasLoopRelatedError)
+ {
+ // Disable [loop] and [flatten]
+ macros = nullptr;
+
+ // Retry without changing compiler flags
+ i--;
+ continue;
+ }
+ }
+ }
+
+ if (SUCCEEDED(result))
+ {
+ *outCompiledBlob = binary;
+
+ (*outDebugInfo) +=
+ "// COMPILER INPUT HLSL BEGIN\n\n" + hlsl + "\n// COMPILER INPUT HLSL END\n";
+
+#if ANGLE_APPEND_ASSEMBLY_TO_SHADER_DEBUG_INFO == ANGLE_ENABLED
+ (*outDebugInfo) += "\n\n// ASSEMBLY BEGIN\n\n";
+ (*outDebugInfo) += "// Compiler configuration: " + configs[i].name + "\n// Flags:\n";
+ for (size_t fIx = 0; fIx < ArraySize(CompilerFlagInfos); ++fIx)
+ {
+ if (IsCompilerFlagSet(configs[i].flags, CompilerFlagInfos[fIx].mFlag))
+ {
+ (*outDebugInfo) += std::string("// ") + CompilerFlagInfos[fIx].mName + "\n";
+ }
+ }
+
+ (*outDebugInfo) += "// Macros:\n";
+ if (macros == nullptr)
+ {
+ (*outDebugInfo) += "// - : -\n";
+ }
+ else
+ {
+ for (const D3D_SHADER_MACRO *mIt = macros; mIt->Name != nullptr; ++mIt)
+ {
+ (*outDebugInfo) +=
+ std::string("// ") + mIt->Name + " : " + mIt->Definition + "\n";
+ }
+ }
+
+ std::string disassembly;
+ ANGLE_TRY(disassembleBinary(context, binary, &disassembly));
+ (*outDebugInfo) += "\n" + disassembly + "\n// ASSEMBLY END\n";
+#endif // ANGLE_APPEND_ASSEMBLY_TO_SHADER_DEBUG_INFO == ANGLE_ENABLED
+ return angle::Result::Continue;
+ }
+
+ if (result == E_OUTOFMEMORY)
+ {
+ *outCompiledBlob = nullptr;
+ ANGLE_TRY_HR(context, result, "HLSL compiler had an unexpected failure");
+ }
+
+ infoLog << "Warning: D3D shader compilation failed with " << configs[i].name << " flags. ("
+ << profile << ")";
+
+ if (i + 1 < configs.size())
+ {
+ infoLog << " Retrying with " << configs[i + 1].name;
+ }
+ }
+
+ // None of the configurations succeeded in compiling this shader but the compiler is still
+ // intact
+ *outCompiledBlob = nullptr;
+ return angle::Result::Continue;
+}
+
+angle::Result HLSLCompiler::disassembleBinary(d3d::Context *context,
+ ID3DBlob *shaderBinary,
+ std::string *disassemblyOut)
+{
+ ANGLE_TRY(ensureInitialized(context));
+
+ // Retrieve disassembly
+ UINT flags = D3D_DISASM_ENABLE_DEFAULT_VALUE_PRINTS | D3D_DISASM_ENABLE_INSTRUCTION_NUMBERING;
+ ID3DBlob *disassembly = nullptr;
+ pD3DDisassemble disassembleFunc = reinterpret_cast<pD3DDisassemble>(mD3DDisassembleFunc);
+ LPCVOID buffer = shaderBinary->GetBufferPointer();
+ SIZE_T bufSize = shaderBinary->GetBufferSize();
+ HRESULT result = disassembleFunc(buffer, bufSize, flags, "", &disassembly);
+
+ if (SUCCEEDED(result))
+ {
+ *disassemblyOut = std::string(static_cast<const char *>(disassembly->GetBufferPointer()));
+ }
+ else
+ {
+ *disassemblyOut = "";
+ }
+
+ SafeRelease(disassembly);
+
+ return angle::Result::Continue;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/HLSLCompiler.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/HLSLCompiler.h
new file mode 100644
index 0000000000..98a17799cf
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/HLSLCompiler.h
@@ -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.
+//
+// HLSLCompiler: Wrapper for the D3DCompiler DLL.
+//
+
+#ifndef LIBANGLE_RENDERER_D3D_HLSLCOMPILER_H_
+#define LIBANGLE_RENDERER_D3D_HLSLCOMPILER_H_
+
+#include "libANGLE/Error.h"
+
+#include "common/angleutils.h"
+#include "common/platform.h"
+
+#include <string>
+#include <vector>
+
+namespace gl
+{
+class InfoLog;
+} // namespace gl
+
+namespace rx
+{
+namespace d3d
+{
+class Context;
+} // namespace d3d
+
+struct CompileConfig
+{
+ UINT flags;
+ std::string name;
+
+ CompileConfig();
+ CompileConfig(UINT flags, const std::string &name);
+};
+
+class HLSLCompiler : angle::NonCopyable
+{
+ public:
+ HLSLCompiler();
+ ~HLSLCompiler();
+
+ void release();
+
+ // Attempt to compile a HLSL shader using the supplied configurations, may output a NULL
+ // compiled blob even if no GL errors are returned.
+ angle::Result compileToBinary(d3d::Context *context,
+ gl::InfoLog &infoLog,
+ const std::string &hlsl,
+ const std::string &profile,
+ const std::vector<CompileConfig> &configs,
+ const D3D_SHADER_MACRO *overrideMacros,
+ ID3DBlob **outCompiledBlob,
+ std::string *outDebugInfo);
+
+ angle::Result disassembleBinary(d3d::Context *context,
+ ID3DBlob *shaderBinary,
+ std::string *disassemblyOut);
+ angle::Result ensureInitialized(d3d::Context *context);
+
+ private:
+ bool mInitialized;
+ HMODULE mD3DCompilerModule;
+ pD3DCompile mD3DCompileFunc;
+ pD3DDisassemble mD3DDisassembleFunc;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_HLSLCOMPILER_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/ImageD3D.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/ImageD3D.cpp
new file mode 100644
index 0000000000..67ad3aee70
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/ImageD3D.cpp
@@ -0,0 +1,56 @@
+//
+// Copyright 2002 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.
+//
+
+// Image.h: Implements the rx::Image class, an abstract base class for the
+// renderer-specific classes which will define the interface to the underlying
+// surfaces or resources.
+
+#include "libANGLE/renderer/d3d/ImageD3D.h"
+
+namespace rx
+{
+
+ImageD3D::ImageD3D()
+ : mWidth(0),
+ mHeight(0),
+ mDepth(0),
+ mInternalFormat(GL_NONE),
+ mRenderable(false),
+ mType(gl::TextureType::InvalidEnum),
+ mDirty(false)
+{}
+
+angle::Result ImageD3D::setManagedSurface2D(const gl::Context *context,
+ TextureStorage *storage,
+ int level)
+{
+ return angle::Result::Continue;
+}
+
+angle::Result ImageD3D::setManagedSurfaceCube(const gl::Context *context,
+ TextureStorage *storage,
+ int face,
+ int level)
+{
+ return angle::Result::Continue;
+}
+
+angle::Result ImageD3D::setManagedSurface3D(const gl::Context *context,
+ TextureStorage *storage,
+ int level)
+{
+ return angle::Result::Continue;
+}
+
+angle::Result ImageD3D::setManagedSurface2DArray(const gl::Context *context,
+ TextureStorage *storage,
+ int layer,
+ int level)
+{
+ return angle::Result::Continue;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/ImageD3D.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/ImageD3D.h
new file mode 100644
index 0000000000..ac58ca5cf6
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/ImageD3D.h
@@ -0,0 +1,105 @@
+//
+// Copyright 2002 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.
+//
+
+// ImageD3D.h: Defines the rx::ImageD3D class, an abstract base class for the
+// renderer-specific classes which will define the interface to the underlying
+// surfaces or resources.
+
+#ifndef LIBANGLE_RENDERER_D3D_IMAGED3D_H_
+#define LIBANGLE_RENDERER_D3D_IMAGED3D_H_
+
+#include "common/debug.h"
+
+#include "common/PackedEnums.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/angletypes.h"
+
+namespace gl
+{
+class Context;
+class Framebuffer;
+class ImageIndex;
+struct PixelUnpackState;
+} // namespace gl
+
+namespace rx
+{
+class TextureStorage;
+class RendererD3D;
+class RenderTargetD3D;
+
+class ImageD3D : angle::NonCopyable
+{
+ public:
+ ImageD3D();
+ virtual ~ImageD3D() {}
+
+ GLsizei getWidth() const { return mWidth; }
+ GLsizei getHeight() const { return mHeight; }
+ GLsizei getDepth() const { return mDepth; }
+ GLenum getInternalFormat() const { return mInternalFormat; }
+ gl::TextureType getType() const { return mType; }
+ bool isRenderableFormat() const { return mRenderable; }
+
+ void markDirty() { mDirty = true; }
+ void markClean() { mDirty = false; }
+ virtual bool isDirty() const = 0;
+
+ virtual bool redefine(gl::TextureType type,
+ GLenum internalformat,
+ const gl::Extents &size,
+ bool forceRelease) = 0;
+
+ virtual angle::Result loadData(const gl::Context *context,
+ const gl::Box &area,
+ const gl::PixelUnpackState &unpack,
+ GLenum type,
+ const void *input,
+ bool applySkipImages) = 0;
+ virtual angle::Result loadCompressedData(const gl::Context *context,
+ const gl::Box &area,
+ const void *input) = 0;
+
+ virtual angle::Result setManagedSurface2D(const gl::Context *context,
+ TextureStorage *storage,
+ int level);
+ virtual angle::Result setManagedSurfaceCube(const gl::Context *context,
+ TextureStorage *storage,
+ int face,
+ int level);
+ virtual angle::Result setManagedSurface3D(const gl::Context *context,
+ TextureStorage *storage,
+ int level);
+ virtual angle::Result setManagedSurface2DArray(const gl::Context *context,
+ TextureStorage *storage,
+ int layer,
+ int level);
+ virtual angle::Result copyToStorage(const gl::Context *context,
+ TextureStorage *storage,
+ const gl::ImageIndex &index,
+ const gl::Box &region) = 0;
+
+ virtual angle::Result copyFromTexStorage(const gl::Context *context,
+ const gl::ImageIndex &imageIndex,
+ TextureStorage *source) = 0;
+ virtual angle::Result copyFromFramebuffer(const gl::Context *context,
+ const gl::Offset &destOffset,
+ const gl::Rectangle &sourceArea,
+ const gl::Framebuffer *source) = 0;
+
+ protected:
+ GLsizei mWidth;
+ GLsizei mHeight;
+ GLsizei mDepth;
+ GLenum mInternalFormat;
+ bool mRenderable;
+ gl::TextureType mType;
+
+ bool mDirty;
+};
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_IMAGED3D_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/IndexBuffer.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/IndexBuffer.cpp
new file mode 100644
index 0000000000..423067e67e
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/IndexBuffer.cpp
@@ -0,0 +1,183 @@
+//
+// Copyright 2002 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.
+//
+
+// IndexBuffer.cpp: Defines the abstract IndexBuffer class and IndexBufferInterface
+// class with derivations, classes that perform graphics API agnostic index buffer operations.
+
+#include "libANGLE/renderer/d3d/IndexBuffer.h"
+
+#include "libANGLE/Context.h"
+#include "libANGLE/renderer/d3d/ContextD3D.h"
+
+namespace rx
+{
+
+unsigned int IndexBuffer::mNextSerial = 1;
+
+IndexBuffer::IndexBuffer()
+{
+ updateSerial();
+}
+
+IndexBuffer::~IndexBuffer() {}
+
+unsigned int IndexBuffer::getSerial() const
+{
+ return mSerial;
+}
+
+void IndexBuffer::updateSerial()
+{
+ mSerial = mNextSerial++;
+}
+
+IndexBufferInterface::IndexBufferInterface(BufferFactoryD3D *factory, bool dynamic)
+{
+ mIndexBuffer = factory->createIndexBuffer();
+
+ mDynamic = dynamic;
+ mWritePosition = 0;
+}
+
+IndexBufferInterface::~IndexBufferInterface()
+{
+ if (mIndexBuffer)
+ {
+ delete mIndexBuffer;
+ }
+}
+
+gl::DrawElementsType IndexBufferInterface::getIndexType() const
+{
+ return mIndexBuffer->getIndexType();
+}
+
+unsigned int IndexBufferInterface::getBufferSize() const
+{
+ return mIndexBuffer->getBufferSize();
+}
+
+unsigned int IndexBufferInterface::getSerial() const
+{
+ return mIndexBuffer->getSerial();
+}
+
+angle::Result IndexBufferInterface::mapBuffer(const gl::Context *context,
+ unsigned int size,
+ void **outMappedMemory,
+ unsigned int *streamOffset)
+{
+ // Protect against integer overflow
+ bool check = (mWritePosition + size < mWritePosition);
+ ANGLE_CHECK(GetImplAs<ContextD3D>(context), !check,
+ "Mapping of internal index buffer would cause an integer overflow.",
+ GL_OUT_OF_MEMORY);
+
+ angle::Result error = mIndexBuffer->mapBuffer(context, mWritePosition, size, outMappedMemory);
+ if (error == angle::Result::Stop)
+ {
+ if (outMappedMemory)
+ {
+ *outMappedMemory = nullptr;
+ }
+ return error;
+ }
+
+ if (streamOffset)
+ {
+ *streamOffset = mWritePosition;
+ }
+
+ mWritePosition += size;
+ return angle::Result::Continue;
+}
+
+angle::Result IndexBufferInterface::unmapBuffer(const gl::Context *context)
+{
+ return mIndexBuffer->unmapBuffer(context);
+}
+
+IndexBuffer *IndexBufferInterface::getIndexBuffer() const
+{
+ return mIndexBuffer;
+}
+
+unsigned int IndexBufferInterface::getWritePosition() const
+{
+ return mWritePosition;
+}
+
+void IndexBufferInterface::setWritePosition(unsigned int writePosition)
+{
+ mWritePosition = writePosition;
+}
+
+angle::Result IndexBufferInterface::discard(const gl::Context *context)
+{
+ return mIndexBuffer->discard(context);
+}
+
+angle::Result IndexBufferInterface::setBufferSize(const gl::Context *context,
+ unsigned int bufferSize,
+ gl::DrawElementsType indexType)
+{
+ if (mIndexBuffer->getBufferSize() == 0)
+ {
+ return mIndexBuffer->initialize(context, bufferSize, indexType, mDynamic);
+ }
+ else
+ {
+ return mIndexBuffer->setSize(context, bufferSize, indexType);
+ }
+}
+
+StreamingIndexBufferInterface::StreamingIndexBufferInterface(BufferFactoryD3D *factory)
+ : IndexBufferInterface(factory, true)
+{}
+
+StreamingIndexBufferInterface::~StreamingIndexBufferInterface() {}
+
+angle::Result StreamingIndexBufferInterface::reserveBufferSpace(const gl::Context *context,
+ unsigned int size,
+ gl::DrawElementsType indexType)
+{
+ unsigned int curBufferSize = getBufferSize();
+ unsigned int writePos = getWritePosition();
+ if (size > curBufferSize)
+ {
+ ANGLE_TRY(setBufferSize(context, std::max(size, 2 * curBufferSize), indexType));
+ setWritePosition(0);
+ }
+ else if (writePos + size > curBufferSize || writePos + size < writePos)
+ {
+ ANGLE_TRY(discard(context));
+ setWritePosition(0);
+ }
+
+ return angle::Result::Continue;
+}
+
+StaticIndexBufferInterface::StaticIndexBufferInterface(BufferFactoryD3D *factory)
+ : IndexBufferInterface(factory, false)
+{}
+
+StaticIndexBufferInterface::~StaticIndexBufferInterface() {}
+
+angle::Result StaticIndexBufferInterface::reserveBufferSpace(const gl::Context *context,
+ unsigned int size,
+ gl::DrawElementsType indexType)
+{
+ unsigned int curSize = getBufferSize();
+ if (curSize == 0)
+ {
+ return setBufferSize(context, size, indexType);
+ }
+
+ ASSERT(curSize >= size && indexType == getIndexType());
+ return angle::Result::Continue;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/IndexBuffer.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/IndexBuffer.h
new file mode 100644
index 0000000000..7bab52a9f0
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/IndexBuffer.h
@@ -0,0 +1,125 @@
+//
+// Copyright 2002 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.
+//
+
+// IndexBuffer.h: Defines the abstract IndexBuffer class and IndexBufferInterface
+// class with derivations, classes that perform graphics API agnostic index buffer operations.
+
+#ifndef LIBANGLE_RENDERER_D3D_INDEXBUFFER_H_
+#define LIBANGLE_RENDERER_D3D_INDEXBUFFER_H_
+
+#include "common/PackedEnums.h"
+#include "common/angleutils.h"
+#include "libANGLE/Error.h"
+
+namespace gl
+{
+class Context;
+} // namespace gl
+
+namespace rx
+{
+class BufferFactoryD3D;
+
+class IndexBuffer : angle::NonCopyable
+{
+ public:
+ IndexBuffer();
+ virtual ~IndexBuffer();
+
+ virtual angle::Result initialize(const gl::Context *context,
+ unsigned int bufferSize,
+ gl::DrawElementsType indexType,
+ bool dynamic) = 0;
+
+ virtual angle::Result mapBuffer(const gl::Context *context,
+ unsigned int offset,
+ unsigned int size,
+ void **outMappedMemory) = 0;
+ virtual angle::Result unmapBuffer(const gl::Context *context) = 0;
+
+ virtual angle::Result discard(const gl::Context *context) = 0;
+
+ virtual gl::DrawElementsType getIndexType() const = 0;
+ virtual unsigned int getBufferSize() const = 0;
+ virtual angle::Result setSize(const gl::Context *context,
+ unsigned int bufferSize,
+ gl::DrawElementsType indexType) = 0;
+
+ unsigned int getSerial() const;
+
+ protected:
+ void updateSerial();
+
+ private:
+ unsigned int mSerial;
+ static unsigned int mNextSerial;
+};
+
+class IndexBufferInterface : angle::NonCopyable
+{
+ public:
+ IndexBufferInterface(BufferFactoryD3D *factory, bool dynamic);
+ virtual ~IndexBufferInterface();
+
+ virtual angle::Result reserveBufferSpace(const gl::Context *context,
+ unsigned int size,
+ gl::DrawElementsType indexType) = 0;
+
+ gl::DrawElementsType getIndexType() const;
+ unsigned int getBufferSize() const;
+
+ unsigned int getSerial() const;
+
+ angle::Result mapBuffer(const gl::Context *context,
+ unsigned int size,
+ void **outMappedMemory,
+ unsigned int *streamOffset);
+ angle::Result unmapBuffer(const gl::Context *context);
+
+ IndexBuffer *getIndexBuffer() const;
+
+ protected:
+ unsigned int getWritePosition() const;
+ void setWritePosition(unsigned int writePosition);
+
+ angle::Result discard(const gl::Context *context);
+
+ angle::Result setBufferSize(const gl::Context *context,
+ unsigned int bufferSize,
+ gl::DrawElementsType indexType);
+
+ private:
+ IndexBuffer *mIndexBuffer;
+
+ unsigned int mWritePosition;
+ bool mDynamic;
+};
+
+class StreamingIndexBufferInterface : public IndexBufferInterface
+{
+ public:
+ explicit StreamingIndexBufferInterface(BufferFactoryD3D *factory);
+ ~StreamingIndexBufferInterface() override;
+
+ angle::Result reserveBufferSpace(const gl::Context *context,
+ unsigned int size,
+ gl::DrawElementsType indexType) override;
+};
+
+class StaticIndexBufferInterface : public IndexBufferInterface
+{
+ public:
+ explicit StaticIndexBufferInterface(BufferFactoryD3D *factory);
+ ~StaticIndexBufferInterface() override;
+
+ angle::Result reserveBufferSpace(const gl::Context *context,
+ unsigned int size,
+ gl::DrawElementsType indexType) override;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_INDEXBUFFER_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/IndexDataManager.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/IndexDataManager.cpp
new file mode 100644
index 0000000000..dd8f45342f
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/IndexDataManager.cpp
@@ -0,0 +1,318 @@
+//
+// Copyright 2002 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.
+//
+
+// IndexDataManager.cpp: Defines the IndexDataManager, a class that
+// runs the Buffer translation process for index buffers.
+
+#include "libANGLE/renderer/d3d/IndexDataManager.h"
+
+#include "common/utilities.h"
+#include "libANGLE/Buffer.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/VertexArray.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/d3d/BufferD3D.h"
+#include "libANGLE/renderer/d3d/ContextD3D.h"
+#include "libANGLE/renderer/d3d/IndexBuffer.h"
+
+namespace rx
+{
+
+namespace
+{
+
+template <typename InputT, typename DestT>
+void ConvertIndexArray(const void *input,
+ gl::DrawElementsType sourceType,
+ void *output,
+ gl::DrawElementsType destinationType,
+ GLsizei count,
+ bool usePrimitiveRestartFixedIndex)
+{
+ const InputT *in = static_cast<const InputT *>(input);
+ DestT *out = static_cast<DestT *>(output);
+
+ if (usePrimitiveRestartFixedIndex)
+ {
+ InputT srcRestartIndex = static_cast<InputT>(gl::GetPrimitiveRestartIndex(sourceType));
+ DestT destRestartIndex = static_cast<DestT>(gl::GetPrimitiveRestartIndex(destinationType));
+ for (GLsizei i = 0; i < count; i++)
+ {
+ out[i] = (in[i] == srcRestartIndex ? destRestartIndex : static_cast<DestT>(in[i]));
+ }
+ }
+ else
+ {
+ for (GLsizei i = 0; i < count; i++)
+ {
+ out[i] = static_cast<DestT>(in[i]);
+ }
+ }
+}
+
+void ConvertIndices(gl::DrawElementsType sourceType,
+ gl::DrawElementsType destinationType,
+ const void *input,
+ GLsizei count,
+ void *output,
+ bool usePrimitiveRestartFixedIndex)
+{
+ if (sourceType == destinationType)
+ {
+ const GLuint dstTypeSize = gl::GetDrawElementsTypeSize(destinationType);
+ memcpy(output, input, count * dstTypeSize);
+ return;
+ }
+
+ if (sourceType == gl::DrawElementsType::UnsignedByte)
+ {
+ ASSERT(destinationType == gl::DrawElementsType::UnsignedShort);
+ ConvertIndexArray<GLubyte, GLushort>(input, sourceType, output, destinationType, count,
+ usePrimitiveRestartFixedIndex);
+ }
+ else if (sourceType == gl::DrawElementsType::UnsignedShort)
+ {
+ ASSERT(destinationType == gl::DrawElementsType::UnsignedInt);
+ ConvertIndexArray<GLushort, GLuint>(input, sourceType, output, destinationType, count,
+ usePrimitiveRestartFixedIndex);
+ }
+ else
+ UNREACHABLE();
+}
+
+angle::Result StreamInIndexBuffer(const gl::Context *context,
+ IndexBufferInterface *buffer,
+ const void *data,
+ unsigned int count,
+ gl::DrawElementsType srcType,
+ gl::DrawElementsType dstType,
+ bool usePrimitiveRestartFixedIndex,
+ unsigned int *offset)
+{
+ const GLuint dstTypeBytesShift = gl::GetDrawElementsTypeShift(dstType);
+
+ bool check = (count > (std::numeric_limits<unsigned int>::max() >> dstTypeBytesShift));
+ ANGLE_CHECK(GetImplAs<ContextD3D>(context), !check,
+ "Reserving indices exceeds the maximum buffer size.", GL_OUT_OF_MEMORY);
+
+ unsigned int bufferSizeRequired = count << dstTypeBytesShift;
+ ANGLE_TRY(buffer->reserveBufferSpace(context, bufferSizeRequired, dstType));
+
+ void *output = nullptr;
+ ANGLE_TRY(buffer->mapBuffer(context, bufferSizeRequired, &output, offset));
+
+ ConvertIndices(srcType, dstType, data, count, output, usePrimitiveRestartFixedIndex);
+
+ ANGLE_TRY(buffer->unmapBuffer(context));
+ return angle::Result::Continue;
+}
+} // anonymous namespace
+
+// IndexDataManager implementation.
+IndexDataManager::IndexDataManager(BufferFactoryD3D *factory)
+ : mFactory(factory), mStreamingBufferShort(), mStreamingBufferInt()
+{}
+
+IndexDataManager::~IndexDataManager() {}
+
+void IndexDataManager::deinitialize()
+{
+ mStreamingBufferShort.reset();
+ mStreamingBufferInt.reset();
+}
+
+// This function translates a GL-style indices into DX-style indices, with their description
+// returned in translated.
+// GL can specify vertex data in immediate mode (pointer to CPU array of indices), which is not
+// possible in DX and requires streaming (Case 1). If the GL indices are specified with a buffer
+// (Case 2), in a format supported by DX (subcase a) then all is good.
+// When we have a buffer with an unsupported format (subcase b) then we need to do some translation:
+// we will start by falling back to streaming, and after a while will start using a static
+// translated copy of the index buffer.
+angle::Result IndexDataManager::prepareIndexData(const gl::Context *context,
+ gl::DrawElementsType srcType,
+ gl::DrawElementsType dstType,
+ GLsizei count,
+ gl::Buffer *glBuffer,
+ const void *indices,
+ TranslatedIndexData *translated)
+{
+ GLuint srcTypeBytes = gl::GetDrawElementsTypeSize(srcType);
+ GLuint srcTypeShift = gl::GetDrawElementsTypeShift(srcType);
+ GLuint dstTypeShift = gl::GetDrawElementsTypeShift(dstType);
+
+ BufferD3D *buffer = glBuffer ? GetImplAs<BufferD3D>(glBuffer) : nullptr;
+
+ translated->indexType = dstType;
+ translated->srcIndexData.srcBuffer = buffer;
+ translated->srcIndexData.srcIndices = indices;
+ translated->srcIndexData.srcIndexType = srcType;
+ translated->srcIndexData.srcCount = count;
+
+ // Context can be nullptr in perf tests.
+ bool primitiveRestartFixedIndexEnabled =
+ context ? context->getState().isPrimitiveRestartEnabled() : false;
+
+ // Case 1: the indices are passed by pointer, which forces the streaming of index data
+ if (glBuffer == nullptr)
+ {
+ translated->storage = nullptr;
+ return streamIndexData(context, indices, count, srcType, dstType,
+ primitiveRestartFixedIndexEnabled, translated);
+ }
+
+ // Case 2: the indices are already in a buffer
+ unsigned int offset = static_cast<unsigned int>(reinterpret_cast<uintptr_t>(indices));
+ ASSERT(srcTypeBytes * static_cast<unsigned int>(count) + offset <= buffer->getSize());
+
+ bool offsetAligned = IsOffsetAligned(srcType, offset);
+
+ // Case 2a: the buffer can be used directly
+ if (offsetAligned && buffer->supportsDirectBinding() && dstType == srcType)
+ {
+ translated->storage = buffer;
+ translated->indexBuffer = nullptr;
+ translated->serial = buffer->getSerial();
+ translated->startIndex = (offset >> srcTypeShift);
+ translated->startOffset = offset;
+ return angle::Result::Continue;
+ }
+
+ translated->storage = nullptr;
+
+ // Case 2b: use a static translated copy or fall back to streaming
+ StaticIndexBufferInterface *staticBuffer = buffer->getStaticIndexBuffer();
+
+ bool staticBufferInitialized = staticBuffer && staticBuffer->getBufferSize() != 0;
+ bool staticBufferUsable =
+ staticBuffer && offsetAligned && staticBuffer->getIndexType() == dstType;
+
+ if (staticBufferInitialized && !staticBufferUsable)
+ {
+ buffer->invalidateStaticData(context);
+ staticBuffer = nullptr;
+ }
+
+ if (staticBuffer == nullptr || !offsetAligned)
+ {
+ const uint8_t *bufferData = nullptr;
+ ANGLE_TRY(buffer->getData(context, &bufferData));
+ ASSERT(bufferData != nullptr);
+
+ ANGLE_TRY(streamIndexData(context, bufferData + offset, count, srcType, dstType,
+ primitiveRestartFixedIndexEnabled, translated));
+ buffer->promoteStaticUsage(context, count << srcTypeShift);
+ }
+ else
+ {
+ if (!staticBufferInitialized)
+ {
+ const uint8_t *bufferData = nullptr;
+ ANGLE_TRY(buffer->getData(context, &bufferData));
+ ASSERT(bufferData != nullptr);
+
+ unsigned int convertCount =
+ static_cast<unsigned int>(buffer->getSize()) >> srcTypeShift;
+ ANGLE_TRY(StreamInIndexBuffer(context, staticBuffer, bufferData, convertCount, srcType,
+ dstType, primitiveRestartFixedIndexEnabled, nullptr));
+ }
+ ASSERT(offsetAligned && staticBuffer->getIndexType() == dstType);
+
+ translated->indexBuffer = staticBuffer->getIndexBuffer();
+ translated->serial = staticBuffer->getSerial();
+ translated->startIndex = (offset >> srcTypeShift);
+ translated->startOffset = (offset >> srcTypeShift) << dstTypeShift;
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result IndexDataManager::streamIndexData(const gl::Context *context,
+ const void *data,
+ unsigned int count,
+ gl::DrawElementsType srcType,
+ gl::DrawElementsType dstType,
+ bool usePrimitiveRestartFixedIndex,
+ TranslatedIndexData *translated)
+{
+ const GLuint dstTypeShift = gl::GetDrawElementsTypeShift(dstType);
+
+ IndexBufferInterface *indexBuffer = nullptr;
+ ANGLE_TRY(getStreamingIndexBuffer(context, dstType, &indexBuffer));
+ ASSERT(indexBuffer != nullptr);
+
+ unsigned int offset;
+ ANGLE_TRY(StreamInIndexBuffer(context, indexBuffer, data, count, srcType, dstType,
+ usePrimitiveRestartFixedIndex, &offset));
+
+ translated->indexBuffer = indexBuffer->getIndexBuffer();
+ translated->serial = indexBuffer->getSerial();
+ translated->startIndex = (offset >> dstTypeShift);
+ translated->startOffset = offset;
+
+ return angle::Result::Continue;
+}
+
+angle::Result IndexDataManager::getStreamingIndexBuffer(const gl::Context *context,
+ gl::DrawElementsType destinationIndexType,
+ IndexBufferInterface **outBuffer)
+{
+ ASSERT(outBuffer);
+ ASSERT(destinationIndexType == gl::DrawElementsType::UnsignedShort ||
+ destinationIndexType == gl::DrawElementsType::UnsignedInt);
+
+ auto &streamingBuffer = (destinationIndexType == gl::DrawElementsType::UnsignedInt)
+ ? mStreamingBufferInt
+ : mStreamingBufferShort;
+
+ if (!streamingBuffer)
+ {
+ StreamingBuffer newBuffer(new StreamingIndexBufferInterface(mFactory));
+ ANGLE_TRY(newBuffer->reserveBufferSpace(context, INITIAL_INDEX_BUFFER_SIZE,
+ destinationIndexType));
+ streamingBuffer = std::move(newBuffer);
+ }
+
+ *outBuffer = streamingBuffer.get();
+ return angle::Result::Continue;
+}
+
+angle::Result GetIndexTranslationDestType(const gl::Context *context,
+ GLsizei indexCount,
+ gl::DrawElementsType indexType,
+ const void *indices,
+ bool usePrimitiveRestartWorkaround,
+ gl::DrawElementsType *destTypeOut)
+{
+ // Avoid D3D11's primitive restart index value
+ // see http://msdn.microsoft.com/en-us/library/windows/desktop/bb205124(v=vs.85).aspx
+ if (usePrimitiveRestartWorkaround)
+ {
+ // Conservatively assume we need to translate the indices for draw indirect.
+ // This is a bit of a trick. We assume the count for an indirect draw is zero.
+ if (indexCount == 0)
+ {
+ *destTypeOut = gl::DrawElementsType::UnsignedInt;
+ return angle::Result::Continue;
+ }
+
+ gl::IndexRange indexRange;
+ ANGLE_TRY(context->getState().getVertexArray()->getIndexRange(
+ context, indexType, indexCount, indices, &indexRange));
+ if (indexRange.end == gl::GetPrimitiveRestartIndex(indexType))
+ {
+ *destTypeOut = gl::DrawElementsType::UnsignedInt;
+ return angle::Result::Continue;
+ }
+ }
+
+ *destTypeOut = (indexType == gl::DrawElementsType::UnsignedInt)
+ ? gl::DrawElementsType::UnsignedInt
+ : gl::DrawElementsType::UnsignedShort;
+ return angle::Result::Continue;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/IndexDataManager.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/IndexDataManager.h
new file mode 100644
index 0000000000..53bfc721da
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/IndexDataManager.h
@@ -0,0 +1,112 @@
+//
+// Copyright 2002 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.
+//
+
+// IndexDataManager.h: Defines the IndexDataManager, a class that
+// runs the Buffer translation process for index buffers.
+
+#ifndef LIBANGLE_INDEXDATAMANAGER_H_
+#define LIBANGLE_INDEXDATAMANAGER_H_
+
+#include <GLES2/gl2.h>
+
+#include "common/angleutils.h"
+#include "common/mathutil.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
+
+namespace
+{
+enum
+{
+ INITIAL_INDEX_BUFFER_SIZE = 4096 * sizeof(GLuint)
+};
+}
+
+namespace gl
+{
+class Buffer;
+}
+
+namespace rx
+{
+class IndexBufferInterface;
+class StaticIndexBufferInterface;
+class StreamingIndexBufferInterface;
+class IndexBuffer;
+class BufferD3D;
+class RendererD3D;
+
+struct SourceIndexData
+{
+ BufferD3D *srcBuffer;
+ const void *srcIndices;
+ unsigned int srcCount;
+ gl::DrawElementsType srcIndexType;
+ bool srcIndicesChanged;
+};
+
+struct TranslatedIndexData
+{
+ unsigned int startIndex;
+ unsigned int startOffset; // In bytes
+
+ IndexBuffer *indexBuffer;
+ BufferD3D *storage;
+ gl::DrawElementsType indexType;
+ unsigned int serial;
+
+ SourceIndexData srcIndexData;
+};
+
+class IndexDataManager : angle::NonCopyable
+{
+ public:
+ explicit IndexDataManager(BufferFactoryD3D *factory);
+ virtual ~IndexDataManager();
+
+ void deinitialize();
+
+ angle::Result prepareIndexData(const gl::Context *context,
+ gl::DrawElementsType srcType,
+ gl::DrawElementsType dstType,
+ GLsizei count,
+ gl::Buffer *glBuffer,
+ const void *indices,
+ TranslatedIndexData *translated);
+
+ private:
+ angle::Result streamIndexData(const gl::Context *context,
+ const void *data,
+ unsigned int count,
+ gl::DrawElementsType srcType,
+ gl::DrawElementsType dstType,
+ bool usePrimitiveRestartFixedIndex,
+ TranslatedIndexData *translated);
+ angle::Result getStreamingIndexBuffer(const gl::Context *context,
+ gl::DrawElementsType destinationIndexType,
+ IndexBufferInterface **outBuffer);
+
+ using StreamingBuffer = std::unique_ptr<StreamingIndexBufferInterface>;
+
+ BufferFactoryD3D *const mFactory;
+ std::unique_ptr<StreamingIndexBufferInterface> mStreamingBufferShort;
+ std::unique_ptr<StreamingIndexBufferInterface> mStreamingBufferInt;
+};
+
+angle::Result GetIndexTranslationDestType(const gl::Context *context,
+ GLsizei indexCount,
+ gl::DrawElementsType indexType,
+ const void *indices,
+ bool usePrimitiveRestartWorkaround,
+ gl::DrawElementsType *destTypeOut);
+
+ANGLE_INLINE bool IsOffsetAligned(gl::DrawElementsType elementType, unsigned int offset)
+{
+ return (offset % gl::GetDrawElementsTypeSize(elementType) == 0);
+}
+} // namespace rx
+
+#endif // LIBANGLE_INDEXDATAMANAGER_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/NativeWindowD3D.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/NativeWindowD3D.cpp
new file mode 100644
index 0000000000..a8543a06d7
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/NativeWindowD3D.cpp
@@ -0,0 +1,19 @@
+//
+// 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.
+//
+
+// NativeWindowD3D.cpp: Defines NativeWindowD3D, a class for managing and performing operations on
+// an EGLNativeWindowType for the D3D renderers.
+
+#include "libANGLE/renderer/d3d/NativeWindowD3D.h"
+
+namespace rx
+{
+
+NativeWindowD3D::NativeWindowD3D(EGLNativeWindowType window) : mWindow(window) {}
+
+NativeWindowD3D::~NativeWindowD3D() {}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/NativeWindowD3D.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/NativeWindowD3D.h
new file mode 100644
index 0000000000..8560f16bde
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/NativeWindowD3D.h
@@ -0,0 +1,38 @@
+//
+// 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.
+//
+
+// NativeWindowD3D.h: Defines NativeWindowD3D, a class for managing and performing operations on an
+// EGLNativeWindowType for the D3D renderers.
+
+#ifndef LIBANGLE_RENDERER_D3D_NATIVEWINDOWD3D_H_
+#define LIBANGLE_RENDERER_D3D_NATIVEWINDOWD3D_H_
+
+#include "common/debug.h"
+#include "common/platform.h"
+
+#include <EGL/eglplatform.h>
+#include "libANGLE/Config.h"
+
+namespace rx
+{
+class NativeWindowD3D : angle::NonCopyable
+{
+ public:
+ NativeWindowD3D(EGLNativeWindowType window);
+ virtual ~NativeWindowD3D();
+
+ virtual bool initialize() = 0;
+ virtual bool getClientRect(LPRECT rect) const = 0;
+ virtual bool isIconic() const = 0;
+
+ inline EGLNativeWindowType getNativeWindow() const { return mWindow; }
+
+ private:
+ EGLNativeWindowType mWindow;
+};
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_NATIVEWINDOWD3D_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/ProgramD3D.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/ProgramD3D.cpp
new file mode 100644
index 0000000000..b38ede4133
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/ProgramD3D.cpp
@@ -0,0 +1,3412 @@
+//
+// 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.
+//
+
+// ProgramD3D.cpp: Defines the rx::ProgramD3D class which implements rx::ProgramImpl.
+
+#include "libANGLE/renderer/d3d/ProgramD3D.h"
+
+#include "common/MemoryBuffer.h"
+#include "common/bitset_utils.h"
+#include "common/string_utils.h"
+#include "common/utilities.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/Program.h"
+#include "libANGLE/ProgramLinkedResources.h"
+#include "libANGLE/Uniform.h"
+#include "libANGLE/VertexArray.h"
+#include "libANGLE/features.h"
+#include "libANGLE/queryconversions.h"
+#include "libANGLE/renderer/ContextImpl.h"
+#include "libANGLE/renderer/d3d/ContextD3D.h"
+#include "libANGLE/renderer/d3d/DynamicHLSL.h"
+#include "libANGLE/renderer/d3d/FramebufferD3D.h"
+#include "libANGLE/renderer/d3d/ShaderD3D.h"
+#include "libANGLE/renderer/d3d/ShaderExecutableD3D.h"
+#include "libANGLE/renderer/d3d/VertexDataManager.h"
+#include "libANGLE/renderer/renderer_utils.h"
+#include "libANGLE/trace.h"
+
+using namespace angle;
+
+namespace rx
+{
+
+namespace
+{
+
+void GetDefaultInputLayoutFromShader(const gl::Context *context,
+ gl::Shader *vertexShader,
+ gl::InputLayout *inputLayoutOut)
+{
+ inputLayoutOut->clear();
+
+ if (!vertexShader)
+ {
+ return;
+ }
+
+ for (const sh::ShaderVariable &shaderAttr : vertexShader->getActiveAttributes(context))
+ {
+ if (shaderAttr.type != GL_NONE)
+ {
+ GLenum transposedType = gl::TransposeMatrixType(shaderAttr.type);
+
+ for (size_t rowIndex = 0;
+ static_cast<int>(rowIndex) < gl::VariableRowCount(transposedType); ++rowIndex)
+ {
+ GLenum componentType = gl::VariableComponentType(transposedType);
+ GLuint components = static_cast<GLuint>(gl::VariableColumnCount(transposedType));
+ bool pureInt = (componentType != GL_FLOAT);
+
+ gl::VertexAttribType attribType =
+ gl::FromGLenum<gl::VertexAttribType>(componentType);
+
+ angle::FormatID defaultID =
+ gl::GetVertexFormatID(attribType, GL_FALSE, components, pureInt);
+
+ inputLayoutOut->push_back(defaultID);
+ }
+ }
+ }
+}
+
+size_t GetMaxOutputIndex(const std::vector<PixelShaderOutputVariable> &shaderOutputVars,
+ size_t location)
+{
+ size_t maxIndex = 0;
+ for (auto &outputVar : shaderOutputVars)
+ {
+ if (outputVar.outputLocation == location)
+ {
+ maxIndex = std::max(maxIndex, outputVar.outputIndex);
+ }
+ }
+ return maxIndex;
+}
+
+void GetDefaultOutputLayoutFromShader(
+ const std::vector<PixelShaderOutputVariable> &shaderOutputVars,
+ std::vector<GLenum> *outputLayoutOut)
+{
+ outputLayoutOut->clear();
+
+ if (!shaderOutputVars.empty())
+ {
+ size_t location = shaderOutputVars[0].outputLocation;
+ size_t maxIndex = GetMaxOutputIndex(shaderOutputVars, location);
+ outputLayoutOut->assign(maxIndex + 1,
+ GL_COLOR_ATTACHMENT0 + static_cast<unsigned int>(location));
+ }
+}
+
+void GetDefaultImage2DBindLayoutFromShader(const std::vector<sh::ShaderVariable> &image2DUniforms,
+ gl::ImageUnitTextureTypeMap *image2DBindLayout)
+{
+ image2DBindLayout->clear();
+
+ for (const sh::ShaderVariable &image2D : image2DUniforms)
+ {
+ if (gl::IsImage2DType(image2D.type))
+ {
+ if (image2D.binding == -1)
+ {
+ image2DBindLayout->insert(std::make_pair(0, gl::TextureType::_2D));
+ }
+ else
+ {
+ for (unsigned int index = 0; index < image2D.getArraySizeProduct(); index++)
+ {
+ image2DBindLayout->insert(
+ std::make_pair(image2D.binding + index, gl::TextureType::_2D));
+ }
+ }
+ }
+ }
+}
+
+gl::PrimitiveMode GetGeometryShaderTypeFromDrawMode(gl::PrimitiveMode drawMode)
+{
+ switch (drawMode)
+ {
+ // Uses the point sprite geometry shader.
+ case gl::PrimitiveMode::Points:
+ return gl::PrimitiveMode::Points;
+
+ // All line drawing uses the same geometry shader.
+ case gl::PrimitiveMode::Lines:
+ case gl::PrimitiveMode::LineStrip:
+ case gl::PrimitiveMode::LineLoop:
+ return gl::PrimitiveMode::Lines;
+
+ // The triangle fan primitive is emulated with strips in D3D11.
+ case gl::PrimitiveMode::Triangles:
+ case gl::PrimitiveMode::TriangleFan:
+ return gl::PrimitiveMode::Triangles;
+
+ // Special case for triangle strips.
+ case gl::PrimitiveMode::TriangleStrip:
+ return gl::PrimitiveMode::TriangleStrip;
+
+ default:
+ UNREACHABLE();
+ return gl::PrimitiveMode::InvalidEnum;
+ }
+}
+
+bool HasFlatInterpolationVarying(const std::vector<sh::ShaderVariable> &varyings)
+{
+ // Note: this assumes nested structs can only be packed with one interpolation.
+ for (const auto &varying : varyings)
+ {
+ if (varying.interpolation == sh::INTERPOLATION_FLAT)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool FindFlatInterpolationVaryingPerShader(const gl::Context *context, gl::Shader *shader)
+{
+ ASSERT(shader);
+ switch (shader->getType())
+ {
+ case gl::ShaderType::Vertex:
+ return HasFlatInterpolationVarying(shader->getOutputVaryings(context));
+ case gl::ShaderType::Fragment:
+ return HasFlatInterpolationVarying(shader->getInputVaryings(context));
+ case gl::ShaderType::Geometry:
+ return HasFlatInterpolationVarying(shader->getInputVaryings(context)) ||
+ HasFlatInterpolationVarying(shader->getOutputVaryings(context));
+ default:
+ UNREACHABLE();
+ return false;
+ }
+}
+
+bool FindFlatInterpolationVarying(const gl::Context *context,
+ const gl::ShaderMap<gl::Shader *> &shaders)
+{
+ for (gl::ShaderType shaderType : gl::kAllGraphicsShaderTypes)
+ {
+ gl::Shader *shader = shaders[shaderType];
+ if (!shader)
+ {
+ continue;
+ }
+
+ if (FindFlatInterpolationVaryingPerShader(context, shader))
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+// Helper class that gathers uniform info from the default uniform block.
+class UniformEncodingVisitorD3D : public sh::BlockEncoderVisitor
+{
+ public:
+ UniformEncodingVisitorD3D(gl::ShaderType shaderType,
+ HLSLRegisterType registerType,
+ sh::BlockLayoutEncoder *encoder,
+ D3DUniformMap *uniformMapOut)
+ : sh::BlockEncoderVisitor("", "", encoder),
+ mShaderType(shaderType),
+ mRegisterType(registerType),
+ mUniformMapOut(uniformMapOut)
+ {}
+
+ void visitNamedOpaqueObject(const sh::ShaderVariable &sampler,
+ const std::string &name,
+ const std::string &mappedName,
+ const std::vector<unsigned int> &arraySizes) override
+ {
+ auto uniformMapEntry = mUniformMapOut->find(name);
+ if (uniformMapEntry == mUniformMapOut->end())
+ {
+ (*mUniformMapOut)[name] =
+ new D3DUniform(sampler.type, mRegisterType, name, sampler.arraySizes, true);
+ }
+ }
+
+ void encodeVariable(const sh::ShaderVariable &variable,
+ const sh::BlockMemberInfo &variableInfo,
+ const std::string &name,
+ const std::string &mappedName) override
+ {
+ auto uniformMapEntry = mUniformMapOut->find(name);
+ D3DUniform *d3dUniform = nullptr;
+
+ if (uniformMapEntry != mUniformMapOut->end())
+ {
+ d3dUniform = uniformMapEntry->second;
+ }
+ else
+ {
+ d3dUniform =
+ new D3DUniform(variable.type, mRegisterType, name, variable.arraySizes, true);
+ (*mUniformMapOut)[name] = d3dUniform;
+ }
+
+ d3dUniform->registerElement = static_cast<unsigned int>(
+ sh::BlockLayoutEncoder::GetBlockRegisterElement(variableInfo));
+ unsigned int reg =
+ static_cast<unsigned int>(sh::BlockLayoutEncoder::GetBlockRegister(variableInfo));
+
+ ASSERT(mShaderType != gl::ShaderType::InvalidEnum);
+ d3dUniform->mShaderRegisterIndexes[mShaderType] = reg;
+ }
+
+ private:
+ gl::ShaderType mShaderType;
+ HLSLRegisterType mRegisterType;
+ D3DUniformMap *mUniformMapOut;
+};
+
+class HLSLBlockLayoutEncoderFactory : public gl::CustomBlockLayoutEncoderFactory
+{
+ public:
+ sh::BlockLayoutEncoder *makeEncoder() override
+ {
+ return new sh::HLSLBlockEncoder(sh::HLSLBlockEncoder::ENCODE_PACKED, false);
+ }
+};
+} // anonymous namespace
+
+// D3DUniform Implementation
+
+D3DUniform::D3DUniform(GLenum type,
+ HLSLRegisterType reg,
+ const std::string &nameIn,
+ const std::vector<unsigned int> &arraySizesIn,
+ bool defaultBlock)
+ : typeInfo(gl::GetUniformTypeInfo(type)),
+ name(nameIn),
+ arraySizes(arraySizesIn),
+ mShaderData({}),
+ regType(reg),
+ registerCount(0),
+ registerElement(0)
+{
+ mShaderRegisterIndexes.fill(GL_INVALID_INDEX);
+
+ // We use data storage for default block uniforms to cache values that are sent to D3D during
+ // rendering
+ // Uniform blocks/buffers are treated separately by the Renderer (ES3 path only)
+ if (defaultBlock)
+ {
+ // Use the row count as register count, will work for non-square matrices.
+ registerCount = typeInfo.rowCount * getArraySizeProduct();
+ }
+}
+
+D3DUniform::~D3DUniform() {}
+
+unsigned int D3DUniform::getArraySizeProduct() const
+{
+ return gl::ArraySizeProduct(arraySizes);
+}
+
+const uint8_t *D3DUniform::getDataPtrToElement(size_t elementIndex) const
+{
+ ASSERT((!isArray() && elementIndex == 0) ||
+ (isArray() && elementIndex < getArraySizeProduct()));
+
+ if (isSampler())
+ {
+ return reinterpret_cast<const uint8_t *>(&mSamplerData[elementIndex]);
+ }
+
+ return firstNonNullData() + (elementIndex > 0 ? (typeInfo.internalSize * elementIndex) : 0u);
+}
+
+bool D3DUniform::isSampler() const
+{
+ return typeInfo.isSampler;
+}
+
+bool D3DUniform::isImage() const
+{
+ return typeInfo.isImageType;
+}
+
+bool D3DUniform::isImage2D() const
+{
+ return gl::IsImage2DType(typeInfo.type);
+}
+
+bool D3DUniform::isReferencedByShader(gl::ShaderType shaderType) const
+{
+ return mShaderRegisterIndexes[shaderType] != GL_INVALID_INDEX;
+}
+
+const uint8_t *D3DUniform::firstNonNullData() const
+{
+ if (!mSamplerData.empty())
+ {
+ return reinterpret_cast<const uint8_t *>(mSamplerData.data());
+ }
+
+ for (gl::ShaderType shaderType : gl::AllShaderTypes())
+ {
+ if (mShaderData[shaderType])
+ {
+ return mShaderData[shaderType];
+ }
+ }
+
+ UNREACHABLE();
+ return nullptr;
+}
+
+// D3DInterfaceBlock Implementation
+D3DInterfaceBlock::D3DInterfaceBlock()
+{
+ mShaderRegisterIndexes.fill(GL_INVALID_INDEX);
+}
+
+D3DInterfaceBlock::D3DInterfaceBlock(const D3DInterfaceBlock &other) = default;
+
+D3DUniformBlock::D3DUniformBlock()
+{
+ mUseStructuredBuffers.fill(false);
+ mByteWidths.fill(0u);
+ mStructureByteStrides.fill(0u);
+}
+
+D3DUniformBlock::D3DUniformBlock(const D3DUniformBlock &other) = default;
+
+// D3DVarying Implementation
+
+D3DVarying::D3DVarying() : semanticIndex(0), componentCount(0), outputSlot(0) {}
+
+D3DVarying::D3DVarying(const std::string &semanticNameIn,
+ unsigned int semanticIndexIn,
+ unsigned int componentCountIn,
+ unsigned int outputSlotIn)
+ : semanticName(semanticNameIn),
+ semanticIndex(semanticIndexIn),
+ componentCount(componentCountIn),
+ outputSlot(outputSlotIn)
+{}
+
+// ProgramD3DMetadata Implementation
+
+ProgramD3DMetadata::ProgramD3DMetadata(RendererD3D *renderer,
+ const gl::ShaderMap<const ShaderD3D *> &attachedShaders,
+ EGLenum clientType)
+ : mRendererMajorShaderModel(renderer->getMajorShaderModel()),
+ mShaderModelSuffix(renderer->getShaderModelSuffix()),
+ mUsesInstancedPointSpriteEmulation(
+ renderer->getFeatures().useInstancedPointSpriteEmulation.enabled),
+ mUsesViewScale(renderer->presentPathFastEnabled()),
+ mCanSelectViewInVertexShader(renderer->canSelectViewInVertexShader()),
+ mAttachedShaders(attachedShaders),
+ mClientType(clientType)
+{}
+
+ProgramD3DMetadata::~ProgramD3DMetadata() = default;
+
+int ProgramD3DMetadata::getRendererMajorShaderModel() const
+{
+ return mRendererMajorShaderModel;
+}
+
+bool ProgramD3DMetadata::usesBroadcast(const gl::State &data) const
+{
+ const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Fragment];
+ return (shader && shader->usesFragColor() && shader->usesMultipleRenderTargets() &&
+ data.getClientMajorVersion() < 3);
+}
+
+bool ProgramD3DMetadata::usesSecondaryColor() const
+{
+ const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Fragment];
+ return (shader && shader->usesSecondaryColor());
+}
+
+bool ProgramD3DMetadata::usesFragDepth() const
+{
+ const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Fragment];
+ return (shader && shader->usesFragDepth());
+}
+
+bool ProgramD3DMetadata::usesPointCoord() const
+{
+ const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Fragment];
+ return (shader && shader->usesPointCoord());
+}
+
+bool ProgramD3DMetadata::usesFragCoord() const
+{
+ const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Fragment];
+ return (shader && shader->usesFragCoord());
+}
+
+bool ProgramD3DMetadata::usesPointSize() const
+{
+ const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Vertex];
+ return (shader && shader->usesPointSize());
+}
+
+bool ProgramD3DMetadata::usesInsertedPointCoordValue() const
+{
+ return (!usesPointSize() || !mUsesInstancedPointSpriteEmulation) && usesPointCoord() &&
+ mRendererMajorShaderModel >= 4;
+}
+
+bool ProgramD3DMetadata::usesViewScale() const
+{
+ return mUsesViewScale;
+}
+
+bool ProgramD3DMetadata::hasANGLEMultiviewEnabled() const
+{
+ const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Vertex];
+ return (shader && shader->hasANGLEMultiviewEnabled());
+}
+
+bool ProgramD3DMetadata::usesVertexID() const
+{
+ const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Vertex];
+ return (shader && shader->usesVertexID());
+}
+
+bool ProgramD3DMetadata::usesViewID() const
+{
+ const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Fragment];
+ return (shader && shader->usesViewID());
+}
+
+bool ProgramD3DMetadata::canSelectViewInVertexShader() const
+{
+ return mCanSelectViewInVertexShader;
+}
+
+bool ProgramD3DMetadata::addsPointCoordToVertexShader() const
+{
+ // 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.
+ // 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 placeholder 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();
+}
+
+bool ProgramD3DMetadata::usesTransformFeedbackGLPosition() const
+{
+ // gl_Position only needs to be outputted from the vertex shader if transform feedback is
+ // active. This isn't supported on D3D11 Feature Level 9_3, so we don't output gl_Position from
+ // the vertex shader in this case. This saves us 1 output vector.
+ return !(mRendererMajorShaderModel >= 4 && mShaderModelSuffix != "");
+}
+
+bool ProgramD3DMetadata::usesSystemValuePointSize() const
+{
+ return !mUsesInstancedPointSpriteEmulation && usesPointSize();
+}
+
+bool ProgramD3DMetadata::usesMultipleFragmentOuts() const
+{
+ const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Fragment];
+ return (shader && shader->usesMultipleRenderTargets());
+}
+
+bool ProgramD3DMetadata::usesCustomOutVars() const
+{
+
+ const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Vertex];
+ int version = shader ? shader->getState().getShaderVersion() : -1;
+
+ switch (mClientType)
+ {
+ case EGL_OPENGL_API:
+ return version >= 130;
+ default:
+ return version >= 300;
+ }
+}
+
+const ShaderD3D *ProgramD3DMetadata::getFragmentShader() const
+{
+ return mAttachedShaders[gl::ShaderType::Fragment];
+}
+
+// ProgramD3D::GetExecutableTask class
+class ProgramD3D::GetExecutableTask : public Closure, public d3d::Context
+{
+ public:
+ GetExecutableTask(const gl::Context *context, ProgramD3D *program)
+ : mProgram(program), mContext(context)
+ {}
+
+ virtual angle::Result run() = 0;
+
+ void operator()() override { mResult = run(); }
+
+ angle::Result getResult() const { return mResult; }
+ const gl::InfoLog &getInfoLog() const { return mInfoLog; }
+ ShaderExecutableD3D *getExecutable() { return mExecutable; }
+
+ void handleResult(HRESULT hr,
+ const char *message,
+ const char *file,
+ const char *function,
+ unsigned int line) override
+ {
+ mStoredHR = hr;
+ mStoredMessage = message;
+ mStoredFile = file;
+ mStoredFunction = function;
+ mStoredLine = line;
+ }
+
+ void popError(d3d::Context *context)
+ {
+ ASSERT(mStoredFile);
+ ASSERT(mStoredFunction);
+ context->handleResult(mStoredHR, mStoredMessage.c_str(), mStoredFile, mStoredFunction,
+ mStoredLine);
+ }
+
+ protected:
+ ProgramD3D *mProgram = nullptr;
+ angle::Result mResult = angle::Result::Continue;
+ gl::InfoLog mInfoLog;
+ ShaderExecutableD3D *mExecutable = nullptr;
+ HRESULT mStoredHR = S_OK;
+ std::string mStoredMessage;
+ const char *mStoredFile = nullptr;
+ const char *mStoredFunction = nullptr;
+ unsigned int mStoredLine = 0;
+ const gl::Context *mContext = nullptr;
+};
+
+// ProgramD3D Implementation
+
+ProgramD3D::VertexExecutable::VertexExecutable(const gl::InputLayout &inputLayout,
+ const Signature &signature,
+ ShaderExecutableD3D *shaderExecutable)
+ : mInputs(inputLayout), mSignature(signature), mShaderExecutable(shaderExecutable)
+{}
+
+ProgramD3D::VertexExecutable::~VertexExecutable()
+{
+ SafeDelete(mShaderExecutable);
+}
+
+// static
+ProgramD3D::VertexExecutable::HLSLAttribType ProgramD3D::VertexExecutable::GetAttribType(
+ GLenum type)
+{
+ switch (type)
+ {
+ case GL_INT:
+ return HLSLAttribType::SIGNED_INT;
+ case GL_UNSIGNED_INT:
+ return HLSLAttribType::UNSIGNED_INT;
+ case GL_SIGNED_NORMALIZED:
+ case GL_UNSIGNED_NORMALIZED:
+ case GL_FLOAT:
+ return HLSLAttribType::FLOAT;
+ default:
+ UNREACHABLE();
+ return HLSLAttribType::FLOAT;
+ }
+}
+
+// static
+void ProgramD3D::VertexExecutable::getSignature(RendererD3D *renderer,
+ const gl::InputLayout &inputLayout,
+ Signature *signatureOut)
+{
+ signatureOut->assign(inputLayout.size(), HLSLAttribType::FLOAT);
+
+ for (size_t index = 0; index < inputLayout.size(); ++index)
+ {
+ angle::FormatID vertexFormatID = inputLayout[index];
+ if (vertexFormatID == angle::FormatID::NONE)
+ continue;
+
+ VertexConversionType conversionType = renderer->getVertexConversionType(vertexFormatID);
+ if ((conversionType & VERTEX_CONVERT_GPU) == 0)
+ continue;
+
+ GLenum componentType = renderer->getVertexComponentType(vertexFormatID);
+ (*signatureOut)[index] = GetAttribType(componentType);
+ }
+}
+
+bool ProgramD3D::VertexExecutable::matchesSignature(const Signature &signature) const
+{
+ size_t limit = std::max(mSignature.size(), signature.size());
+ for (size_t index = 0; index < limit; ++index)
+ {
+ // treat undefined indexes as FLOAT
+ auto a = index < signature.size() ? signature[index] : HLSLAttribType::FLOAT;
+ auto b = index < mSignature.size() ? mSignature[index] : HLSLAttribType::FLOAT;
+ if (a != b)
+ return false;
+ }
+
+ return true;
+}
+
+ProgramD3D::PixelExecutable::PixelExecutable(const std::vector<GLenum> &outputSignature,
+ ShaderExecutableD3D *shaderExecutable)
+ : mOutputSignature(outputSignature), mShaderExecutable(shaderExecutable)
+{}
+
+ProgramD3D::PixelExecutable::~PixelExecutable()
+{
+ SafeDelete(mShaderExecutable);
+}
+
+ProgramD3D::ComputeExecutable::ComputeExecutable(
+ const gl::ImageUnitTextureTypeMap &signature,
+ std::unique_ptr<ShaderExecutableD3D> shaderExecutable)
+ : mSignature(signature), mShaderExecutable(std::move(shaderExecutable))
+{}
+
+ProgramD3D::ComputeExecutable::~ComputeExecutable() {}
+
+ProgramD3D::Sampler::Sampler()
+ : active(false), logicalTextureUnit(0), textureType(gl::TextureType::_2D)
+{}
+
+ProgramD3D::Image::Image() : active(false), logicalImageUnit(0) {}
+
+unsigned int ProgramD3D::mCurrentSerial = 1;
+
+ProgramD3D::ProgramD3D(const gl::ProgramState &state, RendererD3D *renderer)
+ : ProgramImpl(state),
+ mRenderer(renderer),
+ mDynamicHLSL(nullptr),
+ mUsesPointSize(false),
+ mUsesFlatInterpolation(false),
+ mUsedShaderSamplerRanges({}),
+ mDirtySamplerMapping(true),
+ mUsedImageRange({}),
+ mUsedReadonlyImageRange({}),
+ mUsedAtomicCounterRange({}),
+ mSerial(issueSerial())
+{
+ mDynamicHLSL = new DynamicHLSL(renderer);
+}
+
+ProgramD3D::~ProgramD3D()
+{
+ reset();
+ SafeDelete(mDynamicHLSL);
+}
+
+bool ProgramD3D::usesPointSpriteEmulation() const
+{
+ return mUsesPointSize && mRenderer->getMajorShaderModel() >= 4;
+}
+
+bool ProgramD3D::usesGeometryShaderForPointSpriteEmulation() const
+{
+ return usesPointSpriteEmulation() && !usesInstancedPointSpriteEmulation();
+}
+
+bool ProgramD3D::usesGetDimensionsIgnoresBaseLevel() const
+{
+ return mRenderer->getFeatures().getDimensionsIgnoresBaseLevel.enabled;
+}
+
+bool ProgramD3D::usesGeometryShader(const gl::State &state, const gl::PrimitiveMode drawMode) const
+{
+ if (mHasANGLEMultiviewEnabled && !mRenderer->canSelectViewInVertexShader())
+ {
+ return true;
+ }
+ if (drawMode != gl::PrimitiveMode::Points)
+ {
+ if (!mUsesFlatInterpolation)
+ {
+ return false;
+ }
+ return state.getProvokingVertex() == gl::ProvokingVertexConvention::LastVertexConvention;
+ }
+ return usesGeometryShaderForPointSpriteEmulation();
+}
+
+bool ProgramD3D::usesInstancedPointSpriteEmulation() const
+{
+ return mRenderer->getFeatures().useInstancedPointSpriteEmulation.enabled;
+}
+
+GLint ProgramD3D::getSamplerMapping(gl::ShaderType type,
+ unsigned int samplerIndex,
+ const gl::Caps &caps) const
+{
+ GLint logicalTextureUnit = -1;
+
+ ASSERT(type != gl::ShaderType::InvalidEnum);
+
+ ASSERT(samplerIndex < static_cast<unsigned int>(caps.maxShaderTextureImageUnits[type]));
+
+ const auto &samplers = mShaderSamplers[type];
+ if (samplerIndex < samplers.size() && samplers[samplerIndex].active)
+ {
+ logicalTextureUnit = samplers[samplerIndex].logicalTextureUnit;
+ }
+
+ if (logicalTextureUnit >= 0 && logicalTextureUnit < caps.maxCombinedTextureImageUnits)
+ {
+ return logicalTextureUnit;
+ }
+
+ return -1;
+}
+
+// Returns the texture type for a given Direct3D 9 sampler type and
+// index (0-15 for the pixel shader and 0-3 for the vertex shader).
+gl::TextureType ProgramD3D::getSamplerTextureType(gl::ShaderType type,
+ unsigned int samplerIndex) const
+{
+ ASSERT(type != gl::ShaderType::InvalidEnum);
+
+ const auto &samplers = mShaderSamplers[type];
+ ASSERT(samplerIndex < samplers.size());
+ ASSERT(samplers[samplerIndex].active);
+
+ return samplers[samplerIndex].textureType;
+}
+
+gl::RangeUI ProgramD3D::getUsedSamplerRange(gl::ShaderType type) const
+{
+ ASSERT(type != gl::ShaderType::InvalidEnum);
+ return mUsedShaderSamplerRanges[type];
+}
+
+ProgramD3D::SamplerMapping ProgramD3D::updateSamplerMapping()
+{
+ if (!mDirtySamplerMapping)
+ {
+ return SamplerMapping::WasClean;
+ }
+
+ mDirtySamplerMapping = false;
+
+ // Retrieve sampler uniform values
+ for (const D3DUniform *d3dUniform : mD3DUniforms)
+ {
+ if (!d3dUniform->isSampler())
+ continue;
+
+ int count = d3dUniform->getArraySizeProduct();
+
+ for (gl::ShaderType shaderType : gl::AllShaderTypes())
+ {
+ if (!d3dUniform->isReferencedByShader(shaderType))
+ {
+ continue;
+ }
+
+ unsigned int firstIndex = d3dUniform->mShaderRegisterIndexes[shaderType];
+
+ std::vector<Sampler> &samplers = mShaderSamplers[shaderType];
+ for (int i = 0; i < count; i++)
+ {
+ unsigned int samplerIndex = firstIndex + i;
+
+ if (samplerIndex < samplers.size())
+ {
+ ASSERT(samplers[samplerIndex].active);
+ samplers[samplerIndex].logicalTextureUnit = d3dUniform->mSamplerData[i];
+ }
+ }
+ }
+ }
+
+ return SamplerMapping::WasDirty;
+}
+
+GLint ProgramD3D::getImageMapping(gl::ShaderType type,
+ unsigned int imageIndex,
+ bool readonly,
+ const gl::Caps &caps) const
+{
+ GLint logicalImageUnit = -1;
+ ASSERT(imageIndex < static_cast<unsigned int>(caps.maxImageUnits));
+ if (readonly && imageIndex < mReadonlyImages[type].size() &&
+ mReadonlyImages[type][imageIndex].active)
+ {
+ logicalImageUnit = mReadonlyImages[type][imageIndex].logicalImageUnit;
+ }
+ else if (imageIndex < mImages[type].size() && mImages[type][imageIndex].active)
+ {
+ logicalImageUnit = mImages[type][imageIndex].logicalImageUnit;
+ }
+
+ if (logicalImageUnit >= 0 && logicalImageUnit < caps.maxImageUnits)
+ {
+ return logicalImageUnit;
+ }
+
+ return -1;
+}
+
+gl::RangeUI ProgramD3D::getUsedImageRange(gl::ShaderType type, bool readonly) const
+{
+ return readonly ? mUsedReadonlyImageRange[type] : mUsedImageRange[type];
+}
+
+class ProgramD3D::LoadBinaryTask : public ProgramD3D::GetExecutableTask
+{
+ public:
+ LoadBinaryTask(const gl::Context *context,
+ ProgramD3D *program,
+ gl::BinaryInputStream *stream,
+ gl::InfoLog &infoLog)
+ : ProgramD3D::GetExecutableTask(context, program)
+ {
+ ASSERT(mProgram);
+ ASSERT(stream);
+
+ // Copy the remaining data from the stream locally so that the client can't modify it when
+ // loading off thread.
+ size_t dataSize = stream->remainingSize();
+ mDataCopySucceeded = mStreamData.resize(dataSize);
+ if (mDataCopySucceeded)
+ {
+ memcpy(mStreamData.data(), stream->data() + stream->offset(), dataSize);
+ }
+ }
+
+ angle::Result run() override
+ {
+ ANGLE_TRACE_EVENT0("gpu.angle", "ProgramD3D::LoadBinaryTask::run");
+ if (!mDataCopySucceeded)
+ {
+ mInfoLog << "Failed to copy program binary data to local buffer.";
+ return angle::Result::Incomplete;
+ }
+
+ gl::BinaryInputStream stream(mStreamData.data(), mStreamData.size());
+ return mProgram->loadBinaryShaderExecutables(this, &stream, mInfoLog);
+ }
+
+ private:
+ bool mDataCopySucceeded;
+ angle::MemoryBuffer mStreamData;
+};
+
+class ProgramD3D::LoadBinaryLinkEvent final : public LinkEvent
+{
+ public:
+ LoadBinaryLinkEvent(const gl::Context *context,
+ std::shared_ptr<WorkerThreadPool> workerPool,
+ ProgramD3D *program,
+ gl::BinaryInputStream *stream,
+ gl::InfoLog &infoLog)
+ : mTask(std::make_shared<ProgramD3D::LoadBinaryTask>(context, program, stream, infoLog)),
+ mWaitableEvent(angle::WorkerThreadPool::PostWorkerTask(workerPool, mTask))
+ {}
+
+ angle::Result wait(const gl::Context *context) override
+ {
+ mWaitableEvent->wait();
+
+ // Continue and Incomplete are not errors. For Stop, pass the error to the ContextD3D.
+ if (mTask->getResult() != angle::Result::Stop)
+ {
+ return angle::Result::Continue;
+ }
+
+ ContextD3D *contextD3D = GetImplAs<ContextD3D>(context);
+ mTask->popError(contextD3D);
+ return angle::Result::Stop;
+ }
+
+ bool isLinking() override { return !mWaitableEvent->isReady(); }
+
+ private:
+ std::shared_ptr<ProgramD3D::LoadBinaryTask> mTask;
+ std::shared_ptr<WaitableEvent> mWaitableEvent;
+};
+
+std::unique_ptr<rx::LinkEvent> ProgramD3D::load(const gl::Context *context,
+ gl::BinaryInputStream *stream,
+ gl::InfoLog &infoLog)
+{
+
+ // TODO(jmadill): Use Renderer from contextImpl.
+
+ reset();
+
+ DeviceIdentifier binaryDeviceIdentifier = {};
+ stream->readBytes(reinterpret_cast<unsigned char *>(&binaryDeviceIdentifier),
+ sizeof(DeviceIdentifier));
+
+ DeviceIdentifier identifier = mRenderer->getAdapterIdentifier();
+ if (memcmp(&identifier, &binaryDeviceIdentifier, sizeof(DeviceIdentifier)) != 0)
+ {
+ infoLog << "Invalid program binary, device configuration has changed.";
+ return nullptr;
+ }
+
+ int compileFlags = stream->readInt<int>();
+ if (compileFlags != ANGLE_COMPILE_OPTIMIZATION_LEVEL)
+ {
+ infoLog << "Mismatched compilation flags.";
+ return nullptr;
+ }
+
+ for (int &index : mAttribLocationToD3DSemantic)
+ {
+ stream->readInt(&index);
+ }
+
+ for (gl::ShaderType shaderType : gl::AllShaderTypes())
+ {
+ size_t samplerCount = stream->readInt<size_t>();
+ for (size_t sampleIndex = 0; sampleIndex < samplerCount; ++sampleIndex)
+ {
+ Sampler sampler;
+ stream->readBool(&sampler.active);
+ stream->readInt(&sampler.logicalTextureUnit);
+ stream->readEnum(&sampler.textureType);
+ mShaderSamplers[shaderType].push_back(sampler);
+ }
+
+ unsigned int samplerRangeLow, samplerRangeHigh;
+ stream->readInt(&samplerRangeLow);
+ stream->readInt(&samplerRangeHigh);
+ mUsedShaderSamplerRanges[shaderType] = gl::RangeUI(samplerRangeLow, samplerRangeHigh);
+ }
+
+ for (gl::ShaderType shaderType : {gl::ShaderType::Compute, gl::ShaderType::Fragment})
+ {
+ size_t imageCount = stream->readInt<size_t>();
+ for (size_t imageIndex = 0; imageIndex < imageCount; ++imageIndex)
+ {
+ Image image;
+ stream->readBool(&image.active);
+ stream->readInt(&image.logicalImageUnit);
+ mImages[shaderType].push_back(image);
+ }
+
+ size_t readonlyImageCount = stream->readInt<size_t>();
+ for (size_t imageIndex = 0; imageIndex < readonlyImageCount; ++imageIndex)
+ {
+ Image image;
+ stream->readBool(&image.active);
+ stream->readInt(&image.logicalImageUnit);
+ mReadonlyImages[shaderType].push_back(image);
+ }
+
+ unsigned int imageRangeLow, imageRangeHigh, readonlyImageRangeLow, readonlyImageRangeHigh;
+ stream->readInt(&imageRangeLow);
+ stream->readInt(&imageRangeHigh);
+ stream->readInt(&readonlyImageRangeLow);
+ stream->readInt(&readonlyImageRangeHigh);
+ mUsedImageRange[shaderType] = gl::RangeUI(imageRangeLow, imageRangeHigh);
+ mUsedReadonlyImageRange[shaderType] =
+ gl::RangeUI(readonlyImageRangeLow, readonlyImageRangeHigh);
+
+ unsigned int atomicCounterRangeLow, atomicCounterRangeHigh;
+ stream->readInt(&atomicCounterRangeLow);
+ stream->readInt(&atomicCounterRangeHigh);
+ mUsedAtomicCounterRange[shaderType] =
+ gl::RangeUI(atomicCounterRangeLow, atomicCounterRangeHigh);
+ }
+
+ size_t shaderStorageBlockCount = stream->readInt<size_t>();
+ if (stream->error())
+ {
+ infoLog << "Invalid program binary.";
+ return nullptr;
+ }
+
+ ASSERT(mD3DShaderStorageBlocks.empty());
+ for (size_t blockIndex = 0; blockIndex < shaderStorageBlockCount; ++blockIndex)
+ {
+ D3DInterfaceBlock shaderStorageBlock;
+ for (gl::ShaderType shaderType : gl::AllShaderTypes())
+ {
+ stream->readInt(&shaderStorageBlock.mShaderRegisterIndexes[shaderType]);
+ }
+ mD3DShaderStorageBlocks.push_back(shaderStorageBlock);
+ }
+
+ for (gl::ShaderType shaderType : {gl::ShaderType::Compute, gl::ShaderType::Fragment})
+ {
+ size_t image2DUniformCount = stream->readInt<size_t>();
+ if (stream->error())
+ {
+ infoLog << "Invalid program binary.";
+ return nullptr;
+ }
+
+ ASSERT(mImage2DUniforms[shaderType].empty());
+ for (size_t image2DUniformIndex = 0; image2DUniformIndex < image2DUniformCount;
+ ++image2DUniformIndex)
+ {
+ sh::ShaderVariable image2Duniform;
+ gl::LoadShaderVar(stream, &image2Duniform);
+ mImage2DUniforms[shaderType].push_back(image2Duniform);
+ }
+ }
+
+ for (unsigned int ii = 0; ii < gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS; ++ii)
+ {
+ unsigned int index = stream->readInt<unsigned int>();
+ mComputeAtomicCounterBufferRegisterIndices[ii] = index;
+ }
+
+ size_t uniformCount = stream->readInt<size_t>();
+ if (stream->error())
+ {
+ infoLog << "Invalid program binary.";
+ return nullptr;
+ }
+
+ const auto &linkedUniforms = mState.getUniforms();
+ ASSERT(mD3DUniforms.empty());
+ for (size_t uniformIndex = 0; uniformIndex < uniformCount; uniformIndex++)
+ {
+ const gl::LinkedUniform &linkedUniform = linkedUniforms[uniformIndex];
+
+ D3DUniform *d3dUniform =
+ new D3DUniform(linkedUniform.type, HLSLRegisterType::None, linkedUniform.name,
+ linkedUniform.arraySizes, linkedUniform.isInDefaultBlock());
+ stream->readEnum(&d3dUniform->regType);
+ for (gl::ShaderType shaderType : gl::AllShaderTypes())
+ {
+ stream->readInt(&d3dUniform->mShaderRegisterIndexes[shaderType]);
+ }
+ stream->readInt(&d3dUniform->registerCount);
+ stream->readInt(&d3dUniform->registerElement);
+
+ mD3DUniforms.push_back(d3dUniform);
+ }
+
+ size_t blockCount = stream->readInt<size_t>();
+ if (stream->error())
+ {
+ infoLog << "Invalid program binary.";
+ return nullptr;
+ }
+
+ ASSERT(mD3DUniformBlocks.empty());
+ for (size_t blockIndex = 0; blockIndex < blockCount; ++blockIndex)
+ {
+ D3DUniformBlock uniformBlock;
+ for (gl::ShaderType shaderType : gl::AllShaderTypes())
+ {
+ stream->readInt(&uniformBlock.mShaderRegisterIndexes[shaderType]);
+ stream->readBool(&uniformBlock.mUseStructuredBuffers[shaderType]);
+ stream->readInt(&uniformBlock.mByteWidths[shaderType]);
+ stream->readInt(&uniformBlock.mStructureByteStrides[shaderType]);
+ }
+ mD3DUniformBlocks.push_back(uniformBlock);
+ }
+
+ size_t streamOutVaryingCount = stream->readInt<size_t>();
+ mStreamOutVaryings.resize(streamOutVaryingCount);
+ for (size_t varyingIndex = 0; varyingIndex < streamOutVaryingCount; ++varyingIndex)
+ {
+ D3DVarying *varying = &mStreamOutVaryings[varyingIndex];
+
+ stream->readString(&varying->semanticName);
+ stream->readInt(&varying->semanticIndex);
+ stream->readInt(&varying->componentCount);
+ stream->readInt(&varying->outputSlot);
+ }
+
+ for (gl::ShaderType shaderType : gl::AllShaderTypes())
+ {
+ stream->readString(&mShaderHLSL[shaderType]);
+ stream->readBytes(reinterpret_cast<unsigned char *>(&mShaderWorkarounds[shaderType]),
+ sizeof(CompilerWorkaroundsD3D));
+ }
+
+ stream->readBool(&mUsesFragDepth);
+ stream->readBool(&mHasANGLEMultiviewEnabled);
+ stream->readBool(&mUsesVertexID);
+ stream->readBool(&mUsesViewID);
+ stream->readBool(&mUsesPointSize);
+ stream->readBool(&mUsesFlatInterpolation);
+
+ const size_t pixelShaderKeySize = stream->readInt<size_t>();
+ mPixelShaderKey.resize(pixelShaderKeySize);
+ for (size_t pixelShaderKeyIndex = 0; pixelShaderKeyIndex < pixelShaderKeySize;
+ pixelShaderKeyIndex++)
+ {
+ stream->readInt(&mPixelShaderKey[pixelShaderKeyIndex].type);
+ stream->readString(&mPixelShaderKey[pixelShaderKeyIndex].name);
+ stream->readString(&mPixelShaderKey[pixelShaderKeyIndex].source);
+ stream->readInt(&mPixelShaderKey[pixelShaderKeyIndex].outputLocation);
+ stream->readInt(&mPixelShaderKey[pixelShaderKeyIndex].outputIndex);
+ }
+
+ stream->readString(&mGeometryShaderPreamble);
+
+ return std::make_unique<LoadBinaryLinkEvent>(context, context->getWorkerThreadPool(), this,
+ stream, infoLog);
+}
+
+angle::Result ProgramD3D::loadBinaryShaderExecutables(d3d::Context *contextD3D,
+ gl::BinaryInputStream *stream,
+ gl::InfoLog &infoLog)
+{
+ const unsigned char *binary = reinterpret_cast<const unsigned char *>(stream->data());
+
+ bool separateAttribs = (mState.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS);
+
+ size_t vertexShaderCount = stream->readInt<size_t>();
+ for (size_t vertexShaderIndex = 0; vertexShaderIndex < vertexShaderCount; vertexShaderIndex++)
+ {
+ size_t inputLayoutSize = stream->readInt<size_t>();
+ gl::InputLayout inputLayout(inputLayoutSize, angle::FormatID::NONE);
+
+ for (size_t inputIndex = 0; inputIndex < inputLayoutSize; inputIndex++)
+ {
+ inputLayout[inputIndex] = stream->readEnum<angle::FormatID>();
+ }
+
+ size_t vertexShaderSize = stream->readInt<size_t>();
+ const unsigned char *vertexShaderFunction = binary + stream->offset();
+
+ ShaderExecutableD3D *shaderExecutable = nullptr;
+
+ ANGLE_TRY(mRenderer->loadExecutable(contextD3D, vertexShaderFunction, vertexShaderSize,
+ gl::ShaderType::Vertex, mStreamOutVaryings,
+ separateAttribs, &shaderExecutable));
+
+ if (!shaderExecutable)
+ {
+ infoLog << "Could not create vertex shader.";
+ return angle::Result::Incomplete;
+ }
+
+ // generated converted input layout
+ VertexExecutable::Signature signature;
+ VertexExecutable::getSignature(mRenderer, inputLayout, &signature);
+
+ // add new binary
+ mVertexExecutables.push_back(std::unique_ptr<VertexExecutable>(
+ new VertexExecutable(inputLayout, signature, shaderExecutable)));
+
+ stream->skip(vertexShaderSize);
+ }
+
+ size_t pixelShaderCount = stream->readInt<size_t>();
+ for (size_t pixelShaderIndex = 0; pixelShaderIndex < pixelShaderCount; pixelShaderIndex++)
+ {
+ size_t outputCount = stream->readInt<size_t>();
+ std::vector<GLenum> outputs(outputCount);
+ for (size_t outputIndex = 0; outputIndex < outputCount; outputIndex++)
+ {
+ stream->readInt(&outputs[outputIndex]);
+ }
+
+ size_t pixelShaderSize = stream->readInt<size_t>();
+ const unsigned char *pixelShaderFunction = binary + stream->offset();
+ ShaderExecutableD3D *shaderExecutable = nullptr;
+
+ ANGLE_TRY(mRenderer->loadExecutable(contextD3D, pixelShaderFunction, pixelShaderSize,
+ gl::ShaderType::Fragment, mStreamOutVaryings,
+ separateAttribs, &shaderExecutable));
+
+ if (!shaderExecutable)
+ {
+ infoLog << "Could not create pixel shader.";
+ return angle::Result::Incomplete;
+ }
+
+ // add new binary
+ mPixelExecutables.push_back(
+ std::unique_ptr<PixelExecutable>(new PixelExecutable(outputs, shaderExecutable)));
+
+ stream->skip(pixelShaderSize);
+ }
+
+ for (std::unique_ptr<ShaderExecutableD3D> &geometryExe : mGeometryExecutables)
+ {
+ size_t geometryShaderSize = stream->readInt<size_t>();
+ if (geometryShaderSize == 0)
+ {
+ continue;
+ }
+
+ const unsigned char *geometryShaderFunction = binary + stream->offset();
+
+ ShaderExecutableD3D *geometryExecutable = nullptr;
+ ANGLE_TRY(mRenderer->loadExecutable(contextD3D, geometryShaderFunction, geometryShaderSize,
+ gl::ShaderType::Geometry, mStreamOutVaryings,
+ separateAttribs, &geometryExecutable));
+
+ if (!geometryExecutable)
+ {
+ infoLog << "Could not create geometry shader.";
+ return angle::Result::Incomplete;
+ }
+
+ geometryExe.reset(geometryExecutable);
+
+ stream->skip(geometryShaderSize);
+ }
+
+ size_t computeShaderCount = stream->readInt<size_t>();
+ for (size_t computeShaderIndex = 0; computeShaderIndex < computeShaderCount;
+ computeShaderIndex++)
+ {
+ size_t signatureCount = stream->readInt<size_t>();
+ gl::ImageUnitTextureTypeMap signatures;
+ for (size_t signatureIndex = 0; signatureIndex < signatureCount; signatureIndex++)
+ {
+ unsigned int imageUint;
+ gl::TextureType textureType;
+ stream->readInt(&imageUint);
+ stream->readEnum(&textureType);
+ signatures.insert(std::pair<unsigned int, gl::TextureType>(imageUint, textureType));
+ }
+
+ size_t computeShaderSize = stream->readInt<size_t>();
+ const unsigned char *computeShaderFunction = binary + stream->offset();
+
+ ShaderExecutableD3D *computeExecutable = nullptr;
+ ANGLE_TRY(mRenderer->loadExecutable(contextD3D, computeShaderFunction, computeShaderSize,
+ gl::ShaderType::Compute, std::vector<D3DVarying>(),
+ false, &computeExecutable));
+
+ if (!computeExecutable)
+ {
+ infoLog << "Could not create compute shader.";
+ return angle::Result::Incomplete;
+ }
+
+ // add new binary
+ mComputeExecutables.push_back(std::unique_ptr<ComputeExecutable>(new ComputeExecutable(
+ signatures, std::unique_ptr<ShaderExecutableD3D>(computeExecutable))));
+
+ stream->skip(computeShaderSize);
+ }
+
+ size_t bindLayoutCount = stream->readInt<size_t>();
+ for (size_t bindLayoutIndex = 0; bindLayoutIndex < bindLayoutCount; bindLayoutIndex++)
+ {
+ mImage2DBindLayoutCache[gl::ShaderType::Compute].insert(
+ std::pair<unsigned int, gl::TextureType>(stream->readInt<unsigned int>(),
+ gl::TextureType::_2D));
+ }
+
+ initializeUniformStorage(mState.getExecutable().getLinkedShaderStages());
+
+ dirtyAllUniforms();
+
+ return angle::Result::Continue;
+}
+
+void ProgramD3D::save(const gl::Context *context, gl::BinaryOutputStream *stream)
+{
+ // Output the DeviceIdentifier before we output any shader code
+ // When we load the binary again later, we can validate the device identifier before trying to
+ // compile any HLSL
+ DeviceIdentifier binaryIdentifier = mRenderer->getAdapterIdentifier();
+ stream->writeBytes(reinterpret_cast<unsigned char *>(&binaryIdentifier),
+ sizeof(DeviceIdentifier));
+
+ stream->writeInt(ANGLE_COMPILE_OPTIMIZATION_LEVEL);
+
+ for (int d3dSemantic : mAttribLocationToD3DSemantic)
+ {
+ stream->writeInt(d3dSemantic);
+ }
+
+ for (gl::ShaderType shaderType : gl::AllShaderTypes())
+ {
+ stream->writeInt(mShaderSamplers[shaderType].size());
+ for (unsigned int i = 0; i < mShaderSamplers[shaderType].size(); ++i)
+ {
+ stream->writeBool(mShaderSamplers[shaderType][i].active);
+ stream->writeInt(mShaderSamplers[shaderType][i].logicalTextureUnit);
+ stream->writeEnum(mShaderSamplers[shaderType][i].textureType);
+ }
+
+ stream->writeInt(mUsedShaderSamplerRanges[shaderType].low());
+ stream->writeInt(mUsedShaderSamplerRanges[shaderType].high());
+ }
+
+ for (gl::ShaderType shaderType : {gl::ShaderType::Compute, gl::ShaderType::Fragment})
+ {
+ stream->writeInt(mImages[shaderType].size());
+ for (size_t imageIndex = 0; imageIndex < mImages[shaderType].size(); ++imageIndex)
+ {
+ stream->writeBool(mImages[shaderType][imageIndex].active);
+ stream->writeInt(mImages[shaderType][imageIndex].logicalImageUnit);
+ }
+
+ stream->writeInt(mReadonlyImages[shaderType].size());
+ for (size_t imageIndex = 0; imageIndex < mReadonlyImages[shaderType].size(); ++imageIndex)
+ {
+ stream->writeBool(mReadonlyImages[shaderType][imageIndex].active);
+ stream->writeInt(mReadonlyImages[shaderType][imageIndex].logicalImageUnit);
+ }
+
+ stream->writeInt(mUsedImageRange[shaderType].low());
+ stream->writeInt(mUsedImageRange[shaderType].high());
+ stream->writeInt(mUsedReadonlyImageRange[shaderType].low());
+ stream->writeInt(mUsedReadonlyImageRange[shaderType].high());
+ stream->writeInt(mUsedAtomicCounterRange[shaderType].low());
+ stream->writeInt(mUsedAtomicCounterRange[shaderType].high());
+ }
+
+ stream->writeInt(mD3DShaderStorageBlocks.size());
+ for (const D3DInterfaceBlock &shaderStorageBlock : mD3DShaderStorageBlocks)
+ {
+ for (gl::ShaderType shaderType : gl::AllShaderTypes())
+ {
+ stream->writeIntOrNegOne(shaderStorageBlock.mShaderRegisterIndexes[shaderType]);
+ }
+ }
+
+ for (gl::ShaderType shaderType : {gl::ShaderType::Compute, gl::ShaderType::Fragment})
+ {
+ stream->writeInt(mImage2DUniforms[shaderType].size());
+ for (const sh::ShaderVariable &image2DUniform : mImage2DUniforms[shaderType])
+ {
+ gl::WriteShaderVar(stream, image2DUniform);
+ }
+ }
+
+ for (unsigned int ii = 0; ii < gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS; ++ii)
+ {
+ stream->writeInt(mComputeAtomicCounterBufferRegisterIndices[ii]);
+ }
+
+ stream->writeInt(mD3DUniforms.size());
+ for (const D3DUniform *uniform : mD3DUniforms)
+ {
+ // Type, name and arraySize are redundant, so aren't stored in the binary.
+ stream->writeEnum(uniform->regType);
+ for (gl::ShaderType shaderType : gl::AllShaderTypes())
+ {
+ stream->writeIntOrNegOne(uniform->mShaderRegisterIndexes[shaderType]);
+ }
+ stream->writeInt(uniform->registerCount);
+ stream->writeInt(uniform->registerElement);
+ }
+
+ stream->writeInt(mD3DUniformBlocks.size());
+ for (const D3DUniformBlock &uniformBlock : mD3DUniformBlocks)
+ {
+ for (gl::ShaderType shaderType : gl::AllShaderTypes())
+ {
+ stream->writeIntOrNegOne(uniformBlock.mShaderRegisterIndexes[shaderType]);
+ stream->writeBool(uniformBlock.mUseStructuredBuffers[shaderType]);
+ stream->writeInt(uniformBlock.mByteWidths[shaderType]);
+ stream->writeInt(uniformBlock.mStructureByteStrides[shaderType]);
+ }
+ }
+
+ stream->writeInt(mStreamOutVaryings.size());
+ for (const D3DVarying &varying : mStreamOutVaryings)
+ {
+ stream->writeString(varying.semanticName);
+ stream->writeInt(varying.semanticIndex);
+ stream->writeInt(varying.componentCount);
+ stream->writeInt(varying.outputSlot);
+ }
+
+ for (gl::ShaderType shaderType : gl::AllShaderTypes())
+ {
+ stream->writeString(mShaderHLSL[shaderType]);
+ stream->writeBytes(reinterpret_cast<unsigned char *>(&mShaderWorkarounds[shaderType]),
+ sizeof(CompilerWorkaroundsD3D));
+ }
+
+ stream->writeBool(mUsesFragDepth);
+ stream->writeBool(mHasANGLEMultiviewEnabled);
+ stream->writeBool(mUsesVertexID);
+ stream->writeBool(mUsesViewID);
+ stream->writeBool(mUsesPointSize);
+ stream->writeBool(mUsesFlatInterpolation);
+
+ const std::vector<PixelShaderOutputVariable> &pixelShaderKey = mPixelShaderKey;
+ stream->writeInt(pixelShaderKey.size());
+ for (size_t pixelShaderKeyIndex = 0; pixelShaderKeyIndex < pixelShaderKey.size();
+ pixelShaderKeyIndex++)
+ {
+ const PixelShaderOutputVariable &variable = pixelShaderKey[pixelShaderKeyIndex];
+ stream->writeInt(variable.type);
+ stream->writeString(variable.name);
+ stream->writeString(variable.source);
+ stream->writeInt(variable.outputLocation);
+ stream->writeInt(variable.outputIndex);
+ }
+
+ stream->writeString(mGeometryShaderPreamble);
+
+ stream->writeInt(mVertexExecutables.size());
+ for (size_t vertexExecutableIndex = 0; vertexExecutableIndex < mVertexExecutables.size();
+ vertexExecutableIndex++)
+ {
+ VertexExecutable *vertexExecutable = mVertexExecutables[vertexExecutableIndex].get();
+
+ const gl::InputLayout &inputLayout = vertexExecutable->inputs();
+ stream->writeInt(inputLayout.size());
+
+ for (size_t inputIndex = 0; inputIndex < inputLayout.size(); inputIndex++)
+ {
+ stream->writeEnum(inputLayout[inputIndex]);
+ }
+
+ size_t vertexShaderSize = vertexExecutable->shaderExecutable()->getLength();
+ stream->writeInt(vertexShaderSize);
+
+ const uint8_t *vertexBlob = vertexExecutable->shaderExecutable()->getFunction();
+ stream->writeBytes(vertexBlob, vertexShaderSize);
+ }
+
+ stream->writeInt(mPixelExecutables.size());
+ for (size_t pixelExecutableIndex = 0; pixelExecutableIndex < mPixelExecutables.size();
+ pixelExecutableIndex++)
+ {
+ PixelExecutable *pixelExecutable = mPixelExecutables[pixelExecutableIndex].get();
+
+ const std::vector<GLenum> &outputs = pixelExecutable->outputSignature();
+ stream->writeInt(outputs.size());
+ for (size_t outputIndex = 0; outputIndex < outputs.size(); outputIndex++)
+ {
+ stream->writeInt(outputs[outputIndex]);
+ }
+
+ size_t pixelShaderSize = pixelExecutable->shaderExecutable()->getLength();
+ stream->writeInt(pixelShaderSize);
+
+ const uint8_t *pixelBlob = pixelExecutable->shaderExecutable()->getFunction();
+ stream->writeBytes(pixelBlob, pixelShaderSize);
+ }
+
+ for (auto const &geometryExecutable : mGeometryExecutables)
+ {
+ if (!geometryExecutable)
+ {
+ stream->writeInt<size_t>(0);
+ continue;
+ }
+
+ size_t geometryShaderSize = geometryExecutable->getLength();
+ stream->writeInt(geometryShaderSize);
+ stream->writeBytes(geometryExecutable->getFunction(), geometryShaderSize);
+ }
+
+ stream->writeInt(mComputeExecutables.size());
+ for (size_t computeExecutableIndex = 0; computeExecutableIndex < mComputeExecutables.size();
+ computeExecutableIndex++)
+ {
+ ComputeExecutable *computeExecutable = mComputeExecutables[computeExecutableIndex].get();
+
+ const gl::ImageUnitTextureTypeMap signatures = computeExecutable->signature();
+ stream->writeInt(signatures.size());
+ for (const auto &signature : signatures)
+ {
+ stream->writeInt(signature.first);
+ stream->writeEnum(signature.second);
+ }
+
+ size_t computeShaderSize = computeExecutable->shaderExecutable()->getLength();
+ stream->writeInt(computeShaderSize);
+
+ const uint8_t *computeBlob = computeExecutable->shaderExecutable()->getFunction();
+ stream->writeBytes(computeBlob, computeShaderSize);
+ }
+
+ for (gl::ShaderType shaderType : {gl::ShaderType::Compute})
+ {
+ stream->writeInt(mImage2DBindLayoutCache[shaderType].size());
+ for (auto &image2DBindLayout : mImage2DBindLayoutCache[shaderType])
+ {
+ stream->writeInt(image2DBindLayout.first);
+ }
+ }
+}
+
+void ProgramD3D::setBinaryRetrievableHint(bool /* retrievable */) {}
+
+void ProgramD3D::setSeparable(bool /* separable */) {}
+
+angle::Result ProgramD3D::getPixelExecutableForCachedOutputLayout(
+ d3d::Context *context,
+ ShaderExecutableD3D **outExecutable,
+ gl::InfoLog *infoLog)
+{
+ if (mCachedPixelExecutableIndex.valid())
+ {
+ *outExecutable = mPixelExecutables[mCachedPixelExecutableIndex.value()]->shaderExecutable();
+ return angle::Result::Continue;
+ }
+
+ std::string pixelHLSL = mDynamicHLSL->generatePixelShaderForOutputSignature(
+ mShaderHLSL[gl::ShaderType::Fragment], mPixelShaderKey, mUsesFragDepth,
+ mPixelShaderOutputLayoutCache, mShaderStorageBlocks[gl::ShaderType::Fragment],
+ mPixelShaderKey.size());
+
+ std::string finalPixelHLSL = mDynamicHLSL->generateShaderForImage2DBindSignature(
+ *this, mState, gl::ShaderType::Fragment, pixelHLSL,
+ mImage2DUniforms[gl::ShaderType::Fragment],
+ mImage2DBindLayoutCache[gl::ShaderType::Fragment],
+ static_cast<unsigned int>(mPixelShaderKey.size()));
+
+ // Generate new pixel executable
+ ShaderExecutableD3D *pixelExecutable = nullptr;
+
+ gl::InfoLog tempInfoLog;
+ gl::InfoLog *currentInfoLog = infoLog ? infoLog : &tempInfoLog;
+
+ ANGLE_TRY(mRenderer->compileToExecutable(
+ context, *currentInfoLog, finalPixelHLSL, gl::ShaderType::Fragment, mStreamOutVaryings,
+ (mState.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS),
+ mShaderWorkarounds[gl::ShaderType::Fragment], &pixelExecutable));
+
+ if (pixelExecutable)
+ {
+ mPixelExecutables.push_back(std::unique_ptr<PixelExecutable>(
+ new PixelExecutable(mPixelShaderOutputLayoutCache, pixelExecutable)));
+ mCachedPixelExecutableIndex = mPixelExecutables.size() - 1;
+ }
+ else if (!infoLog)
+ {
+ ERR() << "Error compiling dynamic pixel executable:" << std::endl
+ << tempInfoLog.str() << std::endl;
+ }
+
+ *outExecutable = pixelExecutable;
+ return angle::Result::Continue;
+}
+
+angle::Result ProgramD3D::getVertexExecutableForCachedInputLayout(
+ d3d::Context *context,
+ ShaderExecutableD3D **outExectuable,
+ gl::InfoLog *infoLog)
+{
+ if (mCachedVertexExecutableIndex.valid())
+ {
+ *outExectuable =
+ mVertexExecutables[mCachedVertexExecutableIndex.value()]->shaderExecutable();
+ return angle::Result::Continue;
+ }
+
+ // Generate new dynamic layout with attribute conversions
+ std::string finalVertexHLSL = mDynamicHLSL->generateVertexShaderForInputLayout(
+ mShaderHLSL[gl::ShaderType::Vertex], mCachedInputLayout, mState.getProgramInputs(),
+ mShaderStorageBlocks[gl::ShaderType::Vertex], mPixelShaderKey.size());
+
+ // Generate new vertex executable
+ ShaderExecutableD3D *vertexExecutable = nullptr;
+
+ gl::InfoLog tempInfoLog;
+ gl::InfoLog *currentInfoLog = infoLog ? infoLog : &tempInfoLog;
+
+ ANGLE_TRY(mRenderer->compileToExecutable(
+ context, *currentInfoLog, finalVertexHLSL, gl::ShaderType::Vertex, mStreamOutVaryings,
+ (mState.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS),
+ mShaderWorkarounds[gl::ShaderType::Vertex], &vertexExecutable));
+
+ if (vertexExecutable)
+ {
+ mVertexExecutables.push_back(std::unique_ptr<VertexExecutable>(
+ new VertexExecutable(mCachedInputLayout, mCachedVertexSignature, vertexExecutable)));
+ mCachedVertexExecutableIndex = mVertexExecutables.size() - 1;
+ }
+ else if (!infoLog)
+ {
+ ERR() << "Error compiling dynamic vertex executable:" << std::endl
+ << tempInfoLog.str() << std::endl;
+ }
+
+ *outExectuable = vertexExecutable;
+ return angle::Result::Continue;
+}
+
+angle::Result ProgramD3D::getGeometryExecutableForPrimitiveType(d3d::Context *context,
+ const gl::State &state,
+ gl::PrimitiveMode drawMode,
+ ShaderExecutableD3D **outExecutable,
+ gl::InfoLog *infoLog)
+{
+ if (outExecutable)
+ {
+ *outExecutable = nullptr;
+ }
+
+ // Return a null shader if the current rendering doesn't use a geometry shader
+ if (!usesGeometryShader(state, drawMode))
+ {
+ return angle::Result::Continue;
+ }
+
+ gl::PrimitiveMode geometryShaderType = GetGeometryShaderTypeFromDrawMode(drawMode);
+
+ if (mGeometryExecutables[geometryShaderType])
+ {
+ if (outExecutable)
+ {
+ *outExecutable = mGeometryExecutables[geometryShaderType].get();
+ }
+ return angle::Result::Continue;
+ }
+ const gl::Caps &caps = state.getCaps();
+ std::string geometryHLSL = mDynamicHLSL->generateGeometryShaderHLSL(
+ caps, geometryShaderType, mState, mRenderer->presentPathFastEnabled(),
+ mHasANGLEMultiviewEnabled, mRenderer->canSelectViewInVertexShader(),
+ usesGeometryShaderForPointSpriteEmulation(), mGeometryShaderPreamble);
+
+ gl::InfoLog tempInfoLog;
+ gl::InfoLog *currentInfoLog = infoLog ? infoLog : &tempInfoLog;
+
+ ShaderExecutableD3D *geometryExecutable = nullptr;
+ angle::Result result = mRenderer->compileToExecutable(
+ context, *currentInfoLog, geometryHLSL, gl::ShaderType::Geometry, mStreamOutVaryings,
+ (mState.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS), CompilerWorkaroundsD3D(),
+ &geometryExecutable);
+
+ if (!infoLog && result == angle::Result::Stop)
+ {
+ ERR() << "Error compiling dynamic geometry executable:" << std::endl
+ << tempInfoLog.str() << std::endl;
+ }
+
+ if (geometryExecutable != nullptr)
+ {
+ mGeometryExecutables[geometryShaderType].reset(geometryExecutable);
+ }
+
+ if (outExecutable)
+ {
+ *outExecutable = mGeometryExecutables[geometryShaderType].get();
+ }
+ return result;
+}
+
+class ProgramD3D::GetVertexExecutableTask : public ProgramD3D::GetExecutableTask
+{
+ public:
+ GetVertexExecutableTask(const gl::Context *context, ProgramD3D *program)
+ : GetExecutableTask(context, program)
+ {}
+ angle::Result run() override
+ {
+ ANGLE_TRACE_EVENT0("gpu.angle", "ProgramD3D::GetVertexExecutableTask::run");
+
+ ANGLE_TRY(mProgram->getVertexExecutableForCachedInputLayout(this, &mExecutable, &mInfoLog));
+
+ return angle::Result::Continue;
+ }
+};
+
+void ProgramD3D::updateCachedInputLayoutFromShader(const gl::Context *context)
+{
+ GetDefaultInputLayoutFromShader(context, mState.getAttachedShader(gl::ShaderType::Vertex),
+ &mCachedInputLayout);
+ VertexExecutable::getSignature(mRenderer, mCachedInputLayout, &mCachedVertexSignature);
+ updateCachedVertexExecutableIndex();
+}
+
+class ProgramD3D::GetPixelExecutableTask : public ProgramD3D::GetExecutableTask
+{
+ public:
+ GetPixelExecutableTask(const gl::Context *context, ProgramD3D *program)
+ : GetExecutableTask(context, program)
+ {}
+ angle::Result run() override
+ {
+ ANGLE_TRACE_EVENT0("gpu.angle", "ProgramD3D::GetPixelExecutableTask::run");
+ if (!mProgram->mState.getAttachedShader(gl::ShaderType::Fragment))
+ {
+ return angle::Result::Continue;
+ }
+
+ mProgram->updateCachedOutputLayoutFromShader();
+ mProgram->updateCachedImage2DBindLayoutFromShader(gl::ShaderType::Fragment);
+ ANGLE_TRY(mProgram->getPixelExecutableForCachedOutputLayout(this, &mExecutable, &mInfoLog));
+
+ return angle::Result::Continue;
+ }
+};
+
+void ProgramD3D::updateCachedOutputLayoutFromShader()
+{
+ GetDefaultOutputLayoutFromShader(mPixelShaderKey, &mPixelShaderOutputLayoutCache);
+ updateCachedPixelExecutableIndex();
+}
+
+void ProgramD3D::updateCachedImage2DBindLayoutFromShader(gl::ShaderType shaderType)
+{
+ GetDefaultImage2DBindLayoutFromShader(mImage2DUniforms[shaderType],
+ &mImage2DBindLayoutCache[shaderType]);
+ switch (shaderType)
+ {
+ case gl::ShaderType::Compute:
+ updateCachedComputeExecutableIndex();
+ break;
+ case gl::ShaderType::Fragment:
+ updateCachedPixelExecutableIndex();
+ break;
+ case gl::ShaderType::Vertex:
+ updateCachedVertexExecutableIndex();
+ break;
+ default:
+ ASSERT(false);
+ break;
+ }
+}
+
+class ProgramD3D::GetGeometryExecutableTask : public ProgramD3D::GetExecutableTask
+{
+ public:
+ GetGeometryExecutableTask(const gl::Context *context,
+ ProgramD3D *program,
+ const gl::State &state)
+ : GetExecutableTask(context, program), mState(state)
+ {}
+
+ angle::Result run() override
+ {
+ ANGLE_TRACE_EVENT0("gpu.angle", "ProgramD3D::GetGeometryExecutableTask::run");
+ // Auto-generate the geometry shader here, if we expect to be using point rendering in
+ // D3D11.
+ if (mProgram->usesGeometryShader(mState, gl::PrimitiveMode::Points))
+ {
+ ANGLE_TRY(mProgram->getGeometryExecutableForPrimitiveType(
+ this, mState, gl::PrimitiveMode::Points, &mExecutable, &mInfoLog));
+ }
+
+ return angle::Result::Continue;
+ }
+
+ private:
+ const gl::State &mState;
+};
+
+class ProgramD3D::GetComputeExecutableTask : public ProgramD3D::GetExecutableTask
+{
+ public:
+ GetComputeExecutableTask(const gl::Context *context, ProgramD3D *program)
+ : GetExecutableTask(context, program)
+ {}
+ angle::Result run() override
+ {
+ ANGLE_TRACE_EVENT0("gpu.angle", "ProgramD3D::GetComputeExecutableTask::run");
+ mProgram->updateCachedImage2DBindLayoutFromShader(gl::ShaderType::Compute);
+ ShaderExecutableD3D *computeExecutable = nullptr;
+ ANGLE_TRY(mProgram->getComputeExecutableForImage2DBindLayout(
+ mContext, this, &computeExecutable, &mInfoLog));
+
+ return computeExecutable ? angle::Result::Continue : angle::Result::Incomplete;
+ }
+};
+
+// The LinkEvent implementation for linking a rendering(VS, FS, GS) program.
+class ProgramD3D::GraphicsProgramLinkEvent final : public LinkEvent
+{
+ public:
+ GraphicsProgramLinkEvent(gl::InfoLog &infoLog,
+ std::shared_ptr<WorkerThreadPool> workerPool,
+ std::shared_ptr<ProgramD3D::GetVertexExecutableTask> vertexTask,
+ std::shared_ptr<ProgramD3D::GetPixelExecutableTask> pixelTask,
+ std::shared_ptr<ProgramD3D::GetGeometryExecutableTask> geometryTask,
+ bool useGS,
+ const ShaderD3D *vertexShader,
+ const ShaderD3D *fragmentShader)
+ : mInfoLog(infoLog),
+ mVertexTask(vertexTask),
+ mPixelTask(pixelTask),
+ mGeometryTask(geometryTask),
+ mWaitEvents({{std::shared_ptr<WaitableEvent>(
+ angle::WorkerThreadPool::PostWorkerTask(workerPool, mVertexTask)),
+ std::shared_ptr<WaitableEvent>(
+ angle::WorkerThreadPool::PostWorkerTask(workerPool, mPixelTask)),
+ std::shared_ptr<WaitableEvent>(
+ angle::WorkerThreadPool::PostWorkerTask(workerPool, mGeometryTask))}}),
+ mUseGS(useGS),
+ mVertexShader(vertexShader),
+ mFragmentShader(fragmentShader)
+ {}
+
+ angle::Result wait(const gl::Context *context) override
+ {
+ ANGLE_TRACE_EVENT0("gpu.angle", "ProgramD3D::GraphicsProgramLinkEvent::wait");
+ WaitableEvent::WaitMany(&mWaitEvents);
+
+ ANGLE_TRY(checkTask(context, mVertexTask.get()));
+ ANGLE_TRY(checkTask(context, mPixelTask.get()));
+ ANGLE_TRY(checkTask(context, mGeometryTask.get()));
+
+ if (mVertexTask->getResult() == angle::Result::Incomplete ||
+ mPixelTask->getResult() == angle::Result::Incomplete ||
+ mGeometryTask->getResult() == angle::Result::Incomplete)
+ {
+ return angle::Result::Incomplete;
+ }
+
+ ShaderExecutableD3D *defaultVertexExecutable = mVertexTask->getExecutable();
+ ShaderExecutableD3D *defaultPixelExecutable = mPixelTask->getExecutable();
+ ShaderExecutableD3D *pointGS = mGeometryTask->getExecutable();
+
+ if (mUseGS && pointGS)
+ {
+ // Geometry shaders are currently only used internally, so there is no corresponding
+ // shader object at the interface level. For now the geometry shader debug info is
+ // prepended to the vertex shader.
+ mVertexShader->appendDebugInfo("// GEOMETRY SHADER BEGIN\n\n");
+ mVertexShader->appendDebugInfo(pointGS->getDebugInfo());
+ mVertexShader->appendDebugInfo("\nGEOMETRY SHADER END\n\n\n");
+ }
+
+ if (defaultVertexExecutable)
+ {
+ mVertexShader->appendDebugInfo(defaultVertexExecutable->getDebugInfo());
+ }
+
+ if (defaultPixelExecutable)
+ {
+ mFragmentShader->appendDebugInfo(defaultPixelExecutable->getDebugInfo());
+ }
+
+ bool isLinked = (defaultVertexExecutable && defaultPixelExecutable && (!mUseGS || pointGS));
+ if (!isLinked)
+ {
+ mInfoLog << "Failed to create D3D Shaders";
+ }
+ return isLinked ? angle::Result::Continue : angle::Result::Incomplete;
+ }
+
+ bool isLinking() override
+ {
+ for (auto &event : mWaitEvents)
+ {
+ if (!event->isReady())
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private:
+ angle::Result checkTask(const gl::Context *context, ProgramD3D::GetExecutableTask *task)
+ {
+ if (!task->getInfoLog().empty())
+ {
+ mInfoLog << task->getInfoLog().str();
+ }
+
+ // Continue and Incomplete are not errors. For Stop, pass the error to the ContextD3D.
+ if (task->getResult() != angle::Result::Stop)
+ {
+ return angle::Result::Continue;
+ }
+
+ ContextD3D *contextD3D = GetImplAs<ContextD3D>(context);
+ task->popError(contextD3D);
+ return angle::Result::Stop;
+ }
+
+ gl::InfoLog &mInfoLog;
+ std::shared_ptr<ProgramD3D::GetVertexExecutableTask> mVertexTask;
+ std::shared_ptr<ProgramD3D::GetPixelExecutableTask> mPixelTask;
+ std::shared_ptr<ProgramD3D::GetGeometryExecutableTask> mGeometryTask;
+ std::array<std::shared_ptr<WaitableEvent>, 3> mWaitEvents;
+ bool mUseGS;
+ const ShaderD3D *mVertexShader;
+ const ShaderD3D *mFragmentShader;
+};
+
+// The LinkEvent implementation for linking a computing program.
+class ProgramD3D::ComputeProgramLinkEvent final : public LinkEvent
+{
+ public:
+ ComputeProgramLinkEvent(gl::InfoLog &infoLog,
+ std::shared_ptr<ProgramD3D::GetComputeExecutableTask> computeTask,
+ std::shared_ptr<WaitableEvent> event)
+ : mInfoLog(infoLog), mComputeTask(computeTask), mWaitEvent(event)
+ {}
+
+ bool isLinking() override { return !mWaitEvent->isReady(); }
+
+ angle::Result wait(const gl::Context *context) override
+ {
+ ANGLE_TRACE_EVENT0("gpu.angle", "ProgramD3D::ComputeProgramLinkEvent::wait");
+ mWaitEvent->wait();
+
+ angle::Result result = mComputeTask->getResult();
+ if (result != angle::Result::Continue)
+ {
+ mInfoLog << "Failed to create D3D compute shader.";
+ }
+ return result;
+ }
+
+ private:
+ gl::InfoLog &mInfoLog;
+ std::shared_ptr<ProgramD3D::GetComputeExecutableTask> mComputeTask;
+ std::shared_ptr<WaitableEvent> mWaitEvent;
+};
+
+std::unique_ptr<LinkEvent> ProgramD3D::compileProgramExecutables(const gl::Context *context,
+ gl::InfoLog &infoLog)
+{
+ ANGLE_TRACE_EVENT0("gpu.angle", "ProgramD3D::compileProgramExecutables");
+ // Ensure the compiler is initialized to avoid race conditions.
+ angle::Result result = mRenderer->ensureHLSLCompilerInitialized(GetImplAs<ContextD3D>(context));
+ if (result != angle::Result::Continue)
+ {
+ return std::make_unique<LinkEventDone>(result);
+ }
+
+ auto vertexTask = std::make_shared<GetVertexExecutableTask>(context, this);
+ auto pixelTask = std::make_shared<GetPixelExecutableTask>(context, this);
+ auto geometryTask =
+ std::make_shared<GetGeometryExecutableTask>(context, this, context->getState());
+ bool useGS = usesGeometryShader(context->getState(), gl::PrimitiveMode::Points);
+ gl::Shader *vertexShader = mState.getAttachedShader(gl::ShaderType::Vertex);
+ gl::Shader *fragmentShader = mState.getAttachedShader(gl::ShaderType::Fragment);
+ const ShaderD3D *vertexShaderD3D = vertexShader ? GetImplAs<ShaderD3D>(vertexShader) : nullptr;
+ const ShaderD3D *fragmentShaderD3D =
+ fragmentShader ? GetImplAs<ShaderD3D>(fragmentShader) : nullptr;
+
+ return std::make_unique<GraphicsProgramLinkEvent>(infoLog, context->getWorkerThreadPool(),
+ vertexTask, pixelTask, geometryTask, useGS,
+ vertexShaderD3D, fragmentShaderD3D);
+}
+
+std::unique_ptr<LinkEvent> ProgramD3D::compileComputeExecutable(const gl::Context *context,
+ gl::InfoLog &infoLog)
+{
+ ANGLE_TRACE_EVENT0("gpu.angle", "ProgramD3D::compileComputeExecutable");
+ // Ensure the compiler is initialized to avoid race conditions.
+ angle::Result result = mRenderer->ensureHLSLCompilerInitialized(GetImplAs<ContextD3D>(context));
+ if (result != angle::Result::Continue)
+ {
+ return std::make_unique<LinkEventDone>(result);
+ }
+ auto computeTask = std::make_shared<GetComputeExecutableTask>(context, this);
+
+ std::shared_ptr<WaitableEvent> waitableEvent;
+
+ // TODO(jie.a.chen@intel.com): Fix the flaky bug.
+ // http://anglebug.com/3349
+ bool compileInParallel = false;
+ if (!compileInParallel)
+ {
+ (*computeTask)();
+ waitableEvent = std::make_shared<WaitableEventDone>();
+ }
+ else
+ {
+ waitableEvent =
+ WorkerThreadPool::PostWorkerTask(context->getWorkerThreadPool(), computeTask);
+ }
+
+ return std::make_unique<ComputeProgramLinkEvent>(infoLog, computeTask, waitableEvent);
+}
+
+angle::Result ProgramD3D::getComputeExecutableForImage2DBindLayout(
+ const gl::Context *glContext,
+ d3d::Context *context,
+ ShaderExecutableD3D **outExecutable,
+ gl::InfoLog *infoLog)
+{
+ ANGLE_TRACE_EVENT0("gpu.angle", "ProgramD3D::getComputeExecutableForImage2DBindLayout");
+ if (mCachedComputeExecutableIndex.valid())
+ {
+ *outExecutable =
+ mComputeExecutables[mCachedComputeExecutableIndex.value()]->shaderExecutable();
+ return angle::Result::Continue;
+ }
+
+ std::string computeHLSL =
+ mState.getAttachedShader(gl::ShaderType::Compute)->getTranslatedSource(glContext);
+
+ std::string finalComputeHLSL = mDynamicHLSL->generateShaderForImage2DBindSignature(
+ *this, mState, gl::ShaderType::Compute, computeHLSL,
+ mImage2DUniforms[gl::ShaderType::Compute], mImage2DBindLayoutCache[gl::ShaderType::Compute],
+ 0u);
+
+ // Generate new compute executable
+ ShaderExecutableD3D *computeExecutable = nullptr;
+
+ gl::InfoLog tempInfoLog;
+ gl::InfoLog *currentInfoLog = infoLog ? infoLog : &tempInfoLog;
+
+ ANGLE_TRY(mRenderer->compileToExecutable(context, *currentInfoLog, finalComputeHLSL,
+ gl::ShaderType::Compute, std::vector<D3DVarying>(),
+ false, CompilerWorkaroundsD3D(), &computeExecutable));
+
+ if (computeExecutable)
+ {
+ mComputeExecutables.push_back(std::unique_ptr<ComputeExecutable>(
+ new ComputeExecutable(mImage2DBindLayoutCache[gl::ShaderType::Compute],
+ std::unique_ptr<ShaderExecutableD3D>(computeExecutable))));
+ mCachedComputeExecutableIndex = mComputeExecutables.size() - 1;
+ }
+ else if (!infoLog)
+ {
+ ERR() << "Error compiling dynamic compute executable:" << std::endl
+ << tempInfoLog.str() << std::endl;
+ }
+ *outExecutable = computeExecutable;
+
+ return angle::Result::Continue;
+}
+
+std::unique_ptr<LinkEvent> ProgramD3D::link(const gl::Context *context,
+ const gl::ProgramLinkedResources &resources,
+ gl::InfoLog &infoLog,
+ const gl::ProgramMergedVaryings & /*mergedVaryings*/)
+{
+ ANGLE_TRACE_EVENT0("gpu.angle", "ProgramD3D::link");
+ const auto &data = context->getState();
+
+ reset();
+
+ gl::Shader *computeShader = mState.getAttachedShader(gl::ShaderType::Compute);
+ if (computeShader)
+ {
+ mShaderSamplers[gl::ShaderType::Compute].resize(
+ data.getCaps().maxShaderTextureImageUnits[gl::ShaderType::Compute]);
+ mImages[gl::ShaderType::Compute].resize(data.getCaps().maxImageUnits);
+ mReadonlyImages[gl::ShaderType::Compute].resize(data.getCaps().maxImageUnits);
+
+ mShaderUniformsDirty.set(gl::ShaderType::Compute);
+
+ linkResources(context, resources);
+
+ for (const sh::ShaderVariable &uniform : computeShader->getUniforms(context))
+ {
+ if (gl::IsImageType(uniform.type) && gl::IsImage2DType(uniform.type))
+ {
+ mImage2DUniforms[gl::ShaderType::Compute].push_back(uniform);
+ }
+ }
+
+ defineUniformsAndAssignRegisters(context);
+
+ return compileComputeExecutable(context, infoLog);
+ }
+ else
+ {
+ gl::ShaderMap<const ShaderD3D *> shadersD3D = {};
+ for (gl::ShaderType shaderType : gl::kAllGraphicsShaderTypes)
+ {
+ if (gl::Shader *shader = mState.getAttachedShader(shaderType))
+ {
+ shadersD3D[shaderType] = GetImplAs<ShaderD3D>(mState.getAttachedShader(shaderType));
+
+ mShaderSamplers[shaderType].resize(
+ data.getCaps().maxShaderTextureImageUnits[shaderType]);
+ mImages[shaderType].resize(data.getCaps().maxImageUnits);
+ mReadonlyImages[shaderType].resize(data.getCaps().maxImageUnits);
+
+ shadersD3D[shaderType]->generateWorkarounds(&mShaderWorkarounds[shaderType]);
+
+ mShaderUniformsDirty.set(shaderType);
+
+ const std::set<std::string> &slowCompilingUniformBlockSet =
+ shadersD3D[shaderType]->getSlowCompilingUniformBlockSet();
+ if (slowCompilingUniformBlockSet.size() > 0)
+ {
+ std::ostringstream stream;
+ stream << "You could get a better shader compiling performance if you re-write"
+ << " the uniform block(s)\n[ ";
+ for (const std::string &str : slowCompilingUniformBlockSet)
+ {
+ stream << str << " ";
+ }
+ stream << "]\nin the " << gl::GetShaderTypeString(shaderType) << " shader.\n";
+
+ stream << "You could get more details from "
+ "https://chromium.googlesource.com/angle/angle/+/refs/heads/main/"
+ "src/libANGLE/renderer/d3d/d3d11/"
+ "UniformBlockToStructuredBufferTranslation.md\n";
+ ANGLE_PERF_WARNING(context->getState().getDebug(), GL_DEBUG_SEVERITY_MEDIUM,
+ stream.str().c_str());
+ }
+
+ for (const sh::ShaderVariable &uniform : shader->getUniforms(context))
+ {
+ if (gl::IsImageType(uniform.type) && gl::IsImage2DType(uniform.type))
+ {
+ mImage2DUniforms[shaderType].push_back(uniform);
+ }
+ }
+ }
+ }
+
+ if (mRenderer->getNativeLimitations().noFrontFacingSupport)
+ {
+ const ShaderD3D *fragmentShader = shadersD3D[gl::ShaderType::Fragment];
+ if (fragmentShader && fragmentShader->usesFrontFacing())
+ {
+ infoLog << "The current renderer doesn't support gl_FrontFacing";
+ return std::make_unique<LinkEventDone>(angle::Result::Incomplete);
+ }
+ }
+
+ const gl::VaryingPacking &varyingPacking =
+ resources.varyingPacking.getOutputPacking(gl::ShaderType::Vertex);
+
+ ProgramD3DMetadata metadata(mRenderer, shadersD3D, context->getClientType());
+ BuiltinVaryingsD3D builtins(metadata, varyingPacking);
+
+ mDynamicHLSL->generateShaderLinkHLSL(context, context->getCaps(), mState, metadata,
+ varyingPacking, builtins, &mShaderHLSL);
+
+ const ShaderD3D *vertexShader = shadersD3D[gl::ShaderType::Vertex];
+ mUsesPointSize = vertexShader && vertexShader->usesPointSize();
+ mDynamicHLSL->getPixelShaderOutputKey(data, mState, metadata, &mPixelShaderKey);
+ mUsesFragDepth = metadata.usesFragDepth();
+ mUsesVertexID = metadata.usesVertexID();
+ mUsesViewID = metadata.usesViewID();
+ mHasANGLEMultiviewEnabled = metadata.hasANGLEMultiviewEnabled();
+
+ // Cache if we use flat shading
+ mUsesFlatInterpolation = FindFlatInterpolationVarying(context, mState.getAttachedShaders());
+
+ if (mRenderer->getMajorShaderModel() >= 4)
+ {
+ mGeometryShaderPreamble = mDynamicHLSL->generateGeometryShaderPreamble(
+ varyingPacking, builtins, mHasANGLEMultiviewEnabled,
+ metadata.canSelectViewInVertexShader());
+ }
+
+ initAttribLocationsToD3DSemantic(context);
+
+ defineUniformsAndAssignRegisters(context);
+
+ gatherTransformFeedbackVaryings(varyingPacking, builtins[gl::ShaderType::Vertex]);
+
+ linkResources(context, resources);
+
+ if (mState.getAttachedShader(gl::ShaderType::Vertex))
+ {
+ updateCachedInputLayoutFromShader(context);
+ }
+
+ return compileProgramExecutables(context, infoLog);
+ }
+}
+
+GLboolean ProgramD3D::validate(const gl::Caps & /*caps*/, gl::InfoLog * /*infoLog*/)
+{
+ // TODO(jmadill): Do something useful here?
+ return GL_TRUE;
+}
+
+void ProgramD3D::initializeShaderStorageBlocks(const gl::Context *context)
+{
+ if (mState.getShaderStorageBlocks().empty())
+ {
+ return;
+ }
+
+ ASSERT(mD3DShaderStorageBlocks.empty());
+
+ // Assign registers and update sizes.
+ gl::ShaderMap<const ShaderD3D *> shadersD3D = {};
+ for (gl::ShaderType shaderType : gl::AllShaderTypes())
+ {
+ shadersD3D[shaderType] = SafeGetImplAs<ShaderD3D>(mState.getAttachedShader(shaderType));
+ }
+ for (const gl::InterfaceBlock &shaderStorageBlock : mState.getShaderStorageBlocks())
+ {
+ unsigned int shaderStorageBlockElement =
+ shaderStorageBlock.isArray ? shaderStorageBlock.arrayElement : 0;
+ D3DInterfaceBlock d3dShaderStorageBlock;
+
+ for (gl::ShaderType shaderType : gl::AllShaderTypes())
+ {
+ if (shaderStorageBlock.isActive(shaderType))
+ {
+ ASSERT(shadersD3D[shaderType]);
+ unsigned int baseRegister =
+ shadersD3D[shaderType]->getShaderStorageBlockRegister(shaderStorageBlock.name);
+
+ d3dShaderStorageBlock.mShaderRegisterIndexes[shaderType] =
+ baseRegister + shaderStorageBlockElement;
+ }
+ }
+ mD3DShaderStorageBlocks.push_back(d3dShaderStorageBlock);
+ }
+
+ for (gl::ShaderType shaderType : gl::AllShaderTypes())
+ {
+ gl::Shader *shader = mState.getAttachedShader(shaderType);
+ if (!shader)
+ {
+ continue;
+ }
+ ShaderD3D *shaderD3D = SafeGetImplAs<ShaderD3D>(shader);
+ for (const sh::InterfaceBlock &ssbo : shader->getShaderStorageBlocks(context))
+ {
+ if (!ssbo.active)
+ {
+ continue;
+ }
+ ShaderStorageBlock block;
+ block.name = !ssbo.instanceName.empty() ? ssbo.instanceName : ssbo.name;
+ block.arraySize = ssbo.isArray() ? ssbo.arraySize : 0;
+ block.registerIndex = shaderD3D->getShaderStorageBlockRegister(ssbo.name);
+ mShaderStorageBlocks[shaderType].push_back(block);
+ }
+ }
+}
+
+void ProgramD3D::initializeUniformBlocks()
+{
+ if (mState.getUniformBlocks().empty())
+ {
+ return;
+ }
+
+ ASSERT(mD3DUniformBlocks.empty());
+
+ // Assign registers and update sizes.
+ gl::ShaderMap<const ShaderD3D *> shadersD3D = {};
+ for (gl::ShaderType shaderType : gl::AllShaderTypes())
+ {
+ shadersD3D[shaderType] = SafeGetImplAs<ShaderD3D>(mState.getAttachedShader(shaderType));
+ }
+
+ for (const gl::InterfaceBlock &uniformBlock : mState.getUniformBlocks())
+ {
+ unsigned int uniformBlockElement = uniformBlock.isArray ? uniformBlock.arrayElement : 0;
+
+ D3DUniformBlock d3dUniformBlock;
+
+ for (gl::ShaderType shaderType : gl::AllShaderTypes())
+ {
+ if (uniformBlock.isActive(shaderType))
+ {
+ ASSERT(shadersD3D[shaderType]);
+ unsigned int baseRegister =
+ shadersD3D[shaderType]->getUniformBlockRegister(uniformBlock.name);
+ d3dUniformBlock.mShaderRegisterIndexes[shaderType] =
+ baseRegister + uniformBlockElement;
+ bool useStructuredBuffer =
+ shadersD3D[shaderType]->shouldUniformBlockUseStructuredBuffer(
+ uniformBlock.name);
+ if (useStructuredBuffer)
+ {
+ d3dUniformBlock.mUseStructuredBuffers[shaderType] = true;
+ d3dUniformBlock.mByteWidths[shaderType] = uniformBlock.dataSize;
+ d3dUniformBlock.mStructureByteStrides[shaderType] =
+ uniformBlock.firstFieldArraySize == 0u
+ ? uniformBlock.dataSize
+ : uniformBlock.dataSize / uniformBlock.firstFieldArraySize;
+ }
+ }
+ }
+
+ mD3DUniformBlocks.push_back(d3dUniformBlock);
+ }
+}
+
+void ProgramD3D::initializeUniformStorage(const gl::ShaderBitSet &availableShaderStages)
+{
+ // Compute total default block size
+ gl::ShaderMap<unsigned int> shaderRegisters = {};
+ for (const D3DUniform *d3dUniform : mD3DUniforms)
+ {
+ if (d3dUniform->isSampler())
+ {
+ continue;
+ }
+
+ for (gl::ShaderType shaderType : availableShaderStages)
+ {
+ if (d3dUniform->isReferencedByShader(shaderType))
+ {
+ shaderRegisters[shaderType] = std::max(
+ shaderRegisters[shaderType],
+ d3dUniform->mShaderRegisterIndexes[shaderType] + d3dUniform->registerCount);
+ }
+ }
+ }
+
+ // We only reset uniform storages for the shader stages available in the program (attached
+ // shaders in ProgramD3D::link() and linkedShaderStages in ProgramD3D::load()).
+ for (gl::ShaderType shaderType : availableShaderStages)
+ {
+ mShaderUniformStorages[shaderType].reset(
+ mRenderer->createUniformStorage(shaderRegisters[shaderType] * 16u));
+ }
+
+ // Iterate the uniforms again to assign data pointers to default block uniforms.
+ for (D3DUniform *d3dUniform : mD3DUniforms)
+ {
+ if (d3dUniform->isSampler())
+ {
+ d3dUniform->mSamplerData.resize(d3dUniform->getArraySizeProduct(), 0);
+ continue;
+ }
+
+ for (gl::ShaderType shaderType : availableShaderStages)
+ {
+ if (d3dUniform->isReferencedByShader(shaderType))
+ {
+ d3dUniform->mShaderData[shaderType] =
+ mShaderUniformStorages[shaderType]->getDataPointer(
+ d3dUniform->mShaderRegisterIndexes[shaderType],
+ d3dUniform->registerElement);
+ }
+ }
+ }
+}
+
+void ProgramD3D::updateUniformBufferCache(const gl::Caps &caps)
+{
+ if (mState.getUniformBlocks().empty())
+ {
+ return;
+ }
+
+ for (gl::ShaderType shaderType : gl::AllShaderTypes())
+ {
+ mShaderUBOCaches[shaderType].clear();
+ mShaderUBOCachesUseSB[shaderType].clear();
+ }
+
+ for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < mD3DUniformBlocks.size();
+ uniformBlockIndex++)
+ {
+ const D3DUniformBlock &uniformBlock = mD3DUniformBlocks[uniformBlockIndex];
+ GLuint blockBinding = mState.getUniformBlockBinding(uniformBlockIndex);
+
+ // Unnecessary to apply an unreferenced standard or shared UBO
+ for (gl::ShaderType shaderType : gl::AllShaderTypes())
+ {
+ if (!uniformBlock.activeInShader(shaderType))
+ {
+ continue;
+ }
+
+ bool useStructuredBuffer = uniformBlock.mUseStructuredBuffers[shaderType];
+ unsigned int registerIndex = uniformBlock.mShaderRegisterIndexes[shaderType];
+ if (useStructuredBuffer)
+ {
+ D3DUBOCacheUseSB cacheUseSB;
+ cacheUseSB.registerIndex = registerIndex;
+ cacheUseSB.binding = blockBinding;
+ cacheUseSB.byteWidth = uniformBlock.mByteWidths[shaderType];
+ cacheUseSB.structureByteStride = uniformBlock.mStructureByteStrides[shaderType];
+ mShaderUBOCachesUseSB[shaderType].push_back(cacheUseSB);
+ }
+ else
+ {
+ ASSERT(registerIndex <
+ static_cast<unsigned int>(caps.maxShaderUniformBlocks[shaderType]));
+ D3DUBOCache cache;
+ cache.registerIndex = registerIndex;
+ cache.binding = blockBinding;
+ mShaderUBOCaches[shaderType].push_back(cache);
+ }
+ }
+ }
+
+ for (gl::ShaderType shaderType : gl::AllShaderTypes())
+ {
+ GLuint uniformBlockCount = static_cast<GLuint>(mShaderUBOCaches[shaderType].size() +
+ mShaderUBOCachesUseSB[shaderType].size());
+ ASSERT(uniformBlockCount <=
+ static_cast<unsigned int>(caps.maxShaderUniformBlocks[shaderType]));
+ }
+}
+
+unsigned int ProgramD3D::getAtomicCounterBufferRegisterIndex(GLuint binding,
+ gl::ShaderType shaderType) const
+{
+ if (shaderType != gl::ShaderType::Compute)
+ {
+ // Implement atomic counters for non-compute shaders
+ // http://anglebug.com/1729
+ UNIMPLEMENTED();
+ }
+ return mComputeAtomicCounterBufferRegisterIndices[binding];
+}
+
+unsigned int ProgramD3D::getShaderStorageBufferRegisterIndex(GLuint blockIndex,
+ gl::ShaderType shaderType) const
+{
+ return mD3DShaderStorageBlocks[blockIndex].mShaderRegisterIndexes[shaderType];
+}
+
+const std::vector<D3DUBOCache> &ProgramD3D::getShaderUniformBufferCache(
+ gl::ShaderType shaderType) const
+{
+ return mShaderUBOCaches[shaderType];
+}
+
+const std::vector<D3DUBOCacheUseSB> &ProgramD3D::getShaderUniformBufferCacheUseSB(
+ gl::ShaderType shaderType) const
+{
+ return mShaderUBOCachesUseSB[shaderType];
+}
+
+void ProgramD3D::dirtyAllUniforms()
+{
+ mShaderUniformsDirty = mState.getExecutable().getLinkedShaderStages();
+}
+
+void ProgramD3D::markUniformsClean()
+{
+ mShaderUniformsDirty.reset();
+}
+
+void ProgramD3D::setUniform1fv(GLint location, GLsizei count, const GLfloat *v)
+{
+ setUniformInternal(location, count, v, GL_FLOAT);
+}
+
+void ProgramD3D::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
+{
+ setUniformInternal(location, count, v, GL_FLOAT_VEC2);
+}
+
+void ProgramD3D::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
+{
+ setUniformInternal(location, count, v, GL_FLOAT_VEC3);
+}
+
+void ProgramD3D::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
+{
+ setUniformInternal(location, count, v, GL_FLOAT_VEC4);
+}
+
+void ProgramD3D::setUniformMatrix2fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ setUniformMatrixfvInternal<2, 2>(location, count, transpose, value);
+}
+
+void ProgramD3D::setUniformMatrix3fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ setUniformMatrixfvInternal<3, 3>(location, count, transpose, value);
+}
+
+void ProgramD3D::setUniformMatrix4fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ setUniformMatrixfvInternal<4, 4>(location, count, transpose, value);
+}
+
+void ProgramD3D::setUniformMatrix2x3fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ setUniformMatrixfvInternal<2, 3>(location, count, transpose, value);
+}
+
+void ProgramD3D::setUniformMatrix3x2fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ setUniformMatrixfvInternal<3, 2>(location, count, transpose, value);
+}
+
+void ProgramD3D::setUniformMatrix2x4fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ setUniformMatrixfvInternal<2, 4>(location, count, transpose, value);
+}
+
+void ProgramD3D::setUniformMatrix4x2fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ setUniformMatrixfvInternal<4, 2>(location, count, transpose, value);
+}
+
+void ProgramD3D::setUniformMatrix3x4fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ setUniformMatrixfvInternal<3, 4>(location, count, transpose, value);
+}
+
+void ProgramD3D::setUniformMatrix4x3fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ setUniformMatrixfvInternal<4, 3>(location, count, transpose, value);
+}
+
+void ProgramD3D::setUniform1iv(GLint location, GLsizei count, const GLint *v)
+{
+ setUniformInternal(location, count, v, GL_INT);
+}
+
+void ProgramD3D::setUniform2iv(GLint location, GLsizei count, const GLint *v)
+{
+ setUniformInternal(location, count, v, GL_INT_VEC2);
+}
+
+void ProgramD3D::setUniform3iv(GLint location, GLsizei count, const GLint *v)
+{
+ setUniformInternal(location, count, v, GL_INT_VEC3);
+}
+
+void ProgramD3D::setUniform4iv(GLint location, GLsizei count, const GLint *v)
+{
+ setUniformInternal(location, count, v, GL_INT_VEC4);
+}
+
+void ProgramD3D::setUniform1uiv(GLint location, GLsizei count, const GLuint *v)
+{
+ setUniformInternal(location, count, v, GL_UNSIGNED_INT);
+}
+
+void ProgramD3D::setUniform2uiv(GLint location, GLsizei count, const GLuint *v)
+{
+ setUniformInternal(location, count, v, GL_UNSIGNED_INT_VEC2);
+}
+
+void ProgramD3D::setUniform3uiv(GLint location, GLsizei count, const GLuint *v)
+{
+ setUniformInternal(location, count, v, GL_UNSIGNED_INT_VEC3);
+}
+
+void ProgramD3D::setUniform4uiv(GLint location, GLsizei count, const GLuint *v)
+{
+ setUniformInternal(location, count, v, GL_UNSIGNED_INT_VEC4);
+}
+
+void ProgramD3D::defineUniformsAndAssignRegisters(const gl::Context *context)
+{
+ D3DUniformMap uniformMap;
+
+ gl::ShaderBitSet attachedShaders;
+ for (gl::ShaderType shaderType : gl::AllShaderTypes())
+ {
+ gl::Shader *shader = mState.getAttachedShader(shaderType);
+ if (shader)
+ {
+ for (const sh::ShaderVariable &uniform : shader->getUniforms(context))
+ {
+ if (uniform.active)
+ {
+ defineUniformBase(shader, uniform, &uniformMap);
+ }
+ }
+
+ attachedShaders.set(shader->getType());
+ }
+ }
+
+ // Initialize the D3DUniform list to mirror the indexing of the GL layer.
+ for (const gl::LinkedUniform &glUniform : mState.getUniforms())
+ {
+ if (!glUniform.isInDefaultBlock())
+ continue;
+
+ std::string name = glUniform.name;
+ if (glUniform.isArray())
+ {
+ // In the program state, array uniform names include [0] as in the program resource
+ // spec. Here we don't include it.
+ // TODO(oetuaho@nvidia.com): consider using the same uniform naming here as in the GL
+ // layer.
+ ASSERT(angle::EndsWith(name, "[0]"));
+ name.resize(name.length() - 3);
+ }
+ auto mapEntry = uniformMap.find(name);
+ ASSERT(mapEntry != uniformMap.end());
+ mD3DUniforms.push_back(mapEntry->second);
+ }
+
+ assignAllSamplerRegisters();
+ assignAllAtomicCounterRegisters();
+ // Samplers and readonly images share shader input resource slot, adjust low value of
+ // readonly image range.
+ for (gl::ShaderType shaderType : {gl::ShaderType::Compute, gl::ShaderType::Fragment})
+ {
+ mUsedReadonlyImageRange[shaderType] =
+ gl::RangeUI(mUsedShaderSamplerRanges[shaderType].high(),
+ mUsedShaderSamplerRanges[shaderType].high());
+ // Atomic counter buffers and non-readonly images share input resource slots
+ mUsedImageRange[shaderType] = gl::RangeUI(mUsedAtomicCounterRange[shaderType].high(),
+ mUsedAtomicCounterRange[shaderType].high());
+ }
+ assignAllImageRegisters();
+ initializeUniformStorage(attachedShaders);
+}
+
+void ProgramD3D::defineUniformBase(const gl::Shader *shader,
+ const sh::ShaderVariable &uniform,
+ D3DUniformMap *uniformMap)
+{
+ sh::StubBlockEncoder stubEncoder;
+
+ // Samplers get their registers assigned in assignAllSamplerRegisters, and images get their
+ // registers assigned in assignAllImageRegisters.
+ if (gl::IsSamplerType(uniform.type))
+ {
+ UniformEncodingVisitorD3D visitor(shader->getType(), HLSLRegisterType::Texture,
+ &stubEncoder, uniformMap);
+ sh::TraverseShaderVariable(uniform, false, &visitor);
+ return;
+ }
+
+ if (gl::IsImageType(uniform.type))
+ {
+ if (uniform.readonly)
+ {
+ UniformEncodingVisitorD3D visitor(shader->getType(), HLSLRegisterType::Texture,
+ &stubEncoder, uniformMap);
+ sh::TraverseShaderVariable(uniform, false, &visitor);
+ }
+ else
+ {
+ UniformEncodingVisitorD3D visitor(
+ shader->getType(), HLSLRegisterType::UnorderedAccessView, &stubEncoder, uniformMap);
+ sh::TraverseShaderVariable(uniform, false, &visitor);
+ }
+ mImageBindingMap[uniform.name] = uniform.binding;
+ return;
+ }
+
+ if (uniform.isBuiltIn() && !uniform.isEmulatedBuiltIn())
+ {
+ UniformEncodingVisitorD3D visitor(shader->getType(), HLSLRegisterType::None, &stubEncoder,
+ uniformMap);
+ sh::TraverseShaderVariable(uniform, false, &visitor);
+ return;
+ }
+ else if (gl::IsAtomicCounterType(uniform.type))
+ {
+ UniformEncodingVisitorD3D visitor(shader->getType(), HLSLRegisterType::UnorderedAccessView,
+ &stubEncoder, uniformMap);
+ sh::TraverseShaderVariable(uniform, false, &visitor);
+ mAtomicBindingMap[uniform.name] = uniform.binding;
+ return;
+ }
+
+ const ShaderD3D *shaderD3D = GetImplAs<ShaderD3D>(shader);
+ unsigned int startRegister = shaderD3D->getUniformRegister(uniform.name);
+ ShShaderOutput outputType = shaderD3D->getCompilerOutputType();
+ sh::HLSLBlockEncoder encoder(sh::HLSLBlockEncoder::GetStrategyFor(outputType), true);
+ encoder.skipRegisters(startRegister);
+
+ UniformEncodingVisitorD3D visitor(shader->getType(), HLSLRegisterType::None, &encoder,
+ uniformMap);
+ sh::TraverseShaderVariable(uniform, false, &visitor);
+}
+
+bool ProgramD3D::hasNamedUniform(const std::string &name)
+{
+ for (D3DUniform *d3dUniform : mD3DUniforms)
+ {
+ if (d3dUniform->name == name)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+// Assume count is already clamped.
+template <typename T>
+void ProgramD3D::setUniformImpl(D3DUniform *targetUniform,
+ const gl::VariableLocation &locationInfo,
+ GLsizei count,
+ const T *v,
+ uint8_t *targetState,
+ GLenum uniformType)
+{
+ const int components = targetUniform->typeInfo.componentCount;
+ const unsigned int arrayElementOffset = locationInfo.arrayIndex;
+ const int blockSize = 4;
+
+ if (targetUniform->typeInfo.type == uniformType)
+ {
+ T *dest = reinterpret_cast<T *>(targetState) + arrayElementOffset * blockSize;
+ const T *source = v;
+
+ // If the component is equal to the block size, we can optimize to a single memcpy.
+ // Otherwise, we have to do partial block writes.
+ if (components == blockSize)
+ {
+ memcpy(dest, source, components * count * sizeof(T));
+ }
+ else
+ {
+ for (GLint i = 0; i < count; i++, dest += blockSize, source += components)
+ {
+ memcpy(dest, source, components * sizeof(T));
+ }
+ }
+ }
+ else
+ {
+ ASSERT(targetUniform->typeInfo.type == gl::VariableBoolVectorType(uniformType));
+ GLint *boolParams = reinterpret_cast<GLint *>(targetState) + arrayElementOffset * 4;
+
+ for (GLint i = 0; i < count; i++)
+ {
+ GLint *dest = boolParams + (i * 4);
+ const T *source = v + (i * components);
+
+ for (int c = 0; c < components; c++)
+ {
+ dest[c] = (source[c] == static_cast<T>(0)) ? GL_FALSE : GL_TRUE;
+ }
+ }
+ }
+}
+
+template <typename T>
+void ProgramD3D::setUniformInternal(GLint location, GLsizei count, const T *v, GLenum uniformType)
+{
+ const gl::VariableLocation &locationInfo = mState.getUniformLocations()[location];
+ D3DUniform *targetUniform = mD3DUniforms[locationInfo.index];
+
+ if (targetUniform->typeInfo.isSampler)
+ {
+ ASSERT(uniformType == GL_INT);
+ size_t size = count * sizeof(T);
+ GLint *dest = &targetUniform->mSamplerData[locationInfo.arrayIndex];
+ if (memcmp(dest, v, size) != 0)
+ {
+ memcpy(dest, v, size);
+ mDirtySamplerMapping = true;
+ }
+ return;
+ }
+
+ for (gl::ShaderType shaderType : gl::AllShaderTypes())
+ {
+ uint8_t *targetState = targetUniform->mShaderData[shaderType];
+ if (targetState)
+ {
+ setUniformImpl(targetUniform, locationInfo, count, v, targetState, uniformType);
+ mShaderUniformsDirty.set(shaderType);
+ }
+ }
+}
+
+template <int cols, int rows>
+void ProgramD3D::setUniformMatrixfvInternal(GLint location,
+ GLsizei countIn,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ D3DUniform *targetUniform = getD3DUniformFromLocation(location);
+ const gl::VariableLocation &uniformLocation = mState.getUniformLocations()[location];
+ unsigned int arrayElementOffset = uniformLocation.arrayIndex;
+ unsigned int elementCount = targetUniform->getArraySizeProduct();
+
+ for (gl::ShaderType shaderType : gl::AllShaderTypes())
+ {
+ if (targetUniform->mShaderData[shaderType])
+ {
+ SetFloatUniformMatrixHLSL<cols, rows>::Run(arrayElementOffset, elementCount, countIn,
+ transpose, value,
+ targetUniform->mShaderData[shaderType]);
+ mShaderUniformsDirty.set(shaderType);
+ }
+ }
+}
+
+void ProgramD3D::assignAllSamplerRegisters()
+{
+ for (size_t uniformIndex = 0; uniformIndex < mD3DUniforms.size(); ++uniformIndex)
+ {
+ if (mD3DUniforms[uniformIndex]->isSampler())
+ {
+ assignSamplerRegisters(uniformIndex);
+ }
+ }
+}
+
+void ProgramD3D::assignSamplerRegisters(size_t uniformIndex)
+{
+ D3DUniform *d3dUniform = mD3DUniforms[uniformIndex];
+ ASSERT(d3dUniform->isSampler());
+ // If the uniform is an array of arrays, then we have separate entries for each inner array in
+ // mD3DUniforms. However, the sampler register info is stored in the shader only for the
+ // outermost array.
+ std::vector<unsigned int> subscripts;
+ const std::string baseName = gl::ParseResourceName(d3dUniform->name, &subscripts);
+ unsigned int registerOffset =
+ mState.getUniforms()[uniformIndex].parentArrayIndex() * d3dUniform->getArraySizeProduct();
+
+ bool hasUniform = false;
+ for (gl::ShaderType shaderType : gl::AllShaderTypes())
+ {
+ if (!mState.getAttachedShader(shaderType))
+ {
+ continue;
+ }
+
+ const ShaderD3D *shaderD3D = GetImplAs<ShaderD3D>(mState.getAttachedShader(shaderType));
+ if (shaderD3D->hasUniform(baseName))
+ {
+ d3dUniform->mShaderRegisterIndexes[shaderType] =
+ shaderD3D->getUniformRegister(baseName) + registerOffset;
+ ASSERT(d3dUniform->mShaderRegisterIndexes[shaderType] != GL_INVALID_VALUE);
+
+ AssignSamplers(d3dUniform->mShaderRegisterIndexes[shaderType], d3dUniform->typeInfo,
+ d3dUniform->getArraySizeProduct(), mShaderSamplers[shaderType],
+ &mUsedShaderSamplerRanges[shaderType]);
+ hasUniform = true;
+ }
+ }
+
+ ASSERT(hasUniform);
+}
+
+// static
+void ProgramD3D::AssignSamplers(unsigned int startSamplerIndex,
+ const gl::UniformTypeInfo &typeInfo,
+ unsigned int samplerCount,
+ std::vector<Sampler> &outSamplers,
+ gl::RangeUI *outUsedRange)
+{
+ unsigned int samplerIndex = startSamplerIndex;
+
+ do
+ {
+ ASSERT(samplerIndex < outSamplers.size());
+ Sampler *sampler = &outSamplers[samplerIndex];
+ sampler->active = true;
+ sampler->textureType = gl::FromGLenum<gl::TextureType>(typeInfo.textureType);
+ sampler->logicalTextureUnit = 0;
+ outUsedRange->extend(samplerIndex);
+ samplerIndex++;
+ } while (samplerIndex < startSamplerIndex + samplerCount);
+}
+
+void ProgramD3D::assignAllImageRegisters()
+{
+ for (size_t uniformIndex = 0; uniformIndex < mD3DUniforms.size(); ++uniformIndex)
+ {
+ if (mD3DUniforms[uniformIndex]->isImage() && !mD3DUniforms[uniformIndex]->isImage2D())
+ {
+ assignImageRegisters(uniformIndex);
+ }
+ }
+}
+
+void ProgramD3D::assignAllAtomicCounterRegisters()
+{
+ if (mAtomicBindingMap.empty())
+ {
+ return;
+ }
+ gl::ShaderType shaderType = gl::ShaderType::Compute;
+ const gl::Shader *computeShader = mState.getAttachedShader(shaderType);
+ if (computeShader)
+ {
+ const ShaderD3D *computeShaderD3D = GetImplAs<ShaderD3D>(computeShader);
+ auto &registerIndices = mComputeAtomicCounterBufferRegisterIndices;
+ for (auto &atomicBinding : mAtomicBindingMap)
+ {
+ ASSERT(computeShaderD3D->hasUniform(atomicBinding.first));
+ unsigned int currentRegister =
+ computeShaderD3D->getUniformRegister(atomicBinding.first);
+ ASSERT(currentRegister != GL_INVALID_INDEX);
+ const int kBinding = atomicBinding.second;
+
+ registerIndices[kBinding] = currentRegister;
+
+ mUsedAtomicCounterRange[gl::ShaderType::Compute].extend(currentRegister);
+ }
+ }
+ else
+ {
+ // Implement atomic counters for non-compute shaders
+ // http://anglebug.com/1729
+ UNIMPLEMENTED();
+ }
+}
+
+void ProgramD3D::assignImageRegisters(size_t uniformIndex)
+{
+ D3DUniform *d3dUniform = mD3DUniforms[uniformIndex];
+ ASSERT(d3dUniform->isImage());
+ // If the uniform is an array of arrays, then we have separate entries for each inner array in
+ // mD3DUniforms. However, the image register info is stored in the shader only for the
+ // outermost array.
+ std::vector<unsigned int> subscripts;
+ const std::string baseName = gl::ParseResourceName(d3dUniform->name, &subscripts);
+ unsigned int registerOffset =
+ mState.getUniforms()[uniformIndex].parentArrayIndex() * d3dUniform->getArraySizeProduct();
+
+ const gl::Shader *computeShader = mState.getAttachedShader(gl::ShaderType::Compute);
+ if (computeShader)
+ {
+ const ShaderD3D *computeShaderD3D =
+ GetImplAs<ShaderD3D>(mState.getAttachedShader(gl::ShaderType::Compute));
+ ASSERT(computeShaderD3D->hasUniform(baseName));
+ d3dUniform->mShaderRegisterIndexes[gl::ShaderType::Compute] =
+ computeShaderD3D->getUniformRegister(baseName) + registerOffset;
+ ASSERT(d3dUniform->mShaderRegisterIndexes[gl::ShaderType::Compute] != GL_INVALID_INDEX);
+ auto bindingIter = mImageBindingMap.find(baseName);
+ ASSERT(bindingIter != mImageBindingMap.end());
+ if (d3dUniform->regType == HLSLRegisterType::Texture)
+ {
+ AssignImages(d3dUniform->mShaderRegisterIndexes[gl::ShaderType::Compute],
+ bindingIter->second, d3dUniform->getArraySizeProduct(),
+ mReadonlyImages[gl::ShaderType::Compute],
+ &mUsedReadonlyImageRange[gl::ShaderType::Compute]);
+ }
+ else if (d3dUniform->regType == HLSLRegisterType::UnorderedAccessView)
+ {
+ AssignImages(d3dUniform->mShaderRegisterIndexes[gl::ShaderType::Compute],
+ bindingIter->second, d3dUniform->getArraySizeProduct(),
+ mImages[gl::ShaderType::Compute],
+ &mUsedImageRange[gl::ShaderType::Compute]);
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+ }
+ else
+ {
+ // TODO(xinghua.cao@intel.com): Implement image variables in vertex shader and pixel shader.
+ UNIMPLEMENTED();
+ }
+}
+
+// static
+void ProgramD3D::AssignImages(unsigned int startImageIndex,
+ int startLogicalImageUnit,
+ unsigned int imageCount,
+ std::vector<Image> &outImages,
+ gl::RangeUI *outUsedRange)
+{
+ unsigned int imageIndex = startImageIndex;
+
+ // If declare without a binding qualifier, any uniform image variable (include all elements of
+ // unbound image array) shoud be bound to unit zero.
+ if (startLogicalImageUnit == -1)
+ {
+ ASSERT(imageIndex < outImages.size());
+ Image *image = &outImages[imageIndex];
+ image->active = true;
+ image->logicalImageUnit = 0;
+ outUsedRange->extend(imageIndex);
+ return;
+ }
+
+ unsigned int logcalImageUnit = startLogicalImageUnit;
+ do
+ {
+ ASSERT(imageIndex < outImages.size());
+ Image *image = &outImages[imageIndex];
+ image->active = true;
+ image->logicalImageUnit = logcalImageUnit;
+ outUsedRange->extend(imageIndex);
+ imageIndex++;
+ logcalImageUnit++;
+ } while (imageIndex < startImageIndex + imageCount);
+}
+
+void ProgramD3D::assignImage2DRegisters(gl::ShaderType shaderType,
+ unsigned int startImageIndex,
+ int startLogicalImageUnit,
+ bool readonly)
+{
+ if (readonly)
+ {
+ AssignImages(startImageIndex, startLogicalImageUnit, 1, mReadonlyImages[shaderType],
+ &mUsedReadonlyImageRange[shaderType]);
+ }
+ else
+ {
+ AssignImages(startImageIndex, startLogicalImageUnit, 1, mImages[shaderType],
+ &mUsedImageRange[shaderType]);
+ }
+}
+
+void ProgramD3D::reset()
+{
+ mVertexExecutables.clear();
+ mPixelExecutables.clear();
+ mComputeExecutables.clear();
+
+ for (auto &geometryExecutable : mGeometryExecutables)
+ {
+ geometryExecutable.reset(nullptr);
+ }
+
+ for (gl::ShaderType shaderType : gl::AllShaderTypes())
+ {
+ mShaderHLSL[shaderType].clear();
+ }
+
+ mUsesFragDepth = false;
+ mHasANGLEMultiviewEnabled = false;
+ mUsesVertexID = false;
+ mUsesViewID = false;
+ mPixelShaderKey.clear();
+ mUsesPointSize = false;
+ mUsesFlatInterpolation = false;
+
+ SafeDeleteContainer(mD3DUniforms);
+ mD3DUniformBlocks.clear();
+ mD3DShaderStorageBlocks.clear();
+ mComputeAtomicCounterBufferRegisterIndices.fill({});
+
+ for (gl::ShaderType shaderType : gl::AllShaderTypes())
+ {
+ mShaderUniformStorages[shaderType].reset();
+ mShaderSamplers[shaderType].clear();
+ mImages[shaderType].clear();
+ mReadonlyImages[shaderType].clear();
+ }
+
+ mUsedShaderSamplerRanges.fill({0, 0});
+ mUsedAtomicCounterRange.fill({0, 0});
+ mDirtySamplerMapping = true;
+ mUsedImageRange.fill({0, 0});
+ mUsedReadonlyImageRange.fill({0, 0});
+
+ mAttribLocationToD3DSemantic.fill(-1);
+
+ mStreamOutVaryings.clear();
+
+ mGeometryShaderPreamble.clear();
+
+ markUniformsClean();
+
+ mCachedPixelExecutableIndex.reset();
+ mCachedVertexExecutableIndex.reset();
+}
+
+unsigned int ProgramD3D::getSerial() const
+{
+ return mSerial;
+}
+
+unsigned int ProgramD3D::issueSerial()
+{
+ return mCurrentSerial++;
+}
+
+void ProgramD3D::initAttribLocationsToD3DSemantic(const gl::Context *context)
+{
+ gl::Shader *vertexShader = mState.getAttachedShader(gl::ShaderType::Vertex);
+ if (!vertexShader)
+ {
+ return;
+ }
+
+ // Init semantic index
+ int semanticIndex = 0;
+ for (const sh::ShaderVariable &attribute : vertexShader->getActiveAttributes(context))
+ {
+ int regCount = gl::VariableRegisterCount(attribute.type);
+ GLuint location = mState.getAttributeLocation(attribute.name);
+ ASSERT(location != std::numeric_limits<GLuint>::max());
+
+ for (int reg = 0; reg < regCount; ++reg)
+ {
+ mAttribLocationToD3DSemantic[location + reg] = semanticIndex++;
+ }
+ }
+}
+
+void ProgramD3D::updateCachedInputLayout(Serial associatedSerial, const gl::State &state)
+{
+ if (mCurrentVertexArrayStateSerial == associatedSerial)
+ {
+ return;
+ }
+
+ mCurrentVertexArrayStateSerial = associatedSerial;
+ mCachedInputLayout.clear();
+
+ const auto &vertexAttributes = state.getVertexArray()->getVertexAttributes();
+ const gl::AttributesMask &attributesMask =
+ mState.getExecutable().getActiveAttribLocationsMask();
+
+ for (size_t locationIndex : attributesMask)
+ {
+ int d3dSemantic = mAttribLocationToD3DSemantic[locationIndex];
+
+ if (d3dSemantic != -1)
+ {
+ if (mCachedInputLayout.size() < static_cast<size_t>(d3dSemantic + 1))
+ {
+ mCachedInputLayout.resize(d3dSemantic + 1, angle::FormatID::NONE);
+ }
+ mCachedInputLayout[d3dSemantic] =
+ GetVertexFormatID(vertexAttributes[locationIndex],
+ state.getVertexAttribCurrentValue(locationIndex).Type);
+ }
+ }
+
+ VertexExecutable::getSignature(mRenderer, mCachedInputLayout, &mCachedVertexSignature);
+
+ updateCachedVertexExecutableIndex();
+}
+
+void ProgramD3D::updateCachedOutputLayout(const gl::Context *context,
+ const gl::Framebuffer *framebuffer)
+{
+ mPixelShaderOutputLayoutCache.clear();
+
+ FramebufferD3D *fboD3D = GetImplAs<FramebufferD3D>(framebuffer);
+ const auto &colorbuffers = fboD3D->getColorAttachmentsForRender(context);
+
+ for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment)
+ {
+ const gl::FramebufferAttachment *colorbuffer = colorbuffers[colorAttachment];
+
+ if (colorbuffer)
+ {
+ auto binding = colorbuffer->getBinding() == GL_BACK ? GL_COLOR_ATTACHMENT0
+ : colorbuffer->getBinding();
+ size_t maxIndex = binding != GL_NONE ? GetMaxOutputIndex(mPixelShaderKey,
+ binding - GL_COLOR_ATTACHMENT0)
+ : 0;
+ mPixelShaderOutputLayoutCache.insert(mPixelShaderOutputLayoutCache.end(), maxIndex + 1,
+ binding);
+ }
+ else
+ {
+ mPixelShaderOutputLayoutCache.push_back(GL_NONE);
+ }
+ }
+
+ updateCachedPixelExecutableIndex();
+}
+
+void ProgramD3D::updateCachedComputeImage2DBindLayout(const gl::Context *context)
+{
+ const auto &glState = context->getState();
+ for (auto &image2DBindLayout : mImage2DBindLayoutCache[gl::ShaderType::Compute])
+ {
+ const gl::ImageUnit &imageUnit = glState.getImageUnit(image2DBindLayout.first);
+ if (imageUnit.texture.get())
+ {
+ image2DBindLayout.second = imageUnit.texture->getType();
+ }
+ else
+ {
+ image2DBindLayout.second = gl::TextureType::_2D;
+ }
+ }
+
+ updateCachedComputeExecutableIndex();
+}
+
+void ProgramD3D::gatherTransformFeedbackVaryings(const gl::VaryingPacking &varyingPacking,
+ const BuiltinInfo &builtins)
+{
+ const std::string &varyingSemantic =
+ GetVaryingSemantic(mRenderer->getMajorShaderModel(), usesPointSize());
+
+ // Gather the linked varyings that are used for transform feedback, they should all exist.
+ mStreamOutVaryings.clear();
+
+ const auto &tfVaryingNames = mState.getTransformFeedbackVaryingNames();
+ for (unsigned int outputSlot = 0; outputSlot < static_cast<unsigned int>(tfVaryingNames.size());
+ ++outputSlot)
+ {
+ const auto &tfVaryingName = tfVaryingNames[outputSlot];
+ if (tfVaryingName == "gl_Position")
+ {
+ if (builtins.glPosition.enabled)
+ {
+ mStreamOutVaryings.emplace_back(builtins.glPosition.semantic,
+ builtins.glPosition.index, 4, outputSlot);
+ }
+ }
+ else if (tfVaryingName == "gl_FragCoord")
+ {
+ if (builtins.glFragCoord.enabled)
+ {
+ mStreamOutVaryings.emplace_back(builtins.glFragCoord.semantic,
+ builtins.glFragCoord.index, 4, outputSlot);
+ }
+ }
+ else if (tfVaryingName == "gl_PointSize")
+ {
+ if (builtins.glPointSize.enabled)
+ {
+ mStreamOutVaryings.emplace_back("PSIZE", 0, 1, outputSlot);
+ }
+ }
+ else
+ {
+ const auto &registerInfos = varyingPacking.getRegisterList();
+ for (GLuint registerIndex = 0u; registerIndex < registerInfos.size(); ++registerIndex)
+ {
+ const auto &registerInfo = registerInfos[registerIndex];
+ const auto &varying = registerInfo.packedVarying->varying();
+ GLenum transposedType = gl::TransposeMatrixType(varying.type);
+ int componentCount = gl::VariableColumnCount(transposedType);
+ ASSERT(!varying.isBuiltIn() && !varying.isStruct());
+
+ // There can be more than one register assigned to a particular varying, and each
+ // register needs its own stream out entry.
+ if (registerInfo.tfVaryingName() == tfVaryingName)
+ {
+ mStreamOutVaryings.emplace_back(varyingSemantic, registerIndex, componentCount,
+ outputSlot);
+ }
+ }
+ }
+ }
+}
+
+D3DUniform *ProgramD3D::getD3DUniformFromLocation(GLint location)
+{
+ return mD3DUniforms[mState.getUniformLocations()[location].index];
+}
+
+const D3DUniform *ProgramD3D::getD3DUniformFromLocation(GLint location) const
+{
+ return mD3DUniforms[mState.getUniformLocations()[location].index];
+}
+
+bool ProgramD3D::hasVertexExecutableForCachedInputLayout()
+{
+ return mCachedVertexExecutableIndex.valid();
+}
+
+bool ProgramD3D::hasGeometryExecutableForPrimitiveType(const gl::State &state,
+ gl::PrimitiveMode drawMode)
+{
+ if (!usesGeometryShader(state, drawMode))
+ {
+ // No shader necessary mean we have the required (null) executable.
+ return true;
+ }
+
+ gl::PrimitiveMode geometryShaderType = GetGeometryShaderTypeFromDrawMode(drawMode);
+ return mGeometryExecutables[geometryShaderType].get() != nullptr;
+}
+
+bool ProgramD3D::hasPixelExecutableForCachedOutputLayout()
+{
+ return mCachedPixelExecutableIndex.valid();
+}
+
+bool ProgramD3D::hasComputeExecutableForCachedImage2DBindLayout()
+{
+ return mCachedComputeExecutableIndex.valid();
+}
+
+template <typename DestT>
+void ProgramD3D::getUniformInternal(GLint location, DestT *dataOut) const
+{
+ const gl::VariableLocation &locationInfo = mState.getUniformLocations()[location];
+ const gl::LinkedUniform &uniform = mState.getUniforms()[locationInfo.index];
+
+ const D3DUniform *targetUniform = getD3DUniformFromLocation(location);
+ const uint8_t *srcPointer = targetUniform->getDataPtrToElement(locationInfo.arrayIndex);
+
+ if (gl::IsMatrixType(uniform.type))
+ {
+ GetMatrixUniform(uniform.type, dataOut, reinterpret_cast<const DestT *>(srcPointer), true);
+ }
+ else
+ {
+ memcpy(dataOut, srcPointer, uniform.getElementSize());
+ }
+}
+
+void ProgramD3D::getUniformfv(const gl::Context *context, GLint location, GLfloat *params) const
+{
+ getUniformInternal(location, params);
+}
+
+void ProgramD3D::getUniformiv(const gl::Context *context, GLint location, GLint *params) const
+{
+ getUniformInternal(location, params);
+}
+
+void ProgramD3D::getUniformuiv(const gl::Context *context, GLint location, GLuint *params) const
+{
+ getUniformInternal(location, params);
+}
+
+void ProgramD3D::updateCachedVertexExecutableIndex()
+{
+ mCachedVertexExecutableIndex.reset();
+ for (size_t executableIndex = 0; executableIndex < mVertexExecutables.size(); executableIndex++)
+ {
+ if (mVertexExecutables[executableIndex]->matchesSignature(mCachedVertexSignature))
+ {
+ mCachedVertexExecutableIndex = executableIndex;
+ break;
+ }
+ }
+}
+
+void ProgramD3D::updateCachedPixelExecutableIndex()
+{
+ mCachedPixelExecutableIndex.reset();
+ for (size_t executableIndex = 0; executableIndex < mPixelExecutables.size(); executableIndex++)
+ {
+ if (mPixelExecutables[executableIndex]->matchesSignature(mPixelShaderOutputLayoutCache))
+ {
+ mCachedPixelExecutableIndex = executableIndex;
+ break;
+ }
+ }
+}
+
+void ProgramD3D::updateCachedComputeExecutableIndex()
+{
+ mCachedComputeExecutableIndex.reset();
+ for (size_t executableIndex = 0; executableIndex < mComputeExecutables.size();
+ executableIndex++)
+ {
+ if (mComputeExecutables[executableIndex]->matchesSignature(
+ mImage2DBindLayoutCache[gl::ShaderType::Compute]))
+ {
+ mCachedComputeExecutableIndex = executableIndex;
+ break;
+ }
+ }
+}
+
+void ProgramD3D::linkResources(const gl::Context *context,
+ const gl::ProgramLinkedResources &resources)
+{
+ HLSLBlockLayoutEncoderFactory hlslEncoderFactory;
+ gl::ProgramLinkedResourcesLinker linker(&hlslEncoderFactory);
+
+ linker.linkResources(context, mState, resources);
+
+ initializeUniformBlocks();
+ initializeShaderStorageBlocks(context);
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/ProgramD3D.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/ProgramD3D.h
new file mode 100644
index 0000000000..baa77fcb79
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/ProgramD3D.h
@@ -0,0 +1,613 @@
+//
+// 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.
+//
+
+// ProgramD3D.h: Defines the rx::ProgramD3D class which implements rx::ProgramImpl.
+
+#ifndef LIBANGLE_RENDERER_D3D_PROGRAMD3D_H_
+#define LIBANGLE_RENDERER_D3D_PROGRAMD3D_H_
+
+#include <string>
+#include <vector>
+
+#include "compiler/translator/blocklayoutHLSL.h"
+#include "libANGLE/Constants.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/ProgramImpl.h"
+#include "libANGLE/renderer/d3d/DynamicHLSL.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
+#include "platform/FeaturesD3D_autogen.h"
+
+namespace rx
+{
+class RendererD3D;
+class UniformStorageD3D;
+class ShaderExecutableD3D;
+
+#if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL)
+// WARNING: D3DCOMPILE_OPTIMIZATION_LEVEL3 may lead to a DX9 shader compiler hang.
+// It should only be used selectively to work around specific bugs.
+# define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL1
+#endif
+
+enum class HLSLRegisterType : uint8_t
+{
+ None = 0,
+ Texture = 1,
+ UnorderedAccessView = 2
+};
+
+// Helper struct representing a single shader uniform
+// TODO(jmadill): Make uniform blocks shared between all programs, so we don't need separate
+// register indices.
+struct D3DUniform : private angle::NonCopyable
+{
+ D3DUniform(GLenum type,
+ HLSLRegisterType reg,
+ const std::string &nameIn,
+ const std::vector<unsigned int> &arraySizesIn,
+ bool defaultBlock);
+ ~D3DUniform();
+
+ bool isSampler() const;
+ bool isImage() const;
+ bool isImage2D() const;
+ bool isArray() const { return !arraySizes.empty(); }
+ unsigned int getArraySizeProduct() const;
+ bool isReferencedByShader(gl::ShaderType shaderType) const;
+
+ const uint8_t *firstNonNullData() const;
+ const uint8_t *getDataPtrToElement(size_t elementIndex) const;
+
+ // Duplicated from the GL layer
+ const gl::UniformTypeInfo &typeInfo;
+ std::string name; // Names of arrays don't include [0], unlike at the GL layer.
+ std::vector<unsigned int> arraySizes;
+
+ // Pointer to a system copies of the data. Separate pointers for each uniform storage type.
+ gl::ShaderMap<uint8_t *> mShaderData;
+
+ // Register information.
+ HLSLRegisterType regType;
+ gl::ShaderMap<unsigned int> mShaderRegisterIndexes;
+ unsigned int registerCount;
+
+ // Register "elements" are used for uniform structs in ES3, to appropriately identify single
+ // uniforms
+ // inside aggregate types, which are packed according C-like structure rules.
+ unsigned int registerElement;
+
+ // Special buffer for sampler values.
+ std::vector<GLint> mSamplerData;
+};
+
+struct D3DInterfaceBlock
+{
+ D3DInterfaceBlock();
+ D3DInterfaceBlock(const D3DInterfaceBlock &other);
+
+ bool activeInShader(gl::ShaderType shaderType) const
+ {
+ return mShaderRegisterIndexes[shaderType] != GL_INVALID_INDEX;
+ }
+
+ gl::ShaderMap<unsigned int> mShaderRegisterIndexes;
+};
+
+struct D3DUniformBlock : D3DInterfaceBlock
+{
+ D3DUniformBlock();
+ D3DUniformBlock(const D3DUniformBlock &other);
+
+ gl::ShaderMap<bool> mUseStructuredBuffers;
+ gl::ShaderMap<unsigned int> mByteWidths;
+ gl::ShaderMap<unsigned int> mStructureByteStrides;
+};
+
+struct ShaderStorageBlock
+{
+ std::string name;
+ unsigned int arraySize = 0;
+ unsigned int registerIndex = 0;
+};
+
+struct D3DUBOCache
+{
+ unsigned int registerIndex;
+ int binding;
+};
+
+struct D3DUBOCacheUseSB : D3DUBOCache
+{
+ unsigned int byteWidth;
+ unsigned int structureByteStride;
+};
+
+struct D3DVarying final
+{
+ D3DVarying();
+ D3DVarying(const std::string &semanticNameIn,
+ unsigned int semanticIndexIn,
+ unsigned int componentCountIn,
+ unsigned int outputSlotIn);
+
+ D3DVarying(const D3DVarying &) = default;
+ D3DVarying &operator=(const D3DVarying &) = default;
+
+ std::string semanticName;
+ unsigned int semanticIndex;
+ unsigned int componentCount;
+ unsigned int outputSlot;
+};
+
+class ProgramD3DMetadata final : angle::NonCopyable
+{
+ public:
+ ProgramD3DMetadata(RendererD3D *renderer,
+ const gl::ShaderMap<const ShaderD3D *> &attachedShaders,
+ EGLenum clientType);
+ ~ProgramD3DMetadata();
+
+ int getRendererMajorShaderModel() const;
+ bool usesBroadcast(const gl::State &data) const;
+ bool usesSecondaryColor() const;
+ bool usesFragDepth() const;
+ bool usesPointCoord() const;
+ bool usesFragCoord() const;
+ bool usesPointSize() const;
+ bool usesInsertedPointCoordValue() const;
+ bool usesViewScale() const;
+ bool hasANGLEMultiviewEnabled() const;
+ bool usesVertexID() const;
+ bool usesViewID() const;
+ bool canSelectViewInVertexShader() const;
+ bool addsPointCoordToVertexShader() const;
+ bool usesTransformFeedbackGLPosition() const;
+ bool usesSystemValuePointSize() const;
+ bool usesMultipleFragmentOuts() const;
+ bool usesCustomOutVars() const;
+ const ShaderD3D *getFragmentShader() const;
+
+ private:
+ const int mRendererMajorShaderModel;
+ const std::string mShaderModelSuffix;
+ const bool mUsesInstancedPointSpriteEmulation;
+ const bool mUsesViewScale;
+ const bool mCanSelectViewInVertexShader;
+ const gl::ShaderMap<const ShaderD3D *> mAttachedShaders;
+ const EGLenum mClientType;
+};
+
+using D3DUniformMap = std::map<std::string, D3DUniform *>;
+
+class ProgramD3D : public ProgramImpl
+{
+ public:
+ ProgramD3D(const gl::ProgramState &data, RendererD3D *renderer);
+ ~ProgramD3D() override;
+
+ const std::vector<PixelShaderOutputVariable> &getPixelShaderKey() { return mPixelShaderKey; }
+
+ GLint getSamplerMapping(gl::ShaderType type,
+ unsigned int samplerIndex,
+ const gl::Caps &caps) const;
+ gl::TextureType getSamplerTextureType(gl::ShaderType type, unsigned int samplerIndex) const;
+ gl::RangeUI getUsedSamplerRange(gl::ShaderType type) const;
+
+ enum SamplerMapping
+ {
+ WasDirty,
+ WasClean,
+ };
+
+ SamplerMapping updateSamplerMapping();
+
+ GLint getImageMapping(gl::ShaderType type,
+ unsigned int imageIndex,
+ bool readonly,
+ const gl::Caps &caps) const;
+ gl::RangeUI getUsedImageRange(gl::ShaderType type, bool readonly) const;
+
+ bool usesPointSize() const { return mUsesPointSize; }
+ bool usesPointSpriteEmulation() const;
+ bool usesGeometryShader(const gl::State &state, gl::PrimitiveMode drawMode) const;
+ bool usesGeometryShaderForPointSpriteEmulation() const;
+ bool usesGetDimensionsIgnoresBaseLevel() const;
+ bool usesInstancedPointSpriteEmulation() const;
+
+ std::unique_ptr<LinkEvent> load(const gl::Context *context,
+ gl::BinaryInputStream *stream,
+ gl::InfoLog &infoLog) override;
+ void save(const gl::Context *context, gl::BinaryOutputStream *stream) override;
+ void setBinaryRetrievableHint(bool retrievable) override;
+ void setSeparable(bool separable) override;
+
+ angle::Result getVertexExecutableForCachedInputLayout(d3d::Context *context,
+ ShaderExecutableD3D **outExectuable,
+ gl::InfoLog *infoLog);
+ angle::Result getGeometryExecutableForPrimitiveType(d3d::Context *errContext,
+ const gl::State &state,
+ gl::PrimitiveMode drawMode,
+ ShaderExecutableD3D **outExecutable,
+ gl::InfoLog *infoLog);
+ angle::Result getPixelExecutableForCachedOutputLayout(d3d::Context *context,
+ ShaderExecutableD3D **outExectuable,
+ gl::InfoLog *infoLog);
+ angle::Result getComputeExecutableForImage2DBindLayout(const gl::Context *glContext,
+ d3d::Context *context,
+ ShaderExecutableD3D **outExecutable,
+ gl::InfoLog *infoLog);
+ std::unique_ptr<LinkEvent> link(const gl::Context *context,
+ const gl::ProgramLinkedResources &resources,
+ gl::InfoLog &infoLog,
+ const gl::ProgramMergedVaryings &mergedVaryings) override;
+ GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) override;
+
+ void updateUniformBufferCache(const gl::Caps &caps);
+
+ unsigned int getAtomicCounterBufferRegisterIndex(GLuint binding,
+ gl::ShaderType shaderType) const;
+
+ unsigned int getShaderStorageBufferRegisterIndex(GLuint blockIndex,
+ gl::ShaderType shaderType) const;
+ const std::vector<D3DUBOCache> &getShaderUniformBufferCache(gl::ShaderType shaderType) const;
+ const std::vector<D3DUBOCacheUseSB> &getShaderUniformBufferCacheUseSB(
+ gl::ShaderType shaderType) const;
+
+ void dirtyAllUniforms();
+
+ 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;
+
+ void getUniformfv(const gl::Context *context, GLint location, GLfloat *params) const override;
+ void getUniformiv(const gl::Context *context, GLint location, GLint *params) const override;
+ void getUniformuiv(const gl::Context *context, GLint location, GLuint *params) const override;
+
+ UniformStorageD3D *getShaderUniformStorage(gl::ShaderType shaderType) const
+ {
+ return mShaderUniformStorages[shaderType].get();
+ }
+
+ unsigned int getSerial() const;
+
+ const AttribIndexArray &getAttribLocationToD3DSemantics() const
+ {
+ return mAttribLocationToD3DSemantic;
+ }
+
+ void updateCachedInputLayout(Serial associatedSerial, const gl::State &state);
+ void updateCachedOutputLayout(const gl::Context *context, const gl::Framebuffer *framebuffer);
+ void updateCachedComputeImage2DBindLayout(const gl::Context *context);
+
+ bool isSamplerMappingDirty() { return mDirtySamplerMapping; }
+
+ // Checks if we need to recompile certain shaders.
+ bool hasVertexExecutableForCachedInputLayout();
+ bool hasGeometryExecutableForPrimitiveType(const gl::State &state, gl::PrimitiveMode drawMode);
+ bool hasPixelExecutableForCachedOutputLayout();
+ bool hasComputeExecutableForCachedImage2DBindLayout();
+
+ bool anyShaderUniformsDirty() const { return mShaderUniformsDirty.any(); }
+
+ bool areShaderUniformsDirty(gl::ShaderType shaderType) const
+ {
+ return mShaderUniformsDirty[shaderType];
+ }
+ const std::vector<D3DUniform *> &getD3DUniforms() const { return mD3DUniforms; }
+ void markUniformsClean();
+
+ const gl::ProgramState &getState() const { return mState; }
+
+ bool hasShaderStage(gl::ShaderType shaderType) const
+ {
+ return mState.getExecutable().getLinkedShaderStages()[shaderType];
+ }
+
+ void assignImage2DRegisters(gl::ShaderType shaderType,
+ unsigned int startImageIndex,
+ int startLogicalImageUnit,
+ bool readonly);
+ bool hasNamedUniform(const std::string &name);
+
+ bool usesVertexID() const { return mUsesVertexID; }
+
+ private:
+ // These forward-declared tasks are used for multi-thread shader compiles.
+ class GetExecutableTask;
+ class GetVertexExecutableTask;
+ class GetPixelExecutableTask;
+ class GetGeometryExecutableTask;
+ class GetComputeExecutableTask;
+ class GraphicsProgramLinkEvent;
+ class ComputeProgramLinkEvent;
+
+ class LoadBinaryTask;
+ class LoadBinaryLinkEvent;
+
+ class VertexExecutable
+ {
+ public:
+ enum HLSLAttribType
+ {
+ FLOAT,
+ UNSIGNED_INT,
+ SIGNED_INT,
+ };
+
+ typedef std::vector<HLSLAttribType> Signature;
+
+ VertexExecutable(const gl::InputLayout &inputLayout,
+ const Signature &signature,
+ ShaderExecutableD3D *shaderExecutable);
+ ~VertexExecutable();
+
+ bool matchesSignature(const Signature &signature) const;
+ static void getSignature(RendererD3D *renderer,
+ const gl::InputLayout &inputLayout,
+ Signature *signatureOut);
+
+ const gl::InputLayout &inputs() const { return mInputs; }
+ const Signature &signature() const { return mSignature; }
+ ShaderExecutableD3D *shaderExecutable() const { return mShaderExecutable; }
+
+ private:
+ static HLSLAttribType GetAttribType(GLenum type);
+
+ gl::InputLayout mInputs;
+ Signature mSignature;
+ ShaderExecutableD3D *mShaderExecutable;
+ };
+
+ class PixelExecutable
+ {
+ public:
+ PixelExecutable(const std::vector<GLenum> &outputSignature,
+ ShaderExecutableD3D *shaderExecutable);
+ ~PixelExecutable();
+
+ bool matchesSignature(const std::vector<GLenum> &signature) const
+ {
+ return mOutputSignature == signature;
+ }
+
+ const std::vector<GLenum> &outputSignature() const { return mOutputSignature; }
+ ShaderExecutableD3D *shaderExecutable() const { return mShaderExecutable; }
+
+ private:
+ std::vector<GLenum> mOutputSignature;
+ ShaderExecutableD3D *mShaderExecutable;
+ };
+
+ class ComputeExecutable
+ {
+ public:
+ ComputeExecutable(const gl::ImageUnitTextureTypeMap &signature,
+ std::unique_ptr<ShaderExecutableD3D> shaderExecutable);
+ ~ComputeExecutable();
+
+ bool matchesSignature(const gl::ImageUnitTextureTypeMap &signature) const
+ {
+ return mSignature == signature;
+ }
+
+ const gl::ImageUnitTextureTypeMap &signature() const { return mSignature; }
+ ShaderExecutableD3D *shaderExecutable() const { return mShaderExecutable.get(); }
+
+ private:
+ gl::ImageUnitTextureTypeMap mSignature;
+ std::unique_ptr<ShaderExecutableD3D> mShaderExecutable;
+ };
+
+ struct Sampler
+ {
+ Sampler();
+
+ bool active;
+ GLint logicalTextureUnit;
+ gl::TextureType textureType;
+ };
+
+ struct Image
+ {
+ Image();
+ bool active;
+ GLint logicalImageUnit;
+ };
+
+ void initializeUniformStorage(const gl::ShaderBitSet &availableShaderStages);
+
+ void defineUniformsAndAssignRegisters(const gl::Context *context);
+ void defineUniformBase(const gl::Shader *shader,
+ const sh::ShaderVariable &uniform,
+ D3DUniformMap *uniformMap);
+ void assignAllSamplerRegisters();
+ void assignSamplerRegisters(size_t uniformIndex);
+
+ static void AssignSamplers(unsigned int startSamplerIndex,
+ const gl::UniformTypeInfo &typeInfo,
+ unsigned int samplerCount,
+ std::vector<Sampler> &outSamplers,
+ gl::RangeUI *outUsedRange);
+
+ void assignAllImageRegisters();
+ void assignAllAtomicCounterRegisters();
+ void assignImageRegisters(size_t uniformIndex);
+ static void AssignImages(unsigned int startImageIndex,
+ int startLogicalImageUnit,
+ unsigned int imageCount,
+ std::vector<Image> &outImages,
+ gl::RangeUI *outUsedRange);
+
+ template <typename DestT>
+ void getUniformInternal(GLint location, DestT *dataOut) const;
+
+ template <typename T>
+ void setUniformImpl(D3DUniform *targetUniform,
+ const gl::VariableLocation &locationInfo,
+ GLsizei count,
+ const T *v,
+ uint8_t *targetData,
+ GLenum uniformType);
+
+ template <typename T>
+ void setUniformInternal(GLint location, GLsizei count, const T *v, GLenum uniformType);
+
+ template <int cols, int rows>
+ void setUniformMatrixfvInternal(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+
+ std::unique_ptr<LinkEvent> compileProgramExecutables(const gl::Context *context,
+ gl::InfoLog &infoLog);
+ std::unique_ptr<LinkEvent> compileComputeExecutable(const gl::Context *context,
+ gl::InfoLog &infoLog);
+
+ angle::Result loadBinaryShaderExecutables(d3d::Context *contextD3D,
+ gl::BinaryInputStream *stream,
+ gl::InfoLog &infoLog);
+
+ void gatherTransformFeedbackVaryings(const gl::VaryingPacking &varyings,
+ const BuiltinInfo &builtins);
+ D3DUniform *getD3DUniformFromLocation(GLint location);
+ const D3DUniform *getD3DUniformFromLocation(GLint location) const;
+
+ void initAttribLocationsToD3DSemantic(const gl::Context *context);
+
+ void reset();
+ void initializeUniformBlocks();
+ void initializeShaderStorageBlocks(const gl::Context *context);
+
+ void updateCachedInputLayoutFromShader(const gl::Context *context);
+ void updateCachedOutputLayoutFromShader();
+ void updateCachedImage2DBindLayoutFromShader(gl::ShaderType shaderType);
+ void updateCachedVertexExecutableIndex();
+ void updateCachedPixelExecutableIndex();
+ void updateCachedComputeExecutableIndex();
+
+ void linkResources(const gl::Context *context, const gl::ProgramLinkedResources &resources);
+
+ RendererD3D *mRenderer;
+ DynamicHLSL *mDynamicHLSL;
+
+ std::vector<std::unique_ptr<VertexExecutable>> mVertexExecutables;
+ std::vector<std::unique_ptr<PixelExecutable>> mPixelExecutables;
+ angle::PackedEnumMap<gl::PrimitiveMode, std::unique_ptr<ShaderExecutableD3D>>
+ mGeometryExecutables;
+ std::vector<std::unique_ptr<ComputeExecutable>> mComputeExecutables;
+
+ gl::ShaderMap<std::string> mShaderHLSL;
+ gl::ShaderMap<CompilerWorkaroundsD3D> mShaderWorkarounds;
+
+ bool mUsesFragDepth;
+ bool mHasANGLEMultiviewEnabled;
+ bool mUsesVertexID;
+ bool mUsesViewID;
+ std::vector<PixelShaderOutputVariable> mPixelShaderKey;
+
+ // Common code for all dynamic geometry shaders. Consists mainly of the GS input and output
+ // structures, built from the linked varying info. We store the string itself instead of the
+ // packed varyings for simplicity.
+ std::string mGeometryShaderPreamble;
+
+ bool mUsesPointSize;
+ bool mUsesFlatInterpolation;
+
+ gl::ShaderMap<std::unique_ptr<UniformStorageD3D>> mShaderUniformStorages;
+
+ gl::ShaderMap<std::vector<Sampler>> mShaderSamplers;
+ gl::ShaderMap<gl::RangeUI> mUsedShaderSamplerRanges;
+ bool mDirtySamplerMapping;
+
+ gl::ShaderMap<std::vector<Image>> mImages;
+ gl::ShaderMap<std::vector<Image>> mReadonlyImages;
+ gl::ShaderMap<gl::RangeUI> mUsedImageRange;
+ gl::ShaderMap<gl::RangeUI> mUsedReadonlyImageRange;
+ gl::ShaderMap<gl::RangeUI> mUsedAtomicCounterRange;
+
+ // Cache for pixel shader output layout to save reallocations.
+ std::vector<GLenum> mPixelShaderOutputLayoutCache;
+ Optional<size_t> mCachedPixelExecutableIndex;
+
+ AttribIndexArray mAttribLocationToD3DSemantic;
+
+ unsigned int mSerial;
+
+ gl::ShaderMap<std::vector<D3DUBOCache>> mShaderUBOCaches;
+ gl::ShaderMap<std::vector<D3DUBOCacheUseSB>> mShaderUBOCachesUseSB;
+ VertexExecutable::Signature mCachedVertexSignature;
+ gl::InputLayout mCachedInputLayout;
+ Optional<size_t> mCachedVertexExecutableIndex;
+
+ std::vector<D3DVarying> mStreamOutVaryings;
+ std::vector<D3DUniform *> mD3DUniforms;
+ std::map<std::string, int> mImageBindingMap;
+ std::map<std::string, int> mAtomicBindingMap;
+ std::vector<D3DUniformBlock> mD3DUniformBlocks;
+ std::vector<D3DInterfaceBlock> mD3DShaderStorageBlocks;
+ gl::ShaderMap<std::vector<ShaderStorageBlock>> mShaderStorageBlocks;
+ std::array<unsigned int, gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS>
+ mComputeAtomicCounterBufferRegisterIndices;
+
+ gl::ShaderMap<std::vector<sh::ShaderVariable>> mImage2DUniforms;
+ gl::ShaderMap<gl::ImageUnitTextureTypeMap> mImage2DBindLayoutCache;
+ Optional<size_t> mCachedComputeExecutableIndex;
+
+ gl::ShaderBitSet mShaderUniformsDirty;
+
+ static unsigned int issueSerial();
+ static unsigned int mCurrentSerial;
+
+ Serial mCurrentVertexArrayStateSerial;
+};
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_PROGRAMD3D_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/RenderTargetD3D.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/RenderTargetD3D.cpp
new file mode 100644
index 0000000000..4529a9d84e
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/RenderTargetD3D.cpp
@@ -0,0 +1,31 @@
+//
+// Copyright 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.
+//
+
+// RenderTargetD3D.cpp: Implements serial handling for rx::RenderTargetD3D
+
+#include "libANGLE/renderer/d3d/RenderTargetD3D.h"
+
+namespace rx
+{
+unsigned int RenderTargetD3D::mCurrentSerial = 1;
+
+RenderTargetD3D::RenderTargetD3D() : mSerial(issueSerials(1)) {}
+
+RenderTargetD3D::~RenderTargetD3D() {}
+
+unsigned int RenderTargetD3D::getSerial() const
+{
+ return mSerial;
+}
+
+unsigned int RenderTargetD3D::issueSerials(unsigned int count)
+{
+ unsigned int firstSerial = mCurrentSerial;
+ mCurrentSerial += count;
+ return firstSerial;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/RenderTargetD3D.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/RenderTargetD3D.h
new file mode 100644
index 0000000000..b5bed63bcd
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/RenderTargetD3D.h
@@ -0,0 +1,44 @@
+//
+// Copyright 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.
+//
+
+// RenderTargetD3D.h: Defines an abstract wrapper class to manage IDirect3DSurface9
+// and ID3D11View objects belonging to renderbuffers and renderable textures.
+
+#ifndef LIBANGLE_RENDERER_D3D_RENDERTARGETD3D_H_
+#define LIBANGLE_RENDERER_D3D_RENDERTARGETD3D_H_
+
+#include "common/angleutils.h"
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/angletypes.h"
+
+namespace rx
+{
+
+class RenderTargetD3D : public FramebufferAttachmentRenderTarget
+{
+ public:
+ RenderTargetD3D();
+ ~RenderTargetD3D() override;
+
+ virtual GLsizei getWidth() const = 0;
+ virtual GLsizei getHeight() const = 0;
+ virtual GLsizei getDepth() const = 0;
+ virtual GLenum getInternalFormat() const = 0;
+ virtual GLsizei getSamples() const = 0;
+ gl::Extents getExtents() const { return gl::Extents(getWidth(), getHeight(), getDepth()); }
+ bool isMultisampled() const { return getSamples() > 0; }
+
+ virtual unsigned int getSerial() const;
+ static unsigned int issueSerials(unsigned int count);
+
+ private:
+ const unsigned int mSerial;
+ static unsigned int mCurrentSerial;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_RENDERTARGETD3D_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/RenderbufferD3D.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/RenderbufferD3D.cpp
new file mode 100644
index 0000000000..9114b88f3f
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/RenderbufferD3D.cpp
@@ -0,0 +1,126 @@
+//
+// 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.
+//
+
+// RenderbufferD3d.cpp: Implements the RenderbufferD3D class, a specialization of RenderbufferImpl
+
+#include "libANGLE/renderer/d3d/RenderbufferD3D.h"
+
+#include "libANGLE/Context.h"
+#include "libANGLE/Image.h"
+#include "libANGLE/renderer/d3d/ContextD3D.h"
+#include "libANGLE/renderer/d3d/EGLImageD3D.h"
+#include "libANGLE/renderer/d3d/RenderTargetD3D.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
+
+namespace rx
+{
+RenderbufferD3D::RenderbufferD3D(const gl::RenderbufferState &state, RendererD3D *renderer)
+ : RenderbufferImpl(state), mRenderer(renderer), mRenderTarget(nullptr), mImage(nullptr)
+{}
+
+RenderbufferD3D::~RenderbufferD3D()
+{
+ SafeDelete(mRenderTarget);
+ mImage = nullptr;
+}
+
+void RenderbufferD3D::onDestroy(const gl::Context *context)
+{
+ SafeDelete(mRenderTarget);
+}
+
+angle::Result RenderbufferD3D::setStorage(const gl::Context *context,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height)
+{
+ return setStorageMultisample(context, 0, internalformat, width, height,
+ gl::MultisamplingMode::Regular);
+}
+
+angle::Result RenderbufferD3D::setStorageMultisample(const gl::Context *context,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ gl::MultisamplingMode mode)
+{
+ // TODO: Correctly differentiate between normal multisampling and render to texture. In the
+ // latter case, the renderbuffer must be automatically resolved when rendering is broken and
+ // operations performed on it (such as blit, copy etc) should use the resolved image.
+ // http://anglebug.com/3107.
+
+ // If the renderbuffer parameters are queried, the calling function
+ // will expect one of the valid renderbuffer formats for use in
+ // glRenderbufferStorage, but we should create depth and stencil buffers
+ // as DEPTH24_STENCIL8
+ GLenum creationFormat = internalformat;
+ if (internalformat == GL_DEPTH_COMPONENT16 || internalformat == GL_STENCIL_INDEX8)
+ {
+ creationFormat = GL_DEPTH24_STENCIL8_OES;
+ }
+
+ // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
+ // the specified storage.
+ // Because ES 3.0 already knows the exact number of supported samples, it would already have
+ // been validated and generated GL_INVALID_VALUE.
+ const gl::TextureCaps &formatCaps = mRenderer->getNativeTextureCaps().get(creationFormat);
+ ANGLE_CHECK_GL_ALLOC(GetImplAs<ContextD3D>(context),
+ static_cast<uint32_t>(samples) <= formatCaps.getMaxSamples());
+
+ RenderTargetD3D *newRT = nullptr;
+ ANGLE_TRY(
+ mRenderer->createRenderTarget(context, width, height, creationFormat, samples, &newRT));
+
+ SafeDelete(mRenderTarget);
+ mImage = nullptr;
+ mRenderTarget = newRT;
+
+ return angle::Result::Continue;
+}
+
+angle::Result RenderbufferD3D::setStorageEGLImageTarget(const gl::Context *context,
+ egl::Image *image)
+{
+ mImage = GetImplAs<EGLImageD3D>(image);
+ SafeDelete(mRenderTarget);
+
+ return angle::Result::Continue;
+}
+
+angle::Result RenderbufferD3D::getRenderTarget(const gl::Context *context,
+ RenderTargetD3D **outRenderTarget)
+{
+ if (mImage)
+ {
+ return mImage->getRenderTarget(context, outRenderTarget);
+ }
+ else
+ {
+ *outRenderTarget = mRenderTarget;
+ return angle::Result::Continue;
+ }
+}
+
+angle::Result RenderbufferD3D::getAttachmentRenderTarget(const gl::Context *context,
+ GLenum binding,
+ const gl::ImageIndex &imageIndex,
+ GLsizei samples,
+ FramebufferAttachmentRenderTarget **rtOut)
+{
+ return getRenderTarget(context, reinterpret_cast<RenderTargetD3D **>(rtOut));
+}
+
+angle::Result RenderbufferD3D::initializeContents(const gl::Context *context,
+ GLenum binding,
+ const gl::ImageIndex &imageIndex)
+{
+ RenderTargetD3D *renderTarget = nullptr;
+ ANGLE_TRY(getRenderTarget(context, &renderTarget));
+ return mRenderer->initRenderTarget(context, renderTarget);
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/RenderbufferD3D.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/RenderbufferD3D.h
new file mode 100644
index 0000000000..7b48c48073
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/RenderbufferD3D.h
@@ -0,0 +1,63 @@
+//
+// 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.
+//
+
+// RenderbufferD3d.h: Defines the RenderbufferD3D class which implements RenderbufferImpl.
+
+#ifndef LIBANGLE_RENDERER_D3D_RENDERBUFFERD3D_H_
+#define LIBANGLE_RENDERER_D3D_RENDERBUFFERD3D_H_
+
+#include "angle_gl.h"
+
+#include "common/angleutils.h"
+#include "libANGLE/renderer/RenderbufferImpl.h"
+
+namespace rx
+{
+class EGLImageD3D;
+class RendererD3D;
+class RenderTargetD3D;
+class SwapChainD3D;
+
+class RenderbufferD3D : public RenderbufferImpl
+{
+ public:
+ RenderbufferD3D(const gl::RenderbufferState &state, RendererD3D *renderer);
+ ~RenderbufferD3D() override;
+
+ void onDestroy(const gl::Context *context) override;
+
+ angle::Result setStorage(const gl::Context *context,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height) override;
+ angle::Result setStorageMultisample(const gl::Context *context,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ gl::MultisamplingMode mode) override;
+ angle::Result setStorageEGLImageTarget(const gl::Context *context, egl::Image *image) override;
+
+ angle::Result getRenderTarget(const gl::Context *context, RenderTargetD3D **outRenderTarget);
+ angle::Result getAttachmentRenderTarget(const gl::Context *context,
+ GLenum binding,
+ const gl::ImageIndex &imageIndex,
+ GLsizei samples,
+ FramebufferAttachmentRenderTarget **rtOut) override;
+
+ angle::Result initializeContents(const gl::Context *context,
+ GLenum binding,
+ const gl::ImageIndex &imageIndex) override;
+
+ private:
+ RendererD3D *mRenderer;
+ RenderTargetD3D *mRenderTarget;
+ EGLImageD3D *mImage;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_RENDERBUFFERD3D_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/RendererD3D.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/RendererD3D.cpp
new file mode 100644
index 0000000000..39e6e536dd
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/RendererD3D.cpp
@@ -0,0 +1,247 @@
+//
+// 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.
+//
+
+// RendererD3D.cpp: Implementation of the base D3D Renderer.
+
+#include "libANGLE/renderer/d3d/RendererD3D.h"
+
+#include "common/MemoryBuffer.h"
+#include "common/debug.h"
+#include "common/utilities.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Display.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/ImageIndex.h"
+#include "libANGLE/ResourceManager.h"
+#include "libANGLE/State.h"
+#include "libANGLE/VertexArray.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/ContextImpl.h"
+#include "libANGLE/renderer/TextureImpl.h"
+#include "libANGLE/renderer/d3d/BufferD3D.h"
+#include "libANGLE/renderer/d3d/DeviceD3D.h"
+#include "libANGLE/renderer/d3d/DisplayD3D.h"
+#include "libANGLE/renderer/d3d/IndexDataManager.h"
+#include "libANGLE/renderer/d3d/ProgramD3D.h"
+#include "libANGLE/renderer/d3d/SamplerD3D.h"
+#include "libANGLE/renderer/d3d/TextureD3D.h"
+
+namespace rx
+{
+
+RendererD3D::RendererD3D(egl::Display *display)
+ : mDisplay(display),
+ mPresentPathFastEnabled(false),
+ mCapsInitialized(false),
+ mFeaturesInitialized(false),
+ mDisjoint(false),
+ mDeviceLost(false)
+{}
+
+RendererD3D::~RendererD3D() {}
+
+bool RendererD3D::skipDraw(const gl::State &glState, gl::PrimitiveMode drawMode)
+{
+ if (drawMode == gl::PrimitiveMode::Points)
+ {
+ bool usesPointSize = GetImplAs<ProgramD3D>(glState.getProgram())->usesPointSize();
+
+ // ProgramBinary assumes non-point rendering if gl_PointSize isn't written,
+ // which affects varying interpolation. Since the value of gl_PointSize is
+ // undefined when not written, just skip drawing to avoid unexpected results.
+ if (!usesPointSize && !glState.isTransformFeedbackActiveUnpaused())
+ {
+ // Notify developers of risking undefined behavior.
+ WARN() << "Point rendering without writing to gl_PointSize.";
+ return true;
+ }
+ }
+ else if (gl::IsTriangleMode(drawMode))
+ {
+ if (glState.getRasterizerState().cullFace &&
+ glState.getRasterizerState().cullMode == gl::CullFaceMode::FrontAndBack)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+gl::GraphicsResetStatus RendererD3D::getResetStatus()
+{
+ if (!mDeviceLost)
+ {
+ if (testDeviceLost())
+ {
+ mDeviceLost = true;
+ notifyDeviceLost();
+ return gl::GraphicsResetStatus::UnknownContextReset;
+ }
+ return gl::GraphicsResetStatus::NoError;
+ }
+
+ if (testDeviceResettable())
+ {
+ return gl::GraphicsResetStatus::NoError;
+ }
+
+ return gl::GraphicsResetStatus::UnknownContextReset;
+}
+
+void RendererD3D::notifyDeviceLost()
+{
+ mDisplay->notifyDeviceLost();
+}
+
+void RendererD3D::setGPUDisjoint()
+{
+ mDisjoint = true;
+}
+
+GLint RendererD3D::getGPUDisjoint()
+{
+ bool disjoint = mDisjoint;
+
+ // Disjoint flag is cleared when read
+ mDisjoint = false;
+
+ return disjoint;
+}
+
+GLint64 RendererD3D::getTimestamp()
+{
+ // D3D has no way to get an actual timestamp reliably so 0 is returned
+ return 0;
+}
+
+void RendererD3D::ensureCapsInitialized() const
+{
+ if (!mCapsInitialized)
+ {
+ generateCaps(&mNativeCaps, &mNativeTextureCaps, &mNativeExtensions, &mNativeLimitations);
+ mCapsInitialized = true;
+ }
+}
+
+const gl::Caps &RendererD3D::getNativeCaps() const
+{
+ ensureCapsInitialized();
+ return mNativeCaps;
+}
+
+const gl::TextureCapsMap &RendererD3D::getNativeTextureCaps() const
+{
+ ensureCapsInitialized();
+ return mNativeTextureCaps;
+}
+
+const gl::Extensions &RendererD3D::getNativeExtensions() const
+{
+ ensureCapsInitialized();
+ return mNativeExtensions;
+}
+
+const gl::Limitations &RendererD3D::getNativeLimitations() const
+{
+ ensureCapsInitialized();
+ return mNativeLimitations;
+}
+
+ShPixelLocalStorageType RendererD3D::getNativePixelLocalStorageType() const
+{
+ if (!getNativeExtensions().shaderPixelLocalStorageANGLE)
+ {
+ return ShPixelLocalStorageType::NotSupported;
+ }
+ // Read/write UAVs only support "r32*" images.
+ return ShPixelLocalStorageType::ImageStoreR32PackedFormats;
+}
+
+Serial RendererD3D::generateSerial()
+{
+ return mSerialFactory.generate();
+}
+
+bool InstancedPointSpritesActive(ProgramD3D *programD3D, gl::PrimitiveMode mode)
+{
+ return programD3D->usesPointSize() && programD3D->usesInstancedPointSpriteEmulation() &&
+ mode == gl::PrimitiveMode::Points;
+}
+
+angle::Result RendererD3D::initRenderTarget(const gl::Context *context,
+ RenderTargetD3D *renderTarget)
+{
+ return clearRenderTarget(context, renderTarget, gl::ColorF(0, 0, 0, 0), 1, 0);
+}
+
+const angle::FeaturesD3D &RendererD3D::getFeatures() const
+{
+ if (!mFeaturesInitialized)
+ {
+ initializeFeatures(&mFeatures);
+ mFeaturesInitialized = true;
+ }
+
+ return mFeatures;
+}
+
+unsigned int GetBlendSampleMask(const gl::State &glState, int samples)
+{
+ unsigned int mask = 0;
+ if (glState.isSampleCoverageEnabled())
+ {
+ GLfloat coverageValue = glState.getSampleCoverageValue();
+ if (coverageValue != 0)
+ {
+ float threshold = 0.5f;
+
+ for (int i = 0; i < samples; ++i)
+ {
+ mask <<= 1;
+
+ if ((i + 1) * coverageValue >= threshold)
+ {
+ threshold += 1.0f;
+ mask |= 1;
+ }
+ }
+ }
+
+ bool coverageInvert = glState.getSampleCoverageInvert();
+ if (coverageInvert)
+ {
+ mask = ~mask;
+ }
+ }
+ else
+ {
+ mask = 0xFFFFFFFF;
+ }
+
+ if (glState.isSampleMaskEnabled())
+ {
+ mask &= glState.getSampleMaskWord(0);
+ }
+
+ return mask;
+}
+
+GLenum DefaultGLErrorCode(HRESULT hr)
+{
+ switch (hr)
+ {
+#ifdef ANGLE_ENABLE_D3D9
+ case D3DERR_OUTOFVIDEOMEMORY:
+#endif
+ case E_OUTOFMEMORY:
+ return GL_OUT_OF_MEMORY;
+ default:
+ return GL_INVALID_OPERATION;
+ }
+}
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/RendererD3D.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/RendererD3D.h
new file mode 100644
index 0000000000..3846e1eb2a
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/RendererD3D.h
@@ -0,0 +1,489 @@
+
+// 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.
+//
+
+// RendererD3D.h: Defines a back-end specific class for the DirectX renderer.
+
+#ifndef LIBANGLE_RENDERER_D3D_RENDERERD3D_H_
+#define LIBANGLE_RENDERER_D3D_RENDERERD3D_H_
+
+#include <array>
+
+#include "common/Color.h"
+#include "common/MemoryBuffer.h"
+#include "common/debug.h"
+#include "libANGLE/Device.h"
+#include "libANGLE/State.h"
+#include "libANGLE/Version.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/d3d/ShaderD3D.h"
+#include "libANGLE/renderer/d3d/VertexDataManager.h"
+#include "libANGLE/renderer/d3d/formatutilsD3D.h"
+#include "libANGLE/renderer/renderer_utils.h"
+#include "libANGLE/renderer/serial_utils.h"
+#include "platform/FeaturesD3D_autogen.h"
+
+namespace egl
+{
+class ConfigSet;
+}
+
+namespace gl
+{
+class ErrorSet;
+class FramebufferState;
+class InfoLog;
+class Texture;
+struct LinkedVarying;
+} // namespace gl
+
+namespace rx
+{
+class ContextImpl;
+struct D3DUniform;
+struct D3DVarying;
+class DeviceD3D;
+class EGLImageD3D;
+class FramebufferImpl;
+class ImageD3D;
+class IndexBuffer;
+class NativeWindowD3D;
+class ProgramD3D;
+class RenderTargetD3D;
+class ShaderExecutableD3D;
+class SwapChainD3D;
+class TextureStorage;
+struct TranslatedIndexData;
+class UniformStorageD3D;
+class VertexBuffer;
+
+struct DeviceIdentifier
+{
+ UINT VendorId;
+ UINT DeviceId;
+ UINT SubSysId;
+ UINT Revision;
+ UINT FeatureLevel;
+};
+
+enum RendererClass
+{
+ RENDERER_D3D11,
+ RENDERER_D3D9
+};
+
+struct BindFlags
+{
+ bool renderTarget = false;
+ bool unorderedAccess = false;
+ static BindFlags RenderTarget()
+ {
+ BindFlags flags;
+ flags.renderTarget = true;
+ return flags;
+ }
+ static BindFlags UnorderedAccess()
+ {
+ BindFlags flags;
+ flags.unorderedAccess = true;
+ return flags;
+ }
+};
+
+// A d3d::Context wraps error handling.
+namespace d3d
+{
+class Context : angle::NonCopyable
+{
+ public:
+ Context() {}
+ virtual ~Context() {}
+
+ virtual void handleResult(HRESULT hr,
+ const char *message,
+ const char *file,
+ const char *function,
+ unsigned int line) = 0;
+};
+} // namespace d3d
+
+// ANGLE_TRY for HRESULT errors.
+#define ANGLE_TRY_HR(CONTEXT, EXPR, MESSAGE) \
+ do \
+ { \
+ auto ANGLE_LOCAL_VAR = (EXPR); \
+ if (ANGLE_UNLIKELY(FAILED(ANGLE_LOCAL_VAR))) \
+ { \
+ CONTEXT->handleResult(ANGLE_LOCAL_VAR, MESSAGE, __FILE__, ANGLE_FUNCTION, __LINE__); \
+ return angle::Result::Stop; \
+ } \
+ } while (0)
+
+#define ANGLE_CHECK_HR(CONTEXT, EXPR, MESSAGE, ERROR) \
+ do \
+ { \
+ if (ANGLE_UNLIKELY(!(EXPR))) \
+ { \
+ CONTEXT->handleResult(ERROR, MESSAGE, __FILE__, ANGLE_FUNCTION, __LINE__); \
+ return angle::Result::Stop; \
+ } \
+ } while (0)
+
+#define ANGLE_HR_UNREACHABLE(context) \
+ UNREACHABLE(); \
+ ANGLE_CHECK_HR(context, false, "Unreachble code reached.", E_FAIL)
+
+// Check if the device is lost every 10 failures to get the query data
+constexpr unsigned int kPollingD3DDeviceLostCheckFrequency = 10;
+
+// Useful for unit testing
+class BufferFactoryD3D : angle::NonCopyable
+{
+ public:
+ BufferFactoryD3D() {}
+ virtual ~BufferFactoryD3D() {}
+
+ virtual VertexBuffer *createVertexBuffer() = 0;
+ virtual IndexBuffer *createIndexBuffer() = 0;
+
+ // TODO(jmadill): add VertexFormatCaps
+ virtual VertexConversionType getVertexConversionType(angle::FormatID vertexFormatID) const = 0;
+ virtual GLenum getVertexComponentType(angle::FormatID vertexFormatID) const = 0;
+
+ // Warning: you should ensure binding really matches attrib.bindingIndex before using this
+ // function.
+ virtual angle::Result getVertexSpaceRequired(const gl::Context *context,
+ const gl::VertexAttribute &attrib,
+ const gl::VertexBinding &binding,
+ size_t count,
+ GLsizei instances,
+ GLuint baseInstance,
+ unsigned int *bytesRequiredOut) const = 0;
+};
+
+using AttribIndexArray = gl::AttribArray<int>;
+
+class RendererD3D : public BufferFactoryD3D
+{
+ public:
+ explicit RendererD3D(egl::Display *display);
+ ~RendererD3D() override;
+
+ virtual egl::Error initialize() = 0;
+
+ virtual egl::ConfigSet generateConfigs() = 0;
+ virtual void generateDisplayExtensions(egl::DisplayExtensions *outExtensions) const = 0;
+
+ virtual ContextImpl *createContext(const gl::State &state, gl::ErrorSet *errorSet) = 0;
+
+ virtual std::string getRendererDescription() const = 0;
+ virtual std::string getVendorString() const = 0;
+ virtual std::string getVersionString(bool includeFullVersion) const = 0;
+
+ virtual int getMinorShaderModel() const = 0;
+ virtual std::string getShaderModelSuffix() const = 0;
+
+ // Direct3D Specific methods
+ virtual DeviceIdentifier getAdapterIdentifier() const = 0;
+
+ virtual bool isValidNativeWindow(EGLNativeWindowType window) const = 0;
+ virtual NativeWindowD3D *createNativeWindow(EGLNativeWindowType window,
+ const egl::Config *config,
+ const egl::AttributeMap &attribs) const = 0;
+
+ virtual SwapChainD3D *createSwapChain(NativeWindowD3D *nativeWindow,
+ HANDLE shareHandle,
+ IUnknown *d3dTexture,
+ GLenum backBufferFormat,
+ GLenum depthBufferFormat,
+ EGLint orientation,
+ EGLint samples) = 0;
+ virtual egl::Error getD3DTextureInfo(const egl::Config *configuration,
+ IUnknown *d3dTexture,
+ const egl::AttributeMap &attribs,
+ EGLint *width,
+ EGLint *height,
+ GLsizei *samples,
+ gl::Format *glFormat,
+ const angle::Format **angleFormat,
+ UINT *arraySlice) const = 0;
+ virtual egl::Error validateShareHandle(const egl::Config *config,
+ HANDLE shareHandle,
+ const egl::AttributeMap &attribs) const = 0;
+
+ virtual int getMajorShaderModel() const = 0;
+
+ virtual void setGlobalDebugAnnotator() = 0;
+
+ const angle::FeaturesD3D &getFeatures() const;
+
+ // Pixel operations
+ virtual angle::Result copyImage2D(const gl::Context *context,
+ const gl::Framebuffer *framebuffer,
+ const gl::Rectangle &sourceRect,
+ GLenum destFormat,
+ const gl::Offset &destOffset,
+ TextureStorage *storage,
+ GLint level) = 0;
+ virtual angle::Result copyImageCube(const gl::Context *context,
+ const gl::Framebuffer *framebuffer,
+ const gl::Rectangle &sourceRect,
+ GLenum destFormat,
+ const gl::Offset &destOffset,
+ TextureStorage *storage,
+ gl::TextureTarget target,
+ GLint level) = 0;
+ virtual angle::Result copyImage3D(const gl::Context *context,
+ const gl::Framebuffer *framebuffer,
+ const gl::Rectangle &sourceRect,
+ GLenum destFormat,
+ const gl::Offset &destOffset,
+ TextureStorage *storage,
+ GLint level) = 0;
+ virtual angle::Result copyImage2DArray(const gl::Context *context,
+ const gl::Framebuffer *framebuffer,
+ const gl::Rectangle &sourceRect,
+ GLenum destFormat,
+ const gl::Offset &destOffset,
+ TextureStorage *storage,
+ GLint level) = 0;
+
+ virtual angle::Result copyTexture(const gl::Context *context,
+ const gl::Texture *source,
+ GLint sourceLevel,
+ gl::TextureTarget srcTarget,
+ const gl::Box &sourceBox,
+ GLenum destFormat,
+ GLenum destType,
+ const gl::Offset &destOffset,
+ TextureStorage *storage,
+ gl::TextureTarget destTarget,
+ GLint destLevel,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha) = 0;
+ virtual angle::Result copyCompressedTexture(const gl::Context *context,
+ const gl::Texture *source,
+ GLint sourceLevel,
+ TextureStorage *storage,
+ GLint destLevel) = 0;
+
+ // RenderTarget creation
+ virtual angle::Result createRenderTarget(const gl::Context *context,
+ int width,
+ int height,
+ GLenum format,
+ GLsizei samples,
+ RenderTargetD3D **outRT) = 0;
+ virtual angle::Result createRenderTargetCopy(const gl::Context *context,
+ RenderTargetD3D *source,
+ RenderTargetD3D **outRT) = 0;
+
+ // Shader operations
+ virtual angle::Result loadExecutable(d3d::Context *context,
+ const uint8_t *function,
+ size_t length,
+ gl::ShaderType type,
+ const std::vector<D3DVarying> &streamOutVaryings,
+ bool separatedOutputBuffers,
+ ShaderExecutableD3D **outExecutable) = 0;
+ virtual angle::Result compileToExecutable(d3d::Context *context,
+ gl::InfoLog &infoLog,
+ const std::string &shaderHLSL,
+ gl::ShaderType type,
+ const std::vector<D3DVarying> &streamOutVaryings,
+ bool separatedOutputBuffers,
+ const CompilerWorkaroundsD3D &workarounds,
+ ShaderExecutableD3D **outExectuable) = 0;
+ virtual angle::Result ensureHLSLCompilerInitialized(d3d::Context *context) = 0;
+
+ virtual UniformStorageD3D *createUniformStorage(size_t storageSize) = 0;
+
+ // Image operations
+ virtual ImageD3D *createImage() = 0;
+ virtual ExternalImageSiblingImpl *createExternalImageSibling(
+ const gl::Context *context,
+ EGLenum target,
+ EGLClientBuffer buffer,
+ const egl::AttributeMap &attribs) = 0;
+ virtual angle::Result generateMipmap(const gl::Context *context,
+ ImageD3D *dest,
+ ImageD3D *source) = 0;
+ virtual angle::Result generateMipmapUsingD3D(const gl::Context *context,
+ TextureStorage *storage,
+ const gl::TextureState &textureState) = 0;
+ virtual angle::Result copyImage(const gl::Context *context,
+ ImageD3D *dest,
+ ImageD3D *source,
+ const gl::Box &sourceBox,
+ const gl::Offset &destOffset,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha) = 0;
+ virtual TextureStorage *createTextureStorage2D(SwapChainD3D *swapChain,
+ const std::string &label) = 0;
+ virtual TextureStorage *createTextureStorageEGLImage(EGLImageD3D *eglImage,
+ RenderTargetD3D *renderTargetD3D,
+ const std::string &label) = 0;
+ virtual TextureStorage *createTextureStorageBuffer(
+ const gl::OffsetBindingPointer<gl::Buffer> &buffer,
+ GLenum internalFormat,
+ const std::string &label) = 0;
+ virtual TextureStorage *createTextureStorageExternal(
+ egl::Stream *stream,
+ const egl::Stream::GLTextureDescription &desc,
+ const std::string &label) = 0;
+ virtual TextureStorage *createTextureStorage2D(GLenum internalformat,
+ BindFlags bindFlags,
+ GLsizei width,
+ GLsizei height,
+ int levels,
+ const std::string &label,
+ bool hintLevelZeroOnly) = 0;
+ virtual TextureStorage *createTextureStorageCube(GLenum internalformat,
+ BindFlags bindFlags,
+ int size,
+ int levels,
+ bool hintLevelZeroOnly,
+ const std::string &label) = 0;
+ virtual TextureStorage *createTextureStorage3D(GLenum internalformat,
+ BindFlags bindFlags,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ int levels,
+ const std::string &label) = 0;
+ virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat,
+ BindFlags bindFlags,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ int levels,
+ const std::string &label) = 0;
+ virtual TextureStorage *createTextureStorage2DMultisample(GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ int levels,
+ int samples,
+ bool fixedSampleLocations,
+ const std::string &label) = 0;
+ virtual TextureStorage *createTextureStorage2DMultisampleArray(GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ int levels,
+ int samples,
+ bool fixedSampleLocations,
+ const std::string &label) = 0;
+
+ // Buffer-to-texture and Texture-to-buffer copies
+ virtual bool supportsFastCopyBufferToTexture(GLenum internalFormat) const = 0;
+ virtual angle::Result fastCopyBufferToTexture(const gl::Context *context,
+ const gl::PixelUnpackState &unpack,
+ gl::Buffer *unpackBuffer,
+ unsigned int offset,
+ RenderTargetD3D *destRenderTarget,
+ GLenum destinationFormat,
+ GLenum sourcePixelsType,
+ const gl::Box &destArea) = 0;
+
+ // Device lost
+ gl::GraphicsResetStatus getResetStatus();
+ void notifyDeviceLost();
+ virtual bool resetDevice() = 0;
+ virtual bool testDeviceLost() = 0;
+ virtual bool testDeviceResettable() = 0;
+
+ virtual RendererClass getRendererClass() const = 0;
+ virtual void *getD3DDevice() = 0;
+
+ void setGPUDisjoint();
+
+ GLint getGPUDisjoint();
+ GLint64 getTimestamp();
+
+ virtual angle::Result clearRenderTarget(const gl::Context *context,
+ RenderTargetD3D *renderTarget,
+ const gl::ColorF &clearColorValue,
+ const float clearDepthValue,
+ const unsigned int clearStencilValue) = 0;
+
+ virtual DeviceImpl *createEGLDevice() = 0;
+
+ bool presentPathFastEnabled() const { return mPresentPathFastEnabled; }
+
+ // Stream creation
+ virtual StreamProducerImpl *createStreamProducerD3DTexture(
+ egl::Stream::ConsumerType consumerType,
+ const egl::AttributeMap &attribs) = 0;
+
+ const gl::Caps &getNativeCaps() const;
+ const gl::TextureCapsMap &getNativeTextureCaps() const;
+ const gl::Extensions &getNativeExtensions() const;
+ const gl::Limitations &getNativeLimitations() const;
+ ShPixelLocalStorageType getNativePixelLocalStorageType() const;
+ virtual void initializeFrontendFeatures(angle::FrontendFeatures *features) const = 0;
+
+ // Necessary hack for default framebuffers in D3D.
+ virtual FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) = 0;
+
+ virtual gl::Version getMaxSupportedESVersion() const = 0;
+ virtual gl::Version getMaxConformantESVersion() const = 0;
+
+ angle::Result initRenderTarget(const gl::Context *context, RenderTargetD3D *renderTarget);
+
+ virtual angle::Result getIncompleteTexture(const gl::Context *context,
+ gl::TextureType type,
+ gl::Texture **textureOut) = 0;
+
+ Serial generateSerial();
+
+ virtual bool canSelectViewInVertexShader() const = 0;
+
+ protected:
+ virtual bool getLUID(LUID *adapterLuid) const = 0;
+ virtual void generateCaps(gl::Caps *outCaps,
+ gl::TextureCapsMap *outTextureCaps,
+ gl::Extensions *outExtensions,
+ gl::Limitations *outLimitations) const = 0;
+
+ bool skipDraw(const gl::State &glState, gl::PrimitiveMode drawMode);
+
+ egl::Display *mDisplay;
+
+ bool mPresentPathFastEnabled;
+
+ private:
+ void ensureCapsInitialized() const;
+
+ virtual void initializeFeatures(angle::FeaturesD3D *features) const = 0;
+
+ mutable bool mCapsInitialized;
+ mutable gl::Caps mNativeCaps;
+ mutable gl::TextureCapsMap mNativeTextureCaps;
+ mutable gl::Extensions mNativeExtensions;
+ mutable gl::Limitations mNativeLimitations;
+
+ mutable bool mFeaturesInitialized;
+ mutable angle::FeaturesD3D mFeatures;
+
+ bool mDisjoint;
+ bool mDeviceLost;
+
+ SerialFactory mSerialFactory;
+};
+
+unsigned int GetBlendSampleMask(const gl::State &glState, int samples);
+bool InstancedPointSpritesActive(ProgramD3D *programD3D, gl::PrimitiveMode mode);
+GLenum DefaultGLErrorCode(HRESULT hr);
+
+// Define stubs so we don't need to include D3D9/D3D11 headers directly.
+RendererD3D *CreateRenderer11(egl::Display *display);
+RendererD3D *CreateRenderer9(egl::Display *display);
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_RENDERERD3D_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/SamplerD3D.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/SamplerD3D.h
new file mode 100644
index 0000000000..ad4b15a4ab
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/SamplerD3D.h
@@ -0,0 +1,33 @@
+//
+// 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.
+//
+
+// SamplerD3D.h: Defines the rx::SamplerD3D class, an implementation of SamplerImpl.
+
+#ifndef LIBANGLE_RENDERER_D3D_SAMPLERD3D_H_
+#define LIBANGLE_RENDERER_D3D_SAMPLERD3D_H_
+
+#include "libANGLE/renderer/SamplerImpl.h"
+
+namespace rx
+{
+
+class SamplerD3D : public SamplerImpl
+{
+ public:
+ SamplerD3D(const gl::SamplerState &state) : SamplerImpl(state) {}
+ ~SamplerD3D() override {}
+
+ angle::Result syncState(const gl::Context *context, const bool dirtyBits) override;
+};
+
+inline angle::Result SamplerD3D::syncState(const gl::Context *context, const bool dirtyBits)
+{
+ return angle::Result::Continue;
+}
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_SAMPLERD3D_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/ShaderD3D.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/ShaderD3D.cpp
new file mode 100644
index 0000000000..ae8a9ebcfb
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/ShaderD3D.cpp
@@ -0,0 +1,391 @@
+//
+// 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.
+//
+
+// ShaderD3D.cpp: Defines the rx::ShaderD3D class which implements rx::ShaderImpl.
+
+#include "libANGLE/renderer/d3d/ShaderD3D.h"
+
+#include "common/system_utils.h"
+#include "common/utilities.h"
+#include "libANGLE/Caps.h"
+#include "libANGLE/Compiler.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Shader.h"
+#include "libANGLE/features.h"
+#include "libANGLE/renderer/ContextImpl.h"
+#include "libANGLE/renderer/d3d/ProgramD3D.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
+#include "libANGLE/trace.h"
+
+namespace rx
+{
+
+class TranslateTaskD3D : public angle::Closure
+{
+ public:
+ TranslateTaskD3D(ShHandle handle,
+ const ShCompileOptions &options,
+ const std::string &source,
+ const std::string &sourcePath)
+ : mHandle(handle),
+ mOptions(options),
+ mSource(source),
+ mSourcePath(sourcePath),
+ mResult(false)
+ {}
+
+ void operator()() override
+ {
+ ANGLE_TRACE_EVENT1("gpu.angle", "TranslateTask::run", "source", mSource);
+ std::vector<const char *> srcStrings;
+ if (!mSourcePath.empty())
+ {
+ srcStrings.push_back(mSourcePath.c_str());
+ }
+ srcStrings.push_back(mSource.c_str());
+
+ mResult = sh::Compile(mHandle, &srcStrings[0], srcStrings.size(), mOptions);
+ }
+
+ bool getResult() { return mResult; }
+
+ private:
+ ShHandle mHandle;
+ ShCompileOptions mOptions;
+ std::string mSource;
+ std::string mSourcePath;
+ bool mResult;
+};
+
+using PostTranslateFunctor =
+ std::function<bool(gl::ShCompilerInstance *compiler, std::string *infoLog)>;
+
+class WaitableCompileEventD3D final : public WaitableCompileEvent
+{
+ public:
+ WaitableCompileEventD3D(std::shared_ptr<angle::WaitableEvent> waitableEvent,
+ gl::ShCompilerInstance *compilerInstance,
+ PostTranslateFunctor &&postTranslateFunctor,
+ std::shared_ptr<TranslateTaskD3D> translateTask)
+ : WaitableCompileEvent(waitableEvent),
+ mCompilerInstance(compilerInstance),
+ mPostTranslateFunctor(std::move(postTranslateFunctor)),
+ mTranslateTask(translateTask)
+ {}
+
+ bool getResult() override { return mTranslateTask->getResult(); }
+
+ bool postTranslate(std::string *infoLog) override
+ {
+ return mPostTranslateFunctor(mCompilerInstance, infoLog);
+ }
+
+ private:
+ gl::ShCompilerInstance *mCompilerInstance;
+ PostTranslateFunctor mPostTranslateFunctor;
+ std::shared_ptr<TranslateTaskD3D> mTranslateTask;
+};
+
+ShaderD3D::ShaderD3D(const gl::ShaderState &state, RendererD3D *renderer)
+ : ShaderImpl(state), mRenderer(renderer)
+{
+ uncompile();
+}
+
+ShaderD3D::~ShaderD3D() {}
+
+std::string ShaderD3D::getDebugInfo() const
+{
+ if (mDebugInfo.empty())
+ {
+ return "";
+ }
+
+ return mDebugInfo + std::string("\n// ") + gl::GetShaderTypeString(mState.getShaderType()) +
+ " SHADER END\n";
+}
+
+// initialize/clean up previous state
+void ShaderD3D::uncompile()
+{
+ // set by compileToHLSL
+ mCompilerOutputType = SH_ESSL_OUTPUT;
+
+ mUsesMultipleRenderTargets = false;
+ mUsesFragColor = false;
+ mUsesFragData = false;
+ mUsesSecondaryColor = false;
+ mUsesFragCoord = false;
+ mUsesFrontFacing = false;
+ mUsesHelperInvocation = false;
+ mUsesPointSize = false;
+ mUsesPointCoord = false;
+ mUsesDepthRange = false;
+ mUsesFragDepth = false;
+ mHasANGLEMultiviewEnabled = false;
+ mUsesVertexID = false;
+ mUsesViewID = false;
+ mUsesDiscardRewriting = false;
+ mUsesNestedBreak = false;
+ mRequiresIEEEStrictCompiling = false;
+
+ mDebugInfo.clear();
+}
+
+void ShaderD3D::generateWorkarounds(CompilerWorkaroundsD3D *workarounds) const
+{
+ if (mUsesDiscardRewriting)
+ {
+ // ANGLE issue 486:
+ // Work-around a D3D9 compiler bug that presents itself when using conditional discard, by
+ // disabling optimization
+ workarounds->skipOptimization = true;
+ }
+ else if (mUsesNestedBreak)
+ {
+ // ANGLE issue 603:
+ // Work-around a D3D9 compiler bug that presents itself when using break in a nested loop,
+ // by maximizing optimization We want to keep the use of
+ // ANGLE_D3D_WORKAROUND_MAX_OPTIMIZATION minimal to prevent hangs, so usesDiscard takes
+ // precedence
+ workarounds->useMaxOptimization = true;
+ }
+
+ if (mRequiresIEEEStrictCompiling)
+ {
+ // IEEE Strictness for D3D compiler needs to be enabled for NaNs to work.
+ workarounds->enableIEEEStrictness = true;
+ }
+}
+
+unsigned int ShaderD3D::getUniformRegister(const std::string &uniformName) const
+{
+ ASSERT(mUniformRegisterMap.count(uniformName) > 0);
+ return mUniformRegisterMap.find(uniformName)->second;
+}
+
+unsigned int ShaderD3D::getUniformBlockRegister(const std::string &blockName) const
+{
+ ASSERT(mUniformBlockRegisterMap.count(blockName) > 0);
+ return mUniformBlockRegisterMap.find(blockName)->second;
+}
+
+bool ShaderD3D::shouldUniformBlockUseStructuredBuffer(const std::string &blockName) const
+{
+ ASSERT(mUniformBlockUseStructuredBufferMap.count(blockName) > 0);
+ return mUniformBlockUseStructuredBufferMap.find(blockName)->second;
+}
+
+unsigned int ShaderD3D::getShaderStorageBlockRegister(const std::string &blockName) const
+{
+ ASSERT(mShaderStorageBlockRegisterMap.count(blockName) > 0);
+ return mShaderStorageBlockRegisterMap.find(blockName)->second;
+}
+
+ShShaderOutput ShaderD3D::getCompilerOutputType() const
+{
+ return mCompilerOutputType;
+}
+
+bool ShaderD3D::useImage2DFunction(const std::string &functionName) const
+{
+ if (mUsedImage2DFunctionNames.empty())
+ {
+ return false;
+ }
+
+ return mUsedImage2DFunctionNames.find(functionName) != mUsedImage2DFunctionNames.end();
+}
+
+const std::set<std::string> &ShaderD3D::getSlowCompilingUniformBlockSet() const
+{
+ return mSlowCompilingUniformBlockSet;
+}
+
+const std::map<std::string, unsigned int> &GetUniformRegisterMap(
+ const std::map<std::string, unsigned int> *uniformRegisterMap)
+{
+ ASSERT(uniformRegisterMap);
+ return *uniformRegisterMap;
+}
+
+const std::set<std::string> &GetSlowCompilingUniformBlockSet(
+ const std::set<std::string> *slowCompilingUniformBlockSet)
+{
+ ASSERT(slowCompilingUniformBlockSet);
+ return *slowCompilingUniformBlockSet;
+}
+
+const std::set<std::string> &GetUsedImage2DFunctionNames(
+ const std::set<std::string> *usedImage2DFunctionNames)
+{
+ ASSERT(usedImage2DFunctionNames);
+ return *usedImage2DFunctionNames;
+}
+
+std::shared_ptr<WaitableCompileEvent> ShaderD3D::compile(const gl::Context *context,
+ gl::ShCompilerInstance *compilerInstance,
+ ShCompileOptions *options)
+{
+ std::string sourcePath;
+ uncompile();
+
+ const angle::FeaturesD3D &features = mRenderer->getFeatures();
+ const gl::Extensions &extensions = mRenderer->getNativeExtensions();
+
+ const std::string &source = mState.getSource();
+
+#if !defined(ANGLE_ENABLE_WINDOWS_UWP)
+ if (gl::DebugAnnotationsActive(context))
+ {
+ sourcePath = angle::CreateTemporaryFile().value();
+ writeFile(sourcePath.c_str(), source.c_str(), source.length());
+ options->lineDirectives = true;
+ options->sourcePath = true;
+ }
+#endif
+
+ if (features.expandIntegerPowExpressions.enabled)
+ {
+ options->expandSelectHLSLIntegerPowExpressions = true;
+ }
+
+ if (features.getDimensionsIgnoresBaseLevel.enabled)
+ {
+ options->HLSLGetDimensionsIgnoresBaseLevel = true;
+ }
+
+ if (features.preAddTexelFetchOffsets.enabled)
+ {
+ options->rewriteTexelFetchOffsetToTexelFetch = true;
+ }
+ if (features.rewriteUnaryMinusOperator.enabled)
+ {
+ options->rewriteIntegerUnaryMinusOperator = true;
+ }
+ if (features.emulateIsnanFloat.enabled)
+ {
+ options->emulateIsnanFloatFunction = true;
+ }
+ if (features.skipVSConstantRegisterZero.enabled &&
+ mState.getShaderType() == gl::ShaderType::Vertex)
+ {
+ options->skipD3DConstantRegisterZero = true;
+ }
+ if (features.forceAtomicValueResolution.enabled)
+ {
+ options->forceAtomicValueResolution = true;
+ }
+ if (features.allowTranslateUniformBlockToStructuredBuffer.enabled)
+ {
+ options->allowTranslateUniformBlockToStructuredBuffer = true;
+ }
+ if (extensions.multiviewOVR || extensions.multiview2OVR)
+ {
+ options->initializeBuiltinsForInstancedMultiview = true;
+ }
+ if (extensions.shaderPixelLocalStorageANGLE)
+ {
+ options->pls.type = mRenderer->getNativePixelLocalStorageType();
+ if (extensions.shaderPixelLocalStorageCoherentANGLE)
+ {
+ options->pls.fragmentSynchronizationType =
+ ShFragmentSynchronizationType::RasterizerOrderViews_D3D;
+ }
+ }
+
+ auto postTranslateFunctor = [this](gl::ShCompilerInstance *compiler, std::string *infoLog) {
+ // TODO(jmadill): We shouldn't need to cache this.
+ mCompilerOutputType = compiler->getShaderOutputType();
+
+ const std::string &translatedSource = mState.getTranslatedSource();
+
+ mUsesMultipleRenderTargets = translatedSource.find("GL_USES_MRT") != std::string::npos;
+ mUsesFragColor = translatedSource.find("GL_USES_FRAG_COLOR") != std::string::npos;
+ mUsesFragData = translatedSource.find("GL_USES_FRAG_DATA") != std::string::npos;
+ mUsesSecondaryColor = translatedSource.find("GL_USES_SECONDARY_COLOR") != std::string::npos;
+ mUsesFragCoord = translatedSource.find("GL_USES_FRAG_COORD") != std::string::npos;
+ mUsesFrontFacing = translatedSource.find("GL_USES_FRONT_FACING") != std::string::npos;
+ mUsesHelperInvocation =
+ translatedSource.find("GL_USES_HELPER_INVOCATION") != std::string::npos;
+ mUsesPointSize = translatedSource.find("GL_USES_POINT_SIZE") != std::string::npos;
+ mUsesPointCoord = translatedSource.find("GL_USES_POINT_COORD") != std::string::npos;
+ mUsesDepthRange = translatedSource.find("GL_USES_DEPTH_RANGE") != std::string::npos;
+ mUsesFragDepth = translatedSource.find("GL_USES_FRAG_DEPTH") != std::string::npos;
+ mHasANGLEMultiviewEnabled =
+ translatedSource.find("GL_ANGLE_MULTIVIEW_ENABLED") != std::string::npos;
+ mUsesVertexID = translatedSource.find("GL_USES_VERTEX_ID") != std::string::npos;
+ mUsesViewID = translatedSource.find("GL_USES_VIEW_ID") != std::string::npos;
+ mUsesDiscardRewriting =
+ translatedSource.find("ANGLE_USES_DISCARD_REWRITING") != std::string::npos;
+ mUsesNestedBreak = translatedSource.find("ANGLE_USES_NESTED_BREAK") != std::string::npos;
+ mRequiresIEEEStrictCompiling =
+ translatedSource.find("ANGLE_REQUIRES_IEEE_STRICT_COMPILING") != std::string::npos;
+
+ ShHandle compilerHandle = compiler->getHandle();
+
+ mUniformRegisterMap = GetUniformRegisterMap(sh::GetUniformRegisterMap(compilerHandle));
+ mReadonlyImage2DRegisterIndex = sh::GetReadonlyImage2DRegisterIndex(compilerHandle);
+ mImage2DRegisterIndex = sh::GetImage2DRegisterIndex(compilerHandle);
+ mUsedImage2DFunctionNames =
+ GetUsedImage2DFunctionNames(sh::GetUsedImage2DFunctionNames(compilerHandle));
+
+ for (const sh::InterfaceBlock &interfaceBlock : mState.getUniformBlocks())
+ {
+ if (interfaceBlock.active)
+ {
+ unsigned int index = static_cast<unsigned int>(-1);
+ bool blockRegisterResult =
+ sh::GetUniformBlockRegister(compilerHandle, interfaceBlock.name, &index);
+ ASSERT(blockRegisterResult);
+ bool useStructuredBuffer =
+ sh::ShouldUniformBlockUseStructuredBuffer(compilerHandle, interfaceBlock.name);
+
+ mUniformBlockRegisterMap[interfaceBlock.name] = index;
+ mUniformBlockUseStructuredBufferMap[interfaceBlock.name] = useStructuredBuffer;
+ }
+ }
+
+ mSlowCompilingUniformBlockSet =
+ GetSlowCompilingUniformBlockSet(sh::GetSlowCompilingUniformBlockSet(compilerHandle));
+
+ for (const sh::InterfaceBlock &interfaceBlock : mState.getShaderStorageBlocks())
+ {
+ if (interfaceBlock.active)
+ {
+ unsigned int index = static_cast<unsigned int>(-1);
+ bool blockRegisterResult =
+ sh::GetShaderStorageBlockRegister(compilerHandle, interfaceBlock.name, &index);
+ ASSERT(blockRegisterResult);
+
+ mShaderStorageBlockRegisterMap[interfaceBlock.name] = index;
+ }
+ }
+
+ mDebugInfo += std::string("// ") + gl::GetShaderTypeString(mState.getShaderType()) +
+ " SHADER BEGIN\n";
+ mDebugInfo += "\n// GLSL BEGIN\n\n" + mState.getSource() + "\n\n// GLSL END\n\n\n";
+ mDebugInfo +=
+ "// INITIAL HLSL BEGIN\n\n" + translatedSource + "\n// INITIAL HLSL END\n\n\n";
+ // Successive steps will append more info
+ return true;
+ };
+
+ auto workerThreadPool = context->getWorkerThreadPool();
+ auto translateTask = std::make_shared<TranslateTaskD3D>(compilerInstance->getHandle(), *options,
+ source, sourcePath);
+
+ return std::make_shared<WaitableCompileEventD3D>(
+ angle::WorkerThreadPool::PostWorkerTask(workerThreadPool, translateTask), compilerInstance,
+ std::move(postTranslateFunctor), translateTask);
+}
+
+bool ShaderD3D::hasUniform(const std::string &name) const
+{
+ return mUniformRegisterMap.find(name) != mUniformRegisterMap.end();
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/ShaderD3D.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/ShaderD3D.h
new file mode 100644
index 0000000000..d1c5622a27
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/ShaderD3D.h
@@ -0,0 +1,126 @@
+//
+// 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.
+//
+
+// ShaderD3D.h: Defines the rx::ShaderD3D class which implements rx::ShaderImpl.
+
+#ifndef LIBANGLE_RENDERER_D3D_SHADERD3D_H_
+#define LIBANGLE_RENDERER_D3D_SHADERD3D_H_
+
+#include "libANGLE/renderer/ShaderImpl.h"
+
+#include <map>
+
+namespace angle
+{
+struct FeaturesD3D;
+} // namespace angle
+
+namespace gl
+{
+struct Extensions;
+}
+
+namespace rx
+{
+class DynamicHLSL;
+class RendererD3D;
+struct D3DUniform;
+
+// Workarounds attached to each shader. Do not need to expose information about these workarounds so
+// a simple bool struct suffices.
+struct CompilerWorkaroundsD3D
+{
+ bool skipOptimization = false;
+
+ bool useMaxOptimization = false;
+
+ // IEEE strictness needs to be enabled for NANs to work.
+ bool enableIEEEStrictness = false;
+};
+
+class ShaderD3D : public ShaderImpl
+{
+ public:
+ ShaderD3D(const gl::ShaderState &state, RendererD3D *renderer);
+ ~ShaderD3D() override;
+
+ std::shared_ptr<WaitableCompileEvent> compile(const gl::Context *context,
+ gl::ShCompilerInstance *compilerInstance,
+ ShCompileOptions *options) override;
+
+ std::string getDebugInfo() const override;
+
+ // D3D-specific methods
+ void uncompile();
+
+ bool hasUniform(const std::string &name) const;
+
+ // Query regular uniforms with their name. Query sampler fields of structs with field selection
+ // using dot (.) operator.
+ unsigned int getUniformRegister(const std::string &uniformName) const;
+
+ unsigned int getUniformBlockRegister(const std::string &blockName) const;
+ bool shouldUniformBlockUseStructuredBuffer(const std::string &blockName) const;
+ unsigned int getShaderStorageBlockRegister(const std::string &blockName) const;
+ unsigned int getReadonlyImage2DRegisterIndex() const { return mReadonlyImage2DRegisterIndex; }
+ unsigned int getImage2DRegisterIndex() const { return mImage2DRegisterIndex; }
+ bool useImage2DFunction(const std::string &functionName) const;
+ const std::set<std::string> &getSlowCompilingUniformBlockSet() const;
+ void appendDebugInfo(const std::string &info) const { mDebugInfo += info; }
+
+ void generateWorkarounds(CompilerWorkaroundsD3D *workarounds) const;
+
+ bool usesMultipleRenderTargets() const { return mUsesMultipleRenderTargets; }
+ bool usesFragColor() const { return mUsesFragColor; }
+ bool usesFragData() const { return mUsesFragData; }
+ bool usesSecondaryColor() const { return mUsesSecondaryColor; }
+ bool usesFragCoord() const { return mUsesFragCoord; }
+ bool usesFrontFacing() const { return mUsesFrontFacing; }
+ bool usesHelperInvocation() const { return mUsesHelperInvocation; }
+ bool usesPointSize() const { return mUsesPointSize; }
+ bool usesPointCoord() const { return mUsesPointCoord; }
+ bool usesDepthRange() const { return mUsesDepthRange; }
+ bool usesFragDepth() const { return mUsesFragDepth; }
+ bool usesVertexID() const { return mUsesVertexID; }
+ bool usesViewID() const { return mUsesViewID; }
+ bool hasANGLEMultiviewEnabled() const { return mHasANGLEMultiviewEnabled; }
+
+ ShShaderOutput getCompilerOutputType() const;
+
+ private:
+ bool mUsesMultipleRenderTargets;
+ bool mUsesFragColor;
+ bool mUsesFragData;
+ bool mUsesSecondaryColor;
+ bool mUsesFragCoord;
+ bool mUsesFrontFacing;
+ bool mUsesHelperInvocation;
+ bool mUsesPointSize;
+ bool mUsesPointCoord;
+ bool mUsesDepthRange;
+ bool mUsesFragDepth;
+ bool mHasANGLEMultiviewEnabled;
+ bool mUsesVertexID;
+ bool mUsesViewID;
+ bool mUsesDiscardRewriting;
+ bool mUsesNestedBreak;
+ bool mRequiresIEEEStrictCompiling;
+
+ RendererD3D *mRenderer;
+ ShShaderOutput mCompilerOutputType;
+ mutable std::string mDebugInfo;
+ std::map<std::string, unsigned int> mUniformRegisterMap;
+ std::map<std::string, unsigned int> mUniformBlockRegisterMap;
+ std::map<std::string, bool> mUniformBlockUseStructuredBufferMap;
+ std::set<std::string> mSlowCompilingUniformBlockSet;
+ std::map<std::string, unsigned int> mShaderStorageBlockRegisterMap;
+ unsigned int mReadonlyImage2DRegisterIndex;
+ unsigned int mImage2DRegisterIndex;
+ std::set<std::string> mUsedImage2DFunctionNames;
+};
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_SHADERD3D_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/ShaderExecutableD3D.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/ShaderExecutableD3D.cpp
new file mode 100644
index 0000000000..eab3becc91
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/ShaderExecutableD3D.cpp
@@ -0,0 +1,67 @@
+//
+// Copyright 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.
+//
+
+// ShaderExecutable.cpp: Implements a class to contain D3D shader executable
+// implementation details.
+
+#include "libANGLE/renderer/d3d/ShaderExecutableD3D.h"
+
+#include "common/angleutils.h"
+
+namespace rx
+{
+
+ShaderExecutableD3D::ShaderExecutableD3D(const void *function, size_t length)
+ : mFunctionBuffer(length)
+{
+ memcpy(mFunctionBuffer.data(), function, length);
+}
+
+ShaderExecutableD3D::~ShaderExecutableD3D() {}
+
+const uint8_t *ShaderExecutableD3D::getFunction() const
+{
+ return mFunctionBuffer.data();
+}
+
+size_t ShaderExecutableD3D::getLength() const
+{
+ return mFunctionBuffer.size();
+}
+
+const std::string &ShaderExecutableD3D::getDebugInfo() const
+{
+ return mDebugInfo;
+}
+
+void ShaderExecutableD3D::appendDebugInfo(const std::string &info)
+{
+ mDebugInfo += info;
+}
+
+UniformStorageD3D::UniformStorageD3D(size_t initialSize) : mUniformData()
+{
+ bool result = mUniformData.resize(initialSize);
+ ASSERT(result);
+
+ // Uniform data is zero-initialized by default.
+ mUniformData.fill(0);
+}
+
+UniformStorageD3D::~UniformStorageD3D() {}
+
+size_t UniformStorageD3D::size() const
+{
+ return mUniformData.size();
+}
+
+uint8_t *UniformStorageD3D::getDataPointer(unsigned int registerIndex, unsigned int registerElement)
+{
+ size_t offset = ((registerIndex * 4 + registerElement) * sizeof(float));
+ return mUniformData.data() + offset;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/ShaderExecutableD3D.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/ShaderExecutableD3D.h
new file mode 100644
index 0000000000..673822b152
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/ShaderExecutableD3D.h
@@ -0,0 +1,57 @@
+//
+// Copyright 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.
+//
+
+// ShaderExecutable.h: Defines a class to contain D3D shader executable
+// implementation details.
+
+#ifndef LIBANGLE_RENDERER_D3D_SHADEREXECUTABLED3D_H_
+#define LIBANGLE_RENDERER_D3D_SHADEREXECUTABLED3D_H_
+
+#include "common/MemoryBuffer.h"
+#include "common/debug.h"
+
+#include <cstdint>
+#include <vector>
+
+namespace rx
+{
+
+class ShaderExecutableD3D : angle::NonCopyable
+{
+ public:
+ ShaderExecutableD3D(const void *function, size_t length);
+ virtual ~ShaderExecutableD3D();
+
+ const uint8_t *getFunction() const;
+
+ size_t getLength() const;
+
+ const std::string &getDebugInfo() const;
+
+ void appendDebugInfo(const std::string &info);
+
+ private:
+ std::vector<uint8_t> mFunctionBuffer;
+ std::string mDebugInfo;
+};
+
+class UniformStorageD3D : angle::NonCopyable
+{
+ public:
+ UniformStorageD3D(size_t initialSize);
+ virtual ~UniformStorageD3D();
+
+ size_t size() const;
+
+ uint8_t *getDataPointer(unsigned int registerIndex, unsigned int registerElement);
+
+ private:
+ angle::MemoryBuffer mUniformData;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_SHADEREXECUTABLED3D_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/SurfaceD3D.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/SurfaceD3D.cpp
new file mode 100644
index 0000000000..256808637f
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/SurfaceD3D.cpp
@@ -0,0 +1,517 @@
+//
+// 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.
+//
+
+// SurfaceD3D.cpp: D3D implementation of an EGL surface
+
+#include "libANGLE/renderer/d3d/SurfaceD3D.h"
+
+#include "libANGLE/Context.h"
+#include "libANGLE/Display.h"
+#include "libANGLE/Surface.h"
+#include "libANGLE/renderer/Format.h"
+#include "libANGLE/renderer/d3d/DisplayD3D.h"
+#include "libANGLE/renderer/d3d/RenderTargetD3D.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
+#include "libANGLE/renderer/d3d/SwapChainD3D.h"
+
+#include <EGL/eglext.h>
+#include <tchar.h>
+#include <algorithm>
+
+namespace rx
+{
+
+SurfaceD3D::SurfaceD3D(const egl::SurfaceState &state,
+ RendererD3D *renderer,
+ egl::Display *display,
+ EGLNativeWindowType window,
+ EGLenum buftype,
+ EGLClientBuffer clientBuffer,
+ const egl::AttributeMap &attribs)
+ : SurfaceImpl(state),
+ mRenderer(renderer),
+ mDisplay(display),
+ mFixedSize(window == nullptr || attribs.get(EGL_FIXED_SIZE_ANGLE, EGL_FALSE) == EGL_TRUE),
+ mFixedWidth(0),
+ mFixedHeight(0),
+ mOrientation(static_cast<EGLint>(attribs.get(EGL_SURFACE_ORIENTATION_ANGLE, 0))),
+ mRenderTargetFormat(state.config->renderTargetFormat),
+ mDepthStencilFormat(state.config->depthStencilFormat),
+ mColorFormat(nullptr),
+ mSwapChain(nullptr),
+ mSwapIntervalDirty(true),
+ mNativeWindow(renderer->createNativeWindow(window, state.config, attribs)),
+ mWidth(static_cast<EGLint>(attribs.get(EGL_WIDTH, 0))),
+ mHeight(static_cast<EGLint>(attribs.get(EGL_HEIGHT, 0))),
+ mSwapInterval(1),
+ mShareHandle(0),
+ mD3DTexture(nullptr),
+ mBuftype(buftype)
+{
+ if (window != nullptr && !mFixedSize)
+ {
+ mWidth = -1;
+ mHeight = -1;
+ }
+
+ if (mFixedSize)
+ {
+ mFixedWidth = mWidth;
+ mFixedHeight = mHeight;
+ }
+
+ switch (buftype)
+ {
+ case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE:
+ mShareHandle = static_cast<HANDLE>(clientBuffer);
+ break;
+
+ case EGL_D3D_TEXTURE_ANGLE:
+ mD3DTexture = static_cast<IUnknown *>(clientBuffer);
+ ASSERT(mD3DTexture != nullptr);
+ mD3DTexture->AddRef();
+ break;
+
+ default:
+ break;
+ }
+}
+
+SurfaceD3D::~SurfaceD3D()
+{
+ releaseSwapChain();
+ SafeDelete(mNativeWindow);
+ SafeRelease(mD3DTexture);
+}
+
+void SurfaceD3D::releaseSwapChain()
+{
+ SafeDelete(mSwapChain);
+}
+
+egl::Error SurfaceD3D::initialize(const egl::Display *display)
+{
+ if (mNativeWindow->getNativeWindow())
+ {
+ if (!mNativeWindow->initialize())
+ {
+ return egl::EglBadSurface();
+ }
+ }
+
+ if (mBuftype == EGL_D3D_TEXTURE_ANGLE)
+ {
+ ANGLE_TRY(mRenderer->getD3DTextureInfo(mState.config, mD3DTexture, mState.attributes,
+ &mFixedWidth, &mFixedHeight, nullptr, nullptr,
+ &mColorFormat, nullptr));
+ if (mState.attributes.contains(EGL_GL_COLORSPACE))
+ {
+ if (mColorFormat->id != angle::FormatID::R8G8B8A8_TYPELESS &&
+ mColorFormat->id != angle::FormatID::B8G8R8A8_TYPELESS)
+ {
+ return egl::EglBadMatch()
+ << "EGL_GL_COLORSPACE may only be specified for TYPELESS textures";
+ }
+ }
+ if (mColorFormat->id == angle::FormatID::R8G8B8A8_TYPELESS)
+ {
+ EGLAttrib colorspace =
+ mState.attributes.get(EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_LINEAR);
+ if (colorspace == EGL_GL_COLORSPACE_SRGB)
+ {
+ mColorFormat = &angle::Format::Get(angle::FormatID::R8G8B8A8_TYPELESS_SRGB);
+ }
+ }
+ if (mColorFormat->id == angle::FormatID::B8G8R8A8_TYPELESS)
+ {
+ EGLAttrib colorspace =
+ mState.attributes.get(EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_LINEAR);
+ if (colorspace == EGL_GL_COLORSPACE_SRGB)
+ {
+ mColorFormat = &angle::Format::Get(angle::FormatID::B8G8R8A8_TYPELESS_SRGB);
+ }
+ }
+ mRenderTargetFormat = mColorFormat->fboImplementationInternalFormat;
+ }
+
+ ANGLE_TRY(resetSwapChain(display));
+ return egl::NoError();
+}
+
+egl::Error SurfaceD3D::bindTexImage(const gl::Context *, gl::Texture *, EGLint)
+{
+ return egl::NoError();
+}
+
+egl::Error SurfaceD3D::releaseTexImage(const gl::Context *, EGLint)
+{
+ return egl::NoError();
+}
+
+egl::Error SurfaceD3D::getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc)
+{
+ if (!mState.directComposition)
+ {
+ return egl::EglBadSurface()
+ << "getSyncValues: surface requires Direct Composition to be enabled";
+ }
+
+ return mSwapChain->getSyncValues(ust, msc, sbc);
+}
+
+egl::Error SurfaceD3D::getMscRate(EGLint *numerator, EGLint *denominator)
+{
+ UNIMPLEMENTED();
+ return egl::EglBadAccess();
+}
+
+egl::Error SurfaceD3D::resetSwapChain(const egl::Display *display)
+{
+ ASSERT(!mSwapChain);
+
+ int width;
+ int height;
+
+ if (!mFixedSize)
+ {
+ RECT windowRect;
+ if (!mNativeWindow->getClientRect(&windowRect))
+ {
+ ASSERT(false);
+
+ return egl::EglBadSurface() << "Could not retrieve the window dimensions";
+ }
+
+ width = windowRect.right - windowRect.left;
+ height = windowRect.bottom - windowRect.top;
+ }
+ else
+ {
+ // non-window surface - size is determined at creation
+ width = mFixedWidth;
+ height = mFixedHeight;
+ }
+
+ mSwapChain =
+ mRenderer->createSwapChain(mNativeWindow, mShareHandle, mD3DTexture, mRenderTargetFormat,
+ mDepthStencilFormat, mOrientation, mState.config->samples);
+ if (!mSwapChain)
+ {
+ return egl::EglBadAlloc();
+ }
+
+ // This is a bit risky to pass the proxy context here, but it can happen at almost any time.
+ DisplayD3D *displayD3D = GetImplAs<DisplayD3D>(display);
+ egl::Error error = resetSwapChain(displayD3D, width, height);
+ if (error.isError())
+ {
+ SafeDelete(mSwapChain);
+ return error;
+ }
+
+ return egl::NoError();
+}
+
+egl::Error SurfaceD3D::resizeSwapChain(DisplayD3D *displayD3D,
+ int backbufferWidth,
+ int backbufferHeight)
+{
+ ASSERT(backbufferWidth >= 0 && backbufferHeight >= 0);
+ ASSERT(mSwapChain);
+
+ EGLint status =
+ mSwapChain->resize(displayD3D, std::max(1, backbufferWidth), std::max(1, backbufferHeight));
+
+ if (status == EGL_CONTEXT_LOST)
+ {
+ mDisplay->notifyDeviceLost();
+ return egl::Error(status);
+ }
+ else if (status != EGL_SUCCESS)
+ {
+ return egl::Error(status);
+ }
+
+ mWidth = backbufferWidth;
+ mHeight = backbufferHeight;
+
+ return egl::NoError();
+}
+
+egl::Error SurfaceD3D::resetSwapChain(DisplayD3D *displayD3D,
+ int backbufferWidth,
+ int backbufferHeight)
+{
+ ASSERT(backbufferWidth >= 0 && backbufferHeight >= 0);
+ ASSERT(mSwapChain);
+
+ EGLint status = mSwapChain->reset(displayD3D, std::max(1, backbufferWidth),
+ std::max(1, backbufferHeight), mSwapInterval);
+
+ if (status == EGL_CONTEXT_LOST)
+ {
+ mRenderer->notifyDeviceLost();
+ return egl::Error(status);
+ }
+ else if (status != EGL_SUCCESS)
+ {
+ return egl::Error(status);
+ }
+
+ mWidth = backbufferWidth;
+ mHeight = backbufferHeight;
+ mSwapIntervalDirty = false;
+
+ return egl::NoError();
+}
+
+egl::Error SurfaceD3D::swapRect(DisplayD3D *displayD3D,
+ EGLint x,
+ EGLint y,
+ EGLint width,
+ EGLint height)
+{
+ if (!mSwapChain)
+ {
+ return egl::NoError();
+ }
+
+ if (x + width > mWidth)
+ {
+ width = mWidth - x;
+ }
+
+ if (y + height > mHeight)
+ {
+ height = mHeight - y;
+ }
+
+ if (width != 0 && height != 0)
+ {
+ EGLint status = mSwapChain->swapRect(displayD3D, x, y, width, height);
+
+ if (status == EGL_CONTEXT_LOST)
+ {
+ mRenderer->notifyDeviceLost();
+ return egl::Error(status);
+ }
+ else if (status != EGL_SUCCESS)
+ {
+ return egl::Error(status);
+ }
+ }
+
+ ANGLE_TRY(checkForOutOfDateSwapChain(displayD3D));
+
+ return egl::NoError();
+}
+
+egl::Error SurfaceD3D::checkForOutOfDateSwapChain(DisplayD3D *displayD3D)
+{
+ RECT client;
+ int clientWidth = getWidth();
+ int clientHeight = getHeight();
+ bool sizeDirty = false;
+ if (!mFixedSize && !mNativeWindow->isIconic())
+ {
+ // The window is automatically resized to 150x22 when it's minimized, but the swapchain
+ // shouldn't be resized because that's not a useful size to render to.
+ if (!mNativeWindow->getClientRect(&client))
+ {
+ UNREACHABLE();
+ return egl::NoError();
+ }
+
+ // Grow the buffer now, if the window has grown. We need to grow now to avoid losing
+ // information.
+ clientWidth = client.right - client.left;
+ clientHeight = client.bottom - client.top;
+ sizeDirty = clientWidth != getWidth() || clientHeight != getHeight();
+ }
+ else if (mFixedSize)
+ {
+ clientWidth = mFixedWidth;
+ clientHeight = mFixedHeight;
+ sizeDirty = mFixedWidth != getWidth() || mFixedHeight != getHeight();
+ }
+
+ if (mSwapIntervalDirty)
+ {
+ ANGLE_TRY(resetSwapChain(displayD3D, clientWidth, clientHeight));
+ }
+ else if (sizeDirty)
+ {
+ ANGLE_TRY(resizeSwapChain(displayD3D, clientWidth, clientHeight));
+ }
+
+ return egl::NoError();
+}
+
+egl::Error SurfaceD3D::swap(const gl::Context *context)
+{
+ DisplayD3D *displayD3D = GetImplAs<DisplayD3D>(context->getDisplay());
+ return swapRect(displayD3D, 0, 0, mWidth, mHeight);
+}
+
+egl::Error SurfaceD3D::postSubBuffer(const gl::Context *context,
+ EGLint x,
+ EGLint y,
+ EGLint width,
+ EGLint height)
+{
+ DisplayD3D *displayD3D = GetImplAs<DisplayD3D>(context->getDisplay());
+ return swapRect(displayD3D, x, y, width, height);
+}
+
+rx::SwapChainD3D *SurfaceD3D::getSwapChain() const
+{
+ return mSwapChain;
+}
+
+void SurfaceD3D::setSwapInterval(EGLint interval)
+{
+ if (mSwapInterval == interval)
+ {
+ return;
+ }
+
+ mSwapInterval = interval;
+ mSwapIntervalDirty = true;
+}
+
+void SurfaceD3D::setFixedWidth(EGLint width)
+{
+ mFixedWidth = width;
+}
+
+void SurfaceD3D::setFixedHeight(EGLint height)
+{
+ mFixedHeight = height;
+}
+
+EGLint SurfaceD3D::getWidth() const
+{
+ return mWidth;
+}
+
+EGLint SurfaceD3D::getHeight() const
+{
+ return mHeight;
+}
+
+EGLint SurfaceD3D::isPostSubBufferSupported() const
+{
+ // post sub buffer is always possible on D3D surfaces
+ return EGL_TRUE;
+}
+
+EGLint SurfaceD3D::getSwapBehavior() const
+{
+ return EGL_BUFFER_PRESERVED;
+}
+
+egl::Error SurfaceD3D::querySurfacePointerANGLE(EGLint attribute, void **value)
+{
+ if (attribute == EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE)
+ {
+ *value = mSwapChain->getShareHandle();
+ }
+ else if (attribute == EGL_DXGI_KEYED_MUTEX_ANGLE)
+ {
+ *value = mSwapChain->getKeyedMutex();
+ }
+ else
+ UNREACHABLE();
+
+ return egl::NoError();
+}
+
+const angle::Format *SurfaceD3D::getD3DTextureColorFormat() const
+{
+ return mColorFormat;
+}
+
+egl::Error SurfaceD3D::attachToFramebuffer(const gl::Context *context, gl::Framebuffer *framebuffer)
+{
+ return egl::NoError();
+}
+
+egl::Error SurfaceD3D::detachFromFramebuffer(const gl::Context *context,
+ gl::Framebuffer *framebuffer)
+{
+ return egl::NoError();
+}
+
+angle::Result SurfaceD3D::getAttachmentRenderTarget(const gl::Context *context,
+ GLenum binding,
+ const gl::ImageIndex &imageIndex,
+ GLsizei samples,
+ FramebufferAttachmentRenderTarget **rtOut)
+{
+ if (binding == GL_BACK)
+ {
+ *rtOut = mSwapChain->getColorRenderTarget();
+ }
+ else
+ {
+ *rtOut = mSwapChain->getDepthStencilRenderTarget();
+ }
+ return angle::Result::Continue;
+}
+
+angle::Result SurfaceD3D::initializeContents(const gl::Context *context,
+ GLenum binding,
+ const gl::ImageIndex &imageIndex)
+{
+ switch (binding)
+ {
+ case GL_BACK:
+ ASSERT(mState.config->renderTargetFormat != GL_NONE);
+ ANGLE_TRY(mRenderer->initRenderTarget(context, mSwapChain->getColorRenderTarget()));
+ break;
+
+ case GL_DEPTH:
+ case GL_STENCIL:
+ ASSERT(mState.config->depthStencilFormat != GL_NONE);
+ ANGLE_TRY(
+ mRenderer->initRenderTarget(context, mSwapChain->getDepthStencilRenderTarget()));
+ break;
+
+ default:
+ UNREACHABLE();
+ break;
+ }
+ return angle::Result::Continue;
+}
+
+WindowSurfaceD3D::WindowSurfaceD3D(const egl::SurfaceState &state,
+ RendererD3D *renderer,
+ egl::Display *display,
+ EGLNativeWindowType window,
+ const egl::AttributeMap &attribs)
+ : SurfaceD3D(state, renderer, display, window, 0, static_cast<EGLClientBuffer>(0), attribs)
+{}
+
+WindowSurfaceD3D::~WindowSurfaceD3D() {}
+
+PbufferSurfaceD3D::PbufferSurfaceD3D(const egl::SurfaceState &state,
+ RendererD3D *renderer,
+ egl::Display *display,
+ EGLenum buftype,
+ EGLClientBuffer clientBuffer,
+ const egl::AttributeMap &attribs)
+ : SurfaceD3D(state,
+ renderer,
+ display,
+ static_cast<EGLNativeWindowType>(0),
+ buftype,
+ clientBuffer,
+ attribs)
+{}
+
+PbufferSurfaceD3D::~PbufferSurfaceD3D() {}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/SurfaceD3D.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/SurfaceD3D.h
new file mode 100644
index 0000000000..720943c8d1
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/SurfaceD3D.h
@@ -0,0 +1,145 @@
+//
+// 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.
+//
+
+// SurfaceD3D.h: D3D implementation of an EGL surface
+
+#ifndef LIBANGLE_RENDERER_D3D_SURFACED3D_H_
+#define LIBANGLE_RENDERER_D3D_SURFACED3D_H_
+
+#include "libANGLE/renderer/SurfaceImpl.h"
+#include "libANGLE/renderer/d3d/NativeWindowD3D.h"
+
+namespace egl
+{
+class Surface;
+}
+
+namespace rx
+{
+class DisplayD3D;
+class SwapChainD3D;
+class RendererD3D;
+
+class SurfaceD3D : public SurfaceImpl
+{
+ public:
+ ~SurfaceD3D() override;
+ void releaseSwapChain();
+
+ egl::Error initialize(const egl::Display *display) override;
+
+ egl::Error swap(const gl::Context *context) override;
+ egl::Error postSubBuffer(const gl::Context *context,
+ EGLint x,
+ EGLint y,
+ EGLint width,
+ EGLint height) override;
+ egl::Error querySurfacePointerANGLE(EGLint attribute, void **value) override;
+ egl::Error bindTexImage(const gl::Context *context,
+ gl::Texture *texture,
+ EGLint buffer) override;
+ egl::Error releaseTexImage(const gl::Context *context, EGLint buffer) override;
+ egl::Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) override;
+ egl::Error getMscRate(EGLint *numerator, EGLint *denominator) override;
+ void setSwapInterval(EGLint interval) override;
+ void setFixedWidth(EGLint width) override;
+ void setFixedHeight(EGLint height) override;
+
+ EGLint getWidth() const override;
+ EGLint getHeight() const override;
+
+ EGLint isPostSubBufferSupported() const override;
+ EGLint getSwapBehavior() const override;
+
+ // D3D implementations
+ SwapChainD3D *getSwapChain() const;
+
+ egl::Error resetSwapChain(const egl::Display *display);
+
+ egl::Error checkForOutOfDateSwapChain(DisplayD3D *displayD3D);
+
+ angle::Result getAttachmentRenderTarget(const gl::Context *context,
+ GLenum binding,
+ const gl::ImageIndex &imageIndex,
+ GLsizei samples,
+ FramebufferAttachmentRenderTarget **rtOut) override;
+ angle::Result initializeContents(const gl::Context *context,
+ GLenum binding,
+ const gl::ImageIndex &imageIndex) override;
+
+ const angle::Format *getD3DTextureColorFormat() const override;
+
+ egl::Error attachToFramebuffer(const gl::Context *context,
+ gl::Framebuffer *framebuffer) override;
+ egl::Error detachFromFramebuffer(const gl::Context *context,
+ gl::Framebuffer *framebuffer) override;
+
+ protected:
+ SurfaceD3D(const egl::SurfaceState &state,
+ RendererD3D *renderer,
+ egl::Display *display,
+ EGLNativeWindowType window,
+ EGLenum buftype,
+ EGLClientBuffer clientBuffer,
+ const egl::AttributeMap &attribs);
+
+ egl::Error swapRect(DisplayD3D *displayD3D, EGLint x, EGLint y, EGLint width, EGLint height);
+ egl::Error resetSwapChain(DisplayD3D *displayD3D, int backbufferWidth, int backbufferHeight);
+ egl::Error resizeSwapChain(DisplayD3D *displayD3D, int backbufferWidth, int backbufferHeight);
+
+ RendererD3D *mRenderer;
+ egl::Display *mDisplay;
+
+ bool mFixedSize;
+ GLint mFixedWidth;
+ GLint mFixedHeight;
+ GLint mOrientation;
+
+ GLenum mRenderTargetFormat;
+ GLenum mDepthStencilFormat;
+ const angle::Format *mColorFormat;
+
+ SwapChainD3D *mSwapChain;
+ bool mSwapIntervalDirty;
+
+ NativeWindowD3D *mNativeWindow; // Handler for the Window that the surface is created for.
+ EGLint mWidth;
+ EGLint mHeight;
+
+ EGLint mSwapInterval;
+
+ HANDLE mShareHandle;
+ IUnknown *mD3DTexture;
+
+ EGLenum mBuftype;
+};
+
+class WindowSurfaceD3D : public SurfaceD3D
+{
+ public:
+ WindowSurfaceD3D(const egl::SurfaceState &state,
+ RendererD3D *renderer,
+ egl::Display *display,
+ EGLNativeWindowType window,
+ const egl::AttributeMap &attribs);
+ ~WindowSurfaceD3D() override;
+};
+
+class PbufferSurfaceD3D : public SurfaceD3D
+{
+ public:
+ PbufferSurfaceD3D(const egl::SurfaceState &state,
+ RendererD3D *renderer,
+ egl::Display *display,
+ EGLenum buftype,
+ EGLClientBuffer clientBuffer,
+ const egl::AttributeMap &attribs);
+ ~PbufferSurfaceD3D() override;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_SURFACED3D_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/SwapChainD3D.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/SwapChainD3D.cpp
new file mode 100644
index 0000000000..8891888a68
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/SwapChainD3D.cpp
@@ -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.
+//
+
+// SwapChainD3D.cpp: Defines a back-end specific class that hides the details of the
+// implementation-specific swapchain.
+
+#include "libANGLE/renderer/d3d/SwapChainD3D.h"
+
+namespace rx
+{
+
+SwapChainD3D::SwapChainD3D(HANDLE shareHandle,
+ IUnknown *d3dTexture,
+ GLenum backBufferFormat,
+ GLenum depthBufferFormat)
+ : mOffscreenRenderTargetFormat(backBufferFormat),
+ mDepthBufferFormat(depthBufferFormat),
+ mShareHandle(shareHandle),
+ mD3DTexture(d3dTexture)
+{
+ if (mD3DTexture)
+ {
+ mD3DTexture->AddRef();
+ }
+}
+
+SwapChainD3D::~SwapChainD3D()
+{
+ SafeRelease(mD3DTexture);
+}
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/SwapChainD3D.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/SwapChainD3D.h
new file mode 100644
index 0000000000..fcbab95c8d
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/SwapChainD3D.h
@@ -0,0 +1,83 @@
+//
+// Copyright 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.
+//
+
+// SwapChainD3D.h: Defines a back-end specific class that hides the details of the
+// implementation-specific swapchain.
+
+#ifndef LIBANGLE_RENDERER_D3D_SWAPCHAIND3D_H_
+#define LIBANGLE_RENDERER_D3D_SWAPCHAIND3D_H_
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES2/gl2.h>
+
+#include "common/angleutils.h"
+#include "common/platform.h"
+#include "libANGLE/Error.h"
+
+#if !defined(ANGLE_FORCE_VSYNC_OFF)
+# define ANGLE_FORCE_VSYNC_OFF 0
+#endif
+
+namespace gl
+{
+class Context;
+} // namespace gl
+
+namespace egl
+{
+class Display;
+} // namespace egl
+
+namespace rx
+{
+class DisplayD3D;
+class RenderTargetD3D;
+
+class SwapChainD3D : angle::NonCopyable
+{
+ public:
+ SwapChainD3D(HANDLE shareHandle,
+ IUnknown *d3dTexture,
+ GLenum backBufferFormat,
+ GLenum depthBufferFormat);
+ virtual ~SwapChainD3D();
+
+ virtual EGLint resize(DisplayD3D *displayD3D,
+ EGLint backbufferWidth,
+ EGLint backbufferSize) = 0;
+ virtual EGLint reset(DisplayD3D *displayD3D,
+ EGLint backbufferWidth,
+ EGLint backbufferHeight,
+ EGLint swapInterval) = 0;
+ virtual EGLint swapRect(DisplayD3D *displayD3D,
+ EGLint x,
+ EGLint y,
+ EGLint width,
+ EGLint height) = 0;
+ virtual void recreate() = 0;
+
+ virtual RenderTargetD3D *getColorRenderTarget() = 0;
+ virtual RenderTargetD3D *getDepthStencilRenderTarget() = 0;
+
+ GLenum getRenderTargetInternalFormat() const { return mOffscreenRenderTargetFormat; }
+ GLenum getDepthBufferInternalFormat() const { return mDepthBufferFormat; }
+
+ HANDLE getShareHandle() { return mShareHandle; }
+ virtual void *getKeyedMutex() = 0;
+
+ virtual egl::Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) = 0;
+
+ protected:
+ const GLenum mOffscreenRenderTargetFormat;
+ const GLenum mDepthBufferFormat;
+
+ HANDLE mShareHandle;
+ IUnknown *mD3DTexture;
+};
+
+} // namespace rx
+#endif // LIBANGLE_RENDERER_D3D_SWAPCHAIND3D_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/TextureD3D.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/TextureD3D.cpp
new file mode 100644
index 0000000000..fc22f000be
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/TextureD3D.cpp
@@ -0,0 +1,4640 @@
+//
+// 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.
+//
+
+// TextureD3D.cpp: Implementations of the Texture interfaces shared betweeen the D3D backends.
+
+#include "libANGLE/renderer/d3d/TextureD3D.h"
+
+#include "common/mathutil.h"
+#include "common/utilities.h"
+#include "libANGLE/Buffer.h"
+#include "libANGLE/Config.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/Image.h"
+#include "libANGLE/Surface.h"
+#include "libANGLE/Texture.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/BufferImpl.h"
+#include "libANGLE/renderer/d3d/BufferD3D.h"
+#include "libANGLE/renderer/d3d/ContextD3D.h"
+#include "libANGLE/renderer/d3d/EGLImageD3D.h"
+#include "libANGLE/renderer/d3d/ImageD3D.h"
+#include "libANGLE/renderer/d3d/RenderTargetD3D.h"
+#include "libANGLE/renderer/d3d/SurfaceD3D.h"
+#include "libANGLE/renderer/d3d/TextureStorage.h"
+
+namespace rx
+{
+
+namespace
+{
+
+angle::Result GetUnpackPointer(const gl::Context *context,
+ const gl::PixelUnpackState &unpack,
+ gl::Buffer *unpackBuffer,
+ const uint8_t *pixels,
+ ptrdiff_t layerOffset,
+ const uint8_t **pointerOut)
+{
+ if (unpackBuffer)
+ {
+ // Do a CPU readback here, if we have an unpack buffer bound and the fast GPU path is not
+ // supported
+ ptrdiff_t offset = reinterpret_cast<ptrdiff_t>(pixels);
+
+ // TODO: this is the only place outside of renderer that asks for a buffers raw data.
+ // This functionality should be moved into renderer and the getData method of BufferImpl
+ // removed.
+ BufferD3D *bufferD3D = GetImplAs<BufferD3D>(unpackBuffer);
+ ASSERT(bufferD3D);
+ const uint8_t *bufferData = nullptr;
+ ANGLE_TRY(bufferD3D->getData(context, &bufferData));
+ *pointerOut = bufferData + offset;
+ }
+ else
+ {
+ *pointerOut = pixels;
+ }
+
+ // Offset the pointer for 2D array layer (if it's valid)
+ if (*pointerOut != nullptr)
+ {
+ *pointerOut += layerOffset;
+ }
+
+ return angle::Result::Continue;
+}
+
+bool IsRenderTargetUsage(GLenum usage)
+{
+ return (usage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
+}
+} // namespace
+
+TextureD3D::TextureD3D(const gl::TextureState &state, RendererD3D *renderer)
+ : TextureImpl(state),
+ mRenderer(renderer),
+ mDirtyImages(true),
+ mImmutable(false),
+ mTexStorage(nullptr),
+ mTexStorageObserverBinding(this, kTextureStorageObserverMessageIndex),
+ mBaseLevel(0)
+{}
+
+TextureD3D::~TextureD3D()
+{
+ ASSERT(!mTexStorage);
+}
+
+angle::Result TextureD3D::getNativeTexture(const gl::Context *context, TextureStorage **outStorage)
+{
+ // ensure the underlying texture is created
+ ANGLE_TRY(initializeStorage(context, BindFlags()));
+
+ if (mTexStorage)
+ {
+ ANGLE_TRY(updateStorage(context));
+ }
+
+ ASSERT(outStorage);
+
+ *outStorage = mTexStorage;
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D::getImageAndSyncFromStorage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ ImageD3D **outImage)
+{
+ ImageD3D *image = getImage(index);
+ if (mTexStorage && mTexStorage->isRenderTarget())
+ {
+ ANGLE_TRY(image->copyFromTexStorage(context, index, mTexStorage));
+ mDirtyImages = true;
+ }
+ image->markClean();
+ *outImage = image;
+ return angle::Result::Continue;
+}
+
+GLint TextureD3D::getLevelZeroWidth() const
+{
+ ASSERT(gl::CountLeadingZeros(static_cast<uint32_t>(getBaseLevelWidth())) > getBaseLevel());
+ return getBaseLevelWidth() << mBaseLevel;
+}
+
+GLint TextureD3D::getLevelZeroHeight() const
+{
+ ASSERT(gl::CountLeadingZeros(static_cast<uint32_t>(getBaseLevelHeight())) > getBaseLevel());
+ return getBaseLevelHeight() << mBaseLevel;
+}
+
+GLint TextureD3D::getLevelZeroDepth() const
+{
+ return getBaseLevelDepth();
+}
+
+GLint TextureD3D::getBaseLevelWidth() const
+{
+ const ImageD3D *baseImage = getBaseLevelImage();
+ return (baseImage ? baseImage->getWidth() : 0);
+}
+
+GLint TextureD3D::getBaseLevelHeight() const
+{
+ const ImageD3D *baseImage = getBaseLevelImage();
+ return (baseImage ? baseImage->getHeight() : 0);
+}
+
+GLint TextureD3D::getBaseLevelDepth() const
+{
+ const ImageD3D *baseImage = getBaseLevelImage();
+ return (baseImage ? baseImage->getDepth() : 0);
+}
+
+// Note: "base level image" is loosely defined to be any image from the base level,
+// where in the base of 2D array textures and cube maps there are several. Don't use
+// the base level image for anything except querying texture format and size.
+GLenum TextureD3D::getBaseLevelInternalFormat() const
+{
+ const ImageD3D *baseImage = getBaseLevelImage();
+ return (baseImage ? baseImage->getInternalFormat() : GL_NONE);
+}
+
+angle::Result TextureD3D::setStorage(const gl::Context *context,
+ gl::TextureType type,
+ size_t levels,
+ GLenum internalFormat,
+ const gl::Extents &size)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D::setStorageMultisample(const gl::Context *context,
+ gl::TextureType type,
+ GLsizei samples,
+ GLint internalformat,
+ const gl::Extents &size,
+ bool fixedSampleLocations)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D::setBuffer(const gl::Context *context, GLenum internalFormat)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D::setStorageExternalMemory(const gl::Context *context,
+ gl::TextureType type,
+ size_t levels,
+ GLenum internalFormat,
+ const gl::Extents &size,
+ gl::MemoryObject *memoryObject,
+ GLuint64 offset,
+ GLbitfield createFlags,
+ GLbitfield usageFlags,
+ const void *imageCreateInfoPNext)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
+ return angle::Result::Continue;
+}
+
+bool TextureD3D::couldUseSetData() const
+{
+ if (!mRenderer->getFeatures().setDataFasterThanImageUpload.enabled)
+ {
+ return false;
+ }
+
+ if (!mRenderer->getFeatures().setDataFasterThanImageUploadOn128bitFormats.enabled)
+ {
+ gl::InternalFormat internalFormat =
+ gl::GetSizedInternalFormatInfo(getBaseLevelInternalFormat());
+ return internalFormat.pixelBytes < 16;
+ }
+
+ return true;
+}
+
+bool TextureD3D::shouldUseSetData(const ImageD3D *image) const
+{
+ if (!couldUseSetData())
+ {
+ return false;
+ }
+
+ if (image->isDirty())
+ {
+ return false;
+ }
+
+ gl::InternalFormat internalFormat = gl::GetSizedInternalFormatInfo(image->getInternalFormat());
+
+ // We can only handle full updates for depth-stencil textures, so to avoid complications
+ // disable them entirely.
+ if (internalFormat.depthBits > 0 || internalFormat.stencilBits > 0)
+ {
+ return false;
+ }
+
+ // TODO(jmadill): Handle compressed internal formats
+ return (mTexStorage && !internalFormat.compressed);
+}
+
+angle::Result TextureD3D::setImageImpl(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLenum type,
+ const gl::PixelUnpackState &unpack,
+ gl::Buffer *unpackBuffer,
+ const uint8_t *pixels,
+ ptrdiff_t layerOffset)
+{
+ ImageD3D *image = getImage(index);
+ ASSERT(image);
+
+ // No-op
+ if (image->getWidth() == 0 || image->getHeight() == 0 || image->getDepth() == 0)
+ {
+ return angle::Result::Continue;
+ }
+
+ // We no longer need the "GLenum format" parameter to TexImage to determine what data format
+ // "pixels" contains. From our image internal format we know how many channels to expect, and
+ // "type" gives the format of pixel's components.
+ const uint8_t *pixelData = nullptr;
+ ANGLE_TRY(GetUnpackPointer(context, unpack, unpackBuffer, pixels, layerOffset, &pixelData));
+
+ if (pixelData != nullptr)
+ {
+ if (shouldUseSetData(image))
+ {
+ ANGLE_TRY(
+ mTexStorage->setData(context, index, image, nullptr, type, unpack, pixelData));
+ }
+ else
+ {
+ gl::Box fullImageArea(0, 0, 0, image->getWidth(), image->getHeight(),
+ image->getDepth());
+ ANGLE_TRY(image->loadData(context, fullImageArea, unpack, type, pixelData,
+ index.usesTex3D()));
+ }
+
+ mDirtyImages = true;
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D::subImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Box &area,
+ GLenum format,
+ GLenum type,
+ const gl::PixelUnpackState &unpack,
+ gl::Buffer *unpackBuffer,
+ const uint8_t *pixels,
+ ptrdiff_t layerOffset)
+{
+ // CPU readback & copy where direct GPU copy is not supported
+ const uint8_t *pixelData = nullptr;
+ ANGLE_TRY(GetUnpackPointer(context, unpack, unpackBuffer, pixels, layerOffset, &pixelData));
+
+ if (pixelData != nullptr)
+ {
+ ImageD3D *image = getImage(index);
+ ASSERT(image);
+
+ if (shouldUseSetData(image))
+ {
+ return mTexStorage->setData(context, index, image, &area, type, unpack, pixelData);
+ }
+
+ ANGLE_TRY(image->loadData(context, area, unpack, type, pixelData, index.usesTex3D()));
+ ANGLE_TRY(commitRegion(context, index, area));
+ mDirtyImages = true;
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D::setCompressedImageImpl(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::PixelUnpackState &unpack,
+ const uint8_t *pixels,
+ ptrdiff_t layerOffset)
+{
+ ImageD3D *image = getImage(index);
+ ASSERT(image);
+
+ if (image->getWidth() == 0 || image->getHeight() == 0 || image->getDepth() == 0)
+ {
+ return angle::Result::Continue;
+ }
+
+ // We no longer need the "GLenum format" parameter to TexImage to determine what data format
+ // "pixels" contains. From our image internal format we know how many channels to expect, and
+ // "type" gives the format of pixel's components.
+ const uint8_t *pixelData = nullptr;
+ gl::Buffer *unpackBuffer = context->getState().getTargetBuffer(gl::BufferBinding::PixelUnpack);
+ ANGLE_TRY(GetUnpackPointer(context, unpack, unpackBuffer, pixels, layerOffset, &pixelData));
+
+ if (pixelData != nullptr)
+ {
+ gl::Box fullImageArea(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth());
+ ANGLE_TRY(image->loadCompressedData(context, fullImageArea, pixelData));
+
+ mDirtyImages = true;
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D::subImageCompressed(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Box &area,
+ GLenum format,
+ const gl::PixelUnpackState &unpack,
+ const uint8_t *pixels,
+ ptrdiff_t layerOffset)
+{
+ const uint8_t *pixelData = nullptr;
+ gl::Buffer *unpackBuffer = context->getState().getTargetBuffer(gl::BufferBinding::PixelUnpack);
+ ANGLE_TRY(GetUnpackPointer(context, unpack, unpackBuffer, pixels, layerOffset, &pixelData));
+
+ if (pixelData != nullptr)
+ {
+ ImageD3D *image = getImage(index);
+ ASSERT(image);
+
+ ANGLE_TRY(image->loadCompressedData(context, area, pixelData));
+
+ mDirtyImages = true;
+ }
+
+ return angle::Result::Continue;
+}
+
+bool TextureD3D::isFastUnpackable(const gl::Buffer *unpackBuffer,
+ const gl::PixelUnpackState &unpack,
+ GLenum sizedInternalFormat)
+{
+ return unpackBuffer != nullptr && unpack.skipRows == 0 && unpack.skipPixels == 0 &&
+ unpack.imageHeight == 0 && unpack.skipImages == 0 &&
+ mRenderer->supportsFastCopyBufferToTexture(sizedInternalFormat);
+}
+
+angle::Result TextureD3D::fastUnpackPixels(const gl::Context *context,
+ const gl::PixelUnpackState &unpack,
+ gl::Buffer *unpackBuffer,
+ const uint8_t *pixels,
+ const gl::Box &destArea,
+ GLenum sizedInternalFormat,
+ GLenum type,
+ RenderTargetD3D *destRenderTarget)
+{
+ bool check = (unpack.skipRows != 0 || unpack.skipPixels != 0 || unpack.imageHeight != 0 ||
+ unpack.skipImages != 0);
+ ANGLE_CHECK(GetImplAs<ContextD3D>(context), !check,
+ "Unimplemented pixel store parameters in fastUnpackPixels", GL_INVALID_OPERATION);
+
+ // No-op
+ if (destArea.width <= 0 && destArea.height <= 0 && destArea.depth <= 0)
+ {
+ return angle::Result::Continue;
+ }
+
+ // In order to perform the fast copy through the shader, we must have the right format, and be
+ // able to create a render target.
+ ASSERT(mRenderer->supportsFastCopyBufferToTexture(sizedInternalFormat));
+
+ uintptr_t offset = reinterpret_cast<uintptr_t>(pixels);
+
+ ANGLE_TRY(mRenderer->fastCopyBufferToTexture(
+ context, unpack, unpackBuffer, static_cast<unsigned int>(offset), destRenderTarget,
+ sizedInternalFormat, type, destArea));
+
+ return angle::Result::Continue;
+}
+
+GLint TextureD3D::creationLevels(GLsizei width, GLsizei height, GLsizei depth) const
+{
+ if ((gl::isPow2(width) && gl::isPow2(height) && gl::isPow2(depth)) ||
+ mRenderer->getNativeExtensions().textureNpotOES)
+ {
+ // Maximum number of levels
+ return gl::log2(std::max(std::max(width, height), depth)) + 1;
+ }
+ else
+ {
+ // OpenGL ES 2.0 without GL_OES_texture_npot does not permit NPOT mipmaps.
+ return 1;
+ }
+}
+
+TextureStorage *TextureD3D::getStorage()
+{
+ ASSERT(mTexStorage);
+ return mTexStorage;
+}
+
+ImageD3D *TextureD3D::getBaseLevelImage() const
+{
+ if (mBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+ {
+ return nullptr;
+ }
+ return getImage(getImageIndex(mBaseLevel, 0));
+}
+
+angle::Result TextureD3D::setImageExternal(const gl::Context *context,
+ gl::TextureType type,
+ egl::Stream *stream,
+ const egl::Stream::GLTextureDescription &desc)
+{
+ // Only external images can accept external textures
+ ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D::generateMipmap(const gl::Context *context)
+{
+ const GLuint baseLevel = mState.getEffectiveBaseLevel();
+ const GLuint maxLevel = mState.getMipmapMaxLevel();
+ ASSERT(maxLevel > baseLevel); // Should be checked before calling this.
+
+ if (mTexStorage && mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
+ {
+ // Switch to using the mipmapped texture.
+ TextureStorage *textureStorageEXT = nullptr;
+ ANGLE_TRY(getNativeTexture(context, &textureStorageEXT));
+ ANGLE_TRY(textureStorageEXT->useLevelZeroWorkaroundTexture(context, false));
+ }
+
+ // Set up proper mipmap chain in our Image array.
+ ANGLE_TRY(initMipmapImages(context));
+
+ if (mTexStorage && mTexStorage->supportsNativeMipmapFunction())
+ {
+ ANGLE_TRY(updateStorage(context));
+
+ // Generate the mipmap chain using the ad-hoc DirectX function.
+ ANGLE_TRY(mRenderer->generateMipmapUsingD3D(context, mTexStorage, mState));
+ }
+ else
+ {
+ // Generate the mipmap chain, one level at a time.
+ ANGLE_TRY(generateMipmapUsingImages(context, maxLevel));
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D::generateMipmapUsingImages(const gl::Context *context,
+ const GLuint maxLevel)
+{
+ // We know that all layers have the same dimension, for the texture to be complete
+ GLint layerCount = static_cast<GLint>(getLayerCount(mBaseLevel));
+
+ if (mTexStorage && !mTexStorage->isRenderTarget() &&
+ canCreateRenderTargetForImage(getImageIndex(mBaseLevel, 0)) &&
+ mRenderer->getRendererClass() == RENDERER_D3D11)
+ {
+ if (!mRenderer->getFeatures().setDataFasterThanImageUpload.enabled)
+ {
+ ANGLE_TRY(updateStorage(context));
+ }
+ ANGLE_TRY(ensureRenderTarget(context));
+ }
+ else if (couldUseSetData() && mTexStorage)
+ {
+ // When making mipmaps with the setData workaround enabled, the texture storage has
+ // the image data already. For non-render-target storage, we have to pull it out into
+ // an image layer.
+ if (!mTexStorage->isRenderTarget())
+ {
+ // Copy from the storage mip 0 to Image mip 0
+ for (GLint layer = 0; layer < layerCount; ++layer)
+ {
+ gl::ImageIndex srcIndex = getImageIndex(mBaseLevel, layer);
+
+ ImageD3D *image = getImage(srcIndex);
+ ANGLE_TRY(image->copyFromTexStorage(context, srcIndex, mTexStorage));
+ }
+ }
+ else
+ {
+ ANGLE_TRY(updateStorage(context));
+ }
+ }
+
+ // TODO: Decouple this from zeroMaxLodWorkaround. This is a 9_3 restriction, unrelated to
+ // zeroMaxLodWorkaround. The restriction is because Feature Level 9_3 can't create SRVs on
+ // individual levels of the texture. As a result, even if the storage is a rendertarget, we
+ // can't use the GPU to generate the mipmaps without further work. The D3D9 renderer works
+ // around this by copying each level of the texture into its own single-layer GPU texture (in
+ // Blit9::boxFilter). Feature Level 9_3 could do something similar, or it could continue to use
+ // CPU-side mipmap generation, or something else.
+ bool renderableStorage = (mTexStorage && mTexStorage->isRenderTarget() &&
+ !(mRenderer->getFeatures().zeroMaxLodWorkaround.enabled));
+ if (renderableStorage)
+ {
+ ANGLE_TRY(updateStorage(context));
+ }
+
+ for (GLint layer = 0; layer < layerCount; ++layer)
+ {
+ for (GLuint mip = mBaseLevel + 1; mip <= maxLevel; ++mip)
+ {
+ ASSERT(getLayerCount(mip) == layerCount);
+
+ gl::ImageIndex sourceIndex = getImageIndex(mip - 1, layer);
+ gl::ImageIndex destIndex = getImageIndex(mip, layer);
+
+ if (renderableStorage)
+ {
+ // GPU-side mipmapping
+ ANGLE_TRY(mTexStorage->generateMipmap(context, sourceIndex, destIndex));
+ }
+ else
+ {
+ // CPU-side mipmapping
+ ANGLE_TRY(
+ mRenderer->generateMipmap(context, getImage(destIndex), getImage(sourceIndex)));
+ }
+ }
+ }
+
+ mDirtyImages = !renderableStorage;
+
+ if (mTexStorage && mDirtyImages)
+ {
+ ANGLE_TRY(updateStorage(context));
+ }
+
+ return angle::Result::Continue;
+}
+
+bool TextureD3D::isBaseImageZeroSize() const
+{
+ ImageD3D *baseImage = getBaseLevelImage();
+
+ if (!baseImage || baseImage->getWidth() <= 0 || baseImage->getHeight() <= 0)
+ {
+ return true;
+ }
+
+ if (baseImage->getType() == gl::TextureType::_3D && baseImage->getDepth() <= 0)
+ {
+ return true;
+ }
+
+ if (baseImage->getType() == gl::TextureType::_2DArray && getLayerCount(getBaseLevel()) <= 0)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+angle::Result TextureD3D::ensureBindFlags(const gl::Context *context, BindFlags bindFlags)
+{
+ ANGLE_TRY(initializeStorage(context, bindFlags));
+
+ // initializeStorage can fail with NoError if the texture is not complete. This is not
+ // an error for incomplete sampling, but it is a big problem for rendering.
+ if (!mTexStorage)
+ {
+ ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
+ return angle::Result::Stop;
+ }
+
+ if (!isBaseImageZeroSize())
+ {
+ ASSERT(mTexStorage);
+ if ((bindFlags.renderTarget && !mTexStorage->isRenderTarget()) ||
+ (bindFlags.unorderedAccess && !mTexStorage->isUnorderedAccess()))
+ {
+ TexStoragePointer newRenderTargetStorage;
+ ANGLE_TRY(createCompleteStorage(context, bindFlags, &newRenderTargetStorage));
+
+ ANGLE_TRY(mTexStorage->copyToStorage(context, newRenderTargetStorage.get()));
+ ANGLE_TRY(setCompleteTexStorage(context, newRenderTargetStorage.get()));
+ newRenderTargetStorage.release();
+ // If this texture is used in compute shader, we should invalidate this texture so that
+ // the UAV/SRV is rebound again with this new texture storage in next dispatch call.
+ mTexStorage->invalidateTextures();
+ }
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D::ensureRenderTarget(const gl::Context *context)
+{
+ return ensureBindFlags(context, BindFlags::RenderTarget());
+}
+
+angle::Result TextureD3D::ensureUnorderedAccess(const gl::Context *context)
+{
+ return ensureBindFlags(context, BindFlags::UnorderedAccess());
+}
+
+bool TextureD3D::canCreateRenderTargetForImage(const gl::ImageIndex &index) const
+{
+ if (index.getType() == gl::TextureType::_2DMultisample ||
+ index.getType() == gl::TextureType::_2DMultisampleArray)
+ {
+ ASSERT(index.getType() != gl::TextureType::_2DMultisampleArray || index.hasLayer());
+ return true;
+ }
+
+ ImageD3D *image = getImage(index);
+ ASSERT(image);
+ bool levelsComplete = (isImageComplete(index) && isImageComplete(getImageIndex(0, 0)));
+ return (image->isRenderableFormat() && levelsComplete);
+}
+
+angle::Result TextureD3D::commitRegion(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Box &region)
+{
+ if (mTexStorage)
+ {
+ ASSERT(isValidIndex(index));
+ ImageD3D *image = getImage(index);
+ ANGLE_TRY(image->copyToStorage(context, mTexStorage, index, region));
+ image->markClean();
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D::getAttachmentRenderTarget(const gl::Context *context,
+ GLenum binding,
+ const gl::ImageIndex &imageIndex,
+ GLsizei samples,
+ FramebufferAttachmentRenderTarget **rtOut)
+{
+ RenderTargetD3D *rtD3D = nullptr;
+ ANGLE_TRY(getRenderTarget(context, imageIndex, samples, &rtD3D));
+ *rtOut = static_cast<FramebufferAttachmentRenderTarget *>(rtD3D);
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D::setBaseLevel(const gl::Context *context, GLuint baseLevel)
+{
+ const int oldStorageWidth = std::max(1, getLevelZeroWidth());
+ const int oldStorageHeight = std::max(1, getLevelZeroHeight());
+ const int oldStorageDepth = std::max(1, getLevelZeroDepth());
+ const int oldStorageFormat = getBaseLevelInternalFormat();
+ mBaseLevel = baseLevel;
+
+ // When the base level changes, the texture storage might not be valid anymore, since it could
+ // have been created based on the dimensions of the previous specified level range.
+ const int newStorageWidth = std::max(1, getLevelZeroWidth());
+ const int newStorageHeight = std::max(1, getLevelZeroHeight());
+ const int newStorageDepth = std::max(1, getLevelZeroDepth());
+ const int newStorageFormat = getBaseLevelInternalFormat();
+ if (mTexStorage &&
+ (newStorageWidth != oldStorageWidth || newStorageHeight != oldStorageHeight ||
+ newStorageDepth != oldStorageDepth || newStorageFormat != oldStorageFormat))
+ {
+ markAllImagesDirty();
+
+ // Iterate over all images, and backup the content if it's been used as a render target. The
+ // D3D11 backend can automatically restore images on storage destroy, but it only works for
+ // images that have been associated with the texture storage before, which is insufficient
+ // here.
+ if (mTexStorage->isRenderTarget())
+ {
+ gl::ImageIndexIterator iterator = imageIterator();
+ while (iterator.hasNext())
+ {
+ const gl::ImageIndex index = iterator.next();
+ const GLsizei samples = getRenderToTextureSamples();
+ RenderTargetD3D *renderTarget = nullptr;
+ ANGLE_TRY(mTexStorage->findRenderTarget(context, index, samples, &renderTarget));
+ if (renderTarget)
+ {
+ ANGLE_TRY(getImage(index)->copyFromTexStorage(context, index, mTexStorage));
+ }
+ }
+ }
+
+ ANGLE_TRY(releaseTexStorage(context, gl::TexLevelMask()));
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D::onLabelUpdate(const gl::Context *context)
+{
+ if (mTexStorage)
+ {
+ mTexStorage->setLabel(mState.getLabel());
+ }
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D::syncState(const gl::Context *context,
+ const gl::Texture::DirtyBits &dirtyBits,
+ gl::Command source)
+{
+ // This could be improved using dirty bits.
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D::releaseTexStorage(const gl::Context *context,
+ const gl::TexLevelMask &copyStorageToImagesMask)
+{
+ if (!mTexStorage)
+ {
+ return angle::Result::Continue;
+ }
+
+ if (mTexStorage->isRenderTarget())
+ {
+ const GLenum storageFormat = getBaseLevelInternalFormat();
+ const size_t storageLevels = mTexStorage->getLevelCount();
+
+ gl::ImageIndexIterator iterator = imageIterator();
+ while (iterator.hasNext())
+ {
+ const gl::ImageIndex index = iterator.next();
+ ImageD3D *image = getImage(index);
+ const int storageWidth = std::max(1, getLevelZeroWidth() >> index.getLevelIndex());
+ const int storageHeight = std::max(1, getLevelZeroHeight() >> index.getLevelIndex());
+ if (image && isImageComplete(index) && image->getWidth() == storageWidth &&
+ image->getHeight() == storageHeight &&
+ image->getInternalFormat() == storageFormat &&
+ index.getLevelIndex() < static_cast<int>(storageLevels) &&
+ copyStorageToImagesMask[index.getLevelIndex()])
+ {
+ ANGLE_TRY(image->copyFromTexStorage(context, index, mTexStorage));
+ }
+ }
+ }
+
+ onStateChange(angle::SubjectMessage::StorageReleased);
+
+ auto err = mTexStorage->onDestroy(context);
+ SafeDelete(mTexStorage);
+ return err;
+}
+
+void TextureD3D::onDestroy(const gl::Context *context)
+{
+ (void)releaseTexStorage(context, gl::TexLevelMask());
+}
+
+angle::Result TextureD3D::initializeContents(const gl::Context *context,
+ GLenum binding,
+ const gl::ImageIndex &imageIndex)
+{
+ ContextD3D *contextD3D = GetImplAs<ContextD3D>(context);
+ gl::ImageIndex index = imageIndex;
+
+ // Special case for D3D11 3D textures. We can't create render targets for individual layers of a
+ // 3D texture, so force the clear to the entire mip. There shouldn't ever be a case where we
+ // would lose existing data.
+ if (index.getType() == gl::TextureType::_3D)
+ {
+ index = gl::ImageIndex::Make3D(index.getLevelIndex(), gl::ImageIndex::kEntireLevel);
+ }
+ else if (index.getType() == gl::TextureType::_2DArray && !index.hasLayer())
+ {
+ std::array<GLint, gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS> tempLayerCounts;
+
+ GLint levelIndex = index.getLevelIndex();
+ tempLayerCounts[levelIndex] = getLayerCount(levelIndex);
+ gl::ImageIndexIterator iterator =
+ gl::ImageIndexIterator::Make2DArray(levelIndex, levelIndex + 1, tempLayerCounts.data());
+ while (iterator.hasNext())
+ {
+ ANGLE_TRY(initializeContents(context, GL_NONE, iterator.next()));
+ }
+ return angle::Result::Continue;
+ }
+ else if (index.getType() == gl::TextureType::_2DMultisampleArray && !index.hasLayer())
+ {
+ std::array<GLint, gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS> tempLayerCounts;
+
+ ASSERT(index.getLevelIndex() == 0);
+ tempLayerCounts[0] = getLayerCount(0);
+ gl::ImageIndexIterator iterator =
+ gl::ImageIndexIterator::Make2DMultisampleArray(tempLayerCounts.data());
+ while (iterator.hasNext())
+ {
+ ANGLE_TRY(initializeContents(context, GL_NONE, iterator.next()));
+ }
+ return angle::Result::Continue;
+ }
+
+ // Force image clean.
+ ImageD3D *image = getImage(index);
+ if (image)
+ {
+ image->markClean();
+ }
+
+ // Fast path: can use a render target clear.
+ // We don't use the fast path with the zero max lod workaround because it would introduce a race
+ // between the rendertarget and the staging images.
+ const angle::FeaturesD3D &features = mRenderer->getFeatures();
+ bool shouldUseClear = (image == nullptr);
+ if (canCreateRenderTargetForImage(index) && !features.zeroMaxLodWorkaround.enabled &&
+ (shouldUseClear || features.allowClearForRobustResourceInit.enabled))
+ {
+ ANGLE_TRY(ensureRenderTarget(context));
+ ASSERT(mTexStorage);
+ RenderTargetD3D *renderTarget = nullptr;
+ ANGLE_TRY(mTexStorage->getRenderTarget(context, index, 0, &renderTarget));
+ ANGLE_TRY(mRenderer->initRenderTarget(context, renderTarget));
+
+ // Force image clean again, the texture storage may have been re-created and the image used.
+ if (image)
+ {
+ image->markClean();
+ }
+
+ return angle::Result::Continue;
+ }
+
+ ASSERT(image != nullptr);
+
+ // Slow path: non-renderable texture or the texture levels aren't set up.
+ const auto &formatInfo = gl::GetSizedInternalFormatInfo(image->getInternalFormat());
+
+ GLuint imageBytes = 0;
+ ANGLE_CHECK_GL_MATH(contextD3D, formatInfo.computeRowPitch(formatInfo.type, image->getWidth(),
+ 1, 0, &imageBytes));
+ imageBytes *= image->getHeight() * image->getDepth();
+
+ gl::PixelUnpackState zeroDataUnpackState;
+ zeroDataUnpackState.alignment = 1;
+
+ angle::MemoryBuffer *zeroBuffer = nullptr;
+ ANGLE_CHECK_GL_ALLOC(contextD3D, context->getZeroFilledBuffer(imageBytes, &zeroBuffer));
+
+ if (shouldUseSetData(image))
+ {
+ ANGLE_TRY(mTexStorage->setData(context, index, image, nullptr, formatInfo.type,
+ zeroDataUnpackState, zeroBuffer->data()));
+ }
+ else
+ {
+ gl::Box fullImageArea(0, 0, 0, image->getWidth(), image->getHeight(), image->getDepth());
+ ANGLE_TRY(image->loadData(context, fullImageArea, zeroDataUnpackState, formatInfo.type,
+ zeroBuffer->data(), false));
+
+ // Force an update to the tex storage so we avoid problems with subImage and dirty regions.
+ if (mTexStorage)
+ {
+ ANGLE_TRY(commitRegion(context, index, fullImageArea));
+ image->markClean();
+ }
+ else
+ {
+ mDirtyImages = true;
+ }
+ }
+ return angle::Result::Continue;
+}
+
+GLsizei TextureD3D::getRenderToTextureSamples()
+{
+ if (mTexStorage)
+ {
+ return mTexStorage->getRenderToTextureSamples();
+ }
+ return 0;
+}
+
+void TextureD3D::onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message)
+{
+ onStateChange(message);
+}
+
+TextureD3D_2D::TextureD3D_2D(const gl::TextureState &state, RendererD3D *renderer)
+ : TextureD3D(state, renderer)
+{
+ mEGLImageTarget = false;
+ for (auto &image : mImageArray)
+ {
+ image.reset(renderer->createImage());
+ }
+}
+
+void TextureD3D_2D::onDestroy(const gl::Context *context)
+{
+ // Delete the Images before the TextureStorage. Images might be relying on the TextureStorage
+ // for some of their data. If TextureStorage is deleted before the Images, then their data will
+ // be wastefully copied back from the GPU before we delete the Images.
+ for (auto &image : mImageArray)
+ {
+ image.reset();
+ }
+ return TextureD3D::onDestroy(context);
+}
+
+TextureD3D_2D::~TextureD3D_2D() {}
+
+ImageD3D *TextureD3D_2D::getImage(int level, int layer) const
+{
+ ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+ ASSERT(layer == 0);
+ return mImageArray[level].get();
+}
+
+ImageD3D *TextureD3D_2D::getImage(const gl::ImageIndex &index) const
+{
+ ASSERT(index.getLevelIndex() < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+ ASSERT(!index.hasLayer());
+ ASSERT(index.getType() == gl::TextureType::_2D ||
+ index.getType() == gl::TextureType::VideoImage);
+ return mImageArray[index.getLevelIndex()].get();
+}
+
+GLsizei TextureD3D_2D::getLayerCount(int level) const
+{
+ ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+ return 1;
+}
+
+GLsizei TextureD3D_2D::getWidth(GLint level) const
+{
+ if (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+ return mImageArray[level]->getWidth();
+ else
+ return 0;
+}
+
+GLsizei TextureD3D_2D::getHeight(GLint level) const
+{
+ if (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+ return mImageArray[level]->getHeight();
+ else
+ return 0;
+}
+
+GLenum TextureD3D_2D::getInternalFormat(GLint level) const
+{
+ if (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+ return mImageArray[level]->getInternalFormat();
+ else
+ return GL_NONE;
+}
+
+bool TextureD3D_2D::isDepth(GLint level) const
+{
+ return gl::GetSizedInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
+}
+
+bool TextureD3D_2D::isSRGB(GLint level) const
+{
+ return gl::GetSizedInternalFormatInfo(getInternalFormat(level)).colorEncoding == GL_SRGB;
+}
+
+angle::Result TextureD3D_2D::setImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLenum internalFormat,
+ const gl::Extents &size,
+ GLenum format,
+ GLenum type,
+ const gl::PixelUnpackState &unpack,
+ gl::Buffer *unpackBuffer,
+ const uint8_t *pixels)
+{
+ ASSERT((index.getTarget() == gl::TextureTarget::_2D ||
+ index.getTarget() == gl::TextureTarget::VideoImage) &&
+ size.depth == 1);
+
+ const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat, type);
+
+ bool fastUnpacked = false;
+
+ ANGLE_TRY(redefineImage(context, index.getLevelIndex(), internalFormatInfo.sizedInternalFormat,
+ size, false));
+
+ // Attempt a fast gpu copy of the pixel data to the surface
+ if (mTexStorage)
+ {
+ ANGLE_TRY(mTexStorage->releaseMultisampledTexStorageForLevel(index.getLevelIndex()));
+ }
+ if (isFastUnpackable(unpackBuffer, unpack, internalFormatInfo.sizedInternalFormat) &&
+ isLevelComplete(index.getLevelIndex()))
+ {
+ // Will try to create RT storage if it does not exist
+ RenderTargetD3D *destRenderTarget = nullptr;
+ ANGLE_TRY(getRenderTarget(context, index, getRenderToTextureSamples(), &destRenderTarget));
+
+ gl::Box destArea(0, 0, 0, getWidth(index.getLevelIndex()), getHeight(index.getLevelIndex()),
+ 1);
+
+ ANGLE_TRY(fastUnpackPixels(context, unpack, unpackBuffer, pixels, destArea,
+ internalFormatInfo.sizedInternalFormat, type, destRenderTarget));
+
+ // Ensure we don't overwrite our newly initialized data
+ mImageArray[index.getLevelIndex()]->markClean();
+
+ fastUnpacked = true;
+ }
+
+ if (!fastUnpacked)
+ {
+ ANGLE_TRY(setImageImpl(context, index, type, unpack, unpackBuffer, pixels, 0));
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2D::setSubImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Box &area,
+ GLenum format,
+ GLenum type,
+ const gl::PixelUnpackState &unpack,
+ gl::Buffer *unpackBuffer,
+ const uint8_t *pixels)
+{
+ ASSERT(index.getTarget() == gl::TextureTarget::_2D && area.depth == 1 && area.z == 0);
+
+ GLenum mipFormat = getInternalFormat(index.getLevelIndex());
+ if (mTexStorage)
+ {
+ ANGLE_TRY(mTexStorage->releaseMultisampledTexStorageForLevel(index.getLevelIndex()));
+ }
+ if (isFastUnpackable(unpackBuffer, unpack, mipFormat) && isLevelComplete(index.getLevelIndex()))
+ {
+ RenderTargetD3D *renderTarget = nullptr;
+ ANGLE_TRY(getRenderTarget(context, index, getRenderToTextureSamples(), &renderTarget));
+ ASSERT(!mImageArray[index.getLevelIndex()]->isDirty());
+
+ return fastUnpackPixels(context, unpack, unpackBuffer, pixels, area, mipFormat, type,
+ renderTarget);
+ }
+ else
+ {
+ return TextureD3D::subImage(context, index, area, format, type, unpack, unpackBuffer,
+ pixels, 0);
+ }
+}
+
+angle::Result TextureD3D_2D::setCompressedImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLenum internalFormat,
+ const gl::Extents &size,
+ const gl::PixelUnpackState &unpack,
+ size_t imageSize,
+ const uint8_t *pixels)
+{
+ ASSERT(index.getTarget() == gl::TextureTarget::_2D && size.depth == 1);
+
+ // compressed formats don't have separate sized internal formats-- we can just use the
+ // compressed format directly
+ ANGLE_TRY(redefineImage(context, index.getLevelIndex(), internalFormat, size, false));
+
+ return setCompressedImageImpl(context, index, unpack, pixels, 0);
+}
+
+angle::Result TextureD3D_2D::setCompressedSubImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Box &area,
+ GLenum format,
+ const gl::PixelUnpackState &unpack,
+ size_t imageSize,
+ const uint8_t *pixels)
+{
+ ASSERT(index.getTarget() == gl::TextureTarget::_2D && area.depth == 1 && area.z == 0);
+ ANGLE_TRY(TextureD3D::subImageCompressed(context, index, area, format, unpack, pixels, 0));
+
+ return commitRegion(context, index, area);
+}
+
+angle::Result TextureD3D_2D::copyImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Rectangle &sourceArea,
+ GLenum internalFormat,
+ gl::Framebuffer *source)
+{
+ ASSERT(index.getTarget() == gl::TextureTarget::_2D);
+
+ const gl::InternalFormat &internalFormatInfo =
+ gl::GetInternalFormatInfo(internalFormat, GL_UNSIGNED_BYTE);
+ gl::Extents sourceExtents(sourceArea.width, sourceArea.height, 1);
+ ANGLE_TRY(redefineImage(context, index.getLevelIndex(), internalFormatInfo.sizedInternalFormat,
+ sourceExtents, false));
+
+ gl::Extents fbSize = source->getReadColorAttachment()->getSize();
+
+ // Does the read area extend beyond the framebuffer?
+ bool outside = sourceArea.x < 0 || sourceArea.y < 0 ||
+ sourceArea.x + sourceArea.width > fbSize.width ||
+ sourceArea.y + sourceArea.height > fbSize.height;
+
+ // WebGL requires that pixels that would be outside the framebuffer are treated as zero values,
+ // so clear the mip level to 0 prior to making the copy if any pixel would be sampled outside.
+ // Same thing for robust resource init.
+ if (outside && (context->isWebGL() || context->isRobustResourceInitEnabled()))
+ {
+ ANGLE_TRY(initializeContents(context, GL_NONE, index));
+ }
+
+ gl::Rectangle clippedArea;
+ if (!ClipRectangle(sourceArea, gl::Rectangle(0, 0, fbSize.width, fbSize.height), &clippedArea))
+ {
+ // Empty source area, nothing to do.
+ return angle::Result::Continue;
+ }
+
+ gl::Offset destOffset(clippedArea.x - sourceArea.x, clippedArea.y - sourceArea.y, 0);
+
+ // If the zero max LOD workaround is active, then we can't sample from individual layers of the
+ // framebuffer in shaders, so we should use the non-rendering copy path.
+ if (!canCreateRenderTargetForImage(index) ||
+ mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
+ {
+ ANGLE_TRY(mImageArray[index.getLevelIndex()]->copyFromFramebuffer(context, destOffset,
+ clippedArea, source));
+ mDirtyImages = true;
+ }
+ else
+ {
+ ANGLE_TRY(ensureRenderTarget(context));
+
+ if (clippedArea.width != 0 && clippedArea.height != 0 &&
+ isValidLevel(index.getLevelIndex()))
+ {
+ ANGLE_TRY(updateStorageLevel(context, index.getLevelIndex()));
+ ANGLE_TRY(mRenderer->copyImage2D(context, source, clippedArea, internalFormat,
+ destOffset, mTexStorage, index.getLevelIndex()));
+ }
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2D::copySubImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Offset &destOffset,
+ const gl::Rectangle &sourceArea,
+ gl::Framebuffer *source)
+{
+ ASSERT(index.getTarget() == gl::TextureTarget::_2D && destOffset.z == 0);
+
+ gl::Extents fbSize = source->getReadColorAttachment()->getSize();
+ gl::Rectangle clippedArea;
+ if (!ClipRectangle(sourceArea, gl::Rectangle(0, 0, fbSize.width, fbSize.height), &clippedArea))
+ {
+ return angle::Result::Continue;
+ }
+ const gl::Offset clippedOffset(destOffset.x + clippedArea.x - sourceArea.x,
+ destOffset.y + clippedArea.y - sourceArea.y, 0);
+
+ // can only make our texture storage to a render target if level 0 is defined (with a width &
+ // height) and the current level we're copying to is defined (with appropriate format, width &
+ // height)
+
+ // If the zero max LOD workaround is active, then we can't sample from individual layers of the
+ // framebuffer in shaders, so we should use the non-rendering copy path.
+ if (!canCreateRenderTargetForImage(index) ||
+ mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
+ {
+ ANGLE_TRY(mImageArray[index.getLevelIndex()]->copyFromFramebuffer(context, clippedOffset,
+ clippedArea, source));
+ mDirtyImages = true;
+ onStateChange(angle::SubjectMessage::DirtyBitsFlagged);
+ }
+ else
+ {
+ ANGLE_TRY(ensureRenderTarget(context));
+
+ if (isValidLevel(index.getLevelIndex()))
+ {
+ ANGLE_TRY(updateStorageLevel(context, index.getLevelIndex()));
+ ANGLE_TRY(mRenderer->copyImage2D(context, source, clippedArea,
+ gl::GetUnsizedFormat(getBaseLevelInternalFormat()),
+ clippedOffset, mTexStorage, index.getLevelIndex()));
+ }
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2D::copyTexture(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLenum internalFormat,
+ GLenum type,
+ GLint sourceLevel,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha,
+ const gl::Texture *source)
+{
+ ASSERT(index.getTarget() == gl::TextureTarget::_2D);
+
+ gl::TextureType sourceType = source->getType();
+
+ const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat, type);
+ gl::Extents size(
+ static_cast<int>(source->getWidth(NonCubeTextureTypeToTarget(sourceType), sourceLevel)),
+ static_cast<int>(source->getHeight(NonCubeTextureTypeToTarget(sourceType), sourceLevel)),
+ 1);
+ ANGLE_TRY(redefineImage(context, index.getLevelIndex(), internalFormatInfo.sizedInternalFormat,
+ size, false));
+
+ gl::Box sourceBox(0, 0, 0, size.width, size.height, 1);
+ gl::Offset destOffset(0, 0, 0);
+
+ if (!isSRGB(index.getLevelIndex()) && canCreateRenderTargetForImage(index))
+ {
+ ANGLE_TRY(ensureRenderTarget(context));
+ ASSERT(isValidLevel(index.getLevelIndex()));
+ ANGLE_TRY(updateStorageLevel(context, index.getLevelIndex()));
+
+ ANGLE_TRY(mRenderer->copyTexture(context, source, sourceLevel, gl::TextureTarget::_2D,
+ sourceBox, internalFormatInfo.format,
+ internalFormatInfo.type, destOffset, mTexStorage,
+ index.getTarget(), index.getLevelIndex(), unpackFlipY,
+ unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
+ }
+ else
+ {
+ gl::ImageIndex sourceImageIndex = gl::ImageIndex::Make2D(sourceLevel);
+ TextureD3D *sourceD3D = GetImplAs<TextureD3D>(source);
+ ImageD3D *sourceImage = nullptr;
+ ANGLE_TRY(sourceD3D->getImageAndSyncFromStorage(context, sourceImageIndex, &sourceImage));
+
+ ImageD3D *destImage = nullptr;
+ ANGLE_TRY(getImageAndSyncFromStorage(context, index, &destImage));
+
+ ANGLE_TRY(mRenderer->copyImage(context, destImage, sourceImage, sourceBox, destOffset,
+ unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
+
+ mDirtyImages = true;
+
+ gl::Box destRegion(destOffset, size);
+ ANGLE_TRY(commitRegion(context, index, destRegion));
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2D::copySubTexture(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Offset &destOffset,
+ GLint sourceLevel,
+ const gl::Box &sourceBox,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha,
+ const gl::Texture *source)
+{
+ ASSERT(index.getTarget() == gl::TextureTarget::_2D);
+
+ if (!isSRGB(index.getLevelIndex()) && canCreateRenderTargetForImage(index))
+ {
+ ANGLE_TRY(ensureRenderTarget(context));
+ ASSERT(isValidLevel(index.getLevelIndex()));
+ ANGLE_TRY(updateStorageLevel(context, index.getLevelIndex()));
+
+ const gl::InternalFormat &internalFormatInfo =
+ gl::GetSizedInternalFormatInfo(getInternalFormat(index.getLevelIndex()));
+ ANGLE_TRY(mRenderer->copyTexture(context, source, sourceLevel, gl::TextureTarget::_2D,
+ sourceBox, internalFormatInfo.format,
+ internalFormatInfo.type, destOffset, mTexStorage,
+ index.getTarget(), index.getLevelIndex(), unpackFlipY,
+ unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
+ }
+ else
+ {
+ gl::ImageIndex sourceImageIndex = gl::ImageIndex::Make2D(sourceLevel);
+ TextureD3D *sourceD3D = GetImplAs<TextureD3D>(source);
+ ImageD3D *sourceImage = nullptr;
+ ANGLE_TRY(sourceD3D->getImageAndSyncFromStorage(context, sourceImageIndex, &sourceImage));
+
+ ImageD3D *destImage = nullptr;
+ ANGLE_TRY(getImageAndSyncFromStorage(context, index, &destImage));
+
+ ANGLE_TRY(mRenderer->copyImage(context, destImage, sourceImage, sourceBox, destOffset,
+ unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
+
+ mDirtyImages = true;
+
+ gl::Box destRegion(destOffset.x, destOffset.y, 0, sourceBox.width, sourceBox.height, 1);
+ ANGLE_TRY(commitRegion(context, index, destRegion));
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2D::copyCompressedTexture(const gl::Context *context,
+ const gl::Texture *source)
+{
+ gl::TextureTarget sourceTarget = NonCubeTextureTypeToTarget(source->getType());
+ GLint sourceLevel = 0;
+
+ GLint destLevel = 0;
+
+ GLenum sizedInternalFormat =
+ source->getFormat(sourceTarget, sourceLevel).info->sizedInternalFormat;
+ gl::Extents size(static_cast<int>(source->getWidth(sourceTarget, sourceLevel)),
+ static_cast<int>(source->getHeight(sourceTarget, sourceLevel)), 1);
+ ANGLE_TRY(redefineImage(context, destLevel, sizedInternalFormat, size, false));
+
+ ANGLE_TRY(initializeStorage(context, BindFlags()));
+ ASSERT(mTexStorage);
+
+ ANGLE_TRY(
+ mRenderer->copyCompressedTexture(context, source, sourceLevel, mTexStorage, destLevel));
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2D::setStorage(const gl::Context *context,
+ gl::TextureType type,
+ size_t levels,
+ GLenum internalFormat,
+ const gl::Extents &size)
+{
+ ASSERT(type == gl::TextureType::_2D && size.depth == 1);
+
+ for (size_t level = 0; level < levels; level++)
+ {
+ gl::Extents levelSize(std::max(1, size.width >> level), std::max(1, size.height >> level),
+ 1);
+ ANGLE_TRY(redefineImage(context, level, internalFormat, levelSize, true));
+ }
+
+ for (size_t level = levels; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
+ {
+ ANGLE_TRY(redefineImage(context, level, GL_NONE, gl::Extents(0, 0, 1), true));
+ }
+
+ // TODO(geofflang): Verify storage creation had no errors
+ BindFlags flags;
+ flags.renderTarget = IsRenderTargetUsage(mState.getUsage());
+ TexStoragePointer storage = {
+ mRenderer->createTextureStorage2D(internalFormat, flags, size.width, size.height,
+ static_cast<int>(levels), mState.getLabel(), false),
+ context};
+
+ ANGLE_TRY(setCompleteTexStorage(context, storage.get()));
+ storage.release();
+
+ ANGLE_TRY(updateStorage(context));
+
+ mImmutable = true;
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2D::bindTexImage(const gl::Context *context, egl::Surface *surface)
+{
+ GLenum internalformat = surface->getConfig()->renderTargetFormat;
+
+ gl::Extents size(surface->getWidth(), surface->getHeight(), 1);
+ ANGLE_TRY(redefineImage(context, 0, internalformat, size, true));
+
+ ANGLE_TRY(releaseTexStorage(context, gl::TexLevelMask()));
+
+ SurfaceD3D *surfaceD3D = GetImplAs<SurfaceD3D>(surface);
+ ASSERT(surfaceD3D);
+
+ mTexStorage = mRenderer->createTextureStorage2D(surfaceD3D->getSwapChain(), mState.getLabel());
+ mEGLImageTarget = false;
+
+ mDirtyImages = false;
+ mImageArray[0]->markClean();
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2D::releaseTexImage(const gl::Context *context)
+{
+ if (mTexStorage)
+ {
+ ANGLE_TRY(releaseTexStorage(context, gl::TexLevelMask()));
+ }
+
+ for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+ {
+ ANGLE_TRY(redefineImage(context, i, GL_NONE, gl::Extents(0, 0, 1), true));
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2D::setEGLImageTarget(const gl::Context *context,
+ gl::TextureType type,
+ egl::Image *image)
+{
+ EGLImageD3D *eglImaged3d = GetImplAs<EGLImageD3D>(image);
+
+ // Set the properties of the base mip level from the EGL image
+ const auto &format = image->getFormat();
+ gl::Extents size(static_cast<int>(image->getWidth()), static_cast<int>(image->getHeight()), 1);
+ ANGLE_TRY(redefineImage(context, 0, format.info->sizedInternalFormat, size, true));
+
+ // Clear all other images.
+ for (size_t level = 1; level < mImageArray.size(); level++)
+ {
+ ANGLE_TRY(redefineImage(context, level, GL_NONE, gl::Extents(0, 0, 1), true));
+ }
+
+ ANGLE_TRY(releaseTexStorage(context, gl::TexLevelMask()));
+ mImageArray[0]->markClean();
+
+ // Pass in the RenderTargetD3D here: createTextureStorage can't generate an error.
+ RenderTargetD3D *renderTargetD3D = nullptr;
+ ANGLE_TRY(eglImaged3d->getRenderTarget(context, &renderTargetD3D));
+
+ mTexStorage =
+ mRenderer->createTextureStorageEGLImage(eglImaged3d, renderTargetD3D, mState.getLabel());
+ mEGLImageTarget = true;
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2D::initMipmapImages(const gl::Context *context)
+{
+ const GLuint baseLevel = mState.getEffectiveBaseLevel();
+ const GLuint maxLevel = mState.getMipmapMaxLevel();
+ // Purge array levels baseLevel + 1 through q and reset them to represent the generated mipmap
+ // levels.
+ for (GLuint level = baseLevel + 1; level <= maxLevel; level++)
+ {
+ gl::Extents levelSize(std::max(getLevelZeroWidth() >> level, 1),
+ std::max(getLevelZeroHeight() >> level, 1), 1);
+
+ ANGLE_TRY(redefineImage(context, level, getBaseLevelInternalFormat(), levelSize, false));
+ }
+
+ // We should be mip-complete now so generate the storage.
+ ANGLE_TRY(initializeStorage(context, BindFlags::RenderTarget()));
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2D::getRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT)
+{
+ ASSERT(!index.hasLayer());
+
+ // ensure the underlying texture is created
+ ANGLE_TRY(ensureRenderTarget(context));
+ ANGLE_TRY(updateStorageLevel(context, index.getLevelIndex()));
+
+ return mTexStorage->getRenderTarget(context, index, samples, outRT);
+}
+
+bool TextureD3D_2D::isValidLevel(int level) const
+{
+ return (mTexStorage ? (level >= 0 && level < mTexStorage->getLevelCount()) : false);
+}
+
+bool TextureD3D_2D::isLevelComplete(int level) const
+{
+ if (isImmutable())
+ {
+ return true;
+ }
+
+ GLsizei width = getLevelZeroWidth();
+ GLsizei height = getLevelZeroHeight();
+
+ if (width <= 0 || height <= 0)
+ {
+ return false;
+ }
+
+ // The base image level is complete if the width and height are positive
+ if (level == static_cast<int>(getBaseLevel()))
+ {
+ return true;
+ }
+
+ ASSERT(level >= 0 && level <= static_cast<int>(mImageArray.size()) &&
+ mImageArray[level] != nullptr);
+ ImageD3D *image = mImageArray[level].get();
+
+ if (image->getInternalFormat() != getBaseLevelInternalFormat())
+ {
+ return false;
+ }
+
+ if (image->getWidth() != std::max(1, width >> level))
+ {
+ return false;
+ }
+
+ if (image->getHeight() != std::max(1, height >> level))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool TextureD3D_2D::isImageComplete(const gl::ImageIndex &index) const
+{
+ return isLevelComplete(index.getLevelIndex());
+}
+
+// Constructs a native texture resource from the texture images
+angle::Result TextureD3D_2D::initializeStorage(const gl::Context *context, BindFlags bindFlags)
+{
+ // Only initialize the first time this texture is used as a render target or shader resource
+ if (mTexStorage)
+ {
+ return angle::Result::Continue;
+ }
+
+ // do not attempt to create storage for nonexistant data
+ if (!isLevelComplete(getBaseLevel()))
+ {
+ return angle::Result::Continue;
+ }
+
+ bindFlags.renderTarget |= IsRenderTargetUsage(mState.getUsage());
+
+ TexStoragePointer storage;
+ ANGLE_TRY(createCompleteStorage(context, bindFlags, &storage));
+
+ ANGLE_TRY(setCompleteTexStorage(context, storage.get()));
+ storage.release();
+
+ ASSERT(mTexStorage);
+
+ // flush image data to the storage
+ ANGLE_TRY(updateStorage(context));
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2D::createCompleteStorage(const gl::Context *context,
+ BindFlags bindFlags,
+ TexStoragePointer *outStorage) const
+{
+ GLsizei width = getLevelZeroWidth();
+ GLsizei height = getLevelZeroHeight();
+ GLenum internalFormat = getBaseLevelInternalFormat();
+
+ ASSERT(width > 0 && height > 0);
+
+ // use existing storage level count, when previously specified by TexStorage*D
+ GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(width, height, 1));
+
+ bool hintLevelZeroOnly = false;
+ if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
+ {
+ // If any of the CPU images (levels >= 1) are dirty, then the textureStorage2D should use
+ // the mipped texture to begin with. Otherwise, it should use the level-zero-only texture.
+ hintLevelZeroOnly = true;
+ for (int level = 1; level < levels && hintLevelZeroOnly; level++)
+ {
+ hintLevelZeroOnly = !(mImageArray[level]->isDirty() && isLevelComplete(level));
+ }
+ }
+
+ // TODO(geofflang): Determine if the texture creation succeeded
+ *outStorage = {mRenderer->createTextureStorage2D(internalFormat, bindFlags, width, height,
+ levels, mState.getLabel(), hintLevelZeroOnly),
+ context};
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2D::setCompleteTexStorage(const gl::Context *context,
+ TextureStorage *newCompleteTexStorage)
+{
+ if (newCompleteTexStorage && newCompleteTexStorage->isManaged())
+ {
+ for (int level = 0; level < newCompleteTexStorage->getLevelCount(); level++)
+ {
+ ANGLE_TRY(
+ mImageArray[level]->setManagedSurface2D(context, newCompleteTexStorage, level));
+ }
+ }
+
+ gl::TexLevelMask copyImageMask;
+ copyImageMask.set();
+
+ ANGLE_TRY(releaseTexStorage(context, copyImageMask));
+ mTexStorage = newCompleteTexStorage;
+ mTexStorageObserverBinding.bind(mTexStorage);
+
+ mDirtyImages = true;
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2D::updateStorage(const gl::Context *context)
+{
+ if (!mDirtyImages)
+ {
+ return angle::Result::Continue;
+ }
+
+ ASSERT(mTexStorage != nullptr);
+ GLint storageLevels = mTexStorage->getLevelCount();
+ for (int level = 0; level < storageLevels; level++)
+ {
+ if (mImageArray[level]->isDirty() && isLevelComplete(level))
+ {
+ ANGLE_TRY(updateStorageLevel(context, level));
+ }
+ }
+
+ mDirtyImages = false;
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2D::updateStorageLevel(const gl::Context *context, int level)
+{
+ ASSERT(level <= static_cast<int>(mImageArray.size()) && mImageArray[level] != nullptr);
+ ASSERT(isLevelComplete(level));
+
+ if (mImageArray[level]->isDirty())
+ {
+ gl::ImageIndex index = gl::ImageIndex::Make2D(level);
+ gl::Box region(0, 0, 0, getWidth(level), getHeight(level), 1);
+ ANGLE_TRY(commitRegion(context, index, region));
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2D::redefineImage(const gl::Context *context,
+ size_t level,
+ GLenum internalformat,
+ const gl::Extents &size,
+ bool forceRelease)
+{
+ ASSERT(size.depth == 1);
+
+ // If there currently is a corresponding storage texture image, it has these parameters
+ const int storageWidth = std::max(1, getLevelZeroWidth() >> level);
+ const int storageHeight = std::max(1, getLevelZeroHeight() >> level);
+ const GLenum storageFormat = getBaseLevelInternalFormat();
+
+ if (mTexStorage)
+ {
+ const size_t storageLevels = mTexStorage->getLevelCount();
+
+ // If the storage was from an EGL image, copy it back into local images to preserve it
+ // while orphaning
+ if (level != 0 && mEGLImageTarget)
+ {
+ ANGLE_TRY(mImageArray[0]->copyFromTexStorage(context, gl::ImageIndex::Make2D(0),
+ mTexStorage));
+ }
+
+ if ((level >= storageLevels && storageLevels != 0) || size.width != storageWidth ||
+ size.height != storageHeight || internalformat != storageFormat ||
+ mEGLImageTarget) // Discard mismatched storage
+ {
+ gl::TexLevelMask copyImageMask;
+ copyImageMask.set();
+ copyImageMask.set(level, false);
+
+ ANGLE_TRY(releaseTexStorage(context, copyImageMask));
+ markAllImagesDirty();
+ }
+ }
+
+ mImageArray[level]->redefine(gl::TextureType::_2D, internalformat, size, forceRelease);
+ mDirtyImages = mDirtyImages || mImageArray[level]->isDirty();
+
+ // Can't be an EGL image target after being redefined
+ mEGLImageTarget = false;
+
+ return angle::Result::Continue;
+}
+
+gl::ImageIndexIterator TextureD3D_2D::imageIterator() const
+{
+ return gl::ImageIndexIterator::Make2D(0, mTexStorage->getLevelCount());
+}
+
+gl::ImageIndex TextureD3D_2D::getImageIndex(GLint mip, GLint /*layer*/) const
+{
+ // "layer" does not apply to 2D Textures.
+ return gl::ImageIndex::Make2D(mip);
+}
+
+bool TextureD3D_2D::isValidIndex(const gl::ImageIndex &index) const
+{
+ return (mTexStorage && index.getType() == gl::TextureType::_2D && index.getLevelIndex() >= 0 &&
+ index.getLevelIndex() < mTexStorage->getLevelCount());
+}
+
+void TextureD3D_2D::markAllImagesDirty()
+{
+ for (size_t i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+ {
+ mImageArray[i]->markDirty();
+ }
+ mDirtyImages = true;
+}
+
+TextureD3D_Cube::TextureD3D_Cube(const gl::TextureState &state, RendererD3D *renderer)
+ : TextureD3D(state, renderer)
+{
+ for (auto &face : mImageArray)
+ {
+ for (auto &image : face)
+ {
+ image.reset(renderer->createImage());
+ }
+ }
+}
+
+void TextureD3D_Cube::onDestroy(const gl::Context *context)
+{
+ // Delete the Images before the TextureStorage. Images might be relying on the TextureStorage
+ // for some of their data. If TextureStorage is deleted before the Images, then their data will
+ // be wastefully copied back from the GPU before we delete the Images.
+ for (auto &face : mImageArray)
+ {
+ for (auto &image : face)
+ {
+ image.reset();
+ }
+ }
+ return TextureD3D::onDestroy(context);
+}
+
+TextureD3D_Cube::~TextureD3D_Cube() {}
+
+ImageD3D *TextureD3D_Cube::getImage(int level, int layer) const
+{
+ ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+ ASSERT(layer >= 0 && static_cast<size_t>(layer) < gl::kCubeFaceCount);
+ return mImageArray[layer][level].get();
+}
+
+ImageD3D *TextureD3D_Cube::getImage(const gl::ImageIndex &index) const
+{
+ ASSERT(index.getLevelIndex() < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+ ASSERT(gl::IsCubeMapFaceTarget(index.getTarget()));
+ return mImageArray[index.cubeMapFaceIndex()][index.getLevelIndex()].get();
+}
+
+GLsizei TextureD3D_Cube::getLayerCount(int level) const
+{
+ ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+ return gl::kCubeFaceCount;
+}
+
+GLenum TextureD3D_Cube::getInternalFormat(GLint level, GLint layer) const
+{
+ if (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+ return mImageArray[layer][level]->getInternalFormat();
+ else
+ return GL_NONE;
+}
+
+bool TextureD3D_Cube::isDepth(GLint level, GLint layer) const
+{
+ return gl::GetSizedInternalFormatInfo(getInternalFormat(level, layer)).depthBits > 0;
+}
+
+bool TextureD3D_Cube::isSRGB(GLint level, GLint layer) const
+{
+ return gl::GetSizedInternalFormatInfo(getInternalFormat(level, layer)).colorEncoding == GL_SRGB;
+}
+
+angle::Result TextureD3D_Cube::setEGLImageTarget(const gl::Context *context,
+ gl::TextureType type,
+ egl::Image *image)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_Cube::setImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLenum internalFormat,
+ const gl::Extents &size,
+ GLenum format,
+ GLenum type,
+ const gl::PixelUnpackState &unpack,
+ gl::Buffer *unpackBuffer,
+ const uint8_t *pixels)
+{
+ ASSERT(size.depth == 1);
+
+ const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat, type);
+ ANGLE_TRY(redefineImage(context, index.cubeMapFaceIndex(), index.getLevelIndex(),
+ internalFormatInfo.sizedInternalFormat, size, false));
+
+ return setImageImpl(context, index, type, unpack, unpackBuffer, pixels, 0);
+}
+
+angle::Result TextureD3D_Cube::setSubImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Box &area,
+ GLenum format,
+ GLenum type,
+ const gl::PixelUnpackState &unpack,
+ gl::Buffer *unpackBuffer,
+ const uint8_t *pixels)
+{
+ ASSERT(area.depth == 1 && area.z == 0);
+ return TextureD3D::subImage(context, index, area, format, type, unpack, unpackBuffer, pixels,
+ 0);
+}
+
+angle::Result TextureD3D_Cube::setCompressedImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLenum internalFormat,
+ const gl::Extents &size,
+ const gl::PixelUnpackState &unpack,
+ size_t imageSize,
+ const uint8_t *pixels)
+{
+ ASSERT(size.depth == 1);
+
+ // compressed formats don't have separate sized internal formats-- we can just use the
+ // compressed format directly
+ ANGLE_TRY(redefineImage(context, index.cubeMapFaceIndex(), index.getLevelIndex(),
+ internalFormat, size, false));
+
+ return setCompressedImageImpl(context, index, unpack, pixels, 0);
+}
+
+angle::Result TextureD3D_Cube::setCompressedSubImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Box &area,
+ GLenum format,
+ const gl::PixelUnpackState &unpack,
+ size_t imageSize,
+ const uint8_t *pixels)
+{
+ ASSERT(area.depth == 1 && area.z == 0);
+
+ ANGLE_TRY(TextureD3D::subImageCompressed(context, index, area, format, unpack, pixels, 0));
+ return commitRegion(context, index, area);
+}
+
+angle::Result TextureD3D_Cube::copyImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Rectangle &sourceArea,
+ GLenum internalFormat,
+ gl::Framebuffer *source)
+{
+ GLint faceIndex = index.cubeMapFaceIndex();
+ const gl::InternalFormat &internalFormatInfo =
+ gl::GetInternalFormatInfo(internalFormat, GL_UNSIGNED_BYTE);
+
+ gl::Extents size(sourceArea.width, sourceArea.height, 1);
+ ANGLE_TRY(redefineImage(context, faceIndex, index.getLevelIndex(),
+ internalFormatInfo.sizedInternalFormat, size, false));
+
+ gl::Extents fbSize = source->getReadColorAttachment()->getSize();
+
+ // Does the read area extend beyond the framebuffer?
+ bool outside = sourceArea.x < 0 || sourceArea.y < 0 ||
+ sourceArea.x + sourceArea.width > fbSize.width ||
+ sourceArea.y + sourceArea.height > fbSize.height;
+
+ // WebGL requires that pixels that would be outside the framebuffer are treated as zero values,
+ // so clear the mip level to 0 prior to making the copy if any pixel would be sampled outside.
+ // Same thing for robust resource init.
+ if (outside && (context->isWebGL() || context->isRobustResourceInitEnabled()))
+ {
+ ANGLE_TRY(initializeContents(context, GL_NONE, index));
+ }
+
+ gl::Rectangle clippedArea;
+ if (!ClipRectangle(sourceArea, gl::Rectangle(0, 0, fbSize.width, fbSize.height), &clippedArea))
+ {
+ // Empty source area, nothing to do.
+ return angle::Result::Continue;
+ }
+
+ gl::Offset destOffset(clippedArea.x - sourceArea.x, clippedArea.y - sourceArea.y, 0);
+
+ // If the zero max LOD workaround is active, then we can't sample from individual layers of the
+ // framebuffer in shaders, so we should use the non-rendering copy path.
+ if (!canCreateRenderTargetForImage(index) ||
+ mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
+ {
+ ANGLE_TRY(mImageArray[faceIndex][index.getLevelIndex()]->copyFromFramebuffer(
+ context, destOffset, clippedArea, source));
+ mDirtyImages = true;
+ onStateChange(angle::SubjectMessage::DirtyBitsFlagged);
+ }
+ else
+ {
+ ANGLE_TRY(ensureRenderTarget(context));
+
+ ASSERT(size.width == size.height);
+
+ if (size.width > 0 && isValidFaceLevel(faceIndex, index.getLevelIndex()))
+ {
+ ANGLE_TRY(updateStorageFaceLevel(context, faceIndex, index.getLevelIndex()));
+ ANGLE_TRY(mRenderer->copyImageCube(context, source, clippedArea, internalFormat,
+ destOffset, mTexStorage, index.getTarget(),
+ index.getLevelIndex()));
+ }
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_Cube::copySubImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Offset &destOffset,
+ const gl::Rectangle &sourceArea,
+ gl::Framebuffer *source)
+{
+ gl::Extents fbSize = source->getReadColorAttachment()->getSize();
+ gl::Rectangle clippedArea;
+ if (!ClipRectangle(sourceArea, gl::Rectangle(0, 0, fbSize.width, fbSize.height), &clippedArea))
+ {
+ return angle::Result::Continue;
+ }
+ const gl::Offset clippedOffset(destOffset.x + clippedArea.x - sourceArea.x,
+ destOffset.y + clippedArea.y - sourceArea.y, 0);
+
+ GLint faceIndex = index.cubeMapFaceIndex();
+
+ // If the zero max LOD workaround is active, then we can't sample from individual layers of the
+ // framebuffer in shaders, so we should use the non-rendering copy path.
+ if (!canCreateRenderTargetForImage(index) ||
+ mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
+ {
+ ANGLE_TRY(mImageArray[faceIndex][index.getLevelIndex()]->copyFromFramebuffer(
+ context, clippedOffset, clippedArea, source));
+ mDirtyImages = true;
+ onStateChange(angle::SubjectMessage::DirtyBitsFlagged);
+ }
+ else
+ {
+ ANGLE_TRY(ensureRenderTarget(context));
+ if (isValidFaceLevel(faceIndex, index.getLevelIndex()))
+ {
+ ANGLE_TRY(updateStorageFaceLevel(context, faceIndex, index.getLevelIndex()));
+ ANGLE_TRY(mRenderer->copyImageCube(
+ context, source, clippedArea, gl::GetUnsizedFormat(getBaseLevelInternalFormat()),
+ clippedOffset, mTexStorage, index.getTarget(), index.getLevelIndex()));
+ }
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_Cube::copyTexture(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLenum internalFormat,
+ GLenum type,
+ GLint sourceLevel,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha,
+ const gl::Texture *source)
+{
+ ASSERT(gl::IsCubeMapFaceTarget(index.getTarget()));
+
+ gl::TextureTarget sourceTarget = NonCubeTextureTypeToTarget(source->getType());
+
+ GLint faceIndex = index.cubeMapFaceIndex();
+
+ const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat, type);
+ gl::Extents size(static_cast<int>(source->getWidth(sourceTarget, sourceLevel)),
+ static_cast<int>(source->getHeight(sourceTarget, sourceLevel)), 1);
+ ANGLE_TRY(redefineImage(context, faceIndex, index.getLevelIndex(),
+ internalFormatInfo.sizedInternalFormat, size, false));
+
+ gl::Box sourceBox(0, 0, 0, size.width, size.height, 1);
+ gl::Offset destOffset(0, 0, 0);
+
+ if (!isSRGB(index.getLevelIndex(), faceIndex) && canCreateRenderTargetForImage(index))
+ {
+
+ ANGLE_TRY(ensureRenderTarget(context));
+ ASSERT(isValidFaceLevel(faceIndex, index.getLevelIndex()));
+ ANGLE_TRY(updateStorageFaceLevel(context, faceIndex, index.getLevelIndex()));
+
+ ANGLE_TRY(mRenderer->copyTexture(context, source, sourceLevel, gl::TextureTarget::_2D,
+ sourceBox, internalFormatInfo.format,
+ internalFormatInfo.type, destOffset, mTexStorage,
+ index.getTarget(), index.getLevelIndex(), unpackFlipY,
+ unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
+ }
+ else
+ {
+ gl::ImageIndex sourceImageIndex = gl::ImageIndex::Make2D(sourceLevel);
+ TextureD3D *sourceD3D = GetImplAs<TextureD3D>(source);
+ ImageD3D *sourceImage = nullptr;
+ ANGLE_TRY(sourceD3D->getImageAndSyncFromStorage(context, sourceImageIndex, &sourceImage));
+
+ ImageD3D *destImage = nullptr;
+ ANGLE_TRY(getImageAndSyncFromStorage(context, index, &destImage));
+
+ ANGLE_TRY(mRenderer->copyImage(context, destImage, sourceImage, sourceBox, destOffset,
+ unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
+
+ mDirtyImages = true;
+
+ gl::Box destRegion(destOffset, size);
+ ANGLE_TRY(commitRegion(context, index, destRegion));
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_Cube::copySubTexture(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Offset &destOffset,
+ GLint sourceLevel,
+ const gl::Box &sourceBox,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha,
+ const gl::Texture *source)
+{
+ ASSERT(gl::IsCubeMapFaceTarget(index.getTarget()));
+
+ GLint faceIndex = index.cubeMapFaceIndex();
+
+ if (!isSRGB(index.getLevelIndex(), faceIndex) && canCreateRenderTargetForImage(index))
+ {
+ ANGLE_TRY(ensureRenderTarget(context));
+ ASSERT(isValidFaceLevel(faceIndex, index.getLevelIndex()));
+ ANGLE_TRY(updateStorageFaceLevel(context, faceIndex, index.getLevelIndex()));
+
+ const gl::InternalFormat &internalFormatInfo =
+ gl::GetSizedInternalFormatInfo(getInternalFormat(index.getLevelIndex(), faceIndex));
+ ANGLE_TRY(mRenderer->copyTexture(context, source, sourceLevel, gl::TextureTarget::_2D,
+ sourceBox, internalFormatInfo.format,
+ internalFormatInfo.type, destOffset, mTexStorage,
+ index.getTarget(), index.getLevelIndex(), unpackFlipY,
+ unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
+ }
+ else
+ {
+ gl::ImageIndex sourceImageIndex = gl::ImageIndex::Make2D(sourceLevel);
+ TextureD3D *sourceD3D = GetImplAs<TextureD3D>(source);
+ ImageD3D *sourceImage = nullptr;
+ ANGLE_TRY(sourceD3D->getImageAndSyncFromStorage(context, sourceImageIndex, &sourceImage));
+
+ ImageD3D *destImage = nullptr;
+ ANGLE_TRY(getImageAndSyncFromStorage(context, index, &destImage));
+
+ ANGLE_TRY(mRenderer->copyImage(context, destImage, sourceImage, sourceBox, destOffset,
+ unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
+
+ mDirtyImages = true;
+
+ gl::Box destRegion(destOffset.x, destOffset.y, 0, sourceBox.width, sourceBox.height, 1);
+ ANGLE_TRY(commitRegion(context, index, destRegion));
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_Cube::setStorage(const gl::Context *context,
+ gl::TextureType type,
+ size_t levels,
+ GLenum internalFormat,
+ const gl::Extents &size)
+{
+ ASSERT(size.width == size.height);
+ ASSERT(size.depth == 1);
+
+ for (size_t level = 0; level < levels; level++)
+ {
+ GLsizei mipSize = std::max(1, size.width >> level);
+ for (size_t faceIndex = 0; faceIndex < gl::kCubeFaceCount; faceIndex++)
+ {
+ mImageArray[faceIndex][level]->redefine(gl::TextureType::CubeMap, internalFormat,
+ gl::Extents(mipSize, mipSize, 1), true);
+ }
+ }
+
+ for (size_t level = levels; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
+ {
+ for (size_t faceIndex = 0; faceIndex < gl::kCubeFaceCount; faceIndex++)
+ {
+ mImageArray[faceIndex][level]->redefine(gl::TextureType::CubeMap, GL_NONE,
+ gl::Extents(0, 0, 0), true);
+ }
+ }
+
+ // TODO(geofflang): Verify storage creation had no errors
+ BindFlags bindFlags;
+ bindFlags.renderTarget = IsRenderTargetUsage(mState.getUsage());
+
+ TexStoragePointer storage = {
+ mRenderer->createTextureStorageCube(internalFormat, bindFlags, size.width,
+ static_cast<int>(levels), false, mState.getLabel()),
+ context};
+
+ ANGLE_TRY(setCompleteTexStorage(context, storage.get()));
+ storage.release();
+
+ ANGLE_TRY(updateStorage(context));
+
+ mImmutable = true;
+
+ return angle::Result::Continue;
+}
+
+// Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
+bool TextureD3D_Cube::isCubeComplete() const
+{
+ int baseWidth = getBaseLevelWidth();
+ int baseHeight = getBaseLevelHeight();
+ GLenum baseFormat = getBaseLevelInternalFormat();
+
+ if (baseWidth <= 0 || baseWidth != baseHeight)
+ {
+ return false;
+ }
+
+ for (size_t faceIndex = 1; faceIndex < gl::kCubeFaceCount; faceIndex++)
+ {
+ const ImageD3D &faceBaseImage = *mImageArray[faceIndex][getBaseLevel()];
+
+ if (faceBaseImage.getWidth() != baseWidth || faceBaseImage.getHeight() != baseHeight ||
+ faceBaseImage.getInternalFormat() != baseFormat)
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+angle::Result TextureD3D_Cube::bindTexImage(const gl::Context *context, egl::Surface *surface)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_Cube::releaseTexImage(const gl::Context *context)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_Cube::initMipmapImages(const gl::Context *context)
+{
+ const GLuint baseLevel = mState.getEffectiveBaseLevel();
+ const GLuint maxLevel = mState.getMipmapMaxLevel();
+ // Purge array levels baseLevel + 1 through q and reset them to represent the generated mipmap
+ // levels.
+ for (int faceIndex = 0; faceIndex < static_cast<int>(gl::kCubeFaceCount); faceIndex++)
+ {
+ for (GLuint level = baseLevel + 1; level <= maxLevel; level++)
+ {
+ int faceLevelSize =
+ (std::max(mImageArray[faceIndex][baseLevel]->getWidth() >> (level - baseLevel), 1));
+ ANGLE_TRY(redefineImage(context, faceIndex, level,
+ mImageArray[faceIndex][baseLevel]->getInternalFormat(),
+ gl::Extents(faceLevelSize, faceLevelSize, 1), false));
+ }
+ }
+
+ // We should be mip-complete now so generate the storage.
+ ANGLE_TRY(initializeStorage(context, BindFlags::RenderTarget()));
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_Cube::getRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT)
+{
+ ASSERT(gl::IsCubeMapFaceTarget(index.getTarget()));
+
+ // ensure the underlying texture is created
+ ANGLE_TRY(ensureRenderTarget(context));
+ ANGLE_TRY(updateStorageFaceLevel(context, index.cubeMapFaceIndex(), index.getLevelIndex()));
+
+ return mTexStorage->getRenderTarget(context, index, samples, outRT);
+}
+
+angle::Result TextureD3D_Cube::initializeStorage(const gl::Context *context, BindFlags bindFlags)
+{
+ // Only initialize the first time this texture is used as a render target or shader resource
+ if (mTexStorage)
+ {
+ return angle::Result::Continue;
+ }
+
+ // do not attempt to create storage for nonexistant data
+ if (!isFaceLevelComplete(0, getBaseLevel()))
+ {
+ return angle::Result::Continue;
+ }
+
+ bindFlags.renderTarget |= IsRenderTargetUsage(mState.getUsage());
+
+ TexStoragePointer storage;
+ ANGLE_TRY(createCompleteStorage(context, bindFlags, &storage));
+
+ ANGLE_TRY(setCompleteTexStorage(context, storage.get()));
+ storage.release();
+
+ ASSERT(mTexStorage);
+
+ // flush image data to the storage
+ ANGLE_TRY(updateStorage(context));
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_Cube::createCompleteStorage(const gl::Context *context,
+ BindFlags bindFlags,
+ TexStoragePointer *outStorage) const
+{
+ GLsizei size = getLevelZeroWidth();
+
+ ASSERT(size > 0);
+
+ // use existing storage level count, when previously specified by TexStorage*D
+ GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(size, size, 1));
+
+ bool hintLevelZeroOnly = false;
+ if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
+ {
+ // If any of the CPU images (levels >= 1) are dirty, then the textureStorageEXT should use
+ // the mipped texture to begin with. Otherwise, it should use the level-zero-only texture.
+ hintLevelZeroOnly = true;
+ for (int faceIndex = 0;
+ faceIndex < static_cast<int>(gl::kCubeFaceCount) && hintLevelZeroOnly; faceIndex++)
+ {
+ for (int level = 1; level < levels && hintLevelZeroOnly; level++)
+ {
+ hintLevelZeroOnly = !(mImageArray[faceIndex][level]->isDirty() &&
+ isFaceLevelComplete(faceIndex, level));
+ }
+ }
+ }
+
+ // TODO (geofflang): detect if storage creation succeeded
+ *outStorage = {
+ mRenderer->createTextureStorageCube(getBaseLevelInternalFormat(), bindFlags, size, levels,
+ hintLevelZeroOnly, mState.getLabel()),
+ context};
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_Cube::setCompleteTexStorage(const gl::Context *context,
+ TextureStorage *newCompleteTexStorage)
+{
+ if (newCompleteTexStorage && newCompleteTexStorage->isManaged())
+ {
+ for (int faceIndex = 0; faceIndex < static_cast<int>(gl::kCubeFaceCount); faceIndex++)
+ {
+ for (int level = 0; level < newCompleteTexStorage->getLevelCount(); level++)
+ {
+ ANGLE_TRY(mImageArray[faceIndex][level]->setManagedSurfaceCube(
+ context, newCompleteTexStorage, faceIndex, level));
+ }
+ }
+ }
+
+ gl::TexLevelMask copyImageMask;
+ copyImageMask.set();
+
+ ANGLE_TRY(releaseTexStorage(context, copyImageMask));
+ mTexStorage = newCompleteTexStorage;
+ mTexStorageObserverBinding.bind(mTexStorage);
+
+ mDirtyImages = true;
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_Cube::updateStorage(const gl::Context *context)
+{
+ if (!mDirtyImages)
+ {
+ return angle::Result::Continue;
+ }
+
+ ASSERT(mTexStorage != nullptr);
+ GLint storageLevels = mTexStorage->getLevelCount();
+ for (int face = 0; face < static_cast<int>(gl::kCubeFaceCount); face++)
+ {
+ for (int level = 0; level < storageLevels; level++)
+ {
+ if (mImageArray[face][level]->isDirty() && isFaceLevelComplete(face, level))
+ {
+ ANGLE_TRY(updateStorageFaceLevel(context, face, level));
+ }
+ }
+ }
+
+ mDirtyImages = false;
+ return angle::Result::Continue;
+}
+
+bool TextureD3D_Cube::isValidFaceLevel(int faceIndex, int level) const
+{
+ return (mTexStorage ? (level >= 0 && level < mTexStorage->getLevelCount()) : 0);
+}
+
+bool TextureD3D_Cube::isFaceLevelComplete(int faceIndex, int level) const
+{
+ if (getBaseLevel() >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+ {
+ return false;
+ }
+ ASSERT(level >= 0 && static_cast<size_t>(faceIndex) < gl::kCubeFaceCount &&
+ level < static_cast<int>(mImageArray[faceIndex].size()) &&
+ mImageArray[faceIndex][level] != nullptr);
+
+ if (isImmutable())
+ {
+ return true;
+ }
+
+ int levelZeroSize = getLevelZeroWidth();
+
+ if (levelZeroSize <= 0)
+ {
+ return false;
+ }
+
+ // Check that non-zero levels are consistent with the base level.
+ const ImageD3D *faceLevelImage = mImageArray[faceIndex][level].get();
+
+ if (faceLevelImage->getInternalFormat() != getBaseLevelInternalFormat())
+ {
+ return false;
+ }
+
+ if (faceLevelImage->getWidth() != std::max(1, levelZeroSize >> level))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool TextureD3D_Cube::isImageComplete(const gl::ImageIndex &index) const
+{
+ return isFaceLevelComplete(index.cubeMapFaceIndex(), index.getLevelIndex());
+}
+
+angle::Result TextureD3D_Cube::updateStorageFaceLevel(const gl::Context *context,
+ int faceIndex,
+ int level)
+{
+ ASSERT(level >= 0 && static_cast<size_t>(faceIndex) < gl::kCubeFaceCount &&
+ level < static_cast<int>(mImageArray[faceIndex].size()) &&
+ mImageArray[faceIndex][level] != nullptr);
+ ImageD3D *image = mImageArray[faceIndex][level].get();
+
+ if (image->isDirty())
+ {
+ gl::TextureTarget faceTarget = gl::CubeFaceIndexToTextureTarget(faceIndex);
+ gl::ImageIndex index = gl::ImageIndex::MakeCubeMapFace(faceTarget, level);
+ gl::Box region(0, 0, 0, image->getWidth(), image->getHeight(), 1);
+ ANGLE_TRY(commitRegion(context, index, region));
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_Cube::redefineImage(const gl::Context *context,
+ int faceIndex,
+ GLint level,
+ GLenum internalformat,
+ const gl::Extents &size,
+ bool forceRelease)
+{
+ // If there currently is a corresponding storage texture image, it has these parameters
+ const int storageWidth = std::max(1, getLevelZeroWidth() >> level);
+ const int storageHeight = std::max(1, getLevelZeroHeight() >> level);
+ const GLenum storageFormat = getBaseLevelInternalFormat();
+
+ if (mTexStorage)
+ {
+ const int storageLevels = mTexStorage->getLevelCount();
+
+ if ((level >= storageLevels && storageLevels != 0) || size.width != storageWidth ||
+ size.height != storageHeight ||
+ internalformat != storageFormat) // Discard mismatched storage
+ {
+ markAllImagesDirty();
+
+ gl::TexLevelMask copyImageMask;
+ copyImageMask.set();
+ copyImageMask.set(level, false);
+
+ ANGLE_TRY(releaseTexStorage(context, copyImageMask));
+ }
+ }
+
+ mImageArray[faceIndex][level]->redefine(gl::TextureType::CubeMap, internalformat, size,
+ forceRelease);
+ mDirtyImages = mDirtyImages || mImageArray[faceIndex][level]->isDirty();
+
+ return angle::Result::Continue;
+}
+
+gl::ImageIndexIterator TextureD3D_Cube::imageIterator() const
+{
+ return gl::ImageIndexIterator::MakeCube(0, mTexStorage->getLevelCount());
+}
+
+gl::ImageIndex TextureD3D_Cube::getImageIndex(GLint mip, GLint layer) const
+{
+ // The "layer" of the image index corresponds to the cube face
+ return gl::ImageIndex::MakeCubeMapFace(gl::CubeFaceIndexToTextureTarget(layer), mip);
+}
+
+bool TextureD3D_Cube::isValidIndex(const gl::ImageIndex &index) const
+{
+ return (mTexStorage && index.getType() == gl::TextureType::CubeMap &&
+ gl::IsCubeMapFaceTarget(index.getTarget()) && index.getLevelIndex() >= 0 &&
+ index.getLevelIndex() < mTexStorage->getLevelCount());
+}
+
+void TextureD3D_Cube::markAllImagesDirty()
+{
+ for (int dirtyLevel = 0; dirtyLevel < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; dirtyLevel++)
+ {
+ for (size_t dirtyFace = 0; dirtyFace < gl::kCubeFaceCount; dirtyFace++)
+ {
+ mImageArray[dirtyFace][dirtyLevel]->markDirty();
+ }
+ }
+ mDirtyImages = true;
+}
+
+TextureD3D_3D::TextureD3D_3D(const gl::TextureState &state, RendererD3D *renderer)
+ : TextureD3D(state, renderer)
+{
+ for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i)
+ {
+ mImageArray[i].reset(renderer->createImage());
+ }
+}
+
+void TextureD3D_3D::onDestroy(const gl::Context *context)
+{
+ // Delete the Images before the TextureStorage. Images might be relying on the TextureStorage
+ // for some of their data. If TextureStorage is deleted before the Images, then their data will
+ // be wastefully copied back from the GPU before we delete the Images.
+ for (auto &image : mImageArray)
+ {
+ image.reset();
+ }
+ return TextureD3D::onDestroy(context);
+}
+
+TextureD3D_3D::~TextureD3D_3D() {}
+
+ImageD3D *TextureD3D_3D::getImage(int level, int layer) const
+{
+ ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+ ASSERT(layer == 0);
+ return mImageArray[level].get();
+}
+
+ImageD3D *TextureD3D_3D::getImage(const gl::ImageIndex &index) const
+{
+ ASSERT(index.getLevelIndex() < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+ ASSERT(!index.hasLayer());
+ ASSERT(index.getType() == gl::TextureType::_3D);
+ return mImageArray[index.getLevelIndex()].get();
+}
+
+GLsizei TextureD3D_3D::getLayerCount(int level) const
+{
+ ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+ return 1;
+}
+
+GLsizei TextureD3D_3D::getWidth(GLint level) const
+{
+ if (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+ return mImageArray[level]->getWidth();
+ else
+ return 0;
+}
+
+GLsizei TextureD3D_3D::getHeight(GLint level) const
+{
+ if (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+ return mImageArray[level]->getHeight();
+ else
+ return 0;
+}
+
+GLsizei TextureD3D_3D::getDepth(GLint level) const
+{
+ if (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+ return mImageArray[level]->getDepth();
+ else
+ return 0;
+}
+
+GLenum TextureD3D_3D::getInternalFormat(GLint level) const
+{
+ if (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+ return mImageArray[level]->getInternalFormat();
+ else
+ return GL_NONE;
+}
+
+bool TextureD3D_3D::isDepth(GLint level) const
+{
+ return gl::GetSizedInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
+}
+
+bool TextureD3D_3D::isSRGB(GLint level) const
+{
+ return gl::GetSizedInternalFormatInfo(getInternalFormat(level)).colorEncoding == GL_SRGB;
+}
+
+angle::Result TextureD3D_3D::setEGLImageTarget(const gl::Context *context,
+ gl::TextureType type,
+ egl::Image *image)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_3D::setImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLenum internalFormat,
+ const gl::Extents &size,
+ GLenum format,
+ GLenum type,
+ const gl::PixelUnpackState &unpack,
+ gl::Buffer *unpackBuffer,
+ const uint8_t *pixels)
+{
+ ASSERT(index.getTarget() == gl::TextureTarget::_3D);
+ const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat, type);
+
+ ANGLE_TRY(redefineImage(context, index.getLevelIndex(), internalFormatInfo.sizedInternalFormat,
+ size, false));
+
+ bool fastUnpacked = false;
+
+ // Attempt a fast gpu copy of the pixel data to the surface if the app bound an unpack buffer
+ if (isFastUnpackable(unpackBuffer, unpack, internalFormatInfo.sizedInternalFormat) &&
+ !size.empty() && isLevelComplete(index.getLevelIndex()))
+ {
+ // Will try to create RT storage if it does not exist
+ RenderTargetD3D *destRenderTarget = nullptr;
+ ANGLE_TRY(getRenderTarget(context, index, getRenderToTextureSamples(), &destRenderTarget));
+
+ gl::Box destArea(0, 0, 0, getWidth(index.getLevelIndex()), getHeight(index.getLevelIndex()),
+ getDepth(index.getLevelIndex()));
+
+ ANGLE_TRY(fastUnpackPixels(context, unpack, unpackBuffer, pixels, destArea,
+ internalFormatInfo.sizedInternalFormat, type, destRenderTarget));
+
+ // Ensure we don't overwrite our newly initialized data
+ mImageArray[index.getLevelIndex()]->markClean();
+
+ fastUnpacked = true;
+ }
+
+ if (!fastUnpacked)
+ {
+ ANGLE_TRY(setImageImpl(context, index, type, unpack, unpackBuffer, pixels, 0));
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_3D::setSubImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Box &area,
+ GLenum format,
+ GLenum type,
+ const gl::PixelUnpackState &unpack,
+ gl::Buffer *unpackBuffer,
+ const uint8_t *pixels)
+{
+ ASSERT(index.getTarget() == gl::TextureTarget::_3D);
+
+ // Attempt a fast gpu copy of the pixel data to the surface if the app bound an unpack buffer
+ GLenum mipFormat = getInternalFormat(index.getLevelIndex());
+ if (isFastUnpackable(unpackBuffer, unpack, mipFormat) && isLevelComplete(index.getLevelIndex()))
+ {
+ RenderTargetD3D *destRenderTarget = nullptr;
+ ANGLE_TRY(getRenderTarget(context, index, getRenderToTextureSamples(), &destRenderTarget));
+ ASSERT(!mImageArray[index.getLevelIndex()]->isDirty());
+
+ return fastUnpackPixels(context, unpack, unpackBuffer, pixels, area, mipFormat, type,
+ destRenderTarget);
+ }
+ else
+ {
+ return TextureD3D::subImage(context, index, area, format, type, unpack, unpackBuffer,
+ pixels, 0);
+ }
+}
+
+angle::Result TextureD3D_3D::setCompressedImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLenum internalFormat,
+ const gl::Extents &size,
+ const gl::PixelUnpackState &unpack,
+ size_t imageSize,
+ const uint8_t *pixels)
+{
+ ASSERT(index.getTarget() == gl::TextureTarget::_3D);
+
+ // compressed formats don't have separate sized internal formats-- we can just use the
+ // compressed format directly
+ ANGLE_TRY(redefineImage(context, index.getLevelIndex(), internalFormat, size, false));
+
+ return setCompressedImageImpl(context, index, unpack, pixels, 0);
+}
+
+angle::Result TextureD3D_3D::setCompressedSubImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Box &area,
+ GLenum format,
+ const gl::PixelUnpackState &unpack,
+ size_t imageSize,
+ const uint8_t *pixels)
+{
+ ASSERT(index.getTarget() == gl::TextureTarget::_3D);
+
+ ANGLE_TRY(TextureD3D::subImageCompressed(context, index, area, format, unpack, pixels, 0));
+ return commitRegion(context, index, area);
+}
+
+angle::Result TextureD3D_3D::copyImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Rectangle &sourceArea,
+ GLenum internalFormat,
+ gl::Framebuffer *source)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_3D::copySubImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Offset &destOffset,
+ const gl::Rectangle &sourceArea,
+ gl::Framebuffer *source)
+{
+ ASSERT(index.getTarget() == gl::TextureTarget::_3D);
+
+ gl::Extents fbSize = source->getReadColorAttachment()->getSize();
+ gl::Rectangle clippedSourceArea;
+ if (!ClipRectangle(sourceArea, gl::Rectangle(0, 0, fbSize.width, fbSize.height),
+ &clippedSourceArea))
+ {
+ return angle::Result::Continue;
+ }
+ const gl::Offset clippedDestOffset(destOffset.x + clippedSourceArea.x - sourceArea.x,
+ destOffset.y + clippedSourceArea.y - sourceArea.y,
+ destOffset.z);
+
+ // Currently, copying directly to the storage is not possible because it's not possible to
+ // create an SRV from a single layer of a 3D texture. Instead, make sure the image is up to
+ // date before the copy and then copy back to the storage afterwards if needed.
+ // TODO: Investigate 3D blits in D3D11.
+
+ bool syncTexStorage = mTexStorage && isLevelComplete(index.getLevelIndex());
+ if (syncTexStorage)
+ {
+ ANGLE_TRY(
+ mImageArray[index.getLevelIndex()]->copyFromTexStorage(context, index, mTexStorage));
+ }
+ ANGLE_TRY(mImageArray[index.getLevelIndex()]->copyFromFramebuffer(context, clippedDestOffset,
+ clippedSourceArea, source));
+ mDirtyImages = true;
+ onStateChange(angle::SubjectMessage::DirtyBitsFlagged);
+
+ if (syncTexStorage)
+ {
+ ANGLE_TRY(updateStorageLevel(context, index.getLevelIndex()));
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_3D::copyTexture(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLenum internalFormat,
+ GLenum type,
+ GLint sourceLevel,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha,
+ const gl::Texture *source)
+{
+ ASSERT(index.getTarget() == gl::TextureTarget::_3D);
+
+ gl::TextureType sourceType = source->getType();
+
+ const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat, type);
+ gl::Extents size(
+ static_cast<int>(source->getWidth(NonCubeTextureTypeToTarget(sourceType), sourceLevel)),
+ static_cast<int>(source->getHeight(NonCubeTextureTypeToTarget(sourceType), sourceLevel)),
+ static_cast<int>(source->getDepth(NonCubeTextureTypeToTarget(sourceType), sourceLevel)));
+
+ ANGLE_TRY(redefineImage(context, index.getLevelIndex(), internalFormatInfo.sizedInternalFormat,
+ size, false));
+
+ gl::Box sourceBox(0, 0, 0, size.width, size.height, size.depth);
+ gl::Offset destOffset(0, 0, 0);
+ gl::ImageIndex destIndex = gl::ImageIndex::Make3D(static_cast<GLint>(index.getLevelIndex()));
+
+ if (!isSRGB(index.getLevelIndex()) && canCreateRenderTargetForImage(destIndex))
+ {
+ ANGLE_TRY(ensureRenderTarget(context));
+ ASSERT(isValidLevel(index.getLevelIndex()));
+ ANGLE_TRY(updateStorageLevel(context, index.getLevelIndex()));
+
+ ANGLE_TRY(mRenderer->copyTexture(context, source, sourceLevel, gl::TextureTarget::_3D,
+ sourceBox, internalFormatInfo.format,
+ internalFormatInfo.type, destOffset, mTexStorage,
+ index.getTarget(), index.getLevelIndex(), unpackFlipY,
+ unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
+ }
+ else
+ {
+ gl::ImageIndex sourceIndex = gl::ImageIndex::Make3D(sourceLevel);
+ ImageD3D *sourceImage = nullptr;
+ ImageD3D *destImage = nullptr;
+ TextureD3D *sourceD3D = GetImplAs<TextureD3D>(source);
+
+ ANGLE_TRY(getImageAndSyncFromStorage(context, destIndex, &destImage));
+ ANGLE_TRY(sourceD3D->getImageAndSyncFromStorage(context, sourceIndex, &sourceImage));
+
+ ANGLE_TRY(mRenderer->copyImage(context, destImage, sourceImage, sourceBox, destOffset,
+ unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
+
+ mDirtyImages = true;
+
+ gl::Box destRegion(0, 0, 0, sourceBox.width, sourceBox.height, sourceBox.depth);
+ ANGLE_TRY(commitRegion(context, destIndex, destRegion));
+ }
+
+ return angle::Result::Continue;
+}
+angle::Result TextureD3D_3D::copySubTexture(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Offset &destOffset,
+ GLint sourceLevel,
+ const gl::Box &sourceBox,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha,
+ const gl::Texture *source)
+{
+ ASSERT(index.getTarget() == gl::TextureTarget::_3D);
+
+ gl::ImageIndex destIndex = gl::ImageIndex::Make3D(static_cast<GLint>(index.getLevelIndex()));
+
+ if (!isSRGB(index.getLevelIndex()) && canCreateRenderTargetForImage(destIndex))
+ {
+ ANGLE_TRY(ensureRenderTarget(context));
+ ASSERT(isValidLevel(index.getLevelIndex()));
+ ANGLE_TRY(updateStorageLevel(context, index.getLevelIndex()));
+
+ const gl::InternalFormat &internalFormatInfo =
+ gl::GetSizedInternalFormatInfo(getInternalFormat(index.getLevelIndex()));
+ ANGLE_TRY(mRenderer->copyTexture(context, source, sourceLevel, gl::TextureTarget::_3D,
+ sourceBox, internalFormatInfo.format,
+ internalFormatInfo.type, destOffset, mTexStorage,
+ index.getTarget(), index.getLevelIndex(), unpackFlipY,
+ unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
+ }
+ else
+ {
+ gl::ImageIndex sourceImageIndex = gl::ImageIndex::Make3D(sourceLevel);
+ TextureD3D *sourceD3D = GetImplAs<TextureD3D>(source);
+ ImageD3D *sourceImage = nullptr;
+ ANGLE_TRY(sourceD3D->getImageAndSyncFromStorage(context, sourceImageIndex, &sourceImage));
+
+ ImageD3D *destImage = nullptr;
+ ANGLE_TRY(getImageAndSyncFromStorage(context, destIndex, &destImage));
+
+ ANGLE_TRY(mRenderer->copyImage(context, destImage, sourceImage, sourceBox, destOffset,
+ unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
+
+ mDirtyImages = true;
+
+ gl::Box destRegion(destOffset.x, destOffset.y, destOffset.z, sourceBox.width,
+ sourceBox.height, sourceBox.depth);
+ ANGLE_TRY(commitRegion(context, destIndex, destRegion));
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_3D::setStorage(const gl::Context *context,
+ gl::TextureType type,
+ size_t levels,
+ GLenum internalFormat,
+ const gl::Extents &size)
+{
+ ASSERT(type == gl::TextureType::_3D);
+
+ for (size_t level = 0; level < levels; level++)
+ {
+ gl::Extents levelSize(std::max(1, size.width >> level), std::max(1, size.height >> level),
+ std::max(1, size.depth >> level));
+ mImageArray[level]->redefine(gl::TextureType::_3D, internalFormat, levelSize, true);
+ }
+
+ for (size_t level = levels; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
+ {
+ mImageArray[level]->redefine(gl::TextureType::_3D, GL_NONE, gl::Extents(0, 0, 0), true);
+ }
+
+ // TODO(geofflang): Verify storage creation had no errors
+ BindFlags bindFlags;
+ bindFlags.renderTarget = IsRenderTargetUsage(mState.getUsage());
+ TexStoragePointer storage = {
+ mRenderer->createTextureStorage3D(internalFormat, bindFlags, size.width, size.height,
+ size.depth, static_cast<int>(levels), mState.getLabel()),
+ context};
+
+ ANGLE_TRY(setCompleteTexStorage(context, storage.get()));
+ storage.release();
+
+ ANGLE_TRY(updateStorage(context));
+
+ mImmutable = true;
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_3D::bindTexImage(const gl::Context *context, egl::Surface *surface)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_3D::releaseTexImage(const gl::Context *context)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_3D::initMipmapImages(const gl::Context *context)
+{
+ const GLuint baseLevel = mState.getEffectiveBaseLevel();
+ const GLuint maxLevel = mState.getMipmapMaxLevel();
+ // Purge array levels baseLevel + 1 through q and reset them to represent the generated mipmap
+ // levels.
+ for (GLuint level = baseLevel + 1; level <= maxLevel; level++)
+ {
+ gl::Extents levelSize(std::max(getLevelZeroWidth() >> level, 1),
+ std::max(getLevelZeroHeight() >> level, 1),
+ std::max(getLevelZeroDepth() >> level, 1));
+ ANGLE_TRY(redefineImage(context, level, getBaseLevelInternalFormat(), levelSize, false));
+ }
+
+ // We should be mip-complete now so generate the storage.
+ ANGLE_TRY(initializeStorage(context, BindFlags::RenderTarget()));
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_3D::getRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT)
+{
+ // ensure the underlying texture is created
+ ANGLE_TRY(ensureRenderTarget(context));
+
+ if (index.hasLayer())
+ {
+ ANGLE_TRY(updateStorage(context));
+ }
+ else
+ {
+ ANGLE_TRY(updateStorageLevel(context, index.getLevelIndex()));
+ }
+
+ return mTexStorage->getRenderTarget(context, index, samples, outRT);
+}
+
+angle::Result TextureD3D_3D::initializeStorage(const gl::Context *context, BindFlags bindFlags)
+{
+ // Only initialize the first time this texture is used as a render target or shader resource
+ if (mTexStorage)
+ {
+ return angle::Result::Continue;
+ }
+
+ // do not attempt to create storage for nonexistant data
+ if (!isLevelComplete(getBaseLevel()))
+ {
+ return angle::Result::Continue;
+ }
+
+ TexStoragePointer storage;
+ ANGLE_TRY(createCompleteStorage(context, bindFlags, &storage));
+
+ ANGLE_TRY(setCompleteTexStorage(context, storage.get()));
+ storage.release();
+
+ ASSERT(mTexStorage);
+
+ // flush image data to the storage
+ ANGLE_TRY(updateStorage(context));
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_3D::createCompleteStorage(const gl::Context *context,
+ BindFlags bindFlags,
+ TexStoragePointer *outStorage) const
+{
+ GLsizei width = getLevelZeroWidth();
+ GLsizei height = getLevelZeroHeight();
+ GLsizei depth = getLevelZeroDepth();
+ GLenum internalFormat = getBaseLevelInternalFormat();
+
+ ASSERT(width > 0 && height > 0 && depth > 0);
+
+ // use existing storage level count, when previously specified by TexStorage*D
+ GLint levels =
+ (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(width, height, depth));
+
+ // TODO: Verify creation of the storage succeeded
+ *outStorage = {mRenderer->createTextureStorage3D(internalFormat, bindFlags, width, height,
+ depth, levels, mState.getLabel()),
+ context};
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_3D::setCompleteTexStorage(const gl::Context *context,
+ TextureStorage *newCompleteTexStorage)
+{
+ gl::TexLevelMask copyImageMask;
+ copyImageMask.set();
+
+ ANGLE_TRY(releaseTexStorage(context, copyImageMask));
+ mTexStorage = newCompleteTexStorage;
+ mTexStorageObserverBinding.bind(mTexStorage);
+ mDirtyImages = true;
+
+ // We do not support managed 3D storage, as that is D3D9/ES2-only
+ ASSERT(!mTexStorage->isManaged());
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_3D::updateStorage(const gl::Context *context)
+{
+ if (!mDirtyImages)
+ {
+ return angle::Result::Continue;
+ }
+
+ ASSERT(mTexStorage != nullptr);
+ GLint storageLevels = mTexStorage->getLevelCount();
+ for (int level = 0; level < storageLevels; level++)
+ {
+ if (mImageArray[level]->isDirty() && isLevelComplete(level))
+ {
+ ANGLE_TRY(updateStorageLevel(context, level));
+ }
+ }
+
+ mDirtyImages = false;
+ return angle::Result::Continue;
+}
+
+bool TextureD3D_3D::isValidLevel(int level) const
+{
+ return (mTexStorage ? (level >= 0 && level < mTexStorage->getLevelCount()) : 0);
+}
+
+bool TextureD3D_3D::isLevelComplete(int level) const
+{
+ ASSERT(level >= 0 && level < static_cast<int>(mImageArray.size()) &&
+ mImageArray[level] != nullptr);
+
+ if (isImmutable())
+ {
+ return true;
+ }
+
+ GLsizei width = getLevelZeroWidth();
+ GLsizei height = getLevelZeroHeight();
+ GLsizei depth = getLevelZeroDepth();
+
+ if (width <= 0 || height <= 0 || depth <= 0)
+ {
+ return false;
+ }
+
+ if (level == static_cast<int>(getBaseLevel()))
+ {
+ return true;
+ }
+
+ ImageD3D *levelImage = mImageArray[level].get();
+
+ if (levelImage->getInternalFormat() != getBaseLevelInternalFormat())
+ {
+ return false;
+ }
+
+ if (levelImage->getWidth() != std::max(1, width >> level))
+ {
+ return false;
+ }
+
+ if (levelImage->getHeight() != std::max(1, height >> level))
+ {
+ return false;
+ }
+
+ if (levelImage->getDepth() != std::max(1, depth >> level))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool TextureD3D_3D::isImageComplete(const gl::ImageIndex &index) const
+{
+ return isLevelComplete(index.getLevelIndex());
+}
+
+angle::Result TextureD3D_3D::updateStorageLevel(const gl::Context *context, int level)
+{
+ ASSERT(level >= 0 && level < static_cast<int>(mImageArray.size()) &&
+ mImageArray[level] != nullptr);
+ ASSERT(isLevelComplete(level));
+
+ if (mImageArray[level]->isDirty())
+ {
+ gl::ImageIndex index = gl::ImageIndex::Make3D(level);
+ gl::Box region(0, 0, 0, getWidth(level), getHeight(level), getDepth(level));
+ ANGLE_TRY(commitRegion(context, index, region));
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_3D::redefineImage(const gl::Context *context,
+ GLint level,
+ GLenum internalformat,
+ const gl::Extents &size,
+ bool forceRelease)
+{
+ // If there currently is a corresponding storage texture image, it has these parameters
+ const int storageWidth = std::max(1, getLevelZeroWidth() >> level);
+ const int storageHeight = std::max(1, getLevelZeroHeight() >> level);
+ const int storageDepth = std::max(1, getLevelZeroDepth() >> level);
+ const GLenum storageFormat = getBaseLevelInternalFormat();
+
+ if (mTexStorage)
+ {
+ const int storageLevels = mTexStorage->getLevelCount();
+
+ if ((level >= storageLevels && storageLevels != 0) || size.width != storageWidth ||
+ size.height != storageHeight || size.depth != storageDepth ||
+ internalformat != storageFormat) // Discard mismatched storage
+ {
+ markAllImagesDirty();
+
+ gl::TexLevelMask copyImageMask;
+ copyImageMask.set();
+ copyImageMask.set(level, false);
+
+ ANGLE_TRY(releaseTexStorage(context, copyImageMask));
+ }
+ }
+
+ mImageArray[level]->redefine(gl::TextureType::_3D, internalformat, size, forceRelease);
+ mDirtyImages = mDirtyImages || mImageArray[level]->isDirty();
+
+ return angle::Result::Continue;
+}
+
+gl::ImageIndexIterator TextureD3D_3D::imageIterator() const
+{
+ return gl::ImageIndexIterator::Make3D(0, mTexStorage->getLevelCount(),
+ gl::ImageIndex::kEntireLevel,
+ gl::ImageIndex::kEntireLevel);
+}
+
+gl::ImageIndex TextureD3D_3D::getImageIndex(GLint mip, GLint /*layer*/) const
+{
+ // The "layer" here does not apply to 3D images. We use one Image per mip.
+ return gl::ImageIndex::Make3D(mip);
+}
+
+bool TextureD3D_3D::isValidIndex(const gl::ImageIndex &index) const
+{
+ return (mTexStorage && index.getType() == gl::TextureType::_3D && index.getLevelIndex() >= 0 &&
+ index.getLevelIndex() < mTexStorage->getLevelCount());
+}
+
+void TextureD3D_3D::markAllImagesDirty()
+{
+ for (int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+ {
+ mImageArray[i]->markDirty();
+ }
+ mDirtyImages = true;
+}
+
+GLint TextureD3D_3D::getLevelZeroDepth() const
+{
+ ASSERT(gl::CountLeadingZeros(static_cast<uint32_t>(getBaseLevelDepth())) > getBaseLevel());
+ return getBaseLevelDepth() << getBaseLevel();
+}
+
+TextureD3D_2DArray::TextureD3D_2DArray(const gl::TextureState &state, RendererD3D *renderer)
+ : TextureD3D(state, renderer)
+{
+ for (int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++level)
+ {
+ mLayerCounts[level] = 0;
+ mImageArray[level] = nullptr;
+ }
+}
+
+void TextureD3D_2DArray::onDestroy(const gl::Context *context)
+{
+ // Delete the Images before the TextureStorage. Images might be relying on the TextureStorage
+ // for some of their data. If TextureStorage is deleted before the Images, then their data will
+ // be wastefully copied back from the GPU before we delete the Images.
+ deleteImages();
+ return TextureD3D::onDestroy(context);
+}
+
+TextureD3D_2DArray::~TextureD3D_2DArray() {}
+
+ImageD3D *TextureD3D_2DArray::getImage(int level, int layer) const
+{
+ ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+ ASSERT((layer == 0 && mLayerCounts[level] == 0) || layer < mLayerCounts[level]);
+ return (mImageArray[level] ? mImageArray[level][layer] : nullptr);
+}
+
+ImageD3D *TextureD3D_2DArray::getImage(const gl::ImageIndex &index) const
+{
+ ASSERT(index.getLevelIndex() < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+ ASSERT(index.hasLayer());
+ ASSERT((index.getLayerIndex() == 0 && mLayerCounts[index.getLevelIndex()] == 0) ||
+ index.getLayerIndex() < mLayerCounts[index.getLevelIndex()]);
+ ASSERT(index.getType() == gl::TextureType::_2DArray);
+ return (mImageArray[index.getLevelIndex()]
+ ? mImageArray[index.getLevelIndex()][index.getLayerIndex()]
+ : nullptr);
+}
+
+GLsizei TextureD3D_2DArray::getLayerCount(int level) const
+{
+ ASSERT(level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+ return mLayerCounts[level];
+}
+
+GLsizei TextureD3D_2DArray::getWidth(GLint level) const
+{
+ return (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS && mLayerCounts[level] > 0)
+ ? mImageArray[level][0]->getWidth()
+ : 0;
+}
+
+GLsizei TextureD3D_2DArray::getHeight(GLint level) const
+{
+ return (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS && mLayerCounts[level] > 0)
+ ? mImageArray[level][0]->getHeight()
+ : 0;
+}
+
+GLenum TextureD3D_2DArray::getInternalFormat(GLint level) const
+{
+ return (level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS && mLayerCounts[level] > 0)
+ ? mImageArray[level][0]->getInternalFormat()
+ : GL_NONE;
+}
+
+bool TextureD3D_2DArray::isDepth(GLint level) const
+{
+ return gl::GetSizedInternalFormatInfo(getInternalFormat(level)).depthBits > 0;
+}
+
+bool TextureD3D_2DArray::isSRGB(GLint level) const
+{
+ return gl::GetSizedInternalFormatInfo(getInternalFormat(level)).colorEncoding == GL_SRGB;
+}
+
+angle::Result TextureD3D_2DArray::setEGLImageTarget(const gl::Context *context,
+ gl::TextureType type,
+ egl::Image *image)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2DArray::setImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLenum internalFormat,
+ const gl::Extents &size,
+ GLenum format,
+ GLenum type,
+ const gl::PixelUnpackState &unpack,
+ gl::Buffer *unpackBuffer,
+ const uint8_t *pixels)
+{
+ ASSERT(index.getTarget() == gl::TextureTarget::_2DArray);
+
+ const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat, type);
+
+ ANGLE_TRY(
+ redefineImage(context, index.getLevelIndex(), formatInfo.sizedInternalFormat, size, false));
+
+ ContextD3D *contextD3D = GetImplAs<ContextD3D>(context);
+
+ GLuint inputDepthPitch = 0;
+ ANGLE_CHECK_GL_MATH(contextD3D, formatInfo.computeDepthPitch(
+ type, size.width, size.height, unpack.alignment,
+ unpack.rowLength, unpack.imageHeight, &inputDepthPitch));
+
+ for (int i = 0; i < size.depth; i++)
+ {
+ const ptrdiff_t layerOffset = (inputDepthPitch * i);
+ gl::ImageIndex layerIndex = gl::ImageIndex::Make2DArray(index.getLevelIndex(), i);
+ ANGLE_TRY(
+ setImageImpl(context, layerIndex, type, unpack, unpackBuffer, pixels, layerOffset));
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2DArray::setSubImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Box &area,
+ GLenum format,
+ GLenum type,
+ const gl::PixelUnpackState &unpack,
+ gl::Buffer *unpackBuffer,
+ const uint8_t *pixels)
+{
+ ContextD3D *contextD3D = GetImplAs<ContextD3D>(context);
+
+ ASSERT(index.getTarget() == gl::TextureTarget::_2DArray);
+ const gl::InternalFormat &formatInfo =
+ gl::GetInternalFormatInfo(getInternalFormat(index.getLevelIndex()), type);
+ GLuint inputDepthPitch = 0;
+ ANGLE_CHECK_GL_MATH(contextD3D, formatInfo.computeDepthPitch(
+ type, area.width, area.height, unpack.alignment,
+ unpack.rowLength, unpack.imageHeight, &inputDepthPitch));
+
+ for (int i = 0; i < area.depth; i++)
+ {
+ int layer = area.z + i;
+ const ptrdiff_t layerOffset = (inputDepthPitch * i);
+
+ gl::Box layerArea(area.x, area.y, 0, area.width, area.height, 1);
+
+ gl::ImageIndex layerIndex = gl::ImageIndex::Make2DArray(index.getLevelIndex(), layer);
+ ANGLE_TRY(TextureD3D::subImage(context, layerIndex, layerArea, format, type, unpack,
+ unpackBuffer, pixels, layerOffset));
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2DArray::setCompressedImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLenum internalFormat,
+ const gl::Extents &size,
+ const gl::PixelUnpackState &unpack,
+ size_t imageSize,
+ const uint8_t *pixels)
+{
+ ASSERT(index.getTarget() == gl::TextureTarget::_2DArray);
+
+ ContextD3D *contextD3D = GetImplAs<ContextD3D>(context);
+
+ // compressed formats don't have separate sized internal formats-- we can just use the
+ // compressed format directly
+ ANGLE_TRY(redefineImage(context, index.getLevelIndex(), internalFormat, size, false));
+
+ const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalFormat);
+ GLuint inputDepthPitch = 0;
+ ANGLE_CHECK_GL_MATH(
+ contextD3D, formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, size.width, size.height, 1, 0, 0,
+ &inputDepthPitch));
+
+ for (int i = 0; i < size.depth; i++)
+ {
+ const ptrdiff_t layerOffset = (inputDepthPitch * i);
+
+ gl::ImageIndex layerIndex = gl::ImageIndex::Make2DArray(index.getLevelIndex(), i);
+ ANGLE_TRY(setCompressedImageImpl(context, layerIndex, unpack, pixels, layerOffset));
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2DArray::setCompressedSubImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Box &area,
+ GLenum format,
+ const gl::PixelUnpackState &unpack,
+ size_t imageSize,
+ const uint8_t *pixels)
+{
+ ASSERT(index.getTarget() == gl::TextureTarget::_2DArray);
+
+ ContextD3D *contextD3D = GetImplAs<ContextD3D>(context);
+
+ const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(format);
+ GLuint inputDepthPitch = 0;
+ ANGLE_CHECK_GL_MATH(
+ contextD3D, formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, area.width, area.height, 1, 0, 0,
+ &inputDepthPitch));
+
+ for (int i = 0; i < area.depth; i++)
+ {
+ int layer = area.z + i;
+ const ptrdiff_t layerOffset = (inputDepthPitch * i);
+
+ gl::Box layerArea(area.x, area.y, 0, area.width, area.height, 1);
+
+ gl::ImageIndex layerIndex = gl::ImageIndex::Make2DArray(index.getLevelIndex(), layer);
+ ANGLE_TRY(TextureD3D::subImageCompressed(context, layerIndex, layerArea, format, unpack,
+ pixels, layerOffset));
+ ANGLE_TRY(commitRegion(context, layerIndex, layerArea));
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2DArray::copyImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Rectangle &sourceArea,
+ GLenum internalFormat,
+ gl::Framebuffer *source)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2DArray::copySubImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Offset &destOffset,
+ const gl::Rectangle &sourceArea,
+ gl::Framebuffer *source)
+{
+ ASSERT(index.getTarget() == gl::TextureTarget::_2DArray);
+
+ gl::Extents fbSize = source->getReadColorAttachment()->getSize();
+ gl::Rectangle clippedSourceArea;
+ if (!ClipRectangle(sourceArea, gl::Rectangle(0, 0, fbSize.width, fbSize.height),
+ &clippedSourceArea))
+ {
+ return angle::Result::Continue;
+ }
+ const gl::Offset clippedDestOffset(destOffset.x + clippedSourceArea.x - sourceArea.x,
+ destOffset.y + clippedSourceArea.y - sourceArea.y,
+ destOffset.z);
+
+ if (!canCreateRenderTargetForImage(index))
+ {
+ gl::Offset destLayerOffset(clippedDestOffset.x, clippedDestOffset.y, 0);
+ ANGLE_TRY(mImageArray[index.getLevelIndex()][clippedDestOffset.z]->copyFromFramebuffer(
+ context, destLayerOffset, clippedSourceArea, source));
+ mDirtyImages = true;
+ onStateChange(angle::SubjectMessage::DirtyBitsFlagged);
+ }
+ else
+ {
+ ANGLE_TRY(ensureRenderTarget(context));
+
+ if (isValidLevel(index.getLevelIndex()))
+ {
+ ANGLE_TRY(updateStorageLevel(context, index.getLevelIndex()));
+ ANGLE_TRY(
+ mRenderer->copyImage2DArray(context, source, clippedSourceArea,
+ gl::GetUnsizedFormat(getInternalFormat(getBaseLevel())),
+ clippedDestOffset, mTexStorage, index.getLevelIndex()));
+ }
+ }
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2DArray::copyTexture(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLenum internalFormat,
+ GLenum type,
+ GLint sourceLevel,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha,
+ const gl::Texture *source)
+{
+ ASSERT(index.getTarget() == gl::TextureTarget::_2DArray);
+
+ gl::TextureType sourceType = source->getType();
+
+ const gl::InternalFormat &internalFormatInfo = gl::GetInternalFormatInfo(internalFormat, type);
+ gl::Extents size(
+ static_cast<int>(source->getWidth(NonCubeTextureTypeToTarget(sourceType), sourceLevel)),
+ static_cast<int>(source->getHeight(NonCubeTextureTypeToTarget(sourceType), sourceLevel)),
+ static_cast<int>(source->getDepth(NonCubeTextureTypeToTarget(sourceType), sourceLevel)));
+
+ ANGLE_TRY(redefineImage(context, index.getLevelIndex(), internalFormatInfo.sizedInternalFormat,
+ size, false));
+
+ gl::Box sourceBox(0, 0, 0, size.width, size.height, size.depth);
+ gl::Offset destOffset(0, 0, 0);
+
+ gl::ImageIndex destIndex =
+ gl::ImageIndex::Make2DArrayRange(index.getLevelIndex(), 0, size.depth);
+
+ if (!isSRGB(index.getLevelIndex()) &&
+ canCreateRenderTargetForImage(
+ gl::ImageIndex::Make2DArrayRange(index.getLevelIndex(), 0, size.depth)))
+ {
+ ANGLE_TRY(ensureRenderTarget(context));
+ ASSERT(isValidLevel(index.getLevelIndex()));
+ ANGLE_TRY(updateStorageLevel(context, index.getLevelIndex()));
+ ANGLE_TRY(mRenderer->copyTexture(context, source, sourceLevel, gl::TextureTarget::_2DArray,
+ sourceBox, internalFormatInfo.format,
+ internalFormatInfo.type, destOffset, mTexStorage,
+ index.getTarget(), index.getLevelIndex(), unpackFlipY,
+ unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
+ }
+ else
+ {
+ for (int i = 0; i < size.depth; i++)
+ {
+ gl::ImageIndex currentSourceDepthIndex = gl::ImageIndex::Make2DArray(sourceLevel, i);
+ gl::ImageIndex currentDestDepthIndex =
+ gl::ImageIndex::Make2DArray(index.getLevelIndex(), i);
+ ImageD3D *sourceImage = nullptr;
+ ImageD3D *destImage = nullptr;
+ TextureD3D *sourceD3D = GetImplAs<TextureD3D>(source);
+
+ ANGLE_TRY(getImageAndSyncFromStorage(context, currentDestDepthIndex, &destImage));
+ ANGLE_TRY(sourceD3D->getImageAndSyncFromStorage(context, currentSourceDepthIndex,
+ &sourceImage));
+ gl::Box imageBox(sourceBox.x, sourceBox.y, 0, sourceBox.width, sourceBox.height, 1);
+ ANGLE_TRY(mRenderer->copyImage(context, destImage, sourceImage, imageBox, destOffset,
+ unpackFlipY, unpackPremultiplyAlpha,
+ unpackUnmultiplyAlpha));
+ }
+
+ mDirtyImages = true;
+
+ gl::Box destRegion(destOffset.x, destOffset.y, destOffset.z, sourceBox.width,
+ sourceBox.height, sourceBox.depth);
+ ANGLE_TRY(commitRegion(context, destIndex, destRegion));
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2DArray::copySubTexture(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Offset &destOffset,
+ GLint sourceLevel,
+ const gl::Box &sourceBox,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha,
+ const gl::Texture *source)
+{
+ ASSERT(index.getTarget() == gl::TextureTarget::_2DArray);
+
+ gl::ImageIndex destIndex = gl::ImageIndex::Make2DArrayRange(
+ static_cast<GLint>(index.getLevelIndex()), destOffset.z, sourceBox.depth - destOffset.z);
+
+ if (!isSRGB(destIndex.getLevelIndex()) && canCreateRenderTargetForImage(destIndex))
+ {
+ ANGLE_TRY(ensureRenderTarget(context));
+ ASSERT(isValidLevel(destIndex.getLevelIndex()));
+ ANGLE_TRY(updateStorageLevel(context, destIndex.getLevelIndex()));
+
+ const gl::InternalFormat &internalFormatInfo =
+ gl::GetSizedInternalFormatInfo(getInternalFormat(destIndex.getLevelIndex()));
+ ANGLE_TRY(mRenderer->copyTexture(context, source, sourceLevel, gl::TextureTarget::_2DArray,
+ sourceBox, internalFormatInfo.format,
+ internalFormatInfo.type, destOffset, mTexStorage,
+ index.getTarget(), index.getLevelIndex(), unpackFlipY,
+ unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
+ }
+ else
+ {
+ for (int i = 0; i < sourceBox.depth; i++)
+ {
+ gl::ImageIndex currentSourceIndex =
+ gl::ImageIndex::Make2DArray(sourceLevel, i + sourceBox.z);
+ gl::ImageIndex currentDestIndex =
+ gl::ImageIndex::Make2DArray(index.getLevelIndex(), i + destOffset.z);
+
+ gl::Box currentLayerBox(sourceBox.x, sourceBox.y, 0, sourceBox.width, sourceBox.height,
+ 1);
+
+ TextureD3D *sourceD3D = GetImplAs<TextureD3D>(source);
+ ImageD3D *sourceImage = nullptr;
+ ANGLE_TRY(
+ sourceD3D->getImageAndSyncFromStorage(context, currentSourceIndex, &sourceImage));
+
+ ImageD3D *destImage = nullptr;
+ ANGLE_TRY(getImageAndSyncFromStorage(context, currentDestIndex, &destImage));
+
+ ANGLE_TRY(mRenderer->copyImage(context, destImage, sourceImage, currentLayerBox,
+ destOffset, unpackFlipY, unpackPremultiplyAlpha,
+ unpackUnmultiplyAlpha));
+ }
+
+ mDirtyImages = true;
+
+ gl::Box destRegion(destOffset.x, destOffset.y, destOffset.z, sourceBox.width,
+ sourceBox.height, sourceBox.depth);
+ ANGLE_TRY(commitRegion(context, destIndex, destRegion));
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2DArray::setStorage(const gl::Context *context,
+ gl::TextureType type,
+ size_t levels,
+ GLenum internalFormat,
+ const gl::Extents &size)
+{
+ ASSERT(type == gl::TextureType::_2DArray);
+
+ deleteImages();
+
+ for (size_t level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
+ {
+ gl::Extents levelLayerSize(std::max(1, size.width >> level),
+ std::max(1, size.height >> level), 1);
+
+ mLayerCounts[level] = (level < levels ? size.depth : 0);
+
+ if (mLayerCounts[level] > 0)
+ {
+ // Create new images for this level
+ mImageArray[level] = new ImageD3D *[mLayerCounts[level]];
+
+ for (int layer = 0; layer < mLayerCounts[level]; layer++)
+ {
+ mImageArray[level][layer] = mRenderer->createImage();
+ mImageArray[level][layer]->redefine(gl::TextureType::_2DArray, internalFormat,
+ levelLayerSize, true);
+ }
+ }
+ }
+
+ // TODO(geofflang): Verify storage creation had no errors
+ BindFlags bindFlags;
+ bindFlags.renderTarget = IsRenderTargetUsage(mState.getUsage());
+ TexStoragePointer storage = {mRenderer->createTextureStorage2DArray(
+ internalFormat, bindFlags, size.width, size.height, size.depth,
+ static_cast<int>(levels), mState.getLabel()),
+ context};
+
+ ANGLE_TRY(setCompleteTexStorage(context, storage.get()));
+ storage.release();
+
+ ANGLE_TRY(updateStorage(context));
+
+ mImmutable = true;
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2DArray::bindTexImage(const gl::Context *context, egl::Surface *surface)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2DArray::releaseTexImage(const gl::Context *context)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2DArray::initMipmapImages(const gl::Context *context)
+{
+ const GLuint baseLevel = mState.getEffectiveBaseLevel();
+ const GLuint maxLevel = mState.getMipmapMaxLevel();
+ int baseWidth = getLevelZeroWidth();
+ int baseHeight = getLevelZeroHeight();
+ int baseDepth = getLayerCount(getBaseLevel());
+ GLenum baseFormat = getBaseLevelInternalFormat();
+
+ // Purge array levels baseLevel + 1 through q and reset them to represent the generated mipmap
+ // levels.
+ for (GLuint level = baseLevel + 1u; level <= maxLevel; level++)
+ {
+ ASSERT((baseWidth >> level) > 0 || (baseHeight >> level) > 0);
+ gl::Extents levelLayerSize(std::max(baseWidth >> level, 1),
+ std::max(baseHeight >> level, 1), baseDepth);
+ ANGLE_TRY(redefineImage(context, level, baseFormat, levelLayerSize, false));
+ }
+
+ // We should be mip-complete now so generate the storage.
+ ANGLE_TRY(initializeStorage(context, BindFlags::RenderTarget()));
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2DArray::getRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT)
+{
+ // ensure the underlying texture is created
+ ANGLE_TRY(ensureRenderTarget(context));
+ ANGLE_TRY(updateStorageLevel(context, index.getLevelIndex()));
+ return mTexStorage->getRenderTarget(context, index, samples, outRT);
+}
+
+angle::Result TextureD3D_2DArray::initializeStorage(const gl::Context *context, BindFlags bindFlags)
+{
+ // Only initialize the first time this texture is used as a render target or shader resource
+ if (mTexStorage)
+ {
+ return angle::Result::Continue;
+ }
+
+ // do not attempt to create storage for nonexistant data
+ if (!isLevelComplete(getBaseLevel()))
+ {
+ return angle::Result::Continue;
+ }
+
+ bindFlags.renderTarget |= IsRenderTargetUsage(mState.getUsage());
+
+ TexStoragePointer storage;
+ ANGLE_TRY(createCompleteStorage(context, bindFlags, &storage));
+
+ ANGLE_TRY(setCompleteTexStorage(context, storage.get()));
+ storage.release();
+
+ ASSERT(mTexStorage);
+
+ // flush image data to the storage
+ ANGLE_TRY(updateStorage(context));
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2DArray::createCompleteStorage(const gl::Context *context,
+ BindFlags bindFlags,
+ TexStoragePointer *outStorage) const
+{
+ GLsizei width = getLevelZeroWidth();
+ GLsizei height = getLevelZeroHeight();
+ GLsizei depth = getLayerCount(getBaseLevel());
+ GLenum internalFormat = getBaseLevelInternalFormat();
+
+ ASSERT(width > 0 && height > 0 && depth > 0);
+
+ // use existing storage level count, when previously specified by TexStorage*D
+ GLint levels = (mTexStorage ? mTexStorage->getLevelCount() : creationLevels(width, height, 1));
+
+ // TODO(geofflang): Verify storage creation succeeds
+ *outStorage = {mRenderer->createTextureStorage2DArray(internalFormat, bindFlags, width, height,
+ depth, levels, mState.getLabel()),
+ context};
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2DArray::setCompleteTexStorage(const gl::Context *context,
+ TextureStorage *newCompleteTexStorage)
+{
+ gl::TexLevelMask copyImageMask;
+ copyImageMask.set();
+
+ ANGLE_TRY(releaseTexStorage(context, copyImageMask));
+ mTexStorage = newCompleteTexStorage;
+ mTexStorageObserverBinding.bind(mTexStorage);
+ mDirtyImages = true;
+
+ // We do not support managed 2D array storage, as managed storage is ES2/D3D9 only
+ ASSERT(!mTexStorage->isManaged());
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2DArray::updateStorage(const gl::Context *context)
+{
+ if (!mDirtyImages)
+ {
+ return angle::Result::Continue;
+ }
+
+ ASSERT(mTexStorage != nullptr);
+ GLint storageLevels = mTexStorage->getLevelCount();
+ for (int level = 0; level < storageLevels; level++)
+ {
+ if (isLevelComplete(level))
+ {
+ ANGLE_TRY(updateStorageLevel(context, level));
+ }
+ }
+
+ mDirtyImages = false;
+ return angle::Result::Continue;
+}
+
+bool TextureD3D_2DArray::isValidLevel(int level) const
+{
+ return (mTexStorage ? (level >= 0 && level < mTexStorage->getLevelCount()) : 0);
+}
+
+bool TextureD3D_2DArray::isLevelComplete(int level) const
+{
+ ASSERT(level >= 0 && level < (int)ArraySize(mImageArray));
+
+ if (isImmutable())
+ {
+ return true;
+ }
+
+ GLsizei width = getLevelZeroWidth();
+ GLsizei height = getLevelZeroHeight();
+
+ if (width <= 0 || height <= 0)
+ {
+ return false;
+ }
+
+ // Layers check needs to happen after the above checks, otherwise out-of-range base level may be
+ // queried.
+ GLsizei layers = getLayerCount(getBaseLevel());
+
+ if (layers <= 0)
+ {
+ return false;
+ }
+
+ if (level == static_cast<int>(getBaseLevel()))
+ {
+ return true;
+ }
+
+ if (getInternalFormat(level) != getInternalFormat(getBaseLevel()))
+ {
+ return false;
+ }
+
+ if (getWidth(level) != std::max(1, width >> level))
+ {
+ return false;
+ }
+
+ if (getHeight(level) != std::max(1, height >> level))
+ {
+ return false;
+ }
+
+ if (getLayerCount(level) != layers)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool TextureD3D_2DArray::isImageComplete(const gl::ImageIndex &index) const
+{
+ return isLevelComplete(index.getLevelIndex());
+}
+
+angle::Result TextureD3D_2DArray::updateStorageLevel(const gl::Context *context, int level)
+{
+ ASSERT(level >= 0 && level < static_cast<int>(ArraySize(mLayerCounts)));
+ ASSERT(isLevelComplete(level));
+
+ for (int layer = 0; layer < mLayerCounts[level]; layer++)
+ {
+ ASSERT(mImageArray[level] != nullptr && mImageArray[level][layer] != nullptr);
+ if (mImageArray[level][layer]->isDirty())
+ {
+ gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, layer);
+ gl::Box region(0, 0, 0, getWidth(level), getHeight(level), 1);
+ ANGLE_TRY(commitRegion(context, index, region));
+ }
+ }
+
+ return angle::Result::Continue;
+}
+
+void TextureD3D_2DArray::deleteImages()
+{
+ for (int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++level)
+ {
+ for (int layer = 0; layer < mLayerCounts[level]; ++layer)
+ {
+ delete mImageArray[level][layer];
+ }
+ delete[] mImageArray[level];
+ mImageArray[level] = nullptr;
+ mLayerCounts[level] = 0;
+ }
+}
+
+angle::Result TextureD3D_2DArray::redefineImage(const gl::Context *context,
+ GLint level,
+ GLenum internalformat,
+ const gl::Extents &size,
+ bool forceRelease)
+{
+ // If there currently is a corresponding storage texture image, it has these parameters
+ const int storageWidth = std::max(1, getLevelZeroWidth() >> level);
+ const int storageHeight = std::max(1, getLevelZeroHeight() >> level);
+ const GLuint baseLevel = getBaseLevel();
+ const GLenum storageFormat = getBaseLevelInternalFormat();
+
+ int storageDepth = 0;
+ if (baseLevel < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+ {
+ storageDepth = getLayerCount(baseLevel);
+ }
+
+ // Only reallocate the layers if the size doesn't match
+ if (size.depth != mLayerCounts[level])
+ {
+ for (int layer = 0; layer < mLayerCounts[level]; layer++)
+ {
+ SafeDelete(mImageArray[level][layer]);
+ }
+ SafeDeleteArray(mImageArray[level]);
+ mLayerCounts[level] = size.depth;
+
+ if (size.depth > 0)
+ {
+ mImageArray[level] = new ImageD3D *[size.depth];
+ for (int layer = 0; layer < mLayerCounts[level]; layer++)
+ {
+ mImageArray[level][layer] = mRenderer->createImage();
+ }
+ }
+ }
+
+ if (mTexStorage)
+ {
+ const int storageLevels = mTexStorage->getLevelCount();
+
+ if ((level >= storageLevels && storageLevels != 0) || size.width != storageWidth ||
+ size.height != storageHeight || size.depth != storageDepth ||
+ internalformat != storageFormat) // Discard mismatched storage
+ {
+ markAllImagesDirty();
+
+ gl::TexLevelMask copyImageMask;
+ copyImageMask.set();
+ copyImageMask.set(level, false);
+
+ ANGLE_TRY(releaseTexStorage(context, copyImageMask));
+ }
+ }
+
+ if (size.depth > 0)
+ {
+ for (int layer = 0; layer < mLayerCounts[level]; layer++)
+ {
+ mImageArray[level][layer]->redefine(gl::TextureType::_2DArray, internalformat,
+ gl::Extents(size.width, size.height, 1),
+ forceRelease);
+ mDirtyImages = mDirtyImages || mImageArray[level][layer]->isDirty();
+ }
+ }
+
+ return angle::Result::Continue;
+}
+
+gl::ImageIndexIterator TextureD3D_2DArray::imageIterator() const
+{
+ return gl::ImageIndexIterator::Make2DArray(0, mTexStorage->getLevelCount(), mLayerCounts);
+}
+
+gl::ImageIndex TextureD3D_2DArray::getImageIndex(GLint mip, GLint layer) const
+{
+ return gl::ImageIndex::Make2DArray(mip, layer);
+}
+
+bool TextureD3D_2DArray::isValidIndex(const gl::ImageIndex &index) const
+{
+ // Check for having a storage and the right type of index
+ if (!mTexStorage || index.getType() != gl::TextureType::_2DArray)
+ {
+ return false;
+ }
+
+ // Check the mip index
+ if (index.getLevelIndex() < 0 || index.getLevelIndex() >= mTexStorage->getLevelCount())
+ {
+ return false;
+ }
+
+ // Check the layer index
+ return (!index.hasLayer() || (index.getLayerIndex() >= 0 &&
+ index.getLayerIndex() < mLayerCounts[index.getLevelIndex()]));
+}
+
+void TextureD3D_2DArray::markAllImagesDirty()
+{
+ for (int dirtyLevel = 0; dirtyLevel < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; dirtyLevel++)
+ {
+ for (int dirtyLayer = 0; dirtyLayer < mLayerCounts[dirtyLevel]; dirtyLayer++)
+ {
+ mImageArray[dirtyLevel][dirtyLayer]->markDirty();
+ }
+ }
+ mDirtyImages = true;
+}
+
+TextureD3DImmutableBase::TextureD3DImmutableBase(const gl::TextureState &state,
+ RendererD3D *renderer)
+ : TextureD3D(state, renderer)
+{}
+
+TextureD3DImmutableBase::~TextureD3DImmutableBase() {}
+
+ImageD3D *TextureD3DImmutableBase::getImage(const gl::ImageIndex &index) const
+{
+ return nullptr;
+}
+
+angle::Result TextureD3DImmutableBase::setImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLenum internalFormat,
+ const gl::Extents &size,
+ GLenum format,
+ GLenum type,
+ const gl::PixelUnpackState &unpack,
+ gl::Buffer *unpackBuffer,
+ const uint8_t *pixels)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3DImmutableBase::setSubImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Box &area,
+ GLenum format,
+ GLenum type,
+ const gl::PixelUnpackState &unpack,
+ gl::Buffer *unpackBuffer,
+ const uint8_t *pixels)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3DImmutableBase::setCompressedImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLenum internalFormat,
+ const gl::Extents &size,
+ const gl::PixelUnpackState &unpack,
+ size_t imageSize,
+ const uint8_t *pixels)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3DImmutableBase::setCompressedSubImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Box &area,
+ GLenum format,
+ const gl::PixelUnpackState &unpack,
+ size_t imageSize,
+ const uint8_t *pixels)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3DImmutableBase::copyImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Rectangle &sourceArea,
+ GLenum internalFormat,
+ gl::Framebuffer *source)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3DImmutableBase::copySubImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Offset &destOffset,
+ const gl::Rectangle &sourceArea,
+ gl::Framebuffer *source)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3DImmutableBase::bindTexImage(const gl::Context *context,
+ egl::Surface *surface)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3DImmutableBase::releaseTexImage(const gl::Context *context)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
+ return angle::Result::Continue;
+}
+
+TextureD3D_External::TextureD3D_External(const gl::TextureState &state, RendererD3D *renderer)
+ : TextureD3DImmutableBase(state, renderer)
+{}
+
+TextureD3D_External::~TextureD3D_External() {}
+
+GLsizei TextureD3D_External::getLayerCount(int level) const
+{
+ return 1;
+}
+
+angle::Result TextureD3D_External::setImageExternal(const gl::Context *context,
+ gl::TextureType type,
+ egl::Stream *stream,
+ const egl::Stream::GLTextureDescription &desc)
+{
+ ASSERT(type == gl::TextureType::External);
+
+ ANGLE_TRY(releaseTexStorage(context, gl::TexLevelMask()));
+
+ // If the stream is null, the external image is unbound and we release the storage
+ if (stream != nullptr)
+ {
+ mTexStorage = mRenderer->createTextureStorageExternal(stream, desc, mState.getLabel());
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_External::setEGLImageTarget(const gl::Context *context,
+ gl::TextureType type,
+ egl::Image *image)
+{
+ EGLImageD3D *eglImaged3d = GetImplAs<EGLImageD3D>(image);
+
+ // Pass in the RenderTargetD3D here: createTextureStorage can't generate an error.
+ RenderTargetD3D *renderTargetD3D = nullptr;
+ ANGLE_TRY(eglImaged3d->getRenderTarget(context, &renderTargetD3D));
+
+ ANGLE_TRY(releaseTexStorage(context, gl::TexLevelMask()));
+ mTexStorage =
+ mRenderer->createTextureStorageEGLImage(eglImaged3d, renderTargetD3D, mState.getLabel());
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_External::initMipmapImages(const gl::Context *context)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
+ return angle::Result::Stop;
+}
+
+angle::Result TextureD3D_External::getRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT)
+{
+ UNREACHABLE();
+ return angle::Result::Stop;
+}
+
+bool TextureD3D_External::isImageComplete(const gl::ImageIndex &index) const
+{
+ return (index.getLevelIndex() == 0) ? (mTexStorage != nullptr) : false;
+}
+
+angle::Result TextureD3D_External::initializeStorage(const gl::Context *context,
+ BindFlags bindFlags)
+{
+ // Texture storage is created when an external image is bound
+ ASSERT(mTexStorage);
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_External::createCompleteStorage(const gl::Context *context,
+ BindFlags bindFlags,
+ TexStoragePointer *outStorage) const
+{
+ UNREACHABLE();
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_External::setCompleteTexStorage(const gl::Context *context,
+ TextureStorage *newCompleteTexStorage)
+{
+ UNREACHABLE();
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_External::updateStorage(const gl::Context *context)
+{
+ // Texture storage does not need to be updated since it is already loaded with the latest
+ // external image
+ ASSERT(mTexStorage);
+ return angle::Result::Continue;
+}
+
+gl::ImageIndexIterator TextureD3D_External::imageIterator() const
+{
+ return gl::ImageIndexIterator::Make2D(0, mTexStorage->getLevelCount());
+}
+
+gl::ImageIndex TextureD3D_External::getImageIndex(GLint mip, GLint /*layer*/) const
+{
+ // "layer" does not apply to 2D Textures.
+ return gl::ImageIndex::Make2D(mip);
+}
+
+bool TextureD3D_External::isValidIndex(const gl::ImageIndex &index) const
+{
+ return (mTexStorage && index.getType() == gl::TextureType::External &&
+ index.getLevelIndex() == 0);
+}
+
+void TextureD3D_External::markAllImagesDirty()
+{
+ UNREACHABLE();
+}
+
+TextureD3D_2DMultisample::TextureD3D_2DMultisample(const gl::TextureState &state,
+ RendererD3D *renderer)
+ : TextureD3DImmutableBase(state, renderer)
+{}
+
+TextureD3D_2DMultisample::~TextureD3D_2DMultisample() {}
+
+angle::Result TextureD3D_2DMultisample::setStorageMultisample(const gl::Context *context,
+ gl::TextureType type,
+ GLsizei samples,
+ GLint internalformat,
+ const gl::Extents &size,
+ bool fixedSampleLocations)
+{
+ ASSERT(type == gl::TextureType::_2DMultisample && size.depth == 1);
+
+ // We allocate storage immediately instead of doing it lazily like other TextureD3D classes do.
+ // This requires less state in this class.
+ TexStoragePointer storage = {mRenderer->createTextureStorage2DMultisample(
+ internalformat, size.width, size.height, static_cast<int>(0),
+ samples, fixedSampleLocations, mState.getLabel()),
+ context};
+
+ ANGLE_TRY(setCompleteTexStorage(context, storage.get()));
+ storage.release();
+
+ mImmutable = true;
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2DMultisample::setEGLImageTarget(const gl::Context *context,
+ gl::TextureType type,
+ egl::Image *image)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2DMultisample::getRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT)
+{
+ ASSERT(!index.hasLayer());
+
+ // ensure the underlying texture is created
+ ANGLE_TRY(ensureRenderTarget(context));
+
+ return mTexStorage->getRenderTarget(context, index, samples, outRT);
+}
+
+gl::ImageIndexIterator TextureD3D_2DMultisample::imageIterator() const
+{
+ return gl::ImageIndexIterator::Make2DMultisample();
+}
+
+gl::ImageIndex TextureD3D_2DMultisample::getImageIndex(GLint mip, GLint layer) const
+{
+ return gl::ImageIndex::Make2DMultisample();
+}
+
+bool TextureD3D_2DMultisample::isValidIndex(const gl::ImageIndex &index) const
+{
+ return (mTexStorage && index.getType() == gl::TextureType::_2DMultisample &&
+ index.getLevelIndex() == 0);
+}
+
+GLsizei TextureD3D_2DMultisample::getLayerCount(int level) const
+{
+ return 1;
+}
+
+void TextureD3D_2DMultisample::markAllImagesDirty() {}
+
+angle::Result TextureD3D_2DMultisample::initializeStorage(const gl::Context *context,
+ BindFlags bindFlags)
+{
+ // initializeStorage should only be called in a situation where the texture already has storage
+ // associated with it (storage is created in setStorageMultisample).
+ ASSERT(mTexStorage);
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2DMultisample::createCompleteStorage(const gl::Context *context,
+ BindFlags bindFlags,
+ TexStoragePointer *outStorage) const
+{
+ UNREACHABLE();
+ *outStorage = {mTexStorage, context};
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2DMultisample::setCompleteTexStorage(const gl::Context *context,
+ TextureStorage *newCompleteTexStorage)
+{
+ // These textures are immutable, so this should only be ever called once.
+ ASSERT(!mTexStorage);
+ mTexStorage = newCompleteTexStorage;
+ mTexStorageObserverBinding.bind(mTexStorage);
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2DMultisample::updateStorage(const gl::Context *context)
+{
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2DMultisample::initMipmapImages(const gl::Context *context)
+{
+ UNREACHABLE();
+ return angle::Result::Continue;
+}
+
+bool TextureD3D_2DMultisample::isImageComplete(const gl::ImageIndex &index) const
+{
+ return true;
+}
+
+TextureD3D_2DMultisampleArray::TextureD3D_2DMultisampleArray(const gl::TextureState &state,
+ RendererD3D *renderer)
+ : TextureD3DImmutableBase(state, renderer)
+{}
+
+TextureD3D_2DMultisampleArray::~TextureD3D_2DMultisampleArray() {}
+
+angle::Result TextureD3D_2DMultisampleArray::setStorageMultisample(const gl::Context *context,
+ gl::TextureType type,
+ GLsizei samples,
+ GLint internalformat,
+ const gl::Extents &size,
+ bool fixedSampleLocations)
+{
+ ASSERT(type == gl::TextureType::_2DMultisampleArray);
+
+ mLayerCount = size.depth;
+
+ TexStoragePointer storage = {
+ mRenderer->createTextureStorage2DMultisampleArray(internalformat, size.width, size.height,
+ size.depth, static_cast<int>(0), samples,
+ fixedSampleLocations, mState.getLabel()),
+ context};
+
+ ANGLE_TRY(setCompleteTexStorage(context, storage.get()));
+ storage.release();
+
+ mImmutable = true;
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2DMultisampleArray::setEGLImageTarget(const gl::Context *context,
+ gl::TextureType type,
+ egl::Image *image)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2DMultisampleArray::getRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT)
+{
+ // ensure the underlying texture is created
+ ANGLE_TRY(ensureRenderTarget(context));
+
+ return mTexStorage->getRenderTarget(context, index, samples, outRT);
+}
+
+gl::ImageIndexIterator TextureD3D_2DMultisampleArray::imageIterator() const
+{
+ return gl::ImageIndexIterator::Make2DMultisampleArray(&mLayerCount);
+}
+
+gl::ImageIndex TextureD3D_2DMultisampleArray::getImageIndex(GLint mip, GLint layer) const
+{
+ return gl::ImageIndex::Make2DMultisampleArray(layer);
+}
+
+bool TextureD3D_2DMultisampleArray::isValidIndex(const gl::ImageIndex &index) const
+{
+ return (mTexStorage && index.getType() == gl::TextureType::_2DMultisampleArray &&
+ index.getLevelIndex() == 0);
+}
+
+GLsizei TextureD3D_2DMultisampleArray::getLayerCount(int level) const
+{
+ return mLayerCount;
+}
+
+void TextureD3D_2DMultisampleArray::markAllImagesDirty() {}
+
+angle::Result TextureD3D_2DMultisampleArray::initializeStorage(const gl::Context *context,
+ BindFlags bindFlags)
+{
+ // initializeStorage should only be called in a situation where the texture already has storage
+ // associated with it (storage is created in setStorageMultisample).
+ ASSERT(mTexStorage);
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2DMultisampleArray::createCompleteStorage(
+ const gl::Context *context,
+ BindFlags bindFlags,
+ TexStoragePointer *outStorage) const
+{
+ UNREACHABLE();
+ *outStorage = {mTexStorage, context};
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2DMultisampleArray::setCompleteTexStorage(
+ const gl::Context *context,
+ TextureStorage *newCompleteTexStorage)
+{
+ // These textures are immutable, so this should only be ever called once.
+ ASSERT(!mTexStorage);
+ mTexStorage = newCompleteTexStorage;
+ mTexStorageObserverBinding.bind(mTexStorage);
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2DMultisampleArray::updateStorage(const gl::Context *context)
+{
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_2DMultisampleArray::initMipmapImages(const gl::Context *context)
+{
+ UNIMPLEMENTED();
+ return angle::Result::Continue;
+}
+
+bool TextureD3D_2DMultisampleArray::isImageComplete(const gl::ImageIndex &index) const
+{
+ return true;
+}
+
+TextureD3D_Buffer::TextureD3D_Buffer(const gl::TextureState &state, RendererD3D *renderer)
+ : TextureD3D(state, renderer), mInternalFormat(GL_INVALID_ENUM)
+{}
+
+TextureD3D_Buffer::~TextureD3D_Buffer() {}
+
+angle::Result TextureD3D_Buffer::setImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLenum internalFormat,
+ const gl::Extents &size,
+ GLenum format,
+ GLenum type,
+ const gl::PixelUnpackState &unpack,
+ gl::Buffer *unpackBuffer,
+ const uint8_t *pixels)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_Buffer::setSubImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Box &area,
+ GLenum format,
+ GLenum type,
+ const gl::PixelUnpackState &unpack,
+ gl::Buffer *unpackBuffer,
+ const uint8_t *pixels)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_Buffer::setCompressedImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLenum internalFormat,
+ const gl::Extents &size,
+ const gl::PixelUnpackState &unpack,
+ size_t imageSize,
+ const uint8_t *pixels)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_Buffer::setCompressedSubImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Box &area,
+ GLenum format,
+ const gl::PixelUnpackState &unpack,
+ size_t imageSize,
+ const uint8_t *pixels)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_Buffer::copyImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Rectangle &sourceArea,
+ GLenum internalFormat,
+ gl::Framebuffer *source)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_Buffer::copySubImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Offset &destOffset,
+ const gl::Rectangle &sourceArea,
+ gl::Framebuffer *source)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_Buffer::bindTexImage(const gl::Context *context, egl::Surface *surface)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_Buffer::releaseTexImage(const gl::Context *context)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
+ return angle::Result::Continue;
+}
+
+GLsizei TextureD3D_Buffer::getLayerCount(int level) const
+{
+ return 1;
+}
+
+angle::Result TextureD3D_Buffer::initMipmapImages(const gl::Context *context)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
+ return angle::Result::Stop;
+}
+
+bool TextureD3D_Buffer::isImageComplete(const gl::ImageIndex &index) const
+{
+ return (index.getLevelIndex() == 0) ? (mTexStorage != nullptr) : false;
+}
+
+angle::Result TextureD3D_Buffer::initializeStorage(const gl::Context *context, BindFlags bindFlags)
+{
+ ASSERT(mTexStorage);
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_Buffer::createCompleteStorage(const gl::Context *context,
+ BindFlags bindFlags,
+ TexStoragePointer *outStorage) const
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_Buffer::setCompleteTexStorage(const gl::Context *context,
+ TextureStorage *newCompleteTexStorage)
+{
+ ANGLE_TRY(releaseTexStorage(context, gl::TexLevelMask()));
+ mTexStorage = newCompleteTexStorage;
+ mTexStorageObserverBinding.bind(mTexStorage);
+
+ mDirtyImages = true;
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_Buffer::updateStorage(const gl::Context *context)
+{
+ ASSERT(mTexStorage);
+ return angle::Result::Continue;
+}
+
+gl::ImageIndexIterator TextureD3D_Buffer::imageIterator() const
+{
+ return gl::ImageIndexIterator::MakeBuffer();
+}
+
+gl::ImageIndex TextureD3D_Buffer::getImageIndex(GLint mip, GLint layer) const
+{
+ return gl::ImageIndex::MakeBuffer();
+}
+
+bool TextureD3D_Buffer::isValidIndex(const gl::ImageIndex &index) const
+{
+ return (mTexStorage && index.getType() == gl::TextureType::Buffer &&
+ index.getLevelIndex() == 0);
+}
+
+void TextureD3D_Buffer::markAllImagesDirty()
+{
+ UNREACHABLE();
+}
+
+angle::Result TextureD3D_Buffer::setEGLImageTarget(const gl::Context *context,
+ gl::TextureType type,
+ egl::Image *image)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_Buffer::getRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<ContextD3D>(context));
+ return angle::Result::Continue;
+}
+
+ImageD3D *TextureD3D_Buffer::getImage(const gl::ImageIndex &index) const
+{
+ return nullptr;
+}
+
+angle::Result TextureD3D_Buffer::setBuffer(const gl::Context *context, GLenum internalFormat)
+{
+ ASSERT(mState.getType() == gl::TextureType::Buffer);
+ TexStoragePointer storage;
+ storage.reset(mRenderer->createTextureStorageBuffer(mState.getBuffer(), internalFormat,
+ mState.getLabel()));
+ ANGLE_TRY(setCompleteTexStorage(context, storage.get()));
+ storage.release();
+ mInternalFormat = internalFormat;
+ mImmutable = false;
+ return angle::Result::Continue;
+}
+
+angle::Result TextureD3D_Buffer::syncState(const gl::Context *context,
+ const gl::Texture::DirtyBits &dirtyBits,
+ gl::Command source)
+{
+ ASSERT(mState.getType() == gl::TextureType::Buffer);
+ if (dirtyBits.test(gl::Texture::DirtyBitType::DIRTY_BIT_IMPLEMENTATION) &&
+ mState.getBuffer().get() != nullptr)
+ {
+ // buffer data have been changed. Buffer data may out of sync
+ // give up the old TexStorage, create a new one.
+ // this may not efficient, since staging buffer may be patially updated.
+ ANGLE_TRY(setBuffer(context, mInternalFormat));
+ }
+ return angle::Result::Continue;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/TextureD3D.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/TextureD3D.h
new file mode 100644
index 0000000000..a87806b3e7
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/TextureD3D.h
@@ -0,0 +1,1050 @@
+//
+// 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.
+//
+
+// TextureD3D.h: Implementations of the Texture interfaces shared betweeen the D3D backends.
+
+#ifndef LIBANGLE_RENDERER_D3D_TEXTURED3D_H_
+#define LIBANGLE_RENDERER_D3D_TEXTURED3D_H_
+
+#include "common/Color.h"
+#include "libANGLE/Constants.h"
+#include "libANGLE/Stream.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/renderer/TextureImpl.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
+#include "libANGLE/renderer/d3d/TextureStorage.h"
+
+namespace gl
+{
+class Framebuffer;
+}
+
+namespace rx
+{
+class EGLImageD3D;
+class ImageD3D;
+class RendererD3D;
+class RenderTargetD3D;
+class TextureStorage;
+
+class TextureD3D : public TextureImpl, public angle::ObserverInterface
+{
+ public:
+ TextureD3D(const gl::TextureState &data, RendererD3D *renderer);
+ ~TextureD3D() override;
+
+ void onDestroy(const gl::Context *context) override;
+
+ angle::Result getNativeTexture(const gl::Context *context, TextureStorage **outStorage);
+
+ bool hasDirtyImages() const { return mDirtyImages; }
+ void resetDirty() { mDirtyImages = false; }
+
+ virtual ImageD3D *getImage(const gl::ImageIndex &index) const = 0;
+ virtual GLsizei getLayerCount(int level) const = 0;
+
+ angle::Result getImageAndSyncFromStorage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ ImageD3D **outImage);
+
+ GLint getBaseLevelWidth() const;
+ GLint getBaseLevelHeight() const;
+ GLenum getBaseLevelInternalFormat() const;
+
+ angle::Result setStorage(const gl::Context *context,
+ gl::TextureType type,
+ size_t levels,
+ GLenum internalFormat,
+ const gl::Extents &size) override;
+
+ angle::Result setStorageMultisample(const gl::Context *context,
+ gl::TextureType type,
+ GLsizei samples,
+ GLint internalformat,
+ const gl::Extents &size,
+ bool fixedSampleLocations) override;
+
+ angle::Result setBuffer(const gl::Context *context, GLenum internalFormat) override;
+
+ angle::Result setStorageExternalMemory(const gl::Context *context,
+ gl::TextureType type,
+ size_t levels,
+ GLenum internalFormat,
+ const gl::Extents &size,
+ gl::MemoryObject *memoryObject,
+ GLuint64 offset,
+ GLbitfield createFlags,
+ GLbitfield usageFlags,
+ const void *imageCreateInfoPNext) override;
+
+ bool isImmutable() const { return mImmutable; }
+
+ virtual angle::Result getRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) = 0;
+
+ // Returns an iterator over all "Images" for this particular Texture.
+ virtual gl::ImageIndexIterator imageIterator() const = 0;
+
+ // Returns an ImageIndex for a particular "Image". 3D Textures do not have images for
+ // slices of their depth texures, so 3D textures ignore the layer parameter.
+ virtual gl::ImageIndex getImageIndex(GLint mip, GLint layer) const = 0;
+ virtual bool isValidIndex(const gl::ImageIndex &index) const = 0;
+
+ angle::Result setImageExternal(const gl::Context *context,
+ gl::TextureType type,
+ egl::Stream *stream,
+ const egl::Stream::GLTextureDescription &desc) override;
+ angle::Result generateMipmap(const gl::Context *context) override;
+ bool hasStorage() const { return mTexStorage != nullptr; }
+ TextureStorage *getStorage();
+ ImageD3D *getBaseLevelImage() const;
+
+ angle::Result getAttachmentRenderTarget(const gl::Context *context,
+ GLenum binding,
+ const gl::ImageIndex &imageIndex,
+ GLsizei samples,
+ FramebufferAttachmentRenderTarget **rtOut) override;
+
+ angle::Result setBaseLevel(const gl::Context *context, GLuint baseLevel) override;
+
+ angle::Result syncState(const gl::Context *context,
+ const gl::Texture::DirtyBits &dirtyBits,
+ gl::Command source) override;
+
+ angle::Result initializeContents(const gl::Context *context,
+ GLenum binding,
+ const gl::ImageIndex &imageIndex) override;
+
+ GLsizei getRenderToTextureSamples();
+
+ angle::Result ensureUnorderedAccess(const gl::Context *context);
+ angle::Result onLabelUpdate(const gl::Context *context) override;
+
+ // ObserverInterface implementation.
+ void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override;
+
+ protected:
+ angle::Result setImageImpl(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLenum type,
+ const gl::PixelUnpackState &unpack,
+ gl::Buffer *unpackBuffer,
+ const uint8_t *pixels,
+ ptrdiff_t layerOffset);
+ angle::Result subImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Box &area,
+ GLenum format,
+ GLenum type,
+ const gl::PixelUnpackState &unpack,
+ gl::Buffer *unpackBuffer,
+ const uint8_t *pixels,
+ ptrdiff_t layerOffset);
+ angle::Result setCompressedImageImpl(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::PixelUnpackState &unpack,
+ const uint8_t *pixels,
+ ptrdiff_t layerOffset);
+ angle::Result subImageCompressed(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Box &area,
+ GLenum format,
+ const gl::PixelUnpackState &unpack,
+ const uint8_t *pixels,
+ ptrdiff_t layerOffset);
+ bool isFastUnpackable(const gl::Buffer *unpackBuffer,
+ const gl::PixelUnpackState &unpack,
+ GLenum sizedInternalFormat);
+ angle::Result fastUnpackPixels(const gl::Context *context,
+ const gl::PixelUnpackState &unpack,
+ gl::Buffer *unpackBuffer,
+ const uint8_t *pixels,
+ const gl::Box &destArea,
+ GLenum sizedInternalFormat,
+ GLenum type,
+ RenderTargetD3D *destRenderTarget);
+
+ GLint getLevelZeroWidth() const;
+ GLint getLevelZeroHeight() const;
+ virtual GLint getLevelZeroDepth() const;
+
+ GLint creationLevels(GLsizei width, GLsizei height, GLsizei depth) const;
+ virtual angle::Result initMipmapImages(const gl::Context *context) = 0;
+ bool isBaseImageZeroSize() const;
+ virtual bool isImageComplete(const gl::ImageIndex &index) const = 0;
+
+ bool canCreateRenderTargetForImage(const gl::ImageIndex &index) const;
+ angle::Result ensureBindFlags(const gl::Context *context, BindFlags bindFlags);
+ angle::Result ensureRenderTarget(const gl::Context *context);
+
+ virtual angle::Result createCompleteStorage(const gl::Context *context,
+ BindFlags bindFlags,
+ TexStoragePointer *outTexStorage) const = 0;
+ virtual angle::Result setCompleteTexStorage(const gl::Context *context,
+ TextureStorage *newCompleteTexStorage) = 0;
+ angle::Result commitRegion(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Box &region);
+
+ angle::Result releaseTexStorage(const gl::Context *context,
+ const gl::TexLevelMask &copyStorageToImagesMask);
+
+ GLuint getBaseLevel() const { return mBaseLevel; }
+
+ virtual void markAllImagesDirty() = 0;
+
+ GLint getBaseLevelDepth() const;
+
+ RendererD3D *mRenderer;
+
+ bool mDirtyImages;
+
+ bool mImmutable;
+ TextureStorage *mTexStorage;
+ angle::ObserverBinding mTexStorageObserverBinding;
+
+ private:
+ virtual angle::Result initializeStorage(const gl::Context *context, BindFlags bindFlags) = 0;
+
+ virtual angle::Result updateStorage(const gl::Context *context) = 0;
+
+ bool couldUseSetData() const;
+ bool shouldUseSetData(const ImageD3D *image) const;
+
+ angle::Result generateMipmapUsingImages(const gl::Context *context, const GLuint maxLevel);
+
+ GLuint mBaseLevel;
+};
+
+class TextureD3D_2D : public TextureD3D
+{
+ public:
+ TextureD3D_2D(const gl::TextureState &data, RendererD3D *renderer);
+ ~TextureD3D_2D() override;
+
+ void onDestroy(const gl::Context *context) override;
+
+ ImageD3D *getImage(int level, int layer) const;
+ ImageD3D *getImage(const gl::ImageIndex &index) const override;
+ GLsizei getLayerCount(int level) const override;
+
+ GLsizei getWidth(GLint level) const;
+ GLsizei getHeight(GLint level) const;
+ GLenum getInternalFormat(GLint level) const;
+ bool isDepth(GLint level) const;
+ bool isSRGB(GLint level) const;
+
+ angle::Result setImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLenum internalFormat,
+ const gl::Extents &size,
+ GLenum format,
+ GLenum type,
+ const gl::PixelUnpackState &unpack,
+ gl::Buffer *unpackBuffer,
+ const uint8_t *pixels) override;
+ angle::Result setSubImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Box &area,
+ GLenum format,
+ GLenum type,
+ const gl::PixelUnpackState &unpack,
+ gl::Buffer *unpackBuffer,
+ const uint8_t *pixels) override;
+
+ angle::Result setCompressedImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLenum internalFormat,
+ const gl::Extents &size,
+ const gl::PixelUnpackState &unpack,
+ size_t imageSize,
+ const uint8_t *pixels) override;
+ angle::Result setCompressedSubImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Box &area,
+ GLenum format,
+ const gl::PixelUnpackState &unpack,
+ size_t imageSize,
+ const uint8_t *pixels) override;
+
+ angle::Result copyImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Rectangle &sourceArea,
+ GLenum internalFormat,
+ gl::Framebuffer *source) override;
+ angle::Result copySubImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Offset &destOffset,
+ const gl::Rectangle &sourceArea,
+ gl::Framebuffer *source) override;
+
+ angle::Result copyTexture(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLenum internalFormat,
+ GLenum type,
+ GLint sourceLevel,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha,
+ const gl::Texture *source) override;
+ angle::Result copySubTexture(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Offset &destOffset,
+ GLint sourceLevel,
+ const gl::Box &sourceBox,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha,
+ const gl::Texture *source) override;
+ angle::Result copyCompressedTexture(const gl::Context *context,
+ const gl::Texture *source) override;
+
+ angle::Result setStorage(const gl::Context *context,
+ gl::TextureType type,
+ size_t levels,
+ GLenum internalFormat,
+ const gl::Extents &size) override;
+
+ angle::Result bindTexImage(const gl::Context *context, egl::Surface *surface) override;
+ angle::Result releaseTexImage(const gl::Context *context) override;
+
+ angle::Result setEGLImageTarget(const gl::Context *context,
+ gl::TextureType type,
+ egl::Image *image) override;
+
+ angle::Result getRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) override;
+
+ gl::ImageIndexIterator imageIterator() const override;
+ gl::ImageIndex getImageIndex(GLint mip, GLint layer) const override;
+ bool isValidIndex(const gl::ImageIndex &index) const override;
+
+ protected:
+ void markAllImagesDirty() override;
+
+ private:
+ angle::Result initializeStorage(const gl::Context *context, BindFlags bindFlags) override;
+ angle::Result createCompleteStorage(const gl::Context *context,
+ BindFlags bindFlags,
+ TexStoragePointer *outTexStorage) const override;
+ angle::Result setCompleteTexStorage(const gl::Context *context,
+ TextureStorage *newCompleteTexStorage) override;
+
+ angle::Result updateStorage(const gl::Context *context) override;
+ angle::Result initMipmapImages(const gl::Context *context) override;
+
+ bool isValidLevel(int level) const;
+ bool isLevelComplete(int level) const;
+ bool isImageComplete(const gl::ImageIndex &index) const override;
+
+ angle::Result updateStorageLevel(const gl::Context *context, int level);
+
+ angle::Result redefineImage(const gl::Context *context,
+ size_t level,
+ GLenum internalformat,
+ const gl::Extents &size,
+ bool forceRelease);
+
+ bool mEGLImageTarget;
+ gl::TexLevelArray<std::unique_ptr<ImageD3D>> mImageArray;
+};
+
+class TextureD3D_Cube : public TextureD3D
+{
+ public:
+ TextureD3D_Cube(const gl::TextureState &data, RendererD3D *renderer);
+ ~TextureD3D_Cube() override;
+
+ void onDestroy(const gl::Context *context) override;
+
+ ImageD3D *getImage(int level, int layer) const;
+ ImageD3D *getImage(const gl::ImageIndex &index) const override;
+ GLsizei getLayerCount(int level) const override;
+
+ GLenum getInternalFormat(GLint level, GLint layer) const;
+ bool isDepth(GLint level, GLint layer) const;
+ bool isSRGB(GLint level, GLint layer) const;
+
+ angle::Result setImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLenum internalFormat,
+ const gl::Extents &size,
+ GLenum format,
+ GLenum type,
+ const gl::PixelUnpackState &unpack,
+ gl::Buffer *unpackBuffer,
+ const uint8_t *pixels) override;
+ angle::Result setSubImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Box &area,
+ GLenum format,
+ GLenum type,
+ const gl::PixelUnpackState &unpack,
+ gl::Buffer *unpackBuffer,
+ const uint8_t *pixels) override;
+
+ angle::Result setCompressedImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLenum internalFormat,
+ const gl::Extents &size,
+ const gl::PixelUnpackState &unpack,
+ size_t imageSize,
+ const uint8_t *pixels) override;
+ angle::Result setCompressedSubImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Box &area,
+ GLenum format,
+ const gl::PixelUnpackState &unpack,
+ size_t imageSize,
+ const uint8_t *pixels) override;
+
+ angle::Result copyImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Rectangle &sourceArea,
+ GLenum internalFormat,
+ gl::Framebuffer *source) override;
+ angle::Result copySubImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Offset &destOffset,
+ const gl::Rectangle &sourceArea,
+ gl::Framebuffer *source) override;
+
+ angle::Result copyTexture(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLenum internalFormat,
+ GLenum type,
+ GLint sourceLevel,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha,
+ const gl::Texture *source) override;
+ angle::Result copySubTexture(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Offset &destOffset,
+ GLint sourceLevel,
+ const gl::Box &sourceBox,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha,
+ const gl::Texture *source) override;
+
+ angle::Result setStorage(const gl::Context *context,
+ gl::TextureType type,
+ size_t levels,
+ GLenum internalFormat,
+ const gl::Extents &size) override;
+
+ angle::Result bindTexImage(const gl::Context *context, egl::Surface *surface) override;
+ angle::Result releaseTexImage(const gl::Context *context) override;
+
+ angle::Result setEGLImageTarget(const gl::Context *context,
+ gl::TextureType type,
+ egl::Image *image) override;
+
+ angle::Result getRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) override;
+
+ gl::ImageIndexIterator imageIterator() const override;
+ gl::ImageIndex getImageIndex(GLint mip, GLint layer) const override;
+ bool isValidIndex(const gl::ImageIndex &index) const override;
+
+ protected:
+ void markAllImagesDirty() override;
+
+ private:
+ angle::Result initializeStorage(const gl::Context *context, BindFlags bindFlags) override;
+ angle::Result createCompleteStorage(const gl::Context *context,
+ BindFlags bindFlags,
+ TexStoragePointer *outTexStorage) const override;
+ angle::Result setCompleteTexStorage(const gl::Context *context,
+ TextureStorage *newCompleteTexStorage) override;
+
+ angle::Result updateStorage(const gl::Context *context) override;
+ angle::Result initMipmapImages(const gl::Context *context) override;
+
+ bool isValidFaceLevel(int faceIndex, int level) const;
+ bool isFaceLevelComplete(int faceIndex, int level) const;
+ bool isCubeComplete() const;
+ bool isImageComplete(const gl::ImageIndex &index) const override;
+ angle::Result updateStorageFaceLevel(const gl::Context *context, int faceIndex, int level);
+
+ angle::Result redefineImage(const gl::Context *context,
+ int faceIndex,
+ GLint level,
+ GLenum internalformat,
+ const gl::Extents &size,
+ bool forceRelease);
+
+ std::array<gl::TexLevelArray<std::unique_ptr<ImageD3D>>, 6> mImageArray;
+};
+
+class TextureD3D_3D : public TextureD3D
+{
+ public:
+ TextureD3D_3D(const gl::TextureState &data, RendererD3D *renderer);
+ ~TextureD3D_3D() override;
+
+ void onDestroy(const gl::Context *context) override;
+
+ ImageD3D *getImage(int level, int layer) const;
+ ImageD3D *getImage(const gl::ImageIndex &index) const override;
+ GLsizei getLayerCount(int level) const override;
+
+ GLsizei getWidth(GLint level) const;
+ GLsizei getHeight(GLint level) const;
+ GLsizei getDepth(GLint level) const;
+ GLenum getInternalFormat(GLint level) const;
+ bool isDepth(GLint level) const;
+ bool isSRGB(GLint level) const;
+
+ angle::Result setImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLenum internalFormat,
+ const gl::Extents &size,
+ GLenum format,
+ GLenum type,
+ const gl::PixelUnpackState &unpack,
+ gl::Buffer *unpackBuffer,
+ const uint8_t *pixels) override;
+ angle::Result setSubImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Box &area,
+ GLenum format,
+ GLenum type,
+ const gl::PixelUnpackState &unpack,
+ gl::Buffer *unpackBuffer,
+ const uint8_t *pixels) override;
+
+ angle::Result setCompressedImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLenum internalFormat,
+ const gl::Extents &size,
+ const gl::PixelUnpackState &unpack,
+ size_t imageSize,
+ const uint8_t *pixels) override;
+ angle::Result setCompressedSubImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Box &area,
+ GLenum format,
+ const gl::PixelUnpackState &unpack,
+ size_t imageSize,
+ const uint8_t *pixels) override;
+
+ angle::Result copyImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Rectangle &sourceArea,
+ GLenum internalFormat,
+ gl::Framebuffer *source) override;
+ angle::Result copySubImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Offset &destOffset,
+ const gl::Rectangle &sourceArea,
+ gl::Framebuffer *source) override;
+
+ angle::Result copyTexture(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLenum internalFormat,
+ GLenum type,
+ GLint sourceLevel,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha,
+ const gl::Texture *source) override;
+ angle::Result copySubTexture(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Offset &destOffset,
+ GLint sourceLevel,
+ const gl::Box &sourceBox,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha,
+ const gl::Texture *source) override;
+
+ angle::Result setStorage(const gl::Context *context,
+ gl::TextureType type,
+ size_t levels,
+ GLenum internalFormat,
+ const gl::Extents &size) override;
+
+ angle::Result bindTexImage(const gl::Context *context, egl::Surface *surface) override;
+ angle::Result releaseTexImage(const gl::Context *context) override;
+
+ angle::Result setEGLImageTarget(const gl::Context *context,
+ gl::TextureType type,
+ egl::Image *image) override;
+
+ angle::Result getRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) override;
+
+ gl::ImageIndexIterator imageIterator() const override;
+ gl::ImageIndex getImageIndex(GLint mip, GLint layer) const override;
+ bool isValidIndex(const gl::ImageIndex &index) const override;
+
+ protected:
+ void markAllImagesDirty() override;
+ GLint getLevelZeroDepth() const override;
+
+ private:
+ angle::Result initializeStorage(const gl::Context *context, BindFlags bindFlags) override;
+ angle::Result createCompleteStorage(const gl::Context *context,
+ BindFlags bindFlags,
+ TexStoragePointer *outStorage) const override;
+ angle::Result setCompleteTexStorage(const gl::Context *context,
+ TextureStorage *newCompleteTexStorage) override;
+
+ angle::Result updateStorage(const gl::Context *context) override;
+ angle::Result initMipmapImages(const gl::Context *context) override;
+
+ bool isValidLevel(int level) const;
+ bool isLevelComplete(int level) const;
+ bool isImageComplete(const gl::ImageIndex &index) const override;
+ angle::Result updateStorageLevel(const gl::Context *context, int level);
+
+ angle::Result redefineImage(const gl::Context *context,
+ GLint level,
+ GLenum internalformat,
+ const gl::Extents &size,
+ bool forceRelease);
+
+ gl::TexLevelArray<std::unique_ptr<ImageD3D>> mImageArray;
+};
+
+class TextureD3D_2DArray : public TextureD3D
+{
+ public:
+ TextureD3D_2DArray(const gl::TextureState &data, RendererD3D *renderer);
+ ~TextureD3D_2DArray() override;
+
+ void onDestroy(const gl::Context *context) override;
+
+ virtual ImageD3D *getImage(int level, int layer) const;
+ ImageD3D *getImage(const gl::ImageIndex &index) const override;
+ GLsizei getLayerCount(int level) const override;
+
+ GLsizei getWidth(GLint level) const;
+ GLsizei getHeight(GLint level) const;
+ GLenum getInternalFormat(GLint level) const;
+ bool isDepth(GLint level) const;
+
+ angle::Result setImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLenum internalFormat,
+ const gl::Extents &size,
+ GLenum format,
+ GLenum type,
+ const gl::PixelUnpackState &unpack,
+ gl::Buffer *unpackBuffer,
+ const uint8_t *pixels) override;
+ angle::Result setSubImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Box &area,
+ GLenum format,
+ GLenum type,
+ const gl::PixelUnpackState &unpack,
+ gl::Buffer *unpackBuffer,
+ const uint8_t *pixels) override;
+
+ angle::Result setCompressedImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLenum internalFormat,
+ const gl::Extents &size,
+ const gl::PixelUnpackState &unpack,
+ size_t imageSize,
+ const uint8_t *pixels) override;
+ angle::Result setCompressedSubImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Box &area,
+ GLenum format,
+ const gl::PixelUnpackState &unpack,
+ size_t imageSize,
+ const uint8_t *pixels) override;
+
+ angle::Result copyImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Rectangle &sourceArea,
+ GLenum internalFormat,
+ gl::Framebuffer *source) override;
+ angle::Result copySubImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Offset &destOffset,
+ const gl::Rectangle &sourceArea,
+ gl::Framebuffer *source) override;
+
+ angle::Result copyTexture(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLenum internalFormat,
+ GLenum type,
+ GLint sourceLevel,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha,
+ const gl::Texture *source) override;
+ angle::Result copySubTexture(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Offset &destOffset,
+ GLint sourceLevel,
+ const gl::Box &sourceBox,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha,
+ const gl::Texture *source) override;
+
+ angle::Result setStorage(const gl::Context *context,
+ gl::TextureType type,
+ size_t levels,
+ GLenum internalFormat,
+ const gl::Extents &size) override;
+
+ angle::Result bindTexImage(const gl::Context *context, egl::Surface *surface) override;
+ angle::Result releaseTexImage(const gl::Context *context) override;
+
+ angle::Result setEGLImageTarget(const gl::Context *context,
+ gl::TextureType type,
+ egl::Image *image) override;
+
+ angle::Result getRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) override;
+
+ gl::ImageIndexIterator imageIterator() const override;
+ gl::ImageIndex getImageIndex(GLint mip, GLint layer) const override;
+ bool isValidIndex(const gl::ImageIndex &index) const override;
+
+ protected:
+ void markAllImagesDirty() override;
+
+ private:
+ angle::Result initializeStorage(const gl::Context *context, BindFlags bindFlags) override;
+ angle::Result createCompleteStorage(const gl::Context *context,
+ BindFlags bindFlags,
+ TexStoragePointer *outStorage) const override;
+ angle::Result setCompleteTexStorage(const gl::Context *context,
+ TextureStorage *newCompleteTexStorage) override;
+
+ angle::Result updateStorage(const gl::Context *context) override;
+ angle::Result initMipmapImages(const gl::Context *context) override;
+
+ bool isValidLevel(int level) const;
+ bool isLevelComplete(int level) const;
+ bool isImageComplete(const gl::ImageIndex &index) const override;
+ bool isSRGB(GLint level) const;
+ angle::Result updateStorageLevel(const gl::Context *context, int level);
+
+ void deleteImages();
+ angle::Result redefineImage(const gl::Context *context,
+ GLint level,
+ GLenum internalformat,
+ const gl::Extents &size,
+ bool forceRelease);
+
+ // Storing images as an array of single depth textures since D3D11 treats each array level of a
+ // Texture2D object as a separate subresource. Each layer would have to be looped over
+ // to update all the texture layers since they cannot all be updated at once and it makes the
+ // most sense for the Image class to not have to worry about layer subresource as well as mip
+ // subresources.
+ GLsizei mLayerCounts[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
+ ImageD3D **mImageArray[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
+};
+
+// Base class for immutable textures. These don't support manipulation of individual texture images.
+class TextureD3DImmutableBase : public TextureD3D
+{
+ public:
+ TextureD3DImmutableBase(const gl::TextureState &data, RendererD3D *renderer);
+ ~TextureD3DImmutableBase() override;
+
+ ImageD3D *getImage(const gl::ImageIndex &index) const override;
+ angle::Result setImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLenum internalFormat,
+ const gl::Extents &size,
+ GLenum format,
+ GLenum type,
+ const gl::PixelUnpackState &unpack,
+ gl::Buffer *unpackBuffer,
+ const uint8_t *pixels) override;
+ angle::Result setSubImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Box &area,
+ GLenum format,
+ GLenum type,
+ const gl::PixelUnpackState &unpack,
+ gl::Buffer *unpackBuffer,
+ const uint8_t *pixels) override;
+
+ angle::Result setCompressedImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLenum internalFormat,
+ const gl::Extents &size,
+ const gl::PixelUnpackState &unpack,
+ size_t imageSize,
+ const uint8_t *pixels) override;
+ angle::Result setCompressedSubImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Box &area,
+ GLenum format,
+ const gl::PixelUnpackState &unpack,
+ size_t imageSize,
+ const uint8_t *pixels) override;
+
+ angle::Result copyImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Rectangle &sourceArea,
+ GLenum internalFormat,
+ gl::Framebuffer *source) override;
+ angle::Result copySubImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Offset &destOffset,
+ const gl::Rectangle &sourceArea,
+ gl::Framebuffer *source) override;
+
+ angle::Result bindTexImage(const gl::Context *context, egl::Surface *surface) override;
+ angle::Result releaseTexImage(const gl::Context *context) override;
+};
+
+class TextureD3D_External : public TextureD3DImmutableBase
+{
+ public:
+ TextureD3D_External(const gl::TextureState &data, RendererD3D *renderer);
+ ~TextureD3D_External() override;
+
+ GLsizei getLayerCount(int level) const override;
+
+ angle::Result setImageExternal(const gl::Context *context,
+ gl::TextureType type,
+ egl::Stream *stream,
+ const egl::Stream::GLTextureDescription &desc) override;
+
+ angle::Result setEGLImageTarget(const gl::Context *context,
+ gl::TextureType type,
+ egl::Image *image) override;
+
+ angle::Result getRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) override;
+
+ gl::ImageIndexIterator imageIterator() const override;
+ gl::ImageIndex getImageIndex(GLint mip, GLint layer) const override;
+ bool isValidIndex(const gl::ImageIndex &index) const override;
+
+ protected:
+ void markAllImagesDirty() override;
+
+ private:
+ angle::Result initializeStorage(const gl::Context *context, BindFlags bindFlags) override;
+ angle::Result createCompleteStorage(const gl::Context *context,
+ BindFlags bindFlags,
+ TexStoragePointer *outTexStorage) const override;
+ angle::Result setCompleteTexStorage(const gl::Context *context,
+ TextureStorage *newCompleteTexStorage) override;
+
+ angle::Result updateStorage(const gl::Context *context) override;
+ angle::Result initMipmapImages(const gl::Context *context) override;
+
+ bool isImageComplete(const gl::ImageIndex &index) const override;
+};
+
+class TextureD3D_2DMultisample : public TextureD3DImmutableBase
+{
+ public:
+ TextureD3D_2DMultisample(const gl::TextureState &data, RendererD3D *renderer);
+ ~TextureD3D_2DMultisample() override;
+
+ angle::Result setStorageMultisample(const gl::Context *context,
+ gl::TextureType type,
+ GLsizei samples,
+ GLint internalformat,
+ const gl::Extents &size,
+ bool fixedSampleLocations) override;
+
+ angle::Result setEGLImageTarget(const gl::Context *context,
+ gl::TextureType type,
+ egl::Image *image) override;
+
+ angle::Result getRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) override;
+
+ gl::ImageIndexIterator imageIterator() const override;
+ gl::ImageIndex getImageIndex(GLint mip, GLint layer) const override;
+ bool isValidIndex(const gl::ImageIndex &index) const override;
+
+ GLsizei getLayerCount(int level) const override;
+
+ protected:
+ void markAllImagesDirty() override;
+
+ angle::Result setCompleteTexStorage(const gl::Context *context,
+ TextureStorage *newCompleteTexStorage) override;
+
+ angle::Result updateStorage(const gl::Context *context) override;
+
+ private:
+ angle::Result initializeStorage(const gl::Context *context, BindFlags bindFlags) override;
+ angle::Result createCompleteStorage(const gl::Context *context,
+ BindFlags bindFlags,
+ TexStoragePointer *outTexStorage) const override;
+ angle::Result initMipmapImages(const gl::Context *context) override;
+
+ bool isImageComplete(const gl::ImageIndex &index) const override;
+};
+
+class TextureD3D_2DMultisampleArray : public TextureD3DImmutableBase
+{
+ public:
+ TextureD3D_2DMultisampleArray(const gl::TextureState &data, RendererD3D *renderer);
+ ~TextureD3D_2DMultisampleArray() override;
+
+ angle::Result setStorageMultisample(const gl::Context *context,
+ gl::TextureType type,
+ GLsizei samples,
+ GLint internalformat,
+ const gl::Extents &size,
+ bool fixedSampleLocations) override;
+
+ angle::Result setEGLImageTarget(const gl::Context *context,
+ gl::TextureType type,
+ egl::Image *image) override;
+
+ angle::Result getRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) override;
+
+ gl::ImageIndexIterator imageIterator() const override;
+ gl::ImageIndex getImageIndex(GLint mip, GLint layer) const override;
+ bool isValidIndex(const gl::ImageIndex &index) const override;
+
+ GLsizei getLayerCount(int level) const override;
+
+ protected:
+ void markAllImagesDirty() override;
+
+ angle::Result setCompleteTexStorage(const gl::Context *context,
+ TextureStorage *newCompleteTexStorage) override;
+
+ angle::Result updateStorage(const gl::Context *context) override;
+
+ private:
+ angle::Result initializeStorage(const gl::Context *context, BindFlags bindFlags) override;
+ angle::Result createCompleteStorage(const gl::Context *context,
+ BindFlags bindFlags,
+ TexStoragePointer *outTexStorage) const override;
+ angle::Result initMipmapImages(const gl::Context *context) override;
+
+ bool isImageComplete(const gl::ImageIndex &index) const override;
+
+ GLsizei mLayerCount;
+};
+
+class TextureD3D_Buffer : public TextureD3D
+{
+ public:
+ TextureD3D_Buffer(const gl::TextureState &data, RendererD3D *renderer);
+ ~TextureD3D_Buffer() override;
+
+ ImageD3D *getImage(const gl::ImageIndex &index) const override;
+
+ angle::Result setBuffer(const gl::Context *context, GLenum internalFormat) override;
+
+ angle::Result setImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLenum internalFormat,
+ const gl::Extents &size,
+ GLenum format,
+ GLenum type,
+ const gl::PixelUnpackState &unpack,
+ gl::Buffer *unpackBuffer,
+ const uint8_t *pixels) override;
+ angle::Result setSubImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Box &area,
+ GLenum format,
+ GLenum type,
+ const gl::PixelUnpackState &unpack,
+ gl::Buffer *unpackBuffer,
+ const uint8_t *pixels) override;
+
+ angle::Result setCompressedImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLenum internalFormat,
+ const gl::Extents &size,
+ const gl::PixelUnpackState &unpack,
+ size_t imageSize,
+ const uint8_t *pixels) override;
+ angle::Result setCompressedSubImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Box &area,
+ GLenum format,
+ const gl::PixelUnpackState &unpack,
+ size_t imageSize,
+ const uint8_t *pixels) override;
+
+ angle::Result copyImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Rectangle &sourceArea,
+ GLenum internalFormat,
+ gl::Framebuffer *source) override;
+ angle::Result copySubImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ const gl::Offset &destOffset,
+ const gl::Rectangle &sourceArea,
+ gl::Framebuffer *source) override;
+
+ angle::Result bindTexImage(const gl::Context *context, egl::Surface *surface) override;
+ angle::Result releaseTexImage(const gl::Context *context) override;
+
+ angle::Result setEGLImageTarget(const gl::Context *context,
+ gl::TextureType type,
+ egl::Image *image) override;
+
+ angle::Result getRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) override;
+
+ GLsizei getLayerCount(int level) const override;
+
+ angle::Result syncState(const gl::Context *context,
+ const gl::Texture::DirtyBits &dirtyBits,
+ gl::Command source) override;
+
+ gl::ImageIndexIterator imageIterator() const override;
+ gl::ImageIndex getImageIndex(GLint mip, GLint layer) const override;
+ bool isValidIndex(const gl::ImageIndex &index) const override;
+
+ protected:
+ void markAllImagesDirty() override;
+
+ private:
+ angle::Result initializeStorage(const gl::Context *context, BindFlags bindFlags) override;
+ angle::Result createCompleteStorage(const gl::Context *context,
+ BindFlags bindFlags,
+ TexStoragePointer *outTexStorage) const override;
+ angle::Result setCompleteTexStorage(const gl::Context *context,
+ TextureStorage *newCompleteTexStorage) override;
+
+ angle::Result updateStorage(const gl::Context *context) override;
+ angle::Result initMipmapImages(const gl::Context *context) override;
+
+ bool isImageComplete(const gl::ImageIndex &index) const override;
+
+ GLenum mInternalFormat;
+};
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_TEXTURED3D_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/TextureStorage.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/TextureStorage.h
new file mode 100644
index 0000000000..fc073f8b5a
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/TextureStorage.h
@@ -0,0 +1,135 @@
+//
+// Copyright 2002 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.
+//
+
+// TextureStorage.h: Defines the abstract rx::TextureStorage class.
+
+#ifndef LIBANGLE_RENDERER_D3D_TEXTURESTORAGE_H_
+#define LIBANGLE_RENDERER_D3D_TEXTURESTORAGE_H_
+
+#include "common/debug.h"
+#include "libANGLE/angletypes.h"
+
+#include <GLES2/gl2.h>
+#include <stdint.h>
+
+namespace gl
+{
+class Context;
+class ImageIndex;
+struct Box;
+struct PixelUnpackState;
+} // namespace gl
+
+namespace angle
+{
+class Subject;
+} // namespace angle
+
+namespace rx
+{
+class SwapChainD3D;
+class RenderTargetD3D;
+class ImageD3D;
+
+// Dirty bit messages from TextureStorage
+constexpr size_t kTextureStorageObserverMessageIndex = 0;
+
+class TextureStorage : public angle::Subject
+{
+ public:
+ TextureStorage(const std::string &label) : mKHRDebugLabel(label) {}
+ ~TextureStorage() override {}
+
+ virtual angle::Result onDestroy(const gl::Context *context);
+
+ virtual int getTopLevel() const = 0;
+ virtual bool isRenderTarget() const = 0;
+ virtual bool isUnorderedAccess() const = 0;
+ virtual bool isManaged() const = 0;
+ virtual bool supportsNativeMipmapFunction() const = 0;
+ virtual int getLevelCount() const = 0;
+
+ virtual angle::Result findRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) const = 0;
+ virtual angle::Result getRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) = 0;
+ virtual angle::Result generateMipmap(const gl::Context *context,
+ const gl::ImageIndex &sourceIndex,
+ const gl::ImageIndex &destIndex) = 0;
+
+ virtual angle::Result copyToStorage(const gl::Context *context,
+ TextureStorage *destStorage) = 0;
+ virtual angle::Result setData(const gl::Context *context,
+ const gl::ImageIndex &index,
+ ImageD3D *image,
+ const gl::Box *destBox,
+ GLenum type,
+ const gl::PixelUnpackState &unpack,
+ const uint8_t *pixelData) = 0;
+
+ // This is a no-op for most implementations of TextureStorage. Some (e.g. TextureStorage11_2D)
+ // might override it.
+ virtual angle::Result useLevelZeroWorkaroundTexture(const gl::Context *context,
+ bool useLevelZeroTexture);
+
+ virtual void invalidateTextures() {}
+
+ // RenderToTexture methods
+ virtual angle::Result releaseMultisampledTexStorageForLevel(size_t level);
+ virtual angle::Result resolveTexture(const gl::Context *context);
+ virtual GLsizei getRenderToTextureSamples() const;
+
+ // Called by outer object when label has changed via KHR_debug extension
+ void setLabel(const std::string &newLabel);
+
+ protected:
+ virtual void onLabelUpdate() {}
+
+ const angle::Subject *mSubject;
+ std::string mKHRDebugLabel;
+};
+
+inline angle::Result TextureStorage::onDestroy(const gl::Context *context)
+{
+ return angle::Result::Continue;
+}
+
+inline angle::Result TextureStorage::useLevelZeroWorkaroundTexture(const gl::Context *context,
+ bool useLevelZeroTexture)
+{
+ return angle::Result::Continue;
+}
+
+inline angle::Result TextureStorage::releaseMultisampledTexStorageForLevel(size_t level)
+{
+ return angle::Result::Continue;
+}
+
+inline angle::Result TextureStorage::resolveTexture(const gl::Context *context)
+{
+ return angle::Result::Continue;
+}
+
+inline GLsizei TextureStorage::getRenderToTextureSamples() const
+{
+ return 0;
+}
+
+inline void TextureStorage::setLabel(const std::string &newLabel)
+{
+ mKHRDebugLabel = newLabel;
+ onLabelUpdate();
+}
+
+using TexStoragePointer = angle::UniqueObjectPointer<TextureStorage, gl::Context>;
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_TEXTURESTORAGE_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexBuffer.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexBuffer.cpp
new file mode 100644
index 0000000000..acb27adfcc
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexBuffer.cpp
@@ -0,0 +1,308 @@
+//
+// Copyright 2002 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.
+//
+
+// VertexBuffer.cpp: Defines the abstract VertexBuffer class and VertexBufferInterface
+// class with derivations, classes that perform graphics API agnostic vertex buffer operations.
+
+#include "libANGLE/renderer/d3d/VertexBuffer.h"
+
+#include "common/mathutil.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/VertexAttribute.h"
+#include "libANGLE/renderer/d3d/BufferD3D.h"
+#include "libANGLE/renderer/d3d/ContextD3D.h"
+
+namespace rx
+{
+
+// VertexBuffer Implementation
+unsigned int VertexBuffer::mNextSerial = 1;
+
+VertexBuffer::VertexBuffer() : mRefCount(1)
+{
+ updateSerial();
+}
+
+VertexBuffer::~VertexBuffer() {}
+
+void VertexBuffer::updateSerial()
+{
+ mSerial = mNextSerial++;
+}
+
+unsigned int VertexBuffer::getSerial() const
+{
+ return mSerial;
+}
+
+void VertexBuffer::addRef()
+{
+ mRefCount++;
+}
+
+void VertexBuffer::release()
+{
+ ASSERT(mRefCount > 0);
+ mRefCount--;
+
+ if (mRefCount == 0)
+ {
+ delete this;
+ }
+}
+
+// VertexBufferInterface Implementation
+VertexBufferInterface::VertexBufferInterface(BufferFactoryD3D *factory, bool dynamic)
+ : mFactory(factory), mVertexBuffer(factory->createVertexBuffer()), mDynamic(dynamic)
+{}
+
+VertexBufferInterface::~VertexBufferInterface()
+{
+ if (mVertexBuffer)
+ {
+ mVertexBuffer->release();
+ mVertexBuffer = nullptr;
+ }
+}
+
+unsigned int VertexBufferInterface::getSerial() const
+{
+ ASSERT(mVertexBuffer);
+ return mVertexBuffer->getSerial();
+}
+
+unsigned int VertexBufferInterface::getBufferSize() const
+{
+ ASSERT(mVertexBuffer);
+ return mVertexBuffer->getBufferSize();
+}
+
+angle::Result VertexBufferInterface::setBufferSize(const gl::Context *context, unsigned int size)
+{
+ ASSERT(mVertexBuffer);
+ if (mVertexBuffer->getBufferSize() == 0)
+ {
+ return mVertexBuffer->initialize(context, size, mDynamic);
+ }
+
+ return mVertexBuffer->setBufferSize(context, size);
+}
+
+angle::Result VertexBufferInterface::getSpaceRequired(const gl::Context *context,
+ const gl::VertexAttribute &attrib,
+ const gl::VertexBinding &binding,
+ size_t count,
+ GLsizei instances,
+ GLuint baseInstance,
+ unsigned int *spaceInBytesOut) const
+{
+ unsigned int spaceRequired = 0;
+ ANGLE_TRY(mFactory->getVertexSpaceRequired(context, attrib, binding, count, instances,
+ baseInstance, &spaceRequired));
+
+ // Align to 16-byte boundary
+ unsigned int alignedSpaceRequired = roundUpPow2(spaceRequired, 16u);
+ ANGLE_CHECK_GL_ALLOC(GetImplAs<ContextD3D>(context), alignedSpaceRequired >= spaceRequired);
+
+ *spaceInBytesOut = alignedSpaceRequired;
+ return angle::Result::Continue;
+}
+
+angle::Result VertexBufferInterface::discard(const gl::Context *context)
+{
+ ASSERT(mVertexBuffer);
+ return mVertexBuffer->discard(context);
+}
+
+VertexBuffer *VertexBufferInterface::getVertexBuffer() const
+{
+ ASSERT(mVertexBuffer);
+ return mVertexBuffer;
+}
+
+// StreamingVertexBufferInterface Implementation
+StreamingVertexBufferInterface::StreamingVertexBufferInterface(BufferFactoryD3D *factory)
+ : VertexBufferInterface(factory, true), mWritePosition(0), mReservedSpace(0)
+{}
+
+angle::Result StreamingVertexBufferInterface::initialize(const gl::Context *context,
+ std::size_t initialSize)
+{
+ return setBufferSize(context, static_cast<unsigned int>(initialSize));
+}
+
+void StreamingVertexBufferInterface::reset()
+{
+ if (mVertexBuffer)
+ {
+ mVertexBuffer->release();
+ mVertexBuffer = mFactory->createVertexBuffer();
+ }
+}
+
+StreamingVertexBufferInterface::~StreamingVertexBufferInterface() {}
+
+angle::Result StreamingVertexBufferInterface::reserveSpace(const gl::Context *context,
+ unsigned int size)
+{
+ unsigned int curBufferSize = getBufferSize();
+ if (size > curBufferSize)
+ {
+ ANGLE_TRY(setBufferSize(context, std::max(size, 3 * curBufferSize / 2)));
+ mWritePosition = 0;
+ }
+ else if (mWritePosition + size > curBufferSize)
+ {
+ ANGLE_TRY(discard(context));
+ mWritePosition = 0;
+ }
+
+ mReservedSpace = size;
+ return angle::Result::Continue;
+}
+
+angle::Result StreamingVertexBufferInterface::storeDynamicAttribute(
+ const gl::Context *context,
+ const gl::VertexAttribute &attrib,
+ const gl::VertexBinding &binding,
+ gl::VertexAttribType currentValueType,
+ GLint start,
+ size_t count,
+ GLsizei instances,
+ GLuint baseInstance,
+ unsigned int *outStreamOffset,
+ const uint8_t *sourceData)
+{
+ unsigned int spaceRequired = 0;
+ ANGLE_TRY(
+ getSpaceRequired(context, attrib, binding, count, instances, baseInstance, &spaceRequired));
+
+ // Protect against integer overflow
+ angle::CheckedNumeric<unsigned int> checkedPosition(mWritePosition);
+ checkedPosition += spaceRequired;
+ ANGLE_CHECK_GL_ALLOC(GetImplAs<ContextD3D>(context), checkedPosition.IsValid());
+
+ mReservedSpace = 0;
+
+ size_t adjustedCount = count;
+ GLuint divisor = binding.getDivisor();
+
+ if (instances != 0 && divisor != 0)
+ {
+ // The attribute is an instanced attribute and it's an draw instance call
+ // Extra number of elements are copied at the beginning to make sure
+ // the driver is referencing the correct data with non-zero baseInstance
+ adjustedCount += UnsignedCeilDivide(baseInstance, divisor);
+ }
+
+ ANGLE_TRY(mVertexBuffer->storeVertexAttributes(context, attrib, binding, currentValueType,
+ start, adjustedCount, instances, mWritePosition,
+ sourceData));
+
+ if (outStreamOffset)
+ {
+ *outStreamOffset = mWritePosition;
+ }
+
+ mWritePosition += spaceRequired;
+
+ return angle::Result::Continue;
+}
+
+angle::Result StreamingVertexBufferInterface::reserveVertexSpace(const gl::Context *context,
+ const gl::VertexAttribute &attrib,
+ const gl::VertexBinding &binding,
+ size_t count,
+ GLsizei instances,
+ GLuint baseInstance)
+{
+ unsigned int requiredSpace = 0;
+ ANGLE_TRY(mFactory->getVertexSpaceRequired(context, attrib, binding, count, instances,
+ baseInstance, &requiredSpace));
+
+ // Align to 16-byte boundary
+ auto alignedRequiredSpace = rx::CheckedRoundUp(requiredSpace, 16u);
+ alignedRequiredSpace += mReservedSpace;
+
+ // Protect against integer overflow
+ ANGLE_CHECK_GL_ALLOC(GetImplAs<ContextD3D>(context), alignedRequiredSpace.IsValid());
+
+ ANGLE_TRY(reserveSpace(context, alignedRequiredSpace.ValueOrDie()));
+
+ return angle::Result::Continue;
+}
+
+// StaticVertexBufferInterface Implementation
+StaticVertexBufferInterface::AttributeSignature::AttributeSignature()
+ : formatID(angle::FormatID::NONE), stride(0), offset(0)
+{}
+
+bool StaticVertexBufferInterface::AttributeSignature::matchesAttribute(
+ const gl::VertexAttribute &attrib,
+ const gl::VertexBinding &binding) const
+{
+ size_t attribStride = ComputeVertexAttributeStride(attrib, binding);
+
+ if (formatID != attrib.format->id || static_cast<GLuint>(stride) != attribStride)
+ {
+ return false;
+ }
+
+ size_t attribOffset =
+ (static_cast<size_t>(ComputeVertexAttributeOffset(attrib, binding)) % attribStride);
+ return (offset == attribOffset);
+}
+
+void StaticVertexBufferInterface::AttributeSignature::set(const gl::VertexAttribute &attrib,
+ const gl::VertexBinding &binding)
+{
+ formatID = attrib.format->id;
+ offset = stride = static_cast<GLuint>(ComputeVertexAttributeStride(attrib, binding));
+ offset = static_cast<size_t>(ComputeVertexAttributeOffset(attrib, binding)) %
+ ComputeVertexAttributeStride(attrib, binding);
+}
+
+StaticVertexBufferInterface::StaticVertexBufferInterface(BufferFactoryD3D *factory)
+ : VertexBufferInterface(factory, false)
+{}
+
+StaticVertexBufferInterface::~StaticVertexBufferInterface() {}
+
+bool StaticVertexBufferInterface::matchesAttribute(const gl::VertexAttribute &attrib,
+ const gl::VertexBinding &binding) const
+{
+ return mSignature.matchesAttribute(attrib, binding);
+}
+
+void StaticVertexBufferInterface::setAttribute(const gl::VertexAttribute &attrib,
+ const gl::VertexBinding &binding)
+{
+ return mSignature.set(attrib, binding);
+}
+
+angle::Result StaticVertexBufferInterface::storeStaticAttribute(const gl::Context *context,
+ const gl::VertexAttribute &attrib,
+ const gl::VertexBinding &binding,
+ GLint start,
+ GLsizei count,
+ GLsizei instances,
+ const uint8_t *sourceData)
+{
+ unsigned int spaceRequired = 0;
+ ANGLE_TRY(getSpaceRequired(context, attrib, binding, count, instances, 0, &spaceRequired));
+ ANGLE_TRY(setBufferSize(context, spaceRequired));
+
+ ASSERT(attrib.enabled);
+ ANGLE_TRY(mVertexBuffer->storeVertexAttributes(context, attrib, binding,
+ gl::VertexAttribType::InvalidEnum, start, count,
+ instances, 0, sourceData));
+
+ mSignature.set(attrib, binding);
+ mVertexBuffer->hintUnmapResource();
+ return angle::Result::Continue;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexBuffer.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexBuffer.h
new file mode 100644
index 0000000000..45a16c6bf5
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexBuffer.h
@@ -0,0 +1,189 @@
+//
+// Copyright 2002 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.
+//
+
+// VertexBuffer.h: Defines the abstract VertexBuffer class and VertexBufferInterface
+// class with derivations, classes that perform graphics API agnostic vertex buffer operations.
+
+#ifndef LIBANGLE_RENDERER_D3D_VERTEXBUFFER_H_
+#define LIBANGLE_RENDERER_D3D_VERTEXBUFFER_H_
+
+#include "common/PackedEnums.h"
+#include "common/angleutils.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/renderer/Format.h"
+
+#include <GLES2/gl2.h>
+
+#include <cstddef>
+#include <cstdint>
+#include <vector>
+
+namespace gl
+{
+class Context;
+struct VertexAttribute;
+class VertexBinding;
+struct VertexAttribCurrentValueData;
+} // namespace gl
+
+namespace rx
+{
+class BufferFactoryD3D;
+
+// Use a ref-counting scheme with self-deletion on release. We do this so that we can more
+// easily manage the static buffer cache, without deleting currently bound buffers.
+class VertexBuffer : angle::NonCopyable
+{
+ public:
+ VertexBuffer();
+
+ virtual angle::Result initialize(const gl::Context *context,
+ unsigned int size,
+ bool dynamicUsage) = 0;
+
+ // Warning: you should ensure binding really matches attrib.bindingIndex before using this
+ // function.
+ virtual angle::Result storeVertexAttributes(const gl::Context *context,
+ const gl::VertexAttribute &attrib,
+ const gl::VertexBinding &binding,
+ gl::VertexAttribType currentValueType,
+ GLint start,
+ size_t count,
+ GLsizei instances,
+ unsigned int offset,
+ const uint8_t *sourceData) = 0;
+
+ virtual unsigned int getBufferSize() const = 0;
+ virtual angle::Result setBufferSize(const gl::Context *context, unsigned int size) = 0;
+ virtual angle::Result discard(const gl::Context *context) = 0;
+
+ unsigned int getSerial() const;
+
+ // This may be overridden (e.g. by VertexBuffer11) if necessary.
+ virtual void hintUnmapResource() {}
+
+ // Reference counting.
+ void addRef();
+ void release();
+
+ protected:
+ void updateSerial();
+ virtual ~VertexBuffer();
+
+ private:
+ unsigned int mSerial;
+ static unsigned int mNextSerial;
+ unsigned int mRefCount;
+};
+
+class VertexBufferInterface : angle::NonCopyable
+{
+ public:
+ VertexBufferInterface(BufferFactoryD3D *factory, bool dynamic);
+ virtual ~VertexBufferInterface();
+
+ unsigned int getBufferSize() const;
+ bool empty() const { return getBufferSize() == 0; }
+
+ unsigned int getSerial() const;
+
+ VertexBuffer *getVertexBuffer() const;
+
+ protected:
+ angle::Result discard(const gl::Context *context);
+
+ angle::Result setBufferSize(const gl::Context *context, unsigned int size);
+
+ angle::Result getSpaceRequired(const gl::Context *context,
+ const gl::VertexAttribute &attrib,
+ const gl::VertexBinding &binding,
+ size_t count,
+ GLsizei instances,
+ GLuint baseInstance,
+ unsigned int *spaceInBytesOut) const;
+ BufferFactoryD3D *const mFactory;
+ VertexBuffer *mVertexBuffer;
+ bool mDynamic;
+};
+
+class StreamingVertexBufferInterface : public VertexBufferInterface
+{
+ public:
+ StreamingVertexBufferInterface(BufferFactoryD3D *factory);
+ ~StreamingVertexBufferInterface() override;
+
+ angle::Result initialize(const gl::Context *context, std::size_t initialSize);
+ void reset();
+
+ angle::Result storeDynamicAttribute(const gl::Context *context,
+ const gl::VertexAttribute &attrib,
+ const gl::VertexBinding &binding,
+ gl::VertexAttribType currentValueType,
+ GLint start,
+ size_t count,
+ GLsizei instances,
+ GLuint baseInstance,
+ unsigned int *outStreamOffset,
+ const uint8_t *sourceData);
+
+ angle::Result reserveVertexSpace(const gl::Context *context,
+ const gl::VertexAttribute &attribute,
+ const gl::VertexBinding &binding,
+ size_t count,
+ GLsizei instances,
+ GLuint baseInstance);
+
+ private:
+ angle::Result reserveSpace(const gl::Context *context, unsigned int size);
+
+ unsigned int mWritePosition;
+ unsigned int mReservedSpace;
+};
+
+class StaticVertexBufferInterface : public VertexBufferInterface
+{
+ public:
+ explicit StaticVertexBufferInterface(BufferFactoryD3D *factory);
+ ~StaticVertexBufferInterface() override;
+
+ // Warning: you should ensure binding really matches attrib.bindingIndex before using these
+ // functions.
+ angle::Result storeStaticAttribute(const gl::Context *context,
+ const gl::VertexAttribute &attrib,
+ const gl::VertexBinding &binding,
+ GLint start,
+ GLsizei count,
+ GLsizei instances,
+ const uint8_t *sourceData);
+
+ bool matchesAttribute(const gl::VertexAttribute &attribute,
+ const gl::VertexBinding &binding) const;
+
+ void setAttribute(const gl::VertexAttribute &attribute, const gl::VertexBinding &binding);
+
+ private:
+ class AttributeSignature final : angle::NonCopyable
+ {
+ public:
+ AttributeSignature();
+
+ bool matchesAttribute(const gl::VertexAttribute &attrib,
+ const gl::VertexBinding &binding) const;
+
+ void set(const gl::VertexAttribute &attrib, const gl::VertexBinding &binding);
+
+ private:
+ angle::FormatID formatID;
+ GLuint stride;
+ size_t offset;
+ };
+
+ AttributeSignature mSignature;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_VERTEXBUFFER_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexDataManager.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexDataManager.cpp
new file mode 100644
index 0000000000..6b989c9e80
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexDataManager.cpp
@@ -0,0 +1,683 @@
+//
+// Copyright 2002 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.
+//
+
+// VertexDataManager.h: Defines the VertexDataManager, a class that
+// runs the Buffer translation process.
+
+#include "libANGLE/renderer/d3d/VertexDataManager.h"
+
+#include "common/bitset_utils.h"
+#include "libANGLE/Buffer.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Program.h"
+#include "libANGLE/State.h"
+#include "libANGLE/VertexArray.h"
+#include "libANGLE/VertexAttribute.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/d3d/BufferD3D.h"
+#include "libANGLE/renderer/d3d/ContextD3D.h"
+#include "libANGLE/renderer/d3d/VertexBuffer.h"
+
+using namespace angle;
+
+namespace rx
+{
+namespace
+{
+enum
+{
+ INITIAL_STREAM_BUFFER_SIZE = 1024 * 1024
+};
+// This has to be at least 4k or else it fails on ATI cards.
+enum
+{
+ CONSTANT_VERTEX_BUFFER_SIZE = 4096
+};
+
+// Warning: ensure the binding matches attrib.bindingIndex before using these functions.
+int64_t GetMaxAttributeByteOffsetForDraw(const gl::VertexAttribute &attrib,
+ const gl::VertexBinding &binding,
+ int64_t elementCount)
+{
+ CheckedNumeric<int64_t> stride = ComputeVertexAttributeStride(attrib, binding);
+ CheckedNumeric<int64_t> offset = ComputeVertexAttributeOffset(attrib, binding);
+ CheckedNumeric<int64_t> size = ComputeVertexAttributeTypeSize(attrib);
+
+ ASSERT(elementCount > 0);
+
+ CheckedNumeric<int64_t> result =
+ stride * (CheckedNumeric<int64_t>(elementCount) - 1) + size + offset;
+ return result.ValueOrDefault(std::numeric_limits<int64_t>::max());
+}
+
+// Warning: ensure the binding matches attrib.bindingIndex before using these functions.
+int ElementsInBuffer(const gl::VertexAttribute &attrib,
+ const gl::VertexBinding &binding,
+ unsigned int size)
+{
+ angle::CheckedNumeric<int64_t> bufferSize(size);
+ angle::CheckedNumeric<int64_t> stride = ComputeVertexAttributeStride(attrib, binding);
+ angle::CheckedNumeric<int64_t> offset = ComputeVertexAttributeOffset(attrib, binding);
+ angle::CheckedNumeric<int64_t> elementSize = ComputeVertexAttributeTypeSize(attrib);
+
+ auto elementsInBuffer = (bufferSize - (offset % stride) + (stride - elementSize)) / stride;
+ auto elementsInBufferInt = elementsInBuffer.Cast<int>();
+
+ return elementsInBufferInt.ValueOrDefault(0);
+}
+
+// Warning: you should ensure binding really matches attrib.bindingIndex before using this function.
+bool DirectStoragePossible(const gl::Context *context,
+ const gl::VertexAttribute &attrib,
+ const gl::VertexBinding &binding)
+{
+ // Current value attribs may not use direct storage.
+ if (!attrib.enabled)
+ {
+ return false;
+ }
+
+ gl::Buffer *buffer = binding.getBuffer().get();
+ if (!buffer)
+ {
+ return false;
+ }
+
+ BufferD3D *bufferD3D = GetImplAs<BufferD3D>(buffer);
+ ASSERT(bufferD3D);
+ if (!bufferD3D->supportsDirectBinding())
+ {
+ return false;
+ }
+
+ // Alignment restrictions: In D3D, vertex data must be aligned to the format stride, or to a
+ // 4-byte boundary, whichever is smaller. (Undocumented, and experimentally confirmed)
+ size_t alignment = 4;
+
+ // TODO(jmadill): add VertexFormatCaps
+ BufferFactoryD3D *factory = bufferD3D->getFactory();
+
+ angle::FormatID vertexFormatID = attrib.format->id;
+
+ // CPU-converted vertex data must be converted (naturally).
+ if ((factory->getVertexConversionType(vertexFormatID) & VERTEX_CONVERT_CPU) != 0)
+ {
+ return false;
+ }
+
+ if (attrib.format->vertexAttribType != gl::VertexAttribType::Float)
+ {
+ unsigned int elementSize = 0;
+ angle::Result error =
+ factory->getVertexSpaceRequired(context, attrib, binding, 1, 0, 0, &elementSize);
+ ASSERT(error == angle::Result::Continue);
+ alignment = std::min<size_t>(elementSize, 4);
+ }
+
+ GLintptr offset = ComputeVertexAttributeOffset(attrib, binding);
+ // Final alignment check - unaligned data must be converted.
+ return (static_cast<size_t>(ComputeVertexAttributeStride(attrib, binding)) % alignment == 0) &&
+ (static_cast<size_t>(offset) % alignment == 0);
+}
+} // anonymous namespace
+
+TranslatedAttribute::TranslatedAttribute()
+ : active(false),
+ attribute(nullptr),
+ binding(nullptr),
+ currentValueType(gl::VertexAttribType::InvalidEnum),
+ baseOffset(0),
+ usesFirstVertexOffset(false),
+ stride(0),
+ vertexBuffer(),
+ storage(nullptr),
+ serial(0),
+ divisor(0)
+{}
+
+TranslatedAttribute::TranslatedAttribute(const TranslatedAttribute &other) = default;
+
+angle::Result TranslatedAttribute::computeOffset(const gl::Context *context,
+ GLint startVertex,
+ unsigned int *offsetOut) const
+{
+ if (!usesFirstVertexOffset)
+ {
+ *offsetOut = baseOffset;
+ return angle::Result::Continue;
+ }
+
+ CheckedNumeric<unsigned int> offset(baseOffset);
+ CheckedNumeric<unsigned int> checkedStride(stride);
+
+ offset += checkedStride * static_cast<unsigned int>(startVertex);
+ ANGLE_CHECK_GL_MATH(GetImplAs<ContextD3D>(context), offset.IsValid());
+ *offsetOut = offset.ValueOrDie();
+ return angle::Result::Continue;
+}
+
+// Warning: you should ensure binding really matches attrib.bindingIndex before using this function.
+VertexStorageType ClassifyAttributeStorage(const gl::Context *context,
+ const gl::VertexAttribute &attrib,
+ const gl::VertexBinding &binding)
+{
+ // If attribute is disabled, we use the current value.
+ if (!attrib.enabled)
+ {
+ return VertexStorageType::CURRENT_VALUE;
+ }
+
+ // If specified with immediate data, we must use dynamic storage.
+ gl::Buffer *buffer = binding.getBuffer().get();
+ if (!buffer)
+ {
+ return VertexStorageType::DYNAMIC;
+ }
+
+ // Check if the buffer supports direct storage.
+ if (DirectStoragePossible(context, attrib, binding))
+ {
+ return VertexStorageType::DIRECT;
+ }
+
+ // Otherwise the storage is static or dynamic.
+ BufferD3D *bufferD3D = GetImplAs<BufferD3D>(buffer);
+ ASSERT(bufferD3D);
+ switch (bufferD3D->getUsage())
+ {
+ case D3DBufferUsage::DYNAMIC:
+ return VertexStorageType::DYNAMIC;
+ case D3DBufferUsage::STATIC:
+ return VertexStorageType::STATIC;
+ default:
+ UNREACHABLE();
+ return VertexStorageType::UNKNOWN;
+ }
+}
+
+VertexDataManager::CurrentValueState::CurrentValueState(BufferFactoryD3D *factory)
+ : buffer(new StreamingVertexBufferInterface(factory)), offset(0)
+{
+ data.Values.FloatValues[0] = std::numeric_limits<float>::quiet_NaN();
+ data.Values.FloatValues[1] = std::numeric_limits<float>::quiet_NaN();
+ data.Values.FloatValues[2] = std::numeric_limits<float>::quiet_NaN();
+ data.Values.FloatValues[3] = std::numeric_limits<float>::quiet_NaN();
+ data.Type = gl::VertexAttribType::Float;
+}
+
+VertexDataManager::CurrentValueState::CurrentValueState(CurrentValueState &&other)
+{
+ std::swap(buffer, other.buffer);
+ std::swap(data, other.data);
+ std::swap(offset, other.offset);
+}
+
+VertexDataManager::CurrentValueState::~CurrentValueState() {}
+
+VertexDataManager::VertexDataManager(BufferFactoryD3D *factory)
+ : mFactory(factory), mStreamingBuffer(factory)
+{
+ mCurrentValueCache.reserve(gl::MAX_VERTEX_ATTRIBS);
+ for (int currentValueIndex = 0; currentValueIndex < gl::MAX_VERTEX_ATTRIBS; ++currentValueIndex)
+ {
+ mCurrentValueCache.emplace_back(factory);
+ }
+}
+
+VertexDataManager::~VertexDataManager() {}
+
+angle::Result VertexDataManager::initialize(const gl::Context *context)
+{
+ return mStreamingBuffer.initialize(context, INITIAL_STREAM_BUFFER_SIZE);
+}
+
+void VertexDataManager::deinitialize()
+{
+ mStreamingBuffer.reset();
+ mCurrentValueCache.clear();
+}
+
+angle::Result VertexDataManager::prepareVertexData(
+ const gl::Context *context,
+ GLint start,
+ GLsizei count,
+ std::vector<TranslatedAttribute> *translatedAttribs,
+ GLsizei instances)
+{
+ const gl::State &state = context->getState();
+ const gl::ProgramExecutable *executable = state.getProgramExecutable();
+ const gl::VertexArray *vertexArray = state.getVertexArray();
+ const auto &vertexAttributes = vertexArray->getVertexAttributes();
+ const auto &vertexBindings = vertexArray->getVertexBindings();
+
+ mDynamicAttribsMaskCache.reset();
+
+ translatedAttribs->clear();
+
+ for (size_t attribIndex = 0; attribIndex < vertexAttributes.size(); ++attribIndex)
+ {
+ // Skip attrib locations the program doesn't use.
+ if (!executable->isAttribLocationActive(attribIndex))
+ continue;
+
+ const auto &attrib = vertexAttributes[attribIndex];
+ const auto &binding = vertexBindings[attrib.bindingIndex];
+
+ // Resize automatically puts in empty attribs
+ translatedAttribs->resize(attribIndex + 1);
+
+ TranslatedAttribute *translated = &(*translatedAttribs)[attribIndex];
+ auto currentValueData = state.getVertexAttribCurrentValue(attribIndex);
+
+ // Record the attribute now
+ translated->active = true;
+ translated->attribute = &attrib;
+ translated->binding = &binding;
+ translated->currentValueType = currentValueData.Type;
+ translated->divisor = binding.getDivisor();
+
+ switch (ClassifyAttributeStorage(context, attrib, binding))
+ {
+ case VertexStorageType::STATIC:
+ {
+ // Store static attribute.
+ ANGLE_TRY(StoreStaticAttrib(context, translated));
+ break;
+ }
+ case VertexStorageType::DYNAMIC:
+ // Dynamic attributes must be handled together.
+ mDynamicAttribsMaskCache.set(attribIndex);
+ break;
+ case VertexStorageType::DIRECT:
+ // Update translated data for direct attributes.
+ StoreDirectAttrib(context, translated);
+ break;
+ case VertexStorageType::CURRENT_VALUE:
+ {
+ ANGLE_TRY(storeCurrentValue(context, currentValueData, translated, attribIndex));
+ break;
+ }
+ default:
+ UNREACHABLE();
+ break;
+ }
+ }
+
+ if (mDynamicAttribsMaskCache.none())
+ {
+ return angle::Result::Continue;
+ }
+
+ // prepareVertexData is only called by Renderer9 which don't support baseInstance
+ ANGLE_TRY(storeDynamicAttribs(context, translatedAttribs, mDynamicAttribsMaskCache, start,
+ count, instances, 0u));
+
+ PromoteDynamicAttribs(context, *translatedAttribs, mDynamicAttribsMaskCache, count);
+
+ return angle::Result::Continue;
+}
+
+// static
+void VertexDataManager::StoreDirectAttrib(const gl::Context *context,
+ TranslatedAttribute *directAttrib)
+{
+ ASSERT(directAttrib->attribute && directAttrib->binding);
+ const auto &attrib = *directAttrib->attribute;
+ const auto &binding = *directAttrib->binding;
+
+ gl::Buffer *buffer = binding.getBuffer().get();
+ ASSERT(buffer);
+ BufferD3D *bufferD3D = GetImplAs<BufferD3D>(buffer);
+
+ ASSERT(DirectStoragePossible(context, attrib, binding));
+ directAttrib->vertexBuffer.set(nullptr);
+ directAttrib->storage = bufferD3D;
+ directAttrib->serial = bufferD3D->getSerial();
+ directAttrib->stride = static_cast<unsigned int>(ComputeVertexAttributeStride(attrib, binding));
+ directAttrib->baseOffset =
+ static_cast<unsigned int>(ComputeVertexAttributeOffset(attrib, binding));
+
+ // Instanced vertices do not apply the 'start' offset
+ directAttrib->usesFirstVertexOffset = (binding.getDivisor() == 0);
+}
+
+// static
+angle::Result VertexDataManager::StoreStaticAttrib(const gl::Context *context,
+ TranslatedAttribute *translated)
+{
+ ASSERT(translated->attribute && translated->binding);
+ const auto &attrib = *translated->attribute;
+ const auto &binding = *translated->binding;
+
+ gl::Buffer *buffer = binding.getBuffer().get();
+ ASSERT(buffer && attrib.enabled && !DirectStoragePossible(context, attrib, binding));
+ BufferD3D *bufferD3D = GetImplAs<BufferD3D>(buffer);
+
+ // Compute source data pointer
+ const uint8_t *sourceData = nullptr;
+ const int offset = static_cast<int>(ComputeVertexAttributeOffset(attrib, binding));
+
+ ANGLE_TRY(bufferD3D->getData(context, &sourceData));
+
+ if (sourceData)
+ {
+ sourceData += offset;
+ }
+
+ unsigned int streamOffset = 0;
+
+ translated->storage = nullptr;
+ ANGLE_TRY(bufferD3D->getFactory()->getVertexSpaceRequired(context, attrib, binding, 1, 0, 0,
+ &translated->stride));
+
+ auto *staticBuffer = bufferD3D->getStaticVertexBuffer(attrib, binding);
+ ASSERT(staticBuffer);
+
+ if (staticBuffer->empty())
+ {
+ // Convert the entire buffer
+ int totalCount =
+ ElementsInBuffer(attrib, binding, static_cast<unsigned int>(bufferD3D->getSize()));
+ int startIndex = offset / static_cast<int>(ComputeVertexAttributeStride(attrib, binding));
+
+ if (totalCount > 0)
+ {
+ ANGLE_TRY(staticBuffer->storeStaticAttribute(context, attrib, binding, -startIndex,
+ totalCount, 0, sourceData));
+ }
+ }
+
+ unsigned int firstElementOffset =
+ (static_cast<unsigned int>(offset) /
+ static_cast<unsigned int>(ComputeVertexAttributeStride(attrib, binding))) *
+ translated->stride;
+
+ VertexBuffer *vertexBuffer = staticBuffer->getVertexBuffer();
+
+ CheckedNumeric<unsigned int> checkedOffset(streamOffset);
+ checkedOffset += firstElementOffset;
+
+ ANGLE_CHECK_GL_MATH(GetImplAs<ContextD3D>(context), checkedOffset.IsValid());
+
+ translated->vertexBuffer.set(vertexBuffer);
+ translated->serial = vertexBuffer->getSerial();
+ translated->baseOffset = streamOffset + firstElementOffset;
+
+ // Instanced vertices do not apply the 'start' offset
+ translated->usesFirstVertexOffset = (binding.getDivisor() == 0);
+
+ return angle::Result::Continue;
+}
+
+angle::Result VertexDataManager::storeDynamicAttribs(
+ const gl::Context *context,
+ std::vector<TranslatedAttribute> *translatedAttribs,
+ const gl::AttributesMask &dynamicAttribsMask,
+ GLint start,
+ size_t count,
+ GLsizei instances,
+ GLuint baseInstance)
+{
+ // Instantiating this class will ensure the streaming buffer is never left mapped.
+ class StreamingBufferUnmapper final : NonCopyable
+ {
+ public:
+ StreamingBufferUnmapper(StreamingVertexBufferInterface *streamingBuffer)
+ : mStreamingBuffer(streamingBuffer)
+ {
+ ASSERT(mStreamingBuffer);
+ }
+ ~StreamingBufferUnmapper() { mStreamingBuffer->getVertexBuffer()->hintUnmapResource(); }
+
+ private:
+ StreamingVertexBufferInterface *mStreamingBuffer;
+ };
+
+ // Will trigger unmapping on return.
+ StreamingBufferUnmapper localUnmapper(&mStreamingBuffer);
+
+ // Reserve the required space for the dynamic buffers.
+ for (auto attribIndex : dynamicAttribsMask)
+ {
+ const auto &dynamicAttrib = (*translatedAttribs)[attribIndex];
+ ANGLE_TRY(
+ reserveSpaceForAttrib(context, dynamicAttrib, start, count, instances, baseInstance));
+ }
+
+ // Store dynamic attributes
+ for (auto attribIndex : dynamicAttribsMask)
+ {
+ auto *dynamicAttrib = &(*translatedAttribs)[attribIndex];
+ ANGLE_TRY(
+ storeDynamicAttrib(context, dynamicAttrib, start, count, instances, baseInstance));
+ }
+
+ return angle::Result::Continue;
+}
+
+void VertexDataManager::PromoteDynamicAttribs(
+ const gl::Context *context,
+ const std::vector<TranslatedAttribute> &translatedAttribs,
+ const gl::AttributesMask &dynamicAttribsMask,
+ size_t count)
+{
+ for (auto attribIndex : dynamicAttribsMask)
+ {
+ const auto &dynamicAttrib = translatedAttribs[attribIndex];
+ ASSERT(dynamicAttrib.attribute && dynamicAttrib.binding);
+ const auto &binding = *dynamicAttrib.binding;
+
+ gl::Buffer *buffer = binding.getBuffer().get();
+ if (buffer)
+ {
+ // Note: this multiplication can overflow. It should not be a security problem.
+ BufferD3D *bufferD3D = GetImplAs<BufferD3D>(buffer);
+ size_t typeSize = ComputeVertexAttributeTypeSize(*dynamicAttrib.attribute);
+ bufferD3D->promoteStaticUsage(context, count * typeSize);
+ }
+ }
+}
+
+angle::Result VertexDataManager::reserveSpaceForAttrib(const gl::Context *context,
+ const TranslatedAttribute &translatedAttrib,
+ GLint start,
+ size_t count,
+ GLsizei instances,
+ GLuint baseInstance)
+{
+ ASSERT(translatedAttrib.attribute && translatedAttrib.binding);
+ const auto &attrib = *translatedAttrib.attribute;
+ const auto &binding = *translatedAttrib.binding;
+
+ ASSERT(!DirectStoragePossible(context, attrib, binding));
+
+ gl::Buffer *buffer = binding.getBuffer().get();
+ BufferD3D *bufferD3D = buffer ? GetImplAs<BufferD3D>(buffer) : nullptr;
+ ASSERT(!bufferD3D || bufferD3D->getStaticVertexBuffer(attrib, binding) == nullptr);
+
+ size_t totalCount = gl::ComputeVertexBindingElementCount(binding.getDivisor(), count,
+ static_cast<size_t>(instances));
+ // TODO(jiajia.qin@intel.com): force the index buffer to clamp any out of range indices instead
+ // of invalid operation here.
+ if (bufferD3D)
+ {
+ // Vertices do not apply the 'start' offset when the divisor is non-zero even when doing
+ // a non-instanced draw call
+ GLint firstVertexIndex = binding.getDivisor() > 0
+ ? UnsignedCeilDivide(baseInstance, binding.getDivisor())
+ : start;
+ int64_t maxVertexCount =
+ static_cast<int64_t>(firstVertexIndex) + static_cast<int64_t>(totalCount);
+
+ int64_t maxByte = GetMaxAttributeByteOffsetForDraw(attrib, binding, maxVertexCount);
+
+ ASSERT(bufferD3D->getSize() <= static_cast<size_t>(std::numeric_limits<int64_t>::max()));
+ ANGLE_CHECK(GetImplAs<ContextD3D>(context),
+ maxByte <= static_cast<int64_t>(bufferD3D->getSize()),
+ "Vertex buffer is not big enough for the draw call.", GL_INVALID_OPERATION);
+ }
+ return mStreamingBuffer.reserveVertexSpace(context, attrib, binding, totalCount, instances,
+ baseInstance);
+}
+
+angle::Result VertexDataManager::storeDynamicAttrib(const gl::Context *context,
+ TranslatedAttribute *translated,
+ GLint start,
+ size_t count,
+ GLsizei instances,
+ GLuint baseInstance)
+{
+ ASSERT(translated->attribute && translated->binding);
+ const auto &attrib = *translated->attribute;
+ const auto &binding = *translated->binding;
+
+ gl::Buffer *buffer = binding.getBuffer().get();
+ ASSERT(buffer || attrib.pointer);
+ ASSERT(attrib.enabled);
+
+ BufferD3D *storage = buffer ? GetImplAs<BufferD3D>(buffer) : nullptr;
+
+ // Instanced vertices do not apply the 'start' offset
+ GLint firstVertexIndex =
+ (binding.getDivisor() > 0 ? UnsignedCeilDivide(baseInstance, binding.getDivisor()) : start);
+
+ // Compute source data pointer
+ const uint8_t *sourceData = nullptr;
+
+ if (buffer)
+ {
+ ANGLE_TRY(storage->getData(context, &sourceData));
+ sourceData += static_cast<int>(ComputeVertexAttributeOffset(attrib, binding));
+ }
+ else
+ {
+ // Attributes using client memory ignore the VERTEX_ATTRIB_BINDING state.
+ // https://www.opengl.org/registry/specs/ARB/vertex_attrib_binding.txt
+ sourceData = static_cast<const uint8_t *>(attrib.pointer);
+ }
+
+ unsigned int streamOffset = 0;
+
+ translated->storage = nullptr;
+ ANGLE_TRY(
+ mFactory->getVertexSpaceRequired(context, attrib, binding, 1, 0, 0, &translated->stride));
+
+ size_t totalCount = gl::ComputeVertexBindingElementCount(binding.getDivisor(), count,
+ static_cast<size_t>(instances));
+
+ ANGLE_TRY(mStreamingBuffer.storeDynamicAttribute(
+ context, attrib, binding, translated->currentValueType, firstVertexIndex,
+ static_cast<GLsizei>(totalCount), instances, baseInstance, &streamOffset, sourceData));
+
+ VertexBuffer *vertexBuffer = mStreamingBuffer.getVertexBuffer();
+
+ translated->vertexBuffer.set(vertexBuffer);
+ translated->serial = vertexBuffer->getSerial();
+ translated->baseOffset = streamOffset;
+ translated->usesFirstVertexOffset = false;
+
+ return angle::Result::Continue;
+}
+
+angle::Result VertexDataManager::storeCurrentValue(
+ const gl::Context *context,
+ const gl::VertexAttribCurrentValueData &currentValue,
+ TranslatedAttribute *translated,
+ size_t attribIndex)
+{
+ CurrentValueState *cachedState = &mCurrentValueCache[attribIndex];
+ StreamingVertexBufferInterface &buffer = *cachedState->buffer;
+
+ if (buffer.getBufferSize() == 0)
+ {
+ ANGLE_TRY(buffer.initialize(context, CONSTANT_VERTEX_BUFFER_SIZE));
+ }
+
+ if (cachedState->data != currentValue)
+ {
+ ASSERT(translated->attribute && translated->binding);
+ const auto &attrib = *translated->attribute;
+ const auto &binding = *translated->binding;
+
+ ANGLE_TRY(buffer.reserveVertexSpace(context, attrib, binding, 1, 0, 0));
+
+ const uint8_t *sourceData =
+ reinterpret_cast<const uint8_t *>(currentValue.Values.FloatValues);
+ unsigned int streamOffset;
+ ANGLE_TRY(buffer.storeDynamicAttribute(context, attrib, binding, currentValue.Type, 0, 1, 0,
+ 0, &streamOffset, sourceData));
+
+ buffer.getVertexBuffer()->hintUnmapResource();
+
+ cachedState->data = currentValue;
+ cachedState->offset = streamOffset;
+ }
+
+ translated->vertexBuffer.set(buffer.getVertexBuffer());
+
+ translated->storage = nullptr;
+ translated->serial = buffer.getSerial();
+ translated->divisor = 0;
+ translated->stride = 0;
+ translated->baseOffset = static_cast<unsigned int>(cachedState->offset);
+ translated->usesFirstVertexOffset = false;
+
+ return angle::Result::Continue;
+}
+
+// VertexBufferBinding implementation
+VertexBufferBinding::VertexBufferBinding() : mBoundVertexBuffer(nullptr) {}
+
+VertexBufferBinding::VertexBufferBinding(const VertexBufferBinding &other)
+ : mBoundVertexBuffer(other.mBoundVertexBuffer)
+{
+ if (mBoundVertexBuffer)
+ {
+ mBoundVertexBuffer->addRef();
+ }
+}
+
+VertexBufferBinding::~VertexBufferBinding()
+{
+ if (mBoundVertexBuffer)
+ {
+ mBoundVertexBuffer->release();
+ }
+}
+
+VertexBufferBinding &VertexBufferBinding::operator=(const VertexBufferBinding &other)
+{
+ mBoundVertexBuffer = other.mBoundVertexBuffer;
+ if (mBoundVertexBuffer)
+ {
+ mBoundVertexBuffer->addRef();
+ }
+ return *this;
+}
+
+void VertexBufferBinding::set(VertexBuffer *vertexBuffer)
+{
+ if (mBoundVertexBuffer == vertexBuffer)
+ return;
+
+ if (mBoundVertexBuffer)
+ {
+ mBoundVertexBuffer->release();
+ }
+ if (vertexBuffer)
+ {
+ vertexBuffer->addRef();
+ }
+
+ mBoundVertexBuffer = vertexBuffer;
+}
+
+VertexBuffer *VertexBufferBinding::get() const
+{
+ return mBoundVertexBuffer;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexDataManager.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexDataManager.h
new file mode 100644
index 0000000000..50400db027
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/VertexDataManager.h
@@ -0,0 +1,163 @@
+//
+// Copyright 2002 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.
+//
+
+// VertexDataManager.h: Defines the VertexDataManager, a class that
+// runs the Buffer translation process.
+
+#ifndef LIBANGLE_RENDERER_D3D_VERTEXDATAMANAGER_H_
+#define LIBANGLE_RENDERER_D3D_VERTEXDATAMANAGER_H_
+
+#include "common/angleutils.h"
+#include "libANGLE/Constants.h"
+#include "libANGLE/VertexAttribute.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/renderer/d3d/VertexBuffer.h"
+
+namespace gl
+{
+class State;
+struct VertexAttribute;
+class VertexBinding;
+struct VertexAttribCurrentValueData;
+} // namespace gl
+
+namespace rx
+{
+class BufferD3D;
+class BufferFactoryD3D;
+class StreamingVertexBufferInterface;
+class VertexBuffer;
+
+class VertexBufferBinding final
+{
+ public:
+ VertexBufferBinding();
+ VertexBufferBinding(const VertexBufferBinding &other);
+ ~VertexBufferBinding();
+
+ void set(VertexBuffer *vertexBuffer);
+ VertexBuffer *get() const;
+ VertexBufferBinding &operator=(const VertexBufferBinding &other);
+
+ private:
+ VertexBuffer *mBoundVertexBuffer;
+};
+
+struct TranslatedAttribute
+{
+ TranslatedAttribute();
+ TranslatedAttribute(const TranslatedAttribute &other);
+
+ // Computes the correct offset from baseOffset, usesFirstVertexOffset, stride and startVertex.
+ // Can throw an error on integer overflow.
+ angle::Result computeOffset(const gl::Context *context,
+ GLint startVertex,
+ unsigned int *offsetOut) const;
+
+ bool active;
+
+ const gl::VertexAttribute *attribute;
+ const gl::VertexBinding *binding;
+ gl::VertexAttribType currentValueType;
+ unsigned int baseOffset;
+ bool usesFirstVertexOffset;
+ unsigned int stride; // 0 means not to advance the read pointer at all
+
+ VertexBufferBinding vertexBuffer;
+ BufferD3D *storage;
+ unsigned int serial;
+ unsigned int divisor;
+};
+
+enum class VertexStorageType
+{
+ UNKNOWN,
+ STATIC, // Translate the vertex data once and re-use it.
+ DYNAMIC, // Translate the data every frame into a ring buffer.
+ DIRECT, // Bind a D3D buffer directly without any translation.
+ CURRENT_VALUE, // Use a single value for the attribute.
+};
+
+// Given a vertex attribute, return the type of storage it will use.
+VertexStorageType ClassifyAttributeStorage(const gl::Context *context,
+ const gl::VertexAttribute &attrib,
+ const gl::VertexBinding &binding);
+
+class VertexDataManager : angle::NonCopyable
+{
+ public:
+ VertexDataManager(BufferFactoryD3D *factory);
+ virtual ~VertexDataManager();
+
+ angle::Result initialize(const gl::Context *context);
+ void deinitialize();
+
+ angle::Result prepareVertexData(const gl::Context *context,
+ GLint start,
+ GLsizei count,
+ std::vector<TranslatedAttribute> *translatedAttribs,
+ GLsizei instances);
+
+ static void StoreDirectAttrib(const gl::Context *context, TranslatedAttribute *directAttrib);
+
+ static angle::Result StoreStaticAttrib(const gl::Context *context,
+ TranslatedAttribute *translated);
+
+ angle::Result storeDynamicAttribs(const gl::Context *context,
+ std::vector<TranslatedAttribute> *translatedAttribs,
+ const gl::AttributesMask &dynamicAttribsMask,
+ GLint start,
+ size_t count,
+ GLsizei instances,
+ GLuint baseInstance);
+
+ // Promote static usage of dynamic buffers.
+ static void PromoteDynamicAttribs(const gl::Context *context,
+ const std::vector<TranslatedAttribute> &translatedAttribs,
+ const gl::AttributesMask &dynamicAttribsMask,
+ size_t count);
+
+ angle::Result storeCurrentValue(const gl::Context *context,
+ const gl::VertexAttribCurrentValueData &currentValue,
+ TranslatedAttribute *translated,
+ size_t attribIndex);
+
+ private:
+ struct CurrentValueState final : angle::NonCopyable
+ {
+ CurrentValueState(BufferFactoryD3D *factory);
+ CurrentValueState(CurrentValueState &&other);
+ ~CurrentValueState();
+
+ std::unique_ptr<StreamingVertexBufferInterface> buffer;
+ gl::VertexAttribCurrentValueData data;
+ size_t offset;
+ };
+
+ angle::Result reserveSpaceForAttrib(const gl::Context *context,
+ const TranslatedAttribute &translatedAttrib,
+ GLint start,
+ size_t count,
+ GLsizei instances,
+ GLuint baseInstance);
+
+ angle::Result storeDynamicAttrib(const gl::Context *context,
+ TranslatedAttribute *translated,
+ GLint start,
+ size_t count,
+ GLsizei instances,
+ GLuint baseInstance);
+
+ BufferFactoryD3D *const mFactory;
+
+ StreamingVertexBufferInterface mStreamingBuffer;
+ std::vector<CurrentValueState> mCurrentValueCache;
+ gl::AttributesMask mDynamicAttribsMaskCache;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_VERTEXDATAMANAGER_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp
new file mode 100644
index 0000000000..b78ecc5dee
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Blit11.cpp
@@ -0,0 +1,1943 @@
+//
+// Copyright 2013 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.
+//
+
+// Blit11.cpp: Texture copy utility class.
+
+#include "libANGLE/renderer/d3d/d3d11/Blit11.h"
+
+#include <float.h>
+
+#include "common/utilities.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/d3d/d3d11/Context11.h"
+#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
+#include "libANGLE/trace.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/passthrough3d11gs.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11vs.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/swizzlef2darrayps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2dps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef3dps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2darrayps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2dps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei3dps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2darrayps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2dps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui3dps.h"
+
+void StretchedBlitNearest_RowByRow(const gl::Box &sourceArea,
+ const gl::Box &destArea,
+ const gl::Rectangle &clippedDestArea,
+ const gl::Extents &sourceSize,
+ unsigned int sourceRowPitch,
+ unsigned int destRowPitch,
+ size_t pixelSize,
+ const uint8_t *sourceData,
+ uint8_t *destData)
+{
+ int srcHeightSubOne = (sourceArea.height - 1);
+ size_t copySize = pixelSize * clippedDestArea.width;
+ size_t srcOffset = sourceArea.x * pixelSize;
+ size_t destOffset = clippedDestArea.x * pixelSize;
+
+ for (int y = clippedDestArea.y; y < clippedDestArea.y + clippedDestArea.height; y++)
+ {
+ // TODO: Fix divide by zero when height == 1. http://anglebug.com/6099
+ float yPerc = static_cast<float>(y - destArea.y) / (destArea.height - 1);
+
+ // Interpolate using the original source rectangle to determine which row to sample from
+ // while clamping to the edges
+ unsigned int readRow = static_cast<unsigned int>(
+ gl::clamp(sourceArea.y + floor(yPerc * srcHeightSubOne + 0.5f), 0, srcHeightSubOne));
+ unsigned int writeRow = y;
+
+ const uint8_t *sourceRow = sourceData + readRow * sourceRowPitch + srcOffset;
+ uint8_t *destRow = destData + writeRow * destRowPitch + destOffset;
+ memcpy(destRow, sourceRow, copySize);
+ }
+}
+
+void StretchedBlitNearest_PixelByPixel(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)
+{
+ auto xMax = clippedDestArea.x + clippedDestArea.width;
+ auto yMax = clippedDestArea.y + clippedDestArea.height;
+
+ for (int writeRow = clippedDestArea.y; writeRow < yMax; writeRow++)
+ {
+ // Interpolate using the original source rectangle to determine which row to sample from
+ // while clamping to the edges
+ float yPerc = static_cast<float>(writeRow - destArea.y) / (destArea.height - 1);
+ float yRounded = floor(yPerc * (sourceArea.height - 1) + 0.5f);
+ unsigned int readRow =
+ static_cast<unsigned int>(gl::clamp(sourceArea.y + yRounded, 0, sourceSize.height - 1));
+
+ for (int writeColumn = clippedDestArea.x; writeColumn < xMax; writeColumn++)
+ {
+ // Interpolate the original source rectangle to determine which column to sample
+ // from while clamping to the edges
+ float xPerc = static_cast<float>(writeColumn - destArea.x) / (destArea.width - 1);
+ float xRounded = floor(xPerc * (sourceArea.width - 1) + 0.5f);
+ unsigned int readColumn = static_cast<unsigned int>(
+ gl::clamp(sourceArea.x + xRounded, 0, sourceSize.width - 1));
+
+ const uint8_t *sourcePixel =
+ sourceData + readRow * sourceRowPitch + readColumn * srcPixelStride + readOffset;
+
+ uint8_t *destPixel =
+ destData + writeRow * destRowPitch + writeColumn * destPixelStride + writeOffset;
+
+ memcpy(destPixel, sourcePixel, copySize);
+ }
+ }
+}
+
+void StretchedBlitNearest(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::Rectangle clippedDestArea(destArea.x, destArea.y, destArea.width, destArea.height);
+ if (!gl::ClipRectangle(clippedDestArea, clipRect, &clippedDestArea))
+ {
+ return;
+ }
+
+ // Determine if entire rows can be copied at once instead of each individual pixel. There
+ // must be no out of bounds lookups, whole rows copies, and no scale.
+ if (sourceArea.width == clippedDestArea.width && sourceArea.x >= 0 &&
+ sourceArea.x + sourceArea.width <= sourceSize.width && copySize == srcPixelStride &&
+ copySize == destPixelStride)
+ {
+ StretchedBlitNearest_RowByRow(sourceArea, destArea, clippedDestArea, sourceSize,
+ sourceRowPitch, destRowPitch, srcPixelStride, sourceData,
+ destData);
+ }
+ else
+ {
+ StretchedBlitNearest_PixelByPixel(sourceArea, destArea, clippedDestArea, sourceSize,
+ sourceRowPitch, destRowPitch, readOffset, writeOffset,
+ copySize, srcPixelStride, destPixelStride, sourceData,
+ destData);
+ }
+}
+
+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,
+ const gl::Extents &destSize,
+ float *x1,
+ float *y1,
+ float *x2,
+ float *y2,
+ float *u1,
+ float *v1,
+ float *u2,
+ float *v2)
+{
+ *x1 = (destArea.x / float(destSize.width)) * 2.0f - 1.0f;
+ *y1 = ((destSize.height - destArea.y - destArea.height) / float(destSize.height)) * 2.0f - 1.0f;
+ *x2 = ((destArea.x + destArea.width) / float(destSize.width)) * 2.0f - 1.0f;
+ *y2 = ((destSize.height - destArea.y) / float(destSize.height)) * 2.0f - 1.0f;
+
+ *u1 = sourceArea.x / float(sourceSize.width);
+ *v1 = sourceArea.y / float(sourceSize.height);
+ *u2 = (sourceArea.x + sourceArea.width) / float(sourceSize.width);
+ *v2 = (sourceArea.y + sourceArea.height) / float(sourceSize.height);
+}
+
+void Write2DVertices(const gl::Box &sourceArea,
+ const gl::Extents &sourceSize,
+ const gl::Box &destArea,
+ const gl::Extents &destSize,
+ void *outVertices,
+ unsigned int *outStride,
+ unsigned int *outVertexCount,
+ D3D11_PRIMITIVE_TOPOLOGY *outTopology)
+{
+ float x1, y1, x2, y2, u1, v1, u2, v2;
+ GenerateVertexCoords(sourceArea, sourceSize, destArea, destSize, &x1, &y1, &x2, &y2, &u1, &v1,
+ &u2, &v2);
+
+ d3d11::PositionTexCoordVertex *vertices =
+ static_cast<d3d11::PositionTexCoordVertex *>(outVertices);
+
+ d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, u1, v2);
+ d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, u1, v1);
+ d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, u2, v2);
+ d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, u2, v1);
+
+ *outStride = sizeof(d3d11::PositionTexCoordVertex);
+ *outVertexCount = 4;
+ *outTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
+}
+
+void Write3DVertices(const gl::Box &sourceArea,
+ const gl::Extents &sourceSize,
+ const gl::Box &destArea,
+ const gl::Extents &destSize,
+ void *outVertices,
+ unsigned int *outStride,
+ unsigned int *outVertexCount,
+ D3D11_PRIMITIVE_TOPOLOGY *outTopology)
+{
+ ASSERT(sourceSize.depth > 0 && destSize.depth > 0);
+
+ float x1, y1, x2, y2, u1, v1, u2, v2;
+ GenerateVertexCoords(sourceArea, sourceSize, destArea, destSize, &x1, &y1, &x2, &y2, &u1, &v1,
+ &u2, &v2);
+
+ d3d11::PositionLayerTexCoord3DVertex *vertices =
+ static_cast<d3d11::PositionLayerTexCoord3DVertex *>(outVertices);
+
+ for (int i = 0; i < destSize.depth; i++)
+ {
+ float readDepth = (float)i / std::max(destSize.depth - 1, 1);
+
+ d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 0], x1, y1, i, u1, v2, readDepth);
+ d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 1], x1, y2, i, u1, v1, readDepth);
+ d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 2], x2, y1, i, u2, v2, readDepth);
+
+ d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 3], x1, y2, i, u1, v1, readDepth);
+ d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 4], x2, y2, i, u2, v1, readDepth);
+ d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 5], x2, y1, i, u2, v2, readDepth);
+ }
+
+ *outStride = sizeof(d3d11::PositionLayerTexCoord3DVertex);
+ *outVertexCount = destSize.depth * 6;
+ *outTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
+}
+
+unsigned int GetSwizzleIndex(GLenum swizzle)
+{
+ unsigned int colorIndex = 0;
+
+ switch (swizzle)
+ {
+ case GL_RED:
+ colorIndex = 0;
+ break;
+ case GL_GREEN:
+ colorIndex = 1;
+ break;
+ case GL_BLUE:
+ colorIndex = 2;
+ break;
+ case GL_ALPHA:
+ colorIndex = 3;
+ break;
+ case GL_ZERO:
+ colorIndex = 4;
+ break;
+ case GL_ONE:
+ colorIndex = 5;
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ return colorIndex;
+}
+
+D3D11_BLEND_DESC GetAlphaMaskBlendStateDesc()
+{
+ D3D11_BLEND_DESC desc;
+ memset(&desc, 0, sizeof(desc));
+ desc.RenderTarget[0].BlendEnable = TRUE;
+ desc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE;
+ desc.RenderTarget[0].DestBlend = D3D11_BLEND_ZERO;
+ desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
+ desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ZERO;
+ desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
+ desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
+ desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_RED |
+ D3D11_COLOR_WRITE_ENABLE_GREEN |
+ D3D11_COLOR_WRITE_ENABLE_BLUE;
+ return desc;
+}
+
+D3D11_INPUT_ELEMENT_DESC quad2DLayout[] = {
+ {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
+ {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0},
+};
+
+D3D11_INPUT_ELEMENT_DESC quad3DLayout[] = {
+ {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
+ {"LAYER", 0, DXGI_FORMAT_R32_UINT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0},
+ {"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
+
+#include "libANGLE/renderer/d3d/d3d11/Blit11Helper_autogen.inc"
+
+Blit11::Shader::Shader() = default;
+
+Blit11::Shader::Shader(Shader &&other) = default;
+
+Blit11::Shader::~Shader() = default;
+
+Blit11::Shader &Blit11::Shader::operator=(Blit11::Shader &&other) = default;
+
+Blit11::Blit11(Renderer11 *renderer)
+ : mRenderer(renderer),
+ mResourcesInitialized(false),
+ mVertexBuffer(),
+ mPointSampler(),
+ mLinearSampler(),
+ mScissorEnabledRasterizerState(),
+ mScissorDisabledRasterizerState(),
+ mDepthStencilState(),
+ mQuad2DIL(quad2DLayout,
+ ArraySize(quad2DLayout),
+ g_VS_Passthrough2D,
+ ArraySize(g_VS_Passthrough2D),
+ "Blit11 2D input layout"),
+ mQuad2DVS(g_VS_Passthrough2D, ArraySize(g_VS_Passthrough2D), "Blit11 2D vertex shader"),
+ mDepthPS(g_PS_PassthroughDepth2D,
+ ArraySize(g_PS_PassthroughDepth2D),
+ "Blit11 2D depth pixel shader"),
+ mQuad3DIL(quad3DLayout,
+ ArraySize(quad3DLayout),
+ g_VS_Passthrough3D,
+ ArraySize(g_VS_Passthrough3D),
+ "Blit11 3D input layout"),
+ 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(),
+ 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(),
+ mResolvedDepthStencilRTView()
+{}
+
+Blit11::~Blit11() {}
+
+angle::Result Blit11::initResources(const gl::Context *context)
+{
+ if (mResourcesInitialized)
+ {
+ return angle::Result::Continue;
+ }
+
+ ANGLE_TRACE_EVENT0("gpu.angle", "Blit11::initResources");
+
+ D3D11_BUFFER_DESC vbDesc;
+ vbDesc.ByteWidth =
+ static_cast<unsigned int>(std::max(sizeof(d3d11::PositionLayerTexCoord3DVertex),
+ sizeof(d3d11::PositionTexCoordVertex)) *
+ 6 * mRenderer->getNativeCaps().max3DTextureSize);
+ vbDesc.Usage = D3D11_USAGE_DYNAMIC;
+ vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
+ vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+ vbDesc.MiscFlags = 0;
+ vbDesc.StructureByteStride = 0;
+
+ Context11 *context11 = GetImplAs<Context11>(context);
+
+ ANGLE_TRY(mRenderer->allocateResource(context11, vbDesc, &mVertexBuffer));
+ mVertexBuffer.setInternalName("Blit11VertexBuffer");
+
+ D3D11_SAMPLER_DESC pointSamplerDesc;
+ pointSamplerDesc.Filter = D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR;
+ pointSamplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
+ pointSamplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
+ pointSamplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
+ pointSamplerDesc.MipLODBias = 0.0f;
+ pointSamplerDesc.MaxAnisotropy = 0;
+ pointSamplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
+ pointSamplerDesc.BorderColor[0] = 0.0f;
+ pointSamplerDesc.BorderColor[1] = 0.0f;
+ pointSamplerDesc.BorderColor[2] = 0.0f;
+ pointSamplerDesc.BorderColor[3] = 0.0f;
+ pointSamplerDesc.MinLOD = 0.0f;
+ pointSamplerDesc.MaxLOD = FLT_MAX;
+
+ ANGLE_TRY(mRenderer->allocateResource(context11, pointSamplerDesc, &mPointSampler));
+ mPointSampler.setInternalName("Blit11PointSampler");
+
+ D3D11_SAMPLER_DESC linearSamplerDesc;
+ linearSamplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
+ linearSamplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
+ linearSamplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
+ linearSamplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
+ linearSamplerDesc.MipLODBias = 0.0f;
+ linearSamplerDesc.MaxAnisotropy = 0;
+ linearSamplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
+ linearSamplerDesc.BorderColor[0] = 0.0f;
+ linearSamplerDesc.BorderColor[1] = 0.0f;
+ linearSamplerDesc.BorderColor[2] = 0.0f;
+ linearSamplerDesc.BorderColor[3] = 0.0f;
+ linearSamplerDesc.MinLOD = 0.0f;
+ linearSamplerDesc.MaxLOD = FLT_MAX;
+
+ ANGLE_TRY(mRenderer->allocateResource(context11, linearSamplerDesc, &mLinearSampler));
+ mLinearSampler.setInternalName("Blit11LinearSampler");
+
+ // Use a rasterizer state that will not cull so that inverted quads will not be culled
+ D3D11_RASTERIZER_DESC rasterDesc;
+ rasterDesc.FillMode = D3D11_FILL_SOLID;
+ rasterDesc.CullMode = D3D11_CULL_NONE;
+ rasterDesc.FrontCounterClockwise = FALSE;
+ rasterDesc.DepthBias = 0;
+ rasterDesc.SlopeScaledDepthBias = 0.0f;
+ rasterDesc.DepthBiasClamp = 0.0f;
+ rasterDesc.DepthClipEnable = TRUE;
+ rasterDesc.MultisampleEnable = FALSE;
+ rasterDesc.AntialiasedLineEnable = FALSE;
+
+ rasterDesc.ScissorEnable = TRUE;
+ ANGLE_TRY(mRenderer->allocateResource(context11, rasterDesc, &mScissorEnabledRasterizerState));
+ mScissorEnabledRasterizerState.setInternalName("Blit11ScissoringRasterizerState");
+
+ rasterDesc.ScissorEnable = FALSE;
+ ANGLE_TRY(mRenderer->allocateResource(context11, rasterDesc, &mScissorDisabledRasterizerState));
+ mScissorDisabledRasterizerState.setInternalName("Blit11NoScissoringRasterizerState");
+
+ D3D11_DEPTH_STENCIL_DESC depthStencilDesc;
+ depthStencilDesc.DepthEnable = TRUE;
+ depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
+ depthStencilDesc.DepthFunc = D3D11_COMPARISON_ALWAYS;
+ depthStencilDesc.StencilEnable = FALSE;
+ depthStencilDesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK;
+ depthStencilDesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK;
+ depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
+ depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
+ depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
+ depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
+ depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
+ depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
+ depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
+ depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
+
+ ANGLE_TRY(mRenderer->allocateResource(context11, depthStencilDesc, &mDepthStencilState));
+ mDepthStencilState.setInternalName("Blit11DepthStencilState");
+
+ D3D11_BUFFER_DESC swizzleBufferDesc;
+ swizzleBufferDesc.ByteWidth = sizeof(unsigned int) * 4;
+ swizzleBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
+ swizzleBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
+ swizzleBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+ swizzleBufferDesc.MiscFlags = 0;
+ swizzleBufferDesc.StructureByteStride = 0;
+
+ ANGLE_TRY(mRenderer->allocateResource(context11, swizzleBufferDesc, &mSwizzleCB));
+ mSwizzleCB.setInternalName("Blit11SwizzleConstantBuffer");
+
+ mResourcesInitialized = true;
+
+ return angle::Result::Continue;
+}
+
+// static
+Blit11::SwizzleShaderType Blit11::GetSwizzleShaderType(GLenum type,
+ D3D11_SRV_DIMENSION dimensionality)
+{
+ switch (dimensionality)
+ {
+ case D3D11_SRV_DIMENSION_TEXTURE2D:
+ switch (type)
+ {
+ case GL_FLOAT:
+ return SWIZZLESHADER_2D_FLOAT;
+ case GL_UNSIGNED_INT:
+ return SWIZZLESHADER_2D_UINT;
+ case GL_INT:
+ return SWIZZLESHADER_2D_INT;
+ default:
+ UNREACHABLE();
+ return SWIZZLESHADER_INVALID;
+ }
+ case D3D11_SRV_DIMENSION_TEXTURECUBE:
+ switch (type)
+ {
+ case GL_FLOAT:
+ return SWIZZLESHADER_CUBE_FLOAT;
+ case GL_UNSIGNED_INT:
+ return SWIZZLESHADER_CUBE_UINT;
+ case GL_INT:
+ return SWIZZLESHADER_CUBE_INT;
+ default:
+ UNREACHABLE();
+ return SWIZZLESHADER_INVALID;
+ }
+ case D3D11_SRV_DIMENSION_TEXTURE3D:
+ switch (type)
+ {
+ case GL_FLOAT:
+ return SWIZZLESHADER_3D_FLOAT;
+ case GL_UNSIGNED_INT:
+ return SWIZZLESHADER_3D_UINT;
+ case GL_INT:
+ return SWIZZLESHADER_3D_INT;
+ default:
+ UNREACHABLE();
+ return SWIZZLESHADER_INVALID;
+ }
+ case D3D11_SRV_DIMENSION_TEXTURE2DARRAY:
+ switch (type)
+ {
+ case GL_FLOAT:
+ return SWIZZLESHADER_ARRAY_FLOAT;
+ case GL_UNSIGNED_INT:
+ return SWIZZLESHADER_ARRAY_UINT;
+ case GL_INT:
+ return SWIZZLESHADER_ARRAY_INT;
+ default:
+ UNREACHABLE();
+ return SWIZZLESHADER_INVALID;
+ }
+ default:
+ UNREACHABLE();
+ return SWIZZLESHADER_INVALID;
+ }
+}
+
+angle::Result Blit11::getShaderSupport(const gl::Context *context,
+ const Shader &shader,
+ Blit11::ShaderSupport *supportOut)
+{
+
+ Context11 *context11 = GetImplAs<Context11>(context);
+
+ switch (shader.dimension)
+ {
+ case SHADER_2D:
+ {
+ ANGLE_TRY(mQuad2DIL.resolve(context11, mRenderer));
+ ANGLE_TRY(mQuad2DVS.resolve(context11, mRenderer));
+ supportOut->inputLayout = &mQuad2DIL.getObj();
+ supportOut->vertexShader = &mQuad2DVS.getObj();
+ supportOut->geometryShader = nullptr;
+ supportOut->vertexWriteFunction = Write2DVertices;
+ break;
+ }
+ case SHADER_3D:
+ case SHADER_2DARRAY:
+ {
+ ANGLE_TRY(mQuad3DIL.resolve(context11, mRenderer));
+ ANGLE_TRY(mQuad3DVS.resolve(context11, mRenderer));
+ ANGLE_TRY(mQuad3DGS.resolve(context11, mRenderer));
+ supportOut->inputLayout = &mQuad3DIL.getObj();
+ supportOut->vertexShader = &mQuad3DVS.getObj();
+ supportOut->geometryShader = &mQuad3DGS.getObj();
+ supportOut->vertexWriteFunction = Write3DVertices;
+ break;
+ }
+ default:
+ UNREACHABLE();
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result Blit11::swizzleTexture(const gl::Context *context,
+ const d3d11::SharedSRV &source,
+ const d3d11::RenderTargetView &dest,
+ const gl::Extents &size,
+ const gl::SwizzleState &swizzleTarget)
+{
+ ANGLE_TRY(initResources(context));
+
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+
+ D3D11_SHADER_RESOURCE_VIEW_DESC sourceSRVDesc;
+ source.get()->GetDesc(&sourceSRVDesc);
+
+ GLenum componentType = d3d11::GetComponentType(sourceSRVDesc.Format);
+ if (componentType == GL_NONE)
+ {
+ // We're swizzling the depth component of a depth-stencil texture.
+ switch (sourceSRVDesc.Format)
+ {
+ case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
+ componentType = GL_UNSIGNED_NORMALIZED;
+ break;
+ case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
+ componentType = GL_FLOAT;
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ }
+
+ GLenum shaderType = GL_NONE;
+ switch (componentType)
+ {
+ case GL_UNSIGNED_NORMALIZED:
+ case GL_SIGNED_NORMALIZED:
+ case GL_FLOAT:
+ shaderType = GL_FLOAT;
+ break;
+ case GL_INT:
+ shaderType = GL_INT;
+ break;
+ case GL_UNSIGNED_INT:
+ shaderType = GL_UNSIGNED_INT;
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ const Shader *shader = nullptr;
+ ANGLE_TRY(getSwizzleShader(context, shaderType, sourceSRVDesc.ViewDimension, &shader));
+
+ // Set vertices
+ D3D11_MAPPED_SUBRESOURCE mappedResource;
+ ANGLE_TRY(mRenderer->mapResource(context, mVertexBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0,
+ &mappedResource));
+
+ ShaderSupport support;
+ ANGLE_TRY(getShaderSupport(context, *shader, &support));
+
+ UINT stride = 0;
+ UINT drawCount = 0;
+ D3D11_PRIMITIVE_TOPOLOGY topology;
+
+ gl::Box area(0, 0, 0, size.width, size.height, size.depth);
+ support.vertexWriteFunction(area, size, area, size, mappedResource.pData, &stride, &drawCount,
+ &topology);
+
+ deviceContext->Unmap(mVertexBuffer.get(), 0);
+
+ // Set constant buffer
+ ANGLE_TRY(mRenderer->mapResource(context, mSwizzleCB.get(), 0, D3D11_MAP_WRITE_DISCARD, 0,
+ &mappedResource));
+
+ unsigned int *swizzleIndices = static_cast<unsigned int *>(mappedResource.pData);
+ swizzleIndices[0] = GetSwizzleIndex(swizzleTarget.swizzleRed);
+ swizzleIndices[1] = GetSwizzleIndex(swizzleTarget.swizzleGreen);
+ swizzleIndices[2] = GetSwizzleIndex(swizzleTarget.swizzleBlue);
+ swizzleIndices[3] = GetSwizzleIndex(swizzleTarget.swizzleAlpha);
+
+ deviceContext->Unmap(mSwizzleCB.get(), 0);
+
+ StateManager11 *stateManager = mRenderer->getStateManager();
+
+ // Apply vertex buffer
+ stateManager->setSingleVertexBuffer(&mVertexBuffer, stride, 0);
+
+ // Apply constant buffer
+ stateManager->setPixelConstantBuffer(0, &mSwizzleCB);
+
+ // Apply state
+ stateManager->setSimpleBlendState(nullptr);
+ stateManager->setDepthStencilState(nullptr, 0xFFFFFFFF);
+ stateManager->setRasterizerState(&mScissorDisabledRasterizerState);
+
+ // Apply shaders
+ stateManager->setInputLayout(support.inputLayout);
+ stateManager->setPrimitiveTopology(topology);
+
+ stateManager->setDrawShaders(support.vertexShader, support.geometryShader,
+ &shader->pixelShader);
+
+ // Apply render target
+ stateManager->setRenderTarget(dest.get(), nullptr);
+
+ // Set the viewport
+ stateManager->setSimpleViewport(size);
+
+ // Apply textures and sampler
+ stateManager->setSimplePixelTextureAndSampler(source, mPointSampler);
+
+ // Draw the quad
+ deviceContext->Draw(drawCount, 0);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Blit11::copyTexture(const gl::Context *context,
+ const d3d11::SharedSRV &source,
+ const gl::Box &sourceArea,
+ const gl::Extents &sourceSize,
+ GLenum sourceFormat,
+ const d3d11::RenderTargetView &dest,
+ const gl::Box &destArea,
+ const gl::Extents &destSize,
+ const gl::Rectangle *scissor,
+ GLenum destFormat,
+ GLenum destTypeForDownsampling,
+ GLenum filter,
+ bool maskOffAlpha,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha)
+{
+ ANGLE_TRY(initResources(context));
+
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+
+ // Determine if the source format is a signed integer format, the destFormat will already
+ // be GL_XXXX_INTEGER but it does not tell us if it is signed or unsigned.
+ D3D11_SHADER_RESOURCE_VIEW_DESC sourceSRVDesc;
+ source.get()->GetDesc(&sourceSRVDesc);
+
+ GLenum componentType = d3d11::GetComponentType(sourceSRVDesc.Format);
+
+ ASSERT(componentType != GL_NONE);
+ ASSERT(componentType != GL_SIGNED_NORMALIZED);
+ bool isSrcSigned = (componentType == GL_INT);
+
+ D3D11_RENDER_TARGET_VIEW_DESC destRTVDesc;
+ dest.get()->GetDesc(&destRTVDesc);
+
+ GLenum destComponentType = d3d11::GetComponentType(destRTVDesc.Format);
+
+ ASSERT(componentType != GL_NONE);
+ bool isDestSigned = (destComponentType == GL_INT);
+
+ ShaderDimension dimension = SHADER_INVALID;
+
+ switch (sourceSRVDesc.ViewDimension)
+ {
+ case D3D11_SRV_DIMENSION_TEXTURE2D:
+ dimension = SHADER_2D;
+ break;
+ case D3D11_SRV_DIMENSION_TEXTURE3D:
+ dimension = SHADER_3D;
+ break;
+ case D3D11_SRV_DIMENSION_TEXTURE2DARRAY:
+ dimension = SHADER_2DARRAY;
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ const Shader *shader = nullptr;
+
+ ANGLE_TRY(getBlitShader(context, destFormat, sourceFormat, isSrcSigned, isDestSigned,
+ unpackPremultiplyAlpha, unpackUnmultiplyAlpha, destTypeForDownsampling,
+ dimension, &shader));
+
+ ShaderSupport support;
+ ANGLE_TRY(getShaderSupport(context, *shader, &support));
+
+ // Set vertices
+ D3D11_MAPPED_SUBRESOURCE mappedResource;
+ ANGLE_TRY(mRenderer->mapResource(context, mVertexBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0,
+ &mappedResource));
+
+ UINT stride = 0;
+ UINT drawCount = 0;
+ D3D11_PRIMITIVE_TOPOLOGY topology;
+
+ support.vertexWriteFunction(sourceArea, sourceSize, destArea, destSize, mappedResource.pData,
+ &stride, &drawCount, &topology);
+
+ deviceContext->Unmap(mVertexBuffer.get(), 0);
+
+ StateManager11 *stateManager = mRenderer->getStateManager();
+
+ // Apply vertex buffer
+ stateManager->setSingleVertexBuffer(&mVertexBuffer, stride, 0);
+
+ // Apply state
+ if (maskOffAlpha)
+ {
+ ANGLE_TRY(mAlphaMaskBlendState.resolve(GetImplAs<Context11>(context), mRenderer));
+ stateManager->setSimpleBlendState(&mAlphaMaskBlendState.getObj());
+ }
+ else
+ {
+ stateManager->setSimpleBlendState(nullptr);
+ }
+ stateManager->setDepthStencilState(nullptr, 0xFFFFFFFF);
+
+ if (scissor)
+ {
+ stateManager->setSimpleScissorRect(*scissor);
+ stateManager->setRasterizerState(&mScissorEnabledRasterizerState);
+ }
+ else
+ {
+ stateManager->setRasterizerState(&mScissorDisabledRasterizerState);
+ }
+
+ // Apply shaders
+ stateManager->setInputLayout(support.inputLayout);
+ stateManager->setPrimitiveTopology(topology);
+
+ stateManager->setDrawShaders(support.vertexShader, support.geometryShader,
+ &shader->pixelShader);
+
+ // Apply render target
+ stateManager->setRenderTarget(dest.get(), nullptr);
+
+ // Set the viewport
+ stateManager->setSimpleViewport(destSize);
+
+ // Apply texture and sampler
+ switch (filter)
+ {
+ case GL_NEAREST:
+ stateManager->setSimplePixelTextureAndSampler(source, mPointSampler);
+ break;
+ case GL_LINEAR:
+ stateManager->setSimplePixelTextureAndSampler(source, mLinearSampler);
+ break;
+
+ default:
+ UNREACHABLE();
+ ANGLE_TRY_HR(GetImplAs<Context11>(context), E_FAIL,
+ "Internal error, unknown blit filter mode.");
+ }
+
+ // Draw the quad
+ deviceContext->Draw(drawCount, 0);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Blit11::copyStencil(const gl::Context *context,
+ 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)
+{
+ return copyDepthStencilImpl(context, source, sourceSubresource, sourceArea, sourceSize, dest,
+ destSubresource, destArea, destSize, scissor, true);
+}
+
+angle::Result Blit11::copyDepth(const gl::Context *context,
+ const d3d11::SharedSRV &source,
+ const gl::Box &sourceArea,
+ const gl::Extents &sourceSize,
+ const d3d11::DepthStencilView &dest,
+ const gl::Box &destArea,
+ const gl::Extents &destSize,
+ const gl::Rectangle *scissor)
+{
+ ANGLE_TRY(initResources(context));
+
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+
+ // Set vertices
+ D3D11_MAPPED_SUBRESOURCE mappedResource;
+ ANGLE_TRY(mRenderer->mapResource(context, mVertexBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0,
+ &mappedResource));
+
+ UINT stride = 0;
+ UINT drawCount = 0;
+ D3D11_PRIMITIVE_TOPOLOGY topology;
+
+ Write2DVertices(sourceArea, sourceSize, destArea, destSize, mappedResource.pData, &stride,
+ &drawCount, &topology);
+
+ deviceContext->Unmap(mVertexBuffer.get(), 0);
+
+ StateManager11 *stateManager = mRenderer->getStateManager();
+
+ // Apply vertex buffer
+ stateManager->setSingleVertexBuffer(&mVertexBuffer, stride, 0);
+
+ // Apply state
+ stateManager->setSimpleBlendState(nullptr);
+ stateManager->setDepthStencilState(&mDepthStencilState, 0xFFFFFFFF);
+
+ if (scissor)
+ {
+ stateManager->setSimpleScissorRect(*scissor);
+ stateManager->setRasterizerState(&mScissorEnabledRasterizerState);
+ }
+ else
+ {
+ stateManager->setRasterizerState(&mScissorDisabledRasterizerState);
+ }
+
+ Context11 *context11 = GetImplAs<Context11>(context);
+
+ ANGLE_TRY(mQuad2DIL.resolve(context11, mRenderer));
+ ANGLE_TRY(mQuad2DVS.resolve(context11, mRenderer));
+ ANGLE_TRY(mDepthPS.resolve(context11, mRenderer));
+
+ // Apply shaders
+ stateManager->setInputLayout(&mQuad2DIL.getObj());
+ stateManager->setPrimitiveTopology(topology);
+
+ stateManager->setDrawShaders(&mQuad2DVS.getObj(), nullptr, &mDepthPS.getObj());
+
+ // Apply render target
+ stateManager->setRenderTarget(nullptr, dest.get());
+
+ // Set the viewport
+ stateManager->setSimpleViewport(destSize);
+
+ // Apply texture and sampler
+ stateManager->setSimplePixelTextureAndSampler(source, mPointSampler);
+
+ // Draw the quad
+ deviceContext->Draw(drawCount, 0);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Blit11::copyDepthStencil(const gl::Context *context,
+ 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)
+{
+ return copyDepthStencilImpl(context, source, sourceSubresource, sourceArea, sourceSize, dest,
+ destSubresource, destArea, destSize, scissor, false);
+}
+
+angle::Result Blit11::copyDepthStencilImpl(const gl::Context *context,
+ 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,
+ bool stencilOnly)
+{
+ 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);
+
+ if (stencilOnly)
+ {
+ 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((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;
+
+ // Stencil is assumed to be 8-bit - currently this is true for all possible formats.
+ copySize = 1;
+ }
+
+ if (srcDXGIFormat != destDXGIFormat)
+ {
+ if (srcDXGIFormat == DXGI_FORMAT_R24G8_TYPELESS)
+ {
+ ASSERT(sourceArea == destArea && sourceSize == destSize && scissor == nullptr);
+ return copyAndConvert(context, source, sourceSubresource, sourceArea, sourceSize, dest,
+ destSubresource, destArea, destSize, scissor, copyOffset,
+ copyOffset, copySize, srcPixelSize, destPixelSize,
+ BlitD24S8ToD32F);
+ }
+ ASSERT(srcDXGIFormat == DXGI_FORMAT_R32G8X24_TYPELESS);
+ return copyAndConvert(context, source, sourceSubresource, sourceArea, sourceSize, dest,
+ destSubresource, destArea, destSize, scissor, copyOffset, copyOffset,
+ copySize, srcPixelSize, destPixelSize, BlitD32FS8ToD32F);
+ }
+
+ return copyAndConvert(context, source, sourceSubresource, sourceArea, sourceSize, dest,
+ destSubresource, destArea, destSize, scissor, copyOffset, copyOffset,
+ copySize, srcPixelSize, destPixelSize, StretchedBlitNearest);
+}
+
+angle::Result Blit11::copyAndConvertImpl(const gl::Context *context,
+ 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(context));
+
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+
+ TextureHelper11 sourceStaging;
+ ANGLE_TRY(mRenderer->createStagingTexture(context, ResourceType::Texture2D,
+ source.getFormatSet(), sourceSize,
+ StagingAccess::READ, &sourceStaging));
+
+ deviceContext->CopySubresourceRegion(sourceStaging.get(), 0, 0, 0, 0, source.get(),
+ sourceSubresource, nullptr);
+
+ D3D11_MAPPED_SUBRESOURCE sourceMapping;
+ ANGLE_TRY(
+ mRenderer->mapResource(context, sourceStaging.get(), 0, D3D11_MAP_READ, 0, &sourceMapping));
+
+ D3D11_MAPPED_SUBRESOURCE destMapping;
+ angle::Result error =
+ mRenderer->mapResource(context, destStaging.get(), 0, D3D11_MAP_WRITE, 0, &destMapping);
+ if (error == angle::Result::Stop)
+ {
+ deviceContext->Unmap(sourceStaging.get(), 0);
+ return error;
+ }
+
+ // Clip dest area to the destination size
+ gl::Rectangle clipRect = gl::Rectangle(0, 0, destSize.width, destSize.height);
+
+ // Clip dest area to the scissor
+ if (scissor)
+ {
+ if (!gl::ClipRectangle(clipRect, *scissor, &clipRect))
+ {
+ return angle::Result::Continue;
+ }
+ }
+
+ convertFunction(sourceArea, destArea, clipRect, sourceSize, sourceMapping.RowPitch,
+ destMapping.RowPitch, readOffset, writeOffset, copySize, srcPixelStride,
+ destPixelStride, static_cast<const uint8_t *>(sourceMapping.pData),
+ static_cast<uint8_t *>(destMapping.pData));
+
+ deviceContext->Unmap(sourceStaging.get(), 0);
+ deviceContext->Unmap(destStaging.get(), 0);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Blit11::copyAndConvert(const gl::Context *context,
+ 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(context));
+
+ 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(mRenderer->createStagingTexture(context, ResourceType::Texture2D, dest.getFormatSet(),
+ destSize, StagingAccess::READ_WRITE, &destStaging));
+
+ deviceContext->CopySubresourceRegion(destStaging.get(), 0, 0, 0, 0, dest.get(), destSubresource,
+ nullptr);
+
+ ANGLE_TRY(copyAndConvertImpl(context, source, sourceSubresource, sourceArea, sourceSize,
+ destStaging, destArea, destSize, scissor, readOffset, writeOffset,
+ copySize, srcPixelStride, destPixelStride, convertFunction));
+
+ // Work around timeouts/TDRs in older NVIDIA drivers.
+ if (mRenderer->getFeatures().depthStencilBlitExtraCopy.enabled)
+ {
+ D3D11_MAPPED_SUBRESOURCE mapped;
+ ANGLE_TRY(
+ mRenderer->mapResource(context, destStaging.get(), 0, D3D11_MAP_READ, 0, &mapped));
+ deviceContext->UpdateSubresource(dest.get(), destSubresource, nullptr, mapped.pData,
+ mapped.RowPitch, mapped.DepthPitch);
+ deviceContext->Unmap(destStaging.get(), 0);
+ }
+ else
+ {
+ deviceContext->CopySubresourceRegion(dest.get(), destSubresource, 0, 0, 0,
+ destStaging.get(), 0, nullptr);
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result Blit11::addBlitShaderToMap(const gl::Context *context,
+ BlitShaderType blitShaderType,
+ ShaderDimension dimension,
+ const ShaderData &shaderData,
+ const char *name)
+{
+ ASSERT(mBlitShaderMap.find(blitShaderType) == mBlitShaderMap.end());
+
+ d3d11::PixelShader ps;
+ ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), shaderData, &ps));
+ ps.setInternalName(name);
+
+ Shader shader;
+ shader.dimension = dimension;
+ shader.pixelShader = std::move(ps);
+
+ mBlitShaderMap[blitShaderType] = std::move(shader);
+ return angle::Result::Continue;
+}
+
+angle::Result Blit11::addSwizzleShaderToMap(const gl::Context *context,
+ SwizzleShaderType swizzleShaderType,
+ ShaderDimension dimension,
+ const ShaderData &shaderData,
+ const char *name)
+{
+ ASSERT(mSwizzleShaderMap.find(swizzleShaderType) == mSwizzleShaderMap.end());
+
+ d3d11::PixelShader ps;
+ ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), shaderData, &ps));
+ ps.setInternalName(name);
+
+ Shader shader;
+ shader.dimension = dimension;
+ shader.pixelShader = std::move(ps);
+
+ mSwizzleShaderMap[swizzleShaderType] = std::move(shader);
+ return angle::Result::Continue;
+}
+
+void Blit11::clearShaderMap()
+{
+ mBlitShaderMap.clear();
+ mSwizzleShaderMap.clear();
+}
+
+Blit11::BlitShaderOperation Blit11::getBlitShaderOperation(GLenum destinationFormat,
+ GLenum sourceFormat,
+ bool isSrcSigned,
+ bool isDestSigned,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha,
+ GLenum destTypeForDownsampling)
+{
+ bool floatToIntBlit =
+ !gl::IsIntegerFormat(sourceFormat) && gl::IsIntegerFormat(destinationFormat);
+
+ if (isSrcSigned)
+ {
+ ASSERT(!unpackPremultiplyAlpha && !unpackUnmultiplyAlpha);
+ switch (destinationFormat)
+ {
+ case GL_RGBA_INTEGER:
+ return RGBAI;
+ case GL_RGB_INTEGER:
+ return RGBI;
+ case GL_RG_INTEGER:
+ return RGI;
+ case GL_RED_INTEGER:
+ return RI;
+ default:
+ UNREACHABLE();
+ return OPERATION_INVALID;
+ }
+ }
+ else if (isDestSigned)
+ {
+ ASSERT(floatToIntBlit);
+
+ switch (destinationFormat)
+ {
+ case GL_RGBA_INTEGER:
+ if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha)
+ {
+ return RGBAF_TOI;
+ }
+ return unpackPremultiplyAlpha ? RGBAF_TOI_PREMULTIPLY : RGBAF_TOI_UNMULTIPLY;
+ case GL_RGB_INTEGER:
+ case GL_RG_INTEGER:
+ case GL_RED_INTEGER:
+ if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha)
+ {
+ return RGBF_TOI;
+ }
+ return unpackPremultiplyAlpha ? RGBF_TOI_PREMULTIPLY : RGBF_TOI_UNMULTIPLY;
+ default:
+ UNREACHABLE();
+ return OPERATION_INVALID;
+ }
+ }
+ else
+ {
+ // Check for the downsample formats first
+ switch (destTypeForDownsampling)
+ {
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ ASSERT(destinationFormat == GL_RGBA && !floatToIntBlit);
+ if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha)
+ {
+ return RGBAF_4444;
+ }
+ else if (unpackPremultiplyAlpha)
+ {
+ return RGBAF_4444_PREMULTIPLY;
+ }
+ else
+ {
+ return RGBAF_4444_UNMULTIPLY;
+ }
+
+ case GL_UNSIGNED_SHORT_5_6_5:
+ ASSERT(destinationFormat == GL_RGB && !floatToIntBlit);
+ if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha)
+ {
+ return RGBF_565;
+ }
+ else
+ {
+ return unpackPremultiplyAlpha ? RGBF_565_PREMULTIPLY : RGBF_565_UNMULTIPLY;
+ }
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha)
+ {
+ return RGBAF_5551;
+ }
+ else
+ {
+ return unpackPremultiplyAlpha ? RGBAF_5551_PREMULTIPLY : RGBAF_5551_UNMULTIPLY;
+ }
+
+ default:
+ // By default, use the regular passthrough/multiply/unmultiply shaders. The above
+ // shaders are only needed for some emulated texture formats.
+ break;
+ }
+
+ if (unpackPremultiplyAlpha != unpackUnmultiplyAlpha || floatToIntBlit)
+ {
+ switch (destinationFormat)
+ {
+ case GL_RGBA:
+ case GL_BGRA_EXT:
+ ASSERT(!floatToIntBlit);
+ return unpackPremultiplyAlpha ? RGBAF_PREMULTIPLY : RGBAF_UNMULTIPLY;
+ case GL_RGB:
+ case GL_RG:
+ case GL_RED:
+ if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha)
+ {
+ return RGBF_TOUI;
+ }
+ else
+ {
+ return unpackPremultiplyAlpha ? RGBF_PREMULTIPLY : RGBF_UNMULTIPLY;
+ }
+ case GL_RGBA_INTEGER:
+ if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha)
+ {
+ return RGBAF_TOUI;
+ }
+ else
+ {
+ return unpackPremultiplyAlpha ? RGBAF_TOUI_PREMULTIPLY
+ : RGBAF_TOUI_UNMULTIPLY;
+ }
+ case GL_RGB_INTEGER:
+ case GL_RG_INTEGER:
+ case GL_RED_INTEGER:
+ if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha)
+ {
+ return RGBF_TOUI;
+ }
+ else
+ {
+ return unpackPremultiplyAlpha ? RGBF_TOUI_PREMULTIPLY
+ : RGBF_TOUI_UNMULTIPLY;
+ }
+ case GL_LUMINANCE:
+ ASSERT(!floatToIntBlit);
+ return unpackPremultiplyAlpha ? LUMAF_PREMULTIPLY : LUMAF_UNMULTIPLY;
+
+ case GL_LUMINANCE_ALPHA:
+ ASSERT(!floatToIntBlit);
+ return unpackPremultiplyAlpha ? LUMAALPHAF_PREMULTIPLY : LUMAALPHAF_UNMULTIPLY;
+ case GL_ALPHA:
+ return ALPHA;
+ default:
+ UNREACHABLE();
+ return OPERATION_INVALID;
+ }
+ }
+ else
+ {
+ switch (destinationFormat)
+ {
+ case GL_RGBA:
+ return RGBAF;
+ case GL_RGBA_INTEGER:
+ return RGBAUI;
+ case GL_BGRA_EXT:
+ return BGRAF;
+ case GL_RGB:
+ return RGBF;
+ case GL_RGB_INTEGER:
+ return RGBUI;
+ case GL_RG:
+ return RGF;
+ case GL_RG_INTEGER:
+ return RGUI;
+ case GL_RED:
+ return RF;
+ case GL_RED_INTEGER:
+ return RUI;
+ case GL_ALPHA:
+ return ALPHA;
+ case GL_LUMINANCE:
+ return LUMA;
+ case GL_LUMINANCE_ALPHA:
+ return LUMAALPHA;
+ default:
+ UNREACHABLE();
+ return OPERATION_INVALID;
+ }
+ }
+ }
+}
+
+angle::Result Blit11::getBlitShader(const gl::Context *context,
+ GLenum destFormat,
+ GLenum sourceFormat,
+ bool isSrcSigned,
+ bool isDestSigned,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha,
+ GLenum destTypeForDownsampling,
+ ShaderDimension dimension,
+ const Shader **shader)
+{
+ BlitShaderOperation blitShaderOperation = OPERATION_INVALID;
+
+ blitShaderOperation = getBlitShaderOperation(destFormat, sourceFormat, isSrcSigned,
+ isDestSigned, unpackPremultiplyAlpha,
+ unpackUnmultiplyAlpha, destTypeForDownsampling);
+
+ BlitShaderType blitShaderType = BLITSHADER_INVALID;
+
+ blitShaderType = getBlitShaderType(blitShaderOperation, dimension);
+
+ ANGLE_CHECK_HR(GetImplAs<Context11>(context), blitShaderType != BLITSHADER_INVALID,
+ "Internal blit shader type mismatch", E_FAIL);
+
+ auto blitShaderIt = mBlitShaderMap.find(blitShaderType);
+ if (blitShaderIt != mBlitShaderMap.end())
+ {
+ *shader = &blitShaderIt->second;
+ return angle::Result::Continue;
+ }
+
+ ASSERT(dimension == SHADER_2D || mRenderer->isES3Capable());
+
+ ANGLE_TRY(mapBlitShader(context, blitShaderType));
+
+ blitShaderIt = mBlitShaderMap.find(blitShaderType);
+ ASSERT(blitShaderIt != mBlitShaderMap.end());
+ *shader = &blitShaderIt->second;
+ return angle::Result::Continue;
+}
+
+angle::Result Blit11::getSwizzleShader(const gl::Context *context,
+ GLenum type,
+ D3D11_SRV_DIMENSION viewDimension,
+ const Shader **shader)
+{
+ SwizzleShaderType swizzleShaderType = GetSwizzleShaderType(type, viewDimension);
+
+ ANGLE_CHECK_HR(GetImplAs<Context11>(context), swizzleShaderType != SWIZZLESHADER_INVALID,
+ "Swizzle shader type not found", E_FAIL);
+
+ auto swizzleShaderIt = mSwizzleShaderMap.find(swizzleShaderType);
+ if (swizzleShaderIt != mSwizzleShaderMap.end())
+ {
+ *shader = &swizzleShaderIt->second;
+ return angle::Result::Continue;
+ }
+
+ // Swizzling shaders (OpenGL ES 3+)
+ ASSERT(mRenderer->isES3Capable());
+
+ switch (swizzleShaderType)
+ {
+ case SWIZZLESHADER_2D_FLOAT:
+ ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_2D,
+ ShaderData(g_PS_SwizzleF2D),
+ "Blit11 2D F swizzle pixel shader"));
+ break;
+ case SWIZZLESHADER_2D_UINT:
+ ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_2D,
+ ShaderData(g_PS_SwizzleUI2D),
+ "Blit11 2D UI swizzle pixel shader"));
+ break;
+ case SWIZZLESHADER_2D_INT:
+ ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_2D,
+ ShaderData(g_PS_SwizzleI2D),
+ "Blit11 2D I swizzle pixel shader"));
+ break;
+ case SWIZZLESHADER_CUBE_FLOAT:
+ ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_3D,
+ ShaderData(g_PS_SwizzleF2DArray),
+ "Blit11 2D Cube F swizzle pixel shader"));
+ break;
+ case SWIZZLESHADER_CUBE_UINT:
+ ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_3D,
+ ShaderData(g_PS_SwizzleUI2DArray),
+ "Blit11 2D Cube UI swizzle pixel shader"));
+ break;
+ case SWIZZLESHADER_CUBE_INT:
+ ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_3D,
+ ShaderData(g_PS_SwizzleI2DArray),
+ "Blit11 2D Cube I swizzle pixel shader"));
+ break;
+ case SWIZZLESHADER_3D_FLOAT:
+ ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_3D,
+ ShaderData(g_PS_SwizzleF3D),
+ "Blit11 3D F swizzle pixel shader"));
+ break;
+ case SWIZZLESHADER_3D_UINT:
+ ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_3D,
+ ShaderData(g_PS_SwizzleUI3D),
+ "Blit11 3D UI swizzle pixel shader"));
+ break;
+ case SWIZZLESHADER_3D_INT:
+ ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_3D,
+ ShaderData(g_PS_SwizzleI3D),
+ "Blit11 3D I swizzle pixel shader"));
+ break;
+ case SWIZZLESHADER_ARRAY_FLOAT:
+ ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_3D,
+ ShaderData(g_PS_SwizzleF2DArray),
+ "Blit11 2D Array F swizzle pixel shader"));
+ break;
+ case SWIZZLESHADER_ARRAY_UINT:
+ ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_3D,
+ ShaderData(g_PS_SwizzleUI2DArray),
+ "Blit11 2D Array UI swizzle pixel shader"));
+ break;
+ case SWIZZLESHADER_ARRAY_INT:
+ ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_3D,
+ ShaderData(g_PS_SwizzleI2DArray),
+ "Blit11 2D Array I swizzle pixel shader"));
+ break;
+ default:
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
+ }
+
+ swizzleShaderIt = mSwizzleShaderMap.find(swizzleShaderType);
+ ASSERT(swizzleShaderIt != mSwizzleShaderMap.end());
+ *shader = &swizzleShaderIt->second;
+ return angle::Result::Continue;
+}
+
+angle::Result Blit11::resolveDepth(const gl::Context *context,
+ RenderTarget11 *depth,
+ TextureHelper11 *textureOut)
+{
+ ANGLE_TRY(initResources(context));
+
+ // Multisampled depth stencil SRVs are not available in feature level 10.0
+ ASSERT(mRenderer->getRenderer11DeviceCaps().featureLevel > D3D_FEATURE_LEVEL_10_0);
+
+ const auto &extents = depth->getExtents();
+ auto *deviceContext = mRenderer->getDeviceContext();
+ auto *stateManager = mRenderer->getStateManager();
+
+ ANGLE_TRY(initResolveDepthOnly(context, depth->getFormatSet(), extents));
+
+ Context11 *context11 = GetImplAs<Context11>(context);
+
+ ANGLE_TRY(mResolveDepthStencilVS.resolve(context11, mRenderer));
+ ANGLE_TRY(mResolveDepthPS.resolve(context11, mRenderer));
+
+ // Apply the necessary state changes to the D3D11 immediate device context.
+ stateManager->setInputLayout(nullptr);
+ stateManager->setPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
+ stateManager->setDrawShaders(&mResolveDepthStencilVS.getObj(), nullptr,
+ &mResolveDepthPS.getObj());
+ stateManager->setRasterizerState(nullptr);
+ stateManager->setDepthStencilState(&mDepthStencilState, 0xFFFFFFFF);
+ stateManager->setRenderTargets(nullptr, 0, mResolvedDepthDSView.get());
+ stateManager->setSimpleBlendState(nullptr);
+ stateManager->setSimpleViewport(extents);
+
+ // Set the viewport
+ const d3d11::SharedSRV *srv;
+ ANGLE_TRY(depth->getShaderResourceView(context, &srv));
+
+ stateManager->setShaderResourceShared(gl::ShaderType::Fragment, 0, srv);
+
+ // Trigger the blit on the GPU.
+ deviceContext->Draw(6, 0);
+
+ *textureOut = mResolvedDepth;
+ return angle::Result::Continue;
+}
+
+angle::Result Blit11::initResolveDepthOnly(const gl::Context *context,
+ const d3d11::Format &format,
+ const gl::Extents &extents)
+{
+ if (mResolvedDepth.valid() && extents == mResolvedDepth.getExtents() &&
+ format.texFormat == mResolvedDepth.getFormat())
+ {
+ return angle::Result::Continue;
+ }
+
+ D3D11_TEXTURE2D_DESC textureDesc;
+ textureDesc.Width = extents.width;
+ textureDesc.Height = extents.height;
+ textureDesc.MipLevels = 1;
+ textureDesc.ArraySize = 1;
+ textureDesc.Format = format.texFormat;
+ textureDesc.SampleDesc.Count = 1;
+ textureDesc.SampleDesc.Quality = 0;
+ textureDesc.Usage = D3D11_USAGE_DEFAULT;
+ textureDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE;
+ textureDesc.CPUAccessFlags = 0;
+ textureDesc.MiscFlags = 0;
+
+ Context11 *context11 = GetImplAs<Context11>(context);
+
+ ANGLE_TRY(mRenderer->allocateTexture(context11, textureDesc, format, &mResolvedDepth));
+ mResolvedDepth.setInternalName("Blit11::mResolvedDepth");
+
+ D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
+ dsvDesc.Flags = 0;
+ dsvDesc.Format = format.dsvFormat;
+ dsvDesc.Texture2D.MipSlice = 0;
+ dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
+
+ ANGLE_TRY(mRenderer->allocateResource(context11, dsvDesc, mResolvedDepth.get(),
+ &mResolvedDepthDSView));
+ mResolvedDepthDSView.setInternalName("Blit11::mResolvedDepthDSView");
+
+ // Possibly D3D11 bug or undefined behaviour: Clear the DSV so that our first render
+ // works as expected. Otherwise the results of the first use seem to be incorrect.
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+ deviceContext->ClearDepthStencilView(mResolvedDepthDSView.get(), D3D11_CLEAR_DEPTH, 1.0f, 0);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Blit11::initResolveDepthStencil(const gl::Context *context,
+ const gl::Extents &extents)
+{
+ // Check if we need to recreate depth stencil view
+ if (mResolvedDepthStencil.valid() && extents == mResolvedDepthStencil.getExtents())
+ {
+ ASSERT(mResolvedDepthStencil.getFormat() == DXGI_FORMAT_R32G32_FLOAT);
+ return angle::Result::Continue;
+ }
+
+ 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;
+
+ Context11 *context11 = GetImplAs<Context11>(context);
+
+ ANGLE_TRY(
+ mRenderer->allocateTexture(context11, textureDesc, formatSet, &mResolvedDepthStencil));
+ mResolvedDepthStencil.setInternalName("Blit11::mResolvedDepthStencil");
+
+ ANGLE_TRY(mRenderer->allocateResourceNoDesc(context11, mResolvedDepthStencil.get(),
+ &mResolvedDepthStencilRTView));
+ mResolvedDepthStencilRTView.setInternalName("Blit11::mResolvedDepthStencilRTView");
+
+ return angle::Result::Continue;
+}
+
+angle::Result Blit11::resolveStencil(const gl::Context *context,
+ RenderTarget11 *depthStencil,
+ bool alsoDepth,
+ TextureHelper11 *textureOut)
+{
+ ANGLE_TRY(initResources(context));
+
+ // Multisampled depth stencil SRVs are not available in feature level 10.0
+ ASSERT(mRenderer->getRenderer11DeviceCaps().featureLevel > D3D_FEATURE_LEVEL_10_0);
+
+ const auto &extents = depthStencil->getExtents();
+
+ ANGLE_TRY(initResolveDepthStencil(context, extents));
+
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+ auto *stateManager = mRenderer->getStateManager();
+ ID3D11Resource *stencilResource = depthStencil->getTexture().get();
+
+ // Check if we need to re-create the stencil SRV.
+ if (mStencilSRV.valid())
+ {
+ ID3D11Resource *priorResource = nullptr;
+ mStencilSRV.get()->GetResource(&priorResource);
+
+ if (stencilResource != priorResource)
+ {
+ mStencilSRV.reset();
+ }
+
+ SafeRelease(priorResource);
+ }
+
+ Context11 *context11 = GetImplAs<Context11>(context);
+
+ if (!mStencilSRV.valid())
+ {
+ D3D11_SHADER_RESOURCE_VIEW_DESC srViewDesc;
+ srViewDesc.Format = GetStencilSRVFormat(depthStencil->getFormatSet());
+ srViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS;
+
+ ANGLE_TRY(
+ mRenderer->allocateResource(context11, srViewDesc, stencilResource, &mStencilSRV));
+ mStencilSRV.setInternalName("Blit11::mStencilSRV");
+ }
+
+ // Notify the Renderer that all state should be invalidated.
+ ANGLE_TRY(mResolveDepthStencilVS.resolve(context11, mRenderer));
+
+ // 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.
+ const d3d11::PixelShader *pixelShader = nullptr;
+ if (alsoDepth)
+ {
+ ANGLE_TRY(mResolveDepthStencilPS.resolve(context11, mRenderer));
+ pixelShader = &mResolveDepthStencilPS.getObj();
+ }
+ else
+ {
+ ANGLE_TRY(mResolveStencilPS.resolve(context11, mRenderer));
+ pixelShader = &mResolveStencilPS.getObj();
+ }
+
+ // Apply the necessary state changes to the D3D11 immediate device context.
+ stateManager->setInputLayout(nullptr);
+ stateManager->setPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
+ stateManager->setDrawShaders(&mResolveDepthStencilVS.getObj(), nullptr, pixelShader);
+ stateManager->setRasterizerState(nullptr);
+ stateManager->setDepthStencilState(nullptr, 0xFFFFFFFF);
+ stateManager->setRenderTarget(mResolvedDepthStencilRTView.get(), nullptr);
+ stateManager->setSimpleBlendState(nullptr);
+
+ // Set the viewport
+ stateManager->setSimpleViewport(extents);
+ const d3d11::SharedSRV *srv;
+ ANGLE_TRY(depthStencil->getShaderResourceView(context, &srv));
+ stateManager->setShaderResourceShared(gl::ShaderType::Fragment, 0, srv);
+ stateManager->setShaderResource(gl::ShaderType::Fragment, 1, &mStencilSRV);
+
+ // Trigger the blit on the GPU.
+ deviceContext->Draw(6, 0);
+
+ gl::Box copyBox(0, 0, 0, extents.width, extents.height, 1);
+
+ ANGLE_TRY(mRenderer->createStagingTexture(context, ResourceType::Texture2D,
+ depthStencil->getFormatSet(), extents,
+ StagingAccess::READ_WRITE, textureOut));
+
+ const auto &copyFunction = GetCopyDepthStencilFunction(depthStencil->getInternalFormat());
+ const auto &dsFormatSet = depthStencil->getFormatSet();
+ const auto &dsDxgiInfo = d3d11::GetDXGIFormatSizeInfo(dsFormatSet.texFormat);
+
+ ANGLE_TRY(copyAndConvertImpl(context, mResolvedDepthStencil, 0, copyBox, extents, *textureOut,
+ copyBox, extents, nullptr, 0, 0, 0, 8u, dsDxgiInfo.pixelBytes,
+ copyFunction));
+
+ return angle::Result::Continue;
+}
+
+void Blit11::releaseResolveDepthStencilResources()
+{
+ mStencilSRV.reset();
+ mResolvedDepthStencilRTView.reset();
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Blit11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Blit11.h
new file mode 100644
index 0000000000..cef491137d
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Blit11.h
@@ -0,0 +1,300 @@
+//
+// Copyright 2013 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.
+//
+
+// Blit11.cpp: Texture copy utility class.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_BLIT11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_BLIT11_H_
+
+#include "common/angleutils.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/renderer/d3d/d3d11/ResourceManager11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+
+#include <map>
+
+namespace rx
+{
+class Renderer11;
+
+class Blit11 : angle::NonCopyable
+{
+ public:
+ explicit Blit11(Renderer11 *renderer);
+ ~Blit11();
+
+ angle::Result swizzleTexture(const gl::Context *context,
+ const d3d11::SharedSRV &source,
+ const d3d11::RenderTargetView &dest,
+ const gl::Extents &size,
+ const gl::SwizzleState &swizzleTarget);
+
+ // Set destTypeForDownsampling to GL_NONE to skip downsampling
+ angle::Result copyTexture(const gl::Context *context,
+ const d3d11::SharedSRV &source,
+ const gl::Box &sourceArea,
+ const gl::Extents &sourceSize,
+ GLenum sourceFormat,
+ const d3d11::RenderTargetView &dest,
+ const gl::Box &destArea,
+ const gl::Extents &destSize,
+ const gl::Rectangle *scissor,
+ GLenum destFormat,
+ GLenum destTypeForDownsampling,
+ GLenum filter,
+ bool maskOffAlpha,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha);
+
+ angle::Result copyStencil(const gl::Context *context,
+ 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);
+
+ angle::Result copyDepth(const gl::Context *context,
+ const d3d11::SharedSRV &source,
+ const gl::Box &sourceArea,
+ const gl::Extents &sourceSize,
+ const d3d11::DepthStencilView &dest,
+ const gl::Box &destArea,
+ const gl::Extents &destSize,
+ const gl::Rectangle *scissor);
+
+ angle::Result copyDepthStencil(const gl::Context *context,
+ 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);
+
+ angle::Result resolveDepth(const gl::Context *context,
+ RenderTarget11 *depth,
+ TextureHelper11 *textureOut);
+
+ angle::Result resolveStencil(const gl::Context *context,
+ RenderTarget11 *depthStencil,
+ bool alsoDepth,
+ TextureHelper11 *textureOut);
+
+ 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 BlitShaderOperation : unsigned int;
+ enum BlitShaderType : unsigned int;
+ enum SwizzleShaderType
+ {
+ SWIZZLESHADER_INVALID,
+ SWIZZLESHADER_2D_FLOAT,
+ SWIZZLESHADER_2D_UINT,
+ SWIZZLESHADER_2D_INT,
+ SWIZZLESHADER_CUBE_FLOAT,
+ SWIZZLESHADER_CUBE_UINT,
+ SWIZZLESHADER_CUBE_INT,
+ SWIZZLESHADER_3D_FLOAT,
+ SWIZZLESHADER_3D_UINT,
+ SWIZZLESHADER_3D_INT,
+ SWIZZLESHADER_ARRAY_FLOAT,
+ SWIZZLESHADER_ARRAY_UINT,
+ SWIZZLESHADER_ARRAY_INT,
+ };
+
+ typedef void (*WriteVertexFunction)(const gl::Box &sourceArea,
+ const gl::Extents &sourceSize,
+ const gl::Box &destArea,
+ const gl::Extents &destSize,
+ void *outVertices,
+ unsigned int *outStride,
+ unsigned int *outVertexCount,
+ D3D11_PRIMITIVE_TOPOLOGY *outTopology);
+
+ enum ShaderDimension
+ {
+ SHADER_INVALID,
+ SHADER_2D,
+ SHADER_3D,
+ SHADER_2DARRAY
+ };
+
+ struct Shader
+ {
+ Shader();
+ Shader(Shader &&other);
+ ~Shader();
+ Shader &operator=(Shader &&other);
+
+ ShaderDimension dimension;
+ d3d11::PixelShader pixelShader;
+ };
+
+ struct ShaderSupport
+ {
+ const d3d11::InputLayout *inputLayout;
+ const d3d11::VertexShader *vertexShader;
+ const d3d11::GeometryShader *geometryShader;
+ WriteVertexFunction vertexWriteFunction;
+ };
+
+ angle::Result initResources(const gl::Context *context);
+
+ angle::Result getShaderSupport(const gl::Context *context,
+ const Shader &shader,
+ ShaderSupport *supportOut);
+
+ static BlitShaderOperation getBlitShaderOperation(GLenum destinationFormat,
+ GLenum sourceFormat,
+ bool isSrcSigned,
+ bool isDestSigned,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha,
+ GLenum destTypeForDownsampling);
+
+ static BlitShaderType getBlitShaderType(BlitShaderOperation operation,
+ ShaderDimension dimension);
+
+ static SwizzleShaderType GetSwizzleShaderType(GLenum type, D3D11_SRV_DIMENSION dimensionality);
+
+ angle::Result copyDepthStencilImpl(const gl::Context *context,
+ 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,
+ bool stencilOnly);
+
+ angle::Result copyAndConvertImpl(const gl::Context *context,
+ 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::Result copyAndConvert(const gl::Context *context,
+ 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::Result mapBlitShader(const gl::Context *context, BlitShaderType blitShaderType);
+ angle::Result addBlitShaderToMap(const gl::Context *context,
+ BlitShaderType blitShaderType,
+ ShaderDimension dimension,
+ const ShaderData &shaderData,
+ const char *name);
+
+ angle::Result getBlitShader(const gl::Context *context,
+ GLenum destFormat,
+ GLenum sourceFormat,
+ bool isSrcSigned,
+ bool isDestSigned,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha,
+ GLenum destTypeForDownsampling,
+ ShaderDimension dimension,
+ const Shader **shaderOut);
+ angle::Result getSwizzleShader(const gl::Context *context,
+ GLenum type,
+ D3D11_SRV_DIMENSION viewDimension,
+ const Shader **shaderOut);
+
+ angle::Result addSwizzleShaderToMap(const gl::Context *context,
+ SwizzleShaderType swizzleShaderType,
+ ShaderDimension dimension,
+ const ShaderData &shaderData,
+ const char *name);
+
+ void clearShaderMap();
+ void releaseResolveDepthStencilResources();
+ angle::Result initResolveDepthOnly(const gl::Context *context,
+ const d3d11::Format &format,
+ const gl::Extents &extents);
+ angle::Result initResolveDepthStencil(const gl::Context *context, const gl::Extents &extents);
+
+ Renderer11 *mRenderer;
+
+ std::map<BlitShaderType, Shader> mBlitShaderMap;
+ std::map<SwizzleShaderType, Shader> mSwizzleShaderMap;
+
+ bool mResourcesInitialized;
+ d3d11::Buffer mVertexBuffer;
+ d3d11::SamplerState mPointSampler;
+ d3d11::SamplerState mLinearSampler;
+ d3d11::RasterizerState mScissorEnabledRasterizerState;
+ d3d11::RasterizerState mScissorDisabledRasterizerState;
+ d3d11::DepthStencilState mDepthStencilState;
+
+ d3d11::LazyInputLayout mQuad2DIL;
+ d3d11::LazyShader<ID3D11VertexShader> mQuad2DVS;
+ d3d11::LazyShader<ID3D11PixelShader> mDepthPS;
+
+ d3d11::LazyInputLayout mQuad3DIL;
+ d3d11::LazyShader<ID3D11VertexShader> mQuad3DVS;
+ d3d11::LazyShader<ID3D11GeometryShader> mQuad3DGS;
+
+ d3d11::LazyBlendState mAlphaMaskBlendState;
+
+ d3d11::Buffer mSwizzleCB;
+
+ d3d11::LazyShader<ID3D11VertexShader> mResolveDepthStencilVS;
+ d3d11::LazyShader<ID3D11PixelShader> mResolveDepthPS;
+ d3d11::LazyShader<ID3D11PixelShader> mResolveDepthStencilPS;
+ d3d11::LazyShader<ID3D11PixelShader> mResolveStencilPS;
+ d3d11::ShaderResourceView mStencilSRV;
+ TextureHelper11 mResolvedDepthStencil;
+ d3d11::RenderTargetView mResolvedDepthStencilRTView;
+ TextureHelper11 mResolvedDepth;
+ d3d11::DepthStencilView mResolvedDepthDSView;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D11_BLIT11_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Blit11Helper_autogen.inc b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Blit11Helper_autogen.inc
new file mode 100644
index 0000000000..64d8106a18
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Blit11Helper_autogen.inc
@@ -0,0 +1,1575 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_blit11helper.py.
+//
+// Copyright 2018 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.
+//
+// Blit11Helper_autogen.inc:
+// Defines and retrieves blitshaders for the D3D11 backend.
+
+namespace
+{
+// Include inline shaders in the anonymous namespace to make sure no symbols are exported
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2d11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2d11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2d11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrougha2d11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum2d11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha2d11ps.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/passthroughrgb2dui11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2di11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2dui11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2di11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2dui11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2di11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_2d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_2d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_2d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_2d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgba_2d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgba_2d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgba_2d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgb_2d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgb_2d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgb_2d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_luma_2d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_luma_2d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_lumaalpha_2d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_lumaalpha_2d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d_4444_11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_4444_2d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_4444_2d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2d_565_11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_565_2d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_565_2d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d_5551_11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_5551_2d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_5551_2d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3d11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3d11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3d11ps.h"
+#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/passthroughrgba3dui11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3di11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3dui11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3di11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3dui11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3di11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3dui11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3di11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_3d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_3d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_3d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_3d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgba_3d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgba_3d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgba_3d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgb_3d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgb_3d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgb_3d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pt_rgba_3d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pm_rgba_3d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_um_rgba_3d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pt_rgb_3d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pm_rgb_3d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_um_rgb_3d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_luma_3d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_luma_3d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_lumaalpha_3d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_lumaalpha_3d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d_4444_11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_4444_3d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_4444_3d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3d_565_11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_565_3d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_565_3d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d_5551_11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_5551_3d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_5551_3d_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darray11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2darray11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2darray11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2darray11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum2darray11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha2darray11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darrayui11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darrayi11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2darrayui11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2darrayi11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2darrayui11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2darrayi11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2darrayui11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2darrayi11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_2darray_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_2darray_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_2darray_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_2darray_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgba_2darray_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgba_2darray_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgba_2darray_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgb_2darray_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgb_2darray_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgb_2darray_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pt_rgba_2darray_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pm_rgba_2darray_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_um_rgba_2darray_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pt_rgb_2darray_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pm_rgb_2darray_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_um_rgb_2darray_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_luma_2darray_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_luma_2darray_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_lumaalpha_2darray_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_lumaalpha_2darray_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darray_4444_11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_4444_2darray_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_4444_2darray_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2darray_565_11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_565_2darray_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_565_2darray_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darray_5551_11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_5551_2darray_ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_5551_2darray_ps.h"
+} // namespace
+
+enum Blit11::BlitShaderOperation : unsigned int
+{
+ RGBAF,
+ BGRAF,
+ RGBF,
+ RGF,
+ RF,
+ ALPHA,
+ LUMA,
+ LUMAALPHA,
+ RGBAUI,
+ RGBAI,
+ RGBUI,
+ RGBI,
+ RGUI,
+ RGI,
+ RUI,
+ RI,
+ RGBAF_PREMULTIPLY,
+ RGBAF_UNMULTIPLY,
+ RGBF_PREMULTIPLY,
+ RGBF_UNMULTIPLY,
+ RGBAF_TOUI,
+ RGBAF_TOUI_PREMULTIPLY,
+ RGBAF_TOUI_UNMULTIPLY,
+ RGBF_TOUI,
+ RGBF_TOUI_PREMULTIPLY,
+ RGBF_TOUI_UNMULTIPLY,
+ RGBAF_TOI,
+ RGBAF_TOI_PREMULTIPLY,
+ RGBAF_TOI_UNMULTIPLY,
+ RGBF_TOI,
+ RGBF_TOI_PREMULTIPLY,
+ RGBF_TOI_UNMULTIPLY,
+ LUMAF_PREMULTIPLY,
+ LUMAF_UNMULTIPLY,
+ LUMAALPHAF_PREMULTIPLY,
+ LUMAALPHAF_UNMULTIPLY,
+ RGBAF_4444,
+ RGBAF_4444_PREMULTIPLY,
+ RGBAF_4444_UNMULTIPLY,
+ RGBF_565,
+ RGBF_565_PREMULTIPLY,
+ RGBF_565_UNMULTIPLY,
+ RGBAF_5551,
+ RGBAF_5551_PREMULTIPLY,
+ RGBAF_5551_UNMULTIPLY,
+ OPERATION_INVALID
+};
+
+enum Blit11::BlitShaderType : unsigned int
+{
+ BLITSHADER_2D_RGBAF,
+ BLITSHADER_2D_BGRAF,
+ BLITSHADER_2D_RGBF,
+ BLITSHADER_2D_RGF,
+ BLITSHADER_2D_RF,
+ BLITSHADER_2D_ALPHA,
+ BLITSHADER_2D_LUMA,
+ BLITSHADER_2D_LUMAALPHA,
+ BLITSHADER_2D_RGBAUI,
+ BLITSHADER_2D_RGBAI,
+ BLITSHADER_2D_RGBUI,
+ BLITSHADER_2D_RGBI,
+ BLITSHADER_2D_RGUI,
+ BLITSHADER_2D_RGI,
+ BLITSHADER_2D_RUI,
+ BLITSHADER_2D_RI,
+ BLITSHADER_2D_RGBAF_PREMULTIPLY,
+ BLITSHADER_2D_RGBAF_UNMULTIPLY,
+ BLITSHADER_2D_RGBF_PREMULTIPLY,
+ BLITSHADER_2D_RGBF_UNMULTIPLY,
+ BLITSHADER_2D_RGBAF_TOUI,
+ BLITSHADER_2D_RGBAF_TOUI_PREMULTIPLY,
+ BLITSHADER_2D_RGBAF_TOUI_UNMULTIPLY,
+ BLITSHADER_2D_RGBF_TOUI,
+ BLITSHADER_2D_RGBF_TOUI_PREMULTIPLY,
+ BLITSHADER_2D_RGBF_TOUI_UNMULTIPLY,
+ BLITSHADER_2D_LUMAF_PREMULTIPLY,
+ BLITSHADER_2D_LUMAF_UNMULTIPLY,
+ BLITSHADER_2D_LUMAALPHAF_PREMULTIPLY,
+ BLITSHADER_2D_LUMAALPHAF_UNMULTIPLY,
+ BLITSHADER_2D_RGBAF_4444,
+ BLITSHADER_2D_RGBAF_4444_PREMULTIPLY,
+ BLITSHADER_2D_RGBAF_4444_UNMULTIPLY,
+ BLITSHADER_2D_RGBF_565,
+ BLITSHADER_2D_RGBF_565_PREMULTIPLY,
+ BLITSHADER_2D_RGBF_565_UNMULTIPLY,
+ BLITSHADER_2D_RGBAF_5551,
+ BLITSHADER_2D_RGBAF_5551_PREMULTIPLY,
+ BLITSHADER_2D_RGBAF_5551_UNMULTIPLY,
+ BLITSHADER_3D_RGBAF,
+ BLITSHADER_3D_BGRAF,
+ BLITSHADER_3D_RGBF,
+ BLITSHADER_3D_RGF,
+ BLITSHADER_3D_RF,
+ BLITSHADER_3D_ALPHA,
+ BLITSHADER_3D_LUMA,
+ BLITSHADER_3D_LUMAALPHA,
+ BLITSHADER_3D_RGBAUI,
+ BLITSHADER_3D_RGBAI,
+ BLITSHADER_3D_RGBUI,
+ BLITSHADER_3D_RGBI,
+ BLITSHADER_3D_RGUI,
+ BLITSHADER_3D_RGI,
+ BLITSHADER_3D_RUI,
+ BLITSHADER_3D_RI,
+ BLITSHADER_3D_RGBAF_PREMULTIPLY,
+ BLITSHADER_3D_RGBAF_UNMULTIPLY,
+ BLITSHADER_3D_RGBF_PREMULTIPLY,
+ BLITSHADER_3D_RGBF_UNMULTIPLY,
+ BLITSHADER_3D_RGBAF_TOUI,
+ BLITSHADER_3D_RGBAF_TOUI_PREMULTIPLY,
+ BLITSHADER_3D_RGBAF_TOUI_UNMULTIPLY,
+ BLITSHADER_3D_RGBF_TOUI,
+ BLITSHADER_3D_RGBF_TOUI_PREMULTIPLY,
+ BLITSHADER_3D_RGBF_TOUI_UNMULTIPLY,
+ BLITSHADER_3D_RGBAF_TOI,
+ BLITSHADER_3D_RGBAF_TOI_PREMULTIPLY,
+ BLITSHADER_3D_RGBAF_TOI_UNMULTIPLY,
+ BLITSHADER_3D_RGBF_TOI,
+ BLITSHADER_3D_RGBF_TOI_PREMULTIPLY,
+ BLITSHADER_3D_RGBF_TOI_UNMULTIPLY,
+ BLITSHADER_3D_LUMAF_PREMULTIPLY,
+ BLITSHADER_3D_LUMAF_UNMULTIPLY,
+ BLITSHADER_3D_LUMAALPHAF_PREMULTIPLY,
+ BLITSHADER_3D_LUMAALPHAF_UNMULTIPLY,
+ BLITSHADER_3D_RGBAF_4444,
+ BLITSHADER_3D_RGBAF_4444_PREMULTIPLY,
+ BLITSHADER_3D_RGBAF_4444_UNMULTIPLY,
+ BLITSHADER_3D_RGBF_565,
+ BLITSHADER_3D_RGBF_565_PREMULTIPLY,
+ BLITSHADER_3D_RGBF_565_UNMULTIPLY,
+ BLITSHADER_3D_RGBAF_5551,
+ BLITSHADER_3D_RGBAF_5551_PREMULTIPLY,
+ BLITSHADER_3D_RGBAF_5551_UNMULTIPLY,
+ BLITSHADER_2DARRAY_RGBAF,
+ BLITSHADER_2DARRAY_BGRAF,
+ BLITSHADER_2DARRAY_RGBF,
+ BLITSHADER_2DARRAY_RGF,
+ BLITSHADER_2DARRAY_RF,
+ BLITSHADER_2DARRAY_ALPHA,
+ BLITSHADER_2DARRAY_LUMA,
+ BLITSHADER_2DARRAY_LUMAALPHA,
+ BLITSHADER_2DARRAY_RGBAUI,
+ BLITSHADER_2DARRAY_RGBAI,
+ BLITSHADER_2DARRAY_RGBUI,
+ BLITSHADER_2DARRAY_RGBI,
+ BLITSHADER_2DARRAY_RGUI,
+ BLITSHADER_2DARRAY_RGI,
+ BLITSHADER_2DARRAY_RUI,
+ BLITSHADER_2DARRAY_RI,
+ BLITSHADER_2DARRAY_RGBAF_PREMULTIPLY,
+ BLITSHADER_2DARRAY_RGBAF_UNMULTIPLY,
+ BLITSHADER_2DARRAY_RGBF_PREMULTIPLY,
+ BLITSHADER_2DARRAY_RGBF_UNMULTIPLY,
+ BLITSHADER_2DARRAY_RGBAF_TOUI,
+ BLITSHADER_2DARRAY_RGBAF_TOUI_PREMULTIPLY,
+ BLITSHADER_2DARRAY_RGBAF_TOUI_UNMULTIPLY,
+ BLITSHADER_2DARRAY_RGBF_TOUI,
+ BLITSHADER_2DARRAY_RGBF_TOUI_PREMULTIPLY,
+ BLITSHADER_2DARRAY_RGBF_TOUI_UNMULTIPLY,
+ BLITSHADER_2DARRAY_RGBAF_TOI,
+ BLITSHADER_2DARRAY_RGBAF_TOI_PREMULTIPLY,
+ BLITSHADER_2DARRAY_RGBAF_TOI_UNMULTIPLY,
+ BLITSHADER_2DARRAY_RGBF_TOI,
+ BLITSHADER_2DARRAY_RGBF_TOI_PREMULTIPLY,
+ BLITSHADER_2DARRAY_RGBF_TOI_UNMULTIPLY,
+ BLITSHADER_2DARRAY_LUMAF_PREMULTIPLY,
+ BLITSHADER_2DARRAY_LUMAF_UNMULTIPLY,
+ BLITSHADER_2DARRAY_LUMAALPHAF_PREMULTIPLY,
+ BLITSHADER_2DARRAY_LUMAALPHAF_UNMULTIPLY,
+ BLITSHADER_2DARRAY_RGBAF_4444,
+ BLITSHADER_2DARRAY_RGBAF_4444_PREMULTIPLY,
+ BLITSHADER_2DARRAY_RGBAF_4444_UNMULTIPLY,
+ BLITSHADER_2DARRAY_RGBF_565,
+ BLITSHADER_2DARRAY_RGBF_565_PREMULTIPLY,
+ BLITSHADER_2DARRAY_RGBF_565_UNMULTIPLY,
+ BLITSHADER_2DARRAY_RGBAF_5551,
+ BLITSHADER_2DARRAY_RGBAF_5551_PREMULTIPLY,
+ BLITSHADER_2DARRAY_RGBAF_5551_UNMULTIPLY,
+ BLITSHADER_INVALID
+};
+
+Blit11::BlitShaderType Blit11::getBlitShaderType(BlitShaderOperation operation, ShaderDimension dimension)
+{
+ switch(operation)
+ {
+ case RGBAF:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_2D_RGBAF;
+ case SHADER_3D:
+ return BLITSHADER_3D_RGBAF;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_RGBAF;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case BGRAF:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_2D_BGRAF;
+ case SHADER_3D:
+ return BLITSHADER_3D_BGRAF;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_BGRAF;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case RGBF:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_2D_RGBF;
+ case SHADER_3D:
+ return BLITSHADER_3D_RGBF;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_RGBF;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case RGF:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_2D_RGF;
+ case SHADER_3D:
+ return BLITSHADER_3D_RGF;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_RGF;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case RF:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_2D_RF;
+ case SHADER_3D:
+ return BLITSHADER_3D_RF;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_RF;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case ALPHA:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_2D_ALPHA;
+ case SHADER_3D:
+ return BLITSHADER_3D_ALPHA;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_ALPHA;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case LUMA:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_2D_LUMA;
+ case SHADER_3D:
+ return BLITSHADER_3D_LUMA;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_LUMA;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case LUMAALPHA:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_2D_LUMAALPHA;
+ case SHADER_3D:
+ return BLITSHADER_3D_LUMAALPHA;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_LUMAALPHA;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case RGBAUI:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_2D_RGBAUI;
+ case SHADER_3D:
+ return BLITSHADER_3D_RGBAUI;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_RGBAUI;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case RGBAI:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_2D_RGBAI;
+ case SHADER_3D:
+ return BLITSHADER_3D_RGBAI;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_RGBAI;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case RGBUI:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_2D_RGBUI;
+ case SHADER_3D:
+ return BLITSHADER_3D_RGBUI;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_RGBUI;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case RGBI:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_2D_RGBI;
+ case SHADER_3D:
+ return BLITSHADER_3D_RGBI;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_RGBI;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case RGUI:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_2D_RGUI;
+ case SHADER_3D:
+ return BLITSHADER_3D_RGUI;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_RGUI;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case RGI:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_2D_RGI;
+ case SHADER_3D:
+ return BLITSHADER_3D_RGI;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_RGI;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case RUI:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_2D_RUI;
+ case SHADER_3D:
+ return BLITSHADER_3D_RUI;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_RUI;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case RI:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_2D_RI;
+ case SHADER_3D:
+ return BLITSHADER_3D_RI;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_RI;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case RGBAF_PREMULTIPLY:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_2D_RGBAF_PREMULTIPLY;
+ case SHADER_3D:
+ return BLITSHADER_3D_RGBAF_PREMULTIPLY;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_RGBAF_PREMULTIPLY;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case RGBAF_UNMULTIPLY:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_2D_RGBAF_UNMULTIPLY;
+ case SHADER_3D:
+ return BLITSHADER_3D_RGBAF_UNMULTIPLY;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_RGBAF_UNMULTIPLY;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case RGBF_PREMULTIPLY:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_2D_RGBF_PREMULTIPLY;
+ case SHADER_3D:
+ return BLITSHADER_3D_RGBF_PREMULTIPLY;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_RGBF_PREMULTIPLY;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case RGBF_UNMULTIPLY:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_2D_RGBF_UNMULTIPLY;
+ case SHADER_3D:
+ return BLITSHADER_3D_RGBF_UNMULTIPLY;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_RGBF_UNMULTIPLY;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case RGBAF_TOUI:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_2D_RGBAF_TOUI;
+ case SHADER_3D:
+ return BLITSHADER_3D_RGBAF_TOUI;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_RGBAF_TOUI;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case RGBAF_TOUI_PREMULTIPLY:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_2D_RGBAF_TOUI_PREMULTIPLY;
+ case SHADER_3D:
+ return BLITSHADER_3D_RGBAF_TOUI_PREMULTIPLY;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_RGBAF_TOUI_PREMULTIPLY;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case RGBAF_TOUI_UNMULTIPLY:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_2D_RGBAF_TOUI_UNMULTIPLY;
+ case SHADER_3D:
+ return BLITSHADER_3D_RGBAF_TOUI_UNMULTIPLY;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_RGBAF_TOUI_UNMULTIPLY;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case RGBF_TOUI:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_2D_RGBF_TOUI;
+ case SHADER_3D:
+ return BLITSHADER_3D_RGBF_TOUI;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_RGBF_TOUI;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case RGBF_TOUI_PREMULTIPLY:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_2D_RGBF_TOUI_PREMULTIPLY;
+ case SHADER_3D:
+ return BLITSHADER_3D_RGBF_TOUI_PREMULTIPLY;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_RGBF_TOUI_PREMULTIPLY;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case RGBF_TOUI_UNMULTIPLY:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_2D_RGBF_TOUI_UNMULTIPLY;
+ case SHADER_3D:
+ return BLITSHADER_3D_RGBF_TOUI_UNMULTIPLY;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_RGBF_TOUI_UNMULTIPLY;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case RGBAF_TOI:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_INVALID;
+ case SHADER_3D:
+ return BLITSHADER_3D_RGBAF_TOI;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_RGBAF_TOI;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case RGBAF_TOI_PREMULTIPLY:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_INVALID;
+ case SHADER_3D:
+ return BLITSHADER_3D_RGBAF_TOI_PREMULTIPLY;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_RGBAF_TOI_PREMULTIPLY;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case RGBAF_TOI_UNMULTIPLY:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_INVALID;
+ case SHADER_3D:
+ return BLITSHADER_3D_RGBAF_TOI_UNMULTIPLY;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_RGBAF_TOI_UNMULTIPLY;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case RGBF_TOI:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_INVALID;
+ case SHADER_3D:
+ return BLITSHADER_3D_RGBF_TOI;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_RGBF_TOI;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case RGBF_TOI_PREMULTIPLY:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_INVALID;
+ case SHADER_3D:
+ return BLITSHADER_3D_RGBF_TOI_PREMULTIPLY;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_RGBF_TOI_PREMULTIPLY;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case RGBF_TOI_UNMULTIPLY:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_INVALID;
+ case SHADER_3D:
+ return BLITSHADER_3D_RGBF_TOI_UNMULTIPLY;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_RGBF_TOI_UNMULTIPLY;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case LUMAF_PREMULTIPLY:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_2D_LUMAF_PREMULTIPLY;
+ case SHADER_3D:
+ return BLITSHADER_3D_LUMAF_PREMULTIPLY;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_LUMAF_PREMULTIPLY;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case LUMAF_UNMULTIPLY:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_2D_LUMAF_UNMULTIPLY;
+ case SHADER_3D:
+ return BLITSHADER_3D_LUMAF_UNMULTIPLY;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_LUMAF_UNMULTIPLY;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case LUMAALPHAF_PREMULTIPLY:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_2D_LUMAALPHAF_PREMULTIPLY;
+ case SHADER_3D:
+ return BLITSHADER_3D_LUMAALPHAF_PREMULTIPLY;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_LUMAALPHAF_PREMULTIPLY;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case LUMAALPHAF_UNMULTIPLY:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_2D_LUMAALPHAF_UNMULTIPLY;
+ case SHADER_3D:
+ return BLITSHADER_3D_LUMAALPHAF_UNMULTIPLY;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_LUMAALPHAF_UNMULTIPLY;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case RGBAF_4444:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_2D_RGBAF_4444;
+ case SHADER_3D:
+ return BLITSHADER_3D_RGBAF_4444;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_RGBAF_4444;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case RGBAF_4444_PREMULTIPLY:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_2D_RGBAF_4444_PREMULTIPLY;
+ case SHADER_3D:
+ return BLITSHADER_3D_RGBAF_4444_PREMULTIPLY;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_RGBAF_4444_PREMULTIPLY;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case RGBAF_4444_UNMULTIPLY:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_2D_RGBAF_4444_UNMULTIPLY;
+ case SHADER_3D:
+ return BLITSHADER_3D_RGBAF_4444_UNMULTIPLY;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_RGBAF_4444_UNMULTIPLY;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case RGBF_565:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_2D_RGBF_565;
+ case SHADER_3D:
+ return BLITSHADER_3D_RGBF_565;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_RGBF_565;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case RGBF_565_PREMULTIPLY:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_2D_RGBF_565_PREMULTIPLY;
+ case SHADER_3D:
+ return BLITSHADER_3D_RGBF_565_PREMULTIPLY;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_RGBF_565_PREMULTIPLY;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case RGBF_565_UNMULTIPLY:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_2D_RGBF_565_UNMULTIPLY;
+ case SHADER_3D:
+ return BLITSHADER_3D_RGBF_565_UNMULTIPLY;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_RGBF_565_UNMULTIPLY;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case RGBAF_5551:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_2D_RGBAF_5551;
+ case SHADER_3D:
+ return BLITSHADER_3D_RGBAF_5551;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_RGBAF_5551;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case RGBAF_5551_PREMULTIPLY:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_2D_RGBAF_5551_PREMULTIPLY;
+ case SHADER_3D:
+ return BLITSHADER_3D_RGBAF_5551_PREMULTIPLY;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_RGBAF_5551_PREMULTIPLY;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ case RGBAF_5551_UNMULTIPLY:
+ switch (dimension)
+ {
+ case SHADER_2D:
+ return BLITSHADER_2D_RGBAF_5551_UNMULTIPLY;
+ case SHADER_3D:
+ return BLITSHADER_3D_RGBAF_5551_UNMULTIPLY;
+ case SHADER_2DARRAY:
+ return BLITSHADER_2DARRAY_RGBAF_5551_UNMULTIPLY;
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+ default:
+ UNREACHABLE();
+ return BLITSHADER_INVALID;
+ }
+}
+
+angle::Result Blit11::mapBlitShader(const gl::Context *context,
+ BlitShaderType blitShaderType)
+{
+ switch(blitShaderType)
+ {
+ case BLITSHADER_2D_RGBAF:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D,
+ ShaderData(g_PS_PassthroughRGBA2D),
+ "Blit11 2D PassthroughRGBA2D pixel shader"));
+ break;
+ case BLITSHADER_2D_BGRAF:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D,
+ ShaderData(g_PS_PassthroughRGBA2D),
+ "Blit11 2D PassthroughRGBA2D pixel shader"));
+ break;
+ case BLITSHADER_2D_RGBF:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D,
+ ShaderData(g_PS_PassthroughRGB2D),
+ "Blit11 2D PassthroughRGB2D pixel shader"));
+ break;
+ case BLITSHADER_2D_RGF:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D,
+ ShaderData(g_PS_PassthroughRG2D),
+ "Blit11 2D PassthroughRG2D pixel shader"));
+ break;
+ case BLITSHADER_2D_RF:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D,
+ ShaderData(g_PS_PassthroughR2D),
+ "Blit11 2D PassthroughR2D pixel shader"));
+ break;
+ case BLITSHADER_2D_ALPHA:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D,
+ ShaderData(g_PS_PassthroughA2D),
+ "Blit11 2D PassthroughA2D pixel shader"));
+ break;
+ case BLITSHADER_2D_LUMA:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D,
+ ShaderData(g_PS_PassthroughLum2D),
+ "Blit11 2D PassthroughLum2D pixel shader"));
+ break;
+ case BLITSHADER_2D_LUMAALPHA:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D,
+ ShaderData(g_PS_PassthroughLumAlpha2D),
+ "Blit11 2D PassthroughLumAlpha2D pixel shader"));
+ break;
+ case BLITSHADER_2D_RGBAUI:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D,
+ ShaderData(g_PS_PassthroughRGBA2DUI),
+ "Blit11 2D PassthroughRGBA2DUI pixel shader"));
+ break;
+ case BLITSHADER_2D_RGBAI:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D,
+ ShaderData(g_PS_PassthroughRGBA2DI),
+ "Blit11 2D PassthroughRGBA2DI pixel shader"));
+ break;
+ case BLITSHADER_2D_RGBUI:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D,
+ ShaderData(g_PS_PassthroughRGB2DUI),
+ "Blit11 2D PassthroughRGB2DUI pixel shader"));
+ break;
+ case BLITSHADER_2D_RGBI:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D,
+ ShaderData(g_PS_PassthroughRGB2DI),
+ "Blit11 2D PassthroughRGB2DI pixel shader"));
+ break;
+ case BLITSHADER_2D_RGUI:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D,
+ ShaderData(g_PS_PassthroughRG2DUI),
+ "Blit11 2D PassthroughRG2DUI pixel shader"));
+ break;
+ case BLITSHADER_2D_RGI:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D,
+ ShaderData(g_PS_PassthroughRG2DI),
+ "Blit11 2D PassthroughRG2DI pixel shader"));
+ break;
+ case BLITSHADER_2D_RUI:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D,
+ ShaderData(g_PS_PassthroughR2DUI),
+ "Blit11 2D PassthroughR2DUI pixel shader"));
+ break;
+ case BLITSHADER_2D_RI:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D,
+ ShaderData(g_PS_PassthroughR2DI),
+ "Blit11 2D PassthroughR2DI pixel shader"));
+ break;
+ case BLITSHADER_2D_RGBAF_PREMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D,
+ ShaderData(g_PS_FtoF_PM_RGBA_2D),
+ "Blit11 2D FtoF PM RGBA 2D pixel shader"));
+ break;
+ case BLITSHADER_2D_RGBAF_UNMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D,
+ ShaderData(g_PS_FtoF_UM_RGBA_2D),
+ "Blit11 2D FtoF UM RGBA 2D pixel shader"));
+ break;
+ case BLITSHADER_2D_RGBF_PREMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D,
+ ShaderData(g_PS_FtoF_PM_RGB_2D),
+ "Blit11 2D FtoF PM RGB 2D pixel shader"));
+ break;
+ case BLITSHADER_2D_RGBF_UNMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D,
+ ShaderData(g_PS_FtoF_UM_RGB_2D),
+ "Blit11 2D FtoF UM RGB 2D pixel shader"));
+ break;
+ case BLITSHADER_2D_RGBAF_TOUI:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D,
+ ShaderData(g_PS_FtoU_PT_RGBA_2D),
+ "Blit11 2D FtoU PT RGBA 2D pixel shader"));
+ break;
+ case BLITSHADER_2D_RGBAF_TOUI_PREMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D,
+ ShaderData(g_PS_FtoU_PM_RGBA_2D),
+ "Blit11 2D FtoU PM RGBA 2D pixel shader"));
+ break;
+ case BLITSHADER_2D_RGBAF_TOUI_UNMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D,
+ ShaderData(g_PS_FtoU_UM_RGBA_2D),
+ "Blit11 2D FtoU UM RGBA 2D pixel shader"));
+ break;
+ case BLITSHADER_2D_RGBF_TOUI:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D,
+ ShaderData(g_PS_FtoU_PT_RGB_2D),
+ "Blit11 2D FtoU PT RGB 2D pixel shader"));
+ break;
+ case BLITSHADER_2D_RGBF_TOUI_PREMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D,
+ ShaderData(g_PS_FtoU_PM_RGB_2D),
+ "Blit11 2D FtoU PM RGB 2D pixel shader"));
+ break;
+ case BLITSHADER_2D_RGBF_TOUI_UNMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D,
+ ShaderData(g_PS_FtoU_UM_RGB_2D),
+ "Blit11 2D FtoU UM RGB 2D pixel shader"));
+ break;
+ case BLITSHADER_2D_LUMAF_PREMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D,
+ ShaderData(g_PS_FtoF_PM_LUMA_2D),
+ "Blit11 2D FtoF PM LUMA 2D pixel shader"));
+ break;
+ case BLITSHADER_2D_LUMAF_UNMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D,
+ ShaderData(g_PS_FtoF_UM_LUMA_2D),
+ "Blit11 2D FtoF UM LUMA 2D pixel shader"));
+ break;
+ case BLITSHADER_2D_LUMAALPHAF_PREMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D,
+ ShaderData(g_PS_FtoF_PM_LUMAALPHA_2D),
+ "Blit11 2D FtoF PM LUMAALPHA 2D pixel shader"));
+ break;
+ case BLITSHADER_2D_LUMAALPHAF_UNMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D,
+ ShaderData(g_PS_FtoF_UM_LUMAALPHA_2D),
+ "Blit11 2D FtoF UM LUMAALPHA 2D pixel shader"));
+ break;
+ case BLITSHADER_2D_RGBAF_4444:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D,
+ ShaderData(g_PS_PassthroughRGBA2D_4444),
+ "Blit11 2D PassthroughRGBA2D 4444 pixel shader"));
+ break;
+ case BLITSHADER_2D_RGBAF_4444_PREMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D,
+ ShaderData(g_PS_FtoF_PM_RGBA_4444_2D),
+ "Blit11 2D FtoF PM RGBA 4444 2D pixel shader"));
+ break;
+ case BLITSHADER_2D_RGBAF_4444_UNMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D,
+ ShaderData(g_PS_FtoF_UM_RGBA_4444_2D),
+ "Blit11 2D FtoF UM RGBA 4444 2D pixel shader"));
+ break;
+ case BLITSHADER_2D_RGBF_565:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D,
+ ShaderData(g_PS_PassthroughRGB2D_565),
+ "Blit11 2D PassthroughRGB2D 565 pixel shader"));
+ break;
+ case BLITSHADER_2D_RGBF_565_PREMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D,
+ ShaderData(g_PS_FtoF_PM_RGB_565_2D),
+ "Blit11 2D FtoF PM RGB 565 2D pixel shader"));
+ break;
+ case BLITSHADER_2D_RGBF_565_UNMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D,
+ ShaderData(g_PS_FtoF_UM_RGB_565_2D),
+ "Blit11 2D FtoF UM RGB 565 2D pixel shader"));
+ break;
+ case BLITSHADER_2D_RGBAF_5551:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D,
+ ShaderData(g_PS_PassthroughRGBA2D_5551),
+ "Blit11 2D PassthroughRGBA2D 5551 pixel shader"));
+ break;
+ case BLITSHADER_2D_RGBAF_5551_PREMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D,
+ ShaderData(g_PS_FtoF_PM_RGBA_5551_2D),
+ "Blit11 2D FtoF PM RGBA 5551 2D pixel shader"));
+ break;
+ case BLITSHADER_2D_RGBAF_5551_UNMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2D,
+ ShaderData(g_PS_FtoF_UM_RGBA_5551_2D),
+ "Blit11 2D FtoF UM RGBA 5551 2D pixel shader"));
+ break;
+ case BLITSHADER_3D_RGBAF:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_PassthroughRGBA3D),
+ "Blit11 3D PassthroughRGBA3D pixel shader"));
+ break;
+ case BLITSHADER_3D_BGRAF:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_PassthroughRGBA3D),
+ "Blit11 3D PassthroughRGBA3D pixel shader"));
+ break;
+ case BLITSHADER_3D_RGBF:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_PassthroughRGB3D),
+ "Blit11 3D PassthroughRGB3D pixel shader"));
+ break;
+ case BLITSHADER_3D_RGF:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_PassthroughRG3D),
+ "Blit11 3D PassthroughRG3D pixel shader"));
+ break;
+ case BLITSHADER_3D_RF:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_PassthroughR3D),
+ "Blit11 3D PassthroughR3D pixel shader"));
+ break;
+ case BLITSHADER_3D_ALPHA:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_PassthroughRGBA3D),
+ "Blit11 3D PassthroughRGBA3D pixel shader"));
+ break;
+ case BLITSHADER_3D_LUMA:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_PassthroughLum3D),
+ "Blit11 3D PassthroughLum3D pixel shader"));
+ break;
+ case BLITSHADER_3D_LUMAALPHA:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_PassthroughLumAlpha3D),
+ "Blit11 3D PassthroughLumAlpha3D pixel shader"));
+ break;
+ case BLITSHADER_3D_RGBAUI:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_PassthroughRGBA3DUI),
+ "Blit11 3D PassthroughRGBA3DUI pixel shader"));
+ break;
+ case BLITSHADER_3D_RGBAI:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_PassthroughRGBA3DI),
+ "Blit11 3D PassthroughRGBA3DI pixel shader"));
+ break;
+ case BLITSHADER_3D_RGBUI:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_PassthroughRGB3DUI),
+ "Blit11 3D PassthroughRGB3DUI pixel shader"));
+ break;
+ case BLITSHADER_3D_RGBI:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_PassthroughRGB3DI),
+ "Blit11 3D PassthroughRGB3DI pixel shader"));
+ break;
+ case BLITSHADER_3D_RGUI:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_PassthroughRG3DUI),
+ "Blit11 3D PassthroughRG3DUI pixel shader"));
+ break;
+ case BLITSHADER_3D_RGI:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_PassthroughRG3DI),
+ "Blit11 3D PassthroughRG3DI pixel shader"));
+ break;
+ case BLITSHADER_3D_RUI:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_PassthroughR3DUI),
+ "Blit11 3D PassthroughR3DUI pixel shader"));
+ break;
+ case BLITSHADER_3D_RI:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_PassthroughR3DI),
+ "Blit11 3D PassthroughR3DI pixel shader"));
+ break;
+ case BLITSHADER_3D_RGBAF_PREMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_FtoF_PM_RGBA_3D),
+ "Blit11 3D FtoF PM RGBA 3D pixel shader"));
+ break;
+ case BLITSHADER_3D_RGBAF_UNMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_FtoF_UM_RGBA_3D),
+ "Blit11 3D FtoF UM RGBA 3D pixel shader"));
+ break;
+ case BLITSHADER_3D_RGBF_PREMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_FtoF_PM_RGB_3D),
+ "Blit11 3D FtoF PM RGB 3D pixel shader"));
+ break;
+ case BLITSHADER_3D_RGBF_UNMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_FtoF_UM_RGB_3D),
+ "Blit11 3D FtoF UM RGB 3D pixel shader"));
+ break;
+ case BLITSHADER_3D_RGBAF_TOUI:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_FtoU_PT_RGBA_3D),
+ "Blit11 3D FtoU PT RGBA 3D pixel shader"));
+ break;
+ case BLITSHADER_3D_RGBAF_TOUI_PREMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_FtoU_PM_RGBA_3D),
+ "Blit11 3D FtoU PM RGBA 3D pixel shader"));
+ break;
+ case BLITSHADER_3D_RGBAF_TOUI_UNMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_FtoU_UM_RGBA_3D),
+ "Blit11 3D FtoU UM RGBA 3D pixel shader"));
+ break;
+ case BLITSHADER_3D_RGBF_TOUI:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_FtoU_PT_RGB_3D),
+ "Blit11 3D FtoU PT RGB 3D pixel shader"));
+ break;
+ case BLITSHADER_3D_RGBF_TOUI_PREMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_FtoU_PM_RGB_3D),
+ "Blit11 3D FtoU PM RGB 3D pixel shader"));
+ break;
+ case BLITSHADER_3D_RGBF_TOUI_UNMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_FtoU_UM_RGB_3D),
+ "Blit11 3D FtoU UM RGB 3D pixel shader"));
+ break;
+ case BLITSHADER_3D_RGBAF_TOI:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_FtoI_PT_RGBA_3D),
+ "Blit11 3D FtoI PT RGBA 3D pixel shader"));
+ break;
+ case BLITSHADER_3D_RGBAF_TOI_PREMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_FtoI_PM_RGBA_3D),
+ "Blit11 3D FtoI PM RGBA 3D pixel shader"));
+ break;
+ case BLITSHADER_3D_RGBAF_TOI_UNMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_FtoI_UM_RGBA_3D),
+ "Blit11 3D FtoI UM RGBA 3D pixel shader"));
+ break;
+ case BLITSHADER_3D_RGBF_TOI:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_FtoI_PT_RGB_3D),
+ "Blit11 3D FtoI PT RGB 3D pixel shader"));
+ break;
+ case BLITSHADER_3D_RGBF_TOI_PREMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_FtoI_PM_RGB_3D),
+ "Blit11 3D FtoI PM RGB 3D pixel shader"));
+ break;
+ case BLITSHADER_3D_RGBF_TOI_UNMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_FtoI_UM_RGB_3D),
+ "Blit11 3D FtoI UM RGB 3D pixel shader"));
+ break;
+ case BLITSHADER_3D_LUMAF_PREMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_FtoF_PM_LUMA_3D),
+ "Blit11 3D FtoF PM LUMA 3D pixel shader"));
+ break;
+ case BLITSHADER_3D_LUMAF_UNMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_FtoF_UM_LUMA_3D),
+ "Blit11 3D FtoF UM LUMA 3D pixel shader"));
+ break;
+ case BLITSHADER_3D_LUMAALPHAF_PREMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_FtoF_PM_LUMAALPHA_3D),
+ "Blit11 3D FtoF PM LUMAALPHA 3D pixel shader"));
+ break;
+ case BLITSHADER_3D_LUMAALPHAF_UNMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_FtoF_UM_LUMAALPHA_3D),
+ "Blit11 3D FtoF UM LUMAALPHA 3D pixel shader"));
+ break;
+ case BLITSHADER_3D_RGBAF_4444:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_PassthroughRGBA3D_4444),
+ "Blit11 3D PassthroughRGBA3D 4444 pixel shader"));
+ break;
+ case BLITSHADER_3D_RGBAF_4444_PREMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_FtoF_PM_RGBA_4444_3D),
+ "Blit11 3D FtoF PM RGBA 4444 3D pixel shader"));
+ break;
+ case BLITSHADER_3D_RGBAF_4444_UNMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_FtoF_UM_RGBA_4444_3D),
+ "Blit11 3D FtoF UM RGBA 4444 3D pixel shader"));
+ break;
+ case BLITSHADER_3D_RGBF_565:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_PassthroughRGB3D_565),
+ "Blit11 3D PassthroughRGB3D 565 pixel shader"));
+ break;
+ case BLITSHADER_3D_RGBF_565_PREMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_FtoF_PM_RGB_565_3D),
+ "Blit11 3D FtoF PM RGB 565 3D pixel shader"));
+ break;
+ case BLITSHADER_3D_RGBF_565_UNMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_FtoF_UM_RGB_565_3D),
+ "Blit11 3D FtoF UM RGB 565 3D pixel shader"));
+ break;
+ case BLITSHADER_3D_RGBAF_5551:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_PassthroughRGBA3D_5551),
+ "Blit11 3D PassthroughRGBA3D 5551 pixel shader"));
+ break;
+ case BLITSHADER_3D_RGBAF_5551_PREMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_FtoF_PM_RGBA_5551_3D),
+ "Blit11 3D FtoF PM RGBA 5551 3D pixel shader"));
+ break;
+ case BLITSHADER_3D_RGBAF_5551_UNMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_3D,
+ ShaderData(g_PS_FtoF_UM_RGBA_5551_3D),
+ "Blit11 3D FtoF UM RGBA 5551 3D pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_RGBAF:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_PassthroughRGBA2DArray),
+ "Blit11 2DArray PassthroughRGBA2DArray pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_BGRAF:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_PassthroughRGBA2DArray),
+ "Blit11 2DArray PassthroughRGBA2DArray pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_RGBF:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_PassthroughRGB2DArray),
+ "Blit11 2DArray PassthroughRGB2DArray pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_RGF:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_PassthroughRG2DArray),
+ "Blit11 2DArray PassthroughRG2DArray pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_RF:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_PassthroughR2DArray),
+ "Blit11 2DArray PassthroughR2DArray pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_ALPHA:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_PassthroughRGBA2DArray),
+ "Blit11 2DArray PassthroughRGBA2DArray pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_LUMA:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_PassthroughLum2DArray),
+ "Blit11 2DArray PassthroughLum2DArray pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_LUMAALPHA:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_PassthroughLumAlpha2DArray),
+ "Blit11 2DArray PassthroughLumAlpha2DArray pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_RGBAUI:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_PassthroughRGBA2DArrayUI),
+ "Blit11 2DArray PassthroughRGBA2DArrayUI pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_RGBAI:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_PassthroughRGBA2DArrayI),
+ "Blit11 2DArray PassthroughRGBA2DArrayI pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_RGBUI:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_PassthroughRGB2DArrayUI),
+ "Blit11 2DArray PassthroughRGB2DArrayUI pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_RGBI:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_PassthroughRGB2DArrayI),
+ "Blit11 2DArray PassthroughRGB2DArrayI pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_RGUI:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_PassthroughRG2DArrayUI),
+ "Blit11 2DArray PassthroughRG2DArrayUI pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_RGI:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_PassthroughRG2DArrayI),
+ "Blit11 2DArray PassthroughRG2DArrayI pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_RUI:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_PassthroughR2DArrayUI),
+ "Blit11 2DArray PassthroughR2DArrayUI pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_RI:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_PassthroughR2DArrayI),
+ "Blit11 2DArray PassthroughR2DArrayI pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_RGBAF_PREMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_FtoF_PM_RGBA_2DArray),
+ "Blit11 2DArray FtoF PM RGBA 2DArray pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_RGBAF_UNMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_FtoF_UM_RGBA_2DArray),
+ "Blit11 2DArray FtoF UM RGBA 2DArray pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_RGBF_PREMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_FtoF_PM_RGB_2DArray),
+ "Blit11 2DArray FtoF PM RGB 2DArray pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_RGBF_UNMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_FtoF_UM_RGB_2DArray),
+ "Blit11 2DArray FtoF UM RGB 2DArray pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_RGBAF_TOUI:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_FtoU_PT_RGBA_2DArray),
+ "Blit11 2DArray FtoU PT RGBA 2DArray pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_RGBAF_TOUI_PREMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_FtoU_PM_RGBA_2DArray),
+ "Blit11 2DArray FtoU PM RGBA 2DArray pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_RGBAF_TOUI_UNMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_FtoU_UM_RGBA_2DArray),
+ "Blit11 2DArray FtoU UM RGBA 2DArray pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_RGBF_TOUI:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_FtoU_PT_RGB_2DArray),
+ "Blit11 2DArray FtoU PT RGB 2DArray pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_RGBF_TOUI_PREMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_FtoU_PM_RGB_2DArray),
+ "Blit11 2DArray FtoU PM RGB 2DArray pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_RGBF_TOUI_UNMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_FtoU_UM_RGB_2DArray),
+ "Blit11 2DArray FtoU UM RGB 2DArray pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_RGBAF_TOI:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_FtoI_PT_RGBA_2DArray),
+ "Blit11 2DArray FtoI PT RGBA 2DArray pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_RGBAF_TOI_PREMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_FtoI_PM_RGBA_2DArray),
+ "Blit11 2DArray FtoI PM RGBA 2DArray pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_RGBAF_TOI_UNMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_FtoI_UM_RGBA_2DArray),
+ "Blit11 2DArray FtoI UM RGBA 2DArray pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_RGBF_TOI:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_FtoI_PT_RGB_2DArray),
+ "Blit11 2DArray FtoI PT RGB 2DArray pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_RGBF_TOI_PREMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_FtoI_PM_RGB_2DArray),
+ "Blit11 2DArray FtoI PM RGB 2DArray pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_RGBF_TOI_UNMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_FtoI_UM_RGB_2DArray),
+ "Blit11 2DArray FtoI UM RGB 2DArray pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_LUMAF_PREMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_FtoF_PM_LUMA_2DArray),
+ "Blit11 2DArray FtoF PM LUMA 2DArray pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_LUMAF_UNMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_FtoF_UM_LUMA_2DArray),
+ "Blit11 2DArray FtoF UM LUMA 2DArray pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_LUMAALPHAF_PREMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_FtoF_PM_LUMAALPHA_2DArray),
+ "Blit11 2DArray FtoF PM LUMAALPHA 2DArray pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_LUMAALPHAF_UNMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_FtoF_UM_LUMAALPHA_2DArray),
+ "Blit11 2DArray FtoF UM LUMAALPHA 2DArray pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_RGBAF_4444:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_PassthroughRGBA2DArray_4444),
+ "Blit11 2DArray PassthroughRGBA2DArray 4444 pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_RGBAF_4444_PREMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_FtoF_PM_RGBA_4444_2DArray),
+ "Blit11 2DArray FtoF PM RGBA 4444 2DArray pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_RGBAF_4444_UNMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_FtoF_UM_RGBA_4444_2DArray),
+ "Blit11 2DArray FtoF UM RGBA 4444 2DArray pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_RGBF_565:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_PassthroughRGB2DArray_565),
+ "Blit11 2DArray PassthroughRGB2DArray 565 pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_RGBF_565_PREMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_FtoF_PM_RGB_565_2DArray),
+ "Blit11 2DArray FtoF PM RGB 565 2DArray pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_RGBF_565_UNMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_FtoF_UM_RGB_565_2DArray),
+ "Blit11 2DArray FtoF UM RGB 565 2DArray pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_RGBAF_5551:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_PassthroughRGBA2DArray_5551),
+ "Blit11 2DArray PassthroughRGBA2DArray 5551 pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_RGBAF_5551_PREMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_FtoF_PM_RGBA_5551_2DArray),
+ "Blit11 2DArray FtoF PM RGBA 5551 2DArray pixel shader"));
+ break;
+ case BLITSHADER_2DARRAY_RGBAF_5551_UNMULTIPLY:
+ ANGLE_TRY(addBlitShaderToMap(context, blitShaderType, SHADER_2DARRAY,
+ ShaderData(g_PS_FtoF_UM_RGBA_5551_2DArray),
+ "Blit11 2DArray FtoF UM RGBA 5551 2DArray pixel shader"));
+ break;
+ default:
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
+ }
+
+ return angle::Result::Continue;
+}
+
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp
new file mode 100644
index 0000000000..8cc265f288
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Buffer11.cpp
@@ -0,0 +1,1888 @@
+//
+// 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.
+//
+
+// Buffer11.cpp Defines the Buffer11 class.
+
+#include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
+
+#include <memory>
+
+#include "common/MemoryBuffer.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/renderer/d3d/IndexDataManager.h"
+#include "libANGLE/renderer/d3d/VertexDataManager.h"
+#include "libANGLE/renderer/d3d/d3d11/Context11.h"
+#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+#include "libANGLE/renderer/renderer_utils.h"
+
+namespace rx
+{
+
+namespace
+{
+
+template <typename T>
+GLuint ReadIndexValueFromIndices(const uint8_t *data, size_t index)
+{
+ return reinterpret_cast<const T *>(data)[index];
+}
+typedef GLuint (*ReadIndexValueFunction)(const uint8_t *data, size_t index);
+
+enum class CopyResult
+{
+ RECREATED,
+ NOT_RECREATED,
+};
+
+void CalculateConstantBufferParams(GLintptr offset,
+ GLsizeiptr size,
+ UINT *outFirstConstant,
+ UINT *outNumConstants)
+{
+ // The offset must be aligned to 256 bytes (should have been enforced by glBindBufferRange).
+ ASSERT(offset % 256 == 0);
+
+ // firstConstant and numConstants are expressed in constants of 16-bytes. Furthermore they must
+ // be a multiple of 16 constants.
+ *outFirstConstant = static_cast<UINT>(offset / 16);
+
+ // The GL size is not required to be aligned to a 256 bytes boundary.
+ // Round the size up to a 256 bytes boundary then express the results in constants of 16-bytes.
+ *outNumConstants = static_cast<UINT>(rx::roundUpPow2(size, static_cast<GLsizeiptr>(256)) / 16);
+
+ // Since the size is rounded up, firstConstant + numConstants may be bigger than the actual size
+ // of the buffer. This behaviour is explictly allowed according to the documentation on
+ // ID3D11DeviceContext1::PSSetConstantBuffers1
+ // https://msdn.microsoft.com/en-us/library/windows/desktop/hh404649%28v=vs.85%29.aspx
+}
+
+} // anonymous namespace
+
+namespace gl_d3d11
+{
+
+D3D11_MAP GetD3DMapTypeFromBits(BufferUsage usage, GLbitfield access)
+{
+ bool readBit = ((access & GL_MAP_READ_BIT) != 0);
+ bool writeBit = ((access & GL_MAP_WRITE_BIT) != 0);
+
+ ASSERT(readBit || writeBit);
+
+ // Note : we ignore the discard bit, because in D3D11, staging buffers
+ // don't accept the map-discard flag (discard only works for DYNAMIC usage)
+
+ if (readBit && !writeBit)
+ {
+ return D3D11_MAP_READ;
+ }
+ else if (writeBit && !readBit)
+ {
+ // Special case for uniform storage - we only allow full buffer updates.
+ return usage == BUFFER_USAGE_UNIFORM || usage == BUFFER_USAGE_STRUCTURED
+ ? D3D11_MAP_WRITE_DISCARD
+ : D3D11_MAP_WRITE;
+ }
+ else if (writeBit && readBit)
+ {
+ return D3D11_MAP_READ_WRITE;
+ }
+ else
+ {
+ UNREACHABLE();
+ return D3D11_MAP_READ;
+ }
+}
+} // namespace gl_d3d11
+
+// Each instance of Buffer11::BufferStorage is specialized for a class of D3D binding points
+// - vertex/transform feedback buffers
+// - index buffers
+// - pixel unpack buffers
+// - uniform buffers
+class Buffer11::BufferStorage : angle::NonCopyable
+{
+ public:
+ virtual ~BufferStorage() {}
+
+ DataRevision getDataRevision() const { return mRevision; }
+ BufferUsage getUsage() const { return mUsage; }
+ size_t getSize() const { return mBufferSize; }
+ void setDataRevision(DataRevision rev) { mRevision = rev; }
+
+ virtual bool isCPUAccessible(GLbitfield access) const = 0;
+
+ virtual bool isGPUAccessible() const = 0;
+
+ virtual angle::Result copyFromStorage(const gl::Context *context,
+ BufferStorage *source,
+ size_t sourceOffset,
+ size_t size,
+ size_t destOffset,
+ CopyResult *resultOut) = 0;
+ virtual angle::Result resize(const gl::Context *context, size_t size, bool preserveData) = 0;
+
+ virtual angle::Result map(const gl::Context *context,
+ size_t offset,
+ size_t length,
+ GLbitfield access,
+ uint8_t **mapPointerOut) = 0;
+ virtual void unmap() = 0;
+
+ angle::Result setData(const gl::Context *context,
+ const uint8_t *data,
+ size_t offset,
+ size_t size);
+
+ void setStructureByteStride(unsigned int structureByteStride);
+
+ protected:
+ BufferStorage(Renderer11 *renderer, BufferUsage usage);
+
+ Renderer11 *mRenderer;
+ DataRevision mRevision;
+ const BufferUsage mUsage;
+ size_t mBufferSize;
+};
+
+// A native buffer storage represents an underlying D3D11 buffer for a particular
+// type of storage.
+class Buffer11::NativeStorage : public Buffer11::BufferStorage
+{
+ public:
+ NativeStorage(Renderer11 *renderer, BufferUsage usage, const angle::Subject *onStorageChanged);
+ ~NativeStorage() override;
+
+ bool isCPUAccessible(GLbitfield access) const override;
+
+ bool isGPUAccessible() const override { return true; }
+
+ const d3d11::Buffer &getBuffer() const { return mBuffer; }
+ angle::Result copyFromStorage(const gl::Context *context,
+ BufferStorage *source,
+ size_t sourceOffset,
+ size_t size,
+ size_t destOffset,
+ CopyResult *resultOut) override;
+ angle::Result resize(const gl::Context *context, size_t size, bool preserveData) override;
+
+ angle::Result map(const gl::Context *context,
+ size_t offset,
+ size_t length,
+ GLbitfield access,
+ uint8_t **mapPointerOut) override;
+ void unmap() override;
+
+ angle::Result getSRVForFormat(const gl::Context *context,
+ DXGI_FORMAT srvFormat,
+ const d3d11::ShaderResourceView **srvOut);
+ angle::Result getRawUAV(const gl::Context *context,
+ unsigned int offset,
+ unsigned int size,
+ d3d11::UnorderedAccessView **uavOut);
+
+ protected:
+ d3d11::Buffer mBuffer;
+ const angle::Subject *mOnStorageChanged;
+
+ private:
+ static void FillBufferDesc(D3D11_BUFFER_DESC *bufferDesc,
+ Renderer11 *renderer,
+ BufferUsage usage,
+ unsigned int bufferSize);
+ void clearSRVs();
+ void clearUAVs();
+
+ std::map<DXGI_FORMAT, d3d11::ShaderResourceView> mBufferResourceViews;
+ std::map<std::pair<unsigned int, unsigned int>, d3d11::UnorderedAccessView> mBufferRawUAVs;
+};
+
+class Buffer11::StructuredBufferStorage : public Buffer11::NativeStorage
+{
+ public:
+ StructuredBufferStorage(Renderer11 *renderer,
+ BufferUsage usage,
+ const angle::Subject *onStorageChanged);
+ ~StructuredBufferStorage() override;
+ angle::Result resizeStructuredBuffer(const gl::Context *context,
+ unsigned int size,
+ unsigned int structureByteStride);
+ angle::Result getStructuredBufferRangeSRV(const gl::Context *context,
+ unsigned int offset,
+ unsigned int size,
+ unsigned int structureByteStride,
+ const d3d11::ShaderResourceView **bufferOut);
+
+ private:
+ d3d11::ShaderResourceView mStructuredBufferResourceView;
+};
+
+// A emulated indexed buffer storage represents an underlying D3D11 buffer for data
+// that has been expanded to match the indices list used. This storage is only
+// used for FL9_3 pointsprite rendering emulation.
+class Buffer11::EmulatedIndexedStorage : public Buffer11::BufferStorage
+{
+ public:
+ EmulatedIndexedStorage(Renderer11 *renderer);
+ ~EmulatedIndexedStorage() override;
+
+ bool isCPUAccessible(GLbitfield access) const override { return true; }
+
+ bool isGPUAccessible() const override { return false; }
+
+ angle::Result getBuffer(const gl::Context *context,
+ SourceIndexData *indexInfo,
+ const TranslatedAttribute &attribute,
+ GLint startVertex,
+ const d3d11::Buffer **bufferOut);
+
+ angle::Result copyFromStorage(const gl::Context *context,
+ BufferStorage *source,
+ size_t sourceOffset,
+ size_t size,
+ size_t destOffset,
+ CopyResult *resultOut) override;
+
+ angle::Result resize(const gl::Context *context, size_t size, bool preserveData) override;
+
+ angle::Result map(const gl::Context *context,
+ size_t offset,
+ size_t length,
+ GLbitfield access,
+ uint8_t **mapPointerOut) override;
+ void unmap() override;
+
+ private:
+ d3d11::Buffer mBuffer; // contains expanded data for use by D3D
+ angle::MemoryBuffer mMemoryBuffer; // original data (not expanded)
+ angle::MemoryBuffer mIndicesMemoryBuffer; // indices data
+};
+
+// Pack storage represents internal storage for pack buffers. We implement pack buffers
+// as CPU memory, tied to a staging texture, for asynchronous texture readback.
+class Buffer11::PackStorage : public Buffer11::BufferStorage
+{
+ public:
+ explicit PackStorage(Renderer11 *renderer);
+ ~PackStorage() override;
+
+ bool isCPUAccessible(GLbitfield access) const override { return true; }
+
+ bool isGPUAccessible() const override { return false; }
+
+ angle::Result copyFromStorage(const gl::Context *context,
+ BufferStorage *source,
+ size_t sourceOffset,
+ size_t size,
+ size_t destOffset,
+ CopyResult *resultOut) override;
+ angle::Result resize(const gl::Context *context, size_t size, bool preserveData) override;
+
+ angle::Result map(const gl::Context *context,
+ size_t offset,
+ size_t length,
+ GLbitfield access,
+ uint8_t **mapPointerOut) override;
+ void unmap() override;
+
+ angle::Result packPixels(const gl::Context *context,
+ const gl::FramebufferAttachment &readAttachment,
+ const PackPixelsParams &params);
+
+ private:
+ angle::Result flushQueuedPackCommand(const gl::Context *context);
+
+ TextureHelper11 mStagingTexture;
+ angle::MemoryBuffer mMemoryBuffer;
+ std::unique_ptr<PackPixelsParams> mQueuedPackCommand;
+ PackPixelsParams mPackParams;
+ bool mDataModified;
+};
+
+// System memory storage stores a CPU memory buffer with our buffer data.
+// For dynamic data, it's much faster to update the CPU memory buffer than
+// it is to update a D3D staging buffer and read it back later.
+class Buffer11::SystemMemoryStorage : public Buffer11::BufferStorage
+{
+ public:
+ explicit SystemMemoryStorage(Renderer11 *renderer);
+ ~SystemMemoryStorage() override {}
+
+ bool isCPUAccessible(GLbitfield access) const override { return true; }
+
+ bool isGPUAccessible() const override { return false; }
+
+ angle::Result copyFromStorage(const gl::Context *context,
+ BufferStorage *source,
+ size_t sourceOffset,
+ size_t size,
+ size_t destOffset,
+ CopyResult *resultOut) override;
+ angle::Result resize(const gl::Context *context, size_t size, bool preserveData) override;
+
+ angle::Result map(const gl::Context *context,
+ size_t offset,
+ size_t length,
+ GLbitfield access,
+ uint8_t **mapPointerOut) override;
+ void unmap() override;
+
+ angle::MemoryBuffer *getSystemCopy() { return &mSystemCopy; }
+
+ protected:
+ angle::MemoryBuffer mSystemCopy;
+};
+
+Buffer11::Buffer11(const gl::BufferState &state, Renderer11 *renderer)
+ : BufferD3D(state, renderer),
+ mRenderer(renderer),
+ mSize(0),
+ mMappedStorage(nullptr),
+ mBufferStorages({}),
+ mLatestBufferStorage(nullptr),
+ mDeallocThresholds({}),
+ mIdleness({}),
+ mConstantBufferStorageAdditionalSize(0),
+ mMaxConstantBufferLruCount(0),
+ mStructuredBufferStorageAdditionalSize(0),
+ mMaxStructuredBufferLruCount(0)
+{}
+
+Buffer11::~Buffer11()
+{
+ for (BufferStorage *&storage : mBufferStorages)
+ {
+ SafeDelete(storage);
+ }
+
+ for (auto &p : mConstantBufferRangeStoragesCache)
+ {
+ SafeDelete(p.second.storage);
+ }
+
+ for (auto &p : mStructuredBufferRangeStoragesCache)
+ {
+ SafeDelete(p.second.storage);
+ }
+
+ mRenderer->onBufferDelete(this);
+}
+
+angle::Result Buffer11::setData(const gl::Context *context,
+ gl::BufferBinding target,
+ const void *data,
+ size_t size,
+ gl::BufferUsage usage)
+{
+ updateD3DBufferUsage(context, usage);
+ return setSubData(context, target, data, size, 0);
+}
+
+angle::Result Buffer11::getData(const gl::Context *context, const uint8_t **outData)
+{
+ if (mSize == 0)
+ {
+ // TODO(http://anglebug.com/2840): This ensures that we don't crash or assert in robust
+ // buffer access behavior mode if there are buffers without any data. However, technically
+ // it should still be possible to draw, with fetches from this buffer returning zero.
+ return angle::Result::Stop;
+ }
+
+ SystemMemoryStorage *systemMemoryStorage = nullptr;
+ ANGLE_TRY(getBufferStorage(context, BUFFER_USAGE_SYSTEM_MEMORY, &systemMemoryStorage));
+
+ ASSERT(systemMemoryStorage->getSize() >= mSize);
+
+ *outData = systemMemoryStorage->getSystemCopy()->data();
+ return angle::Result::Continue;
+}
+
+angle::Result Buffer11::setSubData(const gl::Context *context,
+ gl::BufferBinding 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 (target == gl::BufferBinding::Uniform)
+ {
+ // If we are a very large uniform buffer, keep system memory storage around so that we
+ // aren't forced to read back from a constant buffer. We also check the workaround for
+ // Intel - this requires us to use system memory so we don't end up having to copy from
+ // a constant buffer to a staging buffer.
+ // TODO(jmadill): Use Context caps.
+ if (offset == 0 && size >= mSize &&
+ size <= static_cast<UINT>(mRenderer->getNativeCaps().maxUniformBlockSize) &&
+ !mRenderer->getFeatures().useSystemMemoryForConstantBuffers.enabled)
+ {
+ BufferStorage *latestStorage = nullptr;
+ ANGLE_TRY(getLatestBufferStorage(context, &latestStorage));
+ if (latestStorage && (latestStorage->getUsage() == BUFFER_USAGE_STRUCTURED))
+ {
+ ANGLE_TRY(getBufferStorage(context, BUFFER_USAGE_STRUCTURED, &writeBuffer));
+ }
+ else
+ {
+ ANGLE_TRY(getBufferStorage(context, BUFFER_USAGE_UNIFORM, &writeBuffer));
+ }
+ }
+ else
+ {
+ ANGLE_TRY(getBufferStorage(context, BUFFER_USAGE_SYSTEM_MEMORY, &writeBuffer));
+ }
+ }
+ else if (supportsDirectBinding())
+ {
+ ANGLE_TRY(getStagingStorage(context, &writeBuffer));
+ }
+ else
+ {
+ ANGLE_TRY(getBufferStorage(context, BUFFER_USAGE_SYSTEM_MEMORY, &writeBuffer));
+ }
+
+ ASSERT(writeBuffer);
+
+ // Explicitly resize the staging buffer, preserving data if the new data will not
+ // completely fill the buffer
+ if (writeBuffer->getSize() < requiredSize)
+ {
+ bool preserveData = (offset > 0);
+ ANGLE_TRY(writeBuffer->resize(context, requiredSize, preserveData));
+ }
+
+ ANGLE_TRY(writeBuffer->setData(context, static_cast<const uint8_t *>(data), offset, size));
+ onStorageUpdate(writeBuffer);
+ }
+
+ mSize = std::max(mSize, requiredSize);
+ invalidateStaticData(context);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Buffer11::copySubData(const gl::Context *context,
+ BufferImpl *source,
+ GLintptr sourceOffset,
+ GLintptr destOffset,
+ GLsizeiptr size)
+{
+ Buffer11 *sourceBuffer = GetAs<Buffer11>(source);
+ ASSERT(sourceBuffer != nullptr);
+
+ BufferStorage *copyDest = nullptr;
+ ANGLE_TRY(getLatestBufferStorage(context, &copyDest));
+
+ if (!copyDest)
+ {
+ ANGLE_TRY(getStagingStorage(context, &copyDest));
+ }
+
+ BufferStorage *copySource = nullptr;
+ ANGLE_TRY(sourceBuffer->getLatestBufferStorage(context, &copySource));
+
+ if (!copySource)
+ {
+ ANGLE_TRY(sourceBuffer->getStagingStorage(context, &copySource));
+ }
+
+ ASSERT(copySource && copyDest);
+
+ // A staging buffer is needed if there is no cpu-cpu or gpu-gpu copy path avaiable.
+ if (!copyDest->isGPUAccessible() && !copySource->isCPUAccessible(GL_MAP_READ_BIT))
+ {
+ ANGLE_TRY(sourceBuffer->getStagingStorage(context, &copySource));
+ }
+ else if (!copySource->isGPUAccessible() && !copyDest->isCPUAccessible(GL_MAP_WRITE_BIT))
+ {
+ ANGLE_TRY(getStagingStorage(context, &copyDest));
+ }
+
+ // D3D11 does not allow overlapped copies until 11.1, and only if the
+ // device supports D3D11_FEATURE_DATA_D3D11_OPTIONS::CopyWithOverlap
+ // Get around this via a different source buffer
+ if (copySource == copyDest)
+ {
+ if (copySource->getUsage() == BUFFER_USAGE_STAGING)
+ {
+ ANGLE_TRY(
+ getBufferStorage(context, BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK, &copySource));
+ }
+ else
+ {
+ ANGLE_TRY(getStagingStorage(context, &copySource));
+ }
+ }
+
+ CopyResult copyResult = CopyResult::NOT_RECREATED;
+ ANGLE_TRY(copyDest->copyFromStorage(context, copySource, sourceOffset, size, destOffset,
+ &copyResult));
+ onStorageUpdate(copyDest);
+
+ mSize = std::max<size_t>(mSize, destOffset + size);
+ invalidateStaticData(context);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Buffer11::map(const gl::Context *context, GLenum access, void **mapPtr)
+{
+ // GL_OES_mapbuffer uses an enum instead of a bitfield for it's access, convert to a bitfield
+ // and call mapRange.
+ ASSERT(access == GL_WRITE_ONLY_OES);
+ return mapRange(context, 0, mSize, GL_MAP_WRITE_BIT, mapPtr);
+}
+
+angle::Result Buffer11::mapRange(const gl::Context *context,
+ size_t offset,
+ size_t length,
+ GLbitfield access,
+ void **mapPtr)
+{
+ ASSERT(!mMappedStorage);
+
+ BufferStorage *latestStorage = nullptr;
+ ANGLE_TRY(getLatestBufferStorage(context, &latestStorage));
+
+ if (latestStorage && (latestStorage->getUsage() == BUFFER_USAGE_PIXEL_PACK ||
+ latestStorage->getUsage() == BUFFER_USAGE_STAGING))
+ {
+ // Latest storage is mappable.
+ mMappedStorage = latestStorage;
+ }
+ else
+ {
+ // Fall back to using the staging buffer if the latest storage does not exist or is not
+ // CPU-accessible.
+ ANGLE_TRY(getStagingStorage(context, &mMappedStorage));
+ }
+
+ Context11 *context11 = GetImplAs<Context11>(context);
+ ANGLE_CHECK_GL_ALLOC(context11, mMappedStorage);
+
+ if ((access & GL_MAP_WRITE_BIT) > 0)
+ {
+ // Update the data revision immediately, since the data might be changed at any time
+ onStorageUpdate(mMappedStorage);
+ invalidateStaticData(context);
+ }
+
+ uint8_t *mappedBuffer = nullptr;
+ ANGLE_TRY(mMappedStorage->map(context, offset, length, access, &mappedBuffer));
+ ASSERT(mappedBuffer);
+
+ *mapPtr = static_cast<void *>(mappedBuffer);
+ return angle::Result::Continue;
+}
+
+angle::Result Buffer11::unmap(const gl::Context *context, GLboolean *result)
+{
+ ASSERT(mMappedStorage);
+ mMappedStorage->unmap();
+ mMappedStorage = nullptr;
+
+ // TODO: detect if we had corruption. if so, return false.
+ *result = GL_TRUE;
+
+ return angle::Result::Continue;
+}
+
+angle::Result Buffer11::markTransformFeedbackUsage(const gl::Context *context)
+{
+ ANGLE_TRY(markBufferUsage(context, BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK));
+ return angle::Result::Continue;
+}
+
+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 buffer memory.
+ // After that, double the threshold each time until we reach the max.
+ if (mDeallocThresholds[usage] == 0)
+ {
+ mDeallocThresholds[usage] = 8;
+ }
+ else if (mDeallocThresholds[usage] < std::numeric_limits<unsigned int>::max() / 2u)
+ {
+ mDeallocThresholds[usage] *= 2u;
+ }
+ else
+ {
+ mDeallocThresholds[usage] = std::numeric_limits<unsigned int>::max();
+ }
+}
+
+// Free the storage if we decide it isn't being used very often.
+angle::Result Buffer11::checkForDeallocation(const gl::Context *context, BufferUsage usage)
+{
+ mIdleness[usage]++;
+
+ BufferStorage *&storage = mBufferStorages[usage];
+ if (storage != nullptr && mIdleness[usage] > mDeallocThresholds[usage])
+ {
+ BufferStorage *latestStorage = nullptr;
+ ANGLE_TRY(getLatestBufferStorage(context, &latestStorage));
+ if (latestStorage != storage)
+ {
+ SafeDelete(storage);
+ }
+ }
+
+ return angle::Result::Continue;
+}
+
+// Keep system memory when we are using it for the canonical version of data.
+bool Buffer11::canDeallocateSystemMemory() const
+{
+ // Must keep system memory on Intel.
+ if (mRenderer->getFeatures().useSystemMemoryForConstantBuffers.enabled)
+ {
+ return false;
+ }
+
+ return (!mBufferStorages[BUFFER_USAGE_UNIFORM] ||
+ mSize <= static_cast<size_t>(mRenderer->getNativeCaps().maxUniformBlockSize));
+}
+
+void Buffer11::markBufferUsage(BufferUsage usage)
+{
+ mIdleness[usage] = 0;
+}
+
+angle::Result Buffer11::markBufferUsage(const gl::Context *context, BufferUsage usage)
+{
+ BufferStorage *bufferStorage = nullptr;
+ ANGLE_TRY(getBufferStorage(context, usage, &bufferStorage));
+
+ if (bufferStorage)
+ {
+ onStorageUpdate(bufferStorage);
+ }
+
+ invalidateStaticData(context);
+ return angle::Result::Continue;
+}
+
+angle::Result Buffer11::garbageCollection(const gl::Context *context, BufferUsage currentUsage)
+{
+ if (currentUsage != BUFFER_USAGE_SYSTEM_MEMORY && canDeallocateSystemMemory())
+ {
+ ANGLE_TRY(checkForDeallocation(context, BUFFER_USAGE_SYSTEM_MEMORY));
+ }
+
+ if (currentUsage != BUFFER_USAGE_STAGING)
+ {
+ ANGLE_TRY(checkForDeallocation(context, BUFFER_USAGE_STAGING));
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result Buffer11::getBuffer(const gl::Context *context,
+ BufferUsage usage,
+ ID3D11Buffer **bufferOut)
+{
+ NativeStorage *storage = nullptr;
+ ANGLE_TRY(getBufferStorage(context, usage, &storage));
+ *bufferOut = storage->getBuffer().get();
+ return angle::Result::Continue;
+}
+
+angle::Result Buffer11::getEmulatedIndexedBuffer(const gl::Context *context,
+ SourceIndexData *indexInfo,
+ const TranslatedAttribute &attribute,
+ GLint startVertex,
+ ID3D11Buffer **bufferOut)
+{
+ ASSERT(indexInfo);
+
+ EmulatedIndexedStorage *emulatedStorage = nullptr;
+ ANGLE_TRY(getBufferStorage(context, BUFFER_USAGE_EMULATED_INDEXED_VERTEX, &emulatedStorage));
+
+ const d3d11::Buffer *nativeBuffer = nullptr;
+ ANGLE_TRY(
+ emulatedStorage->getBuffer(context, indexInfo, attribute, startVertex, &nativeBuffer));
+ *bufferOut = nativeBuffer->get();
+ return angle::Result::Continue;
+}
+
+angle::Result Buffer11::getConstantBufferRange(const gl::Context *context,
+ GLintptr offset,
+ GLsizeiptr size,
+ const d3d11::Buffer **bufferOut,
+ UINT *firstConstantOut,
+ UINT *numConstantsOut)
+{
+ NativeStorage *bufferStorage = nullptr;
+ if ((offset == 0 &&
+ size < static_cast<GLsizeiptr>(mRenderer->getNativeCaps().maxUniformBlockSize)) ||
+ mRenderer->getRenderer11DeviceCaps().supportsConstantBufferOffsets)
+ {
+ ANGLE_TRY(getBufferStorage(context, BUFFER_USAGE_UNIFORM, &bufferStorage));
+ CalculateConstantBufferParams(offset, size, firstConstantOut, numConstantsOut);
+ }
+ else
+ {
+ ANGLE_TRY(getConstantBufferRangeStorage(context, offset, size, &bufferStorage));
+ *firstConstantOut = 0;
+ *numConstantsOut = 0;
+ }
+
+ *bufferOut = &bufferStorage->getBuffer();
+ return angle::Result::Continue;
+}
+
+angle::Result Buffer11::markRawBufferUsage(const gl::Context *context)
+{
+ ANGLE_TRY(markBufferUsage(context, BUFFER_USAGE_RAW_UAV));
+ return angle::Result::Continue;
+}
+
+angle::Result Buffer11::markTypedBufferUsage(const gl::Context *context)
+{
+ ANGLE_TRY(markBufferUsage(context, BUFFER_USAGE_TYPED_UAV));
+ return angle::Result::Continue;
+}
+
+angle::Result Buffer11::getRawUAVRange(const gl::Context *context,
+ GLintptr offset,
+ GLsizeiptr size,
+ d3d11::UnorderedAccessView **uavOut)
+{
+ NativeStorage *nativeStorage = nullptr;
+ ANGLE_TRY(getBufferStorage(context, BUFFER_USAGE_RAW_UAV, &nativeStorage));
+
+ return nativeStorage->getRawUAV(context, static_cast<unsigned int>(offset),
+ static_cast<unsigned int>(size), uavOut);
+}
+
+angle::Result Buffer11::getSRV(const gl::Context *context,
+ DXGI_FORMAT srvFormat,
+ const d3d11::ShaderResourceView **srvOut)
+{
+ NativeStorage *nativeStorage = nullptr;
+ ANGLE_TRY(getBufferStorage(context, BUFFER_USAGE_PIXEL_UNPACK, &nativeStorage));
+ return nativeStorage->getSRVForFormat(context, srvFormat, srvOut);
+}
+
+angle::Result Buffer11::packPixels(const gl::Context *context,
+ const gl::FramebufferAttachment &readAttachment,
+ const PackPixelsParams &params)
+{
+ PackStorage *packStorage = nullptr;
+ ANGLE_TRY(getBufferStorage(context, BUFFER_USAGE_PIXEL_PACK, &packStorage));
+
+ ASSERT(packStorage);
+ ANGLE_TRY(packStorage->packPixels(context, readAttachment, params));
+ onStorageUpdate(packStorage);
+
+ return angle::Result::Continue;
+}
+
+size_t Buffer11::getTotalCPUBufferMemoryBytes() const
+{
+ size_t allocationSize = 0;
+
+ BufferStorage *staging = mBufferStorages[BUFFER_USAGE_STAGING];
+ allocationSize += staging ? staging->getSize() : 0;
+
+ BufferStorage *sysMem = mBufferStorages[BUFFER_USAGE_SYSTEM_MEMORY];
+ allocationSize += sysMem ? sysMem->getSize() : 0;
+
+ return allocationSize;
+}
+
+template <typename StorageOutT>
+angle::Result Buffer11::getBufferStorage(const gl::Context *context,
+ BufferUsage usage,
+ StorageOutT **storageOut)
+{
+ ASSERT(0 <= usage && usage < BUFFER_USAGE_COUNT);
+ BufferStorage *&newStorage = mBufferStorages[usage];
+
+ if (!newStorage)
+ {
+ newStorage = allocateStorage(usage);
+ }
+
+ markBufferUsage(usage);
+
+ // resize buffer
+ if (newStorage->getSize() < mSize)
+ {
+ ANGLE_TRY(newStorage->resize(context, mSize, true));
+ }
+
+ ASSERT(newStorage);
+
+ ANGLE_TRY(updateBufferStorage(context, newStorage, 0, mSize));
+ ANGLE_TRY(garbageCollection(context, usage));
+
+ *storageOut = GetAs<StorageOutT>(newStorage);
+ return angle::Result::Continue;
+}
+
+Buffer11::BufferStorage *Buffer11::allocateStorage(BufferUsage usage)
+{
+ updateDeallocThreshold(usage);
+ switch (usage)
+ {
+ case BUFFER_USAGE_PIXEL_PACK:
+ return new PackStorage(mRenderer);
+ case BUFFER_USAGE_SYSTEM_MEMORY:
+ return new SystemMemoryStorage(mRenderer);
+ case BUFFER_USAGE_EMULATED_INDEXED_VERTEX:
+ return new EmulatedIndexedStorage(mRenderer);
+ case BUFFER_USAGE_INDEX:
+ case BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK:
+ return new NativeStorage(mRenderer, usage, this);
+ case BUFFER_USAGE_STRUCTURED:
+ return new StructuredBufferStorage(mRenderer, usage, nullptr);
+ default:
+ return new NativeStorage(mRenderer, usage, nullptr);
+ }
+}
+
+angle::Result Buffer11::getConstantBufferRangeStorage(const gl::Context *context,
+ GLintptr offset,
+ GLsizeiptr size,
+ Buffer11::NativeStorage **storageOut)
+{
+ BufferStorage *newStorage;
+ {
+ // Keep the cacheEntry in a limited scope because it may be invalidated later in the code if
+ // we need to reclaim some space.
+ BufferCacheEntry *cacheEntry = &mConstantBufferRangeStoragesCache[offset];
+
+ if (!cacheEntry->storage)
+ {
+ cacheEntry->storage = allocateStorage(BUFFER_USAGE_UNIFORM);
+ cacheEntry->lruCount = ++mMaxConstantBufferLruCount;
+ }
+
+ cacheEntry->lruCount = ++mMaxConstantBufferLruCount;
+ newStorage = cacheEntry->storage;
+ }
+
+ markBufferUsage(BUFFER_USAGE_UNIFORM);
+
+ if (newStorage->getSize() < static_cast<size_t>(size))
+ {
+ size_t maximumAllowedAdditionalSize = 2 * getSize();
+
+ size_t sizeDelta = size - newStorage->getSize();
+
+ while (mConstantBufferStorageAdditionalSize + sizeDelta > maximumAllowedAdditionalSize)
+ {
+ auto iter = std::min_element(
+ std::begin(mConstantBufferRangeStoragesCache),
+ std::end(mConstantBufferRangeStoragesCache),
+ [](const BufferCache::value_type &a, const BufferCache::value_type &b) {
+ return a.second.lruCount < b.second.lruCount;
+ });
+
+ ASSERT(iter->second.storage != newStorage);
+ ASSERT(mConstantBufferStorageAdditionalSize >= iter->second.storage->getSize());
+
+ mConstantBufferStorageAdditionalSize -= iter->second.storage->getSize();
+ SafeDelete(iter->second.storage);
+ mConstantBufferRangeStoragesCache.erase(iter);
+ }
+
+ ANGLE_TRY(newStorage->resize(context, size, false));
+ mConstantBufferStorageAdditionalSize += sizeDelta;
+
+ // We don't copy the old data when resizing the constant buffer because the data may be
+ // out-of-date therefore we reset the data revision and let updateBufferStorage() handle the
+ // copy.
+ newStorage->setDataRevision(0);
+ }
+
+ ANGLE_TRY(updateBufferStorage(context, newStorage, offset, size));
+ ANGLE_TRY(garbageCollection(context, BUFFER_USAGE_UNIFORM));
+ *storageOut = GetAs<NativeStorage>(newStorage);
+ return angle::Result::Continue;
+}
+
+angle::Result Buffer11::getStructuredBufferRangeSRV(const gl::Context *context,
+ unsigned int offset,
+ unsigned int size,
+ unsigned int structureByteStride,
+ const d3d11::ShaderResourceView **srvOut)
+{
+ BufferStorage *newStorage;
+
+ {
+ // Keep the cacheEntry in a limited scope because it may be invalidated later in the code if
+ // we need to reclaim some space.
+ StructuredBufferKey structuredBufferKey = StructuredBufferKey(offset, structureByteStride);
+ BufferCacheEntry *cacheEntry = &mStructuredBufferRangeStoragesCache[structuredBufferKey];
+
+ if (!cacheEntry->storage)
+ {
+ cacheEntry->storage = allocateStorage(BUFFER_USAGE_STRUCTURED);
+ cacheEntry->lruCount = ++mMaxStructuredBufferLruCount;
+ }
+
+ cacheEntry->lruCount = ++mMaxStructuredBufferLruCount;
+ newStorage = cacheEntry->storage;
+ }
+
+ StructuredBufferStorage *structuredBufferStorage = GetAs<StructuredBufferStorage>(newStorage);
+
+ markBufferUsage(BUFFER_USAGE_STRUCTURED);
+
+ if (newStorage->getSize() < static_cast<size_t>(size))
+ {
+ size_t maximumAllowedAdditionalSize = 2 * getSize();
+
+ size_t sizeDelta = static_cast<size_t>(size) - newStorage->getSize();
+
+ while (mStructuredBufferStorageAdditionalSize + sizeDelta > maximumAllowedAdditionalSize)
+ {
+ auto iter = std::min_element(std::begin(mStructuredBufferRangeStoragesCache),
+ std::end(mStructuredBufferRangeStoragesCache),
+ [](const StructuredBufferCache::value_type &a,
+ const StructuredBufferCache::value_type &b) {
+ return a.second.lruCount < b.second.lruCount;
+ });
+
+ ASSERT(iter->second.storage != newStorage);
+ ASSERT(mStructuredBufferStorageAdditionalSize >= iter->second.storage->getSize());
+
+ mStructuredBufferStorageAdditionalSize -= iter->second.storage->getSize();
+ SafeDelete(iter->second.storage);
+ mStructuredBufferRangeStoragesCache.erase(iter);
+ }
+
+ ANGLE_TRY(
+ structuredBufferStorage->resizeStructuredBuffer(context, size, structureByteStride));
+ mStructuredBufferStorageAdditionalSize += sizeDelta;
+
+ // We don't copy the old data when resizing the structured buffer because the data may be
+ // out-of-date therefore we reset the data revision and let updateBufferStorage() handle the
+ // copy.
+ newStorage->setDataRevision(0);
+ }
+
+ ANGLE_TRY(updateBufferStorage(context, newStorage, offset, static_cast<size_t>(size)));
+ ANGLE_TRY(garbageCollection(context, BUFFER_USAGE_STRUCTURED));
+ ANGLE_TRY(structuredBufferStorage->getStructuredBufferRangeSRV(context, offset, size,
+ structureByteStride, srvOut));
+ return angle::Result::Continue;
+}
+
+angle::Result Buffer11::updateBufferStorage(const gl::Context *context,
+ BufferStorage *storage,
+ size_t sourceOffset,
+ size_t storageSize)
+{
+ BufferStorage *latestBuffer = nullptr;
+ ANGLE_TRY(getLatestBufferStorage(context, &latestBuffer));
+
+ ASSERT(storage);
+
+ if (!latestBuffer)
+ {
+ onStorageUpdate(storage);
+ return angle::Result::Continue;
+ }
+
+ if (latestBuffer->getDataRevision() <= storage->getDataRevision())
+ {
+ return angle::Result::Continue;
+ }
+
+ if (latestBuffer->getSize() == 0 || storage->getSize() == 0)
+ {
+ return angle::Result::Continue;
+ }
+
+ // Copy through a staging buffer if we're copying from or to a non-staging, mappable
+ // buffer storage. This is because we can't map a GPU buffer, and copy CPU
+ // 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->isCPUAccessible(GL_MAP_READ_BIT) ||
+ !storage->isCPUAccessible(GL_MAP_WRITE_BIT)))
+ {
+ NativeStorage *stagingBuffer = nullptr;
+ ANGLE_TRY(getStagingStorage(context, &stagingBuffer));
+
+ CopyResult copyResult = CopyResult::NOT_RECREATED;
+ ANGLE_TRY(stagingBuffer->copyFromStorage(context, latestBuffer, 0, latestBuffer->getSize(),
+ 0, &copyResult));
+ onCopyStorage(stagingBuffer, latestBuffer);
+
+ latestBuffer = stagingBuffer;
+ }
+
+ CopyResult copyResult = CopyResult::NOT_RECREATED;
+ ANGLE_TRY(
+ storage->copyFromStorage(context, latestBuffer, sourceOffset, storageSize, 0, &copyResult));
+ // If the D3D buffer has been recreated, we should update our serial.
+ if (copyResult == CopyResult::RECREATED)
+ {
+ updateSerial();
+ }
+ onCopyStorage(storage, latestBuffer);
+ return angle::Result::Continue;
+}
+
+angle::Result Buffer11::getLatestBufferStorage(const gl::Context *context,
+ Buffer11::BufferStorage **storageOut) const
+{
+ // resize buffer
+ if (mLatestBufferStorage && mLatestBufferStorage->getSize() < mSize)
+ {
+ ANGLE_TRY(mLatestBufferStorage->resize(context, mSize, true));
+ }
+
+ *storageOut = mLatestBufferStorage;
+ return angle::Result::Continue;
+}
+
+template <typename StorageOutT>
+angle::Result Buffer11::getStagingStorage(const gl::Context *context, StorageOutT **storageOut)
+{
+ return getBufferStorage(context, BUFFER_USAGE_STAGING, storageOut);
+}
+
+size_t Buffer11::getSize() const
+{
+ return mSize;
+}
+
+bool Buffer11::supportsDirectBinding() const
+{
+ // Do not support direct buffers for dynamic data. The streaming buffer
+ // offers better performance for data which changes every frame.
+ return (mUsage == D3DBufferUsage::STATIC);
+}
+
+void Buffer11::initializeStaticData(const gl::Context *context)
+{
+ BufferD3D::initializeStaticData(context);
+ onStateChange(angle::SubjectMessage::SubjectChanged);
+}
+
+void Buffer11::invalidateStaticData(const gl::Context *context)
+{
+ BufferD3D::invalidateStaticData(context);
+ onStateChange(angle::SubjectMessage::SubjectChanged);
+}
+
+void Buffer11::onCopyStorage(BufferStorage *dest, BufferStorage *source)
+{
+ ASSERT(source && mLatestBufferStorage);
+ dest->setDataRevision(source->getDataRevision());
+
+ // Only update the latest buffer storage if our usage index is lower. See comment in header.
+ if (dest->getUsage() < mLatestBufferStorage->getUsage())
+ {
+ mLatestBufferStorage = dest;
+ }
+}
+
+void Buffer11::onStorageUpdate(BufferStorage *updatedStorage)
+{
+ updatedStorage->setDataRevision(updatedStorage->getDataRevision() + 1);
+ mLatestBufferStorage = updatedStorage;
+}
+
+// Buffer11::BufferStorage implementation
+
+Buffer11::BufferStorage::BufferStorage(Renderer11 *renderer, BufferUsage usage)
+ : mRenderer(renderer), mRevision(0), mUsage(usage), mBufferSize(0)
+{}
+
+angle::Result Buffer11::BufferStorage::setData(const gl::Context *context,
+ const uint8_t *data,
+ size_t offset,
+ size_t size)
+{
+ ASSERT(isCPUAccessible(GL_MAP_WRITE_BIT));
+
+ // Uniform storage can have a different internal size than the buffer size. Ensure we don't
+ // overflow.
+ size_t mapSize = std::min(size, mBufferSize - offset);
+
+ uint8_t *writePointer = nullptr;
+ ANGLE_TRY(map(context, offset, mapSize, GL_MAP_WRITE_BIT, &writePointer));
+
+ memcpy(writePointer, data, mapSize);
+
+ unmap();
+
+ return angle::Result::Continue;
+}
+
+// Buffer11::NativeStorage implementation
+
+Buffer11::NativeStorage::NativeStorage(Renderer11 *renderer,
+ BufferUsage usage,
+ const angle::Subject *onStorageChanged)
+ : BufferStorage(renderer, usage), mBuffer(), mOnStorageChanged(onStorageChanged)
+{}
+
+Buffer11::NativeStorage::~NativeStorage()
+{
+ clearSRVs();
+ clearUAVs();
+}
+
+bool Buffer11::NativeStorage::isCPUAccessible(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 ||
+ mUsage == BUFFER_USAGE_STRUCTURED);
+}
+
+// Returns true if it recreates the direct buffer
+angle::Result Buffer11::NativeStorage::copyFromStorage(const gl::Context *context,
+ BufferStorage *source,
+ size_t sourceOffset,
+ size_t size,
+ size_t destOffset,
+ CopyResult *resultOut)
+{
+ size_t requiredSize = destOffset + size;
+
+ // (Re)initialize D3D buffer if needed
+ bool preserveData = (destOffset > 0);
+ if (!mBuffer.valid() || mBufferSize < requiredSize)
+ {
+ ANGLE_TRY(resize(context, requiredSize, preserveData));
+ *resultOut = CopyResult::RECREATED;
+ }
+ else
+ {
+ *resultOut = CopyResult::NOT_RECREATED;
+ }
+
+ size_t clampedSize = size;
+ if (mUsage == BUFFER_USAGE_UNIFORM)
+ {
+ clampedSize = std::min(clampedSize, mBufferSize - destOffset);
+ }
+
+ if (clampedSize == 0)
+ {
+ return angle::Result::Continue;
+ }
+
+ if (source->getUsage() == BUFFER_USAGE_PIXEL_PACK ||
+ source->getUsage() == BUFFER_USAGE_SYSTEM_MEMORY)
+ {
+ ASSERT(source->isCPUAccessible(GL_MAP_READ_BIT) && isCPUAccessible(GL_MAP_WRITE_BIT));
+
+ // Uniform buffers must be mapped with write/discard.
+ ASSERT(!(preserveData && mUsage == BUFFER_USAGE_UNIFORM));
+
+ uint8_t *sourcePointer = nullptr;
+ ANGLE_TRY(source->map(context, sourceOffset, clampedSize, GL_MAP_READ_BIT, &sourcePointer));
+
+ auto err = setData(context, sourcePointer, destOffset, clampedSize);
+ source->unmap();
+ ANGLE_TRY(err);
+ }
+ else
+ {
+ D3D11_BOX srcBox;
+ srcBox.left = static_cast<unsigned int>(sourceOffset);
+ srcBox.right = static_cast<unsigned int>(sourceOffset + clampedSize);
+ srcBox.top = 0;
+ srcBox.bottom = 1;
+ srcBox.front = 0;
+ srcBox.back = 1;
+
+ const d3d11::Buffer *sourceBuffer = &GetAs<NativeStorage>(source)->getBuffer();
+
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+ deviceContext->CopySubresourceRegion(mBuffer.get(), 0,
+ static_cast<unsigned int>(destOffset), 0, 0,
+ sourceBuffer->get(), 0, &srcBox);
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result Buffer11::NativeStorage::resize(const gl::Context *context,
+ size_t size,
+ bool preserveData)
+{
+ if (size == 0)
+ {
+ mBuffer.reset();
+ mBufferSize = 0;
+ return angle::Result::Continue;
+ }
+
+ D3D11_BUFFER_DESC bufferDesc;
+ FillBufferDesc(&bufferDesc, mRenderer, mUsage, static_cast<unsigned int>(size));
+
+ d3d11::Buffer newBuffer;
+ ANGLE_TRY(
+ mRenderer->allocateResource(SafeGetImplAs<Context11>(context), bufferDesc, &newBuffer));
+ newBuffer.setInternalName("Buffer11::NativeStorage");
+
+ if (mBuffer.valid() && preserveData)
+ {
+ // We don't call resize if the buffer is big enough already.
+ ASSERT(mBufferSize <= size);
+
+ D3D11_BOX srcBox;
+ srcBox.left = 0;
+ srcBox.right = static_cast<unsigned int>(mBufferSize);
+ srcBox.top = 0;
+ srcBox.bottom = 1;
+ srcBox.front = 0;
+ srcBox.back = 1;
+
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+ deviceContext->CopySubresourceRegion(newBuffer.get(), 0, 0, 0, 0, mBuffer.get(), 0,
+ &srcBox);
+ }
+
+ // No longer need the old buffer
+ mBuffer = std::move(newBuffer);
+
+ mBufferSize = bufferDesc.ByteWidth;
+
+ // Free the SRVs.
+ clearSRVs();
+
+ // Free the UAVs.
+ clearUAVs();
+
+ // Notify that the storage has changed.
+ if (mOnStorageChanged)
+ {
+ mOnStorageChanged->onStateChange(angle::SubjectMessage::SubjectChanged);
+ }
+
+ return angle::Result::Continue;
+}
+
+// static
+void Buffer11::NativeStorage::FillBufferDesc(D3D11_BUFFER_DESC *bufferDesc,
+ Renderer11 *renderer,
+ BufferUsage usage,
+ unsigned int bufferSize)
+{
+ bufferDesc->ByteWidth = bufferSize;
+ bufferDesc->MiscFlags = 0;
+ bufferDesc->StructureByteStride = 0;
+
+ switch (usage)
+ {
+ case BUFFER_USAGE_STAGING:
+ bufferDesc->Usage = D3D11_USAGE_STAGING;
+ bufferDesc->BindFlags = 0;
+ bufferDesc->CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
+ break;
+
+ case BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK:
+ bufferDesc->Usage = D3D11_USAGE_DEFAULT;
+ bufferDesc->BindFlags = D3D11_BIND_VERTEX_BUFFER;
+
+ if (renderer->isES3Capable())
+ {
+ bufferDesc->BindFlags |= D3D11_BIND_STREAM_OUTPUT;
+ }
+
+ bufferDesc->CPUAccessFlags = 0;
+ break;
+
+ case BUFFER_USAGE_INDEX:
+ bufferDesc->Usage = D3D11_USAGE_DEFAULT;
+ bufferDesc->BindFlags = D3D11_BIND_INDEX_BUFFER;
+ bufferDesc->CPUAccessFlags = 0;
+ break;
+
+ case BUFFER_USAGE_INDIRECT:
+ bufferDesc->MiscFlags = D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS;
+ bufferDesc->Usage = D3D11_USAGE_DEFAULT;
+ bufferDesc->BindFlags = 0;
+ bufferDesc->CPUAccessFlags = 0;
+ break;
+
+ case BUFFER_USAGE_PIXEL_UNPACK:
+ bufferDesc->Usage = D3D11_USAGE_DEFAULT;
+ bufferDesc->BindFlags = D3D11_BIND_SHADER_RESOURCE;
+ bufferDesc->CPUAccessFlags = 0;
+ break;
+
+ case BUFFER_USAGE_UNIFORM:
+ bufferDesc->Usage = D3D11_USAGE_DYNAMIC;
+ bufferDesc->BindFlags = D3D11_BIND_CONSTANT_BUFFER;
+ bufferDesc->CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+
+ // 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 = roundUpPow2(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)
+ if (!renderer->getRenderer11DeviceCaps().supportsConstantBufferOffsets)
+ {
+ bufferDesc->ByteWidth = std::min<UINT>(
+ bufferDesc->ByteWidth,
+ static_cast<UINT>(renderer->getNativeCaps().maxUniformBlockSize));
+ }
+ break;
+
+ case BUFFER_USAGE_RAW_UAV:
+ bufferDesc->MiscFlags = D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS;
+ bufferDesc->BindFlags = D3D11_BIND_UNORDERED_ACCESS;
+ bufferDesc->Usage = D3D11_USAGE_DEFAULT;
+ bufferDesc->CPUAccessFlags = 0;
+ break;
+ case BUFFER_USAGE_TYPED_UAV:
+ bufferDesc->BindFlags = D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE;
+ bufferDesc->Usage = D3D11_USAGE_DEFAULT;
+ bufferDesc->CPUAccessFlags = 0;
+ bufferDesc->MiscFlags = 0;
+ break;
+
+ default:
+ UNREACHABLE();
+ }
+}
+
+angle::Result Buffer11::NativeStorage::map(const gl::Context *context,
+ size_t offset,
+ size_t length,
+ GLbitfield access,
+ uint8_t **mapPointerOut)
+{
+ ASSERT(isCPUAccessible(access));
+
+ D3D11_MAPPED_SUBRESOURCE mappedResource;
+ D3D11_MAP d3dMapType = gl_d3d11::GetD3DMapTypeFromBits(mUsage, access);
+ UINT d3dMapFlag = ((access & GL_MAP_UNSYNCHRONIZED_BIT) != 0 ? D3D11_MAP_FLAG_DO_NOT_WAIT : 0);
+
+ ANGLE_TRY(
+ mRenderer->mapResource(context, mBuffer.get(), 0, d3dMapType, d3dMapFlag, &mappedResource));
+ ASSERT(mappedResource.pData);
+ *mapPointerOut = static_cast<uint8_t *>(mappedResource.pData) + offset;
+ return angle::Result::Continue;
+}
+
+void Buffer11::NativeStorage::unmap()
+{
+ ASSERT(isCPUAccessible(GL_MAP_WRITE_BIT) || isCPUAccessible(GL_MAP_READ_BIT));
+ ID3D11DeviceContext *context = mRenderer->getDeviceContext();
+ context->Unmap(mBuffer.get(), 0);
+}
+
+angle::Result Buffer11::NativeStorage::getSRVForFormat(const gl::Context *context,
+ DXGI_FORMAT srvFormat,
+ const d3d11::ShaderResourceView **srvOut)
+{
+ auto bufferSRVIt = mBufferResourceViews.find(srvFormat);
+
+ if (bufferSRVIt != mBufferResourceViews.end())
+ {
+ *srvOut = &bufferSRVIt->second;
+ return angle::Result::Continue;
+ }
+
+ 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;
+
+ ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), bufferSRVDesc,
+ mBuffer.get(), &mBufferResourceViews[srvFormat]));
+
+ *srvOut = &mBufferResourceViews[srvFormat];
+ return angle::Result::Continue;
+}
+
+angle::Result Buffer11::NativeStorage::getRawUAV(const gl::Context *context,
+ unsigned int offset,
+ unsigned int size,
+ d3d11::UnorderedAccessView **uavOut)
+{
+ ASSERT(offset + size <= mBufferSize);
+
+ auto bufferRawUAV = mBufferRawUAVs.find({offset, size});
+ if (bufferRawUAV != mBufferRawUAVs.end())
+ {
+ *uavOut = &bufferRawUAV->second;
+ return angle::Result::Continue;
+ }
+
+ D3D11_UNORDERED_ACCESS_VIEW_DESC bufferUAVDesc;
+
+ // DXGI_FORMAT_R32_TYPELESS uses 4 bytes per element
+ constexpr int kBytesToElement = 4;
+ bufferUAVDesc.Buffer.FirstElement = offset / kBytesToElement;
+ bufferUAVDesc.Buffer.NumElements = size / kBytesToElement;
+ bufferUAVDesc.Buffer.Flags = D3D11_BUFFER_UAV_FLAG_RAW;
+ bufferUAVDesc.Format = DXGI_FORMAT_R32_TYPELESS; // Format must be DXGI_FORMAT_R32_TYPELESS,
+ // when creating Raw Unordered Access View
+ bufferUAVDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
+
+ ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), bufferUAVDesc,
+ mBuffer.get(), &mBufferRawUAVs[{offset, size}]));
+ *uavOut = &mBufferRawUAVs[{offset, size}];
+ return angle::Result::Continue;
+}
+
+void Buffer11::NativeStorage::clearSRVs()
+{
+ mBufferResourceViews.clear();
+}
+
+void Buffer11::NativeStorage::clearUAVs()
+{
+ mBufferRawUAVs.clear();
+}
+
+Buffer11::StructuredBufferStorage::StructuredBufferStorage(Renderer11 *renderer,
+ BufferUsage usage,
+ const angle::Subject *onStorageChanged)
+ : NativeStorage(renderer, usage, onStorageChanged), mStructuredBufferResourceView()
+{}
+
+Buffer11::StructuredBufferStorage::~StructuredBufferStorage()
+{
+ mStructuredBufferResourceView.reset();
+}
+
+angle::Result Buffer11::StructuredBufferStorage::resizeStructuredBuffer(
+ const gl::Context *context,
+ unsigned int size,
+ unsigned int structureByteStride)
+{
+ if (size == 0)
+ {
+ mBuffer.reset();
+ mBufferSize = 0;
+ return angle::Result::Continue;
+ }
+
+ D3D11_BUFFER_DESC bufferDesc;
+ bufferDesc.ByteWidth = size;
+ bufferDesc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
+ bufferDesc.StructureByteStride = structureByteStride;
+ bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
+ bufferDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
+ bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+
+ d3d11::Buffer newBuffer;
+ ANGLE_TRY(
+ mRenderer->allocateResource(SafeGetImplAs<Context11>(context), bufferDesc, &newBuffer));
+ newBuffer.setInternalName("Buffer11::StructuredBufferStorage");
+
+ // No longer need the old buffer
+ mBuffer = std::move(newBuffer);
+
+ mBufferSize = static_cast<size_t>(bufferDesc.ByteWidth);
+
+ mStructuredBufferResourceView.reset();
+
+ // Notify that the storage has changed.
+ if (mOnStorageChanged)
+ {
+ mOnStorageChanged->onStateChange(angle::SubjectMessage::SubjectChanged);
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result Buffer11::StructuredBufferStorage::getStructuredBufferRangeSRV(
+ const gl::Context *context,
+ unsigned int offset,
+ unsigned int size,
+ unsigned int structureByteStride,
+ const d3d11::ShaderResourceView **srvOut)
+{
+ if (mStructuredBufferResourceView.valid())
+ {
+ *srvOut = &mStructuredBufferResourceView;
+ return angle::Result::Continue;
+ }
+
+ D3D11_SHADER_RESOURCE_VIEW_DESC bufferSRVDesc = {};
+ bufferSRVDesc.BufferEx.NumElements = structureByteStride == 0u ? 1 : size / structureByteStride;
+ bufferSRVDesc.BufferEx.FirstElement = 0;
+ bufferSRVDesc.BufferEx.Flags = 0;
+ bufferSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFEREX;
+ bufferSRVDesc.Format = DXGI_FORMAT_UNKNOWN;
+
+ ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), bufferSRVDesc,
+ mBuffer.get(), &mStructuredBufferResourceView));
+
+ *srvOut = &mStructuredBufferResourceView;
+ return angle::Result::Continue;
+}
+
+// Buffer11::EmulatedIndexStorage implementation
+Buffer11::EmulatedIndexedStorage::EmulatedIndexedStorage(Renderer11 *renderer)
+ : BufferStorage(renderer, BUFFER_USAGE_EMULATED_INDEXED_VERTEX), mBuffer()
+{}
+
+Buffer11::EmulatedIndexedStorage::~EmulatedIndexedStorage() {}
+
+angle::Result Buffer11::EmulatedIndexedStorage::getBuffer(const gl::Context *context,
+ SourceIndexData *indexInfo,
+ const TranslatedAttribute &attribute,
+ GLint startVertex,
+ const d3d11::Buffer **bufferOut)
+{
+ Context11 *context11 = GetImplAs<Context11>(context);
+
+ // If a change in the indices applied from the last draw call is detected, then the emulated
+ // indexed buffer needs to be invalidated. After invalidation, the change detected flag should
+ // be cleared to avoid unnecessary recreation of the buffer.
+ if (!mBuffer.valid() || indexInfo->srcIndicesChanged)
+ {
+ mBuffer.reset();
+
+ // Copy the source index data. This ensures that the lifetime of the indices pointer
+ // stays with this storage until the next time we invalidate.
+ size_t indicesDataSize = 0;
+ switch (indexInfo->srcIndexType)
+ {
+ case gl::DrawElementsType::UnsignedInt:
+ indicesDataSize = sizeof(GLuint) * indexInfo->srcCount;
+ break;
+ case gl::DrawElementsType::UnsignedShort:
+ indicesDataSize = sizeof(GLushort) * indexInfo->srcCount;
+ break;
+ case gl::DrawElementsType::UnsignedByte:
+ indicesDataSize = sizeof(GLubyte) * indexInfo->srcCount;
+ break;
+ default:
+ indicesDataSize = sizeof(GLushort) * indexInfo->srcCount;
+ break;
+ }
+
+ ANGLE_CHECK_GL_ALLOC(context11, mIndicesMemoryBuffer.resize(indicesDataSize));
+
+ memcpy(mIndicesMemoryBuffer.data(), indexInfo->srcIndices, indicesDataSize);
+
+ indexInfo->srcIndicesChanged = false;
+ }
+
+ if (!mBuffer.valid())
+ {
+ unsigned int offset = 0;
+ ANGLE_TRY(attribute.computeOffset(context, startVertex, &offset));
+
+ // Expand the memory storage upon request and cache the results.
+ unsigned int expandedDataSize =
+ static_cast<unsigned int>((indexInfo->srcCount * attribute.stride) + offset);
+ angle::MemoryBuffer expandedData;
+ ANGLE_CHECK_GL_ALLOC(context11, expandedData.resize(expandedDataSize));
+
+ // Clear the contents of the allocated buffer
+ ZeroMemory(expandedData.data(), expandedDataSize);
+
+ uint8_t *curr = expandedData.data();
+ const uint8_t *ptr = static_cast<const uint8_t *>(indexInfo->srcIndices);
+
+ // Ensure that we start in the correct place for the emulated data copy operation to
+ // maintain offset behaviors.
+ curr += offset;
+
+ ReadIndexValueFunction readIndexValue = ReadIndexValueFromIndices<GLushort>;
+
+ switch (indexInfo->srcIndexType)
+ {
+ case gl::DrawElementsType::UnsignedInt:
+ readIndexValue = ReadIndexValueFromIndices<GLuint>;
+ break;
+ case gl::DrawElementsType::UnsignedShort:
+ readIndexValue = ReadIndexValueFromIndices<GLushort>;
+ break;
+ case gl::DrawElementsType::UnsignedByte:
+ readIndexValue = ReadIndexValueFromIndices<GLubyte>;
+ break;
+ default:
+ UNREACHABLE();
+ return angle::Result::Stop;
+ }
+
+ // Iterate over the cached index data and copy entries indicated into the emulated buffer.
+ for (GLuint i = 0; i < indexInfo->srcCount; i++)
+ {
+ GLuint idx = readIndexValue(ptr, i);
+ memcpy(curr, mMemoryBuffer.data() + (attribute.stride * idx), attribute.stride);
+ curr += attribute.stride;
+ }
+
+ // Finally, initialize the emulated indexed native storage object with the newly copied data
+ // and free the temporary buffers used.
+ D3D11_BUFFER_DESC bufferDesc;
+ bufferDesc.ByteWidth = expandedDataSize;
+ bufferDesc.MiscFlags = 0;
+ bufferDesc.StructureByteStride = 0;
+ bufferDesc.Usage = D3D11_USAGE_DEFAULT;
+ bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
+ bufferDesc.CPUAccessFlags = 0;
+
+ D3D11_SUBRESOURCE_DATA subResourceData = {expandedData.data(), 0, 0};
+
+ ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), bufferDesc,
+ &subResourceData, &mBuffer));
+ mBuffer.setInternalName("Buffer11::EmulatedIndexedStorage");
+ }
+
+ *bufferOut = &mBuffer;
+ return angle::Result::Continue;
+}
+
+angle::Result Buffer11::EmulatedIndexedStorage::copyFromStorage(const gl::Context *context,
+ BufferStorage *source,
+ size_t sourceOffset,
+ size_t size,
+ size_t destOffset,
+ CopyResult *resultOut)
+{
+ ASSERT(source->isCPUAccessible(GL_MAP_READ_BIT));
+ uint8_t *sourceData = nullptr;
+ ANGLE_TRY(source->map(context, sourceOffset, size, GL_MAP_READ_BIT, &sourceData));
+ ASSERT(destOffset + size <= mMemoryBuffer.size());
+ memcpy(mMemoryBuffer.data() + destOffset, sourceData, size);
+ source->unmap();
+ *resultOut = CopyResult::RECREATED;
+ return angle::Result::Continue;
+}
+
+angle::Result Buffer11::EmulatedIndexedStorage::resize(const gl::Context *context,
+ size_t size,
+ bool preserveData)
+{
+ if (mMemoryBuffer.size() < size)
+ {
+ Context11 *context11 = GetImplAs<Context11>(context);
+ ANGLE_CHECK_GL_ALLOC(context11, mMemoryBuffer.resize(size));
+ mBufferSize = size;
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result Buffer11::EmulatedIndexedStorage::map(const gl::Context *context,
+ size_t offset,
+ size_t length,
+ GLbitfield access,
+ uint8_t **mapPointerOut)
+{
+ ASSERT(!mMemoryBuffer.empty() && offset + length <= mMemoryBuffer.size());
+ *mapPointerOut = mMemoryBuffer.data() + offset;
+ return angle::Result::Continue;
+}
+
+void Buffer11::EmulatedIndexedStorage::unmap()
+{
+ // No-op
+}
+
+// Buffer11::PackStorage implementation
+
+Buffer11::PackStorage::PackStorage(Renderer11 *renderer)
+ : BufferStorage(renderer, BUFFER_USAGE_PIXEL_PACK), mStagingTexture(), mDataModified(false)
+{}
+
+Buffer11::PackStorage::~PackStorage() {}
+
+angle::Result Buffer11::PackStorage::copyFromStorage(const gl::Context *context,
+ BufferStorage *source,
+ size_t sourceOffset,
+ size_t size,
+ size_t destOffset,
+ CopyResult *resultOut)
+{
+ ANGLE_TRY(flushQueuedPackCommand(context));
+
+ // For all use cases of pack buffers, we must copy through a readable buffer.
+ ASSERT(source->isCPUAccessible(GL_MAP_READ_BIT));
+ uint8_t *sourceData = nullptr;
+ ANGLE_TRY(source->map(context, sourceOffset, size, GL_MAP_READ_BIT, &sourceData));
+ ASSERT(destOffset + size <= mMemoryBuffer.size());
+ memcpy(mMemoryBuffer.data() + destOffset, sourceData, size);
+ source->unmap();
+ *resultOut = CopyResult::NOT_RECREATED;
+ return angle::Result::Continue;
+}
+
+angle::Result Buffer11::PackStorage::resize(const gl::Context *context,
+ size_t size,
+ bool preserveData)
+{
+ if (size != mBufferSize)
+ {
+ Context11 *context11 = GetImplAs<Context11>(context);
+ ANGLE_CHECK_GL_ALLOC(context11, mMemoryBuffer.resize(size));
+ mBufferSize = size;
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result Buffer11::PackStorage::map(const gl::Context *context,
+ size_t offset,
+ size_t length,
+ GLbitfield access,
+ uint8_t **mapPointerOut)
+{
+ ASSERT(offset + length <= getSize());
+ // TODO: fast path
+ // We might be able to optimize out one or more memcpy calls by detecting when
+ // and if D3D packs the staging texture memory identically to how we would fill
+ // the pack buffer according to the current pack state.
+
+ ANGLE_TRY(flushQueuedPackCommand(context));
+
+ mDataModified = (mDataModified || (access & GL_MAP_WRITE_BIT) != 0);
+
+ *mapPointerOut = mMemoryBuffer.data() + offset;
+ return angle::Result::Continue;
+}
+
+void Buffer11::PackStorage::unmap()
+{
+ // No-op
+}
+
+angle::Result Buffer11::PackStorage::packPixels(const gl::Context *context,
+ const gl::FramebufferAttachment &readAttachment,
+ const PackPixelsParams &params)
+{
+ ANGLE_TRY(flushQueuedPackCommand(context));
+
+ RenderTarget11 *renderTarget = nullptr;
+ ANGLE_TRY(readAttachment.getRenderTarget(context, 0, &renderTarget));
+
+ const TextureHelper11 &srcTexture = renderTarget->getTexture();
+ ASSERT(srcTexture.valid());
+ unsigned int srcSubresource = renderTarget->getSubresourceIndex();
+
+ mQueuedPackCommand.reset(new PackPixelsParams(params));
+
+ gl::Extents srcTextureSize(params.area.width, params.area.height, 1);
+ if (!mStagingTexture.get() || mStagingTexture.getFormat() != srcTexture.getFormat() ||
+ mStagingTexture.getExtents() != srcTextureSize)
+ {
+ ANGLE_TRY(mRenderer->createStagingTexture(context, srcTexture.getTextureType(),
+ srcTexture.getFormatSet(), srcTextureSize,
+ StagingAccess::READ, &mStagingTexture));
+ }
+
+ // ReadPixels from multisampled FBOs isn't supported in current GL
+ ASSERT(srcTexture.getSampleCount() <= 1);
+
+ ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
+ D3D11_BOX srcBox;
+ srcBox.left = params.area.x;
+ srcBox.right = params.area.x + params.area.width;
+ srcBox.top = params.area.y;
+ srcBox.bottom = params.area.y + params.area.height;
+
+ // Select the correct layer from a 3D attachment
+ srcBox.front = 0;
+ if (mStagingTexture.is3D())
+ {
+ srcBox.front = static_cast<UINT>(readAttachment.layer());
+ }
+ srcBox.back = srcBox.front + 1;
+
+ // Asynchronous copy
+ immediateContext->CopySubresourceRegion(mStagingTexture.get(), 0, 0, 0, 0, srcTexture.get(),
+ srcSubresource, &srcBox);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Buffer11::PackStorage::flushQueuedPackCommand(const gl::Context *context)
+{
+ ASSERT(mMemoryBuffer.size() > 0);
+
+ if (mQueuedPackCommand)
+ {
+ ANGLE_TRY(mRenderer->packPixels(context, mStagingTexture, *mQueuedPackCommand,
+ mMemoryBuffer.data()));
+ mQueuedPackCommand.reset(nullptr);
+ }
+
+ return angle::Result::Continue;
+}
+
+// Buffer11::SystemMemoryStorage implementation
+
+Buffer11::SystemMemoryStorage::SystemMemoryStorage(Renderer11 *renderer)
+ : Buffer11::BufferStorage(renderer, BUFFER_USAGE_SYSTEM_MEMORY)
+{}
+
+angle::Result Buffer11::SystemMemoryStorage::copyFromStorage(const gl::Context *context,
+ BufferStorage *source,
+ size_t sourceOffset,
+ size_t size,
+ size_t destOffset,
+ CopyResult *resultOut)
+{
+ ASSERT(source->isCPUAccessible(GL_MAP_READ_BIT));
+ uint8_t *sourceData = nullptr;
+ ANGLE_TRY(source->map(context, sourceOffset, size, GL_MAP_READ_BIT, &sourceData));
+ ASSERT(destOffset + size <= mSystemCopy.size());
+ memcpy(mSystemCopy.data() + destOffset, sourceData, size);
+ source->unmap();
+ *resultOut = CopyResult::RECREATED;
+ return angle::Result::Continue;
+}
+
+angle::Result Buffer11::SystemMemoryStorage::resize(const gl::Context *context,
+ size_t size,
+ bool preserveData)
+{
+ if (mSystemCopy.size() < size)
+ {
+ Context11 *context11 = GetImplAs<Context11>(context);
+ ANGLE_CHECK_GL_ALLOC(context11, mSystemCopy.resize(size));
+ mBufferSize = size;
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result Buffer11::SystemMemoryStorage::map(const gl::Context *context,
+ size_t offset,
+ size_t length,
+ GLbitfield access,
+ uint8_t **mapPointerOut)
+{
+ ASSERT(!mSystemCopy.empty() && offset + length <= mSystemCopy.size());
+ *mapPointerOut = mSystemCopy.data() + offset;
+ return angle::Result::Continue;
+}
+
+void Buffer11::SystemMemoryStorage::unmap()
+{
+ // No-op
+}
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Buffer11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Buffer11.h
new file mode 100644
index 0000000000..b24bd1a48b
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Buffer11.h
@@ -0,0 +1,234 @@
+//
+// 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.
+//
+
+// Buffer11.h: Defines the rx::Buffer11 class which implements rx::BufferImpl via rx::BufferD3D.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_BUFFER11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_BUFFER11_H_
+
+#include <array>
+#include <map>
+
+#include "libANGLE/angletypes.h"
+#include "libANGLE/renderer/d3d/BufferD3D.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+
+namespace gl
+{
+class FramebufferAttachment;
+}
+
+namespace rx
+{
+struct PackPixelsParams;
+class Renderer11;
+struct SourceIndexData;
+struct TranslatedAttribute;
+
+// The order of this enum governs priority of 'getLatestBufferStorage'.
+enum BufferUsage
+{
+ BUFFER_USAGE_SYSTEM_MEMORY,
+ BUFFER_USAGE_STAGING,
+ BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK,
+ BUFFER_USAGE_INDEX,
+ BUFFER_USAGE_INDIRECT,
+ BUFFER_USAGE_PIXEL_UNPACK,
+ BUFFER_USAGE_PIXEL_PACK,
+ BUFFER_USAGE_UNIFORM,
+ BUFFER_USAGE_STRUCTURED,
+ BUFFER_USAGE_EMULATED_INDEXED_VERTEX,
+ BUFFER_USAGE_RAW_UAV,
+ BUFFER_USAGE_TYPED_UAV,
+
+ BUFFER_USAGE_COUNT,
+};
+
+typedef size_t DataRevision;
+
+class Buffer11 : public BufferD3D
+{
+ public:
+ Buffer11(const gl::BufferState &state, Renderer11 *renderer);
+ ~Buffer11() override;
+
+ angle::Result getBuffer(const gl::Context *context,
+ BufferUsage usage,
+ ID3D11Buffer **bufferOut);
+ angle::Result getEmulatedIndexedBuffer(const gl::Context *context,
+ SourceIndexData *indexInfo,
+ const TranslatedAttribute &attribute,
+ GLint startVertex,
+ ID3D11Buffer **bufferOut);
+ angle::Result getConstantBufferRange(const gl::Context *context,
+ GLintptr offset,
+ GLsizeiptr size,
+ const d3d11::Buffer **bufferOut,
+ UINT *firstConstantOut,
+ UINT *numConstantsOut);
+ angle::Result getStructuredBufferRangeSRV(const gl::Context *context,
+ unsigned int offset,
+ unsigned int size,
+ unsigned int structureByteStride,
+ const d3d11::ShaderResourceView **srvOut);
+ angle::Result getSRV(const gl::Context *context,
+ DXGI_FORMAT srvFormat,
+ const d3d11::ShaderResourceView **srvOut);
+ angle::Result getRawUAVRange(const gl::Context *context,
+ GLintptr offset,
+ GLsizeiptr size,
+ d3d11::UnorderedAccessView **uavOut);
+
+ angle::Result getTypedUAVRange(const gl::Context *context,
+ GLintptr offset,
+ GLsizeiptr size,
+ DXGI_FORMAT format,
+ d3d11::UnorderedAccessView **uavOut);
+
+ angle::Result markRawBufferUsage(const gl::Context *context);
+ angle::Result markTypedBufferUsage(const gl::Context *context);
+ bool isMapped() const { return mMappedStorage != nullptr; }
+ angle::Result packPixels(const gl::Context *context,
+ const gl::FramebufferAttachment &readAttachment,
+ const PackPixelsParams &params);
+ size_t getTotalCPUBufferMemoryBytes() const;
+
+ // BufferD3D implementation
+ size_t getSize() const override;
+ bool supportsDirectBinding() const override;
+ angle::Result getData(const gl::Context *context, const uint8_t **outData) override;
+ void initializeStaticData(const gl::Context *context) override;
+ void invalidateStaticData(const gl::Context *context) override;
+
+ // BufferImpl implementation
+ angle::Result setData(const gl::Context *context,
+ gl::BufferBinding target,
+ const void *data,
+ size_t size,
+ gl::BufferUsage usage) override;
+ angle::Result setSubData(const gl::Context *context,
+ gl::BufferBinding target,
+ const void *data,
+ size_t size,
+ size_t offset) override;
+ angle::Result copySubData(const gl::Context *context,
+ BufferImpl *source,
+ GLintptr sourceOffset,
+ GLintptr destOffset,
+ GLsizeiptr size) override;
+ angle::Result map(const gl::Context *context, GLenum access, void **mapPtr) override;
+ angle::Result mapRange(const gl::Context *context,
+ size_t offset,
+ size_t length,
+ GLbitfield access,
+ void **mapPtr) override;
+ angle::Result unmap(const gl::Context *context, GLboolean *result) override;
+ angle::Result markTransformFeedbackUsage(const gl::Context *context) override;
+
+ private:
+ class BufferStorage;
+ class EmulatedIndexedStorage;
+ class NativeStorage;
+ class PackStorage;
+ class SystemMemoryStorage;
+ class StructuredBufferStorage;
+
+ struct BufferCacheEntry
+ {
+ BufferCacheEntry() : storage(nullptr), lruCount(0) {}
+
+ BufferStorage *storage;
+ unsigned int lruCount;
+ };
+
+ struct StructuredBufferKey
+ {
+ StructuredBufferKey(unsigned int offsetIn, unsigned int structureByteStrideIn)
+ : offset(offsetIn), structureByteStride(structureByteStrideIn)
+ {}
+ bool operator<(const StructuredBufferKey &rhs) const
+ {
+ return std::tie(offset, structureByteStride) <
+ std::tie(rhs.offset, rhs.structureByteStride);
+ }
+ unsigned int offset;
+ unsigned int structureByteStride;
+ };
+
+ void markBufferUsage(BufferUsage usage);
+ angle::Result markBufferUsage(const gl::Context *context, BufferUsage usage);
+ angle::Result garbageCollection(const gl::Context *context, BufferUsage currentUsage);
+
+ angle::Result updateBufferStorage(const gl::Context *context,
+ BufferStorage *storage,
+ size_t sourceOffset,
+ size_t storageSize);
+
+ angle::Result getNativeStorageForUAV(const gl::Context *context,
+ Buffer11::NativeStorage **storageOut);
+
+ template <typename StorageOutT>
+ angle::Result getBufferStorage(const gl::Context *context,
+ BufferUsage usage,
+ StorageOutT **storageOut);
+
+ template <typename StorageOutT>
+ angle::Result getStagingStorage(const gl::Context *context, StorageOutT **storageOut);
+
+ angle::Result getLatestBufferStorage(const gl::Context *context,
+ BufferStorage **storageOut) const;
+
+ angle::Result getConstantBufferRangeStorage(const gl::Context *context,
+ GLintptr offset,
+ GLsizeiptr size,
+ NativeStorage **storageOut);
+
+ BufferStorage *allocateStorage(BufferUsage usage);
+ void updateDeallocThreshold(BufferUsage usage);
+
+ // Free the storage if we decide it isn't being used very often.
+ angle::Result checkForDeallocation(const gl::Context *context, BufferUsage usage);
+
+ // For some cases of uniform buffer storage, we can't deallocate system memory storage.
+ bool canDeallocateSystemMemory() const;
+
+ // Updates data revisions and latest storage.
+ void onCopyStorage(BufferStorage *dest, BufferStorage *source);
+ void onStorageUpdate(BufferStorage *updatedStorage);
+
+ Renderer11 *mRenderer;
+ size_t mSize;
+
+ BufferStorage *mMappedStorage;
+
+ // Buffer storages are sorted by usage. It's important that the latest buffer storage picks
+ // the lowest usage in the case where two storages are tied on data revision - this ensures
+ // we never do anything dangerous like map a uniform buffer over a staging or system memory
+ // copy.
+ std::array<BufferStorage *, BUFFER_USAGE_COUNT> mBufferStorages;
+ BufferStorage *mLatestBufferStorage;
+
+ // 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.
+ // Constant buffers are indexed by there start offset.
+ typedef std::map<GLintptr /*offset*/, BufferCacheEntry> BufferCache;
+ BufferCache mConstantBufferRangeStoragesCache;
+ size_t mConstantBufferStorageAdditionalSize;
+ unsigned int mMaxConstantBufferLruCount;
+
+ typedef std::map<StructuredBufferKey, BufferCacheEntry> StructuredBufferCache;
+ StructuredBufferCache mStructuredBufferRangeStoragesCache;
+ size_t mStructuredBufferStorageAdditionalSize;
+ unsigned int mMaxStructuredBufferLruCount;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D11_BUFFER11_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp
new file mode 100644
index 0000000000..d85b18b840
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp
@@ -0,0 +1,813 @@
+
+// Copyright 2013 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.
+//
+
+// Clear11.cpp: Framebuffer clear utility class.
+
+#include "libANGLE/renderer/d3d/d3d11/Clear11.h"
+
+#include <algorithm>
+
+#include "libANGLE/Context.h"
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/d3d/FramebufferD3D.h"
+#include "libANGLE/renderer/d3d/d3d11/Context11.h"
+#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+#include "libANGLE/trace.h"
+
+// Precompiled shaders
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11_fl9vs.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11multiviewgs.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11multiviewvs.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11vs.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/cleardepth11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11_fl9ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps1.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps2.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps3.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps4.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps5.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps6.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps7.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps8.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps1.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps2.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps3.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps4.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps5.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps6.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps7.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps8.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps1.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps2.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps3.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps4.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps5.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps6.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps7.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps8.h"
+
+namespace rx
+{
+
+namespace
+{
+constexpr uint32_t g_ConstantBufferSize = sizeof(RtvDsvClearInfo<float>);
+constexpr uint32_t g_VertexSize = sizeof(d3d11::PositionVertex);
+
+// Updates color, depth and alpha components of cached CB if necessary.
+// Returns true if any constants are updated, false otherwise.
+template <typename T>
+bool UpdateDataCache(RtvDsvClearInfo<T> *dataCache,
+ const gl::Color<T> &color,
+ const float *zValue,
+ const uint32_t numRtvs,
+ const uint8_t writeMask)
+{
+ bool cacheDirty = false;
+
+ if (numRtvs > 0)
+ {
+ const bool writeRGB = (writeMask & ~D3D11_COLOR_WRITE_ENABLE_ALPHA) != 0;
+ if (writeRGB && memcmp(&dataCache->r, &color.red, sizeof(T) * 3) != 0)
+ {
+ dataCache->r = color.red;
+ dataCache->g = color.green;
+ dataCache->b = color.blue;
+ cacheDirty = true;
+ }
+
+ const bool writeAlpha = (writeMask & D3D11_COLOR_WRITE_ENABLE_ALPHA) != 0;
+ if (writeAlpha && (dataCache->a != color.alpha))
+ {
+ dataCache->a = color.alpha;
+ cacheDirty = true;
+ }
+ }
+
+ if (zValue)
+ {
+ const float clampedZValue = gl::clamp01(*zValue);
+
+ if (clampedZValue != dataCache->z)
+ {
+ dataCache->z = clampedZValue;
+ cacheDirty = true;
+ }
+ }
+
+ return cacheDirty;
+}
+
+} // anonymous namespace
+
+#define CLEARPS(Index) \
+ d3d11::LazyShader<ID3D11PixelShader>(g_PS_Clear##Index, ArraySize(g_PS_Clear##Index), \
+ "Clear11 PS " ANGLE_STRINGIFY(Index))
+
+Clear11::ShaderManager::ShaderManager()
+ : mIl9(),
+ mVs9(g_VS_Clear_FL9, ArraySize(g_VS_Clear_FL9), "Clear11 VS FL9"),
+ mPsFloat9(g_PS_ClearFloat_FL9, ArraySize(g_PS_ClearFloat_FL9), "Clear11 PS FloatFL9"),
+ mVs(g_VS_Clear, ArraySize(g_VS_Clear), "Clear11 VS"),
+ mVsMultiview(g_VS_Multiview_Clear, ArraySize(g_VS_Multiview_Clear), "Clear11 VS Multiview"),
+ mGsMultiview(g_GS_Multiview_Clear, ArraySize(g_GS_Multiview_Clear), "Clear11 GS Multiview"),
+ mPsDepth(g_PS_ClearDepth, ArraySize(g_PS_ClearDepth), "Clear11 PS Depth"),
+ mPsFloat{{CLEARPS(Float1), CLEARPS(Float2), CLEARPS(Float3), CLEARPS(Float4), CLEARPS(Float5),
+ CLEARPS(Float6), CLEARPS(Float7), CLEARPS(Float8)}},
+ mPsUInt{{CLEARPS(Uint1), CLEARPS(Uint2), CLEARPS(Uint3), CLEARPS(Uint4), CLEARPS(Uint5),
+ CLEARPS(Uint6), CLEARPS(Uint7), CLEARPS(Uint8)}},
+ mPsSInt{{CLEARPS(Sint1), CLEARPS(Sint2), CLEARPS(Sint3), CLEARPS(Sint4), CLEARPS(Sint5),
+ CLEARPS(Sint6), CLEARPS(Sint7), CLEARPS(Sint8)}}
+{}
+
+#undef CLEARPS
+
+Clear11::ShaderManager::~ShaderManager() {}
+
+angle::Result Clear11::ShaderManager::getShadersAndLayout(const gl::Context *context,
+ Renderer11 *renderer,
+ const INT clearType,
+ const uint32_t numRTs,
+ const bool hasLayeredLayout,
+ const d3d11::InputLayout **il,
+ const d3d11::VertexShader **vs,
+ const d3d11::GeometryShader **gs,
+ const d3d11::PixelShader **ps)
+{
+ Context11 *context11 = GetImplAs<Context11>(context);
+
+ if (renderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3)
+ {
+ ASSERT(clearType == GL_FLOAT);
+
+ ANGLE_TRY(mVs9.resolve(context11, renderer));
+ ANGLE_TRY(mPsFloat9.resolve(context11, renderer));
+
+ if (!mIl9.valid())
+ {
+ const D3D11_INPUT_ELEMENT_DESC ilDesc[] = {
+ {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}};
+
+ InputElementArray ilDescArray(ilDesc);
+ ShaderData vertexShader(g_VS_Clear_FL9);
+
+ ANGLE_TRY(renderer->allocateResource(context11, ilDescArray, &vertexShader, &mIl9));
+ }
+
+ *vs = &mVs9.getObj();
+ *gs = nullptr;
+ *il = &mIl9;
+ *ps = &mPsFloat9.getObj();
+ return angle::Result::Continue;
+ }
+
+ if (!hasLayeredLayout)
+ {
+ ANGLE_TRY(mVs.resolve(context11, renderer));
+ *vs = &mVs.getObj();
+ *gs = nullptr;
+ }
+ else
+ {
+ // For layered framebuffers we have to use the multi-view versions of the VS and GS.
+ ANGLE_TRY(mVsMultiview.resolve(context11, renderer));
+ ANGLE_TRY(mGsMultiview.resolve(context11, renderer));
+ *vs = &mVsMultiview.getObj();
+ *gs = &mGsMultiview.getObj();
+ }
+
+ *il = nullptr;
+
+ if (numRTs == 0)
+ {
+ ANGLE_TRY(mPsDepth.resolve(context11, renderer));
+ *ps = &mPsDepth.getObj();
+ return angle::Result::Continue;
+ }
+
+ switch (clearType)
+ {
+ case GL_FLOAT:
+ ANGLE_TRY(mPsFloat[numRTs - 1].resolve(context11, renderer));
+ *ps = &mPsFloat[numRTs - 1].getObj();
+ break;
+ case GL_UNSIGNED_INT:
+ ANGLE_TRY(mPsUInt[numRTs - 1].resolve(context11, renderer));
+ *ps = &mPsUInt[numRTs - 1].getObj();
+ break;
+ case GL_INT:
+ ANGLE_TRY(mPsSInt[numRTs - 1].resolve(context11, renderer));
+ *ps = &mPsSInt[numRTs - 1].getObj();
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ return angle::Result::Continue;
+}
+
+Clear11::Clear11(Renderer11 *renderer)
+ : mRenderer(renderer),
+ mResourcesInitialized(false),
+ mScissorEnabledRasterizerState(),
+ mScissorDisabledRasterizerState(),
+ mShaderManager(),
+ mConstantBuffer(),
+ mVertexBuffer(),
+ mShaderData({})
+{}
+
+Clear11::~Clear11() {}
+
+angle::Result Clear11::ensureResourcesInitialized(const gl::Context *context)
+{
+ if (mResourcesInitialized)
+ {
+ return angle::Result::Continue;
+ }
+
+ ANGLE_TRACE_EVENT0("gpu.angle", "Clear11::ensureResourcesInitialized");
+
+ static_assert((sizeof(RtvDsvClearInfo<float>) == sizeof(RtvDsvClearInfo<int>)),
+ "Size of rx::RtvDsvClearInfo<float> is not equal to rx::RtvDsvClearInfo<int>");
+
+ static_assert(
+ (sizeof(RtvDsvClearInfo<float>) == sizeof(RtvDsvClearInfo<uint32_t>)),
+ "Size of rx::RtvDsvClearInfo<float> is not equal to rx::RtvDsvClearInfo<uint32_t>");
+
+ static_assert((sizeof(RtvDsvClearInfo<float>) % 16 == 0),
+ "The size of RtvDsvClearInfo<float> should be a multiple of 16bytes.");
+
+ // Create Rasterizer States
+ D3D11_RASTERIZER_DESC rsDesc;
+ rsDesc.FillMode = D3D11_FILL_SOLID;
+ rsDesc.CullMode = D3D11_CULL_NONE;
+ rsDesc.FrontCounterClockwise = FALSE;
+ rsDesc.DepthBias = 0;
+ rsDesc.DepthBiasClamp = 0.0f;
+ rsDesc.SlopeScaledDepthBias = 0.0f;
+ rsDesc.DepthClipEnable = TRUE;
+ rsDesc.ScissorEnable = FALSE;
+ rsDesc.MultisampleEnable = FALSE;
+ rsDesc.AntialiasedLineEnable = FALSE;
+
+ Context11 *context11 = GetImplAs<Context11>(context);
+
+ ANGLE_TRY(mRenderer->allocateResource(context11, rsDesc, &mScissorDisabledRasterizerState));
+ mScissorDisabledRasterizerState.setInternalName("Clear11RasterizerStateWithScissorDisabled");
+
+ rsDesc.ScissorEnable = TRUE;
+ ANGLE_TRY(mRenderer->allocateResource(context11, rsDesc, &mScissorEnabledRasterizerState));
+ mScissorEnabledRasterizerState.setInternalName("Clear11RasterizerStateWithScissorEnabled");
+
+ // Initialize Depthstencil state with defaults
+ mDepthStencilStateKey.depthTest = false;
+ mDepthStencilStateKey.depthMask = false;
+ mDepthStencilStateKey.depthFunc = GL_ALWAYS;
+ mDepthStencilStateKey.stencilWritemask = static_cast<GLuint>(-1);
+ mDepthStencilStateKey.stencilBackWritemask = static_cast<GLuint>(-1);
+ mDepthStencilStateKey.stencilBackMask = 0;
+ mDepthStencilStateKey.stencilTest = false;
+ mDepthStencilStateKey.stencilMask = 0;
+ mDepthStencilStateKey.stencilFail = GL_REPLACE;
+ mDepthStencilStateKey.stencilPassDepthFail = GL_REPLACE;
+ mDepthStencilStateKey.stencilPassDepthPass = GL_REPLACE;
+ mDepthStencilStateKey.stencilFunc = GL_ALWAYS;
+ mDepthStencilStateKey.stencilBackFail = GL_REPLACE;
+ mDepthStencilStateKey.stencilBackPassDepthFail = GL_REPLACE;
+ mDepthStencilStateKey.stencilBackPassDepthPass = GL_REPLACE;
+ mDepthStencilStateKey.stencilBackFunc = GL_ALWAYS;
+
+ // Initialize BlendStateKey with defaults
+ mBlendStateKey.blendStateExt = gl::BlendStateExt(mRenderer->getNativeCaps().maxDrawBuffers);
+
+ mResourcesInitialized = true;
+ return angle::Result::Continue;
+}
+
+bool Clear11::useVertexBuffer() const
+{
+ return (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3);
+}
+
+angle::Result Clear11::ensureConstantBufferCreated(const gl::Context *context)
+{
+ if (mConstantBuffer.valid())
+ {
+ return angle::Result::Continue;
+ }
+
+ // Create constant buffer for color & depth data
+
+ D3D11_BUFFER_DESC bufferDesc;
+ bufferDesc.ByteWidth = g_ConstantBufferSize;
+ bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
+ bufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
+ bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+ bufferDesc.MiscFlags = 0;
+ bufferDesc.StructureByteStride = 0;
+
+ D3D11_SUBRESOURCE_DATA initialData;
+ initialData.pSysMem = &mShaderData;
+ initialData.SysMemPitch = g_ConstantBufferSize;
+ initialData.SysMemSlicePitch = g_ConstantBufferSize;
+
+ ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), bufferDesc, &initialData,
+ &mConstantBuffer));
+ mConstantBuffer.setInternalName("Clear11ConstantBuffer");
+ return angle::Result::Continue;
+}
+
+angle::Result Clear11::ensureVertexBufferCreated(const gl::Context *context)
+{
+ ASSERT(useVertexBuffer());
+
+ if (mVertexBuffer.valid())
+ {
+ return angle::Result::Continue;
+ }
+
+ // Create vertex buffer with vertices for a quad covering the entire surface
+
+ static_assert((sizeof(d3d11::PositionVertex) % 16) == 0,
+ "d3d11::PositionVertex should be a multiple of 16 bytes");
+ const d3d11::PositionVertex vbData[6] = {{-1.0f, 1.0f, 0.0f, 1.0f}, {1.0f, -1.0f, 0.0f, 1.0f},
+ {-1.0f, -1.0f, 0.0f, 1.0f}, {-1.0f, 1.0f, 0.0f, 1.0f},
+ {1.0f, 1.0f, 0.0f, 1.0f}, {1.0f, -1.0f, 0.0f, 1.0f}};
+
+ const UINT vbSize = sizeof(vbData);
+
+ D3D11_BUFFER_DESC bufferDesc;
+ bufferDesc.ByteWidth = vbSize;
+ bufferDesc.Usage = D3D11_USAGE_IMMUTABLE;
+ bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
+ bufferDesc.CPUAccessFlags = 0;
+ bufferDesc.MiscFlags = 0;
+ bufferDesc.StructureByteStride = 0;
+
+ D3D11_SUBRESOURCE_DATA initialData;
+ initialData.pSysMem = vbData;
+ initialData.SysMemPitch = vbSize;
+ initialData.SysMemSlicePitch = initialData.SysMemPitch;
+
+ ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), bufferDesc, &initialData,
+ &mVertexBuffer));
+ mVertexBuffer.setInternalName("Clear11VertexBuffer");
+ return angle::Result::Continue;
+}
+
+angle::Result Clear11::clearFramebuffer(const gl::Context *context,
+ const ClearParameters &clearParams,
+ const gl::FramebufferState &fboData)
+{
+ ANGLE_TRY(ensureResourcesInitialized(context));
+
+ // Iterate over the color buffers which require clearing and determine if they can be
+ // cleared with ID3D11DeviceContext::ClearRenderTargetView or ID3D11DeviceContext1::ClearView.
+ // This requires:
+ // 1) The render target is being cleared to a float value (will be cast to integer when clearing
+ // integer render targets as expected but does not work the other way around)
+ // 2) The format of the render target has no color channels that are currently masked out.
+ // Clear the easy-to-clear buffers on the spot and accumulate the ones that require special
+ // work.
+ //
+ // If these conditions are met, and:
+ // - No scissored clear is needed, then clear using ID3D11DeviceContext::ClearRenderTargetView.
+ // - A scissored clear is needed then clear using ID3D11DeviceContext1::ClearView if available.
+ // Otherwise perform a shader based clear.
+ //
+ // Also determine if the DSV can be cleared withID3D11DeviceContext::ClearDepthStencilView by
+ // checking if the stencil write mask covers the entire stencil.
+ //
+ // To clear the remaining buffers, a shader based clear is performed:
+ // - The appropriate ShaderManagers (VS & PS) for the clearType is set
+ // - A CB containing the clear color and Z values is bound
+ // - An IL and VB are bound (for FL93 and below)
+ // - ScissorRect/Raststate/Viewport set as required
+ // - Blendstate set containing appropriate colorMasks
+ // - DepthStencilState set with appropriate parameters for a z or stencil clear if required
+ // - Color and/or Z buffers to be cleared are bound
+ // - Primitive covering entire clear area is drawn
+
+ gl::Extents framebufferSize;
+
+ const auto *depthStencilAttachment = fboData.getDepthOrStencilAttachment();
+ if (depthStencilAttachment != nullptr)
+ {
+ framebufferSize = depthStencilAttachment->getSize();
+ }
+ else
+ {
+ const gl::FramebufferAttachment *colorAttachment = fboData.getFirstColorAttachment();
+ ASSERT(colorAttachment);
+ framebufferSize = colorAttachment->getSize();
+ }
+
+ bool needScissoredClear = false;
+ D3D11_RECT scissorRect;
+ if (clearParams.scissorEnabled)
+ {
+ if (clearParams.scissor.x >= framebufferSize.width ||
+ clearParams.scissor.y >= framebufferSize.height || clearParams.scissor.width == 0 ||
+ clearParams.scissor.height == 0)
+ {
+ // The check assumes that the viewport offsets are not negative as according to the
+ // OVR_multiview2 spec.
+ // Scissor rect is outside the renderbuffer or is an empty rect.
+ return angle::Result::Continue;
+ }
+
+ if (clearParams.scissor.x + clearParams.scissor.width <= 0 ||
+ clearParams.scissor.y + clearParams.scissor.height <= 0)
+ {
+ // Scissor rect is outside the renderbuffer.
+ return angle::Result::Continue;
+ }
+ needScissoredClear =
+ clearParams.scissor.x > 0 || clearParams.scissor.y > 0 ||
+ clearParams.scissor.x + clearParams.scissor.width < framebufferSize.width ||
+ clearParams.scissor.y + clearParams.scissor.height < framebufferSize.height;
+
+ if (needScissoredClear)
+ {
+ // Apply viewport offsets to compute the final scissor rectangles.
+ // Even in multiview all layers share the same viewport and scissor.
+ scissorRect.left = clearParams.scissor.x;
+ scissorRect.right = scissorRect.left + clearParams.scissor.width;
+ scissorRect.top = clearParams.scissor.y;
+ scissorRect.bottom = scissorRect.top + clearParams.scissor.height;
+ }
+ }
+
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+ ID3D11DeviceContext1 *deviceContext1 = mRenderer->getDeviceContext1IfSupported();
+
+ std::array<ID3D11RenderTargetView *, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT> rtvs;
+ std::array<uint8_t, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT> rtvMasks = {};
+
+ uint32_t numRtvs = 0;
+ uint8_t commonColorMask = 0;
+
+ const auto &colorAttachments = fboData.getColorAttachments();
+ for (auto colorAttachmentIndex : fboData.getEnabledDrawBuffers())
+ {
+ const uint8_t colorMask = gl::BlendStateExt::ColorMaskStorage::GetValueIndexed(
+ colorAttachmentIndex, clearParams.colorMask);
+
+ commonColorMask |= colorMask;
+
+ const gl::FramebufferAttachment &attachment = colorAttachments[colorAttachmentIndex];
+
+ if (!clearParams.clearColor[colorAttachmentIndex])
+ {
+ continue;
+ }
+
+ RenderTarget11 *renderTarget = nullptr;
+ ANGLE_TRY(attachment.getRenderTarget(context, attachment.getRenderToTextureSamples(),
+ &renderTarget));
+
+ const gl::InternalFormat &formatInfo = *attachment.getFormat().info;
+
+ if (clearParams.colorType == GL_FLOAT &&
+ !(formatInfo.componentType == GL_FLOAT ||
+ formatInfo.componentType == GL_UNSIGNED_NORMALIZED ||
+ formatInfo.componentType == GL_SIGNED_NORMALIZED))
+ {
+ WARN() << "It is undefined behaviour to clear a render buffer which is not "
+ "normalized fixed point or floating-point to floating point values (color "
+ "attachment "
+ << colorAttachmentIndex << " has internal format " << attachment.getFormat()
+ << ").";
+ }
+
+ bool r, g, b, a;
+ gl::BlendStateExt::UnpackColorMask(colorMask, &r, &g, &b, &a);
+ if ((formatInfo.redBits == 0 || !r) && (formatInfo.greenBits == 0 || !g) &&
+ (formatInfo.blueBits == 0 || !b) && (formatInfo.alphaBits == 0 || !a))
+ {
+ // Every channel either does not exist in the render target or is masked out
+ continue;
+ }
+
+ const auto &framebufferRTV = renderTarget->getRenderTargetView();
+ ASSERT(framebufferRTV.valid());
+
+ bool canClearView = mRenderer->getRenderer11DeviceCaps().supportsClearView;
+ if (canClearView &&
+ mRenderer->getFeatures().emulateClearViewAfterDualSourceBlending.enabled)
+ {
+ // Check the current state to see if we were using dual source blending
+ const auto isDualSource = [](const auto blend) {
+ switch (blend)
+ {
+ case D3D11_BLEND_SRC1_COLOR:
+ case D3D11_BLEND_INV_SRC1_COLOR:
+ case D3D11_BLEND_SRC1_ALPHA:
+ case D3D11_BLEND_INV_SRC1_ALPHA:
+ return true;
+ default:
+ return false;
+ }
+ };
+ FLOAT blendFactor[4];
+ UINT sampleMask;
+ ID3D11BlendState *blendState;
+ deviceContext->OMGetBlendState(&blendState, blendFactor, &sampleMask);
+ if (blendState)
+ {
+ D3D11_BLEND_DESC blendDesc;
+ blendState->GetDesc(&blendDesc);
+ // You can only use dual source blending on slot 0 so only check there
+ if (isDualSource(blendDesc.RenderTarget[0].SrcBlend) ||
+ isDualSource(blendDesc.RenderTarget[0].DestBlend) ||
+ isDualSource(blendDesc.RenderTarget[0].SrcBlendAlpha) ||
+ isDualSource(blendDesc.RenderTarget[0].DestBlendAlpha))
+ {
+ canClearView = false;
+ }
+ }
+ }
+
+ if (needScissoredClear && mRenderer->getFeatures().scissoredClearArtifacts.enabled)
+ {
+ canClearView = false;
+ }
+
+ if ((!canClearView && needScissoredClear) || clearParams.colorType != GL_FLOAT ||
+ (formatInfo.redBits > 0 && !r) || (formatInfo.greenBits > 0 && !g) ||
+ (formatInfo.blueBits > 0 && !b) || (formatInfo.alphaBits > 0 && !a))
+ {
+ rtvs[numRtvs] = framebufferRTV.get();
+ rtvMasks[numRtvs] = gl_d3d11::GetColorMask(formatInfo) & colorMask;
+ numRtvs++;
+ }
+ else
+ {
+ // ID3D11DeviceContext::ClearRenderTargetView or ID3D11DeviceContext1::ClearView is
+ // possible
+
+ 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 && nativeFormat.redBits > 0) ? 0.0f
+ : clearParams.colorF.red),
+ ((formatInfo.greenBits == 0 && nativeFormat.greenBits > 0)
+ ? 0.0f
+ : clearParams.colorF.green),
+ ((formatInfo.blueBits == 0 && nativeFormat.blueBits > 0) ? 0.0f
+ : clearParams.colorF.blue),
+ ((formatInfo.alphaBits == 0 && nativeFormat.alphaBits > 0)
+ ? 1.0f
+ : clearParams.colorF.alpha),
+ };
+
+ 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. We should handle the rounding for them instead.
+ clearValues[3] = (clearParams.colorF.alpha >= 0.5f) ? 1.0f : 0.0f;
+ }
+
+ if (needScissoredClear)
+ {
+ // We shouldn't reach here if deviceContext1 is unavailable.
+ ASSERT(deviceContext1);
+ deviceContext1->ClearView(framebufferRTV.get(), clearValues, &scissorRect, 1);
+ if (mRenderer->getFeatures().callClearTwice.enabled)
+ {
+ deviceContext1->ClearView(framebufferRTV.get(), clearValues, &scissorRect, 1);
+ }
+ }
+ else
+ {
+ deviceContext->ClearRenderTargetView(framebufferRTV.get(), clearValues);
+ if (mRenderer->getFeatures().callClearTwice.enabled)
+ {
+ deviceContext->ClearRenderTargetView(framebufferRTV.get(), clearValues);
+ }
+ }
+ }
+ }
+
+ ID3D11DepthStencilView *dsv = nullptr;
+
+ if (clearParams.clearDepth || clearParams.clearStencil)
+ {
+ RenderTarget11 *depthStencilRenderTarget = nullptr;
+
+ ASSERT(depthStencilAttachment != nullptr);
+ ANGLE_TRY(depthStencilAttachment->getRenderTarget(
+ context, depthStencilAttachment->getRenderToTextureSamples(),
+ &depthStencilRenderTarget));
+
+ dsv = depthStencilRenderTarget->getDepthStencilView().get();
+ ASSERT(dsv != nullptr);
+
+ const auto &nativeFormat = depthStencilRenderTarget->getFormatSet().format();
+ const auto *stencilAttachment = fboData.getStencilAttachment();
+
+ uint32_t stencilUnmasked =
+ (stencilAttachment != nullptr) ? (1 << nativeFormat.stencilBits) - 1 : 0;
+ bool needMaskedStencilClear =
+ clearParams.clearStencil &&
+ (clearParams.stencilWriteMask & stencilUnmasked) != stencilUnmasked;
+
+ if (!needScissoredClear && !needMaskedStencilClear)
+ {
+ const UINT clearFlags = (clearParams.clearDepth ? D3D11_CLEAR_DEPTH : 0) |
+ (clearParams.clearStencil ? D3D11_CLEAR_STENCIL : 0);
+ const FLOAT depthClear = gl::clamp01(clearParams.depthValue);
+ const UINT8 stencilClear = clearParams.stencilValue & 0xFF;
+
+ deviceContext->ClearDepthStencilView(dsv, clearFlags, depthClear, stencilClear);
+
+ dsv = nullptr;
+ }
+ }
+
+ if (numRtvs == 0 && dsv == nullptr)
+ {
+ return angle::Result::Continue;
+ }
+
+ // Clear the remaining render targets and depth stencil in one pass by rendering a quad:
+ //
+ // IA/VS: Vertices containing position and color members are passed through to the next stage.
+ // The vertex position has XY coordinates equal to clip extents and a Z component equal to the
+ // Z clear value. The vertex color contains the clear color.
+ //
+ // Rasterizer: Viewport scales the VS output over the entire surface and depending on whether
+ // or not scissoring is enabled the appropriate scissor rect and rasterizerState with or without
+ // the scissor test enabled is set as well.
+ //
+ // DepthStencilTest: DepthTesting, DepthWrites, StencilMask and StencilWrites will be enabled or
+ // disabled or set depending on what the input depthStencil clear parameters are. Since the PS
+ // is not writing out depth or rejecting pixels, this should happen prior to the PS stage.
+ //
+ // PS: Will write out the color values passed through from the previous stage to all outputs.
+ //
+ // OM: BlendState will perform the required color masking and output to RTV(s).
+
+ //
+ // ======================================================================================
+ //
+ // 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.
+
+ ASSERT(numRtvs <= static_cast<uint32_t>(mRenderer->getNativeCaps().maxDrawBuffers));
+
+ // Setup BlendStateKey parameters
+ mBlendStateKey.blendStateExt.setColorMask(false, false, false, false);
+ for (size_t i = 0; i < numRtvs; i++)
+ {
+ mBlendStateKey.blendStateExt.setColorMaskIndexed(i, rtvMasks[i]);
+ }
+
+ mBlendStateKey.rtvMax = static_cast<uint16_t>(numRtvs);
+
+ // Get BlendState
+ const d3d11::BlendState *blendState = nullptr;
+ ANGLE_TRY(mRenderer->getBlendState(context, mBlendStateKey, &blendState));
+
+ const d3d11::DepthStencilState *dsState = nullptr;
+ const float *zValue = nullptr;
+
+ if (dsv)
+ {
+ // Setup DepthStencilStateKey
+ mDepthStencilStateKey.depthTest = clearParams.clearDepth;
+ mDepthStencilStateKey.depthMask = clearParams.clearDepth;
+ mDepthStencilStateKey.stencilWritemask = clearParams.stencilWriteMask;
+ mDepthStencilStateKey.stencilTest = clearParams.clearStencil;
+
+ // Get DepthStencilState
+ ANGLE_TRY(mRenderer->getDepthStencilState(context, mDepthStencilStateKey, &dsState));
+ zValue = clearParams.clearDepth ? &clearParams.depthValue : nullptr;
+ }
+
+ bool dirtyCb = false;
+
+ // Compare the input color/z values against the CB cache and update it if necessary
+ switch (clearParams.colorType)
+ {
+ case GL_FLOAT:
+ dirtyCb =
+ UpdateDataCache(&mShaderData, clearParams.colorF, zValue, numRtvs, commonColorMask);
+ break;
+ case GL_UNSIGNED_INT:
+ dirtyCb = UpdateDataCache(reinterpret_cast<RtvDsvClearInfo<uint32_t> *>(&mShaderData),
+ clearParams.colorUI, zValue, numRtvs, commonColorMask);
+ break;
+ case GL_INT:
+ dirtyCb = UpdateDataCache(reinterpret_cast<RtvDsvClearInfo<int> *>(&mShaderData),
+ clearParams.colorI, zValue, numRtvs, commonColorMask);
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ ANGLE_TRY(ensureConstantBufferCreated(context));
+
+ if (dirtyCb)
+ {
+ // Update the constant buffer with the updated cache contents
+ // TODO(Shahmeer): Consider using UpdateSubresource1 D3D11_COPY_DISCARD where possible.
+ D3D11_MAPPED_SUBRESOURCE mappedResource;
+ ANGLE_TRY(mRenderer->mapResource(context, mConstantBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD,
+ 0, &mappedResource));
+
+ memcpy(mappedResource.pData, &mShaderData, g_ConstantBufferSize);
+ deviceContext->Unmap(mConstantBuffer.get(), 0);
+ }
+
+ auto *stateManager = mRenderer->getStateManager();
+
+ // Set the viewport to be the same size as the framebuffer.
+ stateManager->setSimpleViewport(framebufferSize);
+
+ // Apply state
+ stateManager->setSimpleBlendState(blendState);
+
+ const UINT stencilValue = clearParams.stencilValue & 0xFF;
+ stateManager->setDepthStencilState(dsState, stencilValue);
+
+ if (needScissoredClear)
+ {
+ stateManager->setRasterizerState(&mScissorEnabledRasterizerState);
+ }
+ else
+ {
+ stateManager->setRasterizerState(&mScissorDisabledRasterizerState);
+ }
+
+ // Get Shaders
+ const d3d11::VertexShader *vs = nullptr;
+ const d3d11::GeometryShader *gs = nullptr;
+ const d3d11::InputLayout *il = nullptr;
+ const d3d11::PixelShader *ps = nullptr;
+ const bool hasLayeredLayout = (fboData.isMultiview());
+ ANGLE_TRY(mShaderManager.getShadersAndLayout(context, mRenderer, clearParams.colorType, numRtvs,
+ hasLayeredLayout, &il, &vs, &gs, &ps));
+
+ // Apply Shaders
+ stateManager->setDrawShaders(vs, gs, ps);
+ stateManager->setPixelConstantBuffer(0, &mConstantBuffer);
+
+ // Bind IL & VB if needed
+ stateManager->setIndexBuffer(nullptr, DXGI_FORMAT_UNKNOWN, 0);
+ stateManager->setInputLayout(il);
+
+ if (useVertexBuffer())
+ {
+ ANGLE_TRY(ensureVertexBufferCreated(context));
+ stateManager->setSingleVertexBuffer(&mVertexBuffer, g_VertexSize, 0);
+ }
+ else
+ {
+ stateManager->setSingleVertexBuffer(nullptr, 0, 0);
+ }
+
+ stateManager->setPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
+
+ // Apply render targets
+ stateManager->setRenderTargets(&rtvs[0], numRtvs, dsv);
+
+ if (needScissoredClear)
+ {
+ stateManager->setScissorRectD3D(scissorRect);
+ }
+ // Draw the fullscreen quad.
+ if (!hasLayeredLayout)
+ {
+ deviceContext->Draw(6, 0);
+ }
+ else
+ {
+ ASSERT(hasLayeredLayout);
+ deviceContext->DrawInstanced(6, static_cast<UINT>(fboData.getNumViews()), 0, 0);
+ }
+
+ return angle::Result::Continue;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Clear11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Clear11.h
new file mode 100644
index 0000000000..2e2eca5e80
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Clear11.h
@@ -0,0 +1,102 @@
+//
+// Copyright 2013 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.
+//
+
+// Clear11.h: Framebuffer clear utility class.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_CLEAR11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_CLEAR11_H_
+
+#include <map>
+#include <vector>
+
+#include "libANGLE/Error.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+
+namespace rx
+{
+class Renderer11;
+class RenderTarget11;
+struct ClearParameters;
+
+template <typename T>
+struct RtvDsvClearInfo
+{
+ T r, g, b, a;
+ float z;
+ float c1padding[3];
+};
+
+class Clear11 : angle::NonCopyable
+{
+ public:
+ explicit Clear11(Renderer11 *renderer);
+ ~Clear11();
+
+ // Clears the framebuffer with the supplied clear parameters, assumes that the framebuffer is
+ // currently applied.
+ angle::Result clearFramebuffer(const gl::Context *context,
+ const ClearParameters &clearParams,
+ const gl::FramebufferState &fboData);
+
+ private:
+ class ShaderManager final : angle::NonCopyable
+ {
+ public:
+ ShaderManager();
+ ~ShaderManager();
+ angle::Result getShadersAndLayout(const gl::Context *context,
+ Renderer11 *renderer,
+ const INT clearType,
+ const uint32_t numRTs,
+ const bool hasLayeredLayout,
+ const d3d11::InputLayout **il,
+ const d3d11::VertexShader **vs,
+ const d3d11::GeometryShader **gs,
+ const d3d11::PixelShader **ps);
+
+ private:
+ constexpr static size_t kNumShaders = D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT;
+
+ d3d11::InputLayout mIl9;
+ d3d11::LazyShader<ID3D11VertexShader> mVs9;
+ d3d11::LazyShader<ID3D11PixelShader> mPsFloat9;
+ d3d11::LazyShader<ID3D11VertexShader> mVs;
+ d3d11::LazyShader<ID3D11VertexShader> mVsMultiview;
+ d3d11::LazyShader<ID3D11GeometryShader> mGsMultiview;
+ d3d11::LazyShader<ID3D11PixelShader> mPsDepth;
+ std::array<d3d11::LazyShader<ID3D11PixelShader>, kNumShaders> mPsFloat;
+ std::array<d3d11::LazyShader<ID3D11PixelShader>, kNumShaders> mPsUInt;
+ std::array<d3d11::LazyShader<ID3D11PixelShader>, kNumShaders> mPsSInt;
+ };
+
+ bool useVertexBuffer() const;
+ angle::Result ensureConstantBufferCreated(const gl::Context *context);
+ angle::Result ensureVertexBufferCreated(const gl::Context *context);
+ angle::Result ensureResourcesInitialized(const gl::Context *context);
+
+ Renderer11 *mRenderer;
+ bool mResourcesInitialized;
+
+ // States
+ d3d11::RasterizerState mScissorEnabledRasterizerState;
+ d3d11::RasterizerState mScissorDisabledRasterizerState;
+ gl::DepthStencilState mDepthStencilStateKey;
+ d3d11::BlendStateKey mBlendStateKey;
+
+ // Shaders and shader resources
+ ShaderManager mShaderManager;
+ d3d11::Buffer mConstantBuffer;
+ d3d11::Buffer mVertexBuffer;
+
+ // Buffer data and draw parameters
+ RtvDsvClearInfo<float> mShaderData;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D11_CLEAR11_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Context11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Context11.cpp
new file mode 100644
index 0000000000..f3b13f678a
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Context11.cpp
@@ -0,0 +1,1048 @@
+//
+// 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.
+//
+// Context11:
+// D3D11-specific functionality associated with a GL Context.
+//
+
+#include "libANGLE/renderer/d3d/d3d11/Context11.h"
+
+#include "common/entry_points_enum_autogen.h"
+#include "common/string_utils.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Context.inl.h"
+#include "libANGLE/MemoryProgramCache.h"
+#include "libANGLE/renderer/OverlayImpl.h"
+#include "libANGLE/renderer/d3d/CompilerD3D.h"
+#include "libANGLE/renderer/d3d/RenderbufferD3D.h"
+#include "libANGLE/renderer/d3d/SamplerD3D.h"
+#include "libANGLE/renderer/d3d/ShaderD3D.h"
+#include "libANGLE/renderer/d3d/TextureD3D.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/IndexBuffer11.h"
+#include "libANGLE/renderer/d3d/d3d11/Program11.h"
+#include "libANGLE/renderer/d3d/d3d11/ProgramPipeline11.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"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+
+namespace rx
+{
+
+namespace
+{
+ANGLE_INLINE bool DrawCallHasDynamicAttribs(const gl::Context *context)
+{
+ VertexArray11 *vertexArray11 = GetImplAs<VertexArray11>(context->getState().getVertexArray());
+ return vertexArray11->hasActiveDynamicAttrib(context);
+}
+
+bool DrawCallHasStreamingVertexArrays(const gl::Context *context, gl::PrimitiveMode mode)
+{
+ // Direct drawing doesn't support dynamic attribute storage since it needs the first and count
+ // to translate when applyVertexBuffer. GL_LINE_LOOP and GL_TRIANGLE_FAN are not supported
+ // either since we need to simulate them in D3D.
+ if (DrawCallHasDynamicAttribs(context) || mode == gl::PrimitiveMode::LineLoop ||
+ mode == gl::PrimitiveMode::TriangleFan)
+ {
+ return true;
+ }
+
+ ProgramD3D *programD3D = GetImplAs<ProgramD3D>(context->getState().getProgram());
+ if (InstancedPointSpritesActive(programD3D, mode))
+ {
+ return true;
+ }
+
+ return false;
+}
+
+bool DrawCallHasStreamingElementArray(const gl::Context *context, gl::DrawElementsType srcType)
+{
+ const gl::State &glState = context->getState();
+ gl::Buffer *elementArrayBuffer = glState.getVertexArray()->getElementArrayBuffer();
+
+ bool primitiveRestartWorkaround =
+ UsePrimitiveRestartWorkaround(glState.isPrimitiveRestartEnabled(), srcType);
+ const gl::DrawElementsType dstType =
+ (srcType == gl::DrawElementsType::UnsignedInt || primitiveRestartWorkaround)
+ ? gl::DrawElementsType::UnsignedInt
+ : gl::DrawElementsType::UnsignedShort;
+
+ // Not clear where the offset comes from here.
+ switch (ClassifyIndexStorage(glState, elementArrayBuffer, srcType, dstType, 0))
+ {
+ case IndexStorageType::Dynamic:
+ return true;
+ case IndexStorageType::Direct:
+ return false;
+ case IndexStorageType::Static:
+ {
+ BufferD3D *bufferD3D = GetImplAs<BufferD3D>(elementArrayBuffer);
+ StaticIndexBufferInterface *staticBuffer = bufferD3D->getStaticIndexBuffer();
+ return (staticBuffer->getBufferSize() == 0 || staticBuffer->getIndexType() != dstType);
+ }
+ default:
+ UNREACHABLE();
+ return true;
+ }
+}
+
+template <typename IndirectBufferT>
+angle::Result ReadbackIndirectBuffer(const gl::Context *context,
+ const void *indirect,
+ const IndirectBufferT **bufferPtrOut)
+{
+ const gl::State &glState = context->getState();
+ gl::Buffer *drawIndirectBuffer = glState.getTargetBuffer(gl::BufferBinding::DrawIndirect);
+ ASSERT(drawIndirectBuffer);
+ Buffer11 *storage = GetImplAs<Buffer11>(drawIndirectBuffer);
+ uintptr_t offset = reinterpret_cast<uintptr_t>(indirect);
+
+ const uint8_t *bufferData = nullptr;
+ ANGLE_TRY(storage->getData(context, &bufferData));
+ ASSERT(bufferData);
+
+ *bufferPtrOut = reinterpret_cast<const IndirectBufferT *>(bufferData + offset);
+ return angle::Result::Continue;
+}
+} // anonymous namespace
+
+Context11::Context11(const gl::State &state, gl::ErrorSet *errorSet, Renderer11 *renderer)
+ : ContextD3D(state, errorSet), mRenderer(renderer)
+{}
+
+Context11::~Context11() {}
+
+angle::Result Context11::initialize()
+{
+ return angle::Result::Continue;
+}
+
+void Context11::onDestroy(const gl::Context *context)
+{
+ mIncompleteTextures.onDestroy(context);
+}
+
+CompilerImpl *Context11::createCompiler()
+{
+ if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3)
+ {
+ return new CompilerD3D(SH_HLSL_4_0_FL9_3_OUTPUT);
+ }
+ else
+ {
+ return new CompilerD3D(SH_HLSL_4_1_OUTPUT);
+ }
+}
+
+ShaderImpl *Context11::createShader(const gl::ShaderState &data)
+{
+ return new ShaderD3D(data, mRenderer);
+}
+
+ProgramImpl *Context11::createProgram(const gl::ProgramState &data)
+{
+ return new Program11(data, mRenderer);
+}
+
+FramebufferImpl *Context11::createFramebuffer(const gl::FramebufferState &data)
+{
+ return new Framebuffer11(data, mRenderer);
+}
+
+TextureImpl *Context11::createTexture(const gl::TextureState &state)
+{
+ switch (state.getType())
+ {
+ case gl::TextureType::_2D:
+ // GL_TEXTURE_VIDEO_IMAGE_WEBGL maps to native 2D texture on Windows platform
+ case gl::TextureType::VideoImage:
+ return new TextureD3D_2D(state, mRenderer);
+ case gl::TextureType::CubeMap:
+ return new TextureD3D_Cube(state, mRenderer);
+ case gl::TextureType::_3D:
+ return new TextureD3D_3D(state, mRenderer);
+ case gl::TextureType::_2DArray:
+ return new TextureD3D_2DArray(state, mRenderer);
+ case gl::TextureType::External:
+ return new TextureD3D_External(state, mRenderer);
+ case gl::TextureType::_2DMultisample:
+ return new TextureD3D_2DMultisample(state, mRenderer);
+ case gl::TextureType::_2DMultisampleArray:
+ return new TextureD3D_2DMultisampleArray(state, mRenderer);
+ case gl::TextureType::Buffer:
+ return new TextureD3D_Buffer(state, mRenderer);
+ default:
+ UNREACHABLE();
+ }
+
+ return nullptr;
+}
+
+RenderbufferImpl *Context11::createRenderbuffer(const gl::RenderbufferState &state)
+{
+ return new RenderbufferD3D(state, mRenderer);
+}
+
+BufferImpl *Context11::createBuffer(const gl::BufferState &state)
+{
+ Buffer11 *buffer = new Buffer11(state, mRenderer);
+ mRenderer->onBufferCreate(buffer);
+ return buffer;
+}
+
+VertexArrayImpl *Context11::createVertexArray(const gl::VertexArrayState &data)
+{
+ return new VertexArray11(data);
+}
+
+QueryImpl *Context11::createQuery(gl::QueryType type)
+{
+ return new Query11(mRenderer, type);
+}
+
+FenceNVImpl *Context11::createFenceNV()
+{
+ return new FenceNV11(mRenderer);
+}
+
+SyncImpl *Context11::createSync()
+{
+ return new Sync11(mRenderer);
+}
+
+TransformFeedbackImpl *Context11::createTransformFeedback(const gl::TransformFeedbackState &state)
+{
+ return new TransformFeedback11(state, mRenderer);
+}
+
+SamplerImpl *Context11::createSampler(const gl::SamplerState &state)
+{
+ return new SamplerD3D(state);
+}
+
+ProgramPipelineImpl *Context11::createProgramPipeline(const gl::ProgramPipelineState &data)
+{
+ return new ProgramPipeline11(data);
+}
+
+MemoryObjectImpl *Context11::createMemoryObject()
+{
+ UNREACHABLE();
+ return nullptr;
+}
+
+SemaphoreImpl *Context11::createSemaphore()
+{
+ UNREACHABLE();
+ return nullptr;
+}
+
+OverlayImpl *Context11::createOverlay(const gl::OverlayState &state)
+{
+ // Not implemented.
+ return new OverlayImpl(state);
+}
+
+angle::Result Context11::flush(const gl::Context *context)
+{
+ return mRenderer->flush(this);
+}
+
+angle::Result Context11::finish(const gl::Context *context)
+{
+ return mRenderer->finish(this);
+}
+
+angle::Result Context11::drawArrays(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLint first,
+ GLsizei count)
+{
+ ASSERT(count > 0);
+ ANGLE_TRY(mRenderer->getStateManager()->updateState(
+ context, mode, first, count, gl::DrawElementsType::InvalidEnum, nullptr, 0, 0, 0, true));
+ return mRenderer->drawArrays(context, mode, first, count, 0, 0, false);
+}
+
+angle::Result Context11::drawArraysInstanced(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLint first,
+ GLsizei count,
+ GLsizei instanceCount)
+{
+ ASSERT(count > 0);
+ ANGLE_TRY(mRenderer->getStateManager()->updateState(context, mode, first, count,
+ gl::DrawElementsType::InvalidEnum, nullptr,
+ instanceCount, 0, 0, true));
+ return mRenderer->drawArrays(context, mode, first, count, instanceCount, 0, true);
+}
+
+angle::Result Context11::drawArraysInstancedBaseInstance(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLint first,
+ GLsizei count,
+ GLsizei instanceCount,
+ GLuint baseInstance)
+{
+ ASSERT(count > 0);
+ ANGLE_TRY(mRenderer->getStateManager()->updateState(context, mode, first, count,
+ gl::DrawElementsType::InvalidEnum, nullptr,
+ instanceCount, 0, baseInstance, true));
+ return mRenderer->drawArrays(context, mode, first, count, instanceCount, baseInstance, true);
+}
+
+ANGLE_INLINE angle::Result Context11::drawElementsImpl(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLsizei indexCount,
+ gl::DrawElementsType indexType,
+ const void *indices,
+ GLsizei instanceCount,
+ GLint baseVertex,
+ GLuint baseInstance,
+ bool promoteDynamic,
+ bool isInstancedDraw)
+{
+ ASSERT(indexCount > 0);
+
+ if (DrawCallHasDynamicAttribs(context))
+ {
+ gl::IndexRange indexRange;
+ ANGLE_TRY(context->getState().getVertexArray()->getIndexRange(
+ context, indexType, indexCount, indices, &indexRange));
+ GLint startVertex;
+ ANGLE_TRY(ComputeStartVertex(GetImplAs<Context11>(context), indexRange, baseVertex,
+ &startVertex));
+ ANGLE_TRY(mRenderer->getStateManager()->updateState(
+ context, mode, startVertex, indexCount, indexType, indices, instanceCount, baseVertex,
+ baseInstance, promoteDynamic));
+ return mRenderer->drawElements(context, mode, startVertex, indexCount, indexType, indices,
+ instanceCount, baseVertex, baseInstance, isInstancedDraw);
+ }
+ else
+ {
+ ANGLE_TRY(mRenderer->getStateManager()->updateState(context, mode, 0, indexCount, indexType,
+ indices, instanceCount, baseVertex,
+ baseInstance, promoteDynamic));
+ return mRenderer->drawElements(context, mode, 0, indexCount, indexType, indices,
+ instanceCount, baseVertex, baseInstance, isInstancedDraw);
+ }
+}
+
+angle::Result Context11::drawElements(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices)
+{
+ return drawElementsImpl(context, mode, count, type, indices, 0, 0, 0, true, false);
+}
+
+angle::Result Context11::drawElementsBaseVertex(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices,
+ GLint baseVertex)
+{
+ return drawElementsImpl(context, mode, count, type, indices, 0, baseVertex, 0, true, false);
+}
+
+angle::Result Context11::drawElementsInstanced(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices,
+ GLsizei instances)
+{
+ return drawElementsImpl(context, mode, count, type, indices, instances, 0, 0, true, true);
+}
+
+angle::Result Context11::drawElementsInstancedBaseVertex(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices,
+ GLsizei instances,
+ GLint baseVertex)
+{
+ return drawElementsImpl(context, mode, count, type, indices, instances, baseVertex, 0, true,
+ true);
+}
+
+angle::Result Context11::drawElementsInstancedBaseVertexBaseInstance(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices,
+ GLsizei instances,
+ GLint baseVertex,
+ GLuint baseInstance)
+{
+ return drawElementsImpl(context, mode, count, type, indices, instances, baseVertex,
+ baseInstance, true, true);
+}
+
+angle::Result Context11::drawRangeElements(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices)
+{
+ return drawElementsImpl(context, mode, count, type, indices, 0, 0, 0, true, false);
+}
+
+angle::Result Context11::drawRangeElementsBaseVertex(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices,
+ GLint baseVertex)
+{
+ return drawElementsImpl(context, mode, count, type, indices, 0, baseVertex, 0, true, false);
+}
+
+angle::Result Context11::drawArraysIndirect(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const void *indirect)
+{
+ if (DrawCallHasStreamingVertexArrays(context, mode))
+ {
+ const gl::DrawArraysIndirectCommand *cmd = nullptr;
+ ANGLE_TRY(ReadbackIndirectBuffer(context, indirect, &cmd));
+
+ ANGLE_TRY(mRenderer->getStateManager()->updateState(
+ context, mode, cmd->first, cmd->count, gl::DrawElementsType::InvalidEnum, nullptr,
+ cmd->instanceCount, 0, 0, true));
+ return mRenderer->drawArrays(context, mode, cmd->first, cmd->count, cmd->instanceCount,
+ cmd->baseInstance, true);
+ }
+ else
+ {
+ ANGLE_TRY(mRenderer->getStateManager()->updateState(
+ context, mode, 0, 0, gl::DrawElementsType::InvalidEnum, nullptr, 0, 0, 0, true));
+ return mRenderer->drawArraysIndirect(context, indirect);
+ }
+}
+
+angle::Result Context11::drawElementsIndirect(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ gl::DrawElementsType type,
+ const void *indirect)
+{
+ if (DrawCallHasStreamingVertexArrays(context, mode) ||
+ DrawCallHasStreamingElementArray(context, type))
+ {
+ const gl::DrawElementsIndirectCommand *cmd = nullptr;
+ ANGLE_TRY(ReadbackIndirectBuffer(context, indirect, &cmd));
+
+ const GLuint typeBytes = gl::GetDrawElementsTypeSize(type);
+ const void *indices =
+ reinterpret_cast<const void *>(static_cast<uintptr_t>(cmd->firstIndex * typeBytes));
+
+ // We must explicitly resolve the index range for the slow-path indirect drawElements to
+ // make sure we are using the correct 'baseVertex'. This parameter does not exist for the
+ // direct drawElements.
+ gl::IndexRange indexRange;
+ ANGLE_TRY(context->getState().getVertexArray()->getIndexRange(context, type, cmd->count,
+ indices, &indexRange));
+
+ GLint startVertex;
+ ANGLE_TRY(ComputeStartVertex(GetImplAs<Context11>(context), indexRange, cmd->baseVertex,
+ &startVertex));
+
+ ANGLE_TRY(mRenderer->getStateManager()->updateState(
+ context, mode, startVertex, cmd->count, type, indices, cmd->primCount, cmd->baseVertex,
+ cmd->baseInstance, true));
+ return mRenderer->drawElements(context, mode, static_cast<GLint>(indexRange.start),
+ cmd->count, type, indices, cmd->primCount, 0, 0, true);
+ }
+ else
+ {
+ ANGLE_TRY(mRenderer->getStateManager()->updateState(context, mode, 0, 0, type, nullptr, 0,
+ 0, 0, true));
+ return mRenderer->drawElementsIndirect(context, indirect);
+ }
+}
+
+#define DRAW_ARRAYS__ \
+ { \
+ ANGLE_TRY(mRenderer->getStateManager()->updateState( \
+ context, mode, firsts[drawID], counts[drawID], gl::DrawElementsType::InvalidEnum, \
+ nullptr, 0, 0, 0, false)); \
+ ANGLE_TRY( \
+ mRenderer->drawArrays(context, mode, firsts[drawID], counts[drawID], 0, 0, false)); \
+ }
+#define DRAW_ARRAYS_INSTANCED_ \
+ { \
+ ANGLE_TRY(mRenderer->getStateManager()->updateState( \
+ context, mode, firsts[drawID], counts[drawID], gl::DrawElementsType::InvalidEnum, \
+ nullptr, instanceCounts[drawID], 0, 0, false)); \
+ ANGLE_TRY(mRenderer->drawArrays(context, mode, firsts[drawID], counts[drawID], \
+ instanceCounts[drawID], 0, true)); \
+ }
+#define DRAW_ARRAYS_INSTANCED_BASE_INSTANCE \
+ { \
+ ANGLE_TRY(mRenderer->getStateManager()->updateState( \
+ context, mode, firsts[drawID], counts[drawID], gl::DrawElementsType::InvalidEnum, \
+ nullptr, instanceCounts[drawID], 0, baseInstances[drawID], false)); \
+ ANGLE_TRY(mRenderer->drawArrays(context, mode, firsts[drawID], counts[drawID], \
+ instanceCounts[drawID], baseInstances[drawID], true)); \
+ }
+#define DRAW_ELEMENTS__ \
+ { \
+ ANGLE_TRY(drawElementsImpl(context, mode, counts[drawID], type, indices[drawID], 0, 0, 0, \
+ false, false)); \
+ }
+#define DRAW_ELEMENTS_INSTANCED_ \
+ { \
+ ANGLE_TRY(drawElementsImpl(context, mode, counts[drawID], type, indices[drawID], \
+ instanceCounts[drawID], 0, 0, false, true)); \
+ }
+#define DRAW_ELEMENTS_INSTANCED_BASE_VERTEX_BASE_INSTANCE \
+ { \
+ ANGLE_TRY(drawElementsImpl(context, mode, counts[drawID], type, indices[drawID], \
+ instanceCounts[drawID], baseVertices[drawID], \
+ baseInstances[drawID], false, true)); \
+ }
+
+#define DRAW_CALL(drawType, instanced, bvbi) DRAW_##drawType##instanced##bvbi
+
+#define MULTI_DRAW_BLOCK(drawType, instanced, bvbi, hasDrawID, hasBaseVertex, hasBaseInstance) \
+ for (GLsizei drawID = 0; drawID < drawcount; ++drawID) \
+ { \
+ if (ANGLE_NOOP_DRAW(instanced)) \
+ { \
+ continue; \
+ } \
+ ANGLE_SET_DRAW_ID_UNIFORM(hasDrawID)(drawID); \
+ ANGLE_SET_BASE_VERTEX_UNIFORM(hasBaseVertex)(baseVertices[drawID]); \
+ ANGLE_SET_BASE_INSTANCE_UNIFORM(hasBaseInstance)(baseInstances[drawID]); \
+ ASSERT(counts[drawID] > 0); \
+ DRAW_CALL(drawType, instanced, bvbi); \
+ ANGLE_MARK_TRANSFORM_FEEDBACK_USAGE(instanced); \
+ gl::MarkShaderStorageUsage(context); \
+ }
+
+angle::Result Context11::multiDrawArrays(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const GLint *firsts,
+ const GLsizei *counts,
+ GLsizei drawcount)
+{
+ gl::Program *programObject = context->getState().getLinkedProgram(context);
+ const bool hasDrawID = programObject && programObject->hasDrawIDUniform();
+ if (hasDrawID)
+ {
+ MULTI_DRAW_BLOCK(ARRAYS, _, _, 1, 0, 0)
+ }
+ else
+ {
+ MULTI_DRAW_BLOCK(ARRAYS, _, _, 0, 0, 0)
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result Context11::multiDrawArraysInstanced(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const GLint *firsts,
+ const GLsizei *counts,
+ const GLsizei *instanceCounts,
+ GLsizei drawcount)
+{
+ gl::Program *programObject = context->getState().getLinkedProgram(context);
+ const bool hasDrawID = programObject && programObject->hasDrawIDUniform();
+ if (hasDrawID)
+ {
+ MULTI_DRAW_BLOCK(ARRAYS, _INSTANCED, _, 1, 0, 0)
+ }
+ else
+ {
+ MULTI_DRAW_BLOCK(ARRAYS, _INSTANCED, _, 0, 0, 0)
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result Context11::multiDrawArraysIndirect(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const void *indirect,
+ GLsizei drawcount,
+ GLsizei stride)
+{
+ return rx::MultiDrawArraysIndirectGeneral(this, context, mode, indirect, drawcount, stride);
+}
+
+angle::Result Context11::multiDrawElements(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const GLsizei *counts,
+ gl::DrawElementsType type,
+ const GLvoid *const *indices,
+ GLsizei drawcount)
+{
+ gl::Program *programObject = context->getState().getLinkedProgram(context);
+ const bool hasDrawID = programObject && programObject->hasDrawIDUniform();
+ if (hasDrawID)
+ {
+ MULTI_DRAW_BLOCK(ELEMENTS, _, _, 1, 0, 0)
+ }
+ else
+ {
+ MULTI_DRAW_BLOCK(ELEMENTS, _, _, 0, 0, 0)
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result Context11::multiDrawElementsInstanced(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const GLsizei *counts,
+ gl::DrawElementsType type,
+ const GLvoid *const *indices,
+ const GLsizei *instanceCounts,
+ GLsizei drawcount)
+{
+ gl::Program *programObject = context->getState().getLinkedProgram(context);
+ const bool hasDrawID = programObject && programObject->hasDrawIDUniform();
+ if (hasDrawID)
+ {
+ MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _, 1, 0, 0)
+ }
+ else
+ {
+ MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _, 0, 0, 0)
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result Context11::multiDrawElementsIndirect(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ gl::DrawElementsType type,
+ const void *indirect,
+ GLsizei drawcount,
+ GLsizei stride)
+{
+ return rx::MultiDrawElementsIndirectGeneral(this, context, mode, type, indirect, drawcount,
+ stride);
+}
+
+angle::Result Context11::multiDrawArraysInstancedBaseInstance(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const GLint *firsts,
+ const GLsizei *counts,
+ const GLsizei *instanceCounts,
+ const GLuint *baseInstances,
+ GLsizei drawcount)
+{
+ gl::Program *programObject = context->getState().getLinkedProgram(context);
+ const bool hasDrawID = programObject && programObject->hasDrawIDUniform();
+ const bool hasBaseInstance = programObject && programObject->hasBaseInstanceUniform();
+ ResetBaseVertexBaseInstance resetUniforms(programObject, false, hasBaseInstance);
+
+ if (hasDrawID && hasBaseInstance)
+ {
+ MULTI_DRAW_BLOCK(ARRAYS, _INSTANCED, _BASE_INSTANCE, 1, 0, 1)
+ }
+ else if (hasDrawID)
+ {
+ MULTI_DRAW_BLOCK(ARRAYS, _INSTANCED, _BASE_INSTANCE, 1, 0, 0)
+ }
+ else if (hasBaseInstance)
+ {
+ MULTI_DRAW_BLOCK(ARRAYS, _INSTANCED, _BASE_INSTANCE, 0, 0, 1)
+ }
+ else
+ {
+ MULTI_DRAW_BLOCK(ARRAYS, _INSTANCED, _BASE_INSTANCE, 0, 0, 0)
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result Context11::multiDrawElementsInstancedBaseVertexBaseInstance(
+ const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const GLsizei *counts,
+ gl::DrawElementsType type,
+ const GLvoid *const *indices,
+ const GLsizei *instanceCounts,
+ const GLint *baseVertices,
+ const GLuint *baseInstances,
+ GLsizei drawcount)
+{
+ gl::Program *programObject = context->getState().getLinkedProgram(context);
+ const bool hasDrawID = programObject && programObject->hasDrawIDUniform();
+ const bool hasBaseVertex = programObject && programObject->hasBaseVertexUniform();
+ const bool hasBaseInstance = programObject && programObject->hasBaseInstanceUniform();
+ ResetBaseVertexBaseInstance resetUniforms(programObject, hasBaseVertex, hasBaseInstance);
+
+ if (hasDrawID)
+ {
+ if (hasBaseVertex)
+ {
+ if (hasBaseInstance)
+ {
+ MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 1, 1, 1)
+ }
+ else
+ {
+ MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 1, 1, 0)
+ }
+ }
+ else
+ {
+ if (hasBaseInstance)
+ {
+ MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 1, 0, 1)
+ }
+ else
+ {
+ MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 1, 0, 0)
+ }
+ }
+ }
+ else
+ {
+ if (hasBaseVertex)
+ {
+ if (hasBaseInstance)
+ {
+ MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 0, 1, 1)
+ }
+ else
+ {
+ MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 0, 1, 0)
+ }
+ }
+ else
+ {
+ if (hasBaseInstance)
+ {
+ MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 0, 0, 1)
+ }
+ else
+ {
+ MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 0, 0, 0)
+ }
+ }
+ }
+
+ return angle::Result::Continue;
+}
+
+gl::GraphicsResetStatus Context11::getResetStatus()
+{
+ return mRenderer->getResetStatus();
+}
+
+angle::Result Context11::insertEventMarker(GLsizei length, const char *marker)
+{
+ mRenderer->getDebugAnnotatorContext()->setMarker(marker);
+ return angle::Result::Continue;
+}
+
+angle::Result Context11::pushGroupMarker(GLsizei length, const char *marker)
+{
+ mRenderer->getDebugAnnotatorContext()->beginEvent(angle::EntryPoint::GLPushGroupMarkerEXT,
+ marker, marker);
+ mMarkerStack.push(std::string(marker));
+ return angle::Result::Continue;
+}
+
+angle::Result Context11::popGroupMarker()
+{
+ const char *marker = nullptr;
+ if (!mMarkerStack.empty())
+ {
+ marker = mMarkerStack.top().c_str();
+ mMarkerStack.pop();
+ mRenderer->getDebugAnnotatorContext()->endEvent(marker,
+ angle::EntryPoint::GLPopGroupMarkerEXT);
+ }
+ return angle::Result::Continue;
+}
+
+angle::Result Context11::pushDebugGroup(const gl::Context *context,
+ GLenum source,
+ GLuint id,
+ const std::string &message)
+{
+ // Fall through to the EXT_debug_marker functions
+ return pushGroupMarker(static_cast<GLsizei>(message.size()), message.c_str());
+}
+
+angle::Result Context11::popDebugGroup(const gl::Context *context)
+{
+ // Fall through to the EXT_debug_marker functions
+ return popGroupMarker();
+}
+
+angle::Result Context11::syncState(const gl::Context *context,
+ const gl::State::DirtyBits &dirtyBits,
+ const gl::State::DirtyBits &bitMask,
+ gl::Command command)
+{
+ mRenderer->getStateManager()->syncState(context, dirtyBits, command);
+ return angle::Result::Continue;
+}
+
+GLint Context11::getGPUDisjoint()
+{
+ return mRenderer->getGPUDisjoint();
+}
+
+GLint64 Context11::getTimestamp()
+{
+ return mRenderer->getTimestamp();
+}
+
+angle::Result Context11::onMakeCurrent(const gl::Context *context)
+{
+ // Immediately return if the device has been lost.
+ if (!mRenderer->getDevice())
+ {
+ return angle::Result::Continue;
+ }
+
+ return mRenderer->getStateManager()->onMakeCurrent(context);
+}
+
+gl::Caps Context11::getNativeCaps() const
+{
+ gl::Caps caps = mRenderer->getNativeCaps();
+
+ // For pixel shaders, the render targets and unordered access views share the same resource
+ // slots, so the maximum number of fragment shader outputs depends on the current context
+ // version:
+ // - If current context is ES 3.0 and below, we use D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT(8)
+ // as the value of max draw buffers because UAVs are not used.
+ // - If current context is ES 3.1 and the feature level is 11_0, the RTVs and UAVs share 8
+ // slots. As ES 3.1 requires at least 1 atomic counter buffer in compute shaders, the value
+ // of max combined shader output resources is limited to 7, thus only 7 RTV slots can be
+ // used simultaneously.
+ // - If current context is ES 3.1 and the feature level is 11_1, the RTVs and UAVs share 64
+ // slots. Currently we allocate 60 slots for combined shader output resources, so we can use
+ // at most D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT(8) RTVs simultaneously.
+ if (mState.getClientVersion() >= gl::ES_3_1 &&
+ mRenderer->getRenderer11DeviceCaps().featureLevel == D3D_FEATURE_LEVEL_11_0)
+ {
+ caps.maxDrawBuffers = caps.maxCombinedShaderOutputResources;
+ caps.maxColorAttachments = caps.maxCombinedShaderOutputResources;
+ }
+
+ return caps;
+}
+
+const gl::TextureCapsMap &Context11::getNativeTextureCaps() const
+{
+ return mRenderer->getNativeTextureCaps();
+}
+
+const gl::Extensions &Context11::getNativeExtensions() const
+{
+ return mRenderer->getNativeExtensions();
+}
+
+const gl::Limitations &Context11::getNativeLimitations() const
+{
+ return mRenderer->getNativeLimitations();
+}
+
+ShPixelLocalStorageType Context11::getNativePixelLocalStorageType() const
+{
+ return mRenderer->getNativePixelLocalStorageType();
+}
+
+angle::Result Context11::dispatchCompute(const gl::Context *context,
+ GLuint numGroupsX,
+ GLuint numGroupsY,
+ GLuint numGroupsZ)
+{
+ return mRenderer->dispatchCompute(context, numGroupsX, numGroupsY, numGroupsZ);
+}
+
+angle::Result Context11::dispatchComputeIndirect(const gl::Context *context, GLintptr indirect)
+{
+ return mRenderer->dispatchComputeIndirect(context, indirect);
+}
+
+angle::Result Context11::triggerDrawCallProgramRecompilation(const gl::Context *context,
+ gl::PrimitiveMode drawMode)
+{
+ const auto &glState = context->getState();
+ const auto *va11 = GetImplAs<VertexArray11>(glState.getVertexArray());
+ const auto *drawFBO = glState.getDrawFramebuffer();
+ gl::Program *program = glState.getProgram();
+ ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
+
+ programD3D->updateCachedInputLayout(va11->getCurrentStateSerial(), glState);
+ programD3D->updateCachedOutputLayout(context, drawFBO);
+
+ bool recompileVS = !programD3D->hasVertexExecutableForCachedInputLayout();
+ bool recompileGS = !programD3D->hasGeometryExecutableForPrimitiveType(glState, drawMode);
+ bool recompilePS = !programD3D->hasPixelExecutableForCachedOutputLayout();
+
+ if (!recompileVS && !recompileGS && !recompilePS)
+ {
+ return angle::Result::Continue;
+ }
+
+ // Load the compiler if necessary and recompile the programs.
+ ANGLE_TRY(mRenderer->ensureHLSLCompilerInitialized(this));
+
+ gl::InfoLog infoLog;
+
+ if (recompileVS)
+ {
+ ShaderExecutableD3D *vertexExe = nullptr;
+ ANGLE_TRY(programD3D->getVertexExecutableForCachedInputLayout(this, &vertexExe, &infoLog));
+ if (!programD3D->hasVertexExecutableForCachedInputLayout())
+ {
+ ASSERT(infoLog.getLength() > 0);
+ ERR() << "Error compiling dynamic vertex executable: " << infoLog.str();
+ ANGLE_TRY_HR(this, E_FAIL, "Error compiling dynamic vertex executable");
+ }
+ }
+
+ if (recompileGS)
+ {
+ ShaderExecutableD3D *geometryExe = nullptr;
+ ANGLE_TRY(programD3D->getGeometryExecutableForPrimitiveType(this, glState, drawMode,
+ &geometryExe, &infoLog));
+ if (!programD3D->hasGeometryExecutableForPrimitiveType(glState, drawMode))
+ {
+ ASSERT(infoLog.getLength() > 0);
+ ERR() << "Error compiling dynamic geometry executable: " << infoLog.str();
+ ANGLE_TRY_HR(this, E_FAIL, "Error compiling dynamic geometry executable");
+ }
+ }
+
+ if (recompilePS)
+ {
+ ShaderExecutableD3D *pixelExe = nullptr;
+ ANGLE_TRY(programD3D->getPixelExecutableForCachedOutputLayout(this, &pixelExe, &infoLog));
+ if (!programD3D->hasPixelExecutableForCachedOutputLayout())
+ {
+ ASSERT(infoLog.getLength() > 0);
+ ERR() << "Error compiling dynamic pixel executable: " << infoLog.str();
+ ANGLE_TRY_HR(this, E_FAIL, "Error compiling dynamic pixel executable");
+ }
+ }
+
+ // Refresh the program cache entry.
+ if (mMemoryProgramCache)
+ {
+ ANGLE_TRY(mMemoryProgramCache->updateProgram(context, program));
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result Context11::triggerDispatchCallProgramRecompilation(const gl::Context *context)
+{
+ const auto &glState = context->getState();
+ gl::Program *program = glState.getProgram();
+ ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
+
+ programD3D->updateCachedComputeImage2DBindLayout(context);
+
+ bool recompileCS = !programD3D->hasComputeExecutableForCachedImage2DBindLayout();
+
+ if (!recompileCS)
+ {
+ return angle::Result::Continue;
+ }
+
+ // Load the compiler if necessary and recompile the programs.
+ ANGLE_TRY(mRenderer->ensureHLSLCompilerInitialized(this));
+
+ gl::InfoLog infoLog;
+
+ ShaderExecutableD3D *computeExe = nullptr;
+ ANGLE_TRY(
+ programD3D->getComputeExecutableForImage2DBindLayout(context, this, &computeExe, &infoLog));
+ if (!programD3D->hasComputeExecutableForCachedImage2DBindLayout())
+ {
+ ASSERT(infoLog.getLength() > 0);
+ ERR() << "Dynamic recompilation error log: " << infoLog.str();
+ ANGLE_TRY_HR(this, E_FAIL, "Error compiling dynamic compute executable");
+ }
+
+ // Refresh the program cache entry.
+ if (mMemoryProgramCache)
+ {
+ ANGLE_TRY(mMemoryProgramCache->updateProgram(context, program));
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result Context11::memoryBarrier(const gl::Context *context, GLbitfield barriers)
+{
+ return angle::Result::Continue;
+}
+
+angle::Result Context11::memoryBarrierByRegion(const gl::Context *context, GLbitfield barriers)
+{
+ return angle::Result::Continue;
+}
+
+angle::Result Context11::getIncompleteTexture(const gl::Context *context,
+ gl::TextureType type,
+ gl::Texture **textureOut)
+{
+ return mIncompleteTextures.getIncompleteTexture(context, type, gl::SamplerFormat::Float, this,
+ textureOut);
+}
+
+angle::Result Context11::initializeMultisampleTextureToBlack(const gl::Context *context,
+ gl::Texture *glTexture)
+{
+ ASSERT(glTexture->getType() == gl::TextureType::_2DMultisample);
+ TextureD3D *textureD3D = GetImplAs<TextureD3D>(glTexture);
+ gl::ImageIndex index = gl::ImageIndex::Make2DMultisample();
+ RenderTargetD3D *renderTarget = nullptr;
+ GLsizei texSamples = textureD3D->getRenderToTextureSamples();
+ ANGLE_TRY(textureD3D->getRenderTarget(context, index, texSamples, &renderTarget));
+ return mRenderer->clearRenderTarget(context, renderTarget, gl::ColorF(0.0f, 0.0f, 0.0f, 1.0f),
+ 1.0f, 0);
+}
+
+void Context11::handleResult(HRESULT hr,
+ const char *message,
+ const char *file,
+ const char *function,
+ unsigned int line)
+{
+ ASSERT(FAILED(hr));
+
+ GLenum glErrorCode = DefaultGLErrorCode(hr);
+
+ std::stringstream errorStream;
+ errorStream << "Internal D3D11 error: " << gl::FmtHR(hr);
+
+ if (d3d11::isDeviceLostError(hr))
+ {
+ HRESULT removalReason = mRenderer->getDevice()->GetDeviceRemovedReason();
+ errorStream << " (removal reason: " << gl::FmtHR(removalReason) << ")";
+ mRenderer->notifyDeviceLost();
+ }
+
+ errorStream << ": " << message;
+
+ mErrors->handleError(glErrorCode, errorStream.str().c_str(), file, function, line);
+}
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Context11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Context11.h
new file mode 100644
index 0000000000..5f84e410b5
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Context11.h
@@ -0,0 +1,282 @@
+//
+// 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.
+//
+// Context11:
+// D3D11-specific functionality associated with a GL Context.
+//
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_CONTEXT11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_CONTEXT11_H_
+
+#include <stack>
+#include "libANGLE/renderer/ContextImpl.h"
+#include "libANGLE/renderer/d3d/ContextD3D.h"
+
+namespace rx
+{
+class Renderer11;
+
+class Context11 : public ContextD3D, public MultisampleTextureInitializer
+{
+ public:
+ Context11(const gl::State &state, gl::ErrorSet *errorSet, Renderer11 *renderer);
+ ~Context11() override;
+
+ angle::Result initialize() override;
+ void onDestroy(const gl::Context *context) override;
+
+ // 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(const gl::RenderbufferState &state) override;
+
+ // Buffer creation
+ BufferImpl *createBuffer(const gl::BufferState &state) override;
+
+ // Vertex Array creation
+ VertexArrayImpl *createVertexArray(const gl::VertexArrayState &data) override;
+
+ // Query and Fence creation
+ QueryImpl *createQuery(gl::QueryType type) override;
+ FenceNVImpl *createFenceNV() override;
+ SyncImpl *createSync() override;
+
+ // Transform Feedback creation
+ TransformFeedbackImpl *createTransformFeedback(
+ const gl::TransformFeedbackState &state) override;
+
+ // Sampler object creation
+ SamplerImpl *createSampler(const gl::SamplerState &state) override;
+
+ // Program Pipeline object creation
+ ProgramPipelineImpl *createProgramPipeline(const gl::ProgramPipelineState &data) override;
+
+ // Memory object creation.
+ MemoryObjectImpl *createMemoryObject() override;
+
+ // Semaphore creation.
+ SemaphoreImpl *createSemaphore() override;
+
+ // Overlay creation.
+ OverlayImpl *createOverlay(const gl::OverlayState &state) override;
+
+ // Flush and finish.
+ angle::Result flush(const gl::Context *context) override;
+ angle::Result finish(const gl::Context *context) override;
+
+ // Drawing methods.
+ angle::Result drawArrays(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLint first,
+ GLsizei count) override;
+ angle::Result drawArraysInstanced(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLint first,
+ GLsizei count,
+ GLsizei instanceCount) override;
+ angle::Result drawArraysInstancedBaseInstance(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLint first,
+ GLsizei count,
+ GLsizei instanceCount,
+ GLuint baseInstance) override;
+
+ angle::Result drawElements(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices) override;
+ angle::Result drawElementsBaseVertex(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices,
+ GLint baseVertex) override;
+ angle::Result drawElementsInstanced(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices,
+ GLsizei instances) override;
+ angle::Result drawElementsInstancedBaseVertex(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices,
+ GLsizei instances,
+ GLint baseVertex) override;
+ angle::Result drawElementsInstancedBaseVertexBaseInstance(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices,
+ GLsizei instances,
+ GLint baseVertex,
+ GLuint baseInstance) override;
+ angle::Result drawRangeElements(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices) override;
+ angle::Result drawRangeElementsBaseVertex(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices,
+ GLint baseVertex) override;
+ angle::Result drawArraysIndirect(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const void *indirect) override;
+ angle::Result drawElementsIndirect(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ gl::DrawElementsType type,
+ const void *indirect) override;
+
+ angle::Result multiDrawArrays(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const GLint *firsts,
+ const GLsizei *counts,
+ GLsizei drawcount) override;
+ angle::Result multiDrawArraysInstanced(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const GLint *firsts,
+ const GLsizei *counts,
+ const GLsizei *instanceCounts,
+ GLsizei drawcount) override;
+ angle::Result multiDrawArraysIndirect(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const void *indirect,
+ GLsizei drawcount,
+ GLsizei stride) override;
+ angle::Result multiDrawElements(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const GLsizei *counts,
+ gl::DrawElementsType type,
+ const GLvoid *const *indices,
+ GLsizei drawcount) override;
+ angle::Result multiDrawElementsInstanced(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const GLsizei *counts,
+ gl::DrawElementsType type,
+ const GLvoid *const *indices,
+ const GLsizei *instanceCounts,
+ GLsizei drawcount) override;
+ angle::Result multiDrawElementsIndirect(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ gl::DrawElementsType type,
+ const void *indirect,
+ GLsizei drawcount,
+ GLsizei stride) override;
+ angle::Result multiDrawArraysInstancedBaseInstance(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const GLint *firsts,
+ const GLsizei *counts,
+ const GLsizei *instanceCounts,
+ const GLuint *baseInstances,
+ GLsizei drawcount) override;
+ angle::Result multiDrawElementsInstancedBaseVertexBaseInstance(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const GLsizei *counts,
+ gl::DrawElementsType type,
+ const GLvoid *const *indices,
+ const GLsizei *instanceCounts,
+ const GLint *baseVertices,
+ const GLuint *baseInstances,
+ GLsizei drawcount) override;
+
+ // Device loss
+ gl::GraphicsResetStatus getResetStatus() override;
+
+ // EXT_debug_marker
+ angle::Result insertEventMarker(GLsizei length, const char *marker) override;
+ angle::Result pushGroupMarker(GLsizei length, const char *marker) override;
+ angle::Result popGroupMarker() override;
+
+ // KHR_debug
+ angle::Result pushDebugGroup(const gl::Context *context,
+ GLenum source,
+ GLuint id,
+ const std::string &message) override;
+ angle::Result popDebugGroup(const gl::Context *context) override;
+
+ // State sync with dirty bits.
+ angle::Result syncState(const gl::Context *context,
+ const gl::State::DirtyBits &dirtyBits,
+ const gl::State::DirtyBits &bitMask,
+ gl::Command command) override;
+
+ // Disjoint timer queries
+ GLint getGPUDisjoint() override;
+ GLint64 getTimestamp() override;
+
+ // Context switching
+ angle::Result onMakeCurrent(const gl::Context *context) override;
+
+ // Caps queries
+ gl::Caps getNativeCaps() const override;
+ const gl::TextureCapsMap &getNativeTextureCaps() const override;
+ const gl::Extensions &getNativeExtensions() const override;
+ const gl::Limitations &getNativeLimitations() const override;
+ ShPixelLocalStorageType getNativePixelLocalStorageType() const override;
+
+ Renderer11 *getRenderer() const { return mRenderer; }
+
+ angle::Result dispatchCompute(const gl::Context *context,
+ GLuint numGroupsX,
+ GLuint numGroupsY,
+ GLuint numGroupsZ) override;
+ angle::Result dispatchComputeIndirect(const gl::Context *context, GLintptr indirect) override;
+
+ angle::Result memoryBarrier(const gl::Context *context, GLbitfield barriers) override;
+ angle::Result memoryBarrierByRegion(const gl::Context *context, GLbitfield barriers) override;
+
+ angle::Result triggerDrawCallProgramRecompilation(const gl::Context *context,
+ gl::PrimitiveMode drawMode);
+ angle::Result triggerDispatchCallProgramRecompilation(const gl::Context *context);
+ angle::Result getIncompleteTexture(const gl::Context *context,
+ gl::TextureType type,
+ gl::Texture **textureOut);
+
+ angle::Result initializeMultisampleTextureToBlack(const gl::Context *context,
+ gl::Texture *glTexture) override;
+
+ void handleResult(HRESULT hr,
+ const char *message,
+ const char *file,
+ const char *function,
+ unsigned int line) override;
+
+ private:
+ angle::Result drawElementsImpl(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLsizei indexCount,
+ gl::DrawElementsType indexType,
+ const void *indices,
+ GLsizei instanceCount,
+ GLint baseVertex,
+ GLuint baseInstance,
+ bool promoteDynamic,
+ bool isInstancedDraw);
+
+ Renderer11 *mRenderer;
+ IncompleteTextureSet mIncompleteTextures;
+ std::stack<std::string> mMarkerStack;
+};
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D11_CONTEXT11_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp
new file mode 100644
index 0000000000..2b947d8957
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.cpp
@@ -0,0 +1,148 @@
+//
+// 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.
+//
+// DebugAnnotator11.cpp: D3D11 helpers for adding trace annotations.
+//
+
+#include "libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h"
+
+#include "libANGLE/renderer/d3d/d3d11/Context11.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+
+#include <versionhelpers.h>
+
+#include "common/system_utils.h"
+
+namespace rx
+{
+
+// DebugAnnotator11 implementation
+DebugAnnotator11::DebugAnnotator11() {}
+
+DebugAnnotator11::~DebugAnnotator11() {}
+
+void DebugAnnotator11::beginEvent(gl::Context *context,
+ angle::EntryPoint entryPoint,
+ const char *eventName,
+ const char *eventMessage)
+{
+ angle::LoggingAnnotator::beginEvent(context, entryPoint, eventName, eventMessage);
+ if (!context)
+ {
+ return;
+ }
+ Renderer11 *renderer11 = GetImplAs<Context11>(context)->getRenderer();
+ renderer11->getDebugAnnotatorContext()->beginEvent(entryPoint, eventName, eventMessage);
+}
+
+void DebugAnnotator11::endEvent(gl::Context *context,
+ const char *eventName,
+ angle::EntryPoint entryPoint)
+{
+ angle::LoggingAnnotator::endEvent(context, eventName, entryPoint);
+ if (!context)
+ {
+ return;
+ }
+ Renderer11 *renderer11 = GetImplAs<Context11>(context)->getRenderer();
+ renderer11->getDebugAnnotatorContext()->endEvent(eventName, entryPoint);
+}
+
+void DebugAnnotator11::setMarker(gl::Context *context, const char *markerName)
+{
+ angle::LoggingAnnotator::setMarker(context, markerName);
+ if (!context)
+ {
+ return;
+ }
+ Renderer11 *renderer11 = GetImplAs<Context11>(context)->getRenderer();
+ renderer11->getDebugAnnotatorContext()->setMarker(markerName);
+}
+
+bool DebugAnnotator11::getStatus(const gl::Context *context)
+{
+ if (!context)
+ {
+ return false;
+ }
+ Renderer11 *renderer11 = GetImplAs<Context11>(context)->getRenderer();
+ return renderer11->getDebugAnnotatorContext()->getStatus();
+}
+
+// DebugAnnotatorContext11 implemenetation
+DebugAnnotatorContext11::DebugAnnotatorContext11() = default;
+
+DebugAnnotatorContext11::~DebugAnnotatorContext11() = default;
+
+void DebugAnnotatorContext11::beginEvent(angle::EntryPoint entryPoint,
+ const char *eventName,
+ const char *eventMessage)
+{
+ if (loggingEnabledForThisThread())
+ {
+ std::mbstate_t state = std::mbstate_t();
+ std::mbsrtowcs(mWCharMessage, &eventMessage, kMaxMessageLength, &state);
+ mUserDefinedAnnotation->BeginEvent(mWCharMessage);
+ }
+}
+
+void DebugAnnotatorContext11::endEvent(const char *eventName, angle::EntryPoint entryPoint)
+{
+ if (loggingEnabledForThisThread())
+ {
+ mUserDefinedAnnotation->EndEvent();
+ }
+}
+
+void DebugAnnotatorContext11::setMarker(const char *markerName)
+{
+ if (loggingEnabledForThisThread())
+ {
+ std::mbstate_t state = std::mbstate_t();
+ std::mbsrtowcs(mWCharMessage, &markerName, kMaxMessageLength, &state);
+ mUserDefinedAnnotation->SetMarker(mWCharMessage);
+ }
+}
+
+bool DebugAnnotatorContext11::getStatus() const
+{
+ if (loggingEnabledForThisThread())
+ {
+ return !!(mUserDefinedAnnotation->GetStatus());
+ }
+
+ return false;
+}
+
+bool DebugAnnotatorContext11::loggingEnabledForThisThread() const
+{
+ return mUserDefinedAnnotation != nullptr &&
+ angle::GetCurrentThreadUniqueId() == mAnnotationThread;
+}
+
+void DebugAnnotatorContext11::initialize(ID3D11DeviceContext *context)
+{
+#if !defined(ANGLE_ENABLE_WINDOWS_UWP)
+ // ID3DUserDefinedAnnotation.GetStatus only works on Windows10 or greater.
+ // Returning true unconditionally from DebugAnnotatorContext11::getStatus() means
+ // writing out all compiled shaders to temporary files even if debugging
+ // tools are not attached. See rx::ShaderD3D::prepareSourceAndReturnOptions.
+ // If you want debug annotations, you must use Windows 10.
+ if (IsWindows10OrGreater())
+#endif
+ {
+ mAnnotationThread = angle::GetCurrentThreadUniqueId();
+ mUserDefinedAnnotation.Attach(
+ d3d11::DynamicCastComObject<ID3DUserDefinedAnnotation>(context));
+ }
+}
+
+void DebugAnnotatorContext11::release()
+{
+ mUserDefinedAnnotation.Reset();
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h
new file mode 100644
index 0000000000..0356636762
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h
@@ -0,0 +1,60 @@
+//
+// 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.
+//
+// DebugAnnotator11.h: D3D11 helpers for adding trace annotations.
+//
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_DEBUGANNOTATOR11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_DEBUGANNOTATOR11_H_
+
+#include "libANGLE/LoggingAnnotator.h"
+
+namespace rx
+{
+
+// Note: To avoid any race conditions between threads, this class has no private data;
+// DebugAnnotatorContext11 will be retrieved from Context11.
+class DebugAnnotator11 : public angle::LoggingAnnotator
+{
+ public:
+ DebugAnnotator11();
+ ~DebugAnnotator11() override;
+ void beginEvent(gl::Context *context,
+ angle::EntryPoint entryPoint,
+ const char *eventName,
+ const char *eventMessage) override;
+ void endEvent(gl::Context *context,
+ const char *eventName,
+ angle::EntryPoint entryPoint) override;
+ void setMarker(gl::Context *context, const char *markerName) override;
+ bool getStatus(const gl::Context *context) override;
+};
+
+class DebugAnnotatorContext11
+{
+ public:
+ DebugAnnotatorContext11();
+ ~DebugAnnotatorContext11();
+ void initialize(ID3D11DeviceContext *context);
+ void release();
+ void beginEvent(angle::EntryPoint entryPoint, const char *eventName, const char *eventMessage);
+ void endEvent(const char *eventName, angle::EntryPoint entryPoint);
+ void setMarker(const char *markerName);
+ bool getStatus() const;
+
+ private:
+ bool loggingEnabledForThisThread() const;
+
+ angle::ComPtr<ID3DUserDefinedAnnotation> mUserDefinedAnnotation;
+ static constexpr size_t kMaxMessageLength = 256;
+ wchar_t mWCharMessage[kMaxMessageLength];
+
+ // Only log annotations from the thread used to initialize the debug annotator
+ uint64_t mAnnotationThread;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D11_DEBUGANNOTATOR11_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ExternalImageSiblingImpl11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ExternalImageSiblingImpl11.cpp
new file mode 100644
index 0000000000..ff2fc8056c
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ExternalImageSiblingImpl11.cpp
@@ -0,0 +1,209 @@
+//
+// Copyright 2019 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 "libANGLE/renderer/d3d/d3d11/ExternalImageSiblingImpl11.h"
+
+#include "libANGLE/Context.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/d3d/d3d11/Context11.h"
+#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
+
+namespace rx
+{
+ExternalImageSiblingImpl11::ExternalImageSiblingImpl11(Renderer11 *renderer,
+ EGLClientBuffer buffer,
+ const egl::AttributeMap &attribs)
+ : mRenderer(renderer), mBuffer(buffer), mAttribs(attribs)
+{}
+
+ExternalImageSiblingImpl11::~ExternalImageSiblingImpl11() {}
+
+egl::Error ExternalImageSiblingImpl11::initialize(const egl::Display *display)
+{
+ const angle::Format *angleFormat = nullptr;
+ ANGLE_TRY(mRenderer->getD3DTextureInfo(nullptr, static_cast<IUnknown *>(mBuffer), mAttribs,
+ &mWidth, &mHeight, &mSamples, &mFormat, &angleFormat,
+ &mArraySlice));
+ ID3D11Texture2D *texture =
+ d3d11::DynamicCastComObject<ID3D11Texture2D>(static_cast<IUnknown *>(mBuffer));
+ ASSERT(texture != nullptr);
+ // TextureHelper11 will release texture on destruction.
+ mTexture.set(texture, d3d11::Format::Get(angleFormat->glInternalFormat,
+ mRenderer->getRenderer11DeviceCaps()));
+ D3D11_TEXTURE2D_DESC textureDesc = {};
+ mTexture.getDesc(&textureDesc);
+
+ IDXGIResource *resource = d3d11::DynamicCastComObject<IDXGIResource>(mTexture.get());
+ ASSERT(resource != nullptr);
+ DXGI_USAGE resourceUsage = 0;
+ resource->GetUsage(&resourceUsage);
+ SafeRelease(resource);
+
+ mIsRenderable = (textureDesc.BindFlags & D3D11_BIND_RENDER_TARGET) &&
+ (resourceUsage & DXGI_USAGE_RENDER_TARGET_OUTPUT) &&
+ !(resourceUsage & DXGI_USAGE_READ_ONLY);
+
+ mIsTexturable = (textureDesc.BindFlags & D3D11_BIND_SHADER_RESOURCE) &&
+ (resourceUsage & DXGI_USAGE_SHADER_INPUT);
+
+ mIsTextureArray = (textureDesc.ArraySize > 1);
+
+ return egl::NoError();
+}
+
+gl::Format ExternalImageSiblingImpl11::getFormat() const
+{
+ return mFormat;
+}
+
+bool ExternalImageSiblingImpl11::isRenderable(const gl::Context *context) const
+{
+ return mIsRenderable;
+}
+
+bool ExternalImageSiblingImpl11::isTexturable(const gl::Context *context) const
+{
+ return mIsTexturable;
+}
+
+bool ExternalImageSiblingImpl11::isYUV() const
+{
+ return false;
+}
+
+bool ExternalImageSiblingImpl11::hasProtectedContent() const
+{
+ return false;
+}
+
+gl::Extents ExternalImageSiblingImpl11::getSize() const
+{
+ return gl::Extents(mWidth, mHeight, 1);
+}
+
+size_t ExternalImageSiblingImpl11::getSamples() const
+{
+ return mSamples;
+}
+
+angle::Result ExternalImageSiblingImpl11::getAttachmentRenderTarget(
+ const gl::Context *context,
+ GLenum binding,
+ const gl::ImageIndex &imageIndex,
+ GLsizei samples,
+ FramebufferAttachmentRenderTarget **rtOut)
+{
+ ANGLE_TRY(createRenderTarget(context));
+ *rtOut = mRenderTarget.get();
+ return angle::Result::Continue;
+}
+
+angle::Result ExternalImageSiblingImpl11::initializeContents(const gl::Context *context,
+ GLenum binding,
+ const gl::ImageIndex &imageIndex)
+{
+ UNREACHABLE();
+ return angle::Result::Stop;
+}
+
+angle::Result ExternalImageSiblingImpl11::createRenderTarget(const gl::Context *context)
+{
+ if (mRenderTarget)
+ return angle::Result::Continue;
+
+ Context11 *context11 = GetImplAs<Context11>(context);
+ const d3d11::Format &formatInfo = mTexture.getFormatSet();
+
+ d3d11::RenderTargetView rtv;
+ if (mIsRenderable)
+ {
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = formatInfo.rtvFormat;
+ if (mIsTextureArray)
+ {
+ if (mSamples == 0)
+ {
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
+ rtvDesc.Texture2DArray.MipSlice = 0;
+ rtvDesc.Texture2DArray.FirstArraySlice = mArraySlice;
+ rtvDesc.Texture2DArray.ArraySize = 1;
+ }
+ else
+ {
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY;
+ rtvDesc.Texture2DMSArray.FirstArraySlice = mArraySlice;
+ rtvDesc.Texture2DMSArray.ArraySize = 1;
+ }
+ }
+ else
+ {
+ if (mSamples == 0)
+ {
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
+ rtvDesc.Texture2D.MipSlice = 0;
+ }
+ else
+ {
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS;
+ }
+ }
+
+ ANGLE_TRY(mRenderer->allocateResource(context11, rtvDesc, mTexture.get(), &rtv));
+ rtv.setInternalName("getAttachmentRenderTarget.RTV");
+ }
+
+ d3d11::SharedSRV srv;
+ if (mIsTexturable)
+ {
+ D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+ srvDesc.Format = formatInfo.srvFormat;
+ if (mIsTextureArray)
+ {
+ if (mSamples == 0)
+ {
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
+ srvDesc.Texture2DArray.MostDetailedMip = 0;
+ srvDesc.Texture2DArray.MipLevels = 1;
+ srvDesc.Texture2DArray.FirstArraySlice = mArraySlice;
+ srvDesc.Texture2DArray.ArraySize = 1;
+ }
+ else
+ {
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY;
+ srvDesc.Texture2DArray.FirstArraySlice = mArraySlice;
+ srvDesc.Texture2DArray.ArraySize = 1;
+ }
+ }
+ else
+ {
+ if (mSamples == 0)
+ {
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
+ srvDesc.Texture2D.MostDetailedMip = 0;
+ srvDesc.Texture2D.MipLevels = 1;
+ }
+ else
+ {
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS;
+ }
+ }
+
+ ANGLE_TRY(mRenderer->allocateResource(context11, srvDesc, mTexture.get(), &srv));
+ srv.setInternalName("getAttachmentRenderTarget.SRV");
+ }
+ d3d11::SharedSRV blitSrv = srv.makeCopy();
+
+ mRenderTarget = std::make_unique<TextureRenderTarget11>(
+ std::move(rtv), mTexture, std::move(srv), std::move(blitSrv), mFormat.info->internalFormat,
+ formatInfo, mWidth, mHeight, 1, mSamples);
+ return angle::Result::Continue;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ExternalImageSiblingImpl11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ExternalImageSiblingImpl11.h
new file mode 100644
index 0000000000..3c57120ba2
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ExternalImageSiblingImpl11.h
@@ -0,0 +1,70 @@
+//
+// Copyright 2019 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 LIBANGLE_RENDERER_D3D_D3D11_EXTERNALIMAGESIBLINGIMPL11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_EXTERNALIMAGESIBLINGIMPL11_H_
+
+#include "libANGLE/renderer/ImageImpl.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+
+namespace rx
+{
+
+class Renderer11;
+class RenderTargetD3D;
+
+class ExternalImageSiblingImpl11 : public ExternalImageSiblingImpl
+{
+ public:
+ ExternalImageSiblingImpl11(Renderer11 *renderer,
+ EGLClientBuffer clientBuffer,
+ const egl::AttributeMap &attribs);
+ ~ExternalImageSiblingImpl11() override;
+
+ // ExternalImageSiblingImpl interface
+ egl::Error initialize(const egl::Display *display) override;
+ gl::Format getFormat() const override;
+ bool isRenderable(const gl::Context *context) const override;
+ bool isTexturable(const gl::Context *context) const override;
+ bool isYUV() const override;
+ bool hasProtectedContent() const override;
+ gl::Extents getSize() const override;
+ size_t getSamples() const override;
+
+ // FramebufferAttachmentObjectImpl interface
+ angle::Result getAttachmentRenderTarget(const gl::Context *context,
+ GLenum binding,
+ const gl::ImageIndex &imageIndex,
+ GLsizei samples,
+ FramebufferAttachmentRenderTarget **rtOut) override;
+ angle::Result initializeContents(const gl::Context *context,
+ GLenum binding,
+ const gl::ImageIndex &imageIndex) override;
+
+ private:
+ angle::Result createRenderTarget(const gl::Context *context);
+
+ Renderer11 *mRenderer;
+ EGLClientBuffer mBuffer;
+ egl::AttributeMap mAttribs;
+
+ TextureHelper11 mTexture;
+
+ gl::Format mFormat = gl::Format::Invalid();
+ bool mIsRenderable = false;
+ bool mIsTexturable = false;
+ bool mIsTextureArray = false;
+ EGLint mWidth = 0;
+ EGLint mHeight = 0;
+ GLsizei mSamples = 0;
+ UINT mArraySlice = 0;
+
+ std::unique_ptr<RenderTargetD3D> mRenderTarget;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D11_EXTERNALIMAGESIBLINGIMPL11_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Fence11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Fence11.cpp
new file mode 100644
index 0000000000..38a7331b00
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Fence11.cpp
@@ -0,0 +1,234 @@
+//
+// Copyright 2013 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.
+//
+
+// Fence11.cpp: Defines the rx::FenceNV11 and rx::Sync11 classes which implement
+// rx::FenceNVImpl and rx::SyncImpl.
+
+#include "libANGLE/renderer/d3d/d3d11/Fence11.h"
+
+#include "common/utilities.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/renderer/d3d/d3d11/Context11.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+
+namespace rx
+{
+
+//
+// Template helpers for set and test operations.
+//
+
+template <class FenceClass>
+angle::Result FenceSetHelper(const gl::Context *context, FenceClass *fence)
+{
+ if (!fence->mQuery)
+ {
+ D3D11_QUERY_DESC queryDesc;
+ queryDesc.Query = D3D11_QUERY_EVENT;
+ queryDesc.MiscFlags = 0;
+
+ Context11 *context11 = GetImplAs<Context11>(context);
+ HRESULT result = fence->mRenderer->getDevice()->CreateQuery(&queryDesc, &fence->mQuery);
+ ANGLE_TRY_HR(context11, result, "Failed to create event query");
+ }
+
+ fence->mRenderer->getDeviceContext()->End(fence->mQuery);
+ return angle::Result::Continue;
+}
+
+template <class FenceClass>
+angle::Result FenceTestHelper(const gl::Context *context,
+ FenceClass *fence,
+ bool flushCommandBuffer,
+ GLboolean *outFinished)
+{
+ ASSERT(fence->mQuery);
+
+ UINT getDataFlags = (flushCommandBuffer ? 0 : D3D11_ASYNC_GETDATA_DONOTFLUSH);
+
+ Context11 *context11 = GetImplAs<Context11>(context);
+ HRESULT result =
+ fence->mRenderer->getDeviceContext()->GetData(fence->mQuery, nullptr, 0, getDataFlags);
+ ANGLE_TRY_HR(context11, result, "Failed to get query data");
+
+ ASSERT(result == S_OK || result == S_FALSE);
+ *outFinished = ((result == S_OK) ? GL_TRUE : GL_FALSE);
+ return angle::Result::Continue;
+}
+
+//
+// FenceNV11
+//
+
+FenceNV11::FenceNV11(Renderer11 *renderer) : FenceNVImpl(), mRenderer(renderer), mQuery(nullptr) {}
+
+FenceNV11::~FenceNV11()
+{
+ SafeRelease(mQuery);
+}
+
+angle::Result FenceNV11::set(const gl::Context *context, GLenum condition)
+{
+ return FenceSetHelper(context, this);
+}
+
+angle::Result FenceNV11::test(const gl::Context *context, GLboolean *outFinished)
+{
+ return FenceTestHelper(context, this, true, outFinished);
+}
+
+angle::Result FenceNV11::finish(const gl::Context *context)
+{
+ GLboolean finished = GL_FALSE;
+
+ int loopCount = 0;
+ while (finished != GL_TRUE)
+ {
+ loopCount++;
+ ANGLE_TRY(FenceTestHelper(context, this, true, &finished));
+
+ bool checkDeviceLost = (loopCount % kPollingD3DDeviceLostCheckFrequency) == 0;
+ if (checkDeviceLost && mRenderer->testDeviceLost())
+ {
+ ANGLE_TRY_HR(GetImplAs<Context11>(context), DXGI_ERROR_DRIVER_INTERNAL_ERROR,
+ "Device was lost while querying result of an event query.");
+ }
+
+ ScheduleYield();
+ }
+
+ return angle::Result::Continue;
+}
+
+//
+// Sync11
+//
+
+// Important note on accurate timers in Windows:
+//
+// QueryPerformanceCounter has a few major issues, including being 10x as expensive to call
+// as timeGetTime on laptops and "jumping" during certain hardware events.
+//
+// See the comments at the top of the Chromium source file "chromium/src/base/time/time_win.cc"
+// https://code.google.com/p/chromium/codesearch#chromium/src/base/time/time_win.cc
+//
+// We still opt to use QPC. In the present and moving forward, most newer systems will not suffer
+// from buggy implementations.
+
+Sync11::Sync11(Renderer11 *renderer) : SyncImpl(), mRenderer(renderer), mQuery(nullptr)
+{
+ LARGE_INTEGER counterFreqency = {};
+ BOOL success = QueryPerformanceFrequency(&counterFreqency);
+ ASSERT(success);
+
+ mCounterFrequency = counterFreqency.QuadPart;
+}
+
+Sync11::~Sync11()
+{
+ SafeRelease(mQuery);
+}
+
+angle::Result Sync11::set(const gl::Context *context, GLenum condition, GLbitfield flags)
+{
+ ASSERT(condition == GL_SYNC_GPU_COMMANDS_COMPLETE && flags == 0);
+ return FenceSetHelper(context, this);
+}
+
+angle::Result Sync11::clientWait(const gl::Context *context,
+ GLbitfield flags,
+ GLuint64 timeout,
+ GLenum *outResult)
+{
+ ASSERT(outResult);
+
+ bool flushCommandBuffer = ((flags & GL_SYNC_FLUSH_COMMANDS_BIT) != 0);
+
+ *outResult = GL_WAIT_FAILED;
+
+ GLboolean result = GL_FALSE;
+ ANGLE_TRY(FenceTestHelper(context, this, flushCommandBuffer, &result));
+
+ if (result == GL_TRUE)
+ {
+ *outResult = GL_ALREADY_SIGNALED;
+ return angle::Result::Continue;
+ }
+
+ if (timeout == 0)
+ {
+ *outResult = GL_TIMEOUT_EXPIRED;
+ return angle::Result::Continue;
+ }
+
+ LARGE_INTEGER currentCounter = {};
+ BOOL success = QueryPerformanceCounter(&currentCounter);
+ ASSERT(success);
+
+ LONGLONG timeoutInSeconds = static_cast<LONGLONG>(timeout / 1000000000ull);
+ LONGLONG endCounter = currentCounter.QuadPart + mCounterFrequency * timeoutInSeconds;
+
+ // Extremely unlikely, but if mCounterFrequency is large enough, endCounter can wrap
+ if (endCounter < currentCounter.QuadPart)
+ {
+ endCounter = MAXLONGLONG;
+ }
+
+ int loopCount = 0;
+ while (currentCounter.QuadPart < endCounter && !result)
+ {
+ loopCount++;
+ ScheduleYield();
+ success = QueryPerformanceCounter(&currentCounter);
+ ASSERT(success);
+
+ *outResult = GL_WAIT_FAILED;
+
+ ANGLE_TRY(FenceTestHelper(context, this, flushCommandBuffer, &result));
+
+ bool checkDeviceLost = (loopCount % kPollingD3DDeviceLostCheckFrequency) == 0;
+ if (checkDeviceLost && mRenderer->testDeviceLost())
+ {
+ *outResult = GL_WAIT_FAILED;
+ ANGLE_TRY_HR(GetImplAs<Context11>(context), DXGI_ERROR_DRIVER_INTERNAL_ERROR,
+ "Device was lost while querying result of an event query.");
+ }
+ }
+
+ if (currentCounter.QuadPart >= endCounter)
+ {
+ *outResult = GL_TIMEOUT_EXPIRED;
+ }
+ else
+ {
+ *outResult = GL_CONDITION_SATISFIED;
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result Sync11::serverWait(const gl::Context *context, GLbitfield flags, GLuint64 timeout)
+{
+ // Because our API is currently designed to be called from a single thread, we don't need to do
+ // extra work for a server-side fence. GPU commands issued after the fence is created will
+ // always be processed after the fence is signaled.
+ return angle::Result::Continue;
+}
+
+angle::Result Sync11::getStatus(const gl::Context *context, GLint *outResult)
+{
+ GLboolean result = GL_FALSE;
+
+ // The spec does not specify any way to report errors during the status test (e.g. device
+ // lost) so we report the fence is unblocked in case of error or signaled.
+ *outResult = GL_SIGNALED;
+ ANGLE_TRY(FenceTestHelper(context, this, false, &result));
+
+ *outResult = (result ? GL_SIGNALED : GL_UNSIGNALED);
+ return angle::Result::Continue;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Fence11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Fence11.h
new file mode 100644
index 0000000000..e35ff6b71c
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Fence11.h
@@ -0,0 +1,76 @@
+//
+// Copyright 2013 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.
+//
+
+// Fence11.h: Defines the rx::FenceNV11 and rx::Sync11 classes which implement rx::FenceNVImpl
+// and rx::SyncImpl.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_FENCE11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_FENCE11_H_
+
+#include "libANGLE/renderer/FenceNVImpl.h"
+#include "libANGLE/renderer/SyncImpl.h"
+
+namespace rx
+{
+class Renderer11;
+
+class FenceNV11 : public FenceNVImpl
+{
+ public:
+ explicit FenceNV11(Renderer11 *renderer);
+ ~FenceNV11() override;
+
+ void onDestroy(const gl::Context *context) override {}
+ angle::Result set(const gl::Context *context, GLenum condition) override;
+ angle::Result test(const gl::Context *context, GLboolean *outFinished) override;
+ angle::Result finish(const gl::Context *context) override;
+
+ private:
+ template <class T>
+ friend angle::Result FenceSetHelper(const gl::Context *context, T *fence);
+ template <class T>
+ friend angle::Result FenceTestHelper(const gl::Context *context,
+ T *fence,
+ bool flushCommandBuffer,
+ GLboolean *outFinished);
+
+ Renderer11 *mRenderer;
+ ID3D11Query *mQuery;
+};
+
+class Sync11 : public SyncImpl
+{
+ public:
+ explicit Sync11(Renderer11 *renderer);
+ ~Sync11() override;
+
+ angle::Result set(const gl::Context *context, GLenum condition, GLbitfield flags) override;
+ angle::Result clientWait(const gl::Context *context,
+ GLbitfield flags,
+ GLuint64 timeout,
+ GLenum *outResult) override;
+ angle::Result serverWait(const gl::Context *context,
+ GLbitfield flags,
+ GLuint64 timeout) override;
+ angle::Result getStatus(const gl::Context *context, GLint *outResult) override;
+
+ private:
+ template <class T>
+ friend angle::Result FenceSetHelper(const gl::Context *context, T *fence);
+ template <class T>
+ friend angle::Result FenceTestHelper(const gl::Context *context,
+ T *fence,
+ bool flushCommandBuffer,
+ GLboolean *outFinished);
+
+ Renderer11 *mRenderer;
+ ID3D11Query *mQuery;
+ LONGLONG mCounterFrequency;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D11_FENCE11_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp
new file mode 100644
index 0000000000..e6516ff521
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp
@@ -0,0 +1,452 @@
+//
+// 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.
+//
+
+// Framebuffer11.cpp: Implements the Framebuffer11 class.
+
+#include "libANGLE/renderer/d3d/d3d11/Framebuffer11.h"
+
+#include "common/bitset_utils.h"
+#include "common/debug.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/Texture.h"
+#include "libANGLE/renderer/d3d/TextureD3D.h"
+#include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
+#include "libANGLE/renderer/d3d/d3d11/Clear11.h"
+#include "libANGLE/renderer/d3d/d3d11/Context11.h"
+#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h"
+#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+
+using namespace angle;
+
+namespace rx
+{
+
+namespace
+{
+angle::Result MarkAttachmentsDirty(const gl::Context *context,
+ const gl::FramebufferAttachment *attachment)
+{
+ if (attachment->type() == GL_TEXTURE)
+ {
+ gl::Texture *texture = attachment->getTexture();
+
+ TextureD3D *textureD3D = GetImplAs<TextureD3D>(texture);
+
+ TextureStorage *texStorage = nullptr;
+ ANGLE_TRY(textureD3D->getNativeTexture(context, &texStorage));
+
+ if (texStorage)
+ {
+ TextureStorage11 *texStorage11 = GetAs<TextureStorage11>(texStorage);
+ ASSERT(texStorage11);
+
+ texStorage11->markLevelDirty(attachment->mipLevel());
+ }
+ }
+
+ return angle::Result::Continue;
+}
+
+UINT GetAttachmentLayer(const gl::FramebufferAttachment *attachment)
+{
+ if (attachment->type() == GL_TEXTURE &&
+ attachment->getTexture()->getType() == gl::TextureType::_3D)
+ {
+ return attachment->layer();
+ }
+ return 0;
+}
+
+} // anonymous namespace
+
+Framebuffer11::Framebuffer11(const gl::FramebufferState &data, Renderer11 *renderer)
+ : FramebufferD3D(data, renderer), mRenderer(renderer)
+{
+ ASSERT(mRenderer != nullptr);
+}
+
+Framebuffer11::~Framebuffer11() {}
+
+angle::Result Framebuffer11::markAttachmentsDirty(const gl::Context *context) const
+{
+ const auto &colorAttachments = mState.getColorAttachments();
+ for (size_t drawBuffer : mState.getEnabledDrawBuffers())
+ {
+ const gl::FramebufferAttachment &colorAttachment = colorAttachments[drawBuffer];
+ ASSERT(colorAttachment.isAttached());
+ ANGLE_TRY(MarkAttachmentsDirty(context, &colorAttachment));
+ }
+
+ const gl::FramebufferAttachment *dsAttachment = mState.getDepthOrStencilAttachment();
+ if (dsAttachment)
+ {
+ ANGLE_TRY(MarkAttachmentsDirty(context, dsAttachment));
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result Framebuffer11::clearImpl(const gl::Context *context,
+ const ClearParameters &clearParams)
+{
+ Clear11 *clearer = mRenderer->getClearer();
+
+ const gl::FramebufferAttachment *colorAttachment = mState.getFirstColorAttachment();
+ if (clearParams.scissorEnabled == true && colorAttachment != nullptr &&
+ UsePresentPathFast(mRenderer, colorAttachment))
+ {
+ // If the current framebuffer is using the default colorbuffer, and present path fast is
+ // active, and the scissor rect is enabled, then we should invert the scissor rect
+ // vertically
+ ClearParameters presentPathFastClearParams = clearParams;
+ gl::Extents framebufferSize = colorAttachment->getSize();
+ presentPathFastClearParams.scissor.y = framebufferSize.height -
+ presentPathFastClearParams.scissor.y -
+ presentPathFastClearParams.scissor.height;
+ ANGLE_TRY(clearer->clearFramebuffer(context, presentPathFastClearParams, mState));
+ }
+ else
+ {
+ ANGLE_TRY(clearer->clearFramebuffer(context, clearParams, mState));
+ }
+
+ ANGLE_TRY(markAttachmentsDirty(context));
+
+ return angle::Result::Continue;
+}
+
+angle::Result Framebuffer11::invalidate(const gl::Context *context,
+ size_t count,
+ const GLenum *attachments)
+{
+ return invalidateBase(context, count, attachments, false);
+}
+
+angle::Result Framebuffer11::discard(const gl::Context *context,
+ size_t count,
+ const GLenum *attachments)
+{
+ return invalidateBase(context, count, attachments, true);
+}
+
+angle::Result Framebuffer11::invalidateBase(const gl::Context *context,
+ size_t count,
+ const GLenum *attachments,
+ bool useEXTBehavior) const
+{
+ ID3D11DeviceContext1 *deviceContext1 = mRenderer->getDeviceContext1IfSupported();
+
+ if (!deviceContext1)
+ {
+ // DiscardView() is only supported on ID3D11DeviceContext1
+ return angle::Result::Continue;
+ }
+
+ bool foundDepth = false;
+ bool foundStencil = false;
+
+ for (size_t i = 0; i < count; ++i)
+ {
+ switch (attachments[i])
+ {
+ // Handle depth and stencil attachments. Defer discarding until later.
+ case GL_DEPTH_STENCIL_ATTACHMENT:
+ foundDepth = true;
+ foundStencil = true;
+ break;
+ case GL_DEPTH_EXT:
+ case GL_DEPTH_ATTACHMENT:
+ foundDepth = true;
+ break;
+ case GL_STENCIL_EXT:
+ case GL_STENCIL_ATTACHMENT:
+ foundStencil = true;
+ break;
+ default:
+ {
+ // Handle color attachments
+ ASSERT((attachments[i] >= GL_COLOR_ATTACHMENT0 &&
+ attachments[i] <= GL_COLOR_ATTACHMENT15) ||
+ (attachments[i] == GL_COLOR));
+
+ size_t colorIndex =
+ (attachments[i] == GL_COLOR ? 0u : (attachments[i] - GL_COLOR_ATTACHMENT0));
+ const gl::FramebufferAttachment *colorAttachment =
+ mState.getColorAttachment(colorIndex);
+ if (colorAttachment)
+ {
+ ANGLE_TRY(invalidateAttachment(context, colorAttachment));
+ }
+ break;
+ }
+ }
+ }
+
+ bool discardDepth = false;
+ bool discardStencil = false;
+
+ // The D3D11 renderer uses the same view for depth and stencil buffers, so we must be careful.
+ if (useEXTBehavior)
+ {
+ // In the extension, if the app discards only one of the depth and stencil attachments, but
+ // those are backed by the same packed_depth_stencil buffer, then both images become
+ // undefined.
+ discardDepth = foundDepth;
+
+ // Don't bother discarding the stencil buffer if the depth buffer will already do it
+ discardStencil = foundStencil && (!discardDepth || mState.getDepthAttachment() == nullptr);
+ }
+ else
+ {
+ // In ES 3.0.4, if a specified attachment has base internal format DEPTH_STENCIL but the
+ // attachments list does not include DEPTH_STENCIL_ATTACHMENT or both DEPTH_ATTACHMENT and
+ // STENCIL_ATTACHMENT, then only the specified portion of every pixel in the subregion of
+ // pixels of the DEPTH_STENCIL buffer may be invalidated, and the other portion must be
+ // preserved.
+ discardDepth = (foundDepth && foundStencil) ||
+ (foundDepth && (mState.getStencilAttachment() == nullptr));
+ discardStencil = (foundStencil && (mState.getDepthAttachment() == nullptr));
+ }
+
+ if (discardDepth && mState.getDepthAttachment())
+ {
+ ANGLE_TRY(invalidateAttachment(context, mState.getDepthAttachment()));
+ }
+
+ if (discardStencil && mState.getStencilAttachment())
+ {
+ ANGLE_TRY(invalidateAttachment(context, mState.getStencilAttachment()));
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result Framebuffer11::invalidateSub(const gl::Context *context,
+ size_t count,
+ const GLenum *attachments,
+ const gl::Rectangle &area)
+{
+ // A no-op implementation conforms to the spec, so don't call UNIMPLEMENTED()
+ return angle::Result::Continue;
+}
+
+angle::Result Framebuffer11::invalidateAttachment(const gl::Context *context,
+ const gl::FramebufferAttachment *attachment) const
+{
+ ID3D11DeviceContext1 *deviceContext1 = mRenderer->getDeviceContext1IfSupported();
+ ASSERT(deviceContext1);
+ ASSERT(attachment && attachment->isAttached());
+
+ RenderTarget11 *renderTarget = nullptr;
+ ANGLE_TRY(attachment->getRenderTarget(context, 0, &renderTarget));
+ const auto &rtv = renderTarget->getRenderTargetView();
+
+ if (rtv.valid())
+ {
+ deviceContext1->DiscardView(rtv.get());
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result Framebuffer11::readPixelsImpl(const gl::Context *context,
+ const gl::Rectangle &area,
+ GLenum format,
+ GLenum type,
+ size_t outputPitch,
+ const gl::PixelPackState &pack,
+ gl::Buffer *packBuffer,
+ uint8_t *pixels)
+{
+ const gl::FramebufferAttachment *readAttachment = mState.getReadPixelsAttachment(format);
+ ASSERT(readAttachment);
+
+ if (packBuffer != nullptr)
+ {
+ Buffer11 *packBufferStorage = GetImplAs<Buffer11>(packBuffer);
+ const angle::Format &angleFormat = GetFormatFromFormatType(format, type);
+ PackPixelsParams packParams(area, angleFormat, static_cast<GLuint>(outputPitch),
+ pack.reverseRowOrder, packBuffer,
+ reinterpret_cast<ptrdiff_t>(pixels));
+
+ return packBufferStorage->packPixels(context, *readAttachment, packParams);
+ }
+
+ return mRenderer->readFromAttachment(context, *readAttachment, area, format, type,
+ static_cast<GLuint>(outputPitch), pack, pixels);
+}
+
+angle::Result Framebuffer11::blitImpl(const gl::Context *context,
+ const gl::Rectangle &sourceArea,
+ const gl::Rectangle &destArea,
+ const gl::Rectangle *scissor,
+ bool blitRenderTarget,
+ bool blitDepth,
+ bool blitStencil,
+ GLenum filter,
+ const gl::Framebuffer *sourceFramebuffer)
+{
+ if (blitRenderTarget)
+ {
+ const gl::FramebufferAttachment *readBuffer = sourceFramebuffer->getReadColorAttachment();
+ ASSERT(readBuffer);
+
+ RenderTargetD3D *readRenderTarget = nullptr;
+ ANGLE_TRY(readBuffer->getRenderTarget(context, 0, &readRenderTarget));
+ ASSERT(readRenderTarget);
+
+ const auto &colorAttachments = mState.getColorAttachments();
+ const auto &drawBufferStates = mState.getDrawBufferStates();
+ UINT readLayer = GetAttachmentLayer(readBuffer);
+
+ for (size_t colorAttachment = 0; colorAttachment < colorAttachments.size();
+ colorAttachment++)
+ {
+ const gl::FramebufferAttachment &drawBuffer = colorAttachments[colorAttachment];
+
+ if (drawBuffer.isAttached() && drawBufferStates[colorAttachment] != GL_NONE)
+ {
+ RenderTargetD3D *drawRenderTarget = nullptr;
+ ANGLE_TRY(drawBuffer.getRenderTarget(
+ context, drawBuffer.getRenderToTextureSamples(), &drawRenderTarget));
+ ASSERT(drawRenderTarget);
+
+ const bool invertColorSource = UsePresentPathFast(mRenderer, readBuffer);
+ gl::Rectangle actualSourceArea = sourceArea;
+ if (invertColorSource)
+ {
+ RenderTarget11 *readRenderTarget11 = GetAs<RenderTarget11>(readRenderTarget);
+ actualSourceArea.y = readRenderTarget11->getHeight() - sourceArea.y;
+ actualSourceArea.height = -sourceArea.height;
+ }
+
+ const bool invertColorDest = UsePresentPathFast(mRenderer, &drawBuffer);
+ gl::Rectangle actualDestArea = destArea;
+ UINT drawLayer = GetAttachmentLayer(&drawBuffer);
+
+ const auto &surfaceTextureOffset = mState.getSurfaceTextureOffset();
+ actualDestArea.x = actualDestArea.x + surfaceTextureOffset.x;
+ actualDestArea.y = actualDestArea.y + surfaceTextureOffset.y;
+
+ if (invertColorDest)
+ {
+ RenderTarget11 *drawRenderTarget11 = GetAs<RenderTarget11>(drawRenderTarget);
+ actualDestArea.y = drawRenderTarget11->getHeight() - destArea.y;
+ actualDestArea.height = -destArea.height;
+ }
+
+ ANGLE_TRY(mRenderer->blitRenderbufferRect(context, actualSourceArea, actualDestArea,
+ readLayer, drawLayer, readRenderTarget,
+ drawRenderTarget, filter, scissor,
+ blitRenderTarget, false, false));
+ }
+ }
+ }
+
+ if (blitDepth || blitStencil)
+ {
+ const gl::FramebufferAttachment *readBuffer =
+ sourceFramebuffer->getDepthOrStencilAttachment();
+ ASSERT(readBuffer);
+ RenderTargetD3D *readRenderTarget = nullptr;
+ ANGLE_TRY(readBuffer->getRenderTarget(context, 0, &readRenderTarget));
+ ASSERT(readRenderTarget);
+
+ const bool invertSource = UsePresentPathFast(mRenderer, readBuffer);
+ gl::Rectangle actualSourceArea = sourceArea;
+ if (invertSource)
+ {
+ RenderTarget11 *readRenderTarget11 = GetAs<RenderTarget11>(readRenderTarget);
+ actualSourceArea.y = readRenderTarget11->getHeight() - sourceArea.y;
+ actualSourceArea.height = -sourceArea.height;
+ }
+
+ const gl::FramebufferAttachment *drawBuffer = mState.getDepthOrStencilAttachment();
+ ASSERT(drawBuffer);
+ RenderTargetD3D *drawRenderTarget = nullptr;
+ ANGLE_TRY(drawBuffer->getRenderTarget(context, drawBuffer->getRenderToTextureSamples(),
+ &drawRenderTarget));
+ ASSERT(drawRenderTarget);
+
+ bool invertDest = UsePresentPathFast(mRenderer, drawBuffer);
+ gl::Rectangle actualDestArea = destArea;
+ if (invertDest)
+ {
+ RenderTarget11 *drawRenderTarget11 = GetAs<RenderTarget11>(drawRenderTarget);
+ actualDestArea.y = drawRenderTarget11->getHeight() - destArea.y;
+ actualDestArea.height = -destArea.height;
+ }
+
+ ANGLE_TRY(mRenderer->blitRenderbufferRect(context, actualSourceArea, actualDestArea, 0, 0,
+ readRenderTarget, drawRenderTarget, filter,
+ scissor, false, blitDepth, blitStencil));
+ }
+
+ ANGLE_TRY(markAttachmentsDirty(context));
+ return angle::Result::Continue;
+}
+
+const gl::InternalFormat &Framebuffer11::getImplementationColorReadFormat(
+ const gl::Context *context) const
+{
+ Context11 *context11 = GetImplAs<Context11>(context);
+ const Renderer11DeviceCaps &caps = context11->getRenderer()->getRenderer11DeviceCaps();
+ GLenum sizedFormat = mState.getReadAttachment()->getFormat().info->sizedInternalFormat;
+ const angle::Format &angleFormat = d3d11::Format::Get(sizedFormat, caps).format();
+ return gl::GetSizedInternalFormatInfo(angleFormat.fboImplementationInternalFormat);
+}
+
+angle::Result Framebuffer11::syncState(const gl::Context *context,
+ GLenum binding,
+ const gl::Framebuffer::DirtyBits &dirtyBits,
+ gl::Command command)
+{
+ ANGLE_TRY(mRenderTargetCache.update(context, mState, dirtyBits));
+ ANGLE_TRY(FramebufferD3D::syncState(context, binding, dirtyBits, command));
+
+ // Call this last to allow the state manager to take advantage of the cached render targets.
+ mRenderer->getStateManager()->invalidateRenderTarget();
+
+ // Call this to syncViewport for framebuffer default parameters.
+ if (mState.getDefaultWidth() != 0 || mState.getDefaultHeight() != 0)
+ {
+ mRenderer->getStateManager()->invalidateViewport(context);
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result Framebuffer11::getSamplePosition(const gl::Context *context,
+ size_t index,
+ GLfloat *xy) const
+{
+ const gl::FramebufferAttachment *attachment = mState.getFirstNonNullAttachment();
+ ASSERT(attachment);
+ GLsizei sampleCount = attachment->getSamples();
+
+ rx::GetSamplePosition(sampleCount, index, xy);
+ return angle::Result::Continue;
+}
+
+RenderTarget11 *Framebuffer11::getFirstRenderTarget() const
+{
+ for (auto *renderTarget : mRenderTargetCache.getColors())
+ {
+ if (renderTarget)
+ {
+ return renderTarget;
+ }
+ }
+
+ return mRenderTargetCache.getDepthStencil();
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h
new file mode 100644
index 0000000000..34cfdbd30e
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h
@@ -0,0 +1,100 @@
+//
+// 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.
+//
+
+// Framebuffer11.h: Defines the Framebuffer11 class.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_FRAMBUFFER11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_FRAMBUFFER11_H_
+
+#include "libANGLE/Observer.h"
+#include "libANGLE/renderer/RenderTargetCache.h"
+#include "libANGLE/renderer/d3d/FramebufferD3D.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+
+namespace rx
+{
+class Renderer11;
+
+class Framebuffer11 : public FramebufferD3D
+{
+ public:
+ Framebuffer11(const gl::FramebufferState &data, Renderer11 *renderer);
+ ~Framebuffer11() override;
+
+ angle::Result discard(const gl::Context *context,
+ size_t count,
+ const GLenum *attachments) override;
+ angle::Result invalidate(const gl::Context *context,
+ size_t count,
+ const GLenum *attachments) override;
+ angle::Result invalidateSub(const gl::Context *context,
+ size_t count,
+ const GLenum *attachments,
+ const gl::Rectangle &area) override;
+
+ // Invalidate the cached swizzles of all bound texture attachments.
+ angle::Result markAttachmentsDirty(const gl::Context *context) const;
+
+ angle::Result syncState(const gl::Context *context,
+ GLenum binding,
+ const gl::Framebuffer::DirtyBits &dirtyBits,
+ gl::Command command) override;
+
+ const gl::AttachmentArray<RenderTarget11 *> &getCachedColorRenderTargets() const
+ {
+ return mRenderTargetCache.getColors();
+ }
+ const RenderTarget11 *getCachedDepthStencilRenderTarget() const
+ {
+ return mRenderTargetCache.getDepthStencil();
+ }
+
+ RenderTarget11 *getFirstRenderTarget() const;
+
+ angle::Result getSamplePosition(const gl::Context *context,
+ size_t index,
+ GLfloat *xy) const override;
+
+ const gl::InternalFormat &getImplementationColorReadFormat(
+ const gl::Context *context) const override;
+
+ private:
+ angle::Result clearImpl(const gl::Context *context,
+ const ClearParameters &clearParams) override;
+
+ angle::Result readPixelsImpl(const gl::Context *context,
+ const gl::Rectangle &area,
+ GLenum format,
+ GLenum type,
+ size_t outputPitch,
+ const gl::PixelPackState &pack,
+ gl::Buffer *packBuffer,
+ uint8_t *pixels) override;
+
+ angle::Result blitImpl(const gl::Context *context,
+ const gl::Rectangle &sourceArea,
+ const gl::Rectangle &destArea,
+ const gl::Rectangle *scissor,
+ bool blitRenderTarget,
+ bool blitDepth,
+ bool blitStencil,
+ GLenum filter,
+ const gl::Framebuffer *sourceFramebuffer) override;
+
+ angle::Result invalidateBase(const gl::Context *context,
+ size_t count,
+ const GLenum *attachments,
+ bool useEXTBehavior) const;
+ angle::Result invalidateAttachment(const gl::Context *context,
+ const gl::FramebufferAttachment *attachment) const;
+
+ Renderer11 *const mRenderer;
+ RenderTargetCache<RenderTarget11> mRenderTargetCache;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D11_FRAMBUFFER11_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Image11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Image11.cpp
new file mode 100644
index 0000000000..2e6558b304
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Image11.cpp
@@ -0,0 +1,676 @@
+//
+// Copyright 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.
+//
+
+// Image11.h: Implements the rx::Image11 class, which acts as the interface to
+// the actual underlying resources of a Texture
+
+#include "libANGLE/renderer/d3d/d3d11/Image11.h"
+
+#include "common/utilities.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/d3d/d3d11/Context11.h"
+#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h"
+#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
+
+namespace rx
+{
+
+Image11::Image11(Renderer11 *renderer)
+ : mRenderer(renderer),
+ mDXGIFormat(DXGI_FORMAT_UNKNOWN),
+ mStagingTexture(),
+ mStagingSubresource(0),
+ mRecoverFromStorage(false),
+ mAssociatedStorage(nullptr),
+ mAssociatedImageIndex(),
+ mRecoveredFromStorageCount(0)
+{}
+
+Image11::~Image11()
+{
+ disassociateStorage();
+ releaseStagingTexture();
+}
+
+// static
+angle::Result Image11::GenerateMipmap(const gl::Context *context,
+ Image11 *dest,
+ Image11 *src,
+ const Renderer11DeviceCaps &rendererCaps)
+{
+ ASSERT(src->getDXGIFormat() == dest->getDXGIFormat());
+ ASSERT(src->getWidth() == 1 || src->getWidth() / 2 == dest->getWidth());
+ ASSERT(src->getHeight() == 1 || src->getHeight() / 2 == dest->getHeight());
+
+ D3D11_MAPPED_SUBRESOURCE destMapped;
+ ANGLE_TRY(dest->map(context, D3D11_MAP_WRITE, &destMapped));
+ d3d11::ScopedUnmapper<Image11> destRAII(dest);
+
+ D3D11_MAPPED_SUBRESOURCE srcMapped;
+ ANGLE_TRY(src->map(context, D3D11_MAP_READ, &srcMapped));
+ d3d11::ScopedUnmapper<Image11> srcRAII(src);
+
+ const uint8_t *sourceData = static_cast<const uint8_t *>(srcMapped.pData);
+ uint8_t *destData = static_cast<uint8_t *>(destMapped.pData);
+
+ 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);
+
+ dest->markDirty();
+
+ return angle::Result::Continue;
+}
+
+// static
+angle::Result Image11::CopyImage(const gl::Context *context,
+ Image11 *dest,
+ Image11 *source,
+ const gl::Box &sourceBox,
+ const gl::Offset &destOffset,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha,
+ const Renderer11DeviceCaps &rendererCaps)
+{
+ D3D11_MAPPED_SUBRESOURCE destMapped;
+ ANGLE_TRY(dest->map(context, D3D11_MAP_WRITE, &destMapped));
+ d3d11::ScopedUnmapper<Image11> destRAII(dest);
+
+ D3D11_MAPPED_SUBRESOURCE srcMapped;
+ ANGLE_TRY(source->map(context, D3D11_MAP_READ, &srcMapped));
+ d3d11::ScopedUnmapper<Image11> sourceRAII(source);
+
+ const auto &sourceFormat =
+ d3d11::Format::Get(source->getInternalFormat(), rendererCaps).format();
+ GLuint sourcePixelBytes =
+ gl::GetSizedInternalFormatInfo(sourceFormat.fboImplementationInternalFormat).pixelBytes;
+
+ GLenum destUnsizedFormat = gl::GetUnsizedFormat(dest->getInternalFormat());
+ const auto &destFormat = d3d11::Format::Get(dest->getInternalFormat(), rendererCaps).format();
+ const auto &destFormatInfo =
+ gl::GetSizedInternalFormatInfo(destFormat.fboImplementationInternalFormat);
+ GLuint destPixelBytes = destFormatInfo.pixelBytes;
+
+ const uint8_t *sourceData = static_cast<const uint8_t *>(srcMapped.pData) +
+ sourceBox.x * sourcePixelBytes + sourceBox.y * srcMapped.RowPitch +
+ sourceBox.z * srcMapped.DepthPitch;
+ uint8_t *destData = static_cast<uint8_t *>(destMapped.pData) + destOffset.x * destPixelBytes +
+ destOffset.y * destMapped.RowPitch + destOffset.z * destMapped.DepthPitch;
+
+ CopyImageCHROMIUM(sourceData, srcMapped.RowPitch, sourcePixelBytes, srcMapped.DepthPitch,
+ sourceFormat.pixelReadFunction, destData, destMapped.RowPitch, destPixelBytes,
+ destMapped.DepthPitch, destFormat.pixelWriteFunction, destUnsizedFormat,
+ destFormatInfo.componentType, sourceBox.width, sourceBox.height,
+ sourceBox.depth, unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha);
+
+ dest->markDirty();
+
+ return angle::Result::Continue;
+}
+
+bool Image11::isDirty() const
+{
+ // If mDirty is true AND mStagingTexture doesn't exist AND mStagingTexture doesn't need to be
+ // recovered from TextureStorage AND the texture doesn't require init data (i.e. a blank new
+ // texture will suffice) AND robust resource initialization is not enabled then isDirty should
+ // still return false.
+ if (mDirty && !mStagingTexture.valid() && !mRecoverFromStorage)
+ {
+ const Renderer11DeviceCaps &deviceCaps = mRenderer->getRenderer11DeviceCaps();
+ const auto &formatInfo = d3d11::Format::Get(mInternalFormat, deviceCaps);
+ if (formatInfo.dataInitializerFunction == nullptr)
+ {
+ return false;
+ }
+ }
+
+ return mDirty;
+}
+
+angle::Result Image11::copyToStorage(const gl::Context *context,
+ TextureStorage *storage,
+ const gl::ImageIndex &index,
+ const gl::Box &region)
+{
+ TextureStorage11 *storage11 = GetAs<TextureStorage11>(storage);
+
+ // If an app's behavior results in an Image11 copying its data to/from to a TextureStorage
+ // multiple times, then we should just keep the staging texture around to prevent the copying
+ // from impacting perf. We allow the Image11 to copy its data to/from TextureStorage once. This
+ // accounts for an app making a late call to glGenerateMipmap.
+ bool attemptToReleaseStagingTexture = (mRecoveredFromStorageCount < 2);
+
+ if (attemptToReleaseStagingTexture)
+ {
+ // If another image is relying on this Storage for its data, then we must let it recover its
+ // data before we overwrite it.
+ ANGLE_TRY(storage11->releaseAssociatedImage(context, index, this));
+ }
+
+ const TextureHelper11 *stagingTexture = nullptr;
+ unsigned int stagingSubresourceIndex = 0;
+ ANGLE_TRY(getStagingTexture(context, &stagingTexture, &stagingSubresourceIndex));
+ ANGLE_TRY(storage11->updateSubresourceLevel(context, *stagingTexture, stagingSubresourceIndex,
+ index, region));
+
+ // Once the image data has been copied into the Storage, we can release it locally.
+ if (attemptToReleaseStagingTexture)
+ {
+ storage11->associateImage(this, index);
+ releaseStagingTexture();
+ mRecoverFromStorage = true;
+ mAssociatedStorage = storage11;
+ mAssociatedImageIndex = index;
+ }
+
+ return angle::Result::Continue;
+}
+
+void Image11::verifyAssociatedStorageValid(TextureStorage11 *textureStorageEXT) const
+{
+ ASSERT(mAssociatedStorage == textureStorageEXT);
+}
+
+angle::Result Image11::recoverFromAssociatedStorage(const gl::Context *context)
+{
+ if (mRecoverFromStorage)
+ {
+ ANGLE_TRY(createStagingTexture(context));
+
+ mAssociatedStorage->verifyAssociatedImageValid(mAssociatedImageIndex, this);
+
+ // CopySubResource from the Storage to the Staging texture
+ gl::Box region(0, 0, 0, mWidth, mHeight, mDepth);
+ ANGLE_TRY(mAssociatedStorage->copySubresourceLevel(
+ context, mStagingTexture, mStagingSubresource, mAssociatedImageIndex, region));
+ mRecoveredFromStorageCount += 1;
+
+ // Reset all the recovery parameters, even if the texture storage association is broken.
+ disassociateStorage();
+
+ markDirty();
+ }
+
+ return angle::Result::Continue;
+}
+
+void Image11::disassociateStorage()
+{
+ if (mRecoverFromStorage)
+ {
+ // Make the texturestorage release the Image11 too
+ mAssociatedStorage->disassociateImage(mAssociatedImageIndex, this);
+
+ mRecoverFromStorage = false;
+ mAssociatedStorage = nullptr;
+ mAssociatedImageIndex = gl::ImageIndex();
+ }
+}
+
+bool Image11::redefine(gl::TextureType type,
+ GLenum internalformat,
+ const gl::Extents &size,
+ bool forceRelease)
+{
+ if (mWidth != size.width || mHeight != size.height || mDepth != size.depth ||
+ mInternalFormat != internalformat || forceRelease)
+ {
+ // End the association with the TextureStorage, since that data will be out of date.
+ // Also reset mRecoveredFromStorageCount since this Image is getting completely redefined.
+ disassociateStorage();
+ mRecoveredFromStorageCount = 0;
+
+ mWidth = size.width;
+ mHeight = size.height;
+ mDepth = size.depth;
+ mInternalFormat = internalformat;
+ mType = type;
+
+ // compute the d3d format that will be used
+ const d3d11::Format &formatInfo =
+ d3d11::Format::Get(internalformat, mRenderer->getRenderer11DeviceCaps());
+ mDXGIFormat = formatInfo.texFormat;
+ mRenderable = (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN);
+
+ releaseStagingTexture();
+ mDirty = (formatInfo.dataInitializerFunction != nullptr);
+
+ return true;
+ }
+
+ return false;
+}
+
+DXGI_FORMAT Image11::getDXGIFormat() const
+{
+ // this should only happen if the image hasn't been redefined first
+ // which would be a bug by the caller
+ ASSERT(mDXGIFormat != DXGI_FORMAT_UNKNOWN);
+
+ return mDXGIFormat;
+}
+
+// Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as
+// format/type at input
+// into the target pixel rectangle.
+angle::Result Image11::loadData(const gl::Context *context,
+ const gl::Box &area,
+ const gl::PixelUnpackState &unpack,
+ GLenum type,
+ const void *input,
+ bool applySkipImages)
+{
+ Context11 *context11 = GetImplAs<Context11>(context);
+
+ const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(mInternalFormat);
+ GLuint inputRowPitch = 0;
+ ANGLE_CHECK_GL_MATH(context11, formatInfo.computeRowPitch(type, area.width, unpack.alignment,
+ unpack.rowLength, &inputRowPitch));
+ GLuint inputDepthPitch = 0;
+ ANGLE_CHECK_GL_MATH(context11, formatInfo.computeDepthPitch(area.height, unpack.imageHeight,
+ inputRowPitch, &inputDepthPitch));
+ GLuint inputSkipBytes = 0;
+ ANGLE_CHECK_GL_MATH(context11,
+ formatInfo.computeSkipBytes(type, inputRowPitch, inputDepthPitch, unpack,
+ applySkipImages, &inputSkipBytes));
+
+ const d3d11::DXGIFormatSize &dxgiFormatInfo = d3d11::GetDXGIFormatSizeInfo(mDXGIFormat);
+ GLuint outputPixelSize = dxgiFormatInfo.pixelBytes;
+
+ const d3d11::Format &d3dFormatInfo =
+ d3d11::Format::Get(mInternalFormat, mRenderer->getRenderer11DeviceCaps());
+ LoadImageFunction loadFunction = d3dFormatInfo.getLoadFunctions()(type).loadFunction;
+
+ D3D11_MAPPED_SUBRESOURCE mappedImage;
+ ANGLE_TRY(map(context, D3D11_MAP_WRITE, &mappedImage));
+
+ uint8_t *offsetMappedData = (static_cast<uint8_t *>(mappedImage.pData) +
+ (area.y * mappedImage.RowPitch + area.x * outputPixelSize +
+ area.z * mappedImage.DepthPitch));
+ loadFunction(area.width, area.height, area.depth,
+ static_cast<const uint8_t *>(input) + inputSkipBytes, inputRowPitch,
+ inputDepthPitch, offsetMappedData, mappedImage.RowPitch, mappedImage.DepthPitch);
+
+ unmap();
+
+ return angle::Result::Continue;
+}
+
+angle::Result Image11::loadCompressedData(const gl::Context *context,
+ const gl::Box &area,
+ const void *input)
+{
+ Context11 *context11 = GetImplAs<Context11>(context);
+
+ const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(mInternalFormat);
+ GLuint inputRowPitch = 0;
+ ANGLE_CHECK_GL_MATH(
+ context11, formatInfo.computeRowPitch(GL_UNSIGNED_BYTE, area.width, 1, 0, &inputRowPitch));
+ GLuint inputDepthPitch = 0;
+ ANGLE_CHECK_GL_MATH(
+ context11, formatInfo.computeDepthPitch(area.height, 0, inputRowPitch, &inputDepthPitch));
+
+ const d3d11::DXGIFormatSize &dxgiFormatInfo = d3d11::GetDXGIFormatSizeInfo(mDXGIFormat);
+ GLuint outputPixelSize = dxgiFormatInfo.pixelBytes;
+ GLuint outputBlockWidth = dxgiFormatInfo.blockWidth;
+ GLuint outputBlockHeight = dxgiFormatInfo.blockHeight;
+
+ ASSERT(area.x % outputBlockWidth == 0);
+ ASSERT(area.y % outputBlockHeight == 0);
+
+ const d3d11::Format &d3dFormatInfo =
+ d3d11::Format::Get(mInternalFormat, mRenderer->getRenderer11DeviceCaps());
+ LoadImageFunction loadFunction =
+ d3dFormatInfo.getLoadFunctions()(GL_UNSIGNED_BYTE).loadFunction;
+
+ D3D11_MAPPED_SUBRESOURCE mappedImage;
+ ANGLE_TRY(map(context, D3D11_MAP_WRITE, &mappedImage));
+
+ uint8_t *offsetMappedData =
+ static_cast<uint8_t *>(mappedImage.pData) +
+ ((area.y / outputBlockHeight) * mappedImage.RowPitch +
+ (area.x / outputBlockWidth) * outputPixelSize + area.z * mappedImage.DepthPitch);
+
+ loadFunction(area.width, area.height, area.depth, static_cast<const uint8_t *>(input),
+ inputRowPitch, inputDepthPitch, offsetMappedData, mappedImage.RowPitch,
+ mappedImage.DepthPitch);
+
+ unmap();
+
+ return angle::Result::Continue;
+}
+
+angle::Result Image11::copyFromTexStorage(const gl::Context *context,
+ const gl::ImageIndex &imageIndex,
+ TextureStorage *source)
+{
+ TextureStorage11 *storage11 = GetAs<TextureStorage11>(source);
+
+ const TextureHelper11 *textureHelper = nullptr;
+ ANGLE_TRY(storage11->getResource(context, &textureHelper));
+
+ UINT subresourceIndex = 0;
+ ANGLE_TRY(storage11->getSubresourceIndex(context, imageIndex, &subresourceIndex));
+
+ gl::Box sourceBox(0, 0, 0, mWidth, mHeight, mDepth);
+ return copyWithoutConversion(context, gl::Offset(), sourceBox, *textureHelper,
+ subresourceIndex);
+}
+
+angle::Result Image11::copyFromFramebuffer(const gl::Context *context,
+ const gl::Offset &destOffset,
+ const gl::Rectangle &sourceArea,
+ const gl::Framebuffer *sourceFBO)
+{
+ const gl::FramebufferAttachment *srcAttachment = sourceFBO->getReadColorAttachment();
+ ASSERT(srcAttachment);
+
+ GLenum sourceInternalFormat = srcAttachment->getFormat().info->sizedInternalFormat;
+ const auto &d3d11Format =
+ d3d11::Format::Get(sourceInternalFormat, mRenderer->getRenderer11DeviceCaps());
+
+ if (d3d11Format.texFormat == mDXGIFormat && sourceInternalFormat == mInternalFormat)
+ {
+ RenderTarget11 *rt11 = nullptr;
+ ANGLE_TRY(srcAttachment->getRenderTarget(context, 0, &rt11));
+ ASSERT(rt11->getTexture().get());
+
+ TextureHelper11 textureHelper = rt11->getTexture();
+ unsigned int sourceSubResource = rt11->getSubresourceIndex();
+
+ gl::Box sourceBox(sourceArea.x, sourceArea.y, 0, sourceArea.width, sourceArea.height, 1);
+ return copyWithoutConversion(context, destOffset, sourceBox, textureHelper,
+ sourceSubResource);
+ }
+
+ // This format requires conversion, so we must copy the texture to staging and manually convert
+ // via readPixels
+ D3D11_MAPPED_SUBRESOURCE mappedImage;
+ ANGLE_TRY(map(context, D3D11_MAP_WRITE, &mappedImage));
+
+ // determine the offset coordinate into the destination buffer
+ const auto &dxgiFormatInfo = d3d11::GetDXGIFormatSizeInfo(mDXGIFormat);
+ GLsizei rowOffset = dxgiFormatInfo.pixelBytes * destOffset.x;
+
+ uint8_t *dataOffset = static_cast<uint8_t *>(mappedImage.pData) +
+ mappedImage.RowPitch * destOffset.y + rowOffset +
+ destOffset.z * mappedImage.DepthPitch;
+
+ const gl::InternalFormat &destFormatInfo = gl::GetSizedInternalFormatInfo(mInternalFormat);
+ const auto &destD3D11Format =
+ d3d11::Format::Get(mInternalFormat, mRenderer->getRenderer11DeviceCaps());
+
+ auto loadFunction = destD3D11Format.getLoadFunctions()(destFormatInfo.type);
+ angle::Result result = angle::Result::Continue;
+ if (loadFunction.requiresConversion)
+ {
+ size_t bufferSize = destFormatInfo.pixelBytes * sourceArea.width * sourceArea.height;
+ angle::MemoryBuffer *memoryBuffer = nullptr;
+ result = mRenderer->getScratchMemoryBuffer(GetImplAs<Context11>(context), bufferSize,
+ &memoryBuffer);
+
+ if (result == angle::Result::Continue)
+ {
+ GLuint memoryBufferRowPitch = destFormatInfo.pixelBytes * sourceArea.width;
+
+ result = mRenderer->readFromAttachment(
+ context, *srcAttachment, sourceArea, destFormatInfo.format, destFormatInfo.type,
+ memoryBufferRowPitch, gl::PixelPackState(), memoryBuffer->data());
+
+ loadFunction.loadFunction(sourceArea.width, sourceArea.height, 1, memoryBuffer->data(),
+ memoryBufferRowPitch, 0, dataOffset, mappedImage.RowPitch,
+ mappedImage.DepthPitch);
+ }
+ }
+ else
+ {
+ result = mRenderer->readFromAttachment(
+ context, *srcAttachment, sourceArea, destFormatInfo.format, destFormatInfo.type,
+ mappedImage.RowPitch, gl::PixelPackState(), dataOffset);
+ }
+
+ unmap();
+ mDirty = true;
+
+ return result;
+}
+
+angle::Result Image11::copyWithoutConversion(const gl::Context *context,
+ const gl::Offset &destOffset,
+ const gl::Box &sourceArea,
+ const TextureHelper11 &textureHelper,
+ UINT sourceSubResource)
+{
+ // No conversion needed-- use copyback fastpath
+ const TextureHelper11 *stagingTexture = nullptr;
+ unsigned int stagingSubresourceIndex = 0;
+ ANGLE_TRY(getStagingTexture(context, &stagingTexture, &stagingSubresourceIndex));
+
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+
+ const gl::Extents &extents = textureHelper.getExtents();
+
+ D3D11_BOX srcBox;
+ srcBox.left = sourceArea.x;
+ srcBox.right = sourceArea.x + sourceArea.width;
+ srcBox.top = sourceArea.y;
+ srcBox.bottom = sourceArea.y + sourceArea.height;
+ srcBox.front = sourceArea.z;
+ srcBox.back = sourceArea.z + sourceArea.depth;
+
+ if (textureHelper.is2D() && textureHelper.getSampleCount() > 1)
+ {
+ D3D11_TEXTURE2D_DESC resolveDesc;
+ resolveDesc.Width = extents.width;
+ resolveDesc.Height = extents.height;
+ resolveDesc.MipLevels = 1;
+ resolveDesc.ArraySize = 1;
+ resolveDesc.Format = textureHelper.getFormat();
+ resolveDesc.SampleDesc.Count = 1;
+ resolveDesc.SampleDesc.Quality = 0;
+ resolveDesc.Usage = D3D11_USAGE_DEFAULT;
+ resolveDesc.BindFlags = 0;
+ resolveDesc.CPUAccessFlags = 0;
+ resolveDesc.MiscFlags = 0;
+
+ d3d11::Texture2D resolveTex;
+ ANGLE_TRY(
+ mRenderer->allocateResource(GetImplAs<Context11>(context), resolveDesc, &resolveTex));
+
+ deviceContext->ResolveSubresource(resolveTex.get(), 0, textureHelper.get(),
+ sourceSubResource, textureHelper.getFormat());
+
+ deviceContext->CopySubresourceRegion(stagingTexture->get(), stagingSubresourceIndex,
+ destOffset.x, destOffset.y, destOffset.z,
+ resolveTex.get(), 0, &srcBox);
+ }
+ else
+ {
+ deviceContext->CopySubresourceRegion(stagingTexture->get(), stagingSubresourceIndex,
+ destOffset.x, destOffset.y, destOffset.z,
+ textureHelper.get(), sourceSubResource, &srcBox);
+ }
+
+ mDirty = true;
+ return angle::Result::Continue;
+}
+
+angle::Result Image11::getStagingTexture(const gl::Context *context,
+ const TextureHelper11 **outStagingTexture,
+ unsigned int *outSubresourceIndex)
+{
+ ANGLE_TRY(createStagingTexture(context));
+
+ *outStagingTexture = &mStagingTexture;
+ *outSubresourceIndex = mStagingSubresource;
+ return angle::Result::Continue;
+}
+
+void Image11::releaseStagingTexture()
+{
+ mStagingTexture.reset();
+ mStagingTextureSubresourceVerifier.reset();
+}
+
+angle::Result Image11::createStagingTexture(const gl::Context *context)
+{
+ if (mStagingTexture.valid())
+ {
+ return angle::Result::Continue;
+ }
+
+ ASSERT(mWidth > 0 && mHeight > 0 && mDepth > 0);
+
+ const DXGI_FORMAT dxgiFormat = getDXGIFormat();
+ const auto &formatInfo =
+ d3d11::Format::Get(mInternalFormat, mRenderer->getRenderer11DeviceCaps());
+
+ int lodOffset = 1;
+ GLsizei width = mWidth;
+ GLsizei height = mHeight;
+
+ // adjust size if needed for compressed textures
+ d3d11::MakeValidSize(false, dxgiFormat, &width, &height, &lodOffset);
+
+ Context11 *context11 = GetImplAs<Context11>(context);
+
+ switch (mType)
+ {
+ case gl::TextureType::_3D:
+ {
+ D3D11_TEXTURE3D_DESC desc;
+ desc.Width = width;
+ desc.Height = height;
+ desc.Depth = mDepth;
+ desc.MipLevels = lodOffset + 1;
+ desc.Format = dxgiFormat;
+ desc.Usage = D3D11_USAGE_STAGING;
+ desc.BindFlags = 0;
+ desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
+ desc.MiscFlags = 0;
+
+ if (formatInfo.dataInitializerFunction != nullptr)
+ {
+ gl::TexLevelArray<D3D11_SUBRESOURCE_DATA> initialData;
+ ANGLE_TRY(d3d11::GenerateInitialTextureData(
+ context, mInternalFormat, mRenderer->getRenderer11DeviceCaps(), width, height,
+ mDepth, lodOffset + 1, &initialData));
+
+ ANGLE_TRY(mRenderer->allocateTexture(context11, desc, formatInfo,
+ initialData.data(), &mStagingTexture));
+ }
+ else
+ {
+ ANGLE_TRY(
+ mRenderer->allocateTexture(context11, desc, formatInfo, &mStagingTexture));
+ }
+
+ mStagingTexture.setInternalName("Image11::StagingTexture3D");
+ mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1);
+ mStagingTextureSubresourceVerifier.setDesc(desc);
+ }
+ break;
+
+ case gl::TextureType::_2D:
+ case gl::TextureType::_2DArray:
+ case gl::TextureType::CubeMap:
+ {
+ D3D11_TEXTURE2D_DESC desc;
+ desc.Width = width;
+ desc.Height = height;
+ desc.MipLevels = lodOffset + 1;
+ desc.ArraySize = 1;
+ desc.Format = dxgiFormat;
+ desc.SampleDesc.Count = 1;
+ desc.SampleDesc.Quality = 0;
+ desc.Usage = D3D11_USAGE_STAGING;
+ desc.BindFlags = 0;
+ desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
+ desc.MiscFlags = 0;
+
+ if (formatInfo.dataInitializerFunction != nullptr)
+ {
+ gl::TexLevelArray<D3D11_SUBRESOURCE_DATA> initialData;
+ ANGLE_TRY(d3d11::GenerateInitialTextureData(
+ context, mInternalFormat, mRenderer->getRenderer11DeviceCaps(), width, height,
+ 1, lodOffset + 1, &initialData));
+
+ ANGLE_TRY(mRenderer->allocateTexture(context11, desc, formatInfo,
+ initialData.data(), &mStagingTexture));
+ }
+ else
+ {
+ ANGLE_TRY(
+ mRenderer->allocateTexture(context11, desc, formatInfo, &mStagingTexture));
+ }
+
+ mStagingTexture.setInternalName("Image11::StagingTexture2D");
+ mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1);
+ mStagingTextureSubresourceVerifier.setDesc(desc);
+ }
+ break;
+
+ default:
+ UNREACHABLE();
+ }
+
+ mDirty = false;
+ return angle::Result::Continue;
+}
+
+angle::Result Image11::map(const gl::Context *context,
+ D3D11_MAP mapType,
+ D3D11_MAPPED_SUBRESOURCE *map)
+{
+ // We must recover from the TextureStorage if necessary, even for D3D11_MAP_WRITE.
+ ANGLE_TRY(recoverFromAssociatedStorage(context));
+
+ const TextureHelper11 *stagingTexture = nullptr;
+ unsigned int subresourceIndex = 0;
+ ANGLE_TRY(getStagingTexture(context, &stagingTexture, &subresourceIndex));
+
+ ASSERT(stagingTexture && stagingTexture->valid());
+
+ ANGLE_TRY(
+ mRenderer->mapResource(context, stagingTexture->get(), subresourceIndex, mapType, 0, map));
+
+ if (!mStagingTextureSubresourceVerifier.wrap(mapType, map))
+ {
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+ deviceContext->Unmap(mStagingTexture.get(), mStagingSubresource);
+ Context11 *context11 = GetImplAs<Context11>(context);
+ context11->handleError(GL_OUT_OF_MEMORY,
+ "Failed to allocate staging texture mapping verifier buffer.",
+ __FILE__, ANGLE_FUNCTION, __LINE__);
+ return angle::Result::Stop;
+ }
+
+ mDirty = true;
+
+ return angle::Result::Continue;
+}
+
+void Image11::unmap()
+{
+ if (mStagingTexture.valid())
+ {
+ mStagingTextureSubresourceVerifier.unwrap();
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+ deviceContext->Unmap(mStagingTexture.get(), mStagingSubresource);
+ }
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Image11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Image11.h
new file mode 100644
index 0000000000..661365240c
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Image11.h
@@ -0,0 +1,128 @@
+//
+// Copyright 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.
+//
+
+// Image11.h: Defines the rx::Image11 class, which acts as the interface to
+// the actual underlying resources of a Texture
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_IMAGE11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_IMAGE11_H_
+
+#include "common/debug.h"
+#include "libANGLE/ImageIndex.h"
+#include "libANGLE/renderer/d3d/ImageD3D.h"
+#include "libANGLE/renderer/d3d/d3d11/MappedSubresourceVerifier11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+
+namespace gl
+{
+class Framebuffer;
+}
+
+namespace d3d11
+{
+template <typename T>
+class ScopedUnmapper;
+} // namespace d3d11
+
+namespace rx
+{
+class Renderer11;
+class TextureHelper11;
+class TextureStorage11;
+struct Renderer11DeviceCaps;
+
+class Image11 : public ImageD3D
+{
+ public:
+ Image11(Renderer11 *renderer);
+ ~Image11() override;
+
+ static angle::Result GenerateMipmap(const gl::Context *context,
+ Image11 *dest,
+ Image11 *src,
+ const Renderer11DeviceCaps &rendererCaps);
+ static angle::Result CopyImage(const gl::Context *context,
+ Image11 *dest,
+ Image11 *source,
+ const gl::Box &sourceBox,
+ const gl::Offset &destOffset,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha,
+ const Renderer11DeviceCaps &rendererCaps);
+
+ bool isDirty() const override;
+
+ angle::Result copyToStorage(const gl::Context *context,
+ TextureStorage *storage,
+ const gl::ImageIndex &index,
+ const gl::Box &region) override;
+
+ bool redefine(gl::TextureType type,
+ GLenum internalformat,
+ const gl::Extents &size,
+ bool forceRelease) override;
+
+ DXGI_FORMAT getDXGIFormat() const;
+
+ angle::Result loadData(const gl::Context *context,
+ const gl::Box &area,
+ const gl::PixelUnpackState &unpack,
+ GLenum type,
+ const void *input,
+ bool applySkipImages) override;
+ angle::Result loadCompressedData(const gl::Context *context,
+ const gl::Box &area,
+ const void *input) override;
+
+ angle::Result copyFromTexStorage(const gl::Context *context,
+ const gl::ImageIndex &imageIndex,
+ TextureStorage *source) override;
+ angle::Result copyFromFramebuffer(const gl::Context *context,
+ const gl::Offset &destOffset,
+ const gl::Rectangle &sourceArea,
+ const gl::Framebuffer *source) override;
+
+ angle::Result recoverFromAssociatedStorage(const gl::Context *context);
+ void verifyAssociatedStorageValid(TextureStorage11 *textureStorageEXT) const;
+ void disassociateStorage();
+
+ angle::Result getStagingTexture(const gl::Context *context,
+ const TextureHelper11 **outStagingTexture,
+ unsigned int *outSubresourceIndex);
+
+ protected:
+ template <typename T>
+ friend class d3d11::ScopedUnmapper;
+ angle::Result map(const gl::Context *context, D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map);
+ void unmap();
+
+ private:
+ angle::Result copyWithoutConversion(const gl::Context *context,
+ const gl::Offset &destOffset,
+ const gl::Box &sourceArea,
+ const TextureHelper11 &textureHelper,
+ UINT sourceSubResource);
+
+ angle::Result createStagingTexture(const gl::Context *context);
+ void releaseStagingTexture();
+
+ Renderer11 *mRenderer;
+
+ DXGI_FORMAT mDXGIFormat;
+ TextureHelper11 mStagingTexture;
+ unsigned int mStagingSubresource;
+ MappedSubresourceVerifier11 mStagingTextureSubresourceVerifier;
+
+ bool mRecoverFromStorage;
+ TextureStorage11 *mAssociatedStorage;
+ gl::ImageIndex mAssociatedImageIndex;
+ unsigned int mRecoveredFromStorageCount;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D11_IMAGE11_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.cpp
new file mode 100644
index 0000000000..7630b341fa
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.cpp
@@ -0,0 +1,160 @@
+//
+// Copyright 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.
+//
+
+// IndexBuffer11.cpp: Defines the D3D11 IndexBuffer implementation.
+
+#include "libANGLE/renderer/d3d/d3d11/IndexBuffer11.h"
+
+#include "libANGLE/Context.h"
+#include "libANGLE/renderer/d3d/d3d11/Context11.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+
+namespace rx
+{
+
+IndexBuffer11::IndexBuffer11(Renderer11 *const renderer)
+ : mRenderer(renderer),
+ mBuffer(),
+ mBufferSize(0),
+ mIndexType(gl::DrawElementsType::InvalidEnum),
+ mDynamicUsage(false)
+{}
+
+IndexBuffer11::~IndexBuffer11() {}
+
+angle::Result IndexBuffer11::initialize(const gl::Context *context,
+ unsigned int bufferSize,
+ gl::DrawElementsType indexType,
+ bool dynamic)
+{
+ mBuffer.reset();
+
+ updateSerial();
+
+ if (bufferSize > 0)
+ {
+ D3D11_BUFFER_DESC bufferDesc;
+ bufferDesc.ByteWidth = bufferSize;
+ bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
+ bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
+ bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+ bufferDesc.MiscFlags = 0;
+ bufferDesc.StructureByteStride = 0;
+
+ ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), bufferDesc, &mBuffer));
+
+ if (dynamic)
+ {
+ mBuffer.setInternalName("IndexBuffer11(dynamic)");
+ }
+ else
+ {
+ mBuffer.setInternalName("IndexBuffer11(static)");
+ }
+ }
+
+ mBufferSize = bufferSize;
+ mIndexType = indexType;
+ mDynamicUsage = dynamic;
+
+ return angle::Result::Continue;
+}
+
+angle::Result IndexBuffer11::mapBuffer(const gl::Context *context,
+ unsigned int offset,
+ unsigned int size,
+ void **outMappedMemory)
+{
+ Context11 *context11 = GetImplAs<Context11>(context);
+ ANGLE_CHECK_HR(context11, mBuffer.valid(), "Internal index buffer is not initialized.",
+ E_OUTOFMEMORY);
+
+ // Check for integer overflows and out-out-bounds map requests
+ bool outOfBounds = (offset + size < offset || offset + size > mBufferSize);
+ ANGLE_CHECK_HR(context11, !outOfBounds, "Index buffer map range is not inside the buffer.",
+ E_OUTOFMEMORY);
+
+ D3D11_MAPPED_SUBRESOURCE mappedResource;
+ ANGLE_TRY(mRenderer->mapResource(context, mBuffer.get(), 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0,
+ &mappedResource));
+
+ *outMappedMemory = static_cast<char *>(mappedResource.pData) + offset;
+ return angle::Result::Continue;
+}
+
+angle::Result IndexBuffer11::unmapBuffer(const gl::Context *context)
+{
+ Context11 *context11 = GetImplAs<Context11>(context);
+ ANGLE_CHECK_HR(context11, mBuffer.valid(), "Internal index buffer is not initialized.",
+ E_OUTOFMEMORY);
+
+ ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
+ dxContext->Unmap(mBuffer.get(), 0);
+ return angle::Result::Continue;
+}
+
+gl::DrawElementsType IndexBuffer11::getIndexType() const
+{
+ return mIndexType;
+}
+
+unsigned int IndexBuffer11::getBufferSize() const
+{
+ return mBufferSize;
+}
+
+angle::Result IndexBuffer11::setSize(const gl::Context *context,
+ unsigned int bufferSize,
+ gl::DrawElementsType indexType)
+{
+ if (bufferSize > mBufferSize || indexType != mIndexType)
+ {
+ return initialize(context, bufferSize, indexType, mDynamicUsage);
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result IndexBuffer11::discard(const gl::Context *context)
+{
+ Context11 *context11 = GetImplAs<Context11>(context);
+ ANGLE_CHECK_HR(context11, mBuffer.valid(), "Internal index buffer is not initialized.",
+ E_OUTOFMEMORY);
+
+ ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
+
+ D3D11_MAPPED_SUBRESOURCE mappedResource;
+ ANGLE_TRY(mRenderer->mapResource(context, mBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0,
+ &mappedResource));
+
+ dxContext->Unmap(mBuffer.get(), 0);
+
+ return angle::Result::Continue;
+}
+
+DXGI_FORMAT IndexBuffer11::getIndexFormat() const
+{
+ switch (mIndexType)
+ {
+ case gl::DrawElementsType::UnsignedByte:
+ return DXGI_FORMAT_R16_UINT;
+ case gl::DrawElementsType::UnsignedShort:
+ return DXGI_FORMAT_R16_UINT;
+ case gl::DrawElementsType::UnsignedInt:
+ return DXGI_FORMAT_R32_UINT;
+ default:
+ UNREACHABLE();
+ return DXGI_FORMAT_UNKNOWN;
+ }
+}
+
+const d3d11::Buffer &IndexBuffer11::getBuffer() const
+{
+ return mBuffer;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.h
new file mode 100644
index 0000000000..53c736cf7a
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/IndexBuffer11.h
@@ -0,0 +1,58 @@
+//
+// Copyright 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.
+//
+
+// IndexBuffer11.h: Defines the D3D11 IndexBuffer implementation.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_INDEXBUFFER11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_INDEXBUFFER11_H_
+
+#include "libANGLE/renderer/d3d/IndexBuffer.h"
+#include "libANGLE/renderer/d3d/d3d11/ResourceManager11.h"
+
+namespace rx
+{
+class Renderer11;
+
+class IndexBuffer11 : public IndexBuffer
+{
+ public:
+ explicit IndexBuffer11(Renderer11 *const renderer);
+ ~IndexBuffer11() override;
+
+ angle::Result initialize(const gl::Context *context,
+ unsigned int bufferSize,
+ gl::DrawElementsType indexType,
+ bool dynamic) override;
+
+ angle::Result mapBuffer(const gl::Context *context,
+ unsigned int offset,
+ unsigned int size,
+ void **outMappedMemory) override;
+ angle::Result unmapBuffer(const gl::Context *context) override;
+
+ gl::DrawElementsType getIndexType() const override;
+ unsigned int getBufferSize() const override;
+ angle::Result setSize(const gl::Context *context,
+ unsigned int bufferSize,
+ gl::DrawElementsType indexType) override;
+
+ angle::Result discard(const gl::Context *context) override;
+
+ DXGI_FORMAT getIndexFormat() const;
+ const d3d11::Buffer &getBuffer() const;
+
+ private:
+ Renderer11 *const mRenderer;
+
+ d3d11::Buffer mBuffer;
+ unsigned int mBufferSize;
+ gl::DrawElementsType mIndexType;
+ bool mDynamicUsage;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D11_INDEXBUFFER11_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp
new file mode 100644
index 0000000000..b5e12499b2
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp
@@ -0,0 +1,313 @@
+//
+// Copyright 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.
+//
+
+// InputLayoutCache.cpp: Defines InputLayoutCache, a class that builds and caches
+// D3D11 input layouts.
+
+#include "libANGLE/renderer/d3d/d3d11/InputLayoutCache.h"
+
+#include "common/bitset_utils.h"
+#include "common/utilities.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Program.h"
+#include "libANGLE/VertexArray.h"
+#include "libANGLE/VertexAttribute.h"
+#include "libANGLE/renderer/d3d/IndexDataManager.h"
+#include "libANGLE/renderer/d3d/ProgramD3D.h"
+#include "libANGLE/renderer/d3d/VertexDataManager.h"
+#include "libANGLE/renderer/d3d/d3d11/Context11.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h"
+#include "libANGLE/renderer/d3d/d3d11/VertexArray11.h"
+#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
+
+namespace rx
+{
+
+namespace
+{
+
+GLenum GetGLSLAttributeType(const std::vector<sh::ShaderVariable> &shaderAttributes, size_t index)
+{
+ // Count matrices differently
+ for (const sh::ShaderVariable &attrib : shaderAttributes)
+ {
+ if (attrib.location == -1)
+ {
+ continue;
+ }
+
+ GLenum transposedType = gl::TransposeMatrixType(attrib.type);
+ int rows = gl::VariableRowCount(transposedType);
+ int intIndex = static_cast<int>(index);
+
+ if (intIndex >= attrib.location && intIndex < attrib.location + rows)
+ {
+ return transposedType;
+ }
+ }
+
+ UNREACHABLE();
+ return GL_NONE;
+}
+
+struct PackedAttribute
+{
+ uint8_t attribType;
+ uint8_t semanticIndex;
+ uint8_t vertexFormatType;
+ uint8_t unusedPadding;
+ uint32_t divisor;
+};
+
+} // anonymous namespace
+
+PackedAttributeLayout::PackedAttributeLayout() : numAttributes(0), flags(0), attributeData({}) {}
+
+PackedAttributeLayout::PackedAttributeLayout(const PackedAttributeLayout &other) = default;
+
+void PackedAttributeLayout::addAttributeData(GLenum glType,
+ UINT semanticIndex,
+ angle::FormatID vertexFormatID,
+ unsigned int divisor)
+{
+ gl::AttributeType attribType = gl::GetAttributeType(glType);
+
+ PackedAttribute packedAttrib;
+ packedAttrib.attribType = static_cast<uint8_t>(attribType);
+ packedAttrib.semanticIndex = static_cast<uint8_t>(semanticIndex);
+ packedAttrib.vertexFormatType = static_cast<uint8_t>(vertexFormatID);
+ packedAttrib.unusedPadding = 0u;
+ packedAttrib.divisor = static_cast<uint32_t>(divisor);
+
+ ASSERT(static_cast<gl::AttributeType>(packedAttrib.attribType) == attribType);
+ ASSERT(static_cast<UINT>(packedAttrib.semanticIndex) == semanticIndex);
+ ASSERT(static_cast<angle::FormatID>(packedAttrib.vertexFormatType) == vertexFormatID);
+ ASSERT(static_cast<unsigned int>(packedAttrib.divisor) == divisor);
+
+ static_assert(sizeof(uint64_t) == sizeof(PackedAttribute),
+ "PackedAttributes must be 64-bits exactly.");
+
+ attributeData[numAttributes++] = gl::bitCast<uint64_t>(packedAttrib);
+}
+
+bool PackedAttributeLayout::operator==(const PackedAttributeLayout &other) const
+{
+ return (numAttributes == other.numAttributes) && (flags == other.flags) &&
+ (attributeData == other.attributeData);
+}
+
+InputLayoutCache::InputLayoutCache() : mLayoutCache(kDefaultCacheSize * 2) {}
+
+InputLayoutCache::~InputLayoutCache() {}
+
+void InputLayoutCache::clear()
+{
+ mLayoutCache.Clear();
+}
+
+angle::Result InputLayoutCache::getInputLayout(
+ Context11 *context11,
+ const gl::State &state,
+ const std::vector<const TranslatedAttribute *> &currentAttributes,
+ const AttribIndexArray &sortedSemanticIndices,
+ gl::PrimitiveMode mode,
+ GLsizei vertexCount,
+ GLsizei instances,
+ const d3d11::InputLayout **inputLayoutOut)
+{
+ gl::Program *program = state.getProgram();
+ const auto &shaderAttributes = program->getAttributes();
+ PackedAttributeLayout layout;
+
+ ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
+ bool programUsesInstancedPointSprites =
+ programD3D->usesPointSize() && programD3D->usesInstancedPointSpriteEmulation();
+ bool instancedPointSpritesActive =
+ programUsesInstancedPointSprites && (mode == gl::PrimitiveMode::Points);
+
+ if (programUsesInstancedPointSprites)
+ {
+ layout.flags |= PackedAttributeLayout::FLAG_USES_INSTANCED_SPRITES;
+ }
+
+ if (instancedPointSpritesActive)
+ {
+ layout.flags |= PackedAttributeLayout::FLAG_INSTANCED_SPRITES_ACTIVE;
+ }
+
+ if (instances > 0)
+ {
+ layout.flags |= PackedAttributeLayout::FLAG_INSTANCED_RENDERING_ACTIVE;
+ }
+
+ const auto &attribs = state.getVertexArray()->getVertexAttributes();
+ const auto &bindings = state.getVertexArray()->getVertexBindings();
+ const auto &locationToSemantic = programD3D->getAttribLocationToD3DSemantics();
+ int divisorMultiplier = program->usesMultiview() ? program->getNumViews() : 1;
+
+ for (size_t attribIndex : state.getProgramExecutable()->getActiveAttribLocationsMask())
+ {
+ // Record the type of the associated vertex shader vector in our key
+ // This will prevent mismatched vertex shaders from using the same input layout
+ GLenum glslElementType = GetGLSLAttributeType(shaderAttributes, attribIndex);
+
+ const auto &attrib = attribs[attribIndex];
+ const auto &binding = bindings[attrib.bindingIndex];
+ int d3dSemantic = locationToSemantic[attribIndex];
+
+ const auto &currentValue =
+ state.getVertexAttribCurrentValue(static_cast<unsigned int>(attribIndex));
+ angle::FormatID vertexFormatID = gl::GetVertexFormatID(attrib, currentValue.Type);
+
+ layout.addAttributeData(glslElementType, d3dSemantic, vertexFormatID,
+ binding.getDivisor() * divisorMultiplier);
+ }
+
+ if (layout.numAttributes > 0 || layout.flags != 0)
+ {
+ auto it = mLayoutCache.Get(layout);
+ if (it != mLayoutCache.end())
+ {
+ *inputLayoutOut = &it->second;
+ }
+ else
+ {
+ angle::TrimCache(mLayoutCache.max_size() / 2, kGCLimit, "input layout", &mLayoutCache);
+
+ d3d11::InputLayout newInputLayout;
+ ANGLE_TRY(createInputLayout(context11, sortedSemanticIndices, currentAttributes, mode,
+ vertexCount, instances, &newInputLayout));
+
+ auto insertIt = mLayoutCache.Put(layout, std::move(newInputLayout));
+ *inputLayoutOut = &insertIt->second;
+ }
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result InputLayoutCache::createInputLayout(
+ Context11 *context11,
+ const AttribIndexArray &sortedSemanticIndices,
+ const std::vector<const TranslatedAttribute *> &currentAttributes,
+ gl::PrimitiveMode mode,
+ GLsizei vertexCount,
+ GLsizei instances,
+ d3d11::InputLayout *inputLayoutOut)
+{
+ Renderer11 *renderer = context11->getRenderer();
+ ProgramD3D *programD3D = renderer->getStateManager()->getProgramD3D();
+ D3D_FEATURE_LEVEL featureLevel = renderer->getRenderer11DeviceCaps().featureLevel;
+
+ bool programUsesInstancedPointSprites =
+ programD3D->usesPointSize() && programD3D->usesInstancedPointSpriteEmulation();
+
+ unsigned int inputElementCount = 0;
+ gl::AttribArray<D3D11_INPUT_ELEMENT_DESC> inputElements;
+
+ for (size_t attribIndex = 0; attribIndex < currentAttributes.size(); ++attribIndex)
+ {
+ const auto &attrib = *currentAttributes[attribIndex];
+ const int sortedIndex = sortedSemanticIndices[attribIndex];
+
+ D3D11_INPUT_CLASSIFICATION inputClass =
+ attrib.divisor > 0 ? D3D11_INPUT_PER_INSTANCE_DATA : D3D11_INPUT_PER_VERTEX_DATA;
+
+ angle::FormatID vertexFormatID =
+ gl::GetVertexFormatID(*attrib.attribute, attrib.currentValueType);
+ const auto &vertexFormatInfo = d3d11::GetVertexFormatInfo(vertexFormatID, featureLevel);
+
+ auto *inputElement = &inputElements[inputElementCount];
+
+ inputElement->SemanticName = "TEXCOORD";
+ inputElement->SemanticIndex = sortedIndex;
+ inputElement->Format = vertexFormatInfo.nativeFormat;
+ inputElement->InputSlot = static_cast<UINT>(attribIndex);
+ inputElement->AlignedByteOffset = 0;
+ inputElement->InputSlotClass = inputClass;
+ inputElement->InstanceDataStepRate = attrib.divisor;
+
+ inputElementCount++;
+ }
+
+ // Instanced PointSprite emulation requires additional entries in the
+ // inputlayout to support the vertices that make up the pointsprite quad.
+ // We do this even if mode != GL_POINTS, since the shader signature has these inputs, and the
+ // input layout must match the shader
+ if (programUsesInstancedPointSprites)
+ {
+ // On 9_3, we must ensure that slot 0 contains non-instanced data.
+ // If slot 0 currently contains instanced data then we swap it with a non-instanced element.
+ // Note that instancing is only available on 9_3 via ANGLE_instanced_arrays, since 9_3
+ // doesn't support OpenGL ES 3.0.
+ // As per the spec for ANGLE_instanced_arrays, not all attributes can be instanced
+ // simultaneously, so a non-instanced element must exist.
+
+ UINT numIndicesPerInstance = 0;
+ if (instances > 0)
+ {
+ // This requires that the index range is resolved.
+ // Note: Vertex indexes can be arbitrarily large.
+ numIndicesPerInstance = gl::clampCast<UINT>(vertexCount);
+ }
+
+ for (size_t elementIndex = 0; elementIndex < inputElementCount; ++elementIndex)
+ {
+ // If rendering points and instanced pointsprite emulation is being used, the
+ // inputClass is required to be configured as per instance data
+ if (mode == gl::PrimitiveMode::Points)
+ {
+ inputElements[elementIndex].InputSlotClass = D3D11_INPUT_PER_INSTANCE_DATA;
+ inputElements[elementIndex].InstanceDataStepRate = 1;
+ if (numIndicesPerInstance > 0 && currentAttributes[elementIndex]->divisor > 0)
+ {
+ inputElements[elementIndex].InstanceDataStepRate = numIndicesPerInstance;
+ }
+ }
+ inputElements[elementIndex].InputSlot++;
+ }
+
+ inputElements[inputElementCount].SemanticName = "SPRITEPOSITION";
+ inputElements[inputElementCount].SemanticIndex = 0;
+ inputElements[inputElementCount].Format = DXGI_FORMAT_R32G32B32_FLOAT;
+ inputElements[inputElementCount].InputSlot = 0;
+ inputElements[inputElementCount].AlignedByteOffset = 0;
+ inputElements[inputElementCount].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
+ inputElements[inputElementCount].InstanceDataStepRate = 0;
+ inputElementCount++;
+
+ inputElements[inputElementCount].SemanticName = "SPRITETEXCOORD";
+ inputElements[inputElementCount].SemanticIndex = 0;
+ inputElements[inputElementCount].Format = DXGI_FORMAT_R32G32_FLOAT;
+ inputElements[inputElementCount].InputSlot = 0;
+ inputElements[inputElementCount].AlignedByteOffset = sizeof(float) * 3;
+ inputElements[inputElementCount].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
+ inputElements[inputElementCount].InstanceDataStepRate = 0;
+ inputElementCount++;
+ }
+
+ ShaderExecutableD3D *shader = nullptr;
+ ANGLE_TRY(programD3D->getVertexExecutableForCachedInputLayout(context11, &shader, nullptr));
+
+ ShaderExecutableD3D *shader11 = GetAs<ShaderExecutable11>(shader);
+
+ InputElementArray inputElementArray(inputElements.data(), inputElementCount);
+ ShaderData vertexShaderData(shader11->getFunction(), shader11->getLength());
+
+ ANGLE_TRY(renderer->allocateResource(context11, inputElementArray, &vertexShaderData,
+ inputLayoutOut));
+ return angle::Result::Continue;
+}
+
+void InputLayoutCache::setCacheSize(size_t newCacheSize)
+{
+ // Forces a reset of the cache.
+ LayoutCache newCache(newCacheSize);
+ mLayoutCache.Swap(newCache);
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h
new file mode 100644
index 0000000000..35d1b60607
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.h
@@ -0,0 +1,123 @@
+//
+// Copyright 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.
+//
+
+// InputLayoutCache.h: Defines InputLayoutCache, a class that builds and caches
+// D3D11 input layouts.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_INPUTLAYOUTCACHE_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_INPUTLAYOUTCACHE_H_
+
+#include <GLES2/gl2.h>
+
+#include <cstddef>
+
+#include <array>
+#include <map>
+
+#include "common/angleutils.h"
+#include "libANGLE/Constants.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/SizedMRUCache.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
+#include "libANGLE/renderer/d3d/d3d11/ResourceManager11.h"
+
+namespace rx
+{
+struct PackedAttributeLayout
+{
+ PackedAttributeLayout();
+ PackedAttributeLayout(const PackedAttributeLayout &other);
+
+ void addAttributeData(GLenum glType,
+ UINT semanticIndex,
+ angle::FormatID vertexFormatID,
+ unsigned int divisor);
+
+ bool operator==(const PackedAttributeLayout &other) const;
+
+ enum Flags
+ {
+ FLAG_USES_INSTANCED_SPRITES = 0x1,
+ FLAG_INSTANCED_SPRITES_ACTIVE = 0x2,
+ FLAG_INSTANCED_RENDERING_ACTIVE = 0x4,
+ };
+
+ uint32_t numAttributes;
+ uint32_t flags;
+ gl::AttribArray<uint64_t> attributeData;
+};
+} // namespace rx
+
+namespace std
+{
+template <>
+struct hash<rx::PackedAttributeLayout>
+{
+ size_t operator()(const rx::PackedAttributeLayout &value) const
+ {
+ return angle::ComputeGenericHash(value);
+ }
+};
+} // namespace std
+
+namespace gl
+{
+class Program;
+} // namespace gl
+
+namespace rx
+{
+class Context11;
+struct TranslatedAttribute;
+struct TranslatedIndexData;
+struct SourceIndexData;
+class ProgramD3D;
+class Renderer11;
+
+class InputLayoutCache : angle::NonCopyable
+{
+ public:
+ InputLayoutCache();
+ ~InputLayoutCache();
+
+ void clear();
+
+ // Useful for testing
+ void setCacheSize(size_t newCacheSize);
+
+ angle::Result getInputLayout(Context11 *context,
+ const gl::State &state,
+ const std::vector<const TranslatedAttribute *> &currentAttributes,
+ const AttribIndexArray &sortedSemanticIndices,
+ gl::PrimitiveMode mode,
+ GLsizei vertexCount,
+ GLsizei instances,
+ const d3d11::InputLayout **inputLayoutOut);
+
+ private:
+ angle::Result createInputLayout(
+ Context11 *context11,
+ const AttribIndexArray &sortedSemanticIndices,
+ const std::vector<const TranslatedAttribute *> &currentAttributes,
+ gl::PrimitiveMode mode,
+ GLsizei vertexCount,
+ GLsizei instances,
+ d3d11::InputLayout *inputLayoutOut);
+
+ // Starting cache size.
+ static constexpr size_t kDefaultCacheSize = 1024;
+
+ // The cache tries to clean up this many states at once.
+ static constexpr size_t kGCLimit = 128;
+
+ using LayoutCache = angle::base::HashingMRUCache<PackedAttributeLayout, d3d11::InputLayout>;
+ LayoutCache mLayoutCache;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D11_INPUTLAYOUTCACHE_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/MappedSubresourceVerifier11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/MappedSubresourceVerifier11.cpp
new file mode 100644
index 0000000000..d0f6906f1e
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/MappedSubresourceVerifier11.cpp
@@ -0,0 +1,119 @@
+//
+// Copyright 2019 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.
+//
+
+// MappedSubresourceVerifier11.cpp: Implements the
+// rx::MappedSubresourceVerifier11 class, a simple wrapper to D3D11 Texture2D
+// mapped memory so that ASAN and MSAN can catch memory errors done with a
+// pointer to the mapped texture memory.
+
+#include "libANGLE/renderer/d3d/d3d11/MappedSubresourceVerifier11.h"
+
+#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
+
+namespace rx
+{
+
+#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || defined(ANGLE_ENABLE_ASSERTS)
+
+namespace
+{
+
+# if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER)
+constexpr bool kUseWrap = true;
+# else
+constexpr bool kUseWrap = false;
+# endif
+
+size_t getPitchCount(const D3D11_TEXTURE2D_DESC &desc)
+{
+ const d3d11::DXGIFormatSize &dxgiFormatInfo = d3d11::GetDXGIFormatSizeInfo(desc.Format);
+ ASSERT(desc.Height % dxgiFormatInfo.blockHeight == 0);
+ return desc.Height / dxgiFormatInfo.blockHeight;
+}
+
+} // namespace
+
+MappedSubresourceVerifier11::MappedSubresourceVerifier11() = default;
+
+MappedSubresourceVerifier11::~MappedSubresourceVerifier11()
+{
+ ASSERT(!mOrigData);
+ ASSERT(!mWrapData.size());
+}
+
+void MappedSubresourceVerifier11::setDesc(const D3D11_TEXTURE2D_DESC &desc)
+{
+ ASSERT(desc.CPUAccessFlags & (D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE));
+ ASSERT(desc.Width);
+ ASSERT(desc.Height);
+ ASSERT(!mOrigData);
+ ASSERT(!mWrapData.size());
+ ASSERT(!mPitchType);
+ ASSERT(!mPitchCount);
+ mPitchType = &D3D11_MAPPED_SUBRESOURCE::RowPitch;
+ mPitchCount = getPitchCount(desc);
+}
+
+void MappedSubresourceVerifier11::setDesc(const D3D11_TEXTURE3D_DESC &desc)
+{
+ ASSERT(desc.CPUAccessFlags & (D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE));
+ ASSERT(desc.Width);
+ ASSERT(desc.Height);
+ ASSERT(desc.Depth);
+ ASSERT(!mOrigData);
+ ASSERT(!mWrapData.size());
+ ASSERT(!mPitchType);
+ ASSERT(!mPitchCount);
+ mPitchType = &D3D11_MAPPED_SUBRESOURCE::DepthPitch;
+ mPitchCount = desc.Depth;
+}
+
+void MappedSubresourceVerifier11::reset()
+{
+ ASSERT(!mOrigData);
+ ASSERT(!mWrapData.size());
+ mPitchType = nullptr;
+ mPitchCount = 0;
+}
+
+bool MappedSubresourceVerifier11::wrap(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map)
+{
+ ASSERT(map && map->pData);
+ ASSERT(mapType == D3D11_MAP_READ || mapType == D3D11_MAP_WRITE ||
+ mapType == D3D11_MAP_READ_WRITE);
+ ASSERT(mPitchCount);
+
+ if (kUseWrap)
+ {
+ if (!mWrapData.resize(mPitchCount * map->*mPitchType))
+ return false;
+ }
+
+ mOrigData = reinterpret_cast<uint8_t *>(map->pData);
+
+ if (kUseWrap)
+ {
+ std::copy(mOrigData, mOrigData + mWrapData.size(), mWrapData.data());
+ map->pData = mWrapData.data();
+ }
+ return true;
+}
+
+void MappedSubresourceVerifier11::unwrap()
+{
+ ASSERT(mPitchCount);
+ ASSERT(mOrigData);
+ if (kUseWrap)
+ {
+ std::copy(mWrapData.data(), mWrapData.data() + mWrapData.size(), mOrigData);
+ mWrapData = angle::MemoryBuffer();
+ }
+ mOrigData = nullptr;
+}
+
+#endif
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/MappedSubresourceVerifier11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/MappedSubresourceVerifier11.h
new file mode 100644
index 0000000000..f0fc70eb85
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/MappedSubresourceVerifier11.h
@@ -0,0 +1,63 @@
+//
+// Copyright 2019 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.
+//
+
+// MappedSubresourceVerifier11.h: Defines the rx::MappedSubresourceVerifier11
+// class, a simple wrapper to D3D11 Texture2D mapped memory so that ASAN
+// MSAN can catch memory errors done with a pointer to the mapped texture
+// memory.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_MAPPED_SUBRESOURCE_VERIFIER11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_MAPPED_SUBRESOURCE_VERIFIER11_H_
+
+#include "common/MemoryBuffer.h"
+#include "common/angleutils.h"
+
+namespace rx
+{
+
+class MappedSubresourceVerifier11 final : angle::NonCopyable
+{
+ public:
+ MappedSubresourceVerifier11();
+ ~MappedSubresourceVerifier11();
+
+ void setDesc(const D3D11_TEXTURE2D_DESC &desc);
+ void setDesc(const D3D11_TEXTURE3D_DESC &desc);
+ void reset();
+
+ bool wrap(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map);
+ void unwrap();
+
+ private:
+#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || defined(ANGLE_ENABLE_ASSERTS)
+ UINT D3D11_MAPPED_SUBRESOURCE::*mPitchType = nullptr;
+ size_t mPitchCount = 0;
+ angle::MemoryBuffer mWrapData;
+ uint8_t *mOrigData = nullptr;
+#endif
+};
+
+#if !(defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || defined(ANGLE_ENABLE_ASSERTS))
+
+inline MappedSubresourceVerifier11::MappedSubresourceVerifier11() = default;
+inline MappedSubresourceVerifier11::~MappedSubresourceVerifier11() = default;
+
+inline void MappedSubresourceVerifier11::setDesc(const D3D11_TEXTURE2D_DESC &desc) {}
+inline void MappedSubresourceVerifier11::setDesc(const D3D11_TEXTURE3D_DESC &desc) {}
+inline void MappedSubresourceVerifier11::reset() {}
+
+inline bool MappedSubresourceVerifier11::wrap(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map)
+{
+ return true;
+}
+
+inline void MappedSubresourceVerifier11::unwrap() {}
+
+#endif
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D11_MAPPED_SUBRESOURCE_VERIFIER11_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/NativeWindow11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/NativeWindow11.h
new file mode 100644
index 0000000000..e11b19cace
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/NativeWindow11.h
@@ -0,0 +1,38 @@
+//
+// 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.
+//
+
+// NativeWindow11.h: Defines NativeWindow11, a class for managing and performing operations on an
+// EGLNativeWindowType for the D3D11 renderer.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_NATIVEWINDOW11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_NATIVEWINDOW11_H_
+
+#include "common/debug.h"
+#include "common/platform.h"
+
+#include "libANGLE/Config.h"
+#include "libANGLE/renderer/d3d/NativeWindowD3D.h"
+
+namespace rx
+{
+
+class NativeWindow11 : public NativeWindowD3D
+{
+ public:
+ NativeWindow11(EGLNativeWindowType window) : NativeWindowD3D(window) {}
+
+ virtual HRESULT createSwapChain(ID3D11Device *device,
+ IDXGIFactory *factory,
+ DXGI_FORMAT format,
+ UINT width,
+ UINT height,
+ UINT samples,
+ IDXGISwapChain **swapChain) = 0;
+ virtual void commitChange() = 0;
+};
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D11_NATIVEWINDOW11_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp
new file mode 100644
index 0000000000..9649a91dd3
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.cpp
@@ -0,0 +1,271 @@
+//
+// Copyright 2013 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.
+//
+
+// PixelTransfer11.cpp:
+// Implementation for buffer-to-texture and texture-to-buffer copies.
+// Used to implement pixel transfers from unpack and to pack buffers.
+//
+
+#include "libANGLE/renderer/d3d/d3d11/PixelTransfer11.h"
+
+#include "libANGLE/Buffer.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Texture.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
+#include "libANGLE/renderer/d3d/d3d11/Context11.h"
+#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h"
+#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
+#include "libANGLE/renderer/serial_utils.h"
+
+// Precompiled shaders
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_gs.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4f.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4i.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4ui.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_vs.h"
+
+namespace rx
+{
+
+PixelTransfer11::PixelTransfer11(Renderer11 *renderer)
+ : mRenderer(renderer),
+ mResourcesLoaded(false),
+ mBufferToTextureVS(),
+ mBufferToTextureGS(),
+ mParamsConstantBuffer(),
+ mCopyRasterizerState(),
+ mCopyDepthStencilState()
+{}
+
+PixelTransfer11::~PixelTransfer11() {}
+
+angle::Result PixelTransfer11::loadResources(const gl::Context *context)
+{
+ if (mResourcesLoaded)
+ {
+ return angle::Result::Continue;
+ }
+
+ D3D11_RASTERIZER_DESC rasterDesc;
+ rasterDesc.FillMode = D3D11_FILL_SOLID;
+ rasterDesc.CullMode = D3D11_CULL_NONE;
+ rasterDesc.FrontCounterClockwise = FALSE;
+ rasterDesc.DepthBias = 0;
+ rasterDesc.SlopeScaledDepthBias = 0.0f;
+ rasterDesc.DepthBiasClamp = 0.0f;
+ rasterDesc.DepthClipEnable = TRUE;
+ rasterDesc.ScissorEnable = FALSE;
+ rasterDesc.MultisampleEnable = FALSE;
+ rasterDesc.AntialiasedLineEnable = FALSE;
+
+ Context11 *context11 = GetImplAs<Context11>(context);
+
+ ANGLE_TRY(mRenderer->allocateResource(context11, rasterDesc, &mCopyRasterizerState));
+
+ D3D11_DEPTH_STENCIL_DESC depthStencilDesc;
+ depthStencilDesc.DepthEnable = true;
+ depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
+ depthStencilDesc.DepthFunc = D3D11_COMPARISON_ALWAYS;
+ depthStencilDesc.StencilEnable = FALSE;
+ depthStencilDesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK;
+ depthStencilDesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK;
+ depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
+ depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
+ depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
+ depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
+ depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
+ depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
+ depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
+ depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
+
+ ANGLE_TRY(mRenderer->allocateResource(context11, depthStencilDesc, &mCopyDepthStencilState));
+
+ D3D11_BUFFER_DESC constantBufferDesc = {};
+ constantBufferDesc.ByteWidth = roundUpPow2<UINT>(sizeof(CopyShaderParams), 32u);
+ constantBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
+ constantBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
+ constantBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+ constantBufferDesc.MiscFlags = 0;
+ constantBufferDesc.StructureByteStride = 0;
+
+ ANGLE_TRY(mRenderer->allocateResource(context11, constantBufferDesc, &mParamsConstantBuffer));
+ mParamsConstantBuffer.setInternalName("PixelTransfer11ConstantBuffer");
+
+ // init shaders
+ ANGLE_TRY(mRenderer->allocateResource(context11, ShaderData(g_VS_BufferToTexture),
+ &mBufferToTextureVS));
+ mBufferToTextureVS.setInternalName("BufferToTextureVS");
+
+ ANGLE_TRY(mRenderer->allocateResource(context11, ShaderData(g_GS_BufferToTexture),
+ &mBufferToTextureGS));
+ mBufferToTextureGS.setInternalName("BufferToTextureGS");
+
+ ANGLE_TRY(buildShaderMap(context));
+
+ StructZero(&mParamsData);
+
+ mResourcesLoaded = true;
+
+ return angle::Result::Continue;
+}
+
+void PixelTransfer11::setBufferToTextureCopyParams(const gl::Box &destArea,
+ const gl::Extents &destSize,
+ GLenum internalFormat,
+ const gl::PixelUnpackState &unpack,
+ unsigned int offset,
+ CopyShaderParams *parametersOut)
+{
+ StructZero(parametersOut);
+
+ float texelCenterX = 0.5f / static_cast<float>(destSize.width);
+ float texelCenterY = 0.5f / static_cast<float>(destSize.height);
+
+ unsigned int bytesPerPixel = gl::GetSizedInternalFormatInfo(internalFormat).pixelBytes;
+ unsigned int alignmentBytes = static_cast<unsigned int>(unpack.alignment);
+ unsigned int alignmentPixels =
+ (alignmentBytes <= bytesPerPixel ? 1 : alignmentBytes / bytesPerPixel);
+
+ parametersOut->FirstPixelOffset = offset / bytesPerPixel;
+ parametersOut->PixelsPerRow =
+ static_cast<unsigned int>((unpack.rowLength > 0) ? unpack.rowLength : destArea.width);
+ parametersOut->RowStride = roundUp(parametersOut->PixelsPerRow, alignmentPixels);
+ parametersOut->RowsPerSlice = static_cast<unsigned int>(destArea.height);
+ parametersOut->PositionOffset[0] =
+ texelCenterX + (destArea.x / float(destSize.width)) * 2.0f - 1.0f;
+ parametersOut->PositionOffset[1] =
+ texelCenterY + ((destSize.height - destArea.y - 1) / float(destSize.height)) * 2.0f - 1.0f;
+ parametersOut->PositionScale[0] = 2.0f / static_cast<float>(destSize.width);
+ parametersOut->PositionScale[1] = -2.0f / static_cast<float>(destSize.height);
+ parametersOut->FirstSlice = destArea.z;
+}
+
+angle::Result PixelTransfer11::copyBufferToTexture(const gl::Context *context,
+ const gl::PixelUnpackState &unpack,
+ gl::Buffer *unpackBuffer,
+ unsigned int offset,
+ RenderTargetD3D *destRenderTarget,
+ GLenum destinationFormat,
+ GLenum sourcePixelsType,
+ const gl::Box &destArea)
+{
+ ASSERT(unpackBuffer);
+
+ ANGLE_TRY(loadResources(context));
+
+ gl::Extents destSize = destRenderTarget->getExtents();
+
+ ASSERT(destArea.x >= 0 && destArea.x + destArea.width <= destSize.width && destArea.y >= 0 &&
+ destArea.y + destArea.height <= destSize.height && destArea.z >= 0 &&
+ destArea.z + destArea.depth <= destSize.depth);
+
+ ASSERT(mRenderer->supportsFastCopyBufferToTexture(destinationFormat));
+
+ const d3d11::PixelShader *pixelShader = findBufferToTexturePS(destinationFormat);
+ ASSERT(pixelShader);
+
+ // The SRV must be in the proper read format, which may be different from the destination format
+ // EG: for half float data, we can load full precision floats with implicit conversion
+ GLenum unsizedFormat = gl::GetUnsizedFormat(destinationFormat);
+ const gl::InternalFormat &sourceglFormatInfo =
+ gl::GetInternalFormatInfo(unsizedFormat, sourcePixelsType);
+
+ const d3d11::Format &sourceFormatInfo = d3d11::Format::Get(
+ sourceglFormatInfo.sizedInternalFormat, mRenderer->getRenderer11DeviceCaps());
+ DXGI_FORMAT srvFormat = sourceFormatInfo.srvFormat;
+ ASSERT(srvFormat != DXGI_FORMAT_UNKNOWN);
+ Buffer11 *bufferStorage11 = GetAs<Buffer11>(unpackBuffer->getImplementation());
+ const d3d11::ShaderResourceView *bufferSRV = nullptr;
+ ANGLE_TRY(bufferStorage11->getSRV(context, srvFormat, &bufferSRV));
+ ASSERT(bufferSRV != nullptr);
+
+ const d3d11::RenderTargetView &textureRTV =
+ GetAs<RenderTarget11>(destRenderTarget)->getRenderTargetView();
+ ASSERT(textureRTV.valid());
+
+ CopyShaderParams shaderParams;
+ setBufferToTextureCopyParams(destArea, destSize, sourceglFormatInfo.sizedInternalFormat, unpack,
+ offset, &shaderParams);
+
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+
+ // Are we doing a 2D or 3D copy?
+ const auto *geometryShader = ((destSize.depth > 1) ? &mBufferToTextureGS : nullptr);
+ StateManager11 *stateManager = mRenderer->getStateManager();
+
+ stateManager->setDrawShaders(&mBufferToTextureVS, geometryShader, pixelShader);
+ stateManager->setShaderResource(gl::ShaderType::Fragment, 0, bufferSRV);
+ stateManager->setInputLayout(nullptr);
+ stateManager->setPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
+
+ stateManager->setSingleVertexBuffer(nullptr, 0, 0);
+ stateManager->setSimpleBlendState(nullptr);
+ stateManager->setDepthStencilState(&mCopyDepthStencilState, 0xFFFFFFFF);
+ stateManager->setRasterizerState(&mCopyRasterizerState);
+
+ stateManager->setRenderTarget(textureRTV.get(), nullptr);
+
+ if (!StructEquals(mParamsData, shaderParams))
+ {
+ d3d11::SetBufferData(deviceContext, mParamsConstantBuffer.get(), shaderParams);
+ mParamsData = shaderParams;
+ }
+
+ stateManager->setVertexConstantBuffer(0, &mParamsConstantBuffer);
+
+ // Set the viewport
+ stateManager->setSimpleViewport(destSize);
+
+ UINT numPixels = (shaderParams.PixelsPerRow * destArea.height * destArea.depth);
+ deviceContext->Draw(numPixels, 0);
+
+ return angle::Result::Continue;
+}
+
+angle::Result PixelTransfer11::buildShaderMap(const gl::Context *context)
+{
+ d3d11::PixelShader bufferToTextureFloat;
+ d3d11::PixelShader bufferToTextureInt;
+ d3d11::PixelShader bufferToTextureUint;
+
+ Context11 *context11 = GetImplAs<Context11>(context);
+
+ ANGLE_TRY(mRenderer->allocateResource(context11, ShaderData(g_PS_BufferToTexture_4F),
+ &bufferToTextureFloat));
+ ANGLE_TRY(mRenderer->allocateResource(context11, ShaderData(g_PS_BufferToTexture_4I),
+ &bufferToTextureInt));
+ ANGLE_TRY(mRenderer->allocateResource(context11, ShaderData(g_PS_BufferToTexture_4UI),
+ &bufferToTextureUint));
+
+ bufferToTextureFloat.setInternalName("BufferToTextureRGBA.ps");
+ bufferToTextureInt.setInternalName("BufferToTextureRGBA-I.ps");
+ bufferToTextureUint.setInternalName("BufferToTextureRGBA-UI.ps");
+
+ mBufferToTexturePSMap[GL_FLOAT] = std::move(bufferToTextureFloat);
+ mBufferToTexturePSMap[GL_INT] = std::move(bufferToTextureInt);
+ mBufferToTexturePSMap[GL_UNSIGNED_INT] = std::move(bufferToTextureUint);
+
+ return angle::Result::Continue;
+}
+
+const d3d11::PixelShader *PixelTransfer11::findBufferToTexturePS(GLenum internalFormat) const
+{
+ GLenum componentType = gl::GetSizedInternalFormatInfo(internalFormat).componentType;
+ if (componentType == GL_SIGNED_NORMALIZED || componentType == GL_UNSIGNED_NORMALIZED)
+ {
+ componentType = GL_FLOAT;
+ }
+
+ auto shaderMapIt = mBufferToTexturePSMap.find(componentType);
+ return (shaderMapIt == mBufferToTexturePSMap.end() ? nullptr : &shaderMapIt->second);
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.h
new file mode 100644
index 0000000000..bdb11b90ff
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/PixelTransfer11.h
@@ -0,0 +1,96 @@
+//
+// Copyright 2013 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.
+//
+
+// PixelTransfer11.h:
+// Buffer-to-Texture and Texture-to-Buffer data transfers.
+// Used to implement pixel unpack and pixel pack buffers in ES3.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_PIXELTRANSFER11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_PIXELTRANSFER11_H_
+
+#include <GLES2/gl2.h>
+
+#include <map>
+
+#include "common/platform.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/renderer/d3d/d3d11/ResourceManager11.h"
+
+namespace gl
+{
+class Buffer;
+class Context;
+struct Box;
+struct Extents;
+struct PixelUnpackState;
+} // namespace gl
+
+namespace rx
+{
+class Renderer11;
+class RenderTargetD3D;
+
+class PixelTransfer11
+{
+ public:
+ explicit PixelTransfer11(Renderer11 *renderer);
+ ~PixelTransfer11();
+
+ // unpack: the source buffer is stored in the unpack state, and buffer strides
+ // offset: the start of the data within the unpack buffer
+ // destRenderTarget: individual slice/layer of a target texture
+ // destinationFormat/sourcePixelsType: determines shaders + shader parameters
+ // destArea: the sub-section of destRenderTarget to copy to
+ angle::Result copyBufferToTexture(const gl::Context *context,
+ const gl::PixelUnpackState &unpack,
+ gl::Buffer *unpackBuffer,
+ unsigned int offset,
+ RenderTargetD3D *destRenderTarget,
+ GLenum destinationFormat,
+ GLenum sourcePixelsType,
+ const gl::Box &destArea);
+
+ private:
+ struct CopyShaderParams
+ {
+ unsigned int FirstPixelOffset;
+ unsigned int PixelsPerRow;
+ unsigned int RowStride;
+ unsigned int RowsPerSlice;
+ float PositionOffset[2];
+ float PositionScale[2];
+ int TexLocationOffset[2];
+ int TexLocationScale[2];
+ unsigned int FirstSlice;
+ };
+
+ static void setBufferToTextureCopyParams(const gl::Box &destArea,
+ const gl::Extents &destSize,
+ GLenum internalFormat,
+ const gl::PixelUnpackState &unpack,
+ unsigned int offset,
+ CopyShaderParams *parametersOut);
+
+ angle::Result loadResources(const gl::Context *context);
+ angle::Result buildShaderMap(const gl::Context *context);
+ const d3d11::PixelShader *findBufferToTexturePS(GLenum internalFormat) const;
+
+ Renderer11 *mRenderer;
+
+ bool mResourcesLoaded;
+ std::map<GLenum, d3d11::PixelShader> mBufferToTexturePSMap;
+ d3d11::VertexShader mBufferToTextureVS;
+ d3d11::GeometryShader mBufferToTextureGS;
+ d3d11::Buffer mParamsConstantBuffer;
+ CopyShaderParams mParamsData;
+
+ d3d11::RasterizerState mCopyRasterizerState;
+ d3d11::DepthStencilState mCopyDepthStencilState;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D11_PIXELTRANSFER11_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Program11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Program11.cpp
new file mode 100644
index 0000000000..510065ccd6
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Program11.cpp
@@ -0,0 +1,34 @@
+//
+// Copyright 2018 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.
+//
+// Program11: D3D11 implementation of an OpenGL Program.
+
+#include "libANGLE/renderer/d3d/d3d11/Program11.h"
+
+#include "libANGLE/Context.h"
+#include "libANGLE/renderer/d3d/d3d11/Context11.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/StateManager11.h"
+
+namespace rx
+{
+Program11::Program11(const gl::ProgramState &programState, Renderer11 *renderer)
+ : ProgramD3D(programState, renderer)
+{}
+
+Program11::~Program11() = default;
+
+angle::Result Program11::syncState(const gl::Context *context,
+ const gl::Program::DirtyBits &dirtyBits)
+{
+ Renderer11 *renderer11 = GetImplAs<Context11>(context)->getRenderer();
+ StateManager11 *stateManager = renderer11->getStateManager();
+
+ // This single flag should be replace by individual dirtyness.
+ stateManager->invalidateProgramUniformBuffers();
+
+ return angle::Result::Continue;
+}
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Program11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Program11.h
new file mode 100644
index 0000000000..2bd6bc3710
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Program11.h
@@ -0,0 +1,28 @@
+//
+// Copyright 2018 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.
+//
+// Program11: D3D11 implementation of an OpenGL Program.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_PROGRAM11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_PROGRAM11_H_
+
+#include "libANGLE/renderer/d3d/ProgramD3D.h"
+
+namespace rx
+{
+class Renderer11;
+
+class Program11 : public ProgramD3D
+{
+ public:
+ Program11(const gl::ProgramState &programState, Renderer11 *renderer11);
+ ~Program11() override;
+
+ angle::Result syncState(const gl::Context *context,
+ const gl::Program::DirtyBits &dirtyBits) override;
+};
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D11_PROGRAM11_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ProgramPipeline11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ProgramPipeline11.cpp
new file mode 100644
index 0000000000..2790809dde
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ProgramPipeline11.cpp
@@ -0,0 +1,21 @@
+//
+// Copyright 2017 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.
+//
+// ProgramPipelineNULL.cpp:
+// Implements the class methods for ProgramPipeline11.
+//
+
+#include "libANGLE/renderer/d3d/d3d11/ProgramPipeline11.h"
+
+namespace rx
+{
+
+ProgramPipeline11::ProgramPipeline11(const gl::ProgramPipelineState &state)
+ : ProgramPipelineImpl(state)
+{}
+
+ProgramPipeline11::~ProgramPipeline11() {}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ProgramPipeline11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ProgramPipeline11.h
new file mode 100644
index 0000000000..cf838eec05
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ProgramPipeline11.h
@@ -0,0 +1,27 @@
+//
+// Copyright 2017 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.
+//
+// ProgramPipeline11.h:
+// Defines the class interface for ProgramPipeline11, implementing ProgramPipelineImpl.
+//
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_PROGRAMPIPELINE11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_PROGRAMPIPELINE11_H_
+
+#include "libANGLE/renderer/ProgramPipelineImpl.h"
+
+namespace rx
+{
+
+class ProgramPipeline11 : public ProgramPipelineImpl
+{
+ public:
+ ProgramPipeline11(const gl::ProgramPipelineState &state);
+ ~ProgramPipeline11() override;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D11_PROGRAMPIPELINE11_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Query11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Query11.cpp
new file mode 100644
index 0000000000..f2368e9f8f
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Query11.cpp
@@ -0,0 +1,357 @@
+//
+// Copyright 2013 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.
+//
+
+// Query11.cpp: Defines the rx::Query11 class which implements rx::QueryImpl.
+
+#include "libANGLE/renderer/d3d/d3d11/Query11.h"
+
+#include <GLES2/gl2ext.h>
+
+#include "common/utilities.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/renderer/d3d/d3d11/Context11.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+
+namespace
+{
+
+GLuint64 MergeQueryResults(gl::QueryType type, GLuint64 currentResult, GLuint64 newResult)
+{
+ switch (type)
+ {
+ case gl::QueryType::AnySamples:
+ case gl::QueryType::AnySamplesConservative:
+ return (currentResult == GL_TRUE || newResult == GL_TRUE) ? GL_TRUE : GL_FALSE;
+
+ case gl::QueryType::TransformFeedbackPrimitivesWritten:
+ return currentResult + newResult;
+
+ case gl::QueryType::TimeElapsed:
+ return currentResult + newResult;
+
+ case gl::QueryType::Timestamp:
+ return newResult;
+
+ case gl::QueryType::CommandsCompleted:
+ return newResult;
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+} // anonymous namespace
+
+namespace rx
+{
+
+Query11::QueryState::QueryState()
+ : getDataAttemptCount(0), query(), beginTimestamp(), endTimestamp(), finished(false)
+{}
+
+Query11::QueryState::~QueryState() {}
+
+Query11::Query11(Renderer11 *renderer, gl::QueryType type)
+ : QueryImpl(type), mResult(0), mResultSum(0), mRenderer(renderer)
+{
+ mActiveQuery = std::unique_ptr<QueryState>(new QueryState());
+}
+
+Query11::~Query11()
+{
+ mRenderer->getStateManager()->onDeleteQueryObject(this);
+}
+
+angle::Result Query11::begin(const gl::Context *context)
+{
+ mResultSum = 0;
+ mRenderer->getStateManager()->onBeginQuery(this);
+ return resume(GetImplAs<Context11>(context));
+}
+
+angle::Result Query11::end(const gl::Context *context)
+{
+ return pause(GetImplAs<Context11>(context));
+}
+
+angle::Result Query11::queryCounter(const gl::Context *context)
+{
+ // This doesn't do anything for D3D11 as we don't support timestamps
+ ASSERT(getType() == gl::QueryType::Timestamp);
+ mResultSum = 0;
+ mPendingQueries.push_back(std::unique_ptr<QueryState>(new QueryState()));
+ return angle::Result::Continue;
+}
+
+template <typename T>
+angle::Result Query11::getResultBase(Context11 *context11, T *params)
+{
+ ASSERT(!mActiveQuery->query.valid());
+ ANGLE_TRY(flush(context11, true));
+ ASSERT(mPendingQueries.empty());
+ *params = static_cast<T>(mResultSum);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Query11::getResult(const gl::Context *context, GLint *params)
+{
+ return getResultBase(GetImplAs<Context11>(context), params);
+}
+
+angle::Result Query11::getResult(const gl::Context *context, GLuint *params)
+{
+ return getResultBase(GetImplAs<Context11>(context), params);
+}
+
+angle::Result Query11::getResult(const gl::Context *context, GLint64 *params)
+{
+ return getResultBase(GetImplAs<Context11>(context), params);
+}
+
+angle::Result Query11::getResult(const gl::Context *context, GLuint64 *params)
+{
+ return getResultBase(GetImplAs<Context11>(context), params);
+}
+
+angle::Result Query11::isResultAvailable(const gl::Context *context, bool *available)
+{
+ ANGLE_TRY(flush(GetImplAs<Context11>(context), false));
+
+ *available = mPendingQueries.empty();
+ return angle::Result::Continue;
+}
+
+angle::Result Query11::pause(Context11 *context11)
+{
+ if (mActiveQuery->query.valid())
+ {
+ ID3D11DeviceContext *context = mRenderer->getDeviceContext();
+ gl::QueryType type = getType();
+
+ // If we are doing time elapsed query the end timestamp
+ if (type == gl::QueryType::TimeElapsed)
+ {
+ context->End(mActiveQuery->endTimestamp.get());
+ }
+
+ context->End(mActiveQuery->query.get());
+
+ mPendingQueries.push_back(std::move(mActiveQuery));
+ mActiveQuery = std::unique_ptr<QueryState>(new QueryState());
+ }
+
+ return flush(context11, false);
+}
+
+angle::Result Query11::resume(Context11 *context11)
+{
+ if (!mActiveQuery->query.valid())
+ {
+ ANGLE_TRY(flush(context11, false));
+
+ gl::QueryType type = getType();
+ D3D11_QUERY d3dQueryType = gl_d3d11::ConvertQueryType(type);
+
+ D3D11_QUERY_DESC queryDesc;
+ queryDesc.Query = d3dQueryType;
+ queryDesc.MiscFlags = 0;
+
+ ANGLE_TRY(mRenderer->allocateResource(context11, queryDesc, &mActiveQuery->query));
+
+ // If we are doing time elapsed we also need a query to actually query the timestamp
+ if (type == gl::QueryType::TimeElapsed)
+ {
+ D3D11_QUERY_DESC desc;
+ desc.Query = D3D11_QUERY_TIMESTAMP;
+ desc.MiscFlags = 0;
+
+ ANGLE_TRY(mRenderer->allocateResource(context11, desc, &mActiveQuery->beginTimestamp));
+ ANGLE_TRY(mRenderer->allocateResource(context11, desc, &mActiveQuery->endTimestamp));
+ }
+
+ ID3D11DeviceContext *context = mRenderer->getDeviceContext();
+
+ if (d3dQueryType != D3D11_QUERY_EVENT)
+ {
+ context->Begin(mActiveQuery->query.get());
+ }
+
+ // If we are doing time elapsed, query the begin timestamp
+ if (type == gl::QueryType::TimeElapsed)
+ {
+ context->End(mActiveQuery->beginTimestamp.get());
+ }
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result Query11::flush(Context11 *context11, bool force)
+{
+ while (!mPendingQueries.empty())
+ {
+ QueryState *query = mPendingQueries.front().get();
+
+ do
+ {
+ ANGLE_TRY(testQuery(context11, query));
+ if (!query->finished && !force)
+ {
+ return angle::Result::Continue;
+ }
+ } while (!query->finished);
+
+ mResultSum = MergeQueryResults(getType(), mResultSum, mResult);
+ mPendingQueries.pop_front();
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result Query11::testQuery(Context11 *context11, QueryState *queryState)
+{
+ if (!queryState->finished)
+ {
+ ID3D11DeviceContext *context = mRenderer->getDeviceContext();
+ switch (getType())
+ {
+ case gl::QueryType::AnySamples:
+ case gl::QueryType::AnySamplesConservative:
+ {
+ ASSERT(queryState->query.valid());
+ UINT64 numPixels = 0;
+ HRESULT result =
+ context->GetData(queryState->query.get(), &numPixels, sizeof(numPixels), 0);
+ ANGLE_TRY_HR(context11, result, "Failed to get the data of an internal query");
+
+ if (result == S_OK)
+ {
+ queryState->finished = true;
+ mResult = (numPixels > 0) ? GL_TRUE : GL_FALSE;
+ }
+ }
+ break;
+
+ case gl::QueryType::TransformFeedbackPrimitivesWritten:
+ {
+ ASSERT(queryState->query.valid());
+ D3D11_QUERY_DATA_SO_STATISTICS soStats = {};
+ HRESULT result =
+ context->GetData(queryState->query.get(), &soStats, sizeof(soStats), 0);
+ ANGLE_TRY_HR(context11, result, "Failed to get the data of an internal query");
+
+ if (result == S_OK)
+ {
+ queryState->finished = true;
+ mResult = static_cast<GLuint64>(soStats.NumPrimitivesWritten);
+ }
+ }
+ break;
+
+ case gl::QueryType::TimeElapsed:
+ {
+ ASSERT(queryState->query.valid());
+ ASSERT(queryState->beginTimestamp.valid());
+ ASSERT(queryState->endTimestamp.valid());
+ D3D11_QUERY_DATA_TIMESTAMP_DISJOINT timeStats = {};
+ HRESULT result =
+ context->GetData(queryState->query.get(), &timeStats, sizeof(timeStats), 0);
+ ANGLE_TRY_HR(context11, result, "Failed to get the data of an internal query");
+
+ if (result == S_OK)
+ {
+ UINT64 beginTime = 0;
+ HRESULT beginRes = context->GetData(queryState->beginTimestamp.get(),
+ &beginTime, sizeof(UINT64), 0);
+ ANGLE_TRY_HR(context11, beginRes,
+ "Failed to get the data of an internal query");
+
+ UINT64 endTime = 0;
+ HRESULT endRes = context->GetData(queryState->endTimestamp.get(), &endTime,
+ sizeof(UINT64), 0);
+ ANGLE_TRY_HR(context11, endRes, "Failed to get the data of an internal query");
+
+ if (beginRes == S_OK && endRes == S_OK)
+ {
+ queryState->finished = true;
+ if (timeStats.Disjoint)
+ {
+ mRenderer->setGPUDisjoint();
+ }
+ static_assert(sizeof(UINT64) == sizeof(unsigned long long),
+ "D3D UINT64 isn't 64 bits");
+
+ angle::CheckedNumeric<UINT64> checkedTime(endTime);
+ checkedTime -= beginTime;
+ checkedTime *= 1000000000ull;
+ checkedTime /= timeStats.Frequency;
+ if (checkedTime.IsValid())
+ {
+ mResult = checkedTime.ValueOrDie();
+ }
+ else
+ {
+ mResult = std::numeric_limits<GLuint64>::max() / timeStats.Frequency;
+ // If an overflow does somehow occur, there is no way the elapsed time
+ // is accurate, so we generate a disjoint event
+ mRenderer->setGPUDisjoint();
+ }
+ }
+ }
+ }
+ break;
+
+ case gl::QueryType::Timestamp:
+ {
+ // D3D11 doesn't support GL timestamp queries as D3D timestamps are not guaranteed
+ // to have any sort of continuity outside of a disjoint timestamp query block, which
+ // GL depends on
+ ASSERT(!queryState->query.valid());
+ mResult = 0;
+ queryState->finished = true;
+ }
+ break;
+
+ case gl::QueryType::CommandsCompleted:
+ {
+ ASSERT(queryState->query.valid());
+ BOOL completed = 0;
+ HRESULT result =
+ context->GetData(queryState->query.get(), &completed, sizeof(completed), 0);
+ ANGLE_TRY_HR(context11, result, "Failed to get the data of an internal query");
+
+ if (result == S_OK)
+ {
+ queryState->finished = true;
+ ASSERT(completed == TRUE);
+ mResult = (completed == TRUE) ? GL_TRUE : GL_FALSE;
+ }
+ }
+ break;
+
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ queryState->getDataAttemptCount++;
+ bool checkDeviceLost =
+ (queryState->getDataAttemptCount % kPollingD3DDeviceLostCheckFrequency) == 0;
+ if (!queryState->finished && checkDeviceLost && mRenderer->testDeviceLost())
+ {
+ mRenderer->notifyDeviceLost();
+ ANGLE_TRY_HR(context11, E_OUTOFMEMORY,
+ "Failed to test get query result, device is lost.");
+ }
+ }
+
+ return angle::Result::Continue;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Query11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Query11.h
new file mode 100644
index 0000000000..96ac59d742
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Query11.h
@@ -0,0 +1,71 @@
+//
+// Copyright 2013 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.
+//
+
+// Query11.h: Defines the rx::Query11 class which implements rx::QueryImpl.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_QUERY11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_QUERY11_H_
+
+#include <deque>
+
+#include "libANGLE/renderer/QueryImpl.h"
+#include "libANGLE/renderer/d3d/d3d11/ResourceManager11.h"
+
+namespace rx
+{
+class Context11;
+class Renderer11;
+
+class Query11 : public QueryImpl
+{
+ public:
+ Query11(Renderer11 *renderer, gl::QueryType type);
+ ~Query11() override;
+
+ angle::Result begin(const gl::Context *context) override;
+ angle::Result end(const gl::Context *context) override;
+ angle::Result queryCounter(const gl::Context *context) override;
+ angle::Result getResult(const gl::Context *context, GLint *params) override;
+ angle::Result getResult(const gl::Context *context, GLuint *params) override;
+ angle::Result getResult(const gl::Context *context, GLint64 *params) override;
+ angle::Result getResult(const gl::Context *context, GLuint64 *params) override;
+ angle::Result isResultAvailable(const gl::Context *context, bool *available) override;
+
+ angle::Result pause(Context11 *context11);
+ angle::Result resume(Context11 *context11);
+
+ private:
+ struct QueryState final : private angle::NonCopyable
+ {
+ QueryState();
+ ~QueryState();
+
+ unsigned int getDataAttemptCount;
+
+ d3d11::Query query;
+ d3d11::Query beginTimestamp;
+ d3d11::Query endTimestamp;
+ bool finished;
+ };
+
+ angle::Result flush(Context11 *context11, bool force);
+ angle::Result testQuery(Context11 *context11, QueryState *queryState);
+
+ template <typename T>
+ angle::Result getResultBase(Context11 *context11, T *params);
+
+ GLuint64 mResult;
+ GLuint64 mResultSum;
+
+ Renderer11 *mRenderer;
+
+ std::unique_ptr<QueryState> mActiveQuery;
+ std::deque<std::unique_ptr<QueryState>> mPendingQueries;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D11_QUERY11_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.cpp
new file mode 100644
index 0000000000..964ac8c287
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.cpp
@@ -0,0 +1,323 @@
+//
+// Copyright 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.
+//
+
+// RenderStateCache.cpp: Defines rx::RenderStateCache, a cache of Direct3D render
+// state objects.
+
+#include "libANGLE/renderer/d3d/d3d11/RenderStateCache.h"
+
+#include <float.h>
+
+#include "common/Color.h"
+#include "common/debug.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/renderer/d3d/d3d11/Context11.h"
+#include "libANGLE/renderer/d3d/d3d11/Framebuffer11.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+
+namespace rx
+{
+using namespace gl_d3d11;
+
+RenderStateCache::RenderStateCache()
+ : mBlendStateCache(kMaxStates),
+ mRasterizerStateCache(kMaxStates),
+ mDepthStencilStateCache(kMaxStates),
+ mSamplerStateCache(kMaxStates)
+{}
+
+RenderStateCache::~RenderStateCache() {}
+
+void RenderStateCache::clear()
+{
+ mBlendStateCache.Clear();
+ mRasterizerStateCache.Clear();
+ mDepthStencilStateCache.Clear();
+ mSamplerStateCache.Clear();
+}
+
+// static
+d3d11::BlendStateKey RenderStateCache::GetBlendStateKey(const gl::Context *context,
+ Framebuffer11 *framebuffer11,
+ const gl::BlendStateExt &blendStateExt,
+ bool sampleAlphaToCoverage)
+{
+ d3d11::BlendStateKey key;
+ // All fields of the BlendStateExt inside the key should be initialized for the caching to
+ // work correctly. Due to mrt_perf_workaround, the actual indices of active draw buffers may be
+ // different, so both arrays should be tracked.
+ key.blendStateExt = gl::BlendStateExt(blendStateExt.getDrawBufferCount());
+ const gl::AttachmentList &colorbuffers = framebuffer11->getColorAttachmentsForRender(context);
+ const gl::DrawBufferMask colorAttachmentsForRenderMask =
+ framebuffer11->getLastColorAttachmentsForRenderMask();
+
+ ASSERT(blendStateExt.getDrawBufferCount() <= colorAttachmentsForRenderMask.size());
+ ASSERT(colorbuffers.size() == colorAttachmentsForRenderMask.count());
+
+ size_t keyBlendIndex = 0;
+
+ // With blending disabled, factors and equations are ignored when building
+ // D3D11_RENDER_TARGET_BLEND_DESC, so we can reduce the amount of unique keys by
+ // enforcing default values.
+ for (size_t sourceIndex : colorAttachmentsForRenderMask)
+ {
+ ASSERT(keyBlendIndex < colorbuffers.size());
+ const gl::FramebufferAttachment *attachment = colorbuffers[keyBlendIndex];
+
+ // Do not set blend state for null attachments that may be present when
+ // mrt_perf_workaround is disabled.
+ if (attachment == nullptr)
+ {
+ keyBlendIndex++;
+ continue;
+ }
+
+ const uint8_t colorMask = blendStateExt.getColorMaskIndexed(sourceIndex);
+
+ const gl::InternalFormat &internalFormat = *attachment->getFormat().info;
+
+ key.blendStateExt.setColorMaskIndexed(keyBlendIndex,
+ gl_d3d11::GetColorMask(internalFormat) & colorMask);
+ key.rtvMax = static_cast<uint16_t>(keyBlendIndex) + 1;
+
+ // Some D3D11 drivers produce unexpected results when blending is enabled for integer
+ // attachments. Per OpenGL ES spec, it must be ignored anyway. When blending is disabled,
+ // the state remains default to reduce the number of unique keys.
+ if (blendStateExt.getEnabledMask().test(sourceIndex) && !internalFormat.isInt())
+ {
+ key.blendStateExt.setEnabledIndexed(keyBlendIndex, true);
+ key.blendStateExt.setEquationsIndexed(keyBlendIndex, sourceIndex, blendStateExt);
+ key.blendStateExt.setFactorsIndexed(keyBlendIndex, sourceIndex, blendStateExt);
+ }
+ keyBlendIndex++;
+ }
+
+ key.sampleAlphaToCoverage = sampleAlphaToCoverage ? 1 : 0;
+ return key;
+}
+
+angle::Result RenderStateCache::getBlendState(const gl::Context *context,
+ Renderer11 *renderer,
+ const d3d11::BlendStateKey &key,
+ const d3d11::BlendState **outBlendState)
+{
+ auto keyIter = mBlendStateCache.Get(key);
+ if (keyIter != mBlendStateCache.end())
+ {
+ *outBlendState = &keyIter->second;
+ return angle::Result::Continue;
+ }
+
+ TrimCache(kMaxStates, kGCLimit, "blend state", &mBlendStateCache);
+
+ // Create a new blend state and insert it into the cache
+ D3D11_BLEND_DESC blendDesc = {}; // avoid undefined fields
+ const gl::BlendStateExt &blendStateExt = key.blendStateExt;
+
+ blendDesc.AlphaToCoverageEnable = key.sampleAlphaToCoverage != 0 ? TRUE : FALSE;
+ blendDesc.IndependentBlendEnable = key.rtvMax > 1 ? TRUE : FALSE;
+
+ // D3D11 API always accepts an array of blend states. Its validity depends on the hardware
+ // feature level. Given that we do not expose GL entrypoints that set per-buffer blend states on
+ // systems lower than FL10_1, this array will be always valid.
+
+ for (size_t i = 0; i < blendStateExt.getDrawBufferCount(); i++)
+ {
+ D3D11_RENDER_TARGET_BLEND_DESC &rtDesc = blendDesc.RenderTarget[i];
+
+ if (blendStateExt.getEnabledMask().test(i))
+ {
+ rtDesc.BlendEnable = true;
+ rtDesc.SrcBlend =
+ gl_d3d11::ConvertBlendFunc(blendStateExt.getSrcColorIndexed(i), false);
+ rtDesc.DestBlend =
+ gl_d3d11::ConvertBlendFunc(blendStateExt.getDstColorIndexed(i), false);
+ rtDesc.BlendOp = gl_d3d11::ConvertBlendOp(blendStateExt.getEquationColorIndexed(i));
+ rtDesc.SrcBlendAlpha =
+ gl_d3d11::ConvertBlendFunc(blendStateExt.getSrcAlphaIndexed(i), true);
+ rtDesc.DestBlendAlpha =
+ gl_d3d11::ConvertBlendFunc(blendStateExt.getDstAlphaIndexed(i), true);
+ rtDesc.BlendOpAlpha =
+ gl_d3d11::ConvertBlendOp(blendStateExt.getEquationAlphaIndexed(i));
+ }
+
+ // blendStateExt.colorMask follows the same packing scheme as
+ // D3D11_RENDER_TARGET_BLEND_DESC.RenderTargetWriteMask
+ rtDesc.RenderTargetWriteMask = blendStateExt.getColorMaskIndexed(i);
+ }
+
+ d3d11::BlendState d3dBlendState;
+ ANGLE_TRY(renderer->allocateResource(GetImplAs<Context11>(context), blendDesc, &d3dBlendState));
+ const auto &iter = mBlendStateCache.Put(key, std::move(d3dBlendState));
+
+ *outBlendState = &iter->second;
+
+ return angle::Result::Continue;
+}
+
+angle::Result RenderStateCache::getRasterizerState(const gl::Context *context,
+ Renderer11 *renderer,
+ const gl::RasterizerState &rasterState,
+ bool scissorEnabled,
+ ID3D11RasterizerState **outRasterizerState)
+{
+ d3d11::RasterizerStateKey key;
+ key.rasterizerState = rasterState;
+ key.scissorEnabled = scissorEnabled ? 1 : 0;
+
+ auto keyIter = mRasterizerStateCache.Get(key);
+ if (keyIter != mRasterizerStateCache.end())
+ {
+ *outRasterizerState = keyIter->second.get();
+ return angle::Result::Continue;
+ }
+
+ TrimCache(kMaxStates, kGCLimit, "rasterizer state", &mRasterizerStateCache);
+
+ D3D11_CULL_MODE cullMode =
+ gl_d3d11::ConvertCullMode(rasterState.cullFace, rasterState.cullMode);
+
+ // Disable culling if drawing points
+ if (rasterState.pointDrawMode)
+ {
+ cullMode = D3D11_CULL_NONE;
+ }
+
+ D3D11_RASTERIZER_DESC rasterDesc;
+ rasterDesc.FillMode = D3D11_FILL_SOLID;
+ rasterDesc.CullMode = cullMode;
+ rasterDesc.FrontCounterClockwise = (rasterState.frontFace == GL_CCW) ? FALSE : TRUE;
+ rasterDesc.DepthBiasClamp = 0.0f; // MSDN documentation of DepthBiasClamp implies a value of
+ // zero will preform no clamping, must be tested though.
+ rasterDesc.DepthClipEnable = TRUE;
+ rasterDesc.ScissorEnable = scissorEnabled ? TRUE : FALSE;
+ rasterDesc.MultisampleEnable = rasterState.multiSample;
+ rasterDesc.AntialiasedLineEnable = FALSE;
+
+ if (rasterState.polygonOffsetFill)
+ {
+ rasterDesc.SlopeScaledDepthBias = rasterState.polygonOffsetFactor;
+ rasterDesc.DepthBias = (INT)rasterState.polygonOffsetUnits;
+ }
+ else
+ {
+ rasterDesc.SlopeScaledDepthBias = 0.0f;
+ rasterDesc.DepthBias = 0;
+ }
+
+ d3d11::RasterizerState dx11RasterizerState;
+ ANGLE_TRY(renderer->allocateResource(GetImplAs<Context11>(context), rasterDesc,
+ &dx11RasterizerState));
+ *outRasterizerState = dx11RasterizerState.get();
+ mRasterizerStateCache.Put(key, std::move(dx11RasterizerState));
+
+ return angle::Result::Continue;
+}
+
+angle::Result RenderStateCache::getDepthStencilState(const gl::Context *context,
+ Renderer11 *renderer,
+ const gl::DepthStencilState &glState,
+ const d3d11::DepthStencilState **outDSState)
+{
+ auto keyIter = mDepthStencilStateCache.Get(glState);
+ if (keyIter != mDepthStencilStateCache.end())
+ {
+ *outDSState = &keyIter->second;
+ return angle::Result::Continue;
+ }
+
+ TrimCache(kMaxStates, kGCLimit, "depth stencil state", &mDepthStencilStateCache);
+
+ D3D11_DEPTH_STENCIL_DESC dsDesc = {};
+ dsDesc.DepthEnable = glState.depthTest ? TRUE : FALSE;
+ dsDesc.DepthWriteMask = ConvertDepthMask(glState.depthMask);
+ dsDesc.DepthFunc = ConvertComparison(glState.depthFunc);
+ dsDesc.StencilEnable = glState.stencilTest ? TRUE : FALSE;
+ dsDesc.StencilReadMask = ConvertStencilMask(glState.stencilMask);
+ dsDesc.StencilWriteMask = ConvertStencilMask(glState.stencilWritemask);
+ dsDesc.FrontFace.StencilFailOp = ConvertStencilOp(glState.stencilFail);
+ dsDesc.FrontFace.StencilDepthFailOp = ConvertStencilOp(glState.stencilPassDepthFail);
+ dsDesc.FrontFace.StencilPassOp = ConvertStencilOp(glState.stencilPassDepthPass);
+ dsDesc.FrontFace.StencilFunc = ConvertComparison(glState.stencilFunc);
+ dsDesc.BackFace.StencilFailOp = ConvertStencilOp(glState.stencilBackFail);
+ dsDesc.BackFace.StencilDepthFailOp = ConvertStencilOp(glState.stencilBackPassDepthFail);
+ dsDesc.BackFace.StencilPassOp = ConvertStencilOp(glState.stencilBackPassDepthPass);
+ dsDesc.BackFace.StencilFunc = ConvertComparison(glState.stencilBackFunc);
+
+ d3d11::DepthStencilState dx11DepthStencilState;
+ ANGLE_TRY(
+ renderer->allocateResource(GetImplAs<Context11>(context), dsDesc, &dx11DepthStencilState));
+ const auto &iter = mDepthStencilStateCache.Put(glState, std::move(dx11DepthStencilState));
+
+ *outDSState = &iter->second;
+
+ return angle::Result::Continue;
+}
+
+angle::Result RenderStateCache::getSamplerState(const gl::Context *context,
+ Renderer11 *renderer,
+ const gl::SamplerState &samplerState,
+ ID3D11SamplerState **outSamplerState)
+{
+ auto keyIter = mSamplerStateCache.Get(samplerState);
+ if (keyIter != mSamplerStateCache.end())
+ {
+ *outSamplerState = keyIter->second.get();
+ return angle::Result::Continue;
+ }
+
+ TrimCache(kMaxStates, kGCLimit, "sampler state", &mSamplerStateCache);
+
+ const auto &featureLevel = renderer->getRenderer11DeviceCaps().featureLevel;
+
+ D3D11_SAMPLER_DESC samplerDesc;
+ samplerDesc.Filter =
+ gl_d3d11::ConvertFilter(samplerState.getMinFilter(), samplerState.getMagFilter(),
+ samplerState.getMaxAnisotropy(), samplerState.getCompareMode());
+ samplerDesc.AddressU = gl_d3d11::ConvertTextureWrap(samplerState.getWrapS());
+ samplerDesc.AddressV = gl_d3d11::ConvertTextureWrap(samplerState.getWrapT());
+ samplerDesc.AddressW = gl_d3d11::ConvertTextureWrap(samplerState.getWrapR());
+ samplerDesc.MipLODBias = 0;
+ samplerDesc.MaxAnisotropy =
+ gl_d3d11::ConvertMaxAnisotropy(samplerState.getMaxAnisotropy(), featureLevel);
+ samplerDesc.ComparisonFunc = gl_d3d11::ConvertComparison(samplerState.getCompareFunc());
+ angle::ColorF borderColor;
+ if (samplerState.getBorderColor().type == angle::ColorGeneric::Type::Float)
+ {
+ borderColor = samplerState.getBorderColor().colorF;
+ }
+ samplerDesc.BorderColor[0] = borderColor.red;
+ samplerDesc.BorderColor[1] = borderColor.green;
+ samplerDesc.BorderColor[2] = borderColor.blue;
+ samplerDesc.BorderColor[3] = borderColor.alpha;
+ samplerDesc.MinLOD = samplerState.getMinLod();
+ samplerDesc.MaxLOD = samplerState.getMaxLod();
+
+ if (featureLevel <= D3D_FEATURE_LEVEL_9_3)
+ {
+ // Check that maxLOD is nearly FLT_MAX (1000.0f is the default), since 9_3 doesn't support
+ // anything other than FLT_MAX. Note that Feature Level 9_* only supports GL ES 2.0, so the
+ // consumer of ANGLE can't modify the Max LOD themselves.
+ ASSERT(samplerState.getMaxLod() >= 999.9f);
+
+ // Now just set MaxLOD to FLT_MAX. Other parts of the renderer (e.g. the non-zero max LOD
+ // workaround) should take account of this.
+ samplerDesc.MaxLOD = FLT_MAX;
+ }
+
+ d3d11::SamplerState dx11SamplerState;
+ ANGLE_TRY(
+ renderer->allocateResource(GetImplAs<Context11>(context), samplerDesc, &dx11SamplerState));
+ *outSamplerState = dx11SamplerState.get();
+ mSamplerStateCache.Put(samplerState, std::move(dx11SamplerState));
+
+ return angle::Result::Continue;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.h
new file mode 100644
index 0000000000..bd853fe86e
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.h
@@ -0,0 +1,124 @@
+//
+// Copyright 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.
+//
+
+// RenderStateCache.h: Defines rx::RenderStateCache, a cache of Direct3D render
+// state objects.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_RENDERSTATECACHE_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_RENDERSTATECACHE_H_
+
+#include "common/angleutils.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/SizedMRUCache.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+
+#include <unordered_map>
+
+namespace std
+{
+template <>
+struct hash<rx::d3d11::BlendStateKey>
+{
+ size_t operator()(const rx::d3d11::BlendStateKey &key) const
+ {
+ return angle::ComputeGenericHash(key);
+ }
+};
+
+template <>
+struct hash<rx::d3d11::RasterizerStateKey>
+{
+ size_t operator()(const rx::d3d11::RasterizerStateKey &key) const
+ {
+ return angle::ComputeGenericHash(key);
+ }
+};
+
+template <>
+struct hash<gl::DepthStencilState>
+{
+ size_t operator()(const gl::DepthStencilState &key) const
+ {
+ return angle::ComputeGenericHash(key);
+ }
+};
+
+template <>
+struct hash<gl::SamplerState>
+{
+ size_t operator()(const gl::SamplerState &key) const { return angle::ComputeGenericHash(key); }
+};
+} // namespace std
+
+namespace rx
+{
+class Framebuffer11;
+class Renderer11;
+
+class RenderStateCache : angle::NonCopyable
+{
+ public:
+ RenderStateCache();
+ virtual ~RenderStateCache();
+
+ void clear();
+
+ static d3d11::BlendStateKey GetBlendStateKey(const gl::Context *context,
+ Framebuffer11 *framebuffer11,
+ const gl::BlendStateExt &blendStateExt,
+ bool sampleAlphaToCoverage);
+ angle::Result getBlendState(const gl::Context *context,
+ Renderer11 *renderer,
+ const d3d11::BlendStateKey &key,
+ const d3d11::BlendState **outBlendState);
+ angle::Result getRasterizerState(const gl::Context *context,
+ Renderer11 *renderer,
+ const gl::RasterizerState &rasterState,
+ bool scissorEnabled,
+ ID3D11RasterizerState **outRasterizerState);
+ angle::Result getDepthStencilState(const gl::Context *context,
+ Renderer11 *renderer,
+ const gl::DepthStencilState &dsState,
+ const d3d11::DepthStencilState **outDSState);
+ angle::Result getSamplerState(const gl::Context *context,
+ Renderer11 *renderer,
+ const gl::SamplerState &samplerState,
+ ID3D11SamplerState **outSamplerState);
+
+ private:
+ // MSDN's documentation of ID3D11Device::CreateBlendState, ID3D11Device::CreateRasterizerState,
+ // ID3D11Device::CreateDepthStencilState and ID3D11Device::CreateSamplerState claims the maximum
+ // number of unique states of each type an application can create is 4096
+ // TODO(ShahmeerEsmail): Revisit the cache sizes to make sure they are appropriate for most
+ // scenarios.
+ static constexpr unsigned int kMaxStates = 4096;
+
+ // The cache tries to clean up this many states at once.
+ static constexpr unsigned int kGCLimit = 128;
+
+ // Blend state cache
+ using BlendStateMap = angle::base::HashingMRUCache<d3d11::BlendStateKey, d3d11::BlendState>;
+ BlendStateMap mBlendStateCache;
+
+ // Rasterizer state cache
+ using RasterizerStateMap =
+ angle::base::HashingMRUCache<d3d11::RasterizerStateKey, d3d11::RasterizerState>;
+ RasterizerStateMap mRasterizerStateCache;
+
+ // Depth stencil state cache
+ using DepthStencilStateMap =
+ angle::base::HashingMRUCache<gl::DepthStencilState, d3d11::DepthStencilState>;
+ DepthStencilStateMap mDepthStencilStateCache;
+
+ // Sample state cache
+ using SamplerStateMap = angle::base::HashingMRUCache<gl::SamplerState, d3d11::SamplerState>;
+ SamplerStateMap mSamplerStateCache;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D11_RENDERSTATECACHE_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp
new file mode 100644
index 0000000000..2f550b5a77
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.cpp
@@ -0,0 +1,403 @@
+//
+// Copyright 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.
+//
+
+// RenderTarget11.cpp: Implements a DX11-specific wrapper for ID3D11View pointers
+// retained by Renderbuffers.
+
+#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
+
+#include "libANGLE/Context.h"
+#include "libANGLE/renderer/d3d/d3d11/Context11.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/SwapChain11.h"
+#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
+
+namespace rx
+{
+
+namespace
+{
+bool GetTextureProperties(ID3D11Resource *resource, unsigned int *mipLevels, unsigned int *samples)
+{
+ ID3D11Texture1D *texture1D = d3d11::DynamicCastComObject<ID3D11Texture1D>(resource);
+ if (texture1D)
+ {
+ D3D11_TEXTURE1D_DESC texDesc;
+ texture1D->GetDesc(&texDesc);
+ SafeRelease(texture1D);
+
+ *mipLevels = texDesc.MipLevels;
+ *samples = 0;
+
+ return true;
+ }
+
+ ID3D11Texture2D *texture2D = d3d11::DynamicCastComObject<ID3D11Texture2D>(resource);
+ if (texture2D)
+ {
+ D3D11_TEXTURE2D_DESC texDesc;
+ texture2D->GetDesc(&texDesc);
+ SafeRelease(texture2D);
+
+ *mipLevels = texDesc.MipLevels;
+ *samples = texDesc.SampleDesc.Count > 1 ? texDesc.SampleDesc.Count : 0;
+
+ return true;
+ }
+
+ ID3D11Texture3D *texture3D = d3d11::DynamicCastComObject<ID3D11Texture3D>(resource);
+ if (texture3D)
+ {
+ D3D11_TEXTURE3D_DESC texDesc;
+ texture3D->GetDesc(&texDesc);
+ SafeRelease(texture3D);
+
+ *mipLevels = texDesc.MipLevels;
+ *samples = 0;
+
+ return true;
+ }
+
+ return false;
+}
+
+unsigned int GetRTVSubresourceIndex(ID3D11Resource *resource, ID3D11RenderTargetView *view)
+{
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ view->GetDesc(&rtvDesc);
+
+ unsigned int mipSlice = 0;
+ unsigned int arraySlice = 0;
+
+ 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;
+ }
+
+ unsigned int mipLevels, samples;
+ GetTextureProperties(resource, &mipLevels, &samples);
+
+ return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels);
+}
+
+unsigned int GetDSVSubresourceIndex(ID3D11Resource *resource, ID3D11DepthStencilView *view)
+{
+ D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
+ view->GetDesc(&dsvDesc);
+
+ unsigned int mipSlice = 0;
+ unsigned int arraySlice = 0;
+
+ 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;
+ }
+
+ unsigned int mipLevels, samples;
+ GetTextureProperties(resource, &mipLevels, &samples);
+
+ return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels);
+}
+
+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) {}
+
+RenderTarget11::~RenderTarget11() {}
+
+TextureRenderTarget11::TextureRenderTarget11(d3d11::RenderTargetView &&rtv,
+ const TextureHelper11 &resource,
+ const d3d11::SharedSRV &srv,
+ const d3d11::SharedSRV &blitSRV,
+ GLenum internalFormat,
+ const d3d11::Format &formatSet,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLsizei samples)
+ : RenderTarget11(formatSet),
+ mWidth(width),
+ mHeight(height),
+ mDepth(depth),
+ mInternalFormat(internalFormat),
+ mSamples(samples),
+ mSubresourceIndex(0),
+ mTexture(resource),
+ mRenderTarget(std::move(rtv)),
+ mDepthStencil(),
+ mShaderResource(srv.makeCopy()),
+ mBlitShaderResource(blitSRV.makeCopy())
+{
+ if (mRenderTarget.valid() && mTexture.valid())
+ {
+ mSubresourceIndex = GetRTVSubresourceIndex(mTexture.get(), mRenderTarget.get());
+ }
+ ASSERT(mFormatSet.formatID != angle::FormatID::NONE || mWidth == 0 || mHeight == 0);
+}
+
+TextureRenderTarget11::TextureRenderTarget11(d3d11::DepthStencilView &&dsv,
+ const TextureHelper11 &resource,
+ const d3d11::SharedSRV &srv,
+ GLenum internalFormat,
+ const d3d11::Format &formatSet,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLsizei samples)
+ : RenderTarget11(formatSet),
+ mWidth(width),
+ mHeight(height),
+ mDepth(depth),
+ mInternalFormat(internalFormat),
+ mSamples(samples),
+ mSubresourceIndex(0),
+ mTexture(resource),
+ mRenderTarget(),
+ mDepthStencil(std::move(dsv)),
+ mShaderResource(srv.makeCopy()),
+ mBlitShaderResource()
+{
+ if (mDepthStencil.valid() && mTexture.valid())
+ {
+ mSubresourceIndex = GetDSVSubresourceIndex(mTexture.get(), mDepthStencil.get());
+ }
+ ASSERT(mFormatSet.formatID != angle::FormatID::NONE || mWidth == 0 || mHeight == 0);
+}
+
+TextureRenderTarget11::~TextureRenderTarget11() {}
+
+const TextureHelper11 &TextureRenderTarget11::getTexture() const
+{
+ return mTexture;
+}
+
+const d3d11::RenderTargetView &TextureRenderTarget11::getRenderTargetView() const
+{
+ return mRenderTarget;
+}
+
+const d3d11::DepthStencilView &TextureRenderTarget11::getDepthStencilView() const
+{
+ return mDepthStencil;
+}
+
+angle::Result TextureRenderTarget11::getShaderResourceView(const gl::Context *context,
+ const d3d11::SharedSRV **outSRV)
+{
+ *outSRV = &mShaderResource;
+ return angle::Result::Continue;
+}
+
+angle::Result TextureRenderTarget11::getBlitShaderResourceView(const gl::Context *context,
+ const d3d11::SharedSRV **outSRV)
+{
+ *outSRV = &mBlitShaderResource;
+ return angle::Result::Continue;
+}
+
+GLsizei TextureRenderTarget11::getWidth() const
+{
+ return mWidth;
+}
+
+GLsizei TextureRenderTarget11::getHeight() const
+{
+ return mHeight;
+}
+
+GLsizei TextureRenderTarget11::getDepth() const
+{
+ return mDepth;
+}
+
+GLenum TextureRenderTarget11::getInternalFormat() const
+{
+ return mInternalFormat;
+}
+
+GLsizei TextureRenderTarget11::getSamples() const
+{
+ return mSamples;
+}
+
+unsigned int TextureRenderTarget11::getSubresourceIndex() const
+{
+ return mSubresourceIndex;
+}
+
+SurfaceRenderTarget11::SurfaceRenderTarget11(SwapChain11 *swapChain,
+ Renderer11 *renderer,
+ bool depth)
+ : RenderTarget11(GetSurfaceFormatSet(depth, swapChain, renderer)),
+ mSwapChain(swapChain),
+ mDepth(depth)
+{
+ ASSERT(mSwapChain);
+}
+
+SurfaceRenderTarget11::~SurfaceRenderTarget11() {}
+
+GLsizei SurfaceRenderTarget11::getWidth() const
+{
+ return mSwapChain->getWidth();
+}
+
+GLsizei SurfaceRenderTarget11::getHeight() const
+{
+ return mSwapChain->getHeight();
+}
+
+GLsizei SurfaceRenderTarget11::getDepth() const
+{
+ return 1;
+}
+
+GLenum SurfaceRenderTarget11::getInternalFormat() const
+{
+ return GetSurfaceRTFormat(mDepth, mSwapChain);
+}
+
+GLsizei SurfaceRenderTarget11::getSamples() const
+{
+ return mSwapChain->getSamples();
+}
+
+const TextureHelper11 &SurfaceRenderTarget11::getTexture() const
+{
+ return (mDepth ? mSwapChain->getDepthStencilTexture() : mSwapChain->getOffscreenTexture());
+}
+
+const d3d11::RenderTargetView &SurfaceRenderTarget11::getRenderTargetView() const
+{
+ ASSERT(!mDepth);
+ return mSwapChain->getRenderTarget();
+}
+
+const d3d11::DepthStencilView &SurfaceRenderTarget11::getDepthStencilView() const
+{
+ ASSERT(mDepth);
+ return mSwapChain->getDepthStencil();
+}
+
+angle::Result SurfaceRenderTarget11::getShaderResourceView(const gl::Context *context,
+ const d3d11::SharedSRV **outSRV)
+{
+ if (mDepth)
+ {
+ *outSRV = &mSwapChain->getDepthStencilShaderResource();
+ }
+ else
+ {
+ ANGLE_TRY(mSwapChain->getRenderTargetShaderResource(GetImplAs<Context11>(context), outSRV));
+ }
+ return angle::Result::Continue;
+}
+
+angle::Result SurfaceRenderTarget11::getBlitShaderResourceView(const gl::Context *context,
+ const d3d11::SharedSRV **outSRV)
+{
+ // The SurfaceRenderTargetView format should always be such that the normal SRV works for blits.
+ return getShaderResourceView(context, outSRV);
+}
+
+unsigned int SurfaceRenderTarget11::getSubresourceIndex() const
+{
+ return 0;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.h
new file mode 100644
index 0000000000..8467831e3b
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/RenderTarget11.h
@@ -0,0 +1,133 @@
+//
+// Copyright 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.
+//
+
+// RenderTarget11.h: Defines a DX11-specific wrapper for ID3D11View pointers
+// retained by Renderbuffers.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_RENDERTARGET11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_RENDERTARGET11_H_
+
+#include "libANGLE/renderer/d3d/RenderTargetD3D.h"
+#include "libANGLE/renderer/d3d/d3d11/ResourceManager11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
+
+namespace rx
+{
+class SwapChain11;
+class Renderer11;
+
+class RenderTarget11 : public RenderTargetD3D
+{
+ public:
+ RenderTarget11(const d3d11::Format &formatSet);
+ ~RenderTarget11() override;
+
+ virtual const TextureHelper11 &getTexture() const = 0;
+ virtual const d3d11::RenderTargetView &getRenderTargetView() const = 0;
+ virtual const d3d11::DepthStencilView &getDepthStencilView() const = 0;
+ virtual angle::Result getShaderResourceView(const gl::Context *context,
+ const d3d11::SharedSRV **outSRV) = 0;
+ virtual angle::Result getBlitShaderResourceView(const gl::Context *context,
+ const d3d11::SharedSRV **outSRV) = 0;
+
+ virtual unsigned int getSubresourceIndex() const = 0;
+
+ const d3d11::Format &getFormatSet() const { return mFormatSet; }
+
+ protected:
+ const d3d11::Format &mFormatSet;
+};
+
+class TextureRenderTarget11 : public RenderTarget11
+{
+ public:
+ // TextureRenderTarget11 takes ownership of any D3D11 resources it is given and will AddRef them
+ TextureRenderTarget11(d3d11::RenderTargetView &&rtv,
+ const TextureHelper11 &resource,
+ const d3d11::SharedSRV &srv,
+ const d3d11::SharedSRV &blitSRV,
+ GLenum internalFormat,
+ const d3d11::Format &formatSet,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLsizei samples);
+ TextureRenderTarget11(d3d11::DepthStencilView &&dsv,
+ const TextureHelper11 &resource,
+ const d3d11::SharedSRV &srv,
+ GLenum internalFormat,
+ const d3d11::Format &formatSet,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLsizei samples);
+ ~TextureRenderTarget11() override;
+
+ GLsizei getWidth() const override;
+ GLsizei getHeight() const override;
+ GLsizei getDepth() const override;
+ GLenum getInternalFormat() const override;
+ GLsizei getSamples() const override;
+
+ const TextureHelper11 &getTexture() const override;
+ const d3d11::RenderTargetView &getRenderTargetView() const override;
+ const d3d11::DepthStencilView &getDepthStencilView() const override;
+ angle::Result getShaderResourceView(const gl::Context *context,
+ const d3d11::SharedSRV **outSRV) override;
+ angle::Result getBlitShaderResourceView(const gl::Context *context,
+ const d3d11::SharedSRV **outSRV) override;
+
+ unsigned int getSubresourceIndex() const override;
+
+ private:
+ GLsizei mWidth;
+ GLsizei mHeight;
+ GLsizei mDepth;
+ GLenum mInternalFormat;
+ GLsizei mSamples;
+
+ unsigned int mSubresourceIndex;
+ TextureHelper11 mTexture;
+ d3d11::RenderTargetView mRenderTarget;
+ d3d11::DepthStencilView mDepthStencil;
+ d3d11::SharedSRV mShaderResource;
+
+ // Shader resource view to use with internal blit shaders. Not set for depth/stencil render
+ // targets.
+ d3d11::SharedSRV mBlitShaderResource;
+};
+
+class SurfaceRenderTarget11 : public RenderTarget11
+{
+ public:
+ SurfaceRenderTarget11(SwapChain11 *swapChain, Renderer11 *renderer, bool depth);
+ ~SurfaceRenderTarget11() override;
+
+ GLsizei getWidth() const override;
+ GLsizei getHeight() const override;
+ GLsizei getDepth() const override;
+ GLenum getInternalFormat() const override;
+ GLsizei getSamples() const override;
+
+ const TextureHelper11 &getTexture() const override;
+ const d3d11::RenderTargetView &getRenderTargetView() const override;
+ const d3d11::DepthStencilView &getDepthStencilView() const override;
+ angle::Result getShaderResourceView(const gl::Context *context,
+ const d3d11::SharedSRV **outSRV) override;
+ angle::Result getBlitShaderResourceView(const gl::Context *context,
+ const d3d11::SharedSRV **outSRV) override;
+
+ unsigned int getSubresourceIndex() const override;
+
+ private:
+ SwapChain11 *mSwapChain;
+ bool mDepth;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D11_RENDERTARGET11_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
new file mode 100644
index 0000000000..fdd264e92b
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
@@ -0,0 +1,4454 @@
+//
+// Copyright 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.
+//
+
+// Renderer11.cpp: Implements a back-end specific class for the D3D11 renderer.
+
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+
+#include <EGL/eglext.h>
+#include <versionhelpers.h>
+#include <sstream>
+
+#include "anglebase/no_destructor.h"
+#include "common/tls.h"
+#include "common/utilities.h"
+#include "libANGLE/Buffer.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Display.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/Program.h"
+#include "libANGLE/State.h"
+#include "libANGLE/Surface.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/histogram_macros.h"
+#include "libANGLE/renderer/d3d/CompilerD3D.h"
+#include "libANGLE/renderer/d3d/DeviceD3D.h"
+#include "libANGLE/renderer/d3d/DisplayD3D.h"
+#include "libANGLE/renderer/d3d/FramebufferD3D.h"
+#include "libANGLE/renderer/d3d/IndexDataManager.h"
+#include "libANGLE/renderer/d3d/RenderbufferD3D.h"
+#include "libANGLE/renderer/d3d/ShaderD3D.h"
+#include "libANGLE/renderer/d3d/SurfaceD3D.h"
+#include "libANGLE/renderer/d3d/TextureD3D.h"
+#include "libANGLE/renderer/d3d/VertexDataManager.h"
+#include "libANGLE/renderer/d3d/d3d11/Blit11.h"
+#include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
+#include "libANGLE/renderer/d3d/d3d11/Clear11.h"
+#include "libANGLE/renderer/d3d/d3d11/Context11.h"
+#include "libANGLE/renderer/d3d/d3d11/ExternalImageSiblingImpl11.h"
+#include "libANGLE/renderer/d3d/d3d11/Fence11.h"
+#include "libANGLE/renderer/d3d/d3d11/Framebuffer11.h"
+#include "libANGLE/renderer/d3d/d3d11/Image11.h"
+#include "libANGLE/renderer/d3d/d3d11/IndexBuffer11.h"
+#include "libANGLE/renderer/d3d/d3d11/PixelTransfer11.h"
+#include "libANGLE/renderer/d3d/d3d11/Program11.h"
+#include "libANGLE/renderer/d3d/d3d11/Query11.h"
+#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
+#include "libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h"
+#include "libANGLE/renderer/d3d/d3d11/StreamProducerD3DTexture.h"
+#include "libANGLE/renderer/d3d/d3d11/SwapChain11.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"
+#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
+#include "libANGLE/renderer/d3d/driver_utils_d3d.h"
+#include "libANGLE/renderer/driver_utils.h"
+#include "libANGLE/renderer/dxgi_support_table.h"
+#include "libANGLE/renderer/renderer_utils.h"
+#include "libANGLE/trace.h"
+
+#ifdef ANGLE_ENABLE_WINDOWS_UWP
+# include "libANGLE/renderer/d3d/d3d11/winrt/NativeWindow11WinRT.h"
+#else
+# include "libANGLE/renderer/d3d/d3d11/win32/NativeWindow11Win32.h"
+#endif
+
+#ifdef ANGLE_ENABLE_D3D11_COMPOSITOR_NATIVE_WINDOW
+# include "libANGLE/renderer/d3d/d3d11/converged/CompositorNativeWindow11.h"
+#endif
+
+// Enable ANGLE_SKIP_DXGI_1_2_CHECK if there is not a possibility of using cross-process
+// HWNDs or the Windows 7 Platform Update (KB2670838) is expected to be installed.
+#ifndef ANGLE_SKIP_DXGI_1_2_CHECK
+# define ANGLE_SKIP_DXGI_1_2_CHECK 0
+#endif
+
+namespace rx
+{
+
+namespace
+{
+
+enum
+{
+ MAX_TEXTURE_IMAGE_UNITS_VTF_SM4 = 16
+};
+
+enum ANGLEFeatureLevel
+{
+ ANGLE_FEATURE_LEVEL_INVALID,
+ ANGLE_FEATURE_LEVEL_9_3,
+ ANGLE_FEATURE_LEVEL_10_0,
+ ANGLE_FEATURE_LEVEL_10_1,
+ ANGLE_FEATURE_LEVEL_11_0,
+ ANGLE_FEATURE_LEVEL_11_1,
+ NUM_ANGLE_FEATURE_LEVELS
+};
+
+ANGLEFeatureLevel GetANGLEFeatureLevel(D3D_FEATURE_LEVEL d3dFeatureLevel)
+{
+ switch (d3dFeatureLevel)
+ {
+ case D3D_FEATURE_LEVEL_9_3:
+ return ANGLE_FEATURE_LEVEL_9_3;
+ case D3D_FEATURE_LEVEL_10_0:
+ return ANGLE_FEATURE_LEVEL_10_0;
+ case D3D_FEATURE_LEVEL_10_1:
+ return ANGLE_FEATURE_LEVEL_10_1;
+ case D3D_FEATURE_LEVEL_11_0:
+ return ANGLE_FEATURE_LEVEL_11_0;
+ case D3D_FEATURE_LEVEL_11_1:
+ return ANGLE_FEATURE_LEVEL_11_1;
+ default:
+ return ANGLE_FEATURE_LEVEL_INVALID;
+ }
+}
+
+void SetLineLoopIndices(GLuint *dest, size_t count)
+{
+ for (size_t i = 0; i < count; i++)
+ {
+ dest[i] = static_cast<GLuint>(i);
+ }
+ dest[count] = 0;
+}
+
+template <typename T>
+void CopyLineLoopIndices(const void *indices, GLuint *dest, size_t count)
+{
+ const T *srcPtr = static_cast<const T *>(indices);
+ for (size_t i = 0; i < count; ++i)
+ {
+ dest[i] = static_cast<GLuint>(srcPtr[i]);
+ }
+ dest[count] = static_cast<GLuint>(srcPtr[0]);
+}
+
+void SetTriangleFanIndices(GLuint *destPtr, size_t numTris)
+{
+ for (size_t i = 0; i < numTris; i++)
+ {
+ destPtr[i * 3 + 0] = 0;
+ destPtr[i * 3 + 1] = static_cast<GLuint>(i) + 1;
+ destPtr[i * 3 + 2] = static_cast<GLuint>(i) + 2;
+ }
+}
+
+void GetLineLoopIndices(const void *indices,
+ gl::DrawElementsType indexType,
+ GLuint count,
+ bool usePrimitiveRestartFixedIndex,
+ std::vector<GLuint> *bufferOut)
+{
+ if (indexType != gl::DrawElementsType::InvalidEnum && usePrimitiveRestartFixedIndex)
+ {
+ size_t indexCount = GetLineLoopWithRestartIndexCount(indexType, count,
+ static_cast<const uint8_t *>(indices));
+ bufferOut->resize(indexCount);
+ switch (indexType)
+ {
+ case gl::DrawElementsType::UnsignedByte:
+ CopyLineLoopIndicesWithRestart<GLubyte, GLuint>(
+ count, static_cast<const uint8_t *>(indices),
+ reinterpret_cast<uint8_t *>(bufferOut->data()));
+ break;
+ case gl::DrawElementsType::UnsignedShort:
+ CopyLineLoopIndicesWithRestart<GLushort, GLuint>(
+ count, static_cast<const uint8_t *>(indices),
+ reinterpret_cast<uint8_t *>(bufferOut->data()));
+ break;
+ case gl::DrawElementsType::UnsignedInt:
+ CopyLineLoopIndicesWithRestart<GLuint, GLuint>(
+ count, static_cast<const uint8_t *>(indices),
+ reinterpret_cast<uint8_t *>(bufferOut->data()));
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ return;
+ }
+
+ // For non-primitive-restart draws, the index count is static.
+ bufferOut->resize(static_cast<size_t>(count) + 1);
+
+ switch (indexType)
+ {
+ // Non-indexed draw
+ case gl::DrawElementsType::InvalidEnum:
+ SetLineLoopIndices(&(*bufferOut)[0], count);
+ break;
+ case gl::DrawElementsType::UnsignedByte:
+ CopyLineLoopIndices<GLubyte>(indices, &(*bufferOut)[0], count);
+ break;
+ case gl::DrawElementsType::UnsignedShort:
+ CopyLineLoopIndices<GLushort>(indices, &(*bufferOut)[0], count);
+ break;
+ case gl::DrawElementsType::UnsignedInt:
+ CopyLineLoopIndices<GLuint>(indices, &(*bufferOut)[0], count);
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+template <typename T>
+void CopyTriangleFanIndices(const void *indices, GLuint *destPtr, size_t numTris)
+{
+ const T *srcPtr = static_cast<const T *>(indices);
+
+ for (size_t i = 0; i < numTris; i++)
+ {
+ destPtr[i * 3 + 0] = static_cast<GLuint>(srcPtr[0]);
+ destPtr[i * 3 + 1] = static_cast<GLuint>(srcPtr[i + 1]);
+ destPtr[i * 3 + 2] = static_cast<GLuint>(srcPtr[i + 2]);
+ }
+}
+
+template <typename T>
+void CopyTriangleFanIndicesWithRestart(const void *indices,
+ GLuint indexCount,
+ gl::DrawElementsType indexType,
+ std::vector<GLuint> *bufferOut)
+{
+ GLuint restartIndex = gl::GetPrimitiveRestartIndex(indexType);
+ GLuint d3dRestartIndex = gl::GetPrimitiveRestartIndex(gl::DrawElementsType::UnsignedInt);
+ const T *srcPtr = static_cast<const T *>(indices);
+ Optional<GLuint> vertexA;
+ Optional<GLuint> vertexB;
+
+ bufferOut->clear();
+
+ for (size_t indexIdx = 0; indexIdx < indexCount; ++indexIdx)
+ {
+ GLuint value = static_cast<GLuint>(srcPtr[indexIdx]);
+
+ if (value == restartIndex)
+ {
+ bufferOut->push_back(d3dRestartIndex);
+ vertexA.reset();
+ vertexB.reset();
+ }
+ else
+ {
+ if (!vertexA.valid())
+ {
+ vertexA = value;
+ }
+ else if (!vertexB.valid())
+ {
+ vertexB = value;
+ }
+ else
+ {
+ bufferOut->push_back(vertexA.value());
+ bufferOut->push_back(vertexB.value());
+ bufferOut->push_back(value);
+ vertexB = value;
+ }
+ }
+ }
+}
+
+void GetTriFanIndices(const void *indices,
+ gl::DrawElementsType indexType,
+ GLuint count,
+ bool usePrimitiveRestartFixedIndex,
+ std::vector<GLuint> *bufferOut)
+{
+ if (indexType != gl::DrawElementsType::InvalidEnum && usePrimitiveRestartFixedIndex)
+ {
+ switch (indexType)
+ {
+ case gl::DrawElementsType::UnsignedByte:
+ CopyTriangleFanIndicesWithRestart<GLubyte>(indices, count, indexType, bufferOut);
+ break;
+ case gl::DrawElementsType::UnsignedShort:
+ CopyTriangleFanIndicesWithRestart<GLushort>(indices, count, indexType, bufferOut);
+ break;
+ case gl::DrawElementsType::UnsignedInt:
+ CopyTriangleFanIndicesWithRestart<GLuint>(indices, count, indexType, bufferOut);
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ return;
+ }
+
+ // For non-primitive-restart draws, the index count is static.
+ GLuint numTris = count - 2;
+ bufferOut->resize(numTris * 3);
+
+ switch (indexType)
+ {
+ // Non-indexed draw
+ case gl::DrawElementsType::InvalidEnum:
+ SetTriangleFanIndices(&(*bufferOut)[0], numTris);
+ break;
+ case gl::DrawElementsType::UnsignedByte:
+ CopyTriangleFanIndices<GLubyte>(indices, &(*bufferOut)[0], numTris);
+ break;
+ case gl::DrawElementsType::UnsignedShort:
+ CopyTriangleFanIndices<GLushort>(indices, &(*bufferOut)[0], numTris);
+ break;
+ case gl::DrawElementsType::UnsignedInt:
+ CopyTriangleFanIndices<GLuint>(indices, &(*bufferOut)[0], numTris);
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+bool IsArrayRTV(ID3D11RenderTargetView *rtv)
+{
+ D3D11_RENDER_TARGET_VIEW_DESC desc;
+ rtv->GetDesc(&desc);
+ if (desc.ViewDimension == D3D11_RTV_DIMENSION_TEXTURE1DARRAY &&
+ desc.Texture1DArray.ArraySize > 1)
+ return true;
+ if (desc.ViewDimension == D3D11_RTV_DIMENSION_TEXTURE2DARRAY &&
+ desc.Texture2DArray.ArraySize > 1)
+ return true;
+ if (desc.ViewDimension == D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY &&
+ desc.Texture2DMSArray.ArraySize > 1)
+ return true;
+ return false;
+}
+
+GLsizei GetAdjustedInstanceCount(const ProgramD3D *program, GLsizei instanceCount)
+{
+ if (!program->getState().usesMultiview())
+ {
+ return instanceCount;
+ }
+ if (instanceCount == 0)
+ {
+ return program->getState().getNumViews();
+ }
+ return program->getState().getNumViews() * instanceCount;
+}
+
+const uint32_t ScratchMemoryBufferLifetime = 1000;
+
+void PopulateFormatDeviceCaps(ID3D11Device *device,
+ DXGI_FORMAT format,
+ UINT *outSupport,
+ UINT *outMaxSamples)
+{
+ if (FAILED(device->CheckFormatSupport(format, outSupport)))
+ {
+ *outSupport = 0;
+ }
+
+ *outMaxSamples = 0;
+ for (UINT sampleCount = 2; sampleCount <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; sampleCount *= 2)
+ {
+ UINT qualityCount = 0;
+ if (FAILED(device->CheckMultisampleQualityLevels(format, sampleCount, &qualityCount)) ||
+ qualityCount == 0)
+ {
+ break;
+ }
+
+ *outMaxSamples = sampleCount;
+ }
+}
+
+angle::Result GetTextureD3DResourceFromStorageOrImage(const gl::Context *context,
+ TextureD3D *texture,
+ const gl::ImageIndex &index,
+ const TextureHelper11 **outResource,
+ UINT *outSubresource)
+{
+ // If the storage exists, use it. Otherwise, copy directly from the images to avoid
+ // allocating a new storage.
+ if (texture->hasStorage())
+ {
+ TextureStorage *storage = nullptr;
+ ANGLE_TRY(texture->getNativeTexture(context, &storage));
+
+ TextureStorage11 *storage11 = GetAs<TextureStorage11>(storage);
+ ANGLE_TRY(storage11->getResource(context, outResource));
+ ANGLE_TRY(storage11->getSubresourceIndex(context, index, outSubresource));
+ }
+ else
+ {
+ ImageD3D *image = texture->getImage(index);
+ Image11 *image11 = GetAs<Image11>(image);
+ ANGLE_TRY(image11->getStagingTexture(context, outResource, outSubresource));
+ }
+
+ return angle::Result::Continue;
+}
+
+} // anonymous namespace
+
+Renderer11DeviceCaps::Renderer11DeviceCaps() = default;
+
+Renderer11::Renderer11(egl::Display *display)
+ : RendererD3D(display),
+ mCreateDebugDevice(false),
+ mStateCache(),
+ mStateManager(this),
+ mLastHistogramUpdateTime(
+ ANGLEPlatformCurrent()->monotonicallyIncreasingTime(ANGLEPlatformCurrent())),
+ mDebug(nullptr),
+ mScratchMemoryBuffer(ScratchMemoryBufferLifetime)
+{
+ mLineLoopIB = nullptr;
+ mTriangleFanIB = nullptr;
+
+ mBlit = nullptr;
+ mPixelTransfer = nullptr;
+
+ mClear = nullptr;
+
+ mTrim = nullptr;
+
+ mRenderer11DeviceCaps.supportsClearView = false;
+ mRenderer11DeviceCaps.supportsConstantBufferOffsets = false;
+ mRenderer11DeviceCaps.supportsVpRtIndexWriteFromVertexShader = false;
+ mRenderer11DeviceCaps.supportsDXGI1_2 = false;
+ mRenderer11DeviceCaps.allowES3OnFL10_0 = false;
+ mRenderer11DeviceCaps.supportsTypedUAVLoadAdditionalFormats = false;
+ mRenderer11DeviceCaps.supportsRasterizerOrderViews = false;
+ mRenderer11DeviceCaps.B5G6R5support = 0;
+ mRenderer11DeviceCaps.B4G4R4A4support = 0;
+ mRenderer11DeviceCaps.B5G5R5A1support = 0;
+
+ mD3d11Module = nullptr;
+ mD3d12Module = nullptr;
+ mDxgiModule = nullptr;
+ mDCompModule = nullptr;
+ mCreatedWithDeviceEXT = false;
+
+ mDevice = nullptr;
+ mDevice1 = nullptr;
+ mDeviceContext = nullptr;
+ mDeviceContext1 = nullptr;
+ mDeviceContext3 = nullptr;
+ mDxgiAdapter = nullptr;
+ mDxgiFactory = nullptr;
+
+ ZeroMemory(&mAdapterDescription, sizeof(mAdapterDescription));
+
+ const auto &attributes = mDisplay->getAttributeMap();
+
+ if (mDisplay->getPlatform() == EGL_PLATFORM_ANGLE_ANGLE)
+ {
+ EGLint requestedMajorVersion = static_cast<EGLint>(
+ attributes.get(EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, EGL_DONT_CARE));
+ EGLint requestedMinorVersion = static_cast<EGLint>(
+ attributes.get(EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, EGL_DONT_CARE));
+
+ if (requestedMajorVersion == EGL_DONT_CARE || requestedMajorVersion >= 11)
+ {
+ if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 1)
+ {
+ // This could potentially lead to failed context creation if done on a system
+ // without the platform update which installs DXGI 1.2. Currently, for Chrome users
+ // D3D11 contexts are only created if the platform update is available, so this
+ // should not cause any issues.
+ mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_11_1);
+ }
+ if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 0)
+ {
+ mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_11_0);
+ }
+ }
+
+ if (requestedMajorVersion == EGL_DONT_CARE || requestedMajorVersion >= 10)
+ {
+ if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 1)
+ {
+ mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_10_1);
+ }
+ if (requestedMinorVersion == EGL_DONT_CARE || requestedMinorVersion >= 0)
+ {
+ mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_10_0);
+ }
+ }
+
+ if (requestedMajorVersion == 9 && requestedMinorVersion == 3)
+ {
+ mAvailableFeatureLevels.push_back(D3D_FEATURE_LEVEL_9_3);
+ }
+
+ EGLint requestedDeviceType = static_cast<EGLint>(attributes.get(
+ EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE));
+ switch (requestedDeviceType)
+ {
+ case EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE:
+ mRequestedDriverType = D3D_DRIVER_TYPE_HARDWARE;
+ break;
+
+ case EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE:
+ mRequestedDriverType = D3D_DRIVER_TYPE_WARP;
+ break;
+
+ case EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_REFERENCE_ANGLE:
+ mRequestedDriverType = D3D_DRIVER_TYPE_REFERENCE;
+ break;
+
+ case EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE:
+ mRequestedDriverType = D3D_DRIVER_TYPE_NULL;
+ break;
+
+ default:
+ UNREACHABLE();
+ }
+
+ mCreateDebugDevice = ShouldUseDebugLayers(attributes);
+ }
+ else if (mDisplay->getPlatform() == EGL_PLATFORM_DEVICE_EXT)
+ {
+ ASSERT(mDisplay->getDevice() != nullptr);
+ mCreatedWithDeviceEXT = true;
+
+ // Also set EGL_PLATFORM_ANGLE_ANGLE variables, in case they're used elsewhere in ANGLE
+ // mAvailableFeatureLevels defaults to empty
+ mRequestedDriverType = D3D_DRIVER_TYPE_UNKNOWN;
+ }
+
+ const EGLenum presentPath = static_cast<EGLenum>(attributes.get(
+ EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE, EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE));
+ mPresentPathFastEnabled = (presentPath == EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE);
+}
+
+Renderer11::~Renderer11()
+{
+ release();
+}
+
+#ifndef __d3d11_1_h__
+# define D3D11_MESSAGE_ID_DEVICE_DRAW_RENDERTARGETVIEW_NOT_SET ((D3D11_MESSAGE_ID)3146081)
+#endif
+
+egl::Error Renderer11::initialize()
+{
+ HRESULT result = S_OK;
+
+ ANGLE_TRY(initializeD3DDevice());
+
+#if !defined(ANGLE_ENABLE_WINDOWS_UWP)
+# if !ANGLE_SKIP_DXGI_1_2_CHECK
+ {
+ ANGLE_TRACE_EVENT0("gpu.angle", "Renderer11::initialize (DXGICheck)");
+ // In order to create a swap chain for an HWND owned by another process, DXGI 1.2 is
+ // required.
+ // The easiest way to check is to query for a IDXGIDevice2.
+ bool requireDXGI1_2 = false;
+ HWND hwnd = WindowFromDC(mDisplay->getNativeDisplayId());
+ if (hwnd)
+ {
+ DWORD currentProcessId = GetCurrentProcessId();
+ DWORD wndProcessId;
+ GetWindowThreadProcessId(hwnd, &wndProcessId);
+ requireDXGI1_2 = (currentProcessId != wndProcessId);
+ }
+ else
+ {
+ requireDXGI1_2 = true;
+ }
+
+ if (requireDXGI1_2)
+ {
+ IDXGIDevice2 *dxgiDevice2 = nullptr;
+ result = mDevice->QueryInterface(__uuidof(IDXGIDevice2), (void **)&dxgiDevice2);
+ if (FAILED(result))
+ {
+ return egl::EglNotInitialized(D3D11_INIT_INCOMPATIBLE_DXGI)
+ << "DXGI 1.2 required to present to HWNDs owned by another process.";
+ }
+ SafeRelease(dxgiDevice2);
+ }
+ }
+# endif
+#endif
+
+ {
+ ANGLE_TRACE_EVENT0("gpu.angle", "Renderer11::initialize (ComQueries)");
+ // Cast the DeviceContext to a DeviceContext1 and DeviceContext3.
+ // This could fail on Windows 7 without the Platform Update.
+ // Don't error in this case- just don't use mDeviceContext1 or mDeviceContext3.
+ mDeviceContext1 = d3d11::DynamicCastComObject<ID3D11DeviceContext1>(mDeviceContext);
+ mDeviceContext3 = d3d11::DynamicCastComObject<ID3D11DeviceContext3>(mDeviceContext);
+
+ IDXGIDevice *dxgiDevice = nullptr;
+ result = mDevice->QueryInterface(__uuidof(IDXGIDevice), (void **)&dxgiDevice);
+
+ if (FAILED(result))
+ {
+ return egl::EglNotInitialized(D3D11_INIT_OTHER_ERROR) << "Could not query DXGI device.";
+ }
+
+ result = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void **)&mDxgiAdapter);
+
+ if (FAILED(result))
+ {
+ return egl::EglNotInitialized(D3D11_INIT_OTHER_ERROR)
+ << "Could not retrieve DXGI adapter";
+ }
+
+ SafeRelease(dxgiDevice);
+
+ IDXGIAdapter2 *dxgiAdapter2 = d3d11::DynamicCastComObject<IDXGIAdapter2>(mDxgiAdapter);
+
+ // On D3D_FEATURE_LEVEL_9_*, IDXGIAdapter::GetDesc returns "Software Adapter" for the
+ // description string.
+ // If DXGI1.2 is available then IDXGIAdapter2::GetDesc2 can be used to get the actual
+ // hardware values.
+ if (mRenderer11DeviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3 && dxgiAdapter2 != nullptr)
+ {
+ DXGI_ADAPTER_DESC2 adapterDesc2 = {};
+ result = dxgiAdapter2->GetDesc2(&adapterDesc2);
+ if (SUCCEEDED(result))
+ {
+ // Copy the contents of the DXGI_ADAPTER_DESC2 into mAdapterDescription (a
+ // DXGI_ADAPTER_DESC).
+ memcpy(mAdapterDescription.Description, adapterDesc2.Description,
+ sizeof(mAdapterDescription.Description));
+ mAdapterDescription.VendorId = adapterDesc2.VendorId;
+ mAdapterDescription.DeviceId = adapterDesc2.DeviceId;
+ mAdapterDescription.SubSysId = adapterDesc2.SubSysId;
+ mAdapterDescription.Revision = adapterDesc2.Revision;
+ mAdapterDescription.DedicatedVideoMemory = adapterDesc2.DedicatedVideoMemory;
+ mAdapterDescription.DedicatedSystemMemory = adapterDesc2.DedicatedSystemMemory;
+ mAdapterDescription.SharedSystemMemory = adapterDesc2.SharedSystemMemory;
+ mAdapterDescription.AdapterLuid = adapterDesc2.AdapterLuid;
+ }
+ }
+ else
+ {
+ result = mDxgiAdapter->GetDesc(&mAdapterDescription);
+ }
+
+ SafeRelease(dxgiAdapter2);
+
+ if (FAILED(result))
+ {
+ return egl::EglNotInitialized(D3D11_INIT_OTHER_ERROR)
+ << "Could not read DXGI adaptor description.";
+ }
+
+ memset(mDescription, 0, sizeof(mDescription));
+ wcstombs(mDescription, mAdapterDescription.Description, sizeof(mDescription) - 1);
+
+ result = mDxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void **)&mDxgiFactory);
+
+ if (!mDxgiFactory || FAILED(result))
+ {
+ return egl::EglNotInitialized(D3D11_INIT_OTHER_ERROR)
+ << "Could not create DXGI factory.";
+ }
+ }
+
+ // Disable some spurious D3D11 debug warnings to prevent them from flooding the output log
+ if (mCreateDebugDevice)
+ {
+ ANGLE_TRACE_EVENT0("gpu.angle", "Renderer11::initialize (HideWarnings)");
+ ID3D11InfoQueue *infoQueue;
+ result = mDevice->QueryInterface(__uuidof(ID3D11InfoQueue), (void **)&infoQueue);
+
+ if (SUCCEEDED(result))
+ {
+ D3D11_MESSAGE_ID hideMessages[] = {
+ D3D11_MESSAGE_ID_DEVICE_DRAW_RENDERTARGETVIEW_NOT_SET,
+
+ // Robust access behaviour makes out of bounds messages safe
+ D3D11_MESSAGE_ID_DEVICE_DRAW_VERTEX_BUFFER_TOO_SMALL,
+ };
+
+ D3D11_INFO_QUEUE_FILTER filter = {};
+ filter.DenyList.NumIDs = static_cast<unsigned int>(ArraySize(hideMessages));
+ filter.DenyList.pIDList = hideMessages;
+
+ infoQueue->AddStorageFilterEntries(&filter);
+ SafeRelease(infoQueue);
+ }
+ }
+
+#if !defined(NDEBUG)
+ mDebug = d3d11::DynamicCastComObject<ID3D11Debug>(mDevice);
+#endif
+
+ ANGLE_TRY(initializeDevice());
+
+ return egl::NoError();
+}
+
+HRESULT Renderer11::callD3D11CreateDevice(PFN_D3D11_CREATE_DEVICE createDevice, bool debug)
+{
+ angle::ComPtr<IDXGIAdapter> adapter;
+
+ const egl::AttributeMap &attributes = mDisplay->getAttributeMap();
+ // Check EGL_ANGLE_platform_angle_d3d_luid
+ long high = static_cast<long>(attributes.get(EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE, 0));
+ unsigned long low =
+ static_cast<unsigned long>(attributes.get(EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE, 0));
+ // Check EGL_ANGLE_platform_angle_device_id
+ if (high == 0 && low == 0)
+ {
+ high = static_cast<long>(attributes.get(EGL_PLATFORM_ANGLE_DEVICE_ID_HIGH_ANGLE, 0));
+ low = static_cast<unsigned long>(attributes.get(EGL_PLATFORM_ANGLE_DEVICE_ID_LOW_ANGLE, 0));
+ }
+ if (high != 0 || low != 0)
+ {
+ angle::ComPtr<IDXGIFactory1> factory;
+ if (SUCCEEDED(CreateDXGIFactory1(IID_PPV_ARGS(&factory))))
+ {
+ angle::ComPtr<IDXGIAdapter> temp;
+ for (UINT i = 0; SUCCEEDED(factory->EnumAdapters(i, &temp)); i++)
+ {
+ DXGI_ADAPTER_DESC desc;
+ if (SUCCEEDED(temp->GetDesc(&desc)))
+ {
+ // EGL_ANGLE_platform_angle_d3d_luid
+ if (desc.AdapterLuid.HighPart == high && desc.AdapterLuid.LowPart == low)
+ {
+ adapter = temp;
+ break;
+ }
+
+ // EGL_ANGLE_platform_angle_device_id
+ // NOTE: If there are multiple GPUs with the same PCI
+ // vendor and device IDs, this will arbitrarily choose one
+ // of them. To select a specific GPU, use the LUID instead.
+ if ((high == 0 || desc.VendorId == static_cast<UINT>(high)) &&
+ (low == 0 || desc.DeviceId == static_cast<UINT>(low)))
+ {
+ adapter = temp;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ // If adapter is not nullptr, the driver type must be D3D_DRIVER_TYPE_UNKNOWN or
+ // D3D11CreateDevice will return E_INVALIDARG.
+ return createDevice(
+ adapter.Get(), adapter ? D3D_DRIVER_TYPE_UNKNOWN : mRequestedDriverType, nullptr,
+ debug ? D3D11_CREATE_DEVICE_DEBUG : 0, mAvailableFeatureLevels.data(),
+ static_cast<unsigned int>(mAvailableFeatureLevels.size()), D3D11_SDK_VERSION, &mDevice,
+ &(mRenderer11DeviceCaps.featureLevel), &mDeviceContext);
+}
+
+HRESULT Renderer11::callD3D11On12CreateDevice(PFN_D3D12_CREATE_DEVICE createDevice12,
+ PFN_D3D11ON12_CREATE_DEVICE createDevice11on12,
+ bool debug)
+{
+ angle::ComPtr<IDXGIFactory4> factory;
+ HRESULT result = CreateDXGIFactory1(IID_PPV_ARGS(&factory));
+ if (FAILED(result))
+ {
+ return result;
+ }
+
+ if (mRequestedDriverType == D3D_DRIVER_TYPE_WARP)
+ {
+ angle::ComPtr<IDXGIAdapter> warpAdapter;
+ result = factory->EnumWarpAdapter(IID_PPV_ARGS(&warpAdapter));
+ if (SUCCEEDED(result))
+ {
+ result = createDevice12(warpAdapter.Get(), mAvailableFeatureLevels[0],
+ IID_PPV_ARGS(&mDevice12));
+ }
+ }
+ else
+ {
+ // Passing nullptr into pAdapter chooses the default adapter which will be the hardware
+ // adapter if it exists.
+ result = createDevice12(nullptr, mAvailableFeatureLevels[0], IID_PPV_ARGS(&mDevice12));
+ }
+
+ if (SUCCEEDED(result))
+ {
+ D3D12_COMMAND_QUEUE_DESC queueDesc = {};
+ queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
+ queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
+ result = mDevice12->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&mCommandQueue));
+ }
+
+ if (SUCCEEDED(result))
+ {
+ result = createDevice11on12(
+ mDevice12.Get(), debug ? D3D11_CREATE_DEVICE_DEBUG : 0, mAvailableFeatureLevels.data(),
+ static_cast<unsigned int>(mAvailableFeatureLevels.size()),
+ reinterpret_cast<IUnknown **>(mCommandQueue.GetAddressOf()), 1 /* NumQueues */,
+ 0 /* NodeMask */, &mDevice, &mDeviceContext, &(mRenderer11DeviceCaps.featureLevel));
+ }
+
+ return result;
+}
+
+egl::Error Renderer11::initializeD3DDevice()
+{
+ HRESULT result = S_OK;
+ bool createD3D11on12Device = false;
+
+ if (!mCreatedWithDeviceEXT)
+ {
+#if !defined(ANGLE_ENABLE_WINDOWS_UWP)
+ PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = nullptr;
+ PFN_D3D12_CREATE_DEVICE D3D12CreateDevice = nullptr;
+ PFN_D3D11ON12_CREATE_DEVICE D3D11On12CreateDevice = nullptr;
+ {
+ ANGLE_TRACE_EVENT0("gpu.angle", "Renderer11::initialize (Load DLLs)");
+ mDxgiModule = LoadLibrary(TEXT("dxgi.dll"));
+ mD3d11Module = LoadLibrary(TEXT("d3d11.dll"));
+ mDCompModule = LoadLibrary(TEXT("dcomp.dll"));
+
+ // create the D3D11 device
+ ASSERT(mDevice == nullptr);
+
+ const egl::AttributeMap &attributes = mDisplay->getAttributeMap();
+ createD3D11on12Device =
+ attributes.get(EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE, EGL_FALSE) == EGL_TRUE;
+
+ if (createD3D11on12Device)
+ {
+ mD3d12Module = LoadLibrary(TEXT("d3d12.dll"));
+ if (mD3d12Module == nullptr)
+ {
+ return egl::EglNotInitialized(D3D11_INIT_MISSING_DEP)
+ << "Could not load D3D12 library.";
+ }
+
+ D3D12CreateDevice = reinterpret_cast<PFN_D3D12_CREATE_DEVICE>(
+ GetProcAddress(mD3d12Module, "D3D12CreateDevice"));
+ if (D3D12CreateDevice == nullptr)
+ {
+ return egl::EglNotInitialized(D3D11_INIT_MISSING_DEP)
+ << "Could not retrieve D3D12CreateDevice address.";
+ }
+
+ D3D11On12CreateDevice = reinterpret_cast<PFN_D3D11ON12_CREATE_DEVICE>(
+ GetProcAddress(mD3d11Module, "D3D11On12CreateDevice"));
+ if (D3D11On12CreateDevice == nullptr)
+ {
+ return egl::EglNotInitialized(D3D11_INIT_MISSING_DEP)
+ << "Could not retrieve D3D11On12CreateDevice address.";
+ }
+ }
+ else
+ {
+ if (mD3d11Module == nullptr || mDxgiModule == nullptr)
+ {
+ return egl::EglNotInitialized(D3D11_INIT_MISSING_DEP)
+ << "Could not load D3D11 or DXGI library.";
+ }
+
+ D3D11CreateDevice = reinterpret_cast<PFN_D3D11_CREATE_DEVICE>(
+ GetProcAddress(mD3d11Module, "D3D11CreateDevice"));
+
+ if (D3D11CreateDevice == nullptr)
+ {
+ return egl::EglNotInitialized(D3D11_INIT_MISSING_DEP)
+ << "Could not retrieve D3D11CreateDevice address.";
+ }
+ }
+ }
+#endif
+
+ if (mCreateDebugDevice)
+ {
+ ANGLE_TRACE_EVENT0("gpu.angle", "D3D11CreateDevice (Debug)");
+ if (createD3D11on12Device)
+ {
+ result = callD3D11On12CreateDevice(D3D12CreateDevice, D3D11On12CreateDevice, true);
+ }
+ else
+ {
+ result = callD3D11CreateDevice(D3D11CreateDevice, true);
+ }
+
+ if (result == E_INVALIDARG && mAvailableFeatureLevels.size() > 1u &&
+ mAvailableFeatureLevels[0] == D3D_FEATURE_LEVEL_11_1)
+ {
+ // On older Windows platforms, D3D11.1 is not supported which returns E_INVALIDARG.
+ // Try again without passing D3D_FEATURE_LEVEL_11_1 in case we have other feature
+ // levels to fall back on.
+ mAvailableFeatureLevels.erase(mAvailableFeatureLevels.begin());
+ if (createD3D11on12Device)
+ {
+ result =
+ callD3D11On12CreateDevice(D3D12CreateDevice, D3D11On12CreateDevice, true);
+ }
+ else
+ {
+ result = callD3D11CreateDevice(D3D11CreateDevice, true);
+ }
+ }
+
+ if (!mDevice || FAILED(result))
+ {
+ WARN() << "Failed creating Debug D3D11 device - falling back to release runtime.";
+ }
+ }
+
+ if (!mDevice || FAILED(result))
+ {
+ ANGLE_TRACE_EVENT0("gpu.angle", "D3D11CreateDevice");
+ if (createD3D11on12Device)
+ {
+ result = callD3D11On12CreateDevice(D3D12CreateDevice, D3D11On12CreateDevice, false);
+ }
+ else
+ {
+ result = callD3D11CreateDevice(D3D11CreateDevice, false);
+ }
+
+ if (result == E_INVALIDARG && mAvailableFeatureLevels.size() > 1u &&
+ mAvailableFeatureLevels[0] == D3D_FEATURE_LEVEL_11_1)
+ {
+ // On older Windows platforms, D3D11.1 is not supported which returns E_INVALIDARG.
+ // Try again without passing D3D_FEATURE_LEVEL_11_1 in case we have other feature
+ // levels to fall back on.
+ mAvailableFeatureLevels.erase(mAvailableFeatureLevels.begin());
+ if (createD3D11on12Device)
+ {
+ result =
+ callD3D11On12CreateDevice(D3D12CreateDevice, D3D11On12CreateDevice, false);
+ }
+ else
+ {
+ result = callD3D11CreateDevice(D3D11CreateDevice, false);
+ }
+ }
+
+ // Cleanup done by destructor
+ if (!mDevice || FAILED(result))
+ {
+ ANGLE_HISTOGRAM_SPARSE_SLOWLY("GPU.ANGLE.D3D11CreateDeviceError",
+ static_cast<int>(result));
+ return egl::EglNotInitialized(D3D11_INIT_CREATEDEVICE_ERROR)
+ << "Could not create D3D11 device.";
+ }
+ }
+ }
+ else
+ {
+ DeviceD3D *deviceD3D = GetImplAs<DeviceD3D>(mDisplay->getDevice());
+ ASSERT(deviceD3D != nullptr);
+
+ // We should use the inputted D3D11 device instead
+ void *device = nullptr;
+ ANGLE_TRY(deviceD3D->getAttribute(mDisplay, EGL_D3D11_DEVICE_ANGLE, &device));
+
+ ID3D11Device *d3dDevice = static_cast<ID3D11Device *>(device);
+ if (FAILED(d3dDevice->GetDeviceRemovedReason()))
+ {
+ return egl::EglNotInitialized() << "Inputted D3D11 device has been lost.";
+ }
+
+ if (d3dDevice->GetFeatureLevel() < D3D_FEATURE_LEVEL_9_3)
+ {
+ return egl::EglNotInitialized()
+ << "Inputted D3D11 device must be Feature Level 9_3 or greater.";
+ }
+
+ // The Renderer11 adds a ref to the inputted D3D11 device, like D3D11CreateDevice does.
+ mDevice = d3dDevice;
+ mDevice->AddRef();
+ mDevice->GetImmediateContext(&mDeviceContext);
+ mRenderer11DeviceCaps.featureLevel = mDevice->GetFeatureLevel();
+ }
+
+ mResourceManager11.setAllocationsInitialized(mCreateDebugDevice);
+
+ d3d11::SetDebugName(mDeviceContext, "DeviceContext", nullptr);
+
+ mAnnotatorContext.initialize(mDeviceContext);
+
+ mDevice->QueryInterface(__uuidof(ID3D11Device1), reinterpret_cast<void **>(&mDevice1));
+
+ return egl::NoError();
+}
+
+void Renderer11::setGlobalDebugAnnotator()
+{
+ static angle::base::NoDestructor<std::mutex> gMutex;
+ static angle::base::NoDestructor<DebugAnnotator11> gGlobalAnnotator;
+
+ std::lock_guard<std::mutex> lg(*gMutex);
+ gl::InitializeDebugAnnotations(gGlobalAnnotator.get());
+}
+
+// do any one-time device initialization
+// NOTE: this is also needed after a device lost/reset
+// to reset the scene status and ensure the default states are reset.
+egl::Error Renderer11::initializeDevice()
+{
+ ANGLE_TRACE_EVENT0("gpu.angle", "Renderer11::initializeDevice");
+
+ populateRenderer11DeviceCaps();
+
+ mStateCache.clear();
+
+ ASSERT(!mBlit);
+ mBlit = new Blit11(this);
+
+ ASSERT(!mClear);
+ mClear = new Clear11(this);
+
+ const auto &attributes = mDisplay->getAttributeMap();
+ // If automatic trim is enabled, DXGIDevice3::Trim( ) is called for the application
+ // automatically when an application is suspended by the OS. This feature is currently
+ // only supported for Windows Store applications.
+ EGLint enableAutoTrim = static_cast<EGLint>(
+ attributes.get(EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_FALSE));
+
+ if (enableAutoTrim == EGL_TRUE)
+ {
+ ASSERT(!mTrim);
+ mTrim = new Trim11(this);
+ }
+
+ ASSERT(!mPixelTransfer);
+ mPixelTransfer = new PixelTransfer11(this);
+
+ // Gather stats on DXGI and D3D feature level
+ ANGLE_HISTOGRAM_BOOLEAN("GPU.ANGLE.SupportsDXGI1_2", mRenderer11DeviceCaps.supportsDXGI1_2);
+
+ ANGLEFeatureLevel angleFeatureLevel = GetANGLEFeatureLevel(mRenderer11DeviceCaps.featureLevel);
+
+ // We don't actually request a 11_1 device, because of complications with the platform
+ // update. Instead we check if the mDeviceContext1 pointer cast succeeded.
+ // Note: we should support D3D11_0 always, but we aren't guaranteed to be at FL11_0
+ // because the app can specify a lower version (such as 9_3) on Display creation.
+ if (mDeviceContext1 != nullptr)
+ {
+ angleFeatureLevel = ANGLE_FEATURE_LEVEL_11_1;
+ }
+
+ ANGLE_HISTOGRAM_ENUMERATION("GPU.ANGLE.D3D11FeatureLevel", angleFeatureLevel,
+ NUM_ANGLE_FEATURE_LEVELS);
+
+ return egl::NoError();
+}
+
+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;
+ HRESULT result = mDevice->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS, &d3d11Options,
+ sizeof(D3D11_FEATURE_DATA_D3D11_OPTIONS));
+ if (SUCCEEDED(result))
+ {
+ mRenderer11DeviceCaps.supportsClearView = (d3d11Options.ClearView != FALSE);
+ mRenderer11DeviceCaps.supportsConstantBufferOffsets =
+ (d3d11Options.ConstantBufferOffsetting != FALSE);
+ }
+ }
+
+ if (mDeviceContext3)
+ {
+ D3D11_FEATURE_DATA_D3D11_OPTIONS3 d3d11Options3;
+ HRESULT result = mDevice->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS3, &d3d11Options3,
+ sizeof(D3D11_FEATURE_DATA_D3D11_OPTIONS3));
+ if (SUCCEEDED(result))
+ {
+ mRenderer11DeviceCaps.supportsVpRtIndexWriteFromVertexShader =
+ (d3d11Options3.VPAndRTArrayIndexFromAnyShaderFeedingRasterizer == TRUE);
+ }
+ D3D11_FEATURE_DATA_D3D11_OPTIONS2 d3d11Options2;
+ result = mDevice->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS2, &d3d11Options2,
+ sizeof(D3D11_FEATURE_DATA_D3D11_OPTIONS2));
+ if (SUCCEEDED(result))
+ {
+ mRenderer11DeviceCaps.supportsTypedUAVLoadAdditionalFormats =
+ d3d11Options2.TypedUAVLoadAdditionalFormats;
+ if (!getFeatures().disableRasterizerOrderViews.enabled)
+ {
+ mRenderer11DeviceCaps.supportsRasterizerOrderViews = d3d11Options2.ROVsSupported;
+ }
+ }
+ }
+
+ mRenderer11DeviceCaps.supportsMultisampledDepthStencilSRVs =
+ mRenderer11DeviceCaps.featureLevel > D3D_FEATURE_LEVEL_10_0;
+
+ if (getFeatures().disableB5G6R5Support.enabled)
+ {
+ mRenderer11DeviceCaps.B5G6R5support = 0;
+ mRenderer11DeviceCaps.B5G6R5maxSamples = 0;
+ }
+ else
+ {
+ PopulateFormatDeviceCaps(mDevice, DXGI_FORMAT_B5G6R5_UNORM,
+ &mRenderer11DeviceCaps.B5G6R5support,
+ &mRenderer11DeviceCaps.B5G6R5maxSamples);
+ }
+
+ if (getFeatures().allowES3OnFL100.enabled)
+ {
+ mRenderer11DeviceCaps.allowES3OnFL10_0 = true;
+ }
+
+ PopulateFormatDeviceCaps(mDevice, DXGI_FORMAT_B4G4R4A4_UNORM,
+ &mRenderer11DeviceCaps.B4G4R4A4support,
+ &mRenderer11DeviceCaps.B4G4R4A4maxSamples);
+ PopulateFormatDeviceCaps(mDevice, DXGI_FORMAT_B5G5R5A1_UNORM,
+ &mRenderer11DeviceCaps.B5G5R5A1support,
+ &mRenderer11DeviceCaps.B5G5R5A1maxSamples);
+
+ IDXGIAdapter2 *dxgiAdapter2 = d3d11::DynamicCastComObject<IDXGIAdapter2>(mDxgiAdapter);
+ mRenderer11DeviceCaps.supportsDXGI1_2 = (dxgiAdapter2 != nullptr);
+ SafeRelease(dxgiAdapter2);
+}
+
+gl::SupportedSampleSet Renderer11::generateSampleSetForEGLConfig(
+ const gl::TextureCaps &colorBufferFormatCaps,
+ const gl::TextureCaps &depthStencilBufferFormatCaps) const
+{
+ gl::SupportedSampleSet sampleCounts;
+
+ // Generate a new set from the set intersection of sample counts between the color and depth
+ // format caps.
+ std::set_intersection(colorBufferFormatCaps.sampleCounts.begin(),
+ colorBufferFormatCaps.sampleCounts.end(),
+ depthStencilBufferFormatCaps.sampleCounts.begin(),
+ depthStencilBufferFormatCaps.sampleCounts.end(),
+ std::inserter(sampleCounts, sampleCounts.begin()));
+
+ // Format of GL_NONE results in no supported sample counts.
+ // Add back the color sample counts to the supported sample set.
+ if (depthStencilBufferFormatCaps.sampleCounts.empty())
+ {
+ sampleCounts = colorBufferFormatCaps.sampleCounts;
+ }
+ else if (colorBufferFormatCaps.sampleCounts.empty())
+ {
+ // Likewise, add back the depth sample counts to the supported sample set.
+ sampleCounts = depthStencilBufferFormatCaps.sampleCounts;
+ }
+
+ // Always support 0 samples
+ sampleCounts.insert(0);
+
+ return sampleCounts;
+}
+
+egl::ConfigSet Renderer11::generateConfigs()
+{
+ std::vector<GLenum> colorBufferFormats;
+
+ // 32-bit supported formats
+ colorBufferFormats.push_back(GL_BGRA8_EXT);
+ colorBufferFormats.push_back(GL_RGBA8_OES);
+
+ // 24-bit supported formats
+ colorBufferFormats.push_back(GL_RGB8_OES);
+
+ if (mRenderer11DeviceCaps.featureLevel >= D3D_FEATURE_LEVEL_10_0)
+ {
+ // Additional high bit depth formats added in D3D 10.0
+ // https://msdn.microsoft.com/en-us/library/windows/desktop/bb173064.aspx
+ colorBufferFormats.push_back(GL_RGBA16F);
+ colorBufferFormats.push_back(GL_RGB10_A2);
+ }
+
+ if (!mPresentPathFastEnabled)
+ {
+ // 16-bit supported formats
+ // These aren't valid D3D11 swapchain formats, so don't expose them as configs
+ // if present path fast is active
+ colorBufferFormats.push_back(GL_RGBA4);
+ colorBufferFormats.push_back(GL_RGB5_A1);
+ colorBufferFormats.push_back(GL_RGB565);
+ }
+
+ static const GLenum depthStencilBufferFormats[] = {
+ GL_NONE, GL_DEPTH24_STENCIL8_OES, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT16,
+ GL_STENCIL_INDEX8,
+ };
+
+ const gl::Caps &rendererCaps = getNativeCaps();
+ const gl::TextureCapsMap &rendererTextureCaps = getNativeTextureCaps();
+
+ const EGLint optimalSurfaceOrientation =
+ mPresentPathFastEnabled ? 0 : EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE;
+
+ egl::ConfigSet configs;
+ for (GLenum colorBufferInternalFormat : colorBufferFormats)
+ {
+ const gl::TextureCaps &colorBufferFormatCaps =
+ rendererTextureCaps.get(colorBufferInternalFormat);
+ if (!colorBufferFormatCaps.renderbuffer)
+ {
+ ASSERT(!colorBufferFormatCaps.textureAttachment);
+ continue;
+ }
+
+ for (GLenum depthStencilBufferInternalFormat : depthStencilBufferFormats)
+ {
+ const gl::TextureCaps &depthStencilBufferFormatCaps =
+ rendererTextureCaps.get(depthStencilBufferInternalFormat);
+ if (!depthStencilBufferFormatCaps.renderbuffer &&
+ depthStencilBufferInternalFormat != GL_NONE)
+ {
+ ASSERT(!depthStencilBufferFormatCaps.textureAttachment);
+ continue;
+ }
+
+ const gl::InternalFormat &colorBufferFormatInfo =
+ gl::GetSizedInternalFormatInfo(colorBufferInternalFormat);
+ const gl::InternalFormat &depthStencilBufferFormatInfo =
+ gl::GetSizedInternalFormatInfo(depthStencilBufferInternalFormat);
+ const gl::Version &maxVersion = getMaxSupportedESVersion();
+
+ const gl::SupportedSampleSet sampleCounts =
+ generateSampleSetForEGLConfig(colorBufferFormatCaps, depthStencilBufferFormatCaps);
+
+ for (GLuint sampleCount : sampleCounts)
+ {
+ egl::Config config;
+ config.renderTargetFormat = colorBufferInternalFormat;
+ config.depthStencilFormat = depthStencilBufferInternalFormat;
+ config.bufferSize = colorBufferFormatInfo.pixelBytes * 8;
+ config.redSize = colorBufferFormatInfo.redBits;
+ config.greenSize = colorBufferFormatInfo.greenBits;
+ config.blueSize = colorBufferFormatInfo.blueBits;
+ config.luminanceSize = colorBufferFormatInfo.luminanceBits;
+ config.alphaSize = colorBufferFormatInfo.alphaBits;
+ config.alphaMaskSize = 0;
+ config.bindToTextureRGB =
+ ((colorBufferFormatInfo.format == GL_RGB) && (sampleCount <= 1));
+ config.bindToTextureRGBA = (((colorBufferFormatInfo.format == GL_RGBA) ||
+ (colorBufferFormatInfo.format == GL_BGRA_EXT)) &&
+ (sampleCount <= 1));
+ config.colorBufferType = EGL_RGB_BUFFER;
+ config.configCaveat = EGL_NONE;
+ config.configID = static_cast<EGLint>(configs.size() + 1);
+
+ // PresentPathFast may not be conformant
+ config.conformant = 0;
+ if (!mPresentPathFastEnabled)
+ {
+ // 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;
+ config.level = 0;
+ config.matchNativePixmap = EGL_NONE;
+ config.maxPBufferWidth = rendererCaps.max2DTextureSize;
+ config.maxPBufferHeight = rendererCaps.max2DTextureSize;
+ config.maxPBufferPixels =
+ rendererCaps.max2DTextureSize * rendererCaps.max2DTextureSize;
+ config.maxSwapInterval = 4;
+ config.minSwapInterval = 0;
+ config.nativeRenderable = EGL_FALSE;
+ config.nativeVisualID = 0;
+ config.nativeVisualType = EGL_NONE;
+
+ // 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 = (sampleCount == 0) ? 0 : 1;
+ config.samples = sampleCount;
+ config.stencilSize = depthStencilBufferFormatInfo.stencilBits;
+ config.surfaceType =
+ EGL_PBUFFER_BIT | EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
+ config.transparentType = EGL_NONE;
+ config.transparentRedValue = 0;
+ config.transparentGreenValue = 0;
+ config.transparentBlueValue = 0;
+ config.optimalOrientation = optimalSurfaceOrientation;
+ config.colorComponentType = gl_egl::GLComponentTypeToEGLColorComponentType(
+ colorBufferFormatInfo.componentType);
+
+ configs.add(config);
+ }
+ }
+ }
+
+ ASSERT(configs.size() > 0);
+ return configs;
+}
+
+void Renderer11::generateDisplayExtensions(egl::DisplayExtensions *outExtensions) const
+{
+ outExtensions->createContextRobustness = true;
+
+ if (getShareHandleSupport())
+ {
+ outExtensions->d3dShareHandleClientBuffer = true;
+ outExtensions->surfaceD3DTexture2DShareHandle = true;
+ }
+ outExtensions->d3dTextureClientBuffer = true;
+ outExtensions->imageD3D11Texture = true;
+
+ outExtensions->keyedMutex = true;
+ outExtensions->querySurfacePointer = true;
+ outExtensions->windowFixedSize = true;
+
+ // If present path fast is active then the surface orientation extension isn't supported
+ outExtensions->surfaceOrientation = !mPresentPathFastEnabled;
+
+ // D3D11 does not support present with dirty rectangles until DXGI 1.2.
+ outExtensions->postSubBuffer = mRenderer11DeviceCaps.supportsDXGI1_2;
+
+ outExtensions->image = true;
+ outExtensions->imageBase = true;
+ outExtensions->glTexture2DImage = true;
+ outExtensions->glTextureCubemapImage = true;
+ outExtensions->glRenderbufferImage = true;
+
+ outExtensions->stream = true;
+ outExtensions->streamConsumerGLTexture = true;
+ outExtensions->streamConsumerGLTextureYUV = true;
+ outExtensions->streamProducerD3DTexture = true;
+
+ outExtensions->noConfigContext = true;
+ outExtensions->directComposition = !!mDCompModule;
+
+ // Contexts are virtualized so textures and semaphores can be shared globally
+ outExtensions->displayTextureShareGroup = true;
+ outExtensions->displaySemaphoreShareGroup = true;
+
+ // syncControlCHROMIUM requires direct composition.
+ outExtensions->syncControlCHROMIUM = outExtensions->directComposition;
+
+ // D3D11 can be used without a swap chain
+ outExtensions->surfacelessContext = true;
+
+ // All D3D feature levels support robust resource init
+ outExtensions->robustResourceInitializationANGLE = true;
+
+#ifdef ANGLE_ENABLE_D3D11_COMPOSITOR_NATIVE_WINDOW
+ // Compositor Native Window capabilies require WinVer >= 1803
+ if (CompositorNativeWindow11::IsSupportedWinRelease())
+ {
+ outExtensions->windowsUIComposition = true;
+ }
+#endif
+}
+
+angle::Result Renderer11::flush(Context11 *context11)
+{
+ mDeviceContext->Flush();
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer11::finish(Context11 *context11)
+{
+ if (!mSyncQuery.valid())
+ {
+ D3D11_QUERY_DESC queryDesc;
+ queryDesc.Query = D3D11_QUERY_EVENT;
+ queryDesc.MiscFlags = 0;
+
+ ANGLE_TRY(allocateResource(context11, queryDesc, &mSyncQuery));
+ }
+
+ mDeviceContext->End(mSyncQuery.get());
+
+ HRESULT result = S_OK;
+ unsigned int attempt = 0;
+ do
+ {
+ unsigned int flushFrequency = 100;
+ UINT flags = (attempt % flushFrequency == 0) ? 0 : D3D11_ASYNC_GETDATA_DONOTFLUSH;
+ attempt++;
+
+ result = mDeviceContext->GetData(mSyncQuery.get(), nullptr, 0, flags);
+ ANGLE_TRY_HR(context11, result, "Failed to get event query data");
+
+ if (result == S_FALSE)
+ {
+ // Keep polling, but allow other threads to do something useful first
+ ScheduleYield();
+ }
+
+ // Attempt is incremented before checking if we should test for device loss so that device
+ // loss is not checked on the first iteration
+ bool checkDeviceLost = (attempt % kPollingD3DDeviceLostCheckFrequency) == 0;
+ if (checkDeviceLost && testDeviceLost())
+ {
+ mDisplay->notifyDeviceLost();
+ ANGLE_CHECK(context11, false, "Device was lost while waiting for sync.",
+ GL_OUT_OF_MEMORY);
+ }
+ } while (result == S_FALSE);
+
+ return angle::Result::Continue;
+}
+
+bool Renderer11::isValidNativeWindow(EGLNativeWindowType window) const
+{
+#if defined(ANGLE_ENABLE_WINDOWS_UWP)
+ if (NativeWindow11WinRT::IsValidNativeWindow(window))
+ {
+ return true;
+ }
+#else
+ if (NativeWindow11Win32::IsValidNativeWindow(window))
+ {
+ return true;
+ }
+#endif
+
+#ifdef ANGLE_ENABLE_D3D11_COMPOSITOR_NATIVE_WINDOW
+ static_assert(sizeof(ABI::Windows::UI::Composition::SpriteVisual *) == sizeof(HWND),
+ "Pointer size must match Window Handle size");
+ if (CompositorNativeWindow11::IsValidNativeWindow(window))
+ {
+ return true;
+ }
+#endif
+
+ return false;
+}
+
+NativeWindowD3D *Renderer11::createNativeWindow(EGLNativeWindowType window,
+ const egl::Config *config,
+ const egl::AttributeMap &attribs) const
+{
+#if defined(ANGLE_ENABLE_WINDOWS_UWP)
+ if (window == nullptr || NativeWindow11WinRT::IsValidNativeWindow(window))
+ {
+ return new NativeWindow11WinRT(window, config->alphaSize > 0);
+ }
+#else
+ if (window == nullptr || NativeWindow11Win32::IsValidNativeWindow(window))
+ {
+ return new NativeWindow11Win32(
+ window, config->alphaSize > 0,
+ attribs.get(EGL_DIRECT_COMPOSITION_ANGLE, EGL_FALSE) == EGL_TRUE);
+ }
+#endif
+
+#ifdef ANGLE_ENABLE_D3D11_COMPOSITOR_NATIVE_WINDOW
+ if (CompositorNativeWindow11::IsValidNativeWindow(window))
+ {
+ return new CompositorNativeWindow11(window, config->alphaSize > 0);
+ }
+#endif
+
+ UNREACHABLE();
+ return nullptr;
+}
+
+egl::Error Renderer11::getD3DTextureInfo(const egl::Config *configuration,
+ IUnknown *texture,
+ const egl::AttributeMap &attribs,
+ EGLint *width,
+ EGLint *height,
+ GLsizei *samples,
+ gl::Format *glFormat,
+ const angle::Format **angleFormat,
+ UINT *arraySlice) const
+{
+ angle::ComPtr<ID3D11Texture2D> d3dTexture =
+ d3d11::DynamicCastComObjectToComPtr<ID3D11Texture2D>(texture);
+ if (d3dTexture == nullptr)
+ {
+ return egl::EglBadParameter() << "client buffer is not a ID3D11Texture2D";
+ }
+
+ angle::ComPtr<ID3D11Device> textureDevice;
+ d3dTexture->GetDevice(&textureDevice);
+ if (textureDevice.Get() != mDevice)
+ {
+ return egl::EglBadParameter() << "Texture's device does not match.";
+ }
+
+ D3D11_TEXTURE2D_DESC desc = {};
+ d3dTexture->GetDesc(&desc);
+
+ EGLint imageWidth = static_cast<EGLint>(desc.Width);
+ EGLint imageHeight = static_cast<EGLint>(desc.Height);
+
+ GLsizei sampleCount = static_cast<GLsizei>(desc.SampleDesc.Count);
+ if (configuration && (configuration->samples != sampleCount))
+ {
+ // Both the texture and EGL config sample count may not be the same when multi-sampling
+ // is disabled. The EGL sample count can be 0 but a D3D texture is always 1. Therefore,
+ // we must only check for a invalid match when the EGL config is non-zero or the texture is
+ // not one.
+ if (configuration->samples != 0 || sampleCount != 1)
+ {
+ return egl::EglBadParameter() << "Texture's sample count does not match.";
+ }
+ }
+
+ const angle::Format *textureAngleFormat = nullptr;
+ GLenum sizedInternalFormat = GL_NONE;
+
+ // From table egl.restrictions in EGL_ANGLE_d3d_texture_client_buffer.
+ if (desc.Format == DXGI_FORMAT_NV12 || desc.Format == DXGI_FORMAT_P010 ||
+ desc.Format == DXGI_FORMAT_P016)
+ {
+ if (!attribs.contains(EGL_D3D11_TEXTURE_PLANE_ANGLE))
+ {
+ return egl::EglBadParameter()
+ << "EGL_D3D11_TEXTURE_PLANE_ANGLE must be specified for YUV textures.";
+ }
+
+ EGLint plane = attribs.getAsInt(EGL_D3D11_TEXTURE_PLANE_ANGLE);
+
+ // P010 and P016 have the same memory layout, SRV/RTV format, etc.
+ const bool isNV12 = (desc.Format == DXGI_FORMAT_NV12);
+ if (plane == 0)
+ {
+ textureAngleFormat = isNV12 ? &angle::Format::Get(angle::FormatID::R8_UNORM)
+ : &angle::Format::Get(angle::FormatID::R16_UNORM);
+ }
+ else if (plane == 1)
+ {
+ textureAngleFormat = isNV12 ? &angle::Format::Get(angle::FormatID::R8G8_UNORM)
+ : &angle::Format::Get(angle::FormatID::R16G16_UNORM);
+ imageWidth /= 2;
+ imageHeight /= 2;
+ }
+ else
+ {
+ return egl::EglBadParameter() << "Invalid client buffer texture plane: " << plane;
+ }
+
+ ASSERT(textureAngleFormat);
+ sizedInternalFormat = textureAngleFormat->glInternalFormat;
+ }
+ else
+ {
+ switch (desc.Format)
+ {
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
+ case DXGI_FORMAT_R8G8B8A8_TYPELESS:
+ case DXGI_FORMAT_B8G8R8A8_UNORM:
+ case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
+ case DXGI_FORMAT_B8G8R8A8_TYPELESS:
+ case DXGI_FORMAT_R16G16B16A16_FLOAT:
+ case DXGI_FORMAT_R32G32B32A32_FLOAT:
+ case DXGI_FORMAT_R10G10B10A2_UNORM:
+ case DXGI_FORMAT_R8_UNORM:
+ case DXGI_FORMAT_R8G8_UNORM:
+ case DXGI_FORMAT_R16_UNORM:
+ case DXGI_FORMAT_R16G16_UNORM:
+ break;
+
+ default:
+ return egl::EglBadParameter()
+ << "Invalid client buffer texture format: " << desc.Format;
+ }
+
+ textureAngleFormat = &d3d11_angle::GetFormat(desc.Format);
+ ASSERT(textureAngleFormat);
+
+ sizedInternalFormat = textureAngleFormat->glInternalFormat;
+
+ if (attribs.contains(EGL_TEXTURE_INTERNAL_FORMAT_ANGLE))
+ {
+ const GLenum internalFormat =
+ static_cast<GLenum>(attribs.get(EGL_TEXTURE_INTERNAL_FORMAT_ANGLE));
+ switch (internalFormat)
+ {
+ case GL_RGBA:
+ case GL_BGRA_EXT:
+ case GL_RGB:
+ case GL_RED_EXT:
+ case GL_RG_EXT:
+ case GL_RGB10_A2_EXT:
+ case GL_R16_EXT:
+ case GL_RG16_EXT:
+ break;
+ default:
+ return egl::EglBadParameter()
+ << "Invalid client buffer texture internal format: " << std::hex
+ << internalFormat;
+ }
+
+ const GLenum type = gl::GetSizedInternalFormatInfo(sizedInternalFormat).type;
+
+ const auto format = gl::Format(internalFormat, type);
+ if (!format.valid())
+ {
+ return egl::EglBadParameter()
+ << "Invalid client buffer texture internal format: " << std::hex
+ << internalFormat;
+ }
+
+ sizedInternalFormat = format.info->sizedInternalFormat;
+ }
+ }
+
+ UINT textureArraySlice =
+ static_cast<UINT>(attribs.getAsInt(EGL_D3D11_TEXTURE_ARRAY_SLICE_ANGLE, 0));
+ if (textureArraySlice >= desc.ArraySize)
+ {
+ return egl::EglBadParameter()
+ << "Invalid client buffer texture array slice: " << textureArraySlice;
+ }
+
+ if (width)
+ {
+ *width = imageWidth;
+ }
+ if (height)
+ {
+ *height = imageHeight;
+ }
+
+ if (samples)
+ {
+ // EGL samples 0 corresponds to D3D11 sample count 1.
+ *samples = sampleCount != 1 ? sampleCount : 0;
+ }
+
+ if (glFormat)
+ {
+ *glFormat = gl::Format(sizedInternalFormat);
+ }
+
+ if (angleFormat)
+ {
+ *angleFormat = textureAngleFormat;
+ }
+
+ if (arraySlice)
+ {
+ *arraySlice = textureArraySlice;
+ }
+
+ return egl::NoError();
+}
+
+egl::Error Renderer11::validateShareHandle(const egl::Config *config,
+ HANDLE shareHandle,
+ const egl::AttributeMap &attribs) const
+{
+ if (shareHandle == nullptr)
+ {
+ return egl::EglBadParameter() << "NULL share handle.";
+ }
+
+ ID3D11Resource *tempResource11 = nullptr;
+ HRESULT result = mDevice->OpenSharedResource(shareHandle, __uuidof(ID3D11Resource),
+ (void **)&tempResource11);
+ if (FAILED(result) && mDevice1)
+ {
+ result = mDevice1->OpenSharedResource1(shareHandle, __uuidof(ID3D11Resource),
+ (void **)&tempResource11);
+ }
+
+ if (FAILED(result))
+ {
+ return egl::EglBadParameter() << "Failed to open share handle, " << gl::FmtHR(result);
+ }
+
+ ID3D11Texture2D *texture2D = d3d11::DynamicCastComObject<ID3D11Texture2D>(tempResource11);
+ SafeRelease(tempResource11);
+
+ if (texture2D == nullptr)
+ {
+ return egl::EglBadParameter()
+ << "Failed to query ID3D11Texture2D object from share handle.";
+ }
+
+ D3D11_TEXTURE2D_DESC desc = {};
+ texture2D->GetDesc(&desc);
+ SafeRelease(texture2D);
+
+ EGLint width = attribs.getAsInt(EGL_WIDTH, 0);
+ EGLint height = attribs.getAsInt(EGL_HEIGHT, 0);
+ ASSERT(width != 0 && height != 0);
+
+ const d3d11::Format &backbufferFormatInfo =
+ d3d11::Format::Get(config->renderTargetFormat, getRenderer11DeviceCaps());
+
+ if (desc.Width != static_cast<UINT>(width) || desc.Height != static_cast<UINT>(height) ||
+ desc.Format != backbufferFormatInfo.texFormat || desc.MipLevels != 1 || desc.ArraySize != 1)
+ {
+ return egl::EglBadParameter() << "Invalid texture parameters in share handle texture.";
+ }
+
+ return egl::NoError();
+}
+
+SwapChainD3D *Renderer11::createSwapChain(NativeWindowD3D *nativeWindow,
+ HANDLE shareHandle,
+ IUnknown *d3dTexture,
+ GLenum backBufferFormat,
+ GLenum depthBufferFormat,
+ EGLint orientation,
+ EGLint samples)
+{
+ return new SwapChain11(this, GetAs<NativeWindow11>(nativeWindow), shareHandle, d3dTexture,
+ backBufferFormat, depthBufferFormat, orientation, samples);
+}
+
+void *Renderer11::getD3DDevice()
+{
+ return mDevice;
+}
+
+angle::Result Renderer11::drawWithGeometryShaderAndTransformFeedback(Context11 *context11,
+ gl::PrimitiveMode mode,
+ UINT instanceCount,
+ UINT vertexCount)
+{
+ const gl::State &glState = context11->getState();
+ ProgramD3D *programD3D = mStateManager.getProgramD3D();
+
+ // Since we use a geometry if-and-only-if we rewrite vertex streams, transform feedback
+ // won't get the correct output. To work around this, draw with *only* the stream out
+ // first (no pixel shader) to feed the stream out buffers and then draw again with the
+ // geometry shader + pixel shader to rasterize the primitives.
+ mStateManager.setPixelShader(nullptr);
+
+ if (instanceCount > 0)
+ {
+ mDeviceContext->DrawInstanced(vertexCount, instanceCount, 0, 0);
+ }
+ else
+ {
+ mDeviceContext->Draw(vertexCount, 0);
+ }
+
+ rx::ShaderExecutableD3D *pixelExe = nullptr;
+ ANGLE_TRY(programD3D->getPixelExecutableForCachedOutputLayout(context11, &pixelExe, nullptr));
+
+ // Skip the draw call if rasterizer discard is enabled (or no fragment shader).
+ if (!pixelExe || glState.getRasterizerState().rasterizerDiscard)
+ {
+ return angle::Result::Continue;
+ }
+
+ mStateManager.setPixelShader(&GetAs<ShaderExecutable11>(pixelExe)->getPixelShader());
+
+ // Retrieve the geometry shader.
+ rx::ShaderExecutableD3D *geometryExe = nullptr;
+ ANGLE_TRY(programD3D->getGeometryExecutableForPrimitiveType(context11, glState, mode,
+ &geometryExe, nullptr));
+
+ mStateManager.setGeometryShader(&GetAs<ShaderExecutable11>(geometryExe)->getGeometryShader());
+
+ if (instanceCount > 0)
+ {
+ mDeviceContext->DrawInstanced(vertexCount, instanceCount, 0, 0);
+ }
+ else
+ {
+ mDeviceContext->Draw(vertexCount, 0);
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer11::drawArrays(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLint firstVertex,
+ GLsizei vertexCount,
+ GLsizei instanceCount,
+ GLuint baseInstance,
+ bool isInstancedDraw)
+{
+ if (mStateManager.getCullEverything())
+ {
+ return angle::Result::Continue;
+ }
+
+ ANGLE_TRY(markRawBufferUsage(context));
+
+ ProgramD3D *programD3D = mStateManager.getProgramD3D();
+ GLsizei adjustedInstanceCount = GetAdjustedInstanceCount(programD3D, instanceCount);
+
+ // Note: vertex indexes can be arbitrarily large.
+ UINT clampedVertexCount = gl::GetClampedVertexCount<UINT>(vertexCount);
+
+ const auto &glState = context->getState();
+ if (glState.getCurrentTransformFeedback() && glState.isTransformFeedbackActiveUnpaused())
+ {
+ ANGLE_TRY(markTransformFeedbackUsage(context));
+
+ if (programD3D->usesGeometryShader(glState, mode))
+ {
+ return drawWithGeometryShaderAndTransformFeedback(
+ GetImplAs<Context11>(context), mode, adjustedInstanceCount, clampedVertexCount);
+ }
+ }
+
+ switch (mode)
+ {
+ case gl::PrimitiveMode::LineLoop:
+ return drawLineLoop(context, clampedVertexCount, gl::DrawElementsType::InvalidEnum,
+ nullptr, 0, adjustedInstanceCount);
+ case gl::PrimitiveMode::TriangleFan:
+ return drawTriangleFan(context, clampedVertexCount, gl::DrawElementsType::InvalidEnum,
+ nullptr, 0, adjustedInstanceCount);
+ case gl::PrimitiveMode::Points:
+ if (getFeatures().useInstancedPointSpriteEmulation.enabled)
+ {
+ // This code should not be reachable by multi-view programs.
+ ASSERT(programD3D->getState().usesMultiview() == false);
+
+ // If the shader is writing to gl_PointSize, then pointsprites are being rendered.
+ // Emulating instanced point sprites for FL9_3 requires the topology to be
+ // D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST and DrawIndexedInstanced is called instead.
+ if (adjustedInstanceCount == 0)
+ {
+ mDeviceContext->DrawIndexedInstanced(6, clampedVertexCount, 0, 0, baseInstance);
+ return angle::Result::Continue;
+ }
+
+ // If pointsprite emulation is used with glDrawArraysInstanced then we need to take
+ // a less efficent code path. Instanced rendering of emulated pointsprites requires
+ // a loop to draw each batch of points. An offset into the instanced data buffer is
+ // calculated and applied on each iteration to ensure all instances are rendered
+ // correctly. Each instance being rendered requires the inputlayout cache to reapply
+ // buffers and offsets.
+ for (GLsizei i = 0; i < instanceCount; i++)
+ {
+ ANGLE_TRY(mStateManager.updateVertexOffsetsForPointSpritesEmulation(
+ context, firstVertex, i));
+ mDeviceContext->DrawIndexedInstanced(6, clampedVertexCount, 0, 0, baseInstance);
+ }
+
+ // This required by updateVertexOffsets... above but is outside of the loop for
+ // speed.
+ mStateManager.invalidateVertexBuffer();
+ return angle::Result::Continue;
+ }
+ break;
+ default:
+ break;
+ }
+
+ // "Normal" draw case.
+ if (!isInstancedDraw && adjustedInstanceCount == 0)
+ {
+ mDeviceContext->Draw(clampedVertexCount, 0);
+ }
+ else
+ {
+ mDeviceContext->DrawInstanced(clampedVertexCount, adjustedInstanceCount, 0, baseInstance);
+ }
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer11::drawElements(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLint startVertex,
+ GLsizei indexCount,
+ gl::DrawElementsType indexType,
+ const void *indices,
+ GLsizei instanceCount,
+ GLint baseVertex,
+ GLuint baseInstance,
+ bool isInstancedDraw)
+{
+ if (mStateManager.getCullEverything())
+ {
+ return angle::Result::Continue;
+ }
+
+ ANGLE_TRY(markRawBufferUsage(context));
+
+ // Transform feedback is not allowed for DrawElements, this error should have been caught at the
+ // API validation layer.
+ const gl::State &glState = context->getState();
+ ASSERT(!glState.isTransformFeedbackActiveUnpaused());
+
+ // If this draw call is coming from an indirect call, offset by the indirect call's base vertex.
+ GLint baseVertexAdjusted = baseVertex - startVertex;
+
+ const ProgramD3D *programD3D = mStateManager.getProgramD3D();
+ GLsizei adjustedInstanceCount = GetAdjustedInstanceCount(programD3D, instanceCount);
+
+ if (mode == gl::PrimitiveMode::LineLoop)
+ {
+ return drawLineLoop(context, indexCount, indexType, indices, baseVertexAdjusted,
+ adjustedInstanceCount);
+ }
+
+ if (mode == gl::PrimitiveMode::TriangleFan)
+ {
+ return drawTriangleFan(context, indexCount, indexType, indices, baseVertexAdjusted,
+ adjustedInstanceCount);
+ }
+
+ if (mode != gl::PrimitiveMode::Points || !programD3D->usesInstancedPointSpriteEmulation())
+ {
+ if (!isInstancedDraw && adjustedInstanceCount == 0)
+ {
+ mDeviceContext->DrawIndexed(indexCount, 0, baseVertexAdjusted);
+ }
+ else
+ {
+ mDeviceContext->DrawIndexedInstanced(indexCount, adjustedInstanceCount, 0,
+ baseVertexAdjusted, baseInstance);
+ }
+ return angle::Result::Continue;
+ }
+
+ // This code should not be reachable by multi-view programs.
+ ASSERT(programD3D->getState().usesMultiview() == false);
+
+ // If the shader is writing to gl_PointSize, then pointsprites are being rendered.
+ // Emulating instanced point sprites for FL9_3 requires the topology to be
+ // D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST and DrawIndexedInstanced is called instead.
+ //
+ // The count parameter passed to drawElements represents the total number of instances to be
+ // rendered. Each instance is referenced by the bound index buffer from the the caller.
+ //
+ // Indexed pointsprite emulation replicates data for duplicate entries found in the index
+ // buffer. This is not an efficent rendering mechanism and is only used on downlevel renderers
+ // that do not support geometry shaders.
+ if (instanceCount == 0)
+ {
+ mDeviceContext->DrawIndexedInstanced(6, indexCount, 0, baseVertexAdjusted, baseInstance);
+ return angle::Result::Continue;
+ }
+
+ // If pointsprite emulation is used with glDrawElementsInstanced then we need to take a less
+ // efficent code path. Instanced rendering of emulated pointsprites requires a loop to draw each
+ // batch of points. An offset into the instanced data buffer is calculated and applied on each
+ // iteration to ensure all instances are rendered correctly.
+ gl::IndexRange indexRange;
+ ANGLE_TRY(glState.getVertexArray()->getIndexRange(context, indexType, indexCount, indices,
+ &indexRange));
+
+ UINT clampedVertexCount = gl::clampCast<UINT>(indexRange.vertexCount());
+
+ // Each instance being rendered requires the inputlayout cache to reapply buffers and offsets.
+ for (GLsizei i = 0; i < instanceCount; i++)
+ {
+ ANGLE_TRY(
+ mStateManager.updateVertexOffsetsForPointSpritesEmulation(context, startVertex, i));
+ mDeviceContext->DrawIndexedInstanced(6, clampedVertexCount, 0, baseVertexAdjusted,
+ baseInstance);
+ }
+ mStateManager.invalidateVertexBuffer();
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer11::drawArraysIndirect(const gl::Context *context, const void *indirect)
+{
+ if (mStateManager.getCullEverything())
+ {
+ return angle::Result::Continue;
+ }
+
+ ANGLE_TRY(markRawBufferUsage(context));
+
+ const gl::State &glState = context->getState();
+ ASSERT(!glState.isTransformFeedbackActiveUnpaused());
+
+ gl::Buffer *drawIndirectBuffer = glState.getTargetBuffer(gl::BufferBinding::DrawIndirect);
+ ASSERT(drawIndirectBuffer);
+ Buffer11 *storage = GetImplAs<Buffer11>(drawIndirectBuffer);
+
+ uintptr_t offset = reinterpret_cast<uintptr_t>(indirect);
+
+ ID3D11Buffer *buffer = nullptr;
+ ANGLE_TRY(storage->getBuffer(context, BUFFER_USAGE_INDIRECT, &buffer));
+ mDeviceContext->DrawInstancedIndirect(buffer, static_cast<unsigned int>(offset));
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer11::drawElementsIndirect(const gl::Context *context, const void *indirect)
+{
+ if (mStateManager.getCullEverything())
+ {
+ return angle::Result::Continue;
+ }
+
+ ANGLE_TRY(markRawBufferUsage(context));
+
+ const gl::State &glState = context->getState();
+ ASSERT(!glState.isTransformFeedbackActiveUnpaused());
+
+ gl::Buffer *drawIndirectBuffer = glState.getTargetBuffer(gl::BufferBinding::DrawIndirect);
+ ASSERT(drawIndirectBuffer);
+ Buffer11 *storage = GetImplAs<Buffer11>(drawIndirectBuffer);
+ uintptr_t offset = reinterpret_cast<uintptr_t>(indirect);
+
+ ID3D11Buffer *buffer = nullptr;
+ ANGLE_TRY(storage->getBuffer(context, BUFFER_USAGE_INDIRECT, &buffer));
+ mDeviceContext->DrawIndexedInstancedIndirect(buffer, static_cast<unsigned int>(offset));
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer11::drawLineLoop(const gl::Context *context,
+ GLuint count,
+ gl::DrawElementsType type,
+ const void *indexPointer,
+ int baseVertex,
+ int instances)
+{
+ const gl::State &glState = context->getState();
+ gl::VertexArray *vao = glState.getVertexArray();
+ gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer();
+
+ const void *indices = indexPointer;
+
+ // Get the raw indices for an indexed draw
+ if (type != gl::DrawElementsType::InvalidEnum && elementArrayBuffer)
+ {
+ BufferD3D *storage = GetImplAs<BufferD3D>(elementArrayBuffer);
+ intptr_t offset = reinterpret_cast<intptr_t>(indices);
+
+ const uint8_t *bufferData = nullptr;
+ ANGLE_TRY(storage->getData(context, &bufferData));
+
+ indices = bufferData + offset;
+ }
+
+ if (!mLineLoopIB)
+ {
+ mLineLoopIB = new StreamingIndexBufferInterface(this);
+ ANGLE_TRY(mLineLoopIB->reserveBufferSpace(context, INITIAL_INDEX_BUFFER_SIZE,
+ gl::DrawElementsType::UnsignedInt));
+ }
+
+ // Checked by Renderer11::applyPrimitiveType
+ bool indexCheck = static_cast<unsigned int>(count) + 1 >
+ (std::numeric_limits<unsigned int>::max() / sizeof(unsigned int));
+ ANGLE_CHECK(GetImplAs<Context11>(context), !indexCheck,
+ "Failed to create a 32-bit looping index buffer for "
+ "GL_LINE_LOOP, too many indices required.",
+ GL_OUT_OF_MEMORY);
+
+ GetLineLoopIndices(indices, type, static_cast<GLuint>(count),
+ glState.isPrimitiveRestartEnabled(), &mScratchIndexDataBuffer);
+
+ unsigned int spaceNeeded =
+ static_cast<unsigned int>(sizeof(GLuint) * mScratchIndexDataBuffer.size());
+ ANGLE_TRY(
+ mLineLoopIB->reserveBufferSpace(context, spaceNeeded, gl::DrawElementsType::UnsignedInt));
+
+ void *mappedMemory = nullptr;
+ unsigned int offset;
+ ANGLE_TRY(mLineLoopIB->mapBuffer(context, spaceNeeded, &mappedMemory, &offset));
+
+ // Copy over the converted index data.
+ memcpy(mappedMemory, &mScratchIndexDataBuffer[0],
+ sizeof(GLuint) * mScratchIndexDataBuffer.size());
+
+ ANGLE_TRY(mLineLoopIB->unmapBuffer(context));
+
+ IndexBuffer11 *indexBuffer = GetAs<IndexBuffer11>(mLineLoopIB->getIndexBuffer());
+ const d3d11::Buffer &d3dIndexBuffer = indexBuffer->getBuffer();
+ DXGI_FORMAT indexFormat = indexBuffer->getIndexFormat();
+
+ mStateManager.setIndexBuffer(d3dIndexBuffer.get(), indexFormat, offset);
+
+ UINT indexCount = static_cast<UINT>(mScratchIndexDataBuffer.size());
+
+ if (instances > 0)
+ {
+ mDeviceContext->DrawIndexedInstanced(indexCount, instances, 0, baseVertex, 0);
+ }
+ else
+ {
+ mDeviceContext->DrawIndexed(indexCount, 0, baseVertex);
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer11::drawTriangleFan(const gl::Context *context,
+ GLuint count,
+ gl::DrawElementsType type,
+ const void *indices,
+ int baseVertex,
+ int instances)
+{
+ const gl::State &glState = context->getState();
+ gl::VertexArray *vao = glState.getVertexArray();
+ gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer();
+
+ const void *indexPointer = indices;
+
+ // Get the raw indices for an indexed draw
+ if (type != gl::DrawElementsType::InvalidEnum && elementArrayBuffer)
+ {
+ BufferD3D *storage = GetImplAs<BufferD3D>(elementArrayBuffer);
+ intptr_t offset = reinterpret_cast<intptr_t>(indices);
+
+ const uint8_t *bufferData = nullptr;
+ ANGLE_TRY(storage->getData(context, &bufferData));
+
+ indexPointer = bufferData + offset;
+ }
+
+ if (!mTriangleFanIB)
+ {
+ mTriangleFanIB = new StreamingIndexBufferInterface(this);
+ ANGLE_TRY(mTriangleFanIB->reserveBufferSpace(context, INITIAL_INDEX_BUFFER_SIZE,
+ gl::DrawElementsType::UnsignedInt));
+ }
+
+ // Checked by Renderer11::applyPrimitiveType
+ ASSERT(count >= 3);
+
+ const GLuint numTris = count - 2;
+
+ bool indexCheck =
+ (numTris > std::numeric_limits<unsigned int>::max() / (sizeof(unsigned int) * 3));
+ ANGLE_CHECK(GetImplAs<Context11>(context), !indexCheck,
+ "Failed to create a scratch index buffer for GL_TRIANGLE_FAN, "
+ "too many indices required.",
+ GL_OUT_OF_MEMORY);
+
+ GetTriFanIndices(indexPointer, type, count, glState.isPrimitiveRestartEnabled(),
+ &mScratchIndexDataBuffer);
+
+ const unsigned int spaceNeeded =
+ static_cast<unsigned int>(mScratchIndexDataBuffer.size() * sizeof(unsigned int));
+ ANGLE_TRY(mTriangleFanIB->reserveBufferSpace(context, spaceNeeded,
+ gl::DrawElementsType::UnsignedInt));
+
+ void *mappedMemory = nullptr;
+ unsigned int offset;
+ ANGLE_TRY(mTriangleFanIB->mapBuffer(context, spaceNeeded, &mappedMemory, &offset));
+
+ memcpy(mappedMemory, &mScratchIndexDataBuffer[0], spaceNeeded);
+
+ ANGLE_TRY(mTriangleFanIB->unmapBuffer(context));
+
+ IndexBuffer11 *indexBuffer = GetAs<IndexBuffer11>(mTriangleFanIB->getIndexBuffer());
+ const d3d11::Buffer &d3dIndexBuffer = indexBuffer->getBuffer();
+ DXGI_FORMAT indexFormat = indexBuffer->getIndexFormat();
+
+ mStateManager.setIndexBuffer(d3dIndexBuffer.get(), indexFormat, offset);
+
+ UINT indexCount = static_cast<UINT>(mScratchIndexDataBuffer.size());
+
+ if (instances > 0)
+ {
+ mDeviceContext->DrawIndexedInstanced(indexCount, instances, 0, baseVertex, 0);
+ }
+ else
+ {
+ mDeviceContext->DrawIndexed(indexCount, 0, baseVertex);
+ }
+
+ return angle::Result::Continue;
+}
+
+void Renderer11::releaseDeviceResources()
+{
+ mStateManager.deinitialize();
+ mStateCache.clear();
+
+ SafeDelete(mLineLoopIB);
+ SafeDelete(mTriangleFanIB);
+ SafeDelete(mBlit);
+ SafeDelete(mClear);
+ SafeDelete(mTrim);
+ SafeDelete(mPixelTransfer);
+
+ mSyncQuery.reset();
+
+ mCachedResolveTexture.reset();
+}
+
+// set notify to true to broadcast a message to all contexts of the device loss
+bool Renderer11::testDeviceLost()
+{
+ if (!mDevice)
+ {
+ return true;
+ }
+
+ // GetRemovedReason is used to test if the device is removed
+ HRESULT result = mDevice->GetDeviceRemovedReason();
+ bool isLost = FAILED(result);
+
+ if (isLost)
+ {
+ ERR() << "The D3D11 device was removed, " << gl::FmtHR(result);
+ }
+
+ return isLost;
+}
+
+bool Renderer11::testDeviceResettable()
+{
+ // determine if the device is resettable by creating a mock device
+ PFN_D3D11_CREATE_DEVICE D3D11CreateDevice =
+ (PFN_D3D11_CREATE_DEVICE)GetProcAddress(mD3d11Module, "D3D11CreateDevice");
+
+ if (D3D11CreateDevice == nullptr)
+ {
+ return false;
+ }
+
+ ID3D11Device *mockDevice;
+ D3D_FEATURE_LEVEL mockFeatureLevel;
+ ID3D11DeviceContext *mockContext;
+ UINT flags = (mCreateDebugDevice ? D3D11_CREATE_DEVICE_DEBUG : 0);
+
+ ASSERT(mRequestedDriverType != D3D_DRIVER_TYPE_UNKNOWN);
+ HRESULT result = D3D11CreateDevice(
+ nullptr, mRequestedDriverType, nullptr, flags, mAvailableFeatureLevels.data(),
+ static_cast<unsigned int>(mAvailableFeatureLevels.size()), D3D11_SDK_VERSION, &mockDevice,
+ &mockFeatureLevel, &mockContext);
+
+ if (!mDevice || FAILED(result))
+ {
+ return false;
+ }
+
+ SafeRelease(mockContext);
+ SafeRelease(mockDevice);
+
+ return true;
+}
+
+void Renderer11::release()
+{
+ mScratchMemoryBuffer.clear();
+
+ mAnnotatorContext.release();
+ gl::UninitializeDebugAnnotations();
+
+ releaseDeviceResources();
+
+ SafeRelease(mDxgiFactory);
+ SafeRelease(mDxgiAdapter);
+
+ SafeRelease(mDeviceContext3);
+ SafeRelease(mDeviceContext1);
+
+ if (mDeviceContext)
+ {
+ mDeviceContext->ClearState();
+ mDeviceContext->Flush();
+ SafeRelease(mDeviceContext);
+ }
+
+ SafeRelease(mDevice);
+ SafeRelease(mDevice1);
+ SafeRelease(mDebug);
+
+ if (mD3d11Module)
+ {
+ FreeLibrary(mD3d11Module);
+ mD3d11Module = nullptr;
+ }
+
+ if (mDxgiModule)
+ {
+ FreeLibrary(mDxgiModule);
+ mDxgiModule = nullptr;
+ }
+
+ if (mDCompModule)
+ {
+ FreeLibrary(mDCompModule);
+ mDCompModule = nullptr;
+ }
+
+ mDevice12.Reset();
+ mCommandQueue.Reset();
+
+ if (mD3d12Module)
+ {
+ FreeLibrary(mD3d12Module);
+ mD3d12Module = nullptr;
+ }
+
+ mCompiler.release();
+
+ mSupportsShareHandles.reset();
+}
+
+bool Renderer11::resetDevice()
+{
+ // recreate everything
+ release();
+ egl::Error result = initialize();
+
+ if (result.isError())
+ {
+ ERR() << "Could not reinitialize D3D11 device: " << result;
+ return false;
+ }
+
+ return true;
+}
+
+std::string Renderer11::getRendererDescription() const
+{
+ std::ostringstream rendererString;
+
+ rendererString << mDescription;
+ rendererString << " Direct3D11";
+
+ rendererString << " vs_" << getMajorShaderModel() << "_" << getMinorShaderModel()
+ << getShaderModelSuffix();
+ rendererString << " ps_" << getMajorShaderModel() << "_" << getMinorShaderModel()
+ << getShaderModelSuffix();
+
+ return rendererString.str();
+}
+
+DeviceIdentifier Renderer11::getAdapterIdentifier() const
+{
+ // Don't use the AdapterLuid here, since that doesn't persist across reboot.
+ DeviceIdentifier deviceIdentifier = {};
+ deviceIdentifier.VendorId = mAdapterDescription.VendorId;
+ deviceIdentifier.DeviceId = mAdapterDescription.DeviceId;
+ deviceIdentifier.SubSysId = mAdapterDescription.SubSysId;
+ deviceIdentifier.Revision = mAdapterDescription.Revision;
+ deviceIdentifier.FeatureLevel = static_cast<UINT>(mRenderer11DeviceCaps.featureLevel);
+
+ return deviceIdentifier;
+}
+
+unsigned int Renderer11::getReservedVertexUniformVectors() const
+{
+ // Driver uniforms are stored in a separate constant buffer
+ return d3d11_gl::GetReservedVertexUniformVectors(mRenderer11DeviceCaps.featureLevel);
+}
+
+unsigned int Renderer11::getReservedFragmentUniformVectors() const
+{
+ // Driver uniforms are stored in a separate constant buffer
+ return d3d11_gl::GetReservedFragmentUniformVectors(mRenderer11DeviceCaps.featureLevel);
+}
+
+gl::ShaderMap<unsigned int> Renderer11::getReservedShaderUniformBuffers() const
+{
+ gl::ShaderMap<unsigned int> shaderReservedUniformBuffers = {};
+
+ // we reserve one buffer for the application uniforms, and one for driver uniforms
+ shaderReservedUniformBuffers[gl::ShaderType::Vertex] = 2;
+ shaderReservedUniformBuffers[gl::ShaderType::Fragment] = 2;
+
+ return shaderReservedUniformBuffers;
+}
+
+d3d11::ANGLED3D11DeviceType Renderer11::getDeviceType() const
+{
+ if (mCreatedWithDeviceEXT)
+ {
+ return d3d11::GetDeviceType(mDevice);
+ }
+
+ if ((mRequestedDriverType == D3D_DRIVER_TYPE_SOFTWARE) ||
+ (mRequestedDriverType == D3D_DRIVER_TYPE_REFERENCE) ||
+ (mRequestedDriverType == D3D_DRIVER_TYPE_NULL))
+ {
+ return d3d11::ANGLE_D3D11_DEVICE_TYPE_SOFTWARE_REF_OR_NULL;
+ }
+
+ if (mRequestedDriverType == D3D_DRIVER_TYPE_WARP)
+ {
+ return d3d11::ANGLE_D3D11_DEVICE_TYPE_WARP;
+ }
+
+ return d3d11::ANGLE_D3D11_DEVICE_TYPE_HARDWARE;
+}
+
+bool Renderer11::getShareHandleSupport() const
+{
+ if (mSupportsShareHandles.valid())
+ {
+ return mSupportsShareHandles.value();
+ }
+
+ // We only currently support share handles with BGRA surfaces, because
+ // chrome needs BGRA. Once chrome fixes this, we should always support them.
+ if (!getNativeExtensions().textureFormatBGRA8888EXT)
+ {
+ mSupportsShareHandles = false;
+ return false;
+ }
+
+ // PIX doesn't seem to support using share handles, so disable them.
+ if (mAnnotatorContext.getStatus())
+ {
+ mSupportsShareHandles = false;
+ return false;
+ }
+
+ // Also disable share handles on Feature Level 9_3, since it doesn't support share handles on
+ // RGBA8 textures/swapchains.
+ if (mRenderer11DeviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3)
+ {
+ mSupportsShareHandles = false;
+ return false;
+ }
+
+ // Find out which type of D3D11 device the Renderer11 is using
+ d3d11::ANGLED3D11DeviceType deviceType = getDeviceType();
+ if (deviceType == d3d11::ANGLE_D3D11_DEVICE_TYPE_UNKNOWN)
+ {
+ mSupportsShareHandles = false;
+ return false;
+ }
+
+ if (deviceType == d3d11::ANGLE_D3D11_DEVICE_TYPE_SOFTWARE_REF_OR_NULL)
+ {
+ // Software/Reference/NULL devices don't support share handles
+ mSupportsShareHandles = false;
+ return false;
+ }
+
+ if (deviceType == d3d11::ANGLE_D3D11_DEVICE_TYPE_WARP)
+ {
+#if !defined(ANGLE_ENABLE_WINDOWS_UWP)
+ if (!IsWindows8OrGreater())
+ {
+ // WARP on Windows 7 doesn't support shared handles
+ mSupportsShareHandles = false;
+ return false;
+ }
+#endif // !defined(ANGLE_ENABLE_WINDOWS_UWP)
+
+ // WARP on Windows 8.0+ supports shared handles when shared with another WARP device
+ // TODO: allow applications to query for HARDWARE or WARP-specific share handles,
+ // to prevent them trying to use a WARP share handle with an a HW device (or
+ // vice-versa)
+ // e.g. by creating EGL_D3D11_[HARDWARE/WARP]_DEVICE_SHARE_HANDLE_ANGLE
+ mSupportsShareHandles = true;
+ return true;
+ }
+
+ ASSERT(mCreatedWithDeviceEXT || mRequestedDriverType == D3D_DRIVER_TYPE_HARDWARE);
+ mSupportsShareHandles = true;
+ return true;
+}
+
+int Renderer11::getMajorShaderModel() const
+{
+ switch (mRenderer11DeviceCaps.featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return D3D11_SHADER_MAJOR_VERSION; // 5
+ case D3D_FEATURE_LEVEL_10_1:
+ return D3D10_1_SHADER_MAJOR_VERSION; // 4
+ case D3D_FEATURE_LEVEL_10_0:
+ return D3D10_SHADER_MAJOR_VERSION; // 4
+ case D3D_FEATURE_LEVEL_9_3:
+ return D3D10_SHADER_MAJOR_VERSION; // 4
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+int Renderer11::getMinorShaderModel() const
+{
+ switch (mRenderer11DeviceCaps.featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return D3D11_SHADER_MINOR_VERSION; // 0
+ case D3D_FEATURE_LEVEL_10_1:
+ return D3D10_1_SHADER_MINOR_VERSION; // 1
+ case D3D_FEATURE_LEVEL_10_0:
+ return D3D10_SHADER_MINOR_VERSION; // 0
+ case D3D_FEATURE_LEVEL_9_3:
+ return D3D10_SHADER_MINOR_VERSION; // 0
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+std::string Renderer11::getShaderModelSuffix() const
+{
+ switch (mRenderer11DeviceCaps.featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return "";
+ case D3D_FEATURE_LEVEL_10_1:
+ return "";
+ case D3D_FEATURE_LEVEL_10_0:
+ return "";
+ case D3D_FEATURE_LEVEL_9_3:
+ return "_level_9_3";
+ default:
+ UNREACHABLE();
+ return "";
+ }
+}
+
+angle::Result Renderer11::copyImageInternal(const gl::Context *context,
+ const gl::Framebuffer *framebuffer,
+ const gl::Rectangle &sourceRect,
+ GLenum destFormat,
+ const gl::Offset &destOffset,
+ RenderTargetD3D *destRenderTarget)
+{
+ const gl::FramebufferAttachment *colorAttachment = framebuffer->getReadColorAttachment();
+ ASSERT(colorAttachment);
+
+ RenderTarget11 *sourceRenderTarget = nullptr;
+ ANGLE_TRY(colorAttachment->getRenderTarget(context, 0, &sourceRenderTarget));
+ ASSERT(sourceRenderTarget);
+
+ const d3d11::RenderTargetView &dest =
+ GetAs<RenderTarget11>(destRenderTarget)->getRenderTargetView();
+ ASSERT(dest.valid());
+
+ gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1);
+ gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1);
+
+ const bool invertSource = UsePresentPathFast(this, colorAttachment);
+ if (invertSource)
+ {
+ 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(destRenderTarget->getWidth(), destRenderTarget->getHeight(), 1);
+
+ // Use nearest filtering because source and destination are the same size for the direct copy.
+ // Convert to the unsized format before calling copyTexture.
+ GLenum sourceFormat = colorAttachment->getFormat().info->format;
+ if (sourceRenderTarget->getTexture().is2D() && sourceRenderTarget->isMultisampled())
+ {
+ TextureHelper11 tex;
+ ANGLE_TRY(resolveMultisampledTexture(context, sourceRenderTarget,
+ colorAttachment->getDepthSize() > 0,
+ colorAttachment->getStencilSize() > 0, &tex));
+
+ D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc;
+ viewDesc.Format = sourceRenderTarget->getFormatSet().srvFormat;
+ viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
+ viewDesc.Texture2D.MipLevels = 1;
+ viewDesc.Texture2D.MostDetailedMip = 0;
+
+ d3d11::SharedSRV readSRV;
+ ANGLE_TRY(allocateResource(GetImplAs<Context11>(context), viewDesc, tex.get(), &readSRV));
+ ASSERT(readSRV.valid());
+
+ ANGLE_TRY(mBlit->copyTexture(context, readSRV, sourceArea, sourceSize, sourceFormat, dest,
+ destArea, destSize, nullptr, gl::GetUnsizedFormat(destFormat),
+ GL_NONE, GL_NEAREST, false, false, false));
+
+ return angle::Result::Continue;
+ }
+
+ ASSERT(!sourceRenderTarget->isMultisampled());
+
+ const d3d11::SharedSRV *source;
+ ANGLE_TRY(sourceRenderTarget->getBlitShaderResourceView(context, &source));
+ ASSERT(source->valid());
+
+ ANGLE_TRY(mBlit->copyTexture(context, *source, sourceArea, sourceSize, sourceFormat, dest,
+ destArea, destSize, nullptr, gl::GetUnsizedFormat(destFormat),
+ GL_NONE, GL_NEAREST, false, false, false));
+
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer11::copyImage2D(const gl::Context *context,
+ const gl::Framebuffer *framebuffer,
+ const gl::Rectangle &sourceRect,
+ GLenum destFormat,
+ const gl::Offset &destOffset,
+ TextureStorage *storage,
+ GLint level)
+{
+ TextureStorage11_2D *storage11 = GetAs<TextureStorage11_2D>(storage);
+ ASSERT(storage11);
+
+ gl::ImageIndex index = gl::ImageIndex::Make2D(level);
+ RenderTargetD3D *destRenderTarget = nullptr;
+ ANGLE_TRY(storage11->getRenderTarget(context, index, storage11->getRenderToTextureSamples(),
+ &destRenderTarget));
+ ASSERT(destRenderTarget);
+
+ ANGLE_TRY(copyImageInternal(context, framebuffer, sourceRect, destFormat, destOffset,
+ destRenderTarget));
+
+ storage11->markLevelDirty(level);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer11::copyImageCube(const gl::Context *context,
+ const gl::Framebuffer *framebuffer,
+ const gl::Rectangle &sourceRect,
+ GLenum destFormat,
+ const gl::Offset &destOffset,
+ TextureStorage *storage,
+ gl::TextureTarget target,
+ GLint level)
+{
+ TextureStorage11_Cube *storage11 = GetAs<TextureStorage11_Cube>(storage);
+ ASSERT(storage11);
+
+ gl::ImageIndex index = gl::ImageIndex::MakeCubeMapFace(target, level);
+ RenderTargetD3D *destRenderTarget = nullptr;
+ ANGLE_TRY(storage11->getRenderTarget(context, index, storage11->getRenderToTextureSamples(),
+ &destRenderTarget));
+ ASSERT(destRenderTarget);
+
+ ANGLE_TRY(copyImageInternal(context, framebuffer, sourceRect, destFormat, destOffset,
+ destRenderTarget));
+
+ storage11->markLevelDirty(level);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer11::copyImage3D(const gl::Context *context,
+ const gl::Framebuffer *framebuffer,
+ const gl::Rectangle &sourceRect,
+ GLenum destFormat,
+ const gl::Offset &destOffset,
+ TextureStorage *storage,
+ GLint level)
+{
+ TextureStorage11_3D *storage11 = GetAs<TextureStorage11_3D>(storage);
+ ASSERT(storage11);
+
+ gl::ImageIndex index = gl::ImageIndex::Make3D(level, destOffset.z);
+ RenderTargetD3D *destRenderTarget = nullptr;
+ ANGLE_TRY(storage11->getRenderTarget(context, index, storage11->getRenderToTextureSamples(),
+ &destRenderTarget));
+ ASSERT(destRenderTarget);
+
+ ANGLE_TRY(copyImageInternal(context, framebuffer, sourceRect, destFormat, destOffset,
+ destRenderTarget));
+
+ storage11->markLevelDirty(level);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer11::copyImage2DArray(const gl::Context *context,
+ const gl::Framebuffer *framebuffer,
+ const gl::Rectangle &sourceRect,
+ GLenum destFormat,
+ const gl::Offset &destOffset,
+ TextureStorage *storage,
+ GLint level)
+{
+ TextureStorage11_2DArray *storage11 = GetAs<TextureStorage11_2DArray>(storage);
+ ASSERT(storage11);
+
+ gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, destOffset.z);
+ RenderTargetD3D *destRenderTarget = nullptr;
+ ANGLE_TRY(storage11->getRenderTarget(context, index, storage11->getRenderToTextureSamples(),
+ &destRenderTarget));
+ ASSERT(destRenderTarget);
+
+ ANGLE_TRY(copyImageInternal(context, framebuffer, sourceRect, destFormat, destOffset,
+ destRenderTarget));
+ storage11->markLevelDirty(level);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer11::copyTexture(const gl::Context *context,
+ const gl::Texture *source,
+ GLint sourceLevel,
+ gl::TextureTarget srcTarget,
+ const gl::Box &sourceBox,
+ GLenum destFormat,
+ GLenum destType,
+ const gl::Offset &destOffset,
+ TextureStorage *storage,
+ gl::TextureTarget destTarget,
+ GLint destLevel,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha)
+{
+
+ TextureD3D *sourceD3D = GetImplAs<TextureD3D>(source);
+ const gl::ImageDesc &sourceImageDesc = source->getTextureState().getImageDesc(
+ NonCubeTextureTypeToTarget(source->getType()), sourceLevel);
+
+ TextureStorage11 *destStorage11 = GetAs<TextureStorage11>(storage);
+ ASSERT(destStorage11);
+
+ // Check for fast path where a CopySubresourceRegion can be used.
+ if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha && !unpackFlipY &&
+ sourceImageDesc.format.info->sizedInternalFormat ==
+ destStorage11->getFormatSet().internalFormat)
+ {
+ const TextureHelper11 *destResource = nullptr;
+ ANGLE_TRY(destStorage11->getResource(context, &destResource));
+
+ if (srcTarget == gl::TextureTarget::_2D || srcTarget == gl::TextureTarget::_3D)
+ {
+ gl::ImageIndex sourceIndex = gl::ImageIndex::MakeFromTarget(srcTarget, sourceLevel, 1);
+ const TextureHelper11 *sourceResource = nullptr;
+ UINT sourceSubresource = 0;
+ ANGLE_TRY(GetTextureD3DResourceFromStorageOrImage(context, sourceD3D, sourceIndex,
+ &sourceResource, &sourceSubresource));
+
+ gl::ImageIndex destIndex = gl::ImageIndex::MakeFromTarget(destTarget, destLevel, 1);
+
+ UINT destSubresource = 0;
+ ANGLE_TRY(destStorage11->getSubresourceIndex(context, destIndex, &destSubresource));
+
+ D3D11_BOX d3dBox{static_cast<UINT>(sourceBox.x),
+ static_cast<UINT>(sourceBox.y),
+ static_cast<UINT>(sourceBox.z),
+ static_cast<UINT>(sourceBox.x + sourceBox.width),
+ static_cast<UINT>(sourceBox.y + sourceBox.height),
+ static_cast<UINT>(sourceBox.z + sourceBox.depth)};
+
+ mDeviceContext->CopySubresourceRegion(
+ destResource->get(), destSubresource, destOffset.x, destOffset.y, destOffset.z,
+ sourceResource->get(), sourceSubresource, &d3dBox);
+ }
+ else if (srcTarget == gl::TextureTarget::_2DArray)
+ {
+ D3D11_BOX d3dBox{static_cast<UINT>(sourceBox.x),
+ static_cast<UINT>(sourceBox.y),
+ 0,
+ static_cast<UINT>(sourceBox.x + sourceBox.width),
+ static_cast<UINT>(sourceBox.y + sourceBox.height),
+ 1u};
+
+ for (int i = 0; i < sourceBox.depth; i++)
+ {
+ gl::ImageIndex sourceIndex =
+ gl::ImageIndex::Make2DArray(sourceLevel, i + sourceBox.z);
+ const TextureHelper11 *sourceResource = nullptr;
+ UINT sourceSubresource = 0;
+ ANGLE_TRY(GetTextureD3DResourceFromStorageOrImage(
+ context, sourceD3D, sourceIndex, &sourceResource, &sourceSubresource));
+
+ gl::ImageIndex dIndex = gl::ImageIndex::Make2DArray(destLevel, i + destOffset.z);
+ UINT destSubresource = 0;
+ ANGLE_TRY(destStorage11->getSubresourceIndex(context, dIndex, &destSubresource));
+
+ mDeviceContext->CopySubresourceRegion(
+ destResource->get(), destSubresource, destOffset.x, destOffset.y, 0,
+ sourceResource->get(), sourceSubresource, &d3dBox);
+ }
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+ }
+ else
+ {
+ TextureStorage *sourceStorage = nullptr;
+ ANGLE_TRY(sourceD3D->getNativeTexture(context, &sourceStorage));
+
+ TextureStorage11 *sourceStorage11 = GetAs<TextureStorage11>(sourceStorage);
+ ASSERT(sourceStorage11);
+
+ const d3d11::SharedSRV *sourceSRV = nullptr;
+ ANGLE_TRY(sourceStorage11->getSRVLevels(context, sourceLevel, sourceLevel, &sourceSRV));
+
+ gl::ImageIndex destIndex;
+ if (destTarget == gl::TextureTarget::_2D || destTarget == gl::TextureTarget::_3D ||
+ gl::IsCubeMapFaceTarget(destTarget))
+ {
+ destIndex = gl::ImageIndex::MakeFromTarget(destTarget, destLevel, 1);
+ }
+ else if (destTarget == gl::TextureTarget::_2DArray)
+ {
+ destIndex = gl::ImageIndex::Make2DArrayRange(destLevel, 0, sourceImageDesc.size.depth);
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+
+ RenderTargetD3D *destRenderTargetD3D = nullptr;
+ ANGLE_TRY(destStorage11->getRenderTarget(
+ context, destIndex, destStorage11->getRenderToTextureSamples(), &destRenderTargetD3D));
+
+ RenderTarget11 *destRenderTarget11 = GetAs<RenderTarget11>(destRenderTargetD3D);
+
+ const d3d11::RenderTargetView &destRTV = destRenderTarget11->getRenderTargetView();
+ ASSERT(destRTV.valid());
+
+ gl::Box sourceArea(sourceBox.x, sourceBox.y, sourceBox.z, sourceBox.width, sourceBox.height,
+ sourceBox.depth);
+
+ if (unpackFlipY)
+ {
+ sourceArea.y += sourceArea.height;
+ sourceArea.height = -sourceArea.height;
+ }
+
+ gl::Box destArea(destOffset.x, destOffset.y, destOffset.z, sourceBox.width,
+ sourceBox.height, sourceBox.depth);
+
+ gl::Extents destSize(destRenderTarget11->getWidth(), destRenderTarget11->getHeight(),
+ sourceBox.depth);
+
+ // Use nearest filtering because source and destination are the same size for the direct
+ // copy
+ GLenum sourceFormat = source->getFormat(srcTarget, sourceLevel).info->format;
+ ANGLE_TRY(mBlit->copyTexture(context, *sourceSRV, sourceArea, sourceImageDesc.size,
+ sourceFormat, destRTV, destArea, destSize, nullptr, destFormat,
+ destType, GL_NEAREST, false, unpackPremultiplyAlpha,
+ unpackUnmultiplyAlpha));
+ }
+
+ destStorage11->markLevelDirty(destLevel);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer11::copyCompressedTexture(const gl::Context *context,
+ const gl::Texture *source,
+ GLint sourceLevel,
+ TextureStorage *storage,
+ GLint destLevel)
+{
+ TextureStorage11_2D *destStorage11 = GetAs<TextureStorage11_2D>(storage);
+ ASSERT(destStorage11);
+
+ const TextureHelper11 *destResource = nullptr;
+ ANGLE_TRY(destStorage11->getResource(context, &destResource));
+
+ gl::ImageIndex destIndex = gl::ImageIndex::Make2D(destLevel);
+ UINT destSubresource = 0;
+ ANGLE_TRY(destStorage11->getSubresourceIndex(context, destIndex, &destSubresource));
+
+ TextureD3D *sourceD3D = GetImplAs<TextureD3D>(source);
+ ASSERT(sourceD3D);
+
+ TextureStorage *sourceStorage = nullptr;
+ ANGLE_TRY(sourceD3D->getNativeTexture(context, &sourceStorage));
+
+ TextureStorage11_2D *sourceStorage11 = GetAs<TextureStorage11_2D>(sourceStorage);
+ ASSERT(sourceStorage11);
+
+ const TextureHelper11 *sourceResource = nullptr;
+ ANGLE_TRY(sourceStorage11->getResource(context, &sourceResource));
+
+ gl::ImageIndex sourceIndex = gl::ImageIndex::Make2D(sourceLevel);
+ UINT sourceSubresource = 0;
+ ANGLE_TRY(sourceStorage11->getSubresourceIndex(context, sourceIndex, &sourceSubresource));
+
+ mDeviceContext->CopySubresourceRegion(destResource->get(), destSubresource, 0, 0, 0,
+ sourceResource->get(), sourceSubresource, nullptr);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer11::createRenderTarget(const gl::Context *context,
+ int width,
+ int height,
+ GLenum format,
+ GLsizei samples,
+ RenderTargetD3D **outRT)
+{
+ const d3d11::Format &formatInfo = d3d11::Format::Get(format, mRenderer11DeviceCaps);
+
+ const gl::TextureCaps &textureCaps = getNativeTextureCaps().get(format);
+ GLuint supportedSamples = textureCaps.getNearestSamples(samples);
+
+ Context11 *context11 = GetImplAs<Context11>(context);
+
+ if (width > 0 && height > 0)
+ {
+ // Create texture resource
+ D3D11_TEXTURE2D_DESC desc;
+ desc.Width = width;
+ desc.Height = height;
+ desc.MipLevels = 1;
+ desc.ArraySize = 1;
+ desc.Format = formatInfo.texFormat;
+ desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples;
+ desc.SampleDesc.Quality = getSampleDescQuality(supportedSamples);
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.CPUAccessFlags = 0;
+ desc.MiscFlags = 0;
+
+ // If a rendertarget or depthstencil format exists for this texture format,
+ // 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.rtvFormat != DXGI_FORMAT_UNKNOWN);
+ bindDSV = (formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN);
+ bindSRV = (formatInfo.srvFormat != DXGI_FORMAT_UNKNOWN);
+
+ bool isMultisampledDepthStencil = bindDSV && desc.SampleDesc.Count > 1;
+ if (isMultisampledDepthStencil &&
+ !mRenderer11DeviceCaps.supportsMultisampledDepthStencilSRVs)
+ {
+ bindSRV = false;
+ }
+
+ 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
+ ASSERT(bindRTV != bindDSV);
+
+ TextureHelper11 texture;
+ ANGLE_TRY(allocateTexture(context11, desc, formatInfo, &texture));
+ texture.setInternalName("createRenderTarget.Texture");
+
+ d3d11::SharedSRV srv;
+ d3d11::SharedSRV blitSRV;
+ if (bindSRV)
+ {
+ D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+ srvDesc.Format = formatInfo.srvFormat;
+ srvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_SRV_DIMENSION_TEXTURE2D
+ : D3D11_SRV_DIMENSION_TEXTURE2DMS;
+ srvDesc.Texture2D.MostDetailedMip = 0;
+ srvDesc.Texture2D.MipLevels = 1;
+
+ ANGLE_TRY(allocateResource(context11, srvDesc, texture.get(), &srv));
+ srv.setInternalName("createRenderTarget.SRV");
+
+ if (formatInfo.blitSRVFormat != formatInfo.srvFormat)
+ {
+ D3D11_SHADER_RESOURCE_VIEW_DESC blitSRVDesc;
+ blitSRVDesc.Format = formatInfo.blitSRVFormat;
+ blitSRVDesc.ViewDimension = (supportedSamples == 0)
+ ? D3D11_SRV_DIMENSION_TEXTURE2D
+ : D3D11_SRV_DIMENSION_TEXTURE2DMS;
+ blitSRVDesc.Texture2D.MostDetailedMip = 0;
+ blitSRVDesc.Texture2D.MipLevels = 1;
+
+ ANGLE_TRY(allocateResource(context11, blitSRVDesc, texture.get(), &blitSRV));
+ blitSRV.setInternalName("createRenderTarget.BlitSRV");
+ }
+ else
+ {
+ blitSRV = srv.makeCopy();
+ }
+ }
+
+ if (bindDSV)
+ {
+ D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
+ dsvDesc.Format = formatInfo.dsvFormat;
+ dsvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_DSV_DIMENSION_TEXTURE2D
+ : D3D11_DSV_DIMENSION_TEXTURE2DMS;
+ dsvDesc.Texture2D.MipSlice = 0;
+ dsvDesc.Flags = 0;
+
+ d3d11::DepthStencilView dsv;
+ ANGLE_TRY(allocateResource(context11, dsvDesc, texture.get(), &dsv));
+ dsv.setInternalName("createRenderTarget.DSV");
+
+ *outRT = new TextureRenderTarget11(std::move(dsv), texture, srv, format, formatInfo,
+ width, height, 1, supportedSamples);
+ }
+ else if (bindRTV)
+ {
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = formatInfo.rtvFormat;
+ rtvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_RTV_DIMENSION_TEXTURE2D
+ : D3D11_RTV_DIMENSION_TEXTURE2DMS;
+ rtvDesc.Texture2D.MipSlice = 0;
+
+ d3d11::RenderTargetView rtv;
+ ANGLE_TRY(allocateResource(context11, rtvDesc, texture.get(), &rtv));
+ rtv.setInternalName("createRenderTarget.RTV");
+
+ if (formatInfo.dataInitializerFunction != nullptr)
+ {
+ const float clearValues[4] = {0.0f, 0.0f, 0.0f, 1.0f};
+ mDeviceContext->ClearRenderTargetView(rtv.get(), clearValues);
+ }
+
+ *outRT = new TextureRenderTarget11(std::move(rtv), texture, srv, blitSRV, format,
+ formatInfo, width, height, 1, supportedSamples);
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+ }
+ else
+ {
+ *outRT = new TextureRenderTarget11(d3d11::RenderTargetView(), TextureHelper11(),
+ d3d11::SharedSRV(), d3d11::SharedSRV(), format,
+ d3d11::Format::Get(GL_NONE, mRenderer11DeviceCaps),
+ width, height, 1, supportedSamples);
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer11::createRenderTargetCopy(const gl::Context *context,
+ RenderTargetD3D *source,
+ RenderTargetD3D **outRT)
+{
+ ASSERT(source != nullptr);
+
+ RenderTargetD3D *newRT = nullptr;
+ ANGLE_TRY(createRenderTarget(context, source->getWidth(), source->getHeight(),
+ source->getInternalFormat(), source->getSamples(), &newRT));
+
+ RenderTarget11 *source11 = GetAs<RenderTarget11>(source);
+ RenderTarget11 *dest11 = GetAs<RenderTarget11>(newRT);
+
+ mDeviceContext->CopySubresourceRegion(dest11->getTexture().get(), dest11->getSubresourceIndex(),
+ 0, 0, 0, source11->getTexture().get(),
+ source11->getSubresourceIndex(), nullptr);
+ *outRT = newRT;
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer11::loadExecutable(d3d::Context *context,
+ const uint8_t *function,
+ size_t length,
+ gl::ShaderType type,
+ const std::vector<D3DVarying> &streamOutVaryings,
+ bool separatedOutputBuffers,
+ ShaderExecutableD3D **outExecutable)
+{
+ ShaderData shaderData(function, length);
+
+ switch (type)
+ {
+ case gl::ShaderType::Vertex:
+ {
+ d3d11::VertexShader vertexShader;
+ d3d11::GeometryShader streamOutShader;
+ ANGLE_TRY(allocateResource(context, shaderData, &vertexShader));
+
+ if (!streamOutVaryings.empty())
+ {
+ std::vector<D3D11_SO_DECLARATION_ENTRY> soDeclaration;
+ soDeclaration.reserve(streamOutVaryings.size());
+
+ for (const auto &streamOutVarying : streamOutVaryings)
+ {
+ D3D11_SO_DECLARATION_ENTRY entry = {};
+ entry.Stream = 0;
+ entry.SemanticName = streamOutVarying.semanticName.c_str();
+ entry.SemanticIndex = streamOutVarying.semanticIndex;
+ entry.StartComponent = 0;
+ entry.ComponentCount = static_cast<BYTE>(streamOutVarying.componentCount);
+ entry.OutputSlot = static_cast<BYTE>(
+ (separatedOutputBuffers ? streamOutVarying.outputSlot : 0));
+ soDeclaration.push_back(entry);
+ }
+
+ ANGLE_TRY(allocateResource(context, shaderData, &soDeclaration, &streamOutShader));
+ }
+
+ *outExecutable = new ShaderExecutable11(function, length, std::move(vertexShader),
+ std::move(streamOutShader));
+ }
+ break;
+ case gl::ShaderType::Fragment:
+ {
+ d3d11::PixelShader pixelShader;
+ ANGLE_TRY(allocateResource(context, shaderData, &pixelShader));
+ *outExecutable = new ShaderExecutable11(function, length, std::move(pixelShader));
+ }
+ break;
+ case gl::ShaderType::Geometry:
+ {
+ d3d11::GeometryShader geometryShader;
+ ANGLE_TRY(allocateResource(context, shaderData, &geometryShader));
+ *outExecutable = new ShaderExecutable11(function, length, std::move(geometryShader));
+ }
+ break;
+ case gl::ShaderType::Compute:
+ {
+ d3d11::ComputeShader computeShader;
+ ANGLE_TRY(allocateResource(context, shaderData, &computeShader));
+ *outExecutable = new ShaderExecutable11(function, length, std::move(computeShader));
+ }
+ break;
+ default:
+ ANGLE_HR_UNREACHABLE(context);
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer11::compileToExecutable(d3d::Context *context,
+ gl::InfoLog &infoLog,
+ const std::string &shaderHLSL,
+ gl::ShaderType type,
+ const std::vector<D3DVarying> &streamOutVaryings,
+ bool separatedOutputBuffers,
+ const CompilerWorkaroundsD3D &workarounds,
+ ShaderExecutableD3D **outExectuable)
+{
+ std::stringstream profileStream;
+
+ switch (type)
+ {
+ case gl::ShaderType::Vertex:
+ profileStream << "vs";
+ break;
+ case gl::ShaderType::Fragment:
+ profileStream << "ps";
+ break;
+ case gl::ShaderType::Geometry:
+ profileStream << "gs";
+ break;
+ case gl::ShaderType::Compute:
+ profileStream << "cs";
+ break;
+ default:
+ ANGLE_HR_UNREACHABLE(context);
+ }
+
+ profileStream << "_" << getMajorShaderModel() << "_" << getMinorShaderModel()
+ << getShaderModelSuffix();
+ std::string profile = profileStream.str();
+
+ UINT flags = D3DCOMPILE_OPTIMIZATION_LEVEL2;
+
+#if defined(ANGLE_ENABLE_DEBUG_TRACE)
+# ifndef NDEBUG
+ flags = D3DCOMPILE_SKIP_OPTIMIZATION;
+# endif // NDEBUG
+ flags |= D3DCOMPILE_DEBUG;
+#endif // defined(ANGLE_ENABLE_DEBUG_TRACE)
+
+ if (workarounds.enableIEEEStrictness)
+ flags |= D3DCOMPILE_IEEE_STRICTNESS;
+
+ // Sometimes D3DCompile will fail with the default compilation flags for complicated shaders
+ // when it would otherwise pass with alternative options.
+ // Try the default flags first and if compilation fails, try some alternatives.
+ std::vector<CompileConfig> configs;
+ configs.push_back(CompileConfig(flags, "default"));
+ configs.push_back(CompileConfig(flags | D3DCOMPILE_SKIP_VALIDATION, "skip validation"));
+ configs.push_back(CompileConfig(flags | D3DCOMPILE_SKIP_OPTIMIZATION, "skip optimization"));
+
+ if (getMajorShaderModel() == 4 && getShaderModelSuffix() != "")
+ {
+ // Some shaders might cause a "blob content mismatch between level9 and d3d10 shader".
+ // e.g. dEQP-GLES2.functional.shaders.struct.local.loop_nested_struct_array_*.
+ // Using the [unroll] directive works around this, as does this D3DCompile flag.
+ configs.push_back(
+ CompileConfig(flags | D3DCOMPILE_AVOID_FLOW_CONTROL, "avoid flow control"));
+ }
+
+ D3D_SHADER_MACRO loopMacros[] = {{"ANGLE_ENABLE_LOOP_FLATTEN", "1"}, {0, 0}};
+
+ // TODO(jmadill): Use ComPtr?
+ ID3DBlob *binary = nullptr;
+ std::string debugInfo;
+ ANGLE_TRY(mCompiler.compileToBinary(context, infoLog, shaderHLSL, profile, configs, loopMacros,
+ &binary, &debugInfo));
+
+ // It's possible that binary is NULL if the compiler failed in all configurations. Set the
+ // executable to NULL and return GL_NO_ERROR to signify that there was a link error but the
+ // internal state is still OK.
+ if (!binary)
+ {
+ *outExectuable = nullptr;
+ return angle::Result::Continue;
+ }
+
+ angle::Result error = loadExecutable(
+ context, static_cast<const uint8_t *>(binary->GetBufferPointer()), binary->GetBufferSize(),
+ type, streamOutVaryings, separatedOutputBuffers, outExectuable);
+
+ SafeRelease(binary);
+ if (error == angle::Result::Stop)
+ {
+ return error;
+ }
+
+ if (!debugInfo.empty())
+ {
+ (*outExectuable)->appendDebugInfo(debugInfo);
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer11::ensureHLSLCompilerInitialized(d3d::Context *context)
+{
+ return mCompiler.ensureInitialized(context);
+}
+
+UniformStorageD3D *Renderer11::createUniformStorage(size_t storageSize)
+{
+ return new UniformStorage11(storageSize);
+}
+
+VertexBuffer *Renderer11::createVertexBuffer()
+{
+ return new VertexBuffer11(this);
+}
+
+IndexBuffer *Renderer11::createIndexBuffer()
+{
+ return new IndexBuffer11(this);
+}
+
+StreamProducerImpl *Renderer11::createStreamProducerD3DTexture(
+ egl::Stream::ConsumerType consumerType,
+ const egl::AttributeMap &attribs)
+{
+ return new StreamProducerD3DTexture(this);
+}
+
+bool Renderer11::supportsFastCopyBufferToTexture(GLenum internalFormat) const
+{
+ ASSERT(getNativeExtensions().pixelBufferObjectNV);
+
+ const gl::InternalFormat &internalFormatInfo = gl::GetSizedInternalFormatInfo(internalFormat);
+ const d3d11::Format &d3d11FormatInfo =
+ d3d11::Format::Get(internalFormat, mRenderer11DeviceCaps);
+
+ // sRGB formats do not work with D3D11 buffer SRVs
+ if (internalFormatInfo.colorEncoding == GL_SRGB)
+ {
+ return false;
+ }
+
+ // We cannot support direct copies to non-color-renderable formats
+ if (d3d11FormatInfo.rtvFormat == DXGI_FORMAT_UNKNOWN)
+ {
+ return false;
+ }
+
+ // We skip all 3-channel formats since sometimes format support is missing
+ if (internalFormatInfo.componentCount == 3)
+ {
+ return false;
+ }
+
+ // We don't support formats which we can't represent without conversion
+ 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;
+ }
+
+ // This format is not supported as a buffer SRV.
+ if (d3d11FormatInfo.texFormat == DXGI_FORMAT_A8_UNORM)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+angle::Result Renderer11::fastCopyBufferToTexture(const gl::Context *context,
+ const gl::PixelUnpackState &unpack,
+ gl::Buffer *unpackBuffer,
+ unsigned int offset,
+ RenderTargetD3D *destRenderTarget,
+ GLenum destinationFormat,
+ GLenum sourcePixelsType,
+ const gl::Box &destArea)
+{
+ ASSERT(supportsFastCopyBufferToTexture(destinationFormat));
+ return mPixelTransfer->copyBufferToTexture(context, unpack, unpackBuffer, offset,
+ destRenderTarget, destinationFormat,
+ sourcePixelsType, destArea);
+}
+
+ImageD3D *Renderer11::createImage()
+{
+ return new Image11(this);
+}
+
+ExternalImageSiblingImpl *Renderer11::createExternalImageSibling(const gl::Context *context,
+ EGLenum target,
+ EGLClientBuffer buffer,
+ const egl::AttributeMap &attribs)
+{
+ switch (target)
+ {
+ case EGL_D3D11_TEXTURE_ANGLE:
+ return new ExternalImageSiblingImpl11(this, buffer, attribs);
+
+ default:
+ UNREACHABLE();
+ return nullptr;
+ }
+}
+
+angle::Result Renderer11::generateMipmap(const gl::Context *context, ImageD3D *dest, ImageD3D *src)
+{
+ Image11 *dest11 = GetAs<Image11>(dest);
+ Image11 *src11 = GetAs<Image11>(src);
+ return Image11::GenerateMipmap(context, dest11, src11, mRenderer11DeviceCaps);
+}
+
+angle::Result Renderer11::generateMipmapUsingD3D(const gl::Context *context,
+ TextureStorage *storage,
+ const gl::TextureState &textureState)
+{
+ TextureStorage11 *storage11 = GetAs<TextureStorage11>(storage);
+
+ ASSERT(storage11->isRenderTarget());
+ ASSERT(storage11->supportsNativeMipmapFunction());
+
+ const d3d11::SharedSRV *srv = nullptr;
+ ANGLE_TRY(storage11->getSRVLevels(context, textureState.getEffectiveBaseLevel(),
+ textureState.getEffectiveMaxLevel(), &srv));
+
+ mDeviceContext->GenerateMips(srv->get());
+
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer11::copyImage(const gl::Context *context,
+ ImageD3D *dest,
+ ImageD3D *source,
+ const gl::Box &sourceBox,
+ const gl::Offset &destOffset,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha)
+{
+ Image11 *dest11 = GetAs<Image11>(dest);
+ Image11 *src11 = GetAs<Image11>(source);
+ return Image11::CopyImage(context, dest11, src11, sourceBox, destOffset, unpackFlipY,
+ unpackPremultiplyAlpha, unpackUnmultiplyAlpha, mRenderer11DeviceCaps);
+}
+
+TextureStorage *Renderer11::createTextureStorage2D(SwapChainD3D *swapChain,
+ const std::string &label)
+{
+ SwapChain11 *swapChain11 = GetAs<SwapChain11>(swapChain);
+ return new TextureStorage11_2D(this, swapChain11, label);
+}
+
+TextureStorage *Renderer11::createTextureStorageEGLImage(EGLImageD3D *eglImage,
+ RenderTargetD3D *renderTargetD3D,
+ const std::string &label)
+{
+ return new TextureStorage11_EGLImage(this, eglImage, GetAs<RenderTarget11>(renderTargetD3D),
+ label);
+}
+
+TextureStorage *Renderer11::createTextureStorageExternal(
+ egl::Stream *stream,
+ const egl::Stream::GLTextureDescription &desc,
+ const std::string &label)
+{
+ return new TextureStorage11_External(this, stream, desc, label);
+}
+
+TextureStorage *Renderer11::createTextureStorage2D(GLenum internalformat,
+ BindFlags bindFlags,
+ GLsizei width,
+ GLsizei height,
+ int levels,
+ const std::string &label,
+ bool hintLevelZeroOnly)
+{
+ return new TextureStorage11_2D(this, internalformat, bindFlags, width, height, levels, label,
+ hintLevelZeroOnly);
+}
+
+TextureStorage *Renderer11::createTextureStorageCube(GLenum internalformat,
+ BindFlags bindFlags,
+ int size,
+ int levels,
+ bool hintLevelZeroOnly,
+ const std::string &label)
+{
+ return new TextureStorage11_Cube(this, internalformat, bindFlags, size, levels,
+ hintLevelZeroOnly, label);
+}
+
+TextureStorage *Renderer11::createTextureStorage3D(GLenum internalformat,
+ BindFlags bindFlags,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ int levels,
+ const std::string &label)
+{
+ return new TextureStorage11_3D(this, internalformat, bindFlags, width, height, depth, levels,
+ label);
+}
+
+TextureStorage *Renderer11::createTextureStorage2DArray(GLenum internalformat,
+ BindFlags bindFlags,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ int levels,
+ const std::string &label)
+{
+ return new TextureStorage11_2DArray(this, internalformat, bindFlags, width, height, depth,
+ levels, label);
+}
+
+TextureStorage *Renderer11::createTextureStorage2DMultisample(GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ int levels,
+ int samples,
+ bool fixedSampleLocations,
+ const std::string &label)
+{
+ return new TextureStorage11_2DMultisample(this, internalformat, width, height, levels, samples,
+ fixedSampleLocations, label);
+}
+
+TextureStorage *Renderer11::createTextureStorageBuffer(
+ const gl::OffsetBindingPointer<gl::Buffer> &buffer,
+ GLenum internalFormat,
+ const std::string &label)
+{
+ return new TextureStorage11_Buffer(this, buffer, internalFormat, label);
+}
+
+TextureStorage *Renderer11::createTextureStorage2DMultisampleArray(GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ int levels,
+ int samples,
+ bool fixedSampleLocations,
+ const std::string &label)
+{
+ return new TextureStorage11_2DMultisampleArray(this, internalformat, width, height, depth,
+ levels, samples, fixedSampleLocations, label);
+}
+
+angle::Result Renderer11::readFromAttachment(const gl::Context *context,
+ const gl::FramebufferAttachment &srcAttachment,
+ const gl::Rectangle &sourceArea,
+ GLenum format,
+ GLenum type,
+ GLuint outputPitch,
+ const gl::PixelPackState &pack,
+ uint8_t *pixelsOut)
+{
+ ASSERT(sourceArea.width >= 0);
+ ASSERT(sourceArea.height >= 0);
+
+ const bool invertTexture = UsePresentPathFast(this, &srcAttachment);
+
+ RenderTarget11 *rt11 = nullptr;
+ ANGLE_TRY(srcAttachment.getRenderTarget(context, 0, &rt11));
+ ASSERT(rt11->getTexture().valid());
+
+ const TextureHelper11 &textureHelper = rt11->getTexture();
+ unsigned int sourceSubResource = rt11->getSubresourceIndex();
+
+ const gl::Extents &texSize = textureHelper.getExtents();
+
+ gl::Rectangle actualArea = sourceArea;
+ bool reverseRowOrder = pack.reverseRowOrder;
+ if (invertTexture)
+ {
+ actualArea.y = texSize.height - actualArea.y - actualArea.height;
+ reverseRowOrder = !reverseRowOrder;
+ }
+
+ // Clamp read region to the defined texture boundaries, preventing out of bounds reads
+ // and reads of uninitialized data.
+ gl::Rectangle safeArea;
+ safeArea.x = gl::clamp(actualArea.x, 0, texSize.width);
+ safeArea.y = gl::clamp(actualArea.y, 0, texSize.height);
+ safeArea.width =
+ gl::clamp(actualArea.width + std::min(actualArea.x, 0), 0, texSize.width - safeArea.x);
+ safeArea.height =
+ gl::clamp(actualArea.height + std::min(actualArea.y, 0), 0, texSize.height - safeArea.y);
+
+ ASSERT(safeArea.x >= 0 && safeArea.y >= 0);
+ ASSERT(safeArea.x + safeArea.width <= texSize.width);
+ ASSERT(safeArea.y + safeArea.height <= texSize.height);
+
+ if (safeArea.width == 0 || safeArea.height == 0)
+ {
+ // no work to do
+ return angle::Result::Continue;
+ }
+
+ gl::Extents safeSize(safeArea.width, safeArea.height, 1);
+ TextureHelper11 stagingHelper;
+ ANGLE_TRY(createStagingTexture(context, textureHelper.getTextureType(),
+ textureHelper.getFormatSet(), safeSize, StagingAccess::READ,
+ &stagingHelper));
+ stagingHelper.setInternalName("readFromAttachment::stagingHelper");
+
+ TextureHelper11 resolvedTextureHelper;
+
+ // "srcTexture" usually points to the source texture.
+ // For 2D multisampled textures, it points to the multisampled resolve texture.
+ const TextureHelper11 *srcTexture = &textureHelper;
+
+ if (textureHelper.is2D() && textureHelper.getSampleCount() > 1)
+ {
+ D3D11_TEXTURE2D_DESC resolveDesc;
+ resolveDesc.Width = static_cast<UINT>(texSize.width);
+ resolveDesc.Height = static_cast<UINT>(texSize.height);
+ resolveDesc.MipLevels = 1;
+ resolveDesc.ArraySize = 1;
+ resolveDesc.Format = textureHelper.getFormat();
+ resolveDesc.SampleDesc.Count = 1;
+ resolveDesc.SampleDesc.Quality = 0;
+ resolveDesc.Usage = D3D11_USAGE_DEFAULT;
+ resolveDesc.BindFlags = 0;
+ resolveDesc.CPUAccessFlags = 0;
+ resolveDesc.MiscFlags = 0;
+
+ ANGLE_TRY(allocateTexture(GetImplAs<Context11>(context), resolveDesc,
+ textureHelper.getFormatSet(), &resolvedTextureHelper));
+ resolvedTextureHelper.setInternalName("readFromAttachment::resolvedTextureHelper");
+
+ mDeviceContext->ResolveSubresource(resolvedTextureHelper.get(), 0, textureHelper.get(),
+ sourceSubResource, textureHelper.getFormat());
+
+ sourceSubResource = 0;
+ srcTexture = &resolvedTextureHelper;
+ }
+
+ D3D11_BOX srcBox;
+ srcBox.left = static_cast<UINT>(safeArea.x);
+ srcBox.right = static_cast<UINT>(safeArea.x + safeArea.width);
+ srcBox.top = static_cast<UINT>(safeArea.y);
+ srcBox.bottom = static_cast<UINT>(safeArea.y + safeArea.height);
+
+ // Select the correct layer from a 3D attachment
+ srcBox.front = 0;
+ if (textureHelper.is3D())
+ {
+ srcBox.front = static_cast<UINT>(srcAttachment.layer());
+ }
+ srcBox.back = srcBox.front + 1;
+
+ mDeviceContext->CopySubresourceRegion(stagingHelper.get(), 0, 0, 0, 0, srcTexture->get(),
+ sourceSubResource, &srcBox);
+
+ const angle::Format &angleFormat = GetFormatFromFormatType(format, type);
+ gl::Buffer *packBuffer = context->getState().getTargetBuffer(gl::BufferBinding::PixelPack);
+
+ PackPixelsParams packParams(safeArea, angleFormat, outputPitch, reverseRowOrder, packBuffer, 0);
+ return packPixels(context, stagingHelper, packParams, pixelsOut);
+}
+
+angle::Result Renderer11::packPixels(const gl::Context *context,
+ const TextureHelper11 &textureHelper,
+ const PackPixelsParams &params,
+ uint8_t *pixelsOut)
+{
+ ID3D11Resource *readResource = textureHelper.get();
+
+ D3D11_MAPPED_SUBRESOURCE mapping;
+ ANGLE_TRY(mapResource(context, readResource, 0, D3D11_MAP_READ, 0, &mapping));
+
+ uint8_t *source = static_cast<uint8_t *>(mapping.pData);
+ int inputPitch = static_cast<int>(mapping.RowPitch);
+
+ const auto &formatInfo = textureHelper.getFormatSet();
+ ASSERT(formatInfo.format().glInternalFormat != GL_NONE);
+
+ PackPixels(params, formatInfo.format(), inputPitch, source, pixelsOut);
+
+ mDeviceContext->Unmap(readResource, 0);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer11::blitRenderbufferRect(const gl::Context *context,
+ const gl::Rectangle &readRectIn,
+ const gl::Rectangle &drawRectIn,
+ UINT readLayer,
+ UINT drawLayer,
+ RenderTargetD3D *readRenderTarget,
+ RenderTargetD3D *drawRenderTarget,
+ GLenum filter,
+ const gl::Rectangle *scissor,
+ bool colorBlit,
+ bool depthBlit,
+ bool stencilBlit)
+{
+ // Since blitRenderbufferRect is called for each render buffer that needs to be blitted,
+ // it should never be the case that both color and depth/stencil need to be blitted at
+ // at the same time.
+ ASSERT(colorBlit != (depthBlit || stencilBlit));
+
+ RenderTarget11 *drawRenderTarget11 = GetAs<RenderTarget11>(drawRenderTarget);
+ ASSERT(drawRenderTarget11);
+
+ const TextureHelper11 &drawTexture = drawRenderTarget11->getTexture();
+ unsigned int drawSubresource = drawRenderTarget11->getSubresourceIndex();
+
+ RenderTarget11 *readRenderTarget11 = GetAs<RenderTarget11>(readRenderTarget);
+ ASSERT(readRenderTarget11);
+
+ const gl::Extents readSize(readRenderTarget->getWidth(), readRenderTarget->getHeight(), 1);
+ const gl::Extents drawSize(drawRenderTarget->getWidth(), drawRenderTarget->getHeight(), 1);
+
+ // From the spec:
+ // "The actual region taken from the read framebuffer is limited to the intersection of the
+ // source buffers being transferred, which may include the color buffer selected by the read
+ // buffer, the depth buffer, and / or the stencil buffer depending on mask."
+ // This means negative x and y are out of bounds, and not to be read from. We handle this here
+ // by internally scaling the read and draw rectangles.
+
+ // Remove reversal from readRect to simplify further operations.
+ gl::Rectangle readRect = readRectIn;
+ gl::Rectangle drawRect = drawRectIn;
+ if (readRect.isReversedX())
+ {
+ readRect.x = readRect.x + readRect.width;
+ readRect.width = -readRect.width;
+ drawRect.x = drawRect.x + drawRect.width;
+ drawRect.width = -drawRect.width;
+ }
+ if (readRect.isReversedY())
+ {
+ readRect.y = readRect.y + readRect.height;
+ readRect.height = -readRect.height;
+ drawRect.y = drawRect.y + drawRect.height;
+ drawRect.height = -drawRect.height;
+ }
+
+ gl::Rectangle readBounds(0, 0, readSize.width, readSize.height);
+ gl::Rectangle inBoundsReadRect;
+ if (!gl::ClipRectangle(readRect, readBounds, &inBoundsReadRect))
+ {
+ return angle::Result::Continue;
+ }
+
+ {
+ // Calculate the drawRect that corresponds to inBoundsReadRect.
+ auto readToDrawX = [&drawRect, &readRect](int readOffset) {
+ double readToDrawScale =
+ static_cast<double>(drawRect.width) / static_cast<double>(readRect.width);
+ return static_cast<int>(
+ round(static_cast<double>(readOffset - readRect.x) * readToDrawScale) + drawRect.x);
+ };
+ auto readToDrawY = [&drawRect, &readRect](int readOffset) {
+ double readToDrawScale =
+ static_cast<double>(drawRect.height) / static_cast<double>(readRect.height);
+ return static_cast<int>(
+ round(static_cast<double>(readOffset - readRect.y) * readToDrawScale) + drawRect.y);
+ };
+
+ gl::Rectangle drawRectMatchingInBoundsReadRect;
+ drawRectMatchingInBoundsReadRect.x = readToDrawX(inBoundsReadRect.x);
+ drawRectMatchingInBoundsReadRect.y = readToDrawY(inBoundsReadRect.y);
+ drawRectMatchingInBoundsReadRect.width =
+ readToDrawX(inBoundsReadRect.x1()) - drawRectMatchingInBoundsReadRect.x;
+ drawRectMatchingInBoundsReadRect.height =
+ readToDrawY(inBoundsReadRect.y1()) - drawRectMatchingInBoundsReadRect.y;
+ drawRect = drawRectMatchingInBoundsReadRect;
+ readRect = inBoundsReadRect;
+ }
+
+ bool scissorNeeded = false;
+ if (scissor)
+ {
+ gl::Rectangle scissoredDrawRect;
+ if (!gl::ClipRectangle(drawRect, *scissor, &scissoredDrawRect))
+ {
+ return angle::Result::Continue;
+ }
+ scissorNeeded = scissoredDrawRect != drawRect;
+ }
+
+ const auto &destFormatInfo =
+ gl::GetSizedInternalFormatInfo(drawRenderTarget->getInternalFormat());
+ const auto &srcFormatInfo =
+ gl::GetSizedInternalFormatInfo(readRenderTarget->getInternalFormat());
+ 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) && (nativeFormat.redBits > 0);
+ colorMask.green = (srcFormatInfo.greenBits > 0) && (destFormatInfo.greenBits == 0) &&
+ (nativeFormat.greenBits > 0);
+ colorMask.blue = (srcFormatInfo.blueBits > 0) && (destFormatInfo.blueBits == 0) &&
+ (nativeFormat.blueBits > 0);
+ colorMask.alpha = (srcFormatInfo.alphaBits > 0) && (destFormatInfo.alphaBits == 0) &&
+ (nativeFormat.alphaBits > 0);
+
+ // We only currently support masking off the alpha channel.
+ bool colorMaskingNeeded = colorMask.alpha;
+ ASSERT(!colorMask.red && !colorMask.green && !colorMask.blue);
+
+ bool wholeBufferCopy = !scissorNeeded && !colorMaskingNeeded && readRect.x == 0 &&
+ readRect.width == readSize.width && readRect.y == 0 &&
+ readRect.height == readSize.height && drawRect.x == 0 &&
+ drawRect.width == drawSize.width && drawRect.y == 0 &&
+ drawRect.height == drawSize.height;
+
+ bool stretchRequired = readRect.width != drawRect.width || readRect.height != drawRect.height;
+
+ ASSERT(!readRect.isReversedX() && !readRect.isReversedY());
+ bool reversalRequired = drawRect.isReversedX() || drawRect.isReversedY();
+
+ bool outOfBounds = readRect.x < 0 || readRect.x + readRect.width > readSize.width ||
+ readRect.y < 0 || readRect.y + readRect.height > readSize.height ||
+ drawRect.x < 0 || drawRect.x + drawRect.width > drawSize.width ||
+ drawRect.y < 0 || drawRect.y + drawRect.height > drawSize.height;
+
+ bool partialDSBlit =
+ (nativeFormat.depthBits > 0 && depthBlit) != (nativeFormat.stencilBits > 0 && stencilBlit);
+
+ const bool canCopySubresource =
+ drawRenderTarget->getSamples() == readRenderTarget->getSamples() &&
+ readRenderTarget11->getFormatSet().formatID ==
+ drawRenderTarget11->getFormatSet().formatID &&
+ !stretchRequired && !outOfBounds && !reversalRequired && !partialDSBlit &&
+ !colorMaskingNeeded && (!(depthBlit || stencilBlit) || wholeBufferCopy);
+
+ TextureHelper11 readTexture;
+ unsigned int readSubresource = 0;
+ d3d11::SharedSRV readSRV;
+
+ if (readRenderTarget->isMultisampled())
+ {
+ ANGLE_TRY(resolveMultisampledTexture(context, readRenderTarget11, depthBlit, stencilBlit,
+ &readTexture));
+
+ if (!stencilBlit && !canCopySubresource)
+ {
+ const auto &readFormatSet = readTexture.getFormatSet();
+
+ D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc;
+ viewDesc.Format = readFormatSet.srvFormat;
+ viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
+ viewDesc.Texture2D.MipLevels = 1;
+ viewDesc.Texture2D.MostDetailedMip = 0;
+
+ ANGLE_TRY(allocateResource(GetImplAs<Context11>(context), viewDesc, readTexture.get(),
+ &readSRV));
+ }
+ }
+ else
+ {
+ ASSERT(readRenderTarget11);
+ readTexture = readRenderTarget11->getTexture();
+ readSubresource = readRenderTarget11->getSubresourceIndex();
+ if (!canCopySubresource)
+ {
+ const d3d11::SharedSRV *blitSRV;
+ ANGLE_TRY(readRenderTarget11->getBlitShaderResourceView(context, &blitSRV));
+ readSRV = blitSRV->makeCopy();
+ if (!readSRV.valid())
+ {
+ ASSERT(depthBlit || stencilBlit);
+ const d3d11::SharedSRV *srv;
+ ANGLE_TRY(readRenderTarget11->getShaderResourceView(context, &srv));
+ readSRV = srv->makeCopy();
+ }
+ ASSERT(readSRV.valid());
+ }
+ }
+
+ if (canCopySubresource)
+ {
+ UINT dstX = drawRect.x;
+ UINT dstY = drawRect.y;
+ UINT dstZ = drawLayer;
+
+ D3D11_BOX readBox;
+ readBox.left = readRect.x;
+ readBox.right = readRect.x + readRect.width;
+ readBox.top = readRect.y;
+ readBox.bottom = readRect.y + readRect.height;
+ readBox.front = readLayer;
+ readBox.back = readLayer + 1;
+
+ if (scissorNeeded)
+ {
+ // drawRect is guaranteed to have positive width and height because stretchRequired is
+ // false.
+ ASSERT(drawRect.width >= 0 || drawRect.height >= 0);
+
+ if (drawRect.x < scissor->x)
+ {
+ dstX = scissor->x;
+ readBox.left += (scissor->x - drawRect.x);
+ }
+ if (drawRect.y < scissor->y)
+ {
+ dstY = scissor->y;
+ readBox.top += (scissor->y - drawRect.y);
+ }
+ if (drawRect.x + drawRect.width > scissor->x + scissor->width)
+ {
+ readBox.right -= ((drawRect.x + drawRect.width) - (scissor->x + scissor->width));
+ }
+ if (drawRect.y + drawRect.height > scissor->y + scissor->height)
+ {
+ readBox.bottom -= ((drawRect.y + drawRect.height) - (scissor->y + scissor->height));
+ }
+ }
+
+ // D3D11 needs depth-stencil CopySubresourceRegions to have a NULL pSrcBox
+ // We also require complete framebuffer copies for depth-stencil blit.
+ D3D11_BOX *pSrcBox = wholeBufferCopy && readLayer == 0 ? nullptr : &readBox;
+
+ mDeviceContext->CopySubresourceRegion(drawTexture.get(), drawSubresource, dstX, dstY, dstZ,
+ readTexture.get(), readSubresource, pSrcBox);
+ }
+ else
+ {
+ gl::Box readArea(readRect.x, readRect.y, 0, readRect.width, readRect.height, 1);
+ gl::Box drawArea(drawRect.x, drawRect.y, 0, drawRect.width, drawRect.height, 1);
+
+ if (depthBlit && stencilBlit)
+ {
+ ANGLE_TRY(mBlit->copyDepthStencil(context, readTexture, readSubresource, readArea,
+ readSize, drawTexture, drawSubresource, drawArea,
+ drawSize, scissor));
+ }
+ else if (depthBlit)
+ {
+ const d3d11::DepthStencilView &drawDSV = drawRenderTarget11->getDepthStencilView();
+ ASSERT(readSRV.valid());
+ ANGLE_TRY(mBlit->copyDepth(context, readSRV, readArea, readSize, drawDSV, drawArea,
+ drawSize, scissor));
+ }
+ else if (stencilBlit)
+ {
+ ANGLE_TRY(mBlit->copyStencil(context, readTexture, readSubresource, readArea, readSize,
+ drawTexture, drawSubresource, drawArea, drawSize,
+ scissor));
+ }
+ else
+ {
+ const d3d11::RenderTargetView &drawRTV = drawRenderTarget11->getRenderTargetView();
+
+ // We don't currently support masking off any other channel than alpha
+ bool maskOffAlpha = colorMaskingNeeded && colorMask.alpha;
+ ASSERT(readSRV.valid());
+ ANGLE_TRY(mBlit->copyTexture(context, readSRV, readArea, readSize, srcFormatInfo.format,
+ drawRTV, drawArea, drawSize, scissor,
+ destFormatInfo.format, GL_NONE, filter, maskOffAlpha,
+ false, false));
+ }
+ }
+
+ return angle::Result::Continue;
+}
+
+bool Renderer11::isES3Capable() const
+{
+ return (d3d11_gl::GetMaximumClientVersion(mRenderer11DeviceCaps).major > 2);
+}
+
+RendererClass Renderer11::getRendererClass() const
+{
+ return RENDERER_D3D11;
+}
+
+void Renderer11::onSwap()
+{
+ // Send histogram updates every half hour
+ const double kHistogramUpdateInterval = 30 * 60;
+
+ auto *platform = ANGLEPlatformCurrent();
+ const double currentTime = platform->monotonicallyIncreasingTime(platform);
+ const double timeSinceLastUpdate = currentTime - mLastHistogramUpdateTime;
+
+ if (timeSinceLastUpdate > kHistogramUpdateInterval)
+ {
+ updateHistograms();
+ mLastHistogramUpdateTime = currentTime;
+ }
+}
+
+void Renderer11::updateHistograms()
+{
+ // Update the buffer CPU memory histogram
+ {
+ size_t sizeSum = 0;
+ for (const Buffer11 *buffer : mAliveBuffers)
+ {
+ sizeSum += buffer->getTotalCPUBufferMemoryBytes();
+ }
+ const int kOneMegaByte = 1024 * 1024;
+ ANGLE_HISTOGRAM_MEMORY_MB("GPU.ANGLE.Buffer11CPUMemoryMB",
+ static_cast<int>(sizeSum) / kOneMegaByte);
+ }
+}
+
+void Renderer11::onBufferCreate(const Buffer11 *created)
+{
+ mAliveBuffers.insert(created);
+}
+
+void Renderer11::onBufferDelete(const Buffer11 *deleted)
+{
+ mAliveBuffers.erase(deleted);
+}
+
+angle::Result Renderer11::resolveMultisampledTexture(const gl::Context *context,
+ RenderTarget11 *renderTarget,
+ bool depth,
+ bool stencil,
+ TextureHelper11 *textureOut)
+{
+ if (depth && !stencil)
+ {
+ return mBlit->resolveDepth(context, renderTarget, textureOut);
+ }
+
+ if (stencil)
+ {
+ return mBlit->resolveStencil(context, renderTarget, depth, textureOut);
+ }
+
+ const auto &formatSet = renderTarget->getFormatSet();
+
+ ASSERT(renderTarget->isMultisampled());
+ const d3d11::SharedSRV *sourceSRV;
+ ANGLE_TRY(renderTarget->getShaderResourceView(context, &sourceSRV));
+ D3D11_SHADER_RESOURCE_VIEW_DESC sourceSRVDesc;
+ sourceSRV->get()->GetDesc(&sourceSRVDesc);
+ ASSERT(sourceSRVDesc.ViewDimension == D3D_SRV_DIMENSION_TEXTURE2DMS ||
+ sourceSRVDesc.ViewDimension == D3D_SRV_DIMENSION_TEXTURE2DMSARRAY);
+
+ if (!mCachedResolveTexture.valid() ||
+ mCachedResolveTexture.getExtents().width != renderTarget->getWidth() ||
+ mCachedResolveTexture.getExtents().height != renderTarget->getHeight() ||
+ mCachedResolveTexture.getFormat() != formatSet.texFormat)
+ {
+ D3D11_TEXTURE2D_DESC resolveDesc;
+ resolveDesc.Width = renderTarget->getWidth();
+ resolveDesc.Height = renderTarget->getHeight();
+ resolveDesc.MipLevels = 1;
+ resolveDesc.ArraySize = 1;
+ resolveDesc.Format = formatSet.texFormat;
+ resolveDesc.SampleDesc.Count = 1;
+ resolveDesc.SampleDesc.Quality = 0;
+ resolveDesc.Usage = D3D11_USAGE_DEFAULT;
+ resolveDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
+ resolveDesc.CPUAccessFlags = 0;
+ resolveDesc.MiscFlags = 0;
+
+ ANGLE_TRY(allocateTexture(GetImplAs<Context11>(context), resolveDesc, formatSet,
+ &mCachedResolveTexture));
+ }
+
+ mDeviceContext->ResolveSubresource(mCachedResolveTexture.get(), 0,
+ renderTarget->getTexture().get(),
+ renderTarget->getSubresourceIndex(), formatSet.texFormat);
+ *textureOut = mCachedResolveTexture;
+ return angle::Result::Continue;
+}
+
+bool Renderer11::getLUID(LUID *adapterLuid) const
+{
+ adapterLuid->HighPart = 0;
+ adapterLuid->LowPart = 0;
+
+ if (!mDxgiAdapter)
+ {
+ return false;
+ }
+
+ DXGI_ADAPTER_DESC adapterDesc;
+ if (FAILED(mDxgiAdapter->GetDesc(&adapterDesc)))
+ {
+ return false;
+ }
+
+ *adapterLuid = adapterDesc.AdapterLuid;
+ return true;
+}
+
+VertexConversionType Renderer11::getVertexConversionType(angle::FormatID vertexFormatID) const
+{
+ return d3d11::GetVertexFormatInfo(vertexFormatID, mRenderer11DeviceCaps.featureLevel)
+ .conversionType;
+}
+
+GLenum Renderer11::getVertexComponentType(angle::FormatID vertexFormatID) const
+{
+ const auto &format =
+ d3d11::GetVertexFormatInfo(vertexFormatID, mRenderer11DeviceCaps.featureLevel);
+ return d3d11::GetComponentType(format.nativeFormat);
+}
+
+angle::Result Renderer11::getVertexSpaceRequired(const gl::Context *context,
+ const gl::VertexAttribute &attrib,
+ const gl::VertexBinding &binding,
+ size_t count,
+ GLsizei instances,
+ GLuint baseInstance,
+ unsigned int *bytesRequiredOut) const
+{
+ if (!attrib.enabled)
+ {
+ *bytesRequiredOut = 16u;
+ return angle::Result::Continue;
+ }
+
+ unsigned int elementCount = 0;
+ const unsigned int divisor = binding.getDivisor();
+ if (instances == 0 || divisor == 0)
+ {
+ // This could be a clipped cast.
+ elementCount = gl::clampCast<unsigned int>(count);
+ }
+ else
+ {
+ // Round up to divisor, if possible
+ elementCount =
+ UnsignedCeilDivide(static_cast<unsigned int>(instances + baseInstance), divisor);
+ }
+
+ ASSERT(elementCount > 0);
+
+ const D3D_FEATURE_LEVEL featureLevel = mRenderer11DeviceCaps.featureLevel;
+ const d3d11::VertexFormat &vertexFormatInfo =
+ d3d11::GetVertexFormatInfo(attrib.format->id, featureLevel);
+ const d3d11::DXGIFormatSize &dxgiFormatInfo =
+ d3d11::GetDXGIFormatSizeInfo(vertexFormatInfo.nativeFormat);
+ unsigned int elementSize = dxgiFormatInfo.pixelBytes;
+ bool check = (elementSize > std::numeric_limits<unsigned int>::max() / elementCount);
+ ANGLE_CHECK(GetImplAs<Context11>(context), !check,
+ "New vertex buffer size would result in an overflow.", GL_OUT_OF_MEMORY);
+
+ *bytesRequiredOut = elementSize * elementCount;
+ return angle::Result::Continue;
+}
+
+void Renderer11::generateCaps(gl::Caps *outCaps,
+ gl::TextureCapsMap *outTextureCaps,
+ gl::Extensions *outExtensions,
+ gl::Limitations *outLimitations) const
+{
+ d3d11_gl::GenerateCaps(mDevice, mDeviceContext, mRenderer11DeviceCaps, getFeatures(),
+ mDescription, outCaps, outTextureCaps, outExtensions, outLimitations);
+}
+
+void Renderer11::initializeFeatures(angle::FeaturesD3D *features) const
+{
+ if (!mDisplay->getState().featuresAllDisabled)
+ {
+ d3d11::InitializeFeatures(mRenderer11DeviceCaps, mAdapterDescription, features);
+ }
+ ApplyFeatureOverrides(features, mDisplay->getState());
+}
+
+void Renderer11::initializeFrontendFeatures(angle::FrontendFeatures *features) const
+{
+ if (!mDisplay->getState().featuresAllDisabled)
+ {
+ d3d11::InitializeFrontendFeatures(mAdapterDescription, features);
+ }
+ ApplyFeatureOverrides(features, mDisplay->getState());
+}
+
+DeviceImpl *Renderer11::createEGLDevice()
+{
+ return new DeviceD3D(EGL_D3D11_DEVICE_ANGLE, mDevice);
+}
+
+ContextImpl *Renderer11::createContext(const gl::State &state, gl::ErrorSet *errorSet)
+{
+ return new Context11(state, errorSet, this);
+}
+
+FramebufferImpl *Renderer11::createDefaultFramebuffer(const gl::FramebufferState &state)
+{
+ return new Framebuffer11(state, this);
+}
+
+angle::Result Renderer11::getScratchMemoryBuffer(Context11 *context11,
+ size_t requestedSize,
+ angle::MemoryBuffer **bufferOut)
+{
+ ANGLE_CHECK_GL_ALLOC(context11, mScratchMemoryBuffer.get(requestedSize, bufferOut));
+ return angle::Result::Continue;
+}
+
+gl::Version Renderer11::getMaxSupportedESVersion() const
+{
+ return d3d11_gl::GetMaximumClientVersion(mRenderer11DeviceCaps);
+}
+
+gl::Version Renderer11::getMaxConformantESVersion() const
+{
+ // 3.1 support is in progress.
+ return std::min(getMaxSupportedESVersion(), gl::Version(3, 0));
+}
+
+DebugAnnotatorContext11 *Renderer11::getDebugAnnotatorContext()
+{
+ return &mAnnotatorContext;
+}
+
+angle::Result Renderer11::dispatchCompute(const gl::Context *context,
+ GLuint numGroupsX,
+ GLuint numGroupsY,
+ GLuint numGroupsZ)
+{
+ const gl::State &glState = context->getState();
+ const gl::Program *program = glState.getProgram();
+ if (program->getActiveShaderStorageBlockCount() > 0 ||
+ program->getActiveAtomicCounterBufferCount() > 0)
+ {
+ ANGLE_TRY(markRawBufferUsage(context));
+ }
+ ANGLE_TRY(markTypedBufferUsage(context));
+ ANGLE_TRY(mStateManager.updateStateForCompute(context, numGroupsX, numGroupsY, numGroupsZ));
+ mDeviceContext->Dispatch(numGroupsX, numGroupsY, numGroupsZ);
+
+ return angle::Result::Continue;
+}
+angle::Result Renderer11::dispatchComputeIndirect(const gl::Context *context, GLintptr indirect)
+{
+ const auto &glState = context->getState();
+ const gl::Program *program = glState.getProgram();
+ if (program->getActiveShaderStorageBlockCount() > 0 ||
+ program->getActiveAtomicCounterBufferCount() > 0)
+ {
+ ANGLE_TRY(markRawBufferUsage(context));
+ }
+
+ auto *dispatchIndirectBuffer = glState.getTargetBuffer(gl::BufferBinding::DispatchIndirect);
+ ASSERT(dispatchIndirectBuffer);
+
+ Buffer11 *storage = GetImplAs<Buffer11>(dispatchIndirectBuffer);
+ const uint8_t *bufferData = nullptr;
+ // TODO(jie.a.chen@intel.com): num_groups_x,y,z have to be written into the driver constant
+ // buffer for the built-in variable gl_NumWorkGroups. There is an opportunity for optimization
+ // to use GPU->GPU copy instead.
+ // http://anglebug.com/2807
+ ANGLE_TRY(storage->getData(context, &bufferData));
+ const GLuint *groups = reinterpret_cast<const GLuint *>(bufferData + indirect);
+ ANGLE_TRY(mStateManager.updateStateForCompute(context, groups[0], groups[1], groups[2]));
+
+ ID3D11Buffer *buffer = nullptr;
+ ANGLE_TRY(storage->getBuffer(context, BUFFER_USAGE_INDIRECT, &buffer));
+
+ mDeviceContext->DispatchIndirect(buffer, static_cast<UINT>(indirect));
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer11::createStagingTexture(const gl::Context *context,
+ ResourceType textureType,
+ const d3d11::Format &formatSet,
+ const gl::Extents &size,
+ StagingAccess readAndWriteAccess,
+ TextureHelper11 *textureOut)
+{
+ Context11 *context11 = GetImplAs<Context11>(context);
+
+ if (textureType == ResourceType::Texture2D)
+ {
+ D3D11_TEXTURE2D_DESC stagingDesc;
+ stagingDesc.Width = size.width;
+ stagingDesc.Height = size.height;
+ stagingDesc.MipLevels = 1;
+ stagingDesc.ArraySize = 1;
+ stagingDesc.Format = formatSet.texFormat;
+ stagingDesc.SampleDesc.Count = 1;
+ stagingDesc.SampleDesc.Quality = 0;
+ stagingDesc.Usage = D3D11_USAGE_STAGING;
+ stagingDesc.BindFlags = 0;
+ stagingDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
+ stagingDesc.MiscFlags = 0;
+
+ if (readAndWriteAccess == StagingAccess::READ_WRITE)
+ {
+ stagingDesc.CPUAccessFlags |= D3D11_CPU_ACCESS_WRITE;
+ }
+
+ ANGLE_TRY(allocateTexture(context11, stagingDesc, formatSet, textureOut));
+ return angle::Result::Continue;
+ }
+ ASSERT(textureType == ResourceType::Texture3D);
+
+ D3D11_TEXTURE3D_DESC stagingDesc;
+ stagingDesc.Width = size.width;
+ stagingDesc.Height = size.height;
+ stagingDesc.Depth = 1;
+ stagingDesc.MipLevels = 1;
+ stagingDesc.Format = formatSet.texFormat;
+ stagingDesc.Usage = D3D11_USAGE_STAGING;
+ stagingDesc.BindFlags = 0;
+ stagingDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
+ stagingDesc.MiscFlags = 0;
+
+ ANGLE_TRY(allocateTexture(context11, stagingDesc, formatSet, textureOut));
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer11::allocateTexture(d3d::Context *context,
+ const D3D11_TEXTURE2D_DESC &desc,
+ const d3d11::Format &format,
+ const D3D11_SUBRESOURCE_DATA *initData,
+ TextureHelper11 *textureOut)
+{
+ d3d11::Texture2D texture;
+ ANGLE_TRY(mResourceManager11.allocate(context, this, &desc, initData, &texture));
+ textureOut->init(std::move(texture), desc, format);
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer11::allocateTexture(d3d::Context *context,
+ const D3D11_TEXTURE3D_DESC &desc,
+ const d3d11::Format &format,
+ const D3D11_SUBRESOURCE_DATA *initData,
+ TextureHelper11 *textureOut)
+{
+ d3d11::Texture3D texture;
+ ANGLE_TRY(mResourceManager11.allocate(context, this, &desc, initData, &texture));
+ textureOut->init(std::move(texture), desc, format);
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer11::getBlendState(const gl::Context *context,
+ const d3d11::BlendStateKey &key,
+ const d3d11::BlendState **outBlendState)
+{
+ return mStateCache.getBlendState(context, this, key, outBlendState);
+}
+
+angle::Result Renderer11::getRasterizerState(const gl::Context *context,
+ const gl::RasterizerState &rasterState,
+ bool scissorEnabled,
+ ID3D11RasterizerState **outRasterizerState)
+{
+ return mStateCache.getRasterizerState(context, this, rasterState, scissorEnabled,
+ outRasterizerState);
+}
+
+angle::Result Renderer11::getDepthStencilState(const gl::Context *context,
+ const gl::DepthStencilState &dsState,
+ const d3d11::DepthStencilState **outDSState)
+{
+ return mStateCache.getDepthStencilState(context, this, dsState, outDSState);
+}
+
+angle::Result Renderer11::getSamplerState(const gl::Context *context,
+ const gl::SamplerState &samplerState,
+ ID3D11SamplerState **outSamplerState)
+{
+ return mStateCache.getSamplerState(context, this, samplerState, outSamplerState);
+}
+
+UINT Renderer11::getSampleDescQuality(GLuint supportedSamples) const
+{
+ // Per the documentation on
+ // https://docs.microsoft.com/en-us/windows/win32/api/d3d11/ne-d3d11-d3d11_standard_multisample_quality_levels
+ // applications can only request the standard multisample pattern on
+ // feature levels 10_1 and above.
+ if (supportedSamples > 0 && mDevice->GetFeatureLevel() >= D3D_FEATURE_LEVEL_10_1)
+ {
+ return D3D11_STANDARD_MULTISAMPLE_PATTERN;
+ }
+ return 0;
+}
+
+angle::Result Renderer11::clearRenderTarget(const gl::Context *context,
+ RenderTargetD3D *renderTarget,
+ const gl::ColorF &clearColorValue,
+ const float clearDepthValue,
+ const unsigned int clearStencilValue)
+{
+ RenderTarget11 *rt11 = GetAs<RenderTarget11>(renderTarget);
+
+ if (rt11->getFormatSet().dsvFormat != DXGI_FORMAT_UNKNOWN)
+ {
+ ASSERT(rt11->getDepthStencilView().valid());
+
+ const auto &format = rt11->getFormatSet();
+ const UINT clearFlags = (format.format().depthBits > 0 ? D3D11_CLEAR_DEPTH : 0) |
+ (format.format().stencilBits ? D3D11_CLEAR_STENCIL : 0);
+ mDeviceContext->ClearDepthStencilView(rt11->getDepthStencilView().get(), clearFlags,
+ clearDepthValue,
+ static_cast<UINT8>(clearStencilValue));
+ return angle::Result::Continue;
+ }
+
+ ASSERT(rt11->getRenderTargetView().valid());
+ ID3D11RenderTargetView *rtv = rt11->getRenderTargetView().get();
+
+ // There are complications with some types of RTV and FL 9_3 with ClearRenderTargetView.
+ // See https://msdn.microsoft.com/en-us/library/windows/desktop/ff476388(v=vs.85).aspx
+ ASSERT(mRenderer11DeviceCaps.featureLevel > D3D_FEATURE_LEVEL_9_3 || !IsArrayRTV(rtv));
+
+ const auto &d3d11Format = rt11->getFormatSet();
+ const auto &glFormat = gl::GetSizedInternalFormatInfo(renderTarget->getInternalFormat());
+
+ gl::ColorF safeClearColor = clearColorValue;
+
+ if (d3d11Format.format().alphaBits > 0 && glFormat.alphaBits == 0)
+ {
+ safeClearColor.alpha = 1.0f;
+ }
+
+ mDeviceContext->ClearRenderTargetView(rtv, &safeClearColor.red);
+ return angle::Result::Continue;
+}
+
+bool Renderer11::canSelectViewInVertexShader() const
+{
+ return !getFeatures().selectViewInGeometryShader.enabled &&
+ getRenderer11DeviceCaps().supportsVpRtIndexWriteFromVertexShader;
+}
+
+angle::Result Renderer11::mapResource(const gl::Context *context,
+ ID3D11Resource *resource,
+ UINT subResource,
+ D3D11_MAP mapType,
+ UINT mapFlags,
+ D3D11_MAPPED_SUBRESOURCE *mappedResource)
+{
+ HRESULT hr = mDeviceContext->Map(resource, subResource, mapType, mapFlags, mappedResource);
+ ANGLE_TRY_HR(GetImplAs<Context11>(context), hr, "Failed to map D3D11 resource.");
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer11::markTypedBufferUsage(const gl::Context *context)
+{
+ const gl::State &glState = context->getState();
+ ProgramD3D *programD3D = GetImplAs<ProgramD3D>(glState.getProgram());
+ gl::RangeUI imageRange = programD3D->getUsedImageRange(gl::ShaderType::Compute, false);
+ for (unsigned int imageIndex = imageRange.low(); imageIndex < imageRange.high(); imageIndex++)
+ {
+ GLint imageUnitIndex = programD3D->getImageMapping(gl::ShaderType::Compute, imageIndex,
+ false, context->getCaps());
+ ASSERT(imageUnitIndex != -1);
+ const gl::ImageUnit &imageUnit = glState.getImageUnit(imageUnitIndex);
+ if (imageUnit.texture.get()->getType() == gl::TextureType::Buffer)
+ {
+ Buffer11 *buffer11 = GetImplAs<Buffer11>(imageUnit.texture.get()->getBuffer().get());
+ ANGLE_TRY(buffer11->markTypedBufferUsage(context));
+ }
+ }
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer11::markRawBufferUsage(const gl::Context *context)
+{
+ const gl::State &glState = context->getState();
+ const gl::Program *program = glState.getProgram();
+ for (size_t blockIndex = 0; blockIndex < program->getActiveShaderStorageBlockCount();
+ blockIndex++)
+ {
+ GLuint binding = program->getShaderStorageBlockBinding(static_cast<GLuint>(blockIndex));
+ const auto &shaderStorageBuffer = glState.getIndexedShaderStorageBuffer(binding);
+ if (shaderStorageBuffer.get() != nullptr)
+ {
+ Buffer11 *bufferStorage = GetImplAs<Buffer11>(shaderStorageBuffer.get());
+ ANGLE_TRY(bufferStorage->markRawBufferUsage(context));
+ }
+ }
+
+ for (const auto &atomicCounterBuffer : program->getState().getAtomicCounterBuffers())
+ {
+ GLuint binding = atomicCounterBuffer.binding;
+ const auto &buffer = glState.getIndexedAtomicCounterBuffer(binding);
+
+ if (buffer.get() != nullptr)
+ {
+ Buffer11 *bufferStorage = GetImplAs<Buffer11>(buffer.get());
+ ANGLE_TRY(bufferStorage->markRawBufferUsage(context));
+ }
+ }
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer11::markTransformFeedbackUsage(const gl::Context *context)
+{
+ const gl::State &glState = context->getState();
+ const gl::TransformFeedback *transformFeedback = glState.getCurrentTransformFeedback();
+ for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
+ {
+ const gl::OffsetBindingPointer<gl::Buffer> &binding =
+ transformFeedback->getIndexedBuffer(i);
+ if (binding.get() != nullptr)
+ {
+ BufferD3D *bufferD3D = GetImplAs<BufferD3D>(binding.get());
+ ANGLE_TRY(bufferD3D->markTransformFeedbackUsage(context));
+ }
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer11::getIncompleteTexture(const gl::Context *context,
+ gl::TextureType type,
+ gl::Texture **textureOut)
+{
+ return GetImplAs<Context11>(context)->getIncompleteTexture(context, type, textureOut);
+}
+
+std::string Renderer11::getVendorString() const
+{
+ return GetVendorString(mAdapterDescription.VendorId);
+}
+
+std::string Renderer11::getVersionString(bool includeFullVersion) const
+{
+ std::ostringstream versionString;
+ versionString << "D3D11";
+ if (includeFullVersion && mRenderer11DeviceCaps.driverVersion.valid())
+ {
+ versionString << "-" << GetDriverVersionString(mRenderer11DeviceCaps.driverVersion.value());
+ }
+ return versionString.str();
+}
+
+RendererD3D *CreateRenderer11(egl::Display *display)
+{
+ return new Renderer11(display);
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Renderer11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Renderer11.h
new file mode 100644
index 0000000000..6d4cb214af
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Renderer11.h
@@ -0,0 +1,632 @@
+//
+// Copyright 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.
+//
+
+// Renderer11.h: Defines a back-end specific class for the D3D11 renderer.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_RENDERER11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_RENDERER11_H_
+
+#include "common/angleutils.h"
+#include "common/mathutil.h"
+#include "libANGLE/AttributeMap.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/renderer/d3d/HLSLCompiler.h"
+#include "libANGLE/renderer/d3d/ProgramD3D.h"
+#include "libANGLE/renderer/d3d/RenderTargetD3D.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
+#include "libANGLE/renderer/d3d/d3d11/DebugAnnotator11.h"
+#include "libANGLE/renderer/d3d/d3d11/RenderStateCache.h"
+#include "libANGLE/renderer/d3d/d3d11/ResourceManager11.h"
+#include "libANGLE/renderer/d3d/d3d11/StateManager11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+
+namespace gl
+{
+class FramebufferAttachment;
+class ImageIndex;
+} // namespace gl
+
+namespace rx
+{
+class Blit11;
+class Buffer11;
+class Clear11;
+class Context11;
+class IndexDataManager;
+struct PackPixelsParams;
+class PixelTransfer11;
+class RenderTarget11;
+class StreamingIndexBufferInterface;
+class Trim11;
+class VertexDataManager;
+
+struct Renderer11DeviceCaps
+{
+ Renderer11DeviceCaps();
+
+ D3D_FEATURE_LEVEL featureLevel;
+ bool supportsDXGI1_2; // Support for DXGI 1.2
+ bool supportsClearView; // Support for ID3D11DeviceContext1::ClearView
+ bool supportsConstantBufferOffsets; // Support for Constant buffer offset
+ bool supportsVpRtIndexWriteFromVertexShader; // VP/RT can be selected in the Vertex Shader
+ // stage.
+ bool supportsMultisampledDepthStencilSRVs; // D3D feature level 10.0 no longer allows creation
+ // of textures with both the bind SRV and DSV flags
+ // when multisampled. Textures will need to be
+ // resolved before reading. crbug.com/656989
+ bool supportsTypedUAVLoadAdditionalFormats; //
+ bool supportsRasterizerOrderViews;
+ bool allowES3OnFL10_0;
+ UINT B5G6R5support; // Bitfield of D3D11_FORMAT_SUPPORT values for DXGI_FORMAT_B5G6R5_UNORM
+ UINT B5G6R5maxSamples; // Maximum number of samples supported by DXGI_FORMAT_B5G6R5_UNORM
+ UINT B4G4R4A4support; // Bitfield of D3D11_FORMAT_SUPPORT values for DXGI_FORMAT_B4G4R4A4_UNORM
+ UINT B4G4R4A4maxSamples; // Maximum number of samples supported by DXGI_FORMAT_B4G4R4A4_UNORM
+ UINT B5G5R5A1support; // Bitfield of D3D11_FORMAT_SUPPORT values for DXGI_FORMAT_B5G5R5A1_UNORM
+ UINT B5G5R5A1maxSamples; // Maximum number of samples supported by DXGI_FORMAT_B5G5R5A1_UNORM
+ Optional<LARGE_INTEGER> driverVersion; // Four-part driver version number.
+};
+
+enum
+{
+ MAX_VERTEX_UNIFORM_VECTORS_D3D11 = 1024,
+ MAX_FRAGMENT_UNIFORM_VECTORS_D3D11 = 1024
+};
+
+class Renderer11 : public RendererD3D
+{
+ public:
+ explicit Renderer11(egl::Display *display);
+ ~Renderer11() override;
+
+ egl::Error initialize() override;
+ bool resetDevice() override;
+
+ egl::ConfigSet generateConfigs() override;
+ void generateDisplayExtensions(egl::DisplayExtensions *outExtensions) const override;
+
+ ContextImpl *createContext(const gl::State &state, gl::ErrorSet *errorSet) override;
+
+ angle::Result flush(Context11 *context11);
+ angle::Result finish(Context11 *context11);
+
+ bool isValidNativeWindow(EGLNativeWindowType window) const override;
+ NativeWindowD3D *createNativeWindow(EGLNativeWindowType window,
+ const egl::Config *config,
+ const egl::AttributeMap &attribs) const override;
+
+ SwapChainD3D *createSwapChain(NativeWindowD3D *nativeWindow,
+ HANDLE shareHandle,
+ IUnknown *d3dTexture,
+ GLenum backBufferFormat,
+ GLenum depthBufferFormat,
+ EGLint orientation,
+ EGLint samples) override;
+ egl::Error getD3DTextureInfo(const egl::Config *configuration,
+ IUnknown *d3dTexture,
+ const egl::AttributeMap &attribs,
+ EGLint *width,
+ EGLint *height,
+ GLsizei *samples,
+ gl::Format *glFormat,
+ const angle::Format **angleFormat,
+ UINT *arraySlice) const override;
+ egl::Error validateShareHandle(const egl::Config *config,
+ HANDLE shareHandle,
+ const egl::AttributeMap &attribs) const override;
+
+ // lost device
+ bool testDeviceLost() override;
+ bool testDeviceResettable() override;
+
+ DeviceIdentifier getAdapterIdentifier() const override;
+
+ unsigned int getReservedVertexUniformVectors() const;
+ unsigned int getReservedFragmentUniformVectors() const;
+ gl::ShaderMap<unsigned int> getReservedShaderUniformBuffers() const;
+
+ bool getShareHandleSupport() const;
+
+ int getMajorShaderModel() const override;
+ int getMinorShaderModel() const override;
+ std::string getShaderModelSuffix() const override;
+
+ // Pixel operations
+ angle::Result copyImage2D(const gl::Context *context,
+ const gl::Framebuffer *framebuffer,
+ const gl::Rectangle &sourceRect,
+ GLenum destFormat,
+ const gl::Offset &destOffset,
+ TextureStorage *storage,
+ GLint level) override;
+ angle::Result copyImageCube(const gl::Context *context,
+ const gl::Framebuffer *framebuffer,
+ const gl::Rectangle &sourceRect,
+ GLenum destFormat,
+ const gl::Offset &destOffset,
+ TextureStorage *storage,
+ gl::TextureTarget target,
+ GLint level) override;
+ angle::Result copyImage3D(const gl::Context *context,
+ const gl::Framebuffer *framebuffer,
+ const gl::Rectangle &sourceRect,
+ GLenum destFormat,
+ const gl::Offset &destOffset,
+ TextureStorage *storage,
+ GLint level) override;
+ angle::Result copyImage2DArray(const gl::Context *context,
+ const gl::Framebuffer *framebuffer,
+ const gl::Rectangle &sourceRect,
+ GLenum destFormat,
+ const gl::Offset &destOffset,
+ TextureStorage *storage,
+ GLint level) override;
+
+ angle::Result copyTexture(const gl::Context *context,
+ const gl::Texture *source,
+ GLint sourceLevel,
+ gl::TextureTarget srcTarget,
+ const gl::Box &sourceBox,
+ GLenum destFormat,
+ GLenum destType,
+ const gl::Offset &destOffset,
+ TextureStorage *storage,
+ gl::TextureTarget destTarget,
+ GLint destLevel,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha) override;
+ angle::Result copyCompressedTexture(const gl::Context *context,
+ const gl::Texture *source,
+ GLint sourceLevel,
+ TextureStorage *storage,
+ GLint destLevel) override;
+
+ // RenderTarget creation
+ angle::Result createRenderTarget(const gl::Context *context,
+ int width,
+ int height,
+ GLenum format,
+ GLsizei samples,
+ RenderTargetD3D **outRT) override;
+ angle::Result createRenderTargetCopy(const gl::Context *context,
+ RenderTargetD3D *source,
+ RenderTargetD3D **outRT) override;
+
+ // Shader operations
+ angle::Result loadExecutable(d3d::Context *context,
+ const uint8_t *function,
+ size_t length,
+ gl::ShaderType type,
+ const std::vector<D3DVarying> &streamOutVaryings,
+ bool separatedOutputBuffers,
+ ShaderExecutableD3D **outExecutable) override;
+ angle::Result compileToExecutable(d3d::Context *context,
+ gl::InfoLog &infoLog,
+ const std::string &shaderHLSL,
+ gl::ShaderType type,
+ const std::vector<D3DVarying> &streamOutVaryings,
+ bool separatedOutputBuffers,
+ const CompilerWorkaroundsD3D &workarounds,
+ ShaderExecutableD3D **outExectuable) override;
+ angle::Result ensureHLSLCompilerInitialized(d3d::Context *context) override;
+
+ UniformStorageD3D *createUniformStorage(size_t storageSize) override;
+
+ // Image operations
+ ImageD3D *createImage() override;
+ ExternalImageSiblingImpl *createExternalImageSibling(const gl::Context *context,
+ EGLenum target,
+ EGLClientBuffer buffer,
+ const egl::AttributeMap &attribs) override;
+ angle::Result generateMipmap(const gl::Context *context,
+ ImageD3D *dest,
+ ImageD3D *source) override;
+ angle::Result generateMipmapUsingD3D(const gl::Context *context,
+ TextureStorage *storage,
+ const gl::TextureState &textureState) override;
+ angle::Result copyImage(const gl::Context *context,
+ ImageD3D *dest,
+ ImageD3D *source,
+ const gl::Box &sourceBox,
+ const gl::Offset &destOffset,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha) override;
+
+ TextureStorage *createTextureStorage2D(SwapChainD3D *swapChain,
+ const std::string &label) override;
+ TextureStorage *createTextureStorageEGLImage(EGLImageD3D *eglImage,
+ RenderTargetD3D *renderTargetD3D,
+ const std::string &label) override;
+ TextureStorage *createTextureStorageExternal(egl::Stream *stream,
+ const egl::Stream::GLTextureDescription &desc,
+ const std::string &label) override;
+ TextureStorage *createTextureStorage2D(GLenum internalformat,
+ BindFlags bindFlags,
+ GLsizei width,
+ GLsizei height,
+ int levels,
+ const std::string &label,
+ bool hintLevelZeroOnly) override;
+ TextureStorage *createTextureStorageCube(GLenum internalformat,
+ BindFlags bindFlags,
+ int size,
+ int levels,
+ bool hintLevelZeroOnly,
+ const std::string &label) override;
+ TextureStorage *createTextureStorage3D(GLenum internalformat,
+ BindFlags bindFlags,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ int levels,
+ const std::string &label) override;
+ TextureStorage *createTextureStorage2DArray(GLenum internalformat,
+ BindFlags bindFlags,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ int levels,
+ const std::string &label) override;
+ TextureStorage *createTextureStorage2DMultisample(GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ int levels,
+ int samples,
+ bool fixedSampleLocations,
+ const std::string &label) override;
+
+ TextureStorage *createTextureStorageBuffer(const gl::OffsetBindingPointer<gl::Buffer> &buffer,
+ GLenum internalFormat,
+ const std::string &label) override;
+ TextureStorage *createTextureStorage2DMultisampleArray(GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ int levels,
+ int samples,
+ bool fixedSampleLocations,
+ const std::string &label) override;
+
+ VertexBuffer *createVertexBuffer() override;
+ IndexBuffer *createIndexBuffer() override;
+
+ // Stream Creation
+ StreamProducerImpl *createStreamProducerD3DTexture(egl::Stream::ConsumerType consumerType,
+ const egl::AttributeMap &attribs) override;
+
+ // D3D11-renderer specific methods
+ ID3D11Device *getDevice() { return mDevice; }
+ ID3D11Device1 *getDevice1() { return mDevice1; }
+ void *getD3DDevice() override;
+ ID3D11DeviceContext *getDeviceContext() { return mDeviceContext; }
+ ID3D11DeviceContext1 *getDeviceContext1IfSupported() { return mDeviceContext1; }
+ IDXGIFactory *getDxgiFactory() { return mDxgiFactory; }
+
+ angle::Result getBlendState(const gl::Context *context,
+ const d3d11::BlendStateKey &key,
+ const d3d11::BlendState **outBlendState);
+ angle::Result getRasterizerState(const gl::Context *context,
+ const gl::RasterizerState &rasterState,
+ bool scissorEnabled,
+ ID3D11RasterizerState **outRasterizerState);
+ angle::Result getDepthStencilState(const gl::Context *context,
+ const gl::DepthStencilState &dsState,
+ const d3d11::DepthStencilState **outDSState);
+ angle::Result getSamplerState(const gl::Context *context,
+ const gl::SamplerState &samplerState,
+ ID3D11SamplerState **outSamplerState);
+ UINT getSampleDescQuality(GLuint supportedSamples) const;
+
+ Blit11 *getBlitter() { return mBlit; }
+ Clear11 *getClearer() { return mClear; }
+ DebugAnnotatorContext11 *getDebugAnnotatorContext();
+
+ // Buffer-to-texture and Texture-to-buffer copies
+ bool supportsFastCopyBufferToTexture(GLenum internalFormat) const override;
+ angle::Result fastCopyBufferToTexture(const gl::Context *context,
+ const gl::PixelUnpackState &unpack,
+ gl::Buffer *unpackBuffer,
+ unsigned int offset,
+ RenderTargetD3D *destRenderTarget,
+ GLenum destinationFormat,
+ GLenum sourcePixelsType,
+ const gl::Box &destArea) override;
+
+ angle::Result packPixels(const gl::Context *context,
+ const TextureHelper11 &textureHelper,
+ const PackPixelsParams &params,
+ uint8_t *pixelsOut);
+
+ bool getLUID(LUID *adapterLuid) const override;
+ VertexConversionType getVertexConversionType(angle::FormatID vertexFormatID) const override;
+ GLenum getVertexComponentType(angle::FormatID vertexFormatID) const override;
+
+ // Warning: you should ensure binding really matches attrib.bindingIndex before using this
+ // function.
+ angle::Result getVertexSpaceRequired(const gl::Context *context,
+ const gl::VertexAttribute &attrib,
+ const gl::VertexBinding &binding,
+ size_t count,
+ GLsizei instances,
+ GLuint baseInstance,
+ unsigned int *bytesRequiredOut) const override;
+
+ angle::Result readFromAttachment(const gl::Context *context,
+ const gl::FramebufferAttachment &srcAttachment,
+ const gl::Rectangle &sourceArea,
+ GLenum format,
+ GLenum type,
+ GLuint outputPitch,
+ const gl::PixelPackState &pack,
+ uint8_t *pixels);
+
+ angle::Result blitRenderbufferRect(const gl::Context *context,
+ const gl::Rectangle &readRect,
+ const gl::Rectangle &drawRect,
+ UINT readLayer,
+ UINT drawLayer,
+ RenderTargetD3D *readRenderTarget,
+ RenderTargetD3D *drawRenderTarget,
+ GLenum filter,
+ const gl::Rectangle *scissor,
+ bool colorBlit,
+ bool depthBlit,
+ bool stencilBlit);
+
+ bool isES3Capable() const;
+ const Renderer11DeviceCaps &getRenderer11DeviceCaps() const { return mRenderer11DeviceCaps; }
+
+ RendererClass getRendererClass() const override;
+ StateManager11 *getStateManager() { return &mStateManager; }
+
+ void onSwap();
+ void onBufferCreate(const Buffer11 *created);
+ void onBufferDelete(const Buffer11 *deleted);
+
+ DeviceImpl *createEGLDevice() override;
+
+ angle::Result drawArrays(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLint firstVertex,
+ GLsizei vertexCount,
+ GLsizei instanceCount,
+ GLuint baseInstance,
+ bool isInstancedDraw);
+ angle::Result drawElements(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLint startVertex,
+ GLsizei indexCount,
+ gl::DrawElementsType indexType,
+ const void *indices,
+ GLsizei instanceCount,
+ GLint baseVertex,
+ GLuint baseInstance,
+ bool isInstancedDraw);
+ angle::Result drawArraysIndirect(const gl::Context *context, const void *indirect);
+ angle::Result drawElementsIndirect(const gl::Context *context, const void *indirect);
+
+ // Necessary hack for default framebuffers in D3D.
+ FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) override;
+
+ angle::Result getScratchMemoryBuffer(Context11 *context11,
+ size_t requestedSize,
+ angle::MemoryBuffer **bufferOut);
+
+ gl::Version getMaxSupportedESVersion() const override;
+ gl::Version getMaxConformantESVersion() const override;
+
+ angle::Result dispatchCompute(const gl::Context *context,
+ GLuint numGroupsX,
+ GLuint numGroupsY,
+ GLuint numGroupsZ);
+ angle::Result dispatchComputeIndirect(const gl::Context *context, GLintptr indirect);
+
+ angle::Result createStagingTexture(const gl::Context *context,
+ ResourceType textureType,
+ const d3d11::Format &formatSet,
+ const gl::Extents &size,
+ StagingAccess readAndWriteAccess,
+ TextureHelper11 *textureOut);
+
+ template <typename DescT, typename ResourceT>
+ angle::Result allocateResource(d3d::Context *context, const DescT &desc, ResourceT *resourceOut)
+ {
+ return mResourceManager11.allocate(context, this, &desc, nullptr, resourceOut);
+ }
+
+ template <typename DescT, typename InitDataT, typename ResourceT>
+ angle::Result allocateResource(d3d::Context *context,
+ const DescT &desc,
+ InitDataT *initData,
+ ResourceT *resourceOut)
+ {
+ return mResourceManager11.allocate(context, this, &desc, initData, resourceOut);
+ }
+
+ template <typename InitDataT, typename ResourceT>
+ angle::Result allocateResourceNoDesc(d3d::Context *context,
+ InitDataT *initData,
+ ResourceT *resourceOut)
+ {
+ return mResourceManager11.allocate(context, this, nullptr, initData, resourceOut);
+ }
+
+ template <typename DescT>
+ angle::Result allocateTexture(d3d::Context *context,
+ const DescT &desc,
+ const d3d11::Format &format,
+ TextureHelper11 *textureOut)
+ {
+ return allocateTexture(context, desc, format, nullptr, textureOut);
+ }
+
+ angle::Result allocateTexture(d3d::Context *context,
+ const D3D11_TEXTURE2D_DESC &desc,
+ const d3d11::Format &format,
+ const D3D11_SUBRESOURCE_DATA *initData,
+ TextureHelper11 *textureOut);
+
+ angle::Result allocateTexture(d3d::Context *context,
+ const D3D11_TEXTURE3D_DESC &desc,
+ const d3d11::Format &format,
+ const D3D11_SUBRESOURCE_DATA *initData,
+ TextureHelper11 *textureOut);
+
+ angle::Result clearRenderTarget(const gl::Context *context,
+ RenderTargetD3D *renderTarget,
+ const gl::ColorF &clearColorValue,
+ const float clearDepthValue,
+ const unsigned int clearStencilValue) override;
+
+ bool canSelectViewInVertexShader() const override;
+
+ angle::Result mapResource(const gl::Context *context,
+ ID3D11Resource *resource,
+ UINT subResource,
+ D3D11_MAP mapType,
+ UINT mapFlags,
+ D3D11_MAPPED_SUBRESOURCE *mappedResource);
+
+ angle::Result getIncompleteTexture(const gl::Context *context,
+ gl::TextureType type,
+ gl::Texture **textureOut) override;
+
+ void setGlobalDebugAnnotator() override;
+
+ std::string getRendererDescription() const override;
+ std::string getVendorString() const override;
+ std::string getVersionString(bool includeFullVersion) const override;
+
+ private:
+ void generateCaps(gl::Caps *outCaps,
+ gl::TextureCapsMap *outTextureCaps,
+ gl::Extensions *outExtensions,
+ gl::Limitations *outLimitations) const override;
+
+ void initializeFeatures(angle::FeaturesD3D *features) const override;
+
+ void initializeFrontendFeatures(angle::FrontendFeatures *features) const override;
+
+ angle::Result drawLineLoop(const gl::Context *context,
+ GLuint count,
+ gl::DrawElementsType type,
+ const void *indices,
+ int baseVertex,
+ int instances);
+ angle::Result drawTriangleFan(const gl::Context *context,
+ GLuint count,
+ gl::DrawElementsType type,
+ const void *indices,
+ int baseVertex,
+ int instances);
+
+ angle::Result resolveMultisampledTexture(const gl::Context *context,
+ RenderTarget11 *renderTarget,
+ bool depth,
+ bool stencil,
+ TextureHelper11 *textureOut);
+
+ void populateRenderer11DeviceCaps();
+
+ void updateHistograms();
+
+ angle::Result copyImageInternal(const gl::Context *context,
+ const gl::Framebuffer *framebuffer,
+ const gl::Rectangle &sourceRect,
+ GLenum destFormat,
+ const gl::Offset &destOffset,
+ RenderTargetD3D *destRenderTarget);
+
+ gl::SupportedSampleSet generateSampleSetForEGLConfig(
+ const gl::TextureCaps &colorBufferFormatCaps,
+ const gl::TextureCaps &depthStencilBufferFormatCaps) const;
+
+ HRESULT callD3D11CreateDevice(PFN_D3D11_CREATE_DEVICE createDevice, bool debug);
+ HRESULT callD3D11On12CreateDevice(PFN_D3D12_CREATE_DEVICE createDevice12,
+ PFN_D3D11ON12_CREATE_DEVICE createDevice11on12,
+ bool debug);
+ egl::Error initializeD3DDevice();
+ egl::Error initializeDevice();
+ void releaseDeviceResources();
+ void release();
+
+ d3d11::ANGLED3D11DeviceType getDeviceType() const;
+
+ // Make sure that the raw buffer is the latest buffer.
+ angle::Result markRawBufferUsage(const gl::Context *context);
+ angle::Result markTypedBufferUsage(const gl::Context *context);
+ angle::Result markTransformFeedbackUsage(const gl::Context *context);
+ angle::Result drawWithGeometryShaderAndTransformFeedback(Context11 *context11,
+ gl::PrimitiveMode mode,
+ UINT instanceCount,
+ UINT vertexCount);
+
+ HMODULE mD3d11Module;
+ HMODULE mD3d12Module;
+ HMODULE mDxgiModule;
+ HMODULE mDCompModule;
+ std::vector<D3D_FEATURE_LEVEL> mAvailableFeatureLevels;
+ D3D_DRIVER_TYPE mRequestedDriverType;
+ bool mCreateDebugDevice;
+ bool mCreatedWithDeviceEXT;
+
+ HLSLCompiler mCompiler;
+
+ RenderStateCache mStateCache;
+
+ StateManager11 mStateManager;
+
+ StreamingIndexBufferInterface *mLineLoopIB;
+ StreamingIndexBufferInterface *mTriangleFanIB;
+
+ // Texture copy resources
+ Blit11 *mBlit;
+ PixelTransfer11 *mPixelTransfer;
+
+ // Masked clear resources
+ Clear11 *mClear;
+
+ // Perform trim for D3D resources
+ Trim11 *mTrim;
+
+ // Sync query
+ d3d11::Query mSyncQuery;
+
+ // Created objects state tracking
+ std::set<const Buffer11 *> mAliveBuffers;
+
+ double mLastHistogramUpdateTime;
+
+ angle::ComPtr<ID3D12Device> mDevice12;
+ angle::ComPtr<ID3D12CommandQueue> mCommandQueue;
+
+ ID3D11Device *mDevice;
+ ID3D11Device1 *mDevice1;
+ Renderer11DeviceCaps mRenderer11DeviceCaps;
+ ID3D11DeviceContext *mDeviceContext;
+ ID3D11DeviceContext1 *mDeviceContext1;
+ ID3D11DeviceContext3 *mDeviceContext3;
+ IDXGIAdapter *mDxgiAdapter;
+ DXGI_ADAPTER_DESC mAdapterDescription;
+ char mDescription[128];
+ IDXGIFactory *mDxgiFactory;
+ ID3D11Debug *mDebug;
+
+ std::vector<GLuint> mScratchIndexDataBuffer;
+
+ angle::ScratchBuffer mScratchMemoryBuffer;
+
+ DebugAnnotatorContext11 mAnnotatorContext;
+
+ mutable Optional<bool> mSupportsShareHandles;
+ ResourceManager11 mResourceManager11;
+
+ TextureHelper11 mCachedResolveTexture;
+};
+
+} // namespace rx
+#endif // LIBANGLE_RENDERER_D3D_D3D11_RENDERER11_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ResourceManager11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ResourceManager11.cpp
new file mode 100644
index 0000000000..ebf2db497f
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ResourceManager11.cpp
@@ -0,0 +1,560 @@
+//
+// Copyright 2017 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.
+//
+// ResourceManager11:
+// Centralized point of allocation for all D3D11 Resources.
+
+#include "libANGLE/renderer/d3d/d3d11/ResourceManager11.h"
+
+#include "common/debug.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
+
+namespace rx
+{
+
+namespace
+{
+
+constexpr uint8_t kDebugInitTextureDataValue = 0x48;
+constexpr FLOAT kDebugColorInitClearValue[4] = {0.3f, 0.5f, 0.7f, 0.5f};
+constexpr FLOAT kDebugDepthInitValue = 0.2f;
+constexpr UINT8 kDebugStencilInitValue = 3;
+
+// A hard limit on buffer size. This works around a problem in the NVIDIA drivers where buffer sizes
+// close to MAX_UINT would give undefined results. The limit of MAX_UINT/2 should be generous enough
+// for almost any demanding application.
+constexpr UINT kMaximumBufferSizeHardLimit = std::numeric_limits<UINT>::max() >> 1;
+
+uint64_t ComputeMippedMemoryUsage(unsigned int width,
+ unsigned int height,
+ unsigned int depth,
+ uint64_t pixelSize,
+ unsigned int mipLevels)
+{
+ uint64_t sizeSum = 0;
+
+ for (unsigned int level = 0; level < mipLevels; ++level)
+ {
+ unsigned int mipWidth = std::max(width >> level, 1u);
+ unsigned int mipHeight = std::max(height >> level, 1u);
+ unsigned int mipDepth = std::max(depth >> level, 1u);
+ sizeSum += static_cast<uint64_t>(mipWidth * mipHeight * mipDepth) * pixelSize;
+ }
+
+ return sizeSum;
+}
+
+uint64_t ComputeMemoryUsage(const D3D11_TEXTURE2D_DESC *desc)
+{
+ ASSERT(desc);
+ uint64_t pixelBytes =
+ static_cast<uint64_t>(d3d11::GetDXGIFormatSizeInfo(desc->Format).pixelBytes);
+ return ComputeMippedMemoryUsage(desc->Width, desc->Height, 1, pixelBytes, desc->MipLevels);
+}
+
+uint64_t ComputeMemoryUsage(const D3D11_TEXTURE3D_DESC *desc)
+{
+ ASSERT(desc);
+ uint64_t pixelBytes =
+ static_cast<uint64_t>(d3d11::GetDXGIFormatSizeInfo(desc->Format).pixelBytes);
+ return ComputeMippedMemoryUsage(desc->Width, desc->Height, desc->Depth, pixelBytes,
+ desc->MipLevels);
+}
+
+uint64_t ComputeMemoryUsage(const D3D11_BUFFER_DESC *desc)
+{
+ ASSERT(desc);
+ return static_cast<uint64_t>(desc->ByteWidth);
+}
+
+template <typename T>
+uint64_t ComputeMemoryUsage(const T *desc)
+{
+ return 0;
+}
+
+template <ResourceType ResourceT>
+uint64_t ComputeGenericMemoryUsage(ID3D11DeviceChild *genericResource)
+{
+ auto *typedResource = static_cast<GetD3D11Type<ResourceT> *>(genericResource);
+ GetDescType<ResourceT> desc;
+ typedResource->GetDesc(&desc);
+ return ComputeMemoryUsage(&desc);
+}
+
+uint64_t ComputeGenericMemoryUsage(ResourceType resourceType, ID3D11DeviceChild *resource)
+{
+ switch (resourceType)
+ {
+ case ResourceType::Texture2D:
+ return ComputeGenericMemoryUsage<ResourceType::Texture2D>(resource);
+ case ResourceType::Texture3D:
+ return ComputeGenericMemoryUsage<ResourceType::Texture3D>(resource);
+ case ResourceType::Buffer:
+ return ComputeGenericMemoryUsage<ResourceType::Buffer>(resource);
+
+ default:
+ return 0;
+ }
+}
+
+HRESULT CreateResource(ID3D11Device *device,
+ const D3D11_BLEND_DESC *desc,
+ void * /*initData*/,
+ ID3D11BlendState **blendState)
+{
+ return device->CreateBlendState(desc, blendState);
+}
+
+HRESULT CreateResource(ID3D11Device *device,
+ const D3D11_BUFFER_DESC *desc,
+ const D3D11_SUBRESOURCE_DATA *initData,
+ ID3D11Buffer **buffer)
+{
+ // Force buffers to be limited to a fixed max size.
+ if (desc->ByteWidth > kMaximumBufferSizeHardLimit)
+ {
+ return E_OUTOFMEMORY;
+ }
+
+ return device->CreateBuffer(desc, initData, buffer);
+}
+
+HRESULT CreateResource(ID3D11Device *device,
+ const ShaderData *desc,
+ void * /*initData*/,
+ ID3D11ComputeShader **resourceOut)
+{
+ return device->CreateComputeShader(desc->get(), desc->size(), nullptr, resourceOut);
+}
+
+HRESULT CreateResource(ID3D11Device *device,
+ const D3D11_DEPTH_STENCIL_DESC *desc,
+ void * /*initData*/,
+ ID3D11DepthStencilState **resourceOut)
+{
+ return device->CreateDepthStencilState(desc, resourceOut);
+}
+
+HRESULT CreateResource(ID3D11Device *device,
+ const D3D11_DEPTH_STENCIL_VIEW_DESC *desc,
+ ID3D11Resource *resource,
+ ID3D11DepthStencilView **resourceOut)
+{
+ return device->CreateDepthStencilView(resource, desc, resourceOut);
+}
+
+HRESULT CreateResource(ID3D11Device *device,
+ const ShaderData *desc,
+ const std::vector<D3D11_SO_DECLARATION_ENTRY> *initData,
+ ID3D11GeometryShader **resourceOut)
+{
+ if (initData)
+ {
+ return device->CreateGeometryShaderWithStreamOutput(
+ desc->get(), desc->size(), initData->data(), static_cast<UINT>(initData->size()),
+ nullptr, 0, 0, nullptr, resourceOut);
+ }
+ else
+ {
+ return device->CreateGeometryShader(desc->get(), desc->size(), nullptr, resourceOut);
+ }
+}
+
+HRESULT CreateResource(ID3D11Device *device,
+ const InputElementArray *desc,
+ const ShaderData *initData,
+ ID3D11InputLayout **resourceOut)
+{
+ return device->CreateInputLayout(desc->get(), static_cast<UINT>(desc->size()), initData->get(),
+ initData->size(), resourceOut);
+}
+
+HRESULT CreateResource(ID3D11Device *device,
+ const ShaderData *desc,
+ void * /*initData*/,
+ ID3D11PixelShader **resourceOut)
+{
+ return device->CreatePixelShader(desc->get(), desc->size(), nullptr, resourceOut);
+}
+
+HRESULT CreateResource(ID3D11Device *device,
+ const D3D11_QUERY_DESC *desc,
+ void * /*initData*/,
+ ID3D11Query **resourceOut)
+{
+ return device->CreateQuery(desc, resourceOut);
+}
+
+HRESULT CreateResource(ID3D11Device *device,
+ const D3D11_RASTERIZER_DESC *desc,
+ void * /*initData*/,
+ ID3D11RasterizerState **rasterizerState)
+{
+ return device->CreateRasterizerState(desc, rasterizerState);
+}
+
+HRESULT CreateResource(ID3D11Device *device,
+ const D3D11_RENDER_TARGET_VIEW_DESC *desc,
+ ID3D11Resource *resource,
+ ID3D11RenderTargetView **renderTargetView)
+{
+ return device->CreateRenderTargetView(resource, desc, renderTargetView);
+}
+
+HRESULT CreateResource(ID3D11Device *device,
+ const D3D11_SAMPLER_DESC *desc,
+ void * /*initData*/,
+ ID3D11SamplerState **resourceOut)
+{
+ return device->CreateSamplerState(desc, resourceOut);
+}
+
+HRESULT CreateResource(ID3D11Device *device,
+ const D3D11_SHADER_RESOURCE_VIEW_DESC *desc,
+ ID3D11Resource *resource,
+ ID3D11ShaderResourceView **resourceOut)
+{
+ return device->CreateShaderResourceView(resource, desc, resourceOut);
+}
+
+HRESULT CreateResource(ID3D11Device *device,
+ const D3D11_UNORDERED_ACCESS_VIEW_DESC *desc,
+ ID3D11Resource *resource,
+ ID3D11UnorderedAccessView **resourceOut)
+{
+ return device->CreateUnorderedAccessView(resource, desc, resourceOut);
+}
+
+HRESULT CreateResource(ID3D11Device *device,
+ const D3D11_TEXTURE2D_DESC *desc,
+ const D3D11_SUBRESOURCE_DATA *initData,
+ ID3D11Texture2D **texture)
+{
+ return device->CreateTexture2D(desc, initData, texture);
+}
+
+HRESULT CreateResource(ID3D11Device *device,
+ const D3D11_TEXTURE3D_DESC *desc,
+ const D3D11_SUBRESOURCE_DATA *initData,
+ ID3D11Texture3D **texture)
+{
+ return device->CreateTexture3D(desc, initData, texture);
+}
+
+HRESULT CreateResource(ID3D11Device *device,
+ const ShaderData *desc,
+ void * /*initData*/,
+ ID3D11VertexShader **resourceOut)
+{
+ return device->CreateVertexShader(desc->get(), desc->size(), nullptr, resourceOut);
+}
+
+DXGI_FORMAT GetTypedDepthStencilFormat(DXGI_FORMAT dxgiFormat)
+{
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_R16_TYPELESS:
+ return DXGI_FORMAT_D16_UNORM;
+ case DXGI_FORMAT_R24G8_TYPELESS:
+ return DXGI_FORMAT_D24_UNORM_S8_UINT;
+ case DXGI_FORMAT_R32_TYPELESS:
+ return DXGI_FORMAT_D32_FLOAT;
+ case DXGI_FORMAT_R32G8X24_TYPELESS:
+ return DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
+ default:
+ return dxgiFormat;
+ }
+}
+
+template <typename DescT, typename ResourceT>
+angle::Result ClearResource(d3d::Context *context,
+ Renderer11 *renderer,
+ const DescT *desc,
+ ResourceT *texture)
+{
+ // No-op.
+ return angle::Result::Continue;
+}
+
+template <>
+angle::Result ClearResource(d3d::Context *context,
+ Renderer11 *renderer,
+ const D3D11_TEXTURE2D_DESC *desc,
+ ID3D11Texture2D *texture)
+{
+ ID3D11DeviceContext *deviceContext = renderer->getDeviceContext();
+
+ if ((desc->BindFlags & D3D11_BIND_DEPTH_STENCIL) != 0)
+ {
+ D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
+ dsvDesc.Flags = 0;
+ dsvDesc.Format = GetTypedDepthStencilFormat(desc->Format);
+
+ const auto &format = d3d11_angle::GetFormat(dsvDesc.Format);
+ UINT clearFlags = (format.depthBits > 0 ? D3D11_CLEAR_DEPTH : 0) |
+ (format.stencilBits > 0 ? D3D11_CLEAR_STENCIL : 0);
+
+ // Must process each mip level individually.
+ for (UINT mipLevel = 0; mipLevel < desc->MipLevels; ++mipLevel)
+ {
+ if (desc->SampleDesc.Count == 0)
+ {
+ dsvDesc.Texture2D.MipSlice = mipLevel;
+ dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
+ }
+ else
+ {
+ dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS;
+ }
+
+ d3d11::DepthStencilView dsv;
+ ANGLE_TRY(renderer->allocateResource(context, dsvDesc, texture, &dsv));
+
+ deviceContext->ClearDepthStencilView(dsv.get(), clearFlags, kDebugDepthInitValue,
+ kDebugStencilInitValue);
+ }
+ }
+ else
+ {
+ ASSERT((desc->BindFlags & D3D11_BIND_RENDER_TARGET) != 0);
+ d3d11::RenderTargetView rtv;
+ ANGLE_TRY(renderer->allocateResourceNoDesc(context, texture, &rtv));
+
+ deviceContext->ClearRenderTargetView(rtv.get(), kDebugColorInitClearValue);
+ }
+
+ return angle::Result::Continue;
+}
+
+template <>
+angle::Result ClearResource(d3d::Context *context,
+ Renderer11 *renderer,
+ const D3D11_TEXTURE3D_DESC *desc,
+ ID3D11Texture3D *texture)
+{
+ ID3D11DeviceContext *deviceContext = renderer->getDeviceContext();
+
+ ASSERT((desc->BindFlags & D3D11_BIND_DEPTH_STENCIL) == 0);
+ ASSERT((desc->BindFlags & D3D11_BIND_RENDER_TARGET) != 0);
+
+ d3d11::RenderTargetView rtv;
+ ANGLE_TRY(renderer->allocateResourceNoDesc(context, texture, &rtv));
+
+ deviceContext->ClearRenderTargetView(rtv.get(), kDebugColorInitClearValue);
+ return angle::Result::Continue;
+}
+
+#define ANGLE_RESOURCE_STRINGIFY_OP(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) \
+ "Error allocating " #RESTYPE,
+
+constexpr std::array<const char *, NumResourceTypes> kResourceTypeErrors = {
+ {ANGLE_RESOURCE_TYPE_OP(Stringify, ANGLE_RESOURCE_STRINGIFY_OP)}};
+static_assert(kResourceTypeErrors[NumResourceTypes - 1] != nullptr,
+ "All members must be initialized.");
+
+} // anonymous namespace
+
+// ResourceManager11 Implementation.
+ResourceManager11::ResourceManager11() : mInitializeAllocations(false)
+{
+ for (auto &count : mAllocatedResourceCounts)
+ {
+ count = 0;
+ }
+ for (auto &memorySize : mAllocatedResourceDeviceMemory)
+ {
+ memorySize = 0;
+ }
+}
+
+ResourceManager11::~ResourceManager11()
+{
+ for (size_t count : mAllocatedResourceCounts)
+ {
+ ASSERT(count == 0);
+ }
+
+ for (uint64_t memorySize : mAllocatedResourceDeviceMemory)
+ {
+ ASSERT(memorySize == 0);
+ }
+}
+
+template <typename T>
+angle::Result ResourceManager11::allocate(d3d::Context *context,
+ Renderer11 *renderer,
+ const GetDescFromD3D11<T> *desc,
+ GetInitDataFromD3D11<T> *initData,
+ Resource11<T> *resourceOut)
+{
+ ID3D11Device *device = renderer->getDevice();
+ T *resource = nullptr;
+
+ GetInitDataFromD3D11<T> *shadowInitData = initData;
+ if (!shadowInitData && mInitializeAllocations)
+ {
+ shadowInitData = createInitDataIfNeeded<T>(desc);
+ }
+
+ HRESULT hr = CreateResource(device, desc, shadowInitData, &resource);
+ ANGLE_TRY_HR(context, hr, kResourceTypeErrors[ResourceTypeIndex<T>()]);
+
+ if (!shadowInitData && mInitializeAllocations)
+ {
+ ANGLE_TRY(ClearResource(context, renderer, desc, resource));
+ }
+
+ ASSERT(resource);
+ incrResource(GetResourceTypeFromD3D11<T>(), ComputeMemoryUsage(desc));
+ *resourceOut = std::move(Resource11<T>(resource, this));
+ return angle::Result::Continue;
+}
+
+void ResourceManager11::incrResource(ResourceType resourceType, uint64_t memorySize)
+{
+ size_t typeIndex = ResourceTypeIndex(resourceType);
+
+ mAllocatedResourceCounts[typeIndex]++;
+ mAllocatedResourceDeviceMemory[typeIndex] += memorySize;
+
+ // This checks for integer overflow.
+ ASSERT(mAllocatedResourceCounts[typeIndex] > 0);
+ ASSERT(mAllocatedResourceDeviceMemory[typeIndex] >= memorySize);
+}
+
+void ResourceManager11::decrResource(ResourceType resourceType, uint64_t memorySize)
+{
+ size_t typeIndex = ResourceTypeIndex(resourceType);
+
+ ASSERT(mAllocatedResourceCounts[typeIndex] > 0);
+ mAllocatedResourceCounts[typeIndex]--;
+ ASSERT(mAllocatedResourceDeviceMemory[typeIndex] >= memorySize);
+ mAllocatedResourceDeviceMemory[typeIndex] -= memorySize;
+}
+
+void ResourceManager11::onReleaseGeneric(ResourceType resourceType, ID3D11DeviceChild *resource)
+{
+ ASSERT(resource);
+ decrResource(resourceType, ComputeGenericMemoryUsage(resourceType, resource));
+}
+
+template <>
+const D3D11_SUBRESOURCE_DATA *ResourceManager11::createInitDataIfNeeded<ID3D11Texture2D>(
+ const D3D11_TEXTURE2D_DESC *desc)
+{
+ ASSERT(desc);
+
+ if ((desc->BindFlags & (D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_RENDER_TARGET)) != 0)
+ {
+ // This will be done using ClearView methods.
+ return nullptr;
+ }
+
+ size_t requiredSize = static_cast<size_t>(ComputeMemoryUsage(desc));
+ if (mZeroMemory.size() < requiredSize)
+ {
+ if (!mZeroMemory.resize(requiredSize))
+ {
+ ERR() << "Failed to allocate D3D texture initialization data.";
+ return nullptr;
+ }
+ mZeroMemory.fill(kDebugInitTextureDataValue);
+ }
+
+ const auto &formatSizeInfo = d3d11::GetDXGIFormatSizeInfo(desc->Format);
+
+ UINT subresourceCount = desc->MipLevels * desc->ArraySize;
+ if (mShadowInitData.size() < subresourceCount)
+ {
+ mShadowInitData.resize(subresourceCount);
+ }
+
+ for (UINT mipLevel = 0; mipLevel < desc->MipLevels; ++mipLevel)
+ {
+ for (UINT arrayIndex = 0; arrayIndex < desc->ArraySize; ++arrayIndex)
+ {
+ UINT subresourceIndex = D3D11CalcSubresource(mipLevel, arrayIndex, desc->MipLevels);
+ D3D11_SUBRESOURCE_DATA *data = &mShadowInitData[subresourceIndex];
+
+ UINT levelWidth = std::max(desc->Width >> mipLevel, 1u);
+ UINT levelHeight = std::max(desc->Height >> mipLevel, 1u);
+
+ data->SysMemPitch = levelWidth * formatSizeInfo.pixelBytes;
+ data->SysMemSlicePitch = data->SysMemPitch * levelHeight;
+ data->pSysMem = mZeroMemory.data();
+ }
+ }
+
+ return mShadowInitData.data();
+}
+
+template <>
+const D3D11_SUBRESOURCE_DATA *ResourceManager11::createInitDataIfNeeded<ID3D11Texture3D>(
+ const D3D11_TEXTURE3D_DESC *desc)
+{
+ ASSERT(desc);
+
+ if ((desc->BindFlags & D3D11_BIND_RENDER_TARGET) != 0)
+ {
+ // This will be done using ClearView methods.
+ return nullptr;
+ }
+
+ size_t requiredSize = static_cast<size_t>(ComputeMemoryUsage(desc));
+ if (mZeroMemory.size() < requiredSize)
+ {
+ if (!mZeroMemory.resize(requiredSize))
+ {
+ ERR() << "Failed to allocate D3D texture initialization data.";
+ return nullptr;
+ }
+ mZeroMemory.fill(kDebugInitTextureDataValue);
+ }
+
+ const auto &formatSizeInfo = d3d11::GetDXGIFormatSizeInfo(desc->Format);
+
+ UINT subresourceCount = desc->MipLevels;
+ if (mShadowInitData.size() < subresourceCount)
+ {
+ mShadowInitData.resize(subresourceCount);
+ }
+
+ for (UINT mipLevel = 0; mipLevel < desc->MipLevels; ++mipLevel)
+ {
+ UINT subresourceIndex = D3D11CalcSubresource(mipLevel, 0, desc->MipLevels);
+ D3D11_SUBRESOURCE_DATA *data = &mShadowInitData[subresourceIndex];
+
+ UINT levelWidth = std::max(desc->Width >> mipLevel, 1u);
+ UINT levelHeight = std::max(desc->Height >> mipLevel, 1u);
+
+ data->SysMemPitch = levelWidth * formatSizeInfo.pixelBytes;
+ data->SysMemSlicePitch = data->SysMemPitch * levelHeight;
+ data->pSysMem = mZeroMemory.data();
+ }
+
+ return mShadowInitData.data();
+}
+
+template <typename T>
+GetInitDataFromD3D11<T> *ResourceManager11::createInitDataIfNeeded(const GetDescFromD3D11<T> *desc)
+{
+ // No-op.
+ return nullptr;
+}
+
+void ResourceManager11::setAllocationsInitialized(bool initialize)
+{
+ mInitializeAllocations = initialize;
+}
+
+#define ANGLE_INSTANTIATE_OP(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) \
+ \
+ template angle::Result ResourceManager11::allocate( \
+ d3d::Context *, Renderer11 *, const DESCTYPE *, INITDATATYPE *, Resource11<D3D11TYPE> *);
+
+ANGLE_RESOURCE_TYPE_OP(Instantitate, ANGLE_INSTANTIATE_OP)
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ResourceManager11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ResourceManager11.h
new file mode 100644
index 0000000000..b013ab8358
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ResourceManager11.h
@@ -0,0 +1,411 @@
+//
+// Copyright 2017 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.
+//
+// ResourceManager11:
+// Centralized point of allocation for all D3D11 Resources.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_RESOURCEFACTORY11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_RESOURCEFACTORY11_H_
+
+#include <array>
+#include <atomic>
+#include <memory>
+
+#include "common/MemoryBuffer.h"
+#include "common/angleutils.h"
+#include "common/debug.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/renderer/serial_utils.h"
+
+namespace rx
+{
+// These two methods are declared here to prevent circular includes.
+namespace d3d11
+{
+HRESULT SetDebugName(ID3D11DeviceChild *resource,
+ const char *internalName,
+ const std::string *khrDebugName);
+
+template <typename T>
+HRESULT SetDebugName(angle::ComPtr<T> &resource,
+ const char *internalName,
+ const std::string *khrDebugName)
+{
+ return SetDebugName(resource.Get(), internalName, khrDebugName);
+}
+} // namespace d3d11
+
+namespace d3d
+{
+class Context;
+} // namespace d3d
+
+class Renderer11;
+class ResourceManager11;
+template <typename T>
+class SharedResource11;
+class TextureHelper11;
+
+using InputElementArray = WrappedArray<D3D11_INPUT_ELEMENT_DESC>;
+using ShaderData = WrappedArray<uint8_t>;
+
+// Format: ResourceType, D3D11 type, DESC type, init data type.
+#define ANGLE_RESOURCE_TYPE_OP(NAME, OP) \
+ OP(NAME, BlendState, ID3D11BlendState, D3D11_BLEND_DESC, void) \
+ OP(NAME, Buffer, ID3D11Buffer, D3D11_BUFFER_DESC, const D3D11_SUBRESOURCE_DATA) \
+ OP(NAME, ComputeShader, ID3D11ComputeShader, ShaderData, void) \
+ OP(NAME, DepthStencilState, ID3D11DepthStencilState, D3D11_DEPTH_STENCIL_DESC, void) \
+ OP(NAME, DepthStencilView, ID3D11DepthStencilView, D3D11_DEPTH_STENCIL_VIEW_DESC, \
+ ID3D11Resource) \
+ OP(NAME, GeometryShader, ID3D11GeometryShader, ShaderData, \
+ const std::vector<D3D11_SO_DECLARATION_ENTRY>) \
+ OP(NAME, InputLayout, ID3D11InputLayout, InputElementArray, const ShaderData) \
+ OP(NAME, PixelShader, ID3D11PixelShader, ShaderData, void) \
+ OP(NAME, Query, ID3D11Query, D3D11_QUERY_DESC, void) \
+ OP(NAME, RasterizerState, ID3D11RasterizerState, D3D11_RASTERIZER_DESC, void) \
+ OP(NAME, RenderTargetView, ID3D11RenderTargetView, D3D11_RENDER_TARGET_VIEW_DESC, \
+ ID3D11Resource) \
+ OP(NAME, SamplerState, ID3D11SamplerState, D3D11_SAMPLER_DESC, void) \
+ OP(NAME, ShaderResourceView, ID3D11ShaderResourceView, D3D11_SHADER_RESOURCE_VIEW_DESC, \
+ ID3D11Resource) \
+ OP(NAME, UnorderedAccessView, ID3D11UnorderedAccessView, D3D11_UNORDERED_ACCESS_VIEW_DESC, \
+ ID3D11Resource) \
+ OP(NAME, Texture2D, ID3D11Texture2D, D3D11_TEXTURE2D_DESC, const D3D11_SUBRESOURCE_DATA) \
+ OP(NAME, Texture3D, ID3D11Texture3D, D3D11_TEXTURE3D_DESC, const D3D11_SUBRESOURCE_DATA) \
+ OP(NAME, VertexShader, ID3D11VertexShader, ShaderData, void)
+
+#define ANGLE_RESOURCE_TYPE_LIST(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) RESTYPE,
+
+enum class ResourceType
+{
+ ANGLE_RESOURCE_TYPE_OP(List, ANGLE_RESOURCE_TYPE_LIST) Last
+};
+
+#undef ANGLE_RESOURCE_TYPE_LIST
+
+constexpr size_t ResourceTypeIndex(ResourceType resourceType)
+{
+ return static_cast<size_t>(resourceType);
+}
+
+constexpr size_t NumResourceTypes = ResourceTypeIndex(ResourceType::Last);
+
+#define ANGLE_RESOURCE_TYPE_TO_D3D11(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) \
+ \
+ template <> \
+ struct NAME<ResourceType::RESTYPE> \
+ { \
+ using Value = D3D11TYPE; \
+ };
+
+#define ANGLE_RESOURCE_TYPE_TO_DESC(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) \
+ \
+ template <> \
+ struct NAME<ResourceType::RESTYPE> \
+ { \
+ using Value = DESCTYPE; \
+ };
+
+#define ANGLE_RESOURCE_TYPE_TO_INIT_DATA(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) \
+ \
+ template <> \
+ struct NAME<ResourceType::RESTYPE> \
+ { \
+ using Value = INITDATATYPE; \
+ };
+
+#define ANGLE_RESOURCE_TYPE_TO_TYPE(NAME, OP) \
+ template <ResourceType Param> \
+ struct NAME; \
+ ANGLE_RESOURCE_TYPE_OP(NAME, OP) \
+ \
+ template <ResourceType Param> \
+ struct NAME \
+ {}; \
+ \
+ template <ResourceType Param> \
+ using Get##NAME = typename NAME<Param>::Value;
+
+ANGLE_RESOURCE_TYPE_TO_TYPE(D3D11Type, ANGLE_RESOURCE_TYPE_TO_D3D11)
+ANGLE_RESOURCE_TYPE_TO_TYPE(DescType, ANGLE_RESOURCE_TYPE_TO_DESC)
+ANGLE_RESOURCE_TYPE_TO_TYPE(InitDataType, ANGLE_RESOURCE_TYPE_TO_INIT_DATA)
+
+#undef ANGLE_RESOURCE_TYPE_TO_D3D11
+#undef ANGLE_RESOURCE_TYPE_TO_DESC
+#undef ANGLE_RESOURCE_TYPE_TO_INIT_DATA
+#undef ANGLE_RESOURCE_TYPE_TO_TYPE
+
+#define ANGLE_TYPE_TO_RESOURCE_TYPE(NAME, OP) \
+ template <typename Param> \
+ struct NAME; \
+ ANGLE_RESOURCE_TYPE_OP(NAME, OP) \
+ \
+ template <typename Param> \
+ struct NAME \
+ {}; \
+ \
+ template <typename Param> \
+ constexpr ResourceType Get##NAME() \
+ { \
+ return NAME<Param>::Value; \
+ }
+
+#define ANGLE_D3D11_TO_RESOURCE_TYPE(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) \
+ \
+ template <> \
+ struct NAME<D3D11TYPE> \
+ { \
+ static constexpr ResourceType Value = ResourceType::RESTYPE; \
+ };
+
+ANGLE_TYPE_TO_RESOURCE_TYPE(ResourceTypeFromD3D11, ANGLE_D3D11_TO_RESOURCE_TYPE)
+
+#undef ANGLE_D3D11_TO_RESOURCE_TYPE
+#undef ANGLE_TYPE_TO_RESOURCE_TYPE
+
+template <typename T>
+using GetDescFromD3D11 = GetDescType<ResourceTypeFromD3D11<T>::Value>;
+
+template <typename T>
+using GetInitDataFromD3D11 = GetInitDataType<ResourceTypeFromD3D11<T>::Value>;
+
+template <typename T>
+constexpr size_t ResourceTypeIndex()
+{
+ return static_cast<size_t>(GetResourceTypeFromD3D11<T>());
+}
+
+template <typename T>
+struct TypedData
+{
+ TypedData() {}
+ ~TypedData();
+
+ T *object = nullptr;
+ ResourceManager11 *manager = nullptr;
+};
+
+// Smart pointer type. Wraps the resource and a factory for safe deletion.
+template <typename T, template <class> class Pointer, typename DataT>
+class Resource11Base : angle::NonCopyable
+{
+ public:
+ T *get() const { return mData->object; }
+ T *const *getPointer() const { return &mData->object; }
+
+ void setInternalName(const char *name)
+ {
+ mInternalDebugName = name;
+ UpdateDebugNameWithD3D();
+ }
+
+ void setKHRDebugLabel(const std::string *label)
+ {
+ mKhrDebugName = label;
+ UpdateDebugNameWithD3D();
+ }
+
+ void setLabels(const char *name, const std::string *label)
+ {
+ mInternalDebugName = name;
+ mKhrDebugName = label;
+ UpdateDebugNameWithD3D();
+ }
+
+ void set(T *object)
+ {
+ ASSERT(!valid());
+ mData->object = object;
+ }
+
+ bool valid() const { return (mData->object != nullptr); }
+
+ void reset()
+ {
+ if (valid())
+ mData.reset(new DataT());
+ }
+
+ ResourceSerial getSerial() const
+ {
+ return ResourceSerial(reinterpret_cast<uintptr_t>(mData->object));
+ }
+
+ protected:
+ friend class TextureHelper11;
+
+ Resource11Base() : mData(new DataT()) {}
+
+ Resource11Base(Resource11Base &&movedObj) : mData(new DataT())
+ {
+ std::swap(mData, movedObj.mData);
+ }
+
+ virtual ~Resource11Base() { mData.reset(); }
+
+ Resource11Base &operator=(Resource11Base &&movedObj)
+ {
+ std::swap(mData, movedObj.mData);
+ return *this;
+ }
+
+ Pointer<DataT> mData;
+
+ private:
+ void UpdateDebugNameWithD3D()
+ {
+ d3d11::SetDebugName(mData->object, mInternalDebugName, mKhrDebugName);
+ }
+
+ const std::string *mKhrDebugName = nullptr;
+ const char *mInternalDebugName = nullptr;
+};
+
+template <typename T>
+using UniquePtr = typename std::unique_ptr<T, std::default_delete<T>>;
+
+template <typename ResourceT>
+class Resource11 : public Resource11Base<ResourceT, UniquePtr, TypedData<ResourceT>>
+{
+ public:
+ Resource11() {}
+ Resource11(Resource11 &&other)
+ : Resource11Base<ResourceT, UniquePtr, TypedData<ResourceT>>(std::move(other))
+ {}
+ Resource11 &operator=(Resource11 &&other)
+ {
+ std::swap(this->mData, other.mData);
+ return *this;
+ }
+
+ private:
+ template <typename T>
+ friend class SharedResource11;
+ friend class ResourceManager11;
+
+ Resource11(ResourceT *object, ResourceManager11 *manager)
+ {
+ this->mData->object = object;
+ this->mData->manager = manager;
+ }
+};
+
+template <typename T>
+class SharedResource11 : public Resource11Base<T, std::shared_ptr, TypedData<T>>
+{
+ public:
+ SharedResource11() {}
+ SharedResource11(SharedResource11 &&movedObj)
+ : Resource11Base<T, std::shared_ptr, TypedData<T>>(std::move(movedObj))
+ {}
+
+ SharedResource11 &operator=(SharedResource11 &&other)
+ {
+ std::swap(this->mData, other.mData);
+ return *this;
+ }
+
+ SharedResource11 makeCopy() const
+ {
+ SharedResource11 copy;
+ copy.mData = this->mData;
+ return std::move(copy);
+ }
+
+ private:
+ friend class ResourceManager11;
+ SharedResource11(Resource11<T> &&obj) : Resource11Base<T, std::shared_ptr, TypedData<T>>()
+ {
+ std::swap(this->mData->manager, obj.mData->manager);
+
+ // Can't use std::swap because of ID3D11Resource.
+ auto temp = this->mData->object;
+ this->mData->object = obj.mData->object;
+ obj.mData->object = static_cast<T *>(temp);
+ }
+};
+
+class ResourceManager11 final : angle::NonCopyable
+{
+ public:
+ ResourceManager11();
+ ~ResourceManager11();
+
+ template <typename T>
+ angle::Result allocate(d3d::Context *context,
+ Renderer11 *renderer,
+ const GetDescFromD3D11<T> *desc,
+ GetInitDataFromD3D11<T> *initData,
+ Resource11<T> *resourceOut);
+
+ template <typename T>
+ angle::Result allocate(d3d::Context *context,
+ Renderer11 *renderer,
+ const GetDescFromD3D11<T> *desc,
+ GetInitDataFromD3D11<T> *initData,
+ SharedResource11<T> *sharedRes)
+ {
+ Resource11<T> res;
+ ANGLE_TRY(allocate(context, renderer, desc, initData, &res));
+ *sharedRes = std::move(res);
+ return angle::Result::Continue;
+ }
+
+ template <typename T>
+ void onRelease(T *resource)
+ {
+ onReleaseGeneric(GetResourceTypeFromD3D11<T>(), resource);
+ }
+
+ void onReleaseGeneric(ResourceType resourceType, ID3D11DeviceChild *resource);
+
+ void setAllocationsInitialized(bool initialize);
+
+ private:
+ void incrResource(ResourceType resourceType, uint64_t memorySize);
+ void decrResource(ResourceType resourceType, uint64_t memorySize);
+
+ template <typename T>
+ GetInitDataFromD3D11<T> *createInitDataIfNeeded(const GetDescFromD3D11<T> *desc);
+
+ bool mInitializeAllocations;
+
+ std::array<std::atomic_size_t, NumResourceTypes> mAllocatedResourceCounts;
+ std::array<std::atomic_uint64_t, NumResourceTypes> mAllocatedResourceDeviceMemory;
+ angle::MemoryBuffer mZeroMemory;
+
+ std::vector<D3D11_SUBRESOURCE_DATA> mShadowInitData;
+};
+
+template <typename ResourceT>
+TypedData<ResourceT>::~TypedData()
+{
+ if (object)
+ {
+ // We can have a nullptr factory when holding passed-in resources.
+ if (manager)
+ {
+ manager->onRelease(object);
+ }
+ object->Release();
+ }
+}
+
+#define ANGLE_RESOURCE_TYPE_CLASS(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) \
+ using RESTYPE = Resource11<D3D11TYPE>;
+
+namespace d3d11
+{
+ANGLE_RESOURCE_TYPE_OP(ClassList, ANGLE_RESOURCE_TYPE_CLASS)
+
+using SharedSRV = SharedResource11<ID3D11ShaderResourceView>;
+using SharedUAV = SharedResource11<ID3D11UnorderedAccessView>;
+} // namespace d3d11
+
+#undef ANGLE_RESOURCE_TYPE_CLASS
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D11_RESOURCEFACTORY11_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.cpp
new file mode 100644
index 0000000000..a30ca417c1
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.cpp
@@ -0,0 +1,116 @@
+//
+// Copyright 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.
+//
+
+// ShaderExecutable11.cpp: Implements a D3D11-specific class to contain shader
+// executable implementation details.
+
+#include "libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h"
+
+#include "libANGLE/Context.h"
+#include "libANGLE/renderer/d3d/d3d11/Context11.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+
+namespace rx
+{
+
+ShaderExecutable11::ShaderExecutable11(const void *function,
+ size_t length,
+ d3d11::PixelShader &&executable)
+ : ShaderExecutableD3D(function, length),
+ mPixelExecutable(std::move(executable)),
+ mVertexExecutable(),
+ mGeometryExecutable(),
+ mStreamOutExecutable(),
+ mComputeExecutable()
+{}
+
+ShaderExecutable11::ShaderExecutable11(const void *function,
+ size_t length,
+ d3d11::VertexShader &&executable,
+ d3d11::GeometryShader &&streamOut)
+ : ShaderExecutableD3D(function, length),
+ mPixelExecutable(),
+ mVertexExecutable(std::move(executable)),
+ mGeometryExecutable(),
+ mStreamOutExecutable(std::move(streamOut)),
+ mComputeExecutable()
+{}
+
+ShaderExecutable11::ShaderExecutable11(const void *function,
+ size_t length,
+ d3d11::GeometryShader &&executable)
+ : ShaderExecutableD3D(function, length),
+ mPixelExecutable(),
+ mVertexExecutable(),
+ mGeometryExecutable(std::move(executable)),
+ mStreamOutExecutable(),
+ mComputeExecutable()
+{}
+
+ShaderExecutable11::ShaderExecutable11(const void *function,
+ size_t length,
+ d3d11::ComputeShader &&executable)
+ : ShaderExecutableD3D(function, length),
+ mPixelExecutable(),
+ mVertexExecutable(),
+ mGeometryExecutable(),
+ mStreamOutExecutable(),
+ mComputeExecutable(std::move(executable))
+{}
+
+ShaderExecutable11::~ShaderExecutable11() {}
+
+const d3d11::VertexShader &ShaderExecutable11::getVertexShader() const
+{
+ return mVertexExecutable;
+}
+
+const d3d11::PixelShader &ShaderExecutable11::getPixelShader() const
+{
+ return mPixelExecutable;
+}
+
+const d3d11::GeometryShader &ShaderExecutable11::getGeometryShader() const
+{
+ return mGeometryExecutable;
+}
+
+const d3d11::GeometryShader &ShaderExecutable11::getStreamOutShader() const
+{
+ return mStreamOutExecutable;
+}
+
+const d3d11::ComputeShader &ShaderExecutable11::getComputeShader() const
+{
+ return mComputeExecutable;
+}
+
+UniformStorage11::UniformStorage11(size_t initialSize)
+ : UniformStorageD3D(initialSize), mConstantBuffer()
+{}
+
+UniformStorage11::~UniformStorage11() {}
+
+angle::Result UniformStorage11::getConstantBuffer(const gl::Context *context,
+ Renderer11 *renderer,
+ const d3d11::Buffer **bufferOut)
+{
+ if (size() > 0 && !mConstantBuffer.valid())
+ {
+ D3D11_BUFFER_DESC desc = {};
+ desc.ByteWidth = static_cast<unsigned int>(size());
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
+
+ ANGLE_TRY(
+ renderer->allocateResource(GetImplAs<Context11>(context), desc, &mConstantBuffer));
+ }
+
+ *bufferOut = &mConstantBuffer;
+ return angle::Result::Continue;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h
new file mode 100644
index 0000000000..75c71b3238
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h
@@ -0,0 +1,69 @@
+//
+// Copyright 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.
+//
+
+// ShaderExecutable11.h: Defines a D3D11-specific class to contain shader
+// executable implementation details.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_SHADEREXECUTABLE11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_SHADEREXECUTABLE11_H_
+
+#include "libANGLE/renderer/d3d/ShaderExecutableD3D.h"
+#include "libANGLE/renderer/d3d/d3d11/ResourceManager11.h"
+
+namespace gl
+{
+class Context;
+} // namespace gl
+
+namespace rx
+{
+class Renderer11;
+class UniformStorage11;
+
+class ShaderExecutable11 : public ShaderExecutableD3D
+{
+ public:
+ ShaderExecutable11(const void *function, size_t length, d3d11::PixelShader &&executable);
+ ShaderExecutable11(const void *function,
+ size_t length,
+ d3d11::VertexShader &&executable,
+ d3d11::GeometryShader &&streamOut);
+ ShaderExecutable11(const void *function, size_t length, d3d11::GeometryShader &&executable);
+ ShaderExecutable11(const void *function, size_t length, d3d11::ComputeShader &&executable);
+
+ ~ShaderExecutable11() override;
+
+ const d3d11::PixelShader &getPixelShader() const;
+ const d3d11::VertexShader &getVertexShader() const;
+ const d3d11::GeometryShader &getGeometryShader() const;
+ const d3d11::GeometryShader &getStreamOutShader() const;
+ const d3d11::ComputeShader &getComputeShader() const;
+
+ private:
+ d3d11::PixelShader mPixelExecutable;
+ d3d11::VertexShader mVertexExecutable;
+ d3d11::GeometryShader mGeometryExecutable;
+ d3d11::GeometryShader mStreamOutExecutable;
+ d3d11::ComputeShader mComputeExecutable;
+};
+
+class UniformStorage11 : public UniformStorageD3D
+{
+ public:
+ UniformStorage11(size_t initialSize);
+ ~UniformStorage11() override;
+
+ angle::Result getConstantBuffer(const gl::Context *context,
+ Renderer11 *renderer,
+ const d3d11::Buffer **bufferOut);
+
+ private:
+ d3d11::Buffer mConstantBuffer;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D11_SHADEREXECUTABLE11_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp
new file mode 100644
index 0000000000..194c89d1c7
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/StateManager11.cpp
@@ -0,0 +1,4004 @@
+//
+// 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.
+//
+
+// StateManager11.cpp: Defines a class for caching D3D11 state
+
+#include "libANGLE/renderer/d3d/d3d11/StateManager11.h"
+
+#include "common/angleutils.h"
+#include "common/bitset_utils.h"
+#include "common/mathutil.h"
+#include "common/utilities.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Query.h"
+#include "libANGLE/Surface.h"
+#include "libANGLE/VertexArray.h"
+#include "libANGLE/renderer/d3d/DisplayD3D.h"
+#include "libANGLE/renderer/d3d/TextureD3D.h"
+#include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
+#include "libANGLE/renderer/d3d/d3d11/Context11.h"
+#include "libANGLE/renderer/d3d/d3d11/Framebuffer11.h"
+#include "libANGLE/renderer/d3d/d3d11/IndexBuffer11.h"
+#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h"
+#include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h"
+#include "libANGLE/renderer/d3d/d3d11/TransformFeedback11.h"
+#include "libANGLE/renderer/d3d/d3d11/VertexArray11.h"
+#include "libANGLE/renderer/d3d/d3d11/VertexBuffer11.h"
+
+namespace rx
+{
+
+namespace
+{
+bool ImageIndexConflictsWithSRV(const gl::ImageIndex &index, D3D11_SHADER_RESOURCE_VIEW_DESC desc)
+{
+ unsigned mipLevel = index.getLevelIndex();
+ gl::TextureType textureType = index.getType();
+
+ switch (desc.ViewDimension)
+ {
+ case D3D11_SRV_DIMENSION_TEXTURE2D:
+ {
+ 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.getLevelIndex();
+ unsigned mipMax = INT_MAX;
+
+ return textureType == gl::TextureType::_2D &&
+ gl::RangeUI(mipMin, mipMax)
+ .intersects(gl::RangeUI(desc.Texture2D.MostDetailedMip, maxSrvMip));
+ }
+
+ case D3D11_SRV_DIMENSION_TEXTURE2DARRAY:
+ {
+ GLint layerIndex = index.getLayerIndex();
+
+ bool allLevels = (desc.Texture2DArray.MipLevels == std::numeric_limits<UINT>::max());
+ unsigned int maxSrvMip =
+ desc.Texture2DArray.MipLevels + desc.Texture2DArray.MostDetailedMip;
+ maxSrvMip = allLevels ? INT_MAX : maxSrvMip;
+
+ unsigned maxSlice = desc.Texture2DArray.FirstArraySlice + desc.Texture2DArray.ArraySize;
+
+ // Cube maps can be mapped to Texture2DArray SRVs
+ return (textureType == gl::TextureType::_2DArray ||
+ textureType == gl::TextureType::CubeMap) &&
+ desc.Texture2DArray.MostDetailedMip <= mipLevel && mipLevel < maxSrvMip &&
+ desc.Texture2DArray.FirstArraySlice <= static_cast<UINT>(layerIndex) &&
+ static_cast<UINT>(layerIndex) < maxSlice;
+ }
+
+ case D3D11_SRV_DIMENSION_TEXTURECUBE:
+ {
+ 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 textureType == gl::TextureType::CubeMap &&
+ desc.TextureCube.MostDetailedMip <= mipLevel && mipLevel < maxSrvMip;
+ }
+
+ case D3D11_SRV_DIMENSION_TEXTURE3D:
+ {
+ 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 textureType == gl::TextureType::_3D &&
+ desc.Texture3D.MostDetailedMip <= mipLevel && mipLevel < maxSrvMip;
+ }
+ default:
+ // We only handle the cases corresponding to valid image indexes
+ UNIMPLEMENTED();
+ }
+
+ return false;
+}
+
+bool ImageIndexConflictsWithUAV(const gl::ImageIndex &index, D3D11_UNORDERED_ACCESS_VIEW_DESC desc)
+{
+ unsigned mipLevel = index.getLevelIndex();
+ gl::TextureType textureType = index.getType();
+
+ switch (desc.ViewDimension)
+ {
+ case D3D11_UAV_DIMENSION_TEXTURE2D:
+ {
+ return textureType == gl::TextureType::_2D && mipLevel == desc.Texture2D.MipSlice;
+ }
+
+ case D3D11_UAV_DIMENSION_TEXTURE2DARRAY:
+ {
+ GLint layerIndex = index.getLayerIndex();
+ unsigned mipSlice = desc.Texture2DArray.MipSlice;
+ unsigned firstArraySlice = desc.Texture2DArray.FirstArraySlice;
+ unsigned lastArraySlice = firstArraySlice + desc.Texture2DArray.ArraySize;
+
+ return (textureType == gl::TextureType::_2DArray ||
+ textureType == gl::TextureType::CubeMap) &&
+ (mipLevel == mipSlice && gl::RangeUI(firstArraySlice, lastArraySlice)
+ .contains(static_cast<UINT>(layerIndex)));
+ }
+
+ case D3D11_UAV_DIMENSION_TEXTURE3D:
+ {
+ GLint layerIndex = index.getLayerIndex();
+ unsigned mipSlice = desc.Texture3D.MipSlice;
+ unsigned firstWSlice = desc.Texture3D.FirstWSlice;
+ unsigned lastWSlice = firstWSlice + desc.Texture3D.WSize;
+
+ return textureType == gl::TextureType::_3D &&
+ (mipLevel == mipSlice &&
+ gl::RangeUI(firstWSlice, lastWSlice).contains(static_cast<UINT>(layerIndex)));
+ }
+ default:
+ return false;
+ }
+}
+
+// Does *not* increment the resource ref count!!
+ID3D11Resource *GetViewResource(ID3D11View *view)
+{
+ ID3D11Resource *resource = nullptr;
+ ASSERT(view);
+ view->GetResource(&resource);
+ resource->Release();
+ return resource;
+}
+
+int GetWrapBits(GLenum wrap)
+{
+ switch (wrap)
+ {
+ case GL_CLAMP_TO_EDGE:
+ return 0x0;
+ case GL_REPEAT:
+ return 0x1;
+ case GL_MIRRORED_REPEAT:
+ return 0x2;
+ case GL_CLAMP_TO_BORDER:
+ return 0x3;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+Optional<size_t> FindFirstNonInstanced(
+ const std::vector<const TranslatedAttribute *> &currentAttributes)
+{
+ for (size_t index = 0; index < currentAttributes.size(); ++index)
+ {
+ if (currentAttributes[index]->divisor == 0)
+ {
+ return Optional<size_t>(index);
+ }
+ }
+
+ return Optional<size_t>::Invalid();
+}
+
+void SortAttributesByLayout(const ProgramD3D &programD3D,
+ const std::vector<TranslatedAttribute> &vertexArrayAttribs,
+ const std::vector<TranslatedAttribute> &currentValueAttribs,
+ AttribIndexArray *sortedD3DSemanticsOut,
+ std::vector<const TranslatedAttribute *> *sortedAttributesOut)
+{
+ sortedAttributesOut->clear();
+
+ const AttribIndexArray &locationToSemantic = programD3D.getAttribLocationToD3DSemantics();
+ const gl::ProgramExecutable &executable = programD3D.getState().getExecutable();
+
+ for (auto locationIndex : executable.getActiveAttribLocationsMask())
+ {
+ int d3dSemantic = locationToSemantic[locationIndex];
+ if (sortedAttributesOut->size() <= static_cast<size_t>(d3dSemantic))
+ {
+ sortedAttributesOut->resize(d3dSemantic + 1);
+ }
+
+ (*sortedD3DSemanticsOut)[d3dSemantic] = d3dSemantic;
+
+ const auto *arrayAttrib = &vertexArrayAttribs[locationIndex];
+ if (arrayAttrib->attribute && arrayAttrib->attribute->enabled)
+ {
+ (*sortedAttributesOut)[d3dSemantic] = arrayAttrib;
+ }
+ else
+ {
+ ASSERT(currentValueAttribs[locationIndex].attribute);
+ (*sortedAttributesOut)[d3dSemantic] = &currentValueAttribs[locationIndex];
+ }
+ }
+}
+
+void UpdateUniformBuffer(ID3D11DeviceContext *deviceContext,
+ UniformStorage11 *storage,
+ const d3d11::Buffer *buffer)
+{
+ deviceContext->UpdateSubresource(buffer->get(), 0, nullptr, storage->getDataPointer(0, 0), 0,
+ 0);
+}
+
+size_t GetReservedBufferCount(bool usesPointSpriteEmulation)
+{
+ return usesPointSpriteEmulation ? 1 : 0;
+}
+
+bool CullsEverything(const gl::State &glState)
+{
+ return (glState.getRasterizerState().cullFace &&
+ glState.getRasterizerState().cullMode == gl::CullFaceMode::FrontAndBack);
+}
+} // anonymous namespace
+
+// StateManager11::ViewCache Implementation.
+template <typename ViewType, typename DescType>
+StateManager11::ViewCache<ViewType, DescType>::ViewCache() : mHighestUsedView(0)
+{}
+
+template <typename ViewType, typename DescType>
+StateManager11::ViewCache<ViewType, DescType>::~ViewCache()
+{}
+
+template <typename ViewType, typename DescType>
+void StateManager11::ViewCache<ViewType, DescType>::update(size_t resourceIndex, ViewType *view)
+{
+ ASSERT(resourceIndex < mCurrentViews.size());
+ ViewRecord<DescType> *record = &mCurrentViews[resourceIndex];
+
+ record->view = reinterpret_cast<uintptr_t>(view);
+ if (view)
+ {
+ record->resource = reinterpret_cast<uintptr_t>(GetViewResource(view));
+ view->GetDesc(&record->desc);
+ mHighestUsedView = std::max(resourceIndex + 1, mHighestUsedView);
+ }
+ else
+ {
+ record->resource = 0;
+
+ if (resourceIndex + 1 == mHighestUsedView)
+ {
+ do
+ {
+ --mHighestUsedView;
+ } while (mHighestUsedView > 0 && mCurrentViews[mHighestUsedView].view == 0);
+ }
+ }
+}
+
+template <typename ViewType, typename DescType>
+void StateManager11::ViewCache<ViewType, DescType>::clear()
+{
+ if (mCurrentViews.empty())
+ {
+ return;
+ }
+
+ memset(&mCurrentViews[0], 0, sizeof(ViewRecord<DescType>) * mCurrentViews.size());
+ mHighestUsedView = 0;
+}
+
+StateManager11::SRVCache *StateManager11::getSRVCache(gl::ShaderType shaderType)
+{
+ ASSERT(shaderType != gl::ShaderType::InvalidEnum);
+ return &mCurShaderSRVs[shaderType];
+}
+
+// ShaderConstants11 implementation
+ShaderConstants11::ShaderConstants11() : mNumActiveShaderSamplers({})
+{
+ mShaderConstantsDirty.set();
+}
+
+ShaderConstants11::~ShaderConstants11() {}
+
+void ShaderConstants11::init(const gl::Caps &caps)
+{
+ for (gl::ShaderType shaderType : gl::AllShaderTypes())
+ {
+ mShaderSamplerMetadata[shaderType].resize(caps.maxShaderTextureImageUnits[shaderType]);
+ mShaderReadonlyImageMetadata[shaderType].resize(caps.maxShaderImageUniforms[shaderType]);
+ mShaderImageMetadata[shaderType].resize(caps.maxShaderImageUniforms[shaderType]);
+ }
+}
+
+size_t ShaderConstants11::GetShaderConstantsStructSize(gl::ShaderType shaderType)
+{
+ switch (shaderType)
+ {
+ case gl::ShaderType::Vertex:
+ return sizeof(Vertex);
+ case gl::ShaderType::Fragment:
+ return sizeof(Pixel);
+ case gl::ShaderType::Compute:
+ return sizeof(Compute);
+
+ // TODO(jiawei.shao@intel.com): return geometry shader constant struct size
+ case gl::ShaderType::Geometry:
+ return 0u;
+
+ default:
+ UNREACHABLE();
+ return 0u;
+ }
+}
+
+size_t ShaderConstants11::getRequiredBufferSize(gl::ShaderType shaderType) const
+{
+ ASSERT(shaderType != gl::ShaderType::InvalidEnum);
+ return GetShaderConstantsStructSize(shaderType) +
+ mShaderSamplerMetadata[shaderType].size() * sizeof(SamplerMetadata) +
+ mShaderImageMetadata[shaderType].size() * sizeof(ImageMetadata) +
+ mShaderReadonlyImageMetadata[shaderType].size() * sizeof(ImageMetadata);
+}
+
+void ShaderConstants11::markDirty()
+{
+ mShaderConstantsDirty.set();
+ mNumActiveShaderSamplers.fill(0);
+}
+
+bool ShaderConstants11::updateSamplerMetadata(SamplerMetadata *data,
+ const gl::Texture &texture,
+ const gl::SamplerState &samplerState)
+{
+ bool dirty = false;
+ unsigned int baseLevel = texture.getTextureState().getEffectiveBaseLevel();
+ gl::TextureTarget target = (texture.getType() == gl::TextureType::CubeMap)
+ ? gl::kCubeMapTextureTargetMin
+ : gl::NonCubeTextureTypeToTarget(texture.getType());
+ GLenum sizedFormat = texture.getFormat(target, baseLevel).info->sizedInternalFormat;
+ if (data->baseLevel != static_cast<int>(baseLevel))
+ {
+ data->baseLevel = static_cast<int>(baseLevel);
+ dirty = true;
+ }
+
+ // Some metadata is needed only for integer textures. We avoid updating the constant buffer
+ // unnecessarily by changing the data only in case the texture is an integer texture and
+ // the values have changed.
+ bool needIntegerTextureMetadata = false;
+ // internalFormatBits == 0 means a 32-bit texture in the case of integer textures.
+ int internalFormatBits = 0;
+ switch (sizedFormat)
+ {
+ case GL_RGBA32I:
+ case GL_RGBA32UI:
+ case GL_RGB32I:
+ case GL_RGB32UI:
+ case GL_RG32I:
+ case GL_RG32UI:
+ case GL_R32I:
+ case GL_R32UI:
+ needIntegerTextureMetadata = true;
+ break;
+ case GL_RGBA16I:
+ case GL_RGBA16UI:
+ case GL_RGB16I:
+ case GL_RGB16UI:
+ case GL_RG16I:
+ case GL_RG16UI:
+ case GL_R16I:
+ case GL_R16UI:
+ needIntegerTextureMetadata = true;
+ internalFormatBits = 16;
+ break;
+ case GL_RGBA8I:
+ case GL_RGBA8UI:
+ case GL_RGB8I:
+ case GL_RGB8UI:
+ case GL_RG8I:
+ case GL_RG8UI:
+ case GL_R8I:
+ case GL_R8UI:
+ needIntegerTextureMetadata = true;
+ internalFormatBits = 8;
+ break;
+ case GL_RGB10_A2UI:
+ needIntegerTextureMetadata = true;
+ internalFormatBits = 10;
+ break;
+ default:
+ break;
+ }
+ if (needIntegerTextureMetadata)
+ {
+ if (data->internalFormatBits != internalFormatBits)
+ {
+ data->internalFormatBits = internalFormatBits;
+ dirty = true;
+ }
+ // Pack the wrap values into one integer so we can fit all the metadata in two 4-integer
+ // vectors.
+ GLenum wrapS = samplerState.getWrapS();
+ GLenum wrapT = samplerState.getWrapT();
+ GLenum wrapR = samplerState.getWrapR();
+ int wrapModes = GetWrapBits(wrapS) | (GetWrapBits(wrapT) << 2) | (GetWrapBits(wrapR) << 4);
+ if (data->wrapModes != wrapModes)
+ {
+ data->wrapModes = wrapModes;
+ dirty = true;
+ }
+
+ const angle::ColorGeneric &borderColor(samplerState.getBorderColor());
+ constexpr int kBlack[4] = {};
+ const void *const intBorderColor = (borderColor.type == angle::ColorGeneric::Type::Float)
+ ? kBlack
+ : borderColor.colorI.data();
+ ASSERT(static_cast<const void *>(borderColor.colorI.data()) ==
+ static_cast<const void *>(borderColor.colorUI.data()));
+ if (memcmp(data->intBorderColor, intBorderColor, sizeof(data->intBorderColor)) != 0)
+ {
+ memcpy(data->intBorderColor, intBorderColor, sizeof(data->intBorderColor));
+ dirty = true;
+ }
+ }
+
+ return dirty;
+}
+
+bool ShaderConstants11::updateImageMetadata(ImageMetadata *data, const gl::ImageUnit &imageUnit)
+{
+ bool dirty = false;
+
+ if (data->layer != static_cast<int>(imageUnit.layer))
+ {
+ data->layer = static_cast<int>(imageUnit.layer);
+ dirty = true;
+ }
+
+ if (data->level != static_cast<unsigned int>(imageUnit.level))
+ {
+ data->level = static_cast<unsigned int>(imageUnit.level);
+ dirty = true;
+ }
+
+ return dirty;
+}
+
+void ShaderConstants11::setComputeWorkGroups(GLuint numGroupsX,
+ GLuint numGroupsY,
+ GLuint numGroupsZ)
+{
+ mCompute.numWorkGroups[0] = numGroupsX;
+ mCompute.numWorkGroups[1] = numGroupsY;
+ mCompute.numWorkGroups[2] = numGroupsZ;
+ mShaderConstantsDirty.set(gl::ShaderType::Compute);
+}
+
+void ShaderConstants11::setMultiviewWriteToViewportIndex(GLfloat index)
+{
+ mVertex.multiviewWriteToViewportIndex = index;
+ mPixel.multiviewWriteToViewportIndex = index;
+ mShaderConstantsDirty.set(gl::ShaderType::Vertex);
+ mShaderConstantsDirty.set(gl::ShaderType::Fragment);
+}
+
+void ShaderConstants11::onViewportChange(const gl::Rectangle &glViewport,
+ const D3D11_VIEWPORT &dxViewport,
+ const gl::Offset &glFragCoordOffset,
+ bool is9_3,
+ bool presentPathFast)
+{
+ mShaderConstantsDirty.set(gl::ShaderType::Vertex);
+ mShaderConstantsDirty.set(gl::ShaderType::Fragment);
+
+ // On Feature Level 9_*, we must emulate large and/or negative viewports in the shaders
+ // using viewAdjust (like the D3D9 renderer).
+ if (is9_3)
+ {
+ mVertex.viewAdjust[0] = static_cast<float>((glViewport.width - dxViewport.Width) +
+ 2 * (glViewport.x - dxViewport.TopLeftX)) /
+ dxViewport.Width;
+ mVertex.viewAdjust[1] = static_cast<float>((glViewport.height - dxViewport.Height) +
+ 2 * (glViewport.y - dxViewport.TopLeftY)) /
+ dxViewport.Height;
+ mVertex.viewAdjust[2] = static_cast<float>(glViewport.width) / dxViewport.Width;
+ mVertex.viewAdjust[3] = static_cast<float>(glViewport.height) / dxViewport.Height;
+ }
+
+ mPixel.viewCoords[0] = glViewport.width * 0.5f;
+ mPixel.viewCoords[1] = glViewport.height * 0.5f;
+ mPixel.viewCoords[2] = glViewport.x + (glViewport.width * 0.5f);
+ mPixel.viewCoords[3] = glViewport.y + (glViewport.height * 0.5f);
+
+ // Instanced pointsprite emulation requires ViewCoords to be defined in the
+ // the vertex shader.
+ mVertex.viewCoords[0] = mPixel.viewCoords[0];
+ mVertex.viewCoords[1] = mPixel.viewCoords[1];
+ mVertex.viewCoords[2] = mPixel.viewCoords[2];
+ mVertex.viewCoords[3] = mPixel.viewCoords[3];
+
+ const float zNear = dxViewport.MinDepth;
+ const float zFar = dxViewport.MaxDepth;
+
+ mPixel.depthFront[0] = (zFar - zNear) * 0.5f;
+ mPixel.depthFront[1] = (zNear + zFar) * 0.5f;
+
+ mVertex.depthRange[0] = zNear;
+ mVertex.depthRange[1] = zFar;
+ mVertex.depthRange[2] = zFar - zNear;
+
+ mPixel.depthRange[0] = zNear;
+ mPixel.depthRange[1] = zFar;
+ mPixel.depthRange[2] = zFar - zNear;
+
+ mPixel.viewScale[0] = 1.0f;
+ mPixel.viewScale[1] = presentPathFast ? 1.0f : -1.0f;
+ // Updates to the multiviewWriteToViewportIndex member are to be handled whenever the draw
+ // framebuffer's layout is changed.
+
+ mVertex.viewScale[0] = mPixel.viewScale[0];
+ mVertex.viewScale[1] = mPixel.viewScale[1];
+
+ mPixel.fragCoordOffset[0] = static_cast<float>(glFragCoordOffset.x);
+ mPixel.fragCoordOffset[1] = static_cast<float>(glFragCoordOffset.y);
+}
+
+// Update the ShaderConstants with a new first vertex and return whether the update dirties them.
+ANGLE_INLINE bool ShaderConstants11::onFirstVertexChange(GLint firstVertex)
+{
+ // firstVertex should already include baseVertex, if any.
+ uint32_t newFirstVertex = static_cast<uint32_t>(firstVertex);
+
+ bool firstVertexDirty = (mVertex.firstVertex != newFirstVertex);
+ if (firstVertexDirty)
+ {
+ mVertex.firstVertex = newFirstVertex;
+ mShaderConstantsDirty.set(gl::ShaderType::Vertex);
+ }
+ return firstVertexDirty;
+}
+
+void ShaderConstants11::onSamplerChange(gl::ShaderType shaderType,
+ unsigned int samplerIndex,
+ const gl::Texture &texture,
+ const gl::SamplerState &samplerState)
+{
+ ASSERT(shaderType != gl::ShaderType::InvalidEnum);
+ if (updateSamplerMetadata(&mShaderSamplerMetadata[shaderType][samplerIndex], texture,
+ samplerState))
+ {
+ mNumActiveShaderSamplers[shaderType] = 0;
+ }
+}
+
+bool ShaderConstants11::onImageChange(gl::ShaderType shaderType,
+ unsigned int imageIndex,
+ const gl::ImageUnit &imageUnit)
+{
+ ASSERT(shaderType != gl::ShaderType::InvalidEnum);
+ bool dirty = false;
+ if (imageUnit.access == GL_READ_ONLY)
+ {
+ if (updateImageMetadata(&mShaderReadonlyImageMetadata[shaderType][imageIndex], imageUnit))
+ {
+ mNumActiveShaderReadonlyImages[shaderType] = 0;
+ dirty = true;
+ }
+ }
+ else
+ {
+ if (updateImageMetadata(&mShaderImageMetadata[shaderType][imageIndex], imageUnit))
+ {
+ mNumActiveShaderImages[shaderType] = 0;
+ dirty = true;
+ }
+ }
+ return dirty;
+}
+
+void ShaderConstants11::onClipControlChange(bool lowerLeft, bool zeroToOne)
+{
+ mVertex.clipControlOrigin = lowerLeft ? -1.0f : 1.0f;
+ mVertex.clipControlZeroToOne = zeroToOne ? 1.0f : 0.0f;
+ mShaderConstantsDirty.set(gl::ShaderType::Vertex);
+}
+
+angle::Result ShaderConstants11::updateBuffer(const gl::Context *context,
+ Renderer11 *renderer,
+ gl::ShaderType shaderType,
+ const ProgramD3D &programD3D,
+ const d3d11::Buffer &driverConstantBuffer)
+{
+ // Re-upload the sampler meta-data if the current program uses more samplers
+ // than we previously uploaded.
+ const int numSamplers = programD3D.getUsedSamplerRange(shaderType).length();
+ const int numReadonlyImages = programD3D.getUsedImageRange(shaderType, true).length();
+ const int numImages = programD3D.getUsedImageRange(shaderType, false).length();
+
+ const bool dirty = mShaderConstantsDirty[shaderType] ||
+ (mNumActiveShaderSamplers[shaderType] < numSamplers) ||
+ (mNumActiveShaderReadonlyImages[shaderType] < numReadonlyImages) ||
+ (mNumActiveShaderImages[shaderType] < numImages);
+
+ const size_t dataSize = GetShaderConstantsStructSize(shaderType);
+ const uint8_t *samplerData =
+ reinterpret_cast<const uint8_t *>(mShaderSamplerMetadata[shaderType].data());
+ const size_t samplerDataSize = sizeof(SamplerMetadata) * numSamplers;
+ const uint8_t *readonlyImageData =
+ reinterpret_cast<const uint8_t *>(mShaderReadonlyImageMetadata[shaderType].data());
+ const size_t readonlyImageDataSize = sizeof(ImageMetadata) * numReadonlyImages;
+ const uint8_t *imageData =
+ reinterpret_cast<const uint8_t *>(mShaderImageMetadata[shaderType].data());
+ const size_t imageDataSize = sizeof(ImageMetadata) * numImages;
+
+ mNumActiveShaderSamplers[shaderType] = numSamplers;
+ mNumActiveShaderReadonlyImages[shaderType] = numReadonlyImages;
+ mNumActiveShaderImages[shaderType] = numImages;
+ mShaderConstantsDirty.set(shaderType, false);
+
+ const uint8_t *data = nullptr;
+ switch (shaderType)
+ {
+ case gl::ShaderType::Vertex:
+ data = reinterpret_cast<const uint8_t *>(&mVertex);
+ break;
+ case gl::ShaderType::Fragment:
+ data = reinterpret_cast<const uint8_t *>(&mPixel);
+ break;
+ case gl::ShaderType::Compute:
+ data = reinterpret_cast<const uint8_t *>(&mCompute);
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ ASSERT(driverConstantBuffer.valid());
+
+ if (!dirty)
+ {
+ return angle::Result::Continue;
+ }
+
+ // Previous buffer contents are discarded, so we need to refresh the whole buffer.
+ D3D11_MAPPED_SUBRESOURCE mapping = {};
+ ANGLE_TRY(renderer->mapResource(context, driverConstantBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD,
+ 0, &mapping));
+
+ memcpy(mapping.pData, data, dataSize);
+ memcpy(static_cast<uint8_t *>(mapping.pData) + dataSize, samplerData,
+ sizeof(SamplerMetadata) * numSamplers);
+
+ memcpy(static_cast<uint8_t *>(mapping.pData) + dataSize + samplerDataSize, readonlyImageData,
+ readonlyImageDataSize);
+ memcpy(
+ static_cast<uint8_t *>(mapping.pData) + dataSize + samplerDataSize + readonlyImageDataSize,
+ imageData, imageDataSize);
+ renderer->getDeviceContext()->Unmap(driverConstantBuffer.get(), 0);
+
+ return angle::Result::Continue;
+}
+
+StateManager11::StateManager11(Renderer11 *renderer)
+ : mRenderer(renderer),
+ mInternalDirtyBits(),
+ mCurSampleAlphaToCoverage(false),
+ mCurBlendStateExt(),
+ mCurBlendColor(0, 0, 0, 0),
+ mCurSampleMask(0),
+ mCurStencilRef(0),
+ mCurStencilBackRef(0),
+ mCurStencilSize(0),
+ mCurScissorEnabled(false),
+ mCurScissorRect(),
+ mCurViewport(),
+ mCurNear(0.0f),
+ mCurFar(0.0f),
+ mViewportBounds(),
+ mRenderTargetIsDirty(true),
+ mCurPresentPathFastEnabled(false),
+ mCurPresentPathFastColorBufferHeight(0),
+ mDirtyCurrentValueAttribs(),
+ mCurrentValueAttribs(),
+ mCurrentInputLayout(),
+ mDirtyVertexBufferRange(gl::MAX_VERTEX_ATTRIBS, 0),
+ mCurrentPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_UNDEFINED),
+ mLastAppliedDrawMode(gl::PrimitiveMode::InvalidEnum),
+ mCullEverything(false),
+ mDirtySwizzles(false),
+ mAppliedIB(nullptr),
+ mAppliedIBFormat(DXGI_FORMAT_UNKNOWN),
+ mAppliedIBOffset(0),
+ mIndexBufferIsDirty(false),
+ mVertexDataManager(renderer),
+ mIndexDataManager(renderer),
+ mIsMultiviewEnabled(false),
+ mIndependentBlendStates(false),
+ mEmptySerial(mRenderer->generateSerial()),
+ mProgramD3D(nullptr),
+ mVertexArray11(nullptr),
+ mFramebuffer11(nullptr)
+{
+ mCurDepthStencilState.depthTest = false;
+ mCurDepthStencilState.depthFunc = GL_LESS;
+ mCurDepthStencilState.depthMask = true;
+ mCurDepthStencilState.stencilTest = false;
+ mCurDepthStencilState.stencilMask = true;
+ mCurDepthStencilState.stencilFail = GL_KEEP;
+ mCurDepthStencilState.stencilPassDepthFail = GL_KEEP;
+ mCurDepthStencilState.stencilPassDepthPass = GL_KEEP;
+ mCurDepthStencilState.stencilWritemask = static_cast<GLuint>(-1);
+ mCurDepthStencilState.stencilBackFunc = GL_ALWAYS;
+ mCurDepthStencilState.stencilBackMask = static_cast<GLuint>(-1);
+ mCurDepthStencilState.stencilBackFail = GL_KEEP;
+ mCurDepthStencilState.stencilBackPassDepthFail = GL_KEEP;
+ mCurDepthStencilState.stencilBackPassDepthPass = GL_KEEP;
+ mCurDepthStencilState.stencilBackWritemask = static_cast<GLuint>(-1);
+
+ mCurRasterState.rasterizerDiscard = false;
+ mCurRasterState.cullFace = false;
+ mCurRasterState.cullMode = gl::CullFaceMode::Back;
+ mCurRasterState.frontFace = GL_CCW;
+ mCurRasterState.polygonOffsetFill = false;
+ mCurRasterState.polygonOffsetFactor = 0.0f;
+ mCurRasterState.polygonOffsetUnits = 0.0f;
+ mCurRasterState.pointDrawMode = false;
+ mCurRasterState.multiSample = false;
+ mCurRasterState.dither = false;
+
+ // Start with all internal dirty bits set except the SRV and UAV bits.
+ mInternalDirtyBits.set();
+ mInternalDirtyBits.reset(DIRTY_BIT_GRAPHICS_SRV_STATE);
+ mInternalDirtyBits.reset(DIRTY_BIT_GRAPHICS_UAV_STATE);
+ mInternalDirtyBits.reset(DIRTY_BIT_COMPUTE_SRV_STATE);
+ mInternalDirtyBits.reset(DIRTY_BIT_COMPUTE_UAV_STATE);
+
+ mGraphicsDirtyBitsMask.set();
+ mGraphicsDirtyBitsMask.reset(DIRTY_BIT_COMPUTE_SRV_STATE);
+ mGraphicsDirtyBitsMask.reset(DIRTY_BIT_COMPUTE_UAV_STATE);
+ mComputeDirtyBitsMask.set(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE);
+ mComputeDirtyBitsMask.set(DIRTY_BIT_PROGRAM_UNIFORMS);
+ mComputeDirtyBitsMask.set(DIRTY_BIT_DRIVER_UNIFORMS);
+ mComputeDirtyBitsMask.set(DIRTY_BIT_PROGRAM_UNIFORM_BUFFERS);
+ mComputeDirtyBitsMask.set(DIRTY_BIT_SHADERS);
+ mComputeDirtyBitsMask.set(DIRTY_BIT_COMPUTE_SRV_STATE);
+ mComputeDirtyBitsMask.set(DIRTY_BIT_COMPUTE_UAV_STATE);
+
+ // Initially all current value attributes must be updated on first use.
+ mDirtyCurrentValueAttribs.set();
+
+ mCurrentVertexBuffers.fill(nullptr);
+ mCurrentVertexStrides.fill(std::numeric_limits<UINT>::max());
+ mCurrentVertexOffsets.fill(std::numeric_limits<UINT>::max());
+}
+
+StateManager11::~StateManager11() {}
+
+template <typename SRVType>
+void StateManager11::setShaderResourceInternal(gl::ShaderType shaderType,
+ UINT resourceSlot,
+ const SRVType *srv)
+{
+ auto *currentSRVs = getSRVCache(shaderType);
+ ASSERT(static_cast<size_t>(resourceSlot) < currentSRVs->size());
+ const ViewRecord<D3D11_SHADER_RESOURCE_VIEW_DESC> &record = (*currentSRVs)[resourceSlot];
+
+ if (record.view != reinterpret_cast<uintptr_t>(srv))
+ {
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+ ID3D11ShaderResourceView *srvPtr = srv ? srv->get() : nullptr;
+ if (srvPtr)
+ {
+ uintptr_t resource = reinterpret_cast<uintptr_t>(GetViewResource(srvPtr));
+ unsetConflictingUAVs(gl::PipelineType::GraphicsPipeline, gl::ShaderType::Compute,
+ resource, nullptr);
+ }
+
+ switch (shaderType)
+ {
+ case gl::ShaderType::Vertex:
+ deviceContext->VSSetShaderResources(resourceSlot, 1, &srvPtr);
+ break;
+ case gl::ShaderType::Fragment:
+ deviceContext->PSSetShaderResources(resourceSlot, 1, &srvPtr);
+ break;
+ case gl::ShaderType::Compute:
+ {
+ if (srvPtr)
+ {
+ uintptr_t resource = reinterpret_cast<uintptr_t>(GetViewResource(srvPtr));
+ unsetConflictingRTVs(resource);
+ }
+ deviceContext->CSSetShaderResources(resourceSlot, 1, &srvPtr);
+ break;
+ }
+ default:
+ UNREACHABLE();
+ }
+
+ currentSRVs->update(resourceSlot, srvPtr);
+ }
+}
+
+template <typename UAVType>
+void StateManager11::setUnorderedAccessViewInternal(UINT resourceSlot,
+ const UAVType *uav,
+ UAVList *uavList)
+{
+ ASSERT(static_cast<size_t>(resourceSlot) < mCurComputeUAVs.size());
+ const ViewRecord<D3D11_UNORDERED_ACCESS_VIEW_DESC> &record = mCurComputeUAVs[resourceSlot];
+
+ if (record.view != reinterpret_cast<uintptr_t>(uav))
+ {
+ ID3D11UnorderedAccessView *uavPtr = uav ? uav->get() : nullptr;
+ // We need to make sure that resource being set to UnorderedAccessView slot |resourceSlot|
+ // is not bound on SRV.
+ if (uavPtr)
+ {
+ uintptr_t resource = reinterpret_cast<uintptr_t>(GetViewResource(uavPtr));
+ unsetConflictingSRVs(gl::PipelineType::ComputePipeline, gl::ShaderType::Vertex,
+ resource, nullptr, false);
+ unsetConflictingSRVs(gl::PipelineType::ComputePipeline, gl::ShaderType::Fragment,
+ resource, nullptr, false);
+ unsetConflictingSRVs(gl::PipelineType::ComputePipeline, gl::ShaderType::Compute,
+ resource, nullptr, false);
+ }
+ uavList->data[resourceSlot] = uavPtr;
+ if (static_cast<int>(resourceSlot) > uavList->highestUsed)
+ {
+ uavList->highestUsed = resourceSlot;
+ }
+
+ mCurComputeUAVs.update(resourceSlot, uavPtr);
+ }
+}
+
+void StateManager11::updateStencilSizeIfChanged(bool depthStencilInitialized,
+ unsigned int stencilSize)
+{
+ if (!depthStencilInitialized || stencilSize != mCurStencilSize)
+ {
+ mCurStencilSize = stencilSize;
+ mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
+ }
+}
+
+void StateManager11::checkPresentPath(const gl::Context *context)
+{
+ const auto *framebuffer = context->getState().getDrawFramebuffer();
+ const auto *firstColorAttachment = framebuffer->getFirstColorAttachment();
+ const bool clipSpaceOriginUpperLeft =
+ context->getState().getClipSpaceOrigin() == gl::ClipSpaceOrigin::UpperLeft;
+ const bool presentPathFastActive =
+ UsePresentPathFast(mRenderer, firstColorAttachment) || clipSpaceOriginUpperLeft;
+
+ const int colorBufferHeight = firstColorAttachment ? firstColorAttachment->getSize().height : 0;
+
+ if ((mCurPresentPathFastEnabled != presentPathFastActive) ||
+ (presentPathFastActive && (colorBufferHeight != mCurPresentPathFastColorBufferHeight)))
+ {
+ mCurPresentPathFastEnabled = presentPathFastActive;
+ mCurPresentPathFastColorBufferHeight = colorBufferHeight;
+
+ // Scissor rect may need to be vertically inverted
+ mInternalDirtyBits.set(DIRTY_BIT_SCISSOR_STATE);
+
+ // Cull Mode may need to be inverted
+ mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
+
+ // Viewport may need to be vertically inverted
+ invalidateViewport(context);
+ }
+}
+
+angle::Result StateManager11::updateStateForCompute(const gl::Context *context,
+ GLuint numGroupsX,
+ GLuint numGroupsY,
+ GLuint numGroupsZ)
+{
+ mShaderConstants.setComputeWorkGroups(numGroupsX, numGroupsY, numGroupsZ);
+
+ if (mProgramD3D->updateSamplerMapping() == ProgramD3D::SamplerMapping::WasDirty)
+ {
+ invalidateTexturesAndSamplers();
+ }
+
+ if (mDirtySwizzles)
+ {
+ ANGLE_TRY(generateSwizzlesForShader(context, gl::ShaderType::Compute));
+ mDirtySwizzles = false;
+ }
+
+ if (mProgramD3D->anyShaderUniformsDirty())
+ {
+ mInternalDirtyBits.set(DIRTY_BIT_PROGRAM_UNIFORMS);
+ }
+
+ auto dirtyBitsCopy = mInternalDirtyBits & mComputeDirtyBitsMask;
+ mInternalDirtyBits &= ~mComputeDirtyBitsMask;
+
+ for (auto iter = dirtyBitsCopy.begin(), end = dirtyBitsCopy.end(); iter != end; ++iter)
+ {
+ switch (*iter)
+ {
+ case DIRTY_BIT_COMPUTE_SRV_STATE:
+ // Avoid to call syncTexturesForCompute function two times.
+ iter.resetLaterBit(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE);
+ ANGLE_TRY(syncTexturesForCompute(context));
+ break;
+ case DIRTY_BIT_COMPUTE_UAV_STATE:
+ ANGLE_TRY(syncUAVsForCompute(context));
+ break;
+ case DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE:
+ ANGLE_TRY(syncTexturesForCompute(context));
+ break;
+ case DIRTY_BIT_PROGRAM_UNIFORMS:
+ case DIRTY_BIT_DRIVER_UNIFORMS:
+ ANGLE_TRY(applyComputeUniforms(context, mProgramD3D));
+ break;
+ case DIRTY_BIT_PROGRAM_UNIFORM_BUFFERS:
+ ANGLE_TRY(syncUniformBuffers(context));
+ break;
+ case DIRTY_BIT_SHADERS:
+ ANGLE_TRY(syncProgramForCompute(context));
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ }
+
+ return angle::Result::Continue;
+}
+
+void StateManager11::syncState(const gl::Context *context,
+ const gl::State::DirtyBits &dirtyBits,
+ gl::Command command)
+{
+ if (!dirtyBits.any())
+ {
+ return;
+ }
+
+ const gl::State &state = context->getState();
+
+ for (size_t dirtyBit : dirtyBits)
+ {
+ switch (dirtyBit)
+ {
+ case gl::State::DIRTY_BIT_BLEND_EQUATIONS:
+ {
+ const gl::BlendStateExt &blendStateExt = state.getBlendStateExt();
+ ASSERT(mCurBlendStateExt.getDrawBufferCount() ==
+ blendStateExt.getDrawBufferCount());
+ // Compare blend equations only for buffers with blending enabled because
+ // subsequent sync stages enforce default values for buffers with blending disabled.
+ if ((blendStateExt.getEnabledMask() &
+ mCurBlendStateExt.compareEquations(blendStateExt))
+ .any())
+ {
+ mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
+ }
+ break;
+ }
+ case gl::State::DIRTY_BIT_BLEND_FUNCS:
+ {
+ const gl::BlendStateExt &blendStateExt = state.getBlendStateExt();
+ ASSERT(mCurBlendStateExt.getDrawBufferCount() ==
+ blendStateExt.getDrawBufferCount());
+ // Compare blend factors only for buffers with blending enabled because
+ // subsequent sync stages enforce default values for buffers with blending disabled.
+ if ((blendStateExt.getEnabledMask() &
+ mCurBlendStateExt.compareFactors(blendStateExt))
+ .any())
+ {
+ mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
+ }
+ break;
+ }
+ case gl::State::DIRTY_BIT_BLEND_ENABLED:
+ {
+ if (state.getBlendStateExt().getEnabledMask() != mCurBlendStateExt.getEnabledMask())
+ {
+ mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
+ }
+ break;
+ }
+ case gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED:
+ if (state.isSampleAlphaToCoverageEnabled() != mCurSampleAlphaToCoverage)
+ {
+ mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
+ }
+ break;
+ case gl::State::DIRTY_BIT_DITHER_ENABLED:
+ if (state.getRasterizerState().dither != mCurRasterState.dither)
+ {
+ mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
+ }
+ break;
+ case gl::State::DIRTY_BIT_COLOR_MASK:
+ {
+ if (state.getBlendStateExt().getColorMaskBits() !=
+ mCurBlendStateExt.getColorMaskBits())
+ {
+ mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
+ }
+ break;
+ }
+ case gl::State::DIRTY_BIT_BLEND_COLOR:
+ if (state.getBlendColor() != mCurBlendColor)
+ {
+ mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
+ }
+ break;
+ // Depth and stencil redundant state changes are guarded in the
+ // frontend so for related cases here just set the dirty bit.
+ case gl::State::DIRTY_BIT_DEPTH_MASK:
+ mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
+ break;
+ case gl::State::DIRTY_BIT_DEPTH_TEST_ENABLED:
+ mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
+ break;
+ case gl::State::DIRTY_BIT_DEPTH_FUNC:
+ mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
+ break;
+ case gl::State::DIRTY_BIT_STENCIL_TEST_ENABLED:
+ mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
+ break;
+ case gl::State::DIRTY_BIT_STENCIL_FUNCS_FRONT:
+ mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
+ break;
+ case gl::State::DIRTY_BIT_STENCIL_FUNCS_BACK:
+ mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
+ break;
+ case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT:
+ mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
+ break;
+ case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_BACK:
+ mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
+ break;
+ case gl::State::DIRTY_BIT_STENCIL_OPS_FRONT:
+ mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
+ break;
+ case gl::State::DIRTY_BIT_STENCIL_OPS_BACK:
+ mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
+ break;
+
+ case gl::State::DIRTY_BIT_CULL_FACE_ENABLED:
+ if (state.getRasterizerState().cullFace != mCurRasterState.cullFace)
+ {
+ mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
+ mInternalDirtyBits.set(DIRTY_BIT_PRIMITIVE_TOPOLOGY);
+ }
+ break;
+ case gl::State::DIRTY_BIT_CULL_FACE:
+ if (state.getRasterizerState().cullMode != mCurRasterState.cullMode)
+ {
+ mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
+ mInternalDirtyBits.set(DIRTY_BIT_PRIMITIVE_TOPOLOGY);
+ }
+ break;
+ case gl::State::DIRTY_BIT_FRONT_FACE:
+ if (state.getRasterizerState().frontFace != mCurRasterState.frontFace)
+ {
+ mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
+ mInternalDirtyBits.set(DIRTY_BIT_PRIMITIVE_TOPOLOGY);
+ }
+ break;
+ case gl::State::DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED:
+ if (state.getRasterizerState().polygonOffsetFill !=
+ mCurRasterState.polygonOffsetFill)
+ {
+ mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
+ }
+ break;
+ case gl::State::DIRTY_BIT_POLYGON_OFFSET:
+ {
+ const gl::RasterizerState &rasterState = state.getRasterizerState();
+ if (rasterState.polygonOffsetFactor != mCurRasterState.polygonOffsetFactor ||
+ rasterState.polygonOffsetUnits != mCurRasterState.polygonOffsetUnits)
+ {
+ mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
+ }
+ break;
+ }
+ case gl::State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED:
+ if (state.getRasterizerState().rasterizerDiscard !=
+ mCurRasterState.rasterizerDiscard)
+ {
+ mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
+
+ // Enabling/disabling rasterizer discard affects the pixel shader.
+ invalidateShaders();
+ }
+ break;
+ case gl::State::DIRTY_BIT_SCISSOR:
+ if (state.getScissor() != mCurScissorRect)
+ {
+ mInternalDirtyBits.set(DIRTY_BIT_SCISSOR_STATE);
+ }
+ break;
+ case gl::State::DIRTY_BIT_SCISSOR_TEST_ENABLED:
+ if (state.isScissorTestEnabled() != mCurScissorEnabled)
+ {
+ mInternalDirtyBits.set(DIRTY_BIT_SCISSOR_STATE);
+ // Rasterizer state update needs mCurScissorsEnabled and updates when it changes
+ mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
+ }
+ break;
+ case gl::State::DIRTY_BIT_DEPTH_RANGE:
+ invalidateViewport(context);
+ break;
+ case gl::State::DIRTY_BIT_VIEWPORT:
+ if (state.getViewport() != mCurViewport)
+ {
+ invalidateViewport(context);
+ }
+ break;
+ case gl::State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING:
+ invalidateRenderTarget();
+ if (mIsMultiviewEnabled)
+ {
+ handleMultiviewDrawFramebufferChange(context);
+ }
+ mFramebuffer11 = GetImplAs<Framebuffer11>(state.getDrawFramebuffer());
+ break;
+ case gl::State::DIRTY_BIT_VERTEX_ARRAY_BINDING:
+ invalidateVertexBuffer();
+ // Force invalidate the current value attributes, since the VertexArray11 keeps an
+ // internal cache of TranslatedAttributes, and they CurrentValue attributes are
+ // owned by the StateManager11/Context.
+ mDirtyCurrentValueAttribs.set();
+ // Invalidate the cached index buffer.
+ invalidateIndexBuffer();
+ mVertexArray11 = GetImplAs<VertexArray11>(state.getVertexArray());
+ break;
+ case gl::State::DIRTY_BIT_UNIFORM_BUFFER_BINDINGS:
+ invalidateProgramUniformBuffers();
+ break;
+ case gl::State::DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING:
+ invalidateProgramAtomicCounterBuffers();
+ break;
+ case gl::State::DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING:
+ invalidateProgramShaderStorageBuffers();
+ break;
+ case gl::State::DIRTY_BIT_TEXTURE_BINDINGS:
+ invalidateTexturesAndSamplers();
+ break;
+ case gl::State::DIRTY_BIT_SAMPLER_BINDINGS:
+ invalidateTexturesAndSamplers();
+ break;
+ case gl::State::DIRTY_BIT_IMAGE_BINDINGS:
+ invalidateImageBindings();
+ break;
+ case gl::State::DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING:
+ invalidateTransformFeedback();
+ break;
+ case gl::State::DIRTY_BIT_PROGRAM_BINDING:
+ mProgramD3D = GetImplAs<ProgramD3D>(state.getProgram());
+ break;
+ case gl::State::DIRTY_BIT_PROGRAM_EXECUTABLE:
+ {
+ invalidateShaders();
+ invalidateTexturesAndSamplers();
+ invalidateProgramUniforms();
+ invalidateProgramUniformBuffers();
+ invalidateProgramAtomicCounterBuffers();
+ invalidateProgramShaderStorageBuffers();
+ invalidateDriverUniforms();
+ const gl::ProgramExecutable *executable = state.getProgramExecutable();
+ if (!executable || command != gl::Command::Dispatch)
+ {
+ mInternalDirtyBits.set(DIRTY_BIT_PRIMITIVE_TOPOLOGY);
+ invalidateVertexBuffer();
+ invalidateRenderTarget();
+ // If OVR_multiview2 is enabled, the attribute divisor has to be updated for
+ // each binding. When using compute, there could be no vertex array.
+ if (mIsMultiviewEnabled && mVertexArray11)
+ {
+ ASSERT(mProgramD3D);
+ ASSERT(mVertexArray11 == GetImplAs<VertexArray11>(state.getVertexArray()));
+ const gl::ProgramState &programState = mProgramD3D->getState();
+ int numViews =
+ programState.usesMultiview() ? programState.getNumViews() : 1;
+ mVertexArray11->markAllAttributeDivisorsForAdjustment(numViews);
+ }
+ }
+ break;
+ }
+ case gl::State::DIRTY_BIT_CURRENT_VALUES:
+ {
+ for (auto attribIndex : state.getAndResetDirtyCurrentValues())
+ {
+ invalidateCurrentValueAttrib(attribIndex);
+ }
+ break;
+ }
+ case gl::State::DIRTY_BIT_PROVOKING_VERTEX:
+ invalidateShaders();
+ break;
+ case gl::State::DIRTY_BIT_EXTENDED:
+ {
+ gl::State::ExtendedDirtyBits extendedDirtyBits =
+ state.getAndResetExtendedDirtyBits();
+
+ for (size_t extendedDirtyBit : extendedDirtyBits)
+ {
+ switch (extendedDirtyBit)
+ {
+ case gl::State::EXTENDED_DIRTY_BIT_CLIP_CONTROL:
+ checkPresentPath(context);
+ break;
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ // TODO(jmadill): Input layout and vertex buffer state.
+}
+
+void StateManager11::handleMultiviewDrawFramebufferChange(const gl::Context *context)
+{
+ const auto &glState = context->getState();
+ const gl::Framebuffer *drawFramebuffer = glState.getDrawFramebuffer();
+ ASSERT(drawFramebuffer != nullptr);
+
+ if (drawFramebuffer->isMultiview())
+ {
+ // Because the base view index is applied as an offset to the 2D texture array when the
+ // RTV is created, we just have to pass a boolean to select which code path is to be
+ // used.
+ mShaderConstants.setMultiviewWriteToViewportIndex(0.0f);
+ }
+}
+
+angle::Result StateManager11::syncBlendState(const gl::Context *context,
+ const gl::BlendStateExt &blendStateExt,
+ const gl::ColorF &blendColor,
+ unsigned int sampleMask,
+ bool sampleAlphaToCoverage,
+ bool emulateConstantAlpha)
+{
+ const d3d11::BlendState *dxBlendState = nullptr;
+ const d3d11::BlendStateKey &key = RenderStateCache::GetBlendStateKey(
+ context, mFramebuffer11, blendStateExt, sampleAlphaToCoverage);
+
+ ANGLE_TRY(mRenderer->getBlendState(context, key, &dxBlendState));
+
+ ASSERT(dxBlendState != nullptr);
+
+ // D3D11 does not support CONSTANT_ALPHA as source or destination color factor, so ANGLE sets
+ // the factor to CONSTANT_COLOR and swizzles the color value to aaaa. For this reason, it's
+ // impossible to simultaneously use CONSTANT_ALPHA and CONSTANT_COLOR as source or destination
+ // color factors in the same blend state. This is enforced in the validation layer.
+ float blendColors[4] = {0.0f};
+ blendColors[0] = emulateConstantAlpha ? blendColor.alpha : blendColor.red;
+ blendColors[1] = emulateConstantAlpha ? blendColor.alpha : blendColor.green;
+ blendColors[2] = emulateConstantAlpha ? blendColor.alpha : blendColor.blue;
+ blendColors[3] = blendColor.alpha;
+
+ mRenderer->getDeviceContext()->OMSetBlendState(dxBlendState->get(), blendColors, sampleMask);
+
+ mCurBlendStateExt = blendStateExt;
+ mCurBlendColor = blendColor;
+ mCurSampleMask = sampleMask;
+ mCurSampleAlphaToCoverage = sampleAlphaToCoverage;
+
+ return angle::Result::Continue;
+}
+
+angle::Result StateManager11::syncDepthStencilState(const gl::Context *context)
+{
+ const gl::State &glState = context->getState();
+
+ mCurDepthStencilState = glState.getDepthStencilState();
+ mCurStencilRef = glState.getStencilRef();
+ mCurStencilBackRef = glState.getStencilBackRef();
+
+ // get the maximum size of the stencil ref
+ unsigned int maxStencil = 0;
+ if (mCurDepthStencilState.stencilTest && mCurStencilSize > 0)
+ {
+ maxStencil = (1 << mCurStencilSize) - 1;
+ }
+ ASSERT((mCurDepthStencilState.stencilWritemask & maxStencil) ==
+ (mCurDepthStencilState.stencilBackWritemask & maxStencil));
+ ASSERT(gl::clamp(mCurStencilRef, 0, static_cast<int>(maxStencil)) ==
+ gl::clamp(mCurStencilBackRef, 0, static_cast<int>(maxStencil)));
+ ASSERT((mCurDepthStencilState.stencilMask & maxStencil) ==
+ (mCurDepthStencilState.stencilBackMask & maxStencil));
+
+ gl::DepthStencilState modifiedGLState = glState.getDepthStencilState();
+
+ ASSERT(mCurDisableDepth.valid() && mCurDisableStencil.valid());
+
+ if (mCurDisableDepth.value())
+ {
+ modifiedGLState.depthTest = false;
+ modifiedGLState.depthMask = false;
+ }
+
+ if (mCurDisableStencil.value())
+ {
+ modifiedGLState.stencilTest = false;
+ }
+ if (!modifiedGLState.stencilTest)
+ {
+ modifiedGLState.stencilWritemask = 0;
+ modifiedGLState.stencilBackWritemask = 0;
+ }
+
+ // If STENCIL_TEST is disabled in glState, stencil testing and writing should be disabled.
+ // Verify that's true in the modifiedGLState so it is propagated to d3dState.
+ ASSERT(glState.getDepthStencilState().stencilTest ||
+ (!modifiedGLState.stencilTest && modifiedGLState.stencilWritemask == 0 &&
+ modifiedGLState.stencilBackWritemask == 0));
+
+ const d3d11::DepthStencilState *d3dState = nullptr;
+ ANGLE_TRY(mRenderer->getDepthStencilState(context, modifiedGLState, &d3dState));
+ ASSERT(d3dState);
+
+ // Max D3D11 stencil reference value is 0xFF,
+ // corresponding to the max 8 bits in a stencil buffer
+ // GL specifies we should clamp the ref value to the
+ // nearest bit depth when doing stencil ops
+ static_assert(D3D11_DEFAULT_STENCIL_READ_MASK == 0xFF,
+ "Unexpected value of D3D11_DEFAULT_STENCIL_READ_MASK");
+ static_assert(D3D11_DEFAULT_STENCIL_WRITE_MASK == 0xFF,
+ "Unexpected value of D3D11_DEFAULT_STENCIL_WRITE_MASK");
+ UINT dxStencilRef = static_cast<UINT>(gl::clamp(mCurStencilRef, 0, 0xFF));
+
+ mRenderer->getDeviceContext()->OMSetDepthStencilState(d3dState->get(), dxStencilRef);
+
+ return angle::Result::Continue;
+}
+
+angle::Result StateManager11::syncRasterizerState(const gl::Context *context,
+ gl::PrimitiveMode mode)
+{
+ // TODO: Remove pointDrawMode and multiSample from gl::RasterizerState.
+ gl::RasterizerState rasterState = context->getState().getRasterizerState();
+ rasterState.pointDrawMode = (mode == gl::PrimitiveMode::Points);
+ rasterState.multiSample = mCurRasterState.multiSample;
+
+ ID3D11RasterizerState *dxRasterState = nullptr;
+
+ if (mCurPresentPathFastEnabled)
+ {
+ gl::RasterizerState modifiedRasterState = rasterState;
+
+ // If prseent path fast is active then we need invert the front face state.
+ // This ensures that both gl_FrontFacing is correct, and front/back culling
+ // is performed correctly.
+ if (modifiedRasterState.frontFace == GL_CCW)
+ {
+ modifiedRasterState.frontFace = GL_CW;
+ }
+ else
+ {
+ ASSERT(modifiedRasterState.frontFace == GL_CW);
+ modifiedRasterState.frontFace = GL_CCW;
+ }
+
+ ANGLE_TRY(mRenderer->getRasterizerState(context, modifiedRasterState, mCurScissorEnabled,
+ &dxRasterState));
+ }
+ else
+ {
+ ANGLE_TRY(mRenderer->getRasterizerState(context, rasterState, mCurScissorEnabled,
+ &dxRasterState));
+ }
+
+ mRenderer->getDeviceContext()->RSSetState(dxRasterState);
+
+ mCurRasterState = rasterState;
+
+ return angle::Result::Continue;
+}
+
+void StateManager11::syncScissorRectangle(const gl::Context *context)
+{
+ const auto &glState = context->getState();
+ gl::Framebuffer *framebuffer = glState.getDrawFramebuffer();
+ const gl::Rectangle &scissor = glState.getScissor();
+ const bool enabled = glState.isScissorTestEnabled();
+
+ mCurScissorOffset = framebuffer->getSurfaceTextureOffset();
+
+ int scissorX = scissor.x + mCurScissorOffset.x;
+ int scissorY = scissor.y + mCurScissorOffset.y;
+
+ if (mCurPresentPathFastEnabled)
+ {
+ scissorY = mCurPresentPathFastColorBufferHeight - scissor.height - scissor.y;
+ }
+
+ if (enabled)
+ {
+ D3D11_RECT rect;
+ int x = scissorX;
+ int y = scissorY;
+ rect.left = std::max(0, x);
+ rect.top = std::max(0, y);
+ rect.right = x + std::max(0, scissor.width);
+ rect.bottom = y + std::max(0, scissor.height);
+ mRenderer->getDeviceContext()->RSSetScissorRects(1, &rect);
+ }
+
+ mCurScissorRect = scissor;
+ mCurScissorEnabled = enabled;
+}
+
+void StateManager11::syncViewport(const gl::Context *context)
+{
+ const auto &glState = context->getState();
+ gl::Framebuffer *framebuffer = glState.getDrawFramebuffer();
+ float actualZNear = gl::clamp01(glState.getNearPlane());
+ float actualZFar = gl::clamp01(glState.getFarPlane());
+
+ const auto &caps = context->getCaps();
+ int dxMaxViewportBoundsX = caps.maxViewportWidth;
+ int dxMaxViewportBoundsY = caps.maxViewportHeight;
+ int dxMinViewportBoundsX = -dxMaxViewportBoundsX;
+ int dxMinViewportBoundsY = -dxMaxViewportBoundsY;
+
+ bool is9_3 = mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3;
+
+ if (is9_3)
+ {
+ // Feature Level 9 viewports shouldn't exceed the dimensions of the rendertarget.
+ dxMaxViewportBoundsX = static_cast<int>(mViewportBounds.width);
+ dxMaxViewportBoundsY = static_cast<int>(mViewportBounds.height);
+ dxMinViewportBoundsX = 0;
+ dxMinViewportBoundsY = 0;
+ }
+
+ bool clipSpaceOriginLowerLeft = glState.getClipSpaceOrigin() == gl::ClipSpaceOrigin::LowerLeft;
+ mShaderConstants.onClipControlChange(clipSpaceOriginLowerLeft,
+ glState.isClipControlDepthZeroToOne());
+
+ const auto &viewport = glState.getViewport();
+
+ int dxViewportTopLeftX = 0;
+ int dxViewportTopLeftY = 0;
+ int dxViewportWidth = 0;
+ int dxViewportHeight = 0;
+
+ mCurViewportOffset = framebuffer->getSurfaceTextureOffset();
+
+ dxViewportTopLeftX =
+ gl::clamp(viewport.x + mCurViewportOffset.x, dxMinViewportBoundsX, dxMaxViewportBoundsX);
+ dxViewportTopLeftY =
+ gl::clamp(viewport.y + mCurViewportOffset.y, dxMinViewportBoundsY, dxMaxViewportBoundsY);
+ dxViewportWidth = gl::clamp(viewport.width, 0, dxMaxViewportBoundsX - dxViewportTopLeftX);
+ dxViewportHeight = gl::clamp(viewport.height, 0, dxMaxViewportBoundsY - dxViewportTopLeftY);
+
+ D3D11_VIEWPORT dxViewport;
+ dxViewport.TopLeftX = static_cast<float>(dxViewportTopLeftX);
+ if (mCurPresentPathFastEnabled && clipSpaceOriginLowerLeft)
+ {
+ // When present path fast is active and we're rendering to framebuffer 0, we must invert
+ // the viewport in Y-axis.
+ // NOTE: We delay the inversion until right before the call to RSSetViewports, and leave
+ // dxViewportTopLeftY unchanged. This allows us to calculate viewAdjust below using the
+ // unaltered dxViewportTopLeftY value.
+ dxViewport.TopLeftY = static_cast<float>(mCurPresentPathFastColorBufferHeight -
+ dxViewportTopLeftY - dxViewportHeight);
+ }
+ else
+ {
+ dxViewport.TopLeftY = static_cast<float>(dxViewportTopLeftY);
+ }
+
+ // The es 3.1 spec section 9.2 states that, "If there are no attachments, rendering
+ // will be limited to a rectangle having a lower left of (0, 0) and an upper right of
+ // (width, height), where width and height are the framebuffer object's default width
+ // and height." See http://anglebug.com/1594
+ // If the Framebuffer has no color attachment and the default width or height is smaller
+ // than the current viewport, use the smaller of the two sizes.
+ // If framebuffer default width or height is 0, the params should not set.
+ if (!framebuffer->getFirstNonNullAttachment() &&
+ (framebuffer->getDefaultWidth() || framebuffer->getDefaultHeight()))
+ {
+ dxViewport.Width =
+ static_cast<GLfloat>(std::min(viewport.width, framebuffer->getDefaultWidth()));
+ dxViewport.Height =
+ static_cast<GLfloat>(std::min(viewport.height, framebuffer->getDefaultHeight()));
+ }
+ else
+ {
+ dxViewport.Width = static_cast<float>(dxViewportWidth);
+ dxViewport.Height = static_cast<float>(dxViewportHeight);
+ }
+ dxViewport.MinDepth = actualZNear;
+ dxViewport.MaxDepth = actualZFar;
+
+ mRenderer->getDeviceContext()->RSSetViewports(1, &dxViewport);
+
+ mCurViewport = viewport;
+ mCurNear = actualZNear;
+ mCurFar = actualZFar;
+
+ const D3D11_VIEWPORT adjustViewport = {static_cast<FLOAT>(dxViewportTopLeftX),
+ static_cast<FLOAT>(dxViewportTopLeftY),
+ static_cast<FLOAT>(dxViewportWidth),
+ static_cast<FLOAT>(dxViewportHeight),
+ actualZNear,
+ actualZFar};
+ mShaderConstants.onViewportChange(viewport, adjustViewport, mCurViewportOffset, is9_3,
+ mCurPresentPathFastEnabled);
+}
+
+void StateManager11::invalidateRenderTarget()
+{
+ mRenderTargetIsDirty = true;
+}
+
+void StateManager11::processFramebufferInvalidation(const gl::Context *context)
+{
+ ASSERT(mRenderTargetIsDirty);
+ ASSERT(context);
+
+ mInternalDirtyBits.set(DIRTY_BIT_RENDER_TARGET);
+
+ // The pixel shader is dependent on the output layout.
+ invalidateShaders();
+
+ // The D3D11 blend state is heavily dependent on the current render target.
+ mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
+
+ gl::Framebuffer *fbo = context->getState().getDrawFramebuffer();
+ ASSERT(fbo);
+
+ // Dirty scissor and viewport because surface texture offset might have changed.
+ if (mCurViewportOffset != fbo->getSurfaceTextureOffset())
+ {
+ mInternalDirtyBits.set(DIRTY_BIT_VIEWPORT_STATE);
+ }
+ if (mCurScissorOffset != fbo->getSurfaceTextureOffset())
+ {
+ mInternalDirtyBits.set(DIRTY_BIT_SCISSOR_STATE);
+ }
+
+ // Disable the depth test/depth write if we are using a stencil-only attachment.
+ // This is because ANGLE emulates stencil-only with D24S8 on D3D11 - we should neither read
+ // nor write to the unused depth part of this emulated texture.
+ bool disableDepth = (!fbo->hasDepth() && fbo->hasStencil());
+
+ // Similarly we disable the stencil portion of the DS attachment if the app only binds depth.
+ bool disableStencil = (fbo->hasDepth() && !fbo->hasStencil());
+
+ if (!mCurDisableDepth.valid() || disableDepth != mCurDisableDepth.value() ||
+ !mCurDisableStencil.valid() || disableStencil != mCurDisableStencil.value())
+ {
+ mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
+ mCurDisableDepth = disableDepth;
+ mCurDisableStencil = disableStencil;
+ }
+
+ bool multiSample = (fbo->getSamples(context) != 0);
+ if (multiSample != mCurRasterState.multiSample)
+ {
+ mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
+ mCurRasterState.multiSample = multiSample;
+ }
+
+ checkPresentPath(context);
+
+ if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3)
+ {
+ const auto *firstAttachment = fbo->getFirstNonNullAttachment();
+ if (firstAttachment)
+ {
+ const auto &size = firstAttachment->getSize();
+ if (mViewportBounds.width != size.width || mViewportBounds.height != size.height)
+ {
+ mViewportBounds = gl::Extents(size.width, size.height, 1);
+ invalidateViewport(context);
+ }
+ }
+ }
+}
+
+void StateManager11::invalidateBoundViews()
+{
+ for (SRVCache &curShaderSRV : mCurShaderSRVs)
+ {
+ curShaderSRV.clear();
+ }
+
+ invalidateRenderTarget();
+}
+
+void StateManager11::invalidateVertexBuffer()
+{
+ unsigned int limit = std::min<unsigned int>(mRenderer->getNativeCaps().maxVertexAttributes,
+ gl::MAX_VERTEX_ATTRIBS);
+ mDirtyVertexBufferRange = gl::RangeUI(0, limit);
+ invalidateInputLayout();
+ invalidateShaders();
+ mInternalDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_ATTRIBS);
+}
+
+void StateManager11::invalidateViewport(const gl::Context *context)
+{
+ mInternalDirtyBits.set(DIRTY_BIT_VIEWPORT_STATE);
+
+ // Viewport affects the driver constants.
+ invalidateDriverUniforms();
+}
+
+void StateManager11::invalidateTexturesAndSamplers()
+{
+ mInternalDirtyBits.set(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE);
+ invalidateSwizzles();
+
+ // Texture state affects the driver uniforms (base level, etc).
+ invalidateDriverUniforms();
+}
+
+void StateManager11::invalidateSwizzles()
+{
+ mDirtySwizzles = true;
+}
+
+void StateManager11::invalidateProgramUniforms()
+{
+ mInternalDirtyBits.set(DIRTY_BIT_PROGRAM_UNIFORMS);
+}
+
+void StateManager11::invalidateDriverUniforms()
+{
+ mInternalDirtyBits.set(DIRTY_BIT_DRIVER_UNIFORMS);
+}
+
+void StateManager11::invalidateProgramUniformBuffers()
+{
+ mInternalDirtyBits.set(DIRTY_BIT_PROGRAM_UNIFORM_BUFFERS);
+}
+
+void StateManager11::invalidateProgramAtomicCounterBuffers()
+{
+ mInternalDirtyBits.set(DIRTY_BIT_GRAPHICS_UAV_STATE);
+ mInternalDirtyBits.set(DIRTY_BIT_COMPUTE_UAV_STATE);
+}
+
+void StateManager11::invalidateProgramShaderStorageBuffers()
+{
+ mInternalDirtyBits.set(DIRTY_BIT_GRAPHICS_UAV_STATE);
+ mInternalDirtyBits.set(DIRTY_BIT_COMPUTE_UAV_STATE);
+}
+
+void StateManager11::invalidateImageBindings()
+{
+ mInternalDirtyBits.set(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE);
+ mInternalDirtyBits.set(DIRTY_BIT_GRAPHICS_SRV_STATE);
+ mInternalDirtyBits.set(DIRTY_BIT_GRAPHICS_UAV_STATE);
+ mInternalDirtyBits.set(DIRTY_BIT_COMPUTE_SRV_STATE);
+ mInternalDirtyBits.set(DIRTY_BIT_COMPUTE_UAV_STATE);
+}
+
+void StateManager11::invalidateConstantBuffer(unsigned int slot)
+{
+ if (slot == d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DRIVER)
+ {
+ invalidateDriverUniforms();
+ }
+ else if (slot == d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DEFAULT_UNIFORM_BLOCK)
+ {
+ invalidateProgramUniforms();
+ }
+ else
+ {
+ invalidateProgramUniformBuffers();
+ }
+}
+
+void StateManager11::invalidateShaders()
+{
+ mInternalDirtyBits.set(DIRTY_BIT_SHADERS);
+}
+
+void StateManager11::invalidateTransformFeedback()
+{
+ // Transform feedback affects the stream-out geometry shader.
+ invalidateShaders();
+ mInternalDirtyBits.set(DIRTY_BIT_TRANSFORM_FEEDBACK);
+ // syncPrimitiveTopology checks the transform feedback state.
+ mInternalDirtyBits.set(DIRTY_BIT_PRIMITIVE_TOPOLOGY);
+}
+
+void StateManager11::invalidateInputLayout()
+{
+ mInternalDirtyBits.set(DIRTY_BIT_VERTEX_BUFFERS_AND_INPUT_LAYOUT);
+}
+
+void StateManager11::invalidateIndexBuffer()
+{
+ mIndexBufferIsDirty = true;
+}
+
+void StateManager11::setRenderTarget(ID3D11RenderTargetView *rtv, ID3D11DepthStencilView *dsv)
+{
+ if (rtv)
+ {
+ unsetConflictingView(gl::PipelineType::GraphicsPipeline, rtv, true);
+ }
+
+ if (dsv)
+ {
+ unsetConflictingView(gl::PipelineType::GraphicsPipeline, dsv, true);
+ }
+
+ mRenderer->getDeviceContext()->OMSetRenderTargets(1, &rtv, dsv);
+ mCurRTVs.clear();
+ mCurRTVs.update(0, rtv);
+ mInternalDirtyBits.set(DIRTY_BIT_RENDER_TARGET);
+}
+
+void StateManager11::setRenderTargets(ID3D11RenderTargetView **rtvs,
+ UINT numRTVs,
+ ID3D11DepthStencilView *dsv)
+{
+ for (UINT rtvIndex = 0; rtvIndex < numRTVs; ++rtvIndex)
+ {
+ unsetConflictingView(gl::PipelineType::GraphicsPipeline, rtvs[rtvIndex], true);
+ }
+
+ if (dsv)
+ {
+ unsetConflictingView(gl::PipelineType::GraphicsPipeline, dsv, true);
+ }
+
+ mRenderer->getDeviceContext()->OMSetRenderTargets(numRTVs, (numRTVs > 0) ? rtvs : nullptr, dsv);
+ mCurRTVs.clear();
+ for (UINT i = 0; i < numRTVs; i++)
+ {
+ mCurRTVs.update(i, rtvs[i]);
+ }
+ mInternalDirtyBits.set(DIRTY_BIT_RENDER_TARGET);
+}
+
+void StateManager11::onBeginQuery(Query11 *query)
+{
+ mCurrentQueries.insert(query);
+}
+
+void StateManager11::onDeleteQueryObject(Query11 *query)
+{
+ mCurrentQueries.erase(query);
+}
+
+angle::Result StateManager11::onMakeCurrent(const gl::Context *context)
+{
+ ANGLE_TRY(ensureInitialized(context));
+
+ const gl::State &state = context->getState();
+
+ Context11 *context11 = GetImplAs<Context11>(context);
+
+ for (Query11 *query : mCurrentQueries)
+ {
+ ANGLE_TRY(query->pause(context11));
+ }
+ mCurrentQueries.clear();
+
+ for (gl::QueryType type : angle::AllEnums<gl::QueryType>())
+ {
+ gl::Query *query = state.getActiveQuery(type);
+ if (query != nullptr)
+ {
+ Query11 *query11 = GetImplAs<Query11>(query);
+ ANGLE_TRY(query11->resume(context11));
+ mCurrentQueries.insert(query11);
+ }
+ }
+
+ // Reset the cache objects.
+ mProgramD3D = nullptr;
+ mVertexArray11 = nullptr;
+ mFramebuffer11 = nullptr;
+
+ return angle::Result::Continue;
+}
+
+void StateManager11::unsetConflictingView(gl::PipelineType pipeline,
+ ID3D11View *view,
+ bool isRenderTarget)
+{
+ uintptr_t resource = reinterpret_cast<uintptr_t>(GetViewResource(view));
+
+ unsetConflictingSRVs(pipeline, gl::ShaderType::Vertex, resource, nullptr, isRenderTarget);
+ unsetConflictingSRVs(pipeline, gl::ShaderType::Fragment, resource, nullptr, isRenderTarget);
+ unsetConflictingSRVs(pipeline, gl::ShaderType::Compute, resource, nullptr, isRenderTarget);
+ unsetConflictingUAVs(pipeline, gl::ShaderType::Compute, resource, nullptr);
+}
+
+void StateManager11::unsetConflictingSRVs(gl::PipelineType pipeline,
+ gl::ShaderType shaderType,
+ uintptr_t resource,
+ const gl::ImageIndex *index,
+ bool isRenderTarget)
+{
+ auto *currentSRVs = getSRVCache(shaderType);
+ gl::PipelineType conflictPipeline = gl::GetPipelineType(shaderType);
+ bool foundOne = false;
+ size_t count = std::min(currentSRVs->size(), currentSRVs->highestUsed());
+ for (size_t resourceIndex = 0; resourceIndex < count; ++resourceIndex)
+ {
+ auto &record = (*currentSRVs)[resourceIndex];
+
+ if (record.view && record.resource == resource &&
+ (!index || ImageIndexConflictsWithSRV(*index, record.desc)))
+ {
+ setShaderResourceInternal<d3d11::ShaderResourceView>(
+ shaderType, static_cast<UINT>(resourceIndex), nullptr);
+ foundOne = true;
+ }
+ }
+
+ if (foundOne && (pipeline != conflictPipeline || isRenderTarget))
+ {
+ switch (conflictPipeline)
+ {
+ case gl::PipelineType::GraphicsPipeline:
+ mInternalDirtyBits.set(DIRTY_BIT_GRAPHICS_SRV_STATE);
+ break;
+ case gl::PipelineType::ComputePipeline:
+ mInternalDirtyBits.set(DIRTY_BIT_COMPUTE_SRV_STATE);
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+}
+
+void StateManager11::unsetConflictingUAVs(gl::PipelineType pipeline,
+ gl::ShaderType shaderType,
+ uintptr_t resource,
+ const gl::ImageIndex *index)
+{
+ ASSERT(shaderType == gl::ShaderType::Compute);
+ bool foundOne = false;
+
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+ size_t count = std::min(mCurComputeUAVs.size(), mCurComputeUAVs.highestUsed());
+ for (size_t resourceIndex = 0; resourceIndex < count; ++resourceIndex)
+ {
+ auto &record = mCurComputeUAVs[resourceIndex];
+
+ if (record.view && record.resource == resource &&
+ (!index || ImageIndexConflictsWithUAV(*index, record.desc)))
+ {
+ deviceContext->CSSetUnorderedAccessViews(static_cast<UINT>(resourceIndex), 1,
+ &mNullUAVs[0], nullptr);
+ mCurComputeUAVs.update(resourceIndex, nullptr);
+ foundOne = true;
+ }
+ }
+
+ if (foundOne && pipeline == gl::PipelineType::GraphicsPipeline)
+ {
+ mInternalDirtyBits.set(DIRTY_BIT_COMPUTE_UAV_STATE);
+ }
+}
+
+void StateManager11::unsetConflictingRTVs(uintptr_t resource)
+{
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+ size_t count = std::min(mCurRTVs.size(), mCurRTVs.highestUsed());
+ for (size_t resourceIndex = 0; resourceIndex < count; ++resourceIndex)
+ {
+ auto &record = mCurRTVs[resourceIndex];
+
+ if (record.view && record.resource == resource)
+ {
+ deviceContext->OMSetRenderTargets(0, nullptr, nullptr);
+ mCurRTVs.clear();
+ mInternalDirtyBits.set(DIRTY_BIT_RENDER_TARGET);
+ return;
+ }
+ }
+}
+
+void StateManager11::unsetConflictingAttachmentResources(
+ const gl::FramebufferAttachment &attachment,
+ ID3D11Resource *resource)
+{
+ // Unbind render target SRVs from the shader here to prevent D3D11 warnings.
+ if (attachment.type() == GL_TEXTURE)
+ {
+ uintptr_t resourcePtr = reinterpret_cast<uintptr_t>(resource);
+ const gl::ImageIndex &index = attachment.getTextureImageIndex();
+ // The index doesn't need to be corrected for the small compressed texture workaround
+ // because a rendertarget is never compressed.
+ unsetConflictingSRVs(gl::PipelineType::GraphicsPipeline, gl::ShaderType::Vertex,
+ resourcePtr, &index, false);
+ unsetConflictingSRVs(gl::PipelineType::GraphicsPipeline, gl::ShaderType::Fragment,
+ resourcePtr, &index, false);
+ unsetConflictingSRVs(gl::PipelineType::GraphicsPipeline, gl::ShaderType::Compute,
+ resourcePtr, &index, false);
+ unsetConflictingUAVs(gl::PipelineType::GraphicsPipeline, gl::ShaderType::Compute,
+ resourcePtr, &index);
+ }
+ else if (attachment.type() == GL_FRAMEBUFFER_DEFAULT)
+ {
+ uintptr_t resourcePtr = reinterpret_cast<uintptr_t>(resource);
+ unsetConflictingSRVs(gl::PipelineType::GraphicsPipeline, gl::ShaderType::Vertex,
+ resourcePtr, nullptr, false);
+ unsetConflictingSRVs(gl::PipelineType::GraphicsPipeline, gl::ShaderType::Fragment,
+ resourcePtr, nullptr, false);
+ unsetConflictingSRVs(gl::PipelineType::GraphicsPipeline, gl::ShaderType::Compute,
+ resourcePtr, nullptr, false);
+ unsetConflictingUAVs(gl::PipelineType::GraphicsPipeline, gl::ShaderType::Compute,
+ resourcePtr, nullptr);
+ }
+}
+
+angle::Result StateManager11::ensureInitialized(const gl::Context *context)
+{
+ Renderer11 *renderer = GetImplAs<Context11>(context)->getRenderer();
+
+ const gl::Caps &caps = renderer->getNativeCaps();
+ const gl::Extensions &extensions = renderer->getNativeExtensions();
+
+ for (gl::ShaderType shaderType : gl::AllShaderTypes())
+ {
+ const GLuint maxShaderTextureImageUnits =
+ static_cast<GLuint>(caps.maxShaderTextureImageUnits[shaderType]);
+
+ mCurShaderSRVs[shaderType].initialize(maxShaderTextureImageUnits);
+ mForceSetShaderSamplerStates[shaderType].resize(maxShaderTextureImageUnits, true);
+ mCurShaderSamplerStates[shaderType].resize(maxShaderTextureImageUnits);
+ }
+ mCurRTVs.initialize(caps.maxColorAttachments);
+ mCurComputeUAVs.initialize(caps.maxImageUnits);
+
+ // Initialize cached NULL SRV block
+ mNullSRVs.resize(caps.maxShaderTextureImageUnits[gl::ShaderType::Fragment], nullptr);
+
+ mNullUAVs.resize(caps.maxImageUnits, nullptr);
+
+ mCurrentValueAttribs.resize(caps.maxVertexAttributes);
+
+ mShaderConstants.init(caps);
+
+ mIsMultiviewEnabled = extensions.multiviewOVR || extensions.multiview2OVR;
+
+ mIndependentBlendStates = extensions.drawBuffersIndexedAny(); // requires FL10_1
+
+ // FL9_3 is limited to 4; ES3.1 context on FL11_0 is limited to 7
+ mCurBlendStateExt =
+ gl::BlendStateExt(GetImplAs<Context11>(context)->getNativeCaps().maxDrawBuffers);
+
+ ANGLE_TRY(mVertexDataManager.initialize(context));
+
+ mCurrentAttributes.reserve(gl::MAX_VERTEX_ATTRIBS);
+
+ return angle::Result::Continue;
+}
+
+void StateManager11::deinitialize()
+{
+ mCurrentValueAttribs.clear();
+ mInputLayoutCache.clear();
+ mVertexDataManager.deinitialize();
+ mIndexDataManager.deinitialize();
+
+ for (d3d11::Buffer &ShaderDriverConstantBuffer : mShaderDriverConstantBuffers)
+ {
+ ShaderDriverConstantBuffer.reset();
+ }
+
+ mPointSpriteVertexBuffer.reset();
+ mPointSpriteIndexBuffer.reset();
+}
+
+// Applies the render target surface, depth stencil surface, viewport rectangle and
+// scissor rectangle to the renderer
+angle::Result StateManager11::syncFramebuffer(const gl::Context *context)
+{
+ // Check for zero-sized default framebuffer, which is a special case.
+ // in this case we do not wish to modify any state and just silently return false.
+ // this will not report any gl error but will cause the calling method to return.
+ if (mFramebuffer11->getState().isDefault())
+ {
+ RenderTarget11 *firstRT = mFramebuffer11->getFirstRenderTarget();
+ const gl::Extents &size = firstRT->getExtents();
+ if (size.empty())
+ {
+ return angle::Result::Continue;
+ }
+ }
+
+ RTVArray framebufferRTVs = {{}};
+ const auto &colorRTs = mFramebuffer11->getCachedColorRenderTargets();
+
+ size_t appliedRTIndex = 0;
+ bool skipInactiveRTs = mRenderer->getFeatures().mrtPerfWorkaround.enabled;
+ const auto &drawStates = mFramebuffer11->getState().getDrawBufferStates();
+ gl::DrawBufferMask activeProgramOutputs =
+ mProgramD3D->getState().getExecutable().getActiveOutputVariablesMask();
+ UINT maxExistingRT = 0;
+ const auto &colorAttachments = mFramebuffer11->getState().getColorAttachments();
+
+ for (size_t rtIndex = 0; rtIndex < colorRTs.size(); ++rtIndex)
+ {
+ const RenderTarget11 *renderTarget = colorRTs[rtIndex];
+
+ // Skip inactive rendertargets if the workaround is enabled.
+ if (skipInactiveRTs &&
+ (!renderTarget || drawStates[rtIndex] == GL_NONE || !activeProgramOutputs[rtIndex]))
+ {
+ continue;
+ }
+
+ if (renderTarget)
+ {
+ framebufferRTVs[appliedRTIndex] = renderTarget->getRenderTargetView().get();
+ ASSERT(framebufferRTVs[appliedRTIndex]);
+ maxExistingRT = static_cast<UINT>(appliedRTIndex) + 1;
+
+ // Unset conflicting texture SRVs
+ const gl::FramebufferAttachment &attachment = colorAttachments[rtIndex];
+ ASSERT(attachment.isAttached());
+ unsetConflictingAttachmentResources(attachment, renderTarget->getTexture().get());
+ }
+
+ appliedRTIndex++;
+ }
+
+ // Get the depth stencil buffers
+ ID3D11DepthStencilView *framebufferDSV = nullptr;
+ const auto *depthStencilRenderTarget = mFramebuffer11->getCachedDepthStencilRenderTarget();
+ if (depthStencilRenderTarget)
+ {
+ framebufferDSV = depthStencilRenderTarget->getDepthStencilView().get();
+ ASSERT(framebufferDSV);
+
+ // Unset conflicting texture SRVs
+ const gl::FramebufferAttachment *attachment =
+ mFramebuffer11->getState().getDepthOrStencilAttachment();
+ ASSERT(attachment);
+ unsetConflictingAttachmentResources(*attachment,
+ depthStencilRenderTarget->getTexture().get());
+ }
+
+ ASSERT(maxExistingRT <= static_cast<UINT>(context->getCaps().maxDrawBuffers));
+
+ // Apply the render target and depth stencil
+ mRenderer->getDeviceContext()->OMSetRenderTargets(maxExistingRT, framebufferRTVs.data(),
+ framebufferDSV);
+ mCurRTVs.clear();
+ for (UINT i = 0; i < maxExistingRT; i++)
+ {
+ mCurRTVs.update(i, framebufferRTVs[i]);
+ }
+ return angle::Result::Continue;
+}
+
+void StateManager11::invalidateCurrentValueAttrib(size_t attribIndex)
+{
+ mDirtyCurrentValueAttribs.set(attribIndex);
+ mInternalDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_ATTRIBS);
+ invalidateInputLayout();
+ invalidateShaders();
+}
+
+angle::Result StateManager11::syncCurrentValueAttribs(
+ const gl::Context *context,
+ const std::vector<gl::VertexAttribCurrentValueData> &currentValues)
+{
+ const gl::ProgramExecutable &executable = mProgramD3D->getState().getExecutable();
+ const auto &activeAttribsMask = executable.getActiveAttribLocationsMask();
+ const auto &dirtyActiveAttribs = (activeAttribsMask & mDirtyCurrentValueAttribs);
+
+ if (!dirtyActiveAttribs.any())
+ {
+ return angle::Result::Continue;
+ }
+
+ const auto &vertexAttributes = mVertexArray11->getState().getVertexAttributes();
+ const auto &vertexBindings = mVertexArray11->getState().getVertexBindings();
+ mDirtyCurrentValueAttribs = (mDirtyCurrentValueAttribs & ~dirtyActiveAttribs);
+
+ for (auto attribIndex : dirtyActiveAttribs)
+ {
+ if (vertexAttributes[attribIndex].enabled)
+ continue;
+
+ const auto *attrib = &vertexAttributes[attribIndex];
+ const auto &currentValue = currentValues[attribIndex];
+ TranslatedAttribute *currentValueAttrib = &mCurrentValueAttribs[attribIndex];
+ currentValueAttrib->currentValueType = currentValue.Type;
+ currentValueAttrib->attribute = attrib;
+ currentValueAttrib->binding = &vertexBindings[attrib->bindingIndex];
+
+ mDirtyVertexBufferRange.extend(static_cast<unsigned int>(attribIndex));
+
+ ANGLE_TRY(mVertexDataManager.storeCurrentValue(context, currentValue, currentValueAttrib,
+ static_cast<size_t>(attribIndex)));
+ }
+
+ return angle::Result::Continue;
+}
+
+void StateManager11::setInputLayout(const d3d11::InputLayout *inputLayout)
+{
+ if (setInputLayoutInternal(inputLayout))
+ {
+ invalidateInputLayout();
+ }
+}
+
+bool StateManager11::setInputLayoutInternal(const d3d11::InputLayout *inputLayout)
+{
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+ if (inputLayout == nullptr)
+ {
+ if (!mCurrentInputLayout.empty())
+ {
+ deviceContext->IASetInputLayout(nullptr);
+ mCurrentInputLayout.clear();
+ return true;
+ }
+ }
+ else if (inputLayout->getSerial() != mCurrentInputLayout)
+ {
+ deviceContext->IASetInputLayout(inputLayout->get());
+ mCurrentInputLayout = inputLayout->getSerial();
+ return true;
+ }
+
+ return false;
+}
+
+bool StateManager11::queueVertexBufferChange(size_t bufferIndex,
+ ID3D11Buffer *buffer,
+ UINT stride,
+ UINT offset)
+{
+ if (buffer != mCurrentVertexBuffers[bufferIndex] ||
+ stride != mCurrentVertexStrides[bufferIndex] ||
+ offset != mCurrentVertexOffsets[bufferIndex])
+ {
+ mDirtyVertexBufferRange.extend(static_cast<unsigned int>(bufferIndex));
+
+ mCurrentVertexBuffers[bufferIndex] = buffer;
+ mCurrentVertexStrides[bufferIndex] = stride;
+ mCurrentVertexOffsets[bufferIndex] = offset;
+ return true;
+ }
+
+ return false;
+}
+
+void StateManager11::applyVertexBufferChanges()
+{
+ if (mDirtyVertexBufferRange.empty())
+ {
+ return;
+ }
+
+ ASSERT(mDirtyVertexBufferRange.high() <= gl::MAX_VERTEX_ATTRIBS);
+
+ UINT start = static_cast<UINT>(mDirtyVertexBufferRange.low());
+
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+ deviceContext->IASetVertexBuffers(start, static_cast<UINT>(mDirtyVertexBufferRange.length()),
+ &mCurrentVertexBuffers[start], &mCurrentVertexStrides[start],
+ &mCurrentVertexOffsets[start]);
+
+ mDirtyVertexBufferRange = gl::RangeUI(gl::MAX_VERTEX_ATTRIBS, 0);
+}
+
+void StateManager11::setSingleVertexBuffer(const d3d11::Buffer *buffer, UINT stride, UINT offset)
+{
+ ID3D11Buffer *native = buffer ? buffer->get() : nullptr;
+ if (queueVertexBufferChange(0, native, stride, offset))
+ {
+ invalidateInputLayout();
+ applyVertexBufferChanges();
+ }
+}
+
+angle::Result StateManager11::updateState(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLint firstVertex,
+ GLsizei vertexOrIndexCount,
+ gl::DrawElementsType indexTypeOrInvalid,
+ const void *indices,
+ GLsizei instanceCount,
+ GLint baseVertex,
+ GLuint baseInstance,
+ bool promoteDynamic)
+{
+ const gl::State &glState = context->getState();
+
+ // TODO(jmadill): Use dirty bits.
+ if (mRenderTargetIsDirty)
+ {
+ processFramebufferInvalidation(context);
+ mRenderTargetIsDirty = false;
+ }
+
+ // TODO(jmadill): Use dirty bits.
+ if (mProgramD3D->updateSamplerMapping() == ProgramD3D::SamplerMapping::WasDirty)
+ {
+ invalidateTexturesAndSamplers();
+ }
+
+ // TODO(jmadill): Use dirty bits.
+ if (mProgramD3D->anyShaderUniformsDirty())
+ {
+ mInternalDirtyBits.set(DIRTY_BIT_PROGRAM_UNIFORMS);
+ }
+
+ // Swizzling can cause internal state changes with blit shaders.
+ if (mDirtySwizzles)
+ {
+ ANGLE_TRY(generateSwizzles(context));
+ mDirtySwizzles = false;
+ }
+
+ ANGLE_TRY(mFramebuffer11->markAttachmentsDirty(context));
+
+ // TODO(jiawei.shao@intel.com): This can be recomputed only on framebuffer or multisample mask
+ // state changes.
+ RenderTarget11 *firstRT = mFramebuffer11->getFirstRenderTarget();
+ int samples = (firstRT ? firstRT->getSamples() : 0);
+ unsigned int sampleMask = GetBlendSampleMask(glState, samples);
+ if (sampleMask != mCurSampleMask)
+ {
+ mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
+ }
+
+ ANGLE_TRY(mVertexArray11->syncStateForDraw(context, firstVertex, vertexOrIndexCount,
+ indexTypeOrInvalid, indices, instanceCount,
+ baseVertex, baseInstance, promoteDynamic));
+
+ // Changes in the draw call can affect the vertex buffer translations.
+ if (!mLastFirstVertex.valid() || mLastFirstVertex.value() != firstVertex)
+ {
+ mLastFirstVertex = firstVertex;
+ invalidateInputLayout();
+ }
+
+ // The ShaderConstants only need to be updated when the program uses vertexID
+ if (mProgramD3D->usesVertexID())
+ {
+ GLint firstVertexOnChange = firstVertex + baseVertex;
+ ASSERT(mVertexArray11);
+ if (mVertexArray11->hasActiveDynamicAttrib(context) &&
+ indexTypeOrInvalid != gl::DrawElementsType::InvalidEnum)
+ {
+ // drawElements with Dynamic attribute
+ // the firstVertex is already including baseVertex when
+ // doing ComputeStartVertex
+ firstVertexOnChange = firstVertex;
+ }
+
+ if (mShaderConstants.onFirstVertexChange(firstVertexOnChange))
+ {
+ mInternalDirtyBits.set(DIRTY_BIT_DRIVER_UNIFORMS);
+ }
+ }
+
+ if (indexTypeOrInvalid != gl::DrawElementsType::InvalidEnum)
+ {
+ ANGLE_TRY(applyIndexBuffer(context, vertexOrIndexCount, indexTypeOrInvalid, indices));
+ }
+
+ if (mLastAppliedDrawMode != mode)
+ {
+ mLastAppliedDrawMode = mode;
+ mInternalDirtyBits.set(DIRTY_BIT_PRIMITIVE_TOPOLOGY);
+
+ bool pointDrawMode = (mode == gl::PrimitiveMode::Points);
+ if (pointDrawMode != mCurRasterState.pointDrawMode)
+ {
+ mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
+
+ // Changing from points to not points (or vice-versa) affects the geometry shader.
+ invalidateShaders();
+ }
+ }
+
+ auto dirtyBitsCopy = mInternalDirtyBits & mGraphicsDirtyBitsMask;
+
+ for (auto iter = dirtyBitsCopy.begin(), end = dirtyBitsCopy.end(); iter != end; ++iter)
+ {
+ mInternalDirtyBits.reset(*iter);
+ switch (*iter)
+ {
+ case DIRTY_BIT_RENDER_TARGET:
+ ANGLE_TRY(syncFramebuffer(context));
+ break;
+ case DIRTY_BIT_VIEWPORT_STATE:
+ syncViewport(context);
+ break;
+ case DIRTY_BIT_SCISSOR_STATE:
+ syncScissorRectangle(context);
+ break;
+ case DIRTY_BIT_RASTERIZER_STATE:
+ ANGLE_TRY(syncRasterizerState(context, mode));
+ break;
+ case DIRTY_BIT_BLEND_STATE:
+ ANGLE_TRY(syncBlendState(
+ context, glState.getBlendStateExt(), glState.getBlendColor(), sampleMask,
+ glState.isSampleAlphaToCoverageEnabled(), glState.hasConstantAlphaBlendFunc()));
+ break;
+ case DIRTY_BIT_DEPTH_STENCIL_STATE:
+ ANGLE_TRY(syncDepthStencilState(context));
+ break;
+ case DIRTY_BIT_GRAPHICS_SRV_STATE:
+ ANGLE_TRY(syncTextures(context));
+ break;
+ case DIRTY_BIT_GRAPHICS_UAV_STATE:
+ ANGLE_TRY(syncUAVsForGraphics(context));
+ break;
+ case DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE:
+ // TODO(jmadill): More fine-grained update.
+ ANGLE_TRY(syncTextures(context));
+ break;
+ case DIRTY_BIT_PROGRAM_UNIFORMS:
+ ANGLE_TRY(applyUniforms(context));
+ break;
+ case DIRTY_BIT_DRIVER_UNIFORMS:
+ // This must happen after viewport sync; the viewport affects builtin uniforms.
+ ANGLE_TRY(applyDriverUniforms(context));
+ break;
+ case DIRTY_BIT_PROGRAM_UNIFORM_BUFFERS:
+ ANGLE_TRY(syncUniformBuffers(context));
+ break;
+ case DIRTY_BIT_SHADERS:
+ ANGLE_TRY(syncProgram(context, mode));
+ break;
+ case DIRTY_BIT_CURRENT_VALUE_ATTRIBS:
+ ANGLE_TRY(syncCurrentValueAttribs(context, glState.getVertexAttribCurrentValues()));
+ break;
+ case DIRTY_BIT_TRANSFORM_FEEDBACK:
+ ANGLE_TRY(syncTransformFeedbackBuffers(context));
+ break;
+ case DIRTY_BIT_VERTEX_BUFFERS_AND_INPUT_LAYOUT:
+ ANGLE_TRY(syncVertexBuffersAndInputLayout(context, mode, firstVertex,
+ vertexOrIndexCount, indexTypeOrInvalid,
+ instanceCount));
+ break;
+ case DIRTY_BIT_PRIMITIVE_TOPOLOGY:
+ syncPrimitiveTopology(glState, mode);
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ }
+
+ // Check that we haven't set any dirty bits in the flushing of the dirty bits loop, except
+ // DIRTY_BIT_COMPUTE_SRVUAV_STATE dirty bit.
+ ASSERT((mInternalDirtyBits & mGraphicsDirtyBitsMask).none());
+
+ return angle::Result::Continue;
+}
+
+void StateManager11::setShaderResourceShared(gl::ShaderType shaderType,
+ UINT resourceSlot,
+ const d3d11::SharedSRV *srv)
+{
+ setShaderResourceInternal(shaderType, resourceSlot, srv);
+
+ // TODO(jmadill): Narrower dirty region.
+ mInternalDirtyBits.set(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE);
+}
+
+void StateManager11::setShaderResource(gl::ShaderType shaderType,
+ UINT resourceSlot,
+ const d3d11::ShaderResourceView *srv)
+{
+ setShaderResourceInternal(shaderType, resourceSlot, srv);
+
+ // TODO(jmadill): Narrower dirty region.
+ mInternalDirtyBits.set(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE);
+}
+
+void StateManager11::setPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY primitiveTopology)
+{
+ if (setPrimitiveTopologyInternal(primitiveTopology))
+ {
+ mInternalDirtyBits.set(DIRTY_BIT_PRIMITIVE_TOPOLOGY);
+ }
+}
+
+bool StateManager11::setPrimitiveTopologyInternal(D3D11_PRIMITIVE_TOPOLOGY primitiveTopology)
+{
+ if (primitiveTopology != mCurrentPrimitiveTopology)
+ {
+ mRenderer->getDeviceContext()->IASetPrimitiveTopology(primitiveTopology);
+ mCurrentPrimitiveTopology = primitiveTopology;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+void StateManager11::setDrawShaders(const d3d11::VertexShader *vertexShader,
+ const d3d11::GeometryShader *geometryShader,
+ const d3d11::PixelShader *pixelShader)
+{
+ setVertexShader(vertexShader);
+ setGeometryShader(geometryShader);
+ setPixelShader(pixelShader);
+}
+
+void StateManager11::setVertexShader(const d3d11::VertexShader *shader)
+{
+ ResourceSerial serial = shader ? shader->getSerial() : ResourceSerial(0);
+
+ if (serial != mAppliedShaders[gl::ShaderType::Vertex])
+ {
+ ID3D11VertexShader *appliedShader = shader ? shader->get() : nullptr;
+ mRenderer->getDeviceContext()->VSSetShader(appliedShader, nullptr, 0);
+ mAppliedShaders[gl::ShaderType::Vertex] = serial;
+ invalidateShaders();
+ }
+}
+
+void StateManager11::setGeometryShader(const d3d11::GeometryShader *shader)
+{
+ ResourceSerial serial = shader ? shader->getSerial() : ResourceSerial(0);
+
+ if (serial != mAppliedShaders[gl::ShaderType::Geometry])
+ {
+ ID3D11GeometryShader *appliedShader = shader ? shader->get() : nullptr;
+ mRenderer->getDeviceContext()->GSSetShader(appliedShader, nullptr, 0);
+ mAppliedShaders[gl::ShaderType::Geometry] = serial;
+ invalidateShaders();
+ }
+}
+
+void StateManager11::setPixelShader(const d3d11::PixelShader *shader)
+{
+ ResourceSerial serial = shader ? shader->getSerial() : ResourceSerial(0);
+
+ if (serial != mAppliedShaders[gl::ShaderType::Fragment])
+ {
+ ID3D11PixelShader *appliedShader = shader ? shader->get() : nullptr;
+ mRenderer->getDeviceContext()->PSSetShader(appliedShader, nullptr, 0);
+ mAppliedShaders[gl::ShaderType::Fragment] = serial;
+ invalidateShaders();
+ }
+}
+
+void StateManager11::setComputeShader(const d3d11::ComputeShader *shader)
+{
+ ResourceSerial serial = shader ? shader->getSerial() : ResourceSerial(0);
+
+ if (serial != mAppliedShaders[gl::ShaderType::Compute])
+ {
+ ID3D11ComputeShader *appliedShader = shader ? shader->get() : nullptr;
+ mRenderer->getDeviceContext()->CSSetShader(appliedShader, nullptr, 0);
+ mAppliedShaders[gl::ShaderType::Compute] = serial;
+ invalidateShaders();
+ }
+}
+
+void StateManager11::setVertexConstantBuffer(unsigned int slot, const d3d11::Buffer *buffer)
+{
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+ auto &currentSerial = mCurrentConstantBufferVS[slot];
+
+ mCurrentConstantBufferVSOffset[slot] = 0;
+ mCurrentConstantBufferVSSize[slot] = 0;
+
+ if (buffer)
+ {
+ if (currentSerial != buffer->getSerial())
+ {
+ deviceContext->VSSetConstantBuffers(slot, 1, buffer->getPointer());
+ currentSerial = buffer->getSerial();
+ invalidateConstantBuffer(slot);
+ }
+ }
+ else
+ {
+ if (!currentSerial.empty())
+ {
+ ID3D11Buffer *nullBuffer = nullptr;
+ deviceContext->VSSetConstantBuffers(slot, 1, &nullBuffer);
+ currentSerial.clear();
+ invalidateConstantBuffer(slot);
+ }
+ }
+}
+
+void StateManager11::setPixelConstantBuffer(unsigned int slot, const d3d11::Buffer *buffer)
+{
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+ auto &currentSerial = mCurrentConstantBufferPS[slot];
+
+ mCurrentConstantBufferPSOffset[slot] = 0;
+ mCurrentConstantBufferPSSize[slot] = 0;
+
+ if (buffer)
+ {
+ if (currentSerial != buffer->getSerial())
+ {
+ deviceContext->PSSetConstantBuffers(slot, 1, buffer->getPointer());
+ currentSerial = buffer->getSerial();
+ invalidateConstantBuffer(slot);
+ }
+ }
+ else
+ {
+ if (!currentSerial.empty())
+ {
+ ID3D11Buffer *nullBuffer = nullptr;
+ deviceContext->PSSetConstantBuffers(slot, 1, &nullBuffer);
+ currentSerial.clear();
+ invalidateConstantBuffer(slot);
+ }
+ }
+}
+
+void StateManager11::setDepthStencilState(const d3d11::DepthStencilState *depthStencilState,
+ UINT stencilRef)
+{
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+
+ if (depthStencilState)
+ {
+ deviceContext->OMSetDepthStencilState(depthStencilState->get(), stencilRef);
+ }
+ else
+ {
+ deviceContext->OMSetDepthStencilState(nullptr, stencilRef);
+ }
+
+ mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
+}
+
+void StateManager11::setSimpleBlendState(const d3d11::BlendState *blendState)
+{
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+
+ if (blendState)
+ {
+ deviceContext->OMSetBlendState(blendState->get(), nullptr, 0xFFFFFFFF);
+ }
+ else
+ {
+ deviceContext->OMSetBlendState(nullptr, nullptr, 0xFFFFFFFF);
+ }
+
+ mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
+}
+
+void StateManager11::setRasterizerState(const d3d11::RasterizerState *rasterizerState)
+{
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+
+ if (rasterizerState)
+ {
+ deviceContext->RSSetState(rasterizerState->get());
+ }
+ else
+ {
+ deviceContext->RSSetState(nullptr);
+ }
+
+ mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
+}
+
+void StateManager11::setSimpleViewport(const gl::Extents &extents)
+{
+ setSimpleViewport(extents.width, extents.height);
+}
+
+void StateManager11::setSimpleViewport(int width, int height)
+{
+ D3D11_VIEWPORT viewport;
+ viewport.TopLeftX = 0;
+ viewport.TopLeftY = 0;
+ viewport.Width = static_cast<FLOAT>(width);
+ viewport.Height = static_cast<FLOAT>(height);
+ viewport.MinDepth = 0.0f;
+ viewport.MaxDepth = 1.0f;
+
+ mRenderer->getDeviceContext()->RSSetViewports(1, &viewport);
+ mInternalDirtyBits.set(DIRTY_BIT_VIEWPORT_STATE);
+}
+
+void StateManager11::setSimplePixelTextureAndSampler(const d3d11::SharedSRV &srv,
+ const d3d11::SamplerState &samplerState)
+{
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+
+ setShaderResourceInternal(gl::ShaderType::Fragment, 0, &srv);
+ deviceContext->PSSetSamplers(0, 1, samplerState.getPointer());
+
+ mInternalDirtyBits.set(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE);
+ mForceSetShaderSamplerStates[gl::ShaderType::Fragment][0] = true;
+}
+
+void StateManager11::setSimpleScissorRect(const gl::Rectangle &glRect)
+{
+ D3D11_RECT scissorRect;
+ scissorRect.left = glRect.x;
+ scissorRect.right = glRect.x + glRect.width;
+ scissorRect.top = glRect.y;
+ scissorRect.bottom = glRect.y + glRect.height;
+ setScissorRectD3D(scissorRect);
+}
+
+void StateManager11::setScissorRectD3D(const D3D11_RECT &d3dRect)
+{
+ mRenderer->getDeviceContext()->RSSetScissorRects(1, &d3dRect);
+ mInternalDirtyBits.set(DIRTY_BIT_SCISSOR_STATE);
+}
+
+angle::Result StateManager11::syncTextures(const gl::Context *context)
+{
+ ANGLE_TRY(applyTexturesForSRVs(context, gl::ShaderType::Vertex));
+ ANGLE_TRY(applyTexturesForSRVs(context, gl::ShaderType::Fragment));
+ if (mProgramD3D->hasShaderStage(gl::ShaderType::Geometry))
+ {
+ ANGLE_TRY(applyTexturesForSRVs(context, gl::ShaderType::Geometry));
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result StateManager11::setSamplerState(const gl::Context *context,
+ gl::ShaderType type,
+ int index,
+ gl::Texture *texture,
+ const gl::SamplerState &samplerState)
+{
+#if !defined(NDEBUG)
+ // Storage should exist, texture should be complete. Only verified in Debug.
+ TextureD3D *textureD3D = GetImplAs<TextureD3D>(texture);
+ TextureStorage *storage = nullptr;
+ ANGLE_TRY(textureD3D->getNativeTexture(context, &storage));
+ ASSERT(storage);
+#endif // !defined(NDEBUG)
+
+ auto *deviceContext = mRenderer->getDeviceContext();
+
+ ASSERT(index < mRenderer->getNativeCaps().maxShaderTextureImageUnits[type]);
+
+ if (mForceSetShaderSamplerStates[type][index] ||
+ memcmp(&samplerState, &mCurShaderSamplerStates[type][index], sizeof(gl::SamplerState)) != 0)
+ {
+ ID3D11SamplerState *dxSamplerState = nullptr;
+ ANGLE_TRY(mRenderer->getSamplerState(context, samplerState, &dxSamplerState));
+
+ ASSERT(dxSamplerState != nullptr);
+
+ switch (type)
+ {
+ case gl::ShaderType::Vertex:
+ deviceContext->VSSetSamplers(index, 1, &dxSamplerState);
+ break;
+ case gl::ShaderType::Fragment:
+ deviceContext->PSSetSamplers(index, 1, &dxSamplerState);
+ break;
+ case gl::ShaderType::Compute:
+ deviceContext->CSSetSamplers(index, 1, &dxSamplerState);
+ break;
+ case gl::ShaderType::Geometry:
+ deviceContext->GSSetSamplers(index, 1, &dxSamplerState);
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ mCurShaderSamplerStates[type][index] = samplerState;
+ }
+
+ mForceSetShaderSamplerStates[type][index] = false;
+
+ // Sampler metadata that's passed to shaders in uniforms is stored separately from rest of the
+ // sampler state since having it in contiguous memory makes it possible to memcpy to a constant
+ // buffer, and it doesn't affect the state set by
+ // PSSetSamplers/VSSetSamplers/CSSetSamplers/GSSetSamplers.
+ mShaderConstants.onSamplerChange(type, index, *texture, samplerState);
+
+ return angle::Result::Continue;
+}
+
+angle::Result StateManager11::setTextureForSampler(const gl::Context *context,
+ gl::ShaderType type,
+ int index,
+ gl::Texture *texture,
+ const gl::SamplerState &sampler)
+{
+ const d3d11::SharedSRV *textureSRV = nullptr;
+
+ if (texture)
+ {
+ TextureD3D *textureImpl = GetImplAs<TextureD3D>(texture);
+
+ TextureStorage *texStorage = nullptr;
+ ANGLE_TRY(textureImpl->getNativeTexture(context, &texStorage));
+
+ // Texture should be complete and have a storage
+ ASSERT(texStorage);
+
+ TextureStorage11 *storage11 = GetAs<TextureStorage11>(texStorage);
+
+ ANGLE_TRY(
+ storage11->getSRVForSampler(context, texture->getTextureState(), sampler, &textureSRV));
+
+ // If we get an invalid SRV here, something went wrong in the texture class and we're
+ // unexpectedly missing the shader resource view.
+ ASSERT(textureSRV->valid());
+
+ textureImpl->resetDirty();
+ }
+
+ ASSERT(
+ (type == gl::ShaderType::Fragment &&
+ index < mRenderer->getNativeCaps().maxShaderTextureImageUnits[gl::ShaderType::Fragment]) ||
+ (type == gl::ShaderType::Vertex &&
+ index < mRenderer->getNativeCaps().maxShaderTextureImageUnits[gl::ShaderType::Vertex]) ||
+ (type == gl::ShaderType::Compute &&
+ index < mRenderer->getNativeCaps().maxShaderTextureImageUnits[gl::ShaderType::Compute]));
+
+ setShaderResourceInternal(type, index, textureSRV);
+ return angle::Result::Continue;
+}
+
+angle::Result StateManager11::setImageState(const gl::Context *context,
+ gl::ShaderType type,
+ int index,
+ const gl::ImageUnit &imageUnit)
+{
+ ASSERT(index < mRenderer->getNativeCaps().maxShaderImageUniforms[type]);
+
+ if (mShaderConstants.onImageChange(type, index, imageUnit))
+ {
+ invalidateProgramUniforms();
+ }
+
+ return angle::Result::Continue;
+}
+
+// For each Direct3D sampler of either the pixel or vertex stage,
+// looks up the corresponding OpenGL texture image unit and texture type,
+// and sets the texture and its addressing/filtering state (or NULL when inactive).
+// Sampler mapping needs to be up-to-date on the program object before this is called.
+angle::Result StateManager11::applyTexturesForSRVs(const gl::Context *context,
+ gl::ShaderType shaderType)
+{
+ const auto &glState = context->getState();
+ const auto &caps = context->getCaps();
+
+ ASSERT(!mProgramD3D->isSamplerMappingDirty());
+
+ // TODO(jmadill): Use the Program's sampler bindings.
+ const gl::ActiveTexturesCache &completeTextures = glState.getActiveTexturesCache();
+
+ const gl::RangeUI samplerRange = mProgramD3D->getUsedSamplerRange(shaderType);
+ for (unsigned int samplerIndex = samplerRange.low(); samplerIndex < samplerRange.high();
+ samplerIndex++)
+ {
+ GLint textureUnit = mProgramD3D->getSamplerMapping(shaderType, samplerIndex, caps);
+ ASSERT(textureUnit != -1);
+ gl::Texture *texture = completeTextures[textureUnit];
+
+ // A nullptr texture indicates incomplete.
+ if (texture)
+ {
+ gl::Sampler *samplerObject = glState.getSampler(textureUnit);
+
+ const gl::SamplerState &samplerState =
+ samplerObject ? samplerObject->getSamplerState() : texture->getSamplerState();
+
+ ANGLE_TRY(setSamplerState(context, shaderType, samplerIndex, texture, samplerState));
+ ANGLE_TRY(
+ setTextureForSampler(context, shaderType, samplerIndex, texture, samplerState));
+ }
+ else
+ {
+ gl::TextureType textureType =
+ mProgramD3D->getSamplerTextureType(shaderType, samplerIndex);
+
+ // Texture is not sampler complete or it is in use by the framebuffer. Bind the
+ // incomplete texture.
+ gl::Texture *incompleteTexture = nullptr;
+ ANGLE_TRY(mRenderer->getIncompleteTexture(context, textureType, &incompleteTexture));
+ ANGLE_TRY(setSamplerState(context, shaderType, samplerIndex, incompleteTexture,
+ incompleteTexture->getSamplerState()));
+ ANGLE_TRY(setTextureForSampler(context, shaderType, samplerIndex, incompleteTexture,
+ incompleteTexture->getSamplerState()));
+ }
+ }
+
+ const gl::RangeUI readonlyImageRange = mProgramD3D->getUsedImageRange(shaderType, true);
+ for (unsigned int readonlyImageIndex = readonlyImageRange.low();
+ readonlyImageIndex < readonlyImageRange.high(); readonlyImageIndex++)
+ {
+ GLint imageUnitIndex =
+ mProgramD3D->getImageMapping(shaderType, readonlyImageIndex, true, caps);
+ ASSERT(imageUnitIndex != -1);
+ const gl::ImageUnit &imageUnit = glState.getImageUnit(imageUnitIndex);
+ if (!imageUnit.layered)
+ {
+ ANGLE_TRY(setImageState(context, gl::ShaderType::Compute,
+ readonlyImageIndex - readonlyImageRange.low(), imageUnit));
+ }
+ ANGLE_TRY(setTextureForImage(context, shaderType, readonlyImageIndex, imageUnit));
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result StateManager11::getUAVsForRWImages(const gl::Context *context,
+ gl::ShaderType shaderType,
+ UAVList *uavList)
+{
+ const auto &glState = context->getState();
+ const auto &caps = context->getCaps();
+
+ const gl::RangeUI imageRange = mProgramD3D->getUsedImageRange(shaderType, false);
+ for (unsigned int imageIndex = imageRange.low(); imageIndex < imageRange.high(); imageIndex++)
+ {
+ GLint imageUnitIndex = mProgramD3D->getImageMapping(shaderType, imageIndex, false, caps);
+ ASSERT(imageUnitIndex != -1);
+ const gl::ImageUnit &imageUnit = glState.getImageUnit(imageUnitIndex);
+ if (!imageUnit.layered)
+ {
+ ANGLE_TRY(setImageState(context, shaderType, imageIndex - imageRange.low(), imageUnit));
+ }
+ ANGLE_TRY(getUAVForRWImage(context, shaderType, imageIndex, imageUnit, uavList));
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result StateManager11::syncTexturesForCompute(const gl::Context *context)
+{
+ ANGLE_TRY(applyTexturesForSRVs(context, gl::ShaderType::Compute));
+ return angle::Result::Continue;
+}
+
+angle::Result StateManager11::setTextureForImage(const gl::Context *context,
+ gl::ShaderType type,
+ int index,
+ const gl::ImageUnit &imageUnit)
+{
+ TextureD3D *textureImpl = nullptr;
+ if (!imageUnit.texture.get())
+ {
+ setShaderResourceInternal<d3d11::ShaderResourceView>(type, static_cast<UINT>(index),
+ nullptr);
+ return angle::Result::Continue;
+ }
+
+ textureImpl = GetImplAs<TextureD3D>(imageUnit.texture.get());
+
+ // Ensure that texture has unordered access; convert it if not.
+ ANGLE_TRY(textureImpl->ensureUnorderedAccess(context));
+
+ TextureStorage *texStorage = nullptr;
+ ANGLE_TRY(textureImpl->getNativeTexture(context, &texStorage));
+ // Texture should be complete and have a storage
+ ASSERT(texStorage);
+ TextureStorage11 *storage11 = GetAs<TextureStorage11>(texStorage);
+
+ const d3d11::SharedSRV *textureSRV = nullptr;
+ ANGLE_TRY(storage11->getSRVForImage(context, imageUnit, &textureSRV));
+ // If we get an invalid SRV here, something went wrong in the texture class and we're
+ // unexpectedly missing the shader resource view.
+ ASSERT(textureSRV->valid());
+ ASSERT((index < mRenderer->getNativeCaps().maxImageUnits));
+ setShaderResourceInternal(type, index, textureSRV);
+
+ textureImpl->resetDirty();
+ return angle::Result::Continue;
+}
+
+angle::Result StateManager11::getUAVForRWImage(const gl::Context *context,
+ gl::ShaderType type,
+ int index,
+ const gl::ImageUnit &imageUnit,
+ UAVList *uavList)
+{
+ TextureD3D *textureImpl = nullptr;
+ if (!imageUnit.texture.get())
+ {
+ setUnorderedAccessViewInternal<d3d11::UnorderedAccessView>(static_cast<UINT>(index),
+ nullptr, uavList);
+ return angle::Result::Continue;
+ }
+
+ textureImpl = GetImplAs<TextureD3D>(imageUnit.texture.get());
+
+ // Ensure that texture has unordered access; convert it if not.
+ ANGLE_TRY(textureImpl->ensureUnorderedAccess(context));
+
+ TextureStorage *texStorage = nullptr;
+ ANGLE_TRY(textureImpl->getNativeTexture(context, &texStorage));
+ // Texture should be complete and have a storage
+ ASSERT(texStorage);
+ TextureStorage11 *storage11 = GetAs<TextureStorage11>(texStorage);
+
+ const d3d11::SharedUAV *textureUAV = nullptr;
+ ANGLE_TRY(storage11->getUAVForImage(context, imageUnit, &textureUAV));
+ // If we get an invalid UAV here, something went wrong in the texture class and we're
+ // unexpectedly missing the unordered access view.
+ ASSERT(textureUAV->valid());
+ ASSERT((index < mRenderer->getNativeCaps().maxImageUnits));
+ setUnorderedAccessViewInternal(index, textureUAV, uavList);
+
+ textureImpl->resetDirty();
+ return angle::Result::Continue;
+}
+
+// Things that affect a program's dirtyness:
+// 1. Directly changing the program executable -> triggered in StateManager11::syncState.
+// 2. The vertex attribute layout -> triggered in VertexArray11::syncState/signal.
+// 3. The fragment shader's rendertargets -> triggered in Framebuffer11::syncState/signal.
+// 4. Enabling/disabling rasterizer discard. -> triggered in StateManager11::syncState.
+// 5. Enabling/disabling transform feedback. -> checked in StateManager11::updateState.
+// 6. An internal shader was used. -> triggered in StateManager11::set*Shader.
+// 7. Drawing with/without point sprites. -> checked in StateManager11::updateState.
+// TODO(jmadill): Use dirty bits for transform feedback.
+angle::Result StateManager11::syncProgram(const gl::Context *context, gl::PrimitiveMode drawMode)
+{
+ Context11 *context11 = GetImplAs<Context11>(context);
+ ANGLE_TRY(context11->triggerDrawCallProgramRecompilation(context, drawMode));
+
+ const auto &glState = context->getState();
+
+ mProgramD3D->updateCachedInputLayout(mVertexArray11->getCurrentStateSerial(), glState);
+
+ // Binaries must be compiled before the sync.
+ ASSERT(mProgramD3D->hasVertexExecutableForCachedInputLayout());
+ ASSERT(mProgramD3D->hasGeometryExecutableForPrimitiveType(glState, drawMode));
+ ASSERT(mProgramD3D->hasPixelExecutableForCachedOutputLayout());
+
+ ShaderExecutableD3D *vertexExe = nullptr;
+ ANGLE_TRY(mProgramD3D->getVertexExecutableForCachedInputLayout(context11, &vertexExe, nullptr));
+
+ ShaderExecutableD3D *pixelExe = nullptr;
+ ANGLE_TRY(mProgramD3D->getPixelExecutableForCachedOutputLayout(context11, &pixelExe, nullptr));
+
+ ShaderExecutableD3D *geometryExe = nullptr;
+ ANGLE_TRY(mProgramD3D->getGeometryExecutableForPrimitiveType(context11, glState, drawMode,
+ &geometryExe, nullptr));
+
+ const d3d11::VertexShader *vertexShader =
+ (vertexExe ? &GetAs<ShaderExecutable11>(vertexExe)->getVertexShader() : nullptr);
+
+ // Skip pixel shader if we're doing rasterizer discard.
+ const d3d11::PixelShader *pixelShader = nullptr;
+ if (!glState.getRasterizerState().rasterizerDiscard)
+ {
+ pixelShader = (pixelExe ? &GetAs<ShaderExecutable11>(pixelExe)->getPixelShader() : nullptr);
+ }
+
+ const d3d11::GeometryShader *geometryShader = nullptr;
+ if (glState.isTransformFeedbackActiveUnpaused())
+ {
+ geometryShader =
+ (vertexExe ? &GetAs<ShaderExecutable11>(vertexExe)->getStreamOutShader() : nullptr);
+ }
+ else
+ {
+ geometryShader =
+ (geometryExe ? &GetAs<ShaderExecutable11>(geometryExe)->getGeometryShader() : nullptr);
+ }
+
+ setDrawShaders(vertexShader, geometryShader, pixelShader);
+
+ // Explicitly clear the shaders dirty bit.
+ mInternalDirtyBits.reset(DIRTY_BIT_SHADERS);
+
+ return angle::Result::Continue;
+}
+
+angle::Result StateManager11::syncProgramForCompute(const gl::Context *context)
+{
+ Context11 *context11 = GetImplAs<Context11>(context);
+ ANGLE_TRY(context11->triggerDispatchCallProgramRecompilation(context));
+
+ mProgramD3D->updateCachedComputeImage2DBindLayout(context);
+
+ // Binaries must be compiled before the sync.
+ ASSERT(mProgramD3D->hasComputeExecutableForCachedImage2DBindLayout());
+
+ ShaderExecutableD3D *computeExe = nullptr;
+ ANGLE_TRY(mProgramD3D->getComputeExecutableForImage2DBindLayout(context, context11, &computeExe,
+ nullptr));
+
+ const d3d11::ComputeShader *computeShader =
+ (computeExe ? &GetAs<ShaderExecutable11>(computeExe)->getComputeShader() : nullptr);
+ setComputeShader(computeShader);
+ // Explicitly clear the shaders dirty bit.
+ mInternalDirtyBits.reset(DIRTY_BIT_SHADERS);
+
+ return angle::Result::Continue;
+}
+
+angle::Result StateManager11::syncVertexBuffersAndInputLayout(
+ const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLint firstVertex,
+ GLsizei vertexOrIndexCount,
+ gl::DrawElementsType indexTypeOrInvalid,
+ GLsizei instanceCount)
+{
+ const auto &vertexArrayAttribs = mVertexArray11->getTranslatedAttribs();
+
+ // Sort the attributes according to ensure we re-use similar input layouts.
+ AttribIndexArray sortedSemanticIndices;
+ SortAttributesByLayout(*mProgramD3D, vertexArrayAttribs, mCurrentValueAttribs,
+ &sortedSemanticIndices, &mCurrentAttributes);
+
+ D3D_FEATURE_LEVEL featureLevel = mRenderer->getRenderer11DeviceCaps().featureLevel;
+
+ // If we are using FL 9_3, make sure the first attribute is not instanced
+ if (featureLevel <= D3D_FEATURE_LEVEL_9_3 && !mCurrentAttributes.empty())
+ {
+ if (mCurrentAttributes[0]->divisor > 0)
+ {
+ Optional<size_t> firstNonInstancedIndex = FindFirstNonInstanced(mCurrentAttributes);
+ if (firstNonInstancedIndex.valid())
+ {
+ size_t index = firstNonInstancedIndex.value();
+ std::swap(mCurrentAttributes[0], mCurrentAttributes[index]);
+ std::swap(sortedSemanticIndices[0], sortedSemanticIndices[index]);
+ }
+ }
+ }
+
+ // Update the applied input layout by querying the cache.
+ const gl::State &state = context->getState();
+ const d3d11::InputLayout *inputLayout = nullptr;
+ ANGLE_TRY(mInputLayoutCache.getInputLayout(GetImplAs<Context11>(context), state,
+ mCurrentAttributes, sortedSemanticIndices, mode,
+ vertexOrIndexCount, instanceCount, &inputLayout));
+ setInputLayoutInternal(inputLayout);
+
+ // Update the applied vertex buffers.
+ ANGLE_TRY(applyVertexBuffers(context, mode, indexTypeOrInvalid, firstVertex));
+
+ return angle::Result::Continue;
+}
+
+angle::Result StateManager11::applyVertexBuffers(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ gl::DrawElementsType indexTypeOrInvalid,
+ GLint firstVertex)
+{
+ bool programUsesInstancedPointSprites =
+ mProgramD3D->usesPointSize() && mProgramD3D->usesInstancedPointSpriteEmulation();
+ bool instancedPointSpritesActive =
+ programUsesInstancedPointSprites && (mode == gl::PrimitiveMode::Points);
+
+ // Note that if we use instance emulation, we reserve the first buffer slot.
+ size_t reservedBuffers = GetReservedBufferCount(programUsesInstancedPointSprites);
+
+ for (size_t attribIndex = 0; attribIndex < (gl::MAX_VERTEX_ATTRIBS - reservedBuffers);
+ ++attribIndex)
+ {
+ ID3D11Buffer *buffer = nullptr;
+ UINT vertexStride = 0;
+ UINT vertexOffset = 0;
+
+ if (attribIndex < mCurrentAttributes.size())
+ {
+ const TranslatedAttribute &attrib = *mCurrentAttributes[attribIndex];
+ Buffer11 *bufferStorage = attrib.storage ? GetAs<Buffer11>(attrib.storage) : nullptr;
+
+ // If indexed pointsprite emulation is active, then we need to take a less efficent code
+ // path. Emulated indexed pointsprite rendering requires that the vertex buffers match
+ // exactly to the indices passed by the caller. This could expand or shrink the vertex
+ // buffer depending on the number of points indicated by the index list or how many
+ // duplicates are found on the index list.
+ if (bufferStorage == nullptr)
+ {
+ ASSERT(attrib.vertexBuffer.get());
+ buffer = GetAs<VertexBuffer11>(attrib.vertexBuffer.get())->getBuffer().get();
+ }
+ else if (instancedPointSpritesActive &&
+ indexTypeOrInvalid != gl::DrawElementsType::InvalidEnum)
+ {
+ ASSERT(mVertexArray11->isCachedIndexInfoValid());
+ TranslatedIndexData indexInfo = mVertexArray11->getCachedIndexInfo();
+ if (indexInfo.srcIndexData.srcBuffer != nullptr)
+ {
+ const uint8_t *bufferData = nullptr;
+ ANGLE_TRY(indexInfo.srcIndexData.srcBuffer->getData(context, &bufferData));
+ ASSERT(bufferData != nullptr);
+
+ ptrdiff_t offset =
+ reinterpret_cast<ptrdiff_t>(indexInfo.srcIndexData.srcIndices);
+ indexInfo.srcIndexData.srcBuffer = nullptr;
+ indexInfo.srcIndexData.srcIndices = bufferData + offset;
+ }
+
+ ANGLE_TRY(bufferStorage->getEmulatedIndexedBuffer(context, &indexInfo.srcIndexData,
+ attrib, firstVertex, &buffer));
+
+ mVertexArray11->updateCachedIndexInfo(indexInfo);
+ }
+ else
+ {
+ ANGLE_TRY(bufferStorage->getBuffer(
+ context, BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK, &buffer));
+ }
+
+ vertexStride = attrib.stride;
+ ANGLE_TRY(attrib.computeOffset(context, firstVertex, &vertexOffset));
+ }
+
+ size_t bufferIndex = reservedBuffers + attribIndex;
+
+ queueVertexBufferChange(bufferIndex, buffer, vertexStride, vertexOffset);
+ }
+
+ Context11 *context11 = GetImplAs<Context11>(context);
+
+ // Instanced PointSprite emulation requires two additional ID3D11Buffers. A vertex buffer needs
+ // to be created and added to the list of current buffers, strides and offsets collections.
+ // This buffer contains the vertices for a single PointSprite quad.
+ // An index buffer also needs to be created and applied because rendering instanced data on
+ // D3D11 FL9_3 requires DrawIndexedInstanced() to be used. Shaders that contain gl_PointSize and
+ // used without the GL_POINTS rendering mode require a vertex buffer because some drivers cannot
+ // handle missing vertex data and will TDR the system.
+ if (programUsesInstancedPointSprites)
+ {
+ constexpr UINT kPointSpriteVertexStride = sizeof(float) * 5;
+
+ if (!mPointSpriteVertexBuffer.valid())
+ {
+ static constexpr float kPointSpriteVertices[] = {
+ // Position | TexCoord
+ -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, /* v0 */
+ -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, /* v1 */
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, /* v2 */
+ 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, /* v3 */
+ -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, /* v4 */
+ 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, /* v5 */
+ };
+
+ D3D11_SUBRESOURCE_DATA vertexBufferData = {kPointSpriteVertices, 0, 0};
+ D3D11_BUFFER_DESC vertexBufferDesc;
+ vertexBufferDesc.ByteWidth = sizeof(kPointSpriteVertices);
+ vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
+ vertexBufferDesc.Usage = D3D11_USAGE_IMMUTABLE;
+ vertexBufferDesc.CPUAccessFlags = 0;
+ vertexBufferDesc.MiscFlags = 0;
+ vertexBufferDesc.StructureByteStride = 0;
+
+ ANGLE_TRY(mRenderer->allocateResource(context11, vertexBufferDesc, &vertexBufferData,
+ &mPointSpriteVertexBuffer));
+ }
+
+ // Set the stride to 0 if GL_POINTS mode is not being used to instruct the driver to avoid
+ // indexing into the vertex buffer.
+ UINT stride = instancedPointSpritesActive ? kPointSpriteVertexStride : 0;
+ queueVertexBufferChange(0, mPointSpriteVertexBuffer.get(), stride, 0);
+
+ if (!mPointSpriteIndexBuffer.valid())
+ {
+ // Create an index buffer and set it for pointsprite rendering
+ static constexpr unsigned short kPointSpriteIndices[] = {
+ 0, 1, 2, 3, 4, 5,
+ };
+
+ D3D11_SUBRESOURCE_DATA indexBufferData = {kPointSpriteIndices, 0, 0};
+ D3D11_BUFFER_DESC indexBufferDesc;
+ indexBufferDesc.ByteWidth = sizeof(kPointSpriteIndices);
+ indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
+ indexBufferDesc.Usage = D3D11_USAGE_IMMUTABLE;
+ indexBufferDesc.CPUAccessFlags = 0;
+ indexBufferDesc.MiscFlags = 0;
+ indexBufferDesc.StructureByteStride = 0;
+
+ ANGLE_TRY(mRenderer->allocateResource(context11, indexBufferDesc, &indexBufferData,
+ &mPointSpriteIndexBuffer));
+ }
+
+ if (instancedPointSpritesActive)
+ {
+ // The index buffer is applied here because Instanced PointSprite emulation uses the a
+ // non-indexed rendering path in ANGLE (DrawArrays). This means that applyIndexBuffer()
+ // on the renderer will not be called and setting this buffer here ensures that the
+ // rendering path will contain the correct index buffers.
+ syncIndexBuffer(mPointSpriteIndexBuffer.get(), DXGI_FORMAT_R16_UINT, 0);
+ }
+ }
+
+ applyVertexBufferChanges();
+ return angle::Result::Continue;
+}
+
+angle::Result StateManager11::applyIndexBuffer(const gl::Context *context,
+ GLsizei indexCount,
+ gl::DrawElementsType indexType,
+ const void *indices)
+{
+ if (!mIndexBufferIsDirty)
+ {
+ // No streaming or index buffer application necessary.
+ return angle::Result::Continue;
+ }
+
+ gl::DrawElementsType destElementType = mVertexArray11->getCachedDestinationIndexType();
+ gl::Buffer *elementArrayBuffer = mVertexArray11->getState().getElementArrayBuffer();
+
+ TranslatedIndexData indexInfo;
+ ANGLE_TRY(mIndexDataManager.prepareIndexData(context, indexType, destElementType, indexCount,
+ elementArrayBuffer, indices, &indexInfo));
+
+ ID3D11Buffer *buffer = nullptr;
+ DXGI_FORMAT bufferFormat = (indexInfo.indexType == gl::DrawElementsType::UnsignedInt)
+ ? DXGI_FORMAT_R32_UINT
+ : DXGI_FORMAT_R16_UINT;
+
+ if (indexInfo.storage)
+ {
+ Buffer11 *storage = GetAs<Buffer11>(indexInfo.storage);
+ ANGLE_TRY(storage->getBuffer(context, BUFFER_USAGE_INDEX, &buffer));
+ }
+ else
+ {
+ IndexBuffer11 *indexBuffer = GetAs<IndexBuffer11>(indexInfo.indexBuffer);
+ buffer = indexBuffer->getBuffer().get();
+ }
+
+ // Track dirty indices in the index range cache.
+ indexInfo.srcIndexData.srcIndicesChanged =
+ syncIndexBuffer(buffer, bufferFormat, indexInfo.startOffset);
+
+ mIndexBufferIsDirty = false;
+
+ mVertexArray11->updateCachedIndexInfo(indexInfo);
+ return angle::Result::Continue;
+}
+
+void StateManager11::setIndexBuffer(ID3D11Buffer *buffer,
+ DXGI_FORMAT indexFormat,
+ unsigned int offset)
+{
+ if (syncIndexBuffer(buffer, indexFormat, offset))
+ {
+ invalidateIndexBuffer();
+ }
+}
+
+bool StateManager11::syncIndexBuffer(ID3D11Buffer *buffer,
+ DXGI_FORMAT indexFormat,
+ unsigned int offset)
+{
+ if (buffer != mAppliedIB || indexFormat != mAppliedIBFormat || offset != mAppliedIBOffset)
+ {
+ mRenderer->getDeviceContext()->IASetIndexBuffer(buffer, indexFormat, offset);
+
+ mAppliedIB = buffer;
+ mAppliedIBFormat = indexFormat;
+ mAppliedIBOffset = offset;
+ return true;
+ }
+
+ return false;
+}
+
+// Vertex buffer is invalidated outside this function.
+angle::Result StateManager11::updateVertexOffsetsForPointSpritesEmulation(
+ const gl::Context *context,
+ GLint startVertex,
+ GLsizei emulatedInstanceId)
+{
+ size_t reservedBuffers = GetReservedBufferCount(true);
+ for (size_t attribIndex = 0; attribIndex < mCurrentAttributes.size(); ++attribIndex)
+ {
+ const auto &attrib = *mCurrentAttributes[attribIndex];
+ size_t bufferIndex = reservedBuffers + attribIndex;
+
+ if (attrib.divisor > 0)
+ {
+ unsigned int offset = 0;
+ ANGLE_TRY(attrib.computeOffset(context, startVertex, &offset));
+ offset += (attrib.stride * (emulatedInstanceId / attrib.divisor));
+ if (offset != mCurrentVertexOffsets[bufferIndex])
+ {
+ invalidateInputLayout();
+ mDirtyVertexBufferRange.extend(static_cast<unsigned int>(bufferIndex));
+ mCurrentVertexOffsets[bufferIndex] = offset;
+ }
+ }
+ }
+
+ applyVertexBufferChanges();
+ return angle::Result::Continue;
+}
+
+angle::Result StateManager11::generateSwizzle(const gl::Context *context, gl::Texture *texture)
+{
+ if (!texture)
+ {
+ return angle::Result::Continue;
+ }
+
+ TextureD3D *textureD3D = GetImplAs<TextureD3D>(texture);
+ ASSERT(textureD3D);
+
+ TextureStorage *texStorage = nullptr;
+ ANGLE_TRY(textureD3D->getNativeTexture(context, &texStorage));
+
+ if (texStorage)
+ {
+ TextureStorage11 *storage11 = GetAs<TextureStorage11>(texStorage);
+ const gl::TextureState &textureState = texture->getTextureState();
+ ANGLE_TRY(storage11->generateSwizzles(context, textureState));
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result StateManager11::generateSwizzlesForShader(const gl::Context *context,
+ gl::ShaderType type)
+{
+ const gl::State &glState = context->getState();
+ const gl::RangeUI samplerRange = mProgramD3D->getUsedSamplerRange(type);
+
+ for (unsigned int i = samplerRange.low(); i < samplerRange.high(); i++)
+ {
+ gl::TextureType textureType = mProgramD3D->getSamplerTextureType(type, i);
+ GLint textureUnit = mProgramD3D->getSamplerMapping(type, i, context->getCaps());
+ if (textureUnit != -1)
+ {
+ gl::Texture *texture = glState.getSamplerTexture(textureUnit, textureType);
+ ASSERT(texture);
+ if (SwizzleRequired(texture->getTextureState()))
+ {
+ ANGLE_TRY(generateSwizzle(context, texture));
+ }
+ }
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result StateManager11::generateSwizzles(const gl::Context *context)
+{
+ ANGLE_TRY(generateSwizzlesForShader(context, gl::ShaderType::Vertex));
+ ANGLE_TRY(generateSwizzlesForShader(context, gl::ShaderType::Fragment));
+ return angle::Result::Continue;
+}
+
+angle::Result StateManager11::applyUniformsForShader(const gl::Context *context,
+ gl::ShaderType shaderType)
+{
+ UniformStorage11 *shaderUniformStorage =
+ GetAs<UniformStorage11>(mProgramD3D->getShaderUniformStorage(shaderType));
+ ASSERT(shaderUniformStorage);
+
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+
+ const d3d11::Buffer *shaderConstantBuffer = nullptr;
+ ANGLE_TRY(shaderUniformStorage->getConstantBuffer(context, mRenderer, &shaderConstantBuffer));
+
+ if (shaderUniformStorage->size() > 0 && mProgramD3D->areShaderUniformsDirty(shaderType))
+ {
+ UpdateUniformBuffer(deviceContext, shaderUniformStorage, shaderConstantBuffer);
+ }
+
+ unsigned int slot = d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DEFAULT_UNIFORM_BLOCK;
+
+ switch (shaderType)
+ {
+ case gl::ShaderType::Vertex:
+ if (mCurrentConstantBufferVS[slot] != shaderConstantBuffer->getSerial())
+ {
+ deviceContext->VSSetConstantBuffers(slot, 1, shaderConstantBuffer->getPointer());
+ mCurrentConstantBufferVS[slot] = shaderConstantBuffer->getSerial();
+ mCurrentConstantBufferVSOffset[slot] = 0;
+ mCurrentConstantBufferVSSize[slot] = 0;
+ }
+ break;
+
+ case gl::ShaderType::Fragment:
+ if (mCurrentConstantBufferPS[slot] != shaderConstantBuffer->getSerial())
+ {
+ deviceContext->PSSetConstantBuffers(slot, 1, shaderConstantBuffer->getPointer());
+ mCurrentConstantBufferPS[slot] = shaderConstantBuffer->getSerial();
+ mCurrentConstantBufferPSOffset[slot] = 0;
+ mCurrentConstantBufferPSSize[slot] = 0;
+ }
+ break;
+
+ // TODO(jiawei.shao@intel.com): apply geometry shader uniforms
+ case gl::ShaderType::Geometry:
+ UNIMPLEMENTED();
+ break;
+
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result StateManager11::applyUniforms(const gl::Context *context)
+{
+ ANGLE_TRY(applyUniformsForShader(context, gl::ShaderType::Vertex));
+ ANGLE_TRY(applyUniformsForShader(context, gl::ShaderType::Fragment));
+ if (mProgramD3D->hasShaderStage(gl::ShaderType::Geometry))
+ {
+ ANGLE_TRY(applyUniformsForShader(context, gl::ShaderType::Geometry));
+ }
+
+ mProgramD3D->markUniformsClean();
+
+ return angle::Result::Continue;
+}
+
+angle::Result StateManager11::applyDriverUniformsForShader(const gl::Context *context,
+ gl::ShaderType shaderType)
+{
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+
+ d3d11::Buffer &shaderDriverConstantBuffer = mShaderDriverConstantBuffers[shaderType];
+ if (!shaderDriverConstantBuffer.valid())
+ {
+ size_t requiredSize = mShaderConstants.getRequiredBufferSize(shaderType);
+
+ D3D11_BUFFER_DESC constantBufferDescription = {};
+ d3d11::InitConstantBufferDesc(&constantBufferDescription, requiredSize);
+ ANGLE_TRY(mRenderer->allocateResource(
+ GetImplAs<Context11>(context), constantBufferDescription, &shaderDriverConstantBuffer));
+
+ ID3D11Buffer *driverConstants = shaderDriverConstantBuffer.get();
+ switch (shaderType)
+ {
+ case gl::ShaderType::Vertex:
+ deviceContext->VSSetConstantBuffers(d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DRIVER, 1,
+ &driverConstants);
+ break;
+
+ case gl::ShaderType::Fragment:
+ deviceContext->PSSetConstantBuffers(d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DRIVER, 1,
+ &driverConstants);
+ break;
+
+ case gl::ShaderType::Geometry:
+ deviceContext->GSSetConstantBuffers(d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DRIVER, 1,
+ &driverConstants);
+ break;
+
+ default:
+ UNREACHABLE();
+ return angle::Result::Continue;
+ }
+ }
+
+ // Sampler metadata and driver constants need to coexist in the same constant buffer to
+ // conserve constant buffer slots. We update both in the constant buffer if needed.
+ ANGLE_TRY(mShaderConstants.updateBuffer(context, mRenderer, shaderType, *mProgramD3D,
+ shaderDriverConstantBuffer));
+
+ return angle::Result::Continue;
+}
+
+angle::Result StateManager11::applyDriverUniforms(const gl::Context *context)
+{
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+
+ ANGLE_TRY(applyDriverUniformsForShader(context, gl::ShaderType::Vertex));
+ ANGLE_TRY(applyDriverUniformsForShader(context, gl::ShaderType::Fragment));
+ if (mProgramD3D->hasShaderStage(gl::ShaderType::Geometry))
+ {
+ ANGLE_TRY(applyDriverUniformsForShader(context, gl::ShaderType::Geometry));
+ }
+
+ // needed for the point sprite geometry shader
+ // GSSetConstantBuffers triggers device removal on 9_3, so we should only call it for ES3.
+ if (mRenderer->isES3Capable())
+ {
+ d3d11::Buffer &driverConstantBufferPS =
+ mShaderDriverConstantBuffers[gl::ShaderType::Fragment];
+ if (mCurrentGeometryConstantBuffer != driverConstantBufferPS.getSerial())
+ {
+ ASSERT(driverConstantBufferPS.valid());
+ deviceContext->GSSetConstantBuffers(0, 1, driverConstantBufferPS.getPointer());
+ mCurrentGeometryConstantBuffer = driverConstantBufferPS.getSerial();
+ }
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result StateManager11::applyComputeUniforms(const gl::Context *context,
+ ProgramD3D *programD3D)
+{
+ UniformStorage11 *computeUniformStorage =
+ GetAs<UniformStorage11>(programD3D->getShaderUniformStorage(gl::ShaderType::Compute));
+ ASSERT(computeUniformStorage);
+
+ const d3d11::Buffer *constantBuffer = nullptr;
+ ANGLE_TRY(computeUniformStorage->getConstantBuffer(context, mRenderer, &constantBuffer));
+
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+
+ if (computeUniformStorage->size() > 0 &&
+ programD3D->areShaderUniformsDirty(gl::ShaderType::Compute))
+ {
+ UpdateUniformBuffer(deviceContext, computeUniformStorage, constantBuffer);
+ programD3D->markUniformsClean();
+ }
+
+ if (mCurrentComputeConstantBuffer != constantBuffer->getSerial())
+ {
+ deviceContext->CSSetConstantBuffers(
+ d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DEFAULT_UNIFORM_BLOCK, 1,
+ constantBuffer->getPointer());
+ mCurrentComputeConstantBuffer = constantBuffer->getSerial();
+ }
+
+ if (!mShaderDriverConstantBuffers[gl::ShaderType::Compute].valid())
+ {
+ size_t requiredSize = mShaderConstants.getRequiredBufferSize(gl::ShaderType::Compute);
+
+ D3D11_BUFFER_DESC constantBufferDescription = {};
+ d3d11::InitConstantBufferDesc(&constantBufferDescription, requiredSize);
+ ANGLE_TRY(
+ mRenderer->allocateResource(GetImplAs<Context11>(context), constantBufferDescription,
+ &mShaderDriverConstantBuffers[gl::ShaderType::Compute]));
+ ID3D11Buffer *buffer = mShaderDriverConstantBuffers[gl::ShaderType::Compute].get();
+ deviceContext->CSSetConstantBuffers(d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DRIVER, 1,
+ &buffer);
+ }
+
+ ANGLE_TRY(mShaderConstants.updateBuffer(context, mRenderer, gl::ShaderType::Compute,
+ *programD3D,
+ mShaderDriverConstantBuffers[gl::ShaderType::Compute]));
+
+ return angle::Result::Continue;
+}
+
+angle::Result StateManager11::syncUniformBuffersForShader(const gl::Context *context,
+ gl::ShaderType shaderType)
+{
+ const auto &glState = context->getState();
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+ ID3D11DeviceContext1 *deviceContext1 = mRenderer->getDeviceContext1IfSupported();
+
+ const auto &shaderUniformBuffers = mProgramD3D->getShaderUniformBufferCache(shaderType);
+
+ for (size_t bufferIndex = 0; bufferIndex < shaderUniformBuffers.size(); ++bufferIndex)
+ {
+ const D3DUBOCache cache = shaderUniformBuffers[bufferIndex];
+ if (cache.binding == -1)
+ {
+ continue;
+ }
+
+ const auto &uniformBuffer = glState.getIndexedUniformBuffer(cache.binding);
+ const GLintptr uniformBufferOffset = uniformBuffer.getOffset();
+ const GLsizeiptr uniformBufferSize = uniformBuffer.getSize();
+
+ if (uniformBuffer.get() == nullptr)
+ {
+ continue;
+ }
+
+ Buffer11 *bufferStorage = GetImplAs<Buffer11>(uniformBuffer.get());
+ const d3d11::Buffer *constantBuffer = nullptr;
+ UINT firstConstant = 0;
+ UINT numConstants = 0;
+
+ ANGLE_TRY(bufferStorage->getConstantBufferRange(context, uniformBufferOffset,
+ uniformBufferSize, &constantBuffer,
+ &firstConstant, &numConstants));
+ ASSERT(constantBuffer);
+
+ switch (shaderType)
+ {
+ case gl::ShaderType::Vertex:
+ {
+ if (mCurrentConstantBufferVS[cache.registerIndex] == constantBuffer->getSerial() &&
+ mCurrentConstantBufferVSOffset[cache.registerIndex] == uniformBufferOffset &&
+ mCurrentConstantBufferVSSize[cache.registerIndex] == uniformBufferSize)
+ {
+ continue;
+ }
+
+ if (firstConstant != 0 && uniformBufferSize != 0)
+ {
+ ASSERT(numConstants != 0);
+ deviceContext1->VSSetConstantBuffers1(cache.registerIndex, 1,
+ constantBuffer->getPointer(),
+ &firstConstant, &numConstants);
+ }
+ else
+ {
+ deviceContext->VSSetConstantBuffers(cache.registerIndex, 1,
+ constantBuffer->getPointer());
+ }
+
+ mCurrentConstantBufferVS[cache.registerIndex] = constantBuffer->getSerial();
+ mCurrentConstantBufferVSOffset[cache.registerIndex] = uniformBufferOffset;
+ mCurrentConstantBufferVSSize[cache.registerIndex] = uniformBufferSize;
+ break;
+ }
+
+ case gl::ShaderType::Fragment:
+ {
+ if (mCurrentConstantBufferPS[cache.registerIndex] == constantBuffer->getSerial() &&
+ mCurrentConstantBufferPSOffset[cache.registerIndex] == uniformBufferOffset &&
+ mCurrentConstantBufferPSSize[cache.registerIndex] == uniformBufferSize)
+ {
+ continue;
+ }
+
+ if (firstConstant != 0 && uniformBufferSize != 0)
+ {
+ deviceContext1->PSSetConstantBuffers1(cache.registerIndex, 1,
+ constantBuffer->getPointer(),
+ &firstConstant, &numConstants);
+ }
+ else
+ {
+ deviceContext->PSSetConstantBuffers(cache.registerIndex, 1,
+ constantBuffer->getPointer());
+ }
+
+ mCurrentConstantBufferPS[cache.registerIndex] = constantBuffer->getSerial();
+ mCurrentConstantBufferPSOffset[cache.registerIndex] = uniformBufferOffset;
+ mCurrentConstantBufferPSSize[cache.registerIndex] = uniformBufferSize;
+ break;
+ }
+
+ case gl::ShaderType::Compute:
+ {
+ if (mCurrentConstantBufferCS[bufferIndex] == constantBuffer->getSerial() &&
+ mCurrentConstantBufferCSOffset[bufferIndex] == uniformBufferOffset &&
+ mCurrentConstantBufferCSSize[bufferIndex] == uniformBufferSize)
+ {
+ continue;
+ }
+
+ if (firstConstant != 0 && uniformBufferSize != 0)
+ {
+ deviceContext1->CSSetConstantBuffers1(cache.registerIndex, 1,
+ constantBuffer->getPointer(),
+ &firstConstant, &numConstants);
+ }
+ else
+ {
+ deviceContext->CSSetConstantBuffers(cache.registerIndex, 1,
+ constantBuffer->getPointer());
+ }
+
+ mCurrentConstantBufferCS[cache.registerIndex] = constantBuffer->getSerial();
+ mCurrentConstantBufferCSOffset[cache.registerIndex] = uniformBufferOffset;
+ mCurrentConstantBufferCSSize[cache.registerIndex] = uniformBufferSize;
+ break;
+ }
+
+ // TODO(jiawei.shao@intel.com): update geometry shader uniform buffers.
+ case gl::ShaderType::Geometry:
+ UNIMPLEMENTED();
+ break;
+
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ const auto &shaderUniformBuffersUseSB =
+ mProgramD3D->getShaderUniformBufferCacheUseSB(shaderType);
+ for (size_t bufferIndex = 0; bufferIndex < shaderUniformBuffersUseSB.size(); ++bufferIndex)
+ {
+ const D3DUBOCacheUseSB cache = shaderUniformBuffersUseSB[bufferIndex];
+ if (cache.binding == -1)
+ {
+ continue;
+ }
+
+ const auto &uniformBuffer = glState.getIndexedUniformBuffer(cache.binding);
+ if (uniformBuffer.get() == nullptr)
+ {
+ continue;
+ }
+ const GLintptr uniformBufferOffset = uniformBuffer.getOffset();
+
+ Buffer11 *bufferStorage = GetImplAs<Buffer11>(uniformBuffer.get());
+ const d3d11::ShaderResourceView *bufferSRV = nullptr;
+ ANGLE_TRY(bufferStorage->getStructuredBufferRangeSRV(
+ context, static_cast<unsigned int>(uniformBufferOffset), cache.byteWidth,
+ cache.structureByteStride, &bufferSRV));
+
+ ASSERT(bufferSRV->valid());
+ setShaderResourceInternal(shaderType, cache.registerIndex, bufferSRV);
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result StateManager11::getUAVsForShaderStorageBuffers(const gl::Context *context,
+ gl::ShaderType shaderType,
+ UAVList *uavList)
+{
+ const gl::State &glState = context->getState();
+ const gl::Program *program = glState.getProgram();
+ angle::FixedVector<Buffer11 *, gl::IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS>
+ previouslyBound;
+ for (size_t blockIndex = 0; blockIndex < program->getActiveShaderStorageBlockCount();
+ blockIndex++)
+ {
+ GLuint binding = program->getShaderStorageBlockBinding(static_cast<GLuint>(blockIndex));
+ const unsigned int registerIndex = mProgramD3D->getShaderStorageBufferRegisterIndex(
+ static_cast<GLuint>(blockIndex), shaderType);
+ // It means this block is active but not statically used.
+ if (registerIndex == GL_INVALID_INDEX)
+ {
+ continue;
+ }
+ const auto &shaderStorageBuffer = glState.getIndexedShaderStorageBuffer(binding);
+ if (shaderStorageBuffer.get() == nullptr)
+ {
+ // We didn't see a driver error like atomic buffer did. But theoretically, the same
+ // thing should be done.
+ setUnorderedAccessViewInternal<d3d11::UnorderedAccessView>(registerIndex, nullptr,
+ uavList);
+ continue;
+ }
+
+ Buffer11 *bufferStorage = GetImplAs<Buffer11>(shaderStorageBuffer.get());
+ if (std::find(previouslyBound.begin(), previouslyBound.end(), bufferStorage) !=
+ previouslyBound.end())
+ {
+ // D3D11 doesn't support binding a buffer multiple times
+ // http://anglebug.com/3032
+ ERR() << "Writing to multiple blocks on the same buffer is not allowed.";
+ return angle::Result::Stop;
+ }
+ previouslyBound.push_back(bufferStorage);
+
+ d3d11::UnorderedAccessView *uavPtr = nullptr;
+ GLsizeiptr viewSize = 0;
+ // Bindings only have a valid size if bound using glBindBufferRange
+ if (shaderStorageBuffer.getSize() > 0)
+ {
+ viewSize = shaderStorageBuffer.getSize();
+ }
+ // We use the buffer size for glBindBufferBase
+ else
+ {
+ viewSize = bufferStorage->getSize();
+ }
+ ANGLE_TRY(bufferStorage->getRawUAVRange(context, shaderStorageBuffer.getOffset(), viewSize,
+ &uavPtr));
+
+ setUnorderedAccessViewInternal(registerIndex, uavPtr, uavList);
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result StateManager11::syncUniformBuffers(const gl::Context *context)
+{
+ mProgramD3D->updateUniformBufferCache(context->getCaps());
+
+ if (mProgramD3D->hasShaderStage(gl::ShaderType::Compute))
+ {
+ ANGLE_TRY(syncUniformBuffersForShader(context, gl::ShaderType::Compute));
+ }
+ else
+ {
+ ANGLE_TRY(syncUniformBuffersForShader(context, gl::ShaderType::Vertex));
+ ANGLE_TRY(syncUniformBuffersForShader(context, gl::ShaderType::Fragment));
+ if (mProgramD3D->hasShaderStage(gl::ShaderType::Geometry))
+ {
+ ANGLE_TRY(syncUniformBuffersForShader(context, gl::ShaderType::Geometry));
+ }
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result StateManager11::getUAVsForAtomicCounterBuffers(const gl::Context *context,
+ gl::ShaderType shaderType,
+ UAVList *uavList)
+{
+ const gl::State &glState = context->getState();
+ const gl::Program *program = glState.getProgram();
+ for (const auto &atomicCounterBuffer : program->getState().getAtomicCounterBuffers())
+ {
+ GLuint binding = atomicCounterBuffer.binding;
+ const auto &buffer = glState.getIndexedAtomicCounterBuffer(binding);
+ const unsigned int registerIndex =
+ mProgramD3D->getAtomicCounterBufferRegisterIndex(binding, shaderType);
+ ASSERT(registerIndex != GL_INVALID_INDEX);
+ if (buffer.get() == nullptr)
+ {
+ // The atomic counter is used in shader. However, there is no buffer binding to it. We
+ // should clear the corresponding UAV in case the previous view type is a texture not a
+ // buffer. Otherwise, below error will be reported. The Unordered Access View dimension
+ // declared in the shader code (BUFFER) does not match the view type bound to slot 0
+ // of the Compute Shader unit (TEXTURE2D).
+ setUnorderedAccessViewInternal<d3d11::UnorderedAccessView>(registerIndex, nullptr,
+ uavList);
+ continue;
+ }
+
+ Buffer11 *bufferStorage = GetImplAs<Buffer11>(buffer.get());
+ // TODO(enrico.galli@intel.com): Check to make sure that we aren't binding the same buffer
+ // multiple times, as this is unsupported by D3D11. http://anglebug.com/3141
+
+ // Bindings only have a valid size if bound using glBindBufferRange. Therefore, we use the
+ // buffer size for glBindBufferBase
+ GLsizeiptr viewSize = (buffer.getSize() > 0) ? buffer.getSize() : bufferStorage->getSize();
+ d3d11::UnorderedAccessView *uavPtr = nullptr;
+ ANGLE_TRY(bufferStorage->getRawUAVRange(context, buffer.getOffset(), viewSize, &uavPtr));
+
+ setUnorderedAccessViewInternal(registerIndex, uavPtr, uavList);
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result StateManager11::getUAVsForShader(const gl::Context *context,
+ gl::ShaderType shaderType,
+ UAVList *uavList)
+{
+ ANGLE_TRY(getUAVsForShaderStorageBuffers(context, shaderType, uavList));
+ ANGLE_TRY(getUAVsForRWImages(context, shaderType, uavList));
+ ANGLE_TRY(getUAVsForAtomicCounterBuffers(context, shaderType, uavList));
+
+ return angle::Result::Continue;
+}
+
+angle::Result StateManager11::syncUAVsForGraphics(const gl::Context *context)
+{
+ UAVList uavList(mRenderer->getNativeCaps().maxImageUnits);
+
+ ANGLE_TRY(getUAVsForShader(context, gl::ShaderType::Fragment, &uavList));
+ ANGLE_TRY(getUAVsForShader(context, gl::ShaderType::Vertex, &uavList));
+
+ if (uavList.highestUsed >= 0)
+ {
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+ UINT baseUAVRegister = static_cast<UINT>(mProgramD3D->getPixelShaderKey().size());
+ deviceContext->OMSetRenderTargetsAndUnorderedAccessViews(
+ D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL, nullptr, nullptr, baseUAVRegister,
+ uavList.highestUsed + 1, uavList.data.data(), nullptr);
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result StateManager11::syncUAVsForCompute(const gl::Context *context)
+{
+ UAVList uavList(mRenderer->getNativeCaps().maxImageUnits);
+
+ ANGLE_TRY(getUAVsForShader(context, gl::ShaderType::Compute, &uavList));
+
+ if (uavList.highestUsed >= 0)
+ {
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+ deviceContext->CSSetUnorderedAccessViews(0, uavList.highestUsed + 1, uavList.data.data(),
+ nullptr);
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result StateManager11::syncTransformFeedbackBuffers(const gl::Context *context)
+{
+ const auto &glState = context->getState();
+
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+
+ // If transform feedback is not active, unbind all buffers
+ if (!glState.isTransformFeedbackActiveUnpaused())
+ {
+ if (mAppliedTFSerial != mEmptySerial)
+ {
+ deviceContext->SOSetTargets(0, nullptr, nullptr);
+ mAppliedTFSerial = mEmptySerial;
+ }
+ return angle::Result::Continue;
+ }
+
+ gl::TransformFeedback *transformFeedback = glState.getCurrentTransformFeedback();
+ TransformFeedback11 *tf11 = GetImplAs<TransformFeedback11>(transformFeedback);
+ if (mAppliedTFSerial == tf11->getSerial() && !tf11->isDirty())
+ {
+ return angle::Result::Continue;
+ }
+
+ const std::vector<ID3D11Buffer *> *soBuffers = nullptr;
+ ANGLE_TRY(tf11->getSOBuffers(context, &soBuffers));
+ const std::vector<UINT> &soOffsets = tf11->getSOBufferOffsets();
+
+ deviceContext->SOSetTargets(tf11->getNumSOBuffers(), soBuffers->data(), soOffsets.data());
+
+ mAppliedTFSerial = tf11->getSerial();
+ tf11->onApply();
+
+ return angle::Result::Continue;
+}
+
+void StateManager11::syncPrimitiveTopology(const gl::State &glState,
+ gl::PrimitiveMode currentDrawMode)
+{
+ D3D11_PRIMITIVE_TOPOLOGY primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED;
+ // Don't cull everything by default, this also resets if we were previously culling
+ mCullEverything = false;
+
+ switch (currentDrawMode)
+ {
+ case gl::PrimitiveMode::Points:
+ {
+ bool usesPointSize = mProgramD3D->usesPointSize();
+
+ // ProgramBinary assumes non-point rendering if gl_PointSize isn't written,
+ // which affects varying interpolation. Since the value of gl_PointSize is
+ // undefined when not written, just skip drawing to avoid unexpected results.
+ if (!usesPointSize && !glState.isTransformFeedbackActiveUnpaused())
+ {
+ // Notify developers of risking undefined behavior.
+ WARN() << "Point rendering without writing to gl_PointSize.";
+ mCullEverything = true;
+ return;
+ }
+
+ // If instanced pointsprites are enabled and the shader uses gl_PointSize, the topology
+ // must be D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST.
+ if (usesPointSize && mRenderer->getFeatures().useInstancedPointSpriteEmulation.enabled)
+ {
+ primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
+ }
+ else
+ {
+ primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST;
+ }
+ break;
+ }
+ case gl::PrimitiveMode::Lines:
+ primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINELIST;
+ break;
+ case gl::PrimitiveMode::LineLoop:
+ primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP;
+ break;
+ case gl::PrimitiveMode::LineStrip:
+ primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP;
+ break;
+ case gl::PrimitiveMode::Triangles:
+ primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
+ mCullEverything = CullsEverything(glState);
+ break;
+ case gl::PrimitiveMode::TriangleStrip:
+ primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
+ mCullEverything = CullsEverything(glState);
+ break;
+ // emulate fans via rewriting index buffer
+ case gl::PrimitiveMode::TriangleFan:
+ primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
+ mCullEverything = CullsEverything(glState);
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ setPrimitiveTopologyInternal(primitiveTopology);
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/StateManager11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/StateManager11.h
new file mode 100644
index 0000000000..d8438a48dc
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/StateManager11.h
@@ -0,0 +1,692 @@
+//
+// 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.
+//
+
+// StateManager11.h: Defines a class for caching D3D11 state
+
+#ifndef LIBANGLE_RENDERER_D3D11_STATEMANAGER11_H_
+#define LIBANGLE_RENDERER_D3D11_STATEMANAGER11_H_
+
+#include <array>
+
+#include "libANGLE/State.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/renderer/d3d/IndexDataManager.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
+#include "libANGLE/renderer/d3d/d3d11/InputLayoutCache.h"
+#include "libANGLE/renderer/d3d/d3d11/Query11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+
+namespace rx
+{
+class Buffer11;
+class DisplayD3D;
+class Framebuffer11;
+struct RenderTargetDesc;
+struct Renderer11DeviceCaps;
+class VertexArray11;
+
+class ShaderConstants11 : angle::NonCopyable
+{
+ public:
+ ShaderConstants11();
+ ~ShaderConstants11();
+
+ void init(const gl::Caps &caps);
+ size_t getRequiredBufferSize(gl::ShaderType shaderType) const;
+ void markDirty();
+
+ void setComputeWorkGroups(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ);
+ void setMultiviewWriteToViewportIndex(GLfloat index);
+ void onViewportChange(const gl::Rectangle &glViewport,
+ const D3D11_VIEWPORT &dxViewport,
+ const gl::Offset &glFragCoordOffset,
+ bool is9_3,
+ bool presentPathFast);
+ bool onFirstVertexChange(GLint firstVertex);
+ void onImageLayerChange(gl::ShaderType shaderType, unsigned int imageIndex, int layer);
+ void onSamplerChange(gl::ShaderType shaderType,
+ unsigned int samplerIndex,
+ const gl::Texture &texture,
+ const gl::SamplerState &samplerState);
+ bool onImageChange(gl::ShaderType shaderType,
+ unsigned int imageIndex,
+ const gl::ImageUnit &imageUnit);
+ void onClipControlChange(bool lowerLeft, bool zeroToOne);
+
+ angle::Result updateBuffer(const gl::Context *context,
+ Renderer11 *renderer,
+ gl::ShaderType shaderType,
+ const ProgramD3D &programD3D,
+ const d3d11::Buffer &driverConstantBuffer);
+
+ private:
+ struct Vertex
+ {
+ Vertex()
+ : depthRange{.0f},
+ viewAdjust{.0f},
+ viewCoords{.0f},
+ viewScale{.0f},
+ multiviewWriteToViewportIndex{.0f},
+ clipControlOrigin{-1.0f},
+ clipControlZeroToOne{.0f},
+ firstVertex{0},
+ padding{.0f, .0f}
+ {}
+
+ float depthRange[4];
+ float viewAdjust[4];
+ float viewCoords[4];
+ float viewScale[2];
+ // multiviewWriteToViewportIndex is used to select either the side-by-side or layered
+ // code-path in the GS. It's value, if set, is either 0.0f or 1.0f. The value is updated
+ // whenever a multi-view draw framebuffer is made active.
+ float multiviewWriteToViewportIndex;
+
+ // EXT_clip_control
+ // Multiplied with Y coordinate: -1.0 for GL_LOWER_LEFT_EXT, 1.0f for GL_UPPER_LEFT_EXT
+ float clipControlOrigin;
+ // 0.0 for GL_NEGATIVE_ONE_TO_ONE_EXT, 1.0 for GL_ZERO_TO_ONE_EXT
+ float clipControlZeroToOne;
+
+ uint32_t firstVertex;
+
+ // Added here to manually pad the struct to 16 byte boundary
+ float padding[2];
+ };
+ static_assert(sizeof(Vertex) % 16u == 0,
+ "D3D11 constant buffers must be multiples of 16 bytes");
+
+ struct Pixel
+ {
+ Pixel()
+ : depthRange{.0f},
+ viewCoords{.0f},
+ depthFront{.0f},
+ fragCoordOffset{.0f},
+ viewScale{.0f},
+ multiviewWriteToViewportIndex{.0f},
+ padding{.0f}
+ {}
+
+ float depthRange[4];
+ float viewCoords[4];
+ float depthFront[4];
+ float fragCoordOffset[2];
+ float viewScale[2];
+ // multiviewWriteToViewportIndex is used to select either the side-by-side or layered
+ // code-path in the GS. It's value, if set, is either 0.0f or 1.0f. The value is updated
+ // whenever a multi-view draw framebuffer is made active.
+ float multiviewWriteToViewportIndex;
+
+ // Added here to manually pad the struct.
+ float padding[3];
+ };
+ static_assert(sizeof(Pixel) % 16u == 0, "D3D11 constant buffers must be multiples of 16 bytes");
+
+ struct Compute
+ {
+ Compute() : numWorkGroups{0u}, padding(0u) {}
+ unsigned int numWorkGroups[3];
+ unsigned int padding; // This just pads the struct to 16 bytes
+ };
+
+ struct SamplerMetadata
+ {
+ SamplerMetadata()
+ : baseLevel(0), internalFormatBits(0), wrapModes(0), padding(0), intBorderColor{0}
+ {}
+
+ int baseLevel;
+ int internalFormatBits;
+ int wrapModes;
+ int padding; // This just pads the struct to 32 bytes
+ int intBorderColor[4];
+ };
+
+ static_assert(sizeof(SamplerMetadata) == 32u,
+ "Sampler metadata struct must be two 4-vec --> 32 bytes.");
+
+ struct ImageMetadata
+ {
+ ImageMetadata() : layer(0), level(0), padding{0} {}
+
+ int layer;
+ unsigned int level;
+ int padding[2]; // This just pads the struct to 16 bytes
+ };
+ static_assert(sizeof(ImageMetadata) == 16u,
+ "Image metadata struct must be one 4-vec --> 16 bytes.");
+
+ static size_t GetShaderConstantsStructSize(gl::ShaderType shaderType);
+
+ // Return true if dirty.
+ bool updateSamplerMetadata(SamplerMetadata *data,
+ const gl::Texture &texture,
+ const gl::SamplerState &samplerState);
+
+ // Return true if dirty.
+ bool updateImageMetadata(ImageMetadata *data, const gl::ImageUnit &imageUnit);
+
+ Vertex mVertex;
+ Pixel mPixel;
+ Compute mCompute;
+ gl::ShaderBitSet mShaderConstantsDirty;
+
+ gl::ShaderMap<std::vector<SamplerMetadata>> mShaderSamplerMetadata;
+ gl::ShaderMap<int> mNumActiveShaderSamplers;
+ gl::ShaderMap<std::vector<ImageMetadata>> mShaderReadonlyImageMetadata;
+ gl::ShaderMap<int> mNumActiveShaderReadonlyImages;
+ gl::ShaderMap<std::vector<ImageMetadata>> mShaderImageMetadata;
+ gl::ShaderMap<int> mNumActiveShaderImages;
+};
+
+class StateManager11 final : angle::NonCopyable
+{
+ public:
+ StateManager11(Renderer11 *renderer);
+ ~StateManager11();
+
+ void deinitialize();
+
+ void syncState(const gl::Context *context,
+ const gl::State::DirtyBits &dirtyBits,
+ gl::Command command);
+
+ angle::Result updateStateForCompute(const gl::Context *context,
+ GLuint numGroupsX,
+ GLuint numGroupsY,
+ GLuint numGroupsZ);
+
+ void updateStencilSizeIfChanged(bool depthStencilInitialized, unsigned int stencilSize);
+
+ // These invalidations methods are called externally.
+
+ // Called from TextureStorage11.
+ void invalidateBoundViews();
+
+ // Called from VertexArray11::updateVertexAttribStorage.
+ void invalidateCurrentValueAttrib(size_t attribIndex);
+
+ // Checks are done on a framebuffer state change to trigger other state changes.
+ // The Context is allowed to be nullptr for these methods, when called in EGL init code.
+ void invalidateRenderTarget();
+
+ // Called by instanced point sprite emulation.
+ void invalidateVertexBuffer();
+
+ // Called by Framebuffer11::syncState for the default sized viewport.
+ void invalidateViewport(const gl::Context *context);
+
+ // Called by TextureStorage11::markLevelDirty.
+ void invalidateSwizzles();
+
+ // Called by the Framebuffer11 and VertexArray11.
+ void invalidateShaders();
+
+ // Called by the Program on Uniform Buffer change. Also called internally.
+ void invalidateProgramUniformBuffers();
+
+ // Called by TransformFeedback11.
+ void invalidateTransformFeedback();
+
+ // Called by VertexArray11.
+ void invalidateInputLayout();
+
+ // Called by VertexArray11 element array buffer sync.
+ void invalidateIndexBuffer();
+
+ // Called by TextureStorage11. Also called internally.
+ void invalidateTexturesAndSamplers();
+
+ void setRenderTarget(ID3D11RenderTargetView *rtv, ID3D11DepthStencilView *dsv);
+ void setRenderTargets(ID3D11RenderTargetView **rtvs, UINT numRtvs, ID3D11DepthStencilView *dsv);
+
+ void onBeginQuery(Query11 *query);
+ void onDeleteQueryObject(Query11 *query);
+ angle::Result onMakeCurrent(const gl::Context *context);
+
+ void setInputLayout(const d3d11::InputLayout *inputLayout);
+
+ void setSingleVertexBuffer(const d3d11::Buffer *buffer, UINT stride, UINT offset);
+
+ angle::Result updateState(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLint firstVertex,
+ GLsizei vertexOrIndexCount,
+ gl::DrawElementsType indexTypeOrInvalid,
+ const void *indices,
+ GLsizei instanceCount,
+ GLint baseVertex,
+ GLuint baseInstance,
+ bool promoteDynamic);
+
+ void setShaderResourceShared(gl::ShaderType shaderType,
+ UINT resourceSlot,
+ const d3d11::SharedSRV *srv);
+ void setShaderResource(gl::ShaderType shaderType,
+ UINT resourceSlot,
+ const d3d11::ShaderResourceView *srv);
+ void setPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY primitiveTopology);
+
+ void setDrawShaders(const d3d11::VertexShader *vertexShader,
+ const d3d11::GeometryShader *geometryShader,
+ const d3d11::PixelShader *pixelShader);
+ void setVertexShader(const d3d11::VertexShader *shader);
+ void setGeometryShader(const d3d11::GeometryShader *shader);
+ void setPixelShader(const d3d11::PixelShader *shader);
+ void setComputeShader(const d3d11::ComputeShader *shader);
+ void setVertexConstantBuffer(unsigned int slot, const d3d11::Buffer *buffer);
+ void setPixelConstantBuffer(unsigned int slot, const d3d11::Buffer *buffer);
+ void setDepthStencilState(const d3d11::DepthStencilState *depthStencilState, UINT stencilRef);
+ void setSimpleBlendState(const d3d11::BlendState *blendState);
+ void setRasterizerState(const d3d11::RasterizerState *rasterizerState);
+ void setSimpleViewport(const gl::Extents &viewportExtents);
+ void setSimpleViewport(int width, int height);
+ void setSimplePixelTextureAndSampler(const d3d11::SharedSRV &srv,
+ const d3d11::SamplerState &samplerState);
+ void setSimpleScissorRect(const gl::Rectangle &glRect);
+ void setScissorRectD3D(const D3D11_RECT &d3dRect);
+
+ void setIndexBuffer(ID3D11Buffer *buffer, DXGI_FORMAT indexFormat, unsigned int offset);
+
+ angle::Result updateVertexOffsetsForPointSpritesEmulation(const gl::Context *context,
+ GLint startVertex,
+ GLsizei emulatedInstanceId);
+
+ // TODO(jmadill): Should be private.
+ angle::Result applyComputeUniforms(const gl::Context *context, ProgramD3D *programD3D);
+
+ // Only used in testing.
+ InputLayoutCache *getInputLayoutCache() { return &mInputLayoutCache; }
+
+ bool getCullEverything() const { return mCullEverything; }
+ VertexDataManager *getVertexDataManager() { return &mVertexDataManager; }
+
+ ProgramD3D *getProgramD3D() const { return mProgramD3D; }
+
+ private:
+ angle::Result ensureInitialized(const gl::Context *context);
+
+ template <typename SRVType>
+ void setShaderResourceInternal(gl::ShaderType shaderType,
+ UINT resourceSlot,
+ const SRVType *srv);
+
+ struct UAVList
+ {
+ UAVList(size_t size) : data(size) {}
+ std::vector<ID3D11UnorderedAccessView *> data;
+ int highestUsed = -1;
+ };
+
+ template <typename UAVType>
+ void setUnorderedAccessViewInternal(UINT resourceSlot, const UAVType *uav, UAVList *uavList);
+
+ void unsetConflictingView(gl::PipelineType pipeline, ID3D11View *view, bool isRenderTarget);
+ void unsetConflictingSRVs(gl::PipelineType pipeline,
+ gl::ShaderType shaderType,
+ uintptr_t resource,
+ const gl::ImageIndex *index,
+ bool isRenderTarget);
+ void unsetConflictingUAVs(gl::PipelineType pipeline,
+ gl::ShaderType shaderType,
+ uintptr_t resource,
+ const gl::ImageIndex *index);
+ void unsetConflictingRTVs(uintptr_t resource);
+
+ void unsetConflictingAttachmentResources(const gl::FramebufferAttachment &attachment,
+ ID3D11Resource *resource);
+
+ angle::Result syncBlendState(const gl::Context *context,
+ const gl::BlendStateExt &blendStateExt,
+ const gl::ColorF &blendColor,
+ unsigned int sampleMask,
+ bool sampleAlphaToCoverage,
+ bool emulateConstantAlpha);
+
+ angle::Result syncDepthStencilState(const gl::Context *context);
+
+ angle::Result syncRasterizerState(const gl::Context *context, gl::PrimitiveMode mode);
+
+ void syncScissorRectangle(const gl::Context *context);
+
+ void syncViewport(const gl::Context *context);
+
+ void checkPresentPath(const gl::Context *context);
+
+ angle::Result syncFramebuffer(const gl::Context *context);
+ angle::Result syncProgram(const gl::Context *context, gl::PrimitiveMode drawMode);
+ angle::Result syncProgramForCompute(const gl::Context *context);
+
+ angle::Result syncTextures(const gl::Context *context);
+ angle::Result applyTexturesForSRVs(const gl::Context *context, gl::ShaderType shaderType);
+ angle::Result applyTexturesForUAVs(const gl::Context *context, gl::ShaderType shaderType);
+ angle::Result syncTexturesForCompute(const gl::Context *context);
+
+ angle::Result setSamplerState(const gl::Context *context,
+ gl::ShaderType type,
+ int index,
+ gl::Texture *texture,
+ const gl::SamplerState &sampler);
+ angle::Result setTextureForSampler(const gl::Context *context,
+ gl::ShaderType type,
+ int index,
+ gl::Texture *texture,
+ const gl::SamplerState &sampler);
+ angle::Result setImageState(const gl::Context *context,
+ gl::ShaderType type,
+ int index,
+ const gl::ImageUnit &imageUnit);
+ angle::Result setTextureForImage(const gl::Context *context,
+ gl::ShaderType type,
+ int index,
+ const gl::ImageUnit &imageUnit);
+ angle::Result getUAVsForRWImages(const gl::Context *context,
+ gl::ShaderType shaderType,
+ UAVList *uavList);
+ angle::Result getUAVForRWImage(const gl::Context *context,
+ gl::ShaderType type,
+ int index,
+ const gl::ImageUnit &imageUnit,
+ UAVList *uavList);
+
+ void handleMultiviewDrawFramebufferChange(const gl::Context *context);
+
+ angle::Result syncCurrentValueAttribs(
+ const gl::Context *context,
+ const std::vector<gl::VertexAttribCurrentValueData> &currentValues);
+
+ angle::Result generateSwizzle(const gl::Context *context, gl::Texture *texture);
+ angle::Result generateSwizzlesForShader(const gl::Context *context, gl::ShaderType type);
+ angle::Result generateSwizzles(const gl::Context *context);
+
+ angle::Result applyDriverUniforms(const gl::Context *context);
+ angle::Result applyDriverUniformsForShader(const gl::Context *context,
+ gl::ShaderType shaderType);
+ angle::Result applyUniforms(const gl::Context *context);
+ angle::Result applyUniformsForShader(const gl::Context *context, gl::ShaderType shaderType);
+
+ angle::Result getUAVsForShaderStorageBuffers(const gl::Context *context,
+ gl::ShaderType shaderType,
+ UAVList *uavList);
+
+ angle::Result syncUniformBuffers(const gl::Context *context);
+ angle::Result syncUniformBuffersForShader(const gl::Context *context,
+ gl::ShaderType shaderType);
+ angle::Result getUAVsForAtomicCounterBuffers(const gl::Context *context,
+ gl::ShaderType shaderType,
+ UAVList *uavList);
+ angle::Result getUAVsForShader(const gl::Context *context,
+ gl::ShaderType shaderType,
+ UAVList *uavList);
+ angle::Result syncUAVsForGraphics(const gl::Context *context);
+ angle::Result syncUAVsForCompute(const gl::Context *context);
+ angle::Result syncTransformFeedbackBuffers(const gl::Context *context);
+
+ // These are currently only called internally.
+ void invalidateDriverUniforms();
+ void invalidateProgramUniforms();
+ void invalidateConstantBuffer(unsigned int slot);
+ void invalidateProgramAtomicCounterBuffers();
+ void invalidateProgramShaderStorageBuffers();
+ void invalidateImageBindings();
+
+ // Called by the Framebuffer11 directly.
+ void processFramebufferInvalidation(const gl::Context *context);
+
+ bool syncIndexBuffer(ID3D11Buffer *buffer, DXGI_FORMAT indexFormat, unsigned int offset);
+ angle::Result syncVertexBuffersAndInputLayout(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLint firstVertex,
+ GLsizei vertexOrIndexCount,
+ gl::DrawElementsType indexTypeOrInvalid,
+ GLsizei instanceCount);
+
+ bool setInputLayoutInternal(const d3d11::InputLayout *inputLayout);
+
+ angle::Result applyVertexBuffers(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ gl::DrawElementsType indexTypeOrInvalid,
+ GLint firstVertex);
+ // TODO(jmadill): Migrate to d3d11::Buffer.
+ bool queueVertexBufferChange(size_t bufferIndex,
+ ID3D11Buffer *buffer,
+ UINT stride,
+ UINT offset);
+ void applyVertexBufferChanges();
+ bool setPrimitiveTopologyInternal(D3D11_PRIMITIVE_TOPOLOGY primitiveTopology);
+ void syncPrimitiveTopology(const gl::State &glState, gl::PrimitiveMode currentDrawMode);
+
+ // Not handled by an internal dirty bit because it isn't synced on drawArrays calls.
+ angle::Result applyIndexBuffer(const gl::Context *context,
+ GLsizei indexCount,
+ gl::DrawElementsType indexType,
+ const void *indices);
+
+ enum DirtyBitType
+ {
+ DIRTY_BIT_RENDER_TARGET,
+ DIRTY_BIT_VIEWPORT_STATE,
+ DIRTY_BIT_SCISSOR_STATE,
+ DIRTY_BIT_RASTERIZER_STATE,
+ DIRTY_BIT_BLEND_STATE,
+ DIRTY_BIT_DEPTH_STENCIL_STATE,
+ // DIRTY_BIT_SHADERS and DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE should be dealt before
+ // DIRTY_BIT_PROGRAM_UNIFORM_BUFFERS for update image layers.
+ DIRTY_BIT_SHADERS,
+ // DIRTY_BIT_GRAPHICS_SRV_STATE and DIRTY_BIT_COMPUTE_SRV_STATE should be lower
+ // bits than DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE.
+ DIRTY_BIT_GRAPHICS_SRV_STATE,
+ DIRTY_BIT_GRAPHICS_UAV_STATE,
+ DIRTY_BIT_COMPUTE_SRV_STATE,
+ DIRTY_BIT_COMPUTE_UAV_STATE,
+ DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE,
+ DIRTY_BIT_PROGRAM_UNIFORMS,
+ DIRTY_BIT_DRIVER_UNIFORMS,
+ DIRTY_BIT_PROGRAM_UNIFORM_BUFFERS,
+ DIRTY_BIT_CURRENT_VALUE_ATTRIBS,
+ DIRTY_BIT_TRANSFORM_FEEDBACK,
+ DIRTY_BIT_VERTEX_BUFFERS_AND_INPUT_LAYOUT,
+ DIRTY_BIT_PRIMITIVE_TOPOLOGY,
+ DIRTY_BIT_INVALID,
+ DIRTY_BIT_MAX = DIRTY_BIT_INVALID,
+ };
+
+ using DirtyBits = angle::BitSet<DIRTY_BIT_MAX>;
+
+ Renderer11 *mRenderer;
+
+ // Internal dirty bits.
+ DirtyBits mInternalDirtyBits;
+ DirtyBits mGraphicsDirtyBitsMask;
+ DirtyBits mComputeDirtyBitsMask;
+
+ bool mCurSampleAlphaToCoverage;
+
+ // Blend State
+ gl::BlendStateExt mCurBlendStateExt;
+ gl::ColorF mCurBlendColor;
+ unsigned int mCurSampleMask;
+
+ // Currently applied depth stencil state
+ gl::DepthStencilState mCurDepthStencilState;
+ int mCurStencilRef;
+ int mCurStencilBackRef;
+ unsigned int mCurStencilSize;
+ Optional<bool> mCurDisableDepth;
+ Optional<bool> mCurDisableStencil;
+
+ // Currently applied rasterizer state
+ gl::RasterizerState mCurRasterState;
+
+ // Currently applied scissor rectangle state
+ bool mCurScissorEnabled;
+ gl::Rectangle mCurScissorRect;
+
+ // Currently applied viewport state
+ gl::Rectangle mCurViewport;
+ float mCurNear;
+ float mCurFar;
+
+ // Currently applied offset to viewport and scissor
+ gl::Offset mCurViewportOffset;
+ gl::Offset mCurScissorOffset;
+
+ // Things needed in viewport state
+ ShaderConstants11 mShaderConstants;
+
+ // Render target variables
+ gl::Extents mViewportBounds;
+ bool mRenderTargetIsDirty;
+
+ // EGL_ANGLE_experimental_present_path variables
+ bool mCurPresentPathFastEnabled;
+ int mCurPresentPathFastColorBufferHeight;
+
+ // Queries that are currently active in this state
+ std::set<Query11 *> mCurrentQueries;
+
+ // Currently applied textures
+ template <typename DescType>
+ struct ViewRecord
+ {
+ uintptr_t view;
+ uintptr_t resource;
+ DescType desc;
+ };
+
+ // A cache of current Views that also tracks the highest 'used' (non-NULL) View.
+ // We might want to investigate a more robust approach that is also fast when there's
+ // a large gap between used Views (e.g. if View 0 and 7 are non-NULL, this approach will
+ // waste time on Views 1-6.)
+ template <typename ViewType, typename DescType>
+ class ViewCache : angle::NonCopyable
+ {
+ public:
+ ViewCache();
+ ~ViewCache();
+
+ void initialize(size_t size) { mCurrentViews.resize(size); }
+
+ size_t size() const { return mCurrentViews.size(); }
+ size_t highestUsed() const { return mHighestUsedView; }
+
+ const ViewRecord<DescType> &operator[](size_t index) const { return mCurrentViews[index]; }
+ void clear();
+ void update(size_t resourceIndex, ViewType *view);
+
+ private:
+ std::vector<ViewRecord<DescType>> mCurrentViews;
+ size_t mHighestUsedView;
+ };
+
+ using SRVCache = ViewCache<ID3D11ShaderResourceView, D3D11_SHADER_RESOURCE_VIEW_DESC>;
+ using UAVCache = ViewCache<ID3D11UnorderedAccessView, D3D11_UNORDERED_ACCESS_VIEW_DESC>;
+ using RTVCache = ViewCache<ID3D11RenderTargetView, D3D11_RENDER_TARGET_VIEW_DESC>;
+ gl::ShaderMap<SRVCache> mCurShaderSRVs;
+ UAVCache mCurComputeUAVs;
+ RTVCache mCurRTVs;
+
+ SRVCache *getSRVCache(gl::ShaderType shaderType);
+
+ // A block of NULL pointers, cached so we don't re-allocate every draw call
+ std::vector<ID3D11ShaderResourceView *> mNullSRVs;
+ std::vector<ID3D11UnorderedAccessView *> mNullUAVs;
+
+ // Current translations of "Current-Value" data - owned by Context, not VertexArray.
+ gl::AttributesMask mDirtyCurrentValueAttribs;
+ std::vector<TranslatedAttribute> mCurrentValueAttribs;
+
+ // Current applied input layout.
+ ResourceSerial mCurrentInputLayout;
+
+ // Current applied vertex states.
+ // TODO(jmadill): Figure out how to use ResourceSerial here.
+ gl::AttribArray<ID3D11Buffer *> mCurrentVertexBuffers;
+ gl::AttribArray<UINT> mCurrentVertexStrides;
+ gl::AttribArray<UINT> mCurrentVertexOffsets;
+ gl::RangeUI mDirtyVertexBufferRange;
+
+ // Currently applied primitive topology
+ D3D11_PRIMITIVE_TOPOLOGY mCurrentPrimitiveTopology;
+ gl::PrimitiveMode mLastAppliedDrawMode;
+ bool mCullEverything;
+
+ // Currently applied shaders
+ gl::ShaderMap<ResourceSerial> mAppliedShaders;
+
+ // Currently applied sampler states
+ gl::ShaderMap<std::vector<bool>> mForceSetShaderSamplerStates;
+ gl::ShaderMap<std::vector<gl::SamplerState>> mCurShaderSamplerStates;
+
+ // Special dirty bit for swizzles. Since they use internal shaders, must be done in a pre-pass.
+ bool mDirtySwizzles;
+
+ // Currently applied index buffer
+ ID3D11Buffer *mAppliedIB;
+ DXGI_FORMAT mAppliedIBFormat;
+ unsigned int mAppliedIBOffset;
+ bool mIndexBufferIsDirty;
+
+ // Vertex, index and input layouts
+ VertexDataManager mVertexDataManager;
+ IndexDataManager mIndexDataManager;
+ InputLayoutCache mInputLayoutCache;
+ std::vector<const TranslatedAttribute *> mCurrentAttributes;
+ Optional<GLint> mLastFirstVertex;
+
+ // ANGLE_multiview.
+ bool mIsMultiviewEnabled;
+
+ bool mIndependentBlendStates;
+
+ // Driver Constants.
+ gl::ShaderMap<d3d11::Buffer> mShaderDriverConstantBuffers;
+
+ ResourceSerial mCurrentComputeConstantBuffer;
+ ResourceSerial mCurrentGeometryConstantBuffer;
+
+ d3d11::Buffer mPointSpriteVertexBuffer;
+ d3d11::Buffer mPointSpriteIndexBuffer;
+
+ template <typename T>
+ using VertexConstantBufferArray =
+ std::array<T, gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS>;
+
+ VertexConstantBufferArray<ResourceSerial> mCurrentConstantBufferVS;
+ VertexConstantBufferArray<GLintptr> mCurrentConstantBufferVSOffset;
+ VertexConstantBufferArray<GLsizeiptr> mCurrentConstantBufferVSSize;
+
+ template <typename T>
+ using FragmentConstantBufferArray =
+ std::array<T, gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS>;
+
+ FragmentConstantBufferArray<ResourceSerial> mCurrentConstantBufferPS;
+ FragmentConstantBufferArray<GLintptr> mCurrentConstantBufferPSOffset;
+ FragmentConstantBufferArray<GLsizeiptr> mCurrentConstantBufferPSSize;
+
+ template <typename T>
+ using ComputeConstantBufferArray =
+ std::array<T, gl::IMPLEMENTATION_MAX_COMPUTE_SHADER_UNIFORM_BUFFERS>;
+
+ ComputeConstantBufferArray<ResourceSerial> mCurrentConstantBufferCS;
+ ComputeConstantBufferArray<GLintptr> mCurrentConstantBufferCSOffset;
+ ComputeConstantBufferArray<GLsizeiptr> mCurrentConstantBufferCSSize;
+
+ // Currently applied transform feedback buffers
+ Serial mAppliedTFSerial;
+
+ Serial mEmptySerial;
+
+ // These objects are cached to avoid having to query the impls.
+ ProgramD3D *mProgramD3D;
+ VertexArray11 *mVertexArray11;
+ Framebuffer11 *mFramebuffer11;
+};
+
+} // namespace rx
+#endif // LIBANGLE_RENDERER_D3D11_STATEMANAGER11_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/StreamProducerD3DTexture.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/StreamProducerD3DTexture.cpp
new file mode 100644
index 0000000000..e77eba71da
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/StreamProducerD3DTexture.cpp
@@ -0,0 +1,166 @@
+//
+// 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.
+//
+
+// StreamProducerD3DTexture.cpp: Implements the stream producer for D3D11 textures
+
+#include "libANGLE/renderer/d3d/d3d11/StreamProducerD3DTexture.h"
+
+#include "common/utilities.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+
+#include <array>
+
+namespace rx
+{
+
+namespace
+{
+
+egl::Error GetGLDescFromTex(ID3D11Texture2D *const tex,
+ const UINT planeIndex,
+ egl::Stream::GLTextureDescription *const out)
+{
+ if (!tex)
+ return egl::EglBadParameter() << "Texture is null";
+
+ D3D11_TEXTURE2D_DESC desc;
+ tex->GetDesc(&desc);
+
+ if (desc.Width < 1 || desc.Height < 1)
+ return egl::EglBadParameter() << "Width or height < 1";
+
+ out->width = desc.Width;
+ out->height = desc.Height;
+ out->mipLevels = 0;
+
+ std::array<uint32_t, 2> planeFormats = {};
+ switch (desc.Format)
+ {
+ case DXGI_FORMAT_NV12:
+ planeFormats = {GL_R8, GL_RG8};
+ break;
+
+ case DXGI_FORMAT_P010:
+ case DXGI_FORMAT_P016:
+ planeFormats = {GL_R16_EXT, GL_RG16_EXT};
+ break;
+
+ case DXGI_FORMAT_R8_UNORM:
+ planeFormats = {GL_R8};
+ break;
+ case DXGI_FORMAT_R8G8_UNORM:
+ planeFormats[0] = GL_RG8;
+ break;
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ planeFormats[0] = GL_RGBA8;
+ break;
+ case DXGI_FORMAT_B8G8R8A8_UNORM:
+ planeFormats[0] = GL_BGRA8_EXT;
+ break;
+
+ case DXGI_FORMAT_R16_UNORM:
+ planeFormats[0] = GL_R16_EXT;
+ break;
+ case DXGI_FORMAT_R16G16_UNORM:
+ planeFormats[0] = GL_RG16_EXT;
+ break;
+ case DXGI_FORMAT_R16G16B16A16_UNORM:
+ planeFormats[0] = GL_RGBA16_EXT;
+ break;
+ case DXGI_FORMAT_R16G16B16A16_FLOAT:
+ planeFormats[0] = GL_RGBA16F;
+ break;
+
+ default:
+ return egl::EglBadParameter() << "Unsupported format";
+ }
+
+ if (planeFormats[1]) // If we have YUV planes, expect 4:2:0.
+ {
+ if ((desc.Width % 2) != 0 || (desc.Height % 2) != 0)
+ return egl::EglBadParameter() << "YUV 4:2:0 textures must have even width and height.";
+ }
+ if (planeIndex > 0)
+ {
+ out->width /= 2;
+ out->height /= 2;
+ }
+
+ out->internalFormat = 0;
+ if (planeIndex < planeFormats.size())
+ {
+ out->internalFormat = planeFormats[planeIndex];
+ }
+ if (!out->internalFormat)
+ return egl::EglBadParameter() << "Plane out of range";
+
+ return egl::NoError();
+}
+
+} // namespace
+
+StreamProducerD3DTexture::StreamProducerD3DTexture(Renderer11 *renderer)
+ : mRenderer(renderer), mTexture(nullptr), mArraySlice(0), mPlaneOffset(0)
+{}
+
+StreamProducerD3DTexture::~StreamProducerD3DTexture()
+{
+ SafeRelease(mTexture);
+}
+
+egl::Error StreamProducerD3DTexture::validateD3DTexture(const void *pointer,
+ const egl::AttributeMap &attributes) const
+{
+ // We must remove the const qualifier because "GetDevice" and "GetDesc" are non-const in D3D11.
+ ID3D11Texture2D *textureD3D = static_cast<ID3D11Texture2D *>(const_cast<void *>(pointer));
+
+ // Check that the texture originated from our device
+ angle::ComPtr<ID3D11Device> device;
+ textureD3D->GetDevice(&device);
+ if (device.Get() != mRenderer->getDevice())
+ {
+ return egl::EglBadParameter() << "Texture not created on ANGLE D3D device";
+ }
+
+ const auto planeId = static_cast<UINT>(attributes.get(EGL_NATIVE_BUFFER_PLANE_OFFSET_IMG, 0));
+ egl::Stream::GLTextureDescription unused;
+ return GetGLDescFromTex(textureD3D, planeId, &unused);
+}
+
+void StreamProducerD3DTexture::postD3DTexture(void *pointer, const egl::AttributeMap &attributes)
+{
+ ASSERT(pointer != nullptr);
+ ID3D11Texture2D *textureD3D = static_cast<ID3D11Texture2D *>(pointer);
+
+ // Release the previous texture if there is one
+ SafeRelease(mTexture);
+
+ mTexture = textureD3D;
+ mTexture->AddRef();
+ mPlaneOffset = static_cast<UINT>(attributes.get(EGL_NATIVE_BUFFER_PLANE_OFFSET_IMG, 0));
+ mArraySlice = static_cast<UINT>(attributes.get(EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE, 0));
+}
+
+egl::Stream::GLTextureDescription StreamProducerD3DTexture::getGLFrameDescription(int planeIndex)
+{
+ const auto planeOffsetIndex = static_cast<UINT>(planeIndex + mPlaneOffset);
+ egl::Stream::GLTextureDescription ret;
+ ANGLE_SWALLOW_ERR(GetGLDescFromTex(mTexture, planeOffsetIndex, &ret));
+ return ret;
+}
+
+ID3D11Texture2D *StreamProducerD3DTexture::getD3DTexture()
+{
+ return mTexture;
+}
+
+UINT StreamProducerD3DTexture::getArraySlice()
+{
+ return mArraySlice;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/StreamProducerD3DTexture.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/StreamProducerD3DTexture.h
new file mode 100644
index 0000000000..bcb0057fde
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/StreamProducerD3DTexture.h
@@ -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.
+//
+
+// StreamProducerD3DTexture.h: Interface for a D3D11 texture stream producer
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_STREAM11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_STREAM11_H_
+
+#include "libANGLE/renderer/StreamProducerImpl.h"
+
+namespace rx
+{
+class Renderer11;
+
+class StreamProducerD3DTexture : public StreamProducerImpl
+{
+ public:
+ StreamProducerD3DTexture(Renderer11 *renderer);
+ ~StreamProducerD3DTexture() override;
+
+ egl::Error validateD3DTexture(const void *pointer,
+ const egl::AttributeMap &attributes) const override;
+ void postD3DTexture(void *pointer, const egl::AttributeMap &attributes) override;
+ egl::Stream::GLTextureDescription getGLFrameDescription(int planeIndex) override;
+
+ // Gets a pointer to the internal D3D texture
+ ID3D11Texture2D *getD3DTexture();
+
+ // Gets the slice index for the D3D texture that the frame is in
+ UINT getArraySlice();
+
+ private:
+ Renderer11 *mRenderer;
+
+ ID3D11Texture2D *mTexture;
+ UINT mArraySlice;
+ UINT mPlaneOffset;
+};
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D11_STREAM11_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
new file mode 100644
index 0000000000..8470510ea8
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
@@ -0,0 +1,1119 @@
+//
+// Copyright 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.
+//
+
+// SwapChain11.cpp: Implements a back-end specific class for the D3D11 swap chain.
+
+#include "libANGLE/renderer/d3d/d3d11/SwapChain11.h"
+
+#include <EGL/eglext.h>
+
+#include "libANGLE/features.h"
+#include "libANGLE/renderer/d3d/DisplayD3D.h"
+#include "libANGLE/renderer/d3d/d3d11/NativeWindow11.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
+#include "libANGLE/trace.h"
+
+// Precompiled shaders
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough2d11vs.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dms11ps.h"
+#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvecolor2dps.h"
+
+#ifdef ANGLE_ENABLE_KEYEDMUTEX
+# define ANGLE_RESOURCE_SHARE_TYPE D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX
+#else
+# define ANGLE_RESOURCE_SHARE_TYPE D3D11_RESOURCE_MISC_SHARED
+#endif
+
+namespace rx
+{
+
+namespace
+{
+// To avoid overflow in QPC to Microseconds calculations, since we multiply
+// by kMicrosecondsPerSecond, then the QPC value should not exceed
+// (2^63 - 1) / 1E6. If it exceeds that threshold, we divide then multiply.
+static constexpr int64_t kQPCOverflowThreshold = 0x8637BD05AF7;
+static constexpr int64_t kMicrosecondsPerSecond = 1000000;
+
+bool NeedsOffscreenTexture(Renderer11 *renderer, NativeWindow11 *nativeWindow, EGLint orientation)
+{
+ // We don't need an offscreen texture if either orientation = INVERT_Y,
+ // or present path fast is enabled and we're not rendering onto an offscreen surface.
+ return orientation != EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE &&
+ !(renderer->presentPathFastEnabled() && nativeWindow->getNativeWindow());
+}
+} // anonymous namespace
+
+SwapChain11::SwapChain11(Renderer11 *renderer,
+ NativeWindow11 *nativeWindow,
+ HANDLE shareHandle,
+ IUnknown *d3dTexture,
+ GLenum backBufferFormat,
+ GLenum depthBufferFormat,
+ EGLint orientation,
+ EGLint samples)
+ : SwapChainD3D(shareHandle, d3dTexture, backBufferFormat, depthBufferFormat),
+ mRenderer(renderer),
+ mWidth(-1),
+ mHeight(-1),
+ mOrientation(orientation),
+ mAppCreatedShareHandle(mShareHandle != nullptr),
+ mSwapInterval(0),
+ mPassThroughResourcesInit(false),
+ mNativeWindow(nativeWindow),
+ mFirstSwap(true),
+ mSwapChain(nullptr),
+ mSwapChain1(nullptr),
+ mKeyedMutex(nullptr),
+ mBackBufferTexture(),
+ mBackBufferRTView(),
+ mBackBufferSRView(),
+ mNeedsOffscreenTexture(NeedsOffscreenTexture(renderer, nativeWindow, orientation)),
+ mOffscreenTexture(),
+ mOffscreenRTView(),
+ mOffscreenSRView(),
+ mNeedsOffscreenTextureCopy(false),
+ mOffscreenTextureCopyForSRV(),
+ mDepthStencilTexture(),
+ mDepthStencilDSView(),
+ mDepthStencilSRView(),
+ mQuadVB(),
+ mPassThroughSampler(),
+ mPassThroughIL(),
+ mPassThroughVS(),
+ mPassThroughOrResolvePS(),
+ mPassThroughRS(),
+ mColorRenderTarget(this, renderer, false),
+ mDepthStencilRenderTarget(this, renderer, true),
+ mEGLSamples(samples)
+{
+ // Check that if present path fast is active then we're using the default orientation
+ ASSERT(!mRenderer->presentPathFastEnabled() || orientation == 0);
+
+ // Get the performance counter
+ LARGE_INTEGER counterFreqency = {};
+ BOOL success = QueryPerformanceFrequency(&counterFreqency);
+ ASSERT(success);
+
+ mQPCFrequency = counterFreqency.QuadPart;
+}
+
+SwapChain11::~SwapChain11()
+{
+ release();
+}
+
+void SwapChain11::release()
+{
+ // TODO(jmadill): Should probably signal that the RenderTarget is dirty.
+
+ SafeRelease(mSwapChain1);
+ SafeRelease(mSwapChain);
+ SafeRelease(mKeyedMutex);
+ mBackBufferTexture.reset();
+ mBackBufferRTView.reset();
+ mBackBufferSRView.reset();
+ mOffscreenTexture.reset();
+ mOffscreenRTView.reset();
+ mOffscreenSRView.reset();
+ mDepthStencilTexture.reset();
+ mDepthStencilDSView.reset();
+ mDepthStencilSRView.reset();
+ mQuadVB.reset();
+ mPassThroughSampler.reset();
+ mPassThroughIL.reset();
+ mPassThroughVS.reset();
+ mPassThroughOrResolvePS.reset();
+ mPassThroughRS.reset();
+
+ if (!mAppCreatedShareHandle)
+ {
+ mShareHandle = nullptr;
+ }
+}
+
+void SwapChain11::releaseOffscreenColorBuffer()
+{
+ mOffscreenTexture.reset();
+ mOffscreenRTView.reset();
+ mOffscreenSRView.reset();
+ mNeedsOffscreenTextureCopy = false;
+ mOffscreenTextureCopyForSRV.reset();
+}
+
+void SwapChain11::releaseOffscreenDepthBuffer()
+{
+ mDepthStencilTexture.reset();
+ mDepthStencilDSView.reset();
+ mDepthStencilSRView.reset();
+}
+
+EGLint SwapChain11::resetOffscreenBuffers(DisplayD3D *displayD3D,
+ int backbufferWidth,
+ int backbufferHeight)
+{
+ if (mNeedsOffscreenTexture)
+ {
+ EGLint result = resetOffscreenColorBuffer(displayD3D, backbufferWidth, backbufferHeight);
+ if (result != EGL_SUCCESS)
+ {
+ return result;
+ }
+ }
+
+ EGLint result = resetOffscreenDepthBuffer(displayD3D, backbufferWidth, backbufferHeight);
+ if (result != EGL_SUCCESS)
+ {
+ return result;
+ }
+
+ mWidth = backbufferWidth;
+ mHeight = backbufferHeight;
+
+ return EGL_SUCCESS;
+}
+
+EGLint SwapChain11::resetOffscreenColorBuffer(DisplayD3D *displayD3D,
+ int backbufferWidth,
+ int backbufferHeight)
+{
+ ASSERT(mNeedsOffscreenTexture);
+
+ ANGLE_TRACE_EVENT0("gpu.angle", "SwapChain11::resetOffscreenTexture");
+ ID3D11Device *device = mRenderer->getDevice();
+
+ ASSERT(device != nullptr);
+
+ // D3D11 does not allow zero size textures
+ ASSERT(backbufferWidth >= 1);
+ ASSERT(backbufferHeight >= 1);
+
+ // Preserve the render target content
+ TextureHelper11 previousOffscreenTexture(std::move(mOffscreenTexture));
+ const int previousWidth = mWidth;
+ const int previousHeight = mHeight;
+
+ releaseOffscreenColorBuffer();
+
+ const d3d11::Format &backbufferFormatInfo =
+ d3d11::Format::Get(mOffscreenRenderTargetFormat, mRenderer->getRenderer11DeviceCaps());
+ D3D11_TEXTURE2D_DESC offscreenTextureDesc = {};
+
+ // If the app passed in a share handle or D3D texture, open the resource
+ // See EGL_ANGLE_d3d_share_handle_client_buffer and EGL_ANGLE_d3d_texture_client_buffer
+ if (mAppCreatedShareHandle || mD3DTexture != nullptr)
+ {
+ if (mAppCreatedShareHandle)
+ {
+ ID3D11Resource *tempResource11;
+ HRESULT result = device->OpenSharedResource(mShareHandle, __uuidof(ID3D11Resource),
+ (void **)&tempResource11);
+ if (FAILED(result) && mRenderer->getDevice1())
+ {
+ result = mRenderer->getDevice1()->OpenSharedResource1(
+ mShareHandle, __uuidof(ID3D11Resource), (void **)&tempResource11);
+ }
+
+ if (FAILED(result))
+ {
+ ERR() << "Could not open shared handle. " << gl::FmtHR(result);
+ release();
+ return EGL_BAD_SURFACE;
+ }
+
+ mOffscreenTexture.set(d3d11::DynamicCastComObject<ID3D11Texture2D>(tempResource11),
+ backbufferFormatInfo);
+ SafeRelease(tempResource11);
+ }
+ else if (mD3DTexture != nullptr)
+ {
+ mOffscreenTexture.set(d3d11::DynamicCastComObject<ID3D11Texture2D>(mD3DTexture),
+ backbufferFormatInfo);
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+ ASSERT(mOffscreenTexture.valid());
+ mOffscreenTexture.getDesc(&offscreenTextureDesc);
+
+ // Fail if the offscreen texture is not renderable.
+ if ((offscreenTextureDesc.BindFlags & D3D11_BIND_RENDER_TARGET) == 0)
+ {
+ ERR() << "Could not use provided offscreen texture, texture not renderable.";
+ release();
+ return EGL_BAD_SURFACE;
+ }
+ }
+ else
+ {
+ const bool useSharedResource =
+ !mNativeWindow->getNativeWindow() && mRenderer->getShareHandleSupport();
+
+ offscreenTextureDesc.Width = backbufferWidth;
+ offscreenTextureDesc.Height = backbufferHeight;
+ offscreenTextureDesc.Format = backbufferFormatInfo.texFormat;
+ offscreenTextureDesc.MipLevels = 1;
+ offscreenTextureDesc.ArraySize = 1;
+ offscreenTextureDesc.SampleDesc.Count = getD3DSamples();
+ offscreenTextureDesc.SampleDesc.Quality = 0;
+ offscreenTextureDesc.Usage = D3D11_USAGE_DEFAULT;
+ offscreenTextureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
+ offscreenTextureDesc.CPUAccessFlags = 0;
+ offscreenTextureDesc.MiscFlags = useSharedResource ? ANGLE_RESOURCE_SHARE_TYPE : 0;
+
+ angle::Result result = mRenderer->allocateTexture(displayD3D, offscreenTextureDesc,
+ backbufferFormatInfo, &mOffscreenTexture);
+ if (result == angle::Result::Stop)
+ {
+ ERR() << "Could not create offscreen texture, " << displayD3D->getStoredErrorString();
+ release();
+ return EGL_BAD_ALLOC;
+ }
+
+ mOffscreenTexture.setInternalName("OffscreenBackBufferTexture");
+
+ // EGL_ANGLE_surface_d3d_texture_2d_share_handle requires that we store a share handle for
+ // the client
+ if (useSharedResource)
+ {
+ IDXGIResource *offscreenTextureResource = nullptr;
+ HRESULT hr = mOffscreenTexture.get()->QueryInterface(
+ __uuidof(IDXGIResource), (void **)&offscreenTextureResource);
+
+ // Fall back to no share handle on failure
+ if (FAILED(hr))
+ {
+ ERR() << "Could not query offscreen texture resource, " << gl::FmtHR(hr);
+ }
+ else
+ {
+ hr = offscreenTextureResource->GetSharedHandle(&mShareHandle);
+ SafeRelease(offscreenTextureResource);
+
+ if (FAILED(hr))
+ {
+ mShareHandle = nullptr;
+ ERR() << "Could not get offscreen texture shared handle, " << gl::FmtHR(hr);
+ }
+ }
+ }
+ }
+
+ // This may return null if the original texture was created without a keyed mutex.
+ mKeyedMutex = d3d11::DynamicCastComObject<IDXGIKeyedMutex>(mOffscreenTexture.get());
+
+ D3D11_RENDER_TARGET_VIEW_DESC offscreenRTVDesc;
+ offscreenRTVDesc.Format = backbufferFormatInfo.rtvFormat;
+ offscreenRTVDesc.ViewDimension =
+ (mEGLSamples <= 1) ? D3D11_RTV_DIMENSION_TEXTURE2D : D3D11_RTV_DIMENSION_TEXTURE2DMS;
+ offscreenRTVDesc.Texture2D.MipSlice = 0;
+
+ angle::Result result = mRenderer->allocateResource(displayD3D, offscreenRTVDesc,
+ mOffscreenTexture.get(), &mOffscreenRTView);
+ if (result == angle::Result::Stop)
+ {
+ ERR() << "Could not create offscreen back buffer render target, "
+ << displayD3D->getStoredErrorString();
+ release();
+ return EGL_BAD_ALLOC;
+ }
+ mOffscreenRTView.setInternalName("OffscreenBackBufferRenderTarget");
+
+ D3D11_SHADER_RESOURCE_VIEW_DESC offscreenSRVDesc;
+ offscreenSRVDesc.Format = backbufferFormatInfo.srvFormat;
+ offscreenSRVDesc.ViewDimension =
+ (mEGLSamples <= 1) ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS;
+ offscreenSRVDesc.Texture2D.MostDetailedMip = 0;
+ offscreenSRVDesc.Texture2D.MipLevels = static_cast<UINT>(-1);
+
+ if (offscreenTextureDesc.BindFlags & D3D11_BIND_SHADER_RESOURCE)
+ {
+ result = mRenderer->allocateResource(displayD3D, offscreenSRVDesc, mOffscreenTexture.get(),
+ &mOffscreenSRView);
+ if (result == angle::Result::Stop)
+ {
+ ERR() << "Could not create offscreen back buffer shader resource, "
+ << displayD3D->getStoredErrorString();
+ release();
+ return EGL_BAD_ALLOC;
+ }
+ mOffscreenSRView.setInternalName("OffscreenBackBufferShaderResource");
+ }
+ else
+ {
+ // Special case for external textures that cannot support sampling. Since internally we
+ // assume our SwapChain is always readable, we make a copy texture that is compatible.
+ mNeedsOffscreenTextureCopy = true;
+ }
+
+ if (previousOffscreenTexture.valid())
+ {
+ D3D11_BOX sourceBox = {};
+ sourceBox.left = 0;
+ sourceBox.right = std::min(previousWidth, backbufferWidth);
+ sourceBox.top = std::max(previousHeight - backbufferHeight, 0);
+ sourceBox.bottom = previousHeight;
+ sourceBox.front = 0;
+ sourceBox.back = 1;
+
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+ const int yoffset = std::max(backbufferHeight - previousHeight, 0);
+ deviceContext->CopySubresourceRegion(mOffscreenTexture.get(), 0, 0, yoffset, 0,
+ previousOffscreenTexture.get(), 0, &sourceBox);
+
+ if (mSwapChain)
+ {
+ swapRect(displayD3D, 0, 0, backbufferWidth, backbufferHeight);
+ }
+ }
+
+ return EGL_SUCCESS;
+}
+
+EGLint SwapChain11::resetOffscreenDepthBuffer(DisplayD3D *displayD3D,
+ int backbufferWidth,
+ int backbufferHeight)
+{
+ releaseOffscreenDepthBuffer();
+
+ if (mDepthBufferFormat != GL_NONE)
+ {
+ const d3d11::Format &depthBufferFormatInfo =
+ d3d11::Format::Get(mDepthBufferFormat, mRenderer->getRenderer11DeviceCaps());
+
+ D3D11_TEXTURE2D_DESC depthStencilTextureDesc;
+ depthStencilTextureDesc.Width = backbufferWidth;
+ depthStencilTextureDesc.Height = backbufferHeight;
+ depthStencilTextureDesc.Format = depthBufferFormatInfo.texFormat;
+ depthStencilTextureDesc.MipLevels = 1;
+ depthStencilTextureDesc.ArraySize = 1;
+ depthStencilTextureDesc.SampleDesc.Count = getD3DSamples();
+ depthStencilTextureDesc.Usage = D3D11_USAGE_DEFAULT;
+ depthStencilTextureDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
+
+ // If there is a multisampled offscreen color texture, the offscreen depth-stencil texture
+ // must also have the same quality value.
+ if (mOffscreenTexture.valid() && getD3DSamples() > 1)
+ {
+ D3D11_TEXTURE2D_DESC offscreenTextureDesc = {};
+ mOffscreenTexture.getDesc(&offscreenTextureDesc);
+ depthStencilTextureDesc.SampleDesc.Quality = offscreenTextureDesc.SampleDesc.Quality;
+ }
+ else
+ {
+ depthStencilTextureDesc.SampleDesc.Quality = 0;
+ }
+
+ // Only create an SRV if it is supported
+ bool depthStencilSRV =
+ depthBufferFormatInfo.srvFormat != DXGI_FORMAT_UNKNOWN &&
+ (mRenderer->getRenderer11DeviceCaps().supportsMultisampledDepthStencilSRVs ||
+ depthStencilTextureDesc.SampleDesc.Count <= 1);
+ if (depthStencilSRV)
+ {
+ depthStencilTextureDesc.BindFlags |= D3D11_BIND_SHADER_RESOURCE;
+ }
+
+ depthStencilTextureDesc.CPUAccessFlags = 0;
+ depthStencilTextureDesc.MiscFlags = 0;
+
+ angle::Result result = mRenderer->allocateTexture(
+ displayD3D, depthStencilTextureDesc, depthBufferFormatInfo, &mDepthStencilTexture);
+ if (result == angle::Result::Stop)
+ {
+ ERR() << "Could not create depthstencil surface for new swap chain, "
+ << displayD3D->getStoredErrorString();
+ release();
+ return EGL_BAD_ALLOC;
+ }
+ mDepthStencilTexture.setInternalName("OffscreenDepthStencilTexture");
+
+ D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilDesc;
+ depthStencilDesc.Format = depthBufferFormatInfo.dsvFormat;
+ depthStencilDesc.ViewDimension =
+ (mEGLSamples <= 1) ? D3D11_DSV_DIMENSION_TEXTURE2D : D3D11_DSV_DIMENSION_TEXTURE2DMS;
+ depthStencilDesc.Flags = 0;
+ depthStencilDesc.Texture2D.MipSlice = 0;
+
+ result = mRenderer->allocateResource(displayD3D, depthStencilDesc,
+ mDepthStencilTexture.get(), &mDepthStencilDSView);
+ ASSERT(result != angle::Result::Stop);
+ mDepthStencilDSView.setInternalName("OffscreenDSV");
+
+ if (depthStencilSRV)
+ {
+ D3D11_SHADER_RESOURCE_VIEW_DESC depthStencilSRVDesc;
+ depthStencilSRVDesc.Format = depthBufferFormatInfo.srvFormat;
+ depthStencilSRVDesc.ViewDimension = (mEGLSamples <= 1)
+ ? D3D11_SRV_DIMENSION_TEXTURE2D
+ : D3D11_SRV_DIMENSION_TEXTURE2DMS;
+ depthStencilSRVDesc.Texture2D.MostDetailedMip = 0;
+ depthStencilSRVDesc.Texture2D.MipLevels = static_cast<UINT>(-1);
+
+ result = mRenderer->allocateResource(displayD3D, depthStencilSRVDesc,
+ mDepthStencilTexture.get(), &mDepthStencilSRView);
+ ASSERT(result != angle::Result::Stop);
+ mDepthStencilSRView.setInternalName("OffscreenDepthStencilSRV");
+ }
+ }
+
+ return EGL_SUCCESS;
+}
+
+EGLint SwapChain11::resize(DisplayD3D *displayD3D, EGLint backbufferWidth, EGLint backbufferHeight)
+{
+ ANGLE_TRACE_EVENT0("gpu.angle", "SwapChain11::resize");
+ ID3D11Device *device = mRenderer->getDevice();
+
+ if (device == nullptr)
+ {
+ return EGL_BAD_ACCESS;
+ }
+
+ // EGL allows creating a surface with 0x0 dimension, however, DXGI does not like 0x0 swapchains
+ if (backbufferWidth < 1 || backbufferHeight < 1)
+ {
+ return EGL_SUCCESS;
+ }
+
+ // Don't resize unnecessarily
+ if (mWidth == backbufferWidth && mHeight == backbufferHeight)
+ {
+ return EGL_SUCCESS;
+ }
+
+ // Can only call resize if we have already created our swap buffer and resources
+ ASSERT(mSwapChain && mBackBufferTexture.valid() && mBackBufferRTView.valid() &&
+ mBackBufferSRView.valid());
+
+ mBackBufferTexture.reset();
+ mBackBufferRTView.reset();
+ mBackBufferSRView.reset();
+
+ // Resize swap chain
+ DXGI_SWAP_CHAIN_DESC desc;
+ HRESULT hr = mSwapChain->GetDesc(&desc);
+ if (FAILED(hr))
+ {
+ ERR() << "Error reading swap chain description, " << gl::FmtHR(hr);
+ release();
+ return EGL_BAD_ALLOC;
+ }
+
+ hr = mSwapChain->ResizeBuffers(desc.BufferCount, backbufferWidth, backbufferHeight,
+ getSwapChainNativeFormat(), 0);
+
+ if (FAILED(hr))
+ {
+ ERR() << "Error resizing swap chain buffers, " << gl::FmtHR(hr);
+ release();
+
+ if (d3d11::isDeviceLostError(hr))
+ {
+ HRESULT reason = device->GetDeviceRemovedReason();
+ ERR() << "Device lost in SwapChain11::resize " << gl::FmtHR(hr)
+ << ", reason: " << gl::FmtHR(reason);
+ return EGL_CONTEXT_LOST;
+ }
+ else
+ {
+ return EGL_BAD_ALLOC;
+ }
+ }
+
+ ID3D11Texture2D *backbufferTexture = nullptr;
+ hr = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D),
+ reinterpret_cast<void **>(&backbufferTexture));
+ ASSERT(SUCCEEDED(hr));
+ if (SUCCEEDED(hr))
+ {
+ const auto &format =
+ d3d11::Format::Get(mOffscreenRenderTargetFormat, mRenderer->getRenderer11DeviceCaps());
+ mBackBufferTexture.set(backbufferTexture, format);
+ mBackBufferTexture.setInternalName("BackBufferTexture");
+
+ angle::Result result = mRenderer->allocateResourceNoDesc(
+ displayD3D, mBackBufferTexture.get(), &mBackBufferRTView);
+ ASSERT(result != angle::Result::Stop);
+ mBackBufferRTView.setInternalName("BackBufferRTV");
+
+ result = mRenderer->allocateResourceNoDesc(displayD3D, mBackBufferTexture.get(),
+ &mBackBufferSRView);
+ ASSERT(result != angle::Result::Stop);
+ mBackBufferSRView.setInternalName("BackBufferSRV");
+ }
+
+ mFirstSwap = true;
+
+ return resetOffscreenBuffers(displayD3D, backbufferWidth, backbufferHeight);
+}
+
+DXGI_FORMAT SwapChain11::getSwapChainNativeFormat() const
+{
+ // Return a render target format for offscreen rendering is supported by IDXGISwapChain.
+ // MSDN https://msdn.microsoft.com/en-us/library/windows/desktop/bb173064(v=vs.85).aspx
+ switch (mOffscreenRenderTargetFormat)
+ {
+ case GL_RGBA8:
+ case GL_RGBA4:
+ case GL_RGB5_A1:
+ case GL_RGB8:
+ case GL_RGB565:
+ return DXGI_FORMAT_R8G8B8A8_UNORM;
+
+ case GL_BGRA8_EXT:
+ return DXGI_FORMAT_B8G8R8A8_UNORM;
+
+ case GL_RGB10_A2:
+ return DXGI_FORMAT_R10G10B10A2_UNORM;
+
+ case GL_RGBA16F:
+ return DXGI_FORMAT_R16G16B16A16_FLOAT;
+
+ default:
+ UNREACHABLE();
+ return DXGI_FORMAT_UNKNOWN;
+ }
+}
+
+EGLint SwapChain11::reset(DisplayD3D *displayD3D,
+ EGLint backbufferWidth,
+ EGLint backbufferHeight,
+ EGLint swapInterval)
+{
+ mSwapInterval = static_cast<unsigned int>(swapInterval);
+ if (mSwapInterval > 4)
+ {
+ // IDXGISwapChain::Present documentation states that valid sync intervals are in the [0,4]
+ // range
+ return EGL_BAD_PARAMETER;
+ }
+
+ // If the swap chain already exists, just resize
+ if (mSwapChain != nullptr)
+ {
+ return resize(displayD3D, backbufferWidth, backbufferHeight);
+ }
+
+ ANGLE_TRACE_EVENT0("gpu.angle", "SwapChain11::reset");
+ ID3D11Device *device = mRenderer->getDevice();
+
+ if (device == nullptr)
+ {
+ return EGL_BAD_ACCESS;
+ }
+
+ // Release specific resources to free up memory for the new render target, while the
+ // old render target still exists for the purpose of preserving its contents.
+ SafeRelease(mSwapChain1);
+ SafeRelease(mSwapChain);
+ mBackBufferTexture.reset();
+ mBackBufferRTView.reset();
+
+ // EGL allows creating a surface with 0x0 dimension, however, DXGI does not like 0x0 swapchains
+ if (backbufferWidth < 1 || backbufferHeight < 1)
+ {
+ releaseOffscreenColorBuffer();
+ return EGL_SUCCESS;
+ }
+
+ if (mNativeWindow->getNativeWindow())
+ {
+ HRESULT hr = mNativeWindow->createSwapChain(
+ device, mRenderer->getDxgiFactory(), getSwapChainNativeFormat(), backbufferWidth,
+ backbufferHeight, mNeedsOffscreenTexture ? 1 : getD3DSamples(), &mSwapChain);
+
+ if (FAILED(hr))
+ {
+ ERR() << "Could not create additional swap chains or offscreen surfaces, "
+ << gl::FmtHR(hr);
+ release();
+
+ if (d3d11::isDeviceLostError(hr))
+ {
+ HRESULT reason = device->GetDeviceRemovedReason();
+ ERR() << "Device lost in SwapChain11::reset " << gl::FmtHR(hr)
+ << ", reason: " << gl::FmtHR(reason);
+ return EGL_CONTEXT_LOST;
+ }
+ else
+ {
+ return EGL_BAD_ALLOC;
+ }
+ }
+
+ if (mRenderer->getRenderer11DeviceCaps().supportsDXGI1_2)
+ {
+ mSwapChain1 = d3d11::DynamicCastComObject<IDXGISwapChain1>(mSwapChain);
+ }
+
+ ID3D11Texture2D *backbufferTex = nullptr;
+ hr = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D),
+ reinterpret_cast<LPVOID *>(&backbufferTex));
+ ASSERT(SUCCEEDED(hr));
+ const auto &format =
+ d3d11::Format::Get(mOffscreenRenderTargetFormat, mRenderer->getRenderer11DeviceCaps());
+ mBackBufferTexture.set(backbufferTex, format);
+ mBackBufferTexture.setInternalName("BackBufferTexture");
+
+ angle::Result result = mRenderer->allocateResourceNoDesc(
+ displayD3D, mBackBufferTexture.get(), &mBackBufferRTView);
+ ASSERT(result != angle::Result::Stop);
+ mBackBufferRTView.setInternalName("BackBufferRTV");
+
+ result = mRenderer->allocateResourceNoDesc(displayD3D, mBackBufferTexture.get(),
+ &mBackBufferSRView);
+ ASSERT(result != angle::Result::Stop);
+ mBackBufferSRView.setInternalName("BackBufferSRV");
+ }
+
+ mFirstSwap = true;
+
+ return resetOffscreenBuffers(displayD3D, backbufferWidth, backbufferHeight);
+}
+
+angle::Result SwapChain11::initPassThroughResources(DisplayD3D *displayD3D)
+{
+ if (mPassThroughResourcesInit)
+ {
+ return angle::Result::Continue;
+ }
+
+ ANGLE_TRACE_EVENT0("gpu.angle", "SwapChain11::initPassThroughResources");
+ ID3D11Device *device = mRenderer->getDevice();
+
+ ASSERT(device != nullptr);
+
+ // Make sure our resources are all not allocated, when we create
+ ASSERT(!mQuadVB.valid() && !mPassThroughSampler.valid());
+ ASSERT(!mPassThroughIL.valid() && !mPassThroughVS.valid() && !mPassThroughOrResolvePS.valid());
+
+ D3D11_BUFFER_DESC vbDesc;
+ vbDesc.ByteWidth = sizeof(d3d11::PositionTexCoordVertex) * 4;
+ vbDesc.Usage = D3D11_USAGE_DYNAMIC;
+ vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
+ vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+ vbDesc.MiscFlags = 0;
+ vbDesc.StructureByteStride = 0;
+
+ ANGLE_TRY(mRenderer->allocateResource(displayD3D, vbDesc, &mQuadVB));
+ mQuadVB.setInternalName("SwapChainQuadVB");
+
+ D3D11_SAMPLER_DESC samplerDesc;
+ samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
+ samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
+ samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
+ samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
+ samplerDesc.MipLODBias = 0.0f;
+ samplerDesc.MaxAnisotropy = 0;
+ samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
+ samplerDesc.BorderColor[0] = 0.0f;
+ samplerDesc.BorderColor[1] = 0.0f;
+ samplerDesc.BorderColor[2] = 0.0f;
+ samplerDesc.BorderColor[3] = 0.0f;
+ samplerDesc.MinLOD = 0;
+ samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
+
+ ANGLE_TRY(mRenderer->allocateResource(displayD3D, samplerDesc, &mPassThroughSampler));
+ mPassThroughSampler.setInternalName("SwapChainPassThroughSampler");
+
+ D3D11_INPUT_ELEMENT_DESC quadLayout[] = {
+ {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
+ {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0},
+ };
+
+ InputElementArray quadElements(quadLayout);
+ ShaderData vertexShaderData(g_VS_Passthrough2D);
+
+ ANGLE_TRY(
+ mRenderer->allocateResource(displayD3D, quadElements, &vertexShaderData, &mPassThroughIL));
+ mPassThroughIL.setInternalName("SwapChainPassThroughIL");
+
+ ANGLE_TRY(mRenderer->allocateResource(displayD3D, vertexShaderData, &mPassThroughVS));
+ mPassThroughVS.setInternalName("SwapChainPassThroughVS");
+
+ if (mEGLSamples <= 1)
+ {
+ ShaderData pixelShaderData(g_PS_PassthroughRGBA2D);
+ ANGLE_TRY(
+ mRenderer->allocateResource(displayD3D, pixelShaderData, &mPassThroughOrResolvePS));
+ }
+ else
+ {
+ if (mNativeWindow->getNativeWindow() && mNeedsOffscreenTexture)
+ {
+ ShaderData pixelShaderData(g_PS_ResolveColor2D);
+ ANGLE_TRY(
+ mRenderer->allocateResource(displayD3D, pixelShaderData, &mPassThroughOrResolvePS));
+ }
+ else
+ {
+ ShaderData pixelShaderData(g_PS_PassthroughRGBA2DMS);
+ ANGLE_TRY(
+ mRenderer->allocateResource(displayD3D, pixelShaderData, &mPassThroughOrResolvePS));
+ }
+ }
+
+ mPassThroughOrResolvePS.setInternalName("SwapChainPassThroughPS");
+
+ // Use the default rasterizer state but without culling
+ D3D11_RASTERIZER_DESC rasterizerDesc;
+ rasterizerDesc.FillMode = D3D11_FILL_SOLID;
+ rasterizerDesc.CullMode = D3D11_CULL_NONE;
+ rasterizerDesc.FrontCounterClockwise = FALSE;
+ rasterizerDesc.DepthBias = 0;
+ rasterizerDesc.SlopeScaledDepthBias = 0.0f;
+ rasterizerDesc.DepthBiasClamp = 0.0f;
+ rasterizerDesc.DepthClipEnable = TRUE;
+ rasterizerDesc.ScissorEnable = FALSE;
+ rasterizerDesc.MultisampleEnable = FALSE;
+ rasterizerDesc.AntialiasedLineEnable = FALSE;
+
+ ANGLE_TRY(mRenderer->allocateResource(displayD3D, rasterizerDesc, &mPassThroughRS));
+ mPassThroughRS.setInternalName("SwapChainPassThroughRasterizerState");
+
+ mPassThroughResourcesInit = true;
+ return angle::Result::Continue;
+}
+
+// parameters should be validated/clamped by caller
+EGLint SwapChain11::swapRect(DisplayD3D *displayD3D,
+ EGLint x,
+ EGLint y,
+ EGLint width,
+ EGLint height)
+{
+ if (mNeedsOffscreenTexture)
+ {
+ EGLint result = copyOffscreenToBackbuffer(displayD3D, x, y, width, height);
+ if (result != EGL_SUCCESS)
+ {
+ return result;
+ }
+ }
+
+ EGLint result = present(displayD3D, x, y, width, height);
+ if (result != EGL_SUCCESS)
+ {
+ return result;
+ }
+
+ mRenderer->onSwap();
+
+ return EGL_SUCCESS;
+}
+
+EGLint SwapChain11::copyOffscreenToBackbuffer(DisplayD3D *displayD3D,
+ EGLint x,
+ EGLint y,
+ EGLint width,
+ EGLint height)
+{
+ if (!mSwapChain)
+ {
+ return EGL_SUCCESS;
+ }
+
+ if (initPassThroughResources(displayD3D) == angle::Result::Stop)
+ {
+ return EGL_BAD_ALLOC;
+ }
+
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+
+ // Set vertices
+ D3D11_MAPPED_SUBRESOURCE mappedResource;
+ HRESULT result =
+ deviceContext->Map(mQuadVB.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
+ if (FAILED(result))
+ {
+ return EGL_BAD_ACCESS;
+ }
+
+ d3d11::PositionTexCoordVertex *vertices =
+ static_cast<d3d11::PositionTexCoordVertex *>(mappedResource.pData);
+
+ // Create a quad in homogeneous coordinates
+ float x1 = (x / float(mWidth)) * 2.0f - 1.0f;
+ float y1 = (y / float(mHeight)) * 2.0f - 1.0f;
+ float x2 = ((x + width) / float(mWidth)) * 2.0f - 1.0f;
+ float y2 = ((y + height) / float(mHeight)) * 2.0f - 1.0f;
+
+ float u1 = x / float(mWidth);
+ float v1 = y / float(mHeight);
+ float u2 = (x + width) / float(mWidth);
+ float v2 = (y + height) / float(mHeight);
+
+ // Invert the quad vertices depending on the surface orientation.
+ if ((mOrientation & EGL_SURFACE_ORIENTATION_INVERT_X_ANGLE) != 0)
+ {
+ std::swap(x1, x2);
+ }
+ if ((mOrientation & EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE) != 0)
+ {
+ std::swap(y1, y2);
+ }
+
+ d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, u1, v1);
+ d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, u1, v2);
+ d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, u2, v1);
+ d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, u2, v2);
+
+ deviceContext->Unmap(mQuadVB.get(), 0);
+
+ StateManager11 *stateManager = mRenderer->getStateManager();
+
+ constexpr UINT stride = sizeof(d3d11::PositionTexCoordVertex);
+ stateManager->setSingleVertexBuffer(&mQuadVB, stride, 0);
+
+ // Apply state
+ stateManager->setDepthStencilState(nullptr, 0xFFFFFFFF);
+ stateManager->setSimpleBlendState(nullptr);
+ stateManager->setRasterizerState(&mPassThroughRS);
+
+ // Apply shaders
+ stateManager->setInputLayout(&mPassThroughIL);
+ stateManager->setPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
+ stateManager->setDrawShaders(&mPassThroughVS, nullptr, &mPassThroughOrResolvePS);
+
+ // Apply render targets. Use the proxy context in display.
+ stateManager->setRenderTarget(mBackBufferRTView.get(), nullptr);
+
+ // Set the viewport
+ stateManager->setSimpleViewport(mWidth, mHeight);
+
+ // Apply textures
+ stateManager->setSimplePixelTextureAndSampler(mOffscreenSRView, mPassThroughSampler);
+
+ // Draw
+ deviceContext->Draw(4, 0);
+
+ return EGL_SUCCESS;
+}
+
+EGLint SwapChain11::present(DisplayD3D *displayD3D, EGLint x, EGLint y, EGLint width, EGLint height)
+{
+ if (!mSwapChain)
+ {
+ return EGL_SUCCESS;
+ }
+
+ UINT swapInterval = mSwapInterval;
+#if ANGLE_VSYNC == ANGLE_DISABLED
+ swapInterval = 0;
+#endif
+
+ HRESULT result = S_OK;
+
+ // Use IDXGISwapChain1::Present1 with a dirty rect if DXGI 1.2 is available.
+ // Dirty rect present is not supported with a multisampled swapchain.
+ if (mSwapChain1 != nullptr && mEGLSamples <= 1)
+ {
+ if (mFirstSwap)
+ {
+ // Can't swap with a dirty rect if this swap chain has never swapped before
+ DXGI_PRESENT_PARAMETERS params = {0, nullptr, nullptr, nullptr};
+ result = mSwapChain1->Present1(swapInterval, 0, &params);
+ }
+ else
+ {
+ RECT rect = {static_cast<LONG>(x), static_cast<LONG>(mHeight - y - height),
+ static_cast<LONG>(x + width), static_cast<LONG>(mHeight - y)};
+ DXGI_PRESENT_PARAMETERS params = {1, &rect, nullptr, nullptr};
+ result = mSwapChain1->Present1(swapInterval, 0, &params);
+ }
+ }
+ else
+ {
+ result = mSwapChain->Present(swapInterval, 0);
+ }
+
+ mFirstSwap = false;
+
+ // Some swapping mechanisms such as DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL unbind the current render
+ // target. Mark it dirty. Use the proxy context in display since there is none available.
+ mRenderer->getStateManager()->invalidateRenderTarget();
+
+ if (result == DXGI_ERROR_DEVICE_REMOVED)
+ {
+ ERR() << "Present failed: the D3D11 device was removed, "
+ << gl::FmtHR(mRenderer->getDevice()->GetDeviceRemovedReason());
+ return EGL_CONTEXT_LOST;
+ }
+ else if (result == DXGI_ERROR_DEVICE_RESET)
+ {
+ ERR() << "Present failed: the D3D11 device was reset from a bad command.";
+ return EGL_CONTEXT_LOST;
+ }
+ else if (FAILED(result))
+ {
+ ERR() << "Present failed with " << gl::FmtHR(result);
+ }
+
+ mNativeWindow->commitChange();
+
+ return EGL_SUCCESS;
+}
+
+const TextureHelper11 &SwapChain11::getOffscreenTexture()
+{
+ return mNeedsOffscreenTexture ? mOffscreenTexture : mBackBufferTexture;
+}
+
+const d3d11::RenderTargetView &SwapChain11::getRenderTarget()
+{
+ return mNeedsOffscreenTexture ? mOffscreenRTView : mBackBufferRTView;
+}
+
+angle::Result SwapChain11::getRenderTargetShaderResource(d3d::Context *context,
+ const d3d11::SharedSRV **outSRV)
+{
+ *outSRV = nullptr;
+
+ if (!mNeedsOffscreenTexture)
+ {
+ ASSERT(mBackBufferSRView.valid());
+ *outSRV = &mBackBufferSRView;
+ return angle::Result::Continue;
+ }
+
+ if (!mNeedsOffscreenTextureCopy)
+ {
+ ASSERT(mOffscreenSRView.valid());
+ *outSRV = &mOffscreenSRView;
+ return angle::Result::Continue;
+ }
+
+ if (!mOffscreenTextureCopyForSRV.valid())
+ {
+ const d3d11::Format &backbufferFormatInfo =
+ d3d11::Format::Get(mOffscreenRenderTargetFormat, mRenderer->getRenderer11DeviceCaps());
+
+ D3D11_TEXTURE2D_DESC offscreenCopyDesc;
+ mOffscreenTexture.getDesc(&offscreenCopyDesc);
+
+ offscreenCopyDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
+ offscreenCopyDesc.MiscFlags = 0;
+ offscreenCopyDesc.CPUAccessFlags = 0;
+ TextureHelper11 offscreenTextureCopyForSRV;
+ ANGLE_TRY(mRenderer->allocateTexture(context, offscreenCopyDesc, backbufferFormatInfo,
+ &offscreenTextureCopyForSRV));
+ offscreenTextureCopyForSRV.setInternalName("OffscreenBackBufferCopyForSRV");
+
+ D3D11_SHADER_RESOURCE_VIEW_DESC offscreenSRVDesc;
+ offscreenSRVDesc.Format = backbufferFormatInfo.srvFormat;
+ offscreenSRVDesc.ViewDimension =
+ (mEGLSamples <= 1) ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS;
+ offscreenSRVDesc.Texture2D.MostDetailedMip = 0;
+ offscreenSRVDesc.Texture2D.MipLevels = static_cast<UINT>(-1);
+
+ d3d11::SharedSRV offscreenSRView;
+ ANGLE_TRY(mRenderer->allocateResource(context, offscreenSRVDesc,
+ offscreenTextureCopyForSRV.get(), &offscreenSRView));
+ offscreenSRView.setInternalName("OffscreenBackBufferSRV");
+
+ // Commit created objects in one step so we don't end up with half baked member variables.
+ mOffscreenTextureCopyForSRV = std::move(offscreenTextureCopyForSRV);
+ mOffscreenSRView = std::move(offscreenSRView);
+ }
+
+ // Need to copy the offscreen texture into the shader-readable copy, since it's external and
+ // we don't know if the copy is up-to-date. This works around the problem we have when the app
+ // passes in a texture that isn't shader-readable.
+ mRenderer->getDeviceContext()->CopyResource(mOffscreenTextureCopyForSRV.get(),
+ mOffscreenTexture.get());
+ *outSRV = &mOffscreenSRView;
+ return angle::Result::Continue;
+}
+
+const d3d11::DepthStencilView &SwapChain11::getDepthStencil()
+{
+ return mDepthStencilDSView;
+}
+
+const d3d11::SharedSRV &SwapChain11::getDepthStencilShaderResource()
+{
+ return mDepthStencilSRView;
+}
+
+const TextureHelper11 &SwapChain11::getDepthStencilTexture()
+{
+ return mDepthStencilTexture;
+}
+
+void *SwapChain11::getKeyedMutex()
+{
+ return mKeyedMutex;
+}
+
+void SwapChain11::recreate()
+{
+ // possibly should use this method instead of reset
+}
+
+RenderTargetD3D *SwapChain11::getColorRenderTarget()
+{
+ return &mColorRenderTarget;
+}
+
+RenderTargetD3D *SwapChain11::getDepthStencilRenderTarget()
+{
+ return &mDepthStencilRenderTarget;
+}
+
+egl::Error SwapChain11::getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc)
+{
+ if (!mSwapChain)
+ {
+ return egl::EglNotInitialized() << "Swap chain uninitialized";
+ }
+
+ DXGI_FRAME_STATISTICS stats = {};
+ HRESULT result = mSwapChain->GetFrameStatistics(&stats);
+
+ if (FAILED(result))
+ {
+ return egl::EglBadAlloc() << "Failed to get frame statistics, " << gl::FmtHR(result);
+ }
+
+ // Conversion from DXGI_FRAME_STATISTICS to the output values:
+ // stats.SyncRefreshCount -> msc
+ // stats.PresentCount -> sbc
+ // stats.SyncQPCTime -> ust with conversion to microseconds via QueryPerformanceFrequency
+ *msc = stats.SyncRefreshCount;
+ *sbc = stats.PresentCount;
+
+ LONGLONG syncQPCValue = stats.SyncQPCTime.QuadPart;
+ // If the QPC Value is below the overflow threshold, we proceed with
+ // simple multiply and divide.
+ if (syncQPCValue < kQPCOverflowThreshold)
+ {
+ *ust = syncQPCValue * kMicrosecondsPerSecond / mQPCFrequency;
+ }
+ else
+ {
+ // Otherwise, calculate microseconds in a round about manner to avoid
+ // overflow and precision issues.
+ int64_t wholeSeconds = syncQPCValue / mQPCFrequency;
+ int64_t leftoverTicks = syncQPCValue - (wholeSeconds * mQPCFrequency);
+ *ust = wholeSeconds * kMicrosecondsPerSecond +
+ leftoverTicks * kMicrosecondsPerSecond / mQPCFrequency;
+ }
+
+ return egl::NoError();
+}
+
+UINT SwapChain11::getD3DSamples() const
+{
+ return (mEGLSamples == 0) ? 1 : mEGLSamples;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h
new file mode 100644
index 0000000000..2d7f0a00ee
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/SwapChain11.h
@@ -0,0 +1,134 @@
+//
+// Copyright 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.
+//
+
+// SwapChain11.h: Defines a back-end specific class for the D3D11 swap chain.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_SWAPCHAIN11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_SWAPCHAIN11_H_
+
+#include "common/angleutils.h"
+#include "libANGLE/renderer/d3d/SwapChainD3D.h"
+#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
+
+namespace rx
+{
+class Renderer11;
+class NativeWindow11;
+
+class SwapChain11 final : public SwapChainD3D
+{
+ public:
+ SwapChain11(Renderer11 *renderer,
+ NativeWindow11 *nativeWindow,
+ HANDLE shareHandle,
+ IUnknown *d3dTexture,
+ GLenum backBufferFormat,
+ GLenum depthBufferFormat,
+ EGLint orientation,
+ EGLint samples);
+ ~SwapChain11() override;
+
+ EGLint resize(DisplayD3D *displayD3D, EGLint backbufferWidth, EGLint backbufferHeight) override;
+ EGLint reset(DisplayD3D *displayD3D,
+ EGLint backbufferWidth,
+ EGLint backbufferHeight,
+ EGLint swapInterval) override;
+ EGLint swapRect(DisplayD3D *displayD3D,
+ EGLint x,
+ EGLint y,
+ EGLint width,
+ EGLint height) override;
+ void recreate() override;
+
+ RenderTargetD3D *getColorRenderTarget() override;
+ RenderTargetD3D *getDepthStencilRenderTarget() override;
+
+ const TextureHelper11 &getOffscreenTexture();
+ const d3d11::RenderTargetView &getRenderTarget();
+ angle::Result getRenderTargetShaderResource(d3d::Context *context,
+ const d3d11::SharedSRV **outSRV);
+
+ const TextureHelper11 &getDepthStencilTexture();
+ const d3d11::DepthStencilView &getDepthStencil();
+ const d3d11::SharedSRV &getDepthStencilShaderResource();
+
+ EGLint getWidth() const { return mWidth; }
+ EGLint getHeight() const { return mHeight; }
+ void *getKeyedMutex() override;
+ EGLint getSamples() const { return mEGLSamples; }
+
+ egl::Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) override;
+
+ private:
+ void release();
+ angle::Result initPassThroughResources(DisplayD3D *displayD3D);
+
+ void releaseOffscreenColorBuffer();
+ void releaseOffscreenDepthBuffer();
+ EGLint resetOffscreenBuffers(DisplayD3D *displayD3D, int backbufferWidth, int backbufferHeight);
+ EGLint resetOffscreenColorBuffer(DisplayD3D *displayD3D,
+ int backbufferWidth,
+ int backbufferHeight);
+ EGLint resetOffscreenDepthBuffer(DisplayD3D *displayD3D,
+ int backbufferWidth,
+ int backbufferHeight);
+
+ DXGI_FORMAT getSwapChainNativeFormat() const;
+
+ EGLint copyOffscreenToBackbuffer(DisplayD3D *displayD3D,
+ EGLint x,
+ EGLint y,
+ EGLint width,
+ EGLint height);
+ EGLint present(DisplayD3D *displayD3D, EGLint x, EGLint y, EGLint width, EGLint height);
+ UINT getD3DSamples() const;
+
+ Renderer11 *mRenderer;
+ EGLint mWidth;
+ EGLint mHeight;
+ const EGLint mOrientation;
+ bool mAppCreatedShareHandle;
+ unsigned int mSwapInterval;
+ bool mPassThroughResourcesInit;
+
+ NativeWindow11 *mNativeWindow; // Handler for the Window that the surface is created for.
+
+ bool mFirstSwap;
+ IDXGISwapChain *mSwapChain;
+ IDXGISwapChain1 *mSwapChain1;
+ IDXGIKeyedMutex *mKeyedMutex;
+
+ TextureHelper11 mBackBufferTexture;
+ d3d11::RenderTargetView mBackBufferRTView;
+ d3d11::SharedSRV mBackBufferSRView;
+
+ const bool mNeedsOffscreenTexture;
+ TextureHelper11 mOffscreenTexture;
+ d3d11::RenderTargetView mOffscreenRTView;
+ d3d11::SharedSRV mOffscreenSRView;
+ bool mNeedsOffscreenTextureCopy;
+ TextureHelper11 mOffscreenTextureCopyForSRV;
+
+ TextureHelper11 mDepthStencilTexture;
+ d3d11::DepthStencilView mDepthStencilDSView;
+ d3d11::SharedSRV mDepthStencilSRView;
+
+ d3d11::Buffer mQuadVB;
+ d3d11::SamplerState mPassThroughSampler;
+ d3d11::InputLayout mPassThroughIL;
+ d3d11::VertexShader mPassThroughVS;
+ d3d11::PixelShader mPassThroughOrResolvePS;
+ d3d11::RasterizerState mPassThroughRS;
+
+ SurfaceRenderTarget11 mColorRenderTarget;
+ SurfaceRenderTarget11 mDepthStencilRenderTarget;
+
+ EGLint mEGLSamples;
+ LONGLONG mQPCFrequency;
+};
+
+} // namespace rx
+#endif // LIBANGLE_RENDERER_D3D_D3D11_SWAPCHAIN11_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp
new file mode 100644
index 0000000000..f1277462a9
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp
@@ -0,0 +1,4352 @@
+//
+// Copyright 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.
+//
+
+// TextureStorage11.cpp: Implements the abstract rx::TextureStorage11 class and its concrete derived
+// classes TextureStorage11_2D and TextureStorage11_Cube, which act as the interface to the D3D11
+// texture.
+
+#include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h"
+
+#include <tuple>
+
+#include "common/MemoryBuffer.h"
+#include "common/utilities.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/ImageIndex.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/d3d/EGLImageD3D.h"
+#include "libANGLE/renderer/d3d/TextureD3D.h"
+#include "libANGLE/renderer/d3d/d3d11/Blit11.h"
+#include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
+#include "libANGLE/renderer/d3d/d3d11/Context11.h"
+#include "libANGLE/renderer/d3d/d3d11/Image11.h"
+#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/StreamProducerD3DTexture.h"
+#include "libANGLE/renderer/d3d/d3d11/SwapChain11.h"
+#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
+
+namespace rx
+{
+TextureStorage11::SamplerKey::SamplerKey()
+ : baseLevel(0), mipLevels(0), swizzle(false), dropStencil(false)
+{}
+
+TextureStorage11::SamplerKey::SamplerKey(int baseLevel,
+ int mipLevels,
+ bool swizzle,
+ bool dropStencil)
+ : baseLevel(baseLevel), mipLevels(mipLevels), swizzle(swizzle), dropStencil(dropStencil)
+{}
+
+bool TextureStorage11::SamplerKey::operator<(const SamplerKey &rhs) const
+{
+ return std::tie(baseLevel, mipLevels, swizzle, dropStencil) <
+ std::tie(rhs.baseLevel, rhs.mipLevels, rhs.swizzle, rhs.dropStencil);
+}
+
+TextureStorage11::ImageKey::ImageKey()
+ : level(0), layered(false), layer(0), access(GL_READ_ONLY), format(GL_R32UI)
+{}
+
+TextureStorage11::ImageKey::ImageKey(int level,
+ bool layered,
+ int layer,
+ GLenum access,
+ GLenum format)
+ : level(level), layered(layered), layer(layer), access(access), format(format)
+{}
+
+bool TextureStorage11::ImageKey::operator<(const ImageKey &rhs) const
+{
+ return std::tie(level, layered, layer, access, format) <
+ std::tie(rhs.level, rhs.layered, rhs.layer, rhs.access, rhs.format);
+}
+
+MultisampledRenderToTextureInfo::MultisampledRenderToTextureInfo(const GLsizei samples,
+ const gl::ImageIndex &indexSS,
+ const gl::ImageIndex &indexMS)
+ : samples(samples), indexSS(indexSS), indexMS(indexMS), msTextureNeedsResolve(false)
+{}
+
+MultisampledRenderToTextureInfo::~MultisampledRenderToTextureInfo() {}
+
+TextureStorage11::TextureStorage11(Renderer11 *renderer,
+ UINT bindFlags,
+ UINT miscFlags,
+ GLenum internalFormat,
+ const std::string &label)
+ : TextureStorage(label),
+ mRenderer(renderer),
+ mTopLevel(0),
+ mMipLevels(0),
+ mFormatInfo(d3d11::Format::Get(internalFormat, mRenderer->getRenderer11DeviceCaps())),
+ mTextureWidth(0),
+ mTextureHeight(0),
+ mTextureDepth(0),
+ mDropStencilTexture(),
+ mBindFlags(bindFlags),
+ mMiscFlags(miscFlags)
+{}
+
+TextureStorage11::~TextureStorage11()
+{
+ mSrvCacheForSampler.clear();
+}
+
+DWORD TextureStorage11::GetTextureBindFlags(GLenum internalFormat,
+ const Renderer11DeviceCaps &renderer11DeviceCaps,
+ BindFlags flags)
+{
+ UINT bindFlags = 0;
+
+ const d3d11::Format &formatInfo = d3d11::Format::Get(internalFormat, renderer11DeviceCaps);
+ if (formatInfo.srvFormat != DXGI_FORMAT_UNKNOWN)
+ {
+ bindFlags |= D3D11_BIND_SHADER_RESOURCE;
+ }
+ if (formatInfo.uavFormat != DXGI_FORMAT_UNKNOWN && flags.unorderedAccess)
+ {
+ bindFlags |= D3D11_BIND_UNORDERED_ACCESS;
+ }
+ if (formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN)
+ {
+ bindFlags |= D3D11_BIND_DEPTH_STENCIL;
+ }
+ if (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN && flags.renderTarget)
+ {
+ bindFlags |= D3D11_BIND_RENDER_TARGET;
+ }
+
+ return bindFlags;
+}
+
+DWORD TextureStorage11::GetTextureMiscFlags(GLenum internalFormat,
+ const Renderer11DeviceCaps &renderer11DeviceCaps,
+ BindFlags bindFlags,
+ int levels)
+{
+ UINT miscFlags = 0;
+
+ const d3d11::Format &formatInfo = d3d11::Format::Get(internalFormat, renderer11DeviceCaps);
+ if (bindFlags.renderTarget)
+ {
+ if (d3d11::SupportsMipGen(formatInfo.texFormat, renderer11DeviceCaps.featureLevel))
+ {
+ miscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS;
+ }
+ }
+
+ return miscFlags;
+}
+
+UINT TextureStorage11::getBindFlags() const
+{
+ return mBindFlags;
+}
+
+UINT TextureStorage11::getMiscFlags() const
+{
+ return mMiscFlags;
+}
+
+int TextureStorage11::getTopLevel() const
+{
+ // Applying top level is meant to be encapsulated inside TextureStorage11.
+ UNREACHABLE();
+ return mTopLevel;
+}
+
+bool TextureStorage11::isRenderTarget() const
+{
+ return (mBindFlags & (D3D11_BIND_RENDER_TARGET | D3D11_BIND_DEPTH_STENCIL)) != 0;
+}
+
+bool TextureStorage11::isManaged() const
+{
+ return false;
+}
+
+bool TextureStorage11::supportsNativeMipmapFunction() const
+{
+ return (mMiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS) != 0;
+}
+
+int TextureStorage11::getLevelCount() const
+{
+ return mMipLevels - mTopLevel;
+}
+
+int TextureStorage11::getLevelWidth(int mipLevel) const
+{
+ return std::max(static_cast<int>(mTextureWidth) >> mipLevel, 1);
+}
+
+int TextureStorage11::getLevelHeight(int mipLevel) const
+{
+ return std::max(static_cast<int>(mTextureHeight) >> mipLevel, 1);
+}
+
+int TextureStorage11::getLevelDepth(int mipLevel) const
+{
+ return std::max(static_cast<int>(mTextureDepth) >> mipLevel, 1);
+}
+
+angle::Result TextureStorage11::getMippedResource(const gl::Context *context,
+ const TextureHelper11 **outResource)
+{
+ return getResource(context, outResource);
+}
+
+angle::Result TextureStorage11::getSubresourceIndex(const gl::Context *context,
+ const gl::ImageIndex &index,
+ UINT *outSubresourceIndex) const
+{
+ UINT mipSlice = static_cast<UINT>(index.getLevelIndex() + mTopLevel);
+ UINT arraySlice = static_cast<UINT>(index.hasLayer() ? index.getLayerIndex() : 0);
+ UINT subresource = D3D11CalcSubresource(mipSlice, arraySlice, mMipLevels);
+ ASSERT(subresource != std::numeric_limits<UINT>::max());
+ *outSubresourceIndex = subresource;
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11::getSRVForSampler(const gl::Context *context,
+ const gl::TextureState &textureState,
+ const gl::SamplerState &sampler,
+ const d3d11::SharedSRV **outSRV)
+{
+ ANGLE_TRY(resolveTexture(context));
+ // Make sure to add the level offset for our tiny compressed texture workaround
+ const GLuint effectiveBaseLevel = textureState.getEffectiveBaseLevel();
+ const bool swizzleRequired = SwizzleRequired(textureState);
+ const bool mipmapping = gl::IsMipmapFiltered(sampler.getMinFilter());
+ unsigned int mipLevels =
+ mipmapping ? (textureState.getEffectiveMaxLevel() - effectiveBaseLevel + 1) : 1;
+
+ // Make sure there's 'mipLevels' mipmap levels below the base level (offset by the top level,
+ // which corresponds to GL level 0)
+ mipLevels = std::min(mipLevels, mMipLevels - mTopLevel - effectiveBaseLevel);
+
+ if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3)
+ {
+ ASSERT(!swizzleRequired);
+ ASSERT(mipLevels == 1 || mipLevels == mMipLevels);
+ }
+
+ if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
+ {
+ // We must ensure that the level zero texture is in sync with mipped texture.
+ ANGLE_TRY(useLevelZeroWorkaroundTexture(context, mipLevels == 1));
+ }
+
+ if (swizzleRequired)
+ {
+ verifySwizzleExists(GetEffectiveSwizzle(textureState));
+ }
+
+ // We drop the stencil when sampling from the SRV if three conditions hold:
+ // 1. the drop stencil workaround is enabled.
+ const bool emulateTinyStencilTextures =
+ mRenderer->getFeatures().emulateTinyStencilTextures.enabled;
+ // 2. this is a stencil texture.
+ const bool hasStencil = (mFormatInfo.format().stencilBits > 0);
+ // 3. the texture has a 1x1 or 2x2 mip.
+ const int effectiveTopLevel = effectiveBaseLevel + mipLevels - 1;
+ const bool hasSmallMips =
+ (getLevelWidth(effectiveTopLevel) <= 2 || getLevelHeight(effectiveTopLevel) <= 2);
+
+ const bool useDropStencil = (emulateTinyStencilTextures && hasStencil && hasSmallMips);
+ const SamplerKey key(effectiveBaseLevel, mipLevels, swizzleRequired, useDropStencil);
+ if (useDropStencil)
+ {
+ // Ensure drop texture gets created.
+ DropStencil result = DropStencil::CREATED;
+ ANGLE_TRY(ensureDropStencilTexture(context, &result));
+
+ // Clear the SRV cache if necessary.
+ // TODO(jmadill): Re-use find query result.
+ const auto srvEntry = mSrvCacheForSampler.find(key);
+ if (result == DropStencil::CREATED && srvEntry != mSrvCacheForSampler.end())
+ {
+ mSrvCacheForSampler.erase(key);
+ }
+ }
+
+ ANGLE_TRY(getCachedOrCreateSRVForSampler(context, key, outSRV));
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11::getCachedOrCreateSRVForSampler(const gl::Context *context,
+ const SamplerKey &key,
+ const d3d11::SharedSRV **outSRV)
+{
+ auto iter = mSrvCacheForSampler.find(key);
+ if (iter != mSrvCacheForSampler.end())
+ {
+ *outSRV = &iter->second;
+ return angle::Result::Continue;
+ }
+
+ const TextureHelper11 *texture = nullptr;
+ DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN;
+
+ if (key.swizzle)
+ {
+ const auto &swizzleFormat =
+ mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps());
+ ASSERT(!key.dropStencil || swizzleFormat.format().stencilBits == 0);
+ ANGLE_TRY(getSwizzleTexture(context, &texture));
+ format = swizzleFormat.srvFormat;
+ }
+ else if (key.dropStencil)
+ {
+ ASSERT(mDropStencilTexture.valid());
+ texture = &mDropStencilTexture;
+ format = DXGI_FORMAT_R32_FLOAT;
+ }
+ else
+ {
+ ANGLE_TRY(getResource(context, &texture));
+ format = mFormatInfo.srvFormat;
+ }
+
+ d3d11::SharedSRV srv;
+
+ ANGLE_TRY(createSRVForSampler(context, key.baseLevel, key.mipLevels, format, *texture, &srv));
+
+ const auto &insertIt = mSrvCacheForSampler.insert(std::make_pair(key, std::move(srv)));
+ *outSRV = &insertIt.first->second;
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11::getSRVLevel(const gl::Context *context,
+ int mipLevel,
+ SRVType srvType,
+ const d3d11::SharedSRV **outSRV)
+{
+ ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
+
+ ANGLE_TRY(resolveTexture(context));
+ if (srvType == SRVType::Stencil)
+ {
+ if (!mLevelStencilSRVs[mipLevel].valid())
+ {
+ const TextureHelper11 *resource = nullptr;
+ ANGLE_TRY(getResource(context, &resource));
+
+ ANGLE_TRY(createSRVForSampler(context, mipLevel, 1, mFormatInfo.stencilSRVFormat,
+ *resource, &mLevelStencilSRVs[mipLevel]));
+ }
+ *outSRV = &mLevelStencilSRVs[mipLevel];
+ return angle::Result::Continue;
+ }
+
+ auto &levelSRVs = srvType == SRVType::Blit ? mLevelBlitSRVs : mLevelSRVs;
+ auto &otherLevelSRVs = srvType == SRVType::Blit ? mLevelSRVs : mLevelBlitSRVs;
+
+ if (!levelSRVs[mipLevel].valid())
+ {
+ // Only create a different SRV for blit if blit format is different from regular srv format
+ if (otherLevelSRVs[mipLevel].valid() && mFormatInfo.srvFormat == mFormatInfo.blitSRVFormat)
+ {
+ levelSRVs[mipLevel] = otherLevelSRVs[mipLevel].makeCopy();
+ }
+ else
+ {
+ const TextureHelper11 *resource = nullptr;
+ ANGLE_TRY(getResource(context, &resource));
+
+ DXGI_FORMAT resourceFormat =
+ srvType == SRVType::Blit ? mFormatInfo.blitSRVFormat : mFormatInfo.srvFormat;
+ ANGLE_TRY(createSRVForSampler(context, mipLevel, 1, resourceFormat, *resource,
+ &levelSRVs[mipLevel]));
+ }
+ }
+
+ *outSRV = &levelSRVs[mipLevel];
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11::getSRVLevels(const gl::Context *context,
+ GLint baseLevel,
+ GLint maxLevel,
+ const d3d11::SharedSRV **outSRV)
+{
+ ANGLE_TRY(resolveTexture(context));
+ unsigned int mipLevels = maxLevel - baseLevel + 1;
+
+ // Make sure there's 'mipLevels' mipmap levels below the base level (offset by the top level,
+ // which corresponds to GL level 0)
+ mipLevels = std::min(mipLevels, mMipLevels - mTopLevel - baseLevel);
+
+ if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3)
+ {
+ ASSERT(mipLevels == 1 || mipLevels == mMipLevels);
+ }
+
+ if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
+ {
+ // We must ensure that the level zero texture is in sync with mipped texture.
+ ANGLE_TRY(useLevelZeroWorkaroundTexture(context, mipLevels == 1));
+ }
+
+ // TODO(jmadill): Assert we don't need to drop stencil.
+
+ SamplerKey key(baseLevel, mipLevels, false, false);
+ ANGLE_TRY(getCachedOrCreateSRVForSampler(context, key, outSRV));
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11::getSRVForImage(const gl::Context *context,
+ const gl::ImageUnit &imageUnit,
+ const d3d11::SharedSRV **outSRV)
+{
+ ANGLE_TRY(resolveTexture(context));
+ // TODO(Xinghua.cao@intel.com): Add solution to handle swizzle required.
+ ImageKey key(imageUnit.level, (imageUnit.layered == GL_TRUE), imageUnit.layer, imageUnit.access,
+ imageUnit.format);
+ ANGLE_TRY(getCachedOrCreateSRVForImage(context, key, outSRV));
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11::getCachedOrCreateSRVForImage(const gl::Context *context,
+ const ImageKey &key,
+ const d3d11::SharedSRV **outSRV)
+{
+ auto iter = mSrvCacheForImage.find(key);
+ if (iter != mSrvCacheForImage.end())
+ {
+ *outSRV = &iter->second;
+ return angle::Result::Continue;
+ }
+ const TextureHelper11 *texture = nullptr;
+ ANGLE_TRY(getResource(context, &texture));
+ DXGI_FORMAT format =
+ d3d11::Format::Get(key.format, mRenderer->getRenderer11DeviceCaps()).srvFormat;
+ d3d11::SharedSRV srv;
+ ANGLE_TRY(createSRVForImage(context, key.level, format, *texture, &srv));
+ const auto &insertIt = mSrvCacheForImage.insert(std::make_pair(key, std::move(srv)));
+ *outSRV = &insertIt.first->second;
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11::getUAVForImage(const gl::Context *context,
+ const gl::ImageUnit &imageUnit,
+ const d3d11::SharedUAV **outUAV)
+{
+ ANGLE_TRY(resolveTexture(context));
+ // TODO(Xinghua.cao@intel.com): Add solution to handle swizzle required.
+ ImageKey key(imageUnit.level, (imageUnit.layered == GL_TRUE), imageUnit.layer, imageUnit.access,
+ imageUnit.format);
+ ANGLE_TRY(getCachedOrCreateUAVForImage(context, key, outUAV));
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11::getCachedOrCreateUAVForImage(const gl::Context *context,
+ const ImageKey &key,
+ const d3d11::SharedUAV **outUAV)
+{
+ auto iter = mUavCacheForImage.find(key);
+ if (iter != mUavCacheForImage.end())
+ {
+ *outUAV = &iter->second;
+ return angle::Result::Continue;
+ }
+ const TextureHelper11 *texture = nullptr;
+ ANGLE_TRY(getResource(context, &texture));
+ DXGI_FORMAT format =
+ d3d11::Format::Get(key.format, mRenderer->getRenderer11DeviceCaps()).uavFormat;
+ ASSERT(format != DXGI_FORMAT_UNKNOWN);
+ d3d11::SharedUAV uav;
+ ANGLE_TRY(createUAVForImage(context, key.level, format, *texture, &uav));
+ const auto &insertIt = mUavCacheForImage.insert(std::make_pair(key, std::move(uav)));
+ *outUAV = &insertIt.first->second;
+ return angle::Result::Continue;
+}
+
+const d3d11::Format &TextureStorage11::getFormatSet() const
+{
+ return mFormatInfo;
+}
+
+angle::Result TextureStorage11::generateSwizzles(const gl::Context *context,
+ const gl::TextureState &textureState)
+{
+ ANGLE_TRY(resolveTexture(context));
+ gl::SwizzleState swizzleTarget = GetEffectiveSwizzle(textureState);
+ for (int level = 0; level < getLevelCount(); level++)
+ {
+ // Check if the swizzle for this level is out of date
+ if (mSwizzleCache[level] != swizzleTarget)
+ {
+ // Need to re-render the swizzle for this level
+ const d3d11::SharedSRV *sourceSRV = nullptr;
+ ANGLE_TRY(getSRVLevel(context, level,
+ textureState.isStencilMode() ? SRVType::Stencil : SRVType::Blit,
+ &sourceSRV));
+
+ const d3d11::RenderTargetView *destRTV;
+ ANGLE_TRY(getSwizzleRenderTarget(context, level, &destRTV));
+
+ gl::Extents size(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level));
+
+ Blit11 *blitter = mRenderer->getBlitter();
+
+ ANGLE_TRY(blitter->swizzleTexture(context, *sourceSRV, *destRTV, size, swizzleTarget));
+
+ mSwizzleCache[level] = swizzleTarget;
+ }
+ }
+
+ return angle::Result::Continue;
+}
+
+void TextureStorage11::markLevelDirty(int mipLevel)
+{
+ if (mipLevel >= 0 && static_cast<size_t>(mipLevel) < mSwizzleCache.size())
+ {
+ // The default constructor of SwizzleState has GL_INVALID_INDEX for all channels which is
+ // not a valid swizzle combination
+ if (mSwizzleCache[mipLevel] != gl::SwizzleState())
+ {
+ // TODO(jmadill): Invalidate specific swizzle.
+ mRenderer->getStateManager()->invalidateSwizzles();
+ mSwizzleCache[mipLevel] = gl::SwizzleState();
+ }
+ }
+
+ if (mDropStencilTexture.valid())
+ {
+ mDropStencilTexture.reset();
+ }
+}
+
+void TextureStorage11::markDirty()
+{
+ for (size_t mipLevel = 0; mipLevel < mSwizzleCache.size(); ++mipLevel)
+ {
+ markLevelDirty(static_cast<int>(mipLevel));
+ }
+}
+
+angle::Result TextureStorage11::updateSubresourceLevel(const gl::Context *context,
+ const TextureHelper11 &srcTexture,
+ unsigned int sourceSubresource,
+ const gl::ImageIndex &index,
+ const gl::Box &copyArea)
+{
+ ASSERT(srcTexture.valid());
+
+ ANGLE_TRY(resolveTexture(context));
+ const GLint level = index.getLevelIndex();
+
+ markLevelDirty(level);
+
+ gl::Extents texSize(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level));
+
+ bool fullCopy = copyArea.coversSameExtent(texSize);
+
+ const TextureHelper11 *dstTexture = nullptr;
+
+ // 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 (level > 0 && mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
+ {
+ ANGLE_TRY(getMippedResource(context, &dstTexture));
+ }
+ else
+ {
+ ANGLE_TRY(getResource(context, &dstTexture));
+ }
+
+ unsigned int dstSubresource = 0;
+ ANGLE_TRY(getSubresourceIndex(context, index, &dstSubresource));
+
+ ASSERT(dstTexture->valid());
+
+ const d3d11::DXGIFormatSize &dxgiFormatSizeInfo =
+ 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();
+ return blitter->copyDepthStencil(context, srcTexture, sourceSubresource, copyArea, texSize,
+ *dstTexture, dstSubresource, copyArea, texSize, nullptr);
+ }
+
+ D3D11_BOX srcBox;
+ srcBox.left = copyArea.x;
+ srcBox.top = copyArea.y;
+ srcBox.right =
+ copyArea.x + roundUp(static_cast<UINT>(copyArea.width), dxgiFormatSizeInfo.blockWidth);
+ srcBox.bottom =
+ copyArea.y + roundUp(static_cast<UINT>(copyArea.height), dxgiFormatSizeInfo.blockHeight);
+ srcBox.front = copyArea.z;
+ srcBox.back = copyArea.z + copyArea.depth;
+
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+
+ deviceContext->CopySubresourceRegion(dstTexture->get(), dstSubresource, copyArea.x, copyArea.y,
+ copyArea.z, srcTexture.get(), sourceSubresource,
+ fullCopy ? nullptr : &srcBox);
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11::copySubresourceLevel(const gl::Context *context,
+ const TextureHelper11 &dstTexture,
+ unsigned int dstSubresource,
+ const gl::ImageIndex &index,
+ const gl::Box &region)
+{
+ ASSERT(dstTexture.valid());
+
+ ANGLE_TRY(resolveTexture(context));
+ const TextureHelper11 *srcTexture = nullptr;
+
+ // 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.getLevelIndex() > 0 && mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
+ {
+ ANGLE_TRY(getMippedResource(context, &srcTexture));
+ }
+ else
+ {
+ ANGLE_TRY(getResource(context, &srcTexture));
+ }
+
+ ASSERT(srcTexture->valid());
+
+ unsigned int srcSubresource = 0;
+ ANGLE_TRY(getSubresourceIndex(context, index, &srcSubresource));
+
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+
+ // D3D11 can't perform partial CopySubresourceRegion on depth/stencil textures, so pSrcBox
+ // should be nullptr.
+ D3D11_BOX srcBox;
+ D3D11_BOX *pSrcBox = nullptr;
+ if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3)
+ {
+ GLsizei width = region.width;
+ GLsizei height = region.height;
+ d3d11::MakeValidSize(false, mFormatInfo.texFormat, &width, &height, nullptr);
+
+ // Keep srcbox as nullptr if we're dealing with tiny mips of compressed textures.
+ if (width == region.width && height == region.height)
+ {
+ // 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(mFormatInfo.dsvFormat == DXGI_FORMAT_UNKNOWN);
+ srcBox.left = region.x;
+ srcBox.right = region.x + region.width;
+ srcBox.top = region.y;
+ srcBox.bottom = region.y + region.height;
+ srcBox.front = region.z;
+ srcBox.back = region.z + region.depth;
+ pSrcBox = &srcBox;
+ }
+ }
+
+ deviceContext->CopySubresourceRegion(dstTexture.get(), dstSubresource, region.x, region.y,
+ region.z, srcTexture->get(), srcSubresource, pSrcBox);
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11::generateMipmap(const gl::Context *context,
+ const gl::ImageIndex &sourceIndex,
+ const gl::ImageIndex &destIndex)
+{
+ ASSERT(sourceIndex.getLayerIndex() == destIndex.getLayerIndex());
+
+ ANGLE_TRY(resolveTexture(context));
+ markLevelDirty(destIndex.getLevelIndex());
+
+ RenderTargetD3D *source = nullptr;
+ ANGLE_TRY(getRenderTarget(context, sourceIndex, 0, &source));
+
+ // dest will always have 0 since, we have just released the MS Texture struct
+ RenderTargetD3D *dest = nullptr;
+ ANGLE_TRY(getRenderTarget(context, destIndex, 0, &dest));
+
+ RenderTarget11 *srcRT11 = GetAs<RenderTarget11>(source);
+ RenderTarget11 *dstRT11 = GetAs<RenderTarget11>(dest);
+ const d3d11::RenderTargetView &destRTV = dstRT11->getRenderTargetView();
+ const d3d11::SharedSRV *sourceSRV;
+ ANGLE_TRY(srcRT11->getBlitShaderResourceView(context, &sourceSRV));
+
+ gl::Box sourceArea(0, 0, 0, source->getWidth(), source->getHeight(), source->getDepth());
+ gl::Extents sourceSize(source->getWidth(), source->getHeight(), source->getDepth());
+
+ gl::Box destArea(0, 0, 0, dest->getWidth(), dest->getHeight(), dest->getDepth());
+ gl::Extents destSize(dest->getWidth(), dest->getHeight(), dest->getDepth());
+
+ Blit11 *blitter = mRenderer->getBlitter();
+ const gl::InternalFormat &sourceInternalFormat =
+ gl::GetSizedInternalFormatInfo(source->getInternalFormat());
+ GLenum format = sourceInternalFormat.format;
+ GLenum type = sourceInternalFormat.type;
+ return blitter->copyTexture(context, *sourceSRV, sourceArea, sourceSize, format, destRTV,
+ destArea, destSize, nullptr, format, type, GL_LINEAR, false, false,
+ false);
+}
+
+void TextureStorage11::verifySwizzleExists(const gl::SwizzleState &swizzleState)
+{
+ for (unsigned int level = 0; level < mMipLevels; level++)
+ {
+ ASSERT(mSwizzleCache[level] == swizzleState);
+ }
+}
+
+void TextureStorage11::clearSRVCache()
+{
+ markDirty();
+ mSrvCacheForSampler.clear();
+
+ for (size_t level = 0; level < mLevelSRVs.size(); level++)
+ {
+ mLevelSRVs[level].reset();
+ mLevelBlitSRVs[level].reset();
+ }
+}
+
+angle::Result TextureStorage11::copyToStorage(const gl::Context *context,
+ TextureStorage *destStorage)
+{
+ ASSERT(destStorage);
+
+ ANGLE_TRY(resolveTexture(context));
+ const TextureHelper11 *sourceResouce = nullptr;
+ ANGLE_TRY(getResource(context, &sourceResouce));
+
+ TextureStorage11 *dest11 = GetAs<TextureStorage11>(destStorage);
+ const TextureHelper11 *destResource = nullptr;
+ ANGLE_TRY(dest11->getResource(context, &destResource));
+
+ ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
+ immediateContext->CopyResource(destResource->get(), sourceResouce->get());
+
+ dest11->markDirty();
+
+ return angle::Result::Continue;
+}
+
+void TextureStorage11::invalidateTextures()
+{
+ mRenderer->getStateManager()->invalidateTexturesAndSamplers();
+}
+
+angle::Result TextureStorage11::setData(const gl::Context *context,
+ const gl::ImageIndex &index,
+ ImageD3D *image,
+ const gl::Box *destBox,
+ GLenum type,
+ const gl::PixelUnpackState &unpack,
+ const uint8_t *pixelData)
+{
+ ASSERT(!image->isDirty());
+
+ ANGLE_TRY(resolveTexture(context));
+ markLevelDirty(index.getLevelIndex());
+
+ const TextureHelper11 *resource = nullptr;
+ ANGLE_TRY(getResource(context, &resource));
+ ASSERT(resource && resource->valid());
+
+ UINT destSubresource = 0;
+ ANGLE_TRY(getSubresourceIndex(context, index, &destSubresource));
+
+ const gl::InternalFormat &internalFormatInfo =
+ gl::GetInternalFormatInfo(image->getInternalFormat(), type);
+
+ gl::Box levelBox(0, 0, 0, getLevelWidth(index.getLevelIndex()),
+ getLevelHeight(index.getLevelIndex()), getLevelDepth(index.getLevelIndex()));
+ bool fullUpdate = (destBox == nullptr || *destBox == levelBox);
+ ASSERT(internalFormatInfo.depthBits == 0 || fullUpdate);
+
+ // TODO(jmadill): Handle compressed formats
+ // Compressed formats have different load syntax, so we'll have to handle them with slightly
+ // different logic. Will implemnent this in a follow-up patch, and ensure we do not use SetData
+ // with compressed formats in the calling logic.
+ ASSERT(!internalFormatInfo.compressed);
+
+ Context11 *context11 = GetImplAs<Context11>(context);
+
+ const int width = destBox ? destBox->width : static_cast<int>(image->getWidth());
+ const int height = destBox ? destBox->height : static_cast<int>(image->getHeight());
+ const int depth = destBox ? destBox->depth : static_cast<int>(image->getDepth());
+ GLuint srcRowPitch = 0;
+ ANGLE_CHECK_GL_MATH(context11,
+ internalFormatInfo.computeRowPitch(type, width, unpack.alignment,
+ unpack.rowLength, &srcRowPitch));
+ GLuint srcDepthPitch = 0;
+ ANGLE_CHECK_GL_MATH(context11, internalFormatInfo.computeDepthPitch(
+ height, unpack.imageHeight, srcRowPitch, &srcDepthPitch));
+ GLuint srcSkipBytes = 0;
+ ANGLE_CHECK_GL_MATH(
+ context11, internalFormatInfo.computeSkipBytes(type, srcRowPitch, srcDepthPitch, unpack,
+ index.usesTex3D(), &srcSkipBytes));
+
+ const d3d11::Format &d3d11Format =
+ d3d11::Format::Get(image->getInternalFormat(), mRenderer->getRenderer11DeviceCaps());
+ const d3d11::DXGIFormatSize &dxgiFormatInfo =
+ d3d11::GetDXGIFormatSizeInfo(d3d11Format.texFormat);
+
+ const size_t outputPixelSize = dxgiFormatInfo.pixelBytes;
+
+ UINT bufferRowPitch = static_cast<unsigned int>(outputPixelSize) * width;
+ UINT bufferDepthPitch = bufferRowPitch * height;
+
+ const size_t neededSize = bufferDepthPitch * depth;
+ angle::MemoryBuffer *conversionBuffer = nullptr;
+ const uint8_t *data = nullptr;
+
+ LoadImageFunctionInfo loadFunctionInfo = d3d11Format.getLoadFunctions()(type);
+ if (loadFunctionInfo.requiresConversion)
+ {
+ ANGLE_TRY(mRenderer->getScratchMemoryBuffer(context11, neededSize, &conversionBuffer));
+ loadFunctionInfo.loadFunction(width, height, depth, pixelData + srcSkipBytes, srcRowPitch,
+ srcDepthPitch, conversionBuffer->data(), bufferRowPitch,
+ bufferDepthPitch);
+ data = conversionBuffer->data();
+ }
+ else
+ {
+ data = pixelData + srcSkipBytes;
+ bufferRowPitch = srcRowPitch;
+ bufferDepthPitch = srcDepthPitch;
+ }
+
+ ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
+
+ if (!fullUpdate)
+ {
+ ASSERT(destBox);
+
+ D3D11_BOX destD3DBox;
+ destD3DBox.left = destBox->x;
+ destD3DBox.right = destBox->x + destBox->width;
+ destD3DBox.top = destBox->y;
+ destD3DBox.bottom = destBox->y + destBox->height;
+ destD3DBox.front = destBox->z;
+ destD3DBox.back = destBox->z + destBox->depth;
+
+ immediateContext->UpdateSubresource(resource->get(), destSubresource, &destD3DBox, data,
+ bufferRowPitch, bufferDepthPitch);
+ }
+ else
+ {
+ immediateContext->UpdateSubresource(resource->get(), destSubresource, nullptr, data,
+ bufferRowPitch, bufferDepthPitch);
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11::ensureDropStencilTexture(
+ const gl::Context *context,
+ TextureStorage11::DropStencil *dropStencilOut)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
+ return angle::Result::Stop;
+}
+
+angle::Result TextureStorage11::initDropStencilTexture(const gl::Context *context,
+ const gl::ImageIndexIterator &it)
+{
+ const TextureHelper11 *sourceTexture = nullptr;
+ ANGLE_TRY(getResource(context, &sourceTexture));
+
+ gl::ImageIndexIterator itCopy = it;
+
+ while (itCopy.hasNext())
+ {
+ gl::ImageIndex index = itCopy.next();
+ gl::Box wholeArea(0, 0, 0, getLevelWidth(index.getLevelIndex()),
+ getLevelHeight(index.getLevelIndex()), 1);
+ gl::Extents wholeSize(wholeArea.width, wholeArea.height, 1);
+
+ UINT subresource = 0;
+ ANGLE_TRY(getSubresourceIndex(context, index, &subresource));
+
+ ANGLE_TRY(mRenderer->getBlitter()->copyDepthStencil(
+ context, *sourceTexture, subresource, wholeArea, wholeSize, mDropStencilTexture,
+ subresource, wholeArea, wholeSize, nullptr));
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11::resolveTextureHelper(const gl::Context *context,
+ const TextureHelper11 &texture)
+{
+ UINT subresourceIndexSS;
+ ANGLE_TRY(getSubresourceIndex(context, mMSTexInfo->indexSS, &subresourceIndexSS));
+ UINT subresourceIndexMS;
+ ANGLE_TRY(getSubresourceIndex(context, mMSTexInfo->indexMS, &subresourceIndexMS));
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+ const TextureHelper11 *resource = nullptr;
+ ANGLE_TRY(mMSTexInfo->msTex->getResource(context, &resource));
+ deviceContext->ResolveSubresource(texture.get(), subresourceIndexSS, resource->get(),
+ subresourceIndexMS, texture.getFormat());
+ mMSTexInfo->msTextureNeedsResolve = false;
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11::releaseMultisampledTexStorageForLevel(size_t level)
+{
+ if (mMSTexInfo && mMSTexInfo->indexSS.getLevelIndex() == static_cast<int>(level))
+ {
+ mMSTexInfo->msTex.reset();
+ onStateChange(angle::SubjectMessage::ContentsChanged);
+ }
+ return angle::Result::Continue;
+}
+
+GLsizei TextureStorage11::getRenderToTextureSamples() const
+{
+ if (mMSTexInfo)
+ {
+ return mMSTexInfo->samples;
+ }
+ return 0;
+}
+
+angle::Result TextureStorage11::findMultisampledRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) const
+{
+ const int level = index.getLevelIndex();
+ if (!mMSTexInfo || level != mMSTexInfo->indexSS.getLevelIndex() ||
+ samples != mMSTexInfo->samples || !mMSTexInfo->msTex)
+ {
+ *outRT = nullptr;
+ return angle::Result::Continue;
+ }
+ RenderTargetD3D *rt;
+ ANGLE_TRY(mMSTexInfo->msTex->findRenderTarget(context, mMSTexInfo->indexMS, samples, &rt));
+ *outRT = rt;
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11::getMultisampledRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT)
+{
+ const int level = index.getLevelIndex();
+ if (!mMSTexInfo || level != mMSTexInfo->indexSS.getLevelIndex() ||
+ samples != mMSTexInfo->samples || !mMSTexInfo->msTex)
+ {
+ // if mMSTexInfo already exists, then we want to resolve and release it
+ // since the mMSTexInfo must be for a different sample count or level
+ ANGLE_TRY(resolveTexture(context));
+
+ // Now we can create a new object for the correct sample and level
+ GLsizei width = getLevelWidth(level);
+ GLsizei height = getLevelHeight(level);
+ GLenum internalFormat = mFormatInfo.internalFormat;
+ std::unique_ptr<TextureStorage11_2DMultisample> texMS(
+ GetAs<TextureStorage11_2DMultisample>(mRenderer->createTextureStorage2DMultisample(
+ internalFormat, width, height, level, samples, true, mKHRDebugLabel)));
+
+ // make sure multisample object has the blitted information.
+ gl::Rectangle area(0, 0, width, height);
+ RenderTargetD3D *readRenderTarget = nullptr;
+ // use incoming index here since the index will correspond to the single sampled texture
+ ANGLE_TRY(getRenderTarget(context, index, 0, &readRenderTarget));
+ gl::ImageIndex indexMS = gl::ImageIndex::Make2DMultisample();
+ RenderTargetD3D *drawRenderTarget = nullptr;
+ ANGLE_TRY(texMS->getRenderTarget(context, indexMS, samples, &drawRenderTarget));
+
+ // blit SS -> MS
+ // mask: GL_COLOR_BUFFER_BIT, filter: GL_NEAREST
+ ANGLE_TRY(mRenderer->blitRenderbufferRect(context, area, area, 0, 0, readRenderTarget,
+ drawRenderTarget, GL_NEAREST, nullptr, true,
+ false, false));
+ mMSTexInfo = std::make_unique<MultisampledRenderToTextureInfo>(samples, index, indexMS);
+ mMSTexInfo->msTex = std::move(texMS);
+ }
+ RenderTargetD3D *rt;
+ ANGLE_TRY(mMSTexInfo->msTex->getRenderTarget(context, mMSTexInfo->indexMS, samples, &rt));
+ // By returning the multisampled render target to the caller, the render target
+ // is expected to be changed so we need to resolve to a single sampled texture
+ // next time resolveTexture is called.
+ mMSTexInfo->msTextureNeedsResolve = true;
+ *outRT = rt;
+ return angle::Result::Continue;
+}
+
+TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer,
+ SwapChain11 *swapchain,
+ const std::string &label)
+ : TextureStorage11(renderer,
+ D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE,
+ 0,
+ swapchain->getRenderTargetInternalFormat(),
+ label),
+ mTexture(swapchain->getOffscreenTexture()),
+ mLevelZeroTexture(),
+ mLevelZeroRenderTarget(nullptr),
+ mUseLevelZeroTexture(false),
+ mSwizzleTexture()
+{
+ for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+ {
+ mAssociatedImages[i] = nullptr;
+ mRenderTarget[i] = nullptr;
+ }
+
+ D3D11_TEXTURE2D_DESC texDesc;
+ mTexture.getDesc(&texDesc);
+ mMipLevels = texDesc.MipLevels;
+ mTextureWidth = texDesc.Width;
+ mTextureHeight = texDesc.Height;
+ mTextureDepth = 1;
+ mHasKeyedMutex = (texDesc.MiscFlags & D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX) != 0;
+}
+
+TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer,
+ GLenum internalformat,
+ BindFlags bindFlags,
+ GLsizei width,
+ GLsizei height,
+ int levels,
+ const std::string &label,
+ bool hintLevelZeroOnly)
+ : TextureStorage11(
+ renderer,
+ GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), bindFlags),
+ GetTextureMiscFlags(internalformat,
+ renderer->getRenderer11DeviceCaps(),
+ bindFlags,
+ levels),
+ internalformat,
+ label),
+ mTexture(),
+ mHasKeyedMutex(false),
+ mLevelZeroTexture(),
+ mLevelZeroRenderTarget(nullptr),
+ mUseLevelZeroTexture(hintLevelZeroOnly && levels > 1),
+ mSwizzleTexture()
+{
+ for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+ {
+ mAssociatedImages[i] = nullptr;
+ mRenderTarget[i] = nullptr;
+ }
+
+ d3d11::MakeValidSize(false, mFormatInfo.texFormat, &width, &height, &mTopLevel);
+ mMipLevels = mTopLevel + levels;
+ mTextureWidth = width;
+ mTextureHeight = height;
+ mTextureDepth = 1;
+
+ // The LevelZeroOnly hint should only be true if the zero max LOD workaround is active.
+ ASSERT(!mUseLevelZeroTexture || mRenderer->getFeatures().zeroMaxLodWorkaround.enabled);
+}
+
+void TextureStorage11_2D::onLabelUpdate()
+{
+ if (mTexture.valid())
+ {
+ mTexture.setKHRDebugLabel(&mKHRDebugLabel);
+ }
+ if (mLevelZeroTexture.valid())
+ {
+ mLevelZeroTexture.setKHRDebugLabel(&mKHRDebugLabel);
+ }
+ if (mSwizzleTexture.valid())
+ {
+ mSwizzleTexture.setKHRDebugLabel(&mKHRDebugLabel);
+ }
+}
+
+angle::Result TextureStorage11_2D::onDestroy(const gl::Context *context)
+{
+ for (unsigned i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+ {
+ if (mAssociatedImages[i] != nullptr)
+ {
+ mAssociatedImages[i]->verifyAssociatedStorageValid(this);
+
+ // We must let the Images recover their data before we delete it from the
+ // TextureStorage.
+ ANGLE_TRY(mAssociatedImages[i]->recoverFromAssociatedStorage(context));
+ }
+ }
+
+ if (mHasKeyedMutex)
+ {
+ // If the keyed mutex is released that will unbind it and cause the state cache to become
+ // desynchronized.
+ mRenderer->getStateManager()->invalidateBoundViews();
+ }
+
+ return angle::Result::Continue;
+}
+
+TextureStorage11_2D::~TextureStorage11_2D() {}
+
+angle::Result TextureStorage11_2D::copyToStorage(const gl::Context *context,
+ TextureStorage *destStorage)
+{
+ ASSERT(destStorage);
+
+ TextureStorage11_2D *dest11 = GetAs<TextureStorage11_2D>(destStorage);
+ ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
+
+ if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
+ {
+ // If either mTexture or mLevelZeroTexture exist, then we need to copy them into the
+ // corresponding textures in destStorage.
+ if (mTexture.valid())
+ {
+ ANGLE_TRY(dest11->useLevelZeroWorkaroundTexture(context, false));
+
+ const TextureHelper11 *destResource = nullptr;
+ ANGLE_TRY(dest11->getResource(context, &destResource));
+
+ immediateContext->CopyResource(destResource->get(), mTexture.get());
+ }
+
+ if (mLevelZeroTexture.valid())
+ {
+ ANGLE_TRY(dest11->useLevelZeroWorkaroundTexture(context, true));
+
+ const TextureHelper11 *destResource = nullptr;
+ ANGLE_TRY(dest11->getResource(context, &destResource));
+
+ immediateContext->CopyResource(destResource->get(), mLevelZeroTexture.get());
+ }
+
+ return angle::Result::Continue;
+ }
+
+ const TextureHelper11 *sourceResouce = nullptr;
+ ANGLE_TRY(getResource(context, &sourceResouce));
+
+ const TextureHelper11 *destResource = nullptr;
+ ANGLE_TRY(dest11->getResource(context, &destResource));
+
+ immediateContext->CopyResource(destResource->get(), sourceResouce->get());
+ dest11->markDirty();
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_2D::useLevelZeroWorkaroundTexture(const gl::Context *context,
+ bool useLevelZeroTexture)
+{
+ if (useLevelZeroTexture && mMipLevels > 1)
+ {
+ if (!mUseLevelZeroTexture && mTexture.valid())
+ {
+ ANGLE_TRY(ensureTextureExists(context, 1));
+
+ // Pull data back from the mipped texture if necessary.
+ ASSERT(mLevelZeroTexture.valid());
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+ deviceContext->CopySubresourceRegion(mLevelZeroTexture.get(), 0, 0, 0, 0,
+ mTexture.get(), 0, nullptr);
+ }
+
+ mUseLevelZeroTexture = true;
+ }
+ else
+ {
+ if (mUseLevelZeroTexture && mLevelZeroTexture.valid())
+ {
+ ANGLE_TRY(ensureTextureExists(context, mMipLevels));
+
+ // Pull data back from the level zero texture if necessary.
+ ASSERT(mTexture.valid());
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+ deviceContext->CopySubresourceRegion(mTexture.get(), 0, 0, 0, 0,
+ mLevelZeroTexture.get(), 0, nullptr);
+ }
+
+ mUseLevelZeroTexture = false;
+ }
+
+ return angle::Result::Continue;
+}
+
+void TextureStorage11_2D::associateImage(Image11 *image, const gl::ImageIndex &index)
+{
+ const GLint level = index.getLevelIndex();
+
+ ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+ if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+ {
+ mAssociatedImages[level] = image;
+ }
+}
+
+void TextureStorage11_2D::verifyAssociatedImageValid(const gl::ImageIndex &index,
+ Image11 *expectedImage)
+{
+ const GLint level = index.getLevelIndex();
+
+ ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+ // This validation check should never return false. It means the Image/TextureStorage
+ // association is broken.
+ ASSERT(mAssociatedImages[level] == expectedImage);
+}
+
+// disassociateImage allows an Image to end its association with a Storage.
+void TextureStorage11_2D::disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage)
+{
+ const GLint level = index.getLevelIndex();
+
+ ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+ ASSERT(mAssociatedImages[level] == expectedImage);
+ mAssociatedImages[level] = nullptr;
+}
+
+// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image
+// recover its data before ending the association.
+angle::Result TextureStorage11_2D::releaseAssociatedImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ Image11 *incomingImage)
+{
+ const GLint level = index.getLevelIndex();
+
+ ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+
+ if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+ {
+ // No need to let the old Image recover its data, if it is also the incoming Image.
+ if (mAssociatedImages[level] != nullptr && mAssociatedImages[level] != incomingImage)
+ {
+ // Ensure that the Image is still associated with this TextureStorage.
+ mAssociatedImages[level]->verifyAssociatedStorageValid(this);
+
+ // Force the image to recover from storage before its data is overwritten.
+ // This will reset mAssociatedImages[level] to nullptr too.
+ ANGLE_TRY(mAssociatedImages[level]->recoverFromAssociatedStorage(context));
+ }
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_2D::getResource(const gl::Context *context,
+ const TextureHelper11 **outResource)
+{
+ if (mUseLevelZeroTexture && mMipLevels > 1)
+ {
+ ANGLE_TRY(ensureTextureExists(context, 1));
+
+ *outResource = &mLevelZeroTexture;
+ return angle::Result::Continue;
+ }
+
+ ANGLE_TRY(ensureTextureExists(context, mMipLevels));
+
+ *outResource = &mTexture;
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_2D::getMippedResource(const gl::Context *context,
+ const TextureHelper11 **outResource)
+{
+ // This shouldn't be called unless the zero max LOD workaround is active.
+ ASSERT(mRenderer->getFeatures().zeroMaxLodWorkaround.enabled);
+
+ ANGLE_TRY(ensureTextureExists(context, mMipLevels));
+
+ *outResource = &mTexture;
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_2D::ensureTextureExists(const gl::Context *context, int mipLevels)
+{
+ // If mMipLevels = 1 then always use mTexture rather than mLevelZeroTexture.
+ ANGLE_TRY(resolveTexture(context));
+ bool useLevelZeroTexture = mRenderer->getFeatures().zeroMaxLodWorkaround.enabled
+ ? (mipLevels == 1) && (mMipLevels > 1)
+ : false;
+ TextureHelper11 *outputTexture = useLevelZeroTexture ? &mLevelZeroTexture : &mTexture;
+
+ // if the width or height is not positive this should be treated as an incomplete texture
+ // we handle that here by skipping the d3d texture creation
+ if (!outputTexture->valid() && mTextureWidth > 0 && mTextureHeight > 0)
+ {
+ ASSERT(mipLevels > 0);
+
+ D3D11_TEXTURE2D_DESC desc;
+ desc.Width = mTextureWidth; // Compressed texture size constraints?
+ desc.Height = mTextureHeight;
+ desc.MipLevels = mipLevels;
+ desc.ArraySize = 1;
+ desc.Format = isUnorderedAccess() ? mFormatInfo.typelessFormat : mFormatInfo.texFormat;
+ desc.SampleDesc.Count = 1;
+ desc.SampleDesc.Quality = 0;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.BindFlags = getBindFlags();
+ desc.CPUAccessFlags = 0;
+ desc.MiscFlags = getMiscFlags();
+
+ ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, mFormatInfo,
+ outputTexture));
+
+ if (useLevelZeroTexture)
+ {
+ outputTexture->setLabels("TexStorage2D.Level0Texture", &mKHRDebugLabel);
+ }
+ else
+ {
+ outputTexture->setLabels("TexStorage2D.Texture", &mKHRDebugLabel);
+ }
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_2D::findRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) const
+{
+ ASSERT(!index.hasLayer());
+
+ const int level = index.getLevelIndex();
+ ASSERT(level >= 0 && level < getLevelCount());
+
+ bool needMS = samples > 0;
+ if (needMS)
+ {
+ return findMultisampledRenderTarget(context, index, samples, outRT);
+ }
+
+ ASSERT(outRT);
+ if (mRenderTarget[level])
+ {
+ *outRT = mRenderTarget[level].get();
+ return angle::Result::Continue;
+ }
+
+ if (mUseLevelZeroTexture)
+ {
+ ASSERT(level == 0);
+ *outRT = mLevelZeroRenderTarget.get();
+ return angle::Result::Continue;
+ }
+
+ *outRT = nullptr;
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_2D::getRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT)
+{
+ ASSERT(!index.hasLayer());
+
+ const int level = index.getLevelIndex();
+ ASSERT(level >= 0 && level < getLevelCount());
+
+ bool needMS = samples > 0;
+ if (needMS)
+ {
+ return getMultisampledRenderTarget(context, index, samples, outRT);
+ }
+ else
+ {
+ ANGLE_TRY(resolveTexture(context));
+ }
+
+ // In GL ES 2.0, the application can only render to level zero of the texture (Section 4.4.3 of
+ // the GLES 2.0 spec, page 113 of version 2.0.25). Other parts of TextureStorage11_2D could
+ // create RTVs on non-zero levels of the texture (e.g. generateMipmap).
+ // On Feature Level 9_3, this is unlikely to be useful. The renderer can't create SRVs on the
+ // individual levels of the texture, so methods like generateMipmap can't do anything useful
+ // with non-zero-level RTVs. Therefore if level > 0 on 9_3 then there's almost certainly
+ // something wrong.
+ ASSERT(
+ !(mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3 && level > 0));
+ ASSERT(outRT);
+ if (mRenderTarget[level])
+ {
+ *outRT = mRenderTarget[level].get();
+ return angle::Result::Continue;
+ }
+
+ if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
+ {
+ ASSERT(level == 0);
+ ANGLE_TRY(useLevelZeroWorkaroundTexture(context, true));
+ }
+
+ const TextureHelper11 *texture = nullptr;
+ ANGLE_TRY(getResource(context, &texture));
+
+ const d3d11::SharedSRV *srv = nullptr;
+ ANGLE_TRY(getSRVLevel(context, level, SRVType::Sample, &srv));
+
+ const d3d11::SharedSRV *blitSRV = nullptr;
+ ANGLE_TRY(getSRVLevel(context, level, SRVType::Blit, &blitSRV));
+
+ Context11 *context11 = GetImplAs<Context11>(context);
+
+ if (mUseLevelZeroTexture)
+ {
+ if (!mLevelZeroRenderTarget)
+ {
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = mFormatInfo.rtvFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
+ rtvDesc.Texture2D.MipSlice = mTopLevel + level;
+
+ d3d11::RenderTargetView rtv;
+ ANGLE_TRY(
+ mRenderer->allocateResource(context11, rtvDesc, mLevelZeroTexture.get(), &rtv));
+ rtv.setLabels("TexStorage2D.Level0RTV", &mKHRDebugLabel);
+
+ mLevelZeroRenderTarget.reset(new TextureRenderTarget11(
+ std::move(rtv), mLevelZeroTexture, d3d11::SharedSRV(), d3d11::SharedSRV(),
+ mFormatInfo.internalFormat, getFormatSet(), getLevelWidth(level),
+ getLevelHeight(level), 1, 0));
+ }
+
+ *outRT = mLevelZeroRenderTarget.get();
+ return angle::Result::Continue;
+ }
+
+ if (mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN)
+ {
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = mFormatInfo.rtvFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
+ rtvDesc.Texture2D.MipSlice = mTopLevel + level;
+
+ d3d11::RenderTargetView rtv;
+ ANGLE_TRY(mRenderer->allocateResource(context11, rtvDesc, texture->get(), &rtv));
+ rtv.setLabels("TexStorage2D.RTV", &mKHRDebugLabel);
+
+ mRenderTarget[level].reset(new TextureRenderTarget11(
+ std::move(rtv), *texture, *srv, *blitSRV, mFormatInfo.internalFormat, getFormatSet(),
+ getLevelWidth(level), getLevelHeight(level), 1, 0));
+
+ *outRT = mRenderTarget[level].get();
+ return angle::Result::Continue;
+ }
+
+ ASSERT(mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN);
+
+ D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
+ dsvDesc.Format = mFormatInfo.dsvFormat;
+ dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
+ dsvDesc.Texture2D.MipSlice = mTopLevel + level;
+ dsvDesc.Flags = 0;
+
+ d3d11::DepthStencilView dsv;
+ ANGLE_TRY(mRenderer->allocateResource(context11, dsvDesc, texture->get(), &dsv));
+ dsv.setLabels("TexStorage2D.DSV", &mKHRDebugLabel);
+
+ mRenderTarget[level].reset(new TextureRenderTarget11(
+ std::move(dsv), *texture, *srv, mFormatInfo.internalFormat, getFormatSet(),
+ getLevelWidth(level), getLevelHeight(level), 1, 0));
+
+ *outRT = mRenderTarget[level].get();
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_2D::createSRVForSampler(const gl::Context *context,
+ int baseLevel,
+ int mipLevels,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedSRV *outSRV)
+{
+ ASSERT(outSRV);
+
+ D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+ srvDesc.Format = format;
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
+ srvDesc.Texture2D.MostDetailedMip = mTopLevel + baseLevel;
+ srvDesc.Texture2D.MipLevels = mipLevels;
+
+ const TextureHelper11 *srvTexture = &texture;
+
+ if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
+ {
+ ASSERT(mTopLevel == 0);
+ ASSERT(baseLevel == 0);
+ // This code also assumes that the incoming texture equals either mLevelZeroTexture or
+ // mTexture.
+
+ if (mipLevels == 1 && mMipLevels > 1)
+ {
+ // We must use a SRV on the level-zero-only texture.
+ ANGLE_TRY(ensureTextureExists(context, 1));
+ srvTexture = &mLevelZeroTexture;
+ }
+ else
+ {
+ ASSERT(mipLevels == static_cast<int>(mMipLevels));
+ ASSERT(mTexture.valid() && texture == mTexture);
+ srvTexture = &mTexture;
+ }
+ }
+
+ ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, srvTexture->get(),
+ outSRV));
+ outSRV->setLabels("TexStorage2D.SRV", &mKHRDebugLabel);
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_2D::createSRVForImage(const gl::Context *context,
+ int level,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedSRV *outSRV)
+{
+ ASSERT(outSRV);
+ D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+ srvDesc.Format = format;
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
+ srvDesc.Texture2D.MostDetailedMip = mTopLevel + level;
+ srvDesc.Texture2D.MipLevels = 1;
+ ANGLE_TRY(
+ mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV));
+ outSRV->setLabels("TexStorage2D.SRVForImage", &mKHRDebugLabel);
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_2D::createUAVForImage(const gl::Context *context,
+ int level,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedUAV *outUAV)
+{
+ ASSERT(outUAV);
+ D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
+ uavDesc.Format = format;
+ uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
+ uavDesc.Texture2D.MipSlice = mTopLevel + level;
+ ANGLE_TRY(
+ mRenderer->allocateResource(GetImplAs<Context11>(context), uavDesc, texture.get(), outUAV));
+ outUAV->setLabels("TexStorage2D.UAVForImage", &mKHRDebugLabel);
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_2D::getSwizzleTexture(const gl::Context *context,
+ const TextureHelper11 **outTexture)
+{
+ ASSERT(outTexture);
+
+ if (!mSwizzleTexture.valid())
+ {
+ const auto &format = mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps());
+
+ D3D11_TEXTURE2D_DESC desc;
+ desc.Width = mTextureWidth;
+ desc.Height = mTextureHeight;
+ desc.MipLevels = mMipLevels;
+ desc.ArraySize = 1;
+ desc.Format = format.texFormat;
+ desc.SampleDesc.Count = 1;
+ desc.SampleDesc.Quality = 0;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
+ desc.CPUAccessFlags = 0;
+ desc.MiscFlags = 0;
+
+ ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, format,
+ &mSwizzleTexture));
+ mSwizzleTexture.setLabels("TexStorage2D.SwizzleTexture", &mKHRDebugLabel);
+ }
+
+ *outTexture = &mSwizzleTexture;
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_2D::getSwizzleRenderTarget(const gl::Context *context,
+ int mipLevel,
+ const d3d11::RenderTargetView **outRTV)
+{
+ ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
+ ASSERT(outRTV);
+
+ if (!mSwizzleRenderTargets[mipLevel].valid())
+ {
+ const TextureHelper11 *swizzleTexture = nullptr;
+ ANGLE_TRY(getSwizzleTexture(context, &swizzleTexture));
+
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format =
+ mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()).rtvFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
+ rtvDesc.Texture2D.MipSlice = mTopLevel + mipLevel;
+
+ ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), rtvDesc,
+ mSwizzleTexture.get(),
+ &mSwizzleRenderTargets[mipLevel]));
+ }
+
+ *outRTV = &mSwizzleRenderTargets[mipLevel];
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_2D::ensureDropStencilTexture(const gl::Context *context,
+ DropStencil *dropStencilOut)
+{
+ if (mDropStencilTexture.valid())
+ {
+ *dropStencilOut = DropStencil::ALREADY_EXISTS;
+ return angle::Result::Continue;
+ }
+
+ 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;
+
+ const auto &format =
+ d3d11::Format::Get(GL_DEPTH_COMPONENT32F, mRenderer->getRenderer11DeviceCaps());
+ ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), dropDesc, format,
+ &mDropStencilTexture));
+ mDropStencilTexture.setLabels("TexStorage2D.DropStencil", &mKHRDebugLabel);
+
+ ANGLE_TRY(initDropStencilTexture(context, gl::ImageIndexIterator::Make2D(0, mMipLevels)));
+
+ *dropStencilOut = DropStencil::CREATED;
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_2D::resolveTexture(const gl::Context *context)
+{
+ if (mMSTexInfo && mMSTexInfo->msTex && mMSTexInfo->msTextureNeedsResolve)
+ {
+ ANGLE_TRY(resolveTextureHelper(context, mTexture));
+ onStateChange(angle::SubjectMessage::ContentsChanged);
+ }
+ return angle::Result::Continue;
+}
+
+TextureStorage11_External::TextureStorage11_External(
+ Renderer11 *renderer,
+ egl::Stream *stream,
+ const egl::Stream::GLTextureDescription &glDesc,
+ const std::string &label)
+ : TextureStorage11(renderer, D3D11_BIND_SHADER_RESOURCE, 0, glDesc.internalFormat, label)
+{
+ ASSERT(stream->getProducerType() == egl::Stream::ProducerType::D3D11Texture);
+ auto *producer = static_cast<StreamProducerD3DTexture *>(stream->getImplementation());
+ mTexture.set(producer->getD3DTexture(), mFormatInfo);
+ mSubresourceIndex = producer->getArraySlice();
+ mTexture.get()->AddRef();
+ mMipLevels = 1;
+
+ D3D11_TEXTURE2D_DESC desc;
+ mTexture.getDesc(&desc);
+ mTextureWidth = desc.Width;
+ mTextureHeight = desc.Height;
+ mTextureDepth = 1;
+ mHasKeyedMutex = (desc.MiscFlags & D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX) != 0;
+}
+
+angle::Result TextureStorage11_External::onDestroy(const gl::Context *context)
+{
+ if (mHasKeyedMutex)
+ {
+ // If the keyed mutex is released that will unbind it and cause the state cache to become
+ // desynchronized.
+ mRenderer->getStateManager()->invalidateBoundViews();
+ }
+
+ return angle::Result::Continue;
+}
+
+TextureStorage11_External::~TextureStorage11_External() {}
+
+angle::Result TextureStorage11_External::copyToStorage(const gl::Context *context,
+ TextureStorage *destStorage)
+{
+ UNIMPLEMENTED();
+ return angle::Result::Continue;
+}
+
+void TextureStorage11_External::associateImage(Image11 *image, const gl::ImageIndex &index)
+{
+ ASSERT(index.getLevelIndex() == 0);
+ mAssociatedImage = image;
+}
+
+void TextureStorage11_External::verifyAssociatedImageValid(const gl::ImageIndex &index,
+ Image11 *expectedImage)
+{
+ ASSERT(index.getLevelIndex() == 0 && mAssociatedImage == expectedImage);
+}
+
+void TextureStorage11_External::disassociateImage(const gl::ImageIndex &index,
+ Image11 *expectedImage)
+{
+ ASSERT(index.getLevelIndex() == 0);
+ ASSERT(mAssociatedImage == expectedImage);
+ mAssociatedImage = nullptr;
+}
+
+angle::Result TextureStorage11_External::releaseAssociatedImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ Image11 *incomingImage)
+{
+ ASSERT(index.getLevelIndex() == 0);
+
+ if (mAssociatedImage != nullptr && mAssociatedImage != incomingImage)
+ {
+ mAssociatedImage->verifyAssociatedStorageValid(this);
+
+ ANGLE_TRY(mAssociatedImage->recoverFromAssociatedStorage(context));
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_External::getResource(const gl::Context *context,
+ const TextureHelper11 **outResource)
+{
+ *outResource = &mTexture;
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_External::getMippedResource(const gl::Context *context,
+ const TextureHelper11 **outResource)
+{
+ *outResource = &mTexture;
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_External::findRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) const
+{
+ // Render targets are not supported for external textures
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
+ return angle::Result::Stop;
+}
+
+angle::Result TextureStorage11_External::getRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT)
+{
+ // Render targets are not supported for external textures
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
+ return angle::Result::Stop;
+}
+
+angle::Result TextureStorage11_External::createSRVForSampler(const gl::Context *context,
+ int baseLevel,
+ int mipLevels,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedSRV *outSRV)
+{
+ // Since external textures are treates as non-mipmapped textures, we ignore mipmap levels and
+ // use the specified subresource ID the storage was created with.
+ ASSERT(mipLevels == 1);
+ ASSERT(outSRV);
+
+ D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+ srvDesc.Format = format;
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
+ // subresource index is equal to the mip level for 2D textures
+ srvDesc.Texture2DArray.MostDetailedMip = 0;
+ srvDesc.Texture2DArray.MipLevels = 1;
+ srvDesc.Texture2DArray.FirstArraySlice = mSubresourceIndex;
+ srvDesc.Texture2DArray.ArraySize = 1;
+
+ ANGLE_TRY(
+ mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV));
+ outSRV->setLabels("TexStorage2D.SRV", &mKHRDebugLabel);
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_External::createSRVForImage(const gl::Context *context,
+ int level,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedSRV *outSRV)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
+ return angle::Result::Stop;
+}
+
+angle::Result TextureStorage11_External::createUAVForImage(const gl::Context *context,
+ int level,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedUAV *outUAV)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
+ return angle::Result::Stop;
+}
+
+angle::Result TextureStorage11_External::getSwizzleTexture(const gl::Context *context,
+ const TextureHelper11 **outTexture)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
+ return angle::Result::Stop;
+}
+
+angle::Result TextureStorage11_External::getSwizzleRenderTarget(
+ const gl::Context *context,
+ int mipLevel,
+ const d3d11::RenderTargetView **outRTV)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
+ return angle::Result::Stop;
+}
+
+void TextureStorage11_External::onLabelUpdate()
+{
+ if (mTexture.valid())
+ {
+ mTexture.setKHRDebugLabel(&mKHRDebugLabel);
+ }
+}
+
+TextureStorage11ImmutableBase::TextureStorage11ImmutableBase(Renderer11 *renderer,
+ UINT bindFlags,
+ UINT miscFlags,
+ GLenum internalFormat,
+ const std::string &label)
+ : TextureStorage11(renderer, bindFlags, miscFlags, internalFormat, label)
+{}
+
+void TextureStorage11ImmutableBase::associateImage(Image11 *, const gl::ImageIndex &) {}
+
+void TextureStorage11ImmutableBase::disassociateImage(const gl::ImageIndex &, Image11 *) {}
+
+void TextureStorage11ImmutableBase::verifyAssociatedImageValid(const gl::ImageIndex &, Image11 *) {}
+
+angle::Result TextureStorage11ImmutableBase::releaseAssociatedImage(const gl::Context *context,
+ const gl::ImageIndex &,
+ Image11 *)
+{
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11ImmutableBase::createSRVForImage(const gl::Context *context,
+ int level,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedSRV *outSRV)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
+ return angle::Result::Stop;
+}
+
+angle::Result TextureStorage11ImmutableBase::createUAVForImage(const gl::Context *context,
+ int level,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedUAV *outUAV)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
+ return angle::Result::Stop;
+}
+
+TextureStorage11_EGLImage::TextureStorage11_EGLImage(Renderer11 *renderer,
+ EGLImageD3D *eglImage,
+ RenderTarget11 *renderTarget11,
+ const std::string &label)
+ : TextureStorage11ImmutableBase(renderer,
+ D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE,
+ 0,
+ renderTarget11->getInternalFormat(),
+ label),
+ mImage(eglImage),
+ mCurrentRenderTarget(0),
+ mSwizzleTexture(),
+ mSwizzleRenderTargets(gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+{
+ mCurrentRenderTarget = reinterpret_cast<uintptr_t>(renderTarget11);
+
+ mMipLevels = 1;
+ mTextureWidth = renderTarget11->getWidth();
+ mTextureHeight = renderTarget11->getHeight();
+ mTextureDepth = 1;
+}
+
+TextureStorage11_EGLImage::~TextureStorage11_EGLImage() {}
+
+angle::Result TextureStorage11_EGLImage::getSubresourceIndex(const gl::Context *context,
+ const gl::ImageIndex &index,
+ UINT *outSubresourceIndex) const
+{
+ ASSERT(index.getType() == gl::TextureType::_2D);
+ ASSERT(index.getLevelIndex() == 0);
+
+ RenderTarget11 *renderTarget11 = nullptr;
+ ANGLE_TRY(getImageRenderTarget(context, &renderTarget11));
+ *outSubresourceIndex = renderTarget11->getSubresourceIndex();
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_EGLImage::getResource(const gl::Context *context,
+ const TextureHelper11 **outResource)
+{
+ ANGLE_TRY(checkForUpdatedRenderTarget(context));
+
+ RenderTarget11 *renderTarget11 = nullptr;
+ ANGLE_TRY(getImageRenderTarget(context, &renderTarget11));
+ *outResource = &renderTarget11->getTexture();
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_EGLImage::getSRVForSampler(const gl::Context *context,
+ const gl::TextureState &textureState,
+ const gl::SamplerState &sampler,
+ const d3d11::SharedSRV **outSRV)
+{
+ ANGLE_TRY(checkForUpdatedRenderTarget(context));
+ return TextureStorage11::getSRVForSampler(context, textureState, sampler, outSRV);
+}
+
+angle::Result TextureStorage11_EGLImage::getMippedResource(const gl::Context *context,
+ const TextureHelper11 **)
+{
+ // This shouldn't be called unless the zero max LOD workaround is active.
+ // EGL images are unavailable in this configuration.
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
+ return angle::Result::Stop;
+}
+
+angle::Result TextureStorage11_EGLImage::findRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) const
+{
+ // Since the render target of an EGL image will be updated when orphaning, trying to find a
+ // cache of it can be rarely useful.
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
+ return angle::Result::Stop;
+}
+
+angle::Result TextureStorage11_EGLImage::getRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT)
+{
+ ASSERT(!index.hasLayer());
+ ASSERT(index.getLevelIndex() == 0);
+
+ ANGLE_TRY(checkForUpdatedRenderTarget(context));
+
+ return mImage->getRenderTarget(context, outRT);
+}
+
+angle::Result TextureStorage11_EGLImage::copyToStorage(const gl::Context *context,
+ TextureStorage *destStorage)
+{
+ const TextureHelper11 *sourceResouce = nullptr;
+ ANGLE_TRY(getResource(context, &sourceResouce));
+
+ ASSERT(destStorage);
+ TextureStorage11_2D *dest11 = GetAs<TextureStorage11_2D>(destStorage);
+ const TextureHelper11 *destResource = nullptr;
+ ANGLE_TRY(dest11->getResource(context, &destResource));
+
+ ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
+ immediateContext->CopyResource(destResource->get(), sourceResouce->get());
+
+ dest11->markDirty();
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_EGLImage::useLevelZeroWorkaroundTexture(const gl::Context *context,
+ bool)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
+ return angle::Result::Stop;
+}
+
+angle::Result TextureStorage11_EGLImage::getSwizzleTexture(const gl::Context *context,
+ const TextureHelper11 **outTexture)
+{
+ ASSERT(outTexture);
+
+ if (!mSwizzleTexture.valid())
+ {
+ const auto &format = mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps());
+
+ D3D11_TEXTURE2D_DESC desc;
+ desc.Width = mTextureWidth;
+ desc.Height = mTextureHeight;
+ desc.MipLevels = mMipLevels;
+ desc.ArraySize = 1;
+ desc.Format = format.texFormat;
+ desc.SampleDesc.Count = 1;
+ desc.SampleDesc.Quality = 0;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
+ desc.CPUAccessFlags = 0;
+ desc.MiscFlags = 0;
+
+ ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, format,
+ &mSwizzleTexture));
+ mSwizzleTexture.setLabels("TexStorageEGLImage.SwizzleTexture", &mKHRDebugLabel);
+ }
+
+ *outTexture = &mSwizzleTexture;
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_EGLImage::getSwizzleRenderTarget(
+ const gl::Context *context,
+ int mipLevel,
+ const d3d11::RenderTargetView **outRTV)
+{
+ ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
+ ASSERT(outRTV);
+
+ if (!mSwizzleRenderTargets[mipLevel].valid())
+ {
+ const TextureHelper11 *swizzleTexture = nullptr;
+ ANGLE_TRY(getSwizzleTexture(context, &swizzleTexture));
+
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format =
+ mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()).rtvFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
+ rtvDesc.Texture2D.MipSlice = mTopLevel + mipLevel;
+
+ ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), rtvDesc,
+ mSwizzleTexture.get(),
+ &mSwizzleRenderTargets[mipLevel]));
+ }
+
+ *outRTV = &mSwizzleRenderTargets[mipLevel];
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_EGLImage::checkForUpdatedRenderTarget(const gl::Context *context)
+{
+ RenderTarget11 *renderTarget11 = nullptr;
+ ANGLE_TRY(getImageRenderTarget(context, &renderTarget11));
+
+ if (mCurrentRenderTarget != reinterpret_cast<uintptr_t>(renderTarget11))
+ {
+ clearSRVCache();
+ mCurrentRenderTarget = reinterpret_cast<uintptr_t>(renderTarget11);
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_EGLImage::createSRVForSampler(const gl::Context *context,
+ int baseLevel,
+ int mipLevels,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedSRV *outSRV)
+{
+ ASSERT(baseLevel == 0);
+ ASSERT(mipLevels == 1);
+ ASSERT(outSRV);
+
+ // Create a new SRV only for the swizzle texture. Otherwise just return the Image's
+ // RenderTarget's SRV.
+ if (texture == mSwizzleTexture)
+ {
+ D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+ srvDesc.Format = format;
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
+ srvDesc.Texture2D.MostDetailedMip = mTopLevel + baseLevel;
+ srvDesc.Texture2D.MipLevels = mipLevels;
+
+ ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(),
+ outSRV));
+ outSRV->setLabels("TexStorageEGLImage.SRV", &mKHRDebugLabel);
+ }
+ else
+ {
+ RenderTarget11 *renderTarget = nullptr;
+ ANGLE_TRY(getImageRenderTarget(context, &renderTarget));
+
+ ASSERT(texture == renderTarget->getTexture());
+
+ const d3d11::SharedSRV *srv;
+ ANGLE_TRY(renderTarget->getShaderResourceView(context, &srv));
+
+ *outSRV = srv->makeCopy();
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_EGLImage::getImageRenderTarget(const gl::Context *context,
+ RenderTarget11 **outRT) const
+{
+ RenderTargetD3D *renderTargetD3D = nullptr;
+ ANGLE_TRY(mImage->getRenderTarget(context, &renderTargetD3D));
+ *outRT = GetAs<RenderTarget11>(renderTargetD3D);
+ return angle::Result::Continue;
+}
+
+void TextureStorage11_EGLImage::onLabelUpdate()
+{
+ if (mSwizzleTexture.valid())
+ {
+ mSwizzleTexture.setKHRDebugLabel(&mKHRDebugLabel);
+ }
+}
+
+TextureStorage11_Cube::TextureStorage11_Cube(Renderer11 *renderer,
+ GLenum internalformat,
+ BindFlags bindFlags,
+ int size,
+ int levels,
+ bool hintLevelZeroOnly,
+ const std::string &label)
+ : TextureStorage11(
+ renderer,
+ GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), bindFlags),
+ GetTextureMiscFlags(internalformat,
+ renderer->getRenderer11DeviceCaps(),
+ bindFlags,
+ levels),
+ internalformat,
+ label),
+ mTexture(),
+ mLevelZeroTexture(),
+ mUseLevelZeroTexture(hintLevelZeroOnly && levels > 1),
+ mSwizzleTexture()
+{
+ for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
+ {
+ for (unsigned int face = 0; face < gl::kCubeFaceCount; face++)
+ {
+ mAssociatedImages[face][level] = nullptr;
+ mRenderTarget[face][level] = nullptr;
+ }
+ }
+
+ for (unsigned int face = 0; face < gl::kCubeFaceCount; face++)
+ {
+ mLevelZeroRenderTarget[face] = nullptr;
+ }
+
+ // adjust size if needed for compressed textures
+ int height = size;
+ d3d11::MakeValidSize(false, mFormatInfo.texFormat, &size, &height, &mTopLevel);
+
+ mMipLevels = mTopLevel + levels;
+ mTextureWidth = size;
+ mTextureHeight = size;
+ mTextureDepth = 1;
+
+ // The LevelZeroOnly hint should only be true if the zero max LOD workaround is active.
+ ASSERT(!mUseLevelZeroTexture || mRenderer->getFeatures().zeroMaxLodWorkaround.enabled);
+}
+
+angle::Result TextureStorage11_Cube::onDestroy(const gl::Context *context)
+{
+ for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
+ {
+ for (unsigned int face = 0; face < gl::kCubeFaceCount; face++)
+ {
+ if (mAssociatedImages[face][level] != nullptr)
+ {
+ mAssociatedImages[face][level]->verifyAssociatedStorageValid(this);
+
+ // We must let the Images recover their data before we delete it from the
+ // TextureStorage.
+ ANGLE_TRY(mAssociatedImages[face][level]->recoverFromAssociatedStorage(context));
+ }
+ }
+ }
+
+ return angle::Result::Continue;
+}
+
+TextureStorage11_Cube::~TextureStorage11_Cube() {}
+
+angle::Result TextureStorage11_Cube::getSubresourceIndex(const gl::Context *context,
+ const gl::ImageIndex &index,
+ UINT *outSubresourceIndex) const
+{
+ UINT arraySlice = index.cubeMapFaceIndex();
+ if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled && mUseLevelZeroTexture &&
+ index.getLevelIndex() == 0)
+ {
+ UINT subresource = D3D11CalcSubresource(0, arraySlice, 1);
+ ASSERT(subresource != std::numeric_limits<UINT>::max());
+ *outSubresourceIndex = subresource;
+ }
+ else
+ {
+ UINT mipSlice = static_cast<UINT>(index.getLevelIndex() + mTopLevel);
+ UINT subresource = D3D11CalcSubresource(mipSlice, arraySlice, mMipLevels);
+ ASSERT(subresource != std::numeric_limits<UINT>::max());
+ *outSubresourceIndex = subresource;
+ }
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_Cube::copyToStorage(const gl::Context *context,
+ TextureStorage *destStorage)
+{
+ ASSERT(destStorage);
+
+ TextureStorage11_Cube *dest11 = GetAs<TextureStorage11_Cube>(destStorage);
+
+ if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
+ {
+ ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
+
+ // If either mTexture or mLevelZeroTexture exist, then we need to copy them into the
+ // corresponding textures in destStorage.
+ if (mTexture.valid())
+ {
+ ANGLE_TRY(dest11->useLevelZeroWorkaroundTexture(context, false));
+
+ const TextureHelper11 *destResource = nullptr;
+ ANGLE_TRY(dest11->getResource(context, &destResource));
+
+ immediateContext->CopyResource(destResource->get(), mTexture.get());
+ }
+
+ if (mLevelZeroTexture.valid())
+ {
+ ANGLE_TRY(dest11->useLevelZeroWorkaroundTexture(context, true));
+
+ const TextureHelper11 *destResource = nullptr;
+ ANGLE_TRY(dest11->getResource(context, &destResource));
+
+ immediateContext->CopyResource(destResource->get(), mLevelZeroTexture.get());
+ }
+ }
+ else
+ {
+ const TextureHelper11 *sourceResouce = nullptr;
+ ANGLE_TRY(getResource(context, &sourceResouce));
+
+ const TextureHelper11 *destResource = nullptr;
+ ANGLE_TRY(dest11->getResource(context, &destResource));
+
+ ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
+ immediateContext->CopyResource(destResource->get(), sourceResouce->get());
+ }
+
+ dest11->markDirty();
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_Cube::useLevelZeroWorkaroundTexture(const gl::Context *context,
+ bool useLevelZeroTexture)
+{
+ if (useLevelZeroTexture && mMipLevels > 1)
+ {
+ if (!mUseLevelZeroTexture && mTexture.valid())
+ {
+ ANGLE_TRY(ensureTextureExists(context, 1));
+
+ // Pull data back from the mipped texture if necessary.
+ ASSERT(mLevelZeroTexture.valid());
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+
+ for (int face = 0; face < 6; face++)
+ {
+ deviceContext->CopySubresourceRegion(mLevelZeroTexture.get(),
+ D3D11CalcSubresource(0, face, 1), 0, 0, 0,
+ mTexture.get(), face * mMipLevels, nullptr);
+ }
+ }
+
+ mUseLevelZeroTexture = true;
+ }
+ else
+ {
+ if (mUseLevelZeroTexture && mLevelZeroTexture.valid())
+ {
+ ANGLE_TRY(ensureTextureExists(context, mMipLevels));
+
+ // Pull data back from the level zero texture if necessary.
+ ASSERT(mTexture.valid());
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+
+ for (int face = 0; face < 6; face++)
+ {
+ deviceContext->CopySubresourceRegion(mTexture.get(),
+ D3D11CalcSubresource(0, face, mMipLevels), 0,
+ 0, 0, mLevelZeroTexture.get(), face, nullptr);
+ }
+ }
+
+ mUseLevelZeroTexture = false;
+ }
+
+ return angle::Result::Continue;
+}
+
+void TextureStorage11_Cube::associateImage(Image11 *image, const gl::ImageIndex &index)
+{
+ const GLint level = index.getLevelIndex();
+ const GLint layerTarget = index.cubeMapFaceIndex();
+
+ ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+ ASSERT(0 <= layerTarget && layerTarget < static_cast<GLint>(gl::kCubeFaceCount));
+
+ if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+ {
+ if (0 <= layerTarget && layerTarget < static_cast<GLint>(gl::kCubeFaceCount))
+ {
+ mAssociatedImages[layerTarget][level] = image;
+ }
+ }
+}
+
+void TextureStorage11_Cube::verifyAssociatedImageValid(const gl::ImageIndex &index,
+ Image11 *expectedImage)
+{
+ const GLint level = index.getLevelIndex();
+ const GLint layerTarget = index.cubeMapFaceIndex();
+
+ ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+ ASSERT(0 <= layerTarget && layerTarget < static_cast<GLint>(gl::kCubeFaceCount));
+ // This validation check should never return false. It means the Image/TextureStorage
+ // association is broken.
+ ASSERT(mAssociatedImages[layerTarget][level] == expectedImage);
+}
+
+// disassociateImage allows an Image to end its association with a Storage.
+void TextureStorage11_Cube::disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage)
+{
+ const GLint level = index.getLevelIndex();
+ const GLint layerTarget = index.cubeMapFaceIndex();
+
+ ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+ ASSERT(0 <= layerTarget && layerTarget < static_cast<GLint>(gl::kCubeFaceCount));
+ ASSERT(mAssociatedImages[layerTarget][level] == expectedImage);
+ mAssociatedImages[layerTarget][level] = nullptr;
+}
+
+// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image
+// recover its data before ending the association.
+angle::Result TextureStorage11_Cube::releaseAssociatedImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ Image11 *incomingImage)
+{
+ const GLint level = index.getLevelIndex();
+ const GLint layerTarget = index.cubeMapFaceIndex();
+
+ ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+ ASSERT(0 <= layerTarget && layerTarget < static_cast<GLint>(gl::kCubeFaceCount));
+
+ if ((0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
+ {
+ if (0 <= layerTarget && layerTarget < static_cast<GLint>(gl::kCubeFaceCount))
+ {
+ // No need to let the old Image recover its data, if it is also the incoming Image.
+ if (mAssociatedImages[layerTarget][level] != nullptr &&
+ mAssociatedImages[layerTarget][level] != incomingImage)
+ {
+ // Ensure that the Image is still associated with this TextureStorage.
+ mAssociatedImages[layerTarget][level]->verifyAssociatedStorageValid(this);
+
+ // Force the image to recover from storage before its data is overwritten.
+ // This will reset mAssociatedImages[level] to nullptr too.
+ ANGLE_TRY(
+ mAssociatedImages[layerTarget][level]->recoverFromAssociatedStorage(context));
+ }
+ }
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_Cube::getResource(const gl::Context *context,
+ const TextureHelper11 **outResource)
+{
+ if (mUseLevelZeroTexture && mMipLevels > 1)
+ {
+ ANGLE_TRY(ensureTextureExists(context, 1));
+ *outResource = &mLevelZeroTexture;
+ }
+ else
+ {
+ ANGLE_TRY(ensureTextureExists(context, mMipLevels));
+ *outResource = &mTexture;
+ }
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_Cube::getMippedResource(const gl::Context *context,
+ const TextureHelper11 **outResource)
+{
+ // This shouldn't be called unless the zero max LOD workaround is active.
+ ASSERT(mRenderer->getFeatures().zeroMaxLodWorkaround.enabled);
+
+ ANGLE_TRY(ensureTextureExists(context, mMipLevels));
+ *outResource = &mTexture;
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_Cube::ensureTextureExists(const gl::Context *context, int mipLevels)
+{
+ // If mMipLevels = 1 then always use mTexture rather than mLevelZeroTexture.
+ ANGLE_TRY(resolveTexture(context));
+ bool useLevelZeroTexture = mRenderer->getFeatures().zeroMaxLodWorkaround.enabled
+ ? (mipLevels == 1) && (mMipLevels > 1)
+ : false;
+ TextureHelper11 *outputTexture = useLevelZeroTexture ? &mLevelZeroTexture : &mTexture;
+
+ // if the size is not positive this should be treated as an incomplete texture
+ // we handle that here by skipping the d3d texture creation
+ if (!outputTexture->valid() && mTextureWidth > 0 && mTextureHeight > 0)
+ {
+ ASSERT(mMipLevels > 0);
+
+ D3D11_TEXTURE2D_DESC desc;
+ desc.Width = mTextureWidth;
+ desc.Height = mTextureHeight;
+ desc.MipLevels = mipLevels;
+ desc.ArraySize = gl::kCubeFaceCount;
+ desc.Format = isUnorderedAccess() ? mFormatInfo.typelessFormat : mFormatInfo.texFormat;
+ desc.SampleDesc.Count = 1;
+ desc.SampleDesc.Quality = 0;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.BindFlags = getBindFlags();
+ desc.CPUAccessFlags = 0;
+ desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE | getMiscFlags();
+
+ ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, mFormatInfo,
+ outputTexture));
+ outputTexture->setLabels("TexStorageCube.Texture", &mKHRDebugLabel);
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_Cube::findRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) const
+{
+ const int faceIndex = index.cubeMapFaceIndex();
+ const int level = index.getLevelIndex();
+
+ ASSERT(level >= 0 && level < getLevelCount());
+ ASSERT(faceIndex >= 0 && faceIndex < static_cast<GLint>(gl::kCubeFaceCount));
+
+ bool needMS = samples > 0;
+ if (needMS)
+ {
+ return findMultisampledRenderTarget(context, index, samples, outRT);
+ }
+
+ if (!mRenderTarget[faceIndex][level])
+ {
+ if (mUseLevelZeroTexture)
+ {
+ ASSERT(index.getLevelIndex() == 0);
+ ASSERT(outRT);
+ *outRT = mLevelZeroRenderTarget[faceIndex].get();
+ return angle::Result::Continue;
+ }
+ }
+
+ ASSERT(outRT);
+ *outRT = mRenderTarget[faceIndex][level].get();
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_Cube::createRenderTargetSRV(const gl::Context *context,
+ const TextureHelper11 &texture,
+ const gl::ImageIndex &index,
+ DXGI_FORMAT resourceFormat,
+ d3d11::SharedSRV *srv) const
+{
+ D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+ srvDesc.Format = resourceFormat;
+ srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + index.getLevelIndex();
+ srvDesc.Texture2DArray.MipLevels = 1;
+ srvDesc.Texture2DArray.FirstArraySlice = index.cubeMapFaceIndex();
+ srvDesc.Texture2DArray.ArraySize = 1;
+
+ if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_10_0)
+ {
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
+ }
+ else
+ {
+ // Will be used with Texture2D sampler, not TextureCube
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
+ }
+
+ ANGLE_TRY(
+ mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), srv));
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_Cube::getRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT)
+{
+ const int faceIndex = index.cubeMapFaceIndex();
+ const int level = index.getLevelIndex();
+
+ ASSERT(level >= 0 && level < getLevelCount());
+ ASSERT(faceIndex >= 0 && faceIndex < static_cast<GLint>(gl::kCubeFaceCount));
+
+ bool needMS = samples > 0;
+ if (needMS)
+ {
+ return getMultisampledRenderTarget(context, index, samples, outRT);
+ }
+ else
+ {
+ ANGLE_TRY(resolveTexture(context));
+ }
+
+ Context11 *context11 = GetImplAs<Context11>(context);
+
+ if (!mRenderTarget[faceIndex][level])
+ {
+ if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
+ {
+ ASSERT(index.getLevelIndex() == 0);
+ ANGLE_TRY(useLevelZeroWorkaroundTexture(context, true));
+ }
+
+ const TextureHelper11 *texture = nullptr;
+ ANGLE_TRY(getResource(context, &texture));
+
+ if (mUseLevelZeroTexture)
+ {
+ if (!mLevelZeroRenderTarget[faceIndex])
+ {
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = mFormatInfo.rtvFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
+ rtvDesc.Texture2DArray.MipSlice = mTopLevel + level;
+ rtvDesc.Texture2DArray.FirstArraySlice = faceIndex;
+ rtvDesc.Texture2DArray.ArraySize = 1;
+
+ d3d11::RenderTargetView rtv;
+ ANGLE_TRY(
+ mRenderer->allocateResource(context11, rtvDesc, mLevelZeroTexture.get(), &rtv));
+
+ mLevelZeroRenderTarget[faceIndex].reset(new TextureRenderTarget11(
+ std::move(rtv), mLevelZeroTexture, d3d11::SharedSRV(), d3d11::SharedSRV(),
+ mFormatInfo.internalFormat, getFormatSet(), getLevelWidth(level),
+ getLevelHeight(level), 1, 0));
+ }
+
+ ASSERT(outRT);
+ *outRT = mLevelZeroRenderTarget[faceIndex].get();
+ return angle::Result::Continue;
+ }
+
+ d3d11::SharedSRV srv;
+ ANGLE_TRY(createRenderTargetSRV(context, *texture, index, mFormatInfo.srvFormat, &srv));
+ d3d11::SharedSRV blitSRV;
+ if (mFormatInfo.blitSRVFormat != mFormatInfo.srvFormat)
+ {
+ ANGLE_TRY(createRenderTargetSRV(context, *texture, index, mFormatInfo.blitSRVFormat,
+ &blitSRV));
+ }
+ else
+ {
+ blitSRV = srv.makeCopy();
+ }
+
+ srv.setLabels("TexStorageCube.RenderTargetSRV", &mKHRDebugLabel);
+
+ if (mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN)
+ {
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = mFormatInfo.rtvFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
+ rtvDesc.Texture2DArray.MipSlice = mTopLevel + level;
+ rtvDesc.Texture2DArray.FirstArraySlice = faceIndex;
+ rtvDesc.Texture2DArray.ArraySize = 1;
+
+ d3d11::RenderTargetView rtv;
+ ANGLE_TRY(mRenderer->allocateResource(context11, rtvDesc, texture->get(), &rtv));
+ rtv.setLabels("TexStorageCube.RenderTargetRTV", &mKHRDebugLabel);
+
+ mRenderTarget[faceIndex][level].reset(new TextureRenderTarget11(
+ std::move(rtv), *texture, srv, blitSRV, mFormatInfo.internalFormat, getFormatSet(),
+ getLevelWidth(level), getLevelHeight(level), 1, 0));
+ }
+ else if (mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN)
+ {
+ D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
+ dsvDesc.Format = mFormatInfo.dsvFormat;
+ dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
+ dsvDesc.Flags = 0;
+ dsvDesc.Texture2DArray.MipSlice = mTopLevel + level;
+ dsvDesc.Texture2DArray.FirstArraySlice = faceIndex;
+ dsvDesc.Texture2DArray.ArraySize = 1;
+
+ d3d11::DepthStencilView dsv;
+ ANGLE_TRY(mRenderer->allocateResource(context11, dsvDesc, texture->get(), &dsv));
+ dsv.setLabels("TexStorageCube.RenderTargetDSV", &mKHRDebugLabel);
+
+ mRenderTarget[faceIndex][level].reset(new TextureRenderTarget11(
+ std::move(dsv), *texture, srv, mFormatInfo.internalFormat, getFormatSet(),
+ getLevelWidth(level), getLevelHeight(level), 1, 0));
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+ }
+
+ ASSERT(outRT);
+ *outRT = mRenderTarget[faceIndex][level].get();
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_Cube::createSRVForSampler(const gl::Context *context,
+ int baseLevel,
+ int mipLevels,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedSRV *outSRV)
+{
+ ASSERT(outSRV);
+
+ D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+ srvDesc.Format = format;
+
+ // Unnormalized integer cube maps are not supported by DX11; we emulate them as an array of six
+ // 2D textures
+ const GLenum componentType = d3d11::GetComponentType(format);
+ if (componentType == GL_INT || componentType == GL_UNSIGNED_INT)
+ {
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
+ srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + baseLevel;
+ srvDesc.Texture2DArray.MipLevels = mipLevels;
+ srvDesc.Texture2DArray.FirstArraySlice = 0;
+ srvDesc.Texture2DArray.ArraySize = gl::kCubeFaceCount;
+ }
+ else
+ {
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
+ srvDesc.TextureCube.MipLevels = mipLevels;
+ srvDesc.TextureCube.MostDetailedMip = mTopLevel + baseLevel;
+ }
+
+ const TextureHelper11 *srvTexture = &texture;
+
+ if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
+ {
+ ASSERT(mTopLevel == 0);
+ ASSERT(baseLevel == 0);
+ // This code also assumes that the incoming texture equals either mLevelZeroTexture or
+ // mTexture.
+
+ if (mipLevels == 1 && mMipLevels > 1)
+ {
+ // We must use a SRV on the level-zero-only texture.
+ ANGLE_TRY(ensureTextureExists(context, 1));
+ srvTexture = &mLevelZeroTexture;
+ }
+ else
+ {
+ ASSERT(mipLevels == static_cast<int>(mMipLevels));
+ ASSERT(mTexture.valid() && texture == mTexture);
+ srvTexture = &mTexture;
+ }
+ }
+
+ ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, srvTexture->get(),
+ outSRV));
+ outSRV->setLabels("TexStorageCube.SRV", &mKHRDebugLabel);
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_Cube::createSRVForImage(const gl::Context *context,
+ int level,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedSRV *outSRV)
+{
+ ASSERT(outSRV);
+ D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+ srvDesc.Format = format;
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
+ srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + level;
+ srvDesc.Texture2DArray.MipLevels = 1;
+ srvDesc.Texture2DArray.FirstArraySlice = 0;
+ srvDesc.Texture2DArray.ArraySize = gl::kCubeFaceCount;
+ ANGLE_TRY(
+ mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV));
+ outSRV->setLabels("TexStorageCube.SRVForImage", &mKHRDebugLabel);
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_Cube::createUAVForImage(const gl::Context *context,
+ int level,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedUAV *outUAV)
+{
+ ASSERT(outUAV);
+ D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
+ uavDesc.Format = format;
+ uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY;
+ uavDesc.Texture2DArray.MipSlice = mTopLevel + level;
+ uavDesc.Texture2DArray.FirstArraySlice = 0;
+ uavDesc.Texture2DArray.ArraySize = gl::kCubeFaceCount;
+ ANGLE_TRY(
+ mRenderer->allocateResource(GetImplAs<Context11>(context), uavDesc, texture.get(), outUAV));
+ outUAV->setLabels("TexStorageCube.UAVForImage", &mKHRDebugLabel);
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_Cube::getSwizzleTexture(const gl::Context *context,
+ const TextureHelper11 **outTexture)
+{
+ ASSERT(outTexture);
+
+ if (!mSwizzleTexture.valid())
+ {
+ const auto &format = mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps());
+
+ D3D11_TEXTURE2D_DESC desc;
+ desc.Width = mTextureWidth;
+ desc.Height = mTextureHeight;
+ desc.MipLevels = mMipLevels;
+ desc.ArraySize = gl::kCubeFaceCount;
+ desc.Format = format.texFormat;
+ desc.SampleDesc.Count = 1;
+ desc.SampleDesc.Quality = 0;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
+ desc.CPUAccessFlags = 0;
+ desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
+
+ ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, format,
+ &mSwizzleTexture));
+ mSwizzleTexture.setLabels("TexStorageCube.SwizzleTexture", &mKHRDebugLabel);
+ }
+
+ *outTexture = &mSwizzleTexture;
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_Cube::getSwizzleRenderTarget(const gl::Context *context,
+ int mipLevel,
+ const d3d11::RenderTargetView **outRTV)
+{
+ ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
+ ASSERT(outRTV);
+
+ if (!mSwizzleRenderTargets[mipLevel].valid())
+ {
+ const TextureHelper11 *swizzleTexture = nullptr;
+ ANGLE_TRY(getSwizzleTexture(context, &swizzleTexture));
+
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format =
+ mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()).rtvFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
+ rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
+ rtvDesc.Texture2DArray.FirstArraySlice = 0;
+ rtvDesc.Texture2DArray.ArraySize = gl::kCubeFaceCount;
+
+ ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), rtvDesc,
+ mSwizzleTexture.get(),
+ &mSwizzleRenderTargets[mipLevel]));
+ }
+
+ *outRTV = &mSwizzleRenderTargets[mipLevel];
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_Cube::ensureDropStencilTexture(const gl::Context *context,
+ DropStencil *dropStencilOut)
+{
+ if (mDropStencilTexture.valid())
+ {
+ *dropStencilOut = DropStencil::ALREADY_EXISTS;
+ return angle::Result::Continue;
+ }
+
+ 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;
+
+ const auto &format =
+ d3d11::Format::Get(GL_DEPTH_COMPONENT32F, mRenderer->getRenderer11DeviceCaps());
+ ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), dropDesc, format,
+ &mDropStencilTexture));
+ mDropStencilTexture.setLabels("TexStorageCube.DropStencil", &mKHRDebugLabel);
+
+ ANGLE_TRY(initDropStencilTexture(context, gl::ImageIndexIterator::MakeCube(0, mMipLevels)));
+
+ *dropStencilOut = DropStencil::CREATED;
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_Cube::resolveTexture(const gl::Context *context)
+{
+ if (mMSTexInfo && mMSTexInfo->msTex && mMSTexInfo->msTextureNeedsResolve)
+ {
+ ANGLE_TRY(resolveTextureHelper(context, mTexture));
+ onStateChange(angle::SubjectMessage::ContentsChanged);
+ }
+ return angle::Result::Continue;
+}
+
+void TextureStorage11_Cube::onLabelUpdate()
+{
+ if (mTexture.valid())
+ {
+ mTexture.setKHRDebugLabel(&mKHRDebugLabel);
+ }
+ if (mLevelZeroTexture.valid())
+ {
+ mLevelZeroTexture.setKHRDebugLabel(&mKHRDebugLabel);
+ }
+ if (mSwizzleTexture.valid())
+ {
+ mSwizzleTexture.setKHRDebugLabel(&mKHRDebugLabel);
+ }
+}
+
+TextureStorage11_3D::TextureStorage11_3D(Renderer11 *renderer,
+ GLenum internalformat,
+ BindFlags bindFlags,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ int levels,
+ const std::string &label)
+ : TextureStorage11(
+ renderer,
+ GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), bindFlags),
+ GetTextureMiscFlags(internalformat,
+ renderer->getRenderer11DeviceCaps(),
+ bindFlags,
+ levels),
+ internalformat,
+ label)
+{
+ for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+ {
+ mAssociatedImages[i] = nullptr;
+ mLevelRenderTargets[i] = nullptr;
+ }
+
+ // adjust size if needed for compressed textures
+ d3d11::MakeValidSize(false, mFormatInfo.texFormat, &width, &height, &mTopLevel);
+
+ mMipLevels = mTopLevel + levels;
+ mTextureWidth = width;
+ mTextureHeight = height;
+ mTextureDepth = depth;
+}
+
+angle::Result TextureStorage11_3D::onDestroy(const gl::Context *context)
+{
+ for (unsigned i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+ {
+ if (mAssociatedImages[i] != nullptr)
+ {
+ mAssociatedImages[i]->verifyAssociatedStorageValid(this);
+
+ // We must let the Images recover their data before we delete it from the
+ // TextureStorage.
+ ANGLE_TRY(mAssociatedImages[i]->recoverFromAssociatedStorage(context));
+ }
+ }
+
+ return angle::Result::Continue;
+}
+
+TextureStorage11_3D::~TextureStorage11_3D() {}
+
+void TextureStorage11_3D::associateImage(Image11 *image, const gl::ImageIndex &index)
+{
+ const GLint level = index.getLevelIndex();
+
+ ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+
+ if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+ {
+ mAssociatedImages[level] = image;
+ }
+}
+
+void TextureStorage11_3D::verifyAssociatedImageValid(const gl::ImageIndex &index,
+ Image11 *expectedImage)
+{
+ const GLint level = index.getLevelIndex();
+
+ ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+ // This validation check should never return false. It means the Image/TextureStorage
+ // association is broken.
+ ASSERT(mAssociatedImages[level] == expectedImage);
+}
+
+// disassociateImage allows an Image to end its association with a Storage.
+void TextureStorage11_3D::disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage)
+{
+ const GLint level = index.getLevelIndex();
+
+ ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+ ASSERT(mAssociatedImages[level] == expectedImage);
+ mAssociatedImages[level] = nullptr;
+}
+
+// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image
+// recover its data before ending the association.
+angle::Result TextureStorage11_3D::releaseAssociatedImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ Image11 *incomingImage)
+{
+ const GLint level = index.getLevelIndex();
+
+ ASSERT((0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS));
+
+ if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+ {
+ // No need to let the old Image recover its data, if it is also the incoming Image.
+ if (mAssociatedImages[level] != nullptr && mAssociatedImages[level] != incomingImage)
+ {
+ // Ensure that the Image is still associated with this TextureStorage.
+ mAssociatedImages[level]->verifyAssociatedStorageValid(this);
+
+ // Force the image to recover from storage before its data is overwritten.
+ // This will reset mAssociatedImages[level] to nullptr too.
+ ANGLE_TRY(mAssociatedImages[level]->recoverFromAssociatedStorage(context));
+ }
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_3D::getResource(const gl::Context *context,
+ const TextureHelper11 **outResource)
+{
+ // If the width, height or depth are not positive this should be treated as an incomplete
+ // texture. We handle that here by skipping the d3d texture creation.
+ if (!mTexture.valid() && mTextureWidth > 0 && mTextureHeight > 0 && mTextureDepth > 0)
+ {
+ ASSERT(mMipLevels > 0);
+
+ D3D11_TEXTURE3D_DESC desc;
+ desc.Width = mTextureWidth;
+ desc.Height = mTextureHeight;
+ desc.Depth = mTextureDepth;
+ desc.MipLevels = mMipLevels;
+ desc.Format = isUnorderedAccess() ? mFormatInfo.typelessFormat : mFormatInfo.texFormat;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.BindFlags = getBindFlags();
+ desc.CPUAccessFlags = 0;
+ desc.MiscFlags = getMiscFlags();
+
+ ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, mFormatInfo,
+ &mTexture));
+ mTexture.setLabels("TexStorage3D.Texture", &mKHRDebugLabel);
+ }
+
+ *outResource = &mTexture;
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_3D::createSRVForSampler(const gl::Context *context,
+ int baseLevel,
+ int mipLevels,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedSRV *outSRV)
+{
+ ASSERT(outSRV);
+
+ D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+ srvDesc.Format = format;
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
+ srvDesc.Texture3D.MostDetailedMip = baseLevel;
+ srvDesc.Texture3D.MipLevels = mipLevels;
+
+ ANGLE_TRY(
+ mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV));
+ outSRV->setLabels("TexStorage3D.SRV", &mKHRDebugLabel);
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_3D::createSRVForImage(const gl::Context *context,
+ int level,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedSRV *outSRV)
+{
+ ASSERT(outSRV);
+ D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+ srvDesc.Format = format;
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
+ srvDesc.Texture3D.MostDetailedMip = mTopLevel + level;
+ srvDesc.Texture3D.MipLevels = 1;
+ ANGLE_TRY(
+ mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV));
+ outSRV->setLabels("TexStorage3D.SRVForImage", &mKHRDebugLabel);
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_3D::createUAVForImage(const gl::Context *context,
+ int level,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedUAV *outUAV)
+{
+ ASSERT(outUAV);
+ D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
+ uavDesc.Format = format;
+ uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE3D;
+ uavDesc.Texture3D.MipSlice = mTopLevel + level;
+ uavDesc.Texture3D.FirstWSlice = 0;
+ uavDesc.Texture3D.WSize = mTextureDepth;
+ ANGLE_TRY(
+ mRenderer->allocateResource(GetImplAs<Context11>(context), uavDesc, texture.get(), outUAV));
+ outUAV->setLabels("TexStorage3D.UAVForImage", &mKHRDebugLabel);
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_3D::findRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) const
+{
+ const int mipLevel = index.getLevelIndex();
+ ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
+
+ if (!index.hasLayer())
+ {
+ ASSERT(outRT);
+ *outRT = mLevelRenderTargets[mipLevel].get();
+ return angle::Result::Continue;
+ }
+
+ const int layer = index.getLayerIndex();
+
+ LevelLayerKey key(mipLevel, layer);
+ if (mLevelLayerRenderTargets.find(key) == mLevelLayerRenderTargets.end())
+ {
+ ASSERT(outRT);
+ *outRT = nullptr;
+ return angle::Result::Continue;
+ }
+
+ ASSERT(outRT);
+ *outRT = mLevelLayerRenderTargets.at(key).get();
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_3D::getRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT)
+{
+ const int mipLevel = index.getLevelIndex();
+ ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
+
+ ASSERT(mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN);
+
+ Context11 *context11 = GetImplAs<Context11>(context);
+
+ if (!index.hasLayer())
+ {
+ if (!mLevelRenderTargets[mipLevel])
+ {
+ const TextureHelper11 *texture = nullptr;
+ ANGLE_TRY(getResource(context, &texture));
+
+ const d3d11::SharedSRV *srv = nullptr;
+ ANGLE_TRY(getSRVLevel(context, mipLevel, SRVType::Sample, &srv));
+
+ const d3d11::SharedSRV *blitSRV = nullptr;
+ ANGLE_TRY(getSRVLevel(context, mipLevel, SRVType::Blit, &blitSRV));
+
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = mFormatInfo.rtvFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
+ rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
+ rtvDesc.Texture3D.FirstWSlice = 0;
+ rtvDesc.Texture3D.WSize = static_cast<UINT>(-1);
+
+ d3d11::RenderTargetView rtv;
+ ANGLE_TRY(mRenderer->allocateResource(context11, rtvDesc, texture->get(), &rtv));
+ rtv.setLabels("TexStorage3D.RTV", &mKHRDebugLabel);
+
+ mLevelRenderTargets[mipLevel].reset(new TextureRenderTarget11(
+ std::move(rtv), *texture, *srv, *blitSRV, mFormatInfo.internalFormat,
+ getFormatSet(), getLevelWidth(mipLevel), getLevelHeight(mipLevel),
+ getLevelDepth(mipLevel), 0));
+ }
+
+ ASSERT(outRT);
+ *outRT = mLevelRenderTargets[mipLevel].get();
+ return angle::Result::Continue;
+ }
+
+ const int layer = index.getLayerIndex();
+
+ LevelLayerKey key(mipLevel, layer);
+ if (mLevelLayerRenderTargets.find(key) == mLevelLayerRenderTargets.end())
+ {
+ const TextureHelper11 *texture = nullptr;
+ ANGLE_TRY(getResource(context, &texture));
+
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = mFormatInfo.rtvFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
+ rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
+ rtvDesc.Texture3D.FirstWSlice = layer;
+ rtvDesc.Texture3D.WSize = 1;
+
+ const d3d11::SharedSRV *srv = nullptr;
+ ANGLE_TRY(getSRVLevel(context, mipLevel, SRVType::Sample, &srv));
+
+ const d3d11::SharedSRV *blitSRV = nullptr;
+ ANGLE_TRY(getSRVLevel(context, mipLevel, SRVType::Blit, &blitSRV));
+
+ d3d11::RenderTargetView rtv;
+ ANGLE_TRY(mRenderer->allocateResource(context11, rtvDesc, texture->get(), &rtv));
+ rtv.setLabels("TexStorage3D.LayerRTV", &mKHRDebugLabel);
+
+ mLevelLayerRenderTargets[key].reset(new TextureRenderTarget11(
+ std::move(rtv), *texture, *srv, *blitSRV, mFormatInfo.internalFormat, getFormatSet(),
+ getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0));
+ }
+
+ ASSERT(outRT);
+ *outRT = mLevelLayerRenderTargets[key].get();
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_3D::getSwizzleTexture(const gl::Context *context,
+ const TextureHelper11 **outTexture)
+{
+ ASSERT(outTexture);
+
+ if (!mSwizzleTexture.valid())
+ {
+ const auto &format = mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps());
+
+ D3D11_TEXTURE3D_DESC desc;
+ desc.Width = mTextureWidth;
+ desc.Height = mTextureHeight;
+ desc.Depth = mTextureDepth;
+ desc.MipLevels = mMipLevels;
+ desc.Format = format.texFormat;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
+ desc.CPUAccessFlags = 0;
+ desc.MiscFlags = 0;
+
+ ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, format,
+ &mSwizzleTexture));
+ mSwizzleTexture.setLabels("TexStorage3D.SwizzleTexture", &mKHRDebugLabel);
+ }
+
+ *outTexture = &mSwizzleTexture;
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_3D::getSwizzleRenderTarget(const gl::Context *context,
+ int mipLevel,
+ const d3d11::RenderTargetView **outRTV)
+{
+ ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
+ ASSERT(outRTV);
+
+ if (!mSwizzleRenderTargets[mipLevel].valid())
+ {
+ const TextureHelper11 *swizzleTexture = nullptr;
+ ANGLE_TRY(getSwizzleTexture(context, &swizzleTexture));
+
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format =
+ mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()).rtvFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
+ rtvDesc.Texture3D.MipSlice = mTopLevel + mipLevel;
+ rtvDesc.Texture3D.FirstWSlice = 0;
+ rtvDesc.Texture3D.WSize = static_cast<UINT>(-1);
+
+ ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), rtvDesc,
+ mSwizzleTexture.get(),
+ &mSwizzleRenderTargets[mipLevel]));
+ mSwizzleRenderTargets[mipLevel].setLabels("TexStorage3D.SwizzleRTV", &mKHRDebugLabel);
+ }
+
+ *outRTV = &mSwizzleRenderTargets[mipLevel];
+ return angle::Result::Continue;
+}
+
+void TextureStorage11_3D::onLabelUpdate()
+{
+ if (mTexture.valid())
+ {
+ mTexture.setKHRDebugLabel(&mKHRDebugLabel);
+ }
+ if (mSwizzleTexture.valid())
+ {
+ mSwizzleTexture.setKHRDebugLabel(&mKHRDebugLabel);
+ }
+}
+
+TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer11 *renderer,
+ GLenum internalformat,
+ BindFlags bindFlags,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ int levels,
+ const std::string &label)
+ : TextureStorage11(
+ renderer,
+ GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), bindFlags),
+ GetTextureMiscFlags(internalformat,
+ renderer->getRenderer11DeviceCaps(),
+ bindFlags,
+ levels),
+ internalformat,
+ label)
+{
+ // adjust size if needed for compressed textures
+ d3d11::MakeValidSize(false, mFormatInfo.texFormat, &width, &height, &mTopLevel);
+
+ mMipLevels = mTopLevel + levels;
+ mTextureWidth = width;
+ mTextureHeight = height;
+ mTextureDepth = depth;
+}
+
+angle::Result TextureStorage11_2DArray::onDestroy(const gl::Context *context)
+{
+ for (auto iter : mAssociatedImages)
+ {
+ if (iter.second)
+ {
+ iter.second->verifyAssociatedStorageValid(this);
+
+ // We must let the Images recover their data before we delete it from the
+ // TextureStorage.
+ ANGLE_TRY(iter.second->recoverFromAssociatedStorage(context));
+ }
+ }
+ mAssociatedImages.clear();
+
+ return angle::Result::Continue;
+}
+
+TextureStorage11_2DArray::~TextureStorage11_2DArray() {}
+
+void TextureStorage11_2DArray::associateImage(Image11 *image, const gl::ImageIndex &index)
+{
+ const GLint level = index.getLevelIndex();
+ const GLint layerTarget = index.getLayerIndex();
+ const GLint numLayers = index.getLayerCount();
+
+ ASSERT(0 <= level && level < getLevelCount());
+
+ if (0 <= level && level < getLevelCount())
+ {
+ LevelLayerRangeKey key(level, layerTarget, numLayers);
+ mAssociatedImages[key] = image;
+ }
+}
+
+void TextureStorage11_2DArray::verifyAssociatedImageValid(const gl::ImageIndex &index,
+ Image11 *expectedImage)
+{
+ const GLint level = index.getLevelIndex();
+ const GLint layerTarget = index.getLayerIndex();
+ const GLint numLayers = index.getLayerCount();
+
+ LevelLayerRangeKey key(level, layerTarget, numLayers);
+
+ // This validation check should never return false. It means the Image/TextureStorage
+ // association is broken.
+ bool retValue = (mAssociatedImages.find(key) != mAssociatedImages.end() &&
+ (mAssociatedImages[key] == expectedImage));
+ ASSERT(retValue);
+}
+
+// disassociateImage allows an Image to end its association with a Storage.
+void TextureStorage11_2DArray::disassociateImage(const gl::ImageIndex &index,
+ Image11 *expectedImage)
+{
+ const GLint level = index.getLevelIndex();
+ const GLint layerTarget = index.getLayerIndex();
+ const GLint numLayers = index.getLayerCount();
+
+ LevelLayerRangeKey key(level, layerTarget, numLayers);
+
+ bool imageAssociationCorrect = (mAssociatedImages.find(key) != mAssociatedImages.end() &&
+ (mAssociatedImages[key] == expectedImage));
+ ASSERT(imageAssociationCorrect);
+ mAssociatedImages[key] = nullptr;
+}
+
+// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image
+// recover its data before ending the association.
+angle::Result TextureStorage11_2DArray::releaseAssociatedImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ Image11 *incomingImage)
+{
+ const GLint level = index.getLevelIndex();
+ const GLint layerTarget = index.getLayerIndex();
+ const GLint numLayers = index.getLayerCount();
+
+ LevelLayerRangeKey key(level, layerTarget, numLayers);
+
+ if (mAssociatedImages.find(key) != mAssociatedImages.end())
+ {
+ if (mAssociatedImages[key] != nullptr && mAssociatedImages[key] != incomingImage)
+ {
+ // Ensure that the Image is still associated with this TextureStorage.
+ mAssociatedImages[key]->verifyAssociatedStorageValid(this);
+
+ // Force the image to recover from storage before its data is overwritten.
+ // This will reset mAssociatedImages[level] to nullptr too.
+ ANGLE_TRY(mAssociatedImages[key]->recoverFromAssociatedStorage(context));
+ }
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_2DArray::getResource(const gl::Context *context,
+ const TextureHelper11 **outResource)
+{
+ // if the width, height or depth is not positive this should be treated as an incomplete texture
+ // we handle that here by skipping the d3d texture creation
+ if (!mTexture.valid() && mTextureWidth > 0 && mTextureHeight > 0 && mTextureDepth > 0)
+ {
+ ASSERT(mMipLevels > 0);
+
+ D3D11_TEXTURE2D_DESC desc;
+ desc.Width = mTextureWidth;
+ desc.Height = mTextureHeight;
+ desc.MipLevels = mMipLevels;
+ desc.ArraySize = mTextureDepth;
+ desc.Format = isUnorderedAccess() ? mFormatInfo.typelessFormat : mFormatInfo.texFormat;
+ desc.SampleDesc.Count = 1;
+ desc.SampleDesc.Quality = 0;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.BindFlags = getBindFlags();
+ desc.CPUAccessFlags = 0;
+ desc.MiscFlags = getMiscFlags();
+
+ ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, mFormatInfo,
+ &mTexture));
+ mTexture.setLabels("TexStorage2DArray.Texture", &mKHRDebugLabel);
+ }
+
+ *outResource = &mTexture;
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_2DArray::createSRVForSampler(const gl::Context *context,
+ int baseLevel,
+ int mipLevels,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedSRV *outSRV)
+{
+ D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+ srvDesc.Format = format;
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
+ srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + baseLevel;
+ srvDesc.Texture2DArray.MipLevels = mipLevels;
+ srvDesc.Texture2DArray.FirstArraySlice = 0;
+ srvDesc.Texture2DArray.ArraySize = mTextureDepth;
+
+ ANGLE_TRY(
+ mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV));
+ outSRV->setLabels("TexStorage2DArray.SRV", &mKHRDebugLabel);
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_2DArray::createSRVForImage(const gl::Context *context,
+ int level,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedSRV *outSRV)
+{
+ ASSERT(outSRV);
+ D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+ srvDesc.Format = format;
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
+ srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + level;
+ srvDesc.Texture2DArray.MipLevels = 1;
+ srvDesc.Texture2DArray.FirstArraySlice = 0;
+ srvDesc.Texture2DArray.ArraySize = mTextureDepth;
+ ANGLE_TRY(
+ mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV));
+ outSRV->setLabels("TexStorage2DArray.SRVForImage", &mKHRDebugLabel);
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_2DArray::createUAVForImage(const gl::Context *context,
+ int level,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedUAV *outUAV)
+{
+ ASSERT(outUAV);
+ D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
+ uavDesc.Format = format;
+ uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY;
+ uavDesc.Texture2DArray.MipSlice = mTopLevel + level;
+ uavDesc.Texture2DArray.FirstArraySlice = 0;
+ uavDesc.Texture2DArray.ArraySize = mTextureDepth;
+ ANGLE_TRY(
+ mRenderer->allocateResource(GetImplAs<Context11>(context), uavDesc, texture.get(), outUAV));
+ outUAV->setLabels("TexStorage2DArray.UAVForImage", &mKHRDebugLabel);
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_2DArray::findRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) const
+{
+ ASSERT(index.hasLayer());
+
+ const int mipLevel = index.getLevelIndex();
+ const int layer = index.getLayerIndex();
+ const int numLayers = index.getLayerCount();
+
+ ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
+
+ LevelLayerRangeKey key(mipLevel, layer, numLayers);
+ if (mRenderTargets.find(key) == mRenderTargets.end())
+ {
+ ASSERT(outRT);
+ *outRT = nullptr;
+ return angle::Result::Continue;
+ }
+
+ ASSERT(outRT);
+ *outRT = mRenderTargets.at(key).get();
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_2DArray::createRenderTargetSRV(const gl::Context *context,
+ const TextureHelper11 &texture,
+ const gl::ImageIndex &index,
+ DXGI_FORMAT resourceFormat,
+ d3d11::SharedSRV *srv) const
+{
+ D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+ srvDesc.Format = resourceFormat;
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
+ srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + index.getLevelIndex();
+ srvDesc.Texture2DArray.MipLevels = 1;
+ srvDesc.Texture2DArray.FirstArraySlice = index.getLayerIndex();
+ srvDesc.Texture2DArray.ArraySize = index.getLayerCount();
+
+ ANGLE_TRY(
+ mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), srv));
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_2DArray::getRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT)
+{
+ ASSERT(index.hasLayer());
+
+ const int mipLevel = index.getLevelIndex();
+ const int layer = index.getLayerIndex();
+ const int numLayers = index.getLayerCount();
+
+ ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
+
+ LevelLayerRangeKey key(mipLevel, layer, numLayers);
+ if (mRenderTargets.find(key) == mRenderTargets.end())
+ {
+ const TextureHelper11 *texture = nullptr;
+ ANGLE_TRY(getResource(context, &texture));
+ d3d11::SharedSRV srv;
+ ANGLE_TRY(createRenderTargetSRV(context, *texture, index, mFormatInfo.srvFormat, &srv));
+ d3d11::SharedSRV blitSRV;
+ if (mFormatInfo.blitSRVFormat != mFormatInfo.srvFormat)
+ {
+ ANGLE_TRY(createRenderTargetSRV(context, *texture, index, mFormatInfo.blitSRVFormat,
+ &blitSRV));
+ }
+ else
+ {
+ blitSRV = srv.makeCopy();
+ }
+
+ srv.setLabels("TexStorage2DArray.RenderTargetSRV", &mKHRDebugLabel);
+
+ if (mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN)
+ {
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = mFormatInfo.rtvFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
+ rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
+ rtvDesc.Texture2DArray.FirstArraySlice = layer;
+ rtvDesc.Texture2DArray.ArraySize = numLayers;
+
+ d3d11::RenderTargetView rtv;
+ ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), rtvDesc,
+ texture->get(), &rtv));
+ rtv.setLabels("TexStorage2DArray.RenderTargetRTV", &mKHRDebugLabel);
+
+ mRenderTargets[key].reset(new TextureRenderTarget11(
+ std::move(rtv), *texture, srv, blitSRV, mFormatInfo.internalFormat, getFormatSet(),
+ getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0));
+ }
+ else
+ {
+ ASSERT(mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN);
+
+ D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
+ dsvDesc.Format = mFormatInfo.dsvFormat;
+ dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
+ dsvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
+ dsvDesc.Texture2DArray.FirstArraySlice = layer;
+ dsvDesc.Texture2DArray.ArraySize = numLayers;
+ dsvDesc.Flags = 0;
+
+ d3d11::DepthStencilView dsv;
+ ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), dsvDesc,
+ texture->get(), &dsv));
+ dsv.setLabels("TexStorage2DArray.RenderTargetDSV", &mKHRDebugLabel);
+
+ mRenderTargets[key].reset(new TextureRenderTarget11(
+ std::move(dsv), *texture, srv, mFormatInfo.internalFormat, getFormatSet(),
+ getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0));
+ }
+ }
+
+ ASSERT(outRT);
+ *outRT = mRenderTargets[key].get();
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_2DArray::getSwizzleTexture(const gl::Context *context,
+ const TextureHelper11 **outTexture)
+{
+ if (!mSwizzleTexture.valid())
+ {
+ const auto &format = mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps());
+
+ D3D11_TEXTURE2D_DESC desc;
+ desc.Width = mTextureWidth;
+ desc.Height = mTextureHeight;
+ desc.MipLevels = mMipLevels;
+ desc.ArraySize = mTextureDepth;
+ desc.Format = format.texFormat;
+ desc.SampleDesc.Count = 1;
+ desc.SampleDesc.Quality = 0;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
+ desc.CPUAccessFlags = 0;
+ desc.MiscFlags = 0;
+
+ ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, format,
+ &mSwizzleTexture));
+ mSwizzleTexture.setLabels("TexStorage2DArray.SwizzleTexture", &mKHRDebugLabel);
+ }
+
+ *outTexture = &mSwizzleTexture;
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_2DArray::getSwizzleRenderTarget(
+ const gl::Context *context,
+ int mipLevel,
+ const d3d11::RenderTargetView **outRTV)
+{
+ ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
+ ASSERT(outRTV);
+
+ if (!mSwizzleRenderTargets[mipLevel].valid())
+ {
+ const TextureHelper11 *swizzleTexture = nullptr;
+ ANGLE_TRY(getSwizzleTexture(context, &swizzleTexture));
+
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format =
+ mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()).rtvFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
+ rtvDesc.Texture2DArray.MipSlice = mTopLevel + mipLevel;
+ rtvDesc.Texture2DArray.FirstArraySlice = 0;
+ rtvDesc.Texture2DArray.ArraySize = mTextureDepth;
+
+ ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), rtvDesc,
+ mSwizzleTexture.get(),
+ &mSwizzleRenderTargets[mipLevel]));
+ }
+
+ *outRTV = &mSwizzleRenderTargets[mipLevel];
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_2DArray::ensureDropStencilTexture(const gl::Context *context,
+ DropStencil *dropStencilOut)
+{
+ if (mDropStencilTexture.valid())
+ {
+ *dropStencilOut = DropStencil::ALREADY_EXISTS;
+ return angle::Result::Continue;
+ }
+
+ 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;
+
+ const auto &format =
+ d3d11::Format::Get(GL_DEPTH_COMPONENT32F, mRenderer->getRenderer11DeviceCaps());
+ ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), dropDesc, format,
+ &mDropStencilTexture));
+ mDropStencilTexture.setLabels("TexStorage2DArray.DropStencil", &mKHRDebugLabel);
+
+ std::vector<GLsizei> layerCounts(mMipLevels, mTextureDepth);
+
+ ANGLE_TRY(initDropStencilTexture(
+ context, gl::ImageIndexIterator::Make2DArray(0, mMipLevels, layerCounts.data())));
+
+ *dropStencilOut = DropStencil::CREATED;
+ return angle::Result::Continue;
+}
+
+void TextureStorage11_2DArray::onLabelUpdate()
+{
+ if (mTexture.valid())
+ {
+ mTexture.setKHRDebugLabel(&mKHRDebugLabel);
+ }
+ if (mSwizzleTexture.valid())
+ {
+ mSwizzleTexture.setKHRDebugLabel(&mKHRDebugLabel);
+ }
+}
+
+TextureStorage11_2DMultisample::TextureStorage11_2DMultisample(Renderer11 *renderer,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ int levels,
+ int samples,
+ bool fixedSampleLocations,
+ const std::string &label)
+ : TextureStorage11ImmutableBase(renderer,
+ GetTextureBindFlags(internalformat,
+ renderer->getRenderer11DeviceCaps(),
+ BindFlags::RenderTarget()),
+ GetTextureMiscFlags(internalformat,
+ renderer->getRenderer11DeviceCaps(),
+ BindFlags::RenderTarget(),
+ levels),
+ internalformat,
+ label),
+ mTexture(),
+ mRenderTarget(nullptr)
+{
+ // There are no multisampled compressed formats, so there's no need to adjust texture size
+ // according to block size.
+ ASSERT(d3d11::GetDXGIFormatSizeInfo(mFormatInfo.texFormat).blockWidth <= 1);
+ ASSERT(d3d11::GetDXGIFormatSizeInfo(mFormatInfo.texFormat).blockHeight <= 1);
+
+ mMipLevels = 1;
+ mTextureWidth = width;
+ mTextureHeight = height;
+ mTextureDepth = 1;
+ mSamples = samples;
+ mFixedSampleLocations = fixedSampleLocations;
+}
+
+angle::Result TextureStorage11_2DMultisample::onDestroy(const gl::Context *context)
+{
+ mRenderTarget.reset();
+ return angle::Result::Continue;
+}
+
+TextureStorage11_2DMultisample::~TextureStorage11_2DMultisample() {}
+
+angle::Result TextureStorage11_2DMultisample::copyToStorage(const gl::Context *context,
+ TextureStorage *destStorage)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
+ return angle::Result::Stop;
+}
+
+angle::Result TextureStorage11_2DMultisample::getResource(const gl::Context *context,
+ const TextureHelper11 **outResource)
+{
+ ANGLE_TRY(ensureTextureExists(context, 1));
+
+ *outResource = &mTexture;
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_2DMultisample::ensureTextureExists(const gl::Context *context,
+ int mipLevels)
+{
+ // For Multisampled textures, mipLevels always equals 1.
+ ASSERT(mipLevels == 1);
+
+ // if the width or height is not positive this should be treated as an incomplete texture
+ // we handle that here by skipping the d3d texture creation
+ if (!mTexture.valid() && mTextureWidth > 0 && mTextureHeight > 0)
+ {
+ D3D11_TEXTURE2D_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.Width = mTextureWidth; // Compressed texture size constraints?
+ desc.Height = mTextureHeight;
+ desc.MipLevels = mipLevels;
+ desc.ArraySize = 1;
+ desc.Format = mFormatInfo.texFormat;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.BindFlags = getBindFlags() & ~D3D11_BIND_UNORDERED_ACCESS;
+ desc.CPUAccessFlags = 0;
+ desc.MiscFlags = getMiscFlags();
+
+ const gl::TextureCaps &textureCaps =
+ mRenderer->getNativeTextureCaps().get(mFormatInfo.internalFormat);
+ GLuint supportedSamples = textureCaps.getNearestSamples(mSamples);
+ desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples;
+ desc.SampleDesc.Quality = mRenderer->getSampleDescQuality(supportedSamples);
+
+ ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, mFormatInfo,
+ &mTexture));
+ mTexture.setLabels("TexStorage2DMS.Texture", &mKHRDebugLabel);
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_2DMultisample::findRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) const
+{
+ ASSERT(!index.hasLayer());
+
+ const int level = index.getLevelIndex();
+ ASSERT(level == 0);
+
+ ASSERT(outRT);
+ *outRT = mRenderTarget.get();
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_2DMultisample::getRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT)
+{
+ ASSERT(!index.hasLayer());
+
+ const int level = index.getLevelIndex();
+ ASSERT(level == 0);
+
+ ASSERT(outRT);
+ if (mRenderTarget)
+ {
+ *outRT = mRenderTarget.get();
+ return angle::Result::Continue;
+ }
+
+ const TextureHelper11 *texture = nullptr;
+ ANGLE_TRY(getResource(context, &texture));
+
+ const d3d11::SharedSRV *srv = nullptr;
+ ANGLE_TRY(getSRVLevel(context, level, SRVType::Sample, &srv));
+
+ const d3d11::SharedSRV *blitSRV = nullptr;
+ ANGLE_TRY(getSRVLevel(context, level, SRVType::Blit, &blitSRV));
+
+ Context11 *context11 = GetImplAs<Context11>(context);
+
+ if (mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN)
+ {
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = mFormatInfo.rtvFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS;
+
+ d3d11::RenderTargetView rtv;
+ ANGLE_TRY(mRenderer->allocateResource(context11, rtvDesc, texture->get(), &rtv));
+
+ mRenderTarget.reset(new TextureRenderTarget11(
+ std::move(rtv), *texture, *srv, *blitSRV, mFormatInfo.internalFormat, getFormatSet(),
+ getLevelWidth(level), getLevelHeight(level), 1, mSamples));
+
+ *outRT = mRenderTarget.get();
+ return angle::Result::Continue;
+ }
+
+ ASSERT(mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN);
+
+ D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
+ dsvDesc.Format = mFormatInfo.dsvFormat;
+ dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS;
+ dsvDesc.Flags = 0;
+
+ d3d11::DepthStencilView dsv;
+ ANGLE_TRY(mRenderer->allocateResource(context11, dsvDesc, texture->get(), &dsv));
+
+ mRenderTarget.reset(new TextureRenderTarget11(
+ std::move(dsv), *texture, *srv, mFormatInfo.internalFormat, getFormatSet(),
+ getLevelWidth(level), getLevelHeight(level), 1, mSamples));
+
+ *outRT = mRenderTarget.get();
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_2DMultisample::createSRVForSampler(const gl::Context *context,
+ int baseLevel,
+ int mipLevels,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedSRV *outSRV)
+{
+ ASSERT(outSRV);
+
+ D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+ srvDesc.Format = format;
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS;
+
+ ANGLE_TRY(
+ mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV));
+ outSRV->setLabels("TexStorage2DMS.SRV", &mKHRDebugLabel);
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_2DMultisample::getSwizzleTexture(const gl::Context *context,
+ const TextureHelper11 **outTexture)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
+ return angle::Result::Stop;
+}
+
+angle::Result TextureStorage11_2DMultisample::getSwizzleRenderTarget(
+ const gl::Context *context,
+ int mipLevel,
+ const d3d11::RenderTargetView **outRTV)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
+ return angle::Result::Stop;
+}
+
+angle::Result TextureStorage11_2DMultisample::ensureDropStencilTexture(const gl::Context *context,
+ DropStencil *dropStencilOut)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
+ return angle::Result::Stop;
+}
+
+void TextureStorage11_2DMultisample::onLabelUpdate()
+{
+ if (mTexture.valid())
+ {
+ mTexture.setKHRDebugLabel(&mKHRDebugLabel);
+ }
+}
+
+TextureStorage11_2DMultisampleArray::TextureStorage11_2DMultisampleArray(Renderer11 *renderer,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ int levels,
+ int samples,
+ bool fixedSampleLocations,
+ const std::string &label)
+ : TextureStorage11ImmutableBase(renderer,
+ GetTextureBindFlags(internalformat,
+ renderer->getRenderer11DeviceCaps(),
+ BindFlags::RenderTarget()),
+ GetTextureMiscFlags(internalformat,
+ renderer->getRenderer11DeviceCaps(),
+ BindFlags::RenderTarget(),
+ levels),
+ internalformat,
+ label),
+ mTexture()
+{
+ // There are no multisampled compressed formats, so there's no need to adjust texture size
+ // according to block size.
+ ASSERT(d3d11::GetDXGIFormatSizeInfo(mFormatInfo.texFormat).blockWidth <= 1);
+ ASSERT(d3d11::GetDXGIFormatSizeInfo(mFormatInfo.texFormat).blockHeight <= 1);
+
+ mMipLevels = 1;
+ mTextureWidth = width;
+ mTextureHeight = height;
+ mTextureDepth = depth;
+ mSamples = samples;
+ mFixedSampleLocations = fixedSampleLocations;
+}
+
+angle::Result TextureStorage11_2DMultisampleArray::onDestroy(const gl::Context *context)
+{
+ return angle::Result::Continue;
+}
+
+TextureStorage11_2DMultisampleArray::~TextureStorage11_2DMultisampleArray() {}
+
+angle::Result TextureStorage11_2DMultisampleArray::copyToStorage(const gl::Context *context,
+ TextureStorage *destStorage)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
+ return angle::Result::Stop;
+}
+
+angle::Result TextureStorage11_2DMultisampleArray::getResource(const gl::Context *context,
+ const TextureHelper11 **outResource)
+{
+ ANGLE_TRY(ensureTextureExists(context, 1));
+
+ *outResource = &mTexture;
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_2DMultisampleArray::ensureTextureExists(const gl::Context *context,
+ int mipLevels)
+{
+ // For multisampled textures, mipLevels always equals 1.
+ ASSERT(mipLevels == 1);
+
+ // if the width or height is not positive this should be treated as an incomplete texture
+ // we handle that here by skipping the d3d texture creation
+ if (!mTexture.valid() && mTextureWidth > 0 && mTextureHeight > 0)
+ {
+ D3D11_TEXTURE2D_DESC desc;
+ ZeroMemory(&desc, sizeof(desc));
+ desc.Width = mTextureWidth;
+ desc.Height = mTextureHeight;
+ desc.MipLevels = mipLevels;
+ desc.ArraySize = mTextureDepth;
+ desc.Format = mFormatInfo.texFormat;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.BindFlags = getBindFlags() & ~D3D11_BIND_UNORDERED_ACCESS;
+ desc.CPUAccessFlags = 0;
+ desc.MiscFlags = getMiscFlags();
+
+ const gl::TextureCaps &textureCaps =
+ mRenderer->getNativeTextureCaps().get(mFormatInfo.internalFormat);
+ GLuint supportedSamples = textureCaps.getNearestSamples(mSamples);
+ desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples;
+ desc.SampleDesc.Quality = mRenderer->getSampleDescQuality(supportedSamples);
+
+ ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, mFormatInfo,
+ &mTexture));
+ mTexture.setLabels("TexStorage2DMSArray.Texture", &mKHRDebugLabel);
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_2DMultisampleArray::findRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) const
+{
+ ASSERT(index.hasLayer());
+
+ const int mipLevel = index.getLevelIndex();
+ ASSERT(mipLevel == 0);
+ const int layer = index.getLayerIndex();
+ const int numLayers = index.getLayerCount();
+
+ ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
+
+ TextureStorage11_2DArray::LevelLayerRangeKey key(mipLevel, layer, numLayers);
+ if (mRenderTargets.find(key) == mRenderTargets.end())
+ {
+ ASSERT(outRT);
+ *outRT = nullptr;
+ return angle::Result::Continue;
+ }
+
+ ASSERT(outRT);
+ *outRT = mRenderTargets.at(key).get();
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_2DMultisampleArray::createRenderTargetSRV(
+ const gl::Context *context,
+ const TextureHelper11 &texture,
+ const gl::ImageIndex &index,
+ DXGI_FORMAT resourceFormat,
+ d3d11::SharedSRV *srv) const
+{
+ D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+ srvDesc.Format = resourceFormat;
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY;
+ srvDesc.Texture2DMSArray.FirstArraySlice = index.getLayerIndex();
+ srvDesc.Texture2DMSArray.ArraySize = index.getLayerCount();
+
+ ANGLE_TRY(
+ mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), srv));
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_2DMultisampleArray::getRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT)
+{
+ ASSERT(index.hasLayer());
+
+ const int mipLevel = index.getLevelIndex();
+ ASSERT(mipLevel == 0);
+ const int layer = index.getLayerIndex();
+ const int numLayers = index.getLayerCount();
+
+ ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
+
+ TextureStorage11_2DArray::LevelLayerRangeKey key(mipLevel, layer, numLayers);
+ if (mRenderTargets.find(key) == mRenderTargets.end())
+ {
+ const TextureHelper11 *texture = nullptr;
+ ANGLE_TRY(getResource(context, &texture));
+ d3d11::SharedSRV srv;
+ ANGLE_TRY(createRenderTargetSRV(context, *texture, index, mFormatInfo.srvFormat, &srv));
+ d3d11::SharedSRV blitSRV;
+ if (mFormatInfo.blitSRVFormat != mFormatInfo.srvFormat)
+ {
+ ANGLE_TRY(createRenderTargetSRV(context, *texture, index, mFormatInfo.blitSRVFormat,
+ &blitSRV));
+ }
+ else
+ {
+ blitSRV = srv.makeCopy();
+ }
+
+ srv.setLabels("TexStorage2DMSArray.RenderTargetSRV", &mKHRDebugLabel);
+
+ if (mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN)
+ {
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = mFormatInfo.rtvFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY;
+ rtvDesc.Texture2DMSArray.FirstArraySlice = layer;
+ rtvDesc.Texture2DMSArray.ArraySize = numLayers;
+
+ d3d11::RenderTargetView rtv;
+ ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), rtvDesc,
+ texture->get(), &rtv));
+ rtv.setLabels("TexStorage2DMSArray.RenderTargetRTV", &mKHRDebugLabel);
+
+ mRenderTargets[key].reset(new TextureRenderTarget11(
+ std::move(rtv), *texture, srv, blitSRV, mFormatInfo.internalFormat, getFormatSet(),
+ getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, mSamples));
+ }
+ else
+ {
+ ASSERT(mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN);
+
+ D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
+ dsvDesc.Format = mFormatInfo.dsvFormat;
+ dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY;
+ dsvDesc.Texture2DMSArray.FirstArraySlice = layer;
+ dsvDesc.Texture2DMSArray.ArraySize = numLayers;
+ dsvDesc.Flags = 0;
+
+ d3d11::DepthStencilView dsv;
+ ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), dsvDesc,
+ texture->get(), &dsv));
+ dsv.setLabels("TexStorage2DMSArray.RenderTargetDSV", &mKHRDebugLabel);
+
+ mRenderTargets[key].reset(new TextureRenderTarget11(
+ std::move(dsv), *texture, srv, mFormatInfo.internalFormat, getFormatSet(),
+ getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, mSamples));
+ }
+ }
+
+ ASSERT(outRT);
+ *outRT = mRenderTargets[key].get();
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_2DMultisampleArray::createSRVForSampler(
+ const gl::Context *context,
+ int baseLevel,
+ int mipLevels,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedSRV *outSRV)
+{
+ ASSERT(outSRV);
+
+ D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+ srvDesc.Format = format;
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY;
+ srvDesc.Texture2DMSArray.FirstArraySlice = 0;
+ srvDesc.Texture2DMSArray.ArraySize = mTextureDepth;
+
+ ANGLE_TRY(
+ mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV));
+ outSRV->setLabels("TexStorage2DMSArray.SRV", &mKHRDebugLabel);
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_2DMultisampleArray::getSwizzleTexture(
+ const gl::Context *context,
+ const TextureHelper11 **outTexture)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
+ return angle::Result::Stop;
+}
+
+angle::Result TextureStorage11_2DMultisampleArray::getSwizzleRenderTarget(
+ const gl::Context *context,
+ int mipLevel,
+ const d3d11::RenderTargetView **outRTV)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
+ return angle::Result::Stop;
+}
+
+angle::Result TextureStorage11_2DMultisampleArray::ensureDropStencilTexture(
+ const gl::Context *context,
+ DropStencil *dropStencilOut)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
+ return angle::Result::Stop;
+}
+
+void TextureStorage11_2DMultisampleArray::onLabelUpdate()
+{
+ if (mTexture.valid())
+ {
+ mTexture.setKHRDebugLabel(&mKHRDebugLabel);
+ }
+}
+
+TextureStorage11_Buffer::TextureStorage11_Buffer(Renderer11 *renderer,
+ const gl::OffsetBindingPointer<gl::Buffer> &buffer,
+ GLenum internalFormat,
+ const std::string &label)
+ : TextureStorage11(renderer,
+ D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE,
+ 0,
+ internalFormat,
+ label),
+ mTexture(),
+ mBuffer(buffer),
+ mDataSize(GetBoundBufferAvailableSize(buffer))
+{
+ unsigned int bytesPerPixel =
+ static_cast<unsigned int>(d3d11::GetDXGIFormatSizeInfo(mFormatInfo.srvFormat).pixelBytes);
+ mMipLevels = 1;
+ mTextureWidth = static_cast<unsigned int>(mDataSize / bytesPerPixel);
+ mTextureHeight = 1;
+ mTextureDepth = 1;
+}
+
+TextureStorage11_Buffer::~TextureStorage11_Buffer() {}
+
+angle::Result TextureStorage11_Buffer::initTexture(const gl::Context *context)
+{
+ if (!mTexture.valid())
+ {
+ ID3D11Buffer *buffer = nullptr;
+ Buffer11 *buffer11 = GetImplAs<Buffer11>(mBuffer.get());
+ ANGLE_TRY(buffer11->getBuffer(context, rx::BufferUsage::BUFFER_USAGE_TYPED_UAV, &buffer));
+ mTexture.set(buffer, mFormatInfo);
+ mTexture.get()->AddRef();
+ }
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_Buffer::getResource(const gl::Context *context,
+ const TextureHelper11 **outResource)
+{
+ ANGLE_TRY(initTexture(context));
+ *outResource = &mTexture;
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_Buffer::getMippedResource(const gl::Context *context,
+ const TextureHelper11 **)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
+ return angle::Result::Stop;
+}
+
+angle::Result TextureStorage11_Buffer::findRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) const
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
+ return angle::Result::Stop;
+}
+
+angle::Result TextureStorage11_Buffer::getRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
+ return angle::Result::Stop;
+}
+
+angle::Result TextureStorage11_Buffer::getSwizzleTexture(const gl::Context *context,
+ const TextureHelper11 **outTexture)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
+ return angle::Result::Stop;
+}
+
+angle::Result TextureStorage11_Buffer::getSwizzleRenderTarget(
+ const gl::Context *context,
+ int mipLevel,
+ const d3d11::RenderTargetView **outRTV)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
+ return angle::Result::Stop;
+}
+
+angle::Result TextureStorage11_Buffer::createSRVForSampler(const gl::Context *context,
+ int baseLevel,
+ int mipLevels,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedSRV *outSRV)
+{
+ ASSERT(baseLevel == 0);
+ ASSERT(mipLevels == 1);
+ ASSERT(outSRV);
+ ANGLE_TRY(initTexture(context));
+ UINT bytesPerPixel = static_cast<UINT>(d3d11::GetDXGIFormatSizeInfo(format).pixelBytes);
+ D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+ srvDesc.Format = format;
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
+ ASSERT(mBuffer.getOffset() % bytesPerPixel == 0);
+ srvDesc.Buffer.FirstElement = static_cast<UINT>(mBuffer.getOffset() / bytesPerPixel);
+ srvDesc.Buffer.NumElements = static_cast<UINT>(mDataSize / bytesPerPixel);
+
+ ANGLE_TRY(
+ mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV));
+ outSRV->setLabels("TexBuffer.SRV", &mKHRDebugLabel);
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage11_Buffer::createSRVForImage(const gl::Context *context,
+ int level,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedSRV *outSRV)
+{
+ ANGLE_TRY(initTexture(context));
+ UINT bytesPerPixel = static_cast<UINT>(d3d11::GetDXGIFormatSizeInfo(format).pixelBytes);
+ D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+ srvDesc.Format = format;
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
+ ASSERT(mBuffer.getOffset() % bytesPerPixel == 0);
+ srvDesc.Buffer.FirstElement = static_cast<UINT>(mBuffer.getOffset() / bytesPerPixel);
+ srvDesc.Buffer.NumElements = static_cast<UINT>(mDataSize / bytesPerPixel);
+
+ ANGLE_TRY(
+ mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV));
+ outSRV->setLabels("TexBuffer.SRVForImage", &mKHRDebugLabel);
+
+ return angle::Result::Continue;
+}
+angle::Result TextureStorage11_Buffer::createUAVForImage(const gl::Context *context,
+ int level,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedUAV *outUAV)
+{
+ ANGLE_TRY(initTexture(context));
+ unsigned bytesPerPixel = d3d11::GetDXGIFormatSizeInfo(format).pixelBytes;
+ D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
+ uavDesc.Format = format;
+ uavDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
+ ASSERT(mBuffer.getOffset() % bytesPerPixel == 0);
+ uavDesc.Buffer.FirstElement = static_cast<UINT>(mBuffer.getOffset() / bytesPerPixel);
+ uavDesc.Buffer.NumElements = static_cast<UINT>(mDataSize / bytesPerPixel);
+ uavDesc.Buffer.Flags = 0;
+
+ ANGLE_TRY(
+ mRenderer->allocateResource(GetImplAs<Context11>(context), uavDesc, texture.get(), outUAV));
+ outUAV->setLabels("TexBuffer.UAVForImage", &mKHRDebugLabel);
+
+ return angle::Result::Continue;
+}
+
+void TextureStorage11_Buffer::associateImage(Image11 *image, const gl::ImageIndex &index) {}
+void TextureStorage11_Buffer::disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage)
+{}
+void TextureStorage11_Buffer::verifyAssociatedImageValid(const gl::ImageIndex &index,
+ Image11 *expectedImage)
+{}
+angle::Result TextureStorage11_Buffer::releaseAssociatedImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ Image11 *incomingImage)
+{
+ return angle::Result::Continue;
+}
+
+void TextureStorage11_Buffer::onLabelUpdate()
+{
+ if (mTexture.valid())
+ {
+ mTexture.setKHRDebugLabel(&mKHRDebugLabel);
+ }
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h
new file mode 100644
index 0000000000..72bc1b802c
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.h
@@ -0,0 +1,1003 @@
+//
+// Copyright 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.
+//
+
+// TextureStorage11.h: Defines the abstract rx::TextureStorage11 class and its concrete derived
+// classes TextureStorage11_2D and TextureStorage11_Cube, which act as the interface to the D3D11
+// texture.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_TEXTURESTORAGE11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_TEXTURESTORAGE11_H_
+
+#include "libANGLE/Error.h"
+#include "libANGLE/Texture.h"
+#include "libANGLE/renderer/d3d/TextureStorage.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
+
+#include <array>
+#include <map>
+
+namespace gl
+{
+class ImageIndex;
+} // namespace gl
+
+namespace rx
+{
+class EGLImageD3D;
+class RenderTargetD3D;
+class RenderTarget11;
+class Renderer11;
+class SwapChain11;
+class Image11;
+struct Renderer11DeviceCaps;
+class TextureStorage11_2DMultisample;
+
+template <typename T>
+using CubeFaceArray = std::array<T, gl::kCubeFaceCount>;
+
+struct MultisampledRenderToTextureInfo
+{
+ MultisampledRenderToTextureInfo(const GLsizei samples,
+ const gl::ImageIndex &indexSS,
+ const gl::ImageIndex &indexMS);
+ ~MultisampledRenderToTextureInfo();
+
+ // How many samples the multisampled texture contains
+ GLsizei samples;
+ // This is the image index for the single sampled texture
+ // This will hold the relevant level information
+ gl::ImageIndex indexSS;
+ // This is the image index for the multisampled texture
+ // For multisampled indexes, there is no level Index since they should
+ // account for the entire level.
+ gl::ImageIndex indexMS;
+ // True when multisampled texture has been written to and needs to be
+ // resolved to the single sampled texture
+ bool msTextureNeedsResolve;
+ std::unique_ptr<TextureStorage11_2DMultisample> msTex;
+};
+
+class TextureStorage11 : public TextureStorage
+{
+ public:
+ ~TextureStorage11() override;
+
+ static DWORD GetTextureBindFlags(GLenum internalFormat,
+ const Renderer11DeviceCaps &renderer11DeviceCaps,
+ BindFlags flags);
+ static DWORD GetTextureMiscFlags(GLenum internalFormat,
+ const Renderer11DeviceCaps &renderer11DeviceCaps,
+ BindFlags flags,
+ int levels);
+
+ UINT getBindFlags() const;
+ UINT getMiscFlags() const;
+ const d3d11::Format &getFormatSet() const;
+ angle::Result getSRVLevels(const gl::Context *context,
+ GLint baseLevel,
+ GLint maxLevel,
+ const d3d11::SharedSRV **outSRV);
+ angle::Result generateSwizzles(const gl::Context *context,
+ const gl::TextureState &textureState);
+ void markLevelDirty(int mipLevel);
+ void markDirty();
+
+ angle::Result updateSubresourceLevel(const gl::Context *context,
+ const TextureHelper11 &texture,
+ unsigned int sourceSubresource,
+ const gl::ImageIndex &index,
+ const gl::Box &copyArea);
+
+ angle::Result copySubresourceLevel(const gl::Context *context,
+ const TextureHelper11 &dstTexture,
+ unsigned int dstSubresource,
+ const gl::ImageIndex &index,
+ const gl::Box &region);
+
+ // TextureStorage virtual functions
+ int getTopLevel() const override;
+ bool isRenderTarget() const override;
+ bool isManaged() const override;
+ bool supportsNativeMipmapFunction() const override;
+ int getLevelCount() const override;
+ bool isUnorderedAccess() const override { return mBindFlags & D3D11_BIND_UNORDERED_ACCESS; }
+ angle::Result generateMipmap(const gl::Context *context,
+ const gl::ImageIndex &sourceIndex,
+ const gl::ImageIndex &destIndex) override;
+ angle::Result copyToStorage(const gl::Context *context, TextureStorage *destStorage) override;
+ angle::Result setData(const gl::Context *context,
+ const gl::ImageIndex &index,
+ ImageD3D *image,
+ const gl::Box *destBox,
+ GLenum type,
+ const gl::PixelUnpackState &unpack,
+ const uint8_t *pixelData) override;
+ void invalidateTextures() override;
+
+ virtual angle::Result getSRVForSampler(const gl::Context *context,
+ const gl::TextureState &textureState,
+ const gl::SamplerState &sampler,
+ const d3d11::SharedSRV **outSRV);
+ angle::Result getSRVForImage(const gl::Context *context,
+ const gl::ImageUnit &imageUnit,
+ const d3d11::SharedSRV **outSRV);
+ angle::Result getUAVForImage(const gl::Context *context,
+ const gl::ImageUnit &imageUnit,
+ const d3d11::SharedUAV **outUAV);
+ virtual angle::Result getSubresourceIndex(const gl::Context *context,
+ const gl::ImageIndex &index,
+ UINT *outSubresourceIndex) const;
+ virtual angle::Result getResource(const gl::Context *context,
+ const TextureHelper11 **outResource) = 0;
+ virtual void associateImage(Image11 *image, const gl::ImageIndex &index) = 0;
+ virtual void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) = 0;
+ virtual void verifyAssociatedImageValid(const gl::ImageIndex &index,
+ Image11 *expectedImage) = 0;
+ virtual angle::Result releaseAssociatedImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ Image11 *incomingImage) = 0;
+
+ GLsizei getRenderToTextureSamples() const override;
+
+ protected:
+ TextureStorage11(Renderer11 *renderer,
+ UINT bindFlags,
+ UINT miscFlags,
+ GLenum internalFormat,
+ const std::string &label);
+ int getLevelWidth(int mipLevel) const;
+ int getLevelHeight(int mipLevel) const;
+ int getLevelDepth(int mipLevel) const;
+
+ // Some classes (e.g. TextureStorage11_2D) will override getMippedResource.
+ virtual angle::Result getMippedResource(const gl::Context *context,
+ const TextureHelper11 **outResource);
+
+ virtual angle::Result getSwizzleTexture(const gl::Context *context,
+ const TextureHelper11 **outTexture) = 0;
+ virtual angle::Result getSwizzleRenderTarget(const gl::Context *context,
+ int mipLevel,
+ const d3d11::RenderTargetView **outRTV) = 0;
+
+ enum class SRVType
+ {
+ Sample,
+ Blit,
+ Stencil
+ };
+ angle::Result getSRVLevel(const gl::Context *context,
+ int mipLevel,
+ SRVType srvType,
+ const d3d11::SharedSRV **outSRV);
+
+ // Get a version of a depth texture with only depth information, not stencil.
+ enum DropStencil
+ {
+ CREATED,
+ ALREADY_EXISTS
+ };
+ virtual angle::Result ensureDropStencilTexture(const gl::Context *context,
+ DropStencil *dropStencilOut);
+ angle::Result initDropStencilTexture(const gl::Context *context,
+ const gl::ImageIndexIterator &it);
+
+ // The baseLevel parameter should *not* have mTopLevel applied.
+ virtual angle::Result createSRVForSampler(const gl::Context *context,
+ int baseLevel,
+ int mipLevels,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedSRV *outSRV) = 0;
+ virtual angle::Result createSRVForImage(const gl::Context *context,
+ int level,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedSRV *outSRV) = 0;
+ virtual angle::Result createUAVForImage(const gl::Context *context,
+ int level,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedUAV *outUAV) = 0;
+
+ void verifySwizzleExists(const gl::SwizzleState &swizzleState);
+
+ // Clear all cached non-swizzle SRVs and invalidate the swizzle cache.
+ void clearSRVCache();
+
+ // Helper for resolving MS shadowed texture
+ angle::Result resolveTextureHelper(const gl::Context *context, const TextureHelper11 &texture);
+ angle::Result releaseMultisampledTexStorageForLevel(size_t level) override;
+ angle::Result findMultisampledRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) const;
+ angle::Result getMultisampledRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT);
+
+ Renderer11 *mRenderer;
+ int mTopLevel;
+ unsigned int mMipLevels;
+
+ const d3d11::Format &mFormatInfo;
+ unsigned int mTextureWidth;
+ unsigned int mTextureHeight;
+ unsigned int mTextureDepth;
+
+ gl::TexLevelArray<gl::SwizzleState> mSwizzleCache;
+ TextureHelper11 mDropStencilTexture;
+
+ std::unique_ptr<MultisampledRenderToTextureInfo> mMSTexInfo;
+
+ private:
+ const UINT mBindFlags;
+ const UINT mMiscFlags;
+
+ struct SamplerKey
+ {
+ SamplerKey();
+ SamplerKey(int baseLevel, int mipLevels, bool swizzle, bool dropStencil);
+
+ bool operator<(const SamplerKey &rhs) const;
+
+ int baseLevel;
+ int mipLevels;
+ bool swizzle;
+ bool dropStencil;
+ };
+
+ angle::Result getCachedOrCreateSRVForSampler(const gl::Context *context,
+ const SamplerKey &key,
+ const d3d11::SharedSRV **outSRV);
+
+ using SRVCacheForSampler = std::map<SamplerKey, d3d11::SharedSRV>;
+ SRVCacheForSampler mSrvCacheForSampler;
+
+ struct ImageKey
+ {
+ ImageKey();
+ ImageKey(int level, bool layered, int layer, GLenum access, GLenum format);
+ bool operator<(const ImageKey &rhs) const;
+ int level;
+ bool layered;
+ int layer;
+ GLenum access;
+ GLenum format;
+ };
+
+ angle::Result getCachedOrCreateSRVForImage(const gl::Context *context,
+ const ImageKey &key,
+ const d3d11::SharedSRV **outSRV);
+ angle::Result getCachedOrCreateUAVForImage(const gl::Context *context,
+ const ImageKey &key,
+ const d3d11::SharedUAV **outUAV);
+
+ using SRVCacheForImage = std::map<ImageKey, d3d11::SharedSRV>;
+ SRVCacheForImage mSrvCacheForImage;
+ using UAVCacheForImage = std::map<ImageKey, d3d11::SharedUAV>;
+ UAVCacheForImage mUavCacheForImage;
+
+ gl::TexLevelArray<d3d11::SharedSRV> mLevelSRVs;
+ gl::TexLevelArray<d3d11::SharedSRV> mLevelBlitSRVs;
+ gl::TexLevelArray<d3d11::SharedSRV> mLevelStencilSRVs;
+};
+
+class TextureStorage11_2D : public TextureStorage11
+{
+ public:
+ TextureStorage11_2D(Renderer11 *renderer, SwapChain11 *swapchain, const std::string &label);
+ TextureStorage11_2D(Renderer11 *renderer,
+ GLenum internalformat,
+ BindFlags bindFlags,
+ GLsizei width,
+ GLsizei height,
+ int levels,
+ const std::string &label,
+ bool hintLevelZeroOnly = false);
+ ~TextureStorage11_2D() override;
+
+ angle::Result onDestroy(const gl::Context *context) override;
+
+ angle::Result getResource(const gl::Context *context,
+ const TextureHelper11 **outResource) override;
+ angle::Result getMippedResource(const gl::Context *context,
+ const TextureHelper11 **outResource) override;
+ angle::Result findRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) const override;
+ angle::Result getRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) override;
+
+ angle::Result copyToStorage(const gl::Context *context, TextureStorage *destStorage) override;
+
+ void associateImage(Image11 *image, const gl::ImageIndex &index) override;
+ void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override;
+ void verifyAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override;
+ angle::Result releaseAssociatedImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ Image11 *incomingImage) override;
+
+ angle::Result useLevelZeroWorkaroundTexture(const gl::Context *context,
+ bool useLevelZeroTexture) override;
+ void onLabelUpdate() override;
+
+ protected:
+ angle::Result getSwizzleTexture(const gl::Context *context,
+ const TextureHelper11 **outTexture) override;
+ angle::Result getSwizzleRenderTarget(const gl::Context *context,
+ int mipLevel,
+ const d3d11::RenderTargetView **outRTV) override;
+
+ angle::Result ensureDropStencilTexture(const gl::Context *context,
+ DropStencil *dropStencilOut) override;
+
+ angle::Result ensureTextureExists(const gl::Context *context, int mipLevels);
+
+ angle::Result resolveTexture(const gl::Context *context) override;
+
+ private:
+ angle::Result createSRVForSampler(const gl::Context *context,
+ int baseLevel,
+ int mipLevels,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedSRV *outSRV) override;
+ angle::Result createSRVForImage(const gl::Context *context,
+ int level,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedSRV *outSRV) override;
+ angle::Result createUAVForImage(const gl::Context *context,
+ int level,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedUAV *outUAV) override;
+
+ TextureHelper11 mTexture;
+ gl::TexLevelArray<std::unique_ptr<RenderTarget11>> mRenderTarget;
+ bool mHasKeyedMutex;
+
+ // These are members related to the zero max-LOD workaround.
+ // D3D11 Feature Level 9_3 can't disable mipmaps on a mipmapped texture (i.e. solely sample from
+ // level zero). These members are used to work around this limitation. Usually only mTexture XOR
+ // mLevelZeroTexture will exist. For example, if an app creates a texture with only one level,
+ // then 9_3 will only create mLevelZeroTexture. However, in some scenarios, both textures have
+ // to be created. This incurs additional memory overhead. One example of this is an application
+ // that creates a texture, calls glGenerateMipmap, and then disables mipmaps on the texture. A
+ // more likely example is an app that creates an empty texture, renders to it, and then calls
+ // glGenerateMipmap
+ // TODO: In this rendering scenario, release the mLevelZeroTexture after mTexture has been
+ // created to save memory.
+ TextureHelper11 mLevelZeroTexture;
+ std::unique_ptr<RenderTarget11> mLevelZeroRenderTarget;
+ bool mUseLevelZeroTexture;
+
+ // Swizzle-related variables
+ TextureHelper11 mSwizzleTexture;
+ gl::TexLevelArray<d3d11::RenderTargetView> mSwizzleRenderTargets;
+
+ gl::TexLevelArray<Image11 *> mAssociatedImages;
+};
+
+class TextureStorage11_External : public TextureStorage11
+{
+ public:
+ TextureStorage11_External(Renderer11 *renderer,
+ egl::Stream *stream,
+ const egl::Stream::GLTextureDescription &glDesc,
+ const std::string &label);
+ ~TextureStorage11_External() override;
+
+ angle::Result onDestroy(const gl::Context *context) override;
+
+ angle::Result getResource(const gl::Context *context,
+ const TextureHelper11 **outResource) override;
+ angle::Result getMippedResource(const gl::Context *context,
+ const TextureHelper11 **outResource) override;
+ angle::Result findRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) const override;
+ angle::Result getRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) override;
+
+ angle::Result copyToStorage(const gl::Context *context, TextureStorage *destStorage) override;
+
+ void associateImage(Image11 *image, const gl::ImageIndex &index) override;
+ void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override;
+ void verifyAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override;
+ angle::Result releaseAssociatedImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ Image11 *incomingImage) override;
+ void onLabelUpdate() override;
+
+ protected:
+ angle::Result getSwizzleTexture(const gl::Context *context,
+ const TextureHelper11 **outTexture) override;
+ angle::Result getSwizzleRenderTarget(const gl::Context *context,
+ int mipLevel,
+ const d3d11::RenderTargetView **outRTV) override;
+
+ private:
+ angle::Result createSRVForSampler(const gl::Context *context,
+ int baseLevel,
+ int mipLevels,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedSRV *outSRV) override;
+ angle::Result createSRVForImage(const gl::Context *context,
+ int level,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedSRV *outSRV) override;
+ angle::Result createUAVForImage(const gl::Context *context,
+ int level,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedUAV *outUAV) override;
+
+ TextureHelper11 mTexture;
+ int mSubresourceIndex;
+ bool mHasKeyedMutex;
+
+ Image11 *mAssociatedImage;
+};
+
+// A base class for texture storage classes where the associated images are not changed, nor are
+// they accessible as images in GLES3.1+ shaders.
+class TextureStorage11ImmutableBase : public TextureStorage11
+{
+ public:
+ TextureStorage11ImmutableBase(Renderer11 *renderer,
+ UINT bindFlags,
+ UINT miscFlags,
+ GLenum internalFormat,
+ const std::string &label);
+
+ void associateImage(Image11 *image, const gl::ImageIndex &index) override;
+ void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override;
+ void verifyAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override;
+ angle::Result releaseAssociatedImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ Image11 *incomingImage) override;
+
+ angle::Result createSRVForImage(const gl::Context *context,
+ int level,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedSRV *outSRV) override;
+ angle::Result createUAVForImage(const gl::Context *context,
+ int level,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedUAV *outUAV) override;
+};
+
+class TextureStorage11_EGLImage final : public TextureStorage11ImmutableBase
+{
+ public:
+ TextureStorage11_EGLImage(Renderer11 *renderer,
+ EGLImageD3D *eglImage,
+ RenderTarget11 *renderTarget11,
+ const std::string &label);
+ ~TextureStorage11_EGLImage() override;
+
+ angle::Result getSubresourceIndex(const gl::Context *context,
+ const gl::ImageIndex &index,
+ UINT *outSubresourceIndex) const override;
+ angle::Result getResource(const gl::Context *context,
+ const TextureHelper11 **outResource) override;
+ angle::Result getSRVForSampler(const gl::Context *context,
+ const gl::TextureState &textureState,
+ const gl::SamplerState &sampler,
+ const d3d11::SharedSRV **outSRV) override;
+ angle::Result getMippedResource(const gl::Context *context,
+ const TextureHelper11 **outResource) override;
+ angle::Result findRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) const override;
+ angle::Result getRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) override;
+
+ angle::Result copyToStorage(const gl::Context *context, TextureStorage *destStorage) override;
+
+ angle::Result useLevelZeroWorkaroundTexture(const gl::Context *context,
+ bool useLevelZeroTexture) override;
+ void onLabelUpdate() override;
+
+ protected:
+ angle::Result getSwizzleTexture(const gl::Context *context,
+ const TextureHelper11 **outTexture) override;
+ angle::Result getSwizzleRenderTarget(const gl::Context *context,
+ int mipLevel,
+ const d3d11::RenderTargetView **outRTV) override;
+
+ private:
+ // Check if the EGL image's render target has been updated due to orphaning and delete
+ // any SRVs and other resources based on the image's old render target.
+ angle::Result checkForUpdatedRenderTarget(const gl::Context *context);
+
+ angle::Result createSRVForSampler(const gl::Context *context,
+ int baseLevel,
+ int mipLevels,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedSRV *outSRV) override;
+
+ angle::Result getImageRenderTarget(const gl::Context *context, RenderTarget11 **outRT) const;
+
+ EGLImageD3D *mImage;
+ uintptr_t mCurrentRenderTarget;
+
+ // Swizzle-related variables
+ TextureHelper11 mSwizzleTexture;
+ std::vector<d3d11::RenderTargetView> mSwizzleRenderTargets;
+};
+
+class TextureStorage11_Cube : public TextureStorage11
+{
+ public:
+ TextureStorage11_Cube(Renderer11 *renderer,
+ GLenum internalformat,
+ BindFlags bindFlags,
+ int size,
+ int levels,
+ bool hintLevelZeroOnly,
+ const std::string &label);
+ ~TextureStorage11_Cube() override;
+
+ angle::Result onDestroy(const gl::Context *context) override;
+
+ angle::Result getSubresourceIndex(const gl::Context *context,
+ const gl::ImageIndex &index,
+ UINT *outSubresourceIndex) const override;
+
+ angle::Result getResource(const gl::Context *context,
+ const TextureHelper11 **outResource) override;
+ angle::Result getMippedResource(const gl::Context *context,
+ const TextureHelper11 **outResource) override;
+ angle::Result findRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) const override;
+ angle::Result getRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) override;
+
+ angle::Result copyToStorage(const gl::Context *context, TextureStorage *destStorage) override;
+
+ void associateImage(Image11 *image, const gl::ImageIndex &index) override;
+ void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override;
+ void verifyAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override;
+ angle::Result releaseAssociatedImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ Image11 *incomingImage) override;
+
+ angle::Result useLevelZeroWorkaroundTexture(const gl::Context *context,
+ bool useLevelZeroTexture) override;
+ void onLabelUpdate() override;
+
+ protected:
+ angle::Result getSwizzleTexture(const gl::Context *context,
+ const TextureHelper11 **outTexture) override;
+ angle::Result getSwizzleRenderTarget(const gl::Context *context,
+ int mipLevel,
+ const d3d11::RenderTargetView **outRTV) override;
+
+ angle::Result ensureDropStencilTexture(const gl::Context *context,
+ DropStencil *dropStencilOut) override;
+
+ angle::Result ensureTextureExists(const gl::Context *context, int mipLevels);
+
+ angle::Result resolveTexture(const gl::Context *context) override;
+
+ private:
+ angle::Result createSRVForSampler(const gl::Context *context,
+ int baseLevel,
+ int mipLevels,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedSRV *outSRV) override;
+ angle::Result createSRVForImage(const gl::Context *context,
+ int level,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedSRV *outSRV) override;
+ angle::Result createUAVForImage(const gl::Context *context,
+ int level,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedUAV *outUAV) override;
+ angle::Result createRenderTargetSRV(const gl::Context *context,
+ const TextureHelper11 &texture,
+ const gl::ImageIndex &index,
+ DXGI_FORMAT resourceFormat,
+ d3d11::SharedSRV *srv) const;
+
+ TextureHelper11 mTexture;
+ CubeFaceArray<gl::TexLevelArray<std::unique_ptr<RenderTarget11>>> mRenderTarget;
+
+ // Level-zero workaround members. See TextureStorage11_2D's workaround members for a
+ // description.
+ TextureHelper11 mLevelZeroTexture;
+ CubeFaceArray<std::unique_ptr<RenderTarget11>> mLevelZeroRenderTarget;
+ bool mUseLevelZeroTexture;
+
+ TextureHelper11 mSwizzleTexture;
+ gl::TexLevelArray<d3d11::RenderTargetView> mSwizzleRenderTargets;
+
+ CubeFaceArray<gl::TexLevelArray<Image11 *>> mAssociatedImages;
+};
+
+class TextureStorage11_3D : public TextureStorage11
+{
+ public:
+ TextureStorage11_3D(Renderer11 *renderer,
+ GLenum internalformat,
+ BindFlags bindFlags,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ int levels,
+ const std::string &label);
+ ~TextureStorage11_3D() override;
+
+ angle::Result onDestroy(const gl::Context *context) override;
+
+ angle::Result getResource(const gl::Context *context,
+ const TextureHelper11 **outResource) override;
+
+ // Handles both layer and non-layer RTs
+ angle::Result findRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) const override;
+ angle::Result getRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) override;
+
+ void associateImage(Image11 *image, const gl::ImageIndex &index) override;
+ void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override;
+ void verifyAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override;
+ angle::Result releaseAssociatedImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ Image11 *incomingImage) override;
+ void onLabelUpdate() override;
+
+ protected:
+ angle::Result getSwizzleTexture(const gl::Context *context,
+ const TextureHelper11 **outTexture) override;
+ angle::Result getSwizzleRenderTarget(const gl::Context *context,
+ int mipLevel,
+ const d3d11::RenderTargetView **outRTV) override;
+
+ private:
+ angle::Result createSRVForSampler(const gl::Context *context,
+ int baseLevel,
+ int mipLevels,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedSRV *outSRV) override;
+ angle::Result createSRVForImage(const gl::Context *context,
+ int level,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedSRV *outSRV) override;
+ angle::Result createUAVForImage(const gl::Context *context,
+ int level,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedUAV *outUAV) override;
+
+ typedef std::pair<int, int> LevelLayerKey;
+ std::map<LevelLayerKey, std::unique_ptr<RenderTarget11>> mLevelLayerRenderTargets;
+
+ gl::TexLevelArray<std::unique_ptr<RenderTarget11>> mLevelRenderTargets;
+
+ TextureHelper11 mTexture;
+ TextureHelper11 mSwizzleTexture;
+ gl::TexLevelArray<d3d11::RenderTargetView> mSwizzleRenderTargets;
+
+ gl::TexLevelArray<Image11 *> mAssociatedImages;
+};
+
+class TextureStorage11_2DArray : public TextureStorage11
+{
+ public:
+ TextureStorage11_2DArray(Renderer11 *renderer,
+ GLenum internalformat,
+ BindFlags bindFlags,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ int levels,
+ const std::string &label);
+ ~TextureStorage11_2DArray() override;
+
+ angle::Result onDestroy(const gl::Context *context) override;
+
+ angle::Result getResource(const gl::Context *context,
+ const TextureHelper11 **outResource) override;
+ angle::Result findRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) const override;
+ angle::Result getRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) override;
+
+ void associateImage(Image11 *image, const gl::ImageIndex &index) override;
+ void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override;
+ void verifyAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override;
+ angle::Result releaseAssociatedImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ Image11 *incomingImage) override;
+ void onLabelUpdate() override;
+
+ struct LevelLayerRangeKey
+ {
+ LevelLayerRangeKey(int mipLevelIn, int layerIn, int numLayersIn)
+ : mipLevel(mipLevelIn), layer(layerIn), numLayers(numLayersIn)
+ {}
+ bool operator<(const LevelLayerRangeKey &other) const
+ {
+ if (mipLevel != other.mipLevel)
+ {
+ return mipLevel < other.mipLevel;
+ }
+ if (layer != other.layer)
+ {
+ return layer < other.layer;
+ }
+ return numLayers < other.numLayers;
+ }
+ int mipLevel;
+ int layer;
+ int numLayers;
+ };
+
+ protected:
+ angle::Result getSwizzleTexture(const gl::Context *context,
+ const TextureHelper11 **outTexture) override;
+ angle::Result getSwizzleRenderTarget(const gl::Context *context,
+ int mipLevel,
+ const d3d11::RenderTargetView **outRTV) override;
+
+ angle::Result ensureDropStencilTexture(const gl::Context *context,
+ DropStencil *dropStencilOut) override;
+
+ private:
+ angle::Result createSRVForSampler(const gl::Context *context,
+ int baseLevel,
+ int mipLevels,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedSRV *outSRV) override;
+ angle::Result createSRVForImage(const gl::Context *context,
+ int level,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedSRV *outSRV) override;
+ angle::Result createUAVForImage(const gl::Context *context,
+ int level,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedUAV *outUAV) override;
+ angle::Result createRenderTargetSRV(const gl::Context *context,
+ const TextureHelper11 &texture,
+ const gl::ImageIndex &index,
+ DXGI_FORMAT resourceFormat,
+ d3d11::SharedSRV *srv) const;
+
+ std::map<LevelLayerRangeKey, std::unique_ptr<RenderTarget11>> mRenderTargets;
+
+ TextureHelper11 mTexture;
+
+ TextureHelper11 mSwizzleTexture;
+ gl::TexLevelArray<d3d11::RenderTargetView> mSwizzleRenderTargets;
+
+ typedef std::map<LevelLayerRangeKey, Image11 *> ImageMap;
+ ImageMap mAssociatedImages;
+};
+
+class TextureStorage11_2DMultisample final : public TextureStorage11ImmutableBase
+{
+ public:
+ TextureStorage11_2DMultisample(Renderer11 *renderer,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ int levels,
+ int samples,
+ bool fixedSampleLocations,
+ const std::string &label);
+ ~TextureStorage11_2DMultisample() override;
+
+ angle::Result onDestroy(const gl::Context *context) override;
+
+ angle::Result getResource(const gl::Context *context,
+ const TextureHelper11 **outResource) override;
+ angle::Result findRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) const override;
+ angle::Result getRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) override;
+
+ angle::Result copyToStorage(const gl::Context *context, TextureStorage *destStorage) override;
+ void onLabelUpdate() override;
+
+ protected:
+ angle::Result getSwizzleTexture(const gl::Context *context,
+ const TextureHelper11 **outTexture) override;
+ angle::Result getSwizzleRenderTarget(const gl::Context *context,
+ int mipLevel,
+ const d3d11::RenderTargetView **outRTV) override;
+
+ angle::Result ensureDropStencilTexture(const gl::Context *context,
+ DropStencil *dropStencilOut) override;
+
+ angle::Result ensureTextureExists(const gl::Context *context, int mipLevels);
+
+ private:
+ angle::Result createSRVForSampler(const gl::Context *context,
+ int baseLevel,
+ int mipLevels,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedSRV *outSRV) override;
+
+ TextureHelper11 mTexture;
+ std::unique_ptr<RenderTarget11> mRenderTarget;
+
+ unsigned int mSamples;
+ GLboolean mFixedSampleLocations;
+};
+
+class TextureStorage11_2DMultisampleArray final : public TextureStorage11ImmutableBase
+{
+ public:
+ TextureStorage11_2DMultisampleArray(Renderer11 *renderer,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ int levels,
+ int samples,
+ bool fixedSampleLocations,
+ const std::string &label);
+ ~TextureStorage11_2DMultisampleArray() override;
+
+ angle::Result onDestroy(const gl::Context *context) override;
+
+ angle::Result getResource(const gl::Context *context,
+ const TextureHelper11 **outResource) override;
+ angle::Result findRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) const override;
+ angle::Result getRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) override;
+
+ angle::Result copyToStorage(const gl::Context *context, TextureStorage *destStorage) override;
+ void onLabelUpdate() override;
+
+ protected:
+ angle::Result getSwizzleTexture(const gl::Context *context,
+ const TextureHelper11 **outTexture) override;
+ angle::Result getSwizzleRenderTarget(const gl::Context *context,
+ int mipLevel,
+ const d3d11::RenderTargetView **outRTV) override;
+
+ angle::Result ensureDropStencilTexture(const gl::Context *context,
+ DropStencil *dropStencilOut) override;
+
+ angle::Result ensureTextureExists(const gl::Context *context, int mipLevels);
+
+ private:
+ angle::Result createRenderTargetSRV(const gl::Context *context,
+ const TextureHelper11 &texture,
+ const gl::ImageIndex &index,
+ DXGI_FORMAT resourceFormat,
+ d3d11::SharedSRV *srv) const;
+
+ angle::Result createSRVForSampler(const gl::Context *context,
+ int baseLevel,
+ int mipLevels,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedSRV *outSRV) override;
+
+ TextureHelper11 mTexture;
+ std::map<TextureStorage11_2DArray::LevelLayerRangeKey, std::unique_ptr<RenderTarget11>>
+ mRenderTargets;
+
+ unsigned int mSamples;
+ GLboolean mFixedSampleLocations;
+};
+
+class TextureStorage11_Buffer : public TextureStorage11
+{
+ public:
+ TextureStorage11_Buffer(Renderer11 *renderer,
+ const gl::OffsetBindingPointer<gl::Buffer> &buffer,
+ GLenum internalFormat,
+ const std::string &label);
+ ~TextureStorage11_Buffer() override;
+
+ angle::Result getResource(const gl::Context *context,
+ const TextureHelper11 **outResource) override;
+ angle::Result getMippedResource(const gl::Context *context,
+ const TextureHelper11 **outResource) override;
+ angle::Result findRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) const override;
+ angle::Result getRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) override;
+
+ void onLabelUpdate() override;
+
+ void associateImage(Image11 *image, const gl::ImageIndex &index) override;
+ void disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage) override;
+ void verifyAssociatedImageValid(const gl::ImageIndex &index, Image11 *expectedImage) override;
+ angle::Result releaseAssociatedImage(const gl::Context *context,
+ const gl::ImageIndex &index,
+ Image11 *incomingImage) override;
+
+ protected:
+ angle::Result getSwizzleTexture(const gl::Context *context,
+ const TextureHelper11 **outTexture) override;
+ angle::Result getSwizzleRenderTarget(const gl::Context *context,
+ int mipLevel,
+ const d3d11::RenderTargetView **outRTV) override;
+
+ private:
+ angle::Result createSRVForSampler(const gl::Context *context,
+ int baseLevel,
+ int mipLevels,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedSRV *outSRV) override;
+ angle::Result createSRVForImage(const gl::Context *context,
+ int level,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedSRV *outSRV) override;
+ angle::Result createUAVForImage(const gl::Context *context,
+ int level,
+ DXGI_FORMAT format,
+ const TextureHelper11 &texture,
+ d3d11::SharedUAV *outUAV) override;
+
+ angle::Result initTexture(const gl::Context *context);
+
+ TextureHelper11 mTexture;
+ const gl::OffsetBindingPointer<gl::Buffer> &mBuffer;
+ GLint64 mDataSize;
+};
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D11_TEXTURESTORAGE11_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/TransformFeedback11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/TransformFeedback11.cpp
new file mode 100644
index 0000000000..1dcd62cd45
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/TransformFeedback11.cpp
@@ -0,0 +1,131 @@
+//
+// 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),
+ mSerial(mRenderer->generateSerial())
+{}
+
+TransformFeedback11::~TransformFeedback11() {}
+
+angle::Result TransformFeedback11::begin(const gl::Context *context,
+ gl::PrimitiveMode primitiveMode)
+{
+ // Reset all the cached offsets to the binding offsets
+ mIsDirty = true;
+ for (size_t bindingIdx = 0; bindingIdx < mBuffers.size(); bindingIdx++)
+ {
+ const auto &binding = mState.getIndexedBuffer(bindingIdx);
+ if (binding.get() != nullptr)
+ {
+ mBufferOffsets[bindingIdx] = static_cast<UINT>(binding.getOffset());
+ }
+ else
+ {
+ mBufferOffsets[bindingIdx] = 0;
+ }
+ }
+ mRenderer->getStateManager()->invalidateTransformFeedback();
+ return angle::Result::Continue;
+}
+
+angle::Result TransformFeedback11::end(const gl::Context *context)
+{
+ mRenderer->getStateManager()->invalidateTransformFeedback();
+ if (mRenderer->getFeatures().flushAfterEndingTransformFeedback.enabled)
+ {
+ mRenderer->getDeviceContext()->Flush();
+ }
+ return angle::Result::Continue;
+}
+
+angle::Result TransformFeedback11::pause(const gl::Context *context)
+{
+ mRenderer->getStateManager()->invalidateTransformFeedback();
+ return angle::Result::Continue;
+}
+
+angle::Result TransformFeedback11::resume(const gl::Context *context)
+{
+ mRenderer->getStateManager()->invalidateTransformFeedback();
+ return angle::Result::Continue;
+}
+
+angle::Result TransformFeedback11::bindIndexedBuffer(
+ const gl::Context *context,
+ size_t index,
+ const gl::OffsetBindingPointer<gl::Buffer> &binding)
+{
+ mIsDirty = true;
+ mBufferOffsets[index] = static_cast<UINT>(binding.getOffset());
+ mRenderer->getStateManager()->invalidateTransformFeedback();
+ return angle::Result::Continue;
+}
+
+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());
+}
+
+angle::Result TransformFeedback11::getSOBuffers(const gl::Context *context,
+ const std::vector<ID3D11Buffer *> **buffersOut)
+{
+ 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(storage->getBuffer(context, BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK,
+ &mBuffers[bindingIdx]));
+ }
+ }
+
+ *buffersOut = &mBuffers;
+ return angle::Result::Continue;
+}
+
+const std::vector<UINT> &TransformFeedback11::getSOBufferOffsets() const
+{
+ return mBufferOffsets;
+}
+
+Serial TransformFeedback11::getSerial() const
+{
+ return mSerial;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/TransformFeedback11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/TransformFeedback11.h
new file mode 100644
index 0000000000..69ae90671b
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/TransformFeedback11.h
@@ -0,0 +1,61 @@
+//
+// 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/Error.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/renderer/TransformFeedbackImpl.h"
+#include "libANGLE/renderer/serial_utils.h"
+
+namespace rx
+{
+
+class Renderer11;
+
+class TransformFeedback11 : public TransformFeedbackImpl
+{
+ public:
+ TransformFeedback11(const gl::TransformFeedbackState &state, Renderer11 *renderer);
+ ~TransformFeedback11() override;
+
+ angle::Result begin(const gl::Context *context, gl::PrimitiveMode primitiveMode) override;
+ angle::Result end(const gl::Context *context) override;
+ angle::Result pause(const gl::Context *context) override;
+ angle::Result resume(const gl::Context *context) override;
+
+ angle::Result bindIndexedBuffer(const gl::Context *context,
+ size_t index,
+ const gl::OffsetBindingPointer<gl::Buffer> &binding) override;
+
+ void onApply();
+
+ bool isDirty() const;
+
+ UINT getNumSOBuffers() const;
+ angle::Result getSOBuffers(const gl::Context *context,
+ const std::vector<ID3D11Buffer *> **buffersOut);
+ const std::vector<UINT> &getSOBufferOffsets() const;
+
+ Serial getSerial() const;
+
+ private:
+ Renderer11 *mRenderer;
+
+ bool mIsDirty;
+ std::vector<ID3D11Buffer *> mBuffers;
+ std::vector<UINT> mBufferOffsets;
+
+ Serial mSerial;
+};
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D11_TRANSFORMFEEDBACK11_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Trim11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Trim11.cpp
new file mode 100644
index 0000000000..ac6d9a5220
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Trim11.cpp
@@ -0,0 +1,103 @@
+//
+// 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.
+//
+
+// Trim11.cpp: Trim support utility class.
+
+#include "libANGLE/renderer/d3d/d3d11/Trim11.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+
+#if defined(ANGLE_ENABLE_WINDOWS_UWP)
+# include <windows.applicationmodel.core.h>
+# include <wrl.h>
+# include <wrl/wrappers/corewrappers.h>
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::ApplicationModel;
+using namespace ABI::Windows::ApplicationModel::Core;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Foundation::Collections;
+#endif
+
+namespace rx
+{
+
+Trim11::Trim11(rx::Renderer11 *renderer) : mRenderer(renderer)
+{
+ bool result = true;
+ result = registerForRendererTrimRequest();
+ ASSERT(result);
+}
+
+Trim11::~Trim11()
+{
+ unregisterForRendererTrimRequest();
+}
+
+void Trim11::trim()
+{
+ if (!mRenderer)
+ {
+ return;
+ }
+
+#if defined(ANGLE_ENABLE_WINDOWS_UWP)
+ ID3D11Device *device = mRenderer->getDevice();
+ IDXGIDevice3 *dxgiDevice3 = d3d11::DynamicCastComObject<IDXGIDevice3>(device);
+ if (dxgiDevice3)
+ {
+ dxgiDevice3->Trim();
+ }
+ SafeRelease(dxgiDevice3);
+#endif
+}
+
+bool Trim11::registerForRendererTrimRequest()
+{
+#if defined(ANGLE_ENABLE_WINDOWS_UWP)
+ ICoreApplication *coreApplication = nullptr;
+ HRESULT result = GetActivationFactory(
+ HStringReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(),
+ &coreApplication);
+ if (SUCCEEDED(result))
+ {
+ auto suspendHandler = Callback<IEventHandler<SuspendingEventArgs *>>(
+ [this](IInspectable *, ISuspendingEventArgs *) -> HRESULT {
+ trim();
+ return S_OK;
+ });
+ result =
+ coreApplication->add_Suspending(suspendHandler.Get(), &mApplicationSuspendedEventToken);
+ }
+ SafeRelease(coreApplication);
+
+ if (FAILED(result))
+ {
+ return false;
+ }
+#endif
+ return true;
+}
+
+void Trim11::unregisterForRendererTrimRequest()
+{
+#if defined(ANGLE_ENABLE_WINDOWS_UWP)
+ if (mApplicationSuspendedEventToken.value != 0)
+ {
+ ICoreApplication *coreApplication = nullptr;
+ if (SUCCEEDED(GetActivationFactory(
+ HStringReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(),
+ &coreApplication)))
+ {
+ coreApplication->remove_Suspending(mApplicationSuspendedEventToken);
+ }
+ mApplicationSuspendedEventToken.value = 0;
+ SafeRelease(coreApplication);
+ }
+#endif
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Trim11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Trim11.h
new file mode 100644
index 0000000000..eb1f3e7e13
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/Trim11.h
@@ -0,0 +1,43 @@
+//
+// 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.
+//
+
+// Trim11.h: Trim support utility class.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_TRIM11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_TRIM11_H_
+
+#include "common/angleutils.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/angletypes.h"
+
+#if defined(ANGLE_ENABLE_WINDOWS_UWP)
+# include <EventToken.h>
+#endif
+
+namespace rx
+{
+class Renderer11;
+
+class Trim11 : angle::NonCopyable
+{
+ public:
+ explicit Trim11(Renderer11 *renderer);
+ ~Trim11();
+
+ private:
+ Renderer11 *mRenderer;
+#if defined(ANGLE_ENABLE_WINDOWS_UWP)
+ EventRegistrationToken mApplicationSuspendedEventToken;
+#endif
+
+ void trim();
+ bool registerForRendererTrimRequest();
+ void unregisterForRendererTrimRequest();
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D11_TRIM11_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexArray11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexArray11.cpp
new file mode 100644
index 0000000000..a5f8b6a176
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexArray11.cpp
@@ -0,0 +1,375 @@
+//
+// 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.
+//
+// VertexArray11:
+// Implementation of rx::VertexArray11.
+//
+
+#include "libANGLE/renderer/d3d/d3d11/VertexArray11.h"
+
+#include "common/bitset_utils.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/renderer/d3d/IndexBuffer.h"
+#include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
+#include "libANGLE/renderer/d3d/d3d11/Context11.h"
+
+using namespace angle;
+
+namespace rx
+{
+VertexArray11::VertexArray11(const gl::VertexArrayState &data)
+ : VertexArrayImpl(data),
+ mAttributeStorageTypes(data.getMaxAttribs(), VertexStorageType::CURRENT_VALUE),
+ mTranslatedAttribs(data.getMaxAttribs()),
+ mAppliedNumViewsToDivisor(1),
+ mCurrentElementArrayStorage(IndexStorageType::Invalid),
+ mCachedDestinationIndexType(gl::DrawElementsType::InvalidEnum)
+{}
+
+VertexArray11::~VertexArray11() {}
+
+void VertexArray11::destroy(const gl::Context *context) {}
+
+// As VertexAttribPointer can modify both attribute and binding, we should also set other attributes
+// that are also using this binding dirty.
+#define ANGLE_VERTEX_DIRTY_ATTRIB_FUNC(INDEX) \
+ case gl::VertexArray::DIRTY_BIT_ATTRIB_0 + INDEX: \
+ if ((*attribBits)[INDEX][gl::VertexArray::DirtyAttribBitType::DIRTY_ATTRIB_POINTER]) \
+ { \
+ attributesToUpdate |= mState.getBindingToAttributesMask(INDEX); \
+ } \
+ else \
+ { \
+ attributesToUpdate.set(INDEX); \
+ } \
+ invalidateVertexBuffer = true; \
+ (*attribBits)[INDEX].reset(); \
+ break;
+
+#define ANGLE_VERTEX_DIRTY_BINDING_FUNC(INDEX) \
+ case gl::VertexArray::DIRTY_BIT_BINDING_0 + INDEX: \
+ attributesToUpdate |= mState.getBindingToAttributesMask(INDEX); \
+ invalidateVertexBuffer = true; \
+ (*bindingBits)[INDEX].reset(); \
+ break;
+
+#define ANGLE_VERTEX_DIRTY_BUFFER_DATA_FUNC(INDEX) \
+ case gl::VertexArray::DIRTY_BIT_BUFFER_DATA_0 + INDEX: \
+ if (mAttributeStorageTypes[INDEX] == VertexStorageType::STATIC) \
+ { \
+ invalidateVertexBuffer = true; \
+ mAttribsToTranslate.set(INDEX); \
+ } \
+ break;
+
+angle::Result VertexArray11::syncState(const gl::Context *context,
+ const gl::VertexArray::DirtyBits &dirtyBits,
+ gl::VertexArray::DirtyAttribBitsArray *attribBits,
+ gl::VertexArray::DirtyBindingBitsArray *bindingBits)
+{
+ ASSERT(dirtyBits.any());
+
+ Renderer11 *renderer = GetImplAs<Context11>(context)->getRenderer();
+ StateManager11 *stateManager = renderer->getStateManager();
+
+ // Generate a state serial. This serial is used in the program class to validate the cached
+ // input layout, and skip recomputation in the fast path.
+ mCurrentStateSerial = renderer->generateSerial();
+
+ bool invalidateVertexBuffer = false;
+
+ gl::AttributesMask attributesToUpdate;
+
+ // Make sure we trigger re-translation for static index or vertex data.
+ for (size_t dirtyBit : dirtyBits)
+ {
+ switch (dirtyBit)
+ {
+ case gl::VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER:
+ case gl::VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER_DATA:
+ {
+ mLastDrawElementsType.reset();
+ mLastDrawElementsIndices.reset();
+ mLastPrimitiveRestartEnabled.reset();
+ mCachedIndexInfo.reset();
+ break;
+ }
+
+ ANGLE_VERTEX_INDEX_CASES(ANGLE_VERTEX_DIRTY_ATTRIB_FUNC)
+ ANGLE_VERTEX_INDEX_CASES(ANGLE_VERTEX_DIRTY_BINDING_FUNC)
+ ANGLE_VERTEX_INDEX_CASES(ANGLE_VERTEX_DIRTY_BUFFER_DATA_FUNC)
+
+ default:
+ UNREACHABLE();
+ break;
+ }
+ }
+
+ for (size_t attribIndex : attributesToUpdate)
+ {
+ updateVertexAttribStorage(context, stateManager, attribIndex);
+ }
+
+ if (invalidateVertexBuffer)
+ {
+ // TODO(jmadill): Individual attribute invalidation.
+ stateManager->invalidateVertexBuffer();
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result VertexArray11::syncStateForDraw(const gl::Context *context,
+ GLint firstVertex,
+ GLsizei vertexOrIndexCount,
+ gl::DrawElementsType indexTypeOrInvalid,
+ const void *indices,
+ GLsizei instances,
+ GLint baseVertex,
+ GLuint baseInstance,
+ bool promoteDynamic)
+{
+ Renderer11 *renderer = GetImplAs<Context11>(context)->getRenderer();
+ StateManager11 *stateManager = renderer->getStateManager();
+
+ const gl::State &glState = context->getState();
+ const gl::Program *program = glState.getProgram();
+ ASSERT(program);
+ const gl::ProgramExecutable &executable = program->getExecutable();
+
+ mAppliedNumViewsToDivisor = (program->usesMultiview() ? program->getNumViews() : 1);
+
+ if (mAttribsToTranslate.any())
+ {
+ const gl::AttributesMask &activeLocations = executable.getActiveAttribLocationsMask();
+ gl::AttributesMask activeDirtyAttribs = (mAttribsToTranslate & activeLocations);
+ if (activeDirtyAttribs.any())
+ {
+ ANGLE_TRY(updateDirtyAttribs(context, activeDirtyAttribs));
+ stateManager->invalidateInputLayout();
+ }
+ }
+
+ if (mDynamicAttribsMask.any())
+ {
+ const gl::AttributesMask &activeLocations = executable.getActiveAttribLocationsMask();
+ gl::AttributesMask activeDynamicAttribs = (mDynamicAttribsMask & activeLocations);
+
+ if (activeDynamicAttribs.any())
+ {
+ ANGLE_TRY(updateDynamicAttribs(context, stateManager->getVertexDataManager(),
+ firstVertex, vertexOrIndexCount, indexTypeOrInvalid,
+ indices, instances, baseVertex, baseInstance,
+ promoteDynamic, activeDynamicAttribs));
+ stateManager->invalidateInputLayout();
+ }
+ }
+
+ if (indexTypeOrInvalid != gl::DrawElementsType::InvalidEnum)
+ {
+ bool restartEnabled = context->getState().isPrimitiveRestartEnabled();
+ if (!mLastDrawElementsType.valid() || mLastDrawElementsType.value() != indexTypeOrInvalid ||
+ mLastDrawElementsIndices.value() != indices ||
+ mLastPrimitiveRestartEnabled.value() != restartEnabled)
+ {
+ mLastDrawElementsType = indexTypeOrInvalid;
+ mLastDrawElementsIndices = indices;
+ mLastPrimitiveRestartEnabled = restartEnabled;
+
+ ANGLE_TRY(updateElementArrayStorage(context, vertexOrIndexCount, indexTypeOrInvalid,
+ indices, restartEnabled));
+ stateManager->invalidateIndexBuffer();
+ }
+ else if (mCurrentElementArrayStorage == IndexStorageType::Dynamic)
+ {
+ stateManager->invalidateIndexBuffer();
+ }
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result VertexArray11::updateElementArrayStorage(const gl::Context *context,
+ GLsizei indexCount,
+ gl::DrawElementsType indexType,
+ const void *indices,
+ bool restartEnabled)
+{
+ bool usePrimitiveRestartWorkaround = UsePrimitiveRestartWorkaround(restartEnabled, indexType);
+
+ ANGLE_TRY(GetIndexTranslationDestType(context, indexCount, indexType, indices,
+ usePrimitiveRestartWorkaround,
+ &mCachedDestinationIndexType));
+
+ unsigned int offset = static_cast<unsigned int>(reinterpret_cast<uintptr_t>(indices));
+
+ mCurrentElementArrayStorage =
+ ClassifyIndexStorage(context->getState(), mState.getElementArrayBuffer(), indexType,
+ mCachedDestinationIndexType, offset);
+
+ return angle::Result::Continue;
+}
+
+void VertexArray11::updateVertexAttribStorage(const gl::Context *context,
+ StateManager11 *stateManager,
+ size_t attribIndex)
+{
+ const gl::VertexAttribute &attrib = mState.getVertexAttribute(attribIndex);
+ const gl::VertexBinding &binding = mState.getBindingFromAttribIndex(attribIndex);
+
+ VertexStorageType newStorageType = ClassifyAttributeStorage(context, attrib, binding);
+
+ // Note: having an unchanged storage type doesn't mean the attribute is clean.
+ mAttribsToTranslate.set(attribIndex, newStorageType != VertexStorageType::DYNAMIC);
+
+ if (mAttributeStorageTypes[attribIndex] == newStorageType)
+ return;
+
+ mAttributeStorageTypes[attribIndex] = newStorageType;
+ mDynamicAttribsMask.set(attribIndex, newStorageType == VertexStorageType::DYNAMIC);
+
+ if (newStorageType == VertexStorageType::CURRENT_VALUE)
+ {
+ stateManager->invalidateCurrentValueAttrib(attribIndex);
+ }
+}
+
+bool VertexArray11::hasActiveDynamicAttrib(const gl::Context *context)
+{
+ const auto &activeLocations =
+ context->getState().getProgramExecutable()->getActiveAttribLocationsMask();
+ gl::AttributesMask activeDynamicAttribs = (mDynamicAttribsMask & activeLocations);
+ return activeDynamicAttribs.any();
+}
+
+angle::Result VertexArray11::updateDirtyAttribs(const gl::Context *context,
+ const gl::AttributesMask &activeDirtyAttribs)
+{
+ const auto &glState = context->getState();
+ const auto &attribs = mState.getVertexAttributes();
+ const auto &bindings = mState.getVertexBindings();
+
+ for (size_t dirtyAttribIndex : activeDirtyAttribs)
+ {
+ auto *translatedAttrib = &mTranslatedAttribs[dirtyAttribIndex];
+ const auto &currentValue = glState.getVertexAttribCurrentValue(dirtyAttribIndex);
+
+ // Record basic attrib info
+ translatedAttrib->attribute = &attribs[dirtyAttribIndex];
+ translatedAttrib->binding = &bindings[translatedAttrib->attribute->bindingIndex];
+ translatedAttrib->currentValueType = currentValue.Type;
+ translatedAttrib->divisor =
+ translatedAttrib->binding->getDivisor() * mAppliedNumViewsToDivisor;
+
+ switch (mAttributeStorageTypes[dirtyAttribIndex])
+ {
+ case VertexStorageType::DIRECT:
+ VertexDataManager::StoreDirectAttrib(context, translatedAttrib);
+ break;
+ case VertexStorageType::STATIC:
+ {
+ ANGLE_TRY(VertexDataManager::StoreStaticAttrib(context, translatedAttrib));
+ break;
+ }
+ case VertexStorageType::CURRENT_VALUE:
+ // Current value attribs are managed by the StateManager11.
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ // Make sure we reset the dirty bit after the switch because STATIC can early exit.
+ mAttribsToTranslate.reset(dirtyAttribIndex);
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result VertexArray11::updateDynamicAttribs(const gl::Context *context,
+ VertexDataManager *vertexDataManager,
+ GLint firstVertex,
+ GLsizei vertexOrIndexCount,
+ gl::DrawElementsType indexTypeOrInvalid,
+ const void *indices,
+ GLsizei instances,
+ GLint baseVertex,
+ GLuint baseInstance,
+ bool promoteDynamic,
+ const gl::AttributesMask &activeDynamicAttribs)
+{
+ const auto &glState = context->getState();
+ const auto &attribs = mState.getVertexAttributes();
+ const auto &bindings = mState.getVertexBindings();
+
+ GLint startVertex;
+ size_t vertexCount;
+ ANGLE_TRY(GetVertexRangeInfo(context, firstVertex, vertexOrIndexCount, indexTypeOrInvalid,
+ indices, baseVertex, &startVertex, &vertexCount));
+
+ for (size_t dynamicAttribIndex : activeDynamicAttribs)
+ {
+ auto *dynamicAttrib = &mTranslatedAttribs[dynamicAttribIndex];
+ const auto &currentValue = glState.getVertexAttribCurrentValue(dynamicAttribIndex);
+
+ // Record basic attrib info
+ dynamicAttrib->attribute = &attribs[dynamicAttribIndex];
+ dynamicAttrib->binding = &bindings[dynamicAttrib->attribute->bindingIndex];
+ dynamicAttrib->currentValueType = currentValue.Type;
+ dynamicAttrib->divisor = dynamicAttrib->binding->getDivisor() * mAppliedNumViewsToDivisor;
+ }
+
+ ANGLE_TRY(vertexDataManager->storeDynamicAttribs(context, &mTranslatedAttribs,
+ activeDynamicAttribs, startVertex, vertexCount,
+ instances, baseInstance));
+
+ if (promoteDynamic)
+ {
+ VertexDataManager::PromoteDynamicAttribs(context, mTranslatedAttribs, activeDynamicAttribs,
+ vertexCount);
+ }
+
+ return angle::Result::Continue;
+}
+
+const std::vector<TranslatedAttribute> &VertexArray11::getTranslatedAttribs() const
+{
+ return mTranslatedAttribs;
+}
+
+void VertexArray11::markAllAttributeDivisorsForAdjustment(int numViews)
+{
+ if (mAppliedNumViewsToDivisor != numViews)
+ {
+ mAppliedNumViewsToDivisor = numViews;
+ mAttribsToTranslate.set();
+ // mDynamicAttribsMask may have already been set (updateVertexAttribStorage
+ // We don't want to override DYNAMIC attribs as they will be handled separately.
+ mAttribsToTranslate = mAttribsToTranslate ^ mDynamicAttribsMask;
+ }
+}
+
+const TranslatedIndexData &VertexArray11::getCachedIndexInfo() const
+{
+ ASSERT(mCachedIndexInfo.valid());
+ return mCachedIndexInfo.value();
+}
+
+void VertexArray11::updateCachedIndexInfo(const TranslatedIndexData &indexInfo)
+{
+ mCachedIndexInfo = indexInfo;
+}
+
+bool VertexArray11::isCachedIndexInfoValid() const
+{
+ return mCachedIndexInfo.valid();
+}
+
+gl::DrawElementsType VertexArray11::getCachedDestinationIndexType() const
+{
+ return mCachedDestinationIndexType;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexArray11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexArray11.h
new file mode 100644
index 0000000000..a0ac5d74f1
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexArray11.h
@@ -0,0 +1,112 @@
+//
+// 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.
+//
+
+// VertexArray11.h: Defines the rx::VertexArray11 class which implements rx::VertexArrayImpl.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_VERTEXARRAY11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_VERTEXARRAY11_H_
+
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/renderer/VertexArrayImpl.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+
+namespace rx
+{
+class Renderer11;
+
+class VertexArray11 : public VertexArrayImpl
+{
+ public:
+ VertexArray11(const gl::VertexArrayState &data);
+ ~VertexArray11() override;
+ void destroy(const gl::Context *context) override;
+
+ // Does not apply any state updates - these are done in syncStateForDraw which as access to
+ // the draw call parameters.
+ angle::Result syncState(const gl::Context *context,
+ const gl::VertexArray::DirtyBits &dirtyBits,
+ gl::VertexArray::DirtyAttribBitsArray *attribBits,
+ gl::VertexArray::DirtyBindingBitsArray *bindingBits) override;
+
+ // Applied buffer pointers are updated here.
+ angle::Result syncStateForDraw(const gl::Context *context,
+ GLint firstVertex,
+ GLsizei vertexOrIndexCount,
+ gl::DrawElementsType indexTypeOrInvalid,
+ const void *indices,
+ GLsizei instances,
+ GLint baseVertex,
+ GLuint baseInstance,
+ bool promoteDynamic);
+
+ // This will check the dynamic attribs mask.
+ bool hasActiveDynamicAttrib(const gl::Context *context);
+
+ const std::vector<TranslatedAttribute> &getTranslatedAttribs() const;
+
+ Serial getCurrentStateSerial() const { return mCurrentStateSerial; }
+
+ // In case of a multi-view program change, we have to update all attributes so that the divisor
+ // is adjusted.
+ void markAllAttributeDivisorsForAdjustment(int numViews);
+
+ const TranslatedIndexData &getCachedIndexInfo() const;
+ void updateCachedIndexInfo(const TranslatedIndexData &indexInfo);
+ bool isCachedIndexInfoValid() const;
+
+ gl::DrawElementsType getCachedDestinationIndexType() const;
+
+ private:
+ void updateVertexAttribStorage(const gl::Context *context,
+ StateManager11 *stateManager,
+ size_t attribIndex);
+ angle::Result updateDirtyAttribs(const gl::Context *context,
+ const gl::AttributesMask &activeDirtyAttribs);
+ angle::Result updateDynamicAttribs(const gl::Context *context,
+ VertexDataManager *vertexDataManager,
+ GLint firstVertex,
+ GLsizei vertexOrIndexCount,
+ gl::DrawElementsType indexTypeOrInvalid,
+ const void *indices,
+ GLsizei instances,
+ GLint baseVertex,
+ GLuint baseInstance,
+ bool promoteDynamic,
+ const gl::AttributesMask &activeDynamicAttribs);
+
+ angle::Result updateElementArrayStorage(const gl::Context *context,
+ GLsizei indexCount,
+ gl::DrawElementsType indexType,
+ const void *indices,
+ bool restartEnabled);
+
+ std::vector<VertexStorageType> mAttributeStorageTypes;
+ std::vector<TranslatedAttribute> mTranslatedAttribs;
+
+ // The mask of attributes marked as dynamic.
+ gl::AttributesMask mDynamicAttribsMask;
+
+ // A set of attributes we know are dirty, and need to be re-translated.
+ gl::AttributesMask mAttribsToTranslate;
+
+ Serial mCurrentStateSerial;
+
+ // The numViews value used to adjust the divisor.
+ int mAppliedNumViewsToDivisor;
+
+ // If the index buffer needs re-streaming.
+ Optional<gl::DrawElementsType> mLastDrawElementsType;
+ Optional<const void *> mLastDrawElementsIndices;
+ Optional<bool> mLastPrimitiveRestartEnabled;
+ IndexStorageType mCurrentElementArrayStorage;
+ Optional<TranslatedIndexData> mCachedIndexInfo;
+ gl::DrawElementsType mCachedDestinationIndexType;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D11_VERTEXARRAY11_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp
new file mode 100644
index 0000000000..9daa8f83f9
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.cpp
@@ -0,0 +1,167 @@
+//
+// Copyright 2013 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.
+//
+
+// VertexBuffer11.cpp: Defines the D3D11 VertexBuffer implementation.
+
+#include "libANGLE/renderer/d3d/d3d11/VertexBuffer11.h"
+
+#include "libANGLE/Buffer.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/VertexAttribute.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
+#include "libANGLE/renderer/d3d/d3d11/Context11.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+
+namespace rx
+{
+
+VertexBuffer11::VertexBuffer11(Renderer11 *const renderer)
+ : mRenderer(renderer),
+ mBuffer(),
+ mBufferSize(0),
+ mDynamicUsage(false),
+ mMappedResourceData(nullptr)
+{}
+
+VertexBuffer11::~VertexBuffer11()
+{
+ ASSERT(mMappedResourceData == nullptr);
+}
+
+angle::Result VertexBuffer11::initialize(const gl::Context *context,
+ unsigned int size,
+ bool dynamicUsage)
+{
+ mBuffer.reset();
+ updateSerial();
+
+ if (size > 0)
+ {
+ D3D11_BUFFER_DESC bufferDesc;
+ bufferDesc.ByteWidth = size;
+ bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
+ bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
+ bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+ bufferDesc.MiscFlags = 0;
+ bufferDesc.StructureByteStride = 0;
+
+ ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), bufferDesc, &mBuffer));
+
+ if (dynamicUsage)
+ {
+ mBuffer.setInternalName("VertexBuffer11(dynamic)");
+ }
+ else
+ {
+ mBuffer.setInternalName("VertexBuffer11(static)");
+ }
+ }
+
+ mBufferSize = size;
+ mDynamicUsage = dynamicUsage;
+
+ return angle::Result::Continue;
+}
+
+angle::Result VertexBuffer11::mapResource(const gl::Context *context)
+{
+ if (mMappedResourceData == nullptr)
+ {
+ D3D11_MAPPED_SUBRESOURCE mappedResource;
+
+ ANGLE_TRY(mRenderer->mapResource(context, mBuffer.get(), 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0,
+ &mappedResource));
+
+ mMappedResourceData = static_cast<uint8_t *>(mappedResource.pData);
+ }
+
+ return angle::Result::Continue;
+}
+
+void VertexBuffer11::hintUnmapResource()
+{
+ if (mMappedResourceData != nullptr)
+ {
+ ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
+ dxContext->Unmap(mBuffer.get(), 0);
+
+ mMappedResourceData = nullptr;
+ }
+}
+
+angle::Result VertexBuffer11::storeVertexAttributes(const gl::Context *context,
+ const gl::VertexAttribute &attrib,
+ const gl::VertexBinding &binding,
+ gl::VertexAttribType currentValueType,
+ GLint start,
+ size_t count,
+ GLsizei instances,
+ unsigned int offset,
+ const uint8_t *sourceData)
+{
+ ASSERT(mBuffer.valid());
+
+ int inputStride = static_cast<int>(ComputeVertexAttributeStride(attrib, binding));
+
+ // This will map the resource if it isn't already mapped.
+ ANGLE_TRY(mapResource(context));
+
+ uint8_t *output = mMappedResourceData + offset;
+
+ const uint8_t *input = sourceData;
+
+ if (instances == 0 || binding.getDivisor() == 0)
+ {
+ input += inputStride * start;
+ }
+
+ angle::FormatID vertexFormatID = gl::GetVertexFormatID(attrib, currentValueType);
+ const D3D_FEATURE_LEVEL featureLevel = mRenderer->getRenderer11DeviceCaps().featureLevel;
+ const d3d11::VertexFormat &vertexFormatInfo =
+ d3d11::GetVertexFormatInfo(vertexFormatID, featureLevel);
+ ASSERT(vertexFormatInfo.copyFunction != nullptr);
+ vertexFormatInfo.copyFunction(input, inputStride, count, output);
+
+ return angle::Result::Continue;
+}
+
+unsigned int VertexBuffer11::getBufferSize() const
+{
+ return mBufferSize;
+}
+
+angle::Result VertexBuffer11::setBufferSize(const gl::Context *context, unsigned int size)
+{
+ if (size > mBufferSize)
+ {
+ return initialize(context, size, mDynamicUsage);
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result VertexBuffer11::discard(const gl::Context *context)
+{
+ ASSERT(mBuffer.valid());
+
+ D3D11_MAPPED_SUBRESOURCE mappedResource;
+ ANGLE_TRY(mRenderer->mapResource(context, mBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0,
+ &mappedResource));
+
+ mRenderer->getDeviceContext()->Unmap(mBuffer.get(), 0);
+
+ return angle::Result::Continue;
+}
+
+const d3d11::Buffer &VertexBuffer11::getBuffer() const
+{
+ return mBuffer;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.h
new file mode 100644
index 0000000000..46b52cb602
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/VertexBuffer11.h
@@ -0,0 +1,65 @@
+//
+// Copyright 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.
+//
+
+// VertexBuffer11.h: Defines the D3D11 VertexBuffer implementation.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_VERTEXBUFFER11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_VERTEXBUFFER11_H_
+
+#include <stdint.h>
+
+#include "libANGLE/renderer/d3d/VertexBuffer.h"
+#include "libANGLE/renderer/d3d/d3d11/ResourceManager11.h"
+
+namespace rx
+{
+class Renderer11;
+
+class VertexBuffer11 : public VertexBuffer
+{
+ public:
+ explicit VertexBuffer11(Renderer11 *const renderer);
+
+ angle::Result initialize(const gl::Context *context,
+ unsigned int size,
+ bool dynamicUsage) override;
+
+ // Warning: you should ensure binding really matches attrib.bindingIndex before using this
+ // function.
+ angle::Result storeVertexAttributes(const gl::Context *context,
+ const gl::VertexAttribute &attrib,
+ const gl::VertexBinding &binding,
+ gl::VertexAttribType currentValueType,
+ GLint start,
+ size_t count,
+ GLsizei instances,
+ unsigned int offset,
+ const uint8_t *sourceData) override;
+
+ unsigned int getBufferSize() const override;
+ angle::Result setBufferSize(const gl::Context *context, unsigned int size) override;
+ angle::Result discard(const gl::Context *context) override;
+
+ void hintUnmapResource() override;
+
+ const d3d11::Buffer &getBuffer() const;
+
+ private:
+ ~VertexBuffer11() override;
+ angle::Result mapResource(const gl::Context *context);
+
+ Renderer11 *const mRenderer;
+
+ d3d11::Buffer mBuffer;
+ unsigned int mBufferSize;
+ bool mDynamicUsage;
+
+ uint8_t *mMappedResourceData;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D11_VERTEXBUFFER11_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/converged/CompositorNativeWindow11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/converged/CompositorNativeWindow11.cpp
new file mode 100644
index 0000000000..0e64f78d53
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/converged/CompositorNativeWindow11.cpp
@@ -0,0 +1,457 @@
+//
+// Copyright 2018 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.
+//
+
+// CompositorNativeWindow11.cpp: Implementation of NativeWindow11 using Windows.UI.Composition APIs
+// which work in both Win32 and WinRT contexts.
+
+#include "libANGLE/renderer/d3d/d3d11/converged/CompositorNativeWindow11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+
+#include "common/debug.h"
+
+using namespace Microsoft::WRL;
+
+namespace rx
+{
+
+CompositorNativeWindow11::CompositorNativeWindow11(EGLNativeWindowType window, bool hasAlpha)
+ : NativeWindow11(window), mHasAlpha(hasAlpha)
+{
+ ABI::Windows::UI::Composition::ISpriteVisual *inspPtr =
+ reinterpret_cast<ABI::Windows::UI::Composition::ISpriteVisual *>(window);
+ mHostVisual = Microsoft::WRL::ComPtr<ABI::Windows::UI::Composition::ISpriteVisual>{inspPtr};
+}
+
+CompositorNativeWindow11::~CompositorNativeWindow11() = default;
+
+bool CompositorNativeWindow11::initialize()
+{
+ return true;
+}
+
+bool CompositorNativeWindow11::getClientRect(LPRECT rect) const
+{
+ ComPtr<ABI::Windows::UI::Composition::IVisual> visual;
+ mHostVisual.As(&visual);
+
+ ABI::Windows::Foundation::Numerics::Vector2 size;
+ HRESULT hr = visual->get_Size(&size);
+ if (FAILED(hr))
+ {
+ return false;
+ }
+
+ ABI::Windows::Foundation::Numerics::Vector3 offset;
+ hr = visual->get_Offset(&offset);
+ if (FAILED(hr))
+ {
+ return false;
+ }
+
+ rect->top = static_cast<LONG>(offset.Y);
+ rect->left = static_cast<LONG>(offset.X);
+ rect->right = static_cast<LONG>(offset.X) + static_cast<LONG>(size.X);
+ rect->bottom = static_cast<LONG>(offset.Y) + static_cast<LONG>(size.Y);
+
+ return true;
+}
+
+bool CompositorNativeWindow11::isIconic() const
+{
+ return false;
+}
+
+HRESULT CompositorNativeWindow11::createSwapChain(ID3D11Device *device,
+ IDXGIFactory *factory,
+ DXGI_FORMAT format,
+ UINT width,
+ UINT height,
+ UINT samples,
+ IDXGISwapChain **swapChain)
+{
+ if (device == nullptr || factory == nullptr || swapChain == nullptr || width == 0 ||
+ height == 0)
+ {
+ return E_INVALIDARG;
+ }
+
+ HRESULT hr{E_FAIL};
+
+ ComPtr<ABI::Windows::UI::Composition::ICompositionObject> hostVisual;
+ hr = mHostVisual.As(&hostVisual);
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+
+ Microsoft::WRL::ComPtr<ABI::Windows::UI::Composition::ICompositor> compositor;
+ hr = hostVisual->get_Compositor(&compositor);
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+
+ ComPtr<ABI::Windows::UI::Composition::ICompositorInterop> interop;
+
+ hr = compositor.As(&interop);
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+
+ ComPtr<IDXGIFactory2> factory2;
+ factory2.Attach(d3d11::DynamicCastComObject<IDXGIFactory2>(factory));
+
+ DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {};
+ swapChainDesc.Width = width;
+ swapChainDesc.Height = height;
+ swapChainDesc.Format = format;
+ swapChainDesc.Stereo = FALSE;
+ swapChainDesc.SampleDesc.Count = 1;
+ swapChainDesc.SampleDesc.Quality = 0;
+ swapChainDesc.BufferUsage =
+ DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER | DXGI_USAGE_SHADER_INPUT;
+ swapChainDesc.BufferCount = 2;
+ swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
+ swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
+ swapChainDesc.AlphaMode = mHasAlpha ? DXGI_ALPHA_MODE_PREMULTIPLIED : DXGI_ALPHA_MODE_IGNORE;
+#ifndef ANGLE_ENABLE_WINDOWS_UWP
+ swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG::DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT;
+#endif
+ Microsoft::WRL::ComPtr<IDXGISwapChain1> swapChain1;
+ hr = factory2->CreateSwapChainForComposition(device, &swapChainDesc, nullptr, &swapChain1);
+ if (SUCCEEDED(hr))
+ {
+ swapChain1.CopyTo(swapChain);
+ }
+
+ hr = interop->CreateCompositionSurfaceForSwapChain(swapChain1.Get(), &mSurface);
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+
+ hr = compositor->CreateSurfaceBrushWithSurface(mSurface.Get(), &mSurfaceBrush);
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+
+ hr = mSurfaceBrush.As(&mCompositionBrush);
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+
+ hr = mHostVisual->put_Brush(mCompositionBrush.Get());
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+
+ return hr;
+}
+
+void CompositorNativeWindow11::commitChange()
+{
+ // Windows::UI::Composition uses an implicit commit model hence no action needed here
+}
+
+// static
+bool CompositorNativeWindow11::IsValidNativeWindow(EGLNativeWindowType window)
+{
+ return IsSupportedWinRelease() && IsSpriteVisual(window);
+}
+
+// static
+bool CompositorNativeWindow11::IsSupportedWinRelease()
+{
+ RoHelper helper;
+ if (!helper.WinRtAvailable())
+ {
+ return false;
+ }
+
+ return helper.SupportedWindowsRelease();
+}
+
+bool CompositorNativeWindow11::IsSpriteVisual(EGLNativeWindowType window)
+{
+ RoHelper helper;
+
+ ABI::Windows::UI::Composition::ISpriteVisual *inspp =
+ reinterpret_cast<ABI::Windows::UI::Composition::ISpriteVisual *>(window);
+ HSTRING className, spriteClassName;
+ HSTRING_HEADER spriteClassNameHeader;
+
+ auto hr = helper.GetStringReference(RuntimeClass_Windows_UI_Composition_SpriteVisual,
+ &spriteClassName, &spriteClassNameHeader);
+ if (FAILED(hr))
+ {
+ return false;
+ }
+
+ hr = inspp->GetRuntimeClassName(&className);
+ if (FAILED(hr))
+ {
+ return false;
+ }
+
+ INT32 result = -1;
+ hr = helper.WindowsCompareStringOrdinal(className, spriteClassName, &result);
+
+ helper.WindowsDeleteString(className);
+
+ if (FAILED(hr))
+ {
+ return false;
+ }
+
+ if (result == 0)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+// RoHelperImpl
+
+template <typename T>
+bool AssignProcAddress(HMODULE comBaseModule, const char *name, T *&outProc)
+{
+ outProc = reinterpret_cast<T *>(GetProcAddress(comBaseModule, name));
+ return *outProc != nullptr;
+}
+
+RoHelper::RoHelper()
+ : mFpWindowsCreateStringReference(nullptr),
+ mFpGetActivationFactory(nullptr),
+ mFpWindowsCompareStringOrdinal(nullptr),
+ mFpCreateDispatcherQueueController(nullptr),
+ mFpWindowsDeleteString(nullptr),
+ mFpRoInitialize(nullptr),
+ mFpRoUninitialize(nullptr),
+ mWinRtAvailable(false),
+ mWinRtInitialized(false),
+ mComBaseModule(nullptr),
+ mCoreMessagingModule(nullptr)
+{
+
+#ifdef ANGLE_ENABLE_WINDOWS_UWP
+ mFpWindowsCreateStringReference = &::WindowsCreateStringReference;
+ mFpRoInitialize = &::RoInitialize;
+ mFpRoUninitialize = &::RoUninitialize;
+ mFpWindowsDeleteString = &::WindowsDeleteString;
+ mFpGetActivationFactory = &::RoGetActivationFactory;
+ mFpWindowsCompareStringOrdinal = &::WindowsCompareStringOrdinal;
+ mFpCreateDispatcherQueueController = &::CreateDispatcherQueueController;
+ mWinRtAvailable = true;
+#else
+
+ mComBaseModule = LoadLibraryA("ComBase.dll");
+
+ if (mComBaseModule == nullptr)
+ {
+ return;
+ }
+
+ if (!AssignProcAddress(mComBaseModule, "WindowsCreateStringReference",
+ mFpWindowsCreateStringReference))
+ {
+ return;
+ }
+
+ if (!AssignProcAddress(mComBaseModule, "RoGetActivationFactory", mFpGetActivationFactory))
+ {
+ return;
+ }
+
+ if (!AssignProcAddress(mComBaseModule, "WindowsCompareStringOrdinal",
+ mFpWindowsCompareStringOrdinal))
+ {
+ return;
+ }
+
+ if (!AssignProcAddress(mComBaseModule, "WindowsDeleteString", mFpWindowsDeleteString))
+ {
+ return;
+ }
+
+ if (!AssignProcAddress(mComBaseModule, "RoInitialize", mFpRoInitialize))
+ {
+ return;
+ }
+
+ if (!AssignProcAddress(mComBaseModule, "RoUninitialize", mFpRoUninitialize))
+ {
+ return;
+ }
+
+ mCoreMessagingModule = LoadLibraryA("coremessaging.dll");
+
+ if (mCoreMessagingModule == nullptr)
+ {
+ return;
+ }
+
+ if (!AssignProcAddress(mCoreMessagingModule, "CreateDispatcherQueueController",
+ mFpCreateDispatcherQueueController))
+ {
+ return;
+ }
+
+ auto result = RoInitialize(RO_INIT_MULTITHREADED);
+
+ if (SUCCEEDED(result) || result == RPC_E_CHANGED_MODE)
+ {
+ mWinRtAvailable = true;
+
+ if (SUCCEEDED(result))
+ {
+ mWinRtInitialized = true;
+ }
+ }
+#endif
+}
+
+RoHelper::~RoHelper()
+{
+#ifndef ANGLE_ENABLE_WINDOWS_UWP
+ if (mWinRtInitialized)
+ {
+ RoUninitialize();
+ }
+
+ if (mCoreMessagingModule != nullptr)
+ {
+ FreeLibrary(mCoreMessagingModule);
+ mCoreMessagingModule = nullptr;
+ }
+
+ if (mComBaseModule != nullptr)
+ {
+ FreeLibrary(mComBaseModule);
+ mComBaseModule = nullptr;
+ }
+#endif
+}
+
+bool RoHelper::WinRtAvailable() const
+{
+ return mWinRtAvailable;
+}
+
+bool RoHelper::SupportedWindowsRelease()
+{
+ if (!mWinRtAvailable)
+ {
+ return false;
+ }
+
+ HSTRING className, contractName;
+ HSTRING_HEADER classNameHeader, contractNameHeader;
+ boolean isSupported = false;
+
+ HRESULT hr = GetStringReference(RuntimeClass_Windows_Foundation_Metadata_ApiInformation,
+ &className, &classNameHeader);
+
+ if (FAILED(hr))
+ {
+ return !!isSupported;
+ }
+
+ Microsoft::WRL::ComPtr<ABI::Windows::Foundation::Metadata::IApiInformationStatics> api;
+
+ hr = GetActivationFactory(
+ className, __uuidof(ABI::Windows::Foundation::Metadata::IApiInformationStatics), &api);
+
+ if (FAILED(hr))
+ {
+ return !!isSupported;
+ }
+
+ hr = GetStringReference(L"Windows.Foundation.UniversalApiContract", &contractName,
+ &contractNameHeader);
+ if (FAILED(hr))
+ {
+ return !!isSupported;
+ }
+
+ api->IsApiContractPresentByMajor(contractName, 6, &isSupported);
+
+ return !!isSupported;
+}
+
+HRESULT RoHelper::GetStringReference(PCWSTR source, HSTRING *act, HSTRING_HEADER *header)
+{
+ if (!mWinRtAvailable)
+ {
+ return E_FAIL;
+ }
+
+ const wchar_t *str = static_cast<const wchar_t *>(source);
+
+ unsigned int length;
+ HRESULT hr = SizeTToUInt32(::wcslen(str), &length);
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+
+ return mFpWindowsCreateStringReference(source, length, header, act);
+}
+
+HRESULT RoHelper::GetActivationFactory(const HSTRING act, const IID &interfaceId, void **fac)
+{
+ if (!mWinRtAvailable)
+ {
+ return E_FAIL;
+ }
+ auto hr = mFpGetActivationFactory(act, interfaceId, fac);
+ return hr;
+}
+
+HRESULT RoHelper::WindowsCompareStringOrdinal(HSTRING one, HSTRING two, int *result)
+{
+ if (!mWinRtAvailable)
+ {
+ return E_FAIL;
+ }
+ return mFpWindowsCompareStringOrdinal(one, two, result);
+}
+
+HRESULT RoHelper::CreateDispatcherQueueController(
+ DispatcherQueueOptions options,
+ ABI::Windows::System::IDispatcherQueueController **dispatcherQueueController)
+{
+ if (!mWinRtAvailable)
+ {
+ return E_FAIL;
+ }
+ return mFpCreateDispatcherQueueController(options, dispatcherQueueController);
+}
+
+HRESULT RoHelper::WindowsDeleteString(HSTRING one)
+{
+ if (!mWinRtAvailable)
+ {
+ return E_FAIL;
+ }
+ return mFpWindowsDeleteString(one);
+}
+
+HRESULT RoHelper::RoInitialize(RO_INIT_TYPE type)
+{
+ return mFpRoInitialize(type);
+}
+
+void RoHelper::RoUninitialize()
+{
+ mFpRoUninitialize();
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/converged/CompositorNativeWindow11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/converged/CompositorNativeWindow11.h
new file mode 100644
index 0000000000..82857322e0
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/converged/CompositorNativeWindow11.h
@@ -0,0 +1,116 @@
+//
+// Copyright 2018 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.
+//
+
+// CompositorNativeWindow11.h: Implementation of NativeWindow11 using Windows.UI.Composition APIs
+// which work in both Win32 and WinRT contexts.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_CONVERGED_COMPOSITORNATIVEWINDOW11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_CONVERGED_COMPOSITORNATIVEWINDOW11_H_
+
+#include "libANGLE/renderer/d3d/d3d11/NativeWindow11.h"
+
+#include <dispatcherqueue.h>
+#include <versionhelpers.h>
+#include <windows.foundation.metadata.h>
+#include <windows.ui.composition.h>
+#include <windows.ui.composition.interop.h>
+#include <wrl.h>
+
+namespace rx
+{
+
+class RoHelper
+{
+ public:
+ RoHelper();
+ ~RoHelper();
+ bool WinRtAvailable() const;
+ bool SupportedWindowsRelease();
+ HRESULT GetStringReference(PCWSTR source, HSTRING *act, HSTRING_HEADER *header);
+ HRESULT GetActivationFactory(const HSTRING act, const IID &interfaceId, void **fac);
+ HRESULT WindowsCompareStringOrdinal(HSTRING one, HSTRING two, int *result);
+ HRESULT CreateDispatcherQueueController(
+ DispatcherQueueOptions options,
+ ABI::Windows::System::IDispatcherQueueController **dispatcherQueueController);
+ HRESULT WindowsDeleteString(HSTRING one);
+ HRESULT RoInitialize(RO_INIT_TYPE type);
+ void RoUninitialize();
+
+ private:
+ using WindowsCreateStringReference_ = HRESULT __stdcall(PCWSTR,
+ UINT32,
+ HSTRING_HEADER *,
+ HSTRING *);
+
+ using GetActivationFactory_ = HRESULT __stdcall(HSTRING, REFIID, void **);
+
+ using WindowsCompareStringOrginal_ = HRESULT __stdcall(HSTRING, HSTRING, int *);
+
+ using WindowsDeleteString_ = HRESULT __stdcall(HSTRING);
+
+ using CreateDispatcherQueueController_ =
+ HRESULT __stdcall(DispatcherQueueOptions,
+ ABI::Windows::System::IDispatcherQueueController **);
+
+ using RoInitialize_ = HRESULT __stdcall(RO_INIT_TYPE);
+ using RoUninitialize_ = void __stdcall();
+
+ WindowsCreateStringReference_ *mFpWindowsCreateStringReference;
+ GetActivationFactory_ *mFpGetActivationFactory;
+ WindowsCompareStringOrginal_ *mFpWindowsCompareStringOrdinal;
+ CreateDispatcherQueueController_ *mFpCreateDispatcherQueueController;
+ WindowsDeleteString_ *mFpWindowsDeleteString;
+ RoInitialize_ *mFpRoInitialize;
+ RoUninitialize_ *mFpRoUninitialize;
+
+ bool mWinRtAvailable;
+ bool mWinRtInitialized;
+
+ HMODULE mComBaseModule;
+ HMODULE mCoreMessagingModule;
+};
+
+class CompositorNativeWindow11 : public NativeWindow11
+{
+ public:
+ CompositorNativeWindow11(EGLNativeWindowType window, bool hasAlpha);
+ ~CompositorNativeWindow11() override;
+
+ bool initialize() override;
+ bool getClientRect(LPRECT rect) const override;
+ bool isIconic() const override;
+
+ HRESULT createSwapChain(ID3D11Device *device,
+ IDXGIFactory *factory,
+ DXGI_FORMAT format,
+ UINT width,
+ UINT height,
+ UINT samples,
+ IDXGISwapChain **swapChain) override;
+
+ void commitChange() override;
+
+ static bool IsValidNativeWindow(EGLNativeWindowType window);
+
+ static bool IsSupportedWinRelease();
+
+ private:
+ static bool IsSpriteVisual(EGLNativeWindowType window);
+
+ bool mHasAlpha;
+
+ RoHelper mRoHelper;
+
+ // Namespace prefix required here for some reason despite using namespace
+ Microsoft::WRL::ComPtr<ABI::Windows::UI::Composition::ISpriteVisual> mHostVisual;
+ Microsoft::WRL::ComPtr<ABI::Windows::UI::Composition::ICompositionBrush> mCompositionBrush;
+ Microsoft::WRL::ComPtr<ABI::Windows::UI::Composition::ICompositionSurface> mSurface;
+ Microsoft::WRL::ComPtr<ABI::Windows::UI::Composition::ICompositionSurfaceBrush> mSurfaceBrush;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D11_CONVERGED_COMPOSITORNATIVEWINDOW11_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/formatutils11.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/formatutils11.cpp
new file mode 100644
index 0000000000..75ddbd9ea1
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/formatutils11.cpp
@@ -0,0 +1,1029 @@
+//
+// Copyright 2013 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.
+//
+
+// formatutils11.cpp: Queries for GL image formats and their translations to D3D11
+// formats.
+
+#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/copyvertex.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+#include "libANGLE/renderer/dxgi_support_table.h"
+
+namespace rx
+{
+
+namespace d3d11
+{
+
+bool SupportsMipGen(DXGI_FORMAT dxgiFormat, D3D_FEATURE_LEVEL featureLevel)
+{
+ const auto &support = GetDXGISupport(dxgiFormat, featureLevel);
+ ASSERT((support.optionallySupportedFlags & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN) == 0);
+ return ((support.alwaysSupportedFlags & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN) != 0);
+}
+
+DXGIFormatSize::DXGIFormatSize(GLuint pixelBits, GLuint blockWidth, GLuint blockHeight)
+ : pixelBytes(pixelBits / 8), blockWidth(blockWidth), blockHeight(blockHeight)
+{}
+
+const DXGIFormatSize &GetDXGIFormatSizeInfo(DXGI_FORMAT format)
+{
+ static const DXGIFormatSize sizeUnknown(0, 0, 0);
+ static const DXGIFormatSize size128(128, 1, 1);
+ static const DXGIFormatSize size96(96, 1, 1);
+ static const DXGIFormatSize size64(64, 1, 1);
+ static const DXGIFormatSize size32(32, 1, 1);
+ static const DXGIFormatSize size16(16, 1, 1);
+ static const DXGIFormatSize size8(8, 1, 1);
+ static const DXGIFormatSize sizeBC1(64, 4, 4);
+ static const DXGIFormatSize sizeBC2(128, 4, 4);
+ static const DXGIFormatSize sizeBC3(128, 4, 4);
+ static const DXGIFormatSize sizeBC4(64, 4, 4);
+ static const DXGIFormatSize sizeBC5(128, 4, 4);
+ static const DXGIFormatSize sizeBC6H(128, 4, 4);
+ static const DXGIFormatSize sizeBC7(128, 4, 4);
+ switch (format)
+ {
+ case DXGI_FORMAT_UNKNOWN:
+ return sizeUnknown;
+ case DXGI_FORMAT_R32G32B32A32_TYPELESS:
+ case DXGI_FORMAT_R32G32B32A32_FLOAT:
+ case DXGI_FORMAT_R32G32B32A32_UINT:
+ case DXGI_FORMAT_R32G32B32A32_SINT:
+ return size128;
+ case DXGI_FORMAT_R32G32B32_TYPELESS:
+ case DXGI_FORMAT_R32G32B32_FLOAT:
+ case DXGI_FORMAT_R32G32B32_UINT:
+ case DXGI_FORMAT_R32G32B32_SINT:
+ return size96;
+ case DXGI_FORMAT_R16G16B16A16_TYPELESS:
+ case DXGI_FORMAT_R16G16B16A16_FLOAT:
+ case DXGI_FORMAT_R16G16B16A16_UNORM:
+ case DXGI_FORMAT_R16G16B16A16_UINT:
+ case DXGI_FORMAT_R16G16B16A16_SNORM:
+ case DXGI_FORMAT_R16G16B16A16_SINT:
+ case DXGI_FORMAT_R32G32_TYPELESS:
+ case DXGI_FORMAT_R32G32_FLOAT:
+ case DXGI_FORMAT_R32G32_UINT:
+ case DXGI_FORMAT_R32G32_SINT:
+ case DXGI_FORMAT_R32G8X24_TYPELESS:
+ case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
+ case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
+ case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
+ return size64;
+ case DXGI_FORMAT_R10G10B10A2_TYPELESS:
+ case DXGI_FORMAT_R10G10B10A2_UNORM:
+ case DXGI_FORMAT_R10G10B10A2_UINT:
+ case DXGI_FORMAT_R11G11B10_FLOAT:
+ case DXGI_FORMAT_R8G8B8A8_TYPELESS:
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
+ case DXGI_FORMAT_R8G8B8A8_UINT:
+ case DXGI_FORMAT_R8G8B8A8_SNORM:
+ case DXGI_FORMAT_R8G8B8A8_SINT:
+ case DXGI_FORMAT_R16G16_TYPELESS:
+ case DXGI_FORMAT_R16G16_FLOAT:
+ case DXGI_FORMAT_R16G16_UNORM:
+ case DXGI_FORMAT_R16G16_UINT:
+ case DXGI_FORMAT_R16G16_SNORM:
+ case DXGI_FORMAT_R16G16_SINT:
+ case DXGI_FORMAT_R32_TYPELESS:
+ case DXGI_FORMAT_D32_FLOAT:
+ case DXGI_FORMAT_R32_FLOAT:
+ case DXGI_FORMAT_R32_UINT:
+ case DXGI_FORMAT_R32_SINT:
+ case DXGI_FORMAT_R24G8_TYPELESS:
+ case DXGI_FORMAT_D24_UNORM_S8_UINT:
+ case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
+ case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
+ return size32;
+ case DXGI_FORMAT_R8G8_TYPELESS:
+ case DXGI_FORMAT_R8G8_UNORM:
+ case DXGI_FORMAT_R8G8_UINT:
+ case DXGI_FORMAT_R8G8_SNORM:
+ case DXGI_FORMAT_R8G8_SINT:
+ case DXGI_FORMAT_R16_TYPELESS:
+ case DXGI_FORMAT_R16_FLOAT:
+ case DXGI_FORMAT_D16_UNORM:
+ case DXGI_FORMAT_R16_UNORM:
+ case DXGI_FORMAT_R16_UINT:
+ case DXGI_FORMAT_R16_SNORM:
+ case DXGI_FORMAT_R16_SINT:
+ return size16;
+ case DXGI_FORMAT_R8_TYPELESS:
+ case DXGI_FORMAT_R8_UNORM:
+ case DXGI_FORMAT_R8_UINT:
+ case DXGI_FORMAT_R8_SNORM:
+ case DXGI_FORMAT_R8_SINT:
+ case DXGI_FORMAT_A8_UNORM:
+ return size8;
+ case DXGI_FORMAT_R1_UNORM:
+ UNREACHABLE();
+ return sizeUnknown;
+ case DXGI_FORMAT_R9G9B9E5_SHAREDEXP:
+ case DXGI_FORMAT_R8G8_B8G8_UNORM:
+ case DXGI_FORMAT_G8R8_G8B8_UNORM:
+ return size32;
+ case DXGI_FORMAT_BC1_TYPELESS:
+ case DXGI_FORMAT_BC1_UNORM:
+ case DXGI_FORMAT_BC1_UNORM_SRGB:
+ return sizeBC1;
+ case DXGI_FORMAT_BC2_TYPELESS:
+ case DXGI_FORMAT_BC2_UNORM:
+ case DXGI_FORMAT_BC2_UNORM_SRGB:
+ return sizeBC2;
+ case DXGI_FORMAT_BC3_TYPELESS:
+ case DXGI_FORMAT_BC3_UNORM:
+ case DXGI_FORMAT_BC3_UNORM_SRGB:
+ return sizeBC3;
+ case DXGI_FORMAT_BC4_TYPELESS:
+ case DXGI_FORMAT_BC4_UNORM:
+ case DXGI_FORMAT_BC4_SNORM:
+ return sizeBC4;
+ case DXGI_FORMAT_BC5_TYPELESS:
+ case DXGI_FORMAT_BC5_UNORM:
+ case DXGI_FORMAT_BC5_SNORM:
+ return sizeBC5;
+ case DXGI_FORMAT_B5G6R5_UNORM:
+ case DXGI_FORMAT_B5G5R5A1_UNORM:
+ return size16;
+ case DXGI_FORMAT_B8G8R8A8_UNORM:
+ case DXGI_FORMAT_B8G8R8X8_UNORM:
+ case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
+ case DXGI_FORMAT_B8G8R8A8_TYPELESS:
+ case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
+ case DXGI_FORMAT_B8G8R8X8_TYPELESS:
+ case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
+ return size32;
+ case DXGI_FORMAT_BC6H_TYPELESS:
+ case DXGI_FORMAT_BC6H_UF16:
+ case DXGI_FORMAT_BC6H_SF16:
+ return sizeBC6H;
+ case DXGI_FORMAT_BC7_TYPELESS:
+ case DXGI_FORMAT_BC7_UNORM:
+ case DXGI_FORMAT_BC7_UNORM_SRGB:
+ return sizeBC7;
+ case DXGI_FORMAT_AYUV:
+ case DXGI_FORMAT_Y410:
+ case DXGI_FORMAT_Y416:
+ case DXGI_FORMAT_NV12:
+ case DXGI_FORMAT_P010:
+ case DXGI_FORMAT_P016:
+ case DXGI_FORMAT_420_OPAQUE:
+ case DXGI_FORMAT_YUY2:
+ case DXGI_FORMAT_Y210:
+ case DXGI_FORMAT_Y216:
+ case DXGI_FORMAT_NV11:
+ case DXGI_FORMAT_AI44:
+ case DXGI_FORMAT_IA44:
+ case DXGI_FORMAT_P8:
+ case DXGI_FORMAT_A8P8:
+ UNREACHABLE();
+ return sizeUnknown;
+ case DXGI_FORMAT_B4G4R4A4_UNORM:
+ return size16;
+ default:
+ UNREACHABLE();
+ return sizeUnknown;
+ }
+}
+
+constexpr VertexFormat::VertexFormat()
+ : conversionType(VERTEX_CONVERT_NONE), nativeFormat(DXGI_FORMAT_UNKNOWN), copyFunction(nullptr)
+{}
+
+constexpr VertexFormat::VertexFormat(VertexConversionType conversionTypeIn,
+ DXGI_FORMAT nativeFormatIn,
+ VertexCopyFunction copyFunctionIn)
+ : conversionType(conversionTypeIn), nativeFormat(nativeFormatIn), copyFunction(copyFunctionIn)
+{}
+
+const VertexFormat *GetVertexFormatInfo_FL_9_3(angle::FormatID vertexFormatID)
+{
+ // D3D11 Feature Level 9_3 doesn't support as many formats for vertex buffer resource as Feature
+ // Level 10_0+.
+ // http://msdn.microsoft.com/en-us/library/windows/desktop/ff471324(v=vs.85).aspx
+
+ switch (vertexFormatID)
+ {
+ // GL_BYTE -- unnormalized
+ case angle::FormatID::R8_SSCALED:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16_SINT,
+ &Copy8SintTo16SintVertexData<1, 2>);
+ return &info;
+ }
+ case angle::FormatID::R8G8_SSCALED:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16_SINT,
+ &Copy8SintTo16SintVertexData<2, 2>);
+ return &info;
+ }
+ case angle::FormatID::R8G8B8_SSCALED:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_SINT,
+ &Copy8SintTo16SintVertexData<3, 4>);
+ return &info;
+ }
+ case angle::FormatID::R8G8B8A8_SSCALED:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_SINT,
+ &Copy8SintTo16SintVertexData<4, 4>);
+ return &info;
+ }
+
+ // GL_BYTE -- normalized
+ case angle::FormatID::R8_SNORM:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16_SNORM,
+ &Copy8SnormTo16SnormVertexData<1, 2>);
+ return &info;
+ }
+ case angle::FormatID::R8G8_SNORM:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16_SNORM,
+ &Copy8SnormTo16SnormVertexData<2, 2>);
+ return &info;
+ }
+ case angle::FormatID::R8G8B8_SNORM:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SNORM,
+ &Copy8SnormTo16SnormVertexData<3, 4>);
+ return &info;
+ }
+ case angle::FormatID::R8G8B8A8_SNORM:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SNORM,
+ &Copy8SnormTo16SnormVertexData<4, 4>);
+ return &info;
+ }
+
+ // GL_UNSIGNED_BYTE -- un-normalized
+ // NOTE: 3 and 4 component unnormalized GL_UNSIGNED_BYTE should use the default format
+ // table.
+ case angle::FormatID::R8_USCALED:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_UINT,
+ &CopyNativeVertexData<GLubyte, 1, 4, 1>);
+ return &info;
+ }
+ case angle::FormatID::R8G8_USCALED:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_UINT,
+ &CopyNativeVertexData<GLubyte, 2, 4, 1>);
+ return &info;
+ }
+
+ // GL_UNSIGNED_BYTE -- normalized
+ // NOTE: 3 and 4 component normalized GL_UNSIGNED_BYTE should use the default format table.
+
+ // GL_UNSIGNED_BYTE -- normalized
+ case angle::FormatID::R8_UNORM:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_UNORM,
+ &CopyNativeVertexData<GLubyte, 1, 4, UINT8_MAX>);
+ return &info;
+ }
+ case angle::FormatID::R8G8_UNORM:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_UNORM,
+ &CopyNativeVertexData<GLubyte, 2, 4, UINT8_MAX>);
+ return &info;
+ }
+
+ // GL_SHORT -- un-normalized
+ // NOTE: 2, 3 and 4 component unnormalized GL_SHORT should use the default format table.
+ case angle::FormatID::R16_SSCALED:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16_SINT,
+ &CopyNativeVertexData<GLshort, 1, 2, 0>);
+ return &info;
+ }
+
+ // GL_SHORT -- normalized
+ // NOTE: 2, 3 and 4 component normalized GL_SHORT should use the default format table.
+ case angle::FormatID::R16_SNORM:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16_SNORM,
+ &CopyNativeVertexData<GLshort, 1, 2, 0>);
+ return &info;
+ }
+
+ // GL_UNSIGNED_SHORT -- un-normalized
+ case angle::FormatID::R16_USCALED:
+ {
+ static constexpr VertexFormat info(
+ VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT,
+ &CopyToFloatVertexData<GLushort, 1, 2, false, false>);
+ return &info;
+ }
+ case angle::FormatID::R16G16_USCALED:
+ {
+ static constexpr VertexFormat info(
+ VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT,
+ &CopyToFloatVertexData<GLushort, 2, 2, false, false>);
+ return &info;
+ }
+ case angle::FormatID::R16G16B16_USCALED:
+ {
+ static constexpr VertexFormat info(
+ VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT,
+ &CopyToFloatVertexData<GLushort, 3, 3, false, false>);
+ return &info;
+ }
+ case angle::FormatID::R16G16B16A16_USCALED:
+ {
+ static constexpr VertexFormat info(
+ VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT,
+ &CopyToFloatVertexData<GLushort, 4, 4, false, false>);
+ return &info;
+ }
+
+ // GL_UNSIGNED_SHORT -- normalized
+ case angle::FormatID::R16_UNORM:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT,
+ &CopyToFloatVertexData<GLushort, 1, 2, true, false>);
+ return &info;
+ }
+ case angle::FormatID::R16G16_UNORM:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT,
+ &CopyToFloatVertexData<GLushort, 2, 2, true, false>);
+ return &info;
+ }
+ case angle::FormatID::R16G16B16_UNORM:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT,
+ &CopyToFloatVertexData<GLushort, 3, 3, true, false>);
+ return &info;
+ }
+ case angle::FormatID::R16G16B16A16_UNORM:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT,
+ &CopyToFloatVertexData<GLushort, 4, 4, true, false>);
+ return &info;
+ }
+
+ // GL_FIXED
+ // TODO: Add test to verify that this works correctly.
+ // NOTE: 2, 3 and 4 component GL_FIXED should use the default format table.
+ case angle::FormatID::R32_FIXED:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT,
+ &Copy32FixedTo32FVertexData<1, 2>);
+ return &info;
+ }
+
+ // GL_FLOAT
+ // TODO: Add test to verify that this works correctly.
+ // NOTE: 2, 3 and 4 component GL_FLOAT should use the default format table.
+ case angle::FormatID::R32_FLOAT:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT,
+ &CopyNativeVertexData<GLfloat, 1, 2, 0>);
+ return &info;
+ }
+
+ default:
+ return nullptr;
+ }
+}
+
+const VertexFormat &GetVertexFormatInfo(angle::FormatID vertexFormatID,
+ D3D_FEATURE_LEVEL featureLevel)
+{
+ if (featureLevel == D3D_FEATURE_LEVEL_9_3)
+ {
+ const VertexFormat *result = GetVertexFormatInfo_FL_9_3(vertexFormatID);
+ if (result)
+ {
+ return *result;
+ }
+ }
+
+ switch (vertexFormatID)
+ {
+ //
+ // Float formats
+ //
+
+ // GL_BYTE -- un-normalized
+ case angle::FormatID::R8_SSCALED:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R8_SINT,
+ &CopyNativeVertexData<GLbyte, 1, 1, 0>);
+ return info;
+ }
+ case angle::FormatID::R8G8_SSCALED:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8_SINT,
+ &CopyNativeVertexData<GLbyte, 2, 2, 0>);
+ return info;
+ }
+ case angle::FormatID::R8G8B8_SSCALED:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_SINT,
+ &CopyNativeVertexData<GLbyte, 3, 4, 1>);
+ return info;
+ }
+ case angle::FormatID::R8G8B8A8_SSCALED:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8B8A8_SINT,
+ &CopyNativeVertexData<GLbyte, 4, 4, 0>);
+ return info;
+ }
+
+ // GL_BYTE -- normalized
+ case angle::FormatID::R8_SNORM:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_SNORM,
+ &CopyNativeVertexData<GLbyte, 1, 1, 0>);
+ return info;
+ }
+ case angle::FormatID::R8G8_SNORM:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_SNORM,
+ &CopyNativeVertexData<GLbyte, 2, 2, 0>);
+ return info;
+ }
+ case angle::FormatID::R8G8B8_SNORM:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_SNORM,
+ &CopyNativeVertexData<GLbyte, 3, 4, INT8_MAX>);
+ return info;
+ }
+ case angle::FormatID::R8G8B8A8_SNORM:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_SNORM,
+ &CopyNativeVertexData<GLbyte, 4, 4, 0>);
+ return info;
+ }
+
+ // GL_UNSIGNED_BYTE -- un-normalized
+ case angle::FormatID::R8_USCALED:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R8_UINT,
+ &CopyNativeVertexData<GLubyte, 1, 1, 0>);
+ return info;
+ }
+ case angle::FormatID::R8G8_USCALED:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8_UINT,
+ &CopyNativeVertexData<GLubyte, 2, 2, 0>);
+ return info;
+ }
+ case angle::FormatID::R8G8B8_USCALED:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R8G8B8A8_UINT,
+ &CopyNativeVertexData<GLubyte, 3, 4, 1>);
+ return info;
+ }
+ case angle::FormatID::R8G8B8A8_USCALED:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R8G8B8A8_UINT,
+ &CopyNativeVertexData<GLubyte, 4, 4, 0>);
+ return info;
+ }
+
+ // GL_UNSIGNED_BYTE -- normalized
+ case angle::FormatID::R8_UNORM:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_UNORM,
+ &CopyNativeVertexData<GLubyte, 1, 1, 0>);
+ return info;
+ }
+ case angle::FormatID::R8G8_UNORM:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_UNORM,
+ &CopyNativeVertexData<GLubyte, 2, 2, 0>);
+ return info;
+ }
+ case angle::FormatID::R8G8B8_UNORM:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_UNORM,
+ &CopyNativeVertexData<GLubyte, 3, 4, UINT8_MAX>);
+ return info;
+ }
+ case angle::FormatID::R8G8B8A8_UNORM:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_UNORM,
+ &CopyNativeVertexData<GLubyte, 4, 4, 0>);
+ return info;
+ }
+
+ // GL_SHORT -- un-normalized
+ case angle::FormatID::R16_SSCALED:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R16_SINT,
+ &CopyNativeVertexData<GLshort, 1, 1, 0>);
+ return info;
+ }
+ case angle::FormatID::R16G16_SSCALED:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16_SINT,
+ &CopyNativeVertexData<GLshort, 2, 2, 0>);
+ return info;
+ }
+ case angle::FormatID::R16G16B16_SSCALED:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_SINT,
+ &CopyNativeVertexData<GLshort, 3, 4, 1>);
+ return info;
+ }
+ case angle::FormatID::R16G16B16A16_SSCALED:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16B16A16_SINT,
+ &CopyNativeVertexData<GLshort, 4, 4, 0>);
+ return info;
+ }
+
+ // GL_SHORT -- normalized
+ case angle::FormatID::R16_SNORM:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_SNORM,
+ &CopyNativeVertexData<GLshort, 1, 1, 0>);
+ return info;
+ }
+ case angle::FormatID::R16G16_SNORM:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_SNORM,
+ &CopyNativeVertexData<GLshort, 2, 2, 0>);
+ return info;
+ }
+ case angle::FormatID::R16G16B16_SNORM:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SNORM,
+ &CopyNativeVertexData<GLshort, 3, 4, INT16_MAX>);
+ return info;
+ }
+ case angle::FormatID::R16G16B16A16_SNORM:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_SNORM,
+ &CopyNativeVertexData<GLshort, 4, 4, 0>);
+ return info;
+ }
+
+ // GL_UNSIGNED_SHORT -- un-normalized
+ case angle::FormatID::R16_USCALED:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R16_UINT,
+ &CopyNativeVertexData<GLushort, 1, 1, 0>);
+ return info;
+ }
+ case angle::FormatID::R16G16_USCALED:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16_UINT,
+ &CopyNativeVertexData<GLushort, 2, 2, 0>);
+ return info;
+ }
+ case angle::FormatID::R16G16B16_USCALED:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_BOTH, DXGI_FORMAT_R16G16B16A16_UINT,
+ &CopyNativeVertexData<GLushort, 3, 4, 1>);
+ return info;
+ }
+ case angle::FormatID::R16G16B16A16_USCALED:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R16G16B16A16_UINT,
+ &CopyNativeVertexData<GLushort, 4, 4, 0>);
+ return info;
+ }
+
+ // GL_UNSIGNED_SHORT -- normalized
+ case angle::FormatID::R16_UNORM:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_UNORM,
+ &CopyNativeVertexData<GLushort, 1, 1, 0>);
+ return info;
+ }
+ case angle::FormatID::R16G16_UNORM:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_UNORM,
+ &CopyNativeVertexData<GLushort, 2, 2, 0>);
+ return info;
+ }
+ case angle::FormatID::R16G16B16_UNORM:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_UNORM,
+ &CopyNativeVertexData<GLushort, 3, 4, UINT16_MAX>);
+ return info;
+ }
+ case angle::FormatID::R16G16B16A16_UNORM:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_UNORM,
+ &CopyNativeVertexData<GLushort, 4, 4, 0>);
+ return info;
+ }
+
+ // GL_INT -- un-normalized
+ case angle::FormatID::R32_SSCALED:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32_SINT,
+ &CopyNativeVertexData<GLint, 1, 1, 0>);
+ return info;
+ }
+ case angle::FormatID::R32G32_SSCALED:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32_SINT,
+ &CopyNativeVertexData<GLint, 2, 2, 0>);
+ return info;
+ }
+ case angle::FormatID::R32G32B32_SSCALED:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32_SINT,
+ &CopyNativeVertexData<GLint, 3, 3, 0>);
+ return info;
+ }
+ case angle::FormatID::R32G32B32A32_SSCALED:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32A32_SINT,
+ &CopyNativeVertexData<GLint, 4, 4, 0>);
+ return info;
+ }
+
+ // GL_INT -- normalized
+ case angle::FormatID::R32_SNORM:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32_FLOAT,
+ &CopyToFloatVertexData<GLint, 1, 1, true, false>);
+ return info;
+ }
+ case angle::FormatID::R32G32_SNORM:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT,
+ &CopyToFloatVertexData<GLint, 2, 2, true, false>);
+ return info;
+ }
+ case angle::FormatID::R32G32B32_SNORM:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT,
+ &CopyToFloatVertexData<GLint, 3, 3, true, false>);
+ return info;
+ }
+ case angle::FormatID::R32G32B32A32_SNORM:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT,
+ &CopyToFloatVertexData<GLint, 4, 4, true, false>);
+ return info;
+ }
+
+ // GL_UNSIGNED_INT -- un-normalized
+ case angle::FormatID::R32_USCALED:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32_UINT,
+ &CopyNativeVertexData<GLuint, 1, 1, 0>);
+ return info;
+ }
+ case angle::FormatID::R32G32_USCALED:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32_UINT,
+ &CopyNativeVertexData<GLuint, 2, 2, 0>);
+ return info;
+ }
+ case angle::FormatID::R32G32B32_USCALED:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32_UINT,
+ &CopyNativeVertexData<GLuint, 3, 3, 0>);
+ return info;
+ }
+ case angle::FormatID::R32G32B32A32_USCALED:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_GPU, DXGI_FORMAT_R32G32B32A32_UINT,
+ &CopyNativeVertexData<GLuint, 4, 4, 0>);
+ return info;
+ }
+
+ // GL_UNSIGNED_INT -- normalized
+ case angle::FormatID::R32_UNORM:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32_FLOAT,
+ &CopyToFloatVertexData<GLuint, 1, 1, true, false>);
+ return info;
+ }
+ case angle::FormatID::R32G32_UNORM:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT,
+ &CopyToFloatVertexData<GLuint, 2, 2, true, false>);
+ return info;
+ }
+ case angle::FormatID::R32G32B32_UNORM:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT,
+ &CopyToFloatVertexData<GLuint, 3, 3, true, false>);
+ return info;
+ }
+ case angle::FormatID::R32G32B32A32_UNORM:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT,
+ &CopyToFloatVertexData<GLuint, 4, 4, true, false>);
+ return info;
+ }
+
+ // GL_FIXED
+ case angle::FormatID::R32_FIXED:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32_FLOAT,
+ &Copy32FixedTo32FVertexData<1, 1>);
+ return info;
+ }
+ case angle::FormatID::R32G32_FIXED:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32_FLOAT,
+ &Copy32FixedTo32FVertexData<2, 2>);
+ return info;
+ }
+ case angle::FormatID::R32G32B32_FIXED:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32_FLOAT,
+ &Copy32FixedTo32FVertexData<3, 3>);
+ return info;
+ }
+ case angle::FormatID::R32G32B32A32_FIXED:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT,
+ &Copy32FixedTo32FVertexData<4, 4>);
+ return info;
+ }
+
+ // GL_HALF_FLOAT
+ case angle::FormatID::R16_FLOAT:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_FLOAT,
+ &CopyNativeVertexData<GLhalf, 1, 1, 0>);
+ return info;
+ }
+ case angle::FormatID::R16G16_FLOAT:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_FLOAT,
+ &CopyNativeVertexData<GLhalf, 2, 2, 0>);
+ return info;
+ }
+ case angle::FormatID::R16G16B16_FLOAT:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_FLOAT,
+ &CopyNativeVertexData<GLhalf, 3, 4, gl::Float16One>);
+ return info;
+ }
+ case angle::FormatID::R16G16B16A16_FLOAT:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_FLOAT,
+ &CopyNativeVertexData<GLhalf, 4, 4, 0>);
+ return info;
+ }
+
+ // GL_FLOAT
+ case angle::FormatID::R32_FLOAT:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_FLOAT,
+ &CopyNativeVertexData<GLfloat, 1, 1, 0>);
+ return info;
+ }
+ case angle::FormatID::R32G32_FLOAT:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_FLOAT,
+ &CopyNativeVertexData<GLfloat, 2, 2, 0>);
+ return info;
+ }
+ case angle::FormatID::R32G32B32_FLOAT:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_FLOAT,
+ &CopyNativeVertexData<GLfloat, 3, 3, 0>);
+ return info;
+ }
+ case angle::FormatID::R32G32B32A32_FLOAT:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_FLOAT,
+ &CopyNativeVertexData<GLfloat, 4, 4, 0>);
+ return info;
+ }
+
+ // GL_INT_2_10_10_10_REV
+ case angle::FormatID::R10G10B10A2_SSCALED:
+ {
+ static constexpr VertexFormat info(
+ VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT,
+ &CopyXYZ10W2ToXYZWFloatVertexData<true, false, true, false>);
+ return info;
+ }
+ case angle::FormatID::R10G10B10A2_SNORM:
+ {
+ static constexpr VertexFormat info(
+ VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT,
+ &CopyXYZ10W2ToXYZWFloatVertexData<true, true, true, false>);
+ return info;
+ }
+
+ // GL_UNSIGNED_INT_2_10_10_10_REV
+ case angle::FormatID::R10G10B10A2_USCALED:
+ {
+ static constexpr VertexFormat info(
+ VERTEX_CONVERT_CPU, DXGI_FORMAT_R32G32B32A32_FLOAT,
+ &CopyXYZ10W2ToXYZWFloatVertexData<false, false, true, false>);
+ return info;
+ }
+ case angle::FormatID::R10G10B10A2_UNORM:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R10G10B10A2_UNORM,
+ &CopyNativeVertexData<GLuint, 1, 1, 0>);
+ return info;
+ }
+
+ //
+ // Integer Formats
+ //
+
+ // GL_BYTE
+ case angle::FormatID::R8_SINT:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_SINT,
+ &CopyNativeVertexData<GLbyte, 1, 1, 0>);
+ return info;
+ }
+ case angle::FormatID::R8G8_SINT:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_SINT,
+ &CopyNativeVertexData<GLbyte, 2, 2, 0>);
+ return info;
+ }
+ case angle::FormatID::R8G8B8_SINT:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_SINT,
+ &CopyNativeVertexData<GLbyte, 3, 4, 1>);
+ return info;
+ }
+ case angle::FormatID::R8G8B8A8_SINT:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_SINT,
+ &CopyNativeVertexData<GLbyte, 4, 4, 0>);
+ return info;
+ }
+
+ // GL_UNSIGNED_BYTE
+ case angle::FormatID::R8_UINT:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8_UINT,
+ &CopyNativeVertexData<GLubyte, 1, 1, 0>);
+ return info;
+ }
+ case angle::FormatID::R8G8_UINT:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8_UINT,
+ &CopyNativeVertexData<GLubyte, 2, 2, 0>);
+ return info;
+ }
+ case angle::FormatID::R8G8B8_UINT:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R8G8B8A8_UINT,
+ &CopyNativeVertexData<GLubyte, 3, 4, 1>);
+ return info;
+ }
+ case angle::FormatID::R8G8B8A8_UINT:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R8G8B8A8_UINT,
+ &CopyNativeVertexData<GLubyte, 4, 4, 0>);
+ return info;
+ }
+
+ // GL_SHORT
+ case angle::FormatID::R16_SINT:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_SINT,
+ &CopyNativeVertexData<GLshort, 1, 1, 0>);
+ return info;
+ }
+ case angle::FormatID::R16G16_SINT:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_SINT,
+ &CopyNativeVertexData<GLshort, 2, 2, 0>);
+ return info;
+ }
+ case angle::FormatID::R16G16B16_SINT:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SINT,
+ &CopyNativeVertexData<GLshort, 3, 4, 1>);
+ return info;
+ }
+ case angle::FormatID::R16G16B16A16_SINT:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_SINT,
+ &CopyNativeVertexData<GLshort, 4, 4, 0>);
+ return info;
+ }
+
+ // GL_UNSIGNED_SHORT
+ case angle::FormatID::R16_UINT:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16_UINT,
+ &CopyNativeVertexData<GLushort, 1, 1, 0>);
+ return info;
+ }
+ case angle::FormatID::R16G16_UINT:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16_UINT,
+ &CopyNativeVertexData<GLushort, 2, 2, 0>);
+ return info;
+ }
+ case angle::FormatID::R16G16B16_UINT:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_UINT,
+ &CopyNativeVertexData<GLushort, 3, 4, 1>);
+ return info;
+ }
+ case angle::FormatID::R16G16B16A16_UINT:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R16G16B16A16_UINT,
+ &CopyNativeVertexData<GLushort, 4, 4, 0>);
+ return info;
+ }
+
+ // GL_INT
+ case angle::FormatID::R32_SINT:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_SINT,
+ &CopyNativeVertexData<GLint, 1, 1, 0>);
+ return info;
+ }
+ case angle::FormatID::R32G32_SINT:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_SINT,
+ &CopyNativeVertexData<GLint, 2, 2, 0>);
+ return info;
+ }
+ case angle::FormatID::R32G32B32_SINT:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_SINT,
+ &CopyNativeVertexData<GLint, 3, 3, 0>);
+ return info;
+ }
+ case angle::FormatID::R32G32B32A32_SINT:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_SINT,
+ &CopyNativeVertexData<GLint, 4, 4, 0>);
+ return info;
+ }
+
+ // GL_UNSIGNED_INT
+ case angle::FormatID::R32_UINT:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32_SINT,
+ &CopyNativeVertexData<GLuint, 1, 1, 0>);
+ return info;
+ }
+ case angle::FormatID::R32G32_UINT:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32_SINT,
+ &CopyNativeVertexData<GLuint, 2, 2, 0>);
+ return info;
+ }
+ case angle::FormatID::R32G32B32_UINT:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32_SINT,
+ &CopyNativeVertexData<GLuint, 3, 3, 0>);
+ return info;
+ }
+ case angle::FormatID::R32G32B32A32_UINT:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R32G32B32A32_SINT,
+ &CopyNativeVertexData<GLuint, 4, 4, 0>);
+ return info;
+ }
+
+ // GL_INT_2_10_10_10_REV
+ case angle::FormatID::R10G10B10A2_SINT:
+ {
+ static constexpr VertexFormat info(
+ VERTEX_CONVERT_CPU, DXGI_FORMAT_R16G16B16A16_SINT,
+ &CopyXYZ10W2ToXYZWFloatVertexData<true, true, false, false>);
+ return info;
+ }
+
+ // GL_UNSIGNED_INT_2_10_10_10_REV
+ case angle::FormatID::R10G10B10A2_UINT:
+ {
+ static constexpr VertexFormat info(VERTEX_CONVERT_NONE, DXGI_FORMAT_R10G10B10A2_UINT,
+ &CopyNativeVertexData<GLuint, 1, 1, 0>);
+ return info;
+ }
+
+ default:
+ {
+ static constexpr VertexFormat info;
+ return info;
+ }
+ }
+}
+
+} // namespace d3d11
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/formatutils11.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/formatutils11.h
new file mode 100644
index 0000000000..e4c3994280
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/formatutils11.h
@@ -0,0 +1,64 @@
+//
+// Copyright 2013 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.
+//
+
+// formatutils11.h: Queries for GL image formats and their translations to D3D11
+// formats.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_FORMATUTILS11_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_FORMATUTILS11_H_
+
+#include <map>
+
+#include "common/platform.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/copyvertex.h"
+#include "libANGLE/renderer/d3d/formatutilsD3D.h"
+#include "libANGLE/renderer/dxgi_format_map.h"
+#include "libANGLE/renderer/renderer_utils.h"
+
+namespace rx
+{
+struct Renderer11DeviceCaps;
+
+namespace d3d11
+{
+
+// A texture might be stored as DXGI_FORMAT_R16_TYPELESS but store integer components,
+// which are accessed through an DXGI_FORMAT_R16_SINT view. It's easy to write code which queries
+// information about the wrong format. Therefore, use of this should be avoided where possible.
+
+bool SupportsMipGen(DXGI_FORMAT dxgiFormat, D3D_FEATURE_LEVEL featureLevel);
+
+struct DXGIFormatSize
+{
+ DXGIFormatSize(GLuint pixelBits, GLuint blockWidth, GLuint blockHeight);
+
+ GLuint pixelBytes;
+ GLuint blockWidth;
+ GLuint blockHeight;
+};
+const DXGIFormatSize &GetDXGIFormatSizeInfo(DXGI_FORMAT format);
+
+struct VertexFormat : private angle::NonCopyable
+{
+ constexpr VertexFormat();
+ constexpr VertexFormat(VertexConversionType conversionType,
+ DXGI_FORMAT nativeFormat,
+ VertexCopyFunction copyFunction);
+
+ VertexConversionType conversionType;
+ DXGI_FORMAT nativeFormat;
+ VertexCopyFunction copyFunction;
+};
+
+const VertexFormat &GetVertexFormatInfo(angle::FormatID vertexFormatID,
+ D3D_FEATURE_LEVEL featureLevel);
+} // namespace d3d11
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D11_FORMATUTILS11_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
new file mode 100644
index 0000000000..8cd97ee43d
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
@@ -0,0 +1,2751 @@
+//
+// Copyright 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.
+//
+
+// renderer11_utils.cpp: Conversion functions and other utility routines
+// specific to the D3D11 renderer.
+
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+
+#include <versionhelpers.h>
+#include <algorithm>
+
+#include "common/debug.h"
+#include "libANGLE/Buffer.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/Program.h"
+#include "libANGLE/State.h"
+#include "libANGLE/VertexArray.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/d3d/BufferD3D.h"
+#include "libANGLE/renderer/d3d/FramebufferD3D.h"
+#include "libANGLE/renderer/d3d/d3d11/Context11.h"
+#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
+#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
+#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
+#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
+#include "libANGLE/renderer/driver_utils.h"
+#include "libANGLE/renderer/dxgi_support_table.h"
+#include "platform/FeaturesD3D_autogen.h"
+#include "platform/PlatformMethods.h"
+
+namespace rx
+{
+
+namespace d3d11_gl
+{
+namespace
+{
+// TODO(xinghua.cao@intel.com): Get a more accurate limit.
+static D3D_FEATURE_LEVEL kMinimumFeatureLevelForES31 = D3D_FEATURE_LEVEL_11_0;
+
+// Helper functor for querying DXGI support. Saves passing the parameters repeatedly.
+class DXGISupportHelper : angle::NonCopyable
+{
+ public:
+ DXGISupportHelper(ID3D11Device *device, D3D_FEATURE_LEVEL featureLevel)
+ : mDevice(device), mFeatureLevel(featureLevel)
+ {}
+
+ bool query(DXGI_FORMAT dxgiFormat, UINT supportMask)
+ {
+ if (dxgiFormat == DXGI_FORMAT_UNKNOWN)
+ return false;
+
+ auto dxgiSupport = d3d11::GetDXGISupport(dxgiFormat, mFeatureLevel);
+
+ UINT supportedBits = dxgiSupport.alwaysSupportedFlags;
+
+ if ((dxgiSupport.optionallySupportedFlags & supportMask) != 0)
+ {
+ UINT formatSupport;
+ if (SUCCEEDED(mDevice->CheckFormatSupport(dxgiFormat, &formatSupport)))
+ {
+ supportedBits |= (formatSupport & supportMask);
+ }
+ else
+ {
+ // TODO(jmadill): find out why we fail this call sometimes in FL9_3
+ // ERR() << "Error checking format support for format 0x" << std::hex << dxgiFormat;
+ }
+ }
+
+ return ((supportedBits & supportMask) == supportMask);
+ }
+
+ private:
+ ID3D11Device *mDevice;
+ D3D_FEATURE_LEVEL mFeatureLevel;
+};
+
+gl::TextureCaps GenerateTextureFormatCaps(gl::Version maxClientVersion,
+ GLenum internalFormat,
+ ID3D11Device *device,
+ const Renderer11DeviceCaps &renderer11DeviceCaps)
+{
+ gl::TextureCaps textureCaps;
+
+ DXGISupportHelper support(device, renderer11DeviceCaps.featureLevel);
+ const d3d11::Format &formatInfo = d3d11::Format::Get(internalFormat, renderer11DeviceCaps);
+
+ const gl::InternalFormat &internalFormatInfo = gl::GetSizedInternalFormatInfo(internalFormat);
+
+ UINT texSupportMask = D3D11_FORMAT_SUPPORT_TEXTURE2D;
+ if (internalFormatInfo.depthBits == 0 && internalFormatInfo.stencilBits == 0)
+ {
+ texSupportMask |= D3D11_FORMAT_SUPPORT_TEXTURECUBE;
+ if (maxClientVersion.major > 2)
+ {
+ texSupportMask |= D3D11_FORMAT_SUPPORT_TEXTURE3D;
+ }
+ }
+
+ textureCaps.texturable = support.query(formatInfo.texFormat, texSupportMask);
+ textureCaps.filterable =
+ support.query(formatInfo.srvFormat, D3D11_FORMAT_SUPPORT_SHADER_SAMPLE);
+ textureCaps.textureAttachment =
+ (support.query(formatInfo.rtvFormat, D3D11_FORMAT_SUPPORT_RENDER_TARGET)) ||
+ (support.query(formatInfo.dsvFormat, D3D11_FORMAT_SUPPORT_DEPTH_STENCIL));
+ textureCaps.renderbuffer = textureCaps.textureAttachment;
+ textureCaps.blendable = textureCaps.renderbuffer;
+
+ DXGI_FORMAT renderFormat = DXGI_FORMAT_UNKNOWN;
+ if (formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN)
+ {
+ renderFormat = formatInfo.dsvFormat;
+ }
+ else if (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN)
+ {
+ renderFormat = formatInfo.rtvFormat;
+ }
+ if (renderFormat != DXGI_FORMAT_UNKNOWN &&
+ support.query(renderFormat, D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET))
+ {
+ // Assume 1x
+ textureCaps.sampleCounts.insert(1);
+
+ for (unsigned int sampleCount = 2; sampleCount <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT;
+ sampleCount *= 2)
+ {
+ UINT qualityCount = 0;
+ if (SUCCEEDED(device->CheckMultisampleQualityLevels(renderFormat, sampleCount,
+ &qualityCount)))
+ {
+ // Assume we always support lower sample counts
+ if (qualityCount == 0)
+ {
+ break;
+ }
+ textureCaps.sampleCounts.insert(sampleCount);
+ }
+ }
+ }
+
+ return textureCaps;
+}
+
+bool GetNPOTTextureSupport(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return true;
+
+ // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return false;
+
+ default:
+ UNREACHABLE();
+ return false;
+ }
+}
+
+float GetMaximumAnisotropy(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return D3D11_MAX_MAXANISOTROPY;
+
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return D3D10_MAX_MAXANISOTROPY;
+
+ // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ return 16;
+
+ case D3D_FEATURE_LEVEL_9_1:
+ return D3D_FL9_1_DEFAULT_MAX_ANISOTROPY;
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+bool GetOcclusionQuerySupport(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return true;
+
+ // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150.aspx
+ // ID3D11Device::CreateQuery
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ return true;
+ case D3D_FEATURE_LEVEL_9_1:
+ return false;
+
+ default:
+ UNREACHABLE();
+ return false;
+ }
+}
+
+bool GetEventQuerySupport(D3D_FEATURE_LEVEL featureLevel)
+{
+ // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150.aspx
+ // ID3D11Device::CreateQuery
+
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return true;
+
+ default:
+ UNREACHABLE();
+ return false;
+ }
+}
+
+bool GetInstancingSupport(D3D_FEATURE_LEVEL featureLevel)
+{
+ // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150.aspx
+ // ID3D11Device::CreateInputLayout
+
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return true;
+
+ // Feature Level 9_3 supports instancing, but slot 0 in the input layout must not be
+ // instanced.
+ // D3D9 has a similar restriction, where stream 0 must not be instanced.
+ // This restriction can be worked around by remapping any non-instanced slot to slot
+ // 0.
+ // This works because HLSL uses shader semantics to match the vertex inputs to the
+ // elements in the input layout, rather than the slots.
+ // Note that we only support instancing via ANGLE_instanced_array on 9_3, since 9_3
+ // doesn't support OpenGL ES 3.0
+ case D3D_FEATURE_LEVEL_9_3:
+ return true;
+
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return false;
+
+ default:
+ UNREACHABLE();
+ return false;
+ }
+}
+
+bool GetFramebufferMultisampleSupport(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return true;
+
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return false;
+
+ default:
+ UNREACHABLE();
+ return false;
+ }
+}
+
+bool GetFramebufferBlitSupport(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return true;
+
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return false;
+
+ default:
+ UNREACHABLE();
+ return false;
+ }
+}
+
+bool GetDerivativeInstructionSupport(D3D_FEATURE_LEVEL featureLevel)
+{
+ // http://msdn.microsoft.com/en-us/library/windows/desktop/bb509588.aspx states that
+ // shader model
+ // ps_2_x is required for the ddx (and other derivative functions).
+
+ // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx states that
+ // feature level
+ // 9.3 supports shader model ps_2_x.
+
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ case D3D_FEATURE_LEVEL_9_3:
+ return true;
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return false;
+
+ default:
+ UNREACHABLE();
+ return false;
+ }
+}
+
+bool GetShaderTextureLODSupport(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return true;
+
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return false;
+
+ default:
+ UNREACHABLE();
+ return false;
+ }
+}
+
+int GetMaximumSimultaneousRenderTargets(D3D_FEATURE_LEVEL featureLevel)
+{
+ // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476150.aspx
+ // ID3D11Device::CreateInputLayout
+
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT;
+
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT;
+
+ case D3D_FEATURE_LEVEL_9_3:
+ return D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT;
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT;
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+int GetMaximum2DTextureSize(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
+
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION;
+
+ case D3D_FEATURE_LEVEL_9_3:
+ return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION;
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION;
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+int GetMaximumCubeMapTextureSize(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return D3D11_REQ_TEXTURECUBE_DIMENSION;
+
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return D3D10_REQ_TEXTURECUBE_DIMENSION;
+
+ case D3D_FEATURE_LEVEL_9_3:
+ return D3D_FL9_3_REQ_TEXTURECUBE_DIMENSION;
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return D3D_FL9_1_REQ_TEXTURECUBE_DIMENSION;
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+int GetMaximum2DTextureArraySize(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION;
+
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return D3D10_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION;
+
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return 0;
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+int GetMaximum3DTextureSize(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION;
+
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return D3D10_REQ_TEXTURE3D_U_V_OR_W_DIMENSION;
+
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return D3D_FL9_1_REQ_TEXTURE3D_U_V_OR_W_DIMENSION;
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+int GetMaximumViewportSize(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return D3D11_VIEWPORT_BOUNDS_MAX;
+
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return D3D10_VIEWPORT_BOUNDS_MAX;
+
+ // No constants for D3D11 Feature Level 9 viewport size limits, use the maximum
+ // texture sizes
+ case D3D_FEATURE_LEVEL_9_3:
+ return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION;
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION;
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+int GetMaximumDrawIndexedIndexCount(D3D_FEATURE_LEVEL featureLevel)
+{
+ // D3D11 allows up to 2^32 elements, but we report max signed int for convenience since
+ // that's what's
+ // returned from glGetInteger
+ static_assert(D3D11_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP == 32,
+ "Unexpected D3D11 constant value.");
+ static_assert(D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP == 32,
+ "Unexpected D3D11 constant value.");
+
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return std::numeric_limits<GLint>::max();
+
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ return D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT;
+ case D3D_FEATURE_LEVEL_9_1:
+ return D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT;
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+int GetMaximumDrawVertexCount(D3D_FEATURE_LEVEL featureLevel)
+{
+ // D3D11 allows up to 2^32 elements, but we report max signed int for convenience since
+ // that's what's
+ // returned from glGetInteger
+ static_assert(D3D11_REQ_DRAW_VERTEX_COUNT_2_TO_EXP == 32, "Unexpected D3D11 constant value.");
+ static_assert(D3D10_REQ_DRAW_VERTEX_COUNT_2_TO_EXP == 32, "Unexpected D3D11 constant value.");
+
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return std::numeric_limits<GLint>::max();
+
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ return D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT;
+ case D3D_FEATURE_LEVEL_9_1:
+ return D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT;
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+int GetMaximumVertexInputSlots(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return D3D11_STANDARD_VERTEX_ELEMENT_COUNT;
+
+ case D3D_FEATURE_LEVEL_10_1:
+ return D3D10_1_STANDARD_VERTEX_ELEMENT_COUNT;
+ case D3D_FEATURE_LEVEL_10_0:
+ return D3D10_STANDARD_VERTEX_ELEMENT_COUNT;
+
+ // From http://http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876.aspx
+ // "Max Input Slots"
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return 16;
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+int GetMaximumVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ 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 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:
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return 255 - d3d11_gl::GetReservedVertexUniformVectors(featureLevel);
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+int GetMaximumVertexUniformBlocks(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT -
+ d3d11::RESERVED_CONSTANT_BUFFER_SLOT_COUNT;
+
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT -
+ d3d11::RESERVED_CONSTANT_BUFFER_SLOT_COUNT;
+
+ // Uniform blocks not supported on D3D11 Feature Level 9
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return 0;
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+int GetReservedVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel)
+{
+ // 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.
+ // Therefore, we should not reserve output vectors for them.
+
+ switch (featureLevel)
+ {
+ // We must reserve one output vector for dx_Position.
+ // We also reserve one for gl_Position, which we unconditionally output on Feature
+ // Levels 10_0+,
+ // even if it's unused in the shader (e.g. for transform feedback). TODO: This could
+ // be improved.
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return 2;
+
+ // Just reserve dx_Position on Feature Level 9, since we don't ever need to output
+ // gl_Position.
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return 1;
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+int GetMaximumVertexOutputVectors(D3D_FEATURE_LEVEL featureLevel)
+{
+ static_assert(gl::IMPLEMENTATION_MAX_VARYING_VECTORS == D3D11_VS_OUTPUT_REGISTER_COUNT,
+ "Unexpected D3D11 constant value.");
+
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return D3D11_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel);
+
+ case D3D_FEATURE_LEVEL_10_1:
+ return D3D10_1_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel);
+ case D3D_FEATURE_LEVEL_10_0:
+ return D3D10_VS_OUTPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel);
+
+ // Use Shader Model 2.X limits
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return 8 - GetReservedVertexOutputVectors(featureLevel);
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+int GetMaximumVertexTextureUnits(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT;
+
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT;
+
+ // Vertex textures not supported on D3D11 Feature Level 9 according to
+ // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx
+ // ID3D11DeviceContext::VSSetSamplers and ID3D11DeviceContext::VSSetShaderResources
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return 0;
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+int GetMaximumPixelUniformVectors(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_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return 1024; // D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT;
+
+ // From http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx
+ // ID3D11DeviceContext::PSSetConstantBuffers
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return 32 - d3d11_gl::GetReservedFragmentUniformVectors(featureLevel);
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+int GetMaximumPixelUniformBlocks(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT -
+ d3d11::RESERVED_CONSTANT_BUFFER_SLOT_COUNT;
+
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT -
+ d3d11::RESERVED_CONSTANT_BUFFER_SLOT_COUNT;
+
+ // Uniform blocks not supported on D3D11 Feature Level 9
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return 0;
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+int GetMaximumPixelInputVectors(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return D3D11_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel);
+
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return D3D10_PS_INPUT_REGISTER_COUNT - GetReservedVertexOutputVectors(featureLevel);
+
+ // Use Shader Model 2.X limits
+ case D3D_FEATURE_LEVEL_9_3:
+ return 8 - GetReservedVertexOutputVectors(featureLevel);
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return 8 - GetReservedVertexOutputVectors(featureLevel);
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+int GetMaximumPixelTextureUnits(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT;
+
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT;
+
+ // http://msdn.microsoft.com/en-us/library/windows/desktop/ff476149.aspx
+ // ID3D11DeviceContext::PSSetShaderResources
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return 16;
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+std::array<GLint, 3> GetMaxComputeWorkGroupCount(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return {{D3D11_CS_DISPATCH_MAX_THREAD_GROUPS_PER_DIMENSION,
+ D3D11_CS_DISPATCH_MAX_THREAD_GROUPS_PER_DIMENSION,
+ D3D11_CS_DISPATCH_MAX_THREAD_GROUPS_PER_DIMENSION}};
+ default:
+ return {{0, 0, 0}};
+ }
+}
+
+std::array<GLint, 3> GetMaxComputeWorkGroupSize(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return {{D3D11_CS_THREAD_GROUP_MAX_X, D3D11_CS_THREAD_GROUP_MAX_Y,
+ D3D11_CS_THREAD_GROUP_MAX_Z}};
+ default:
+ return {{0, 0, 0}};
+ }
+}
+
+int GetMaxComputeWorkGroupInvocations(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return D3D11_CS_THREAD_GROUP_MAX_THREADS_PER_GROUP;
+ default:
+ return 0;
+ }
+}
+
+int GetMaxComputeSharedMemorySize(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+ // In D3D11 the maximum total size of all variables with the groupshared storage class is
+ // 32kb.
+ // https://docs.microsoft.com/en-us/windows/desktop/direct3dhlsl/dx-graphics-hlsl-variable-syntax
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return 32768;
+ default:
+ return 0;
+ }
+}
+
+int GetMaximumComputeUniformVectors(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT;
+ default:
+ return 0;
+ }
+}
+
+int GetMaximumComputeUniformBlocks(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT -
+ d3d11::RESERVED_CONSTANT_BUFFER_SLOT_COUNT;
+ default:
+ return 0;
+ }
+}
+
+int GetMaximumComputeTextureUnits(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT;
+ default:
+ return 0;
+ }
+}
+
+void SetUAVRelatedResourceLimits(D3D_FEATURE_LEVEL featureLevel, gl::Caps *caps)
+{
+ ASSERT(caps);
+
+ GLuint reservedUAVsForAtomicCounterBuffers = 0u;
+
+ // For pixel shaders, the render targets and unordered access views share the same resource
+ // slots when being written out.
+ // https://msdn.microsoft.com/en-us/library/windows/desktop/ff476465(v=vs.85).aspx
+ GLuint maxNumRTVsAndUAVs = 0u;
+
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ // Currently we allocate 4 UAV slots for atomic counter buffers on feature level 11_1.
+ reservedUAVsForAtomicCounterBuffers = 4u;
+ maxNumRTVsAndUAVs = D3D11_1_UAV_SLOT_COUNT;
+ break;
+ case D3D_FEATURE_LEVEL_11_0:
+ // Currently we allocate 1 UAV slot for atomic counter buffers on feature level 11_0.
+ reservedUAVsForAtomicCounterBuffers = 1u;
+ maxNumRTVsAndUAVs = D3D11_PS_CS_UAV_REGISTER_COUNT;
+ break;
+ default:
+ return;
+ }
+
+ // Set limits on atomic counter buffers in fragment shaders and compute shaders.
+ caps->maxCombinedAtomicCounterBuffers = reservedUAVsForAtomicCounterBuffers;
+ caps->maxShaderAtomicCounterBuffers[gl::ShaderType::Compute] =
+ reservedUAVsForAtomicCounterBuffers;
+ caps->maxShaderAtomicCounterBuffers[gl::ShaderType::Fragment] =
+ reservedUAVsForAtomicCounterBuffers;
+ caps->maxAtomicCounterBufferBindings = reservedUAVsForAtomicCounterBuffers;
+
+ // Setting MAX_COMPUTE_ATOMIC_COUNTERS to a conservative number of 1024 * the number of UAV
+ // reserved for atomic counters. It could theoretically be set to max buffer size / 4 but that
+ // number could cause problems.
+ caps->maxCombinedAtomicCounters = reservedUAVsForAtomicCounterBuffers * 1024;
+ caps->maxShaderAtomicCounters[gl::ShaderType::Compute] = caps->maxCombinedAtomicCounters;
+
+ // See
+ // https://docs.microsoft.com/en-us/windows/desktop/direct3d11/overviews-direct3d-11-resources-limits
+ // Resource size (in MB) for any of the preceding resources is min(max(128,0.25f * (amount of
+ // dedicated VRAM)), 2048) MB. So we set it to 128MB to keep same with GL backend.
+ caps->maxShaderStorageBlockSize =
+ D3D11_REQ_RESOURCE_SIZE_IN_MEGABYTES_EXPRESSION_A_TERM * 1024 * 1024;
+
+ // Allocate the remaining slots for images and shader storage blocks.
+ // The maximum number of fragment shader outputs depends on the current context version, so we
+ // will not set it here. See comments in Context11::initialize().
+ caps->maxCombinedShaderOutputResources =
+ maxNumRTVsAndUAVs - reservedUAVsForAtomicCounterBuffers;
+
+ // Set limits on images and shader storage blocks in fragment shaders and compute shaders.
+ caps->maxCombinedShaderStorageBlocks = caps->maxCombinedShaderOutputResources;
+ caps->maxShaderStorageBlocks[gl::ShaderType::Compute] = caps->maxCombinedShaderOutputResources;
+ caps->maxShaderStorageBlocks[gl::ShaderType::Fragment] = caps->maxCombinedShaderOutputResources;
+ caps->maxShaderStorageBufferBindings = caps->maxCombinedShaderOutputResources;
+
+ caps->maxImageUnits = caps->maxCombinedShaderOutputResources;
+ caps->maxCombinedImageUniforms = caps->maxCombinedShaderOutputResources;
+ caps->maxShaderImageUniforms[gl::ShaderType::Compute] = caps->maxCombinedShaderOutputResources;
+ caps->maxShaderImageUniforms[gl::ShaderType::Fragment] = caps->maxCombinedShaderOutputResources;
+
+ // On feature level 11_1, UAVs are also available in vertex shaders and geometry shaders.
+ if (featureLevel == D3D_FEATURE_LEVEL_11_1)
+ {
+ caps->maxShaderAtomicCounterBuffers[gl::ShaderType::Vertex] =
+ caps->maxCombinedAtomicCounterBuffers;
+ caps->maxShaderAtomicCounterBuffers[gl::ShaderType::Geometry] =
+ caps->maxCombinedAtomicCounterBuffers;
+
+ caps->maxShaderImageUniforms[gl::ShaderType::Vertex] =
+ caps->maxCombinedShaderOutputResources;
+ caps->maxShaderStorageBlocks[gl::ShaderType::Vertex] =
+ caps->maxCombinedShaderOutputResources;
+ caps->maxShaderImageUniforms[gl::ShaderType::Geometry] =
+ caps->maxCombinedShaderOutputResources;
+ caps->maxShaderStorageBlocks[gl::ShaderType::Geometry] =
+ caps->maxCombinedShaderOutputResources;
+ }
+}
+
+int GetMinimumTexelOffset(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE;
+
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return D3D10_COMMONSHADER_TEXEL_OFFSET_MAX_NEGATIVE;
+
+ // Sampling functions with offsets are not available below shader model 4.0.
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return 0;
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+int GetMaximumTexelOffset(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE;
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return D3D11_COMMONSHADER_TEXEL_OFFSET_MAX_POSITIVE;
+
+ // Sampling functions with offsets are not available below shader model 4.0.
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return 0;
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+int GetMinimumTextureGatherOffset(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+ // https://docs.microsoft.com/en-us/windows/desktop/direct3dhlsl/gather4-po--sm5---asm-
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return -32;
+
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return 0;
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+int GetMaximumTextureGatherOffset(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+ // https://docs.microsoft.com/en-us/windows/desktop/direct3dhlsl/gather4-po--sm5---asm-
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return 31;
+
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return 0;
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+size_t GetMaximumConstantBufferSize(D3D_FEATURE_LEVEL featureLevel)
+{
+ // Returns a size_t despite the limit being a GLuint64 because size_t is the maximum
+ // size of
+ // any buffer that could be allocated.
+
+ const size_t bytesPerComponent = 4 * sizeof(float);
+
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * bytesPerComponent;
+
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * bytesPerComponent;
+
+ // Limits from http://msdn.microsoft.com/en-us/library/windows/desktop/ff476501.aspx
+ // remarks section
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return 4096 * bytesPerComponent;
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+int GetMaximumStreamOutputBuffers(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return D3D11_SO_BUFFER_SLOT_COUNT;
+
+ case D3D_FEATURE_LEVEL_10_1:
+ return D3D10_1_SO_BUFFER_SLOT_COUNT;
+ case D3D_FEATURE_LEVEL_10_0:
+ return D3D10_SO_BUFFER_SLOT_COUNT;
+
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return 0;
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+int GetMaximumStreamOutputInterleavedComponents(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return GetMaximumVertexOutputVectors(featureLevel) * 4;
+
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return 0;
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+int GetMaximumStreamOutputSeparateComponents(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return GetMaximumStreamOutputInterleavedComponents(featureLevel) /
+ GetMaximumStreamOutputBuffers(featureLevel);
+
+ // D3D 10 and 10.1 only allow one output per output slot if an output slot other
+ // than zero is used.
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return 4;
+
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return 0;
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+int GetMaximumRenderToBufferWindowSize(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return D3D11_REQ_RENDER_TO_BUFFER_WINDOW_WIDTH;
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return D3D10_REQ_RENDER_TO_BUFFER_WINDOW_WIDTH;
+
+ // REQ_RENDER_TO_BUFFER_WINDOW_WIDTH not supported on D3D11 Feature Level 9,
+ // use the maximum texture sizes
+ case D3D_FEATURE_LEVEL_9_3:
+ return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION;
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION;
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+IntelDriverVersion GetIntelDriverVersion(const Optional<LARGE_INTEGER> driverVersion)
+{
+ if (!driverVersion.valid())
+ return IntelDriverVersion(0);
+
+ DWORD lowPart = driverVersion.value().LowPart;
+ return IntelDriverVersion(HIWORD(lowPart) * 10000 + LOWORD(lowPart));
+}
+
+} // anonymous namespace
+
+unsigned int GetReservedVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return 0;
+
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return 3; // dx_ViewAdjust, dx_ViewCoords and dx_ViewScale
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+unsigned int GetReservedFragmentUniformVectors(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return 0;
+
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return 4; // dx_ViewCoords, dx_DepthFront, dx_DepthRange, dx_FragCoordOffset
+
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+gl::Version GetMaximumClientVersion(const Renderer11DeviceCaps &caps)
+{
+ switch (caps.featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return gl::Version(3, 1);
+ case D3D_FEATURE_LEVEL_10_1:
+ return gl::Version(3, 0);
+
+ case D3D_FEATURE_LEVEL_10_0:
+ if (caps.allowES3OnFL10_0)
+ {
+ return gl::Version(3, 0);
+ }
+ else
+ {
+ return gl::Version(2, 0);
+ }
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return gl::Version(2, 0);
+
+ default:
+ UNREACHABLE();
+ return gl::Version(0, 0);
+ }
+}
+
+D3D_FEATURE_LEVEL GetMinimumFeatureLevelForES31()
+{
+ return kMinimumFeatureLevelForES31;
+}
+
+unsigned int GetMaxViewportAndScissorRectanglesPerPipeline(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE;
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return 1;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+bool IsMultiviewSupported(D3D_FEATURE_LEVEL featureLevel)
+{
+ // The ANGLE_multiview extension can always be supported in D3D11 through geometry shaders.
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ return true;
+ default:
+ return false;
+ }
+}
+
+int GetMaxSampleMaskWords(D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+ // D3D10+ only allows 1 sample mask.
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return 1;
+ case D3D_FEATURE_LEVEL_9_3:
+ case D3D_FEATURE_LEVEL_9_2:
+ case D3D_FEATURE_LEVEL_9_1:
+ return 0;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+bool HasTextureBufferSupport(ID3D11Device *device, const Renderer11DeviceCaps &renderer11DeviceCaps)
+{
+ if (renderer11DeviceCaps.featureLevel < D3D_FEATURE_LEVEL_11_0)
+ return false;
+
+ if (!renderer11DeviceCaps.supportsTypedUAVLoadAdditionalFormats)
+ return false;
+
+ // https://docs.microsoft.com/en-us/windows/win32/direct3d12/typed-unordered-access-view-loads
+ // we don't need to check the typed store. from the spec,
+ // https://microsoft.github.io/DirectX-Specs/d3d/archive/D3D11_3_FunctionalSpec.htm#FormatList
+ // all the following format support typed stored.
+ // According to spec,
+ // https://www.khronos.org/registry/OpenGL-Refpages/es3/html/glBindImageTexture.xhtml the
+ // required image unit format are GL_RGBA32F, GL_RGBA32UI, GL_RGBA32I, GL_RGBA16F, GL_RGBA16UI,
+ // GL_RGBA16I, GL_RGBA8, GL_RGBAUI, GL_RGBA8I, GL_RGBA8_SNORM, GL_R32F, GL_R32UI, GL_R32I,
+ const std::array<DXGI_FORMAT, 2> &optionalFormats = {
+ DXGI_FORMAT_R32G32B32A32_FLOAT, // test for GL_RGBA32(UIF), GL_RGBA16(UIF),
+ // GL_RGBA8(UIUnorm)
+ DXGI_FORMAT_R8G8B8A8_SNORM, // test for GL_RGBA8_SNORM,
+ };
+
+ for (DXGI_FORMAT dxgiFormat : optionalFormats)
+ {
+ D3D11_FEATURE_DATA_FORMAT_SUPPORT FormatSupport = {dxgiFormat, 0};
+ if (!SUCCEEDED(device->CheckFeatureSupport(D3D11_FEATURE_FORMAT_SUPPORT, &FormatSupport,
+ sizeof(FormatSupport))))
+ {
+ WARN() << "Error checking typed load support for format 0x" << std::hex << dxgiFormat;
+ return false;
+ }
+ if ((FormatSupport.OutFormatSupport & D3D11_FORMAT_SUPPORT2_UAV_TYPED_LOAD) == 0)
+ return false;
+ }
+ return true;
+}
+
+void GenerateCaps(ID3D11Device *device,
+ ID3D11DeviceContext *deviceContext,
+ const Renderer11DeviceCaps &renderer11DeviceCaps,
+ const angle::FeaturesD3D &features,
+ const char *description,
+ gl::Caps *caps,
+ gl::TextureCapsMap *textureCapsMap,
+ gl::Extensions *extensions,
+ gl::Limitations *limitations)
+{
+ D3D_FEATURE_LEVEL featureLevel = renderer11DeviceCaps.featureLevel;
+ const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats();
+ for (GLenum internalFormat : allFormats)
+ {
+ gl::TextureCaps textureCaps =
+ GenerateTextureFormatCaps(GetMaximumClientVersion(renderer11DeviceCaps), internalFormat,
+ device, renderer11DeviceCaps);
+ textureCapsMap->insert(internalFormat, textureCaps);
+ }
+
+ // GL core feature limits
+ // Reserve MAX_UINT for D3D11's primitive restart.
+ caps->maxElementIndex = static_cast<GLint64>(std::numeric_limits<unsigned int>::max() - 1);
+ caps->max3DTextureSize = GetMaximum3DTextureSize(featureLevel);
+ caps->max2DTextureSize = GetMaximum2DTextureSize(featureLevel);
+ caps->maxCubeMapTextureSize = GetMaximumCubeMapTextureSize(featureLevel);
+ caps->maxArrayTextureLayers = GetMaximum2DTextureArraySize(featureLevel);
+
+ // Unimplemented, set to minimum required
+ caps->maxLODBias = 2.0f;
+
+ // No specific limits on render target size, maximum 2D texture size is equivalent
+ caps->maxRenderbufferSize = caps->max2DTextureSize;
+
+ // Maximum draw buffers and color attachments are the same, max color attachments could
+ // eventually be increased to 16
+ caps->maxDrawBuffers = GetMaximumSimultaneousRenderTargets(featureLevel);
+ caps->maxColorAttachments = GetMaximumSimultaneousRenderTargets(featureLevel);
+
+ // D3D11 has the same limit for viewport width and height
+ caps->maxViewportWidth = GetMaximumViewportSize(featureLevel);
+ caps->maxViewportHeight = caps->maxViewportWidth;
+
+ // Choose a reasonable maximum, enforced in the shader.
+ caps->minAliasedPointSize = 1.0f;
+ caps->maxAliasedPointSize = 1024.0f;
+
+ // Wide lines not supported
+ caps->minAliasedLineWidth = 1.0f;
+ caps->maxAliasedLineWidth = 1.0f;
+
+ // Primitive count limits
+ caps->maxElementsIndices = GetMaximumDrawIndexedIndexCount(featureLevel);
+ caps->maxElementsVertices = GetMaximumDrawVertexCount(featureLevel);
+
+ // Program and shader binary formats (no supported shader binary formats)
+ caps->programBinaryFormats.push_back(GL_PROGRAM_BINARY_ANGLE);
+
+ caps->vertexHighpFloat.setIEEEFloat();
+ caps->vertexMediumpFloat.setIEEEFloat();
+ caps->vertexLowpFloat.setIEEEFloat();
+ caps->fragmentHighpFloat.setIEEEFloat();
+ caps->fragmentMediumpFloat.setIEEEFloat();
+ caps->fragmentLowpFloat.setIEEEFloat();
+
+ // 32-bit integers are natively supported
+ caps->vertexHighpInt.setTwosComplementInt(32);
+ caps->vertexMediumpInt.setTwosComplementInt(32);
+ caps->vertexLowpInt.setTwosComplementInt(32);
+ caps->fragmentHighpInt.setTwosComplementInt(32);
+ caps->fragmentMediumpInt.setTwosComplementInt(32);
+ caps->fragmentLowpInt.setTwosComplementInt(32);
+
+ // We do not wait for server fence objects internally, so report a max timeout of zero.
+ caps->maxServerWaitTimeout = 0;
+
+ // Vertex shader limits
+ caps->maxVertexAttributes = GetMaximumVertexInputSlots(featureLevel);
+ caps->maxVertexUniformVectors = GetMaximumVertexUniformVectors(featureLevel);
+ if (features.skipVSConstantRegisterZero.enabled)
+ {
+ caps->maxVertexUniformVectors -= 1;
+ }
+ caps->maxShaderUniformComponents[gl::ShaderType::Vertex] = caps->maxVertexUniformVectors * 4;
+ caps->maxShaderUniformBlocks[gl::ShaderType::Vertex] =
+ GetMaximumVertexUniformBlocks(featureLevel);
+ caps->maxVertexOutputComponents = GetMaximumVertexOutputVectors(featureLevel) * 4;
+ caps->maxShaderTextureImageUnits[gl::ShaderType::Vertex] =
+ GetMaximumVertexTextureUnits(featureLevel);
+
+ // Vertex Attribute Bindings are emulated on D3D11.
+ caps->maxVertexAttribBindings = caps->maxVertexAttributes;
+ // Experimental testing confirmed there is no explicit limit on maximum buffer offset in D3D11.
+ caps->maxVertexAttribRelativeOffset = std::numeric_limits<GLint>::max();
+ // Experimental testing confirmed 2048 is the maximum stride that D3D11 can support on all
+ // platforms.
+ caps->maxVertexAttribStride = 2048;
+
+ // Fragment shader limits
+ caps->maxFragmentUniformVectors = GetMaximumPixelUniformVectors(featureLevel);
+ caps->maxShaderUniformComponents[gl::ShaderType::Fragment] =
+ caps->maxFragmentUniformVectors * 4;
+ caps->maxShaderUniformBlocks[gl::ShaderType::Fragment] =
+ GetMaximumPixelUniformBlocks(featureLevel);
+ caps->maxFragmentInputComponents = GetMaximumPixelInputVectors(featureLevel) * 4;
+ caps->maxShaderTextureImageUnits[gl::ShaderType::Fragment] =
+ GetMaximumPixelTextureUnits(featureLevel);
+ caps->minProgramTexelOffset = GetMinimumTexelOffset(featureLevel);
+ caps->maxProgramTexelOffset = GetMaximumTexelOffset(featureLevel);
+
+ // Compute shader limits
+ caps->maxComputeWorkGroupCount = GetMaxComputeWorkGroupCount(featureLevel);
+ caps->maxComputeWorkGroupSize = GetMaxComputeWorkGroupSize(featureLevel);
+ caps->maxComputeWorkGroupInvocations = GetMaxComputeWorkGroupInvocations(featureLevel);
+ caps->maxComputeSharedMemorySize = GetMaxComputeSharedMemorySize(featureLevel);
+ caps->maxShaderUniformComponents[gl::ShaderType::Compute] =
+ GetMaximumComputeUniformVectors(featureLevel) * 4;
+ caps->maxShaderUniformBlocks[gl::ShaderType::Compute] =
+ GetMaximumComputeUniformBlocks(featureLevel);
+ caps->maxShaderTextureImageUnits[gl::ShaderType::Compute] =
+ GetMaximumComputeTextureUnits(featureLevel);
+
+ SetUAVRelatedResourceLimits(featureLevel, caps);
+
+ // Aggregate shader limits
+ caps->maxUniformBufferBindings = caps->maxShaderUniformBlocks[gl::ShaderType::Vertex] +
+ caps->maxShaderUniformBlocks[gl::ShaderType::Fragment];
+ caps->maxUniformBlockSize = static_cast<GLuint64>(GetMaximumConstantBufferSize(featureLevel));
+
+ // TODO(oetuaho): Get a more accurate limit. For now using the minimum requirement for GLES 3.1.
+ caps->maxUniformLocations = 1024;
+
+ // With DirectX 11.1, constant buffer offset and size must be a multiple of 16 constants of 16
+ // bytes each.
+ // https://msdn.microsoft.com/en-us/library/windows/desktop/hh404649%28v=vs.85%29.aspx
+ // With DirectX 11.0, we emulate UBO offsets using copies of ranges of the UBO however
+ // we still keep the same alignment as 11.1 for consistency.
+ caps->uniformBufferOffsetAlignment = 256;
+
+ caps->maxCombinedUniformBlocks = caps->maxShaderUniformBlocks[gl::ShaderType::Vertex] +
+ caps->maxShaderUniformBlocks[gl::ShaderType::Fragment];
+
+ // A shader storage block will be translated to a structure in HLSL. So We reference the HLSL
+ // structure packing rules
+ // https://msdn.microsoft.com/en-us/library/windows/desktop/bb509632(v=vs.85).aspx. The
+ // resulting size of any structure will always be evenly divisible by sizeof(four-component
+ // vector).
+ caps->shaderStorageBufferOffsetAlignment = 16;
+
+ for (gl::ShaderType shaderType : gl::AllShaderTypes())
+ {
+ caps->maxCombinedShaderUniformComponents[shaderType] =
+ static_cast<GLint64>(caps->maxShaderUniformBlocks[shaderType]) *
+ static_cast<GLint64>(caps->maxUniformBlockSize / 4) +
+ static_cast<GLint64>(caps->maxShaderUniformComponents[shaderType]);
+ }
+
+ caps->maxVaryingComponents = GetMaximumVertexOutputVectors(featureLevel) * 4;
+ caps->maxVaryingVectors = GetMaximumVertexOutputVectors(featureLevel);
+ caps->maxCombinedTextureImageUnits = caps->maxShaderTextureImageUnits[gl::ShaderType::Vertex] +
+ caps->maxShaderTextureImageUnits[gl::ShaderType::Fragment];
+
+ // Transform feedback limits
+ caps->maxTransformFeedbackInterleavedComponents =
+ GetMaximumStreamOutputInterleavedComponents(featureLevel);
+ caps->maxTransformFeedbackSeparateAttributes = GetMaximumStreamOutputBuffers(featureLevel);
+ caps->maxTransformFeedbackSeparateComponents =
+ GetMaximumStreamOutputSeparateComponents(featureLevel);
+
+ // Defer the computation of multisample limits to Context::updateCaps() where max*Samples values
+ // are determined according to available sample counts for each individual format.
+ caps->maxSamples = std::numeric_limits<GLint>::max();
+ caps->maxColorTextureSamples = std::numeric_limits<GLint>::max();
+ caps->maxDepthTextureSamples = std::numeric_limits<GLint>::max();
+ caps->maxIntegerSamples = std::numeric_limits<GLint>::max();
+
+ // Sample mask words limits
+ caps->maxSampleMaskWords = GetMaxSampleMaskWords(featureLevel);
+
+ // Framebuffer limits
+ caps->maxFramebufferSamples = std::numeric_limits<GLint>::max();
+ caps->maxFramebufferWidth = GetMaximumRenderToBufferWindowSize(featureLevel);
+ caps->maxFramebufferHeight = caps->maxFramebufferWidth;
+
+ // Texture gather offset limits
+ caps->minProgramTextureGatherOffset = GetMinimumTextureGatherOffset(featureLevel);
+ caps->maxProgramTextureGatherOffset = GetMaximumTextureGatherOffset(featureLevel);
+
+ caps->maxTextureAnisotropy = GetMaximumAnisotropy(featureLevel);
+ caps->queryCounterBitsTimeElapsed = 64;
+ caps->queryCounterBitsTimestamp = 0; // Timestamps cannot be supported due to D3D11 limitations
+ caps->maxDualSourceDrawBuffers = 1;
+
+ // GL extension support
+ extensions->setTextureExtensionSupport(*textureCapsMap);
+
+ // Explicitly disable GL_OES_compressed_ETC1_RGB8_texture because it's emulated and never
+ // becomes core. WebGL doesn't want to expose it unless there is native support.
+ extensions->compressedETC1RGB8TextureOES = false;
+ extensions->compressedETC1RGB8SubTextureEXT = false;
+
+ extensions->elementIndexUintOES = true;
+ extensions->getProgramBinaryOES = true;
+ extensions->rgb8Rgba8OES = true;
+ extensions->readFormatBgraEXT = true;
+ extensions->pixelBufferObjectNV = true;
+ extensions->mapbufferOES = true;
+ extensions->mapBufferRangeEXT = true;
+ extensions->textureNpotOES = GetNPOTTextureSupport(featureLevel);
+ extensions->drawBuffersEXT = GetMaximumSimultaneousRenderTargets(featureLevel) > 1;
+ extensions->drawBuffersIndexedEXT =
+ (renderer11DeviceCaps.featureLevel >= D3D_FEATURE_LEVEL_10_1);
+ extensions->drawBuffersIndexedOES = extensions->drawBuffersIndexedEXT;
+ extensions->textureStorageEXT = true;
+ extensions->textureFilterAnisotropicEXT = true;
+ extensions->occlusionQueryBooleanEXT = GetOcclusionQuerySupport(featureLevel);
+ extensions->fenceNV = GetEventQuerySupport(featureLevel);
+ extensions->disjointTimerQueryEXT = true;
+ extensions->robustnessEXT = true;
+ // Direct3D guarantees to return zero for any resource that is accessed out of bounds.
+ // See https://msdn.microsoft.com/en-us/library/windows/desktop/ff476332(v=vs.85).aspx
+ // and https://msdn.microsoft.com/en-us/library/windows/desktop/ff476900(v=vs.85).aspx
+ extensions->robustBufferAccessBehaviorKHR = true;
+ extensions->blendMinmaxEXT = true;
+ // https://docs.microsoft.com/en-us/windows/desktop/direct3ddxgi/format-support-for-direct3d-11-0-feature-level-hardware
+ extensions->floatBlendEXT = true;
+ extensions->framebufferBlitANGLE = GetFramebufferBlitSupport(featureLevel);
+ extensions->framebufferBlitNV = extensions->framebufferBlitANGLE;
+ extensions->framebufferMultisampleANGLE = GetFramebufferMultisampleSupport(featureLevel);
+ extensions->instancedArraysANGLE = GetInstancingSupport(featureLevel);
+ extensions->instancedArraysEXT = GetInstancingSupport(featureLevel);
+ extensions->packReverseRowOrderANGLE = true;
+ extensions->standardDerivativesOES = GetDerivativeInstructionSupport(featureLevel);
+ extensions->shaderTextureLodEXT = GetShaderTextureLODSupport(featureLevel);
+ extensions->fragDepthEXT = true;
+ extensions->multiviewOVR = IsMultiviewSupported(featureLevel);
+ extensions->multiview2OVR = IsMultiviewSupported(featureLevel);
+ if (extensions->multiviewOVR || extensions->multiview2OVR)
+ {
+ caps->maxViews = std::min(static_cast<GLuint>(GetMaximum2DTextureArraySize(featureLevel)),
+ GetMaxViewportAndScissorRectanglesPerPipeline(featureLevel));
+ }
+ extensions->textureUsageANGLE = true; // This could be false since it has no effect in D3D11
+ extensions->discardFramebufferEXT = true;
+ extensions->translatedShaderSourceANGLE = true;
+ extensions->fboRenderMipmapOES = true;
+ extensions->debugMarkerEXT = true;
+ extensions->EGLImageOES = true;
+ extensions->EGLImageExternalOES = true;
+ extensions->EGLImageExternalWrapModesEXT = true;
+ extensions->EGLImageExternalEssl3OES = true;
+ extensions->EGLStreamConsumerExternalNV = true;
+ extensions->unpackSubimageEXT = true;
+ extensions->packSubimageNV = true;
+ extensions->lossyEtcDecodeANGLE = true;
+ extensions->syncQueryCHROMIUM = GetEventQuerySupport(featureLevel);
+ extensions->copyTextureCHROMIUM = true;
+ extensions->copyCompressedTextureCHROMIUM = true;
+ extensions->textureStorageMultisample2dArrayOES = true;
+ extensions->multiviewMultisampleANGLE =
+ ((extensions->multiviewOVR || extensions->multiview2OVR) &&
+ extensions->textureStorageMultisample2dArrayOES);
+ extensions->copyTexture3dANGLE = true;
+ extensions->textureBorderClampOES = true;
+ extensions->multiDrawIndirectEXT = true;
+ extensions->textureMultisampleANGLE = true;
+ extensions->provokingVertexANGLE = true;
+ extensions->blendFuncExtendedEXT = true;
+ // http://anglebug.com/4926
+ extensions->texture3DOES = false;
+ extensions->baseInstanceEXT = true;
+ extensions->baseVertexBaseInstanceANGLE = true;
+ extensions->baseVertexBaseInstanceShaderBuiltinANGLE = true;
+ extensions->drawElementsBaseVertexOES = true;
+ extensions->drawElementsBaseVertexEXT = true;
+ if (!strstr(description, "Adreno"))
+ {
+ extensions->multisampledRenderToTextureEXT = true;
+ }
+ extensions->videoTextureWEBGL = true;
+
+ // D3D11 cannot support reading depth texture as a luminance texture.
+ // It treats it as a red-channel-only texture.
+ extensions->depthTextureOES = false;
+
+ // readPixels on depth & stencil not working with D3D11 backend.
+ extensions->readDepthNV = false;
+ extensions->readStencilNV = false;
+ extensions->depthBufferFloat2NV = false;
+
+ // GL_EXT_clip_control
+ extensions->clipControlEXT = (renderer11DeviceCaps.featureLevel >= D3D_FEATURE_LEVEL_9_3);
+
+ // GL_KHR_parallel_shader_compile
+ extensions->parallelShaderCompileKHR = true;
+
+ // GL_EXT_texture_buffer
+ extensions->textureBufferEXT = HasTextureBufferSupport(device, renderer11DeviceCaps);
+
+ // GL_OES_texture_buffer
+ extensions->textureBufferOES = extensions->textureBufferEXT;
+
+ // ANGLE_shader_pixel_local_storage -- fragment shader UAVs appear in D3D 11.0.
+ extensions->shaderPixelLocalStorageANGLE = (featureLevel >= D3D_FEATURE_LEVEL_11_0);
+ extensions->shaderPixelLocalStorageCoherentANGLE =
+ renderer11DeviceCaps.supportsRasterizerOrderViews;
+
+ // 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.
+ limitations->noFrontFacingSupport =
+ (renderer11DeviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3);
+
+ // D3D11 Feature Level 9_3 doesn't support alpha-to-coverage
+ limitations->noSampleAlphaToCoverageSupport =
+ (renderer11DeviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3);
+
+ // D3D11 Feature Levels 9_3 and below do not support non-constant loop indexing and require
+ // additional
+ // pre-validation of the shader at compile time to produce a better error message.
+ limitations->shadersRequireIndexedLoopValidation =
+ (renderer11DeviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3);
+
+ // D3D11 has no concept of separate masks and refs for front and back faces in the depth stencil
+ // state.
+ limitations->noSeparateStencilRefsAndMasks = true;
+
+ // D3D11 cannot support constant color and alpha blend funcs together
+ limitations->noSimultaneousConstantColorAndAlphaBlendFunc = true;
+
+ // D3D11 does not support multiple transform feedback outputs writing to the same buffer.
+ limitations->noDoubleBoundTransformFeedbackBuffers = true;
+
+ // D3D11 does not support vertex attribute aliasing
+ limitations->noVertexAttributeAliasing = true;
+
+ // D3D11 does not support compressed textures where the base mip level is not a multiple of 4
+ limitations->compressedBaseMipLevelMultipleOfFour = true;
+
+ if (extensions->textureBufferAny())
+ {
+ caps->maxTextureBufferSize = 1 << D3D11_REQ_BUFFER_RESOURCE_TEXEL_COUNT_2_TO_EXP;
+ // this maybe touble for RGB32 format.
+ caps->textureBufferOffsetAlignment = 16;
+ }
+
+#ifdef ANGLE_ENABLE_WINDOWS_UWP
+ // Setting a non-zero divisor on attribute zero doesn't work on certain Windows Phone 8-era
+ // devices. We should prevent developers from doing this on ALL Windows Store devices. This will
+ // maintain consistency across all Windows devices. We allow non-zero divisors on attribute zero
+ // if the Client Version >= 3, since devices affected by this issue don't support ES3+.
+ limitations->attributeZeroRequiresZeroDivisorInEXT = true;
+#endif
+}
+
+} // namespace d3d11_gl
+
+namespace gl_d3d11
+{
+
+D3D11_BLEND ConvertBlendFunc(GLenum glBlend, bool isAlpha)
+{
+ D3D11_BLEND d3dBlend = D3D11_BLEND_ZERO;
+
+ switch (glBlend)
+ {
+ case GL_ZERO:
+ d3dBlend = D3D11_BLEND_ZERO;
+ break;
+ case GL_ONE:
+ d3dBlend = D3D11_BLEND_ONE;
+ break;
+ case GL_SRC_COLOR:
+ d3dBlend = (isAlpha ? D3D11_BLEND_SRC_ALPHA : D3D11_BLEND_SRC_COLOR);
+ break;
+ case GL_ONE_MINUS_SRC_COLOR:
+ d3dBlend = (isAlpha ? D3D11_BLEND_INV_SRC_ALPHA : D3D11_BLEND_INV_SRC_COLOR);
+ break;
+ case GL_DST_COLOR:
+ d3dBlend = (isAlpha ? D3D11_BLEND_DEST_ALPHA : D3D11_BLEND_DEST_COLOR);
+ break;
+ case GL_ONE_MINUS_DST_COLOR:
+ d3dBlend = (isAlpha ? D3D11_BLEND_INV_DEST_ALPHA : D3D11_BLEND_INV_DEST_COLOR);
+ break;
+ case GL_SRC_ALPHA:
+ d3dBlend = D3D11_BLEND_SRC_ALPHA;
+ break;
+ case GL_ONE_MINUS_SRC_ALPHA:
+ d3dBlend = D3D11_BLEND_INV_SRC_ALPHA;
+ break;
+ case GL_DST_ALPHA:
+ d3dBlend = D3D11_BLEND_DEST_ALPHA;
+ break;
+ case GL_ONE_MINUS_DST_ALPHA:
+ d3dBlend = D3D11_BLEND_INV_DEST_ALPHA;
+ break;
+ case GL_CONSTANT_COLOR:
+ d3dBlend = D3D11_BLEND_BLEND_FACTOR;
+ break;
+ case GL_ONE_MINUS_CONSTANT_COLOR:
+ d3dBlend = D3D11_BLEND_INV_BLEND_FACTOR;
+ break;
+ case GL_CONSTANT_ALPHA:
+ d3dBlend = D3D11_BLEND_BLEND_FACTOR;
+ break;
+ case GL_ONE_MINUS_CONSTANT_ALPHA:
+ d3dBlend = D3D11_BLEND_INV_BLEND_FACTOR;
+ break;
+ case GL_SRC_ALPHA_SATURATE:
+ d3dBlend = D3D11_BLEND_SRC_ALPHA_SAT;
+ break;
+ case GL_SRC1_COLOR_EXT:
+ d3dBlend = (isAlpha ? D3D11_BLEND_SRC1_ALPHA : D3D11_BLEND_SRC1_COLOR);
+ break;
+ case GL_SRC1_ALPHA_EXT:
+ d3dBlend = D3D11_BLEND_SRC1_ALPHA;
+ break;
+ case GL_ONE_MINUS_SRC1_COLOR_EXT:
+ d3dBlend = (isAlpha ? D3D11_BLEND_INV_SRC1_ALPHA : D3D11_BLEND_INV_SRC1_COLOR);
+ break;
+ case GL_ONE_MINUS_SRC1_ALPHA_EXT:
+ d3dBlend = D3D11_BLEND_INV_SRC1_ALPHA;
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ return d3dBlend;
+}
+
+D3D11_BLEND_OP ConvertBlendOp(GLenum glBlendOp)
+{
+ D3D11_BLEND_OP d3dBlendOp = D3D11_BLEND_OP_ADD;
+
+ switch (glBlendOp)
+ {
+ case GL_FUNC_ADD:
+ d3dBlendOp = D3D11_BLEND_OP_ADD;
+ break;
+ case GL_FUNC_SUBTRACT:
+ d3dBlendOp = D3D11_BLEND_OP_SUBTRACT;
+ break;
+ case GL_FUNC_REVERSE_SUBTRACT:
+ d3dBlendOp = D3D11_BLEND_OP_REV_SUBTRACT;
+ break;
+ case GL_MIN:
+ d3dBlendOp = D3D11_BLEND_OP_MIN;
+ break;
+ case GL_MAX:
+ d3dBlendOp = D3D11_BLEND_OP_MAX;
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ return d3dBlendOp;
+}
+
+UINT8 ConvertColorMask(bool red, bool green, bool blue, bool alpha)
+{
+ UINT8 mask = 0;
+ if (red)
+ {
+ mask |= D3D11_COLOR_WRITE_ENABLE_RED;
+ }
+ if (green)
+ {
+ mask |= D3D11_COLOR_WRITE_ENABLE_GREEN;
+ }
+ if (blue)
+ {
+ mask |= D3D11_COLOR_WRITE_ENABLE_BLUE;
+ }
+ if (alpha)
+ {
+ mask |= D3D11_COLOR_WRITE_ENABLE_ALPHA;
+ }
+ return mask;
+}
+
+D3D11_CULL_MODE ConvertCullMode(bool cullEnabled, gl::CullFaceMode cullMode)
+{
+ D3D11_CULL_MODE cull = D3D11_CULL_NONE;
+
+ if (cullEnabled)
+ {
+ switch (cullMode)
+ {
+ case gl::CullFaceMode::Front:
+ cull = D3D11_CULL_FRONT;
+ break;
+ case gl::CullFaceMode::Back:
+ cull = D3D11_CULL_BACK;
+ break;
+ case gl::CullFaceMode::FrontAndBack:
+ cull = D3D11_CULL_NONE;
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+ else
+ {
+ cull = D3D11_CULL_NONE;
+ }
+
+ return cull;
+}
+
+D3D11_COMPARISON_FUNC ConvertComparison(GLenum comparison)
+{
+ D3D11_COMPARISON_FUNC d3dComp = D3D11_COMPARISON_NEVER;
+ switch (comparison)
+ {
+ case GL_NEVER:
+ d3dComp = D3D11_COMPARISON_NEVER;
+ break;
+ case GL_ALWAYS:
+ d3dComp = D3D11_COMPARISON_ALWAYS;
+ break;
+ case GL_LESS:
+ d3dComp = D3D11_COMPARISON_LESS;
+ break;
+ case GL_LEQUAL:
+ d3dComp = D3D11_COMPARISON_LESS_EQUAL;
+ break;
+ case GL_EQUAL:
+ d3dComp = D3D11_COMPARISON_EQUAL;
+ break;
+ case GL_GREATER:
+ d3dComp = D3D11_COMPARISON_GREATER;
+ break;
+ case GL_GEQUAL:
+ d3dComp = D3D11_COMPARISON_GREATER_EQUAL;
+ break;
+ case GL_NOTEQUAL:
+ d3dComp = D3D11_COMPARISON_NOT_EQUAL;
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ return d3dComp;
+}
+
+D3D11_DEPTH_WRITE_MASK ConvertDepthMask(bool depthWriteEnabled)
+{
+ return depthWriteEnabled ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO;
+}
+
+UINT8 ConvertStencilMask(GLuint stencilmask)
+{
+ return static_cast<UINT8>(stencilmask);
+}
+
+D3D11_STENCIL_OP ConvertStencilOp(GLenum stencilOp)
+{
+ D3D11_STENCIL_OP d3dStencilOp = D3D11_STENCIL_OP_KEEP;
+
+ switch (stencilOp)
+ {
+ case GL_ZERO:
+ d3dStencilOp = D3D11_STENCIL_OP_ZERO;
+ break;
+ case GL_KEEP:
+ d3dStencilOp = D3D11_STENCIL_OP_KEEP;
+ break;
+ case GL_REPLACE:
+ d3dStencilOp = D3D11_STENCIL_OP_REPLACE;
+ break;
+ case GL_INCR:
+ d3dStencilOp = D3D11_STENCIL_OP_INCR_SAT;
+ break;
+ case GL_DECR:
+ d3dStencilOp = D3D11_STENCIL_OP_DECR_SAT;
+ break;
+ case GL_INVERT:
+ d3dStencilOp = D3D11_STENCIL_OP_INVERT;
+ break;
+ case GL_INCR_WRAP:
+ d3dStencilOp = D3D11_STENCIL_OP_INCR;
+ break;
+ case GL_DECR_WRAP:
+ d3dStencilOp = D3D11_STENCIL_OP_DECR;
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ return d3dStencilOp;
+}
+
+D3D11_FILTER ConvertFilter(GLenum minFilter,
+ GLenum magFilter,
+ float maxAnisotropy,
+ GLenum comparisonMode)
+{
+ bool comparison = comparisonMode != GL_NONE;
+
+ if (maxAnisotropy > 1.0f)
+ {
+ return D3D11_ENCODE_ANISOTROPIC_FILTER(static_cast<D3D11_COMPARISON_FUNC>(comparison));
+ }
+ else
+ {
+ D3D11_FILTER_TYPE dxMin = D3D11_FILTER_TYPE_POINT;
+ D3D11_FILTER_TYPE dxMip = D3D11_FILTER_TYPE_POINT;
+ switch (minFilter)
+ {
+ case GL_NEAREST:
+ dxMin = D3D11_FILTER_TYPE_POINT;
+ dxMip = D3D11_FILTER_TYPE_POINT;
+ break;
+ case GL_LINEAR:
+ dxMin = D3D11_FILTER_TYPE_LINEAR;
+ dxMip = D3D11_FILTER_TYPE_POINT;
+ break;
+ case GL_NEAREST_MIPMAP_NEAREST:
+ dxMin = D3D11_FILTER_TYPE_POINT;
+ dxMip = D3D11_FILTER_TYPE_POINT;
+ break;
+ case GL_LINEAR_MIPMAP_NEAREST:
+ dxMin = D3D11_FILTER_TYPE_LINEAR;
+ dxMip = D3D11_FILTER_TYPE_POINT;
+ break;
+ case GL_NEAREST_MIPMAP_LINEAR:
+ dxMin = D3D11_FILTER_TYPE_POINT;
+ dxMip = D3D11_FILTER_TYPE_LINEAR;
+ break;
+ case GL_LINEAR_MIPMAP_LINEAR:
+ dxMin = D3D11_FILTER_TYPE_LINEAR;
+ dxMip = D3D11_FILTER_TYPE_LINEAR;
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ D3D11_FILTER_TYPE dxMag = D3D11_FILTER_TYPE_POINT;
+ switch (magFilter)
+ {
+ case GL_NEAREST:
+ dxMag = D3D11_FILTER_TYPE_POINT;
+ break;
+ case GL_LINEAR:
+ dxMag = D3D11_FILTER_TYPE_LINEAR;
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ return D3D11_ENCODE_BASIC_FILTER(dxMin, dxMag, dxMip,
+ static_cast<D3D11_COMPARISON_FUNC>(comparison));
+ }
+}
+
+D3D11_TEXTURE_ADDRESS_MODE ConvertTextureWrap(GLenum wrap)
+{
+ switch (wrap)
+ {
+ case GL_REPEAT:
+ return D3D11_TEXTURE_ADDRESS_WRAP;
+ case GL_CLAMP_TO_EDGE:
+ return D3D11_TEXTURE_ADDRESS_CLAMP;
+ case GL_CLAMP_TO_BORDER:
+ return D3D11_TEXTURE_ADDRESS_BORDER;
+ case GL_MIRRORED_REPEAT:
+ return D3D11_TEXTURE_ADDRESS_MIRROR;
+ default:
+ UNREACHABLE();
+ }
+
+ return D3D11_TEXTURE_ADDRESS_WRAP;
+}
+
+UINT ConvertMaxAnisotropy(float maxAnisotropy, D3D_FEATURE_LEVEL featureLevel)
+{
+ return static_cast<UINT>(std::min(maxAnisotropy, d3d11_gl::GetMaximumAnisotropy(featureLevel)));
+}
+
+D3D11_QUERY ConvertQueryType(gl::QueryType type)
+{
+ switch (type)
+ {
+ case gl::QueryType::AnySamples:
+ case gl::QueryType::AnySamplesConservative:
+ return D3D11_QUERY_OCCLUSION;
+ case gl::QueryType::TransformFeedbackPrimitivesWritten:
+ return D3D11_QUERY_SO_STATISTICS;
+ case gl::QueryType::TimeElapsed:
+ // Two internal queries are also created for begin/end timestamps
+ return D3D11_QUERY_TIMESTAMP_DISJOINT;
+ case gl::QueryType::CommandsCompleted:
+ return D3D11_QUERY_EVENT;
+ default:
+ UNREACHABLE();
+ return D3D11_QUERY_EVENT;
+ }
+}
+
+// Get the D3D11 write mask covering all color channels of a given format
+UINT8 GetColorMask(const gl::InternalFormat &format)
+{
+ return ConvertColorMask(format.redBits > 0, format.greenBits > 0, format.blueBits > 0,
+ format.alphaBits > 0);
+}
+
+} // namespace gl_d3d11
+
+namespace d3d11
+{
+
+ANGLED3D11DeviceType GetDeviceType(ID3D11Device *device)
+{
+ // Note that this function returns an ANGLED3D11DeviceType rather than a D3D_DRIVER_TYPE value,
+ // since it is difficult to tell Software and Reference devices apart
+
+ IDXGIDevice *dxgiDevice = nullptr;
+ IDXGIAdapter *dxgiAdapter = nullptr;
+ IDXGIAdapter2 *dxgiAdapter2 = nullptr;
+
+ ANGLED3D11DeviceType retDeviceType = ANGLE_D3D11_DEVICE_TYPE_UNKNOWN;
+
+ HRESULT hr = device->QueryInterface(__uuidof(IDXGIDevice), (void **)&dxgiDevice);
+ if (SUCCEEDED(hr))
+ {
+ hr = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void **)&dxgiAdapter);
+ if (SUCCEEDED(hr))
+ {
+ std::wstring adapterString;
+ HRESULT adapter2hr =
+ dxgiAdapter->QueryInterface(__uuidof(dxgiAdapter2), (void **)&dxgiAdapter2);
+ if (SUCCEEDED(adapter2hr))
+ {
+ // On D3D_FEATURE_LEVEL_9_*, IDXGIAdapter::GetDesc returns "Software Adapter"
+ // for the description string. Try to use IDXGIAdapter2::GetDesc2 to get the
+ // actual hardware values if possible.
+ DXGI_ADAPTER_DESC2 adapterDesc2;
+ dxgiAdapter2->GetDesc2(&adapterDesc2);
+ adapterString = std::wstring(adapterDesc2.Description);
+ }
+ else
+ {
+ DXGI_ADAPTER_DESC adapterDesc;
+ dxgiAdapter->GetDesc(&adapterDesc);
+ adapterString = std::wstring(adapterDesc.Description);
+ }
+
+ // Both Reference and Software adapters will be 'Software Adapter'
+ const bool isSoftwareDevice =
+ (adapterString.find(std::wstring(L"Software Adapter")) != std::string::npos);
+ const bool isNullDevice = (adapterString == L"");
+ const bool isWARPDevice =
+ (adapterString.find(std::wstring(L"Basic Render")) != std::string::npos);
+
+ if (isSoftwareDevice || isNullDevice)
+ {
+ ASSERT(!isWARPDevice);
+ retDeviceType = ANGLE_D3D11_DEVICE_TYPE_SOFTWARE_REF_OR_NULL;
+ }
+ else if (isWARPDevice)
+ {
+ retDeviceType = ANGLE_D3D11_DEVICE_TYPE_WARP;
+ }
+ else
+ {
+ retDeviceType = ANGLE_D3D11_DEVICE_TYPE_HARDWARE;
+ }
+ }
+ }
+
+ SafeRelease(dxgiDevice);
+ SafeRelease(dxgiAdapter);
+ SafeRelease(dxgiAdapter2);
+
+ return retDeviceType;
+}
+
+void MakeValidSize(bool isImage,
+ DXGI_FORMAT format,
+ GLsizei *requestWidth,
+ GLsizei *requestHeight,
+ int *levelOffset)
+{
+ const DXGIFormatSize &dxgiFormatInfo = d3d11::GetDXGIFormatSizeInfo(format);
+ bool validFormat = format != DXGI_FORMAT_UNKNOWN;
+ bool validImage = isImage && validFormat;
+
+ int upsampleCount = 0;
+ // Don't expand the size of full textures that are at least (blockWidth x blockHeight) already.
+ if (validImage || *requestWidth < static_cast<GLsizei>(dxgiFormatInfo.blockWidth) ||
+ *requestHeight < static_cast<GLsizei>(dxgiFormatInfo.blockHeight))
+ {
+ while (*requestWidth % dxgiFormatInfo.blockWidth != 0 ||
+ *requestHeight % dxgiFormatInfo.blockHeight != 0)
+ {
+ *requestWidth <<= 1;
+ *requestHeight <<= 1;
+ upsampleCount++;
+ }
+ }
+ else if (validFormat)
+ {
+ if (*requestWidth % dxgiFormatInfo.blockWidth != 0)
+ {
+ *requestWidth = roundUp(*requestWidth, static_cast<GLsizei>(dxgiFormatInfo.blockWidth));
+ }
+
+ if (*requestHeight % dxgiFormatInfo.blockHeight != 0)
+ {
+ *requestHeight =
+ roundUp(*requestHeight, static_cast<GLsizei>(dxgiFormatInfo.blockHeight));
+ }
+ }
+
+ if (levelOffset)
+ {
+ *levelOffset = upsampleCount;
+ }
+}
+
+angle::Result GenerateInitialTextureData(
+ const gl::Context *context,
+ GLint internalFormat,
+ const Renderer11DeviceCaps &renderer11DeviceCaps,
+ GLuint width,
+ GLuint height,
+ GLuint depth,
+ GLuint mipLevels,
+ gl::TexLevelArray<D3D11_SUBRESOURCE_DATA> *outSubresourceData)
+{
+ const d3d11::Format &d3dFormatInfo = d3d11::Format::Get(internalFormat, renderer11DeviceCaps);
+ ASSERT(d3dFormatInfo.dataInitializerFunction != nullptr);
+
+ const d3d11::DXGIFormatSize &dxgiFormatInfo =
+ d3d11::GetDXGIFormatSizeInfo(d3dFormatInfo.texFormat);
+
+ using CheckedSize = angle::CheckedNumeric<size_t>;
+ CheckedSize rowPitch = CheckedSize(dxgiFormatInfo.pixelBytes) * CheckedSize(width);
+ CheckedSize depthPitch = rowPitch * CheckedSize(height);
+ CheckedSize maxImageSize = depthPitch * CheckedSize(depth);
+
+ Context11 *context11 = GetImplAs<Context11>(context);
+ ANGLE_CHECK_GL_ALLOC(context11, maxImageSize.IsValid());
+
+ angle::MemoryBuffer *scratchBuffer = nullptr;
+ ANGLE_CHECK_GL_ALLOC(context11,
+ context->getScratchBuffer(maxImageSize.ValueOrDie(), &scratchBuffer));
+
+ d3dFormatInfo.dataInitializerFunction(width, height, depth, scratchBuffer->data(),
+ rowPitch.ValueOrDie(), depthPitch.ValueOrDie());
+
+ for (unsigned int i = 0; i < mipLevels; i++)
+ {
+ unsigned int mipWidth = std::max(width >> i, 1U);
+ unsigned int mipHeight = std::max(height >> i, 1U);
+
+ using CheckedUINT = angle::CheckedNumeric<UINT>;
+ CheckedUINT mipRowPitch = CheckedUINT(dxgiFormatInfo.pixelBytes) * CheckedUINT(mipWidth);
+ CheckedUINT mipDepthPitch = mipRowPitch * CheckedUINT(mipHeight);
+
+ ANGLE_CHECK_GL_ALLOC(context11, mipRowPitch.IsValid() && mipDepthPitch.IsValid());
+
+ outSubresourceData->at(i).pSysMem = scratchBuffer->data();
+ outSubresourceData->at(i).SysMemPitch = mipRowPitch.ValueOrDie();
+ outSubresourceData->at(i).SysMemSlicePitch = mipDepthPitch.ValueOrDie();
+ }
+
+ return angle::Result::Continue;
+}
+
+UINT GetPrimitiveRestartIndex()
+{
+ return std::numeric_limits<UINT>::max();
+}
+
+void SetPositionTexCoordVertex(PositionTexCoordVertex *vertex, float x, float y, float u, float v)
+{
+ vertex->x = x;
+ vertex->y = y;
+ vertex->u = u;
+ vertex->v = v;
+}
+
+void SetPositionLayerTexCoord3DVertex(PositionLayerTexCoord3DVertex *vertex,
+ float x,
+ float y,
+ unsigned int layer,
+ float u,
+ float v,
+ float s)
+{
+ vertex->x = x;
+ vertex->y = y;
+ vertex->l = layer;
+ vertex->u = u;
+ vertex->v = v;
+ vertex->s = s;
+}
+
+BlendStateKey::BlendStateKey()
+{
+ memset(this, 0, sizeof(BlendStateKey));
+ blendStateExt = gl::BlendStateExt();
+}
+
+BlendStateKey::BlendStateKey(const BlendStateKey &other)
+{
+ memcpy(this, &other, sizeof(BlendStateKey));
+}
+
+bool operator==(const BlendStateKey &a, const BlendStateKey &b)
+{
+ return memcmp(&a, &b, sizeof(BlendStateKey)) == 0;
+}
+
+bool operator!=(const BlendStateKey &a, const BlendStateKey &b)
+{
+ return !(a == b);
+}
+
+RasterizerStateKey::RasterizerStateKey()
+{
+ memset(this, 0, sizeof(RasterizerStateKey));
+}
+
+bool operator==(const RasterizerStateKey &a, const RasterizerStateKey &b)
+{
+ return memcmp(&a, &b, sizeof(RasterizerStateKey)) == 0;
+}
+
+bool operator!=(const RasterizerStateKey &a, const RasterizerStateKey &b)
+{
+ return !(a == b);
+}
+
+HRESULT SetDebugName(ID3D11DeviceChild *resource,
+ const char *internalName,
+ const std::string *khrDebugName)
+{
+ // Prepend ANGLE to separate names from other components in the same process.
+ std::string d3dName = "ANGLE";
+ bool sendNameToD3D = false;
+ if (internalName && internalName[0] != '\0')
+ {
+ d3dName += std::string("_") + internalName;
+ sendNameToD3D = true;
+ }
+ if (khrDebugName && !khrDebugName->empty())
+ {
+ d3dName += std::string("_") + *khrDebugName;
+ sendNameToD3D = true;
+ }
+ // If both internalName and khrDebugName are empty, avoid sending the string to d3d.
+ if (sendNameToD3D)
+ {
+ return resource->SetPrivateData(WKPDID_D3DDebugObjectName,
+ static_cast<UINT>(d3dName.size()), d3dName.c_str());
+ }
+ return S_OK;
+}
+
+// Keep this in cpp file where it has visibility of Renderer11.h, otherwise calling
+// allocateResource is only compatible with Clang and MSVS, which support calling a
+// method on a forward declared class in a template.
+template <ResourceType ResourceT>
+angle::Result LazyResource<ResourceT>::resolveImpl(d3d::Context *context,
+ Renderer11 *renderer,
+ const GetDescType<ResourceT> &desc,
+ GetInitDataType<ResourceT> *initData,
+ const char *name)
+{
+ if (!mResource.valid())
+ {
+ ANGLE_TRY(renderer->allocateResource(context, desc, initData, &mResource));
+ mResource.setInternalName(name);
+ }
+ return angle::Result::Continue;
+}
+
+template angle::Result LazyResource<ResourceType::BlendState>::resolveImpl(
+ d3d::Context *context,
+ Renderer11 *renderer,
+ const D3D11_BLEND_DESC &desc,
+ void *initData,
+ const char *name);
+template angle::Result LazyResource<ResourceType::ComputeShader>::resolveImpl(
+ d3d::Context *context,
+ Renderer11 *renderer,
+ const ShaderData &desc,
+ void *initData,
+ const char *name);
+template angle::Result LazyResource<ResourceType::GeometryShader>::resolveImpl(
+ d3d::Context *context,
+ Renderer11 *renderer,
+ const ShaderData &desc,
+ const std::vector<D3D11_SO_DECLARATION_ENTRY> *initData,
+ const char *name);
+template angle::Result LazyResource<ResourceType::InputLayout>::resolveImpl(
+ d3d::Context *context,
+ Renderer11 *renderer,
+ const InputElementArray &desc,
+ const ShaderData *initData,
+ const char *name);
+template angle::Result LazyResource<ResourceType::PixelShader>::resolveImpl(d3d::Context *context,
+ Renderer11 *renderer,
+ const ShaderData &desc,
+ void *initData,
+ const char *name);
+template angle::Result LazyResource<ResourceType::VertexShader>::resolveImpl(d3d::Context *context,
+ Renderer11 *renderer,
+ const ShaderData &desc,
+ void *initData,
+ const char *name);
+
+LazyInputLayout::LazyInputLayout(const D3D11_INPUT_ELEMENT_DESC *inputDesc,
+ size_t inputDescLen,
+ const BYTE *byteCode,
+ size_t byteCodeLen,
+ const char *debugName)
+ : mInputDesc(inputDesc, inputDescLen), mByteCode(byteCode, byteCodeLen), mDebugName(debugName)
+{}
+
+LazyInputLayout::~LazyInputLayout() {}
+
+angle::Result LazyInputLayout::resolve(d3d::Context *context, Renderer11 *renderer)
+{
+ return resolveImpl(context, renderer, mInputDesc, &mByteCode, mDebugName);
+}
+
+LazyBlendState::LazyBlendState(const D3D11_BLEND_DESC &desc, const char *debugName)
+ : mDesc(desc), mDebugName(debugName)
+{}
+
+angle::Result LazyBlendState::resolve(d3d::Context *context, Renderer11 *renderer)
+{
+ return resolveImpl(context, renderer, mDesc, nullptr, mDebugName);
+}
+
+void InitializeFeatures(const Renderer11DeviceCaps &deviceCaps,
+ const DXGI_ADAPTER_DESC &adapterDesc,
+ angle::FeaturesD3D *features)
+{
+ bool isNvidia = IsNvidia(adapterDesc.VendorId);
+ bool isIntel = IsIntel(adapterDesc.VendorId);
+ bool isSkylake = false;
+ bool isBroadwell = false;
+ bool isHaswell = false;
+ bool isIvyBridge = false;
+ bool isSandyBridge = false;
+ bool isAMD = IsAMD(adapterDesc.VendorId);
+ bool isFeatureLevel9_3 = (deviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3);
+
+ IntelDriverVersion capsVersion = IntelDriverVersion(0);
+ if (isIntel)
+ {
+ capsVersion = d3d11_gl::GetIntelDriverVersion(deviceCaps.driverVersion);
+
+ isSkylake = IsSkylake(adapterDesc.DeviceId);
+ isBroadwell = IsBroadwell(adapterDesc.DeviceId);
+ isHaswell = IsHaswell(adapterDesc.DeviceId);
+ isIvyBridge = IsIvyBridge(adapterDesc.DeviceId);
+ isSandyBridge = IsSandyBridge(adapterDesc.DeviceId);
+ }
+
+ if (isNvidia)
+ {
+ // TODO(jmadill): Narrow problematic driver range.
+ bool driverVersionValid = deviceCaps.driverVersion.valid();
+ if (driverVersionValid)
+ {
+ 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.
+ ANGLE_FEATURE_CONDITION(
+ features, depthStencilBlitExtraCopy,
+ (part1 <= 13u && part2 < 6881) && isNvidia && driverVersionValid);
+ }
+ else
+ {
+ ANGLE_FEATURE_CONDITION(features, depthStencilBlitExtraCopy,
+ isNvidia && !driverVersionValid);
+ }
+ }
+
+ ANGLE_FEATURE_CONDITION(features, mrtPerfWorkaround, true);
+ ANGLE_FEATURE_CONDITION(features, zeroMaxLodWorkaround, isFeatureLevel9_3);
+ ANGLE_FEATURE_CONDITION(features, useInstancedPointSpriteEmulation, isFeatureLevel9_3);
+ ANGLE_FEATURE_CONDITION(features, allowES3OnFL100, false);
+
+ // TODO(jmadill): Disable workaround when we have a fixed compiler DLL.
+ ANGLE_FEATURE_CONDITION(features, expandIntegerPowExpressions, true);
+
+ ANGLE_FEATURE_CONDITION(features, flushAfterEndingTransformFeedback, isNvidia);
+ ANGLE_FEATURE_CONDITION(features, getDimensionsIgnoresBaseLevel, isNvidia);
+ ANGLE_FEATURE_CONDITION(features, skipVSConstantRegisterZero, isNvidia);
+ ANGLE_FEATURE_CONDITION(features, forceAtomicValueResolution, isNvidia);
+
+ ANGLE_FEATURE_CONDITION(features, preAddTexelFetchOffsets, isIntel);
+ ANGLE_FEATURE_CONDITION(features, useSystemMemoryForConstantBuffers, isIntel);
+
+ // ClearView on Skylake seems to incorrectly clear with unaligned rects (edge has saw tooth
+ // pattern instead of straight).
+ ANGLE_FEATURE_CONDITION(features, scissoredClearArtifacts, isIntel && isSkylake);
+
+ ANGLE_FEATURE_CONDITION(features, callClearTwice,
+ isIntel && isSkylake && capsVersion >= IntelDriverVersion(160000) &&
+ capsVersion < IntelDriverVersion(164771));
+ ANGLE_FEATURE_CONDITION(features, emulateIsnanFloat,
+ isIntel && isSkylake && capsVersion >= IntelDriverVersion(160000) &&
+ capsVersion < IntelDriverVersion(164542));
+ ANGLE_FEATURE_CONDITION(features, rewriteUnaryMinusOperator,
+ isIntel && (isBroadwell || isHaswell) &&
+ capsVersion >= IntelDriverVersion(150000) &&
+ capsVersion < IntelDriverVersion(154624));
+
+ ANGLE_FEATURE_CONDITION(features, addMockTextureNoRenderTarget,
+ isIntel && capsVersion >= IntelDriverVersion(160000) &&
+ capsVersion < IntelDriverVersion(164815));
+
+ // Haswell drivers occasionally corrupt (small?) (vertex?) texture data uploads for 128bit
+ // formats.
+ ANGLE_FEATURE_CONDITION(features, setDataFasterThanImageUpload, true);
+ ANGLE_FEATURE_CONDITION(features, setDataFasterThanImageUploadOn128bitFormats,
+ !(isIvyBridge || isBroadwell || isHaswell));
+
+ ANGLE_FEATURE_CONDITION(features, emulateClearViewAfterDualSourceBlending, isSandyBridge);
+
+ ANGLE_FEATURE_CONDITION(features, disableB5G6R5Support,
+ (isIntel && capsVersion >= IntelDriverVersion(150000) &&
+ capsVersion < IntelDriverVersion(154539)) ||
+ isAMD);
+
+ // TODO(jmadill): Disable when we have a fixed driver version.
+ // The tiny stencil texture workaround involves using CopySubresource or UpdateSubresource on a
+ // depth stencil texture. This is not allowed until feature level 10.1 but since it is not
+ // possible to support ES3 on these devices, there is no need for the workaround to begin with
+ // (anglebug.com/1572).
+ ANGLE_FEATURE_CONDITION(features, emulateTinyStencilTextures,
+ isAMD && !(deviceCaps.featureLevel < D3D_FEATURE_LEVEL_10_1));
+
+ // If the VPAndRTArrayIndexFromAnyShaderFeedingRasterizer feature is not available, we have to
+ // select the viewport / RT array index in the geometry shader.
+ ANGLE_FEATURE_CONDITION(features, selectViewInGeometryShader,
+ !deviceCaps.supportsVpRtIndexWriteFromVertexShader);
+
+ // NVidia drivers have no trouble clearing textures without showing corruption.
+ // Intel and AMD drivers that have trouble have been blocklisted by Chromium. In the case of
+ // Intel, they've been blocklisted to the DX9 runtime.
+ ANGLE_FEATURE_CONDITION(features, allowClearForRobustResourceInit, true);
+
+ // Allow translating uniform block to StructuredBuffer on Windows 10. This is targeted
+ // to work around a slow fxc compile performance issue with dynamic uniform indexing.
+ ANGLE_FEATURE_CONDITION(features, allowTranslateUniformBlockToStructuredBuffer,
+ IsWin10OrGreater());
+}
+
+void InitializeFrontendFeatures(const DXGI_ADAPTER_DESC &adapterDesc,
+ angle::FrontendFeatures *features)
+{
+ bool isAMD = IsAMD(adapterDesc.VendorId);
+
+ ANGLE_FEATURE_CONDITION(features, forceDepthAttachmentInitOnClear, isAMD);
+}
+
+void InitConstantBufferDesc(D3D11_BUFFER_DESC *constantBufferDescription, size_t byteWidth)
+{
+ constantBufferDescription->ByteWidth = static_cast<UINT>(byteWidth);
+ constantBufferDescription->Usage = D3D11_USAGE_DYNAMIC;
+ constantBufferDescription->BindFlags = D3D11_BIND_CONSTANT_BUFFER;
+ constantBufferDescription->CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+ constantBufferDescription->MiscFlags = 0;
+ constantBufferDescription->StructureByteStride = 0;
+}
+
+} // namespace d3d11
+
+// TextureHelper11 implementation.
+TextureHelper11::TextureHelper11() : mFormatSet(nullptr), mSampleCount(0) {}
+
+TextureHelper11::TextureHelper11(TextureHelper11 &&toCopy) : TextureHelper11()
+{
+ *this = std::move(toCopy);
+}
+
+TextureHelper11::TextureHelper11(const TextureHelper11 &other)
+ : mFormatSet(other.mFormatSet), mExtents(other.mExtents), mSampleCount(other.mSampleCount)
+{
+ mData = other.mData;
+}
+
+TextureHelper11::~TextureHelper11() {}
+
+void TextureHelper11::getDesc(D3D11_TEXTURE2D_DESC *desc) const
+{
+ static_cast<ID3D11Texture2D *>(mData->object)->GetDesc(desc);
+}
+
+void TextureHelper11::getDesc(D3D11_TEXTURE3D_DESC *desc) const
+{
+ static_cast<ID3D11Texture3D *>(mData->object)->GetDesc(desc);
+}
+
+void TextureHelper11::getDesc(D3D11_BUFFER_DESC *desc) const
+{
+ static_cast<ID3D11Buffer *>(mData->object)->GetDesc(desc);
+}
+
+void TextureHelper11::initDesc(const D3D11_TEXTURE2D_DESC &desc2D)
+{
+ mData->resourceType = ResourceType::Texture2D;
+ mExtents.width = static_cast<int>(desc2D.Width);
+ mExtents.height = static_cast<int>(desc2D.Height);
+ mExtents.depth = 1;
+ mSampleCount = desc2D.SampleDesc.Count;
+}
+
+void TextureHelper11::initDesc(const D3D11_TEXTURE3D_DESC &desc3D)
+{
+ mData->resourceType = ResourceType::Texture3D;
+ mExtents.width = static_cast<int>(desc3D.Width);
+ mExtents.height = static_cast<int>(desc3D.Height);
+ mExtents.depth = static_cast<int>(desc3D.Depth);
+ mSampleCount = 1;
+}
+
+void TextureHelper11::initDesc(const D3D11_BUFFER_DESC &descBuffer)
+{
+ mData->resourceType = ResourceType::Buffer;
+ mExtents.width = static_cast<int>(descBuffer.ByteWidth);
+ mExtents.height = 1;
+ mExtents.depth = 1;
+ mSampleCount = 1;
+}
+
+TextureHelper11 &TextureHelper11::operator=(TextureHelper11 &&other)
+{
+ std::swap(mData, other.mData);
+ std::swap(mExtents, other.mExtents);
+ std::swap(mFormatSet, other.mFormatSet);
+ std::swap(mSampleCount, other.mSampleCount);
+ return *this;
+}
+
+TextureHelper11 &TextureHelper11::operator=(const TextureHelper11 &other)
+{
+ mData = other.mData;
+ mExtents = other.mExtents;
+ mFormatSet = other.mFormatSet;
+ mSampleCount = other.mSampleCount;
+ return *this;
+}
+
+bool TextureHelper11::operator==(const TextureHelper11 &other) const
+{
+ return mData->object == other.mData->object;
+}
+
+bool TextureHelper11::operator!=(const TextureHelper11 &other) const
+{
+ return mData->object != other.mData->object;
+}
+
+bool UsePresentPathFast(const Renderer11 *renderer,
+ const gl::FramebufferAttachment *framebufferAttachment)
+{
+ if (framebufferAttachment == nullptr)
+ {
+ return false;
+ }
+
+ return (framebufferAttachment->type() == GL_FRAMEBUFFER_DEFAULT &&
+ renderer->presentPathFastEnabled());
+}
+
+bool UsePrimitiveRestartWorkaround(bool primitiveRestartFixedIndexEnabled,
+ gl::DrawElementsType type)
+{
+ // We should never have to deal with primitive restart workaround issue with GL_UNSIGNED_INT
+ // indices, since we restrict it via MAX_ELEMENT_INDEX.
+ return (!primitiveRestartFixedIndexEnabled && type == gl::DrawElementsType::UnsignedShort);
+}
+
+IndexStorageType ClassifyIndexStorage(const gl::State &glState,
+ const gl::Buffer *elementArrayBuffer,
+ gl::DrawElementsType elementType,
+ gl::DrawElementsType destElementType,
+ unsigned int offset)
+{
+ // No buffer bound means we are streaming from a client pointer.
+ if (!elementArrayBuffer || !IsOffsetAligned(elementType, offset))
+ {
+ return IndexStorageType::Dynamic;
+ }
+
+ // The buffer can be used directly if the storage supports it and no translation needed.
+ BufferD3D *bufferD3D = GetImplAs<BufferD3D>(elementArrayBuffer);
+ if (bufferD3D->supportsDirectBinding() && destElementType == elementType)
+ {
+ return IndexStorageType::Direct;
+ }
+
+ // Use a static copy when available.
+ StaticIndexBufferInterface *staticBuffer = bufferD3D->getStaticIndexBuffer();
+ if (staticBuffer != nullptr)
+ {
+ return IndexStorageType::Static;
+ }
+
+ // Static buffer not available, fall back to streaming.
+ return IndexStorageType::Dynamic;
+}
+
+bool SwizzleRequired(const gl::TextureState &textureState)
+{
+ // When sampling stencil, a swizzle is needed to move the stencil channel from G to R.
+ return textureState.swizzleRequired() || textureState.isStencilMode();
+}
+
+gl::SwizzleState GetEffectiveSwizzle(const gl::TextureState &textureState)
+{
+ const gl::SwizzleState &swizzle = textureState.getSwizzleState();
+ if (textureState.isStencilMode())
+ {
+ // Per GL semantics, the stencil value should be in the red channel, while D3D11 formats
+ // leave stencil in the green channel. So copy the stencil value from green to all
+ // components requesting red. Green and blue become zero; alpha becomes one.
+ std::unordered_map<GLenum, GLenum> map = {{GL_RED, GL_GREEN}, {GL_GREEN, GL_ZERO},
+ {GL_BLUE, GL_ZERO}, {GL_ALPHA, GL_ONE},
+ {GL_ZERO, GL_ZERO}, {GL_ONE, GL_ONE}};
+
+ return gl::SwizzleState(map[swizzle.swizzleRed], map[swizzle.swizzleGreen],
+ map[swizzle.swizzleBlue], map[swizzle.swizzleAlpha]);
+ }
+ return swizzle;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h
new file mode 100644
index 0000000000..a8cd430bc6
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.h
@@ -0,0 +1,478 @@
+//
+// Copyright 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.
+//
+
+// renderer11_utils.h: Conversion functions and other utility routines
+// specific to the D3D11 renderer.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_RENDERER11_UTILS_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_RENDERER11_UTILS_H_
+
+#include <array>
+#include <functional>
+#include <vector>
+
+#include "common/Color.h"
+
+#include "libANGLE/Caps.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
+#include "libANGLE/renderer/d3d/d3d11/ResourceManager11.h"
+#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
+
+namespace gl
+{
+class FramebufferAttachment;
+}
+
+namespace rx
+{
+class Context11;
+class Renderer11;
+class RenderTarget11;
+struct Renderer11DeviceCaps;
+
+using RTVArray = std::array<ID3D11RenderTargetView *, gl::IMPLEMENTATION_MAX_DRAW_BUFFERS>;
+
+namespace gl_d3d11
+{
+
+D3D11_BLEND ConvertBlendFunc(GLenum glBlend, bool isAlpha);
+D3D11_BLEND_OP ConvertBlendOp(GLenum glBlendOp);
+UINT8 ConvertColorMask(bool maskRed, bool maskGreen, bool maskBlue, bool maskAlpha);
+
+D3D11_CULL_MODE ConvertCullMode(bool cullEnabled, gl::CullFaceMode cullMode);
+
+D3D11_COMPARISON_FUNC ConvertComparison(GLenum comparison);
+D3D11_DEPTH_WRITE_MASK ConvertDepthMask(bool depthWriteEnabled);
+UINT8 ConvertStencilMask(GLuint stencilmask);
+D3D11_STENCIL_OP ConvertStencilOp(GLenum stencilOp);
+
+D3D11_FILTER ConvertFilter(GLenum minFilter,
+ GLenum magFilter,
+ float maxAnisotropy,
+ GLenum comparisonMode);
+D3D11_TEXTURE_ADDRESS_MODE ConvertTextureWrap(GLenum wrap);
+UINT ConvertMaxAnisotropy(float maxAnisotropy, D3D_FEATURE_LEVEL featureLevel);
+
+D3D11_QUERY ConvertQueryType(gl::QueryType type);
+
+UINT8 GetColorMask(const gl::InternalFormat &formatInfo);
+
+} // namespace gl_d3d11
+
+namespace d3d11_gl
+{
+
+unsigned int GetReservedVertexUniformVectors(D3D_FEATURE_LEVEL featureLevel);
+
+unsigned int GetReservedFragmentUniformVectors(D3D_FEATURE_LEVEL featureLevel);
+
+gl::Version GetMaximumClientVersion(const Renderer11DeviceCaps &caps);
+void GenerateCaps(ID3D11Device *device,
+ ID3D11DeviceContext *deviceContext,
+ const Renderer11DeviceCaps &renderer11DeviceCaps,
+ const angle::FeaturesD3D &features,
+ const char *description,
+ gl::Caps *caps,
+ gl::TextureCapsMap *textureCapsMap,
+ gl::Extensions *extensions,
+ gl::Limitations *limitations);
+
+D3D_FEATURE_LEVEL GetMinimumFeatureLevelForES31();
+
+} // namespace d3d11_gl
+
+namespace d3d11
+{
+
+enum ANGLED3D11DeviceType
+{
+ ANGLE_D3D11_DEVICE_TYPE_UNKNOWN,
+ ANGLE_D3D11_DEVICE_TYPE_HARDWARE,
+ ANGLE_D3D11_DEVICE_TYPE_SOFTWARE_REF_OR_NULL,
+ ANGLE_D3D11_DEVICE_TYPE_WARP,
+};
+
+ANGLED3D11DeviceType GetDeviceType(ID3D11Device *device);
+
+void MakeValidSize(bool isImage,
+ DXGI_FORMAT format,
+ GLsizei *requestWidth,
+ GLsizei *requestHeight,
+ int *levelOffset);
+
+angle::Result GenerateInitialTextureData(
+ const gl::Context *context,
+ GLint internalFormat,
+ const Renderer11DeviceCaps &renderer11DeviceCaps,
+ GLuint width,
+ GLuint height,
+ GLuint depth,
+ GLuint mipLevels,
+ gl::TexLevelArray<D3D11_SUBRESOURCE_DATA> *outSubresourceData);
+
+UINT GetPrimitiveRestartIndex();
+
+struct PositionTexCoordVertex
+{
+ float x, y;
+ float u, v;
+};
+void SetPositionTexCoordVertex(PositionTexCoordVertex *vertex, float x, float y, float u, float v);
+
+struct PositionLayerTexCoord3DVertex
+{
+ float x, y;
+ unsigned int l;
+ float u, v, s;
+};
+void SetPositionLayerTexCoord3DVertex(PositionLayerTexCoord3DVertex *vertex,
+ float x,
+ float y,
+ unsigned int layer,
+ float u,
+ float v,
+ float s);
+
+struct PositionVertex
+{
+ float x, y, z, w;
+};
+
+struct BlendStateKey final
+{
+ // This will zero-initialize the struct, including padding.
+ BlendStateKey();
+ BlendStateKey(const BlendStateKey &other);
+
+ gl::BlendStateExt blendStateExt;
+
+ // Use two 16-bit ints to round the struct nicely.
+ uint16_t rtvMax;
+ uint16_t sampleAlphaToCoverage;
+};
+
+bool operator==(const BlendStateKey &a, const BlendStateKey &b);
+bool operator!=(const BlendStateKey &a, const BlendStateKey &b);
+
+struct RasterizerStateKey final
+{
+ // This will zero-initialize the struct, including padding.
+ RasterizerStateKey();
+
+ gl::RasterizerState rasterizerState;
+
+ // Use a 32-bit int to round the struct nicely.
+ uint32_t scissorEnabled;
+};
+
+bool operator==(const RasterizerStateKey &a, const RasterizerStateKey &b);
+bool operator!=(const RasterizerStateKey &a, const RasterizerStateKey &b);
+
+template <typename outType>
+outType *DynamicCastComObject(IUnknown *object)
+{
+ outType *outObject = nullptr;
+ HRESULT result =
+ object->QueryInterface(__uuidof(outType), reinterpret_cast<void **>(&outObject));
+ if (SUCCEEDED(result))
+ {
+ return outObject;
+ }
+ else
+ {
+ SafeRelease(outObject);
+ return nullptr;
+ }
+}
+
+template <typename outType>
+angle::ComPtr<outType> DynamicCastComObjectToComPtr(IUnknown *object)
+{
+ angle::ComPtr<outType> outObject;
+ const HRESULT hr = object->QueryInterface(IID_PPV_ARGS(&outObject));
+ if (SUCCEEDED(hr))
+ {
+ return outObject;
+ }
+ else
+ {
+ return nullptr;
+ }
+}
+
+inline bool isDeviceLostError(HRESULT errorCode)
+{
+ switch (errorCode)
+ {
+ case DXGI_ERROR_DEVICE_HUNG:
+ case DXGI_ERROR_DEVICE_REMOVED:
+ case DXGI_ERROR_DEVICE_RESET:
+ case DXGI_ERROR_DRIVER_INTERNAL_ERROR:
+ case DXGI_ERROR_NOT_CURRENTLY_AVAILABLE:
+ return true;
+ default:
+ return false;
+ }
+}
+
+template <ResourceType ResourceT>
+class LazyResource : angle::NonCopyable
+{
+ public:
+ constexpr LazyResource() : mResource() {}
+ virtual ~LazyResource() {}
+
+ virtual angle::Result resolve(d3d::Context *context, Renderer11 *renderer) = 0;
+ void reset() { mResource.reset(); }
+ GetD3D11Type<ResourceT> *get() const
+ {
+ ASSERT(mResource.valid());
+ return mResource.get();
+ }
+
+ const Resource11<GetD3D11Type<ResourceT>> &getObj() const { return mResource; }
+
+ protected:
+ LazyResource(LazyResource &&other) : mResource(std::move(other.mResource)) {}
+
+ // Specialized in the cpp file to avoid MSVS/Clang specific code.
+ angle::Result resolveImpl(d3d::Context *context,
+ Renderer11 *renderer,
+ const GetDescType<ResourceT> &desc,
+ GetInitDataType<ResourceT> *initData,
+ const char *name);
+
+ Resource11<GetD3D11Type<ResourceT>> mResource;
+};
+
+template <typename D3D11ShaderType>
+class LazyShader final : public LazyResource<GetResourceTypeFromD3D11<D3D11ShaderType>()>
+{
+ public:
+ // All parameters must be constexpr. Not supported in VS2013.
+ constexpr LazyShader(const BYTE *byteCode, size_t byteCodeSize, const char *name)
+ : mByteCode(byteCode, byteCodeSize), mName(name)
+ {}
+
+ constexpr LazyShader(LazyShader &&shader)
+ : LazyResource<GetResourceTypeFromD3D11<D3D11ShaderType>()>(std::move(shader)),
+ mByteCode(std::move(shader.mByteCode)),
+ mName(shader.mName)
+ {}
+
+ angle::Result resolve(d3d::Context *context, Renderer11 *renderer) override
+ {
+ return this->resolveImpl(context, renderer, mByteCode, nullptr, mName);
+ }
+
+ private:
+ ShaderData mByteCode;
+ const char *mName;
+};
+
+class LazyInputLayout final : public LazyResource<ResourceType::InputLayout>
+{
+ public:
+ LazyInputLayout(const D3D11_INPUT_ELEMENT_DESC *inputDesc,
+ size_t inputDescLen,
+ const BYTE *byteCode,
+ size_t byteCodeLen,
+ const char *debugName);
+ ~LazyInputLayout() override;
+
+ angle::Result resolve(d3d::Context *context, Renderer11 *renderer) override;
+
+ private:
+ InputElementArray mInputDesc;
+ ShaderData mByteCode;
+ const char *mDebugName;
+};
+
+class LazyBlendState final : public LazyResource<ResourceType::BlendState>
+{
+ public:
+ LazyBlendState(const D3D11_BLEND_DESC &desc, const char *debugName);
+
+ angle::Result resolve(d3d::Context *context, Renderer11 *renderer) override;
+
+ private:
+ D3D11_BLEND_DESC mDesc;
+ const char *mDebugName;
+};
+
+// Copy data to small D3D11 buffers, such as for small constant buffers, which use one struct to
+// represent an entire buffer.
+template <class T>
+void SetBufferData(ID3D11DeviceContext *context, ID3D11Buffer *constantBuffer, const T &value)
+{
+ D3D11_MAPPED_SUBRESOURCE mappedResource = {};
+ HRESULT result = context->Map(constantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
+ ASSERT(SUCCEEDED(result));
+ if (SUCCEEDED(result))
+ {
+ memcpy(mappedResource.pData, &value, sizeof(T));
+ context->Unmap(constantBuffer, 0);
+ }
+}
+
+void InitializeFeatures(const Renderer11DeviceCaps &deviceCaps,
+ const DXGI_ADAPTER_DESC &adapterDesc,
+ angle::FeaturesD3D *features);
+
+void InitializeFrontendFeatures(const DXGI_ADAPTER_DESC &adapterDesc,
+ angle::FrontendFeatures *features);
+
+enum ReservedConstantBufferSlot
+{
+ RESERVED_CONSTANT_BUFFER_SLOT_DEFAULT_UNIFORM_BLOCK = 0,
+ RESERVED_CONSTANT_BUFFER_SLOT_DRIVER = 1,
+
+ RESERVED_CONSTANT_BUFFER_SLOT_COUNT = 2
+};
+
+void InitConstantBufferDesc(D3D11_BUFFER_DESC *constantBufferDescription, size_t byteWidth);
+
+// Helper class for RAII patterning.
+template <typename T>
+class [[nodiscard]] ScopedUnmapper final : angle::NonCopyable
+{
+ public:
+ ScopedUnmapper(T *object) : mObject(object) {}
+ ~ScopedUnmapper() { mObject->unmap(); }
+
+ private:
+ T *mObject;
+};
+} // namespace d3d11
+
+struct GenericData
+{
+ GenericData() {}
+ ~GenericData()
+ {
+ if (object)
+ {
+ // We can have a nullptr factory when holding passed-in resources.
+ if (manager)
+ {
+ manager->onReleaseGeneric(resourceType, object);
+ manager = nullptr;
+ }
+ object->Release();
+ object = nullptr;
+ }
+ }
+
+ ResourceType resourceType = ResourceType::Last;
+ ID3D11Resource *object = nullptr;
+ ResourceManager11 *manager = nullptr;
+};
+
+// A helper class which wraps a 2D or 3D texture.
+class TextureHelper11 : public Resource11Base<ID3D11Resource, std::shared_ptr, GenericData>
+{
+ public:
+ TextureHelper11();
+ TextureHelper11(TextureHelper11 &&other);
+ TextureHelper11(const TextureHelper11 &other);
+ ~TextureHelper11() override;
+ TextureHelper11 &operator=(TextureHelper11 &&other);
+ TextureHelper11 &operator=(const TextureHelper11 &other);
+
+ bool isBuffer() const { return mData->resourceType == ResourceType::Buffer; }
+ bool is2D() const { return mData->resourceType == ResourceType::Texture2D; }
+ bool is3D() const { return mData->resourceType == ResourceType::Texture3D; }
+ ResourceType getTextureType() const { return mData->resourceType; }
+ gl::Extents getExtents() const { return mExtents; }
+ DXGI_FORMAT getFormat() const { return mFormatSet->texFormat; }
+ const d3d11::Format &getFormatSet() const { return *mFormatSet; }
+ int getSampleCount() const { return mSampleCount; }
+
+ template <typename DescT, typename ResourceT>
+ void init(Resource11<ResourceT> &&texture, const DescT &desc, const d3d11::Format &format)
+ {
+ std::swap(mData->manager, texture.mData->manager);
+
+ // Can't use std::swap because texture is typed, and here we use ID3D11Resource.
+ ID3D11Resource *temp = mData->object;
+ mData->object = texture.mData->object;
+ texture.mData->object = static_cast<ResourceT *>(temp);
+
+ mFormatSet = &format;
+ initDesc(desc);
+ }
+
+ template <typename ResourceT>
+ void set(ResourceT *object, const d3d11::Format &format)
+ {
+ ASSERT(!valid());
+
+ mFormatSet = &format;
+ mData->object = object;
+ mData->manager = nullptr;
+
+ GetDescFromD3D11<ResourceT> desc;
+ getDesc(&desc);
+ initDesc(desc);
+ }
+
+ bool operator==(const TextureHelper11 &other) const;
+ bool operator!=(const TextureHelper11 &other) const;
+
+ void getDesc(D3D11_TEXTURE2D_DESC *desc) const;
+ void getDesc(D3D11_TEXTURE3D_DESC *desc) const;
+ void getDesc(D3D11_BUFFER_DESC *desc) const;
+
+ private:
+ void initDesc(const D3D11_TEXTURE2D_DESC &desc2D);
+ void initDesc(const D3D11_TEXTURE3D_DESC &desc3D);
+ void initDesc(const D3D11_BUFFER_DESC &descBuffer);
+
+ const d3d11::Format *mFormatSet;
+ gl::Extents mExtents;
+ int mSampleCount;
+};
+
+enum class StagingAccess
+{
+ READ,
+ READ_WRITE,
+};
+
+bool UsePresentPathFast(const Renderer11 *renderer, const gl::FramebufferAttachment *colorbuffer);
+bool UsePrimitiveRestartWorkaround(bool primitiveRestartFixedIndexEnabled,
+ gl::DrawElementsType type);
+
+enum class IndexStorageType
+{
+ // Dynamic indexes are re-streamed every frame. They come from a client data pointer or
+ // from buffers that are updated frequently.
+ Dynamic,
+
+ // Static indexes are translated from the original storage once, and re-used multiple times.
+ Static,
+
+ // Direct indexes are never transated and are used directly from the source buffer. They are
+ // the fastest available path.
+ Direct,
+
+ // Not a real storage type.
+ Invalid,
+};
+
+IndexStorageType ClassifyIndexStorage(const gl::State &glState,
+ const gl::Buffer *elementArrayBuffer,
+ gl::DrawElementsType elementType,
+ gl::DrawElementsType destElementType,
+ unsigned int offset);
+
+bool SwizzleRequired(const gl::TextureState &textureState);
+gl::SwizzleState GetEffectiveSwizzle(const gl::TextureState &textureState);
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D11_RENDERER11_UTILS_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_gs.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_gs.h
new file mode 100644
index 0000000000..9bfc750765
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_gs.h
@@ -0,0 +1,80 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_Position 0 xyzw 0 POS float xyzw
+// TEXCOORD 0 x 1 NONE uint x
+// LAYER 0 y 1 NONE uint y
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_Position 0 xyzw 0 POS float xyzw
+// TEXCOORD 0 x 1 NONE uint x
+// SV_RenderTargetArrayIndex 0 y 1 RTINDEX uint y
+//
+gs_4_0
+dcl_input_siv v[1][0].xyzw, position
+dcl_input v[1][1].x
+dcl_input v[1][1].y
+dcl_inputprimitive point
+dcl_outputtopology pointlist
+dcl_output_siv o0.xyzw, position
+dcl_output o1.x
+dcl_output_siv o1.y, rendertarget_array_index
+dcl_maxout 1
+mov o0.xyzw, v[0][0].xyzw
+mov o1.x, v[0][1].x
+mov o1.y, v[0][1].y
+emit
+ret
+// Approximately 5 instruction slots used
+#endif
+
+const BYTE g_GS_BufferToTexture[] = {
+ 68, 88, 66, 67, 181, 104, 45, 14, 26, 142, 216, 235, 63, 167, 110, 6, 1, 170, 134,
+ 100, 1, 0, 0, 0, 200, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 128, 0,
+ 0, 0, 244, 0, 0, 0, 124, 1, 0, 0, 76, 2, 0, 0, 82, 68, 69, 70, 68,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 83, 71, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 108,
+ 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 92, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1,
+ 0, 0, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1,
+ 0, 0, 0, 2, 2, 0, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0,
+ 84, 69, 88, 67, 79, 79, 82, 68, 0, 76, 65, 89, 69, 82, 0, 171, 79, 83, 71,
+ 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 92,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,
+ 1, 14, 0, 0, 101, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0,
+ 0, 1, 0, 0, 0, 2, 13, 0, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111,
+ 110, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 82, 101, 110, 100, 101,
+ 114, 84, 97, 114, 103, 101, 116, 65, 114, 114, 97, 121, 73, 110, 100, 101, 120, 0, 171,
+ 83, 72, 68, 82, 200, 0, 0, 0, 64, 0, 2, 0, 50, 0, 0, 0, 97, 0, 0,
+ 5, 242, 16, 32, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 95, 0,
+ 0, 4, 18, 16, 32, 0, 1, 0, 0, 0, 1, 0, 0, 0, 95, 0, 0, 4, 34,
+ 16, 32, 0, 1, 0, 0, 0, 1, 0, 0, 0, 93, 8, 0, 1, 92, 8, 0, 1,
+ 103, 0, 0, 4, 242, 32, 16, 0, 0, 0, 0, 0, 1, 0, 0, 0, 101, 0, 0,
+ 3, 18, 32, 16, 0, 1, 0, 0, 0, 103, 0, 0, 4, 34, 32, 16, 0, 1, 0,
+ 0, 0, 4, 0, 0, 0, 94, 0, 0, 2, 1, 0, 0, 0, 54, 0, 0, 6, 242,
+ 32, 16, 0, 0, 0, 0, 0, 70, 30, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 54, 0, 0, 6, 18, 32, 16, 0, 1, 0, 0, 0, 10, 16, 32, 0, 0, 0, 0,
+ 0, 1, 0, 0, 0, 54, 0, 0, 6, 34, 32, 16, 0, 1, 0, 0, 0, 26, 16,
+ 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 19, 0, 0, 1, 62, 0, 0, 1, 83,
+ 84, 65, 84, 116, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 6, 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, 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, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4f.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4f.h
new file mode 100644
index 0000000000..87730ffe5c
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4f.h
@@ -0,0 +1,65 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Buffer4F texture float4 buf t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_Position 0 xyzw 0 POS float
+// TEXCOORD 0 x 1 NONE uint x
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_Target 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_resource_buffer (float,float,float,float) t0
+dcl_input_ps constant v1.x
+dcl_output o0.xyzw
+ld o0.xyzw, v1.xxxx, t0.xyzw
+ret
+// Approximately 2 instruction slots used
+#endif
+
+const BYTE g_PS_BufferToTexture_4F[] = {
+ 68, 88, 66, 67, 156, 38, 137, 246, 11, 113, 21, 186, 20, 101, 47, 15, 216, 211, 176,
+ 224, 1, 0, 0, 0, 12, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0,
+ 0, 0, 4, 1, 0, 0, 56, 1, 0, 0, 144, 1, 0, 0, 82, 68, 69, 70, 112,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 69, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0,
+ 0, 5, 0, 0, 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0,
+ 0, 0, 13, 0, 0, 0, 66, 117, 102, 102, 101, 114, 52, 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, 49, 48, 46, 49, 0, 171, 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, 1, 0, 0, 0,
+ 1, 0, 0, 0, 1, 1, 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, 15, 0, 0, 0, 83, 86, 95, 84,
+ 97, 114, 103, 101, 116, 0, 171, 171, 83, 72, 68, 82, 80, 0, 0, 0, 64, 0, 0,
+ 0, 20, 0, 0, 0, 88, 8, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85,
+ 0, 0, 98, 8, 0, 3, 18, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242,
+ 32, 16, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 32, 16, 0, 0, 0, 0, 0,
+ 6, 16, 16, 0, 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 62, 0, 0,
+ 1, 83, 84, 65, 84, 116, 0, 0, 0, 2, 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, 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, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4i.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4i.h
new file mode 100644
index 0000000000..64304f956d
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4i.h
@@ -0,0 +1,65 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Buffer4I texture sint4 buf t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_Position 0 xyzw 0 POS float
+// TEXCOORD 0 x 1 NONE uint x
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_Target 0 xyzw 0 TARGET int xyzw
+//
+ps_4_0
+dcl_resource_buffer (sint,sint,sint,sint) t0
+dcl_input_ps constant v1.x
+dcl_output o0.xyzw
+ld o0.xyzw, v1.xxxx, t0.xyzw
+ret
+// Approximately 2 instruction slots used
+#endif
+
+const BYTE g_PS_BufferToTexture_4I[] = {
+ 68, 88, 66, 67, 162, 203, 46, 4, 155, 72, 142, 126, 228, 80, 83, 117, 139, 11, 48,
+ 250, 1, 0, 0, 0, 12, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0,
+ 0, 0, 4, 1, 0, 0, 56, 1, 0, 0, 144, 1, 0, 0, 82, 68, 69, 70, 112,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 69, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0,
+ 0, 3, 0, 0, 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0,
+ 0, 0, 13, 0, 0, 0, 66, 117, 102, 102, 101, 114, 52, 73, 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, 49, 48, 46, 49, 0, 171, 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, 1, 0, 0, 0,
+ 1, 0, 0, 0, 1, 1, 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, 2, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84,
+ 97, 114, 103, 101, 116, 0, 171, 171, 83, 72, 68, 82, 80, 0, 0, 0, 64, 0, 0,
+ 0, 20, 0, 0, 0, 88, 8, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 51, 51,
+ 0, 0, 98, 8, 0, 3, 18, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242,
+ 32, 16, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 32, 16, 0, 0, 0, 0, 0,
+ 6, 16, 16, 0, 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 62, 0, 0,
+ 1, 83, 84, 65, 84, 116, 0, 0, 0, 2, 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, 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, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4ui.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4ui.h
new file mode 100644
index 0000000000..9504753bde
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4ui.h
@@ -0,0 +1,65 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Buffer4UI texture uint4 buf t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_Position 0 xyzw 0 POS float
+// TEXCOORD 0 x 1 NONE uint x
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_Target 0 xyzw 0 TARGET uint xyzw
+//
+ps_4_0
+dcl_resource_buffer (uint,uint,uint,uint) t0
+dcl_input_ps constant v1.x
+dcl_output o0.xyzw
+ld o0.xyzw, v1.xxxx, t0.xyzw
+ret
+// Approximately 2 instruction slots used
+#endif
+
+const BYTE g_PS_BufferToTexture_4UI[] = {
+ 68, 88, 66, 67, 168, 39, 110, 5, 143, 0, 75, 136, 251, 25, 27, 24, 35, 191, 3,
+ 64, 1, 0, 0, 0, 12, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0,
+ 0, 0, 4, 1, 0, 0, 56, 1, 0, 0, 144, 1, 0, 0, 82, 68, 69, 70, 112,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 70, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0,
+ 0, 4, 0, 0, 0, 1, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0,
+ 0, 0, 13, 0, 0, 0, 66, 117, 102, 102, 101, 114, 52, 85, 73, 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, 49, 48, 46, 49, 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, 1, 0, 0, 0,
+ 1, 0, 0, 0, 1, 1, 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, 1, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84,
+ 97, 114, 103, 101, 116, 0, 171, 171, 83, 72, 68, 82, 80, 0, 0, 0, 64, 0, 0,
+ 0, 20, 0, 0, 0, 88, 8, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 68, 68,
+ 0, 0, 98, 8, 0, 3, 18, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242,
+ 32, 16, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 32, 16, 0, 0, 0, 0, 0,
+ 6, 16, 16, 0, 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 62, 0, 0,
+ 1, 83, 84, 65, 84, 116, 0, 0, 0, 2, 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, 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, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_vs.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_vs.h
new file mode 100644
index 0000000000..b9ce502123
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_vs.h
@@ -0,0 +1,145 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Buffer Definitions:
+//
+// cbuffer BufferCopyParams
+// {
+//
+// uint FirstPixelOffset; // Offset: 0 Size: 4
+// uint PixelsPerRow; // Offset: 4 Size: 4
+// uint RowStride; // Offset: 8 Size: 4
+// uint RowsPerSlice; // Offset: 12 Size: 4
+// float2 PositionOffset; // Offset: 16 Size: 8
+// float2 PositionScale; // Offset: 24 Size: 8
+// int2 TexLocationOffset; // Offset: 32 Size: 8 [unused]
+// int2 TexLocationScale; // Offset: 40 Size: 8 [unused]
+// uint FirstSlice; // Offset: 48 Size: 4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// BufferCopyParams cbuffer NA NA cb0 1
+//
+//
+//
+// 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 x 1 NONE uint x
+// LAYER 0 y 1 NONE uint y
+//
+vs_4_0
+dcl_constantbuffer CB0[4], immediateIndexed
+dcl_input_sgv v0.x, vertex_id
+dcl_output_siv o0.xyzw, position
+dcl_output o1.x
+dcl_output o1.y
+dcl_temps 2
+mov o0.zw, l(0,0,0,1.000000)
+imul null, r0.xy, cb0[0].wwww, cb0[0].yzyy
+udiv r0.z, null, v0.x, r0.x
+imad r0.x, -r0.z, r0.x, v0.x
+imad r0.y, r0.z, r0.y, cb0[0].x
+iadd o1.y, r0.z, cb0[3].x
+udiv r0.z, null, r0.x, cb0[0].y
+imad r0.x, -r0.z, cb0[0].y, r0.x
+utof r1.xy, r0.xzxx
+imad r0.y, r0.z, cb0[0].z, r0.y
+iadd o1.x, r0.x, r0.y
+mad o0.xy, cb0[1].zwzz, r1.xyxx, cb0[1].xyxx
+ret
+// Approximately 13 instruction slots used
+#endif
+
+const BYTE g_VS_BufferToTexture[] = {
+ 68, 88, 66, 67, 153, 33, 196, 57, 209, 115, 237, 17, 59, 231, 206, 105, 1, 81, 121,
+ 39, 1, 0, 0, 0, 140, 5, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 88, 2,
+ 0, 0, 140, 2, 0, 0, 0, 3, 0, 0, 16, 5, 0, 0, 82, 68, 69, 70, 28,
+ 2, 0, 0, 1, 0, 0, 0, 80, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 254, 255, 0, 1, 0, 0, 244, 1, 0, 0, 60, 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, 1, 0, 0, 0, 66, 117, 102, 102, 101, 114, 67, 111, 112, 121, 80, 97, 114,
+ 97, 109, 115, 0, 171, 171, 171, 60, 0, 0, 0, 9, 0, 0, 0, 104, 0, 0, 0,
+ 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 1, 0, 0, 0, 0, 0,
+ 0, 4, 0, 0, 0, 2, 0, 0, 0, 84, 1, 0, 0, 0, 0, 0, 0, 100, 1,
+ 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 84, 1, 0, 0, 0,
+ 0, 0, 0, 113, 1, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0,
+ 84, 1, 0, 0, 0, 0, 0, 0, 123, 1, 0, 0, 12, 0, 0, 0, 4, 0, 0,
+ 0, 2, 0, 0, 0, 84, 1, 0, 0, 0, 0, 0, 0, 136, 1, 0, 0, 16, 0,
+ 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 152, 1, 0, 0, 0, 0, 0, 0, 168,
+ 1, 0, 0, 24, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 152, 1, 0, 0,
+ 0, 0, 0, 0, 182, 1, 0, 0, 32, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0,
+ 0, 200, 1, 0, 0, 0, 0, 0, 0, 216, 1, 0, 0, 40, 0, 0, 0, 8, 0,
+ 0, 0, 0, 0, 0, 0, 200, 1, 0, 0, 0, 0, 0, 0, 233, 1, 0, 0, 48,
+ 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 84, 1, 0, 0, 0, 0, 0, 0,
+ 70, 105, 114, 115, 116, 80, 105, 120, 101, 108, 79, 102, 102, 115, 101, 116, 0, 171, 171,
+ 171, 0, 0, 19, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 105,
+ 120, 101, 108, 115, 80, 101, 114, 82, 111, 119, 0, 82, 111, 119, 83, 116, 114, 105, 100,
+ 101, 0, 82, 111, 119, 115, 80, 101, 114, 83, 108, 105, 99, 101, 0, 80, 111, 115, 105,
+ 116, 105, 111, 110, 79, 102, 102, 115, 101, 116, 0, 171, 1, 0, 3, 0, 1, 0, 2,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 83, 99,
+ 97, 108, 101, 0, 84, 101, 120, 76, 111, 99, 97, 116, 105, 111, 110, 79, 102, 102, 115,
+ 101, 116, 0, 1, 0, 2, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 84, 101, 120, 76, 111, 99, 97, 116, 105, 111, 110, 83, 99, 97, 108, 101, 0, 70, 105,
+ 114, 115, 116, 83, 108, 105, 99, 101, 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, 49, 48, 46, 49, 0, 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, 108, 0, 0, 0, 3, 0, 0, 0, 8,
+ 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0,
+ 0, 0, 0, 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 14, 0, 0, 101, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 13, 0, 0, 83,
+ 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 84, 69, 88, 67, 79, 79, 82, 68,
+ 0, 76, 65, 89, 69, 82, 0, 171, 83, 72, 68, 82, 8, 2, 0, 0, 64, 0, 1,
+ 0, 130, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 4, 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,
+ 18, 32, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 34, 32, 16, 0, 1, 0, 0,
+ 0, 104, 0, 0, 2, 2, 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, 38, 0, 0, 10, 0, 208, 0, 0, 50, 0, 16, 0, 0, 0, 0, 0,
+ 246, 143, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 133, 32, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 78, 0, 0, 8, 66, 0, 16, 0, 0, 0, 0, 0, 0, 208,
+ 0, 0, 10, 16, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 35,
+ 0, 0, 10, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 128, 65, 0, 0, 0,
+ 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 0, 0, 0,
+ 0, 35, 0, 0, 10, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0,
+ 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 30, 0, 0, 8, 34, 32, 16, 0, 1, 0, 0, 0, 42, 0, 16, 0,
+ 0, 0, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 78, 0, 0,
+ 9, 66, 0, 16, 0, 0, 0, 0, 0, 0, 208, 0, 0, 10, 0, 16, 0, 0, 0,
+ 0, 0, 26, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 11, 18,
+ 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0,
+ 26, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0,
+ 0, 86, 0, 0, 5, 50, 0, 16, 0, 1, 0, 0, 0, 134, 0, 16, 0, 0, 0,
+ 0, 0, 35, 0, 0, 10, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0,
+ 0, 0, 0, 42, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 16, 0,
+ 0, 0, 0, 0, 30, 0, 0, 7, 18, 32, 16, 0, 1, 0, 0, 0, 10, 0, 16,
+ 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 50, 0, 0, 11, 50, 32,
+ 16, 0, 0, 0, 0, 0, 230, 138, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 70,
+ 0, 16, 0, 1, 0, 0, 0, 70, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+ 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 13, 0, 0, 0, 2, 0, 0,
+ 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0, 2, 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, 1, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11_fl9vs.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11_fl9vs.h
new file mode 100644
index 0000000000..9b4ccfb902
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11_fl9vs.h
@@ -0,0 +1,71 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// POSITION 0 xyzw 0 NONE float xyzw
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float xyzw
+//
+//
+// Runtime generated constant mappings:
+//
+// Target Reg Constant Description
+// ---------- --------------------------------------------------
+// c0 Vertex Shader position offset
+//
+//
+// Level9 shader bytecode:
+//
+ vs_2_x
+ dcl_texcoord v0
+ mad oPos.xy, v0.w, c0, v0
+ mov oPos.zw, v0
+
+// approximately 2 instruction slots used
+vs_4_0
+dcl_input v0.xyzw
+dcl_output_siv o0.xyzw, position
+mov o0.xyzw, v0.xyzw
+ret
+// Approximately 2 instruction slots used
+#endif
+
+const BYTE g_VS_Clear_FL9[] = {
+ 68, 88, 66, 67, 166, 109, 78, 113, 107, 98, 65, 70, 91, 88, 250, 161, 103, 22, 241, 76,
+ 1, 0, 0, 0, 16, 2, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 156, 0, 0, 0,
+ 224, 0, 0, 0, 92, 1, 0, 0, 168, 1, 0, 0, 220, 1, 0, 0, 65, 111, 110, 57,
+ 92, 0, 0, 0, 92, 0, 0, 0, 0, 2, 254, 255, 52, 0, 0, 0, 40, 0, 0, 0,
+ 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 36, 0, 1, 0, 36, 0,
+ 0, 0, 0, 0, 1, 2, 254, 255, 31, 0, 0, 2, 5, 0, 0, 128, 0, 0, 15, 144,
+ 4, 0, 0, 4, 0, 0, 3, 192, 0, 0, 255, 144, 0, 0, 228, 160, 0, 0, 228, 144,
+ 1, 0, 0, 2, 0, 0, 12, 192, 0, 0, 228, 144, 255, 255, 0, 0, 83, 72, 68, 82,
+ 60, 0, 0, 0, 64, 0, 1, 0, 15, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0,
+ 0, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+ 54, 0, 0, 5, 242, 32, 16, 0, 0, 0, 0, 0, 70, 30, 16, 0, 0, 0, 0, 0,
+ 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 2, 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,
+ 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, 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, 68, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 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, 49,
+ 48, 46, 49, 0, 73, 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, 15, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 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,
+ 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11multiviewgs.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11multiviewgs.h
new file mode 100644
index 0000000000..92b192107b
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11multiviewgs.h
@@ -0,0 +1,83 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_Position 0 xyzw 0 POS float xyzw
+// TEXCOORD 0 x 1 NONE uint x
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_Position 0 xyzw 0 POS float xyzw
+// SV_RenderTargetArrayIndex 0 x 1 RTINDEX uint x
+//
+gs_4_0
+dcl_input_siv v[3][0].xyzw, position
+dcl_input v[3][1].x
+dcl_temps 1
+dcl_inputprimitive triangle
+dcl_outputtopology trianglestrip
+dcl_output_siv o0.xyzw, position
+dcl_output_siv o1.x, rendertarget_array_index
+dcl_maxout 3
+mov r0.x, l(0)
+loop
+ ige r0.y, r0.x, l(3)
+ breakc_nz r0.y
+ mov o0.xyzw, v[r0.x + 0][0].xyzw
+ mov o1.x, v[r0.x + 0][1].x
+ emit
+ iadd r0.x, r0.x, l(1)
+endloop
+cut
+ret
+// Approximately 11 instruction slots used
+#endif
+
+const BYTE g_GS_Multiview_Clear[] = {
+ 68, 88, 66, 67, 110, 37, 141, 207, 15, 59, 27, 66, 207, 215, 205, 198, 147, 31, 42,
+ 22, 1, 0, 0, 0, 204, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 128, 0,
+ 0, 0, 216, 0, 0, 0, 64, 1, 0, 0, 80, 2, 0, 0, 82, 68, 69, 70, 68,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 83, 71, 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, 49, 48, 46, 49, 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, 15, 0, 0, 68, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1,
+ 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, 96, 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, 4, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 14, 0, 0, 83, 86, 95, 80, 111,
+ 115, 105, 116, 105, 111, 110, 0, 83, 86, 95, 82, 101, 110, 100, 101, 114, 84, 97, 114,
+ 103, 101, 116, 65, 114, 114, 97, 121, 73, 110, 100, 101, 120, 0, 171, 171, 83, 72, 68,
+ 82, 8, 1, 0, 0, 64, 0, 2, 0, 66, 0, 0, 0, 97, 0, 0, 5, 242, 16,
+ 32, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 95, 0, 0, 4, 18,
+ 16, 32, 0, 3, 0, 0, 0, 1, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0,
+ 93, 24, 0, 1, 92, 40, 0, 1, 103, 0, 0, 4, 242, 32, 16, 0, 0, 0, 0,
+ 0, 1, 0, 0, 0, 103, 0, 0, 4, 18, 32, 16, 0, 1, 0, 0, 0, 4, 0,
+ 0, 0, 94, 0, 0, 2, 3, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 0,
+ 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 48, 0, 0, 1, 33, 0, 0, 7,
+ 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0,
+ 0, 3, 0, 0, 0, 3, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 54, 0,
+ 0, 7, 242, 32, 16, 0, 0, 0, 0, 0, 70, 30, 160, 0, 10, 0, 16, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 18, 32, 16, 0, 1, 0, 0, 0,
+ 10, 16, 160, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 0, 0, 0, 19, 0, 0,
+ 1, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0,
+ 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 22, 0, 0, 1, 9, 0, 0, 1, 62,
+ 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 11, 0, 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 2, 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, 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, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11multiviewvs.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11multiviewvs.h
new file mode 100644
index 0000000000..ba1c5425e2
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11multiviewvs.h
@@ -0,0 +1,80 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_VertexID 0 x 0 VERTID uint x
+// SV_InstanceID 0 x 1 INSTID uint x
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float xyzw
+// TEXCOORD 0 x 1 NONE uint x
+//
+vs_4_0
+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_input_sgv v1.x, instance_id
+dcl_output_siv o0.xyzw, position
+dcl_output o1.x
+dcl_temps 1
+mov r0.x, v0.x
+mov o0.xy, icb[r0.x + 0].xyxx
+mov o0.zw, l(0,0,0,1.000000)
+mov o1.x, v1.x
+ret
+// Approximately 5 instruction slots used
+#endif
+
+const BYTE g_VS_Multiview_Clear[] = {
+ 68, 88, 66, 67, 29, 63, 249, 196, 208, 130, 142, 190, 155, 101, 165, 213, 91, 14, 122,
+ 2, 1, 0, 0, 0, 208, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 128, 0,
+ 0, 0, 220, 0, 0, 0, 52, 1, 0, 0, 84, 2, 0, 0, 82, 68, 69, 70, 68,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0,
+ 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 84,
+ 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0,
+ 6, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 68, 0, 0,
+ 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1,
+ 0, 0, 83, 86, 95, 86, 101, 114, 116, 101, 120, 73, 68, 0, 83, 86, 95, 73, 110,
+ 115, 116, 97, 110, 99, 101, 73, 68, 0, 171, 171, 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, 1, 0, 0, 0, 1, 0, 0, 0, 1, 14, 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, 83, 72, 68, 82, 24, 1, 0, 0, 64, 0, 1, 0, 70, 0, 0,
+ 0, 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, 96, 0, 0, 4, 18, 16, 16, 0, 1, 0, 0, 0,
+ 8, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 101, 0, 0, 3, 18, 32, 16, 0, 1, 0, 0, 0, 104, 0, 0, 2, 1, 0,
+ 0, 0, 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, 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, 32, 16, 0, 1, 0, 0, 0, 10, 16, 16, 0, 1,
+ 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 5, 0, 0, 0,
+ 1, 0, 0, 0, 6, 0, 0, 0, 4, 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, 0, 0, 0, 0, 0, 0, 0, 0, 4, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11vs.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11vs.h
new file mode 100644
index 0000000000..035a1fdca0
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11vs.h
@@ -0,0 +1,69 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+//
+// 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
+//
+vs_4_0
+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_temps 1
+mov r0.x, v0.x
+mov o0.xy, icb[r0.x + 0].xyxx
+mov o0.zw, l(0,0,0,1.000000)
+ret
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_VS_Clear[] = {
+ 68, 88, 66, 67, 142, 0, 156, 121, 128, 35, 189, 41, 14, 141, 59, 193, 158, 19, 28,
+ 184, 1, 0, 0, 0, 84, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 128, 0,
+ 0, 0, 180, 0, 0, 0, 232, 0, 0, 0, 216, 1, 0, 0, 82, 68, 69, 70, 68,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0,
+ 0, 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, 49, 48, 46, 49, 0, 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, 44, 0, 0, 0, 1, 0,
+ 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3,
+ 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84,
+ 73, 79, 78, 0, 83, 72, 68, 82, 232, 0, 0, 0, 64, 0, 1, 0, 58, 0, 0,
+ 0, 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, 104, 0, 0, 2, 1, 0, 0, 0, 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, 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, 62, 0, 0, 1, 83, 84, 65,
+ 84, 116, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 6, 0, 0, 0, 2, 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, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/cleardepth11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/cleardepth11ps.h
new file mode 100644
index 0000000000..41a39aead9
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/cleardepth11ps.h
@@ -0,0 +1,74 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Buffer Definitions:
+//
+// cbuffer DepthOnlyData
+// {
+//
+// float zValue_Depth; // Offset: 16 Size: 4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// DepthOnlyData cbuffer NA NA cb0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_DEPTH 0 N/A oDepth DEPTH float YES
+//
+ps_4_0
+dcl_constantbuffer CB0[2], immediateIndexed
+dcl_output oDepth
+mov oDepth, cb0[1].x
+ret
+// Approximately 2 instruction slots used
+#endif
+
+const BYTE g_PS_ClearDepth[] = {
+ 68, 88, 66, 67, 27, 164, 102, 59, 78, 154, 233, 127, 65, 17, 101, 9, 4, 119, 201,
+ 97, 1, 0, 0, 0, 36, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 0, 1,
+ 0, 0, 52, 1, 0, 0, 104, 1, 0, 0, 168, 1, 0, 0, 82, 68, 69, 70, 196,
+ 0, 0, 0, 1, 0, 0, 0, 76, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 156, 0, 0, 0, 60, 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, 1, 0, 0, 0, 68, 101, 112, 116, 104, 79, 110, 108, 121, 68, 97, 116, 97,
+ 0, 171, 171, 60, 0, 0, 0, 1, 0, 0, 0, 100, 0, 0, 0, 32, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 124, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0,
+ 0, 2, 0, 0, 0, 140, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97, 108, 117, 101,
+ 95, 68, 101, 112, 116, 104, 0, 171, 171, 171, 0, 0, 3, 0, 1, 0, 1, 0, 0,
+ 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0, 0, 1, 0,
+ 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3,
+ 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84,
+ 73, 79, 78, 0, 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, 255, 255,
+ 255, 255, 1, 14, 0, 0, 83, 86, 95, 68, 69, 80, 84, 72, 0, 171, 171, 171, 83,
+ 72, 68, 82, 56, 0, 0, 0, 64, 0, 0, 0, 14, 0, 0, 0, 89, 0, 0, 4,
+ 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 101, 0, 0, 2, 1, 192, 0,
+ 0, 54, 0, 0, 5, 1, 192, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 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, 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, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11_fl9ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11_fl9ps.h
new file mode 100644
index 0000000000..cebc263110
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11_fl9ps.h
@@ -0,0 +1,128 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Buffer Definitions:
+//
+// cbuffer ColorAndDepthDataFloat
+// {
+//
+// float4 color_Float; // Offset: 0 Size: 16
+// float zValueF_Float; // Offset: 16 Size: 4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// ColorAndDepthDataFloat cbuffer NA NA cb0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+// SV_TARGET 1 xyzw 1 TARGET float xyzw
+// SV_TARGET 2 xyzw 2 TARGET float xyzw
+// SV_TARGET 3 xyzw 3 TARGET float xyzw
+// SV_DEPTH 0 N/A oDepth DEPTH float YES
+//
+//
+// Constant buffer to DX9 shader constant mappings:
+//
+// Target Reg Buffer Start Reg # of Regs Data Conversion
+// ---------- ------- --------- --------- ----------------------
+// c0 cb0 0 2 ( FLT, FLT, FLT, FLT)
+//
+//
+// Level9 shader bytecode:
+//
+ ps_2_x
+ mov oC0, c0
+ mov oC1, c0
+ mov oC2, c0
+ mov oC3, c0
+ mov oDepth, c1.x
+
+// approximately 5 instruction slots used
+ps_4_0
+dcl_constantbuffer CB0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output o2.xyzw
+dcl_output o3.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov o2.xyzw, cb0[0].xyzw
+mov o3.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret
+// Approximately 6 instruction slots used
+#endif
+
+const BYTE g_PS_ClearFloat_FL9[] = {
+ 68, 88, 66, 67, 85, 216, 43, 21, 188, 93, 222, 90, 179, 114, 11, 205, 194, 17, 203,
+ 168, 1, 0, 0, 0, 216, 3, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 180, 0,
+ 0, 0, 132, 1, 0, 0, 0, 2, 0, 0, 8, 3, 0, 0, 60, 3, 0, 0, 65,
+ 111, 110, 57, 116, 0, 0, 0, 116, 0, 0, 0, 0, 2, 255, 255, 68, 0, 0, 0,
+ 48, 0, 0, 0, 1, 0, 36, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0, 0, 36,
+ 0, 0, 0, 48, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 2,
+ 255, 255, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 160, 1, 0, 0, 2, 1,
+ 8, 15, 128, 0, 0, 228, 160, 1, 0, 0, 2, 2, 8, 15, 128, 0, 0, 228, 160,
+ 1, 0, 0, 2, 3, 8, 15, 128, 0, 0, 228, 160, 1, 0, 0, 2, 0, 8, 15,
+ 144, 1, 0, 0, 160, 255, 255, 0, 0, 83, 72, 68, 82, 200, 0, 0, 0, 64, 0,
+ 0, 0, 50, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 2,
+ 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3,
+ 242, 32, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 2, 0, 0,
+ 0, 101, 0, 0, 3, 242, 32, 16, 0, 3, 0, 0, 0, 101, 0, 0, 2, 1, 192,
+ 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 1, 0, 0, 0,
+ 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16,
+ 0, 2, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0,
+ 0, 6, 242, 32, 16, 0, 3, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 54, 0, 0, 5, 1, 192, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 6, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 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, 0, 0, 0, 0, 0, 0, 0, 0, 5, 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, 0, 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0,
+ 28, 0, 0, 0, 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68,
+ 101, 112, 116, 104, 68, 97, 116, 97, 70, 108, 111, 97, 116, 0, 171, 60, 0, 0, 0,
+ 2, 0, 0, 0, 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 156, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0,
+ 0, 0, 0, 0, 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2,
+ 0, 0, 0, 200, 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 70, 108,
+ 111, 97, 116, 0, 1, 0, 3, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 122, 86, 97, 108, 117, 101, 70, 95, 70, 108, 111, 97, 116, 0, 171, 171, 0, 0,
+ 3, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71,
+ 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83,
+ 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 148, 0, 0, 0,
+ 5, 0, 0, 0, 8, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 128, 0, 0, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 128,
+ 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0,
+ 15, 0, 0, 0, 128, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0,
+ 0, 3, 0, 0, 0, 15, 0, 0, 0, 138, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 3, 0, 0, 0, 255, 255, 255, 255, 1, 14, 0, 0, 83, 86, 95, 84, 65,
+ 82, 71, 69, 84, 0, 83, 86, 95, 68, 69, 80, 84, 72, 0, 171};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps1.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps1.h
new file mode 100644
index 0000000000..d2845b994b
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps1.h
@@ -0,0 +1,85 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Buffer Definitions:
+//
+// cbuffer ColorAndDepthDataFloat
+// {
+//
+// float4 color_Float; // Offset: 0 Size: 16
+// float zValueF_Float; // Offset: 16 Size: 4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// ColorAndDepthDataFloat cbuffer NA NA cb0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+// SV_DEPTH 0 N/A oDepth DEPTH float YES
+//
+ps_4_0
+dcl_constantbuffer CB0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret
+// Approximately 3 instruction slots used
+#endif
+
+const BYTE g_PS_ClearFloat1[] = {
+ 68, 88, 66, 67, 249, 37, 129, 249, 125, 252, 189, 145, 109, 207, 171, 136, 14, 159, 102,
+ 81, 1, 0, 0, 0, 164, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1,
+ 0, 0, 112, 1, 0, 0, 196, 1, 0, 0, 40, 2, 0, 0, 82, 68, 69, 70, 0,
+ 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104,
+ 68, 97, 116, 97, 70, 108, 111, 97, 116, 0, 171, 60, 0, 0, 0, 2, 0, 0, 0,
+ 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0,
+ 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0,
+ 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200,
+ 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 70, 108, 111, 97, 116, 0,
+ 1, 0, 3, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97,
+ 108, 117, 101, 70, 95, 70, 108, 111, 97, 116, 0, 171, 171, 0, 0, 3, 0, 1, 0,
+ 1, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0,
+ 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79,
+ 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 76, 0, 0, 0, 2, 0, 0, 0,
+ 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0,
+ 0, 0, 0, 0, 0, 15, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 3, 0, 0, 0, 255, 255, 255, 255, 1, 14, 0, 0, 83, 86, 95, 84, 65,
+ 82, 71, 69, 84, 0, 83, 86, 95, 68, 69, 80, 84, 72, 0, 171, 83, 72, 68, 82,
+ 92, 0, 0, 0, 64, 0, 0, 0, 23, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32,
+ 0, 0, 0, 0, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0,
+ 0, 0, 101, 0, 0, 2, 1, 192, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 0,
+ 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5,
+ 1, 192, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 62, 0, 0,
+ 1, 83, 84, 65, 84, 116, 0, 0, 0, 3, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps2.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps2.h
new file mode 100644
index 0000000000..b1b3a4e441
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps2.h
@@ -0,0 +1,91 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Buffer Definitions:
+//
+// cbuffer ColorAndDepthDataFloat
+// {
+//
+// float4 color_Float; // Offset: 0 Size: 16
+// float zValueF_Float; // Offset: 16 Size: 4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// ColorAndDepthDataFloat cbuffer NA NA cb0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+// SV_TARGET 1 xyzw 1 TARGET float xyzw
+// SV_DEPTH 0 N/A oDepth DEPTH float YES
+//
+ps_4_0
+dcl_constantbuffer CB0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_PS_ClearFloat2[] = {
+ 68, 88, 66, 67, 47, 142, 59, 204, 239, 80, 8, 161, 169, 171, 199, 199, 129, 33, 42,
+ 115, 1, 0, 0, 0, 224, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1,
+ 0, 0, 112, 1, 0, 0, 220, 1, 0, 0, 100, 2, 0, 0, 82, 68, 69, 70, 0,
+ 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104,
+ 68, 97, 116, 97, 70, 108, 111, 97, 116, 0, 171, 60, 0, 0, 0, 2, 0, 0, 0,
+ 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0,
+ 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0,
+ 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200,
+ 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 70, 108, 111, 97, 116, 0,
+ 1, 0, 3, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97,
+ 108, 117, 101, 70, 95, 70, 108, 111, 97, 116, 0, 171, 171, 0, 0, 3, 0, 1, 0,
+ 1, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0,
+ 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79,
+ 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 100, 0, 0, 0, 3, 0, 0, 0,
+ 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0,
+ 0, 0, 0, 0, 0, 15, 0, 0, 0, 80, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 90, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 255, 255, 255, 255, 1, 14, 0, 0,
+ 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 83, 86, 95, 68, 69, 80, 84, 72, 0,
+ 171, 83, 72, 68, 82, 128, 0, 0, 0, 64, 0, 0, 0, 32, 0, 0, 0, 89, 0,
+ 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242,
+ 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0,
+ 101, 0, 0, 2, 1, 192, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 0, 0, 0,
+ 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32,
+ 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54,
+ 0, 0, 5, 1, 192, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+ 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 4, 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, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps3.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps3.h
new file mode 100644
index 0000000000..e84854ff68
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps3.h
@@ -0,0 +1,97 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Buffer Definitions:
+//
+// cbuffer ColorAndDepthDataFloat
+// {
+//
+// float4 color_Float; // Offset: 0 Size: 16
+// float zValueF_Float; // Offset: 16 Size: 4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// ColorAndDepthDataFloat cbuffer NA NA cb0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+// SV_TARGET 1 xyzw 1 TARGET float xyzw
+// SV_TARGET 2 xyzw 2 TARGET float xyzw
+// SV_DEPTH 0 N/A oDepth DEPTH float YES
+//
+ps_4_0
+dcl_constantbuffer CB0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output o2.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov o2.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret
+// Approximately 5 instruction slots used
+#endif
+
+const BYTE g_PS_ClearFloat3[] = {
+ 68, 88, 66, 67, 98, 17, 13, 150, 202, 50, 172, 72, 101, 93, 116, 134, 154, 66, 233,
+ 63, 1, 0, 0, 0, 28, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1,
+ 0, 0, 112, 1, 0, 0, 244, 1, 0, 0, 160, 2, 0, 0, 82, 68, 69, 70, 0,
+ 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104,
+ 68, 97, 116, 97, 70, 108, 111, 97, 116, 0, 171, 60, 0, 0, 0, 2, 0, 0, 0,
+ 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0,
+ 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0,
+ 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200,
+ 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 70, 108, 111, 97, 116, 0,
+ 1, 0, 3, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97,
+ 108, 117, 101, 70, 95, 70, 108, 111, 97, 116, 0, 171, 171, 0, 0, 3, 0, 1, 0,
+ 1, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0,
+ 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79,
+ 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 124, 0, 0, 0, 4, 0, 0, 0,
+ 8, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0,
+ 0, 0, 0, 0, 0, 15, 0, 0, 0, 104, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 104, 0, 0, 0, 2,
+ 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0,
+ 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 255, 255, 255,
+ 255, 1, 14, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 83, 86, 95, 68,
+ 69, 80, 84, 72, 0, 171, 83, 72, 68, 82, 164, 0, 0, 0, 64, 0, 0, 0, 41,
+ 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0,
+ 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16,
+ 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 2, 0, 0, 0, 101, 0,
+ 0, 2, 1, 192, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 0, 0, 0, 0, 70,
+ 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0,
+ 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0,
+ 6, 242, 32, 16, 0, 2, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 54, 0, 0, 5, 1, 192, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 1,
+ 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 5, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 4, 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, 0, 0, 0, 0, 0, 0, 0, 0, 4, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps4.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps4.h
new file mode 100644
index 0000000000..60584aceef
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps4.h
@@ -0,0 +1,104 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Buffer Definitions:
+//
+// cbuffer ColorAndDepthDataFloat
+// {
+//
+// float4 color_Float; // Offset: 0 Size: 16
+// float zValueF_Float; // Offset: 16 Size: 4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// ColorAndDepthDataFloat cbuffer NA NA cb0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+// SV_TARGET 1 xyzw 1 TARGET float xyzw
+// SV_TARGET 2 xyzw 2 TARGET float xyzw
+// SV_TARGET 3 xyzw 3 TARGET float xyzw
+// SV_DEPTH 0 N/A oDepth DEPTH float YES
+//
+ps_4_0
+dcl_constantbuffer CB0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output o2.xyzw
+dcl_output o3.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov o2.xyzw, cb0[0].xyzw
+mov o3.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret
+// Approximately 6 instruction slots used
+#endif
+
+const BYTE g_PS_ClearFloat4[] = {
+ 68, 88, 66, 67, 138, 36, 21, 91, 225, 8, 214, 250, 89, 152, 40, 168, 243, 126, 8,
+ 187, 1, 0, 0, 0, 88, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1,
+ 0, 0, 112, 1, 0, 0, 12, 2, 0, 0, 220, 2, 0, 0, 82, 68, 69, 70, 0,
+ 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104,
+ 68, 97, 116, 97, 70, 108, 111, 97, 116, 0, 171, 60, 0, 0, 0, 2, 0, 0, 0,
+ 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0,
+ 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0,
+ 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200,
+ 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 70, 108, 111, 97, 116, 0,
+ 1, 0, 3, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97,
+ 108, 117, 101, 70, 95, 70, 108, 111, 97, 116, 0, 171, 171, 0, 0, 3, 0, 1, 0,
+ 1, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0,
+ 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79,
+ 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 148, 0, 0, 0, 5, 0, 0, 0,
+ 8, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0,
+ 0, 0, 0, 0, 0, 15, 0, 0, 0, 128, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 128, 0, 0, 0, 2,
+ 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0,
+ 128, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0,
+ 0, 15, 0, 0, 0, 138, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0,
+ 0, 0, 255, 255, 255, 255, 1, 14, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84,
+ 0, 83, 86, 95, 68, 69, 80, 84, 72, 0, 171, 83, 72, 68, 82, 200, 0, 0, 0,
+ 64, 0, 0, 0, 50, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0,
+ 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 101, 0,
+ 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 2,
+ 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 3, 0, 0, 0, 101, 0, 0, 2,
+ 1, 192, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 0, 0, 0, 0, 70, 142, 32,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 1, 0,
+ 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242,
+ 32, 16, 0, 2, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 54, 0, 0, 6, 242, 32, 16, 0, 3, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 54, 0, 0, 5, 1, 192, 0, 0, 10, 128, 32, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 6,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 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, 0, 0, 0, 0, 0, 0, 0, 0, 5,
+ 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps5.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps5.h
new file mode 100644
index 0000000000..15c0545fee
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps5.h
@@ -0,0 +1,110 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Buffer Definitions:
+//
+// cbuffer ColorAndDepthDataFloat
+// {
+//
+// float4 color_Float; // Offset: 0 Size: 16
+// float zValueF_Float; // Offset: 16 Size: 4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// ColorAndDepthDataFloat cbuffer NA NA cb0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+// SV_TARGET 1 xyzw 1 TARGET float xyzw
+// SV_TARGET 2 xyzw 2 TARGET float xyzw
+// SV_TARGET 3 xyzw 3 TARGET float xyzw
+// SV_TARGET 4 xyzw 4 TARGET float xyzw
+// SV_DEPTH 0 N/A oDepth DEPTH float YES
+//
+ps_4_0
+dcl_constantbuffer CB0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output o2.xyzw
+dcl_output o3.xyzw
+dcl_output o4.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov o2.xyzw, cb0[0].xyzw
+mov o3.xyzw, cb0[0].xyzw
+mov o4.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret
+// Approximately 7 instruction slots used
+#endif
+
+const BYTE g_PS_ClearFloat5[] = {
+ 68, 88, 66, 67, 19, 82, 125, 81, 104, 222, 105, 50, 128, 46, 184, 118, 230, 154, 80,
+ 52, 1, 0, 0, 0, 148, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1,
+ 0, 0, 112, 1, 0, 0, 36, 2, 0, 0, 24, 3, 0, 0, 82, 68, 69, 70, 0,
+ 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104,
+ 68, 97, 116, 97, 70, 108, 111, 97, 116, 0, 171, 60, 0, 0, 0, 2, 0, 0, 0,
+ 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0,
+ 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0,
+ 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200,
+ 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 70, 108, 111, 97, 116, 0,
+ 1, 0, 3, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97,
+ 108, 117, 101, 70, 95, 70, 108, 111, 97, 116, 0, 171, 171, 0, 0, 3, 0, 1, 0,
+ 1, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0,
+ 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79,
+ 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 172, 0, 0, 0, 6, 0, 0, 0,
+ 8, 0, 0, 0, 152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0,
+ 0, 0, 0, 0, 0, 15, 0, 0, 0, 152, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 152, 0, 0, 0, 2,
+ 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0,
+ 152, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0,
+ 0, 15, 0, 0, 0, 152, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0,
+ 0, 0, 4, 0, 0, 0, 15, 0, 0, 0, 162, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 255, 255, 255, 255, 1, 14, 0, 0, 83, 86, 95, 84,
+ 65, 82, 71, 69, 84, 0, 83, 86, 95, 68, 69, 80, 84, 72, 0, 171, 83, 72, 68,
+ 82, 236, 0, 0, 0, 64, 0, 0, 0, 59, 0, 0, 0, 89, 0, 0, 4, 70, 142,
+ 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0,
+ 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3,
+ 242, 32, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 3, 0, 0,
+ 0, 101, 0, 0, 3, 242, 32, 16, 0, 4, 0, 0, 0, 101, 0, 0, 2, 1, 192,
+ 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 1, 0, 0, 0,
+ 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16,
+ 0, 2, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0,
+ 0, 6, 242, 32, 16, 0, 3, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 4, 0, 0, 0, 70, 142, 32, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 1, 192, 0, 0, 10, 128, 32,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0,
+ 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 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, 0, 0, 0, 0, 0, 0,
+ 0, 0, 6, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps6.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps6.h
new file mode 100644
index 0000000000..7cd6a03188
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps6.h
@@ -0,0 +1,116 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Buffer Definitions:
+//
+// cbuffer ColorAndDepthDataFloat
+// {
+//
+// float4 color_Float; // Offset: 0 Size: 16
+// float zValueF_Float; // Offset: 16 Size: 4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// ColorAndDepthDataFloat cbuffer NA NA cb0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+// SV_TARGET 1 xyzw 1 TARGET float xyzw
+// SV_TARGET 2 xyzw 2 TARGET float xyzw
+// SV_TARGET 3 xyzw 3 TARGET float xyzw
+// SV_TARGET 4 xyzw 4 TARGET float xyzw
+// SV_TARGET 5 xyzw 5 TARGET float xyzw
+// SV_DEPTH 0 N/A oDepth DEPTH float YES
+//
+ps_4_0
+dcl_constantbuffer CB0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output o2.xyzw
+dcl_output o3.xyzw
+dcl_output o4.xyzw
+dcl_output o5.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov o2.xyzw, cb0[0].xyzw
+mov o3.xyzw, cb0[0].xyzw
+mov o4.xyzw, cb0[0].xyzw
+mov o5.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret
+// Approximately 8 instruction slots used
+#endif
+
+const BYTE g_PS_ClearFloat6[] = {
+ 68, 88, 66, 67, 115, 157, 164, 56, 254, 153, 37, 126, 220, 182, 131, 196, 87, 71, 44,
+ 30, 1, 0, 0, 0, 208, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1,
+ 0, 0, 112, 1, 0, 0, 60, 2, 0, 0, 84, 3, 0, 0, 82, 68, 69, 70, 0,
+ 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104,
+ 68, 97, 116, 97, 70, 108, 111, 97, 116, 0, 171, 60, 0, 0, 0, 2, 0, 0, 0,
+ 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0,
+ 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0,
+ 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200,
+ 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 70, 108, 111, 97, 116, 0,
+ 1, 0, 3, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97,
+ 108, 117, 101, 70, 95, 70, 108, 111, 97, 116, 0, 171, 171, 0, 0, 3, 0, 1, 0,
+ 1, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0,
+ 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79,
+ 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 196, 0, 0, 0, 7, 0, 0, 0,
+ 8, 0, 0, 0, 176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0,
+ 0, 0, 0, 0, 0, 15, 0, 0, 0, 176, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 176, 0, 0, 0, 2,
+ 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0,
+ 176, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0,
+ 0, 15, 0, 0, 0, 176, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0,
+ 0, 0, 4, 0, 0, 0, 15, 0, 0, 0, 176, 0, 0, 0, 5, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 186, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 255, 255, 255, 255, 1, 14, 0,
+ 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 83, 86, 95, 68, 69, 80, 84, 72,
+ 0, 171, 83, 72, 68, 82, 16, 1, 0, 0, 64, 0, 0, 0, 68, 0, 0, 0, 89,
+ 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 101, 0, 0, 3,
+ 242, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0,
+ 0, 101, 0, 0, 3, 242, 32, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32,
+ 16, 0, 3, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 4, 0, 0, 0, 101,
+ 0, 0, 3, 242, 32, 16, 0, 5, 0, 0, 0, 101, 0, 0, 2, 1, 192, 0, 0,
+ 54, 0, 0, 6, 242, 32, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 1, 0, 0, 0, 70, 142,
+ 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 2,
+ 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6,
+ 242, 32, 16, 0, 3, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 54, 0, 0, 6, 242, 32, 16, 0, 4, 0, 0, 0, 70, 142, 32, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 5, 0, 0, 0, 70,
+ 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 1, 192, 0, 0,
+ 10, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65,
+ 84, 116, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 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, 0, 0, 0,
+ 0, 0, 0, 0, 0, 7, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps7.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps7.h
new file mode 100644
index 0000000000..048471ad6b
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps7.h
@@ -0,0 +1,122 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Buffer Definitions:
+//
+// cbuffer ColorAndDepthDataFloat
+// {
+//
+// float4 color_Float; // Offset: 0 Size: 16
+// float zValueF_Float; // Offset: 16 Size: 4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// ColorAndDepthDataFloat cbuffer NA NA cb0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+// SV_TARGET 1 xyzw 1 TARGET float xyzw
+// SV_TARGET 2 xyzw 2 TARGET float xyzw
+// SV_TARGET 3 xyzw 3 TARGET float xyzw
+// SV_TARGET 4 xyzw 4 TARGET float xyzw
+// SV_TARGET 5 xyzw 5 TARGET float xyzw
+// SV_TARGET 6 xyzw 6 TARGET float xyzw
+// SV_DEPTH 0 N/A oDepth DEPTH float YES
+//
+ps_4_0
+dcl_constantbuffer CB0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output o2.xyzw
+dcl_output o3.xyzw
+dcl_output o4.xyzw
+dcl_output o5.xyzw
+dcl_output o6.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov o2.xyzw, cb0[0].xyzw
+mov o3.xyzw, cb0[0].xyzw
+mov o4.xyzw, cb0[0].xyzw
+mov o5.xyzw, cb0[0].xyzw
+mov o6.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret
+// Approximately 9 instruction slots used
+#endif
+
+const BYTE g_PS_ClearFloat7[] = {
+ 68, 88, 66, 67, 142, 12, 138, 6, 10, 107, 58, 43, 178, 14, 208, 224, 48, 233, 91,
+ 50, 1, 0, 0, 0, 12, 4, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1,
+ 0, 0, 112, 1, 0, 0, 84, 2, 0, 0, 144, 3, 0, 0, 82, 68, 69, 70, 0,
+ 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104,
+ 68, 97, 116, 97, 70, 108, 111, 97, 116, 0, 171, 60, 0, 0, 0, 2, 0, 0, 0,
+ 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0,
+ 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0,
+ 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200,
+ 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 70, 108, 111, 97, 116, 0,
+ 1, 0, 3, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97,
+ 108, 117, 101, 70, 95, 70, 108, 111, 97, 116, 0, 171, 171, 0, 0, 3, 0, 1, 0,
+ 1, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0,
+ 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79,
+ 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 220, 0, 0, 0, 8, 0, 0, 0,
+ 8, 0, 0, 0, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0,
+ 0, 0, 0, 0, 0, 15, 0, 0, 0, 200, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 200, 0, 0, 0, 2,
+ 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0,
+ 200, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0,
+ 0, 15, 0, 0, 0, 200, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0,
+ 0, 0, 4, 0, 0, 0, 15, 0, 0, 0, 200, 0, 0, 0, 5, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 200, 0, 0, 0,
+ 6, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 15, 0, 0,
+ 0, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 255, 255,
+ 255, 255, 1, 14, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 83, 86, 95,
+ 68, 69, 80, 84, 72, 0, 171, 83, 72, 68, 82, 52, 1, 0, 0, 64, 0, 0, 0,
+ 77, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0,
+ 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32,
+ 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 2, 0, 0, 0, 101,
+ 0, 0, 3, 242, 32, 16, 0, 3, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0,
+ 4, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 5, 0, 0, 0, 101, 0, 0,
+ 3, 242, 32, 16, 0, 6, 0, 0, 0, 101, 0, 0, 2, 1, 192, 0, 0, 54, 0,
+ 0, 6, 242, 32, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 2, 0, 0,
+ 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32,
+ 16, 0, 3, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54,
+ 0, 0, 6, 242, 32, 16, 0, 4, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 5, 0, 0, 0, 70, 142, 32,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 6, 0,
+ 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 1,
+ 192, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 62, 0, 0, 1,
+ 83, 84, 65, 84, 116, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 8, 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,
+ 0, 0, 0, 0, 0, 0, 0, 0, 8, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps8.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps8.h
new file mode 100644
index 0000000000..b338868e18
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps8.h
@@ -0,0 +1,128 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Buffer Definitions:
+//
+// cbuffer ColorAndDepthDataFloat
+// {
+//
+// float4 color_Float; // Offset: 0 Size: 16
+// float zValueF_Float; // Offset: 16 Size: 4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// ColorAndDepthDataFloat cbuffer NA NA cb0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+// SV_TARGET 1 xyzw 1 TARGET float xyzw
+// SV_TARGET 2 xyzw 2 TARGET float xyzw
+// SV_TARGET 3 xyzw 3 TARGET float xyzw
+// SV_TARGET 4 xyzw 4 TARGET float xyzw
+// SV_TARGET 5 xyzw 5 TARGET float xyzw
+// SV_TARGET 6 xyzw 6 TARGET float xyzw
+// SV_TARGET 7 xyzw 7 TARGET float xyzw
+// SV_DEPTH 0 N/A oDepth DEPTH float YES
+//
+ps_4_0
+dcl_constantbuffer CB0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output o2.xyzw
+dcl_output o3.xyzw
+dcl_output o4.xyzw
+dcl_output o5.xyzw
+dcl_output o6.xyzw
+dcl_output o7.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov o2.xyzw, cb0[0].xyzw
+mov o3.xyzw, cb0[0].xyzw
+mov o4.xyzw, cb0[0].xyzw
+mov o5.xyzw, cb0[0].xyzw
+mov o6.xyzw, cb0[0].xyzw
+mov o7.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret
+// Approximately 10 instruction slots used
+#endif
+
+const BYTE g_PS_ClearFloat8[] = {
+ 68, 88, 66, 67, 228, 232, 153, 58, 173, 161, 124, 75, 45, 184, 173, 123, 62, 150, 36,
+ 145, 1, 0, 0, 0, 72, 4, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1,
+ 0, 0, 112, 1, 0, 0, 108, 2, 0, 0, 204, 3, 0, 0, 82, 68, 69, 70, 0,
+ 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104,
+ 68, 97, 116, 97, 70, 108, 111, 97, 116, 0, 171, 60, 0, 0, 0, 2, 0, 0, 0,
+ 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0,
+ 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0,
+ 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200,
+ 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 70, 108, 111, 97, 116, 0,
+ 1, 0, 3, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97,
+ 108, 117, 101, 70, 95, 70, 108, 111, 97, 116, 0, 171, 171, 0, 0, 3, 0, 1, 0,
+ 1, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0,
+ 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79,
+ 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 244, 0, 0, 0, 9, 0, 0, 0,
+ 8, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0,
+ 0, 0, 0, 0, 0, 15, 0, 0, 0, 224, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 224, 0, 0, 0, 2,
+ 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0,
+ 224, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0,
+ 0, 15, 0, 0, 0, 224, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0,
+ 0, 0, 4, 0, 0, 0, 15, 0, 0, 0, 224, 0, 0, 0, 5, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 224, 0, 0, 0,
+ 6, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 15, 0, 0,
+ 0, 224, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 7, 0,
+ 0, 0, 15, 0, 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 0, 0, 0, 255, 255, 255, 255, 1, 14, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69,
+ 84, 0, 83, 86, 95, 68, 69, 80, 84, 72, 0, 171, 83, 72, 68, 82, 88, 1, 0,
+ 0, 64, 0, 0, 0, 86, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0,
+ 0, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 101,
+ 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0,
+ 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 3, 0, 0, 0, 101, 0, 0,
+ 3, 242, 32, 16, 0, 4, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 5, 0,
+ 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 6, 0, 0, 0, 101, 0, 0, 3, 242,
+ 32, 16, 0, 7, 0, 0, 0, 101, 0, 0, 2, 1, 192, 0, 0, 54, 0, 0, 6,
+ 242, 32, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 54, 0, 0, 6, 242, 32, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 2, 0, 0, 0, 70,
+ 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0,
+ 3, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0,
+ 6, 242, 32, 16, 0, 4, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 5, 0, 0, 0, 70, 142, 32, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 6, 0, 0, 0,
+ 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16,
+ 0, 7, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0,
+ 0, 5, 1, 192, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 62,
+ 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 9, 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, 0, 0, 0, 0, 0, 0, 0, 0, 9, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps1.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps1.h
new file mode 100644
index 0000000000..d6139430ee
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps1.h
@@ -0,0 +1,85 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Buffer Definitions:
+//
+// cbuffer ColorAndDepthDataSint
+// {
+//
+// int4 color_Sint; // Offset: 0 Size: 16
+// float zValueF_Sint; // Offset: 16 Size: 4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// ColorAndDepthDataSint cbuffer NA NA cb0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET int xyzw
+// SV_DEPTH 0 N/A oDepth DEPTH float YES
+//
+ps_4_0
+dcl_constantbuffer CB0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret
+// Approximately 3 instruction slots used
+#endif
+
+const BYTE g_PS_ClearSint1[] = {
+ 68, 88, 66, 67, 231, 188, 2, 59, 91, 73, 220, 119, 245, 143, 245, 143, 240, 202, 170,
+ 163, 1, 0, 0, 0, 164, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1,
+ 0, 0, 112, 1, 0, 0, 196, 1, 0, 0, 40, 2, 0, 0, 82, 68, 69, 70, 0,
+ 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104,
+ 68, 97, 116, 97, 83, 105, 110, 116, 0, 171, 171, 60, 0, 0, 0, 2, 0, 0, 0,
+ 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0,
+ 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0,
+ 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200,
+ 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 83, 105, 110, 116, 0, 171,
+ 1, 0, 2, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97,
+ 108, 117, 101, 70, 95, 83, 105, 110, 116, 0, 171, 171, 171, 0, 0, 3, 0, 1, 0,
+ 1, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0,
+ 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79,
+ 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 76, 0, 0, 0, 2, 0, 0, 0,
+ 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0,
+ 0, 0, 0, 0, 0, 15, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 3, 0, 0, 0, 255, 255, 255, 255, 1, 14, 0, 0, 83, 86, 95, 84, 65,
+ 82, 71, 69, 84, 0, 83, 86, 95, 68, 69, 80, 84, 72, 0, 171, 83, 72, 68, 82,
+ 92, 0, 0, 0, 64, 0, 0, 0, 23, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32,
+ 0, 0, 0, 0, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0,
+ 0, 0, 101, 0, 0, 2, 1, 192, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 0,
+ 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5,
+ 1, 192, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 62, 0, 0,
+ 1, 83, 84, 65, 84, 116, 0, 0, 0, 3, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps2.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps2.h
new file mode 100644
index 0000000000..a7cc7221ce
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps2.h
@@ -0,0 +1,91 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Buffer Definitions:
+//
+// cbuffer ColorAndDepthDataSint
+// {
+//
+// int4 color_Sint; // Offset: 0 Size: 16
+// float zValueF_Sint; // Offset: 16 Size: 4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// ColorAndDepthDataSint cbuffer NA NA cb0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET int xyzw
+// SV_TARGET 1 xyzw 1 TARGET int xyzw
+// SV_DEPTH 0 N/A oDepth DEPTH float YES
+//
+ps_4_0
+dcl_constantbuffer CB0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_PS_ClearSint2[] = {
+ 68, 88, 66, 67, 85, 225, 210, 35, 166, 97, 84, 193, 114, 210, 51, 82, 238, 19, 251,
+ 198, 1, 0, 0, 0, 224, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1,
+ 0, 0, 112, 1, 0, 0, 220, 1, 0, 0, 100, 2, 0, 0, 82, 68, 69, 70, 0,
+ 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104,
+ 68, 97, 116, 97, 83, 105, 110, 116, 0, 171, 171, 60, 0, 0, 0, 2, 0, 0, 0,
+ 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0,
+ 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0,
+ 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200,
+ 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 83, 105, 110, 116, 0, 171,
+ 1, 0, 2, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97,
+ 108, 117, 101, 70, 95, 83, 105, 110, 116, 0, 171, 171, 171, 0, 0, 3, 0, 1, 0,
+ 1, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0,
+ 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79,
+ 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 100, 0, 0, 0, 3, 0, 0, 0,
+ 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0,
+ 0, 0, 0, 0, 0, 15, 0, 0, 0, 80, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 90, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 255, 255, 255, 255, 1, 14, 0, 0,
+ 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 83, 86, 95, 68, 69, 80, 84, 72, 0,
+ 171, 83, 72, 68, 82, 128, 0, 0, 0, 64, 0, 0, 0, 32, 0, 0, 0, 89, 0,
+ 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242,
+ 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0,
+ 101, 0, 0, 2, 1, 192, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 0, 0, 0,
+ 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32,
+ 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54,
+ 0, 0, 5, 1, 192, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+ 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 4, 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, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps3.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps3.h
new file mode 100644
index 0000000000..053de6d738
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps3.h
@@ -0,0 +1,97 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Buffer Definitions:
+//
+// cbuffer ColorAndDepthDataSint
+// {
+//
+// int4 color_Sint; // Offset: 0 Size: 16
+// float zValueF_Sint; // Offset: 16 Size: 4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// ColorAndDepthDataSint cbuffer NA NA cb0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET int xyzw
+// SV_TARGET 1 xyzw 1 TARGET int xyzw
+// SV_TARGET 2 xyzw 2 TARGET int xyzw
+// SV_DEPTH 0 N/A oDepth DEPTH float YES
+//
+ps_4_0
+dcl_constantbuffer CB0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output o2.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov o2.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret
+// Approximately 5 instruction slots used
+#endif
+
+const BYTE g_PS_ClearSint3[] = {
+ 68, 88, 66, 67, 101, 236, 110, 148, 64, 148, 5, 108, 246, 70, 148, 1, 36, 90, 92,
+ 9, 1, 0, 0, 0, 28, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1,
+ 0, 0, 112, 1, 0, 0, 244, 1, 0, 0, 160, 2, 0, 0, 82, 68, 69, 70, 0,
+ 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104,
+ 68, 97, 116, 97, 83, 105, 110, 116, 0, 171, 171, 60, 0, 0, 0, 2, 0, 0, 0,
+ 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0,
+ 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0,
+ 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200,
+ 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 83, 105, 110, 116, 0, 171,
+ 1, 0, 2, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97,
+ 108, 117, 101, 70, 95, 83, 105, 110, 116, 0, 171, 171, 171, 0, 0, 3, 0, 1, 0,
+ 1, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0,
+ 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79,
+ 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 124, 0, 0, 0, 4, 0, 0, 0,
+ 8, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0,
+ 0, 0, 0, 0, 0, 15, 0, 0, 0, 104, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 104, 0, 0, 0, 2,
+ 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0,
+ 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 255, 255, 255,
+ 255, 1, 14, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 83, 86, 95, 68,
+ 69, 80, 84, 72, 0, 171, 83, 72, 68, 82, 164, 0, 0, 0, 64, 0, 0, 0, 41,
+ 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0,
+ 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16,
+ 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 2, 0, 0, 0, 101, 0,
+ 0, 2, 1, 192, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 0, 0, 0, 0, 70,
+ 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0,
+ 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0,
+ 6, 242, 32, 16, 0, 2, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 54, 0, 0, 5, 1, 192, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 1,
+ 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 5, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 4, 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, 0, 0, 0, 0, 0, 0, 0, 0, 4, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps4.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps4.h
new file mode 100644
index 0000000000..134f6253ee
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps4.h
@@ -0,0 +1,104 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Buffer Definitions:
+//
+// cbuffer ColorAndDepthDataSint
+// {
+//
+// int4 color_Sint; // Offset: 0 Size: 16
+// float zValueF_Sint; // Offset: 16 Size: 4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// ColorAndDepthDataSint cbuffer NA NA cb0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET int xyzw
+// SV_TARGET 1 xyzw 1 TARGET int xyzw
+// SV_TARGET 2 xyzw 2 TARGET int xyzw
+// SV_TARGET 3 xyzw 3 TARGET int xyzw
+// SV_DEPTH 0 N/A oDepth DEPTH float YES
+//
+ps_4_0
+dcl_constantbuffer CB0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output o2.xyzw
+dcl_output o3.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov o2.xyzw, cb0[0].xyzw
+mov o3.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret
+// Approximately 6 instruction slots used
+#endif
+
+const BYTE g_PS_ClearSint4[] = {
+ 68, 88, 66, 67, 206, 59, 157, 191, 139, 37, 109, 85, 193, 141, 185, 200, 81, 149, 0,
+ 246, 1, 0, 0, 0, 88, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1,
+ 0, 0, 112, 1, 0, 0, 12, 2, 0, 0, 220, 2, 0, 0, 82, 68, 69, 70, 0,
+ 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104,
+ 68, 97, 116, 97, 83, 105, 110, 116, 0, 171, 171, 60, 0, 0, 0, 2, 0, 0, 0,
+ 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0,
+ 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0,
+ 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200,
+ 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 83, 105, 110, 116, 0, 171,
+ 1, 0, 2, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97,
+ 108, 117, 101, 70, 95, 83, 105, 110, 116, 0, 171, 171, 171, 0, 0, 3, 0, 1, 0,
+ 1, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0,
+ 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79,
+ 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 148, 0, 0, 0, 5, 0, 0, 0,
+ 8, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0,
+ 0, 0, 0, 0, 0, 15, 0, 0, 0, 128, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 128, 0, 0, 0, 2,
+ 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0,
+ 128, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0,
+ 0, 15, 0, 0, 0, 138, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0,
+ 0, 0, 255, 255, 255, 255, 1, 14, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84,
+ 0, 83, 86, 95, 68, 69, 80, 84, 72, 0, 171, 83, 72, 68, 82, 200, 0, 0, 0,
+ 64, 0, 0, 0, 50, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0,
+ 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 101, 0,
+ 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 2,
+ 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 3, 0, 0, 0, 101, 0, 0, 2,
+ 1, 192, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 0, 0, 0, 0, 70, 142, 32,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 1, 0,
+ 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242,
+ 32, 16, 0, 2, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 54, 0, 0, 6, 242, 32, 16, 0, 3, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 54, 0, 0, 5, 1, 192, 0, 0, 10, 128, 32, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 6,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 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, 0, 0, 0, 0, 0, 0, 0, 0, 5,
+ 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps5.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps5.h
new file mode 100644
index 0000000000..3466e72460
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps5.h
@@ -0,0 +1,110 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Buffer Definitions:
+//
+// cbuffer ColorAndDepthDataSint
+// {
+//
+// int4 color_Sint; // Offset: 0 Size: 16
+// float zValueF_Sint; // Offset: 16 Size: 4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// ColorAndDepthDataSint cbuffer NA NA cb0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET int xyzw
+// SV_TARGET 1 xyzw 1 TARGET int xyzw
+// SV_TARGET 2 xyzw 2 TARGET int xyzw
+// SV_TARGET 3 xyzw 3 TARGET int xyzw
+// SV_TARGET 4 xyzw 4 TARGET int xyzw
+// SV_DEPTH 0 N/A oDepth DEPTH float YES
+//
+ps_4_0
+dcl_constantbuffer CB0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output o2.xyzw
+dcl_output o3.xyzw
+dcl_output o4.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov o2.xyzw, cb0[0].xyzw
+mov o3.xyzw, cb0[0].xyzw
+mov o4.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret
+// Approximately 7 instruction slots used
+#endif
+
+const BYTE g_PS_ClearSint5[] = {
+ 68, 88, 66, 67, 91, 91, 66, 76, 160, 92, 0, 147, 5, 30, 128, 248, 1, 125, 140,
+ 124, 1, 0, 0, 0, 148, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1,
+ 0, 0, 112, 1, 0, 0, 36, 2, 0, 0, 24, 3, 0, 0, 82, 68, 69, 70, 0,
+ 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104,
+ 68, 97, 116, 97, 83, 105, 110, 116, 0, 171, 171, 60, 0, 0, 0, 2, 0, 0, 0,
+ 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0,
+ 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0,
+ 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200,
+ 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 83, 105, 110, 116, 0, 171,
+ 1, 0, 2, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97,
+ 108, 117, 101, 70, 95, 83, 105, 110, 116, 0, 171, 171, 171, 0, 0, 3, 0, 1, 0,
+ 1, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0,
+ 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79,
+ 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 172, 0, 0, 0, 6, 0, 0, 0,
+ 8, 0, 0, 0, 152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0,
+ 0, 0, 0, 0, 0, 15, 0, 0, 0, 152, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 152, 0, 0, 0, 2,
+ 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0,
+ 152, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0,
+ 0, 15, 0, 0, 0, 152, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 2, 0,
+ 0, 0, 4, 0, 0, 0, 15, 0, 0, 0, 162, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 255, 255, 255, 255, 1, 14, 0, 0, 83, 86, 95, 84,
+ 65, 82, 71, 69, 84, 0, 83, 86, 95, 68, 69, 80, 84, 72, 0, 171, 83, 72, 68,
+ 82, 236, 0, 0, 0, 64, 0, 0, 0, 59, 0, 0, 0, 89, 0, 0, 4, 70, 142,
+ 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0,
+ 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3,
+ 242, 32, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 3, 0, 0,
+ 0, 101, 0, 0, 3, 242, 32, 16, 0, 4, 0, 0, 0, 101, 0, 0, 2, 1, 192,
+ 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 1, 0, 0, 0,
+ 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16,
+ 0, 2, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0,
+ 0, 6, 242, 32, 16, 0, 3, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 4, 0, 0, 0, 70, 142, 32, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 1, 192, 0, 0, 10, 128, 32,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0,
+ 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 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, 0, 0, 0, 0, 0, 0,
+ 0, 0, 6, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps6.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps6.h
new file mode 100644
index 0000000000..b54bcf1fea
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps6.h
@@ -0,0 +1,116 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Buffer Definitions:
+//
+// cbuffer ColorAndDepthDataSint
+// {
+//
+// int4 color_Sint; // Offset: 0 Size: 16
+// float zValueF_Sint; // Offset: 16 Size: 4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// ColorAndDepthDataSint cbuffer NA NA cb0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET int xyzw
+// SV_TARGET 1 xyzw 1 TARGET int xyzw
+// SV_TARGET 2 xyzw 2 TARGET int xyzw
+// SV_TARGET 3 xyzw 3 TARGET int xyzw
+// SV_TARGET 4 xyzw 4 TARGET int xyzw
+// SV_TARGET 5 xyzw 5 TARGET int xyzw
+// SV_DEPTH 0 N/A oDepth DEPTH float YES
+//
+ps_4_0
+dcl_constantbuffer CB0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output o2.xyzw
+dcl_output o3.xyzw
+dcl_output o4.xyzw
+dcl_output o5.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov o2.xyzw, cb0[0].xyzw
+mov o3.xyzw, cb0[0].xyzw
+mov o4.xyzw, cb0[0].xyzw
+mov o5.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret
+// Approximately 8 instruction slots used
+#endif
+
+const BYTE g_PS_ClearSint6[] = {
+ 68, 88, 66, 67, 245, 94, 2, 129, 134, 247, 241, 8, 253, 220, 200, 172, 215, 17, 127,
+ 35, 1, 0, 0, 0, 208, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1,
+ 0, 0, 112, 1, 0, 0, 60, 2, 0, 0, 84, 3, 0, 0, 82, 68, 69, 70, 0,
+ 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104,
+ 68, 97, 116, 97, 83, 105, 110, 116, 0, 171, 171, 60, 0, 0, 0, 2, 0, 0, 0,
+ 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0,
+ 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0,
+ 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200,
+ 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 83, 105, 110, 116, 0, 171,
+ 1, 0, 2, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97,
+ 108, 117, 101, 70, 95, 83, 105, 110, 116, 0, 171, 171, 171, 0, 0, 3, 0, 1, 0,
+ 1, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0,
+ 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79,
+ 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 196, 0, 0, 0, 7, 0, 0, 0,
+ 8, 0, 0, 0, 176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0,
+ 0, 0, 0, 0, 0, 15, 0, 0, 0, 176, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 176, 0, 0, 0, 2,
+ 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0,
+ 176, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0,
+ 0, 15, 0, 0, 0, 176, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 2, 0,
+ 0, 0, 4, 0, 0, 0, 15, 0, 0, 0, 176, 0, 0, 0, 5, 0, 0, 0, 0,
+ 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 186, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 255, 255, 255, 255, 1, 14, 0,
+ 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 83, 86, 95, 68, 69, 80, 84, 72,
+ 0, 171, 83, 72, 68, 82, 16, 1, 0, 0, 64, 0, 0, 0, 68, 0, 0, 0, 89,
+ 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 101, 0, 0, 3,
+ 242, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0,
+ 0, 101, 0, 0, 3, 242, 32, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32,
+ 16, 0, 3, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 4, 0, 0, 0, 101,
+ 0, 0, 3, 242, 32, 16, 0, 5, 0, 0, 0, 101, 0, 0, 2, 1, 192, 0, 0,
+ 54, 0, 0, 6, 242, 32, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 1, 0, 0, 0, 70, 142,
+ 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 2,
+ 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6,
+ 242, 32, 16, 0, 3, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 54, 0, 0, 6, 242, 32, 16, 0, 4, 0, 0, 0, 70, 142, 32, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 5, 0, 0, 0, 70,
+ 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 1, 192, 0, 0,
+ 10, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65,
+ 84, 116, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 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, 0, 0, 0,
+ 0, 0, 0, 0, 0, 7, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps7.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps7.h
new file mode 100644
index 0000000000..0c7755d295
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps7.h
@@ -0,0 +1,122 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Buffer Definitions:
+//
+// cbuffer ColorAndDepthDataSint
+// {
+//
+// int4 color_Sint; // Offset: 0 Size: 16
+// float zValueF_Sint; // Offset: 16 Size: 4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// ColorAndDepthDataSint cbuffer NA NA cb0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET int xyzw
+// SV_TARGET 1 xyzw 1 TARGET int xyzw
+// SV_TARGET 2 xyzw 2 TARGET int xyzw
+// SV_TARGET 3 xyzw 3 TARGET int xyzw
+// SV_TARGET 4 xyzw 4 TARGET int xyzw
+// SV_TARGET 5 xyzw 5 TARGET int xyzw
+// SV_TARGET 6 xyzw 6 TARGET int xyzw
+// SV_DEPTH 0 N/A oDepth DEPTH float YES
+//
+ps_4_0
+dcl_constantbuffer CB0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output o2.xyzw
+dcl_output o3.xyzw
+dcl_output o4.xyzw
+dcl_output o5.xyzw
+dcl_output o6.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov o2.xyzw, cb0[0].xyzw
+mov o3.xyzw, cb0[0].xyzw
+mov o4.xyzw, cb0[0].xyzw
+mov o5.xyzw, cb0[0].xyzw
+mov o6.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret
+// Approximately 9 instruction slots used
+#endif
+
+const BYTE g_PS_ClearSint7[] = {
+ 68, 88, 66, 67, 203, 48, 20, 196, 108, 146, 109, 165, 143, 63, 145, 150, 29, 34, 214,
+ 22, 1, 0, 0, 0, 12, 4, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1,
+ 0, 0, 112, 1, 0, 0, 84, 2, 0, 0, 144, 3, 0, 0, 82, 68, 69, 70, 0,
+ 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104,
+ 68, 97, 116, 97, 83, 105, 110, 116, 0, 171, 171, 60, 0, 0, 0, 2, 0, 0, 0,
+ 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0,
+ 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0,
+ 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200,
+ 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 83, 105, 110, 116, 0, 171,
+ 1, 0, 2, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97,
+ 108, 117, 101, 70, 95, 83, 105, 110, 116, 0, 171, 171, 171, 0, 0, 3, 0, 1, 0,
+ 1, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0,
+ 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79,
+ 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 220, 0, 0, 0, 8, 0, 0, 0,
+ 8, 0, 0, 0, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0,
+ 0, 0, 0, 0, 0, 15, 0, 0, 0, 200, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 200, 0, 0, 0, 2,
+ 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0,
+ 200, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0,
+ 0, 15, 0, 0, 0, 200, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 2, 0,
+ 0, 0, 4, 0, 0, 0, 15, 0, 0, 0, 200, 0, 0, 0, 5, 0, 0, 0, 0,
+ 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 200, 0, 0, 0,
+ 6, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 15, 0, 0,
+ 0, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 255, 255,
+ 255, 255, 1, 14, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 83, 86, 95,
+ 68, 69, 80, 84, 72, 0, 171, 83, 72, 68, 82, 52, 1, 0, 0, 64, 0, 0, 0,
+ 77, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0,
+ 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32,
+ 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 2, 0, 0, 0, 101,
+ 0, 0, 3, 242, 32, 16, 0, 3, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0,
+ 4, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 5, 0, 0, 0, 101, 0, 0,
+ 3, 242, 32, 16, 0, 6, 0, 0, 0, 101, 0, 0, 2, 1, 192, 0, 0, 54, 0,
+ 0, 6, 242, 32, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 2, 0, 0,
+ 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32,
+ 16, 0, 3, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54,
+ 0, 0, 6, 242, 32, 16, 0, 4, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 5, 0, 0, 0, 70, 142, 32,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 6, 0,
+ 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 1,
+ 192, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 62, 0, 0, 1,
+ 83, 84, 65, 84, 116, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 8, 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,
+ 0, 0, 0, 0, 0, 0, 0, 0, 8, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps8.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps8.h
new file mode 100644
index 0000000000..10e77dfcc3
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps8.h
@@ -0,0 +1,128 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Buffer Definitions:
+//
+// cbuffer ColorAndDepthDataSint
+// {
+//
+// int4 color_Sint; // Offset: 0 Size: 16
+// float zValueF_Sint; // Offset: 16 Size: 4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// ColorAndDepthDataSint cbuffer NA NA cb0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET int xyzw
+// SV_TARGET 1 xyzw 1 TARGET int xyzw
+// SV_TARGET 2 xyzw 2 TARGET int xyzw
+// SV_TARGET 3 xyzw 3 TARGET int xyzw
+// SV_TARGET 4 xyzw 4 TARGET int xyzw
+// SV_TARGET 5 xyzw 5 TARGET int xyzw
+// SV_TARGET 6 xyzw 6 TARGET int xyzw
+// SV_TARGET 7 xyzw 7 TARGET int xyzw
+// SV_DEPTH 0 N/A oDepth DEPTH float YES
+//
+ps_4_0
+dcl_constantbuffer CB0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output o2.xyzw
+dcl_output o3.xyzw
+dcl_output o4.xyzw
+dcl_output o5.xyzw
+dcl_output o6.xyzw
+dcl_output o7.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov o2.xyzw, cb0[0].xyzw
+mov o3.xyzw, cb0[0].xyzw
+mov o4.xyzw, cb0[0].xyzw
+mov o5.xyzw, cb0[0].xyzw
+mov o6.xyzw, cb0[0].xyzw
+mov o7.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret
+// Approximately 10 instruction slots used
+#endif
+
+const BYTE g_PS_ClearSint8[] = {
+ 68, 88, 66, 67, 199, 7, 207, 179, 143, 119, 139, 38, 92, 223, 215, 110, 33, 171, 222,
+ 186, 1, 0, 0, 0, 72, 4, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1,
+ 0, 0, 112, 1, 0, 0, 108, 2, 0, 0, 204, 3, 0, 0, 82, 68, 69, 70, 0,
+ 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104,
+ 68, 97, 116, 97, 83, 105, 110, 116, 0, 171, 171, 60, 0, 0, 0, 2, 0, 0, 0,
+ 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0,
+ 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0,
+ 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200,
+ 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 83, 105, 110, 116, 0, 171,
+ 1, 0, 2, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97,
+ 108, 117, 101, 70, 95, 83, 105, 110, 116, 0, 171, 171, 171, 0, 0, 3, 0, 1, 0,
+ 1, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0,
+ 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79,
+ 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 244, 0, 0, 0, 9, 0, 0, 0,
+ 8, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0,
+ 0, 0, 0, 0, 0, 15, 0, 0, 0, 224, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 224, 0, 0, 0, 2,
+ 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0,
+ 224, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0,
+ 0, 15, 0, 0, 0, 224, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 2, 0,
+ 0, 0, 4, 0, 0, 0, 15, 0, 0, 0, 224, 0, 0, 0, 5, 0, 0, 0, 0,
+ 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 224, 0, 0, 0,
+ 6, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 15, 0, 0,
+ 0, 224, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0,
+ 0, 0, 15, 0, 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 0, 0, 0, 255, 255, 255, 255, 1, 14, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69,
+ 84, 0, 83, 86, 95, 68, 69, 80, 84, 72, 0, 171, 83, 72, 68, 82, 88, 1, 0,
+ 0, 64, 0, 0, 0, 86, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0,
+ 0, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 101,
+ 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0,
+ 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 3, 0, 0, 0, 101, 0, 0,
+ 3, 242, 32, 16, 0, 4, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 5, 0,
+ 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 6, 0, 0, 0, 101, 0, 0, 3, 242,
+ 32, 16, 0, 7, 0, 0, 0, 101, 0, 0, 2, 1, 192, 0, 0, 54, 0, 0, 6,
+ 242, 32, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 54, 0, 0, 6, 242, 32, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 2, 0, 0, 0, 70,
+ 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0,
+ 3, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0,
+ 6, 242, 32, 16, 0, 4, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 5, 0, 0, 0, 70, 142, 32, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 6, 0, 0, 0,
+ 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16,
+ 0, 7, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0,
+ 0, 5, 1, 192, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 62,
+ 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 9, 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, 0, 0, 0, 0, 0, 0, 0, 0, 9, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps1.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps1.h
new file mode 100644
index 0000000000..10f1a56e51
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps1.h
@@ -0,0 +1,85 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Buffer Definitions:
+//
+// cbuffer ColorAndDepthDataUint
+// {
+//
+// uint4 color_Uint; // Offset: 0 Size: 16
+// float zValueF_Uint; // Offset: 16 Size: 4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// ColorAndDepthDataUint cbuffer NA NA cb0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET uint xyzw
+// SV_DEPTH 0 N/A oDepth DEPTH float YES
+//
+ps_4_0
+dcl_constantbuffer CB0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret
+// Approximately 3 instruction slots used
+#endif
+
+const BYTE g_PS_ClearUint1[] = {
+ 68, 88, 66, 67, 153, 3, 197, 234, 233, 241, 61, 147, 138, 167, 150, 193, 156, 181, 197,
+ 213, 1, 0, 0, 0, 164, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1,
+ 0, 0, 112, 1, 0, 0, 196, 1, 0, 0, 40, 2, 0, 0, 82, 68, 69, 70, 0,
+ 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104,
+ 68, 97, 116, 97, 85, 105, 110, 116, 0, 171, 171, 60, 0, 0, 0, 2, 0, 0, 0,
+ 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0,
+ 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0,
+ 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200,
+ 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 85, 105, 110, 116, 0, 171,
+ 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97,
+ 108, 117, 101, 70, 95, 85, 105, 110, 116, 0, 171, 171, 171, 0, 0, 3, 0, 1, 0,
+ 1, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0,
+ 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79,
+ 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 76, 0, 0, 0, 2, 0, 0, 0,
+ 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0, 15, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 3, 0, 0, 0, 255, 255, 255, 255, 1, 14, 0, 0, 83, 86, 95, 84, 65,
+ 82, 71, 69, 84, 0, 83, 86, 95, 68, 69, 80, 84, 72, 0, 171, 83, 72, 68, 82,
+ 92, 0, 0, 0, 64, 0, 0, 0, 23, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32,
+ 0, 0, 0, 0, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0,
+ 0, 0, 101, 0, 0, 2, 1, 192, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 0,
+ 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5,
+ 1, 192, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 62, 0, 0,
+ 1, 83, 84, 65, 84, 116, 0, 0, 0, 3, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps2.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps2.h
new file mode 100644
index 0000000000..8c94b388f9
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps2.h
@@ -0,0 +1,91 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Buffer Definitions:
+//
+// cbuffer ColorAndDepthDataUint
+// {
+//
+// uint4 color_Uint; // Offset: 0 Size: 16
+// float zValueF_Uint; // Offset: 16 Size: 4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// ColorAndDepthDataUint cbuffer NA NA cb0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET uint xyzw
+// SV_TARGET 1 xyzw 1 TARGET uint xyzw
+// SV_DEPTH 0 N/A oDepth DEPTH float YES
+//
+ps_4_0
+dcl_constantbuffer CB0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_PS_ClearUint2[] = {
+ 68, 88, 66, 67, 192, 246, 30, 248, 11, 186, 26, 252, 71, 98, 86, 143, 152, 241, 57,
+ 66, 1, 0, 0, 0, 224, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1,
+ 0, 0, 112, 1, 0, 0, 220, 1, 0, 0, 100, 2, 0, 0, 82, 68, 69, 70, 0,
+ 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104,
+ 68, 97, 116, 97, 85, 105, 110, 116, 0, 171, 171, 60, 0, 0, 0, 2, 0, 0, 0,
+ 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0,
+ 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0,
+ 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200,
+ 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 85, 105, 110, 116, 0, 171,
+ 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97,
+ 108, 117, 101, 70, 95, 85, 105, 110, 116, 0, 171, 171, 171, 0, 0, 3, 0, 1, 0,
+ 1, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0,
+ 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79,
+ 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 100, 0, 0, 0, 3, 0, 0, 0,
+ 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0, 15, 0, 0, 0, 80, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 90, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 255, 255, 255, 255, 1, 14, 0, 0,
+ 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 83, 86, 95, 68, 69, 80, 84, 72, 0,
+ 171, 83, 72, 68, 82, 128, 0, 0, 0, 64, 0, 0, 0, 32, 0, 0, 0, 89, 0,
+ 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242,
+ 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0,
+ 101, 0, 0, 2, 1, 192, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 0, 0, 0,
+ 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32,
+ 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54,
+ 0, 0, 5, 1, 192, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+ 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 4, 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, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps3.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps3.h
new file mode 100644
index 0000000000..3c31a85656
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps3.h
@@ -0,0 +1,97 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Buffer Definitions:
+//
+// cbuffer ColorAndDepthDataUint
+// {
+//
+// uint4 color_Uint; // Offset: 0 Size: 16
+// float zValueF_Uint; // Offset: 16 Size: 4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// ColorAndDepthDataUint cbuffer NA NA cb0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET uint xyzw
+// SV_TARGET 1 xyzw 1 TARGET uint xyzw
+// SV_TARGET 2 xyzw 2 TARGET uint xyzw
+// SV_DEPTH 0 N/A oDepth DEPTH float YES
+//
+ps_4_0
+dcl_constantbuffer CB0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output o2.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov o2.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret
+// Approximately 5 instruction slots used
+#endif
+
+const BYTE g_PS_ClearUint3[] = {
+ 68, 88, 66, 67, 122, 152, 146, 15, 20, 60, 207, 219, 181, 233, 35, 208, 96, 171, 60,
+ 29, 1, 0, 0, 0, 28, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1,
+ 0, 0, 112, 1, 0, 0, 244, 1, 0, 0, 160, 2, 0, 0, 82, 68, 69, 70, 0,
+ 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104,
+ 68, 97, 116, 97, 85, 105, 110, 116, 0, 171, 171, 60, 0, 0, 0, 2, 0, 0, 0,
+ 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0,
+ 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0,
+ 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200,
+ 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 85, 105, 110, 116, 0, 171,
+ 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97,
+ 108, 117, 101, 70, 95, 85, 105, 110, 116, 0, 171, 171, 171, 0, 0, 3, 0, 1, 0,
+ 1, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0,
+ 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79,
+ 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 124, 0, 0, 0, 4, 0, 0, 0,
+ 8, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0, 15, 0, 0, 0, 104, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 104, 0, 0, 0, 2,
+ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0,
+ 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 255, 255, 255,
+ 255, 1, 14, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 83, 86, 95, 68,
+ 69, 80, 84, 72, 0, 171, 83, 72, 68, 82, 164, 0, 0, 0, 64, 0, 0, 0, 41,
+ 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0,
+ 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16,
+ 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 2, 0, 0, 0, 101, 0,
+ 0, 2, 1, 192, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 0, 0, 0, 0, 70,
+ 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0,
+ 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0,
+ 6, 242, 32, 16, 0, 2, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 54, 0, 0, 5, 1, 192, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 1,
+ 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 5, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 4, 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, 0, 0, 0, 0, 0, 0, 0, 0, 4, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps4.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps4.h
new file mode 100644
index 0000000000..722f1f0acc
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps4.h
@@ -0,0 +1,104 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Buffer Definitions:
+//
+// cbuffer ColorAndDepthDataUint
+// {
+//
+// uint4 color_Uint; // Offset: 0 Size: 16
+// float zValueF_Uint; // Offset: 16 Size: 4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// ColorAndDepthDataUint cbuffer NA NA cb0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET uint xyzw
+// SV_TARGET 1 xyzw 1 TARGET uint xyzw
+// SV_TARGET 2 xyzw 2 TARGET uint xyzw
+// SV_TARGET 3 xyzw 3 TARGET uint xyzw
+// SV_DEPTH 0 N/A oDepth DEPTH float YES
+//
+ps_4_0
+dcl_constantbuffer CB0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output o2.xyzw
+dcl_output o3.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov o2.xyzw, cb0[0].xyzw
+mov o3.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret
+// Approximately 6 instruction slots used
+#endif
+
+const BYTE g_PS_ClearUint4[] = {
+ 68, 88, 66, 67, 255, 94, 158, 125, 94, 174, 68, 246, 120, 231, 8, 70, 114, 202, 111,
+ 31, 1, 0, 0, 0, 88, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1,
+ 0, 0, 112, 1, 0, 0, 12, 2, 0, 0, 220, 2, 0, 0, 82, 68, 69, 70, 0,
+ 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104,
+ 68, 97, 116, 97, 85, 105, 110, 116, 0, 171, 171, 60, 0, 0, 0, 2, 0, 0, 0,
+ 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0,
+ 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0,
+ 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200,
+ 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 85, 105, 110, 116, 0, 171,
+ 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97,
+ 108, 117, 101, 70, 95, 85, 105, 110, 116, 0, 171, 171, 171, 0, 0, 3, 0, 1, 0,
+ 1, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0,
+ 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79,
+ 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 148, 0, 0, 0, 5, 0, 0, 0,
+ 8, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0, 15, 0, 0, 0, 128, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 128, 0, 0, 0, 2,
+ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0,
+ 128, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0,
+ 0, 15, 0, 0, 0, 138, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0,
+ 0, 0, 255, 255, 255, 255, 1, 14, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84,
+ 0, 83, 86, 95, 68, 69, 80, 84, 72, 0, 171, 83, 72, 68, 82, 200, 0, 0, 0,
+ 64, 0, 0, 0, 50, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0,
+ 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 101, 0,
+ 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 2,
+ 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 3, 0, 0, 0, 101, 0, 0, 2,
+ 1, 192, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 0, 0, 0, 0, 70, 142, 32,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 1, 0,
+ 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242,
+ 32, 16, 0, 2, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 54, 0, 0, 6, 242, 32, 16, 0, 3, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 54, 0, 0, 5, 1, 192, 0, 0, 10, 128, 32, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 6,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 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, 0, 0, 0, 0, 0, 0, 0, 0, 5,
+ 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps5.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps5.h
new file mode 100644
index 0000000000..d387a76848
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps5.h
@@ -0,0 +1,110 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Buffer Definitions:
+//
+// cbuffer ColorAndDepthDataUint
+// {
+//
+// uint4 color_Uint; // Offset: 0 Size: 16
+// float zValueF_Uint; // Offset: 16 Size: 4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// ColorAndDepthDataUint cbuffer NA NA cb0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET uint xyzw
+// SV_TARGET 1 xyzw 1 TARGET uint xyzw
+// SV_TARGET 2 xyzw 2 TARGET uint xyzw
+// SV_TARGET 3 xyzw 3 TARGET uint xyzw
+// SV_TARGET 4 xyzw 4 TARGET uint xyzw
+// SV_DEPTH 0 N/A oDepth DEPTH float YES
+//
+ps_4_0
+dcl_constantbuffer CB0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output o2.xyzw
+dcl_output o3.xyzw
+dcl_output o4.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov o2.xyzw, cb0[0].xyzw
+mov o3.xyzw, cb0[0].xyzw
+mov o4.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret
+// Approximately 7 instruction slots used
+#endif
+
+const BYTE g_PS_ClearUint5[] = {
+ 68, 88, 66, 67, 208, 22, 91, 140, 204, 34, 72, 161, 50, 27, 2, 156, 220, 29, 44,
+ 80, 1, 0, 0, 0, 148, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1,
+ 0, 0, 112, 1, 0, 0, 36, 2, 0, 0, 24, 3, 0, 0, 82, 68, 69, 70, 0,
+ 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104,
+ 68, 97, 116, 97, 85, 105, 110, 116, 0, 171, 171, 60, 0, 0, 0, 2, 0, 0, 0,
+ 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0,
+ 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0,
+ 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200,
+ 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 85, 105, 110, 116, 0, 171,
+ 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97,
+ 108, 117, 101, 70, 95, 85, 105, 110, 116, 0, 171, 171, 171, 0, 0, 3, 0, 1, 0,
+ 1, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0,
+ 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79,
+ 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 172, 0, 0, 0, 6, 0, 0, 0,
+ 8, 0, 0, 0, 152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0, 15, 0, 0, 0, 152, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 152, 0, 0, 0, 2,
+ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0,
+ 152, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0,
+ 0, 15, 0, 0, 0, 152, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 4, 0, 0, 0, 15, 0, 0, 0, 162, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 255, 255, 255, 255, 1, 14, 0, 0, 83, 86, 95, 84,
+ 65, 82, 71, 69, 84, 0, 83, 86, 95, 68, 69, 80, 84, 72, 0, 171, 83, 72, 68,
+ 82, 236, 0, 0, 0, 64, 0, 0, 0, 59, 0, 0, 0, 89, 0, 0, 4, 70, 142,
+ 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0,
+ 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3,
+ 242, 32, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 3, 0, 0,
+ 0, 101, 0, 0, 3, 242, 32, 16, 0, 4, 0, 0, 0, 101, 0, 0, 2, 1, 192,
+ 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 1, 0, 0, 0,
+ 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16,
+ 0, 2, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0,
+ 0, 6, 242, 32, 16, 0, 3, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 4, 0, 0, 0, 70, 142, 32, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 1, 192, 0, 0, 10, 128, 32,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0,
+ 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 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, 0, 0, 0, 0, 0, 0,
+ 0, 0, 6, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps6.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps6.h
new file mode 100644
index 0000000000..b3dce8228d
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps6.h
@@ -0,0 +1,116 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Buffer Definitions:
+//
+// cbuffer ColorAndDepthDataUint
+// {
+//
+// uint4 color_Uint; // Offset: 0 Size: 16
+// float zValueF_Uint; // Offset: 16 Size: 4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// ColorAndDepthDataUint cbuffer NA NA cb0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET uint xyzw
+// SV_TARGET 1 xyzw 1 TARGET uint xyzw
+// SV_TARGET 2 xyzw 2 TARGET uint xyzw
+// SV_TARGET 3 xyzw 3 TARGET uint xyzw
+// SV_TARGET 4 xyzw 4 TARGET uint xyzw
+// SV_TARGET 5 xyzw 5 TARGET uint xyzw
+// SV_DEPTH 0 N/A oDepth DEPTH float YES
+//
+ps_4_0
+dcl_constantbuffer CB0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output o2.xyzw
+dcl_output o3.xyzw
+dcl_output o4.xyzw
+dcl_output o5.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov o2.xyzw, cb0[0].xyzw
+mov o3.xyzw, cb0[0].xyzw
+mov o4.xyzw, cb0[0].xyzw
+mov o5.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret
+// Approximately 8 instruction slots used
+#endif
+
+const BYTE g_PS_ClearUint6[] = {
+ 68, 88, 66, 67, 78, 113, 96, 10, 75, 203, 142, 20, 121, 52, 202, 19, 182, 137, 113,
+ 117, 1, 0, 0, 0, 208, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1,
+ 0, 0, 112, 1, 0, 0, 60, 2, 0, 0, 84, 3, 0, 0, 82, 68, 69, 70, 0,
+ 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104,
+ 68, 97, 116, 97, 85, 105, 110, 116, 0, 171, 171, 60, 0, 0, 0, 2, 0, 0, 0,
+ 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0,
+ 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0,
+ 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200,
+ 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 85, 105, 110, 116, 0, 171,
+ 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97,
+ 108, 117, 101, 70, 95, 85, 105, 110, 116, 0, 171, 171, 171, 0, 0, 3, 0, 1, 0,
+ 1, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0,
+ 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79,
+ 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 196, 0, 0, 0, 7, 0, 0, 0,
+ 8, 0, 0, 0, 176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0, 15, 0, 0, 0, 176, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 176, 0, 0, 0, 2,
+ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0,
+ 176, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0,
+ 0, 15, 0, 0, 0, 176, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 4, 0, 0, 0, 15, 0, 0, 0, 176, 0, 0, 0, 5, 0, 0, 0, 0,
+ 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 186, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 255, 255, 255, 255, 1, 14, 0,
+ 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 83, 86, 95, 68, 69, 80, 84, 72,
+ 0, 171, 83, 72, 68, 82, 16, 1, 0, 0, 64, 0, 0, 0, 68, 0, 0, 0, 89,
+ 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 101, 0, 0, 3,
+ 242, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0,
+ 0, 101, 0, 0, 3, 242, 32, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32,
+ 16, 0, 3, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 4, 0, 0, 0, 101,
+ 0, 0, 3, 242, 32, 16, 0, 5, 0, 0, 0, 101, 0, 0, 2, 1, 192, 0, 0,
+ 54, 0, 0, 6, 242, 32, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 1, 0, 0, 0, 70, 142,
+ 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 2,
+ 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6,
+ 242, 32, 16, 0, 3, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 54, 0, 0, 6, 242, 32, 16, 0, 4, 0, 0, 0, 70, 142, 32, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 5, 0, 0, 0, 70,
+ 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 1, 192, 0, 0,
+ 10, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65,
+ 84, 116, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 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, 0, 0, 0,
+ 0, 0, 0, 0, 0, 7, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps7.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps7.h
new file mode 100644
index 0000000000..95987043f2
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps7.h
@@ -0,0 +1,122 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Buffer Definitions:
+//
+// cbuffer ColorAndDepthDataUint
+// {
+//
+// uint4 color_Uint; // Offset: 0 Size: 16
+// float zValueF_Uint; // Offset: 16 Size: 4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// ColorAndDepthDataUint cbuffer NA NA cb0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET uint xyzw
+// SV_TARGET 1 xyzw 1 TARGET uint xyzw
+// SV_TARGET 2 xyzw 2 TARGET uint xyzw
+// SV_TARGET 3 xyzw 3 TARGET uint xyzw
+// SV_TARGET 4 xyzw 4 TARGET uint xyzw
+// SV_TARGET 5 xyzw 5 TARGET uint xyzw
+// SV_TARGET 6 xyzw 6 TARGET uint xyzw
+// SV_DEPTH 0 N/A oDepth DEPTH float YES
+//
+ps_4_0
+dcl_constantbuffer CB0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output o2.xyzw
+dcl_output o3.xyzw
+dcl_output o4.xyzw
+dcl_output o5.xyzw
+dcl_output o6.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov o2.xyzw, cb0[0].xyzw
+mov o3.xyzw, cb0[0].xyzw
+mov o4.xyzw, cb0[0].xyzw
+mov o5.xyzw, cb0[0].xyzw
+mov o6.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret
+// Approximately 9 instruction slots used
+#endif
+
+const BYTE g_PS_ClearUint7[] = {
+ 68, 88, 66, 67, 187, 93, 194, 62, 133, 16, 185, 196, 51, 199, 55, 8, 8, 169, 14,
+ 118, 1, 0, 0, 0, 12, 4, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1,
+ 0, 0, 112, 1, 0, 0, 84, 2, 0, 0, 144, 3, 0, 0, 82, 68, 69, 70, 0,
+ 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104,
+ 68, 97, 116, 97, 85, 105, 110, 116, 0, 171, 171, 60, 0, 0, 0, 2, 0, 0, 0,
+ 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0,
+ 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0,
+ 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200,
+ 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 85, 105, 110, 116, 0, 171,
+ 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97,
+ 108, 117, 101, 70, 95, 85, 105, 110, 116, 0, 171, 171, 171, 0, 0, 3, 0, 1, 0,
+ 1, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0,
+ 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79,
+ 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 220, 0, 0, 0, 8, 0, 0, 0,
+ 8, 0, 0, 0, 200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0, 15, 0, 0, 0, 200, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 200, 0, 0, 0, 2,
+ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0,
+ 200, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0,
+ 0, 15, 0, 0, 0, 200, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 4, 0, 0, 0, 15, 0, 0, 0, 200, 0, 0, 0, 5, 0, 0, 0, 0,
+ 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 200, 0, 0, 0,
+ 6, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 6, 0, 0, 0, 15, 0, 0,
+ 0, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 255, 255,
+ 255, 255, 1, 14, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 83, 86, 95,
+ 68, 69, 80, 84, 72, 0, 171, 83, 72, 68, 82, 52, 1, 0, 0, 64, 0, 0, 0,
+ 77, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0,
+ 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32,
+ 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 2, 0, 0, 0, 101,
+ 0, 0, 3, 242, 32, 16, 0, 3, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0,
+ 4, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 5, 0, 0, 0, 101, 0, 0,
+ 3, 242, 32, 16, 0, 6, 0, 0, 0, 101, 0, 0, 2, 1, 192, 0, 0, 54, 0,
+ 0, 6, 242, 32, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 2, 0, 0,
+ 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32,
+ 16, 0, 3, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54,
+ 0, 0, 6, 242, 32, 16, 0, 4, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 5, 0, 0, 0, 70, 142, 32,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 6, 0,
+ 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 1,
+ 192, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 62, 0, 0, 1,
+ 83, 84, 65, 84, 116, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 8, 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,
+ 0, 0, 0, 0, 0, 0, 0, 0, 8, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps8.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps8.h
new file mode 100644
index 0000000000..c470ab47bf
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps8.h
@@ -0,0 +1,128 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Buffer Definitions:
+//
+// cbuffer ColorAndDepthDataUint
+// {
+//
+// uint4 color_Uint; // Offset: 0 Size: 16
+// float zValueF_Uint; // Offset: 16 Size: 4
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// ColorAndDepthDataUint cbuffer NA NA cb0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET uint xyzw
+// SV_TARGET 1 xyzw 1 TARGET uint xyzw
+// SV_TARGET 2 xyzw 2 TARGET uint xyzw
+// SV_TARGET 3 xyzw 3 TARGET uint xyzw
+// SV_TARGET 4 xyzw 4 TARGET uint xyzw
+// SV_TARGET 5 xyzw 5 TARGET uint xyzw
+// SV_TARGET 6 xyzw 6 TARGET uint xyzw
+// SV_TARGET 7 xyzw 7 TARGET uint xyzw
+// SV_DEPTH 0 N/A oDepth DEPTH float YES
+//
+ps_4_0
+dcl_constantbuffer CB0[2], immediateIndexed
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output o2.xyzw
+dcl_output o3.xyzw
+dcl_output o4.xyzw
+dcl_output o5.xyzw
+dcl_output o6.xyzw
+dcl_output o7.xyzw
+dcl_output oDepth
+mov o0.xyzw, cb0[0].xyzw
+mov o1.xyzw, cb0[0].xyzw
+mov o2.xyzw, cb0[0].xyzw
+mov o3.xyzw, cb0[0].xyzw
+mov o4.xyzw, cb0[0].xyzw
+mov o5.xyzw, cb0[0].xyzw
+mov o6.xyzw, cb0[0].xyzw
+mov o7.xyzw, cb0[0].xyzw
+mov oDepth, cb0[1].x
+ret
+// Approximately 10 instruction slots used
+#endif
+
+const BYTE g_PS_ClearUint8[] = {
+ 68, 88, 66, 67, 206, 106, 135, 121, 179, 175, 105, 51, 32, 41, 211, 246, 201, 25, 75,
+ 237, 1, 0, 0, 0, 72, 4, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 60, 1,
+ 0, 0, 112, 1, 0, 0, 108, 2, 0, 0, 204, 3, 0, 0, 82, 68, 69, 70, 0,
+ 1, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 216, 0, 0, 0, 60, 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, 1, 0, 0, 0, 67, 111, 108, 111, 114, 65, 110, 100, 68, 101, 112, 116, 104,
+ 68, 97, 116, 97, 85, 105, 110, 116, 0, 171, 171, 60, 0, 0, 0, 2, 0, 0, 0,
+ 108, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0,
+ 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 168, 0, 0, 0, 0, 0,
+ 0, 0, 184, 0, 0, 0, 16, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 200,
+ 0, 0, 0, 0, 0, 0, 0, 99, 111, 108, 111, 114, 95, 85, 105, 110, 116, 0, 171,
+ 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 86, 97,
+ 108, 117, 101, 70, 95, 85, 105, 110, 116, 0, 171, 171, 171, 0, 0, 3, 0, 1, 0,
+ 1, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0,
+ 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 79,
+ 83, 73, 84, 73, 79, 78, 0, 79, 83, 71, 78, 244, 0, 0, 0, 9, 0, 0, 0,
+ 8, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0, 15, 0, 0, 0, 224, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 224, 0, 0, 0, 2,
+ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0,
+ 224, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0,
+ 0, 15, 0, 0, 0, 224, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 4, 0, 0, 0, 15, 0, 0, 0, 224, 0, 0, 0, 5, 0, 0, 0, 0,
+ 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 15, 0, 0, 0, 224, 0, 0, 0,
+ 6, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 6, 0, 0, 0, 15, 0, 0,
+ 0, 224, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 7, 0,
+ 0, 0, 15, 0, 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 0, 0, 0, 255, 255, 255, 255, 1, 14, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69,
+ 84, 0, 83, 86, 95, 68, 69, 80, 84, 72, 0, 171, 83, 72, 68, 82, 88, 1, 0,
+ 0, 64, 0, 0, 0, 86, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0,
+ 0, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 101,
+ 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0,
+ 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 3, 0, 0, 0, 101, 0, 0,
+ 3, 242, 32, 16, 0, 4, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 5, 0,
+ 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 6, 0, 0, 0, 101, 0, 0, 3, 242,
+ 32, 16, 0, 7, 0, 0, 0, 101, 0, 0, 2, 1, 192, 0, 0, 54, 0, 0, 6,
+ 242, 32, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 54, 0, 0, 6, 242, 32, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 2, 0, 0, 0, 70,
+ 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0,
+ 3, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0,
+ 6, 242, 32, 16, 0, 4, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 5, 0, 0, 0, 70, 142, 32, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16, 0, 6, 0, 0, 0,
+ 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 242, 32, 16,
+ 0, 7, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0,
+ 0, 5, 1, 192, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 62,
+ 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 9, 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, 0, 0, 0, 0, 0, 0, 0, 0, 9, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_luma_2d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_luma_2d_ps.h
new file mode 100644
index 0000000000..215c315abf
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_luma_2d_ps.h
@@ -0,0 +1,76 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 2d t0 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
+//
+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.xxxx
+mov o0.w, l(1.000000)
+ret
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_PM_LUMA_2D[] = {
+ 68, 88, 66, 67, 196, 88, 192, 127, 243, 30, 81, 182, 148, 19, 99, 57, 115, 181, 138,
+ 146, 1, 0, 0, 0, 128, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 44, 1, 0, 0, 96, 1, 0, 0, 4, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 49, 48, 46, 49, 0,
+ 171, 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, 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, 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, 6, 0, 16, 0, 0, 0, 0, 0, 54, 0,
+ 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_luma_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_luma_2darray_ps.h
new file mode 100644
index 0000000000..6918bb1bb3
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_luma_2darray_ps.h
@@ -0,0 +1,86 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_2DArray texture float4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2darray (float,float,float,float) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 1
+utof r0.z, v1.x
+mov r0.xy, v2.xyxx
+sample r0.xyzw, r0.xyzx, t0.xyzw, s0
+mul o0.xyz, r0.wwww, r0.xxxx
+mov o0.w, l(1.000000)
+ret
+// Approximately 6 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_PM_LUMA_2DArray[] = {
+ 68, 88, 66, 67, 96, 91, 207, 234, 31, 106, 235, 231, 220, 198, 196, 200, 17, 9, 209,
+ 197, 1, 0, 0, 0, 240, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0,
+ 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 116, 2, 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, 117, 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, 5,
+ 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, 95, 50, 68,
+ 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0,
+ 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0,
+ 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0,
+ 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95,
+ 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78,
+ 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 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, 83, 72, 68, 82, 212, 0, 0, 0, 64, 0,
+ 0, 0, 53, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88,
+ 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4,
+ 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16,
+ 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0,
+ 0, 2, 1, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10,
+ 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0,
+ 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0,
+ 0, 70, 2, 16, 0, 0, 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, 6, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5,
+ 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 62, 0, 0,
+ 1, 83, 84, 65, 84, 116, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 3, 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, 2, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_luma_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_luma_3d_ps.h
new file mode 100644
index 0000000000..0c5f9d3b26
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_luma_3d_ps.h
@@ -0,0 +1,80 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_3D texture float4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v2.xyzx, t0.xyzw, s0
+mul o0.xyz, r0.wwww, r0.xxxx
+mov o0.w, l(1.000000)
+ret
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_PM_LUMA_3D[] = {
+ 68, 88, 66, 67, 241, 186, 22, 7, 74, 156, 103, 227, 226, 7, 140, 127, 65, 83, 2,
+ 111, 1, 0, 0, 0, 176, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 52, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 112, 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, 8,
+ 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, 95, 51, 68,
+ 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, 49, 48,
+ 46, 49, 0, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 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, 40, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 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, 18, 16, 0, 2, 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,
+ 6, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0,
+ 0, 1, 64, 0, 0, 0, 0, 128, 63, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_lumaalpha_2d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_lumaalpha_2d_ps.h
new file mode 100644
index 0000000000..5904f217e3
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_lumaalpha_2d_ps.h
@@ -0,0 +1,76 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 2d t0 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
+//
+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.xxxx
+mov o0.w, r0.w
+ret
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_PM_LUMAALPHA_2D[] = {
+ 68, 88, 66, 67, 101, 29, 108, 117, 250, 233, 255, 220, 65, 43, 102, 162, 164, 247, 189,
+ 112, 1, 0, 0, 0, 128, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 44, 1, 0, 0, 96, 1, 0, 0, 4, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 49, 48, 46, 49, 0,
+ 171, 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, 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, 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, 6, 0, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_lumaalpha_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_lumaalpha_2darray_ps.h
new file mode 100644
index 0000000000..09d9bad5c0
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_lumaalpha_2darray_ps.h
@@ -0,0 +1,86 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_2DArray texture float4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2darray (float,float,float,float) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 1
+utof r0.z, v1.x
+mov r0.xy, v2.xyxx
+sample r0.xyzw, r0.xyzx, t0.xyzw, s0
+mul o0.xyz, r0.wwww, r0.xxxx
+mov o0.w, r0.w
+ret
+// Approximately 6 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_PM_LUMAALPHA_2DArray[] = {
+ 68, 88, 66, 67, 16, 148, 215, 158, 112, 164, 42, 84, 33, 70, 148, 190, 238, 94, 245,
+ 128, 1, 0, 0, 0, 240, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0,
+ 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 116, 2, 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, 117, 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, 5,
+ 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, 95, 50, 68,
+ 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0,
+ 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0,
+ 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0,
+ 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95,
+ 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78,
+ 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 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, 83, 72, 68, 82, 212, 0, 0, 0, 64, 0,
+ 0, 0, 53, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88,
+ 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4,
+ 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16,
+ 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0,
+ 0, 2, 1, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10,
+ 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0,
+ 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0,
+ 0, 70, 2, 16, 0, 0, 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, 6, 0, 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, 1, 0, 0, 0, 0, 0,
+ 0, 0, 3, 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, 2, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_lumaalpha_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_lumaalpha_3d_ps.h
new file mode 100644
index 0000000000..d8ca1c845a
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_lumaalpha_3d_ps.h
@@ -0,0 +1,80 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_3D texture float4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v2.xyzx, t0.xyzw, s0
+mul o0.xyz, r0.wwww, r0.xxxx
+mov o0.w, r0.w
+ret
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_PM_LUMAALPHA_3D[] = {
+ 68, 88, 66, 67, 9, 39, 6, 28, 108, 109, 23, 108, 237, 131, 58, 1, 102, 159, 191,
+ 61, 1, 0, 0, 0, 176, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 52, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 112, 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, 8,
+ 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, 95, 51, 68,
+ 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, 49, 48,
+ 46, 49, 0, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 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, 40, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 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, 18, 16, 0, 2, 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,
+ 6, 0, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_2d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_2d_ps.h
new file mode 100644
index 0000000000..be18a987f8
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_2d_ps.h
@@ -0,0 +1,76 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 2d t0 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
+//
+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, l(1.000000)
+ret
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_PM_RGB_2D[] = {
+ 68, 88, 66, 67, 87, 204, 158, 94, 75, 152, 102, 217, 0, 88, 222, 29, 232, 182, 2,
+ 132, 1, 0, 0, 0, 128, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 44, 1, 0, 0, 96, 1, 0, 0, 4, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 49, 48, 46, 49, 0,
+ 171, 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, 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, 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, 1, 64, 0, 0, 0, 0, 128, 63, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_2darray_ps.h
new file mode 100644
index 0000000000..7f18036816
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_2darray_ps.h
@@ -0,0 +1,86 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_2DArray texture float4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2darray (float,float,float,float) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 1
+utof r0.z, v1.x
+mov r0.xy, v2.xyxx
+sample r0.xyzw, r0.xyzx, t0.xyzw, s0
+mul o0.xyz, r0.wwww, r0.xyzx
+mov o0.w, l(1.000000)
+ret
+// Approximately 6 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_PM_RGB_2DArray[] = {
+ 68, 88, 66, 67, 73, 224, 127, 95, 171, 173, 116, 230, 242, 111, 205, 239, 210, 69, 91,
+ 238, 1, 0, 0, 0, 240, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0,
+ 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 116, 2, 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, 117, 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, 5,
+ 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, 95, 50, 68,
+ 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0,
+ 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0,
+ 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0,
+ 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95,
+ 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78,
+ 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 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, 83, 72, 68, 82, 212, 0, 0, 0, 64, 0,
+ 0, 0, 53, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88,
+ 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4,
+ 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16,
+ 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0,
+ 0, 2, 1, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10,
+ 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0,
+ 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0,
+ 0, 70, 2, 16, 0, 0, 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, 1, 64, 0, 0, 0, 0, 128, 63, 62, 0, 0,
+ 1, 83, 84, 65, 84, 116, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 3, 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, 2, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_3d_ps.h
new file mode 100644
index 0000000000..78ed86a6cf
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_3d_ps.h
@@ -0,0 +1,80 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_3D texture float4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v2.xyzx, t0.xyzw, s0
+mul o0.xyz, r0.wwww, r0.xyzx
+mov o0.w, l(1.000000)
+ret
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_PM_RGB_3D[] = {
+ 68, 88, 66, 67, 188, 235, 5, 90, 236, 180, 172, 101, 155, 220, 117, 214, 110, 8, 67,
+ 121, 1, 0, 0, 0, 176, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 52, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 112, 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, 8,
+ 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, 95, 51, 68,
+ 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, 49, 48,
+ 46, 49, 0, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 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, 40, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 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, 18, 16, 0, 2, 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, 1, 64, 0, 0, 0, 0, 128, 63, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_565_2d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_565_2d_ps.h
new file mode 100644
index 0000000000..05af034cf3
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_565_2d_ps.h
@@ -0,0 +1,84 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 2d t0 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
+//
+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 r0.xyz, r0.wwww, r0.xyzx
+mul r0.xyz, r0.xyzx, l(31.000000, 63.000000, 31.000000, 0.000000)
+round_ne r0.xyz, r0.xyzx
+mul o0.xyz, r0.xyzx, l(0.032258, 0.015873, 0.032258, 0.000000)
+mov o0.w, l(1.000000)
+ret
+// Approximately 7 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_PM_RGB_565_2D[] = {
+ 68, 88, 66, 67, 107, 29, 4, 204, 154, 16, 239, 118, 140, 65, 255, 118, 32, 171, 247,
+ 239, 1, 0, 0, 0, 228, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 44, 1, 0, 0, 96, 1, 0, 0, 104, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 49, 48, 46, 49, 0,
+ 171, 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, 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, 83, 72, 68, 82, 0, 1, 0, 0, 64,
+ 0, 0, 0, 64, 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, 0, 16, 0, 0, 0, 0,
+ 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0,
+ 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2,
+ 64, 0, 0, 0, 0, 248, 65, 0, 0, 124, 66, 0, 0, 248, 65, 0, 0, 0, 0,
+ 64, 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0,
+ 0, 56, 0, 0, 10, 114, 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0,
+ 0, 0, 2, 64, 0, 0, 8, 33, 4, 61, 33, 8, 130, 60, 8, 33, 4, 61, 0,
+ 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0,
+ 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 7, 0, 0,
+ 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 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, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_565_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_565_2darray_ps.h
new file mode 100644
index 0000000000..af5eb349ba
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_565_2darray_ps.h
@@ -0,0 +1,94 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_2DArray texture float4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2darray (float,float,float,float) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 1
+utof r0.z, v1.x
+mov r0.xy, v2.xyxx
+sample r0.xyzw, r0.xyzx, t0.xyzw, s0
+mul r0.xyz, r0.wwww, r0.xyzx
+mul r0.xyz, r0.xyzx, l(31.000000, 63.000000, 31.000000, 0.000000)
+round_ne r0.xyz, r0.xyzx
+mul o0.xyz, r0.xyzx, l(0.032258, 0.015873, 0.032258, 0.000000)
+mov o0.w, l(1.000000)
+ret
+// Approximately 9 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_PM_RGB_565_2DArray[] = {
+ 68, 88, 66, 67, 45, 176, 85, 221, 234, 218, 205, 113, 163, 153, 221, 15, 166, 157, 230,
+ 200, 1, 0, 0, 0, 84, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0,
+ 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 216, 2, 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, 117, 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, 5,
+ 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, 95, 50, 68,
+ 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0,
+ 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0,
+ 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0,
+ 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95,
+ 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78,
+ 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 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, 83, 72, 68, 82, 56, 1, 0, 0, 64, 0,
+ 0, 0, 78, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88,
+ 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4,
+ 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16,
+ 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0,
+ 0, 2, 1, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10,
+ 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0,
+ 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0,
+ 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96,
+ 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 0, 0, 0, 0, 246,
+ 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10,
+ 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0,
+ 0, 0, 0, 248, 65, 0, 0, 124, 66, 0, 0, 248, 65, 0, 0, 0, 0, 64, 0,
+ 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56,
+ 0, 0, 10, 114, 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0,
+ 2, 64, 0, 0, 8, 33, 4, 61, 33, 8, 130, 60, 8, 33, 4, 61, 0, 0, 0,
+ 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0,
+ 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 9, 0, 0, 0, 1,
+ 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4, 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, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_565_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_565_3d_ps.h
new file mode 100644
index 0000000000..bf02050d89
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgb_565_3d_ps.h
@@ -0,0 +1,88 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_3D texture float4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v2.xyzx, t0.xyzw, s0
+mul r0.xyz, r0.wwww, r0.xyzx
+mul r0.xyz, r0.xyzx, l(31.000000, 63.000000, 31.000000, 0.000000)
+round_ne r0.xyz, r0.xyzx
+mul o0.xyz, r0.xyzx, l(0.032258, 0.015873, 0.032258, 0.000000)
+mov o0.w, l(1.000000)
+ret
+// Approximately 7 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_PM_RGB_565_3D[] = {
+ 68, 88, 66, 67, 72, 210, 100, 140, 147, 53, 29, 56, 170, 112, 233, 37, 175, 201, 198,
+ 250, 1, 0, 0, 0, 20, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 152, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 112, 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, 8,
+ 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, 95, 51, 68,
+ 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, 49, 48,
+ 46, 49, 0, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 83, 72, 68, 82, 0, 1, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 90, 0,
+ 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 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, 18, 16, 0, 2, 0,
+ 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56,
+ 0, 0, 7, 114, 0, 16, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0,
+ 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 114, 0, 16, 0, 0, 0, 0,
+ 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 248, 65, 0, 0,
+ 124, 66, 0, 0, 248, 65, 0, 0, 0, 0, 64, 0, 0, 5, 114, 0, 16, 0, 0,
+ 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 114, 32, 16, 0,
+ 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 8, 33, 4,
+ 61, 33, 8, 130, 60, 8, 33, 4, 61, 0, 0, 0, 0, 54, 0, 0, 5, 130, 32,
+ 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 62, 0, 0, 1, 83,
+ 84, 65, 84, 116, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 2, 0, 0, 0, 4, 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, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_2d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_2d_ps.h
new file mode 100644
index 0000000000..68712ef7f5
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_2d_ps.h
@@ -0,0 +1,76 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 2d t0 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
+//
+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_FtoF_PM_RGBA_2D[] = {
+ 68, 88, 66, 67, 132, 105, 208, 138, 186, 182, 112, 82, 173, 16, 240, 222, 116, 72, 178,
+ 126, 1, 0, 0, 0, 128, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 44, 1, 0, 0, 96, 1, 0, 0, 4, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 49, 48, 46, 49, 0,
+ 171, 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, 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, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_2darray_ps.h
new file mode 100644
index 0000000000..2f0b59abe0
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_2darray_ps.h
@@ -0,0 +1,86 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_2DArray texture float4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2darray (float,float,float,float) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 1
+utof r0.z, v1.x
+mov r0.xy, v2.xyxx
+sample r0.xyzw, r0.xyzx, t0.xyzw, s0
+mul o0.xyz, r0.wwww, r0.xyzx
+mov o0.w, r0.w
+ret
+// Approximately 6 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_PM_RGBA_2DArray[] = {
+ 68, 88, 66, 67, 61, 17, 53, 94, 235, 123, 58, 146, 86, 204, 96, 4, 97, 221, 95,
+ 134, 1, 0, 0, 0, 240, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0,
+ 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 116, 2, 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, 117, 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, 5,
+ 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, 95, 50, 68,
+ 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0,
+ 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0,
+ 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0,
+ 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95,
+ 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78,
+ 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 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, 83, 72, 68, 82, 212, 0, 0, 0, 64, 0,
+ 0, 0, 53, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88,
+ 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4,
+ 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16,
+ 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0,
+ 0, 2, 1, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10,
+ 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0,
+ 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0,
+ 0, 70, 2, 16, 0, 0, 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, 6, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 3, 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, 2, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_3d_ps.h
new file mode 100644
index 0000000000..62d18d62db
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_3d_ps.h
@@ -0,0 +1,80 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_3D texture float4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v2.xyzx, 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_FtoF_PM_RGBA_3D[] = {
+ 68, 88, 66, 67, 80, 173, 64, 240, 1, 143, 85, 115, 221, 254, 89, 145, 213, 191, 49,
+ 141, 1, 0, 0, 0, 176, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 52, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 112, 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, 8,
+ 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, 95, 51, 68,
+ 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, 49, 48,
+ 46, 49, 0, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 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, 40, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 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, 18, 16, 0, 2, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_4444_2d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_4444_2d_ps.h
new file mode 100644
index 0000000000..62e59d2e4e
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_4444_2d_ps.h
@@ -0,0 +1,82 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 2d t0 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
+//
+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 r0.xyz, r0.wwww, r0.xyzx
+mul r0.xyzw, r0.xyzw, l(15.000000, 15.000000, 15.000000, 15.000000)
+round_ne r0.xyzw, r0.xyzw
+mul o0.xyzw, r0.xyzw, l(0.066667, 0.066667, 0.066667, 0.066667)
+ret
+// Approximately 6 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_PM_RGBA_4444_2D[] = {
+ 68, 88, 66, 67, 52, 89, 222, 242, 25, 197, 40, 54, 79, 232, 156, 234, 251, 41, 41,
+ 226, 1, 0, 0, 0, 208, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 44, 1, 0, 0, 96, 1, 0, 0, 84, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 49, 48, 46, 49, 0,
+ 171, 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, 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, 83, 72, 68, 82, 236, 0, 0, 0, 64,
+ 0, 0, 0, 59, 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, 0, 16, 0, 0, 0, 0,
+ 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0,
+ 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2,
+ 64, 0, 0, 0, 0, 112, 65, 0, 0, 112, 65, 0, 0, 112, 65, 0, 0, 112, 65,
+ 64, 0, 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0,
+ 0, 56, 0, 0, 10, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0,
+ 0, 0, 2, 64, 0, 0, 137, 136, 136, 61, 137, 136, 136, 61, 137, 136, 136, 61, 137,
+ 136, 136, 61, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 6, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 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, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_4444_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_4444_2darray_ps.h
new file mode 100644
index 0000000000..ebfce59f6a
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_4444_2darray_ps.h
@@ -0,0 +1,92 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_2DArray texture float4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2darray (float,float,float,float) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 1
+utof r0.z, v1.x
+mov r0.xy, v2.xyxx
+sample r0.xyzw, r0.xyzx, t0.xyzw, s0
+mul r0.xyz, r0.wwww, r0.xyzx
+mul r0.xyzw, r0.xyzw, l(15.000000, 15.000000, 15.000000, 15.000000)
+round_ne r0.xyzw, r0.xyzw
+mul o0.xyzw, r0.xyzw, l(0.066667, 0.066667, 0.066667, 0.066667)
+ret
+// Approximately 8 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_PM_RGBA_4444_2DArray[] = {
+ 68, 88, 66, 67, 119, 1, 180, 34, 213, 167, 228, 86, 205, 242, 230, 17, 87, 32, 74,
+ 6, 1, 0, 0, 0, 64, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0,
+ 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 196, 2, 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, 117, 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, 5,
+ 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, 95, 50, 68,
+ 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0,
+ 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0,
+ 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0,
+ 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95,
+ 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78,
+ 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 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, 83, 72, 68, 82, 36, 1, 0, 0, 64, 0,
+ 0, 0, 73, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88,
+ 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4,
+ 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16,
+ 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0,
+ 0, 2, 1, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10,
+ 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0,
+ 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0,
+ 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96,
+ 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 0, 0, 0, 0, 246,
+ 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10,
+ 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0,
+ 0, 0, 0, 112, 65, 0, 0, 112, 65, 0, 0, 112, 65, 0, 0, 112, 65, 64, 0,
+ 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 56,
+ 0, 0, 10, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0,
+ 2, 64, 0, 0, 137, 136, 136, 61, 137, 136, 136, 61, 137, 136, 136, 61, 137, 136, 136,
+ 61, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 8, 0, 0, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4, 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, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_4444_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_4444_3d_ps.h
new file mode 100644
index 0000000000..a5dd42a2a7
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_4444_3d_ps.h
@@ -0,0 +1,86 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_3D texture float4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v2.xyzx, t0.xyzw, s0
+mul r0.xyz, r0.wwww, r0.xyzx
+mul r0.xyzw, r0.xyzw, l(15.000000, 15.000000, 15.000000, 15.000000)
+round_ne r0.xyzw, r0.xyzw
+mul o0.xyzw, r0.xyzw, l(0.066667, 0.066667, 0.066667, 0.066667)
+ret
+// Approximately 6 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_PM_RGBA_4444_3D[] = {
+ 68, 88, 66, 67, 233, 160, 206, 221, 201, 110, 121, 251, 163, 213, 234, 30, 171, 187, 79,
+ 242, 1, 0, 0, 0, 0, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 132, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 112, 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, 8,
+ 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, 95, 51, 68,
+ 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, 49, 48,
+ 46, 49, 0, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 83, 72, 68, 82, 236, 0, 0, 0, 64, 0, 0, 0, 59, 0, 0, 0, 90, 0,
+ 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 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, 18, 16, 0, 2, 0,
+ 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56,
+ 0, 0, 7, 114, 0, 16, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0,
+ 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0,
+ 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 112, 65, 0, 0,
+ 112, 65, 0, 0, 112, 65, 0, 0, 112, 65, 64, 0, 0, 5, 242, 0, 16, 0, 0,
+ 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 32, 16, 0,
+ 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 137, 136, 136,
+ 61, 137, 136, 136, 61, 137, 136, 136, 61, 137, 136, 136, 61, 62, 0, 0, 1, 83, 84,
+ 65, 84, 116, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2,
+ 0, 0, 0, 4, 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, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_5551_2d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_5551_2d_ps.h
new file mode 100644
index 0000000000..fca424ebc2
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_5551_2d_ps.h
@@ -0,0 +1,82 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 2d t0 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
+//
+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 r0.xyz, r0.wwww, r0.xyzx
+mul r0.xyzw, r0.xyzw, l(31.000000, 31.000000, 31.000000, 1.000000)
+round_ne r0.xyzw, r0.xyzw
+mul o0.xyzw, r0.xyzw, l(0.032258, 0.032258, 0.032258, 1.000000)
+ret
+// Approximately 6 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_PM_RGBA_5551_2D[] = {
+ 68, 88, 66, 67, 157, 187, 40, 209, 230, 225, 190, 246, 40, 140, 167, 190, 61, 115, 94,
+ 70, 1, 0, 0, 0, 208, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 44, 1, 0, 0, 96, 1, 0, 0, 84, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 49, 48, 46, 49, 0,
+ 171, 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, 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, 83, 72, 68, 82, 236, 0, 0, 0, 64,
+ 0, 0, 0, 59, 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, 0, 16, 0, 0, 0, 0,
+ 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0,
+ 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2,
+ 64, 0, 0, 0, 0, 248, 65, 0, 0, 248, 65, 0, 0, 248, 65, 0, 0, 128, 63,
+ 64, 0, 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0,
+ 0, 56, 0, 0, 10, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0,
+ 0, 0, 2, 64, 0, 0, 8, 33, 4, 61, 8, 33, 4, 61, 8, 33, 4, 61, 0,
+ 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 6, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 4, 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, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_5551_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_5551_2darray_ps.h
new file mode 100644
index 0000000000..ee5c7d6e27
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_5551_2darray_ps.h
@@ -0,0 +1,92 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_2DArray texture float4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2darray (float,float,float,float) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 1
+utof r0.z, v1.x
+mov r0.xy, v2.xyxx
+sample r0.xyzw, r0.xyzx, t0.xyzw, s0
+mul r0.xyz, r0.wwww, r0.xyzx
+mul r0.xyzw, r0.xyzw, l(31.000000, 31.000000, 31.000000, 1.000000)
+round_ne r0.xyzw, r0.xyzw
+mul o0.xyzw, r0.xyzw, l(0.032258, 0.032258, 0.032258, 1.000000)
+ret
+// Approximately 8 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_PM_RGBA_5551_2DArray[] = {
+ 68, 88, 66, 67, 66, 21, 128, 163, 11, 21, 65, 137, 107, 224, 148, 78, 244, 169, 148,
+ 247, 1, 0, 0, 0, 64, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0,
+ 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 196, 2, 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, 117, 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, 5,
+ 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, 95, 50, 68,
+ 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0,
+ 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0,
+ 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0,
+ 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95,
+ 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78,
+ 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 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, 83, 72, 68, 82, 36, 1, 0, 0, 64, 0,
+ 0, 0, 73, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88,
+ 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4,
+ 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16,
+ 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0,
+ 0, 2, 1, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10,
+ 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0,
+ 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0,
+ 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96,
+ 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 0, 0, 0, 0, 246,
+ 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10,
+ 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0,
+ 0, 0, 0, 248, 65, 0, 0, 248, 65, 0, 0, 248, 65, 0, 0, 128, 63, 64, 0,
+ 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 56,
+ 0, 0, 10, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0,
+ 2, 64, 0, 0, 8, 33, 4, 61, 8, 33, 4, 61, 8, 33, 4, 61, 0, 0, 128,
+ 63, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 8, 0, 0, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4, 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, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_5551_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_5551_3d_ps.h
new file mode 100644
index 0000000000..f4b47c002f
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_pm_rgba_5551_3d_ps.h
@@ -0,0 +1,86 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_3D texture float4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v2.xyzx, t0.xyzw, s0
+mul r0.xyz, r0.wwww, r0.xyzx
+mul r0.xyzw, r0.xyzw, l(31.000000, 31.000000, 31.000000, 1.000000)
+round_ne r0.xyzw, r0.xyzw
+mul o0.xyzw, r0.xyzw, l(0.032258, 0.032258, 0.032258, 1.000000)
+ret
+// Approximately 6 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_PM_RGBA_5551_3D[] = {
+ 68, 88, 66, 67, 74, 0, 199, 89, 200, 147, 93, 64, 244, 239, 156, 102, 110, 132, 22,
+ 10, 1, 0, 0, 0, 0, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 132, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 112, 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, 8,
+ 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, 95, 51, 68,
+ 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, 49, 48,
+ 46, 49, 0, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 83, 72, 68, 82, 236, 0, 0, 0, 64, 0, 0, 0, 59, 0, 0, 0, 90, 0,
+ 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 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, 18, 16, 0, 2, 0,
+ 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56,
+ 0, 0, 7, 114, 0, 16, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0,
+ 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0,
+ 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 248, 65, 0, 0,
+ 248, 65, 0, 0, 248, 65, 0, 0, 128, 63, 64, 0, 0, 5, 242, 0, 16, 0, 0,
+ 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 32, 16, 0,
+ 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 8, 33, 4,
+ 61, 8, 33, 4, 61, 8, 33, 4, 61, 0, 0, 128, 63, 62, 0, 0, 1, 83, 84,
+ 65, 84, 116, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2,
+ 0, 0, 0, 4, 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, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_luma_2d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_luma_2d_ps.h
new file mode 100644
index 0000000000..a0023c0013
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_luma_2d_ps.h
@@ -0,0 +1,82 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 2d t0 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
+//
+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 r0.w, r0.x, r0.w
+movc o0.xyz, r1.xxxx, r0.wwww, r0.xyzx
+mov o0.w, l(1.000000)
+ret
+// Approximately 6 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_UM_LUMA_2D[] = {
+ 68, 88, 66, 67, 75, 92, 229, 222, 23, 169, 5, 92, 146, 12, 107, 229, 137, 155, 179,
+ 250, 1, 0, 0, 0, 192, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 44, 1, 0, 0, 96, 1, 0, 0, 68, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 49, 48, 46, 49, 0,
+ 171, 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, 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, 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, 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58,
+ 0, 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, 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, 1, 64,
+ 0, 0, 0, 0, 128, 63, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_luma_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_luma_2darray_ps.h
new file mode 100644
index 0000000000..4ad691bef4
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_luma_2darray_ps.h
@@ -0,0 +1,91 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_2DArray texture float4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2darray (float,float,float,float) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 2
+utof r0.z, v1.x
+mov r0.xy, v2.xyxx
+sample r0.xyzw, r0.xyzx, t0.xyzw, s0
+lt r1.x, l(0.000000), r0.w
+div r0.w, r0.x, r0.w
+movc o0.xyz, r1.xxxx, r0.wwww, r0.xyzx
+mov o0.w, l(1.000000)
+ret
+// Approximately 8 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_UM_LUMA_2DArray[] = {
+ 68, 88, 66, 67, 2, 234, 137, 29, 211, 208, 186, 172, 235, 8, 55, 155, 195, 91, 134,
+ 133, 1, 0, 0, 0, 48, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0,
+ 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 180, 2, 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, 117, 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, 5,
+ 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, 95, 50, 68,
+ 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0,
+ 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0,
+ 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0,
+ 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95,
+ 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78,
+ 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 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, 83, 72, 68, 82, 20, 1, 0, 0, 64, 0,
+ 0, 0, 69, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88,
+ 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4,
+ 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16,
+ 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0,
+ 0, 2, 2, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10,
+ 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0,
+ 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0,
+ 0, 70, 2, 16, 0, 0, 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,
+ 130, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 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, 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, 1, 64, 0, 0,
+ 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 8, 0, 0,
+ 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 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, 2, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_luma_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_luma_3d_ps.h
new file mode 100644
index 0000000000..4eed8c15ba
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_luma_3d_ps.h
@@ -0,0 +1,85 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_3D texture float4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 2
+sample r0.xyzw, v2.xyzx, t0.xyzw, s0
+lt r1.x, l(0.000000), r0.w
+div r0.w, r0.x, r0.w
+movc o0.xyz, r1.xxxx, r0.wwww, r0.xyzx
+mov o0.w, l(1.000000)
+ret
+// Approximately 6 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_UM_LUMA_3D[] = {
+ 68, 88, 66, 67, 120, 214, 14, 47, 69, 88, 46, 178, 8, 214, 190, 124, 42, 131, 170,
+ 151, 1, 0, 0, 0, 240, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 116, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 112, 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, 8,
+ 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, 95, 51, 68,
+ 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, 49, 48,
+ 46, 49, 0, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 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, 40, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 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, 18, 16, 0, 2, 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, 130, 0, 16, 0, 0, 0, 0,
+ 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 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, 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, 1, 64, 0, 0, 0, 0, 128, 63, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_lumaalpha_2d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_lumaalpha_2d_ps.h
new file mode 100644
index 0000000000..7501fae643
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_lumaalpha_2d_ps.h
@@ -0,0 +1,82 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 2d t0 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
+//
+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.y, r0.x, r0.w
+movc o0.xyz, r1.xxxx, r1.yyyy, r0.xyzx
+mov o0.w, r0.w
+ret
+// Approximately 6 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_UM_LUMAALPHA_2D[] = {
+ 68, 88, 66, 67, 190, 69, 123, 211, 19, 130, 132, 1, 132, 116, 62, 1, 233, 115, 38,
+ 22, 1, 0, 0, 0, 192, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 44, 1, 0, 0, 96, 1, 0, 0, 68, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 49, 48, 46, 49, 0,
+ 171, 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, 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, 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, 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58,
+ 0, 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, 86, 5, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_lumaalpha_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_lumaalpha_2darray_ps.h
new file mode 100644
index 0000000000..40eb1f480c
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_lumaalpha_2darray_ps.h
@@ -0,0 +1,91 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_2DArray texture float4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2darray (float,float,float,float) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 2
+utof r0.z, v1.x
+mov r0.xy, v2.xyxx
+sample r0.xyzw, r0.xyzx, t0.xyzw, s0
+lt r1.x, l(0.000000), r0.w
+div r1.y, r0.x, r0.w
+movc o0.xyz, r1.xxxx, r1.yyyy, r0.xyzx
+mov o0.w, r0.w
+ret
+// Approximately 8 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_UM_LUMAALPHA_2DArray[] = {
+ 68, 88, 66, 67, 222, 131, 31, 168, 174, 145, 73, 243, 164, 132, 216, 2, 103, 0, 142,
+ 101, 1, 0, 0, 0, 48, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0,
+ 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 180, 2, 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, 117, 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, 5,
+ 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, 95, 50, 68,
+ 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0,
+ 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0,
+ 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0,
+ 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95,
+ 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78,
+ 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 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, 83, 72, 68, 82, 20, 1, 0, 0, 64, 0,
+ 0, 0, 69, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88,
+ 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4,
+ 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16,
+ 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0,
+ 0, 2, 2, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10,
+ 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0,
+ 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0,
+ 0, 70, 2, 16, 0, 0, 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,
+ 34, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 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, 86, 5, 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, 8, 0, 0,
+ 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 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, 2, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_lumaalpha_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_lumaalpha_3d_ps.h
new file mode 100644
index 0000000000..f6bbc8cc01
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_lumaalpha_3d_ps.h
@@ -0,0 +1,85 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_3D texture float4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 2
+sample r0.xyzw, v2.xyzx, t0.xyzw, s0
+lt r1.x, l(0.000000), r0.w
+div r1.y, r0.x, r0.w
+movc o0.xyz, r1.xxxx, r1.yyyy, r0.xyzx
+mov o0.w, r0.w
+ret
+// Approximately 6 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_UM_LUMAALPHA_3D[] = {
+ 68, 88, 66, 67, 160, 196, 1, 185, 15, 156, 153, 67, 85, 102, 198, 128, 138, 216, 238,
+ 143, 1, 0, 0, 0, 240, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 116, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 112, 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, 8,
+ 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, 95, 51, 68,
+ 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, 49, 48,
+ 46, 49, 0, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 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, 40, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 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, 18, 16, 0, 2, 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, 34, 0, 16, 0, 1, 0, 0,
+ 0, 10, 0, 16, 0, 0, 0, 0, 0, 58, 0, 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, 86,
+ 5, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_2d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_2d_ps.h
new file mode 100644
index 0000000000..ce44a394d7
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_2d_ps.h
@@ -0,0 +1,82 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 2d t0 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
+//
+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, l(1.000000)
+ret
+// Approximately 6 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_UM_RGB_2D[] = {
+ 68, 88, 66, 67, 93, 55, 14, 204, 55, 114, 238, 111, 6, 213, 4, 64, 58, 99, 168,
+ 104, 1, 0, 0, 0, 192, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 44, 1, 0, 0, 96, 1, 0, 0, 68, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 49, 48, 46, 49, 0,
+ 171, 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, 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, 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, 1, 64,
+ 0, 0, 0, 0, 128, 63, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_2darray_ps.h
new file mode 100644
index 0000000000..ea38e2e559
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_2darray_ps.h
@@ -0,0 +1,91 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_2DArray texture float4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2darray (float,float,float,float) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 2
+utof r0.z, v1.x
+mov r0.xy, v2.xyxx
+sample r0.xyzw, r0.xyzx, 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, l(1.000000)
+ret
+// Approximately 8 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_UM_RGB_2DArray[] = {
+ 68, 88, 66, 67, 224, 13, 199, 125, 145, 168, 88, 56, 242, 2, 144, 118, 87, 186, 241,
+ 248, 1, 0, 0, 0, 48, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0,
+ 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 180, 2, 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, 117, 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, 5,
+ 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, 95, 50, 68,
+ 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0,
+ 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0,
+ 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0,
+ 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95,
+ 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78,
+ 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 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, 83, 72, 68, 82, 20, 1, 0, 0, 64, 0,
+ 0, 0, 69, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88,
+ 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4,
+ 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16,
+ 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0,
+ 0, 2, 2, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10,
+ 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0,
+ 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0,
+ 0, 70, 2, 16, 0, 0, 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, 1, 64, 0, 0,
+ 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 8, 0, 0,
+ 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 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, 2, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_3d_ps.h
new file mode 100644
index 0000000000..da862eb119
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_3d_ps.h
@@ -0,0 +1,85 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_3D texture float4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 2
+sample r0.xyzw, v2.xyzx, 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, l(1.000000)
+ret
+// Approximately 6 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_UM_RGB_3D[] = {
+ 68, 88, 66, 67, 200, 37, 175, 150, 106, 41, 102, 69, 21, 246, 40, 148, 142, 99, 101,
+ 71, 1, 0, 0, 0, 240, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 116, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 112, 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, 8,
+ 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, 95, 51, 68,
+ 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, 49, 48,
+ 46, 49, 0, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 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, 40, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 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, 18, 16, 0, 2, 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, 1, 64, 0, 0, 0, 0, 128, 63, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_565_2d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_565_2d_ps.h
new file mode 100644
index 0000000000..5996ba335e
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_565_2d_ps.h
@@ -0,0 +1,90 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 2d t0 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
+//
+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 r0.xyz, r1.xxxx, r1.yzwy, r0.xyzx
+mul r0.xyz, r0.xyzx, l(31.000000, 63.000000, 31.000000, 0.000000)
+round_ne r0.xyz, r0.xyzx
+mul o0.xyz, r0.xyzx, l(0.032258, 0.015873, 0.032258, 0.000000)
+mov o0.w, l(1.000000)
+ret
+// Approximately 9 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_UM_RGB_565_2D[] = {
+ 68, 88, 66, 67, 120, 138, 72, 172, 147, 159, 222, 80, 129, 231, 133, 236, 125, 211, 201,
+ 82, 1, 0, 0, 0, 36, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 44, 1, 0, 0, 96, 1, 0, 0, 168, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 49, 48, 46, 49, 0,
+ 171, 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, 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, 83, 72, 68, 82, 64, 1, 0, 0, 64,
+ 0, 0, 0, 80, 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, 0, 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, 56, 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2,
+ 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 248, 65, 0, 0, 124, 66, 0,
+ 0, 248, 65, 0, 0, 0, 0, 64, 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0,
+ 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 114, 32, 16, 0, 0, 0, 0,
+ 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 8, 33, 4, 61, 33, 8,
+ 130, 60, 8, 33, 4, 61, 0, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0,
+ 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84,
+ 116, 0, 0, 0, 9, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0,
+ 0, 5, 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, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_565_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_565_2darray_ps.h
new file mode 100644
index 0000000000..b36c06adb0
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_565_2darray_ps.h
@@ -0,0 +1,100 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_2DArray texture float4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2darray (float,float,float,float) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 2
+utof r0.z, v1.x
+mov r0.xy, v2.xyxx
+sample r0.xyzw, r0.xyzx, t0.xyzw, s0
+lt r1.x, l(0.000000), r0.w
+div r1.yzw, r0.xxyz, r0.wwww
+movc r0.xyz, r1.xxxx, r1.yzwy, r0.xyzx
+mul r0.xyz, r0.xyzx, l(31.000000, 63.000000, 31.000000, 0.000000)
+round_ne r0.xyz, r0.xyzx
+mul o0.xyz, r0.xyzx, l(0.032258, 0.015873, 0.032258, 0.000000)
+mov o0.w, l(1.000000)
+ret
+// Approximately 11 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_UM_RGB_565_2DArray[] = {
+ 68, 88, 66, 67, 44, 2, 174, 208, 118, 237, 233, 207, 57, 29, 178, 223, 138, 140, 88,
+ 102, 1, 0, 0, 0, 148, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0,
+ 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 24, 3, 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, 117, 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, 5,
+ 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, 95, 50, 68,
+ 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0,
+ 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0,
+ 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0,
+ 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95,
+ 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78,
+ 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 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, 83, 72, 68, 82, 120, 1, 0, 0, 64, 0,
+ 0, 0, 94, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88,
+ 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4,
+ 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16,
+ 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0,
+ 0, 2, 2, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10,
+ 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0,
+ 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0,
+ 0, 70, 2, 16, 0, 0, 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, 0, 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, 56, 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0,
+ 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 248, 65, 0, 0, 124, 66, 0, 0, 248,
+ 65, 0, 0, 0, 0, 64, 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2,
+ 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 114, 32, 16, 0, 0, 0, 0, 0, 70,
+ 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 8, 33, 4, 61, 33, 8, 130, 60,
+ 8, 33, 4, 61, 0, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0,
+ 0, 1, 64, 0, 0, 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0,
+ 0, 0, 11, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 5,
+ 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, 2, 0, 0, 0, 1, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_565_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_565_3d_ps.h
new file mode 100644
index 0000000000..8de8d85d37
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgb_565_3d_ps.h
@@ -0,0 +1,93 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_3D texture float4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 2
+sample r0.xyzw, v2.xyzx, t0.xyzw, s0
+lt r1.x, l(0.000000), r0.w
+div r1.yzw, r0.xxyz, r0.wwww
+movc r0.xyz, r1.xxxx, r1.yzwy, r0.xyzx
+mul r0.xyz, r0.xyzx, l(31.000000, 63.000000, 31.000000, 0.000000)
+round_ne r0.xyz, r0.xyzx
+mul o0.xyz, r0.xyzx, l(0.032258, 0.015873, 0.032258, 0.000000)
+mov o0.w, l(1.000000)
+ret
+// Approximately 9 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_UM_RGB_565_3D[] = {
+ 68, 88, 66, 67, 250, 168, 68, 191, 15, 51, 156, 108, 63, 18, 251, 133, 207, 174, 26,
+ 44, 1, 0, 0, 0, 84, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 216, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 112, 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, 8,
+ 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, 95, 51, 68,
+ 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, 49, 48,
+ 46, 49, 0, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 83, 72, 68, 82, 64, 1, 0, 0, 64, 0, 0, 0, 80, 0, 0, 0, 90, 0,
+ 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 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, 18, 16, 0, 2, 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, 0, 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, 56, 0, 0, 10,
+ 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0,
+ 0, 0, 0, 248, 65, 0, 0, 124, 66, 0, 0, 248, 65, 0, 0, 0, 0, 64, 0,
+ 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56,
+ 0, 0, 10, 114, 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0,
+ 2, 64, 0, 0, 8, 33, 4, 61, 33, 8, 130, 60, 8, 33, 4, 61, 0, 0, 0,
+ 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0,
+ 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 9, 0, 0, 0, 2,
+ 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 5, 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, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_2d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_2d_ps.h
new file mode 100644
index 0000000000..764b560d78
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_2d_ps.h
@@ -0,0 +1,82 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 2d t0 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
+//
+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_FtoF_UM_RGBA_2D[] = {
+ 68, 88, 66, 67, 43, 116, 27, 96, 239, 39, 33, 81, 44, 127, 180, 166, 1, 156, 105,
+ 167, 1, 0, 0, 0, 192, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 44, 1, 0, 0, 96, 1, 0, 0, 68, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 49, 48, 46, 49, 0,
+ 171, 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, 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, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_2darray_ps.h
new file mode 100644
index 0000000000..84cf6ebefa
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_2darray_ps.h
@@ -0,0 +1,91 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_2DArray texture float4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2darray (float,float,float,float) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 2
+utof r0.z, v1.x
+mov r0.xy, v2.xyxx
+sample r0.xyzw, r0.xyzx, 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 8 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_UM_RGBA_2DArray[] = {
+ 68, 88, 66, 67, 226, 210, 183, 205, 237, 244, 131, 11, 158, 229, 134, 100, 181, 52, 86,
+ 124, 1, 0, 0, 0, 48, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0,
+ 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 180, 2, 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, 117, 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, 5,
+ 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, 95, 50, 68,
+ 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0,
+ 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0,
+ 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0,
+ 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95,
+ 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78,
+ 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 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, 83, 72, 68, 82, 20, 1, 0, 0, 64, 0,
+ 0, 0, 69, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88,
+ 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4,
+ 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16,
+ 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0,
+ 0, 2, 2, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10,
+ 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0,
+ 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0,
+ 0, 70, 2, 16, 0, 0, 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, 8, 0, 0,
+ 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 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, 2, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_3d_ps.h
new file mode 100644
index 0000000000..d0725735e4
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_3d_ps.h
@@ -0,0 +1,85 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_3D texture float4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 2
+sample r0.xyzw, v2.xyzx, 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_FtoF_UM_RGBA_3D[] = {
+ 68, 88, 66, 67, 47, 35, 68, 46, 230, 212, 160, 221, 21, 19, 140, 22, 115, 9, 100,
+ 58, 1, 0, 0, 0, 240, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 116, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 112, 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, 8,
+ 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, 95, 51, 68,
+ 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, 49, 48,
+ 46, 49, 0, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 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, 40, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 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, 18, 16, 0, 2, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_4444_2d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_4444_2d_ps.h
new file mode 100644
index 0000000000..cfa23a7bf9
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_4444_2d_ps.h
@@ -0,0 +1,88 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 2d t0 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
+//
+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 r0.xyz, r1.xxxx, r1.yzwy, r0.xyzx
+mul r0.xyzw, r0.xyzw, l(15.000000, 15.000000, 15.000000, 15.000000)
+round_ne r0.xyzw, r0.xyzw
+mul o0.xyzw, r0.xyzw, l(0.066667, 0.066667, 0.066667, 0.066667)
+ret
+// Approximately 8 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_UM_RGBA_4444_2D[] = {
+ 68, 88, 66, 67, 233, 41, 159, 52, 49, 178, 50, 48, 148, 28, 18, 200, 140, 164, 4,
+ 13, 1, 0, 0, 0, 16, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 44, 1, 0, 0, 96, 1, 0, 0, 148, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 49, 48, 46, 49, 0,
+ 171, 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, 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, 83, 72, 68, 82, 44, 1, 0, 0, 64,
+ 0, 0, 0, 75, 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, 0, 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, 56, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14,
+ 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 112, 65, 0, 0, 112, 65, 0,
+ 0, 112, 65, 0, 0, 112, 65, 64, 0, 0, 5, 242, 0, 16, 0, 0, 0, 0, 0,
+ 70, 14, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 32, 16, 0, 0, 0, 0,
+ 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 137, 136, 136, 61, 137, 136,
+ 136, 61, 137, 136, 136, 61, 137, 136, 136, 61, 62, 0, 0, 1, 83, 84, 65, 84, 116,
+ 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0,
+ 5, 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, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_4444_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_4444_2darray_ps.h
new file mode 100644
index 0000000000..1a08e60147
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_4444_2darray_ps.h
@@ -0,0 +1,98 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_2DArray texture float4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2darray (float,float,float,float) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 2
+utof r0.z, v1.x
+mov r0.xy, v2.xyxx
+sample r0.xyzw, r0.xyzx, t0.xyzw, s0
+lt r1.x, l(0.000000), r0.w
+div r1.yzw, r0.xxyz, r0.wwww
+movc r0.xyz, r1.xxxx, r1.yzwy, r0.xyzx
+mul r0.xyzw, r0.xyzw, l(15.000000, 15.000000, 15.000000, 15.000000)
+round_ne r0.xyzw, r0.xyzw
+mul o0.xyzw, r0.xyzw, l(0.066667, 0.066667, 0.066667, 0.066667)
+ret
+// Approximately 10 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_UM_RGBA_4444_2DArray[] = {
+ 68, 88, 66, 67, 51, 224, 15, 241, 219, 215, 90, 241, 40, 140, 3, 53, 152, 74, 169,
+ 200, 1, 0, 0, 0, 128, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0,
+ 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 4, 3, 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, 117, 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, 5,
+ 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, 95, 50, 68,
+ 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0,
+ 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0,
+ 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0,
+ 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95,
+ 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78,
+ 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 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, 83, 72, 68, 82, 100, 1, 0, 0, 64, 0,
+ 0, 0, 89, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88,
+ 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4,
+ 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16,
+ 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0,
+ 0, 2, 2, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10,
+ 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0,
+ 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0,
+ 0, 70, 2, 16, 0, 0, 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, 0, 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, 56, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0,
+ 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 112, 65, 0, 0, 112, 65, 0, 0, 112,
+ 65, 0, 0, 112, 65, 64, 0, 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14,
+ 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 32, 16, 0, 0, 0, 0, 0, 70,
+ 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 137, 136, 136, 61, 137, 136, 136, 61,
+ 137, 136, 136, 61, 137, 136, 136, 61, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0,
+ 0, 10, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 5, 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, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_4444_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_4444_3d_ps.h
new file mode 100644
index 0000000000..ef493e3f4b
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_4444_3d_ps.h
@@ -0,0 +1,91 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_3D texture float4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 2
+sample r0.xyzw, v2.xyzx, t0.xyzw, s0
+lt r1.x, l(0.000000), r0.w
+div r1.yzw, r0.xxyz, r0.wwww
+movc r0.xyz, r1.xxxx, r1.yzwy, r0.xyzx
+mul r0.xyzw, r0.xyzw, l(15.000000, 15.000000, 15.000000, 15.000000)
+round_ne r0.xyzw, r0.xyzw
+mul o0.xyzw, r0.xyzw, l(0.066667, 0.066667, 0.066667, 0.066667)
+ret
+// Approximately 8 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_UM_RGBA_4444_3D[] = {
+ 68, 88, 66, 67, 210, 247, 48, 228, 222, 252, 207, 191, 86, 78, 158, 63, 239, 245, 179,
+ 7, 1, 0, 0, 0, 64, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 196, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 112, 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, 8,
+ 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, 95, 51, 68,
+ 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, 49, 48,
+ 46, 49, 0, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 83, 72, 68, 82, 44, 1, 0, 0, 64, 0, 0, 0, 75, 0, 0, 0, 90, 0,
+ 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 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, 18, 16, 0, 2, 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, 0, 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, 56, 0, 0, 10,
+ 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0,
+ 0, 0, 0, 112, 65, 0, 0, 112, 65, 0, 0, 112, 65, 0, 0, 112, 65, 64, 0,
+ 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 56,
+ 0, 0, 10, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0,
+ 2, 64, 0, 0, 137, 136, 136, 61, 137, 136, 136, 61, 137, 136, 136, 61, 137, 136, 136,
+ 61, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 8, 0, 0, 0, 2, 0,
+ 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 5, 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, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_5551_2d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_5551_2d_ps.h
new file mode 100644
index 0000000000..42829c90c9
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_5551_2d_ps.h
@@ -0,0 +1,88 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 2d t0 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
+//
+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 r0.xyz, r1.xxxx, r1.yzwy, r0.xyzx
+mul r0.xyzw, r0.xyzw, l(31.000000, 31.000000, 31.000000, 1.000000)
+round_ne r0.xyzw, r0.xyzw
+mul o0.xyzw, r0.xyzw, l(0.032258, 0.032258, 0.032258, 1.000000)
+ret
+// Approximately 8 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_UM_RGBA_5551_2D[] = {
+ 68, 88, 66, 67, 140, 39, 186, 158, 51, 211, 162, 56, 171, 90, 89, 241, 42, 247, 30,
+ 222, 1, 0, 0, 0, 16, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 44, 1, 0, 0, 96, 1, 0, 0, 148, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 49, 48, 46, 49, 0,
+ 171, 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, 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, 83, 72, 68, 82, 44, 1, 0, 0, 64,
+ 0, 0, 0, 75, 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, 0, 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, 56, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14,
+ 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 248, 65, 0, 0, 248, 65, 0,
+ 0, 248, 65, 0, 0, 128, 63, 64, 0, 0, 5, 242, 0, 16, 0, 0, 0, 0, 0,
+ 70, 14, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 32, 16, 0, 0, 0, 0,
+ 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 8, 33, 4, 61, 8, 33,
+ 4, 61, 8, 33, 4, 61, 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, 116,
+ 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0,
+ 5, 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, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_5551_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_5551_2darray_ps.h
new file mode 100644
index 0000000000..22389cfa5d
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_5551_2darray_ps.h
@@ -0,0 +1,98 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_2DArray texture float4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2darray (float,float,float,float) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 2
+utof r0.z, v1.x
+mov r0.xy, v2.xyxx
+sample r0.xyzw, r0.xyzx, t0.xyzw, s0
+lt r1.x, l(0.000000), r0.w
+div r1.yzw, r0.xxyz, r0.wwww
+movc r0.xyz, r1.xxxx, r1.yzwy, r0.xyzx
+mul r0.xyzw, r0.xyzw, l(31.000000, 31.000000, 31.000000, 1.000000)
+round_ne r0.xyzw, r0.xyzw
+mul o0.xyzw, r0.xyzw, l(0.032258, 0.032258, 0.032258, 1.000000)
+ret
+// Approximately 10 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_UM_RGBA_5551_2DArray[] = {
+ 68, 88, 66, 67, 17, 161, 17, 46, 139, 141, 231, 172, 21, 139, 205, 213, 78, 192, 111,
+ 150, 1, 0, 0, 0, 128, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0,
+ 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 4, 3, 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, 117, 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, 5,
+ 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, 95, 50, 68,
+ 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0,
+ 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0,
+ 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0,
+ 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95,
+ 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78,
+ 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 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, 83, 72, 68, 82, 100, 1, 0, 0, 64, 0,
+ 0, 0, 89, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88,
+ 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4,
+ 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16,
+ 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0,
+ 0, 2, 2, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10,
+ 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0,
+ 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0,
+ 0, 70, 2, 16, 0, 0, 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, 0, 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, 56, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0,
+ 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 248, 65, 0, 0, 248, 65, 0, 0, 248,
+ 65, 0, 0, 128, 63, 64, 0, 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14,
+ 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 32, 16, 0, 0, 0, 0, 0, 70,
+ 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 8, 33, 4, 61, 8, 33, 4, 61,
+ 8, 33, 4, 61, 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0,
+ 0, 10, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 5, 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, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_5551_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_5551_3d_ps.h
new file mode 100644
index 0000000000..a97e54f1d2
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftof_um_rgba_5551_3d_ps.h
@@ -0,0 +1,91 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_3D texture float4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 2
+sample r0.xyzw, v2.xyzx, t0.xyzw, s0
+lt r1.x, l(0.000000), r0.w
+div r1.yzw, r0.xxyz, r0.wwww
+movc r0.xyz, r1.xxxx, r1.yzwy, r0.xyzx
+mul r0.xyzw, r0.xyzw, l(31.000000, 31.000000, 31.000000, 1.000000)
+round_ne r0.xyzw, r0.xyzw
+mul o0.xyzw, r0.xyzw, l(0.032258, 0.032258, 0.032258, 1.000000)
+ret
+// Approximately 8 instruction slots used
+#endif
+
+const BYTE g_PS_FtoF_UM_RGBA_5551_3D[] = {
+ 68, 88, 66, 67, 95, 144, 206, 44, 123, 213, 142, 219, 42, 152, 39, 211, 195, 66, 184,
+ 29, 1, 0, 0, 0, 64, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 196, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 112, 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, 8,
+ 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, 95, 51, 68,
+ 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, 49, 48,
+ 46, 49, 0, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 83, 72, 68, 82, 44, 1, 0, 0, 64, 0, 0, 0, 75, 0, 0, 0, 90, 0,
+ 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 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, 18, 16, 0, 2, 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, 0, 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, 56, 0, 0, 10,
+ 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0,
+ 0, 0, 0, 248, 65, 0, 0, 248, 65, 0, 0, 248, 65, 0, 0, 128, 63, 64, 0,
+ 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 56,
+ 0, 0, 10, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0,
+ 2, 64, 0, 0, 8, 33, 4, 61, 8, 33, 4, 61, 8, 33, 4, 61, 0, 0, 128,
+ 63, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 8, 0, 0, 0, 2, 0,
+ 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 5, 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, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pm_rgb_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pm_rgb_2darray_ps.h
new file mode 100644
index 0000000000..2921c17e7d
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pm_rgb_2darray_ps.h
@@ -0,0 +1,96 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_2DArray texture float4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET int xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2darray (float,float,float,float) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 1
+utof r0.z, v1.x
+mov r0.xy, v2.xyxx
+sample r0.xyzw, r0.xyzx, t0.xyzw, s0
+mul r0.xyz, r0.wwww, r0.xyzx
+mul r0.xyz, r0.xyzx, l(127.000000, 127.000000, 127.000000, 0.000000)
+round_ne r0.xyz, r0.xyzx
+mul r0.xyz, r0.xyzx, l(1.000000, 1.000000, 1.000000, 0.000000)
+ftoi o0.xyz, r0.xyzx
+mov o0.w, l(1)
+ret
+// Approximately 10 instruction slots used
+#endif
+
+const BYTE g_PS_FtoI_PM_RGB_2DArray[] = {
+ 68, 88, 66, 67, 214, 86, 133, 76, 36, 73, 187, 120, 120, 177, 199, 23, 161, 34, 44,
+ 41, 1, 0, 0, 0, 104, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0,
+ 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 236, 2, 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, 117, 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, 5,
+ 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, 95, 50, 68,
+ 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0,
+ 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0,
+ 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0,
+ 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95,
+ 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78,
+ 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 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, 2, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95,
+ 84, 65, 82, 71, 69, 84, 0, 171, 171, 83, 72, 68, 82, 76, 1, 0, 0, 64, 0,
+ 0, 0, 83, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88,
+ 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4,
+ 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16,
+ 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0,
+ 0, 2, 1, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10,
+ 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0,
+ 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0,
+ 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96,
+ 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 0, 0, 0, 0, 246,
+ 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10,
+ 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0,
+ 0, 0, 0, 254, 66, 0, 0, 254, 66, 0, 0, 254, 66, 0, 0, 0, 0, 64, 0,
+ 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56,
+ 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0,
+ 2, 64, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 0,
+ 0, 27, 0, 0, 5, 114, 32, 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, 1, 64, 0, 0, 1,
+ 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, 3, 0, 0, 0, 4, 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, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pm_rgb_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pm_rgb_3d_ps.h
new file mode 100644
index 0000000000..18741678e1
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pm_rgb_3d_ps.h
@@ -0,0 +1,90 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_3D texture float4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET int xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v2.xyzx, t0.xyzw, s0
+mul r0.xyz, r0.wwww, r0.xyzx
+mul r0.xyz, r0.xyzx, l(127.000000, 127.000000, 127.000000, 0.000000)
+round_ne r0.xyz, r0.xyzx
+mul r0.xyz, r0.xyzx, l(1.000000, 1.000000, 1.000000, 0.000000)
+ftoi o0.xyz, r0.xyzx
+mov o0.w, l(1)
+ret
+// Approximately 8 instruction slots used
+#endif
+
+const BYTE g_PS_FtoI_PM_RGB_3D[] = {
+ 68, 88, 66, 67, 233, 244, 68, 31, 244, 75, 174, 119, 157, 230, 155, 216, 124, 72, 238,
+ 41, 1, 0, 0, 0, 40, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 172, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 112, 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, 8,
+ 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, 95, 51, 68,
+ 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, 49, 48,
+ 46, 49, 0, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 2, 0, 0, 0,
+ 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 171,
+ 171, 83, 72, 68, 82, 20, 1, 0, 0, 64, 0, 0, 0, 69, 0, 0, 0, 90, 0,
+ 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 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, 18, 16, 0, 2, 0,
+ 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56,
+ 0, 0, 7, 114, 0, 16, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0,
+ 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 114, 0, 16, 0, 0, 0, 0,
+ 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 254, 66, 0, 0,
+ 254, 66, 0, 0, 254, 66, 0, 0, 0, 0, 64, 0, 0, 5, 114, 0, 16, 0, 0,
+ 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 114, 0, 16, 0,
+ 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128,
+ 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 0, 0, 27, 0, 0, 5, 114, 32,
+ 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, 1, 64, 0, 0, 1, 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, 4, 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, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pm_rgba_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pm_rgba_2darray_ps.h
new file mode 100644
index 0000000000..f877df2d74
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pm_rgba_2darray_ps.h
@@ -0,0 +1,94 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_2DArray texture float4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET int xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2darray (float,float,float,float) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 1
+utof r0.z, v1.x
+mov r0.xy, v2.xyxx
+sample r0.xyzw, r0.xyzx, t0.xyzw, s0
+mul r0.xyz, r0.wwww, r0.xyzx
+mul r0.xyzw, r0.xyzw, l(127.000000, 127.000000, 127.000000, 127.000000)
+round_ne r0.xyzw, r0.xyzw
+mul r0.xyzw, r0.xyzw, l(1.000000, 1.000000, 1.000000, 1.000000)
+ftoi o0.xyzw, r0.xyzw
+ret
+// Approximately 9 instruction slots used
+#endif
+
+const BYTE g_PS_FtoI_PM_RGBA_2DArray[] = {
+ 68, 88, 66, 67, 6, 46, 120, 27, 94, 101, 87, 132, 53, 181, 154, 63, 109, 237, 51,
+ 143, 1, 0, 0, 0, 84, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0,
+ 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 216, 2, 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, 117, 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, 5,
+ 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, 95, 50, 68,
+ 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0,
+ 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0,
+ 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0,
+ 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95,
+ 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78,
+ 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 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, 2, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95,
+ 84, 65, 82, 71, 69, 84, 0, 171, 171, 83, 72, 68, 82, 56, 1, 0, 0, 64, 0,
+ 0, 0, 78, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88,
+ 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4,
+ 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16,
+ 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0,
+ 0, 2, 1, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10,
+ 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0,
+ 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0,
+ 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96,
+ 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 0, 0, 0, 0, 246,
+ 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10,
+ 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0,
+ 0, 0, 0, 254, 66, 0, 0, 254, 66, 0, 0, 254, 66, 0, 0, 254, 66, 64, 0,
+ 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 56,
+ 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0,
+ 2, 64, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128,
+ 63, 27, 0, 0, 5, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 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, 3, 0, 0, 0, 4, 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, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pm_rgba_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pm_rgba_3d_ps.h
new file mode 100644
index 0000000000..e4b96a279b
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pm_rgba_3d_ps.h
@@ -0,0 +1,88 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_3D texture float4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET int xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v2.xyzx, t0.xyzw, s0
+mul r0.xyz, r0.wwww, r0.xyzx
+mul r0.xyzw, r0.xyzw, l(127.000000, 127.000000, 127.000000, 127.000000)
+round_ne r0.xyzw, r0.xyzw
+mul r0.xyzw, r0.xyzw, l(1.000000, 1.000000, 1.000000, 1.000000)
+ftoi o0.xyzw, r0.xyzw
+ret
+// Approximately 7 instruction slots used
+#endif
+
+const BYTE g_PS_FtoI_PM_RGBA_3D[] = {
+ 68, 88, 66, 67, 249, 90, 79, 118, 112, 44, 159, 0, 189, 165, 140, 198, 201, 78, 213,
+ 100, 1, 0, 0, 0, 20, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 152, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 112, 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, 8,
+ 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, 95, 51, 68,
+ 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, 49, 48,
+ 46, 49, 0, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 2, 0, 0, 0,
+ 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 171,
+ 171, 83, 72, 68, 82, 0, 1, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 90, 0,
+ 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 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, 18, 16, 0, 2, 0,
+ 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56,
+ 0, 0, 7, 114, 0, 16, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0,
+ 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0,
+ 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 254, 66, 0, 0,
+ 254, 66, 0, 0, 254, 66, 0, 0, 254, 66, 64, 0, 0, 5, 242, 0, 16, 0, 0,
+ 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0,
+ 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128,
+ 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 27, 0, 0, 5, 242, 32,
+ 16, 0, 0, 0, 0, 0, 70, 14, 16, 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, 0, 0, 0, 0,
+ 2, 0, 0, 0, 4, 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, 0, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pt_rgb_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pt_rgb_2darray_ps.h
new file mode 100644
index 0000000000..8970316b3d
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pt_rgb_2darray_ps.h
@@ -0,0 +1,94 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_2DArray texture float4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET int xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2darray (float,float,float,float) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 1
+utof r0.z, v1.x
+mov r0.xy, v2.xyxx
+sample r0.xyzw, r0.xyzx, t0.xyzw, s0
+mul r0.xyz, r0.xyzx, l(127.000000, 127.000000, 127.000000, 0.000000)
+round_ne r0.xyz, r0.xyzx
+mul r0.xyz, r0.xyzx, l(1.000000, 1.000000, 1.000000, 0.000000)
+ftoi o0.xyz, r0.xyzx
+mov o0.w, l(1)
+ret
+// Approximately 9 instruction slots used
+#endif
+
+const BYTE g_PS_FtoI_PT_RGB_2DArray[] = {
+ 68, 88, 66, 67, 168, 185, 143, 219, 147, 147, 203, 58, 217, 196, 122, 65, 228, 189, 209,
+ 238, 1, 0, 0, 0, 76, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0,
+ 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 208, 2, 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, 117, 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, 5,
+ 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, 95, 50, 68,
+ 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0,
+ 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0,
+ 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0,
+ 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95,
+ 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78,
+ 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 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, 2, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95,
+ 84, 65, 82, 71, 69, 84, 0, 171, 171, 83, 72, 68, 82, 48, 1, 0, 0, 64, 0,
+ 0, 0, 76, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88,
+ 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4,
+ 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16,
+ 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0,
+ 0, 2, 1, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10,
+ 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0,
+ 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0,
+ 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96,
+ 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 70,
+ 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 254, 66, 0, 0, 254, 66,
+ 0, 0, 254, 66, 0, 0, 0, 0, 64, 0, 0, 5, 114, 0, 16, 0, 0, 0, 0,
+ 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 114, 0, 16, 0, 0, 0,
+ 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 63, 0,
+ 0, 128, 63, 0, 0, 128, 63, 0, 0, 0, 0, 27, 0, 0, 5, 114, 32, 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, 1, 64, 0, 0, 1, 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, 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, 1, 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, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pt_rgb_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pt_rgb_3d_ps.h
new file mode 100644
index 0000000000..3f93541ea7
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pt_rgb_3d_ps.h
@@ -0,0 +1,88 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_3D texture float4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET int xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v2.xyzx, t0.xyzw, s0
+mul r0.xyz, r0.xyzx, l(127.000000, 127.000000, 127.000000, 0.000000)
+round_ne r0.xyz, r0.xyzx
+mul r0.xyz, r0.xyzx, l(1.000000, 1.000000, 1.000000, 0.000000)
+ftoi o0.xyz, r0.xyzx
+mov o0.w, l(1)
+ret
+// Approximately 7 instruction slots used
+#endif
+
+const BYTE g_PS_FtoI_PT_RGB_3D[] = {
+ 68, 88, 66, 67, 65, 66, 171, 227, 204, 106, 7, 188, 141, 169, 26, 209, 77, 251, 140,
+ 247, 1, 0, 0, 0, 12, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 144, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 112, 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, 8,
+ 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, 95, 51, 68,
+ 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, 49, 48,
+ 46, 49, 0, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 2, 0, 0, 0,
+ 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 171,
+ 171, 83, 72, 68, 82, 248, 0, 0, 0, 64, 0, 0, 0, 62, 0, 0, 0, 90, 0,
+ 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 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, 18, 16, 0, 2, 0,
+ 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56,
+ 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0,
+ 2, 64, 0, 0, 0, 0, 254, 66, 0, 0, 254, 66, 0, 0, 254, 66, 0, 0, 0,
+ 0, 64, 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0,
+ 0, 0, 56, 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0,
+ 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63,
+ 0, 0, 0, 0, 27, 0, 0, 5, 114, 32, 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, 1, 64,
+ 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 7,
+ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 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, 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, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pt_rgba_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pt_rgba_2darray_ps.h
new file mode 100644
index 0000000000..493fc2292b
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pt_rgba_2darray_ps.h
@@ -0,0 +1,92 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_2DArray texture float4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET int xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2darray (float,float,float,float) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 1
+utof r0.z, v1.x
+mov r0.xy, v2.xyxx
+sample r0.xyzw, r0.xyzx, t0.xyzw, s0
+mul r0.xyzw, r0.xyzw, l(127.000000, 127.000000, 127.000000, 127.000000)
+round_ne r0.xyzw, r0.xyzw
+mul r0.xyzw, r0.xyzw, l(1.000000, 1.000000, 1.000000, 1.000000)
+ftoi o0.xyzw, r0.xyzw
+ret
+// Approximately 8 instruction slots used
+#endif
+
+const BYTE g_PS_FtoI_PT_RGBA_2DArray[] = {
+ 68, 88, 66, 67, 157, 78, 228, 79, 217, 28, 225, 96, 83, 195, 47, 176, 240, 168, 229,
+ 128, 1, 0, 0, 0, 56, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0,
+ 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 188, 2, 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, 117, 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, 5,
+ 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, 95, 50, 68,
+ 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0,
+ 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0,
+ 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0,
+ 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95,
+ 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78,
+ 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 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, 2, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95,
+ 84, 65, 82, 71, 69, 84, 0, 171, 171, 83, 72, 68, 82, 28, 1, 0, 0, 64, 0,
+ 0, 0, 71, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88,
+ 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4,
+ 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16,
+ 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0,
+ 0, 2, 1, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10,
+ 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0,
+ 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0,
+ 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96,
+ 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70,
+ 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 254, 66, 0, 0, 254, 66,
+ 0, 0, 254, 66, 0, 0, 254, 66, 64, 0, 0, 5, 242, 0, 16, 0, 0, 0, 0,
+ 0, 70, 14, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 0, 0,
+ 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 63, 0,
+ 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 27, 0, 0, 5, 242, 32, 16, 0,
+ 0, 0, 0, 0, 70, 14, 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, 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, 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, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pt_rgba_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pt_rgba_3d_ps.h
new file mode 100644
index 0000000000..c602d2fb2e
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_pt_rgba_3d_ps.h
@@ -0,0 +1,85 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_3D texture float4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET int xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v2.xyzx, t0.xyzw, s0
+mul r0.xyzw, r0.xyzw, l(127.000000, 127.000000, 127.000000, 127.000000)
+round_ne r0.xyzw, r0.xyzw
+mul r0.xyzw, r0.xyzw, l(1.000000, 1.000000, 1.000000, 1.000000)
+ftoi o0.xyzw, r0.xyzw
+ret
+// Approximately 6 instruction slots used
+#endif
+
+const BYTE g_PS_FtoI_PT_RGBA_3D[] = {
+ 68, 88, 66, 67, 73, 236, 106, 44, 249, 119, 115, 91, 94, 156, 145, 139, 146, 47, 33,
+ 36, 1, 0, 0, 0, 248, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 124, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 112, 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, 8,
+ 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, 95, 51, 68,
+ 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, 49, 48,
+ 46, 49, 0, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 2, 0, 0, 0,
+ 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 171,
+ 171, 83, 72, 68, 82, 228, 0, 0, 0, 64, 0, 0, 0, 57, 0, 0, 0, 90, 0,
+ 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 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, 18, 16, 0, 2, 0,
+ 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56,
+ 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0,
+ 2, 64, 0, 0, 0, 0, 254, 66, 0, 0, 254, 66, 0, 0, 254, 66, 0, 0, 254,
+ 66, 64, 0, 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0,
+ 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0,
+ 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63,
+ 0, 0, 128, 63, 27, 0, 0, 5, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16,
+ 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 6, 0,
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 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, 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, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_um_rgb_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_um_rgb_2darray_ps.h
new file mode 100644
index 0000000000..8335a149c6
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_um_rgb_2darray_ps.h
@@ -0,0 +1,102 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_2DArray texture float4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET int xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2darray (float,float,float,float) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 2
+utof r0.z, v1.x
+mov r0.xy, v2.xyxx
+sample r0.xyzw, r0.xyzx, t0.xyzw, s0
+lt r1.x, l(0.000000), r0.w
+div r1.yzw, r0.xxyz, r0.wwww
+movc r0.xyz, r1.xxxx, r1.yzwy, r0.xyzx
+mul r0.xyz, r0.xyzx, l(127.000000, 127.000000, 127.000000, 0.000000)
+round_ne r0.xyz, r0.xyzx
+mul r0.xyz, r0.xyzx, l(1.000000, 1.000000, 1.000000, 0.000000)
+ftoi o0.xyz, r0.xyzx
+mov o0.w, l(1)
+ret
+// Approximately 12 instruction slots used
+#endif
+
+const BYTE g_PS_FtoI_UM_RGB_2DArray[] = {
+ 68, 88, 66, 67, 229, 156, 153, 172, 30, 111, 168, 172, 47, 75, 227, 206, 198, 78, 62,
+ 42, 1, 0, 0, 0, 168, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0,
+ 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 44, 3, 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, 117, 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, 5,
+ 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, 95, 50, 68,
+ 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0,
+ 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0,
+ 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0,
+ 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95,
+ 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78,
+ 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 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, 2, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95,
+ 84, 65, 82, 71, 69, 84, 0, 171, 171, 83, 72, 68, 82, 140, 1, 0, 0, 64, 0,
+ 0, 0, 99, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88,
+ 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4,
+ 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16,
+ 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0,
+ 0, 2, 2, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10,
+ 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0,
+ 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0,
+ 0, 70, 2, 16, 0, 0, 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, 0, 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, 56, 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0,
+ 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 254, 66, 0, 0, 254, 66, 0, 0, 254,
+ 66, 0, 0, 0, 0, 64, 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2,
+ 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 70,
+ 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63,
+ 0, 0, 128, 63, 0, 0, 0, 0, 27, 0, 0, 5, 114, 32, 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, 1, 64, 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116,
+ 0, 0, 0, 12, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,
+ 5, 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, 2, 0, 0, 0, 1, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_um_rgb_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_um_rgb_3d_ps.h
new file mode 100644
index 0000000000..2df877322f
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_um_rgb_3d_ps.h
@@ -0,0 +1,95 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_3D texture float4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET int xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 2
+sample r0.xyzw, v2.xyzx, t0.xyzw, s0
+lt r1.x, l(0.000000), r0.w
+div r1.yzw, r0.xxyz, r0.wwww
+movc r0.xyz, r1.xxxx, r1.yzwy, r0.xyzx
+mul r0.xyz, r0.xyzx, l(127.000000, 127.000000, 127.000000, 0.000000)
+round_ne r0.xyz, r0.xyzx
+mul r0.xyz, r0.xyzx, l(1.000000, 1.000000, 1.000000, 0.000000)
+ftoi o0.xyz, r0.xyzx
+mov o0.w, l(1)
+ret
+// Approximately 10 instruction slots used
+#endif
+
+const BYTE g_PS_FtoI_UM_RGB_3D[] = {
+ 68, 88, 66, 67, 23, 5, 101, 80, 190, 217, 192, 233, 141, 228, 109, 126, 239, 211, 129,
+ 244, 1, 0, 0, 0, 104, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 236, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 112, 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, 8,
+ 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, 95, 51, 68,
+ 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, 49, 48,
+ 46, 49, 0, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 2, 0, 0, 0,
+ 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 171,
+ 171, 83, 72, 68, 82, 84, 1, 0, 0, 64, 0, 0, 0, 85, 0, 0, 0, 90, 0,
+ 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 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, 18, 16, 0, 2, 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, 0, 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, 56, 0, 0, 10,
+ 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0,
+ 0, 0, 0, 254, 66, 0, 0, 254, 66, 0, 0, 254, 66, 0, 0, 0, 0, 64, 0,
+ 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56,
+ 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0,
+ 2, 64, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 0,
+ 0, 27, 0, 0, 5, 114, 32, 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, 1, 64, 0, 0, 1,
+ 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 10, 0, 0, 0,
+ 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 5, 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, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_um_rgba_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_um_rgba_2darray_ps.h
new file mode 100644
index 0000000000..3d4dfa2bb9
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_um_rgba_2darray_ps.h
@@ -0,0 +1,100 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_2DArray texture float4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET int xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2darray (float,float,float,float) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 2
+utof r0.z, v1.x
+mov r0.xy, v2.xyxx
+sample r0.xyzw, r0.xyzx, t0.xyzw, s0
+lt r1.x, l(0.000000), r0.w
+div r1.yzw, r0.xxyz, r0.wwww
+movc r0.xyz, r1.xxxx, r1.yzwy, r0.xyzx
+mul r0.xyzw, r0.xyzw, l(127.000000, 127.000000, 127.000000, 127.000000)
+round_ne r0.xyzw, r0.xyzw
+mul r0.xyzw, r0.xyzw, l(1.000000, 1.000000, 1.000000, 1.000000)
+ftoi o0.xyzw, r0.xyzw
+ret
+// Approximately 11 instruction slots used
+#endif
+
+const BYTE g_PS_FtoI_UM_RGBA_2DArray[] = {
+ 68, 88, 66, 67, 131, 143, 223, 155, 139, 202, 127, 87, 193, 203, 100, 239, 91, 19, 167,
+ 10, 1, 0, 0, 0, 148, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0,
+ 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 24, 3, 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, 117, 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, 5,
+ 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, 95, 50, 68,
+ 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0,
+ 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0,
+ 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0,
+ 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95,
+ 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78,
+ 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 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, 2, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95,
+ 84, 65, 82, 71, 69, 84, 0, 171, 171, 83, 72, 68, 82, 120, 1, 0, 0, 64, 0,
+ 0, 0, 94, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88,
+ 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4,
+ 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16,
+ 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0,
+ 0, 2, 2, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10,
+ 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0,
+ 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0,
+ 0, 70, 2, 16, 0, 0, 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, 0, 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, 56, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0,
+ 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 254, 66, 0, 0, 254, 66, 0, 0, 254,
+ 66, 0, 0, 254, 66, 64, 0, 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14,
+ 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70,
+ 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63,
+ 0, 0, 128, 63, 0, 0, 128, 63, 27, 0, 0, 5, 242, 32, 16, 0, 0, 0, 0,
+ 0, 70, 14, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0,
+ 0, 0, 11, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 5,
+ 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, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_um_rgba_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_um_rgba_3d_ps.h
new file mode 100644
index 0000000000..89b06059e3
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftoi_um_rgba_3d_ps.h
@@ -0,0 +1,93 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_3D texture float4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET int xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 2
+sample r0.xyzw, v2.xyzx, t0.xyzw, s0
+lt r1.x, l(0.000000), r0.w
+div r1.yzw, r0.xxyz, r0.wwww
+movc r0.xyz, r1.xxxx, r1.yzwy, r0.xyzx
+mul r0.xyzw, r0.xyzw, l(127.000000, 127.000000, 127.000000, 127.000000)
+round_ne r0.xyzw, r0.xyzw
+mul r0.xyzw, r0.xyzw, l(1.000000, 1.000000, 1.000000, 1.000000)
+ftoi o0.xyzw, r0.xyzw
+ret
+// Approximately 9 instruction slots used
+#endif
+
+const BYTE g_PS_FtoI_UM_RGBA_3D[] = {
+ 68, 88, 66, 67, 221, 247, 207, 180, 133, 35, 246, 152, 57, 87, 23, 116, 186, 51, 233,
+ 199, 1, 0, 0, 0, 84, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 216, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 112, 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, 8,
+ 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, 95, 51, 68,
+ 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, 49, 48,
+ 46, 49, 0, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 2, 0, 0, 0,
+ 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 171,
+ 171, 83, 72, 68, 82, 64, 1, 0, 0, 64, 0, 0, 0, 80, 0, 0, 0, 90, 0,
+ 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 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, 18, 16, 0, 2, 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, 0, 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, 56, 0, 0, 10,
+ 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0,
+ 0, 0, 0, 254, 66, 0, 0, 254, 66, 0, 0, 254, 66, 0, 0, 254, 66, 64, 0,
+ 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 56,
+ 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0,
+ 2, 64, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128,
+ 63, 27, 0, 0, 5, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0,
+ 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 9, 0, 0, 0, 2,
+ 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 5, 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, 0, 0, 0, 0, 1,
+ 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgb_2d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgb_2d_ps.h
new file mode 100644
index 0000000000..29a60b7f93
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgb_2d_ps.h
@@ -0,0 +1,81 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 2d t0 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 uint xyzw
+//
+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 r0.xyz, r0.wwww, r0.xyzx
+mul r0.xyz, r0.xyzx, l(255.000000, 255.000000, 255.000000, 0.000000)
+ftou o0.xyz, r0.xyzx
+mov o0.w, l(1)
+ret
+// Approximately 6 instruction slots used
+#endif
+
+const BYTE g_PS_FtoU_PM_RGB_2D[] = {
+ 68, 88, 66, 67, 157, 10, 67, 137, 249, 135, 12, 161, 255, 107, 225, 32, 54, 65, 72,
+ 121, 1, 0, 0, 0, 188, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 44, 1, 0, 0, 96, 1, 0, 0, 64, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 49, 48, 46, 49, 0,
+ 171, 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, 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, 1, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86,
+ 95, 84, 65, 82, 71, 69, 84, 0, 171, 171, 83, 72, 68, 82, 216, 0, 0, 0, 64,
+ 0, 0, 0, 54, 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, 0, 16, 0, 0, 0, 0,
+ 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0,
+ 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2,
+ 64, 0, 0, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 0, 0,
+ 28, 0, 0, 5, 114, 32, 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, 1, 64, 0, 0, 1, 0,
+ 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 6, 0, 0, 0, 1,
+ 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, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgb_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgb_2darray_ps.h
new file mode 100644
index 0000000000..f5937d6336
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgb_2darray_ps.h
@@ -0,0 +1,91 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_2DArray texture float4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET uint xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2darray (float,float,float,float) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 1
+utof r0.z, v1.x
+mov r0.xy, v2.xyxx
+sample r0.xyzw, r0.xyzx, t0.xyzw, s0
+mul r0.xyz, r0.wwww, r0.xyzx
+mul r0.xyz, r0.xyzx, l(255.000000, 255.000000, 255.000000, 0.000000)
+ftou o0.xyz, r0.xyzx
+mov o0.w, l(1)
+ret
+// Approximately 8 instruction slots used
+#endif
+
+const BYTE g_PS_FtoU_PM_RGB_2DArray[] = {
+ 68, 88, 66, 67, 42, 230, 32, 82, 5, 44, 80, 225, 105, 151, 142, 19, 19, 183, 76,
+ 193, 1, 0, 0, 0, 44, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0,
+ 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 176, 2, 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, 117, 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, 5,
+ 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, 95, 50, 68,
+ 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0,
+ 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0,
+ 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0,
+ 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95,
+ 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78,
+ 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 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, 1, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95,
+ 84, 65, 82, 71, 69, 84, 0, 171, 171, 83, 72, 68, 82, 16, 1, 0, 0, 64, 0,
+ 0, 0, 68, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88,
+ 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4,
+ 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16,
+ 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0,
+ 0, 2, 1, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10,
+ 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0,
+ 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0,
+ 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96,
+ 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 0, 0, 0, 0, 246,
+ 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10,
+ 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0,
+ 0, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 0, 0, 28, 0,
+ 0, 5, 114, 32, 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, 1, 64, 0, 0, 1, 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, 3, 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, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgb_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgb_3d_ps.h
new file mode 100644
index 0000000000..1e074f9236
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgb_3d_ps.h
@@ -0,0 +1,85 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_3D texture float4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET uint xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v2.xyzx, t0.xyzw, s0
+mul r0.xyz, r0.wwww, r0.xyzx
+mul r0.xyz, r0.xyzx, l(255.000000, 255.000000, 255.000000, 0.000000)
+ftou o0.xyz, r0.xyzx
+mov o0.w, l(1)
+ret
+// Approximately 6 instruction slots used
+#endif
+
+const BYTE g_PS_FtoU_PM_RGB_3D[] = {
+ 68, 88, 66, 67, 181, 194, 196, 252, 71, 44, 79, 110, 172, 188, 24, 27, 37, 220, 16,
+ 181, 1, 0, 0, 0, 236, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 112, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 112, 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, 8,
+ 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, 95, 51, 68,
+ 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, 49, 48,
+ 46, 49, 0, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 1, 0, 0, 0,
+ 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 171,
+ 171, 83, 72, 68, 82, 216, 0, 0, 0, 64, 0, 0, 0, 54, 0, 0, 0, 90, 0,
+ 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 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, 18, 16, 0, 2, 0,
+ 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56,
+ 0, 0, 7, 114, 0, 16, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0,
+ 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 114, 0, 16, 0, 0, 0, 0,
+ 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 127, 67, 0, 0,
+ 127, 67, 0, 0, 127, 67, 0, 0, 0, 0, 28, 0, 0, 5, 114, 32, 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, 1, 64, 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65,
+ 84, 116, 0, 0, 0, 6, 0, 0, 0, 1, 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, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgba_2d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgba_2d_ps.h
new file mode 100644
index 0000000000..f33e4d5bac
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgba_2d_ps.h
@@ -0,0 +1,79 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 2d t0 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 uint xyzw
+//
+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 r0.xyz, r0.wwww, r0.xyzx
+mul r0.xyzw, r0.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000)
+ftou o0.xyzw, r0.xyzw
+ret
+// Approximately 5 instruction slots used
+#endif
+
+const BYTE g_PS_FtoU_PM_RGBA_2D[] = {
+ 68, 88, 66, 67, 40, 207, 117, 251, 196, 95, 200, 222, 47, 24, 239, 143, 252, 25, 140,
+ 25, 1, 0, 0, 0, 168, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 44, 1, 0, 0, 96, 1, 0, 0, 44, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 49, 48, 46, 49, 0,
+ 171, 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, 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, 1, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86,
+ 95, 84, 65, 82, 71, 69, 84, 0, 171, 171, 83, 72, 68, 82, 196, 0, 0, 0, 64,
+ 0, 0, 0, 49, 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, 0, 16, 0, 0, 0, 0,
+ 0, 246, 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0,
+ 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2,
+ 64, 0, 0, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67,
+ 28, 0, 0, 5, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0,
+ 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 5, 0, 0, 0, 1, 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, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgba_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgba_2darray_ps.h
new file mode 100644
index 0000000000..42ceb4a597
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgba_2darray_ps.h
@@ -0,0 +1,89 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_2DArray texture float4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET uint xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2darray (float,float,float,float) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 1
+utof r0.z, v1.x
+mov r0.xy, v2.xyxx
+sample r0.xyzw, r0.xyzx, t0.xyzw, s0
+mul r0.xyz, r0.wwww, r0.xyzx
+mul r0.xyzw, r0.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000)
+ftou o0.xyzw, r0.xyzw
+ret
+// Approximately 7 instruction slots used
+#endif
+
+const BYTE g_PS_FtoU_PM_RGBA_2DArray[] = {
+ 68, 88, 66, 67, 72, 177, 176, 126, 150, 61, 34, 127, 37, 128, 200, 148, 82, 84, 84,
+ 63, 1, 0, 0, 0, 24, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0,
+ 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 156, 2, 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, 117, 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, 5,
+ 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, 95, 50, 68,
+ 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0,
+ 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0,
+ 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0,
+ 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95,
+ 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78,
+ 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 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, 1, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95,
+ 84, 65, 82, 71, 69, 84, 0, 171, 171, 83, 72, 68, 82, 252, 0, 0, 0, 64, 0,
+ 0, 0, 63, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88,
+ 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4,
+ 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16,
+ 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0,
+ 0, 2, 1, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10,
+ 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0,
+ 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0,
+ 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96,
+ 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 0, 0, 0, 0, 246,
+ 15, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10,
+ 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0,
+ 0, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 28, 0,
+ 0, 5, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 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,
+ 0, 0, 0, 0, 3, 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, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgba_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgba_3d_ps.h
new file mode 100644
index 0000000000..1e91151b5a
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pm_rgba_3d_ps.h
@@ -0,0 +1,83 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_3D texture float4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET uint xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v2.xyzx, t0.xyzw, s0
+mul r0.xyz, r0.wwww, r0.xyzx
+mul r0.xyzw, r0.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000)
+ftou o0.xyzw, r0.xyzw
+ret
+// Approximately 5 instruction slots used
+#endif
+
+const BYTE g_PS_FtoU_PM_RGBA_3D[] = {
+ 68, 88, 66, 67, 108, 177, 182, 169, 224, 190, 112, 68, 155, 228, 67, 226, 65, 238, 217,
+ 116, 1, 0, 0, 0, 216, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 92, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 112, 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, 8,
+ 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, 95, 51, 68,
+ 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, 49, 48,
+ 46, 49, 0, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 1, 0, 0, 0,
+ 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 171,
+ 171, 83, 72, 68, 82, 196, 0, 0, 0, 64, 0, 0, 0, 49, 0, 0, 0, 90, 0,
+ 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 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, 18, 16, 0, 2, 0,
+ 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56,
+ 0, 0, 7, 114, 0, 16, 0, 0, 0, 0, 0, 246, 15, 16, 0, 0, 0, 0, 0,
+ 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0,
+ 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 127, 67, 0, 0,
+ 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 28, 0, 0, 5, 242, 32, 16, 0, 0,
+ 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84,
+ 116, 0, 0, 0, 5, 0, 0, 0, 1, 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, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgb_2d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgb_2d_ps.h
new file mode 100644
index 0000000000..c74a48f769
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgb_2d_ps.h
@@ -0,0 +1,79 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 2d t0 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 uint xyzw
+//
+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 r0.xyz, r0.xyzx, l(255.000000, 255.000000, 255.000000, 0.000000)
+ftou o0.xyz, r0.xyzx
+mov o0.w, l(1)
+ret
+// Approximately 5 instruction slots used
+#endif
+
+const BYTE g_PS_FtoU_PT_RGB_2D[] = {
+ 68, 88, 66, 67, 21, 43, 226, 215, 164, 244, 10, 22, 123, 34, 48, 235, 95, 92, 229,
+ 201, 1, 0, 0, 0, 160, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 44, 1, 0, 0, 96, 1, 0, 0, 36, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 49, 48, 46, 49, 0,
+ 171, 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, 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, 1, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86,
+ 95, 84, 65, 82, 71, 69, 84, 0, 171, 171, 83, 72, 68, 82, 188, 0, 0, 0, 64,
+ 0, 0, 0, 47, 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, 10, 114, 0, 16, 0, 0, 0, 0,
+ 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 127, 67, 0, 0,
+ 127, 67, 0, 0, 127, 67, 0, 0, 0, 0, 28, 0, 0, 5, 114, 32, 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, 1, 64, 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65,
+ 84, 116, 0, 0, 0, 5, 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, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgb_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgb_2darray_ps.h
new file mode 100644
index 0000000000..dd66bae38b
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgb_2darray_ps.h
@@ -0,0 +1,89 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_2DArray texture float4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET uint xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2darray (float,float,float,float) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 1
+utof r0.z, v1.x
+mov r0.xy, v2.xyxx
+sample r0.xyzw, r0.xyzx, t0.xyzw, s0
+mul r0.xyz, r0.xyzx, l(255.000000, 255.000000, 255.000000, 0.000000)
+ftou o0.xyz, r0.xyzx
+mov o0.w, l(1)
+ret
+// Approximately 7 instruction slots used
+#endif
+
+const BYTE g_PS_FtoU_PT_RGB_2DArray[] = {
+ 68, 88, 66, 67, 135, 27, 134, 107, 134, 245, 87, 208, 181, 1, 171, 9, 139, 65, 67,
+ 42, 1, 0, 0, 0, 16, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0,
+ 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 148, 2, 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, 117, 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, 5,
+ 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, 95, 50, 68,
+ 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0,
+ 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0,
+ 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0,
+ 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95,
+ 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78,
+ 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 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, 1, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95,
+ 84, 65, 82, 71, 69, 84, 0, 171, 171, 83, 72, 68, 82, 244, 0, 0, 0, 64, 0,
+ 0, 0, 61, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88,
+ 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4,
+ 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16,
+ 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0,
+ 0, 2, 1, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10,
+ 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0,
+ 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0,
+ 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96,
+ 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 70,
+ 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 127, 67, 0, 0, 127, 67,
+ 0, 0, 127, 67, 0, 0, 0, 0, 28, 0, 0, 5, 114, 32, 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, 1, 64, 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116,
+ 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 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, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgb_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgb_3d_ps.h
new file mode 100644
index 0000000000..cedb2554e8
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgb_3d_ps.h
@@ -0,0 +1,80 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_3D texture float4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET uint xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v2.xyzx, t0.xyzw, s0
+mul r0.xyz, r0.xyzx, l(255.000000, 255.000000, 255.000000, 0.000000)
+ftou o0.xyz, r0.xyzx
+mov o0.w, l(1)
+ret
+// Approximately 5 instruction slots used
+#endif
+
+const BYTE g_PS_FtoU_PT_RGB_3D[] = {
+ 68, 88, 66, 67, 198, 108, 113, 77, 139, 67, 45, 18, 83, 139, 168, 237, 165, 209, 182, 76,
+ 1, 0, 0, 0, 208, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0, 0, 0,
+ 92, 1, 0, 0, 144, 1, 0, 0, 84, 2, 0, 0, 82, 68, 69, 70, 152, 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, 112, 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, 8, 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, 95, 51, 68, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 128, 0, 0, 0,
+ 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
+ 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0,
+ 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0,
+ 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69,
+ 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69,
+ 88, 67, 79, 79, 82, 68, 0, 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, 1, 0, 0, 0,
+ 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 171, 171,
+ 83, 72, 68, 82, 188, 0, 0, 0, 64, 0, 0, 0, 47, 0, 0, 0, 90, 0, 0, 3,
+ 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0,
+ 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 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, 18, 16, 0, 2, 0, 0, 0, 70, 126, 16, 0,
+ 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 114, 0, 16, 0,
+ 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 127, 67,
+ 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 0, 0, 28, 0, 0, 5, 114, 32, 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, 1, 64, 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84,
+ 116, 0, 0, 0, 5, 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, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgba_2d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgba_2d_ps.h
new file mode 100644
index 0000000000..22bce837e4
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgba_2d_ps.h
@@ -0,0 +1,77 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 2d t0 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 uint xyzw
+//
+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 r0.xyzw, r0.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000)
+ftou o0.xyzw, r0.xyzw
+ret
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_PS_FtoU_PT_RGBA_2D[] = {
+ 68, 88, 66, 67, 15, 203, 215, 26, 226, 132, 179, 250, 218, 76, 219, 205, 201, 184, 211,
+ 22, 1, 0, 0, 0, 140, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 44, 1, 0, 0, 96, 1, 0, 0, 16, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 49, 48, 46, 49, 0,
+ 171, 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, 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, 1, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86,
+ 95, 84, 65, 82, 71, 69, 84, 0, 171, 171, 83, 72, 68, 82, 168, 0, 0, 0, 64,
+ 0, 0, 0, 42, 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, 10, 242, 0, 16, 0, 0, 0, 0,
+ 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 127, 67, 0, 0,
+ 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 28, 0, 0, 5, 242, 32, 16, 0, 0,
+ 0, 0, 0, 70, 14, 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, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgba_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgba_2darray_ps.h
new file mode 100644
index 0000000000..3fffb1c2d3
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgba_2darray_ps.h
@@ -0,0 +1,87 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_2DArray texture float4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET uint xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2darray (float,float,float,float) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 1
+utof r0.z, v1.x
+mov r0.xy, v2.xyxx
+sample r0.xyzw, r0.xyzx, t0.xyzw, s0
+mul r0.xyzw, r0.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000)
+ftou o0.xyzw, r0.xyzw
+ret
+// Approximately 6 instruction slots used
+#endif
+
+const BYTE g_PS_FtoU_PT_RGBA_2DArray[] = {
+ 68, 88, 66, 67, 141, 122, 224, 133, 227, 61, 69, 44, 172, 221, 157, 131, 76, 235, 81,
+ 130, 1, 0, 0, 0, 252, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0,
+ 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 128, 2, 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, 117, 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, 5,
+ 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, 95, 50, 68,
+ 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0,
+ 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0,
+ 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0,
+ 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95,
+ 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78,
+ 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 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, 1, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95,
+ 84, 65, 82, 71, 69, 84, 0, 171, 171, 83, 72, 68, 82, 224, 0, 0, 0, 64, 0,
+ 0, 0, 56, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88,
+ 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4,
+ 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16,
+ 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0,
+ 0, 2, 1, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10,
+ 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0,
+ 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0,
+ 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96,
+ 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70,
+ 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 127, 67, 0, 0, 127, 67,
+ 0, 0, 127, 67, 0, 0, 127, 67, 28, 0, 0, 5, 242, 32, 16, 0, 0, 0, 0,
+ 0, 70, 14, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0,
+ 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 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, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgba_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgba_3d_ps.h
new file mode 100644
index 0000000000..bd50542b5d
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_pt_rgba_3d_ps.h
@@ -0,0 +1,80 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_3D texture float4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET uint xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v2.xyzx, t0.xyzw, s0
+mul r0.xyzw, r0.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000)
+ftou o0.xyzw, r0.xyzw
+ret
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_PS_FtoU_PT_RGBA_3D[] = {
+ 68, 88, 66, 67, 60, 29, 156, 198, 163, 110, 141, 222, 219, 229, 175, 1, 103, 9, 217,
+ 156, 1, 0, 0, 0, 188, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 64, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 112, 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, 8,
+ 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, 95, 51, 68,
+ 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, 49, 48,
+ 46, 49, 0, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 1, 0, 0, 0,
+ 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 171,
+ 171, 83, 72, 68, 82, 168, 0, 0, 0, 64, 0, 0, 0, 42, 0, 0, 0, 90, 0,
+ 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 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, 18, 16, 0, 2, 0,
+ 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56,
+ 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0,
+ 2, 64, 0, 0, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127,
+ 67, 28, 0, 0, 5, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 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, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgb_2d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgb_2d_ps.h
new file mode 100644
index 0000000000..25149b232d
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgb_2d_ps.h
@@ -0,0 +1,87 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 2d t0 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 uint xyzw
+//
+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 r0.xyz, r1.xxxx, r1.yzwy, r0.xyzx
+mul r0.xyz, r0.xyzx, l(255.000000, 255.000000, 255.000000, 0.000000)
+ftou o0.xyz, r0.xyzx
+mov o0.w, l(1)
+ret
+// Approximately 8 instruction slots used
+#endif
+
+const BYTE g_PS_FtoU_UM_RGB_2D[] = {
+ 68, 88, 66, 67, 104, 222, 184, 218, 135, 243, 133, 232, 177, 236, 20, 60, 64, 9, 17,
+ 90, 1, 0, 0, 0, 252, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 44, 1, 0, 0, 96, 1, 0, 0, 128, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 49, 48, 46, 49, 0,
+ 171, 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, 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, 1, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86,
+ 95, 84, 65, 82, 71, 69, 84, 0, 171, 171, 83, 72, 68, 82, 24, 1, 0, 0, 64,
+ 0, 0, 0, 70, 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, 0, 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, 56, 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2,
+ 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 127, 67, 0, 0, 127, 67, 0,
+ 0, 127, 67, 0, 0, 0, 0, 28, 0, 0, 5, 114, 32, 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, 1, 64, 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0,
+ 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 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, 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, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgb_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgb_2darray_ps.h
new file mode 100644
index 0000000000..8b8d1d3b7f
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgb_2darray_ps.h
@@ -0,0 +1,97 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_2DArray texture float4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET uint xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2darray (float,float,float,float) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 2
+utof r0.z, v1.x
+mov r0.xy, v2.xyxx
+sample r0.xyzw, r0.xyzx, t0.xyzw, s0
+lt r1.x, l(0.000000), r0.w
+div r1.yzw, r0.xxyz, r0.wwww
+movc r0.xyz, r1.xxxx, r1.yzwy, r0.xyzx
+mul r0.xyz, r0.xyzx, l(255.000000, 255.000000, 255.000000, 0.000000)
+ftou o0.xyz, r0.xyzx
+mov o0.w, l(1)
+ret
+// Approximately 10 instruction slots used
+#endif
+
+const BYTE g_PS_FtoU_UM_RGB_2DArray[] = {
+ 68, 88, 66, 67, 211, 11, 247, 147, 13, 61, 188, 52, 49, 20, 122, 213, 216, 130, 203,
+ 211, 1, 0, 0, 0, 108, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0,
+ 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 240, 2, 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, 117, 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, 5,
+ 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, 95, 50, 68,
+ 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0,
+ 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0,
+ 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0,
+ 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95,
+ 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78,
+ 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 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, 1, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95,
+ 84, 65, 82, 71, 69, 84, 0, 171, 171, 83, 72, 68, 82, 80, 1, 0, 0, 64, 0,
+ 0, 0, 84, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88,
+ 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4,
+ 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16,
+ 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0,
+ 0, 2, 2, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10,
+ 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0,
+ 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0,
+ 0, 70, 2, 16, 0, 0, 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, 0, 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, 56, 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0,
+ 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127,
+ 67, 0, 0, 0, 0, 28, 0, 0, 5, 114, 32, 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, 1,
+ 64, 0, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0,
+ 10, 0, 0, 0, 2, 0, 0, 0, 0, 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, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 2, 0, 0, 0, 1, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgb_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgb_3d_ps.h
new file mode 100644
index 0000000000..f7746e87ee
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgb_3d_ps.h
@@ -0,0 +1,90 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_3D texture float4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET uint xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 2
+sample r0.xyzw, v2.xyzx, t0.xyzw, s0
+lt r1.x, l(0.000000), r0.w
+div r1.yzw, r0.xxyz, r0.wwww
+movc r0.xyz, r1.xxxx, r1.yzwy, r0.xyzx
+mul r0.xyz, r0.xyzx, l(255.000000, 255.000000, 255.000000, 0.000000)
+ftou o0.xyz, r0.xyzx
+mov o0.w, l(1)
+ret
+// Approximately 8 instruction slots used
+#endif
+
+const BYTE g_PS_FtoU_UM_RGB_3D[] = {
+ 68, 88, 66, 67, 211, 77, 171, 115, 172, 101, 224, 185, 62, 127, 82, 90, 150, 163, 227,
+ 209, 1, 0, 0, 0, 44, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 176, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 112, 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, 8,
+ 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, 95, 51, 68,
+ 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, 49, 48,
+ 46, 49, 0, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 1, 0, 0, 0,
+ 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 171,
+ 171, 83, 72, 68, 82, 24, 1, 0, 0, 64, 0, 0, 0, 70, 0, 0, 0, 90, 0,
+ 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 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, 18, 16, 0, 2, 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, 0, 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, 56, 0, 0, 10,
+ 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0,
+ 0, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 0, 0, 28, 0,
+ 0, 5, 114, 32, 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, 1, 64, 0, 0, 1, 0, 0, 0,
+ 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0,
+ 0, 0, 0, 0, 0, 2, 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, 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, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgba_2d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgba_2d_ps.h
new file mode 100644
index 0000000000..71530637ef
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgba_2d_ps.h
@@ -0,0 +1,85 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 2d t0 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 uint xyzw
+//
+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 r0.xyz, r1.xxxx, r1.yzwy, r0.xyzx
+mul r0.xyzw, r0.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000)
+ftou o0.xyzw, r0.xyzw
+ret
+// Approximately 7 instruction slots used
+#endif
+
+const BYTE g_PS_FtoU_UM_RGBA_2D[] = {
+ 68, 88, 66, 67, 79, 47, 172, 229, 63, 231, 120, 201, 52, 133, 90, 84, 23, 233, 153,
+ 100, 1, 0, 0, 0, 232, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 44, 1, 0, 0, 96, 1, 0, 0, 108, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 49, 48, 46, 49, 0,
+ 171, 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, 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, 1, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86,
+ 95, 84, 65, 82, 71, 69, 84, 0, 171, 171, 83, 72, 68, 82, 4, 1, 0, 0, 64,
+ 0, 0, 0, 65, 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, 0, 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, 56, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14,
+ 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 127, 67, 0, 0, 127, 67, 0,
+ 0, 127, 67, 0, 0, 127, 67, 28, 0, 0, 5, 242, 32, 16, 0, 0, 0, 0, 0,
+ 70, 14, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0,
+ 0, 7, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 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,
+ 1, 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, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgba_2darray_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgba_2darray_ps.h
new file mode 100644
index 0000000000..5d75b8df6d
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgba_2darray_ps.h
@@ -0,0 +1,95 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_2DArray texture float4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET uint xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2darray (float,float,float,float) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 2
+utof r0.z, v1.x
+mov r0.xy, v2.xyxx
+sample r0.xyzw, r0.xyzx, t0.xyzw, s0
+lt r1.x, l(0.000000), r0.w
+div r1.yzw, r0.xxyz, r0.wwww
+movc r0.xyz, r1.xxxx, r1.yzwy, r0.xyzx
+mul r0.xyzw, r0.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000)
+ftou o0.xyzw, r0.xyzw
+ret
+// Approximately 9 instruction slots used
+#endif
+
+const BYTE g_PS_FtoU_UM_RGBA_2DArray[] = {
+ 68, 88, 66, 67, 237, 98, 226, 3, 103, 212, 163, 240, 153, 59, 189, 19, 100, 209, 34,
+ 202, 1, 0, 0, 0, 88, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 220, 0,
+ 0, 0, 100, 1, 0, 0, 152, 1, 0, 0, 220, 2, 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, 117, 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, 5,
+ 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, 95, 50, 68,
+ 65, 114, 114, 97, 121, 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, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0,
+ 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0,
+ 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0,
+ 7, 3, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95,
+ 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78,
+ 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 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, 1, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95,
+ 84, 65, 82, 71, 69, 84, 0, 171, 171, 83, 72, 68, 82, 60, 1, 0, 0, 64, 0,
+ 0, 0, 79, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88,
+ 64, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4,
+ 18, 16, 16, 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16,
+ 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0,
+ 0, 2, 2, 0, 0, 0, 86, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10,
+ 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0,
+ 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0,
+ 0, 70, 2, 16, 0, 0, 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, 0, 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, 56, 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0,
+ 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127,
+ 67, 0, 0, 127, 67, 28, 0, 0, 5, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14,
+ 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 9,
+ 0, 0, 0, 2, 0, 0, 0, 0, 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, 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, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgba_3d_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgba_3d_ps.h
new file mode 100644
index 0000000000..7d98511943
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/multiplyalpha_ftou_um_rgba_3d_ps.h
@@ -0,0 +1,88 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF_3D texture float4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET uint xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 2
+sample r0.xyzw, v2.xyzx, t0.xyzw, s0
+lt r1.x, l(0.000000), r0.w
+div r1.yzw, r0.xxyz, r0.wwww
+movc r0.xyz, r1.xxxx, r1.yzwy, r0.xyzx
+mul r0.xyzw, r0.xyzw, l(255.000000, 255.000000, 255.000000, 255.000000)
+ftou o0.xyzw, r0.xyzw
+ret
+// Approximately 7 instruction slots used
+#endif
+
+const BYTE g_PS_FtoU_UM_RGBA_3D[] = {
+ 68, 88, 66, 67, 9, 246, 142, 132, 23, 145, 144, 223, 33, 247, 146, 14, 116, 28, 69,
+ 175, 1, 0, 0, 0, 24, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 156, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 112, 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, 8,
+ 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, 95, 51, 68,
+ 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, 49, 48,
+ 46, 49, 0, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 1, 0, 0, 0,
+ 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 171,
+ 171, 83, 72, 68, 82, 4, 1, 0, 0, 64, 0, 0, 0, 65, 0, 0, 0, 90, 0,
+ 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 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, 18, 16, 0, 2, 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, 0, 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, 56, 0, 0, 10,
+ 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2, 64, 0,
+ 0, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 0, 0, 127, 67, 28, 0,
+ 0, 5, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 62,
+ 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 7, 0, 0, 0, 2, 0, 0, 0,
+ 0, 0, 0, 0, 2, 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, 1, 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,
+ 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough2d11vs.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough2d11vs.h
new file mode 100644
index 0000000000..fdeae67ad9
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough2d11vs.h
@@ -0,0 +1,91 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// POSITION 0 xy 0 NONE float xy
+// TEXCOORD 0 xy 1 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float xyzw
+// TEXCOORD 0 xy 1 NONE float xy
+//
+//
+// Runtime generated constant mappings:
+//
+// Target Reg Constant Description
+// ---------- --------------------------------------------------
+// c0 Vertex Shader position offset
+//
+//
+// Level9 shader bytecode:
+//
+ vs_2_x
+ def c1, 0, 1, 0, 0
+ dcl_texcoord v0
+ dcl_texcoord1 v1
+ add oPos.xy, v0, c0
+ mov oPos.zw, c1.xyxy
+ mov oT0.xy, v1
+
+// approximately 3 instruction slots used
+vs_4_0
+dcl_input v0.xy
+dcl_input v1.xy
+dcl_output_siv o0.xyzw, position
+dcl_output o1.xy
+mov o0.xy, v0.xyxx
+mov o0.zw, l(0,0,0,1.000000)
+mov o1.xy, v1.xyxx
+ret
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_VS_Passthrough2D[] = {
+ 68, 88, 66, 67, 157, 119, 222, 216, 39, 186, 195, 24, 174, 138, 22, 73, 223, 185, 107,
+ 36, 1, 0, 0, 0, 204, 2, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 200, 0,
+ 0, 0, 88, 1, 0, 0, 212, 1, 0, 0, 32, 2, 0, 0, 116, 2, 0, 0, 65,
+ 111, 110, 57, 136, 0, 0, 0, 136, 0, 0, 0, 0, 2, 254, 255, 96, 0, 0, 0,
+ 40, 0, 0, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 36,
+ 0, 1, 0, 36, 0, 0, 0, 0, 0, 1, 2, 254, 255, 81, 0, 0, 5, 1, 0,
+ 15, 160, 0, 0, 0, 0, 0, 0, 128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 31,
+ 0, 0, 2, 5, 0, 0, 128, 0, 0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128,
+ 1, 0, 15, 144, 2, 0, 0, 3, 0, 0, 3, 192, 0, 0, 228, 144, 0, 0, 228,
+ 160, 1, 0, 0, 2, 0, 0, 12, 192, 1, 0, 68, 160, 1, 0, 0, 2, 0, 0,
+ 3, 224, 1, 0, 228, 144, 255, 255, 0, 0, 83, 72, 68, 82, 136, 0, 0, 0, 64,
+ 0, 1, 0, 34, 0, 0, 0, 95, 0, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0,
+ 95, 0, 0, 3, 50, 16, 16, 0, 1, 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, 54, 0, 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0,
+ 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, 50, 32, 16, 0, 1, 0, 0, 0, 70, 16, 16, 0, 1, 0, 0, 0, 62, 0,
+ 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 4, 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, 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, 82, 68, 69, 70, 68, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 76, 0, 0,
+ 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 65, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 3, 3, 0, 0,
+ 80, 79, 83, 73, 84, 73, 79, 78, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171,
+ 171, 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, 79, 83, 73, 84, 73, 79, 78,
+ 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11gs.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11gs.h
new file mode 100644
index 0000000000..23fc7f99ea
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11gs.h
@@ -0,0 +1,93 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float xyzw
+// LAYER 0 x 1 NONE uint x
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float xyzw
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+gs_4_0
+dcl_input_siv v[3][0].xyzw, position
+dcl_input v[3][1].x
+dcl_input v[3][2].xyz
+dcl_temps 1
+dcl_inputprimitive triangle
+dcl_outputtopology trianglestrip
+dcl_output_siv o0.xyzw, position
+dcl_output_siv o1.x, rendertarget_array_index
+dcl_output o2.xyz
+dcl_maxout 3
+mov r0.x, l(0)
+loop
+ ige r0.y, r0.x, l(3)
+ breakc_nz r0.y
+ mov o0.xyzw, v[r0.x + 0][0].xyzw
+ mov o1.x, v[r0.x + 0][1].x
+ mov o2.xyz, v[r0.x + 0][2].xyzx
+ emit
+ iadd r0.x, r0.x, l(1)
+endloop
+ret
+// Approximately 11 instruction slots used
+#endif
+
+const BYTE g_GS_Passthrough3D[] = {
+ 68, 88, 66, 67, 226, 188, 145, 36, 193, 19, 254, 1, 249, 51, 174, 53, 33, 65, 233,
+ 89, 1, 0, 0, 0, 60, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 128, 0,
+ 0, 0, 244, 0, 0, 0, 124, 1, 0, 0, 192, 2, 0, 0, 82, 68, 69, 70, 68,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 83, 71, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 108,
+ 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 92, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1,
+ 0, 0, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2,
+ 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0,
+ 76, 65, 89, 69, 82, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 79, 83, 71,
+ 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 92,
+ 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,
+ 1, 14, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0,
+ 0, 2, 0, 0, 0, 7, 8, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79,
+ 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69, 84, 65, 82,
+ 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171,
+ 83, 72, 68, 82, 60, 1, 0, 0, 64, 0, 2, 0, 79, 0, 0, 0, 97, 0, 0,
+ 5, 242, 16, 32, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 95, 0,
+ 0, 4, 18, 16, 32, 0, 3, 0, 0, 0, 1, 0, 0, 0, 95, 0, 0, 4, 114,
+ 16, 32, 0, 3, 0, 0, 0, 2, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0,
+ 93, 24, 0, 1, 92, 40, 0, 1, 103, 0, 0, 4, 242, 32, 16, 0, 0, 0, 0,
+ 0, 1, 0, 0, 0, 103, 0, 0, 4, 18, 32, 16, 0, 1, 0, 0, 0, 4, 0,
+ 0, 0, 101, 0, 0, 3, 114, 32, 16, 0, 2, 0, 0, 0, 94, 0, 0, 2, 3,
+ 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0,
+ 0, 0, 0, 0, 48, 0, 0, 1, 33, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0,
+ 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 3, 0, 0, 0, 3, 0,
+ 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 7, 242, 32, 16, 0, 0,
+ 0, 0, 0, 70, 30, 160, 0, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 54, 0, 0, 7, 18, 32, 16, 0, 1, 0, 0, 0, 10, 16, 160, 0, 10, 0, 16,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 7, 114, 32, 16, 0, 2, 0,
+ 0, 0, 70, 18, 160, 0, 10, 0, 16, 0, 0, 0, 0, 0, 2, 0, 0, 0, 19,
+ 0, 0, 1, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0,
+ 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 22, 0, 0, 1, 62, 0, 0,
+ 1, 83, 84, 65, 84, 116, 0, 0, 0, 11, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 2, 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, 1, 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, 3, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11vs.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11vs.h
new file mode 100644
index 0000000000..3c833f79a8
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11vs.h
@@ -0,0 +1,75 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// POSITION 0 xy 0 NONE float xy
+// LAYER 0 x 1 NONE uint x
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float xyzw
+// LAYER 0 x 1 NONE uint x
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+vs_4_0
+dcl_input v0.xy
+dcl_input v1.x
+dcl_input v2.xyz
+dcl_output_siv o0.xyzw, position
+dcl_output o1.x
+dcl_output o2.xyz
+mov o0.xy, v0.xyxx
+mov o0.zw, l(0,0,0,1.000000)
+mov o1.x, v1.x
+mov o2.xyz, v2.xyzx
+ret
+// Approximately 5 instruction slots used
+#endif
+
+const BYTE g_VS_Passthrough3D[] = {
+ 68, 88, 66, 67, 136, 150, 103, 162, 167, 195, 182, 112, 150, 17, 18, 65, 73, 164, 12,
+ 142, 1, 0, 0, 0, 156, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 128, 0,
+ 0, 0, 240, 0, 0, 0, 100, 1, 0, 0, 32, 2, 0, 0, 82, 68, 69, 70, 68,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0,
+ 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 104,
+ 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 89, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1,
+ 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2,
+ 0, 0, 0, 7, 7, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 76, 65, 89,
+ 69, 82, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 78, 108, 0, 0,
+ 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 92, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 14, 0, 0,
+ 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0,
+ 0, 7, 8, 0, 0, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 76, 65,
+ 89, 69, 82, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 83, 72, 68, 82, 180,
+ 0, 0, 0, 64, 0, 1, 0, 45, 0, 0, 0, 95, 0, 0, 3, 50, 16, 16, 0,
+ 0, 0, 0, 0, 95, 0, 0, 3, 18, 16, 16, 0, 1, 0, 0, 0, 95, 0, 0,
+ 3, 114, 16, 16, 0, 2, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 101, 0, 0, 3, 18, 32, 16, 0, 1, 0, 0, 0, 101,
+ 0, 0, 3, 114, 32, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 50, 32, 16, 0,
+ 0, 0, 0, 0, 70, 16, 16, 0, 0, 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, 32, 16, 0, 1, 0, 0, 0, 10,
+ 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 114, 32, 16, 0, 2, 0, 0, 0,
+ 70, 18, 16, 0, 2, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0,
+ 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 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, 0, 0, 0, 0, 0, 0, 0,
+ 0, 4, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrougha2d11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrougha2d11ps.h
new file mode 100644
index 0000000000..a338628659
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrougha2d11ps.h
@@ -0,0 +1,103 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 2d t0 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
+ def c0, 0, 1, 0, 0
+ dcl t0.xy
+ dcl_2d s0
+ texld r0, t0, s0
+ mul r0, r0.w, c0.xxxy
+ 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
+mov o0.w, r0.w
+mov o0.xyz, l(0,0,0,0)
+ret
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughA2D[] = {
+ 68, 88, 66, 67, 194, 169, 124, 165, 14, 7, 97, 151, 180, 238, 123, 252, 63, 248, 162,
+ 165, 1, 0, 0, 0, 28, 3, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 204, 0,
+ 0, 0, 116, 1, 0, 0, 240, 1, 0, 0, 144, 2, 0, 0, 232, 2, 0, 0, 65,
+ 111, 110, 57, 140, 0, 0, 0, 140, 0, 0, 0, 0, 2, 255, 255, 100, 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, 81, 0, 0, 5, 0, 0,
+ 15, 160, 0, 0, 0, 0, 0, 0, 128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 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, 15, 128, 0, 0, 255, 128, 0, 0, 64, 160, 1, 0,
+ 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 160,
+ 0, 0, 0, 64, 0, 0, 0, 40, 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, 54, 0, 0, 5, 130, 32, 16,
+ 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 8, 114, 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, 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, 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, 1,
+ 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, 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, 152, 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, 49, 48, 46, 49, 0, 171, 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, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughdepth2d11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughdepth2d11ps.h
new file mode 100644
index 0000000000..e8790cade6
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughdepth2d11ps.h
@@ -0,0 +1,73 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 2d t0 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_DEPTH 0 N/A oDepth DEPTH float YES
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2d (float,float,float,float) t0
+dcl_input_ps linear v1.xy
+dcl_output oDepth
+dcl_temps 1
+sample r0.xyzw, v1.xyxx, t0.xyzw, s0
+mov oDepth, r0.x
+ret
+// Approximately 3 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughDepth2D[] = {
+ 68, 88, 66, 67, 215, 216, 149, 20, 177, 67, 115, 222, 9, 179, 226, 21, 58, 197, 172,
+ 136, 1, 0, 0, 0, 92, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 44, 1, 0, 0, 96, 1, 0, 0, 224, 1, 0, 0, 82, 68, 69, 70, 152,
+ 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, 49, 48, 46, 49, 0,
+ 171, 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, 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, 255, 255, 255, 255, 1, 14, 0, 0, 83, 86,
+ 95, 68, 69, 80, 84, 72, 0, 171, 171, 171, 83, 72, 68, 82, 120, 0, 0, 0, 64,
+ 0, 0, 0, 30, 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, 2, 1, 192, 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, 54, 0, 0, 4, 1, 192, 0, 0, 10, 0, 16, 0, 0, 0, 0,
+ 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 3, 0, 0, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 2, 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, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum2d11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum2d11ps.h
new file mode 100644
index 0000000000..c8a472e9b6
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum2d11ps.h
@@ -0,0 +1,103 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 2d t0 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
+ def c0, 1, 0, 0, 0
+ dcl t0.xy
+ dcl_2d s0
+ texld r0, t0, s0
+ mad r0, r0.x, c0.xxxy, c0.yyyx
+ 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
+mov o0.xyz, r0.xxxx
+mov o0.w, l(1.000000)
+ret
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughLum2D[] = {
+ 68, 88, 66, 67, 241, 199, 66, 51, 118, 205, 236, 165, 244, 231, 234, 126, 203, 25, 231,
+ 134, 1, 0, 0, 0, 20, 3, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 208, 0,
+ 0, 0, 108, 1, 0, 0, 232, 1, 0, 0, 136, 2, 0, 0, 224, 2, 0, 0, 65,
+ 111, 110, 57, 144, 0, 0, 0, 144, 0, 0, 0, 0, 2, 255, 255, 104, 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, 81, 0, 0, 5, 0, 0,
+ 15, 160, 0, 0, 128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 4, 0, 0, 4, 0, 0, 15, 128, 0, 0, 0, 128, 0, 0, 64, 160, 0, 0,
+ 21, 160, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83,
+ 72, 68, 82, 148, 0, 0, 0, 64, 0, 0, 0, 37, 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, 54, 0, 0,
+ 5, 114, 32, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 54, 0,
+ 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 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, 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, 1, 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, 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, 152, 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, 49, 48, 46, 49, 0, 171,
+ 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, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum2darray11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum2darray11ps.h
new file mode 100644
index 0000000000..4741497d93
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum2darray11ps.h
@@ -0,0 +1,85 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2darray (float,float,float,float) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 1
+utof r0.z, v1.x
+mov r0.xy, v2.xyxx
+sample r0.xyzw, r0.xyzx, t0.xyzw, s0
+mov o0.xyz, r0.xxxx
+mov o0.w, l(1.000000)
+ret
+// Approximately 6 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughLum2DArray[] = {
+ 68, 88, 66, 67, 84, 131, 205, 28, 3, 168, 120, 6, 89, 75, 169, 140, 154, 126, 61,
+ 31, 1, 0, 0, 0, 224, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 100, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 5,
+ 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, 49, 48, 46, 49, 0,
+ 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 3, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 83, 72, 68, 82, 204, 0, 0, 0, 64, 0, 0, 0, 51, 0, 0, 0, 90, 0,
+ 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 64, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, 18, 16, 16, 0, 1, 0, 0, 0,
+ 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0,
+ 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 86, 0,
+ 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 1, 0, 0, 0, 54,
+ 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 2, 0, 0, 0,
+ 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0,
+ 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 54, 0,
+ 0, 5, 114, 32, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 54,
+ 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63,
+ 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0, 3, 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, 1, 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, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum3d11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum3d11ps.h
new file mode 100644
index 0000000000..5c9ffc039a
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlum3d11ps.h
@@ -0,0 +1,79 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v2.xyzx, t0.xyzw, s0
+mov o0.xyz, r0.xxxx
+mov o0.w, l(1.000000)
+ret
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughLum3D[] = {
+ 68, 88, 66, 67, 15, 80, 145, 76, 93, 127, 194, 208, 106, 29, 26, 87, 147, 62, 128,
+ 143, 1, 0, 0, 0, 168, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 44, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 8,
+ 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, 49, 48, 46, 49, 0,
+ 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 83, 72, 68, 82, 148, 0, 0, 0, 64, 0, 0, 0, 37, 0, 0, 0, 90, 0,
+ 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 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, 18, 16, 0, 2, 0,
+ 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 54,
+ 0, 0, 5, 114, 32, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0,
+ 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128,
+ 63, 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, 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, 1, 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, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha2d11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha2d11ps.h
new file mode 100644
index 0000000000..6229e57ea2
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha2d11ps.h
@@ -0,0 +1,98 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 2d t0 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
+ mov r0, r0.xxxw
+ 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
+mov o0.xyzw, r0.xxxw
+ret
+// Approximately 3 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughLumAlpha2D[] = {
+ 68, 88, 66, 67, 19, 109, 76, 235, 225, 193, 54, 241, 78, 207, 77, 62, 148, 127, 172,
+ 73, 1, 0, 0, 0, 224, 2, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 176, 0,
+ 0, 0, 56, 1, 0, 0, 180, 1, 0, 0, 84, 2, 0, 0, 172, 2, 0, 0, 65,
+ 111, 110, 57, 112, 0, 0, 0, 112, 0, 0, 0, 0, 2, 255, 255, 72, 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, 1, 0, 0, 2,
+ 0, 0, 15, 128, 0, 0, 192, 128, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228,
+ 128, 255, 255, 0, 0, 83, 72, 68, 82, 128, 0, 0, 0, 64, 0, 0, 0, 32, 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, 54, 0, 0, 5, 242, 32, 16, 0, 0, 0, 0, 0, 6, 12, 16, 0,
+ 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 3, 0, 0,
+ 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 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, 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, 152, 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, 49,
+ 48, 46, 49, 0, 171, 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, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha2darray11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha2darray11ps.h
new file mode 100644
index 0000000000..cdc91561bc
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha2darray11ps.h
@@ -0,0 +1,83 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2darray (float,float,float,float) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 1
+utof r0.z, v1.x
+mov r0.xy, v2.xyxx
+sample r0.xyzw, r0.xyzx, t0.xyzw, s0
+mov o0.xyzw, r0.xxxw
+ret
+// Approximately 5 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughLumAlpha2DArray[] = {
+ 68, 88, 66, 67, 117, 33, 119, 91, 15, 156, 83, 232, 200, 231, 183, 116, 40, 238, 79,
+ 163, 1, 0, 0, 0, 204, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 80, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 5,
+ 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, 49, 48, 46, 49, 0,
+ 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 3, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 83, 72, 68, 82, 184, 0, 0, 0, 64, 0, 0, 0, 46, 0, 0, 0, 90, 0,
+ 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 64, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, 18, 16, 16, 0, 1, 0, 0, 0,
+ 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0,
+ 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 86, 0,
+ 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 1, 0, 0, 0, 54,
+ 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 2, 0, 0, 0,
+ 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0,
+ 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 54, 0,
+ 0, 5, 242, 32, 16, 0, 0, 0, 0, 0, 6, 12, 16, 0, 0, 0, 0, 0, 62,
+ 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0, 3, 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, 1, 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,
+ 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha3d11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha3d11ps.h
new file mode 100644
index 0000000000..941b5b2b86
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughlumalpha3d11ps.h
@@ -0,0 +1,77 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v2.xyzx, t0.xyzw, s0
+mov o0.xyzw, r0.xxxw
+ret
+// Approximately 3 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughLumAlpha3D[] = {
+ 68, 88, 66, 67, 158, 22, 231, 90, 211, 81, 99, 1, 181, 209, 159, 145, 140, 162, 254,
+ 17, 1, 0, 0, 0, 148, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 24, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 8,
+ 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, 49, 48, 46, 49, 0,
+ 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 83, 72, 68, 82, 128, 0, 0, 0, 64, 0, 0, 0, 32, 0, 0, 0, 90, 0,
+ 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 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, 18, 16, 0, 2, 0,
+ 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 54,
+ 0, 0, 5, 242, 32, 16, 0, 0, 0, 0, 0, 6, 12, 16, 0, 0, 0, 0, 0,
+ 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0, 2, 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, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2d11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2d11ps.h
new file mode 100644
index 0000000000..1b41ed1602
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2d11ps.h
@@ -0,0 +1,104 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 2d t0 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
+ def c0, 1, 0, 0, 0
+ dcl t0.xy
+ dcl_2d s0
+ texld r0, t0, s0
+ mad r0, r0.x, c0.xyyy, c0.yyyx
+ 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
+mov o0.x, r0.x
+mov o0.yzw, l(0,0,0,1.000000)
+ret
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughR2D[] = {
+ 68, 88, 66, 67, 14, 165, 206, 90, 117, 2, 221, 45, 225, 30, 128, 173, 62, 238, 39,
+ 64, 1, 0, 0, 0, 32, 3, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 208, 0,
+ 0, 0, 120, 1, 0, 0, 244, 1, 0, 0, 148, 2, 0, 0, 236, 2, 0, 0, 65,
+ 111, 110, 57, 144, 0, 0, 0, 144, 0, 0, 0, 0, 2, 255, 255, 104, 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, 81, 0, 0, 5, 0, 0,
+ 15, 160, 0, 0, 128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 4, 0, 0, 4, 0, 0, 15, 128, 0, 0, 0, 128, 0, 0, 84, 160, 0, 0,
+ 21, 160, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83,
+ 72, 68, 82, 160, 0, 0, 0, 64, 0, 0, 0, 40, 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, 54, 0, 0,
+ 5, 18, 32, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0,
+ 0, 8, 226, 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, 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, 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, 1, 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, 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, 152, 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, 49, 48, 46, 49, 0, 171, 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, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2darray11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2darray11ps.h
new file mode 100644
index 0000000000..a5e3d5e52e
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2darray11ps.h
@@ -0,0 +1,86 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2darray (float,float,float,float) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 1
+utof r0.z, v1.x
+mov r0.xy, v2.xyxx
+sample r0.xyzw, r0.xyzx, t0.xyzw, s0
+mov o0.x, r0.x
+mov o0.yzw, l(0,0,0,1.000000)
+ret
+// Approximately 6 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughR2DArray[] = {
+ 68, 88, 66, 67, 67, 125, 115, 154, 244, 73, 25, 207, 88, 140, 76, 46, 206, 166, 161,
+ 193, 1, 0, 0, 0, 236, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 112, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 5,
+ 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, 49, 48, 46, 49, 0,
+ 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 3, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 83, 72, 68, 82, 216, 0, 0, 0, 64, 0, 0, 0, 54, 0, 0, 0, 90, 0,
+ 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 64, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, 18, 16, 16, 0, 1, 0, 0, 0,
+ 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0,
+ 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 86, 0,
+ 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 1, 0, 0, 0, 54,
+ 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 2, 0, 0, 0,
+ 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0,
+ 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 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, 54,
+ 0, 0, 8, 226, 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, 62, 0, 0, 1, 83, 84, 65,
+ 84, 116, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 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, 1, 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, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2darrayi11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2darrayi11ps.h
new file mode 100644
index 0000000000..eb41a93e37
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2darrayi11ps.h
@@ -0,0 +1,90 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// TextureI texture sint4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET int xyzw
+//
+ps_4_0
+dcl_resource_texture2darray (sint,sint,sint,sint) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 1
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xy, r0.xyxx
+mul r0.xy, r0.xyxx, v2.xyxx
+ftoi r0.xy, r0.xyxx
+mov r0.z, v1.x
+mov r0.w, l(0)
+ld r0.xyzw, r0.xyzw, t0.xyzw
+mov o0.x, r0.x
+mov o0.yzw, l(0,0,0,1)
+ret
+// Approximately 10 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughR2DArrayI[] = {
+ 68, 88, 66, 67, 200, 92, 148, 185, 17, 79, 183, 61, 19, 121, 215, 3, 144, 133, 210,
+ 72, 1, 0, 0, 0, 16, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0,
+ 0, 0, 52, 1, 0, 0, 104, 1, 0, 0, 148, 2, 0, 0, 82, 68, 69, 70, 112,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 69, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0,
+ 0, 3, 0, 0, 0, 5, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0,
+ 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 73, 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, 49, 48, 46, 49, 0, 171, 171,
+ 171, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15,
+ 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0,
+ 1, 0, 0, 0, 1, 1, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 3, 0, 0, 83, 86, 95, 80, 79, 83,
+ 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, 82, 71,
+ 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, 79, 79,
+ 82, 68, 0, 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, 2, 0, 0, 0, 0, 0,
+ 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 171, 171, 83,
+ 72, 68, 82, 36, 1, 0, 0, 64, 0, 0, 0, 73, 0, 0, 0, 88, 64, 0, 4,
+ 0, 112, 16, 0, 0, 0, 0, 0, 51, 51, 0, 0, 100, 8, 0, 4, 18, 16, 16,
+ 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 2, 0,
+ 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1,
+ 0, 0, 0, 61, 16, 0, 7, 242, 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, 2,
+ 0, 0, 0, 27, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0,
+ 0, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16,
+ 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64,
+ 0, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 70,
+ 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 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, 54, 0, 0,
+ 8, 226, 32, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1, 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, 3, 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, 4, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2darrayui11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2darrayui11ps.h
new file mode 100644
index 0000000000..12825c89e6
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2darrayui11ps.h
@@ -0,0 +1,90 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// TextureUI texture uint4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET uint xyzw
+//
+ps_4_0
+dcl_resource_texture2darray (uint,uint,uint,uint) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 1
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xy, r0.xyxx
+mul r0.xy, r0.xyxx, v2.xyxx
+ftoi r0.xy, r0.xyxx
+mov r0.z, v1.x
+mov r0.w, l(0)
+ld r0.xyzw, r0.xyzw, t0.xyzw
+mov o0.x, r0.x
+mov o0.yzw, l(0,0,0,1)
+ret
+// Approximately 10 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughR2DArrayUI[] = {
+ 68, 88, 66, 67, 201, 224, 137, 9, 164, 198, 146, 11, 60, 99, 27, 27, 235, 209, 108,
+ 242, 1, 0, 0, 0, 16, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0,
+ 0, 0, 52, 1, 0, 0, 104, 1, 0, 0, 148, 2, 0, 0, 82, 68, 69, 70, 112,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 70, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0,
+ 0, 4, 0, 0, 0, 5, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0,
+ 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 85, 73, 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, 49, 48, 46, 49, 0, 171,
+ 171, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15,
+ 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0,
+ 1, 0, 0, 0, 1, 1, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 3, 0, 0, 83, 86, 95, 80, 79, 83,
+ 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, 82, 71,
+ 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, 79, 79,
+ 82, 68, 0, 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, 1, 0, 0, 0, 0, 0,
+ 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 171, 171, 83,
+ 72, 68, 82, 36, 1, 0, 0, 64, 0, 0, 0, 73, 0, 0, 0, 88, 64, 0, 4,
+ 0, 112, 16, 0, 0, 0, 0, 0, 68, 68, 0, 0, 100, 8, 0, 4, 18, 16, 16,
+ 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 2, 0,
+ 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1,
+ 0, 0, 0, 61, 16, 0, 7, 242, 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, 2,
+ 0, 0, 0, 27, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0,
+ 0, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16,
+ 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64,
+ 0, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 70,
+ 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 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, 54, 0, 0,
+ 8, 226, 32, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1, 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, 3, 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, 4, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2di11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2di11ps.h
new file mode 100644
index 0000000000..ea6bbcd460
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2di11ps.h
@@ -0,0 +1,83 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// TextureI texture sint4 2d t0 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 int xyzw
+//
+ps_4_0
+dcl_resource_texture2d (sint,sint,sint,sint) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 1
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xy, r0.xyxx
+mul r0.xy, r0.xyxx, v1.xyxx
+ftoi r0.xy, r0.xyxx
+mov r0.zw, l(0,0,0,0)
+ld r0.xyzw, r0.xyzw, t0.xyzw
+mov o0.x, r0.x
+mov o0.yzw, l(0,0,0,0)
+ret
+// Approximately 9 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughR2DI[] = {
+ 68, 88, 66, 67, 8, 16, 169, 157, 145, 179, 119, 85, 36, 37, 85, 107, 44, 112, 158,
+ 100, 1, 0, 0, 0, 200, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0,
+ 0, 0, 4, 1, 0, 0, 56, 1, 0, 0, 76, 2, 0, 0, 82, 68, 69, 70, 112,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 69, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0,
+ 0, 3, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0,
+ 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 73, 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, 49, 48, 46, 49, 0, 171, 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, 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, 2, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84,
+ 65, 82, 71, 69, 84, 0, 171, 171, 83, 72, 68, 82, 12, 1, 0, 0, 64, 0, 0,
+ 0, 67, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 51, 51,
+ 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, 61, 16, 0, 7,
+ 242, 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, 27, 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, 45, 0, 0, 7, 242, 0, 16, 0, 0,
+ 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 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, 54, 0, 0, 8, 226, 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, 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, 3, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2dui11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2dui11ps.h
new file mode 100644
index 0000000000..bc034faaf6
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr2dui11ps.h
@@ -0,0 +1,83 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// TextureUI texture uint4 2d t0 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 uint xyzw
+//
+ps_4_0
+dcl_resource_texture2d (uint,uint,uint,uint) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 1
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xy, r0.xyxx
+mul r0.xy, r0.xyxx, v1.xyxx
+ftoi r0.xy, r0.xyxx
+mov r0.zw, l(0,0,0,0)
+ld r0.xyzw, r0.xyzw, t0.xyzw
+mov o0.x, r0.x
+mov o0.yzw, l(0,0,0,0)
+ret
+// Approximately 9 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughR2DUI[] = {
+ 68, 88, 66, 67, 6, 47, 175, 167, 62, 144, 171, 206, 77, 165, 245, 226, 135, 124, 142,
+ 188, 1, 0, 0, 0, 200, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0,
+ 0, 0, 4, 1, 0, 0, 56, 1, 0, 0, 76, 2, 0, 0, 82, 68, 69, 70, 112,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 70, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0,
+ 0, 4, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0,
+ 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 85, 73, 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, 49, 48, 46, 49, 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, 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, 1, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84,
+ 65, 82, 71, 69, 84, 0, 171, 171, 83, 72, 68, 82, 12, 1, 0, 0, 64, 0, 0,
+ 0, 67, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 68, 68,
+ 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, 61, 16, 0, 7,
+ 242, 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, 27, 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, 45, 0, 0, 7, 242, 0, 16, 0, 0,
+ 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 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, 54, 0, 0, 8, 226, 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, 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, 3, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3d11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3d11ps.h
new file mode 100644
index 0000000000..010e3eae14
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3d11ps.h
@@ -0,0 +1,80 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v2.xyzx, t0.xyzw, s0
+mov o0.x, r0.x
+mov o0.yzw, l(0,0,0,1.000000)
+ret
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughR3D[] = {
+ 68, 88, 66, 67, 134, 101, 76, 73, 205, 199, 65, 249, 170, 201, 40, 128, 129, 87, 93,
+ 148, 1, 0, 0, 0, 180, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 56, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 8,
+ 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, 49, 48, 46, 49, 0,
+ 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 83, 72, 68, 82, 160, 0, 0, 0, 64, 0, 0, 0, 40, 0, 0, 0, 90, 0,
+ 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 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, 18, 16, 0, 2, 0,
+ 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 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,
+ 54, 0, 0, 8, 226, 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, 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, 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, 1, 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, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3di11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3di11ps.h
new file mode 100644
index 0000000000..447690e35e
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3di11ps.h
@@ -0,0 +1,86 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// TextureI texture sint4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET int xyzw
+//
+ps_4_0
+dcl_resource_texture3d (sint,sint,sint,sint) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xyz, r0.xyzx
+mul r0.xyz, r0.xyzx, v2.xyzx
+ftoi r0.xyz, r0.xyzx
+mov r0.w, l(0)
+ld r0.xyzw, r0.xyzw, t0.xyzw
+mov o0.x, r0.x
+mov o0.yzw, l(0,0,0,0)
+ret
+// Approximately 9 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughR3DI[] = {
+ 68, 88, 66, 67, 250, 224, 56, 242, 8, 157, 92, 236, 205, 252, 68, 242, 80, 46, 223,
+ 98, 1, 0, 0, 0, 236, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0,
+ 0, 0, 52, 1, 0, 0, 104, 1, 0, 0, 112, 2, 0, 0, 82, 68, 69, 70, 112,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 69, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0,
+ 0, 3, 0, 0, 0, 8, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0,
+ 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 73, 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, 49, 48, 46, 49, 0, 171, 171,
+ 171, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15,
+ 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0,
+ 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, 79, 83,
+ 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, 82, 71,
+ 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, 79, 79,
+ 82, 68, 0, 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, 2, 0, 0, 0, 0, 0,
+ 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 171, 171, 83,
+ 72, 68, 82, 0, 1, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 88, 40, 0, 4,
+ 0, 112, 16, 0, 0, 0, 0, 0, 51, 51, 0, 0, 98, 16, 0, 3, 114, 16, 16,
+ 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0,
+ 0, 2, 1, 0, 0, 0, 61, 16, 0, 7, 242, 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,
+ 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0,
+ 7, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 18,
+ 16, 0, 2, 0, 0, 0, 27, 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70,
+ 2, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0,
+ 1, 64, 0, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0,
+ 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 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, 54,
+ 0, 0, 8, 226, 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, 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, 3, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3dui11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3dui11ps.h
new file mode 100644
index 0000000000..040b333116
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughr3dui11ps.h
@@ -0,0 +1,86 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// TextureUI texture uint4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET uint xyzw
+//
+ps_4_0
+dcl_resource_texture3d (uint,uint,uint,uint) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xyz, r0.xyzx
+mul r0.xyz, r0.xyzx, v2.xyzx
+ftoi r0.xyz, r0.xyzx
+mov r0.w, l(0)
+ld r0.xyzw, r0.xyzw, t0.xyzw
+mov o0.x, r0.x
+mov o0.yzw, l(0,0,0,0)
+ret
+// Approximately 9 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughR3DUI[] = {
+ 68, 88, 66, 67, 125, 15, 246, 192, 16, 228, 182, 55, 2, 24, 75, 71, 132, 253, 233,
+ 61, 1, 0, 0, 0, 236, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0,
+ 0, 0, 52, 1, 0, 0, 104, 1, 0, 0, 112, 2, 0, 0, 82, 68, 69, 70, 112,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 70, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0,
+ 0, 4, 0, 0, 0, 8, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0,
+ 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 85, 73, 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, 49, 48, 46, 49, 0, 171,
+ 171, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15,
+ 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0,
+ 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, 79, 83,
+ 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, 82, 71,
+ 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, 79, 79,
+ 82, 68, 0, 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, 1, 0, 0, 0, 0, 0,
+ 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 171, 171, 83,
+ 72, 68, 82, 0, 1, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 88, 40, 0, 4,
+ 0, 112, 16, 0, 0, 0, 0, 0, 68, 68, 0, 0, 98, 16, 0, 3, 114, 16, 16,
+ 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0,
+ 0, 2, 1, 0, 0, 0, 61, 16, 0, 7, 242, 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,
+ 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0,
+ 7, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 18,
+ 16, 0, 2, 0, 0, 0, 27, 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70,
+ 2, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0,
+ 1, 64, 0, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0,
+ 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 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, 54,
+ 0, 0, 8, 226, 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, 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, 3, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2d11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2d11ps.h
new file mode 100644
index 0000000000..a9373f69ab
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2d11ps.h
@@ -0,0 +1,104 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 2d t0 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
+ def c0, 1, 0, 0, 0
+ dcl t0.xy
+ dcl_2d s0
+ texld r0, t0, s0
+ mad r0, r0.xyxx, c0.xxyy, c0.yyyx
+ 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
+mov o0.xy, r0.xyxx
+mov o0.zw, l(0,0,0,1.000000)
+ret
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRG2D[] = {
+ 68, 88, 66, 67, 151, 54, 111, 200, 187, 200, 177, 214, 12, 69, 246, 113, 254, 31, 23,
+ 45, 1, 0, 0, 0, 32, 3, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 208, 0,
+ 0, 0, 120, 1, 0, 0, 244, 1, 0, 0, 148, 2, 0, 0, 236, 2, 0, 0, 65,
+ 111, 110, 57, 144, 0, 0, 0, 144, 0, 0, 0, 0, 2, 255, 255, 104, 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, 81, 0, 0, 5, 0, 0,
+ 15, 160, 0, 0, 128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 4, 0, 0, 4, 0, 0, 15, 128, 0, 0, 4, 128, 0, 0, 80, 160, 0, 0,
+ 21, 160, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83,
+ 72, 68, 82, 160, 0, 0, 0, 64, 0, 0, 0, 40, 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, 54, 0, 0,
+ 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 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, 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, 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, 1, 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, 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, 152, 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, 49, 48, 46, 49, 0, 171, 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, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2darray11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2darray11ps.h
new file mode 100644
index 0000000000..e97f66a770
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2darray11ps.h
@@ -0,0 +1,86 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2darray (float,float,float,float) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 1
+utof r0.z, v1.x
+mov r0.xy, v2.xyxx
+sample r0.xyzw, r0.xyzx, t0.xyzw, s0
+mov o0.xy, r0.xyxx
+mov o0.zw, l(0,0,0,1.000000)
+ret
+// Approximately 6 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRG2DArray[] = {
+ 68, 88, 66, 67, 20, 85, 120, 206, 181, 139, 167, 245, 44, 89, 37, 135, 242, 39, 108,
+ 150, 1, 0, 0, 0, 236, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 112, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 5,
+ 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, 49, 48, 46, 49, 0,
+ 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 3, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 83, 72, 68, 82, 216, 0, 0, 0, 64, 0, 0, 0, 54, 0, 0, 0, 90, 0,
+ 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 64, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, 18, 16, 16, 0, 1, 0, 0, 0,
+ 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0,
+ 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 86, 0,
+ 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 1, 0, 0, 0, 54,
+ 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 2, 0, 0, 0,
+ 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0,
+ 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 54, 0,
+ 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 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, 62, 0, 0, 1, 83, 84, 65,
+ 84, 116, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 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, 1, 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, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2darrayi11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2darrayi11ps.h
new file mode 100644
index 0000000000..f7ac20960d
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2darrayi11ps.h
@@ -0,0 +1,90 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// TextureI texture sint4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET int xyzw
+//
+ps_4_0
+dcl_resource_texture2darray (sint,sint,sint,sint) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 1
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xy, r0.xyxx
+mul r0.xy, r0.xyxx, v2.xyxx
+ftoi r0.xy, r0.xyxx
+mov r0.z, v1.x
+mov r0.w, l(0)
+ld r0.xyzw, r0.xyzw, t0.xyzw
+mov o0.xy, r0.xyxx
+mov o0.zw, l(0,0,0,1)
+ret
+// Approximately 10 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRG2DArrayI[] = {
+ 68, 88, 66, 67, 221, 150, 25, 83, 110, 171, 138, 218, 81, 94, 8, 224, 63, 191, 253,
+ 25, 1, 0, 0, 0, 16, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0,
+ 0, 0, 52, 1, 0, 0, 104, 1, 0, 0, 148, 2, 0, 0, 82, 68, 69, 70, 112,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 69, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0,
+ 0, 3, 0, 0, 0, 5, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0,
+ 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 73, 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, 49, 48, 46, 49, 0, 171, 171,
+ 171, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15,
+ 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0,
+ 1, 0, 0, 0, 1, 1, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 3, 0, 0, 83, 86, 95, 80, 79, 83,
+ 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, 82, 71,
+ 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, 79, 79,
+ 82, 68, 0, 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, 2, 0, 0, 0, 0, 0,
+ 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 171, 171, 83,
+ 72, 68, 82, 36, 1, 0, 0, 64, 0, 0, 0, 73, 0, 0, 0, 88, 64, 0, 4,
+ 0, 112, 16, 0, 0, 0, 0, 0, 51, 51, 0, 0, 100, 8, 0, 4, 18, 16, 16,
+ 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 2, 0,
+ 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1,
+ 0, 0, 0, 61, 16, 0, 7, 242, 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, 2,
+ 0, 0, 0, 27, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0,
+ 0, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16,
+ 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64,
+ 0, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 70,
+ 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5,
+ 50, 32, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 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, 1, 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, 3, 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, 4, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2darrayui11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2darrayui11ps.h
new file mode 100644
index 0000000000..2caa7b3b80
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2darrayui11ps.h
@@ -0,0 +1,90 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// TextureUI texture uint4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET uint xyzw
+//
+ps_4_0
+dcl_resource_texture2darray (uint,uint,uint,uint) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 1
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xy, r0.xyxx
+mul r0.xy, r0.xyxx, v2.xyxx
+ftoi r0.xy, r0.xyxx
+mov r0.z, v1.x
+mov r0.w, l(0)
+ld r0.xyzw, r0.xyzw, t0.xyzw
+mov o0.xy, r0.xyxx
+mov o0.zw, l(0,0,0,1)
+ret
+// Approximately 10 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRG2DArrayUI[] = {
+ 68, 88, 66, 67, 120, 173, 124, 47, 122, 95, 175, 210, 44, 74, 36, 182, 242, 25, 225,
+ 20, 1, 0, 0, 0, 16, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0,
+ 0, 0, 52, 1, 0, 0, 104, 1, 0, 0, 148, 2, 0, 0, 82, 68, 69, 70, 112,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 70, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0,
+ 0, 4, 0, 0, 0, 5, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0,
+ 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 85, 73, 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, 49, 48, 46, 49, 0, 171,
+ 171, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15,
+ 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0,
+ 1, 0, 0, 0, 1, 1, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 3, 0, 0, 83, 86, 95, 80, 79, 83,
+ 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, 82, 71,
+ 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, 79, 79,
+ 82, 68, 0, 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, 1, 0, 0, 0, 0, 0,
+ 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 171, 171, 83,
+ 72, 68, 82, 36, 1, 0, 0, 64, 0, 0, 0, 73, 0, 0, 0, 88, 64, 0, 4,
+ 0, 112, 16, 0, 0, 0, 0, 0, 68, 68, 0, 0, 100, 8, 0, 4, 18, 16, 16,
+ 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 2, 0,
+ 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1,
+ 0, 0, 0, 61, 16, 0, 7, 242, 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, 2,
+ 0, 0, 0, 27, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0,
+ 0, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16,
+ 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64,
+ 0, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 70,
+ 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5,
+ 50, 32, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 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, 1, 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, 3, 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, 4, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2di11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2di11ps.h
new file mode 100644
index 0000000000..25f0638e82
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2di11ps.h
@@ -0,0 +1,83 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// TextureI texture sint4 2d t0 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 int xyzw
+//
+ps_4_0
+dcl_resource_texture2d (sint,sint,sint,sint) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 1
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xy, r0.xyxx
+mul r0.xy, r0.xyxx, v1.xyxx
+ftoi r0.xy, r0.xyxx
+mov r0.zw, l(0,0,0,0)
+ld r0.xyzw, r0.xyzw, t0.xyzw
+mov o0.xy, r0.xyxx
+mov o0.zw, l(0,0,0,0)
+ret
+// Approximately 9 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRG2DI[] = {
+ 68, 88, 66, 67, 161, 76, 0, 115, 100, 69, 2, 128, 179, 140, 112, 55, 172, 151, 175,
+ 231, 1, 0, 0, 0, 200, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0,
+ 0, 0, 4, 1, 0, 0, 56, 1, 0, 0, 76, 2, 0, 0, 82, 68, 69, 70, 112,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 69, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0,
+ 0, 3, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0,
+ 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 73, 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, 49, 48, 46, 49, 0, 171, 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, 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, 2, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84,
+ 65, 82, 71, 69, 84, 0, 171, 171, 83, 72, 68, 82, 12, 1, 0, 0, 64, 0, 0,
+ 0, 67, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 51, 51,
+ 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, 61, 16, 0, 7,
+ 242, 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, 27, 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, 45, 0, 0, 7, 242, 0, 16, 0, 0,
+ 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0,
+ 54, 0, 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 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, 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, 3, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2dui11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2dui11ps.h
new file mode 100644
index 0000000000..cf9f8c793b
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg2dui11ps.h
@@ -0,0 +1,83 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// TextureUI texture uint4 2d t0 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 uint xyzw
+//
+ps_4_0
+dcl_resource_texture2d (uint,uint,uint,uint) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 1
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xy, r0.xyxx
+mul r0.xy, r0.xyxx, v1.xyxx
+ftoi r0.xy, r0.xyxx
+mov r0.zw, l(0,0,0,0)
+ld r0.xyzw, r0.xyzw, t0.xyzw
+mov o0.xy, r0.xyxx
+mov o0.zw, l(0,0,0,0)
+ret
+// Approximately 9 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRG2DUI[] = {
+ 68, 88, 66, 67, 161, 19, 0, 215, 231, 88, 50, 183, 124, 43, 107, 122, 144, 150, 193,
+ 168, 1, 0, 0, 0, 200, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0,
+ 0, 0, 4, 1, 0, 0, 56, 1, 0, 0, 76, 2, 0, 0, 82, 68, 69, 70, 112,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 70, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0,
+ 0, 4, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0,
+ 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 85, 73, 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, 49, 48, 46, 49, 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, 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, 1, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84,
+ 65, 82, 71, 69, 84, 0, 171, 171, 83, 72, 68, 82, 12, 1, 0, 0, 64, 0, 0,
+ 0, 67, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 68, 68,
+ 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, 61, 16, 0, 7,
+ 242, 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, 27, 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, 45, 0, 0, 7, 242, 0, 16, 0, 0,
+ 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0,
+ 54, 0, 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 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, 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, 3, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3d11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3d11ps.h
new file mode 100644
index 0000000000..f9d91f7bd7
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3d11ps.h
@@ -0,0 +1,80 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v2.xyzx, t0.xyzw, s0
+mov o0.xy, r0.xyxx
+mov o0.zw, l(0,0,0,1.000000)
+ret
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRG3D[] = {
+ 68, 88, 66, 67, 234, 174, 205, 77, 197, 154, 113, 172, 235, 131, 32, 212, 121, 65, 136,
+ 164, 1, 0, 0, 0, 180, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 56, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 8,
+ 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, 49, 48, 46, 49, 0,
+ 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 83, 72, 68, 82, 160, 0, 0, 0, 64, 0, 0, 0, 40, 0, 0, 0, 90, 0,
+ 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 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, 18, 16, 0, 2, 0,
+ 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 54,
+ 0, 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 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, 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, 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, 1, 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, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3di11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3di11ps.h
new file mode 100644
index 0000000000..53b5685cd6
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3di11ps.h
@@ -0,0 +1,86 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// TextureI texture sint4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET int xyzw
+//
+ps_4_0
+dcl_resource_texture3d (sint,sint,sint,sint) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xyz, r0.xyzx
+mul r0.xyz, r0.xyzx, v2.xyzx
+ftoi r0.xyz, r0.xyzx
+mov r0.w, l(0)
+ld r0.xyzw, r0.xyzw, t0.xyzw
+mov o0.xy, r0.xyxx
+mov o0.zw, l(0,0,0,0)
+ret
+// Approximately 9 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRG3DI[] = {
+ 68, 88, 66, 67, 215, 62, 152, 236, 50, 188, 41, 213, 133, 37, 41, 228, 13, 20, 9,
+ 166, 1, 0, 0, 0, 236, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0,
+ 0, 0, 52, 1, 0, 0, 104, 1, 0, 0, 112, 2, 0, 0, 82, 68, 69, 70, 112,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 69, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0,
+ 0, 3, 0, 0, 0, 8, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0,
+ 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 73, 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, 49, 48, 46, 49, 0, 171, 171,
+ 171, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15,
+ 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0,
+ 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, 79, 83,
+ 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, 82, 71,
+ 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, 79, 79,
+ 82, 68, 0, 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, 2, 0, 0, 0, 0, 0,
+ 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 171, 171, 83,
+ 72, 68, 82, 0, 1, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 88, 40, 0, 4,
+ 0, 112, 16, 0, 0, 0, 0, 0, 51, 51, 0, 0, 98, 16, 0, 3, 114, 16, 16,
+ 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0,
+ 0, 2, 1, 0, 0, 0, 61, 16, 0, 7, 242, 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,
+ 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0,
+ 7, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 18,
+ 16, 0, 2, 0, 0, 0, 27, 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70,
+ 2, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0,
+ 1, 64, 0, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0,
+ 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 54, 0,
+ 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 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, 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, 3, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3dui11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3dui11ps.h
new file mode 100644
index 0000000000..de7c00b8cb
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrg3dui11ps.h
@@ -0,0 +1,86 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// TextureUI texture uint4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET uint xyzw
+//
+ps_4_0
+dcl_resource_texture3d (uint,uint,uint,uint) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xyz, r0.xyzx
+mul r0.xyz, r0.xyzx, v2.xyzx
+ftoi r0.xyz, r0.xyzx
+mov r0.w, l(0)
+ld r0.xyzw, r0.xyzw, t0.xyzw
+mov o0.xy, r0.xyxx
+mov o0.zw, l(0,0,0,0)
+ret
+// Approximately 9 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRG3DUI[] = {
+ 68, 88, 66, 67, 136, 113, 120, 69, 210, 200, 206, 216, 193, 132, 168, 220, 72, 141, 170,
+ 116, 1, 0, 0, 0, 236, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0,
+ 0, 0, 52, 1, 0, 0, 104, 1, 0, 0, 112, 2, 0, 0, 82, 68, 69, 70, 112,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 70, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0,
+ 0, 4, 0, 0, 0, 8, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0,
+ 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 85, 73, 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, 49, 48, 46, 49, 0, 171,
+ 171, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15,
+ 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0,
+ 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, 79, 83,
+ 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, 82, 71,
+ 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, 79, 79,
+ 82, 68, 0, 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, 1, 0, 0, 0, 0, 0,
+ 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 171, 171, 83,
+ 72, 68, 82, 0, 1, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 88, 40, 0, 4,
+ 0, 112, 16, 0, 0, 0, 0, 0, 68, 68, 0, 0, 98, 16, 0, 3, 114, 16, 16,
+ 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0,
+ 0, 2, 1, 0, 0, 0, 61, 16, 0, 7, 242, 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,
+ 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0,
+ 7, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 18,
+ 16, 0, 2, 0, 0, 0, 27, 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70,
+ 2, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0,
+ 1, 64, 0, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0,
+ 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 54, 0,
+ 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 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, 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, 3, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2d11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2d11ps.h
new file mode 100644
index 0000000000..7187de985f
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2d11ps.h
@@ -0,0 +1,103 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 2d t0 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
+ def c0, 1, 0, 0, 0
+ dcl t0.xy
+ dcl_2d s0
+ texld r0, t0, s0
+ mad r0, r0.xyzx, c0.xxxy, c0.yyyx
+ 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
+mov o0.xyz, r0.xyzx
+mov o0.w, l(1.000000)
+ret
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGB2D[] = {
+ 68, 88, 66, 67, 250, 48, 137, 17, 146, 199, 249, 10, 198, 141, 227, 123, 246, 248, 120,
+ 90, 1, 0, 0, 0, 20, 3, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 208, 0,
+ 0, 0, 108, 1, 0, 0, 232, 1, 0, 0, 136, 2, 0, 0, 224, 2, 0, 0, 65,
+ 111, 110, 57, 144, 0, 0, 0, 144, 0, 0, 0, 0, 2, 255, 255, 104, 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, 81, 0, 0, 5, 0, 0,
+ 15, 160, 0, 0, 128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 4, 0, 0, 4, 0, 0, 15, 128, 0, 0, 36, 128, 0, 0, 64, 160, 0, 0,
+ 21, 160, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83,
+ 72, 68, 82, 148, 0, 0, 0, 64, 0, 0, 0, 37, 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, 54, 0, 0,
+ 5, 114, 32, 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, 1, 64, 0, 0, 0, 0, 128, 63, 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, 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, 1, 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, 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, 152, 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, 49, 48, 46, 49, 0, 171,
+ 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, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2d_565_11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2d_565_11ps.h
new file mode 100644
index 0000000000..7807225fa7
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2d_565_11ps.h
@@ -0,0 +1,118 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 2d t0 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
+ def c0, 31, 63, 0.5, 1
+ def c1, 0.0322580636, 0.0158730168, 0, 0
+ dcl t0.xy
+ dcl_2d s0
+ texld r0, t0, s0
+ mad r0.xyz, r0, c0.xyxw, c0.z
+ frc r1.xyz, r0
+ add r0.xyz, r0, -r1
+ mul r0.xyz, r0, c1.xyxw
+ mov r0.w, c0.w
+ mov oC0, r0
+
+// approximately 7 instruction slots used (1 texture, 6 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 r0.xyz, r0.xyzx, l(31.000000, 63.000000, 31.000000, 0.000000)
+round_ne r0.xyz, r0.xyzx
+mul o0.xyz, r0.xyzx, l(0.032258, 0.015873, 0.032258, 0.000000)
+mov o0.w, l(1.000000)
+ret
+// Approximately 6 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGB2D_565[] = {
+ 68, 88, 66, 67, 120, 69, 206, 120, 97, 29, 104, 168, 87, 8, 112, 9, 57, 119, 88,
+ 99, 1, 0, 0, 0, 180, 3, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 32, 1,
+ 0, 0, 12, 2, 0, 0, 136, 2, 0, 0, 40, 3, 0, 0, 128, 3, 0, 0, 65,
+ 111, 110, 57, 224, 0, 0, 0, 224, 0, 0, 0, 0, 2, 255, 255, 184, 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, 81, 0, 0, 5, 0, 0,
+ 15, 160, 0, 0, 248, 65, 0, 0, 124, 66, 0, 0, 0, 63, 0, 0, 128, 63, 81,
+ 0, 0, 5, 1, 0, 15, 160, 8, 33, 4, 61, 33, 8, 130, 60, 0, 0, 0, 0,
+ 0, 0, 0, 0, 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, 4, 0, 0, 4, 0, 0, 7, 128, 0, 0, 228, 128, 0,
+ 0, 196, 160, 0, 0, 170, 160, 19, 0, 0, 2, 1, 0, 7, 128, 0, 0, 228, 128,
+ 2, 0, 0, 3, 0, 0, 7, 128, 0, 0, 228, 128, 1, 0, 228, 129, 5, 0, 0,
+ 3, 0, 0, 7, 128, 0, 0, 228, 128, 1, 0, 196, 160, 1, 0, 0, 2, 0, 0,
+ 8, 128, 0, 0, 255, 160, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255,
+ 255, 0, 0, 83, 72, 68, 82, 228, 0, 0, 0, 64, 0, 0, 0, 57, 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, 10, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0,
+ 0, 0, 2, 64, 0, 0, 0, 0, 248, 65, 0, 0, 124, 66, 0, 0, 248, 65, 0,
+ 0, 0, 0, 64, 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0,
+ 0, 0, 0, 0, 56, 0, 0, 10, 114, 32, 16, 0, 0, 0, 0, 0, 70, 2, 16,
+ 0, 0, 0, 0, 0, 2, 64, 0, 0, 8, 33, 4, 61, 33, 8, 130, 60, 8, 33,
+ 4, 61, 0, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1,
+ 64, 0, 0, 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0,
+ 6, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 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, 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, 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, 82, 68, 69, 70, 152, 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, 49, 48, 46, 49, 0, 171, 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, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2darray11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2darray11ps.h
new file mode 100644
index 0000000000..22fc48b370
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2darray11ps.h
@@ -0,0 +1,85 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2darray (float,float,float,float) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 1
+utof r0.z, v1.x
+mov r0.xy, v2.xyxx
+sample r0.xyzw, r0.xyzx, t0.xyzw, s0
+mov o0.xyz, r0.xyzx
+mov o0.w, l(1.000000)
+ret
+// Approximately 6 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGB2DArray[] = {
+ 68, 88, 66, 67, 26, 40, 103, 223, 174, 169, 46, 176, 180, 125, 61, 98, 234, 113, 13,
+ 48, 1, 0, 0, 0, 224, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 100, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 5,
+ 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, 49, 48, 46, 49, 0,
+ 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 3, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 83, 72, 68, 82, 204, 0, 0, 0, 64, 0, 0, 0, 51, 0, 0, 0, 90, 0,
+ 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 64, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, 18, 16, 16, 0, 1, 0, 0, 0,
+ 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0,
+ 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 86, 0,
+ 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 1, 0, 0, 0, 54,
+ 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 2, 0, 0, 0,
+ 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0,
+ 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 54, 0,
+ 0, 5, 114, 32, 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, 1, 64, 0, 0, 0, 0, 128, 63,
+ 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0, 3, 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, 1, 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, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2darray_565_11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2darray_565_11ps.h
new file mode 100644
index 0000000000..93c8675762
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2darray_565_11ps.h
@@ -0,0 +1,91 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2darray (float,float,float,float) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 1
+utof r0.z, v1.x
+mov r0.xy, v2.xyxx
+sample r0.xyzw, r0.xyzx, t0.xyzw, s0
+mul r0.xyz, r0.xyzx, l(31.000000, 63.000000, 31.000000, 0.000000)
+round_ne r0.xyz, r0.xyzx
+mul o0.xyz, r0.xyzx, l(0.032258, 0.015873, 0.032258, 0.000000)
+mov o0.w, l(1.000000)
+ret
+// Approximately 8 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGB2DArray_565[] = {
+ 68, 88, 66, 67, 185, 16, 51, 115, 29, 189, 183, 180, 27, 245, 224, 140, 177, 41, 213,
+ 79, 1, 0, 0, 0, 48, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 180, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 5,
+ 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, 49, 48, 46, 49, 0,
+ 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 3, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 83, 72, 68, 82, 28, 1, 0, 0, 64, 0, 0, 0, 71, 0, 0, 0, 90, 0,
+ 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 64, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, 18, 16, 16, 0, 1, 0, 0, 0,
+ 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0,
+ 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 86, 0,
+ 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 1, 0, 0, 0, 54,
+ 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 2, 0, 0, 0,
+ 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0,
+ 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56, 0,
+ 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2,
+ 64, 0, 0, 0, 0, 248, 65, 0, 0, 124, 66, 0, 0, 248, 65, 0, 0, 0, 0,
+ 64, 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0,
+ 0, 56, 0, 0, 10, 114, 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0,
+ 0, 0, 2, 64, 0, 0, 8, 33, 4, 61, 33, 8, 130, 60, 8, 33, 4, 61, 0,
+ 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0,
+ 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 8, 0, 0,
+ 0, 1, 0, 0, 0, 0, 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, 1, 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, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2darrayi11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2darrayi11ps.h
new file mode 100644
index 0000000000..da517dedc7
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2darrayi11ps.h
@@ -0,0 +1,89 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// TextureI texture sint4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET int xyzw
+//
+ps_4_0
+dcl_resource_texture2darray (sint,sint,sint,sint) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 1
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xy, r0.xyxx
+mul r0.xy, r0.xyxx, v2.xyxx
+ftoi r0.xy, r0.xyxx
+mov r0.z, v1.x
+mov r0.w, l(0)
+ld r0.xyzw, r0.xyzw, t0.xyzw
+mov o0.xyz, r0.xyzx
+mov o0.w, l(1)
+ret
+// Approximately 10 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGB2DArrayI[] = {
+ 68, 88, 66, 67, 176, 173, 178, 89, 17, 53, 136, 1, 253, 33, 56, 172, 20, 106, 131,
+ 127, 1, 0, 0, 0, 4, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0,
+ 0, 0, 52, 1, 0, 0, 104, 1, 0, 0, 136, 2, 0, 0, 82, 68, 69, 70, 112,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 69, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0,
+ 0, 3, 0, 0, 0, 5, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0,
+ 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 73, 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, 49, 48, 46, 49, 0, 171, 171,
+ 171, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15,
+ 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0,
+ 1, 0, 0, 0, 1, 1, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 3, 0, 0, 83, 86, 95, 80, 79, 83,
+ 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, 82, 71,
+ 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, 79, 79,
+ 82, 68, 0, 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, 2, 0, 0, 0, 0, 0,
+ 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 171, 171, 83,
+ 72, 68, 82, 24, 1, 0, 0, 64, 0, 0, 0, 70, 0, 0, 0, 88, 64, 0, 4,
+ 0, 112, 16, 0, 0, 0, 0, 0, 51, 51, 0, 0, 100, 8, 0, 4, 18, 16, 16,
+ 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 2, 0,
+ 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1,
+ 0, 0, 0, 61, 16, 0, 7, 242, 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, 2,
+ 0, 0, 0, 27, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0,
+ 0, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16,
+ 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64,
+ 0, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 70,
+ 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5,
+ 114, 32, 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, 1, 64, 0, 0, 1, 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, 3, 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, 4, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2darrayui11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2darrayui11ps.h
new file mode 100644
index 0000000000..3b33754c28
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2darrayui11ps.h
@@ -0,0 +1,89 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// TextureUI texture uint4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET uint xyzw
+//
+ps_4_0
+dcl_resource_texture2darray (uint,uint,uint,uint) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 1
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xy, r0.xyxx
+mul r0.xy, r0.xyxx, v2.xyxx
+ftoi r0.xy, r0.xyxx
+mov r0.z, v1.x
+mov r0.w, l(0)
+ld r0.xyzw, r0.xyzw, t0.xyzw
+mov o0.xyz, r0.xyzx
+mov o0.w, l(1)
+ret
+// Approximately 10 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGB2DArrayUI[] = {
+ 68, 88, 66, 67, 239, 124, 234, 46, 158, 116, 212, 164, 152, 122, 22, 86, 114, 177, 255,
+ 160, 1, 0, 0, 0, 4, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0,
+ 0, 0, 52, 1, 0, 0, 104, 1, 0, 0, 136, 2, 0, 0, 82, 68, 69, 70, 112,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 70, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0,
+ 0, 4, 0, 0, 0, 5, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0,
+ 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 85, 73, 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, 49, 48, 46, 49, 0, 171,
+ 171, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15,
+ 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0,
+ 1, 0, 0, 0, 1, 1, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 3, 0, 0, 83, 86, 95, 80, 79, 83,
+ 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, 82, 71,
+ 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, 79, 79,
+ 82, 68, 0, 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, 1, 0, 0, 0, 0, 0,
+ 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 171, 171, 83,
+ 72, 68, 82, 24, 1, 0, 0, 64, 0, 0, 0, 70, 0, 0, 0, 88, 64, 0, 4,
+ 0, 112, 16, 0, 0, 0, 0, 0, 68, 68, 0, 0, 100, 8, 0, 4, 18, 16, 16,
+ 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 2, 0,
+ 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1,
+ 0, 0, 0, 61, 16, 0, 7, 242, 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, 2,
+ 0, 0, 0, 27, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0,
+ 0, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16,
+ 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64,
+ 0, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 70,
+ 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5,
+ 114, 32, 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, 1, 64, 0, 0, 1, 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, 3, 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, 4, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2di11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2di11ps.h
new file mode 100644
index 0000000000..79ff3c4168
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2di11ps.h
@@ -0,0 +1,82 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// TextureI texture sint4 2d t0 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 int xyzw
+//
+ps_4_0
+dcl_resource_texture2d (sint,sint,sint,sint) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 1
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xy, r0.xyxx
+mul r0.xy, r0.xyxx, v1.xyxx
+ftoi r0.xy, r0.xyxx
+mov r0.zw, l(0,0,0,0)
+ld r0.xyzw, r0.xyzw, t0.xyzw
+mov o0.xyz, r0.xyzx
+mov o0.w, l(0)
+ret
+// Approximately 9 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGB2DI[] = {
+ 68, 88, 66, 67, 190, 234, 127, 190, 151, 71, 156, 183, 160, 74, 156, 153, 91, 12, 95,
+ 85, 1, 0, 0, 0, 188, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0,
+ 0, 0, 4, 1, 0, 0, 56, 1, 0, 0, 64, 2, 0, 0, 82, 68, 69, 70, 112,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 69, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0,
+ 0, 3, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0,
+ 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 73, 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, 49, 48, 46, 49, 0, 171, 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, 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, 2, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84,
+ 65, 82, 71, 69, 84, 0, 171, 171, 83, 72, 68, 82, 0, 1, 0, 0, 64, 0, 0,
+ 0, 64, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 51, 51,
+ 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, 61, 16, 0, 7,
+ 242, 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, 27, 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, 45, 0, 0, 7, 242, 0, 16, 0, 0,
+ 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0,
+ 54, 0, 0, 5, 114, 32, 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, 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, 3, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2dui11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2dui11ps.h
new file mode 100644
index 0000000000..74ef0a2236
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb2dui11ps.h
@@ -0,0 +1,82 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// TextureUI texture uint4 2d t0 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 uint xyzw
+//
+ps_4_0
+dcl_resource_texture2d (uint,uint,uint,uint) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 1
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xy, r0.xyxx
+mul r0.xy, r0.xyxx, v1.xyxx
+ftoi r0.xy, r0.xyxx
+mov r0.zw, l(0,0,0,0)
+ld r0.xyzw, r0.xyzw, t0.xyzw
+mov o0.xyz, r0.xyzx
+mov o0.w, l(0)
+ret
+// Approximately 9 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGB2DUI[] = {
+ 68, 88, 66, 67, 240, 47, 31, 84, 32, 155, 233, 36, 235, 43, 92, 251, 152, 13, 113,
+ 169, 1, 0, 0, 0, 188, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0,
+ 0, 0, 4, 1, 0, 0, 56, 1, 0, 0, 64, 2, 0, 0, 82, 68, 69, 70, 112,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 70, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0,
+ 0, 4, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0,
+ 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 85, 73, 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, 49, 48, 46, 49, 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, 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, 1, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84,
+ 65, 82, 71, 69, 84, 0, 171, 171, 83, 72, 68, 82, 0, 1, 0, 0, 64, 0, 0,
+ 0, 64, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 68, 68,
+ 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, 61, 16, 0, 7,
+ 242, 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, 27, 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, 45, 0, 0, 7, 242, 0, 16, 0, 0,
+ 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0,
+ 54, 0, 0, 5, 114, 32, 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, 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, 3, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3d11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3d11ps.h
new file mode 100644
index 0000000000..b533c74d77
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3d11ps.h
@@ -0,0 +1,79 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v2.xyzx, t0.xyzw, s0
+mov o0.xyz, r0.xyzx
+mov o0.w, l(1.000000)
+ret
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGB3D[] = {
+ 68, 88, 66, 67, 121, 178, 78, 177, 99, 144, 108, 81, 39, 245, 135, 91, 55, 31, 56,
+ 111, 1, 0, 0, 0, 168, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 44, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 8,
+ 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, 49, 48, 46, 49, 0,
+ 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 83, 72, 68, 82, 148, 0, 0, 0, 64, 0, 0, 0, 37, 0, 0, 0, 90, 0,
+ 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 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, 18, 16, 0, 2, 0,
+ 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 54,
+ 0, 0, 5, 114, 32, 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, 1, 64, 0, 0, 0, 0, 128,
+ 63, 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, 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, 1, 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, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3d_565_11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3d_565_11ps.h
new file mode 100644
index 0000000000..5222d51cc3
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3d_565_11ps.h
@@ -0,0 +1,85 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v2.xyzx, t0.xyzw, s0
+mul r0.xyz, r0.xyzx, l(31.000000, 63.000000, 31.000000, 0.000000)
+round_ne r0.xyz, r0.xyzx
+mul o0.xyz, r0.xyzx, l(0.032258, 0.015873, 0.032258, 0.000000)
+mov o0.w, l(1.000000)
+ret
+// Approximately 6 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGB3D_565[] = {
+ 68, 88, 66, 67, 190, 139, 108, 54, 112, 70, 128, 98, 155, 40, 89, 132, 48, 127, 91,
+ 244, 1, 0, 0, 0, 248, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 124, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 8,
+ 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, 49, 48, 46, 49, 0,
+ 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 83, 72, 68, 82, 228, 0, 0, 0, 64, 0, 0, 0, 57, 0, 0, 0, 90, 0,
+ 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 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, 18, 16, 0, 2, 0,
+ 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56,
+ 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0,
+ 2, 64, 0, 0, 0, 0, 248, 65, 0, 0, 124, 66, 0, 0, 248, 65, 0, 0, 0,
+ 0, 64, 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0,
+ 0, 0, 56, 0, 0, 10, 114, 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0,
+ 0, 0, 0, 2, 64, 0, 0, 8, 33, 4, 61, 33, 8, 130, 60, 8, 33, 4, 61,
+ 0, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0,
+ 0, 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 6, 0,
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 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, 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, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3di11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3di11ps.h
new file mode 100644
index 0000000000..9e590b3ebb
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3di11ps.h
@@ -0,0 +1,85 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// TextureI texture sint4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET int xyzw
+//
+ps_4_0
+dcl_resource_texture3d (sint,sint,sint,sint) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xyz, r0.xyzx
+mul r0.xyz, r0.xyzx, v2.xyzx
+ftoi r0.xyz, r0.xyzx
+mov r0.w, l(0)
+ld r0.xyzw, r0.xyzw, t0.xyzw
+mov o0.xyz, r0.xyzx
+mov o0.w, l(0)
+ret
+// Approximately 9 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGB3DI[] = {
+ 68, 88, 66, 67, 122, 80, 149, 91, 225, 62, 16, 173, 12, 194, 248, 74, 159, 33, 217,
+ 135, 1, 0, 0, 0, 224, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0,
+ 0, 0, 52, 1, 0, 0, 104, 1, 0, 0, 100, 2, 0, 0, 82, 68, 69, 70, 112,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 69, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0,
+ 0, 3, 0, 0, 0, 8, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0,
+ 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 73, 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, 49, 48, 46, 49, 0, 171, 171,
+ 171, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15,
+ 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0,
+ 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, 79, 83,
+ 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, 82, 71,
+ 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, 79, 79,
+ 82, 68, 0, 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, 2, 0, 0, 0, 0, 0,
+ 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 171, 171, 83,
+ 72, 68, 82, 244, 0, 0, 0, 64, 0, 0, 0, 61, 0, 0, 0, 88, 40, 0, 4,
+ 0, 112, 16, 0, 0, 0, 0, 0, 51, 51, 0, 0, 98, 16, 0, 3, 114, 16, 16,
+ 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0,
+ 0, 2, 1, 0, 0, 0, 61, 16, 0, 7, 242, 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,
+ 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0,
+ 7, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 18,
+ 16, 0, 2, 0, 0, 0, 27, 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70,
+ 2, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0,
+ 1, 64, 0, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0,
+ 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 54, 0,
+ 0, 5, 114, 32, 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, 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, 3, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3dui11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3dui11ps.h
new file mode 100644
index 0000000000..534b9d9faa
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgb3dui11ps.h
@@ -0,0 +1,85 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// TextureUI texture uint4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET uint xyzw
+//
+ps_4_0
+dcl_resource_texture3d (uint,uint,uint,uint) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xyz, r0.xyzx
+mul r0.xyz, r0.xyzx, v2.xyzx
+ftoi r0.xyz, r0.xyzx
+mov r0.w, l(0)
+ld r0.xyzw, r0.xyzw, t0.xyzw
+mov o0.xyz, r0.xyzx
+mov o0.w, l(0)
+ret
+// Approximately 9 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGB3DUI[] = {
+ 68, 88, 66, 67, 177, 156, 23, 109, 67, 253, 176, 134, 182, 213, 173, 70, 148, 235, 60,
+ 205, 1, 0, 0, 0, 224, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0,
+ 0, 0, 52, 1, 0, 0, 104, 1, 0, 0, 100, 2, 0, 0, 82, 68, 69, 70, 112,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 70, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0,
+ 0, 4, 0, 0, 0, 8, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0,
+ 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 85, 73, 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, 49, 48, 46, 49, 0, 171,
+ 171, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15,
+ 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0,
+ 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, 79, 83,
+ 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, 82, 71,
+ 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, 79, 79,
+ 82, 68, 0, 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, 1, 0, 0, 0, 0, 0,
+ 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 171, 171, 83,
+ 72, 68, 82, 244, 0, 0, 0, 64, 0, 0, 0, 61, 0, 0, 0, 88, 40, 0, 4,
+ 0, 112, 16, 0, 0, 0, 0, 0, 68, 68, 0, 0, 98, 16, 0, 3, 114, 16, 16,
+ 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0,
+ 0, 2, 1, 0, 0, 0, 61, 16, 0, 7, 242, 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,
+ 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0,
+ 7, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 18,
+ 16, 0, 2, 0, 0, 0, 27, 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70,
+ 2, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0,
+ 1, 64, 0, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0,
+ 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 54, 0,
+ 0, 5, 114, 32, 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, 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, 3, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d11ps.h
new file mode 100644
index 0000000000..f8b36063f2
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d11ps.h
@@ -0,0 +1,93 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 2d t0 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
+ mov oC0, r0
+
+// approximately 2 instruction slots used (1 texture, 1 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
+sample o0.xyzw, v1.xyxx, t0.xyzw, s0
+ret
+// Approximately 2 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGBA2D[] = {
+ 68, 88, 66, 67, 23, 65, 12, 167, 50, 71, 137, 250, 170, 67, 18, 134, 110, 213, 196,
+ 219, 1, 0, 0, 0, 184, 2, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 164, 0,
+ 0, 0, 16, 1, 0, 0, 140, 1, 0, 0, 44, 2, 0, 0, 132, 2, 0, 0, 65,
+ 111, 110, 57, 100, 0, 0, 0, 100, 0, 0, 0, 0, 2, 255, 255, 60, 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, 1, 0, 0, 2,
+ 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 100, 0, 0,
+ 0, 64, 0, 0, 0, 25, 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, 69, 0, 0, 9, 242, 32, 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, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 2, 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, 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, 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, 82, 68, 69,
+ 70, 152, 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, 49, 48, 46,
+ 49, 0, 171, 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, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d_4444_11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d_4444_11ps.h
new file mode 100644
index 0000000000..2f94f13c12
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d_4444_11ps.h
@@ -0,0 +1,112 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 2d t0 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
+ def c0, 15, 0.5, 0.0666666701, 0
+ dcl t0.xy
+ dcl_2d s0
+ texld r0, t0, s0
+ mad r0, r0, c0.x, c0.y
+ frc r1, r0
+ add r0, r0, -r1
+ mul r0, r0, c0.z
+ mov oC0, r0
+
+// approximately 6 instruction slots used (1 texture, 5 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 r0.xyzw, r0.xyzw, l(15.000000, 15.000000, 15.000000, 15.000000)
+round_ne r0.xyzw, r0.xyzw
+mul o0.xyzw, r0.xyzw, l(0.066667, 0.066667, 0.066667, 0.066667)
+ret
+// Approximately 5 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGBA2D_4444[] = {
+ 68, 88, 66, 67, 188, 56, 0, 47, 220, 85, 24, 210, 59, 166, 131, 1, 131, 90, 227,
+ 171, 1, 0, 0, 0, 124, 3, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 252, 0,
+ 0, 0, 212, 1, 0, 0, 80, 2, 0, 0, 240, 2, 0, 0, 72, 3, 0, 0, 65,
+ 111, 110, 57, 188, 0, 0, 0, 188, 0, 0, 0, 0, 2, 255, 255, 148, 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, 81, 0, 0, 5, 0, 0,
+ 15, 160, 0, 0, 112, 65, 0, 0, 0, 63, 137, 136, 136, 61, 0, 0, 0, 0, 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, 4, 0, 0, 4, 0, 0, 15, 128, 0, 0, 228, 128, 0, 0, 0, 160, 0, 0,
+ 85, 160, 19, 0, 0, 2, 1, 0, 15, 128, 0, 0, 228, 128, 2, 0, 0, 3, 0,
+ 0, 15, 128, 0, 0, 228, 128, 1, 0, 228, 129, 5, 0, 0, 3, 0, 0, 15, 128,
+ 0, 0, 228, 128, 0, 0, 170, 160, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228,
+ 128, 255, 255, 0, 0, 83, 72, 68, 82, 208, 0, 0, 0, 64, 0, 0, 0, 52, 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, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0,
+ 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 112, 65, 0, 0, 112, 65, 0, 0, 112,
+ 65, 0, 0, 112, 65, 64, 0, 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14,
+ 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 32, 16, 0, 0, 0, 0, 0, 70,
+ 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 137, 136, 136, 61, 137, 136, 136, 61,
+ 137, 136, 136, 61, 137, 136, 136, 61, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0,
+ 0, 5, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 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,
+ 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, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 82, 68, 69, 70, 152, 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, 49, 48, 46, 49, 0, 171, 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, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d_5551_11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d_5551_11ps.h
new file mode 100644
index 0000000000..44966d6a9b
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2d_5551_11ps.h
@@ -0,0 +1,112 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 2d t0 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
+ def c0, 31, 1, 0.5, 0.0322580636
+ dcl t0.xy
+ dcl_2d s0
+ texld r0, t0, s0
+ mad r0, r0, c0.xxxy, c0.z
+ frc r1, r0
+ add r0, r0, -r1
+ mul r0, r0, c0.wwwy
+ mov oC0, r0
+
+// approximately 6 instruction slots used (1 texture, 5 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 r0.xyzw, r0.xyzw, l(31.000000, 31.000000, 31.000000, 1.000000)
+round_ne r0.xyzw, r0.xyzw
+mul o0.xyzw, r0.xyzw, l(0.032258, 0.032258, 0.032258, 1.000000)
+ret
+// Approximately 5 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGBA2D_5551[] = {
+ 68, 88, 66, 67, 202, 32, 204, 89, 54, 13, 5, 203, 247, 109, 207, 183, 162, 90, 24,
+ 32, 1, 0, 0, 0, 124, 3, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 252, 0,
+ 0, 0, 212, 1, 0, 0, 80, 2, 0, 0, 240, 2, 0, 0, 72, 3, 0, 0, 65,
+ 111, 110, 57, 188, 0, 0, 0, 188, 0, 0, 0, 0, 2, 255, 255, 148, 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, 81, 0, 0, 5, 0, 0,
+ 15, 160, 0, 0, 248, 65, 0, 0, 128, 63, 0, 0, 0, 63, 8, 33, 4, 61, 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, 4, 0, 0, 4, 0, 0, 15, 128, 0, 0, 228, 128, 0, 0, 64, 160, 0, 0,
+ 170, 160, 19, 0, 0, 2, 1, 0, 15, 128, 0, 0, 228, 128, 2, 0, 0, 3, 0,
+ 0, 15, 128, 0, 0, 228, 128, 1, 0, 228, 129, 5, 0, 0, 3, 0, 0, 15, 128,
+ 0, 0, 228, 128, 0, 0, 127, 160, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228,
+ 128, 255, 255, 0, 0, 83, 72, 68, 82, 208, 0, 0, 0, 64, 0, 0, 0, 52, 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, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0,
+ 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 248, 65, 0, 0, 248, 65, 0, 0, 248,
+ 65, 0, 0, 128, 63, 64, 0, 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14,
+ 16, 0, 0, 0, 0, 0, 56, 0, 0, 10, 242, 32, 16, 0, 0, 0, 0, 0, 70,
+ 14, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 8, 33, 4, 61, 8, 33, 4, 61,
+ 8, 33, 4, 61, 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0,
+ 0, 5, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 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,
+ 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, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 82, 68, 69, 70, 152, 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, 49, 48, 46, 49, 0, 171, 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, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darray11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darray11ps.h
new file mode 100644
index 0000000000..227aab3bf9
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darray11ps.h
@@ -0,0 +1,81 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2darray (float,float,float,float) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 1
+utof r0.z, v1.x
+mov r0.xy, v2.xyxx
+sample o0.xyzw, r0.xyzx, t0.xyzw, s0
+ret
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGBA2DArray[] = {
+ 68, 88, 66, 67, 200, 215, 233, 151, 66, 46, 221, 224, 83, 242, 34, 162, 166, 5, 137,
+ 148, 1, 0, 0, 0, 184, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 60, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 5,
+ 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, 49, 48, 46, 49, 0,
+ 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 3, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 83, 72, 68, 82, 164, 0, 0, 0, 64, 0, 0, 0, 41, 0, 0, 0, 90, 0,
+ 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 64, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, 18, 16, 16, 0, 1, 0, 0, 0,
+ 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0,
+ 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 86, 0,
+ 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 1, 0, 0, 0, 54,
+ 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 2, 0, 0, 0,
+ 69, 0, 0, 9, 242, 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0,
+ 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 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, 3, 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, 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, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darray_4444_11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darray_4444_11ps.h
new file mode 100644
index 0000000000..24011717c7
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darray_4444_11ps.h
@@ -0,0 +1,89 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2darray (float,float,float,float) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 1
+utof r0.z, v1.x
+mov r0.xy, v2.xyxx
+sample r0.xyzw, r0.xyzx, t0.xyzw, s0
+mul r0.xyzw, r0.xyzw, l(15.000000, 15.000000, 15.000000, 15.000000)
+round_ne r0.xyzw, r0.xyzw
+mul o0.xyzw, r0.xyzw, l(0.066667, 0.066667, 0.066667, 0.066667)
+ret
+// Approximately 7 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGBA2DArray_4444[] = {
+ 68, 88, 66, 67, 88, 17, 60, 194, 201, 5, 168, 96, 74, 117, 234, 137, 214, 224, 224,
+ 134, 1, 0, 0, 0, 28, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 160, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 5,
+ 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, 49, 48, 46, 49, 0,
+ 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 3, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 83, 72, 68, 82, 8, 1, 0, 0, 64, 0, 0, 0, 66, 0, 0, 0, 90, 0,
+ 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 64, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, 18, 16, 16, 0, 1, 0, 0, 0,
+ 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0,
+ 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 86, 0,
+ 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 1, 0, 0, 0, 54,
+ 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 2, 0, 0, 0,
+ 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0,
+ 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56, 0,
+ 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2,
+ 64, 0, 0, 0, 0, 112, 65, 0, 0, 112, 65, 0, 0, 112, 65, 0, 0, 112, 65,
+ 64, 0, 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0,
+ 0, 56, 0, 0, 10, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0,
+ 0, 0, 2, 64, 0, 0, 137, 136, 136, 61, 137, 136, 136, 61, 137, 136, 136, 61, 137,
+ 136, 136, 61, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 7, 0, 0, 0,
+ 1, 0, 0, 0, 0, 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, 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, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darray_5551_11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darray_5551_11ps.h
new file mode 100644
index 0000000000..f6335bccef
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darray_5551_11ps.h
@@ -0,0 +1,89 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2darray (float,float,float,float) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 1
+utof r0.z, v1.x
+mov r0.xy, v2.xyxx
+sample r0.xyzw, r0.xyzx, t0.xyzw, s0
+mul r0.xyzw, r0.xyzw, l(31.000000, 31.000000, 31.000000, 1.000000)
+round_ne r0.xyzw, r0.xyzw
+mul o0.xyzw, r0.xyzw, l(0.032258, 0.032258, 0.032258, 1.000000)
+ret
+// Approximately 7 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGBA2DArray_5551[] = {
+ 68, 88, 66, 67, 68, 140, 194, 251, 165, 142, 204, 154, 232, 236, 200, 233, 255, 120, 4,
+ 27, 1, 0, 0, 0, 28, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 160, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 5,
+ 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, 49, 48, 46, 49, 0,
+ 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 3, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 83, 72, 68, 82, 8, 1, 0, 0, 64, 0, 0, 0, 66, 0, 0, 0, 90, 0,
+ 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 64, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, 18, 16, 16, 0, 1, 0, 0, 0,
+ 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0,
+ 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 86, 0,
+ 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 1, 0, 0, 0, 54,
+ 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 2, 0, 0, 0,
+ 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0,
+ 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56, 0,
+ 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 2,
+ 64, 0, 0, 0, 0, 248, 65, 0, 0, 248, 65, 0, 0, 248, 65, 0, 0, 128, 63,
+ 64, 0, 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0,
+ 0, 56, 0, 0, 10, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0,
+ 0, 0, 2, 64, 0, 0, 8, 33, 4, 61, 8, 33, 4, 61, 8, 33, 4, 61, 0,
+ 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 7, 0, 0, 0,
+ 1, 0, 0, 0, 0, 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, 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, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darrayi11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darrayi11ps.h
new file mode 100644
index 0000000000..457935a252
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darrayi11ps.h
@@ -0,0 +1,85 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// TextureI texture sint4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET int xyzw
+//
+ps_4_0
+dcl_resource_texture2darray (sint,sint,sint,sint) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 1
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xy, r0.xyxx
+mul r0.xy, r0.xyxx, v2.xyxx
+ftoi r0.xy, r0.xyxx
+mov r0.z, v1.x
+mov r0.w, l(0)
+ld o0.xyzw, r0.xyzw, t0.xyzw
+ret
+// Approximately 8 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGBA2DArrayI[] = {
+ 68, 88, 66, 67, 215, 68, 211, 98, 73, 229, 148, 22, 136, 6, 112, 36, 206, 148, 145,
+ 188, 1, 0, 0, 0, 220, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0,
+ 0, 0, 52, 1, 0, 0, 104, 1, 0, 0, 96, 2, 0, 0, 82, 68, 69, 70, 112,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 69, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0,
+ 0, 3, 0, 0, 0, 5, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0,
+ 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 73, 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, 49, 48, 46, 49, 0, 171, 171,
+ 171, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15,
+ 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0,
+ 1, 0, 0, 0, 1, 1, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 3, 0, 0, 83, 86, 95, 80, 79, 83,
+ 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, 82, 71,
+ 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, 79, 79,
+ 82, 68, 0, 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, 2, 0, 0, 0, 0, 0,
+ 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 171, 171, 83,
+ 72, 68, 82, 240, 0, 0, 0, 64, 0, 0, 0, 60, 0, 0, 0, 88, 64, 0, 4,
+ 0, 112, 16, 0, 0, 0, 0, 0, 51, 51, 0, 0, 100, 8, 0, 4, 18, 16, 16,
+ 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 2, 0,
+ 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1,
+ 0, 0, 0, 61, 16, 0, 7, 242, 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, 2,
+ 0, 0, 0, 27, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0,
+ 0, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16,
+ 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64,
+ 0, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 32, 16, 0, 0, 0, 0, 0, 70,
+ 14, 16, 0, 0, 0, 0, 0, 70, 126, 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, 3, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darrayui11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darrayui11ps.h
new file mode 100644
index 0000000000..58b67ac728
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2darrayui11ps.h
@@ -0,0 +1,85 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// TextureUI texture uint4 2darray t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET uint xyzw
+//
+ps_4_0
+dcl_resource_texture2darray (uint,uint,uint,uint) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 1
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xy, r0.xyxx
+mul r0.xy, r0.xyxx, v2.xyxx
+ftoi r0.xy, r0.xyxx
+mov r0.z, v1.x
+mov r0.w, l(0)
+ld o0.xyzw, r0.xyzw, t0.xyzw
+ret
+// Approximately 8 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGBA2DArrayUI[] = {
+ 68, 88, 66, 67, 31, 32, 146, 134, 107, 181, 50, 167, 97, 108, 64, 57, 238, 167, 69,
+ 217, 1, 0, 0, 0, 220, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0,
+ 0, 0, 52, 1, 0, 0, 104, 1, 0, 0, 96, 2, 0, 0, 82, 68, 69, 70, 112,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 70, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0,
+ 0, 4, 0, 0, 0, 5, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0,
+ 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 85, 73, 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, 49, 48, 46, 49, 0, 171,
+ 171, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15,
+ 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0,
+ 1, 0, 0, 0, 1, 1, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 3, 0, 0, 83, 86, 95, 80, 79, 83,
+ 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, 82, 71,
+ 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, 79, 79,
+ 82, 68, 0, 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, 1, 0, 0, 0, 0, 0,
+ 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 171, 171, 83,
+ 72, 68, 82, 240, 0, 0, 0, 64, 0, 0, 0, 60, 0, 0, 0, 88, 64, 0, 4,
+ 0, 112, 16, 0, 0, 0, 0, 0, 68, 68, 0, 0, 100, 8, 0, 4, 18, 16, 16,
+ 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 2, 0,
+ 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1,
+ 0, 0, 0, 61, 16, 0, 7, 242, 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, 2,
+ 0, 0, 0, 27, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0,
+ 0, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16,
+ 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64,
+ 0, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 32, 16, 0, 0, 0, 0, 0, 70,
+ 14, 16, 0, 0, 0, 0, 0, 70, 126, 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, 3, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2di11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2di11ps.h
new file mode 100644
index 0000000000..eb0ebbd6ea
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2di11ps.h
@@ -0,0 +1,78 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// TextureI texture sint4 2d t0 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 int xyzw
+//
+ps_4_0
+dcl_resource_texture2d (sint,sint,sint,sint) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 1
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xy, r0.xyxx
+mul r0.xy, r0.xyxx, v1.xyxx
+ftoi r0.xy, r0.xyxx
+mov r0.zw, l(0,0,0,0)
+ld o0.xyzw, r0.xyzw, t0.xyzw
+ret
+// Approximately 7 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGBA2DI[] = {
+ 68, 88, 66, 67, 11, 194, 121, 174, 53, 241, 53, 229, 116, 76, 99, 226, 54, 79, 165,
+ 216, 1, 0, 0, 0, 148, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0,
+ 0, 0, 4, 1, 0, 0, 56, 1, 0, 0, 24, 2, 0, 0, 82, 68, 69, 70, 112,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 69, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0,
+ 0, 3, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0,
+ 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 73, 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, 49, 48, 46, 49, 0, 171, 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, 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, 2, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84,
+ 65, 82, 71, 69, 84, 0, 171, 171, 83, 72, 68, 82, 216, 0, 0, 0, 64, 0, 0,
+ 0, 54, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 51, 51,
+ 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, 61, 16, 0, 7,
+ 242, 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, 27, 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, 45, 0, 0, 7, 242, 32, 16, 0, 0,
+ 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 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, 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, 1, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dms11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dms11ps.h
new file mode 100644
index 0000000000..76361532d2
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dms11ps.h
@@ -0,0 +1,80 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// TextureF_MS texture float4 2dMS t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// TEXCOORD 0 xy 1 NONE float xy
+// SV_SAMPLEINDEX 0 x 2 SAMPLE uint x
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+// Pixel Shader runs at sample frequency
+//
+ps_4_1
+dcl_globalFlags refactoringAllowed
+dcl_resource_texture2dms(0) (float,float,float,float) t0
+dcl_input_ps linear v1.xy
+dcl_input_ps_sgv constant v2.x, sampleIndex
+dcl_output o0.xyzw
+dcl_temps 1
+ftou r0.xy, v1.xyxx
+mov r0.zw, l(0,0,0,0)
+ldms o0.xyzw, r0.xyzw, t0.xyzw, v2.x
+ret
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGBA2DMS[] = {
+ 68, 88, 66, 67, 49, 75, 69, 135, 188, 202, 223, 102, 144, 42, 4, 30, 173, 255, 143,
+ 210, 1, 0, 0, 0, 136, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0,
+ 0, 0, 40, 1, 0, 0, 92, 1, 0, 0, 12, 2, 0, 0, 82, 68, 69, 70, 112,
+ 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, 72, 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, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 77, 83, 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, 49, 48, 46, 49,
+ 0, 73, 83, 71, 78, 116, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15,
+ 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,
+ 1, 0, 0, 0, 3, 3, 0, 0, 101, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0,
+ 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 1, 0, 0, 83, 86, 95, 80, 79, 83,
+ 73, 84, 73, 79, 78, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 83,
+ 65, 77, 80, 76, 69, 73, 78, 68, 69, 88, 0, 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, 83, 72, 68, 82, 168, 0, 0, 0, 65, 0, 0, 0, 42,
+ 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, 99, 8, 0,
+ 4, 18, 16, 16, 0, 2, 0, 0, 0, 10, 0, 0, 0, 101, 0, 0, 3, 242, 32,
+ 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 28, 0, 0, 5, 50,
+ 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 1, 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, 242, 32, 16, 0, 0, 0,
+ 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 10,
+ 16, 16, 0, 2, 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, 3, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dui11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dui11ps.h
new file mode 100644
index 0000000000..31f84d0d74
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba2dui11ps.h
@@ -0,0 +1,78 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// TextureUI texture uint4 2d t0 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 uint xyzw
+//
+ps_4_0
+dcl_resource_texture2d (uint,uint,uint,uint) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 1
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xy, r0.xyxx
+mul r0.xy, r0.xyxx, v1.xyxx
+ftoi r0.xy, r0.xyxx
+mov r0.zw, l(0,0,0,0)
+ld o0.xyzw, r0.xyzw, t0.xyzw
+ret
+// Approximately 7 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGBA2DUI[] = {
+ 68, 88, 66, 67, 116, 109, 92, 124, 46, 28, 237, 165, 173, 42, 6, 53, 183, 101, 128,
+ 93, 1, 0, 0, 0, 148, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0,
+ 0, 0, 4, 1, 0, 0, 56, 1, 0, 0, 24, 2, 0, 0, 82, 68, 69, 70, 112,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 70, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0,
+ 0, 4, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0,
+ 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 85, 73, 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, 49, 48, 46, 49, 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, 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, 1, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84,
+ 65, 82, 71, 69, 84, 0, 171, 171, 83, 72, 68, 82, 216, 0, 0, 0, 64, 0, 0,
+ 0, 54, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 68, 68,
+ 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, 61, 16, 0, 7,
+ 242, 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, 27, 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, 45, 0, 0, 7, 242, 32, 16, 0, 0,
+ 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 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, 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, 1, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d11ps.h
new file mode 100644
index 0000000000..4aef441bcd
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d11ps.h
@@ -0,0 +1,74 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+sample o0.xyzw, v2.xyzx, t0.xyzw, s0
+ret
+// Approximately 2 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGBA3D[] = {
+ 68, 88, 66, 67, 68, 93, 216, 66, 165, 49, 226, 52, 230, 199, 150, 143, 253, 53, 233,
+ 213, 1, 0, 0, 0, 120, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 252, 1, 0, 0, 82, 68, 69, 70, 152,
+ 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, 8,
+ 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, 49, 48, 46, 49, 0,
+ 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 83, 72, 68, 82, 100, 0, 0, 0, 64, 0, 0, 0, 25, 0, 0, 0, 90, 0,
+ 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 0, 0, 0,
+ 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 69, 0, 0, 9, 242, 32, 16,
+ 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, 0, 0, 70, 126, 16, 0, 0, 0,
+ 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116,
+ 0, 0, 0, 2, 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, 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, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d_4444_11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d_4444_11ps.h
new file mode 100644
index 0000000000..d6c7a28333
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d_4444_11ps.h
@@ -0,0 +1,83 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v2.xyzx, t0.xyzw, s0
+mul r0.xyzw, r0.xyzw, l(15.000000, 15.000000, 15.000000, 15.000000)
+round_ne r0.xyzw, r0.xyzw
+mul o0.xyzw, r0.xyzw, l(0.066667, 0.066667, 0.066667, 0.066667)
+ret
+// Approximately 5 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGBA3D_4444[] = {
+ 68, 88, 66, 67, 244, 22, 101, 89, 172, 184, 153, 143, 94, 198, 255, 75, 136, 76, 172,
+ 69, 1, 0, 0, 0, 228, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 104, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 8,
+ 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, 49, 48, 46, 49, 0,
+ 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 83, 72, 68, 82, 208, 0, 0, 0, 64, 0, 0, 0, 52, 0, 0, 0, 90, 0,
+ 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 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, 18, 16, 0, 2, 0,
+ 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56,
+ 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0,
+ 2, 64, 0, 0, 0, 0, 112, 65, 0, 0, 112, 65, 0, 0, 112, 65, 0, 0, 112,
+ 65, 64, 0, 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0,
+ 0, 0, 56, 0, 0, 10, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0,
+ 0, 0, 0, 2, 64, 0, 0, 137, 136, 136, 61, 137, 136, 136, 61, 137, 136, 136, 61,
+ 137, 136, 136, 61, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 5, 0, 0,
+ 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d_5551_11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d_5551_11ps.h
new file mode 100644
index 0000000000..3329c4d2ce
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3d_5551_11ps.h
@@ -0,0 +1,83 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF texture float4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v2.xyzx, t0.xyzw, s0
+mul r0.xyzw, r0.xyzw, l(31.000000, 31.000000, 31.000000, 1.000000)
+round_ne r0.xyzw, r0.xyzw
+mul o0.xyzw, r0.xyzw, l(0.032258, 0.032258, 0.032258, 1.000000)
+ret
+// Approximately 5 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGBA3D_5551[] = {
+ 68, 88, 66, 67, 84, 84, 9, 48, 70, 52, 100, 237, 108, 219, 183, 20, 215, 148, 144,
+ 173, 1, 0, 0, 0, 228, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 212, 0,
+ 0, 0, 92, 1, 0, 0, 144, 1, 0, 0, 104, 2, 0, 0, 82, 68, 69, 70, 152,
+ 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, 8,
+ 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, 49, 48, 46, 49, 0,
+ 171, 171, 171, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80,
+ 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65,
+ 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67,
+ 79, 79, 82, 68, 0, 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, 83, 72, 68, 82, 208, 0, 0, 0, 64, 0, 0, 0, 52, 0, 0, 0, 90, 0,
+ 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 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, 18, 16, 0, 2, 0,
+ 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56,
+ 0, 0, 10, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0,
+ 2, 64, 0, 0, 0, 0, 248, 65, 0, 0, 248, 65, 0, 0, 248, 65, 0, 0, 128,
+ 63, 64, 0, 0, 5, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0,
+ 0, 0, 56, 0, 0, 10, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0,
+ 0, 0, 0, 2, 64, 0, 0, 8, 33, 4, 61, 8, 33, 4, 61, 8, 33, 4, 61,
+ 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 5, 0, 0,
+ 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3di11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3di11ps.h
new file mode 100644
index 0000000000..81adb14ca9
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3di11ps.h
@@ -0,0 +1,81 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// TextureI texture sint4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET int xyzw
+//
+ps_4_0
+dcl_resource_texture3d (sint,sint,sint,sint) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xyz, r0.xyzx
+mul r0.xyz, r0.xyzx, v2.xyzx
+ftoi r0.xyz, r0.xyzx
+mov r0.w, l(0)
+ld o0.xyzw, r0.xyzw, t0.xyzw
+ret
+// Approximately 7 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGBA3DI[] = {
+ 68, 88, 66, 67, 112, 154, 25, 211, 170, 223, 11, 97, 14, 10, 139, 203, 225, 190, 33,
+ 158, 1, 0, 0, 0, 184, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0,
+ 0, 0, 52, 1, 0, 0, 104, 1, 0, 0, 60, 2, 0, 0, 82, 68, 69, 70, 112,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 69, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0,
+ 0, 3, 0, 0, 0, 8, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0,
+ 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 73, 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, 49, 48, 46, 49, 0, 171, 171,
+ 171, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15,
+ 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0,
+ 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, 79, 83,
+ 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, 82, 71,
+ 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, 79, 79,
+ 82, 68, 0, 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, 2, 0, 0, 0, 0, 0,
+ 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 171, 171, 83,
+ 72, 68, 82, 204, 0, 0, 0, 64, 0, 0, 0, 51, 0, 0, 0, 88, 40, 0, 4,
+ 0, 112, 16, 0, 0, 0, 0, 0, 51, 51, 0, 0, 98, 16, 0, 3, 114, 16, 16,
+ 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0,
+ 0, 2, 1, 0, 0, 0, 61, 16, 0, 7, 242, 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,
+ 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0,
+ 7, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 18,
+ 16, 0, 2, 0, 0, 0, 27, 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70,
+ 2, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0,
+ 1, 64, 0, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 32, 16, 0, 0, 0, 0,
+ 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 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, 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, 1, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3dui11ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3dui11ps.h
new file mode 100644
index 0000000000..31bc39204d
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughrgba3dui11ps.h
@@ -0,0 +1,81 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// TextureUI texture uint4 3d t0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET uint xyzw
+//
+ps_4_0
+dcl_resource_texture3d (uint,uint,uint,uint) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xyz, r0.xyzx
+mul r0.xyz, r0.xyzx, v2.xyzx
+ftoi r0.xyz, r0.xyzx
+mov r0.w, l(0)
+ld o0.xyzw, r0.xyzw, t0.xyzw
+ret
+// Approximately 7 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGBA3DUI[] = {
+ 68, 88, 66, 67, 136, 72, 192, 109, 253, 59, 232, 36, 69, 34, 127, 153, 17, 12, 205,
+ 209, 1, 0, 0, 0, 184, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0,
+ 0, 0, 52, 1, 0, 0, 104, 1, 0, 0, 60, 2, 0, 0, 82, 68, 69, 70, 112,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 70, 0, 0, 0, 60, 0, 0, 0, 2, 0, 0,
+ 0, 4, 0, 0, 0, 8, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0,
+ 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 85, 73, 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, 49, 48, 46, 49, 0, 171,
+ 171, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0,
+ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15,
+ 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0,
+ 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, 79, 83,
+ 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, 82, 71,
+ 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, 79, 79,
+ 82, 68, 0, 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, 1, 0, 0, 0, 0, 0,
+ 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 171, 171, 83,
+ 72, 68, 82, 204, 0, 0, 0, 64, 0, 0, 0, 51, 0, 0, 0, 88, 40, 0, 4,
+ 0, 112, 16, 0, 0, 0, 0, 0, 68, 68, 0, 0, 98, 16, 0, 3, 114, 16, 16,
+ 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0,
+ 0, 2, 1, 0, 0, 0, 61, 16, 0, 7, 242, 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,
+ 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0,
+ 7, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 18,
+ 16, 0, 2, 0, 0, 0, 27, 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70,
+ 2, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0,
+ 1, 64, 0, 0, 0, 0, 0, 0, 45, 0, 0, 7, 242, 32, 16, 0, 0, 0, 0,
+ 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 126, 16, 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, 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, 1, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvecolor2dps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvecolor2dps.h
new file mode 100644
index 0000000000..8283ea9c4c
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvecolor2dps.h
@@ -0,0 +1,103 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// TextureF_MS texture float4 2dMS t0 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
+//
+ps_4_1
+dcl_globalFlags refactoringAllowed
+dcl_resource_texture2dms(0) (float,float,float,float) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 4
+resinfo_uint r0.xy, l(0), t0.xyzw
+sampleinfo_uint r0.z, t0.x
+utof r0.xy, r0.xyxx
+mul r0.xy, r0.xyxx, v1.xyxx
+ftou r1.xy, r0.xyxx
+mov r1.zw, l(0,0,0,0)
+mov r2.xyzw, l(0,0,0,0)
+mov r0.x, l(0)
+loop
+ uge r0.y, r0.x, r0.z
+ breakc_nz r0.y
+ ldms r3.xyzw, r1.xyzw, t0.xyzw, r0.x
+ add r2.xyzw, r2.xyzw, r3.xyzw
+ iadd r0.x, r0.x, l(1)
+endloop
+sampleinfo r0.x, t0.x
+div o0.xyzw, r2.xyzw, r0.xxxx
+ret
+// Approximately 18 instruction slots used
+#endif
+
+const BYTE g_PS_ResolveColor2D[] = {
+ 68, 88, 66, 67, 93, 61, 55, 147, 13, 181, 1, 129, 207, 120, 176, 100, 210, 126, 243,
+ 242, 1, 0, 0, 0, 128, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 172, 0,
+ 0, 0, 4, 1, 0, 0, 56, 1, 0, 0, 4, 3, 0, 0, 82, 68, 69, 70, 112,
+ 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, 72, 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, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 70, 95, 77, 83, 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, 49, 48, 46, 49,
+ 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, 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, 83, 72, 68, 82, 196, 1, 0, 0, 65, 0, 0,
+ 0, 113, 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, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 4, 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, 111, 8, 0, 5, 66, 0, 16, 0, 0, 0,
+ 0, 0, 10, 112, 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, 1, 0, 0, 0, 70, 0, 16, 0, 0, 0,
+ 0, 0, 54, 0, 0, 8, 194, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 8,
+ 242, 0, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 5, 18, 0, 16, 0, 0, 0,
+ 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 48, 0, 0, 1, 80, 0, 0, 7, 34,
+ 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0,
+ 0, 0, 0, 0, 3, 0, 4, 3, 26, 0, 16, 0, 0, 0, 0, 0, 46, 0, 0,
+ 9, 242, 0, 16, 0, 3, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 70, 126,
+ 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 7, 242,
+ 0, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 14, 16, 0,
+ 3, 0, 0, 0, 30, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16,
+ 0, 0, 0, 0, 0, 1, 64, 0, 0, 1, 0, 0, 0, 22, 0, 0, 1, 111, 0,
+ 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 10, 112, 16, 0, 0, 0, 0, 0, 14,
+ 0, 0, 7, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0,
+ 6, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0,
+ 0, 18, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0,
+ 0, 0, 1, 0, 0, 0, 1, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 3, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepth11_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepth11_ps.h
new file mode 100644
index 0000000000..0f986c7843
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepth11_ps.h
@@ -0,0 +1,81 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Depth texture float 2dMS t0 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_Depth 0 N/A oDepth DEPTH float YES
+//
+ps_4_1
+dcl_globalFlags refactoringAllowed
+dcl_resource_texture2dms(0) (float,float,float,float) t0
+dcl_input_ps linear v1.xy
+dcl_output oDepth
+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 oDepth, r0.x
+ret
+// Approximately 8 instruction slots used
+#endif
+
+const BYTE g_PS_ResolveDepth[] = {
+ 68, 88, 66, 67, 133, 15, 63, 40, 192, 212, 199, 79, 7, 253, 243, 47, 246, 158, 13,
+ 45, 1, 0, 0, 0, 168, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 168, 0,
+ 0, 0, 0, 1, 0, 0, 52, 1, 0, 0, 44, 2, 0, 0, 82, 68, 69, 70, 108,
+ 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, 49, 48, 46, 49, 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, 255, 255, 255, 255, 1, 14, 0, 0, 83, 86, 95, 68, 101, 112, 116, 104,
+ 0, 171, 171, 171, 83, 72, 68, 82, 240, 0, 0, 0, 65, 0, 0, 0, 60, 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, 2, 1,
+ 192, 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, 4, 1, 192, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepthstencil11_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepthstencil11_ps.h
new file mode 100644
index 0000000000..449fbdbed9
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepthstencil11_ps.h
@@ -0,0 +1,92 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Depth texture float 2dMS t0 1
+// Stencil texture uint2 2dMS t1 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, 89, 136, 221, 180, 85, 229, 18, 205, 242, 112, 176, 35, 107, 34, 5,
+ 254, 1, 0, 0, 0, 32, 3, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 208, 0,
+ 0, 0, 40, 1, 0, 0, 92, 1, 0, 0, 164, 2, 0, 0, 82, 68, 69, 70, 148,
+ 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, 49, 48, 46, 49, 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, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepthstencil11_vs.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepthstencil11_vs.h
new file mode 100644
index 0000000000..162168be33
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepthstencil11_vs.h
@@ -0,0 +1,83 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+//
+// 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, 151, 71, 251, 149, 26, 9, 107, 111, 231, 137, 148, 94, 92, 2, 252,
+ 182, 1, 0, 0, 0, 244, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 128, 0,
+ 0, 0, 180, 0, 0, 0, 12, 1, 0, 0, 120, 2, 0, 0, 82, 68, 69, 70, 68,
+ 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, 49, 48, 46, 49, 0, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvestencil11_ps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvestencil11_ps.h
new file mode 100644
index 0000000000..0f96154858
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvestencil11_ps.h
@@ -0,0 +1,84 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Stencil texture uint2 2dMS t1 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, 123, 66, 135, 11, 171, 75, 198, 85, 15, 70, 47, 122, 95, 167, 34,
+ 235, 1, 0, 0, 0, 196, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 168, 0,
+ 0, 0, 0, 1, 0, 0, 52, 1, 0, 0, 72, 2, 0, 0, 82, 68, 69, 70, 108,
+ 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, 49, 48, 46, 49, 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, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2darrayps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2darrayps.h
new file mode 100644
index 0000000000..d3d5c0f0e3
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2darrayps.h
@@ -0,0 +1,135 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Buffer Definitions:
+//
+// cbuffer SwizzleProperties
+// {
+//
+// uint4 SwizzleIndices; // Offset: 0 Size: 16
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF2DArray texture float4 2darray t0 1
+// SwizzleProperties cbuffer NA NA cb0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_constantbuffer CB0[1], immediateIndexed
+dcl_sampler s0, mode_default
+dcl_resource_texture2darray (float,float,float,float) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 1
+dcl_indexableTemp x0[6], 4
+utof r0.z, v1.x
+mov r0.xy, v2.xyxx
+sample r0.xyzw, r0.xyzx, t0.xyzw, s0
+mov x0[0].x, r0.x
+mov x0[1].x, r0.y
+mov x0[2].x, r0.z
+mov x0[3].x, r0.w
+mov x0[4].x, l(0)
+mov x0[5].x, l(1.000000)
+mov r0.x, cb0[0].x
+mov o0.x, x0[r0.x + 0].x
+mov r0.x, cb0[0].y
+mov o0.y, x0[r0.x + 0].x
+mov r0.x, cb0[0].z
+mov o0.z, x0[r0.x + 0].x
+mov r0.x, cb0[0].w
+mov o0.w, x0[r0.x + 0].x
+ret
+// Approximately 18 instruction slots used
+#endif
+
+const BYTE g_PS_SwizzleF2DArray[] = {
+ 68, 88, 66, 67, 43, 191, 227, 129, 77, 88, 223, 209, 64, 17, 168, 91, 78, 216, 210,
+ 134, 1, 0, 0, 0, 192, 4, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 92, 1,
+ 0, 0, 228, 1, 0, 0, 24, 2, 0, 0, 68, 4, 0, 0, 82, 68, 69, 70, 32,
+ 1, 0, 0, 1, 0, 0, 0, 168, 0, 0, 0, 3, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 248, 0, 0, 0, 124, 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, 132, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 5,
+ 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0,
+ 148, 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, 1, 0, 0, 0, 83, 97, 109, 112, 108, 101,
+ 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 50, 68, 65, 114, 114, 97, 121, 0, 83,
+ 119, 105, 122, 122, 108, 101, 80, 114, 111, 112, 101, 114, 116, 105, 101, 115, 0, 171, 171,
+ 148, 0, 0, 0, 1, 0, 0, 0, 192, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0,
+ 0, 0, 232, 0, 0, 0, 0, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 73, 110,
+ 100, 105, 99, 101, 115, 0, 171, 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0,
+ 0, 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, 49, 48, 46, 49, 0, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8,
+ 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0,
+ 0, 0, 0, 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0,
+ 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 3, 0, 0, 83,
+ 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69,
+ 82, 84, 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84,
+ 69, 88, 67, 79, 79, 82, 68, 0, 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, 83, 72, 68, 82, 36, 2, 0, 0, 64, 0, 0, 0, 137, 0, 0,
+ 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 90, 0,
+ 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 64, 0, 4, 0, 112, 16, 0, 0,
+ 0, 0, 0, 85, 85, 0, 0, 100, 8, 0, 4, 18, 16, 16, 0, 1, 0, 0, 0,
+ 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0,
+ 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 105, 0,
+ 0, 4, 0, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 86, 0, 0, 5, 66,
+ 0, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5,
+ 50, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 2, 0, 0, 0, 69, 0, 0,
+ 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 126,
+ 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18,
+ 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0,
+ 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, 0, 16,
+ 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 2, 0,
+ 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0,
+ 0, 0, 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6,
+ 18, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0,
+ 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 1, 64,
+ 0, 0, 0, 0, 128, 63, 54, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 10,
+ 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 18, 32, 16, 0,
+ 0, 0, 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0,
+ 0, 54, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 26, 128, 32, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 34, 32, 16, 0, 0, 0, 0, 0, 10,
+ 48, 32, 4, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6,
+ 18, 0, 16, 0, 0, 0, 0, 0, 42, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 54, 0, 0, 7, 66, 32, 16, 0, 0, 0, 0, 0, 10, 48, 32, 4, 0, 0,
+ 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 0,
+ 0, 0, 0, 58, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7,
+ 130, 32, 16, 0, 0, 0, 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, 10, 0, 16,
+ 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 18, 0,
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 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,
+ 6, 0, 0, 0, 10, 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, 5, 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};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2dps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2dps.h
new file mode 100644
index 0000000000..091c3e29ea
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2dps.h
@@ -0,0 +1,126 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Buffer Definitions:
+//
+// cbuffer SwizzleProperties
+// {
+//
+// uint4 SwizzleIndices; // Offset: 0 Size: 16
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF2D texture float4 2d t0 1
+// SwizzleProperties cbuffer NA NA cb0 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
+//
+ps_4_0
+dcl_constantbuffer CB0[1], immediateIndexed
+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
+dcl_indexableTemp x0[6], 4
+sample r0.xyzw, v1.xyxx, t0.xyzw, s0
+mov x0[0].x, r0.x
+mov x0[1].x, r0.y
+mov x0[2].x, r0.z
+mov x0[3].x, r0.w
+mov x0[4].x, l(0)
+mov x0[5].x, l(1.000000)
+mov r0.x, cb0[0].x
+mov o0.x, x0[r0.x + 0].x
+mov r0.x, cb0[0].y
+mov o0.y, x0[r0.x + 0].x
+mov r0.x, cb0[0].z
+mov o0.z, x0[r0.x + 0].x
+mov r0.x, cb0[0].w
+mov o0.w, x0[r0.x + 0].x
+ret
+// Approximately 16 instruction slots used
+#endif
+
+const BYTE g_PS_SwizzleF2D[] = {
+ 68, 88, 66, 67, 221, 55, 186, 66, 171, 208, 86, 211, 37, 150, 98, 209, 236, 60, 108,
+ 41, 1, 0, 0, 0, 84, 4, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 88, 1,
+ 0, 0, 176, 1, 0, 0, 228, 1, 0, 0, 216, 3, 0, 0, 82, 68, 69, 70, 28,
+ 1, 0, 0, 1, 0, 0, 0, 164, 0, 0, 0, 3, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 244, 0, 0, 0, 124, 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, 132, 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,
+ 143, 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, 1, 0, 0, 0, 83, 97, 109, 112, 108, 101,
+ 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 50, 68, 0, 83, 119, 105, 122, 122, 108,
+ 101, 80, 114, 111, 112, 101, 114, 116, 105, 101, 115, 0, 171, 171, 171, 143, 0, 0, 0,
+ 1, 0, 0, 0, 188, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 212, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 228, 0,
+ 0, 0, 0, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 73, 110, 100, 105, 99, 101,
+ 115, 0, 171, 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46,
+ 49, 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, 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, 83, 72, 68, 82, 236, 1, 0, 0, 64, 0,
+ 0, 0, 123, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 1,
+ 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, 105, 0, 0, 4, 0, 0, 0, 0, 6, 0, 0, 0, 4,
+ 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, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0,
+ 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 1,
+ 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0,
+ 0, 0, 0, 0, 2, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0,
+ 6, 18, 48, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0,
+ 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1,
+ 64, 0, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0,
+ 5, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 54, 0, 0, 6, 18, 0, 16,
+ 0, 0, 0, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0,
+ 0, 7, 18, 32, 16, 0, 0, 0, 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, 10,
+ 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0,
+ 26, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 34, 32, 16,
+ 0, 0, 0, 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0,
+ 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 42, 128, 32, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 66, 32, 16, 0, 0, 0, 0, 0,
+ 10, 48, 32, 4, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0,
+ 6, 18, 0, 16, 0, 0, 0, 0, 0, 58, 128, 32, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 54, 0, 0, 7, 130, 32, 16, 0, 0, 0, 0, 0, 10, 48, 32, 4, 0,
+ 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84,
+ 116, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 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, 6, 0, 0, 0, 10, 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, 4, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef3dps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef3dps.h
new file mode 100644
index 0000000000..042cd18005
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef3dps.h
@@ -0,0 +1,129 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Buffer Definitions:
+//
+// cbuffer SwizzleProperties
+// {
+//
+// uint4 SwizzleIndices; // Offset: 0 Size: 16
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// Sampler sampler NA NA s0 1
+// TextureF3D texture float4 3d t0 1
+// SwizzleProperties cbuffer NA NA cb0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET float xyzw
+//
+ps_4_0
+dcl_constantbuffer CB0[1], immediateIndexed
+dcl_sampler s0, mode_default
+dcl_resource_texture3d (float,float,float,float) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+dcl_indexableTemp x0[6], 4
+sample r0.xyzw, v2.xyzx, t0.xyzw, s0
+mov x0[0].x, r0.x
+mov x0[1].x, r0.y
+mov x0[2].x, r0.z
+mov x0[3].x, r0.w
+mov x0[4].x, l(0)
+mov x0[5].x, l(1.000000)
+mov r0.x, cb0[0].x
+mov o0.x, x0[r0.x + 0].x
+mov r0.x, cb0[0].y
+mov o0.y, x0[r0.x + 0].x
+mov r0.x, cb0[0].z
+mov o0.z, x0[r0.x + 0].x
+mov r0.x, cb0[0].w
+mov o0.w, x0[r0.x + 0].x
+ret
+// Approximately 16 instruction slots used
+#endif
+
+const BYTE g_PS_SwizzleF3D[] = {
+ 68, 88, 66, 67, 73, 214, 47, 221, 178, 220, 225, 86, 113, 45, 198, 41, 129, 110, 186,
+ 79, 1, 0, 0, 0, 132, 4, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 88, 1,
+ 0, 0, 224, 1, 0, 0, 20, 2, 0, 0, 8, 4, 0, 0, 82, 68, 69, 70, 28,
+ 1, 0, 0, 1, 0, 0, 0, 164, 0, 0, 0, 3, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 244, 0, 0, 0, 124, 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, 132, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 8,
+ 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0,
+ 143, 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, 1, 0, 0, 0, 83, 97, 109, 112, 108, 101,
+ 114, 0, 84, 101, 120, 116, 117, 114, 101, 70, 51, 68, 0, 83, 119, 105, 122, 122, 108,
+ 101, 80, 114, 111, 112, 101, 114, 116, 105, 101, 115, 0, 171, 171, 171, 143, 0, 0, 0,
+ 1, 0, 0, 0, 188, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 212, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 228, 0,
+ 0, 0, 0, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 73, 110, 100, 105, 99, 101,
+ 115, 0, 171, 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46,
+ 49, 0, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80,
+ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0,
+ 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0,
+ 0, 1, 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, 79,
+ 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, 82,
+ 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, 79,
+ 79, 82, 68, 0, 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,
+ 83, 72, 68, 82, 236, 1, 0, 0, 64, 0, 0, 0, 123, 0, 0, 0, 89, 0, 0,
+ 4, 70, 142, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 90, 0, 0, 3, 0, 96,
+ 16, 0, 0, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85,
+ 85, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3,
+ 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 105, 0, 0,
+ 4, 0, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 69, 0, 0, 9, 242, 0,
+ 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, 0, 0, 70, 126, 16, 0, 0,
+ 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0,
+ 6, 18, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0,
+ 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 42,
+ 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0,
+ 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32,
+ 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, 0,
+ 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 1, 64, 0, 0, 0,
+ 0, 128, 63, 54, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 10, 128, 32, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 18, 32, 16, 0, 0, 0, 0,
+ 0, 10, 48, 32, 4, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0,
+ 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 26, 128, 32, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 54, 0, 0, 7, 34, 32, 16, 0, 0, 0, 0, 0, 10, 48, 32, 4,
+ 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16,
+ 0, 0, 0, 0, 0, 42, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0,
+ 0, 7, 66, 32, 16, 0, 0, 0, 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, 10,
+ 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0,
+ 58, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 130, 32, 16,
+ 0, 0, 0, 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0,
+ 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 16, 0, 0, 0, 1,
+ 0, 0, 0, 0, 0, 0, 0, 2, 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, 6, 0, 0,
+ 0, 10, 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, 4, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2darrayps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2darrayps.h
new file mode 100644
index 0000000000..08c48427e2
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2darrayps.h
@@ -0,0 +1,139 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Buffer Definitions:
+//
+// cbuffer SwizzleProperties
+// {
+//
+// uint4 SwizzleIndices; // Offset: 0 Size: 16
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// TextureI2DArray texture sint4 2darray t0 1
+// SwizzleProperties cbuffer NA NA cb0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET int xyzw
+//
+ps_4_0
+dcl_constantbuffer CB0[1], immediateIndexed
+dcl_resource_texture2darray (sint,sint,sint,sint) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 1
+dcl_indexableTemp x0[6], 4
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xy, r0.xyxx
+mul r0.xy, r0.xyxx, v2.xyxx
+ftoi r0.xy, r0.xyxx
+mov r0.z, v1.x
+mov r0.w, l(0)
+ld r0.xyzw, r0.xyzw, t0.xyzw
+mov x0[0].x, r0.x
+mov x0[1].x, r0.y
+mov x0[2].x, r0.z
+mov x0[3].x, r0.w
+mov x0[4].x, l(0)
+mov x0[5].x, l(1)
+mov r0.x, cb0[0].x
+mov o0.x, x0[r0.x + 0].x
+mov r0.x, cb0[0].y
+mov o0.y, x0[r0.x + 0].x
+mov r0.x, cb0[0].z
+mov o0.z, x0[r0.x + 0].x
+mov r0.x, cb0[0].w
+mov o0.w, x0[r0.x + 0].x
+ret
+// Approximately 22 instruction slots used
+#endif
+
+const BYTE g_PS_SwizzleI2DArray[] = {
+ 68, 88, 66, 67, 212, 163, 121, 141, 10, 113, 132, 178, 58, 176, 145, 98, 43, 111, 211,
+ 61, 1, 0, 0, 0, 228, 4, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 52, 1,
+ 0, 0, 188, 1, 0, 0, 240, 1, 0, 0, 104, 4, 0, 0, 82, 68, 69, 70, 248,
+ 0, 0, 0, 1, 0, 0, 0, 128, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 208, 0, 0, 0, 92, 0, 0, 0, 2, 0, 0,
+ 0, 3, 0, 0, 0, 5, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0,
+ 0, 0, 13, 0, 0, 0, 108, 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, 1, 0, 0, 0,
+ 84, 101, 120, 116, 117, 114, 101, 73, 50, 68, 65, 114, 114, 97, 121, 0, 83, 119, 105,
+ 122, 122, 108, 101, 80, 114, 111, 112, 101, 114, 116, 105, 101, 115, 0, 171, 171, 108, 0,
+ 0, 0, 1, 0, 0, 0, 152, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 176, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0,
+ 192, 0, 0, 0, 0, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 73, 110, 100, 105,
+ 99, 101, 115, 0, 171, 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 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, 49,
+ 48, 46, 49, 0, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0,
+ 0, 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0,
+ 0, 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1,
+ 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 3, 0, 0, 83, 86, 95,
+ 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84,
+ 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88,
+ 67, 79, 79, 82, 68, 0, 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, 2, 0, 0,
+ 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0,
+ 171, 171, 83, 72, 68, 82, 112, 2, 0, 0, 64, 0, 0, 0, 156, 0, 0, 0, 89,
+ 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 88, 64, 0, 4,
+ 0, 112, 16, 0, 0, 0, 0, 0, 51, 51, 0, 0, 100, 8, 0, 4, 18, 16, 16,
+ 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 2, 0,
+ 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1,
+ 0, 0, 0, 105, 0, 0, 4, 0, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0,
+ 61, 16, 0, 7, 242, 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, 2, 0, 0, 0,
+ 27, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0,
+ 0, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 1, 0,
+ 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0,
+ 0, 0, 0, 45, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0,
+ 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0,
+ 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0,
+ 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0,
+ 42, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0,
+ 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48,
+ 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54,
+ 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 1, 64, 0, 0,
+ 1, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 10, 128, 32,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 18, 32, 16, 0, 0, 0,
+ 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54,
+ 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 26, 128, 32, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 54, 0, 0, 7, 34, 32, 16, 0, 0, 0, 0, 0, 10, 48, 32,
+ 4, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 0,
+ 16, 0, 0, 0, 0, 0, 42, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54,
+ 0, 0, 7, 66, 32, 16, 0, 0, 0, 0, 0, 10, 48, 32, 4, 0, 0, 0, 0,
+ 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0,
+ 0, 58, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 130, 32,
+ 16, 0, 0, 0, 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, 10, 0, 16, 0, 0,
+ 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 22, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 3, 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, 6, 0,
+ 0, 0, 10, 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, 6, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2dps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2dps.h
new file mode 100644
index 0000000000..fbce5942df
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2dps.h
@@ -0,0 +1,132 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Buffer Definitions:
+//
+// cbuffer SwizzleProperties
+// {
+//
+// uint4 SwizzleIndices; // Offset: 0 Size: 16
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// TextureI2D texture sint4 2d t0 1
+// SwizzleProperties cbuffer NA NA cb0 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 int xyzw
+//
+ps_4_0
+dcl_constantbuffer CB0[1], immediateIndexed
+dcl_resource_texture2d (sint,sint,sint,sint) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 1
+dcl_indexableTemp x0[6], 4
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xy, r0.xyxx
+mul r0.xy, r0.xyxx, v1.xyxx
+ftoi r0.xy, r0.xyxx
+mov r0.zw, l(0,0,0,0)
+ld r0.xyzw, r0.xyzw, t0.xyzw
+mov x0[0].x, r0.x
+mov x0[1].x, r0.y
+mov x0[2].x, r0.z
+mov x0[3].x, r0.w
+mov x0[4].x, l(0)
+mov x0[5].x, l(1)
+mov r0.x, cb0[0].x
+mov o0.x, x0[r0.x + 0].x
+mov r0.x, cb0[0].y
+mov o0.y, x0[r0.x + 0].x
+mov r0.x, cb0[0].z
+mov o0.z, x0[r0.x + 0].x
+mov r0.x, cb0[0].w
+mov o0.w, x0[r0.x + 0].x
+ret
+// Approximately 21 instruction slots used
+#endif
+
+const BYTE g_PS_SwizzleI2D[] = {
+ 68, 88, 66, 67, 177, 45, 190, 185, 217, 208, 59, 28, 232, 250, 124, 179, 32, 246, 26,
+ 206, 1, 0, 0, 0, 152, 4, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 48, 1,
+ 0, 0, 136, 1, 0, 0, 188, 1, 0, 0, 28, 4, 0, 0, 82, 68, 69, 70, 244,
+ 0, 0, 0, 1, 0, 0, 0, 124, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 204, 0, 0, 0, 92, 0, 0, 0, 2, 0, 0,
+ 0, 3, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0,
+ 0, 0, 13, 0, 0, 0, 103, 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, 1, 0, 0, 0,
+ 84, 101, 120, 116, 117, 114, 101, 73, 50, 68, 0, 83, 119, 105, 122, 122, 108, 101, 80,
+ 114, 111, 112, 101, 114, 116, 105, 101, 115, 0, 171, 171, 171, 103, 0, 0, 0, 1, 0,
+ 0, 0, 148, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172,
+ 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 188, 0, 0, 0,
+ 0, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 73, 110, 100, 105, 99, 101, 115, 0,
+ 171, 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 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, 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, 2, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 65,
+ 82, 71, 69, 84, 0, 171, 171, 83, 72, 68, 82, 88, 2, 0, 0, 64, 0, 0, 0,
+ 150, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 51, 51, 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, 105, 0, 0, 4, 0, 0, 0, 0,
+ 6, 0, 0, 0, 4, 0, 0, 0, 61, 16, 0, 7, 242, 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, 27, 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, 45, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0,
+ 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0,
+ 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0,
+ 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0,
+ 42, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0,
+ 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48,
+ 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54,
+ 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 1, 64, 0, 0,
+ 1, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 10, 128, 32,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 18, 32, 16, 0, 0, 0,
+ 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54,
+ 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 26, 128, 32, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 54, 0, 0, 7, 34, 32, 16, 0, 0, 0, 0, 0, 10, 48, 32,
+ 4, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 0,
+ 16, 0, 0, 0, 0, 0, 42, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54,
+ 0, 0, 7, 66, 32, 16, 0, 0, 0, 0, 0, 10, 48, 32, 4, 0, 0, 0, 0,
+ 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0,
+ 0, 58, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 130, 32,
+ 16, 0, 0, 0, 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, 10, 0, 16, 0, 0,
+ 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 21, 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, 6, 0,
+ 0, 0, 10, 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, 5, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei3dps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei3dps.h
new file mode 100644
index 0000000000..1ce3ce47c8
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei3dps.h
@@ -0,0 +1,135 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Buffer Definitions:
+//
+// cbuffer SwizzleProperties
+// {
+//
+// uint4 SwizzleIndices; // Offset: 0 Size: 16
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// TextureI3D texture sint4 3d t0 1
+// SwizzleProperties cbuffer NA NA cb0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET int xyzw
+//
+ps_4_0
+dcl_constantbuffer CB0[1], immediateIndexed
+dcl_resource_texture3d (sint,sint,sint,sint) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+dcl_indexableTemp x0[6], 4
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xyz, r0.xyzx
+mul r0.xyz, r0.xyzx, v2.xyzx
+ftoi r0.xyz, r0.xyzx
+mov r0.w, l(0)
+ld r0.xyzw, r0.xyzw, t0.xyzw
+mov x0[0].x, r0.x
+mov x0[1].x, r0.y
+mov x0[2].x, r0.z
+mov x0[3].x, r0.w
+mov x0[4].x, l(0)
+mov x0[5].x, l(1)
+mov r0.x, cb0[0].x
+mov o0.x, x0[r0.x + 0].x
+mov r0.x, cb0[0].y
+mov o0.y, x0[r0.x + 0].x
+mov r0.x, cb0[0].z
+mov o0.z, x0[r0.x + 0].x
+mov r0.x, cb0[0].w
+mov o0.w, x0[r0.x + 0].x
+ret
+// Approximately 21 instruction slots used
+#endif
+
+const BYTE g_PS_SwizzleI3D[] = {
+ 68, 88, 66, 67, 239, 203, 72, 66, 58, 92, 169, 191, 239, 77, 187, 21, 109, 161, 64,
+ 95, 1, 0, 0, 0, 188, 4, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 48, 1,
+ 0, 0, 184, 1, 0, 0, 236, 1, 0, 0, 64, 4, 0, 0, 82, 68, 69, 70, 244,
+ 0, 0, 0, 1, 0, 0, 0, 124, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 204, 0, 0, 0, 92, 0, 0, 0, 2, 0, 0,
+ 0, 3, 0, 0, 0, 8, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0,
+ 0, 0, 13, 0, 0, 0, 103, 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, 1, 0, 0, 0,
+ 84, 101, 120, 116, 117, 114, 101, 73, 51, 68, 0, 83, 119, 105, 122, 122, 108, 101, 80,
+ 114, 111, 112, 101, 114, 116, 105, 101, 115, 0, 171, 171, 171, 103, 0, 0, 0, 1, 0,
+ 0, 0, 148, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172,
+ 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 188, 0, 0, 0,
+ 0, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 73, 110, 100, 105, 99, 101, 115, 0,
+ 171, 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0,
+ 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0,
+ 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 1,
+ 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, 79, 83, 73,
+ 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69,
+ 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82,
+ 68, 0, 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, 2, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 171, 171, 83, 72,
+ 68, 82, 76, 2, 0, 0, 64, 0, 0, 0, 147, 0, 0, 0, 89, 0, 0, 4, 70,
+ 142, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0,
+ 0, 0, 0, 0, 51, 51, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 0, 0,
+ 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0,
+ 0, 0, 105, 0, 0, 4, 0, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 61,
+ 16, 0, 7, 242, 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, 114, 0, 16, 0, 0, 0, 0,
+ 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 0, 0,
+ 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, 0, 0, 27,
+ 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0,
+ 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0,
+ 0, 45, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0,
+ 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6,
+ 18, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0,
+ 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 42, 0,
+ 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 3,
+ 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0,
+ 0, 0, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, 0, 0,
+ 6, 18, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0,
+ 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 10, 128, 32, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 18, 32, 16, 0, 0, 0, 0, 0,
+ 10, 48, 32, 4, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0,
+ 6, 18, 0, 16, 0, 0, 0, 0, 0, 26, 128, 32, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 54, 0, 0, 7, 34, 32, 16, 0, 0, 0, 0, 0, 10, 48, 32, 4, 0,
+ 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0,
+ 0, 0, 0, 0, 42, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0,
+ 7, 66, 32, 16, 0, 0, 0, 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, 10, 0,
+ 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 58,
+ 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 130, 32, 16, 0,
+ 0, 0, 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0,
+ 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 21, 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, 6, 0, 0, 0,
+ 10, 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, 5, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2darrayps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2darrayps.h
new file mode 100644
index 0000000000..d3d479f7b0
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2darrayps.h
@@ -0,0 +1,139 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Buffer Definitions:
+//
+// cbuffer SwizzleProperties
+// {
+//
+// uint4 SwizzleIndices; // Offset: 0 Size: 16
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// TextureUI2DArray texture uint4 2darray t0 1
+// SwizzleProperties cbuffer NA NA cb0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint x
+// TEXCOORD 0 xyz 2 NONE float xy
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET uint xyzw
+//
+ps_4_0
+dcl_constantbuffer CB0[1], immediateIndexed
+dcl_resource_texture2darray (uint,uint,uint,uint) t0
+dcl_input_ps_siv constant v1.x, rendertarget_array_index
+dcl_input_ps linear v2.xy
+dcl_output o0.xyzw
+dcl_temps 1
+dcl_indexableTemp x0[6], 4
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xy, r0.xyxx
+mul r0.xy, r0.xyxx, v2.xyxx
+ftoi r0.xy, r0.xyxx
+mov r0.z, v1.x
+mov r0.w, l(0)
+ld r0.xyzw, r0.xyzw, t0.xyzw
+mov x0[0].x, r0.x
+mov x0[1].x, r0.y
+mov x0[2].x, r0.z
+mov x0[3].x, r0.w
+mov x0[4].x, l(0)
+mov x0[5].x, l(1)
+mov r0.x, cb0[0].x
+mov o0.x, x0[r0.x + 0].x
+mov r0.x, cb0[0].y
+mov o0.y, x0[r0.x + 0].x
+mov r0.x, cb0[0].z
+mov o0.z, x0[r0.x + 0].x
+mov r0.x, cb0[0].w
+mov o0.w, x0[r0.x + 0].x
+ret
+// Approximately 22 instruction slots used
+#endif
+
+const BYTE g_PS_SwizzleUI2DArray[] = {
+ 68, 88, 66, 67, 116, 247, 215, 129, 4, 49, 47, 120, 164, 87, 225, 112, 75, 76, 233,
+ 53, 1, 0, 0, 0, 228, 4, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 52, 1,
+ 0, 0, 188, 1, 0, 0, 240, 1, 0, 0, 104, 4, 0, 0, 82, 68, 69, 70, 248,
+ 0, 0, 0, 1, 0, 0, 0, 128, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 208, 0, 0, 0, 92, 0, 0, 0, 2, 0, 0,
+ 0, 4, 0, 0, 0, 5, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0,
+ 0, 0, 13, 0, 0, 0, 109, 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, 1, 0, 0, 0,
+ 84, 101, 120, 116, 117, 114, 101, 85, 73, 50, 68, 65, 114, 114, 97, 121, 0, 83, 119,
+ 105, 122, 122, 108, 101, 80, 114, 111, 112, 101, 114, 116, 105, 101, 115, 0, 171, 109, 0,
+ 0, 0, 1, 0, 0, 0, 152, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 176, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0,
+ 192, 0, 0, 0, 0, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 73, 110, 100, 105,
+ 99, 101, 115, 0, 171, 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 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, 49,
+ 48, 46, 49, 0, 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0,
+ 0, 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0,
+ 0, 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1,
+ 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 7, 3, 0, 0, 83, 86, 95,
+ 80, 79, 83, 73, 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84,
+ 65, 82, 71, 69, 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88,
+ 67, 79, 79, 82, 68, 0, 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, 1, 0, 0,
+ 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0,
+ 171, 171, 83, 72, 68, 82, 112, 2, 0, 0, 64, 0, 0, 0, 156, 0, 0, 0, 89,
+ 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 88, 64, 0, 4,
+ 0, 112, 16, 0, 0, 0, 0, 0, 68, 68, 0, 0, 100, 8, 0, 4, 18, 16, 16,
+ 0, 1, 0, 0, 0, 4, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 2, 0,
+ 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1,
+ 0, 0, 0, 105, 0, 0, 4, 0, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0,
+ 61, 16, 0, 7, 242, 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, 2, 0, 0, 0,
+ 27, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0,
+ 0, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 1, 0,
+ 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0,
+ 0, 0, 0, 45, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0,
+ 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0,
+ 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0,
+ 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0,
+ 42, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0,
+ 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48,
+ 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54,
+ 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 1, 64, 0, 0,
+ 1, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 10, 128, 32,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 18, 32, 16, 0, 0, 0,
+ 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54,
+ 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 26, 128, 32, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 54, 0, 0, 7, 34, 32, 16, 0, 0, 0, 0, 0, 10, 48, 32,
+ 4, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 0,
+ 16, 0, 0, 0, 0, 0, 42, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54,
+ 0, 0, 7, 66, 32, 16, 0, 0, 0, 0, 0, 10, 48, 32, 4, 0, 0, 0, 0,
+ 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0,
+ 0, 58, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 130, 32,
+ 16, 0, 0, 0, 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, 10, 0, 16, 0, 0,
+ 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 22, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 3, 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, 6, 0,
+ 0, 0, 10, 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, 6, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2dps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2dps.h
new file mode 100644
index 0000000000..b83bd117be
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2dps.h
@@ -0,0 +1,132 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Buffer Definitions:
+//
+// cbuffer SwizzleProperties
+// {
+//
+// uint4 SwizzleIndices; // Offset: 0 Size: 16
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// TextureUI2D texture uint4 2d t0 1
+// SwizzleProperties cbuffer NA NA cb0 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 uint xyzw
+//
+ps_4_0
+dcl_constantbuffer CB0[1], immediateIndexed
+dcl_resource_texture2d (uint,uint,uint,uint) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 1
+dcl_indexableTemp x0[6], 4
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xy, r0.xyxx
+mul r0.xy, r0.xyxx, v1.xyxx
+ftoi r0.xy, r0.xyxx
+mov r0.zw, l(0,0,0,0)
+ld r0.xyzw, r0.xyzw, t0.xyzw
+mov x0[0].x, r0.x
+mov x0[1].x, r0.y
+mov x0[2].x, r0.z
+mov x0[3].x, r0.w
+mov x0[4].x, l(0)
+mov x0[5].x, l(1)
+mov r0.x, cb0[0].x
+mov o0.x, x0[r0.x + 0].x
+mov r0.x, cb0[0].y
+mov o0.y, x0[r0.x + 0].x
+mov r0.x, cb0[0].z
+mov o0.z, x0[r0.x + 0].x
+mov r0.x, cb0[0].w
+mov o0.w, x0[r0.x + 0].x
+ret
+// Approximately 21 instruction slots used
+#endif
+
+const BYTE g_PS_SwizzleUI2D[] = {
+ 68, 88, 66, 67, 5, 230, 100, 22, 104, 28, 143, 55, 98, 102, 32, 210, 129, 6, 68,
+ 183, 1, 0, 0, 0, 152, 4, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 48, 1,
+ 0, 0, 136, 1, 0, 0, 188, 1, 0, 0, 28, 4, 0, 0, 82, 68, 69, 70, 244,
+ 0, 0, 0, 1, 0, 0, 0, 124, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 204, 0, 0, 0, 92, 0, 0, 0, 2, 0, 0,
+ 0, 4, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0,
+ 0, 0, 13, 0, 0, 0, 104, 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, 1, 0, 0, 0,
+ 84, 101, 120, 116, 117, 114, 101, 85, 73, 50, 68, 0, 83, 119, 105, 122, 122, 108, 101,
+ 80, 114, 111, 112, 101, 114, 116, 105, 101, 115, 0, 171, 171, 104, 0, 0, 0, 1, 0,
+ 0, 0, 148, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172,
+ 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 188, 0, 0, 0,
+ 0, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 73, 110, 100, 105, 99, 101, 115, 0,
+ 171, 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 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, 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, 1, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 65,
+ 82, 71, 69, 84, 0, 171, 171, 83, 72, 68, 82, 88, 2, 0, 0, 64, 0, 0, 0,
+ 150, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 68, 68, 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, 105, 0, 0, 4, 0, 0, 0, 0,
+ 6, 0, 0, 0, 4, 0, 0, 0, 61, 16, 0, 7, 242, 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, 27, 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, 45, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0,
+ 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0,
+ 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0,
+ 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0,
+ 42, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0,
+ 0, 3, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48,
+ 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54,
+ 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 1, 64, 0, 0,
+ 1, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 10, 128, 32,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 18, 32, 16, 0, 0, 0,
+ 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54,
+ 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 26, 128, 32, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 54, 0, 0, 7, 34, 32, 16, 0, 0, 0, 0, 0, 10, 48, 32,
+ 4, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 0,
+ 16, 0, 0, 0, 0, 0, 42, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54,
+ 0, 0, 7, 66, 32, 16, 0, 0, 0, 0, 0, 10, 48, 32, 4, 0, 0, 0, 0,
+ 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0,
+ 0, 58, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 130, 32,
+ 16, 0, 0, 0, 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, 10, 0, 16, 0, 0,
+ 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 21, 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, 6, 0,
+ 0, 0, 10, 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, 5, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui3dps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui3dps.h
new file mode 100644
index 0000000000..a7024e22db
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui3dps.h
@@ -0,0 +1,135 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.1
+//
+//
+// Buffer Definitions:
+//
+// cbuffer SwizzleProperties
+// {
+//
+// uint4 SwizzleIndices; // Offset: 0 Size: 16
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name Type Format Dim HLSL Bind Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// TextureUI3D texture uint4 3d t0 1
+// SwizzleProperties cbuffer NA NA cb0 1
+//
+//
+//
+// Input signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION 0 xyzw 0 POS float
+// SV_RENDERTARGETARRAYINDEX 0 x 1 RTINDEX uint
+// TEXCOORD 0 xyz 2 NONE float xyz
+//
+//
+// Output signature:
+//
+// Name Index Mask Register SysValue Format Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET 0 xyzw 0 TARGET uint xyzw
+//
+ps_4_0
+dcl_constantbuffer CB0[1], immediateIndexed
+dcl_resource_texture3d (uint,uint,uint,uint) t0
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 1
+dcl_indexableTemp x0[6], 4
+resinfo_uint r0.xyzw, l(0), t0.xyzw
+utof r0.xyz, r0.xyzx
+mul r0.xyz, r0.xyzx, v2.xyzx
+ftoi r0.xyz, r0.xyzx
+mov r0.w, l(0)
+ld r0.xyzw, r0.xyzw, t0.xyzw
+mov x0[0].x, r0.x
+mov x0[1].x, r0.y
+mov x0[2].x, r0.z
+mov x0[3].x, r0.w
+mov x0[4].x, l(0)
+mov x0[5].x, l(1)
+mov r0.x, cb0[0].x
+mov o0.x, x0[r0.x + 0].x
+mov r0.x, cb0[0].y
+mov o0.y, x0[r0.x + 0].x
+mov r0.x, cb0[0].z
+mov o0.z, x0[r0.x + 0].x
+mov r0.x, cb0[0].w
+mov o0.w, x0[r0.x + 0].x
+ret
+// Approximately 21 instruction slots used
+#endif
+
+const BYTE g_PS_SwizzleUI3D[] = {
+ 68, 88, 66, 67, 234, 128, 119, 252, 97, 217, 113, 192, 202, 15, 92, 121, 106, 82, 46,
+ 102, 1, 0, 0, 0, 188, 4, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 48, 1,
+ 0, 0, 184, 1, 0, 0, 236, 1, 0, 0, 64, 4, 0, 0, 82, 68, 69, 70, 244,
+ 0, 0, 0, 1, 0, 0, 0, 124, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0,
+ 0, 4, 255, 255, 0, 1, 0, 0, 204, 0, 0, 0, 92, 0, 0, 0, 2, 0, 0,
+ 0, 4, 0, 0, 0, 8, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0,
+ 0, 0, 13, 0, 0, 0, 104, 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, 1, 0, 0, 0,
+ 84, 101, 120, 116, 117, 114, 101, 85, 73, 51, 68, 0, 83, 119, 105, 122, 122, 108, 101,
+ 80, 114, 111, 112, 101, 114, 116, 105, 101, 115, 0, 171, 171, 104, 0, 0, 0, 1, 0,
+ 0, 0, 148, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172,
+ 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 188, 0, 0, 0,
+ 0, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 73, 110, 100, 105, 99, 101, 115, 0,
+ 171, 1, 0, 19, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 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, 49, 48, 46, 49, 0,
+ 73, 83, 71, 78, 128, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0,
+ 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 1,
+ 0, 0, 0, 1, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 3, 0, 0, 0, 2, 0, 0, 0, 7, 7, 0, 0, 83, 86, 95, 80, 79, 83, 73,
+ 84, 73, 79, 78, 0, 83, 86, 95, 82, 69, 78, 68, 69, 82, 84, 65, 82, 71, 69,
+ 84, 65, 82, 82, 65, 89, 73, 78, 68, 69, 88, 0, 84, 69, 88, 67, 79, 79, 82,
+ 68, 0, 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, 1, 0, 0, 0, 0, 0, 0,
+ 0, 15, 0, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 171, 171, 83, 72,
+ 68, 82, 76, 2, 0, 0, 64, 0, 0, 0, 147, 0, 0, 0, 89, 0, 0, 4, 70,
+ 142, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 88, 40, 0, 4, 0, 112, 16, 0,
+ 0, 0, 0, 0, 68, 68, 0, 0, 98, 16, 0, 3, 114, 16, 16, 0, 2, 0, 0,
+ 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0,
+ 0, 0, 105, 0, 0, 4, 0, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 61,
+ 16, 0, 7, 242, 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, 114, 0, 16, 0, 0, 0, 0,
+ 0, 70, 2, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 114, 0, 16, 0, 0, 0,
+ 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, 0, 0, 27,
+ 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0,
+ 54, 0, 0, 5, 130, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0,
+ 0, 45, 0, 0, 7, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0,
+ 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6,
+ 18, 48, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0,
+ 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 42, 0,
+ 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0, 0, 0, 0, 0, 3,
+ 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 48, 32, 0,
+ 0, 0, 0, 0, 4, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 54, 0, 0,
+ 6, 18, 48, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 1, 64, 0, 0, 1, 0,
+ 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 10, 128, 32, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 18, 32, 16, 0, 0, 0, 0, 0,
+ 10, 48, 32, 4, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0,
+ 6, 18, 0, 16, 0, 0, 0, 0, 0, 26, 128, 32, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 54, 0, 0, 7, 34, 32, 16, 0, 0, 0, 0, 0, 10, 48, 32, 4, 0,
+ 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0,
+ 0, 0, 0, 0, 42, 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0,
+ 7, 66, 32, 16, 0, 0, 0, 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, 10, 0,
+ 16, 0, 0, 0, 0, 0, 54, 0, 0, 6, 18, 0, 16, 0, 0, 0, 0, 0, 58,
+ 128, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 7, 130, 32, 16, 0,
+ 0, 0, 0, 0, 10, 48, 32, 4, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0,
+ 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 21, 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, 6, 0, 0, 0,
+ 10, 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, 5, 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/texture_format_table.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/texture_format_table.cpp
new file mode 100644
index 0000000000..a9dfec56b8
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/texture_format_table.cpp
@@ -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.
+//
+// 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
+{
+
+const Format &Format::getSwizzleFormat(const Renderer11DeviceCaps &deviceCaps) const
+{
+ return (swizzleFormat == internalFormat ? *this : Format::Get(swizzleFormat, deviceCaps));
+}
+
+LoadFunctionMap Format::getLoadFunctions() const
+{
+ return GetLoadFunctionsMap(internalFormat, formatID);
+}
+
+const angle::Format &Format::format() const
+{
+ return angle::Format::Get(formatID);
+}
+
+} // namespace d3d11
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/texture_format_table.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/texture_format_table.h
new file mode 100644
index 0000000000..1797476f62
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/texture_format_table.h
@@ -0,0 +1,118 @@
+//
+// 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.
+//
+// texture_format_table:
+// Queries for full textureFormat information based on internalFormat
+//
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_TEXTUREFORMATTABLE_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_TEXTUREFORMATTABLE_H_
+
+#include <map>
+
+#include "common/angleutils.h"
+#include "common/platform.h"
+#include "libANGLE/renderer/Format.h"
+#include "libANGLE/renderer/d3d/formatutilsD3D.h"
+#include "libANGLE/renderer/renderer_utils.h"
+
+namespace rx
+{
+
+struct Renderer11DeviceCaps;
+
+namespace d3d11
+{
+
+// 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 : private angle::NonCopyable
+{
+ inline constexpr Format();
+ inline constexpr Format(GLenum internalFormat,
+ angle::FormatID formatID,
+ DXGI_FORMAT texFormat,
+ DXGI_FORMAT srvFormat,
+ DXGI_FORMAT uavFormat,
+ DXGI_FORMAT rtvFormat,
+ DXGI_FORMAT dsvFormat,
+ DXGI_FORMAT blitSRVFormat,
+ DXGI_FORMAT stencilSRVFormat,
+ DXGI_FORMAT typelessFormat,
+ GLenum swizzleFormat,
+ InitializeTextureDataFunction internalFormatInitializer);
+
+ static const Format &Get(GLenum internalFormat, const Renderer11DeviceCaps &deviceCaps);
+
+ const Format &getSwizzleFormat(const Renderer11DeviceCaps &deviceCaps) const;
+ LoadFunctionMap getLoadFunctions() const;
+ const angle::Format &format() const;
+
+ GLenum internalFormat;
+ angle::FormatID formatID;
+
+ DXGI_FORMAT texFormat;
+ DXGI_FORMAT srvFormat;
+ DXGI_FORMAT uavFormat;
+ DXGI_FORMAT rtvFormat;
+ DXGI_FORMAT dsvFormat;
+
+ DXGI_FORMAT blitSRVFormat;
+ DXGI_FORMAT stencilSRVFormat;
+ DXGI_FORMAT typelessFormat;
+
+ GLenum swizzleFormat;
+
+ InitializeTextureDataFunction dataInitializerFunction;
+};
+
+constexpr Format::Format()
+ : internalFormat(GL_NONE),
+ formatID(angle::FormatID::NONE),
+ texFormat(DXGI_FORMAT_UNKNOWN),
+ srvFormat(DXGI_FORMAT_UNKNOWN),
+ uavFormat(DXGI_FORMAT_UNKNOWN),
+ rtvFormat(DXGI_FORMAT_UNKNOWN),
+ dsvFormat(DXGI_FORMAT_UNKNOWN),
+ blitSRVFormat(DXGI_FORMAT_UNKNOWN),
+ stencilSRVFormat(DXGI_FORMAT_UNKNOWN),
+ typelessFormat(DXGI_FORMAT_UNKNOWN),
+ swizzleFormat(GL_NONE),
+ dataInitializerFunction(nullptr)
+{}
+
+constexpr Format::Format(GLenum internalFormat,
+ angle::FormatID formatID,
+ DXGI_FORMAT texFormat,
+ DXGI_FORMAT srvFormat,
+ DXGI_FORMAT uavFormat,
+ DXGI_FORMAT rtvFormat,
+ DXGI_FORMAT dsvFormat,
+ DXGI_FORMAT blitSRVFormat,
+ DXGI_FORMAT stencilSRVFormat,
+ DXGI_FORMAT typelessFormat,
+ GLenum swizzleFormat,
+ InitializeTextureDataFunction internalFormatInitializer)
+ : internalFormat(internalFormat),
+ formatID(formatID),
+ texFormat(texFormat),
+ srvFormat(srvFormat),
+ uavFormat(uavFormat),
+ rtvFormat(rtvFormat),
+ dsvFormat(dsvFormat),
+ blitSRVFormat(blitSRVFormat),
+ stencilSRVFormat(stencilSRVFormat),
+ typelessFormat(typelessFormat),
+ swizzleFormat(swizzleFormat),
+ dataInitializerFunction(internalFormatInitializer)
+{}
+
+} // namespace d3d11
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D11_TEXTUREFORMATTABLE_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp
new file mode 100644
index 0000000000..39d03a93fd
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/texture_format_table_autogen.cpp
@@ -0,0 +1,3269 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_texture_format_table.py using data from texture_format_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.
+//
+// texture_format_table:
+// Queries for full textureFormat information based in internalFormat
+//
+
+#include "libANGLE/renderer/d3d/d3d11/texture_format_table.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/renderer11_utils.h"
+#include "libANGLE/renderer/d3d/d3d11/texture_format_table_utils.h"
+
+using namespace angle;
+
+namespace rx
+{
+
+namespace d3d11
+{
+
+// static
+const Format &Format::Get(GLenum internalFormat, const Renderer11DeviceCaps &deviceCaps)
+{
+ // clang-format off
+ switch (internalFormat)
+ {
+ case GL_ALPHA16F_EXT:
+ {
+ static constexpr Format info(GL_ALPHA16F_EXT,
+ angle::FormatID::R16G16B16A16_FLOAT,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16B16A16_TYPELESS,
+ GL_RGBA16F,
+ nullptr);
+ return info;
+ }
+ case GL_ALPHA32F_EXT:
+ {
+ static constexpr Format info(GL_ALPHA32F_EXT,
+ angle::FormatID::R32G32B32A32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R32G32B32A32_TYPELESS,
+ GL_RGBA32F,
+ nullptr);
+ return info;
+ }
+ case GL_ALPHA8_EXT:
+ {
+ if (OnlyFL10Plus(deviceCaps))
+ {
+ static constexpr Format info(GL_ALPHA8_EXT,
+ angle::FormatID::A8_UNORM,
+ DXGI_FORMAT_A8_UNORM,
+ DXGI_FORMAT_A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_RGBA8,
+ nullptr);
+ return info;
+ }
+ else
+ {
+ static constexpr Format info(GL_ALPHA8_EXT,
+ angle::FormatID::R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_TYPELESS,
+ GL_RGBA8,
+ nullptr);
+ return info;
+ }
+ }
+ case GL_BGR10_A2_ANGLEX:
+ {
+ static constexpr Format info(GL_BGR10_A2_ANGLEX,
+ angle::FormatID::B10G10R10A2_UNORM,
+ DXGI_FORMAT_R10G10B10A2_UNORM,
+ DXGI_FORMAT_R10G10B10A2_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R10G10B10A2_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R10G10B10A2_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R10G10B10A2_TYPELESS,
+ GL_RGBA16_EXT,
+ nullptr);
+ return info;
+ }
+ case GL_BGR565_ANGLEX:
+ {
+ if (SupportsFormat(DXGI_FORMAT_B5G6R5_UNORM, deviceCaps))
+ {
+ static constexpr Format info(GL_BGR565_ANGLEX,
+ angle::FormatID::B5G6R5_UNORM,
+ DXGI_FORMAT_B5G6R5_UNORM,
+ DXGI_FORMAT_B5G6R5_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_B5G6R5_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_B5G6R5_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_RGBA8,
+ nullptr);
+ return info;
+ }
+ else
+ {
+ static constexpr Format info(GL_BGR565_ANGLEX,
+ angle::FormatID::R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_TYPELESS,
+ GL_RGBA8,
+ nullptr);
+ return info;
+ }
+ }
+ case GL_BGR5_A1_ANGLEX:
+ {
+ static constexpr Format info(GL_BGR5_A1_ANGLEX,
+ angle::FormatID::B8G8R8A8_UNORM,
+ DXGI_FORMAT_B8G8R8A8_UNORM,
+ DXGI_FORMAT_B8G8R8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_B8G8R8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_B8G8R8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_B8G8R8A8_TYPELESS,
+ GL_BGRA8_EXT,
+ nullptr);
+ return info;
+ }
+ case GL_BGRA4_ANGLEX:
+ {
+ static constexpr Format info(GL_BGRA4_ANGLEX,
+ angle::FormatID::B8G8R8A8_UNORM,
+ DXGI_FORMAT_B8G8R8A8_UNORM,
+ DXGI_FORMAT_B8G8R8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_B8G8R8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_B8G8R8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_B8G8R8A8_TYPELESS,
+ GL_BGRA8_EXT,
+ nullptr);
+ return info;
+ }
+ case GL_BGRA8_EXT:
+ {
+ static constexpr Format info(GL_BGRA8_EXT,
+ angle::FormatID::B8G8R8A8_UNORM,
+ DXGI_FORMAT_B8G8R8A8_UNORM,
+ DXGI_FORMAT_B8G8R8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_B8G8R8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_B8G8R8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_B8G8R8A8_TYPELESS,
+ GL_BGRA8_EXT,
+ nullptr);
+ return info;
+ }
+ case GL_BGRA8_SRGB_ANGLEX:
+ {
+ static constexpr Format info(GL_BGRA8_SRGB_ANGLEX,
+ angle::FormatID::B8G8R8A8_UNORM_SRGB,
+ DXGI_FORMAT_B8G8R8A8_UNORM_SRGB,
+ DXGI_FORMAT_B8G8R8A8_UNORM_SRGB,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_B8G8R8A8_UNORM_SRGB,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_B8G8R8A8_UNORM_SRGB,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_B8G8R8A8_TYPELESS,
+ GL_BGRA8_SRGB_ANGLEX,
+ nullptr);
+ return info;
+ }
+ case GL_BGRX8_ANGLEX:
+ {
+ if (OnlyFL11_1Plus(deviceCaps))
+ {
+ static constexpr Format info(GL_BGRX8_ANGLEX,
+ angle::FormatID::B8G8R8X8_UNORM,
+ DXGI_FORMAT_B8G8R8X8_UNORM,
+ DXGI_FORMAT_B8G8R8X8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_B8G8R8X8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_B8G8R8X8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_B8G8R8X8_TYPELESS,
+ GL_BGRX8_ANGLEX,
+ nullptr);
+ return info;
+ }
+ else
+ {
+ static constexpr Format info(GL_BGRX8_ANGLEX,
+ angle::FormatID::R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_TYPELESS,
+ GL_RGBA8,
+ nullptr);
+ return info;
+ }
+ }
+ case GL_COMPRESSED_R11_EAC:
+ {
+ static constexpr Format info(GL_COMPRESSED_R11_EAC,
+ angle::FormatID::R16_UNORM,
+ DXGI_FORMAT_R16_UNORM,
+ DXGI_FORMAT_R16_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16_TYPELESS,
+ GL_RGBA16_EXT,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
+ {
+ static constexpr Format info(GL_COMPRESSED_RED_GREEN_RGTC2_EXT,
+ angle::FormatID::BC5_RG_UNORM_BLOCK,
+ DXGI_FORMAT_BC5_UNORM,
+ DXGI_FORMAT_BC5_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_BC5_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_RGBA8,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_RED_RGTC1_EXT:
+ {
+ static constexpr Format info(GL_COMPRESSED_RED_RGTC1_EXT,
+ angle::FormatID::BC4_RED_UNORM_BLOCK,
+ DXGI_FORMAT_BC4_UNORM,
+ DXGI_FORMAT_BC4_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_BC4_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_RGBA8,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_RG11_EAC:
+ {
+ static constexpr Format info(GL_COMPRESSED_RG11_EAC,
+ angle::FormatID::R16G16_UNORM,
+ DXGI_FORMAT_R16G16_UNORM,
+ DXGI_FORMAT_R16G16_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16_TYPELESS,
+ GL_RGBA16_EXT,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_RGB8_ETC2:
+ {
+ static constexpr Format info(GL_COMPRESSED_RGB8_ETC2,
+ angle::FormatID::R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_TYPELESS,
+ GL_RGBA8,
+ Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>);
+ return info;
+ }
+ case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
+ {
+ static constexpr Format info(GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE,
+ angle::FormatID::BC1_RGB_UNORM_BLOCK,
+ DXGI_FORMAT_BC1_UNORM,
+ DXGI_FORMAT_BC1_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_BC1_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_RGBA8,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+ {
+ static constexpr Format info(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,
+ angle::FormatID::R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_TYPELESS,
+ GL_RGBA8,
+ Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>);
+ return info;
+ }
+ case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
+ {
+ static constexpr Format info(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE,
+ angle::FormatID::BC1_RGBA_UNORM_BLOCK,
+ DXGI_FORMAT_BC1_UNORM,
+ DXGI_FORMAT_BC1_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_BC1_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_RGBA8,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_RGBA8_ETC2_EAC:
+ {
+ static constexpr Format info(GL_COMPRESSED_RGBA8_ETC2_EAC,
+ angle::FormatID::R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_TYPELESS,
+ GL_RGBA8,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
+ {
+ static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_10x10_KHR,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
+ {
+ static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_10x5_KHR,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
+ {
+ static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_10x6_KHR,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
+ {
+ static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_10x8_KHR,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
+ {
+ static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_12x10_KHR,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
+ {
+ static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_12x12_KHR,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_RGBA_ASTC_3x3x3_OES:
+ {
+ static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_3x3x3_OES,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_RGBA_ASTC_4x3x3_OES:
+ {
+ static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_4x3x3_OES,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
+ {
+ static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_4x4_KHR,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_RGBA_ASTC_4x4x3_OES:
+ {
+ static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_4x4x3_OES,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_RGBA_ASTC_4x4x4_OES:
+ {
+ static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_4x4x4_OES,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
+ {
+ static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_5x4_KHR,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_RGBA_ASTC_5x4x4_OES:
+ {
+ static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_5x4x4_OES,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
+ {
+ static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_5x5_KHR,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_RGBA_ASTC_5x5x4_OES:
+ {
+ static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_5x5x4_OES,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_RGBA_ASTC_5x5x5_OES:
+ {
+ static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_5x5x5_OES,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
+ {
+ static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_6x5_KHR,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_RGBA_ASTC_6x5x5_OES:
+ {
+ static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_6x5x5_OES,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
+ {
+ static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_6x6_KHR,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_RGBA_ASTC_6x6x5_OES:
+ {
+ static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_6x6x5_OES,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_RGBA_ASTC_6x6x6_OES:
+ {
+ static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_6x6x6_OES,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
+ {
+ static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_8x5_KHR,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
+ {
+ static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_8x6_KHR,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
+ {
+ static constexpr Format info(GL_COMPRESSED_RGBA_ASTC_8x8_KHR,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
+ {
+ static constexpr Format info(GL_COMPRESSED_RGBA_BPTC_UNORM_EXT,
+ angle::FormatID::BC7_RGBA_UNORM_BLOCK,
+ DXGI_FORMAT_BC7_UNORM,
+ DXGI_FORMAT_BC7_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_BC7_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_RGBA8,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
+ {
+ static constexpr Format info(GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
+ {
+ static constexpr Format info(GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ {
+ static constexpr Format info(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
+ angle::FormatID::BC1_RGBA_UNORM_BLOCK,
+ DXGI_FORMAT_BC1_UNORM,
+ DXGI_FORMAT_BC1_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_BC1_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_RGBA8,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
+ {
+ static constexpr Format info(GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE,
+ angle::FormatID::BC2_RGBA_UNORM_BLOCK,
+ DXGI_FORMAT_BC2_UNORM,
+ DXGI_FORMAT_BC2_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_BC2_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_RGBA8,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
+ {
+ static constexpr Format info(GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE,
+ angle::FormatID::BC3_RGBA_UNORM_BLOCK,
+ DXGI_FORMAT_BC3_UNORM,
+ DXGI_FORMAT_BC3_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_BC3_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_RGBA8,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
+ {
+ static constexpr Format info(GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT,
+ angle::FormatID::BC6H_RGB_SFLOAT_BLOCK,
+ DXGI_FORMAT_BC6H_SF16,
+ DXGI_FORMAT_BC6H_SF16,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_BC6H_SF16,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_RGBA32F,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
+ {
+ static constexpr Format info(GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT,
+ angle::FormatID::BC6H_RGB_UFLOAT_BLOCK,
+ DXGI_FORMAT_BC6H_UF16,
+ DXGI_FORMAT_BC6H_UF16,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_BC6H_UF16,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_RGBA32F,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
+ {
+ static constexpr Format info(GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
+ {
+ static constexpr Format info(GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ {
+ static constexpr Format info(GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
+ angle::FormatID::BC1_RGB_UNORM_BLOCK,
+ DXGI_FORMAT_BC1_UNORM,
+ DXGI_FORMAT_BC1_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_BC1_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_RGBA8,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_SIGNED_R11_EAC:
+ {
+ static constexpr Format info(GL_COMPRESSED_SIGNED_R11_EAC,
+ angle::FormatID::R16_SNORM,
+ DXGI_FORMAT_R16_SNORM,
+ DXGI_FORMAT_R16_SNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16_SNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16_TYPELESS,
+ GL_RGBA16_SNORM_EXT,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:
+ {
+ static constexpr Format info(GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT,
+ angle::FormatID::BC5_RG_SNORM_BLOCK,
+ DXGI_FORMAT_BC5_SNORM,
+ DXGI_FORMAT_BC5_SNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_BC5_SNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_RGBA8_SNORM,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:
+ {
+ static constexpr Format info(GL_COMPRESSED_SIGNED_RED_RGTC1_EXT,
+ angle::FormatID::BC4_RED_SNORM_BLOCK,
+ DXGI_FORMAT_BC4_SNORM,
+ DXGI_FORMAT_BC4_SNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_BC4_SNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_RGBA8_SNORM,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_SIGNED_RG11_EAC:
+ {
+ static constexpr Format info(GL_COMPRESSED_SIGNED_RG11_EAC,
+ angle::FormatID::R16G16_SNORM,
+ DXGI_FORMAT_R16G16_SNORM,
+ DXGI_FORMAT_R16G16_SNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16_SNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16_TYPELESS,
+ GL_RGBA16_SNORM_EXT,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
+ {
+ static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
+ {
+ static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
+ {
+ static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
+ {
+ static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
+ {
+ static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
+ {
+ static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES:
+ {
+ static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES:
+ {
+ static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
+ {
+ static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES:
+ {
+ static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES:
+ {
+ static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
+ {
+ static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES:
+ {
+ static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
+ {
+ static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES:
+ {
+ static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES:
+ {
+ static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
+ {
+ static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES:
+ {
+ static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
+ {
+ static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES:
+ {
+ static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES:
+ {
+ static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
+ {
+ static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
+ {
+ static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
+ {
+ static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
+ {
+ static constexpr Format info(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,
+ angle::FormatID::R8G8B8A8_UNORM_SRGB,
+ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_TYPELESS,
+ GL_SRGB8_ALPHA8,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_SRGB8_ETC2:
+ {
+ static constexpr Format info(GL_COMPRESSED_SRGB8_ETC2,
+ angle::FormatID::R8G8B8A8_UNORM_SRGB,
+ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_TYPELESS,
+ GL_SRGB8_ALPHA8,
+ Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>);
+ return info;
+ }
+ case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
+ {
+ static constexpr Format info(GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE,
+ angle::FormatID::BC1_RGB_UNORM_SRGB_BLOCK,
+ DXGI_FORMAT_BC1_UNORM_SRGB,
+ DXGI_FORMAT_BC1_UNORM_SRGB,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_BC1_UNORM_SRGB,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_RGBA8,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+ {
+ static constexpr Format info(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,
+ angle::FormatID::R8G8B8A8_UNORM_SRGB,
+ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_TYPELESS,
+ GL_SRGB8_ALPHA8,
+ Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>);
+ return info;
+ }
+ case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
+ {
+ static constexpr Format info(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE,
+ angle::FormatID::BC1_RGBA_UNORM_SRGB_BLOCK,
+ DXGI_FORMAT_BC1_UNORM_SRGB,
+ DXGI_FORMAT_BC1_UNORM_SRGB,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_BC1_UNORM_SRGB,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_RGBA8,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
+ {
+ static constexpr Format info(GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT,
+ angle::FormatID::BC7_RGBA_UNORM_SRGB_BLOCK,
+ DXGI_FORMAT_BC7_UNORM_SRGB,
+ DXGI_FORMAT_BC7_UNORM_SRGB,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_BC7_UNORM_SRGB,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_SRGB8_ALPHA8,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT:
+ {
+ static constexpr Format info(GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT:
+ {
+ static constexpr Format info(GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
+ {
+ static constexpr Format info(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT,
+ angle::FormatID::BC1_RGBA_UNORM_SRGB_BLOCK,
+ DXGI_FORMAT_BC1_UNORM_SRGB,
+ DXGI_FORMAT_BC1_UNORM_SRGB,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_BC1_UNORM_SRGB,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_RGBA8,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
+ {
+ static constexpr Format info(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT,
+ angle::FormatID::BC2_RGBA_UNORM_SRGB_BLOCK,
+ DXGI_FORMAT_BC2_UNORM_SRGB,
+ DXGI_FORMAT_BC2_UNORM_SRGB,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_BC2_UNORM_SRGB,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_RGBA8,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
+ {
+ static constexpr Format info(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT,
+ angle::FormatID::BC3_RGBA_UNORM_SRGB_BLOCK,
+ DXGI_FORMAT_BC3_UNORM_SRGB,
+ DXGI_FORMAT_BC3_UNORM_SRGB,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_BC3_UNORM_SRGB,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_RGBA8,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT:
+ {
+ static constexpr Format info(GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT:
+ {
+ static constexpr Format info(GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
+ {
+ static constexpr Format info(GL_COMPRESSED_SRGB_S3TC_DXT1_EXT,
+ angle::FormatID::BC1_RGB_UNORM_SRGB_BLOCK,
+ DXGI_FORMAT_BC1_UNORM_SRGB,
+ DXGI_FORMAT_BC1_UNORM_SRGB,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_BC1_UNORM_SRGB,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_RGBA8,
+ nullptr);
+ return info;
+ }
+ case GL_DEPTH24_STENCIL8:
+ {
+ if (OnlyFL10Plus(deviceCaps))
+ {
+ static constexpr Format info(GL_DEPTH24_STENCIL8,
+ angle::FormatID::D24_UNORM_S8_UINT,
+ DXGI_FORMAT_R24G8_TYPELESS,
+ DXGI_FORMAT_R24_UNORM_X8_TYPELESS,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_D24_UNORM_S8_UINT,
+ DXGI_FORMAT_R24_UNORM_X8_TYPELESS,
+ DXGI_FORMAT_X24_TYPELESS_G8_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ GL_RGBA32F,
+ nullptr);
+ return info;
+ }
+ else
+ {
+ static constexpr Format info(GL_DEPTH24_STENCIL8,
+ angle::FormatID::D24_UNORM_S8_UINT,
+ DXGI_FORMAT_D24_UNORM_S8_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_D24_UNORM_S8_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_RGBA32F,
+ nullptr);
+ return info;
+ }
+ }
+ case GL_DEPTH32F_STENCIL8:
+ {
+ static constexpr Format info(GL_DEPTH32F_STENCIL8,
+ angle::FormatID::D32_FLOAT_S8X24_UINT,
+ DXGI_FORMAT_R32G8X24_TYPELESS,
+ DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_D32_FLOAT_S8X24_UINT,
+ DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS,
+ DXGI_FORMAT_X32_TYPELESS_G8X24_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ GL_RGBA32F,
+ nullptr);
+ return info;
+ }
+ case GL_DEPTH_COMPONENT16:
+ {
+ if (OnlyFL10Plus(deviceCaps))
+ {
+ static constexpr Format info(GL_DEPTH_COMPONENT16,
+ angle::FormatID::D16_UNORM,
+ DXGI_FORMAT_R16_TYPELESS,
+ DXGI_FORMAT_R16_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_D16_UNORM,
+ DXGI_FORMAT_R16_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_RGBA16_EXT,
+ nullptr);
+ return info;
+ }
+ else
+ {
+ static constexpr Format info(GL_DEPTH_COMPONENT16,
+ angle::FormatID::D16_UNORM,
+ DXGI_FORMAT_D16_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_D16_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_RGBA16_EXT,
+ nullptr);
+ return info;
+ }
+ }
+ case GL_DEPTH_COMPONENT24:
+ {
+ if (OnlyFL10Plus(deviceCaps))
+ {
+ static constexpr Format info(GL_DEPTH_COMPONENT24,
+ angle::FormatID::D24_UNORM_S8_UINT,
+ DXGI_FORMAT_R24G8_TYPELESS,
+ DXGI_FORMAT_R24_UNORM_X8_TYPELESS,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_D24_UNORM_S8_UINT,
+ DXGI_FORMAT_R24_UNORM_X8_TYPELESS,
+ DXGI_FORMAT_X24_TYPELESS_G8_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ GL_RGBA32F,
+ nullptr);
+ return info;
+ }
+ else
+ {
+ static constexpr Format info(GL_DEPTH_COMPONENT24,
+ angle::FormatID::D24_UNORM_S8_UINT,
+ DXGI_FORMAT_D24_UNORM_S8_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_D24_UNORM_S8_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_RGBA32F,
+ nullptr);
+ return info;
+ }
+ }
+ case GL_DEPTH_COMPONENT32F:
+ {
+ static constexpr Format info(GL_DEPTH_COMPONENT32F,
+ angle::FormatID::D32_FLOAT,
+ DXGI_FORMAT_R32_TYPELESS,
+ DXGI_FORMAT_R32_FLOAT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_D32_FLOAT,
+ DXGI_FORMAT_R32_FLOAT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_RGBA32F,
+ nullptr);
+ return info;
+ }
+ case GL_DEPTH_COMPONENT32_OES:
+ {
+ if (OnlyFL10Plus(deviceCaps))
+ {
+ static constexpr Format info(GL_DEPTH_COMPONENT32_OES,
+ angle::FormatID::D24_UNORM_S8_UINT,
+ DXGI_FORMAT_R24G8_TYPELESS,
+ DXGI_FORMAT_R24_UNORM_X8_TYPELESS,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_D24_UNORM_S8_UINT,
+ DXGI_FORMAT_R24_UNORM_X8_TYPELESS,
+ DXGI_FORMAT_X24_TYPELESS_G8_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ GL_RGBA32F,
+ nullptr);
+ return info;
+ }
+ else
+ {
+ static constexpr Format info(GL_DEPTH_COMPONENT32_OES,
+ angle::FormatID::D24_UNORM_S8_UINT,
+ DXGI_FORMAT_D24_UNORM_S8_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_D24_UNORM_S8_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_RGBA32F,
+ nullptr);
+ return info;
+ }
+ }
+ case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
+ {
+ static constexpr Format info(GL_ETC1_RGB8_LOSSY_DECODE_ANGLE,
+ angle::FormatID::BC1_RGB_UNORM_BLOCK,
+ DXGI_FORMAT_BC1_UNORM,
+ DXGI_FORMAT_BC1_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_BC1_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_RGBA8,
+ nullptr);
+ return info;
+ }
+ case GL_ETC1_RGB8_OES:
+ {
+ static constexpr Format info(GL_ETC1_RGB8_OES,
+ angle::FormatID::R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_TYPELESS,
+ GL_RGBA8,
+ Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>);
+ return info;
+ }
+ case GL_G8_B8R8_2PLANE_420_UNORM_ANGLE:
+ {
+ static constexpr Format info(GL_G8_B8R8_2PLANE_420_UNORM_ANGLE,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE:
+ {
+ static constexpr Format info(GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_LUMINANCE16F_EXT:
+ {
+ static constexpr Format info(GL_LUMINANCE16F_EXT,
+ angle::FormatID::R16G16B16A16_FLOAT,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16B16A16_TYPELESS,
+ GL_RGBA16F,
+ Initialize4ComponentData<GLhalf, 0x0000, 0x0000, 0x0000, gl::Float16One>);
+ return info;
+ }
+ case GL_LUMINANCE32F_EXT:
+ {
+ static constexpr Format info(GL_LUMINANCE32F_EXT,
+ angle::FormatID::R32G32B32A32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R32G32B32A32_TYPELESS,
+ GL_RGBA32F,
+ Initialize4ComponentData<GLfloat, 0x00000000, 0x00000000, 0x00000000, gl::Float32One>);
+ return info;
+ }
+ case GL_LUMINANCE8_ALPHA8_EXT:
+ {
+ static constexpr Format info(GL_LUMINANCE8_ALPHA8_EXT,
+ angle::FormatID::R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_TYPELESS,
+ GL_RGBA8,
+ nullptr);
+ return info;
+ }
+ case GL_LUMINANCE8_EXT:
+ {
+ static constexpr Format info(GL_LUMINANCE8_EXT,
+ angle::FormatID::R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_TYPELESS,
+ GL_RGBA8,
+ Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>);
+ return info;
+ }
+ case GL_LUMINANCE_ALPHA16F_EXT:
+ {
+ static constexpr Format info(GL_LUMINANCE_ALPHA16F_EXT,
+ angle::FormatID::R16G16B16A16_FLOAT,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16B16A16_TYPELESS,
+ GL_RGBA16F,
+ nullptr);
+ return info;
+ }
+ case GL_LUMINANCE_ALPHA32F_EXT:
+ {
+ static constexpr Format info(GL_LUMINANCE_ALPHA32F_EXT,
+ angle::FormatID::R32G32B32A32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R32G32B32A32_TYPELESS,
+ GL_RGBA32F,
+ nullptr);
+ return info;
+ }
+ case GL_NONE:
+ {
+ static constexpr Format info(GL_NONE,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_PALETTE4_R5_G6_B5_OES:
+ {
+ static constexpr Format info(GL_PALETTE4_R5_G6_B5_OES,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_PALETTE4_RGB5_A1_OES:
+ {
+ static constexpr Format info(GL_PALETTE4_RGB5_A1_OES,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_PALETTE4_RGB8_OES:
+ {
+ static constexpr Format info(GL_PALETTE4_RGB8_OES,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_PALETTE4_RGBA4_OES:
+ {
+ static constexpr Format info(GL_PALETTE4_RGBA4_OES,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_PALETTE4_RGBA8_OES:
+ {
+ static constexpr Format info(GL_PALETTE4_RGBA8_OES,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_PALETTE8_R5_G6_B5_OES:
+ {
+ static constexpr Format info(GL_PALETTE8_R5_G6_B5_OES,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_PALETTE8_RGB5_A1_OES:
+ {
+ static constexpr Format info(GL_PALETTE8_RGB5_A1_OES,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_PALETTE8_RGB8_OES:
+ {
+ static constexpr Format info(GL_PALETTE8_RGB8_OES,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_PALETTE8_RGBA4_OES:
+ {
+ static constexpr Format info(GL_PALETTE8_RGBA4_OES,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_PALETTE8_RGBA8_OES:
+ {
+ static constexpr Format info(GL_PALETTE8_RGBA8_OES,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_R11F_G11F_B10F:
+ {
+ static constexpr Format info(GL_R11F_G11F_B10F,
+ angle::FormatID::R11G11B10_FLOAT,
+ DXGI_FORMAT_R11G11B10_FLOAT,
+ DXGI_FORMAT_R11G11B10_FLOAT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R11G11B10_FLOAT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R11G11B10_FLOAT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_RGBA16F_EXT,
+ nullptr);
+ return info;
+ }
+ case GL_R16F:
+ {
+ static constexpr Format info(GL_R16F,
+ angle::FormatID::R16_FLOAT,
+ DXGI_FORMAT_R16_FLOAT,
+ DXGI_FORMAT_R16_FLOAT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16_FLOAT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16_FLOAT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16_TYPELESS,
+ GL_RGBA16F_EXT,
+ nullptr);
+ return info;
+ }
+ case GL_R16I:
+ {
+ static constexpr Format info(GL_R16I,
+ angle::FormatID::R16_SINT,
+ DXGI_FORMAT_R16_SINT,
+ DXGI_FORMAT_R16_SINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16_SINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16_SINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16_TYPELESS,
+ GL_RGBA16I,
+ nullptr);
+ return info;
+ }
+ case GL_R16UI:
+ {
+ static constexpr Format info(GL_R16UI,
+ angle::FormatID::R16_UINT,
+ DXGI_FORMAT_R16_UINT,
+ DXGI_FORMAT_R16_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16_TYPELESS,
+ GL_RGBA16I,
+ nullptr);
+ return info;
+ }
+ case GL_R16_EXT:
+ {
+ static constexpr Format info(GL_R16_EXT,
+ angle::FormatID::R16_UNORM,
+ DXGI_FORMAT_R16_UNORM,
+ DXGI_FORMAT_R16_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16_TYPELESS,
+ GL_RGBA16_EXT,
+ nullptr);
+ return info;
+ }
+ case GL_R16_SNORM_EXT:
+ {
+ static constexpr Format info(GL_R16_SNORM_EXT,
+ angle::FormatID::R16_SNORM,
+ DXGI_FORMAT_R16_SNORM,
+ DXGI_FORMAT_R16_SNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16_SNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16_TYPELESS,
+ GL_RGBA16_SNORM_EXT,
+ nullptr);
+ return info;
+ }
+ case GL_R32F:
+ {
+ static constexpr Format info(GL_R32F,
+ angle::FormatID::R32_FLOAT,
+ DXGI_FORMAT_R32_FLOAT,
+ DXGI_FORMAT_R32_FLOAT,
+ DXGI_FORMAT_R32_FLOAT,
+ DXGI_FORMAT_R32_FLOAT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R32_FLOAT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R32_TYPELESS,
+ GL_RGBA32F,
+ nullptr);
+ return info;
+ }
+ case GL_R32I:
+ {
+ static constexpr Format info(GL_R32I,
+ angle::FormatID::R32_SINT,
+ DXGI_FORMAT_R32_SINT,
+ DXGI_FORMAT_R32_SINT,
+ DXGI_FORMAT_R32_SINT,
+ DXGI_FORMAT_R32_SINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R32_SINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R32_TYPELESS,
+ GL_RGBA32I,
+ nullptr);
+ return info;
+ }
+ case GL_R32UI:
+ {
+ static constexpr Format info(GL_R32UI,
+ angle::FormatID::R32_UINT,
+ DXGI_FORMAT_R32_UINT,
+ DXGI_FORMAT_R32_UINT,
+ DXGI_FORMAT_R32_UINT,
+ DXGI_FORMAT_R32_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R32_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R32_TYPELESS,
+ GL_RGBA32I,
+ nullptr);
+ return info;
+ }
+ case GL_R8:
+ {
+ static constexpr Format info(GL_R8,
+ angle::FormatID::R8_UNORM,
+ DXGI_FORMAT_R8_UNORM,
+ DXGI_FORMAT_R8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8_TYPELESS,
+ GL_RGBA8,
+ nullptr);
+ return info;
+ }
+ case GL_R8I:
+ {
+ static constexpr Format info(GL_R8I,
+ angle::FormatID::R8_SINT,
+ DXGI_FORMAT_R8_SINT,
+ DXGI_FORMAT_R8_SINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8_SINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8_SINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8_TYPELESS,
+ GL_RGBA8I,
+ nullptr);
+ return info;
+ }
+ case GL_R8UI:
+ {
+ static constexpr Format info(GL_R8UI,
+ angle::FormatID::R8_UINT,
+ DXGI_FORMAT_R8_UINT,
+ DXGI_FORMAT_R8_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8_TYPELESS,
+ GL_RGBA8I,
+ nullptr);
+ return info;
+ }
+ case GL_R8_SNORM:
+ {
+ static constexpr Format info(GL_R8_SNORM,
+ angle::FormatID::R8_SNORM,
+ DXGI_FORMAT_R8_SNORM,
+ DXGI_FORMAT_R8_SNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8_SNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8_TYPELESS,
+ GL_RGBA8_SNORM,
+ nullptr);
+ return info;
+ }
+ case GL_RG16F:
+ {
+ static constexpr Format info(GL_RG16F,
+ angle::FormatID::R16G16_FLOAT,
+ DXGI_FORMAT_R16G16_FLOAT,
+ DXGI_FORMAT_R16G16_FLOAT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16_FLOAT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16_FLOAT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16_TYPELESS,
+ GL_RGBA16F_EXT,
+ nullptr);
+ return info;
+ }
+ case GL_RG16I:
+ {
+ static constexpr Format info(GL_RG16I,
+ angle::FormatID::R16G16_SINT,
+ DXGI_FORMAT_R16G16_SINT,
+ DXGI_FORMAT_R16G16_SINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16_SINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16_SINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16_TYPELESS,
+ GL_RGBA16I,
+ nullptr);
+ return info;
+ }
+ case GL_RG16UI:
+ {
+ static constexpr Format info(GL_RG16UI,
+ angle::FormatID::R16G16_UINT,
+ DXGI_FORMAT_R16G16_UINT,
+ DXGI_FORMAT_R16G16_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16_TYPELESS,
+ GL_RGBA16I,
+ nullptr);
+ return info;
+ }
+ case GL_RG16_EXT:
+ {
+ static constexpr Format info(GL_RG16_EXT,
+ angle::FormatID::R16G16_UNORM,
+ DXGI_FORMAT_R16G16_UNORM,
+ DXGI_FORMAT_R16G16_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16_TYPELESS,
+ GL_RGBA16_EXT,
+ nullptr);
+ return info;
+ }
+ case GL_RG16_SNORM_EXT:
+ {
+ static constexpr Format info(GL_RG16_SNORM_EXT,
+ angle::FormatID::R16G16_SNORM,
+ DXGI_FORMAT_R16G16_SNORM,
+ DXGI_FORMAT_R16G16_SNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16_SNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16_TYPELESS,
+ GL_RGBA16_SNORM_EXT,
+ nullptr);
+ return info;
+ }
+ case GL_RG32F:
+ {
+ static constexpr Format info(GL_RG32F,
+ angle::FormatID::R32G32_FLOAT,
+ DXGI_FORMAT_R32G32_FLOAT,
+ DXGI_FORMAT_R32G32_FLOAT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R32G32_FLOAT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R32G32_FLOAT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R32G32_TYPELESS,
+ GL_RGBA32F,
+ nullptr);
+ return info;
+ }
+ case GL_RG32I:
+ {
+ static constexpr Format info(GL_RG32I,
+ angle::FormatID::R32G32_SINT,
+ DXGI_FORMAT_R32G32_SINT,
+ DXGI_FORMAT_R32G32_SINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R32G32_SINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R32G32_SINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R32G32_TYPELESS,
+ GL_RGBA32I,
+ nullptr);
+ return info;
+ }
+ case GL_RG32UI:
+ {
+ static constexpr Format info(GL_RG32UI,
+ angle::FormatID::R32G32_UINT,
+ DXGI_FORMAT_R32G32_UINT,
+ DXGI_FORMAT_R32G32_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R32G32_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R32G32_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R32G32_TYPELESS,
+ GL_RGBA32I,
+ nullptr);
+ return info;
+ }
+ case GL_RG8:
+ {
+ static constexpr Format info(GL_RG8,
+ angle::FormatID::R8G8_UNORM,
+ DXGI_FORMAT_R8G8_UNORM,
+ DXGI_FORMAT_R8G8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8_TYPELESS,
+ GL_RGBA8,
+ nullptr);
+ return info;
+ }
+ case GL_RG8I:
+ {
+ static constexpr Format info(GL_RG8I,
+ angle::FormatID::R8G8_SINT,
+ DXGI_FORMAT_R8G8_SINT,
+ DXGI_FORMAT_R8G8_SINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8_SINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8_SINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8_TYPELESS,
+ GL_RGBA8I,
+ nullptr);
+ return info;
+ }
+ case GL_RG8UI:
+ {
+ static constexpr Format info(GL_RG8UI,
+ angle::FormatID::R8G8_UINT,
+ DXGI_FORMAT_R8G8_UINT,
+ DXGI_FORMAT_R8G8_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8_TYPELESS,
+ GL_RGBA8I,
+ nullptr);
+ return info;
+ }
+ case GL_RG8_SNORM:
+ {
+ static constexpr Format info(GL_RG8_SNORM,
+ angle::FormatID::R8G8_SNORM,
+ DXGI_FORMAT_R8G8_SNORM,
+ DXGI_FORMAT_R8G8_SNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8_SNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8_TYPELESS,
+ GL_RGBA8_SNORM,
+ nullptr);
+ return info;
+ }
+ case GL_RGB:
+ {
+ static constexpr Format info(GL_RGB,
+ angle::FormatID::R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_TYPELESS,
+ GL_RGBA8,
+ Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>);
+ return info;
+ }
+ case GL_RGB10_A2:
+ {
+ static constexpr Format info(GL_RGB10_A2,
+ angle::FormatID::R10G10B10A2_UNORM,
+ DXGI_FORMAT_R10G10B10A2_UNORM,
+ DXGI_FORMAT_R10G10B10A2_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R10G10B10A2_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R10G10B10A2_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R10G10B10A2_TYPELESS,
+ GL_RGBA16_EXT,
+ nullptr);
+ return info;
+ }
+ case GL_RGB10_A2UI:
+ {
+ static constexpr Format info(GL_RGB10_A2UI,
+ angle::FormatID::R10G10B10A2_UINT,
+ DXGI_FORMAT_R10G10B10A2_UINT,
+ DXGI_FORMAT_R10G10B10A2_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R10G10B10A2_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R10G10B10A2_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R10G10B10A2_TYPELESS,
+ GL_RGBA16I,
+ nullptr);
+ return info;
+ }
+ case GL_RGB10_UNORM_ANGLEX:
+ {
+ static constexpr Format info(GL_RGB10_UNORM_ANGLEX,
+ angle::FormatID::R10G10B10X2_UNORM,
+ DXGI_FORMAT_R10G10B10A2_UNORM,
+ DXGI_FORMAT_R10G10B10A2_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R10G10B10A2_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R10G10B10A2_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R10G10B10A2_TYPELESS,
+ GL_RGBA16_EXT,
+ nullptr);
+ return info;
+ }
+ case GL_RGB16F:
+ {
+ static constexpr Format info(GL_RGB16F,
+ angle::FormatID::R16G16B16A16_FLOAT,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16B16A16_TYPELESS,
+ GL_RGBA16F,
+ Initialize4ComponentData<GLhalf, 0x0000, 0x0000, 0x0000, gl::Float16One>);
+ return info;
+ }
+ case GL_RGB16I:
+ {
+ static constexpr Format info(GL_RGB16I,
+ angle::FormatID::R16G16B16A16_SINT,
+ DXGI_FORMAT_R16G16B16A16_SINT,
+ DXGI_FORMAT_R16G16B16A16_SINT,
+ DXGI_FORMAT_R16G16B16A16_SINT,
+ DXGI_FORMAT_R16G16B16A16_SINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16B16A16_SINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16B16A16_TYPELESS,
+ GL_RGBA16I,
+ Initialize4ComponentData<GLshort, 0x0000, 0x0000, 0x0000, 0x0001>);
+ return info;
+ }
+ case GL_RGB16UI:
+ {
+ static constexpr Format info(GL_RGB16UI,
+ angle::FormatID::R16G16B16A16_UINT,
+ DXGI_FORMAT_R16G16B16A16_UINT,
+ DXGI_FORMAT_R16G16B16A16_UINT,
+ DXGI_FORMAT_R16G16B16A16_UINT,
+ DXGI_FORMAT_R16G16B16A16_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16B16A16_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16B16A16_TYPELESS,
+ GL_RGBA16UI,
+ Initialize4ComponentData<GLushort, 0x0000, 0x0000, 0x0000, 0x0001>);
+ return info;
+ }
+ case GL_RGB16_EXT:
+ {
+ static constexpr Format info(GL_RGB16_EXT,
+ angle::FormatID::R16G16B16A16_UNORM,
+ DXGI_FORMAT_R16G16B16A16_UNORM,
+ DXGI_FORMAT_R16G16B16A16_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16B16A16_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16B16A16_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16B16A16_TYPELESS,
+ GL_RGBA16_EXT,
+ Initialize4ComponentData<GLubyte, 0x0000, 0x0000, 0x0000, 0xFFFF>);
+ return info;
+ }
+ case GL_RGB16_SNORM_EXT:
+ {
+ static constexpr Format info(GL_RGB16_SNORM_EXT,
+ angle::FormatID::R16G16B16A16_SNORM,
+ DXGI_FORMAT_R16G16B16A16_SNORM,
+ DXGI_FORMAT_R16G16B16A16_SNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16B16A16_SNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16B16A16_TYPELESS,
+ GL_RGBA16_SNORM_EXT,
+ Initialize4ComponentData<GLushort, 0x0000, 0x0000, 0x0000, 0x7FFF>);
+ return info;
+ }
+ case GL_RGB32F:
+ {
+ static constexpr Format info(GL_RGB32F,
+ angle::FormatID::R32G32B32A32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R32G32B32A32_TYPELESS,
+ GL_RGBA32F,
+ Initialize4ComponentData<GLfloat, 0x00000000, 0x00000000, 0x00000000, gl::Float32One>);
+ return info;
+ }
+ case GL_RGB32I:
+ {
+ static constexpr Format info(GL_RGB32I,
+ angle::FormatID::R32G32B32A32_SINT,
+ DXGI_FORMAT_R32G32B32A32_SINT,
+ DXGI_FORMAT_R32G32B32A32_SINT,
+ DXGI_FORMAT_R32G32B32A32_SINT,
+ DXGI_FORMAT_R32G32B32A32_SINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R32G32B32A32_SINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R32G32B32A32_TYPELESS,
+ GL_RGBA32I,
+ Initialize4ComponentData<GLint, 0x00000000, 0x00000000, 0x00000000, 0x00000001>);
+ return info;
+ }
+ case GL_RGB32UI:
+ {
+ static constexpr Format info(GL_RGB32UI,
+ angle::FormatID::R32G32B32A32_UINT,
+ DXGI_FORMAT_R32G32B32A32_UINT,
+ DXGI_FORMAT_R32G32B32A32_UINT,
+ DXGI_FORMAT_R32G32B32A32_UINT,
+ DXGI_FORMAT_R32G32B32A32_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R32G32B32A32_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R32G32B32A32_TYPELESS,
+ GL_RGBA32UI,
+ Initialize4ComponentData<GLuint, 0x00000000, 0x00000000, 0x00000000, 0x00000001>);
+ return info;
+ }
+ case GL_RGB565:
+ {
+ if (SupportsFormat(DXGI_FORMAT_B5G6R5_UNORM, deviceCaps))
+ {
+ static constexpr Format info(GL_RGB565,
+ angle::FormatID::B5G6R5_UNORM,
+ DXGI_FORMAT_B5G6R5_UNORM,
+ DXGI_FORMAT_B5G6R5_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_B5G6R5_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_B5G6R5_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_RGBA8,
+ nullptr);
+ return info;
+ }
+ else
+ {
+ static constexpr Format info(GL_RGB565,
+ angle::FormatID::R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_TYPELESS,
+ GL_RGBA8,
+ Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>);
+ return info;
+ }
+ }
+ case GL_RGB5_A1:
+ {
+ if (SupportsFormat(DXGI_FORMAT_B5G5R5A1_UNORM, deviceCaps))
+ {
+ static constexpr Format info(GL_RGB5_A1,
+ angle::FormatID::B5G5R5A1_UNORM,
+ DXGI_FORMAT_B5G5R5A1_UNORM,
+ DXGI_FORMAT_B5G5R5A1_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_B5G5R5A1_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_B5G5R5A1_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_RGBA8,
+ nullptr);
+ return info;
+ }
+ else
+ {
+ static constexpr Format info(GL_RGB5_A1,
+ angle::FormatID::R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_TYPELESS,
+ GL_RGBA8,
+ nullptr);
+ return info;
+ }
+ }
+ case GL_RGB8:
+ {
+ static constexpr Format info(GL_RGB8,
+ angle::FormatID::R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_TYPELESS,
+ GL_RGBA8,
+ Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>);
+ return info;
+ }
+ case GL_RGB8I:
+ {
+ static constexpr Format info(GL_RGB8I,
+ angle::FormatID::R8G8B8A8_SINT,
+ DXGI_FORMAT_R8G8B8A8_SINT,
+ DXGI_FORMAT_R8G8B8A8_SINT,
+ DXGI_FORMAT_R8G8B8A8_SINT,
+ DXGI_FORMAT_R8G8B8A8_SINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_SINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_TYPELESS,
+ GL_RGBA8I,
+ Initialize4ComponentData<GLbyte, 0x00, 0x00, 0x00, 0x01>);
+ return info;
+ }
+ case GL_RGB8UI:
+ {
+ static constexpr Format info(GL_RGB8UI,
+ angle::FormatID::R8G8B8A8_UINT,
+ DXGI_FORMAT_R8G8B8A8_UINT,
+ DXGI_FORMAT_R8G8B8A8_UINT,
+ DXGI_FORMAT_R8G8B8A8_UINT,
+ DXGI_FORMAT_R8G8B8A8_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_TYPELESS,
+ GL_RGBA8UI,
+ Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0x01>);
+ return info;
+ }
+ case GL_RGB8_SNORM:
+ {
+ static constexpr Format info(GL_RGB8_SNORM,
+ angle::FormatID::R8G8B8A8_SNORM,
+ DXGI_FORMAT_R8G8B8A8_SNORM,
+ DXGI_FORMAT_R8G8B8A8_SNORM,
+ DXGI_FORMAT_R8G8B8A8_SNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_SNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_TYPELESS,
+ GL_RGBA8_SNORM,
+ Initialize4ComponentData<GLbyte, 0x00, 0x00, 0x00, 0x7F>);
+ return info;
+ }
+ case GL_RGB9_E5:
+ {
+ static constexpr Format info(GL_RGB9_E5,
+ angle::FormatID::R9G9B9E5_SHAREDEXP,
+ DXGI_FORMAT_R9G9B9E5_SHAREDEXP,
+ DXGI_FORMAT_R9G9B9E5_SHAREDEXP,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R9G9B9E5_SHAREDEXP,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_RGBA16F_EXT,
+ nullptr);
+ return info;
+ }
+ case GL_RGBA:
+ {
+ static constexpr Format info(GL_RGBA,
+ angle::FormatID::R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_TYPELESS,
+ GL_RGBA8,
+ nullptr);
+ return info;
+ }
+ case GL_RGBA16F:
+ {
+ static constexpr Format info(GL_RGBA16F,
+ angle::FormatID::R16G16B16A16_FLOAT,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16B16A16_TYPELESS,
+ GL_RGBA16F,
+ nullptr);
+ return info;
+ }
+ case GL_RGBA16I:
+ {
+ static constexpr Format info(GL_RGBA16I,
+ angle::FormatID::R16G16B16A16_SINT,
+ DXGI_FORMAT_R16G16B16A16_SINT,
+ DXGI_FORMAT_R16G16B16A16_SINT,
+ DXGI_FORMAT_R16G16B16A16_SINT,
+ DXGI_FORMAT_R16G16B16A16_SINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16B16A16_SINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16B16A16_TYPELESS,
+ GL_RGBA16I,
+ nullptr);
+ return info;
+ }
+ case GL_RGBA16UI:
+ {
+ static constexpr Format info(GL_RGBA16UI,
+ angle::FormatID::R16G16B16A16_UINT,
+ DXGI_FORMAT_R16G16B16A16_UINT,
+ DXGI_FORMAT_R16G16B16A16_UINT,
+ DXGI_FORMAT_R16G16B16A16_UINT,
+ DXGI_FORMAT_R16G16B16A16_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16B16A16_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16B16A16_TYPELESS,
+ GL_RGBA16UI,
+ nullptr);
+ return info;
+ }
+ case GL_RGBA16_EXT:
+ {
+ static constexpr Format info(GL_RGBA16_EXT,
+ angle::FormatID::R16G16B16A16_UNORM,
+ DXGI_FORMAT_R16G16B16A16_UNORM,
+ DXGI_FORMAT_R16G16B16A16_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16B16A16_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16B16A16_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16B16A16_TYPELESS,
+ GL_RGBA16_EXT,
+ nullptr);
+ return info;
+ }
+ case GL_RGBA16_SNORM_EXT:
+ {
+ static constexpr Format info(GL_RGBA16_SNORM_EXT,
+ angle::FormatID::R16G16B16A16_SNORM,
+ DXGI_FORMAT_R16G16B16A16_SNORM,
+ DXGI_FORMAT_R16G16B16A16_SNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16B16A16_SNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R16G16B16A16_TYPELESS,
+ GL_RGBA16_SNORM_EXT,
+ nullptr);
+ return info;
+ }
+ case GL_RGBA32F:
+ {
+ static constexpr Format info(GL_RGBA32F,
+ angle::FormatID::R32G32B32A32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R32G32B32A32_TYPELESS,
+ GL_RGBA32F,
+ nullptr);
+ return info;
+ }
+ case GL_RGBA32I:
+ {
+ static constexpr Format info(GL_RGBA32I,
+ angle::FormatID::R32G32B32A32_SINT,
+ DXGI_FORMAT_R32G32B32A32_SINT,
+ DXGI_FORMAT_R32G32B32A32_SINT,
+ DXGI_FORMAT_R32G32B32A32_SINT,
+ DXGI_FORMAT_R32G32B32A32_SINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R32G32B32A32_SINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R32G32B32A32_TYPELESS,
+ GL_RGBA32I,
+ nullptr);
+ return info;
+ }
+ case GL_RGBA32UI:
+ {
+ static constexpr Format info(GL_RGBA32UI,
+ angle::FormatID::R32G32B32A32_UINT,
+ DXGI_FORMAT_R32G32B32A32_UINT,
+ DXGI_FORMAT_R32G32B32A32_UINT,
+ DXGI_FORMAT_R32G32B32A32_UINT,
+ DXGI_FORMAT_R32G32B32A32_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R32G32B32A32_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R32G32B32A32_TYPELESS,
+ GL_RGBA32UI,
+ nullptr);
+ return info;
+ }
+ case GL_RGBA4:
+ {
+ if (SupportsFormat(DXGI_FORMAT_B4G4R4A4_UNORM, deviceCaps))
+ {
+ static constexpr Format info(GL_RGBA4,
+ angle::FormatID::B4G4R4A4_UNORM,
+ DXGI_FORMAT_B4G4R4A4_UNORM,
+ DXGI_FORMAT_B4G4R4A4_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_B4G4R4A4_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_B4G4R4A4_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_RGBA4,
+ nullptr);
+ return info;
+ }
+ else
+ {
+ static constexpr Format info(GL_RGBA4,
+ angle::FormatID::R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_TYPELESS,
+ GL_RGBA8,
+ nullptr);
+ return info;
+ }
+ }
+ case GL_RGBA8:
+ {
+ static constexpr Format info(GL_RGBA8,
+ angle::FormatID::R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_TYPELESS,
+ GL_RGBA8,
+ nullptr);
+ return info;
+ }
+ case GL_RGBA8I:
+ {
+ static constexpr Format info(GL_RGBA8I,
+ angle::FormatID::R8G8B8A8_SINT,
+ DXGI_FORMAT_R8G8B8A8_SINT,
+ DXGI_FORMAT_R8G8B8A8_SINT,
+ DXGI_FORMAT_R8G8B8A8_SINT,
+ DXGI_FORMAT_R8G8B8A8_SINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_SINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_TYPELESS,
+ GL_RGBA8I,
+ nullptr);
+ return info;
+ }
+ case GL_RGBA8UI:
+ {
+ static constexpr Format info(GL_RGBA8UI,
+ angle::FormatID::R8G8B8A8_UINT,
+ DXGI_FORMAT_R8G8B8A8_UINT,
+ DXGI_FORMAT_R8G8B8A8_UINT,
+ DXGI_FORMAT_R8G8B8A8_UINT,
+ DXGI_FORMAT_R8G8B8A8_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_TYPELESS,
+ GL_RGBA8UI,
+ nullptr);
+ return info;
+ }
+ case GL_RGBA8_SNORM:
+ {
+ static constexpr Format info(GL_RGBA8_SNORM,
+ angle::FormatID::R8G8B8A8_SNORM,
+ DXGI_FORMAT_R8G8B8A8_SNORM,
+ DXGI_FORMAT_R8G8B8A8_SNORM,
+ DXGI_FORMAT_R8G8B8A8_SNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_SNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_TYPELESS,
+ GL_RGBA8_SNORM,
+ nullptr);
+ return info;
+ }
+ case GL_RGBX8_ANGLE:
+ {
+ if (OnlyFL11_1Plus(deviceCaps))
+ {
+ static constexpr Format info(GL_RGBX8_ANGLE,
+ angle::FormatID::R8G8B8X8_UNORM,
+ DXGI_FORMAT_B8G8R8X8_UNORM,
+ DXGI_FORMAT_B8G8R8X8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_B8G8R8X8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_B8G8R8X8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_RGBX8_ANGLE,
+ nullptr);
+ return info;
+ }
+ else
+ {
+ static constexpr Format info(GL_RGBX8_ANGLE,
+ angle::FormatID::R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_TYPELESS,
+ GL_RGBA8,
+ nullptr);
+ return info;
+ }
+ }
+ case GL_SR8_EXT:
+ {
+ static constexpr Format info(GL_SR8_EXT,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_SRG8_EXT:
+ {
+ static constexpr Format info(GL_SRG8_EXT,
+ angle::FormatID::NONE,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_NONE,
+ nullptr);
+ return info;
+ }
+ case GL_SRGB8:
+ {
+ static constexpr Format info(GL_SRGB8,
+ angle::FormatID::R8G8B8A8_UNORM_SRGB,
+ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_TYPELESS,
+ GL_SRGB8_ALPHA8,
+ Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>);
+ return info;
+ }
+ case GL_SRGB8_ALPHA8:
+ {
+ static constexpr Format info(GL_SRGB8_ALPHA8,
+ angle::FormatID::R8G8B8A8_UNORM_SRGB,
+ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_R8G8B8A8_TYPELESS,
+ GL_SRGB8_ALPHA8,
+ nullptr);
+ return info;
+ }
+ case GL_STENCIL_INDEX8:
+ {
+ if (OnlyFL10Plus(deviceCaps))
+ {
+ static constexpr Format info(GL_STENCIL_INDEX8,
+ angle::FormatID::D24_UNORM_S8_UINT,
+ DXGI_FORMAT_R24G8_TYPELESS,
+ DXGI_FORMAT_R24_UNORM_X8_TYPELESS,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_D24_UNORM_S8_UINT,
+ DXGI_FORMAT_R24_UNORM_X8_TYPELESS,
+ DXGI_FORMAT_X24_TYPELESS_G8_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ GL_RGBA32F,
+ nullptr);
+ return info;
+ }
+ else
+ {
+ static constexpr Format info(GL_STENCIL_INDEX8,
+ angle::FormatID::D24_UNORM_S8_UINT,
+ DXGI_FORMAT_D24_UNORM_S8_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_D24_UNORM_S8_UINT,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ GL_RGBA32F,
+ nullptr);
+ return info;
+ }
+ }
+
+ default:
+ break;
+ }
+ // clang-format on
+
+ UNREACHABLE();
+ static constexpr Format defaultInfo;
+ return defaultInfo;
+}
+
+} // namespace d3d11
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/texture_format_table_utils.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/texture_format_table_utils.h
new file mode 100644
index 0000000000..f46f769182
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/texture_format_table_utils.h
@@ -0,0 +1,90 @@
+//
+// 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 OnlyFL11_1Plus(const Renderer11DeviceCaps &deviceCaps)
+{
+ return (deviceCaps.featureLevel >= D3D_FEATURE_LEVEL_11_1);
+}
+
+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;
+ UINT minimumRequiredSamples = 0;
+
+ if (d3d11_gl::GetMaximumClientVersion(deviceCaps).major > 2)
+ {
+ mustSupport |= D3D11_FORMAT_SUPPORT_TEXTURE3D;
+
+ // RGBA4, RGB5A1 and RGB565 are all required multisampled renderbuffer formats in ES3 and
+ // need to support a minimum of 4 samples.
+ minimumRequiredSamples = 4;
+ }
+
+ 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) &&
+ deviceCaps.B5G6R5maxSamples >= minimumRequiredSamples;
+ }
+ else if (format == DXGI_FORMAT_B4G4R4A4_UNORM)
+ {
+ fullSupport = ((deviceCaps.B4G4R4A4support & mustSupport) == mustSupport) &&
+ deviceCaps.B4G4R4A4maxSamples >= minimumRequiredSamples;
+ }
+ else if (format == DXGI_FORMAT_B5G5R5A1_UNORM)
+ {
+ fullSupport = ((deviceCaps.B5G5R5A1support & mustSupport) == mustSupport) &&
+ deviceCaps.B5G5R5A1maxSamples >= minimumRequiredSamples;
+ }
+ 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/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow11Win32.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow11Win32.cpp
new file mode 100644
index 0000000000..722510a482
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow11Win32.cpp
@@ -0,0 +1,218 @@
+//
+// 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.
+//
+
+// NativeWindow11Win32.cpp: Implementation of NativeWindow11 using win32 window APIs.
+
+#include "libANGLE/renderer/d3d/d3d11/win32/NativeWindow11Win32.h"
+#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
+
+#include "common/debug.h"
+
+// This header must be included before dcomp.h.
+#include <initguid.h>
+
+#include <dcomp.h>
+
+namespace rx
+{
+
+NativeWindow11Win32::NativeWindow11Win32(EGLNativeWindowType window,
+ bool hasAlpha,
+ bool directComposition)
+ : NativeWindow11(window),
+ mDirectComposition(directComposition),
+ mHasAlpha(hasAlpha),
+ mDevice(nullptr),
+ mCompositionTarget(nullptr),
+ mVisual(nullptr)
+{}
+
+NativeWindow11Win32::~NativeWindow11Win32()
+{
+ SafeRelease(mCompositionTarget);
+ SafeRelease(mDevice);
+ SafeRelease(mVisual);
+}
+
+bool NativeWindow11Win32::initialize()
+{
+ return true;
+}
+
+bool NativeWindow11Win32::getClientRect(LPRECT rect) const
+{
+ return GetClientRect(getNativeWindow(), rect) == TRUE;
+}
+
+bool NativeWindow11Win32::isIconic() const
+{
+ return IsIconic(getNativeWindow()) == TRUE;
+}
+
+HRESULT NativeWindow11Win32::createSwapChain(ID3D11Device *device,
+ IDXGIFactory *factory,
+ DXGI_FORMAT format,
+ UINT width,
+ UINT height,
+ UINT samples,
+ IDXGISwapChain **swapChain)
+{
+ if (device == nullptr || factory == nullptr || swapChain == nullptr || width == 0 ||
+ height == 0)
+ {
+ return E_INVALIDARG;
+ }
+
+ if (mDirectComposition)
+ {
+ HMODULE dcomp = ::GetModuleHandle(TEXT("dcomp.dll"));
+ if (!dcomp)
+ {
+ return E_INVALIDARG;
+ }
+
+ typedef HRESULT(WINAPI * PFN_DCOMPOSITION_CREATE_DEVICE)(
+ IDXGIDevice * dxgiDevice, REFIID iid, void **dcompositionDevice);
+ PFN_DCOMPOSITION_CREATE_DEVICE createDComp =
+ reinterpret_cast<PFN_DCOMPOSITION_CREATE_DEVICE>(
+ GetProcAddress(dcomp, "DCompositionCreateDevice"));
+ if (!createDComp)
+ {
+ return E_INVALIDARG;
+ }
+
+ if (!mDevice)
+ {
+ IDXGIDevice *dxgiDevice = d3d11::DynamicCastComObject<IDXGIDevice>(device);
+ HRESULT result = createDComp(dxgiDevice, __uuidof(IDCompositionDevice),
+ reinterpret_cast<void **>(&mDevice));
+ SafeRelease(dxgiDevice);
+
+ if (FAILED(result))
+ {
+ return result;
+ }
+ }
+
+ if (!mCompositionTarget)
+ {
+ HRESULT result =
+ mDevice->CreateTargetForHwnd(getNativeWindow(), TRUE, &mCompositionTarget);
+ if (FAILED(result))
+ {
+ return result;
+ }
+ }
+
+ if (!mVisual)
+ {
+ HRESULT result = mDevice->CreateVisual(&mVisual);
+ if (FAILED(result))
+ {
+ return result;
+ }
+ }
+
+ IDXGIFactory2 *factory2 = d3d11::DynamicCastComObject<IDXGIFactory2>(factory);
+ DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {};
+ swapChainDesc.Width = width;
+ swapChainDesc.Height = height;
+ swapChainDesc.Format = format;
+ swapChainDesc.Stereo = FALSE;
+ swapChainDesc.SampleDesc.Count = 1;
+ swapChainDesc.SampleDesc.Quality = 0;
+ swapChainDesc.BufferUsage =
+ DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER | DXGI_USAGE_SHADER_INPUT;
+ swapChainDesc.BufferCount = 2;
+ swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
+ swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
+ swapChainDesc.AlphaMode =
+ mHasAlpha ? DXGI_ALPHA_MODE_PREMULTIPLIED : DXGI_ALPHA_MODE_IGNORE;
+ swapChainDesc.Flags = 0;
+ IDXGISwapChain1 *swapChain1 = nullptr;
+ HRESULT result =
+ factory2->CreateSwapChainForComposition(device, &swapChainDesc, nullptr, &swapChain1);
+ if (SUCCEEDED(result))
+ {
+ *swapChain = static_cast<IDXGISwapChain *>(swapChain1);
+ }
+ mVisual->SetContent(swapChain1);
+ mCompositionTarget->SetRoot(mVisual);
+ SafeRelease(factory2);
+ return result;
+ }
+
+ // Use IDXGIFactory2::CreateSwapChainForHwnd if DXGI 1.2 is available to create a
+ // DXGI_SWAP_EFFECT_SEQUENTIAL swap chain.
+ IDXGIFactory2 *factory2 = d3d11::DynamicCastComObject<IDXGIFactory2>(factory);
+ if (factory2 != nullptr)
+ {
+ DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {};
+ swapChainDesc.Width = width;
+ swapChainDesc.Height = height;
+ swapChainDesc.Format = format;
+ swapChainDesc.Stereo = FALSE;
+ swapChainDesc.SampleDesc.Count = samples;
+ swapChainDesc.SampleDesc.Quality = 0;
+ swapChainDesc.BufferUsage =
+ DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_BACK_BUFFER;
+ swapChainDesc.BufferCount = 1;
+ swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
+ swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_SEQUENTIAL;
+ swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED;
+ swapChainDesc.Flags = 0;
+ IDXGISwapChain1 *swapChain1 = nullptr;
+ HRESULT result = factory2->CreateSwapChainForHwnd(device, getNativeWindow(), &swapChainDesc,
+ nullptr, nullptr, &swapChain1);
+ if (SUCCEEDED(result))
+ {
+ factory2->MakeWindowAssociation(getNativeWindow(), DXGI_MWA_NO_ALT_ENTER);
+ *swapChain = static_cast<IDXGISwapChain *>(swapChain1);
+ }
+ SafeRelease(factory2);
+ return result;
+ }
+
+ DXGI_SWAP_CHAIN_DESC swapChainDesc = {};
+ swapChainDesc.BufferCount = 1;
+ swapChainDesc.BufferDesc.Format = format;
+ swapChainDesc.BufferDesc.Width = width;
+ swapChainDesc.BufferDesc.Height = height;
+ swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
+ swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
+ swapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
+ swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
+ swapChainDesc.BufferUsage =
+ DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_BACK_BUFFER;
+ swapChainDesc.Flags = 0;
+ swapChainDesc.OutputWindow = getNativeWindow();
+ swapChainDesc.SampleDesc.Count = samples;
+ swapChainDesc.SampleDesc.Quality = 0;
+ swapChainDesc.Windowed = TRUE;
+ swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
+
+ HRESULT result = factory->CreateSwapChain(device, &swapChainDesc, swapChain);
+ if (SUCCEEDED(result))
+ {
+ factory->MakeWindowAssociation(getNativeWindow(), DXGI_MWA_NO_ALT_ENTER);
+ }
+ return result;
+}
+
+void NativeWindow11Win32::commitChange()
+{
+ if (mDevice)
+ {
+ mDevice->Commit();
+ }
+}
+
+// static
+bool NativeWindow11Win32::IsValidNativeWindow(EGLNativeWindowType window)
+{
+ return IsWindow(window) == TRUE;
+}
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow11Win32.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow11Win32.h
new file mode 100644
index 0000000000..f67cfc73a8
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow11Win32.h
@@ -0,0 +1,53 @@
+//
+// 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.
+//
+
+// NativeWindow11Win32.h: Implementation of NativeWindow11 using win32 window APIs.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D11_WIN32_NATIVEWINDOW11WIN32_H_
+#define LIBANGLE_RENDERER_D3D_D3D11_WIN32_NATIVEWINDOW11WIN32_H_
+
+#include "libANGLE/renderer/d3d/d3d11/NativeWindow11.h"
+
+typedef interface IDCompositionDevice IDCompositionDevice;
+typedef interface IDCompositionTarget IDCompositionTarget;
+typedef interface IDCompositionVisual IDCompositionVisual;
+
+namespace rx
+{
+
+class NativeWindow11Win32 : public NativeWindow11
+{
+ public:
+ NativeWindow11Win32(EGLNativeWindowType window, bool hasAlpha, bool directComposition);
+ ~NativeWindow11Win32() override;
+
+ bool initialize() override;
+ bool getClientRect(LPRECT rect) const override;
+ bool isIconic() const override;
+
+ HRESULT createSwapChain(ID3D11Device *device,
+ IDXGIFactory *factory,
+ DXGI_FORMAT format,
+ UINT width,
+ UINT height,
+ UINT samples,
+ IDXGISwapChain **swapChain) override;
+
+ void commitChange() override;
+
+ static bool IsValidNativeWindow(EGLNativeWindowType window);
+
+ private:
+ bool mDirectComposition;
+ bool mHasAlpha;
+ IDCompositionDevice *mDevice;
+ IDCompositionTarget *mCompositionTarget;
+ IDCompositionVisual *mVisual;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D11_WIN32_NATIVEWINDOW11WIN32_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Blit9.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Blit9.cpp
new file mode 100644
index 0000000000..429159b4cb
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Blit9.cpp
@@ -0,0 +1,760 @@
+//
+// Copyright 2002 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.
+//
+
+// Blit9.cpp: Surface copy utility class.
+
+#include "libANGLE/renderer/d3d/d3d9/Blit9.h"
+
+#include "libANGLE/Context.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/renderer/d3d/TextureD3D.h"
+#include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h"
+#include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
+#include "libANGLE/renderer/d3d/d3d9/TextureStorage9.h"
+#include "libANGLE/renderer/d3d/d3d9/formatutils9.h"
+#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h"
+
+namespace
+{
+// Precompiled shaders
+#include "libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskpremultps.h"
+#include "libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskps.h"
+#include "libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskunmultps.h"
+#include "libANGLE/renderer/d3d/d3d9/shaders/compiled/luminancepremultps.h"
+#include "libANGLE/renderer/d3d/d3d9/shaders/compiled/luminanceps.h"
+#include "libANGLE/renderer/d3d/d3d9/shaders/compiled/luminanceunmultps.h"
+#include "libANGLE/renderer/d3d/d3d9/shaders/compiled/passthroughps.h"
+#include "libANGLE/renderer/d3d/d3d9/shaders/compiled/standardvs.h"
+
+const BYTE *const g_shaderCode[] = {
+ g_vs20_standardvs,
+ g_ps20_passthroughps,
+ g_ps20_luminanceps,
+ g_ps20_luminancepremultps,
+ g_ps20_luminanceunmultps,
+ g_ps20_componentmaskps,
+ g_ps20_componentmaskpremultps,
+ g_ps20_componentmaskunmultps,
+};
+
+const size_t g_shaderSize[] = {
+ sizeof(g_vs20_standardvs),
+ sizeof(g_ps20_passthroughps),
+ sizeof(g_ps20_luminanceps),
+ sizeof(g_ps20_luminancepremultps),
+ sizeof(g_ps20_luminanceunmultps),
+ sizeof(g_ps20_componentmaskps),
+ sizeof(g_ps20_componentmaskpremultps),
+ sizeof(g_ps20_componentmaskunmultps),
+};
+} // namespace
+
+namespace rx
+{
+
+Blit9::Blit9(Renderer9 *renderer)
+ : mRenderer(renderer),
+ mGeometryLoaded(false),
+ mQuadVertexBuffer(nullptr),
+ mQuadVertexDeclaration(nullptr),
+ mSavedStateBlock(nullptr),
+ mSavedRenderTarget(nullptr),
+ mSavedDepthStencil(nullptr)
+{
+ memset(mCompiledShaders, 0, sizeof(mCompiledShaders));
+}
+
+Blit9::~Blit9()
+{
+ SafeRelease(mSavedStateBlock);
+ SafeRelease(mQuadVertexBuffer);
+ SafeRelease(mQuadVertexDeclaration);
+
+ for (int i = 0; i < SHADER_COUNT; i++)
+ {
+ SafeRelease(mCompiledShaders[i]);
+ }
+}
+
+angle::Result Blit9::initialize(Context9 *context9)
+{
+ if (mGeometryLoaded)
+ {
+ return angle::Result::Continue;
+ }
+
+ static const float quad[] = {-1, -1, -1, 1, 1, -1, 1, 1};
+
+ IDirect3DDevice9 *device = mRenderer->getDevice();
+
+ HRESULT result = device->CreateVertexBuffer(sizeof(quad), D3DUSAGE_WRITEONLY, 0,
+ D3DPOOL_DEFAULT, &mQuadVertexBuffer, nullptr);
+
+ ANGLE_TRY_HR(context9, result, "Failed to create internal blit vertex shader");
+
+ void *lockPtr = nullptr;
+ result = mQuadVertexBuffer->Lock(0, 0, &lockPtr, 0);
+
+ ANGLE_TRY_HR(context9, result, "Failed to lock internal blit vertex shader");
+ ASSERT(lockPtr);
+
+ memcpy(lockPtr, quad, sizeof(quad));
+ mQuadVertexBuffer->Unlock();
+
+ static const D3DVERTEXELEMENT9 elements[] = {
+ {0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, D3DDECL_END()};
+
+ result = device->CreateVertexDeclaration(elements, &mQuadVertexDeclaration);
+ ANGLE_TRY_HR(context9, result, "Failed to create internal blit vertex shader declaration");
+
+ mGeometryLoaded = true;
+ return angle::Result::Continue;
+}
+
+template <class D3DShaderType>
+angle::Result Blit9::setShader(Context9 *context9,
+ ShaderId source,
+ const char *profile,
+ angle::Result (Renderer9::*createShader)(d3d::Context *,
+ const DWORD *,
+ size_t length,
+ D3DShaderType **outShader),
+ HRESULT (WINAPI IDirect3DDevice9::*setShader)(D3DShaderType *))
+{
+ IDirect3DDevice9 *device = mRenderer->getDevice();
+
+ D3DShaderType *shader = nullptr;
+
+ if (mCompiledShaders[source] != nullptr)
+ {
+ shader = static_cast<D3DShaderType *>(mCompiledShaders[source]);
+ }
+ else
+ {
+ const BYTE *shaderCode = g_shaderCode[source];
+ size_t shaderSize = g_shaderSize[source];
+ ANGLE_TRY((mRenderer->*createShader)(context9, reinterpret_cast<const DWORD *>(shaderCode),
+ shaderSize, &shader));
+ mCompiledShaders[source] = shader;
+ }
+
+ HRESULT hr = (device->*setShader)(shader);
+ ANGLE_TRY_HR(context9, hr, "Failed to set shader for blit operation");
+ return angle::Result::Continue;
+}
+
+angle::Result Blit9::setVertexShader(Context9 *context9, ShaderId shader)
+{
+ return setShader<IDirect3DVertexShader9>(context9, shader, "vs_2_0",
+ &Renderer9::createVertexShader,
+ &IDirect3DDevice9::SetVertexShader);
+}
+
+angle::Result Blit9::setPixelShader(Context9 *context9, ShaderId shader)
+{
+ return setShader<IDirect3DPixelShader9>(context9, shader, "ps_2_0",
+ &Renderer9::createPixelShader,
+ &IDirect3DDevice9::SetPixelShader);
+}
+
+RECT Blit9::getSurfaceRect(IDirect3DSurface9 *surface) const
+{
+ D3DSURFACE_DESC desc;
+ surface->GetDesc(&desc);
+
+ RECT rect;
+ rect.left = 0;
+ rect.top = 0;
+ rect.right = desc.Width;
+ rect.bottom = desc.Height;
+
+ return rect;
+}
+
+gl::Extents Blit9::getSurfaceSize(IDirect3DSurface9 *surface) const
+{
+ D3DSURFACE_DESC desc;
+ surface->GetDesc(&desc);
+
+ return gl::Extents(desc.Width, desc.Height, 1);
+}
+
+angle::Result Blit9::boxFilter(Context9 *context9,
+ IDirect3DSurface9 *source,
+ IDirect3DSurface9 *dest)
+{
+ ANGLE_TRY(initialize(context9));
+
+ angle::ComPtr<IDirect3DBaseTexture9> texture = nullptr;
+ ANGLE_TRY(copySurfaceToTexture(context9, source, getSurfaceRect(source), &texture));
+
+ IDirect3DDevice9 *device = mRenderer->getDevice();
+
+ saveState();
+
+ device->SetTexture(0, texture.Get());
+ device->SetRenderTarget(0, dest);
+
+ ANGLE_TRY(setVertexShader(context9, SHADER_VS_STANDARD));
+ ANGLE_TRY(setPixelShader(context9, SHADER_PS_PASSTHROUGH));
+
+ setCommonBlitState();
+ device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
+ device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
+
+ setViewportAndShaderConstants(getSurfaceRect(source), getSurfaceSize(source),
+ getSurfaceRect(dest), false);
+
+ render();
+
+ restoreState();
+
+ return angle::Result::Continue;
+}
+
+angle::Result Blit9::copy2D(const gl::Context *context,
+ const gl::Framebuffer *framebuffer,
+ const RECT &sourceRect,
+ GLenum destFormat,
+ const gl::Offset &destOffset,
+ TextureStorage *storage,
+ GLint level)
+{
+ Context9 *context9 = GetImplAs<Context9>(context);
+
+ ANGLE_TRY(initialize(context9));
+
+ const gl::FramebufferAttachment *colorbuffer = framebuffer->getColorAttachment(0);
+ ASSERT(colorbuffer);
+
+ RenderTarget9 *renderTarget9 = nullptr;
+ ANGLE_TRY(colorbuffer->getRenderTarget(context, 0, &renderTarget9));
+ ASSERT(renderTarget9);
+
+ angle::ComPtr<IDirect3DSurface9> source = renderTarget9->getSurface();
+ ASSERT(source);
+
+ angle::ComPtr<IDirect3DSurface9> destSurface = nullptr;
+ TextureStorage9 *storage9 = GetAs<TextureStorage9>(storage);
+ ANGLE_TRY(
+ storage9->getSurfaceLevel(context, gl::TextureTarget::_2D, level, true, &destSurface));
+ ASSERT(destSurface);
+
+ ANGLE_TRY(copy(context9, source.Get(), nullptr, sourceRect, destFormat, destOffset,
+ destSurface.Get(), false, false, false));
+ return angle::Result::Continue;
+}
+
+angle::Result Blit9::copyCube(const gl::Context *context,
+ const gl::Framebuffer *framebuffer,
+ const RECT &sourceRect,
+ GLenum destFormat,
+ const gl::Offset &destOffset,
+ TextureStorage *storage,
+ gl::TextureTarget target,
+ GLint level)
+{
+ Context9 *context9 = GetImplAs<Context9>(context);
+
+ ANGLE_TRY(initialize(context9));
+
+ const gl::FramebufferAttachment *colorbuffer = framebuffer->getColorAttachment(0);
+ ASSERT(colorbuffer);
+
+ RenderTarget9 *renderTarget9 = nullptr;
+ ANGLE_TRY(colorbuffer->getRenderTarget(context, 0, &renderTarget9));
+ ASSERT(renderTarget9);
+
+ angle::ComPtr<IDirect3DSurface9> source = renderTarget9->getSurface();
+ ASSERT(source);
+
+ angle::ComPtr<IDirect3DSurface9> destSurface = nullptr;
+ TextureStorage9 *storage9 = GetAs<TextureStorage9>(storage);
+ ANGLE_TRY(storage9->getSurfaceLevel(context, target, level, true, &destSurface));
+ ASSERT(destSurface);
+
+ return copy(context9, source.Get(), nullptr, sourceRect, destFormat, destOffset,
+ destSurface.Get(), false, false, false);
+}
+
+angle::Result Blit9::copyTexture(const gl::Context *context,
+ const gl::Texture *source,
+ GLint sourceLevel,
+ const RECT &sourceRect,
+ GLenum destFormat,
+ const gl::Offset &destOffset,
+ TextureStorage *storage,
+ gl::TextureTarget destTarget,
+ GLint destLevel,
+ bool flipY,
+ bool premultiplyAlpha,
+ bool unmultiplyAlpha)
+{
+ Context9 *context9 = GetImplAs<Context9>(context);
+ ANGLE_TRY(initialize(context9));
+
+ TextureD3D *sourceD3D = GetImplAs<TextureD3D>(source);
+
+ TextureStorage *sourceStorage = nullptr;
+ ANGLE_TRY(sourceD3D->getNativeTexture(context, &sourceStorage));
+
+ TextureStorage9_2D *sourceStorage9 = GetAs<TextureStorage9_2D>(sourceStorage);
+ ASSERT(sourceStorage9);
+
+ TextureStorage9 *destStorage9 = GetAs<TextureStorage9>(storage);
+ ASSERT(destStorage9);
+
+ ASSERT(sourceLevel == 0);
+ IDirect3DBaseTexture9 *sourceTexture = nullptr;
+ ANGLE_TRY(sourceStorage9->getBaseTexture(context, &sourceTexture));
+
+ angle::ComPtr<IDirect3DSurface9> sourceSurface = nullptr;
+ ANGLE_TRY(sourceStorage9->getSurfaceLevel(context, gl::TextureTarget::_2D, sourceLevel, true,
+ &sourceSurface));
+
+ angle::ComPtr<IDirect3DSurface9> destSurface = nullptr;
+ ANGLE_TRY(destStorage9->getSurfaceLevel(context, destTarget, destLevel, true, &destSurface));
+
+ return copy(context9, sourceSurface.Get(), sourceTexture, sourceRect, destFormat, destOffset,
+ destSurface.Get(), flipY, premultiplyAlpha, unmultiplyAlpha);
+}
+
+angle::Result Blit9::copy(Context9 *context9,
+ IDirect3DSurface9 *source,
+ IDirect3DBaseTexture9 *sourceTexture,
+ const RECT &sourceRect,
+ GLenum destFormat,
+ const gl::Offset &destOffset,
+ IDirect3DSurface9 *dest,
+ bool flipY,
+ bool premultiplyAlpha,
+ bool unmultiplyAlpha)
+{
+ ASSERT(source != nullptr && dest != nullptr);
+
+ IDirect3DDevice9 *device = mRenderer->getDevice();
+
+ D3DSURFACE_DESC sourceDesc;
+ D3DSURFACE_DESC destDesc;
+ source->GetDesc(&sourceDesc);
+ dest->GetDesc(&destDesc);
+
+ // Check if it's possible to use StetchRect
+ if (sourceDesc.Format == destDesc.Format && (destDesc.Usage & D3DUSAGE_RENDERTARGET) &&
+ d3d9_gl::IsFormatChannelEquivalent(destDesc.Format, destFormat) && !flipY &&
+ premultiplyAlpha == unmultiplyAlpha)
+ {
+ RECT destRect = {destOffset.x, destOffset.y,
+ destOffset.x + (sourceRect.right - sourceRect.left),
+ destOffset.y + (sourceRect.bottom - sourceRect.top)};
+ HRESULT result = device->StretchRect(source, &sourceRect, dest, &destRect, D3DTEXF_POINT);
+ ANGLE_TRY_HR(context9, result, "StretchRect failed to blit between textures");
+ return angle::Result::Continue;
+ }
+
+ angle::ComPtr<IDirect3DBaseTexture9> texture = sourceTexture;
+ RECT adjustedSourceRect = sourceRect;
+ gl::Extents sourceSize(sourceDesc.Width, sourceDesc.Height, 1);
+
+ if (texture == nullptr)
+ {
+ ANGLE_TRY(copySurfaceToTexture(context9, source, sourceRect, &texture));
+
+ // copySurfaceToTexture only copies in the sourceRect area of the source surface.
+ // Adjust sourceRect so that it is now covering the entire source texture
+ adjustedSourceRect.left = 0;
+ adjustedSourceRect.right = sourceRect.right - sourceRect.left;
+ adjustedSourceRect.top = 0;
+ adjustedSourceRect.bottom = sourceRect.bottom - sourceRect.top;
+
+ sourceSize.width = sourceRect.right - sourceRect.left;
+ sourceSize.height = sourceRect.bottom - sourceRect.top;
+ }
+
+ ANGLE_TRY(formatConvert(context9, texture.Get(), adjustedSourceRect, sourceSize, destFormat,
+ destOffset, dest, flipY, premultiplyAlpha, unmultiplyAlpha));
+ return angle::Result::Continue;
+}
+
+angle::Result Blit9::formatConvert(Context9 *context9,
+ IDirect3DBaseTexture9 *source,
+ const RECT &sourceRect,
+ const gl::Extents &sourceSize,
+ GLenum destFormat,
+ const gl::Offset &destOffset,
+ IDirect3DSurface9 *dest,
+ bool flipY,
+ bool premultiplyAlpha,
+ bool unmultiplyAlpha)
+{
+ ANGLE_TRY(initialize(context9));
+
+ IDirect3DDevice9 *device = mRenderer->getDevice();
+
+ saveState();
+
+ device->SetTexture(0, source);
+ device->SetRenderTarget(0, dest);
+
+ RECT destRect;
+ destRect.left = destOffset.x;
+ destRect.right = destOffset.x + (sourceRect.right - sourceRect.left);
+ destRect.top = destOffset.y;
+ destRect.bottom = destOffset.y + (sourceRect.bottom - sourceRect.top);
+
+ setViewportAndShaderConstants(sourceRect, sourceSize, destRect, flipY);
+
+ setCommonBlitState();
+
+ angle::Result result =
+ setFormatConvertShaders(context9, destFormat, flipY, premultiplyAlpha, unmultiplyAlpha);
+ if (result == angle::Result::Continue)
+ {
+ render();
+ }
+
+ restoreState();
+
+ return result;
+}
+
+angle::Result Blit9::setFormatConvertShaders(Context9 *context9,
+ GLenum destFormat,
+ bool flipY,
+ bool premultiplyAlpha,
+ bool unmultiplyAlpha)
+{
+ ANGLE_TRY(setVertexShader(context9, SHADER_VS_STANDARD));
+
+ switch (destFormat)
+ {
+ case GL_RGBA:
+ case GL_BGRA_EXT:
+ case GL_RGB:
+ case GL_RG_EXT:
+ case GL_RED_EXT:
+ case GL_ALPHA:
+ if (premultiplyAlpha == unmultiplyAlpha)
+ {
+ ANGLE_TRY(setPixelShader(context9, SHADER_PS_COMPONENTMASK));
+ }
+ else if (premultiplyAlpha)
+ {
+ ANGLE_TRY(setPixelShader(context9, SHADER_PS_COMPONENTMASK_PREMULTIPLY_ALPHA));
+ }
+ else
+ {
+ ASSERT(unmultiplyAlpha);
+ ANGLE_TRY(setPixelShader(context9, SHADER_PS_COMPONENTMASK_UNMULTIPLY_ALPHA));
+ }
+ break;
+
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ if (premultiplyAlpha == unmultiplyAlpha)
+ {
+ ANGLE_TRY(setPixelShader(context9, SHADER_PS_LUMINANCE));
+ }
+ else if (premultiplyAlpha)
+ {
+ ANGLE_TRY(setPixelShader(context9, SHADER_PS_LUMINANCE_PREMULTIPLY_ALPHA));
+ }
+ else
+ {
+ ASSERT(unmultiplyAlpha);
+ ANGLE_TRY(setPixelShader(context9, SHADER_PS_LUMINANCE_UNMULTIPLY_ALPHA));
+ }
+ break;
+
+ default:
+ UNREACHABLE();
+ }
+
+ enum
+ {
+ X = 0,
+ Y = 1,
+ Z = 2,
+ W = 3
+ };
+
+ // The meaning of this constant depends on the shader that was selected.
+ // See the shader assembly code above for details.
+ // Allocate one array for both registers and split it into two float4's.
+ float psConst[8] = {0};
+ float *multConst = &psConst[0];
+ float *addConst = &psConst[4];
+
+ switch (destFormat)
+ {
+ case GL_RGBA:
+ case GL_BGRA_EXT:
+ multConst[X] = 1;
+ multConst[Y] = 1;
+ multConst[Z] = 1;
+ multConst[W] = 1;
+ addConst[X] = 0;
+ addConst[Y] = 0;
+ addConst[Z] = 0;
+ addConst[W] = 0;
+ break;
+
+ case GL_RGB:
+ multConst[X] = 1;
+ multConst[Y] = 1;
+ multConst[Z] = 1;
+ multConst[W] = 0;
+ addConst[X] = 0;
+ addConst[Y] = 0;
+ addConst[Z] = 0;
+ addConst[W] = 1;
+ break;
+
+ case GL_RG_EXT:
+ multConst[X] = 1;
+ multConst[Y] = 1;
+ multConst[Z] = 0;
+ multConst[W] = 0;
+ addConst[X] = 0;
+ addConst[Y] = 0;
+ addConst[Z] = 0;
+ addConst[W] = 1;
+ break;
+
+ case GL_RED_EXT:
+ multConst[X] = 1;
+ multConst[Y] = 0;
+ multConst[Z] = 0;
+ multConst[W] = 0;
+ addConst[X] = 0;
+ addConst[Y] = 0;
+ addConst[Z] = 0;
+ addConst[W] = 1;
+ break;
+
+ case GL_ALPHA:
+ multConst[X] = 0;
+ multConst[Y] = 0;
+ multConst[Z] = 0;
+ multConst[W] = 1;
+ addConst[X] = 0;
+ addConst[Y] = 0;
+ addConst[Z] = 0;
+ addConst[W] = 0;
+ break;
+
+ case GL_LUMINANCE:
+ multConst[X] = 1;
+ multConst[Y] = 0;
+ multConst[Z] = 0;
+ multConst[W] = 0;
+ addConst[X] = 0;
+ addConst[Y] = 0;
+ addConst[Z] = 0;
+ addConst[W] = 1;
+ break;
+
+ case GL_LUMINANCE_ALPHA:
+ multConst[X] = 1;
+ multConst[Y] = 0;
+ multConst[Z] = 0;
+ multConst[W] = 1;
+ addConst[X] = 0;
+ addConst[Y] = 0;
+ addConst[Z] = 0;
+ addConst[W] = 0;
+ break;
+
+ default:
+ UNREACHABLE();
+ }
+
+ mRenderer->getDevice()->SetPixelShaderConstantF(0, psConst, 2);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Blit9::copySurfaceToTexture(Context9 *context9,
+ IDirect3DSurface9 *surface,
+ const RECT &sourceRect,
+ angle::ComPtr<IDirect3DBaseTexture9> *outTexture)
+{
+ ASSERT(surface);
+
+ IDirect3DDevice9 *device = mRenderer->getDevice();
+
+ D3DSURFACE_DESC sourceDesc;
+ surface->GetDesc(&sourceDesc);
+
+ // Copy the render target into a texture
+ angle::ComPtr<IDirect3DTexture9> texture;
+ HRESULT result = device->CreateTexture(
+ sourceRect.right - sourceRect.left, sourceRect.bottom - sourceRect.top, 1,
+ D3DUSAGE_RENDERTARGET, sourceDesc.Format, D3DPOOL_DEFAULT, &texture, nullptr);
+ ANGLE_TRY_HR(context9, result, "Failed to allocate internal texture for blit");
+
+ angle::ComPtr<IDirect3DSurface9> textureSurface;
+ result = texture->GetSurfaceLevel(0, &textureSurface);
+ ANGLE_TRY_HR(context9, result, "Failed to query surface of internal blit texture");
+
+ mRenderer->endScene();
+ result = device->StretchRect(surface, &sourceRect, textureSurface.Get(), nullptr, D3DTEXF_NONE);
+ ANGLE_TRY_HR(context9, result, "Failed to copy between internal blit textures");
+ *outTexture = texture;
+
+ return angle::Result::Continue;
+}
+
+void Blit9::setViewportAndShaderConstants(const RECT &sourceRect,
+ const gl::Extents &sourceSize,
+ const RECT &destRect,
+ bool flipY)
+{
+ IDirect3DDevice9 *device = mRenderer->getDevice();
+
+ D3DVIEWPORT9 vp;
+ vp.X = destRect.left;
+ vp.Y = destRect.top;
+ vp.Width = destRect.right - destRect.left;
+ vp.Height = destRect.bottom - destRect.top;
+ vp.MinZ = 0.0f;
+ vp.MaxZ = 1.0f;
+ device->SetViewport(&vp);
+
+ float vertexConstants[8] = {
+ // halfPixelAdjust
+ -1.0f / vp.Width,
+ 1.0f / vp.Height,
+ 0,
+ 0,
+ // texcoordOffset
+ static_cast<float>(sourceRect.left) / sourceSize.width,
+ static_cast<float>(flipY ? sourceRect.bottom : sourceRect.top) / sourceSize.height,
+ static_cast<float>(sourceRect.right - sourceRect.left) / sourceSize.width,
+ static_cast<float>(flipY ? sourceRect.top - sourceRect.bottom
+ : sourceRect.bottom - sourceRect.top) /
+ sourceSize.height,
+ };
+
+ device->SetVertexShaderConstantF(0, vertexConstants, 2);
+}
+
+void Blit9::setCommonBlitState()
+{
+ IDirect3DDevice9 *device = mRenderer->getDevice();
+
+ device->SetDepthStencilSurface(nullptr);
+
+ device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
+ device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
+ device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+ device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
+ device->SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
+ device->SetRenderState(D3DRS_COLORWRITEENABLE,
+ D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_BLUE |
+ D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED);
+ device->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE);
+ device->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
+
+ device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
+ device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
+ device->SetSamplerState(0, D3DSAMP_SRGBTEXTURE, FALSE);
+ device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
+ device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
+
+ RECT scissorRect = {}; // Scissoring is disabled for flipping, but we need this to capture and
+ // restore the old rectangle
+ device->SetScissorRect(&scissorRect);
+
+ for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
+ {
+ device->SetStreamSourceFreq(i, 1);
+ }
+}
+
+void Blit9::render()
+{
+ IDirect3DDevice9 *device = mRenderer->getDevice();
+
+ device->SetStreamSource(0, mQuadVertexBuffer, 0, 2 * sizeof(float));
+ device->SetVertexDeclaration(mQuadVertexDeclaration);
+
+ mRenderer->startScene();
+ device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
+}
+
+void Blit9::saveState()
+{
+ IDirect3DDevice9 *device = mRenderer->getDevice();
+
+ HRESULT hr;
+
+ device->GetDepthStencilSurface(&mSavedDepthStencil);
+ device->GetRenderTarget(0, &mSavedRenderTarget);
+
+ if (mSavedStateBlock == nullptr)
+ {
+ hr = device->BeginStateBlock();
+ ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY);
+
+ setCommonBlitState();
+
+ static const float mockConst[8] = {0};
+
+ device->SetVertexShader(nullptr);
+ device->SetVertexShaderConstantF(0, mockConst, 2);
+ device->SetPixelShader(nullptr);
+ device->SetPixelShaderConstantF(0, mockConst, 2);
+
+ D3DVIEWPORT9 mockVp;
+ mockVp.X = 0;
+ mockVp.Y = 0;
+ mockVp.Width = 1;
+ mockVp.Height = 1;
+ mockVp.MinZ = 0;
+ mockVp.MaxZ = 1;
+
+ device->SetViewport(&mockVp);
+
+ device->SetTexture(0, nullptr);
+
+ device->SetStreamSource(0, mQuadVertexBuffer, 0, 0);
+
+ device->SetVertexDeclaration(mQuadVertexDeclaration);
+
+ hr = device->EndStateBlock(&mSavedStateBlock);
+ ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY);
+ }
+
+ ASSERT(mSavedStateBlock != nullptr);
+
+ if (mSavedStateBlock != nullptr)
+ {
+ hr = mSavedStateBlock->Capture();
+ ASSERT(SUCCEEDED(hr));
+ }
+}
+
+void Blit9::restoreState()
+{
+ IDirect3DDevice9 *device = mRenderer->getDevice();
+
+ device->SetDepthStencilSurface(mSavedDepthStencil);
+ SafeRelease(mSavedDepthStencil);
+
+ device->SetRenderTarget(0, mSavedRenderTarget);
+ SafeRelease(mSavedRenderTarget);
+
+ ASSERT(mSavedStateBlock != nullptr);
+
+ if (mSavedStateBlock != nullptr)
+ {
+ mSavedStateBlock->Apply();
+ }
+}
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Blit9.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Blit9.h
new file mode 100644
index 0000000000..1c99413ecd
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Blit9.h
@@ -0,0 +1,166 @@
+//
+// Copyright 2002 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.
+//
+
+// Blit9.cpp: Surface copy utility class.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D9_BLIT9_H_
+#define LIBANGLE_RENDERER_D3D_D3D9_BLIT9_H_
+
+#include "common/PackedEnums.h"
+#include "common/angleutils.h"
+#include "libANGLE/Error.h"
+
+namespace gl
+{
+class Context;
+class Framebuffer;
+class Texture;
+struct Extents;
+struct Offset;
+} // namespace gl
+
+namespace rx
+{
+class Context9;
+class Renderer9;
+class TextureStorage;
+
+namespace d3d
+{
+class Context;
+} // namespace d3d
+
+class Blit9 : angle::NonCopyable
+{
+ public:
+ explicit Blit9(Renderer9 *renderer);
+ ~Blit9();
+
+ angle::Result initialize(Context9 *context9);
+
+ // Copy from source surface to dest surface.
+ // sourceRect, xoffset, yoffset are in D3D coordinates (0,0 in upper-left)
+ angle::Result copy2D(const gl::Context *context,
+ const gl::Framebuffer *framebuffer,
+ const RECT &sourceRect,
+ GLenum destFormat,
+ const gl::Offset &destOffset,
+ TextureStorage *storage,
+ GLint level);
+ angle::Result copyCube(const gl::Context *context,
+ const gl::Framebuffer *framebuffer,
+ const RECT &sourceRect,
+ GLenum destFormat,
+ const gl::Offset &destOffset,
+ TextureStorage *storage,
+ gl::TextureTarget target,
+ GLint level);
+ angle::Result copyTexture(const gl::Context *context,
+ const gl::Texture *source,
+ GLint sourceLevel,
+ const RECT &sourceRect,
+ GLenum destFormat,
+ const gl::Offset &destOffset,
+ TextureStorage *storage,
+ gl::TextureTarget destTarget,
+ GLint destLevel,
+ bool flipY,
+ bool premultiplyAlpha,
+ bool unmultiplyAlpha);
+
+ // 2x2 box filter sample from source to dest.
+ // Requires that source is RGB(A) and dest has the same format as source.
+ angle::Result boxFilter(Context9 *context9, IDirect3DSurface9 *source, IDirect3DSurface9 *dest);
+
+ private:
+ Renderer9 *mRenderer;
+
+ bool mGeometryLoaded;
+ IDirect3DVertexBuffer9 *mQuadVertexBuffer;
+ IDirect3DVertexDeclaration9 *mQuadVertexDeclaration;
+
+ // Copy from source texture to dest surface.
+ // sourceRect, xoffset, yoffset are in D3D coordinates (0,0 in upper-left)
+ // source is interpreted as RGBA and destFormat specifies the desired result format. For
+ // example, if destFormat = GL_RGB, the alpha channel will be forced to 0.
+ angle::Result formatConvert(Context9 *context9,
+ IDirect3DBaseTexture9 *source,
+ const RECT &sourceRect,
+ const gl::Extents &sourceSize,
+ GLenum destFormat,
+ const gl::Offset &destOffset,
+ IDirect3DSurface9 *dest,
+ bool flipY,
+ bool premultiplyAlpha,
+ bool unmultiplyAlpha);
+ angle::Result setFormatConvertShaders(Context9 *context9,
+ GLenum destFormat,
+ bool flipY,
+ bool premultiplyAlpha,
+ bool unmultiplyAlpha);
+
+ angle::Result copy(Context9 *context9,
+ IDirect3DSurface9 *source,
+ IDirect3DBaseTexture9 *sourceTexture,
+ const RECT &sourceRect,
+ GLenum destFormat,
+ const gl::Offset &destOffset,
+ IDirect3DSurface9 *dest,
+ bool flipY,
+ bool premultiplyAlpha,
+ bool unmultiplyAlpha);
+ angle::Result copySurfaceToTexture(Context9 *context9,
+ IDirect3DSurface9 *surface,
+ const RECT &sourceRect,
+ angle::ComPtr<IDirect3DBaseTexture9> *outTexture);
+ void setViewportAndShaderConstants(const RECT &sourceRect,
+ const gl::Extents &sourceSize,
+ const RECT &destRect,
+ bool flipY);
+ void setCommonBlitState();
+ RECT getSurfaceRect(IDirect3DSurface9 *surface) const;
+ gl::Extents getSurfaceSize(IDirect3DSurface9 *surface) const;
+
+ // This enum is used to index mCompiledShaders and mShaderSource.
+ enum ShaderId
+ {
+ SHADER_VS_STANDARD,
+ SHADER_PS_PASSTHROUGH,
+ SHADER_PS_LUMINANCE,
+ SHADER_PS_LUMINANCE_PREMULTIPLY_ALPHA,
+ SHADER_PS_LUMINANCE_UNMULTIPLY_ALPHA,
+ SHADER_PS_COMPONENTMASK,
+ SHADER_PS_COMPONENTMASK_PREMULTIPLY_ALPHA,
+ SHADER_PS_COMPONENTMASK_UNMULTIPLY_ALPHA,
+ SHADER_COUNT,
+ };
+
+ // This actually contains IDirect3DVertexShader9 or IDirect3DPixelShader9 casted to IUnknown.
+ IUnknown *mCompiledShaders[SHADER_COUNT];
+
+ template <class D3DShaderType>
+ angle::Result setShader(Context9 *,
+ ShaderId source,
+ const char *profile,
+ angle::Result (Renderer9::*createShader)(d3d::Context *context,
+ const DWORD *,
+ size_t length,
+ D3DShaderType **outShader),
+ HRESULT (WINAPI IDirect3DDevice9::*setShader)(D3DShaderType *));
+
+ angle::Result setVertexShader(Context9 *context9, ShaderId shader);
+ angle::Result setPixelShader(Context9 *context9, ShaderId shader);
+ void render();
+
+ void saveState();
+ void restoreState();
+ IDirect3DStateBlock9 *mSavedStateBlock;
+ IDirect3DSurface9 *mSavedRenderTarget;
+ IDirect3DSurface9 *mSavedDepthStencil;
+};
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D9_BLIT9_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp
new file mode 100644
index 0000000000..dbf875134b
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp
@@ -0,0 +1,141 @@
+//
+// 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.
+//
+
+// Buffer9.cpp Defines the Buffer9 class.
+
+#include "libANGLE/renderer/d3d/d3d9/Buffer9.h"
+
+#include "libANGLE/Context.h"
+#include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
+
+namespace rx
+{
+
+Buffer9::Buffer9(const gl::BufferState &state, Renderer9 *renderer)
+ : BufferD3D(state, renderer), mSize(0)
+{}
+
+Buffer9::~Buffer9()
+{
+ mSize = 0;
+}
+
+size_t Buffer9::getSize() const
+{
+ return mSize;
+}
+
+bool Buffer9::supportsDirectBinding() const
+{
+ return false;
+}
+
+angle::Result Buffer9::setData(const gl::Context *context,
+ gl::BufferBinding target,
+ const void *data,
+ size_t size,
+ gl::BufferUsage usage)
+{
+ if (size > mMemory.size())
+ {
+ ANGLE_CHECK_GL_ALLOC(GetImplAs<Context9>(context), mMemory.resize(size));
+ }
+
+ mSize = size;
+ if (data && size > 0)
+ {
+ memcpy(mMemory.data(), data, size);
+ }
+
+ updateD3DBufferUsage(context, usage);
+
+ invalidateStaticData(context);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Buffer9::getData(const gl::Context *context, const uint8_t **outData)
+{
+ if (mMemory.empty())
+ {
+ *outData = nullptr;
+ }
+ else
+ {
+ *outData = mMemory.data();
+ }
+ return angle::Result::Continue;
+}
+
+angle::Result Buffer9::setSubData(const gl::Context *context,
+ gl::BufferBinding target,
+ const void *data,
+ size_t size,
+ size_t offset)
+{
+ if (offset + size > mMemory.size())
+ {
+ ANGLE_CHECK_GL_ALLOC(GetImplAs<Context9>(context), mMemory.resize(size + offset));
+ }
+
+ mSize = std::max(mSize, offset + size);
+ if (data && size > 0)
+ {
+ memcpy(mMemory.data() + offset, data, size);
+ }
+
+ invalidateStaticData(context);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Buffer9::copySubData(const gl::Context *context,
+ BufferImpl *source,
+ GLintptr sourceOffset,
+ GLintptr destOffset,
+ GLsizeiptr size)
+{
+ // Note: this method is currently unreachable
+ Buffer9 *sourceBuffer = GetAs<Buffer9>(source);
+ ASSERT(sourceBuffer);
+
+ memcpy(mMemory.data() + destOffset, sourceBuffer->mMemory.data() + sourceOffset, size);
+
+ invalidateStaticData(context);
+
+ return angle::Result::Continue;
+}
+
+// We do not support buffer mapping in D3D9
+angle::Result Buffer9::map(const gl::Context *context, GLenum access, void **mapPtr)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context9>(context));
+ return angle::Result::Stop;
+}
+
+angle::Result Buffer9::mapRange(const gl::Context *context,
+ size_t offset,
+ size_t length,
+ GLbitfield access,
+ void **mapPtr)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context9>(context));
+ return angle::Result::Stop;
+}
+
+angle::Result Buffer9::unmap(const gl::Context *context, GLboolean *result)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context9>(context));
+ return angle::Result::Stop;
+}
+
+angle::Result Buffer9::markTransformFeedbackUsage(const gl::Context *context)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context9>(context));
+ return angle::Result::Stop;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Buffer9.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Buffer9.h
new file mode 100644
index 0000000000..dad120d75b
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Buffer9.h
@@ -0,0 +1,63 @@
+//
+// 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.
+//
+
+// Buffer9.h: Defines the rx::Buffer9 class which implements rx::BufferImpl via rx::BufferD3D.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D9_BUFFER9_H_
+#define LIBANGLE_RENDERER_D3D_D3D9_BUFFER9_H_
+
+#include "common/MemoryBuffer.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/renderer/d3d/BufferD3D.h"
+
+namespace rx
+{
+class Renderer9;
+
+class Buffer9 : public BufferD3D
+{
+ public:
+ Buffer9(const gl::BufferState &state, Renderer9 *renderer);
+ ~Buffer9() override;
+
+ // BufferD3D implementation
+ size_t getSize() const override;
+ bool supportsDirectBinding() const override;
+ angle::Result getData(const gl::Context *context, const uint8_t **outData) override;
+
+ // BufferImpl implementation
+ angle::Result setData(const gl::Context *context,
+ gl::BufferBinding target,
+ const void *data,
+ size_t size,
+ gl::BufferUsage usage) override;
+ angle::Result setSubData(const gl::Context *context,
+ gl::BufferBinding target,
+ const void *data,
+ size_t size,
+ size_t offset) override;
+ angle::Result copySubData(const gl::Context *context,
+ BufferImpl *source,
+ GLintptr sourceOffset,
+ GLintptr destOffset,
+ GLsizeiptr size) override;
+ angle::Result map(const gl::Context *context, GLenum access, void **mapPtr) override;
+ angle::Result mapRange(const gl::Context *context,
+ size_t offset,
+ size_t length,
+ GLbitfield access,
+ void **mapPtr) override;
+ angle::Result unmap(const gl::Context *context, GLboolean *result) override;
+ angle::Result markTransformFeedbackUsage(const gl::Context *context) override;
+
+ private:
+ angle::MemoryBuffer mMemory;
+ size_t mSize;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D9_BUFFER9_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Context9.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Context9.cpp
new file mode 100644
index 0000000000..b879d9c93b
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Context9.cpp
@@ -0,0 +1,529 @@
+//
+// 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.
+//
+// Context9:
+// D3D9-specific functionality associated with a GL Context.
+//
+
+#include "libANGLE/renderer/d3d/d3d9/Context9.h"
+
+#include "common/entry_points_enum_autogen.h"
+#include "common/string_utils.h"
+#include "libANGLE/renderer/OverlayImpl.h"
+#include "libANGLE/renderer/d3d/CompilerD3D.h"
+#include "libANGLE/renderer/d3d/ProgramD3D.h"
+#include "libANGLE/renderer/d3d/RenderbufferD3D.h"
+#include "libANGLE/renderer/d3d/SamplerD3D.h"
+#include "libANGLE/renderer/d3d/ShaderD3D.h"
+#include "libANGLE/renderer/d3d/TextureD3D.h"
+#include "libANGLE/renderer/d3d/d3d9/Buffer9.h"
+#include "libANGLE/renderer/d3d/d3d9/Fence9.h"
+#include "libANGLE/renderer/d3d/d3d9/Framebuffer9.h"
+#include "libANGLE/renderer/d3d/d3d9/Query9.h"
+#include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
+#include "libANGLE/renderer/d3d/d3d9/StateManager9.h"
+#include "libANGLE/renderer/d3d/d3d9/VertexArray9.h"
+
+namespace rx
+{
+
+Context9::Context9(const gl::State &state, gl::ErrorSet *errorSet, Renderer9 *renderer)
+ : ContextD3D(state, errorSet), mRenderer(renderer)
+{}
+
+Context9::~Context9() {}
+
+angle::Result Context9::initialize()
+{
+ return angle::Result::Continue;
+}
+
+void Context9::onDestroy(const gl::Context *context)
+{
+ mIncompleteTextures.onDestroy(context);
+}
+
+CompilerImpl *Context9::createCompiler()
+{
+ return new CompilerD3D(SH_HLSL_3_0_OUTPUT);
+}
+
+ShaderImpl *Context9::createShader(const gl::ShaderState &data)
+{
+ return new ShaderD3D(data, mRenderer);
+}
+
+ProgramImpl *Context9::createProgram(const gl::ProgramState &data)
+{
+ return new ProgramD3D(data, mRenderer);
+}
+
+FramebufferImpl *Context9::createFramebuffer(const gl::FramebufferState &data)
+{
+ return new Framebuffer9(data, mRenderer);
+}
+
+TextureImpl *Context9::createTexture(const gl::TextureState &state)
+{
+ switch (state.getType())
+ {
+ case gl::TextureType::_2D:
+ // GL_TEXTURE_VIDEO_IMAGE_WEBGL maps to 2D texture on Windows platform.
+ case gl::TextureType::VideoImage:
+ return new TextureD3D_2D(state, mRenderer);
+ case gl::TextureType::CubeMap:
+ return new TextureD3D_Cube(state, mRenderer);
+ case gl::TextureType::External:
+ return new TextureD3D_External(state, mRenderer);
+ default:
+ UNREACHABLE();
+ }
+ return nullptr;
+}
+
+RenderbufferImpl *Context9::createRenderbuffer(const gl::RenderbufferState &state)
+{
+ return new RenderbufferD3D(state, mRenderer);
+}
+
+BufferImpl *Context9::createBuffer(const gl::BufferState &state)
+{
+ return new Buffer9(state, mRenderer);
+}
+
+VertexArrayImpl *Context9::createVertexArray(const gl::VertexArrayState &data)
+{
+ return new VertexArray9(data);
+}
+
+QueryImpl *Context9::createQuery(gl::QueryType type)
+{
+ return new Query9(mRenderer, type);
+}
+
+FenceNVImpl *Context9::createFenceNV()
+{
+ return new FenceNV9(mRenderer);
+}
+
+SyncImpl *Context9::createSync()
+{
+ // D3D9 doesn't support ES 3.0 and its sync objects.
+ UNREACHABLE();
+ return nullptr;
+}
+
+TransformFeedbackImpl *Context9::createTransformFeedback(const gl::TransformFeedbackState &state)
+{
+ UNREACHABLE();
+ return nullptr;
+}
+
+SamplerImpl *Context9::createSampler(const gl::SamplerState &state)
+{
+ return new SamplerD3D(state);
+}
+
+ProgramPipelineImpl *Context9::createProgramPipeline(const gl::ProgramPipelineState &data)
+{
+ UNREACHABLE();
+ return nullptr;
+}
+
+MemoryObjectImpl *Context9::createMemoryObject()
+{
+ UNREACHABLE();
+ return nullptr;
+}
+
+SemaphoreImpl *Context9::createSemaphore()
+{
+ UNREACHABLE();
+ return nullptr;
+}
+
+OverlayImpl *Context9::createOverlay(const gl::OverlayState &state)
+{
+ // Not implemented.
+ return new OverlayImpl(state);
+}
+
+angle::Result Context9::flush(const gl::Context *context)
+{
+ return mRenderer->flush(context);
+}
+
+angle::Result Context9::finish(const gl::Context *context)
+{
+ return mRenderer->finish(context);
+}
+
+angle::Result Context9::drawArrays(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLint first,
+ GLsizei count)
+{
+ return mRenderer->genericDrawArrays(context, mode, first, count, 0);
+}
+
+angle::Result Context9::drawArraysInstanced(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLint first,
+ GLsizei count,
+ GLsizei instanceCount)
+{
+ return mRenderer->genericDrawArrays(context, mode, first, count, instanceCount);
+}
+
+angle::Result Context9::drawArraysInstancedBaseInstance(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLint first,
+ GLsizei count,
+ GLsizei instanceCount,
+ GLuint baseInstance)
+{
+ ANGLE_HR_UNREACHABLE(this);
+ return angle::Result::Continue;
+}
+
+angle::Result Context9::drawElements(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices)
+{
+ return mRenderer->genericDrawElements(context, mode, count, type, indices, 0);
+}
+
+angle::Result Context9::drawElementsBaseVertex(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices,
+ GLint baseVertex)
+{
+ ANGLE_HR_UNREACHABLE(this);
+ return angle::Result::Continue;
+}
+
+angle::Result Context9::drawElementsInstanced(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices,
+ GLsizei instances)
+{
+ return mRenderer->genericDrawElements(context, mode, count, type, indices, instances);
+}
+
+angle::Result Context9::drawElementsInstancedBaseVertex(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices,
+ GLsizei instances,
+ GLint baseVertex)
+{
+ ANGLE_HR_UNREACHABLE(this);
+ return angle::Result::Continue;
+}
+
+angle::Result Context9::drawElementsInstancedBaseVertexBaseInstance(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices,
+ GLsizei instances,
+ GLint baseVertex,
+ GLuint baseInstance)
+{
+ ANGLE_HR_UNREACHABLE(this);
+ return angle::Result::Continue;
+}
+
+angle::Result Context9::drawRangeElements(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices)
+{
+ return mRenderer->genericDrawElements(context, mode, count, type, indices, 0);
+}
+
+angle::Result Context9::drawRangeElementsBaseVertex(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices,
+ GLint baseVertex)
+{
+ ANGLE_HR_UNREACHABLE(this);
+ return angle::Result::Continue;
+}
+
+angle::Result Context9::drawArraysIndirect(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const void *indirect)
+{
+ ANGLE_HR_UNREACHABLE(this);
+ return angle::Result::Stop;
+}
+
+angle::Result Context9::drawElementsIndirect(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ gl::DrawElementsType type,
+ const void *indirect)
+{
+ ANGLE_HR_UNREACHABLE(this);
+ return angle::Result::Stop;
+}
+
+angle::Result Context9::multiDrawArrays(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const GLint *firsts,
+ const GLsizei *counts,
+ GLsizei drawcount)
+{
+ return rx::MultiDrawArraysGeneral(this, context, mode, firsts, counts, drawcount);
+}
+
+angle::Result Context9::multiDrawArraysInstanced(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const GLint *firsts,
+ const GLsizei *counts,
+ const GLsizei *instanceCounts,
+ GLsizei drawcount)
+{
+ return rx::MultiDrawArraysInstancedGeneral(this, context, mode, firsts, counts, instanceCounts,
+ drawcount);
+}
+
+angle::Result Context9::multiDrawArraysIndirect(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const void *indirect,
+ GLsizei drawcount,
+ GLsizei stride)
+{
+ UNREACHABLE();
+ return angle::Result::Stop;
+}
+
+angle::Result Context9::multiDrawElements(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const GLsizei *counts,
+ gl::DrawElementsType type,
+ const GLvoid *const *indices,
+ GLsizei drawcount)
+{
+ return rx::MultiDrawElementsGeneral(this, context, mode, counts, type, indices, drawcount);
+}
+
+angle::Result Context9::multiDrawElementsInstanced(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const GLsizei *counts,
+ gl::DrawElementsType type,
+ const GLvoid *const *indices,
+ const GLsizei *instanceCounts,
+ GLsizei drawcount)
+{
+ return rx::MultiDrawElementsInstancedGeneral(this, context, mode, counts, type, indices,
+ instanceCounts, drawcount);
+}
+
+angle::Result Context9::multiDrawElementsIndirect(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ gl::DrawElementsType type,
+ const void *indirect,
+ GLsizei drawcount,
+ GLsizei stride)
+{
+ UNREACHABLE();
+ return angle::Result::Stop;
+}
+
+angle::Result Context9::multiDrawArraysInstancedBaseInstance(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const GLint *firsts,
+ const GLsizei *counts,
+ const GLsizei *instanceCounts,
+ const GLuint *baseInstances,
+ GLsizei drawcount)
+{
+ ANGLE_HR_UNREACHABLE(this);
+ return angle::Result::Stop;
+}
+
+angle::Result Context9::multiDrawElementsInstancedBaseVertexBaseInstance(
+ const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const GLsizei *counts,
+ gl::DrawElementsType type,
+ const GLvoid *const *indices,
+ const GLsizei *instanceCounts,
+ const GLint *baseVertices,
+ const GLuint *baseInstances,
+ GLsizei drawcount)
+{
+ ANGLE_HR_UNREACHABLE(this);
+ return angle::Result::Stop;
+}
+
+gl::GraphicsResetStatus Context9::getResetStatus()
+{
+ return mRenderer->getResetStatus();
+}
+
+angle::Result Context9::insertEventMarker(GLsizei length, const char *marker)
+{
+ mRenderer->getAnnotator()->setMarker(/*context=*/nullptr, marker);
+ return angle::Result::Continue;
+}
+
+angle::Result Context9::pushGroupMarker(GLsizei length, const char *marker)
+{
+ mRenderer->getAnnotator()->beginEvent(nullptr, angle::EntryPoint::GLPushGroupMarkerEXT, marker,
+ marker);
+ mMarkerStack.push(std::string(marker));
+ return angle::Result::Continue;
+}
+
+angle::Result Context9::popGroupMarker()
+{
+ const char *marker = nullptr;
+ if (!mMarkerStack.empty())
+ {
+ marker = mMarkerStack.top().c_str();
+ mMarkerStack.pop();
+ mRenderer->getAnnotator()->endEvent(nullptr, marker,
+ angle::EntryPoint::GLPopGroupMarkerEXT);
+ }
+ return angle::Result::Continue;
+}
+
+angle::Result Context9::pushDebugGroup(const gl::Context *context,
+ GLenum source,
+ GLuint id,
+ const std::string &message)
+{
+ // Fall through to the EXT_debug_marker functions
+ return pushGroupMarker(static_cast<GLsizei>(message.size()), message.c_str());
+}
+
+angle::Result Context9::popDebugGroup(const gl::Context *context)
+{
+ // Fall through to the EXT_debug_marker functions
+ return popGroupMarker();
+}
+
+angle::Result Context9::syncState(const gl::Context *context,
+ const gl::State::DirtyBits &dirtyBits,
+ const gl::State::DirtyBits &bitMask,
+ gl::Command command)
+{
+ mRenderer->getStateManager()->syncState(mState, dirtyBits);
+ return angle::Result::Continue;
+}
+
+GLint Context9::getGPUDisjoint()
+{
+ return mRenderer->getGPUDisjoint();
+}
+
+GLint64 Context9::getTimestamp()
+{
+ return mRenderer->getTimestamp();
+}
+
+angle::Result Context9::onMakeCurrent(const gl::Context *context)
+{
+ mRenderer->getStateManager()->setAllDirtyBits();
+ return mRenderer->ensureVertexDataManagerInitialized(context);
+}
+
+gl::Caps Context9::getNativeCaps() const
+{
+ return mRenderer->getNativeCaps();
+}
+
+const gl::TextureCapsMap &Context9::getNativeTextureCaps() const
+{
+ return mRenderer->getNativeTextureCaps();
+}
+
+const gl::Extensions &Context9::getNativeExtensions() const
+{
+ return mRenderer->getNativeExtensions();
+}
+
+const gl::Limitations &Context9::getNativeLimitations() const
+{
+ return mRenderer->getNativeLimitations();
+}
+
+ShPixelLocalStorageType Context9::getNativePixelLocalStorageType() const
+{
+ return mRenderer->getNativePixelLocalStorageType();
+}
+
+angle::Result Context9::dispatchCompute(const gl::Context *context,
+ GLuint numGroupsX,
+ GLuint numGroupsY,
+ GLuint numGroupsZ)
+{
+ ANGLE_HR_UNREACHABLE(this);
+ return angle::Result::Stop;
+}
+
+angle::Result Context9::dispatchComputeIndirect(const gl::Context *context, GLintptr indirect)
+{
+ ANGLE_HR_UNREACHABLE(this);
+ return angle::Result::Stop;
+}
+
+angle::Result Context9::memoryBarrier(const gl::Context *context, GLbitfield barriers)
+{
+ ANGLE_HR_UNREACHABLE(this);
+ return angle::Result::Stop;
+}
+
+angle::Result Context9::memoryBarrierByRegion(const gl::Context *context, GLbitfield barriers)
+{
+ ANGLE_HR_UNREACHABLE(this);
+ return angle::Result::Stop;
+}
+
+angle::Result Context9::getIncompleteTexture(const gl::Context *context,
+ gl::TextureType type,
+ gl::Texture **textureOut)
+{
+ return mIncompleteTextures.getIncompleteTexture(context, type, gl::SamplerFormat::Float,
+ nullptr, textureOut);
+}
+
+void Context9::handleResult(HRESULT hr,
+ const char *message,
+ const char *file,
+ const char *function,
+ unsigned int line)
+{
+ ASSERT(FAILED(hr));
+
+ if (d3d9::isDeviceLostError(hr))
+ {
+ mRenderer->notifyDeviceLost();
+ }
+
+ GLenum glErrorCode = DefaultGLErrorCode(hr);
+
+ std::stringstream errorStream;
+ errorStream << "Internal D3D9 error: " << gl::FmtHR(hr) << ": " << message;
+
+ mErrors->handleError(glErrorCode, errorStream.str().c_str(), file, function, line);
+}
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Context9.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Context9.h
new file mode 100644
index 0000000000..ce3e930295
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Context9.h
@@ -0,0 +1,265 @@
+//
+// 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.
+//
+// Context9:
+// D3D9-specific functionality associated with a GL Context.
+//
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D9_CONTEXT9_H_
+#define LIBANGLE_RENDERER_D3D_D3D9_CONTEXT9_H_
+
+#include <stack>
+#include "libANGLE/renderer/d3d/ContextD3D.h"
+
+namespace rx
+{
+class Renderer9;
+
+class Context9 : public ContextD3D
+{
+ public:
+ Context9(const gl::State &state, gl::ErrorSet *errorSet, Renderer9 *renderer);
+ ~Context9() override;
+
+ angle::Result initialize() override;
+ void onDestroy(const gl::Context *context) override;
+
+ // 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(const gl::RenderbufferState &state) override;
+
+ // Buffer creation
+ BufferImpl *createBuffer(const gl::BufferState &state) override;
+
+ // Vertex Array creation
+ VertexArrayImpl *createVertexArray(const gl::VertexArrayState &data) override;
+
+ // Query and Fence creation
+ QueryImpl *createQuery(gl::QueryType type) override;
+ FenceNVImpl *createFenceNV() override;
+ SyncImpl *createSync() override;
+
+ // Transform Feedback creation
+ TransformFeedbackImpl *createTransformFeedback(
+ const gl::TransformFeedbackState &state) override;
+
+ // Sampler object creation
+ SamplerImpl *createSampler(const gl::SamplerState &state) override;
+
+ // Program Pipeline object creation
+ ProgramPipelineImpl *createProgramPipeline(const gl::ProgramPipelineState &data) override;
+
+ // Memory object creation.
+ MemoryObjectImpl *createMemoryObject() override;
+
+ // Semaphore creation.
+ SemaphoreImpl *createSemaphore() override;
+
+ // Overlay creation.
+ OverlayImpl *createOverlay(const gl::OverlayState &state) override;
+
+ // Flush and finish.
+ angle::Result flush(const gl::Context *context) override;
+ angle::Result finish(const gl::Context *context) override;
+
+ // Drawing methods.
+ angle::Result drawArrays(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLint first,
+ GLsizei count) override;
+ angle::Result drawArraysInstanced(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLint first,
+ GLsizei count,
+ GLsizei instanceCount) override;
+ angle::Result drawArraysInstancedBaseInstance(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLint first,
+ GLsizei count,
+ GLsizei instanceCount,
+ GLuint baseInstance) override;
+
+ angle::Result drawElements(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices) override;
+ angle::Result drawElementsBaseVertex(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices,
+ GLint baseVertex) override;
+ angle::Result drawElementsInstanced(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices,
+ GLsizei instances) override;
+ angle::Result drawElementsInstancedBaseVertex(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices,
+ GLsizei instances,
+ GLint baseVertex) override;
+ angle::Result drawElementsInstancedBaseVertexBaseInstance(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices,
+ GLsizei instances,
+ GLint baseVertex,
+ GLuint baseInstance) override;
+ angle::Result drawRangeElements(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices) override;
+ angle::Result drawRangeElementsBaseVertex(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices,
+ GLint baseVertex) override;
+ angle::Result drawArraysIndirect(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const void *indirect) override;
+ angle::Result drawElementsIndirect(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ gl::DrawElementsType type,
+ const void *indirect) override;
+
+ angle::Result multiDrawArrays(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const GLint *firsts,
+ const GLsizei *counts,
+ GLsizei drawcount) override;
+ angle::Result multiDrawArraysInstanced(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const GLint *firsts,
+ const GLsizei *counts,
+ const GLsizei *instanceCounts,
+ GLsizei drawcount) override;
+ angle::Result multiDrawArraysIndirect(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const void *indirect,
+ GLsizei drawcount,
+ GLsizei stride) override;
+ angle::Result multiDrawElements(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const GLsizei *counts,
+ gl::DrawElementsType type,
+ const GLvoid *const *indices,
+ GLsizei drawcount) override;
+ angle::Result multiDrawElementsInstanced(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const GLsizei *counts,
+ gl::DrawElementsType type,
+ const GLvoid *const *indices,
+ const GLsizei *instanceCounts,
+ GLsizei drawcount) override;
+ angle::Result multiDrawElementsIndirect(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ gl::DrawElementsType type,
+ const void *indirect,
+ GLsizei drawcount,
+ GLsizei stride) override;
+ angle::Result multiDrawArraysInstancedBaseInstance(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const GLint *firsts,
+ const GLsizei *counts,
+ const GLsizei *instanceCounts,
+ const GLuint *baseInstances,
+ GLsizei drawcount) override;
+ angle::Result multiDrawElementsInstancedBaseVertexBaseInstance(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const GLsizei *counts,
+ gl::DrawElementsType type,
+ const GLvoid *const *indices,
+ const GLsizei *instanceCounts,
+ const GLint *baseVertices,
+ const GLuint *baseInstances,
+ GLsizei drawcount) override;
+
+ // Device loss
+ gl::GraphicsResetStatus getResetStatus() override;
+
+ // EXT_debug_marker
+ angle::Result insertEventMarker(GLsizei length, const char *marker) override;
+ angle::Result pushGroupMarker(GLsizei length, const char *marker) override;
+ angle::Result popGroupMarker() override;
+
+ // KHR_debug
+ angle::Result pushDebugGroup(const gl::Context *context,
+ GLenum source,
+ GLuint id,
+ const std::string &message) override;
+ angle::Result popDebugGroup(const gl::Context *context) override;
+
+ // State sync with dirty bits.
+ angle::Result syncState(const gl::Context *context,
+ const gl::State::DirtyBits &dirtyBits,
+ const gl::State::DirtyBits &bitMask,
+ gl::Command command) override;
+
+ // Disjoint timer queries
+ GLint getGPUDisjoint() override;
+ GLint64 getTimestamp() override;
+
+ // Context switching
+ angle::Result onMakeCurrent(const gl::Context *context) override;
+
+ // Caps queries
+ gl::Caps getNativeCaps() const override;
+ const gl::TextureCapsMap &getNativeTextureCaps() const override;
+ const gl::Extensions &getNativeExtensions() const override;
+ const gl::Limitations &getNativeLimitations() const override;
+ ShPixelLocalStorageType getNativePixelLocalStorageType() const override;
+
+ angle::Result dispatchCompute(const gl::Context *context,
+ GLuint numGroupsX,
+ GLuint numGroupsY,
+ GLuint numGroupsZ) override;
+ angle::Result dispatchComputeIndirect(const gl::Context *context, GLintptr indirect) override;
+
+ angle::Result memoryBarrier(const gl::Context *context, GLbitfield barriers) override;
+ angle::Result memoryBarrierByRegion(const gl::Context *context, GLbitfield barriers) override;
+
+ Renderer9 *getRenderer() const { return mRenderer; }
+
+ angle::Result getIncompleteTexture(const gl::Context *context,
+ gl::TextureType type,
+ gl::Texture **textureOut);
+
+ void handleResult(HRESULT hr,
+ const char *message,
+ const char *file,
+ const char *function,
+ unsigned int line) override;
+
+ private:
+ Renderer9 *mRenderer;
+ IncompleteTextureSet mIncompleteTextures;
+ std::stack<std::string> mMarkerStack;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D9_CONTEXT9_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.cpp
new file mode 100644
index 0000000000..7e597e564b
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.cpp
@@ -0,0 +1,48 @@
+//
+// 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.
+//
+// DebugAnnotator9.h: D3D9 helpers for adding trace annotations.
+//
+
+#include "libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h"
+
+#include "common/platform.h"
+
+namespace rx
+{
+
+void DebugAnnotator9::beginEvent(gl::Context *context,
+ angle::EntryPoint entryPoint,
+ const char *eventName,
+ const char *eventMessage)
+{
+ angle::LoggingAnnotator::beginEvent(context, entryPoint, eventName, eventMessage);
+ std::mbstate_t state = std::mbstate_t();
+ std::mbsrtowcs(mWCharMessage, &eventMessage, kMaxMessageLength, &state);
+ D3DPERF_BeginEvent(0, mWCharMessage);
+}
+
+void DebugAnnotator9::endEvent(gl::Context *context,
+ const char *eventName,
+ angle::EntryPoint entryPoint)
+{
+ angle::LoggingAnnotator::endEvent(context, eventName, entryPoint);
+ D3DPERF_EndEvent();
+}
+
+void DebugAnnotator9::setMarker(gl::Context *context, const char *markerName)
+{
+ angle::LoggingAnnotator::setMarker(context, markerName);
+ std::mbstate_t state = std::mbstate_t();
+ std::mbsrtowcs(mWCharMessage, &markerName, kMaxMessageLength, &state);
+ D3DPERF_SetMarker(0, mWCharMessage);
+}
+
+bool DebugAnnotator9::getStatus(const gl::Context *context)
+{
+ return !!D3DPERF_GetStatus();
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h
new file mode 100644
index 0000000000..40f8189bea
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h
@@ -0,0 +1,38 @@
+//
+// 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.
+//
+// DebugAnnotator9.h: D3D9 helpers for adding trace annotations.
+//
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D9_DEBUGANNOTATOR9_H_
+#define LIBANGLE_RENDERER_D3D_D3D9_DEBUGANNOTATOR9_H_
+
+#include "libANGLE/LoggingAnnotator.h"
+
+namespace rx
+{
+
+class DebugAnnotator9 : public angle::LoggingAnnotator
+{
+ public:
+ DebugAnnotator9() {}
+ void beginEvent(gl::Context *context,
+ angle::EntryPoint entryPoint,
+ const char *eventName,
+ const char *eventMessage) override;
+ void endEvent(gl::Context *context,
+ const char *eventName,
+ angle::EntryPoint entryPoint) override;
+ void setMarker(gl::Context *context, const char *markerName) override;
+ bool getStatus(const gl::Context *context) override;
+
+ private:
+ static constexpr size_t kMaxMessageLength = 256;
+ wchar_t mWCharMessage[kMaxMessageLength];
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D9_DEBUGANNOTATOR9_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Fence9.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Fence9.cpp
new file mode 100644
index 0000000000..e844a9ae70
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Fence9.cpp
@@ -0,0 +1,73 @@
+//
+// Copyright 2013 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.
+//
+
+// Fence9.cpp: Defines the rx::FenceNV9 class.
+
+#include "libANGLE/renderer/d3d/d3d9/Fence9.h"
+
+#include "libANGLE/Context.h"
+#include "libANGLE/renderer/d3d/d3d9/Context9.h"
+#include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
+#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h"
+
+namespace rx
+{
+
+FenceNV9::FenceNV9(Renderer9 *renderer) : FenceNVImpl(), mRenderer(renderer), mQuery(nullptr) {}
+
+FenceNV9::~FenceNV9()
+{
+ SafeRelease(mQuery);
+}
+
+angle::Result FenceNV9::set(const gl::Context *context, GLenum condition)
+{
+ if (!mQuery)
+ {
+ ANGLE_TRY(mRenderer->allocateEventQuery(context, &mQuery));
+ }
+
+ HRESULT result = mQuery->Issue(D3DISSUE_END);
+ if (FAILED(result))
+ {
+ SafeRelease(mQuery);
+ }
+ ANGLE_TRY_HR(GetImplAs<Context9>(context), result, "Failed to end event query");
+ return angle::Result::Continue;
+}
+
+angle::Result FenceNV9::test(const gl::Context *context, GLboolean *outFinished)
+{
+ return testHelper(GetImplAs<Context9>(context), true, outFinished);
+}
+
+angle::Result FenceNV9::finish(const gl::Context *context)
+{
+ GLboolean finished = GL_FALSE;
+ while (finished != GL_TRUE)
+ {
+ ANGLE_TRY(testHelper(GetImplAs<Context9>(context), true, &finished));
+ Sleep(0);
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result FenceNV9::testHelper(Context9 *context9,
+ bool flushCommandBuffer,
+ GLboolean *outFinished)
+{
+ ASSERT(mQuery);
+
+ DWORD getDataFlags = (flushCommandBuffer ? D3DGETDATA_FLUSH : 0);
+ HRESULT result = mQuery->GetData(nullptr, 0, getDataFlags);
+ ANGLE_TRY_HR(context9, result, "Failed to get query data");
+ ASSERT(result == S_OK || result == S_FALSE);
+ *outFinished = ((result == S_OK) ? GL_TRUE : GL_FALSE);
+ return angle::Result::Continue;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Fence9.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Fence9.h
new file mode 100644
index 0000000000..c46671c102
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Fence9.h
@@ -0,0 +1,39 @@
+//
+// Copyright 2013 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.
+//
+
+// Fence9.h: Defines the rx::FenceNV9 class which implements rx::FenceNVImpl.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D9_FENCE9_H_
+#define LIBANGLE_RENDERER_D3D_D3D9_FENCE9_H_
+
+#include "libANGLE/renderer/FenceNVImpl.h"
+#include "libANGLE/renderer/SyncImpl.h"
+
+namespace rx
+{
+class Context9;
+class Renderer9;
+
+class FenceNV9 : public FenceNVImpl
+{
+ public:
+ explicit FenceNV9(Renderer9 *renderer);
+ ~FenceNV9() override;
+
+ void onDestroy(const gl::Context *context) override {}
+ angle::Result set(const gl::Context *context, GLenum condition) override;
+ angle::Result test(const gl::Context *context, GLboolean *outFinished) override;
+ angle::Result finish(const gl::Context *context) override;
+
+ private:
+ angle::Result testHelper(Context9 *context9, bool flushCommandBuffer, GLboolean *outFinished);
+
+ Renderer9 *mRenderer;
+ IDirect3DQuery9 *mQuery;
+};
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D9_FENCE9_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp
new file mode 100644
index 0000000000..f90fefac20
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp
@@ -0,0 +1,416 @@
+//
+// 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.
+//
+
+// Framebuffer9.cpp: Implements the Framebuffer9 class.
+
+#include "libANGLE/renderer/d3d/d3d9/Framebuffer9.h"
+
+#include "libANGLE/Context.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/Texture.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/ContextImpl.h"
+#include "libANGLE/renderer/d3d/TextureD3D.h"
+#include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h"
+#include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
+#include "libANGLE/renderer/d3d/d3d9/TextureStorage9.h"
+#include "libANGLE/renderer/d3d/d3d9/formatutils9.h"
+#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h"
+#include "libANGLE/renderer/renderer_utils.h"
+
+namespace rx
+{
+Framebuffer9::Framebuffer9(const gl::FramebufferState &data, Renderer9 *renderer)
+ : FramebufferD3D(data, renderer), mRenderer(renderer)
+{
+ ASSERT(mRenderer != nullptr);
+}
+
+Framebuffer9::~Framebuffer9() {}
+
+angle::Result Framebuffer9::discard(const gl::Context *context,
+ size_t count,
+ const GLenum *attachments)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context9>(context));
+ return angle::Result::Stop;
+}
+
+angle::Result Framebuffer9::invalidate(const gl::Context *context,
+ size_t count,
+ const GLenum *attachments)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context9>(context));
+ return angle::Result::Stop;
+}
+
+angle::Result Framebuffer9::invalidateSub(const gl::Context *context,
+ size_t count,
+ const GLenum *attachments,
+ const gl::Rectangle &area)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context9>(context));
+ return angle::Result::Stop;
+}
+
+angle::Result Framebuffer9::clearImpl(const gl::Context *context,
+ const ClearParameters &clearParams)
+{
+ ANGLE_TRY(mRenderer->applyRenderTarget(context, mRenderTargetCache.getColors()[0],
+ mRenderTargetCache.getDepthStencil()));
+
+ const gl::State &glState = context->getState();
+ float nearZ = glState.getNearPlane();
+ float farZ = glState.getFarPlane();
+ mRenderer->setViewport(glState.getViewport(), nearZ, farZ, gl::PrimitiveMode::Triangles,
+ glState.getRasterizerState().frontFace, true);
+
+ mRenderer->setScissorRectangle(glState.getScissor(), glState.isScissorTestEnabled());
+
+ mRenderer->clear(clearParams, mRenderTargetCache.getColors()[0],
+ mRenderTargetCache.getDepthStencil());
+ return angle::Result::Continue;
+}
+
+angle::Result Framebuffer9::readPixelsImpl(const gl::Context *context,
+ const gl::Rectangle &area,
+ GLenum format,
+ GLenum type,
+ size_t outputPitch,
+ const gl::PixelPackState &pack,
+ gl::Buffer *packBuffer,
+ uint8_t *pixels)
+{
+ const gl::FramebufferAttachment *colorbuffer = mState.getColorAttachment(0);
+ ASSERT(colorbuffer);
+
+ RenderTarget9 *renderTarget = nullptr;
+ ANGLE_TRY(colorbuffer->getRenderTarget(context, 0, &renderTarget));
+ ASSERT(renderTarget);
+
+ IDirect3DSurface9 *surface = renderTarget->getSurface();
+ ASSERT(surface);
+
+ D3DSURFACE_DESC desc;
+ surface->GetDesc(&desc);
+
+ Context9 *context9 = GetImplAs<Context9>(context);
+
+ if (desc.MultiSampleType != D3DMULTISAMPLE_NONE)
+ {
+ UNIMPLEMENTED(); // FIXME: Requires resolve using StretchRect into non-multisampled render
+ // target
+ SafeRelease(surface);
+ ANGLE_TRY_HR(context9, E_OUTOFMEMORY,
+ "ReadPixels is unimplemented for multisampled framebuffer attachments.");
+ }
+
+ IDirect3DDevice9 *device = mRenderer->getDevice();
+ ASSERT(device);
+
+ HRESULT result;
+ IDirect3DSurface9 *systemSurface = nullptr;
+ bool directToPixels =
+ !pack.reverseRowOrder && pack.alignment <= 4 && mRenderer->getShareHandleSupport() &&
+ area.x == 0 && area.y == 0 && static_cast<UINT>(area.width) == desc.Width &&
+ static_cast<UINT>(area.height) == desc.Height && desc.Format == D3DFMT_A8R8G8B8 &&
+ format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE;
+ if (directToPixels)
+ {
+ // Use the pixels ptr as a shared handle to write directly into client's memory
+ result = device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format,
+ D3DPOOL_SYSTEMMEM, &systemSurface,
+ reinterpret_cast<void **>(&pixels));
+ if (FAILED(result))
+ {
+ // Try again without the shared handle
+ directToPixels = false;
+ }
+ }
+
+ if (!directToPixels)
+ {
+ result = device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format,
+ D3DPOOL_SYSTEMMEM, &systemSurface, nullptr);
+ if (FAILED(result))
+ {
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+ SafeRelease(surface);
+ ANGLE_TRY_HR(context9, E_OUTOFMEMORY,
+ "Failed to allocate internal texture for ReadPixels.");
+ }
+ }
+
+ result = device->GetRenderTargetData(surface, systemSurface);
+ SafeRelease(surface);
+
+ if (FAILED(result))
+ {
+ SafeRelease(systemSurface);
+
+ // It turns out that D3D will sometimes produce more error
+ // codes than those documented.
+ if (d3d9::isDeviceLostError(result))
+ {
+ mRenderer->notifyDeviceLost();
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+
+ ANGLE_TRY_HR(context9, E_OUTOFMEMORY, "Failed to read internal render target data.");
+ }
+
+ if (directToPixels)
+ {
+ SafeRelease(systemSurface);
+ return angle::Result::Continue;
+ }
+
+ RECT rect;
+ rect.left = gl::clamp(area.x, 0L, static_cast<LONG>(desc.Width));
+ rect.top = gl::clamp(area.y, 0L, static_cast<LONG>(desc.Height));
+ rect.right = gl::clamp(area.x + area.width, 0L, static_cast<LONG>(desc.Width));
+ rect.bottom = gl::clamp(area.y + area.height, 0L, static_cast<LONG>(desc.Height));
+
+ D3DLOCKED_RECT lock;
+ result = systemSurface->LockRect(&lock, &rect, D3DLOCK_READONLY);
+
+ if (FAILED(result))
+ {
+ UNREACHABLE();
+ SafeRelease(systemSurface);
+
+ ANGLE_TRY_HR(context9, E_OUTOFMEMORY, "Failed to lock internal render target.");
+ }
+
+ uint8_t *source = static_cast<uint8_t *>(lock.pBits);
+ int inputPitch = lock.Pitch;
+
+ const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(desc.Format);
+
+ gl::FormatType formatType(format, type);
+
+ PackPixelsParams packParams;
+ packParams.area.x = rect.left;
+ packParams.area.y = rect.top;
+ packParams.area.width = rect.right - rect.left;
+ packParams.area.height = rect.bottom - rect.top;
+ packParams.destFormat = &GetFormatFromFormatType(format, type);
+ packParams.outputPitch = static_cast<GLuint>(outputPitch);
+ packParams.reverseRowOrder = pack.reverseRowOrder;
+
+ PackPixels(packParams, d3dFormatInfo.info(), inputPitch, source, pixels);
+
+ systemSurface->UnlockRect();
+ SafeRelease(systemSurface);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Framebuffer9::blitImpl(const gl::Context *context,
+ const gl::Rectangle &sourceArea,
+ const gl::Rectangle &destArea,
+ const gl::Rectangle *scissor,
+ bool blitRenderTarget,
+ bool blitDepth,
+ bool blitStencil,
+ GLenum filter,
+ const gl::Framebuffer *sourceFramebuffer)
+{
+ ASSERT(filter == GL_NEAREST);
+
+ IDirect3DDevice9 *device = mRenderer->getDevice();
+ ASSERT(device);
+
+ mRenderer->endScene();
+
+ Context9 *context9 = GetImplAs<Context9>(context);
+
+ if (blitRenderTarget)
+ {
+ const gl::FramebufferAttachment *readBuffer = sourceFramebuffer->getColorAttachment(0);
+ ASSERT(readBuffer);
+
+ RenderTarget9 *readRenderTarget = nullptr;
+ ANGLE_TRY(readBuffer->getRenderTarget(context, 0, &readRenderTarget));
+ ASSERT(readRenderTarget);
+
+ const gl::FramebufferAttachment *drawBuffer = mState.getColorAttachment(0);
+ ASSERT(drawBuffer);
+
+ RenderTarget9 *drawRenderTarget = nullptr;
+ ANGLE_TRY(
+ drawBuffer->getRenderTarget(context, drawBuffer->getSamples(), &drawRenderTarget));
+ ASSERT(drawRenderTarget);
+
+ // The getSurface calls do an AddRef so save them until after no errors are possible
+ IDirect3DSurface9 *readSurface = readRenderTarget->getSurface();
+ ASSERT(readSurface);
+
+ IDirect3DSurface9 *drawSurface = drawRenderTarget->getSurface();
+ ASSERT(drawSurface);
+
+ gl::Extents srcSize(readRenderTarget->getWidth(), readRenderTarget->getHeight(), 1);
+ gl::Extents dstSize(drawRenderTarget->getWidth(), drawRenderTarget->getHeight(), 1);
+
+ RECT srcRect;
+ srcRect.left = sourceArea.x;
+ srcRect.right = sourceArea.x + sourceArea.width;
+ srcRect.top = sourceArea.y;
+ srcRect.bottom = sourceArea.y + sourceArea.height;
+
+ RECT dstRect;
+ dstRect.left = destArea.x;
+ dstRect.right = destArea.x + destArea.width;
+ dstRect.top = destArea.y;
+ dstRect.bottom = destArea.y + destArea.height;
+
+ // Clip the rectangles to the scissor rectangle
+ if (scissor)
+ {
+ if (dstRect.left < scissor->x)
+ {
+ srcRect.left += (scissor->x - dstRect.left);
+ dstRect.left = scissor->x;
+ }
+ if (dstRect.top < scissor->y)
+ {
+ srcRect.top += (scissor->y - dstRect.top);
+ dstRect.top = scissor->y;
+ }
+ if (dstRect.right > scissor->x + scissor->width)
+ {
+ srcRect.right -= (dstRect.right - (scissor->x + scissor->width));
+ dstRect.right = scissor->x + scissor->width;
+ }
+ if (dstRect.bottom > scissor->y + scissor->height)
+ {
+ srcRect.bottom -= (dstRect.bottom - (scissor->y + scissor->height));
+ dstRect.bottom = scissor->y + scissor->height;
+ }
+ }
+
+ // Clip the rectangles to the destination size
+ if (dstRect.left < 0)
+ {
+ srcRect.left += -dstRect.left;
+ dstRect.left = 0;
+ }
+ if (dstRect.right > dstSize.width)
+ {
+ srcRect.right -= (dstRect.right - dstSize.width);
+ dstRect.right = dstSize.width;
+ }
+ if (dstRect.top < 0)
+ {
+ srcRect.top += -dstRect.top;
+ dstRect.top = 0;
+ }
+ if (dstRect.bottom > dstSize.height)
+ {
+ srcRect.bottom -= (dstRect.bottom - dstSize.height);
+ dstRect.bottom = dstSize.height;
+ }
+
+ // Clip the rectangles to the source size
+ if (srcRect.left < 0)
+ {
+ dstRect.left += -srcRect.left;
+ srcRect.left = 0;
+ }
+ if (srcRect.right > srcSize.width)
+ {
+ dstRect.right -= (srcRect.right - srcSize.width);
+ srcRect.right = srcSize.width;
+ }
+ if (srcRect.top < 0)
+ {
+ dstRect.top += -srcRect.top;
+ srcRect.top = 0;
+ }
+ if (srcRect.bottom > srcSize.height)
+ {
+ dstRect.bottom -= (srcRect.bottom - srcSize.height);
+ srcRect.bottom = srcSize.height;
+ }
+
+ HRESULT result =
+ device->StretchRect(readSurface, &srcRect, drawSurface, &dstRect, D3DTEXF_NONE);
+
+ SafeRelease(readSurface);
+ SafeRelease(drawSurface);
+
+ ANGLE_TRY_HR(context9, result, "Internal blit failed.");
+ }
+
+ if (blitDepth || blitStencil)
+ {
+ const gl::FramebufferAttachment *readBuffer =
+ sourceFramebuffer->getDepthOrStencilAttachment();
+ ASSERT(readBuffer);
+
+ RenderTarget9 *readDepthStencil = nullptr;
+ ANGLE_TRY(readBuffer->getRenderTarget(context, 0, &readDepthStencil));
+ ASSERT(readDepthStencil);
+
+ const gl::FramebufferAttachment *drawBuffer = mState.getDepthOrStencilAttachment();
+ ASSERT(drawBuffer);
+
+ RenderTarget9 *drawDepthStencil = nullptr;
+ ANGLE_TRY(
+ drawBuffer->getRenderTarget(context, drawBuffer->getSamples(), &drawDepthStencil));
+ ASSERT(drawDepthStencil);
+
+ // The getSurface calls do an AddRef so save them until after no errors are possible
+ IDirect3DSurface9 *readSurface = readDepthStencil->getSurface();
+ ASSERT(readDepthStencil);
+
+ IDirect3DSurface9 *drawSurface = drawDepthStencil->getSurface();
+ ASSERT(drawDepthStencil);
+
+ HRESULT result =
+ device->StretchRect(readSurface, nullptr, drawSurface, nullptr, D3DTEXF_NONE);
+
+ SafeRelease(readSurface);
+ SafeRelease(drawSurface);
+
+ ANGLE_TRY_HR(context9, result, "Internal blit failed.");
+ }
+
+ return angle::Result::Continue;
+}
+
+const gl::InternalFormat &Framebuffer9::getImplementationColorReadFormat(
+ const gl::Context *context) const
+{
+ GLenum sizedFormat = mState.getReadAttachment()->getFormat().info->sizedInternalFormat;
+ const d3d9::TextureFormat &textureFormat = d3d9::GetTextureFormatInfo(sizedFormat);
+ const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(textureFormat.renderFormat);
+ const angle::Format &angleFormat = angle::Format::Get(d3dFormatInfo.formatID);
+ return gl::GetSizedInternalFormatInfo(angleFormat.fboImplementationInternalFormat);
+}
+
+angle::Result Framebuffer9::getSamplePosition(const gl::Context *context,
+ size_t index,
+ GLfloat *xy) const
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context9>(context));
+ return angle::Result::Stop;
+}
+
+angle::Result Framebuffer9::syncState(const gl::Context *context,
+ GLenum binding,
+ const gl::Framebuffer::DirtyBits &dirtyBits,
+ gl::Command command)
+{
+ ANGLE_TRY(FramebufferD3D::syncState(context, binding, dirtyBits, command));
+ ANGLE_TRY(mRenderTargetCache.update(context, mState, dirtyBits));
+ return angle::Result::Continue;
+}
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h
new file mode 100644
index 0000000000..a44118ff34
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h
@@ -0,0 +1,89 @@
+//
+// 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.
+//
+
+// Framebuffer9.h: Defines the Framebuffer9 class.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D9_FRAMBUFFER9_H_
+#define LIBANGLE_RENDERER_D3D_D3D9_FRAMBUFFER9_H_
+
+#include "libANGLE/renderer/RenderTargetCache.h"
+#include "libANGLE/renderer/d3d/FramebufferD3D.h"
+#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h"
+
+namespace rx
+{
+class Renderer9;
+
+class Framebuffer9 : public FramebufferD3D
+{
+ public:
+ Framebuffer9(const gl::FramebufferState &data, Renderer9 *renderer);
+ ~Framebuffer9() override;
+
+ angle::Result discard(const gl::Context *context,
+ size_t count,
+ const GLenum *attachments) override;
+ angle::Result invalidate(const gl::Context *context,
+ size_t count,
+ const GLenum *attachments) override;
+ angle::Result invalidateSub(const gl::Context *context,
+ size_t count,
+ const GLenum *attachments,
+ const gl::Rectangle &area) override;
+
+ angle::Result getSamplePosition(const gl::Context *context,
+ size_t index,
+ GLfloat *xy) const override;
+
+ angle::Result syncState(const gl::Context *context,
+ GLenum binding,
+ const gl::Framebuffer::DirtyBits &dirtyBits,
+ gl::Command command) override;
+
+ const gl::AttachmentArray<RenderTarget9 *> &getCachedColorRenderTargets() const
+ {
+ return mRenderTargetCache.getColors();
+ }
+
+ const RenderTarget9 *getCachedDepthStencilRenderTarget() const
+ {
+ return mRenderTargetCache.getDepthStencil();
+ }
+
+ const gl::InternalFormat &getImplementationColorReadFormat(
+ const gl::Context *context) const override;
+
+ private:
+ angle::Result clearImpl(const gl::Context *context,
+ const ClearParameters &clearParams) override;
+
+ angle::Result readPixelsImpl(const gl::Context *context,
+ const gl::Rectangle &area,
+ GLenum format,
+ GLenum type,
+ size_t outputPitch,
+ const gl::PixelPackState &pack,
+ gl::Buffer *packPixels,
+ uint8_t *pixels) override;
+
+ angle::Result blitImpl(const gl::Context *context,
+ const gl::Rectangle &sourceArea,
+ const gl::Rectangle &destArea,
+ const gl::Rectangle *scissor,
+ bool blitRenderTarget,
+ bool blitDepth,
+ bool blitStencil,
+ GLenum filter,
+ const gl::Framebuffer *sourceFramebuffer) override;
+
+ Renderer9 *const mRenderer;
+
+ RenderTargetCache<RenderTarget9> mRenderTargetCache;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D9_FRAMBUFFER9_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Image9.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Image9.cpp
new file mode 100644
index 0000000000..229d54ced9
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Image9.cpp
@@ -0,0 +1,907 @@
+//
+// Copyright 2002 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.
+//
+
+// Image9.cpp: Implements the rx::Image9 class, which acts as the interface to
+// the actual underlying surfaces of a Texture.
+
+#include "libANGLE/renderer/d3d/d3d9/Image9.h"
+
+#include "common/utilities.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/Renderbuffer.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/copyvertex.h"
+#include "libANGLE/renderer/d3d/d3d9/Context9.h"
+#include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h"
+#include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
+#include "libANGLE/renderer/d3d/d3d9/TextureStorage9.h"
+#include "libANGLE/renderer/d3d/d3d9/formatutils9.h"
+#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h"
+
+namespace rx
+{
+
+Image9::Image9(Renderer9 *renderer)
+{
+ mSurface = nullptr;
+ mRenderer = nullptr;
+
+ mD3DPool = D3DPOOL_SYSTEMMEM;
+ mD3DFormat = D3DFMT_UNKNOWN;
+
+ mRenderer = renderer;
+}
+
+Image9::~Image9()
+{
+ SafeRelease(mSurface);
+}
+
+// static
+angle::Result Image9::GenerateMip(Context9 *context9,
+ IDirect3DSurface9 *destSurface,
+ IDirect3DSurface9 *sourceSurface)
+{
+ D3DSURFACE_DESC destDesc;
+ HRESULT result = destSurface->GetDesc(&destDesc);
+ ASSERT(SUCCEEDED(result));
+ ANGLE_TRY_HR(context9, result,
+ "Failed to query the source surface description for mipmap generation");
+
+ D3DSURFACE_DESC sourceDesc;
+ result = sourceSurface->GetDesc(&sourceDesc);
+ ASSERT(SUCCEEDED(result));
+ ANGLE_TRY_HR(context9, result,
+ "Failed to query the destination surface description for mipmap generation");
+
+ ASSERT(sourceDesc.Format == destDesc.Format);
+ ASSERT(sourceDesc.Width == 1 || sourceDesc.Width / 2 == destDesc.Width);
+ ASSERT(sourceDesc.Height == 1 || sourceDesc.Height / 2 == destDesc.Height);
+
+ const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(sourceDesc.Format);
+ ASSERT(d3dFormatInfo.info().mipGenerationFunction != nullptr);
+
+ D3DLOCKED_RECT sourceLocked = {};
+ result = sourceSurface->LockRect(&sourceLocked, nullptr, D3DLOCK_READONLY);
+ ASSERT(SUCCEEDED(result));
+ ANGLE_TRY_HR(context9, result, "Failed to lock the source surface for mipmap generation");
+
+ D3DLOCKED_RECT destLocked = {};
+ result = destSurface->LockRect(&destLocked, nullptr, 0);
+ ASSERT(SUCCEEDED(result));
+ ANGLE_TRY_HR(context9, result, "Failed to lock the destination surface for mipmap generation");
+
+ const uint8_t *sourceData = static_cast<const uint8_t *>(sourceLocked.pBits);
+ uint8_t *destData = static_cast<uint8_t *>(destLocked.pBits);
+
+ ASSERT(sourceData && destData);
+
+ d3dFormatInfo.info().mipGenerationFunction(sourceDesc.Width, sourceDesc.Height, 1, sourceData,
+ sourceLocked.Pitch, 0, destData, destLocked.Pitch,
+ 0);
+
+ destSurface->UnlockRect();
+ sourceSurface->UnlockRect();
+
+ return angle::Result::Continue;
+}
+
+// static
+angle::Result Image9::GenerateMipmap(Context9 *context9, Image9 *dest, Image9 *source)
+{
+ IDirect3DSurface9 *sourceSurface = nullptr;
+ ANGLE_TRY(source->getSurface(context9, &sourceSurface));
+
+ IDirect3DSurface9 *destSurface = nullptr;
+ ANGLE_TRY(dest->getSurface(context9, &destSurface));
+
+ ANGLE_TRY(GenerateMip(context9, destSurface, sourceSurface));
+
+ dest->markDirty();
+
+ return angle::Result::Continue;
+}
+
+// static
+angle::Result Image9::CopyLockableSurfaces(Context9 *context9,
+ IDirect3DSurface9 *dest,
+ IDirect3DSurface9 *source)
+{
+ D3DLOCKED_RECT sourceLock = {};
+ D3DLOCKED_RECT destLock = {};
+
+ HRESULT result;
+
+ result = source->LockRect(&sourceLock, nullptr, 0);
+ ANGLE_TRY_HR(context9, result, "Failed to lock source surface for copy");
+
+ result = dest->LockRect(&destLock, nullptr, 0);
+ if (FAILED(result))
+ {
+ source->UnlockRect();
+ }
+ ANGLE_TRY_HR(context9, result, "Failed to lock destination surface for copy");
+
+ ASSERT(sourceLock.pBits && destLock.pBits);
+
+ D3DSURFACE_DESC desc;
+ source->GetDesc(&desc);
+
+ const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(desc.Format);
+ unsigned int rows = desc.Height / d3dFormatInfo.blockHeight;
+
+ unsigned int bytes = d3d9::ComputeBlockSize(desc.Format, desc.Width, d3dFormatInfo.blockHeight);
+ ASSERT(bytes <= static_cast<unsigned int>(sourceLock.Pitch) &&
+ bytes <= static_cast<unsigned int>(destLock.Pitch));
+
+ for (unsigned int i = 0; i < rows; i++)
+ {
+ memcpy((char *)destLock.pBits + destLock.Pitch * i,
+ (char *)sourceLock.pBits + sourceLock.Pitch * i, bytes);
+ }
+
+ source->UnlockRect();
+ dest->UnlockRect();
+
+ return angle::Result::Continue;
+}
+
+// static
+angle::Result Image9::CopyImage(const gl::Context *context,
+ Image9 *dest,
+ Image9 *source,
+ const gl::Rectangle &sourceRect,
+ const gl::Offset &destOffset,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha)
+{
+ Context9 *context9 = GetImplAs<Context9>(context);
+
+ IDirect3DSurface9 *sourceSurface = nullptr;
+ ANGLE_TRY(source->getSurface(context9, &sourceSurface));
+
+ IDirect3DSurface9 *destSurface = nullptr;
+ ANGLE_TRY(dest->getSurface(context9, &destSurface));
+
+ D3DSURFACE_DESC destDesc;
+ HRESULT result = destSurface->GetDesc(&destDesc);
+ ASSERT(SUCCEEDED(result));
+ ANGLE_TRY_HR(context9, result, "Failed to query the source surface description for CopyImage");
+ const d3d9::D3DFormat &destD3DFormatInfo = d3d9::GetD3DFormatInfo(destDesc.Format);
+
+ D3DSURFACE_DESC sourceDesc;
+ result = sourceSurface->GetDesc(&sourceDesc);
+ ASSERT(SUCCEEDED(result));
+ ANGLE_TRY_HR(context9, result,
+ "Failed to query the destination surface description for CopyImage");
+ const d3d9::D3DFormat &sourceD3DFormatInfo = d3d9::GetD3DFormatInfo(sourceDesc.Format);
+
+ D3DLOCKED_RECT sourceLocked = {};
+ result = sourceSurface->LockRect(&sourceLocked, nullptr, D3DLOCK_READONLY);
+ ASSERT(SUCCEEDED(result));
+ ANGLE_TRY_HR(context9, result, "Failed to lock the source surface for CopyImage");
+
+ D3DLOCKED_RECT destLocked = {};
+ result = destSurface->LockRect(&destLocked, nullptr, 0);
+ ASSERT(SUCCEEDED(result));
+ if (FAILED(result))
+ {
+ sourceSurface->UnlockRect();
+ }
+ ANGLE_TRY_HR(context9, result, "Failed to lock the destination surface for CopyImage");
+
+ const uint8_t *sourceData = static_cast<const uint8_t *>(sourceLocked.pBits) +
+ sourceRect.x * sourceD3DFormatInfo.pixelBytes +
+ sourceRect.y * sourceLocked.Pitch;
+ uint8_t *destData = static_cast<uint8_t *>(destLocked.pBits) +
+ destOffset.x * destD3DFormatInfo.pixelBytes +
+ destOffset.y * destLocked.Pitch;
+ ASSERT(sourceData && destData);
+
+ CopyImageCHROMIUM(sourceData, sourceLocked.Pitch, sourceD3DFormatInfo.pixelBytes, 0,
+ sourceD3DFormatInfo.info().pixelReadFunction, destData, destLocked.Pitch,
+ destD3DFormatInfo.pixelBytes, 0, destD3DFormatInfo.info().pixelWriteFunction,
+ gl::GetUnsizedFormat(dest->getInternalFormat()),
+ destD3DFormatInfo.info().componentType, sourceRect.width, sourceRect.height,
+ 1, unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha);
+
+ dest->markDirty();
+
+ destSurface->UnlockRect();
+ sourceSurface->UnlockRect();
+
+ return angle::Result::Continue;
+}
+
+bool Image9::redefine(gl::TextureType type,
+ GLenum internalformat,
+ const gl::Extents &size,
+ bool forceRelease)
+{
+ // 3D textures are not supported by the D3D9 backend.
+ ASSERT(size.depth <= 1);
+
+ // Only 2D and cube texture are supported by the D3D9 backend.
+ ASSERT(type == gl::TextureType::_2D || type == gl::TextureType::CubeMap);
+
+ if (mWidth != size.width || mHeight != size.height || mDepth != size.depth ||
+ mInternalFormat != internalformat || forceRelease)
+ {
+ mWidth = size.width;
+ mHeight = size.height;
+ mDepth = size.depth;
+ mType = type;
+ mInternalFormat = internalformat;
+
+ // compute the d3d format that will be used
+ const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(internalformat);
+ mD3DFormat = d3d9FormatInfo.texFormat;
+ mRenderable = (d3d9FormatInfo.renderFormat != D3DFMT_UNKNOWN);
+
+ SafeRelease(mSurface);
+ mDirty = (d3d9FormatInfo.dataInitializerFunction != nullptr);
+
+ return true;
+ }
+
+ return false;
+}
+
+angle::Result Image9::createSurface(Context9 *context9)
+{
+ if (mSurface)
+ {
+ return angle::Result::Continue;
+ }
+
+ IDirect3DTexture9 *newTexture = nullptr;
+ IDirect3DSurface9 *newSurface = nullptr;
+ const D3DPOOL poolToUse = D3DPOOL_SYSTEMMEM;
+ const D3DFORMAT d3dFormat = getD3DFormat();
+
+ if (mWidth != 0 && mHeight != 0)
+ {
+ int levelToFetch = 0;
+ GLsizei requestWidth = mWidth;
+ GLsizei requestHeight = mHeight;
+ d3d9::MakeValidSize(true, d3dFormat, &requestWidth, &requestHeight, &levelToFetch);
+
+ IDirect3DDevice9 *device = mRenderer->getDevice();
+
+ HRESULT result = device->CreateTexture(requestWidth, requestHeight, levelToFetch + 1, 0,
+ d3dFormat, poolToUse, &newTexture, nullptr);
+
+ ANGLE_TRY_HR(context9, result, "Failed to create image surface");
+
+ newTexture->GetSurfaceLevel(levelToFetch, &newSurface);
+ SafeRelease(newTexture);
+
+ const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(mInternalFormat);
+ if (d3dFormatInfo.dataInitializerFunction != nullptr)
+ {
+ RECT entireRect;
+ entireRect.left = 0;
+ entireRect.right = mWidth;
+ entireRect.top = 0;
+ entireRect.bottom = mHeight;
+
+ D3DLOCKED_RECT lockedRect;
+ result = newSurface->LockRect(&lockedRect, &entireRect, 0);
+ ASSERT(SUCCEEDED(result));
+ ANGLE_TRY_HR(context9, result, "Failed to lock image surface");
+
+ d3dFormatInfo.dataInitializerFunction(
+ mWidth, mHeight, 1, static_cast<uint8_t *>(lockedRect.pBits), lockedRect.Pitch, 0);
+
+ result = newSurface->UnlockRect();
+ ASSERT(SUCCEEDED(result));
+ ANGLE_TRY_HR(context9, result, "Failed to unlock image surface");
+ }
+ }
+
+ mSurface = newSurface;
+ mDirty = false;
+ mD3DPool = poolToUse;
+
+ return angle::Result::Continue;
+}
+
+angle::Result Image9::lock(Context9 *context9, D3DLOCKED_RECT *lockedRect, const RECT &rect)
+{
+ ANGLE_TRY(createSurface(context9));
+
+ if (mSurface)
+ {
+ HRESULT result = mSurface->LockRect(lockedRect, &rect, 0);
+ ASSERT(SUCCEEDED(result));
+ ANGLE_TRY_HR(context9, result, "Failed to lock image surface");
+ mDirty = true;
+ }
+
+ return angle::Result::Continue;
+}
+
+void Image9::unlock()
+{
+ if (mSurface)
+ {
+ HRESULT result = mSurface->UnlockRect();
+ ASSERT(SUCCEEDED(result));
+ }
+}
+
+D3DFORMAT Image9::getD3DFormat() const
+{
+ // this should only happen if the image hasn't been redefined first
+ // which would be a bug by the caller
+ ASSERT(mD3DFormat != D3DFMT_UNKNOWN);
+
+ return mD3DFormat;
+}
+
+bool Image9::isDirty() const
+{
+ // Make sure to that this image is marked as dirty even if the staging texture hasn't been
+ // created yet if initialization is required before use.
+ return (mSurface ||
+ d3d9::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != nullptr) &&
+ mDirty;
+}
+
+angle::Result Image9::getSurface(Context9 *context9, IDirect3DSurface9 **outSurface)
+{
+ ANGLE_TRY(createSurface(context9));
+ *outSurface = mSurface;
+ return angle::Result::Continue;
+}
+
+angle::Result Image9::setManagedSurface2D(const gl::Context *context,
+ TextureStorage *storage,
+ int level)
+{
+ IDirect3DSurface9 *surface = nullptr;
+ TextureStorage9 *storage9 = GetAs<TextureStorage9>(storage);
+ ANGLE_TRY(storage9->getSurfaceLevel(context, gl::TextureTarget::_2D, level, false, &surface));
+ return setManagedSurface(GetImplAs<Context9>(context), surface);
+}
+
+angle::Result Image9::setManagedSurfaceCube(const gl::Context *context,
+ TextureStorage *storage,
+ int face,
+ int level)
+{
+ IDirect3DSurface9 *surface = nullptr;
+ TextureStorage9 *storage9 = GetAs<TextureStorage9>(storage);
+ ANGLE_TRY(storage9->getSurfaceLevel(context, gl::CubeFaceIndexToTextureTarget(face), level,
+ false, &surface));
+ return setManagedSurface(GetImplAs<Context9>(context), surface);
+}
+
+angle::Result Image9::setManagedSurface(Context9 *context9, IDirect3DSurface9 *surface)
+{
+ D3DSURFACE_DESC desc;
+ surface->GetDesc(&desc);
+ ASSERT(desc.Pool == D3DPOOL_MANAGED);
+
+ if ((GLsizei)desc.Width == mWidth && (GLsizei)desc.Height == mHeight)
+ {
+ if (mSurface)
+ {
+ angle::Result result = CopyLockableSurfaces(context9, surface, mSurface);
+ SafeRelease(mSurface);
+ ANGLE_TRY(result);
+ }
+
+ mSurface = surface;
+ mD3DPool = desc.Pool;
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result Image9::copyToStorage(const gl::Context *context,
+ TextureStorage *storage,
+ const gl::ImageIndex &index,
+ const gl::Box &region)
+{
+ ANGLE_TRY(createSurface(GetImplAs<Context9>(context)));
+
+ TextureStorage9 *storage9 = GetAs<TextureStorage9>(storage);
+ IDirect3DSurface9 *destSurface = nullptr;
+ ANGLE_TRY(storage9->getSurfaceLevel(context, index.getTarget(), index.getLevelIndex(), true,
+ &destSurface));
+
+ angle::Result result = copyToSurface(GetImplAs<Context9>(context), destSurface, region);
+ SafeRelease(destSurface);
+ return result;
+}
+
+angle::Result Image9::copyToSurface(Context9 *context9,
+ IDirect3DSurface9 *destSurface,
+ const gl::Box &area)
+{
+ ASSERT(area.width > 0 && area.height > 0 && area.depth == 1);
+ ASSERT(destSurface);
+
+ IDirect3DSurface9 *sourceSurface = nullptr;
+ ANGLE_TRY(getSurface(context9, &sourceSurface));
+
+ ASSERT(sourceSurface && sourceSurface != destSurface);
+
+ RECT rect;
+ rect.left = area.x;
+ rect.top = area.y;
+ rect.right = area.x + area.width;
+ rect.bottom = area.y + area.height;
+
+ POINT point = {rect.left, rect.top};
+
+ IDirect3DDevice9 *device = mRenderer->getDevice();
+
+ if (mD3DPool == D3DPOOL_MANAGED)
+ {
+ D3DSURFACE_DESC desc;
+ sourceSurface->GetDesc(&desc);
+
+ IDirect3DSurface9 *surf = 0;
+ HRESULT result = device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format,
+ D3DPOOL_SYSTEMMEM, &surf, nullptr);
+ ANGLE_TRY_HR(context9, result, "Internal CreateOffscreenPlainSurface call failed");
+
+ auto err = CopyLockableSurfaces(context9, surf, sourceSurface);
+ result = device->UpdateSurface(surf, &rect, destSurface, &point);
+ SafeRelease(surf);
+ ANGLE_TRY(err);
+ ASSERT(SUCCEEDED(result));
+ ANGLE_TRY_HR(context9, result, "Internal UpdateSurface call failed");
+ }
+ else
+ {
+ // UpdateSurface: source must be SYSTEMMEM, dest must be DEFAULT pools
+ HRESULT result = device->UpdateSurface(sourceSurface, &rect, destSurface, &point);
+ ASSERT(SUCCEEDED(result));
+ ANGLE_TRY_HR(context9, result, "Internal UpdateSurface call failed");
+ }
+
+ return angle::Result::Continue;
+}
+
+// Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as
+// format/type at input into the target pixel rectangle.
+angle::Result Image9::loadData(const gl::Context *context,
+ const gl::Box &area,
+ const gl::PixelUnpackState &unpack,
+ GLenum type,
+ const void *input,
+ bool applySkipImages)
+{
+ // 3D textures are not supported by the D3D9 backend.
+ ASSERT(area.z == 0 && area.depth == 1);
+
+ Context9 *context9 = GetImplAs<Context9>(context);
+
+ const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(mInternalFormat);
+ GLuint inputRowPitch = 0;
+ ANGLE_CHECK_GL_MATH(context9, formatInfo.computeRowPitch(type, area.width, unpack.alignment,
+ unpack.rowLength, &inputRowPitch));
+ ASSERT(!applySkipImages);
+ ASSERT(unpack.skipPixels == 0);
+ ASSERT(unpack.skipRows == 0);
+
+ const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(mInternalFormat);
+ ASSERT(d3dFormatInfo.loadFunction != nullptr);
+
+ RECT lockRect = {area.x, area.y, area.x + area.width, area.y + area.height};
+
+ D3DLOCKED_RECT locked;
+ ANGLE_TRY(lock(GetImplAs<Context9>(context), &locked, lockRect));
+
+ d3dFormatInfo.loadFunction(area.width, area.height, area.depth,
+ static_cast<const uint8_t *>(input), inputRowPitch, 0,
+ static_cast<uint8_t *>(locked.pBits), locked.Pitch, 0);
+
+ unlock();
+
+ return angle::Result::Continue;
+}
+
+angle::Result Image9::loadCompressedData(const gl::Context *context,
+ const gl::Box &area,
+ const void *input)
+{
+ // 3D textures are not supported by the D3D9 backend.
+ ASSERT(area.z == 0 && area.depth == 1);
+
+ Context9 *context9 = GetImplAs<Context9>(context);
+
+ const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(mInternalFormat);
+ GLuint inputRowPitch = 0;
+ ANGLE_CHECK_GL_MATH(
+ context9, formatInfo.computeRowPitch(GL_UNSIGNED_BYTE, area.width, 1, 0, &inputRowPitch));
+
+ GLuint inputDepthPitch = 0;
+ ANGLE_CHECK_GL_MATH(
+ context9, formatInfo.computeDepthPitch(area.height, 0, inputRowPitch, &inputDepthPitch));
+
+ const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(mInternalFormat);
+
+ ASSERT(area.x % d3d9::GetD3DFormatInfo(d3d9FormatInfo.texFormat).blockWidth == 0);
+ ASSERT(area.y % d3d9::GetD3DFormatInfo(d3d9FormatInfo.texFormat).blockHeight == 0);
+
+ ASSERT(d3d9FormatInfo.loadFunction != nullptr);
+
+ RECT lockRect = {area.x, area.y, area.x + area.width, area.y + area.height};
+
+ D3DLOCKED_RECT locked;
+ ANGLE_TRY(lock(GetImplAs<Context9>(context), &locked, lockRect));
+
+ d3d9FormatInfo.loadFunction(area.width, area.height, area.depth,
+ static_cast<const uint8_t *>(input), inputRowPitch, inputDepthPitch,
+ static_cast<uint8_t *>(locked.pBits), locked.Pitch, 0);
+
+ unlock();
+
+ return angle::Result::Continue;
+}
+
+// This implements glCopyTex[Sub]Image2D for non-renderable internal texture formats and incomplete
+// textures
+angle::Result Image9::copyFromRTInternal(Context9 *context9,
+ const gl::Offset &destOffset,
+ const gl::Rectangle &sourceArea,
+ RenderTargetD3D *source)
+{
+ ASSERT(source);
+
+ // ES3.0 only behaviour to copy into a 3d texture
+ ASSERT(destOffset.z == 0);
+
+ RenderTarget9 *renderTarget = GetAs<RenderTarget9>(source);
+
+ angle::ComPtr<IDirect3DSurface9> surface = renderTarget->getSurface();
+ ASSERT(surface);
+
+ IDirect3DDevice9 *device = mRenderer->getDevice();
+
+ angle::ComPtr<IDirect3DSurface9> renderTargetData = nullptr;
+ D3DSURFACE_DESC description;
+ surface->GetDesc(&description);
+
+ HRESULT hr = device->CreateOffscreenPlainSurface(description.Width, description.Height,
+ description.Format, D3DPOOL_SYSTEMMEM,
+ &renderTargetData, nullptr);
+
+ ANGLE_TRY_HR(context9, hr, "Could not create matching destination surface");
+
+ hr = device->GetRenderTargetData(surface.Get(), renderTargetData.Get());
+
+ ANGLE_TRY_HR(context9, hr, "GetRenderTargetData unexpectedly failed");
+
+ int width = sourceArea.width;
+ int height = sourceArea.height;
+
+ RECT sourceRect = {sourceArea.x, sourceArea.y, sourceArea.x + width, sourceArea.y + height};
+ RECT destRect = {destOffset.x, destOffset.y, destOffset.x + width, destOffset.y + height};
+
+ D3DLOCKED_RECT sourceLock = {};
+ hr = renderTargetData->LockRect(&sourceLock, &sourceRect, 0);
+
+ ANGLE_TRY_HR(context9, hr, "Failed to lock the source surface (rectangle might be invalid)");
+
+ D3DLOCKED_RECT destLock = {};
+ angle::Result result = lock(context9, &destLock, destRect);
+ if (result == angle::Result::Stop)
+ {
+ renderTargetData->UnlockRect();
+ }
+ ANGLE_TRY(result);
+
+ ASSERT(destLock.pBits && sourceLock.pBits);
+
+ unsigned char *sourcePixels = (unsigned char *)sourceLock.pBits;
+ unsigned char *destPixels = (unsigned char *)destLock.pBits;
+
+ switch (description.Format)
+ {
+ case D3DFMT_X8R8G8B8:
+ case D3DFMT_A8R8G8B8:
+ switch (getD3DFormat())
+ {
+ case D3DFMT_X8R8G8B8:
+ case D3DFMT_A8R8G8B8:
+ for (int y = 0; y < height; y++)
+ {
+ memcpy(destPixels, sourcePixels, 4 * width);
+ sourcePixels += sourceLock.Pitch;
+ destPixels += destLock.Pitch;
+ }
+ break;
+ case D3DFMT_L8:
+ for (int y = 0; y < height; y++)
+ {
+ for (int x = 0; x < width; x++)
+ {
+ destPixels[x] = sourcePixels[x * 4 + 2];
+ }
+ sourcePixels += sourceLock.Pitch;
+ destPixels += destLock.Pitch;
+ }
+ break;
+ case D3DFMT_A8L8:
+ for (int y = 0; y < height; y++)
+ {
+ for (int x = 0; x < width; x++)
+ {
+ destPixels[x * 2 + 0] = sourcePixels[x * 4 + 2];
+ destPixels[x * 2 + 1] = sourcePixels[x * 4 + 3];
+ }
+ sourcePixels += sourceLock.Pitch;
+ destPixels += destLock.Pitch;
+ }
+ break;
+ default:
+ UNREACHABLE();
+ }
+ break;
+ case D3DFMT_R5G6B5:
+ switch (getD3DFormat())
+ {
+ case D3DFMT_X8R8G8B8:
+ for (int y = 0; y < height; y++)
+ {
+ for (int x = 0; x < width; x++)
+ {
+ unsigned short rgb = ((unsigned short *)sourcePixels)[x];
+ unsigned char red = static_cast<unsigned char>((rgb & 0xF800) >> 8);
+ unsigned char green = static_cast<unsigned char>((rgb & 0x07E0) >> 3);
+ unsigned char blue = static_cast<unsigned char>((rgb & 0x001F) << 3);
+ destPixels[x + 0] = blue | (blue >> 5);
+ destPixels[x + 1] = green | (green >> 6);
+ destPixels[x + 2] = red | (red >> 5);
+ destPixels[x + 3] = 0xFF;
+ }
+ sourcePixels += sourceLock.Pitch;
+ destPixels += destLock.Pitch;
+ }
+ break;
+ case D3DFMT_L8:
+ for (int y = 0; y < height; y++)
+ {
+ for (int x = 0; x < width; x++)
+ {
+ unsigned char red = sourcePixels[x * 2 + 1] & 0xF8;
+ destPixels[x] = red | (red >> 5);
+ }
+ sourcePixels += sourceLock.Pitch;
+ destPixels += destLock.Pitch;
+ }
+ break;
+ default:
+ UNREACHABLE();
+ }
+ break;
+ case D3DFMT_A1R5G5B5:
+ switch (getD3DFormat())
+ {
+ case D3DFMT_X8R8G8B8:
+ for (int y = 0; y < height; y++)
+ {
+ for (int x = 0; x < width; x++)
+ {
+ unsigned short argb = ((unsigned short *)sourcePixels)[x];
+ unsigned char red = static_cast<unsigned char>((argb & 0x7C00) >> 7);
+ unsigned char green = static_cast<unsigned char>((argb & 0x03E0) >> 2);
+ unsigned char blue = static_cast<unsigned char>((argb & 0x001F) << 3);
+ destPixels[x + 0] = blue | (blue >> 5);
+ destPixels[x + 1] = green | (green >> 5);
+ destPixels[x + 2] = red | (red >> 5);
+ destPixels[x + 3] = 0xFF;
+ }
+ sourcePixels += sourceLock.Pitch;
+ destPixels += destLock.Pitch;
+ }
+ break;
+ case D3DFMT_A8R8G8B8:
+ for (int y = 0; y < height; y++)
+ {
+ for (int x = 0; x < width; x++)
+ {
+ unsigned short argb = ((unsigned short *)sourcePixels)[x];
+ unsigned char red = static_cast<unsigned char>((argb & 0x7C00) >> 7);
+ unsigned char green = static_cast<unsigned char>((argb & 0x03E0) >> 2);
+ unsigned char blue = static_cast<unsigned char>((argb & 0x001F) << 3);
+ unsigned char alpha = (signed short)argb >> 15;
+ destPixels[x + 0] = blue | (blue >> 5);
+ destPixels[x + 1] = green | (green >> 5);
+ destPixels[x + 2] = red | (red >> 5);
+ destPixels[x + 3] = alpha;
+ }
+ sourcePixels += sourceLock.Pitch;
+ destPixels += destLock.Pitch;
+ }
+ break;
+ case D3DFMT_L8:
+ for (int y = 0; y < height; y++)
+ {
+ for (int x = 0; x < width; x++)
+ {
+ unsigned char red = sourcePixels[x * 2 + 1] & 0x7C;
+ destPixels[x] = (red << 1) | (red >> 4);
+ }
+ sourcePixels += sourceLock.Pitch;
+ destPixels += destLock.Pitch;
+ }
+ break;
+ case D3DFMT_A8L8:
+ for (int y = 0; y < height; y++)
+ {
+ for (int x = 0; x < width; x++)
+ {
+ unsigned char red = sourcePixels[x * 2 + 1] & 0x7C;
+ destPixels[x * 2 + 0] = (red << 1) | (red >> 4);
+ destPixels[x * 2 + 1] = (signed char)sourcePixels[x * 2 + 1] >> 7;
+ }
+ sourcePixels += sourceLock.Pitch;
+ destPixels += destLock.Pitch;
+ }
+ break;
+ default:
+ UNREACHABLE();
+ }
+ break;
+ case D3DFMT_A16B16G16R16F:
+ switch (getD3DFormat())
+ {
+ case D3DFMT_X8R8G8B8:
+ case D3DFMT_A8R8G8B8:
+ for (int y = 0; y < height; y++)
+ {
+ const uint16_t *sourcePixels16F =
+ reinterpret_cast<uint16_t *>(sourcePixels);
+ for (int x = 0; x < width; x++)
+ {
+ float r = gl::float16ToFloat32(sourcePixels16F[x * 4 + 0]);
+ float g = gl::float16ToFloat32(sourcePixels16F[x * 4 + 1]);
+ float b = gl::float16ToFloat32(sourcePixels16F[x * 4 + 2]);
+ float a = gl::float16ToFloat32(sourcePixels16F[x * 4 + 3]);
+ destPixels[x * 4 + 0] = gl::floatToNormalized<uint8_t>(b);
+ destPixels[x * 4 + 1] = gl::floatToNormalized<uint8_t>(g);
+ destPixels[x * 4 + 2] = gl::floatToNormalized<uint8_t>(r);
+ destPixels[x * 4 + 3] = gl::floatToNormalized<uint8_t>(a);
+ }
+ sourcePixels += sourceLock.Pitch;
+ destPixels += destLock.Pitch;
+ }
+ break;
+ case D3DFMT_L8:
+ for (int y = 0; y < height; y++)
+ {
+ const uint16_t *sourcePixels16F =
+ reinterpret_cast<uint16_t *>(sourcePixels);
+ for (int x = 0; x < width; x++)
+ {
+ float r = gl::float16ToFloat32(sourcePixels16F[x * 4]);
+ destPixels[x] = gl::floatToNormalized<uint8_t>(r);
+ }
+ sourcePixels += sourceLock.Pitch;
+ destPixels += destLock.Pitch;
+ }
+ break;
+ case D3DFMT_A8L8:
+ for (int y = 0; y < height; y++)
+ {
+ const uint16_t *sourcePixels16F =
+ reinterpret_cast<uint16_t *>(sourcePixels);
+ for (int x = 0; x < width; x++)
+ {
+ float r = gl::float16ToFloat32(sourcePixels16F[x * 4 + 0]);
+ float a = gl::float16ToFloat32(sourcePixels16F[x * 4 + 3]);
+ destPixels[x * 2 + 0] = gl::floatToNormalized<uint8_t>(r);
+ destPixels[x * 2 + 1] = gl::floatToNormalized<uint8_t>(a);
+ }
+ sourcePixels += sourceLock.Pitch;
+ destPixels += destLock.Pitch;
+ }
+ break;
+ default:
+ UNREACHABLE();
+ }
+ break;
+ case D3DFMT_A32B32G32R32F:
+ switch (getD3DFormat())
+ {
+ case D3DFMT_X8R8G8B8:
+ case D3DFMT_A8R8G8B8:
+ for (int y = 0; y < height; y++)
+ {
+ const float *sourcePixels32F = reinterpret_cast<float *>(sourcePixels);
+ for (int x = 0; x < width; x++)
+ {
+ float r = sourcePixels32F[x * 4 + 0];
+ float g = sourcePixels32F[x * 4 + 1];
+ float b = sourcePixels32F[x * 4 + 2];
+ float a = sourcePixels32F[x * 4 + 3];
+ destPixels[x * 4 + 0] = gl::floatToNormalized<uint8_t>(b);
+ destPixels[x * 4 + 1] = gl::floatToNormalized<uint8_t>(g);
+ destPixels[x * 4 + 2] = gl::floatToNormalized<uint8_t>(r);
+ destPixels[x * 4 + 3] = gl::floatToNormalized<uint8_t>(a);
+ }
+ sourcePixels += sourceLock.Pitch;
+ destPixels += destLock.Pitch;
+ }
+ break;
+ case D3DFMT_L8:
+ for (int y = 0; y < height; y++)
+ {
+ const float *sourcePixels32F = reinterpret_cast<float *>(sourcePixels);
+ for (int x = 0; x < width; x++)
+ {
+ float r = sourcePixels32F[x * 4];
+ destPixels[x] = gl::floatToNormalized<uint8_t>(r);
+ }
+ sourcePixels += sourceLock.Pitch;
+ destPixels += destLock.Pitch;
+ }
+ break;
+ case D3DFMT_A8L8:
+ for (int y = 0; y < height; y++)
+ {
+ const float *sourcePixels32F = reinterpret_cast<float *>(sourcePixels);
+ for (int x = 0; x < width; x++)
+ {
+ float r = sourcePixels32F[x * 4 + 0];
+ float a = sourcePixels32F[x * 4 + 3];
+ destPixels[x * 2 + 0] = gl::floatToNormalized<uint8_t>(r);
+ destPixels[x * 2 + 1] = gl::floatToNormalized<uint8_t>(a);
+ }
+ sourcePixels += sourceLock.Pitch;
+ destPixels += destLock.Pitch;
+ }
+ break;
+ default:
+ UNREACHABLE();
+ }
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ unlock();
+ renderTargetData->UnlockRect();
+
+ mDirty = true;
+ return angle::Result::Continue;
+}
+
+angle::Result Image9::copyFromTexStorage(const gl::Context *context,
+ const gl::ImageIndex &imageIndex,
+ TextureStorage *source)
+{
+ RenderTargetD3D *renderTarget = nullptr;
+ ANGLE_TRY(source->getRenderTarget(context, imageIndex, 0, &renderTarget));
+
+ gl::Rectangle sourceArea(0, 0, mWidth, mHeight);
+ return copyFromRTInternal(GetImplAs<Context9>(context), gl::Offset(), sourceArea, renderTarget);
+}
+
+angle::Result Image9::copyFromFramebuffer(const gl::Context *context,
+ const gl::Offset &destOffset,
+ const gl::Rectangle &sourceArea,
+ const gl::Framebuffer *source)
+{
+ const gl::FramebufferAttachment *srcAttachment = source->getReadColorAttachment();
+ ASSERT(srcAttachment);
+
+ RenderTargetD3D *renderTarget = nullptr;
+ ANGLE_TRY(srcAttachment->getRenderTarget(context, 0, &renderTarget));
+ ASSERT(renderTarget);
+ return copyFromRTInternal(GetImplAs<Context9>(context), destOffset, sourceArea, renderTarget);
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Image9.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Image9.h
new file mode 100644
index 0000000000..80064aa24b
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Image9.h
@@ -0,0 +1,112 @@
+//
+// Copyright 2002 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.
+//
+
+// Image9.h: Defines the rx::Image9 class, which acts as the interface to
+// the actual underlying surfaces of a Texture.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D9_IMAGE9_H_
+#define LIBANGLE_RENDERER_D3D_D3D9_IMAGE9_H_
+
+#include "common/debug.h"
+#include "libANGLE/renderer/d3d/ImageD3D.h"
+
+namespace gl
+{
+class Framebuffer;
+}
+
+namespace rx
+{
+class Context9;
+class Renderer9;
+
+class Image9 : public ImageD3D
+{
+ public:
+ Image9(Renderer9 *renderer);
+ ~Image9() override;
+
+ static angle::Result GenerateMipmap(Context9 *context9, Image9 *dest, Image9 *source);
+ static angle::Result GenerateMip(Context9 *context9,
+ IDirect3DSurface9 *destSurface,
+ IDirect3DSurface9 *sourceSurface);
+ static angle::Result CopyLockableSurfaces(Context9 *context9,
+ IDirect3DSurface9 *dest,
+ IDirect3DSurface9 *source);
+ static angle::Result CopyImage(const gl::Context *context,
+ Image9 *dest,
+ Image9 *source,
+ const gl::Rectangle &sourceRect,
+ const gl::Offset &destOffset,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha);
+
+ bool redefine(gl::TextureType type,
+ GLenum internalformat,
+ const gl::Extents &size,
+ bool forceRelease) override;
+
+ D3DFORMAT getD3DFormat() const;
+
+ bool isDirty() const override;
+
+ angle::Result setManagedSurface2D(const gl::Context *context,
+ TextureStorage *storage,
+ int level) override;
+ angle::Result setManagedSurfaceCube(const gl::Context *context,
+ TextureStorage *storage,
+ int face,
+ int level) override;
+ angle::Result copyToStorage(const gl::Context *context,
+ TextureStorage *storage,
+ const gl::ImageIndex &index,
+ const gl::Box &region) override;
+
+ angle::Result loadData(const gl::Context *context,
+ const gl::Box &area,
+ const gl::PixelUnpackState &unpack,
+ GLenum type,
+ const void *input,
+ bool applySkipImages) override;
+ angle::Result loadCompressedData(const gl::Context *context,
+ const gl::Box &area,
+ const void *input) override;
+
+ angle::Result copyFromTexStorage(const gl::Context *context,
+ const gl::ImageIndex &imageIndex,
+ TextureStorage *source) override;
+ angle::Result copyFromFramebuffer(const gl::Context *context,
+ const gl::Offset &destOffset,
+ const gl::Rectangle &sourceArea,
+ const gl::Framebuffer *source) override;
+
+ private:
+ angle::Result getSurface(Context9 *context9, IDirect3DSurface9 **outSurface);
+
+ angle::Result createSurface(Context9 *context9);
+ angle::Result setManagedSurface(Context9 *context9, IDirect3DSurface9 *surface);
+ angle::Result copyToSurface(Context9 *context9, IDirect3DSurface9 *dest, const gl::Box &area);
+
+ angle::Result lock(Context9 *context9, D3DLOCKED_RECT *lockedRect, const RECT &rect);
+ void unlock();
+
+ angle::Result copyFromRTInternal(Context9 *context9,
+ const gl::Offset &destOffset,
+ const gl::Rectangle &sourceArea,
+ RenderTargetD3D *source);
+
+ Renderer9 *mRenderer;
+
+ D3DPOOL mD3DPool; // can only be D3DPOOL_SYSTEMMEM or D3DPOOL_MANAGED since it needs to be
+ // lockable.
+ D3DFORMAT mD3DFormat;
+
+ IDirect3DSurface9 *mSurface;
+};
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D9_IMAGE9_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.cpp
new file mode 100644
index 0000000000..26bae3bdb8
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.cpp
@@ -0,0 +1,161 @@
+//
+// Copyright 2002 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.
+//
+
+// Indexffer9.cpp: Defines the D3D9 IndexBuffer implementation.
+
+#include "libANGLE/renderer/d3d/d3d9/IndexBuffer9.h"
+
+#include "libANGLE/Context.h"
+#include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
+
+namespace rx
+{
+
+IndexBuffer9::IndexBuffer9(Renderer9 *const renderer) : mRenderer(renderer)
+{
+ mIndexBuffer = nullptr;
+ mBufferSize = 0;
+ mIndexType = gl::DrawElementsType::InvalidEnum;
+ mDynamic = false;
+}
+
+IndexBuffer9::~IndexBuffer9()
+{
+ SafeRelease(mIndexBuffer);
+}
+
+angle::Result IndexBuffer9::initialize(const gl::Context *context,
+ unsigned int bufferSize,
+ gl::DrawElementsType indexType,
+ bool dynamic)
+{
+ SafeRelease(mIndexBuffer);
+
+ updateSerial();
+
+ if (bufferSize > 0)
+ {
+ D3DFORMAT format = D3DFMT_UNKNOWN;
+ if (indexType == gl::DrawElementsType::UnsignedShort ||
+ indexType == gl::DrawElementsType::UnsignedByte)
+ {
+ format = D3DFMT_INDEX16;
+ }
+ else if (indexType == gl::DrawElementsType::UnsignedInt)
+ {
+ ASSERT(mRenderer->getNativeExtensions().elementIndexUintOES);
+ format = D3DFMT_INDEX32;
+ }
+ else
+ UNREACHABLE();
+
+ DWORD usageFlags = D3DUSAGE_WRITEONLY;
+ if (dynamic)
+ {
+ usageFlags |= D3DUSAGE_DYNAMIC;
+ }
+
+ HRESULT result =
+ mRenderer->createIndexBuffer(bufferSize, usageFlags, format, &mIndexBuffer);
+ ANGLE_TRY_HR(GetImplAs<Context9>(context), result,
+ "Failed to allocate internal index buffer");
+ }
+
+ mBufferSize = bufferSize;
+ mIndexType = indexType;
+ mDynamic = dynamic;
+
+ return angle::Result::Continue;
+}
+
+angle::Result IndexBuffer9::mapBuffer(const gl::Context *context,
+ unsigned int offset,
+ unsigned int size,
+ void **outMappedMemory)
+{
+ ASSERT(mIndexBuffer);
+
+ DWORD lockFlags = mDynamic ? D3DLOCK_NOOVERWRITE : 0;
+
+ void *mapPtr = nullptr;
+ HRESULT result = mIndexBuffer->Lock(offset, size, &mapPtr, lockFlags);
+ ANGLE_TRY_HR(GetImplAs<Context9>(context), result, "Failed to lock internal index buffer");
+
+ *outMappedMemory = mapPtr;
+ return angle::Result::Continue;
+}
+
+angle::Result IndexBuffer9::unmapBuffer(const gl::Context *context)
+{
+ ASSERT(mIndexBuffer);
+ HRESULT result = mIndexBuffer->Unlock();
+ ANGLE_TRY_HR(GetImplAs<Context9>(context), result, "Failed to unlock internal index buffer");
+
+ return angle::Result::Continue;
+}
+
+gl::DrawElementsType IndexBuffer9::getIndexType() const
+{
+ return mIndexType;
+}
+
+unsigned int IndexBuffer9::getBufferSize() const
+{
+ return mBufferSize;
+}
+
+angle::Result IndexBuffer9::setSize(const gl::Context *context,
+ unsigned int bufferSize,
+ gl::DrawElementsType indexType)
+{
+ if (bufferSize > mBufferSize || indexType != mIndexType)
+ {
+ return initialize(context, bufferSize, indexType, mDynamic);
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result IndexBuffer9::discard(const gl::Context *context)
+{
+ ASSERT(mIndexBuffer);
+
+ void *mock;
+ HRESULT result;
+
+ Context9 *context9 = GetImplAs<Context9>(context);
+
+ result = mIndexBuffer->Lock(0, 1, &mock, D3DLOCK_DISCARD);
+ ANGLE_TRY_HR(context9, result, "Failed to lock internal index buffer");
+
+ result = mIndexBuffer->Unlock();
+ ANGLE_TRY_HR(context9, result, "Failed to unlock internal index buffer");
+
+ return angle::Result::Continue;
+}
+
+D3DFORMAT IndexBuffer9::getIndexFormat() const
+{
+ switch (mIndexType)
+ {
+ case gl::DrawElementsType::UnsignedByte:
+ return D3DFMT_INDEX16;
+ case gl::DrawElementsType::UnsignedShort:
+ return D3DFMT_INDEX16;
+ case gl::DrawElementsType::UnsignedInt:
+ return D3DFMT_INDEX32;
+ default:
+ UNREACHABLE();
+ return D3DFMT_UNKNOWN;
+ }
+}
+
+IDirect3DIndexBuffer9 *IndexBuffer9::getBuffer() const
+{
+ return mIndexBuffer;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.h
new file mode 100644
index 0000000000..9493a1ebbe
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.h
@@ -0,0 +1,57 @@
+//
+// Copyright 2002 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.
+//
+
+// Indexffer9.h: Defines the D3D9 IndexBuffer implementation.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D9_INDEXBUFFER9_H_
+#define LIBANGLE_RENDERER_D3D_D3D9_INDEXBUFFER9_H_
+
+#include "libANGLE/renderer/d3d/IndexBuffer.h"
+
+namespace rx
+{
+class Renderer9;
+
+class IndexBuffer9 : public IndexBuffer
+{
+ public:
+ explicit IndexBuffer9(Renderer9 *const renderer);
+ ~IndexBuffer9() override;
+
+ angle::Result initialize(const gl::Context *context,
+ unsigned int bufferSize,
+ gl::DrawElementsType indexType,
+ bool dynamic) override;
+
+ angle::Result mapBuffer(const gl::Context *context,
+ unsigned int offset,
+ unsigned int size,
+ void **outMappedMemory) override;
+ angle::Result unmapBuffer(const gl::Context *context) override;
+
+ gl::DrawElementsType getIndexType() const override;
+ unsigned int getBufferSize() const override;
+ angle::Result setSize(const gl::Context *context,
+ unsigned int bufferSize,
+ gl::DrawElementsType indexType) override;
+
+ angle::Result discard(const gl::Context *context) override;
+
+ D3DFORMAT getIndexFormat() const;
+ IDirect3DIndexBuffer9 *getBuffer() const;
+
+ private:
+ Renderer9 *const mRenderer;
+
+ IDirect3DIndexBuffer9 *mIndexBuffer;
+ unsigned int mBufferSize;
+ gl::DrawElementsType mIndexType;
+ bool mDynamic;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D9_INDEXBUFFER9_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/NativeWindow9.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/NativeWindow9.cpp
new file mode 100644
index 0000000000..e4834b44eb
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/NativeWindow9.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.
+//
+
+// NativeWindow9.cpp: Defines NativeWindow9, a class for managing and
+// performing operations on an EGLNativeWindowType for the D3D9 renderer.
+
+#include "libANGLE/renderer/d3d/d3d9/NativeWindow9.h"
+
+namespace rx
+{
+NativeWindow9::NativeWindow9(EGLNativeWindowType window) : NativeWindowD3D(window) {}
+
+bool NativeWindow9::initialize()
+{
+ return true;
+}
+
+bool NativeWindow9::getClientRect(LPRECT rect) const
+{
+ return GetClientRect(getNativeWindow(), rect) == TRUE;
+}
+
+bool NativeWindow9::isIconic() const
+{
+ return IsIconic(getNativeWindow()) == TRUE;
+}
+
+// static
+bool NativeWindow9::IsValidNativeWindow(EGLNativeWindowType window)
+{
+ return IsWindow(window) == TRUE;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/NativeWindow9.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/NativeWindow9.h
new file mode 100644
index 0000000000..aae9e13cc0
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/NativeWindow9.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.
+//
+
+// NativeWindow9.h: Defines NativeWindow9, a class for managing and
+// performing operations on an EGLNativeWindowType for the D3D9 renderer.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D9_NATIVEWINDOW9_H_
+#define LIBANGLE_RENDERER_D3D_D3D9_NATIVEWINDOW9_H_
+
+#include "common/debug.h"
+#include "common/platform.h"
+
+#include "libANGLE/renderer/d3d/NativeWindowD3D.h"
+
+namespace rx
+{
+
+class NativeWindow9 : public NativeWindowD3D
+{
+ public:
+ explicit NativeWindow9(EGLNativeWindowType window);
+
+ bool initialize() override;
+ bool getClientRect(LPRECT rect) const override;
+ bool isIconic() const override;
+
+ static bool IsValidNativeWindow(EGLNativeWindowType window);
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D9_NATIVEWINDOW9_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Query9.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Query9.cpp
new file mode 100644
index 0000000000..aeefd6a29f
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Query9.cpp
@@ -0,0 +1,176 @@
+//
+// Copyright 2013 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.
+//
+
+// Query9.cpp: Defines the rx::Query9 class which implements rx::QueryImpl.
+
+#include "libANGLE/renderer/d3d/d3d9/Query9.h"
+
+#include "libANGLE/Context.h"
+#include "libANGLE/renderer/d3d/d3d9/Context9.h"
+#include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
+#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h"
+
+#include <GLES2/gl2ext.h>
+
+namespace rx
+{
+Query9::Query9(Renderer9 *renderer, gl::QueryType type)
+ : QueryImpl(type),
+ mGetDataAttemptCount(0),
+ mResult(GL_FALSE),
+ mQueryFinished(false),
+ mRenderer(renderer),
+ mQuery(nullptr)
+{}
+
+Query9::~Query9()
+{
+ SafeRelease(mQuery);
+}
+
+angle::Result Query9::begin(const gl::Context *context)
+{
+ Context9 *context9 = GetImplAs<Context9>(context);
+
+ D3DQUERYTYPE d3dQueryType = gl_d3d9::ConvertQueryType(getType());
+ if (mQuery == nullptr)
+ {
+ HRESULT result = mRenderer->getDevice()->CreateQuery(d3dQueryType, &mQuery);
+ ANGLE_TRY_HR(context9, result, "Internal query creation failed");
+ }
+
+ if (d3dQueryType != D3DQUERYTYPE_EVENT)
+ {
+ HRESULT result = mQuery->Issue(D3DISSUE_BEGIN);
+ ASSERT(SUCCEEDED(result));
+ ANGLE_TRY_HR(context9, result, "Failed to begin internal query");
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result Query9::end(const gl::Context *context)
+{
+ Context9 *context9 = GetImplAs<Context9>(context);
+ ASSERT(mQuery);
+
+ HRESULT result = mQuery->Issue(D3DISSUE_END);
+ ASSERT(SUCCEEDED(result));
+ ANGLE_TRY_HR(context9, result, "Failed to end internal query");
+ mQueryFinished = false;
+ mResult = GL_FALSE;
+
+ return angle::Result::Continue;
+}
+
+angle::Result Query9::queryCounter(const gl::Context *context)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context9>(context));
+}
+
+template <typename T>
+angle::Result Query9::getResultBase(Context9 *context9, T *params)
+{
+ while (!mQueryFinished)
+ {
+ ANGLE_TRY(testQuery(context9));
+
+ if (!mQueryFinished)
+ {
+ Sleep(0);
+ }
+ }
+
+ ASSERT(mQueryFinished);
+ *params = static_cast<T>(mResult);
+ return angle::Result::Continue;
+}
+
+angle::Result Query9::getResult(const gl::Context *context, GLint *params)
+{
+ return getResultBase(GetImplAs<Context9>(context), params);
+}
+
+angle::Result Query9::getResult(const gl::Context *context, GLuint *params)
+{
+ return getResultBase(GetImplAs<Context9>(context), params);
+}
+
+angle::Result Query9::getResult(const gl::Context *context, GLint64 *params)
+{
+ return getResultBase(GetImplAs<Context9>(context), params);
+}
+
+angle::Result Query9::getResult(const gl::Context *context, GLuint64 *params)
+{
+ return getResultBase(GetImplAs<Context9>(context), params);
+}
+
+angle::Result Query9::isResultAvailable(const gl::Context *context, bool *available)
+{
+ ANGLE_TRY(testQuery(GetImplAs<Context9>(context)));
+ *available = mQueryFinished;
+ return angle::Result::Continue;
+}
+
+angle::Result Query9::testQuery(Context9 *context9)
+{
+ if (!mQueryFinished)
+ {
+ ASSERT(mQuery);
+
+ HRESULT result = S_OK;
+ switch (getType())
+ {
+ case gl::QueryType::AnySamples:
+ case gl::QueryType::AnySamplesConservative:
+ {
+ DWORD numPixels = 0;
+ result = mQuery->GetData(&numPixels, sizeof(numPixels), D3DGETDATA_FLUSH);
+ if (result == S_OK)
+ {
+ mQueryFinished = true;
+ mResult = (numPixels > 0) ? GL_TRUE : GL_FALSE;
+ }
+ break;
+ }
+
+ case gl::QueryType::CommandsCompleted:
+ {
+ BOOL completed = FALSE;
+ result = mQuery->GetData(&completed, sizeof(completed), D3DGETDATA_FLUSH);
+ if (result == S_OK)
+ {
+ mQueryFinished = true;
+ mResult = (completed == TRUE) ? GL_TRUE : GL_FALSE;
+ }
+ break;
+ }
+
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ if (!mQueryFinished)
+ {
+ ANGLE_TRY_HR(context9, result, "Failed to test get query result");
+
+ mGetDataAttemptCount++;
+ bool checkDeviceLost =
+ (mGetDataAttemptCount % kPollingD3DDeviceLostCheckFrequency) == 0;
+ if (checkDeviceLost && mRenderer->testDeviceLost())
+ {
+ ANGLE_TRY_HR(context9, D3DERR_DEVICELOST,
+ "Failed to test get query result, device is lost");
+ }
+ }
+ }
+
+ return angle::Result::Continue;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Query9.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Query9.h
new file mode 100644
index 0000000000..df10ded225
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Query9.h
@@ -0,0 +1,50 @@
+//
+// Copyright 2013 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.
+//
+
+// Query9.h: Defines the rx::Query9 class which implements rx::QueryImpl.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D9_QUERY9_H_
+#define LIBANGLE_RENDERER_D3D_D3D9_QUERY9_H_
+
+#include "libANGLE/renderer/QueryImpl.h"
+
+namespace rx
+{
+class Context9;
+class Renderer9;
+
+class Query9 : public QueryImpl
+{
+ public:
+ Query9(Renderer9 *renderer, gl::QueryType type);
+ ~Query9() override;
+
+ angle::Result begin(const gl::Context *context) override;
+ angle::Result end(const gl::Context *context) override;
+ angle::Result queryCounter(const gl::Context *context) override;
+ angle::Result getResult(const gl::Context *context, GLint *params) override;
+ angle::Result getResult(const gl::Context *context, GLuint *params) override;
+ angle::Result getResult(const gl::Context *context, GLint64 *params) override;
+ angle::Result getResult(const gl::Context *context, GLuint64 *params) override;
+ angle::Result isResultAvailable(const gl::Context *context, bool *available) override;
+
+ private:
+ angle::Result testQuery(Context9 *context9);
+
+ template <typename T>
+ angle::Result getResultBase(Context9 *context9, T *params);
+
+ unsigned int mGetDataAttemptCount;
+ GLuint64 mResult;
+ bool mQueryFinished;
+
+ Renderer9 *mRenderer;
+ IDirect3DQuery9 *mQuery;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D9_QUERY9_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.cpp
new file mode 100644
index 0000000000..54c3291799
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.cpp
@@ -0,0 +1,160 @@
+//
+// Copyright 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.
+//
+
+// RenderTarget9.cpp: Implements a D3D9-specific wrapper for IDirect3DSurface9
+// pointers retained by renderbuffers.
+
+#include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h"
+#include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
+#include "libANGLE/renderer/d3d/d3d9/SwapChain9.h"
+#include "libANGLE/renderer/d3d/d3d9/formatutils9.h"
+#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h"
+
+namespace rx
+{
+
+// TODO: AddRef the incoming surface to take ownership instead of expecting that its ref is being
+// given.
+TextureRenderTarget9::TextureRenderTarget9(IDirect3DBaseTexture9 *texture,
+ size_t textureLevel,
+ IDirect3DSurface9 *surface,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLsizei samples)
+ : mWidth(width),
+ mHeight(height),
+ mDepth(depth),
+ mInternalFormat(internalFormat),
+ mD3DFormat(D3DFMT_UNKNOWN),
+ mSamples(samples),
+ mTexture(texture),
+ mTextureLevel(textureLevel),
+ mRenderTarget(surface)
+{
+ ASSERT(mDepth == 1);
+
+ if (mRenderTarget)
+ {
+ D3DSURFACE_DESC description;
+ mRenderTarget->GetDesc(&description);
+ mD3DFormat = description.Format;
+ }
+}
+
+TextureRenderTarget9::~TextureRenderTarget9()
+{
+ SafeRelease(mTexture);
+ SafeRelease(mRenderTarget);
+}
+
+GLsizei TextureRenderTarget9::getWidth() const
+{
+ return mWidth;
+}
+
+GLsizei TextureRenderTarget9::getHeight() const
+{
+ return mHeight;
+}
+
+GLsizei TextureRenderTarget9::getDepth() const
+{
+ return mDepth;
+}
+
+GLenum TextureRenderTarget9::getInternalFormat() const
+{
+ return mInternalFormat;
+}
+
+GLsizei TextureRenderTarget9::getSamples() const
+{
+ return mSamples;
+}
+
+IDirect3DBaseTexture9 *TextureRenderTarget9::getTexture() const
+{
+ return mTexture;
+}
+
+size_t TextureRenderTarget9::getTextureLevel() const
+{
+ return mTextureLevel;
+}
+
+IDirect3DSurface9 *TextureRenderTarget9::getSurface() const
+{
+ // Caller is responsible for releasing the returned surface reference.
+ // TODO: remove the AddRef to match RenderTarget11
+ if (mRenderTarget)
+ {
+ mRenderTarget->AddRef();
+ }
+
+ return mRenderTarget;
+}
+
+D3DFORMAT TextureRenderTarget9::getD3DFormat() const
+{
+ return mD3DFormat;
+}
+
+SurfaceRenderTarget9::SurfaceRenderTarget9(SwapChain9 *swapChain, bool depth)
+ : mSwapChain(swapChain), mDepth(depth)
+{}
+
+SurfaceRenderTarget9::~SurfaceRenderTarget9() {}
+
+GLsizei SurfaceRenderTarget9::getWidth() const
+{
+ return mSwapChain->getWidth();
+}
+
+GLsizei SurfaceRenderTarget9::getHeight() const
+{
+ return mSwapChain->getHeight();
+}
+
+GLsizei SurfaceRenderTarget9::getDepth() const
+{
+ return 1;
+}
+
+GLenum SurfaceRenderTarget9::getInternalFormat() const
+{
+ return (mDepth ? mSwapChain->getDepthBufferInternalFormat()
+ : mSwapChain->getRenderTargetInternalFormat());
+}
+
+GLsizei SurfaceRenderTarget9::getSamples() const
+{
+ // Our EGL surfaces do not support multisampling.
+ return 0;
+}
+
+IDirect3DSurface9 *SurfaceRenderTarget9::getSurface() const
+{
+ return (mDepth ? mSwapChain->getDepthStencil() : mSwapChain->getRenderTarget());
+}
+
+IDirect3DBaseTexture9 *SurfaceRenderTarget9::getTexture() const
+{
+ return (mDepth ? nullptr : mSwapChain->getOffscreenTexture());
+}
+
+size_t SurfaceRenderTarget9::getTextureLevel() const
+{
+ return 0;
+}
+
+D3DFORMAT SurfaceRenderTarget9::getD3DFormat() const
+{
+ return d3d9::GetTextureFormatInfo(getInternalFormat()).texFormat;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.h
new file mode 100644
index 0000000000..010955eb41
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.h
@@ -0,0 +1,98 @@
+//
+// Copyright 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.
+//
+
+// RenderTarget9.h: Defines a D3D9-specific wrapper for IDirect3DSurface9 pointers
+// retained by Renderbuffers.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D9_RENDERTARGET9_H_
+#define LIBANGLE_RENDERER_D3D_D3D9_RENDERTARGET9_H_
+
+#include "libANGLE/renderer/d3d/RenderTargetD3D.h"
+
+namespace rx
+{
+class Renderer9;
+class SwapChain9;
+
+class RenderTarget9 : public RenderTargetD3D
+{
+ public:
+ RenderTarget9() {}
+ ~RenderTarget9() override {}
+ // Retrieve the texture that backs this render target, may be null for swap chain render
+ // targets.
+ virtual IDirect3DBaseTexture9 *getTexture() const = 0;
+ virtual size_t getTextureLevel() const = 0;
+
+ virtual IDirect3DSurface9 *getSurface() const = 0;
+
+ virtual D3DFORMAT getD3DFormat() const = 0;
+};
+
+class TextureRenderTarget9 : public RenderTarget9
+{
+ public:
+ TextureRenderTarget9(IDirect3DBaseTexture9 *texture,
+ size_t textureLevel,
+ IDirect3DSurface9 *surface,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLsizei samples);
+ ~TextureRenderTarget9() override;
+
+ GLsizei getWidth() const override;
+ GLsizei getHeight() const override;
+ GLsizei getDepth() const override;
+ GLenum getInternalFormat() const override;
+ GLsizei getSamples() const override;
+
+ IDirect3DBaseTexture9 *getTexture() const override;
+ size_t getTextureLevel() const override;
+ IDirect3DSurface9 *getSurface() const override;
+
+ D3DFORMAT getD3DFormat() const override;
+
+ private:
+ GLsizei mWidth;
+ GLsizei mHeight;
+ GLsizei mDepth;
+ GLenum mInternalFormat;
+ D3DFORMAT mD3DFormat;
+ GLsizei mSamples;
+
+ IDirect3DBaseTexture9 *mTexture;
+ size_t mTextureLevel;
+ IDirect3DSurface9 *mRenderTarget;
+};
+
+class SurfaceRenderTarget9 : public RenderTarget9
+{
+ public:
+ SurfaceRenderTarget9(SwapChain9 *swapChain, bool depth);
+ ~SurfaceRenderTarget9() override;
+
+ GLsizei getWidth() const override;
+ GLsizei getHeight() const override;
+ GLsizei getDepth() const override;
+ GLenum getInternalFormat() const override;
+ GLsizei getSamples() const override;
+
+ IDirect3DBaseTexture9 *getTexture() const override;
+ size_t getTextureLevel() const override;
+ IDirect3DSurface9 *getSurface() const override;
+
+ D3DFORMAT getD3DFormat() const override;
+
+ private:
+ SwapChain9 *mSwapChain;
+ bool mDepth;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D9_RENDERTARGET9_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
new file mode 100644
index 0000000000..d80997392d
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
@@ -0,0 +1,3338 @@
+//
+// Copyright 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.
+//
+
+// Renderer9.cpp: Implements a back-end specific class for the D3D9 renderer.
+
+#include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
+
+#include <EGL/eglext.h>
+#include <sstream>
+
+#include "common/utilities.h"
+#include "libANGLE/Buffer.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Display.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/Program.h"
+#include "libANGLE/Renderbuffer.h"
+#include "libANGLE/State.h"
+#include "libANGLE/Surface.h"
+#include "libANGLE/Texture.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/features.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/d3d/CompilerD3D.h"
+#include "libANGLE/renderer/d3d/DeviceD3D.h"
+#include "libANGLE/renderer/d3d/DisplayD3D.h"
+#include "libANGLE/renderer/d3d/FramebufferD3D.h"
+#include "libANGLE/renderer/d3d/IndexDataManager.h"
+#include "libANGLE/renderer/d3d/ProgramD3D.h"
+#include "libANGLE/renderer/d3d/RenderbufferD3D.h"
+#include "libANGLE/renderer/d3d/ShaderD3D.h"
+#include "libANGLE/renderer/d3d/SurfaceD3D.h"
+#include "libANGLE/renderer/d3d/TextureD3D.h"
+#include "libANGLE/renderer/d3d/d3d9/Blit9.h"
+#include "libANGLE/renderer/d3d/d3d9/Buffer9.h"
+#include "libANGLE/renderer/d3d/d3d9/Context9.h"
+#include "libANGLE/renderer/d3d/d3d9/Fence9.h"
+#include "libANGLE/renderer/d3d/d3d9/Framebuffer9.h"
+#include "libANGLE/renderer/d3d/d3d9/Image9.h"
+#include "libANGLE/renderer/d3d/d3d9/IndexBuffer9.h"
+#include "libANGLE/renderer/d3d/d3d9/NativeWindow9.h"
+#include "libANGLE/renderer/d3d/d3d9/Query9.h"
+#include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h"
+#include "libANGLE/renderer/d3d/d3d9/ShaderExecutable9.h"
+#include "libANGLE/renderer/d3d/d3d9/SwapChain9.h"
+#include "libANGLE/renderer/d3d/d3d9/TextureStorage9.h"
+#include "libANGLE/renderer/d3d/d3d9/VertexArray9.h"
+#include "libANGLE/renderer/d3d/d3d9/VertexBuffer9.h"
+#include "libANGLE/renderer/d3d/d3d9/formatutils9.h"
+#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h"
+#include "libANGLE/renderer/d3d/driver_utils_d3d.h"
+#include "libANGLE/renderer/driver_utils.h"
+#include "libANGLE/trace.h"
+
+#if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL)
+# define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL3
+#endif
+
+// Enable ANGLE_SUPPORT_SHADER_MODEL_2 if you wish devices with only shader model 2.
+// Such a device would not be conformant.
+#ifndef ANGLE_SUPPORT_SHADER_MODEL_2
+# define ANGLE_SUPPORT_SHADER_MODEL_2 0
+#endif
+
+namespace rx
+{
+
+namespace
+{
+enum
+{
+ MAX_VERTEX_CONSTANT_VECTORS_D3D9 = 256,
+ MAX_PIXEL_CONSTANT_VECTORS_SM2 = 32,
+ MAX_PIXEL_CONSTANT_VECTORS_SM3 = 224,
+ MAX_VARYING_VECTORS_SM2 = 8,
+ MAX_VARYING_VECTORS_SM3 = 10,
+
+ MAX_TEXTURE_IMAGE_UNITS_VTF_SM3 = 4
+};
+
+template <typename T>
+static void DrawPoints(IDirect3DDevice9 *device, GLsizei count, const void *indices, int minIndex)
+{
+ for (int i = 0; i < count; i++)
+ {
+ unsigned int indexValue =
+ static_cast<unsigned int>(static_cast<const T *>(indices)[i]) - minIndex;
+ device->DrawPrimitive(D3DPT_POINTLIST, indexValue, 1);
+ }
+}
+
+// A hard limit on buffer size. This works around a problem in the NVIDIA drivers where buffer sizes
+// close to MAX_UINT would give undefined results. The limit of MAX_UINT/2 should be generous enough
+// for almost any demanding application.
+constexpr UINT kMaximumBufferSizeHardLimit = std::numeric_limits<UINT>::max() >> 1;
+} // anonymous namespace
+
+Renderer9::Renderer9(egl::Display *display) : RendererD3D(display), mStateManager(this)
+{
+ mD3d9Module = nullptr;
+
+ mD3d9 = nullptr;
+ mD3d9Ex = nullptr;
+ mDevice = nullptr;
+ mDeviceEx = nullptr;
+ mDeviceWindow = nullptr;
+ mBlit = nullptr;
+
+ mAdapter = D3DADAPTER_DEFAULT;
+
+ const egl::AttributeMap &attributes = display->getAttributeMap();
+ EGLint requestedDeviceType = static_cast<EGLint>(attributes.get(
+ EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE));
+ switch (requestedDeviceType)
+ {
+ case EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE:
+ mDeviceType = D3DDEVTYPE_HAL;
+ break;
+
+ case EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_REFERENCE_ANGLE:
+ mDeviceType = D3DDEVTYPE_REF;
+ break;
+
+ case EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE:
+ mDeviceType = D3DDEVTYPE_NULLREF;
+ break;
+
+ default:
+ UNREACHABLE();
+ }
+
+ mMaskedClearSavedState = nullptr;
+
+ mVertexDataManager = nullptr;
+ mIndexDataManager = nullptr;
+ mLineLoopIB = nullptr;
+ mCountingIB = nullptr;
+
+ mMaxNullColorbufferLRU = 0;
+ for (int i = 0; i < NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++)
+ {
+ mNullRenderTargetCache[i].lruCount = 0;
+ mNullRenderTargetCache[i].width = 0;
+ mNullRenderTargetCache[i].height = 0;
+ mNullRenderTargetCache[i].renderTarget = nullptr;
+ }
+
+ mAppliedVertexShader = nullptr;
+ mAppliedPixelShader = nullptr;
+ mAppliedProgramSerial = 0;
+
+ gl::InitializeDebugAnnotations(&mAnnotator);
+}
+
+void Renderer9::setGlobalDebugAnnotator()
+{
+ gl::InitializeDebugAnnotations(&mAnnotator);
+}
+
+Renderer9::~Renderer9()
+{
+ if (mDevice)
+ {
+ // If the device is lost, reset it first to prevent leaving the driver in an unstable state
+ if (testDeviceLost())
+ {
+ resetDevice();
+ }
+ }
+
+ release();
+}
+
+void Renderer9::release()
+{
+ gl::UninitializeDebugAnnotations();
+
+ mTranslatedAttribCache.clear();
+
+ releaseDeviceResources();
+
+ SafeRelease(mDevice);
+ SafeRelease(mDeviceEx);
+ SafeRelease(mD3d9);
+ SafeRelease(mD3d9Ex);
+
+ mCompiler.release();
+
+ if (mDeviceWindow)
+ {
+ DestroyWindow(mDeviceWindow);
+ mDeviceWindow = nullptr;
+ }
+
+ mD3d9Module = nullptr;
+}
+
+egl::Error Renderer9::initialize()
+{
+ ANGLE_TRACE_EVENT0("gpu.angle", "GetModuleHandle_d3d9");
+ mD3d9Module = ::LoadLibrary(TEXT("d3d9.dll"));
+
+ if (mD3d9Module == nullptr)
+ {
+ return egl::EglNotInitialized(D3D9_INIT_MISSING_DEP) << "No D3D9 module found.";
+ }
+
+ typedef HRESULT(WINAPI * Direct3DCreate9ExFunc)(UINT, IDirect3D9Ex **);
+ Direct3DCreate9ExFunc Direct3DCreate9ExPtr =
+ reinterpret_cast<Direct3DCreate9ExFunc>(GetProcAddress(mD3d9Module, "Direct3DCreate9Ex"));
+
+ // Use Direct3D9Ex if available. Among other things, this version is less
+ // inclined to report a lost context, for example when the user switches
+ // desktop. Direct3D9Ex is available in Windows Vista and later if suitable drivers are
+ // available.
+ if (ANGLE_D3D9EX == ANGLE_ENABLED && Direct3DCreate9ExPtr &&
+ SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9Ex)))
+ {
+ ANGLE_TRACE_EVENT0("gpu.angle", "D3d9Ex_QueryInterface");
+ ASSERT(mD3d9Ex);
+ mD3d9Ex->QueryInterface(__uuidof(IDirect3D9), reinterpret_cast<void **>(&mD3d9));
+ ASSERT(mD3d9);
+ }
+ else
+ {
+ ANGLE_TRACE_EVENT0("gpu.angle", "Direct3DCreate9");
+ mD3d9 = Direct3DCreate9(D3D_SDK_VERSION);
+ }
+
+ if (!mD3d9)
+ {
+ return egl::EglNotInitialized(D3D9_INIT_MISSING_DEP) << "Could not create D3D9 device.";
+ }
+
+ if (mDisplay->getNativeDisplayId() != nullptr)
+ {
+ // UNIMPLEMENTED(); // FIXME: Determine which adapter index the device context
+ // corresponds to
+ }
+
+ HRESULT result;
+
+ // Give up on getting device caps after about one second.
+ {
+ ANGLE_TRACE_EVENT0("gpu.angle", "GetDeviceCaps");
+ for (int i = 0; i < 10; ++i)
+ {
+ result = mD3d9->GetDeviceCaps(mAdapter, mDeviceType, &mDeviceCaps);
+ if (SUCCEEDED(result))
+ {
+ break;
+ }
+ else if (result == D3DERR_NOTAVAILABLE)
+ {
+ Sleep(100); // Give the driver some time to initialize/recover
+ }
+ else if (FAILED(result)) // D3DERR_OUTOFVIDEOMEMORY, E_OUTOFMEMORY,
+ // D3DERR_INVALIDDEVICE, or another error we can't recover
+ // from
+ {
+ return egl::EglNotInitialized(D3D9_INIT_OTHER_ERROR)
+ << "Failed to get device caps, " << gl::FmtHR(result);
+ }
+ }
+ }
+
+#if ANGLE_SUPPORT_SHADER_MODEL_2
+ size_t minShaderModel = 2;
+#else
+ size_t minShaderModel = 3;
+#endif
+
+ if (mDeviceCaps.PixelShaderVersion < D3DPS_VERSION(minShaderModel, 0))
+ {
+ return egl::EglNotInitialized(D3D9_INIT_UNSUPPORTED_VERSION)
+ << "Renderer does not support PS " << minShaderModel << ".0, aborting!";
+ }
+
+ // When DirectX9 is running with an older DirectX8 driver, a StretchRect from a regular texture
+ // to a render target texture is not supported. This is required by
+ // Texture2D::ensureRenderTarget.
+ if ((mDeviceCaps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES) == 0)
+ {
+ return egl::EglNotInitialized(D3D9_INIT_UNSUPPORTED_STRETCHRECT)
+ << "Renderer does not support StretctRect from textures.";
+ }
+
+ {
+ ANGLE_TRACE_EVENT0("gpu.angle", "GetAdapterIdentifier");
+ mD3d9->GetAdapterIdentifier(mAdapter, 0, &mAdapterIdentifier);
+ }
+
+ static const TCHAR windowName[] = TEXT("AngleHiddenWindow");
+ static const TCHAR className[] = TEXT("STATIC");
+
+ {
+ ANGLE_TRACE_EVENT0("gpu.angle", "CreateWindowEx");
+ mDeviceWindow =
+ CreateWindowEx(WS_EX_NOACTIVATE, className, windowName, WS_DISABLED | WS_POPUP, 0, 0, 1,
+ 1, HWND_MESSAGE, nullptr, GetModuleHandle(nullptr), nullptr);
+ }
+
+ D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters();
+ DWORD behaviorFlags =
+ D3DCREATE_FPU_PRESERVE | D3DCREATE_NOWINDOWCHANGES | D3DCREATE_MULTITHREADED;
+
+ {
+ ANGLE_TRACE_EVENT0("gpu.angle", "D3d9_CreateDevice");
+ result = mD3d9->CreateDevice(
+ mAdapter, mDeviceType, mDeviceWindow,
+ behaviorFlags | D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE,
+ &presentParameters, &mDevice);
+
+ if (FAILED(result))
+ {
+ ERR() << "CreateDevice1 failed: (" << gl::FmtHR(result) << ")";
+ }
+ }
+ if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DEVICELOST)
+ {
+ return egl::EglBadAlloc(D3D9_INIT_OUT_OF_MEMORY)
+ << "CreateDevice failed: device lost or out of memory (" << gl::FmtHR(result) << ")";
+ }
+
+ if (FAILED(result))
+ {
+ ANGLE_TRACE_EVENT0("gpu.angle", "D3d9_CreateDevice2");
+ result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow,
+ behaviorFlags | D3DCREATE_SOFTWARE_VERTEXPROCESSING,
+ &presentParameters, &mDevice);
+
+ if (FAILED(result))
+ {
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY ||
+ result == D3DERR_NOTAVAILABLE || result == D3DERR_DEVICELOST);
+ return egl::EglBadAlloc(D3D9_INIT_OUT_OF_MEMORY)
+ << "CreateDevice2 failed: device lost, not available, or of out of memory ("
+ << gl::FmtHR(result) << ")";
+ }
+ }
+
+ if (mD3d9Ex)
+ {
+ ANGLE_TRACE_EVENT0("gpu.angle", "mDevice_QueryInterface");
+ result = mDevice->QueryInterface(__uuidof(IDirect3DDevice9Ex), (void **)&mDeviceEx);
+ ASSERT(SUCCEEDED(result));
+ }
+
+ {
+ ANGLE_TRACE_EVENT0("gpu.angle", "ShaderCache initialize");
+ mVertexShaderCache.initialize(mDevice);
+ mPixelShaderCache.initialize(mDevice);
+ }
+
+ D3DDISPLAYMODE currentDisplayMode;
+ mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
+
+ // Check vertex texture support
+ // Only Direct3D 10 ready devices support all the necessary vertex texture formats.
+ // We test this using D3D9 by checking support for the R16F format.
+ mVertexTextureSupport = mDeviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0) &&
+ SUCCEEDED(mD3d9->CheckDeviceFormat(
+ mAdapter, mDeviceType, currentDisplayMode.Format,
+ D3DUSAGE_QUERY_VERTEXTEXTURE, D3DRTYPE_TEXTURE, D3DFMT_R16F));
+
+ ANGLE_TRY(initializeDevice());
+
+ return egl::NoError();
+}
+
+// do any one-time device initialization
+// NOTE: this is also needed after a device lost/reset
+// to reset the scene status and ensure the default states are reset.
+egl::Error Renderer9::initializeDevice()
+{
+ // Permanent non-default states
+ mDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);
+ mDevice->SetRenderState(D3DRS_LASTPIXEL, FALSE);
+
+ if (mDeviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0))
+ {
+ mDevice->SetRenderState(D3DRS_POINTSIZE_MAX, (DWORD &)mDeviceCaps.MaxPointSize);
+ }
+ else
+ {
+ mDevice->SetRenderState(D3DRS_POINTSIZE_MAX, 0x3F800000); // 1.0f
+ }
+
+ const gl::Caps &rendererCaps = getNativeCaps();
+
+ mCurVertexSamplerStates.resize(rendererCaps.maxShaderTextureImageUnits[gl::ShaderType::Vertex]);
+ mCurPixelSamplerStates.resize(
+ rendererCaps.maxShaderTextureImageUnits[gl::ShaderType::Fragment]);
+
+ mCurVertexTextures.resize(rendererCaps.maxShaderTextureImageUnits[gl::ShaderType::Vertex]);
+ mCurPixelTextures.resize(rendererCaps.maxShaderTextureImageUnits[gl::ShaderType::Fragment]);
+
+ markAllStateDirty();
+
+ mSceneStarted = false;
+
+ ASSERT(!mBlit);
+ mBlit = new Blit9(this);
+
+ ASSERT(!mVertexDataManager && !mIndexDataManager);
+ mIndexDataManager = new IndexDataManager(this);
+
+ mTranslatedAttribCache.resize(getNativeCaps().maxVertexAttributes);
+
+ mStateManager.initialize();
+
+ return egl::NoError();
+}
+
+D3DPRESENT_PARAMETERS Renderer9::getDefaultPresentParameters()
+{
+ D3DPRESENT_PARAMETERS presentParameters = {};
+
+ // The default swap chain is never actually used. Surface will create a new swap chain with the
+ // proper parameters.
+ presentParameters.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
+ presentParameters.BackBufferCount = 1;
+ presentParameters.BackBufferFormat = D3DFMT_UNKNOWN;
+ presentParameters.BackBufferWidth = 1;
+ presentParameters.BackBufferHeight = 1;
+ presentParameters.EnableAutoDepthStencil = FALSE;
+ presentParameters.Flags = 0;
+ presentParameters.hDeviceWindow = mDeviceWindow;
+ presentParameters.MultiSampleQuality = 0;
+ presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE;
+ presentParameters.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
+ presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
+ presentParameters.Windowed = TRUE;
+
+ return presentParameters;
+}
+
+egl::ConfigSet Renderer9::generateConfigs()
+{
+ static const GLenum colorBufferFormats[] = {
+ GL_BGR5_A1_ANGLEX,
+ GL_BGRA8_EXT,
+ GL_RGB565,
+
+ };
+
+ static const GLenum depthStencilBufferFormats[] = {
+ GL_NONE,
+ GL_DEPTH_COMPONENT32_OES,
+ GL_DEPTH24_STENCIL8_OES,
+ GL_DEPTH_COMPONENT24_OES,
+ GL_DEPTH_COMPONENT16,
+ };
+
+ const gl::Caps &rendererCaps = getNativeCaps();
+ const gl::TextureCapsMap &rendererTextureCaps = getNativeTextureCaps();
+
+ D3DDISPLAYMODE currentDisplayMode;
+ mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
+
+ // Determine the min and max swap intervals
+ int minSwapInterval = 4;
+ int maxSwapInterval = 0;
+
+ if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_IMMEDIATE)
+ {
+ minSwapInterval = std::min(minSwapInterval, 0);
+ maxSwapInterval = std::max(maxSwapInterval, 0);
+ }
+ if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_ONE)
+ {
+ minSwapInterval = std::min(minSwapInterval, 1);
+ maxSwapInterval = std::max(maxSwapInterval, 1);
+ }
+ if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_TWO)
+ {
+ minSwapInterval = std::min(minSwapInterval, 2);
+ maxSwapInterval = std::max(maxSwapInterval, 2);
+ }
+ if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_THREE)
+ {
+ minSwapInterval = std::min(minSwapInterval, 3);
+ maxSwapInterval = std::max(maxSwapInterval, 3);
+ }
+ if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_FOUR)
+ {
+ minSwapInterval = std::min(minSwapInterval, 4);
+ maxSwapInterval = std::max(maxSwapInterval, 4);
+ }
+
+ egl::ConfigSet configs;
+ for (size_t formatIndex = 0; formatIndex < ArraySize(colorBufferFormats); formatIndex++)
+ {
+ GLenum colorBufferInternalFormat = colorBufferFormats[formatIndex];
+ const gl::TextureCaps &colorBufferFormatCaps =
+ rendererTextureCaps.get(colorBufferInternalFormat);
+ if (colorBufferFormatCaps.renderbuffer)
+ {
+ ASSERT(colorBufferFormatCaps.textureAttachment);
+ for (size_t depthStencilIndex = 0;
+ depthStencilIndex < ArraySize(depthStencilBufferFormats); depthStencilIndex++)
+ {
+ GLenum depthStencilBufferInternalFormat =
+ depthStencilBufferFormats[depthStencilIndex];
+ const gl::TextureCaps &depthStencilBufferFormatCaps =
+ rendererTextureCaps.get(depthStencilBufferInternalFormat);
+ if (depthStencilBufferFormatCaps.renderbuffer ||
+ depthStencilBufferInternalFormat == GL_NONE)
+ {
+ ASSERT(depthStencilBufferFormatCaps.textureAttachment ||
+ depthStencilBufferInternalFormat == GL_NONE);
+ const gl::InternalFormat &colorBufferFormatInfo =
+ gl::GetSizedInternalFormatInfo(colorBufferInternalFormat);
+ const gl::InternalFormat &depthStencilBufferFormatInfo =
+ gl::GetSizedInternalFormatInfo(depthStencilBufferInternalFormat);
+ const d3d9::TextureFormat &d3d9ColorBufferFormatInfo =
+ d3d9::GetTextureFormatInfo(colorBufferInternalFormat);
+
+ egl::Config config;
+ config.renderTargetFormat = colorBufferInternalFormat;
+ config.depthStencilFormat = depthStencilBufferInternalFormat;
+ config.bufferSize = colorBufferFormatInfo.pixelBytes * 8;
+ config.redSize = colorBufferFormatInfo.redBits;
+ config.greenSize = colorBufferFormatInfo.greenBits;
+ config.blueSize = colorBufferFormatInfo.blueBits;
+ config.luminanceSize = colorBufferFormatInfo.luminanceBits;
+ config.alphaSize = colorBufferFormatInfo.alphaBits;
+ config.alphaMaskSize = 0;
+ config.bindToTextureRGB = (colorBufferFormatInfo.format == GL_RGB);
+ config.bindToTextureRGBA = (colorBufferFormatInfo.format == GL_RGBA ||
+ colorBufferFormatInfo.format == GL_BGRA_EXT);
+ config.colorBufferType = EGL_RGB_BUFFER;
+ // Mark as slow if blits to the back-buffer won't be straight forward
+ config.configCaveat =
+ (currentDisplayMode.Format == d3d9ColorBufferFormatInfo.renderFormat)
+ ? EGL_NONE
+ : EGL_SLOW_CONFIG;
+ config.configID = static_cast<EGLint>(configs.size() + 1);
+ config.conformant = EGL_OPENGL_ES2_BIT;
+ config.depthSize = depthStencilBufferFormatInfo.depthBits;
+ config.level = 0;
+ config.matchNativePixmap = EGL_NONE;
+ config.maxPBufferWidth = rendererCaps.max2DTextureSize;
+ config.maxPBufferHeight = rendererCaps.max2DTextureSize;
+ config.maxPBufferPixels =
+ rendererCaps.max2DTextureSize * rendererCaps.max2DTextureSize;
+ config.maxSwapInterval = maxSwapInterval;
+ config.minSwapInterval = minSwapInterval;
+ config.nativeRenderable = EGL_FALSE;
+ config.nativeVisualID = 0;
+ config.nativeVisualType = EGL_NONE;
+ config.renderableType = EGL_OPENGL_ES2_BIT;
+ config.sampleBuffers = 0; // FIXME: enumerate multi-sampling
+ config.samples = 0;
+ config.stencilSize = depthStencilBufferFormatInfo.stencilBits;
+ config.surfaceType =
+ EGL_PBUFFER_BIT | EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
+ config.transparentType = EGL_NONE;
+ config.transparentRedValue = 0;
+ config.transparentGreenValue = 0;
+ config.transparentBlueValue = 0;
+ config.colorComponentType = gl_egl::GLComponentTypeToEGLColorComponentType(
+ colorBufferFormatInfo.componentType);
+
+ configs.add(config);
+ }
+ }
+ }
+ }
+
+ ASSERT(configs.size() > 0);
+ return configs;
+}
+
+void Renderer9::generateDisplayExtensions(egl::DisplayExtensions *outExtensions) const
+{
+ outExtensions->createContextRobustness = true;
+
+ if (getShareHandleSupport())
+ {
+ outExtensions->d3dShareHandleClientBuffer = true;
+ outExtensions->surfaceD3DTexture2DShareHandle = true;
+ }
+ outExtensions->d3dTextureClientBuffer = true;
+
+ outExtensions->querySurfacePointer = true;
+ outExtensions->windowFixedSize = true;
+ outExtensions->postSubBuffer = true;
+
+ outExtensions->image = true;
+ outExtensions->imageBase = true;
+ outExtensions->glTexture2DImage = true;
+ outExtensions->glRenderbufferImage = true;
+
+ outExtensions->noConfigContext = true;
+
+ // Contexts are virtualized so textures and semaphores can be shared globally
+ outExtensions->displayTextureShareGroup = true;
+ outExtensions->displaySemaphoreShareGroup = true;
+
+ // D3D9 can be used without an output surface
+ outExtensions->surfacelessContext = true;
+
+ outExtensions->robustResourceInitializationANGLE = true;
+}
+
+void Renderer9::startScene()
+{
+ if (!mSceneStarted)
+ {
+ long result = mDevice->BeginScene();
+ if (SUCCEEDED(result))
+ {
+ // This is defensive checking against the device being
+ // lost at unexpected times.
+ mSceneStarted = true;
+ }
+ }
+}
+
+void Renderer9::endScene()
+{
+ if (mSceneStarted)
+ {
+ // EndScene can fail if the device was lost, for example due
+ // to a TDR during a draw call.
+ mDevice->EndScene();
+ mSceneStarted = false;
+ }
+}
+
+angle::Result Renderer9::flush(const gl::Context *context)
+{
+ IDirect3DQuery9 *query = nullptr;
+ ANGLE_TRY(allocateEventQuery(context, &query));
+
+ Context9 *context9 = GetImplAs<Context9>(context);
+
+ HRESULT result = query->Issue(D3DISSUE_END);
+ ANGLE_TRY_HR(context9, result, "Failed to issue event query");
+
+ // Grab the query data once
+ result = query->GetData(nullptr, 0, D3DGETDATA_FLUSH);
+ freeEventQuery(query);
+ ANGLE_TRY_HR(context9, result, "Failed to get event query data");
+
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer9::finish(const gl::Context *context)
+{
+ IDirect3DQuery9 *query = nullptr;
+ ANGLE_TRY(allocateEventQuery(context, &query));
+
+ Context9 *context9 = GetImplAs<Context9>(context);
+
+ HRESULT result = query->Issue(D3DISSUE_END);
+ ANGLE_TRY_HR(context9, result, "Failed to issue event query");
+
+ // Grab the query data once
+ result = query->GetData(nullptr, 0, D3DGETDATA_FLUSH);
+ if (FAILED(result))
+ {
+ freeEventQuery(query);
+ }
+ ANGLE_TRY_HR(context9, result, "Failed to get event query data");
+
+ // Loop until the query completes
+ unsigned int attempt = 0;
+ while (result == S_FALSE)
+ {
+ // Keep polling, but allow other threads to do something useful first
+ ScheduleYield();
+
+ result = query->GetData(nullptr, 0, D3DGETDATA_FLUSH);
+ attempt++;
+
+ if (result == S_FALSE)
+ {
+ // explicitly check for device loss
+ // some drivers seem to return S_FALSE even if the device is lost
+ // instead of D3DERR_DEVICELOST like they should
+ bool checkDeviceLost = (attempt % kPollingD3DDeviceLostCheckFrequency) == 0;
+ if (checkDeviceLost && testDeviceLost())
+ {
+ result = D3DERR_DEVICELOST;
+ }
+ }
+
+ if (FAILED(result))
+ {
+ freeEventQuery(query);
+ }
+ ANGLE_TRY_HR(context9, result, "Failed to get event query data");
+ }
+
+ freeEventQuery(query);
+
+ return angle::Result::Continue;
+}
+
+bool Renderer9::isValidNativeWindow(EGLNativeWindowType window) const
+{
+ return NativeWindow9::IsValidNativeWindow(window);
+}
+
+NativeWindowD3D *Renderer9::createNativeWindow(EGLNativeWindowType window,
+ const egl::Config *,
+ const egl::AttributeMap &) const
+{
+ return new NativeWindow9(window);
+}
+
+SwapChainD3D *Renderer9::createSwapChain(NativeWindowD3D *nativeWindow,
+ HANDLE shareHandle,
+ IUnknown *d3dTexture,
+ GLenum backBufferFormat,
+ GLenum depthBufferFormat,
+ EGLint orientation,
+ EGLint samples)
+{
+ return new SwapChain9(this, GetAs<NativeWindow9>(nativeWindow), shareHandle, d3dTexture,
+ backBufferFormat, depthBufferFormat, orientation);
+}
+
+egl::Error Renderer9::getD3DTextureInfo(const egl::Config *configuration,
+ IUnknown *d3dTexture,
+ const egl::AttributeMap &attribs,
+ EGLint *width,
+ EGLint *height,
+ GLsizei *samples,
+ gl::Format *glFormat,
+ const angle::Format **angleFormat,
+ UINT *arraySlice) const
+{
+ IDirect3DTexture9 *texture = nullptr;
+ if (FAILED(d3dTexture->QueryInterface(&texture)))
+ {
+ return egl::EglBadParameter() << "Client buffer is not a IDirect3DTexture9";
+ }
+
+ IDirect3DDevice9 *textureDevice = nullptr;
+ texture->GetDevice(&textureDevice);
+ if (textureDevice != mDevice)
+ {
+ SafeRelease(texture);
+ return egl::EglBadParameter() << "Texture's device does not match.";
+ }
+ SafeRelease(textureDevice);
+
+ D3DSURFACE_DESC desc;
+ texture->GetLevelDesc(0, &desc);
+ SafeRelease(texture);
+
+ if (width)
+ {
+ *width = static_cast<EGLint>(desc.Width);
+ }
+ if (height)
+ {
+ *height = static_cast<EGLint>(desc.Height);
+ }
+
+ // GetSamplesCount() returns 0 when multisampling isn't used.
+ GLsizei sampleCount = d3d9_gl::GetSamplesCount(desc.MultiSampleType);
+ if ((configuration && configuration->samples > 1) || sampleCount != 0)
+ {
+ return egl::EglBadParameter() << "Multisampling not supported for client buffer texture";
+ }
+ if (samples)
+ {
+ *samples = static_cast<EGLint>(sampleCount);
+ }
+
+ // From table egl.restrictions in EGL_ANGLE_d3d_texture_client_buffer.
+ switch (desc.Format)
+ {
+ case D3DFMT_R8G8B8:
+ case D3DFMT_A8R8G8B8:
+ case D3DFMT_A16B16G16R16F:
+ case D3DFMT_A32B32G32R32F:
+ break;
+
+ default:
+ return egl::EglBadParameter()
+ << "Unknown client buffer texture format: " << desc.Format;
+ }
+
+ const auto &d3dFormatInfo = d3d9::GetD3DFormatInfo(desc.Format);
+ ASSERT(d3dFormatInfo.info().id != angle::FormatID::NONE);
+
+ if (glFormat)
+ {
+ *glFormat = gl::Format(d3dFormatInfo.info().glInternalFormat);
+ }
+
+ if (angleFormat)
+ {
+
+ *angleFormat = &d3dFormatInfo.info();
+ }
+
+ if (arraySlice)
+ {
+ *arraySlice = 0;
+ }
+
+ return egl::NoError();
+}
+
+egl::Error Renderer9::validateShareHandle(const egl::Config *config,
+ HANDLE shareHandle,
+ const egl::AttributeMap &attribs) const
+{
+ if (shareHandle == nullptr)
+ {
+ return egl::EglBadParameter() << "NULL share handle.";
+ }
+
+ EGLint width = attribs.getAsInt(EGL_WIDTH, 0);
+ EGLint height = attribs.getAsInt(EGL_HEIGHT, 0);
+ ASSERT(width != 0 && height != 0);
+
+ const d3d9::TextureFormat &backBufferd3dFormatInfo =
+ d3d9::GetTextureFormatInfo(config->renderTargetFormat);
+
+ IDirect3DTexture9 *texture = nullptr;
+ HRESULT result = mDevice->CreateTexture(width, height, 1, D3DUSAGE_RENDERTARGET,
+ backBufferd3dFormatInfo.texFormat, D3DPOOL_DEFAULT,
+ &texture, &shareHandle);
+ if (FAILED(result))
+ {
+ return egl::EglBadParameter() << "Failed to open share handle, " << gl::FmtHR(result);
+ }
+
+ DWORD levelCount = texture->GetLevelCount();
+
+ D3DSURFACE_DESC desc;
+ texture->GetLevelDesc(0, &desc);
+ SafeRelease(texture);
+
+ if (levelCount != 1 || desc.Width != static_cast<UINT>(width) ||
+ desc.Height != static_cast<UINT>(height) ||
+ desc.Format != backBufferd3dFormatInfo.texFormat)
+ {
+ return egl::EglBadParameter() << "Invalid texture parameters in share handle texture.";
+ }
+
+ return egl::NoError();
+}
+
+ContextImpl *Renderer9::createContext(const gl::State &state, gl::ErrorSet *errorSet)
+{
+ return new Context9(state, errorSet, this);
+}
+
+void *Renderer9::getD3DDevice()
+{
+ return mDevice;
+}
+
+angle::Result Renderer9::allocateEventQuery(const gl::Context *context, IDirect3DQuery9 **outQuery)
+{
+ if (mEventQueryPool.empty())
+ {
+ HRESULT result = mDevice->CreateQuery(D3DQUERYTYPE_EVENT, outQuery);
+ ANGLE_TRY_HR(GetImplAs<Context9>(context), result, "Failed to allocate event query");
+ }
+ else
+ {
+ *outQuery = mEventQueryPool.back();
+ mEventQueryPool.pop_back();
+ }
+
+ return angle::Result::Continue;
+}
+
+void Renderer9::freeEventQuery(IDirect3DQuery9 *query)
+{
+ if (mEventQueryPool.size() > 1000)
+ {
+ SafeRelease(query);
+ }
+ else
+ {
+ mEventQueryPool.push_back(query);
+ }
+}
+
+angle::Result Renderer9::createVertexShader(d3d::Context *context,
+ const DWORD *function,
+ size_t length,
+ IDirect3DVertexShader9 **outShader)
+{
+ return mVertexShaderCache.create(context, function, length, outShader);
+}
+
+angle::Result Renderer9::createPixelShader(d3d::Context *context,
+ const DWORD *function,
+ size_t length,
+ IDirect3DPixelShader9 **outShader)
+{
+ return mPixelShaderCache.create(context, function, length, outShader);
+}
+
+HRESULT Renderer9::createVertexBuffer(UINT Length,
+ DWORD Usage,
+ IDirect3DVertexBuffer9 **ppVertexBuffer)
+{
+ // Force buffers to be limited to a fixed max size.
+ if (Length > kMaximumBufferSizeHardLimit)
+ {
+ return E_OUTOFMEMORY;
+ }
+
+ D3DPOOL Pool = getBufferPool(Usage);
+ return mDevice->CreateVertexBuffer(Length, Usage, 0, Pool, ppVertexBuffer, nullptr);
+}
+
+VertexBuffer *Renderer9::createVertexBuffer()
+{
+ return new VertexBuffer9(this);
+}
+
+HRESULT Renderer9::createIndexBuffer(UINT Length,
+ DWORD Usage,
+ D3DFORMAT Format,
+ IDirect3DIndexBuffer9 **ppIndexBuffer)
+{
+ // Force buffers to be limited to a fixed max size.
+ if (Length > kMaximumBufferSizeHardLimit)
+ {
+ return E_OUTOFMEMORY;
+ }
+
+ D3DPOOL Pool = getBufferPool(Usage);
+ return mDevice->CreateIndexBuffer(Length, Usage, Format, Pool, ppIndexBuffer, nullptr);
+}
+
+IndexBuffer *Renderer9::createIndexBuffer()
+{
+ return new IndexBuffer9(this);
+}
+
+StreamProducerImpl *Renderer9::createStreamProducerD3DTexture(
+ egl::Stream::ConsumerType consumerType,
+ const egl::AttributeMap &attribs)
+{
+ // Streams are not supported under D3D9
+ UNREACHABLE();
+ return nullptr;
+}
+
+bool Renderer9::supportsFastCopyBufferToTexture(GLenum internalFormat) const
+{
+ // Pixel buffer objects are not supported in D3D9, since D3D9 is ES2-only and PBOs are ES3.
+ return false;
+}
+
+angle::Result Renderer9::fastCopyBufferToTexture(const gl::Context *context,
+ const gl::PixelUnpackState &unpack,
+ gl::Buffer *unpackBuffer,
+ unsigned int offset,
+ RenderTargetD3D *destRenderTarget,
+ GLenum destinationFormat,
+ GLenum sourcePixelsType,
+ const gl::Box &destArea)
+{
+ // Pixel buffer objects are not supported in D3D9, since D3D9 is ES2-only and PBOs are ES3.
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context9>(context));
+ return angle::Result::Stop;
+}
+
+angle::Result Renderer9::setSamplerState(const gl::Context *context,
+ gl::ShaderType type,
+ int index,
+ gl::Texture *texture,
+ const gl::SamplerState &samplerState)
+{
+ CurSamplerState &appliedSampler = (type == gl::ShaderType::Fragment)
+ ? mCurPixelSamplerStates[index]
+ : mCurVertexSamplerStates[index];
+
+ // Make sure to add the level offset for our tiny compressed texture workaround
+ TextureD3D *textureD3D = GetImplAs<TextureD3D>(texture);
+
+ TextureStorage *storage = nullptr;
+ ANGLE_TRY(textureD3D->getNativeTexture(context, &storage));
+
+ // Storage should exist, texture should be complete
+ ASSERT(storage);
+
+ DWORD baseLevel = texture->getBaseLevel() + storage->getTopLevel();
+
+ if (appliedSampler.forceSet || appliedSampler.baseLevel != baseLevel ||
+ memcmp(&samplerState, &appliedSampler, sizeof(gl::SamplerState)) != 0)
+ {
+ int d3dSamplerOffset = (type == gl::ShaderType::Fragment) ? 0 : D3DVERTEXTEXTURESAMPLER0;
+ int d3dSampler = index + d3dSamplerOffset;
+
+ mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSU,
+ gl_d3d9::ConvertTextureWrap(samplerState.getWrapS()));
+ mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSV,
+ gl_d3d9::ConvertTextureWrap(samplerState.getWrapT()));
+
+ mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAGFILTER,
+ gl_d3d9::ConvertMagFilter(samplerState.getMagFilter(),
+ samplerState.getMaxAnisotropy()));
+
+ D3DTEXTUREFILTERTYPE d3dMinFilter, d3dMipFilter;
+ float lodBias;
+ gl_d3d9::ConvertMinFilter(samplerState.getMinFilter(), &d3dMinFilter, &d3dMipFilter,
+ &lodBias, samplerState.getMaxAnisotropy(), baseLevel);
+ mDevice->SetSamplerState(d3dSampler, D3DSAMP_MINFILTER, d3dMinFilter);
+ mDevice->SetSamplerState(d3dSampler, D3DSAMP_MIPFILTER, d3dMipFilter);
+ mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXMIPLEVEL, baseLevel);
+ mDevice->SetSamplerState(d3dSampler, D3DSAMP_MIPMAPLODBIAS, static_cast<DWORD>(lodBias));
+ if (getNativeExtensions().textureFilterAnisotropicEXT)
+ {
+ DWORD maxAnisotropy = std::min(mDeviceCaps.MaxAnisotropy,
+ static_cast<DWORD>(samplerState.getMaxAnisotropy()));
+ mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXANISOTROPY, maxAnisotropy);
+ }
+
+ const bool isSrgb = gl::GetSizedInternalFormatInfo(textureD3D->getBaseLevelInternalFormat())
+ .colorEncoding == GL_SRGB;
+ mDevice->SetSamplerState(d3dSampler, D3DSAMP_SRGBTEXTURE, isSrgb);
+
+ ASSERT(texture->getBorderColor().type == angle::ColorGeneric::Type::Float);
+ mDevice->SetSamplerState(d3dSampler, D3DSAMP_BORDERCOLOR,
+ gl_d3d9::ConvertColor(texture->getBorderColor().colorF));
+ }
+
+ appliedSampler.forceSet = false;
+ appliedSampler.samplerState = samplerState;
+ appliedSampler.baseLevel = baseLevel;
+
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer9::setTexture(const gl::Context *context,
+ gl::ShaderType type,
+ int index,
+ gl::Texture *texture)
+{
+ int d3dSamplerOffset = (type == gl::ShaderType::Fragment) ? 0 : D3DVERTEXTEXTURESAMPLER0;
+ int d3dSampler = index + d3dSamplerOffset;
+ IDirect3DBaseTexture9 *d3dTexture = nullptr;
+ bool forceSetTexture = false;
+
+ std::vector<uintptr_t> &appliedTextures =
+ (type == gl::ShaderType::Fragment) ? mCurPixelTextures : mCurVertexTextures;
+
+ if (texture)
+ {
+ TextureD3D *textureImpl = GetImplAs<TextureD3D>(texture);
+
+ TextureStorage *texStorage = nullptr;
+ ANGLE_TRY(textureImpl->getNativeTexture(context, &texStorage));
+
+ // Texture should be complete and have a storage
+ ASSERT(texStorage);
+
+ TextureStorage9 *storage9 = GetAs<TextureStorage9>(texStorage);
+ ANGLE_TRY(storage9->getBaseTexture(context, &d3dTexture));
+
+ // If we get NULL back from getBaseTexture here, something went wrong
+ // in the texture class and we're unexpectedly missing the d3d texture
+ ASSERT(d3dTexture != nullptr);
+
+ forceSetTexture = textureImpl->hasDirtyImages();
+ textureImpl->resetDirty();
+ }
+
+ if (forceSetTexture || appliedTextures[index] != reinterpret_cast<uintptr_t>(d3dTexture))
+ {
+ mDevice->SetTexture(d3dSampler, d3dTexture);
+ }
+
+ appliedTextures[index] = reinterpret_cast<uintptr_t>(d3dTexture);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer9::updateState(const gl::Context *context, gl::PrimitiveMode drawMode)
+{
+ const auto &glState = context->getState();
+
+ // Applies the render target surface, depth stencil surface, viewport rectangle and
+ // scissor rectangle to the renderer
+ gl::Framebuffer *framebuffer = glState.getDrawFramebuffer();
+ ASSERT(framebuffer && !framebuffer->hasAnyDirtyBit());
+
+ Framebuffer9 *framebuffer9 = GetImplAs<Framebuffer9>(framebuffer);
+
+ ANGLE_TRY(applyRenderTarget(context, framebuffer9->getCachedColorRenderTargets()[0],
+ framebuffer9->getCachedDepthStencilRenderTarget()));
+
+ // Setting viewport state
+ setViewport(glState.getViewport(), glState.getNearPlane(), glState.getFarPlane(), drawMode,
+ glState.getRasterizerState().frontFace, false);
+
+ // Setting scissors state
+ setScissorRectangle(glState.getScissor(), glState.isScissorTestEnabled());
+
+ // Setting blend, depth stencil, and rasterizer states
+ // Since framebuffer->getSamples will return the original samples which may be different with
+ // the sample counts that we set in render target view, here we use renderTarget->getSamples to
+ // get the actual samples.
+ GLsizei samples = 0;
+ const gl::FramebufferAttachment *firstColorAttachment = framebuffer->getFirstColorAttachment();
+ if (firstColorAttachment)
+ {
+ ASSERT(firstColorAttachment->isAttached());
+ RenderTarget9 *renderTarget = nullptr;
+ ANGLE_TRY(firstColorAttachment->getRenderTarget(context, firstColorAttachment->getSamples(),
+ &renderTarget));
+ samples = renderTarget->getSamples();
+
+ mDevice->SetRenderState(D3DRS_SRGBWRITEENABLE,
+ renderTarget->getInternalFormat() == GL_SRGB8_ALPHA8);
+ }
+ gl::RasterizerState rasterizer = glState.getRasterizerState();
+ rasterizer.pointDrawMode = (drawMode == gl::PrimitiveMode::Points);
+ rasterizer.multiSample = (samples != 0);
+
+ ANGLE_TRY(setBlendDepthRasterStates(context, drawMode));
+
+ mStateManager.resetDirtyBits();
+
+ return angle::Result::Continue;
+}
+
+void Renderer9::setScissorRectangle(const gl::Rectangle &scissor, bool enabled)
+{
+ mStateManager.setScissorState(scissor, enabled);
+}
+
+angle::Result Renderer9::setBlendDepthRasterStates(const gl::Context *context,
+ gl::PrimitiveMode drawMode)
+{
+ const auto &glState = context->getState();
+ gl::Framebuffer *drawFramebuffer = glState.getDrawFramebuffer();
+ ASSERT(!drawFramebuffer->hasAnyDirtyBit());
+ // Since framebuffer->getSamples will return the original samples which may be different with
+ // the sample counts that we set in render target view, here we use renderTarget->getSamples to
+ // get the actual samples.
+ GLsizei samples = 0;
+ const gl::FramebufferAttachment *firstColorAttachment =
+ drawFramebuffer->getFirstColorAttachment();
+ if (firstColorAttachment)
+ {
+ ASSERT(firstColorAttachment->isAttached());
+ RenderTarget9 *renderTarget = nullptr;
+ ANGLE_TRY(firstColorAttachment->getRenderTarget(context, firstColorAttachment->getSamples(),
+ &renderTarget));
+ samples = renderTarget->getSamples();
+ }
+ gl::RasterizerState rasterizer = glState.getRasterizerState();
+ rasterizer.pointDrawMode = (drawMode == gl::PrimitiveMode::Points);
+ rasterizer.multiSample = (samples != 0);
+
+ unsigned int mask = GetBlendSampleMask(glState, samples);
+ mStateManager.setBlendDepthRasterStates(glState, mask);
+ return angle::Result::Continue;
+}
+
+void Renderer9::setViewport(const gl::Rectangle &viewport,
+ float zNear,
+ float zFar,
+ gl::PrimitiveMode drawMode,
+ GLenum frontFace,
+ bool ignoreViewport)
+{
+ mStateManager.setViewportState(viewport, zNear, zFar, drawMode, frontFace, ignoreViewport);
+}
+
+bool Renderer9::applyPrimitiveType(gl::PrimitiveMode mode, GLsizei count, bool usesPointSize)
+{
+ switch (mode)
+ {
+ case gl::PrimitiveMode::Points:
+ mPrimitiveType = D3DPT_POINTLIST;
+ mPrimitiveCount = count;
+ break;
+ case gl::PrimitiveMode::Lines:
+ mPrimitiveType = D3DPT_LINELIST;
+ mPrimitiveCount = count / 2;
+ break;
+ case gl::PrimitiveMode::LineLoop:
+ mPrimitiveType = D3DPT_LINESTRIP;
+ mPrimitiveCount =
+ count - 1; // D3D doesn't support line loops, so we draw the last line separately
+ break;
+ case gl::PrimitiveMode::LineStrip:
+ mPrimitiveType = D3DPT_LINESTRIP;
+ mPrimitiveCount = count - 1;
+ break;
+ case gl::PrimitiveMode::Triangles:
+ mPrimitiveType = D3DPT_TRIANGLELIST;
+ mPrimitiveCount = count / 3;
+ break;
+ case gl::PrimitiveMode::TriangleStrip:
+ mPrimitiveType = D3DPT_TRIANGLESTRIP;
+ mPrimitiveCount = count - 2;
+ break;
+ case gl::PrimitiveMode::TriangleFan:
+ mPrimitiveType = D3DPT_TRIANGLEFAN;
+ mPrimitiveCount = count - 2;
+ break;
+ default:
+ UNREACHABLE();
+ return false;
+ }
+
+ return mPrimitiveCount > 0;
+}
+
+angle::Result Renderer9::getNullColorRenderTarget(const gl::Context *context,
+ const RenderTarget9 *depthRenderTarget,
+ const RenderTarget9 **outColorRenderTarget)
+{
+ ASSERT(depthRenderTarget);
+
+ const gl::Extents &size = depthRenderTarget->getExtents();
+
+ // search cached nullcolorbuffers
+ for (int i = 0; i < NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++)
+ {
+ if (mNullRenderTargetCache[i].renderTarget != nullptr &&
+ mNullRenderTargetCache[i].width == size.width &&
+ mNullRenderTargetCache[i].height == size.height)
+ {
+ mNullRenderTargetCache[i].lruCount = ++mMaxNullColorbufferLRU;
+ *outColorRenderTarget = mNullRenderTargetCache[i].renderTarget;
+ return angle::Result::Continue;
+ }
+ }
+
+ RenderTargetD3D *nullRenderTarget = nullptr;
+ ANGLE_TRY(createRenderTarget(context, size.width, size.height, GL_NONE, 0, &nullRenderTarget));
+
+ // add nullbuffer to the cache
+ NullRenderTargetCacheEntry *oldest = &mNullRenderTargetCache[0];
+ for (int i = 1; i < NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++)
+ {
+ if (mNullRenderTargetCache[i].lruCount < oldest->lruCount)
+ {
+ oldest = &mNullRenderTargetCache[i];
+ }
+ }
+
+ SafeDelete(oldest->renderTarget);
+ oldest->renderTarget = GetAs<RenderTarget9>(nullRenderTarget);
+ oldest->lruCount = ++mMaxNullColorbufferLRU;
+ oldest->width = size.width;
+ oldest->height = size.height;
+
+ *outColorRenderTarget = oldest->renderTarget;
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer9::applyRenderTarget(const gl::Context *context,
+ const RenderTarget9 *colorRenderTargetIn,
+ const RenderTarget9 *depthStencilRenderTarget)
+{
+ // if there is no color attachment we must synthesize a NULL colorattachment
+ // to keep the D3D runtime happy. This should only be possible if depth texturing.
+ const RenderTarget9 *colorRenderTarget = colorRenderTargetIn;
+ if (colorRenderTarget == nullptr)
+ {
+ ANGLE_TRY(getNullColorRenderTarget(context, depthStencilRenderTarget, &colorRenderTarget));
+ }
+ ASSERT(colorRenderTarget != nullptr);
+
+ size_t renderTargetWidth = 0;
+ size_t renderTargetHeight = 0;
+
+ bool renderTargetChanged = false;
+ unsigned int renderTargetSerial = colorRenderTarget->getSerial();
+ if (renderTargetSerial != mAppliedRenderTargetSerial)
+ {
+ // Apply the render target on the device
+ IDirect3DSurface9 *renderTargetSurface = colorRenderTarget->getSurface();
+ ASSERT(renderTargetSurface);
+
+ mDevice->SetRenderTarget(0, renderTargetSurface);
+ SafeRelease(renderTargetSurface);
+
+ renderTargetWidth = colorRenderTarget->getWidth();
+ renderTargetHeight = colorRenderTarget->getHeight();
+
+ mAppliedRenderTargetSerial = renderTargetSerial;
+ renderTargetChanged = true;
+ }
+
+ unsigned int depthStencilSerial = 0;
+ if (depthStencilRenderTarget != nullptr)
+ {
+ depthStencilSerial = depthStencilRenderTarget->getSerial();
+ }
+
+ if (depthStencilSerial != mAppliedDepthStencilSerial || !mDepthStencilInitialized)
+ {
+ unsigned int depthSize = 0;
+ unsigned int stencilSize = 0;
+
+ // Apply the depth stencil on the device
+ if (depthStencilRenderTarget)
+ {
+ IDirect3DSurface9 *depthStencilSurface = depthStencilRenderTarget->getSurface();
+ ASSERT(depthStencilSurface);
+
+ mDevice->SetDepthStencilSurface(depthStencilSurface);
+ SafeRelease(depthStencilSurface);
+
+ const gl::InternalFormat &format =
+ gl::GetSizedInternalFormatInfo(depthStencilRenderTarget->getInternalFormat());
+
+ depthSize = format.depthBits;
+ stencilSize = format.stencilBits;
+ }
+ else
+ {
+ mDevice->SetDepthStencilSurface(nullptr);
+ }
+
+ mStateManager.updateDepthSizeIfChanged(mDepthStencilInitialized, depthSize);
+ mStateManager.updateStencilSizeIfChanged(mDepthStencilInitialized, stencilSize);
+
+ mAppliedDepthStencilSerial = depthStencilSerial;
+ mDepthStencilInitialized = true;
+ }
+
+ if (renderTargetChanged || !mRenderTargetDescInitialized)
+ {
+ mStateManager.forceSetBlendState();
+ mStateManager.forceSetScissorState();
+ mStateManager.setRenderTargetBounds(renderTargetWidth, renderTargetHeight);
+ mRenderTargetDescInitialized = true;
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer9::applyVertexBuffer(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLint first,
+ GLsizei count,
+ GLsizei instances,
+ TranslatedIndexData * /*indexInfo*/)
+{
+ const gl::State &state = context->getState();
+ ANGLE_TRY(mVertexDataManager->prepareVertexData(context, first, count, &mTranslatedAttribCache,
+ instances));
+
+ return mVertexDeclarationCache.applyDeclaration(context, mDevice, mTranslatedAttribCache,
+ state.getProgram(), first, instances,
+ &mRepeatDraw);
+}
+
+// Applies the indices and element array bindings to the Direct3D 9 device
+angle::Result Renderer9::applyIndexBuffer(const gl::Context *context,
+ const void *indices,
+ GLsizei count,
+ gl::PrimitiveMode mode,
+ gl::DrawElementsType type,
+ TranslatedIndexData *indexInfo)
+{
+ gl::VertexArray *vao = context->getState().getVertexArray();
+ gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer();
+
+ gl::DrawElementsType dstType = gl::DrawElementsType::InvalidEnum;
+ ANGLE_TRY(GetIndexTranslationDestType(context, count, type, indices, false, &dstType));
+
+ ANGLE_TRY(mIndexDataManager->prepareIndexData(context, type, dstType, count, elementArrayBuffer,
+ indices, indexInfo));
+
+ // Directly binding the storage buffer is not supported for d3d9
+ ASSERT(indexInfo->storage == nullptr);
+
+ if (indexInfo->serial != mAppliedIBSerial)
+ {
+ IndexBuffer9 *indexBuffer = GetAs<IndexBuffer9>(indexInfo->indexBuffer);
+
+ mDevice->SetIndices(indexBuffer->getBuffer());
+ mAppliedIBSerial = indexInfo->serial;
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer9::drawArraysImpl(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLint startVertex,
+ GLsizei count,
+ GLsizei instances)
+{
+ ASSERT(!context->getState().isTransformFeedbackActiveUnpaused());
+
+ startScene();
+
+ if (mode == gl::PrimitiveMode::LineLoop)
+ {
+ return drawLineLoop(context, count, gl::DrawElementsType::InvalidEnum, nullptr, 0, nullptr);
+ }
+
+ if (instances > 0)
+ {
+ StaticIndexBufferInterface *countingIB = nullptr;
+ ANGLE_TRY(getCountingIB(context, count, &countingIB));
+
+ if (mAppliedIBSerial != countingIB->getSerial())
+ {
+ IndexBuffer9 *indexBuffer = GetAs<IndexBuffer9>(countingIB->getIndexBuffer());
+
+ mDevice->SetIndices(indexBuffer->getBuffer());
+ mAppliedIBSerial = countingIB->getSerial();
+ }
+
+ for (int i = 0; i < mRepeatDraw; i++)
+ {
+ mDevice->DrawIndexedPrimitive(mPrimitiveType, 0, 0, count, 0, mPrimitiveCount);
+ }
+
+ return angle::Result::Continue;
+ }
+
+ // Regular case
+ mDevice->DrawPrimitive(mPrimitiveType, 0, mPrimitiveCount);
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer9::drawElementsImpl(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices,
+ GLsizei instances)
+{
+ TranslatedIndexData indexInfo;
+
+ ANGLE_TRY(applyIndexBuffer(context, indices, count, mode, type, &indexInfo));
+
+ gl::IndexRange indexRange;
+ ANGLE_TRY(context->getState().getVertexArray()->getIndexRange(context, type, count, indices,
+ &indexRange));
+
+ size_t vertexCount = indexRange.vertexCount();
+ ANGLE_TRY(applyVertexBuffer(context, mode, static_cast<GLsizei>(indexRange.start),
+ static_cast<GLsizei>(vertexCount), instances, &indexInfo));
+
+ startScene();
+
+ int minIndex = static_cast<int>(indexRange.start);
+
+ gl::VertexArray *vao = context->getState().getVertexArray();
+ gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer();
+
+ if (mode == gl::PrimitiveMode::Points)
+ {
+ return drawIndexedPoints(context, count, type, indices, minIndex, elementArrayBuffer);
+ }
+
+ if (mode == gl::PrimitiveMode::LineLoop)
+ {
+ return drawLineLoop(context, count, type, indices, minIndex, elementArrayBuffer);
+ }
+
+ for (int i = 0; i < mRepeatDraw; i++)
+ {
+ mDevice->DrawIndexedPrimitive(mPrimitiveType, -minIndex, minIndex,
+ static_cast<UINT>(vertexCount), indexInfo.startIndex,
+ mPrimitiveCount);
+ }
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer9::drawLineLoop(const gl::Context *context,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices,
+ int minIndex,
+ gl::Buffer *elementArrayBuffer)
+{
+ // Get the raw indices for an indexed draw
+ if (type != gl::DrawElementsType::InvalidEnum && elementArrayBuffer)
+ {
+ BufferD3D *storage = GetImplAs<BufferD3D>(elementArrayBuffer);
+ intptr_t offset = reinterpret_cast<intptr_t>(indices);
+ const uint8_t *bufferData = nullptr;
+ ANGLE_TRY(storage->getData(context, &bufferData));
+ indices = bufferData + offset;
+ }
+
+ unsigned int startIndex = 0;
+ Context9 *context9 = GetImplAs<Context9>(context);
+
+ if (getNativeExtensions().elementIndexUintOES)
+ {
+ if (!mLineLoopIB)
+ {
+ mLineLoopIB = new StreamingIndexBufferInterface(this);
+ ANGLE_TRY(mLineLoopIB->reserveBufferSpace(context, INITIAL_INDEX_BUFFER_SIZE,
+ gl::DrawElementsType::UnsignedInt));
+ }
+
+ // Checked by Renderer9::applyPrimitiveType
+ ASSERT(count >= 0);
+
+ ANGLE_CHECK(context9,
+ static_cast<unsigned int>(count) + 1 <=
+ (std::numeric_limits<unsigned int>::max() / sizeof(unsigned int)),
+ "Failed to create a 32-bit looping index buffer for "
+ "GL_LINE_LOOP, too many indices required.",
+ GL_OUT_OF_MEMORY);
+
+ const unsigned int spaceNeeded =
+ (static_cast<unsigned int>(count) + 1) * sizeof(unsigned int);
+ ANGLE_TRY(mLineLoopIB->reserveBufferSpace(context, spaceNeeded,
+ gl::DrawElementsType::UnsignedInt));
+
+ void *mappedMemory = nullptr;
+ unsigned int offset = 0;
+ ANGLE_TRY(mLineLoopIB->mapBuffer(context, spaceNeeded, &mappedMemory, &offset));
+
+ startIndex = static_cast<unsigned int>(offset) / 4;
+ unsigned int *data = static_cast<unsigned int *>(mappedMemory);
+
+ switch (type)
+ {
+ case gl::DrawElementsType::InvalidEnum: // Non-indexed draw
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = i;
+ }
+ data[count] = 0;
+ break;
+ case gl::DrawElementsType::UnsignedByte:
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = static_cast<const GLubyte *>(indices)[i];
+ }
+ data[count] = static_cast<const GLubyte *>(indices)[0];
+ break;
+ case gl::DrawElementsType::UnsignedShort:
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = static_cast<const GLushort *>(indices)[i];
+ }
+ data[count] = static_cast<const GLushort *>(indices)[0];
+ break;
+ case gl::DrawElementsType::UnsignedInt:
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = static_cast<const GLuint *>(indices)[i];
+ }
+ data[count] = static_cast<const GLuint *>(indices)[0];
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ ANGLE_TRY(mLineLoopIB->unmapBuffer(context));
+ }
+ else
+ {
+ if (!mLineLoopIB)
+ {
+ mLineLoopIB = new StreamingIndexBufferInterface(this);
+ ANGLE_TRY(mLineLoopIB->reserveBufferSpace(context, INITIAL_INDEX_BUFFER_SIZE,
+ gl::DrawElementsType::UnsignedShort));
+ }
+
+ // Checked by Renderer9::applyPrimitiveType
+ ASSERT(count >= 0);
+
+ ANGLE_CHECK(context9,
+ static_cast<unsigned int>(count) + 1 <=
+ (std::numeric_limits<unsigned short>::max() / sizeof(unsigned short)),
+ "Failed to create a 16-bit looping index buffer for "
+ "GL_LINE_LOOP, too many indices required.",
+ GL_OUT_OF_MEMORY);
+
+ const unsigned int spaceNeeded =
+ (static_cast<unsigned int>(count) + 1) * sizeof(unsigned short);
+ ANGLE_TRY(mLineLoopIB->reserveBufferSpace(context, spaceNeeded,
+ gl::DrawElementsType::UnsignedShort));
+
+ void *mappedMemory = nullptr;
+ unsigned int offset;
+ ANGLE_TRY(mLineLoopIB->mapBuffer(context, spaceNeeded, &mappedMemory, &offset));
+
+ startIndex = static_cast<unsigned int>(offset) / 2;
+ unsigned short *data = static_cast<unsigned short *>(mappedMemory);
+
+ switch (type)
+ {
+ case gl::DrawElementsType::InvalidEnum: // Non-indexed draw
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = static_cast<unsigned short>(i);
+ }
+ data[count] = 0;
+ break;
+ case gl::DrawElementsType::UnsignedByte:
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = static_cast<const GLubyte *>(indices)[i];
+ }
+ data[count] = static_cast<const GLubyte *>(indices)[0];
+ break;
+ case gl::DrawElementsType::UnsignedShort:
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = static_cast<const GLushort *>(indices)[i];
+ }
+ data[count] = static_cast<const GLushort *>(indices)[0];
+ break;
+ case gl::DrawElementsType::UnsignedInt:
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = static_cast<unsigned short>(static_cast<const GLuint *>(indices)[i]);
+ }
+ data[count] = static_cast<unsigned short>(static_cast<const GLuint *>(indices)[0]);
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ ANGLE_TRY(mLineLoopIB->unmapBuffer(context));
+ }
+
+ if (mAppliedIBSerial != mLineLoopIB->getSerial())
+ {
+ IndexBuffer9 *indexBuffer = GetAs<IndexBuffer9>(mLineLoopIB->getIndexBuffer());
+
+ mDevice->SetIndices(indexBuffer->getBuffer());
+ mAppliedIBSerial = mLineLoopIB->getSerial();
+ }
+
+ mDevice->DrawIndexedPrimitive(D3DPT_LINESTRIP, -minIndex, minIndex, count, startIndex, count);
+
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer9::drawIndexedPoints(const gl::Context *context,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices,
+ int minIndex,
+ gl::Buffer *elementArrayBuffer)
+{
+ // Drawing index point lists is unsupported in d3d9, fall back to a regular DrawPrimitive call
+ // for each individual point. This call is not expected to happen often.
+
+ if (elementArrayBuffer)
+ {
+ BufferD3D *storage = GetImplAs<BufferD3D>(elementArrayBuffer);
+ intptr_t offset = reinterpret_cast<intptr_t>(indices);
+
+ const uint8_t *bufferData = nullptr;
+ ANGLE_TRY(storage->getData(context, &bufferData));
+ indices = bufferData + offset;
+ }
+
+ switch (type)
+ {
+ case gl::DrawElementsType::UnsignedByte:
+ DrawPoints<GLubyte>(mDevice, count, indices, minIndex);
+ return angle::Result::Continue;
+ case gl::DrawElementsType::UnsignedShort:
+ DrawPoints<GLushort>(mDevice, count, indices, minIndex);
+ return angle::Result::Continue;
+ case gl::DrawElementsType::UnsignedInt:
+ DrawPoints<GLuint>(mDevice, count, indices, minIndex);
+ return angle::Result::Continue;
+ default:
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context9>(context));
+ }
+}
+
+angle::Result Renderer9::getCountingIB(const gl::Context *context,
+ size_t count,
+ StaticIndexBufferInterface **outIB)
+{
+ // Update the counting index buffer if it is not large enough or has not been created yet.
+ if (count <= 65536) // 16-bit indices
+ {
+ const unsigned int spaceNeeded = static_cast<unsigned int>(count) * sizeof(unsigned short);
+
+ if (!mCountingIB || mCountingIB->getBufferSize() < spaceNeeded)
+ {
+ SafeDelete(mCountingIB);
+ mCountingIB = new StaticIndexBufferInterface(this);
+ ANGLE_TRY(mCountingIB->reserveBufferSpace(context, spaceNeeded,
+ gl::DrawElementsType::UnsignedShort));
+
+ void *mappedMemory = nullptr;
+ ANGLE_TRY(mCountingIB->mapBuffer(context, spaceNeeded, &mappedMemory, nullptr));
+
+ unsigned short *data = static_cast<unsigned short *>(mappedMemory);
+ for (size_t i = 0; i < count; i++)
+ {
+ data[i] = static_cast<unsigned short>(i);
+ }
+
+ ANGLE_TRY(mCountingIB->unmapBuffer(context));
+ }
+ }
+ else if (getNativeExtensions().elementIndexUintOES)
+ {
+ const unsigned int spaceNeeded = static_cast<unsigned int>(count) * sizeof(unsigned int);
+
+ if (!mCountingIB || mCountingIB->getBufferSize() < spaceNeeded)
+ {
+ SafeDelete(mCountingIB);
+ mCountingIB = new StaticIndexBufferInterface(this);
+ ANGLE_TRY(mCountingIB->reserveBufferSpace(context, spaceNeeded,
+ gl::DrawElementsType::UnsignedInt));
+
+ void *mappedMemory = nullptr;
+ ANGLE_TRY(mCountingIB->mapBuffer(context, spaceNeeded, &mappedMemory, nullptr));
+
+ unsigned int *data = static_cast<unsigned int *>(mappedMemory);
+ for (unsigned int i = 0; i < count; i++)
+ {
+ data[i] = i;
+ }
+
+ ANGLE_TRY(mCountingIB->unmapBuffer(context));
+ }
+ }
+ else
+ {
+ ANGLE_TRY_HR(GetImplAs<Context9>(context), E_OUTOFMEMORY,
+ "Could not create a counting index buffer for glDrawArraysInstanced.");
+ }
+
+ *outIB = mCountingIB;
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer9::applyShaders(const gl::Context *context, gl::PrimitiveMode drawMode)
+{
+ const gl::State &state = context->getState();
+ d3d::Context *contextD3D = GetImplAs<ContextD3D>(context);
+
+ // This method is called single-threaded.
+ ANGLE_TRY(ensureHLSLCompilerInitialized(contextD3D));
+
+ ProgramD3D *programD3D = GetImplAs<ProgramD3D>(state.getProgram());
+ VertexArray9 *vao = GetImplAs<VertexArray9>(state.getVertexArray());
+ programD3D->updateCachedInputLayout(vao->getCurrentStateSerial(), state);
+
+ ShaderExecutableD3D *vertexExe = nullptr;
+ ANGLE_TRY(programD3D->getVertexExecutableForCachedInputLayout(contextD3D, &vertexExe, nullptr));
+
+ const gl::Framebuffer *drawFramebuffer = state.getDrawFramebuffer();
+ programD3D->updateCachedOutputLayout(context, drawFramebuffer);
+
+ ShaderExecutableD3D *pixelExe = nullptr;
+ ANGLE_TRY(programD3D->getPixelExecutableForCachedOutputLayout(contextD3D, &pixelExe, nullptr));
+
+ IDirect3DVertexShader9 *vertexShader =
+ (vertexExe ? GetAs<ShaderExecutable9>(vertexExe)->getVertexShader() : nullptr);
+ IDirect3DPixelShader9 *pixelShader =
+ (pixelExe ? GetAs<ShaderExecutable9>(pixelExe)->getPixelShader() : nullptr);
+
+ if (vertexShader != mAppliedVertexShader)
+ {
+ mDevice->SetVertexShader(vertexShader);
+ mAppliedVertexShader = vertexShader;
+ }
+
+ if (pixelShader != mAppliedPixelShader)
+ {
+ mDevice->SetPixelShader(pixelShader);
+ mAppliedPixelShader = pixelShader;
+ }
+
+ // D3D9 has a quirk where creating multiple shaders with the same content
+ // can return the same shader pointer. Because GL programs store different data
+ // per-program, checking the program serial guarantees we upload fresh
+ // uniform data even if our shader pointers are the same.
+ // https://code.google.com/p/angleproject/issues/detail?id=661
+ unsigned int programSerial = programD3D->getSerial();
+ if (programSerial != mAppliedProgramSerial)
+ {
+ programD3D->dirtyAllUniforms();
+ mStateManager.forceSetDXUniformsState();
+ mAppliedProgramSerial = programSerial;
+ }
+
+ applyUniforms(programD3D);
+
+ // Driver uniforms
+ mStateManager.setShaderConstants();
+
+ return angle::Result::Continue;
+}
+
+void Renderer9::applyUniforms(ProgramD3D *programD3D)
+{
+ // Skip updates if we're not dirty. Note that D3D9 cannot have compute or geometry.
+ if (!programD3D->anyShaderUniformsDirty())
+ {
+ return;
+ }
+
+ const auto &uniformArray = programD3D->getD3DUniforms();
+
+ for (const D3DUniform *targetUniform : uniformArray)
+ {
+ // Built-in uniforms must be skipped.
+ if (!targetUniform->isReferencedByShader(gl::ShaderType::Vertex) &&
+ !targetUniform->isReferencedByShader(gl::ShaderType::Fragment))
+ continue;
+
+ const GLfloat *f = reinterpret_cast<const GLfloat *>(targetUniform->firstNonNullData());
+ const GLint *i = reinterpret_cast<const GLint *>(targetUniform->firstNonNullData());
+
+ switch (targetUniform->typeInfo.type)
+ {
+ case GL_SAMPLER_2D:
+ case GL_SAMPLER_CUBE:
+ case GL_SAMPLER_EXTERNAL_OES:
+ case GL_SAMPLER_VIDEO_IMAGE_WEBGL:
+ break;
+ case GL_BOOL:
+ case GL_BOOL_VEC2:
+ case GL_BOOL_VEC3:
+ case GL_BOOL_VEC4:
+ applyUniformnbv(targetUniform, i);
+ break;
+ case GL_FLOAT:
+ case GL_FLOAT_VEC2:
+ case GL_FLOAT_VEC3:
+ case GL_FLOAT_VEC4:
+ case GL_FLOAT_MAT2:
+ case GL_FLOAT_MAT3:
+ case GL_FLOAT_MAT4:
+ applyUniformnfv(targetUniform, f);
+ break;
+ case GL_INT:
+ case GL_INT_VEC2:
+ case GL_INT_VEC3:
+ case GL_INT_VEC4:
+ applyUniformniv(targetUniform, i);
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ programD3D->markUniformsClean();
+}
+
+void Renderer9::applyUniformnfv(const D3DUniform *targetUniform, const GLfloat *v)
+{
+ if (targetUniform->isReferencedByShader(gl::ShaderType::Fragment))
+ {
+ mDevice->SetPixelShaderConstantF(
+ targetUniform->mShaderRegisterIndexes[gl::ShaderType::Fragment], v,
+ targetUniform->registerCount);
+ }
+
+ if (targetUniform->isReferencedByShader(gl::ShaderType::Vertex))
+ {
+ mDevice->SetVertexShaderConstantF(
+ targetUniform->mShaderRegisterIndexes[gl::ShaderType::Vertex], v,
+ targetUniform->registerCount);
+ }
+}
+
+void Renderer9::applyUniformniv(const D3DUniform *targetUniform, const GLint *v)
+{
+ ASSERT(targetUniform->registerCount <= MAX_VERTEX_CONSTANT_VECTORS_D3D9);
+ GLfloat vector[MAX_VERTEX_CONSTANT_VECTORS_D3D9][4];
+
+ for (unsigned int i = 0; i < targetUniform->registerCount; i++)
+ {
+ vector[i][0] = (GLfloat)v[4 * i + 0];
+ vector[i][1] = (GLfloat)v[4 * i + 1];
+ vector[i][2] = (GLfloat)v[4 * i + 2];
+ vector[i][3] = (GLfloat)v[4 * i + 3];
+ }
+
+ applyUniformnfv(targetUniform, (GLfloat *)vector);
+}
+
+void Renderer9::applyUniformnbv(const D3DUniform *targetUniform, const GLint *v)
+{
+ ASSERT(targetUniform->registerCount <= MAX_VERTEX_CONSTANT_VECTORS_D3D9);
+ GLfloat vector[MAX_VERTEX_CONSTANT_VECTORS_D3D9][4];
+
+ for (unsigned int i = 0; i < targetUniform->registerCount; i++)
+ {
+ vector[i][0] = (v[4 * i + 0] == GL_FALSE) ? 0.0f : 1.0f;
+ vector[i][1] = (v[4 * i + 1] == GL_FALSE) ? 0.0f : 1.0f;
+ vector[i][2] = (v[4 * i + 2] == GL_FALSE) ? 0.0f : 1.0f;
+ vector[i][3] = (v[4 * i + 3] == GL_FALSE) ? 0.0f : 1.0f;
+ }
+
+ applyUniformnfv(targetUniform, (GLfloat *)vector);
+}
+
+void Renderer9::clear(const ClearParameters &clearParams,
+ const RenderTarget9 *colorRenderTarget,
+ const RenderTarget9 *depthStencilRenderTarget)
+{
+ // Clearing buffers with non-float values is not supported by Renderer9 and ES 2.0
+ ASSERT(clearParams.colorType == GL_FLOAT);
+
+ // Clearing individual buffers other than buffer zero is not supported by Renderer9 and ES 2.0
+ bool clearColor = clearParams.clearColor[0];
+ for (unsigned int i = 0; i < clearParams.clearColor.size(); i++)
+ {
+ ASSERT(clearParams.clearColor[i] == clearColor);
+ }
+
+ float depth = gl::clamp01(clearParams.depthValue);
+ DWORD stencil = clearParams.stencilValue & 0x000000FF;
+
+ unsigned int stencilUnmasked = 0x0;
+ if (clearParams.clearStencil && depthStencilRenderTarget)
+ {
+ const gl::InternalFormat &depthStencilFormat =
+ gl::GetSizedInternalFormatInfo(depthStencilRenderTarget->getInternalFormat());
+ if (depthStencilFormat.stencilBits > 0)
+ {
+ const d3d9::D3DFormat &d3dFormatInfo =
+ d3d9::GetD3DFormatInfo(depthStencilRenderTarget->getD3DFormat());
+ stencilUnmasked = (0x1 << d3dFormatInfo.stencilBits) - 1;
+ }
+ }
+
+ const bool needMaskedStencilClear =
+ clearParams.clearStencil &&
+ (clearParams.stencilWriteMask & stencilUnmasked) != stencilUnmasked;
+
+ bool needMaskedColorClear = false;
+ D3DCOLOR color = D3DCOLOR_ARGB(255, 0, 0, 0);
+ if (clearColor)
+ {
+ ASSERT(colorRenderTarget != nullptr);
+
+ const gl::InternalFormat &formatInfo =
+ gl::GetSizedInternalFormatInfo(colorRenderTarget->getInternalFormat());
+ const d3d9::D3DFormat &d3dFormatInfo =
+ d3d9::GetD3DFormatInfo(colorRenderTarget->getD3DFormat());
+
+ color =
+ D3DCOLOR_ARGB(gl::unorm<8>((formatInfo.alphaBits == 0 && d3dFormatInfo.alphaBits > 0)
+ ? 1.0f
+ : clearParams.colorF.alpha),
+ gl::unorm<8>((formatInfo.redBits == 0 && d3dFormatInfo.redBits > 0)
+ ? 0.0f
+ : clearParams.colorF.red),
+ gl::unorm<8>((formatInfo.greenBits == 0 && d3dFormatInfo.greenBits > 0)
+ ? 0.0f
+ : clearParams.colorF.green),
+ gl::unorm<8>((formatInfo.blueBits == 0 && d3dFormatInfo.blueBits > 0)
+ ? 0.0f
+ : clearParams.colorF.blue));
+
+ const uint8_t colorMask =
+ gl::BlendStateExt::ColorMaskStorage::GetValueIndexed(0, clearParams.colorMask);
+ bool r, g, b, a;
+ gl::BlendStateExt::UnpackColorMask(colorMask, &r, &g, &b, &a);
+ if ((formatInfo.redBits > 0 && !r) || (formatInfo.greenBits > 0 && !g) ||
+ (formatInfo.blueBits > 0 && !b) || (formatInfo.alphaBits > 0 && !a))
+ {
+ needMaskedColorClear = true;
+ }
+ }
+
+ if (needMaskedColorClear || needMaskedStencilClear)
+ {
+ // State which is altered in all paths from this point to the clear call is saved.
+ // State which is altered in only some paths will be flagged dirty in the case that
+ // that path is taken.
+ HRESULT hr;
+ if (mMaskedClearSavedState == nullptr)
+ {
+ hr = mDevice->BeginStateBlock();
+ ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY);
+
+ mDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
+ mDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
+ mDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
+ mDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
+ mDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
+ mDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
+ mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+ mDevice->SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
+ mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0);
+ mDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE);
+ mDevice->SetPixelShader(nullptr);
+ mDevice->SetVertexShader(nullptr);
+ mDevice->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
+ mDevice->SetStreamSource(0, nullptr, 0, 0);
+ mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
+ mDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
+ mDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
+ mDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
+ mDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR);
+ mDevice->SetRenderState(D3DRS_TEXTUREFACTOR, color);
+ mDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
+
+ for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
+ {
+ mDevice->SetStreamSourceFreq(i, 1);
+ }
+
+ hr = mDevice->EndStateBlock(&mMaskedClearSavedState);
+ ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY);
+ }
+
+ ASSERT(mMaskedClearSavedState != nullptr);
+
+ if (mMaskedClearSavedState != nullptr)
+ {
+ hr = mMaskedClearSavedState->Capture();
+ ASSERT(SUCCEEDED(hr));
+ }
+
+ mDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
+ mDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
+ mDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
+ mDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
+ mDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
+ mDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
+ mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+ mDevice->SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
+
+ if (clearColor)
+ {
+ // clearParams.colorMask follows the same packing scheme as
+ // D3DCOLORWRITEENABLE_RED/GREEN/BLUE/ALPHA
+ mDevice->SetRenderState(
+ D3DRS_COLORWRITEENABLE,
+ gl::BlendStateExt::ColorMaskStorage::GetValueIndexed(0, clearParams.colorMask));
+ }
+ else
+ {
+ mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0);
+ }
+
+ if (stencilUnmasked != 0x0 && clearParams.clearStencil)
+ {
+ mDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE);
+ mDevice->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, FALSE);
+ mDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
+ mDevice->SetRenderState(D3DRS_STENCILREF, stencil);
+ mDevice->SetRenderState(D3DRS_STENCILWRITEMASK, clearParams.stencilWriteMask);
+ mDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_REPLACE);
+ mDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_REPLACE);
+ mDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
+ }
+ else
+ {
+ mDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE);
+ }
+
+ mDevice->SetPixelShader(nullptr);
+ mDevice->SetVertexShader(nullptr);
+ mDevice->SetFVF(D3DFVF_XYZRHW);
+ mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
+ mDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
+ mDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
+ mDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
+ mDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR);
+ mDevice->SetRenderState(D3DRS_TEXTUREFACTOR, color);
+ mDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
+
+ for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
+ {
+ mDevice->SetStreamSourceFreq(i, 1);
+ }
+
+ int renderTargetWidth = mStateManager.getRenderTargetWidth();
+ int renderTargetHeight = mStateManager.getRenderTargetHeight();
+
+ float quad[4][4]; // A quadrilateral covering the target, aligned to match the edges
+ quad[0][0] = -0.5f;
+ quad[0][1] = renderTargetHeight - 0.5f;
+ quad[0][2] = 0.0f;
+ quad[0][3] = 1.0f;
+
+ quad[1][0] = renderTargetWidth - 0.5f;
+ quad[1][1] = renderTargetHeight - 0.5f;
+ quad[1][2] = 0.0f;
+ quad[1][3] = 1.0f;
+
+ quad[2][0] = -0.5f;
+ quad[2][1] = -0.5f;
+ quad[2][2] = 0.0f;
+ quad[2][3] = 1.0f;
+
+ quad[3][0] = renderTargetWidth - 0.5f;
+ quad[3][1] = -0.5f;
+ quad[3][2] = 0.0f;
+ quad[3][3] = 1.0f;
+
+ startScene();
+ mDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float[4]));
+
+ if (clearParams.clearDepth)
+ {
+ mDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
+ mDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
+ mDevice->Clear(0, nullptr, D3DCLEAR_ZBUFFER, color, depth, stencil);
+ }
+
+ if (mMaskedClearSavedState != nullptr)
+ {
+ mMaskedClearSavedState->Apply();
+ }
+ }
+ else if (clearColor || clearParams.clearDepth || clearParams.clearStencil)
+ {
+ DWORD dxClearFlags = 0;
+ if (clearColor)
+ {
+ dxClearFlags |= D3DCLEAR_TARGET;
+ }
+ if (clearParams.clearDepth)
+ {
+ dxClearFlags |= D3DCLEAR_ZBUFFER;
+ }
+ if (clearParams.clearStencil)
+ {
+ dxClearFlags |= D3DCLEAR_STENCIL;
+ }
+
+ mDevice->Clear(0, nullptr, dxClearFlags, color, depth, stencil);
+ }
+}
+
+void Renderer9::markAllStateDirty()
+{
+ mAppliedRenderTargetSerial = 0;
+ mAppliedDepthStencilSerial = 0;
+ mDepthStencilInitialized = false;
+ mRenderTargetDescInitialized = false;
+
+ mStateManager.forceSetRasterState();
+ mStateManager.forceSetDepthStencilState();
+ mStateManager.forceSetBlendState();
+ mStateManager.forceSetScissorState();
+ mStateManager.forceSetViewportState();
+
+ ASSERT(mCurVertexSamplerStates.size() == mCurVertexTextures.size());
+ for (unsigned int i = 0; i < mCurVertexTextures.size(); i++)
+ {
+ mCurVertexSamplerStates[i].forceSet = true;
+ mCurVertexTextures[i] = angle::DirtyPointer;
+ }
+
+ ASSERT(mCurPixelSamplerStates.size() == mCurPixelTextures.size());
+ for (unsigned int i = 0; i < mCurPixelSamplerStates.size(); i++)
+ {
+ mCurPixelSamplerStates[i].forceSet = true;
+ mCurPixelTextures[i] = angle::DirtyPointer;
+ }
+
+ mAppliedIBSerial = 0;
+ mAppliedVertexShader = nullptr;
+ mAppliedPixelShader = nullptr;
+ mAppliedProgramSerial = 0;
+ mStateManager.forceSetDXUniformsState();
+
+ mVertexDeclarationCache.markStateDirty();
+}
+
+void Renderer9::releaseDeviceResources()
+{
+ for (size_t i = 0; i < mEventQueryPool.size(); i++)
+ {
+ SafeRelease(mEventQueryPool[i]);
+ }
+ mEventQueryPool.clear();
+
+ SafeRelease(mMaskedClearSavedState);
+
+ mVertexShaderCache.clear();
+ mPixelShaderCache.clear();
+
+ SafeDelete(mBlit);
+ SafeDelete(mVertexDataManager);
+ SafeDelete(mIndexDataManager);
+ SafeDelete(mLineLoopIB);
+ SafeDelete(mCountingIB);
+
+ for (int i = 0; i < NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++)
+ {
+ SafeDelete(mNullRenderTargetCache[i].renderTarget);
+ }
+}
+
+// set notify to true to broadcast a message to all contexts of the device loss
+bool Renderer9::testDeviceLost()
+{
+ HRESULT status = getDeviceStatusCode();
+ return FAILED(status);
+}
+
+HRESULT Renderer9::getDeviceStatusCode()
+{
+ HRESULT status = D3D_OK;
+
+ if (mDeviceEx)
+ {
+ status = mDeviceEx->CheckDeviceState(nullptr);
+ }
+ else if (mDevice)
+ {
+ status = mDevice->TestCooperativeLevel();
+ }
+
+ return status;
+}
+
+bool Renderer9::testDeviceResettable()
+{
+ // On D3D9Ex, DEVICELOST represents a hung device that needs to be restarted
+ // DEVICEREMOVED indicates the device has been stopped and must be recreated
+ switch (getDeviceStatusCode())
+ {
+ case D3DERR_DEVICENOTRESET:
+ case D3DERR_DEVICEHUNG:
+ return true;
+ case D3DERR_DEVICELOST:
+ return (mDeviceEx != nullptr);
+ case D3DERR_DEVICEREMOVED:
+ ASSERT(mDeviceEx != nullptr);
+ return isRemovedDeviceResettable();
+ default:
+ return false;
+ }
+}
+
+bool Renderer9::resetDevice()
+{
+ releaseDeviceResources();
+
+ D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters();
+
+ HRESULT result = D3D_OK;
+ bool lost = testDeviceLost();
+ bool removedDevice = (getDeviceStatusCode() == D3DERR_DEVICEREMOVED);
+
+ // Device Removed is a feature which is only present with D3D9Ex
+ ASSERT(mDeviceEx != nullptr || !removedDevice);
+
+ for (int attempts = 3; lost && attempts > 0; attempts--)
+ {
+ if (removedDevice)
+ {
+ // Device removed, which may trigger on driver reinstallation,
+ // may cause a longer wait other reset attempts before the
+ // system is ready to handle creating a new device.
+ Sleep(800);
+ lost = !resetRemovedDevice();
+ }
+ else if (mDeviceEx)
+ {
+ Sleep(500); // Give the graphics driver some CPU time
+ result = mDeviceEx->ResetEx(&presentParameters, nullptr);
+ lost = testDeviceLost();
+ }
+ else
+ {
+ result = mDevice->TestCooperativeLevel();
+ while (result == D3DERR_DEVICELOST)
+ {
+ Sleep(100); // Give the graphics driver some CPU time
+ result = mDevice->TestCooperativeLevel();
+ }
+
+ if (result == D3DERR_DEVICENOTRESET)
+ {
+ result = mDevice->Reset(&presentParameters);
+ }
+ lost = testDeviceLost();
+ }
+ }
+
+ if (FAILED(result))
+ {
+ ERR() << "Reset/ResetEx failed multiple times, " << gl::FmtHR(result);
+ return false;
+ }
+
+ if (removedDevice && lost)
+ {
+ ERR() << "Device lost reset failed multiple times";
+ return false;
+ }
+
+ // If the device was removed, we already finished re-initialization in resetRemovedDevice
+ if (!removedDevice)
+ {
+ // reset device defaults
+ if (initializeDevice().isError())
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool Renderer9::isRemovedDeviceResettable() const
+{
+ bool success = false;
+
+#if ANGLE_D3D9EX == ANGLE_ENABLED
+ IDirect3D9Ex *d3d9Ex = nullptr;
+ typedef HRESULT(WINAPI * Direct3DCreate9ExFunc)(UINT, IDirect3D9Ex **);
+ Direct3DCreate9ExFunc Direct3DCreate9ExPtr =
+ reinterpret_cast<Direct3DCreate9ExFunc>(GetProcAddress(mD3d9Module, "Direct3DCreate9Ex"));
+
+ if (Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &d3d9Ex)))
+ {
+ D3DCAPS9 deviceCaps;
+ HRESULT result = d3d9Ex->GetDeviceCaps(mAdapter, mDeviceType, &deviceCaps);
+ success = SUCCEEDED(result);
+ }
+
+ SafeRelease(d3d9Ex);
+#else
+ UNREACHABLE();
+#endif
+
+ return success;
+}
+
+bool Renderer9::resetRemovedDevice()
+{
+ // From http://msdn.microsoft.com/en-us/library/windows/desktop/bb172554(v=vs.85).aspx:
+ // The hardware adapter has been removed. Application must destroy the device, do enumeration of
+ // adapters and create another Direct3D device. If application continues rendering without
+ // calling Reset, the rendering calls will succeed. Applies to Direct3D 9Ex only.
+ release();
+ return !initialize().isError();
+}
+
+VendorID Renderer9::getVendorId() const
+{
+ return static_cast<VendorID>(mAdapterIdentifier.VendorId);
+}
+
+std::string Renderer9::getRendererDescription() const
+{
+ std::ostringstream rendererString;
+
+ rendererString << mAdapterIdentifier.Description;
+ if (getShareHandleSupport())
+ {
+ rendererString << " Direct3D9Ex";
+ }
+ else
+ {
+ rendererString << " Direct3D9";
+ }
+
+ rendererString << " vs_" << D3DSHADER_VERSION_MAJOR(mDeviceCaps.VertexShaderVersion) << "_"
+ << D3DSHADER_VERSION_MINOR(mDeviceCaps.VertexShaderVersion);
+ rendererString << " ps_" << D3DSHADER_VERSION_MAJOR(mDeviceCaps.PixelShaderVersion) << "_"
+ << D3DSHADER_VERSION_MINOR(mDeviceCaps.PixelShaderVersion);
+
+ return rendererString.str();
+}
+
+DeviceIdentifier Renderer9::getAdapterIdentifier() const
+{
+ DeviceIdentifier deviceIdentifier = {};
+ deviceIdentifier.VendorId = static_cast<UINT>(mAdapterIdentifier.VendorId);
+ deviceIdentifier.DeviceId = static_cast<UINT>(mAdapterIdentifier.DeviceId);
+ deviceIdentifier.SubSysId = static_cast<UINT>(mAdapterIdentifier.SubSysId);
+ deviceIdentifier.Revision = static_cast<UINT>(mAdapterIdentifier.Revision);
+ deviceIdentifier.FeatureLevel = 0;
+
+ return deviceIdentifier;
+}
+
+unsigned int Renderer9::getReservedVertexUniformVectors() const
+{
+ return d3d9_gl::GetReservedVertexUniformVectors();
+}
+
+unsigned int Renderer9::getReservedFragmentUniformVectors() const
+{
+ return d3d9_gl::GetReservedFragmentUniformVectors();
+}
+
+bool Renderer9::getShareHandleSupport() const
+{
+ // PIX doesn't seem to support using share handles, so disable them.
+ return (mD3d9Ex != nullptr) && !gl::DebugAnnotationsActive(/*context=*/nullptr);
+}
+
+int Renderer9::getMajorShaderModel() const
+{
+ return D3DSHADER_VERSION_MAJOR(mDeviceCaps.PixelShaderVersion);
+}
+
+int Renderer9::getMinorShaderModel() const
+{
+ return D3DSHADER_VERSION_MINOR(mDeviceCaps.PixelShaderVersion);
+}
+
+std::string Renderer9::getShaderModelSuffix() const
+{
+ return "";
+}
+
+DWORD Renderer9::getCapsDeclTypes() const
+{
+ return mDeviceCaps.DeclTypes;
+}
+
+D3DPOOL Renderer9::getBufferPool(DWORD usage) const
+{
+ if (mD3d9Ex != nullptr)
+ {
+ return D3DPOOL_DEFAULT;
+ }
+ else
+ {
+ if (!(usage & D3DUSAGE_DYNAMIC))
+ {
+ return D3DPOOL_MANAGED;
+ }
+ }
+
+ return D3DPOOL_DEFAULT;
+}
+
+angle::Result Renderer9::copyImage2D(const gl::Context *context,
+ const gl::Framebuffer *framebuffer,
+ const gl::Rectangle &sourceRect,
+ GLenum destFormat,
+ const gl::Offset &destOffset,
+ TextureStorage *storage,
+ GLint level)
+{
+ RECT rect;
+ rect.left = sourceRect.x;
+ rect.top = sourceRect.y;
+ rect.right = sourceRect.x + sourceRect.width;
+ rect.bottom = sourceRect.y + sourceRect.height;
+
+ return mBlit->copy2D(context, framebuffer, rect, destFormat, destOffset, storage, level);
+}
+
+angle::Result Renderer9::copyImageCube(const gl::Context *context,
+ const gl::Framebuffer *framebuffer,
+ const gl::Rectangle &sourceRect,
+ GLenum destFormat,
+ const gl::Offset &destOffset,
+ TextureStorage *storage,
+ gl::TextureTarget target,
+ GLint level)
+{
+ RECT rect;
+ rect.left = sourceRect.x;
+ rect.top = sourceRect.y;
+ rect.right = sourceRect.x + sourceRect.width;
+ rect.bottom = sourceRect.y + sourceRect.height;
+
+ return mBlit->copyCube(context, framebuffer, rect, destFormat, destOffset, storage, target,
+ level);
+}
+
+angle::Result Renderer9::copyImage3D(const gl::Context *context,
+ const gl::Framebuffer *framebuffer,
+ const gl::Rectangle &sourceRect,
+ GLenum destFormat,
+ const gl::Offset &destOffset,
+ TextureStorage *storage,
+ GLint level)
+{
+ // 3D textures are not available in the D3D9 backend.
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context9>(context));
+ return angle::Result::Stop;
+}
+
+angle::Result Renderer9::copyImage2DArray(const gl::Context *context,
+ const gl::Framebuffer *framebuffer,
+ const gl::Rectangle &sourceRect,
+ GLenum destFormat,
+ const gl::Offset &destOffset,
+ TextureStorage *storage,
+ GLint level)
+{
+ // 2D array textures are not available in the D3D9 backend.
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context9>(context));
+ return angle::Result::Stop;
+}
+
+angle::Result Renderer9::copyTexture(const gl::Context *context,
+ const gl::Texture *source,
+ GLint sourceLevel,
+ gl::TextureTarget srcTarget,
+ const gl::Box &sourceBox,
+ GLenum destFormat,
+ GLenum destType,
+ const gl::Offset &destOffset,
+ TextureStorage *storage,
+ gl::TextureTarget destTarget,
+ GLint destLevel,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha)
+{
+ RECT rect;
+ rect.left = sourceBox.x;
+ rect.top = sourceBox.y;
+ rect.right = sourceBox.x + sourceBox.width;
+ rect.bottom = sourceBox.y + sourceBox.height;
+
+ return mBlit->copyTexture(context, source, sourceLevel, rect, destFormat, destOffset, storage,
+ destTarget, destLevel, unpackFlipY, unpackPremultiplyAlpha,
+ unpackUnmultiplyAlpha);
+}
+
+angle::Result Renderer9::copyCompressedTexture(const gl::Context *context,
+ const gl::Texture *source,
+ GLint sourceLevel,
+ TextureStorage *storage,
+ GLint destLevel)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context9>(context));
+ return angle::Result::Stop;
+}
+
+angle::Result Renderer9::createRenderTarget(const gl::Context *context,
+ int width,
+ int height,
+ GLenum format,
+ GLsizei samples,
+ RenderTargetD3D **outRT)
+{
+ const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(format);
+
+ const gl::TextureCaps &textureCaps = getNativeTextureCaps().get(format);
+ GLuint supportedSamples = textureCaps.getNearestSamples(samples);
+
+ IDirect3DTexture9 *texture = nullptr;
+ IDirect3DSurface9 *renderTarget = nullptr;
+ if (width > 0 && height > 0)
+ {
+ bool requiresInitialization = false;
+ HRESULT result = D3DERR_INVALIDCALL;
+
+ const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(format);
+ if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0)
+ {
+ result = mDevice->CreateDepthStencilSurface(
+ width, height, d3d9FormatInfo.renderFormat,
+ gl_d3d9::GetMultisampleType(supportedSamples), 0, FALSE, &renderTarget, nullptr);
+ }
+ else
+ {
+ requiresInitialization = (d3d9FormatInfo.dataInitializerFunction != nullptr);
+ if (supportedSamples > 0)
+ {
+ result = mDevice->CreateRenderTarget(width, height, d3d9FormatInfo.renderFormat,
+ gl_d3d9::GetMultisampleType(supportedSamples),
+ 0, FALSE, &renderTarget, nullptr);
+ }
+ else
+ {
+ result = mDevice->CreateTexture(
+ width, height, 1, D3DUSAGE_RENDERTARGET, d3d9FormatInfo.texFormat,
+ getTexturePool(D3DUSAGE_RENDERTARGET), &texture, nullptr);
+ if (!FAILED(result))
+ {
+ result = texture->GetSurfaceLevel(0, &renderTarget);
+ }
+ }
+ }
+
+ ANGLE_TRY_HR(GetImplAs<Context9>(context), result, "Failed to create render target");
+
+ if (requiresInitialization)
+ {
+ // This format requires that the data be initialized before the render target can be
+ // used Unfortunately this requires a Get call on the d3d device but it is far better
+ // than having to mark the render target as lockable and copy data to the gpu.
+ IDirect3DSurface9 *prevRenderTarget = nullptr;
+ mDevice->GetRenderTarget(0, &prevRenderTarget);
+ mDevice->SetRenderTarget(0, renderTarget);
+ mDevice->Clear(0, nullptr, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 0, 255), 0.0f, 0);
+ mDevice->SetRenderTarget(0, prevRenderTarget);
+ }
+ }
+
+ *outRT = new TextureRenderTarget9(texture, 0, renderTarget, format, width, height, 1,
+ supportedSamples);
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer9::createRenderTargetCopy(const gl::Context *context,
+ RenderTargetD3D *source,
+ RenderTargetD3D **outRT)
+{
+ ASSERT(source != nullptr);
+
+ RenderTargetD3D *newRT = nullptr;
+ ANGLE_TRY(createRenderTarget(context, source->getWidth(), source->getHeight(),
+ source->getInternalFormat(), source->getSamples(), &newRT));
+
+ RenderTarget9 *source9 = GetAs<RenderTarget9>(source);
+ RenderTarget9 *dest9 = GetAs<RenderTarget9>(newRT);
+
+ HRESULT result = mDevice->StretchRect(source9->getSurface(), nullptr, dest9->getSurface(),
+ nullptr, D3DTEXF_NONE);
+ ANGLE_TRY_HR(GetImplAs<Context9>(context), result, "Failed to copy render target");
+
+ *outRT = newRT;
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer9::loadExecutable(d3d::Context *context,
+ const uint8_t *function,
+ size_t length,
+ gl::ShaderType type,
+ const std::vector<D3DVarying> &streamOutVaryings,
+ bool separatedOutputBuffers,
+ ShaderExecutableD3D **outExecutable)
+{
+ // Transform feedback is not supported in ES2 or D3D9
+ ASSERT(streamOutVaryings.empty());
+
+ switch (type)
+ {
+ case gl::ShaderType::Vertex:
+ {
+ IDirect3DVertexShader9 *vshader = nullptr;
+ ANGLE_TRY(createVertexShader(context, (DWORD *)function, length, &vshader));
+ *outExecutable = new ShaderExecutable9(function, length, vshader);
+ }
+ break;
+ case gl::ShaderType::Fragment:
+ {
+ IDirect3DPixelShader9 *pshader = nullptr;
+ ANGLE_TRY(createPixelShader(context, (DWORD *)function, length, &pshader));
+ *outExecutable = new ShaderExecutable9(function, length, pshader);
+ }
+ break;
+ default:
+ ANGLE_HR_UNREACHABLE(context);
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer9::compileToExecutable(d3d::Context *context,
+ gl::InfoLog &infoLog,
+ const std::string &shaderHLSL,
+ gl::ShaderType type,
+ const std::vector<D3DVarying> &streamOutVaryings,
+ bool separatedOutputBuffers,
+ const CompilerWorkaroundsD3D &workarounds,
+ ShaderExecutableD3D **outExectuable)
+{
+ // Transform feedback is not supported in ES2 or D3D9
+ ASSERT(streamOutVaryings.empty());
+
+ std::stringstream profileStream;
+
+ switch (type)
+ {
+ case gl::ShaderType::Vertex:
+ profileStream << "vs";
+ break;
+ case gl::ShaderType::Fragment:
+ profileStream << "ps";
+ break;
+ default:
+ ANGLE_HR_UNREACHABLE(context);
+ }
+
+ profileStream << "_" << ((getMajorShaderModel() >= 3) ? 3 : 2);
+ profileStream << "_"
+ << "0";
+
+ std::string profile = profileStream.str();
+
+ UINT flags = ANGLE_COMPILE_OPTIMIZATION_LEVEL;
+
+ if (workarounds.skipOptimization)
+ {
+ flags = D3DCOMPILE_SKIP_OPTIMIZATION;
+ }
+ else if (workarounds.useMaxOptimization)
+ {
+ flags = D3DCOMPILE_OPTIMIZATION_LEVEL3;
+ }
+
+ if (gl::DebugAnnotationsActive(/*context=*/nullptr))
+ {
+#ifndef NDEBUG
+ flags = D3DCOMPILE_SKIP_OPTIMIZATION;
+#endif
+
+ flags |= D3DCOMPILE_DEBUG;
+ }
+
+ // Sometimes D3DCompile will fail with the default compilation flags for complicated shaders
+ // when it would otherwise pass with alternative options. Try the default flags first and if
+ // compilation fails, try some alternatives.
+ std::vector<CompileConfig> configs;
+ configs.push_back(CompileConfig(flags, "default"));
+ configs.push_back(CompileConfig(flags | D3DCOMPILE_AVOID_FLOW_CONTROL, "avoid flow control"));
+ configs.push_back(CompileConfig(flags | D3DCOMPILE_PREFER_FLOW_CONTROL, "prefer flow control"));
+
+ ID3DBlob *binary = nullptr;
+ std::string debugInfo;
+ angle::Result error = mCompiler.compileToBinary(context, infoLog, shaderHLSL, profile, configs,
+ nullptr, &binary, &debugInfo);
+ ANGLE_TRY(error);
+
+ // It's possible that binary is NULL if the compiler failed in all configurations. Set the
+ // executable to NULL and return GL_NO_ERROR to signify that there was a link error but the
+ // internal state is still OK.
+ if (!binary)
+ {
+ *outExectuable = nullptr;
+ return angle::Result::Continue;
+ }
+
+ error = loadExecutable(context, reinterpret_cast<const uint8_t *>(binary->GetBufferPointer()),
+ binary->GetBufferSize(), type, streamOutVaryings, separatedOutputBuffers,
+ outExectuable);
+
+ SafeRelease(binary);
+ ANGLE_TRY(error);
+
+ if (!debugInfo.empty())
+ {
+ (*outExectuable)->appendDebugInfo(debugInfo);
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer9::ensureHLSLCompilerInitialized(d3d::Context *context)
+{
+ return mCompiler.ensureInitialized(context);
+}
+
+UniformStorageD3D *Renderer9::createUniformStorage(size_t storageSize)
+{
+ return new UniformStorageD3D(storageSize);
+}
+
+angle::Result Renderer9::boxFilter(Context9 *context9,
+ IDirect3DSurface9 *source,
+ IDirect3DSurface9 *dest)
+{
+ return mBlit->boxFilter(context9, source, dest);
+}
+
+D3DPOOL Renderer9::getTexturePool(DWORD usage) const
+{
+ if (mD3d9Ex != nullptr)
+ {
+ return D3DPOOL_DEFAULT;
+ }
+ else
+ {
+ if (!(usage & (D3DUSAGE_DEPTHSTENCIL | D3DUSAGE_RENDERTARGET)))
+ {
+ return D3DPOOL_MANAGED;
+ }
+ }
+
+ return D3DPOOL_DEFAULT;
+}
+
+angle::Result Renderer9::copyToRenderTarget(const gl::Context *context,
+ IDirect3DSurface9 *dest,
+ IDirect3DSurface9 *source,
+ bool fromManaged)
+{
+ ASSERT(source && dest);
+
+ Context9 *context9 = GetImplAs<Context9>(context);
+
+ HRESULT result = D3DERR_OUTOFVIDEOMEMORY;
+
+ if (fromManaged)
+ {
+ D3DSURFACE_DESC desc;
+ source->GetDesc(&desc);
+
+ IDirect3DSurface9 *surf = 0;
+ result = mDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format,
+ D3DPOOL_SYSTEMMEM, &surf, nullptr);
+
+ if (SUCCEEDED(result))
+ {
+ ANGLE_TRY(Image9::CopyLockableSurfaces(context9, surf, source));
+ result = mDevice->UpdateSurface(surf, nullptr, dest, nullptr);
+ SafeRelease(surf);
+ }
+ }
+ else
+ {
+ endScene();
+ result = mDevice->StretchRect(source, nullptr, dest, nullptr, D3DTEXF_NONE);
+ }
+
+ ANGLE_TRY_HR(context9, result, "Failed to blit internal texture");
+ return angle::Result::Continue;
+}
+
+RendererClass Renderer9::getRendererClass() const
+{
+ return RENDERER_D3D9;
+}
+
+ImageD3D *Renderer9::createImage()
+{
+ return new Image9(this);
+}
+
+ExternalImageSiblingImpl *Renderer9::createExternalImageSibling(const gl::Context *context,
+ EGLenum target,
+ EGLClientBuffer buffer,
+ const egl::AttributeMap &attribs)
+{
+ UNREACHABLE();
+ return nullptr;
+}
+
+angle::Result Renderer9::generateMipmap(const gl::Context *context, ImageD3D *dest, ImageD3D *src)
+{
+ Image9 *src9 = GetAs<Image9>(src);
+ Image9 *dst9 = GetAs<Image9>(dest);
+ return Image9::GenerateMipmap(GetImplAs<Context9>(context), dst9, src9);
+}
+
+angle::Result Renderer9::generateMipmapUsingD3D(const gl::Context *context,
+ TextureStorage *storage,
+ const gl::TextureState &textureState)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context9>(context));
+ return angle::Result::Stop;
+}
+
+angle::Result Renderer9::copyImage(const gl::Context *context,
+ ImageD3D *dest,
+ ImageD3D *source,
+ const gl::Box &sourceBox,
+ const gl::Offset &destOffset,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha)
+{
+ Image9 *dest9 = GetAs<Image9>(dest);
+ Image9 *src9 = GetAs<Image9>(source);
+ return Image9::CopyImage(context, dest9, src9, sourceBox.toRect(), destOffset, unpackFlipY,
+ unpackPremultiplyAlpha, unpackUnmultiplyAlpha);
+}
+
+TextureStorage *Renderer9::createTextureStorage2D(SwapChainD3D *swapChain, const std::string &label)
+{
+ SwapChain9 *swapChain9 = GetAs<SwapChain9>(swapChain);
+ return new TextureStorage9_2D(this, swapChain9, label);
+}
+
+TextureStorage *Renderer9::createTextureStorageEGLImage(EGLImageD3D *eglImage,
+ RenderTargetD3D *renderTargetD3D,
+ const std::string &label)
+{
+ return new TextureStorage9_EGLImage(this, eglImage, GetAs<RenderTarget9>(renderTargetD3D),
+ label);
+}
+
+TextureStorage *Renderer9::createTextureStorageBuffer(
+ const gl::OffsetBindingPointer<gl::Buffer> &buffer,
+ GLenum internalFormat,
+ const std::string &label)
+{
+ UNREACHABLE();
+ return nullptr;
+}
+
+TextureStorage *Renderer9::createTextureStorageExternal(
+ egl::Stream *stream,
+ const egl::Stream::GLTextureDescription &desc,
+ const std::string &label)
+{
+ UNIMPLEMENTED();
+ return nullptr;
+}
+
+TextureStorage *Renderer9::createTextureStorage2D(GLenum internalformat,
+ BindFlags bindFlags,
+ GLsizei width,
+ GLsizei height,
+ int levels,
+ const std::string &label,
+ bool hintLevelZeroOnly)
+{
+ return new TextureStorage9_2D(this, internalformat, bindFlags.renderTarget, width, height,
+ levels, label);
+}
+
+TextureStorage *Renderer9::createTextureStorageCube(GLenum internalformat,
+ BindFlags bindFlags,
+ int size,
+ int levels,
+ bool hintLevelZeroOnly,
+ const std::string &label)
+{
+ return new TextureStorage9_Cube(this, internalformat, bindFlags.renderTarget, size, levels,
+ hintLevelZeroOnly, label);
+}
+
+TextureStorage *Renderer9::createTextureStorage3D(GLenum internalformat,
+ BindFlags bindFlags,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ int levels,
+ const std::string &label)
+{
+ // 3D textures are not supported by the D3D9 backend.
+ UNREACHABLE();
+
+ return nullptr;
+}
+
+TextureStorage *Renderer9::createTextureStorage2DArray(GLenum internalformat,
+ BindFlags bindFlags,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ int levels,
+ const std::string &label)
+{
+ // 2D array textures are not supported by the D3D9 backend.
+ UNREACHABLE();
+
+ return nullptr;
+}
+
+TextureStorage *Renderer9::createTextureStorage2DMultisample(GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ int levels,
+ int samples,
+ bool fixedSampleLocations,
+ const std::string &label)
+{
+ // 2D multisampled textures are not supported by the D3D9 backend.
+ UNREACHABLE();
+
+ return nullptr;
+}
+
+TextureStorage *Renderer9::createTextureStorage2DMultisampleArray(GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ int levels,
+ int samples,
+ bool fixedSampleLocations,
+ const std::string &label)
+{
+ // 2D multisampled textures are not supported by the D3D9 backend.
+ UNREACHABLE();
+
+ return nullptr;
+}
+
+bool Renderer9::getLUID(LUID *adapterLuid) const
+{
+ adapterLuid->HighPart = 0;
+ adapterLuid->LowPart = 0;
+
+ if (mD3d9Ex)
+ {
+ mD3d9Ex->GetAdapterLUID(mAdapter, adapterLuid);
+ return true;
+ }
+
+ return false;
+}
+
+VertexConversionType Renderer9::getVertexConversionType(angle::FormatID vertexFormatID) const
+{
+ return d3d9::GetVertexFormatInfo(getCapsDeclTypes(), vertexFormatID).conversionType;
+}
+
+GLenum Renderer9::getVertexComponentType(angle::FormatID vertexFormatID) const
+{
+ return d3d9::GetVertexFormatInfo(getCapsDeclTypes(), vertexFormatID).componentType;
+}
+
+angle::Result Renderer9::getVertexSpaceRequired(const gl::Context *context,
+ const gl::VertexAttribute &attrib,
+ const gl::VertexBinding &binding,
+ size_t count,
+ GLsizei instances,
+ GLuint baseInstance,
+ unsigned int *bytesRequiredOut) const
+{
+ if (!attrib.enabled)
+ {
+ *bytesRequiredOut = 16u;
+ return angle::Result::Continue;
+ }
+
+ angle::FormatID vertexFormatID = gl::GetVertexFormatID(attrib, gl::VertexAttribType::Float);
+ const d3d9::VertexFormat &d3d9VertexInfo =
+ d3d9::GetVertexFormatInfo(getCapsDeclTypes(), vertexFormatID);
+
+ unsigned int elementCount = 0;
+ const unsigned int divisor = binding.getDivisor();
+ if (instances == 0 || divisor == 0)
+ {
+ elementCount = static_cast<unsigned int>(count);
+ }
+ else
+ {
+ // Round up to divisor, if possible
+ elementCount = UnsignedCeilDivide(static_cast<unsigned int>(instances), divisor);
+ }
+
+ bool check = (d3d9VertexInfo.outputElementSize >
+ std::numeric_limits<unsigned int>::max() / elementCount);
+ ANGLE_CHECK(GetImplAs<Context9>(context), !check,
+ "New vertex buffer size would result in an overflow.", GL_OUT_OF_MEMORY);
+
+ *bytesRequiredOut = static_cast<unsigned int>(d3d9VertexInfo.outputElementSize) * elementCount;
+ return angle::Result::Continue;
+}
+
+void Renderer9::generateCaps(gl::Caps *outCaps,
+ gl::TextureCapsMap *outTextureCaps,
+ gl::Extensions *outExtensions,
+ gl::Limitations *outLimitations) const
+{
+ d3d9_gl::GenerateCaps(mD3d9, mDevice, mDeviceType, mAdapter, outCaps, outTextureCaps,
+ outExtensions, outLimitations);
+}
+
+void Renderer9::initializeFeatures(angle::FeaturesD3D *features) const
+{
+ if (!mDisplay->getState().featuresAllDisabled)
+ {
+ d3d9::InitializeFeatures(features);
+ }
+ ApplyFeatureOverrides(features, mDisplay->getState());
+}
+
+void Renderer9::initializeFrontendFeatures(angle::FrontendFeatures *features) const {}
+
+DeviceImpl *Renderer9::createEGLDevice()
+{
+ return new DeviceD3D(EGL_D3D9_DEVICE_ANGLE, mDevice);
+}
+
+Renderer9::CurSamplerState::CurSamplerState()
+ : forceSet(true), baseLevel(std::numeric_limits<size_t>::max()), samplerState()
+{}
+
+angle::Result Renderer9::genericDrawElements(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices,
+ GLsizei instances)
+{
+ const gl::State &state = context->getState();
+ gl::Program *program = context->getState().getProgram();
+ ASSERT(program != nullptr);
+ ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
+ bool usesPointSize = programD3D->usesPointSize();
+
+ programD3D->updateSamplerMapping();
+
+ if (!applyPrimitiveType(mode, count, usesPointSize))
+ {
+ return angle::Result::Continue;
+ }
+
+ ANGLE_TRY(updateState(context, mode));
+ ANGLE_TRY(applyTextures(context));
+ ANGLE_TRY(applyShaders(context, mode));
+
+ if (!skipDraw(state, mode))
+ {
+ ANGLE_TRY(drawElementsImpl(context, mode, count, type, indices, instances));
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer9::genericDrawArrays(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLint first,
+ GLsizei count,
+ GLsizei instances)
+{
+ gl::Program *program = context->getState().getProgram();
+ ASSERT(program != nullptr);
+ ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
+ bool usesPointSize = programD3D->usesPointSize();
+
+ programD3D->updateSamplerMapping();
+
+ if (!applyPrimitiveType(mode, count, usesPointSize))
+ {
+ return angle::Result::Continue;
+ }
+
+ ANGLE_TRY(updateState(context, mode));
+ ANGLE_TRY(applyVertexBuffer(context, mode, first, count, instances, nullptr));
+ ANGLE_TRY(applyTextures(context));
+ ANGLE_TRY(applyShaders(context, mode));
+
+ if (!skipDraw(context->getState(), mode))
+ {
+ ANGLE_TRY(drawArraysImpl(context, mode, first, count, instances));
+ }
+
+ return angle::Result::Continue;
+}
+
+FramebufferImpl *Renderer9::createDefaultFramebuffer(const gl::FramebufferState &state)
+{
+ return new Framebuffer9(state, this);
+}
+
+gl::Version Renderer9::getMaxSupportedESVersion() const
+{
+ return gl::Version(2, 0);
+}
+
+gl::Version Renderer9::getMaxConformantESVersion() const
+{
+ return gl::Version(2, 0);
+}
+
+angle::Result Renderer9::clearRenderTarget(const gl::Context *context,
+ RenderTargetD3D *renderTarget,
+ const gl::ColorF &clearColorValue,
+ const float clearDepthValue,
+ const unsigned int clearStencilValue)
+{
+ D3DCOLOR color =
+ D3DCOLOR_ARGB(gl::unorm<8>(clearColorValue.alpha), gl::unorm<8>(clearColorValue.red),
+ gl::unorm<8>(clearColorValue.green), gl::unorm<8>(clearColorValue.blue));
+ float depth = clearDepthValue;
+ DWORD stencil = clearStencilValue & 0x000000FF;
+
+ unsigned int renderTargetSerial = renderTarget->getSerial();
+ RenderTarget9 *renderTarget9 = GetAs<RenderTarget9>(renderTarget);
+ IDirect3DSurface9 *renderTargetSurface = renderTarget9->getSurface();
+ ASSERT(renderTargetSurface);
+
+ DWORD dxClearFlags = 0;
+
+ const gl::InternalFormat &internalFormatInfo =
+ gl::GetSizedInternalFormatInfo(renderTarget->getInternalFormat());
+ if (internalFormatInfo.depthBits > 0 || internalFormatInfo.stencilBits > 0)
+ {
+ dxClearFlags = D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL;
+ if (mAppliedDepthStencilSerial != renderTargetSerial)
+ {
+ mDevice->SetDepthStencilSurface(renderTargetSurface);
+ }
+ }
+ else
+ {
+ dxClearFlags = D3DCLEAR_TARGET;
+ if (mAppliedRenderTargetSerial != renderTargetSerial)
+ {
+ mDevice->SetRenderTarget(0, renderTargetSurface);
+ }
+ }
+ SafeRelease(renderTargetSurface);
+
+ D3DVIEWPORT9 viewport;
+ viewport.X = 0;
+ viewport.Y = 0;
+ viewport.Width = renderTarget->getWidth();
+ viewport.Height = renderTarget->getHeight();
+ mDevice->SetViewport(&viewport);
+
+ mDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
+
+ mDevice->Clear(0, nullptr, dxClearFlags, color, depth, stencil);
+
+ markAllStateDirty();
+
+ return angle::Result::Continue;
+}
+
+bool Renderer9::canSelectViewInVertexShader() const
+{
+ return false;
+}
+
+// For each Direct3D sampler of either the pixel or vertex stage,
+// looks up the corresponding OpenGL texture image unit and texture type,
+// and sets the texture and its addressing/filtering state (or NULL when inactive).
+// Sampler mapping needs to be up-to-date on the program object before this is called.
+angle::Result Renderer9::applyTextures(const gl::Context *context, gl::ShaderType shaderType)
+{
+ const auto &glState = context->getState();
+ const auto &caps = context->getCaps();
+ ProgramD3D *programD3D = GetImplAs<ProgramD3D>(glState.getProgram());
+
+ ASSERT(!programD3D->isSamplerMappingDirty());
+
+ // TODO(jmadill): Use the Program's sampler bindings.
+ const gl::ActiveTexturesCache &activeTextures = glState.getActiveTexturesCache();
+
+ const gl::RangeUI samplerRange = programD3D->getUsedSamplerRange(shaderType);
+ for (unsigned int samplerIndex = samplerRange.low(); samplerIndex < samplerRange.high();
+ samplerIndex++)
+ {
+ GLint textureUnit = programD3D->getSamplerMapping(shaderType, samplerIndex, caps);
+ ASSERT(textureUnit != -1);
+ gl::Texture *texture = activeTextures[textureUnit];
+
+ // A nullptr texture indicates incomplete.
+ if (texture)
+ {
+ gl::Sampler *samplerObject = glState.getSampler(textureUnit);
+
+ const gl::SamplerState &samplerState =
+ samplerObject ? samplerObject->getSamplerState() : texture->getSamplerState();
+
+ ANGLE_TRY(setSamplerState(context, shaderType, samplerIndex, texture, samplerState));
+ ANGLE_TRY(setTexture(context, shaderType, samplerIndex, texture));
+ }
+ else
+ {
+ gl::TextureType textureType =
+ programD3D->getSamplerTextureType(shaderType, samplerIndex);
+
+ // Texture is not sampler complete or it is in use by the framebuffer. Bind the
+ // incomplete texture.
+ gl::Texture *incompleteTexture = nullptr;
+ ANGLE_TRY(getIncompleteTexture(context, textureType, &incompleteTexture));
+ ANGLE_TRY(setSamplerState(context, shaderType, samplerIndex, incompleteTexture,
+ incompleteTexture->getSamplerState()));
+ ANGLE_TRY(setTexture(context, shaderType, samplerIndex, incompleteTexture));
+ }
+ }
+
+ // Set all the remaining textures to NULL
+ int samplerCount = (shaderType == gl::ShaderType::Fragment)
+ ? caps.maxShaderTextureImageUnits[gl::ShaderType::Fragment]
+ : caps.maxShaderTextureImageUnits[gl::ShaderType::Vertex];
+
+ // TODO(jmadill): faster way?
+ for (int samplerIndex = samplerRange.high(); samplerIndex < samplerCount; samplerIndex++)
+ {
+ ANGLE_TRY(setTexture(context, shaderType, samplerIndex, nullptr));
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer9::applyTextures(const gl::Context *context)
+{
+ ANGLE_TRY(applyTextures(context, gl::ShaderType::Vertex));
+ ANGLE_TRY(applyTextures(context, gl::ShaderType::Fragment));
+ return angle::Result::Continue;
+}
+
+angle::Result Renderer9::getIncompleteTexture(const gl::Context *context,
+ gl::TextureType type,
+ gl::Texture **textureOut)
+{
+ return GetImplAs<Context9>(context)->getIncompleteTexture(context, type, textureOut);
+}
+
+angle::Result Renderer9::ensureVertexDataManagerInitialized(const gl::Context *context)
+{
+ if (!mVertexDataManager)
+ {
+ mVertexDataManager = new VertexDataManager(this);
+ ANGLE_TRY(mVertexDataManager->initialize(context));
+ }
+
+ return angle::Result::Continue;
+}
+
+std::string Renderer9::getVendorString() const
+{
+ return GetVendorString(getVendorId());
+}
+
+std::string Renderer9::getVersionString(bool includeFullVersion) const
+{
+ std::ostringstream versionString;
+ std::string driverName(mAdapterIdentifier.Driver);
+ if (!driverName.empty())
+ {
+ versionString << mAdapterIdentifier.Driver;
+ }
+ else
+ {
+ versionString << "D3D9";
+ }
+
+ if (includeFullVersion)
+ {
+ versionString << " -";
+ versionString << GetDriverVersionString(mAdapterIdentifier.DriverVersion);
+ }
+
+ return versionString.str();
+}
+
+RendererD3D *CreateRenderer9(egl::Display *display)
+{
+ return new Renderer9(display);
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Renderer9.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Renderer9.h
new file mode 100644
index 0000000000..67a20f56ba
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/Renderer9.h
@@ -0,0 +1,586 @@
+//
+// Copyright 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.
+//
+
+// Renderer9.h: Defines a back-end specific class for the D3D9 renderer.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D9_RENDERER9_H_
+#define LIBANGLE_RENDERER_D3D_D3D9_RENDERER9_H_
+
+#include "common/angleutils.h"
+#include "common/mathutil.h"
+#include "libANGLE/renderer/d3d/HLSLCompiler.h"
+#include "libANGLE/renderer/d3d/RenderTargetD3D.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
+#include "libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h"
+#include "libANGLE/renderer/d3d/d3d9/ShaderCache.h"
+#include "libANGLE/renderer/d3d/d3d9/StateManager9.h"
+#include "libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h"
+#include "libANGLE/renderer/driver_utils.h"
+
+namespace gl
+{
+class FramebufferAttachment;
+}
+
+namespace egl
+{
+class AttributeMap;
+}
+
+namespace rx
+{
+class Blit9;
+class Context9;
+class IndexDataManager;
+class ProgramD3D;
+class RenderTarget9;
+class StreamingIndexBufferInterface;
+class StaticIndexBufferInterface;
+class VertexDataManager;
+struct ClearParameters;
+struct D3DUniform;
+struct TranslatedAttribute;
+
+class Renderer9 : public RendererD3D
+{
+ public:
+ explicit Renderer9(egl::Display *display);
+ ~Renderer9() override;
+
+ egl::Error initialize() override;
+ bool resetDevice() override;
+
+ egl::ConfigSet generateConfigs() override;
+ void generateDisplayExtensions(egl::DisplayExtensions *outExtensions) const override;
+
+ void startScene();
+ void endScene();
+
+ angle::Result flush(const gl::Context *context);
+ angle::Result finish(const gl::Context *context);
+
+ bool isValidNativeWindow(EGLNativeWindowType window) const override;
+ NativeWindowD3D *createNativeWindow(EGLNativeWindowType window,
+ const egl::Config *config,
+ const egl::AttributeMap &attribs) const override;
+
+ SwapChainD3D *createSwapChain(NativeWindowD3D *nativeWindow,
+ HANDLE shareHandle,
+ IUnknown *d3dTexture,
+ GLenum backBufferFormat,
+ GLenum depthBufferFormat,
+ EGLint orientation,
+ EGLint samples) override;
+ egl::Error getD3DTextureInfo(const egl::Config *configuration,
+ IUnknown *d3dTexture,
+ const egl::AttributeMap &attribs,
+ EGLint *width,
+ EGLint *height,
+ GLsizei *samples,
+ gl::Format *glFormat,
+ const angle::Format **angleFormat,
+ UINT *arraySlice) const override;
+ egl::Error validateShareHandle(const egl::Config *config,
+ HANDLE shareHandle,
+ const egl::AttributeMap &attribs) const override;
+
+ ContextImpl *createContext(const gl::State &state, gl::ErrorSet *errorSet) override;
+
+ angle::Result allocateEventQuery(const gl::Context *context, IDirect3DQuery9 **outQuery);
+ void freeEventQuery(IDirect3DQuery9 *query);
+
+ // resource creation
+ angle::Result createVertexShader(d3d::Context *context,
+ const DWORD *function,
+ size_t length,
+ IDirect3DVertexShader9 **outShader);
+ angle::Result createPixelShader(d3d::Context *context,
+ 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);
+ angle::Result setSamplerState(const gl::Context *context,
+ gl::ShaderType type,
+ int index,
+ gl::Texture *texture,
+ const gl::SamplerState &sampler);
+ angle::Result setTexture(const gl::Context *context,
+ gl::ShaderType type,
+ int index,
+ gl::Texture *texture);
+
+ angle::Result updateState(const gl::Context *context, gl::PrimitiveMode drawMode);
+
+ void setScissorRectangle(const gl::Rectangle &scissor, bool enabled);
+ void setViewport(const gl::Rectangle &viewport,
+ float zNear,
+ float zFar,
+ gl::PrimitiveMode drawMode,
+ GLenum frontFace,
+ bool ignoreViewport);
+
+ angle::Result applyRenderTarget(const gl::Context *context,
+ const RenderTarget9 *colorRenderTarget,
+ const RenderTarget9 *depthStencilRenderTarget);
+ void applyUniforms(ProgramD3D *programD3D);
+ bool applyPrimitiveType(gl::PrimitiveMode primitiveType,
+ GLsizei elementCount,
+ bool usesPointSize);
+ angle::Result applyVertexBuffer(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLint first,
+ GLsizei count,
+ GLsizei instances,
+ TranslatedIndexData *indexInfo);
+ angle::Result applyIndexBuffer(const gl::Context *context,
+ const void *indices,
+ GLsizei count,
+ gl::PrimitiveMode mode,
+ gl::DrawElementsType type,
+ TranslatedIndexData *indexInfo);
+
+ void clear(const ClearParameters &clearParams,
+ const RenderTarget9 *colorRenderTarget,
+ const RenderTarget9 *depthStencilRenderTarget);
+
+ void markAllStateDirty();
+
+ // lost device
+ bool testDeviceLost() override;
+ bool testDeviceResettable() override;
+
+ VendorID getVendorId() const;
+ DeviceIdentifier getAdapterIdentifier() const override;
+
+ IDirect3DDevice9 *getDevice() { return mDevice; }
+ void *getD3DDevice() override;
+
+ unsigned int getReservedVertexUniformVectors() const;
+ unsigned int getReservedFragmentUniformVectors() const;
+
+ bool getShareHandleSupport() const;
+
+ int getMajorShaderModel() const override;
+ int getMinorShaderModel() const override;
+ std::string getShaderModelSuffix() const override;
+
+ DWORD getCapsDeclTypes() const;
+
+ // Pixel operations
+ angle::Result copyImage2D(const gl::Context *context,
+ const gl::Framebuffer *framebuffer,
+ const gl::Rectangle &sourceRect,
+ GLenum destFormat,
+ const gl::Offset &destOffset,
+ TextureStorage *storage,
+ GLint level) override;
+ angle::Result copyImageCube(const gl::Context *context,
+ const gl::Framebuffer *framebuffer,
+ const gl::Rectangle &sourceRect,
+ GLenum destFormat,
+ const gl::Offset &destOffset,
+ TextureStorage *storage,
+ gl::TextureTarget target,
+ GLint level) override;
+ angle::Result copyImage3D(const gl::Context *context,
+ const gl::Framebuffer *framebuffer,
+ const gl::Rectangle &sourceRect,
+ GLenum destFormat,
+ const gl::Offset &destOffset,
+ TextureStorage *storage,
+ GLint level) override;
+ angle::Result copyImage2DArray(const gl::Context *context,
+ const gl::Framebuffer *framebuffer,
+ const gl::Rectangle &sourceRect,
+ GLenum destFormat,
+ const gl::Offset &destOffset,
+ TextureStorage *storage,
+ GLint level) override;
+
+ angle::Result copyTexture(const gl::Context *context,
+ const gl::Texture *source,
+ GLint sourceLevel,
+ gl::TextureTarget srcTarget,
+ const gl::Box &sourceBox,
+ GLenum destFormat,
+ GLenum destType,
+ const gl::Offset &destOffset,
+ TextureStorage *storage,
+ gl::TextureTarget destTarget,
+ GLint destLevel,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha) override;
+ angle::Result copyCompressedTexture(const gl::Context *context,
+ const gl::Texture *source,
+ GLint sourceLevel,
+ TextureStorage *storage,
+ GLint destLevel) override;
+
+ // RenderTarget creation
+ angle::Result createRenderTarget(const gl::Context *context,
+ int width,
+ int height,
+ GLenum format,
+ GLsizei samples,
+ RenderTargetD3D **outRT) override;
+ angle::Result createRenderTargetCopy(const gl::Context *context,
+ RenderTargetD3D *source,
+ RenderTargetD3D **outRT) override;
+
+ // Shader operations
+ angle::Result loadExecutable(d3d::Context *context,
+ const uint8_t *function,
+ size_t length,
+ gl::ShaderType type,
+ const std::vector<D3DVarying> &streamOutVaryings,
+ bool separatedOutputBuffers,
+ ShaderExecutableD3D **outExecutable) override;
+ angle::Result compileToExecutable(d3d::Context *context,
+ gl::InfoLog &infoLog,
+ const std::string &shaderHLSL,
+ gl::ShaderType type,
+ const std::vector<D3DVarying> &streamOutVaryings,
+ bool separatedOutputBuffers,
+ const CompilerWorkaroundsD3D &workarounds,
+ ShaderExecutableD3D **outExectuable) override;
+ angle::Result ensureHLSLCompilerInitialized(d3d::Context *context) override;
+
+ UniformStorageD3D *createUniformStorage(size_t storageSize) override;
+
+ // Image operations
+ ImageD3D *createImage() override;
+ ExternalImageSiblingImpl *createExternalImageSibling(const gl::Context *context,
+ EGLenum target,
+ EGLClientBuffer buffer,
+ const egl::AttributeMap &attribs) override;
+ angle::Result generateMipmap(const gl::Context *context,
+ ImageD3D *dest,
+ ImageD3D *source) override;
+ angle::Result generateMipmapUsingD3D(const gl::Context *context,
+ TextureStorage *storage,
+ const gl::TextureState &textureState) override;
+ angle::Result copyImage(const gl::Context *context,
+ ImageD3D *dest,
+ ImageD3D *source,
+ const gl::Box &sourceBox,
+ const gl::Offset &destOffset,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha) override;
+ TextureStorage *createTextureStorage2D(SwapChainD3D *swapChain,
+ const std::string &label) override;
+ TextureStorage *createTextureStorageEGLImage(EGLImageD3D *eglImage,
+ RenderTargetD3D *renderTargetD3D,
+ const std::string &label) override;
+
+ TextureStorage *createTextureStorageBuffer(const gl::OffsetBindingPointer<gl::Buffer> &buffer,
+ GLenum internalFormat,
+ const std::string &label) override;
+
+ TextureStorage *createTextureStorageExternal(egl::Stream *stream,
+ const egl::Stream::GLTextureDescription &desc,
+ const std::string &label) override;
+
+ TextureStorage *createTextureStorage2D(GLenum internalformat,
+ BindFlags bindFlags,
+ GLsizei width,
+ GLsizei height,
+ int levels,
+ const std::string &label,
+ bool hintLevelZeroOnly) override;
+ TextureStorage *createTextureStorageCube(GLenum internalformat,
+ BindFlags bindFlags,
+ int size,
+ int levels,
+ bool hintLevelZeroOnly,
+ const std::string &label) override;
+ TextureStorage *createTextureStorage3D(GLenum internalformat,
+ BindFlags bindFlags,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ int levels,
+ const std::string &label) override;
+ TextureStorage *createTextureStorage2DArray(GLenum internalformat,
+ BindFlags bindFlags,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ int levels,
+ const std::string &label) override;
+
+ TextureStorage *createTextureStorage2DMultisample(GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ int levels,
+ int samples,
+ bool fixedSampleLocations,
+ const std::string &label) override;
+ TextureStorage *createTextureStorage2DMultisampleArray(GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ int levels,
+ int samples,
+ bool fixedSampleLocations,
+ const std::string &label) override;
+
+ // Buffer creation
+ VertexBuffer *createVertexBuffer() override;
+ IndexBuffer *createIndexBuffer() override;
+
+ // Stream Creation
+ StreamProducerImpl *createStreamProducerD3DTexture(egl::Stream::ConsumerType consumerType,
+ const egl::AttributeMap &attribs) override;
+
+ // Buffer-to-texture and Texture-to-buffer copies
+ bool supportsFastCopyBufferToTexture(GLenum internalFormat) const override;
+ angle::Result fastCopyBufferToTexture(const gl::Context *context,
+ const gl::PixelUnpackState &unpack,
+ gl::Buffer *unpackBuffer,
+ unsigned int offset,
+ RenderTargetD3D *destRenderTarget,
+ GLenum destinationFormat,
+ GLenum sourcePixelsType,
+ const gl::Box &destArea) override;
+
+ // D3D9-renderer specific methods
+ angle::Result boxFilter(Context9 *context9, IDirect3DSurface9 *source, IDirect3DSurface9 *dest);
+
+ D3DPOOL getTexturePool(DWORD usage) const;
+
+ bool getLUID(LUID *adapterLuid) const override;
+ VertexConversionType getVertexConversionType(angle::FormatID vertexFormatID) const override;
+ GLenum getVertexComponentType(angle::FormatID vertexFormatID) const override;
+
+ // Warning: you should ensure binding really matches attrib.bindingIndex before using this
+ // function.
+ angle::Result getVertexSpaceRequired(const gl::Context *context,
+ const gl::VertexAttribute &attrib,
+ const gl::VertexBinding &binding,
+ size_t count,
+ GLsizei instances,
+ GLuint baseInstance,
+ unsigned int *bytesRequiredOut) const override;
+
+ angle::Result copyToRenderTarget(const gl::Context *context,
+ IDirect3DSurface9 *dest,
+ IDirect3DSurface9 *source,
+ bool fromManaged);
+
+ RendererClass getRendererClass() const override;
+
+ D3DDEVTYPE getD3D9DeviceType() const { return mDeviceType; }
+
+ DeviceImpl *createEGLDevice() override;
+
+ StateManager9 *getStateManager() { return &mStateManager; }
+
+ angle::Result genericDrawArrays(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLint first,
+ GLsizei count,
+ GLsizei instances);
+
+ angle::Result genericDrawElements(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices,
+ GLsizei instances);
+
+ // Necessary hack for default framebuffers in D3D.
+ FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) override;
+
+ DebugAnnotator9 *getAnnotator() { return &mAnnotator; }
+
+ gl::Version getMaxSupportedESVersion() const override;
+ gl::Version getMaxConformantESVersion() const override;
+
+ angle::Result clearRenderTarget(const gl::Context *context,
+ RenderTargetD3D *renderTarget,
+ const gl::ColorF &clearColorValue,
+ const float clearDepthValue,
+ const unsigned int clearStencilValue) override;
+
+ bool canSelectViewInVertexShader() const override;
+
+ angle::Result getIncompleteTexture(const gl::Context *context,
+ gl::TextureType type,
+ gl::Texture **textureOut) override;
+
+ angle::Result ensureVertexDataManagerInitialized(const gl::Context *context);
+
+ void setGlobalDebugAnnotator() override;
+
+ std::string getRendererDescription() const override;
+ std::string getVendorString() const override;
+ std::string getVersionString(bool includeFullVersion) const override;
+
+ private:
+ angle::Result drawArraysImpl(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLint startVertex,
+ GLsizei count,
+ GLsizei instances);
+ angle::Result drawElementsImpl(const gl::Context *context,
+ gl::PrimitiveMode mode,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices,
+ GLsizei instances);
+
+ angle::Result applyShaders(const gl::Context *context, gl::PrimitiveMode drawMode);
+
+ angle::Result applyTextures(const gl::Context *context);
+ angle::Result applyTextures(const gl::Context *context, gl::ShaderType shaderType);
+
+ void generateCaps(gl::Caps *outCaps,
+ gl::TextureCapsMap *outTextureCaps,
+ gl::Extensions *outExtensions,
+ gl::Limitations *outLimitations) const override;
+
+ void initializeFeatures(angle::FeaturesD3D *features) const override;
+
+ void initializeFrontendFeatures(angle::FrontendFeatures *features) const override;
+
+ angle::Result setBlendDepthRasterStates(const gl::Context *context, gl::PrimitiveMode drawMode);
+
+ void release();
+
+ void applyUniformnfv(const D3DUniform *targetUniform, const GLfloat *v);
+ void applyUniformniv(const D3DUniform *targetUniform, const GLint *v);
+ void applyUniformnbv(const D3DUniform *targetUniform, const GLint *v);
+
+ angle::Result drawLineLoop(const gl::Context *context,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices,
+ int minIndex,
+ gl::Buffer *elementArrayBuffer);
+ angle::Result drawIndexedPoints(const gl::Context *context,
+ GLsizei count,
+ gl::DrawElementsType type,
+ const void *indices,
+ int minIndex,
+ gl::Buffer *elementArrayBuffer);
+
+ angle::Result getCountingIB(const gl::Context *context,
+ size_t count,
+ StaticIndexBufferInterface **outIB);
+
+ angle::Result getNullColorRenderTarget(const gl::Context *context,
+ const RenderTarget9 *depthRenderTarget,
+ const RenderTarget9 **outColorRenderTarget);
+
+ D3DPOOL getBufferPool(DWORD usage) const;
+
+ HMODULE mD3d9Module;
+
+ egl::Error initializeDevice();
+ D3DPRESENT_PARAMETERS getDefaultPresentParameters();
+ void releaseDeviceResources();
+
+ HRESULT getDeviceStatusCode();
+ bool isRemovedDeviceResettable() const;
+ bool resetRemovedDevice();
+
+ UINT mAdapter;
+ D3DDEVTYPE mDeviceType;
+ IDirect3D9 *mD3d9; // Always valid after successful initialization.
+ IDirect3D9Ex *mD3d9Ex; // Might be null if D3D9Ex is not supported.
+ IDirect3DDevice9 *mDevice;
+ IDirect3DDevice9Ex *mDeviceEx; // Might be null if D3D9Ex is not supported.
+
+ HLSLCompiler mCompiler;
+
+ Blit9 *mBlit;
+
+ HWND mDeviceWindow;
+
+ D3DCAPS9 mDeviceCaps;
+ D3DADAPTER_IDENTIFIER9 mAdapterIdentifier;
+
+ D3DPRIMITIVETYPE mPrimitiveType;
+ int mPrimitiveCount;
+ GLsizei mRepeatDraw;
+
+ bool mSceneStarted;
+
+ bool mVertexTextureSupport;
+
+ // current render target states
+ unsigned int mAppliedRenderTargetSerial;
+ unsigned int mAppliedDepthStencilSerial;
+ bool mDepthStencilInitialized;
+ bool mRenderTargetDescInitialized;
+
+ IDirect3DStateBlock9 *mMaskedClearSavedState;
+
+ StateManager9 mStateManager;
+
+ // Currently applied sampler states
+ struct CurSamplerState
+ {
+ CurSamplerState();
+
+ bool forceSet;
+ size_t baseLevel;
+ gl::SamplerState samplerState;
+ };
+ std::vector<CurSamplerState> mCurVertexSamplerStates;
+ std::vector<CurSamplerState> mCurPixelSamplerStates;
+
+ // Currently applied textures
+ std::vector<uintptr_t> mCurVertexTextures;
+ std::vector<uintptr_t> mCurPixelTextures;
+
+ unsigned int mAppliedIBSerial;
+ IDirect3DVertexShader9 *mAppliedVertexShader;
+ IDirect3DPixelShader9 *mAppliedPixelShader;
+ unsigned int mAppliedProgramSerial;
+
+ // A pool of event queries that are currently unused.
+ std::vector<IDirect3DQuery9 *> mEventQueryPool;
+ VertexShaderCache mVertexShaderCache;
+ PixelShaderCache mPixelShaderCache;
+
+ VertexDataManager *mVertexDataManager;
+ VertexDeclarationCache mVertexDeclarationCache;
+
+ IndexDataManager *mIndexDataManager;
+ StreamingIndexBufferInterface *mLineLoopIB;
+ StaticIndexBufferInterface *mCountingIB;
+
+ enum
+ {
+ NUM_NULL_COLORBUFFER_CACHE_ENTRIES = 12
+ };
+ struct NullRenderTargetCacheEntry
+ {
+ UINT lruCount;
+ int width;
+ int height;
+ RenderTarget9 *renderTarget;
+ };
+
+ std::array<NullRenderTargetCacheEntry, NUM_NULL_COLORBUFFER_CACHE_ENTRIES>
+ mNullRenderTargetCache;
+ UINT mMaxNullColorbufferLRU;
+
+ std::vector<TranslatedAttribute> mTranslatedAttribCache;
+
+ DebugAnnotator9 mAnnotator;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D9_RENDERER9_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/ShaderCache.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/ShaderCache.h
new file mode 100644
index 0000000000..bd1a4cf269
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/ShaderCache.h
@@ -0,0 +1,110 @@
+//
+// Copyright 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.
+//
+
+// ShaderCache: Defines rx::ShaderCache, a cache of Direct3D shader objects
+// keyed by their byte code.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D9_SHADERCACHE_H_
+#define LIBANGLE_RENDERER_D3D_D3D9_SHADERCACHE_H_
+
+#include "libANGLE/Error.h"
+
+#include "common/debug.h"
+#include "libANGLE/renderer/d3d/d3d9/Context9.h"
+
+#include <cstddef>
+#include <mutex>
+#include <string>
+#include <unordered_map>
+
+namespace rx
+{
+template <typename ShaderObject>
+class ShaderCache : angle::NonCopyable
+{
+ public:
+ ShaderCache() : mDevice(nullptr) {}
+
+ ~ShaderCache()
+ {
+ // Call clear while the device is still valid.
+ ASSERT(mMap.empty());
+ }
+
+ void initialize(IDirect3DDevice9 *device) { mDevice = device; }
+
+ angle::Result create(d3d::Context *context,
+ const DWORD *function,
+ size_t length,
+ ShaderObject **outShaderObject)
+ {
+ std::lock_guard<std::mutex> lock(mMutex);
+
+ std::string key(reinterpret_cast<const char *>(function), length);
+ typename Map::iterator it = mMap.find(key);
+ if (it != mMap.end())
+ {
+ it->second->AddRef();
+ *outShaderObject = it->second;
+ return angle::Result::Continue;
+ }
+
+ ShaderObject *shader;
+ HRESULT result = createShader(function, &shader);
+ ANGLE_TRY_HR(context, result, "Failed to create shader");
+
+ // Random eviction policy.
+ if (mMap.size() >= kMaxMapSize)
+ {
+ SafeRelease(mMap.begin()->second);
+ mMap.erase(mMap.begin());
+ }
+
+ shader->AddRef();
+ mMap[key] = shader;
+
+ *outShaderObject = shader;
+ return angle::Result::Continue;
+ }
+
+ void clear()
+ {
+ std::lock_guard<std::mutex> lock(mMutex);
+
+ for (typename Map::iterator it = mMap.begin(); it != mMap.end(); ++it)
+ {
+ SafeRelease(it->second);
+ }
+
+ mMap.clear();
+ }
+
+ private:
+ const static size_t kMaxMapSize = 100;
+
+ HRESULT createShader(const DWORD *function, IDirect3DVertexShader9 **shader)
+ {
+ return mDevice->CreateVertexShader(function, shader);
+ }
+
+ HRESULT createShader(const DWORD *function, IDirect3DPixelShader9 **shader)
+ {
+ return mDevice->CreatePixelShader(function, shader);
+ }
+
+ typedef angle::HashMap<std::string, ShaderObject *> Map;
+ Map mMap;
+ std::mutex mMutex;
+
+ IDirect3DDevice9 *mDevice;
+};
+
+typedef ShaderCache<IDirect3DVertexShader9> VertexShaderCache;
+typedef ShaderCache<IDirect3DPixelShader9> PixelShaderCache;
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D9_SHADERCACHE_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.cpp
new file mode 100644
index 0000000000..b5c237f9a7
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.cpp
@@ -0,0 +1,51 @@
+//
+// Copyright 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.
+//
+
+// ShaderExecutable9.cpp: Implements a D3D9-specific class to contain shader
+// executable implementation details.
+
+#include "libANGLE/renderer/d3d/d3d9/ShaderExecutable9.h"
+
+#include "common/debug.h"
+
+namespace rx
+{
+
+ShaderExecutable9::ShaderExecutable9(const void *function,
+ size_t length,
+ IDirect3DPixelShader9 *executable)
+ : ShaderExecutableD3D(function, length)
+{
+ mPixelExecutable = executable;
+ mVertexExecutable = nullptr;
+}
+
+ShaderExecutable9::ShaderExecutable9(const void *function,
+ size_t length,
+ IDirect3DVertexShader9 *executable)
+ : ShaderExecutableD3D(function, length)
+{
+ mVertexExecutable = executable;
+ mPixelExecutable = nullptr;
+}
+
+ShaderExecutable9::~ShaderExecutable9()
+{
+ SafeRelease(mVertexExecutable);
+ SafeRelease(mPixelExecutable);
+}
+
+IDirect3DVertexShader9 *ShaderExecutable9::getVertexShader() const
+{
+ return mVertexExecutable;
+}
+
+IDirect3DPixelShader9 *ShaderExecutable9::getPixelShader() const
+{
+ return mPixelExecutable;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.h
new file mode 100644
index 0000000000..0c8c595ef0
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.h
@@ -0,0 +1,35 @@
+//
+// Copyright 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.
+//
+
+// ShaderExecutable9.h: Defines a D3D9-specific class to contain shader
+// executable implementation details.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D9_SHADEREXECUTABLE9_H_
+#define LIBANGLE_RENDERER_D3D_D3D9_SHADEREXECUTABLE9_H_
+
+#include "libANGLE/renderer/d3d/ShaderExecutableD3D.h"
+
+namespace rx
+{
+
+class ShaderExecutable9 : public ShaderExecutableD3D
+{
+ public:
+ ShaderExecutable9(const void *function, size_t length, IDirect3DPixelShader9 *executable);
+ ShaderExecutable9(const void *function, size_t length, IDirect3DVertexShader9 *executable);
+ ~ShaderExecutable9() override;
+
+ IDirect3DPixelShader9 *getPixelShader() const;
+ IDirect3DVertexShader9 *getVertexShader() const;
+
+ private:
+ IDirect3DPixelShader9 *mPixelExecutable;
+ IDirect3DVertexShader9 *mVertexExecutable;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D9_SHADEREXECUTABLE9_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp
new file mode 100644
index 0000000000..cad011b25a
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp
@@ -0,0 +1,888 @@
+//
+// 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.
+//
+
+// StateManager9.cpp: Defines a class for caching D3D9 state
+#include "libANGLE/renderer/d3d/d3d9/StateManager9.h"
+
+#include "common/bitset_utils.h"
+#include "common/utilities.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/d3d/d3d9/Framebuffer9.h"
+#include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
+#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h"
+
+namespace rx
+{
+
+StateManager9::StateManager9(Renderer9 *renderer9)
+ : mUsingZeroColorMaskWorkaround(false),
+ mCurSampleAlphaToCoverage(false),
+ mCurBlendState(),
+ mCurBlendColor(0, 0, 0, 0),
+ mCurSampleMask(0),
+ mCurRasterState(),
+ mCurDepthSize(0),
+ mCurDepthStencilState(),
+ mCurStencilRef(0),
+ mCurStencilBackRef(0),
+ mCurFrontFaceCCW(0),
+ mCurStencilSize(0),
+ mCurScissorRect(),
+ mCurScissorEnabled(false),
+ mCurViewport(),
+ mCurNear(0.0f),
+ mCurFar(0.0f),
+ mCurDepthFront(0.0f),
+ mCurIgnoreViewport(false),
+ mRenderer9(renderer9),
+ mDirtyBits()
+{
+ mBlendStateDirtyBits.set(DIRTY_BIT_BLEND_ENABLED);
+ mBlendStateDirtyBits.set(DIRTY_BIT_BLEND_COLOR);
+ mBlendStateDirtyBits.set(DIRTY_BIT_BLEND_FUNCS_EQUATIONS);
+ mBlendStateDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE);
+ mBlendStateDirtyBits.set(DIRTY_BIT_COLOR_MASK);
+ mBlendStateDirtyBits.set(DIRTY_BIT_DITHER);
+ mBlendStateDirtyBits.set(DIRTY_BIT_SAMPLE_MASK);
+
+ mRasterizerStateDirtyBits.set(DIRTY_BIT_CULL_MODE);
+ mRasterizerStateDirtyBits.set(DIRTY_BIT_DEPTH_BIAS);
+
+ mDepthStencilStateDirtyBits.set(DIRTY_BIT_STENCIL_DEPTH_MASK);
+ mDepthStencilStateDirtyBits.set(DIRTY_BIT_STENCIL_DEPTH_FUNC);
+ mDepthStencilStateDirtyBits.set(DIRTY_BIT_STENCIL_TEST_ENABLED);
+ mDepthStencilStateDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_FRONT);
+ mDepthStencilStateDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_BACK);
+ mDepthStencilStateDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
+ mDepthStencilStateDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK);
+ mDepthStencilStateDirtyBits.set(DIRTY_BIT_STENCIL_OPS_FRONT);
+ mDepthStencilStateDirtyBits.set(DIRTY_BIT_STENCIL_OPS_BACK);
+
+ mScissorStateDirtyBits.set(DIRTY_BIT_SCISSOR_ENABLED);
+ mScissorStateDirtyBits.set(DIRTY_BIT_SCISSOR_RECT);
+}
+
+StateManager9::~StateManager9() {}
+
+void StateManager9::initialize()
+{
+ mUsingZeroColorMaskWorkaround = IsAMD(mRenderer9->getVendorId());
+}
+
+void StateManager9::forceSetBlendState()
+{
+ mDirtyBits |= mBlendStateDirtyBits;
+}
+
+void StateManager9::forceSetRasterState()
+{
+ mDirtyBits |= mRasterizerStateDirtyBits;
+}
+
+void StateManager9::forceSetDepthStencilState()
+{
+ mDirtyBits |= mDepthStencilStateDirtyBits;
+}
+
+void StateManager9::forceSetScissorState()
+{
+ mDirtyBits |= mScissorStateDirtyBits;
+}
+
+void StateManager9::forceSetViewportState()
+{
+ mForceSetViewport = true;
+}
+
+void StateManager9::forceSetDXUniformsState()
+{
+ mDxUniformsDirty = true;
+}
+
+void StateManager9::updateStencilSizeIfChanged(bool depthStencilInitialized,
+ unsigned int stencilSize)
+{
+ if (!depthStencilInitialized || stencilSize != mCurStencilSize)
+ {
+ mCurStencilSize = stencilSize;
+ forceSetDepthStencilState();
+ }
+}
+
+void StateManager9::syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits)
+{
+ if (!dirtyBits.any())
+ {
+ return;
+ }
+
+ for (auto dirtyBit : dirtyBits)
+ {
+ switch (dirtyBit)
+ {
+ case gl::State::DIRTY_BIT_BLEND_ENABLED:
+ if (state.getBlendState().blend != mCurBlendState.blend)
+ {
+ mDirtyBits.set(DIRTY_BIT_BLEND_ENABLED);
+ // BlendColor and funcs and equations has to be set if blend is enabled
+ mDirtyBits.set(DIRTY_BIT_BLEND_COLOR);
+ mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS_EQUATIONS);
+
+ // The color mask may have to be updated if the blend state changes
+ if (mUsingZeroColorMaskWorkaround)
+ {
+ mDirtyBits.set(DIRTY_BIT_COLOR_MASK);
+ }
+ }
+ break;
+ case gl::State::DIRTY_BIT_BLEND_FUNCS:
+ {
+ const gl::BlendState &blendState = state.getBlendState();
+ if (blendState.sourceBlendRGB != mCurBlendState.sourceBlendRGB ||
+ blendState.destBlendRGB != mCurBlendState.destBlendRGB ||
+ blendState.sourceBlendAlpha != mCurBlendState.sourceBlendAlpha ||
+ blendState.destBlendAlpha != mCurBlendState.destBlendAlpha)
+ {
+ mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS_EQUATIONS);
+ // BlendColor depends on the values of blend funcs
+ mDirtyBits.set(DIRTY_BIT_BLEND_COLOR);
+
+ // The color mask may have to be updated if the blend funcs change
+ if (mUsingZeroColorMaskWorkaround)
+ {
+ mDirtyBits.set(DIRTY_BIT_COLOR_MASK);
+ }
+ }
+ break;
+ }
+ case gl::State::DIRTY_BIT_BLEND_EQUATIONS:
+ {
+ const gl::BlendState &blendState = state.getBlendState();
+ if (blendState.blendEquationRGB != mCurBlendState.blendEquationRGB ||
+ blendState.blendEquationAlpha != mCurBlendState.blendEquationAlpha)
+ {
+ mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS_EQUATIONS);
+
+ // The color mask may have to be updated if the blend funcs change
+ if (mUsingZeroColorMaskWorkaround)
+ {
+ mDirtyBits.set(DIRTY_BIT_COLOR_MASK);
+ }
+ }
+ break;
+ }
+ case gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED:
+ if (state.isSampleAlphaToCoverageEnabled() != mCurSampleAlphaToCoverage)
+ {
+ mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE);
+ }
+ break;
+ case gl::State::DIRTY_BIT_COLOR_MASK:
+ {
+ const gl::BlendState &blendState = state.getBlendState();
+ if (blendState.colorMaskRed != mCurBlendState.colorMaskRed ||
+ blendState.colorMaskGreen != mCurBlendState.colorMaskGreen ||
+ blendState.colorMaskBlue != mCurBlendState.colorMaskBlue ||
+ blendState.colorMaskAlpha != mCurBlendState.colorMaskAlpha)
+ {
+ mDirtyBits.set(DIRTY_BIT_COLOR_MASK);
+
+ // The color mask can cause the blend state to get out of sync when using the
+ // zero color mask workaround
+ if (mUsingZeroColorMaskWorkaround)
+ {
+ mDirtyBits.set(DIRTY_BIT_BLEND_ENABLED);
+ mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS_EQUATIONS);
+ }
+ }
+ break;
+ }
+ case gl::State::DIRTY_BIT_DITHER_ENABLED:
+ if (state.getRasterizerState().dither != mCurRasterState.dither)
+ {
+ mDirtyBits.set(DIRTY_BIT_DITHER);
+ }
+ break;
+ case gl::State::DIRTY_BIT_BLEND_COLOR:
+ if (state.getBlendColor() != mCurBlendColor)
+ {
+ mDirtyBits.set(DIRTY_BIT_BLEND_COLOR);
+ }
+ break;
+ case gl::State::DIRTY_BIT_CULL_FACE_ENABLED:
+ if (state.getRasterizerState().cullFace != mCurRasterState.cullFace)
+ {
+ mDirtyBits.set(DIRTY_BIT_CULL_MODE);
+ }
+ break;
+ case gl::State::DIRTY_BIT_CULL_FACE:
+ if (state.getRasterizerState().cullMode != mCurRasterState.cullMode)
+ {
+ mDirtyBits.set(DIRTY_BIT_CULL_MODE);
+ }
+ break;
+ case gl::State::DIRTY_BIT_FRONT_FACE:
+ if (state.getRasterizerState().frontFace != mCurRasterState.frontFace)
+ {
+ mDirtyBits.set(DIRTY_BIT_CULL_MODE);
+
+ // Viewport state depends on rasterizer.frontface
+ mDirtyBits.set(DIRTY_BIT_VIEWPORT);
+ }
+ break;
+ case gl::State::DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED:
+ if (state.getRasterizerState().polygonOffsetFill !=
+ mCurRasterState.polygonOffsetFill)
+ {
+ mDirtyBits.set(DIRTY_BIT_DEPTH_BIAS);
+ }
+ break;
+ case gl::State::DIRTY_BIT_POLYGON_OFFSET:
+ {
+ const gl::RasterizerState &rasterizerState = state.getRasterizerState();
+ if (rasterizerState.polygonOffsetFactor != mCurRasterState.polygonOffsetFactor ||
+ rasterizerState.polygonOffsetUnits != mCurRasterState.polygonOffsetUnits)
+ {
+ mDirtyBits.set(DIRTY_BIT_DEPTH_BIAS);
+ }
+ break;
+ }
+ // Depth and stencil redundant state changes are guarded in the
+ // frontend so for related cases here just set the dirty bit.
+ case gl::State::DIRTY_BIT_DEPTH_MASK:
+ if (state.getDepthStencilState().depthMask != mCurDepthStencilState.depthMask)
+ {
+ mDirtyBits.set(DIRTY_BIT_STENCIL_DEPTH_MASK);
+ }
+ break;
+ case gl::State::DIRTY_BIT_DEPTH_TEST_ENABLED:
+ mDirtyBits.set(DIRTY_BIT_STENCIL_DEPTH_FUNC);
+ break;
+ case gl::State::DIRTY_BIT_DEPTH_FUNC:
+ mDirtyBits.set(DIRTY_BIT_STENCIL_DEPTH_FUNC);
+ break;
+ case gl::State::DIRTY_BIT_STENCIL_TEST_ENABLED:
+ mDirtyBits.set(DIRTY_BIT_STENCIL_TEST_ENABLED);
+ // If we enable the stencil test, all of these must be set
+ mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK);
+ mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
+ mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_FRONT);
+ mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_BACK);
+ mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_FRONT);
+ mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_BACK);
+ break;
+ case gl::State::DIRTY_BIT_STENCIL_FUNCS_FRONT:
+ mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_FRONT);
+ break;
+ case gl::State::DIRTY_BIT_STENCIL_FUNCS_BACK:
+ mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_BACK);
+ break;
+ case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT:
+ mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
+ break;
+ case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_BACK:
+ mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK);
+ break;
+ case gl::State::DIRTY_BIT_STENCIL_OPS_FRONT:
+ mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_FRONT);
+ break;
+ case gl::State::DIRTY_BIT_STENCIL_OPS_BACK:
+ mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_BACK);
+ break;
+ case gl::State::DIRTY_BIT_SCISSOR_TEST_ENABLED:
+ if (state.isScissorTestEnabled() != mCurScissorEnabled)
+ {
+ mDirtyBits.set(DIRTY_BIT_SCISSOR_ENABLED);
+ // If scissor is enabled, we have to set the scissor rect
+ mDirtyBits.set(DIRTY_BIT_SCISSOR_RECT);
+ }
+ break;
+ case gl::State::DIRTY_BIT_SCISSOR:
+ if (state.getScissor() != mCurScissorRect)
+ {
+ mDirtyBits.set(DIRTY_BIT_SCISSOR_RECT);
+ }
+ break;
+ case gl::State::DIRTY_BIT_DEPTH_RANGE:
+ mDirtyBits.set(DIRTY_BIT_VIEWPORT);
+ break;
+ case gl::State::DIRTY_BIT_VIEWPORT:
+ if (state.getViewport() != mCurViewport)
+ {
+ mDirtyBits.set(DIRTY_BIT_VIEWPORT);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void StateManager9::setBlendDepthRasterStates(const gl::State &glState, unsigned int sampleMask)
+{
+ const gl::Framebuffer *framebuffer = glState.getDrawFramebuffer();
+
+ const gl::BlendState &blendState = glState.getBlendState();
+ const gl::ColorF &blendColor = glState.getBlendColor();
+ const gl::RasterizerState &rasterState = glState.getRasterizerState();
+
+ const auto &depthStencilState = glState.getDepthStencilState();
+ bool frontFaceCCW = (glState.getRasterizerState().frontFace == GL_CCW);
+ unsigned int maxStencil = (1 << mCurStencilSize) - 1;
+
+ // All the depth stencil states depends on the front face ccw variable
+ if (frontFaceCCW != mCurFrontFaceCCW)
+ {
+ forceSetDepthStencilState();
+ mCurFrontFaceCCW = frontFaceCCW;
+ }
+
+ for (auto dirtyBit : mDirtyBits)
+ {
+ switch (dirtyBit)
+ {
+ case DIRTY_BIT_BLEND_ENABLED:
+ setBlendEnabled(blendState.blend);
+ break;
+ case DIRTY_BIT_BLEND_COLOR:
+ setBlendColor(blendState, blendColor);
+ break;
+ case DIRTY_BIT_BLEND_FUNCS_EQUATIONS:
+ setBlendFuncsEquations(blendState);
+ break;
+ case DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE:
+ setSampleAlphaToCoverage(glState.isSampleAlphaToCoverageEnabled());
+ break;
+ case DIRTY_BIT_COLOR_MASK:
+ setColorMask(framebuffer, blendState.colorMaskRed, blendState.colorMaskBlue,
+ blendState.colorMaskGreen, blendState.colorMaskAlpha);
+ break;
+ case DIRTY_BIT_DITHER:
+ setDither(rasterState.dither);
+ break;
+ case DIRTY_BIT_CULL_MODE:
+ setCullMode(rasterState.cullFace, rasterState.cullMode, rasterState.frontFace);
+ break;
+ case DIRTY_BIT_DEPTH_BIAS:
+ setDepthBias(rasterState.polygonOffsetFill, rasterState.polygonOffsetFactor,
+ rasterState.polygonOffsetUnits);
+ break;
+ case DIRTY_BIT_STENCIL_DEPTH_MASK:
+ setDepthMask(depthStencilState.depthMask);
+ break;
+ case DIRTY_BIT_STENCIL_DEPTH_FUNC:
+ setDepthFunc(depthStencilState.depthTest, depthStencilState.depthFunc);
+ break;
+ case DIRTY_BIT_STENCIL_TEST_ENABLED:
+ setStencilTestEnabled(depthStencilState.stencilTest);
+ break;
+ case DIRTY_BIT_STENCIL_FUNCS_FRONT:
+ setStencilFuncsFront(depthStencilState.stencilFunc, depthStencilState.stencilMask,
+ glState.getStencilRef(), frontFaceCCW, maxStencil);
+ break;
+ case DIRTY_BIT_STENCIL_FUNCS_BACK:
+ setStencilFuncsBack(depthStencilState.stencilBackFunc,
+ depthStencilState.stencilBackMask, glState.getStencilBackRef(),
+ frontFaceCCW, maxStencil);
+ break;
+ case DIRTY_BIT_STENCIL_WRITEMASK_FRONT:
+ setStencilWriteMask(depthStencilState.stencilWritemask, frontFaceCCW);
+ break;
+ case DIRTY_BIT_STENCIL_WRITEMASK_BACK:
+ setStencilBackWriteMask(depthStencilState.stencilBackWritemask, frontFaceCCW);
+ break;
+ case DIRTY_BIT_STENCIL_OPS_FRONT:
+ setStencilOpsFront(depthStencilState.stencilFail,
+ depthStencilState.stencilPassDepthFail,
+ depthStencilState.stencilPassDepthPass, frontFaceCCW);
+ break;
+ case DIRTY_BIT_STENCIL_OPS_BACK:
+ setStencilOpsBack(depthStencilState.stencilBackFail,
+ depthStencilState.stencilBackPassDepthFail,
+ depthStencilState.stencilBackPassDepthPass, frontFaceCCW);
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (sampleMask != mCurSampleMask)
+ {
+ setSampleMask(sampleMask);
+ }
+}
+
+void StateManager9::setViewportState(const gl::Rectangle &viewport,
+ float zNear,
+ float zFar,
+ gl::PrimitiveMode drawMode,
+ GLenum frontFace,
+ bool ignoreViewport)
+{
+ if (!mDirtyBits.test(DIRTY_BIT_VIEWPORT) && mCurIgnoreViewport == ignoreViewport)
+ return;
+
+ gl::Rectangle actualViewport = viewport;
+ float actualZNear = gl::clamp01(zNear);
+ float actualZFar = gl::clamp01(zFar);
+
+ if (ignoreViewport)
+ {
+ actualViewport.x = 0;
+ actualViewport.y = 0;
+ actualViewport.width = static_cast<int>(mRenderTargetBounds.width);
+ actualViewport.height = static_cast<int>(mRenderTargetBounds.height);
+ actualZNear = 0.0f;
+ actualZFar = 1.0f;
+ }
+
+ D3DVIEWPORT9 dxViewport;
+ dxViewport.X = gl::clamp(actualViewport.x, 0, static_cast<int>(mRenderTargetBounds.width));
+ dxViewport.Y = gl::clamp(actualViewport.y, 0, static_cast<int>(mRenderTargetBounds.height));
+ dxViewport.Width =
+ gl::clamp(actualViewport.width, 0,
+ static_cast<int>(mRenderTargetBounds.width) - static_cast<int>(dxViewport.X));
+ dxViewport.Height =
+ gl::clamp(actualViewport.height, 0,
+ static_cast<int>(mRenderTargetBounds.height) - static_cast<int>(dxViewport.Y));
+ dxViewport.MinZ = actualZNear;
+ dxViewport.MaxZ = actualZFar;
+
+ float depthFront = !gl::IsTriangleMode(drawMode) ? 0.0f : (frontFace == GL_CCW ? 1.0f : -1.0f);
+
+ mRenderer9->getDevice()->SetViewport(&dxViewport);
+
+ mCurViewport = actualViewport;
+ mCurNear = actualZNear;
+ mCurFar = actualZFar;
+ mCurDepthFront = depthFront;
+ mCurIgnoreViewport = ignoreViewport;
+
+ // Setting shader constants
+ dx_VertexConstants9 vc = {};
+ dx_PixelConstants9 pc = {};
+
+ vc.viewAdjust[0] =
+ static_cast<float>((actualViewport.width - static_cast<int>(dxViewport.Width)) +
+ 2 * (actualViewport.x - static_cast<int>(dxViewport.X)) - 1) /
+ dxViewport.Width;
+ vc.viewAdjust[1] =
+ static_cast<float>((actualViewport.height - static_cast<int>(dxViewport.Height)) +
+ 2 * (actualViewport.y - static_cast<int>(dxViewport.Y)) - 1) /
+ dxViewport.Height;
+ vc.viewAdjust[2] = static_cast<float>(actualViewport.width) / dxViewport.Width;
+ vc.viewAdjust[3] = static_cast<float>(actualViewport.height) / dxViewport.Height;
+
+ pc.viewCoords[0] = actualViewport.width * 0.5f;
+ pc.viewCoords[1] = actualViewport.height * 0.5f;
+ pc.viewCoords[2] = actualViewport.x + (actualViewport.width * 0.5f);
+ pc.viewCoords[3] = actualViewport.y + (actualViewport.height * 0.5f);
+
+ pc.depthFront[0] = (actualZFar - actualZNear) * 0.5f;
+ pc.depthFront[1] = (actualZNear + actualZFar) * 0.5f;
+ pc.depthFront[2] = depthFront;
+
+ vc.depthRange[0] = actualZNear;
+ vc.depthRange[1] = actualZFar;
+ vc.depthRange[2] = actualZFar - actualZNear;
+
+ pc.depthRange[0] = actualZNear;
+ pc.depthRange[1] = actualZFar;
+ pc.depthRange[2] = actualZFar - actualZNear;
+
+ if (memcmp(&vc, &mVertexConstants, sizeof(dx_VertexConstants9)) != 0)
+ {
+ mVertexConstants = vc;
+ mDxUniformsDirty = true;
+ }
+
+ if (memcmp(&pc, &mPixelConstants, sizeof(dx_PixelConstants9)) != 0)
+ {
+ mPixelConstants = pc;
+ mDxUniformsDirty = true;
+ }
+
+ mForceSetViewport = false;
+}
+
+void StateManager9::setShaderConstants()
+{
+ if (!mDxUniformsDirty)
+ return;
+
+ IDirect3DDevice9 *device = mRenderer9->getDevice();
+ device->SetVertexShaderConstantF(0, reinterpret_cast<float *>(&mVertexConstants),
+ sizeof(dx_VertexConstants9) / sizeof(float[4]));
+ device->SetPixelShaderConstantF(0, reinterpret_cast<float *>(&mPixelConstants),
+ sizeof(dx_PixelConstants9) / sizeof(float[4]));
+ mDxUniformsDirty = false;
+}
+
+// This is separate from the main state loop because other functions
+// outside call only setScissorState to update scissor state
+void StateManager9::setScissorState(const gl::Rectangle &scissor, bool enabled)
+{
+ if (mDirtyBits.test(DIRTY_BIT_SCISSOR_ENABLED))
+ setScissorEnabled(enabled);
+
+ if (mDirtyBits.test(DIRTY_BIT_SCISSOR_RECT))
+ setScissorRect(scissor, enabled);
+}
+
+void StateManager9::setRenderTargetBounds(size_t width, size_t height)
+{
+ mRenderTargetBounds.width = (int)width;
+ mRenderTargetBounds.height = (int)height;
+ forceSetViewportState();
+}
+
+void StateManager9::setScissorEnabled(bool scissorEnabled)
+{
+ mRenderer9->getDevice()->SetRenderState(D3DRS_SCISSORTESTENABLE, scissorEnabled ? TRUE : FALSE);
+ mCurScissorEnabled = scissorEnabled;
+}
+
+void StateManager9::setScissorRect(const gl::Rectangle &scissor, bool enabled)
+{
+ if (!enabled)
+ return;
+
+ RECT rect;
+ rect.left = gl::clamp(scissor.x, 0, static_cast<int>(mRenderTargetBounds.width));
+ rect.top = gl::clamp(scissor.y, 0, static_cast<int>(mRenderTargetBounds.height));
+ rect.right =
+ gl::clamp(scissor.x + scissor.width, 0, static_cast<int>(mRenderTargetBounds.width));
+ rect.bottom =
+ gl::clamp(scissor.y + scissor.height, 0, static_cast<int>(mRenderTargetBounds.height));
+ mRenderer9->getDevice()->SetScissorRect(&rect);
+}
+
+void StateManager9::setDepthFunc(bool depthTest, GLenum depthFunc)
+{
+ if (depthTest)
+ {
+ IDirect3DDevice9 *device = mRenderer9->getDevice();
+ device->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
+ device->SetRenderState(D3DRS_ZFUNC, gl_d3d9::ConvertComparison(depthFunc));
+ }
+ else
+ {
+ mRenderer9->getDevice()->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
+ }
+
+ mCurDepthStencilState.depthTest = depthTest;
+ mCurDepthStencilState.depthFunc = depthFunc;
+}
+
+void StateManager9::setStencilOpsFront(GLenum stencilFail,
+ GLenum stencilPassDepthFail,
+ GLenum stencilPassDepthPass,
+ bool frontFaceCCW)
+{
+ // TODO(dianx) It may be slightly more efficient todo these and other similar areas
+ // with separate dirty bits.
+ IDirect3DDevice9 *device = mRenderer9->getDevice();
+ device->SetRenderState(frontFaceCCW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL,
+ gl_d3d9::ConvertStencilOp(stencilFail));
+ device->SetRenderState(frontFaceCCW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL,
+ gl_d3d9::ConvertStencilOp(stencilPassDepthFail));
+ device->SetRenderState(frontFaceCCW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS,
+ gl_d3d9::ConvertStencilOp(stencilPassDepthPass));
+
+ mCurDepthStencilState.stencilFail = stencilFail;
+ mCurDepthStencilState.stencilPassDepthFail = stencilPassDepthFail;
+ mCurDepthStencilState.stencilPassDepthPass = stencilPassDepthPass;
+}
+
+void StateManager9::setStencilOpsBack(GLenum stencilBackFail,
+ GLenum stencilBackPassDepthFail,
+ GLenum stencilBackPassDepthPass,
+ bool frontFaceCCW)
+{
+ IDirect3DDevice9 *device = mRenderer9->getDevice();
+ device->SetRenderState(!frontFaceCCW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL,
+ gl_d3d9::ConvertStencilOp(stencilBackFail));
+ device->SetRenderState(!frontFaceCCW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL,
+ gl_d3d9::ConvertStencilOp(stencilBackPassDepthFail));
+ device->SetRenderState(!frontFaceCCW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS,
+ gl_d3d9::ConvertStencilOp(stencilBackPassDepthPass));
+
+ mCurDepthStencilState.stencilBackFail = stencilBackFail;
+ mCurDepthStencilState.stencilBackPassDepthFail = stencilBackPassDepthFail;
+ mCurDepthStencilState.stencilBackPassDepthPass = stencilBackPassDepthPass;
+}
+
+void StateManager9::setStencilBackWriteMask(GLuint stencilBackWriteMask, bool frontFaceCCW)
+{
+ mRenderer9->getDevice()->SetRenderState(
+ !frontFaceCCW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, stencilBackWriteMask);
+
+ mCurDepthStencilState.stencilBackWritemask = stencilBackWriteMask;
+}
+
+void StateManager9::setStencilFuncsBack(GLenum stencilBackFunc,
+ GLuint stencilBackMask,
+ GLint stencilBackRef,
+ bool frontFaceCCW,
+ unsigned int maxStencil)
+{
+ IDirect3DDevice9 *device = mRenderer9->getDevice();
+ device->SetRenderState(!frontFaceCCW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC,
+ gl_d3d9::ConvertComparison(stencilBackFunc));
+ device->SetRenderState(!frontFaceCCW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF,
+ (stencilBackRef < (int)maxStencil) ? stencilBackRef : maxStencil);
+ device->SetRenderState(!frontFaceCCW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK,
+ stencilBackMask);
+
+ mCurDepthStencilState.stencilBackFunc = stencilBackFunc;
+ mCurStencilBackRef = stencilBackRef;
+ mCurDepthStencilState.stencilBackMask = stencilBackMask;
+}
+
+void StateManager9::setStencilWriteMask(GLuint stencilWriteMask, bool frontFaceCCW)
+{
+ mRenderer9->getDevice()->SetRenderState(
+ frontFaceCCW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, stencilWriteMask);
+ mCurDepthStencilState.stencilWritemask = stencilWriteMask;
+}
+
+void StateManager9::setStencilFuncsFront(GLenum stencilFunc,
+ GLuint stencilMask,
+ GLint stencilRef,
+ bool frontFaceCCW,
+ unsigned int maxStencil)
+{
+ IDirect3DDevice9 *device = mRenderer9->getDevice();
+ device->SetRenderState(frontFaceCCW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC,
+ gl_d3d9::ConvertComparison(stencilFunc));
+ device->SetRenderState(frontFaceCCW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF,
+ (stencilRef < static_cast<int>(maxStencil)) ? stencilRef : maxStencil);
+ device->SetRenderState(frontFaceCCW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, stencilMask);
+
+ mCurDepthStencilState.stencilFunc = stencilFunc;
+ mCurStencilRef = stencilRef;
+ mCurDepthStencilState.stencilMask = stencilMask;
+}
+void StateManager9::setStencilTestEnabled(bool stencilTestEnabled)
+{
+ if (stencilTestEnabled && mCurStencilSize > 0)
+ {
+ mRenderer9->getDevice()->SetRenderState(D3DRS_STENCILENABLE, TRUE);
+ mRenderer9->getDevice()->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, TRUE);
+ }
+ else
+ {
+ mRenderer9->getDevice()->SetRenderState(D3DRS_STENCILENABLE, FALSE);
+ }
+
+ mCurDepthStencilState.stencilTest = stencilTestEnabled;
+}
+
+void StateManager9::setDepthMask(bool depthMask)
+{
+ mRenderer9->getDevice()->SetRenderState(D3DRS_ZWRITEENABLE, depthMask ? TRUE : FALSE);
+ mCurDepthStencilState.depthMask = depthMask;
+}
+
+// TODO(dianx) one bit for sampleAlphaToCoverage
+void StateManager9::setSampleAlphaToCoverage(bool enabled)
+{
+ if (enabled)
+ {
+ // D3D9 support for alpha-to-coverage is vendor-specific.
+ UNIMPLEMENTED();
+ }
+}
+
+void StateManager9::setBlendColor(const gl::BlendState &blendState, const gl::ColorF &blendColor)
+{
+ if (!blendState.blend)
+ return;
+
+ if (blendState.sourceBlendRGB != GL_CONSTANT_ALPHA &&
+ blendState.sourceBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA &&
+ blendState.destBlendRGB != GL_CONSTANT_ALPHA &&
+ blendState.destBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA)
+ {
+ mRenderer9->getDevice()->SetRenderState(D3DRS_BLENDFACTOR,
+ gl_d3d9::ConvertColor(blendColor));
+ }
+ else
+ {
+ mRenderer9->getDevice()->SetRenderState(
+ D3DRS_BLENDFACTOR,
+ D3DCOLOR_RGBA(gl::unorm<8>(blendColor.alpha), gl::unorm<8>(blendColor.alpha),
+ gl::unorm<8>(blendColor.alpha), gl::unorm<8>(blendColor.alpha)));
+ }
+ mCurBlendColor = blendColor;
+}
+
+void StateManager9::setBlendFuncsEquations(const gl::BlendState &blendState)
+{
+ if (!blendState.blend)
+ return;
+
+ IDirect3DDevice9 *device = mRenderer9->getDevice();
+
+ device->SetRenderState(D3DRS_SRCBLEND, gl_d3d9::ConvertBlendFunc(blendState.sourceBlendRGB));
+ device->SetRenderState(D3DRS_DESTBLEND, gl_d3d9::ConvertBlendFunc(blendState.destBlendRGB));
+ device->SetRenderState(D3DRS_BLENDOP, gl_d3d9::ConvertBlendOp(blendState.blendEquationRGB));
+
+ if (blendState.sourceBlendRGB != blendState.sourceBlendAlpha ||
+ blendState.destBlendRGB != blendState.destBlendAlpha ||
+ blendState.blendEquationRGB != blendState.blendEquationAlpha)
+ {
+ device->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
+
+ device->SetRenderState(D3DRS_SRCBLENDALPHA,
+ gl_d3d9::ConvertBlendFunc(blendState.sourceBlendAlpha));
+ device->SetRenderState(D3DRS_DESTBLENDALPHA,
+ gl_d3d9::ConvertBlendFunc(blendState.destBlendAlpha));
+ device->SetRenderState(D3DRS_BLENDOPALPHA,
+ gl_d3d9::ConvertBlendOp(blendState.blendEquationAlpha));
+ }
+ else
+ {
+ device->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, FALSE);
+ }
+
+ mCurBlendState.sourceBlendRGB = blendState.sourceBlendRGB;
+ mCurBlendState.destBlendRGB = blendState.destBlendRGB;
+ mCurBlendState.blendEquationRGB = blendState.blendEquationRGB;
+ mCurBlendState.blendEquationAlpha = blendState.blendEquationAlpha;
+}
+
+void StateManager9::setBlendEnabled(bool enabled)
+{
+ mRenderer9->getDevice()->SetRenderState(D3DRS_ALPHABLENDENABLE, enabled ? TRUE : FALSE);
+ mCurBlendState.blend = enabled;
+}
+
+void StateManager9::setDither(bool dither)
+{
+ mRenderer9->getDevice()->SetRenderState(D3DRS_DITHERENABLE, dither ? TRUE : FALSE);
+ mCurRasterState.dither = dither;
+}
+
+// TODO(dianx) one bit for color mask
+void StateManager9::setColorMask(const gl::Framebuffer *framebuffer,
+ bool red,
+ bool blue,
+ bool green,
+ bool alpha)
+{
+ // Set the color mask
+
+ const auto *attachment = framebuffer->getFirstColorAttachment();
+ const auto &format = attachment ? attachment->getFormat() : gl::Format::Invalid();
+
+ DWORD colorMask = gl_d3d9::ConvertColorMask(
+ 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
+ // blend state so that no drawing is done.
+ // http://anglebug.com/169
+ if (colorMask == 0 && mUsingZeroColorMaskWorkaround)
+ {
+ IDirect3DDevice9 *device = mRenderer9->getDevice();
+ // Enable green channel, but set blending so nothing will be drawn.
+ device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_GREEN);
+
+ device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
+
+ device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
+ device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
+ device->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
+
+ mCurBlendState.colorMaskRed = false;
+ mCurBlendState.colorMaskGreen = true;
+ mCurBlendState.colorMaskBlue = false;
+ mCurBlendState.colorMaskAlpha = false;
+
+ mCurBlendState.blend = true;
+ mCurBlendState.sourceBlendRGB = GL_ZERO;
+ mCurBlendState.sourceBlendAlpha = GL_ZERO;
+ mCurBlendState.destBlendRGB = GL_ONE;
+ mCurBlendState.destBlendAlpha = GL_ONE;
+ mCurBlendState.blendEquationRGB = GL_FUNC_ADD;
+ mCurBlendState.blendEquationAlpha = GL_FUNC_ADD;
+ }
+ else
+ {
+ mRenderer9->getDevice()->SetRenderState(D3DRS_COLORWRITEENABLE, colorMask);
+
+ mCurBlendState.colorMaskRed = red;
+ mCurBlendState.colorMaskGreen = green;
+ mCurBlendState.colorMaskBlue = blue;
+ mCurBlendState.colorMaskAlpha = alpha;
+ }
+}
+
+void StateManager9::setSampleMask(unsigned int sampleMask)
+{
+ IDirect3DDevice9 *device = mRenderer9->getDevice();
+ // Set the multisample mask
+ device->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE);
+ device->SetRenderState(D3DRS_MULTISAMPLEMASK, static_cast<DWORD>(sampleMask));
+
+ mCurSampleMask = sampleMask;
+}
+
+void StateManager9::setCullMode(bool cullFace, gl::CullFaceMode cullMode, GLenum frontFace)
+{
+ if (cullFace)
+ {
+ mRenderer9->getDevice()->SetRenderState(D3DRS_CULLMODE,
+ gl_d3d9::ConvertCullMode(cullMode, frontFace));
+ }
+ else
+ {
+ mRenderer9->getDevice()->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
+ }
+
+ mCurRasterState.cullFace = cullFace;
+ mCurRasterState.cullMode = cullMode;
+ mCurRasterState.frontFace = frontFace;
+}
+
+void StateManager9::setDepthBias(bool polygonOffsetFill,
+ GLfloat polygonOffsetFactor,
+ GLfloat polygonOffsetUnits)
+{
+ if (polygonOffsetFill)
+ {
+ if (mCurDepthSize > 0)
+ {
+ IDirect3DDevice9 *device = mRenderer9->getDevice();
+ device->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, *(DWORD *)&polygonOffsetFactor);
+
+ float depthBias = ldexp(polygonOffsetUnits, -static_cast<int>(mCurDepthSize));
+ device->SetRenderState(D3DRS_DEPTHBIAS, *(DWORD *)&depthBias);
+ }
+ }
+ else
+ {
+ IDirect3DDevice9 *device = mRenderer9->getDevice();
+ device->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, 0);
+ device->SetRenderState(D3DRS_DEPTHBIAS, 0);
+ }
+
+ mCurRasterState.polygonOffsetFill = polygonOffsetFill;
+ mCurRasterState.polygonOffsetFactor = polygonOffsetFactor;
+ mCurRasterState.polygonOffsetUnits = polygonOffsetUnits;
+}
+
+void StateManager9::updateDepthSizeIfChanged(bool depthStencilInitialized, unsigned int depthSize)
+{
+ if (!depthStencilInitialized || depthSize != mCurDepthSize)
+ {
+ mCurDepthSize = depthSize;
+ forceSetRasterState();
+ }
+}
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/StateManager9.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/StateManager9.h
new file mode 100644
index 0000000000..b047b69cdd
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/StateManager9.h
@@ -0,0 +1,211 @@
+//
+// 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.
+//
+
+// StateManager9.h: Defines a class for caching D3D9 state
+
+#ifndef LIBANGLE_RENDERER_D3D9_STATEMANAGER9_H_
+#define LIBANGLE_RENDERER_D3D9_STATEMANAGER9_H_
+
+#include "libANGLE/State.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
+
+namespace rx
+{
+
+class Renderer9;
+
+struct dx_VertexConstants9
+{
+ float depthRange[4];
+ float viewAdjust[4];
+ float viewCoords[4];
+};
+
+struct dx_PixelConstants9
+{
+ float depthRange[4];
+ float viewCoords[4];
+ float depthFront[4];
+};
+
+class StateManager9 final : angle::NonCopyable
+{
+ public:
+ StateManager9(Renderer9 *renderer9);
+ ~StateManager9();
+
+ void initialize();
+
+ void syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits);
+
+ void setBlendDepthRasterStates(const gl::State &glState, unsigned int sampleMask);
+ void setScissorState(const gl::Rectangle &scissor, bool enabled);
+ void setViewportState(const gl::Rectangle &viewport,
+ float zNear,
+ float zFar,
+ gl::PrimitiveMode drawMode,
+ GLenum frontFace,
+ bool ignoreViewport);
+
+ void setShaderConstants();
+
+ void forceSetBlendState();
+ void forceSetRasterState();
+ void forceSetDepthStencilState();
+ void forceSetScissorState();
+ void forceSetViewportState();
+ void forceSetDXUniformsState();
+
+ void updateDepthSizeIfChanged(bool depthStencilInitialized, unsigned int depthSize);
+ void updateStencilSizeIfChanged(bool depthStencilInitialized, unsigned int stencilSize);
+
+ void setRenderTargetBounds(size_t width, size_t height);
+
+ int getRenderTargetWidth() const { return mRenderTargetBounds.width; }
+ int getRenderTargetHeight() const { return mRenderTargetBounds.height; }
+
+ void setAllDirtyBits() { mDirtyBits.set(); }
+ void resetDirtyBits() { mDirtyBits.reset(); }
+
+ private:
+ // Blend state functions
+ void setBlendEnabled(bool enabled);
+ void setBlendColor(const gl::BlendState &blendState, const gl::ColorF &blendColor);
+ void setBlendFuncsEquations(const gl::BlendState &blendState);
+ void setColorMask(const gl::Framebuffer *framebuffer,
+ bool red,
+ bool blue,
+ bool green,
+ bool alpha);
+ void setSampleAlphaToCoverage(bool enabled);
+ void setDither(bool dither);
+ void setSampleMask(unsigned int sampleMask);
+
+ // Current raster state functions
+ void setCullMode(bool cullFace, gl::CullFaceMode cullMode, GLenum frontFace);
+ void setDepthBias(bool polygonOffsetFill,
+ GLfloat polygonOffsetFactor,
+ GLfloat polygonOffsetUnits);
+
+ // Depth stencil state functions
+ void setStencilOpsFront(GLenum stencilFail,
+ GLenum stencilPassDepthFail,
+ GLenum stencilPassDepthPass,
+ bool frontFaceCCW);
+ void setStencilOpsBack(GLenum stencilBackFail,
+ GLenum stencilBackPassDepthFail,
+ GLenum stencilBackPassDepthPass,
+ bool frontFaceCCW);
+ void setStencilBackWriteMask(GLuint stencilBackWriteMask, bool frontFaceCCW);
+ void setDepthFunc(bool depthTest, GLenum depthFunc);
+ void setStencilTestEnabled(bool enabled);
+ void setDepthMask(bool depthMask);
+ void setStencilFuncsFront(GLenum stencilFunc,
+ GLuint stencilMask,
+ GLint stencilRef,
+ bool frontFaceCCW,
+ unsigned int maxStencil);
+ void setStencilFuncsBack(GLenum stencilBackFunc,
+ GLuint stencilBackMask,
+ GLint stencilBackRef,
+ bool frontFaceCCW,
+ unsigned int maxStencil);
+ void setStencilWriteMask(GLuint stencilWriteMask, bool frontFaceCCW);
+
+ void setScissorEnabled(bool scissorEnabled);
+ void setScissorRect(const gl::Rectangle &scissor, bool enabled);
+
+ enum DirtyBitType
+ {
+ // Blend dirty bits
+ DIRTY_BIT_BLEND_ENABLED,
+ DIRTY_BIT_BLEND_COLOR,
+ DIRTY_BIT_BLEND_FUNCS_EQUATIONS,
+ DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE,
+ DIRTY_BIT_COLOR_MASK,
+ DIRTY_BIT_DITHER,
+ DIRTY_BIT_SAMPLE_MASK,
+
+ // Rasterizer dirty bits
+ DIRTY_BIT_CULL_MODE,
+ DIRTY_BIT_DEPTH_BIAS,
+
+ // Depth stencil dirty bits
+ DIRTY_BIT_STENCIL_DEPTH_MASK,
+ DIRTY_BIT_STENCIL_DEPTH_FUNC,
+ DIRTY_BIT_STENCIL_TEST_ENABLED,
+ DIRTY_BIT_STENCIL_FUNCS_FRONT,
+ DIRTY_BIT_STENCIL_FUNCS_BACK,
+ DIRTY_BIT_STENCIL_WRITEMASK_FRONT,
+ DIRTY_BIT_STENCIL_WRITEMASK_BACK,
+ DIRTY_BIT_STENCIL_OPS_FRONT,
+ DIRTY_BIT_STENCIL_OPS_BACK,
+
+ // Scissor dirty bits
+ DIRTY_BIT_SCISSOR_ENABLED,
+ DIRTY_BIT_SCISSOR_RECT,
+
+ // Viewport dirty bits
+ DIRTY_BIT_VIEWPORT,
+
+ DIRTY_BIT_MAX
+ };
+
+ using DirtyBits = angle::BitSet<DIRTY_BIT_MAX>;
+
+ bool mUsingZeroColorMaskWorkaround;
+
+ bool mCurSampleAlphaToCoverage;
+
+ // Currently applied blend state
+ gl::BlendState mCurBlendState;
+ gl::ColorF mCurBlendColor;
+ unsigned int mCurSampleMask;
+ DirtyBits mBlendStateDirtyBits;
+
+ // Currently applied raster state
+ gl::RasterizerState mCurRasterState;
+ unsigned int mCurDepthSize;
+ DirtyBits mRasterizerStateDirtyBits;
+
+ // Currently applied depth stencil state
+ gl::DepthStencilState mCurDepthStencilState;
+ int mCurStencilRef;
+ int mCurStencilBackRef;
+ bool mCurFrontFaceCCW;
+ unsigned int mCurStencilSize;
+ DirtyBits mDepthStencilStateDirtyBits;
+
+ // Currently applied scissor states
+ gl::Rectangle mCurScissorRect;
+ bool mCurScissorEnabled;
+ gl::Extents mRenderTargetBounds;
+ DirtyBits mScissorStateDirtyBits;
+
+ // Currently applied viewport states
+ bool mForceSetViewport;
+ gl::Rectangle mCurViewport;
+ float mCurNear;
+ float mCurFar;
+ float mCurDepthFront;
+ bool mCurIgnoreViewport;
+
+ dx_VertexConstants9 mVertexConstants;
+ dx_PixelConstants9 mPixelConstants;
+ bool mDxUniformsDirty;
+
+ // FIXME: Unsupported by D3D9
+ static const D3DRENDERSTATETYPE D3DRS_CCW_STENCILREF = D3DRS_STENCILREF;
+ static const D3DRENDERSTATETYPE D3DRS_CCW_STENCILMASK = D3DRS_STENCILMASK;
+ static const D3DRENDERSTATETYPE D3DRS_CCW_STENCILWRITEMASK = D3DRS_STENCILWRITEMASK;
+
+ Renderer9 *mRenderer9;
+ DirtyBits mDirtyBits;
+};
+
+} // namespace rx
+#endif // LIBANGLE_RENDERER_D3D9_STATEMANAGER9_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp
new file mode 100644
index 0000000000..c8abac7a57
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp
@@ -0,0 +1,472 @@
+//
+// Copyright 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.
+//
+
+// SwapChain9.cpp: Implements a back-end specific class for the D3D9 swap chain.
+
+#include "libANGLE/renderer/d3d/d3d9/SwapChain9.h"
+
+#include "libANGLE/features.h"
+#include "libANGLE/renderer/d3d/d3d9/NativeWindow9.h"
+#include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
+#include "libANGLE/renderer/d3d/d3d9/formatutils9.h"
+#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h"
+
+namespace rx
+{
+
+SwapChain9::SwapChain9(Renderer9 *renderer,
+ NativeWindow9 *nativeWindow,
+ HANDLE shareHandle,
+ IUnknown *d3dTexture,
+ GLenum backBufferFormat,
+ GLenum depthBufferFormat,
+ EGLint orientation)
+ : SwapChainD3D(shareHandle, d3dTexture, backBufferFormat, depthBufferFormat),
+ mRenderer(renderer),
+ mWidth(-1),
+ mHeight(-1),
+ mSwapInterval(-1),
+ mNativeWindow(nativeWindow),
+ mSwapChain(nullptr),
+ mBackBuffer(nullptr),
+ mRenderTarget(nullptr),
+ mDepthStencil(nullptr),
+ mOffscreenTexture(nullptr),
+ mColorRenderTarget(this, false),
+ mDepthStencilRenderTarget(this, true)
+{
+ ASSERT(orientation == 0);
+}
+
+SwapChain9::~SwapChain9()
+{
+ release();
+}
+
+void SwapChain9::release()
+{
+ SafeRelease(mSwapChain);
+ SafeRelease(mBackBuffer);
+ SafeRelease(mDepthStencil);
+ SafeRelease(mRenderTarget);
+ SafeRelease(mOffscreenTexture);
+
+ if (mNativeWindow->getNativeWindow())
+ {
+ mShareHandle = nullptr;
+ }
+}
+
+static DWORD convertInterval(EGLint interval)
+{
+#if ANGLE_VSYNC == ANGLE_DISABLED
+ return D3DPRESENT_INTERVAL_IMMEDIATE;
+#else
+ switch (interval)
+ {
+ case 0:
+ return D3DPRESENT_INTERVAL_IMMEDIATE;
+ case 1:
+ return D3DPRESENT_INTERVAL_ONE;
+ case 2:
+ return D3DPRESENT_INTERVAL_TWO;
+ case 3:
+ return D3DPRESENT_INTERVAL_THREE;
+ case 4:
+ return D3DPRESENT_INTERVAL_FOUR;
+ default:
+ UNREACHABLE();
+ }
+
+ return D3DPRESENT_INTERVAL_DEFAULT;
+#endif
+}
+
+EGLint SwapChain9::resize(DisplayD3D *displayD3D, int backbufferWidth, int backbufferHeight)
+{
+ // D3D9 does not support resizing swap chains without recreating them
+ return reset(displayD3D, backbufferWidth, backbufferHeight, mSwapInterval);
+}
+
+EGLint SwapChain9::reset(DisplayD3D *displayD3D,
+ int backbufferWidth,
+ int backbufferHeight,
+ EGLint swapInterval)
+{
+ IDirect3DDevice9 *device = mRenderer->getDevice();
+
+ if (device == nullptr)
+ {
+ return EGL_BAD_ACCESS;
+ }
+
+ // Evict all non-render target textures to system memory and release all resources
+ // before reallocating them to free up as much video memory as possible.
+ device->EvictManagedResources();
+
+ HRESULT result;
+
+ // Release specific resources to free up memory for the new render target, while the
+ // old render target still exists for the purpose of preserving its contents.
+ SafeRelease(mSwapChain);
+ SafeRelease(mBackBuffer);
+ SafeRelease(mOffscreenTexture);
+ SafeRelease(mDepthStencil);
+
+ const d3d9::TextureFormat &backBufferd3dFormatInfo =
+ d3d9::GetTextureFormatInfo(mOffscreenRenderTargetFormat);
+ if (mD3DTexture != nullptr)
+ {
+ result = mD3DTexture->QueryInterface(&mOffscreenTexture);
+ ASSERT(SUCCEEDED(result));
+ }
+ else
+ {
+ HANDLE *pShareHandle = nullptr;
+ if (!mNativeWindow->getNativeWindow() && mRenderer->getShareHandleSupport())
+ {
+ pShareHandle = &mShareHandle;
+ }
+
+ result = device->CreateTexture(backbufferWidth, backbufferHeight, 1, D3DUSAGE_RENDERTARGET,
+ backBufferd3dFormatInfo.texFormat, D3DPOOL_DEFAULT,
+ &mOffscreenTexture, pShareHandle);
+ if (FAILED(result))
+ {
+ ERR() << "Could not create offscreen texture, " << gl::FmtHR(result);
+ release();
+
+ if (d3d9::isDeviceLostError(result))
+ {
+ return EGL_CONTEXT_LOST;
+ }
+ else
+ {
+ return EGL_BAD_ALLOC;
+ }
+ }
+ }
+
+ IDirect3DSurface9 *oldRenderTarget = mRenderTarget;
+
+ result = mOffscreenTexture->GetSurfaceLevel(0, &mRenderTarget);
+ ASSERT(SUCCEEDED(result));
+
+ if (oldRenderTarget)
+ {
+ RECT rect = {0, 0, mWidth, mHeight};
+
+ if (rect.right > static_cast<LONG>(backbufferWidth))
+ {
+ rect.right = backbufferWidth;
+ }
+
+ if (rect.bottom > static_cast<LONG>(backbufferHeight))
+ {
+ rect.bottom = backbufferHeight;
+ }
+
+ mRenderer->endScene();
+
+ result = device->StretchRect(oldRenderTarget, &rect, mRenderTarget, &rect, D3DTEXF_NONE);
+ ASSERT(SUCCEEDED(result));
+
+ SafeRelease(oldRenderTarget);
+ }
+
+ const d3d9::TextureFormat &depthBufferd3dFormatInfo =
+ d3d9::GetTextureFormatInfo(mDepthBufferFormat);
+
+ // Don't create a swapchain for NULLREF devices
+ D3DDEVTYPE deviceType = mRenderer->getD3D9DeviceType();
+ EGLNativeWindowType window = mNativeWindow->getNativeWindow();
+ if (window && deviceType != D3DDEVTYPE_NULLREF)
+ {
+ D3DPRESENT_PARAMETERS presentParameters = {};
+ presentParameters.AutoDepthStencilFormat = depthBufferd3dFormatInfo.renderFormat;
+ presentParameters.BackBufferCount = 1;
+ presentParameters.BackBufferFormat = backBufferd3dFormatInfo.renderFormat;
+ presentParameters.EnableAutoDepthStencil = FALSE;
+ presentParameters.Flags = 0;
+ presentParameters.hDeviceWindow = window;
+ presentParameters.MultiSampleQuality = 0; // FIXME: Unimplemented
+ presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE; // FIXME: Unimplemented
+ presentParameters.PresentationInterval = convertInterval(swapInterval);
+ presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
+ presentParameters.Windowed = TRUE;
+ presentParameters.BackBufferWidth = backbufferWidth;
+ presentParameters.BackBufferHeight = backbufferHeight;
+
+ // http://crbug.com/140239
+ // http://crbug.com/143434
+ //
+ // Some AMD/Intel switchable systems / drivers appear to round swap chain surfaces to a
+ // multiple of 64 pixels in width when using the integrated Intel. This rounds the width up
+ // rather than down.
+ //
+ // Some non-switchable AMD GPUs / drivers do not respect the source rectangle to Present.
+ // Therefore, when the vendor ID is not Intel, the back buffer width must be exactly the
+ // same width as the window or horizontal scaling will occur.
+ if (IsIntel(mRenderer->getVendorId()))
+ {
+ presentParameters.BackBufferWidth = (presentParameters.BackBufferWidth + 63) / 64 * 64;
+ }
+
+ result = device->CreateAdditionalSwapChain(&presentParameters, &mSwapChain);
+
+ if (FAILED(result))
+ {
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY ||
+ result == D3DERR_INVALIDCALL || result == D3DERR_DEVICELOST);
+
+ ERR() << "Could not create additional swap chains or offscreen surfaces, "
+ << gl::FmtHR(result);
+ release();
+
+ if (d3d9::isDeviceLostError(result))
+ {
+ return EGL_CONTEXT_LOST;
+ }
+ else
+ {
+ return EGL_BAD_ALLOC;
+ }
+ }
+
+ result = mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackBuffer);
+ ASSERT(SUCCEEDED(result));
+ InvalidateRect(window, nullptr, FALSE);
+ }
+
+ if (mDepthBufferFormat != GL_NONE)
+ {
+ result = device->CreateDepthStencilSurface(
+ backbufferWidth, backbufferHeight, depthBufferd3dFormatInfo.renderFormat,
+ D3DMULTISAMPLE_NONE, 0, FALSE, &mDepthStencil, nullptr);
+
+ if (FAILED(result))
+ {
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY ||
+ result == D3DERR_INVALIDCALL);
+
+ ERR() << "Could not create depthstencil surface for new swap chain, "
+ << gl::FmtHR(result);
+ release();
+
+ if (d3d9::isDeviceLostError(result))
+ {
+ return EGL_CONTEXT_LOST;
+ }
+ else
+ {
+ return EGL_BAD_ALLOC;
+ }
+ }
+ }
+
+ mWidth = backbufferWidth;
+ mHeight = backbufferHeight;
+ mSwapInterval = swapInterval;
+
+ return EGL_SUCCESS;
+}
+
+// parameters should be validated/clamped by caller
+EGLint SwapChain9::swapRect(DisplayD3D *displayD3D, EGLint x, EGLint y, EGLint width, EGLint height)
+{
+ if (!mSwapChain)
+ {
+ return EGL_SUCCESS;
+ }
+
+ IDirect3DDevice9 *device = mRenderer->getDevice();
+
+ // Disable all pipeline operations
+ device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
+ device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
+ device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
+ device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+ device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
+ device->SetRenderState(D3DRS_STENCILENABLE, FALSE);
+ device->SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
+ device->SetRenderState(D3DRS_COLORWRITEENABLE,
+ D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_BLUE |
+ D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED);
+ device->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE);
+ device->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
+ device->SetPixelShader(nullptr);
+ device->SetVertexShader(nullptr);
+
+ device->SetRenderTarget(0, mBackBuffer);
+ device->SetDepthStencilSurface(nullptr);
+
+ device->SetTexture(0, mOffscreenTexture);
+ device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
+ device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
+ device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
+ device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
+ device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
+ device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
+ device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
+ device->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1);
+
+ for (UINT streamIndex = 0; streamIndex < gl::MAX_VERTEX_ATTRIBS; streamIndex++)
+ {
+ device->SetStreamSourceFreq(streamIndex, 1);
+ }
+
+ D3DVIEWPORT9 viewport = {0, 0, static_cast<DWORD>(mWidth), static_cast<DWORD>(mHeight),
+ 0.0f, 1.0f};
+ device->SetViewport(&viewport);
+
+ float x1 = x - 0.5f;
+ float y1 = (mHeight - y - height) - 0.5f;
+ float x2 = (x + width) - 0.5f;
+ float y2 = (mHeight - y) - 0.5f;
+
+ float u1 = x / float(mWidth);
+ float v1 = y / float(mHeight);
+ float u2 = (x + width) / float(mWidth);
+ float v2 = (y + height) / float(mHeight);
+
+ float quad[4][6] = {{x1, y1, 0.0f, 1.0f, u1, v2},
+ {x2, y1, 0.0f, 1.0f, u2, v2},
+ {x2, y2, 0.0f, 1.0f, u2, v1},
+ {x1, y2, 0.0f, 1.0f, u1, v1}}; // x, y, z, rhw, u, v
+
+ mRenderer->startScene();
+ device->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, quad, 6 * sizeof(float));
+ mRenderer->endScene();
+
+ device->SetTexture(0, nullptr);
+
+ RECT rect = {static_cast<LONG>(x), static_cast<LONG>(mHeight - y - height),
+ static_cast<LONG>(x + width), static_cast<LONG>(mHeight - y)};
+
+ HRESULT result = mSwapChain->Present(&rect, &rect, nullptr, nullptr, 0);
+
+ mRenderer->markAllStateDirty();
+
+ if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY ||
+ result == D3DERR_DRIVERINTERNALERROR)
+ {
+ return EGL_BAD_ALLOC;
+ }
+
+ // 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 == static_cast<HRESULT>(0x88760873) || result == static_cast<HRESULT>(0x88760872))
+ {
+ return EGL_BAD_MATCH;
+ }
+
+ // http://crbug.com/313210
+ // If our swap failed, trigger a device lost event. Resetting will work around an AMD-specific
+ // device removed bug with lost contexts when reinstalling drivers.
+ if (FAILED(result))
+ {
+ mRenderer->notifyDeviceLost();
+ return EGL_CONTEXT_LOST;
+ }
+
+ return EGL_SUCCESS;
+}
+
+// Increments refcount on surface.
+// caller must Release() the returned surface
+// TODO: remove the AddRef to match SwapChain11
+IDirect3DSurface9 *SwapChain9::getRenderTarget()
+{
+ if (mRenderTarget)
+ {
+ mRenderTarget->AddRef();
+ }
+
+ return mRenderTarget;
+}
+
+// Increments refcount on surface.
+// caller must Release() the returned surface
+// TODO: remove the AddRef to match SwapChain11
+IDirect3DSurface9 *SwapChain9::getDepthStencil()
+{
+ if (mDepthStencil)
+ {
+ mDepthStencil->AddRef();
+ }
+
+ return mDepthStencil;
+}
+
+// Increments refcount on texture.
+// caller must Release() the returned texture
+// TODO: remove the AddRef to match SwapChain11
+IDirect3DTexture9 *SwapChain9::getOffscreenTexture()
+{
+ if (mOffscreenTexture)
+ {
+ mOffscreenTexture->AddRef();
+ }
+
+ return mOffscreenTexture;
+}
+
+void *SwapChain9::getKeyedMutex()
+{
+ UNREACHABLE();
+ return nullptr;
+}
+
+egl::Error SwapChain9::getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc)
+{
+ UNREACHABLE();
+ return egl::EglBadSurface();
+}
+
+void SwapChain9::recreate()
+{
+ if (!mSwapChain)
+ {
+ return;
+ }
+
+ IDirect3DDevice9 *device = mRenderer->getDevice();
+ if (device == nullptr)
+ {
+ return;
+ }
+
+ D3DPRESENT_PARAMETERS presentParameters;
+ HRESULT result = mSwapChain->GetPresentParameters(&presentParameters);
+ ASSERT(SUCCEEDED(result));
+
+ IDirect3DSwapChain9 *newSwapChain = nullptr;
+ result = device->CreateAdditionalSwapChain(&presentParameters, &newSwapChain);
+ if (FAILED(result))
+ {
+ return;
+ }
+
+ SafeRelease(mSwapChain);
+ mSwapChain = newSwapChain;
+
+ SafeRelease(mBackBuffer);
+ result = mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackBuffer);
+ ASSERT(SUCCEEDED(result));
+}
+
+RenderTargetD3D *SwapChain9::getColorRenderTarget()
+{
+ return &mColorRenderTarget;
+}
+
+RenderTargetD3D *SwapChain9::getDepthStencilRenderTarget()
+{
+ return &mDepthStencilRenderTarget;
+}
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/SwapChain9.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/SwapChain9.h
new file mode 100644
index 0000000000..2b3176967d
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/SwapChain9.h
@@ -0,0 +1,80 @@
+//
+// Copyright 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.
+//
+
+// SwapChain9.h: Defines a back-end specific class for the D3D9 swap chain.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D9_SWAPCHAIN9_H_
+#define LIBANGLE_RENDERER_D3D_D3D9_SWAPCHAIN9_H_
+
+#include "common/angleutils.h"
+#include "libANGLE/renderer/d3d/SwapChainD3D.h"
+#include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h"
+
+namespace rx
+{
+class NativeWindow9;
+class Renderer9;
+
+class SwapChain9 : public SwapChainD3D
+{
+ public:
+ SwapChain9(Renderer9 *renderer,
+ NativeWindow9 *nativeWindow,
+ HANDLE shareHandle,
+ IUnknown *d3dTexture,
+ GLenum backBufferFormat,
+ GLenum depthBufferFormat,
+ EGLint orientation);
+ ~SwapChain9() override;
+
+ EGLint resize(DisplayD3D *displayD3D, EGLint backbufferWidth, EGLint backbufferHeight) override;
+ EGLint reset(DisplayD3D *displayD3D,
+ EGLint backbufferWidth,
+ EGLint backbufferHeight,
+ EGLint swapInterval) override;
+ EGLint swapRect(DisplayD3D *displayD3D,
+ EGLint x,
+ EGLint y,
+ EGLint width,
+ EGLint height) override;
+ void recreate() override;
+
+ RenderTargetD3D *getColorRenderTarget() override;
+ RenderTargetD3D *getDepthStencilRenderTarget() override;
+
+ virtual IDirect3DSurface9 *getRenderTarget();
+ virtual IDirect3DSurface9 *getDepthStencil();
+ virtual IDirect3DTexture9 *getOffscreenTexture();
+
+ EGLint getWidth() const { return mWidth; }
+ EGLint getHeight() const { return mHeight; }
+
+ void *getKeyedMutex() override;
+
+ egl::Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) override;
+
+ private:
+ void release();
+
+ Renderer9 *mRenderer;
+ EGLint mWidth;
+ EGLint mHeight;
+ EGLint mSwapInterval;
+
+ NativeWindow9 *mNativeWindow;
+
+ IDirect3DSwapChain9 *mSwapChain;
+ IDirect3DSurface9 *mBackBuffer;
+ IDirect3DSurface9 *mRenderTarget;
+ IDirect3DSurface9 *mDepthStencil;
+ IDirect3DTexture9 *mOffscreenTexture;
+
+ SurfaceRenderTarget9 mColorRenderTarget;
+ SurfaceRenderTarget9 mDepthStencilRenderTarget;
+};
+
+} // namespace rx
+#endif // LIBANGLE_RENDERER_D3D_D3D9_SWAPCHAIN9_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp
new file mode 100644
index 0000000000..b2fea07fd5
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp
@@ -0,0 +1,575 @@
+//
+// Copyright 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.
+//
+
+// TextureStorage9.cpp: Implements the abstract rx::TextureStorage9 class and its concrete derived
+// classes TextureStorage9_2D and TextureStorage9_Cube, which act as the interface to the
+// D3D9 texture.
+
+#include "libANGLE/renderer/d3d/d3d9/TextureStorage9.h"
+
+#include "common/utilities.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Texture.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/d3d/EGLImageD3D.h"
+#include "libANGLE/renderer/d3d/TextureD3D.h"
+#include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h"
+#include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
+#include "libANGLE/renderer/d3d/d3d9/SwapChain9.h"
+#include "libANGLE/renderer/d3d/d3d9/formatutils9.h"
+#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h"
+
+namespace rx
+{
+TextureStorage9::TextureStorage9(Renderer9 *renderer, DWORD usage, const std::string &label)
+ : TextureStorage(label),
+ mTopLevel(0),
+ mMipLevels(0),
+ mTextureWidth(0),
+ mTextureHeight(0),
+ mInternalFormat(GL_NONE),
+ mTextureFormat(D3DFMT_UNKNOWN),
+ mRenderer(renderer),
+ mD3DUsage(usage),
+ mD3DPool(mRenderer->getTexturePool(usage))
+{}
+
+TextureStorage9::~TextureStorage9() {}
+
+DWORD TextureStorage9::GetTextureUsage(GLenum internalformat, bool renderTarget)
+{
+ DWORD d3dusage = 0;
+
+ const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
+ const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalformat);
+ if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0)
+ {
+ d3dusage |= D3DUSAGE_DEPTHSTENCIL;
+ }
+ else if (renderTarget && (d3dFormatInfo.renderFormat != D3DFMT_UNKNOWN))
+ {
+ d3dusage |= D3DUSAGE_RENDERTARGET;
+ }
+
+ return d3dusage;
+}
+
+bool TextureStorage9::isRenderTarget() const
+{
+ return (mD3DUsage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL)) != 0;
+}
+
+bool TextureStorage9::isManaged() const
+{
+ return (mD3DPool == D3DPOOL_MANAGED);
+}
+
+bool TextureStorage9::supportsNativeMipmapFunction() const
+{
+ return false;
+}
+
+D3DPOOL TextureStorage9::getPool() const
+{
+ return mD3DPool;
+}
+
+DWORD TextureStorage9::getUsage() const
+{
+ return mD3DUsage;
+}
+
+int TextureStorage9::getTopLevel() const
+{
+ return mTopLevel;
+}
+
+int TextureStorage9::getLevelCount() const
+{
+ return static_cast<int>(mMipLevels) - mTopLevel;
+}
+
+angle::Result TextureStorage9::setData(const gl::Context *context,
+ const gl::ImageIndex &index,
+ ImageD3D *image,
+ const gl::Box *destBox,
+ GLenum type,
+ const gl::PixelUnpackState &unpack,
+ const uint8_t *pixelData)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context9>(context));
+ return angle::Result::Stop;
+}
+
+TextureStorage9_2D::TextureStorage9_2D(Renderer9 *renderer,
+ SwapChain9 *swapchain,
+ const std::string &label)
+ : TextureStorage9(renderer, D3DUSAGE_RENDERTARGET, label)
+{
+ IDirect3DTexture9 *surfaceTexture = swapchain->getOffscreenTexture();
+ mTexture = surfaceTexture;
+ mMipLevels = surfaceTexture->GetLevelCount();
+
+ mInternalFormat = swapchain->getRenderTargetInternalFormat();
+
+ D3DSURFACE_DESC surfaceDesc;
+ surfaceTexture->GetLevelDesc(0, &surfaceDesc);
+ mTextureWidth = surfaceDesc.Width;
+ mTextureHeight = surfaceDesc.Height;
+ mTextureFormat = surfaceDesc.Format;
+
+ mRenderTargets.resize(mMipLevels, nullptr);
+}
+
+TextureStorage9_2D::TextureStorage9_2D(Renderer9 *renderer,
+ GLenum internalformat,
+ bool renderTarget,
+ GLsizei width,
+ GLsizei height,
+ int levels,
+ const std::string &label)
+ : TextureStorage9(renderer, GetTextureUsage(internalformat, renderTarget), label)
+{
+ mTexture = nullptr;
+
+ mInternalFormat = internalformat;
+
+ const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalformat);
+ mTextureFormat = d3dFormatInfo.texFormat;
+
+ d3d9::MakeValidSize(false, d3dFormatInfo.texFormat, &width, &height, &mTopLevel);
+ mTextureWidth = width;
+ mTextureHeight = height;
+ mMipLevels = mTopLevel + levels;
+
+ mRenderTargets.resize(levels, nullptr);
+}
+
+TextureStorage9_2D::~TextureStorage9_2D()
+{
+ SafeRelease(mTexture);
+ for (RenderTargetD3D *renderTarget : mRenderTargets)
+ {
+ SafeDelete(renderTarget);
+ }
+}
+
+// Increments refcount on surface.
+// caller must Release() the returned surface
+angle::Result TextureStorage9_2D::getSurfaceLevel(const gl::Context *context,
+ gl::TextureTarget target,
+ int level,
+ bool dirty,
+ IDirect3DSurface9 **outSurface)
+{
+ ASSERT(target == gl::TextureTarget::_2D);
+
+ IDirect3DBaseTexture9 *baseTexture = nullptr;
+ ANGLE_TRY(getBaseTexture(context, &baseTexture));
+
+ IDirect3DTexture9 *texture = static_cast<IDirect3DTexture9 *>(baseTexture);
+
+ HRESULT result = texture->GetSurfaceLevel(level + mTopLevel, outSurface);
+ ANGLE_TRY_HR(GetImplAs<Context9>(context), result, "Failed to get the surface from a texture");
+
+ // With managed textures the driver needs to be informed of updates to the lower mipmap levels
+ if (level + mTopLevel != 0 && isManaged() && dirty)
+ {
+ texture->AddDirtyRect(nullptr);
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage9_2D::findRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) const
+{
+ ASSERT(index.getLevelIndex() < getLevelCount());
+
+ ASSERT(outRT);
+ *outRT = mRenderTargets[index.getLevelIndex()];
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage9_2D::getRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT)
+{
+ ASSERT(index.getLevelIndex() < getLevelCount());
+
+ if (!mRenderTargets[index.getLevelIndex()] && isRenderTarget())
+ {
+ IDirect3DBaseTexture9 *baseTexture = nullptr;
+ ANGLE_TRY(getBaseTexture(context, &baseTexture));
+
+ IDirect3DSurface9 *surface = nullptr;
+ ANGLE_TRY(getSurfaceLevel(context, gl::TextureTarget::_2D, index.getLevelIndex(), false,
+ &surface));
+
+ size_t textureMipLevel = mTopLevel + index.getLevelIndex();
+ size_t mipWidth = std::max<size_t>(mTextureWidth >> textureMipLevel, 1u);
+ size_t mipHeight = std::max<size_t>(mTextureHeight >> textureMipLevel, 1u);
+
+ baseTexture->AddRef();
+ mRenderTargets[index.getLevelIndex()] = new TextureRenderTarget9(
+ baseTexture, textureMipLevel, surface, mInternalFormat, static_cast<GLsizei>(mipWidth),
+ static_cast<GLsizei>(mipHeight), 1, 0);
+ }
+
+ ASSERT(outRT);
+ *outRT = mRenderTargets[index.getLevelIndex()];
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage9_2D::generateMipmap(const gl::Context *context,
+ const gl::ImageIndex &sourceIndex,
+ const gl::ImageIndex &destIndex)
+{
+ angle::ComPtr<IDirect3DSurface9> upper = nullptr;
+ ANGLE_TRY(getSurfaceLevel(context, gl::TextureTarget::_2D, sourceIndex.getLevelIndex(), false,
+ &upper));
+
+ angle::ComPtr<IDirect3DSurface9> lower = nullptr;
+ ANGLE_TRY(
+ getSurfaceLevel(context, gl::TextureTarget::_2D, destIndex.getLevelIndex(), true, &lower));
+
+ ASSERT(upper && lower);
+ return mRenderer->boxFilter(GetImplAs<Context9>(context), upper.Get(), lower.Get());
+}
+
+angle::Result TextureStorage9_2D::getBaseTexture(const gl::Context *context,
+ IDirect3DBaseTexture9 **outTexture)
+{
+ // if the width or height is not positive this should be treated as an incomplete texture
+ // we handle that here by skipping the d3d texture creation
+ if (mTexture == nullptr && mTextureWidth > 0 && mTextureHeight > 0)
+ {
+ ASSERT(mMipLevels > 0);
+
+ IDirect3DDevice9 *device = mRenderer->getDevice();
+ HRESULT result = device->CreateTexture(static_cast<unsigned int>(mTextureWidth),
+ static_cast<unsigned int>(mTextureHeight),
+ static_cast<unsigned int>(mMipLevels), getUsage(),
+ mTextureFormat, getPool(), &mTexture, nullptr);
+ ANGLE_TRY_HR(GetImplAs<Context9>(context), result, "Failed to create 2D storage texture");
+ }
+
+ *outTexture = mTexture;
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage9_2D::copyToStorage(const gl::Context *context,
+ TextureStorage *destStorage)
+{
+ ASSERT(destStorage);
+
+ TextureStorage9_2D *dest9 = GetAs<TextureStorage9_2D>(destStorage);
+
+ int levels = getLevelCount();
+ for (int i = 0; i < levels; ++i)
+ {
+ angle::ComPtr<IDirect3DSurface9> srcSurf = nullptr;
+ ANGLE_TRY(getSurfaceLevel(context, gl::TextureTarget::_2D, i, false, &srcSurf));
+
+ angle::ComPtr<IDirect3DSurface9> dstSurf = nullptr;
+ ANGLE_TRY(dest9->getSurfaceLevel(context, gl::TextureTarget::_2D, i, true, &dstSurf));
+
+ ANGLE_TRY(
+ mRenderer->copyToRenderTarget(context, dstSurf.Get(), srcSurf.Get(), isManaged()));
+ }
+
+ return angle::Result::Continue;
+}
+
+TextureStorage9_EGLImage::TextureStorage9_EGLImage(Renderer9 *renderer,
+ EGLImageD3D *image,
+ RenderTarget9 *renderTarget9,
+ const std::string &label)
+ : TextureStorage9(renderer, D3DUSAGE_RENDERTARGET, label), mImage(image)
+{
+
+ mInternalFormat = renderTarget9->getInternalFormat();
+ mTextureFormat = renderTarget9->getD3DFormat();
+ mTextureWidth = renderTarget9->getWidth();
+ mTextureHeight = renderTarget9->getHeight();
+ mTopLevel = static_cast<int>(renderTarget9->getTextureLevel());
+ mMipLevels = mTopLevel + 1;
+}
+
+TextureStorage9_EGLImage::~TextureStorage9_EGLImage() {}
+
+angle::Result TextureStorage9_EGLImage::getSurfaceLevel(const gl::Context *context,
+ gl::TextureTarget target,
+ int level,
+ bool,
+ IDirect3DSurface9 **outSurface)
+{
+ ASSERT(target == gl::TextureTarget::_2D);
+ ASSERT(level == 0);
+
+ RenderTargetD3D *renderTargetD3D = nullptr;
+ ANGLE_TRY(mImage->getRenderTarget(context, &renderTargetD3D));
+
+ RenderTarget9 *renderTarget9 = GetAs<RenderTarget9>(renderTargetD3D);
+
+ *outSurface = renderTarget9->getSurface();
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage9_EGLImage::findRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) const
+{
+ // Since the render target of a EGL image will be updated when orphaning, trying to find a cache
+ // of it can be rarely useful.
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context9>(context));
+ return angle::Result::Stop;
+}
+
+angle::Result TextureStorage9_EGLImage::getRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT)
+{
+ ASSERT(!index.hasLayer());
+ ASSERT(index.getLevelIndex() == 0);
+ ASSERT(samples == 0);
+
+ return mImage->getRenderTarget(context, outRT);
+}
+
+angle::Result TextureStorage9_EGLImage::getBaseTexture(const gl::Context *context,
+ IDirect3DBaseTexture9 **outTexture)
+{
+ RenderTargetD3D *renderTargetD3D = nullptr;
+ ANGLE_TRY(mImage->getRenderTarget(context, &renderTargetD3D));
+
+ RenderTarget9 *renderTarget9 = GetAs<RenderTarget9>(renderTargetD3D);
+ *outTexture = renderTarget9->getTexture();
+ ASSERT(*outTexture != nullptr);
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage9_EGLImage::generateMipmap(const gl::Context *context,
+ const gl::ImageIndex &,
+ const gl::ImageIndex &)
+{
+ ANGLE_HR_UNREACHABLE(GetImplAs<Context9>(context));
+ return angle::Result::Stop;
+}
+
+angle::Result TextureStorage9_EGLImage::copyToStorage(const gl::Context *context,
+ TextureStorage *destStorage)
+{
+ ASSERT(destStorage);
+ ASSERT(getLevelCount() == 1);
+
+ TextureStorage9 *dest9 = GetAs<TextureStorage9>(destStorage);
+
+ IDirect3DBaseTexture9 *destBaseTexture9 = nullptr;
+ ANGLE_TRY(dest9->getBaseTexture(context, &destBaseTexture9));
+
+ IDirect3DTexture9 *destTexture9 = static_cast<IDirect3DTexture9 *>(destBaseTexture9);
+
+ angle::ComPtr<IDirect3DSurface9> destSurface = nullptr;
+ HRESULT result = destTexture9->GetSurfaceLevel(destStorage->getTopLevel(), &destSurface);
+ ANGLE_TRY_HR(GetImplAs<Context9>(context), result, "Failed to get the surface from a texture");
+
+ RenderTargetD3D *sourceRenderTarget = nullptr;
+ ANGLE_TRY(mImage->getRenderTarget(context, &sourceRenderTarget));
+
+ RenderTarget9 *sourceRenderTarget9 = GetAs<RenderTarget9>(sourceRenderTarget);
+ ANGLE_TRY(mRenderer->copyToRenderTarget(context, destSurface.Get(),
+ sourceRenderTarget9->getSurface(), isManaged()));
+
+ if (destStorage->getTopLevel() != 0)
+ {
+ destTexture9->AddDirtyRect(nullptr);
+ }
+
+ return angle::Result::Continue;
+}
+
+TextureStorage9_Cube::TextureStorage9_Cube(Renderer9 *renderer,
+ GLenum internalformat,
+ bool renderTarget,
+ int size,
+ int levels,
+ bool hintLevelZeroOnly,
+ const std::string &label)
+ : TextureStorage9(renderer, GetTextureUsage(internalformat, renderTarget), label)
+{
+ mTexture = nullptr;
+ for (size_t i = 0; i < gl::kCubeFaceCount; ++i)
+ {
+ mRenderTarget[i] = nullptr;
+ }
+
+ mInternalFormat = internalformat;
+
+ const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalformat);
+ mTextureFormat = d3dFormatInfo.texFormat;
+
+ int height = size;
+ d3d9::MakeValidSize(false, d3dFormatInfo.texFormat, &size, &height, &mTopLevel);
+ mTextureWidth = size;
+ mTextureHeight = size;
+ mMipLevels = mTopLevel + levels;
+}
+
+TextureStorage9_Cube::~TextureStorage9_Cube()
+{
+ SafeRelease(mTexture);
+
+ for (size_t i = 0; i < gl::kCubeFaceCount; ++i)
+ {
+ SafeDelete(mRenderTarget[i]);
+ }
+}
+
+// Increments refcount on surface.
+// caller must Release() the returned surface
+angle::Result TextureStorage9_Cube::getSurfaceLevel(const gl::Context *context,
+ gl::TextureTarget target,
+ int level,
+ bool dirty,
+ IDirect3DSurface9 **outSurface)
+{
+ IDirect3DBaseTexture9 *baseTexture = nullptr;
+ ANGLE_TRY(getBaseTexture(context, &baseTexture));
+
+ IDirect3DCubeTexture9 *texture = static_cast<IDirect3DCubeTexture9 *>(baseTexture);
+
+ D3DCUBEMAP_FACES face = gl_d3d9::ConvertCubeFace(target);
+ HRESULT result = texture->GetCubeMapSurface(face, level, outSurface);
+ ANGLE_TRY_HR(GetImplAs<Context9>(context), result, "Failed to get the surface from a texture");
+
+ // With managed textures the driver needs to be informed of updates to the lower mipmap levels
+ if (level != 0 && isManaged() && dirty)
+ {
+ texture->AddDirtyRect(face, nullptr);
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage9_Cube::findRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) const
+{
+ ASSERT(outRT);
+ ASSERT(index.getLevelIndex() == 0);
+ ASSERT(samples == 0);
+
+ ASSERT(index.getType() == gl::TextureType::CubeMap &&
+ gl::IsCubeMapFaceTarget(index.getTarget()));
+ const size_t renderTargetIndex = index.cubeMapFaceIndex();
+
+ *outRT = mRenderTarget[renderTargetIndex];
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage9_Cube::getRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT)
+{
+ ASSERT(outRT);
+ ASSERT(index.getLevelIndex() == 0);
+ ASSERT(samples == 0);
+
+ ASSERT(index.getType() == gl::TextureType::CubeMap &&
+ gl::IsCubeMapFaceTarget(index.getTarget()));
+ const size_t renderTargetIndex = index.cubeMapFaceIndex();
+
+ if (mRenderTarget[renderTargetIndex] == nullptr && isRenderTarget())
+ {
+ IDirect3DBaseTexture9 *baseTexture = nullptr;
+ ANGLE_TRY(getBaseTexture(context, &baseTexture));
+
+ IDirect3DSurface9 *surface = nullptr;
+ ANGLE_TRY(getSurfaceLevel(context, index.getTarget(), mTopLevel + index.getLevelIndex(),
+ false, &surface));
+
+ baseTexture->AddRef();
+ mRenderTarget[renderTargetIndex] = new TextureRenderTarget9(
+ baseTexture, mTopLevel + index.getLevelIndex(), surface, mInternalFormat,
+ static_cast<GLsizei>(mTextureWidth), static_cast<GLsizei>(mTextureHeight), 1, 0);
+ }
+
+ *outRT = mRenderTarget[renderTargetIndex];
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage9_Cube::generateMipmap(const gl::Context *context,
+ const gl::ImageIndex &sourceIndex,
+ const gl::ImageIndex &destIndex)
+{
+ angle::ComPtr<IDirect3DSurface9> upper = nullptr;
+ ANGLE_TRY(getSurfaceLevel(context, sourceIndex.getTarget(), sourceIndex.getLevelIndex(), false,
+ &upper));
+
+ angle::ComPtr<IDirect3DSurface9> lower = nullptr;
+ ANGLE_TRY(
+ getSurfaceLevel(context, destIndex.getTarget(), destIndex.getLevelIndex(), true, &lower));
+
+ ASSERT(upper && lower);
+ return mRenderer->boxFilter(GetImplAs<Context9>(context), upper.Get(), lower.Get());
+}
+
+angle::Result TextureStorage9_Cube::getBaseTexture(const gl::Context *context,
+ IDirect3DBaseTexture9 **outTexture)
+{
+ // if the size is not positive this should be treated as an incomplete texture
+ // we handle that here by skipping the d3d texture creation
+ if (mTexture == nullptr && mTextureWidth > 0 && mTextureHeight > 0)
+ {
+ ASSERT(mMipLevels > 0);
+ ASSERT(mTextureWidth == mTextureHeight);
+
+ IDirect3DDevice9 *device = mRenderer->getDevice();
+ HRESULT result = device->CreateCubeTexture(
+ static_cast<unsigned int>(mTextureWidth), static_cast<unsigned int>(mMipLevels),
+ getUsage(), mTextureFormat, getPool(), &mTexture, nullptr);
+ ANGLE_TRY_HR(GetImplAs<Context9>(context), result, "Failed to create cube storage texture");
+ }
+
+ *outTexture = mTexture;
+ return angle::Result::Continue;
+}
+
+angle::Result TextureStorage9_Cube::copyToStorage(const gl::Context *context,
+ TextureStorage *destStorage)
+{
+ ASSERT(destStorage);
+
+ TextureStorage9_Cube *dest9 = GetAs<TextureStorage9_Cube>(destStorage);
+
+ int levels = getLevelCount();
+ for (gl::TextureTarget face : gl::AllCubeFaceTextureTargets())
+ {
+ for (int i = 0; i < levels; i++)
+ {
+ angle::ComPtr<IDirect3DSurface9> srcSurf = nullptr;
+ ANGLE_TRY(getSurfaceLevel(context, face, i, false, &srcSurf));
+
+ angle::ComPtr<IDirect3DSurface9> dstSurf = nullptr;
+ ANGLE_TRY(dest9->getSurfaceLevel(context, face, i, true, &dstSurf));
+
+ ANGLE_TRY(
+ mRenderer->copyToRenderTarget(context, dstSurf.Get(), srcSurf.Get(), isManaged()));
+ }
+ }
+
+ return angle::Result::Continue;
+}
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.h
new file mode 100644
index 0000000000..9882c341f9
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.h
@@ -0,0 +1,186 @@
+//
+// Copyright 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.
+//
+
+// TextureStorage9.h: Defines the abstract rx::TextureStorage9 class and its concrete derived
+// classes TextureStorage9_2D and TextureStorage9_Cube, which act as the interface to the
+// D3D9 texture.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D9_TEXTURESTORAGE9_H_
+#define LIBANGLE_RENDERER_D3D_D3D9_TEXTURESTORAGE9_H_
+
+#include "common/debug.h"
+#include "libANGLE/renderer/d3d/TextureStorage.h"
+
+namespace rx
+{
+class EGLImageD3D;
+class Renderer9;
+class SwapChain9;
+class RenderTargetD3D;
+class RenderTarget9;
+
+class TextureStorage9 : public TextureStorage
+{
+ public:
+ ~TextureStorage9() override;
+
+ static DWORD GetTextureUsage(GLenum internalformat, bool renderTarget);
+
+ D3DPOOL getPool() const;
+ DWORD getUsage() const;
+
+ virtual angle::Result getSurfaceLevel(const gl::Context *context,
+ gl::TextureTarget target,
+ int level,
+ bool dirty,
+ IDirect3DSurface9 **outSurface) = 0;
+ virtual angle::Result getBaseTexture(const gl::Context *context,
+ IDirect3DBaseTexture9 **outTexture) = 0;
+
+ int getTopLevel() const override;
+ bool isRenderTarget() const override;
+ bool isUnorderedAccess() const override { return false; }
+ bool isManaged() const override;
+ bool supportsNativeMipmapFunction() const override;
+ int getLevelCount() const override;
+
+ angle::Result setData(const gl::Context *context,
+ const gl::ImageIndex &index,
+ ImageD3D *image,
+ const gl::Box *destBox,
+ GLenum type,
+ const gl::PixelUnpackState &unpack,
+ const uint8_t *pixelData) override;
+
+ protected:
+ int mTopLevel;
+ size_t mMipLevels;
+ size_t mTextureWidth;
+ size_t mTextureHeight;
+ GLenum mInternalFormat;
+ D3DFORMAT mTextureFormat;
+
+ Renderer9 *mRenderer;
+
+ TextureStorage9(Renderer9 *renderer, DWORD usage, const std::string &label);
+
+ private:
+ const DWORD mD3DUsage;
+ const D3DPOOL mD3DPool;
+};
+
+class TextureStorage9_2D : public TextureStorage9
+{
+ public:
+ TextureStorage9_2D(Renderer9 *renderer, SwapChain9 *swapchain, const std::string &label);
+ TextureStorage9_2D(Renderer9 *renderer,
+ GLenum internalformat,
+ bool renderTarget,
+ GLsizei width,
+ GLsizei height,
+ int levels,
+ const std::string &label);
+ ~TextureStorage9_2D() override;
+
+ angle::Result getSurfaceLevel(const gl::Context *context,
+ gl::TextureTarget target,
+ int level,
+ bool dirty,
+ IDirect3DSurface9 **outSurface) override;
+ angle::Result findRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) const override;
+ angle::Result getRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) override;
+ angle::Result getBaseTexture(const gl::Context *context,
+ IDirect3DBaseTexture9 **outTexture) override;
+ angle::Result generateMipmap(const gl::Context *context,
+ const gl::ImageIndex &sourceIndex,
+ const gl::ImageIndex &destIndex) override;
+ angle::Result copyToStorage(const gl::Context *context, TextureStorage *destStorage) override;
+
+ private:
+ IDirect3DTexture9 *mTexture;
+ std::vector<RenderTarget9 *> mRenderTargets;
+};
+
+class TextureStorage9_EGLImage final : public TextureStorage9
+{
+ public:
+ TextureStorage9_EGLImage(Renderer9 *renderer,
+ EGLImageD3D *image,
+ RenderTarget9 *renderTarget9,
+ const std::string &label);
+ ~TextureStorage9_EGLImage() override;
+
+ angle::Result getSurfaceLevel(const gl::Context *context,
+ gl::TextureTarget target,
+ int level,
+ bool dirty,
+ IDirect3DSurface9 **outSurface) override;
+ angle::Result findRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) const override;
+ angle::Result getRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) override;
+ angle::Result getBaseTexture(const gl::Context *context,
+ IDirect3DBaseTexture9 **outTexture) override;
+ angle::Result generateMipmap(const gl::Context *context,
+ const gl::ImageIndex &sourceIndex,
+ const gl::ImageIndex &destIndex) override;
+ angle::Result copyToStorage(const gl::Context *context, TextureStorage *destStorage) override;
+
+ private:
+ EGLImageD3D *mImage;
+};
+
+class TextureStorage9_Cube : public TextureStorage9
+{
+ public:
+ TextureStorage9_Cube(Renderer9 *renderer,
+ GLenum internalformat,
+ bool renderTarget,
+ int size,
+ int levels,
+ bool hintLevelZeroOnly,
+ const std::string &label);
+
+ ~TextureStorage9_Cube() override;
+
+ angle::Result getSurfaceLevel(const gl::Context *context,
+ gl::TextureTarget target,
+ int level,
+ bool dirty,
+ IDirect3DSurface9 **outSurface) override;
+ angle::Result findRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) const override;
+ angle::Result getRenderTarget(const gl::Context *context,
+ const gl::ImageIndex &index,
+ GLsizei samples,
+ RenderTargetD3D **outRT) override;
+ angle::Result getBaseTexture(const gl::Context *context,
+ IDirect3DBaseTexture9 **outTexture) override;
+ angle::Result generateMipmap(const gl::Context *context,
+ const gl::ImageIndex &sourceIndex,
+ const gl::ImageIndex &destIndex) override;
+ angle::Result copyToStorage(const gl::Context *context, TextureStorage *destStorage) override;
+
+ private:
+ IDirect3DCubeTexture9 *mTexture;
+ RenderTarget9 *mRenderTarget[gl::kCubeFaceCount];
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D9_TEXTURESTORAGE9_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexArray9.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexArray9.h
new file mode 100644
index 0000000000..a9c1ee7d4b
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexArray9.h
@@ -0,0 +1,57 @@
+//
+// 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.
+//
+
+// VertexArray9.h: Defines the rx::VertexArray9 class which implements rx::VertexArrayImpl.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D9_VERTEXARRAY9_H_
+#define LIBANGLE_RENDERER_D3D_D3D9_VERTEXARRAY9_H_
+
+#include "libANGLE/Context.h"
+#include "libANGLE/renderer/VertexArrayImpl.h"
+#include "libANGLE/renderer/d3d/d3d9/Context9.h"
+#include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
+
+namespace rx
+{
+class Renderer9;
+
+class VertexArray9 : public VertexArrayImpl
+{
+ public:
+ VertexArray9(const gl::VertexArrayState &data) : VertexArrayImpl(data) {}
+
+ angle::Result syncState(const gl::Context *context,
+ const gl::VertexArray::DirtyBits &dirtyBits,
+ gl::VertexArray::DirtyAttribBitsArray *attribBits,
+ gl::VertexArray::DirtyBindingBitsArray *bindingBits) override;
+
+ ~VertexArray9() override {}
+
+ Serial getCurrentStateSerial() const { return mCurrentStateSerial; }
+
+ private:
+ Serial mCurrentStateSerial;
+};
+
+inline angle::Result VertexArray9::syncState(const gl::Context *context,
+ const gl::VertexArray::DirtyBits &dirtyBits,
+ gl::VertexArray::DirtyAttribBitsArray *attribBits,
+ gl::VertexArray::DirtyBindingBitsArray *bindingBits)
+{
+
+ ASSERT(dirtyBits.any());
+ Renderer9 *renderer = GetImplAs<Context9>(context)->getRenderer();
+ mCurrentStateSerial = renderer->generateSerial();
+
+ // Clear the dirty bits in the back-end here.
+ memset(attribBits, 0, sizeof(gl::VertexArray::DirtyAttribBitsArray));
+ memset(bindingBits, 0, sizeof(gl::VertexArray::DirtyBindingBitsArray));
+
+ return angle::Result::Continue;
+}
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D9_VERTEXARRAY9_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.cpp
new file mode 100644
index 0000000000..915928686a
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.cpp
@@ -0,0 +1,153 @@
+//
+// Copyright 2002 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.
+//
+
+// VertexBuffer9.cpp: Defines the D3D9 VertexBuffer implementation.
+
+#include "libANGLE/renderer/d3d/d3d9/VertexBuffer9.h"
+
+#include "libANGLE/Buffer.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/VertexAttribute.h"
+#include "libANGLE/renderer/d3d/BufferD3D.h"
+#include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
+#include "libANGLE/renderer/d3d/d3d9/formatutils9.h"
+#include "libANGLE/renderer/d3d/d3d9/vertexconversion.h"
+
+namespace rx
+{
+
+VertexBuffer9::VertexBuffer9(Renderer9 *renderer) : mRenderer(renderer)
+{
+ mVertexBuffer = nullptr;
+ mBufferSize = 0;
+ mDynamicUsage = false;
+}
+
+VertexBuffer9::~VertexBuffer9()
+{
+ SafeRelease(mVertexBuffer);
+}
+
+angle::Result VertexBuffer9::initialize(const gl::Context *context,
+ unsigned int size,
+ bool dynamicUsage)
+{
+ SafeRelease(mVertexBuffer);
+
+ updateSerial();
+
+ if (size > 0)
+ {
+ DWORD flags = D3DUSAGE_WRITEONLY;
+ if (dynamicUsage)
+ {
+ flags |= D3DUSAGE_DYNAMIC;
+ }
+
+ HRESULT result = mRenderer->createVertexBuffer(size, flags, &mVertexBuffer);
+ ANGLE_TRY_HR(GetImplAs<Context9>(context), result,
+ "Failed to allocate internal vertex buffer");
+ }
+
+ mBufferSize = size;
+ mDynamicUsage = dynamicUsage;
+ return angle::Result::Continue;
+}
+
+angle::Result VertexBuffer9::storeVertexAttributes(const gl::Context *context,
+ const gl::VertexAttribute &attrib,
+ const gl::VertexBinding &binding,
+ gl::VertexAttribType currentValueType,
+ GLint start,
+ size_t count,
+ GLsizei instances,
+ unsigned int offset,
+ const uint8_t *sourceData)
+{
+ ASSERT(mVertexBuffer);
+
+ size_t inputStride = gl::ComputeVertexAttributeStride(attrib, binding);
+ size_t elementSize = gl::ComputeVertexAttributeTypeSize(attrib);
+
+ DWORD lockFlags = mDynamicUsage ? D3DLOCK_NOOVERWRITE : 0;
+
+ uint8_t *mapPtr = nullptr;
+
+ unsigned int mapSize = 0;
+ ANGLE_TRY(
+ mRenderer->getVertexSpaceRequired(context, attrib, binding, count, instances, 0, &mapSize));
+
+ HRESULT result =
+ mVertexBuffer->Lock(offset, mapSize, reinterpret_cast<void **>(&mapPtr), lockFlags);
+ ANGLE_TRY_HR(GetImplAs<Context9>(context), result, "Failed to lock internal vertex buffer");
+
+ const uint8_t *input = sourceData;
+
+ if (instances == 0 || binding.getDivisor() == 0)
+ {
+ input += inputStride * start;
+ }
+
+ angle::FormatID vertexFormatID = gl::GetVertexFormatID(attrib, currentValueType);
+ const d3d9::VertexFormat &d3dVertexInfo =
+ d3d9::GetVertexFormatInfo(mRenderer->getCapsDeclTypes(), vertexFormatID);
+ bool needsConversion = (d3dVertexInfo.conversionType & VERTEX_CONVERT_CPU) > 0;
+
+ if (!needsConversion && inputStride == elementSize)
+ {
+ size_t copySize = count * inputStride;
+ memcpy(mapPtr, input, copySize);
+ }
+ else
+ {
+ d3dVertexInfo.copyFunction(input, inputStride, count, mapPtr);
+ }
+
+ mVertexBuffer->Unlock();
+
+ return angle::Result::Continue;
+}
+
+unsigned int VertexBuffer9::getBufferSize() const
+{
+ return mBufferSize;
+}
+
+angle::Result VertexBuffer9::setBufferSize(const gl::Context *context, unsigned int size)
+{
+ if (size > mBufferSize)
+ {
+ return initialize(context, size, mDynamicUsage);
+ }
+ else
+ {
+ return angle::Result::Continue;
+ }
+}
+
+angle::Result VertexBuffer9::discard(const gl::Context *context)
+{
+ ASSERT(mVertexBuffer);
+
+ void *mock;
+ HRESULT result;
+
+ Context9 *context9 = GetImplAs<Context9>(context);
+
+ result = mVertexBuffer->Lock(0, 1, &mock, D3DLOCK_DISCARD);
+ ANGLE_TRY_HR(context9, result, "Failed to lock internal vertex buffer for discarding");
+
+ result = mVertexBuffer->Unlock();
+ ANGLE_TRY_HR(context9, result, "Failed to unlock internal vertex buffer for discarding");
+
+ return angle::Result::Continue;
+}
+
+IDirect3DVertexBuffer9 *VertexBuffer9::getBuffer() const
+{
+ return mVertexBuffer;
+}
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.h
new file mode 100644
index 0000000000..d5c156e5f5
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.h
@@ -0,0 +1,56 @@
+//
+// Copyright 2002 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.
+//
+
+// VertexBuffer9.h: Defines the D3D9 VertexBuffer implementation.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D9_VERTEXBUFFER9_H_
+#define LIBANGLE_RENDERER_D3D_D3D9_VERTEXBUFFER9_H_
+
+#include "libANGLE/renderer/d3d/VertexBuffer.h"
+
+namespace rx
+{
+class Renderer9;
+
+class VertexBuffer9 : public VertexBuffer
+{
+ public:
+ explicit VertexBuffer9(Renderer9 *renderer);
+
+ angle::Result initialize(const gl::Context *context,
+ unsigned int size,
+ bool dynamicUsage) override;
+
+ // Warning: you should ensure binding really matches attrib.bindingIndex before using this
+ // function.
+ angle::Result storeVertexAttributes(const gl::Context *context,
+ const gl::VertexAttribute &attrib,
+ const gl::VertexBinding &binding,
+ gl::VertexAttribType currentValueType,
+ GLint start,
+ size_t count,
+ GLsizei instances,
+ unsigned int offset,
+ const uint8_t *sourceData) override;
+
+ unsigned int getBufferSize() const override;
+ angle::Result setBufferSize(const gl::Context *context, unsigned int size) override;
+ angle::Result discard(const gl::Context *context) override;
+
+ IDirect3DVertexBuffer9 *getBuffer() const;
+
+ private:
+ ~VertexBuffer9() override;
+ Renderer9 *mRenderer;
+
+ IDirect3DVertexBuffer9 *mVertexBuffer;
+ unsigned int mBufferSize;
+ bool mDynamicUsage;
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D9_VERTEXBUFFER9_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.cpp
new file mode 100644
index 0000000000..e129ae9786
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.cpp
@@ -0,0 +1,262 @@
+//
+// Copyright 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.
+//
+
+// VertexDeclarationCache.cpp: Implements a helper class to construct and cache vertex declarations.
+
+#include "libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h"
+
+#include "libANGLE/Context.h"
+#include "libANGLE/VertexAttribute.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/d3d/ProgramD3D.h"
+#include "libANGLE/renderer/d3d/d3d9/Context9.h"
+#include "libANGLE/renderer/d3d/d3d9/VertexBuffer9.h"
+#include "libANGLE/renderer/d3d/d3d9/formatutils9.h"
+
+namespace rx
+{
+
+VertexDeclarationCache::VertexDeclarationCache() : mMaxLru(0)
+{
+ for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++)
+ {
+ mVertexDeclCache[i].vertexDeclaration = nullptr;
+ mVertexDeclCache[i].lruCount = 0;
+ }
+
+ for (VBData &vb : mAppliedVBs)
+ {
+ vb.serial = 0;
+ }
+
+ mLastSetVDecl = nullptr;
+ mInstancingEnabled = true;
+}
+
+VertexDeclarationCache::~VertexDeclarationCache()
+{
+ for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++)
+ {
+ SafeRelease(mVertexDeclCache[i].vertexDeclaration);
+ }
+}
+
+angle::Result VertexDeclarationCache::applyDeclaration(
+ const gl::Context *context,
+ IDirect3DDevice9 *device,
+ const std::vector<TranslatedAttribute> &attributes,
+ gl::Program *program,
+ GLint start,
+ GLsizei instances,
+ GLsizei *repeatDraw)
+{
+ ASSERT(gl::MAX_VERTEX_ATTRIBS >= attributes.size());
+
+ *repeatDraw = 1;
+
+ const size_t invalidAttribIndex = attributes.size();
+ size_t indexedAttribute = invalidAttribIndex;
+ size_t instancedAttribute = invalidAttribIndex;
+
+ if (instances == 0)
+ {
+ for (size_t i = 0; i < attributes.size(); ++i)
+ {
+ if (attributes[i].divisor != 0)
+ {
+ // If a divisor is set, it still applies even if an instanced draw was not used, so
+ // treat as a single-instance draw.
+ instances = 1;
+ break;
+ }
+ }
+ }
+
+ if (instances > 0)
+ {
+ // Find an indexed attribute to be mapped to D3D stream 0
+ for (size_t i = 0; i < attributes.size(); i++)
+ {
+ if (attributes[i].active)
+ {
+ if (indexedAttribute == invalidAttribIndex && attributes[i].divisor == 0)
+ {
+ indexedAttribute = i;
+ }
+ else if (instancedAttribute == invalidAttribIndex && attributes[i].divisor != 0)
+ {
+ instancedAttribute = i;
+ }
+ if (indexedAttribute != invalidAttribIndex &&
+ instancedAttribute != invalidAttribIndex)
+ break; // Found both an indexed and instanced attribute
+ }
+ }
+
+ // The validation layer checks that there is at least one active attribute with a zero
+ // divisor as per the GL_ANGLE_instanced_arrays spec.
+ ASSERT(indexedAttribute != invalidAttribIndex);
+ }
+
+ D3DCAPS9 caps;
+ device->GetDeviceCaps(&caps);
+
+ D3DVERTEXELEMENT9 elements[gl::MAX_VERTEX_ATTRIBS + 1];
+ D3DVERTEXELEMENT9 *element = &elements[0];
+
+ ProgramD3D *programD3D = GetImplAs<ProgramD3D>(program);
+ const auto &semanticIndexes = programD3D->getAttribLocationToD3DSemantics();
+
+ for (size_t i = 0; i < attributes.size(); i++)
+ {
+ if (attributes[i].active)
+ {
+ // Directly binding the storage buffer is not supported for d3d9
+ ASSERT(attributes[i].storage == nullptr);
+
+ int stream = static_cast<int>(i);
+
+ if (instances > 0)
+ {
+ // Due to a bug on ATI cards we can't enable instancing when none of the attributes
+ // are instanced.
+ if (instancedAttribute == invalidAttribIndex)
+ {
+ *repeatDraw = instances;
+ }
+ else
+ {
+ if (i == indexedAttribute)
+ {
+ stream = 0;
+ }
+ else if (i == 0)
+ {
+ stream = static_cast<int>(indexedAttribute);
+ }
+
+ UINT frequency = 1;
+
+ if (attributes[i].divisor == 0)
+ {
+ frequency = D3DSTREAMSOURCE_INDEXEDDATA | instances;
+ }
+ else
+ {
+ frequency = D3DSTREAMSOURCE_INSTANCEDATA | attributes[i].divisor;
+ }
+
+ device->SetStreamSourceFreq(stream, frequency);
+ mInstancingEnabled = true;
+ }
+ }
+
+ VertexBuffer9 *vertexBuffer = GetAs<VertexBuffer9>(attributes[i].vertexBuffer.get());
+
+ unsigned int offset = 0;
+ ANGLE_TRY(attributes[i].computeOffset(context, start, &offset));
+
+ if (mAppliedVBs[stream].serial != attributes[i].serial ||
+ mAppliedVBs[stream].stride != attributes[i].stride ||
+ mAppliedVBs[stream].offset != offset)
+ {
+ device->SetStreamSource(stream, vertexBuffer->getBuffer(), offset,
+ attributes[i].stride);
+ mAppliedVBs[stream].serial = attributes[i].serial;
+ mAppliedVBs[stream].stride = attributes[i].stride;
+ mAppliedVBs[stream].offset = offset;
+ }
+
+ angle::FormatID vertexformatID =
+ gl::GetVertexFormatID(*attributes[i].attribute, gl::VertexAttribType::Float);
+ const d3d9::VertexFormat &d3d9VertexInfo =
+ d3d9::GetVertexFormatInfo(caps.DeclTypes, vertexformatID);
+
+ element->Stream = static_cast<WORD>(stream);
+ element->Offset = 0;
+ element->Type = static_cast<BYTE>(d3d9VertexInfo.nativeFormat);
+ element->Method = D3DDECLMETHOD_DEFAULT;
+ element->Usage = D3DDECLUSAGE_TEXCOORD;
+ element->UsageIndex = static_cast<BYTE>(semanticIndexes[i]);
+ element++;
+ }
+ }
+
+ if (instances == 0 || instancedAttribute == invalidAttribIndex)
+ {
+ if (mInstancingEnabled)
+ {
+ for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
+ {
+ device->SetStreamSourceFreq(i, 1);
+ }
+
+ mInstancingEnabled = false;
+ }
+ }
+
+ static const D3DVERTEXELEMENT9 end = D3DDECL_END();
+ *(element++) = end;
+
+ for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++)
+ {
+ VertexDeclCacheEntry *entry = &mVertexDeclCache[i];
+ if (memcmp(entry->cachedElements, elements,
+ (element - elements) * sizeof(D3DVERTEXELEMENT9)) == 0 &&
+ entry->vertexDeclaration)
+ {
+ entry->lruCount = ++mMaxLru;
+ if (entry->vertexDeclaration != mLastSetVDecl)
+ {
+ device->SetVertexDeclaration(entry->vertexDeclaration);
+ mLastSetVDecl = entry->vertexDeclaration;
+ }
+
+ return angle::Result::Continue;
+ }
+ }
+
+ VertexDeclCacheEntry *lastCache = mVertexDeclCache;
+
+ for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++)
+ {
+ if (mVertexDeclCache[i].lruCount < lastCache->lruCount)
+ {
+ lastCache = &mVertexDeclCache[i];
+ }
+ }
+
+ if (lastCache->vertexDeclaration != nullptr)
+ {
+ SafeRelease(lastCache->vertexDeclaration);
+ // mLastSetVDecl is set to the replacement, so we don't have to worry
+ // about it.
+ }
+
+ memcpy(lastCache->cachedElements, elements, (element - elements) * sizeof(D3DVERTEXELEMENT9));
+ HRESULT result = device->CreateVertexDeclaration(elements, &lastCache->vertexDeclaration);
+ ANGLE_TRY_HR(GetImplAs<Context9>(context), result,
+ "Failed to create internal vertex declaration");
+
+ device->SetVertexDeclaration(lastCache->vertexDeclaration);
+ mLastSetVDecl = lastCache->vertexDeclaration;
+ lastCache->lruCount = ++mMaxLru;
+
+ return angle::Result::Continue;
+}
+
+void VertexDeclarationCache::markStateDirty()
+{
+ for (VBData &vb : mAppliedVBs)
+ {
+ vb.serial = 0;
+ }
+
+ mLastSetVDecl = nullptr;
+ mInstancingEnabled = true; // Forces it to be disabled when not used
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h
new file mode 100644
index 0000000000..22e677d800
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h
@@ -0,0 +1,68 @@
+//
+// Copyright 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.
+//
+
+// VertexDeclarationCache.h: Defines a helper class to construct and cache vertex declarations.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D9_VERTEXDECLARATIONCACHE_H_
+#define LIBANGLE_RENDERER_D3D_D3D9_VERTEXDECLARATIONCACHE_H_
+
+#include "libANGLE/Error.h"
+#include "libANGLE/renderer/d3d/VertexDataManager.h"
+
+namespace gl
+{
+class VertexDataManager;
+class Program;
+} // namespace gl
+
+namespace rx
+{
+class VertexDeclarationCache
+{
+ public:
+ VertexDeclarationCache();
+ ~VertexDeclarationCache();
+
+ angle::Result applyDeclaration(const gl::Context *context,
+ IDirect3DDevice9 *device,
+ const std::vector<TranslatedAttribute> &attributes,
+ gl::Program *program,
+ GLint start,
+ GLsizei instances,
+ GLsizei *repeatDraw);
+
+ void markStateDirty();
+
+ private:
+ UINT mMaxLru;
+
+ enum
+ {
+ NUM_VERTEX_DECL_CACHE_ENTRIES = 32
+ };
+
+ struct VBData
+ {
+ unsigned int serial;
+ unsigned int stride;
+ unsigned int offset;
+ };
+
+ VBData mAppliedVBs[gl::MAX_VERTEX_ATTRIBS];
+ IDirect3DVertexDeclaration9 *mLastSetVDecl;
+ bool mInstancingEnabled;
+
+ struct VertexDeclCacheEntry
+ {
+ D3DVERTEXELEMENT9 cachedElements[gl::MAX_VERTEX_ATTRIBS + 1];
+ UINT lruCount;
+ IDirect3DVertexDeclaration9 *vertexDeclaration;
+ } mVertexDeclCache[NUM_VERTEX_DECL_CACHE_ENTRIES];
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D9_VERTEXDECLARATIONCACHE_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp
new file mode 100644
index 0000000000..19a10b9cfb
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp
@@ -0,0 +1,695 @@
+//
+// Copyright 2013 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.
+//
+
+// formatutils9.cpp: Queries for GL image formats and their translations to D3D9
+// formats.
+
+#include "libANGLE/renderer/d3d/d3d9/formatutils9.h"
+
+#include "image_util/copyimage.h"
+#include "image_util/generatemip.h"
+#include "image_util/loadimage.h"
+
+#include "anglebase/no_destructor.h"
+#include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
+#include "libANGLE/renderer/d3d/d3d9/vertexconversion.h"
+
+using namespace angle;
+
+namespace rx
+{
+
+namespace d3d9
+{
+
+constexpr D3DFORMAT D3DFMT_INTZ = ((D3DFORMAT)(MAKEFOURCC('I', 'N', 'T', 'Z')));
+constexpr D3DFORMAT D3DFMT_NULL = ((D3DFORMAT)(MAKEFOURCC('N', 'U', 'L', 'L')));
+
+// A map to determine the pixel size and mip generation function of a given D3D format
+typedef std::map<D3DFORMAT, D3DFormat> D3D9FormatInfoMap;
+
+typedef std::pair<GLint, InitializeTextureDataFunction> InternalFormatInitialzerPair;
+typedef std::map<GLint, InitializeTextureDataFunction> InternalFormatInitialzerMap;
+
+static InternalFormatInitialzerMap BuildInternalFormatInitialzerMap()
+{
+ using namespace angle; // For image initialization functions
+
+ InternalFormatInitialzerMap map;
+
+ map.insert(InternalFormatInitialzerPair(
+ GL_RGB16F, Initialize4ComponentData<GLhalf, 0x0000, 0x0000, 0x0000, gl::Float16One>));
+ map.insert(InternalFormatInitialzerPair(
+ GL_RGB32F,
+ Initialize4ComponentData<GLfloat, 0x00000000, 0x00000000, 0x00000000, gl::Float32One>));
+
+ return map;
+}
+
+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)
+{
+ UNREACHABLE();
+}
+
+typedef std::pair<GLenum, TextureFormat> D3D9FormatPair;
+typedef std::map<GLenum, TextureFormat> D3D9FormatMap;
+
+TextureFormat::TextureFormat()
+ : texFormat(D3DFMT_UNKNOWN),
+ renderFormat(D3DFMT_UNKNOWN),
+ dataInitializerFunction(nullptr),
+ loadFunction(UnreachableLoad)
+{}
+
+static inline void InsertD3D9FormatInfo(D3D9FormatMap *map,
+ GLenum internalFormat,
+ D3DFORMAT texFormat,
+ D3DFORMAT renderFormat,
+ LoadImageFunction loadFunction)
+{
+ TextureFormat info;
+ info.texFormat = texFormat;
+ info.renderFormat = renderFormat;
+
+ static const angle::base::NoDestructor<InternalFormatInitialzerMap> dataInitializationMap(
+ BuildInternalFormatInitialzerMap());
+ InternalFormatInitialzerMap::const_iterator dataInitIter =
+ dataInitializationMap->find(internalFormat);
+ info.dataInitializerFunction =
+ (dataInitIter != dataInitializationMap->end()) ? dataInitIter->second : nullptr;
+
+ info.loadFunction = loadFunction;
+
+ map->insert(std::make_pair(internalFormat, info));
+}
+
+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 );
+
+ // We choose to downsample the GL_DEPTH_COMPONENT32_OES format to a 24-bit format because D3DFMT_D32 is not widely
+ // supported. We're allowed to do this because:
+ // - The ES spec 2.0.25 sec 3.7.1 states that we're allowed to store texture formats with internal format
+ // resolutions of our own choosing.
+ // - OES_depth_texture states that downsampling of the depth formats is allowed.
+ // - ANGLE_depth_texture does not state minimum required resolutions of the depth texture formats it
+ // introduces.
+ // In ES3 however, there are minimum resolutions for the texture formats and this would not be allowed.
+
+ InsertD3D9FormatInfo(&map, GL_DEPTH_COMPONENT16, D3DFMT_INTZ, D3DFMT_D24S8, UnreachableLoad );
+ InsertD3D9FormatInfo(&map, GL_DEPTH_COMPONENT32_OES, D3DFMT_INTZ, D3DFMT_D24X8, UnreachableLoad );
+ InsertD3D9FormatInfo(&map, GL_DEPTH24_STENCIL8_OES, D3DFMT_INTZ, D3DFMT_D24S8, UnreachableLoad );
+ InsertD3D9FormatInfo(&map, GL_STENCIL_INDEX8, D3DFMT_UNKNOWN, D3DFMT_D24S8, UnreachableLoad ); // TODO: What's the texture format?
+
+ InsertD3D9FormatInfo(&map, GL_RGBA32F_EXT, D3DFMT_A32B32G32R32F, D3DFMT_A32B32G32R32F, LoadToNative<GLfloat, 4> );
+ InsertD3D9FormatInfo(&map, GL_RGB32F_EXT, D3DFMT_A32B32G32R32F, D3DFMT_A32B32G32R32F, LoadToNative3To4<GLfloat, gl::Float32One>);
+ InsertD3D9FormatInfo(&map, GL_RG32F_EXT, D3DFMT_G32R32F, D3DFMT_G32R32F, LoadToNative<GLfloat, 2> );
+ InsertD3D9FormatInfo(&map, GL_R32F_EXT, D3DFMT_R32F, D3DFMT_R32F, LoadToNative<GLfloat, 1> );
+ InsertD3D9FormatInfo(&map, GL_ALPHA32F_EXT, D3DFMT_A32B32G32R32F, D3DFMT_UNKNOWN, LoadA32FToRGBA32F );
+ InsertD3D9FormatInfo(&map, GL_LUMINANCE32F_EXT, D3DFMT_A32B32G32R32F, D3DFMT_UNKNOWN, LoadL32FToRGBA32F );
+ InsertD3D9FormatInfo(&map, GL_LUMINANCE_ALPHA32F_EXT, D3DFMT_A32B32G32R32F, D3DFMT_UNKNOWN, LoadLA32FToRGBA32F );
+
+ InsertD3D9FormatInfo(&map, GL_RGBA16F_EXT, D3DFMT_A16B16G16R16F, D3DFMT_A16B16G16R16F, LoadToNative<GLhalf, 4> );
+ InsertD3D9FormatInfo(&map, GL_RGB16F_EXT, D3DFMT_A16B16G16R16F, D3DFMT_A16B16G16R16F, LoadToNative3To4<GLhalf, gl::Float16One> );
+ InsertD3D9FormatInfo(&map, GL_RG16F_EXT, D3DFMT_G16R16F, D3DFMT_G16R16F, LoadToNative<GLhalf, 2> );
+ InsertD3D9FormatInfo(&map, GL_R16F_EXT, D3DFMT_R16F, D3DFMT_R16F, LoadToNative<GLhalf, 1> );
+ InsertD3D9FormatInfo(&map, GL_ALPHA16F_EXT, D3DFMT_A16B16G16R16F, D3DFMT_UNKNOWN, LoadA16FToRGBA16F );
+ 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, 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, 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 );
+ InsertD3D9FormatInfo(&map, GL_RG8_EXT, D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, LoadRG8ToBGRX8 );
+
+ InsertD3D9FormatInfo(&map, GL_SRGB8, D3DFMT_X8R8G8B8, D3DFMT_UNKNOWN, LoadRGB8ToBGRX8 );
+ InsertD3D9FormatInfo(&map, GL_SRGB8_ALPHA8_EXT, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadRGBA8ToBGRA8 );
+
+ InsertD3D9FormatInfo(&map, GL_BGRA8_EXT, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadToNative<GLubyte, 4> );
+ InsertD3D9FormatInfo(&map, GL_BGRA4_ANGLEX, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadBGRA4ToBGRA8 );
+ InsertD3D9FormatInfo(&map, GL_BGR5_A1_ANGLEX, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadBGR5A1ToBGRA8 );
+
+ InsertD3D9FormatInfo(&map, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, D3DFMT_DXT1, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 1, 8> );
+ InsertD3D9FormatInfo(&map, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, D3DFMT_DXT1, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 1, 8> );
+ InsertD3D9FormatInfo(&map, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, D3DFMT_DXT3, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 1, 16> );
+ InsertD3D9FormatInfo(&map, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, D3DFMT_DXT5, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 1, 16> );
+
+ InsertD3D9FormatInfo(&map, GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, D3DFMT_DXT1, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 1, 8> );
+ InsertD3D9FormatInfo(&map, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, D3DFMT_DXT1, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 1, 8> );
+ InsertD3D9FormatInfo(&map, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, D3DFMT_DXT3, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 1, 16> );
+ InsertD3D9FormatInfo(&map, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, D3DFMT_DXT5, D3DFMT_UNKNOWN, LoadCompressedToNative<4, 4, 1, 16> );
+
+ // These formats require checking if the renderer supports D3DFMT_L8 or D3DFMT_A8L8 and
+ // 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;
+}
+
+const TextureFormat &GetTextureFormatInfo(GLenum internalFormat)
+{
+ static const angle::base::NoDestructor<D3D9FormatMap> formatMap(BuildD3D9FormatMap());
+ D3D9FormatMap::const_iterator iter = formatMap->find(internalFormat);
+ if (iter != formatMap->end())
+ {
+ return iter->second;
+ }
+ else
+ {
+ static const TextureFormat defaultInfo;
+ return defaultInfo;
+ }
+}
+
+static GLenum GetDeclTypeComponentType(D3DDECLTYPE declType)
+{
+ switch (declType)
+ {
+ case D3DDECLTYPE_FLOAT1:
+ return GL_FLOAT;
+ case D3DDECLTYPE_FLOAT2:
+ return GL_FLOAT;
+ case D3DDECLTYPE_FLOAT3:
+ return GL_FLOAT;
+ case D3DDECLTYPE_FLOAT4:
+ return GL_FLOAT;
+ case D3DDECLTYPE_UBYTE4:
+ return GL_UNSIGNED_INT;
+ case D3DDECLTYPE_SHORT2:
+ return GL_INT;
+ case D3DDECLTYPE_SHORT4:
+ return GL_INT;
+ case D3DDECLTYPE_UBYTE4N:
+ return GL_UNSIGNED_NORMALIZED;
+ case D3DDECLTYPE_SHORT4N:
+ return GL_SIGNED_NORMALIZED;
+ case D3DDECLTYPE_USHORT4N:
+ return GL_UNSIGNED_NORMALIZED;
+ case D3DDECLTYPE_SHORT2N:
+ return GL_SIGNED_NORMALIZED;
+ case D3DDECLTYPE_USHORT2N:
+ return GL_UNSIGNED_NORMALIZED;
+ default:
+ UNREACHABLE();
+ return GL_NONE;
+ }
+}
+
+// Attribute format conversion
+enum
+{
+ NUM_GL_VERTEX_ATTRIB_TYPES = 6
+};
+
+struct TranslationDescription
+{
+ DWORD capsFlag;
+ VertexFormat preferredConversion;
+ VertexFormat fallbackConversion;
+};
+
+// Mapping from OpenGL-ES vertex attrib type to D3D decl type:
+//
+// BYTE SHORT (Cast)
+// BYTE-norm FLOAT (Normalize) (can't be exactly represented as SHORT-norm)
+// UNSIGNED_BYTE UBYTE4 (Identity) or SHORT (Cast)
+// UNSIGNED_BYTE-norm UBYTE4N (Identity) or FLOAT (Normalize)
+// SHORT SHORT (Identity)
+// SHORT-norm SHORT-norm (Identity) or FLOAT (Normalize)
+// UNSIGNED_SHORT FLOAT (Cast)
+// UNSIGNED_SHORT-norm USHORT-norm (Identity) or FLOAT (Normalize)
+// FIXED (not in WebGL) FLOAT (FixedToFloat)
+// FLOAT FLOAT (Identity)
+
+// GLToCType maps from GL type (as GLenum) to the C typedef.
+template <GLenum GLType>
+struct GLToCType
+{};
+
+template <>
+struct GLToCType<GL_BYTE>
+{
+ typedef GLbyte type;
+};
+template <>
+struct GLToCType<GL_UNSIGNED_BYTE>
+{
+ typedef GLubyte type;
+};
+template <>
+struct GLToCType<GL_SHORT>
+{
+ typedef GLshort type;
+};
+template <>
+struct GLToCType<GL_UNSIGNED_SHORT>
+{
+ typedef GLushort type;
+};
+template <>
+struct GLToCType<GL_FIXED>
+{
+ typedef GLuint type;
+};
+template <>
+struct GLToCType<GL_FLOAT>
+{
+ typedef GLfloat type;
+};
+
+// This differs from D3DDECLTYPE in that it is unsized. (Size expansion is applied last.)
+enum D3DVertexType
+{
+ D3DVT_FLOAT,
+ D3DVT_SHORT,
+ D3DVT_SHORT_NORM,
+ D3DVT_UBYTE,
+ D3DVT_UBYTE_NORM,
+ D3DVT_USHORT_NORM
+};
+
+// D3DToCType maps from D3D vertex type (as enum D3DVertexType) to the corresponding C type.
+template <unsigned int D3DType>
+struct D3DToCType
+{};
+
+template <>
+struct D3DToCType<D3DVT_FLOAT>
+{
+ typedef float type;
+};
+template <>
+struct D3DToCType<D3DVT_SHORT>
+{
+ typedef short type;
+};
+template <>
+struct D3DToCType<D3DVT_SHORT_NORM>
+{
+ typedef short type;
+};
+template <>
+struct D3DToCType<D3DVT_UBYTE>
+{
+ typedef unsigned char type;
+};
+template <>
+struct D3DToCType<D3DVT_UBYTE_NORM>
+{
+ typedef unsigned char type;
+};
+template <>
+struct D3DToCType<D3DVT_USHORT_NORM>
+{
+ typedef unsigned short type;
+};
+
+// Encode the type/size combinations that D3D permits. For each type/size it expands to a widener
+// that will provide the appropriate final size.
+template <unsigned int type, int size>
+struct WidenRule
+{};
+
+template <int size>
+struct WidenRule<D3DVT_FLOAT, size> : NoWiden<size>
+{};
+template <int size>
+struct WidenRule<D3DVT_SHORT, size> : WidenToEven<size>
+{};
+template <int size>
+struct WidenRule<D3DVT_SHORT_NORM, size> : WidenToEven<size>
+{};
+template <int size>
+struct WidenRule<D3DVT_UBYTE, size> : WidenToFour<size>
+{};
+template <int size>
+struct WidenRule<D3DVT_UBYTE_NORM, size> : WidenToFour<size>
+{};
+template <int size>
+struct WidenRule<D3DVT_USHORT_NORM, size> : WidenToEven<size>
+{};
+
+// VertexTypeFlags encodes the D3DCAPS9::DeclType flag and vertex declaration flag for each D3D
+// vertex type & size combination.
+template <unsigned int d3dtype, int size>
+struct VertexTypeFlags
+{};
+
+template <unsigned int _capflag, unsigned int _declflag>
+struct VertexTypeFlagsHelper
+{
+ enum
+ {
+ capflag = _capflag
+ };
+ enum
+ {
+ declflag = _declflag
+ };
+};
+
+template <>
+struct VertexTypeFlags<D3DVT_FLOAT, 1> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT1>
+{};
+template <>
+struct VertexTypeFlags<D3DVT_FLOAT, 2> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT2>
+{};
+template <>
+struct VertexTypeFlags<D3DVT_FLOAT, 3> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT3>
+{};
+template <>
+struct VertexTypeFlags<D3DVT_FLOAT, 4> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT4>
+{};
+template <>
+struct VertexTypeFlags<D3DVT_SHORT, 2> : VertexTypeFlagsHelper<0, D3DDECLTYPE_SHORT2>
+{};
+template <>
+struct VertexTypeFlags<D3DVT_SHORT, 4> : VertexTypeFlagsHelper<0, D3DDECLTYPE_SHORT4>
+{};
+template <>
+struct VertexTypeFlags<D3DVT_SHORT_NORM, 2>
+ : VertexTypeFlagsHelper<D3DDTCAPS_SHORT2N, D3DDECLTYPE_SHORT2N>
+{};
+template <>
+struct VertexTypeFlags<D3DVT_SHORT_NORM, 4>
+ : VertexTypeFlagsHelper<D3DDTCAPS_SHORT4N, D3DDECLTYPE_SHORT4N>
+{};
+template <>
+struct VertexTypeFlags<D3DVT_UBYTE, 4> : VertexTypeFlagsHelper<D3DDTCAPS_UBYTE4, D3DDECLTYPE_UBYTE4>
+{};
+template <>
+struct VertexTypeFlags<D3DVT_UBYTE_NORM, 4>
+ : VertexTypeFlagsHelper<D3DDTCAPS_UBYTE4N, D3DDECLTYPE_UBYTE4N>
+{};
+template <>
+struct VertexTypeFlags<D3DVT_USHORT_NORM, 2>
+ : VertexTypeFlagsHelper<D3DDTCAPS_USHORT2N, D3DDECLTYPE_USHORT2N>
+{};
+template <>
+struct VertexTypeFlags<D3DVT_USHORT_NORM, 4>
+ : VertexTypeFlagsHelper<D3DDTCAPS_USHORT4N, D3DDECLTYPE_USHORT4N>
+{};
+
+// VertexTypeMapping maps GL type & normalized flag to preferred and fallback D3D vertex types (as
+// D3DVertexType enums).
+template <GLenum GLtype, bool normalized>
+struct VertexTypeMapping
+{};
+
+template <D3DVertexType Preferred, D3DVertexType Fallback = Preferred>
+struct VertexTypeMappingBase
+{
+ enum
+ {
+ preferred = Preferred
+ };
+ enum
+ {
+ fallback = Fallback
+ };
+};
+
+template <>
+struct VertexTypeMapping<GL_BYTE, false> : VertexTypeMappingBase<D3DVT_SHORT>
+{}; // Cast
+template <>
+struct VertexTypeMapping<GL_BYTE, true> : VertexTypeMappingBase<D3DVT_FLOAT>
+{}; // Normalize
+template <>
+struct VertexTypeMapping<GL_UNSIGNED_BYTE, false> : VertexTypeMappingBase<D3DVT_UBYTE, D3DVT_FLOAT>
+{}; // Identity, Cast
+template <>
+struct VertexTypeMapping<GL_UNSIGNED_BYTE, true>
+ : VertexTypeMappingBase<D3DVT_UBYTE_NORM, D3DVT_FLOAT>
+{}; // Identity, Normalize
+template <>
+struct VertexTypeMapping<GL_SHORT, false> : VertexTypeMappingBase<D3DVT_SHORT>
+{}; // Identity
+template <>
+struct VertexTypeMapping<GL_SHORT, true> : VertexTypeMappingBase<D3DVT_SHORT_NORM, D3DVT_FLOAT>
+{}; // Cast, Normalize
+template <>
+struct VertexTypeMapping<GL_UNSIGNED_SHORT, false> : VertexTypeMappingBase<D3DVT_FLOAT>
+{}; // Cast
+template <>
+struct VertexTypeMapping<GL_UNSIGNED_SHORT, true>
+ : VertexTypeMappingBase<D3DVT_USHORT_NORM, D3DVT_FLOAT>
+{}; // Cast, Normalize
+template <bool normalized>
+struct VertexTypeMapping<GL_FIXED, normalized> : VertexTypeMappingBase<D3DVT_FLOAT>
+{}; // FixedToFloat
+template <bool normalized>
+struct VertexTypeMapping<GL_FLOAT, normalized> : VertexTypeMappingBase<D3DVT_FLOAT>
+{}; // Identity
+
+// Given a GL type & norm flag and a D3D type, ConversionRule provides the type conversion rule
+// (Cast, Normalize, Identity, FixedToFloat). The conversion rules themselves are defined in
+// vertexconversion.h.
+
+// Almost all cases are covered by Cast (including those that are actually Identity since Cast<T,T>
+// knows it's an identity mapping).
+template <GLenum fromType, bool normalized, unsigned int toType>
+struct ConversionRule : Cast<typename GLToCType<fromType>::type, typename D3DToCType<toType>::type>
+{};
+
+// All conversions from normalized types to float use the Normalize operator.
+template <GLenum fromType>
+struct ConversionRule<fromType, true, D3DVT_FLOAT> : Normalize<typename GLToCType<fromType>::type>
+{};
+
+// Use a full specialization for this so that it preferentially matches ahead of the generic
+// normalize-to-float rules.
+template <>
+struct ConversionRule<GL_FIXED, true, D3DVT_FLOAT> : FixedToFloat<GLint, 16>
+{};
+template <>
+struct ConversionRule<GL_FIXED, false, D3DVT_FLOAT> : FixedToFloat<GLint, 16>
+{};
+
+// A 2-stage construction is used for DefaultVertexValues because float must use SimpleDefaultValues
+// (i.e. 0/1) whether it is normalized or not.
+template <class T, bool normalized>
+struct DefaultVertexValuesStage2
+{};
+
+template <class T>
+struct DefaultVertexValuesStage2<T, true> : NormalizedDefaultValues<T>
+{};
+template <class T>
+struct DefaultVertexValuesStage2<T, false> : SimpleDefaultValues<T>
+{};
+
+// Work out the default value rule for a D3D type (expressed as the C type) and
+template <class T, bool normalized>
+struct DefaultVertexValues : DefaultVertexValuesStage2<T, normalized>
+{};
+template <bool normalized>
+struct DefaultVertexValues<float, normalized> : SimpleDefaultValues<float>
+{};
+
+// Policy rules for use with Converter, to choose whether to use the preferred or fallback
+// conversion. The fallback conversion produces an output that all D3D9 devices must support.
+template <class T>
+struct UsePreferred
+{
+ enum
+ {
+ type = T::preferred
+ };
+};
+template <class T>
+struct UseFallback
+{
+ enum
+ {
+ type = T::fallback
+ };
+};
+
+// Converter ties it all together. Given an OpenGL type/norm/size and choice of preferred/fallback
+// conversion, it provides all the members of the appropriate VertexDataConverter, the
+// D3DCAPS9::DeclTypes flag in cap flag and the D3DDECLTYPE member needed for the vertex declaration
+// in declflag.
+template <GLenum fromType, bool normalized, int size, template <class T> class PreferenceRule>
+struct Converter
+ : VertexDataConverter<
+ typename GLToCType<fromType>::type,
+ WidenRule<PreferenceRule<VertexTypeMapping<fromType, normalized>>::type, size>,
+ ConversionRule<fromType,
+ normalized,
+ PreferenceRule<VertexTypeMapping<fromType, normalized>>::type>,
+ DefaultVertexValues<typename D3DToCType<PreferenceRule<
+ VertexTypeMapping<fromType, normalized>>::type>::type,
+ normalized>>
+{
+ private:
+ enum
+ {
+ d3dtype = PreferenceRule<VertexTypeMapping<fromType, normalized>>::type
+ };
+ enum
+ {
+ d3dsize = WidenRule<d3dtype, size>::finalWidth
+ };
+
+ public:
+ enum
+ {
+ capflag = VertexTypeFlags<d3dtype, d3dsize>::capflag
+ };
+ enum
+ {
+ declflag = VertexTypeFlags<d3dtype, d3dsize>::declflag
+ };
+};
+
+VertexFormat::VertexFormat()
+ : conversionType(VERTEX_CONVERT_NONE),
+ outputElementSize(0),
+ copyFunction(nullptr),
+ nativeFormat(D3DDECLTYPE_UNUSED),
+ componentType(GL_NONE)
+{}
+
+// Initialize a TranslationInfo
+VertexFormat CreateVertexFormatInfo(bool identity,
+ size_t elementSize,
+ VertexCopyFunction copyFunc,
+ D3DDECLTYPE nativeFormat)
+{
+ VertexFormat formatInfo;
+ formatInfo.conversionType = identity ? VERTEX_CONVERT_NONE : VERTEX_CONVERT_CPU;
+ formatInfo.outputElementSize = elementSize;
+ formatInfo.copyFunction = copyFunc;
+ formatInfo.nativeFormat = nativeFormat;
+ formatInfo.componentType = GetDeclTypeComponentType(nativeFormat);
+ return formatInfo;
+}
+
+#define TRANSLATION(type, norm, size, preferred) \
+ CreateVertexFormatInfo( \
+ Converter<type, norm, size, preferred>::identity, \
+ Converter<type, norm, size, preferred>::finalSize, \
+ Converter<type, norm, size, preferred>::convertArray, \
+ static_cast<D3DDECLTYPE>(Converter<type, norm, size, preferred>::declflag))
+
+#define TRANSLATION_FOR_TYPE_NORM_SIZE(type, norm, size) \
+ { \
+ Converter<type, norm, size, UsePreferred>::capflag, \
+ TRANSLATION(type, norm, size, UsePreferred), \
+ TRANSLATION(type, norm, size, UseFallback) \
+ }
+
+#define TRANSLATIONS_FOR_TYPE(type) \
+ { \
+ {TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), \
+ TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), \
+ TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), \
+ TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4)}, \
+ {TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 1), \
+ TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 2), \
+ TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 3), \
+ TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 4)}, \
+ }
+
+#define TRANSLATIONS_FOR_TYPE_NO_NORM(type) \
+ { \
+ {TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), \
+ TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), \
+ TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), \
+ TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4)}, \
+ {TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), \
+ TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), \
+ TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), \
+ TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4)}, \
+ }
+
+static inline unsigned int ComputeTypeIndex(GLenum type)
+{
+ switch (type)
+ {
+ case GL_BYTE:
+ return 0;
+ case GL_UNSIGNED_BYTE:
+ return 1;
+ case GL_SHORT:
+ return 2;
+ case GL_UNSIGNED_SHORT:
+ return 3;
+ case GL_FIXED:
+ return 4;
+ case GL_FLOAT:
+ return 5;
+
+ default:
+ UNREACHABLE();
+ return 5;
+ }
+}
+
+const VertexFormat &GetVertexFormatInfo(DWORD supportedDeclTypes, angle::FormatID vertexFormatID)
+{
+ static DWORD initializedDeclTypes = 0;
+ static VertexFormat formatConverters[NUM_GL_VERTEX_ATTRIB_TYPES][2][4];
+ if (initializedDeclTypes != supportedDeclTypes)
+ {
+ const TranslationDescription
+ translations[NUM_GL_VERTEX_ATTRIB_TYPES][2]
+ [4] = // [GL types as enumerated by typeIndex()][normalized][size-1]
+ {TRANSLATIONS_FOR_TYPE(GL_BYTE), TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_BYTE),
+ TRANSLATIONS_FOR_TYPE(GL_SHORT), TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_SHORT),
+ TRANSLATIONS_FOR_TYPE_NO_NORM(GL_FIXED), TRANSLATIONS_FOR_TYPE_NO_NORM(GL_FLOAT)};
+ for (unsigned int i = 0; i < NUM_GL_VERTEX_ATTRIB_TYPES; i++)
+ {
+ for (unsigned int j = 0; j < 2; j++)
+ {
+ for (unsigned int k = 0; k < 4; k++)
+ {
+ if (translations[i][j][k].capsFlag == 0 ||
+ (supportedDeclTypes & translations[i][j][k].capsFlag) != 0)
+ {
+ formatConverters[i][j][k] = translations[i][j][k].preferredConversion;
+ }
+ else
+ {
+ formatConverters[i][j][k] = translations[i][j][k].fallbackConversion;
+ }
+ }
+ }
+ }
+ initializedDeclTypes = supportedDeclTypes;
+ }
+
+ const gl::VertexFormat &vertexFormat = gl::GetVertexFormatFromID(vertexFormatID);
+
+ // Pure integer attributes only supported in ES3.0
+ ASSERT(!vertexFormat.pureInteger);
+ return formatConverters[ComputeTypeIndex(vertexFormat.type)][vertexFormat.normalized]
+ [vertexFormat.components - 1];
+}
+} // namespace d3d9
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/formatutils9.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/formatutils9.h
new file mode 100644
index 0000000000..c3997ec0e9
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/formatutils9.h
@@ -0,0 +1,59 @@
+//
+// Copyright 2013 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.
+//
+
+// formatutils9.h: Queries for GL image formats and their translations to D3D9
+// formats.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D9_FORMATUTILS9_H_
+#define LIBANGLE_RENDERER_D3D_D3D9_FORMATUTILS9_H_
+
+#include <map>
+
+#include "common/platform.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/Format.h"
+#include "libANGLE/renderer/copyvertex.h"
+#include "libANGLE/renderer/d3d/formatutilsD3D.h"
+#include "libANGLE/renderer/d3d_format.h"
+#include "libANGLE/renderer/renderer_utils.h"
+
+namespace rx
+{
+
+class Renderer9;
+
+namespace d3d9
+{
+
+struct VertexFormat
+{
+ VertexFormat();
+
+ VertexConversionType conversionType;
+ size_t outputElementSize;
+ VertexCopyFunction copyFunction;
+ D3DDECLTYPE nativeFormat;
+ GLenum componentType;
+};
+const VertexFormat &GetVertexFormatInfo(DWORD supportedDeclTypes, angle::FormatID vertexFormatID);
+
+struct TextureFormat
+{
+ TextureFormat();
+
+ D3DFORMAT texFormat;
+ D3DFORMAT renderFormat;
+
+ InitializeTextureDataFunction dataInitializerFunction;
+
+ LoadImageFunction loadFunction;
+};
+const TextureFormat &GetTextureFormatInfo(GLenum internalFormat);
+} // namespace d3d9
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D9_FORMATUTILS9_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp
new file mode 100644
index 0000000000..79e5c9cb06
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp
@@ -0,0 +1,845 @@
+//
+// Copyright 2002 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.
+//
+
+// renderer9_utils.cpp: Conversion functions and other utility routines
+// specific to the D3D9 renderer.
+
+#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h"
+
+#include "common/debug.h"
+#include "common/mathutil.h"
+
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h"
+#include "libANGLE/renderer/d3d/d3d9/formatutils9.h"
+#include "libANGLE/renderer/driver_utils.h"
+#include "platform/FeaturesD3D_autogen.h"
+#include "platform/PlatformMethods.h"
+
+#include "third_party/systeminfo/SystemInfo.h"
+
+namespace rx
+{
+
+namespace gl_d3d9
+{
+
+D3DCMPFUNC ConvertComparison(GLenum comparison)
+{
+ D3DCMPFUNC d3dComp = D3DCMP_ALWAYS;
+ switch (comparison)
+ {
+ case GL_NEVER:
+ d3dComp = D3DCMP_NEVER;
+ break;
+ case GL_ALWAYS:
+ d3dComp = D3DCMP_ALWAYS;
+ break;
+ case GL_LESS:
+ d3dComp = D3DCMP_LESS;
+ break;
+ case GL_LEQUAL:
+ d3dComp = D3DCMP_LESSEQUAL;
+ break;
+ case GL_EQUAL:
+ d3dComp = D3DCMP_EQUAL;
+ break;
+ case GL_GREATER:
+ d3dComp = D3DCMP_GREATER;
+ break;
+ case GL_GEQUAL:
+ d3dComp = D3DCMP_GREATEREQUAL;
+ break;
+ case GL_NOTEQUAL:
+ d3dComp = D3DCMP_NOTEQUAL;
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ return d3dComp;
+}
+
+D3DCOLOR ConvertColor(gl::ColorF color)
+{
+ return D3DCOLOR_RGBA(gl::unorm<8>(color.red), gl::unorm<8>(color.green),
+ gl::unorm<8>(color.blue), gl::unorm<8>(color.alpha));
+}
+
+D3DBLEND ConvertBlendFunc(GLenum blend)
+{
+ D3DBLEND d3dBlend = D3DBLEND_ZERO;
+
+ switch (blend)
+ {
+ case GL_ZERO:
+ d3dBlend = D3DBLEND_ZERO;
+ break;
+ case GL_ONE:
+ d3dBlend = D3DBLEND_ONE;
+ break;
+ case GL_SRC_COLOR:
+ d3dBlend = D3DBLEND_SRCCOLOR;
+ break;
+ case GL_ONE_MINUS_SRC_COLOR:
+ d3dBlend = D3DBLEND_INVSRCCOLOR;
+ break;
+ case GL_DST_COLOR:
+ d3dBlend = D3DBLEND_DESTCOLOR;
+ break;
+ case GL_ONE_MINUS_DST_COLOR:
+ d3dBlend = D3DBLEND_INVDESTCOLOR;
+ break;
+ case GL_SRC_ALPHA:
+ d3dBlend = D3DBLEND_SRCALPHA;
+ break;
+ case GL_ONE_MINUS_SRC_ALPHA:
+ d3dBlend = D3DBLEND_INVSRCALPHA;
+ break;
+ case GL_DST_ALPHA:
+ d3dBlend = D3DBLEND_DESTALPHA;
+ break;
+ case GL_ONE_MINUS_DST_ALPHA:
+ d3dBlend = D3DBLEND_INVDESTALPHA;
+ break;
+ case GL_CONSTANT_COLOR:
+ d3dBlend = D3DBLEND_BLENDFACTOR;
+ break;
+ case GL_ONE_MINUS_CONSTANT_COLOR:
+ d3dBlend = D3DBLEND_INVBLENDFACTOR;
+ break;
+ case GL_CONSTANT_ALPHA:
+ d3dBlend = D3DBLEND_BLENDFACTOR;
+ break;
+ case GL_ONE_MINUS_CONSTANT_ALPHA:
+ d3dBlend = D3DBLEND_INVBLENDFACTOR;
+ break;
+ case GL_SRC_ALPHA_SATURATE:
+ d3dBlend = D3DBLEND_SRCALPHASAT;
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ return d3dBlend;
+}
+
+D3DBLENDOP ConvertBlendOp(GLenum blendOp)
+{
+ D3DBLENDOP d3dBlendOp = D3DBLENDOP_ADD;
+
+ switch (blendOp)
+ {
+ case GL_FUNC_ADD:
+ d3dBlendOp = D3DBLENDOP_ADD;
+ break;
+ case GL_FUNC_SUBTRACT:
+ d3dBlendOp = D3DBLENDOP_SUBTRACT;
+ break;
+ case GL_FUNC_REVERSE_SUBTRACT:
+ d3dBlendOp = D3DBLENDOP_REVSUBTRACT;
+ break;
+ case GL_MIN_EXT:
+ d3dBlendOp = D3DBLENDOP_MIN;
+ break;
+ case GL_MAX_EXT:
+ d3dBlendOp = D3DBLENDOP_MAX;
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ return d3dBlendOp;
+}
+
+D3DSTENCILOP ConvertStencilOp(GLenum stencilOp)
+{
+ D3DSTENCILOP d3dStencilOp = D3DSTENCILOP_KEEP;
+
+ switch (stencilOp)
+ {
+ case GL_ZERO:
+ d3dStencilOp = D3DSTENCILOP_ZERO;
+ break;
+ case GL_KEEP:
+ d3dStencilOp = D3DSTENCILOP_KEEP;
+ break;
+ case GL_REPLACE:
+ d3dStencilOp = D3DSTENCILOP_REPLACE;
+ break;
+ case GL_INCR:
+ d3dStencilOp = D3DSTENCILOP_INCRSAT;
+ break;
+ case GL_DECR:
+ d3dStencilOp = D3DSTENCILOP_DECRSAT;
+ break;
+ case GL_INVERT:
+ d3dStencilOp = D3DSTENCILOP_INVERT;
+ break;
+ case GL_INCR_WRAP:
+ d3dStencilOp = D3DSTENCILOP_INCR;
+ break;
+ case GL_DECR_WRAP:
+ d3dStencilOp = D3DSTENCILOP_DECR;
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ return d3dStencilOp;
+}
+
+D3DTEXTUREADDRESS ConvertTextureWrap(GLenum wrap)
+{
+ D3DTEXTUREADDRESS d3dWrap = D3DTADDRESS_WRAP;
+
+ switch (wrap)
+ {
+ case GL_REPEAT:
+ d3dWrap = D3DTADDRESS_WRAP;
+ break;
+ case GL_CLAMP_TO_EDGE:
+ d3dWrap = D3DTADDRESS_CLAMP;
+ break;
+ case GL_CLAMP_TO_BORDER:
+ d3dWrap = D3DTADDRESS_BORDER;
+ break;
+ case GL_MIRRORED_REPEAT:
+ d3dWrap = D3DTADDRESS_MIRROR;
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ return d3dWrap;
+}
+
+D3DCULL ConvertCullMode(gl::CullFaceMode cullFace, GLenum frontFace)
+{
+ D3DCULL cull = D3DCULL_CCW;
+ switch (cullFace)
+ {
+ case gl::CullFaceMode::Front:
+ cull = (frontFace == GL_CCW ? D3DCULL_CW : D3DCULL_CCW);
+ break;
+ case gl::CullFaceMode::Back:
+ cull = (frontFace == GL_CCW ? D3DCULL_CCW : D3DCULL_CW);
+ break;
+ case gl::CullFaceMode::FrontAndBack:
+ cull = D3DCULL_NONE; // culling will be handled during draw
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ return cull;
+}
+
+D3DCUBEMAP_FACES ConvertCubeFace(gl::TextureTarget cubeFace)
+{
+ D3DCUBEMAP_FACES face = D3DCUBEMAP_FACE_POSITIVE_X;
+
+ switch (cubeFace)
+ {
+ case gl::TextureTarget::CubeMapPositiveX:
+ face = D3DCUBEMAP_FACE_POSITIVE_X;
+ break;
+ case gl::TextureTarget::CubeMapNegativeX:
+ face = D3DCUBEMAP_FACE_NEGATIVE_X;
+ break;
+ case gl::TextureTarget::CubeMapPositiveY:
+ face = D3DCUBEMAP_FACE_POSITIVE_Y;
+ break;
+ case gl::TextureTarget::CubeMapNegativeY:
+ face = D3DCUBEMAP_FACE_NEGATIVE_Y;
+ break;
+ case gl::TextureTarget::CubeMapPositiveZ:
+ face = D3DCUBEMAP_FACE_POSITIVE_Z;
+ break;
+ case gl::TextureTarget::CubeMapNegativeZ:
+ face = D3DCUBEMAP_FACE_NEGATIVE_Z;
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ return face;
+}
+
+DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha)
+{
+ return (red ? D3DCOLORWRITEENABLE_RED : 0) | (green ? D3DCOLORWRITEENABLE_GREEN : 0) |
+ (blue ? D3DCOLORWRITEENABLE_BLUE : 0) | (alpha ? D3DCOLORWRITEENABLE_ALPHA : 0);
+}
+
+D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter, float maxAnisotropy)
+{
+ if (maxAnisotropy > 1.0f)
+ {
+ return D3DTEXF_ANISOTROPIC;
+ }
+
+ D3DTEXTUREFILTERTYPE d3dMagFilter = D3DTEXF_POINT;
+ switch (magFilter)
+ {
+ case GL_NEAREST:
+ d3dMagFilter = D3DTEXF_POINT;
+ break;
+ case GL_LINEAR:
+ d3dMagFilter = D3DTEXF_LINEAR;
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ return d3dMagFilter;
+}
+
+void ConvertMinFilter(GLenum minFilter,
+ D3DTEXTUREFILTERTYPE *d3dMinFilter,
+ D3DTEXTUREFILTERTYPE *d3dMipFilter,
+ float *d3dLodBias,
+ float maxAnisotropy,
+ size_t baseLevel)
+{
+ switch (minFilter)
+ {
+ case GL_NEAREST:
+ *d3dMinFilter = D3DTEXF_POINT;
+ *d3dMipFilter = D3DTEXF_NONE;
+ break;
+ case GL_LINEAR:
+ *d3dMinFilter = D3DTEXF_LINEAR;
+ *d3dMipFilter = D3DTEXF_NONE;
+ break;
+ case GL_NEAREST_MIPMAP_NEAREST:
+ *d3dMinFilter = D3DTEXF_POINT;
+ *d3dMipFilter = D3DTEXF_POINT;
+ break;
+ case GL_LINEAR_MIPMAP_NEAREST:
+ *d3dMinFilter = D3DTEXF_LINEAR;
+ *d3dMipFilter = D3DTEXF_POINT;
+ break;
+ case GL_NEAREST_MIPMAP_LINEAR:
+ *d3dMinFilter = D3DTEXF_POINT;
+ *d3dMipFilter = D3DTEXF_LINEAR;
+ break;
+ case GL_LINEAR_MIPMAP_LINEAR:
+ *d3dMinFilter = D3DTEXF_LINEAR;
+ *d3dMipFilter = D3DTEXF_LINEAR;
+ break;
+ default:
+ *d3dMinFilter = D3DTEXF_POINT;
+ *d3dMipFilter = D3DTEXF_NONE;
+ UNREACHABLE();
+ }
+
+ // Disabling mipmapping will always sample from level 0 of the texture. It is possible to work
+ // around this by modifying D3DSAMP_MAXMIPLEVEL to force a specific mip level to become the
+ // lowest sampled mip level and using a large negative value for D3DSAMP_MIPMAPLODBIAS to
+ // ensure that only the base mip level is sampled.
+ if (baseLevel > 0 && *d3dMipFilter == D3DTEXF_NONE)
+ {
+ *d3dMipFilter = D3DTEXF_POINT;
+ *d3dLodBias = -static_cast<float>(gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
+ }
+ else
+ {
+ *d3dLodBias = 0.0f;
+ }
+
+ if (maxAnisotropy > 1.0f)
+ {
+ *d3dMinFilter = D3DTEXF_ANISOTROPIC;
+ }
+}
+
+D3DQUERYTYPE ConvertQueryType(gl::QueryType type)
+{
+ switch (type)
+ {
+ case gl::QueryType::AnySamples:
+ case gl::QueryType::AnySamplesConservative:
+ return D3DQUERYTYPE_OCCLUSION;
+ case gl::QueryType::CommandsCompleted:
+ return D3DQUERYTYPE_EVENT;
+ default:
+ UNREACHABLE();
+ return static_cast<D3DQUERYTYPE>(0);
+ }
+}
+
+D3DMULTISAMPLE_TYPE GetMultisampleType(GLuint samples)
+{
+ return (samples > 1) ? static_cast<D3DMULTISAMPLE_TYPE>(samples) : D3DMULTISAMPLE_NONE;
+}
+
+} // namespace gl_d3d9
+
+namespace d3d9_gl
+{
+
+unsigned int GetReservedVaryingVectors()
+{
+ // We reserve two registers for "dx_Position" and "gl_Position". The spec says they
+ // don't count towards the varying limit, so we must make space for them. We also
+ // reserve the last register since it can only pass a PSIZE, and not any arbitrary
+ // varying.
+ return 3;
+}
+
+unsigned int GetReservedVertexUniformVectors()
+{
+ return 3; // dx_ViewCoords, dx_ViewAdjust and dx_DepthRange.
+}
+
+unsigned int GetReservedFragmentUniformVectors()
+{
+ return 4; // dx_ViewCoords, dx_DepthFront, dx_DepthRange, dx_FragCoordoffset.
+}
+
+GLsizei GetSamplesCount(D3DMULTISAMPLE_TYPE type)
+{
+ return (type != D3DMULTISAMPLE_NONMASKABLE) ? type : 0;
+}
+
+bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format)
+{
+ GLenum internalFormat = d3d9::GetD3DFormatInfo(d3dformat).info().glInternalFormat;
+ GLenum convertedFormat = gl::GetSizedInternalFormatInfo(internalFormat).format;
+ return convertedFormat == format;
+}
+
+static gl::TextureCaps GenerateTextureFormatCaps(GLenum internalFormat,
+ IDirect3D9 *d3d9,
+ D3DDEVTYPE deviceType,
+ UINT adapter,
+ D3DFORMAT adapterFormat)
+{
+ gl::TextureCaps textureCaps;
+
+ const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalFormat);
+ const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalFormat);
+
+ if (d3dFormatInfo.texFormat != D3DFMT_UNKNOWN)
+ {
+ if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0)
+ {
+ textureCaps.texturable = SUCCEEDED(d3d9->CheckDeviceFormat(
+ adapter, deviceType, adapterFormat, 0, D3DRTYPE_TEXTURE, d3dFormatInfo.texFormat));
+ }
+ else
+ {
+ textureCaps.texturable =
+ SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, 0,
+ D3DRTYPE_TEXTURE, d3dFormatInfo.texFormat)) &&
+ SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, 0,
+ D3DRTYPE_CUBETEXTURE, d3dFormatInfo.texFormat));
+ if (textureCaps.texturable && (formatInfo.colorEncoding == GL_SRGB))
+ {
+ textureCaps.texturable =
+ SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat,
+ D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE,
+ d3dFormatInfo.texFormat)) &&
+ SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat,
+ D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_CUBETEXTURE,
+ d3dFormatInfo.texFormat));
+ }
+ }
+
+ textureCaps.filterable = SUCCEEDED(
+ d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_QUERY_FILTER,
+ D3DRTYPE_TEXTURE, d3dFormatInfo.texFormat));
+ }
+
+ if (d3dFormatInfo.renderFormat != D3DFMT_UNKNOWN)
+ {
+ textureCaps.textureAttachment = SUCCEEDED(
+ d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_RENDERTARGET,
+ D3DRTYPE_TEXTURE, d3dFormatInfo.renderFormat));
+ if (textureCaps.textureAttachment && (formatInfo.colorEncoding == GL_SRGB))
+ {
+ textureCaps.textureAttachment = SUCCEEDED(d3d9->CheckDeviceFormat(
+ adapter, deviceType, adapterFormat, D3DUSAGE_QUERY_SRGBWRITE, D3DRTYPE_TEXTURE,
+ d3dFormatInfo.renderFormat));
+ }
+
+ if ((formatInfo.depthBits > 0 || formatInfo.stencilBits > 0) &&
+ !textureCaps.textureAttachment)
+ {
+ textureCaps.textureAttachment = SUCCEEDED(
+ d3d9->CheckDeviceFormat(adapter, deviceType, adapterFormat, D3DUSAGE_DEPTHSTENCIL,
+ D3DRTYPE_TEXTURE, d3dFormatInfo.renderFormat));
+ }
+ textureCaps.renderbuffer = textureCaps.textureAttachment;
+ textureCaps.blendable = textureCaps.renderbuffer;
+
+ textureCaps.sampleCounts.insert(1);
+ for (unsigned int i = D3DMULTISAMPLE_2_SAMPLES; i <= D3DMULTISAMPLE_16_SAMPLES; i++)
+ {
+ D3DMULTISAMPLE_TYPE multisampleType = D3DMULTISAMPLE_TYPE(i);
+
+ HRESULT result = d3d9->CheckDeviceMultiSampleType(
+ adapter, deviceType, d3dFormatInfo.renderFormat, TRUE, multisampleType, nullptr);
+ if (SUCCEEDED(result))
+ {
+ textureCaps.sampleCounts.insert(i);
+ }
+ }
+ }
+
+ return textureCaps;
+}
+
+void GenerateCaps(IDirect3D9 *d3d9,
+ IDirect3DDevice9 *device,
+ D3DDEVTYPE deviceType,
+ UINT adapter,
+ gl::Caps *caps,
+ gl::TextureCapsMap *textureCapsMap,
+ gl::Extensions *extensions,
+ gl::Limitations *limitations)
+{
+ D3DCAPS9 deviceCaps;
+ if (FAILED(d3d9->GetDeviceCaps(adapter, deviceType, &deviceCaps)))
+ {
+ // Can't continue with out device caps
+ return;
+ }
+
+ D3DDISPLAYMODE currentDisplayMode;
+ d3d9->GetAdapterDisplayMode(adapter, &currentDisplayMode);
+
+ GLuint maxSamples = 0;
+ for (GLenum internalFormat : gl::GetAllSizedInternalFormats())
+ {
+ gl::TextureCaps textureCaps = GenerateTextureFormatCaps(internalFormat, d3d9, deviceType,
+ adapter, currentDisplayMode.Format);
+ textureCapsMap->insert(internalFormat, textureCaps);
+
+ maxSamples = std::max(maxSamples, textureCaps.getMaxSamples());
+ }
+
+ // GL core feature limits
+ caps->maxElementIndex = static_cast<GLint64>(std::numeric_limits<unsigned int>::max());
+
+ // 3D textures are unimplemented in D3D9
+ caps->max3DTextureSize = 1;
+
+ // Only one limit in GL, use the minimum dimension
+ caps->max2DTextureSize = std::min(deviceCaps.MaxTextureWidth, deviceCaps.MaxTextureHeight);
+
+ // D3D treats cube maps as a special case of 2D textures
+ caps->maxCubeMapTextureSize = caps->max2DTextureSize;
+
+ // Array textures are not available in D3D9
+ caps->maxArrayTextureLayers = 1;
+
+ // ES3-only feature
+ caps->maxLODBias = 0.0f;
+
+ // No specific limits on render target size, maximum 2D texture size is equivalent
+ caps->maxRenderbufferSize = caps->max2DTextureSize;
+
+ // Draw buffers are not supported in D3D9
+ caps->maxDrawBuffers = 1;
+ caps->maxColorAttachments = 1;
+
+ // No specific limits on viewport size, maximum 2D texture size is equivalent
+ caps->maxViewportWidth = caps->max2DTextureSize;
+ caps->maxViewportHeight = caps->maxViewportWidth;
+
+ // Point size is clamped to 1.0f when the shader model is less than 3
+ caps->minAliasedPointSize = 1.0f;
+ caps->maxAliasedPointSize =
+ ((D3DSHADER_VERSION_MAJOR(deviceCaps.PixelShaderVersion) >= 3) ? deviceCaps.MaxPointSize
+ : 1.0f);
+
+ // Wide lines not supported
+ caps->minAliasedLineWidth = 1.0f;
+ caps->maxAliasedLineWidth = 1.0f;
+
+ // Primitive count limits (unused in ES2)
+ caps->maxElementsIndices = 0;
+ caps->maxElementsVertices = 0;
+
+ // Program and shader binary formats (no supported shader binary formats)
+ caps->programBinaryFormats.push_back(GL_PROGRAM_BINARY_ANGLE);
+
+ caps->vertexHighpFloat.setIEEEFloat();
+ caps->vertexMediumpFloat.setIEEEFloat();
+ caps->vertexLowpFloat.setIEEEFloat();
+ caps->fragmentHighpFloat.setIEEEFloat();
+ caps->fragmentMediumpFloat.setIEEEFloat();
+ caps->fragmentLowpFloat.setIEEEFloat();
+
+ // Some (most) hardware only supports single-precision floating-point numbers,
+ // which can accurately represent integers up to +/-16777216
+ caps->vertexHighpInt.setSimulatedInt(24);
+ caps->vertexMediumpInt.setSimulatedInt(24);
+ caps->vertexLowpInt.setSimulatedInt(24);
+ caps->fragmentHighpInt.setSimulatedInt(24);
+ caps->fragmentMediumpInt.setSimulatedInt(24);
+ caps->fragmentLowpInt.setSimulatedInt(24);
+
+ // WaitSync is ES3-only, set to zero
+ caps->maxServerWaitTimeout = 0;
+
+ // Vertex shader limits
+ caps->maxVertexAttributes = 16;
+ // Vertex Attrib Binding not supported.
+ caps->maxVertexAttribBindings = caps->maxVertexAttributes;
+
+ const size_t MAX_VERTEX_CONSTANT_VECTORS_D3D9 = 256;
+ caps->maxVertexUniformVectors =
+ MAX_VERTEX_CONSTANT_VECTORS_D3D9 - GetReservedVertexUniformVectors();
+ caps->maxShaderUniformComponents[gl::ShaderType::Vertex] = caps->maxVertexUniformVectors * 4;
+
+ caps->maxShaderUniformBlocks[gl::ShaderType::Vertex] = 0;
+
+ // SM3 only supports 12 output variables, but the special 12th register is only for PSIZE.
+ const unsigned int MAX_VERTEX_OUTPUT_VECTORS_SM3 = 12 - GetReservedVaryingVectors();
+ const unsigned int MAX_VERTEX_OUTPUT_VECTORS_SM2 = 10 - GetReservedVaryingVectors();
+ caps->maxVertexOutputComponents =
+ ((deviceCaps.VertexShaderVersion >= D3DVS_VERSION(3, 0)) ? MAX_VERTEX_OUTPUT_VECTORS_SM3
+ : MAX_VERTEX_OUTPUT_VECTORS_SM2) *
+ 4;
+
+ // Only Direct3D 10 ready devices support all the necessary vertex texture formats.
+ // We test this using D3D9 by checking support for the R16F format.
+ if (deviceCaps.VertexShaderVersion >= D3DVS_VERSION(3, 0) &&
+ SUCCEEDED(d3d9->CheckDeviceFormat(adapter, deviceType, currentDisplayMode.Format,
+ D3DUSAGE_QUERY_VERTEXTEXTURE, D3DRTYPE_TEXTURE,
+ D3DFMT_R16F)))
+ {
+ const size_t MAX_TEXTURE_IMAGE_UNITS_VTF_SM3 = 4;
+ caps->maxShaderTextureImageUnits[gl::ShaderType::Vertex] = MAX_TEXTURE_IMAGE_UNITS_VTF_SM3;
+ }
+ else
+ {
+ caps->maxShaderTextureImageUnits[gl::ShaderType::Vertex] = 0;
+ }
+
+ // Fragment shader limits
+ const size_t MAX_PIXEL_CONSTANT_VECTORS_SM3 = 224;
+ const size_t MAX_PIXEL_CONSTANT_VECTORS_SM2 = 32;
+ caps->maxFragmentUniformVectors =
+ ((deviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) ? MAX_PIXEL_CONSTANT_VECTORS_SM3
+ : MAX_PIXEL_CONSTANT_VECTORS_SM2) -
+ GetReservedFragmentUniformVectors();
+ caps->maxShaderUniformComponents[gl::ShaderType::Fragment] =
+ caps->maxFragmentUniformVectors * 4;
+ caps->maxShaderUniformBlocks[gl::ShaderType::Fragment] = 0;
+ caps->maxFragmentInputComponents = caps->maxVertexOutputComponents;
+ caps->maxShaderTextureImageUnits[gl::ShaderType::Fragment] = 16;
+ caps->minProgramTexelOffset = 0;
+ caps->maxProgramTexelOffset = 0;
+
+ // Aggregate shader limits (unused in ES2)
+ caps->maxUniformBufferBindings = 0;
+ caps->maxUniformBlockSize = 0;
+ caps->uniformBufferOffsetAlignment = 0;
+ caps->maxCombinedUniformBlocks = 0;
+ caps->maxCombinedShaderUniformComponents[gl::ShaderType::Vertex] = 0;
+ caps->maxCombinedShaderUniformComponents[gl::ShaderType::Fragment] = 0;
+ caps->maxVaryingComponents = 0;
+
+ // Aggregate shader limits
+ caps->maxVaryingVectors = caps->maxVertexOutputComponents / 4;
+ caps->maxCombinedTextureImageUnits = caps->maxShaderTextureImageUnits[gl::ShaderType::Vertex] +
+ caps->maxShaderTextureImageUnits[gl::ShaderType::Fragment];
+
+ // Transform feedback limits
+ caps->maxTransformFeedbackInterleavedComponents = 0;
+ caps->maxTransformFeedbackSeparateAttributes = 0;
+ caps->maxTransformFeedbackSeparateComponents = 0;
+
+ // Multisample limits
+ caps->maxSamples = maxSamples;
+
+ // GL extension support
+ extensions->setTextureExtensionSupport(*textureCapsMap);
+ extensions->elementIndexUintOES = deviceCaps.MaxVertexIndex >= (1 << 16);
+ extensions->getProgramBinaryOES = true;
+ extensions->rgb8Rgba8OES = true;
+ extensions->readFormatBgraEXT = true;
+ extensions->pixelBufferObjectNV = false;
+ extensions->mapbufferOES = false;
+ extensions->mapBufferRangeEXT = false;
+
+ // D3D does not allow depth textures to have more than one mipmap level OES_depth_texture
+ // allows for that so we can't implement full support with the D3D9 back end.
+ extensions->depthTextureOES = false;
+
+ // textureRgEXT is emulated and not performant.
+ extensions->textureRgEXT = false;
+
+ // GL_KHR_parallel_shader_compile
+ extensions->parallelShaderCompileKHR = true;
+
+ D3DADAPTER_IDENTIFIER9 adapterId = {};
+ if (SUCCEEDED(d3d9->GetAdapterIdentifier(adapter, 0, &adapterId)))
+ {
+ // ATI cards on XP have problems with non-power-of-two textures.
+ extensions->textureNpotOES =
+ !(deviceCaps.TextureCaps & D3DPTEXTURECAPS_POW2) &&
+ !(deviceCaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2) &&
+ !(deviceCaps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) &&
+ !(!isWindowsVistaOrGreater() && IsAMD(adapterId.VendorId));
+
+ // Disable depth texture support on AMD cards (See ANGLE issue 839)
+ if (IsAMD(adapterId.VendorId))
+ {
+ extensions->depthTextureANGLE = false;
+ extensions->depthTextureOES = false;
+ }
+ }
+ else
+ {
+ extensions->textureNpotOES = false;
+ }
+
+ extensions->drawBuffersEXT = false;
+ extensions->textureStorageEXT = true;
+
+ // Must support a minimum of 2:1 anisotropy for max anisotropy to be considered supported, per
+ // the spec
+ extensions->textureFilterAnisotropicEXT =
+ (deviceCaps.RasterCaps & D3DPRASTERCAPS_ANISOTROPY) != 0 && deviceCaps.MaxAnisotropy >= 2;
+ caps->maxTextureAnisotropy = static_cast<GLfloat>(deviceCaps.MaxAnisotropy);
+
+ // Check occlusion query support by trying to create one
+ IDirect3DQuery9 *occlusionQuery = nullptr;
+ extensions->occlusionQueryBooleanEXT =
+ SUCCEEDED(device->CreateQuery(D3DQUERYTYPE_OCCLUSION, &occlusionQuery)) && occlusionQuery;
+ SafeRelease(occlusionQuery);
+
+ // Check event query support by trying to create one
+ IDirect3DQuery9 *eventQuery = nullptr;
+ extensions->fenceNV =
+ SUCCEEDED(device->CreateQuery(D3DQUERYTYPE_EVENT, &eventQuery)) && eventQuery;
+ SafeRelease(eventQuery);
+
+ extensions->disjointTimerQueryEXT = false;
+ extensions->robustnessEXT = true;
+ // It seems that only DirectX 10 and higher enforce the well-defined behavior of always
+ // returning zero values when out-of-bounds reads. See
+ // https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_robustness.txt
+ extensions->robustBufferAccessBehaviorKHR = false;
+ extensions->blendMinmaxEXT = true;
+ // Although according to
+ // https://docs.microsoft.com/en-us/windows/desktop/direct3ddxgi/format-support-for-direct3d-feature-level-9-1-hardware
+ // D3D9 doesn't have full blending capability for RGBA32F. But turns out it could provide
+ // correct blending result in reality. As a result of some regression reports by client app, we
+ // decided to turn floatBlendEXT on for D3D9
+ extensions->floatBlendEXT = true;
+ extensions->framebufferBlitANGLE = true;
+ extensions->framebufferMultisampleANGLE = true;
+ extensions->instancedArraysANGLE = deviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0);
+ // D3D9 requires at least one attribute that has a divisor of 0, which isn't required by the EXT
+ // extension
+ extensions->instancedArraysEXT = false;
+ extensions->packReverseRowOrderANGLE = true;
+ extensions->standardDerivativesOES =
+ (deviceCaps.PS20Caps.Caps & D3DPS20CAPS_GRADIENTINSTRUCTIONS) != 0;
+ extensions->shaderTextureLodEXT = true;
+ extensions->fragDepthEXT = true;
+ extensions->textureUsageANGLE = true;
+ extensions->translatedShaderSourceANGLE = true;
+ extensions->fboRenderMipmapOES = true;
+ extensions->discardFramebufferEXT = false; // It would be valid to set this to true, since
+ // glDiscardFramebufferEXT is just a hint
+ extensions->colorBufferFloatEXT = false;
+ extensions->debugMarkerEXT = true;
+ extensions->EGLImageOES = true;
+ extensions->EGLImageExternalOES = true;
+ extensions->unpackSubimageEXT = true;
+ extensions->packSubimageNV = true;
+ extensions->syncQueryCHROMIUM = extensions->fenceNV;
+ extensions->copyTextureCHROMIUM = true;
+ extensions->textureBorderClampOES = true;
+ extensions->videoTextureWEBGL = true;
+
+ // D3D9 has no concept of separate masks and refs for front and back faces in the depth stencil
+ // state.
+ limitations->noSeparateStencilRefsAndMasks = true;
+
+ // D3D9 shader models have limited support for looping, so the Appendix A
+ // index/loop limitations are necessary. Workarounds that are needed to
+ // support dynamic indexing of vectors on HLSL also don't work on D3D9.
+ limitations->shadersRequireIndexedLoopValidation = true;
+
+ // D3D9 cannot support constant color and alpha blend funcs together
+ limitations->noSimultaneousConstantColorAndAlphaBlendFunc = true;
+
+ // D3D9 cannot support unclamped constant blend color
+ limitations->noUnclampedBlendColor = true;
+
+ // D3D9 cannot support packing more than one variable to a single varying.
+ // TODO(jmadill): Implement more sophisticated component packing in D3D9.
+ limitations->noFlexibleVaryingPacking = true;
+
+ // D3D9 does not support vertex attribute aliasing
+ limitations->noVertexAttributeAliasing = true;
+
+ // D3D9 does not support compressed textures where the base mip level is not a multiple of 4
+ limitations->compressedBaseMipLevelMultipleOfFour = true;
+}
+
+} // namespace d3d9_gl
+
+namespace d3d9
+{
+
+GLuint ComputeBlockSize(D3DFORMAT format, GLuint width, GLuint height)
+{
+ const D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(format);
+ GLuint numBlocksWide = (width + d3dFormatInfo.blockWidth - 1) / d3dFormatInfo.blockWidth;
+ GLuint numBlocksHight = (height + d3dFormatInfo.blockHeight - 1) / d3dFormatInfo.blockHeight;
+ return (d3dFormatInfo.pixelBytes * numBlocksWide * numBlocksHight);
+}
+
+void MakeValidSize(bool isImage,
+ D3DFORMAT format,
+ GLsizei *requestWidth,
+ GLsizei *requestHeight,
+ int *levelOffset)
+{
+ const D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(format);
+
+ int upsampleCount = 0;
+ // Don't expand the size of full textures that are at least (blockWidth x blockHeight) already.
+ if (isImage || *requestWidth < static_cast<GLsizei>(d3dFormatInfo.blockWidth) ||
+ *requestHeight < static_cast<GLsizei>(d3dFormatInfo.blockHeight))
+ {
+ while (*requestWidth % d3dFormatInfo.blockWidth != 0 ||
+ *requestHeight % d3dFormatInfo.blockHeight != 0)
+ {
+ *requestWidth <<= 1;
+ *requestHeight <<= 1;
+ upsampleCount++;
+ }
+ }
+ *levelOffset = upsampleCount;
+}
+
+void InitializeFeatures(angle::FeaturesD3D *features)
+{
+ ANGLE_FEATURE_CONDITION(features, mrtPerfWorkaround, true);
+ ANGLE_FEATURE_CONDITION(features, setDataFasterThanImageUpload, false);
+ ANGLE_FEATURE_CONDITION(features, setDataFasterThanImageUploadOn128bitFormats, false);
+ ANGLE_FEATURE_CONDITION(features, useInstancedPointSpriteEmulation, false);
+
+ // TODO(jmadill): Disable workaround when we have a fixed compiler DLL.
+ ANGLE_FEATURE_CONDITION(features, expandIntegerPowExpressions, true);
+
+ // crbug.com/1011627 Turn this on for D3D9.
+ ANGLE_FEATURE_CONDITION(features, allowClearForRobustResourceInit, true);
+}
+
+} // namespace d3d9
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h
new file mode 100644
index 0000000000..b900e9c44c
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h
@@ -0,0 +1,105 @@
+//
+// Copyright 2002 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.
+//
+
+// renderer9_utils.h: Conversion functions and other utility routines
+// specific to the D3D9 renderer
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D9_RENDERER9UTILS_H_
+#define LIBANGLE_RENDERER_D3D_D3D9_RENDERER9UTILS_H_
+
+#include "common/Color.h"
+#include "libANGLE/Caps.h"
+#include "libANGLE/Error.h"
+#include "platform/FeaturesD3D_autogen.h"
+
+namespace gl
+{
+class FramebufferAttachment;
+}
+
+namespace rx
+{
+class RenderTarget9;
+
+namespace gl_d3d9
+{
+
+D3DCMPFUNC ConvertComparison(GLenum comparison);
+D3DCOLOR ConvertColor(gl::ColorF color);
+D3DBLEND ConvertBlendFunc(GLenum blend);
+D3DBLENDOP ConvertBlendOp(GLenum blendOp);
+D3DSTENCILOP ConvertStencilOp(GLenum stencilOp);
+D3DTEXTUREADDRESS ConvertTextureWrap(GLenum wrap);
+D3DCULL ConvertCullMode(gl::CullFaceMode cullFace, GLenum frontFace);
+D3DCUBEMAP_FACES ConvertCubeFace(gl::TextureTarget cubeFace);
+DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha);
+D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter, float maxAnisotropy);
+void ConvertMinFilter(GLenum minFilter,
+ D3DTEXTUREFILTERTYPE *d3dMinFilter,
+ D3DTEXTUREFILTERTYPE *d3dMipFilter,
+ float *d3dLodBias,
+ float maxAnisotropy,
+ size_t baseLevel);
+D3DQUERYTYPE ConvertQueryType(gl::QueryType type);
+
+D3DMULTISAMPLE_TYPE GetMultisampleType(GLuint samples);
+
+} // namespace gl_d3d9
+
+namespace d3d9_gl
+{
+
+unsigned int GetReservedVaryingVectors();
+
+unsigned int GetReservedVertexUniformVectors();
+
+unsigned int GetReservedFragmentUniformVectors();
+
+GLsizei GetSamplesCount(D3DMULTISAMPLE_TYPE type);
+
+bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format);
+
+void GenerateCaps(IDirect3D9 *d3d9,
+ IDirect3DDevice9 *device,
+ D3DDEVTYPE deviceType,
+ UINT adapter,
+ gl::Caps *caps,
+ gl::TextureCapsMap *textureCapsMap,
+ gl::Extensions *extensions,
+ gl::Limitations *limitations);
+} // namespace d3d9_gl
+
+namespace d3d9
+{
+
+GLuint ComputeBlockSize(D3DFORMAT format, GLuint width, GLuint height);
+
+void MakeValidSize(bool isImage,
+ D3DFORMAT format,
+ GLsizei *requestWidth,
+ GLsizei *requestHeight,
+ int *levelOffset);
+
+inline bool isDeviceLostError(HRESULT errorCode)
+{
+ switch (errorCode)
+ {
+ case D3DERR_DRIVERINTERNALERROR:
+ case D3DERR_DEVICELOST:
+ case D3DERR_DEVICEHUNG:
+ case D3DERR_DEVICEREMOVED:
+ return true;
+ default:
+ return false;
+ }
+}
+
+void InitializeFeatures(angle::FeaturesD3D *features);
+} // namespace d3d9
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D9_RENDERER9UTILS_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskpremultps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskpremultps.h
new file mode 100644
index 0000000000..04868aeb9c
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskpremultps.h
@@ -0,0 +1,50 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+// Parameters:
+//
+// float4 add;
+// float4 mult;
+// sampler2D tex;
+//
+//
+// Registers:
+//
+// Name Reg Size
+// ------------ ----- ----
+// mult c0 1
+// add c1 1
+// tex s0 1
+//
+
+ ps_2_0
+ dcl t0.xy
+ dcl_2d s0
+ texld r0, t0, s0
+ mul r0.xyz, r0.w, r0
+ mov r1, c0
+ mad r0, r0, r1, c1
+ mov oC0, r0
+
+// approximately 5 instruction slots used (1 texture, 4 arithmetic)
+#endif
+
+const BYTE g_ps20_componentmaskpremultps[] = {
+ 0, 2, 255, 255, 254, 255, 50, 0, 67, 84, 65, 66, 28, 0, 0, 0, 143, 0, 0,
+ 0, 0, 2, 255, 255, 3, 0, 0, 0, 28, 0, 0, 0, 0, 1, 0, 0, 136, 0,
+ 0, 0, 88, 0, 0, 0, 2, 0, 1, 0, 1, 0, 0, 0, 92, 0, 0, 0, 0,
+ 0, 0, 0, 108, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 92, 0, 0, 0,
+ 0, 0, 0, 0, 113, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 120, 0, 0,
+ 0, 0, 0, 0, 0, 97, 100, 100, 0, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 109, 117, 108, 116, 0, 116, 101, 120, 0, 171, 171, 171, 4,
+ 0, 12, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 112, 115, 95, 50,
+ 95, 48, 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, 171, 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, 1, 0, 15, 128, 0, 0, 228, 160, 4, 0, 0, 4, 0, 0, 15, 128, 0,
+ 0, 228, 128, 1, 0, 228, 128, 1, 0, 228, 160, 1, 0, 0, 2, 0, 8, 15, 128,
+ 0, 0, 228, 128, 255, 255, 0, 0};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskps.h
new file mode 100644
index 0000000000..06673ae5f7
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskps.h
@@ -0,0 +1,48 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+// Parameters:
+//
+// float4 add;
+// float4 mult;
+// sampler2D tex;
+//
+//
+// Registers:
+//
+// Name Reg Size
+// ------------ ----- ----
+// mult c0 1
+// add c1 1
+// tex s0 1
+//
+
+ ps_2_0
+ dcl t0.xy
+ dcl_2d s0
+ texld r0, t0, s0
+ mov r1, c0
+ mad r0, r0, r1, c1
+ mov oC0, r0
+
+// approximately 4 instruction slots used (1 texture, 3 arithmetic)
+#endif
+
+const BYTE g_ps20_componentmaskps[] = {
+ 0, 2, 255, 255, 254, 255, 50, 0, 67, 84, 65, 66, 28, 0, 0, 0, 143, 0, 0,
+ 0, 0, 2, 255, 255, 3, 0, 0, 0, 28, 0, 0, 0, 0, 1, 0, 0, 136, 0,
+ 0, 0, 88, 0, 0, 0, 2, 0, 1, 0, 1, 0, 0, 0, 92, 0, 0, 0, 0,
+ 0, 0, 0, 108, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 92, 0, 0, 0,
+ 0, 0, 0, 0, 113, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 120, 0, 0,
+ 0, 0, 0, 0, 0, 97, 100, 100, 0, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 109, 117, 108, 116, 0, 116, 101, 120, 0, 171, 171, 171, 4,
+ 0, 12, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 112, 115, 95, 50,
+ 95, 48, 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, 171, 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, 1, 0, 0, 2, 1, 0, 15, 128, 0, 0, 228, 160, 4, 0, 0, 4, 0, 0,
+ 15, 128, 0, 0, 228, 128, 1, 0, 228, 128, 1, 0, 228, 160, 1, 0, 0, 2, 0,
+ 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskunmultps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskunmultps.h
new file mode 100644
index 0000000000..ad15364bb8
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskunmultps.h
@@ -0,0 +1,54 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+// Parameters:
+//
+// float4 add;
+// float4 mult;
+// sampler2D tex;
+//
+//
+// Registers:
+//
+// Name Reg Size
+// ------------ ----- ----
+// mult c0 1
+// add c1 1
+// tex s0 1
+//
+
+ ps_2_0
+ 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 r1, c0
+ mad r0, r0, r1, c1
+ mov oC0, r0
+
+// approximately 7 instruction slots used (1 texture, 6 arithmetic)
+#endif
+
+const BYTE g_ps20_componentmaskunmultps[] = {
+ 0, 2, 255, 255, 254, 255, 50, 0, 67, 84, 65, 66, 28, 0, 0, 0, 143, 0, 0,
+ 0, 0, 2, 255, 255, 3, 0, 0, 0, 28, 0, 0, 0, 0, 1, 0, 0, 136, 0,
+ 0, 0, 88, 0, 0, 0, 2, 0, 1, 0, 1, 0, 0, 0, 92, 0, 0, 0, 0,
+ 0, 0, 0, 108, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 92, 0, 0, 0,
+ 0, 0, 0, 0, 113, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 120, 0, 0,
+ 0, 0, 0, 0, 0, 97, 100, 100, 0, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 109, 117, 108, 116, 0, 116, 101, 120, 0, 171, 171, 171, 4,
+ 0, 12, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 112, 115, 95, 50,
+ 95, 48, 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, 171, 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, 1, 0, 15, 128,
+ 0, 0, 228, 160, 4, 0, 0, 4, 0, 0, 15, 128, 0, 0, 228, 128, 1, 0, 228,
+ 128, 1, 0, 228, 160, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255,
+ 0, 0};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/luminancepremultps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/luminancepremultps.h
new file mode 100644
index 0000000000..274a7824f9
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/luminancepremultps.h
@@ -0,0 +1,50 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+// Parameters:
+//
+// float4 add;
+// float4 mult;
+// sampler2D tex;
+//
+//
+// Registers:
+//
+// Name Reg Size
+// ------------ ----- ----
+// mult c0 1
+// add c1 1
+// tex s0 1
+//
+
+ ps_2_0
+ dcl t0.xy
+ dcl_2d s0
+ texld r0, t0, s0
+ mul r0.xyz, r0.w, r0.x
+ mov r1, c0
+ mad r0, r0, r1, c1
+ mov oC0, r0
+
+// approximately 5 instruction slots used (1 texture, 4 arithmetic)
+#endif
+
+const BYTE g_ps20_luminancepremultps[] = {
+ 0, 2, 255, 255, 254, 255, 50, 0, 67, 84, 65, 66, 28, 0, 0, 0, 143, 0, 0,
+ 0, 0, 2, 255, 255, 3, 0, 0, 0, 28, 0, 0, 0, 0, 1, 0, 0, 136, 0,
+ 0, 0, 88, 0, 0, 0, 2, 0, 1, 0, 1, 0, 0, 0, 92, 0, 0, 0, 0,
+ 0, 0, 0, 108, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 92, 0, 0, 0,
+ 0, 0, 0, 0, 113, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 120, 0, 0,
+ 0, 0, 0, 0, 0, 97, 100, 100, 0, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 109, 117, 108, 116, 0, 116, 101, 120, 0, 171, 171, 171, 4,
+ 0, 12, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 112, 115, 95, 50,
+ 95, 48, 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, 171, 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, 0, 128, 1, 0,
+ 0, 2, 1, 0, 15, 128, 0, 0, 228, 160, 4, 0, 0, 4, 0, 0, 15, 128, 0,
+ 0, 228, 128, 1, 0, 228, 128, 1, 0, 228, 160, 1, 0, 0, 2, 0, 8, 15, 128,
+ 0, 0, 228, 128, 255, 255, 0, 0};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/luminanceps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/luminanceps.h
new file mode 100644
index 0000000000..0be665c525
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/luminanceps.h
@@ -0,0 +1,53 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+// Parameters:
+//
+// float4 add;
+// float4 mult;
+// sampler2D tex;
+//
+//
+// Registers:
+//
+// Name Reg Size
+// ------------ ----- ----
+// mult c0 1
+// add c1 1
+// tex s0 1
+//
+
+ ps_2_0
+ dcl t0.xy
+ dcl_2d s0
+ texld r0, t0, s0
+ mov r1.xw, c0
+ mad r0.x, r0.x, r1.x, c1.x
+ mad r0.y, r0.w, r1.w, c1.w
+ mov r1.xyz, r0.x
+ mov r1.w, r0.y
+ mov oC0, r1
+
+// approximately 7 instruction slots used (1 texture, 6 arithmetic)
+#endif
+
+const BYTE g_ps20_luminanceps[] = {
+ 0, 2, 255, 255, 254, 255, 50, 0, 67, 84, 65, 66, 28, 0, 0, 0, 143, 0, 0,
+ 0, 0, 2, 255, 255, 3, 0, 0, 0, 28, 0, 0, 0, 0, 1, 0, 0, 136, 0,
+ 0, 0, 88, 0, 0, 0, 2, 0, 1, 0, 1, 0, 0, 0, 92, 0, 0, 0, 0,
+ 0, 0, 0, 108, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 92, 0, 0, 0,
+ 0, 0, 0, 0, 113, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 120, 0, 0,
+ 0, 0, 0, 0, 0, 97, 100, 100, 0, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 109, 117, 108, 116, 0, 116, 101, 120, 0, 171, 171, 171, 4,
+ 0, 12, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 112, 115, 95, 50,
+ 95, 48, 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, 171, 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, 1, 0, 0, 2, 1, 0, 9, 128, 0, 0, 228, 160, 4, 0, 0, 4, 0, 0,
+ 1, 128, 0, 0, 0, 128, 1, 0, 0, 128, 1, 0, 0, 160, 4, 0, 0, 4, 0,
+ 0, 2, 128, 0, 0, 255, 128, 1, 0, 255, 128, 1, 0, 255, 160, 1, 0, 0, 2,
+ 1, 0, 7, 128, 0, 0, 0, 128, 1, 0, 0, 2, 1, 0, 8, 128, 0, 0, 85,
+ 128, 1, 0, 0, 2, 0, 8, 15, 128, 1, 0, 228, 128, 255, 255, 0, 0};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/luminanceunmultps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/luminanceunmultps.h
new file mode 100644
index 0000000000..1100d0b088
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/luminanceunmultps.h
@@ -0,0 +1,54 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+// Parameters:
+//
+// float4 add;
+// float4 mult;
+// sampler2D tex;
+//
+//
+// Registers:
+//
+// Name Reg Size
+// ------------ ----- ----
+// mult c0 1
+// add c1 1
+// tex s0 1
+//
+
+ ps_2_0
+ dcl t0.xy
+ dcl_2d s0
+ texld r0, t0, s0
+ rcp r1.w, r0.w
+ mul r1.x, r0.x, r1.w
+ cmp r0.xyz, -r0.w, r0.x, r1.x
+ mov r1, c0
+ mad r0, r0, r1, c1
+ mov oC0, r0
+
+// approximately 7 instruction slots used (1 texture, 6 arithmetic)
+#endif
+
+const BYTE g_ps20_luminanceunmultps[] = {
+ 0, 2, 255, 255, 254, 255, 50, 0, 67, 84, 65, 66, 28, 0, 0, 0, 143, 0, 0,
+ 0, 0, 2, 255, 255, 3, 0, 0, 0, 28, 0, 0, 0, 0, 1, 0, 0, 136, 0,
+ 0, 0, 88, 0, 0, 0, 2, 0, 1, 0, 1, 0, 0, 0, 92, 0, 0, 0, 0,
+ 0, 0, 0, 108, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 92, 0, 0, 0,
+ 0, 0, 0, 0, 113, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 120, 0, 0,
+ 0, 0, 0, 0, 0, 97, 100, 100, 0, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 109, 117, 108, 116, 0, 116, 101, 120, 0, 171, 171, 171, 4,
+ 0, 12, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 112, 115, 95, 50,
+ 95, 48, 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, 171, 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,
+ 1, 128, 0, 0, 0, 128, 1, 0, 255, 128, 88, 0, 0, 4, 0, 0, 7, 128, 0,
+ 0, 255, 129, 0, 0, 0, 128, 1, 0, 0, 128, 1, 0, 0, 2, 1, 0, 15, 128,
+ 0, 0, 228, 160, 4, 0, 0, 4, 0, 0, 15, 128, 0, 0, 228, 128, 1, 0, 228,
+ 128, 1, 0, 228, 160, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255,
+ 0, 0};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/passthroughps.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/passthroughps.h
new file mode 100644
index 0000000000..0c17739e17
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/passthroughps.h
@@ -0,0 +1,37 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+// Parameters:
+//
+// sampler2D tex;
+//
+//
+// Registers:
+//
+// Name Reg Size
+// ------------ ----- ----
+// tex s0 1
+//
+
+ ps_2_0
+ dcl t0.xy
+ dcl_2d s0
+ texld r0, t0, s0
+ mov oC0, r0
+
+// approximately 2 instruction slots used (1 texture, 1 arithmetic)
+#endif
+
+const BYTE g_ps20_passthroughps[] = {
+ 0, 2, 255, 255, 254, 255, 33, 0, 67, 84, 65, 66, 28, 0, 0, 0, 75, 0,
+ 0, 0, 0, 2, 255, 255, 1, 0, 0, 0, 28, 0, 0, 0, 0, 1, 0, 0,
+ 68, 0, 0, 0, 48, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 52, 0,
+ 0, 0, 0, 0, 0, 0, 116, 101, 120, 0, 4, 0, 12, 0, 1, 0, 1, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 112, 115, 95, 50, 95, 48, 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, 171, 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,
+ 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/standardvs.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/standardvs.h
new file mode 100644
index 0000000000..e4d7e0e1a8
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/shaders/compiled/standardvs.h
@@ -0,0 +1,46 @@
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+// Parameters:
+//
+// float4 halfPixelSize;
+// float4 texcoordOffset;
+//
+//
+// Registers:
+//
+// Name Reg Size
+// -------------- ----- ----
+// halfPixelSize c0 1
+// texcoordOffset c1 1
+//
+
+ vs_2_0
+ def c2, 0.5, -0.5, 1, 0
+ dcl_position v0
+ add oPos, v0, c0
+ mad r0, v0, c2.xyzz, c2.xxww
+ mov oT0.zw, r0
+ mad oT0.xy, r0, c1.zwzw, c1
+
+// approximately 4 instruction slots used
+#endif
+
+const BYTE g_vs20_standardvs[] = {
+ 0, 2, 254, 255, 254, 255, 44, 0, 67, 84, 65, 66, 28, 0, 0, 0, 122, 0, 0,
+ 0, 0, 2, 254, 255, 2, 0, 0, 0, 28, 0, 0, 0, 0, 1, 0, 0, 115, 0,
+ 0, 0, 68, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 0,
+ 0, 0, 0, 100, 0, 0, 0, 2, 0, 1, 0, 1, 0, 0, 0, 84, 0, 0, 0,
+ 0, 0, 0, 0, 104, 97, 108, 102, 80, 105, 120, 101, 108, 83, 105, 122, 101, 0, 171,
+ 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 116, 101,
+ 120, 99, 111, 111, 114, 100, 79, 102, 102, 115, 101, 116, 0, 118, 115, 95, 50, 95, 48,
+ 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, 81, 0, 0, 5, 2, 0,
+ 15, 160, 0, 0, 0, 63, 0, 0, 0, 191, 0, 0, 128, 63, 0, 0, 0, 0, 31,
+ 0, 0, 2, 0, 0, 0, 128, 0, 0, 15, 144, 2, 0, 0, 3, 0, 0, 15, 192,
+ 0, 0, 228, 144, 0, 0, 228, 160, 4, 0, 0, 4, 0, 0, 15, 128, 0, 0, 228,
+ 144, 2, 0, 164, 160, 2, 0, 240, 160, 1, 0, 0, 2, 0, 0, 12, 224, 0, 0,
+ 228, 128, 4, 0, 0, 4, 0, 0, 3, 224, 0, 0, 228, 128, 1, 0, 238, 160, 1,
+ 0, 228, 160, 255, 255, 0, 0};
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/vertexconversion.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/vertexconversion.h
new file mode 100644
index 0000000000..fb172448d1
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/d3d9/vertexconversion.h
@@ -0,0 +1,197 @@
+//
+// Copyright 2002 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.
+//
+
+// vertexconversion.h: A library of vertex conversion classes that can be used to build
+// the FormatConverter objects used by the buffer conversion system.
+
+#ifndef LIBANGLE_RENDERER_D3D_D3D9_VERTEXCONVERSION_H_
+#define LIBANGLE_RENDERER_D3D_D3D9_VERTEXCONVERSION_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <limits>
+
+namespace rx
+{
+
+// Conversion types:
+// static const bool identity: true if this is an identity transform, false otherwise
+// static U convert(T): convert a single element from the input type to the output type
+// typedef ... OutputType: the type produced by this conversion
+
+template <class T>
+struct Identity
+{
+ static const bool identity = true;
+
+ typedef T OutputType;
+
+ static T convert(T x) { return x; }
+};
+
+template <class FromT, class ToT>
+struct Cast
+{
+ static const bool identity = false;
+
+ typedef ToT OutputType;
+
+ static ToT convert(FromT x) { return static_cast<ToT>(x); }
+};
+
+template <class T>
+struct Cast<T, T>
+{
+ static const bool identity = true;
+
+ typedef T OutputType;
+
+ static T convert(T x) { return static_cast<T>(x); }
+};
+
+template <class T>
+struct Normalize
+{
+ static const bool identity = false;
+
+ typedef float OutputType;
+
+ static float convert(T x)
+ {
+ typedef std::numeric_limits<T> NL;
+ float f = static_cast<float>(x);
+
+ if (NL::is_signed)
+ {
+ // const float => VC2008 computes it at compile time
+ // static const float => VC2008 computes it the first time we get here, stores it to
+ // memory with static guard and all that.
+ const float divisor = 1.0f / (2 * static_cast<float>(NL::max()) + 1);
+ return (2 * f + 1) * divisor;
+ }
+ else
+ {
+ return f / NL::max();
+ }
+ }
+};
+
+template <class FromType, std::size_t ScaleBits>
+struct FixedToFloat
+{
+ static const bool identity = false;
+
+ typedef float OutputType;
+
+ static float convert(FromType x)
+ {
+ const float divisor = 1.0f / static_cast<float>(static_cast<FromType>(1) << ScaleBits);
+ return static_cast<float>(x) * divisor;
+ }
+};
+
+// Widen types:
+// static const unsigned int initialWidth: number of components before conversion
+// static const unsigned int finalWidth: number of components after conversion
+
+// Float is supported at any size.
+template <std::size_t N>
+struct NoWiden
+{
+ static const std::size_t initialWidth = N;
+ static const std::size_t finalWidth = N;
+};
+
+// SHORT, norm-SHORT, norm-UNSIGNED_SHORT are supported but only with 2 or 4 components
+template <std::size_t N>
+struct WidenToEven
+{
+ static const std::size_t initialWidth = N;
+ static const std::size_t finalWidth = N + (N & 1);
+};
+
+template <std::size_t N>
+struct WidenToFour
+{
+ static const std::size_t initialWidth = N;
+ static const std::size_t finalWidth = 4;
+};
+
+// Most types have 0 and 1 that are just that.
+template <class T>
+struct SimpleDefaultValues
+{
+ static T zero() { return static_cast<T>(0); }
+ static T one() { return static_cast<T>(1); }
+};
+
+// But normalised types only store [0,1] or [-1,1] so 1.0 is represented by the max value.
+template <class T>
+struct NormalizedDefaultValues
+{
+ static T zero() { return static_cast<T>(0); }
+ static T one() { return std::numeric_limits<T>::max(); }
+};
+
+// Converter:
+// static const bool identity: true if this is an identity transform (with no widening)
+// static const std::size_t finalSize: number of bytes per output vertex
+// static void convertArray(const void *in, std::size_t stride, std::size_t n, void *out): convert
+// an array of vertices. Input may be strided, but output will be unstrided.
+
+template <class InT,
+ class WidenRule,
+ class Converter,
+ class DefaultValueRule = SimpleDefaultValues<InT>>
+struct VertexDataConverter
+{
+ typedef typename Converter::OutputType OutputType;
+ typedef InT InputType;
+
+ static const bool identity =
+ (WidenRule::initialWidth == WidenRule::finalWidth) && Converter::identity;
+ static const std::size_t finalSize = WidenRule::finalWidth * sizeof(OutputType);
+
+ static void convertArray(const uint8_t *input, size_t stride, size_t n, uint8_t *output)
+ {
+ OutputType *out = reinterpret_cast<OutputType *>(output);
+
+ for (std::size_t i = 0; i < n; i++)
+ {
+ const InputType *ein = reinterpret_cast<const InputType *>(input + i * stride);
+
+ copyComponent(out, ein, 0, static_cast<OutputType>(DefaultValueRule::zero()));
+ copyComponent(out, ein, 1, static_cast<OutputType>(DefaultValueRule::zero()));
+ copyComponent(out, ein, 2, static_cast<OutputType>(DefaultValueRule::zero()));
+ copyComponent(out, ein, 3, static_cast<OutputType>(DefaultValueRule::one()));
+
+ out += WidenRule::finalWidth;
+ }
+ }
+
+ private:
+ static void copyComponent(OutputType *out,
+ const InputType *in,
+ std::size_t elementindex,
+ OutputType defaultvalue)
+ {
+ if (WidenRule::finalWidth > elementindex)
+ {
+ if (WidenRule::initialWidth > elementindex)
+ {
+ out[elementindex] = Converter::convert(in[elementindex]);
+ }
+ else
+ {
+ out[elementindex] = defaultvalue;
+ }
+ }
+ }
+};
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_D3D9_VERTEXCONVERSION_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/driver_utils_d3d.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d/driver_utils_d3d.cpp
new file mode 100644
index 0000000000..1709f82868
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/driver_utils_d3d.cpp
@@ -0,0 +1,26 @@
+//
+// Copyright 2020 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.
+//
+
+// driver_utils_d3d.cpp: Information specific to the D3D driver
+
+#include "libANGLE/renderer/d3d/driver_utils_d3d.h"
+
+namespace rx
+{
+
+std::string GetDriverVersionString(LARGE_INTEGER driverVersion)
+{
+ std::stringstream versionString;
+ uint64_t intVersion = driverVersion.QuadPart;
+ constexpr uint64_t kMask16 = std::numeric_limits<uint16_t>::max();
+ versionString << ((intVersion >> 48) & kMask16) << ".";
+ versionString << ((intVersion >> 32) & kMask16) << ".";
+ versionString << ((intVersion >> 16) & kMask16) << ".";
+ versionString << (intVersion & kMask16);
+ return versionString.str();
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/driver_utils_d3d.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/driver_utils_d3d.h
new file mode 100644
index 0000000000..3b217838f9
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/driver_utils_d3d.h
@@ -0,0 +1,21 @@
+//
+// Copyright 2020 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.
+//
+
+// driver_utils_d3d.h: Information specific to the D3D driver
+
+#ifndef LIBANGLE_RENDERER_D3D_DRIVER_UTILS_D3D_H_
+#define LIBANGLE_RENDERER_D3D_DRIVER_UTILS_D3D_H_
+
+#include "libANGLE/angletypes.h"
+
+namespace rx
+{
+
+std::string GetDriverVersionString(LARGE_INTEGER driverVersion);
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_DRIVER_UTILS_D3D_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d/formatutilsD3D.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d/formatutilsD3D.h
new file mode 100644
index 0000000000..f0e876d49d
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d/formatutilsD3D.h
@@ -0,0 +1,24 @@
+//
+// 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.
+//
+
+// formatutils9.h: Queries for GL image formats and their translations to D3D
+// formats.
+
+#ifndef LIBANGLE_RENDERER_D3D_FORMATUTILSD3D_H_
+#define LIBANGLE_RENDERER_D3D_FORMATUTILSD3D_H_
+
+namespace rx
+{
+enum VertexConversionType
+{
+ VERTEX_CONVERT_NONE = 0,
+ VERTEX_CONVERT_CPU = 1,
+ VERTEX_CONVERT_GPU = 2,
+ VERTEX_CONVERT_BOTH = 3
+};
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_FORMATUTILSD3D_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d_format.cpp b/gfx/angle/checkout/src/libANGLE/renderer/d3d_format.cpp
new file mode 100644
index 0000000000..0823b37a5d
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d_format.cpp
@@ -0,0 +1,206 @@
+//
+// Copyright 2020 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.
+//
+// d3d_format: Describes a D3D9 format. Used by the D3D9 and GL back-ends.
+
+#include "libANGLE/renderer/d3d_format.h"
+
+using namespace angle;
+
+namespace rx
+{
+namespace d3d9
+{
+namespace
+{
+constexpr D3DFORMAT D3DFMT_INTZ = ((D3DFORMAT)(MAKEFOURCC('I', 'N', 'T', 'Z')));
+constexpr D3DFORMAT D3DFMT_NULL = ((D3DFORMAT)(MAKEFOURCC('N', 'U', 'L', 'L')));
+} // anonymous namespace
+
+D3DFormat::D3DFormat()
+ : pixelBytes(0),
+ blockWidth(0),
+ blockHeight(0),
+ redBits(0),
+ greenBits(0),
+ blueBits(0),
+ alphaBits(0),
+ luminanceBits(0),
+ depthBits(0),
+ stencilBits(0),
+ formatID(angle::FormatID::NONE)
+{}
+
+D3DFormat::D3DFormat(GLuint bits,
+ GLuint blockWidth,
+ GLuint blockHeight,
+ GLuint redBits,
+ GLuint greenBits,
+ GLuint blueBits,
+ GLuint alphaBits,
+ GLuint lumBits,
+ GLuint depthBits,
+ GLuint stencilBits,
+ FormatID formatID)
+ : pixelBytes(bits / 8),
+ blockWidth(blockWidth),
+ blockHeight(blockHeight),
+ redBits(redBits),
+ greenBits(greenBits),
+ blueBits(blueBits),
+ alphaBits(alphaBits),
+ luminanceBits(lumBits),
+ depthBits(depthBits),
+ stencilBits(stencilBits),
+ formatID(formatID)
+{}
+
+const D3DFormat &GetD3DFormatInfo(D3DFORMAT format)
+{
+ if (format == D3DFMT_NULL)
+ {
+ static const D3DFormat info(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, FormatID::NONE);
+ return info;
+ }
+
+ if (format == D3DFMT_INTZ)
+ {
+ static const D3DFormat info(32, 1, 1, 0, 0, 0, 0, 0, 24, 8, FormatID::D24_UNORM_S8_UINT);
+ return info;
+ }
+
+ switch (format)
+ {
+ case D3DFMT_UNKNOWN:
+ {
+ static const D3DFormat info(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, FormatID::NONE);
+ return info;
+ }
+
+ case D3DFMT_L8:
+ {
+ static const D3DFormat info(8, 1, 1, 0, 0, 0, 0, 8, 0, 0, FormatID::L8_UNORM);
+ return info;
+ }
+ case D3DFMT_A8:
+ {
+ static const D3DFormat info(8, 1, 1, 0, 0, 0, 8, 0, 0, 0, FormatID::A8_UNORM);
+ return info;
+ }
+ case D3DFMT_A8L8:
+ {
+ static const D3DFormat info(16, 1, 1, 0, 0, 0, 8, 8, 0, 0, FormatID::L8A8_UNORM);
+ return info;
+ }
+
+ case D3DFMT_A4R4G4B4:
+ {
+ static const D3DFormat info(16, 1, 1, 4, 4, 4, 4, 0, 0, 0, FormatID::B4G4R4A4_UNORM);
+ return info;
+ }
+ case D3DFMT_A1R5G5B5:
+ {
+ static const D3DFormat info(16, 1, 1, 5, 5, 5, 1, 0, 0, 0, FormatID::B5G5R5A1_UNORM);
+ return info;
+ }
+ case D3DFMT_R5G6B5:
+ {
+ static const D3DFormat info(16, 1, 1, 5, 6, 5, 0, 0, 0, 0, FormatID::R5G6B5_UNORM);
+ return info;
+ }
+ case D3DFMT_X8R8G8B8:
+ {
+ static const D3DFormat info(32, 1, 1, 8, 8, 8, 0, 0, 0, 0, FormatID::B8G8R8X8_UNORM);
+ return info;
+ }
+ case D3DFMT_A8R8G8B8:
+ {
+ static const D3DFormat info(32, 1, 1, 8, 8, 8, 8, 0, 0, 0, FormatID::B8G8R8A8_UNORM);
+ return info;
+ }
+
+ case D3DFMT_R16F:
+ {
+ static const D3DFormat info(16, 1, 1, 16, 0, 0, 0, 0, 0, 0, FormatID::R16_FLOAT);
+ return info;
+ }
+ case D3DFMT_G16R16F:
+ {
+ static const D3DFormat info(32, 1, 1, 16, 16, 0, 0, 0, 0, 0, FormatID::R16G16_FLOAT);
+ return info;
+ }
+ case D3DFMT_A16B16G16R16F:
+ {
+ static const D3DFormat info(64, 1, 1, 16, 16, 16, 16, 0, 0, 0,
+ FormatID::R16G16B16A16_FLOAT);
+ return info;
+ }
+ case D3DFMT_R32F:
+ {
+ static const D3DFormat info(32, 1, 1, 32, 0, 0, 0, 0, 0, 0, FormatID::R32_FLOAT);
+ return info;
+ }
+ case D3DFMT_G32R32F:
+ {
+ static const D3DFormat info(64, 1, 1, 32, 32, 0, 0, 0, 0, 0, FormatID::R32G32_FLOAT);
+ return info;
+ }
+ case D3DFMT_A32B32G32R32F:
+ {
+ static const D3DFormat info(128, 1, 1, 32, 32, 32, 32, 0, 0, 0,
+ FormatID::R32G32B32A32_FLOAT);
+ return info;
+ }
+
+ case D3DFMT_D16:
+ {
+ static const D3DFormat info(16, 1, 1, 0, 0, 0, 0, 0, 16, 0, FormatID::D16_UNORM);
+ return info;
+ }
+ case D3DFMT_D24S8:
+ {
+ static const D3DFormat info(32, 1, 1, 0, 0, 0, 0, 0, 24, 8,
+ FormatID::D24_UNORM_S8_UINT);
+ return info;
+ }
+ case D3DFMT_D24X8:
+ {
+ static const D3DFormat info(32, 1, 1, 0, 0, 0, 0, 0, 24, 0, FormatID::D16_UNORM);
+ return info;
+ }
+ case D3DFMT_D32:
+ {
+ static const D3DFormat info(32, 1, 1, 0, 0, 0, 0, 0, 32, 0, FormatID::D32_UNORM);
+ return info;
+ }
+
+ case D3DFMT_DXT1:
+ {
+ static const D3DFormat info(64, 4, 4, 0, 0, 0, 0, 0, 0, 0,
+ FormatID::BC1_RGBA_UNORM_BLOCK);
+ return info;
+ }
+ case D3DFMT_DXT3:
+ {
+ static const D3DFormat info(128, 4, 4, 0, 0, 0, 0, 0, 0, 0,
+ FormatID::BC2_RGBA_UNORM_BLOCK);
+ return info;
+ }
+ case D3DFMT_DXT5:
+ {
+ static const D3DFormat info(128, 4, 4, 0, 0, 0, 0, 0, 0, 0,
+ FormatID::BC3_RGBA_UNORM_BLOCK);
+ return info;
+ }
+
+ default:
+ {
+ static const D3DFormat defaultInfo;
+ return defaultInfo;
+ }
+ }
+}
+} // namespace d3d9
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/d3d_format.h b/gfx/angle/checkout/src/libANGLE/renderer/d3d_format.h
new file mode 100644
index 0000000000..4554f11460
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/d3d_format.h
@@ -0,0 +1,58 @@
+//
+// Copyright 2020 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.
+//
+// d3d_format: Describes a D3D9 format. Used by the D3D9 and GL back-ends.
+
+#ifndef LIBANGLE_RENDERER_D3D_FORMAT_H_
+#define LIBANGLE_RENDERER_D3D_FORMAT_H_
+
+#include "libANGLE/renderer/Format.h"
+
+// We forcibly include the D3D9 header here because this file can be used from 3 different backends.
+#include <d3d9.h>
+
+namespace rx
+{
+namespace d3d9
+{
+struct D3DFormat
+{
+ D3DFormat();
+ D3DFormat(GLuint pixelBytes,
+ GLuint blockWidth,
+ GLuint blockHeight,
+ GLuint redBits,
+ GLuint greenBits,
+ GLuint blueBits,
+ GLuint alphaBits,
+ GLuint luminanceBits,
+ GLuint depthBits,
+ GLuint stencilBits,
+ angle::FormatID formatID);
+
+ const angle::Format &info() const { return angle::Format::Get(formatID); }
+
+ GLuint pixelBytes;
+ GLuint blockWidth;
+ GLuint blockHeight;
+
+ GLuint redBits;
+ GLuint greenBits;
+ GLuint blueBits;
+ GLuint alphaBits;
+ GLuint luminanceBits;
+
+ GLuint depthBits;
+ GLuint stencilBits;
+
+ angle::FormatID formatID;
+};
+
+const D3DFormat &GetD3DFormatInfo(D3DFORMAT format);
+
+} // namespace d3d9
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_D3D_FORMAT_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/driver_utils.cpp b/gfx/angle/checkout/src/libANGLE/renderer/driver_utils.cpp
new file mode 100644
index 0000000000..360a0dd9a2
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/driver_utils.cpp
@@ -0,0 +1,438 @@
+//
+// 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.
+//
+
+// driver_utils.h : provides more information about current driver.
+
+#include <algorithm>
+
+#include "libANGLE/renderer/driver_utils.h"
+
+#include "common/platform.h"
+#include "common/system_utils.h"
+
+#if defined(ANGLE_PLATFORM_ANDROID)
+# include <sys/system_properties.h>
+#endif
+
+#if defined(ANGLE_PLATFORM_LINUX)
+# include <sys/utsname.h>
+#endif
+
+#if defined(ANGLE_PLATFORM_WINDOWS)
+# include <versionhelpers.h>
+#endif
+
+namespace rx
+{
+// Intel
+// Referenced from
+// https://gitlab.freedesktop.org/mesa/mesa/-/blob/main/include/pci_ids/crocus_pci_ids.h
+// https://gitlab.freedesktop.org/mesa/mesa/-/blob/main/include/pci_ids/iris_pci_ids.h
+namespace
+{
+// gen6
+const uint16_t SandyBridge[] = {
+ 0x0102, 0x0106, 0x010A, // snb_gt1
+ 0x0112, 0x0122, 0x0116, 0x0126 // snb_gt2
+};
+
+// gen7
+const uint16_t IvyBridge[] = {
+ 0x0152, 0x0156, 0x015A, // ivb_gt1
+ 0x0162, 0x0166, 0x016A // ivb_gt2
+};
+
+// gen 7.5
+const uint16_t Haswell[] = {
+ 0x0402, 0x0406, 0x040A, 0x040B, 0x040E, 0x0C02, 0x0C06, 0x0C0A, 0x0C0B, 0x0C0E,
+ 0x0A02, 0x0A06, 0x0A0A, 0x0A0B, 0x0A0E, 0x0D02, 0x0D06, 0x0D0A, 0x0D0B, 0x0D0E, // hsw_gt1
+ 0x0412, 0x0416, 0x041A, 0x041B, 0x041E, 0x0C12, 0x0C16, 0x0C1A, 0x0C1B, 0x0C1E,
+ 0x0A12, 0x0A16, 0x0A1A, 0x0A1B, 0x0A1E, 0x0D12, 0x0D16, 0x0D1A, 0x0D1B, 0x0D1E, // hsw_gt2
+ 0x0422, 0x0426, 0x042A, 0x042B, 0x042E, 0x0C22, 0x0C26, 0x0C2A, 0x0C2B, 0x0C2E,
+ 0x0A22, 0x0A26, 0x0A2A, 0x0A2B, 0x0A2E, 0x0D22, 0x0D26, 0x0D2A, 0x0D2B, 0x0D2E // hsw_gt3
+};
+
+// gen8
+const uint16_t Broadwell[] = {
+ 0x1602, 0x1606, 0x160A, 0x160B, 0x160D, 0x160E, // bdw_gt1
+ 0x1612, 0x1616, 0x161A, 0x161B, 0x161D, 0x161E, // bdw_gt2
+ 0x1622, 0x1626, 0x162A, 0x162B, 0x162D, 0x162E // bdw_gt3
+};
+
+const uint16_t CherryView[] = {0x22B0, 0x22B1, 0x22B2, 0x22B3};
+
+// gen9
+const uint16_t Skylake[] = {
+ 0x1902, 0x1906, 0x190A, 0x190B, 0x190E, // skl_gt1
+ 0x1912, 0x1913, 0x1915, 0x1916, 0x1917, 0x191A, 0x191B, 0x191D, 0x191E, 0x1921, // skl_gt2
+ 0x1923, 0x1926, 0x1927, 0x192B, 0x192D, // skl_gt3
+ 0x192A, 0x1932, 0x193A, 0x193B, 0x193D // skl_gt4
+};
+
+// gen9lp
+const uint16_t Broxton[] = {0x0A84, 0x1A84, 0x1A85, 0x5A84, 0x5A85};
+
+const uint16_t GeminiLake[] = {0x3184, 0x3185};
+
+// gen9p5
+const uint16_t KabyLake[] = {
+ // Kaby Lake
+ 0x5902, 0x5906, 0x5908, 0x590A, 0x590B, 0x590E, // kbl_gt1
+ 0x5913, 0x5915, // kbl_gt1_5
+ 0x5912, 0x5916, 0x5917, 0x591A, 0x591B, 0x591D, 0x591E, 0x5921, // kbl_gt2
+ 0x5923, 0x5926, 0x5927, // kbl_gt3
+ 0x593B, // kbl_gt4
+ // Amber Lake
+ 0x591C, 0x87C0 // kbl_gt2
+};
+
+const uint16_t CoffeeLake[] = {
+ // Amber Lake
+ 0x87CA, // cfl_gt2
+
+ // Coffee Lake
+ 0x3E90, 0x3E93, 0x3E99, 0x3E9C, // cfl_gt1
+ 0x3E91, 0x3E92, 0x3E94, 0x3E96, 0x3E98, 0x3E9A, 0x3E9B, 0x3EA9, // cfl_gt2
+ 0x3EA5, 0x3EA6, 0x3EA7, 0x3EA8, // cfl_gt3
+
+ // Whisky Lake
+ 0x3EA1, 0x3EA4, // cfl_gt1
+ 0x3EA0, 0x3EA3, // cfl_gt2
+ 0x3EA2, // cfl_gt3
+
+ // Comet Lake
+ 0x9B21, 0x9BA0, 0x9BA2, 0x9BA4, 0x9BA5, 0x9BA8, 0x9BAA, 0x9BAB, 0x9BAC, // cfl_gt1
+ 0x9B41, 0x9BC0, 0x9BC2, 0x9BC4, 0x9BC5, 0x9BC6, 0x9BC8, 0x9BCA, 0x9BCB, 0x9BCC, // cfl_gt2
+ 0x9BE6, 0x9BF6 // cfl_gt2
+};
+
+const uint16_t IntelGen11[] = {
+ // Ice Lake
+ 0x8A71, // icl_gt0_5
+ 0x8A56, 0x8A58, 0x8A5B, 0x8A5D, // icl_gt1
+ 0x8A54, 0x8A57, 0x8A59, 0x8A5A, 0x8A5C, // icl_gt1_5
+ 0x8A50, 0x8A51, 0x8A52, 0x8A53, // icl_gt2
+
+ // Elkhart Lake
+ 0x4500, 0x4541, 0x4551, 0x4555, 0x4557, 0x4571,
+
+ // Jasper Lake
+ 0x4E51, 0x4E55, 0x4E57, 0x4E61, 0x4E71};
+
+const uint16_t IntelGen12[] = {
+ // Rocket Lake
+ 0x4C8C, // rkl_gt05
+ 0x4C8A, 0x4C8B, 0x4C90, 0x4C9A, // rkl_gt1
+
+ // Alder Lake
+ 0x4683, 0x4693, // adl_gt05
+ 0x4680, 0x4681, 0x4682, 0x4688, 0x4689, 0x4690, 0x4691, 0x4692, // adl_gt1
+ 0x4626, 0x4628, 0x462A, 0x46A0, 0x46A1, 0x46A2, 0x46A3, 0x46A6, 0x46A8, // adl_gt2
+ 0x46AA, 0x46B0, 0x46B1, 0x46B2, 0x46B3, 0x46C0, 0x46C1, 0x46C2, 0x46C3, // adl_gt2
+ 0x46D0, 0x46D1, 0x46D2, // adl_n
+
+ // Tiger Lake
+ 0x9A60, 0x9A68, 0x9A70, // tgl_gt1
+ 0x9A40, 0x9A49, 0x9A59, 0x9A78, 0x9AC0, 0x9AC9, 0x9AD9, 0x9AF8, // tgl_gt2
+
+ // Raptop Lake
+ 0xA780, 0xA781, 0xA782, 0xA783, 0xA788, 0xA789, // rpl
+ 0xA720, 0xA721, 0xA7A0, 0xA7A1, 0xA7A8, 0xA7A9, // rpl_p
+
+ // DG1
+ 0x4905, 0x4906, 0x4907, 0x4908, 0x4909};
+
+} // anonymous namespace
+
+IntelDriverVersion::IntelDriverVersion(uint32_t buildNumber) : mBuildNumber(buildNumber) {}
+
+bool IntelDriverVersion::operator==(const IntelDriverVersion &version)
+{
+ return mBuildNumber == version.mBuildNumber;
+}
+
+bool IntelDriverVersion::operator!=(const IntelDriverVersion &version)
+{
+ return !(*this == version);
+}
+
+bool IntelDriverVersion::operator<(const IntelDriverVersion &version)
+{
+ return mBuildNumber < version.mBuildNumber;
+}
+
+bool IntelDriverVersion::operator>=(const IntelDriverVersion &version)
+{
+ return !(*this < version);
+}
+
+bool IsSandyBridge(uint32_t DeviceId)
+{
+ return std::find(std::begin(SandyBridge), std::end(SandyBridge), DeviceId) !=
+ std::end(SandyBridge);
+}
+
+bool IsIvyBridge(uint32_t DeviceId)
+{
+ return std::find(std::begin(IvyBridge), std::end(IvyBridge), DeviceId) != std::end(IvyBridge);
+}
+
+bool IsHaswell(uint32_t DeviceId)
+{
+ return std::find(std::begin(Haswell), std::end(Haswell), DeviceId) != std::end(Haswell);
+}
+
+bool IsBroadwell(uint32_t DeviceId)
+{
+ return std::find(std::begin(Broadwell), std::end(Broadwell), DeviceId) != std::end(Broadwell);
+}
+
+bool IsCherryView(uint32_t DeviceId)
+{
+ return std::find(std::begin(CherryView), std::end(CherryView), DeviceId) !=
+ std::end(CherryView);
+}
+
+bool IsSkylake(uint32_t DeviceId)
+{
+ return std::find(std::begin(Skylake), std::end(Skylake), DeviceId) != std::end(Skylake);
+}
+
+bool IsBroxton(uint32_t DeviceId)
+{
+ return std::find(std::begin(Broxton), std::end(Broxton), DeviceId) != std::end(Broxton);
+}
+
+bool IsKabyLake(uint32_t DeviceId)
+{
+ return std::find(std::begin(KabyLake), std::end(KabyLake), DeviceId) != std::end(KabyLake);
+}
+
+bool IsGeminiLake(uint32_t DeviceId)
+{
+ return std::find(std::begin(GeminiLake), std::end(GeminiLake), DeviceId) !=
+ std::end(GeminiLake);
+}
+
+bool IsCoffeeLake(uint32_t DeviceId)
+{
+ return std::find(std::begin(CoffeeLake), std::end(CoffeeLake), DeviceId) !=
+ std::end(CoffeeLake);
+}
+
+bool Is9thGenIntel(uint32_t DeviceId)
+{
+ return IsSkylake(DeviceId) || IsBroxton(DeviceId) || IsKabyLake(DeviceId);
+}
+
+bool Is11thGenIntel(uint32_t DeviceId)
+{
+ return std::find(std::begin(IntelGen11), std::end(IntelGen11), DeviceId) !=
+ std::end(IntelGen11);
+}
+
+bool Is12thGenIntel(uint32_t DeviceId)
+{
+ return std::find(std::begin(IntelGen12), std::end(IntelGen12), DeviceId) !=
+ std::end(IntelGen12);
+}
+
+const char *GetVendorString(uint32_t vendorId)
+{
+ switch (vendorId)
+ {
+ case VENDOR_ID_AMD:
+ return "AMD";
+ case VENDOR_ID_ARM:
+ return "ARM";
+ case VENDOR_ID_APPLE:
+ return "Apple";
+ case VENDOR_ID_BROADCOM:
+ return "Broadcom";
+ case VENDOR_ID_GOOGLE:
+ return "Google";
+ case VENDOR_ID_INTEL:
+ return "Intel";
+ case VENDOR_ID_MESA:
+ return "Mesa";
+ case VENDOR_ID_MICROSOFT:
+ return "Microsoft";
+ case VENDOR_ID_NVIDIA:
+ return "NVIDIA";
+ case VENDOR_ID_POWERVR:
+ return "Imagination Technologies";
+ case VENDOR_ID_QUALCOMM:
+ return "Qualcomm";
+ case VENDOR_ID_SAMSUNG:
+ return "Samsung Electronics Co., Ltd.";
+ case VENDOR_ID_VIVANTE:
+ return "Vivante";
+ case VENDOR_ID_VMWARE:
+ return "VMware";
+ case 0xba5eba11: // Mock vendor ID used for tests.
+ return "Test";
+ case 0:
+ return "NULL";
+ default:
+ // TODO(jmadill): More vendor IDs.
+ UNIMPLEMENTED();
+ return "Unknown";
+ }
+}
+
+MajorMinorPatchVersion::MajorMinorPatchVersion() {}
+MajorMinorPatchVersion::MajorMinorPatchVersion(int major, int minor, int patch)
+ : majorVersion(major), minorVersion(minor), patchVersion(patch)
+{}
+
+bool operator==(const MajorMinorPatchVersion &a, const MajorMinorPatchVersion &b)
+{
+ return std::tie(a.majorVersion, a.minorVersion, a.patchVersion) ==
+ std::tie(b.majorVersion, b.minorVersion, b.patchVersion);
+}
+bool operator!=(const MajorMinorPatchVersion &a, const MajorMinorPatchVersion &b)
+{
+ return std::tie(a.majorVersion, a.minorVersion, a.patchVersion) !=
+ std::tie(b.majorVersion, b.minorVersion, b.patchVersion);
+}
+bool operator<(const MajorMinorPatchVersion &a, const MajorMinorPatchVersion &b)
+{
+ return std::tie(a.majorVersion, a.minorVersion, a.patchVersion) <
+ std::tie(b.majorVersion, b.minorVersion, b.patchVersion);
+}
+bool operator>=(const MajorMinorPatchVersion &a, const MajorMinorPatchVersion &b)
+{
+ return std::tie(a.majorVersion, a.minorVersion, a.patchVersion) >=
+ std::tie(b.majorVersion, b.minorVersion, b.patchVersion);
+}
+
+ARMDriverVersion ParseARMDriverVersion(uint32_t driverVersion)
+{
+ // ARM driver versions are built with the following macro:
+ // ((((uint32_t)(major)) << 22) | (((uint32_t)(minor)) << 12) | ((uint32_t)(patch)))
+ constexpr uint32_t kMinorVersionMask = angle::BitMask<uint32_t>(10);
+ constexpr uint32_t kPatchMask = angle::BitMask<uint32_t>(12);
+ return ARMDriverVersion(driverVersion >> 22, (driverVersion >> 12) & kMinorVersionMask,
+ driverVersion & kPatchMask);
+}
+
+int GetAndroidSDKVersion()
+{
+#if defined(ANGLE_PLATFORM_ANDROID)
+ char apiVersion[PROP_VALUE_MAX];
+ int length = __system_property_get("ro.build.version.sdk", apiVersion);
+ if (length == 0)
+ {
+ return 0;
+ }
+ return atoi(apiVersion);
+#else
+ return 0;
+#endif
+}
+#if !defined(ANGLE_PLATFORM_MACOS)
+OSVersion GetMacOSVersion()
+{
+ // Return a default version
+ return OSVersion(0, 0, 0);
+}
+#endif
+
+#if !defined(ANGLE_PLATFORM_IOS)
+OSVersion GetiOSVersion()
+{
+ // Return a default version
+ return OSVersion(0, 0, 0);
+}
+#endif
+
+#if defined(ANGLE_PLATFORM_LINUX)
+bool ParseLinuxOSVersion(const char *version, int *major, int *minor, int *patch)
+{
+ errno = 0; // reset global error flag.
+ char *next;
+ *major = static_cast<int>(strtol(version, &next, 10));
+ if (next == nullptr || *next != '.' || errno != 0)
+ {
+ return false;
+ }
+
+ *minor = static_cast<int>(strtol(next + 1, &next, 10));
+ if (next == nullptr || *next != '.' || errno != 0)
+ {
+ return false;
+ }
+
+ *patch = static_cast<int>(strtol(next + 1, &next, 10));
+ if (errno != 0)
+ {
+ return false;
+ }
+
+ return true;
+}
+#endif
+
+OSVersion GetLinuxOSVersion()
+{
+#if defined(ANGLE_PLATFORM_LINUX)
+ struct utsname uname_info;
+ if (uname(&uname_info) != 0)
+ {
+ return OSVersion(0, 0, 0);
+ }
+
+ int majorVersion = 0, minorVersion = 0, patchVersion = 0;
+ if (ParseLinuxOSVersion(uname_info.release, &majorVersion, &minorVersion, &patchVersion))
+ {
+ return OSVersion(majorVersion, minorVersion, patchVersion);
+ }
+#endif
+
+ return OSVersion(0, 0, 0);
+}
+
+// There are multiple environment variables that may or may not be set during Wayland
+// sessions, including WAYLAND_DISPLAY, XDG_SESSION_TYPE, and DESKTOP_SESSION
+bool IsWayland()
+{
+ static bool checked = false;
+ static bool isWayland = false;
+ if (!checked)
+ {
+ if (IsLinux())
+ {
+ if (!angle::GetEnvironmentVar("WAYLAND_DISPLAY").empty())
+ {
+ isWayland = true;
+ }
+ else if (angle::GetEnvironmentVar("XDG_SESSION_TYPE") == "wayland")
+ {
+ isWayland = true;
+ }
+ else if (angle::GetEnvironmentVar("DESKTOP_SESSION").find("wayland") !=
+ std::string::npos)
+ {
+ isWayland = true;
+ }
+ }
+ checked = true;
+ }
+ return isWayland;
+}
+
+bool IsWin10OrGreater()
+{
+#if defined(ANGLE_ENABLE_WINDOWS_UWP)
+ return true;
+#elif defined(ANGLE_PLATFORM_WINDOWS)
+ return IsWindows10OrGreater();
+#else
+ return false;
+#endif
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/driver_utils.h b/gfx/angle/checkout/src/libANGLE/renderer/driver_utils.h
new file mode 100644
index 0000000000..3addc07ffd
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/driver_utils.h
@@ -0,0 +1,278 @@
+//
+// 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.
+//
+
+// driver_utils.h : provides more information about current driver.
+
+#ifndef LIBANGLE_RENDERER_DRIVER_UTILS_H_
+#define LIBANGLE_RENDERER_DRIVER_UTILS_H_
+
+#include "common/platform.h"
+#include "libANGLE/angletypes.h"
+
+namespace rx
+{
+
+enum VendorID : uint32_t
+{
+ VENDOR_ID_UNKNOWN = 0x0,
+ VENDOR_ID_AMD = 0x1002,
+ VENDOR_ID_APPLE = 0x106B,
+ VENDOR_ID_ARM = 0x13B5,
+ // Broadcom devices won't use PCI, but this is their Vulkan vendor id.
+ VENDOR_ID_BROADCOM = 0x14E4,
+ VENDOR_ID_GOOGLE = 0x1AE0,
+ VENDOR_ID_INTEL = 0x8086,
+ VENDOR_ID_MESA = 0x10005,
+ VENDOR_ID_MICROSOFT = 0x1414,
+ VENDOR_ID_NVIDIA = 0x10DE,
+ VENDOR_ID_POWERVR = 0x1010,
+ // This is Qualcomm PCI Vendor ID.
+ // Android doesn't have a PCI bus, but all we need is a unique id.
+ VENDOR_ID_QUALCOMM = 0x5143,
+ VENDOR_ID_SAMSUNG = 0x144D,
+ VENDOR_ID_VIVANTE = 0x9999,
+ VENDOR_ID_VMWARE = 0x15AD,
+};
+
+enum AndroidDeviceID : uint32_t
+{
+ ANDROID_DEVICE_ID_UNKNOWN = 0x0,
+ ANDROID_DEVICE_ID_NEXUS5X = 0x4010800,
+ ANDROID_DEVICE_ID_PIXEL2 = 0x5040001,
+ ANDROID_DEVICE_ID_PIXEL1XL = 0x5030004,
+ ANDROID_DEVICE_ID_PIXEL4 = 0x6040001,
+ ANDROID_DEVICE_ID_SWIFTSHADER = 0xC0DE,
+};
+
+inline bool IsAMD(uint32_t vendorId)
+{
+ return vendorId == VENDOR_ID_AMD;
+}
+
+inline bool IsApple(uint32_t vendorId)
+{
+ return vendorId == VENDOR_ID_APPLE;
+}
+
+inline bool IsARM(uint32_t vendorId)
+{
+ return vendorId == VENDOR_ID_ARM;
+}
+
+inline bool IsBroadcom(uint32_t vendorId)
+{
+ return vendorId == VENDOR_ID_BROADCOM;
+}
+
+inline bool IsIntel(uint32_t vendorId)
+{
+ return vendorId == VENDOR_ID_INTEL;
+}
+
+inline bool IsGoogle(uint32_t vendorId)
+{
+ return vendorId == VENDOR_ID_GOOGLE;
+}
+
+inline bool IsMicrosoft(uint32_t vendorId)
+{
+ return vendorId == VENDOR_ID_MICROSOFT;
+}
+
+inline bool IsNvidia(uint32_t vendorId)
+{
+ return vendorId == VENDOR_ID_NVIDIA;
+}
+
+inline bool IsPowerVR(uint32_t vendorId)
+{
+ return vendorId == VENDOR_ID_POWERVR;
+}
+
+inline bool IsQualcomm(uint32_t vendorId)
+{
+ return vendorId == VENDOR_ID_QUALCOMM;
+}
+
+inline bool IsSamsung(uint32_t vendorId)
+{
+ return vendorId == VENDOR_ID_SAMSUNG;
+}
+
+inline bool IsVivante(uint32_t vendorId)
+{
+ return vendorId == VENDOR_ID_VIVANTE;
+}
+
+inline bool IsVMWare(uint32_t vendorId)
+{
+ return vendorId == VENDOR_ID_VMWARE;
+}
+
+inline bool IsNexus5X(uint32_t vendorId, uint32_t deviceId)
+{
+ return IsQualcomm(vendorId) && deviceId == ANDROID_DEVICE_ID_NEXUS5X;
+}
+
+inline bool IsPixel1XL(uint32_t vendorId, uint32_t deviceId)
+{
+ return IsQualcomm(vendorId) && deviceId == ANDROID_DEVICE_ID_PIXEL1XL;
+}
+
+inline bool IsPixel2(uint32_t vendorId, uint32_t deviceId)
+{
+ return IsQualcomm(vendorId) && deviceId == ANDROID_DEVICE_ID_PIXEL2;
+}
+
+inline bool IsPixel4(uint32_t vendorId, uint32_t deviceId)
+{
+ return IsQualcomm(vendorId) && deviceId == ANDROID_DEVICE_ID_PIXEL4;
+}
+
+inline bool IsSwiftshader(uint32_t vendorId, uint32_t deviceId)
+{
+ return IsGoogle(vendorId) && deviceId == ANDROID_DEVICE_ID_SWIFTSHADER;
+}
+
+const char *GetVendorString(uint32_t vendorId);
+
+// For Linux, Intel graphics driver version is the Mesa version. The version number has three
+// fields: major revision, minor revision and release number.
+// For Windows, The version number includes 3rd and 4th fields. Please refer the details at
+// http://www.intel.com/content/www/us/en/support/graphics-drivers/000005654.html.
+// Current implementation only supports Windows.
+class IntelDriverVersion
+{
+ public:
+ IntelDriverVersion(uint32_t buildNumber);
+ bool operator==(const IntelDriverVersion &);
+ bool operator!=(const IntelDriverVersion &);
+ bool operator<(const IntelDriverVersion &);
+ bool operator>=(const IntelDriverVersion &);
+
+ private:
+ uint32_t mBuildNumber;
+};
+
+bool IsSandyBridge(uint32_t DeviceId);
+bool IsIvyBridge(uint32_t DeviceId);
+bool IsHaswell(uint32_t DeviceId);
+bool IsBroadwell(uint32_t DeviceId);
+bool IsCherryView(uint32_t DeviceId);
+bool IsSkylake(uint32_t DeviceId);
+bool IsBroxton(uint32_t DeviceId);
+bool IsKabyLake(uint32_t DeviceId);
+bool IsGeminiLake(uint32_t DeviceId);
+bool IsCoffeeLake(uint32_t DeviceId);
+bool Is9thGenIntel(uint32_t DeviceId);
+bool Is11thGenIntel(uint32_t DeviceId);
+bool Is12thGenIntel(uint32_t DeviceId);
+
+struct MajorMinorPatchVersion
+{
+ MajorMinorPatchVersion();
+ MajorMinorPatchVersion(int major, int minor, int patch);
+
+ int majorVersion = 0;
+ int minorVersion = 0;
+ int patchVersion = 0;
+};
+bool operator==(const MajorMinorPatchVersion &a, const MajorMinorPatchVersion &b);
+bool operator!=(const MajorMinorPatchVersion &a, const MajorMinorPatchVersion &b);
+bool operator<(const MajorMinorPatchVersion &a, const MajorMinorPatchVersion &b);
+bool operator>=(const MajorMinorPatchVersion &a, const MajorMinorPatchVersion &b);
+
+using ARMDriverVersion = MajorMinorPatchVersion;
+ARMDriverVersion ParseARMDriverVersion(uint32_t driverVersion);
+
+// Platform helpers
+inline bool IsWindows()
+{
+#if defined(ANGLE_PLATFORM_WINDOWS)
+ return true;
+#else
+ return false;
+#endif
+}
+
+inline bool IsLinux()
+{
+#if defined(ANGLE_PLATFORM_LINUX)
+ return true;
+#else
+ return false;
+#endif
+}
+
+inline bool IsChromeOS()
+{
+#if defined(ANGLE_PLATFORM_CHROMEOS)
+ return true;
+#else
+ return false;
+#endif
+}
+
+inline bool IsApple()
+{
+#if defined(ANGLE_PLATFORM_APPLE)
+ return true;
+#else
+ return false;
+#endif
+}
+
+inline bool IsMac()
+{
+#if defined(ANGLE_PLATFORM_APPLE) && defined(ANGLE_PLATFORM_MACOS)
+ return true;
+#else
+ return false;
+#endif
+}
+
+inline bool IsFuchsia()
+{
+#if defined(ANGLE_PLATFORM_FUCHSIA)
+ return true;
+#else
+ return false;
+#endif
+}
+
+inline bool IsIOS()
+{
+#if defined(ANGLE_PLATFORM_IOS)
+ return true;
+#else
+ return false;
+#endif
+}
+
+bool IsWayland();
+bool IsWin10OrGreater();
+
+using OSVersion = MajorMinorPatchVersion;
+
+OSVersion GetMacOSVersion();
+
+OSVersion GetiOSVersion();
+
+OSVersion GetLinuxOSVersion();
+
+inline bool IsAndroid()
+{
+#if defined(ANGLE_PLATFORM_ANDROID)
+ return true;
+#else
+ return false;
+#endif
+}
+
+int GetAndroidSDKVersion();
+
+} // namespace rx
+#endif // LIBANGLE_RENDERER_DRIVER_UTILS_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/dxgi_format_map.h b/gfx/angle/checkout/src/libANGLE/renderer/dxgi_format_map.h
new file mode 100644
index 0000000000..711d0d0a0b
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/dxgi_format_map.h
@@ -0,0 +1,27 @@
+//
+// Copyright 2020 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.
+//
+// DXGI format info:
+// Determining metadata about a DXGI format.
+
+#ifndef LIBANGLE_RENDERER_DXGI_FORMAT_MAP_H_
+#define LIBANGLE_RENDERER_DXGI_FORMAT_MAP_H_
+
+#include "common/platform.h"
+
+namespace rx
+{
+namespace d3d11
+{
+GLenum GetComponentType(DXGI_FORMAT dxgiFormat);
+} // namespace d3d11
+
+namespace d3d11_angle
+{
+const angle::Format &GetFormat(DXGI_FORMAT dxgiFormat);
+} // namespace d3d11_angle
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_DXGI_FORMAT_MAP_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/dxgi_format_map_autogen.cpp b/gfx/angle/checkout/src/libANGLE/renderer/dxgi_format_map_autogen.cpp
new file mode 100644
index 0000000000..a46567ae0d
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/dxgi_format_map_autogen.cpp
@@ -0,0 +1,516 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_dxgi_format_table.py using data from dxgi_format_data.json.
+//
+// Copyright 2020 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.
+//
+// DXGI format info:
+// Determining metadata about a DXGI format.
+
+#include "libANGLE/renderer/Format.h"
+
+using namespace angle;
+
+namespace rx
+{
+
+namespace d3d11
+{
+
+GLenum GetComponentType(DXGI_FORMAT dxgiFormat)
+{
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_420_OPAQUE:
+ break;
+ case DXGI_FORMAT_A8P8:
+ break;
+ case DXGI_FORMAT_A8_UNORM:
+ return GL_UNSIGNED_NORMALIZED;
+ case DXGI_FORMAT_AI44:
+ break;
+ case DXGI_FORMAT_AYUV:
+ break;
+ case DXGI_FORMAT_B4G4R4A4_UNORM:
+ return GL_UNSIGNED_NORMALIZED;
+ case DXGI_FORMAT_B5G5R5A1_UNORM:
+ return GL_UNSIGNED_NORMALIZED;
+ case DXGI_FORMAT_B5G6R5_UNORM:
+ return GL_UNSIGNED_NORMALIZED;
+ case DXGI_FORMAT_B8G8R8A8_TYPELESS:
+ break;
+ case DXGI_FORMAT_B8G8R8A8_UNORM:
+ return GL_UNSIGNED_NORMALIZED;
+ case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
+ return GL_UNSIGNED_NORMALIZED;
+ case DXGI_FORMAT_B8G8R8X8_TYPELESS:
+ break;
+ case DXGI_FORMAT_B8G8R8X8_UNORM:
+ return GL_UNSIGNED_NORMALIZED;
+ case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
+ return GL_UNSIGNED_NORMALIZED;
+ case DXGI_FORMAT_BC1_TYPELESS:
+ break;
+ case DXGI_FORMAT_BC1_UNORM:
+ return GL_UNSIGNED_NORMALIZED;
+ case DXGI_FORMAT_BC1_UNORM_SRGB:
+ return GL_UNSIGNED_NORMALIZED;
+ case DXGI_FORMAT_BC2_TYPELESS:
+ break;
+ case DXGI_FORMAT_BC2_UNORM:
+ return GL_UNSIGNED_NORMALIZED;
+ case DXGI_FORMAT_BC2_UNORM_SRGB:
+ return GL_UNSIGNED_NORMALIZED;
+ case DXGI_FORMAT_BC3_TYPELESS:
+ break;
+ case DXGI_FORMAT_BC3_UNORM:
+ return GL_UNSIGNED_NORMALIZED;
+ case DXGI_FORMAT_BC3_UNORM_SRGB:
+ return GL_UNSIGNED_NORMALIZED;
+ case DXGI_FORMAT_BC4_SNORM:
+ return GL_SIGNED_NORMALIZED;
+ case DXGI_FORMAT_BC4_TYPELESS:
+ break;
+ case DXGI_FORMAT_BC4_UNORM:
+ return GL_UNSIGNED_NORMALIZED;
+ case DXGI_FORMAT_BC5_SNORM:
+ return GL_SIGNED_NORMALIZED;
+ case DXGI_FORMAT_BC5_TYPELESS:
+ break;
+ case DXGI_FORMAT_BC5_UNORM:
+ return GL_UNSIGNED_NORMALIZED;
+ case DXGI_FORMAT_BC6H_SF16:
+ break;
+ case DXGI_FORMAT_BC6H_TYPELESS:
+ break;
+ case DXGI_FORMAT_BC6H_UF16:
+ break;
+ case DXGI_FORMAT_BC7_TYPELESS:
+ break;
+ case DXGI_FORMAT_BC7_UNORM:
+ return GL_UNSIGNED_NORMALIZED;
+ case DXGI_FORMAT_BC7_UNORM_SRGB:
+ return GL_UNSIGNED_NORMALIZED;
+ case DXGI_FORMAT_D16_UNORM:
+ return GL_UNSIGNED_NORMALIZED;
+ case DXGI_FORMAT_D24_UNORM_S8_UINT:
+ break;
+ case DXGI_FORMAT_D32_FLOAT:
+ return GL_FLOAT;
+ case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
+ break;
+ case DXGI_FORMAT_G8R8_G8B8_UNORM:
+ return GL_UNSIGNED_NORMALIZED;
+ case DXGI_FORMAT_IA44:
+ break;
+ case DXGI_FORMAT_NV11:
+ break;
+ case DXGI_FORMAT_NV12:
+ break;
+ case DXGI_FORMAT_P010:
+ break;
+ case DXGI_FORMAT_P016:
+ break;
+ case DXGI_FORMAT_P8:
+ break;
+ case DXGI_FORMAT_R10G10B10A2_TYPELESS:
+ break;
+ case DXGI_FORMAT_R10G10B10A2_UINT:
+ return GL_UNSIGNED_INT;
+ case DXGI_FORMAT_R10G10B10A2_UNORM:
+ return GL_UNSIGNED_NORMALIZED;
+ case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
+ return GL_UNSIGNED_NORMALIZED;
+ case DXGI_FORMAT_R11G11B10_FLOAT:
+ return GL_FLOAT;
+ case DXGI_FORMAT_R16G16B16A16_FLOAT:
+ return GL_FLOAT;
+ case DXGI_FORMAT_R16G16B16A16_SINT:
+ return GL_INT;
+ case DXGI_FORMAT_R16G16B16A16_SNORM:
+ return GL_SIGNED_NORMALIZED;
+ case DXGI_FORMAT_R16G16B16A16_TYPELESS:
+ break;
+ case DXGI_FORMAT_R16G16B16A16_UINT:
+ return GL_UNSIGNED_INT;
+ case DXGI_FORMAT_R16G16B16A16_UNORM:
+ return GL_UNSIGNED_NORMALIZED;
+ case DXGI_FORMAT_R16G16_FLOAT:
+ return GL_FLOAT;
+ case DXGI_FORMAT_R16G16_SINT:
+ return GL_INT;
+ case DXGI_FORMAT_R16G16_SNORM:
+ return GL_SIGNED_NORMALIZED;
+ case DXGI_FORMAT_R16G16_TYPELESS:
+ break;
+ case DXGI_FORMAT_R16G16_UINT:
+ return GL_UNSIGNED_INT;
+ case DXGI_FORMAT_R16G16_UNORM:
+ return GL_UNSIGNED_NORMALIZED;
+ case DXGI_FORMAT_R16_FLOAT:
+ return GL_FLOAT;
+ case DXGI_FORMAT_R16_SINT:
+ return GL_INT;
+ case DXGI_FORMAT_R16_SNORM:
+ return GL_SIGNED_NORMALIZED;
+ case DXGI_FORMAT_R16_TYPELESS:
+ break;
+ case DXGI_FORMAT_R16_UINT:
+ return GL_UNSIGNED_INT;
+ case DXGI_FORMAT_R16_UNORM:
+ return GL_UNSIGNED_NORMALIZED;
+ case DXGI_FORMAT_R1_UNORM:
+ return GL_UNSIGNED_NORMALIZED;
+ case DXGI_FORMAT_R24G8_TYPELESS:
+ break;
+ case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
+ return GL_UNSIGNED_NORMALIZED;
+ case DXGI_FORMAT_R32G32B32A32_FLOAT:
+ return GL_FLOAT;
+ case DXGI_FORMAT_R32G32B32A32_SINT:
+ return GL_INT;
+ case DXGI_FORMAT_R32G32B32A32_TYPELESS:
+ break;
+ case DXGI_FORMAT_R32G32B32A32_UINT:
+ return GL_UNSIGNED_INT;
+ case DXGI_FORMAT_R32G32B32_FLOAT:
+ return GL_FLOAT;
+ case DXGI_FORMAT_R32G32B32_SINT:
+ return GL_INT;
+ case DXGI_FORMAT_R32G32B32_TYPELESS:
+ break;
+ case DXGI_FORMAT_R32G32B32_UINT:
+ return GL_UNSIGNED_INT;
+ case DXGI_FORMAT_R32G32_FLOAT:
+ return GL_FLOAT;
+ case DXGI_FORMAT_R32G32_SINT:
+ return GL_INT;
+ case DXGI_FORMAT_R32G32_TYPELESS:
+ break;
+ case DXGI_FORMAT_R32G32_UINT:
+ return GL_UNSIGNED_INT;
+ case DXGI_FORMAT_R32G8X24_TYPELESS:
+ break;
+ case DXGI_FORMAT_R32_FLOAT:
+ return GL_FLOAT;
+ case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
+ return GL_FLOAT;
+ case DXGI_FORMAT_R32_SINT:
+ return GL_INT;
+ case DXGI_FORMAT_R32_TYPELESS:
+ break;
+ case DXGI_FORMAT_R32_UINT:
+ return GL_UNSIGNED_INT;
+ case DXGI_FORMAT_R8G8B8A8_SINT:
+ return GL_INT;
+ case DXGI_FORMAT_R8G8B8A8_SNORM:
+ return GL_SIGNED_NORMALIZED;
+ case DXGI_FORMAT_R8G8B8A8_TYPELESS:
+ break;
+ case DXGI_FORMAT_R8G8B8A8_UINT:
+ return GL_UNSIGNED_INT;
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ return GL_UNSIGNED_NORMALIZED;
+ case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
+ return GL_UNSIGNED_NORMALIZED;
+ case DXGI_FORMAT_R8G8_B8G8_UNORM:
+ return GL_UNSIGNED_NORMALIZED;
+ case DXGI_FORMAT_R8G8_SINT:
+ return GL_INT;
+ case DXGI_FORMAT_R8G8_SNORM:
+ return GL_SIGNED_NORMALIZED;
+ case DXGI_FORMAT_R8G8_TYPELESS:
+ break;
+ case DXGI_FORMAT_R8G8_UINT:
+ return GL_UNSIGNED_INT;
+ case DXGI_FORMAT_R8G8_UNORM:
+ return GL_UNSIGNED_NORMALIZED;
+ case DXGI_FORMAT_R8_SINT:
+ return GL_INT;
+ case DXGI_FORMAT_R8_SNORM:
+ return GL_SIGNED_NORMALIZED;
+ case DXGI_FORMAT_R8_TYPELESS:
+ break;
+ case DXGI_FORMAT_R8_UINT:
+ return GL_UNSIGNED_INT;
+ case DXGI_FORMAT_R8_UNORM:
+ return GL_UNSIGNED_NORMALIZED;
+ case DXGI_FORMAT_R9G9B9E5_SHAREDEXP:
+ return GL_FLOAT;
+ case DXGI_FORMAT_UNKNOWN:
+ break;
+ case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
+ return GL_UNSIGNED_INT;
+ case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
+ return GL_UNSIGNED_INT;
+ case DXGI_FORMAT_Y210:
+ break;
+ case DXGI_FORMAT_Y216:
+ break;
+ case DXGI_FORMAT_Y410:
+ break;
+ case DXGI_FORMAT_Y416:
+ break;
+ case DXGI_FORMAT_YUY2:
+ break;
+ default:
+ break;
+ }
+
+ UNREACHABLE();
+ return GL_NONE;
+}
+
+} // namespace d3d11
+
+namespace d3d11_angle
+{
+
+const Format &GetFormat(DXGI_FORMAT dxgiFormat)
+{
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_420_OPAQUE:
+ break;
+ case DXGI_FORMAT_A8P8:
+ break;
+ case DXGI_FORMAT_A8_UNORM:
+ return Format::Get(FormatID::A8_UNORM);
+ case DXGI_FORMAT_AI44:
+ break;
+ case DXGI_FORMAT_AYUV:
+ break;
+ case DXGI_FORMAT_B4G4R4A4_UNORM:
+ return Format::Get(FormatID::B4G4R4A4_UNORM);
+ case DXGI_FORMAT_B5G5R5A1_UNORM:
+ return Format::Get(FormatID::B5G5R5A1_UNORM);
+ case DXGI_FORMAT_B5G6R5_UNORM:
+ return Format::Get(FormatID::B5G6R5_UNORM);
+ case DXGI_FORMAT_B8G8R8A8_TYPELESS:
+ return Format::Get(FormatID::B8G8R8A8_TYPELESS);
+ case DXGI_FORMAT_B8G8R8A8_UNORM:
+ return Format::Get(FormatID::B8G8R8A8_UNORM);
+ case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
+ return Format::Get(FormatID::B8G8R8A8_UNORM_SRGB);
+ case DXGI_FORMAT_B8G8R8X8_TYPELESS:
+ break;
+ case DXGI_FORMAT_B8G8R8X8_UNORM:
+ return Format::Get(FormatID::B8G8R8X8_UNORM);
+ case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
+ break;
+ case DXGI_FORMAT_BC1_TYPELESS:
+ break;
+ case DXGI_FORMAT_BC1_UNORM:
+ return Format::Get(FormatID::BC1_RGBA_UNORM_BLOCK);
+ case DXGI_FORMAT_BC1_UNORM_SRGB:
+ return Format::Get(FormatID::BC1_RGBA_UNORM_SRGB_BLOCK);
+ case DXGI_FORMAT_BC2_TYPELESS:
+ break;
+ case DXGI_FORMAT_BC2_UNORM:
+ return Format::Get(FormatID::BC2_RGBA_UNORM_BLOCK);
+ case DXGI_FORMAT_BC2_UNORM_SRGB:
+ return Format::Get(FormatID::BC2_RGBA_UNORM_SRGB_BLOCK);
+ case DXGI_FORMAT_BC3_TYPELESS:
+ break;
+ case DXGI_FORMAT_BC3_UNORM:
+ return Format::Get(FormatID::BC3_RGBA_UNORM_BLOCK);
+ case DXGI_FORMAT_BC3_UNORM_SRGB:
+ return Format::Get(FormatID::BC3_RGBA_UNORM_SRGB_BLOCK);
+ case DXGI_FORMAT_BC4_SNORM:
+ return Format::Get(FormatID::BC4_RED_SNORM_BLOCK);
+ case DXGI_FORMAT_BC4_TYPELESS:
+ break;
+ case DXGI_FORMAT_BC4_UNORM:
+ return Format::Get(FormatID::BC4_RED_UNORM_BLOCK);
+ case DXGI_FORMAT_BC5_SNORM:
+ return Format::Get(FormatID::BC5_RG_SNORM_BLOCK);
+ case DXGI_FORMAT_BC5_TYPELESS:
+ break;
+ case DXGI_FORMAT_BC5_UNORM:
+ return Format::Get(FormatID::BC5_RG_UNORM_BLOCK);
+ case DXGI_FORMAT_BC6H_SF16:
+ break;
+ case DXGI_FORMAT_BC6H_TYPELESS:
+ break;
+ case DXGI_FORMAT_BC6H_UF16:
+ break;
+ case DXGI_FORMAT_BC7_TYPELESS:
+ break;
+ case DXGI_FORMAT_BC7_UNORM:
+ break;
+ case DXGI_FORMAT_BC7_UNORM_SRGB:
+ break;
+ case DXGI_FORMAT_D16_UNORM:
+ return Format::Get(FormatID::D16_UNORM);
+ case DXGI_FORMAT_D24_UNORM_S8_UINT:
+ return Format::Get(FormatID::D24_UNORM_S8_UINT);
+ case DXGI_FORMAT_D32_FLOAT:
+ return Format::Get(FormatID::D32_FLOAT);
+ case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
+ return Format::Get(FormatID::D32_FLOAT_S8X24_UINT);
+ case DXGI_FORMAT_G8R8_G8B8_UNORM:
+ break;
+ case DXGI_FORMAT_IA44:
+ break;
+ case DXGI_FORMAT_NV11:
+ break;
+ case DXGI_FORMAT_NV12:
+ break;
+ case DXGI_FORMAT_P010:
+ break;
+ case DXGI_FORMAT_P016:
+ break;
+ case DXGI_FORMAT_P8:
+ break;
+ case DXGI_FORMAT_R10G10B10A2_TYPELESS:
+ break;
+ case DXGI_FORMAT_R10G10B10A2_UINT:
+ return Format::Get(FormatID::R10G10B10A2_UINT);
+ case DXGI_FORMAT_R10G10B10A2_UNORM:
+ return Format::Get(FormatID::R10G10B10A2_UNORM);
+ case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
+ break;
+ case DXGI_FORMAT_R11G11B10_FLOAT:
+ return Format::Get(FormatID::R11G11B10_FLOAT);
+ case DXGI_FORMAT_R16G16B16A16_FLOAT:
+ return Format::Get(FormatID::R16G16B16A16_FLOAT);
+ case DXGI_FORMAT_R16G16B16A16_SINT:
+ return Format::Get(FormatID::R16G16B16A16_SINT);
+ case DXGI_FORMAT_R16G16B16A16_SNORM:
+ return Format::Get(FormatID::R16G16B16A16_SNORM);
+ case DXGI_FORMAT_R16G16B16A16_TYPELESS:
+ break;
+ case DXGI_FORMAT_R16G16B16A16_UINT:
+ return Format::Get(FormatID::R16G16B16A16_UINT);
+ case DXGI_FORMAT_R16G16B16A16_UNORM:
+ return Format::Get(FormatID::R16G16B16A16_UNORM);
+ case DXGI_FORMAT_R16G16_FLOAT:
+ return Format::Get(FormatID::R16G16_FLOAT);
+ case DXGI_FORMAT_R16G16_SINT:
+ return Format::Get(FormatID::R16G16_SINT);
+ case DXGI_FORMAT_R16G16_SNORM:
+ return Format::Get(FormatID::R16G16_SNORM);
+ case DXGI_FORMAT_R16G16_TYPELESS:
+ break;
+ case DXGI_FORMAT_R16G16_UINT:
+ return Format::Get(FormatID::R16G16_UINT);
+ case DXGI_FORMAT_R16G16_UNORM:
+ return Format::Get(FormatID::R16G16_UNORM);
+ case DXGI_FORMAT_R16_FLOAT:
+ return Format::Get(FormatID::R16_FLOAT);
+ case DXGI_FORMAT_R16_SINT:
+ return Format::Get(FormatID::R16_SINT);
+ case DXGI_FORMAT_R16_SNORM:
+ return Format::Get(FormatID::R16_SNORM);
+ case DXGI_FORMAT_R16_TYPELESS:
+ break;
+ case DXGI_FORMAT_R16_UINT:
+ return Format::Get(FormatID::R16_UINT);
+ case DXGI_FORMAT_R16_UNORM:
+ return Format::Get(FormatID::R16_UNORM);
+ case DXGI_FORMAT_R1_UNORM:
+ break;
+ case DXGI_FORMAT_R24G8_TYPELESS:
+ break;
+ case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
+ break;
+ case DXGI_FORMAT_R32G32B32A32_FLOAT:
+ return Format::Get(FormatID::R32G32B32A32_FLOAT);
+ case DXGI_FORMAT_R32G32B32A32_SINT:
+ return Format::Get(FormatID::R32G32B32A32_SINT);
+ case DXGI_FORMAT_R32G32B32A32_TYPELESS:
+ break;
+ case DXGI_FORMAT_R32G32B32A32_UINT:
+ return Format::Get(FormatID::R32G32B32A32_UINT);
+ case DXGI_FORMAT_R32G32B32_FLOAT:
+ return Format::Get(FormatID::R32G32B32_FLOAT);
+ case DXGI_FORMAT_R32G32B32_SINT:
+ return Format::Get(FormatID::R32G32B32_SINT);
+ case DXGI_FORMAT_R32G32B32_TYPELESS:
+ break;
+ case DXGI_FORMAT_R32G32B32_UINT:
+ return Format::Get(FormatID::R32G32B32_UINT);
+ case DXGI_FORMAT_R32G32_FLOAT:
+ return Format::Get(FormatID::R32G32_FLOAT);
+ case DXGI_FORMAT_R32G32_SINT:
+ return Format::Get(FormatID::R32G32_SINT);
+ case DXGI_FORMAT_R32G32_TYPELESS:
+ break;
+ case DXGI_FORMAT_R32G32_UINT:
+ return Format::Get(FormatID::R32G32_UINT);
+ case DXGI_FORMAT_R32G8X24_TYPELESS:
+ break;
+ case DXGI_FORMAT_R32_FLOAT:
+ return Format::Get(FormatID::R32_FLOAT);
+ case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
+ break;
+ case DXGI_FORMAT_R32_SINT:
+ return Format::Get(FormatID::R32_SINT);
+ case DXGI_FORMAT_R32_TYPELESS:
+ break;
+ case DXGI_FORMAT_R32_UINT:
+ return Format::Get(FormatID::R32_UINT);
+ case DXGI_FORMAT_R8G8B8A8_SINT:
+ return Format::Get(FormatID::R8G8B8A8_SINT);
+ case DXGI_FORMAT_R8G8B8A8_SNORM:
+ return Format::Get(FormatID::R8G8B8A8_SNORM);
+ case DXGI_FORMAT_R8G8B8A8_TYPELESS:
+ return Format::Get(FormatID::R8G8B8A8_TYPELESS);
+ case DXGI_FORMAT_R8G8B8A8_UINT:
+ return Format::Get(FormatID::R8G8B8A8_UINT);
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ return Format::Get(FormatID::R8G8B8A8_UNORM);
+ case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
+ return Format::Get(FormatID::R8G8B8A8_UNORM_SRGB);
+ case DXGI_FORMAT_R8G8_B8G8_UNORM:
+ break;
+ case DXGI_FORMAT_R8G8_SINT:
+ return Format::Get(FormatID::R8G8_SINT);
+ case DXGI_FORMAT_R8G8_SNORM:
+ return Format::Get(FormatID::R8G8_SNORM);
+ case DXGI_FORMAT_R8G8_TYPELESS:
+ break;
+ case DXGI_FORMAT_R8G8_UINT:
+ return Format::Get(FormatID::R8G8_UINT);
+ case DXGI_FORMAT_R8G8_UNORM:
+ return Format::Get(FormatID::R8G8_UNORM);
+ case DXGI_FORMAT_R8_SINT:
+ return Format::Get(FormatID::R8_SINT);
+ case DXGI_FORMAT_R8_SNORM:
+ return Format::Get(FormatID::R8_SNORM);
+ case DXGI_FORMAT_R8_TYPELESS:
+ break;
+ case DXGI_FORMAT_R8_UINT:
+ return Format::Get(FormatID::R8_UINT);
+ case DXGI_FORMAT_R8_UNORM:
+ return Format::Get(FormatID::R8_UNORM);
+ case DXGI_FORMAT_R9G9B9E5_SHAREDEXP:
+ return Format::Get(FormatID::R9G9B9E5_SHAREDEXP);
+ case DXGI_FORMAT_UNKNOWN:
+ return Format::Get(FormatID::NONE);
+ case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
+ break;
+ case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
+ break;
+ case DXGI_FORMAT_Y210:
+ break;
+ case DXGI_FORMAT_Y216:
+ break;
+ case DXGI_FORMAT_Y410:
+ break;
+ case DXGI_FORMAT_Y416:
+ break;
+ case DXGI_FORMAT_YUY2:
+ break;
+ default:
+ break;
+ }
+
+ UNREACHABLE();
+ return Format::Get(FormatID::NONE);
+}
+
+} // namespace d3d11_angle
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/dxgi_support_table.h b/gfx/angle/checkout/src/libANGLE/renderer/dxgi_support_table.h
new file mode 100644
index 0000000000..fef57d0a1b
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/dxgi_support_table.h
@@ -0,0 +1,43 @@
+//
+// 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.
+//
+// dxgi_support_table:
+// Queries for DXGI support of various texture formats. Depends on DXGI
+// version, D3D feature level, and is sometimes guaranteed or optional.
+//
+
+#ifndef LIBANGLE_RENDERER_DXGI_SUPPORT_TABLE_H_
+#define LIBANGLE_RENDERER_DXGI_SUPPORT_TABLE_H_
+
+#include "common/platform.h"
+
+namespace rx
+{
+
+namespace d3d11
+{
+
+struct DXGISupport
+{
+ DXGISupport() : alwaysSupportedFlags(0), neverSupportedFlags(0), optionallySupportedFlags(0) {}
+
+ DXGISupport(UINT alwaysSupportedIn, UINT neverSupportedIn, UINT optionallySupportedIn)
+ : alwaysSupportedFlags(alwaysSupportedIn),
+ neverSupportedFlags(neverSupportedIn),
+ optionallySupportedFlags(optionallySupportedIn)
+ {}
+
+ UINT alwaysSupportedFlags;
+ UINT neverSupportedFlags;
+ UINT optionallySupportedFlags;
+};
+
+const DXGISupport &GetDXGISupport(DXGI_FORMAT dxgiFormat, D3D_FEATURE_LEVEL featureLevel);
+
+} // namespace d3d11
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_DXGI_SUPPORT_TABLE_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/dxgi_support_table_autogen.cpp b/gfx/angle/checkout/src/libANGLE/renderer/dxgi_support_table_autogen.cpp
new file mode 100644
index 0000000000..56bbaed0db
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/dxgi_support_table_autogen.cpp
@@ -0,0 +1,3042 @@
+// GENERATED FILE - DO NOT EDIT. See dxgi_support_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.
+//
+// dxgi_support_table:
+// Queries for DXGI support of various texture formats. Depends on DXGI
+// version, D3D feature level, and is sometimes guaranteed or optional.
+//
+
+#include "libANGLE/renderer/dxgi_support_table.h"
+
+#include "common/debug.h"
+
+namespace rx
+{
+
+namespace d3d11
+{
+
+#define F_2D D3D11_FORMAT_SUPPORT_TEXTURE2D
+#define F_3D D3D11_FORMAT_SUPPORT_TEXTURE3D
+#define F_CUBE D3D11_FORMAT_SUPPORT_TEXTURECUBE
+#define F_SAMPLE D3D11_FORMAT_SUPPORT_SHADER_SAMPLE
+#define F_RT D3D11_FORMAT_SUPPORT_RENDER_TARGET
+#define F_MS D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET
+#define F_DS D3D11_FORMAT_SUPPORT_DEPTH_STENCIL
+#define F_MIPGEN D3D11_FORMAT_SUPPORT_MIP_AUTOGEN
+
+namespace
+{
+
+const DXGISupport &GetDefaultSupport()
+{
+ static UINT AllSupportFlags =
+ D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_TEXTURE3D |
+ D3D11_FORMAT_SUPPORT_TEXTURECUBE | D3D11_FORMAT_SUPPORT_SHADER_SAMPLE |
+ D3D11_FORMAT_SUPPORT_RENDER_TARGET | D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET |
+ D3D11_FORMAT_SUPPORT_DEPTH_STENCIL | D3D11_FORMAT_SUPPORT_MIP_AUTOGEN;
+ static const DXGISupport defaultSupport(0, 0, AllSupportFlags);
+ return defaultSupport;
+}
+
+const DXGISupport &GetDXGISupport_9_3(DXGI_FORMAT dxgiFormat)
+{
+ // clang-format off
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_420_OPAQUE:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_A8P8:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_A8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_AI44:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_AYUV:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_B4G4R4A4_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_SAMPLE, F_DS, F_MS | F_RT);
+ return info;
+ }
+ case DXGI_FORMAT_B5G5R5A1_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_SAMPLE, F_DS, F_MS | F_RT);
+ return info;
+ }
+ case DXGI_FORMAT_B5G6R5_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8A8_TYPELESS:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8A8_UNORM:
+ {
+ static const DXGISupport info(F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_2D | F_3D | F_CUBE | F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_MIPGEN | F_RT, F_DS, F_2D | F_3D | F_CUBE | F_MS | F_SAMPLE);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8X8_TYPELESS:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8X8_UNORM:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN, F_2D | F_3D | F_CUBE | F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN, F_2D | F_3D | F_CUBE | F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_BC1_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC1_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC1_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC2_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC2_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC2_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC3_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC3_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC3_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC4_SNORM:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC4_TYPELESS:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC4_UNORM:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC5_SNORM:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC5_TYPELESS:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC5_UNORM:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC6H_SF16:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC6H_TYPELESS:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC6H_UF16:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC7_TYPELESS:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC7_UNORM:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC7_UNORM_SRGB:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_D16_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_D24_UNORM_S8_UINT:
+ {
+ static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_D32_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_CUBE, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
+ {
+ static const DXGISupport info(F_2D | F_CUBE, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_G8R8_G8B8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_IA44:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_NV11:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_NV12:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_P010:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_P016:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_P8:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R10G10B10A2_TYPELESS:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R10G10B10A2_UINT:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R10G10B10A2_UNORM:
+ {
+ static const DXGISupport info(0, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
+ {
+ static const DXGISupport info(0, F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D);
+ return info;
+ }
+ case DXGI_FORMAT_R11G11B10_FLOAT:
+ {
+ static const DXGISupport info(0, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT, F_DS, F_MS | F_SAMPLE);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_SINT:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_SNORM:
+ {
+ static const DXGISupport info(0, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_UINT:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_SINT:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_UINT:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16_FLOAT:
+ {
+ static const DXGISupport info(0, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16_SINT:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16_SNORM:
+ {
+ static const DXGISupport info(0, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R16_UINT:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R1_UNORM:
+ {
+ static const DXGISupport info(F_2D, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R24G8_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32A32_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32A32_SINT:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32A32_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32A32_UINT:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN, F_MS | F_RT);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_SAMPLE, F_MS | F_RT);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_SAMPLE, F_MS | F_RT);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32_SINT:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32_UINT:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G8X24_TYPELESS:
+ {
+ static const DXGISupport info(0, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32_SINT:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32_TYPELESS:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32_UINT:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_SINT:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_UINT:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_B8G8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_SINT:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_UINT:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_UNORM:
+ {
+ static const DXGISupport info(0, F_DS, F_MS | F_RT | F_SAMPLE);
+ return info;
+ }
+ case DXGI_FORMAT_R8_SINT:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8_SNORM:
+ {
+ static const DXGISupport info(0, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R8_UINT:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS, F_MS | F_RT);
+ return info;
+ }
+ case DXGI_FORMAT_R9G9B9E5_SHAREDEXP:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_UNKNOWN:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
+ {
+ static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
+ {
+ static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_Y210:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_Y216:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_Y410:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_Y416:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_YUY2:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+
+ default:
+ UNREACHABLE();
+ return GetDefaultSupport();
+ }
+ // clang-format on
+}
+
+const DXGISupport &GetDXGISupport_10_0(DXGI_FORMAT dxgiFormat)
+{
+ // clang-format off
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_420_OPAQUE:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_A8P8:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_A8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_AI44:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_AYUV:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_B4G4R4A4_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_SAMPLE, F_DS, F_MS | F_RT);
+ return info;
+ }
+ case DXGI_FORMAT_B5G5R5A1_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_SAMPLE, F_DS, F_MS | F_RT);
+ return info;
+ }
+ case DXGI_FORMAT_B5G6R5_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8A8_TYPELESS:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8A8_UNORM:
+ {
+ static const DXGISupport info(F_MIPGEN, F_DS, F_2D | F_3D | F_CUBE | F_MS | F_RT | F_SAMPLE);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_MIPGEN | F_RT, F_DS, F_2D | F_3D | F_CUBE | F_MS | F_SAMPLE);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8X8_TYPELESS:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8X8_UNORM:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN, F_2D | F_3D | F_CUBE | F_MS | F_SAMPLE);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN, F_2D | F_3D | F_CUBE | F_MS | F_SAMPLE);
+ return info;
+ }
+ case DXGI_FORMAT_BC1_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC1_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC1_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC2_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC2_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC2_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC3_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC3_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC3_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC4_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC4_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC4_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC5_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC5_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC5_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC6H_SF16:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC6H_TYPELESS:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC6H_UF16:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC7_TYPELESS:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC7_UNORM:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC7_UNORM_SRGB:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_D16_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_D24_UNORM_S8_UINT:
+ {
+ static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_D32_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
+ {
+ static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_G8R8_G8B8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_IA44:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_NV11:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_NV12:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_P010:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_P016:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_P8:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R10G10B10A2_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R10G10B10A2_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R10G10B10A2_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
+ {
+ static const DXGISupport info(0, F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D);
+ return info;
+ }
+ case DXGI_FORMAT_R11G11B10_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R16_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R1_UNORM:
+ {
+ static const DXGISupport info(F_2D, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R24G8_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT, F_SAMPLE);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32A32_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT, F_DS, F_MS | F_SAMPLE);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32A32_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32A32_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32A32_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN, F_MS | F_RT);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_SAMPLE, F_MS | F_RT);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_SAMPLE, F_MS | F_RT);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT, F_DS, F_MS | F_SAMPLE);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G8X24_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT, F_DS, F_MS | F_SAMPLE);
+ return info;
+ }
+ case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT, F_SAMPLE);
+ return info;
+ }
+ case DXGI_FORMAT_R32_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_B8G8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R8_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R9G9B9E5_SHAREDEXP:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_UNKNOWN:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
+ {
+ static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
+ {
+ static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_Y210:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_Y216:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_Y410:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_Y416:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_YUY2:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+
+ default:
+ UNREACHABLE();
+ return GetDefaultSupport();
+ }
+ // clang-format on
+}
+
+const DXGISupport &GetDXGISupport_10_1(DXGI_FORMAT dxgiFormat)
+{
+ // clang-format off
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_420_OPAQUE:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_A8P8:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_A8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_AI44:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_AYUV:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_B4G4R4A4_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_SAMPLE, F_DS, F_MS | F_RT);
+ return info;
+ }
+ case DXGI_FORMAT_B5G5R5A1_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_SAMPLE, F_DS, F_MS | F_RT);
+ return info;
+ }
+ case DXGI_FORMAT_B5G6R5_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8A8_TYPELESS:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8A8_UNORM:
+ {
+ static const DXGISupport info(F_MIPGEN, F_DS, F_2D | F_3D | F_CUBE | F_MS | F_RT | F_SAMPLE);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_MIPGEN | F_RT, F_DS, F_2D | F_3D | F_CUBE | F_MS | F_SAMPLE);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8X8_TYPELESS:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8X8_UNORM:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN, F_2D | F_3D | F_CUBE | F_MS | F_SAMPLE);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN, F_2D | F_3D | F_CUBE | F_MS | F_SAMPLE);
+ return info;
+ }
+ case DXGI_FORMAT_BC1_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC1_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC1_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC2_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC2_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC2_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC3_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC3_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC3_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC4_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC4_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC4_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC5_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC5_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC5_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC6H_SF16:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC6H_TYPELESS:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC6H_UF16:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC7_TYPELESS:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC7_UNORM:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC7_UNORM_SRGB:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_D16_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_D24_UNORM_S8_UINT:
+ {
+ static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_D32_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
+ {
+ static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_G8R8_G8B8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_IA44:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_NV11:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_NV12:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_P010:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_P016:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_P8:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R10G10B10A2_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R10G10B10A2_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R10G10B10A2_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
+ {
+ static const DXGISupport info(0, F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D);
+ return info;
+ }
+ case DXGI_FORMAT_R11G11B10_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R16_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R1_UNORM:
+ {
+ static const DXGISupport info(F_2D, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R24G8_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_CUBE | F_SAMPLE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32A32_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32A32_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32A32_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32A32_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN, F_MS | F_RT);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_SAMPLE, F_MS | F_RT);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_SAMPLE, F_MS | F_RT);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G8X24_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_CUBE | F_SAMPLE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_B8G8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R8_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R9G9B9E5_SHAREDEXP:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_UNKNOWN:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
+ {
+ static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
+ {
+ static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_Y210:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_Y216:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_Y410:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_Y416:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_YUY2:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+
+ default:
+ UNREACHABLE();
+ return GetDefaultSupport();
+ }
+ // clang-format on
+}
+
+const DXGISupport &GetDXGISupport_11_0(DXGI_FORMAT dxgiFormat)
+{
+ // clang-format off
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_420_OPAQUE:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_A8P8:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_A8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_AI44:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_AYUV:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_B4G4R4A4_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_SAMPLE, F_DS, F_MS | F_RT);
+ return info;
+ }
+ case DXGI_FORMAT_B5G5R5A1_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_SAMPLE, F_DS, F_MS | F_RT);
+ return info;
+ }
+ case DXGI_FORMAT_B5G6R5_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8A8_TYPELESS:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8A8_UNORM:
+ {
+ static const DXGISupport info(F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_2D | F_3D | F_CUBE | F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_2D | F_3D | F_CUBE | F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8X8_TYPELESS:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8X8_UNORM:
+ {
+ static const DXGISupport info(F_RT | F_SAMPLE, F_DS | F_MIPGEN, F_2D | F_3D | F_CUBE | F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_RT | F_SAMPLE, F_DS | F_MIPGEN, F_2D | F_3D | F_CUBE | F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_BC1_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC1_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC1_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC2_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC2_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC2_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC3_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC3_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC3_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC4_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC4_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC4_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC5_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC5_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC5_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC6H_SF16:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC6H_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC6H_UF16:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC7_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC7_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC7_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_D16_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_D24_UNORM_S8_UINT:
+ {
+ static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_D32_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
+ {
+ static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_G8R8_G8B8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_IA44:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_NV11:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_NV12:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_P010:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_P016:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_P8:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R10G10B10A2_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R10G10B10A2_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R10G10B10A2_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
+ {
+ static const DXGISupport info(0, F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D);
+ return info;
+ }
+ case DXGI_FORMAT_R11G11B10_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R16_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R1_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R24G8_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_CUBE | F_SAMPLE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32A32_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32A32_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32A32_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32A32_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN, F_MS | F_RT);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_SAMPLE, F_MS | F_RT);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_SAMPLE, F_MS | F_RT);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G8X24_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_CUBE | F_SAMPLE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_B8G8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R8_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R9G9B9E5_SHAREDEXP:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_UNKNOWN:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
+ {
+ static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
+ {
+ static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_Y210:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_Y216:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_Y410:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_Y416:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_YUY2:
+ {
+ static const DXGISupport info(0, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+
+ default:
+ UNREACHABLE();
+ return GetDefaultSupport();
+ }
+ // clang-format on
+}
+
+const DXGISupport &GetDXGISupport_11_1(DXGI_FORMAT dxgiFormat)
+{
+ // clang-format off
+ switch (dxgiFormat)
+ {
+ case DXGI_FORMAT_420_OPAQUE:
+ {
+ static const DXGISupport info(F_2D, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_A8P8:
+ {
+ static const DXGISupport info(F_2D, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_A8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_AI44:
+ {
+ static const DXGISupport info(F_2D, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_AYUV:
+ {
+ static const DXGISupport info(F_2D | F_RT | F_SAMPLE, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_B4G4R4A4_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_SAMPLE, F_DS, F_MS | F_RT);
+ return info;
+ }
+ case DXGI_FORMAT_B5G5R5A1_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_SAMPLE, F_DS, F_MS | F_RT);
+ return info;
+ }
+ case DXGI_FORMAT_B5G6R5_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8A8_TYPELESS:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8A8_UNORM:
+ {
+ static const DXGISupport info(F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_2D | F_3D | F_CUBE | F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_2D | F_3D | F_CUBE | F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8X8_TYPELESS:
+ {
+ static const DXGISupport info(0, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D | F_CUBE);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8X8_UNORM:
+ {
+ static const DXGISupport info(F_RT | F_SAMPLE, F_DS | F_MIPGEN, F_2D | F_3D | F_CUBE | F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_RT | F_SAMPLE, F_DS | F_MIPGEN, F_2D | F_3D | F_CUBE | F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_BC1_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC1_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC1_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC2_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC2_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC2_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC3_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC3_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC3_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC4_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC4_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC4_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC5_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC5_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC5_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC6H_SF16:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC6H_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC6H_UF16:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC7_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC7_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_BC7_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_D16_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_D24_UNORM_S8_UINT:
+ {
+ static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_D32_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
+ {
+ static const DXGISupport info(F_2D | F_CUBE | F_DS, F_3D | F_MIPGEN | F_RT | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_G8R8_G8B8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_IA44:
+ {
+ static const DXGISupport info(F_2D, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_NV11:
+ {
+ static const DXGISupport info(F_2D | F_RT | F_SAMPLE, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_NV12:
+ {
+ static const DXGISupport info(F_2D | F_RT | F_SAMPLE, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_P010:
+ {
+ static const DXGISupport info(F_2D | F_RT | F_SAMPLE, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_P016:
+ {
+ static const DXGISupport info(F_2D | F_RT | F_SAMPLE, F_3D | F_CUBE | F_DS | F_MIPGEN, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_P8:
+ {
+ static const DXGISupport info(F_2D, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R10G10B10A2_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R10G10B10A2_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R10G10B10A2_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
+ {
+ static const DXGISupport info(0, F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, F_2D | F_3D);
+ return info;
+ }
+ case DXGI_FORMAT_R11G11B10_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16B16A16_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16G16_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R16_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R16_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R1_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R24G8_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_CUBE | F_SAMPLE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32A32_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32A32_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32A32_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32A32_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN, F_MS | F_RT);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_SAMPLE, F_MS | F_RT);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32B32_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_SAMPLE, F_MS | F_RT);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32G32_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32G8X24_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32_FLOAT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_CUBE | F_SAMPLE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R32_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R32_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_B8G8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8G8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8_SINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8_SNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8_TYPELESS:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE, F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_R8_UINT:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_RT, F_DS | F_MIPGEN | F_SAMPLE, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R8_UNORM:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_MIPGEN | F_RT | F_SAMPLE, F_DS, F_MS);
+ return info;
+ }
+ case DXGI_FORMAT_R9G9B9E5_SHAREDEXP:
+ {
+ static const DXGISupport info(F_2D | F_3D | F_CUBE | F_SAMPLE, F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_UNKNOWN:
+ {
+ static const DXGISupport info(0, F_2D | F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
+ {
+ static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
+ {
+ static const DXGISupport info(F_2D | F_CUBE, F_3D | F_DS | F_MIPGEN | F_MS | F_RT | F_SAMPLE, 0);
+ return info;
+ }
+ case DXGI_FORMAT_Y210:
+ {
+ static const DXGISupport info(F_2D | F_SAMPLE, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_Y216:
+ {
+ static const DXGISupport info(F_2D | F_SAMPLE, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_Y410:
+ {
+ static const DXGISupport info(F_2D | F_SAMPLE, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_Y416:
+ {
+ static const DXGISupport info(F_2D | F_SAMPLE, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+ case DXGI_FORMAT_YUY2:
+ {
+ static const DXGISupport info(F_2D | F_SAMPLE, F_3D | F_CUBE | F_DS | F_MIPGEN | F_MS | F_RT, 0);
+ return info;
+ }
+
+ default:
+ UNREACHABLE();
+ return GetDefaultSupport();
+ }
+ // clang-format on
+}
+
+} // namespace
+
+#undef F_2D
+#undef F_3D
+#undef F_CUBE
+#undef F_SAMPLE
+#undef F_RT
+#undef F_MS
+#undef F_DS
+#undef F_MIPGEN
+
+const DXGISupport &GetDXGISupport(DXGI_FORMAT dxgiFormat, D3D_FEATURE_LEVEL featureLevel)
+{
+ switch (featureLevel)
+ {
+ case D3D_FEATURE_LEVEL_9_3:
+ return GetDXGISupport_9_3(dxgiFormat);
+ case D3D_FEATURE_LEVEL_10_0:
+ return GetDXGISupport_10_0(dxgiFormat);
+ case D3D_FEATURE_LEVEL_10_1:
+ return GetDXGISupport_10_1(dxgiFormat);
+ case D3D_FEATURE_LEVEL_11_0:
+ return GetDXGISupport_11_0(dxgiFormat);
+ case D3D_FEATURE_LEVEL_11_1:
+ return GetDXGISupport_11_1(dxgiFormat);
+ default:
+ return GetDefaultSupport();
+ }
+}
+
+} // namespace d3d11
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/gl/functionsgl_enums.h b/gfx/angle/checkout/src/libANGLE/renderer/gl/functionsgl_enums.h
new file mode 100644
index 0000000000..667436e915
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/gl/functionsgl_enums.h
@@ -0,0 +1,1376 @@
+//
+// 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.
+//
+
+// functionsgl_enums.h: OpenGL enums for versions 1.0 through 4.5.
+
+#ifndef LIBANGLE_RENDERER_GL_FUNCTIONSGLENUMS_H_
+#define LIBANGLE_RENDERER_GL_FUNCTIONSGLENUMS_H_
+
+// 1.0
+#define GL_ALPHA 0x1906
+#define GL_ALWAYS 0x0207
+#define GL_AND 0x1501
+#define GL_AND_INVERTED 0x1504
+#define GL_AND_REVERSE 0x1502
+#define GL_BACK 0x0405
+#define GL_BACK_LEFT 0x0402
+#define GL_BACK_RIGHT 0x0403
+#define GL_BLEND 0x0BE2
+#define GL_BLEND_DST 0x0BE0
+#define GL_BLEND_SRC 0x0BE1
+#define GL_BLUE 0x1905
+#define GL_BYTE 0x1400
+#define GL_CCW 0x0901
+#define GL_CLEAR 0x1500
+#define GL_COLOR 0x1800
+#define GL_COLOR_BUFFER_BIT 0x00004000
+#define GL_COLOR_CLEAR_VALUE 0x0C22
+#define GL_COLOR_LOGIC_OP 0x0BF2
+#define GL_COLOR_WRITEMASK 0x0C23
+#define GL_COPY 0x1503
+#define GL_COPY_INVERTED 0x150C
+#define GL_CULL_FACE 0x0B44
+#define GL_CULL_FACE_MODE 0x0B45
+#define GL_CW 0x0900
+#define GL_DECR 0x1E03
+#define GL_DEPTH 0x1801
+#define GL_DEPTH_BUFFER_BIT 0x00000100
+#define GL_DEPTH_CLEAR_VALUE 0x0B73
+#define GL_DEPTH_COMPONENT 0x1902
+#define GL_DEPTH_FUNC 0x0B74
+#define GL_DEPTH_RANGE 0x0B70
+#define GL_DEPTH_TEST 0x0B71
+#define GL_DEPTH_WRITEMASK 0x0B72
+#define GL_DITHER 0x0BD0
+#define GL_DONT_CARE 0x1100
+#define GL_DOUBLE 0x140A
+#define GL_DOUBLEBUFFER 0x0C32
+#define GL_DRAW_BUFFER 0x0C01
+#define GL_DST_ALPHA 0x0304
+#define GL_DST_COLOR 0x0306
+#define GL_EQUAL 0x0202
+#define GL_EQUIV 0x1509
+#define GL_EXTENSIONS 0x1F03
+#define GL_FALSE 0
+#define GL_FASTEST 0x1101
+#define GL_FILL 0x1B02
+#define GL_FLOAT 0x1406
+#define GL_FRONT 0x0404
+#define GL_FRONT_AND_BACK 0x0408
+#define GL_FRONT_FACE 0x0B46
+#define GL_FRONT_LEFT 0x0400
+#define GL_FRONT_RIGHT 0x0401
+#define GL_GEQUAL 0x0206
+#define GL_GREATER 0x0204
+#define GL_GREEN 0x1904
+#define GL_INCR 0x1E02
+#define GL_INT 0x1404
+#define GL_INVALID_ENUM 0x0500
+#define GL_INVALID_OPERATION 0x0502
+#define GL_INVALID_VALUE 0x0501
+#define GL_INVERT 0x150A
+#define GL_KEEP 0x1E00
+#define GL_LEFT 0x0406
+#define GL_LEQUAL 0x0203
+#define GL_LESS 0x0201
+#define GL_LINE 0x1B01
+#define GL_LINEAR 0x2601
+#define GL_LINEAR_MIPMAP_LINEAR 0x2703
+#define GL_LINEAR_MIPMAP_NEAREST 0x2701
+#define GL_LINES 0x0001
+#define GL_LINE_LOOP 0x0002
+#define GL_LINE_SMOOTH 0x0B20
+#define GL_LINE_SMOOTH_HINT 0x0C52
+#define GL_LINE_STRIP 0x0003
+#define GL_LINE_WIDTH 0x0B21
+#define GL_LINE_WIDTH_GRANULARITY 0x0B23
+#define GL_LINE_WIDTH_RANGE 0x0B22
+#define GL_LOGIC_OP_MODE 0x0BF0
+#define GL_MAX_TEXTURE_SIZE 0x0D33
+#define GL_MAX_VIEWPORT_DIMS 0x0D3A
+#define GL_NAND 0x150E
+#define GL_NEAREST 0x2600
+#define GL_NEAREST_MIPMAP_LINEAR 0x2702
+#define GL_NEAREST_MIPMAP_NEAREST 0x2700
+#define GL_NEVER 0x0200
+#define GL_NICEST 0x1102
+#define GL_NONE 0
+#define GL_NOOP 0x1505
+#define GL_NOR 0x1508
+#define GL_NOTEQUAL 0x0205
+#define GL_NO_ERROR 0
+#define GL_ONE 1
+#define GL_ONE_MINUS_DST_ALPHA 0x0305
+#define GL_ONE_MINUS_DST_COLOR 0x0307
+#define GL_ONE_MINUS_SRC_ALPHA 0x0303
+#define GL_ONE_MINUS_SRC_COLOR 0x0301
+#define GL_OR 0x1507
+#define GL_OR_INVERTED 0x150D
+#define GL_OR_REVERSE 0x150B
+#define GL_OUT_OF_MEMORY 0x0505
+#define GL_PACK_ALIGNMENT 0x0D05
+#define GL_PACK_LSB_FIRST 0x0D01
+#define GL_PACK_ROW_LENGTH 0x0D02
+#define GL_PACK_SKIP_PIXELS 0x0D04
+#define GL_PACK_SKIP_ROWS 0x0D03
+#define GL_PACK_SWAP_BYTES 0x0D00
+#define GL_POINT 0x1B00
+#define GL_POINTS 0x0000
+#define GL_POINT_SIZE 0x0B11
+#define GL_POINT_SIZE_GRANULARITY 0x0B13
+#define GL_POINT_SIZE_RANGE 0x0B12
+#define GL_POLYGON_MODE 0x0B40
+#define GL_POLYGON_OFFSET_FACTOR 0x8038
+#define GL_POLYGON_OFFSET_FILL 0x8037
+#define GL_POLYGON_OFFSET_LINE 0x2A02
+#define GL_POLYGON_OFFSET_POINT 0x2A01
+#define GL_POLYGON_OFFSET_UNITS 0x2A00
+#define GL_POLYGON_SMOOTH 0x0B41
+#define GL_POLYGON_SMOOTH_HINT 0x0C53
+#define GL_PROXY_TEXTURE_1D 0x8063
+#define GL_PROXY_TEXTURE_2D 0x8064
+#define GL_QUADS 0x0007
+#define GL_R3_G3_B2 0x2A10
+#define GL_READ_BUFFER 0x0C02
+#define GL_RED 0x1903
+#define GL_RENDERER 0x1F01
+#define GL_REPEAT 0x2901
+#define GL_REPLACE 0x1E01
+#define GL_RGB 0x1907
+#define GL_RGB10 0x8052
+#define GL_RGB10_A2 0x8059
+#define GL_RGB12 0x8053
+#define GL_RGB16 0x8054
+#define GL_RGB4 0x804F
+#define GL_RGB5 0x8050
+#define GL_RGB5_A1 0x8057
+#define GL_RGB8 0x8051
+#define GL_RGBA 0x1908
+#define GL_RGBA12 0x805A
+#define GL_RGBA16 0x805B
+#define GL_RGBA2 0x8055
+#define GL_RGBA4 0x8056
+#define GL_RGBA8 0x8058
+#define GL_RIGHT 0x0407
+#define GL_SCISSOR_BOX 0x0C10
+#define GL_SCISSOR_TEST 0x0C11
+#define GL_SET 0x150F
+#define GL_SHORT 0x1402
+#define GL_SRC_ALPHA 0x0302
+#define GL_SRC_ALPHA_SATURATE 0x0308
+#define GL_SRC_COLOR 0x0300
+#define GL_STENCIL 0x1802
+#define GL_STENCIL_BUFFER_BIT 0x00000400
+#define GL_STENCIL_CLEAR_VALUE 0x0B91
+#define GL_STENCIL_FAIL 0x0B94
+#define GL_STENCIL_FUNC 0x0B92
+#define GL_STENCIL_INDEX 0x1901
+#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95
+#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96
+#define GL_STENCIL_REF 0x0B97
+#define GL_STENCIL_TEST 0x0B90
+#define GL_STENCIL_VALUE_MASK 0x0B93
+#define GL_STENCIL_WRITEMASK 0x0B98
+#define GL_STEREO 0x0C33
+#define GL_SUBPIXEL_BITS 0x0D50
+#define GL_TEXTURE 0x1702
+#define GL_TEXTURE_1D 0x0DE0
+#define GL_TEXTURE_2D 0x0DE1
+#define GL_TEXTURE_ALPHA_SIZE 0x805F
+#define GL_TEXTURE_BINDING_1D 0x8068
+#define GL_TEXTURE_BINDING_2D 0x8069
+#define GL_TEXTURE_BLUE_SIZE 0x805E
+#define GL_TEXTURE_BORDER_COLOR 0x1004
+#define GL_TEXTURE_GREEN_SIZE 0x805D
+#define GL_TEXTURE_HEIGHT 0x1001
+#define GL_TEXTURE_INTERNAL_FORMAT 0x1003
+#define GL_TEXTURE_MAG_FILTER 0x2800
+#define GL_TEXTURE_MIN_FILTER 0x2801
+#define GL_TEXTURE_RED_SIZE 0x805C
+#define GL_TEXTURE_WIDTH 0x1000
+#define GL_TEXTURE_WRAP_S 0x2802
+#define GL_TEXTURE_WRAP_T 0x2803
+#define GL_TRIANGLES 0x0004
+#define GL_TRIANGLE_FAN 0x0006
+#define GL_TRIANGLE_STRIP 0x0005
+#define GL_TRUE 1
+#define GL_UNPACK_ALIGNMENT 0x0CF5
+#define GL_UNPACK_LSB_FIRST 0x0CF1
+#define GL_UNPACK_ROW_LENGTH 0x0CF2
+#define GL_UNPACK_SKIP_PIXELS 0x0CF4
+#define GL_UNPACK_SKIP_ROWS 0x0CF3
+#define GL_UNPACK_SWAP_BYTES 0x0CF0
+#define GL_UNSIGNED_BYTE 0x1401
+#define GL_UNSIGNED_INT 0x1405
+#define GL_UNSIGNED_SHORT 0x1403
+#define GL_VENDOR 0x1F00
+#define GL_VERSION 0x1F02
+#define GL_VIEWPORT 0x0BA2
+#define GL_XOR 0x1506
+#define GL_ZERO 0
+
+// 1.2
+#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E
+#define GL_BGR 0x80E0
+#define GL_BGRA 0x80E1
+#define GL_CLAMP_TO_EDGE 0x812F
+#define GL_MAX_3D_TEXTURE_SIZE 0x8073
+#define GL_MAX_ELEMENTS_INDICES 0x80E9
+#define GL_MAX_ELEMENTS_VERTICES 0x80E8
+#define GL_PACK_IMAGE_HEIGHT 0x806C
+#define GL_PACK_SKIP_IMAGES 0x806B
+#define GL_PROXY_TEXTURE_3D 0x8070
+#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23
+#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22
+#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13
+#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12
+#define GL_TEXTURE_3D 0x806F
+#define GL_TEXTURE_BASE_LEVEL 0x813C
+#define GL_TEXTURE_BINDING_3D 0x806A
+#define GL_TEXTURE_DEPTH 0x8071
+#define GL_TEXTURE_MAX_LEVEL 0x813D
+#define GL_TEXTURE_MAX_LOD 0x813B
+#define GL_TEXTURE_MIN_LOD 0x813A
+#define GL_TEXTURE_WRAP_R 0x8072
+#define GL_UNPACK_IMAGE_HEIGHT 0x806E
+#define GL_UNPACK_SKIP_IMAGES 0x806D
+#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362
+#define GL_UNSIGNED_BYTE_3_3_2 0x8032
+#define GL_UNSIGNED_INT_10_10_10_2 0x8036
+#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
+#define GL_UNSIGNED_INT_8_8_8_8 0x8035
+#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
+#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366
+#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
+#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365
+#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
+#define GL_UNSIGNED_SHORT_5_6_5 0x8363
+#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364
+
+// 1.2 Extensions
+#define GL_ALL_COMPLETED_NV 0x84F2
+#define GL_FENCE_STATUS_NV 0x84F3
+#define GL_FENCE_CONDITION_NV 0x84F4
+
+// 1.3
+#define GL_ACTIVE_TEXTURE 0x84E0
+#define GL_CLAMP_TO_BORDER 0x812D
+#define GL_COMPRESSED_RGB 0x84ED
+#define GL_COMPRESSED_RGBA 0x84EE
+#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C
+#define GL_MULTISAMPLE 0x809D
+#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2
+#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B
+#define GL_SAMPLES 0x80A9
+#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E
+#define GL_SAMPLE_ALPHA_TO_ONE 0x809F
+#define GL_SAMPLE_BUFFERS 0x80A8
+#define GL_SAMPLE_COVERAGE 0x80A0
+#define GL_SAMPLE_COVERAGE_INVERT 0x80AB
+#define GL_SAMPLE_COVERAGE_VALUE 0x80AA
+#define GL_TEXTURE0 0x84C0
+#define GL_TEXTURE1 0x84C1
+#define GL_TEXTURE10 0x84CA
+#define GL_TEXTURE11 0x84CB
+#define GL_TEXTURE12 0x84CC
+#define GL_TEXTURE13 0x84CD
+#define GL_TEXTURE14 0x84CE
+#define GL_TEXTURE15 0x84CF
+#define GL_TEXTURE16 0x84D0
+#define GL_TEXTURE17 0x84D1
+#define GL_TEXTURE18 0x84D2
+#define GL_TEXTURE19 0x84D3
+#define GL_TEXTURE2 0x84C2
+#define GL_TEXTURE20 0x84D4
+#define GL_TEXTURE21 0x84D5
+#define GL_TEXTURE22 0x84D6
+#define GL_TEXTURE23 0x84D7
+#define GL_TEXTURE24 0x84D8
+#define GL_TEXTURE25 0x84D9
+#define GL_TEXTURE26 0x84DA
+#define GL_TEXTURE27 0x84DB
+#define GL_TEXTURE28 0x84DC
+#define GL_TEXTURE29 0x84DD
+#define GL_TEXTURE3 0x84C3
+#define GL_TEXTURE30 0x84DE
+#define GL_TEXTURE31 0x84DF
+#define GL_TEXTURE4 0x84C4
+#define GL_TEXTURE5 0x84C5
+#define GL_TEXTURE6 0x84C6
+#define GL_TEXTURE7 0x84C7
+#define GL_TEXTURE8 0x84C8
+#define GL_TEXTURE9 0x84C9
+#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514
+#define GL_TEXTURE_COMPRESSED 0x86A1
+#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0
+#define GL_TEXTURE_COMPRESSION_HINT 0x84EF
+#define GL_TEXTURE_CUBE_MAP 0x8513
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519
+
+// 1.5
+#define GL_BLEND_COLOR 0x8005
+#define GL_BLEND_DST_ALPHA 0x80CA
+#define GL_BLEND_DST_RGB 0x80C8
+#define GL_BLEND_EQUATION 0x8009
+#define GL_BLEND_SRC_ALPHA 0x80CB
+#define GL_BLEND_SRC_RGB 0x80C9
+#define GL_CONSTANT_ALPHA 0x8003
+#define GL_CONSTANT_COLOR 0x8001
+#define GL_DECR_WRAP 0x8508
+#define GL_DEPTH_COMPONENT16 0x81A5
+#define GL_DEPTH_COMPONENT24 0x81A6
+#define GL_DEPTH_COMPONENT32 0x81A7
+#define GL_FUNC_ADD 0x8006
+#define GL_FUNC_REVERSE_SUBTRACT 0x800B
+#define GL_FUNC_SUBTRACT 0x800A
+#define GL_INCR_WRAP 0x8507
+#define GL_MAX 0x8008
+#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD
+#define GL_MIN 0x8007
+#define GL_MIRRORED_REPEAT 0x8370
+#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004
+#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002
+#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128
+#define GL_TEXTURE_COMPARE_FUNC 0x884D
+#define GL_TEXTURE_COMPARE_MODE 0x884C
+#define GL_TEXTURE_DEPTH_SIZE 0x884A
+#define GL_TEXTURE_LOD_BIAS 0x8501
+
+// 1.5
+#define GL_ARRAY_BUFFER 0x8892
+#define GL_ARRAY_BUFFER_BINDING 0x8894
+#define GL_BUFFER_ACCESS 0x88BB
+#define GL_BUFFER_MAPPED 0x88BC
+#define GL_BUFFER_MAP_POINTER 0x88BD
+#define GL_BUFFER_SIZE 0x8764
+#define GL_BUFFER_USAGE 0x8765
+#define GL_CURRENT_QUERY 0x8865
+#define GL_DYNAMIC_COPY 0x88EA
+#define GL_DYNAMIC_DRAW 0x88E8
+#define GL_DYNAMIC_READ 0x88E9
+#define GL_ELEMENT_ARRAY_BUFFER 0x8893
+#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
+#define GL_QUERY_COUNTER_BITS 0x8864
+#define GL_QUERY_RESULT 0x8866
+#define GL_QUERY_RESULT_AVAILABLE 0x8867
+#define GL_READ_ONLY 0x88B8
+#define GL_READ_WRITE 0x88BA
+#define GL_SAMPLES_PASSED 0x8914
+#define GL_SRC1_ALPHA 0x8589
+#define GL_STATIC_COPY 0x88E6
+#define GL_STATIC_DRAW 0x88E4
+#define GL_STATIC_READ 0x88E5
+#define GL_STREAM_COPY 0x88E2
+#define GL_STREAM_DRAW 0x88E0
+#define GL_STREAM_READ 0x88E1
+#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F
+#define GL_WRITE_ONLY 0x88B9
+
+// 2.0
+#define GL_ACTIVE_ATTRIBUTES 0x8B89
+#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A
+#define GL_ACTIVE_UNIFORMS 0x8B86
+#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87
+#define GL_ATTACHED_SHADERS 0x8B85
+#define GL_BLEND_EQUATION_ALPHA 0x883D
+#define GL_BLEND_EQUATION_RGB 0x8009
+#define GL_BOOL 0x8B56
+#define GL_BOOL_VEC2 0x8B57
+#define GL_BOOL_VEC3 0x8B58
+#define GL_BOOL_VEC4 0x8B59
+#define GL_COMPILE_STATUS 0x8B81
+#define GL_CURRENT_PROGRAM 0x8B8D
+#define GL_CURRENT_VERTEX_ATTRIB 0x8626
+#define GL_DELETE_STATUS 0x8B80
+#define GL_DRAW_BUFFER0 0x8825
+#define GL_DRAW_BUFFER1 0x8826
+#define GL_DRAW_BUFFER10 0x882F
+#define GL_DRAW_BUFFER11 0x8830
+#define GL_DRAW_BUFFER12 0x8831
+#define GL_DRAW_BUFFER13 0x8832
+#define GL_DRAW_BUFFER14 0x8833
+#define GL_DRAW_BUFFER15 0x8834
+#define GL_DRAW_BUFFER2 0x8827
+#define GL_DRAW_BUFFER3 0x8828
+#define GL_DRAW_BUFFER4 0x8829
+#define GL_DRAW_BUFFER5 0x882A
+#define GL_DRAW_BUFFER6 0x882B
+#define GL_DRAW_BUFFER7 0x882C
+#define GL_DRAW_BUFFER8 0x882D
+#define GL_DRAW_BUFFER9 0x882E
+#define GL_FLOAT_MAT2 0x8B5A
+#define GL_FLOAT_MAT3 0x8B5B
+#define GL_FLOAT_MAT4 0x8B5C
+#define GL_FLOAT_VEC2 0x8B50
+#define GL_FLOAT_VEC3 0x8B51
+#define GL_FLOAT_VEC4 0x8B52
+#define GL_FRAGMENT_SHADER 0x8B30
+#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B
+#define GL_INFO_LOG_LENGTH 0x8B84
+#define GL_INT_VEC2 0x8B53
+#define GL_INT_VEC3 0x8B54
+#define GL_INT_VEC4 0x8B55
+#define GL_LINK_STATUS 0x8B82
+#define GL_LOWER_LEFT 0x8CA1
+#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D
+#define GL_MAX_DRAW_BUFFERS 0x8824
+#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49
+#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872
+#define GL_MAX_VARYING_FLOATS 0x8B4B
+#define GL_MAX_VERTEX_ATTRIBS 0x8869
+#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C
+#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A
+#define GL_POINT_SPRITE 0x8861
+#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0
+#define GL_SAMPLER_1D 0x8B5D
+#define GL_SAMPLER_1D_SHADOW 0x8B61
+#define GL_SAMPLER_2D 0x8B5E
+#define GL_SAMPLER_2D_SHADOW 0x8B62
+#define GL_SAMPLER_3D 0x8B5F
+#define GL_SAMPLER_CUBE 0x8B60
+#define GL_SHADER_SOURCE_LENGTH 0x8B88
+#define GL_SHADER_TYPE 0x8B4F
+#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
+#define GL_STENCIL_BACK_FAIL 0x8801
+#define GL_STENCIL_BACK_FUNC 0x8800
+#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802
+#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803
+#define GL_STENCIL_BACK_REF 0x8CA3
+#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4
+#define GL_STENCIL_BACK_WRITEMASK 0x8CA5
+#define GL_UPPER_LEFT 0x8CA2
+#define GL_VALIDATE_STATUS 0x8B83
+#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
+#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A
+#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645
+#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
+#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624
+#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625
+#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642
+#define GL_VERTEX_SHADER 0x8B31
+
+// 2.1
+#define GL_COMPRESSED_SRGB 0x8C48
+#define GL_COMPRESSED_SRGB_ALPHA 0x8C49
+#define GL_FLOAT_MAT2x3 0x8B65
+#define GL_FLOAT_MAT2x4 0x8B66
+#define GL_FLOAT_MAT3x2 0x8B67
+#define GL_FLOAT_MAT3x4 0x8B68
+#define GL_FLOAT_MAT4x2 0x8B69
+#define GL_FLOAT_MAT4x3 0x8B6A
+#define GL_PIXEL_PACK_BUFFER 0x88EB
+#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED
+#define GL_PIXEL_UNPACK_BUFFER 0x88EC
+#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF
+#define GL_SRGB 0x8C40
+#define GL_SRGB8 0x8C41
+#define GL_SRGB8_ALPHA8 0x8C43
+#define GL_SRGB_ALPHA 0x8C42
+
+// 3.0
+#define GL_BGRA_INTEGER 0x8D9B
+#define GL_BGR_INTEGER 0x8D9A
+#define GL_BLUE_INTEGER 0x8D96
+#define GL_BUFFER_ACCESS_FLAGS 0x911F
+#define GL_BUFFER_MAP_LENGTH 0x9120
+#define GL_BUFFER_MAP_OFFSET 0x9121
+#define GL_CLAMP_READ_COLOR 0x891C
+#define GL_CLIP_DISTANCE0 0x3000
+#define GL_CLIP_DISTANCE1 0x3001
+#define GL_CLIP_DISTANCE2 0x3002
+#define GL_CLIP_DISTANCE3 0x3003
+#define GL_CLIP_DISTANCE4 0x3004
+#define GL_CLIP_DISTANCE5 0x3005
+#define GL_CLIP_DISTANCE6 0x3006
+#define GL_CLIP_DISTANCE7 0x3007
+#define GL_COLOR_ATTACHMENT0 0x8CE0
+#define GL_COLOR_ATTACHMENT1 0x8CE1
+#define GL_COLOR_ATTACHMENT10 0x8CEA
+#define GL_COLOR_ATTACHMENT11 0x8CEB
+#define GL_COLOR_ATTACHMENT12 0x8CEC
+#define GL_COLOR_ATTACHMENT13 0x8CED
+#define GL_COLOR_ATTACHMENT14 0x8CEE
+#define GL_COLOR_ATTACHMENT15 0x8CEF
+#define GL_COLOR_ATTACHMENT2 0x8CE2
+#define GL_COLOR_ATTACHMENT3 0x8CE3
+#define GL_COLOR_ATTACHMENT4 0x8CE4
+#define GL_COLOR_ATTACHMENT5 0x8CE5
+#define GL_COLOR_ATTACHMENT6 0x8CE6
+#define GL_COLOR_ATTACHMENT7 0x8CE7
+#define GL_COLOR_ATTACHMENT8 0x8CE8
+#define GL_COLOR_ATTACHMENT9 0x8CE9
+#define GL_COMPARE_REF_TO_TEXTURE 0x884E
+#define GL_COMPRESSED_RED 0x8225
+#define GL_COMPRESSED_RED_RGTC1 0x8DBB
+#define GL_COMPRESSED_RG 0x8226
+#define GL_COMPRESSED_RG_RGTC2 0x8DBD
+#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC
+#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE
+#define GL_CONTEXT_FLAGS 0x821E
+#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x00000001
+#define GL_DEPTH24_STENCIL8 0x88F0
+#define GL_DEPTH32F_STENCIL8 0x8CAD
+#define GL_DEPTH_ATTACHMENT 0x8D00
+#define GL_DEPTH_COMPONENT32F 0x8CAC
+#define GL_DEPTH_STENCIL 0x84F9
+#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A
+#define GL_DRAW_FRAMEBUFFER 0x8CA9
+#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6
+#define GL_FIXED_ONLY 0x891D
+#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD
+#define GL_FRAMEBUFFER 0x8D40
+#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215
+#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214
+#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210
+#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211
+#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216
+#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0
+#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212
+#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2
+#define GL_FRAMEBUFFER_BINDING 0x8CA6
+#define GL_FRAMEBUFFER_COMPLETE 0x8CD5
+#define GL_FRAMEBUFFER_DEFAULT 0x8218
+#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6
+#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB
+#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56
+#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC
+#define GL_FRAMEBUFFER_SRGB 0x8DB9
+#define GL_FRAMEBUFFER_UNDEFINED 0x8219
+#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD
+#define GL_GREEN_INTEGER 0x8D95
+#define GL_HALF_FLOAT 0x140B
+#define GL_INTERLEAVED_ATTRIBS 0x8C8C
+#define GL_INT_SAMPLER_1D 0x8DC9
+#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE
+#define GL_INT_SAMPLER_2D 0x8DCA
+#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF
+#define GL_INT_SAMPLER_3D 0x8DCB
+#define GL_INT_SAMPLER_CUBE 0x8DCC
+#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506
+#define GL_MAJOR_VERSION 0x821B
+#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010
+#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008
+#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004
+#define GL_MAP_READ_BIT 0x0001
+#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020
+#define GL_MAP_WRITE_BIT 0x0002
+#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF
+#define GL_MAX_CLIP_DISTANCES 0x0D32
+#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF
+#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905
+#define GL_MAX_RENDERBUFFER_SIZE 0x84E8
+#define GL_MAX_SAMPLES 0x8D57
+#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80
+#define GL_MAX_VARYING_COMPONENTS 0x8B4B
+#define GL_MINOR_VERSION 0x821C
+#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904
+#define GL_NUM_EXTENSIONS 0x821D
+#define GL_PRIMITIVES_GENERATED 0x8C87
+#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19
+#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B
+#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16
+#define GL_QUERY_BY_REGION_WAIT 0x8E15
+#define GL_QUERY_NO_WAIT 0x8E14
+#define GL_QUERY_WAIT 0x8E13
+#define GL_R11F_G11F_B10F 0x8C3A
+#define GL_R16 0x822A
+#define GL_R16F 0x822D
+#define GL_R16I 0x8233
+#define GL_R16UI 0x8234
+#define GL_R32F 0x822E
+#define GL_R32I 0x8235
+#define GL_R32UI 0x8236
+#define GL_R8 0x8229
+#define GL_R8I 0x8231
+#define GL_R8UI 0x8232
+#define GL_RASTERIZER_DISCARD 0x8C89
+#define GL_READ_FRAMEBUFFER 0x8CA8
+#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA
+#define GL_RED_INTEGER 0x8D94
+#define GL_RENDERBUFFER 0x8D41
+#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53
+#define GL_RENDERBUFFER_BINDING 0x8CA7
+#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52
+#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54
+#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51
+#define GL_RENDERBUFFER_HEIGHT 0x8D43
+#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44
+#define GL_RENDERBUFFER_RED_SIZE 0x8D50
+#define GL_RENDERBUFFER_SAMPLES 0x8CAB
+#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55
+#define GL_RENDERBUFFER_WIDTH 0x8D42
+#define GL_RG 0x8227
+#define GL_RG16 0x822C
+#define GL_RG16F 0x822F
+#define GL_RG16I 0x8239
+#define GL_RG16UI 0x823A
+#define GL_RG32F 0x8230
+#define GL_RG32I 0x823B
+#define GL_RG32UI 0x823C
+#define GL_RG8 0x822B
+#define GL_RG8I 0x8237
+#define GL_RG8UI 0x8238
+#define GL_RGB16F 0x881B
+#define GL_RGB16I 0x8D89
+#define GL_RGB16UI 0x8D77
+#define GL_RGB32F 0x8815
+#define GL_RGB32I 0x8D83
+#define GL_RGB32UI 0x8D71
+#define GL_RGB8I 0x8D8F
+#define GL_RGB8UI 0x8D7D
+#define GL_RGB9_E5 0x8C3D
+#define GL_RGBA16F 0x881A
+#define GL_RGBA16I 0x8D88
+#define GL_RGBA16UI 0x8D76
+#define GL_RGBA32F 0x8814
+#define GL_RGBA32I 0x8D82
+#define GL_RGBA32UI 0x8D70
+#define GL_RGBA8I 0x8D8E
+#define GL_RGBA8UI 0x8D7C
+#define GL_RGBA_INTEGER 0x8D99
+#define GL_RGB_INTEGER 0x8D98
+#define GL_RG_INTEGER 0x8228
+#define GL_SAMPLER_1D_ARRAY 0x8DC0
+#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3
+#define GL_SAMPLER_2D_ARRAY 0x8DC1
+#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4
+#define GL_SAMPLER_CUBE_SHADOW 0x8DC5
+#define GL_SEPARATE_ATTRIBS 0x8C8D
+#define GL_STENCIL_ATTACHMENT 0x8D20
+#define GL_STENCIL_INDEX1 0x8D46
+#define GL_STENCIL_INDEX16 0x8D49
+#define GL_STENCIL_INDEX4 0x8D47
+#define GL_STENCIL_INDEX8 0x8D48
+#define GL_TEXTURE_1D_ARRAY 0x8C18
+#define GL_TEXTURE_2D_ARRAY 0x8C1A
+#define GL_TEXTURE_ALPHA_TYPE 0x8C13
+#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C
+#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D
+#define GL_TEXTURE_BLUE_TYPE 0x8C12
+#define GL_TEXTURE_DEPTH_TYPE 0x8C16
+#define GL_TEXTURE_GREEN_TYPE 0x8C11
+#define GL_TEXTURE_RED_TYPE 0x8C10
+#define GL_TEXTURE_SHARED_SIZE 0x8C3F
+#define GL_TEXTURE_STENCIL_SIZE 0x88F1
+#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E
+#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F
+#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F
+#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85
+#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84
+#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88
+#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83
+#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76
+#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B
+#define GL_UNSIGNED_INT_24_8 0x84FA
+#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E
+#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1
+#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6
+#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2
+#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7
+#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3
+#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4
+#define GL_UNSIGNED_INT_VEC2 0x8DC6
+#define GL_UNSIGNED_INT_VEC3 0x8DC7
+#define GL_UNSIGNED_INT_VEC4 0x8DC8
+#define GL_UNSIGNED_NORMALIZED 0x8C17
+#define GL_VERTEX_ARRAY_BINDING 0x85B5
+#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD
+
+// 3.1
+#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36
+#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35
+#define GL_COPY_READ_BUFFER 0x8F36
+#define GL_COPY_WRITE_BUFFER 0x8F37
+#define GL_INT_SAMPLER_2D_RECT 0x8DCD
+#define GL_INT_SAMPLER_BUFFER 0x8DD0
+#define GL_INVALID_INDEX 0xFFFFFFFFu
+#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33
+#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E
+#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31
+#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D
+#define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8
+#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B
+#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30
+#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F
+#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B
+#define GL_PRIMITIVE_RESTART 0x8F9D
+#define GL_PRIMITIVE_RESTART_INDEX 0x8F9E
+#define GL_PROXY_TEXTURE_RECTANGLE 0x84F7
+#define GL_R16_SNORM 0x8F98
+#define GL_R8_SNORM 0x8F94
+#define GL_RG16_SNORM 0x8F99
+#define GL_RG8_SNORM 0x8F95
+#define GL_RGB16_SNORM 0x8F9A
+#define GL_RGB8_SNORM 0x8F96
+#define GL_RGBA16_SNORM 0x8F9B
+#define GL_RGBA8_SNORM 0x8F97
+#define GL_SAMPLER_2D_RECT 0x8B63
+#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64
+#define GL_SAMPLER_BUFFER 0x8DC2
+#define GL_SIGNED_NORMALIZED 0x8F9C
+#define GL_TEXTURE_BINDING_BUFFER 0x8C2C
+#define GL_TEXTURE_BINDING_RECTANGLE 0x84F6
+#define GL_TEXTURE_BUFFER 0x8C2A
+#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D
+#define GL_TEXTURE_RECTANGLE 0x84F5
+#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C
+#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42
+#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43
+#define GL_UNIFORM_BLOCK_BINDING 0x8A3F
+#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40
+#define GL_UNIFORM_BLOCK_INDEX 0x8A3A
+#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44
+#define GL_UNIFORM_BUFFER 0x8A11
+#define GL_UNIFORM_BUFFER_BINDING 0x8A28
+#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34
+#define GL_UNIFORM_BUFFER_SIZE 0x8A2A
+#define GL_UNIFORM_BUFFER_START 0x8A29
+#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E
+#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D
+#define GL_UNIFORM_NAME_LENGTH 0x8A39
+#define GL_UNIFORM_OFFSET 0x8A3B
+#define GL_UNIFORM_SIZE 0x8A38
+#define GL_UNIFORM_TYPE 0x8A37
+#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5
+#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8
+
+// 3.2
+#define GL_ALREADY_SIGNALED 0x911A
+#define GL_CONDITION_SATISFIED 0x911C
+#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002
+#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001
+#define GL_CONTEXT_PROFILE_MASK 0x9126
+#define GL_DEPTH_CLAMP 0x864F
+#define GL_FIRST_VERTEX_CONVENTION 0x8E4D
+#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8
+#define GL_GEOMETRY_INPUT_TYPE 0x8917
+#define GL_GEOMETRY_OUTPUT_TYPE 0x8918
+#define GL_GEOMETRY_SHADER 0x8DD9
+#define GL_GEOMETRY_VERTICES_OUT 0x8916
+#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109
+#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C
+#define GL_LAST_VERTEX_CONVENTION 0x8E4E
+#define GL_LINES_ADJACENCY 0x000A
+#define GL_LINE_STRIP_ADJACENCY 0x000B
+#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E
+#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F
+#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125
+#define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123
+#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124
+#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0
+#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29
+#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1
+#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF
+#define GL_MAX_INTEGER_SAMPLES 0x9110
+#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59
+#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111
+#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122
+#define GL_OBJECT_TYPE 0x9112
+#define GL_PROGRAM_POINT_SIZE 0x8642
+#define GL_PROVOKING_VERTEX 0x8E4F
+#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101
+#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103
+#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C
+#define GL_SAMPLER_2D_MULTISAMPLE 0x9108
+#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B
+#define GL_SAMPLE_MASK 0x8E51
+#define GL_SAMPLE_MASK_VALUE 0x8E52
+#define GL_SAMPLE_POSITION 0x8E50
+#define GL_SIGNALED 0x9119
+#define GL_SYNC_CONDITION 0x9113
+#define GL_SYNC_FENCE 0x9116
+#define GL_SYNC_FLAGS 0x9115
+#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001
+#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117
+#define GL_SYNC_STATUS 0x9114
+#define GL_TEXTURE_2D_MULTISAMPLE 0x9100
+#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102
+#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104
+#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105
+#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F
+#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107
+#define GL_TEXTURE_SAMPLES 0x9106
+#define GL_TIMEOUT_EXPIRED 0x911B
+#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull
+#define GL_TRIANGLES_ADJACENCY 0x000C
+#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D
+#define GL_UNSIGNALED 0x9118
+#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A
+#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D
+#define GL_WAIT_FAILED 0x911D
+
+// 3.3
+#define GL_ANY_SAMPLES_PASSED 0x8C2F
+#define GL_INT_2_10_10_10_REV 0x8D9F
+#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS 0x88FC
+#define GL_ONE_MINUS_SRC1_ALPHA 0x88FB
+#define GL_ONE_MINUS_SRC1_COLOR 0x88FA
+#define GL_RGB10_A2UI 0x906F
+#define GL_SAMPLER_BINDING 0x8919
+#define GL_SRC1_COLOR 0x88F9
+#define GL_TEXTURE_SWIZZLE_A 0x8E45
+#define GL_TEXTURE_SWIZZLE_B 0x8E44
+#define GL_TEXTURE_SWIZZLE_G 0x8E43
+#define GL_TEXTURE_SWIZZLE_R 0x8E42
+#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46
+#define GL_TIMESTAMP 0x8E28
+#define GL_TIME_ELAPSED 0x88BF
+#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE
+
+// 4.0
+#define GL_ACTIVE_SUBROUTINES 0x8DE5
+#define GL_ACTIVE_SUBROUTINE_MAX_LENGTH 0x8E48
+#define GL_ACTIVE_SUBROUTINE_UNIFORMS 0x8DE6
+#define GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS 0x8E47
+#define GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH 0x8E49
+#define GL_COMPATIBLE_SUBROUTINES 0x8E4B
+#define GL_DOUBLE_MAT2 0x8F46
+#define GL_DOUBLE_MAT2x3 0x8F49
+#define GL_DOUBLE_MAT2x4 0x8F4A
+#define GL_DOUBLE_MAT3 0x8F47
+#define GL_DOUBLE_MAT3x2 0x8F4B
+#define GL_DOUBLE_MAT3x4 0x8F4C
+#define GL_DOUBLE_MAT4 0x8F48
+#define GL_DOUBLE_MAT4x2 0x8F4D
+#define GL_DOUBLE_MAT4x3 0x8F4E
+#define GL_DOUBLE_VEC2 0x8FFC
+#define GL_DOUBLE_VEC3 0x8FFD
+#define GL_DOUBLE_VEC4 0x8FFE
+#define GL_DRAW_INDIRECT_BUFFER 0x8F3F
+#define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43
+#define GL_FRACTIONAL_EVEN 0x8E7C
+#define GL_FRACTIONAL_ODD 0x8E7B
+#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS 0x8E5D
+#define GL_GEOMETRY_SHADER_INVOCATIONS 0x887F
+#define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E
+#define GL_ISOLINES 0x8E7A
+#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E
+#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F
+#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET 0x8E5C
+#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS 0x8E5A
+#define GL_MAX_PATCH_VERTICES 0x8E7D
+#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F
+#define GL_MAX_SUBROUTINES 0x8DE7
+#define GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS 0x8DE8
+#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS 0x886C
+#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS 0x8E83
+#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS 0x8E81
+#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS 0x8E85
+#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS 0x8E89
+#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E7F
+#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS 0x886D
+#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS 0x8E86
+#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS 0x8E82
+#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS 0x8E8A
+#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E80
+#define GL_MAX_TESS_GEN_LEVEL 0x8E7E
+#define GL_MAX_TESS_PATCH_COMPONENTS 0x8E84
+#define GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70
+#define GL_MAX_VERTEX_STREAMS 0x8E71
+#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET 0x8E5B
+#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E
+#define GL_MIN_SAMPLE_SHADING_VALUE 0x8C37
+#define GL_NUM_COMPATIBLE_SUBROUTINES 0x8E4A
+#define GL_PATCHES 0x000E
+#define GL_PATCH_DEFAULT_INNER_LEVEL 0x8E73
+#define GL_PATCH_DEFAULT_OUTER_LEVEL 0x8E74
+#define GL_PATCH_VERTICES 0x8E72
+#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY 0x900B
+#define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C
+#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D
+#define GL_SAMPLE_SHADING 0x8C36
+#define GL_TESS_CONTROL_OUTPUT_VERTICES 0x8E75
+#define GL_TESS_CONTROL_SHADER 0x8E88
+#define GL_TESS_EVALUATION_SHADER 0x8E87
+#define GL_TESS_GEN_MODE 0x8E76
+#define GL_TESS_GEN_POINT_MODE 0x8E79
+#define GL_TESS_GEN_SPACING 0x8E77
+#define GL_TESS_GEN_VERTEX_ORDER 0x8E78
+#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A
+#define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009
+#define GL_TRANSFORM_FEEDBACK 0x8E22
+#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25
+#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE 0x8E24
+#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED 0x8E23
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER 0x84F0
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER 0x84F1
+#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F
+
+// 4.1
+#define GL_ACTIVE_PROGRAM 0x8259
+#define GL_ALL_SHADER_BITS 0xFFFFFFFF
+#define GL_FIXED 0x140C
+#define GL_FRAGMENT_SHADER_BIT 0x00000002
+#define GL_GEOMETRY_SHADER_BIT 0x00000004
+#define GL_HIGH_FLOAT 0x8DF2
+#define GL_HIGH_INT 0x8DF5
+#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B
+#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A
+#define GL_LAYER_PROVOKING_VERTEX 0x825E
+#define GL_LOW_FLOAT 0x8DF0
+#define GL_LOW_INT 0x8DF3
+#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD
+#define GL_MAX_VARYING_VECTORS 0x8DFC
+#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB
+#define GL_MAX_VIEWPORTS 0x825B
+#define GL_MEDIUM_FLOAT 0x8DF1
+#define GL_MEDIUM_INT 0x8DF4
+#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE
+#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9
+#define GL_PROGRAM_BINARY_FORMATS 0x87FF
+#define GL_PROGRAM_BINARY_LENGTH 0x8741
+#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257
+#define GL_PROGRAM_PIPELINE_BINDING 0x825A
+#define GL_PROGRAM_SEPARABLE 0x8258
+#define GL_RGB565 0x8D62
+#define GL_SHADER_BINARY_FORMATS 0x8DF8
+#define GL_SHADER_COMPILER 0x8DFA
+#define GL_TESS_CONTROL_SHADER_BIT 0x00000008
+#define GL_TESS_EVALUATION_SHADER_BIT 0x00000010
+#define GL_UNDEFINED_VERTEX 0x8260
+#define GL_VERTEX_SHADER_BIT 0x00000001
+#define GL_VIEWPORT_BOUNDS_RANGE 0x825D
+#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX 0x825F
+#define GL_VIEWPORT_SUBPIXEL_BITS 0x825C
+
+// 4.2
+#define GL_ACTIVE_ATOMIC_COUNTER_BUFFERS 0x92D9
+#define GL_ALL_BARRIER_BITS 0xFFFFFFFF
+#define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000
+#define GL_ATOMIC_COUNTER_BUFFER 0x92C0
+#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS 0x92C5
+#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES 0x92C6
+#define GL_ATOMIC_COUNTER_BUFFER_BINDING 0x92C1
+#define GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE 0x92C4
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER 0x92CB
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER 0x92CA
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER 0x92C8
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER 0x92C9
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER 0x92C7
+#define GL_ATOMIC_COUNTER_BUFFER_SIZE 0x92C3
+#define GL_ATOMIC_COUNTER_BUFFER_START 0x92C2
+#define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200
+#define GL_COMMAND_BARRIER_BIT 0x00000040
+#define GL_COMPRESSED_RGBA_BPTC_UNORM 0x8E8C
+#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E
+#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F
+#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM 0x8E8D
+#define GL_COPY_READ_BUFFER_BINDING 0x8F36
+#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37
+#define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002
+#define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400
+#define GL_IMAGE_1D 0x904C
+#define GL_IMAGE_1D_ARRAY 0x9052
+#define GL_IMAGE_2D 0x904D
+#define GL_IMAGE_2D_ARRAY 0x9053
+#define GL_IMAGE_2D_MULTISAMPLE 0x9055
+#define GL_IMAGE_2D_MULTISAMPLE_ARRAY 0x9056
+#define GL_IMAGE_2D_RECT 0x904F
+#define GL_IMAGE_3D 0x904E
+#define GL_IMAGE_BINDING_ACCESS 0x8F3E
+#define GL_IMAGE_BINDING_FORMAT 0x906E
+#define GL_IMAGE_BINDING_LAYER 0x8F3D
+#define GL_IMAGE_BINDING_LAYERED 0x8F3C
+#define GL_IMAGE_BINDING_LEVEL 0x8F3B
+#define GL_IMAGE_BINDING_NAME 0x8F3A
+#define GL_IMAGE_BUFFER 0x9051
+#define GL_IMAGE_CUBE 0x9050
+#define GL_IMAGE_CUBE_MAP_ARRAY 0x9054
+#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS 0x90C9
+#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE 0x90C8
+#define GL_IMAGE_FORMAT_COMPATIBILITY_TYPE 0x90C7
+#define GL_INT_IMAGE_1D 0x9057
+#define GL_INT_IMAGE_1D_ARRAY 0x905D
+#define GL_INT_IMAGE_2D 0x9058
+#define GL_INT_IMAGE_2D_ARRAY 0x905E
+#define GL_INT_IMAGE_2D_MULTISAMPLE 0x9060
+#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x9061
+#define GL_INT_IMAGE_2D_RECT 0x905A
+#define GL_INT_IMAGE_3D 0x9059
+#define GL_INT_IMAGE_BUFFER 0x905C
+#define GL_INT_IMAGE_CUBE 0x905B
+#define GL_INT_IMAGE_CUBE_MAP_ARRAY 0x905F
+#define GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS 0x92DC
+#define GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE 0x92D8
+#define GL_MAX_COMBINED_ATOMIC_COUNTERS 0x92D7
+#define GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS 0x92D1
+#define GL_MAX_COMBINED_IMAGE_UNIFORMS 0x90CF
+#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS 0x8F39
+#define GL_MAX_FRAGMENT_ATOMIC_COUNTERS 0x92D6
+#define GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS 0x92D0
+#define GL_MAX_FRAGMENT_IMAGE_UNIFORMS 0x90CE
+#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS 0x92D5
+#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS 0x92CF
+#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS 0x90CD
+#define GL_MAX_IMAGE_SAMPLES 0x906D
+#define GL_MAX_IMAGE_UNITS 0x8F38
+#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS 0x92D3
+#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS 0x92CD
+#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS 0x90CB
+#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS 0x92D4
+#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS 0x92CE
+#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS 0x90CC
+#define GL_MAX_VERTEX_ATOMIC_COUNTERS 0x92D2
+#define GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS 0x92CC
+#define GL_MAX_VERTEX_IMAGE_UNIFORMS 0x90CA
+#define GL_MIN_MAP_BUFFER_ALIGNMENT 0x90BC
+#define GL_NUM_SAMPLE_COUNTS 0x9380
+#define GL_PACK_COMPRESSED_BLOCK_DEPTH 0x912D
+#define GL_PACK_COMPRESSED_BLOCK_HEIGHT 0x912C
+#define GL_PACK_COMPRESSED_BLOCK_SIZE 0x912E
+#define GL_PACK_COMPRESSED_BLOCK_WIDTH 0x912B
+#define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080
+#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020
+#define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008
+#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F
+#define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100
+#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24
+#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800
+#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23
+#define GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX 0x92DA
+#define GL_UNIFORM_BARRIER_BIT 0x00000004
+#define GL_UNPACK_COMPRESSED_BLOCK_DEPTH 0x9129
+#define GL_UNPACK_COMPRESSED_BLOCK_HEIGHT 0x9128
+#define GL_UNPACK_COMPRESSED_BLOCK_SIZE 0x912A
+#define GL_UNPACK_COMPRESSED_BLOCK_WIDTH 0x9127
+#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB
+#define GL_UNSIGNED_INT_IMAGE_1D 0x9062
+#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY 0x9068
+#define GL_UNSIGNED_INT_IMAGE_2D 0x9063
+#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069
+#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE 0x906B
+#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x906C
+#define GL_UNSIGNED_INT_IMAGE_2D_RECT 0x9065
+#define GL_UNSIGNED_INT_IMAGE_3D 0x9064
+#define GL_UNSIGNED_INT_IMAGE_BUFFER 0x9067
+#define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066
+#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A
+#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001
+
+// 4.3
+#define GL_ACTIVE_RESOURCES 0x92F5
+#define GL_ACTIVE_VARIABLES 0x9305
+#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A
+#define GL_ARRAY_SIZE 0x92FB
+#define GL_ARRAY_STRIDE 0x92FE
+#define GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER 0x90ED
+#define GL_AUTO_GENERATE_MIPMAP 0x8295
+#define GL_BLOCK_INDEX 0x92FD
+#define GL_BUFFER 0x82E0
+#define GL_BUFFER_BINDING 0x9302
+#define GL_BUFFER_DATA_SIZE 0x9303
+#define GL_BUFFER_VARIABLE 0x92E5
+#define GL_CAVEAT_SUPPORT 0x82B8
+#define GL_CLEAR_BUFFER 0x82B4
+#define GL_COLOR_COMPONENTS 0x8283
+#define GL_COLOR_ENCODING 0x8296
+#define GL_COLOR_RENDERABLE 0x8286
+#define GL_COMPRESSED_R11_EAC 0x9270
+#define GL_COMPRESSED_RG11_EAC 0x9272
+#define GL_COMPRESSED_RGB8_ETC2 0x9274
+#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276
+#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
+#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271
+#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273
+#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279
+#define GL_COMPRESSED_SRGB8_ETC2 0x9275
+#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277
+#define GL_COMPUTE_SHADER 0x91B9
+#define GL_COMPUTE_SHADER_BIT 0x00000020
+#define GL_COMPUTE_SUBROUTINE 0x92ED
+#define GL_COMPUTE_SUBROUTINE_UNIFORM 0x92F3
+#define GL_COMPUTE_TEXTURE 0x82A0
+#define GL_COMPUTE_WORK_GROUP_SIZE 0x8267
+#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002
+#define GL_DEBUG_CALLBACK_FUNCTION 0x8244
+#define GL_DEBUG_CALLBACK_USER_PARAM 0x8245
+#define GL_DEBUG_GROUP_STACK_DEPTH 0x826D
+#define GL_DEBUG_LOGGED_MESSAGES 0x9145
+#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243
+#define GL_DEBUG_OUTPUT 0x92E0
+#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242
+#define GL_DEBUG_SEVERITY_HIGH 0x9146
+#define GL_DEBUG_SEVERITY_LOW 0x9148
+#define GL_DEBUG_SEVERITY_MEDIUM 0x9147
+#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B
+#define GL_DEBUG_SOURCE_API 0x8246
+#define GL_DEBUG_SOURCE_APPLICATION 0x824A
+#define GL_DEBUG_SOURCE_OTHER 0x824B
+#define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248
+#define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249
+#define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247
+#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D
+#define GL_DEBUG_TYPE_ERROR 0x824C
+#define GL_DEBUG_TYPE_MARKER 0x8268
+#define GL_DEBUG_TYPE_OTHER 0x8251
+#define GL_DEBUG_TYPE_PERFORMANCE 0x8250
+#define GL_DEBUG_TYPE_POP_GROUP 0x826A
+#define GL_DEBUG_TYPE_PORTABILITY 0x824F
+#define GL_DEBUG_TYPE_PUSH_GROUP 0x8269
+#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E
+#define GL_DEPTH_COMPONENTS 0x8284
+#define GL_DEPTH_RENDERABLE 0x8287
+#define GL_DEPTH_STENCIL_TEXTURE_MODE 0x90EA
+#define GL_DISPATCH_INDIRECT_BUFFER 0x90EE
+#define GL_DISPATCH_INDIRECT_BUFFER_BINDING 0x90EF
+#define GL_FILTER 0x829A
+#define GL_FRAGMENT_SUBROUTINE 0x92EC
+#define GL_FRAGMENT_SUBROUTINE_UNIFORM 0x92F2
+#define GL_FRAGMENT_TEXTURE 0x829F
+#define GL_FRAMEBUFFER_BLEND 0x828B
+#define GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS 0x9314
+#define GL_FRAMEBUFFER_DEFAULT_HEIGHT 0x9311
+#define GL_FRAMEBUFFER_DEFAULT_LAYERS 0x9312
+#define GL_FRAMEBUFFER_DEFAULT_SAMPLES 0x9313
+#define GL_FRAMEBUFFER_DEFAULT_WIDTH 0x9310
+#define GL_FRAMEBUFFER_RENDERABLE 0x8289
+#define GL_FRAMEBUFFER_RENDERABLE_LAYERED 0x828A
+#define GL_FULL_SUPPORT 0x82B7
+#define GL_GEOMETRY_SUBROUTINE 0x92EB
+#define GL_GEOMETRY_SUBROUTINE_UNIFORM 0x92F1
+#define GL_GEOMETRY_TEXTURE 0x829E
+#define GL_GET_TEXTURE_IMAGE_FORMAT 0x8291
+#define GL_GET_TEXTURE_IMAGE_TYPE 0x8292
+#define GL_IMAGE_CLASS_10_10_10_2 0x82C3
+#define GL_IMAGE_CLASS_11_11_10 0x82C2
+#define GL_IMAGE_CLASS_1_X_16 0x82BE
+#define GL_IMAGE_CLASS_1_X_32 0x82BB
+#define GL_IMAGE_CLASS_1_X_8 0x82C1
+#define GL_IMAGE_CLASS_2_X_16 0x82BD
+#define GL_IMAGE_CLASS_2_X_32 0x82BA
+#define GL_IMAGE_CLASS_2_X_8 0x82C0
+#define GL_IMAGE_CLASS_4_X_16 0x82BC
+#define GL_IMAGE_CLASS_4_X_32 0x82B9
+#define GL_IMAGE_CLASS_4_X_8 0x82BF
+#define GL_IMAGE_COMPATIBILITY_CLASS 0x82A8
+#define GL_IMAGE_PIXEL_FORMAT 0x82A9
+#define GL_IMAGE_PIXEL_TYPE 0x82AA
+#define GL_IMAGE_TEXEL_SIZE 0x82A7
+#define GL_INTERNALFORMAT_ALPHA_SIZE 0x8274
+#define GL_INTERNALFORMAT_ALPHA_TYPE 0x827B
+#define GL_INTERNALFORMAT_BLUE_SIZE 0x8273
+#define GL_INTERNALFORMAT_BLUE_TYPE 0x827A
+#define GL_INTERNALFORMAT_DEPTH_SIZE 0x8275
+#define GL_INTERNALFORMAT_DEPTH_TYPE 0x827C
+#define GL_INTERNALFORMAT_GREEN_SIZE 0x8272
+#define GL_INTERNALFORMAT_GREEN_TYPE 0x8279
+#define GL_INTERNALFORMAT_PREFERRED 0x8270
+#define GL_INTERNALFORMAT_RED_SIZE 0x8271
+#define GL_INTERNALFORMAT_RED_TYPE 0x8278
+#define GL_INTERNALFORMAT_SHARED_SIZE 0x8277
+#define GL_INTERNALFORMAT_STENCIL_SIZE 0x8276
+#define GL_INTERNALFORMAT_STENCIL_TYPE 0x827D
+#define GL_INTERNALFORMAT_SUPPORTED 0x826F
+#define GL_IS_PER_PATCH 0x92E7
+#define GL_IS_ROW_MAJOR 0x9300
+#define GL_LOCATION 0x930E
+#define GL_LOCATION_INDEX 0x930F
+#define GL_MANUAL_GENERATE_MIPMAP 0x8294
+#define GL_MATRIX_STRIDE 0x92FF
+#define GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS 0x8266
+#define GL_MAX_COMBINED_DIMENSIONS 0x8282
+#define GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES 0x8F39
+#define GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS 0x90DC
+#define GL_MAX_COMPUTE_ATOMIC_COUNTERS 0x8265
+#define GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS 0x8264
+#define GL_MAX_COMPUTE_IMAGE_UNIFORMS 0x91BD
+#define GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS 0x90DB
+#define GL_MAX_COMPUTE_SHARED_MEMORY_SIZE 0x8262
+#define GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS 0x91BC
+#define GL_MAX_COMPUTE_UNIFORM_BLOCKS 0x91BB
+#define GL_MAX_COMPUTE_UNIFORM_COMPONENTS 0x8263
+#define GL_MAX_COMPUTE_WORK_GROUP_COUNT 0x91BE
+#define GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS 0x90EB
+#define GL_MAX_COMPUTE_WORK_GROUP_SIZE 0x91BF
+#define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C
+#define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144
+#define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143
+#define GL_MAX_DEPTH 0x8280
+#define GL_MAX_ELEMENT_INDEX 0x8D6B
+#define GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS 0x90DA
+#define GL_MAX_FRAMEBUFFER_HEIGHT 0x9316
+#define GL_MAX_FRAMEBUFFER_LAYERS 0x9317
+#define GL_MAX_FRAMEBUFFER_SAMPLES 0x9318
+#define GL_MAX_FRAMEBUFFER_WIDTH 0x9315
+#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS 0x90D7
+#define GL_MAX_HEIGHT 0x827F
+#define GL_MAX_LABEL_LENGTH 0x82E8
+#define GL_MAX_LAYERS 0x8281
+#define GL_MAX_NAME_LENGTH 0x92F6
+#define GL_MAX_NUM_ACTIVE_VARIABLES 0x92F7
+#define GL_MAX_NUM_COMPATIBLE_SUBROUTINES 0x92F8
+#define GL_MAX_SHADER_STORAGE_BLOCK_SIZE 0x90DE
+#define GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS 0x90DD
+#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS 0x90D8
+#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS 0x90D9
+#define GL_MAX_UNIFORM_LOCATIONS 0x826E
+#define GL_MAX_VERTEX_ATTRIB_BINDINGS 0x82DA
+#define GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D9
+#define GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS 0x90D6
+#define GL_MAX_WIDTH 0x827E
+#define GL_MIPMAP 0x8293
+#define GL_NAME_LENGTH 0x92F9
+#define GL_NUM_ACTIVE_VARIABLES 0x9304
+#define GL_NUM_SHADING_LANGUAGE_VERSIONS 0x82E9
+#define GL_OFFSET 0x92FC
+#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69
+#define GL_PROGRAM 0x82E2
+#define GL_PROGRAM_INPUT 0x92E3
+#define GL_PROGRAM_OUTPUT 0x92E4
+#define GL_PROGRAM_PIPELINE 0x82E4
+#define GL_QUERY 0x82E3
+#define GL_READ_PIXELS 0x828C
+#define GL_READ_PIXELS_FORMAT 0x828D
+#define GL_READ_PIXELS_TYPE 0x828E
+#define GL_REFERENCED_BY_COMPUTE_SHADER 0x930B
+#define GL_REFERENCED_BY_FRAGMENT_SHADER 0x930A
+#define GL_REFERENCED_BY_GEOMETRY_SHADER 0x9309
+#define GL_REFERENCED_BY_TESS_CONTROL_SHADER 0x9307
+#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER 0x9308
+#define GL_REFERENCED_BY_VERTEX_SHADER 0x9306
+#define GL_SAMPLER 0x82E6
+#define GL_SHADER 0x82E1
+#define GL_SHADER_IMAGE_ATOMIC 0x82A6
+#define GL_SHADER_IMAGE_LOAD 0x82A4
+#define GL_SHADER_IMAGE_STORE 0x82A5
+#define GL_SHADER_STORAGE_BARRIER_BIT 0x00002000
+#define GL_SHADER_STORAGE_BLOCK 0x92E6
+#define GL_SHADER_STORAGE_BUFFER 0x90D2
+#define GL_SHADER_STORAGE_BUFFER_BINDING 0x90D3
+#define GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT 0x90DF
+#define GL_SHADER_STORAGE_BUFFER_SIZE 0x90D5
+#define GL_SHADER_STORAGE_BUFFER_START 0x90D4
+#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST 0x82AC
+#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE 0x82AE
+#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST 0x82AD
+#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE 0x82AF
+#define GL_SRGB_READ 0x8297
+#define GL_SRGB_WRITE 0x8298
+#define GL_STENCIL_COMPONENTS 0x8285
+#define GL_STENCIL_RENDERABLE 0x8288
+#define GL_TESS_CONTROL_SUBROUTINE 0x92E9
+#define GL_TESS_CONTROL_SUBROUTINE_UNIFORM 0x92EF
+#define GL_TESS_CONTROL_TEXTURE 0x829C
+#define GL_TESS_EVALUATION_SUBROUTINE 0x92EA
+#define GL_TESS_EVALUATION_SUBROUTINE_UNIFORM 0x92F0
+#define GL_TESS_EVALUATION_TEXTURE 0x829D
+#define GL_TEXTURE_BUFFER_OFFSET 0x919D
+#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT 0x919F
+#define GL_TEXTURE_BUFFER_SIZE 0x919E
+#define GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT 0x82B2
+#define GL_TEXTURE_COMPRESSED_BLOCK_SIZE 0x82B3
+#define GL_TEXTURE_COMPRESSED_BLOCK_WIDTH 0x82B1
+#define GL_TEXTURE_GATHER 0x82A2
+#define GL_TEXTURE_GATHER_SHADOW 0x82A3
+#define GL_TEXTURE_IMAGE_FORMAT 0x828F
+#define GL_TEXTURE_IMAGE_TYPE 0x8290
+#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF
+#define GL_TEXTURE_SHADOW 0x82A1
+#define GL_TEXTURE_VIEW 0x82B5
+#define GL_TEXTURE_VIEW_MIN_LAYER 0x82DD
+#define GL_TEXTURE_VIEW_MIN_LEVEL 0x82DB
+#define GL_TEXTURE_VIEW_NUM_LAYERS 0x82DE
+#define GL_TEXTURE_VIEW_NUM_LEVELS 0x82DC
+#define GL_TOP_LEVEL_ARRAY_SIZE 0x930C
+#define GL_TOP_LEVEL_ARRAY_STRIDE 0x930D
+#define GL_TRANSFORM_FEEDBACK_VARYING 0x92F4
+#define GL_TYPE 0x92FA
+#define GL_UNIFORM 0x92E1
+#define GL_UNIFORM_BLOCK 0x92E2
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER 0x90EC
+#define GL_VERTEX_ATTRIB_ARRAY_LONG 0x874E
+#define GL_VERTEX_ATTRIB_BINDING 0x82D4
+#define GL_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5
+#define GL_VERTEX_BINDING_BUFFER 0x8F4F
+#define GL_VERTEX_BINDING_DIVISOR 0x82D6
+#define GL_VERTEX_BINDING_OFFSET 0x82D7
+#define GL_VERTEX_BINDING_STRIDE 0x82D8
+#define GL_VERTEX_SUBROUTINE 0x92E8
+#define GL_VERTEX_SUBROUTINE_UNIFORM 0x92EE
+#define GL_VERTEX_TEXTURE 0x829B
+#define GL_VIEW_CLASS_128_BITS 0x82C4
+#define GL_VIEW_CLASS_16_BITS 0x82CA
+#define GL_VIEW_CLASS_24_BITS 0x82C9
+#define GL_VIEW_CLASS_32_BITS 0x82C8
+#define GL_VIEW_CLASS_48_BITS 0x82C7
+#define GL_VIEW_CLASS_64_BITS 0x82C6
+#define GL_VIEW_CLASS_8_BITS 0x82CB
+#define GL_VIEW_CLASS_96_BITS 0x82C5
+#define GL_VIEW_CLASS_BPTC_FLOAT 0x82D3
+#define GL_VIEW_CLASS_BPTC_UNORM 0x82D2
+#define GL_VIEW_CLASS_RGTC1_RED 0x82D0
+#define GL_VIEW_CLASS_RGTC2_RG 0x82D1
+#define GL_VIEW_CLASS_S3TC_DXT1_RGB 0x82CC
+#define GL_VIEW_CLASS_S3TC_DXT1_RGBA 0x82CD
+#define GL_VIEW_CLASS_S3TC_DXT3_RGBA 0x82CE
+#define GL_VIEW_CLASS_S3TC_DXT5_RGBA 0x82CF
+#define GL_VIEW_COMPATIBILITY_CLASS 0x82B6
+
+// 4.4
+#define GL_BUFFER_IMMUTABLE_STORAGE 0x821F
+#define GL_BUFFER_STORAGE_FLAGS 0x8220
+#define GL_CLEAR_TEXTURE 0x9365
+#define GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT 0x00004000
+#define GL_CLIENT_STORAGE_BIT 0x0200
+#define GL_DYNAMIC_STORAGE_BIT 0x0100
+#define GL_LOCATION_COMPONENT 0x934A
+#define GL_MAP_COHERENT_BIT 0x0080
+#define GL_MAP_PERSISTENT_BIT 0x0040
+#define GL_MAX_VERTEX_ATTRIB_STRIDE 0x82E5
+#define GL_MIRROR_CLAMP_TO_EDGE 0x8743
+#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED 0x8221
+#define GL_QUERY_BUFFER 0x9192
+#define GL_QUERY_BUFFER_BARRIER_BIT 0x00008000
+#define GL_QUERY_BUFFER_BINDING 0x9193
+#define GL_QUERY_RESULT_NO_WAIT 0x9194
+#define GL_TEXTURE_BUFFER_BINDING 0x8C2A
+#define GL_TRANSFORM_FEEDBACK_BUFFER_INDEX 0x934B
+#define GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE 0x934C
+
+// 4.5
+#define GL_CLIP_DEPTH_MODE 0x935D
+#define GL_CLIP_ORIGIN 0x935C
+#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT 0x00000004
+#define GL_CONTEXT_LOST 0x0507
+#define GL_CONTEXT_RELEASE_BEHAVIOR 0x82FB
+#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH 0x82FC
+#define GL_GUILTY_CONTEXT_RESET 0x8253
+#define GL_INNOCENT_CONTEXT_RESET 0x8254
+#define GL_LOSE_CONTEXT_ON_RESET 0x8252
+#define GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES 0x82FA
+#define GL_MAX_CULL_DISTANCES 0x82F9
+#define GL_NEGATIVE_ONE_TO_ONE 0x935E
+#define GL_NO_RESET_NOTIFICATION 0x8261
+#define GL_QUERY_BY_REGION_NO_WAIT_INVERTED 0x8E1A
+#define GL_QUERY_BY_REGION_WAIT_INVERTED 0x8E19
+#define GL_QUERY_NO_WAIT_INVERTED 0x8E18
+#define GL_QUERY_TARGET 0x82EA
+#define GL_QUERY_WAIT_INVERTED 0x8E17
+#define GL_RESET_NOTIFICATION_STRATEGY 0x8256
+#define GL_TEXTURE_TARGET 0x1006
+#define GL_UNKNOWN_CONTEXT_RESET 0x8255
+#define GL_ZERO_TO_ONE 0x935F
+#define GL_COMPLETION_STATUS 0x91B1
+
+#endif // LIBANGLE_RENDERER_GL_FUNCTIONSGLENUMS_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/load_functions_table.h b/gfx/angle/checkout/src/libANGLE/renderer/load_functions_table.h
new file mode 100644
index 0000000000..27eaebc8e7
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/load_functions_table.h
@@ -0,0 +1,20 @@
+//
+// 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, FormatID angleFormat);
+} // namespace angle
+
+#endif // LIBANGLE_RENDERER_LOADFUNCTIONSTABLE_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/load_functions_table_autogen.cpp b/gfx/angle/checkout/src/libANGLE/renderer/load_functions_table_autogen.cpp
new file mode 100644
index 0000000000..11fe60fe0d
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/load_functions_table_autogen.cpp
@@ -0,0 +1,5465 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_load_functions_table.py using data from load_functions_data.json
+//
+// Copyright 2020 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 A1RGB5_ANGLEX_to_A1R5G5B5_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadRGB5A1ToRGBA8, true);
+ case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
+ return LoadImageFunctionInfo(LoadToNative<GLushort, 1>, false);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+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_R16_FLOAT(GLenum type)
+{
+ switch (type)
+ {
+ 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 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_R32_FLOAT(GLenum type)
+{
+ switch (type)
+ {
+ case GL_FLOAT:
+ return LoadImageFunctionInfo(LoadToNative<GLfloat, 1>, false);
+ 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 ALPHA8_EXT_to_R8_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadToNative<GLubyte, 1>, false);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo BGR10_A2_ANGLEX_to_B10G10R10A2_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 BGR565_ANGLEX_to_B5G6R5_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadRGB8ToBGR565, true);
+ 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(LoadRGB5A1ToRGBA8, true);
+ case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
+ return LoadImageFunctionInfo(LoadToNative<GLushort, 1>, false);
+ 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 BGRA8_SRGB_ANGLEX_to_B8G8R8A8_UNORM_SRGB(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 BGRX8_ANGLEX_to_B8G8R8A8_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadToNative<GLubyte, 4>, false);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo BGRX8_ANGLEX_to_B8G8R8X8_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadToNative<GLubyte, 4>, false);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_R11_EAC_to_EAC_R11_UNORM_BLOCK(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 8>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_R11_EAC_to_R16_FLOAT(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadEACR11ToR16F, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_R11_EAC_to_R16_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadEACR11ToR16, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RED_GREEN_RGTC2_EXT_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RED_RGTC1_EXT_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 8>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RG11_EAC_to_EAC_R11G11_UNORM_BLOCK(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RG11_EAC_to_R16G16_FLOAT(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadEACRG11ToRG16F, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RG11_EAC_to_R16G16_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadEACRG11ToRG16, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGB8_ETC2_to_ETC2_R8G8B8_UNORM_BLOCK(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 8>, 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_LOSSY_DECODE_ETC2_ANGLE_to_BC1_RGB_UNORM_BLOCK(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadETC2RGB8ToBC1, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2_to_ETC2_R8G8B8A1_UNORM_BLOCK(
+ GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 8>, 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_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE_to_BC1_RGBA_UNORM_BLOCK(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadETC2RGB8A1ToBC1, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGBA8_ETC2_EAC_to_ETC2_R8G8B8A8_UNORM_BLOCK(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 16>, 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_ASTC_10x10_KHR_to_R8G8B8A8_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadASTCToRGBA8<10, 10>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_10x10_KHR_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<10, 10, 1, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_10x5_KHR_to_R8G8B8A8_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadASTCToRGBA8<10, 5>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_10x5_KHR_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<10, 5, 1, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_10x6_KHR_to_R8G8B8A8_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadASTCToRGBA8<10, 6>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_10x6_KHR_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<10, 6, 1, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_10x8_KHR_to_R8G8B8A8_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadASTCToRGBA8<10, 8>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_10x8_KHR_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<10, 8, 1, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_12x10_KHR_to_R8G8B8A8_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadASTCToRGBA8<12, 10>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_12x10_KHR_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<12, 10, 1, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_12x12_KHR_to_R8G8B8A8_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadASTCToRGBA8<12, 12>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_12x12_KHR_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<12, 12, 1, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_3x3x3_OES_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<3, 3, 3, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_4x3x3_OES_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<4, 3, 3, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_4x4_KHR_to_R8G8B8A8_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadASTCToRGBA8<4, 4>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_4x4_KHR_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_4x4x3_OES_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 3, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_4x4x4_OES_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 4, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_5x4_KHR_to_R8G8B8A8_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadASTCToRGBA8<5, 4>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_5x4_KHR_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<5, 4, 1, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_5x4x4_OES_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<5, 4, 4, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_5x5_KHR_to_R8G8B8A8_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadASTCToRGBA8<5, 5>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_5x5_KHR_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<5, 5, 1, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_5x5x4_OES_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<5, 5, 4, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_5x5x5_OES_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<5, 5, 5, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_6x5_KHR_to_R8G8B8A8_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadASTCToRGBA8<6, 5>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_6x5_KHR_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<6, 5, 1, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_6x5x5_OES_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<6, 5, 5, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_6x6_KHR_to_R8G8B8A8_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadASTCToRGBA8<6, 6>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_6x6_KHR_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<6, 6, 1, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_6x6x5_OES_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<6, 6, 5, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_6x6x6_OES_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<6, 6, 6, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_8x5_KHR_to_R8G8B8A8_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadASTCToRGBA8<8, 5>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_8x5_KHR_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<8, 5, 1, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_8x6_KHR_to_R8G8B8A8_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadASTCToRGBA8<8, 6>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_8x6_KHR_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<8, 6, 1, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_8x8_KHR_to_R8G8B8A8_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadASTCToRGBA8<8, 8>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGBA_ASTC_8x8_KHR_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<8, 8, 1, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGBA_BPTC_UNORM_EXT_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 16>, 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, 1, 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, 1, 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, 1, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 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, 1, 8>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SIGNED_R11_EAC_to_EAC_R11_SNORM_BLOCK(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 8>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SIGNED_R11_EAC_to_R16_FLOAT(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadEACR11SToR16F, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SIGNED_R11_EAC_to_R16_SNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadEACR11SToR16, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SIGNED_RED_RGTC1_EXT_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 8>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SIGNED_RG11_EAC_to_EAC_R11G11_SNORM_BLOCK(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SIGNED_RG11_EAC_to_R16G16_FLOAT(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadEACRG11SToRG16F, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SIGNED_RG11_EAC_to_R16G16_SNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadEACRG11SToRG16, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR_to_R8G8B8A8_UNORM_SRGB(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadASTCToRGBA8<10, 10>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<10, 10, 1, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR_to_R8G8B8A8_UNORM_SRGB(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadASTCToRGBA8<10, 5>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<10, 5, 1, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR_to_R8G8B8A8_UNORM_SRGB(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadASTCToRGBA8<10, 6>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<10, 6, 1, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR_to_R8G8B8A8_UNORM_SRGB(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadASTCToRGBA8<10, 8>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<10, 8, 1, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR_to_R8G8B8A8_UNORM_SRGB(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadASTCToRGBA8<12, 10>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<12, 10, 1, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR_to_R8G8B8A8_UNORM_SRGB(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadASTCToRGBA8<12, 12>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<12, 12, 1, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<3, 3, 3, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<4, 3, 3, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR_to_R8G8B8A8_UNORM_SRGB(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadASTCToRGBA8<4, 4>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 3, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 4, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR_to_R8G8B8A8_UNORM_SRGB(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadASTCToRGBA8<5, 4>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<5, 4, 1, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<5, 4, 4, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR_to_R8G8B8A8_UNORM_SRGB(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadASTCToRGBA8<5, 5>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<5, 5, 1, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<5, 5, 4, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<5, 5, 5, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR_to_R8G8B8A8_UNORM_SRGB(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadASTCToRGBA8<6, 5>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<6, 5, 1, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<6, 5, 5, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR_to_R8G8B8A8_UNORM_SRGB(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadASTCToRGBA8<6, 6>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<6, 6, 1, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<6, 6, 5, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<6, 6, 6, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR_to_R8G8B8A8_UNORM_SRGB(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadASTCToRGBA8<8, 5>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<8, 5, 1, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR_to_R8G8B8A8_UNORM_SRGB(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadASTCToRGBA8<8, 6>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<8, 6, 1, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR_to_R8G8B8A8_UNORM_SRGB(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadASTCToRGBA8<8, 8>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<8, 8, 1, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB8_ALPHA8_ETC2_EAC_to_ETC2_R8G8B8A8_SRGB_BLOCK(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 16>, 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_ETC2_R8G8B8_SRGB_BLOCK(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 8>, 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_LOSSY_DECODE_ETC2_ANGLE_to_BC1_RGB_UNORM_SRGB_BLOCK(
+ GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadETC2SRGB8ToBC1, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2_to_ETC2_R8G8B8A1_SRGB_BLOCK(
+ GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 8>, 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
+COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE_to_BC1_RGBA_UNORM_SRGB_BLOCK(
+ GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadETC2SRGB8A1ToBC1, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 8>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 16>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo COMPRESSED_SRGB_S3TC_DXT1_EXT_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 8>, 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 DEPTH24_STENCIL8_to_D32_FLOAT_S8X24_UINT(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_INT_24_8:
+ return LoadImageFunctionInfo(LoadD24S8ToD32FS8X24, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo DEPTH32F_STENCIL8_to_D24_UNORM_S8_UINT(GLenum type)
+{
+ switch (type)
+ {
+ case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
+ return LoadImageFunctionInfo(LoadD32FS8X24ToD24S8, 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_COMPONENT16_to_D32_FLOAT(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_INT:
+ return LoadImageFunctionInfo(LoadUNorm32To32F, true);
+ case GL_UNSIGNED_SHORT:
+ return LoadImageFunctionInfo(LoadUNorm16To32F, true);
+ 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_COMPONENT24_to_D24_UNORM_X8_UINT(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_INT:
+ return LoadImageFunctionInfo(LoadR32ToR24G8, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo DEPTH_COMPONENT24_to_D32_FLOAT(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_INT:
+ return LoadImageFunctionInfo(LoadD24S8ToD32F, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo DEPTH_COMPONENT24_to_D32_FLOAT_S8X24_UINT(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_INT:
+ return LoadImageFunctionInfo(LoadD32ToD32FX32, true);
+ case GL_UNSIGNED_INT_24_8:
+ return LoadImageFunctionInfo(LoadD24S8ToD32FS8X24, 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_D32_FLOAT(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_INT:
+ return LoadImageFunctionInfo(LoadD32ToD32F, 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_ETC1_R8G8B8_UNORM_BLOCK(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 8>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo ETC1_RGB8_OES_to_ETC2_R8G8B8_UNORM_BLOCK(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadCompressedToNative<4, 4, 1, 8>, 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 G8_B8R8_2PLANE_420_UNORM_ANGLE_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadYuvToNative, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo G8_B8_R8_3PLANE_420_UNORM_ANGLE_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(UnimplementedLoadFunction, 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_R16_FLOAT(GLenum type)
+{
+ switch (type)
+ {
+ 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 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_R32_FLOAT(GLenum type)
+{
+ switch (type)
+ {
+ case GL_FLOAT:
+ return LoadImageFunctionInfo(LoadToNative<GLfloat, 1>, false);
+ 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_R8G8B8A8_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadLA8ToRGBA8, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo LUMINANCE8_ALPHA8_EXT_to_R8G8_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadToNative<GLubyte, 2>, false);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo LUMINANCE8_EXT_to_R8G8B8A8_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadL8ToRGBA8, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo LUMINANCE8_EXT_to_R8_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadToNative<GLubyte, 1>, false);
+ 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_R16G16_FLOAT(GLenum type)
+{
+ switch (type)
+ {
+ 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 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_R32G32_FLOAT(GLenum type)
+{
+ switch (type)
+ {
+ case GL_FLOAT:
+ return LoadImageFunctionInfo(LoadToNative<GLfloat, 2>, false);
+ 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 PALETTE4_R5_G6_B5_OES_to_R8G8B8A8_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadPalettedToRGBA8<4, 5, 6, 0>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo PALETTE4_RGB5_A1_OES_to_R8G8B8A8_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadPalettedToRGBA8<4, 5, 5, 1>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo PALETTE4_RGB8_OES_to_R8G8B8A8_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadPalettedToRGBA8<4, 8, 8, 0>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo PALETTE4_RGBA4_OES_to_R8G8B8A8_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadPalettedToRGBA8<4, 4, 4, 4>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo PALETTE4_RGBA8_OES_to_R8G8B8A8_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadPalettedToRGBA8<4, 8, 8, 8>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo PALETTE8_R5_G6_B5_OES_to_R8G8B8A8_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadPalettedToRGBA8<8, 5, 6, 0>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo PALETTE8_RGB5_A1_OES_to_R8G8B8A8_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadPalettedToRGBA8<8, 5, 5, 1>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo PALETTE8_RGB8_OES_to_R8G8B8A8_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadPalettedToRGBA8<8, 8, 8, 0>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo PALETTE8_RGBA4_OES_to_R8G8B8A8_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadPalettedToRGBA8<8, 4, 4, 4>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo PALETTE8_RGBA8_OES_to_R8G8B8A8_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadPalettedToRGBA8<8, 8, 8, 8>, 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 R16_SSCALED_ANGLEX_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo R16_USCALED_ANGLEX_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ 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 R8_SSCALED_ANGLEX_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo R8_USCALED_ANGLEX_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ 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 RG16_SSCALED_ANGLEX_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo RG16_USCALED_ANGLEX_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ 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 RG8_SSCALED_ANGLEX_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo RG8_USCALED_ANGLEX_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ 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 RGB10_A2_SINT_ANGLEX_to_R10G10B10A2_SINT(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadRGB10A2ToRGBA8, true);
+ case GL_UNSIGNED_INT_2_10_10_10_REV:
+ return LoadImageFunctionInfo(LoadToNative<GLuint, 1>, false);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo RGB10_A2_SNORM_ANGLEX_to_R10G10B10A2_SNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadRGB10A2ToRGBA8, true);
+ case GL_UNSIGNED_INT_2_10_10_10_REV:
+ return LoadImageFunctionInfo(LoadToNative<GLuint, 1>, false);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo RGB10_A2_SSCALED_ANGLEX_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo RGB10_A2_USCALED_ANGLEX_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo RGB10_UNORM_ANGLEX_to_R10G10B10A2_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_INT_2_10_10_10_REV:
+ return LoadImageFunctionInfo(LoadRGB10A2ToRGB10X2, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo RGB10_UNORM_ANGLEX_to_R10G10B10X2_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_INT_2_10_10_10_REV:
+ return LoadImageFunctionInfo(LoadRGB10A2ToRGB10X2, true);
+ 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 RGB16F_to_R16G16B16_FLOAT(GLenum type)
+{
+ switch (type)
+ {
+ case GL_FLOAT:
+ return LoadImageFunctionInfo(LoadRGB32FToRGB16F, true);
+ case GL_HALF_FLOAT:
+ return LoadImageFunctionInfo(LoadToNative<GLhalf, 3>, false);
+ case GL_HALF_FLOAT_OES:
+ return LoadImageFunctionInfo(LoadToNative<GLhalf, 3>, false);
+ 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 RGB16I_to_R16G16B16_SINT(GLenum type)
+{
+ switch (type)
+ {
+ case GL_SHORT:
+ return LoadImageFunctionInfo(LoadToNative<GLshort, 3>, false);
+ 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 RGB16UI_to_R16G16B16_UINT(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_SHORT:
+ return LoadImageFunctionInfo(LoadToNative<GLushort, 3>, false);
+ 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_EXT_to_R16G16B16_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_SHORT:
+ return LoadImageFunctionInfo(LoadToNative<GLushort, 3>, false);
+ 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 RGB16_SNORM_EXT_to_R16G16B16_SNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_SHORT:
+ return LoadImageFunctionInfo(LoadToNative<GLushort, 3>, false);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo RGB16_SSCALED_ANGLEX_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo RGB16_USCALED_ANGLEX_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(UnreachableLoadFunction, 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 RGB32F_to_R32G32B32_FLOAT(GLenum type)
+{
+ switch (type)
+ {
+ case GL_FLOAT:
+ return LoadImageFunctionInfo(LoadToNative<GLfloat, 3>, false);
+ 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 RGB32I_to_R32G32B32_SINT(GLenum type)
+{
+ switch (type)
+ {
+ case GL_INT:
+ return LoadImageFunctionInfo(LoadToNative<GLint, 3>, false);
+ 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 RGB32UI_to_R32G32B32_UINT(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_INT:
+ return LoadImageFunctionInfo(LoadToNative<GLuint, 3>, false);
+ 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_R5G6B5_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_A1R5G5B5_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_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_R5G5B5A1_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadRGBA8ToRGB5A1, true);
+ case GL_UNSIGNED_INT_2_10_10_10_REV:
+ return LoadImageFunctionInfo(LoadRGB10A2ToRGB5A1, true);
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ return LoadImageFunctionInfo(LoadToNative<GLushort, 1>, false);
+ 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 RGB8_to_R8G8B8_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadToNative<GLbyte, 3>, false);
+ 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 RGB8I_to_R8G8B8_SINT(GLenum type)
+{
+ switch (type)
+ {
+ case GL_BYTE:
+ return LoadImageFunctionInfo(LoadToNative<GLbyte, 3>, false);
+ 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 RGB8UI_to_R8G8B8_UINT(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadToNative<GLubyte, 3>, false);
+ 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 RGB8_SNORM_to_R8G8B8_SNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_BYTE:
+ return LoadImageFunctionInfo(LoadToNative<GLbyte, 3>, false);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo RGB8_SSCALED_ANGLEX_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo RGB8_USCALED_ANGLEX_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(UnreachableLoadFunction, 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 RGBA16_SSCALED_ANGLEX_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo RGBA16_USCALED_ANGLEX_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ 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_R4G4B4A4_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadRGBA8ToRGBA4, true);
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ return LoadImageFunctionInfo(LoadToNative<GLushort, 1>, false);
+ 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 RGBA8_SSCALED_ANGLEX_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo RGBA8_USCALED_ANGLEX_to_default(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo RGBX8_ANGLE_to_R8G8B8A8_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadToNative3To4<GLubyte, 0xFF>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo RGBX8_ANGLE_to_R8G8B8X8_UNORM(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadToNative3To4<GLubyte, 0xFF>, true);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo SR8_EXT_to_R8_UNORM_SRGB(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadToNative<GLbyte, 1>, false);
+ default:
+ UNREACHABLE();
+ return LoadImageFunctionInfo(UnreachableLoadFunction, true);
+ }
+}
+
+LoadImageFunctionInfo SRG8_EXT_to_R8G8_UNORM_SRGB(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadToNative<GLbyte, 2>, 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_to_R8G8B8_UNORM_SRGB(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadToNative<GLbyte, 3>, false);
+ 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_S8_UINT(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ return LoadImageFunctionInfo(LoadToNative<GLubyte, 1>, 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, FormatID angleFormat)
+{
+ // clang-format off
+ switch (internalFormat)
+ {
+ case GL_A1RGB5_ANGLEX:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::A1R5G5B5_UNORM:
+ return A1RGB5_ANGLEX_to_A1R5G5B5_UNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_ALPHA:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R16G16B16A16_FLOAT:
+ return ALPHA_to_R16G16B16A16_FLOAT;
+ case FormatID::R32G32B32A32_FLOAT:
+ return ALPHA_to_R32G32B32A32_FLOAT;
+ default:
+ return ALPHA_to_default;
+ }
+ }
+ case GL_ALPHA16F_EXT:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R16_FLOAT:
+ return ALPHA16F_EXT_to_R16_FLOAT;
+ default:
+ return ALPHA16F_EXT_to_default;
+ }
+ }
+ case GL_ALPHA32F_EXT:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R32_FLOAT:
+ return ALPHA32F_EXT_to_R32_FLOAT;
+ default:
+ return ALPHA32F_EXT_to_default;
+ }
+ }
+ case GL_ALPHA8_EXT:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::A8_UNORM:
+ return ALPHA8_EXT_to_A8_UNORM;
+ case FormatID::R8G8B8A8_UNORM:
+ return ALPHA8_EXT_to_R8G8B8A8_UNORM;
+ case FormatID::R8_UNORM:
+ return ALPHA8_EXT_to_R8_UNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_BGR10_A2_ANGLEX:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::B10G10R10A2_UNORM:
+ return BGR10_A2_ANGLEX_to_B10G10R10A2_UNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_BGR565_ANGLEX:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::B5G6R5_UNORM:
+ return BGR565_ANGLEX_to_B5G6R5_UNORM;
+ default:
+ break;
+ }
+ 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_BGRA8_SRGB_ANGLEX:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::B8G8R8A8_UNORM_SRGB:
+ return BGRA8_SRGB_ANGLEX_to_B8G8R8A8_UNORM_SRGB;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_BGRA_EXT:
+ return BGRA_EXT_to_default;
+ case GL_BGRX8_ANGLEX:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::B8G8R8A8_UNORM:
+ return BGRX8_ANGLEX_to_B8G8R8A8_UNORM;
+ case FormatID::B8G8R8X8_UNORM:
+ return BGRX8_ANGLEX_to_B8G8R8X8_UNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_COMPRESSED_R11_EAC:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::EAC_R11_UNORM_BLOCK:
+ return COMPRESSED_R11_EAC_to_EAC_R11_UNORM_BLOCK;
+ case FormatID::R16_FLOAT:
+ return COMPRESSED_R11_EAC_to_R16_FLOAT;
+ case FormatID::R16_UNORM:
+ return COMPRESSED_R11_EAC_to_R16_UNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
+ return COMPRESSED_RED_GREEN_RGTC2_EXT_to_default;
+ case GL_COMPRESSED_RED_RGTC1_EXT:
+ return COMPRESSED_RED_RGTC1_EXT_to_default;
+ case GL_COMPRESSED_RG11_EAC:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::EAC_R11G11_UNORM_BLOCK:
+ return COMPRESSED_RG11_EAC_to_EAC_R11G11_UNORM_BLOCK;
+ case FormatID::R16G16_FLOAT:
+ return COMPRESSED_RG11_EAC_to_R16G16_FLOAT;
+ case FormatID::R16G16_UNORM:
+ return COMPRESSED_RG11_EAC_to_R16G16_UNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_COMPRESSED_RGB8_ETC2:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::ETC2_R8G8B8_UNORM_BLOCK:
+ return COMPRESSED_RGB8_ETC2_to_ETC2_R8G8B8_UNORM_BLOCK;
+ case FormatID::R8G8B8A8_UNORM:
+ return COMPRESSED_RGB8_ETC2_to_R8G8B8A8_UNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::BC1_RGB_UNORM_BLOCK:
+ return COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE_to_BC1_RGB_UNORM_BLOCK;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::ETC2_R8G8B8A1_UNORM_BLOCK:
+ return COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2_to_ETC2_R8G8B8A1_UNORM_BLOCK;
+ case FormatID::R8G8B8A8_UNORM:
+ return COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2_to_R8G8B8A8_UNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::BC1_RGBA_UNORM_BLOCK:
+ return COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE_to_BC1_RGBA_UNORM_BLOCK;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_COMPRESSED_RGBA8_ETC2_EAC:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::ETC2_R8G8B8A8_UNORM_BLOCK:
+ return COMPRESSED_RGBA8_ETC2_EAC_to_ETC2_R8G8B8A8_UNORM_BLOCK;
+ case FormatID::R8G8B8A8_UNORM:
+ return COMPRESSED_RGBA8_ETC2_EAC_to_R8G8B8A8_UNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM:
+ return COMPRESSED_RGBA_ASTC_10x10_KHR_to_R8G8B8A8_UNORM;
+ default:
+ return COMPRESSED_RGBA_ASTC_10x10_KHR_to_default;
+ }
+ }
+ case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM:
+ return COMPRESSED_RGBA_ASTC_10x5_KHR_to_R8G8B8A8_UNORM;
+ default:
+ return COMPRESSED_RGBA_ASTC_10x5_KHR_to_default;
+ }
+ }
+ case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM:
+ return COMPRESSED_RGBA_ASTC_10x6_KHR_to_R8G8B8A8_UNORM;
+ default:
+ return COMPRESSED_RGBA_ASTC_10x6_KHR_to_default;
+ }
+ }
+ case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM:
+ return COMPRESSED_RGBA_ASTC_10x8_KHR_to_R8G8B8A8_UNORM;
+ default:
+ return COMPRESSED_RGBA_ASTC_10x8_KHR_to_default;
+ }
+ }
+ case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM:
+ return COMPRESSED_RGBA_ASTC_12x10_KHR_to_R8G8B8A8_UNORM;
+ default:
+ return COMPRESSED_RGBA_ASTC_12x10_KHR_to_default;
+ }
+ }
+ case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM:
+ return COMPRESSED_RGBA_ASTC_12x12_KHR_to_R8G8B8A8_UNORM;
+ default:
+ return COMPRESSED_RGBA_ASTC_12x12_KHR_to_default;
+ }
+ }
+ case GL_COMPRESSED_RGBA_ASTC_3x3x3_OES:
+ return COMPRESSED_RGBA_ASTC_3x3x3_OES_to_default;
+ case GL_COMPRESSED_RGBA_ASTC_4x3x3_OES:
+ return COMPRESSED_RGBA_ASTC_4x3x3_OES_to_default;
+ case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM:
+ return COMPRESSED_RGBA_ASTC_4x4_KHR_to_R8G8B8A8_UNORM;
+ default:
+ return COMPRESSED_RGBA_ASTC_4x4_KHR_to_default;
+ }
+ }
+ case GL_COMPRESSED_RGBA_ASTC_4x4x3_OES:
+ return COMPRESSED_RGBA_ASTC_4x4x3_OES_to_default;
+ case GL_COMPRESSED_RGBA_ASTC_4x4x4_OES:
+ return COMPRESSED_RGBA_ASTC_4x4x4_OES_to_default;
+ case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM:
+ return COMPRESSED_RGBA_ASTC_5x4_KHR_to_R8G8B8A8_UNORM;
+ default:
+ return COMPRESSED_RGBA_ASTC_5x4_KHR_to_default;
+ }
+ }
+ case GL_COMPRESSED_RGBA_ASTC_5x4x4_OES:
+ return COMPRESSED_RGBA_ASTC_5x4x4_OES_to_default;
+ case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM:
+ return COMPRESSED_RGBA_ASTC_5x5_KHR_to_R8G8B8A8_UNORM;
+ default:
+ return COMPRESSED_RGBA_ASTC_5x5_KHR_to_default;
+ }
+ }
+ case GL_COMPRESSED_RGBA_ASTC_5x5x4_OES:
+ return COMPRESSED_RGBA_ASTC_5x5x4_OES_to_default;
+ case GL_COMPRESSED_RGBA_ASTC_5x5x5_OES:
+ return COMPRESSED_RGBA_ASTC_5x5x5_OES_to_default;
+ case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM:
+ return COMPRESSED_RGBA_ASTC_6x5_KHR_to_R8G8B8A8_UNORM;
+ default:
+ return COMPRESSED_RGBA_ASTC_6x5_KHR_to_default;
+ }
+ }
+ case GL_COMPRESSED_RGBA_ASTC_6x5x5_OES:
+ return COMPRESSED_RGBA_ASTC_6x5x5_OES_to_default;
+ case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM:
+ return COMPRESSED_RGBA_ASTC_6x6_KHR_to_R8G8B8A8_UNORM;
+ default:
+ return COMPRESSED_RGBA_ASTC_6x6_KHR_to_default;
+ }
+ }
+ case GL_COMPRESSED_RGBA_ASTC_6x6x5_OES:
+ return COMPRESSED_RGBA_ASTC_6x6x5_OES_to_default;
+ case GL_COMPRESSED_RGBA_ASTC_6x6x6_OES:
+ return COMPRESSED_RGBA_ASTC_6x6x6_OES_to_default;
+ case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM:
+ return COMPRESSED_RGBA_ASTC_8x5_KHR_to_R8G8B8A8_UNORM;
+ default:
+ return COMPRESSED_RGBA_ASTC_8x5_KHR_to_default;
+ }
+ }
+ case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM:
+ return COMPRESSED_RGBA_ASTC_8x6_KHR_to_R8G8B8A8_UNORM;
+ default:
+ return COMPRESSED_RGBA_ASTC_8x6_KHR_to_default;
+ }
+ }
+ case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM:
+ return COMPRESSED_RGBA_ASTC_8x8_KHR_to_R8G8B8A8_UNORM;
+ default:
+ return COMPRESSED_RGBA_ASTC_8x8_KHR_to_default;
+ }
+ }
+ case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
+ return COMPRESSED_RGBA_BPTC_UNORM_EXT_to_default;
+ 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_BPTC_SIGNED_FLOAT_EXT:
+ return COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT_to_default;
+ case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
+ return COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT_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 FormatID::EAC_R11_SNORM_BLOCK:
+ return COMPRESSED_SIGNED_R11_EAC_to_EAC_R11_SNORM_BLOCK;
+ case FormatID::R16_FLOAT:
+ return COMPRESSED_SIGNED_R11_EAC_to_R16_FLOAT;
+ case FormatID::R16_SNORM:
+ return COMPRESSED_SIGNED_R11_EAC_to_R16_SNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:
+ return COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT_to_default;
+ case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:
+ return COMPRESSED_SIGNED_RED_RGTC1_EXT_to_default;
+ case GL_COMPRESSED_SIGNED_RG11_EAC:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::EAC_R11G11_SNORM_BLOCK:
+ return COMPRESSED_SIGNED_RG11_EAC_to_EAC_R11G11_SNORM_BLOCK;
+ case FormatID::R16G16_FLOAT:
+ return COMPRESSED_SIGNED_RG11_EAC_to_R16G16_FLOAT;
+ case FormatID::R16G16_SNORM:
+ return COMPRESSED_SIGNED_RG11_EAC_to_R16G16_SNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM_SRGB:
+ return COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR_to_R8G8B8A8_UNORM_SRGB;
+ default:
+ return COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR_to_default;
+ }
+ }
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM_SRGB:
+ return COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR_to_R8G8B8A8_UNORM_SRGB;
+ default:
+ return COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR_to_default;
+ }
+ }
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM_SRGB:
+ return COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR_to_R8G8B8A8_UNORM_SRGB;
+ default:
+ return COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR_to_default;
+ }
+ }
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM_SRGB:
+ return COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR_to_R8G8B8A8_UNORM_SRGB;
+ default:
+ return COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR_to_default;
+ }
+ }
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM_SRGB:
+ return COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR_to_R8G8B8A8_UNORM_SRGB;
+ default:
+ return COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR_to_default;
+ }
+ }
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM_SRGB:
+ return COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR_to_R8G8B8A8_UNORM_SRGB;
+ default:
+ return COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR_to_default;
+ }
+ }
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES:
+ return COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES_to_default;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES:
+ return COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES_to_default;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM_SRGB:
+ return COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR_to_R8G8B8A8_UNORM_SRGB;
+ default:
+ return COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR_to_default;
+ }
+ }
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES:
+ return COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES_to_default;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES:
+ return COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES_to_default;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM_SRGB:
+ return COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR_to_R8G8B8A8_UNORM_SRGB;
+ default:
+ return COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR_to_default;
+ }
+ }
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES:
+ return COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES_to_default;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM_SRGB:
+ return COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR_to_R8G8B8A8_UNORM_SRGB;
+ default:
+ return COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR_to_default;
+ }
+ }
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES:
+ return COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES_to_default;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES:
+ return COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES_to_default;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM_SRGB:
+ return COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR_to_R8G8B8A8_UNORM_SRGB;
+ default:
+ return COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR_to_default;
+ }
+ }
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES:
+ return COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES_to_default;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM_SRGB:
+ return COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR_to_R8G8B8A8_UNORM_SRGB;
+ default:
+ return COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR_to_default;
+ }
+ }
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES:
+ return COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES_to_default;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES:
+ return COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES_to_default;
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM_SRGB:
+ return COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR_to_R8G8B8A8_UNORM_SRGB;
+ default:
+ return COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR_to_default;
+ }
+ }
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM_SRGB:
+ return COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR_to_R8G8B8A8_UNORM_SRGB;
+ default:
+ return COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR_to_default;
+ }
+ }
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM_SRGB:
+ return COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR_to_R8G8B8A8_UNORM_SRGB;
+ default:
+ return COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR_to_default;
+ }
+ }
+ case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::ETC2_R8G8B8A8_SRGB_BLOCK:
+ return COMPRESSED_SRGB8_ALPHA8_ETC2_EAC_to_ETC2_R8G8B8A8_SRGB_BLOCK;
+ case FormatID::R8G8B8A8_UNORM_SRGB:
+ return COMPRESSED_SRGB8_ALPHA8_ETC2_EAC_to_R8G8B8A8_UNORM_SRGB;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_COMPRESSED_SRGB8_ETC2:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::ETC2_R8G8B8_SRGB_BLOCK:
+ return COMPRESSED_SRGB8_ETC2_to_ETC2_R8G8B8_SRGB_BLOCK;
+ case FormatID::R8G8B8A8_UNORM_SRGB:
+ return COMPRESSED_SRGB8_ETC2_to_R8G8B8A8_UNORM_SRGB;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::BC1_RGB_UNORM_SRGB_BLOCK:
+ return COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE_to_BC1_RGB_UNORM_SRGB_BLOCK;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::ETC2_R8G8B8A1_SRGB_BLOCK:
+ return COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2_to_ETC2_R8G8B8A1_SRGB_BLOCK;
+ case FormatID::R8G8B8A8_UNORM_SRGB:
+ return COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2_to_R8G8B8A8_UNORM_SRGB;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::BC1_RGBA_UNORM_SRGB_BLOCK:
+ return COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE_to_BC1_RGBA_UNORM_SRGB_BLOCK;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
+ return COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT_to_default;
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
+ return COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT_to_default;
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
+ return COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT_to_default;
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
+ return COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT_to_default;
+ case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
+ return COMPRESSED_SRGB_S3TC_DXT1_EXT_to_default;
+ case GL_DEPTH24_STENCIL8:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::D24_UNORM_S8_UINT:
+ return DEPTH24_STENCIL8_to_D24_UNORM_S8_UINT;
+ case FormatID::D32_FLOAT_S8X24_UINT:
+ return DEPTH24_STENCIL8_to_D32_FLOAT_S8X24_UINT;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_DEPTH32F_STENCIL8:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::D24_UNORM_S8_UINT:
+ return DEPTH32F_STENCIL8_to_D24_UNORM_S8_UINT;
+ case FormatID::D32_FLOAT_S8X24_UINT:
+ return DEPTH32F_STENCIL8_to_D32_FLOAT_S8X24_UINT;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_DEPTH_COMPONENT16:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::D16_UNORM:
+ return DEPTH_COMPONENT16_to_D16_UNORM;
+ case FormatID::D32_FLOAT:
+ return DEPTH_COMPONENT16_to_D32_FLOAT;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_DEPTH_COMPONENT24:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::D24_UNORM_S8_UINT:
+ return DEPTH_COMPONENT24_to_D24_UNORM_S8_UINT;
+ case FormatID::D24_UNORM_X8_UINT:
+ return DEPTH_COMPONENT24_to_D24_UNORM_X8_UINT;
+ case FormatID::D32_FLOAT:
+ return DEPTH_COMPONENT24_to_D32_FLOAT;
+ case FormatID::D32_FLOAT_S8X24_UINT:
+ return DEPTH_COMPONENT24_to_D32_FLOAT_S8X24_UINT;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_DEPTH_COMPONENT32F:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::D32_FLOAT:
+ return DEPTH_COMPONENT32F_to_D32_FLOAT;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_DEPTH_COMPONENT32_OES:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::D32_FLOAT:
+ return DEPTH_COMPONENT32_OES_to_D32_FLOAT;
+ default:
+ return DEPTH_COMPONENT32_OES_to_default;
+ }
+ }
+ case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::BC1_RGB_UNORM_BLOCK:
+ return ETC1_RGB8_LOSSY_DECODE_ANGLE_to_BC1_RGB_UNORM_BLOCK;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_ETC1_RGB8_OES:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::ETC1_R8G8B8_UNORM_BLOCK:
+ return ETC1_RGB8_OES_to_ETC1_R8G8B8_UNORM_BLOCK;
+ case FormatID::ETC2_R8G8B8_UNORM_BLOCK:
+ return ETC1_RGB8_OES_to_ETC2_R8G8B8_UNORM_BLOCK;
+ case FormatID::R8G8B8A8_UNORM:
+ return ETC1_RGB8_OES_to_R8G8B8A8_UNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_G8_B8R8_2PLANE_420_UNORM_ANGLE:
+ return G8_B8R8_2PLANE_420_UNORM_ANGLE_to_default;
+ case GL_G8_B8_R8_3PLANE_420_UNORM_ANGLE:
+ return G8_B8_R8_3PLANE_420_UNORM_ANGLE_to_default;
+ case GL_LUMINANCE:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R16G16B16A16_FLOAT:
+ return LUMINANCE_to_R16G16B16A16_FLOAT;
+ case FormatID::R32G32B32A32_FLOAT:
+ return LUMINANCE_to_R32G32B32A32_FLOAT;
+ default:
+ return LUMINANCE_to_default;
+ }
+ }
+ case GL_LUMINANCE16F_EXT:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R16_FLOAT:
+ return LUMINANCE16F_EXT_to_R16_FLOAT;
+ default:
+ return LUMINANCE16F_EXT_to_default;
+ }
+ }
+ case GL_LUMINANCE32F_EXT:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R32_FLOAT:
+ return LUMINANCE32F_EXT_to_R32_FLOAT;
+ default:
+ return LUMINANCE32F_EXT_to_default;
+ }
+ }
+ case GL_LUMINANCE8_ALPHA8_EXT:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM:
+ return LUMINANCE8_ALPHA8_EXT_to_R8G8B8A8_UNORM;
+ case FormatID::R8G8_UNORM:
+ return LUMINANCE8_ALPHA8_EXT_to_R8G8_UNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_LUMINANCE8_EXT:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM:
+ return LUMINANCE8_EXT_to_R8G8B8A8_UNORM;
+ case FormatID::R8_UNORM:
+ return LUMINANCE8_EXT_to_R8_UNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_LUMINANCE_ALPHA:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R16G16B16A16_FLOAT:
+ return LUMINANCE_ALPHA_to_R16G16B16A16_FLOAT;
+ case FormatID::R32G32B32A32_FLOAT:
+ return LUMINANCE_ALPHA_to_R32G32B32A32_FLOAT;
+ default:
+ return LUMINANCE_ALPHA_to_default;
+ }
+ }
+ case GL_LUMINANCE_ALPHA16F_EXT:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R16G16_FLOAT:
+ return LUMINANCE_ALPHA16F_EXT_to_R16G16_FLOAT;
+ default:
+ return LUMINANCE_ALPHA16F_EXT_to_default;
+ }
+ }
+ case GL_LUMINANCE_ALPHA32F_EXT:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R32G32_FLOAT:
+ return LUMINANCE_ALPHA32F_EXT_to_R32G32_FLOAT;
+ default:
+ return LUMINANCE_ALPHA32F_EXT_to_default;
+ }
+ }
+ case GL_PALETTE4_R5_G6_B5_OES:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM:
+ return PALETTE4_R5_G6_B5_OES_to_R8G8B8A8_UNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_PALETTE4_RGB5_A1_OES:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM:
+ return PALETTE4_RGB5_A1_OES_to_R8G8B8A8_UNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_PALETTE4_RGB8_OES:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM:
+ return PALETTE4_RGB8_OES_to_R8G8B8A8_UNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_PALETTE4_RGBA4_OES:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM:
+ return PALETTE4_RGBA4_OES_to_R8G8B8A8_UNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_PALETTE4_RGBA8_OES:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM:
+ return PALETTE4_RGBA8_OES_to_R8G8B8A8_UNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_PALETTE8_R5_G6_B5_OES:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM:
+ return PALETTE8_R5_G6_B5_OES_to_R8G8B8A8_UNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_PALETTE8_RGB5_A1_OES:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM:
+ return PALETTE8_RGB5_A1_OES_to_R8G8B8A8_UNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_PALETTE8_RGB8_OES:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM:
+ return PALETTE8_RGB8_OES_to_R8G8B8A8_UNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_PALETTE8_RGBA4_OES:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM:
+ return PALETTE8_RGBA4_OES_to_R8G8B8A8_UNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_PALETTE8_RGBA8_OES:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM:
+ return PALETTE8_RGBA8_OES_to_R8G8B8A8_UNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_R11F_G11F_B10F:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R11G11B10_FLOAT:
+ return R11F_G11F_B10F_to_R11G11B10_FLOAT;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_R16F:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R16_FLOAT:
+ return R16F_to_R16_FLOAT;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_R16I:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R16_SINT:
+ return R16I_to_R16_SINT;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_R16UI:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R16_UINT:
+ return R16UI_to_R16_UINT;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_R16_EXT:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R16_UNORM:
+ return R16_EXT_to_R16_UNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_R16_SNORM_EXT:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R16_SNORM:
+ return R16_SNORM_EXT_to_R16_SNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_R16_SSCALED_ANGLEX:
+ return R16_SSCALED_ANGLEX_to_default;
+ case GL_R16_USCALED_ANGLEX:
+ return R16_USCALED_ANGLEX_to_default;
+ case GL_R32F:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R32_FLOAT:
+ return R32F_to_R32_FLOAT;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_R32I:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R32_SINT:
+ return R32I_to_R32_SINT;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_R32UI:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R32_UINT:
+ return R32UI_to_R32_UINT;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_R8:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8_UNORM:
+ return R8_to_R8_UNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_R8I:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8_SINT:
+ return R8I_to_R8_SINT;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_R8UI:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8_UINT:
+ return R8UI_to_R8_UINT;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_R8_SNORM:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8_SNORM:
+ return R8_SNORM_to_R8_SNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_R8_SSCALED_ANGLEX:
+ return R8_SSCALED_ANGLEX_to_default;
+ case GL_R8_USCALED_ANGLEX:
+ return R8_USCALED_ANGLEX_to_default;
+ case GL_RG16F:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R16G16_FLOAT:
+ return RG16F_to_R16G16_FLOAT;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RG16I:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R16G16_SINT:
+ return RG16I_to_R16G16_SINT;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RG16UI:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R16G16_UINT:
+ return RG16UI_to_R16G16_UINT;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RG16_EXT:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R16G16_UNORM:
+ return RG16_EXT_to_R16G16_UNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RG16_SNORM_EXT:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R16G16_SNORM:
+ return RG16_SNORM_EXT_to_R16G16_SNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RG16_SSCALED_ANGLEX:
+ return RG16_SSCALED_ANGLEX_to_default;
+ case GL_RG16_USCALED_ANGLEX:
+ return RG16_USCALED_ANGLEX_to_default;
+ case GL_RG32F:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R32G32_FLOAT:
+ return RG32F_to_R32G32_FLOAT;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RG32I:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R32G32_SINT:
+ return RG32I_to_R32G32_SINT;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RG32UI:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R32G32_UINT:
+ return RG32UI_to_R32G32_UINT;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RG8:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8_UNORM:
+ return RG8_to_R8G8_UNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RG8I:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8_SINT:
+ return RG8I_to_R8G8_SINT;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RG8UI:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8_UINT:
+ return RG8UI_to_R8G8_UINT;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RG8_SNORM:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8_SNORM:
+ return RG8_SNORM_to_R8G8_SNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RG8_SSCALED_ANGLEX:
+ return RG8_SSCALED_ANGLEX_to_default;
+ case GL_RG8_USCALED_ANGLEX:
+ return RG8_USCALED_ANGLEX_to_default;
+ case GL_RGB:
+ return RGB_to_default;
+ case GL_RGB10_A2:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R10G10B10A2_UNORM:
+ return RGB10_A2_to_R10G10B10A2_UNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RGB10_A2UI:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R10G10B10A2_UINT:
+ return RGB10_A2UI_to_R10G10B10A2_UINT;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RGB10_A2_SINT_ANGLEX:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R10G10B10A2_SINT:
+ return RGB10_A2_SINT_ANGLEX_to_R10G10B10A2_SINT;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RGB10_A2_SNORM_ANGLEX:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R10G10B10A2_SNORM:
+ return RGB10_A2_SNORM_ANGLEX_to_R10G10B10A2_SNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RGB10_A2_SSCALED_ANGLEX:
+ return RGB10_A2_SSCALED_ANGLEX_to_default;
+ case GL_RGB10_A2_USCALED_ANGLEX:
+ return RGB10_A2_USCALED_ANGLEX_to_default;
+ case GL_RGB10_UNORM_ANGLEX:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R10G10B10A2_UNORM:
+ return RGB10_UNORM_ANGLEX_to_R10G10B10A2_UNORM;
+ case FormatID::R10G10B10X2_UNORM:
+ return RGB10_UNORM_ANGLEX_to_R10G10B10X2_UNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RGB16F:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R16G16B16A16_FLOAT:
+ return RGB16F_to_R16G16B16A16_FLOAT;
+ case FormatID::R16G16B16_FLOAT:
+ return RGB16F_to_R16G16B16_FLOAT;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RGB16I:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R16G16B16A16_SINT:
+ return RGB16I_to_R16G16B16A16_SINT;
+ case FormatID::R16G16B16_SINT:
+ return RGB16I_to_R16G16B16_SINT;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RGB16UI:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R16G16B16A16_UINT:
+ return RGB16UI_to_R16G16B16A16_UINT;
+ case FormatID::R16G16B16_UINT:
+ return RGB16UI_to_R16G16B16_UINT;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RGB16_EXT:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R16G16B16A16_UNORM:
+ return RGB16_EXT_to_R16G16B16A16_UNORM;
+ case FormatID::R16G16B16_UNORM:
+ return RGB16_EXT_to_R16G16B16_UNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RGB16_SNORM_EXT:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R16G16B16A16_SNORM:
+ return RGB16_SNORM_EXT_to_R16G16B16A16_SNORM;
+ case FormatID::R16G16B16_SNORM:
+ return RGB16_SNORM_EXT_to_R16G16B16_SNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RGB16_SSCALED_ANGLEX:
+ return RGB16_SSCALED_ANGLEX_to_default;
+ case GL_RGB16_USCALED_ANGLEX:
+ return RGB16_USCALED_ANGLEX_to_default;
+ case GL_RGB32F:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R32G32B32A32_FLOAT:
+ return RGB32F_to_R32G32B32A32_FLOAT;
+ case FormatID::R32G32B32_FLOAT:
+ return RGB32F_to_R32G32B32_FLOAT;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RGB32I:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R32G32B32A32_SINT:
+ return RGB32I_to_R32G32B32A32_SINT;
+ case FormatID::R32G32B32_SINT:
+ return RGB32I_to_R32G32B32_SINT;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RGB32UI:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R32G32B32A32_UINT:
+ return RGB32UI_to_R32G32B32A32_UINT;
+ case FormatID::R32G32B32_UINT:
+ return RGB32UI_to_R32G32B32_UINT;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RGB565:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::B5G6R5_UNORM:
+ return RGB565_to_B5G6R5_UNORM;
+ case FormatID::R5G6B5_UNORM:
+ return RGB565_to_R5G6B5_UNORM;
+ case FormatID::R8G8B8A8_UNORM:
+ return RGB565_to_R8G8B8A8_UNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RGB5_A1:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::A1R5G5B5_UNORM:
+ return RGB5_A1_to_A1R5G5B5_UNORM;
+ case FormatID::B5G5R5A1_UNORM:
+ return RGB5_A1_to_B5G5R5A1_UNORM;
+ case FormatID::R5G5B5A1_UNORM:
+ return RGB5_A1_to_R5G5B5A1_UNORM;
+ case FormatID::R8G8B8A8_UNORM:
+ return RGB5_A1_to_R8G8B8A8_UNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RGB8:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM:
+ return RGB8_to_R8G8B8A8_UNORM;
+ case FormatID::R8G8B8_UNORM:
+ return RGB8_to_R8G8B8_UNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RGB8I:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_SINT:
+ return RGB8I_to_R8G8B8A8_SINT;
+ case FormatID::R8G8B8_SINT:
+ return RGB8I_to_R8G8B8_SINT;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RGB8UI:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UINT:
+ return RGB8UI_to_R8G8B8A8_UINT;
+ case FormatID::R8G8B8_UINT:
+ return RGB8UI_to_R8G8B8_UINT;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RGB8_SNORM:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_SNORM:
+ return RGB8_SNORM_to_R8G8B8A8_SNORM;
+ case FormatID::R8G8B8_SNORM:
+ return RGB8_SNORM_to_R8G8B8_SNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RGB8_SSCALED_ANGLEX:
+ return RGB8_SSCALED_ANGLEX_to_default;
+ case GL_RGB8_USCALED_ANGLEX:
+ return RGB8_USCALED_ANGLEX_to_default;
+ case GL_RGB9_E5:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R9G9B9E5_SHAREDEXP:
+ return RGB9_E5_to_R9G9B9E5_SHAREDEXP;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RGBA:
+ return RGBA_to_default;
+ case GL_RGBA16F:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R16G16B16A16_FLOAT:
+ return RGBA16F_to_R16G16B16A16_FLOAT;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RGBA16I:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R16G16B16A16_SINT:
+ return RGBA16I_to_R16G16B16A16_SINT;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RGBA16UI:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R16G16B16A16_UINT:
+ return RGBA16UI_to_R16G16B16A16_UINT;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RGBA16_EXT:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R16G16B16A16_UNORM:
+ return RGBA16_EXT_to_R16G16B16A16_UNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RGBA16_SNORM_EXT:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R16G16B16A16_SNORM:
+ return RGBA16_SNORM_EXT_to_R16G16B16A16_SNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RGBA16_SSCALED_ANGLEX:
+ return RGBA16_SSCALED_ANGLEX_to_default;
+ case GL_RGBA16_USCALED_ANGLEX:
+ return RGBA16_USCALED_ANGLEX_to_default;
+ case GL_RGBA32F:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R32G32B32A32_FLOAT:
+ return RGBA32F_to_R32G32B32A32_FLOAT;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RGBA32I:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R32G32B32A32_SINT:
+ return RGBA32I_to_R32G32B32A32_SINT;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RGBA32UI:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R32G32B32A32_UINT:
+ return RGBA32UI_to_R32G32B32A32_UINT;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RGBA4:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::B4G4R4A4_UNORM:
+ return RGBA4_to_B4G4R4A4_UNORM;
+ case FormatID::R4G4B4A4_UNORM:
+ return RGBA4_to_R4G4B4A4_UNORM;
+ case FormatID::R8G8B8A8_UNORM:
+ return RGBA4_to_R8G8B8A8_UNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RGBA8:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM:
+ return RGBA8_to_R8G8B8A8_UNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RGBA8I:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_SINT:
+ return RGBA8I_to_R8G8B8A8_SINT;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RGBA8UI:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UINT:
+ return RGBA8UI_to_R8G8B8A8_UINT;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RGBA8_SNORM:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_SNORM:
+ return RGBA8_SNORM_to_R8G8B8A8_SNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_RGBA8_SSCALED_ANGLEX:
+ return RGBA8_SSCALED_ANGLEX_to_default;
+ case GL_RGBA8_USCALED_ANGLEX:
+ return RGBA8_USCALED_ANGLEX_to_default;
+ case GL_RGBX8_ANGLE:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM:
+ return RGBX8_ANGLE_to_R8G8B8A8_UNORM;
+ case FormatID::R8G8B8X8_UNORM:
+ return RGBX8_ANGLE_to_R8G8B8X8_UNORM;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_SR8_EXT:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8_UNORM_SRGB:
+ return SR8_EXT_to_R8_UNORM_SRGB;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_SRG8_EXT:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8_UNORM_SRGB:
+ return SRG8_EXT_to_R8G8_UNORM_SRGB;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_SRGB8:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM_SRGB:
+ return SRGB8_to_R8G8B8A8_UNORM_SRGB;
+ case FormatID::R8G8B8_UNORM_SRGB:
+ return SRGB8_to_R8G8B8_UNORM_SRGB;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_SRGB8_ALPHA8:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::R8G8B8A8_UNORM_SRGB:
+ return SRGB8_ALPHA8_to_R8G8B8A8_UNORM_SRGB;
+ default:
+ break;
+ }
+ break;
+ }
+ case GL_STENCIL_INDEX8:
+ {
+ switch (angleFormat)
+ {
+ case FormatID::S8_UINT:
+ return STENCIL_INDEX8_to_S8_UINT;
+ default:
+ return STENCIL_INDEX8_to_default;
+ }
+ }
+
+ default:
+ break;
+ }
+ // clang-format on
+ ASSERT(internalFormat == GL_NONE || angleFormat == angle::FormatID::NONE);
+ static LoadFunctionMap emptyLoadFunctionsMap;
+ return emptyLoadFunctionsMap;
+
+} // GetLoadFunctionsMap
+
+} // namespace angle
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/renderer_utils.cpp b/gfx/angle/checkout/src/libANGLE/renderer/renderer_utils.cpp
new file mode 100644
index 0000000000..152de2f25d
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/renderer_utils.cpp
@@ -0,0 +1,1583 @@
+//
+// 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.
+//
+// renderer_utils:
+// Helper methods pertaining to most or all back-ends.
+//
+
+#include "libANGLE/renderer/renderer_utils.h"
+
+#include "common/string_utils.h"
+#include "common/system_utils.h"
+#include "common/utilities.h"
+#include "image_util/copyimage.h"
+#include "image_util/imageformats.h"
+#include "libANGLE/AttributeMap.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Context.inl.h"
+#include "libANGLE/Display.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/ContextImpl.h"
+#include "libANGLE/renderer/Format.h"
+#include "platform/Feature.h"
+
+#include <string.h>
+#include <cctype>
+
+namespace angle
+{
+namespace
+{
+// For the sake of feature name matching, underscore is ignored, and the names are matched
+// case-insensitive. This allows feature names to be overriden both in snake_case (previously used
+// by ANGLE) and camelCase. The second string (user-provided name) can end in `*` for wildcard
+// matching.
+bool FeatureNameMatch(const std::string &a, const std::string &b)
+{
+ size_t ai = 0;
+ size_t bi = 0;
+
+ while (ai < a.size() && bi < b.size())
+ {
+ if (a[ai] == '_')
+ {
+ ++ai;
+ }
+ if (b[bi] == '_')
+ {
+ ++bi;
+ }
+ if (b[bi] == '*' && bi + 1 == b.size())
+ {
+ // If selected feature name ends in wildcard, match it.
+ return true;
+ }
+ if (std::tolower(a[ai++]) != std::tolower(b[bi++]))
+ {
+ return false;
+ }
+ }
+
+ return ai == a.size() && bi == b.size();
+}
+} // anonymous namespace
+
+// FeatureSetBase implementation
+void FeatureSetBase::overrideFeatures(const std::vector<std::string> &featureNames, bool enabled)
+{
+ for (const std::string &name : featureNames)
+ {
+ const bool hasWildcard = name.back() == '*';
+ for (auto iter : members)
+ {
+ const std::string &featureName = iter.first;
+ FeatureInfo *feature = iter.second;
+
+ if (!FeatureNameMatch(featureName, name))
+ {
+ continue;
+ }
+
+ feature->enabled = enabled;
+
+ // If name has a wildcard, try to match it with all features. Otherwise, bail on first
+ // match, as names are unique.
+ if (!hasWildcard)
+ {
+ break;
+ }
+ }
+ }
+}
+
+void FeatureSetBase::populateFeatureList(FeatureList *features) const
+{
+ for (FeatureMap::const_iterator it = members.begin(); it != members.end(); it++)
+ {
+ features->push_back(it->second);
+ }
+}
+} // namespace angle
+
+namespace rx
+{
+
+namespace
+{
+// Both D3D and Vulkan support the same set of standard sample positions for 1, 2, 4, 8, and 16
+// samples. See:
+//
+// - https://msdn.microsoft.com/en-us/library/windows/desktop/ff476218.aspx
+//
+// -
+// https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#primsrast-multisampling
+using SamplePositionsArray = std::array<float, 32>;
+constexpr std::array<SamplePositionsArray, 5> kSamplePositions = {
+ {{{0.5f, 0.5f}},
+ {{0.75f, 0.75f, 0.25f, 0.25f}},
+ {{0.375f, 0.125f, 0.875f, 0.375f, 0.125f, 0.625f, 0.625f, 0.875f}},
+ {{0.5625f, 0.3125f, 0.4375f, 0.6875f, 0.8125f, 0.5625f, 0.3125f, 0.1875f, 0.1875f, 0.8125f,
+ 0.0625f, 0.4375f, 0.6875f, 0.9375f, 0.9375f, 0.0625f}},
+ {{0.5625f, 0.5625f, 0.4375f, 0.3125f, 0.3125f, 0.625f, 0.75f, 0.4375f,
+ 0.1875f, 0.375f, 0.625f, 0.8125f, 0.8125f, 0.6875f, 0.6875f, 0.1875f,
+ 0.375f, 0.875f, 0.5f, 0.0625f, 0.25f, 0.125f, 0.125f, 0.75f,
+ 0.0f, 0.5f, 0.9375f, 0.25f, 0.875f, 0.9375f, 0.0625f, 0.0f}}}};
+
+struct IncompleteTextureParameters
+{
+ GLenum sizedInternalFormat;
+ GLenum format;
+ GLenum type;
+ GLubyte clearColor[4];
+};
+
+// Note that for gl::SamplerFormat::Shadow, the clearColor datatype needs to be GLushort and as such
+// we will reinterpret GLubyte[4] as GLushort[2].
+constexpr angle::PackedEnumMap<gl::SamplerFormat, IncompleteTextureParameters>
+ kIncompleteTextureParameters = {
+ {gl::SamplerFormat::Float, {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, {0, 0, 0, 255}}},
+ {gl::SamplerFormat::Unsigned,
+ {GL_RGBA8UI, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, {0, 0, 0, 255}}},
+ {gl::SamplerFormat::Signed, {GL_RGBA8I, GL_RGBA_INTEGER, GL_BYTE, {0, 0, 0, 127}}},
+ {gl::SamplerFormat::Shadow,
+ {GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, {0, 0, 0, 0}}}};
+
+void CopyColor(gl::ColorF *color)
+{
+ // No-op
+}
+
+void PremultiplyAlpha(gl::ColorF *color)
+{
+ color->red *= color->alpha;
+ color->green *= color->alpha;
+ color->blue *= color->alpha;
+}
+
+void UnmultiplyAlpha(gl::ColorF *color)
+{
+ if (color->alpha != 0.0f)
+ {
+ float invAlpha = 1.0f / color->alpha;
+ color->red *= invAlpha;
+ color->green *= invAlpha;
+ color->blue *= invAlpha;
+ }
+}
+
+void ClipChannelsR(gl::ColorF *color)
+{
+ color->green = 0.0f;
+ color->blue = 0.0f;
+ color->alpha = 1.0f;
+}
+
+void ClipChannelsRG(gl::ColorF *color)
+{
+ color->blue = 0.0f;
+ color->alpha = 1.0f;
+}
+
+void ClipChannelsRGB(gl::ColorF *color)
+{
+ color->alpha = 1.0f;
+}
+
+void ClipChannelsLuminance(gl::ColorF *color)
+{
+ color->alpha = 1.0f;
+}
+
+void ClipChannelsAlpha(gl::ColorF *color)
+{
+ color->red = 0.0f;
+ color->green = 0.0f;
+ color->blue = 0.0f;
+}
+
+void ClipChannelsNoOp(gl::ColorF *color) {}
+
+void WriteUintColor(const gl::ColorF &color,
+ PixelWriteFunction colorWriteFunction,
+ uint8_t *destPixelData)
+{
+ gl::ColorUI destColor(
+ static_cast<unsigned int>(color.red * 255), static_cast<unsigned int>(color.green * 255),
+ static_cast<unsigned int>(color.blue * 255), static_cast<unsigned int>(color.alpha * 255));
+ colorWriteFunction(reinterpret_cast<const uint8_t *>(&destColor), destPixelData);
+}
+
+void WriteFloatColor(const gl::ColorF &color,
+ PixelWriteFunction colorWriteFunction,
+ uint8_t *destPixelData)
+{
+ colorWriteFunction(reinterpret_cast<const uint8_t *>(&color), destPixelData);
+}
+
+template <int cols, int rows, bool IsColumnMajor>
+inline int GetFlattenedIndex(int col, int row)
+{
+ if (IsColumnMajor)
+ {
+ return col * rows + row;
+ }
+ else
+ {
+ return row * cols + col;
+ }
+}
+
+template <typename T,
+ bool IsSrcColumnMajor,
+ int colsSrc,
+ int rowsSrc,
+ bool IsDstColumnMajor,
+ int colsDst,
+ int rowsDst>
+void ExpandMatrix(T *target, const GLfloat *value)
+{
+ static_assert(colsSrc <= colsDst && rowsSrc <= rowsDst, "Can only expand!");
+
+ constexpr int kDstFlatSize = colsDst * rowsDst;
+ T staging[kDstFlatSize] = {0};
+
+ for (int r = 0; r < rowsSrc; r++)
+ {
+ for (int c = 0; c < colsSrc; c++)
+ {
+ int srcIndex = GetFlattenedIndex<colsSrc, rowsSrc, IsSrcColumnMajor>(c, r);
+ int dstIndex = GetFlattenedIndex<colsDst, rowsDst, IsDstColumnMajor>(c, r);
+
+ staging[dstIndex] = static_cast<T>(value[srcIndex]);
+ }
+ }
+
+ memcpy(target, staging, kDstFlatSize * sizeof(T));
+}
+
+template <bool IsSrcColumMajor,
+ int colsSrc,
+ int rowsSrc,
+ bool IsDstColumnMajor,
+ int colsDst,
+ int rowsDst>
+void SetFloatUniformMatrix(unsigned int arrayElementOffset,
+ unsigned int elementCount,
+ GLsizei countIn,
+ const GLfloat *value,
+ uint8_t *targetData)
+{
+ unsigned int count =
+ std::min(elementCount - arrayElementOffset, static_cast<unsigned int>(countIn));
+
+ const unsigned int targetMatrixStride = colsDst * rowsDst;
+ GLfloat *target = reinterpret_cast<GLfloat *>(
+ targetData + arrayElementOffset * sizeof(GLfloat) * targetMatrixStride);
+
+ for (unsigned int i = 0; i < count; i++)
+ {
+ ExpandMatrix<GLfloat, IsSrcColumMajor, colsSrc, rowsSrc, IsDstColumnMajor, colsDst,
+ rowsDst>(target, value);
+
+ target += targetMatrixStride;
+ value += colsSrc * rowsSrc;
+ }
+}
+
+void SetFloatUniformMatrixFast(unsigned int arrayElementOffset,
+ unsigned int elementCount,
+ GLsizei countIn,
+ size_t matrixSize,
+ const GLfloat *value,
+ uint8_t *targetData)
+{
+ const unsigned int count =
+ std::min(elementCount - arrayElementOffset, static_cast<unsigned int>(countIn));
+
+ const uint8_t *valueData = reinterpret_cast<const uint8_t *>(value);
+ targetData = targetData + arrayElementOffset * matrixSize;
+
+ memcpy(targetData, valueData, matrixSize * count);
+}
+} // anonymous namespace
+
+bool IsRotatedAspectRatio(SurfaceRotation rotation)
+{
+ switch (rotation)
+ {
+ case SurfaceRotation::Rotated90Degrees:
+ case SurfaceRotation::Rotated270Degrees:
+ case SurfaceRotation::FlippedRotated90Degrees:
+ case SurfaceRotation::FlippedRotated270Degrees:
+ return true;
+ default:
+ return false;
+ }
+}
+
+void RotateRectangle(const SurfaceRotation rotation,
+ const bool flipY,
+ const int framebufferWidth,
+ const int framebufferHeight,
+ const gl::Rectangle &incoming,
+ gl::Rectangle *outgoing)
+{
+ // GLES's y-axis points up; Vulkan's points down.
+ switch (rotation)
+ {
+ case SurfaceRotation::Identity:
+ // Do not rotate gl_Position (surface matches the device's orientation):
+ outgoing->x = incoming.x;
+ outgoing->y = flipY ? framebufferHeight - incoming.y - incoming.height : incoming.y;
+ outgoing->width = incoming.width;
+ outgoing->height = incoming.height;
+ break;
+ case SurfaceRotation::Rotated90Degrees:
+ // Rotate gl_Position 90 degrees:
+ outgoing->x = incoming.y;
+ outgoing->y = flipY ? incoming.x : framebufferWidth - incoming.x - incoming.width;
+ outgoing->width = incoming.height;
+ outgoing->height = incoming.width;
+ break;
+ case SurfaceRotation::Rotated180Degrees:
+ // Rotate gl_Position 180 degrees:
+ outgoing->x = framebufferWidth - incoming.x - incoming.width;
+ outgoing->y = flipY ? incoming.y : framebufferHeight - incoming.y - incoming.height;
+ outgoing->width = incoming.width;
+ outgoing->height = incoming.height;
+ break;
+ case SurfaceRotation::Rotated270Degrees:
+ // Rotate gl_Position 270 degrees:
+ outgoing->x = framebufferHeight - incoming.y - incoming.height;
+ outgoing->y = flipY ? framebufferWidth - incoming.x - incoming.width : incoming.x;
+ outgoing->width = incoming.height;
+ outgoing->height = incoming.width;
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+}
+
+PackPixelsParams::PackPixelsParams()
+ : destFormat(nullptr),
+ outputPitch(0),
+ packBuffer(nullptr),
+ offset(0),
+ rotation(SurfaceRotation::Identity)
+{}
+
+PackPixelsParams::PackPixelsParams(const gl::Rectangle &areaIn,
+ const angle::Format &destFormat,
+ GLuint outputPitchIn,
+ bool reverseRowOrderIn,
+ gl::Buffer *packBufferIn,
+ ptrdiff_t offsetIn)
+ : area(areaIn),
+ destFormat(&destFormat),
+ outputPitch(outputPitchIn),
+ packBuffer(packBufferIn),
+ reverseRowOrder(reverseRowOrderIn),
+ offset(offsetIn),
+ rotation(SurfaceRotation::Identity)
+{}
+
+void PackPixels(const PackPixelsParams &params,
+ const angle::Format &sourceFormat,
+ int inputPitchIn,
+ const uint8_t *sourceIn,
+ uint8_t *destWithoutOffset)
+{
+ uint8_t *destWithOffset = destWithoutOffset + params.offset;
+
+ const uint8_t *source = sourceIn;
+ int inputPitch = inputPitchIn;
+ int destWidth = params.area.width;
+ int destHeight = params.area.height;
+ int xAxisPitch = 0;
+ int yAxisPitch = 0;
+ switch (params.rotation)
+ {
+ case SurfaceRotation::Identity:
+ // The source image is not rotated (i.e. matches the device's orientation), and may or
+ // may not be y-flipped. The image is row-major. Each source row (one step along the
+ // y-axis for each step in the dest y-axis) is inputPitch past the previous row. Along
+ // a row, each source pixel (one step along the x-axis for each step in the dest
+ // x-axis) is sourceFormat.pixelBytes past the previous pixel.
+ xAxisPitch = sourceFormat.pixelBytes;
+ if (params.reverseRowOrder)
+ {
+ // The source image is y-flipped, which means we start at the last row, and each
+ // source row is BEFORE the previous row.
+ source += inputPitchIn * (params.area.height - 1);
+ inputPitch = -inputPitch;
+ yAxisPitch = -inputPitchIn;
+ }
+ else
+ {
+ yAxisPitch = inputPitchIn;
+ }
+ break;
+ case SurfaceRotation::Rotated90Degrees:
+ // The source image is rotated 90 degrees counter-clockwise. Y-flip is always applied
+ // to rotated images. The image is column-major. Each source column (one step along
+ // the source x-axis for each step in the dest y-axis) is inputPitch past the previous
+ // column. Along a column, each source pixel (one step along the y-axis for each step
+ // in the dest x-axis) is sourceFormat.pixelBytes past the previous pixel.
+ xAxisPitch = inputPitchIn;
+ yAxisPitch = sourceFormat.pixelBytes;
+ destWidth = params.area.height;
+ destHeight = params.area.width;
+ break;
+ case SurfaceRotation::Rotated180Degrees:
+ // The source image is rotated 180 degrees. Y-flip is always applied to rotated
+ // images. The image is row-major, but upside down. Each source row (one step along
+ // the y-axis for each step in the dest y-axis) is inputPitch after the previous row.
+ // Along a row, each source pixel (one step along the x-axis for each step in the dest
+ // x-axis) is sourceFormat.pixelBytes BEFORE the previous pixel.
+ xAxisPitch = -static_cast<int>(sourceFormat.pixelBytes);
+ yAxisPitch = inputPitchIn;
+ source += sourceFormat.pixelBytes * (params.area.width - 1);
+ break;
+ case SurfaceRotation::Rotated270Degrees:
+ // The source image is rotated 270 degrees counter-clockwise (or 90 degrees clockwise).
+ // Y-flip is always applied to rotated images. The image is column-major, where each
+ // column (one step in the source x-axis for one step in the dest y-axis) is inputPitch
+ // BEFORE the previous column. Along a column, each source pixel (one step along the
+ // y-axis for each step in the dest x-axis) is sourceFormat.pixelBytes BEFORE the
+ // previous pixel. The first pixel is at the end of the source.
+ xAxisPitch = -inputPitchIn;
+ yAxisPitch = -static_cast<int>(sourceFormat.pixelBytes);
+ destWidth = params.area.height;
+ destHeight = params.area.width;
+ source += inputPitch * (params.area.height - 1) +
+ sourceFormat.pixelBytes * (params.area.width - 1);
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ if (params.rotation == SurfaceRotation::Identity && sourceFormat == *params.destFormat)
+ {
+ // Direct copy possible
+ for (int y = 0; y < params.area.height; ++y)
+ {
+ memcpy(destWithOffset + y * params.outputPitch, source + y * inputPitch,
+ params.area.width * sourceFormat.pixelBytes);
+ }
+ return;
+ }
+
+ FastCopyFunction fastCopyFunc = sourceFormat.fastCopyFunctions.get(params.destFormat->id);
+
+ if (fastCopyFunc)
+ {
+ // Fast copy is possible through some special function
+ fastCopyFunc(source, xAxisPitch, yAxisPitch, destWithOffset, params.destFormat->pixelBytes,
+ params.outputPitch, destWidth, destHeight);
+ return;
+ }
+
+ PixelWriteFunction pixelWriteFunction = params.destFormat->pixelWriteFunction;
+ ASSERT(pixelWriteFunction != nullptr);
+
+ // Maximum size of any Color<T> type used.
+ uint8_t temp[16];
+ static_assert(sizeof(temp) >= sizeof(gl::ColorF) && sizeof(temp) >= sizeof(gl::ColorUI) &&
+ sizeof(temp) >= sizeof(gl::ColorI) &&
+ sizeof(temp) >= sizeof(angle::DepthStencil),
+ "Unexpected size of pixel struct.");
+
+ PixelReadFunction pixelReadFunction = sourceFormat.pixelReadFunction;
+ ASSERT(pixelReadFunction != nullptr);
+
+ for (int y = 0; y < destHeight; ++y)
+ {
+ for (int x = 0; x < destWidth; ++x)
+ {
+ uint8_t *dest =
+ destWithOffset + y * params.outputPitch + x * params.destFormat->pixelBytes;
+ const uint8_t *src = source + y * yAxisPitch + x * xAxisPitch;
+
+ // readFunc and writeFunc will be using the same type of color, CopyTexImage
+ // will not allow the copy otherwise.
+ pixelReadFunction(src, temp);
+ pixelWriteFunction(temp, dest);
+ }
+ }
+}
+
+bool FastCopyFunctionMap::has(angle::FormatID formatID) const
+{
+ return (get(formatID) != nullptr);
+}
+
+namespace
+{
+
+const FastCopyFunctionMap::Entry *getEntry(const FastCopyFunctionMap::Entry *entry,
+ size_t numEntries,
+ angle::FormatID formatID)
+{
+ const FastCopyFunctionMap::Entry *end = entry + numEntries;
+ while (entry != end)
+ {
+ if (entry->formatID == formatID)
+ {
+ return entry;
+ }
+ ++entry;
+ }
+
+ return nullptr;
+}
+
+} // namespace
+
+FastCopyFunction FastCopyFunctionMap::get(angle::FormatID formatID) const
+{
+ const FastCopyFunctionMap::Entry *entry = getEntry(mData, mSize, formatID);
+ return entry ? entry->func : nullptr;
+}
+
+bool ShouldUseDebugLayers(const egl::AttributeMap &attribs)
+{
+ EGLAttrib debugSetting =
+ attribs.get(EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED_ANGLE, EGL_DONT_CARE);
+
+ // Prefer to enable debug layers when available.
+#if defined(ANGLE_ENABLE_ASSERTS)
+ return (debugSetting != EGL_FALSE);
+#else
+ return (debugSetting == EGL_TRUE);
+#endif // defined(ANGLE_ENABLE_ASSERTS)
+}
+
+void CopyImageCHROMIUM(const uint8_t *sourceData,
+ size_t sourceRowPitch,
+ size_t sourcePixelBytes,
+ size_t sourceDepthPitch,
+ PixelReadFunction pixelReadFunction,
+ uint8_t *destData,
+ size_t destRowPitch,
+ size_t destPixelBytes,
+ size_t destDepthPitch,
+ PixelWriteFunction pixelWriteFunction,
+ GLenum destUnsizedFormat,
+ GLenum destComponentType,
+ size_t width,
+ size_t height,
+ size_t depth,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha)
+{
+ using ConversionFunction = void (*)(gl::ColorF *);
+ ConversionFunction conversionFunction = CopyColor;
+ if (unpackPremultiplyAlpha != unpackUnmultiplyAlpha)
+ {
+ if (unpackPremultiplyAlpha)
+ {
+ conversionFunction = PremultiplyAlpha;
+ }
+ else
+ {
+ conversionFunction = UnmultiplyAlpha;
+ }
+ }
+
+ auto clipChannelsFunction = ClipChannelsNoOp;
+ switch (destUnsizedFormat)
+ {
+ case GL_RED:
+ clipChannelsFunction = ClipChannelsR;
+ break;
+ case GL_RG:
+ clipChannelsFunction = ClipChannelsRG;
+ break;
+ case GL_RGB:
+ clipChannelsFunction = ClipChannelsRGB;
+ break;
+ case GL_LUMINANCE:
+ clipChannelsFunction = ClipChannelsLuminance;
+ break;
+ case GL_ALPHA:
+ clipChannelsFunction = ClipChannelsAlpha;
+ break;
+ }
+
+ auto writeFunction = (destComponentType == GL_UNSIGNED_INT) ? WriteUintColor : WriteFloatColor;
+
+ for (size_t z = 0; z < depth; z++)
+ {
+ for (size_t y = 0; y < height; y++)
+ {
+ for (size_t x = 0; x < width; x++)
+ {
+ const uint8_t *sourcePixelData =
+ sourceData + y * sourceRowPitch + x * sourcePixelBytes + z * sourceDepthPitch;
+
+ gl::ColorF sourceColor;
+ pixelReadFunction(sourcePixelData, reinterpret_cast<uint8_t *>(&sourceColor));
+
+ conversionFunction(&sourceColor);
+ clipChannelsFunction(&sourceColor);
+
+ size_t destY = 0;
+ if (unpackFlipY)
+ {
+ destY += (height - 1);
+ destY -= y;
+ }
+ else
+ {
+ destY += y;
+ }
+
+ uint8_t *destPixelData =
+ destData + destY * destRowPitch + x * destPixelBytes + z * destDepthPitch;
+ writeFunction(sourceColor, pixelWriteFunction, destPixelData);
+ }
+ }
+ }
+}
+
+// IncompleteTextureSet implementation.
+IncompleteTextureSet::IncompleteTextureSet() : mIncompleteTextureBufferAttachment(nullptr) {}
+
+IncompleteTextureSet::~IncompleteTextureSet() {}
+
+void IncompleteTextureSet::onDestroy(const gl::Context *context)
+{
+ // Clear incomplete textures.
+ for (auto &incompleteTextures : mIncompleteTextures)
+ {
+ for (auto &incompleteTexture : incompleteTextures)
+ {
+ if (incompleteTexture.get() != nullptr)
+ {
+ incompleteTexture->onDestroy(context);
+ incompleteTexture.set(context, nullptr);
+ }
+ }
+ }
+ if (mIncompleteTextureBufferAttachment != nullptr)
+ {
+ mIncompleteTextureBufferAttachment->onDestroy(context);
+ mIncompleteTextureBufferAttachment = nullptr;
+ }
+}
+
+angle::Result IncompleteTextureSet::getIncompleteTexture(
+ const gl::Context *context,
+ gl::TextureType type,
+ gl::SamplerFormat format,
+ MultisampleTextureInitializer *multisampleInitializer,
+ gl::Texture **textureOut)
+{
+ *textureOut = mIncompleteTextures[format][type].get();
+ if (*textureOut != nullptr)
+ {
+ return angle::Result::Continue;
+ }
+
+ ContextImpl *implFactory = context->getImplementation();
+
+ gl::Extents colorSize(1, 1, 1);
+ gl::PixelUnpackState unpack;
+ unpack.alignment = 1;
+ gl::Box area(0, 0, 0, 1, 1, 1);
+ const IncompleteTextureParameters &incompleteTextureParam =
+ kIncompleteTextureParameters[format];
+
+ // Cube map arrays are expected to have layer counts that are multiples of 6
+ constexpr int kCubeMapArraySize = 6;
+ if (type == gl::TextureType::CubeMapArray)
+ {
+ // From the GLES 3.2 spec:
+ // 8.18. IMMUTABLE-FORMAT TEXTURE IMAGES
+ // TexStorage3D Errors
+ // An INVALID_OPERATION error is generated if any of the following conditions hold:
+ // * target is TEXTURE_CUBE_MAP_ARRAY and depth is not a multiple of 6
+ // Since ANGLE treats incomplete textures as immutable, respect that here.
+ colorSize.depth = kCubeMapArraySize;
+ area.depth = kCubeMapArraySize;
+ }
+
+ // If a texture is external use a 2D texture for the incomplete texture
+ gl::TextureType createType = (type == gl::TextureType::External) ? gl::TextureType::_2D : type;
+
+ gl::Texture *tex =
+ new gl::Texture(implFactory, {std::numeric_limits<GLuint>::max()}, createType);
+ angle::UniqueObjectPointer<gl::Texture, gl::Context> t(tex, context);
+
+ // This is a bit of a kludge but is necessary to consume the error.
+ gl::Context *mutableContext = const_cast<gl::Context *>(context);
+
+ if (createType == gl::TextureType::Buffer)
+ {
+ constexpr uint32_t kBufferInitData = 0;
+ mIncompleteTextureBufferAttachment =
+ new gl::Buffer(implFactory, {std::numeric_limits<GLuint>::max()});
+ ANGLE_TRY(mIncompleteTextureBufferAttachment->bufferData(
+ mutableContext, gl::BufferBinding::Texture, &kBufferInitData, sizeof(kBufferInitData),
+ gl::BufferUsage::StaticDraw));
+ }
+ else if (createType == gl::TextureType::_2DMultisample)
+ {
+ ANGLE_TRY(t->setStorageMultisample(mutableContext, createType, 1,
+ incompleteTextureParam.sizedInternalFormat, colorSize,
+ true));
+ }
+ else
+ {
+ ANGLE_TRY(t->setStorage(mutableContext, createType, 1,
+ incompleteTextureParam.sizedInternalFormat, colorSize));
+ }
+
+ if (type == gl::TextureType::CubeMap)
+ {
+ for (gl::TextureTarget face : gl::AllCubeFaceTextureTargets())
+ {
+ ANGLE_TRY(t->setSubImage(mutableContext, unpack, nullptr, face, 0, area,
+ incompleteTextureParam.format, incompleteTextureParam.type,
+ incompleteTextureParam.clearColor));
+ }
+ }
+ else if (type == gl::TextureType::CubeMapArray)
+ {
+ // We need to provide enough pixel data to fill the array of six faces
+ GLubyte incompleteCubeArrayPixels[kCubeMapArraySize][4];
+ for (int i = 0; i < kCubeMapArraySize; ++i)
+ {
+ incompleteCubeArrayPixels[i][0] = incompleteTextureParam.clearColor[0];
+ incompleteCubeArrayPixels[i][1] = incompleteTextureParam.clearColor[1];
+ incompleteCubeArrayPixels[i][2] = incompleteTextureParam.clearColor[2];
+ incompleteCubeArrayPixels[i][3] = incompleteTextureParam.clearColor[3];
+ }
+
+ ANGLE_TRY(t->setSubImage(mutableContext, unpack, nullptr,
+ gl::NonCubeTextureTypeToTarget(createType), 0, area,
+ incompleteTextureParam.format, incompleteTextureParam.type,
+ *incompleteCubeArrayPixels));
+ }
+ else if (type == gl::TextureType::_2DMultisample)
+ {
+ // Call a specialized clear function to init a multisample texture.
+ ANGLE_TRY(multisampleInitializer->initializeMultisampleTextureToBlack(context, t.get()));
+ }
+ else if (type == gl::TextureType::Buffer)
+ {
+ ANGLE_TRY(t->setBuffer(context, mIncompleteTextureBufferAttachment,
+ incompleteTextureParam.sizedInternalFormat));
+ }
+ else
+ {
+ ANGLE_TRY(t->setSubImage(mutableContext, unpack, nullptr,
+ gl::NonCubeTextureTypeToTarget(createType), 0, area,
+ incompleteTextureParam.format, incompleteTextureParam.type,
+ incompleteTextureParam.clearColor));
+ }
+
+ if (format == gl::SamplerFormat::Shadow)
+ {
+ // To avoid the undefined spec behavior for shadow samplers with a depth texture, we set the
+ // compare mode to GL_COMPARE_REF_TO_TEXTURE
+ ASSERT(!t->hasObservers());
+ t->setCompareMode(context, GL_COMPARE_REF_TO_TEXTURE);
+ }
+
+ ANGLE_TRY(t->syncState(context, gl::Command::Other));
+
+ mIncompleteTextures[format][type].set(context, t.release());
+ *textureOut = mIncompleteTextures[format][type].get();
+ return angle::Result::Continue;
+}
+
+#define ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(api, cols, rows) \
+ template void SetFloatUniformMatrix##api<cols, rows>::Run( \
+ unsigned int, unsigned int, GLsizei, GLboolean, const GLfloat *, uint8_t *)
+
+ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(GLSL, 2, 2);
+ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(GLSL, 3, 3);
+ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(GLSL, 2, 3);
+ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(GLSL, 3, 2);
+ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(GLSL, 4, 2);
+ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(GLSL, 4, 3);
+
+ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(HLSL, 2, 2);
+ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(HLSL, 3, 3);
+ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(HLSL, 2, 3);
+ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(HLSL, 3, 2);
+ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(HLSL, 2, 4);
+ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC(HLSL, 3, 4);
+
+#undef ANGLE_INSTANTIATE_SET_UNIFORM_MATRIX_FUNC
+
+#define ANGLE_SPECIALIZATION_ROWS_SET_UNIFORM_MATRIX_FUNC(api, cols, rows) \
+ template void SetFloatUniformMatrix##api<cols, 4>::Run(unsigned int, unsigned int, GLsizei, \
+ GLboolean, const GLfloat *, uint8_t *)
+
+template <int cols>
+struct SetFloatUniformMatrixGLSL<cols, 4>
+{
+ static void Run(unsigned int arrayElementOffset,
+ unsigned int elementCount,
+ GLsizei countIn,
+ GLboolean transpose,
+ const GLfloat *value,
+ uint8_t *targetData);
+};
+
+ANGLE_SPECIALIZATION_ROWS_SET_UNIFORM_MATRIX_FUNC(GLSL, 2, 4);
+ANGLE_SPECIALIZATION_ROWS_SET_UNIFORM_MATRIX_FUNC(GLSL, 3, 4);
+ANGLE_SPECIALIZATION_ROWS_SET_UNIFORM_MATRIX_FUNC(GLSL, 4, 4);
+
+#undef ANGLE_SPECIALIZATION_ROWS_SET_UNIFORM_MATRIX_FUNC
+
+#define ANGLE_SPECIALIZATION_COLS_SET_UNIFORM_MATRIX_FUNC(api, cols, rows) \
+ template void SetFloatUniformMatrix##api<4, rows>::Run(unsigned int, unsigned int, GLsizei, \
+ GLboolean, const GLfloat *, uint8_t *)
+
+template <int rows>
+struct SetFloatUniformMatrixHLSL<4, rows>
+{
+ static void Run(unsigned int arrayElementOffset,
+ unsigned int elementCount,
+ GLsizei countIn,
+ GLboolean transpose,
+ const GLfloat *value,
+ uint8_t *targetData);
+};
+
+ANGLE_SPECIALIZATION_COLS_SET_UNIFORM_MATRIX_FUNC(HLSL, 4, 2);
+ANGLE_SPECIALIZATION_COLS_SET_UNIFORM_MATRIX_FUNC(HLSL, 4, 3);
+ANGLE_SPECIALIZATION_COLS_SET_UNIFORM_MATRIX_FUNC(HLSL, 4, 4);
+
+#undef ANGLE_SPECIALIZATION_COLS_SET_UNIFORM_MATRIX_FUNC
+
+template <int cols>
+void SetFloatUniformMatrixGLSL<cols, 4>::Run(unsigned int arrayElementOffset,
+ unsigned int elementCount,
+ GLsizei countIn,
+ GLboolean transpose,
+ const GLfloat *value,
+ uint8_t *targetData)
+{
+ const bool isSrcColumnMajor = !transpose;
+ if (isSrcColumnMajor)
+ {
+ // Both src and dst matrixs are has same layout,
+ // a single memcpy updates all the matrices
+ constexpr size_t srcMatrixSize = sizeof(GLfloat) * cols * 4;
+ SetFloatUniformMatrixFast(arrayElementOffset, elementCount, countIn, srcMatrixSize, value,
+ targetData);
+ }
+ else
+ {
+ // fallback to general cases
+ SetFloatUniformMatrix<false, cols, 4, true, cols, 4>(arrayElementOffset, elementCount,
+ countIn, value, targetData);
+ }
+}
+
+template <int cols, int rows>
+void SetFloatUniformMatrixGLSL<cols, rows>::Run(unsigned int arrayElementOffset,
+ unsigned int elementCount,
+ GLsizei countIn,
+ GLboolean transpose,
+ const GLfloat *value,
+ uint8_t *targetData)
+{
+ const bool isSrcColumnMajor = !transpose;
+ // GLSL expects matrix uniforms to be column-major, and each column is padded to 4 rows.
+ if (isSrcColumnMajor)
+ {
+ SetFloatUniformMatrix<true, cols, rows, true, cols, 4>(arrayElementOffset, elementCount,
+ countIn, value, targetData);
+ }
+ else
+ {
+ SetFloatUniformMatrix<false, cols, rows, true, cols, 4>(arrayElementOffset, elementCount,
+ countIn, value, targetData);
+ }
+}
+
+template <int rows>
+void SetFloatUniformMatrixHLSL<4, rows>::Run(unsigned int arrayElementOffset,
+ unsigned int elementCount,
+ GLsizei countIn,
+ GLboolean transpose,
+ const GLfloat *value,
+ uint8_t *targetData)
+{
+ const bool isSrcColumnMajor = !transpose;
+ if (!isSrcColumnMajor)
+ {
+ // Both src and dst matrixs are has same layout,
+ // a single memcpy updates all the matrices
+ constexpr size_t srcMatrixSize = sizeof(GLfloat) * 4 * rows;
+ SetFloatUniformMatrixFast(arrayElementOffset, elementCount, countIn, srcMatrixSize, value,
+ targetData);
+ }
+ else
+ {
+ // fallback to general cases
+ SetFloatUniformMatrix<true, 4, rows, false, 4, rows>(arrayElementOffset, elementCount,
+ countIn, value, targetData);
+ }
+}
+
+template <int cols, int rows>
+void SetFloatUniformMatrixHLSL<cols, rows>::Run(unsigned int arrayElementOffset,
+ unsigned int elementCount,
+ GLsizei countIn,
+ GLboolean transpose,
+ const GLfloat *value,
+ uint8_t *targetData)
+{
+ const bool isSrcColumnMajor = !transpose;
+ // Internally store matrices as row-major to accomodate HLSL matrix indexing. Each row is
+ // padded to 4 columns.
+ if (!isSrcColumnMajor)
+ {
+ SetFloatUniformMatrix<false, cols, rows, false, 4, rows>(arrayElementOffset, elementCount,
+ countIn, value, targetData);
+ }
+ else
+ {
+ SetFloatUniformMatrix<true, cols, rows, false, 4, rows>(arrayElementOffset, elementCount,
+ countIn, value, targetData);
+ }
+}
+
+template void GetMatrixUniform<GLint>(GLenum, GLint *, const GLint *, bool);
+template void GetMatrixUniform<GLuint>(GLenum, GLuint *, const GLuint *, bool);
+
+void GetMatrixUniform(GLenum type, GLfloat *dataOut, const GLfloat *source, bool transpose)
+{
+ int columns = gl::VariableColumnCount(type);
+ int rows = gl::VariableRowCount(type);
+ for (GLint col = 0; col < columns; ++col)
+ {
+ for (GLint row = 0; row < rows; ++row)
+ {
+ GLfloat *outptr = dataOut + ((col * rows) + row);
+ const GLfloat *inptr =
+ transpose ? source + ((row * 4) + col) : source + ((col * 4) + row);
+ *outptr = *inptr;
+ }
+ }
+}
+
+template <typename NonFloatT>
+void GetMatrixUniform(GLenum type, NonFloatT *dataOut, const NonFloatT *source, bool transpose)
+{
+ UNREACHABLE();
+}
+
+const angle::Format &GetFormatFromFormatType(GLenum format, GLenum type)
+{
+ GLenum sizedInternalFormat = gl::GetInternalFormatInfo(format, type).sizedInternalFormat;
+ angle::FormatID angleFormatID = angle::Format::InternalFormatToID(sizedInternalFormat);
+ return angle::Format::Get(angleFormatID);
+}
+
+angle::Result ComputeStartVertex(ContextImpl *contextImpl,
+ const gl::IndexRange &indexRange,
+ GLint baseVertex,
+ GLint *firstVertexOut)
+{
+ // The entire index range should be within the limits of a 32-bit uint because the largest
+ // GL index type is GL_UNSIGNED_INT.
+ ASSERT(indexRange.start <= std::numeric_limits<uint32_t>::max() &&
+ indexRange.end <= std::numeric_limits<uint32_t>::max());
+
+ // The base vertex is only used in DrawElementsIndirect. Given the assertion above and the
+ // type of mBaseVertex (GLint), adding them both as 64-bit ints is safe.
+ int64_t startVertexInt64 =
+ static_cast<int64_t>(baseVertex) + static_cast<int64_t>(indexRange.start);
+
+ // OpenGL ES 3.2 spec section 10.5: "Behavior of DrawElementsOneInstance is undefined if the
+ // vertex ID is negative for any element"
+ ANGLE_CHECK_GL_MATH(contextImpl, startVertexInt64 >= 0);
+
+ // OpenGL ES 3.2 spec section 10.5: "If the vertex ID is larger than the maximum value
+ // representable by type, it should behave as if the calculation were upconverted to 32-bit
+ // unsigned integers(with wrapping on overflow conditions)." ANGLE does not fully handle
+ // these rules, an overflow error is returned if the start vertex cannot be stored in a
+ // 32-bit signed integer.
+ ANGLE_CHECK_GL_MATH(contextImpl, startVertexInt64 <= std::numeric_limits<GLint>::max());
+
+ *firstVertexOut = static_cast<GLint>(startVertexInt64);
+ return angle::Result::Continue;
+}
+
+angle::Result GetVertexRangeInfo(const gl::Context *context,
+ GLint firstVertex,
+ GLsizei vertexOrIndexCount,
+ gl::DrawElementsType indexTypeOrInvalid,
+ const void *indices,
+ GLint baseVertex,
+ GLint *startVertexOut,
+ size_t *vertexCountOut)
+{
+ if (indexTypeOrInvalid != gl::DrawElementsType::InvalidEnum)
+ {
+ gl::IndexRange indexRange;
+ ANGLE_TRY(context->getState().getVertexArray()->getIndexRange(
+ context, indexTypeOrInvalid, vertexOrIndexCount, indices, &indexRange));
+ ANGLE_TRY(ComputeStartVertex(context->getImplementation(), indexRange, baseVertex,
+ startVertexOut));
+ *vertexCountOut = indexRange.vertexCount();
+ }
+ else
+ {
+ *startVertexOut = firstVertex;
+ *vertexCountOut = vertexOrIndexCount;
+ }
+ return angle::Result::Continue;
+}
+
+gl::Rectangle ClipRectToScissor(const gl::State &glState, const gl::Rectangle &rect, bool invertY)
+{
+ // If the scissor test isn't enabled, assume it has infinite size. Its intersection with the
+ // rect would be the rect itself.
+ //
+ // Note that on Vulkan, returning this (as opposed to a fixed max-int-sized rect) could lead to
+ // unnecessary pipeline creations if two otherwise identical pipelines are used on framebuffers
+ // with different sizes. If such usage is observed in an application, we should investigate
+ // possible optimizations.
+ if (!glState.isScissorTestEnabled())
+ {
+ return rect;
+ }
+
+ gl::Rectangle clippedRect;
+ if (!gl::ClipRectangle(glState.getScissor(), rect, &clippedRect))
+ {
+ return gl::Rectangle();
+ }
+
+ if (invertY)
+ {
+ clippedRect.y = rect.height - clippedRect.y - clippedRect.height;
+ }
+
+ return clippedRect;
+}
+
+void LogFeatureStatus(const angle::FeatureSetBase &features,
+ const std::vector<std::string> &featureNames,
+ bool enabled)
+{
+ for (const std::string &name : featureNames)
+ {
+ const bool hasWildcard = name.back() == '*';
+ for (auto iter : features.getFeatures())
+ {
+ const std::string &featureName = iter.first;
+
+ if (!angle::FeatureNameMatch(featureName, name))
+ {
+ continue;
+ }
+
+ INFO() << "Feature: " << featureName << (enabled ? " enabled" : " disabled");
+
+ if (!hasWildcard)
+ {
+ break;
+ }
+ }
+ }
+}
+
+void ApplyFeatureOverrides(angle::FeatureSetBase *features, const egl::DisplayState &state)
+{
+ features->overrideFeatures(state.featureOverridesEnabled, true);
+ features->overrideFeatures(state.featureOverridesDisabled, false);
+
+ // Override with environment as well.
+ constexpr char kAngleFeatureOverridesEnabledEnvName[] = "ANGLE_FEATURE_OVERRIDES_ENABLED";
+ constexpr char kAngleFeatureOverridesDisabledEnvName[] = "ANGLE_FEATURE_OVERRIDES_DISABLED";
+ constexpr char kAngleFeatureOverridesEnabledPropertyName[] =
+ "debug.angle.feature_overrides_enabled";
+ constexpr char kAngleFeatureOverridesDisabledPropertyName[] =
+ "debug.angle.feature_overrides_disabled";
+ std::vector<std::string> overridesEnabled =
+ angle::GetCachedStringsFromEnvironmentVarOrAndroidProperty(
+ kAngleFeatureOverridesEnabledEnvName, kAngleFeatureOverridesEnabledPropertyName, ":");
+ std::vector<std::string> overridesDisabled =
+ angle::GetCachedStringsFromEnvironmentVarOrAndroidProperty(
+ kAngleFeatureOverridesDisabledEnvName, kAngleFeatureOverridesDisabledPropertyName, ":");
+
+ features->overrideFeatures(overridesEnabled, true);
+ LogFeatureStatus(*features, overridesEnabled, true);
+
+ features->overrideFeatures(overridesDisabled, false);
+ LogFeatureStatus(*features, overridesDisabled, false);
+}
+
+void GetSamplePosition(GLsizei sampleCount, size_t index, GLfloat *xy)
+{
+ ASSERT(gl::isPow2(sampleCount));
+ if (sampleCount > 16)
+ {
+ // Vulkan (and D3D11) doesn't have standard sample positions for 32 and 64 samples (and no
+ // drivers are known to support that many samples)
+ xy[0] = 0.5f;
+ xy[1] = 0.5f;
+ }
+ else
+ {
+ size_t indexKey = static_cast<size_t>(gl::log2(sampleCount));
+ ASSERT(indexKey < kSamplePositions.size() &&
+ (2 * index + 1) < kSamplePositions[indexKey].size());
+
+ xy[0] = kSamplePositions[indexKey][2 * index];
+ xy[1] = kSamplePositions[indexKey][2 * index + 1];
+ }
+}
+
+// These macros are to avoid code too much duplication for variations of multi draw types
+#define DRAW_ARRAYS__ contextImpl->drawArrays(context, mode, firsts[drawID], counts[drawID])
+#define DRAW_ARRAYS_INSTANCED_ \
+ contextImpl->drawArraysInstanced(context, mode, firsts[drawID], counts[drawID], \
+ instanceCounts[drawID])
+#define DRAW_ELEMENTS__ \
+ contextImpl->drawElements(context, mode, counts[drawID], type, indices[drawID])
+#define DRAW_ELEMENTS_INSTANCED_ \
+ contextImpl->drawElementsInstanced(context, mode, counts[drawID], type, indices[drawID], \
+ instanceCounts[drawID])
+#define DRAW_ARRAYS_INSTANCED_BASE_INSTANCE \
+ contextImpl->drawArraysInstancedBaseInstance(context, mode, firsts[drawID], counts[drawID], \
+ instanceCounts[drawID], baseInstances[drawID])
+#define DRAW_ELEMENTS_INSTANCED_BASE_VERTEX_BASE_INSTANCE \
+ contextImpl->drawElementsInstancedBaseVertexBaseInstance( \
+ context, mode, counts[drawID], type, indices[drawID], instanceCounts[drawID], \
+ baseVertices[drawID], baseInstances[drawID])
+#define DRAW_CALL(drawType, instanced, bvbi) DRAW_##drawType##instanced##bvbi
+
+#define MULTI_DRAW_BLOCK(drawType, instanced, bvbi, hasDrawID, hasBaseVertex, hasBaseInstance) \
+ for (GLsizei drawID = 0; drawID < drawcount; ++drawID) \
+ { \
+ if (ANGLE_NOOP_DRAW(instanced)) \
+ { \
+ ANGLE_TRY(contextImpl->handleNoopDrawEvent()); \
+ continue; \
+ } \
+ ANGLE_SET_DRAW_ID_UNIFORM(hasDrawID)(drawID); \
+ ANGLE_SET_BASE_VERTEX_UNIFORM(hasBaseVertex)(baseVertices[drawID]); \
+ ANGLE_SET_BASE_INSTANCE_UNIFORM(hasBaseInstance)(baseInstances[drawID]); \
+ ANGLE_TRY(DRAW_CALL(drawType, instanced, bvbi)); \
+ ANGLE_MARK_TRANSFORM_FEEDBACK_USAGE(instanced); \
+ gl::MarkShaderStorageUsage(context); \
+ }
+
+angle::Result MultiDrawArraysGeneral(ContextImpl *contextImpl,
+ const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const GLint *firsts,
+ const GLsizei *counts,
+ GLsizei drawcount)
+{
+ gl::Program *programObject = context->getState().getLinkedProgram(context);
+ const bool hasDrawID = programObject && programObject->hasDrawIDUniform();
+ if (hasDrawID)
+ {
+ MULTI_DRAW_BLOCK(ARRAYS, _, _, 1, 0, 0)
+ }
+ else
+ {
+ MULTI_DRAW_BLOCK(ARRAYS, _, _, 0, 0, 0)
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result MultiDrawArraysIndirectGeneral(ContextImpl *contextImpl,
+ const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const void *indirect,
+ GLsizei drawcount,
+ GLsizei stride)
+{
+ const GLubyte *indirectPtr = static_cast<const GLubyte *>(indirect);
+
+ for (auto count = 0; count < drawcount; count++)
+ {
+ ANGLE_TRY(contextImpl->drawArraysIndirect(
+ context, mode, reinterpret_cast<const gl::DrawArraysIndirectCommand *>(indirectPtr)));
+ if (stride == 0)
+ {
+ indirectPtr += sizeof(gl::DrawArraysIndirectCommand);
+ }
+ else
+ {
+ indirectPtr += stride;
+ }
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result MultiDrawArraysInstancedGeneral(ContextImpl *contextImpl,
+ const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const GLint *firsts,
+ const GLsizei *counts,
+ const GLsizei *instanceCounts,
+ GLsizei drawcount)
+{
+ gl::Program *programObject = context->getState().getLinkedProgram(context);
+ const bool hasDrawID = programObject && programObject->hasDrawIDUniform();
+ if (hasDrawID)
+ {
+ MULTI_DRAW_BLOCK(ARRAYS, _INSTANCED, _, 1, 0, 0)
+ }
+ else
+ {
+ MULTI_DRAW_BLOCK(ARRAYS, _INSTANCED, _, 0, 0, 0)
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result MultiDrawElementsGeneral(ContextImpl *contextImpl,
+ const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const GLsizei *counts,
+ gl::DrawElementsType type,
+ const GLvoid *const *indices,
+ GLsizei drawcount)
+{
+ gl::Program *programObject = context->getState().getLinkedProgram(context);
+ const bool hasDrawID = programObject && programObject->hasDrawIDUniform();
+ if (hasDrawID)
+ {
+ MULTI_DRAW_BLOCK(ELEMENTS, _, _, 1, 0, 0)
+ }
+ else
+ {
+ MULTI_DRAW_BLOCK(ELEMENTS, _, _, 0, 0, 0)
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result MultiDrawElementsIndirectGeneral(ContextImpl *contextImpl,
+ const gl::Context *context,
+ gl::PrimitiveMode mode,
+ gl::DrawElementsType type,
+ const void *indirect,
+ GLsizei drawcount,
+ GLsizei stride)
+{
+ const GLubyte *indirectPtr = static_cast<const GLubyte *>(indirect);
+
+ for (auto count = 0; count < drawcount; count++)
+ {
+ ANGLE_TRY(contextImpl->drawElementsIndirect(
+ context, mode, type,
+ reinterpret_cast<const gl::DrawElementsIndirectCommand *>(indirectPtr)));
+ if (stride == 0)
+ {
+ indirectPtr += sizeof(gl::DrawElementsIndirectCommand);
+ }
+ else
+ {
+ indirectPtr += stride;
+ }
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result MultiDrawElementsInstancedGeneral(ContextImpl *contextImpl,
+ const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const GLsizei *counts,
+ gl::DrawElementsType type,
+ const GLvoid *const *indices,
+ const GLsizei *instanceCounts,
+ GLsizei drawcount)
+{
+ gl::Program *programObject = context->getState().getLinkedProgram(context);
+ const bool hasDrawID = programObject && programObject->hasDrawIDUniform();
+ if (hasDrawID)
+ {
+ MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _, 1, 0, 0)
+ }
+ else
+ {
+ MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _, 0, 0, 0)
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result MultiDrawArraysInstancedBaseInstanceGeneral(ContextImpl *contextImpl,
+ const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const GLint *firsts,
+ const GLsizei *counts,
+ const GLsizei *instanceCounts,
+ const GLuint *baseInstances,
+ GLsizei drawcount)
+{
+ gl::Program *programObject = context->getState().getLinkedProgram(context);
+ const bool hasDrawID = programObject && programObject->hasDrawIDUniform();
+ const bool hasBaseInstance = programObject && programObject->hasBaseInstanceUniform();
+ ResetBaseVertexBaseInstance resetUniforms(programObject, false, hasBaseInstance);
+
+ if (hasDrawID && hasBaseInstance)
+ {
+ MULTI_DRAW_BLOCK(ARRAYS, _INSTANCED, _BASE_INSTANCE, 1, 0, 1)
+ }
+ else if (hasDrawID)
+ {
+ MULTI_DRAW_BLOCK(ARRAYS, _INSTANCED, _BASE_INSTANCE, 1, 0, 0)
+ }
+ else if (hasBaseInstance)
+ {
+ MULTI_DRAW_BLOCK(ARRAYS, _INSTANCED, _BASE_INSTANCE, 0, 0, 1)
+ }
+ else
+ {
+ MULTI_DRAW_BLOCK(ARRAYS, _INSTANCED, _BASE_INSTANCE, 0, 0, 0)
+ }
+
+ return angle::Result::Continue;
+}
+
+angle::Result MultiDrawElementsInstancedBaseVertexBaseInstanceGeneral(ContextImpl *contextImpl,
+ const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const GLsizei *counts,
+ gl::DrawElementsType type,
+ const GLvoid *const *indices,
+ const GLsizei *instanceCounts,
+ const GLint *baseVertices,
+ const GLuint *baseInstances,
+ GLsizei drawcount)
+{
+ gl::Program *programObject = context->getState().getLinkedProgram(context);
+ const bool hasDrawID = programObject && programObject->hasDrawIDUniform();
+ const bool hasBaseVertex = programObject && programObject->hasBaseVertexUniform();
+ const bool hasBaseInstance = programObject && programObject->hasBaseInstanceUniform();
+ ResetBaseVertexBaseInstance resetUniforms(programObject, hasBaseVertex, hasBaseInstance);
+
+ if (hasDrawID)
+ {
+ if (hasBaseVertex)
+ {
+ if (hasBaseInstance)
+ {
+ MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 1, 1, 1)
+ }
+ else
+ {
+ MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 1, 1, 0)
+ }
+ }
+ else
+ {
+ if (hasBaseInstance)
+ {
+ MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 1, 0, 1)
+ }
+ else
+ {
+ MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 1, 0, 0)
+ }
+ }
+ }
+ else
+ {
+ if (hasBaseVertex)
+ {
+ if (hasBaseInstance)
+ {
+ MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 0, 1, 1)
+ }
+ else
+ {
+ MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 0, 1, 0)
+ }
+ }
+ else
+ {
+ if (hasBaseInstance)
+ {
+ MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 0, 0, 1)
+ }
+ else
+ {
+ MULTI_DRAW_BLOCK(ELEMENTS, _INSTANCED, _BASE_VERTEX_BASE_INSTANCE, 0, 0, 0)
+ }
+ }
+ }
+
+ return angle::Result::Continue;
+}
+
+ResetBaseVertexBaseInstance::ResetBaseVertexBaseInstance(gl::Program *programObject,
+ bool resetBaseVertex,
+ bool resetBaseInstance)
+ : mProgramObject(programObject),
+ mResetBaseVertex(resetBaseVertex),
+ mResetBaseInstance(resetBaseInstance)
+{}
+
+ResetBaseVertexBaseInstance::~ResetBaseVertexBaseInstance()
+{
+ if (mProgramObject)
+ {
+ // Reset emulated uniforms to zero to avoid affecting other draw calls
+ if (mResetBaseVertex)
+ {
+ mProgramObject->setBaseVertexUniform(0);
+ }
+
+ if (mResetBaseInstance)
+ {
+ mProgramObject->setBaseInstanceUniform(0);
+ }
+ }
+}
+
+angle::FormatID ConvertToSRGB(angle::FormatID formatID)
+{
+ switch (formatID)
+ {
+ case angle::FormatID::R8_UNORM:
+ return angle::FormatID::R8_UNORM_SRGB;
+ case angle::FormatID::R8G8_UNORM:
+ return angle::FormatID::R8G8_UNORM_SRGB;
+ case angle::FormatID::R8G8B8_UNORM:
+ return angle::FormatID::R8G8B8_UNORM_SRGB;
+ case angle::FormatID::R8G8B8A8_UNORM:
+ return angle::FormatID::R8G8B8A8_UNORM_SRGB;
+ case angle::FormatID::B8G8R8A8_UNORM:
+ return angle::FormatID::B8G8R8A8_UNORM_SRGB;
+ case angle::FormatID::BC1_RGB_UNORM_BLOCK:
+ return angle::FormatID::BC1_RGB_UNORM_SRGB_BLOCK;
+ case angle::FormatID::BC1_RGBA_UNORM_BLOCK:
+ return angle::FormatID::BC1_RGBA_UNORM_SRGB_BLOCK;
+ case angle::FormatID::BC2_RGBA_UNORM_BLOCK:
+ return angle::FormatID::BC2_RGBA_UNORM_SRGB_BLOCK;
+ case angle::FormatID::BC3_RGBA_UNORM_BLOCK:
+ return angle::FormatID::BC3_RGBA_UNORM_SRGB_BLOCK;
+ case angle::FormatID::BC7_RGBA_UNORM_BLOCK:
+ return angle::FormatID::BC7_RGBA_UNORM_SRGB_BLOCK;
+ case angle::FormatID::ETC2_R8G8B8_UNORM_BLOCK:
+ return angle::FormatID::ETC2_R8G8B8_SRGB_BLOCK;
+ case angle::FormatID::ETC2_R8G8B8A1_UNORM_BLOCK:
+ return angle::FormatID::ETC2_R8G8B8A1_SRGB_BLOCK;
+ case angle::FormatID::ETC2_R8G8B8A8_UNORM_BLOCK:
+ return angle::FormatID::ETC2_R8G8B8A8_SRGB_BLOCK;
+ case angle::FormatID::ASTC_4x4_UNORM_BLOCK:
+ return angle::FormatID::ASTC_4x4_SRGB_BLOCK;
+ case angle::FormatID::ASTC_5x4_UNORM_BLOCK:
+ return angle::FormatID::ASTC_5x4_SRGB_BLOCK;
+ case angle::FormatID::ASTC_5x5_UNORM_BLOCK:
+ return angle::FormatID::ASTC_5x5_SRGB_BLOCK;
+ case angle::FormatID::ASTC_6x5_UNORM_BLOCK:
+ return angle::FormatID::ASTC_6x5_SRGB_BLOCK;
+ case angle::FormatID::ASTC_6x6_UNORM_BLOCK:
+ return angle::FormatID::ASTC_6x6_SRGB_BLOCK;
+ case angle::FormatID::ASTC_8x5_UNORM_BLOCK:
+ return angle::FormatID::ASTC_8x5_SRGB_BLOCK;
+ case angle::FormatID::ASTC_8x6_UNORM_BLOCK:
+ return angle::FormatID::ASTC_8x6_SRGB_BLOCK;
+ case angle::FormatID::ASTC_8x8_UNORM_BLOCK:
+ return angle::FormatID::ASTC_8x8_SRGB_BLOCK;
+ case angle::FormatID::ASTC_10x5_UNORM_BLOCK:
+ return angle::FormatID::ASTC_10x5_SRGB_BLOCK;
+ case angle::FormatID::ASTC_10x6_UNORM_BLOCK:
+ return angle::FormatID::ASTC_10x6_SRGB_BLOCK;
+ case angle::FormatID::ASTC_10x8_UNORM_BLOCK:
+ return angle::FormatID::ASTC_10x8_SRGB_BLOCK;
+ case angle::FormatID::ASTC_10x10_UNORM_BLOCK:
+ return angle::FormatID::ASTC_10x10_SRGB_BLOCK;
+ case angle::FormatID::ASTC_12x10_UNORM_BLOCK:
+ return angle::FormatID::ASTC_12x10_SRGB_BLOCK;
+ case angle::FormatID::ASTC_12x12_UNORM_BLOCK:
+ return angle::FormatID::ASTC_12x12_SRGB_BLOCK;
+ default:
+ return angle::FormatID::NONE;
+ }
+}
+
+angle::FormatID ConvertToLinear(angle::FormatID formatID)
+{
+ switch (formatID)
+ {
+ case angle::FormatID::R8_UNORM_SRGB:
+ return angle::FormatID::R8_UNORM;
+ case angle::FormatID::R8G8_UNORM_SRGB:
+ return angle::FormatID::R8G8_UNORM;
+ case angle::FormatID::R8G8B8_UNORM_SRGB:
+ return angle::FormatID::R8G8B8_UNORM;
+ case angle::FormatID::R8G8B8A8_UNORM_SRGB:
+ return angle::FormatID::R8G8B8A8_UNORM;
+ case angle::FormatID::B8G8R8A8_UNORM_SRGB:
+ return angle::FormatID::B8G8R8A8_UNORM;
+ case angle::FormatID::BC1_RGB_UNORM_SRGB_BLOCK:
+ return angle::FormatID::BC1_RGB_UNORM_BLOCK;
+ case angle::FormatID::BC1_RGBA_UNORM_SRGB_BLOCK:
+ return angle::FormatID::BC1_RGBA_UNORM_BLOCK;
+ case angle::FormatID::BC2_RGBA_UNORM_SRGB_BLOCK:
+ return angle::FormatID::BC2_RGBA_UNORM_BLOCK;
+ case angle::FormatID::BC3_RGBA_UNORM_SRGB_BLOCK:
+ return angle::FormatID::BC3_RGBA_UNORM_BLOCK;
+ case angle::FormatID::BC7_RGBA_UNORM_SRGB_BLOCK:
+ return angle::FormatID::BC7_RGBA_UNORM_BLOCK;
+ case angle::FormatID::ETC2_R8G8B8_SRGB_BLOCK:
+ return angle::FormatID::ETC2_R8G8B8_UNORM_BLOCK;
+ case angle::FormatID::ETC2_R8G8B8A1_SRGB_BLOCK:
+ return angle::FormatID::ETC2_R8G8B8A1_UNORM_BLOCK;
+ case angle::FormatID::ETC2_R8G8B8A8_SRGB_BLOCK:
+ return angle::FormatID::ETC2_R8G8B8A8_UNORM_BLOCK;
+ case angle::FormatID::ASTC_4x4_SRGB_BLOCK:
+ return angle::FormatID::ASTC_4x4_UNORM_BLOCK;
+ case angle::FormatID::ASTC_5x4_SRGB_BLOCK:
+ return angle::FormatID::ASTC_5x4_UNORM_BLOCK;
+ case angle::FormatID::ASTC_5x5_SRGB_BLOCK:
+ return angle::FormatID::ASTC_5x5_UNORM_BLOCK;
+ case angle::FormatID::ASTC_6x5_SRGB_BLOCK:
+ return angle::FormatID::ASTC_6x5_UNORM_BLOCK;
+ case angle::FormatID::ASTC_6x6_SRGB_BLOCK:
+ return angle::FormatID::ASTC_6x6_UNORM_BLOCK;
+ case angle::FormatID::ASTC_8x5_SRGB_BLOCK:
+ return angle::FormatID::ASTC_8x5_UNORM_BLOCK;
+ case angle::FormatID::ASTC_8x6_SRGB_BLOCK:
+ return angle::FormatID::ASTC_8x6_UNORM_BLOCK;
+ case angle::FormatID::ASTC_8x8_SRGB_BLOCK:
+ return angle::FormatID::ASTC_8x8_UNORM_BLOCK;
+ case angle::FormatID::ASTC_10x5_SRGB_BLOCK:
+ return angle::FormatID::ASTC_10x5_UNORM_BLOCK;
+ case angle::FormatID::ASTC_10x6_SRGB_BLOCK:
+ return angle::FormatID::ASTC_10x6_UNORM_BLOCK;
+ case angle::FormatID::ASTC_10x8_SRGB_BLOCK:
+ return angle::FormatID::ASTC_10x8_UNORM_BLOCK;
+ case angle::FormatID::ASTC_10x10_SRGB_BLOCK:
+ return angle::FormatID::ASTC_10x10_UNORM_BLOCK;
+ case angle::FormatID::ASTC_12x10_SRGB_BLOCK:
+ return angle::FormatID::ASTC_12x10_UNORM_BLOCK;
+ case angle::FormatID::ASTC_12x12_SRGB_BLOCK:
+ return angle::FormatID::ASTC_12x12_UNORM_BLOCK;
+ default:
+ return angle::FormatID::NONE;
+ }
+}
+
+bool IsOverridableLinearFormat(angle::FormatID formatID)
+{
+ return ConvertToSRGB(formatID) != angle::FormatID::NONE;
+}
+} // namespace rx
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/renderer_utils.h b/gfx/angle/checkout/src/libANGLE/renderer/renderer_utils.h
new file mode 100644
index 0000000000..92002db56f
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/renderer_utils.h
@@ -0,0 +1,499 @@
+//
+// 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.
+//
+// renderer_utils:
+// Helper methods pertaining to most or all back-ends.
+//
+
+#ifndef LIBANGLE_RENDERER_RENDERER_UTILS_H_
+#define LIBANGLE_RENDERER_RENDERER_UTILS_H_
+
+#include <cstdint>
+
+#include <limits>
+#include <map>
+
+#include "GLSLANG/ShaderLang.h"
+#include "common/angleutils.h"
+#include "common/utilities.h"
+#include "libANGLE/angletypes.h"
+
+namespace angle
+{
+struct FeatureSetBase;
+struct Format;
+enum class FormatID;
+} // namespace angle
+
+namespace gl
+{
+struct FormatType;
+struct InternalFormat;
+class State;
+} // namespace gl
+
+namespace egl
+{
+class AttributeMap;
+struct DisplayState;
+} // namespace egl
+
+namespace rx
+{
+class ContextImpl;
+
+// The possible rotations of the surface/draw framebuffer, particularly for the Vulkan back-end on
+// Android.
+enum class SurfaceRotation
+{
+ Identity,
+ Rotated90Degrees,
+ Rotated180Degrees,
+ Rotated270Degrees,
+ FlippedIdentity,
+ FlippedRotated90Degrees,
+ FlippedRotated180Degrees,
+ FlippedRotated270Degrees,
+
+ InvalidEnum,
+ EnumCount = InvalidEnum,
+};
+
+bool IsRotatedAspectRatio(SurfaceRotation rotation);
+
+using SpecConstUsageBits = angle::PackedEnumBitSet<sh::vk::SpecConstUsage, uint32_t>;
+
+void RotateRectangle(const SurfaceRotation rotation,
+ const bool flipY,
+ const int framebufferWidth,
+ const int framebufferHeight,
+ const gl::Rectangle &incoming,
+ gl::Rectangle *outgoing);
+
+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 (*PixelReadFunction)(const uint8_t *source, uint8_t *dest);
+typedef void (*PixelWriteFunction)(const uint8_t *source, uint8_t *dest);
+typedef void (*FastCopyFunction)(const uint8_t *source,
+ int srcXAxisPitch,
+ int srcYAxisPitch,
+ uint8_t *dest,
+ int destXAxisPitch,
+ int destYAxisPitch,
+ int width,
+ int height);
+
+class FastCopyFunctionMap
+{
+ public:
+ struct Entry
+ {
+ angle::FormatID formatID;
+ FastCopyFunction func;
+ };
+
+ constexpr FastCopyFunctionMap() : FastCopyFunctionMap(nullptr, 0) {}
+
+ constexpr FastCopyFunctionMap(const Entry *data, size_t size) : mSize(size), mData(data) {}
+
+ bool has(angle::FormatID formatID) const;
+ FastCopyFunction get(angle::FormatID formatID) const;
+
+ private:
+ size_t mSize;
+ const Entry *mData;
+};
+
+struct PackPixelsParams
+{
+ PackPixelsParams();
+ PackPixelsParams(const gl::Rectangle &area,
+ const angle::Format &destFormat,
+ GLuint outputPitch,
+ bool reverseRowOrderIn,
+ gl::Buffer *packBufferIn,
+ ptrdiff_t offset);
+
+ gl::Rectangle area;
+ const angle::Format *destFormat;
+ GLuint outputPitch;
+ gl::Buffer *packBuffer;
+ bool reverseRowOrder;
+ ptrdiff_t offset;
+ SurfaceRotation rotation;
+};
+
+void PackPixels(const PackPixelsParams &params,
+ const angle::Format &sourceFormat,
+ int inputPitch,
+ const uint8_t *source,
+ uint8_t *destination);
+
+using InitializeTextureDataFunction = void (*)(size_t width,
+ size_t height,
+ size_t depth,
+ uint8_t *output,
+ size_t outputRowPitch,
+ size_t outputDepthPitch);
+
+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);
+
+bool ShouldUseDebugLayers(const egl::AttributeMap &attribs);
+
+void CopyImageCHROMIUM(const uint8_t *sourceData,
+ size_t sourceRowPitch,
+ size_t sourcePixelBytes,
+ size_t sourceDepthPitch,
+ PixelReadFunction pixelReadFunction,
+ uint8_t *destData,
+ size_t destRowPitch,
+ size_t destPixelBytes,
+ size_t destDepthPitch,
+ PixelWriteFunction pixelWriteFunction,
+ GLenum destUnsizedFormat,
+ GLenum destComponentType,
+ size_t width,
+ size_t height,
+ size_t depth,
+ bool unpackFlipY,
+ bool unpackPremultiplyAlpha,
+ bool unpackUnmultiplyAlpha);
+
+// Incomplete textures are 1x1 textures filled with black, used when samplers are incomplete.
+// This helper class encapsulates handling incomplete textures. Because the GL back-end
+// can take advantage of the driver's incomplete textures, and because clearing multisample
+// textures is so difficult, we can keep an instance of this class in the back-end instead
+// of moving the logic to the Context front-end.
+
+// This interface allows us to call-back to init a multisample texture.
+class MultisampleTextureInitializer
+{
+ public:
+ virtual ~MultisampleTextureInitializer() {}
+ virtual angle::Result initializeMultisampleTextureToBlack(const gl::Context *context,
+ gl::Texture *glTexture) = 0;
+};
+
+class IncompleteTextureSet final : angle::NonCopyable
+{
+ public:
+ IncompleteTextureSet();
+ ~IncompleteTextureSet();
+
+ void onDestroy(const gl::Context *context);
+
+ angle::Result getIncompleteTexture(const gl::Context *context,
+ gl::TextureType type,
+ gl::SamplerFormat format,
+ MultisampleTextureInitializer *multisampleInitializer,
+ gl::Texture **textureOut);
+
+ private:
+ using TextureMapWithSamplerFormat = angle::PackedEnumMap<gl::SamplerFormat, gl::TextureMap>;
+
+ TextureMapWithSamplerFormat mIncompleteTextures;
+ gl::Buffer *mIncompleteTextureBufferAttachment;
+};
+
+// Helpers to set a matrix uniform value based on GLSL or HLSL semantics.
+// The return value indicate if the data was updated or not.
+template <int cols, int rows>
+struct SetFloatUniformMatrixGLSL
+{
+ static void Run(unsigned int arrayElementOffset,
+ unsigned int elementCount,
+ GLsizei countIn,
+ GLboolean transpose,
+ const GLfloat *value,
+ uint8_t *targetData);
+};
+
+template <int cols, int rows>
+struct SetFloatUniformMatrixHLSL
+{
+ static void Run(unsigned int arrayElementOffset,
+ unsigned int elementCount,
+ GLsizei countIn,
+ GLboolean transpose,
+ const GLfloat *value,
+ uint8_t *targetData);
+};
+
+// Helper method to de-tranpose a matrix uniform for an API query.
+void GetMatrixUniform(GLenum type, GLfloat *dataOut, const GLfloat *source, bool transpose);
+
+template <typename NonFloatT>
+void GetMatrixUniform(GLenum type, NonFloatT *dataOut, const NonFloatT *source, bool transpose);
+
+const angle::Format &GetFormatFromFormatType(GLenum format, GLenum type);
+
+angle::Result ComputeStartVertex(ContextImpl *contextImpl,
+ const gl::IndexRange &indexRange,
+ GLint baseVertex,
+ GLint *firstVertexOut);
+
+angle::Result GetVertexRangeInfo(const gl::Context *context,
+ GLint firstVertex,
+ GLsizei vertexOrIndexCount,
+ gl::DrawElementsType indexTypeOrInvalid,
+ const void *indices,
+ GLint baseVertex,
+ GLint *startVertexOut,
+ size_t *vertexCountOut);
+
+gl::Rectangle ClipRectToScissor(const gl::State &glState, const gl::Rectangle &rect, bool invertY);
+
+// Helper method to intialize a FeatureSet with overrides from the DisplayState
+void ApplyFeatureOverrides(angle::FeatureSetBase *features, const egl::DisplayState &state);
+
+template <typename In>
+uint32_t LineLoopRestartIndexCountHelper(GLsizei indexCount, const uint8_t *srcPtr)
+{
+ constexpr In restartIndex = gl::GetPrimitiveRestartIndexFromType<In>();
+ const In *inIndices = reinterpret_cast<const In *>(srcPtr);
+ uint32_t numIndices = 0;
+ // See CopyLineLoopIndicesWithRestart() below for more info on how
+ // numIndices is calculated.
+ GLsizei loopStartIndex = 0;
+ for (GLsizei curIndex = 0; curIndex < indexCount; curIndex++)
+ {
+ In vertex = inIndices[curIndex];
+ if (vertex != restartIndex)
+ {
+ numIndices++;
+ }
+ else
+ {
+ if (curIndex > loopStartIndex)
+ {
+ numIndices += 2;
+ }
+ loopStartIndex = curIndex + 1;
+ }
+ }
+ if (indexCount > loopStartIndex)
+ {
+ numIndices++;
+ }
+ return numIndices;
+}
+
+inline uint32_t GetLineLoopWithRestartIndexCount(gl::DrawElementsType glIndexType,
+ GLsizei indexCount,
+ const uint8_t *srcPtr)
+{
+ switch (glIndexType)
+ {
+ case gl::DrawElementsType::UnsignedByte:
+ return LineLoopRestartIndexCountHelper<uint8_t>(indexCount, srcPtr);
+ case gl::DrawElementsType::UnsignedShort:
+ return LineLoopRestartIndexCountHelper<uint16_t>(indexCount, srcPtr);
+ case gl::DrawElementsType::UnsignedInt:
+ return LineLoopRestartIndexCountHelper<uint32_t>(indexCount, srcPtr);
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+// Writes the line-strip vertices for a line loop to outPtr,
+// where outLimit is calculated as in GetPrimitiveRestartIndexCount.
+template <typename In, typename Out>
+void CopyLineLoopIndicesWithRestart(GLsizei indexCount, const uint8_t *srcPtr, uint8_t *outPtr)
+{
+ constexpr In restartIndex = gl::GetPrimitiveRestartIndexFromType<In>();
+ constexpr Out outRestartIndex = gl::GetPrimitiveRestartIndexFromType<Out>();
+ const In *inIndices = reinterpret_cast<const In *>(srcPtr);
+ Out *outIndices = reinterpret_cast<Out *>(outPtr);
+ GLsizei loopStartIndex = 0;
+ for (GLsizei curIndex = 0; curIndex < indexCount; curIndex++)
+ {
+ In vertex = inIndices[curIndex];
+ if (vertex != restartIndex)
+ {
+ *(outIndices++) = static_cast<Out>(vertex);
+ }
+ else
+ {
+ if (curIndex > loopStartIndex)
+ {
+ // Emit an extra vertex only if the loop is not empty.
+ *(outIndices++) = inIndices[loopStartIndex];
+ // Then restart the strip.
+ *(outIndices++) = outRestartIndex;
+ }
+ loopStartIndex = curIndex + 1;
+ }
+ }
+ if (indexCount > loopStartIndex)
+ {
+ // Close the last loop if not empty.
+ *(outIndices++) = inIndices[loopStartIndex];
+ }
+}
+
+void GetSamplePosition(GLsizei sampleCount, size_t index, GLfloat *xy);
+
+angle::Result MultiDrawArraysGeneral(ContextImpl *contextImpl,
+ const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const GLint *firsts,
+ const GLsizei *counts,
+ GLsizei drawcount);
+angle::Result MultiDrawArraysIndirectGeneral(ContextImpl *contextImpl,
+ const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const void *indirect,
+ GLsizei drawcount,
+ GLsizei stride);
+angle::Result MultiDrawArraysInstancedGeneral(ContextImpl *contextImpl,
+ const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const GLint *firsts,
+ const GLsizei *counts,
+ const GLsizei *instanceCounts,
+ GLsizei drawcount);
+angle::Result MultiDrawElementsGeneral(ContextImpl *contextImpl,
+ const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const GLsizei *counts,
+ gl::DrawElementsType type,
+ const GLvoid *const *indices,
+ GLsizei drawcount);
+angle::Result MultiDrawElementsIndirectGeneral(ContextImpl *contextImpl,
+ const gl::Context *context,
+ gl::PrimitiveMode mode,
+ gl::DrawElementsType type,
+ const void *indirect,
+ GLsizei drawcount,
+ GLsizei stride);
+angle::Result MultiDrawElementsInstancedGeneral(ContextImpl *contextImpl,
+ const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const GLsizei *counts,
+ gl::DrawElementsType type,
+ const GLvoid *const *indices,
+ const GLsizei *instanceCounts,
+ GLsizei drawcount);
+angle::Result MultiDrawArraysInstancedBaseInstanceGeneral(ContextImpl *contextImpl,
+ const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const GLint *firsts,
+ const GLsizei *counts,
+ const GLsizei *instanceCounts,
+ const GLuint *baseInstances,
+ GLsizei drawcount);
+angle::Result MultiDrawElementsInstancedBaseVertexBaseInstanceGeneral(ContextImpl *contextImpl,
+ const gl::Context *context,
+ gl::PrimitiveMode mode,
+ const GLsizei *counts,
+ gl::DrawElementsType type,
+ const GLvoid *const *indices,
+ const GLsizei *instanceCounts,
+ const GLint *baseVertices,
+ const GLuint *baseInstances,
+ GLsizei drawcount);
+
+// RAII object making sure reset uniforms is called no matter whether there's an error in draw calls
+class ResetBaseVertexBaseInstance : angle::NonCopyable
+{
+ public:
+ ResetBaseVertexBaseInstance(gl::Program *programObject,
+ bool resetBaseVertex,
+ bool resetBaseInstance);
+
+ ~ResetBaseVertexBaseInstance();
+
+ private:
+ gl::Program *mProgramObject;
+ bool mResetBaseVertex;
+ bool mResetBaseInstance;
+};
+
+angle::FormatID ConvertToSRGB(angle::FormatID formatID);
+angle::FormatID ConvertToLinear(angle::FormatID formatID);
+bool IsOverridableLinearFormat(angle::FormatID formatID);
+
+enum class PipelineType
+{
+ Graphics = 0,
+ Compute = 1,
+
+ InvalidEnum = 2,
+ EnumCount = 2,
+};
+} // namespace rx
+
+// MultiDraw macro patterns
+// These macros are to avoid too much code duplication as we don't want to have if detect for
+// hasDrawID/BaseVertex/BaseInstance inside for loop in a multiDrawANGLE call Part of these are put
+// in the header as we want to share with specialized context impl on some platforms for multidraw
+#define ANGLE_SET_DRAW_ID_UNIFORM_0(drawID) \
+ {}
+#define ANGLE_SET_DRAW_ID_UNIFORM_1(drawID) programObject->setDrawIDUniform(drawID)
+#define ANGLE_SET_DRAW_ID_UNIFORM(cond) ANGLE_SET_DRAW_ID_UNIFORM_##cond
+
+#define ANGLE_SET_BASE_VERTEX_UNIFORM_0(baseVertex) \
+ {}
+#define ANGLE_SET_BASE_VERTEX_UNIFORM_1(baseVertex) programObject->setBaseVertexUniform(baseVertex);
+#define ANGLE_SET_BASE_VERTEX_UNIFORM(cond) ANGLE_SET_BASE_VERTEX_UNIFORM_##cond
+
+#define ANGLE_SET_BASE_INSTANCE_UNIFORM_0(baseInstance) \
+ {}
+#define ANGLE_SET_BASE_INSTANCE_UNIFORM_1(baseInstance) \
+ programObject->setBaseInstanceUniform(baseInstance)
+#define ANGLE_SET_BASE_INSTANCE_UNIFORM(cond) ANGLE_SET_BASE_INSTANCE_UNIFORM_##cond
+
+#define ANGLE_NOOP_DRAW_ context->noopDraw(mode, counts[drawID])
+#define ANGLE_NOOP_DRAW_INSTANCED \
+ context->noopDrawInstanced(mode, counts[drawID], instanceCounts[drawID])
+#define ANGLE_NOOP_DRAW(_instanced) ANGLE_NOOP_DRAW##_instanced
+
+#define ANGLE_MARK_TRANSFORM_FEEDBACK_USAGE_ \
+ gl::MarkTransformFeedbackBufferUsage(context, counts[drawID], 1)
+#define ANGLE_MARK_TRANSFORM_FEEDBACK_USAGE_INSTANCED \
+ gl::MarkTransformFeedbackBufferUsage(context, counts[drawID], instanceCounts[drawID])
+#define ANGLE_MARK_TRANSFORM_FEEDBACK_USAGE(instanced) \
+ ANGLE_MARK_TRANSFORM_FEEDBACK_USAGE##instanced
+
+// Helper macro that casts to a bitfield type then verifies no bits were dropped.
+#define SetBitField(lhs, rhs) \
+ do \
+ { \
+ auto ANGLE_LOCAL_VAR = rhs; \
+ lhs = static_cast<typename std::decay<decltype(lhs)>::type>(ANGLE_LOCAL_VAR); \
+ ASSERT(static_cast<decltype(ANGLE_LOCAL_VAR)>(lhs) == ANGLE_LOCAL_VAR); \
+ } while (0)
+
+#endif // LIBANGLE_RENDERER_RENDERER_UTILS_H_
diff --git a/gfx/angle/checkout/src/libANGLE/renderer/serial_utils.h b/gfx/angle/checkout/src/libANGLE/renderer/serial_utils.h
new file mode 100644
index 0000000000..49a65c4e26
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/renderer/serial_utils.h
@@ -0,0 +1,126 @@
+//
+// Copyright 2019 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.
+//
+// serial_utils:
+// Utilities for generating unique IDs for resources in ANGLE.
+//
+
+#ifndef LIBANGLE_RENDERER_SERIAL_UTILS_H_
+#define LIBANGLE_RENDERER_SERIAL_UTILS_H_
+
+#include <atomic>
+#include <limits>
+
+#include "common/angleutils.h"
+#include "common/debug.h"
+
+namespace rx
+{
+class ResourceSerial
+{
+ public:
+ constexpr ResourceSerial() : mValue(kDirty) {}
+ explicit constexpr ResourceSerial(uintptr_t value) : mValue(value) {}
+ constexpr bool operator==(ResourceSerial other) const { return mValue == other.mValue; }
+ constexpr bool operator!=(ResourceSerial other) const { return mValue != other.mValue; }
+
+ void dirty() { mValue = kDirty; }
+ void clear() { mValue = kEmpty; }
+
+ constexpr bool valid() const { return mValue != kEmpty && mValue != kDirty; }
+ constexpr bool empty() const { return mValue == kEmpty; }
+
+ private:
+ constexpr static uintptr_t kDirty = std::numeric_limits<uintptr_t>::max();
+ constexpr static uintptr_t kEmpty = 0;
+
+ uintptr_t mValue;
+};
+
+class Serial final
+{
+ public:
+ constexpr Serial() : mValue(kInvalid) {}
+ constexpr Serial(const Serial &other) = default;
+ Serial &operator=(const Serial &other) = default;
+
+ static constexpr Serial Infinite() { return Serial(std::numeric_limits<uint64_t>::max()); }
+
+ constexpr bool operator==(const Serial &other) const
+ {
+ return mValue != kInvalid && mValue == other.mValue;
+ }
+ constexpr bool operator==(uint32_t value) const
+ {
+ return mValue != kInvalid && mValue == static_cast<uint64_t>(value);
+ }
+ constexpr bool operator!=(const Serial &other) const
+ {
+ return mValue == kInvalid || mValue != other.mValue;
+ }
+ constexpr bool operator>(const Serial &other) const { return mValue > other.mValue; }
+ constexpr bool operator>=(const Serial &other) const { return mValue >= other.mValue; }
+ constexpr bool operator<(const Serial &other) const { return mValue < other.mValue; }
+ constexpr bool operator<=(const Serial &other) const { return mValue <= other.mValue; }
+
+ constexpr bool operator<(uint32_t value) const { return mValue < static_cast<uint64_t>(value); }
+
+ // Useful for serialization.
+ constexpr uint64_t getValue() const { return mValue; }
+ constexpr bool valid() const { return mValue != kInvalid; }
+
+ private:
+ template <typename T>
+ friend class SerialFactoryBase;
+ friend class AtomicQueueSerial;
+ constexpr explicit Serial(uint64_t value) : mValue(value) {}
+ uint64_t mValue;
+ static constexpr uint64_t kInvalid = 0;
+};
+
+// Defines class to track the queue serial that can be load/store from multiple threads atomically.
+class AtomicQueueSerial final
+{
+ public:
+ constexpr AtomicQueueSerial() : mValue(kInvalid) { ASSERT(mValue.is_lock_free()); }
+ AtomicQueueSerial &operator=(const Serial &other)
+ {
+ mValue.store(other.mValue, std::memory_order_release);
+ return *this;
+ }
+ Serial getSerial() const { return Serial(mValue.load(std::memory_order_consume)); }
+
+ private:
+ std::atomic<uint64_t> mValue;
+ static constexpr uint64_t kInvalid = 0;
+};
+
+// Used as default/initial serial
+static constexpr Serial kZeroSerial = Serial();
+
+template <typename SerialBaseType>
+class SerialFactoryBase final : angle::NonCopyable
+{
+ public:
+ SerialFactoryBase() : mSerial(1) {}
+
+ Serial generate()
+ {
+ uint64_t current = mSerial++;
+ ASSERT(mSerial > current); // Integer overflow
+ return Serial(current);
+ }
+
+ private:
+ SerialBaseType mSerial;
+};
+
+using SerialFactory = SerialFactoryBase<uint64_t>;
+using AtomicSerialFactory = SerialFactoryBase<std::atomic<uint64_t>>;
+using RenderPassSerialFactory = SerialFactoryBase<uint64_t>;
+
+} // namespace rx
+
+#endif // LIBANGLE_RENDERER_SERIAL_UTILS_H_
diff --git a/gfx/angle/checkout/src/libANGLE/trace.h b/gfx/angle/checkout/src/libANGLE/trace.h
new file mode 100644
index 0000000000..fc8d40c646
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/trace.h
@@ -0,0 +1,26 @@
+//
+// Copyright 2019 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.
+//
+// trace.h: Wrappers for ANGLE trace event functions.
+//
+
+#ifndef LIBANGLE_TRACE_H_
+#define LIBANGLE_TRACE_H_
+
+#include <platform/PlatformMethods.h>
+#include "third_party/trace_event/trace_event.h"
+
+// TODO: Pass platform directly to these methods. http://anglebug.com/1892
+#define ANGLE_TRACE_EVENT_BEGIN0(CATEGORY, EVENT) \
+ TRACE_EVENT_BEGIN0(ANGLEPlatformCurrent(), CATEGORY, EVENT)
+#define ANGLE_TRACE_EVENT_END0(CATEGORY, EVENT) \
+ TRACE_EVENT_END0(ANGLEPlatformCurrent(), CATEGORY, EVENT)
+#define ANGLE_TRACE_EVENT_INSTANT0(CATEGORY, EVENT) \
+ TRACE_EVENT_INSTANT0(ANGLEPlatformCurrent(), CATEGORY, EVENT)
+#define ANGLE_TRACE_EVENT0(CATEGORY, EVENT) TRACE_EVENT0(ANGLEPlatformCurrent(), CATEGORY, EVENT)
+#define ANGLE_TRACE_EVENT1(CATEGORY, EVENT, NAME, PARAM) \
+ TRACE_EVENT1(ANGLEPlatformCurrent(), CATEGORY, EVENT, NAME, PARAM)
+
+#endif // LIBANGLE_TRACE_H_
diff --git a/gfx/angle/checkout/src/libANGLE/validationEGL.cpp b/gfx/angle/checkout/src/libANGLE/validationEGL.cpp
new file mode 100644
index 0000000000..e73535ab5c
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/validationEGL.cpp
@@ -0,0 +1,6782 @@
+//
+// 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.
+//
+
+// validationEGL.cpp: Validation functions for generic EGL entry point parameters
+
+#include "libANGLE/validationEGL_autogen.h"
+
+#include "common/utilities.h"
+#include "libANGLE/Config.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Device.h"
+#include "libANGLE/Display.h"
+#include "libANGLE/EGLSync.h"
+#include "libANGLE/Image.h"
+#include "libANGLE/Stream.h"
+#include "libANGLE/Surface.h"
+#include "libANGLE/Texture.h"
+#include "libANGLE/Thread.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/DisplayImpl.h"
+
+#include <EGL/eglext.h>
+
+namespace egl
+{
+namespace
+{
+size_t GetMaximumMipLevel(const gl::Context *context, gl::TextureType type)
+{
+ const gl::Caps &caps = context->getCaps();
+
+ int maxDimension = 0;
+ switch (type)
+ {
+ case gl::TextureType::_2D:
+ case gl::TextureType::_2DArray:
+ case gl::TextureType::_2DMultisample:
+ maxDimension = caps.max2DTextureSize;
+ break;
+ case gl::TextureType::Rectangle:
+ maxDimension = caps.maxRectangleTextureSize;
+ break;
+ case gl::TextureType::CubeMap:
+ maxDimension = caps.maxCubeMapTextureSize;
+ break;
+ case gl::TextureType::_3D:
+ maxDimension = caps.max3DTextureSize;
+ break;
+
+ default:
+ UNREACHABLE();
+ }
+
+ return gl::log2(maxDimension);
+}
+
+bool TextureHasNonZeroMipLevelsSpecified(const gl::Context *context, const gl::Texture *texture)
+{
+ size_t maxMip = GetMaximumMipLevel(context, texture->getType());
+ for (size_t level = 1; level < maxMip; level++)
+ {
+ if (texture->getType() == gl::TextureType::CubeMap)
+ {
+ for (gl::TextureTarget face : gl::AllCubeFaceTextureTargets())
+ {
+ if (texture->getFormat(face, level).valid())
+ {
+ return true;
+ }
+ }
+ }
+ else
+ {
+ if (texture->getFormat(gl::NonCubeTextureTypeToTarget(texture->getType()), level)
+ .valid())
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+bool CubeTextureHasUnspecifiedLevel0Face(const gl::Texture *texture)
+{
+ ASSERT(texture->getType() == gl::TextureType::CubeMap);
+ for (gl::TextureTarget face : gl::AllCubeFaceTextureTargets())
+ {
+ if (!texture->getFormat(face, 0).valid())
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool ValidateStreamAttribute(const ValidationContext *val,
+ const EGLAttrib attribute,
+ const EGLAttrib value,
+ const DisplayExtensions &extensions)
+{
+ switch (attribute)
+ {
+ case EGL_STREAM_STATE_KHR:
+ case EGL_PRODUCER_FRAME_KHR:
+ case EGL_CONSUMER_FRAME_KHR:
+ val->setError(EGL_BAD_ACCESS, "Attempt to initialize readonly parameter");
+ return false;
+ case EGL_CONSUMER_LATENCY_USEC_KHR:
+ // Technically not in spec but a latency < 0 makes no sense so we check it
+ if (value < 0)
+ {
+ val->setError(EGL_BAD_PARAMETER, "Latency must be positive");
+ return false;
+ }
+ break;
+ case EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR:
+ if (!extensions.streamConsumerGLTexture)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE, "Consumer GL extension not enabled");
+ return false;
+ }
+ // Again not in spec but it should be positive anyways
+ if (value < 0)
+ {
+ val->setError(EGL_BAD_PARAMETER, "Timeout must be positive");
+ return false;
+ }
+ break;
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE, "Invalid stream attribute");
+ return false;
+ }
+ return true;
+}
+
+bool ValidateCreateImageMipLevelCommon(const ValidationContext *val,
+ const gl::Context *context,
+ const gl::Texture *texture,
+ EGLAttrib level)
+{
+ // Note that the spec EGL_create_image spec does not explicitly specify an error
+ // when the level is outside the base/max level range, but it does mention that the
+ // level "must be a part of the complete texture object <buffer>". It can be argued
+ // that out-of-range levels are not a part of the complete texture.
+ const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
+ if (level > 0 &&
+ (!texture->isMipmapComplete() || static_cast<GLuint>(level) < effectiveBaseLevel ||
+ static_cast<GLuint>(level) > texture->getTextureState().getMipmapMaxLevel()))
+ {
+ val->setError(EGL_BAD_PARAMETER, "texture must be complete if level is non-zero.");
+ return false;
+ }
+
+ if (level == 0 && !texture->isMipmapComplete() &&
+ TextureHasNonZeroMipLevelsSpecified(context, texture))
+ {
+ val->setError(EGL_BAD_PARAMETER,
+ "if level is zero and the texture is incomplete, it must "
+ "have no mip levels specified except zero.");
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateConfigAttribute(const ValidationContext *val,
+ const Display *display,
+ EGLAttrib attribute)
+{
+ switch (attribute)
+ {
+ case EGL_BUFFER_SIZE:
+ case EGL_ALPHA_SIZE:
+ case EGL_BLUE_SIZE:
+ case EGL_GREEN_SIZE:
+ case EGL_RED_SIZE:
+ case EGL_DEPTH_SIZE:
+ case EGL_STENCIL_SIZE:
+ case EGL_CONFIG_CAVEAT:
+ case EGL_CONFIG_ID:
+ case EGL_LEVEL:
+ case EGL_NATIVE_RENDERABLE:
+ case EGL_NATIVE_VISUAL_ID:
+ case EGL_NATIVE_VISUAL_TYPE:
+ case EGL_SAMPLES:
+ case EGL_SAMPLE_BUFFERS:
+ case EGL_SURFACE_TYPE:
+ case EGL_TRANSPARENT_TYPE:
+ case EGL_TRANSPARENT_BLUE_VALUE:
+ case EGL_TRANSPARENT_GREEN_VALUE:
+ case EGL_TRANSPARENT_RED_VALUE:
+ case EGL_BIND_TO_TEXTURE_RGB:
+ case EGL_BIND_TO_TEXTURE_RGBA:
+ case EGL_MIN_SWAP_INTERVAL:
+ case EGL_MAX_SWAP_INTERVAL:
+ case EGL_LUMINANCE_SIZE:
+ case EGL_ALPHA_MASK_SIZE:
+ case EGL_COLOR_BUFFER_TYPE:
+ case EGL_RENDERABLE_TYPE:
+ case EGL_MATCH_NATIVE_PIXMAP:
+ case EGL_CONFORMANT:
+ case EGL_MAX_PBUFFER_WIDTH:
+ case EGL_MAX_PBUFFER_HEIGHT:
+ case EGL_MAX_PBUFFER_PIXELS:
+ break;
+
+ case EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE:
+ if (!display->getExtensions().surfaceOrientation)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE, "EGL_ANGLE_surface_orientation is not enabled.");
+ return false;
+ }
+ break;
+
+ case EGL_COLOR_COMPONENT_TYPE_EXT:
+ if (!display->getExtensions().pixelFormatFloat)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE, "EGL_EXT_pixel_format_float is not enabled.");
+ return false;
+ }
+ break;
+
+ case EGL_RECORDABLE_ANDROID:
+ if (!display->getExtensions().recordable)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE, "EGL_ANDROID_recordable is not enabled.");
+ return false;
+ }
+ break;
+
+ case EGL_FRAMEBUFFER_TARGET_ANDROID:
+ if (!display->getExtensions().framebufferTargetANDROID)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE, "EGL_ANDROID_framebuffer_target is not enabled.");
+ return false;
+ }
+ break;
+
+ case EGL_BIND_TO_TEXTURE_TARGET_ANGLE:
+ if (!display->getExtensions().iosurfaceClientBuffer)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_ANGLE_iosurface_client_buffer is not enabled.");
+ return false;
+ }
+ break;
+
+ case EGL_Y_INVERTED_NOK:
+ if (!display->getExtensions().textureFromPixmapNOK)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE, "EGL_NOK_texture_from_pixmap is not enabled.");
+ return false;
+ }
+ break;
+
+ case EGL_MATCH_FORMAT_KHR:
+ if (!display->getExtensions().lockSurface3KHR)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE, "EGL_KHR_lock_surface3 is not enabled.");
+ return false;
+ }
+ break;
+
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE, "Unknown attribute: 0x%04" PRIxPTR "X", attribute);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateConfigAttributeValue(const ValidationContext *val,
+ const Display *display,
+ EGLAttrib attribute,
+ EGLAttrib value)
+{
+ switch (attribute)
+ {
+
+ case EGL_BIND_TO_TEXTURE_RGB:
+ case EGL_BIND_TO_TEXTURE_RGBA:
+ switch (value)
+ {
+ case EGL_DONT_CARE:
+ case EGL_TRUE:
+ case EGL_FALSE:
+ break;
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE, "EGL_bind_to_texture invalid attribute: 0x%X",
+ static_cast<uint32_t>(value));
+ return false;
+ }
+ break;
+
+ case EGL_COLOR_BUFFER_TYPE:
+ switch (value)
+ {
+ case EGL_RGB_BUFFER:
+ case EGL_LUMINANCE_BUFFER:
+ // EGL_DONT_CARE doesn't match the spec, but does match dEQP usage
+ case EGL_DONT_CARE:
+ break;
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_color_buffer_type invalid attribute: 0x%X",
+ static_cast<uint32_t>(value));
+ return false;
+ }
+ break;
+
+ case EGL_NATIVE_RENDERABLE:
+ switch (value)
+ {
+ case EGL_DONT_CARE:
+ case EGL_TRUE:
+ case EGL_FALSE:
+ break;
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_native_renderable invalid attribute: 0x%X",
+ static_cast<uint32_t>(value));
+ return false;
+ }
+ break;
+
+ case EGL_TRANSPARENT_TYPE:
+ switch (value)
+ {
+ case EGL_NONE:
+ case EGL_TRANSPARENT_RGB:
+ // EGL_DONT_CARE doesn't match the spec, but does match dEQP usage
+ case EGL_DONT_CARE:
+ break;
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE, "EGL_transparent_type invalid attribute: 0x%X",
+ static_cast<uint32_t>(value));
+ return false;
+ }
+ break;
+
+ case EGL_RECORDABLE_ANDROID:
+ switch (value)
+ {
+ case EGL_TRUE:
+ case EGL_FALSE:
+ case EGL_DONT_CARE:
+ break;
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_RECORDABLE_ANDROID invalid attribute: 0x%X",
+ static_cast<uint32_t>(value));
+ return false;
+ }
+ break;
+
+ case EGL_COLOR_COMPONENT_TYPE_EXT:
+ switch (value)
+ {
+ case EGL_COLOR_COMPONENT_TYPE_FIXED_EXT:
+ case EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT:
+ case EGL_DONT_CARE:
+ break;
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_COLOR_COMPONENT_TYPE_EXT invalid attribute: 0x%X",
+ static_cast<uint32_t>(value));
+ return false;
+ }
+ break;
+
+ case EGL_MATCH_FORMAT_KHR:
+ switch (value)
+ {
+ case EGL_FORMAT_RGB_565_KHR:
+ case EGL_FORMAT_RGBA_8888_KHR:
+ case EGL_FORMAT_RGB_565_EXACT_KHR:
+ case EGL_FORMAT_RGBA_8888_EXACT_KHR:
+ break;
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_KHR_lock_surface3 invalid attribute: 0x%X",
+ static_cast<uint32_t>(value));
+ return false;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return true;
+}
+
+bool ValidateConfigAttributes(const ValidationContext *val,
+ const Display *display,
+ const AttributeMap &attributes)
+{
+ ANGLE_VALIDATION_TRY(attributes.validate(val, display, ValidateConfigAttribute));
+
+ for (const auto &attrib : attributes)
+ {
+ EGLAttrib pname = attrib.first;
+ EGLAttrib value = attrib.second;
+ ANGLE_VALIDATION_TRY(ValidateConfigAttributeValue(val, display, pname, value));
+ }
+
+ return true;
+}
+
+bool ValidateColorspaceAttribute(const ValidationContext *val,
+ const DisplayExtensions &displayExtensions,
+ EGLAttrib colorSpace)
+{
+ switch (colorSpace)
+ {
+ case EGL_GL_COLORSPACE_SRGB:
+ break;
+ case EGL_GL_COLORSPACE_LINEAR:
+ break;
+ case EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT:
+ if (!displayExtensions.glColorspaceDisplayP3Linear &&
+ !displayExtensions.eglColorspaceAttributePassthroughANGLE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EXT_gl_colorspace_display_p3_linear is not available.");
+ return false;
+ }
+ break;
+ case EGL_GL_COLORSPACE_DISPLAY_P3_EXT:
+ if (!displayExtensions.glColorspaceDisplayP3 &&
+ !displayExtensions.eglColorspaceAttributePassthroughANGLE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE, "EXT_gl_colorspace_display_p3 is not available.");
+ return false;
+ }
+ break;
+ case EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT:
+ if (!displayExtensions.glColorspaceDisplayP3Passthrough &&
+ !displayExtensions.eglColorspaceAttributePassthroughANGLE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_EXT_gl_colorspace_display_p3_passthrough is not available.");
+ return false;
+ }
+ break;
+ case EGL_GL_COLORSPACE_SCRGB_EXT:
+ if (!displayExtensions.glColorspaceScrgb &&
+ !displayExtensions.eglColorspaceAttributePassthroughANGLE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE, "EXT_gl_colorspace_scrgb is not available.");
+ return false;
+ }
+ break;
+ case EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT:
+ if (!displayExtensions.glColorspaceScrgbLinear &&
+ !displayExtensions.eglColorspaceAttributePassthroughANGLE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EXT_gl_colorspace_scrgb_linear is not available.");
+ return false;
+ }
+ break;
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE);
+ return false;
+ }
+ return true;
+}
+bool ValidatePlatformType(const ValidationContext *val,
+ const ClientExtensions &clientExtensions,
+ EGLAttrib platformType)
+{
+ switch (platformType)
+ {
+ case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE:
+ break;
+
+ case EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE:
+ case EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE:
+ if (!clientExtensions.platformANGLED3D)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE, "Direct3D platform is unsupported.");
+ return false;
+ }
+ break;
+
+ case EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE:
+ case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE:
+ if (!clientExtensions.platformANGLEOpenGL)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE, "OpenGL platform is unsupported.");
+ return false;
+ }
+ break;
+
+ case EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE:
+ if (!clientExtensions.platformANGLENULL)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "Display type EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE "
+ "requires EGL_ANGLE_platform_angle_null.");
+ return false;
+ }
+ break;
+
+ case EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE:
+ if (!clientExtensions.platformANGLEVulkan)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE, "Vulkan platform is unsupported.");
+ return false;
+ }
+ break;
+
+ case EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE:
+ if (!clientExtensions.platformANGLEMetal)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE, "Metal platform is unsupported.");
+ return false;
+ }
+ break;
+
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE, "Unknown platform type.");
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetPlatformDisplayCommon(const ValidationContext *val,
+ EGLenum platform,
+ const void *native_display,
+ const AttributeMap &attribMap)
+{
+ const ClientExtensions &clientExtensions = Display::GetClientExtensions();
+
+ switch (platform)
+ {
+ case EGL_PLATFORM_ANGLE_ANGLE:
+ if (!clientExtensions.platformANGLE)
+ {
+ val->setError(EGL_BAD_PARAMETER, "Platform ANGLE extension is not active");
+ return false;
+ }
+ break;
+ case EGL_PLATFORM_DEVICE_EXT:
+ if (!clientExtensions.platformDevice)
+ {
+ val->setError(EGL_BAD_PARAMETER, "Platform Device extension is not active");
+ return false;
+ }
+ break;
+ case EGL_PLATFORM_GBM_KHR:
+ if (!clientExtensions.platformGbmKHR)
+ {
+ val->setError(EGL_BAD_PARAMETER, "Platform GBM extension is not active");
+ return false;
+ }
+ break;
+ case EGL_PLATFORM_WAYLAND_EXT:
+ if (!clientExtensions.platformWaylandEXT)
+ {
+ val->setError(EGL_BAD_PARAMETER, "Platform Wayland extension is not active");
+ return false;
+ }
+ break;
+ default:
+ val->setError(EGL_BAD_CONFIG, "Bad platform type.");
+ return false;
+ }
+
+ attribMap.initializeWithoutValidation();
+
+ if (platform != EGL_PLATFORM_DEVICE_EXT)
+ {
+ EGLAttrib platformType = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE;
+ bool enableAutoTrimSpecified = false;
+ bool enableD3D11on12 = false;
+ bool presentPathSpecified = false;
+ bool luidSpecified = false;
+ bool deviceIdSpecified = false;
+
+ Optional<EGLAttrib> majorVersion;
+ Optional<EGLAttrib> minorVersion;
+ Optional<EGLAttrib> deviceType;
+ Optional<EGLAttrib> eglHandle;
+
+ for (const auto &curAttrib : attribMap)
+ {
+ const EGLAttrib value = curAttrib.second;
+
+ switch (curAttrib.first)
+ {
+ case EGL_PLATFORM_ANGLE_TYPE_ANGLE:
+ {
+ ANGLE_VALIDATION_TRY(ValidatePlatformType(val, clientExtensions, value));
+ platformType = value;
+ break;
+ }
+
+ case EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE:
+ if (value != EGL_DONT_CARE)
+ {
+ majorVersion = value;
+ }
+ break;
+
+ case EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE:
+ if (value != EGL_DONT_CARE)
+ {
+ minorVersion = value;
+ }
+ break;
+
+ case EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE:
+ switch (value)
+ {
+ case EGL_TRUE:
+ case EGL_FALSE:
+ break;
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE, "Invalid automatic trim attribute");
+ return false;
+ }
+ enableAutoTrimSpecified = true;
+ break;
+
+ case EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE:
+ if (!clientExtensions.platformANGLED3D ||
+ !clientExtensions.platformANGLED3D11ON12)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE extension not active.");
+ return false;
+ }
+
+ switch (value)
+ {
+ case EGL_TRUE:
+ case EGL_FALSE:
+ break;
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE, "Invalid D3D11on12 attribute");
+ return false;
+ }
+ enableD3D11on12 = true;
+ break;
+
+ case EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE:
+ if (!clientExtensions.experimentalPresentPath)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_ANGLE_experimental_present_path extension not active");
+ return false;
+ }
+
+ switch (value)
+ {
+ case EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE:
+ case EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE:
+ break;
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "Invalid value for EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE");
+ return false;
+ }
+ presentPathSpecified = true;
+ break;
+
+ case EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE:
+ switch (value)
+ {
+ case EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE:
+ case EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE:
+ break;
+
+ case EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE:
+ case EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_REFERENCE_ANGLE:
+ if (!clientExtensions.platformANGLED3D)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_ANGLE_platform_angle_d3d is not supported");
+ return false;
+ }
+ break;
+
+ case EGL_PLATFORM_ANGLE_DEVICE_TYPE_EGL_ANGLE:
+ if (!clientExtensions.platformANGLEDeviceTypeEGLANGLE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_ANGLE_platform_angle_device_type_"
+ "egl_angle is not supported");
+ return false;
+ }
+ break;
+
+ case EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE:
+ if (!clientExtensions.platformANGLEDeviceTypeSwiftShader)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_ANGLE_platform_angle_device_type_"
+ "swiftshader is not supported");
+ return false;
+ }
+ break;
+
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "Invalid value for "
+ "EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE "
+ "attrib");
+ return false;
+ }
+ deviceType = value;
+ break;
+
+ case EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED_ANGLE:
+ if (!clientExtensions.platformANGLE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_ANGLE_platform_angle extension not active");
+ return false;
+ }
+ if (value != EGL_TRUE && value != EGL_FALSE && value != EGL_DONT_CARE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED_ANGLE "
+ "must be EGL_TRUE, EGL_FALSE, or "
+ "EGL_DONT_CARE.");
+ return false;
+ }
+ break;
+
+ case EGL_PLATFORM_ANGLE_EGL_HANDLE_ANGLE:
+ if (value != EGL_DONT_CARE)
+ {
+ eglHandle = value;
+ }
+ break;
+
+ case EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE:
+ case EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE:
+ luidSpecified = true;
+ break;
+ case EGL_PLATFORM_ANGLE_DEVICE_CONTEXT_VOLATILE_EAGL_ANGLE:
+ // The property does not have an effect if it's not active, so do not check
+ // for non-support.
+ switch (value)
+ {
+ case EGL_FALSE:
+ case EGL_TRUE:
+ break;
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "Invalid value for "
+ "EGL_PLATFORM_ANGLE_DEVICE_CONTEXT_VOLATILE_"
+ "EAGL_ANGLE attrib");
+ return false;
+ }
+ break;
+ case EGL_PLATFORM_ANGLE_DEVICE_CONTEXT_VOLATILE_CGL_ANGLE:
+ // The property does not have an effect if it's not active, so do not check
+ // for non-support.
+ switch (value)
+ {
+ case EGL_FALSE:
+ case EGL_TRUE:
+ break;
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "Invalid value for "
+ "EGL_PLATFORM_ANGLE_DEVICE_CONTEXT_VOLATILE_"
+ "CGL_ANGLE attrib");
+ return false;
+ }
+ break;
+ case EGL_PLATFORM_ANGLE_DEVICE_ID_HIGH_ANGLE:
+ case EGL_PLATFORM_ANGLE_DEVICE_ID_LOW_ANGLE:
+ if (!clientExtensions.platformANGLEDeviceId)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_ANGLE_platform_angle_device_id is not supported");
+ return false;
+ }
+ deviceIdSpecified = true;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (!majorVersion.valid() && minorVersion.valid())
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "Must specify major version if you specify a minor version.");
+ return false;
+ }
+
+ if (deviceType == EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE &&
+ platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE requires a "
+ "device type of EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE.");
+ return false;
+ }
+
+ if (enableAutoTrimSpecified && platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE "
+ "requires a device type of "
+ "EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE.");
+ return false;
+ }
+
+ if (enableD3D11on12)
+ {
+ if (platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE "
+ "requires a platform type of "
+ "EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE.");
+ return false;
+ }
+
+ if (deviceType.valid() && deviceType != EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE &&
+ deviceType != EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE requires a device "
+ "type of EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE "
+ "or EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE");
+ return false;
+ }
+ }
+
+ if (presentPathSpecified && platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE requires a "
+ "device type of EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE.");
+ return false;
+ }
+
+ if (luidSpecified)
+ {
+ if (platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE and "
+ "EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE "
+ "require a platform type of "
+ "EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE.");
+ return false;
+ }
+
+ if (attribMap.get(EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE, 0) == 0 &&
+ attribMap.get(EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE, 0) == 0)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "If either EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE "
+ "and/or EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE are "
+ "specified, at least one must non-zero.");
+ return false;
+ }
+ }
+
+ if (deviceIdSpecified)
+ {
+ if (attribMap.get(EGL_PLATFORM_ANGLE_DEVICE_ID_HIGH_ANGLE, 0) == 0 &&
+ attribMap.get(EGL_PLATFORM_ANGLE_DEVICE_ID_LOW_ANGLE, 0) == 0)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "If either EGL_PLATFORM_ANGLE_DEVICE_ID_HIGH_ANGLE "
+ "and/or EGL_PLATFORM_ANGLE_DEVICE_ID_LOW_ANGLE are "
+ "specified, at least one must non-zero.");
+ return false;
+ }
+ }
+
+ if (deviceType.valid())
+ {
+ switch (deviceType.value())
+ {
+ case EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_REFERENCE_ANGLE:
+ case EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE:
+ if (platformType != EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE &&
+ platformType != EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "This device type requires a "
+ "platform type of EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE or "
+ "EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE.");
+ return false;
+ }
+ break;
+
+ case EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE:
+ if (platformType != EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "This device type requires a "
+ "platform type of EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE.");
+ return false;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (platformType == EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE)
+ {
+ if ((majorVersion.valid() && majorVersion.value() != 1) ||
+ (minorVersion.valid() && minorVersion.value() != 0))
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE currently "
+ "only supports Vulkan 1.0.");
+ return false;
+ }
+ }
+
+ if (eglHandle.valid() && platformType != EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE &&
+ platformType != EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_PLATFORM_ANGLE_EGL_HANDLE_ANGLE requires a "
+ "device type of EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE.");
+ return false;
+ }
+ }
+ else
+ {
+ const Device *eglDevice = static_cast<const Device *>(native_display);
+ if (eglDevice == nullptr || !Device::IsValidDevice(eglDevice))
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "native_display should be a valid EGL device if "
+ "platform equals EGL_PLATFORM_DEVICE_EXT");
+ return false;
+ }
+ }
+
+ if (attribMap.contains(EGL_POWER_PREFERENCE_ANGLE))
+ {
+ if (!clientExtensions.displayPowerPreferenceANGLE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "Attribute EGL_POWER_PREFERENCE_ANGLE "
+ "requires EGL_ANGLE_display_power_preference.");
+ return false;
+ }
+ EGLAttrib value = attribMap.get(EGL_POWER_PREFERENCE_ANGLE, 0);
+ if (value != EGL_LOW_POWER_ANGLE && value != EGL_HIGH_POWER_ANGLE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_POWER_PREFERENCE_ANGLE must be "
+ "either EGL_LOW_POWER_ANGLE or EGL_HIGH_POWER_ANGLE.");
+ return false;
+ }
+ }
+
+ if (attribMap.contains(EGL_FEATURE_OVERRIDES_ENABLED_ANGLE))
+ {
+ if (!clientExtensions.featureControlANGLE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE, "EGL_ANGLE_feature_control is not supported");
+ return false;
+ }
+ else if (attribMap.get(EGL_FEATURE_OVERRIDES_ENABLED_ANGLE, 0) == 0)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_FEATURE_OVERRIDES_ENABLED_ANGLE must be a valid pointer");
+ return false;
+ }
+ }
+ if (attribMap.contains(EGL_FEATURE_OVERRIDES_DISABLED_ANGLE))
+ {
+ if (!clientExtensions.featureControlANGLE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE, "EGL_ANGLE_feature_control is not supported");
+ return false;
+ }
+ else if (attribMap.get(EGL_FEATURE_OVERRIDES_DISABLED_ANGLE, 0) == 0)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_FEATURE_OVERRIDES_DISABLED_ANGLE must be a valid pointer");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateStream(const ValidationContext *val, const Display *display, const Stream *stream)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+
+ const DisplayExtensions &displayExtensions = display->getExtensions();
+ if (!displayExtensions.stream)
+ {
+ val->setError(EGL_BAD_ACCESS, "Stream extension not active");
+ return false;
+ }
+
+ if (stream == EGL_NO_STREAM_KHR || !display->isValidStream(stream))
+ {
+ val->setError(EGL_BAD_STREAM_KHR, "Invalid stream");
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateLabeledObject(const ValidationContext *val,
+ const Display *display,
+ ObjectType objectType,
+ EGLObjectKHR object,
+ LabeledObject **outLabeledObject)
+{
+ switch (objectType)
+ {
+ case ObjectType::Context:
+ {
+ gl::Context *context = static_cast<gl::Context *>(object);
+ ANGLE_VALIDATION_TRY(ValidateContext(val, display, context));
+ *outLabeledObject = context;
+ break;
+ }
+
+ case ObjectType::Display:
+ {
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+ if (display != object)
+ {
+ if (val)
+ {
+ val->setError(EGL_BAD_PARAMETER,
+ "when object type is EGL_OBJECT_DISPLAY_KHR, the "
+ "object must be the same as the display.");
+ }
+ return false;
+ }
+
+ *outLabeledObject = static_cast<Display *>(object);
+ break;
+ }
+
+ case ObjectType::Image:
+ {
+ Image *image = static_cast<Image *>(object);
+ ANGLE_VALIDATION_TRY(ValidateImage(val, display, image));
+ *outLabeledObject = image;
+ break;
+ }
+
+ case ObjectType::Stream:
+ {
+ Stream *stream = static_cast<Stream *>(object);
+ ANGLE_VALIDATION_TRY(ValidateStream(val, display, stream));
+ *outLabeledObject = stream;
+ break;
+ }
+
+ case ObjectType::Surface:
+ {
+ Surface *surface = static_cast<Surface *>(object);
+ ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface));
+ *outLabeledObject = surface;
+ break;
+ }
+
+ case ObjectType::Sync:
+ {
+ Sync *sync = static_cast<Sync *>(object);
+ ANGLE_VALIDATION_TRY(ValidateSync(val, display, sync));
+ *outLabeledObject = sync;
+ break;
+ }
+
+ case ObjectType::Thread:
+ {
+ ASSERT(val);
+ *outLabeledObject = val->eglThread;
+ break;
+ }
+
+ default:
+ if (val)
+ {
+ val->setError(EGL_BAD_PARAMETER, "unknown object type.");
+ }
+ return false;
+ }
+
+ return true;
+}
+
+// This is a common sub-check of Display status that's shared by multiple functions
+bool ValidateDisplayPointer(const ValidationContext *val, const Display *display)
+{
+ if (display == EGL_NO_DISPLAY)
+ {
+ if (val)
+ {
+ val->setError(EGL_BAD_DISPLAY, "display is EGL_NO_DISPLAY.");
+ }
+ return false;
+ }
+
+ if (!Display::isValidDisplay(display))
+ {
+ if (val)
+ {
+ val->setError(EGL_BAD_DISPLAY, "display is not a valid display: 0x%p", display);
+ }
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidCompositorTimingName(CompositorTiming name)
+{
+ switch (name)
+ {
+ case CompositorTiming::CompositeDeadline:
+ case CompositorTiming::CompositInterval:
+ case CompositorTiming::CompositToPresentLatency:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+bool ValidTimestampType(Timestamp timestamp)
+{
+ switch (timestamp)
+ {
+ case Timestamp::RequestedPresentTime:
+ case Timestamp::RenderingCompleteTime:
+ case Timestamp::CompositionLatchTime:
+ case Timestamp::FirstCompositionStartTime:
+ case Timestamp::LastCompositionStartTime:
+ case Timestamp::FirstCompositionGPUFinishedTime:
+ case Timestamp::DisplayPresentTime:
+ case Timestamp::DequeueReadyTime:
+ case Timestamp::ReadsDoneTime:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+bool ValidateCompatibleSurface(const ValidationContext *val,
+ const Display *display,
+ const gl::Context *context,
+ const Surface *surface)
+{
+ const Config *contextConfig = context->getConfig();
+ const Config *surfaceConfig = surface->getConfig();
+
+ if (context->getClientType() != EGL_OPENGL_API)
+ {
+ // Surface compatible with client API - only OPENGL_ES supported
+ switch (context->getClientMajorVersion())
+ {
+ case 1:
+ if (!(surfaceConfig->renderableType & EGL_OPENGL_ES_BIT))
+ {
+ val->setError(EGL_BAD_MATCH, "Surface not compatible with OpenGL ES 1.x.");
+ return false;
+ }
+ break;
+ case 2:
+ if (!(surfaceConfig->renderableType & EGL_OPENGL_ES2_BIT))
+ {
+ val->setError(EGL_BAD_MATCH, "Surface not compatible with OpenGL ES 2.x.");
+ return false;
+ }
+ break;
+ case 3:
+ if (!(surfaceConfig->renderableType & (EGL_OPENGL_ES2_BIT | EGL_OPENGL_ES3_BIT)))
+ {
+ val->setError(EGL_BAD_MATCH, "Surface not compatible with OpenGL ES 3.x.");
+ return false;
+ }
+ break;
+ default:
+ val->setError(EGL_BAD_MATCH, "Surface not compatible with Context API.");
+ return false;
+ }
+ }
+ else
+ {
+ if (!(surfaceConfig->renderableType & EGL_OPENGL_BIT))
+ {
+ val->setError(EGL_BAD_MATCH, "Surface not compatible with OpenGL Desktop.");
+ return false;
+ }
+ }
+
+ // EGL KHR no config context
+ if (context->getConfig() == EGL_NO_CONFIG_KHR)
+ {
+ const DisplayExtensions &displayExtensions = display->getExtensions();
+ if (displayExtensions.noConfigContext)
+ {
+ return true;
+ }
+ val->setError(EGL_BAD_MATCH, "Context with no config is not supported.");
+ return false;
+ }
+
+ // Config compatibility is defined in section 2.2 of the EGL 1.5 spec
+
+ bool colorBufferCompat = surfaceConfig->colorBufferType == contextConfig->colorBufferType;
+ if (!colorBufferCompat)
+ {
+ val->setError(EGL_BAD_MATCH, "Color buffer types are not compatible.");
+ return false;
+ }
+
+ bool colorCompat = surfaceConfig->redSize == contextConfig->redSize &&
+ surfaceConfig->greenSize == contextConfig->greenSize &&
+ surfaceConfig->blueSize == contextConfig->blueSize &&
+ surfaceConfig->alphaSize == contextConfig->alphaSize &&
+ surfaceConfig->luminanceSize == contextConfig->luminanceSize;
+ if (!colorCompat)
+ {
+ val->setError(EGL_BAD_MATCH, "Color buffer sizes are not compatible.");
+ return false;
+ }
+
+ bool componentTypeCompat =
+ surfaceConfig->colorComponentType == contextConfig->colorComponentType;
+ if (!componentTypeCompat)
+ {
+ val->setError(EGL_BAD_MATCH, "Color buffer component types are not compatible.");
+ return false;
+ }
+
+ bool dsCompat = surfaceConfig->depthSize == contextConfig->depthSize &&
+ surfaceConfig->stencilSize == contextConfig->stencilSize;
+ if (!dsCompat)
+ {
+ val->setError(EGL_BAD_MATCH, "Depth-stencil buffer types are not compatible.");
+ return false;
+ }
+
+ bool surfaceTypeCompat = (surfaceConfig->surfaceType & contextConfig->surfaceType) != 0;
+ if (!surfaceTypeCompat)
+ {
+ val->setError(EGL_BAD_MATCH, "Surface type is not compatible.");
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateCreateSyncBase(const ValidationContext *val,
+ const Display *display,
+ EGLenum type,
+ const AttributeMap &attribs,
+ bool isExt)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+
+ attribs.initializeWithoutValidation();
+
+ gl::Context *currentContext = val->eglThread->getContext();
+ egl::Display *currentDisplay = currentContext ? currentContext->getDisplay() : nullptr;
+
+ switch (type)
+ {
+ case EGL_SYNC_FENCE_KHR:
+ if (!attribs.isEmpty())
+ {
+ val->setError(EGL_BAD_ATTRIBUTE, "Invalid attribute");
+ return false;
+ }
+
+ if (!display->getExtensions().fenceSync)
+ {
+ val->setError(EGL_BAD_MATCH, "EGL_KHR_fence_sync extension is not available");
+ return false;
+ }
+
+ if (display != currentDisplay)
+ {
+ val->setError(EGL_BAD_MATCH,
+ "CreateSync can only be called on the current display");
+ return false;
+ }
+
+ ANGLE_VALIDATION_TRY(ValidateContext(val, currentDisplay, currentContext));
+
+ if (!currentContext->getExtensions().EGLSyncOES)
+ {
+ val->setError(EGL_BAD_MATCH,
+ "EGL_SYNC_FENCE_KHR cannot be used without "
+ "GL_OES_EGL_sync support.");
+ return false;
+ }
+ break;
+
+ case EGL_SYNC_NATIVE_FENCE_ANDROID:
+ if (!display->getExtensions().fenceSync)
+ {
+ val->setError(EGL_BAD_MATCH, "EGL_KHR_fence_sync extension is not available");
+ return false;
+ }
+
+ if (!display->getExtensions().nativeFenceSyncANDROID)
+ {
+ val->setError(EGL_BAD_DISPLAY,
+ "EGL_ANDROID_native_fence_sync extension is not available.");
+ return false;
+ }
+
+ if (display != currentDisplay)
+ {
+ val->setError(EGL_BAD_MATCH,
+ "CreateSync can only be called on the current display");
+ return false;
+ }
+
+ ANGLE_VALIDATION_TRY(ValidateContext(val, currentDisplay, currentContext));
+
+ if (!currentContext->getExtensions().EGLSyncOES)
+ {
+ val->setError(EGL_BAD_MATCH,
+ "EGL_SYNC_FENCE_KHR cannot be used without "
+ "GL_OES_EGL_sync support.");
+ return false;
+ }
+
+ for (const auto &attributeIter : attribs)
+ {
+ EGLAttrib attribute = attributeIter.first;
+
+ switch (attribute)
+ {
+ case EGL_SYNC_NATIVE_FENCE_FD_ANDROID:
+ break;
+
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE, "Invalid attribute");
+ return false;
+ }
+ }
+ break;
+
+ case EGL_SYNC_REUSABLE_KHR:
+ if (!attribs.isEmpty())
+ {
+ val->setError(EGL_BAD_ATTRIBUTE, "Invalid attribute");
+ return false;
+ }
+
+ if (!display->getExtensions().reusableSyncKHR)
+ {
+ val->setError(EGL_BAD_MATCH, "EGL_KHR_reusable_sync extension is not available.");
+ return false;
+ }
+ break;
+
+ case EGL_SYNC_METAL_SHARED_EVENT_ANGLE:
+ if (!display->getExtensions().fenceSync)
+ {
+ val->setError(EGL_BAD_MATCH, "EGL_KHR_fence_sync extension is not available");
+ return false;
+ }
+
+ if (!display->getExtensions().mtlSyncSharedEventANGLE)
+ {
+ val->setError(EGL_BAD_DISPLAY,
+ "EGL_ANGLE_metal_shared_event_sync is not available");
+ return false;
+ }
+
+ if (display != currentDisplay)
+ {
+ val->setError(EGL_BAD_MATCH,
+ "CreateSync can only be called on the current display");
+ return false;
+ }
+
+ ANGLE_VALIDATION_TRY(ValidateContext(val, currentDisplay, currentContext));
+
+ // This should be implied by exposing EGL_KHR_fence_sync
+ ASSERT(currentContext->getExtensions().EGLSyncOES);
+
+ for (const auto &attributeIter : attribs)
+ {
+ EGLAttrib attribute = attributeIter.first;
+ EGLAttrib value = attributeIter.second;
+
+ switch (attribute)
+ {
+ case EGL_SYNC_METAL_SHARED_EVENT_OBJECT_ANGLE:
+ if (!value)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_SYNC_METAL_SHARED_EVENT_ANGLE can't be NULL");
+ return false;
+ }
+ break;
+
+ case EGL_SYNC_METAL_SHARED_EVENT_SIGNAL_VALUE_LO_ANGLE:
+ case EGL_SYNC_METAL_SHARED_EVENT_SIGNAL_VALUE_HI_ANGLE:
+ break;
+
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE, "Invalid attribute");
+ return false;
+ }
+ }
+ break;
+
+ default:
+ if (isExt)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE, "Invalid type parameter");
+ return false;
+ }
+ else
+ {
+ val->setError(EGL_BAD_PARAMETER, "Invalid type parameter");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateGetSyncAttribBase(const ValidationContext *val,
+ const Display *display,
+ const Sync *sync,
+ EGLint attribute)
+{
+ ANGLE_VALIDATION_TRY(ValidateSync(val, display, sync));
+
+ switch (attribute)
+ {
+ case EGL_SYNC_CONDITION_KHR:
+ switch (sync->getType())
+ {
+ case EGL_SYNC_FENCE_KHR:
+ case EGL_SYNC_NATIVE_FENCE_ANDROID:
+ case EGL_SYNC_METAL_SHARED_EVENT_ANGLE:
+ break;
+
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_SYNC_CONDITION_KHR is not valid for this sync type.");
+ return false;
+ }
+ break;
+
+ // The following attributes are accepted by all types
+ case EGL_SYNC_TYPE_KHR:
+ case EGL_SYNC_STATUS_KHR:
+ break;
+
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE, "Invalid attribute");
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateQueryDisplayAttribBase(const ValidationContext *val,
+ const Display *display,
+ const EGLint attribute)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+
+ switch (attribute)
+ {
+ case EGL_DEVICE_EXT:
+ if (!Display::GetClientExtensions().deviceQueryEXT)
+ {
+ val->setError(EGL_BAD_DISPLAY, "EGL_EXT_device_query extension is not available.");
+ return false;
+ }
+ break;
+
+ case EGL_FEATURE_COUNT_ANGLE:
+ if (!Display::GetClientExtensions().featureControlANGLE)
+ {
+ val->setError(EGL_BAD_DISPLAY,
+ "EGL_ANGLE_feature_control extension is not available.");
+ return false;
+ }
+ break;
+
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE, "attribute is not valid.");
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateCreateContextAttribute(const ValidationContext *val,
+ const Display *display,
+ EGLAttrib attribute)
+{
+ switch (attribute)
+ {
+ case EGL_CONTEXT_CLIENT_VERSION:
+ case EGL_CONTEXT_MINOR_VERSION:
+ case EGL_CONTEXT_FLAGS_KHR:
+ case EGL_CONTEXT_OPENGL_DEBUG:
+ break;
+
+ case EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR:
+ if (val->eglThread->getAPI() != EGL_OPENGL_API)
+ {
+ // Only valid for OpenGL (non-ES) contexts
+ val->setError(EGL_BAD_ATTRIBUTE, "OpenGL profile mask requires an OpenGL context.");
+ return false;
+ }
+ break;
+
+ case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT:
+ if (!display->getExtensions().createContextRobustness)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE);
+ return false;
+ }
+ break;
+
+ case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT:
+ if (!display->getExtensions().createContextRobustness)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE);
+ return false;
+ }
+ break;
+
+ case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY:
+ {
+ // We either need to have -
+ // 1. EGL 1.5 which added support for this as part of core spec
+ // 2. EGL_KHR_create_context extension which requires EGL 1.4
+ constexpr EGLint kRequiredMajorVersion = 1;
+ constexpr EGLint kRequiredMinorVersion = 5;
+ if ((kEglMajorVersion < kRequiredMajorVersion ||
+ kEglMinorVersion < kRequiredMinorVersion) &&
+ !display->getExtensions().createContext)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE);
+ return false;
+ }
+ break;
+ }
+
+ case EGL_CONTEXT_OPENGL_NO_ERROR_KHR:
+ if (!display->getExtensions().createContextNoError)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE, "Invalid Context attribute.");
+ return false;
+ }
+ break;
+
+ case EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE:
+ if (!display->getExtensions().createContextWebGLCompatibility)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "Attribute "
+ "EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE requires "
+ "EGL_ANGLE_create_context_webgl_compatibility.");
+ return false;
+ }
+ break;
+
+ case EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM:
+ if (!display->getExtensions().createContextBindGeneratesResource)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "Attribute EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM requires "
+ "EGL_CHROMIUM_create_context_bind_generates_resource.");
+ return false;
+ }
+ break;
+
+ case EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE:
+ if (!display->getExtensions().displayTextureShareGroup)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "Attribute "
+ "EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE requires "
+ "EGL_ANGLE_display_texture_share_group.");
+ return false;
+ }
+ break;
+
+ case EGL_DISPLAY_SEMAPHORE_SHARE_GROUP_ANGLE:
+ if (!display->getExtensions().displayTextureShareGroup)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "Attribute "
+ "EGL_DISPLAY_SEMAPHORE_SHARE_GROUP_ANGLE requires "
+ "EGL_ANGLE_display_semaphore_share_group.");
+ return false;
+ }
+ break;
+
+ case EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE:
+ if (!display->getExtensions().createContextClientArrays)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "Attribute EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE requires "
+ "EGL_ANGLE_create_context_client_arrays.");
+ return false;
+ }
+ break;
+
+ case EGL_CONTEXT_PROGRAM_BINARY_CACHE_ENABLED_ANGLE:
+ if (!display->getExtensions().programCacheControlANGLE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "Attribute EGL_CONTEXT_PROGRAM_BINARY_CACHE_ENABLED_ANGLE "
+ "requires EGL_ANGLE_program_cache_control.");
+ return false;
+ }
+ break;
+
+ case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
+ if (!display->getExtensions().robustResourceInitializationANGLE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "Attribute EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE "
+ "requires EGL_ANGLE_robust_resource_initialization.");
+ return false;
+ }
+ break;
+
+ case EGL_EXTENSIONS_ENABLED_ANGLE:
+ if (!display->getExtensions().createContextExtensionsEnabled)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "Attribute EGL_EXTENSIONS_ENABLED_ANGLE "
+ "requires EGL_ANGLE_create_context_extensions_enabled.");
+ return false;
+ }
+ break;
+
+ case EGL_POWER_PREFERENCE_ANGLE:
+ if (!display->getExtensions().powerPreference)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "Attribute EGL_POWER_PREFERENCE_ANGLE "
+ "requires EGL_ANGLE_power_preference.");
+ return false;
+ }
+ break;
+
+ case EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE:
+ if (!display->getExtensions().createContextBackwardsCompatible)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "Attribute EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE "
+ "requires EGL_ANGLE_create_context_backwards_compatible.");
+ return false;
+ }
+ break;
+
+ case EGL_CONTEXT_PRIORITY_LEVEL_IMG:
+ if (!display->getExtensions().contextPriority)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "Attribute EGL_CONTEXT_PRIORITY_LEVEL_IMG requires "
+ "extension EGL_IMG_context_priority.");
+ return false;
+ }
+ break;
+
+ case EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV:
+ if (!display->getExtensions().robustnessVideoMemoryPurgeNV)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "Attribute EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV requires "
+ "extension EGL_NV_robustness_video_memory_purge.");
+ return false;
+ }
+ break;
+
+ case EGL_EXTERNAL_CONTEXT_ANGLE:
+ if (!display->getExtensions().externalContextAndSurface)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "Attribute "
+ "EGL_EXTERNAL_CONTEXT_ANGLE requires "
+ "EGL_ANGLE_external_context_and_surface.");
+ return false;
+ }
+ break;
+ case EGL_EXTERNAL_CONTEXT_SAVE_STATE_ANGLE:
+ if (!display->getExtensions().externalContextAndSurface)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "Attribute "
+ "EGL_EXTERNAL_CONTEXT_SAVE_STATE_ANGLE requires "
+ "EGL_ANGLE_external_context_and_surface.");
+ return false;
+ }
+ break;
+
+ case EGL_PROTECTED_CONTENT_EXT:
+ if (!display->getExtensions().protectedContentEXT)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "Attribute EGL_PROTECTED_CONTEXT_EXT requires "
+ "extension EGL_EXT_protected_content.");
+ return false;
+ }
+ break;
+
+ case EGL_CONTEXT_VIRTUALIZATION_GROUP_ANGLE:
+ if (!display->getExtensions().contextVirtualizationANGLE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "Attribute EGL_CONTEXT_VIRTUALIZATION_GROUP_ANGLE requires "
+ "extension EGL_ANGLE_context_virtualization.");
+ return false;
+ }
+ break;
+
+ case EGL_CONTEXT_METAL_OWNERSHIP_IDENTITY_ANGLE:
+ if (!display->getExtensions().metalCreateContextOwnershipIdentityANGLE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "Attribute EGL_CONTEXT_METAL_OWNERSHIP_IDENTITY_ANGLE requires "
+ "EGL_ANGLE_metal_create_context_ownership_identity.");
+ }
+ break;
+
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE, "Unknown attribute: 0x%04" PRIxPTR "X", attribute);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateCreateContextAttributeValue(const ValidationContext *val,
+ const Display *display,
+ const gl::Context *shareContext,
+ EGLAttrib attribute,
+ EGLAttrib value)
+{
+ switch (attribute)
+ {
+ case EGL_CONTEXT_CLIENT_VERSION:
+ case EGL_CONTEXT_MINOR_VERSION:
+ case EGL_CONTEXT_OPENGL_DEBUG:
+ case EGL_CONTEXT_VIRTUALIZATION_GROUP_ANGLE:
+ break;
+
+ case EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR:
+ {
+ constexpr EGLint kValidProfileMaskFlags =
+ (EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT |
+ EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT);
+ if ((value & ~kValidProfileMaskFlags) != 0)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE, "Invalid OpenGL profile mask.");
+ return false;
+ }
+ break;
+ }
+
+ case EGL_CONTEXT_FLAGS_KHR:
+ {
+ // Note: EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR does not apply to ES
+ constexpr EGLint kValidContextFlags =
+ (EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR | EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR);
+ if ((value & ~kValidContextFlags) != 0)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE);
+ return false;
+ }
+ break;
+ }
+
+ case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT:
+ if (value != EGL_TRUE && value != EGL_FALSE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE);
+ return false;
+ }
+ break;
+
+ case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT:
+ case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY:
+ if (value != EGL_LOSE_CONTEXT_ON_RESET_EXT && value != EGL_NO_RESET_NOTIFICATION_EXT)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE);
+ return false;
+ }
+
+ if (shareContext && shareContext->isResetNotificationEnabled() !=
+ (value == EGL_LOSE_CONTEXT_ON_RESET_EXT))
+ {
+ val->setError(EGL_BAD_MATCH);
+ return false;
+ }
+ break;
+
+ case EGL_CONTEXT_OPENGL_NO_ERROR_KHR:
+ if (value != EGL_TRUE && value != EGL_FALSE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE, "Attribute must be EGL_TRUE or EGL_FALSE.");
+ return false;
+ }
+ break;
+
+ case EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE:
+ if (value != EGL_TRUE && value != EGL_FALSE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE must be "
+ "EGL_TRUE or EGL_FALSE.");
+ return false;
+ }
+ break;
+
+ case EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM:
+ if (value != EGL_TRUE && value != EGL_FALSE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM "
+ "must be EGL_TRUE or EGL_FALSE.");
+ return false;
+ }
+ break;
+
+ case EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE:
+ if (value != EGL_TRUE && value != EGL_FALSE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE must be "
+ "EGL_TRUE or EGL_FALSE.");
+ return false;
+ }
+ if (shareContext &&
+ shareContext->usingDisplayTextureShareGroup() != (value == EGL_TRUE))
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "All contexts within a share group must be "
+ "created with the same value of "
+ "EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE.");
+ return false;
+ }
+ break;
+
+ case EGL_DISPLAY_SEMAPHORE_SHARE_GROUP_ANGLE:
+ if (value != EGL_TRUE && value != EGL_FALSE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_DISPLAY_SEMAPHORE_SHARE_GROUP_ANGLE must be "
+ "EGL_TRUE or EGL_FALSE.");
+ return false;
+ }
+ if (shareContext &&
+ shareContext->usingDisplaySemaphoreShareGroup() != (value == EGL_TRUE))
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "All contexts within a share group must be "
+ "created with the same value of "
+ "EGL_DISPLAY_SEMAPHORE_SHARE_GROUP_ANGLE.");
+ return false;
+ }
+ break;
+
+ case EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE:
+ if (value != EGL_TRUE && value != EGL_FALSE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE must "
+ "be EGL_TRUE or EGL_FALSE.");
+ return false;
+ }
+ break;
+
+ case EGL_CONTEXT_PROGRAM_BINARY_CACHE_ENABLED_ANGLE:
+ if (value != EGL_TRUE && value != EGL_FALSE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_CONTEXT_PROGRAM_BINARY_CACHE_ENABLED_ANGLE must "
+ "be EGL_TRUE or EGL_FALSE.");
+ return false;
+ }
+ break;
+
+ case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
+ if (value != EGL_TRUE && value != EGL_FALSE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE must be "
+ "either EGL_TRUE or EGL_FALSE.");
+ return false;
+ }
+ break;
+
+ case EGL_EXTENSIONS_ENABLED_ANGLE:
+ if (value != EGL_TRUE && value != EGL_FALSE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_EXTENSIONS_ENABLED_ANGLE must be "
+ "either EGL_TRUE or EGL_FALSE.");
+ return false;
+ }
+ break;
+
+ case EGL_POWER_PREFERENCE_ANGLE:
+ if (value != EGL_LOW_POWER_ANGLE && value != EGL_HIGH_POWER_ANGLE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_POWER_PREFERENCE_ANGLE must be "
+ "either EGL_LOW_POWER_ANGLE or EGL_HIGH_POWER_ANGLE.");
+ return false;
+ }
+ break;
+
+ case EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE:
+ if (value != EGL_TRUE && value != EGL_FALSE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE must be "
+ "either EGL_TRUE or EGL_FALSE.");
+ return false;
+ }
+ break;
+
+ case EGL_CONTEXT_PRIORITY_LEVEL_IMG:
+ switch (value)
+ {
+ case EGL_CONTEXT_PRIORITY_LOW_IMG:
+ case EGL_CONTEXT_PRIORITY_MEDIUM_IMG:
+ case EGL_CONTEXT_PRIORITY_HIGH_IMG:
+ break;
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "Attribute EGL_CONTEXT_PRIORITY_LEVEL_IMG "
+ "must be one of: EGL_CONTEXT_PRIORITY_LOW_IMG, "
+ "EGL_CONTEXT_PRIORITY_MEDIUM_IMG, or "
+ "EGL_CONTEXT_PRIORITY_HIGH_IMG.");
+ return false;
+ }
+ break;
+
+ case EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV:
+ if (value != EGL_TRUE && value != EGL_FALSE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV must "
+ "be either EGL_TRUE or EGL_FALSE.");
+ return false;
+ }
+ break;
+
+ case EGL_EXTERNAL_CONTEXT_ANGLE:
+ if (value != EGL_TRUE && value != EGL_FALSE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_EXTERNAL_CONTEXT_ANGLE must "
+ "be either EGL_TRUE or EGL_FALSE.");
+ return false;
+ }
+ if (shareContext && (value == EGL_TRUE))
+ {
+ val->setError(
+ EGL_BAD_ATTRIBUTE,
+ "EGL_EXTERNAL_CONTEXT_ANGLE doesn't allow creating with sharedContext.");
+ return false;
+ }
+ break;
+ case EGL_EXTERNAL_CONTEXT_SAVE_STATE_ANGLE:
+ if (value != EGL_TRUE && value != EGL_FALSE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_EXTERNAL_CONTEXT_SAVE_STATE_ANGLE must "
+ "be either EGL_TRUE or EGL_FALSE.");
+ return false;
+ }
+ break;
+
+ case EGL_PROTECTED_CONTENT_EXT:
+ if (value != EGL_TRUE && value != EGL_FALSE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_PROTECTED_CONTENT_EXT must "
+ "be either EGL_TRUE or EGL_FALSE.");
+ return false;
+ }
+ break;
+
+ case EGL_CONTEXT_METAL_OWNERSHIP_IDENTITY_ANGLE:
+ if (value == 0)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_CONTEXT_METAL_OWNERSHIP_IDENTITY_ANGLE must"
+ "be non-zero.");
+ return false;
+ }
+ break;
+
+ default:
+ UNREACHABLE();
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateCreatePbufferSurfaceAttribute(const ValidationContext *val,
+ const Display *display,
+ EGLAttrib attribute)
+{
+ const DisplayExtensions &displayExtensions = display->getExtensions();
+
+ switch (attribute)
+ {
+ case EGL_WIDTH:
+ case EGL_HEIGHT:
+ case EGL_LARGEST_PBUFFER:
+ case EGL_TEXTURE_FORMAT:
+ case EGL_TEXTURE_TARGET:
+ case EGL_MIPMAP_TEXTURE:
+ case EGL_VG_COLORSPACE:
+ case EGL_GL_COLORSPACE:
+ case EGL_VG_ALPHA_FORMAT:
+ break;
+
+ case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
+ if (!displayExtensions.robustResourceInitializationANGLE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "Attribute EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE "
+ "requires EGL_ANGLE_robust_resource_initialization.");
+ return false;
+ }
+ break;
+
+ case EGL_PROTECTED_CONTENT_EXT:
+ if (!displayExtensions.protectedContentEXT)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "Attribute EGL_PROTECTED_CONTEXT_EXT requires "
+ "extension EGL_EXT_protected_content.");
+ return false;
+ }
+ break;
+
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateCreatePbufferSurfaceAttributeValue(const ValidationContext *val,
+ const Display *display,
+ EGLAttrib attribute,
+ EGLAttrib value)
+{
+ const DisplayExtensions &displayExtensions = display->getExtensions();
+
+ switch (attribute)
+ {
+ case EGL_WIDTH:
+ case EGL_HEIGHT:
+ if (value < 0)
+ {
+ val->setError(EGL_BAD_PARAMETER);
+ return false;
+ }
+ break;
+
+ case EGL_LARGEST_PBUFFER:
+ break;
+
+ case EGL_TEXTURE_FORMAT:
+ switch (value)
+ {
+ case EGL_NO_TEXTURE:
+ case EGL_TEXTURE_RGB:
+ case EGL_TEXTURE_RGBA:
+ break;
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE);
+ return false;
+ }
+ break;
+
+ case EGL_TEXTURE_TARGET:
+ switch (value)
+ {
+ case EGL_NO_TEXTURE:
+ case EGL_TEXTURE_2D:
+ break;
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE);
+ return false;
+ }
+ break;
+
+ case EGL_MIPMAP_TEXTURE:
+ break;
+
+ case EGL_VG_COLORSPACE:
+ break;
+
+ case EGL_GL_COLORSPACE:
+ ANGLE_VALIDATION_TRY(ValidateColorspaceAttribute(val, displayExtensions, value));
+ break;
+
+ case EGL_VG_ALPHA_FORMAT:
+ break;
+
+ case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
+ ASSERT(displayExtensions.robustResourceInitializationANGLE);
+ if (value != EGL_TRUE && value != EGL_FALSE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE must be "
+ "either EGL_TRUE or EGL_FALSE.");
+ return false;
+ }
+ break;
+
+ case EGL_PROTECTED_CONTENT_EXT:
+ ASSERT(displayExtensions.protectedContentEXT);
+ if (value != EGL_TRUE && value != EGL_FALSE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_PROTECTED_CONTENT_EXT must "
+ "be either EGL_TRUE or EGL_FALSE.");
+ return false;
+ }
+ break;
+
+ default:
+ UNREACHABLE();
+ return false;
+ }
+
+ return true;
+}
+} // anonymous namespace
+
+void ValidationContext::setError(EGLint error) const
+{
+ eglThread->setError(error, entryPoint, labeledObject, nullptr);
+}
+
+void ValidationContext::setError(EGLint error, const char *message...) const
+{
+ ASSERT(message);
+
+ constexpr uint32_t kBufferSize = 1000;
+ char buffer[kBufferSize];
+
+ va_list args;
+ va_start(args, message);
+ vsnprintf(buffer, kBufferSize, message, args);
+
+ eglThread->setError(error, entryPoint, labeledObject, buffer);
+}
+
+bool ValidateDisplay(const ValidationContext *val, const Display *display)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplayPointer(val, display));
+
+ if (!display->isInitialized())
+ {
+ if (val)
+ {
+ val->setError(EGL_NOT_INITIALIZED, "display is not initialized.");
+ }
+ return false;
+ }
+
+ if (display->isDeviceLost())
+ {
+ if (val)
+ {
+ val->setError(EGL_CONTEXT_LOST, "display had a context loss");
+ }
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateSurface(const ValidationContext *val, const Display *display, const Surface *surface)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+
+ if (!display->isValidSurface(surface))
+ {
+ if (val)
+ {
+ val->setError(EGL_BAD_SURFACE);
+ }
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateConfig(const ValidationContext *val, const Display *display, const Config *config)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+
+ if (!display->isValidConfig(config))
+ {
+ if (val)
+ {
+ val->setError(EGL_BAD_CONFIG);
+ }
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateContext(const ValidationContext *val,
+ const Display *display,
+ const gl::Context *context)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+
+ if (!display->isValidContext(context))
+ {
+ if (val)
+ {
+ val->setError(EGL_BAD_CONTEXT);
+ }
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateImage(const ValidationContext *val, const Display *display, const Image *image)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+
+ if (!display->isValidImage(image))
+ {
+ if (val)
+ {
+ val->setError(EGL_BAD_PARAMETER, "image is not valid.");
+ }
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateDevice(const ValidationContext *val, const Device *device)
+{
+ if (device == EGL_NO_DEVICE_EXT)
+ {
+ if (val)
+ {
+ val->setError(EGL_BAD_ACCESS, "device is EGL_NO_DEVICE.");
+ }
+ return false;
+ }
+
+ if (!Device::IsValidDevice(device))
+ {
+ if (val)
+ {
+ val->setError(EGL_BAD_ACCESS, "device is not valid.");
+ }
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateSync(const ValidationContext *val, const Display *display, const Sync *sync)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+
+ if (!display->isValidSync(sync))
+ {
+ if (val)
+ {
+ val->setError(EGL_BAD_PARAMETER, "sync object is not valid.");
+ }
+ return false;
+ }
+
+ return true;
+}
+
+const Thread *GetThreadIfValid(const Thread *thread)
+{
+ // Threads should always be valid
+ return thread;
+}
+
+const Display *GetDisplayIfValid(const Display *display)
+{
+ return ValidateDisplay(nullptr, display) ? display : nullptr;
+}
+
+const Surface *GetSurfaceIfValid(const Display *display, const Surface *surface)
+{
+ return ValidateSurface(nullptr, display, surface) ? surface : nullptr;
+}
+
+const Image *GetImageIfValid(const Display *display, const Image *image)
+{
+ return ValidateImage(nullptr, display, image) ? image : nullptr;
+}
+
+const Stream *GetStreamIfValid(const Display *display, const Stream *stream)
+{
+ return ValidateStream(nullptr, display, stream) ? stream : nullptr;
+}
+
+const gl::Context *GetContextIfValid(const Display *display, const gl::Context *context)
+{
+ return ValidateContext(nullptr, display, context) ? context : nullptr;
+}
+
+const Device *GetDeviceIfValid(const Device *device)
+{
+ return ValidateDevice(nullptr, device) ? device : nullptr;
+}
+
+const Sync *GetSyncIfValid(const Display *display, const Sync *sync)
+{
+ return ValidateSync(nullptr, display, sync) ? sync : nullptr;
+}
+
+LabeledObject *GetLabeledObjectIfValid(Thread *thread,
+ const Display *display,
+ ObjectType objectType,
+ EGLObjectKHR object)
+{
+ if (objectType == ObjectType::Thread)
+ {
+ return thread;
+ }
+
+ LabeledObject *labeledObject = nullptr;
+ if (ValidateLabeledObject(nullptr, display, objectType, object, &labeledObject))
+ {
+ return labeledObject;
+ }
+
+ return nullptr;
+}
+
+bool ValidateInitialize(const ValidationContext *val,
+ const Display *display,
+ const EGLint *major,
+ const EGLint *minor)
+{
+ return ValidateDisplayPointer(val, display);
+}
+
+bool ValidateTerminate(const ValidationContext *val, const Display *display)
+{
+ return ValidateDisplayPointer(val, display);
+}
+
+bool ValidateCreateContext(const ValidationContext *val,
+ const Display *display,
+ const Config *configuration,
+ const gl::Context *shareContext,
+ const AttributeMap &attributes)
+{
+ if (configuration)
+ {
+ ANGLE_VALIDATION_TRY(ValidateConfig(val, display, configuration));
+ }
+ else
+ {
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+ const DisplayExtensions &displayExtensions = display->getExtensions();
+ if (!displayExtensions.noConfigContext)
+ {
+ val->setError(EGL_BAD_CONFIG);
+ return false;
+ }
+ }
+
+ ANGLE_VALIDATION_TRY(attributes.validate(val, display, ValidateCreateContextAttribute));
+
+ for (const auto &attributePair : attributes)
+ {
+ EGLAttrib attribute = attributePair.first;
+ EGLAttrib value = attributePair.second;
+ ANGLE_VALIDATION_TRY(
+ ValidateCreateContextAttributeValue(val, display, shareContext, attribute, value));
+ }
+
+ // Get the requested client version (default is 1) and check it is 2 or 3.
+ EGLAttrib clientMajorVersion = attributes.get(EGL_CONTEXT_CLIENT_VERSION, 1);
+ EGLAttrib clientMinorVersion = attributes.get(EGL_CONTEXT_MINOR_VERSION, 0);
+ EGLenum api = val->eglThread->getAPI();
+
+ switch (api)
+ {
+ case EGL_OPENGL_ES_API:
+ switch (clientMajorVersion)
+ {
+ case 1:
+ if (clientMinorVersion != 0 && clientMinorVersion != 1)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE);
+ return false;
+ }
+ if (configuration == EGL_NO_CONFIG_KHR)
+ {
+ val->setError(EGL_BAD_MATCH);
+ return false;
+ }
+ if ((configuration != EGL_NO_CONFIG_KHR) &&
+ !(configuration->renderableType & EGL_OPENGL_ES_BIT))
+ {
+ val->setError(EGL_BAD_MATCH);
+ return false;
+ }
+ break;
+
+ case 2:
+ if (clientMinorVersion != 0)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE);
+ return false;
+ }
+ if ((configuration != EGL_NO_CONFIG_KHR) &&
+ !(configuration->renderableType & EGL_OPENGL_ES2_BIT))
+ {
+ val->setError(EGL_BAD_MATCH);
+ return false;
+ }
+ break;
+ case 3:
+ if (clientMinorVersion < 0 || clientMinorVersion > 2)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE);
+ return false;
+ }
+ if ((configuration != EGL_NO_CONFIG_KHR) &&
+ !(configuration->renderableType & EGL_OPENGL_ES3_BIT))
+ {
+ val->setError(EGL_BAD_MATCH);
+ return false;
+ }
+ if (display->getMaxSupportedESVersion() <
+ gl::Version(static_cast<GLuint>(clientMajorVersion),
+ static_cast<GLuint>(clientMinorVersion)))
+ {
+ gl::Version max = display->getMaxSupportedESVersion();
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "Requested GLES version (%" PRIxPTR ".%" PRIxPTR
+ ") is greater than "
+ "max supported (%d, %d).",
+ clientMajorVersion, clientMinorVersion, max.major, max.minor);
+ return false;
+ }
+ if ((attributes.get(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE, EGL_FALSE) ==
+ EGL_TRUE) &&
+ (clientMinorVersion > 1))
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "Requested GLES version (%" PRIxPTR ".%" PRIxPTR
+ ") is greater than "
+ "max supported 3.1 for WebGL.",
+ clientMajorVersion, clientMinorVersion);
+ return false;
+ }
+ break;
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE);
+ return false;
+ }
+ break;
+
+ case EGL_OPENGL_API:
+ // The requested configuration must use EGL_OPENGL_BIT if EGL_OPENGL_BIT is the
+ // currently bound API.
+ if ((configuration != EGL_NO_CONFIG_KHR) &&
+ !(configuration->renderableType & EGL_OPENGL_BIT))
+ {
+ val->setError(EGL_BAD_CONFIG);
+ return false;
+ }
+ // TODO(http://anglebug.com/7533): validate desktop OpenGL versions and profile mask
+ break;
+
+ default:
+ val->setError(EGL_BAD_MATCH, "Unsupported API.");
+ return false;
+ }
+
+ if (shareContext)
+ {
+ // Shared context is invalid or is owned by another display
+ if (!display->isValidContext(shareContext))
+ {
+ val->setError(EGL_BAD_MATCH);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateCreateWindowSurface(const ValidationContext *val,
+ const Display *display,
+ const Config *config,
+ EGLNativeWindowType window,
+ const AttributeMap &attributes)
+{
+ ANGLE_VALIDATION_TRY(ValidateConfig(val, display, config));
+
+ if (!display->isValidNativeWindow(window))
+ {
+ val->setError(EGL_BAD_NATIVE_WINDOW);
+ return false;
+ }
+
+ const DisplayExtensions &displayExtensions = display->getExtensions();
+
+ attributes.initializeWithoutValidation();
+
+ for (const auto &attributeIter : attributes)
+ {
+ EGLAttrib attribute = attributeIter.first;
+ EGLAttrib value = attributeIter.second;
+
+ switch (attribute)
+ {
+ case EGL_RENDER_BUFFER:
+ switch (value)
+ {
+ case EGL_BACK_BUFFER:
+ break;
+ case EGL_SINGLE_BUFFER:
+ break;
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE);
+ return false;
+ }
+ break;
+
+ case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
+ if (!displayExtensions.postSubBuffer)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE);
+ return false;
+ }
+ break;
+
+ case EGL_WIDTH:
+ case EGL_HEIGHT:
+ if (!displayExtensions.windowFixedSize)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE);
+ return false;
+ }
+ if (value < 0)
+ {
+ val->setError(EGL_BAD_PARAMETER);
+ return false;
+ }
+ break;
+
+ case EGL_FIXED_SIZE_ANGLE:
+ if (!displayExtensions.windowFixedSize)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE);
+ return false;
+ }
+ break;
+
+ case EGL_SURFACE_ORIENTATION_ANGLE:
+ if (!displayExtensions.surfaceOrientation)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_ANGLE_surface_orientation is not enabled.");
+ return false;
+ }
+ break;
+
+ case EGL_VG_COLORSPACE:
+ if (value != EGL_VG_COLORSPACE_sRGB)
+ {
+ val->setError(EGL_BAD_MATCH);
+ return false;
+ }
+ break;
+
+ case EGL_GL_COLORSPACE:
+ ANGLE_VALIDATION_TRY(ValidateColorspaceAttribute(val, displayExtensions, value));
+ break;
+
+ case EGL_VG_ALPHA_FORMAT:
+ val->setError(EGL_BAD_MATCH);
+ return false;
+
+ case EGL_DIRECT_COMPOSITION_ANGLE:
+ if (!displayExtensions.directComposition)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE);
+ return false;
+ }
+ break;
+
+ case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
+ if (!display->getExtensions().robustResourceInitializationANGLE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "Attribute EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE "
+ "requires EGL_ANGLE_robust_resource_initialization.");
+ return false;
+ }
+ if (value != EGL_TRUE && value != EGL_FALSE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE must be "
+ "either EGL_TRUE or EGL_FALSE.");
+ return false;
+ }
+ break;
+
+ case EGL_GGP_STREAM_DESCRIPTOR_ANGLE:
+ if (!display->getExtensions().ggpStreamDescriptor)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_GGP_STREAM_DESCRIPTOR_ANGLE requires "
+ "EGL_ANGLE_ggp_stream_descriptor.");
+ return false;
+ }
+ break;
+
+ case EGL_PROTECTED_CONTENT_EXT:
+ if (!displayExtensions.protectedContentEXT)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "Attribute EGL_PROTECTED_CONTEXT_EXT requires "
+ "extension EGL_EXT_protected_content.");
+ return false;
+ }
+ if (value != EGL_TRUE && value != EGL_FALSE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_PROTECTED_CONTENT_EXT must "
+ "be either EGL_TRUE or EGL_FALSE.");
+ return false;
+ }
+ break;
+
+ case EGL_SWAP_INTERVAL_ANGLE:
+ if (!displayExtensions.createSurfaceSwapIntervalANGLE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "Attribute EGL_SWAP_INTERVAL_ANGLE requires "
+ "extension EGL_ANGLE_create_surface_swap_interval.");
+ return false;
+ }
+ if (value < config->minSwapInterval || value > config->maxSwapInterval)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_SWAP_INTERVAL_ANGLE must "
+ "be within the EGLConfig min and max swap intervals.");
+ return false;
+ }
+ break;
+
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE);
+ return false;
+ }
+ }
+
+ if (Display::hasExistingWindowSurface(window))
+ {
+ val->setError(EGL_BAD_ALLOC);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateCreatePbufferSurface(const ValidationContext *val,
+ const Display *display,
+ const Config *config,
+ const AttributeMap &attributes)
+{
+ ANGLE_VALIDATION_TRY(ValidateConfig(val, display, config));
+ ANGLE_VALIDATION_TRY(attributes.validate(val, display, ValidateCreatePbufferSurfaceAttribute));
+
+ for (const auto &attributeIter : attributes)
+ {
+ EGLAttrib attribute = attributeIter.first;
+ EGLAttrib value = attributeIter.second;
+
+ ANGLE_VALIDATION_TRY(
+ ValidateCreatePbufferSurfaceAttributeValue(val, display, attribute, value));
+ }
+
+ if ((config->surfaceType & EGL_PBUFFER_BIT) == 0)
+ {
+ val->setError(EGL_BAD_MATCH);
+ return false;
+ }
+
+ const Caps &caps = display->getCaps();
+
+ EGLAttrib textureFormat = attributes.get(EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE);
+ EGLAttrib textureTarget = attributes.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE);
+
+ if ((textureFormat != EGL_NO_TEXTURE && textureTarget == EGL_NO_TEXTURE) ||
+ (textureFormat == EGL_NO_TEXTURE && textureTarget != EGL_NO_TEXTURE))
+ {
+ val->setError(EGL_BAD_MATCH);
+ return false;
+ }
+
+ if ((textureFormat == EGL_TEXTURE_RGB && config->bindToTextureRGB != EGL_TRUE) ||
+ (textureFormat == EGL_TEXTURE_RGBA && config->bindToTextureRGBA != EGL_TRUE))
+ {
+ val->setError(EGL_BAD_ATTRIBUTE);
+ return false;
+ }
+
+ EGLint width = static_cast<EGLint>(attributes.get(EGL_WIDTH, 0));
+ EGLint height = static_cast<EGLint>(attributes.get(EGL_HEIGHT, 0));
+ if (textureFormat != EGL_NO_TEXTURE && !caps.textureNPOT &&
+ (!gl::isPow2(width) || !gl::isPow2(height)))
+ {
+ val->setError(EGL_BAD_MATCH);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateCreatePbufferFromClientBuffer(const ValidationContext *val,
+ const Display *display,
+ EGLenum buftype,
+ EGLClientBuffer buffer,
+ const Config *config,
+ const AttributeMap &attributes)
+{
+ ANGLE_VALIDATION_TRY(ValidateConfig(val, display, config));
+
+ const DisplayExtensions &displayExtensions = display->getExtensions();
+
+ attributes.initializeWithoutValidation();
+
+ switch (buftype)
+ {
+ case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE:
+ if (!displayExtensions.d3dShareHandleClientBuffer)
+ {
+ val->setError(EGL_BAD_PARAMETER);
+ return false;
+ }
+ if (buffer == nullptr)
+ {
+ val->setError(EGL_BAD_PARAMETER);
+ return false;
+ }
+ break;
+
+ case EGL_D3D_TEXTURE_ANGLE:
+ if (!displayExtensions.d3dTextureClientBuffer)
+ {
+ val->setError(EGL_BAD_PARAMETER);
+ return false;
+ }
+ if (buffer == nullptr)
+ {
+ val->setError(EGL_BAD_PARAMETER);
+ return false;
+ }
+ break;
+
+ case EGL_IOSURFACE_ANGLE:
+ if (!displayExtensions.iosurfaceClientBuffer)
+ {
+ val->setError(EGL_BAD_PARAMETER,
+ "<buftype> EGL_IOSURFACE_ANGLE requires the "
+ "EGL_ANGLE_iosurface_client_buffer extension.");
+ return false;
+ }
+ if (buffer == nullptr)
+ {
+ val->setError(EGL_BAD_PARAMETER, "<buffer> must be non null");
+ return false;
+ }
+ break;
+ case EGL_EXTERNAL_SURFACE_ANGLE:
+ if (!display->getExtensions().externalContextAndSurface)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "Attribute "
+ "EGL_EXTERNAL_SURFACE_ANGLE requires "
+ "EGL_ANGLE_external_context_and_surface.");
+ return false;
+ }
+ if (buffer != nullptr)
+ {
+ val->setError(EGL_BAD_PARAMETER, "<buffer> must be null");
+ return false;
+ }
+ break;
+
+ default:
+ val->setError(EGL_BAD_PARAMETER);
+ return false;
+ }
+
+ for (AttributeMap::const_iterator attributeIter = attributes.begin();
+ attributeIter != attributes.end(); attributeIter++)
+ {
+ EGLAttrib attribute = attributeIter->first;
+ EGLAttrib value = attributeIter->second;
+
+ switch (attribute)
+ {
+ case EGL_WIDTH:
+ case EGL_HEIGHT:
+ if (buftype != EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE &&
+ buftype != EGL_D3D_TEXTURE_ANGLE && buftype != EGL_IOSURFACE_ANGLE &&
+ buftype != EGL_EXTERNAL_SURFACE_ANGLE)
+ {
+ val->setError(EGL_BAD_PARAMETER,
+ "Width and Height are not supported for this <buftype>");
+ return false;
+ }
+ if (value < 0)
+ {
+ val->setError(EGL_BAD_PARAMETER, "Width and Height must be positive");
+ return false;
+ }
+ break;
+
+ case EGL_TEXTURE_FORMAT:
+ switch (value)
+ {
+ case EGL_NO_TEXTURE:
+ case EGL_TEXTURE_RGB:
+ case EGL_TEXTURE_RGBA:
+ break;
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE, "Invalid value for EGL_TEXTURE_FORMAT");
+ return false;
+ }
+ break;
+
+ case EGL_TEXTURE_TARGET:
+ switch (value)
+ {
+ case EGL_NO_TEXTURE:
+ case EGL_TEXTURE_2D:
+ break;
+ case EGL_TEXTURE_RECTANGLE_ANGLE:
+ if (buftype != EGL_IOSURFACE_ANGLE)
+ {
+ val->setError(EGL_BAD_PARAMETER,
+ "<buftype> doesn't support rectangle texture targets");
+ return false;
+ }
+ break;
+
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE, "Invalid value for EGL_TEXTURE_TARGET");
+ return false;
+ }
+ break;
+
+ case EGL_MIPMAP_TEXTURE:
+ break;
+
+ case EGL_IOSURFACE_PLANE_ANGLE:
+ if (buftype != EGL_IOSURFACE_ANGLE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE, "<buftype> doesn't support iosurface plane");
+ return false;
+ }
+ break;
+
+ case EGL_TEXTURE_TYPE_ANGLE:
+ if (buftype != EGL_IOSURFACE_ANGLE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE, "<buftype> doesn't support texture type");
+ return false;
+ }
+ break;
+
+ case EGL_TEXTURE_INTERNAL_FORMAT_ANGLE:
+ if (buftype != EGL_IOSURFACE_ANGLE && buftype != EGL_D3D_TEXTURE_ANGLE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "<buftype> doesn't support texture internal format");
+ return false;
+ }
+ break;
+
+ case EGL_GL_COLORSPACE:
+ if (buftype != EGL_D3D_TEXTURE_ANGLE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "<buftype> doesn't support setting GL colorspace");
+ return false;
+ }
+ break;
+
+ case EGL_IOSURFACE_USAGE_HINT_ANGLE:
+ if (value & ~(EGL_IOSURFACE_READ_HINT_ANGLE | EGL_IOSURFACE_WRITE_HINT_ANGLE))
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "IOSurface usage hint must only contain READ or WRITE");
+ return false;
+ }
+ break;
+
+ case EGL_TEXTURE_OFFSET_X_ANGLE:
+ case EGL_TEXTURE_OFFSET_Y_ANGLE:
+ if (buftype != EGL_D3D_TEXTURE_ANGLE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "<buftype> doesn't support setting texture offset");
+ return false;
+ }
+ break;
+
+ case EGL_PROTECTED_CONTENT_EXT:
+ if (!displayExtensions.protectedContentEXT)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "Attribute EGL_PROTECTED_CONTEXT_EXT requires "
+ "extension EGL_EXT_protected_content.");
+ return false;
+ }
+ if (value != EGL_TRUE && value != EGL_FALSE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_PROTECTED_CONTENT_EXT must "
+ "be either EGL_TRUE or EGL_FALSE.");
+ return false;
+ }
+ break;
+
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE);
+ return false;
+ }
+ }
+
+ EGLAttrib colorspace = attributes.get(EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_LINEAR);
+ if (colorspace != EGL_GL_COLORSPACE_LINEAR && colorspace != EGL_GL_COLORSPACE_SRGB)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE, "invalid GL colorspace");
+ return false;
+ }
+
+ if (!(config->surfaceType & EGL_PBUFFER_BIT))
+ {
+ val->setError(EGL_BAD_MATCH);
+ return false;
+ }
+
+ EGLAttrib textureFormat = attributes.get(EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE);
+ EGLAttrib textureTarget = attributes.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE);
+ if ((textureFormat != EGL_NO_TEXTURE && textureTarget == EGL_NO_TEXTURE) ||
+ (textureFormat == EGL_NO_TEXTURE && textureTarget != EGL_NO_TEXTURE))
+ {
+ val->setError(EGL_BAD_MATCH);
+ return false;
+ }
+ if ((textureFormat == EGL_TEXTURE_RGB && config->bindToTextureRGB != EGL_TRUE) ||
+ (textureFormat == EGL_TEXTURE_RGBA && config->bindToTextureRGBA != EGL_TRUE))
+ {
+ // TODO(cwallez@chromium.org): For IOSurface pbuffers we require that EGL_TEXTURE_RGBA is
+ // set so that eglBindTexImage works. Normally this is only allowed if the config exposes
+ // the bindToTextureRGB/RGBA flag. This issue is that enabling this flags means that
+ // eglBindTexImage should also work for regular pbuffers which isn't implemented on macOS.
+ // Instead of adding the flag we special case the check here to be ignored for IOSurfaces.
+ // The TODO is to find a proper solution for this, maybe by implementing eglBindTexImage on
+ // OSX?
+ if (buftype != EGL_IOSURFACE_ANGLE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE);
+ return false;
+ }
+ }
+
+ if (buftype == EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE)
+ {
+ EGLint width = static_cast<EGLint>(attributes.get(EGL_WIDTH, 0));
+ EGLint height = static_cast<EGLint>(attributes.get(EGL_HEIGHT, 0));
+
+ if (width == 0 || height == 0)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE);
+ return false;
+ }
+
+ const Caps &caps = display->getCaps();
+ if (textureFormat != EGL_NO_TEXTURE && !caps.textureNPOT &&
+ (!gl::isPow2(width) || !gl::isPow2(height)))
+ {
+ val->setError(EGL_BAD_MATCH);
+ return false;
+ }
+ }
+
+ if (buftype == EGL_IOSURFACE_ANGLE)
+ {
+ if (static_cast<EGLenum>(textureTarget) != config->bindToTextureTarget)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_IOSURFACE requires the texture target to match the config");
+ return false;
+ }
+ if (textureFormat != EGL_TEXTURE_RGBA)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE, "EGL_IOSURFACE requires the EGL_TEXTURE_RGBA format");
+ return false;
+ }
+
+ if (!attributes.contains(EGL_WIDTH) || !attributes.contains(EGL_HEIGHT) ||
+ !attributes.contains(EGL_TEXTURE_FORMAT) ||
+ !attributes.contains(EGL_TEXTURE_TYPE_ANGLE) ||
+ !attributes.contains(EGL_TEXTURE_INTERNAL_FORMAT_ANGLE) ||
+ !attributes.contains(EGL_IOSURFACE_PLANE_ANGLE))
+ {
+ val->setError(EGL_BAD_PARAMETER, "Missing required attribute for EGL_IOSURFACE");
+ return false;
+ }
+ }
+
+ ANGLE_EGL_TRY_RETURN(val->eglThread,
+ display->validateClientBuffer(config, buftype, buffer, attributes),
+ val->entryPoint, val->labeledObject, false);
+
+ return true;
+}
+
+bool ValidateCreatePixmapSurface(const ValidationContext *val,
+ const Display *display,
+ const Config *config,
+ EGLNativePixmapType pixmap,
+ const AttributeMap &attributes)
+{
+ ANGLE_VALIDATION_TRY(ValidateConfig(val, display, config));
+
+ const DisplayExtensions &displayExtensions = display->getExtensions();
+
+ attributes.initializeWithoutValidation();
+
+ for (const auto &attributePair : attributes)
+ {
+ EGLAttrib attribute = attributePair.first;
+ EGLAttrib value = attributePair.second;
+
+ switch (attribute)
+ {
+ case EGL_GL_COLORSPACE:
+ ANGLE_VALIDATION_TRY(ValidateColorspaceAttribute(val, displayExtensions, value));
+ break;
+
+ case EGL_VG_COLORSPACE:
+ break;
+ case EGL_VG_ALPHA_FORMAT:
+ break;
+
+ case EGL_TEXTURE_FORMAT:
+ if (!displayExtensions.textureFromPixmapNOK)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE, "EGL_NOK_texture_from_pixmap is not enabled.");
+ return false;
+ }
+ switch (value)
+ {
+ case EGL_NO_TEXTURE:
+ case EGL_TEXTURE_RGB:
+ case EGL_TEXTURE_RGBA:
+ break;
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE);
+ return false;
+ }
+ break;
+
+ case EGL_TEXTURE_TARGET:
+ if (!displayExtensions.textureFromPixmapNOK)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE, "EGL_NOK_texture_from_pixmap is not enabled.");
+ return false;
+ }
+ switch (value)
+ {
+ case EGL_NO_TEXTURE:
+ case EGL_TEXTURE_2D:
+ break;
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE);
+ return false;
+ }
+ break;
+
+ case EGL_MIPMAP_TEXTURE:
+ if (!displayExtensions.textureFromPixmapNOK)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE, "EGL_NOK_texture_from_pixmap is not enabled.");
+ return false;
+ }
+ break;
+
+ case EGL_PROTECTED_CONTENT_EXT:
+ if (!displayExtensions.protectedContentEXT)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "Attribute EGL_PROTECTED_CONTEXT_EXT requires "
+ "extension EGL_EXT_protected_content.");
+ return false;
+ }
+ if (value != EGL_TRUE && value != EGL_FALSE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_PROTECTED_CONTENT_EXT must "
+ "be either EGL_TRUE or EGL_FALSE.");
+ return false;
+ }
+ break;
+
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE, "Unknown attribute: 0x%04" PRIxPTR, attribute);
+ return false;
+ }
+ }
+
+ if (!(config->surfaceType & EGL_PIXMAP_BIT))
+ {
+ val->setError(EGL_BAD_MATCH, "Congfig does not suport pixmaps.");
+ return false;
+ }
+
+ ANGLE_EGL_TRY_RETURN(val->eglThread, display->valdiatePixmap(config, pixmap, attributes),
+ val->entryPoint, val->labeledObject, false);
+
+ return true;
+}
+
+bool ValidateMakeCurrent(const ValidationContext *val,
+ const Display *display,
+ const Surface *draw,
+ const Surface *read,
+ const gl::Context *context)
+{
+ if (context == EGL_NO_CONTEXT && (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE))
+ {
+ val->setError(EGL_BAD_MATCH, "If ctx is EGL_NO_CONTEXT, surfaces must be EGL_NO_SURFACE");
+ return false;
+ }
+
+ // If ctx is EGL_NO_CONTEXT and either draw or read are not EGL_NO_SURFACE, an EGL_BAD_MATCH
+ // error is generated. EGL_KHR_surfaceless_context allows both surfaces to be EGL_NO_SURFACE.
+ if (context != EGL_NO_CONTEXT && (draw == EGL_NO_SURFACE || read == EGL_NO_SURFACE))
+ {
+ if (display->getExtensions().surfacelessContext)
+ {
+ if ((draw == EGL_NO_SURFACE) != (read == EGL_NO_SURFACE))
+ {
+ val->setError(EGL_BAD_MATCH,
+ "If ctx is not EGL_NOT_CONTEXT, draw or read must "
+ "both be EGL_NO_SURFACE, or both not");
+ return false;
+ }
+ }
+ else
+ {
+ val->setError(EGL_BAD_MATCH,
+ "If ctx is not EGL_NO_CONTEXT, surfaces must not be EGL_NO_SURFACE");
+ return false;
+ }
+ }
+
+ // If either of draw or read is a valid surface and the other is EGL_NO_SURFACE, an
+ // EGL_BAD_MATCH error is generated.
+ if ((read == EGL_NO_SURFACE) != (draw == EGL_NO_SURFACE))
+ {
+ val->setError(EGL_BAD_MATCH,
+ "read and draw must both be valid surfaces, or both be EGL_NO_SURFACE");
+ return false;
+ }
+
+ if (display == EGL_NO_DISPLAY || !Display::isValidDisplay(display))
+ {
+ val->setError(EGL_BAD_DISPLAY, "'dpy' not a valid EGLDisplay handle");
+ return false;
+ }
+
+ // EGL 1.5 spec: dpy can be uninitialized if all other parameters are null
+ if (!display->isInitialized() &&
+ (context != EGL_NO_CONTEXT || draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE))
+ {
+ val->setError(EGL_NOT_INITIALIZED, "'dpy' not initialized");
+ return false;
+ }
+
+ if (context != EGL_NO_CONTEXT)
+ {
+ ANGLE_VALIDATION_TRY(ValidateContext(val, display, context));
+ }
+
+ if (display->isInitialized() && display->isDeviceLost())
+ {
+ val->setError(EGL_CONTEXT_LOST);
+ return false;
+ }
+
+ if (draw != EGL_NO_SURFACE)
+ {
+ ANGLE_VALIDATION_TRY(ValidateSurface(val, display, draw));
+ }
+
+ if (read != EGL_NO_SURFACE)
+ {
+ ANGLE_VALIDATION_TRY(ValidateSurface(val, display, read));
+ ANGLE_VALIDATION_TRY(ValidateCompatibleSurface(val, display, context, read));
+ }
+
+ if (draw != read)
+ {
+ if (draw)
+ {
+ ANGLE_VALIDATION_TRY(ValidateCompatibleSurface(val, display, context, draw));
+ }
+ if (read)
+ {
+ ANGLE_VALIDATION_TRY(ValidateCompatibleSurface(val, display, context, read));
+ }
+ }
+ return true;
+}
+
+bool ValidateCreateImage(const ValidationContext *val,
+ const Display *display,
+ const gl::Context *context,
+ EGLenum target,
+ EGLClientBuffer buffer,
+ const AttributeMap &attributes)
+{
+
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+
+ attributes.initializeWithoutValidation();
+
+ const DisplayExtensions &displayExtensions = display->getExtensions();
+
+ // TODO(geofflang): Complete validation from EGL_KHR_image_base:
+ // If the resource specified by <dpy>, <ctx>, <target>, <buffer> and <attrib_list> is itself an
+ // EGLImage sibling, the error EGL_BAD_ACCESS is generated.
+
+ for (AttributeMap::const_iterator attributeIter = attributes.begin();
+ attributeIter != attributes.end(); attributeIter++)
+ {
+ EGLAttrib attribute = attributeIter->first;
+ EGLAttrib value = attributeIter->second;
+
+ switch (attribute)
+ {
+ case EGL_IMAGE_PRESERVED:
+ switch (value)
+ {
+ case EGL_TRUE:
+ case EGL_FALSE:
+ break;
+
+ default:
+ val->setError(EGL_BAD_PARAMETER,
+ "EGL_IMAGE_PRESERVED must be EGL_TRUE or EGL_FALSE.");
+ return false;
+ }
+ break;
+
+ case EGL_GL_TEXTURE_LEVEL:
+ if (!displayExtensions.glTexture2DImage &&
+ !displayExtensions.glTextureCubemapImage && !displayExtensions.glTexture3DImage)
+ {
+ val->setError(EGL_BAD_PARAMETER,
+ "EGL_GL_TEXTURE_LEVEL cannot be used "
+ "without KHR_gl_texture_*_image support.");
+ return false;
+ }
+
+ if (value < 0)
+ {
+ val->setError(EGL_BAD_PARAMETER, "EGL_GL_TEXTURE_LEVEL cannot be negative.");
+ return false;
+ }
+ break;
+
+ case EGL_GL_TEXTURE_ZOFFSET:
+ if (!displayExtensions.glTexture3DImage)
+ {
+ val->setError(EGL_BAD_PARAMETER,
+ "EGL_GL_TEXTURE_ZOFFSET cannot be used "
+ "without KHR_gl_texture_3D_image support.");
+ return false;
+ }
+ break;
+
+ case EGL_GL_COLORSPACE:
+ if (!displayExtensions.glColorspace)
+ {
+ val->setError(EGL_BAD_PARAMETER,
+ "EGL_GL_COLORSPACE cannot be used "
+ "without EGL_KHR_gl_colorspace support.");
+ return false;
+ }
+ switch (value)
+ {
+ case EGL_GL_COLORSPACE_DEFAULT_EXT:
+ break;
+ default:
+ ANGLE_VALIDATION_TRY(
+ ValidateColorspaceAttribute(val, displayExtensions, value));
+ break;
+ }
+ break;
+
+ case EGL_TEXTURE_INTERNAL_FORMAT_ANGLE:
+ if (!displayExtensions.imageD3D11Texture && !displayExtensions.vulkanImageANGLE)
+ {
+ val->setError(
+ EGL_BAD_PARAMETER,
+ "EGL_TEXTURE_INTERNAL_FORMAT_ANGLE cannot be used without "
+ "EGL_ANGLE_image_d3d11_texture or EGL_ANGLE_vulkan_image support.");
+ return false;
+ }
+ break;
+
+ case EGL_D3D11_TEXTURE_PLANE_ANGLE:
+ if (!displayExtensions.imageD3D11Texture)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_D3D11_TEXTURE_PLANE_ANGLE cannot be used without "
+ "EGL_ANGLE_image_d3d11_texture support.");
+ return false;
+ }
+ break;
+
+ case EGL_D3D11_TEXTURE_ARRAY_SLICE_ANGLE:
+ if (!displayExtensions.imageD3D11Texture)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_D3D11_TEXTURE_ARRAY_SLICE_ANGLE cannot be used without "
+ "EGL_ANGLE_image_d3d11_texture support.");
+ return false;
+ }
+ break;
+
+ case EGL_WIDTH:
+ case EGL_HEIGHT:
+ if (target != EGL_LINUX_DMA_BUF_EXT)
+ {
+ val->setError(
+ EGL_BAD_PARAMETER,
+ "Parameter cannot be used if target is not EGL_LINUX_DMA_BUF_EXT");
+ return false;
+ }
+ break;
+
+ case EGL_LINUX_DRM_FOURCC_EXT:
+ case EGL_DMA_BUF_PLANE0_FD_EXT:
+ case EGL_DMA_BUF_PLANE0_OFFSET_EXT:
+ case EGL_DMA_BUF_PLANE0_PITCH_EXT:
+ case EGL_DMA_BUF_PLANE1_FD_EXT:
+ case EGL_DMA_BUF_PLANE1_OFFSET_EXT:
+ case EGL_DMA_BUF_PLANE1_PITCH_EXT:
+ case EGL_DMA_BUF_PLANE2_FD_EXT:
+ case EGL_DMA_BUF_PLANE2_OFFSET_EXT:
+ case EGL_DMA_BUF_PLANE2_PITCH_EXT:
+ if (!displayExtensions.imageDmaBufImportEXT)
+ {
+ val->setError(EGL_BAD_PARAMETER,
+ "Parameter cannot be used without "
+ "EGL_EXT_image_dma_buf_import support.");
+ return false;
+ }
+ break;
+
+ case EGL_YUV_COLOR_SPACE_HINT_EXT:
+ if (!displayExtensions.imageDmaBufImportEXT)
+ {
+ val->setError(EGL_BAD_PARAMETER,
+ "Parameter cannot be used without "
+ "EGL_EXT_image_dma_buf_import support.");
+ return false;
+ }
+
+ switch (value)
+ {
+ case EGL_ITU_REC601_EXT:
+ case EGL_ITU_REC709_EXT:
+ case EGL_ITU_REC2020_EXT:
+ break;
+
+ default:
+ val->setError(EGL_BAD_PARAMETER,
+ "Invalid value for EGL_YUV_COLOR_SPACE_HINT_EXT.");
+ return false;
+ }
+ break;
+
+ case EGL_SAMPLE_RANGE_HINT_EXT:
+ if (!displayExtensions.imageDmaBufImportEXT)
+ {
+ val->setError(EGL_BAD_PARAMETER,
+ "Parameter cannot be used without "
+ "EGL_EXT_image_dma_buf_import support.");
+ return false;
+ }
+
+ switch (value)
+ {
+ case EGL_YUV_FULL_RANGE_EXT:
+ case EGL_YUV_NARROW_RANGE_EXT:
+ break;
+
+ default:
+ val->setError(EGL_BAD_PARAMETER,
+ "Invalid value for EGL_SAMPLE_RANGE_HINT_EXT.");
+ return false;
+ }
+ break;
+
+ case EGL_YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT:
+ case EGL_YUV_CHROMA_VERTICAL_SITING_HINT_EXT:
+ if (!displayExtensions.imageDmaBufImportEXT)
+ {
+ val->setError(EGL_BAD_PARAMETER,
+ "Parameter cannot be used without "
+ "EGL_EXT_image_dma_buf_import support.");
+ return false;
+ }
+
+ switch (value)
+ {
+ case EGL_YUV_CHROMA_SITING_0_EXT:
+ case EGL_YUV_CHROMA_SITING_0_5_EXT:
+ break;
+
+ default:
+ val->setError(
+ EGL_BAD_PARAMETER,
+ "Invalid value for EGL_YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT or "
+ "EGL_YUV_CHROMA_VERTICAL_SITING_HINT_EXT.");
+ return false;
+ }
+ break;
+
+ case EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT:
+ case EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT:
+ case EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT:
+ case EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT:
+ case EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT:
+ case EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT:
+ case EGL_DMA_BUF_PLANE3_FD_EXT:
+ case EGL_DMA_BUF_PLANE3_OFFSET_EXT:
+ case EGL_DMA_BUF_PLANE3_PITCH_EXT:
+ case EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT:
+ case EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT:
+ if (!displayExtensions.imageDmaBufImportModifiersEXT)
+ {
+ val->setError(EGL_BAD_PARAMETER,
+ "Parameter cannot be used without "
+ "EGL_EXT_image_dma_buf_import_modifiers support.");
+ return false;
+ }
+ break;
+
+ case EGL_PROTECTED_CONTENT_EXT:
+ if (!displayExtensions.protectedContentEXT)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "Attribute EGL_PROTECTED_CONTEXT_EXT requires "
+ "extension EGL_EXT_protected_content.");
+ return false;
+ }
+ if (value != EGL_TRUE && value != EGL_FALSE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_PROTECTED_CONTENT_EXT must "
+ "be either EGL_TRUE or EGL_FALSE.");
+ return false;
+ }
+ break;
+
+ case EGL_VULKAN_IMAGE_CREATE_INFO_HI_ANGLE:
+ case EGL_VULKAN_IMAGE_CREATE_INFO_LO_ANGLE:
+ if (!displayExtensions.vulkanImageANGLE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "Attribute EGL_VULKAN_IMAGE_CREATE_INFO_{HI,LO}_ANGLE require "
+ "extension EGL_ANGLE_vulkan_image.");
+ return false;
+ }
+ break;
+
+ default:
+ val->setError(EGL_BAD_PARAMETER, "invalid attribute: 0x%04" PRIxPTR "X", attribute);
+ return false;
+ }
+ }
+
+ switch (target)
+ {
+ case EGL_GL_TEXTURE_2D:
+ {
+ if (!displayExtensions.glTexture2DImage)
+ {
+ val->setError(EGL_BAD_PARAMETER, "KHR_gl_texture_2D_image not supported.");
+ return false;
+ }
+
+ if (buffer == 0)
+ {
+ val->setError(EGL_BAD_PARAMETER,
+ "buffer cannot reference a 2D texture with the name 0.");
+ return false;
+ }
+
+ ANGLE_VALIDATION_TRY(ValidateContext(val, display, context));
+ const gl::Texture *texture =
+ context->getTexture({egl_gl::EGLClientBufferToGLObjectHandle(buffer)});
+ if (texture == nullptr || texture->getType() != gl::TextureType::_2D)
+ {
+ val->setError(EGL_BAD_PARAMETER, "target is not a 2D texture.");
+ return false;
+ }
+
+ if (texture->getBoundSurface() != nullptr)
+ {
+ val->setError(EGL_BAD_ACCESS, "texture has a surface bound to it.");
+ return false;
+ }
+
+ EGLAttrib level = attributes.get(EGL_GL_TEXTURE_LEVEL, 0);
+ if (texture->getWidth(gl::TextureTarget::_2D, static_cast<size_t>(level)) == 0 ||
+ texture->getHeight(gl::TextureTarget::_2D, static_cast<size_t>(level)) == 0)
+ {
+ val->setError(EGL_BAD_PARAMETER,
+ "target 2D texture does not have a valid size at specified level.");
+ return false;
+ }
+
+ bool protectedContentAttrib =
+ (attributes.getAsInt(EGL_PROTECTED_CONTENT_EXT, EGL_FALSE) != EGL_FALSE);
+ if (protectedContentAttrib != texture->hasProtectedContent())
+ {
+ val->setError(EGL_BAD_PARAMETER,
+ "EGL_PROTECTED_CONTENT_EXT attribute does not match protected state "
+ "of target.");
+ return false;
+ }
+
+ ANGLE_VALIDATION_TRY(ValidateCreateImageMipLevelCommon(val, context, texture, level));
+ }
+ break;
+
+ case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+ case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+ case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ {
+ if (!displayExtensions.glTextureCubemapImage)
+ {
+ val->setError(EGL_BAD_PARAMETER, "KHR_gl_texture_cubemap_image not supported.");
+ return false;
+ }
+
+ if (buffer == 0)
+ {
+ val->setError(EGL_BAD_PARAMETER,
+ "buffer cannot reference a cubemap texture with the name 0.");
+ return false;
+ }
+
+ ANGLE_VALIDATION_TRY(ValidateContext(val, display, context));
+ const gl::Texture *texture =
+ context->getTexture({egl_gl::EGLClientBufferToGLObjectHandle(buffer)});
+ if (texture == nullptr || texture->getType() != gl::TextureType::CubeMap)
+ {
+ val->setError(EGL_BAD_PARAMETER, "target is not a cubemap texture.");
+ return false;
+ }
+
+ if (texture->getBoundSurface() != nullptr)
+ {
+ val->setError(EGL_BAD_ACCESS, "texture has a surface bound to it.");
+ return false;
+ }
+
+ EGLAttrib level = attributes.get(EGL_GL_TEXTURE_LEVEL, 0);
+ gl::TextureTarget cubeMapFace = egl_gl::EGLCubeMapTargetToCubeMapTarget(target);
+ if (texture->getWidth(cubeMapFace, static_cast<size_t>(level)) == 0 ||
+ texture->getHeight(cubeMapFace, static_cast<size_t>(level)) == 0)
+ {
+ val->setError(EGL_BAD_PARAMETER,
+ "target cubemap texture does not have a valid "
+ "size at specified level and face.");
+ return false;
+ }
+
+ ANGLE_VALIDATION_TRY(ValidateCreateImageMipLevelCommon(val, context, texture, level));
+
+ if (level == 0 && !texture->isMipmapComplete() &&
+ CubeTextureHasUnspecifiedLevel0Face(texture))
+ {
+ val->setError(EGL_BAD_PARAMETER,
+ "if level is zero and the texture is incomplete, "
+ "it must have all of its faces specified at level "
+ "zero.");
+ return false;
+ }
+
+ bool protectedContentAttrib =
+ (attributes.getAsInt(EGL_PROTECTED_CONTENT_EXT, EGL_FALSE) != EGL_FALSE);
+ if (protectedContentAttrib != texture->hasProtectedContent())
+ {
+ val->setError(EGL_BAD_PARAMETER,
+ "EGL_PROTECTED_CONTENT_EXT attribute does not match protected state "
+ "of target.");
+ return false;
+ }
+ }
+ break;
+
+ case EGL_GL_TEXTURE_3D:
+ {
+ if (!displayExtensions.glTexture3DImage)
+ {
+ val->setError(EGL_BAD_PARAMETER, "KHR_gl_texture_3D_image not supported.");
+ return false;
+ }
+
+ if (buffer == 0)
+ {
+ val->setError(EGL_BAD_PARAMETER,
+ "buffer cannot reference a 3D texture with the name 0.");
+ return false;
+ }
+
+ ANGLE_VALIDATION_TRY(ValidateContext(val, display, context));
+ const gl::Texture *texture =
+ context->getTexture({egl_gl::EGLClientBufferToGLObjectHandle(buffer)});
+ if (texture == nullptr || texture->getType() != gl::TextureType::_3D)
+ {
+ val->setError(EGL_BAD_PARAMETER, "target is not a 3D texture.");
+ return false;
+ }
+
+ if (texture->getBoundSurface() != nullptr)
+ {
+ val->setError(EGL_BAD_ACCESS, "texture has a surface bound to it.");
+ return false;
+ }
+
+ EGLAttrib level = attributes.get(EGL_GL_TEXTURE_LEVEL, 0);
+ EGLAttrib zOffset = attributes.get(EGL_GL_TEXTURE_ZOFFSET, 0);
+ if (texture->getWidth(gl::TextureTarget::_3D, static_cast<size_t>(level)) == 0 ||
+ texture->getHeight(gl::TextureTarget::_3D, static_cast<size_t>(level)) == 0 ||
+ texture->getDepth(gl::TextureTarget::_3D, static_cast<size_t>(level)) == 0)
+ {
+ val->setError(EGL_BAD_PARAMETER,
+ "target 3D texture does not have a valid size at specified level.");
+ return false;
+ }
+
+ if (static_cast<size_t>(zOffset) >=
+ texture->getDepth(gl::TextureTarget::_3D, static_cast<size_t>(level)))
+ {
+ val->setError(EGL_BAD_PARAMETER,
+ "target 3D texture does not have enough layers "
+ "for the specified Z offset at the specified "
+ "level.");
+ return false;
+ }
+
+ bool protectedContentAttrib =
+ (attributes.getAsInt(EGL_PROTECTED_CONTENT_EXT, EGL_FALSE) != EGL_FALSE);
+ if (protectedContentAttrib != texture->hasProtectedContent())
+ {
+ val->setError(EGL_BAD_PARAMETER,
+ "EGL_PROTECTED_CONTENT_EXT attribute does not match protected state "
+ "of target.");
+ return false;
+ }
+
+ ANGLE_VALIDATION_TRY(ValidateCreateImageMipLevelCommon(val, context, texture, level));
+ }
+ break;
+
+ case EGL_GL_RENDERBUFFER:
+ {
+ if (!displayExtensions.glRenderbufferImage)
+ {
+ val->setError(EGL_BAD_PARAMETER, "KHR_gl_renderbuffer_image not supported.");
+ return false;
+ }
+
+ if (attributes.contains(EGL_GL_TEXTURE_LEVEL))
+ {
+ val->setError(EGL_BAD_PARAMETER,
+ "EGL_GL_TEXTURE_LEVEL cannot be used in "
+ "conjunction with a renderbuffer target.");
+ return false;
+ }
+
+ if (buffer == 0)
+ {
+ val->setError(EGL_BAD_PARAMETER,
+ "buffer cannot reference a renderbuffer with the name 0.");
+ return false;
+ }
+
+ ANGLE_VALIDATION_TRY(ValidateContext(val, display, context));
+ const gl::Renderbuffer *renderbuffer =
+ context->getRenderbuffer({egl_gl::EGLClientBufferToGLObjectHandle(buffer)});
+ if (renderbuffer == nullptr)
+ {
+ val->setError(EGL_BAD_PARAMETER, "target is not a renderbuffer.");
+ return false;
+ }
+
+ if (renderbuffer->getSamples() > 0)
+ {
+ val->setError(EGL_BAD_PARAMETER, "target renderbuffer cannot be multisampled.");
+ return false;
+ }
+
+ bool protectedContentAttrib =
+ (attributes.getAsInt(EGL_PROTECTED_CONTENT_EXT, EGL_FALSE) != EGL_FALSE);
+ if (protectedContentAttrib != renderbuffer->hasProtectedContent())
+ {
+ val->setError(EGL_BAD_ACCESS,
+ "EGL_PROTECTED_CONTENT_EXT attribute does not match protected state "
+ "of target.");
+ return false;
+ }
+ }
+ break;
+
+ case EGL_NATIVE_BUFFER_ANDROID:
+ {
+ if (!displayExtensions.imageNativeBuffer)
+ {
+ val->setError(EGL_BAD_PARAMETER, "EGL_ANDROID_image_native_buffer not supported.");
+ return false;
+ }
+
+ if (context != nullptr)
+ {
+ val->setError(EGL_BAD_CONTEXT, "ctx must be EGL_NO_CONTEXT.");
+ return false;
+ }
+
+ ANGLE_EGL_TRY_RETURN(
+ val->eglThread,
+ display->validateImageClientBuffer(context, target, buffer, attributes),
+ val->entryPoint, val->labeledObject, false);
+ }
+ break;
+
+ case EGL_D3D11_TEXTURE_ANGLE:
+ if (!displayExtensions.imageD3D11Texture)
+ {
+ val->setError(EGL_BAD_PARAMETER, "EGL_ANGLE_image_d3d11_texture not supported.");
+ return false;
+ }
+
+ if (context != nullptr)
+ {
+ val->setError(EGL_BAD_CONTEXT, "ctx must be EGL_NO_CONTEXT.");
+ return false;
+ }
+
+ ANGLE_EGL_TRY_RETURN(
+ val->eglThread,
+ display->validateImageClientBuffer(context, target, buffer, attributes),
+ val->entryPoint, val->labeledObject, false);
+ break;
+
+ case EGL_LINUX_DMA_BUF_EXT:
+ if (!displayExtensions.imageDmaBufImportEXT)
+ {
+ val->setError(EGL_BAD_PARAMETER, "EGL_EXT_image_dma_buf_import not supported.");
+ return false;
+ }
+
+ if (context != nullptr)
+ {
+ val->setError(EGL_BAD_CONTEXT, "ctx must be EGL_NO_CONTEXT.");
+ return false;
+ }
+
+ if (buffer != nullptr)
+ {
+ val->setError(EGL_BAD_PARAMETER, "buffer must be NULL.");
+ return false;
+ }
+
+ {
+ EGLenum kRequiredParameters[] = {EGL_WIDTH,
+ EGL_HEIGHT,
+ EGL_LINUX_DRM_FOURCC_EXT,
+ EGL_DMA_BUF_PLANE0_FD_EXT,
+ EGL_DMA_BUF_PLANE0_OFFSET_EXT,
+ EGL_DMA_BUF_PLANE0_PITCH_EXT};
+ for (EGLenum requiredParameter : kRequiredParameters)
+ {
+ if (!attributes.contains(requiredParameter))
+ {
+ val->setError(EGL_BAD_PARAMETER,
+ "Missing required parameter 0x%X for image target "
+ "EGL_LINUX_DMA_BUF_EXT.",
+ requiredParameter);
+ return false;
+ }
+ }
+
+ bool containPlane0ModifierLo =
+ attributes.contains(EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT);
+ bool containPlane0ModifierHi =
+ attributes.contains(EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT);
+ bool containPlane1ModifierLo =
+ attributes.contains(EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT);
+ bool containPlane1ModifierHi =
+ attributes.contains(EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT);
+ bool containPlane2ModifierLo =
+ attributes.contains(EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT);
+ bool containPlane2ModifierHi =
+ attributes.contains(EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT);
+ bool containPlane3ModifierLo =
+ attributes.contains(EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT);
+ bool containPlane3ModifierHi =
+ attributes.contains(EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT);
+ if ((containPlane0ModifierLo ^ containPlane0ModifierHi) ||
+ (containPlane1ModifierLo ^ containPlane1ModifierHi) ||
+ (containPlane2ModifierLo ^ containPlane2ModifierHi) ||
+ (containPlane3ModifierLo ^ containPlane3ModifierHi))
+ {
+ val->setError(
+ EGL_BAD_PARAMETER,
+ "the list of attributes contains EGL_DMA_BUF_PLANE*_MODIFIER_LO_EXT "
+ "but not EGL_DMA_BUF_PLANE*_MODIFIER_HI_EXT or vice versa.");
+ return false;
+ }
+ }
+ break;
+
+ case EGL_METAL_TEXTURE_ANGLE:
+ if (!displayExtensions.mtlTextureClientBuffer)
+ {
+ val->setError(EGL_BAD_PARAMETER,
+ "EGL_ANGLE_metal_texture_client_buffer not supported.");
+ return false;
+ }
+
+ if (context != nullptr)
+ {
+ val->setError(EGL_BAD_CONTEXT, "ctx must be EGL_NO_CONTEXT.");
+ return false;
+ }
+
+ ANGLE_EGL_TRY_RETURN(
+ val->eglThread,
+ display->validateImageClientBuffer(context, target, buffer, attributes),
+ val->entryPoint, val->labeledObject, false);
+ break;
+ case EGL_VULKAN_IMAGE_ANGLE:
+ if (!displayExtensions.vulkanImageANGLE)
+ {
+ val->setError(EGL_BAD_PARAMETER, "EGL_ANGLE_vulkan_image not supported.");
+ return false;
+ }
+
+ if (context != nullptr)
+ {
+ val->setError(EGL_BAD_CONTEXT, "ctx must be EGL_NO_CONTEXT.");
+ return false;
+ }
+
+ {
+ const EGLenum kRequiredParameters[] = {
+ EGL_VULKAN_IMAGE_CREATE_INFO_HI_ANGLE,
+ EGL_VULKAN_IMAGE_CREATE_INFO_LO_ANGLE,
+ };
+ for (EGLenum requiredParameter : kRequiredParameters)
+ {
+ if (!attributes.contains(requiredParameter))
+ {
+ val->setError(EGL_BAD_PARAMETER,
+ "Missing required parameter 0x%X for image target "
+ "EGL_VULKAN_IMAGE_ANGLE.",
+ requiredParameter);
+ return false;
+ }
+ }
+ }
+
+ ANGLE_EGL_TRY_RETURN(
+ val->eglThread,
+ display->validateImageClientBuffer(context, target, buffer, attributes),
+ val->entryPoint, val->labeledObject, false);
+ break;
+ default:
+ val->setError(EGL_BAD_PARAMETER, "invalid target: 0x%X", target);
+ return false;
+ }
+
+ if (attributes.contains(EGL_GL_TEXTURE_ZOFFSET) && target != EGL_GL_TEXTURE_3D)
+ {
+ val->setError(EGL_BAD_PARAMETER,
+ "EGL_GL_TEXTURE_ZOFFSET must be used with a 3D texture target.");
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateDestroyImage(const ValidationContext *val, const Display *display, const Image *image)
+{
+ ANGLE_VALIDATION_TRY(ValidateImage(val, display, image));
+
+ return true;
+}
+
+bool ValidateCreateImageKHR(const ValidationContext *val,
+ const Display *display,
+ const gl::Context *context,
+ EGLenum target,
+ EGLClientBuffer buffer,
+ const AttributeMap &attributes)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+
+ if (!display->getExtensions().imageBase && !display->getExtensions().image)
+ {
+ // It is out of spec what happens when calling an extension function when the extension is
+ // not available.
+ // EGL_BAD_DISPLAY seems like a reasonable error.
+ val->setError(EGL_BAD_DISPLAY, "EGL_KHR_image not supported.");
+ return false;
+ }
+
+ return ValidateCreateImage(val, display, context, target, buffer, attributes);
+}
+
+bool ValidateDestroyImageKHR(const ValidationContext *val,
+ const Display *display,
+ const Image *image)
+{
+ ANGLE_VALIDATION_TRY(ValidateImage(val, display, image));
+
+ if (!display->getExtensions().imageBase && !display->getExtensions().image)
+ {
+ // It is out of spec what happens when calling an extension function when the extension is
+ // not available.
+ // EGL_BAD_DISPLAY seems like a reasonable error.
+ val->setError(EGL_BAD_DISPLAY);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateCreateDeviceANGLE(const ValidationContext *val,
+ EGLint device_type,
+ const void *native_device,
+ const EGLAttrib *attrib_list)
+{
+ const ClientExtensions &clientExtensions = Display::GetClientExtensions();
+ if (!clientExtensions.deviceCreation)
+ {
+ val->setError(EGL_BAD_ACCESS, "Device creation extension not active");
+ return false;
+ }
+
+ if (attrib_list != nullptr && attrib_list[0] != EGL_NONE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE, "Invalid attrib_list parameter");
+ return false;
+ }
+
+ switch (device_type)
+ {
+ case EGL_D3D11_DEVICE_ANGLE:
+ if (!clientExtensions.deviceCreationD3D11)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE, "D3D11 device creation extension not active");
+ return false;
+ }
+ break;
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE, "Invalid device_type parameter");
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateReleaseDeviceANGLE(const ValidationContext *val, const Device *device)
+{
+ const ClientExtensions &clientExtensions = Display::GetClientExtensions();
+ if (!clientExtensions.deviceCreation)
+ {
+ val->setError(EGL_BAD_ACCESS, "Device creation extension not active");
+ return false;
+ }
+
+ if (device == EGL_NO_DEVICE_EXT || !Device::IsValidDevice(device))
+ {
+ val->setError(EGL_BAD_DEVICE_EXT, "Invalid device parameter");
+ return false;
+ }
+
+ Display *owningDisplay = device->getOwningDisplay();
+ if (owningDisplay != nullptr)
+ {
+ val->setError(EGL_BAD_DEVICE_EXT, "Device must have been created using eglCreateDevice");
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateCreateSync(const ValidationContext *val,
+ const Display *display,
+ EGLenum type,
+ const AttributeMap &attribs)
+{
+ return ValidateCreateSyncBase(val, display, type, attribs, false);
+}
+
+bool ValidateCreateSyncKHR(const ValidationContext *val,
+ const Display *display,
+ EGLenum type,
+ const AttributeMap &attribs)
+{
+ return ValidateCreateSyncBase(val, display, type, attribs, true);
+}
+
+bool ValidateDestroySync(const ValidationContext *val, const Display *display, const Sync *sync)
+{
+ ANGLE_VALIDATION_TRY(ValidateSync(val, display, sync));
+ return true;
+}
+
+bool ValidateDestroySyncKHR(const ValidationContext *val,
+ const Display *dpyPacked,
+ const Sync *syncPacked)
+{
+ return ValidateDestroySync(val, dpyPacked, syncPacked);
+}
+
+bool ValidateClientWaitSync(const ValidationContext *val,
+ const Display *display,
+ const Sync *sync,
+ EGLint flags,
+ EGLTime timeout)
+{
+ ANGLE_VALIDATION_TRY(ValidateSync(val, display, sync));
+ return true;
+}
+
+bool ValidateClientWaitSyncKHR(const ValidationContext *val,
+ const Display *dpyPacked,
+ const Sync *syncPacked,
+ EGLint flags,
+ EGLTimeKHR timeout)
+{
+ return ValidateClientWaitSync(val, dpyPacked, syncPacked, flags, timeout);
+}
+
+bool ValidateWaitSync(const ValidationContext *val,
+ const Display *display,
+ const Sync *sync,
+ EGLint flags)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+
+ const DisplayExtensions &extensions = display->getExtensions();
+ if (!extensions.waitSync)
+ {
+ val->setError(EGL_BAD_ACCESS, "EGL_KHR_wait_sync extension is not available");
+ return false;
+ }
+
+ ANGLE_VALIDATION_TRY(ValidateSync(val, display, sync));
+
+ gl::Context *context = val->eglThread->getContext();
+ if (context == nullptr)
+ {
+ val->setError(EGL_BAD_MATCH, "No context is current.");
+ return false;
+ }
+
+ if (!context->getExtensions().EGLSyncOES)
+ {
+ val->setError(EGL_BAD_MATCH,
+ "Server-side waits cannot be performed without "
+ "GL_OES_EGL_sync support.");
+ return false;
+ }
+
+ if (flags != 0)
+ {
+ val->setError(EGL_BAD_PARAMETER, "flags must be zero");
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateWaitSyncKHR(const ValidationContext *val,
+ const Display *dpyPacked,
+ const Sync *syncPacked,
+ EGLint flags)
+{
+ return ValidateWaitSync(val, dpyPacked, syncPacked, flags);
+}
+
+bool ValidateGetSyncAttrib(const ValidationContext *val,
+ const Display *display,
+ const Sync *sync,
+ EGLint attribute,
+ const EGLAttrib *value)
+{
+ if (value == nullptr)
+ {
+ val->setError(EGL_BAD_PARAMETER, "Invalid value parameter");
+ return false;
+ }
+ return ValidateGetSyncAttribBase(val, display, sync, attribute);
+}
+
+bool ValidateGetSyncAttribKHR(const ValidationContext *val,
+ const Display *display,
+ const Sync *sync,
+ EGLint attribute,
+ const EGLint *value)
+{
+ if (value == nullptr)
+ {
+ val->setError(EGL_BAD_PARAMETER, "Invalid value parameter");
+ return false;
+ }
+ return ValidateGetSyncAttribBase(val, display, sync, attribute);
+}
+
+bool ValidateCreateStreamKHR(const ValidationContext *val,
+ const Display *display,
+ const AttributeMap &attributes)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+
+ const DisplayExtensions &displayExtensions = display->getExtensions();
+ if (!displayExtensions.stream)
+ {
+ val->setError(EGL_BAD_ALLOC, "Stream extension not active");
+ return false;
+ }
+
+ attributes.initializeWithoutValidation();
+
+ for (const auto &attributeIter : attributes)
+ {
+ EGLAttrib attribute = attributeIter.first;
+ EGLAttrib value = attributeIter.second;
+
+ ANGLE_VALIDATION_TRY(ValidateStreamAttribute(val, attribute, value, displayExtensions));
+ }
+
+ return true;
+}
+
+bool ValidateDestroyStreamKHR(const ValidationContext *val,
+ const Display *display,
+ const Stream *stream)
+{
+ ANGLE_VALIDATION_TRY(ValidateStream(val, display, stream));
+ return true;
+}
+
+bool ValidateStreamAttribKHR(const ValidationContext *val,
+ const Display *display,
+ const Stream *stream,
+ EGLenum attribute,
+ EGLint value)
+{
+ ANGLE_VALIDATION_TRY(ValidateStream(val, display, stream));
+
+ if (stream->getState() == EGL_STREAM_STATE_DISCONNECTED_KHR)
+ {
+ val->setError(EGL_BAD_STATE_KHR, "Bad stream state");
+ return false;
+ }
+
+ return ValidateStreamAttribute(val, attribute, value, display->getExtensions());
+}
+
+bool ValidateQueryStreamKHR(const ValidationContext *val,
+ const Display *display,
+ const Stream *stream,
+ EGLenum attribute,
+ const EGLint *value)
+{
+ ANGLE_VALIDATION_TRY(ValidateStream(val, display, stream));
+
+ switch (attribute)
+ {
+ case EGL_STREAM_STATE_KHR:
+ case EGL_CONSUMER_LATENCY_USEC_KHR:
+ break;
+ case EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR:
+ if (!display->getExtensions().streamConsumerGLTexture)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE, "Consumer GLTexture extension not active");
+ return false;
+ }
+ break;
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE, "Invalid attribute");
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateQueryStreamu64KHR(const ValidationContext *val,
+ const Display *display,
+ const Stream *stream,
+ EGLenum attribute,
+ const EGLuint64KHR *value)
+{
+ ANGLE_VALIDATION_TRY(ValidateStream(val, display, stream));
+
+ switch (attribute)
+ {
+ case EGL_CONSUMER_FRAME_KHR:
+ case EGL_PRODUCER_FRAME_KHR:
+ break;
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE, "Invalid attribute");
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateStreamConsumerGLTextureExternalKHR(const ValidationContext *val,
+ const Display *display,
+ const Stream *stream)
+{
+ gl::Context *context = val->eglThread->getContext();
+ ANGLE_VALIDATION_TRY(ValidateContext(val, display, context));
+
+ const DisplayExtensions &displayExtensions = display->getExtensions();
+ if (!displayExtensions.streamConsumerGLTexture)
+ {
+ val->setError(EGL_BAD_ACCESS, "Stream consumer extension not active");
+ return false;
+ }
+
+ if (!context->getExtensions().EGLStreamConsumerExternalNV)
+ {
+ val->setError(EGL_BAD_ACCESS, "EGL stream consumer external GL extension not enabled");
+ return false;
+ }
+
+ if (stream == EGL_NO_STREAM_KHR || !display->isValidStream(stream))
+ {
+ val->setError(EGL_BAD_STREAM_KHR, "Invalid stream");
+ return false;
+ }
+
+ if (stream->getState() != EGL_STREAM_STATE_CREATED_KHR)
+ {
+ val->setError(EGL_BAD_STATE_KHR, "Invalid stream state");
+ return false;
+ }
+
+ // Lookup the texture and ensure it is correct
+ gl::Texture *texture = context->getState().getTargetTexture(gl::TextureType::External);
+ if (texture == nullptr || texture->id().value == 0)
+ {
+ val->setError(EGL_BAD_ACCESS, "No external texture bound");
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateStreamConsumerAcquireKHR(const ValidationContext *val,
+ const Display *display,
+ const Stream *stream)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+
+ const DisplayExtensions &displayExtensions = display->getExtensions();
+ if (!displayExtensions.streamConsumerGLTexture)
+ {
+ val->setError(EGL_BAD_ACCESS, "Stream consumer extension not active");
+ return false;
+ }
+
+ if (stream == EGL_NO_STREAM_KHR || !display->isValidStream(stream))
+ {
+ val->setError(EGL_BAD_STREAM_KHR, "Invalid stream");
+ return false;
+ }
+
+ gl::Context *context = val->eglThread->getContext();
+ if (!context)
+ {
+ val->setError(EGL_BAD_ACCESS, "No GL context current to calling thread.");
+ return false;
+ }
+
+ ANGLE_VALIDATION_TRY(ValidateContext(val, display, context));
+
+ if (!stream->isConsumerBoundToContext(context))
+ {
+ val->setError(EGL_BAD_ACCESS, "Current GL context not associated with stream consumer");
+ return false;
+ }
+
+ if (stream->getConsumerType() != Stream::ConsumerType::GLTextureRGB &&
+ stream->getConsumerType() != Stream::ConsumerType::GLTextureYUV)
+ {
+ val->setError(EGL_BAD_ACCESS, "Invalid stream consumer type");
+ return false;
+ }
+
+ // Note: technically EGL_STREAM_STATE_EMPTY_KHR is a valid state when the timeout is non-zero.
+ // However, the timeout is effectively ignored since it has no useful functionality with the
+ // current producers that are implemented, so we don't allow that state
+ if (stream->getState() != EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR &&
+ stream->getState() != EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR)
+ {
+ val->setError(EGL_BAD_STATE_KHR, "Invalid stream state");
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateStreamConsumerReleaseKHR(const ValidationContext *val,
+ const Display *display,
+ const Stream *stream)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+
+ const DisplayExtensions &displayExtensions = display->getExtensions();
+ if (!displayExtensions.streamConsumerGLTexture)
+ {
+ val->setError(EGL_BAD_ACCESS, "Stream consumer extension not active");
+ return false;
+ }
+
+ if (stream == EGL_NO_STREAM_KHR || !display->isValidStream(stream))
+ {
+ val->setError(EGL_BAD_STREAM_KHR, "Invalid stream");
+ return false;
+ }
+
+ gl::Context *context = val->eglThread->getContext();
+ if (!context)
+ {
+ val->setError(EGL_BAD_ACCESS, "No GL context current to calling thread.");
+ return false;
+ }
+
+ ANGLE_VALIDATION_TRY(ValidateContext(val, display, context));
+
+ if (!stream->isConsumerBoundToContext(context))
+ {
+ val->setError(EGL_BAD_ACCESS, "Current GL context not associated with stream consumer");
+ return false;
+ }
+
+ if (stream->getConsumerType() != Stream::ConsumerType::GLTextureRGB &&
+ stream->getConsumerType() != Stream::ConsumerType::GLTextureYUV)
+ {
+ val->setError(EGL_BAD_ACCESS, "Invalid stream consumer type");
+ return false;
+ }
+
+ if (stream->getState() != EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR &&
+ stream->getState() != EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR)
+ {
+ val->setError(EGL_BAD_STATE_KHR, "Invalid stream state");
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateStreamConsumerGLTextureExternalAttribsNV(const ValidationContext *val,
+ const Display *display,
+ const Stream *stream,
+ const AttributeMap &attribs)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+
+ const DisplayExtensions &displayExtensions = display->getExtensions();
+ if (!displayExtensions.streamConsumerGLTexture)
+ {
+ val->setError(EGL_BAD_ACCESS, "Stream consumer extension not active");
+ return false;
+ }
+
+ gl::Context *context = val->eglThread->getContext();
+ ANGLE_VALIDATION_TRY(ValidateContext(val, display, context));
+
+ // Although technically not a requirement in spec, the context needs to be checked for support
+ // for external textures or future logic will cause assertations. This extension is also
+ // effectively useless without external textures.
+ if (!context->getExtensions().EGLStreamConsumerExternalNV)
+ {
+ val->setError(EGL_BAD_ACCESS, "EGL stream consumer external GL extension not enabled");
+ return false;
+ }
+
+ if (stream == EGL_NO_STREAM_KHR || !display->isValidStream(stream))
+ {
+ val->setError(EGL_BAD_STREAM_KHR, "Invalid stream");
+ return false;
+ }
+
+ if (stream->getState() != EGL_STREAM_STATE_CREATED_KHR)
+ {
+ val->setError(EGL_BAD_STATE_KHR, "Invalid stream state");
+ return false;
+ }
+
+ const gl::Caps &glCaps = context->getCaps();
+
+ EGLAttrib colorBufferType = EGL_RGB_BUFFER;
+ EGLAttrib planeCount = -1;
+ EGLAttrib plane[3];
+ for (int i = 0; i < 3; i++)
+ {
+ plane[i] = -1;
+ }
+
+ attribs.initializeWithoutValidation();
+
+ for (const auto &attributeIter : attribs)
+ {
+ EGLAttrib attribute = attributeIter.first;
+ EGLAttrib value = attributeIter.second;
+
+ switch (attribute)
+ {
+ case EGL_COLOR_BUFFER_TYPE:
+ if (value != EGL_RGB_BUFFER && value != EGL_YUV_BUFFER_EXT)
+ {
+ val->setError(EGL_BAD_PARAMETER, "Invalid color buffer type");
+ return false;
+ }
+ colorBufferType = value;
+ break;
+ case EGL_YUV_NUMBER_OF_PLANES_EXT:
+ // planeCount = -1 is a tag for the default plane count so the value must be checked
+ // to be positive here to ensure future logic doesn't break on invalid negative
+ // inputs
+ if (value < 0)
+ {
+ val->setError(EGL_BAD_MATCH, "Invalid plane count");
+ return false;
+ }
+ planeCount = value;
+ break;
+ default:
+ if (attribute >= EGL_YUV_PLANE0_TEXTURE_UNIT_NV &&
+ attribute <= EGL_YUV_PLANE2_TEXTURE_UNIT_NV)
+ {
+ if ((value < 0 ||
+ value >= static_cast<EGLAttrib>(glCaps.maxCombinedTextureImageUnits)) &&
+ value != EGL_NONE)
+ {
+ val->setError(EGL_BAD_ACCESS, "Invalid texture unit");
+ return false;
+ }
+ plane[attribute - EGL_YUV_PLANE0_TEXTURE_UNIT_NV] = value;
+ }
+ else
+ {
+ val->setError(EGL_BAD_ATTRIBUTE, "Invalid attribute");
+ return false;
+ }
+ }
+ }
+
+ if (colorBufferType == EGL_RGB_BUFFER)
+ {
+ if (planeCount > 0)
+ {
+ val->setError(EGL_BAD_MATCH, "Plane count must be 0 for RGB buffer");
+ return false;
+ }
+ for (int i = 0; i < 3; i++)
+ {
+ if (plane[i] != -1)
+ {
+ val->setError(EGL_BAD_MATCH, "Planes cannot be specified");
+ return false;
+ }
+ }
+
+ // Lookup the texture and ensure it is correct
+ gl::Texture *texture = context->getState().getTargetTexture(gl::TextureType::External);
+ if (texture == nullptr || texture->id().value == 0)
+ {
+ val->setError(EGL_BAD_ACCESS, "No external texture bound");
+ return false;
+ }
+ }
+ else
+ {
+ if (planeCount == -1)
+ {
+ planeCount = 2;
+ }
+ if (planeCount < 1 || planeCount > 3)
+ {
+ val->setError(EGL_BAD_MATCH, "Invalid YUV plane count");
+ return false;
+ }
+ for (EGLAttrib i = planeCount; i < 3; i++)
+ {
+ if (plane[i] != -1)
+ {
+ val->setError(EGL_BAD_MATCH, "Invalid plane specified");
+ return false;
+ }
+ }
+
+ // Set to ensure no texture is referenced more than once
+ std::set<gl::Texture *> textureSet;
+ for (EGLAttrib i = 0; i < planeCount; i++)
+ {
+ if (plane[i] == -1)
+ {
+ val->setError(EGL_BAD_MATCH, "Not all planes specified");
+ return false;
+ }
+ if (plane[i] != EGL_NONE)
+ {
+ gl::Texture *texture = context->getState().getSamplerTexture(
+ static_cast<unsigned int>(plane[i]), gl::TextureType::External);
+ if (texture == nullptr || texture->id().value == 0)
+ {
+ val->setError(
+ EGL_BAD_ACCESS,
+ "No external texture bound at one or more specified texture units");
+ return false;
+ }
+ if (textureSet.find(texture) != textureSet.end())
+ {
+ val->setError(EGL_BAD_ACCESS, "Multiple planes bound to same texture object");
+ return false;
+ }
+ textureSet.insert(texture);
+ }
+ }
+ }
+
+ return true;
+}
+
+bool ValidateCreateStreamProducerD3DTextureANGLE(const ValidationContext *val,
+ const Display *display,
+ const Stream *stream,
+ const AttributeMap &attribs)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+
+ const DisplayExtensions &displayExtensions = display->getExtensions();
+ if (!displayExtensions.streamProducerD3DTexture)
+ {
+ val->setError(EGL_BAD_ACCESS, "Stream producer extension not active");
+ return false;
+ }
+
+ ANGLE_VALIDATION_TRY(ValidateStream(val, display, stream));
+
+ attribs.initializeWithoutValidation();
+
+ if (!attribs.isEmpty())
+ {
+ val->setError(EGL_BAD_ATTRIBUTE, "Invalid attribute");
+ return false;
+ }
+
+ if (stream->getState() != EGL_STREAM_STATE_CONNECTING_KHR)
+ {
+ val->setError(EGL_BAD_STATE_KHR, "Stream not in connecting state");
+ return false;
+ }
+
+ switch (stream->getConsumerType())
+ {
+ case Stream::ConsumerType::GLTextureYUV:
+ if (stream->getPlaneCount() != 2)
+ {
+ val->setError(EGL_BAD_MATCH, "Incompatible stream consumer type");
+ return false;
+ }
+ break;
+
+ case Stream::ConsumerType::GLTextureRGB:
+ if (stream->getPlaneCount() != 1)
+ {
+ val->setError(EGL_BAD_MATCH, "Incompatible stream consumer type");
+ return false;
+ }
+ break;
+
+ default:
+ val->setError(EGL_BAD_MATCH, "Incompatible stream consumer type");
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateStreamPostD3DTextureANGLE(const ValidationContext *val,
+ const Display *display,
+ const Stream *stream,
+ const void *texture,
+ const AttributeMap &attribs)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+
+ const DisplayExtensions &displayExtensions = display->getExtensions();
+ if (!displayExtensions.streamProducerD3DTexture)
+ {
+ val->setError(EGL_BAD_ACCESS, "Stream producer extension not active");
+ return false;
+ }
+
+ ANGLE_VALIDATION_TRY(ValidateStream(val, display, stream));
+
+ attribs.initializeWithoutValidation();
+
+ for (auto &attributeIter : attribs)
+ {
+ EGLAttrib attribute = attributeIter.first;
+ EGLAttrib value = attributeIter.second;
+
+ switch (attribute)
+ {
+ case EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE:
+ if (value < 0)
+ {
+ val->setError(EGL_BAD_PARAMETER, "Invalid subresource index");
+ return false;
+ }
+ break;
+ case EGL_NATIVE_BUFFER_PLANE_OFFSET_IMG:
+ if (value < 0)
+ {
+ val->setError(EGL_BAD_PARAMETER, "Invalid plane offset");
+ return false;
+ }
+ break;
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE, "Invalid attribute");
+ return false;
+ }
+ }
+
+ if (stream->getState() != EGL_STREAM_STATE_EMPTY_KHR &&
+ stream->getState() != EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR &&
+ stream->getState() != EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR)
+ {
+ val->setError(EGL_BAD_STATE_KHR, "Stream not fully configured");
+ return false;
+ }
+
+ if (stream->getProducerType() != Stream::ProducerType::D3D11Texture)
+ {
+ val->setError(EGL_BAD_MATCH, "Incompatible stream producer");
+ return false;
+ }
+
+ if (texture == nullptr)
+ {
+ val->setError(EGL_BAD_PARAMETER, "Texture is null");
+ return false;
+ }
+
+ ANGLE_EGL_TRY_RETURN(val->eglThread, stream->validateD3D11Texture(texture, attribs),
+ val->entryPoint, val->labeledObject, false);
+
+ return true;
+}
+
+bool ValidateSyncControlCHROMIUM(const ValidationContext *val,
+ const Display *display,
+ const Surface *eglSurface)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+ ANGLE_VALIDATION_TRY(ValidateSurface(val, display, eglSurface));
+
+ const DisplayExtensions &displayExtensions = display->getExtensions();
+ if (!displayExtensions.syncControlCHROMIUM)
+ {
+ val->setError(EGL_BAD_ACCESS, "syncControlCHROMIUM extension not active");
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateSyncControlRateANGLE(const ValidationContext *val,
+ const Display *display,
+ const Surface *eglSurface)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+ ANGLE_VALIDATION_TRY(ValidateSurface(val, display, eglSurface));
+
+ const DisplayExtensions &displayExtensions = display->getExtensions();
+ if (!displayExtensions.syncControlRateANGLE)
+ {
+ val->setError(EGL_BAD_ACCESS, "syncControlRateANGLE extension not active");
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetMscRateANGLE(const ValidationContext *val,
+ const Display *display,
+ const Surface *eglSurface,
+ const EGLint *numerator,
+ const EGLint *denominator)
+{
+ ANGLE_VALIDATION_TRY(ValidateSyncControlRateANGLE(val, display, eglSurface));
+
+ if (numerator == nullptr)
+ {
+ val->setError(EGL_BAD_PARAMETER, "numerator is null");
+ return false;
+ }
+ if (denominator == nullptr)
+ {
+ val->setError(EGL_BAD_PARAMETER, "denominator is null");
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetSyncValuesCHROMIUM(const ValidationContext *val,
+ const Display *display,
+ const Surface *eglSurface,
+ const EGLuint64KHR *ust,
+ const EGLuint64KHR *msc,
+ const EGLuint64KHR *sbc)
+{
+ ANGLE_VALIDATION_TRY(ValidateSyncControlCHROMIUM(val, display, eglSurface));
+
+ if (ust == nullptr)
+ {
+ val->setError(EGL_BAD_PARAMETER, "ust is null");
+ return false;
+ }
+ if (msc == nullptr)
+ {
+ val->setError(EGL_BAD_PARAMETER, "msc is null");
+ return false;
+ }
+ if (sbc == nullptr)
+ {
+ val->setError(EGL_BAD_PARAMETER, "sbc is null");
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateDestroySurface(const ValidationContext *val,
+ const Display *display,
+ const Surface *surface)
+{
+ ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface));
+ return true;
+}
+
+bool ValidateDestroyContext(const ValidationContext *val,
+ const Display *display,
+ const gl::Context *glCtx)
+{
+ ANGLE_VALIDATION_TRY(ValidateContext(val, display, glCtx));
+ return true;
+}
+
+bool ValidateSwapBuffers(const ValidationContext *val,
+ const Display *display,
+ const Surface *eglSurface)
+{
+ ANGLE_VALIDATION_TRY(ValidateSurface(val, display, eglSurface));
+
+ if (display->isDeviceLost())
+ {
+ val->setError(EGL_CONTEXT_LOST);
+ return false;
+ }
+
+ if (eglSurface->isLocked())
+ {
+ val->setError(EGL_BAD_ACCESS);
+ return false;
+ }
+
+ if (eglSurface == EGL_NO_SURFACE || !val->eglThread->getContext() ||
+ val->eglThread->getCurrentDrawSurface() != eglSurface)
+ {
+ val->setError(EGL_BAD_SURFACE);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateSwapBuffersWithDamageKHR(const ValidationContext *val,
+ const Display *display,
+ const Surface *surface,
+ const EGLint *rects,
+ EGLint n_rects)
+{
+ ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface));
+
+ if (!display->getExtensions().swapBuffersWithDamage)
+ {
+ // It is out of spec what happens when calling an extension function when the extension is
+ // not available. EGL_BAD_DISPLAY seems like a reasonable error.
+ val->setError(EGL_BAD_DISPLAY, "EGL_KHR_swap_buffers_with_damage is not available.");
+ return false;
+ }
+
+ if (surface == EGL_NO_SURFACE)
+ {
+ val->setError(EGL_BAD_SURFACE, "Swap surface cannot be EGL_NO_SURFACE.");
+ return false;
+ }
+
+ if (n_rects < 0)
+ {
+ val->setError(EGL_BAD_PARAMETER, "n_rects cannot be negative.");
+ return false;
+ }
+
+ if (n_rects > 0 && rects == nullptr)
+ {
+ val->setError(EGL_BAD_PARAMETER, "n_rects cannot be greater than zero when rects is NULL.");
+ return false;
+ }
+
+ if (surface->isLocked())
+ {
+ val->setError(EGL_BAD_ACCESS);
+ return false;
+ }
+
+ // TODO(jmadill): Validate Surface is bound to the thread.
+
+ return true;
+}
+
+bool ValidateWaitNative(const ValidationContext *val, const EGLint engine)
+{
+ if (val->eglThread->getDisplay() == nullptr)
+ {
+ // EGL spec says this about eglWaitNative -
+ // eglWaitNative is ignored if there is no current EGL rendering context.
+ return true;
+ }
+
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, val->eglThread->getDisplay()));
+
+ if (engine != EGL_CORE_NATIVE_ENGINE)
+ {
+ val->setError(EGL_BAD_PARAMETER, "the 'engine' parameter has an unrecognized value");
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateCopyBuffers(const ValidationContext *val,
+ const Display *display,
+ const Surface *surface,
+ EGLNativePixmapType target)
+{
+ ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface));
+
+ if (display->isDeviceLost())
+ {
+ val->setError(EGL_CONTEXT_LOST);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateBindTexImage(const ValidationContext *val,
+ const Display *display,
+ const Surface *surface,
+ const EGLint buffer)
+{
+ ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface));
+
+ if (buffer != EGL_BACK_BUFFER)
+ {
+ val->setError(EGL_BAD_PARAMETER);
+ return false;
+ }
+
+ if (surface->getType() == EGL_WINDOW_BIT)
+ {
+ val->setError(EGL_BAD_SURFACE);
+ return false;
+ }
+
+ if (surface->getBoundTexture())
+ {
+ val->setError(EGL_BAD_ACCESS);
+ return false;
+ }
+
+ if (surface->getTextureFormat() == TextureFormat::NoTexture)
+ {
+ val->setError(EGL_BAD_MATCH);
+ return false;
+ }
+
+ if (surface->isLocked())
+ {
+ val->setError(EGL_BAD_ACCESS);
+ return false;
+ }
+
+ gl::Context *context = val->eglThread->getContext();
+ if (context && !context->isContextLost())
+ {
+ gl::TextureType type = egl_gl::EGLTextureTargetToTextureType(surface->getTextureTarget());
+ gl::Texture *textureObject = context->getTextureByType(type);
+ ASSERT(textureObject != nullptr);
+
+ if (textureObject->getImmutableFormat())
+ {
+ val->setError(EGL_BAD_MATCH);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateReleaseTexImage(const ValidationContext *val,
+ const Display *display,
+ const Surface *surface,
+ const EGLint buffer)
+{
+ ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface));
+
+ if (buffer != EGL_BACK_BUFFER)
+ {
+ val->setError(EGL_BAD_PARAMETER);
+ return false;
+ }
+
+ if (surface->getType() == EGL_WINDOW_BIT)
+ {
+ val->setError(EGL_BAD_SURFACE);
+ return false;
+ }
+
+ if (surface->getTextureFormat() == TextureFormat::NoTexture)
+ {
+ val->setError(EGL_BAD_MATCH);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateSwapInterval(const ValidationContext *val, const Display *display, EGLint interval)
+{
+ const gl::Context *context = val->eglThread->getContext();
+ ANGLE_VALIDATION_TRY(ValidateContext(val, display, context));
+
+ Surface *drawSurface = val->eglThread->getCurrentDrawSurface();
+ if (drawSurface == nullptr)
+ {
+ val->setError(EGL_BAD_SURFACE);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateBindAPI(const ValidationContext *val, const EGLenum api)
+{
+ switch (api)
+ {
+ case EGL_OPENGL_ES_API:
+ case EGL_OPENGL_API:
+ break;
+ case EGL_OPENVG_API:
+ val->setError(EGL_BAD_PARAMETER);
+ return false; // Not supported by this implementation
+ default:
+ val->setError(EGL_BAD_PARAMETER);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidatePresentationTimeANDROID(const ValidationContext *val,
+ const Display *display,
+ const Surface *surface,
+ EGLnsecsANDROID time)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+
+ if (!display->getExtensions().presentationTime)
+ {
+ // It is out of spec what happens when calling an extension function when the extension is
+ // not available. EGL_BAD_DISPLAY seems like a reasonable error.
+ val->setError(EGL_BAD_DISPLAY, "EGL_ANDROID_presentation_time is not available.");
+ return false;
+ }
+
+ ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface));
+
+ return true;
+}
+
+bool ValidateSetBlobCacheFuncsANDROID(const ValidationContext *val,
+ const Display *display,
+ EGLSetBlobFuncANDROID set,
+ EGLGetBlobFuncANDROID get)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+
+ if (display->areBlobCacheFuncsSet())
+ {
+ val->setError(EGL_BAD_PARAMETER,
+ "Blob cache functions can only be set once in the lifetime of a Display");
+ return false;
+ }
+
+ if (set == nullptr || get == nullptr)
+ {
+ val->setError(EGL_BAD_PARAMETER, "Blob cache callbacks cannot be null.");
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetConfigAttrib(const ValidationContext *val,
+ const Display *display,
+ const Config *config,
+ EGLint attribute,
+ const EGLint *value)
+{
+ ANGLE_VALIDATION_TRY(ValidateConfig(val, display, config));
+ ANGLE_TRY(ValidateConfigAttribute(val, display, static_cast<EGLAttrib>(attribute)));
+ return true;
+}
+
+bool ValidateChooseConfig(const ValidationContext *val,
+ const Display *display,
+ const AttributeMap &attribs,
+ const EGLConfig *configs,
+ EGLint configSize,
+ const EGLint *numConfig)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+ ANGLE_VALIDATION_TRY(ValidateConfigAttributes(val, display, attribs));
+
+ if (numConfig == nullptr)
+ {
+ val->setError(EGL_BAD_PARAMETER, "num_config cannot be null.");
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetConfigs(const ValidationContext *val,
+ const Display *display,
+ const EGLConfig *configs,
+ EGLint configSize,
+ const EGLint *numConfig)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+
+ if (numConfig == nullptr)
+ {
+ val->setError(EGL_BAD_PARAMETER, "num_config cannot be null.");
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetPlatformDisplay(const ValidationContext *val,
+ EGLenum platform,
+ const void *native_display,
+ const AttributeMap &attribMap)
+{
+ return ValidateGetPlatformDisplayCommon(val, platform, native_display, attribMap);
+}
+
+bool ValidateGetPlatformDisplayEXT(const ValidationContext *val,
+ EGLenum platform,
+ const void *native_display,
+ const AttributeMap &attribMap)
+{
+ return ValidateGetPlatformDisplayCommon(val, platform, native_display, attribMap);
+}
+
+bool ValidateCreatePlatformWindowSurfaceEXT(const ValidationContext *val,
+ const Display *display,
+ const Config *configuration,
+ const void *nativeWindow,
+ const AttributeMap &attributes)
+{
+ if (!Display::GetClientExtensions().platformBase)
+ {
+ val->setError(EGL_BAD_ACCESS, "EGL_EXT_platform_base not supported");
+ return false;
+ }
+
+ const void *actualNativeWindow = display->getImplementation()->isX11()
+ ? *reinterpret_cast<const void *const *>(nativeWindow)
+ : nativeWindow;
+
+ return ValidateCreatePlatformWindowSurface(val, display, configuration, actualNativeWindow,
+ attributes);
+}
+
+bool ValidateCreatePlatformPixmapSurfaceEXT(const ValidationContext *val,
+ const Display *display,
+ const Config *configuration,
+ const void *nativePixmap,
+ const AttributeMap &attributes)
+{
+ if (!Display::GetClientExtensions().platformBase)
+ {
+ val->setError(EGL_BAD_ACCESS, "EGL_EXT_platform_base not supported");
+ return false;
+ }
+
+ ANGLE_VALIDATION_TRY(ValidateConfig(val, display, configuration));
+
+ val->setError(EGL_BAD_DISPLAY, "ValidateCreatePlatformPixmapSurfaceEXT unimplemented.");
+ return false;
+}
+
+bool ValidateProgramCacheGetAttribANGLE(const ValidationContext *val,
+ const Display *display,
+ EGLenum attrib)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+
+ if (!display->getExtensions().programCacheControlANGLE)
+ {
+ val->setError(EGL_BAD_ACCESS, "Extension not supported");
+ return false;
+ }
+
+ switch (attrib)
+ {
+ case EGL_PROGRAM_CACHE_KEY_LENGTH_ANGLE:
+ case EGL_PROGRAM_CACHE_SIZE_ANGLE:
+ break;
+
+ default:
+ val->setError(EGL_BAD_PARAMETER, "Invalid program cache attribute.");
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateProgramCacheQueryANGLE(const ValidationContext *val,
+ const Display *display,
+ EGLint index,
+ const void *key,
+ const EGLint *keysize,
+ const void *binary,
+ const EGLint *binarysize)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+
+ if (!display->getExtensions().programCacheControlANGLE)
+ {
+ val->setError(EGL_BAD_ACCESS, "Extension not supported");
+ return false;
+ }
+
+ if (index < 0 || index >= display->programCacheGetAttrib(EGL_PROGRAM_CACHE_SIZE_ANGLE))
+ {
+ val->setError(EGL_BAD_PARAMETER, "Program index out of range.");
+ return false;
+ }
+
+ if (keysize == nullptr || binarysize == nullptr)
+ {
+ val->setError(EGL_BAD_PARAMETER, "keysize and binarysize must always be valid pointers.");
+ return false;
+ }
+
+ if (binary && *keysize != static_cast<EGLint>(egl::BlobCache::kKeyLength))
+ {
+ val->setError(EGL_BAD_PARAMETER, "Invalid program key size.");
+ return false;
+ }
+
+ if ((key == nullptr) != (binary == nullptr))
+ {
+ val->setError(EGL_BAD_PARAMETER, "key and binary must both be null or both non-null.");
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateProgramCachePopulateANGLE(const ValidationContext *val,
+ const Display *display,
+ const void *key,
+ EGLint keysize,
+ const void *binary,
+ EGLint binarysize)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+
+ if (!display->getExtensions().programCacheControlANGLE)
+ {
+ val->setError(EGL_BAD_ACCESS, "Extension not supported");
+ return false;
+ }
+
+ if (keysize != static_cast<EGLint>(egl::BlobCache::kKeyLength))
+ {
+ val->setError(EGL_BAD_PARAMETER, "Invalid program key size.");
+ return false;
+ }
+
+ if (key == nullptr || binary == nullptr)
+ {
+ val->setError(EGL_BAD_PARAMETER, "null pointer in arguments.");
+ return false;
+ }
+
+ // Upper bound for binarysize is arbitrary.
+ if (binarysize <= 0 || binarysize > egl::kProgramCacheSizeAbsoluteMax)
+ {
+ val->setError(EGL_BAD_PARAMETER, "binarysize out of valid range.");
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateProgramCacheResizeANGLE(const ValidationContext *val,
+ const Display *display,
+ EGLint limit,
+ EGLint mode)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+
+ if (!display->getExtensions().programCacheControlANGLE)
+ {
+ val->setError(EGL_BAD_ACCESS, "Extension not supported");
+ return false;
+ }
+
+ if (limit < 0)
+ {
+ val->setError(EGL_BAD_PARAMETER, "limit must be non-negative.");
+ return false;
+ }
+
+ switch (mode)
+ {
+ case EGL_PROGRAM_CACHE_RESIZE_ANGLE:
+ case EGL_PROGRAM_CACHE_TRIM_ANGLE:
+ break;
+
+ default:
+ val->setError(EGL_BAD_PARAMETER, "Invalid cache resize mode.");
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateSurfaceAttrib(const ValidationContext *val,
+ const Display *display,
+ const Surface *surface,
+ EGLint attribute,
+ EGLint value)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+ ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface));
+
+ if (surface == EGL_NO_SURFACE)
+ {
+ val->setError(EGL_BAD_SURFACE, "Surface cannot be EGL_NO_SURFACE.");
+ return false;
+ }
+
+ switch (attribute)
+ {
+ case EGL_MIPMAP_LEVEL:
+ break;
+
+ case EGL_MULTISAMPLE_RESOLVE:
+ switch (value)
+ {
+ case EGL_MULTISAMPLE_RESOLVE_DEFAULT:
+ break;
+
+ case EGL_MULTISAMPLE_RESOLVE_BOX:
+ if ((surface->getConfig()->surfaceType & EGL_MULTISAMPLE_RESOLVE_BOX_BIT) == 0)
+ {
+ val->setError(EGL_BAD_MATCH,
+ "Surface does not support EGL_MULTISAMPLE_RESOLVE_BOX.");
+ return false;
+ }
+ break;
+
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE, "Invalid multisample resolve type.");
+ return false;
+ }
+ break;
+
+ case EGL_SWAP_BEHAVIOR:
+ switch (value)
+ {
+ case EGL_BUFFER_PRESERVED:
+ if ((surface->getConfig()->surfaceType & EGL_SWAP_BEHAVIOR_PRESERVED_BIT) == 0)
+ {
+ val->setError(EGL_BAD_MATCH,
+ "Surface does not support EGL_SWAP_BEHAVIOR_PRESERVED.");
+ return false;
+ }
+ break;
+
+ case EGL_BUFFER_DESTROYED:
+ break;
+
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE, "Invalid swap behaviour.");
+ return false;
+ }
+ break;
+
+ case EGL_WIDTH:
+ case EGL_HEIGHT:
+ if (!display->getExtensions().windowFixedSize)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_WIDTH or EGL_HEIGHT cannot be set without "
+ "EGL_ANGLE_window_fixed_size support.");
+ return false;
+ }
+ if (!surface->isFixedSize())
+ {
+ val->setError(EGL_BAD_MATCH,
+ "EGL_WIDTH or EGL_HEIGHT cannot be set without "
+ "EGL_FIXED_SIZE_ANGLE being enabled on the surface.");
+ return false;
+ }
+ break;
+
+ case EGL_TIMESTAMPS_ANDROID:
+ if (!display->getExtensions().getFrameTimestamps &&
+ !display->getExtensions().timestampSurfaceAttributeANGLE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_TIMESTAMPS_ANDROID cannot be used without "
+ "EGL_ANDROID_get_frame_timestamps support.");
+ return false;
+ }
+ switch (value)
+ {
+ case EGL_TRUE:
+ case EGL_FALSE:
+ break;
+
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE, "Invalid value.");
+ return false;
+ }
+ break;
+
+ case EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID:
+ ASSERT(value == EGL_TRUE || value == EGL_FALSE);
+ break;
+
+ case EGL_RENDER_BUFFER:
+ if (value != EGL_BACK_BUFFER && value != EGL_SINGLE_BUFFER)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_RENDER_BUFFER must be EGL_BACK_BUFFER or EGL_SINGLE_BUFFER.");
+ return false;
+ }
+
+ if (value == EGL_SINGLE_BUFFER)
+ {
+ if (!display->getExtensions().mutableRenderBufferKHR)
+ {
+ val->setError(
+ EGL_BAD_ATTRIBUTE,
+ "Attribute EGL_RENDER_BUFFER requires EGL_KHR_mutable_render_buffer.");
+ return false;
+ }
+
+ if ((surface->getConfig()->surfaceType & EGL_MUTABLE_RENDER_BUFFER_BIT_KHR) == 0)
+ {
+ val->setError(EGL_BAD_MATCH,
+ "EGL_RENDER_BUFFER requires the surface type bit "
+ "EGL_MUTABLE_RENDER_BUFFER_BIT_KHR.");
+ return false;
+ }
+ }
+ break;
+
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE, "Invalid surface attribute: 0x%04X", attribute);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateQuerySurface(const ValidationContext *val,
+ const Display *display,
+ const Surface *surface,
+ EGLint attribute,
+ const EGLint *value)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+ ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface));
+
+ if (surface == EGL_NO_SURFACE)
+ {
+ val->setError(EGL_BAD_SURFACE, "Surface cannot be EGL_NO_SURFACE.");
+ return false;
+ }
+
+ switch (attribute)
+ {
+ case EGL_GL_COLORSPACE:
+ case EGL_VG_ALPHA_FORMAT:
+ case EGL_VG_COLORSPACE:
+ case EGL_CONFIG_ID:
+ case EGL_HEIGHT:
+ case EGL_HORIZONTAL_RESOLUTION:
+ case EGL_LARGEST_PBUFFER:
+ case EGL_MIPMAP_TEXTURE:
+ case EGL_MIPMAP_LEVEL:
+ case EGL_MULTISAMPLE_RESOLVE:
+ case EGL_PIXEL_ASPECT_RATIO:
+ case EGL_RENDER_BUFFER:
+ case EGL_SWAP_BEHAVIOR:
+ case EGL_TEXTURE_FORMAT:
+ case EGL_TEXTURE_TARGET:
+ case EGL_VERTICAL_RESOLUTION:
+ case EGL_WIDTH:
+ break;
+
+ case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
+ if (!display->getExtensions().postSubBuffer)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_POST_SUB_BUFFER_SUPPORTED_NV cannot be used "
+ "without EGL_ANGLE_surface_orientation support.");
+ return false;
+ }
+ break;
+
+ case EGL_FIXED_SIZE_ANGLE:
+ if (!display->getExtensions().windowFixedSize)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_FIXED_SIZE_ANGLE cannot be used without "
+ "EGL_ANGLE_window_fixed_size support.");
+ return false;
+ }
+ break;
+
+ case EGL_SURFACE_ORIENTATION_ANGLE:
+ if (!display->getExtensions().surfaceOrientation)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_SURFACE_ORIENTATION_ANGLE cannot be "
+ "queried without "
+ "EGL_ANGLE_surface_orientation support.");
+ return false;
+ }
+ break;
+
+ case EGL_DIRECT_COMPOSITION_ANGLE:
+ if (!display->getExtensions().directComposition)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_DIRECT_COMPOSITION_ANGLE cannot be "
+ "used without "
+ "EGL_ANGLE_direct_composition support.");
+ return false;
+ }
+ break;
+
+ case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
+ if (!display->getExtensions().robustResourceInitializationANGLE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE cannot be "
+ "used without EGL_ANGLE_robust_resource_initialization "
+ "support.");
+ return false;
+ }
+ break;
+
+ case EGL_TIMESTAMPS_ANDROID:
+ if (!display->getExtensions().getFrameTimestamps &&
+ !display->getExtensions().timestampSurfaceAttributeANGLE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_TIMESTAMPS_ANDROID cannot be used without "
+ "EGL_ANDROID_get_frame_timestamps support.");
+ return false;
+ }
+ break;
+
+ case EGL_BUFFER_AGE_EXT:
+ {
+ if (!display->getExtensions().bufferAgeEXT)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_BUFFER_AGE_EXT cannot be used without "
+ "EGL_EXT_buffer_age support.");
+ return false;
+ }
+ gl::Context *context = val->eglThread->getContext();
+ if ((context == nullptr) || (context->getCurrentDrawSurface() != surface))
+ {
+ val->setError(EGL_BAD_SURFACE,
+ "The surface must be current to the current context "
+ "in order to query buffer age per extension "
+ "EGL_EXT_buffer_age.");
+ return false;
+ }
+ }
+ break;
+
+ case EGL_BITMAP_PITCH_KHR:
+ case EGL_BITMAP_ORIGIN_KHR:
+ case EGL_BITMAP_PIXEL_RED_OFFSET_KHR:
+ case EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR:
+ case EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR:
+ case EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR:
+ case EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR:
+ case EGL_BITMAP_PIXEL_SIZE_KHR:
+ if (!display->getExtensions().lockSurface3KHR)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE, "EGL_KHR_lock_surface3 is not supported.");
+ return false;
+ }
+ break;
+
+ case EGL_PROTECTED_CONTENT_EXT:
+ if (!display->getExtensions().protectedContentEXT)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE, "EGL_EXT_protected_content not supported");
+ return false;
+ }
+ break;
+
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE, "Invalid surface attribute: 0x%04X", attribute);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateQueryContext(const ValidationContext *val,
+ const Display *display,
+ const gl::Context *context,
+ EGLint attribute,
+ const EGLint *value)
+{
+ ANGLE_VALIDATION_TRY(ValidateContext(val, display, context));
+
+ switch (attribute)
+ {
+ case EGL_CONFIG_ID:
+ case EGL_CONTEXT_CLIENT_TYPE:
+ case EGL_CONTEXT_CLIENT_VERSION:
+ case EGL_RENDER_BUFFER:
+ break;
+
+ case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
+ if (!display->getExtensions().robustResourceInitializationANGLE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE cannot be "
+ "used without EGL_ANGLE_robust_resource_initialization "
+ "support.");
+ return false;
+ }
+ break;
+
+ case EGL_CONTEXT_PRIORITY_LEVEL_IMG:
+ if (!display->getExtensions().contextPriority)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "Attribute EGL_CONTEXT_PRIORITY_LEVEL_IMG requires "
+ "extension EGL_IMG_context_priority.");
+ return false;
+ }
+ break;
+
+ case EGL_PROTECTED_CONTENT_EXT:
+ if (!display->getExtensions().protectedContentEXT)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE, "EGL_EXT_protected_content not supported");
+ return false;
+ }
+ break;
+
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE, "Invalid context attribute: 0x%04X", attribute);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateDebugMessageControlKHR(const ValidationContext *val,
+ EGLDEBUGPROCKHR callback,
+ const AttributeMap &attribs)
+{
+ const ClientExtensions &clientExtensions = Display::GetClientExtensions();
+ if (!clientExtensions.debug)
+ {
+ val->setError(EGL_BAD_ACCESS, "EGL_KHR_debug extension is not available.");
+ return false;
+ }
+
+ attribs.initializeWithoutValidation();
+
+ for (const auto &attrib : attribs)
+ {
+ switch (attrib.first)
+ {
+ case EGL_DEBUG_MSG_CRITICAL_KHR:
+ case EGL_DEBUG_MSG_ERROR_KHR:
+ case EGL_DEBUG_MSG_WARN_KHR:
+ case EGL_DEBUG_MSG_INFO_KHR:
+ if (attrib.second != EGL_TRUE && attrib.second != EGL_FALSE)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE,
+ "message controls must be EGL_TRUE or EGL_FALSE.");
+ return false;
+ }
+ break;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateQueryDebugKHR(const ValidationContext *val, EGLint attribute, const EGLAttrib *value)
+{
+ const ClientExtensions &clientExtensions = Display::GetClientExtensions();
+ if (!clientExtensions.debug)
+ {
+ val->setError(EGL_BAD_ACCESS, "EGL_KHR_debug extension is not available.");
+ return false;
+ }
+
+ switch (attribute)
+ {
+ case EGL_DEBUG_MSG_CRITICAL_KHR:
+ case EGL_DEBUG_MSG_ERROR_KHR:
+ case EGL_DEBUG_MSG_WARN_KHR:
+ case EGL_DEBUG_MSG_INFO_KHR:
+ case EGL_DEBUG_CALLBACK_KHR:
+ break;
+
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE, "Unknown attribute: 0x%04X", attribute);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateLabelObjectKHR(const ValidationContext *val,
+ const Display *display,
+ ObjectType objectType,
+ EGLObjectKHR object,
+ EGLLabelKHR label)
+{
+ const ClientExtensions &clientExtensions = Display::GetClientExtensions();
+ if (!clientExtensions.debug)
+ {
+ val->setError(EGL_BAD_ACCESS, "EGL_KHR_debug extension is not available.");
+ return false;
+ }
+
+ LabeledObject *labeledObject = nullptr;
+ ANGLE_VALIDATION_TRY(ValidateLabeledObject(val, display, objectType, object, &labeledObject));
+
+ return true;
+}
+
+bool ValidateGetCompositorTimingSupportedANDROID(const ValidationContext *val,
+ const Display *display,
+ const Surface *surface,
+ CompositorTiming name)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+
+ if (!display->getExtensions().getFrameTimestamps)
+ {
+ val->setError(EGL_BAD_DISPLAY,
+ "EGL_ANDROID_get_frame_timestamps extension is not available.");
+ return false;
+ }
+
+ ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface));
+
+ if (!ValidCompositorTimingName(name))
+ {
+ val->setError(EGL_BAD_PARAMETER, "invalid timing name.");
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetCompositorTimingANDROID(const ValidationContext *val,
+ const Display *display,
+ const Surface *surface,
+ EGLint numTimestamps,
+ const EGLint *names,
+ const EGLnsecsANDROID *values)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+
+ if (!display->getExtensions().getFrameTimestamps)
+ {
+ val->setError(EGL_BAD_DISPLAY,
+ "EGL_ANDROID_get_frame_timestamps extension is not available.");
+ return false;
+ }
+
+ ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface));
+
+ if (names == nullptr && numTimestamps > 0)
+ {
+ val->setError(EGL_BAD_PARAMETER, "names is NULL.");
+ return false;
+ }
+
+ if (values == nullptr && numTimestamps > 0)
+ {
+ val->setError(EGL_BAD_PARAMETER, "values is NULL.");
+ return false;
+ }
+
+ if (numTimestamps < 0)
+ {
+ val->setError(EGL_BAD_PARAMETER, "numTimestamps must be at least 0.");
+ return false;
+ }
+
+ for (EGLint i = 0; i < numTimestamps; i++)
+ {
+ CompositorTiming name = FromEGLenum<CompositorTiming>(names[i]);
+
+ if (!ValidCompositorTimingName(name))
+ {
+ val->setError(EGL_BAD_PARAMETER, "invalid compositor timing.");
+ return false;
+ }
+
+ if (!surface->getSupportedCompositorTimings().test(name))
+ {
+ val->setError(EGL_BAD_PARAMETER, "compositor timing not supported by surface.");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateGetNextFrameIdANDROID(const ValidationContext *val,
+ const Display *display,
+ const Surface *surface,
+ const EGLuint64KHR *frameId)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+
+ if (!display->getExtensions().getFrameTimestamps)
+ {
+ val->setError(EGL_BAD_DISPLAY,
+ "EGL_ANDROID_get_frame_timestamps extension is not available.");
+ return false;
+ }
+
+ ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface));
+
+ if (frameId == nullptr)
+ {
+ val->setError(EGL_BAD_PARAMETER, "frameId is NULL.");
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetFrameTimestampSupportedANDROID(const ValidationContext *val,
+ const Display *display,
+ const Surface *surface,
+ Timestamp timestamp)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+
+ if (!display->getExtensions().getFrameTimestamps)
+ {
+ val->setError(EGL_BAD_DISPLAY,
+ "EGL_ANDROID_get_frame_timestamps extension is not available.");
+ return false;
+ }
+
+ ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface));
+
+ if (!ValidTimestampType(timestamp))
+ {
+ val->setError(EGL_BAD_PARAMETER, "invalid timestamp type.");
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetFrameTimestampsANDROID(const ValidationContext *val,
+ const Display *display,
+ const Surface *surface,
+ EGLuint64KHR frameId,
+ EGLint numTimestamps,
+ const EGLint *timestamps,
+ const EGLnsecsANDROID *values)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+
+ if (!display->getExtensions().getFrameTimestamps)
+ {
+ val->setError(EGL_BAD_DISPLAY,
+ "EGL_ANDROID_get_frame_timestamps extension is not available.");
+ return false;
+ }
+
+ ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface));
+
+ if (!surface->isTimestampsEnabled())
+ {
+ val->setError(EGL_BAD_SURFACE, "timestamp collection is not enabled for this surface.");
+ return false;
+ }
+
+ if (timestamps == nullptr && numTimestamps > 0)
+ {
+ val->setError(EGL_BAD_PARAMETER, "timestamps is NULL.");
+ return false;
+ }
+
+ if (values == nullptr && numTimestamps > 0)
+ {
+ val->setError(EGL_BAD_PARAMETER, "values is NULL.");
+ return false;
+ }
+
+ if (numTimestamps < 0)
+ {
+ val->setError(EGL_BAD_PARAMETER, "numTimestamps must be at least 0.");
+ return false;
+ }
+
+ for (EGLint i = 0; i < numTimestamps; i++)
+ {
+ Timestamp timestamp = FromEGLenum<Timestamp>(timestamps[i]);
+
+ if (!ValidTimestampType(timestamp))
+ {
+ val->setError(EGL_BAD_PARAMETER, "invalid timestamp type.");
+ return false;
+ }
+
+ if (!surface->getSupportedTimestamps().test(timestamp))
+ {
+ val->setError(EGL_BAD_PARAMETER, "timestamp not supported by surface.");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateQueryStringiANGLE(const ValidationContext *val,
+ const Display *display,
+ EGLint name,
+ EGLint index)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+
+ if (!Display::GetClientExtensions().featureControlANGLE)
+ {
+ val->setError(EGL_BAD_DISPLAY, "EGL_ANGLE_feature_control extension is not available.");
+ return false;
+ }
+
+ if (index < 0)
+ {
+ val->setError(EGL_BAD_PARAMETER, "index is negative.");
+ return false;
+ }
+
+ switch (name)
+ {
+ case EGL_FEATURE_NAME_ANGLE:
+ case EGL_FEATURE_CATEGORY_ANGLE:
+ case EGL_FEATURE_DESCRIPTION_ANGLE:
+ case EGL_FEATURE_BUG_ANGLE:
+ case EGL_FEATURE_STATUS_ANGLE:
+ case EGL_FEATURE_CONDITION_ANGLE:
+ break;
+ default:
+ val->setError(EGL_BAD_PARAMETER, "name is not valid.");
+ return false;
+ }
+
+ if (static_cast<size_t>(index) >= display->getFeatures().size())
+ {
+ val->setError(EGL_BAD_PARAMETER, "index is too big.");
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateQueryDisplayAttribEXT(const ValidationContext *val,
+ const Display *display,
+ const EGLint attribute,
+ const EGLAttrib *value)
+{
+ ANGLE_VALIDATION_TRY(ValidateQueryDisplayAttribBase(val, display, attribute));
+ return true;
+}
+
+bool ValidateQueryDisplayAttribANGLE(const ValidationContext *val,
+ const Display *display,
+ const EGLint attribute,
+ const EGLAttrib *value)
+{
+ ANGLE_VALIDATION_TRY(ValidateQueryDisplayAttribBase(val, display, attribute));
+ return true;
+}
+
+bool ValidateGetNativeClientBufferANDROID(const ValidationContext *val,
+ const AHardwareBuffer *buffer)
+{
+ // No extension check is done because no display is passed to eglGetNativeClientBufferANDROID
+ // despite it being a display extension. No display is needed for the implementation though.
+ if (buffer == nullptr)
+ {
+ val->setError(EGL_BAD_PARAMETER, "NULL buffer.");
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateCreateNativeClientBufferANDROID(const ValidationContext *val,
+ const egl::AttributeMap &attribMap)
+{
+ attribMap.initializeWithoutValidation();
+
+ if (attribMap.isEmpty() || attribMap.begin()->second == EGL_NONE)
+ {
+ val->setError(EGL_BAD_PARAMETER, "invalid attribute list.");
+ return false;
+ }
+
+ int width = attribMap.getAsInt(EGL_WIDTH, 0);
+ int height = attribMap.getAsInt(EGL_HEIGHT, 0);
+ int redSize = attribMap.getAsInt(EGL_RED_SIZE, 0);
+ int greenSize = attribMap.getAsInt(EGL_GREEN_SIZE, 0);
+ int blueSize = attribMap.getAsInt(EGL_BLUE_SIZE, 0);
+ int alphaSize = attribMap.getAsInt(EGL_ALPHA_SIZE, 0);
+ int usage = attribMap.getAsInt(EGL_NATIVE_BUFFER_USAGE_ANDROID, 0);
+
+ for (AttributeMap::const_iterator attributeIter = attribMap.begin();
+ attributeIter != attribMap.end(); attributeIter++)
+ {
+ EGLAttrib attribute = attributeIter->first;
+ switch (attribute)
+ {
+ case EGL_WIDTH:
+ case EGL_HEIGHT:
+ // Validation done after the switch statement
+ break;
+ case EGL_RED_SIZE:
+ case EGL_GREEN_SIZE:
+ case EGL_BLUE_SIZE:
+ case EGL_ALPHA_SIZE:
+ if (redSize < 0 || greenSize < 0 || blueSize < 0 || alphaSize < 0)
+ {
+ val->setError(EGL_BAD_PARAMETER, "incorrect channel size requested");
+ return false;
+ }
+ break;
+ case EGL_NATIVE_BUFFER_USAGE_ANDROID:
+ // The buffer must be used for either a texture or a renderbuffer.
+ if ((usage & ~(EGL_NATIVE_BUFFER_USAGE_PROTECTED_BIT_ANDROID |
+ EGL_NATIVE_BUFFER_USAGE_RENDERBUFFER_BIT_ANDROID |
+ EGL_NATIVE_BUFFER_USAGE_TEXTURE_BIT_ANDROID)) != 0)
+ {
+ val->setError(EGL_BAD_PARAMETER, "invalid usage flag");
+ return false;
+ }
+ break;
+ case EGL_NONE:
+ break;
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE, "invalid attribute");
+ return false;
+ }
+ }
+
+ // Validate EGL_WIDTH and EGL_HEIGHT values passed in. Done here to account
+ // for the case where EGL_WIDTH and EGL_HEIGHT were not part of the attribute list.
+ if (width <= 0 || height <= 0)
+ {
+ val->setError(EGL_BAD_PARAMETER, "incorrect buffer dimensions requested");
+ return false;
+ }
+
+ if (gl::GetAndroidHardwareBufferFormatFromChannelSizes(attribMap) == 0)
+ {
+ val->setError(EGL_BAD_PARAMETER, "unsupported format");
+ return false;
+ }
+ return true;
+}
+
+bool ValidateCopyMetalSharedEventANGLE(const ValidationContext *val,
+ const Display *display,
+ const Sync *sync)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+
+ if (!display->getExtensions().mtlSyncSharedEventANGLE)
+ {
+ val->setError(EGL_BAD_DISPLAY, "EGL_ANGLE_metal_shared_event_sync is not available.");
+ return false;
+ }
+
+ ANGLE_VALIDATION_TRY(ValidateSync(val, display, sync));
+
+ return true;
+}
+
+bool ValidateDupNativeFenceFDANDROID(const ValidationContext *val,
+ const Display *display,
+ const Sync *sync)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+
+ if (!display->getExtensions().nativeFenceSyncANDROID)
+ {
+ val->setError(EGL_BAD_DISPLAY, "EGL_ANDROID_native_fence_sync extension is not available.");
+ return false;
+ }
+
+ ANGLE_VALIDATION_TRY(ValidateSync(val, display, sync));
+
+ return true;
+}
+
+bool ValidateSwapBuffersWithFrameTokenANGLE(const ValidationContext *val,
+ const Display *display,
+ const Surface *surface,
+ EGLFrameTokenANGLE frametoken)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+
+ if (!display->getExtensions().swapWithFrameToken)
+ {
+ val->setError(EGL_BAD_DISPLAY, "EGL_ANGLE_swap_buffers_with_frame_token is not available.");
+ return false;
+ }
+
+ ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface));
+
+ return true;
+}
+
+bool ValidatePrepareSwapBuffersANGLE(const ValidationContext *val,
+ const Display *display,
+ const Surface *surface)
+{
+ return ValidateSwapBuffers(val, display, surface);
+}
+
+bool ValidateSignalSyncKHR(const ValidationContext *val,
+ const Display *display,
+ const Sync *sync,
+ EGLenum mode)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+
+ ANGLE_VALIDATION_TRY(ValidateSync(val, display, sync));
+
+ if (sync->getType() == EGL_SYNC_REUSABLE_KHR)
+ {
+ if (!display->getExtensions().reusableSyncKHR)
+ {
+ val->setError(EGL_BAD_MATCH, "EGL_KHR_reusable_sync extension is not available.");
+ return false;
+ }
+
+ if ((mode != EGL_SIGNALED_KHR) && (mode != EGL_UNSIGNALED_KHR))
+ {
+ val->setError(EGL_BAD_PARAMETER, "eglSignalSyncKHR invalid mode.");
+ return false;
+ }
+
+ return true;
+ }
+
+ val->setError(EGL_BAD_MATCH);
+ return false;
+}
+
+bool ValidateQuerySurfacePointerANGLE(const ValidationContext *val,
+ const Display *display,
+ const Surface *eglSurface,
+ EGLint attribute,
+ void *const *value)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+
+ if (!display->getExtensions().querySurfacePointer)
+ {
+ val->setError(EGL_BAD_ACCESS);
+ return false;
+ }
+
+ ANGLE_VALIDATION_TRY(ValidateSurface(val, display, eglSurface));
+
+ // validate the attribute parameter
+ switch (attribute)
+ {
+ case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE:
+ if (!display->getExtensions().surfaceD3DTexture2DShareHandle)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE);
+ return false;
+ }
+ break;
+ case EGL_DXGI_KEYED_MUTEX_ANGLE:
+ if (!display->getExtensions().keyedMutex)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE);
+ return false;
+ }
+ break;
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidatePostSubBufferNV(const ValidationContext *val,
+ const Display *display,
+ const Surface *eglSurface,
+ EGLint x,
+ EGLint y,
+ EGLint width,
+ EGLint height)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+
+ if (!display->getExtensions().postSubBuffer)
+ {
+ val->setError(EGL_BAD_ACCESS);
+ return false;
+ }
+
+ if (x < 0 || y < 0 || width < 0 || height < 0)
+ {
+ val->setError(EGL_BAD_PARAMETER);
+ return false;
+ }
+
+ ANGLE_VALIDATION_TRY(ValidateSurface(val, display, eglSurface));
+
+ if (display->isDeviceLost())
+ {
+ val->setError(EGL_CONTEXT_LOST);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateQueryDeviceAttribEXT(const ValidationContext *val,
+ const Device *device,
+ EGLint attribute,
+ const EGLAttrib *value)
+{
+ ANGLE_VALIDATION_TRY(ValidateDevice(val, device));
+
+ if (!Display::GetClientExtensions().deviceQueryEXT)
+ {
+ val->setError(EGL_BAD_ACCESS, "EGL_EXT_device_query not supported.");
+ return false;
+ }
+
+ // validate the attribute parameter
+ switch (attribute)
+ {
+ case EGL_D3D11_DEVICE_ANGLE:
+ case EGL_D3D9_DEVICE_ANGLE:
+ if (!device->getExtensions().deviceD3D || device->getType() != attribute)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE);
+ return false;
+ }
+ break;
+ case EGL_EAGL_CONTEXT_ANGLE:
+ if (!device->getExtensions().deviceEAGL)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE);
+ return false;
+ }
+ break;
+ case EGL_METAL_DEVICE_ANGLE:
+ if (!device->getExtensions().deviceMetal)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE);
+ return false;
+ }
+ break;
+ case EGL_VULKAN_VERSION_ANGLE:
+ case EGL_VULKAN_INSTANCE_ANGLE:
+ case EGL_VULKAN_INSTANCE_EXTENSIONS_ANGLE:
+ case EGL_VULKAN_PHYSICAL_DEVICE_ANGLE:
+ case EGL_VULKAN_DEVICE_ANGLE:
+ case EGL_VULKAN_DEVICE_EXTENSIONS_ANGLE:
+ case EGL_VULKAN_FEATURES_ANGLE:
+ case EGL_VULKAN_QUEUE_ANGLE:
+ case EGL_VULKAN_QUEUE_FAMILIY_INDEX_ANGLE:
+ case EGL_VULKAN_GET_INSTANCE_PROC_ADDR:
+ if (!device->getExtensions().deviceVulkan)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE);
+ return false;
+ }
+ break;
+ case EGL_CGL_CONTEXT_ANGLE:
+ case EGL_CGL_PIXEL_FORMAT_ANGLE:
+ if (!device->getExtensions().deviceCGL)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE);
+ return false;
+ }
+ break;
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE);
+ return false;
+ }
+ return true;
+}
+
+bool ValidateQueryDeviceStringEXT(const ValidationContext *val, const Device *device, EGLint name)
+{
+ ANGLE_VALIDATION_TRY(ValidateDevice(val, device));
+ return true;
+}
+
+bool ValidateReleaseHighPowerGPUANGLE(const ValidationContext *val,
+ const Display *display,
+ const gl::Context *context)
+{
+ ANGLE_VALIDATION_TRY(ValidateContext(val, display, context));
+ return true;
+}
+
+bool ValidateReacquireHighPowerGPUANGLE(const ValidationContext *val,
+ const Display *display,
+ const gl::Context *context)
+{
+ ANGLE_VALIDATION_TRY(ValidateContext(val, display, context));
+ return true;
+}
+
+bool ValidateHandleGPUSwitchANGLE(const ValidationContext *val, const Display *display)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+ return true;
+}
+
+bool ValidateForceGPUSwitchANGLE(const ValidationContext *val,
+ const Display *display,
+ EGLint gpuIDHigh,
+ EGLint gpuIDLow)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+ return true;
+}
+
+bool ValidateGetCurrentDisplay(const ValidationContext *val)
+{
+ return true;
+}
+
+bool ValidateGetCurrentSurface(const ValidationContext *val, EGLint readdraw)
+{
+ return true;
+}
+
+bool ValidateGetDisplay(const ValidationContext *val, EGLNativeDisplayType display_id)
+{
+ return true;
+}
+
+bool ValidateGetError(const ValidationContext *val)
+{
+ return true;
+}
+
+bool ValidateGetProcAddress(const ValidationContext *val, const char *procname)
+{
+ return true;
+}
+
+bool ValidateQueryString(const ValidationContext *val, const Display *dpyPacked, EGLint name)
+{
+ // The only situation where EGL_NO_DISPLAY is allowed is when querying
+ // EGL_EXTENSIONS or EGL_VERSION.
+ const bool canQueryWithoutDisplay = (name == EGL_VERSION || name == EGL_EXTENSIONS);
+
+ if (dpyPacked != nullptr || !canQueryWithoutDisplay)
+ {
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, dpyPacked));
+ }
+
+ switch (name)
+ {
+ case EGL_CLIENT_APIS:
+ case EGL_EXTENSIONS:
+ case EGL_VENDOR:
+ case EGL_VERSION:
+ break;
+ default:
+ val->setError(EGL_BAD_PARAMETER);
+ return false;
+ }
+ return true;
+}
+
+bool ValidateWaitGL(const ValidationContext *val)
+{
+ if (val->eglThread->getDisplay() == nullptr)
+ {
+ // EGL spec says this about eglWaitGL -
+ // eglWaitGL is ignored if there is no current EGL rendering context for OpenGL ES.
+ return true;
+ }
+
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, val->eglThread->getDisplay()));
+ return true;
+}
+
+bool ValidateQueryAPI(const ValidationContext *val)
+{
+ return true;
+}
+
+bool ValidateReleaseThread(const ValidationContext *val)
+{
+ return true;
+}
+
+bool ValidateWaitClient(const ValidationContext *val)
+{
+ if (val->eglThread->getDisplay() == nullptr)
+ {
+ // EGL spec says this about eglWaitClient -
+ // If there is no current context for the current rendering API,
+ // the function has no effect but still returns EGL_TRUE.
+ return true;
+ }
+
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, val->eglThread->getDisplay()));
+ return true;
+}
+
+bool ValidateGetCurrentContext(const ValidationContext *val)
+{
+ return true;
+}
+
+bool ValidateCreatePlatformPixmapSurface(const ValidationContext *val,
+ const Display *dpyPacked,
+ const Config *configPacked,
+ const void *native_pixmap,
+ const AttributeMap &attrib_listPacked)
+{
+ EGLNativePixmapType nativePixmap =
+ reinterpret_cast<EGLNativePixmapType>(const_cast<void *>(native_pixmap));
+ return ValidateCreatePixmapSurface(val, dpyPacked, configPacked, nativePixmap,
+ attrib_listPacked);
+}
+
+bool ValidateCreatePlatformWindowSurface(const ValidationContext *val,
+ const Display *dpyPacked,
+ const Config *configPacked,
+ const void *native_window,
+ const AttributeMap &attrib_listPacked)
+{
+ EGLNativeWindowType nativeWindow =
+ reinterpret_cast<EGLNativeWindowType>(const_cast<void *>(native_window));
+ return ValidateCreateWindowSurface(val, dpyPacked, configPacked, nativeWindow,
+ attrib_listPacked);
+}
+
+bool ValidateLockSurfaceKHR(const ValidationContext *val,
+ const egl::Display *dpy,
+ const Surface *surface,
+ const AttributeMap &attributes)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, dpy));
+ ANGLE_VALIDATION_TRY(ValidateSurface(val, dpy, surface));
+
+ if (!dpy->getExtensions().lockSurface3KHR)
+ {
+ val->setError(EGL_BAD_ACCESS);
+ return false;
+ }
+
+ if (surface->isLocked())
+ {
+ val->setError(EGL_BAD_ACCESS);
+ return false;
+ }
+
+ if ((surface->getConfig()->surfaceType & EGL_LOCK_SURFACE_BIT_KHR) == false)
+ {
+ val->setError(EGL_BAD_ACCESS, "Config does not support EGL_LOCK_SURFACE_BIT");
+ return false;
+ }
+
+ if (surface->isCurrentOnAnyContext())
+ {
+ val->setError(EGL_BAD_ACCESS,
+ "Surface cannot be current to a context for eglLockSurface()");
+ return false;
+ }
+
+ if (surface->hasProtectedContent())
+ {
+ val->setError(EGL_BAD_ACCESS, "Surface cannot be protected content for eglLockSurface()");
+ return false;
+ }
+
+ attributes.initializeWithoutValidation();
+
+ for (const auto &attributeIter : attributes)
+ {
+ EGLAttrib attribute = attributeIter.first;
+ EGLAttrib value = attributeIter.second;
+
+ switch (attribute)
+ {
+ case EGL_MAP_PRESERVE_PIXELS_KHR:
+ if (!((value == EGL_FALSE) || (value == EGL_TRUE)))
+ {
+ val->setError(EGL_BAD_ATTRIBUTE, "Invalid EGL_MAP_PRESERVE_PIXELS_KHR value");
+ return false;
+ }
+ break;
+ case EGL_LOCK_USAGE_HINT_KHR:
+ if ((value & (EGL_READ_SURFACE_BIT_KHR | EGL_WRITE_SURFACE_BIT_KHR)) != value)
+ {
+ val->setError(EGL_BAD_ATTRIBUTE, "Invalid EGL_LOCK_USAGE_HINT_KHR value");
+ return false;
+ }
+ break;
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE, "Invalid query surface64 attribute");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateQuerySurface64KHR(const ValidationContext *val,
+ const egl::Display *dpy,
+ const Surface *surface,
+ EGLint attribute,
+ const EGLAttribKHR *value)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, dpy));
+ ANGLE_VALIDATION_TRY(ValidateSurface(val, dpy, surface));
+
+ if (!dpy->getExtensions().lockSurface3KHR)
+ {
+ val->setError(EGL_BAD_ACCESS);
+ return false;
+ }
+
+ switch (attribute)
+ {
+ case EGL_BITMAP_PITCH_KHR:
+ case EGL_BITMAP_ORIGIN_KHR:
+ case EGL_BITMAP_PIXEL_RED_OFFSET_KHR:
+ case EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR:
+ case EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR:
+ case EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR:
+ case EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR:
+ case EGL_BITMAP_PIXEL_SIZE_KHR:
+ case EGL_BITMAP_POINTER_KHR:
+ break;
+ default:
+ val->setError(EGL_BAD_ATTRIBUTE, "Invalid eglQuerySurface64 attribute");
+ return false;
+ }
+
+ if (value == nullptr)
+ {
+ val->setError(EGL_BAD_PARAMETER, "value is NULL.");
+ return false;
+ }
+
+ if (!surface->isLocked())
+ {
+ val->setError(EGL_BAD_ACCESS, "Surface is not locked");
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateUnlockSurfaceKHR(const ValidationContext *val,
+ const egl::Display *dpy,
+ const Surface *surface)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, dpy));
+ ANGLE_VALIDATION_TRY(ValidateSurface(val, dpy, surface));
+
+ if (!dpy->getExtensions().lockSurface3KHR)
+ {
+ val->setError(EGL_BAD_ACCESS);
+ return false;
+ }
+
+ if (!surface->isLocked())
+ {
+ val->setError(EGL_BAD_PARAMETER, "Surface is not locked.");
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateExportVkImageANGLE(const ValidationContext *val,
+ const Display *dpy,
+ const Image *image,
+ const void *vkImage,
+ const void *vkImageCreateInfo)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, dpy));
+ ANGLE_VALIDATION_TRY(ValidateImage(val, dpy, image));
+
+ if (!dpy->getExtensions().vulkanImageANGLE)
+ {
+ val->setError(EGL_BAD_ACCESS);
+ return false;
+ }
+
+ if (!vkImage)
+ {
+ val->setError(EGL_BAD_PARAMETER, "Output VkImage pointer is null.");
+ return false;
+ }
+
+ if (!vkImageCreateInfo)
+ {
+ val->setError(EGL_BAD_PARAMETER, "Output VkImageCreateInfo pointer is null.");
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateSetDamageRegionKHR(const ValidationContext *val,
+ const Display *display,
+ const Surface *surface,
+ const EGLint *rects,
+ EGLint n_rects)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, display));
+ ANGLE_VALIDATION_TRY(ValidateSurface(val, display, surface));
+
+ if (!(surface->getType() & EGL_WINDOW_BIT))
+ {
+ val->setError(EGL_BAD_MATCH, "surface is not a postable surface");
+ return false;
+ }
+
+ if (surface != val->eglThread->getCurrentDrawSurface())
+ {
+ val->setError(EGL_BAD_MATCH,
+ "surface is not the current draw surface for the calling thread");
+ return false;
+ }
+
+ if (surface->getSwapBehavior() != EGL_BUFFER_DESTROYED)
+ {
+ val->setError(EGL_BAD_MATCH, "surface's swap behavior is not EGL_BUFFER_DESTROYED");
+ return false;
+ }
+
+ if (surface->isDamageRegionSet())
+ {
+ val->setError(
+ EGL_BAD_ACCESS,
+ "damage region has already been set on surface since the most recent frame boundary");
+ return false;
+ }
+
+ if (!surface->bufferAgeQueriedSinceLastSwap())
+ {
+ val->setError(EGL_BAD_ACCESS,
+ "EGL_BUFFER_AGE_KHR attribute of surface has not been queried since the most "
+ "recent frame boundary");
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateQueryDmaBufFormatsEXT(ValidationContext const *val,
+ Display const *dpy,
+ EGLint max_formats,
+ const EGLint *formats,
+ const EGLint *num_formats)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, dpy));
+
+ if (!dpy->getExtensions().imageDmaBufImportModifiersEXT)
+ {
+ val->setError(EGL_BAD_ACCESS, "EGL_EXT_dma_buf_import_modfier not supported");
+ return false;
+ }
+
+ if (max_formats < 0)
+ {
+ val->setError(EGL_BAD_PARAMETER, "max_formats should not be negative");
+ return false;
+ }
+
+ if (max_formats > 0 && formats == nullptr)
+ {
+ val->setError(EGL_BAD_PARAMETER, "if max_formats is positive, formats should not be NULL");
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateQueryDmaBufModifiersEXT(ValidationContext const *val,
+ Display const *dpy,
+ EGLint format,
+ EGLint max_modifiers,
+ const EGLuint64KHR *modifiers,
+ const EGLBoolean *external_only,
+ const EGLint *num_modifiers)
+{
+ ANGLE_VALIDATION_TRY(ValidateDisplay(val, dpy));
+
+ if (!dpy->getExtensions().imageDmaBufImportModifiersEXT)
+ {
+ val->setError(EGL_BAD_ACCESS, "EGL_EXT_dma_buf_import_modfier not supported");
+ return false;
+ }
+
+ if (max_modifiers < 0)
+ {
+ val->setError(EGL_BAD_PARAMETER, "max_modifiers should not be negative");
+ return false;
+ }
+
+ if (max_modifiers > 0 && modifiers == nullptr)
+ {
+ val->setError(EGL_BAD_PARAMETER,
+ "if max_modifiers is positive, modifiers should not be NULL");
+ return false;
+ }
+
+ if (!dpy->supportsDmaBufFormat(format))
+ {
+ val->setError(EGL_BAD_PARAMETER,
+ "format should be one of the formats advertised by QueryDmaBufFormatsEXT");
+ return false;
+ }
+ return true;
+}
+
+} // namespace egl
diff --git a/gfx/angle/checkout/src/libANGLE/validationEGL.h b/gfx/angle/checkout/src/libANGLE/validationEGL.h
new file mode 100644
index 0000000000..8f04de288f
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/validationEGL.h
@@ -0,0 +1,201 @@
+//
+// 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.
+//
+
+// validationEGL.h: Validation functions for generic EGL entry point parameters
+
+#ifndef LIBANGLE_VALIDATIONEGL_H_
+#define LIBANGLE_VALIDATIONEGL_H_
+
+#include "common/PackedEnums.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/Thread.h"
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+namespace gl
+{
+class Context;
+}
+
+namespace egl
+{
+constexpr EGLint kEglMajorVersion = 1;
+constexpr EGLint kEglMinorVersion = 5;
+
+class AttributeMap;
+struct ClientExtensions;
+struct Config;
+class Device;
+class Display;
+class Image;
+class Stream;
+class Surface;
+class Sync;
+class Thread;
+class LabeledObject;
+
+struct ValidationContext
+{
+ ValidationContext(Thread *threadIn, const char *entryPointIn, const LabeledObject *objectIn)
+ : eglThread(threadIn), entryPoint(entryPointIn), labeledObject(objectIn)
+ {}
+
+ // We should remove the message-less overload once we have messages for all EGL errors.
+ void setError(EGLint error) const;
+ ANGLE_FORMAT_PRINTF(3, 4)
+ void setError(EGLint error, const char *message...) const;
+
+ Thread *eglThread;
+ const char *entryPoint;
+ const LabeledObject *labeledObject;
+};
+
+// Object validation
+bool ValidateDisplay(const ValidationContext *val, const Display *display);
+bool ValidateSurface(const ValidationContext *val, const Display *display, const Surface *surface);
+bool ValidateConfig(const ValidationContext *val, const Display *display, const Config *config);
+bool ValidateContext(const ValidationContext *val,
+ const Display *display,
+ const gl::Context *context);
+bool ValidateImage(const ValidationContext *val, const Display *display, const Image *image);
+bool ValidateDevice(const ValidationContext *val, const Device *device);
+bool ValidateSync(const ValidationContext *val, const Display *display, const Sync *sync);
+
+// Return the requested object only if it is valid (otherwise nullptr)
+const Thread *GetThreadIfValid(const Thread *thread);
+const Display *GetDisplayIfValid(const Display *display);
+const Surface *GetSurfaceIfValid(const Display *display, const Surface *surface);
+const Image *GetImageIfValid(const Display *display, const Image *image);
+const Stream *GetStreamIfValid(const Display *display, const Stream *stream);
+const gl::Context *GetContextIfValid(const Display *display, const gl::Context *context);
+const Device *GetDeviceIfValid(const Device *device);
+const Sync *GetSyncIfValid(const Display *display, const Sync *sync);
+LabeledObject *GetLabeledObjectIfValid(Thread *thread,
+ const Display *display,
+ ObjectType objectType,
+ EGLObjectKHR object);
+
+// A template struct for determining the default value to return for each entry point.
+template <angle::EntryPoint EP, typename ReturnType>
+struct DefaultReturnValue
+{
+ static constexpr ReturnType kValue = static_cast<ReturnType>(0);
+};
+
+template <angle::EntryPoint EP, typename ReturnType>
+ReturnType GetDefaultReturnValue(Thread *thread);
+
+template <>
+ANGLE_INLINE EGLint
+GetDefaultReturnValue<angle::EntryPoint::EGLLabelObjectKHR, EGLint>(Thread *thread)
+{
+ return thread->getError();
+}
+
+template <angle::EntryPoint EP, typename ReturnType>
+ANGLE_INLINE ReturnType GetDefaultReturnValue(Thread *thread)
+{
+ return DefaultReturnValue<EP, ReturnType>::kValue;
+}
+
+// First case: handling packed enums.
+template <typename PackedT, typename FromT>
+typename std::enable_if<std::is_enum<PackedT>::value, PackedT>::type PackParam(FromT from)
+{
+ return FromEGLenum<PackedT>(from);
+}
+
+// This and the next 2 template specializations handle distinguishing between EGLint, EGLAttrib
+// and other. This is needed because on some architectures EGLint and EGLAttrib are not the same
+// base type. Previously the code conditionally compiled 2 specializations on 64 bit but it turns
+// out on WatchOS the assumption about 32/64 bit and if EGLint and ELGAttrib are the same or
+// different did not hold.
+template <typename PackedT,
+ typename FromT,
+ typename std::enable_if<!std::is_enum<PackedT>::value>::type * = nullptr,
+ typename std::enable_if<std::is_same<FromT, const EGLint *>::value>::type * = nullptr>
+typename std::remove_reference<PackedT>::type PackParam(FromT attribs)
+{
+ return AttributeMap::CreateFromIntArray(attribs);
+}
+
+template <typename PackedT,
+ typename FromT,
+ typename std::enable_if<!std::is_enum<PackedT>::value>::type * = nullptr,
+ typename std::enable_if<!std::is_same<FromT, const EGLint *>::value>::type * = nullptr,
+ typename std::enable_if<std::is_same<FromT, const EGLAttrib *>::value>::type * = nullptr>
+typename std::remove_reference<PackedT>::type PackParam(FromT attribs)
+{
+ return AttributeMap::CreateFromAttribArray(attribs);
+}
+
+template <typename PackedT,
+ typename FromT,
+ typename std::enable_if<!std::is_enum<PackedT>::value>::type * = nullptr,
+ typename std::enable_if<!std::is_same<FromT, const EGLint *>::value>::type * = nullptr,
+ typename std::enable_if<!std::is_same<FromT, const EGLAttrib *>::value>::type * = nullptr>
+typename std::remove_reference<PackedT>::type PackParam(FromT attribs)
+{
+ return static_cast<PackedT>(attribs);
+}
+
+} // namespace egl
+
+#define ANGLE_EGL_VALIDATE(THREAD, EP, OBJ, RETURN_TYPE, ...) \
+ do \
+ { \
+ const char *epname = "egl" #EP; \
+ ValidationContext vctx(THREAD, epname, OBJ); \
+ auto ANGLE_LOCAL_VAR = (Validate##EP(&vctx, ##__VA_ARGS__)); \
+ if (!ANGLE_LOCAL_VAR) \
+ { \
+ return GetDefaultReturnValue<angle::EntryPoint::EGL##EP, RETURN_TYPE>(THREAD); \
+ } \
+ } while (0)
+
+#define ANGLE_EGL_VALIDATE_VOID(THREAD, EP, OBJ, ...) \
+ do \
+ { \
+ const char *epname = "egl" #EP; \
+ ValidationContext vctx(THREAD, epname, OBJ); \
+ auto ANGLE_LOCAL_VAR = (Validate##EP(&vctx, ##__VA_ARGS__)); \
+ if (!ANGLE_LOCAL_VAR) \
+ { \
+ return; \
+ } \
+ } while (0)
+
+#define ANGLE_EGL_TRY(THREAD, EXPR, FUNCNAME, LABELOBJECT) \
+ do \
+ { \
+ auto ANGLE_LOCAL_VAR = (EXPR); \
+ if (ANGLE_LOCAL_VAR.isError()) \
+ return THREAD->setError(ANGLE_LOCAL_VAR, FUNCNAME, LABELOBJECT); \
+ } while (0)
+
+#define ANGLE_EGL_TRY_RETURN(THREAD, EXPR, FUNCNAME, LABELOBJECT, RETVAL) \
+ do \
+ { \
+ auto ANGLE_LOCAL_VAR = (EXPR); \
+ if (ANGLE_LOCAL_VAR.isError()) \
+ { \
+ THREAD->setError(ANGLE_LOCAL_VAR, FUNCNAME, LABELOBJECT); \
+ return RETVAL; \
+ } \
+ } while (0)
+
+#define ANGLE_EGLBOOLEAN_TRY(EXPR) \
+ do \
+ { \
+ EGLBoolean ANGLE_LOCAL_VAR = (EXPR); \
+ if (ANGLE_LOCAL_VAR != EGL_TRUE) \
+ { \
+ return ANGLE_LOCAL_VAR; \
+ } \
+ } while (0)
+
+#endif // LIBANGLE_VALIDATIONEGL_H_
diff --git a/gfx/angle/checkout/src/libANGLE/validationEGL_autogen.h b/gfx/angle/checkout/src/libANGLE/validationEGL_autogen.h
new file mode 100644
index 0000000000..57bd334227
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/validationEGL_autogen.h
@@ -0,0 +1,510 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from egl.xml and egl_angle_ext.xml.
+//
+// Copyright 2020 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.
+//
+// validationEGL_autogen.h:
+// Validation functions for the EGL entry points.
+
+#ifndef LIBANGLE_VALIDATION_EGL_AUTOGEN_H_
+#define LIBANGLE_VALIDATION_EGL_AUTOGEN_H_
+
+#include "libANGLE/validationEGL.h"
+
+namespace egl
+{
+
+// EGL 1.0
+bool ValidateChooseConfig(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const AttributeMap &attrib_listPacked,
+ const EGLConfig *configs,
+ EGLint config_size,
+ const EGLint *num_config);
+bool ValidateCopyBuffers(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Surface *surfacePacked,
+ EGLNativePixmapType target);
+bool ValidateCreateContext(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Config *configPacked,
+ const gl::Context *share_contextPacked,
+ const AttributeMap &attrib_listPacked);
+bool ValidateCreatePbufferSurface(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Config *configPacked,
+ const AttributeMap &attrib_listPacked);
+bool ValidateCreatePixmapSurface(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Config *configPacked,
+ EGLNativePixmapType pixmap,
+ const AttributeMap &attrib_listPacked);
+bool ValidateCreateWindowSurface(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Config *configPacked,
+ EGLNativeWindowType win,
+ const AttributeMap &attrib_listPacked);
+bool ValidateDestroyContext(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const gl::Context *ctxPacked);
+bool ValidateDestroySurface(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Surface *surfacePacked);
+bool ValidateGetConfigAttrib(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Config *configPacked,
+ EGLint attribute,
+ const EGLint *value);
+bool ValidateGetConfigs(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const EGLConfig *configs,
+ EGLint config_size,
+ const EGLint *num_config);
+bool ValidateGetCurrentDisplay(const ValidationContext *val);
+bool ValidateGetCurrentSurface(const ValidationContext *val, EGLint readdraw);
+bool ValidateGetDisplay(const ValidationContext *val, EGLNativeDisplayType display_id);
+bool ValidateGetError(const ValidationContext *val);
+bool ValidateGetProcAddress(const ValidationContext *val, const char *procname);
+bool ValidateInitialize(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const EGLint *major,
+ const EGLint *minor);
+bool ValidateMakeCurrent(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Surface *drawPacked,
+ const Surface *readPacked,
+ const gl::Context *ctxPacked);
+bool ValidateQueryContext(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const gl::Context *ctxPacked,
+ EGLint attribute,
+ const EGLint *value);
+bool ValidateQueryString(const ValidationContext *val, const egl::Display *dpyPacked, EGLint name);
+bool ValidateQuerySurface(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Surface *surfacePacked,
+ EGLint attribute,
+ const EGLint *value);
+bool ValidateSwapBuffers(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Surface *surfacePacked);
+bool ValidateTerminate(const ValidationContext *val, const egl::Display *dpyPacked);
+bool ValidateWaitGL(const ValidationContext *val);
+bool ValidateWaitNative(const ValidationContext *val, EGLint engine);
+
+// EGL 1.1
+bool ValidateBindTexImage(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Surface *surfacePacked,
+ EGLint buffer);
+bool ValidateReleaseTexImage(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Surface *surfacePacked,
+ EGLint buffer);
+bool ValidateSurfaceAttrib(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Surface *surfacePacked,
+ EGLint attribute,
+ EGLint value);
+bool ValidateSwapInterval(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ EGLint interval);
+
+// EGL 1.2
+bool ValidateBindAPI(const ValidationContext *val, EGLenum api);
+bool ValidateCreatePbufferFromClientBuffer(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ EGLenum buftype,
+ EGLClientBuffer buffer,
+ const Config *configPacked,
+ const AttributeMap &attrib_listPacked);
+bool ValidateQueryAPI(const ValidationContext *val);
+bool ValidateReleaseThread(const ValidationContext *val);
+bool ValidateWaitClient(const ValidationContext *val);
+
+// EGL 1.4
+bool ValidateGetCurrentContext(const ValidationContext *val);
+
+// EGL 1.5
+bool ValidateClientWaitSync(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Sync *syncPacked,
+ EGLint flags,
+ EGLTime timeout);
+bool ValidateCreateImage(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const gl::Context *ctxPacked,
+ EGLenum target,
+ EGLClientBuffer buffer,
+ const AttributeMap &attrib_listPacked);
+bool ValidateCreatePlatformPixmapSurface(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Config *configPacked,
+ const void *native_pixmap,
+ const AttributeMap &attrib_listPacked);
+bool ValidateCreatePlatformWindowSurface(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Config *configPacked,
+ const void *native_window,
+ const AttributeMap &attrib_listPacked);
+bool ValidateCreateSync(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ EGLenum type,
+ const AttributeMap &attrib_listPacked);
+bool ValidateDestroyImage(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Image *imagePacked);
+bool ValidateDestroySync(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Sync *syncPacked);
+bool ValidateGetPlatformDisplay(const ValidationContext *val,
+ EGLenum platform,
+ const void *native_display,
+ const AttributeMap &attrib_listPacked);
+bool ValidateGetSyncAttrib(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Sync *syncPacked,
+ EGLint attribute,
+ const EGLAttrib *value);
+bool ValidateWaitSync(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Sync *syncPacked,
+ EGLint flags);
+
+// EGL_ANDROID_blob_cache
+bool ValidateSetBlobCacheFuncsANDROID(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ EGLSetBlobFuncANDROID set,
+ EGLGetBlobFuncANDROID get);
+
+// EGL_ANDROID_create_native_client_buffer
+bool ValidateCreateNativeClientBufferANDROID(const ValidationContext *val,
+ const AttributeMap &attrib_listPacked);
+
+// EGL_ANDROID_get_frame_timestamps
+bool ValidateGetCompositorTimingSupportedANDROID(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Surface *surfacePacked,
+ CompositorTiming namePacked);
+bool ValidateGetCompositorTimingANDROID(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Surface *surfacePacked,
+ EGLint numTimestamps,
+ const EGLint *names,
+ const EGLnsecsANDROID *values);
+bool ValidateGetNextFrameIdANDROID(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Surface *surfacePacked,
+ const EGLuint64KHR *frameId);
+bool ValidateGetFrameTimestampSupportedANDROID(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Surface *surfacePacked,
+ Timestamp timestampPacked);
+bool ValidateGetFrameTimestampsANDROID(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Surface *surfacePacked,
+ EGLuint64KHR frameId,
+ EGLint numTimestamps,
+ const EGLint *timestamps,
+ const EGLnsecsANDROID *values);
+
+// EGL_ANDROID_get_native_client_buffer
+bool ValidateGetNativeClientBufferANDROID(const ValidationContext *val,
+ const struct AHardwareBuffer *buffer);
+
+// EGL_ANDROID_native_fence_sync
+bool ValidateDupNativeFenceFDANDROID(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Sync *syncPacked);
+
+// EGL_ANDROID_presentation_time
+bool ValidatePresentationTimeANDROID(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Surface *surfacePacked,
+ EGLnsecsANDROID time);
+
+// EGL_ANGLE_device_creation
+bool ValidateCreateDeviceANGLE(const ValidationContext *val,
+ EGLint device_type,
+ const void *native_device,
+ const EGLAttrib *attrib_list);
+bool ValidateReleaseDeviceANGLE(const ValidationContext *val, const Device *devicePacked);
+
+// EGL_ANGLE_feature_control
+bool ValidateQueryStringiANGLE(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ EGLint name,
+ EGLint index);
+bool ValidateQueryDisplayAttribANGLE(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ EGLint attribute,
+ const EGLAttrib *value);
+
+// EGL_ANGLE_metal_shared_event_sync
+bool ValidateCopyMetalSharedEventANGLE(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Sync *syncPacked);
+
+// EGL_ANGLE_power_preference
+bool ValidateReleaseHighPowerGPUANGLE(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const gl::Context *ctxPacked);
+bool ValidateReacquireHighPowerGPUANGLE(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const gl::Context *ctxPacked);
+bool ValidateHandleGPUSwitchANGLE(const ValidationContext *val, const egl::Display *dpyPacked);
+bool ValidateForceGPUSwitchANGLE(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ EGLint gpuIDHigh,
+ EGLint gpuIDLow);
+
+// EGL_ANGLE_prepare_swap_buffers
+bool ValidatePrepareSwapBuffersANGLE(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Surface *surfacePacked);
+
+// EGL_ANGLE_program_cache_control
+bool ValidateProgramCacheGetAttribANGLE(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ EGLenum attrib);
+bool ValidateProgramCacheQueryANGLE(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ EGLint index,
+ const void *key,
+ const EGLint *keysize,
+ const void *binary,
+ const EGLint *binarysize);
+bool ValidateProgramCachePopulateANGLE(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const void *key,
+ EGLint keysize,
+ const void *binary,
+ EGLint binarysize);
+bool ValidateProgramCacheResizeANGLE(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ EGLint limit,
+ EGLint mode);
+
+// EGL_ANGLE_query_surface_pointer
+bool ValidateQuerySurfacePointerANGLE(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Surface *surfacePacked,
+ EGLint attribute,
+ void *const *value);
+
+// EGL_ANGLE_stream_producer_d3d_texture
+bool ValidateCreateStreamProducerD3DTextureANGLE(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Stream *streamPacked,
+ const AttributeMap &attrib_listPacked);
+bool ValidateStreamPostD3DTextureANGLE(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Stream *streamPacked,
+ const void *texture,
+ const AttributeMap &attrib_listPacked);
+
+// EGL_ANGLE_swap_with_frame_token
+bool ValidateSwapBuffersWithFrameTokenANGLE(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Surface *surfacePacked,
+ EGLFrameTokenANGLE frametoken);
+
+// EGL_ANGLE_sync_control_rate
+bool ValidateGetMscRateANGLE(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Surface *surfacePacked,
+ const EGLint *numerator,
+ const EGLint *denominator);
+
+// EGL_ANGLE_vulkan_image
+bool ValidateExportVkImageANGLE(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Image *imagePacked,
+ const void *vk_image,
+ const void *vk_image_create_info);
+
+// EGL_CHROMIUM_sync_control
+bool ValidateGetSyncValuesCHROMIUM(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Surface *surfacePacked,
+ const EGLuint64KHR *ust,
+ const EGLuint64KHR *msc,
+ const EGLuint64KHR *sbc);
+
+// EGL_EXT_device_query
+bool ValidateQueryDeviceAttribEXT(const ValidationContext *val,
+ const Device *devicePacked,
+ EGLint attribute,
+ const EGLAttrib *value);
+bool ValidateQueryDeviceStringEXT(const ValidationContext *val,
+ const Device *devicePacked,
+ EGLint name);
+bool ValidateQueryDisplayAttribEXT(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ EGLint attribute,
+ const EGLAttrib *value);
+
+// EGL_EXT_image_dma_buf_import_modifiers
+bool ValidateQueryDmaBufFormatsEXT(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ EGLint max_formats,
+ const EGLint *formats,
+ const EGLint *num_formats);
+bool ValidateQueryDmaBufModifiersEXT(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ EGLint format,
+ EGLint max_modifiers,
+ const EGLuint64KHR *modifiers,
+ const EGLBoolean *external_only,
+ const EGLint *num_modifiers);
+
+// EGL_EXT_platform_base
+bool ValidateCreatePlatformPixmapSurfaceEXT(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Config *configPacked,
+ const void *native_pixmap,
+ const AttributeMap &attrib_listPacked);
+bool ValidateCreatePlatformWindowSurfaceEXT(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Config *configPacked,
+ const void *native_window,
+ const AttributeMap &attrib_listPacked);
+bool ValidateGetPlatformDisplayEXT(const ValidationContext *val,
+ EGLenum platform,
+ const void *native_display,
+ const AttributeMap &attrib_listPacked);
+
+// EGL_KHR_debug
+bool ValidateDebugMessageControlKHR(const ValidationContext *val,
+ EGLDEBUGPROCKHR callback,
+ const AttributeMap &attrib_listPacked);
+bool ValidateLabelObjectKHR(const ValidationContext *val,
+ const egl::Display *displayPacked,
+ ObjectType objectTypePacked,
+ EGLObjectKHR object,
+ EGLLabelKHR label);
+bool ValidateQueryDebugKHR(const ValidationContext *val, EGLint attribute, const EGLAttrib *value);
+
+// EGL_KHR_fence_sync
+bool ValidateClientWaitSyncKHR(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Sync *syncPacked,
+ EGLint flags,
+ EGLTimeKHR timeout);
+bool ValidateCreateSyncKHR(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ EGLenum type,
+ const AttributeMap &attrib_listPacked);
+bool ValidateDestroySyncKHR(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Sync *syncPacked);
+bool ValidateGetSyncAttribKHR(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Sync *syncPacked,
+ EGLint attribute,
+ const EGLint *value);
+
+// EGL_KHR_image
+bool ValidateCreateImageKHR(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const gl::Context *ctxPacked,
+ EGLenum target,
+ EGLClientBuffer buffer,
+ const AttributeMap &attrib_listPacked);
+bool ValidateDestroyImageKHR(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Image *imagePacked);
+
+// EGL_KHR_lock_surface3
+bool ValidateLockSurfaceKHR(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Surface *surfacePacked,
+ const AttributeMap &attrib_listPacked);
+bool ValidateQuerySurface64KHR(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Surface *surfacePacked,
+ EGLint attribute,
+ const EGLAttribKHR *value);
+bool ValidateUnlockSurfaceKHR(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Surface *surfacePacked);
+
+// EGL_KHR_partial_update
+bool ValidateSetDamageRegionKHR(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Surface *surfacePacked,
+ const EGLint *rects,
+ EGLint n_rects);
+
+// EGL_KHR_reusable_sync
+bool ValidateSignalSyncKHR(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Sync *syncPacked,
+ EGLenum mode);
+
+// EGL_KHR_stream
+bool ValidateCreateStreamKHR(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const AttributeMap &attrib_listPacked);
+bool ValidateDestroyStreamKHR(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Stream *streamPacked);
+bool ValidateQueryStreamKHR(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Stream *streamPacked,
+ EGLenum attribute,
+ const EGLint *value);
+bool ValidateQueryStreamu64KHR(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Stream *streamPacked,
+ EGLenum attribute,
+ const EGLuint64KHR *value);
+bool ValidateStreamAttribKHR(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Stream *streamPacked,
+ EGLenum attribute,
+ EGLint value);
+
+// EGL_KHR_stream_consumer_gltexture
+bool ValidateStreamConsumerAcquireKHR(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Stream *streamPacked);
+bool ValidateStreamConsumerGLTextureExternalKHR(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Stream *streamPacked);
+bool ValidateStreamConsumerReleaseKHR(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Stream *streamPacked);
+
+// EGL_KHR_swap_buffers_with_damage
+bool ValidateSwapBuffersWithDamageKHR(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Surface *surfacePacked,
+ const EGLint *rects,
+ EGLint n_rects);
+
+// EGL_KHR_wait_sync
+bool ValidateWaitSyncKHR(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Sync *syncPacked,
+ EGLint flags);
+
+// EGL_NV_post_sub_buffer
+bool ValidatePostSubBufferNV(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Surface *surfacePacked,
+ EGLint x,
+ EGLint y,
+ EGLint width,
+ EGLint height);
+
+// EGL_NV_stream_consumer_gltexture_yuv
+bool ValidateStreamConsumerGLTextureExternalAttribsNV(const ValidationContext *val,
+ const egl::Display *dpyPacked,
+ const Stream *streamPacked,
+ const AttributeMap &attrib_listPacked);
+} // namespace egl
+
+#endif // LIBANGLE_VALIDATION_EGL_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libANGLE/validationES.cpp b/gfx/angle/checkout/src/libANGLE/validationES.cpp
new file mode 100644
index 0000000000..ddc586b1ad
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/validationES.cpp
@@ -0,0 +1,8666 @@
+//
+// Copyright 2013 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.
+//
+
+// validationES.h: Validation functions for generic OpenGL ES entry point parameters
+
+#include "libANGLE/validationES.h"
+
+#include "libANGLE/Context.h"
+#include "libANGLE/Display.h"
+#include "libANGLE/ErrorStrings.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/Image.h"
+#include "libANGLE/Program.h"
+#include "libANGLE/Query.h"
+#include "libANGLE/Texture.h"
+#include "libANGLE/TransformFeedback.h"
+#include "libANGLE/angletypes.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/queryconversions.h"
+#include "libANGLE/queryutils.h"
+#include "libANGLE/validationES2.h"
+#include "libANGLE/validationES3.h"
+
+#include "common/mathutil.h"
+#include "common/utilities.h"
+
+using namespace angle;
+
+namespace gl
+{
+using namespace err;
+
+namespace
+{
+bool CompressedTextureFormatRequiresExactSize(GLenum internalFormat)
+{
+ // List of compressed format that require that the texture size is smaller than or a multiple of
+ // the compressed block size.
+ switch (internalFormat)
+ {
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
+ case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
+ case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
+ case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
+ case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
+ case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
+ case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
+ case GL_COMPRESSED_RGBA8_LOSSY_DECODE_ETC2_EAC_ANGLE:
+ case GL_COMPRESSED_SRGB8_ALPHA8_LOSSY_DECODE_ETC2_EAC_ANGLE:
+ case GL_COMPRESSED_RED_RGTC1_EXT:
+ case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:
+ case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
+ case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:
+ case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
+ case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
+ case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
+ return true;
+
+ default:
+ return false;
+ }
+}
+bool CompressedSubTextureFormatRequiresExactSize(GLenum internalFormat)
+{
+ // Compressed sub textures have additional formats that requires exact size.
+ // ES 3.1, Section 8.7, Page 171
+ return CompressedTextureFormatRequiresExactSize(internalFormat) ||
+ IsETC2EACFormat(internalFormat) || IsASTC2DFormat(internalFormat);
+}
+
+bool DifferenceCanOverflow(GLint a, GLint b)
+{
+ CheckedNumeric<GLint> checkedA(a);
+ checkedA -= b;
+ // Use negation to make sure that the difference can't overflow regardless of the order.
+ checkedA = -checkedA;
+ return !checkedA.IsValid();
+}
+
+bool ValidReadPixelsTypeEnum(const Context *context, GLenum type)
+{
+ switch (type)
+ {
+ // Types referenced in Table 3.4 of the ES 2.0.25 spec
+ case GL_UNSIGNED_BYTE:
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ case GL_UNSIGNED_SHORT_5_6_5:
+ return context->getClientVersion() >= ES_2_0;
+
+ // Types referenced in Table 3.2 of the ES 3.0.5 spec (Except depth stencil)
+ case GL_BYTE:
+ case GL_INT:
+ case GL_SHORT:
+ case GL_UNSIGNED_INT:
+ case GL_UNSIGNED_INT_10F_11F_11F_REV:
+ case GL_UNSIGNED_INT_2_10_10_10_REV:
+ case GL_UNSIGNED_INT_5_9_9_9_REV:
+ case GL_UNSIGNED_SHORT:
+ case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
+ case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
+ return context->getClientVersion() >= ES_3_0;
+
+ case GL_FLOAT:
+ return context->getClientVersion() >= ES_3_0 ||
+ context->getExtensions().textureFloatOES ||
+ context->getExtensions().colorBufferHalfFloatEXT;
+
+ case GL_HALF_FLOAT:
+ return context->getClientVersion() >= ES_3_0 ||
+ context->getExtensions().textureHalfFloatOES;
+
+ case GL_HALF_FLOAT_OES:
+ return context->getExtensions().colorBufferHalfFloatEXT;
+
+ default:
+ return false;
+ }
+}
+
+bool ValidReadPixelsFormatEnum(const Context *context, GLenum format)
+{
+ switch (format)
+ {
+ // Formats referenced in Table 3.4 of the ES 2.0.25 spec (Except luminance)
+ case GL_RGBA:
+ case GL_RGB:
+ case GL_ALPHA:
+ return context->getClientVersion() >= ES_2_0;
+
+ // Formats referenced in Table 3.2 of the ES 3.0.5 spec
+ case GL_RG:
+ case GL_RED:
+ case GL_RGBA_INTEGER:
+ case GL_RGB_INTEGER:
+ case GL_RG_INTEGER:
+ case GL_RED_INTEGER:
+ return context->getClientVersion() >= ES_3_0;
+
+ case GL_SRGB_ALPHA_EXT:
+ case GL_SRGB_EXT:
+ return context->getExtensions().sRGBEXT;
+
+ case GL_BGRA_EXT:
+ return context->getExtensions().readFormatBgraEXT;
+
+ case GL_RGBX8_ANGLE:
+ return context->getExtensions().rgbxInternalFormatANGLE;
+
+ default:
+ return false;
+ }
+}
+
+bool ValidReadPixelsUnsignedNormalizedDepthType(const Context *context,
+ const gl::InternalFormat *info,
+ GLenum type)
+{
+ bool supportsReadDepthNV = context->getExtensions().readDepthNV && (info->depthBits > 0);
+ switch (type)
+ {
+ case GL_UNSIGNED_SHORT:
+ case GL_UNSIGNED_INT:
+ case GL_UNSIGNED_INT_24_8:
+ return supportsReadDepthNV;
+ default:
+ return false;
+ }
+}
+
+bool ValidReadPixelsFloatDepthType(const Context *context,
+ const gl::InternalFormat *info,
+ GLenum type)
+{
+ return context->getExtensions().readDepthNV && (type == GL_FLOAT) &&
+ context->getExtensions().depthBufferFloat2NV;
+}
+
+bool ValidReadPixelsFormatType(const Context *context,
+ const gl::InternalFormat *info,
+ GLenum format,
+ GLenum type)
+{
+ switch (info->componentType)
+ {
+ 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
+ switch (format)
+ {
+ case GL_RGBA:
+ return ((type == GL_UNSIGNED_BYTE) && info->pixelBytes >= 1) ||
+ (context->getExtensions().textureNorm16EXT &&
+ (type == GL_UNSIGNED_SHORT) && info->pixelBytes >= 2);
+ case GL_BGRA_EXT:
+ return context->getExtensions().readFormatBgraEXT && (type == GL_UNSIGNED_BYTE);
+ case GL_STENCIL_INDEX_OES:
+ return context->getExtensions().readStencilNV && (type == GL_UNSIGNED_BYTE);
+ case GL_DEPTH_COMPONENT:
+ return ValidReadPixelsUnsignedNormalizedDepthType(context, info, type);
+ case GL_DEPTH_STENCIL_OES:
+ return context->getExtensions().readDepthStencilNV &&
+ (type == GL_UNSIGNED_INT_24_8_OES) && info->stencilBits > 0;
+ case GL_RGBX8_ANGLE:
+ return context->getExtensions().rgbxInternalFormatANGLE &&
+ (type == GL_UNSIGNED_BYTE);
+ default:
+ return false;
+ }
+ case GL_SIGNED_NORMALIZED:
+ return (format == GL_RGBA && type == GL_BYTE && info->pixelBytes >= 1) ||
+ (context->getExtensions().textureNorm16EXT && format == GL_RGBA &&
+ type == GL_UNSIGNED_SHORT && info->pixelBytes >= 2);
+
+ 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:
+ switch (format)
+ {
+ case GL_RGBA:
+ return (type == GL_FLOAT);
+ case GL_DEPTH_COMPONENT:
+ return ValidReadPixelsFloatDepthType(context, info, type);
+ case GL_DEPTH_STENCIL_OES:
+ return context->getExtensions().readDepthStencilNV &&
+ type == GL_FLOAT_32_UNSIGNED_INT_24_8_REV && info->stencilBits > 0;
+ default:
+ return false;
+ }
+ default:
+ UNREACHABLE();
+ return false;
+ }
+}
+
+template <typename ParamType>
+bool ValidateTextureWrapModeValue(const Context *context,
+ angle::EntryPoint entryPoint,
+ const ParamType *params,
+ bool restrictedWrapModes)
+{
+ switch (ConvertToGLenum(params[0]))
+ {
+ case GL_CLAMP_TO_EDGE:
+ break;
+
+ case GL_CLAMP_TO_BORDER:
+ if (!context->getExtensions().textureBorderClampAny() &&
+ context->getClientVersion() < ES_3_2)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kExtensionNotEnabled);
+ return false;
+ }
+ break;
+
+ case GL_REPEAT:
+ case GL_MIRRORED_REPEAT:
+ if (restrictedWrapModes)
+ {
+ // OES_EGL_image_external and ANGLE_texture_rectangle specifies this error.
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidWrapModeTexture);
+ return false;
+ }
+ break;
+
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureWrap);
+ return false;
+ }
+
+ return true;
+}
+
+template <typename ParamType>
+bool ValidateTextureMinFilterValue(const Context *context,
+ angle::EntryPoint entryPoint,
+ const ParamType *params,
+ bool restrictedMinFilter)
+{
+ switch (ConvertToGLenum(params[0]))
+ {
+ case GL_NEAREST:
+ case GL_LINEAR:
+ break;
+
+ case GL_NEAREST_MIPMAP_NEAREST:
+ case GL_LINEAR_MIPMAP_NEAREST:
+ case GL_NEAREST_MIPMAP_LINEAR:
+ case GL_LINEAR_MIPMAP_LINEAR:
+ if (restrictedMinFilter)
+ {
+ // OES_EGL_image_external specifies this error.
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFilterTexture);
+ return false;
+ }
+ break;
+
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureFilterParam);
+ return false;
+ }
+
+ return true;
+}
+
+template <typename ParamType>
+bool ValidateTextureMagFilterValue(const Context *context,
+ angle::EntryPoint entryPoint,
+ const ParamType *params)
+{
+ switch (ConvertToGLenum(params[0]))
+ {
+ case GL_NEAREST:
+ case GL_LINEAR:
+ break;
+
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureFilterParam);
+ return false;
+ }
+
+ return true;
+}
+
+template <typename ParamType>
+bool ValidateTextureCompareModeValue(const Context *context,
+ angle::EntryPoint entryPoint,
+ const ParamType *params)
+{
+ // Acceptable mode parameters from GLES 3.0.2 spec, table 3.17
+ switch (ConvertToGLenum(params[0]))
+ {
+ case GL_NONE:
+ case GL_COMPARE_REF_TO_TEXTURE:
+ break;
+
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kUnknownParameter);
+ return false;
+ }
+
+ return true;
+}
+
+template <typename ParamType>
+bool ValidateTextureCompareFuncValue(const Context *context,
+ angle::EntryPoint entryPoint,
+ const ParamType *params)
+{
+ // Acceptable function parameters from GLES 3.0.2 spec, table 3.17
+ switch (ConvertToGLenum(params[0]))
+ {
+ case GL_LEQUAL:
+ case GL_GEQUAL:
+ case GL_LESS:
+ case GL_GREATER:
+ case GL_EQUAL:
+ case GL_NOTEQUAL:
+ case GL_ALWAYS:
+ case GL_NEVER:
+ break;
+
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kUnknownParameter);
+ return false;
+ }
+
+ return true;
+}
+
+template <typename ParamType>
+bool ValidateTextureSRGBDecodeValue(const Context *context,
+ angle::EntryPoint entryPoint,
+ const ParamType *params)
+{
+ if (!context->getExtensions().textureSRGBDecodeEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kExtensionNotEnabled);
+ return false;
+ }
+
+ switch (ConvertToGLenum(params[0]))
+ {
+ case GL_DECODE_EXT:
+ case GL_SKIP_DECODE_EXT:
+ break;
+
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kUnknownParameter);
+ return false;
+ }
+
+ return true;
+}
+
+template <typename ParamType>
+bool ValidateTextureSRGBOverrideValue(const Context *context,
+ angle::EntryPoint entryPoint,
+ const ParamType *params)
+{
+ if (!context->getExtensions().textureFormatSRGBOverrideEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kExtensionNotEnabled);
+ return false;
+ }
+
+ switch (ConvertToGLenum(params[0]))
+ {
+ case GL_SRGB:
+ case GL_NONE:
+ break;
+
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kUnknownParameter);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateTextureMaxAnisotropyExtensionEnabled(const Context *context,
+ angle::EntryPoint entryPoint)
+{
+ if (!context->getExtensions().textureFilterAnisotropicEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kExtensionNotEnabled);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateTextureMaxAnisotropyValue(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat paramValue)
+{
+ if (!ValidateTextureMaxAnisotropyExtensionEnabled(context, entryPoint))
+ {
+ return false;
+ }
+
+ GLfloat largest = context->getCaps().maxTextureAnisotropy;
+
+ if (paramValue < 1 || paramValue > largest)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kOutsideOfBounds);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateFragmentShaderColorBufferMaskMatch(const Context *context)
+{
+ const auto &glState = context->getState();
+ const Program *program = context->getActiveLinkedProgram();
+ const Framebuffer *framebuffer = glState.getDrawFramebuffer();
+
+ auto drawBufferMask =
+ framebuffer->getDrawBufferMask() & glState.getBlendStateExt().compareColorMask(0);
+ auto fragmentOutputMask = program->getExecutable().getActiveOutputVariablesMask();
+
+ return drawBufferMask == (drawBufferMask & fragmentOutputMask);
+}
+
+bool ValidateFragmentShaderColorBufferTypeMatch(const Context *context)
+{
+ const ProgramExecutable *executable = context->getState().getLinkedProgramExecutable(context);
+ const Framebuffer *framebuffer = context->getState().getDrawFramebuffer();
+
+ return ValidateComponentTypeMasks(executable->getFragmentOutputsTypeMask().to_ulong(),
+ framebuffer->getDrawBufferTypeMask().to_ulong(),
+ executable->getActiveOutputVariablesMask().to_ulong(),
+ framebuffer->getDrawBufferMask().to_ulong());
+}
+
+bool ValidateVertexShaderAttributeTypeMatch(const Context *context)
+{
+ const auto &glState = context->getState();
+ const Program *program = context->getActiveLinkedProgram();
+ const VertexArray *vao = context->getState().getVertexArray();
+
+ if (!program)
+ {
+ return false;
+ }
+
+ unsigned long stateCurrentValuesTypeBits = glState.getCurrentValuesTypeMask().to_ulong();
+ unsigned long vaoAttribTypeBits = vao->getAttributesTypeMask().to_ulong();
+ unsigned long vaoAttribEnabledMask = vao->getAttributesMask().to_ulong();
+
+ vaoAttribEnabledMask |= vaoAttribEnabledMask << kMaxComponentTypeMaskIndex;
+ vaoAttribTypeBits = (vaoAttribEnabledMask & vaoAttribTypeBits);
+ vaoAttribTypeBits |= (~vaoAttribEnabledMask & stateCurrentValuesTypeBits);
+
+ const ProgramExecutable &executable = program->getExecutable();
+ return ValidateComponentTypeMasks(executable.getAttributesTypeMask().to_ulong(),
+ vaoAttribTypeBits, executable.getAttributesMask().to_ulong(),
+ 0xFFFF);
+}
+
+bool IsCompatibleDrawModeWithGeometryShader(PrimitiveMode drawMode,
+ PrimitiveMode geometryShaderInputPrimitiveType)
+{
+ // [EXT_geometry_shader] Section 11.1gs.1, Geometry Shader Input Primitives
+ switch (drawMode)
+ {
+ case PrimitiveMode::Points:
+ return geometryShaderInputPrimitiveType == PrimitiveMode::Points;
+ case PrimitiveMode::Lines:
+ case PrimitiveMode::LineStrip:
+ case PrimitiveMode::LineLoop:
+ return geometryShaderInputPrimitiveType == PrimitiveMode::Lines;
+ case PrimitiveMode::LinesAdjacency:
+ case PrimitiveMode::LineStripAdjacency:
+ return geometryShaderInputPrimitiveType == PrimitiveMode::LinesAdjacency;
+ case PrimitiveMode::Triangles:
+ case PrimitiveMode::TriangleFan:
+ case PrimitiveMode::TriangleStrip:
+ return geometryShaderInputPrimitiveType == PrimitiveMode::Triangles;
+ case PrimitiveMode::TrianglesAdjacency:
+ case PrimitiveMode::TriangleStripAdjacency:
+ return geometryShaderInputPrimitiveType == PrimitiveMode::TrianglesAdjacency;
+ default:
+ UNREACHABLE();
+ return false;
+ }
+}
+
+// GLES1 texture parameters are a small subset of the others
+bool IsValidGLES1TextureParameter(GLenum pname)
+{
+ switch (pname)
+ {
+ case GL_TEXTURE_MAG_FILTER:
+ case GL_TEXTURE_MIN_FILTER:
+ case GL_TEXTURE_WRAP_S:
+ case GL_TEXTURE_WRAP_T:
+ case GL_TEXTURE_WRAP_R:
+ case GL_GENERATE_MIPMAP:
+ case GL_TEXTURE_CROP_RECT_OES:
+ return true;
+ default:
+ return false;
+ }
+}
+
+unsigned int GetSamplerParameterCount(GLenum pname)
+{
+ return pname == GL_TEXTURE_BORDER_COLOR ? 4 : 1;
+}
+
+const char *ValidateProgramDrawAdvancedBlendState(const Context *context, Program *program)
+{
+ const State &state = context->getState();
+ const BlendEquationBitSet &supportedBlendEquations =
+ program->getExecutable().getAdvancedBlendEquations();
+ const DrawBufferMask &enabledDrawBufferMask = state.getBlendStateExt().getEnabledMask();
+
+ for (size_t blendEnabledBufferIndex : enabledDrawBufferMask)
+ {
+ const gl::BlendEquationType &enabledBlendEquation = gl::FromGLenum<gl::BlendEquationType>(
+ state.getBlendStateExt().getEquationColorIndexed(blendEnabledBufferIndex));
+
+ if (enabledBlendEquation < gl::BlendEquationType::Multiply ||
+ enabledBlendEquation > gl::BlendEquationType::HslLuminosity)
+ {
+ continue;
+ }
+
+ if (!supportedBlendEquations.test(enabledBlendEquation))
+ {
+ return gl::err::kBlendEquationNotEnabled;
+ }
+ }
+
+ return nullptr;
+}
+
+ANGLE_INLINE const char *ValidateProgramDrawStates(const Context *context,
+ const Extensions &extensions,
+ Program *program)
+{
+ const State &state = context->getState();
+ if (extensions.multiviewOVR || extensions.multiview2OVR)
+ {
+ const int programNumViews = program->usesMultiview() ? program->getNumViews() : 1;
+ Framebuffer *framebuffer = state.getDrawFramebuffer();
+ const int framebufferNumViews = framebuffer->getNumViews();
+
+ if (framebufferNumViews != programNumViews)
+ {
+ return gl::err::kMultiviewMismatch;
+ }
+
+ if (state.isTransformFeedbackActiveUnpaused() && framebufferNumViews > 1)
+ {
+ return gl::err::kMultiviewTransformFeedback;
+ }
+
+ if (extensions.disjointTimerQueryEXT && framebufferNumViews > 1 &&
+ state.isQueryActive(QueryType::TimeElapsed))
+ {
+ return gl::err::kMultiviewTimerQuery;
+ }
+ }
+
+ // Uniform buffer validation
+ for (unsigned int uniformBlockIndex = 0;
+ uniformBlockIndex < program->getActiveUniformBlockCount(); uniformBlockIndex++)
+ {
+ const InterfaceBlock &uniformBlock = program->getUniformBlockByIndex(uniformBlockIndex);
+ GLuint blockBinding = program->getUniformBlockBinding(uniformBlockIndex);
+ const OffsetBindingPointer<Buffer> &uniformBuffer =
+ state.getIndexedUniformBuffer(blockBinding);
+
+ if (uniformBuffer.get() == nullptr && context->isWebGL())
+ {
+ // undefined behaviour
+ return gl::err::kUniformBufferUnbound;
+ }
+
+ size_t uniformBufferSize = GetBoundBufferAvailableSize(uniformBuffer);
+ if (uniformBufferSize < uniformBlock.dataSize &&
+ (context->isWebGL() || context->isBufferAccessValidationEnabled()))
+ {
+ // undefined behaviour
+ return gl::err::kUniformBufferTooSmall;
+ }
+
+ if (uniformBuffer->hasWebGLXFBBindingConflict(context->isWebGL()))
+ {
+ return gl::err::kUniformBufferBoundForTransformFeedback;
+ }
+ }
+
+ // Enabled blend equation validation
+ const char *errorString = nullptr;
+
+ if (extensions.blendEquationAdvancedKHR)
+ {
+ errorString = ValidateProgramDrawAdvancedBlendState(context, program);
+ }
+
+ return errorString;
+}
+} // anonymous namespace
+
+void SetRobustLengthParam(const GLsizei *length, GLsizei value)
+{
+ if (length)
+ {
+ // Currently we modify robust length parameters in the validation layer. We should be only
+ // doing this in the Context instead.
+ // TODO(http://anglebug.com/4406): Remove when possible.
+ *const_cast<GLsizei *>(length) = value;
+ }
+}
+
+bool ValidTextureTarget(const Context *context, TextureType type)
+{
+ switch (type)
+ {
+ case TextureType::_2D:
+ case TextureType::CubeMap:
+ return true;
+
+ case TextureType::Rectangle:
+ return context->getExtensions().textureRectangleANGLE;
+
+ case TextureType::_3D:
+ return ((context->getClientMajorVersion() >= 3) ||
+ context->getExtensions().texture3DOES);
+
+ case TextureType::_2DArray:
+ return (context->getClientMajorVersion() >= 3);
+
+ case TextureType::_2DMultisample:
+ return (context->getClientVersion() >= Version(3, 1) ||
+ context->getExtensions().textureMultisampleANGLE);
+ case TextureType::_2DMultisampleArray:
+ return context->getExtensions().textureStorageMultisample2dArrayOES;
+
+ case TextureType::CubeMapArray:
+ return (context->getClientVersion() >= Version(3, 2) ||
+ context->getExtensions().textureCubeMapArrayAny());
+
+ case TextureType::VideoImage:
+ return context->getExtensions().videoTextureWEBGL;
+
+ case TextureType::Buffer:
+ return (context->getClientVersion() >= Version(3, 2) ||
+ context->getExtensions().textureBufferAny());
+
+ default:
+ return false;
+ }
+}
+
+bool ValidTexture2DTarget(const Context *context, TextureType type)
+{
+ switch (type)
+ {
+ case TextureType::_2D:
+ case TextureType::CubeMap:
+ return true;
+
+ case TextureType::Rectangle:
+ return context->getExtensions().textureRectangleANGLE;
+
+ default:
+ return false;
+ }
+}
+
+bool ValidTexture3DTarget(const Context *context, TextureType target)
+{
+ switch (target)
+ {
+ case TextureType::_3D:
+ case TextureType::_2DArray:
+ return (context->getClientMajorVersion() >= 3);
+
+ case TextureType::CubeMapArray:
+ return (context->getClientVersion() >= Version(3, 2) ||
+ context->getExtensions().textureCubeMapArrayAny());
+
+ default:
+ return false;
+ }
+}
+
+// Most texture GL calls are not compatible with external textures, so we have a separate validation
+// function for use in the GL calls that do
+bool ValidTextureExternalTarget(const Context *context, TextureType target)
+{
+ return (target == TextureType::External) &&
+ (context->getExtensions().EGLImageExternalOES ||
+ context->getExtensions().EGLStreamConsumerExternalNV);
+}
+
+bool ValidTextureExternalTarget(const Context *context, TextureTarget target)
+{
+ return (target == TextureTarget::External) &&
+ ValidTextureExternalTarget(context, TextureType::External);
+}
+
+// This function differs from ValidTextureTarget in that the target must be
+// usable as the destination of a 2D operation-- so a cube face is valid, but
+// GL_TEXTURE_CUBE_MAP is not.
+// Note: duplicate of IsInternalTextureTarget
+bool ValidTexture2DDestinationTarget(const Context *context, TextureTarget target)
+{
+ switch (target)
+ {
+ case TextureTarget::_2D:
+ case TextureTarget::CubeMapNegativeX:
+ case TextureTarget::CubeMapNegativeY:
+ case TextureTarget::CubeMapNegativeZ:
+ case TextureTarget::CubeMapPositiveX:
+ case TextureTarget::CubeMapPositiveY:
+ case TextureTarget::CubeMapPositiveZ:
+ return true;
+ case TextureTarget::Rectangle:
+ return context->getExtensions().textureRectangleANGLE;
+ case TextureTarget::VideoImage:
+ return context->getExtensions().videoTextureWEBGL;
+ default:
+ return false;
+ }
+}
+
+bool ValidateTransformFeedbackPrimitiveMode(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode transformFeedbackPrimitiveMode,
+ PrimitiveMode renderPrimitiveMode)
+{
+ ASSERT(context);
+
+ if ((!context->getExtensions().geometryShaderAny() ||
+ !context->getExtensions().tessellationShaderEXT) &&
+ context->getClientVersion() < ES_3_2)
+ {
+ // It is an invalid operation to call DrawArrays or DrawArraysInstanced with a draw mode
+ // that does not match the current transform feedback object's draw mode (if transform
+ // feedback is active), (3.0.2, section 2.14, pg 86)
+ return transformFeedbackPrimitiveMode == renderPrimitiveMode;
+ }
+
+ const ProgramExecutable *executable = context->getState().getLinkedProgramExecutable(context);
+ ASSERT(executable);
+ if (executable->hasLinkedShaderStage(ShaderType::Geometry))
+ {
+ // If geometry shader is active, transform feedback mode must match what is output from this
+ // stage.
+ renderPrimitiveMode = executable->getGeometryShaderOutputPrimitiveType();
+ }
+ else if (executable->hasLinkedShaderStage(ShaderType::TessEvaluation))
+ {
+ // Similarly with tessellation shaders, but only if no geometry shader is present. With
+ // tessellation shaders, only triangles are possibly output.
+ return transformFeedbackPrimitiveMode == PrimitiveMode::Triangles &&
+ executable->getTessGenMode() == GL_TRIANGLES;
+ }
+
+ // [GL_EXT_geometry_shader] Table 12.1gs
+ switch (renderPrimitiveMode)
+ {
+ case PrimitiveMode::Points:
+ return transformFeedbackPrimitiveMode == PrimitiveMode::Points;
+ case PrimitiveMode::Lines:
+ case PrimitiveMode::LineStrip:
+ case PrimitiveMode::LineLoop:
+ return transformFeedbackPrimitiveMode == PrimitiveMode::Lines;
+ case PrimitiveMode::Triangles:
+ case PrimitiveMode::TriangleFan:
+ case PrimitiveMode::TriangleStrip:
+ return transformFeedbackPrimitiveMode == PrimitiveMode::Triangles;
+ case PrimitiveMode::Patches:
+ return transformFeedbackPrimitiveMode == PrimitiveMode::Patches;
+ default:
+ UNREACHABLE();
+ return false;
+ }
+}
+
+bool ValidateDrawElementsInstancedBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLsizei count,
+ DrawElementsType type,
+ const void *indices,
+ GLsizei primcount)
+{
+ if (primcount <= 0)
+ {
+ if (primcount < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativePrimcount);
+ return false;
+ }
+
+ // Early exit.
+ return ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices,
+ primcount);
+ }
+
+ if (!ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices, primcount))
+ {
+ return false;
+ }
+
+ if (count == 0)
+ {
+ // Early exit.
+ return true;
+ }
+
+ return ValidateDrawInstancedAttribs(context, entryPoint, primcount);
+}
+
+bool ValidateDrawArraysInstancedBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLint first,
+ GLsizei count,
+ GLsizei primcount)
+{
+ if (primcount <= 0)
+ {
+ if (primcount < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativePrimcount);
+ return false;
+ }
+
+ // Early exit.
+ return ValidateDrawArraysCommon(context, entryPoint, mode, first, count, primcount);
+ }
+
+ if (!ValidateDrawArraysCommon(context, entryPoint, mode, first, count, primcount))
+ {
+ return false;
+ }
+
+ if (count == 0)
+ {
+ // Early exit.
+ return true;
+ }
+
+ return ValidateDrawInstancedAttribs(context, entryPoint, primcount);
+}
+
+bool ValidateDrawInstancedANGLE(const Context *context, angle::EntryPoint entryPoint)
+{
+ // Verify there is at least one active attribute with a divisor of zero
+ const State &state = context->getState();
+ const ProgramExecutable *executable = state.getLinkedProgramExecutable(context);
+
+ if (!executable)
+ {
+ // No executable means there is no Program/PPO bound, which is undefined behavior, but isn't
+ // an error.
+ context->getState().getDebug().insertMessage(
+ GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR, 0, GL_DEBUG_SEVERITY_HIGH,
+ std::string("Attempting to draw without a program"), gl::LOG_WARN, entryPoint);
+ return true;
+ }
+
+ const auto &attribs = state.getVertexArray()->getVertexAttributes();
+ const auto &bindings = state.getVertexArray()->getVertexBindings();
+ for (size_t attributeIndex = 0; attributeIndex < attribs.size(); attributeIndex++)
+ {
+ const VertexAttribute &attrib = attribs[attributeIndex];
+ const VertexBinding &binding = bindings[attrib.bindingIndex];
+ if (executable->isAttribLocationActive(attributeIndex) && binding.getDivisor() == 0)
+ {
+ return true;
+ }
+ }
+
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kNoZeroDivisor);
+ return false;
+}
+
+bool ValidTexture3DDestinationTarget(const Context *context, TextureTarget target)
+{
+ switch (target)
+ {
+ case TextureTarget::_3D:
+ case TextureTarget::_2DArray:
+ return true;
+ case TextureTarget::CubeMapArray:
+ return (context->getClientVersion() >= Version(3, 2) ||
+ context->getExtensions().textureCubeMapArrayAny());
+ default:
+ return false;
+ }
+}
+
+bool ValidTexLevelDestinationTarget(const Context *context, TextureType type)
+{
+ switch (type)
+ {
+ case TextureType::_2D:
+ case TextureType::_2DArray:
+ case TextureType::_2DMultisample:
+ case TextureType::CubeMap:
+ case TextureType::_3D:
+ return true;
+ case TextureType::CubeMapArray:
+ return (context->getClientVersion() >= Version(3, 2) ||
+ context->getExtensions().textureCubeMapArrayAny());
+ case TextureType::Rectangle:
+ return context->getExtensions().textureRectangleANGLE;
+ case TextureType::_2DMultisampleArray:
+ return context->getExtensions().textureStorageMultisample2dArrayOES;
+ case TextureType::Buffer:
+ return (context->getClientVersion() >= Version(3, 2) ||
+ context->getExtensions().textureBufferAny());
+ default:
+ return false;
+ }
+}
+
+bool ValidFramebufferTarget(const Context *context, GLenum target)
+{
+ static_assert(GL_DRAW_FRAMEBUFFER_ANGLE == GL_DRAW_FRAMEBUFFER &&
+ GL_READ_FRAMEBUFFER_ANGLE == GL_READ_FRAMEBUFFER,
+ "ANGLE framebuffer enums must equal the ES3 framebuffer enums.");
+
+ switch (target)
+ {
+ case GL_FRAMEBUFFER:
+ return true;
+
+ case GL_READ_FRAMEBUFFER:
+ case GL_DRAW_FRAMEBUFFER:
+ return (context->getExtensions().framebufferBlitAny() ||
+ context->getClientMajorVersion() >= 3);
+
+ default:
+ return false;
+ }
+}
+
+bool ValidMipLevel(const Context *context, TextureType type, GLint level)
+{
+ const auto &caps = context->getCaps();
+ int maxDimension = 0;
+ switch (type)
+ {
+ case TextureType::_2D:
+ case TextureType::_2DArray:
+ case TextureType::_2DMultisample:
+ case TextureType::_2DMultisampleArray:
+ // TODO(http://anglebug.com/2775): It's a bit unclear what the "maximum allowable
+ // level-of-detail" for multisample textures should be. Could maybe make it zero.
+ maxDimension = caps.max2DTextureSize;
+ break;
+
+ case TextureType::CubeMap:
+ case TextureType::CubeMapArray:
+ maxDimension = caps.maxCubeMapTextureSize;
+ break;
+
+ case TextureType::External:
+ case TextureType::Rectangle:
+ case TextureType::VideoImage:
+ case TextureType::Buffer:
+ return level == 0;
+
+ case TextureType::_3D:
+ maxDimension = caps.max3DTextureSize;
+ break;
+
+ default:
+ UNREACHABLE();
+ }
+
+ return level <= log2(maxDimension) && level >= 0;
+}
+
+bool ValidImageSizeParameters(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLint level,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ bool isSubImage)
+{
+ if (width < 0 || height < 0 || depth < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeSize);
+ return false;
+ }
+ // TexSubImage parameters can be NPOT without textureNPOT extension,
+ // as long as the destination texture is POT.
+ bool hasNPOTSupport =
+ context->getExtensions().textureNpotOES || context->getClientVersion() >= Version(3, 0);
+ if (!isSubImage && !hasNPOTSupport &&
+ (level != 0 && (!isPow2(width) || !isPow2(height) || !isPow2(depth))))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kTextureNotPow2);
+ return false;
+ }
+
+ if (!ValidMipLevel(context, target, level))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidCompressedBaseLevel(GLsizei size, GLuint blockSize, GLint level)
+{
+ // Already checked in ValidMipLevel.
+ ASSERT(level < 32);
+ // This function is used only for 4x4 BC formats.
+ ASSERT(blockSize == 4);
+ // Use the constant value to avoid division.
+ return ((size << level) % 4) == 0;
+}
+
+bool ValidCompressedImageSize(const Context *context,
+ GLenum internalFormat,
+ GLint level,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth)
+{
+ if (width < 0 || height < 0)
+ {
+ return false;
+ }
+
+ const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalFormat);
+
+ if (!formatInfo.compressed && !formatInfo.paletted)
+ {
+ return false;
+ }
+
+ // A texture format can not be both block-compressed and paletted
+ ASSERT(!(formatInfo.compressed && formatInfo.paletted));
+
+ if (formatInfo.compressed)
+ {
+ // Only PVRTC1 requires dimensions to be powers of two
+ if (IsPVRTC1Format(internalFormat))
+ {
+ if (!isPow2(width) || !isPow2(height))
+ {
+ return false;
+ }
+
+ if (context->getLimitations().squarePvrtc1)
+ {
+ if (width != height)
+ {
+ return false;
+ }
+ }
+ }
+
+ if (CompressedTextureFormatRequiresExactSize(internalFormat))
+ {
+ // In WebGL compatibility mode and D3D, enforce that the base level implied
+ // by the compressed texture's mip level would conform to the block
+ // size.
+ if (context->isWebGL() ||
+ context->getLimitations().compressedBaseMipLevelMultipleOfFour)
+ {
+ // This check is performed only for BC formats.
+ ASSERT(formatInfo.compressedBlockDepth == 1);
+ if (!ValidCompressedBaseLevel(width, formatInfo.compressedBlockWidth, level) ||
+ !ValidCompressedBaseLevel(height, formatInfo.compressedBlockHeight, level))
+ {
+ return false;
+ }
+ }
+ // non-WebGL and non-D3D check is not necessary for the following formats
+ // From EXT_texture_compression_s3tc specification:
+ // If the width or height is not a multiple of four, there will be 4x4 blocks at the
+ // edge of the image that contain "extra" texels that are not part of the image. From
+ // EXT_texture_compression_bptc & EXT_texture_compression_rgtc specification: If an
+ // RGTC/BPTC image has a width or height that is not a multiple of four, the data
+ // corresponding to texels outside the image are irrelevant and undefined.
+ }
+ }
+
+ if (formatInfo.paletted)
+ {
+ // TODO(http://anglebug.com/7688): multi-level paletted images
+ if (level != 0)
+ {
+ return false;
+ }
+
+ if (!isPow2(width) || !isPow2(height))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidCompressedSubImageSize(const Context *context,
+ GLenum internalFormat,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ size_t textureWidth,
+ size_t textureHeight,
+ size_t textureDepth)
+{
+ const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalFormat);
+ if (!formatInfo.compressed)
+ {
+ return false;
+ }
+
+ if (xoffset < 0 || yoffset < 0 || zoffset < 0 || width < 0 || height < 0 || depth < 0)
+ {
+ return false;
+ }
+
+ // ANGLE does not support compressed 3D blocks (provided exclusively by ASTC 3D formats), so
+ // there is no need to check the depth here. Only width and height determine whether a 2D array
+ // element or a 2D slice of a sliced 3D texture fill the entire level.
+ bool fillsEntireMip = xoffset == 0 && yoffset == 0 &&
+ static_cast<size_t>(width) == textureWidth &&
+ static_cast<size_t>(height) == textureHeight;
+
+ if (CompressedFormatRequiresWholeImage(internalFormat))
+ {
+ return fillsEntireMip;
+ }
+
+ if (CompressedSubTextureFormatRequiresExactSize(internalFormat))
+ {
+ if (xoffset % formatInfo.compressedBlockWidth != 0 ||
+ yoffset % formatInfo.compressedBlockHeight != 0 ||
+ zoffset % formatInfo.compressedBlockDepth != 0)
+ {
+ return false;
+ }
+
+ // Allowed to either have data that is a multiple of block size or is smaller than the block
+ // size but fills the entire mip
+ bool sizeMultipleOfBlockSize = (width % formatInfo.compressedBlockWidth) == 0 &&
+ (height % formatInfo.compressedBlockHeight) == 0 &&
+ (depth % formatInfo.compressedBlockDepth) == 0;
+ if (!sizeMultipleOfBlockSize && !fillsEntireMip)
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidImageDataSize(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType texType,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ const void *pixels,
+ GLsizei imageSize)
+{
+ Buffer *pixelUnpackBuffer = context->getState().getTargetBuffer(BufferBinding::PixelUnpack);
+ 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.
+ const InternalFormat &formatInfo = GetInternalFormatInfo(format, type);
+ ASSERT(formatInfo.internalFormat != GL_NONE);
+ const Extents size(width, height, depth);
+ const auto &unpack = context->getState().getUnpackState();
+
+ bool targetIs3D = texType == TextureType::_3D || texType == TextureType::_2DArray;
+ GLuint endByte = 0;
+ if (!formatInfo.computePackUnpackEndByte(type, size, unpack, targetIs3D, &endByte))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kIntegerOverflow);
+ return false;
+ }
+
+ if (pixelUnpackBuffer)
+ {
+ CheckedNumeric<size_t> checkedEndByte(endByte);
+ 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->validationError(entryPoint, GL_INVALID_OPERATION, kIntegerOverflow);
+ return false;
+ }
+ if (pixelUnpackBuffer->hasWebGLXFBBindingConflict(context->isWebGL()))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kPixelUnpackBufferBoundForTransformFeedback);
+ return false;
+ }
+ }
+ else
+ {
+ ASSERT(imageSize >= 0);
+ if (pixels == nullptr && imageSize != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kImageSizeMustBeZero);
+ return false;
+ }
+
+ if (pixels != nullptr && endByte > static_cast<GLuint>(imageSize))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kImageSizeTooSmall);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidQueryType(const Context *context, QueryType queryType)
+{
+ switch (queryType)
+ {
+ case QueryType::AnySamples:
+ case QueryType::AnySamplesConservative:
+ return context->getClientMajorVersion() >= 3 ||
+ context->getExtensions().occlusionQueryBooleanEXT;
+ case QueryType::TransformFeedbackPrimitivesWritten:
+ return (context->getClientMajorVersion() >= 3);
+ case QueryType::TimeElapsed:
+ return context->getExtensions().disjointTimerQueryEXT;
+ case QueryType::CommandsCompleted:
+ return context->getExtensions().syncQueryCHROMIUM;
+ case QueryType::PrimitivesGenerated:
+ return context->getClientVersion() >= ES_3_2 ||
+ context->getExtensions().geometryShaderAny();
+ default:
+ return false;
+ }
+}
+
+bool ValidateWebGLVertexAttribPointer(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexAttribType type,
+ GLboolean normalized,
+ GLsizei stride,
+ const void *ptr,
+ bool pureInteger)
+{
+ ASSERT(context->isWebGL());
+ // WebGL 1.0 [Section 6.11] Vertex Attribute Data Stride
+ // The WebGL API supports vertex attribute data strides up to 255 bytes. A call to
+ // vertexAttribPointer will generate an INVALID_VALUE error if the value for the stride
+ // parameter exceeds 255.
+ constexpr GLsizei kMaxWebGLStride = 255;
+ if (stride > kMaxWebGLStride)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kStrideExceedsWebGLLimit);
+ return false;
+ }
+
+ // WebGL 1.0 [Section 6.4] Buffer Offset and Stride Requirements
+ // The offset arguments to drawElements and vertexAttribPointer, and the stride argument to
+ // vertexAttribPointer, must be a multiple of the size of the data type passed to the call,
+ // or an INVALID_OPERATION error is generated.
+ angle::FormatID internalType = GetVertexFormatID(type, normalized, 1, pureInteger);
+ size_t typeSize = GetVertexFormatSize(internalType);
+
+ ASSERT(isPow2(typeSize) && typeSize > 0);
+ size_t sizeMask = (typeSize - 1);
+ if ((reinterpret_cast<intptr_t>(ptr) & sizeMask) != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kOffsetMustBeMultipleOfType);
+ return false;
+ }
+
+ if ((stride & sizeMask) != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kStrideMustBeMultipleOfType);
+ return false;
+ }
+
+ return true;
+}
+
+Program *GetValidProgramNoResolve(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID id)
+{
+ // ES3 spec (section 2.11.1) -- "Commands that accept shader or program object names will
+ // generate the error INVALID_VALUE if the provided name is not the name of either a shader
+ // or program object and INVALID_OPERATION if the provided name identifies an object
+ // that is not the expected type."
+
+ Program *validProgram = context->getProgramNoResolveLink(id);
+
+ if (!validProgram)
+ {
+ if (context->getShader(id))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExpectedProgramName);
+ }
+ else
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidProgramName);
+ }
+ }
+
+ return validProgram;
+}
+
+Program *GetValidProgram(const Context *context, angle::EntryPoint entryPoint, ShaderProgramID id)
+{
+ Program *program = GetValidProgramNoResolve(context, entryPoint, id);
+ if (program)
+ {
+ program->resolveLink(context);
+ }
+ return program;
+}
+
+Shader *GetValidShader(const Context *context, angle::EntryPoint entryPoint, ShaderProgramID id)
+{
+ // See ValidProgram for spec details.
+
+ Shader *validShader = context->getShader(id);
+
+ if (!validShader)
+ {
+ if (context->getProgramNoResolveLink(id))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExpectedShaderName);
+ }
+ else
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidShaderName);
+ }
+ }
+
+ return validShader;
+}
+
+bool ValidateAttachmentTarget(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum attachment)
+{
+ if (attachment >= GL_COLOR_ATTACHMENT1_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
+ {
+ if (context->getClientMajorVersion() < 3 && !context->getExtensions().drawBuffersEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidAttachment);
+ return false;
+ }
+
+ // Color attachment 0 is validated below because it is always valid
+ const int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT);
+ if (colorAttachment >= context->getCaps().maxColorAttachments)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidAttachment);
+ return false;
+ }
+ }
+ else
+ {
+ switch (attachment)
+ {
+ case GL_COLOR_ATTACHMENT0:
+ case GL_DEPTH_ATTACHMENT:
+ case GL_STENCIL_ATTACHMENT:
+ break;
+
+ case GL_DEPTH_STENCIL_ATTACHMENT:
+ if (!context->isWebGL() && context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidAttachment);
+ return false;
+ }
+ break;
+
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidAttachment);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateRenderbufferStorageParametersBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height)
+{
+ switch (target)
+ {
+ case GL_RENDERBUFFER:
+ break;
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidRenderbufferTarget);
+ return false;
+ }
+
+ if (width < 0 || height < 0 || samples < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidRenderbufferWidthHeight);
+ return false;
+ }
+
+ // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
+ GLenum convertedInternalFormat = context->getConvertedRenderbufferFormat(internalformat);
+
+ const TextureCaps &formatCaps = context->getTextureCaps().get(convertedInternalFormat);
+ if (!formatCaps.renderbuffer)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidRenderbufferInternalFormat);
+ return false;
+ }
+
+ // ANGLE_framebuffer_multisample does not explicitly state that the internal format must be
+ // sized but it does state that the format must be in the ES2.0 spec table 4.5 which contains
+ // only sized internal formats.
+ const InternalFormat &formatInfo = GetSizedInternalFormatInfo(convertedInternalFormat);
+ if (formatInfo.internalFormat == GL_NONE)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidRenderbufferInternalFormat);
+ return false;
+ }
+
+ if (std::max(width, height) > context->getCaps().maxRenderbufferSize)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxRenderbufferSize);
+ return false;
+ }
+
+ RenderbufferID id = context->getState().getRenderbufferId();
+ if (id.value == 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidRenderbufferTarget);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateBlitFramebufferParameters(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint srcX0,
+ GLint srcY0,
+ GLint srcX1,
+ GLint srcY1,
+ GLint dstX0,
+ GLint dstY0,
+ GLint dstX1,
+ GLint dstY1,
+ GLbitfield mask,
+ GLenum filter)
+{
+ switch (filter)
+ {
+ case GL_NEAREST:
+ break;
+ case GL_LINEAR:
+ break;
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kBlitInvalidFilter);
+ return false;
+ }
+
+ if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kBlitInvalidMask);
+ return false;
+ }
+
+ // ES3.0 spec, section 4.3.2 states that linear filtering is only available for the
+ // color buffer, leaving only nearest being unfiltered from above
+ if ((mask & ~GL_COLOR_BUFFER_BIT) != 0 && filter != GL_NEAREST)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kBlitOnlyNearestForNonColor);
+ return false;
+ }
+
+ const auto &glState = context->getState();
+ Framebuffer *readFramebuffer = glState.getReadFramebuffer();
+ Framebuffer *drawFramebuffer = glState.getDrawFramebuffer();
+
+ if (!readFramebuffer || !drawFramebuffer)
+ {
+ context->validationError(entryPoint, GL_INVALID_FRAMEBUFFER_OPERATION,
+ kBlitFramebufferMissing);
+ return false;
+ }
+
+ if (!ValidateFramebufferComplete(context, entryPoint, readFramebuffer))
+ {
+ return false;
+ }
+
+ if (!ValidateFramebufferComplete(context, entryPoint, drawFramebuffer))
+ {
+ return false;
+ }
+
+ // EXT_YUV_target disallows blitting to or from a YUV framebuffer
+ if ((mask & GL_COLOR_BUFFER_BIT) != 0 &&
+ (readFramebuffer->hasYUVAttachment() || drawFramebuffer->hasYUVAttachment()))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kBlitYUVFramebuffer);
+ return false;
+ }
+
+ // The draw and read framebuffers can only match if:
+ // - They are the default framebuffer AND
+ // - The read/draw surfaces are different
+ if ((readFramebuffer->id() == drawFramebuffer->id()) &&
+ ((drawFramebuffer->id() != Framebuffer::kDefaultDrawFramebufferHandle) ||
+ (context->getCurrentDrawSurface() == context->getCurrentReadSurface())))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kBlitFeedbackLoop);
+ return false;
+ }
+
+ // Not allow blitting to MS buffers, therefore if renderToTextureSamples exist,
+ // consider it MS. checkReadBufferResourceSamples = false
+ if (!ValidateFramebufferNotMultisampled(context, entryPoint, drawFramebuffer, false))
+ {
+ return false;
+ }
+
+ // This validation is specified in the WebGL 2.0 spec and not in the GLES 3.0.5 spec, but we
+ // always run it in order to avoid triggering driver bugs.
+ if (DifferenceCanOverflow(srcX0, srcX1) || DifferenceCanOverflow(srcY0, srcY1) ||
+ DifferenceCanOverflow(dstX0, dstX1) || DifferenceCanOverflow(dstY0, dstY1))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kBlitDimensionsOutOfRange);
+ return false;
+ }
+
+ bool sameBounds = srcX0 == dstX0 && srcY0 == dstY0 && srcX1 == dstX1 && srcY1 == dstY1;
+
+ if (mask & GL_COLOR_BUFFER_BIT)
+ {
+ const FramebufferAttachment *readColorBuffer = readFramebuffer->getReadColorAttachment();
+ const Extensions &extensions = context->getExtensions();
+
+ if (readColorBuffer)
+ {
+ const Format &readFormat = readColorBuffer->getFormat();
+
+ for (size_t drawbufferIdx = 0;
+ drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
+ {
+ const FramebufferAttachment *attachment =
+ drawFramebuffer->getDrawBuffer(drawbufferIdx);
+ if (attachment)
+ {
+ 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
+ // 2) If the read buffer is an unsigned integer format, the draw buffer must be
+ // as well
+ // 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 = readFormat.info->componentType;
+ GLenum drawComponentType = drawFormat.info->componentType;
+ bool readFixedPoint = (readComponentType == GL_UNSIGNED_NORMALIZED ||
+ readComponentType == GL_SIGNED_NORMALIZED);
+ bool drawFixedPoint = (drawComponentType == GL_UNSIGNED_NORMALIZED ||
+ drawComponentType == GL_SIGNED_NORMALIZED);
+
+ if (extensions.colorBufferFloatEXT)
+ {
+ bool readFixedOrFloat = (readFixedPoint || readComponentType == GL_FLOAT);
+ bool drawFixedOrFloat = (drawFixedPoint || drawComponentType == GL_FLOAT);
+
+ if (readFixedOrFloat != drawFixedOrFloat)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kBlitTypeMismatchFixedOrFloat);
+ return false;
+ }
+ }
+ else if (readFixedPoint != drawFixedPoint)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kBlitTypeMismatchFixedPoint);
+ return false;
+ }
+
+ if (readComponentType == GL_UNSIGNED_INT &&
+ drawComponentType != GL_UNSIGNED_INT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kBlitTypeMismatchUnsignedInteger);
+ return false;
+ }
+
+ if (readComponentType == GL_INT && drawComponentType != GL_INT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kBlitTypeMismatchSignedInteger);
+ return false;
+ }
+
+ if (readColorBuffer->getResourceSamples() > 0 &&
+ (!Format::EquivalentForBlit(readFormat, drawFormat) || !sameBounds))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kBlitMultisampledFormatOrBoundsMismatch);
+ return false;
+ }
+
+ if (context->isWebGL() && *readColorBuffer == *attachment)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kBlitSameImageColor);
+ return false;
+ }
+ }
+ }
+
+ if (readFormat.info->isInt() && filter == GL_LINEAR)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kBlitIntegerWithLinearFilter);
+ return false;
+ }
+ }
+ // WebGL 2.0 BlitFramebuffer when blitting from a missing attachment
+ // In OpenGL ES it is undefined what happens when an operation tries to blit from a missing
+ // attachment and WebGL defines it to be an error. We do the check unconditionally as the
+ // situation is an application error that would lead to a crash in ANGLE.
+ else if (drawFramebuffer->hasEnabledDrawBuffer())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kBlitMissingColor);
+ return false;
+ }
+ }
+
+ GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
+ GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
+ for (size_t i = 0; i < 2; i++)
+ {
+ if (mask & masks[i])
+ {
+ const FramebufferAttachment *readBuffer =
+ readFramebuffer->getAttachment(context, attachments[i]);
+ const FramebufferAttachment *drawBuffer =
+ drawFramebuffer->getAttachment(context, attachments[i]);
+
+ if (readBuffer && drawBuffer)
+ {
+ if (!Format::EquivalentForBlit(readBuffer->getFormat(), drawBuffer->getFormat()))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kBlitDepthOrStencilFormatMismatch);
+ return false;
+ }
+
+ if (readBuffer->getResourceSamples() > 0 && !sameBounds)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kBlitMultisampledBoundsMismatch);
+ return false;
+ }
+
+ if (context->isWebGL() && *readBuffer == *drawBuffer)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kBlitSameImageDepthOrStencil);
+ return false;
+ }
+ }
+ // WebGL 2.0 BlitFramebuffer when blitting from a missing attachment
+ else if (drawBuffer)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kBlitMissingDepthOrStencil);
+ return false;
+ }
+ }
+ }
+
+ // OVR_multiview2:
+ // Calling BlitFramebuffer will result in an INVALID_FRAMEBUFFER_OPERATION error if the
+ // current draw framebuffer isMultiview() or the number of
+ // views in the current read framebuffer is more than one.
+ if (readFramebuffer->readDisallowedByMultiview())
+ {
+ context->validationError(entryPoint, GL_INVALID_FRAMEBUFFER_OPERATION, kBlitFromMultiview);
+ return false;
+ }
+ if (drawFramebuffer->isMultiview())
+ {
+ context->validationError(entryPoint, GL_INVALID_FRAMEBUFFER_OPERATION, kBlitToMultiview);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateBindFramebufferBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ FramebufferID framebuffer)
+{
+ if (!ValidFramebufferTarget(context, target))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFramebufferTarget);
+ return false;
+ }
+
+ if (!context->getState().isBindGeneratesResourceEnabled() &&
+ !context->isFramebufferGenerated(framebuffer))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kObjectNotGenerated);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateBindRenderbufferBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ RenderbufferID renderbuffer)
+{
+ if (target != GL_RENDERBUFFER)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidRenderbufferTarget);
+ return false;
+ }
+
+ if (!context->getState().isBindGeneratesResourceEnabled() &&
+ !context->isRenderbufferGenerated(renderbuffer))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kObjectNotGenerated);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateFramebufferParameteriBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum pname,
+ GLint param)
+{
+ if (!ValidFramebufferTarget(context, target))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFramebufferTarget);
+ return false;
+ }
+
+ switch (pname)
+ {
+ case GL_FRAMEBUFFER_DEFAULT_WIDTH:
+ {
+ GLint maxWidth = context->getCaps().maxFramebufferWidth;
+ if (param < 0 || param > maxWidth)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsFramebufferWidth);
+ return false;
+ }
+ break;
+ }
+ case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
+ {
+ GLint maxHeight = context->getCaps().maxFramebufferHeight;
+ if (param < 0 || param > maxHeight)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsFramebufferHeight);
+ return false;
+ }
+ break;
+ }
+ case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
+ {
+ GLint maxSamples = context->getCaps().maxFramebufferSamples;
+ if (param < 0 || param > maxSamples)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsFramebufferSamples);
+ return false;
+ }
+ break;
+ }
+ case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
+ {
+ break;
+ }
+ case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
+ {
+ if (!context->getExtensions().geometryShaderAny() &&
+ context->getClientVersion() < ES_3_2)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM,
+ kGeometryShaderExtensionNotEnabled);
+ return false;
+ }
+ GLint maxLayers = context->getCaps().maxFramebufferLayers;
+ if (param < 0 || param > maxLayers)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidFramebufferLayer);
+ return false;
+ }
+ break;
+ }
+ case GL_FRAMEBUFFER_FLIP_Y_MESA:
+ {
+ if (!context->getExtensions().framebufferFlipYMESA)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname);
+ return false;
+ }
+ break;
+ }
+ default:
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname);
+ return false;
+ }
+ }
+
+ const Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
+ ASSERT(framebuffer);
+ if (framebuffer->isDefault())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kDefaultFramebuffer);
+ return false;
+ }
+ return true;
+}
+
+bool ValidateFramebufferRenderbufferBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ GLenum renderbuffertarget,
+ RenderbufferID renderbuffer)
+{
+ if (!ValidFramebufferTarget(context, target))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFramebufferTarget);
+ return false;
+ }
+
+ if (renderbuffertarget != GL_RENDERBUFFER)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidRenderbufferTarget);
+ return false;
+ }
+
+ Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
+
+ ASSERT(framebuffer);
+ if (framebuffer->isDefault())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kDefaultFramebufferTarget);
+ return false;
+ }
+
+ if (!ValidateAttachmentTarget(context, entryPoint, attachment))
+ {
+ return false;
+ }
+
+ // [OpenGL ES 2.0.25] Section 4.4.3 page 112
+ // [OpenGL ES 3.0.2] Section 4.4.2 page 201
+ // 'renderbuffer' must be either zero or the name of an existing renderbuffer object of
+ // type 'renderbuffertarget', otherwise an INVALID_OPERATION error is generated.
+ if (renderbuffer.value != 0)
+ {
+ if (!context->getRenderbuffer(renderbuffer))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidRenderbufferTarget);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateFramebufferTextureBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ TextureID texture,
+ GLint level)
+{
+ if (!ValidFramebufferTarget(context, target))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFramebufferTarget);
+ return false;
+ }
+
+ if (!ValidateAttachmentTarget(context, entryPoint, attachment))
+ {
+ return false;
+ }
+
+ if (texture.value != 0)
+ {
+ Texture *tex = context->getTexture(texture);
+
+ if (tex == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kMissingTexture);
+ return false;
+ }
+
+ if (level < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel);
+ return false;
+ }
+
+ // GLES spec 3.1, Section 9.2.8 "Attaching Texture Images to a Framebuffer"
+ // An INVALID_VALUE error is generated if texture is not zero and level is
+ // not a supported texture level for textarget
+
+ // Common criteria for not supported texture levels(other criteria are handled case by case
+ // in non base functions): If texture refers to an immutable-format texture, level must be
+ // greater than or equal to zero and smaller than the value of TEXTURE_IMMUTABLE_LEVELS for
+ // texture.
+ if (tex->getImmutableFormat() && context->getClientVersion() >= ES_3_1)
+ {
+ if (level >= static_cast<GLint>(tex->getImmutableLevels()))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel);
+ return false;
+ }
+ }
+
+ // GLES spec 3.2, Section 9.2.8 "Attaching Texture Images to a Framebuffer"
+ // An INVALID_OPERATION error is generated if <texture> is the name of a buffer texture.
+ if ((context->getClientVersion() >= ES_3_2 ||
+ context->getExtensions().textureBufferAny()) &&
+ tex->getType() == TextureType::Buffer)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidTextureTarget);
+ return false;
+ }
+
+ if (tex->getState().hasProtectedContent() != context->getState().hasProtectedContent())
+ {
+ context->validationError(
+ entryPoint, GL_INVALID_OPERATION,
+ "Mismatch between Texture and Context Protected Content state");
+ return false;
+ }
+ }
+
+ const Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
+ ASSERT(framebuffer);
+
+ if (framebuffer->isDefault())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kDefaultFramebufferTarget);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGenerateMipmapBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target)
+{
+ if (!ValidTextureTarget(context, target))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget);
+ return false;
+ }
+
+ Texture *texture = context->getTextureByType(target);
+
+ if (texture == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kTextureNotBound);
+ return false;
+ }
+
+ const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
+
+ // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
+ // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
+ if (effectiveBaseLevel >= IMPLEMENTATION_MAX_TEXTURE_LEVELS)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kBaseLevelOutOfRange);
+ return false;
+ }
+
+ TextureTarget baseTarget = (target == TextureType::CubeMap)
+ ? TextureTarget::CubeMapPositiveX
+ : NonCubeTextureTypeToTarget(target);
+ const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
+ if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
+ format.stencilBits > 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
+ return false;
+ }
+
+ // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
+ bool formatUnsized = !format.sized;
+ bool formatColorRenderableAndFilterable =
+ format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
+ format.textureAttachmentSupport(context->getClientVersion(), context->getExtensions());
+ if (!formatUnsized && !formatColorRenderableAndFilterable)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
+ return false;
+ }
+
+ // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
+ // generation
+ if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
+ return false;
+ }
+
+ // According to the OpenGL extension spec EXT_sRGB.txt, EXT_SRGB is based on ES 2.0 and
+ // generateMipmap is not allowed if texture format is SRGB_EXT or SRGB_ALPHA_EXT.
+ if (context->getClientVersion() < Version(3, 0) && format.colorEncoding == GL_SRGB)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
+ return false;
+ }
+
+ // Non-power of 2 ES2 check
+ if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNpotOES &&
+ (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
+ !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
+ {
+ ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
+ target == TextureType::CubeMap);
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kTextureNotPow2);
+ return false;
+ }
+
+ // Cube completeness check
+ if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kCubemapIncomplete);
+ return false;
+ }
+
+ if (context->isWebGL() && (texture->getWidth(baseTarget, effectiveBaseLevel) == 0 ||
+ texture->getHeight(baseTarget, effectiveBaseLevel) == 0))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kGenerateMipmapZeroSize);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateReadPixelsRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLsizei *columns,
+ const GLsizei *rows,
+ const void *pixels)
+{
+ if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
+ {
+ return false;
+ }
+
+ GLsizei writeLength = 0;
+ GLsizei writeColumns = 0;
+ GLsizei writeRows = 0;
+
+ if (!ValidateReadPixelsBase(context, entryPoint, x, y, width, height, format, type, bufSize,
+ &writeLength, &writeColumns, &writeRows, pixels))
+ {
+ return false;
+ }
+
+ if (!ValidateRobustBufferSize(context, entryPoint, bufSize, writeLength))
+ {
+ return false;
+ }
+
+ SetRobustLengthParam(length, writeLength);
+ SetRobustLengthParam(columns, writeColumns);
+ SetRobustLengthParam(rows, writeRows);
+
+ return true;
+}
+
+bool ValidateReadnPixelsEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *pixels)
+{
+ if (bufSize < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBufferSize);
+ return false;
+ }
+
+ return ValidateReadPixelsBase(context, entryPoint, x, y, width, height, format, type, bufSize,
+ nullptr, nullptr, nullptr, pixels);
+}
+
+bool ValidateReadnPixelsRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLsizei *columns,
+ const GLsizei *rows,
+ const void *data)
+{
+ GLsizei writeLength = 0;
+ GLsizei writeColumns = 0;
+ GLsizei writeRows = 0;
+
+ if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
+ {
+ return false;
+ }
+
+ if (!ValidateReadPixelsBase(context, entryPoint, x, y, width, height, format, type, bufSize,
+ &writeLength, &writeColumns, &writeRows, data))
+ {
+ return false;
+ }
+
+ if (!ValidateRobustBufferSize(context, entryPoint, bufSize, writeLength))
+ {
+ return false;
+ }
+
+ SetRobustLengthParam(length, writeLength);
+ SetRobustLengthParam(columns, writeColumns);
+ SetRobustLengthParam(rows, writeRows);
+
+ return true;
+}
+
+bool ValidateGenQueriesEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const QueryID *ids)
+{
+ if (!context->getExtensions().occlusionQueryBooleanEXT &&
+ !context->getExtensions().disjointTimerQueryEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kQueryExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateGenOrDelete(context, entryPoint, n);
+}
+
+bool ValidateDeleteQueriesEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const QueryID *ids)
+{
+ if (!context->getExtensions().occlusionQueryBooleanEXT &&
+ !context->getExtensions().disjointTimerQueryEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kQueryExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateGenOrDelete(context, entryPoint, n);
+}
+
+bool ValidateIsQueryEXT(const Context *context, angle::EntryPoint entryPoint, QueryID id)
+{
+ if (!context->getExtensions().occlusionQueryBooleanEXT &&
+ !context->getExtensions().disjointTimerQueryEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kQueryExtensionNotEnabled);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateBeginQueryBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryType target,
+ QueryID id)
+{
+ if (!ValidQueryType(context, target))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidQueryType);
+ return false;
+ }
+
+ if (id.value == 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidQueryId);
+ return false;
+ }
+
+ // From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id>
+ // of zero, if the active query object name for <target> is non-zero (for the
+ // targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if
+ // the active query for either target is non-zero), if <id> is the name of an
+ // existing query object whose type does not match <target>, or if <id> is the
+ // active query object name for any query type, the error INVALID_OPERATION is
+ // generated.
+
+ // Ensure no other queries are active
+ // NOTE: If other queries than occlusion are supported, we will need to check
+ // separately that:
+ // a) The query ID passed is not the current active query for any target/type
+ // b) There are no active queries for the requested target (and in the case
+ // of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
+ // no query may be active for either if glBeginQuery targets either.
+
+ if (context->getState().isQueryActive(target))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kOtherQueryActive);
+ return false;
+ }
+
+ // check that name was obtained with glGenQueries
+ if (!context->isQueryGenerated(id))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidQueryId);
+ return false;
+ }
+
+ // Check for type mismatch. If query is not yet started we're good to go.
+ Query *queryObject = context->getQuery(id);
+ if (queryObject && queryObject->getType() != target)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kQueryTargetMismatch);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateBeginQueryEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryType target,
+ QueryID id)
+{
+ if (!context->getExtensions().occlusionQueryBooleanEXT &&
+ !context->getExtensions().disjointTimerQueryEXT &&
+ !context->getExtensions().syncQueryCHROMIUM)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kQueryExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateBeginQueryBase(context, entryPoint, target, id);
+}
+
+bool ValidateEndQueryBase(const Context *context, angle::EntryPoint entryPoint, QueryType target)
+{
+ if (!ValidQueryType(context, target))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidQueryType);
+ return false;
+ }
+
+ const Query *queryObject = context->getState().getActiveQuery(target);
+
+ if (queryObject == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kQueryInactive);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateEndQueryEXT(const Context *context, angle::EntryPoint entryPoint, QueryType target)
+{
+ if (!context->getExtensions().occlusionQueryBooleanEXT &&
+ !context->getExtensions().disjointTimerQueryEXT &&
+ !context->getExtensions().syncQueryCHROMIUM)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kQueryExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateEndQueryBase(context, entryPoint, target);
+}
+
+bool ValidateQueryCounterEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID id,
+ QueryType target)
+{
+ if (!context->getExtensions().disjointTimerQueryEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ if (target != QueryType::Timestamp)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidQueryTarget);
+ return false;
+ }
+
+ if (!context->isQueryGenerated(id))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidQueryId);
+ return false;
+ }
+
+ // If query object is not started, that's fine.
+ Query *queryObject = context->getQuery(id);
+ if (queryObject && context->getState().isQueryActive(queryObject))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kQueryActive);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetQueryivBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryType target,
+ GLenum pname,
+ GLsizei *numParams)
+{
+ if (numParams)
+ {
+ *numParams = 0;
+ }
+
+ if (!ValidQueryType(context, target) && target != QueryType::Timestamp)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidQueryType);
+ return false;
+ }
+
+ switch (pname)
+ {
+ case GL_CURRENT_QUERY_EXT:
+ if (target == QueryType::Timestamp)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidQueryTarget);
+ return false;
+ }
+ break;
+ case GL_QUERY_COUNTER_BITS_EXT:
+ if (!context->getExtensions().disjointTimerQueryEXT ||
+ (target != QueryType::Timestamp && target != QueryType::TimeElapsed))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname);
+ return false;
+ }
+ break;
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname);
+ return false;
+ }
+
+ if (numParams)
+ {
+ // All queries return only one value
+ *numParams = 1;
+ }
+
+ return true;
+}
+
+bool ValidateGetQueryivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryType target,
+ GLenum pname,
+ const GLint *params)
+{
+ if (!context->getExtensions().occlusionQueryBooleanEXT &&
+ !context->getExtensions().disjointTimerQueryEXT &&
+ !context->getExtensions().syncQueryCHROMIUM)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateGetQueryivBase(context, entryPoint, target, pname, nullptr);
+}
+
+bool ValidateGetQueryivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryType target,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params)
+{
+ if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
+ {
+ return false;
+ }
+
+ GLsizei numParams = 0;
+
+ if (!ValidateGetQueryivBase(context, entryPoint, target, pname, &numParams))
+ {
+ return false;
+ }
+
+ if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
+ {
+ return false;
+ }
+
+ SetRobustLengthParam(length, numParams);
+
+ return true;
+}
+
+bool ValidateGetQueryObjectValueBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID id,
+ GLenum pname,
+ GLsizei *numParams)
+{
+ if (numParams)
+ {
+ *numParams = 1;
+ }
+
+ if (context->isContextLost())
+ {
+ context->validationError(entryPoint, GL_CONTEXT_LOST, kContextLost);
+
+ if (pname == GL_QUERY_RESULT_AVAILABLE_EXT)
+ {
+ // Generate an error but still return true, the context still needs to return a
+ // value in this case.
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ Query *queryObject = context->getQuery(id);
+
+ if (!queryObject)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidQueryId);
+ return false;
+ }
+
+ if (context->getState().isQueryActive(queryObject))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kQueryActive);
+ return false;
+ }
+
+ switch (pname)
+ {
+ case GL_QUERY_RESULT_EXT:
+ case GL_QUERY_RESULT_AVAILABLE_EXT:
+ break;
+
+ default:
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetQueryObjectivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID id,
+ GLenum pname,
+ const GLint *params)
+{
+ if (!context->getExtensions().disjointTimerQueryEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+ return ValidateGetQueryObjectValueBase(context, entryPoint, id, pname, nullptr);
+}
+
+bool ValidateGetQueryObjectivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID id,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params)
+{
+ if (!context->getExtensions().disjointTimerQueryEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
+ {
+ return false;
+ }
+
+ GLsizei numParams = 0;
+
+ if (!ValidateGetQueryObjectValueBase(context, entryPoint, id, pname, &numParams))
+ {
+ return false;
+ }
+
+ if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
+ {
+ return false;
+ }
+
+ SetRobustLengthParam(length, numParams);
+
+ return true;
+}
+
+bool ValidateGetQueryObjectuivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID id,
+ GLenum pname,
+ const GLuint *params)
+{
+ if (!context->getExtensions().disjointTimerQueryEXT &&
+ !context->getExtensions().occlusionQueryBooleanEXT &&
+ !context->getExtensions().syncQueryCHROMIUM)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+ return ValidateGetQueryObjectValueBase(context, entryPoint, id, pname, nullptr);
+}
+
+bool ValidateGetQueryObjectuivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID id,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLuint *params)
+{
+ if (!context->getExtensions().disjointTimerQueryEXT &&
+ !context->getExtensions().occlusionQueryBooleanEXT &&
+ !context->getExtensions().syncQueryCHROMIUM)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
+ {
+ return false;
+ }
+
+ GLsizei numParams = 0;
+
+ if (!ValidateGetQueryObjectValueBase(context, entryPoint, id, pname, &numParams))
+ {
+ return false;
+ }
+
+ if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
+ {
+ return false;
+ }
+
+ SetRobustLengthParam(length, numParams);
+
+ return true;
+}
+
+bool ValidateGetQueryObjecti64vEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID id,
+ GLenum pname,
+ GLint64 *params)
+{
+ if (!context->getExtensions().disjointTimerQueryEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+ return ValidateGetQueryObjectValueBase(context, entryPoint, id, pname, nullptr);
+}
+
+bool ValidateGetQueryObjecti64vRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID id,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ GLint64 *params)
+{
+ if (!context->getExtensions().disjointTimerQueryEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
+ {
+ return false;
+ }
+
+ GLsizei numParams = 0;
+
+ if (!ValidateGetQueryObjectValueBase(context, entryPoint, id, pname, &numParams))
+ {
+ return false;
+ }
+
+ if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
+ {
+ return false;
+ }
+
+ SetRobustLengthParam(length, numParams);
+
+ return true;
+}
+
+bool ValidateGetQueryObjectui64vEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID id,
+ GLenum pname,
+ GLuint64 *params)
+{
+ if (!context->getExtensions().disjointTimerQueryEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+ return ValidateGetQueryObjectValueBase(context, entryPoint, id, pname, nullptr);
+}
+
+bool ValidateGetQueryObjectui64vRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID id,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ GLuint64 *params)
+{
+ if (!context->getExtensions().disjointTimerQueryEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
+ {
+ return false;
+ }
+
+ GLsizei numParams = 0;
+
+ if (!ValidateGetQueryObjectValueBase(context, entryPoint, id, pname, &numParams))
+ {
+ return false;
+ }
+
+ if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
+ {
+ return false;
+ }
+
+ SetRobustLengthParam(length, numParams);
+
+ return true;
+}
+
+bool ValidateUniformCommonBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ const Program *program,
+ UniformLocation location,
+ GLsizei count,
+ const LinkedUniform **uniformOut)
+{
+ // TODO(Jiajia): Add image uniform check in future.
+ if (count < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeCount);
+ return false;
+ }
+
+ if (!program)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidProgramName);
+ return false;
+ }
+
+ if (!program->isLinked())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotLinked);
+ return false;
+ }
+
+ if (location.value == -1)
+ {
+ // Silently ignore the uniform command
+ return false;
+ }
+
+ const auto &uniformLocations = program->getUniformLocations();
+ size_t castedLocation = static_cast<size_t>(location.value);
+ if (castedLocation >= uniformLocations.size())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidUniformLocation);
+ return false;
+ }
+
+ const auto &uniformLocation = uniformLocations[castedLocation];
+ if (uniformLocation.ignored)
+ {
+ // Silently ignore the uniform command
+ return false;
+ }
+
+ if (!uniformLocation.used())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidUniformLocation);
+ return false;
+ }
+
+ const auto &uniform = program->getUniformByIndex(uniformLocation.index);
+
+ // attempting to write an array to a non-array uniform is an INVALID_OPERATION
+ if (count > 1 && !uniform.isArray())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidUniformCount);
+ return false;
+ }
+
+ *uniformOut = &uniform;
+ return true;
+}
+
+bool ValidateUniform1ivValue(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum uniformType,
+ GLsizei count,
+ const GLint *value)
+{
+ // Value type is GL_INT, because we only get here from glUniform1i{v}.
+ // It is compatible with INT or BOOL.
+ // Do these cheap tests first, for a little extra speed.
+ if (GL_INT == uniformType || GL_BOOL == uniformType)
+ {
+ return true;
+ }
+
+ if (IsSamplerType(uniformType))
+ {
+ // Check that the values are in range.
+ const GLint max = context->getCaps().maxCombinedTextureImageUnits;
+ for (GLsizei i = 0; i < count; ++i)
+ {
+ if (value[i] < 0 || value[i] >= max)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kSamplerUniformValueOutOfRange);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kUniformTypeMismatch);
+ return false;
+}
+
+bool ValidateUniformMatrixValue(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum valueType,
+ GLenum uniformType)
+{
+ // Check that the value type is compatible with uniform type.
+ if (valueType == uniformType)
+ {
+ return true;
+ }
+
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kUniformTypeMismatch);
+ return false;
+}
+
+bool ValidateUniform(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum valueType,
+ UniformLocation location,
+ GLsizei count)
+{
+ const LinkedUniform *uniform = nullptr;
+ Program *programObject = context->getActiveLinkedProgram();
+ return ValidateUniformCommonBase(context, entryPoint, programObject, location, count,
+ &uniform) &&
+ ValidateUniformValue(context, entryPoint, valueType, uniform->type);
+}
+
+bool ValidateUniform1iv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLsizei count,
+ const GLint *value)
+{
+ const LinkedUniform *uniform = nullptr;
+ Program *programObject = context->getActiveLinkedProgram();
+ return ValidateUniformCommonBase(context, entryPoint, programObject, location, count,
+ &uniform) &&
+ ValidateUniform1ivValue(context, entryPoint, uniform->type, count, value);
+}
+
+bool ValidateUniformMatrix(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum valueType,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose)
+{
+ if (ConvertToBool(transpose) && context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kES3Required);
+ return false;
+ }
+
+ const LinkedUniform *uniform = nullptr;
+ Program *programObject = context->getActiveLinkedProgram();
+ return ValidateUniformCommonBase(context, entryPoint, programObject, location, count,
+ &uniform) &&
+ ValidateUniformMatrixValue(context, entryPoint, valueType, uniform->type);
+}
+
+bool ValidateStateQuery(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLenum *nativeType,
+ unsigned int *numParams)
+{
+ if (!context->getQueryParameterInfo(pname, nativeType, numParams))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname);
+ return false;
+ }
+
+ const Caps &caps = context->getCaps();
+
+ if (pname >= GL_DRAW_BUFFER0 && pname <= GL_DRAW_BUFFER15)
+ {
+ int colorAttachment = (pname - GL_DRAW_BUFFER0);
+
+ if (colorAttachment >= caps.maxDrawBuffers)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kIndexExceedsMaxDrawBuffer);
+ return false;
+ }
+ }
+
+ switch (pname)
+ {
+ case GL_TEXTURE_BINDING_2D:
+ case GL_TEXTURE_BINDING_CUBE_MAP:
+ case GL_TEXTURE_BINDING_3D:
+ case GL_TEXTURE_BINDING_2D_ARRAY:
+ case GL_TEXTURE_BINDING_2D_MULTISAMPLE:
+ break;
+ case GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY:
+ if (!context->getExtensions().textureStorageMultisample2dArrayOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM,
+ kMultisampleArrayExtensionRequired);
+ return false;
+ }
+ break;
+ case GL_TEXTURE_BINDING_RECTANGLE_ANGLE:
+ if (!context->getExtensions().textureRectangleANGLE)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname);
+ return false;
+ }
+ break;
+ case GL_TEXTURE_BINDING_EXTERNAL_OES:
+ if (!context->getExtensions().EGLStreamConsumerExternalNV &&
+ !context->getExtensions().EGLImageExternalOES)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname);
+ return false;
+ }
+ break;
+ case GL_TEXTURE_BUFFER_BINDING:
+ case GL_TEXTURE_BINDING_BUFFER:
+ case GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
+ case GL_MAX_TEXTURE_BUFFER_SIZE:
+ if (context->getClientVersion() < Version(3, 2) &&
+ !context->getExtensions().textureBufferAny())
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM,
+ kTextureBufferExtensionNotAvailable);
+ return false;
+ }
+ break;
+
+ case GL_IMPLEMENTATION_COLOR_READ_TYPE:
+ case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
+ {
+ Framebuffer *readFramebuffer = context->getState().getReadFramebuffer();
+ ASSERT(readFramebuffer);
+
+ if (!ValidateFramebufferComplete<GL_INVALID_OPERATION>(context, entryPoint,
+ readFramebuffer))
+ {
+ return false;
+ }
+
+ if (readFramebuffer->getReadBufferState() == GL_NONE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kReadBufferNone);
+ return false;
+ }
+
+ const FramebufferAttachment *attachment = readFramebuffer->getReadColorAttachment();
+ if (!attachment)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kReadBufferNotAttached);
+ return false;
+ }
+ }
+ break;
+
+ case GL_PRIMITIVE_BOUNDING_BOX:
+ if (!context->getExtensions().primitiveBoundingBoxAny())
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kExtensionNotEnabled);
+ return false;
+ }
+ break;
+
+ case GL_SHADING_RATE_QCOM:
+ if (!context->getExtensions().shadingRateQCOM)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kExtensionNotEnabled);
+ return false;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ // pname is valid, but there are no parameters to return
+ if (*numParams == 0)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetBooleanvRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLboolean *params)
+{
+ GLenum nativeType;
+ unsigned int numParams = 0;
+
+ if (!ValidateRobustStateQuery(context, entryPoint, pname, bufSize, &nativeType, &numParams))
+ {
+ return false;
+ }
+
+ SetRobustLengthParam(length, numParams);
+
+ return true;
+}
+
+bool ValidateGetFloatvRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLfloat *params)
+{
+ GLenum nativeType;
+ unsigned int numParams = 0;
+
+ if (!ValidateRobustStateQuery(context, entryPoint, pname, bufSize, &nativeType, &numParams))
+ {
+ return false;
+ }
+
+ SetRobustLengthParam(length, numParams);
+
+ return true;
+}
+
+bool ValidateGetIntegervRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *data)
+{
+ GLenum nativeType;
+ unsigned int numParams = 0;
+
+ if (!ValidateRobustStateQuery(context, entryPoint, pname, bufSize, &nativeType, &numParams))
+ {
+ return false;
+ }
+
+ SetRobustLengthParam(length, numParams);
+
+ return true;
+}
+
+bool ValidateGetInteger64vRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ GLint64 *data)
+{
+ GLenum nativeType;
+ unsigned int numParams = 0;
+
+ if (!ValidateRobustStateQuery(context, entryPoint, pname, bufSize, &nativeType, &numParams))
+ {
+ return false;
+ }
+
+ if (nativeType == GL_INT_64_ANGLEX)
+ {
+ CastStateValues(context, nativeType, pname, numParams, data);
+ return false;
+ }
+
+ SetRobustLengthParam(length, numParams);
+ return true;
+}
+
+bool ValidateRobustStateQuery(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLsizei bufSize,
+ GLenum *nativeType,
+ unsigned int *numParams)
+{
+ if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
+ {
+ return false;
+ }
+
+ if (!ValidateStateQuery(context, entryPoint, pname, nativeType, numParams))
+ {
+ return false;
+ }
+
+ if (!ValidateRobustBufferSize(context, entryPoint, bufSize, *numParams))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateCopyImageSubDataTarget(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint name,
+ GLenum target)
+{
+ // From EXT_copy_image: INVALID_ENUM is generated if either <srcTarget> or <dstTarget> is not
+ // RENDERBUFFER or a valid non - proxy texture target, is TEXTURE_BUFFER, or is one of the
+ // cubemap face selectors described in table 3.17, or if the target does not match the type of
+ // the object. INVALID_VALUE is generated if either <srcName> or <dstName> does not correspond
+ // to a valid renderbuffer or texture object according to the corresponding target parameter.
+ switch (target)
+ {
+ case GL_RENDERBUFFER:
+ {
+ RenderbufferID renderbuffer = PackParam<RenderbufferID>(name);
+ if (!context->isRenderbuffer(renderbuffer))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidRenderbufferName);
+ return false;
+ }
+ break;
+ }
+ case GL_TEXTURE_2D:
+ case GL_TEXTURE_3D:
+ case GL_TEXTURE_2D_ARRAY:
+ case GL_TEXTURE_CUBE_MAP:
+ case GL_TEXTURE_CUBE_MAP_ARRAY_EXT:
+ {
+ TextureID texture = PackParam<TextureID>(name);
+ if (!context->isTexture(texture))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidTextureName);
+ return false;
+ }
+
+ Texture *textureObject = context->getTexture(texture);
+ if (textureObject && textureObject->getType() != PackParam<TextureType>(target))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, err::kTextureTypeMismatch);
+ return false;
+ }
+ break;
+ }
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTarget);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateCopyImageSubDataLevel(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLint level)
+{
+ switch (target)
+ {
+ case GL_RENDERBUFFER:
+ {
+ if (level != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel);
+ return false;
+ }
+ break;
+ }
+ case GL_TEXTURE_2D:
+ case GL_TEXTURE_3D:
+ case GL_TEXTURE_2D_ARRAY:
+ case GL_TEXTURE_CUBE_MAP:
+ case GL_TEXTURE_CUBE_MAP_ARRAY_EXT:
+ {
+ if (!ValidMipLevel(context, PackParam<TextureType>(target), level))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel);
+ return false;
+ }
+ break;
+ }
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTarget);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateCopyImageSubDataTargetRegion(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint name,
+ GLenum target,
+ GLint level,
+ GLint offsetX,
+ GLint offsetY,
+ GLint offsetZ,
+ GLsizei width,
+ GLsizei height,
+ GLsizei *samples)
+{
+ // INVALID_VALUE is generated if the dimensions of the either subregion exceeds the boundaries
+ // of the corresponding image object.
+ if (offsetX < 0 || offsetY < 0 || offsetZ < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeOffset);
+ return false;
+ }
+
+ if (target == GL_RENDERBUFFER)
+ {
+ // INVALID_VALUE is generated if the dimensions of the either subregion exceeds the
+ // boundaries of the corresponding image object
+ Renderbuffer *buffer = context->getRenderbuffer(PackParam<RenderbufferID>(name));
+ if ((buffer->getWidth() - offsetX < width) || (buffer->getHeight() - offsetY < height))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kSourceTextureTooSmall);
+ return false;
+ }
+ }
+ else
+ {
+ Texture *texture = context->getTexture(PackParam<TextureID>(name));
+
+ // INVALID_OPERATION is generated if either object is a texture and the texture is not
+ // complete
+ // This will handle the texture completeness check. Note that this ignores format-based
+ // compleness rules.
+ if (!texture->isSamplerCompleteForCopyImage(context, nullptr))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kNotTextureComplete);
+ return false;
+ }
+
+ GLenum textureTargetToUse = target;
+ if (target == GL_TEXTURE_CUBE_MAP)
+ {
+ // Use GL_TEXTURE_CUBE_MAP_POSITIVE_X to properly gather the textureWidth/textureHeight
+ textureTargetToUse = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
+ }
+
+ const GLsizei textureWidth = static_cast<GLsizei>(
+ texture->getWidth(PackParam<TextureTarget>(textureTargetToUse), level));
+ const GLsizei textureHeight = static_cast<GLsizei>(
+ texture->getHeight(PackParam<TextureTarget>(textureTargetToUse), level));
+
+ // INVALID_VALUE is generated if the dimensions of the either subregion exceeds the
+ // boundaries of the corresponding image object
+ if ((textureWidth - offsetX < width) || (textureHeight - offsetY < height))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kSourceTextureTooSmall);
+ return false;
+ }
+
+ *samples = texture->getSamples(PackParam<TextureTarget>(textureTargetToUse), level);
+ *samples = (*samples == 0) ? 1 : *samples;
+ }
+
+ return true;
+}
+
+bool ValidateCompressedRegion(const Context *context,
+ angle::EntryPoint entryPoint,
+ const InternalFormat &formatInfo,
+ GLsizei width,
+ GLsizei height)
+{
+ ASSERT(formatInfo.compressed);
+
+ // INVALID_VALUE is generated if the image format is compressed and the dimensions of the
+ // subregion fail to meet the alignment constraints of the format.
+ if ((width % formatInfo.compressedBlockWidth != 0) ||
+ (height % formatInfo.compressedBlockHeight != 0))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidCompressedRegionSize);
+ return false;
+ }
+
+ return true;
+}
+
+const InternalFormat &GetTargetFormatInfo(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint name,
+ GLenum target,
+ GLint level)
+{
+ static const InternalFormat defaultInternalFormat;
+
+ switch (target)
+ {
+ case GL_RENDERBUFFER:
+ {
+ Renderbuffer *buffer = context->getRenderbuffer(PackParam<RenderbufferID>(name));
+ return *buffer->getFormat().info;
+ }
+ case GL_TEXTURE_2D:
+ case GL_TEXTURE_3D:
+ case GL_TEXTURE_2D_ARRAY:
+ case GL_TEXTURE_CUBE_MAP:
+ case GL_TEXTURE_CUBE_MAP_ARRAY_EXT:
+ {
+ Texture *texture = context->getTexture(PackParam<TextureID>(name));
+ GLenum textureTargetToUse = target;
+
+ if (target == GL_TEXTURE_CUBE_MAP)
+ {
+ // Use GL_TEXTURE_CUBE_MAP_POSITIVE_X to properly gather the
+ // textureWidth/textureHeight
+ textureTargetToUse = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
+ }
+ return *texture->getFormat(PackParam<TextureTarget>(textureTargetToUse), level).info;
+ }
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTarget);
+ return defaultInternalFormat;
+ }
+}
+
+bool ValidateCopyMixedFormatCompatible(GLenum uncompressedFormat, GLenum compressedFormat)
+{
+ // Validates mixed format compatibility (uncompressed and compressed) from Table 4.X.1 of the
+ // EXT_copy_image spec.
+ switch (compressedFormat)
+ {
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
+ case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
+ case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:
+ case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
+ case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
+ case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
+ case GL_COMPRESSED_RGBA8_ETC2_EAC:
+ case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
+ case GL_COMPRESSED_RG11_EAC:
+ case GL_COMPRESSED_SIGNED_RG11_EAC:
+ case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
+ case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
+ case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
+ case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
+ case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
+ case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
+ case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
+ case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
+ case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
+ case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
+ case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
+ case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
+ case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
+ case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
+ case GL_COMPRESSED_RGBA_ASTC_3x3x3_OES:
+ case GL_COMPRESSED_RGBA_ASTC_4x3x3_OES:
+ case GL_COMPRESSED_RGBA_ASTC_4x4x3_OES:
+ case GL_COMPRESSED_RGBA_ASTC_4x4x4_OES:
+ case GL_COMPRESSED_RGBA_ASTC_5x4x4_OES:
+ case GL_COMPRESSED_RGBA_ASTC_5x5x4_OES:
+ case GL_COMPRESSED_RGBA_ASTC_5x5x5_OES:
+ case GL_COMPRESSED_RGBA_ASTC_6x5x5_OES:
+ case GL_COMPRESSED_RGBA_ASTC_6x6x5_OES:
+ case GL_COMPRESSED_RGBA_ASTC_6x6x6_OES:
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES:
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES:
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES:
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES:
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES:
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES:
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES:
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES:
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES:
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES:
+ {
+ switch (uncompressedFormat)
+ {
+ case GL_RGBA32UI:
+ case GL_RGBA32I:
+ case GL_RGBA32F:
+ return true;
+ default:
+ return false;
+ }
+ }
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RED_RGTC1_EXT:
+ case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:
+ case GL_COMPRESSED_RGB8_ETC2:
+ case GL_COMPRESSED_SRGB8_ETC2:
+ case GL_COMPRESSED_R11_EAC:
+ case GL_COMPRESSED_SIGNED_R11_EAC:
+ case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+ case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+ {
+ switch (uncompressedFormat)
+ {
+ case GL_RGBA16UI:
+ case GL_RGBA16I:
+ case GL_RGBA16F:
+ case GL_RG32UI:
+ case GL_RG32I:
+ case GL_RG32F:
+ return true;
+ default:
+ return false;
+ }
+ }
+ default:
+ break;
+ }
+
+ return false;
+}
+
+bool ValidateCopyCompressedFormatCompatible(const InternalFormat &srcFormatInfo,
+ const InternalFormat &dstFormatInfo)
+{
+ // Validates compressed format compatibility from Table 4.X.2 of the EXT_copy_image spec.
+
+ ASSERT(srcFormatInfo.internalFormat != dstFormatInfo.internalFormat);
+
+ const GLenum srcFormat = srcFormatInfo.internalFormat;
+ const GLenum dstFormat = dstFormatInfo.internalFormat;
+
+ switch (srcFormat)
+ {
+ case GL_COMPRESSED_RED_RGTC1_EXT:
+ return (dstFormat == GL_COMPRESSED_SIGNED_RED_RGTC1_EXT);
+ case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:
+ return (dstFormat == GL_COMPRESSED_RED_RGTC1_EXT);
+ case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
+ return (dstFormat == GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT);
+ case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:
+ return (dstFormat == GL_COMPRESSED_RED_GREEN_RGTC2_EXT);
+ case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
+ return (dstFormat == GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT);
+ case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
+ return (dstFormat == GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT);
+ case GL_COMPRESSED_R11_EAC:
+ return (dstFormat == GL_COMPRESSED_SIGNED_R11_EAC);
+ case GL_COMPRESSED_SIGNED_R11_EAC:
+ return (dstFormat == GL_COMPRESSED_R11_EAC);
+ case GL_COMPRESSED_RG11_EAC:
+ return (dstFormat == GL_COMPRESSED_SIGNED_RG11_EAC);
+ case GL_COMPRESSED_SIGNED_RG11_EAC:
+ return (dstFormat == GL_COMPRESSED_RG11_EAC);
+ default:
+ break;
+ }
+
+ // Since they can't be the same format and are both compressed formats, one must be linear and
+ // the other nonlinear.
+ if (srcFormatInfo.colorEncoding == dstFormatInfo.colorEncoding)
+ {
+ return false;
+ }
+
+ const GLenum linearFormat = (srcFormatInfo.colorEncoding == GL_LINEAR) ? srcFormat : dstFormat;
+ const GLenum nonLinearFormat =
+ (srcFormatInfo.colorEncoding != GL_LINEAR) ? srcFormat : dstFormat;
+
+ switch (linearFormat)
+ {
+ case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
+ return (nonLinearFormat == GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT);
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ return (nonLinearFormat == GL_COMPRESSED_SRGB_S3TC_DXT1_EXT);
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ return (nonLinearFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT);
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ return (nonLinearFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT);
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+ return (nonLinearFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT);
+ case GL_COMPRESSED_RGB8_ETC2:
+ return (nonLinearFormat == GL_COMPRESSED_SRGB8_ETC2);
+ case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
+ return (nonLinearFormat == GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2);
+ case GL_COMPRESSED_RGBA8_ETC2_EAC:
+ return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC);
+ case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
+ return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR);
+ case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
+ return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR);
+ case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
+ return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR);
+ case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
+ return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR);
+ case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
+ return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR);
+ case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
+ return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR);
+ case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
+ return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR);
+ case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
+ return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR);
+ case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
+ return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR);
+ case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
+ return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR);
+ case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
+ return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR);
+ case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
+ return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR);
+ case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
+ return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR);
+ case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
+ return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR);
+ case GL_COMPRESSED_RGBA_ASTC_3x3x3_OES:
+ return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES);
+ case GL_COMPRESSED_RGBA_ASTC_4x3x3_OES:
+ return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES);
+ case GL_COMPRESSED_RGBA_ASTC_4x4x3_OES:
+ return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES);
+ case GL_COMPRESSED_RGBA_ASTC_4x4x4_OES:
+ return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES);
+ case GL_COMPRESSED_RGBA_ASTC_5x4x4_OES:
+ return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES);
+ case GL_COMPRESSED_RGBA_ASTC_5x5x4_OES:
+ return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES);
+ case GL_COMPRESSED_RGBA_ASTC_5x5x5_OES:
+ return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES);
+ case GL_COMPRESSED_RGBA_ASTC_6x5x5_OES:
+ return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES);
+ case GL_COMPRESSED_RGBA_ASTC_6x6x5_OES:
+ return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES);
+ case GL_COMPRESSED_RGBA_ASTC_6x6x6_OES:
+ return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES);
+ default:
+ break;
+ }
+
+ return false;
+}
+
+bool ValidateCopyFormatCompatible(const InternalFormat &srcFormatInfo,
+ const InternalFormat &dstFormatInfo)
+{
+ // Matching source and destination formats are compatible.
+ if (srcFormatInfo.internalFormat == dstFormatInfo.internalFormat)
+ {
+ return true;
+ }
+
+ if (srcFormatInfo.compressed != dstFormatInfo.compressed)
+ {
+ GLenum uncompressedFormat = (!srcFormatInfo.compressed) ? srcFormatInfo.internalFormat
+ : dstFormatInfo.internalFormat;
+ GLenum compressedFormat = (srcFormatInfo.compressed) ? srcFormatInfo.internalFormat
+ : dstFormatInfo.internalFormat;
+
+ return ValidateCopyMixedFormatCompatible(uncompressedFormat, compressedFormat);
+ }
+
+ if (!srcFormatInfo.compressed)
+ {
+ // Source and destination are uncompressed formats.
+ return (srcFormatInfo.pixelBytes == dstFormatInfo.pixelBytes);
+ }
+
+ return ValidateCopyCompressedFormatCompatible(srcFormatInfo, dstFormatInfo);
+}
+
+bool ValidateCopyImageSubDataBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint srcName,
+ GLenum srcTarget,
+ GLint srcLevel,
+ GLint srcX,
+ GLint srcY,
+ GLint srcZ,
+ GLuint dstName,
+ GLenum dstTarget,
+ GLint dstLevel,
+ GLint dstX,
+ GLint dstY,
+ GLint dstZ,
+ GLsizei srcWidth,
+ GLsizei srcHeight,
+ GLsizei srcDepth)
+{
+ // INVALID_VALUE is generated if the dimensions of the either subregion exceeds the boundaries
+ // of the corresponding image object
+ if ((srcWidth < 0) || (srcHeight < 0) || (srcDepth < 0))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeSize);
+ return false;
+ }
+
+ if (!ValidateCopyImageSubDataTarget(context, entryPoint, srcName, srcTarget))
+ {
+ return false;
+ }
+ if (!ValidateCopyImageSubDataTarget(context, entryPoint, dstName, dstTarget))
+ {
+ return false;
+ }
+
+ if (!ValidateCopyImageSubDataLevel(context, entryPoint, srcTarget, srcLevel))
+ {
+ return false;
+ }
+ if (!ValidateCopyImageSubDataLevel(context, entryPoint, dstTarget, dstLevel))
+ {
+ return false;
+ }
+
+ const InternalFormat &srcFormatInfo =
+ GetTargetFormatInfo(context, entryPoint, srcName, srcTarget, srcLevel);
+ const InternalFormat &dstFormatInfo =
+ GetTargetFormatInfo(context, entryPoint, dstName, dstTarget, dstLevel);
+ GLsizei dstWidth = srcWidth;
+ GLsizei dstHeight = srcHeight;
+ GLsizei srcSamples = 1;
+ GLsizei dstSamples = 1;
+
+ if (srcFormatInfo.internalFormat == GL_NONE || dstFormatInfo.internalFormat == GL_NONE)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidTextureLevel);
+ return false;
+ }
+
+ if (!ValidateCopyImageSubDataTargetRegion(context, entryPoint, srcName, srcTarget, srcLevel,
+ srcX, srcY, srcZ, srcWidth, srcHeight, &srcSamples))
+ {
+ return false;
+ }
+
+ // When copying from a compressed image to an uncompressed image the image texel dimensions
+ // written to the uncompressed image will be source extent divided by the compressed texel block
+ // dimensions.
+ if ((srcFormatInfo.compressed) && (!dstFormatInfo.compressed))
+ {
+ ASSERT(srcFormatInfo.compressedBlockWidth != 0);
+ ASSERT(srcFormatInfo.compressedBlockHeight != 0);
+
+ dstWidth /= srcFormatInfo.compressedBlockWidth;
+ dstHeight /= srcFormatInfo.compressedBlockHeight;
+ }
+ // When copying from an uncompressed image to a compressed image the image texel dimensions
+ // written to the compressed image will be the source extent multiplied by the compressed texel
+ // block dimensions.
+ else if ((!srcFormatInfo.compressed) && (dstFormatInfo.compressed))
+ {
+ dstWidth *= dstFormatInfo.compressedBlockWidth;
+ dstHeight *= dstFormatInfo.compressedBlockHeight;
+ }
+
+ if (!ValidateCopyImageSubDataTargetRegion(context, entryPoint, dstName, dstTarget, dstLevel,
+ dstX, dstY, dstZ, dstWidth, dstHeight, &dstSamples))
+ {
+ return false;
+ }
+
+ bool fillsEntireMip = false;
+ gl::Texture *dstTexture = context->getTexture({dstName});
+ gl::TextureTarget dstTargetPacked = gl::PackParam<gl::TextureTarget>(dstTarget);
+ // TODO(http://anglebug.com/5643): Some targets (e.g., GL_TEXTURE_CUBE_MAP, GL_RENDERBUFFER) are
+ // unsupported when used with compressed formats due to gl::PackParam() returning
+ // TextureTarget::InvalidEnum.
+ if (dstTargetPacked != gl::TextureTarget::InvalidEnum)
+ {
+ const gl::Extents &dstExtents = dstTexture->getExtents(dstTargetPacked, dstLevel);
+ fillsEntireMip = dstX == 0 && dstY == 0 && dstZ == 0 && srcWidth == dstExtents.width &&
+ srcHeight == dstExtents.height && srcDepth == dstExtents.depth;
+ }
+
+ if (srcFormatInfo.compressed && !fillsEntireMip &&
+ !ValidateCompressedRegion(context, entryPoint, srcFormatInfo, srcWidth, srcHeight))
+ {
+ return false;
+ }
+
+ if (dstFormatInfo.compressed && !fillsEntireMip &&
+ !ValidateCompressedRegion(context, entryPoint, dstFormatInfo, dstWidth, dstHeight))
+ {
+ return false;
+ }
+
+ // From EXT_copy_image: INVALID_OPERATION is generated if the source and destination formats
+ // are not compatible, if one image is compressed and the other is uncompressed and the block
+ // size of compressed image is not equal to the texel size of the compressed image.
+ if (!ValidateCopyFormatCompatible(srcFormatInfo, dstFormatInfo))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kIncompatibleTextures);
+ return false;
+ }
+
+ // INVALID_OPERATION is generated if the source and destination number of samples do not match
+ if (srcSamples != dstSamples)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kSamplesOutOfRange);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateCopyTexImageParametersBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLenum internalformat,
+ bool isSubImage,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ Format *textureFormatOut)
+{
+ TextureType texType = TextureTargetToType(target);
+
+ if (xoffset < 0 || yoffset < 0 || zoffset < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeOffset);
+ return false;
+ }
+
+ if (width < 0 || height < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeSize);
+ return false;
+ }
+
+ if (std::numeric_limits<GLsizei>::max() - xoffset < width ||
+ std::numeric_limits<GLsizei>::max() - yoffset < height)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kOffsetOverflow);
+ return false;
+ }
+
+ if (std::numeric_limits<GLint>::max() - width < x ||
+ std::numeric_limits<GLint>::max() - height < y)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kIntegerOverflow);
+ return false;
+ }
+
+ if (border != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidBorder);
+ return false;
+ }
+
+ if (!ValidMipLevel(context, texType, level))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel);
+ return false;
+ }
+
+ const State &state = context->getState();
+ Framebuffer *readFramebuffer = state.getReadFramebuffer();
+ if (!ValidateFramebufferComplete(context, entryPoint, readFramebuffer))
+ {
+ return false;
+ }
+
+ // checkReadBufferResourceSamples = true. Treat renderToTexture textures as single sample since
+ // they will be resolved before copying.
+ if (!readFramebuffer->isDefault() &&
+ !ValidateFramebufferNotMultisampled(context, entryPoint, readFramebuffer, true))
+ {
+ return false;
+ }
+
+ if (readFramebuffer->getReadBufferState() == GL_NONE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kReadBufferNone);
+ return false;
+ }
+
+ // WebGL 1.0 [Section 6.26] Reading From a Missing Attachment
+ // In OpenGL ES it is undefined what happens when an operation tries to read from a missing
+ // attachment and WebGL defines it to be an error. We do the check unconditionally as the
+ // situation is an application error that would lead to a crash in ANGLE.
+ const FramebufferAttachment *source = readFramebuffer->getReadColorAttachment();
+ if (source == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kMissingReadAttachment);
+ return false;
+ }
+
+ if (source->isYUV())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kCopyFromYUVFramebuffer);
+ return false;
+ }
+
+ // ANGLE_multiview spec, Revision 1:
+ // Calling CopyTexSubImage3D, CopyTexImage2D, or CopyTexSubImage2D will result in an
+ // INVALID_FRAMEBUFFER_OPERATION error if the multi-view layout of the current read framebuffer
+ // is FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE or the number of views in the current read
+ // framebuffer is more than one.
+ if (readFramebuffer->readDisallowedByMultiview())
+ {
+ context->validationError(entryPoint, GL_INVALID_FRAMEBUFFER_OPERATION,
+ kMultiviewReadFramebuffer);
+ return false;
+ }
+
+ const Caps &caps = context->getCaps();
+
+ GLint maxDimension = 0;
+ switch (texType)
+ {
+ case TextureType::_2D:
+ maxDimension = caps.max2DTextureSize;
+ break;
+
+ case TextureType::CubeMap:
+ case TextureType::CubeMapArray:
+ maxDimension = caps.maxCubeMapTextureSize;
+ break;
+
+ case TextureType::Rectangle:
+ maxDimension = caps.maxRectangleTextureSize;
+ break;
+
+ case TextureType::_2DArray:
+ maxDimension = caps.max2DTextureSize;
+ break;
+
+ case TextureType::_3D:
+ maxDimension = caps.max3DTextureSize;
+ break;
+
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget);
+ return false;
+ }
+
+ Texture *texture = state.getTargetTexture(texType);
+ if (!texture)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kTextureNotBound);
+ return false;
+ }
+
+ if (texture->getImmutableFormat() && !isSubImage)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kTextureIsImmutable);
+ return false;
+ }
+
+ const InternalFormat &formatInfo =
+ isSubImage ? *texture->getFormat(target, level).info
+ : GetInternalFormatInfo(internalformat, GL_UNSIGNED_BYTE);
+
+ if (formatInfo.depthBits > 0 || formatInfo.compressed)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormat);
+ return false;
+ }
+
+ if (isSubImage)
+ {
+ if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
+ static_cast<size_t>(yoffset + height) > texture->getHeight(target, level) ||
+ static_cast<size_t>(zoffset) >= texture->getDepth(target, level))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kOffsetOverflow);
+ return false;
+ }
+ }
+ else
+ {
+ if ((texType == TextureType::CubeMap || texType == TextureType::CubeMapArray) &&
+ width != height)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kCubemapIncomplete);
+ return false;
+ }
+
+ if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported,
+ internalformat);
+ return false;
+ }
+
+ int maxLevelDimension = (maxDimension >> level);
+ if (static_cast<int>(width) > maxLevelDimension ||
+ static_cast<int>(height) > maxLevelDimension)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize);
+ return false;
+ }
+ }
+
+ // Do not leak the previous texture format for non-subImage case.
+ if (textureFormatOut && isSubImage)
+ {
+ *textureFormatOut = texture->getFormat(target, level);
+ }
+
+ // Detect texture copying feedback loops for WebGL.
+ if (context->isWebGL())
+ {
+ if (readFramebuffer->formsCopyingFeedbackLoopWith(texture->id(), level, zoffset))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kFeedbackLoop);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+const char *ValidateProgramPipelineDrawStates(const Context *context,
+ const Extensions &extensions,
+ ProgramPipeline *programPipeline)
+{
+ for (const ShaderType shaderType : gl::AllShaderTypes())
+ {
+ Program *program = programPipeline->getShaderProgram(shaderType);
+ if (program)
+ {
+ const char *errorMsg = ValidateProgramDrawStates(context, extensions, program);
+ if (errorMsg)
+ {
+ return errorMsg;
+ }
+ }
+ }
+
+ return nullptr;
+}
+
+const char *ValidateProgramPipelineAttachedPrograms(ProgramPipeline *programPipeline)
+{
+ // An INVALID_OPERATION error is generated by any command that transfers vertices to the
+ // GL or launches compute work if the current set of active
+ // program objects cannot be executed, for reasons including:
+ // - There is no current program object specified by UseProgram, there is a current program
+ // pipeline object, and that object is empty (no executable code is installed for any stage).
+ // - A program object is active for at least one, but not all of the shader
+ // stages that were present when the program was linked.
+ if (!programPipeline->getExecutable().getLinkedShaderStages().any())
+ {
+ return gl::err::kNoExecutableCodeInstalled;
+ }
+ for (const ShaderType shaderType : gl::AllShaderTypes())
+ {
+ Program *shaderProgram = programPipeline->getShaderProgram(shaderType);
+ if (shaderProgram)
+ {
+ ProgramExecutable &executable = shaderProgram->getExecutable();
+ for (const ShaderType programShaderType : executable.getLinkedShaderStages())
+ {
+ if (shaderProgram != programPipeline->getShaderProgram(programShaderType))
+ {
+ return gl::err::kNotAllStagesOfSeparableProgramUsed;
+ }
+ }
+ }
+ }
+
+ // [EXT_geometry_shader] Section 11.1.gs Geometry Shaders
+ // A non-separable program object or program pipeline object that includes
+ // a geometry shader must also include a vertex shader.
+ // An INVALID_OPERATION error is generated by any command that transfers
+ // vertices to the GL if the current program state has a geometry shader
+ // but no vertex shader.
+ if (!programPipeline->getShaderProgram(ShaderType::Vertex) &&
+ programPipeline->getShaderProgram(ShaderType::Geometry))
+ {
+ return gl::err::kNoActiveGraphicsShaderStage;
+ }
+
+ return nullptr;
+}
+
+// Note all errors returned from this function are INVALID_OPERATION except for the draw framebuffer
+// completeness check.
+const char *ValidateDrawStates(const Context *context)
+{
+ const Extensions &extensions = context->getExtensions();
+ const State &state = context->getState();
+
+ // WebGL buffers cannot be mapped/unmapped because the MapBufferRange, FlushMappedBufferRange,
+ // and UnmapBuffer entry points are removed from the WebGL 2.0 API.
+ // https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.14
+ VertexArray *vertexArray = state.getVertexArray();
+ ASSERT(vertexArray);
+
+ if (!extensions.webglCompatibilityANGLE && vertexArray->hasInvalidMappedArrayBuffer())
+ {
+ return kBufferMapped;
+ }
+
+ // Note: these separate values are not supported in WebGL, due to D3D's limitations. See
+ // Section 6.10 of the WebGL 1.0 spec.
+ Framebuffer *framebuffer = state.getDrawFramebuffer();
+ ASSERT(framebuffer);
+
+ if (context->getLimitations().noSeparateStencilRefsAndMasks ||
+ extensions.webglCompatibilityANGLE)
+ {
+ ASSERT(framebuffer);
+ const FramebufferAttachment *dsAttachment =
+ framebuffer->getStencilOrDepthStencilAttachment();
+ const GLuint stencilBits = dsAttachment ? dsAttachment->getStencilSize() : 0;
+ ASSERT(stencilBits <= 8);
+
+ const DepthStencilState &depthStencilState = state.getDepthStencilState();
+ if (depthStencilState.stencilTest && stencilBits > 0)
+ {
+ GLuint maxStencilValue = (1 << stencilBits) - 1;
+
+ bool differentRefs =
+ clamp(state.getStencilRef(), 0, static_cast<GLint>(maxStencilValue)) !=
+ clamp(state.getStencilBackRef(), 0, static_cast<GLint>(maxStencilValue));
+ bool differentWritemasks = (depthStencilState.stencilWritemask & maxStencilValue) !=
+ (depthStencilState.stencilBackWritemask & maxStencilValue);
+ bool differentMasks = (depthStencilState.stencilMask & maxStencilValue) !=
+ (depthStencilState.stencilBackMask & maxStencilValue);
+
+ if (differentRefs || differentWritemasks || differentMasks)
+ {
+ if (!extensions.webglCompatibilityANGLE)
+ {
+ WARN() << "This ANGLE implementation does not support separate front/back "
+ "stencil writemasks, reference values, or stencil mask values.";
+ }
+ return kStencilReferenceMaskOrMismatch;
+ }
+ }
+ }
+
+ if (!extensions.floatBlendEXT)
+ {
+ const DrawBufferMask blendEnabledActiveFloat32ColorAttachmentDrawBufferMask =
+ state.getBlendEnabledDrawBufferMask() &
+ framebuffer->getActiveFloat32ColorAttachmentDrawBufferMask();
+ if (blendEnabledActiveFloat32ColorAttachmentDrawBufferMask.any())
+ {
+ return kUnsupportedFloatBlending;
+ }
+ }
+
+ if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
+ extensions.webglCompatibilityANGLE)
+ {
+ if (state.hasSimultaneousConstantColorAndAlphaBlendFunc())
+ {
+ if (extensions.webglCompatibilityANGLE)
+ {
+ return kInvalidConstantColor;
+ }
+
+ WARN() << kConstantColorAlphaLimitation;
+ return kConstantColorAlphaLimitation;
+ }
+ }
+
+ if (!framebuffer->isComplete(context))
+ {
+ // Note: this error should be generated as INVALID_FRAMEBUFFER_OPERATION.
+ return kDrawFramebufferIncomplete;
+ }
+
+ bool framebufferIsYUV = framebuffer->hasYUVAttachment();
+ if (framebufferIsYUV)
+ {
+ const BlendState &blendState = state.getBlendState();
+ if (!blendState.colorMaskRed || !blendState.colorMaskGreen || !blendState.colorMaskBlue)
+ {
+ // When rendering into a YUV framebuffer, the color mask must have r g and b set to
+ // true.
+ return kInvalidColorMaskForYUV;
+ }
+
+ if (blendState.blend)
+ {
+ // When rendering into a YUV framebuffer, blending must be disabled.
+ return kInvalidBlendStateForYUV;
+ }
+ }
+ else
+ {
+ if (framebuffer->hasExternalTextureAttachment())
+ {
+ // It is an error to render into an external texture that is not YUV.
+ return kExternalTextureAttachmentNotYUV;
+ }
+ }
+
+ // Advanced blend equation can only be enabled for a single render target.
+ const BlendStateExt &blendStateExt = state.getBlendStateExt();
+ if (blendStateExt.getUsesAdvancedBlendEquationMask().any())
+ {
+ const size_t drawBufferCount = framebuffer->getDrawbufferStateCount();
+ uint32_t advancedBlendRenderTargetCount = 0;
+
+ for (size_t drawBufferIndex : blendStateExt.getUsesAdvancedBlendEquationMask())
+ {
+ if (drawBufferIndex < drawBufferCount &&
+ framebuffer->getDrawBufferState(drawBufferIndex) != GL_NONE &&
+ blendStateExt.getEnabledMask().test(drawBufferIndex) &&
+ blendStateExt.getUsesAdvancedBlendEquationMask().test(drawBufferIndex))
+ {
+ ++advancedBlendRenderTargetCount;
+ }
+ }
+
+ if (advancedBlendRenderTargetCount > 1)
+ {
+ return kAdvancedBlendEquationWithMRT;
+ }
+ }
+
+ if (context->getStateCache().hasAnyEnabledClientAttrib())
+ {
+ if (extensions.webglCompatibilityANGLE || !state.areClientArraysEnabled())
+ {
+ // [WebGL 1.0] Section 6.5 Enabled Vertex Attributes and Range Checking
+ // If a vertex attribute is enabled as an array via enableVertexAttribArray but no
+ // buffer is bound to that attribute via bindBuffer and vertexAttribPointer, then calls
+ // to drawArrays or drawElements will generate an INVALID_OPERATION error.
+ return kVertexArrayNoBuffer;
+ }
+
+ if (state.getVertexArray()->hasEnabledNullPointerClientArray())
+ {
+ // This is an application error that would normally result in a crash, but we catch it
+ // and return an error
+ return kVertexArrayNoBufferPointer;
+ }
+ }
+
+ // If we are running GLES1, there is no current program.
+ if (context->getClientVersion() >= Version(2, 0))
+ {
+ Program *program = state.getLinkedProgram(context);
+ ProgramPipeline *programPipeline = state.getLinkedProgramPipeline(context);
+ const ProgramExecutable *executable = state.getProgramExecutable();
+
+ bool programIsYUVOutput = false;
+
+ if (program)
+ {
+ const char *errorMsg = ValidateProgramDrawStates(context, extensions, program);
+ if (errorMsg)
+ {
+ return errorMsg;
+ }
+
+ programIsYUVOutput = executable->isYUVOutput();
+ }
+ else if (programPipeline)
+ {
+ const char *errorMsg = ValidateProgramPipelineAttachedPrograms(programPipeline);
+ if (errorMsg)
+ {
+ return errorMsg;
+ }
+
+ errorMsg = ValidateProgramPipelineDrawStates(context, extensions, programPipeline);
+ if (errorMsg)
+ {
+ return errorMsg;
+ }
+
+ if (!programPipeline->isLinked())
+ {
+ return kProgramPipelineLinkFailed;
+ }
+
+ programIsYUVOutput = executable->isYUVOutput();
+ }
+
+ if (executable)
+ {
+ if (!executable->validateSamplers(nullptr, context->getCaps()))
+ {
+ return kTextureTypeConflict;
+ }
+
+ if (executable->hasLinkedTessellationShader())
+ {
+ if (!executable->hasLinkedShaderStage(ShaderType::Vertex))
+ {
+ return kTessellationShaderRequiresVertexShader;
+ }
+
+ if (!executable->hasLinkedShaderStage(ShaderType::TessControl) ||
+ !executable->hasLinkedShaderStage(ShaderType::TessEvaluation))
+ {
+ return kTessellationShaderRequiresBothControlAndEvaluation;
+ }
+ }
+
+ if (state.isTransformFeedbackActive())
+ {
+ if (!ValidateProgramExecutableXFBBuffersPresent(context, executable))
+ {
+ return kTransformFeedbackBufferMissing;
+ }
+ }
+ }
+
+ if (programIsYUVOutput != framebufferIsYUV)
+ {
+ // Both the program and framebuffer must match in YUV output state.
+ return kYUVOutputMissmatch;
+ }
+
+ if (!state.validateSamplerFormats())
+ {
+ return kSamplerFormatMismatch;
+ }
+
+ // Do some additional WebGL-specific validation
+ if (extensions.webglCompatibilityANGLE)
+ {
+ const TransformFeedback *transformFeedbackObject = state.getCurrentTransformFeedback();
+ if (state.isTransformFeedbackActive() &&
+ transformFeedbackObject->buffersBoundForOtherUseInWebGL())
+ {
+ return kTransformFeedbackBufferDoubleBound;
+ }
+
+ // Detect rendering feedback loops for WebGL.
+ if (framebuffer->formsRenderingFeedbackLoopWith(context))
+ {
+ return kFeedbackLoop;
+ }
+
+ // Detect that the vertex shader input types match the attribute types
+ if (!ValidateVertexShaderAttributeTypeMatch(context))
+ {
+ return kVertexShaderTypeMismatch;
+ }
+
+ if (!context->getState().getRasterizerState().rasterizerDiscard &&
+ !context->getState().allActiveDrawBufferChannelsMasked())
+ {
+ // Detect that if there's active color buffer without fragment shader output
+ if (!ValidateFragmentShaderColorBufferMaskMatch(context))
+ {
+ return kDrawBufferMaskMismatch;
+ }
+
+ // Detect that the color buffer types match the fragment shader output types
+ if (!ValidateFragmentShaderColorBufferTypeMatch(context))
+ {
+ return kDrawBufferTypeMismatch;
+ }
+ }
+
+ const VertexArray *vao = context->getState().getVertexArray();
+ if (vao->hasTransformFeedbackBindingConflict(context))
+ {
+ return kVertexBufferBoundForTransformFeedback;
+ }
+
+ // Validate that we are rendering with a linked program.
+ if (!program->isLinked())
+ {
+ return kProgramNotLinked;
+ }
+ }
+ }
+
+ return nullptr;
+}
+
+const char *ValidateProgramPipeline(const Context *context)
+{
+ const State &state = context->getState();
+ // If we are running GLES1, there is no current program.
+ if (context->getClientVersion() >= Version(2, 0))
+ {
+ ProgramPipeline *programPipeline = state.getProgramPipeline();
+ if (programPipeline)
+ {
+ const char *errorMsg = ValidateProgramPipelineAttachedPrograms(programPipeline);
+ if (errorMsg)
+ {
+ return errorMsg;
+ }
+ }
+ }
+ return nullptr;
+}
+
+void RecordDrawModeError(const Context *context, angle::EntryPoint entryPoint, PrimitiveMode mode)
+{
+ const State &state = context->getState();
+ TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
+ if (state.isTransformFeedbackActiveUnpaused())
+ {
+ if (!ValidateTransformFeedbackPrimitiveMode(context, entryPoint,
+ curTransformFeedback->getPrimitiveMode(), mode))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kInvalidDrawModeTransformFeedback);
+ return;
+ }
+ }
+
+ const Extensions &extensions = context->getExtensions();
+
+ switch (mode)
+ {
+ case PrimitiveMode::Points:
+ case PrimitiveMode::Lines:
+ case PrimitiveMode::LineLoop:
+ case PrimitiveMode::LineStrip:
+ case PrimitiveMode::Triangles:
+ case PrimitiveMode::TriangleStrip:
+ case PrimitiveMode::TriangleFan:
+ break;
+
+ case PrimitiveMode::LinesAdjacency:
+ case PrimitiveMode::LineStripAdjacency:
+ case PrimitiveMode::TrianglesAdjacency:
+ case PrimitiveMode::TriangleStripAdjacency:
+ if (!extensions.geometryShaderAny() && context->getClientVersion() < ES_3_2)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM,
+ kGeometryShaderExtensionNotEnabled);
+ return;
+ }
+ break;
+
+ case PrimitiveMode::Patches:
+ if (!extensions.tessellationShaderEXT && context->getClientVersion() < ES_3_2)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM,
+ kTessellationShaderExtensionNotEnabled);
+ return;
+ }
+ break;
+
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidDrawMode);
+ return;
+ }
+
+ // If we are running GLES1, there is no current program.
+ if (context->getClientVersion() >= Version(2, 0))
+ {
+ const ProgramExecutable *executable = state.getProgramExecutable();
+ ASSERT(executable);
+
+ // Do geometry shader specific validations
+ if (executable->hasLinkedShaderStage(ShaderType::Geometry))
+ {
+ if (!IsCompatibleDrawModeWithGeometryShader(
+ mode, executable->getGeometryShaderInputPrimitiveType()))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kIncompatibleDrawModeAgainstGeometryShader);
+ return;
+ }
+ }
+
+ if (executable->hasLinkedTessellationShader() && mode != PrimitiveMode::Patches)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kIncompatibleDrawModeWithTessellationShader);
+ return;
+ }
+
+ if (!executable->hasLinkedTessellationShader() && mode == PrimitiveMode::Patches)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kIncompatibleDrawModeWithoutTessellationShader);
+ return;
+ }
+ }
+
+ // An error should be recorded.
+ UNREACHABLE();
+}
+
+bool ValidateDrawArraysInstancedANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLint first,
+ GLsizei count,
+ GLsizei primcount)
+{
+ if (!context->getExtensions().instancedArraysANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ if (!ValidateDrawArraysInstancedBase(context, entryPoint, mode, first, count, primcount))
+ {
+ return false;
+ }
+
+ return ValidateDrawInstancedANGLE(context, entryPoint);
+}
+
+bool ValidateDrawArraysInstancedEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLint first,
+ GLsizei count,
+ GLsizei primcount)
+{
+ if (!context->getExtensions().instancedArraysEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ if (!ValidateDrawArraysInstancedBase(context, entryPoint, mode, first, count, primcount))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+const char *ValidateDrawElementsStates(const Context *context)
+{
+ const State &state = context->getState();
+
+ if (context->getStateCache().isTransformFeedbackActiveUnpaused())
+ {
+ // EXT_geometry_shader allows transform feedback to work with all draw commands.
+ // [EXT_geometry_shader] Section 12.1, "Transform Feedback"
+ if (!context->getExtensions().geometryShaderAny() && context->getClientVersion() < ES_3_2)
+ {
+ // It is an invalid operation to call DrawElements, DrawRangeElements or
+ // DrawElementsInstanced while transform feedback is active, (3.0.2, section 2.14, pg
+ // 86)
+ return kUnsupportedDrawModeForTransformFeedback;
+ }
+ }
+
+ const VertexArray *vao = state.getVertexArray();
+ Buffer *elementArrayBuffer = vao->getElementArrayBuffer();
+
+ if (elementArrayBuffer)
+ {
+ if (elementArrayBuffer->hasWebGLXFBBindingConflict(context->isWebGL()))
+ {
+ return kElementArrayBufferBoundForTransformFeedback;
+ }
+ if (elementArrayBuffer->isMapped() &&
+ (!elementArrayBuffer->isImmutable() ||
+ (elementArrayBuffer->getAccessFlags() & GL_MAP_PERSISTENT_BIT_EXT) == 0))
+ {
+ return kBufferMapped;
+ }
+ }
+ else
+ {
+ // [WebGL 1.0] Section 6.2 No Client Side Arrays
+ // If an indexed draw command (drawElements) is called and no WebGLBuffer is bound to
+ // the ELEMENT_ARRAY_BUFFER binding point, an INVALID_OPERATION error is generated.
+ if (!context->getState().areClientArraysEnabled() || context->isWebGL())
+ {
+ return kMustHaveElementArrayBinding;
+ }
+ }
+
+ return nullptr;
+}
+
+bool ValidateDrawElementsInstancedANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLsizei count,
+ DrawElementsType type,
+ const void *indices,
+ GLsizei primcount)
+{
+ if (!context->getExtensions().instancedArraysANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ if (!ValidateDrawElementsInstancedBase(context, entryPoint, mode, count, type, indices,
+ primcount))
+ {
+ return false;
+ }
+
+ return ValidateDrawInstancedANGLE(context, entryPoint);
+}
+
+bool ValidateDrawElementsInstancedEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLsizei count,
+ DrawElementsType type,
+ const void *indices,
+ GLsizei primcount)
+{
+ if (!context->getExtensions().instancedArraysEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ if (!ValidateDrawElementsInstancedBase(context, entryPoint, mode, count, type, indices,
+ primcount))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetUniformBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location)
+{
+ if (program.value == 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kProgramDoesNotExist);
+ return false;
+ }
+
+ Program *programObject = GetValidProgram(context, entryPoint, program);
+ if (!programObject)
+ {
+ return false;
+ }
+
+ if (!programObject || !programObject->isLinked())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotLinked);
+ return false;
+ }
+
+ if (!programObject->isValidUniformLocation(location))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidUniformLocation);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateSizedGetUniform(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei bufSize,
+ GLsizei *length)
+{
+ if (length)
+ {
+ *length = 0;
+ }
+
+ if (!ValidateGetUniformBase(context, entryPoint, program, location))
+ {
+ return false;
+ }
+
+ if (bufSize < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kNegativeBufferSize);
+ return false;
+ }
+
+ Program *programObject = context->getProgramResolveLink(program);
+ ASSERT(programObject);
+
+ // sized queries -- ensure the provided buffer is large enough
+ const LinkedUniform &uniform = programObject->getUniformByLocation(location);
+ size_t requiredBytes = VariableExternalSize(uniform.type);
+ if (static_cast<size_t>(bufSize) < requiredBytes)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInsufficientBufferSize);
+ return false;
+ }
+
+ if (length)
+ {
+ *length = VariableComponentCount(uniform.type);
+ }
+ return true;
+}
+
+bool ValidateGetnUniformfvEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei bufSize,
+ const GLfloat *params)
+{
+ return ValidateSizedGetUniform(context, entryPoint, program, location, bufSize, nullptr);
+}
+
+bool ValidateGetnUniformfvRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLfloat *params)
+{
+ UNIMPLEMENTED();
+ return false;
+}
+
+bool ValidateGetnUniformivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei bufSize,
+ const GLint *params)
+{
+ return ValidateSizedGetUniform(context, entryPoint, program, location, bufSize, nullptr);
+}
+
+bool ValidateGetnUniformivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params)
+{
+ UNIMPLEMENTED();
+ return false;
+}
+
+bool ValidateGetnUniformuivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLuint *params)
+{
+ UNIMPLEMENTED();
+ return false;
+}
+
+bool ValidateGetUniformfvRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLfloat *params)
+{
+ if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
+ {
+ return false;
+ }
+
+ GLsizei writeLength = 0;
+
+ // bufSize is validated in ValidateSizedGetUniform
+ if (!ValidateSizedGetUniform(context, entryPoint, program, location, bufSize, &writeLength))
+ {
+ return false;
+ }
+
+ SetRobustLengthParam(length, writeLength);
+
+ return true;
+}
+
+bool ValidateGetUniformivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params)
+{
+ if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
+ {
+ return false;
+ }
+
+ GLsizei writeLength = 0;
+
+ // bufSize is validated in ValidateSizedGetUniform
+ if (!ValidateSizedGetUniform(context, entryPoint, program, location, bufSize, &writeLength))
+ {
+ return false;
+ }
+
+ SetRobustLengthParam(length, writeLength);
+
+ return true;
+}
+
+bool ValidateGetUniformuivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLuint *params)
+{
+ if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
+ {
+ return false;
+ }
+
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ GLsizei writeLength = 0;
+
+ // bufSize is validated in ValidateSizedGetUniform
+ if (!ValidateSizedGetUniform(context, entryPoint, program, location, bufSize, &writeLength))
+ {
+ return false;
+ }
+
+ SetRobustLengthParam(length, writeLength);
+
+ return true;
+}
+
+bool ValidateDiscardFramebufferBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLsizei numAttachments,
+ const GLenum *attachments,
+ bool defaultFramebuffer)
+{
+ if (numAttachments < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeAttachments);
+ return false;
+ }
+
+ for (GLsizei i = 0; i < numAttachments; ++i)
+ {
+ if (attachments[i] >= GL_COLOR_ATTACHMENT0 && attachments[i] <= GL_COLOR_ATTACHMENT31)
+ {
+ if (defaultFramebuffer)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM,
+ kDefaultFramebufferInvalidAttachment);
+ return false;
+ }
+
+ if (attachments[i] >=
+ GL_COLOR_ATTACHMENT0 + static_cast<GLuint>(context->getCaps().maxColorAttachments))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kExceedsMaxColorAttachments);
+ return false;
+ }
+ }
+ else
+ {
+ switch (attachments[i])
+ {
+ case GL_DEPTH_ATTACHMENT:
+ case GL_STENCIL_ATTACHMENT:
+ case GL_DEPTH_STENCIL_ATTACHMENT:
+ if (defaultFramebuffer)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM,
+ kDefaultFramebufferInvalidAttachment);
+ return false;
+ }
+ break;
+ case GL_COLOR:
+ case GL_DEPTH:
+ case GL_STENCIL:
+ if (!defaultFramebuffer)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM,
+ kDefaultFramebufferAttachmentOnUserFBO);
+ return false;
+ }
+ break;
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidAttachment);
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+bool ValidateInsertEventMarkerEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei length,
+ const char *marker)
+{
+ if (!context->getExtensions().debugMarkerEXT)
+ {
+ // The debug marker calls should not set error state
+ // However, it seems reasonable to set an error state if the extension is not enabled
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ // Note that debug marker calls must not set error state
+ if (length < 0)
+ {
+ return false;
+ }
+
+ if (marker == nullptr)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidatePushGroupMarkerEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei length,
+ const char *marker)
+{
+ if (!context->getExtensions().debugMarkerEXT)
+ {
+ // The debug marker calls should not set error state
+ // However, it seems reasonable to set an error state if the extension is not enabled
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ // Note that debug marker calls must not set error state
+ if (length < 0)
+ {
+ return false;
+ }
+
+ if (length > 0 && marker == nullptr)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateEGLImageObject(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType type,
+ GLeglImageOES image)
+{
+ egl::Image *imageObject = static_cast<egl::Image *>(image);
+
+ ASSERT(context->getDisplay());
+ if (!context->getDisplay()->isValidImage(imageObject))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidEGLImage);
+ return false;
+ }
+
+ if (imageObject->getSamples() > 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kEGLImageCannotCreate2DMultisampled);
+ return false;
+ }
+
+ if (!imageObject->isTexturable(context))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kEGLImageTextureFormatNotSupported);
+ return false;
+ }
+
+ // Validate source egl image and target texture are compatible
+ size_t depth = static_cast<size_t>(imageObject->getExtents().depth);
+ if (imageObject->isYUV() && type != TextureType::External)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ "Image is YUV, target must be TEXTURE_EXTERNAL_OES");
+ return false;
+ }
+
+ if (depth > 1 && type != TextureType::_2DArray && type != TextureType::CubeMap &&
+ type != TextureType::CubeMapArray && type != TextureType::_3D)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kEGLImageTextureTargetMismatch);
+ return false;
+ }
+
+ if (imageObject->isCubeMap() && type != TextureType::CubeMapArray &&
+ (type != TextureType::CubeMap || depth > gl::kCubeFaceCount))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kEGLImageTextureTargetMismatch);
+ return false;
+ }
+
+ if (imageObject->getLevelCount() > 1 && type == TextureType::External)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kEGLImageTextureTargetMismatch);
+ return false;
+ }
+
+ // 3d EGLImages are currently not supported
+ if (type == TextureType::_3D)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kEGLImageTextureTargetMismatch);
+ return false;
+ }
+
+ if (imageObject->hasProtectedContent() && !context->getState().hasProtectedContent())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ "Mismatch between Image and Context Protected Content state");
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateEGLImageTargetTexture2DOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType type,
+ GLeglImageOES image)
+{
+ if (!context->getExtensions().EGLImageOES && !context->getExtensions().EGLImageExternalOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ switch (type)
+ {
+ case TextureType::_2D:
+ if (!context->getExtensions().EGLImageOES)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported,
+ ToGLenum(type));
+ }
+ break;
+
+ case TextureType::_2DArray:
+ if (!context->getExtensions().EGLImageArrayEXT)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported,
+ ToGLenum(type));
+ }
+ break;
+
+ case TextureType::External:
+ if (!context->getExtensions().EGLImageExternalOES)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported,
+ ToGLenum(type));
+ }
+ break;
+
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget);
+ return false;
+ }
+
+ return ValidateEGLImageObject(context, entryPoint, type, image);
+}
+
+bool ValidateEGLImageTargetRenderbufferStorageOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLeglImageOES image)
+{
+ if (!context->getExtensions().EGLImageOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ switch (target)
+ {
+ case GL_RENDERBUFFER:
+ break;
+
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidRenderbufferTarget);
+ return false;
+ }
+
+ egl::Image *imageObject = static_cast<egl::Image *>(image);
+
+ ASSERT(context->getDisplay());
+ if (!context->getDisplay()->isValidImage(imageObject))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidEGLImage);
+ return false;
+ }
+
+ if (!imageObject->isRenderable(context))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kEGLImageRenderbufferFormatNotSupported);
+ return false;
+ }
+
+ if (imageObject->hasProtectedContent() != context->getState().hasProtectedContent())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ "Mismatch between Image and Context Protected Content state");
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateProgramBinaryBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLenum binaryFormat,
+ const void *binary,
+ GLint length)
+{
+ Program *programObject = GetValidProgram(context, entryPoint, program);
+ if (programObject == nullptr)
+ {
+ return false;
+ }
+
+ const std::vector<GLenum> &programBinaryFormats = context->getCaps().programBinaryFormats;
+ if (std::find(programBinaryFormats.begin(), programBinaryFormats.end(), binaryFormat) ==
+ programBinaryFormats.end())
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidProgramBinaryFormat);
+ return false;
+ }
+
+ if (context->hasActiveTransformFeedback(program))
+ {
+ // ES 3.0.4 section 2.15 page 91
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kTransformFeedbackProgramBinary);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetProgramBinaryBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLenum *binaryFormat,
+ const void *binary)
+{
+ Program *programObject = GetValidProgram(context, entryPoint, program);
+ if (programObject == nullptr)
+ {
+ return false;
+ }
+
+ if (!programObject->isLinked())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotLinked);
+ return false;
+ }
+
+ if (context->getCaps().programBinaryFormats.empty())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kNoProgramBinaryFormats);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateDrawBuffersBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const GLenum *bufs)
+{
+ // INVALID_VALUE is generated if n is negative or greater than value of MAX_DRAW_BUFFERS
+ if (n < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeCount);
+ return false;
+ }
+ if (n > context->getCaps().maxDrawBuffers)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxDrawBuffer);
+ return false;
+ }
+
+ ASSERT(context->getState().getDrawFramebuffer());
+ FramebufferID frameBufferId = context->getState().getDrawFramebuffer()->id();
+ GLuint maxColorAttachment = GL_COLOR_ATTACHMENT0_EXT + context->getCaps().maxColorAttachments;
+
+ // This should come first before the check for the default frame buffer
+ // because when we switch to ES3.1+, invalid enums will return INVALID_ENUM
+ // rather than INVALID_OPERATION
+ for (int colorAttachment = 0; colorAttachment < n; colorAttachment++)
+ {
+ const GLenum attachment = GL_COLOR_ATTACHMENT0_EXT + colorAttachment;
+
+ if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != GL_BACK &&
+ (bufs[colorAttachment] < GL_COLOR_ATTACHMENT0 ||
+ bufs[colorAttachment] > GL_COLOR_ATTACHMENT31))
+ {
+ // Value in bufs is not NONE, BACK, or GL_COLOR_ATTACHMENTi
+ // The 3.0.4 spec says to generate GL_INVALID_OPERATION here, but this
+ // was changed to GL_INVALID_ENUM in 3.1, which dEQP also expects.
+ // 3.1 is still a bit ambiguous about the error, but future specs are
+ // expected to clarify that GL_INVALID_ENUM is the correct error.
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidDrawBuffer);
+ return false;
+ }
+ else if (bufs[colorAttachment] >= maxColorAttachment)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExceedsMaxColorAttachments);
+ return false;
+ }
+ else if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != attachment &&
+ frameBufferId.value != 0)
+ {
+ // INVALID_OPERATION-GL is bound to buffer and ith argument
+ // is not COLOR_ATTACHMENTi or NONE
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidDrawBufferValue);
+ return false;
+ }
+ }
+
+ // INVALID_OPERATION is generated if GL is bound to the default framebuffer
+ // and n is not 1 or bufs is bound to value other than BACK and NONE
+ if (frameBufferId.value == 0)
+ {
+ if (n != 1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kInvalidDrawBufferCountForDefault);
+ return false;
+ }
+
+ if (bufs[0] != GL_NONE && bufs[0] != GL_BACK)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kDefaultFramebufferInvalidDrawBuffer);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateGetBufferPointervBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding target,
+ GLenum pname,
+ GLsizei *length,
+ void *const *params)
+{
+ if (length)
+ {
+ *length = 0;
+ }
+
+ if (!context->isValidBufferBinding(target))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBufferTypes);
+ return false;
+ }
+
+ switch (pname)
+ {
+ case GL_BUFFER_MAP_POINTER:
+ break;
+
+ default:
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname);
+ return false;
+ }
+
+ // GLES 3.0 section 2.10.1: "Attempts to attempts to modify or query buffer object state for a
+ // target bound to zero generate an INVALID_OPERATION error."
+ // GLES 3.1 section 6.6 explicitly specifies this error.
+ if (context->getState().getTargetBuffer(target) == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferPointerNotAvailable);
+ return false;
+ }
+
+ if (length)
+ {
+ *length = 1;
+ }
+
+ return true;
+}
+
+bool ValidateUnmapBufferBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding target)
+{
+ if (!context->isValidBufferBinding(target))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBufferTypes);
+ return false;
+ }
+
+ Buffer *buffer = context->getState().getTargetBuffer(target);
+
+ if (buffer == nullptr || !buffer->isMapped())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferNotMapped);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateMapBufferRangeBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding target,
+ GLintptr offset,
+ GLsizeiptr length,
+ GLbitfield access)
+{
+ if (!context->isValidBufferBinding(target))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBufferTypes);
+ return false;
+ }
+
+ if (offset < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeOffset);
+ return false;
+ }
+
+ if (length < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeLength);
+ return false;
+ }
+
+ Buffer *buffer = context->getState().getTargetBuffer(target);
+
+ if (!buffer)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferNotMappable);
+ return false;
+ }
+
+ // Check for buffer overflow
+ CheckedNumeric<size_t> checkedOffset(offset);
+ auto checkedSize = checkedOffset + length;
+
+ if (!checkedSize.IsValid() || checkedSize.ValueOrDie() > static_cast<size_t>(buffer->getSize()))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kMapOutOfRange);
+ return false;
+ }
+
+ // Check for invalid bits in the mask
+ constexpr GLbitfield kAllAccessBits =
+ GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT |
+ GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_UNSYNCHRONIZED_BIT;
+
+ if (buffer->isImmutable())
+ {
+ // GL_EXT_buffer_storage's additions to glMapBufferRange
+ constexpr GLbitfield kBufferStorageAccessBits =
+ kAllAccessBits | GL_MAP_PERSISTENT_BIT_EXT | GL_MAP_COHERENT_BIT_EXT;
+
+ if ((access & ~kBufferStorageAccessBits) != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidAccessBits);
+ return false;
+ }
+
+ // It is invalid if any of bufferStorageMatchedAccessBits bits are included in access,
+ // but the same bits are not included in the buffer's storage flags
+ constexpr GLbitfield kBufferStorageMatchedAccessBits = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT |
+ GL_MAP_PERSISTENT_BIT_EXT |
+ GL_MAP_COHERENT_BIT_EXT;
+ GLbitfield accessFlags = access & kBufferStorageMatchedAccessBits;
+ if ((accessFlags & buffer->getStorageExtUsageFlags()) != accessFlags)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidAccessBits);
+ return false;
+ }
+ }
+ else if ((access & ~kAllAccessBits) != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidAccessBits);
+ return false;
+ }
+
+ if (length == 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kLengthZero);
+ return false;
+ }
+
+ if (buffer->isMapped())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferAlreadyMapped);
+ return false;
+ }
+
+ // Check for invalid bit combinations
+ if ((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidAccessBitsReadWrite);
+ return false;
+ }
+
+ GLbitfield writeOnlyBits =
+ GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT;
+
+ if ((access & GL_MAP_READ_BIT) != 0 && (access & writeOnlyBits) != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidAccessBitsRead);
+ return false;
+ }
+
+ if ((access & GL_MAP_WRITE_BIT) == 0 && (access & GL_MAP_FLUSH_EXPLICIT_BIT) != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidAccessBitsFlush);
+ return false;
+ }
+
+ return ValidateMapBufferBase(context, entryPoint, target);
+}
+
+bool ValidateFlushMappedBufferRangeBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding target,
+ GLintptr offset,
+ GLsizeiptr length)
+{
+ if (offset < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeOffset);
+ return false;
+ }
+
+ if (length < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeLength);
+ return false;
+ }
+
+ if (!context->isValidBufferBinding(target))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBufferTypes);
+ return false;
+ }
+
+ Buffer *buffer = context->getState().getTargetBuffer(target);
+
+ if (buffer == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFlushZero);
+ return false;
+ }
+
+ if (!buffer->isMapped() || (buffer->getAccessFlags() & GL_MAP_FLUSH_EXPLICIT_BIT) == 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFlushTarget);
+ return false;
+ }
+
+ // Check for buffer overflow
+ CheckedNumeric<size_t> checkedOffset(offset);
+ auto checkedSize = checkedOffset + length;
+
+ if (!checkedSize.IsValid() ||
+ checkedSize.ValueOrDie() > static_cast<size_t>(buffer->getMapLength()))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidFlushOutOfRange);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGenOrDelete(const Context *context, angle::EntryPoint entryPoint, GLint n)
+{
+ if (n < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeCount);
+ return false;
+ }
+ return true;
+}
+
+bool ValidateRobustEntryPoint(const Context *context, angle::EntryPoint entryPoint, GLsizei bufSize)
+{
+ if (!context->getExtensions().robustClientMemoryANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ if (bufSize < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBufferSize);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateRobustBufferSize(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei bufSize,
+ GLsizei numParams)
+{
+ if (bufSize < numParams)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInsufficientParams);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetFramebufferAttachmentParameterivBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ GLenum pname,
+ GLsizei *numParams)
+{
+ if (!ValidFramebufferTarget(context, target))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFramebufferTarget);
+ 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_TEXTURE_NUM_VIEWS_OVR:
+ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR:
+ if (clientVersion < 3 ||
+ !(context->getExtensions().multiviewOVR || context->getExtensions().multiview2OVR))
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname);
+ return false;
+ }
+ break;
+
+ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT:
+ if (!context->getExtensions().multisampledRenderToTextureEXT)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname);
+ return false;
+ }
+ break;
+
+ case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
+ if (clientVersion < 3 && !context->getExtensions().sRGBEXT)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname);
+ 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->validationError(entryPoint, GL_INVALID_ENUM, kES3Required);
+ return false;
+ }
+ break;
+
+ case GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT:
+ if (!context->getExtensions().geometryShaderAny() &&
+ context->getClientVersion() < ES_3_2)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM,
+ kGeometryShaderExtensionNotEnabled);
+ return false;
+ }
+ break;
+
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname);
+ return false;
+ }
+
+ // Determine if the attachment is a valid enum
+ switch (attachment)
+ {
+ case GL_BACK:
+ case GL_DEPTH:
+ case GL_STENCIL:
+ if (clientVersion < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidAttachment);
+ return false;
+ }
+ break;
+
+ case GL_DEPTH_STENCIL_ATTACHMENT:
+ if (clientVersion < 3 && !context->isWebGL1())
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidAttachment);
+ return false;
+ }
+ break;
+
+ case GL_COLOR_ATTACHMENT0:
+ case GL_DEPTH_ATTACHMENT:
+ case GL_STENCIL_ATTACHMENT:
+ break;
+
+ default:
+ if ((clientVersion < 3 && !context->getExtensions().drawBuffersEXT) ||
+ attachment < GL_COLOR_ATTACHMENT0_EXT ||
+ (attachment - GL_COLOR_ATTACHMENT0_EXT) >=
+ static_cast<GLuint>(context->getCaps().maxColorAttachments))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidAttachment);
+ return false;
+ }
+ break;
+ }
+
+ const Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
+ ASSERT(framebuffer);
+
+ if (framebuffer->isDefault())
+ {
+ if (clientVersion < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kDefaultFramebufferTarget);
+ return false;
+ }
+
+ switch (attachment)
+ {
+ case GL_BACK:
+ case GL_DEPTH:
+ case GL_STENCIL:
+ break;
+
+ default:
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidAttachment);
+ 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->isWebGL1())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kInvalidAttachment);
+ return false;
+ }
+ break;
+
+ default:
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidAttachment);
+ return false;
+ }
+ }
+ }
+
+ const FramebufferAttachment *attachmentObject = framebuffer->getAttachment(context, 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->validationError(entryPoint, GL_INVALID_ENUM,
+ kFramebufferIncompleteAttachment);
+ return false;
+ }
+ break;
+
+ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
+ if (attachmentObject->type() != GL_TEXTURE)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM,
+ kFramebufferIncompleteAttachment);
+ return false;
+ }
+ break;
+
+ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
+ if (attachmentObject->type() != GL_TEXTURE)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM,
+ kFramebufferIncompleteAttachment);
+ return false;
+ }
+ break;
+
+ case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
+ if (attachment == GL_DEPTH_STENCIL_ATTACHMENT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidAttachment);
+ return false;
+ }
+ break;
+
+ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
+ if (attachmentObject->type() != GL_TEXTURE)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM,
+ kFramebufferIncompleteAttachment);
+ 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->validationError(entryPoint, GL_INVALID_ENUM,
+ kInvalidFramebufferAttachmentParameter);
+ return false;
+ }
+ break;
+
+ default:
+ if (clientVersion < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM,
+ kInvalidFramebufferAttachmentParameter);
+ return false;
+ }
+ else
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kInvalidFramebufferAttachmentParameter);
+ return false;
+ }
+ }
+ }
+
+ if (numParams)
+ {
+ *numParams = 1;
+ }
+
+ return true;
+}
+
+bool ValidateGetFramebufferParameterivBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum pname,
+ const GLint *params)
+{
+ if (!ValidFramebufferTarget(context, target))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFramebufferTarget);
+ return false;
+ }
+
+ switch (pname)
+ {
+ case GL_FRAMEBUFFER_DEFAULT_WIDTH:
+ case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
+ case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
+ case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
+ break;
+ case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
+ if (!context->getExtensions().geometryShaderAny() &&
+ context->getClientVersion() < ES_3_2)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM,
+ kGeometryShaderExtensionNotEnabled);
+ return false;
+ }
+ break;
+ case GL_FRAMEBUFFER_FLIP_Y_MESA:
+ if (!context->getExtensions().framebufferFlipYMESA)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname);
+ return false;
+ }
+ break;
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname);
+ return false;
+ }
+
+ const Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
+ ASSERT(framebuffer);
+
+ if (framebuffer->isDefault())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kDefaultFramebuffer);
+ return false;
+ }
+ return true;
+}
+
+bool ValidateGetFramebufferAttachmentParameterivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params)
+{
+ if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
+ {
+ return false;
+ }
+
+ GLsizei numParams = 0;
+ if (!ValidateGetFramebufferAttachmentParameterivBase(context, entryPoint, target, attachment,
+ pname, &numParams))
+ {
+ return false;
+ }
+
+ if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
+ {
+ return false;
+ }
+
+ SetRobustLengthParam(length, numParams);
+
+ return true;
+}
+
+bool ValidateGetBufferParameterivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding target,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params)
+{
+ if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
+ {
+ return false;
+ }
+
+ GLsizei numParams = 0;
+
+ if (!ValidateGetBufferParameterBase(context, entryPoint, target, pname, false, &numParams))
+ {
+ return false;
+ }
+
+ if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
+ {
+ return false;
+ }
+
+ SetRobustLengthParam(length, numParams);
+ return true;
+}
+
+bool ValidateGetBufferParameteri64vRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding target,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint64 *params)
+{
+ GLsizei numParams = 0;
+
+ if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
+ {
+ return false;
+ }
+
+ if (!ValidateGetBufferParameterBase(context, entryPoint, target, pname, false, &numParams))
+ {
+ return false;
+ }
+
+ if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
+ {
+ return false;
+ }
+
+ SetRobustLengthParam(length, numParams);
+
+ return true;
+}
+
+bool ValidateGetProgramivBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLenum pname,
+ GLsizei *numParams)
+{
+ // Currently, all GetProgramiv queries return 1 parameter
+ if (numParams)
+ {
+ *numParams = 1;
+ }
+
+ if (context->isContextLost())
+ {
+ context->validationError(entryPoint, GL_CONTEXT_LOST, kContextLost);
+
+ if (context->getExtensions().parallelShaderCompileKHR && pname == GL_COMPLETION_STATUS_KHR)
+ {
+ // Generate an error but still return true, the context still needs to return a
+ // value in this case.
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ // Special case for GL_COMPLETION_STATUS_KHR: don't resolve the link. Otherwise resolve it now.
+ Program *programObject = (pname == GL_COMPLETION_STATUS_KHR)
+ ? GetValidProgramNoResolve(context, entryPoint, program)
+ : GetValidProgram(context, entryPoint, 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().getProgramBinaryOES)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname);
+ 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->validationError(entryPoint, GL_INVALID_ENUM, kEnumRequiresGLES30);
+ return false;
+ }
+ break;
+
+ case GL_PROGRAM_SEPARABLE:
+ case GL_ACTIVE_ATOMIC_COUNTER_BUFFERS:
+ if (context->getClientVersion() < Version(3, 1))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kEnumRequiresGLES31);
+ return false;
+ }
+ break;
+
+ case GL_COMPUTE_WORK_GROUP_SIZE:
+ if (context->getClientVersion() < Version(3, 1))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kEnumRequiresGLES31);
+ return false;
+ }
+
+ // [OpenGL ES 3.1] Chapter 7.12 Page 122
+ // An INVALID_OPERATION error is generated if COMPUTE_WORK_GROUP_SIZE is queried for a
+ // program which has not been linked successfully, or which does not contain objects to
+ // form a compute shader.
+ if (!programObject->isLinked())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotLinked);
+ return false;
+ }
+ if (!programObject->getExecutable().hasLinkedShaderStage(ShaderType::Compute))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kNoActiveComputeShaderStage);
+ return false;
+ }
+ break;
+
+ case GL_GEOMETRY_LINKED_INPUT_TYPE_EXT:
+ case GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT:
+ case GL_GEOMETRY_LINKED_VERTICES_OUT_EXT:
+ case GL_GEOMETRY_SHADER_INVOCATIONS_EXT:
+ if (!context->getExtensions().geometryShaderAny() &&
+ context->getClientVersion() < ES_3_2)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM,
+ kGeometryShaderExtensionNotEnabled);
+ return false;
+ }
+
+ // [EXT_geometry_shader] Chapter 7.12
+ // An INVALID_OPERATION error is generated if GEOMETRY_LINKED_VERTICES_OUT_EXT,
+ // GEOMETRY_LINKED_INPUT_TYPE_EXT, GEOMETRY_LINKED_OUTPUT_TYPE_EXT, or
+ // GEOMETRY_SHADER_INVOCATIONS_EXT are queried for a program which has not been linked
+ // successfully, or which does not contain objects to form a geometry shader.
+ if (!programObject->isLinked())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotLinked);
+ return false;
+ }
+ if (!programObject->getExecutable().hasLinkedShaderStage(ShaderType::Geometry))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kNoActiveGeometryShaderStage);
+ return false;
+ }
+ break;
+
+ case GL_COMPLETION_STATUS_KHR:
+ if (!context->getExtensions().parallelShaderCompileKHR)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+ break;
+ case GL_TESS_CONTROL_OUTPUT_VERTICES_EXT:
+ case GL_TESS_GEN_MODE_EXT:
+ case GL_TESS_GEN_SPACING_EXT:
+ case GL_TESS_GEN_VERTEX_ORDER_EXT:
+ case GL_TESS_GEN_POINT_MODE_EXT:
+ if (!context->getExtensions().tessellationShaderEXT &&
+ context->getClientVersion() < ES_3_2)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM,
+ kTessellationShaderExtensionNotEnabled);
+ return false;
+ }
+ if (!programObject->isLinked())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotLinked);
+ return false;
+ }
+ break;
+ default:
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetProgramivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params)
+{
+ if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
+ {
+ return false;
+ }
+
+ GLsizei numParams = 0;
+
+ if (!ValidateGetProgramivBase(context, entryPoint, program, pname, &numParams))
+ {
+ return false;
+ }
+
+ if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
+ {
+ return false;
+ }
+
+ SetRobustLengthParam(length, numParams);
+
+ return true;
+}
+
+bool ValidateGetRenderbufferParameterivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params)
+{
+ if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
+ {
+ return false;
+ }
+
+ GLsizei numParams = 0;
+
+ if (!ValidateGetRenderbufferParameterivBase(context, entryPoint, target, pname, &numParams))
+ {
+ return false;
+ }
+
+ if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
+ {
+ return false;
+ }
+
+ SetRobustLengthParam(length, numParams);
+
+ return true;
+}
+
+bool ValidateGetShaderivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID shader,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params)
+{
+ if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
+ {
+ return false;
+ }
+
+ GLsizei numParams = 0;
+
+ if (!ValidateGetShaderivBase(context, entryPoint, shader, pname, &numParams))
+ {
+ return false;
+ }
+
+ if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
+ {
+ return false;
+ }
+
+ SetRobustLengthParam(length, numParams);
+
+ return true;
+}
+
+bool ValidateGetTexParameterfvRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLfloat *params)
+{
+ if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
+ {
+ return false;
+ }
+
+ GLsizei numParams = 0;
+
+ if (!ValidateGetTexParameterBase(context, entryPoint, target, pname, &numParams))
+ {
+ return false;
+ }
+
+ if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
+ {
+ return false;
+ }
+
+ SetRobustLengthParam(length, numParams);
+
+ return true;
+}
+
+bool ValidateGetTexParameterivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params)
+{
+
+ if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
+ {
+ return false;
+ }
+ GLsizei numParams = 0;
+ if (!ValidateGetTexParameterBase(context, entryPoint, target, pname, &numParams))
+ {
+ return false;
+ }
+
+ if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
+ {
+ return false;
+ }
+
+ SetRobustLengthParam(length, numParams);
+ return true;
+}
+
+bool ValidateGetTexParameterIivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params)
+{
+ UNIMPLEMENTED();
+ return false;
+}
+
+bool ValidateGetTexParameterIuivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLuint *params)
+{
+ UNIMPLEMENTED();
+ return false;
+}
+
+bool ValidateTexParameterfvRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLfloat *params)
+{
+ if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
+ {
+ return false;
+ }
+
+ return ValidateTexParameterBase(context, entryPoint, target, pname, bufSize, true, params);
+}
+
+bool ValidateTexParameterivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLint *params)
+{
+ if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
+ {
+ return false;
+ }
+
+ return ValidateTexParameterBase(context, entryPoint, target, pname, bufSize, true, params);
+}
+
+bool ValidateTexParameterIivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLint *params)
+{
+ UNIMPLEMENTED();
+ return false;
+}
+
+bool ValidateTexParameterIuivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLuint *params)
+{
+ UNIMPLEMENTED();
+ return false;
+}
+
+bool ValidateGetSamplerParameterfvRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID sampler,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLfloat *params)
+{
+ if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
+ {
+ return false;
+ }
+
+ GLsizei numParams = 0;
+
+ if (!ValidateGetSamplerParameterBase(context, entryPoint, sampler, pname, &numParams))
+ {
+ return false;
+ }
+
+ if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
+ {
+ return false;
+ }
+
+ SetRobustLengthParam(length, numParams);
+ return true;
+}
+
+bool ValidateGetSamplerParameterivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID sampler,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params)
+{
+ if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
+ {
+ return false;
+ }
+
+ GLsizei numParams = 0;
+
+ if (!ValidateGetSamplerParameterBase(context, entryPoint, sampler, pname, &numParams))
+ {
+ return false;
+ }
+
+ if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
+ {
+ return false;
+ }
+
+ SetRobustLengthParam(length, numParams);
+ return true;
+}
+
+bool ValidateGetSamplerParameterIivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID sampler,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params)
+{
+ UNIMPLEMENTED();
+ return false;
+}
+
+bool ValidateGetSamplerParameterIuivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID sampler,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLuint *params)
+{
+ UNIMPLEMENTED();
+ return false;
+}
+
+bool ValidateSamplerParameterfvRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID sampler,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLfloat *params)
+{
+ if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
+ {
+ return false;
+ }
+
+ return ValidateSamplerParameterBase(context, entryPoint, sampler, pname, bufSize, true, params);
+}
+
+bool ValidateSamplerParameterivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID sampler,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLint *params)
+{
+ if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
+ {
+ return false;
+ }
+
+ return ValidateSamplerParameterBase(context, entryPoint, sampler, pname, bufSize, true, params);
+}
+
+bool ValidateSamplerParameterIivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID sampler,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLint *param)
+{
+ UNIMPLEMENTED();
+ return false;
+}
+
+bool ValidateSamplerParameterIuivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID sampler,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLuint *param)
+{
+ UNIMPLEMENTED();
+ return false;
+}
+
+bool ValidateGetVertexAttribfvRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLfloat *params)
+{
+ if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
+ {
+ return false;
+ }
+
+ GLsizei writeLength = 0;
+
+ if (!ValidateGetVertexAttribBase(context, entryPoint, index, pname, &writeLength, false, false))
+ {
+ return false;
+ }
+
+ if (!ValidateRobustBufferSize(context, entryPoint, bufSize, writeLength))
+ {
+ return false;
+ }
+
+ SetRobustLengthParam(length, writeLength);
+ return true;
+}
+
+bool ValidateGetVertexAttribivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params)
+{
+ if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
+ {
+ return false;
+ }
+
+ GLsizei writeLength = 0;
+
+ if (!ValidateGetVertexAttribBase(context, entryPoint, index, pname, &writeLength, false, false))
+ {
+ return false;
+ }
+
+ if (!ValidateRobustBufferSize(context, entryPoint, bufSize, writeLength))
+ {
+ return false;
+ }
+
+ SetRobustLengthParam(length, writeLength);
+
+ return true;
+}
+
+bool ValidateGetVertexAttribPointervRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ void *const *pointer)
+{
+ if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
+ {
+ return false;
+ }
+
+ GLsizei writeLength = 0;
+
+ if (!ValidateGetVertexAttribBase(context, entryPoint, index, pname, &writeLength, true, false))
+ {
+ return false;
+ }
+
+ if (!ValidateRobustBufferSize(context, entryPoint, bufSize, writeLength))
+ {
+ return false;
+ }
+
+ SetRobustLengthParam(length, writeLength);
+
+ return true;
+}
+
+bool ValidateGetVertexAttribIivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params)
+{
+ if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
+ {
+ return false;
+ }
+
+ GLsizei writeLength = 0;
+
+ if (!ValidateGetVertexAttribBase(context, entryPoint, index, pname, &writeLength, false, true))
+ {
+ return false;
+ }
+
+ if (!ValidateRobustBufferSize(context, entryPoint, bufSize, writeLength))
+ {
+ return false;
+ }
+
+ SetRobustLengthParam(length, writeLength);
+
+ return true;
+}
+
+bool ValidateGetVertexAttribIuivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLuint *params)
+{
+ if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
+ {
+ return false;
+ }
+
+ GLsizei writeLength = 0;
+
+ if (!ValidateGetVertexAttribBase(context, entryPoint, index, pname, &writeLength, false, true))
+ {
+ return false;
+ }
+
+ if (!ValidateRobustBufferSize(context, entryPoint, bufSize, writeLength))
+ {
+ return false;
+ }
+
+ SetRobustLengthParam(length, writeLength);
+
+ return true;
+}
+
+bool ValidateGetActiveUniformBlockivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformBlockIndex uniformBlockIndex,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params)
+{
+ if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
+ {
+ return false;
+ }
+
+ GLsizei writeLength = 0;
+
+ if (!ValidateGetActiveUniformBlockivBase(context, entryPoint, program, uniformBlockIndex, pname,
+ &writeLength))
+ {
+ return false;
+ }
+
+ if (!ValidateRobustBufferSize(context, entryPoint, bufSize, writeLength))
+ {
+ return false;
+ }
+
+ SetRobustLengthParam(length, writeLength);
+
+ return true;
+}
+
+bool ValidateGetInternalformativRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum internalformat,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params)
+{
+ if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
+ {
+ return false;
+ }
+
+ GLsizei numParams = 0;
+
+ if (!ValidateGetInternalFormativBase(context, entryPoint, target, internalformat, pname,
+ bufSize, &numParams))
+ {
+ return false;
+ }
+
+ if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
+ {
+ return false;
+ }
+
+ SetRobustLengthParam(length, numParams);
+
+ return true;
+}
+
+// Perform validation from WebGL 2 section 5.10 "Invalid Clears":
+// In the WebGL 2 API, trying to perform a clear when there is a mismatch between the type of the
+// specified clear value and the type of a buffer that is being cleared generates an
+// INVALID_OPERATION error instead of producing undefined results
+bool ValidateWebGLFramebufferAttachmentClearType(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint drawbuffer,
+ const GLenum *validComponentTypes,
+ size_t validComponentTypeCount)
+{
+ const FramebufferAttachment *attachment =
+ context->getState().getDrawFramebuffer()->getDrawBuffer(drawbuffer);
+ if (attachment)
+ {
+ GLenum componentType = attachment->getFormat().info->componentType;
+ const GLenum *end = validComponentTypes + validComponentTypeCount;
+ if (std::find(validComponentTypes, end, componentType) == end)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kNoDefinedClearConversion);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateRobustCompressedTexImageBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei imageSize,
+ GLsizei dataSize)
+{
+ if (!ValidateRobustEntryPoint(context, entryPoint, dataSize))
+ {
+ return false;
+ }
+
+ Buffer *pixelUnpackBuffer = context->getState().getTargetBuffer(BufferBinding::PixelUnpack);
+ if (pixelUnpackBuffer == nullptr)
+ {
+ if (dataSize < imageSize)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kCompressedDataSizeTooSmall);
+ }
+ }
+ return true;
+}
+
+bool ValidateGetBufferParameterBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding target,
+ GLenum pname,
+ bool pointerVersion,
+ GLsizei *numParams)
+{
+ if (numParams)
+ {
+ *numParams = 0;
+ }
+
+ if (!context->isValidBufferBinding(target))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBufferTypes);
+ return false;
+ }
+
+ const Buffer *buffer = context->getState().getTargetBuffer(target);
+ if (!buffer)
+ {
+ // A null buffer means that "0" is bound to the requested buffer target
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferNotBound);
+ return false;
+ }
+
+ const Extensions &extensions = context->getExtensions();
+
+ switch (pname)
+ {
+ case GL_BUFFER_USAGE:
+ case GL_BUFFER_SIZE:
+ break;
+
+ case GL_BUFFER_ACCESS_OES:
+ if (!extensions.mapbufferOES)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname);
+ return false;
+ }
+ break;
+
+ case GL_BUFFER_MAPPED:
+ static_assert(GL_BUFFER_MAPPED == GL_BUFFER_MAPPED_OES, "GL enums should be equal.");
+ if (context->getClientMajorVersion() < 3 && !extensions.mapbufferOES &&
+ !extensions.mapBufferRangeEXT)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname);
+ return false;
+ }
+ break;
+
+ case GL_BUFFER_MAP_POINTER:
+ if (!pointerVersion)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidMapPointerQuery);
+ return false;
+ }
+ break;
+
+ case GL_BUFFER_ACCESS_FLAGS:
+ case GL_BUFFER_MAP_OFFSET:
+ case GL_BUFFER_MAP_LENGTH:
+ if (context->getClientMajorVersion() < 3 && !extensions.mapBufferRangeEXT)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname);
+ return false;
+ }
+ break;
+
+ case GL_MEMORY_SIZE_ANGLE:
+ if (!context->getExtensions().memorySizeANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kExtensionNotEnabled);
+ return false;
+ }
+ break;
+
+ case GL_RESOURCE_INITIALIZED_ANGLE:
+ if (!context->getExtensions().robustResourceInitializationANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM,
+ kRobustResourceInitializationExtensionRequired);
+ return false;
+ }
+ break;
+
+ default:
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname);
+ return false;
+ }
+
+ // All buffer parameter queries return one value.
+ if (numParams)
+ {
+ *numParams = 1;
+ }
+
+ return true;
+}
+
+bool ValidateGetRenderbufferParameterivBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum pname,
+ GLsizei *length)
+{
+ if (length)
+ {
+ *length = 0;
+ }
+
+ if (target != GL_RENDERBUFFER)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidRenderbufferTarget);
+ return false;
+ }
+
+ Renderbuffer *renderbuffer = context->getState().getCurrentRenderbuffer();
+ if (renderbuffer == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kRenderbufferNotBound);
+ return false;
+ }
+
+ switch (pname)
+ {
+ case GL_RENDERBUFFER_WIDTH:
+ case GL_RENDERBUFFER_HEIGHT:
+ case GL_RENDERBUFFER_INTERNAL_FORMAT:
+ case GL_RENDERBUFFER_RED_SIZE:
+ case GL_RENDERBUFFER_GREEN_SIZE:
+ case GL_RENDERBUFFER_BLUE_SIZE:
+ case GL_RENDERBUFFER_ALPHA_SIZE:
+ case GL_RENDERBUFFER_DEPTH_SIZE:
+ case GL_RENDERBUFFER_STENCIL_SIZE:
+ break;
+
+ case GL_RENDERBUFFER_SAMPLES_ANGLE:
+ if (context->getClientMajorVersion() < 3 &&
+ !context->getExtensions().framebufferMultisampleANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kExtensionNotEnabled);
+ return false;
+ }
+ break;
+
+ case GL_MEMORY_SIZE_ANGLE:
+ if (!context->getExtensions().memorySizeANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kExtensionNotEnabled);
+ return false;
+ }
+ break;
+
+ case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
+ case GL_IMPLEMENTATION_COLOR_READ_TYPE:
+ if (!context->getExtensions().getImageANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kGetImageExtensionNotEnabled);
+ return false;
+ }
+ break;
+
+ case GL_RESOURCE_INITIALIZED_ANGLE:
+ if (!context->getExtensions().robustResourceInitializationANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM,
+ kRobustResourceInitializationExtensionRequired);
+ return false;
+ }
+ break;
+
+ default:
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname);
+ return false;
+ }
+
+ if (length)
+ {
+ *length = 1;
+ }
+ return true;
+}
+
+bool ValidateGetShaderivBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID shader,
+ GLenum pname,
+ GLsizei *length)
+{
+ if (length)
+ {
+ *length = 0;
+ }
+
+ if (context->isContextLost())
+ {
+ context->validationError(entryPoint, GL_CONTEXT_LOST, kContextLost);
+
+ if (context->getExtensions().parallelShaderCompileKHR && pname == GL_COMPLETION_STATUS_KHR)
+ {
+ // Generate an error but still return true, the context still needs to return a
+ // value in this case.
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ if (GetValidShader(context, entryPoint, shader) == nullptr)
+ {
+ return false;
+ }
+
+ switch (pname)
+ {
+ case GL_SHADER_TYPE:
+ case GL_DELETE_STATUS:
+ case GL_COMPILE_STATUS:
+ case GL_INFO_LOG_LENGTH:
+ case GL_SHADER_SOURCE_LENGTH:
+ break;
+
+ case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
+ if (!context->getExtensions().translatedShaderSourceANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kExtensionNotEnabled);
+ return false;
+ }
+ break;
+
+ case GL_COMPLETION_STATUS_KHR:
+ if (!context->getExtensions().parallelShaderCompileKHR)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+ break;
+
+ default:
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname);
+ return false;
+ }
+
+ if (length)
+ {
+ *length = 1;
+ }
+ return true;
+}
+
+bool ValidateGetTexParameterBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLenum pname,
+ GLsizei *length)
+{
+ if (length)
+ {
+ *length = 0;
+ }
+
+ if ((!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target)) ||
+ target == TextureType::Buffer)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget);
+ return false;
+ }
+
+ if (context->getTextureByType(target) == nullptr)
+ {
+ // Should only be possible for external textures
+ context->validationError(entryPoint, GL_INVALID_ENUM, kTextureNotBound);
+ return false;
+ }
+
+ if (context->getClientMajorVersion() == 1 && !IsValidGLES1TextureParameter(pname))
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname);
+ return false;
+ }
+
+ switch (pname)
+ {
+ case GL_TEXTURE_MAG_FILTER:
+ case GL_TEXTURE_MIN_FILTER:
+ case GL_TEXTURE_WRAP_S:
+ case GL_TEXTURE_WRAP_T:
+ break;
+
+ case GL_TEXTURE_USAGE_ANGLE:
+ if (!context->getExtensions().textureUsageANGLE)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname);
+ return false;
+ }
+ break;
+
+ case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+ if (!ValidateTextureMaxAnisotropyExtensionEnabled(context, entryPoint))
+ {
+ return false;
+ }
+ break;
+
+ case GL_TEXTURE_IMMUTABLE_FORMAT:
+ if (context->getClientMajorVersion() < 3 && !context->getExtensions().textureStorageEXT)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname);
+ return false;
+ }
+ break;
+
+ case GL_TEXTURE_WRAP_R:
+ case GL_TEXTURE_IMMUTABLE_LEVELS:
+ case GL_TEXTURE_SWIZZLE_R:
+ case GL_TEXTURE_SWIZZLE_G:
+ case GL_TEXTURE_SWIZZLE_B:
+ case GL_TEXTURE_SWIZZLE_A:
+ case GL_TEXTURE_BASE_LEVEL:
+ case GL_TEXTURE_MAX_LEVEL:
+ case GL_TEXTURE_MIN_LOD:
+ case GL_TEXTURE_MAX_LOD:
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kEnumRequiresGLES30);
+ return false;
+ }
+ break;
+
+ case GL_TEXTURE_COMPARE_MODE:
+ case GL_TEXTURE_COMPARE_FUNC:
+ if (context->getClientMajorVersion() < 3 && !context->getExtensions().shadowSamplersEXT)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname);
+ return false;
+ }
+ break;
+
+ case GL_TEXTURE_SRGB_DECODE_EXT:
+ if (!context->getExtensions().textureSRGBDecodeEXT)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname);
+ return false;
+ }
+ break;
+
+ case GL_DEPTH_STENCIL_TEXTURE_MODE:
+ case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE:
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kEnumRequiresGLES31);
+ return false;
+ }
+ break;
+
+ case GL_GENERATE_MIPMAP:
+ case GL_TEXTURE_CROP_RECT_OES:
+ // TODO(lfy@google.com): Restrict to GL_OES_draw_texture
+ // after GL_OES_draw_texture functionality implemented
+ if (context->getClientMajorVersion() > 1)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kGLES1Only);
+ return false;
+ }
+ break;
+
+ case GL_MEMORY_SIZE_ANGLE:
+ if (!context->getExtensions().memorySizeANGLE)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname);
+ return false;
+ }
+ break;
+
+ case GL_TEXTURE_BORDER_COLOR:
+ if (!context->getExtensions().textureBorderClampOES &&
+ context->getClientVersion() < ES_3_2)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kExtensionNotEnabled);
+ return false;
+ }
+ break;
+
+ case GL_TEXTURE_NATIVE_ID_ANGLE:
+ if (!context->getExtensions().textureExternalUpdateANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kExtensionNotEnabled);
+ return false;
+ }
+ break;
+
+ case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
+ case GL_IMPLEMENTATION_COLOR_READ_TYPE:
+ if (!context->getExtensions().getImageANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kGetImageExtensionNotEnabled);
+ return false;
+ }
+ break;
+
+ case GL_RESOURCE_INITIALIZED_ANGLE:
+ if (!context->getExtensions().robustResourceInitializationANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM,
+ kRobustResourceInitializationExtensionRequired);
+ return false;
+ }
+ break;
+
+ case GL_TEXTURE_PROTECTED_EXT:
+ if (!context->getExtensions().protectedTexturesEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM,
+ kProtectedTexturesExtensionRequired);
+ return false;
+ }
+ break;
+
+ case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
+ break;
+
+ default:
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname);
+ return false;
+ }
+
+ if (length)
+ {
+ *length = GetTexParameterCount(pname);
+ }
+ return true;
+}
+
+bool ValidateGetVertexAttribBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum pname,
+ GLsizei *length,
+ bool pointer,
+ bool pureIntegerEntryPoint)
+{
+ if (length)
+ {
+ *length = 0;
+ }
+
+ if (pureIntegerEntryPoint && context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ if (index >= static_cast<GLuint>(context->getCaps().maxVertexAttributes))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
+ return false;
+ }
+
+ if (pointer)
+ {
+ if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname);
+ return false;
+ }
+ }
+ else
+ {
+ switch (pname)
+ {
+ case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
+ case GL_VERTEX_ATTRIB_ARRAY_SIZE:
+ case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
+ case GL_VERTEX_ATTRIB_ARRAY_TYPE:
+ case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
+ case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
+ case GL_CURRENT_VERTEX_ATTRIB:
+ break;
+
+ case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
+ static_assert(
+ GL_VERTEX_ATTRIB_ARRAY_DIVISOR == GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE,
+ "ANGLE extension enums not equal to GL enums.");
+ if (context->getClientMajorVersion() < 3 &&
+ !context->getExtensions().instancedArraysAny())
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported,
+ pname);
+ return false;
+ }
+ break;
+
+ case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported,
+ pname);
+ return false;
+ }
+ break;
+
+ case GL_VERTEX_ATTRIB_BINDING:
+ case GL_VERTEX_ATTRIB_RELATIVE_OFFSET:
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kEnumRequiresGLES31);
+ return false;
+ }
+ break;
+
+ default:
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname);
+ return false;
+ }
+ }
+
+ if (length)
+ {
+ if (pname == GL_CURRENT_VERTEX_ATTRIB)
+ {
+ *length = 4;
+ }
+ else
+ {
+ *length = 1;
+ }
+ }
+
+ return true;
+}
+
+bool ValidatePixelPack(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum format,
+ GLenum type,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLsizei bufSize,
+ GLsizei *length,
+ const void *pixels)
+{
+ // Check for pixel pack buffer related API errors
+ Buffer *pixelPackBuffer = context->getState().getTargetBuffer(BufferBinding::PixelPack);
+ if (pixelPackBuffer != nullptr && pixelPackBuffer->isMapped())
+ {
+ // ...the buffer object's data store is currently mapped.
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferMapped);
+ return false;
+ }
+ if (pixelPackBuffer != nullptr &&
+ pixelPackBuffer->hasWebGLXFBBindingConflict(context->isWebGL()))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kPixelPackBufferBoundForTransformFeedback);
+ return false;
+ }
+
+ // .. the data would be packed to the buffer object such that the memory writes required
+ // would exceed the data store size.
+ const InternalFormat &formatInfo = GetInternalFormatInfo(format, type);
+ const Extents size(width, height, 1);
+ const auto &pack = context->getState().getPackState();
+
+ GLuint endByte = 0;
+ if (!formatInfo.computePackUnpackEndByte(type, size, pack, false, &endByte))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kIntegerOverflow);
+ return false;
+ }
+
+ if (bufSize >= 0)
+ {
+ if (pixelPackBuffer == nullptr && static_cast<size_t>(bufSize) < endByte)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInsufficientBufferSize);
+ return false;
+ }
+ }
+
+ if (pixelPackBuffer != nullptr)
+ {
+ CheckedNumeric<size_t> checkedEndByte(endByte);
+ 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->validationError(entryPoint, GL_INVALID_OPERATION, kParamOverflow);
+ return false;
+ }
+ }
+
+ if (pixelPackBuffer == nullptr && length != nullptr)
+ {
+ if (endByte > static_cast<size_t>(std::numeric_limits<GLsizei>::max()))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kIntegerOverflow);
+ return false;
+ }
+
+ *length = static_cast<GLsizei>(endByte);
+ }
+
+ if (context->isWebGL())
+ {
+ // WebGL 2.0 disallows the scenario:
+ // GL_PACK_SKIP_PIXELS + width > DataStoreWidth
+ // where:
+ // DataStoreWidth = (GL_PACK_ROW_LENGTH ? GL_PACK_ROW_LENGTH : width)
+ // Since these two pack parameters can only be set to non-zero values
+ // on WebGL 2.0 contexts, verify them for all WebGL contexts.
+ GLint dataStoreWidth = pack.rowLength ? pack.rowLength : width;
+ if (pack.skipPixels + width > dataStoreWidth)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kInvalidPackParametersForWebGL);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateReadPixelsBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLsizei *columns,
+ GLsizei *rows,
+ const void *pixels)
+{
+ if (length != nullptr)
+ {
+ *length = 0;
+ }
+ if (rows != nullptr)
+ {
+ *rows = 0;
+ }
+ if (columns != nullptr)
+ {
+ *columns = 0;
+ }
+
+ if (width < 0 || height < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeSize);
+ return false;
+ }
+
+ Framebuffer *readFramebuffer = context->getState().getReadFramebuffer();
+ ASSERT(readFramebuffer);
+
+ if (!ValidateFramebufferComplete(context, entryPoint, readFramebuffer))
+ {
+ return false;
+ }
+
+ // needIntrinsic = true. Treat renderToTexture textures as single sample since they will be
+ // resolved before reading.
+ if (!readFramebuffer->isDefault() &&
+ !ValidateFramebufferNotMultisampled(context, entryPoint, readFramebuffer, true))
+ {
+ return false;
+ }
+
+ if (readFramebuffer->getReadBufferState() == GL_NONE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kReadBufferNone);
+ return false;
+ }
+
+ const FramebufferAttachment *readBuffer = nullptr;
+ switch (format)
+ {
+ case GL_DEPTH_COMPONENT:
+ readBuffer = readFramebuffer->getDepthAttachment();
+ break;
+ case GL_STENCIL_INDEX_OES:
+ case GL_DEPTH_STENCIL_OES:
+ readBuffer = readFramebuffer->getStencilOrDepthStencilAttachment();
+ break;
+ default:
+ readBuffer = readFramebuffer->getReadColorAttachment();
+ break;
+ }
+
+ // OVR_multiview2, Revision 1:
+ // ReadPixels generates an INVALID_FRAMEBUFFER_OPERATION error if
+ // the number of views in the current read framebuffer is more than one.
+ if (readFramebuffer->readDisallowedByMultiview())
+ {
+ context->validationError(entryPoint, GL_INVALID_FRAMEBUFFER_OPERATION,
+ kMultiviewReadFramebuffer);
+ return false;
+ }
+
+ if (context->isWebGL())
+ {
+ // The ES 2.0 spec states that the format must be "among those defined in table 3.4,
+ // excluding formats LUMINANCE and LUMINANCE_ALPHA.". This requires validating the format
+ // and type before validating the combination of format and type. However, the
+ // dEQP-GLES3.functional.negative_api.buffer.read_pixels passes GL_LUMINANCE as a format and
+ // verifies that GL_INVALID_OPERATION is generated.
+ // TODO(geofflang): Update this check to be done in all/no cases once this is resolved in
+ // dEQP/WebGL.
+ if (!ValidReadPixelsFormatEnum(context, format))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat);
+ return false;
+ }
+
+ if (!ValidReadPixelsTypeEnum(context, type))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidType);
+ return false;
+ }
+ }
+
+ // WebGL 1.0 [Section 6.26] Reading From a Missing Attachment
+ // In OpenGL ES it is undefined what happens when an operation tries to read from a missing
+ // attachment and WebGL defines it to be an error. We do the check unconditionally as the
+ // situation is an application error that would lead to a crash in ANGLE.
+ if (readBuffer == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kMissingReadAttachment);
+ return false;
+ }
+
+ GLenum currentFormat = GL_NONE;
+ GLenum currentType = GL_NONE;
+
+ switch (format)
+ {
+ case GL_DEPTH_COMPONENT:
+ case GL_STENCIL_INDEX_OES:
+ case GL_DEPTH_STENCIL_OES:
+ // Only rely on ValidReadPixelsFormatType for depth/stencil formats
+ break;
+ default:
+ currentFormat = readFramebuffer->getImplementationColorReadFormat(context);
+ currentType = readFramebuffer->getImplementationColorReadType(context);
+ break;
+ }
+
+ bool validFormatTypeCombination =
+ ValidReadPixelsFormatType(context, readBuffer->getFormat().info, format, type);
+
+ if (!(currentFormat == format && currentType == type) && !validFormatTypeCombination)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
+ return false;
+ }
+
+ if (!ValidatePixelPack(context, entryPoint, format, type, x, y, width, height, bufSize, length,
+ pixels))
+ {
+ return false;
+ }
+
+ auto getClippedExtent = [](GLint start, GLsizei length, int bufferSize, GLsizei *outExtent) {
+ angle::CheckedNumeric<int> clippedExtent(length);
+ if (start < 0)
+ {
+ // "subtract" the area that is less than 0
+ clippedExtent += start;
+ }
+
+ angle::CheckedNumeric<int> readExtent = start;
+ readExtent += length;
+ if (!readExtent.IsValid())
+ {
+ return false;
+ }
+
+ if (readExtent.ValueOrDie() > bufferSize)
+ {
+ // Subtract the region to the right of the read buffer
+ clippedExtent -= (readExtent - bufferSize);
+ }
+
+ if (!clippedExtent.IsValid())
+ {
+ return false;
+ }
+
+ *outExtent = std::max<int>(clippedExtent.ValueOrDie(), 0);
+ return true;
+ };
+
+ GLsizei writtenColumns = 0;
+ if (!getClippedExtent(x, width, readBuffer->getSize().width, &writtenColumns))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kIntegerOverflow);
+ return false;
+ }
+
+ GLsizei writtenRows = 0;
+ if (!getClippedExtent(y, height, readBuffer->getSize().height, &writtenRows))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kIntegerOverflow);
+ return false;
+ }
+
+ if (columns != nullptr)
+ {
+ *columns = writtenColumns;
+ }
+
+ if (rows != nullptr)
+ {
+ *rows = writtenRows;
+ }
+
+ return true;
+}
+
+template <typename ParamType>
+bool ValidateTexParameterBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLenum pname,
+ GLsizei bufSize,
+ bool vectorParams,
+ const ParamType *params)
+{
+ if ((!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target)) ||
+ target == TextureType::Buffer)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget);
+ return false;
+ }
+
+ if (context->getTextureByType(target) == nullptr)
+ {
+ // Should only be possible for external textures
+ context->validationError(entryPoint, GL_INVALID_ENUM, kTextureNotBound);
+ return false;
+ }
+
+ const GLsizei minBufSize = GetTexParameterCount(pname);
+ if (bufSize >= 0 && bufSize < minBufSize)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInsufficientBufferSize);
+ return false;
+ }
+
+ if (context->getClientMajorVersion() == 1 && !IsValidGLES1TextureParameter(pname))
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname);
+ return false;
+ }
+
+ switch (pname)
+ {
+ case GL_TEXTURE_WRAP_R:
+ case GL_TEXTURE_SWIZZLE_R:
+ case GL_TEXTURE_SWIZZLE_G:
+ case GL_TEXTURE_SWIZZLE_B:
+ case GL_TEXTURE_SWIZZLE_A:
+ case GL_TEXTURE_BASE_LEVEL:
+ case GL_TEXTURE_MAX_LEVEL:
+ case GL_TEXTURE_COMPARE_MODE:
+ case GL_TEXTURE_COMPARE_FUNC:
+ case GL_TEXTURE_MIN_LOD:
+ case GL_TEXTURE_MAX_LOD:
+ if (context->getClientMajorVersion() < 3 &&
+ !(pname == GL_TEXTURE_WRAP_R && context->getExtensions().texture3DOES))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kES3Required);
+ return false;
+ }
+ if (target == TextureType::External &&
+ !context->getExtensions().EGLImageExternalEssl3OES)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname);
+ return false;
+ }
+ if (target == TextureType::VideoImage && !context->getExtensions().videoTextureWEBGL)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname);
+ }
+ break;
+
+ case GL_GENERATE_MIPMAP:
+ case GL_TEXTURE_CROP_RECT_OES:
+ if (context->getClientMajorVersion() > 1)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kGLES1Only);
+ return false;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (target == TextureType::_2DMultisample || target == TextureType::_2DMultisampleArray)
+ {
+ switch (pname)
+ {
+ case GL_TEXTURE_MIN_FILTER:
+ case GL_TEXTURE_MAG_FILTER:
+ case GL_TEXTURE_WRAP_S:
+ case GL_TEXTURE_WRAP_T:
+ case GL_TEXTURE_WRAP_R:
+ case GL_TEXTURE_MIN_LOD:
+ case GL_TEXTURE_MAX_LOD:
+ case GL_TEXTURE_COMPARE_MODE:
+ case GL_TEXTURE_COMPARE_FUNC:
+ case GL_TEXTURE_BORDER_COLOR:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname);
+ return false;
+ }
+ }
+
+ switch (pname)
+ {
+ case GL_TEXTURE_WRAP_S:
+ case GL_TEXTURE_WRAP_T:
+ case GL_TEXTURE_WRAP_R:
+ {
+ bool restrictedWrapModes = ((target == TextureType::External &&
+ !context->getExtensions().EGLImageExternalWrapModesEXT) ||
+ target == TextureType::Rectangle);
+ if (!ValidateTextureWrapModeValue(context, entryPoint, params, restrictedWrapModes))
+ {
+ return false;
+ }
+ }
+ break;
+
+ case GL_TEXTURE_MIN_FILTER:
+ {
+ bool restrictedMinFilter =
+ target == TextureType::External || target == TextureType::Rectangle;
+ if (!ValidateTextureMinFilterValue(context, entryPoint, params, restrictedMinFilter))
+ {
+ return false;
+ }
+ }
+ break;
+
+ case GL_TEXTURE_MAG_FILTER:
+ if (!ValidateTextureMagFilterValue(context, entryPoint, params))
+ {
+ return false;
+ }
+ break;
+
+ case GL_TEXTURE_USAGE_ANGLE:
+ if (!context->getExtensions().textureUsageANGLE)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname);
+ return false;
+ }
+
+ switch (ConvertToGLenum(params[0]))
+ {
+ case GL_NONE:
+ case GL_FRAMEBUFFER_ATTACHMENT_ANGLE:
+ break;
+
+ default:
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported,
+ pname);
+ return false;
+ }
+ break;
+
+ case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+ {
+ GLfloat paramValue = static_cast<GLfloat>(params[0]);
+ if (!ValidateTextureMaxAnisotropyValue(context, entryPoint, paramValue))
+ {
+ return false;
+ }
+ ASSERT(static_cast<ParamType>(paramValue) == params[0]);
+ }
+ break;
+
+ case GL_TEXTURE_MIN_LOD:
+ case GL_TEXTURE_MAX_LOD:
+ // any value is permissible
+ break;
+
+ case GL_TEXTURE_COMPARE_MODE:
+ if (!ValidateTextureCompareModeValue(context, entryPoint, params))
+ {
+ return false;
+ }
+ break;
+
+ case GL_TEXTURE_COMPARE_FUNC:
+ if (!ValidateTextureCompareFuncValue(context, entryPoint, params))
+ {
+ return false;
+ }
+ break;
+
+ case GL_TEXTURE_SWIZZLE_R:
+ case GL_TEXTURE_SWIZZLE_G:
+ case GL_TEXTURE_SWIZZLE_B:
+ case GL_TEXTURE_SWIZZLE_A:
+ switch (ConvertToGLenum(params[0]))
+ {
+ case GL_RED:
+ case GL_GREEN:
+ case GL_BLUE:
+ case GL_ALPHA:
+ case GL_ZERO:
+ case GL_ONE:
+ break;
+
+ default:
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported,
+ pname);
+ return false;
+ }
+ break;
+
+ case GL_TEXTURE_BASE_LEVEL:
+ if (ConvertToGLint(params[0]) < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kBaseLevelNegative);
+ return false;
+ }
+ if (target == TextureType::External && static_cast<GLuint>(params[0]) != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kBaseLevelNonZero);
+ return false;
+ }
+ if ((target == TextureType::_2DMultisample ||
+ target == TextureType::_2DMultisampleArray) &&
+ static_cast<GLuint>(params[0]) != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kBaseLevelNonZero);
+ return false;
+ }
+ if (target == TextureType::Rectangle && static_cast<GLuint>(params[0]) != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kBaseLevelNonZero);
+ return false;
+ }
+ break;
+
+ case GL_TEXTURE_MAX_LEVEL:
+ if (ConvertToGLint(params[0]) < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel);
+ return false;
+ }
+ break;
+
+ case GL_DEPTH_STENCIL_TEXTURE_MODE:
+ if (context->getClientVersion() < Version(3, 1))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kEnumRequiresGLES31);
+ return false;
+ }
+ switch (ConvertToGLenum(params[0]))
+ {
+ case GL_DEPTH_COMPONENT:
+ case GL_STENCIL_INDEX:
+ break;
+
+ default:
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported,
+ pname);
+ return false;
+ }
+ break;
+
+ case GL_TEXTURE_SRGB_DECODE_EXT:
+ if (!ValidateTextureSRGBDecodeValue(context, entryPoint, params))
+ {
+ return false;
+ }
+ break;
+
+ case GL_TEXTURE_FORMAT_SRGB_OVERRIDE_EXT:
+ if (!ValidateTextureSRGBOverrideValue(context, entryPoint, params))
+ {
+ return false;
+ }
+ break;
+
+ case GL_GENERATE_MIPMAP:
+ if (context->getClientMajorVersion() > 1)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kGLES1Only);
+ return false;
+ }
+ break;
+
+ case GL_TEXTURE_CROP_RECT_OES:
+ if (context->getClientMajorVersion() > 1)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kGLES1Only);
+ return false;
+ }
+ if (!vectorParams)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInsufficientBufferSize);
+ return false;
+ }
+ break;
+
+ case GL_TEXTURE_BORDER_COLOR:
+ if (!context->getExtensions().textureBorderClampOES &&
+ context->getClientVersion() < ES_3_2)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kExtensionNotEnabled);
+ return false;
+ }
+ if (!vectorParams)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInsufficientBufferSize);
+ return false;
+ }
+ break;
+
+ case GL_RESOURCE_INITIALIZED_ANGLE:
+ if (!context->getExtensions().robustResourceInitializationANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM,
+ kRobustResourceInitializationExtensionRequired);
+ return false;
+ }
+ break;
+
+ case GL_TEXTURE_PROTECTED_EXT:
+ if (!context->getExtensions().protectedTexturesEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM,
+ kProtectedTexturesExtensionRequired);
+ return false;
+ }
+ if (ConvertToBool(params[0]) != context->getState().hasProtectedContent())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ "Protected Texture must match Protected Context");
+ return false;
+ }
+ break;
+
+ default:
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname);
+ return false;
+ }
+
+ return true;
+}
+
+template bool ValidateTexParameterBase(const Context *,
+ angle::EntryPoint,
+ TextureType,
+ GLenum,
+ GLsizei,
+ bool,
+ const GLfloat *);
+template bool ValidateTexParameterBase(const Context *,
+ angle::EntryPoint,
+ TextureType,
+ GLenum,
+ GLsizei,
+ bool,
+ const GLint *);
+template bool ValidateTexParameterBase(const Context *,
+ angle::EntryPoint,
+ TextureType,
+ GLenum,
+ GLsizei,
+ bool,
+ const GLuint *);
+
+bool ValidateGetActiveUniformBlockivBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformBlockIndex uniformBlockIndex,
+ GLenum pname,
+ GLsizei *length)
+{
+ if (length)
+ {
+ *length = 0;
+ }
+
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ Program *programObject = GetValidProgram(context, entryPoint, program);
+ if (!programObject)
+ {
+ return false;
+ }
+
+ if (uniformBlockIndex.value >= programObject->getActiveUniformBlockCount())
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kIndexExceedsActiveUniformBlockCount);
+ return false;
+ }
+
+ switch (pname)
+ {
+ case GL_UNIFORM_BLOCK_BINDING:
+ case GL_UNIFORM_BLOCK_DATA_SIZE:
+ case GL_UNIFORM_BLOCK_NAME_LENGTH:
+ case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
+ case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
+ case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
+ case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
+ break;
+
+ default:
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname);
+ return false;
+ }
+
+ if (length)
+ {
+ if (pname == GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES)
+ {
+ const InterfaceBlock &uniformBlock =
+ programObject->getUniformBlockByIndex(uniformBlockIndex.value);
+ *length = static_cast<GLsizei>(uniformBlock.memberIndexes.size());
+ }
+ else
+ {
+ *length = 1;
+ }
+ }
+
+ return true;
+}
+
+template <typename ParamType>
+bool ValidateSamplerParameterBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID sampler,
+ GLenum pname,
+ GLsizei bufSize,
+ bool vectorParams,
+ const ParamType *params)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ if (!context->isSampler(sampler))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidSampler);
+ return false;
+ }
+
+ const GLsizei minBufSize = GetSamplerParameterCount(pname);
+ if (bufSize >= 0 && bufSize < minBufSize)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInsufficientBufferSize);
+ return false;
+ }
+
+ switch (pname)
+ {
+ case GL_TEXTURE_WRAP_S:
+ case GL_TEXTURE_WRAP_T:
+ case GL_TEXTURE_WRAP_R:
+ if (!ValidateTextureWrapModeValue(context, entryPoint, params, false))
+ {
+ return false;
+ }
+ break;
+
+ case GL_TEXTURE_MIN_FILTER:
+ if (!ValidateTextureMinFilterValue(context, entryPoint, params, false))
+ {
+ return false;
+ }
+ break;
+
+ case GL_TEXTURE_MAG_FILTER:
+ if (!ValidateTextureMagFilterValue(context, entryPoint, params))
+ {
+ return false;
+ }
+ break;
+
+ case GL_TEXTURE_MIN_LOD:
+ case GL_TEXTURE_MAX_LOD:
+ // any value is permissible
+ break;
+
+ case GL_TEXTURE_COMPARE_MODE:
+ if (!ValidateTextureCompareModeValue(context, entryPoint, params))
+ {
+ return false;
+ }
+ break;
+
+ case GL_TEXTURE_COMPARE_FUNC:
+ if (!ValidateTextureCompareFuncValue(context, entryPoint, params))
+ {
+ return false;
+ }
+ break;
+
+ case GL_TEXTURE_SRGB_DECODE_EXT:
+ if (!ValidateTextureSRGBDecodeValue(context, entryPoint, params))
+ {
+ return false;
+ }
+ break;
+
+ case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+ {
+ GLfloat paramValue = static_cast<GLfloat>(params[0]);
+ if (!ValidateTextureMaxAnisotropyValue(context, entryPoint, paramValue))
+ {
+ return false;
+ }
+ }
+ break;
+
+ case GL_TEXTURE_BORDER_COLOR:
+ if (!context->getExtensions().textureBorderClampOES &&
+ context->getClientVersion() < ES_3_2)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kExtensionNotEnabled);
+ return false;
+ }
+ if (!vectorParams)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInsufficientBufferSize);
+ return false;
+ }
+ break;
+
+ default:
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname);
+ return false;
+ }
+
+ return true;
+}
+
+template bool ValidateSamplerParameterBase(const Context *,
+ angle::EntryPoint,
+ SamplerID,
+ GLenum,
+ GLsizei,
+ bool,
+ const GLfloat *);
+template bool ValidateSamplerParameterBase(const Context *,
+ angle::EntryPoint,
+ SamplerID,
+ GLenum,
+ GLsizei,
+ bool,
+ const GLint *);
+template bool ValidateSamplerParameterBase(const Context *,
+ angle::EntryPoint,
+ SamplerID,
+ GLenum,
+ GLsizei,
+ bool,
+ const GLuint *);
+
+bool ValidateGetSamplerParameterBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID sampler,
+ GLenum pname,
+ GLsizei *length)
+{
+ if (length)
+ {
+ *length = 0;
+ }
+
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ if (!context->isSampler(sampler))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidSampler);
+ return false;
+ }
+
+ switch (pname)
+ {
+ case GL_TEXTURE_WRAP_S:
+ case GL_TEXTURE_WRAP_T:
+ case GL_TEXTURE_WRAP_R:
+ case GL_TEXTURE_MIN_FILTER:
+ case GL_TEXTURE_MAG_FILTER:
+ case GL_TEXTURE_MIN_LOD:
+ case GL_TEXTURE_MAX_LOD:
+ case GL_TEXTURE_COMPARE_MODE:
+ case GL_TEXTURE_COMPARE_FUNC:
+ break;
+
+ case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+ if (!ValidateTextureMaxAnisotropyExtensionEnabled(context, entryPoint))
+ {
+ return false;
+ }
+ break;
+
+ case GL_TEXTURE_SRGB_DECODE_EXT:
+ if (!context->getExtensions().textureSRGBDecodeEXT)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname);
+ return false;
+ }
+ break;
+
+ case GL_TEXTURE_BORDER_COLOR:
+ if (!context->getExtensions().textureBorderClampOES &&
+ context->getClientVersion() < ES_3_2)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kExtensionNotEnabled);
+ return false;
+ }
+ break;
+
+ default:
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname);
+ return false;
+ }
+
+ if (length)
+ {
+ *length = GetSamplerParameterCount(pname);
+ }
+ return true;
+}
+
+bool ValidateGetInternalFormativBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum internalformat,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *numParams)
+{
+ if (numParams)
+ {
+ *numParams = 0;
+ }
+
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
+ if (!formatCaps.renderbuffer)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kFormatNotRenderable);
+ return false;
+ }
+
+ switch (target)
+ {
+ case GL_RENDERBUFFER:
+ break;
+
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ if (context->getClientVersion() < ES_3_1 &&
+ !context->getExtensions().textureMultisampleANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM,
+ kMultisampleTextureExtensionOrES31Required);
+ return false;
+ }
+ break;
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES:
+ if (!context->getExtensions().textureStorageMultisample2dArrayOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM,
+ kMultisampleArrayExtensionRequired);
+ return false;
+ }
+ break;
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTarget);
+ return false;
+ }
+
+ if (bufSize < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInsufficientBufferSize);
+ return false;
+ }
+
+ GLsizei maxWriteParams = 0;
+ switch (pname)
+ {
+ case GL_NUM_SAMPLE_COUNTS:
+ maxWriteParams = 1;
+ break;
+
+ case GL_SAMPLES:
+ maxWriteParams = static_cast<GLsizei>(formatCaps.sampleCounts.size());
+ break;
+
+ default:
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname);
+ return false;
+ }
+
+ if (numParams)
+ {
+ // glGetInternalFormativ will not overflow bufSize
+ *numParams = std::min(bufSize, maxWriteParams);
+ }
+
+ return true;
+}
+
+bool ValidateFramebufferNotMultisampled(const Context *context,
+ angle::EntryPoint entryPoint,
+ const Framebuffer *framebuffer,
+ bool checkReadBufferResourceSamples)
+{
+ int samples = checkReadBufferResourceSamples
+ ? framebuffer->getReadBufferResourceSamples(context)
+ : framebuffer->getSamples(context);
+ if (samples != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kInvalidMultisampledFramebufferOperation);
+ return false;
+ }
+ return true;
+}
+
+bool ValidateMultitextureUnit(const Context *context, angle::EntryPoint entryPoint, GLenum texture)
+{
+ if (texture < GL_TEXTURE0 || texture >= GL_TEXTURE0 + context->getCaps().maxMultitextureUnits)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidMultitextureUnit);
+ return false;
+ }
+ return true;
+}
+
+bool ValidateTexStorageMultisample(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLsizei samples,
+ GLint internalFormat,
+ GLsizei width,
+ GLsizei height)
+{
+ const Caps &caps = context->getCaps();
+ if (width > caps.max2DTextureSize || height > caps.max2DTextureSize)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kTextureWidthOrHeightOutOfRange);
+ return false;
+ }
+
+ if (samples == 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kSamplesZero);
+ return false;
+ }
+
+ const TextureCaps &formatCaps = context->getTextureCaps().get(internalFormat);
+ if (!formatCaps.textureAttachment)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kRenderableInternalFormat);
+ return false;
+ }
+
+ // The ES3.1 spec(section 8.8) states that an INVALID_ENUM error is generated if internalformat
+ // is one of the unsized base internalformats listed in table 8.11.
+ const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalFormat);
+ if (formatInfo.internalFormat == GL_NONE)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kUnsizedInternalFormatUnsupported);
+ return false;
+ }
+
+ if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kSamplesOutOfRange);
+ return false;
+ }
+
+ Texture *texture = context->getTextureByType(target);
+ if (!texture || texture->id().value == 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kZeroBoundToTarget);
+ return false;
+ }
+
+ if (texture->getImmutableFormat())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kImmutableTextureBound);
+ return false;
+ }
+ return true;
+}
+
+bool ValidateTexStorage2DMultisampleBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLsizei samples,
+ GLint internalFormat,
+ GLsizei width,
+ GLsizei height)
+{
+ if (target != TextureType::_2DMultisample)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTarget);
+ return false;
+ }
+
+ if (width < 1 || height < 1)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kTextureSizeTooSmall);
+ return false;
+ }
+
+ return ValidateTexStorageMultisample(context, entryPoint, target, samples, internalFormat,
+ width, height);
+}
+
+bool ValidateGetTexLevelParameterBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLenum pname,
+ GLsizei *length)
+{
+
+ if (length)
+ {
+ *length = 0;
+ }
+
+ TextureType type = TextureTargetToType(target);
+
+ if (!ValidTexLevelDestinationTarget(context, type))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget);
+ return false;
+ }
+
+ if (context->getTextureByType(type) == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kTextureNotBound);
+ return false;
+ }
+
+ if (!ValidMipLevel(context, type, level))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel);
+ return false;
+ }
+
+ switch (pname)
+ {
+ case GL_TEXTURE_RED_TYPE:
+ case GL_TEXTURE_GREEN_TYPE:
+ case GL_TEXTURE_BLUE_TYPE:
+ case GL_TEXTURE_ALPHA_TYPE:
+ case GL_TEXTURE_DEPTH_TYPE:
+ case GL_TEXTURE_RED_SIZE:
+ case GL_TEXTURE_GREEN_SIZE:
+ case GL_TEXTURE_BLUE_SIZE:
+ case GL_TEXTURE_ALPHA_SIZE:
+ case GL_TEXTURE_DEPTH_SIZE:
+ case GL_TEXTURE_STENCIL_SIZE:
+ case GL_TEXTURE_SHARED_SIZE:
+ case GL_TEXTURE_INTERNAL_FORMAT:
+ case GL_TEXTURE_WIDTH:
+ case GL_TEXTURE_HEIGHT:
+ case GL_TEXTURE_DEPTH:
+ case GL_TEXTURE_SAMPLES:
+ case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
+ case GL_TEXTURE_COMPRESSED:
+ break;
+
+ case GL_RESOURCE_INITIALIZED_ANGLE:
+ if (!context->getExtensions().robustResourceInitializationANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM,
+ kRobustResourceInitializationExtensionRequired);
+ return false;
+ }
+ break;
+
+ case GL_TEXTURE_BUFFER_DATA_STORE_BINDING:
+ case GL_TEXTURE_BUFFER_OFFSET:
+ case GL_TEXTURE_BUFFER_SIZE:
+ if (context->getClientVersion() < Version(3, 2) &&
+ !context->getExtensions().textureBufferAny())
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM,
+ kTextureBufferExtensionNotAvailable);
+ return false;
+ }
+ break;
+
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname);
+ return false;
+ }
+
+ if (length)
+ {
+ *length = 1;
+ }
+ return true;
+}
+
+bool ValidateGetMultisamplefvBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLuint index,
+ const GLfloat *val)
+{
+ if (pname != GL_SAMPLE_POSITION)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname);
+ return false;
+ }
+
+ Framebuffer *framebuffer = context->getState().getDrawFramebuffer();
+ GLint samples = framebuffer->getSamples(context);
+
+ if (index >= static_cast<GLuint>(samples))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsSamples);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateSampleMaskiBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint maskNumber,
+ GLbitfield mask)
+{
+ if (maskNumber >= static_cast<GLuint>(context->getCaps().maxSampleMaskWords))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidSampleMaskNumber);
+ return false;
+ }
+
+ return true;
+}
+
+void RecordDrawAttribsError(const Context *context, angle::EntryPoint entryPoint)
+{
+ // An overflow can happen when adding the offset. Check against a special constant.
+ if (context->getStateCache().getNonInstancedVertexElementLimit() ==
+ VertexAttribute::kIntegerOverflow ||
+ context->getStateCache().getInstancedVertexElementLimit() ==
+ VertexAttribute::kIntegerOverflow)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kIntegerOverflow);
+ }
+ else
+ {
+ // [OpenGL ES 3.0.2] section 2.9.4 page 40:
+ // We can return INVALID_OPERATION if our buffer does not have enough backing data.
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInsufficientVertexBufferSize);
+ }
+}
+
+bool ValidateLoseContextCHROMIUM(const Context *context,
+ angle::EntryPoint entryPoint,
+ GraphicsResetStatus current,
+ GraphicsResetStatus other)
+{
+ if (!context->getExtensions().loseContextCHROMIUM)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ switch (current)
+ {
+ case GraphicsResetStatus::GuiltyContextReset:
+ case GraphicsResetStatus::InnocentContextReset:
+ case GraphicsResetStatus::UnknownContextReset:
+ break;
+
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidResetStatus);
+ }
+
+ switch (other)
+ {
+ case GraphicsResetStatus::GuiltyContextReset:
+ case GraphicsResetStatus::InnocentContextReset:
+ case GraphicsResetStatus::UnknownContextReset:
+ break;
+
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidResetStatus);
+ }
+
+ return true;
+}
+
+// GL_ANGLE_texture_storage_external
+bool ValidateTexImage2DExternalANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLenum format,
+ GLenum type)
+{
+ if (!context->getExtensions().textureExternalUpdateANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ if (!ValidTexture2DDestinationTarget(context, target) &&
+ !ValidTextureExternalTarget(context, target))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget);
+ return false;
+ }
+
+ if (context->getClientMajorVersion() <= 2)
+ {
+ if (!ValidateES2TexImageParametersBase(context, entryPoint, target, level, internalformat,
+ false, false, 0, 0, width, height, border, format,
+ type, -1, nullptr))
+ {
+ return false;
+ }
+ }
+ else
+ {
+ if (!ValidateES3TexImageParametersBase(context, entryPoint, target, level, internalformat,
+ false, false, 0, 0, 0, width, height, 1, border,
+ format, type, -1, nullptr))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateInvalidateTextureANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target)
+{
+ if (!context->getExtensions().textureExternalUpdateANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ if (!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateProgramExecutableXFBBuffersPresent(const Context *context,
+ const ProgramExecutable *programExecutable)
+{
+ size_t programXfbCount = programExecutable->getTransformFeedbackBufferCount();
+ const TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
+ for (size_t programXfbIndex = 0; programXfbIndex < programXfbCount; ++programXfbIndex)
+ {
+ const OffsetBindingPointer<Buffer> &buffer =
+ transformFeedback->getIndexedBuffer(programXfbIndex);
+ if (!buffer.get())
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateLogicOpCommon(const Context *context,
+ angle::EntryPoint entryPoint,
+ LogicalOperation opcodePacked)
+{
+ switch (opcodePacked)
+ {
+ case LogicalOperation::And:
+ case LogicalOperation::AndInverted:
+ case LogicalOperation::AndReverse:
+ case LogicalOperation::Clear:
+ case LogicalOperation::Copy:
+ case LogicalOperation::CopyInverted:
+ case LogicalOperation::Equiv:
+ case LogicalOperation::Invert:
+ case LogicalOperation::Nand:
+ case LogicalOperation::Noop:
+ case LogicalOperation::Nor:
+ case LogicalOperation::Or:
+ case LogicalOperation::OrInverted:
+ case LogicalOperation::OrReverse:
+ case LogicalOperation::Set:
+ case LogicalOperation::Xor:
+ return true;
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidLogicOp);
+ return false;
+ }
+}
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/validationES.h b/gfx/angle/checkout/src/libANGLE/validationES.h
new file mode 100644
index 0000000000..685e1e505b
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/validationES.h
@@ -0,0 +1,1272 @@
+//
+// Copyright 2013 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.
+//
+
+// validationES.h: Validation functions for generic OpenGL ES entry point parameters
+
+#ifndef LIBANGLE_VALIDATION_ES_H_
+#define LIBANGLE_VALIDATION_ES_H_
+
+#include "common/PackedEnums.h"
+#include "common/mathutil.h"
+#include "common/utilities.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/ErrorStrings.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/VertexArray.h"
+
+#include <GLES2/gl2.h>
+#include <GLES3/gl3.h>
+#include <GLES3/gl31.h>
+
+namespace egl
+{
+class Display;
+class Image;
+} // namespace egl
+
+namespace gl
+{
+class Context;
+struct Format;
+class Framebuffer;
+struct LinkedUniform;
+class Program;
+class Shader;
+
+void SetRobustLengthParam(const GLsizei *length, GLsizei value);
+bool ValidTextureTarget(const Context *context, TextureType type);
+bool ValidTexture2DTarget(const Context *context, TextureType type);
+bool ValidTexture3DTarget(const Context *context, TextureType target);
+bool ValidTextureExternalTarget(const Context *context, TextureType target);
+bool ValidTextureExternalTarget(const Context *context, TextureTarget target);
+bool ValidTexture2DDestinationTarget(const Context *context, TextureTarget target);
+bool ValidTexture3DDestinationTarget(const Context *context, TextureTarget target);
+bool ValidTexLevelDestinationTarget(const Context *context, TextureType type);
+bool ValidFramebufferTarget(const Context *context, GLenum target);
+bool ValidMipLevel(const Context *context, TextureType type, GLint level);
+bool ValidImageSizeParameters(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLint level,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ bool isSubImage);
+bool ValidCompressedImageSize(const Context *context,
+ GLenum internalFormat,
+ GLint level,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth);
+bool ValidCompressedSubImageSize(const Context *context,
+ GLenum internalFormat,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ size_t textureWidth,
+ size_t textureHeight,
+ size_t textureDepth);
+bool ValidImageDataSize(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType texType,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ const void *pixels,
+ GLsizei imageSize);
+
+bool ValidQueryType(const Context *context, QueryType queryType);
+
+bool ValidateWebGLVertexAttribPointer(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexAttribType type,
+ GLboolean normalized,
+ GLsizei stride,
+ const void *ptr,
+ bool pureInteger);
+
+// Returns valid program if id is a valid program name
+// Errors INVALID_OPERATION if valid shader is given and returns NULL
+// Errors INVALID_VALUE otherwise and returns NULL
+Program *GetValidProgram(const Context *context, angle::EntryPoint entryPoint, ShaderProgramID id);
+
+// Returns valid shader if id is a valid shader name
+// Errors INVALID_OPERATION if valid program is given and returns NULL
+// Errors INVALID_VALUE otherwise and returns NULL
+Shader *GetValidShader(const Context *context, angle::EntryPoint entryPoint, ShaderProgramID id);
+
+bool ValidateAttachmentTarget(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum attachment);
+
+bool ValidateBlitFramebufferParameters(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint srcX0,
+ GLint srcY0,
+ GLint srcX1,
+ GLint srcY1,
+ GLint dstX0,
+ GLint dstY0,
+ GLint dstX1,
+ GLint dstY1,
+ GLbitfield mask,
+ GLenum filter);
+
+bool ValidateBindFramebufferBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ FramebufferID framebuffer);
+bool ValidateBindRenderbufferBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ RenderbufferID renderbuffer);
+bool ValidateFramebufferParameteriBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum pname,
+ GLint param);
+bool ValidateFramebufferRenderbufferBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ GLenum renderbuffertarget,
+ RenderbufferID renderbuffer);
+bool ValidateFramebufferTextureBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ TextureID texture,
+ GLint level);
+bool ValidateGenerateMipmapBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target);
+
+bool ValidateRenderbufferStorageParametersBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height);
+
+bool ValidatePixelPack(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum format,
+ GLenum type,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLsizei bufSize,
+ GLsizei *length,
+ const void *pixels);
+
+bool ValidateReadPixelsBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLsizei *columns,
+ GLsizei *rows,
+ const void *pixels);
+bool ValidateReadPixelsRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLsizei *columns,
+ const GLsizei *rows,
+ const void *pixels);
+bool ValidateReadnPixelsEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *pixels);
+bool ValidateReadnPixelsRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLsizei *columns,
+ const GLsizei *rows,
+ const void *data);
+
+bool ValidateGenQueriesEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const QueryID *ids);
+bool ValidateDeleteQueriesEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const QueryID *ids);
+bool ValidateIsQueryEXT(const Context *context, angle::EntryPoint entryPoint, QueryID id);
+bool ValidateBeginQueryBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryType target,
+ QueryID id);
+bool ValidateBeginQueryEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryType target,
+ QueryID id);
+bool ValidateEndQueryBase(const Context *context, angle::EntryPoint entryPoint, QueryType target);
+bool ValidateEndQueryEXT(const Context *context, angle::EntryPoint entryPoint, QueryType target);
+bool ValidateQueryCounterEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID id,
+ QueryType target);
+bool ValidateGetQueryivBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryType target,
+ GLenum pname,
+ GLsizei *numParams);
+bool ValidateGetQueryivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryType target,
+ GLenum pname,
+ const GLint *params);
+bool ValidateGetQueryivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryType target,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params);
+bool ValidateGetQueryObjectValueBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID id,
+ GLenum pname,
+ GLsizei *numParams);
+bool ValidateGetQueryObjectivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID id,
+ GLenum pname,
+ const GLint *params);
+bool ValidateGetQueryObjectivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID id,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params);
+bool ValidateGetQueryObjectuivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID id,
+ GLenum pname,
+ const GLuint *params);
+bool ValidateGetQueryObjectuivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID id,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLuint *params);
+bool ValidateGetQueryObjecti64vEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID id,
+ GLenum pname,
+ GLint64 *params);
+bool ValidateGetQueryObjecti64vRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID id,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ GLint64 *params);
+bool ValidateGetQueryObjectui64vEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID id,
+ GLenum pname,
+ GLuint64 *params);
+bool ValidateGetQueryObjectui64vRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID id,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ GLuint64 *params);
+
+bool ValidateUniformCommonBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ const Program *program,
+ UniformLocation location,
+ GLsizei count,
+ const LinkedUniform **uniformOut);
+bool ValidateUniform1ivValue(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum uniformType,
+ GLsizei count,
+ const GLint *value);
+
+ANGLE_INLINE bool ValidateUniformValue(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum valueType,
+ GLenum uniformType)
+{
+ // Check that the value type is compatible with uniform type.
+ // Do the cheaper test first, for a little extra speed.
+ if (valueType != uniformType && VariableBoolVectorType(valueType) != uniformType)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, err::kUniformSizeMismatch);
+ return false;
+ }
+ return true;
+}
+
+bool ValidateUniformMatrixValue(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum valueType,
+ GLenum uniformType);
+bool ValidateUniform(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum uniformType,
+ UniformLocation location,
+ GLsizei count);
+bool ValidateUniformMatrix(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum matrixType,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose);
+bool ValidateGetBooleanvRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLboolean *params);
+bool ValidateGetFloatvRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLfloat *params);
+bool ValidateStateQuery(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLenum *nativeType,
+ unsigned int *numParams);
+bool ValidateGetIntegervRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *data);
+bool ValidateGetInteger64vRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ GLint64 *data);
+bool ValidateRobustStateQuery(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLsizei bufSize,
+ GLenum *nativeType,
+ unsigned int *numParams);
+
+bool ValidateCopyImageSubDataBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint srcName,
+ GLenum srcTarget,
+ GLint srcLevel,
+ GLint srcX,
+ GLint srcY,
+ GLint srcZ,
+ GLuint dstName,
+ GLenum dstTarget,
+ GLint dstLevel,
+ GLint dstX,
+ GLint dstY,
+ GLint dstZ,
+ GLsizei srcWidth,
+ GLsizei srcHeight,
+ GLsizei srcDepth);
+
+bool ValidateCopyTexImageParametersBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLenum internalformat,
+ bool isSubImage,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ Format *textureFormatOut);
+
+void RecordDrawModeError(const Context *context, angle::EntryPoint entryPoint, PrimitiveMode mode);
+const char *ValidateDrawElementsStates(const Context *context);
+
+ANGLE_INLINE bool ValidateDrawBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode)
+{
+ intptr_t drawStatesError = context->getStateCache().getBasicDrawStatesError(context);
+ if (drawStatesError)
+ {
+ const char *errorMessage = reinterpret_cast<const char *>(drawStatesError);
+
+ // All errors from ValidateDrawStates should return INVALID_OPERATION except Framebuffer
+ // Incomplete.
+ bool isFramebufferIncomplete = strcmp(errorMessage, err::kDrawFramebufferIncomplete) == 0;
+ GLenum errorCode =
+ isFramebufferIncomplete ? GL_INVALID_FRAMEBUFFER_OPERATION : GL_INVALID_OPERATION;
+ context->validationError(entryPoint, errorCode, errorMessage);
+ return false;
+ }
+
+ if (!context->getStateCache().isValidDrawMode(mode))
+ {
+ RecordDrawModeError(context, entryPoint, mode);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateDrawArraysInstancedBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLint first,
+ GLsizei count,
+ GLsizei primcount);
+bool ValidateDrawArraysInstancedANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLint first,
+ GLsizei count,
+ GLsizei primcount);
+bool ValidateDrawArraysInstancedEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLint first,
+ GLsizei count,
+ GLsizei primcount);
+
+bool ValidateDrawElementsInstancedBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLsizei count,
+ DrawElementsType type,
+ const void *indices,
+ GLsizei primcount);
+bool ValidateDrawElementsInstancedANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLsizei count,
+ DrawElementsType type,
+ const void *indices,
+ GLsizei primcount);
+bool ValidateDrawElementsInstancedEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLsizei count,
+ DrawElementsType type,
+ const void *indices,
+ GLsizei primcount);
+
+bool ValidateDrawInstancedANGLE(const Context *context, angle::EntryPoint entryPoint);
+
+bool ValidateGetUniformBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location);
+bool ValidateSizedGetUniform(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei bufSize,
+ GLsizei *length);
+bool ValidateGetnUniformfvEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei bufSize,
+ const GLfloat *params);
+bool ValidateGetnUniformfvRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLfloat *params);
+bool ValidateGetnUniformivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei bufSize,
+ const GLint *params);
+bool ValidateGetnUniformivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params);
+bool ValidateGetnUniformuivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLuint *params);
+bool ValidateGetUniformfvRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLfloat *params);
+bool ValidateGetUniformivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params);
+bool ValidateGetUniformuivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLuint *params);
+
+bool ValidateDiscardFramebufferBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLsizei numAttachments,
+ const GLenum *attachments,
+ bool defaultFramebuffer);
+
+bool ValidateInsertEventMarkerEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei length,
+ const char *marker);
+bool ValidatePushGroupMarkerEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei length,
+ const char *marker);
+bool ValidateEGLImageObject(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType type,
+ GLeglImageOES image);
+bool ValidateEGLImageTargetTexture2DOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType type,
+ GLeglImageOES image);
+bool ValidateEGLImageTargetRenderbufferStorageOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLeglImageOES image);
+
+bool ValidateProgramBinaryBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLenum binaryFormat,
+ const void *binary,
+ GLint length);
+bool ValidateGetProgramBinaryBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLenum *binaryFormat,
+ const void *binary);
+
+bool ValidateDrawBuffersBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const GLenum *bufs);
+
+bool ValidateGetBufferPointervBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding target,
+ GLenum pname,
+ GLsizei *length,
+ void *const *params);
+bool ValidateUnmapBufferBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding target);
+bool ValidateMapBufferRangeBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding target,
+ GLintptr offset,
+ GLsizeiptr length,
+ GLbitfield access);
+bool ValidateFlushMappedBufferRangeBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding target,
+ GLintptr offset,
+ GLsizeiptr length);
+
+bool ValidateGenOrDelete(const Context *context, angle::EntryPoint entryPoint, GLint n);
+
+bool ValidateRobustEntryPoint(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei bufSize);
+bool ValidateRobustBufferSize(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei bufSize,
+ GLsizei numParams);
+
+bool ValidateGetFramebufferAttachmentParameterivBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ GLenum pname,
+ GLsizei *numParams);
+
+bool ValidateGetFramebufferParameterivBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum pname,
+ const GLint *params);
+
+bool ValidateGetBufferParameterBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding target,
+ GLenum pname,
+ bool pointerVersion,
+ GLsizei *numParams);
+
+bool ValidateGetProgramivBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLenum pname,
+ GLsizei *numParams);
+
+bool ValidateGetRenderbufferParameterivBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum pname,
+ GLsizei *length);
+
+bool ValidateGetShaderivBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID shader,
+ GLenum pname,
+ GLsizei *length);
+
+bool ValidateGetTexParameterBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLenum pname,
+ GLsizei *length);
+
+template <typename ParamType>
+bool ValidateTexParameterBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLenum pname,
+ GLsizei bufSize,
+ bool vectorParams,
+ const ParamType *params);
+
+bool ValidateGetVertexAttribBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum pname,
+ GLsizei *length,
+ bool pointer,
+ bool pureIntegerEntryPoint);
+
+ANGLE_INLINE bool ValidateVertexFormat(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLint size,
+ VertexAttribTypeCase validation)
+{
+ const Caps &caps = context->getCaps();
+ if (index >= static_cast<GLuint>(caps.maxVertexAttributes))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ err::kIndexExceedsMaxVertexAttribute);
+ return false;
+ }
+
+ switch (validation)
+ {
+ case VertexAttribTypeCase::Invalid:
+ context->validationError(entryPoint, GL_INVALID_ENUM, err::kInvalidType);
+ return false;
+ case VertexAttribTypeCase::Valid:
+ if (size < 1 || size > 4)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, err::kInvalidVertexAttrSize);
+ return false;
+ }
+ break;
+ case VertexAttribTypeCase::ValidSize4Only:
+ if (size != 4)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ err::kInvalidVertexAttribSize2101010);
+ return false;
+ }
+ break;
+ case VertexAttribTypeCase::ValidSize3or4:
+ if (size != 3 && size != 4)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ err::kInvalidVertexAttribSize1010102);
+ return false;
+ }
+ break;
+ }
+
+ return true;
+}
+
+// Note: These byte, short, and int types are all converted to float for the shader.
+ANGLE_INLINE bool ValidateFloatVertexFormat(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLint size,
+ VertexAttribType type)
+{
+ return ValidateVertexFormat(context, entryPoint, index, size,
+ context->getStateCache().getVertexAttribTypeValidation(type));
+}
+
+ANGLE_INLINE bool ValidateIntegerVertexFormat(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLint size,
+ VertexAttribType type)
+{
+ return ValidateVertexFormat(
+ context, entryPoint, index, size,
+ context->getStateCache().getIntegerVertexAttribTypeValidation(type));
+}
+
+bool ValidateWebGLFramebufferAttachmentClearType(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint drawbuffer,
+ const GLenum *validComponentTypes,
+ size_t validComponentTypeCount);
+
+bool ValidateRobustCompressedTexImageBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei imageSize,
+ GLsizei dataSize);
+
+bool ValidateVertexAttribIndex(const Context *context, angle::EntryPoint entryPoint, GLuint index);
+
+bool ValidateGetActiveUniformBlockivBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformBlockIndex uniformBlockIndex,
+ GLenum pname,
+ GLsizei *length);
+
+bool ValidateGetSamplerParameterBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID sampler,
+ GLenum pname,
+ GLsizei *length);
+
+template <typename ParamType>
+bool ValidateSamplerParameterBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID sampler,
+ GLenum pname,
+ GLsizei bufSize,
+ bool vectorParams,
+ const ParamType *params);
+
+bool ValidateGetInternalFormativBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum internalformat,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *numParams);
+
+bool ValidateFramebufferNotMultisampled(const Context *context,
+ angle::EntryPoint entryPoint,
+ const Framebuffer *framebuffer,
+ bool checkReadBufferResourceSamples);
+
+bool ValidateMultitextureUnit(const Context *context, angle::EntryPoint entryPoint, GLenum texture);
+
+bool ValidateTransformFeedbackPrimitiveMode(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode transformFeedbackPrimitiveMode,
+ PrimitiveMode renderPrimitiveMode);
+
+// Common validation for 2D and 3D variants of TexStorage*Multisample.
+bool ValidateTexStorageMultisample(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLsizei samples,
+ GLint internalFormat,
+ GLsizei width,
+ GLsizei height);
+
+bool ValidateTexStorage2DMultisampleBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLsizei samples,
+ GLint internalFormat,
+ GLsizei width,
+ GLsizei height);
+
+bool ValidateGetTexLevelParameterBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLenum pname,
+ GLsizei *length);
+
+bool ValidateMapBufferBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding target);
+bool ValidateIndexedStateQuery(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLuint index,
+ GLsizei *length);
+bool ValidateES3TexImage2DParameters(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLenum internalformat,
+ bool isCompressed,
+ bool isSubImage,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ GLsizei imageSize,
+ const void *pixels);
+bool ValidateES3CopyTexImage2DParameters(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLenum internalformat,
+ bool isSubImage,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLint border);
+bool ValidateES3TexStorageParametersBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth);
+bool ValidateES3TexStorage2DParameters(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth);
+bool ValidateES3TexStorage3DParameters(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth);
+
+bool ValidateGetMultisamplefvBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLuint index,
+ const GLfloat *val);
+bool ValidateSampleMaskiBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint maskNumber,
+ GLbitfield mask);
+
+bool ValidateProgramExecutableXFBBuffersPresent(const Context *context,
+ const ProgramExecutable *programExecutable);
+
+// We should check with Khronos if returning INVALID_FRAMEBUFFER_OPERATION is OK when querying
+// implementation format info for incomplete framebuffers. It seems like these queries are
+// incongruent with the other errors.
+// Inlined for speed.
+template <GLenum ErrorCode = GL_INVALID_FRAMEBUFFER_OPERATION>
+ANGLE_INLINE bool ValidateFramebufferComplete(const Context *context,
+ angle::EntryPoint entryPoint,
+ const Framebuffer *framebuffer)
+{
+ const FramebufferStatus &framebufferStatus = framebuffer->checkStatus(context);
+ if (!framebufferStatus.isComplete())
+ {
+ ASSERT(framebufferStatus.reason != nullptr);
+ context->validationError(entryPoint, ErrorCode, framebufferStatus.reason);
+ return false;
+ }
+
+ return true;
+}
+
+const char *ValidateProgramPipelineDrawStates(const State &state,
+ const Extensions &extensions,
+ ProgramPipeline *programPipeline);
+const char *ValidateProgramPipelineAttachedPrograms(ProgramPipeline *programPipeline);
+const char *ValidateDrawStates(const Context *context);
+const char *ValidateProgramPipeline(const Context *context);
+
+void RecordDrawAttribsError(const Context *context, angle::EntryPoint entryPoint);
+
+ANGLE_INLINE bool ValidateDrawAttribs(const Context *context,
+ angle::EntryPoint entryPoint,
+ int64_t maxVertex)
+{
+ if (maxVertex > context->getStateCache().getNonInstancedVertexElementLimit())
+ {
+ RecordDrawAttribsError(context, entryPoint);
+ return false;
+ }
+
+ return true;
+}
+
+ANGLE_INLINE bool ValidateDrawArraysAttribs(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint first,
+ GLsizei count)
+{
+ if (!context->isBufferAccessValidationEnabled())
+ {
+ return true;
+ }
+
+ // Check the computation of maxVertex doesn't overflow.
+ // - first < 0 has been checked as an error condition.
+ // - if count <= 0, skip validating no-op draw calls.
+ // From this we know maxVertex will be positive, and only need to check if it overflows GLint.
+ ASSERT(first >= 0);
+ ASSERT(count > 0);
+ int64_t maxVertex = static_cast<int64_t>(first) + static_cast<int64_t>(count) - 1;
+ if (maxVertex > static_cast<int64_t>(std::numeric_limits<GLint>::max()))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, err::kIntegerOverflow);
+ return false;
+ }
+
+ return ValidateDrawAttribs(context, entryPoint, maxVertex);
+}
+
+ANGLE_INLINE bool ValidateDrawInstancedAttribs(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint primcount)
+{
+ if (!context->isBufferAccessValidationEnabled())
+ {
+ return true;
+ }
+
+ if ((primcount - 1) > context->getStateCache().getInstancedVertexElementLimit())
+ {
+ RecordDrawAttribsError(context, entryPoint);
+ return false;
+ }
+
+ return true;
+}
+
+ANGLE_INLINE bool ValidateDrawArraysCommon(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLint first,
+ GLsizei count,
+ GLsizei primcount)
+{
+ if (first < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, err::kNegativeStart);
+ return false;
+ }
+
+ if (count <= 0)
+ {
+ if (count < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, err::kNegativeCount);
+ return false;
+ }
+
+ // Early exit.
+ return ValidateDrawBase(context, entryPoint, mode);
+ }
+
+ if (primcount <= 0)
+ {
+ if (primcount < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, err::kNegativeCount);
+ return false;
+ }
+ // Early exit.
+ return ValidateDrawBase(context, entryPoint, mode);
+ }
+
+ if (!ValidateDrawBase(context, entryPoint, mode))
+ {
+ return false;
+ }
+
+ if (context->getStateCache().isTransformFeedbackActiveUnpaused() &&
+ !context->supportsGeometryOrTesselation())
+ {
+ const State &state = context->getState();
+ TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
+ if (!curTransformFeedback->checkBufferSpaceForDraw(count, primcount))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ err::kTransformFeedbackBufferTooSmall);
+ return false;
+ }
+ }
+
+ return ValidateDrawArraysAttribs(context, entryPoint, first, count);
+}
+
+ANGLE_INLINE bool ValidateDrawElementsBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ DrawElementsType type)
+{
+ if (!context->getStateCache().isValidDrawElementsType(type))
+ {
+ if (type == DrawElementsType::UnsignedInt)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, err::kTypeNotUnsignedShortByte);
+ return false;
+ }
+
+ ASSERT(type == DrawElementsType::InvalidEnum);
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, err::kEnumInvalid);
+ return false;
+ }
+
+ intptr_t drawElementsError = context->getStateCache().getBasicDrawElementsError(context);
+ if (drawElementsError)
+ {
+ // All errors from ValidateDrawElementsStates return INVALID_OPERATION.
+ const char *errorMessage = reinterpret_cast<const char *>(drawElementsError);
+ context->validationError(entryPoint, GL_INVALID_OPERATION, errorMessage);
+ return false;
+ }
+
+ // Note that we are missing overflow checks for active transform feedback buffers.
+ return true;
+}
+
+ANGLE_INLINE bool ValidateDrawElementsCommon(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLsizei count,
+ DrawElementsType type,
+ const void *indices,
+ GLsizei primcount)
+{
+ if (!ValidateDrawElementsBase(context, entryPoint, mode, type))
+ {
+ return false;
+ }
+
+ ASSERT(isPow2(GetDrawElementsTypeSize(type)) && GetDrawElementsTypeSize(type) > 0);
+
+ if (context->isWebGL())
+ {
+ GLuint typeBytes = GetDrawElementsTypeSize(type);
+
+ if ((reinterpret_cast<uintptr_t>(indices) & static_cast<uintptr_t>(typeBytes - 1)) != 0)
+ {
+ // [WebGL 1.0] Section 6.4 Buffer Offset and Stride Requirements
+ // The offset arguments to drawElements and [...], must be a multiple of the size of the
+ // data type passed to the call, or an INVALID_OPERATION error is generated.
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ err::kOffsetMustBeMultipleOfType);
+ return false;
+ }
+
+ // [WebGL 1.0] Section 6.4 Buffer Offset and Stride Requirements
+ // In addition the offset argument to drawElements must be non-negative or an INVALID_VALUE
+ // error is generated.
+ if (reinterpret_cast<intptr_t>(indices) < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, err::kNegativeOffset);
+ return false;
+ }
+ }
+
+ if (count <= 0)
+ {
+ if (count < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, err::kNegativeCount);
+ return false;
+ }
+
+ // Early exit.
+ return ValidateDrawBase(context, entryPoint, mode);
+ }
+
+ if (!ValidateDrawBase(context, entryPoint, mode))
+ {
+ return false;
+ }
+
+ const State &state = context->getState();
+ const VertexArray *vao = state.getVertexArray();
+ Buffer *elementArrayBuffer = vao->getElementArrayBuffer();
+
+ if (!elementArrayBuffer)
+ {
+ if (!indices)
+ {
+ // This is an application error that would normally result in a crash, but we catch
+ // it and return an error
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ err::kElementArrayNoBufferOrPointer);
+ return false;
+ }
+ }
+ else
+ {
+ // The max possible type size is 8 and count is on 32 bits so doing the multiplication
+ // in a 64 bit integer is safe. Also we are guaranteed that here count > 0.
+ static_assert(std::is_same<int, GLsizei>::value, "GLsizei isn't the expected type");
+ constexpr uint64_t kMaxTypeSize = 8;
+ constexpr uint64_t kIntMax = std::numeric_limits<int>::max();
+ constexpr uint64_t kUint64Max = std::numeric_limits<uint64_t>::max();
+ static_assert(kIntMax < kUint64Max / kMaxTypeSize, "");
+
+ uint64_t elementCount = static_cast<uint64_t>(count);
+ ASSERT(elementCount > 0 && GetDrawElementsTypeSize(type) <= kMaxTypeSize);
+
+ // Doing the multiplication here is overflow-safe
+ uint64_t elementDataSizeNoOffset = elementCount << GetDrawElementsTypeShift(type);
+
+ // The offset can be any value, check for overflows
+ uint64_t offset = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(indices));
+ uint64_t elementDataSizeWithOffset = elementDataSizeNoOffset + offset;
+ if (elementDataSizeWithOffset < elementDataSizeNoOffset)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, err::kIntegerOverflow);
+ return false;
+ }
+
+ // Related to possible test bug: https://github.com/KhronosGroup/WebGL/issues/3064
+ if ((elementDataSizeWithOffset > static_cast<uint64_t>(elementArrayBuffer->getSize())) &&
+ (primcount > 0))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ err::kInsufficientBufferSize);
+ return false;
+ }
+ }
+
+ if (context->isBufferAccessValidationEnabled() && primcount > 0)
+ {
+ // Use the parameter buffer to retrieve and cache the index range.
+ IndexRange indexRange{IndexRange::Undefined()};
+ ANGLE_VALIDATION_TRY(vao->getIndexRange(context, type, count, indices, &indexRange));
+
+ // If we use an index greater than our maximum supported index range, return an error.
+ // The ES3 spec does not specify behaviour here, it is undefined, but ANGLE should
+ // always return an error if possible here.
+ if (static_cast<GLint64>(indexRange.end) >= context->getCaps().maxElementIndex)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, err::kExceedsMaxElement);
+ return false;
+ }
+
+ if (!ValidateDrawAttribs(context, entryPoint, static_cast<GLint>(indexRange.end)))
+ {
+ return false;
+ }
+
+ // No op if there are no real indices in the index data (all are primitive restart).
+ return (indexRange.vertexIndexCount > 0);
+ }
+
+ return true;
+}
+
+ANGLE_INLINE bool ValidateBindVertexArrayBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexArrayID array)
+{
+ if (!context->isVertexArrayGenerated(array))
+ {
+ // The default VAO should always exist
+ ASSERT(array.value != 0);
+ context->validationError(entryPoint, GL_INVALID_OPERATION, err::kInvalidVertexArray);
+ return false;
+ }
+
+ return true;
+}
+
+ANGLE_INLINE bool ValidateVertexAttribIndex(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index)
+{
+ if (index >= static_cast<GLuint>(context->getCaps().maxVertexAttributes))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ err::kIndexExceedsMaxVertexAttribute);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateLogicOpCommon(const Context *context,
+ angle::EntryPoint entryPoint,
+ LogicalOperation opcodePacked);
+} // namespace gl
+
+#endif // LIBANGLE_VALIDATION_ES_H_
diff --git a/gfx/angle/checkout/src/libANGLE/validationES1.cpp b/gfx/angle/checkout/src/libANGLE/validationES1.cpp
new file mode 100644
index 0000000000..f872689492
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/validationES1.cpp
@@ -0,0 +1,2129 @@
+//
+// Copyright 2018 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.
+//
+
+// validationES1.cpp: Validation functions for OpenGL ES 1.0 entry point parameters
+
+#include "libANGLE/validationES1_autogen.h"
+
+#include "common/debug.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/ErrorStrings.h"
+#include "libANGLE/GLES1State.h"
+#include "libANGLE/queryconversions.h"
+#include "libANGLE/queryutils.h"
+#include "libANGLE/validationES.h"
+
+#define ANGLE_VALIDATE_IS_GLES1(context, entryPoint) \
+ do \
+ { \
+ if (context->getClientType() != EGL_OPENGL_API && context->getClientMajorVersion() > 1) \
+ { \
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kGLES1Only); \
+ return false; \
+ } \
+ } while (0)
+
+namespace gl
+{
+using namespace err;
+
+bool ValidateAlphaFuncCommon(const Context *context,
+ angle::EntryPoint entryPoint,
+ AlphaTestFunc func)
+{
+ switch (func)
+ {
+ case AlphaTestFunc::AlwaysPass:
+ case AlphaTestFunc::Equal:
+ case AlphaTestFunc::Gequal:
+ case AlphaTestFunc::Greater:
+ case AlphaTestFunc::Lequal:
+ case AlphaTestFunc::Less:
+ case AlphaTestFunc::Never:
+ case AlphaTestFunc::NotEqual:
+ return true;
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kEnumInvalid);
+ return false;
+ }
+}
+
+bool ValidateClientStateCommon(const Context *context,
+ angle::EntryPoint entryPoint,
+ ClientVertexArrayType arrayType)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ switch (arrayType)
+ {
+ case ClientVertexArrayType::Vertex:
+ case ClientVertexArrayType::Normal:
+ case ClientVertexArrayType::Color:
+ case ClientVertexArrayType::TextureCoord:
+ return true;
+ case ClientVertexArrayType::PointSize:
+ if (!context->getExtensions().pointSizeArrayOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM,
+ kPointSizeArrayExtensionNotEnabled);
+ return false;
+ }
+ return true;
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidClientState);
+ return false;
+ }
+}
+
+bool ValidateBuiltinVertexAttributeCommon(const Context *context,
+ angle::EntryPoint entryPoint,
+ ClientVertexArrayType arrayType,
+ GLint size,
+ VertexAttribType type,
+ GLsizei stride,
+ const void *pointer)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+
+ if (stride < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidVertexPointerStride);
+ return false;
+ }
+
+ int minSize = 1;
+ int maxSize = 4;
+
+ switch (arrayType)
+ {
+ case ClientVertexArrayType::Vertex:
+ case ClientVertexArrayType::TextureCoord:
+ minSize = 2;
+ maxSize = 4;
+ break;
+ case ClientVertexArrayType::Normal:
+ minSize = 3;
+ maxSize = 3;
+ break;
+ case ClientVertexArrayType::Color:
+ minSize = 4;
+ maxSize = 4;
+ break;
+ case ClientVertexArrayType::PointSize:
+ if (!context->getExtensions().pointSizeArrayOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM,
+ kPointSizeArrayExtensionNotEnabled);
+ return false;
+ }
+
+ minSize = 1;
+ maxSize = 1;
+ break;
+ default:
+ UNREACHABLE();
+ return false;
+ }
+
+ if (size < minSize || size > maxSize)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidVertexPointerSize);
+ return false;
+ }
+
+ switch (type)
+ {
+ case VertexAttribType::Byte:
+ if (arrayType == ClientVertexArrayType::PointSize)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidVertexPointerType);
+ return false;
+ }
+ break;
+ case VertexAttribType::Short:
+ if (arrayType == ClientVertexArrayType::PointSize ||
+ arrayType == ClientVertexArrayType::Color)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidVertexPointerType);
+ return false;
+ }
+ break;
+ case VertexAttribType::Fixed:
+ case VertexAttribType::Float:
+ break;
+ case VertexAttribType::UnsignedByte:
+ if (arrayType != ClientVertexArrayType::Color)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidVertexPointerType);
+ return false;
+ }
+ break;
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidVertexPointerType);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateLightCaps(const Context *context, angle::EntryPoint entryPoint, GLenum light)
+{
+ if (light < GL_LIGHT0 || light >= GL_LIGHT0 + context->getCaps().maxLights)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidLight);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateLightCommon(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum light,
+ LightParameter pname,
+ const GLfloat *params)
+{
+
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+
+ if (!ValidateLightCaps(context, entryPoint, light))
+ {
+ return false;
+ }
+
+ switch (pname)
+ {
+ case LightParameter::Ambient:
+ case LightParameter::Diffuse:
+ case LightParameter::Specular:
+ case LightParameter::Position:
+ case LightParameter::SpotDirection:
+ return true;
+ case LightParameter::SpotExponent:
+ if (params[0] < 0.0f || params[0] > 128.0f)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kLightParameterOutOfRange);
+ return false;
+ }
+ return true;
+ case LightParameter::SpotCutoff:
+ if (params[0] == 180.0f)
+ {
+ return true;
+ }
+ if (params[0] < 0.0f || params[0] > 90.0f)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kLightParameterOutOfRange);
+ return false;
+ }
+ return true;
+ case LightParameter::ConstantAttenuation:
+ case LightParameter::LinearAttenuation:
+ case LightParameter::QuadraticAttenuation:
+ if (params[0] < 0.0f)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kLightParameterOutOfRange);
+ return false;
+ }
+ return true;
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidLightParameter);
+ return false;
+ }
+}
+
+bool ValidateLightSingleComponent(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum light,
+ LightParameter pname,
+ GLfloat param)
+{
+ if (!ValidateLightCommon(context, entryPoint, light, pname, &param))
+ {
+ return false;
+ }
+
+ if (GetLightParameterCount(pname) > 1)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidLightParameter);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateMaterialCommon(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum face,
+ MaterialParameter pname,
+ const GLfloat *params)
+{
+ switch (pname)
+ {
+ case MaterialParameter::Ambient:
+ case MaterialParameter::AmbientAndDiffuse:
+ case MaterialParameter::Diffuse:
+ case MaterialParameter::Specular:
+ case MaterialParameter::Emission:
+ return true;
+ case MaterialParameter::Shininess:
+ if (params[0] < 0.0f || params[0] > 128.0f)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kMaterialParameterOutOfRange);
+ return false;
+ }
+ return true;
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidMaterialParameter);
+ return false;
+ }
+}
+
+bool ValidateMaterialSetting(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum face,
+ MaterialParameter pname,
+ const GLfloat *params)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+
+ if (face != GL_FRONT_AND_BACK)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidMaterialFace);
+ return false;
+ }
+
+ return ValidateMaterialCommon(context, entryPoint, face, pname, params);
+}
+
+bool ValidateMaterialQuery(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum face,
+ MaterialParameter pname)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+
+ if (face != GL_FRONT && face != GL_BACK)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidMaterialFace);
+ return false;
+ }
+
+ GLfloat validateParams[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+
+ return ValidateMaterialCommon(context, entryPoint, face, pname, validateParams);
+}
+
+bool ValidateMaterialSingleComponent(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum face,
+ MaterialParameter pname,
+ GLfloat param)
+{
+ if (!ValidateMaterialSetting(context, entryPoint, face, pname, &param))
+ {
+ return false;
+ }
+
+ if (GetMaterialParameterCount(pname) > 1)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidMaterialParameter);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateLightModelCommon(const Context *context, angle::EntryPoint entryPoint, GLenum pname)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ switch (pname)
+ {
+ case GL_LIGHT_MODEL_AMBIENT:
+ case GL_LIGHT_MODEL_TWO_SIDE:
+ return true;
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidLightModelParameter);
+ return false;
+ }
+}
+
+bool ValidateLightModelSingleComponent(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname)
+{
+ if (!ValidateLightModelCommon(context, entryPoint, pname))
+ {
+ return false;
+ }
+
+ switch (pname)
+ {
+ case GL_LIGHT_MODEL_TWO_SIDE:
+ return true;
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidLightModelParameter);
+ return false;
+ }
+}
+
+bool ValidateClipPlaneCommon(const Context *context, angle::EntryPoint entryPoint, GLenum plane)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+
+ if (plane < GL_CLIP_PLANE0 || plane >= GL_CLIP_PLANE0 + context->getCaps().maxClipPlanes)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidClipPlane);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateFogCommon(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ const GLfloat *params)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+
+ switch (pname)
+ {
+ case GL_FOG_MODE:
+ {
+ GLenum modeParam = static_cast<GLenum>(params[0]);
+ switch (modeParam)
+ {
+ case GL_EXP:
+ case GL_EXP2:
+ case GL_LINEAR:
+ return true;
+ default:
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidFogMode);
+ return false;
+ }
+ }
+ case GL_FOG_START:
+ case GL_FOG_END:
+ case GL_FOG_COLOR:
+ break;
+ case GL_FOG_DENSITY:
+ if (params[0] < 0.0f)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidFogDensity);
+ return false;
+ }
+ break;
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFogParameter);
+ return false;
+ }
+ return true;
+}
+
+bool ValidateTexEnvCommon(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureEnvTarget target,
+ TextureEnvParameter pname,
+ const GLfloat *params)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+
+ switch (target)
+ {
+ case TextureEnvTarget::Env:
+ switch (pname)
+ {
+ case TextureEnvParameter::Mode:
+ {
+ TextureEnvMode mode = FromGLenum<TextureEnvMode>(ConvertToGLenum(params[0]));
+ switch (mode)
+ {
+ case TextureEnvMode::Add:
+ case TextureEnvMode::Blend:
+ case TextureEnvMode::Combine:
+ case TextureEnvMode::Decal:
+ case TextureEnvMode::Modulate:
+ case TextureEnvMode::Replace:
+ break;
+ default:
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kInvalidTextureEnvMode);
+ return false;
+ }
+ break;
+ }
+ case TextureEnvParameter::CombineRgb:
+ case TextureEnvParameter::CombineAlpha:
+ {
+ TextureCombine combine = FromGLenum<TextureCombine>(ConvertToGLenum(params[0]));
+ switch (combine)
+ {
+ case TextureCombine::Add:
+ case TextureCombine::AddSigned:
+ case TextureCombine::Interpolate:
+ case TextureCombine::Modulate:
+ case TextureCombine::Replace:
+ case TextureCombine::Subtract:
+ break;
+ case TextureCombine::Dot3Rgb:
+ case TextureCombine::Dot3Rgba:
+ if (pname == TextureEnvParameter::CombineAlpha)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kInvalidTextureCombine);
+ return false;
+ }
+ break;
+ default:
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kInvalidTextureCombine);
+ return false;
+ }
+ break;
+ }
+ case TextureEnvParameter::Src0Rgb:
+ case TextureEnvParameter::Src1Rgb:
+ case TextureEnvParameter::Src2Rgb:
+ case TextureEnvParameter::Src0Alpha:
+ case TextureEnvParameter::Src1Alpha:
+ case TextureEnvParameter::Src2Alpha:
+ {
+ TextureSrc combine = FromGLenum<TextureSrc>(ConvertToGLenum(params[0]));
+ switch (combine)
+ {
+ case TextureSrc::Constant:
+ case TextureSrc::Previous:
+ case TextureSrc::PrimaryColor:
+ case TextureSrc::Texture:
+ break;
+ default:
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kInvalidTextureCombineSrc);
+ return false;
+ }
+ break;
+ }
+ case TextureEnvParameter::Op0Rgb:
+ case TextureEnvParameter::Op1Rgb:
+ case TextureEnvParameter::Op2Rgb:
+ case TextureEnvParameter::Op0Alpha:
+ case TextureEnvParameter::Op1Alpha:
+ case TextureEnvParameter::Op2Alpha:
+ {
+ TextureOp operand = FromGLenum<TextureOp>(ConvertToGLenum(params[0]));
+ switch (operand)
+ {
+ case TextureOp::SrcAlpha:
+ case TextureOp::OneMinusSrcAlpha:
+ break;
+ case TextureOp::SrcColor:
+ case TextureOp::OneMinusSrcColor:
+ if (pname == TextureEnvParameter::Op0Alpha ||
+ pname == TextureEnvParameter::Op1Alpha ||
+ pname == TextureEnvParameter::Op2Alpha)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kInvalidTextureCombine);
+ return false;
+ }
+ break;
+ default:
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kInvalidTextureCombineOp);
+ return false;
+ }
+ break;
+ }
+ case TextureEnvParameter::RgbScale:
+ case TextureEnvParameter::AlphaScale:
+ if (params[0] != 1.0f && params[0] != 2.0f && params[0] != 4.0f)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kInvalidTextureEnvScale);
+ return false;
+ }
+ break;
+ case TextureEnvParameter::Color:
+ break;
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM,
+ kInvalidTextureEnvParameter);
+ return false;
+ }
+ break;
+ case TextureEnvTarget::PointSprite:
+ if (!context->getExtensions().pointSpriteOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureEnvTarget);
+ return false;
+ }
+ switch (pname)
+ {
+ case TextureEnvParameter::PointCoordReplace:
+ break;
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM,
+ kInvalidTextureEnvParameter);
+ return false;
+ }
+ break;
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureEnvTarget);
+ return false;
+ }
+ return true;
+}
+
+bool ValidateGetTexEnvCommon(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureEnvTarget target,
+ TextureEnvParameter pname)
+{
+ GLfloat validateParams[4] = {};
+ switch (pname)
+ {
+ case TextureEnvParameter::Mode:
+ ConvertPackedEnum(TextureEnvMode::Add, validateParams);
+ break;
+ case TextureEnvParameter::CombineRgb:
+ case TextureEnvParameter::CombineAlpha:
+ ConvertPackedEnum(TextureCombine::Add, validateParams);
+ break;
+ case TextureEnvParameter::Src0Rgb:
+ case TextureEnvParameter::Src1Rgb:
+ case TextureEnvParameter::Src2Rgb:
+ case TextureEnvParameter::Src0Alpha:
+ case TextureEnvParameter::Src1Alpha:
+ case TextureEnvParameter::Src2Alpha:
+ ConvertPackedEnum(TextureSrc::Constant, validateParams);
+ break;
+ case TextureEnvParameter::Op0Rgb:
+ case TextureEnvParameter::Op1Rgb:
+ case TextureEnvParameter::Op2Rgb:
+ case TextureEnvParameter::Op0Alpha:
+ case TextureEnvParameter::Op1Alpha:
+ case TextureEnvParameter::Op2Alpha:
+ ConvertPackedEnum(TextureOp::SrcAlpha, validateParams);
+ break;
+ case TextureEnvParameter::RgbScale:
+ case TextureEnvParameter::AlphaScale:
+ case TextureEnvParameter::PointCoordReplace:
+ validateParams[0] = 1.0f;
+ break;
+ default:
+ break;
+ }
+
+ return ValidateTexEnvCommon(context, entryPoint, target, pname, validateParams);
+}
+
+bool ValidatePointParameterCommon(const Context *context,
+ angle::EntryPoint entryPoint,
+ PointParameter pname,
+ const GLfloat *params)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+
+ switch (pname)
+ {
+ case PointParameter::PointSizeMin:
+ case PointParameter::PointSizeMax:
+ case PointParameter::PointFadeThresholdSize:
+ case PointParameter::PointDistanceAttenuation:
+ for (unsigned int i = 0; i < GetPointParameterCount(pname); i++)
+ {
+ if (params[i] < 0.0f)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kInvalidPointParameterValue);
+ return false;
+ }
+ }
+ break;
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPointParameter);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidatePointSizeCommon(const Context *context, angle::EntryPoint entryPoint, GLfloat size)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+
+ if (size <= 0.0f)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidPointSizeValue);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateDrawTexCommon(const Context *context,
+ angle::EntryPoint entryPoint,
+ float width,
+ float height)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+
+ if (width <= 0.0f || height <= 0.0f)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNonPositiveDrawTextureDimension);
+ return false;
+ }
+
+ return true;
+}
+
+} // namespace gl
+
+namespace gl
+{
+
+bool ValidateAlphaFunc(const Context *context,
+ angle::EntryPoint entryPoint,
+ AlphaTestFunc func,
+ GLfloat ref)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ return ValidateAlphaFuncCommon(context, entryPoint, func);
+}
+
+bool ValidateAlphaFuncx(const Context *context,
+ angle::EntryPoint entryPoint,
+ AlphaTestFunc func,
+ GLfixed ref)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ return ValidateAlphaFuncCommon(context, entryPoint, func);
+}
+
+bool ValidateClearColorx(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfixed red,
+ GLfixed green,
+ GLfixed blue,
+ GLfixed alpha)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ return true;
+}
+
+bool ValidateClearDepthx(const Context *context, angle::EntryPoint entryPoint, GLfixed depth)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ return true;
+}
+
+bool ValidateClientActiveTexture(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum texture)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ return ValidateMultitextureUnit(context, entryPoint, texture);
+}
+
+bool ValidateClipPlanef(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum plane,
+ const GLfloat *eqn)
+{
+ return ValidateClipPlaneCommon(context, entryPoint, plane);
+}
+
+bool ValidateClipPlanex(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum plane,
+ const GLfixed *equation)
+{
+ return ValidateClipPlaneCommon(context, entryPoint, plane);
+}
+
+bool ValidateColor4f(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat red,
+ GLfloat green,
+ GLfloat blue,
+ GLfloat alpha)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ return true;
+}
+
+bool ValidateColor4ub(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLubyte red,
+ GLubyte green,
+ GLubyte blue,
+ GLubyte alpha)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ return true;
+}
+
+bool ValidateColor4x(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfixed red,
+ GLfixed green,
+ GLfixed blue,
+ GLfixed alpha)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ return true;
+}
+
+bool ValidateColorPointer(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint size,
+ VertexAttribType type,
+ GLsizei stride,
+ const void *pointer)
+{
+ return ValidateBuiltinVertexAttributeCommon(context, entryPoint, ClientVertexArrayType::Color,
+ size, type, stride, pointer);
+}
+
+bool ValidateCullFace(const Context *context, angle::EntryPoint entryPoint, GLenum mode)
+{
+ UNIMPLEMENTED();
+ return true;
+}
+
+bool ValidateDepthRangex(const Context *context, angle::EntryPoint entryPoint, GLfixed n, GLfixed f)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ if (context->isWebGL() && n > f)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidDepthRange);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateDisableClientState(const Context *context,
+ angle::EntryPoint entryPoint,
+ ClientVertexArrayType arrayType)
+{
+ return ValidateClientStateCommon(context, entryPoint, arrayType);
+}
+
+bool ValidateEnableClientState(const Context *context,
+ angle::EntryPoint entryPoint,
+ ClientVertexArrayType arrayType)
+{
+ return ValidateClientStateCommon(context, entryPoint, arrayType);
+}
+
+bool ValidateFogf(const Context *context, angle::EntryPoint entryPoint, GLenum pname, GLfloat param)
+{
+ return ValidateFogCommon(context, entryPoint, pname, &param);
+}
+
+bool ValidateFogfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ const GLfloat *params)
+{
+ return ValidateFogCommon(context, entryPoint, pname, params);
+}
+
+bool ValidateFogx(const Context *context, angle::EntryPoint entryPoint, GLenum pname, GLfixed param)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ GLfloat asFloat =
+ pname == GL_FOG_MODE ? static_cast<GLfloat>(param) : ConvertFixedToFloat(param);
+ return ValidateFogCommon(context, entryPoint, pname, &asFloat);
+}
+
+bool ValidateFogxv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ const GLfixed *params)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ unsigned int paramCount = GetFogParameterCount(pname);
+ GLfloat paramsf[4] = {};
+
+ if (pname == GL_FOG_MODE)
+ {
+ paramsf[0] = static_cast<GLfloat>(params[0]);
+ }
+ else
+ {
+ for (unsigned int i = 0; i < paramCount; i++)
+ {
+ paramsf[i] = ConvertFixedToFloat(params[i]);
+ }
+ }
+
+ return ValidateFogCommon(context, entryPoint, pname, paramsf);
+}
+
+bool ValidateFrustumf(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat l,
+ GLfloat r,
+ GLfloat b,
+ GLfloat t,
+ GLfloat n,
+ GLfloat f)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ if (l == r || b == t || n == f || n <= 0.0f || f <= 0.0f)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidProjectionMatrix);
+ return false;
+ }
+ return true;
+}
+
+bool ValidateFrustumx(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfixed l,
+ GLfixed r,
+ GLfixed b,
+ GLfixed t,
+ GLfixed n,
+ GLfixed f)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ if (l == r || b == t || n == f || n <= 0 || f <= 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidProjectionMatrix);
+ return false;
+ }
+ return true;
+}
+
+bool ValidateGetBufferParameteriv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum pname,
+ const GLint *params)
+{
+ UNIMPLEMENTED();
+ return true;
+}
+
+bool ValidateGetClipPlanef(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum plane,
+ const GLfloat *equation)
+{
+ return ValidateClipPlaneCommon(context, entryPoint, plane);
+}
+
+bool ValidateGetClipPlanex(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum plane,
+ const GLfixed *equation)
+{
+ return ValidateClipPlaneCommon(context, entryPoint, plane);
+}
+
+bool ValidateGetFixedv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ const GLfixed *params)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ GLenum nativeType;
+ unsigned int numParams = 0;
+ return ValidateStateQuery(context, entryPoint, pname, &nativeType, &numParams);
+}
+
+bool ValidateGetLightfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum light,
+ LightParameter pname,
+ const GLfloat *params)
+{
+ GLfloat validateParams[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ return ValidateLightCommon(context, entryPoint, light, pname, validateParams);
+}
+
+bool ValidateGetLightxv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum light,
+ LightParameter pname,
+ const GLfixed *params)
+{
+ GLfloat validateParams[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ return ValidateLightCommon(context, entryPoint, light, pname, validateParams);
+}
+
+bool ValidateGetMaterialfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum face,
+ MaterialParameter pname,
+ const GLfloat *params)
+{
+ return ValidateMaterialQuery(context, entryPoint, face, pname);
+}
+
+bool ValidateGetMaterialxv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum face,
+ MaterialParameter pname,
+ const GLfixed *params)
+{
+ return ValidateMaterialQuery(context, entryPoint, face, pname);
+}
+
+bool ValidateGetTexEnvfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureEnvTarget target,
+ TextureEnvParameter pname,
+ const GLfloat *params)
+{
+ return ValidateGetTexEnvCommon(context, entryPoint, target, pname);
+}
+
+bool ValidateGetTexEnviv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureEnvTarget target,
+ TextureEnvParameter pname,
+ const GLint *params)
+{
+ return ValidateGetTexEnvCommon(context, entryPoint, target, pname);
+}
+
+bool ValidateGetTexEnvxv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureEnvTarget target,
+ TextureEnvParameter pname,
+ const GLfixed *params)
+{
+ return ValidateGetTexEnvCommon(context, entryPoint, target, pname);
+}
+
+bool ValidateGetTexParameterxv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLenum pname,
+ const GLfixed *params)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+
+ if (!ValidateGetTexParameterBase(context, entryPoint, target, pname, nullptr))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateLightModelf(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLfloat param)
+{
+ return ValidateLightModelSingleComponent(context, entryPoint, pname);
+}
+
+bool ValidateLightModelfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ const GLfloat *params)
+{
+ return ValidateLightModelCommon(context, entryPoint, pname);
+}
+
+bool ValidateLightModelx(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLfixed param)
+{
+ return ValidateLightModelSingleComponent(context, entryPoint, pname);
+}
+
+bool ValidateLightModelxv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ const GLfixed *param)
+{
+ return ValidateLightModelCommon(context, entryPoint, pname);
+}
+
+bool ValidateLightf(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum light,
+ LightParameter pname,
+ GLfloat param)
+{
+ return ValidateLightSingleComponent(context, entryPoint, light, pname, param);
+}
+
+bool ValidateLightfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum light,
+ LightParameter pname,
+ const GLfloat *params)
+{
+ return ValidateLightCommon(context, entryPoint, light, pname, params);
+}
+
+bool ValidateLightx(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum light,
+ LightParameter pname,
+ GLfixed param)
+{
+ return ValidateLightSingleComponent(context, entryPoint, light, pname,
+ ConvertFixedToFloat(param));
+}
+
+bool ValidateLightxv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum light,
+ LightParameter pname,
+ const GLfixed *params)
+{
+ GLfloat paramsf[4];
+ for (unsigned int i = 0; i < GetLightParameterCount(pname); i++)
+ {
+ paramsf[i] = ConvertFixedToFloat(params[i]);
+ }
+
+ return ValidateLightCommon(context, entryPoint, light, pname, paramsf);
+}
+
+bool ValidateLineWidthx(const Context *context, angle::EntryPoint entryPoint, GLfixed width)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ if (width <= 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidWidth);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateLoadIdentity(const Context *context, angle::EntryPoint entryPoint)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ return true;
+}
+
+bool ValidateLoadMatrixf(const Context *context, angle::EntryPoint entryPoint, const GLfloat *m)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ return true;
+}
+
+bool ValidateLoadMatrixx(const Context *context, angle::EntryPoint entryPoint, const GLfixed *m)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ return true;
+}
+
+bool ValidateLogicOp(const Context *context, angle::EntryPoint entryPoint, LogicalOperation opcode)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ return ValidateLogicOpCommon(context, entryPoint, opcode);
+}
+
+bool ValidateMaterialf(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum face,
+ MaterialParameter pname,
+ GLfloat param)
+{
+ return ValidateMaterialSingleComponent(context, entryPoint, face, pname, param);
+}
+
+bool ValidateMaterialfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum face,
+ MaterialParameter pname,
+ const GLfloat *params)
+{
+ return ValidateMaterialSetting(context, entryPoint, face, pname, params);
+}
+
+bool ValidateMaterialx(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum face,
+ MaterialParameter pname,
+ GLfixed param)
+{
+ return ValidateMaterialSingleComponent(context, entryPoint, face, pname,
+ ConvertFixedToFloat(param));
+}
+
+bool ValidateMaterialxv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum face,
+ MaterialParameter pname,
+ const GLfixed *params)
+{
+ GLfloat paramsf[4];
+
+ for (unsigned int i = 0; i < GetMaterialParameterCount(pname); i++)
+ {
+ paramsf[i] = ConvertFixedToFloat(params[i]);
+ }
+
+ return ValidateMaterialSetting(context, entryPoint, face, pname, paramsf);
+}
+
+bool ValidateMatrixMode(const Context *context, angle::EntryPoint entryPoint, MatrixType mode)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ switch (mode)
+ {
+ case MatrixType::Projection:
+ case MatrixType::Modelview:
+ case MatrixType::Texture:
+ return true;
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidMatrixMode);
+ return false;
+ }
+}
+
+bool ValidateMultMatrixf(const Context *context, angle::EntryPoint entryPoint, const GLfloat *m)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ return true;
+}
+
+bool ValidateMultMatrixx(const Context *context, angle::EntryPoint entryPoint, const GLfixed *m)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ return true;
+}
+
+bool ValidateMultiTexCoord4f(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLfloat s,
+ GLfloat t,
+ GLfloat r,
+ GLfloat q)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ return ValidateMultitextureUnit(context, entryPoint, target);
+}
+
+bool ValidateMultiTexCoord4x(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLfixed s,
+ GLfixed t,
+ GLfixed r,
+ GLfixed q)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ return ValidateMultitextureUnit(context, entryPoint, target);
+}
+
+bool ValidateNormal3f(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat nx,
+ GLfloat ny,
+ GLfloat nz)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ return true;
+}
+
+bool ValidateNormal3x(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfixed nx,
+ GLfixed ny,
+ GLfixed nz)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ return true;
+}
+
+bool ValidateNormalPointer(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexAttribType type,
+ GLsizei stride,
+ const void *pointer)
+{
+ return ValidateBuiltinVertexAttributeCommon(context, entryPoint, ClientVertexArrayType::Normal,
+ 3, type, stride, pointer);
+}
+
+bool ValidateOrthof(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat l,
+ GLfloat r,
+ GLfloat b,
+ GLfloat t,
+ GLfloat n,
+ GLfloat f)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ // [OpenGL ES 1.1.12] section 2.10.2 page 31:
+ // If l is equal to r, b is equal to t, or n is equal to f, the
+ // error INVALID VALUE results.
+ if (l == r || b == t || n == f)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidProjectionMatrix);
+ return false;
+ }
+ return true;
+}
+
+bool ValidateOrthox(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfixed l,
+ GLfixed r,
+ GLfixed b,
+ GLfixed t,
+ GLfixed n,
+ GLfixed f)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ if (l == r || b == t || n == f)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidProjectionMatrix);
+ return false;
+ }
+ return true;
+}
+
+bool ValidatePointParameterf(const Context *context,
+ angle::EntryPoint entryPoint,
+ PointParameter pname,
+ GLfloat param)
+{
+ unsigned int paramCount = GetPointParameterCount(pname);
+ if (paramCount != 1)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPointParameter);
+ return false;
+ }
+
+ return ValidatePointParameterCommon(context, entryPoint, pname, &param);
+}
+
+bool ValidatePointParameterfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ PointParameter pname,
+ const GLfloat *params)
+{
+ return ValidatePointParameterCommon(context, entryPoint, pname, params);
+}
+
+bool ValidatePointParameterx(const Context *context,
+ angle::EntryPoint entryPoint,
+ PointParameter pname,
+ GLfixed param)
+{
+ unsigned int paramCount = GetPointParameterCount(pname);
+ if (paramCount != 1)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPointParameter);
+ return false;
+ }
+
+ GLfloat paramf = ConvertFixedToFloat(param);
+ return ValidatePointParameterCommon(context, entryPoint, pname, &paramf);
+}
+
+bool ValidatePointParameterxv(const Context *context,
+ angle::EntryPoint entryPoint,
+ PointParameter pname,
+ const GLfixed *params)
+{
+ GLfloat paramsf[4] = {};
+ for (unsigned int i = 0; i < GetPointParameterCount(pname); i++)
+ {
+ paramsf[i] = ConvertFixedToFloat(params[i]);
+ }
+ return ValidatePointParameterCommon(context, entryPoint, pname, paramsf);
+}
+
+bool ValidatePointSize(const Context *context, angle::EntryPoint entryPoint, GLfloat size)
+{
+ return ValidatePointSizeCommon(context, entryPoint, size);
+}
+
+bool ValidatePointSizex(const Context *context, angle::EntryPoint entryPoint, GLfixed size)
+{
+ return ValidatePointSizeCommon(context, entryPoint, ConvertFixedToFloat(size));
+}
+
+bool ValidatePolygonOffsetx(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfixed factor,
+ GLfixed units)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ return true;
+}
+
+bool ValidatePopMatrix(const Context *context, angle::EntryPoint entryPoint)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ const auto &stack = context->getState().gles1().currentMatrixStack();
+ if (stack.size() == 1)
+ {
+ context->validationError(entryPoint, GL_STACK_UNDERFLOW, kMatrixStackUnderflow);
+ return false;
+ }
+ return true;
+}
+
+bool ValidatePushMatrix(const Context *context, angle::EntryPoint entryPoint)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ const auto &stack = context->getState().gles1().currentMatrixStack();
+ if (stack.size() == stack.max_size())
+ {
+ context->validationError(entryPoint, GL_STACK_OVERFLOW, kMatrixStackOverflow);
+ return false;
+ }
+ return true;
+}
+
+bool ValidateRotatef(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat angle,
+ GLfloat x,
+ GLfloat y,
+ GLfloat z)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ return true;
+}
+
+bool ValidateRotatex(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfixed angle,
+ GLfixed x,
+ GLfixed y,
+ GLfixed z)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ return true;
+}
+
+bool ValidateSampleCoveragex(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLclampx value,
+ GLboolean invert)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ return true;
+}
+
+bool ValidateScalef(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat x,
+ GLfloat y,
+ GLfloat z)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ return true;
+}
+
+bool ValidateScalex(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfixed x,
+ GLfixed y,
+ GLfixed z)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ return true;
+}
+
+bool ValidateShadeModel(const Context *context, angle::EntryPoint entryPoint, ShadingModel mode)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ switch (mode)
+ {
+ case ShadingModel::Flat:
+ case ShadingModel::Smooth:
+ return true;
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidShadingModel);
+ return false;
+ }
+}
+
+bool ValidateTexCoordPointer(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint size,
+ VertexAttribType type,
+ GLsizei stride,
+ const void *pointer)
+{
+ return ValidateBuiltinVertexAttributeCommon(
+ context, entryPoint, ClientVertexArrayType::TextureCoord, size, type, stride, pointer);
+}
+
+bool ValidateTexEnvf(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureEnvTarget target,
+ TextureEnvParameter pname,
+ GLfloat param)
+{
+ return ValidateTexEnvCommon(context, entryPoint, target, pname, &param);
+}
+
+bool ValidateTexEnvfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureEnvTarget target,
+ TextureEnvParameter pname,
+ const GLfloat *params)
+{
+ return ValidateTexEnvCommon(context, entryPoint, target, pname, params);
+}
+
+bool ValidateTexEnvi(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureEnvTarget target,
+ TextureEnvParameter pname,
+ GLint param)
+{
+ GLfloat paramf = static_cast<GLfloat>(param);
+ return ValidateTexEnvCommon(context, entryPoint, target, pname, &paramf);
+}
+
+bool ValidateTexEnviv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureEnvTarget target,
+ TextureEnvParameter pname,
+ const GLint *params)
+{
+ GLfloat paramsf[4];
+ for (unsigned int i = 0; i < GetTextureEnvParameterCount(pname); i++)
+ {
+ paramsf[i] = static_cast<GLfloat>(params[i]);
+ }
+ return ValidateTexEnvCommon(context, entryPoint, target, pname, paramsf);
+}
+
+bool ValidateTexEnvx(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureEnvTarget target,
+ TextureEnvParameter pname,
+ GLfixed param)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ GLfloat paramsf[4] = {};
+ ConvertTextureEnvFromFixed(pname, &param, paramsf);
+ return ValidateTexEnvCommon(context, entryPoint, target, pname, paramsf);
+}
+
+bool ValidateTexEnvxv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureEnvTarget target,
+ TextureEnvParameter pname,
+ const GLfixed *params)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ GLfloat paramsf[4] = {};
+ ConvertTextureEnvFromFixed(pname, params, paramsf);
+ return ValidateTexEnvCommon(context, entryPoint, target, pname, paramsf);
+}
+
+bool ValidateTexParameterBaseForGLfixed(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLenum pname,
+ GLsizei bufSize,
+ bool vectorParams,
+ const GLfixed *params)
+{
+ // Convert GLfixed parameter for GL_TEXTURE_MAX_ANISOTROPY_EXT independently
+ // since it compares against 1 and maxTextureAnisotropy instead of just 0
+ // (other values are fine to leave unconverted since they only check positive or negative or
+ // are used as enums)
+ GLfloat paramValue;
+ if (pname == GL_TEXTURE_MAX_ANISOTROPY_EXT)
+ {
+ paramValue = ConvertFixedToFloat(static_cast<GLfixed>(params[0]));
+ }
+ else
+ {
+ paramValue = static_cast<GLfloat>(params[0]);
+ }
+ return ValidateTexParameterBase(context, entryPoint, target, pname, bufSize, vectorParams,
+ &paramValue);
+}
+
+bool ValidateTexParameterx(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLenum pname,
+ GLfixed param)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ return ValidateTexParameterBaseForGLfixed(context, entryPoint, target, pname, -1, false,
+ &param);
+}
+
+bool ValidateTexParameterxv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLenum pname,
+ const GLfixed *params)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ return ValidateTexParameterBaseForGLfixed(context, entryPoint, target, pname, -1, true, params);
+}
+
+bool ValidateTranslatef(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat x,
+ GLfloat y,
+ GLfloat z)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ return true;
+}
+
+bool ValidateTranslatex(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfixed x,
+ GLfixed y,
+ GLfixed z)
+{
+ ANGLE_VALIDATE_IS_GLES1(context, entryPoint);
+ return true;
+}
+
+bool ValidateVertexPointer(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint size,
+ VertexAttribType type,
+ GLsizei stride,
+ const void *pointer)
+{
+ return ValidateBuiltinVertexAttributeCommon(context, entryPoint, ClientVertexArrayType::Vertex,
+ size, type, stride, pointer);
+}
+
+bool ValidateDrawTexfOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat x,
+ GLfloat y,
+ GLfloat z,
+ GLfloat width,
+ GLfloat height)
+{
+ return ValidateDrawTexCommon(context, entryPoint, width, height);
+}
+
+bool ValidateDrawTexfvOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLfloat *coords)
+{
+ return ValidateDrawTexCommon(context, entryPoint, coords[3], coords[4]);
+}
+
+bool ValidateDrawTexiOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint x,
+ GLint y,
+ GLint z,
+ GLint width,
+ GLint height)
+{
+ return ValidateDrawTexCommon(context, entryPoint, static_cast<GLfloat>(width),
+ static_cast<GLfloat>(height));
+}
+
+bool ValidateDrawTexivOES(const Context *context, angle::EntryPoint entryPoint, const GLint *coords)
+{
+ return ValidateDrawTexCommon(context, entryPoint, static_cast<GLfloat>(coords[3]),
+ static_cast<GLfloat>(coords[4]));
+}
+
+bool ValidateDrawTexsOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLshort x,
+ GLshort y,
+ GLshort z,
+ GLshort width,
+ GLshort height)
+{
+ return ValidateDrawTexCommon(context, entryPoint, static_cast<GLfloat>(width),
+ static_cast<GLfloat>(height));
+}
+
+bool ValidateDrawTexsvOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLshort *coords)
+{
+ return ValidateDrawTexCommon(context, entryPoint, static_cast<GLfloat>(coords[3]),
+ static_cast<GLfloat>(coords[4]));
+}
+
+bool ValidateDrawTexxOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfixed x,
+ GLfixed y,
+ GLfixed z,
+ GLfixed width,
+ GLfixed height)
+{
+ return ValidateDrawTexCommon(context, entryPoint, ConvertFixedToFloat(width),
+ ConvertFixedToFloat(height));
+}
+
+bool ValidateDrawTexxvOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLfixed *coords)
+{
+ return ValidateDrawTexCommon(context, entryPoint, ConvertFixedToFloat(coords[3]),
+ ConvertFixedToFloat(coords[4]));
+}
+
+bool ValidateCurrentPaletteMatrixOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint matrixpaletteindex)
+{
+ UNIMPLEMENTED();
+ return true;
+}
+
+bool ValidateLoadPaletteFromModelViewMatrixOES(const Context *context, angle::EntryPoint entryPoint)
+{
+ UNIMPLEMENTED();
+ return true;
+}
+
+bool ValidateMatrixIndexPointerOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint size,
+ GLenum type,
+ GLsizei stride,
+ const void *pointer)
+{
+ UNIMPLEMENTED();
+ return true;
+}
+
+bool ValidateWeightPointerOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint size,
+ GLenum type,
+ GLsizei stride,
+ const void *pointer)
+{
+ UNIMPLEMENTED();
+ return true;
+}
+
+bool ValidatePointSizePointerOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexAttribType type,
+ GLsizei stride,
+ const void *pointer)
+{
+ return ValidateBuiltinVertexAttributeCommon(
+ context, entryPoint, ClientVertexArrayType::PointSize, 1, type, stride, pointer);
+}
+
+bool ValidateQueryMatrixxOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLfixed *mantissa,
+ const GLint *exponent)
+{
+ UNIMPLEMENTED();
+ return true;
+}
+
+bool ValidateGenFramebuffersOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const FramebufferID *framebuffers)
+{
+ if (!context->getExtensions().framebufferObjectOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateGenOrDelete(context, entryPoint, n);
+}
+
+bool ValidateDeleteFramebuffersOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const FramebufferID *framebuffers)
+{
+ if (!context->getExtensions().framebufferObjectOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateGenOrDelete(context, entryPoint, n);
+}
+
+bool ValidateGenRenderbuffersOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const RenderbufferID *renderbuffers)
+{
+ if (!context->getExtensions().framebufferObjectOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateGenOrDelete(context, entryPoint, n);
+}
+
+bool ValidateDeleteRenderbuffersOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const RenderbufferID *renderbuffers)
+{
+ if (!context->getExtensions().framebufferObjectOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateGenOrDelete(context, entryPoint, n);
+}
+
+bool ValidateBindFramebufferOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ FramebufferID framebuffer)
+{
+ if (!context->getExtensions().framebufferObjectOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateBindFramebufferBase(context, entryPoint, target, framebuffer);
+}
+
+bool ValidateBindRenderbufferOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ RenderbufferID renderbuffer)
+{
+ if (!context->getExtensions().framebufferObjectOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateBindRenderbufferBase(context, entryPoint, target, renderbuffer);
+}
+
+bool ValidateCheckFramebufferStatusOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target)
+{
+ if (!context->getExtensions().framebufferObjectOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ if (!ValidFramebufferTarget(context, target))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFramebufferTarget);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateFramebufferRenderbufferOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ GLenum rbtarget,
+ RenderbufferID renderbuffer)
+{
+ if (!context->getExtensions().framebufferObjectOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateFramebufferRenderbufferBase(context, entryPoint, target, attachment, rbtarget,
+ renderbuffer);
+}
+
+bool ValidateFramebufferTexture2DOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ TextureTarget textarget,
+ TextureID texture,
+ GLint level)
+{
+ if (!context->getExtensions().framebufferObjectOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ if (level != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidFramebufferTextureLevel);
+ return false;
+ }
+
+ if (!ValidateFramebufferTextureBase(context, entryPoint, target, attachment, texture, level))
+ {
+ return false;
+ }
+
+ if (texture.value != 0)
+ {
+ Texture *tex = context->getTexture(texture);
+ ASSERT(tex);
+
+ const Caps &caps = context->getCaps();
+
+ switch (textarget)
+ {
+ case TextureTarget::_2D:
+ {
+ if (level > log2(caps.max2DTextureSize))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel);
+ return false;
+ }
+ if (tex->getType() != TextureType::_2D)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kInvalidTextureTarget);
+ return false;
+ }
+ }
+ break;
+
+ case TextureTarget::CubeMapNegativeX:
+ case TextureTarget::CubeMapNegativeY:
+ case TextureTarget::CubeMapNegativeZ:
+ case TextureTarget::CubeMapPositiveX:
+ case TextureTarget::CubeMapPositiveY:
+ case TextureTarget::CubeMapPositiveZ:
+ {
+ if (!context->getExtensions().textureCubeMapOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget);
+ return false;
+ }
+
+ if (level > log2(caps.maxCubeMapTextureSize))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel);
+ return false;
+ }
+ if (tex->getType() != TextureType::CubeMap)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kTextureTargetMismatch);
+ return false;
+ }
+ }
+ break;
+
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateGenerateMipmapOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target)
+{
+ if (!context->getExtensions().framebufferObjectOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateGenerateMipmapBase(context, entryPoint, target);
+}
+
+bool ValidateGetFramebufferAttachmentParameterivOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ GLenum pname,
+ const GLint *params)
+{
+ if (!context->getExtensions().framebufferObjectOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateGetFramebufferAttachmentParameterivBase(context, entryPoint, target, attachment,
+ pname, nullptr);
+}
+
+bool ValidateGetRenderbufferParameterivOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum pname,
+ const GLint *params)
+{
+ if (!context->getExtensions().framebufferObjectOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateGetRenderbufferParameterivBase(context, entryPoint, target, pname, nullptr);
+}
+
+bool ValidateIsFramebufferOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ FramebufferID framebuffer)
+{
+ if (!context->getExtensions().framebufferObjectOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateIsRenderbufferOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ RenderbufferID renderbuffer)
+{
+ if (!context->getExtensions().framebufferObjectOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateRenderbufferStorageOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height)
+{
+ if (!context->getExtensions().framebufferObjectOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateRenderbufferStorageParametersBase(context, entryPoint, target, 0, internalformat,
+ width, height);
+}
+
+// GL_OES_texture_cube_map
+
+bool ValidateGetTexGenfvOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum coord,
+ GLenum pname,
+ const GLfloat *params)
+{
+ UNIMPLEMENTED();
+ return true;
+}
+
+bool ValidateGetTexGenivOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum coord,
+ GLenum pname,
+ const int *params)
+{
+ UNIMPLEMENTED();
+ return true;
+}
+
+bool ValidateGetTexGenxvOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum coord,
+ GLenum pname,
+ const GLfixed *params)
+{
+ UNIMPLEMENTED();
+ return true;
+}
+
+bool ValidateTexGenfvOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum coord,
+ GLenum pname,
+ const GLfloat *params)
+{
+ UNIMPLEMENTED();
+ return true;
+}
+
+bool ValidateTexGenivOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum coord,
+ GLenum pname,
+ const GLint *param)
+{
+ UNIMPLEMENTED();
+ return true;
+}
+
+bool ValidateTexGenxvOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum coord,
+ GLenum pname,
+ const GLint *param)
+{
+ UNIMPLEMENTED();
+ return true;
+}
+
+bool ValidateTexGenfOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum coord,
+ GLenum pname,
+ GLfloat param)
+{
+ UNIMPLEMENTED();
+ return true;
+}
+
+bool ValidateTexGeniOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum coord,
+ GLenum pname,
+ GLint param)
+{
+ UNIMPLEMENTED();
+ return true;
+}
+
+bool ValidateTexGenxOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum coord,
+ GLenum pname,
+ GLfixed param)
+{
+ UNIMPLEMENTED();
+ return true;
+}
+
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/validationES1.h b/gfx/angle/checkout/src/libANGLE/validationES1.h
new file mode 100644
index 0000000000..e2e6248400
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/validationES1.h
@@ -0,0 +1,20 @@
+//
+// Copyright 2018 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.
+//
+// validationES1.h:
+// Inlined validation functions for OpenGL ES 1.0 entry points.
+
+#ifndef LIBANGLE_VALIDATION_ES1_H_
+#define LIBANGLE_VALIDATION_ES1_H_
+
+#include "libANGLE/ErrorStrings.h"
+#include "libANGLE/validationES1_autogen.h"
+
+namespace gl
+{
+// Nothing here yet.
+} // namespace gl
+
+#endif // LIBANGLE_VALIDATION_ES1_H_
diff --git a/gfx/angle/checkout/src/libANGLE/validationES1_autogen.h b/gfx/angle/checkout/src/libANGLE/validationES1_autogen.h
new file mode 100644
index 0000000000..81f168e573
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/validationES1_autogen.h
@@ -0,0 +1,395 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml and gl_angle_ext.xml.
+//
+// Copyright 2020 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.
+//
+// validationES1_autogen.h:
+// Validation functions for the OpenGL ES 1.0 entry points.
+
+#ifndef LIBANGLE_VALIDATION_ES1_AUTOGEN_H_
+#define LIBANGLE_VALIDATION_ES1_AUTOGEN_H_
+
+#include "common/PackedEnums.h"
+#include "common/entry_points_enum_autogen.h"
+
+namespace gl
+{
+class Context;
+
+bool ValidateAlphaFunc(const Context *context,
+ angle::EntryPoint entryPoint,
+ AlphaTestFunc funcPacked,
+ GLfloat ref);
+bool ValidateAlphaFuncx(const Context *context,
+ angle::EntryPoint entryPoint,
+ AlphaTestFunc funcPacked,
+ GLfixed ref);
+bool ValidateClearColorx(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfixed red,
+ GLfixed green,
+ GLfixed blue,
+ GLfixed alpha);
+bool ValidateClearDepthx(const Context *context, angle::EntryPoint entryPoint, GLfixed depth);
+bool ValidateClientActiveTexture(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum texture);
+bool ValidateClipPlanef(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum p,
+ const GLfloat *eqn);
+bool ValidateClipPlanex(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum plane,
+ const GLfixed *equation);
+bool ValidateColor4f(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat red,
+ GLfloat green,
+ GLfloat blue,
+ GLfloat alpha);
+bool ValidateColor4ub(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLubyte red,
+ GLubyte green,
+ GLubyte blue,
+ GLubyte alpha);
+bool ValidateColor4x(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfixed red,
+ GLfixed green,
+ GLfixed blue,
+ GLfixed alpha);
+bool ValidateColorPointer(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint size,
+ VertexAttribType typePacked,
+ GLsizei stride,
+ const void *pointer);
+bool ValidateDepthRangex(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfixed n,
+ GLfixed f);
+bool ValidateDisableClientState(const Context *context,
+ angle::EntryPoint entryPoint,
+ ClientVertexArrayType arrayPacked);
+bool ValidateEnableClientState(const Context *context,
+ angle::EntryPoint entryPoint,
+ ClientVertexArrayType arrayPacked);
+bool ValidateFogf(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLfloat param);
+bool ValidateFogfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ const GLfloat *params);
+bool ValidateFogx(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLfixed param);
+bool ValidateFogxv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ const GLfixed *param);
+bool ValidateFrustumf(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat l,
+ GLfloat r,
+ GLfloat b,
+ GLfloat t,
+ GLfloat n,
+ GLfloat f);
+bool ValidateFrustumx(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfixed l,
+ GLfixed r,
+ GLfixed b,
+ GLfixed t,
+ GLfixed n,
+ GLfixed f);
+bool ValidateGetClipPlanef(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum plane,
+ const GLfloat *equation);
+bool ValidateGetClipPlanex(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum plane,
+ const GLfixed *equation);
+bool ValidateGetFixedv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ const GLfixed *params);
+bool ValidateGetLightfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum light,
+ LightParameter pnamePacked,
+ const GLfloat *params);
+bool ValidateGetLightxv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum light,
+ LightParameter pnamePacked,
+ const GLfixed *params);
+bool ValidateGetMaterialfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum face,
+ MaterialParameter pnamePacked,
+ const GLfloat *params);
+bool ValidateGetMaterialxv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum face,
+ MaterialParameter pnamePacked,
+ const GLfixed *params);
+bool ValidateGetTexEnvfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureEnvTarget targetPacked,
+ TextureEnvParameter pnamePacked,
+ const GLfloat *params);
+bool ValidateGetTexEnviv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureEnvTarget targetPacked,
+ TextureEnvParameter pnamePacked,
+ const GLint *params);
+bool ValidateGetTexEnvxv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureEnvTarget targetPacked,
+ TextureEnvParameter pnamePacked,
+ const GLfixed *params);
+bool ValidateGetTexParameterxv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLfixed *params);
+bool ValidateLightModelf(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLfloat param);
+bool ValidateLightModelfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ const GLfloat *params);
+bool ValidateLightModelx(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLfixed param);
+bool ValidateLightModelxv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ const GLfixed *param);
+bool ValidateLightf(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum light,
+ LightParameter pnamePacked,
+ GLfloat param);
+bool ValidateLightfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum light,
+ LightParameter pnamePacked,
+ const GLfloat *params);
+bool ValidateLightx(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum light,
+ LightParameter pnamePacked,
+ GLfixed param);
+bool ValidateLightxv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum light,
+ LightParameter pnamePacked,
+ const GLfixed *params);
+bool ValidateLineWidthx(const Context *context, angle::EntryPoint entryPoint, GLfixed width);
+bool ValidateLoadIdentity(const Context *context, angle::EntryPoint entryPoint);
+bool ValidateLoadMatrixf(const Context *context, angle::EntryPoint entryPoint, const GLfloat *m);
+bool ValidateLoadMatrixx(const Context *context, angle::EntryPoint entryPoint, const GLfixed *m);
+bool ValidateLogicOp(const Context *context,
+ angle::EntryPoint entryPoint,
+ LogicalOperation opcodePacked);
+bool ValidateMaterialf(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum face,
+ MaterialParameter pnamePacked,
+ GLfloat param);
+bool ValidateMaterialfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum face,
+ MaterialParameter pnamePacked,
+ const GLfloat *params);
+bool ValidateMaterialx(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum face,
+ MaterialParameter pnamePacked,
+ GLfixed param);
+bool ValidateMaterialxv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum face,
+ MaterialParameter pnamePacked,
+ const GLfixed *param);
+bool ValidateMatrixMode(const Context *context,
+ angle::EntryPoint entryPoint,
+ MatrixType modePacked);
+bool ValidateMultMatrixf(const Context *context, angle::EntryPoint entryPoint, const GLfloat *m);
+bool ValidateMultMatrixx(const Context *context, angle::EntryPoint entryPoint, const GLfixed *m);
+bool ValidateMultiTexCoord4f(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLfloat s,
+ GLfloat t,
+ GLfloat r,
+ GLfloat q);
+bool ValidateMultiTexCoord4x(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum texture,
+ GLfixed s,
+ GLfixed t,
+ GLfixed r,
+ GLfixed q);
+bool ValidateNormal3f(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat nx,
+ GLfloat ny,
+ GLfloat nz);
+bool ValidateNormal3x(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfixed nx,
+ GLfixed ny,
+ GLfixed nz);
+bool ValidateNormalPointer(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexAttribType typePacked,
+ GLsizei stride,
+ const void *pointer);
+bool ValidateOrthof(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat l,
+ GLfloat r,
+ GLfloat b,
+ GLfloat t,
+ GLfloat n,
+ GLfloat f);
+bool ValidateOrthox(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfixed l,
+ GLfixed r,
+ GLfixed b,
+ GLfixed t,
+ GLfixed n,
+ GLfixed f);
+bool ValidatePointParameterf(const Context *context,
+ angle::EntryPoint entryPoint,
+ PointParameter pnamePacked,
+ GLfloat param);
+bool ValidatePointParameterfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ PointParameter pnamePacked,
+ const GLfloat *params);
+bool ValidatePointParameterx(const Context *context,
+ angle::EntryPoint entryPoint,
+ PointParameter pnamePacked,
+ GLfixed param);
+bool ValidatePointParameterxv(const Context *context,
+ angle::EntryPoint entryPoint,
+ PointParameter pnamePacked,
+ const GLfixed *params);
+bool ValidatePointSize(const Context *context, angle::EntryPoint entryPoint, GLfloat size);
+bool ValidatePointSizex(const Context *context, angle::EntryPoint entryPoint, GLfixed size);
+bool ValidatePolygonOffsetx(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfixed factor,
+ GLfixed units);
+bool ValidatePopMatrix(const Context *context, angle::EntryPoint entryPoint);
+bool ValidatePushMatrix(const Context *context, angle::EntryPoint entryPoint);
+bool ValidateRotatef(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat angle,
+ GLfloat x,
+ GLfloat y,
+ GLfloat z);
+bool ValidateRotatex(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfixed angle,
+ GLfixed x,
+ GLfixed y,
+ GLfixed z);
+bool ValidateSampleCoveragex(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLclampx value,
+ GLboolean invert);
+bool ValidateScalef(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat x,
+ GLfloat y,
+ GLfloat z);
+bool ValidateScalex(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfixed x,
+ GLfixed y,
+ GLfixed z);
+bool ValidateShadeModel(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShadingModel modePacked);
+bool ValidateTexCoordPointer(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint size,
+ VertexAttribType typePacked,
+ GLsizei stride,
+ const void *pointer);
+bool ValidateTexEnvf(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureEnvTarget targetPacked,
+ TextureEnvParameter pnamePacked,
+ GLfloat param);
+bool ValidateTexEnvfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureEnvTarget targetPacked,
+ TextureEnvParameter pnamePacked,
+ const GLfloat *params);
+bool ValidateTexEnvi(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureEnvTarget targetPacked,
+ TextureEnvParameter pnamePacked,
+ GLint param);
+bool ValidateTexEnviv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureEnvTarget targetPacked,
+ TextureEnvParameter pnamePacked,
+ const GLint *params);
+bool ValidateTexEnvx(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureEnvTarget targetPacked,
+ TextureEnvParameter pnamePacked,
+ GLfixed param);
+bool ValidateTexEnvxv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureEnvTarget targetPacked,
+ TextureEnvParameter pnamePacked,
+ const GLfixed *params);
+bool ValidateTexParameterx(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum pname,
+ GLfixed param);
+bool ValidateTexParameterxv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLfixed *params);
+bool ValidateTranslatef(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat x,
+ GLfloat y,
+ GLfloat z);
+bool ValidateTranslatex(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfixed x,
+ GLfixed y,
+ GLfixed z);
+bool ValidateVertexPointer(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint size,
+ VertexAttribType typePacked,
+ GLsizei stride,
+ const void *pointer);
+} // namespace gl
+
+#endif // LIBANGLE_VALIDATION_ES1_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libANGLE/validationES2.cpp b/gfx/angle/checkout/src/libANGLE/validationES2.cpp
new file mode 100644
index 0000000000..00f5fc5502
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/validationES2.cpp
@@ -0,0 +1,6544 @@
+//
+// Copyright 2013 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.
+//
+
+// validationES2.cpp: Validation functions for OpenGL ES 2.0 entry point parameters
+
+#include "libANGLE/validationES2_autogen.h"
+
+#include <cstdint>
+
+#include "common/mathutil.h"
+#include "common/string_utils.h"
+#include "common/utilities.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/ErrorStrings.h"
+#include "libANGLE/Fence.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/MemoryObject.h"
+#include "libANGLE/Renderbuffer.h"
+#include "libANGLE/Shader.h"
+#include "libANGLE/Texture.h"
+#include "libANGLE/Uniform.h"
+#include "libANGLE/VertexArray.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/validationES.h"
+#include "libANGLE/validationES2.h"
+#include "libANGLE/validationES3_autogen.h"
+
+namespace gl
+{
+using namespace err;
+
+namespace
+{
+
+bool IsPartialBlit(const Context *context,
+ const FramebufferAttachment *readBuffer,
+ const FramebufferAttachment *writeBuffer,
+ GLint srcX0,
+ GLint srcY0,
+ GLint srcX1,
+ GLint srcY1,
+ GLint dstX0,
+ GLint dstY0,
+ GLint dstX1,
+ GLint dstY1)
+{
+ const Extents &writeSize = writeBuffer->getSize();
+ const Extents &readSize = readBuffer->getSize();
+
+ if (srcX0 != 0 || srcY0 != 0 || dstX0 != 0 || dstY0 != 0 || dstX1 != writeSize.width ||
+ dstY1 != writeSize.height || srcX1 != readSize.width || srcY1 != readSize.height)
+ {
+ return true;
+ }
+
+ if (context->getState().isScissorTestEnabled())
+ {
+ const Rectangle &scissor = context->getState().getScissor();
+ return scissor.x > 0 || scissor.y > 0 || scissor.width < writeSize.width ||
+ scissor.height < writeSize.height;
+ }
+
+ return false;
+}
+
+bool IsValidCopyTextureSourceInternalFormatEnum(GLenum internalFormat)
+{
+ // Table 1.1 from the CHROMIUM_copy_texture spec
+ switch (GetUnsizedFormat(internalFormat))
+ {
+ case GL_RED:
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ case GL_RGB:
+ case GL_RGBA:
+ case GL_RGB8:
+ case GL_RGBA8:
+ case GL_BGRA_EXT:
+ case GL_BGRA8_EXT:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+bool IsValidCopySubTextureSourceInternalFormat(GLenum internalFormat)
+{
+ return IsValidCopyTextureSourceInternalFormatEnum(internalFormat);
+}
+
+bool IsValidCopyTextureDestinationInternalFormatEnum(GLint internalFormat)
+{
+ // Table 1.0 from the CHROMIUM_copy_texture spec
+ switch (internalFormat)
+ {
+ case GL_ALPHA:
+ case GL_BGRA8_EXT:
+ case GL_BGRA_EXT:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ case GL_R11F_G11F_B10F:
+ case GL_R16F:
+ case GL_R32F:
+ case GL_R8:
+ case GL_R8UI:
+ case GL_RG16F:
+ case GL_RG32F:
+ case GL_RG8:
+ case GL_RG8UI:
+ case GL_RGB:
+ case GL_RGB10_A2:
+ case GL_RGB16F:
+ case GL_RGB32F:
+ case GL_RGB565:
+ case GL_RGB5_A1:
+ case GL_RGB8:
+ case GL_RGB8UI:
+ case GL_RGB9_E5:
+ case GL_RGBA:
+ case GL_RGBA16F:
+ case GL_RGBA32F:
+ case GL_RGBA4:
+ case GL_RGBA8:
+ case GL_RGBA8UI:
+ case GL_RGBX8_ANGLE:
+ case GL_SRGB8:
+ case GL_SRGB8_ALPHA8:
+ case GL_SRGB_ALPHA_EXT:
+ case GL_SRGB_EXT:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+bool IsValidCopySubTextureDestionationInternalFormat(GLenum internalFormat)
+{
+ return IsValidCopyTextureDestinationInternalFormatEnum(internalFormat);
+}
+
+bool IsValidCopyTextureDestinationFormatType(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint internalFormat,
+ GLenum type)
+{
+ if (!IsValidCopyTextureDestinationInternalFormatEnum(internalFormat))
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_OPERATION, kInvalidInternalFormat,
+ internalFormat);
+ return false;
+ }
+
+ if (!ValidES3FormatCombination(GetUnsizedFormat(internalFormat), type, internalFormat))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
+ return false;
+ }
+
+ const InternalFormat &internalFormatInfo = GetInternalFormatInfo(internalFormat, type);
+ if (!internalFormatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_OPERATION, kInvalidInternalFormat,
+ internalFormat);
+ return false;
+ }
+
+ return true;
+}
+
+bool IsValidCopyTextureDestinationTargetEnum(const Context *context, TextureTarget target)
+{
+ switch (target)
+ {
+ case TextureTarget::_2D:
+ case TextureTarget::CubeMapNegativeX:
+ case TextureTarget::CubeMapNegativeY:
+ case TextureTarget::CubeMapNegativeZ:
+ case TextureTarget::CubeMapPositiveX:
+ case TextureTarget::CubeMapPositiveY:
+ case TextureTarget::CubeMapPositiveZ:
+ return true;
+
+ case TextureTarget::Rectangle:
+ return context->getExtensions().textureRectangleANGLE;
+
+ default:
+ return false;
+ }
+}
+
+bool IsValidCopyTextureDestinationTarget(const Context *context,
+ TextureType textureType,
+ TextureTarget target)
+{
+ return TextureTargetToType(target) == textureType;
+}
+
+bool IsValidCopyTextureSourceTarget(const Context *context, TextureType type)
+{
+ switch (type)
+ {
+ case TextureType::_2D:
+ return true;
+ case TextureType::Rectangle:
+ return context->getExtensions().textureRectangleANGLE;
+ case TextureType::External:
+ return context->getExtensions().EGLImageExternalOES;
+ case TextureType::VideoImage:
+ return context->getExtensions().videoTextureWEBGL;
+ default:
+ return false;
+ }
+}
+
+bool IsValidCopyTextureSourceLevel(const Context *context, TextureType type, GLint level)
+{
+ if (!ValidMipLevel(context, type, level))
+ {
+ return false;
+ }
+
+ if (level > 0 && context->getClientVersion() < ES_3_0)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool IsValidCopyTextureDestinationLevel(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType type,
+ GLint level,
+ GLsizei width,
+ GLsizei height,
+ bool isSubImage)
+{
+ if (!ValidMipLevel(context, type, level))
+ {
+ return false;
+ }
+
+ if (!ValidImageSizeParameters(context, entryPoint, type, level, width, height, 1, isSubImage))
+ {
+ return false;
+ }
+
+ const Caps &caps = context->getCaps();
+ switch (type)
+ {
+ case TextureType::_2D:
+ return width <= (caps.max2DTextureSize >> level) &&
+ height <= (caps.max2DTextureSize >> level);
+ case TextureType::Rectangle:
+ ASSERT(level == 0);
+ return width <= (caps.max2DTextureSize >> level) &&
+ height <= (caps.max2DTextureSize >> level);
+
+ case TextureType::CubeMap:
+ return width <= (caps.maxCubeMapTextureSize >> level) &&
+ height <= (caps.maxCubeMapTextureSize >> level);
+ default:
+ return true;
+ }
+}
+
+bool IsValidStencilFunc(GLenum func)
+{
+ switch (func)
+ {
+ case GL_NEVER:
+ case GL_ALWAYS:
+ case GL_LESS:
+ case GL_LEQUAL:
+ case GL_EQUAL:
+ case GL_GEQUAL:
+ case GL_GREATER:
+ case GL_NOTEQUAL:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+bool IsValidStencilFace(GLenum face)
+{
+ switch (face)
+ {
+ case GL_FRONT:
+ case GL_BACK:
+ case GL_FRONT_AND_BACK:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+bool IsValidStencilOp(GLenum op)
+{
+ switch (op)
+ {
+ case GL_ZERO:
+ case GL_KEEP:
+ case GL_REPLACE:
+ case GL_INCR:
+ case GL_DECR:
+ case GL_INVERT:
+ case GL_INCR_WRAP:
+ case GL_DECR_WRAP:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+static inline bool Valid1to4ComponentFloatColorBufferFormat(const Context *context, GLenum format)
+{
+ return (context->getExtensions().textureFloatOES &&
+ (format == GL_RGBA32F || format == GL_RGB32F || format == GL_RG32F ||
+ format == GL_R32F)) ||
+ (context->getExtensions().textureHalfFloatOES &&
+ (format == GL_RGBA16F || format == GL_RGB16F || format == GL_RG16F ||
+ format == GL_R16F));
+}
+
+static inline bool Valid2to4ComponentFloatColorBufferFormat(const Context *context, GLenum format)
+{
+ return (context->getExtensions().textureFloatOES &&
+ (format == GL_RGBA32F || format == GL_RGB32F || format == GL_RG32F)) ||
+ (context->getExtensions().textureHalfFloatOES &&
+ (format == GL_RGBA16F || format == GL_RGB16F || format == GL_RG16F));
+}
+
+static inline bool Valid3to4ComponentFloatColorBufferFormat(const Context *context, GLenum format)
+{
+ return (context->getExtensions().textureFloatOES &&
+ (format == GL_RGBA32F || format == GL_RGB32F)) ||
+ (context->getExtensions().textureHalfFloatOES &&
+ (format == GL_RGBA16F || format == GL_RGB16F));
+}
+
+static inline bool Valid4ComponentFloatColorBufferFormat(const Context *context, GLenum format)
+{
+ return (context->getExtensions().textureFloatOES && format == GL_RGBA32F) ||
+ (context->getExtensions().textureHalfFloatOES && format == GL_RGBA16F);
+}
+
+bool ValidateES2CopyTexImageParameters(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLenum internalformat,
+ bool isSubImage,
+ GLint xoffset,
+ GLint yoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLint border)
+{
+ if (!ValidTexture2DDestinationTarget(context, target))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget);
+ return false;
+ }
+
+ TextureType texType = TextureTargetToType(target);
+ if (!ValidImageSizeParameters(context, entryPoint, texType, level, width, height, 1,
+ isSubImage))
+ {
+ // Error is already handled.
+ return false;
+ }
+
+ Format textureFormat = Format::Invalid();
+ if (!ValidateCopyTexImageParametersBase(context, entryPoint, target, level, internalformat,
+ isSubImage, xoffset, yoffset, 0, x, y, width, height,
+ border, &textureFormat))
+ {
+ return false;
+ }
+
+ ASSERT(textureFormat.valid() || !isSubImage);
+
+ const Framebuffer *framebuffer = context->getState().getReadFramebuffer();
+ GLenum colorbufferFormat =
+ framebuffer->getReadColorAttachment()->getFormat().info->sizedInternalFormat;
+ const auto &formatInfo = *textureFormat.info;
+
+ // ValidateCopyTexImageParametersBase rejects compressed formats with GL_INVALID_OPERATION.
+ ASSERT(!formatInfo.compressed);
+ ASSERT(!GetInternalFormatInfo(internalformat, GL_UNSIGNED_BYTE).compressed);
+
+ // ValidateCopyTexImageParametersBase rejects depth formats with GL_INVALID_OPERATION.
+ ASSERT(!formatInfo.depthBits);
+ ASSERT(!GetInternalFormatInfo(internalformat, GL_UNSIGNED_BYTE).depthBits);
+
+ // [OpenGL ES 2.0.24] table 3.9
+ if (isSubImage)
+ {
+ switch (formatInfo.format)
+ {
+ case GL_ALPHA:
+ if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
+ colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
+ colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX &&
+ !Valid4ComponentFloatColorBufferFormat(context, colorbufferFormat))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormat);
+ return false;
+ }
+ break;
+ case GL_LUMINANCE:
+ if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
+ colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
+ colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
+ colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGRA8_EXT &&
+ colorbufferFormat != GL_BGR5_A1_ANGLEX &&
+ colorbufferFormat != GL_BGRX8_ANGLEX && colorbufferFormat != GL_RGBX8_ANGLE &&
+ !Valid1to4ComponentFloatColorBufferFormat(context, colorbufferFormat))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormat);
+ return false;
+ }
+ break;
+ case GL_RED_EXT:
+ if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
+ colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
+ colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
+ colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_R32F &&
+ colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
+ colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
+ colorbufferFormat != GL_BGR5_A1_ANGLEX &&
+ colorbufferFormat != GL_BGRX8_ANGLEX && colorbufferFormat != GL_RGBX8_ANGLE &&
+ !Valid1to4ComponentFloatColorBufferFormat(context, colorbufferFormat))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormat);
+ return false;
+ }
+ break;
+ case GL_RG_EXT:
+ if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
+ colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
+ colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
+ colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
+ colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
+ colorbufferFormat != GL_BGR5_A1_ANGLEX &&
+ colorbufferFormat != GL_BGRX8_ANGLEX && colorbufferFormat != GL_RGBX8_ANGLE &&
+ !Valid2to4ComponentFloatColorBufferFormat(context, colorbufferFormat))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormat);
+ return false;
+ }
+ break;
+ case GL_RGB:
+ if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
+ colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
+ colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGB32F &&
+ colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
+ colorbufferFormat != GL_BGR5_A1_ANGLEX &&
+ colorbufferFormat != GL_BGRX8_ANGLEX && colorbufferFormat != GL_RGBX8_ANGLE &&
+ !Valid3to4ComponentFloatColorBufferFormat(context, colorbufferFormat))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormat);
+ return false;
+ }
+ break;
+ case GL_LUMINANCE_ALPHA:
+ case GL_RGBA:
+ if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
+ colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGBA32F &&
+ colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX &&
+ !Valid4ComponentFloatColorBufferFormat(context, colorbufferFormat))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormat);
+ return false;
+ }
+ break;
+ default:
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormat);
+ return false;
+ }
+
+ if (formatInfo.type == GL_FLOAT && !context->getExtensions().textureFloatOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormat);
+ return false;
+ }
+ }
+ else
+ {
+ switch (internalformat)
+ {
+ case GL_ALPHA:
+ if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
+ colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
+ colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX &&
+ !Valid4ComponentFloatColorBufferFormat(context, colorbufferFormat))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormat);
+ return false;
+ }
+ break;
+ case GL_LUMINANCE:
+ case GL_RED_EXT:
+ if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
+ colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
+ colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
+ colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
+ colorbufferFormat != GL_BGR5_A1_ANGLEX &&
+ colorbufferFormat != GL_BGRX8_ANGLEX && colorbufferFormat != GL_RGBX8_ANGLE &&
+ !Valid1to4ComponentFloatColorBufferFormat(context, colorbufferFormat))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormat);
+ return false;
+ }
+ break;
+ case GL_RG_EXT:
+ if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
+ colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
+ colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
+ colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX &&
+ colorbufferFormat != GL_BGRX8_ANGLEX && colorbufferFormat != GL_RGBX8_ANGLE &&
+ !Valid2to4ComponentFloatColorBufferFormat(context, colorbufferFormat))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormat);
+ return false;
+ }
+ break;
+ case GL_RGB:
+ if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
+ colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
+ colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
+ colorbufferFormat != GL_BGR5_A1_ANGLEX &&
+ colorbufferFormat != GL_BGRX8_ANGLEX && colorbufferFormat != GL_RGBX8_ANGLE &&
+ !Valid3to4ComponentFloatColorBufferFormat(context, colorbufferFormat))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormat);
+ return false;
+ }
+ break;
+ case GL_LUMINANCE_ALPHA:
+ case GL_RGBA:
+ if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
+ colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
+ colorbufferFormat != GL_BGR5_A1_ANGLEX && colorbufferFormat != GL_RGBA16F &&
+ !Valid4ComponentFloatColorBufferFormat(context, colorbufferFormat))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormat);
+ return false;
+ }
+ break;
+ default:
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported,
+ internalformat);
+ return false;
+ }
+ }
+
+ // If width or height is zero, it is a no-op. Return false without setting an error.
+ return (width > 0 && height > 0);
+}
+
+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().multisampleCompatibilityEXT;
+
+ 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->getClientMajorVersion() >= 3);
+
+ case GL_DEBUG_OUTPUT_SYNCHRONOUS:
+ case GL_DEBUG_OUTPUT:
+ return context->getExtensions().debugKHR;
+
+ case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
+ return queryOnly && context->getExtensions().bindGeneratesResourceCHROMIUM;
+
+ case GL_CLIENT_ARRAYS_ANGLE:
+ return queryOnly && context->getExtensions().clientArraysANGLE;
+
+ case GL_FRAMEBUFFER_SRGB_EXT:
+ return context->getExtensions().sRGBWriteControlEXT;
+
+ case GL_SAMPLE_MASK:
+ return context->getClientVersion() >= Version(3, 1);
+
+ case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
+ return queryOnly && context->getExtensions().robustResourceInitializationANGLE;
+
+ case GL_TEXTURE_RECTANGLE_ANGLE:
+ return context->isWebGL();
+
+ // GL_APPLE_clip_distance/GL_EXT_clip_cull_distance
+ case GL_CLIP_DISTANCE0_EXT:
+ case GL_CLIP_DISTANCE1_EXT:
+ case GL_CLIP_DISTANCE2_EXT:
+ case GL_CLIP_DISTANCE3_EXT:
+ case GL_CLIP_DISTANCE4_EXT:
+ case GL_CLIP_DISTANCE5_EXT:
+ case GL_CLIP_DISTANCE6_EXT:
+ case GL_CLIP_DISTANCE7_EXT:
+ if (context->getExtensions().clipDistanceAPPLE ||
+ context->getExtensions().clipCullDistanceEXT)
+ {
+ return true;
+ }
+ break;
+ case GL_SAMPLE_SHADING:
+ return context->getExtensions().sampleShadingOES;
+ case GL_SHADING_RATE_PRESERVE_ASPECT_RATIO_QCOM:
+ return context->getExtensions().shadingRateQCOM;
+
+ // COLOR_LOGIC_OP is in GLES1, but exposed through an ANGLE extension.
+ case GL_COLOR_LOGIC_OP:
+ return context->getClientVersion() < Version(2, 0) ||
+ context->getExtensions().logicOpANGLE;
+
+ default:
+ break;
+ }
+
+ // GLES1 emulation: GLES1-specific caps after this point
+ if (context->getClientVersion().major != 1)
+ {
+ return false;
+ }
+
+ switch (cap)
+ {
+ case GL_ALPHA_TEST:
+ case GL_VERTEX_ARRAY:
+ case GL_NORMAL_ARRAY:
+ case GL_COLOR_ARRAY:
+ case GL_TEXTURE_COORD_ARRAY:
+ case GL_TEXTURE_2D:
+ case GL_LIGHTING:
+ case GL_LIGHT0:
+ case GL_LIGHT1:
+ case GL_LIGHT2:
+ case GL_LIGHT3:
+ case GL_LIGHT4:
+ case GL_LIGHT5:
+ case GL_LIGHT6:
+ case GL_LIGHT7:
+ case GL_NORMALIZE:
+ case GL_RESCALE_NORMAL:
+ case GL_COLOR_MATERIAL:
+ case GL_CLIP_PLANE0:
+ case GL_CLIP_PLANE1:
+ case GL_CLIP_PLANE2:
+ case GL_CLIP_PLANE3:
+ case GL_CLIP_PLANE4:
+ case GL_CLIP_PLANE5:
+ case GL_FOG:
+ case GL_POINT_SMOOTH:
+ case GL_LINE_SMOOTH:
+ return context->getClientVersion() < Version(2, 0);
+ case GL_POINT_SIZE_ARRAY_OES:
+ return context->getClientVersion() < Version(2, 0) &&
+ context->getExtensions().pointSizeArrayOES;
+ case GL_TEXTURE_CUBE_MAP:
+ return context->getClientVersion() < Version(2, 0) &&
+ context->getExtensions().textureCubeMapOES;
+ case GL_POINT_SPRITE_OES:
+ return context->getClientVersion() < Version(2, 0) &&
+ context->getExtensions().pointSpriteOES;
+ default:
+ return false;
+ }
+}
+
+// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
+// 3.1.
+bool IsValidESSLCharacter(unsigned char c)
+{
+ // Printing characters are valid except " $ ` @ \ ' DEL.
+ if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
+ c != '\'')
+ {
+ return true;
+ }
+
+ // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
+ if (c >= 9 && c <= 13)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+bool IsValidESSLString(const char *str, size_t len)
+{
+ for (size_t i = 0; i < len; i++)
+ {
+ if (!IsValidESSLCharacter(str[i]))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateWebGLNamePrefix(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLchar *name)
+{
+ ASSERT(context->isWebGL());
+
+ // WebGL 1.0 [Section 6.16] GLSL Constructs
+ // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL.
+ if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kWebglBindAttribLocationReservedPrefix);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateWebGLNameLength(const Context *context, angle::EntryPoint entryPoint, size_t length)
+{
+ ASSERT(context->isWebGL());
+
+ if (context->isWebGL1() && length > 256)
+ {
+ // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths
+ // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute
+ // locations.
+ context->validationError(entryPoint, GL_INVALID_VALUE, kWebglNameLengthLimitExceeded);
+
+ return false;
+ }
+ else if (length > 1024)
+ {
+ // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of
+ // uniform and attribute locations.
+ context->validationError(entryPoint, GL_INVALID_VALUE, kWebgl2NameLengthLimitExceeded);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidBlendFunc(const Context *context, GLenum val)
+{
+ const Extensions &ext = context->getExtensions();
+
+ // these are always valid for src and dst.
+ switch (val)
+ {
+ 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:
+ return true;
+
+ // EXT_blend_func_extended.
+ case GL_SRC1_COLOR_EXT:
+ case GL_SRC1_ALPHA_EXT:
+ case GL_ONE_MINUS_SRC1_COLOR_EXT:
+ case GL_ONE_MINUS_SRC1_ALPHA_EXT:
+ case GL_SRC_ALPHA_SATURATE_EXT:
+ return ext.blendFuncExtendedEXT;
+
+ default:
+ return false;
+ }
+}
+
+bool ValidSrcBlendFunc(const Context *context, GLenum val)
+{
+ if (ValidBlendFunc(context, val))
+ return true;
+
+ if (val == GL_SRC_ALPHA_SATURATE)
+ return true;
+
+ return false;
+}
+
+bool ValidDstBlendFunc(const Context *context, GLenum val)
+{
+ if (ValidBlendFunc(context, val))
+ return true;
+
+ if (val == GL_SRC_ALPHA_SATURATE)
+ {
+ if (context->getClientMajorVersion() >= 3)
+ return true;
+ }
+
+ return false;
+}
+
+bool ValidateES2TexImageParameters(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget 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 void *pixels)
+{
+ if (!ValidTexture2DDestinationTarget(context, target))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget);
+ return false;
+ }
+
+ return ValidateES2TexImageParametersBase(context, entryPoint, target, level, internalformat,
+ isCompressed, isSubImage, xoffset, yoffset, width,
+ height, border, format, type, imageSize, pixels);
+}
+
+} // anonymous namespace
+
+bool ValidateES2TexImageParametersBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget 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 void *pixels)
+{
+
+ TextureType texType = TextureTargetToType(target);
+ if (!ValidImageSizeParameters(context, entryPoint, texType, level, width, height, 1,
+ isSubImage))
+ {
+ // Error already handled.
+ return false;
+ }
+
+ if (!ValidMipLevel(context, texType, level))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel);
+ return false;
+ }
+
+ if ((xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width) ||
+ (yoffset < 0 || std::numeric_limits<GLsizei>::max() - yoffset < height))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize);
+ return false;
+ }
+
+ const Caps &caps = context->getCaps();
+
+ switch (texType)
+ {
+ case TextureType::_2D:
+ case TextureType::External:
+ case TextureType::VideoImage:
+ if (width > (caps.max2DTextureSize >> level) ||
+ height > (caps.max2DTextureSize >> level))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize);
+ return false;
+ }
+ break;
+
+ case TextureType::Rectangle:
+ ASSERT(level == 0);
+ if (width > caps.maxRectangleTextureSize || height > caps.maxRectangleTextureSize)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize);
+ return false;
+ }
+ if (isCompressed)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kRectangleTextureCompressed);
+ return false;
+ }
+ break;
+
+ case TextureType::CubeMap:
+ if (!isSubImage && width != height)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kCubemapFacesEqualDimensions);
+ return false;
+ }
+
+ if (width > (caps.maxCubeMapTextureSize >> level) ||
+ height > (caps.maxCubeMapTextureSize >> level))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize);
+ return false;
+ }
+ break;
+
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget);
+ return false;
+ }
+
+ Texture *texture = context->getTextureByType(texType);
+ if (!texture)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferNotBound);
+ return false;
+ }
+
+ // Verify zero border
+ if (border != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidBorder);
+ return false;
+ }
+
+ bool nonEqualFormatsAllowed = false;
+
+ if (isCompressed)
+ {
+ GLenum actualInternalFormat =
+ isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
+ : internalformat;
+
+ const InternalFormat &internalFormatInfo = GetSizedInternalFormatInfo(actualInternalFormat);
+
+ if (!internalFormatInfo.compressed && !internalFormatInfo.paletted)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kInvalidInternalFormat,
+ internalformat);
+ return false;
+ }
+
+ if (!internalFormatInfo.textureSupport(context->getClientVersion(),
+ context->getExtensions()))
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kInvalidInternalFormat,
+ internalformat);
+ return false;
+ }
+
+ if (isSubImage)
+ {
+ // From OpenGL ES Version 1.1.12, section 3.7.4 Compressed Paletted
+ // Textures:
+ //
+ // Subimages may not be specified for compressed paletted textures.
+ // Calling CompressedTexSubImage2D with any of the PALETTE*
+ // arguments in table 3.11 will generate an INVALID OPERATION error.
+ if (internalFormatInfo.paletted)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_OPERATION, kInvalidInternalFormat,
+ internalformat);
+ return false;
+ }
+
+ // From the OES_compressed_ETC1_RGB8_texture spec:
+ //
+ // INVALID_OPERATION is generated by CompressedTexSubImage2D, TexSubImage2D, or
+ // CopyTexSubImage2D if the texture image <level> bound to <target> has internal format
+ // ETC1_RGB8_OES.
+ //
+ // This is relaxed if GL_EXT_compressed_ETC1_RGB8_sub_texture is supported.
+ if (IsETC1Format(actualInternalFormat) &&
+ !context->getExtensions().compressedETC1RGB8SubTextureEXT)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_OPERATION, kInvalidInternalFormat,
+ internalformat);
+ return false;
+ }
+
+ if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, 0,
+ width, height, 1, texture->getWidth(target, level),
+ texture->getHeight(target, level),
+ texture->getDepth(target, level)))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kInvalidCompressedImageSize);
+ return false;
+ }
+
+ if (format != actualInternalFormat)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormat);
+ return false;
+ }
+ }
+ else
+ {
+ if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height, 1))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kInvalidCompressedImageSize);
+ return false;
+ }
+ }
+ }
+ else
+ {
+ // validate <type> by itself (used as secondary key below)
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ case GL_UNSIGNED_SHORT_5_6_5:
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ case GL_UNSIGNED_SHORT:
+ case GL_UNSIGNED_INT:
+ case GL_UNSIGNED_INT_24_8_OES:
+ case GL_HALF_FLOAT_OES:
+ case GL_FLOAT:
+ break;
+ case GL_UNSIGNED_INT_2_10_10_10_REV_EXT:
+ if (!context->getExtensions().textureType2101010REVEXT)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, type);
+ return false;
+ }
+ break;
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidType);
+ return false;
+ }
+
+ // validate <format> + <type> combinations
+ // - invalid <format> -> sets INVALID_ENUM
+ // - invalid <format>+<type> combination -> sets INVALID_OPERATION
+ switch (format)
+ {
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ case GL_FLOAT:
+ case GL_HALF_FLOAT_OES:
+ break;
+ default:
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kMismatchedTypeAndFormat);
+ return false;
+ }
+ break;
+ case GL_RED:
+ case GL_RG:
+ if (!context->getExtensions().textureRgEXT)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported,
+ format);
+ return false;
+ }
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ break;
+ case GL_FLOAT:
+ if (!context->getExtensions().textureFloatOES)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM,
+ kEnumNotSupported, type);
+ return false;
+ }
+ break;
+ case GL_HALF_FLOAT_OES:
+ if (!context->getExtensions().textureFloatOES &&
+ !context->getExtensions().textureHalfFloatOES)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM,
+ kEnumNotSupported, type);
+ return false;
+ }
+ break;
+ case GL_SHORT:
+ case GL_UNSIGNED_SHORT:
+ if (!context->getExtensions().textureNorm16EXT)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM,
+ kEnumNotSupported, type);
+ return false;
+ }
+ break;
+ default:
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kMismatchedTypeAndFormat);
+ return false;
+ }
+ break;
+ case GL_RGB:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ case GL_UNSIGNED_SHORT_5_6_5:
+ case GL_UNSIGNED_INT_2_10_10_10_REV_EXT:
+ case GL_FLOAT:
+ case GL_HALF_FLOAT_OES:
+ break;
+ case GL_SHORT:
+ case GL_UNSIGNED_SHORT:
+ if (!context->getExtensions().textureNorm16EXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kMismatchedTypeAndFormat);
+ return false;
+ }
+ break;
+ default:
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kMismatchedTypeAndFormat);
+ return false;
+ }
+ break;
+ case GL_RGBA:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ case GL_FLOAT:
+ case GL_HALF_FLOAT_OES:
+ case GL_UNSIGNED_INT_2_10_10_10_REV_EXT:
+ break;
+ case GL_SHORT:
+ case GL_UNSIGNED_SHORT:
+ if (!context->getExtensions().textureNorm16EXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kMismatchedTypeAndFormat);
+ return false;
+ }
+ break;
+ default:
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kMismatchedTypeAndFormat);
+ return false;
+ }
+ break;
+ case GL_BGRA_EXT:
+ if (!context->getExtensions().textureFormatBGRA8888EXT)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported,
+ format);
+ return false;
+ }
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ break;
+ default:
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kMismatchedTypeAndFormat);
+ return false;
+ }
+ break;
+ case GL_SRGB_EXT:
+ case GL_SRGB_ALPHA_EXT:
+ if (!context->getExtensions().sRGBEXT)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported,
+ format);
+ return false;
+ }
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ break;
+ default:
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kMismatchedTypeAndFormat);
+ return false;
+ }
+ break;
+ case GL_DEPTH_COMPONENT:
+ switch (type)
+ {
+ case GL_UNSIGNED_SHORT:
+ case GL_UNSIGNED_INT:
+ break;
+ case GL_FLOAT:
+ if (!context->getExtensions().depthBufferFloat2NV)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kMismatchedTypeAndFormat);
+ return false;
+ }
+ break;
+ default:
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kMismatchedTypeAndFormat);
+ return false;
+ }
+ break;
+ case GL_DEPTH_STENCIL_OES:
+ switch (type)
+ {
+ case GL_UNSIGNED_INT_24_8_OES:
+ break;
+ default:
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kMismatchedTypeAndFormat);
+ return false;
+ }
+ break;
+ case GL_STENCIL_INDEX:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ break;
+ default:
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kMismatchedTypeAndFormat);
+ return false;
+ }
+ break;
+ default:
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, format);
+ return false;
+ }
+
+ switch (format)
+ {
+ case GL_DEPTH_COMPONENT:
+ case GL_DEPTH_STENCIL_OES:
+ if (!context->getExtensions().depthTextureANGLE &&
+ !((context->getExtensions().packedDepthStencilOES ||
+ context->getExtensions().depthTextureCubeMapOES) &&
+ context->getExtensions().depthTextureOES))
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported,
+ format);
+ return false;
+ }
+
+ switch (target)
+ {
+ case TextureTarget::_2D:
+ break;
+ case TextureTarget::CubeMapNegativeX:
+ case TextureTarget::CubeMapNegativeY:
+ case TextureTarget::CubeMapNegativeZ:
+ case TextureTarget::CubeMapPositiveX:
+ case TextureTarget::CubeMapPositiveY:
+ case TextureTarget::CubeMapPositiveZ:
+ if (!context->getExtensions().depthTextureCubeMapOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kMismatchedTargetAndFormat);
+ return false;
+ }
+ break;
+ default:
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kMismatchedTargetAndFormat);
+ return false;
+ }
+
+ // OES_depth_texture supports loading depth data and multiple levels,
+ // but ANGLE_depth_texture does not
+ if (!context->getExtensions().depthTextureOES)
+ {
+ if (pixels != nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kPixelDataNotNull);
+ return false;
+ }
+ if (level != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kLevelNotZero);
+ return false;
+ }
+ }
+ break;
+ case GL_STENCIL_INDEX:
+ if (!context->getExtensions().textureStencil8OES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormat);
+ return false;
+ }
+
+ switch (target)
+ {
+ case TextureTarget::_2D:
+ case TextureTarget::_2DArray:
+ case TextureTarget::CubeMapNegativeX:
+ case TextureTarget::CubeMapNegativeY:
+ case TextureTarget::CubeMapNegativeZ:
+ case TextureTarget::CubeMapPositiveX:
+ case TextureTarget::CubeMapPositiveY:
+ case TextureTarget::CubeMapPositiveZ:
+ break;
+ default:
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kMismatchedTargetAndFormat);
+ return false;
+ }
+
+ if (internalformat != GL_STENCIL_INDEX8)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kMismatchedTargetAndFormat);
+ return false;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (!isSubImage)
+ {
+ switch (internalformat)
+ {
+ // Core ES 2.0 formats
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ case GL_RGB:
+ case GL_RGBA:
+ break;
+
+ case GL_RGBA32F:
+ if (!context->getExtensions().colorBufferFloatRgbaCHROMIUM)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat);
+ return false;
+ }
+
+ nonEqualFormatsAllowed = true;
+
+ if (type != GL_FLOAT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kMismatchedTypeAndFormat);
+ return false;
+ }
+ if (format != GL_RGBA)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kMismatchedTypeAndFormat);
+ return false;
+ }
+ break;
+
+ case GL_RGB32F:
+ if (!context->getExtensions().colorBufferFloatRgbCHROMIUM)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat);
+ return false;
+ }
+
+ nonEqualFormatsAllowed = true;
+
+ if (type != GL_FLOAT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kMismatchedTypeAndFormat);
+ return false;
+ }
+ if (format != GL_RGB)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kMismatchedTypeAndFormat);
+ return false;
+ }
+ break;
+
+ case GL_BGRA_EXT:
+ if (!context->getExtensions().textureFormatBGRA8888EXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat);
+ return false;
+ }
+ break;
+
+ case GL_DEPTH_COMPONENT:
+ if (!(context->getExtensions().depthTextureAny()))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat);
+ return false;
+ }
+ break;
+
+ case GL_DEPTH_STENCIL:
+ if (!(context->getExtensions().depthTextureANGLE ||
+ context->getExtensions().packedDepthStencilOES ||
+ context->getExtensions().depthTextureCubeMapOES))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat);
+ return false;
+ }
+ break;
+
+ case GL_STENCIL_INDEX8:
+ if (!context->getExtensions().textureStencil8OES)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat);
+ return false;
+ }
+ break;
+
+ case GL_RED:
+ case GL_RG:
+ if (!context->getExtensions().textureRgEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat);
+ return false;
+ }
+ break;
+
+ case GL_SRGB_EXT:
+ case GL_SRGB_ALPHA_EXT:
+ if (!context->getExtensions().sRGBEXT)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported,
+ internalformat);
+ return false;
+ }
+ break;
+
+ case GL_RGB10_A2_EXT:
+ if (!context->getExtensions().textureType2101010REVEXT)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported,
+ internalformat);
+ return false;
+ }
+
+ if (type != GL_UNSIGNED_INT_2_10_10_10_REV_EXT || format != GL_RGBA)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kMismatchedTypeAndFormat);
+ return false;
+ }
+
+ nonEqualFormatsAllowed = true;
+
+ break;
+
+ case GL_RGB5_A1:
+ if (context->getExtensions().textureType2101010REVEXT &&
+ type == GL_UNSIGNED_INT_2_10_10_10_REV_EXT && format == GL_RGBA)
+ {
+ nonEqualFormatsAllowed = true;
+ }
+
+ break;
+
+ case GL_RGBX8_ANGLE:
+ if (context->getExtensions().rgbxInternalFormatANGLE &&
+ type == GL_UNSIGNED_BYTE && format == GL_RGB)
+ {
+ nonEqualFormatsAllowed = true;
+ }
+
+ break;
+
+ case GL_R16_EXT:
+ case GL_RG16_EXT:
+ case GL_RGB16_EXT:
+ case GL_RGBA16_EXT:
+ case GL_R16_SNORM_EXT:
+ case GL_RG16_SNORM_EXT:
+ case GL_RGB16_SNORM_EXT:
+ case GL_RGBA16_SNORM_EXT:
+ if (!context->getExtensions().textureNorm16EXT)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported,
+ internalformat);
+ return false;
+ }
+ break;
+ default:
+ // Compressed formats are not valid internal formats for glTexImage*D
+ context->validationErrorF(entryPoint, GL_INVALID_VALUE, kInvalidInternalFormat,
+ internalformat);
+ return false;
+ }
+ }
+
+ if (type == GL_FLOAT)
+ {
+ if (!context->getExtensions().textureFloatOES)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, type);
+ return false;
+ }
+ }
+ else if (type == GL_HALF_FLOAT_OES)
+ {
+ if (!context->getExtensions().textureHalfFloatOES)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, type);
+ return false;
+ }
+ }
+ }
+
+ if (isSubImage)
+ {
+ const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
+ if (textureInternalFormat.internalFormat == GL_NONE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidTextureLevel);
+ return false;
+ }
+
+ if (format != textureInternalFormat.format)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, err::kTextureFormatMismatch);
+ return false;
+ }
+
+ if (context->isWebGL())
+ {
+ if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
+ textureInternalFormat.sizedInternalFormat)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kTextureTypeMismatch);
+ return false;
+ }
+ }
+
+ if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
+ static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kOffsetOverflow);
+ return false;
+ }
+
+ if (width > 0 && height > 0 && pixels == nullptr &&
+ context->getState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kPixelDataNull);
+ return false;
+ }
+ }
+ else
+ {
+ if (texture->getImmutableFormat())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kTextureIsImmutable);
+ return false;
+ }
+ }
+
+ // From GL_CHROMIUM_color_buffer_float_rgb[a]:
+ // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
+ // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
+ // internalformat parameter and format parameter of TexImage2D must match is lifted for this
+ // case.
+ if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormatCombination);
+ return false;
+ }
+
+ GLenum sizeCheckFormat = isSubImage ? format : internalformat;
+ return ValidImageDataSize(context, entryPoint, texType, width, height, 1, sizeCheckFormat, type,
+ pixels, imageSize);
+}
+
+bool ValidateES2TexStorageParametersBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height)
+{
+ if (target != TextureType::_2D && target != TextureType::CubeMap &&
+ target != TextureType::Rectangle)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget);
+ return false;
+ }
+
+ if (width < 1 || height < 1 || levels < 1)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kTextureSizeTooSmall);
+ return false;
+ }
+
+ if (target == TextureType::CubeMap && width != height)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kCubemapFacesEqualDimensions);
+ return false;
+ }
+
+ if (levels != 1 && levels != log2(std::max(width, height)) + 1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidMipLevels);
+ return false;
+ }
+
+ const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
+ if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat);
+ return false;
+ }
+
+ const Caps &caps = context->getCaps();
+
+ switch (target)
+ {
+ case TextureType::_2D:
+ if (width > caps.max2DTextureSize || height > caps.max2DTextureSize)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize);
+ return false;
+ }
+ break;
+ case TextureType::Rectangle:
+ if (levels != 1)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel);
+ return false;
+ }
+
+ if (width > caps.maxRectangleTextureSize || height > caps.maxRectangleTextureSize)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize);
+ return false;
+ }
+ if (formatInfo.compressed)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kRectangleTextureCompressed);
+ return false;
+ }
+ break;
+ case TextureType::CubeMap:
+ if (width > caps.maxCubeMapTextureSize || height > caps.maxCubeMapTextureSize)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize);
+ return false;
+ }
+ break;
+ case TextureType::InvalidEnum:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kEnumInvalid);
+ return false;
+ default:
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported,
+ ToGLenum(target));
+ return false;
+ }
+
+ if (levels != 1 && !context->getExtensions().textureNpotOES)
+ {
+ if (!isPow2(width) || !isPow2(height))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kDimensionsMustBePow2);
+ return false;
+ }
+ }
+
+ if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat);
+ return false;
+ }
+
+ // Even with OES_texture_npot, some compressed formats may impose extra restrictions.
+ if (formatInfo.compressed)
+ {
+ if (!ValidCompressedImageSize(context, formatInfo.internalFormat, 0, width, height, 1))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidCompressedImageSize);
+ return false;
+ }
+ }
+
+ switch (internalformat)
+ {
+ case GL_DEPTH_COMPONENT16:
+ case GL_DEPTH_COMPONENT32_OES:
+ switch (target)
+ {
+ case TextureType::_2D:
+ break;
+ case TextureType::CubeMap:
+ if (!context->getExtensions().depthTextureCubeMapOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kInvalidTextureTarget);
+ return false;
+ }
+ break;
+ default:
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kInvalidTextureTarget);
+ return false;
+ }
+
+ // ANGLE_depth_texture only supports 1-level textures
+ if (!context->getExtensions().depthTextureOES)
+ {
+ if (levels != 1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidMipLevels);
+ return false;
+ }
+ }
+ break;
+ case GL_DEPTH24_STENCIL8_OES:
+ switch (target)
+ {
+ case TextureType::_2D:
+ break;
+ case TextureType::CubeMap:
+ if (!context->getExtensions().depthTextureCubeMapOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kInvalidTextureTarget);
+ return false;
+ }
+ break;
+ default:
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kInvalidTextureTarget);
+ return false;
+ }
+
+ if (!context->getExtensions().packedDepthStencilOES &&
+ !context->getExtensions().depthTextureCubeMapOES)
+ {
+ // ANGLE_depth_texture only supports 1-level textures
+ if (levels != 1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidMipLevels);
+ return false;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ Texture *texture = context->getTextureByType(target);
+ if (!texture || texture->id().value == 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kMissingTexture);
+ return false;
+ }
+
+ if (texture->getImmutableFormat())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kTextureIsImmutable);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateDiscardFramebufferEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLsizei numAttachments,
+ const GLenum *attachments)
+{
+ if (!context->getExtensions().discardFramebufferEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ bool defaultFramebuffer = false;
+
+ switch (target)
+ {
+ case GL_FRAMEBUFFER:
+ defaultFramebuffer =
+ (context->getState().getTargetFramebuffer(GL_FRAMEBUFFER)->isDefault());
+ break;
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFramebufferTarget);
+ return false;
+ }
+
+ return ValidateDiscardFramebufferBase(context, entryPoint, target, numAttachments, attachments,
+ defaultFramebuffer);
+}
+
+bool ValidateBindVertexArrayOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexArrayID array)
+{
+ if (!context->getExtensions().vertexArrayObjectOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateBindVertexArrayBase(context, entryPoint, array);
+}
+
+bool ValidateDeleteVertexArraysOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const VertexArrayID *arrays)
+{
+ if (!context->getExtensions().vertexArrayObjectOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateGenOrDelete(context, entryPoint, n);
+}
+
+bool ValidateGenVertexArraysOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const VertexArrayID *arrays)
+{
+ if (!context->getExtensions().vertexArrayObjectOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateGenOrDelete(context, entryPoint, n);
+}
+
+bool ValidateIsVertexArrayOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexArrayID array)
+{
+ if (!context->getExtensions().vertexArrayObjectOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateProgramBinaryOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLenum binaryFormat,
+ const void *binary,
+ GLint length)
+{
+ if (!context->getExtensions().getProgramBinaryOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateProgramBinaryBase(context, entryPoint, program, binaryFormat, binary, length);
+}
+
+bool ValidateGetProgramBinaryOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLenum *binaryFormat,
+ const void *binary)
+{
+ if (!context->getExtensions().getProgramBinaryOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateGetProgramBinaryBase(context, entryPoint, program, bufSize, length, binaryFormat,
+ binary);
+}
+
+static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
+{
+ switch (source)
+ {
+ case GL_DEBUG_SOURCE_API:
+ case GL_DEBUG_SOURCE_SHADER_COMPILER:
+ case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
+ case GL_DEBUG_SOURCE_OTHER:
+ // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
+ return !mustBeThirdPartyOrApplication;
+
+ case GL_DEBUG_SOURCE_THIRD_PARTY:
+ case GL_DEBUG_SOURCE_APPLICATION:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+static bool ValidDebugType(GLenum type)
+{
+ switch (type)
+ {
+ case GL_DEBUG_TYPE_ERROR:
+ case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
+ case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
+ case GL_DEBUG_TYPE_PERFORMANCE:
+ case GL_DEBUG_TYPE_PORTABILITY:
+ case GL_DEBUG_TYPE_OTHER:
+ case GL_DEBUG_TYPE_MARKER:
+ case GL_DEBUG_TYPE_PUSH_GROUP:
+ case GL_DEBUG_TYPE_POP_GROUP:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+static bool ValidDebugSeverity(GLenum severity)
+{
+ switch (severity)
+ {
+ case GL_DEBUG_SEVERITY_HIGH:
+ case GL_DEBUG_SEVERITY_MEDIUM:
+ case GL_DEBUG_SEVERITY_LOW:
+ case GL_DEBUG_SEVERITY_NOTIFICATION:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+bool ValidateDebugMessageControlKHR(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum source,
+ GLenum type,
+ GLenum severity,
+ GLsizei count,
+ const GLuint *ids,
+ GLboolean enabled)
+{
+ if (!context->getExtensions().debugKHR)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidDebugSource);
+ return false;
+ }
+
+ if (!ValidDebugType(type) && type != GL_DONT_CARE)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidDebugType);
+ return false;
+ }
+
+ if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidDebugSeverity);
+ return false;
+ }
+
+ if (count > 0)
+ {
+ if (source == GL_DONT_CARE || type == GL_DONT_CARE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidDebugSourceType);
+ return false;
+ }
+
+ if (severity != GL_DONT_CARE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidDebugSeverity);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateDebugMessageInsertKHR(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum source,
+ GLenum type,
+ GLuint id,
+ GLenum severity,
+ GLsizei length,
+ const GLchar *buf)
+{
+ if (!context->getExtensions().debugKHR)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ if (!context->getState().getDebug().isOutputEnabled())
+ {
+ // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
+ // not generate an error.
+ return false;
+ }
+
+ if (!ValidDebugSeverity(severity))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidDebugSource);
+ return false;
+ }
+
+ if (!ValidDebugType(type))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidDebugType);
+ return false;
+ }
+
+ if (!ValidDebugSource(source, true))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidDebugSource);
+ return false;
+ }
+
+ size_t messageLength = (length < 0) ? strlen(buf) : length;
+ if (messageLength > context->getCaps().maxDebugMessageLength)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsMaxDebugMessageLength);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateDebugMessageCallbackKHR(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLDEBUGPROCKHR callback,
+ const void *userParam)
+{
+ if (!context->getExtensions().debugKHR)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetDebugMessageLogKHR(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint count,
+ GLsizei bufSize,
+ const GLenum *sources,
+ const GLenum *types,
+ const GLuint *ids,
+ const GLenum *severities,
+ const GLsizei *lengths,
+ const GLchar *messageLog)
+{
+ if (!context->getExtensions().debugKHR)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ if (bufSize < 0 && messageLog != nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBufferSize);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidatePushDebugGroupKHR(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum source,
+ GLuint id,
+ GLsizei length,
+ const GLchar *message)
+{
+ if (!context->getExtensions().debugKHR)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ if (!ValidDebugSource(source, true))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidDebugSource);
+ return false;
+ }
+
+ size_t messageLength = (length < 0) ? strlen(message) : length;
+ if (messageLength > context->getCaps().maxDebugMessageLength)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsMaxDebugMessageLength);
+ return false;
+ }
+
+ size_t currentStackSize = context->getState().getDebug().getGroupStackDepth();
+ if (currentStackSize >= context->getCaps().maxDebugGroupStackDepth)
+ {
+ context->validationError(entryPoint, GL_STACK_OVERFLOW, kExceedsMaxDebugGroupStackDepth);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidatePopDebugGroupKHR(const Context *context, angle::EntryPoint entryPoint)
+{
+ if (!context->getExtensions().debugKHR)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ size_t currentStackSize = context->getState().getDebug().getGroupStackDepth();
+ if (currentStackSize <= 1)
+ {
+ context->validationError(entryPoint, GL_STACK_UNDERFLOW, kCannotPopDefaultDebugGroup);
+ return false;
+ }
+
+ return true;
+}
+
+static bool ValidateObjectIdentifierAndName(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum identifier,
+ GLuint name)
+{
+ switch (identifier)
+ {
+ case GL_BUFFER:
+ if (context->getBuffer({name}) == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidBufferName);
+ return false;
+ }
+ return true;
+
+ case GL_SHADER:
+ if (context->getShader({name}) == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidShaderName);
+ return false;
+ }
+ return true;
+
+ case GL_PROGRAM:
+ if (context->getProgramNoResolveLink({name}) == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidProgramName);
+ return false;
+ }
+ return true;
+
+ case GL_VERTEX_ARRAY:
+ if (context->getVertexArray({name}) == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidVertexArrayName);
+ return false;
+ }
+ return true;
+
+ case GL_QUERY:
+ if (context->getQuery({name}) == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidQueryName);
+ return false;
+ }
+ return true;
+
+ case GL_TRANSFORM_FEEDBACK:
+ if (context->getTransformFeedback({name}) == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kInvalidTransformFeedbackName);
+ return false;
+ }
+ return true;
+
+ case GL_SAMPLER:
+ if (context->getSampler({name}) == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidSamplerName);
+ return false;
+ }
+ return true;
+
+ case GL_TEXTURE:
+ if (context->getTexture({name}) == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidTextureName);
+ return false;
+ }
+ return true;
+
+ case GL_RENDERBUFFER:
+ if (!context->isRenderbuffer({name}))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidRenderbufferName);
+ return false;
+ }
+ return true;
+
+ case GL_FRAMEBUFFER:
+ if (context->getFramebuffer({name}) == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidFramebufferName);
+ return false;
+ }
+ return true;
+
+ case GL_PROGRAM_PIPELINE:
+ if (context->getProgramPipeline({name}) == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidProgramPipelineName);
+ return false;
+ }
+ return true;
+
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidIndentifier);
+ return false;
+ }
+}
+
+static bool ValidateLabelLength(const Context *context,
+ angle::EntryPoint entryPoint,
+ 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->getCaps().maxLabelLength)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsMaxLabelLength);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateObjectLabelKHR(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum identifier,
+ GLuint name,
+ GLsizei length,
+ const GLchar *label)
+{
+ if (!context->getExtensions().debugKHR)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ if (!ValidateObjectIdentifierAndName(context, entryPoint, identifier, name))
+ {
+ return false;
+ }
+
+ if (!ValidateLabelLength(context, entryPoint, length, label))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetObjectLabelKHR(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum identifier,
+ GLuint name,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLchar *label)
+{
+ if (!context->getExtensions().debugKHR)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ if (bufSize < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBufferSize);
+ return false;
+ }
+
+ if (!ValidateObjectIdentifierAndName(context, entryPoint, identifier, name))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+static bool ValidateObjectPtrName(const Context *context,
+ angle::EntryPoint entryPoint,
+ const void *ptr)
+{
+ if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidSyncPointer);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateObjectPtrLabelKHR(const Context *context,
+ angle::EntryPoint entryPoint,
+ const void *ptr,
+ GLsizei length,
+ const GLchar *label)
+{
+ if (!context->getExtensions().debugKHR)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ if (!ValidateObjectPtrName(context, entryPoint, ptr))
+ {
+ return false;
+ }
+
+ if (!ValidateLabelLength(context, entryPoint, length, label))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetObjectPtrLabelKHR(const Context *context,
+ angle::EntryPoint entryPoint,
+ const void *ptr,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLchar *label)
+{
+ if (!context->getExtensions().debugKHR)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ if (bufSize < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBufferSize);
+ return false;
+ }
+
+ if (!ValidateObjectPtrName(context, entryPoint, ptr))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetPointervKHR(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ void *const *params)
+{
+ if (!context->getExtensions().debugKHR)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ // TODO: represent this in Context::getQueryParameterInfo.
+ switch (pname)
+ {
+ case GL_DEBUG_CALLBACK_FUNCTION:
+ case GL_DEBUG_CALLBACK_USER_PARAM:
+ break;
+
+ default:
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetPointervRobustANGLERobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ void *const *params)
+{
+ UNIMPLEMENTED();
+ return false;
+}
+
+bool ValidateBlitFramebufferANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint srcX0,
+ GLint srcY0,
+ GLint srcX1,
+ GLint srcY1,
+ GLint dstX0,
+ GLint dstY0,
+ GLint dstX1,
+ GLint dstY1,
+ GLbitfield mask,
+ GLenum filter)
+{
+ if (!context->getExtensions().framebufferBlitANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kBlitExtensionNotAvailable);
+ return false;
+ }
+
+ if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
+ {
+ // TODO(jmadill): Determine if this should be available on other implementations.
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kBlitExtensionScaleOrFlip);
+ return false;
+ }
+
+ if (filter == GL_LINEAR)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kBlitExtensionLinear);
+ return false;
+ }
+
+ Framebuffer *readFramebuffer = context->getState().getReadFramebuffer();
+ Framebuffer *drawFramebuffer = context->getState().getDrawFramebuffer();
+
+ if (mask & GL_COLOR_BUFFER_BIT)
+ {
+ const FramebufferAttachment *readColorAttachment =
+ readFramebuffer->getReadColorAttachment();
+ const FramebufferAttachment *drawColorAttachment =
+ drawFramebuffer->getFirstColorAttachment();
+
+ if (readColorAttachment && drawColorAttachment)
+ {
+ if (!(readColorAttachment->type() == GL_TEXTURE &&
+ (readColorAttachment->getTextureImageIndex().getType() == TextureType::_2D ||
+ readColorAttachment->getTextureImageIndex().getType() ==
+ TextureType::Rectangle)) &&
+ readColorAttachment->type() != GL_RENDERBUFFER &&
+ readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kBlitExtensionFromInvalidAttachmentType);
+ return false;
+ }
+
+ for (size_t drawbufferIdx = 0;
+ drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
+ {
+ const FramebufferAttachment *attachment =
+ drawFramebuffer->getDrawBuffer(drawbufferIdx);
+ if (attachment)
+ {
+ if (!(attachment->type() == GL_TEXTURE &&
+ (attachment->getTextureImageIndex().getType() == TextureType::_2D ||
+ attachment->getTextureImageIndex().getType() ==
+ TextureType::Rectangle)) &&
+ attachment->type() != GL_RENDERBUFFER &&
+ attachment->type() != GL_FRAMEBUFFER_DEFAULT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kBlitExtensionToInvalidAttachmentType);
+ return false;
+ }
+
+ // Return an error if the destination formats do not match
+ if (!Format::EquivalentForBlit(attachment->getFormat(),
+ readColorAttachment->getFormat()))
+ {
+ context->validationErrorF(
+ entryPoint, GL_INVALID_OPERATION, kBlitExtensionFormatMismatch,
+ readColorAttachment->getFormat().info->sizedInternalFormat,
+ attachment->getFormat().info->sizedInternalFormat);
+ return false;
+ }
+ }
+ }
+
+ GLint samples = readFramebuffer->getSamples(context);
+ if (samples != 0 &&
+ IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
+ srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kBlitExtensionMultisampledWholeBufferBlit);
+ return false;
+ }
+ }
+ }
+
+ GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
+ GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
+ for (size_t i = 0; i < 2; i++)
+ {
+ if (mask & masks[i])
+ {
+ const FramebufferAttachment *readBuffer =
+ readFramebuffer->getAttachment(context, attachments[i]);
+ const FramebufferAttachment *drawBuffer =
+ drawFramebuffer->getAttachment(context, attachments[i]);
+
+ if (readBuffer && drawBuffer)
+ {
+ if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
+ dstX0, dstY0, dstX1, dstY1))
+ {
+ // only whole-buffer copies are permitted
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kBlitExtensionDepthStencilWholeBufferBlit);
+ return false;
+ }
+
+ if (readBuffer->getResourceSamples() != 0 || drawBuffer->getResourceSamples() != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kBlitExtensionMultisampledDepthOrStencil);
+ return false;
+ }
+ }
+ }
+ }
+
+ return ValidateBlitFramebufferParameters(context, entryPoint, srcX0, srcY0, srcX1, srcY1, dstX0,
+ dstY0, dstX1, dstY1, mask, filter);
+}
+
+bool ValidateBlitFramebufferNV(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint srcX0,
+ GLint srcY0,
+ GLint srcX1,
+ GLint srcY1,
+ GLint dstX0,
+ GLint dstY0,
+ GLint dstX1,
+ GLint dstY1,
+ GLbitfield mask,
+ GLenum filter)
+{
+ if (!context->getExtensions().framebufferBlitANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kBlitExtensionNotAvailable);
+ return false;
+ }
+
+ return ValidateBlitFramebufferParameters(context, entryPoint, srcX0, srcY0, srcX1, srcY1, dstX0,
+ dstY0, dstX1, dstY1, mask, filter);
+}
+
+bool ValidateClear(const Context *context, angle::EntryPoint entryPoint, GLbitfield mask)
+{
+ Framebuffer *fbo = context->getState().getDrawFramebuffer();
+ const Extensions &extensions = context->getExtensions();
+
+ if (!ValidateFramebufferComplete(context, entryPoint, fbo))
+ {
+ return false;
+ }
+
+ if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidClearMask);
+ return false;
+ }
+
+ if (extensions.webglCompatibilityANGLE && (mask & GL_COLOR_BUFFER_BIT) != 0)
+ {
+ constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
+ GL_SIGNED_NORMALIZED};
+
+ for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
+ drawBufferIdx++)
+ {
+ if (!ValidateWebGLFramebufferAttachmentClearType(context, entryPoint, drawBufferIdx,
+ validComponentTypes,
+ ArraySize(validComponentTypes)))
+ {
+ return false;
+ }
+ }
+ }
+
+ if ((extensions.multiviewOVR || extensions.multiview2OVR) && extensions.disjointTimerQueryEXT)
+ {
+ const State &state = context->getState();
+ Framebuffer *framebuffer = state.getDrawFramebuffer();
+ if (framebuffer->getNumViews() > 1 && state.isQueryActive(QueryType::TimeElapsed))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kMultiviewTimerQuery);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateDrawBuffersEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const GLenum *bufs)
+{
+ if (!context->getExtensions().drawBuffersEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateDrawBuffersBase(context, entryPoint, n, bufs);
+}
+
+bool ValidateTexImage2D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ return ValidateES2TexImageParameters(context, entryPoint, target, level, internalformat,
+ false, false, 0, 0, width, height, border, format,
+ type, -1, pixels);
+ }
+
+ ASSERT(context->getClientMajorVersion() >= 3);
+ return ValidateES3TexImage2DParameters(context, entryPoint, target, level, internalformat,
+ false, false, 0, 0, 0, width, height, 1, border, format,
+ type, -1, pixels);
+}
+
+bool ValidateTexImage2DRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *pixels)
+{
+ if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
+ {
+ return false;
+ }
+
+ if (context->getClientMajorVersion() < 3)
+ {
+ return ValidateES2TexImageParameters(context, entryPoint, target, level, internalformat,
+ false, false, 0, 0, width, height, border, format,
+ type, bufSize, pixels);
+ }
+
+ ASSERT(context->getClientMajorVersion() >= 3);
+ return ValidateES3TexImage2DParameters(context, entryPoint, target, level, internalformat,
+ false, false, 0, 0, 0, width, height, 1, border, format,
+ type, bufSize, pixels);
+}
+
+bool ValidateTexSubImage2D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+
+ if (context->getClientMajorVersion() < 3)
+ {
+ return ValidateES2TexImageParameters(context, entryPoint, target, level, GL_NONE, false,
+ true, xoffset, yoffset, width, height, 0, format, type,
+ -1, pixels);
+ }
+
+ ASSERT(context->getClientMajorVersion() >= 3);
+ return ValidateES3TexImage2DParameters(context, entryPoint, target, level, GL_NONE, false, true,
+ xoffset, yoffset, 0, width, height, 1, 0, format, type,
+ -1, pixels);
+}
+
+bool ValidateTexSubImage2DRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *pixels)
+{
+ if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
+ {
+ return false;
+ }
+
+ if (context->getClientMajorVersion() < 3)
+ {
+ return ValidateES2TexImageParameters(context, entryPoint, target, level, GL_NONE, false,
+ true, xoffset, yoffset, width, height, 0, format, type,
+ bufSize, pixels);
+ }
+
+ ASSERT(context->getClientMajorVersion() >= 3);
+ return ValidateES3TexImage2DParameters(context, entryPoint, target, level, GL_NONE, false, true,
+ xoffset, yoffset, 0, width, height, 1, 0, format, type,
+ bufSize, pixels);
+}
+
+bool ValidateTexSubImage3DOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ return ValidateTexSubImage3D(context, entryPoint, target, level, xoffset, yoffset, zoffset,
+ width, height, depth, format, type, pixels);
+}
+
+bool ValidateCompressedTexImage2D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLsizei imageSize,
+ const void *data)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ if (!ValidateES2TexImageParameters(context, entryPoint, target, level, internalformat, true,
+ false, 0, 0, width, height, border, GL_NONE, GL_NONE, -1,
+ data))
+ {
+ return false;
+ }
+ }
+ else
+ {
+ ASSERT(context->getClientMajorVersion() >= 3);
+ if (!ValidateES3TexImage2DParameters(context, entryPoint, target, level, internalformat,
+ true, false, 0, 0, 0, width, height, 1, border,
+ GL_NONE, GL_NONE, -1, data))
+ {
+ return false;
+ }
+ }
+
+ const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
+
+ GLuint expectedImageSize = 0;
+ if (!formatInfo.computeCompressedImageSize(Extents(width, height, 1), &expectedImageSize))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kIntegerOverflow);
+ return false;
+ }
+
+ if (imageSize < 0 || static_cast<GLuint>(imageSize) != expectedImageSize)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kCompressedTextureDimensionsMustMatchData);
+ return false;
+ }
+
+ if (target == TextureTarget::Rectangle)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kRectangleTextureCompressed);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateCompressedTexImage2DRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLsizei imageSize,
+ GLsizei dataSize,
+ const void *data)
+{
+ if (!ValidateRobustCompressedTexImageBase(context, entryPoint, imageSize, dataSize))
+ {
+ return false;
+ }
+
+ return ValidateCompressedTexImage2D(context, entryPoint, target, level, internalformat, width,
+ height, border, imageSize, data);
+}
+
+bool ValidateCompressedTexImage3DOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLsizei imageSize,
+ const void *data)
+{
+ return ValidateCompressedTexImage3D(context, entryPoint, target, level, internalformat, width,
+ height, depth, border, imageSize, data);
+}
+
+bool ValidateCompressedTexSubImage2DRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLsizei imageSize,
+ GLsizei dataSize,
+ const void *data)
+{
+ if (!ValidateRobustCompressedTexImageBase(context, entryPoint, imageSize, dataSize))
+ {
+ return false;
+ }
+
+ return ValidateCompressedTexSubImage2D(context, entryPoint, target, level, xoffset, yoffset,
+ width, height, format, imageSize, data);
+}
+
+bool ValidateCompressedTexSubImage2D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ if (!ValidateES2TexImageParameters(context, entryPoint, target, level, GL_NONE, true, true,
+ xoffset, yoffset, width, height, 0, format, GL_NONE, -1,
+ data))
+ {
+ return false;
+ }
+ }
+ else
+ {
+ ASSERT(context->getClientMajorVersion() >= 3);
+ if (!ValidateES3TexImage2DParameters(context, entryPoint, target, level, GL_NONE, true,
+ true, xoffset, yoffset, 0, width, height, 1, 0, format,
+ GL_NONE, -1, data))
+ {
+ return false;
+ }
+ }
+
+ const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
+ GLuint blockSize = 0;
+ if (!formatInfo.computeCompressedImageSize(Extents(width, height, 1), &blockSize))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kIntegerOverflow);
+ return false;
+ }
+
+ if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidCompressedImageSize);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateCompressedTexSubImage3DOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data)
+{
+ return ValidateCompressedTexSubImage3D(context, entryPoint, target, level, xoffset, yoffset,
+ zoffset, width, height, depth, format, imageSize, data);
+}
+
+bool ValidateGetBufferPointervOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding target,
+ GLenum pname,
+ void *const *params)
+{
+ if (!context->getExtensions().mapbufferOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateGetBufferPointervBase(context, entryPoint, target, pname, nullptr, params);
+}
+
+bool ValidateMapBufferOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding target,
+ GLenum access)
+{
+ if (!context->getExtensions().mapbufferOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ if (!context->isValidBufferBinding(target))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBufferTypes);
+ return false;
+ }
+
+ Buffer *buffer = context->getState().getTargetBuffer(target);
+
+ if (buffer == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferNotMappable);
+ return false;
+ }
+
+ if (access != GL_WRITE_ONLY_OES)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidAccessBits);
+ return false;
+ }
+
+ // Though there is no explicit mention of an interaction between GL_EXT_buffer_storage
+ // and GL_OES_mapbuffer extension, allow it as long as the access type of glmapbufferOES
+ // is compatible with the buffer's usage flags specified during glBufferStorageEXT
+ if (buffer->isImmutable() && (buffer->getStorageExtUsageFlags() & GL_MAP_WRITE_BIT) == 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferNotMappable);
+ return false;
+ }
+
+ if (buffer->isMapped())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferAlreadyMapped);
+ return false;
+ }
+
+ return ValidateMapBufferBase(context, entryPoint, target);
+}
+
+bool ValidateUnmapBufferOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding target)
+{
+ if (!context->getExtensions().mapbufferOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateUnmapBufferBase(context, entryPoint, target);
+}
+
+bool ValidateMapBufferRangeEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding target,
+ GLintptr offset,
+ GLsizeiptr length,
+ GLbitfield access)
+{
+ if (!context->getExtensions().mapBufferRangeEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateMapBufferRangeBase(context, entryPoint, target, offset, length, access);
+}
+
+bool ValidateMapBufferBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding target)
+{
+ Buffer *buffer = context->getState().getTargetBuffer(target);
+ ASSERT(buffer != nullptr);
+
+ // Check if this buffer is currently being used as a transform feedback output buffer
+ if (context->getState().isTransformFeedbackActive())
+ {
+ TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
+ for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
+ {
+ const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
+ if (transformFeedbackBuffer.get() == buffer)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kBufferBoundForTransformFeedback);
+ return false;
+ }
+ }
+ }
+
+ if (buffer->hasWebGLXFBBindingConflict(context->isWebGL()))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kBufferBoundForTransformFeedback);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateFlushMappedBufferRangeEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding target,
+ GLintptr offset,
+ GLsizeiptr length)
+{
+ if (!context->getExtensions().mapBufferRangeEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateFlushMappedBufferRangeBase(context, entryPoint, target, offset, length);
+}
+
+bool ValidateBindUniformLocationCHROMIUM(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ const GLchar *name)
+{
+ if (!context->getExtensions().bindUniformLocationCHROMIUM)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ Program *programObject = GetValidProgram(context, entryPoint, program);
+ if (!programObject)
+ {
+ return false;
+ }
+
+ if (location.value < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeLocation);
+ return false;
+ }
+
+ const Caps &caps = context->getCaps();
+ if (static_cast<long>(location.value) >=
+ (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidBindUniformLocation);
+ return false;
+ }
+
+ // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
+ // shader-related entry points
+ if (context->isWebGL() && !IsValidESSLString(name, strlen(name)))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidNameCharacters);
+ return false;
+ }
+
+ if (strncmp(name, "gl_", 3) == 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNameBeginsWithGL);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateCoverageModulationCHROMIUM(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum components)
+{
+ if (!context->getExtensions().framebufferMixedSamplesCHROMIUM)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+ switch (components)
+ {
+ case GL_RGB:
+ case GL_RGBA:
+ case GL_ALPHA:
+ case GL_NONE:
+ break;
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidCoverageComponents);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateCopyTextureCHROMIUM(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID sourceId,
+ GLint sourceLevel,
+ TextureTarget destTarget,
+ TextureID destId,
+ GLint destLevel,
+ GLint internalFormat,
+ GLenum destType,
+ GLboolean unpackFlipY,
+ GLboolean unpackPremultiplyAlpha,
+ GLboolean unpackUnmultiplyAlpha)
+{
+ if (!context->getExtensions().copyTextureCHROMIUM)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ const Texture *source = context->getTexture(sourceId);
+ if (source == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidSourceTexture);
+ return false;
+ }
+
+ if (!IsValidCopyTextureSourceTarget(context, source->getType()))
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_OPERATION, kInvalidInternalFormat,
+ internalFormat);
+ return false;
+ }
+
+ TextureType sourceType = source->getType();
+ ASSERT(sourceType != TextureType::CubeMap);
+ TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
+
+ if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidSourceTextureLevel);
+ return false;
+ }
+
+ GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
+ GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
+ if (sourceWidth == 0 || sourceHeight == 0)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_OPERATION, kInvalidInternalFormat,
+ internalFormat);
+ return false;
+ }
+
+ const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
+ if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kInvalidSourceTextureInternalFormat);
+ return false;
+ }
+
+ if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget);
+ return false;
+ }
+
+ const Texture *dest = context->getTexture(destId);
+ if (dest == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidDestinationTexture);
+ return false;
+ }
+
+ const InternalFormat &destInternalFormatInfo = GetInternalFormatInfo(internalFormat, destType);
+ if (sourceType == TextureType::External && destInternalFormatInfo.isInt() &&
+ !context->getExtensions().EGLImageExternalEssl3OES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kANGLECopyTextureMissingRequiredExtension);
+ return false;
+ }
+
+ if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidDestinationTextureType);
+ return false;
+ }
+
+ if (!IsValidCopyTextureDestinationLevel(context, entryPoint, dest->getType(), destLevel,
+ sourceWidth, sourceHeight, false))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel);
+ return false;
+ }
+
+ if (!IsValidCopyTextureDestinationFormatType(context, entryPoint, internalFormat, destType))
+ {
+ return false;
+ }
+
+ if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kCubemapFacesEqualDimensions);
+ return false;
+ }
+
+ if (dest->getImmutableFormat())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kDestinationImmutable);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateCopySubTextureCHROMIUM(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID sourceId,
+ GLint sourceLevel,
+ TextureTarget destTarget,
+ TextureID destId,
+ GLint destLevel,
+ GLint xoffset,
+ GLint yoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLboolean unpackFlipY,
+ GLboolean unpackPremultiplyAlpha,
+ GLboolean unpackUnmultiplyAlpha)
+{
+ if (!context->getExtensions().copyTextureCHROMIUM)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ const Texture *source = context->getTexture(sourceId);
+ if (source == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidSourceTexture);
+ return false;
+ }
+
+ if (!IsValidCopyTextureSourceTarget(context, source->getType()))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidSourceTextureType);
+ return false;
+ }
+
+ TextureType sourceType = source->getType();
+ ASSERT(sourceType != TextureType::CubeMap);
+ TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
+
+ if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel);
+ return false;
+ }
+
+ if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
+ source->getHeight(sourceTarget, sourceLevel) == 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidSourceTextureLevel);
+ return false;
+ }
+
+ if (x < 0 || y < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeOffset);
+ return false;
+ }
+
+ if (width < 0 || height < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeSize);
+ return false;
+ }
+
+ if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
+ static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kSourceTextureTooSmall);
+ return false;
+ }
+
+ const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
+ if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_OPERATION, kInvalidInternalFormat,
+ sourceFormat.info->internalFormat);
+ return false;
+ }
+
+ if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget);
+ return false;
+ }
+
+ const Texture *dest = context->getTexture(destId);
+ if (dest == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidDestinationTexture);
+ return false;
+ }
+
+ if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidDestinationTextureType);
+ return false;
+ }
+
+ if (!IsValidCopyTextureDestinationLevel(context, entryPoint, dest->getType(), destLevel, width,
+ height, true))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel);
+ return false;
+ }
+
+ if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kDestinationLevelNotDefined);
+ return false;
+ }
+
+ const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
+ if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormatCombination);
+ return false;
+ }
+
+ if (sourceType == TextureType::External && destFormat.isInt() &&
+ !context->getExtensions().EGLImageExternalEssl3OES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kANGLECopyTextureMissingRequiredExtension);
+ return false;
+ }
+
+ if (xoffset < 0 || yoffset < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeOffset);
+ return false;
+ }
+
+ if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
+ static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kOffsetOverflow);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateCompressedCopyTextureCHROMIUM(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID sourceId,
+ TextureID destId)
+{
+ if (!context->getExtensions().copyCompressedTextureCHROMIUM)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ const Texture *source = context->getTexture(sourceId);
+ if (source == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidSourceTexture);
+ return false;
+ }
+
+ if (source->getType() != TextureType::_2D)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidSourceTextureType);
+ return false;
+ }
+
+ if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
+ source->getHeight(TextureTarget::_2D, 0) == 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kSourceTextureLevelZeroDefined);
+ return false;
+ }
+
+ const Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
+ if (!sourceFormat.info->compressed)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kSourceTextureMustBeCompressed);
+ return false;
+ }
+
+ const Texture *dest = context->getTexture(destId);
+ if (dest == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidDestinationTexture);
+ return false;
+ }
+
+ if (dest->getType() != TextureType::_2D)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidDestinationTextureType);
+ return false;
+ }
+
+ if (dest->getImmutableFormat())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kDestinationImmutable);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateCreateShader(const Context *context, angle::EntryPoint entryPoint, ShaderType type)
+{
+ switch (type)
+ {
+ case ShaderType::Vertex:
+ case ShaderType::Fragment:
+ break;
+
+ case ShaderType::Compute:
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kES31Required);
+ return false;
+ }
+ break;
+
+ case ShaderType::Geometry:
+ if (!context->getExtensions().geometryShaderAny() &&
+ context->getClientVersion() < ES_3_2)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidShaderType);
+ return false;
+ }
+ break;
+
+ case ShaderType::TessControl:
+ if (!context->getExtensions().tessellationShaderEXT &&
+ context->getClientVersion() < ES_3_2)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidShaderType);
+ return false;
+ }
+ break;
+
+ case ShaderType::TessEvaluation:
+ if (!context->getExtensions().tessellationShaderEXT &&
+ context->getClientVersion() < ES_3_2)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidShaderType);
+ return false;
+ }
+ break;
+
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidShaderType);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateBufferData(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding target,
+ GLsizeiptr size,
+ const void *data,
+ BufferUsage usage)
+{
+ if (size < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeSize);
+ return false;
+ }
+
+ switch (usage)
+ {
+ case BufferUsage::StreamDraw:
+ case BufferUsage::StaticDraw:
+ case BufferUsage::DynamicDraw:
+ break;
+
+ case BufferUsage::StreamRead:
+ case BufferUsage::StaticRead:
+ case BufferUsage::DynamicRead:
+ case BufferUsage::StreamCopy:
+ case BufferUsage::StaticCopy:
+ case BufferUsage::DynamicCopy:
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBufferUsage);
+ return false;
+ }
+ break;
+
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBufferUsage);
+ return false;
+ }
+
+ if (!context->isValidBufferBinding(target))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBufferTypes);
+ return false;
+ }
+
+ Buffer *buffer = context->getState().getTargetBuffer(target);
+
+ if (!buffer)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferNotBound);
+ return false;
+ }
+
+ if (buffer->hasWebGLXFBBindingConflict(context->isWebGL()))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kBufferBoundForTransformFeedback);
+ return false;
+ }
+
+ if (buffer->isImmutable())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferImmutable);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateBufferSubData(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding target,
+ GLintptr offset,
+ GLsizeiptr size,
+ const void *data)
+{
+ if (size < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeSize);
+ return false;
+ }
+
+ if (offset < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeOffset);
+ return false;
+ }
+
+ if (!context->isValidBufferBinding(target))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBufferTypes);
+ return false;
+ }
+
+ Buffer *buffer = context->getState().getTargetBuffer(target);
+
+ if (!buffer)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferNotBound);
+ return false;
+ }
+
+ // EXT_buffer_storage allows persistently mapped buffers to be updated via glBufferSubData
+ bool isPersistent = (buffer->getAccessFlags() & GL_MAP_PERSISTENT_BIT_EXT) != 0;
+
+ // Verify that buffer is not currently mapped unless persistent
+ if (buffer->isMapped() && !isPersistent)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferMapped);
+ return false;
+ }
+
+ if (buffer->hasWebGLXFBBindingConflict(context->isWebGL()))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kBufferBoundForTransformFeedback);
+ return false;
+ }
+
+ if (buffer->isImmutable() &&
+ (buffer->getStorageExtUsageFlags() & GL_DYNAMIC_STORAGE_BIT_EXT) == 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferNotUpdatable);
+ return false;
+ }
+
+ // Check for possible overflow of size + offset
+ angle::CheckedNumeric<decltype(size + offset)> checkedSize(size);
+ checkedSize += offset;
+ if (!checkedSize.IsValid())
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kParamOverflow);
+ return false;
+ }
+
+ if (size + offset > buffer->getSize())
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInsufficientBufferSize);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateRequestExtensionANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLchar *name)
+{
+ if (!context->getExtensions().requestExtensionANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ if (!context->isExtensionRequestable(name))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotRequestable);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateDisableExtensionANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLchar *name)
+{
+ if (!context->getExtensions().requestExtensionANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ if (!context->isExtensionDisablable(name))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotDisablable);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateActiveTexture(const Context *context, angle::EntryPoint entryPoint, GLenum texture)
+{
+ if (context->getClientMajorVersion() < 2)
+ {
+ return ValidateMultitextureUnit(context, entryPoint, texture);
+ }
+
+ if (texture < GL_TEXTURE0 ||
+ texture >
+ GL_TEXTURE0 + static_cast<GLuint>(context->getCaps().maxCombinedTextureImageUnits) - 1)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidCombinedImageUnit);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateAttachShader(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ ShaderProgramID shader)
+{
+ Program *programObject = GetValidProgram(context, entryPoint, program);
+ if (!programObject)
+ {
+ return false;
+ }
+
+ Shader *shaderObject = GetValidShader(context, entryPoint, shader);
+ if (!shaderObject)
+ {
+ return false;
+ }
+
+ if (programObject->getAttachedShader(shaderObject->getType()))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kShaderAttachmentHasShader);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateBindAttribLocation(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLuint index,
+ const GLchar *name)
+{
+ if (index >= static_cast<GLuint>(context->getCaps().maxVertexAttributes))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
+ return false;
+ }
+
+ if (strncmp(name, "gl_", 3) == 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kNameBeginsWithGL);
+ return false;
+ }
+
+ if (context->isWebGL())
+ {
+ const size_t length = strlen(name);
+
+ if (!IsValidESSLString(name, length))
+ {
+ // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
+ // for shader-related entry points
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidNameCharacters);
+ return false;
+ }
+
+ if (!ValidateWebGLNameLength(context, entryPoint, length) ||
+ !ValidateWebGLNamePrefix(context, entryPoint, name))
+ {
+ return false;
+ }
+ }
+
+ return GetValidProgram(context, entryPoint, program) != nullptr;
+}
+
+bool ValidateBindFramebuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ FramebufferID framebuffer)
+{
+ return ValidateBindFramebufferBase(context, entryPoint, target, framebuffer);
+}
+
+bool ValidateBindRenderbuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ RenderbufferID renderbuffer)
+{
+ return ValidateBindRenderbufferBase(context, entryPoint, target, renderbuffer);
+}
+
+static bool ValidBlendEquationMode(const Context *context, GLenum mode)
+{
+ switch (mode)
+ {
+ case GL_FUNC_ADD:
+ case GL_FUNC_SUBTRACT:
+ case GL_FUNC_REVERSE_SUBTRACT:
+ return true;
+
+ case GL_MIN:
+ case GL_MAX:
+ return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinmaxEXT;
+
+ default:
+ return false;
+ }
+}
+
+static bool ValidAdvancedBlendEquationMode(const Context *context, GLenum mode)
+{
+ switch (mode)
+ {
+ case GL_MULTIPLY_KHR:
+ case GL_SCREEN_KHR:
+ case GL_OVERLAY_KHR:
+ case GL_DARKEN_KHR:
+ case GL_LIGHTEN_KHR:
+ case GL_COLORDODGE_KHR:
+ case GL_COLORBURN_KHR:
+ case GL_HARDLIGHT_KHR:
+ case GL_SOFTLIGHT_KHR:
+ case GL_DIFFERENCE_KHR:
+ case GL_EXCLUSION_KHR:
+ case GL_HSL_HUE_KHR:
+ case GL_HSL_SATURATION_KHR:
+ case GL_HSL_COLOR_KHR:
+ case GL_HSL_LUMINOSITY_KHR:
+ return context->getClientVersion() >= ES_3_2 ||
+ context->getExtensions().blendEquationAdvancedKHR;
+
+ default:
+ return false;
+ }
+}
+
+bool ValidateBlendColor(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat red,
+ GLfloat green,
+ GLfloat blue,
+ GLfloat alpha)
+{
+ return true;
+}
+
+bool ValidateBlendEquation(const Context *context, angle::EntryPoint entryPoint, GLenum mode)
+{
+ if (!ValidBlendEquationMode(context, mode) && !ValidAdvancedBlendEquationMode(context, mode))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBlendEquation);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateBlendEquationSeparate(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum modeRGB,
+ GLenum modeAlpha)
+{
+ if (!ValidBlendEquationMode(context, modeRGB))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBlendEquation);
+ return false;
+ }
+
+ if (!ValidBlendEquationMode(context, modeAlpha))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBlendEquation);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateBlendFunc(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum sfactor,
+ GLenum dfactor)
+{
+ return ValidateBlendFuncSeparate(context, entryPoint, sfactor, dfactor, sfactor, dfactor);
+}
+
+bool ValidateBlendFuncSeparate(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum srcRGB,
+ GLenum dstRGB,
+ GLenum srcAlpha,
+ GLenum dstAlpha)
+{
+ if (!ValidSrcBlendFunc(context, srcRGB))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBlendFunction);
+ return false;
+ }
+
+ if (!ValidDstBlendFunc(context, dstRGB))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBlendFunction);
+ return false;
+ }
+
+ if (!ValidSrcBlendFunc(context, srcAlpha))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBlendFunction);
+ return false;
+ }
+
+ if (!ValidDstBlendFunc(context, dstAlpha))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBlendFunction);
+ return false;
+ }
+
+ if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
+ context->isWebGL())
+ {
+ bool constantColorUsed =
+ (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
+ dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
+
+ bool constantAlphaUsed =
+ (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
+ dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
+
+ if (constantColorUsed && constantAlphaUsed)
+ {
+ if (context->isWebGL())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidConstantColor);
+ return false;
+ }
+
+ WARN() << kConstantColorAlphaLimitation;
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kConstantColorAlphaLimitation);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateGetString(const Context *context, angle::EntryPoint entryPoint, GLenum name)
+{
+ switch (name)
+ {
+ case GL_VENDOR:
+ case GL_RENDERER:
+ case GL_VERSION:
+ case GL_SHADING_LANGUAGE_VERSION:
+ case GL_EXTENSIONS:
+ break;
+
+ case GL_REQUESTABLE_EXTENSIONS_ANGLE:
+ if (!context->getExtensions().requestExtensionANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidName);
+ return false;
+ }
+ break;
+
+ case GL_SERIALIZED_CONTEXT_STRING_ANGLE:
+ if (!context->getExtensions().getSerializedContextStringANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidName);
+ return false;
+ }
+ break;
+
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidName);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateLineWidth(const Context *context, angle::EntryPoint entryPoint, GLfloat width)
+{
+ if (width <= 0.0f || isNaN(width))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidWidth);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateDepthRangef(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat zNear,
+ GLfloat zFar)
+{
+ if (context->isWebGL() && zNear > zFar)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidDepthRange);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateRenderbufferStorage(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height)
+{
+ return ValidateRenderbufferStorageParametersBase(context, entryPoint, target, 0, internalformat,
+ width, height);
+}
+
+bool ValidateRenderbufferStorageMultisampleANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height)
+{
+ if (!context->getExtensions().framebufferMultisampleANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
+ // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_VALUE is
+ // generated.
+ if (samples > context->getCaps().maxSamples)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kSamplesOutOfRange);
+ return false;
+ }
+
+ // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
+ // 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->getClientMajorVersion() >= 3)
+ {
+ const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
+ if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
+ {
+ context->validationError(entryPoint, GL_OUT_OF_MEMORY, kSamplesOutOfRange);
+ return false;
+ }
+ }
+
+ return ValidateRenderbufferStorageParametersBase(context, entryPoint, target, samples,
+ internalformat, width, height);
+}
+
+bool ValidateCheckFramebufferStatus(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target)
+{
+ if (!ValidFramebufferTarget(context, target))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFramebufferTarget);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateClearColor(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat red,
+ GLfloat green,
+ GLfloat blue,
+ GLfloat alpha)
+{
+ return true;
+}
+
+bool ValidateClearDepthf(const Context *context, angle::EntryPoint entryPoint, GLfloat depth)
+{
+ return true;
+}
+
+bool ValidateClearStencil(const Context *context, angle::EntryPoint entryPoint, GLint s)
+{
+ return true;
+}
+
+bool ValidateColorMask(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLboolean red,
+ GLboolean green,
+ GLboolean blue,
+ GLboolean alpha)
+{
+ return true;
+}
+
+bool ValidateCompileShader(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID shader)
+{
+ return true;
+}
+
+bool ValidateCreateProgram(const Context *context, angle::EntryPoint entryPoint)
+{
+ return true;
+}
+
+bool ValidateCullFace(const Context *context, angle::EntryPoint entryPoint, CullFaceMode mode)
+{
+ switch (mode)
+ {
+ case CullFaceMode::Front:
+ case CullFaceMode::Back:
+ case CullFaceMode::FrontAndBack:
+ break;
+
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidCullMode);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateDeleteProgram(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program)
+{
+ if (program.value == 0)
+ {
+ return false;
+ }
+
+ if (!context->getProgramResolveLink(program))
+ {
+ if (context->getShader(program))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExpectedProgramName);
+ return false;
+ }
+ else
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidProgramName);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateDeleteShader(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID shader)
+{
+ if (shader.value == 0)
+ {
+ return false;
+ }
+
+ if (!context->getShader(shader))
+ {
+ if (context->getProgramResolveLink(shader))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidShaderName);
+ return false;
+ }
+ else
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kExpectedShaderName);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateDepthFunc(const Context *context, angle::EntryPoint entryPoint, GLenum func)
+{
+ switch (func)
+ {
+ case GL_NEVER:
+ case GL_ALWAYS:
+ case GL_LESS:
+ case GL_LEQUAL:
+ case GL_EQUAL:
+ case GL_GREATER:
+ case GL_GEQUAL:
+ case GL_NOTEQUAL:
+ break;
+
+ default:
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, func);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateDepthMask(const Context *context, angle::EntryPoint entryPoint, GLboolean flag)
+{
+ return true;
+}
+
+bool ValidateDetachShader(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ ShaderProgramID shader)
+{
+ Program *programObject = GetValidProgram(context, entryPoint, program);
+ if (!programObject)
+ {
+ return false;
+ }
+
+ Shader *shaderObject = GetValidShader(context, entryPoint, shader);
+ if (!shaderObject)
+ {
+ return false;
+ }
+
+ const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType());
+ if (attachedShader != shaderObject)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kShaderToDetachMustBeAttached);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateDisableVertexAttribArray(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index)
+{
+ if (index >= static_cast<GLuint>(context->getCaps().maxVertexAttributes))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateEnableVertexAttribArray(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index)
+{
+ if (index >= static_cast<GLuint>(context->getCaps().maxVertexAttributes))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateFinish(const Context *context, angle::EntryPoint entryPoint)
+{
+ return true;
+}
+
+bool ValidateFlush(const Context *context, angle::EntryPoint entryPoint)
+{
+ return true;
+}
+
+bool ValidateFrontFace(const Context *context, angle::EntryPoint entryPoint, GLenum mode)
+{
+ switch (mode)
+ {
+ case GL_CW:
+ case GL_CCW:
+ break;
+ default:
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, mode);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetActiveAttrib(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLuint index,
+ GLsizei bufsize,
+ const GLsizei *length,
+ const GLint *size,
+ const GLenum *type,
+ const GLchar *name)
+{
+ if (bufsize < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBufferSize);
+ return false;
+ }
+
+ Program *programObject = GetValidProgram(context, entryPoint, program);
+
+ if (!programObject)
+ {
+ return false;
+ }
+
+ if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxActiveUniform);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetActiveUniform(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLuint index,
+ GLsizei bufsize,
+ const GLsizei *length,
+ const GLint *size,
+ const GLenum *type,
+ const GLchar *name)
+{
+ if (bufsize < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBufferSize);
+ return false;
+ }
+
+ Program *programObject = GetValidProgram(context, entryPoint, program);
+
+ if (!programObject)
+ {
+ return false;
+ }
+
+ if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxActiveUniform);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetAttachedShaders(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLsizei maxcount,
+ const GLsizei *count,
+ const ShaderProgramID *shaders)
+{
+ if (maxcount < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeMaxCount);
+ return false;
+ }
+
+ Program *programObject = GetValidProgram(context, entryPoint, program);
+
+ if (!programObject)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetAttribLocation(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ const GLchar *name)
+{
+ if (strncmp(name, "gl_", 3) == 0)
+ {
+ return false;
+ }
+
+ if (context->isWebGL())
+ {
+ const size_t length = strlen(name);
+
+ if (!IsValidESSLString(name, length))
+ {
+ // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
+ // for shader-related entry points
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidNameCharacters);
+ return false;
+ }
+
+ if (!ValidateWebGLNameLength(context, entryPoint, length) ||
+ strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
+ {
+ return false;
+ }
+ }
+
+ Program *programObject = GetValidProgram(context, entryPoint, program);
+
+ if (!programObject)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotBound);
+ return false;
+ }
+
+ if (!programObject->isLinked())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotLinked);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetBooleanv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ const GLboolean *params)
+{
+ GLenum nativeType;
+ unsigned int numParams = 0;
+ return ValidateStateQuery(context, entryPoint, pname, &nativeType, &numParams);
+}
+
+bool ValidateGetError(const Context *context, angle::EntryPoint entryPoint)
+{
+ return true;
+}
+
+bool ValidateGetFloatv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ const GLfloat *params)
+{
+ GLenum nativeType;
+ unsigned int numParams = 0;
+ return ValidateStateQuery(context, entryPoint, pname, &nativeType, &numParams);
+}
+
+bool ValidateGetIntegerv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ const GLint *params)
+{
+ GLenum nativeType;
+ unsigned int numParams = 0;
+ return ValidateStateQuery(context, entryPoint, pname, &nativeType, &numParams);
+}
+
+bool ValidateGetProgramInfoLog(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLsizei bufsize,
+ const GLsizei *length,
+ const GLchar *infolog)
+{
+ if (bufsize < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBufferSize);
+ return false;
+ }
+
+ Program *programObject = GetValidProgram(context, entryPoint, program);
+ if (!programObject)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetShaderInfoLog(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID shader,
+ GLsizei bufsize,
+ const GLsizei *length,
+ const GLchar *infolog)
+{
+ if (bufsize < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBufferSize);
+ return false;
+ }
+
+ Shader *shaderObject = GetValidShader(context, entryPoint, shader);
+ if (!shaderObject)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetShaderPrecisionFormat(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum shadertype,
+ GLenum precisiontype,
+ const GLint *range,
+ const GLint *precision)
+{
+ switch (shadertype)
+ {
+ case GL_VERTEX_SHADER:
+ case GL_FRAGMENT_SHADER:
+ break;
+ case GL_COMPUTE_SHADER:
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kUnimplementedComputeShaderPrecision);
+ return false;
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidShaderType);
+ return false;
+ }
+
+ switch (precisiontype)
+ {
+ case GL_LOW_FLOAT:
+ case GL_MEDIUM_FLOAT:
+ case GL_HIGH_FLOAT:
+ case GL_LOW_INT:
+ case GL_MEDIUM_INT:
+ case GL_HIGH_INT:
+ break;
+
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPrecision);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetShaderSource(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID shader,
+ GLsizei bufsize,
+ const GLsizei *length,
+ const GLchar *source)
+{
+ if (bufsize < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBufferSize);
+ return false;
+ }
+
+ Shader *shaderObject = GetValidShader(context, entryPoint, shader);
+ if (!shaderObject)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetUniformLocation(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ const GLchar *name)
+{
+ if (strstr(name, "gl_") == name)
+ {
+ return false;
+ }
+
+ // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
+ // shader-related entry points
+ if (context->isWebGL() && !IsValidESSLString(name, strlen(name)))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidNameCharacters);
+ return false;
+ }
+
+ Program *programObject = GetValidProgram(context, entryPoint, program);
+
+ if (!programObject)
+ {
+ return false;
+ }
+
+ if (!programObject->isLinked())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotLinked);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateHint(const Context *context, angle::EntryPoint entryPoint, GLenum target, GLenum mode)
+{
+ switch (mode)
+ {
+ case GL_FASTEST:
+ case GL_NICEST:
+ case GL_DONT_CARE:
+ break;
+
+ default:
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, mode);
+ return false;
+ }
+
+ switch (target)
+ {
+ case GL_GENERATE_MIPMAP_HINT:
+ break;
+
+ case GL_TEXTURE_FILTERING_HINT_CHROMIUM:
+ if (!context->getExtensions().textureFilteringHintCHROMIUM)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, target);
+ return false;
+ }
+ break;
+
+ case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
+ if (context->getClientVersion() < ES_3_0 &&
+ !context->getExtensions().standardDerivativesOES)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, target);
+ return false;
+ }
+ break;
+
+ case GL_PERSPECTIVE_CORRECTION_HINT:
+ case GL_POINT_SMOOTH_HINT:
+ case GL_LINE_SMOOTH_HINT:
+ case GL_FOG_HINT:
+ if (context->getClientMajorVersion() >= 2)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, target);
+ return false;
+ }
+ break;
+
+ default:
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, target);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateIsBuffer(const Context *context, angle::EntryPoint entryPoint, BufferID buffer)
+{
+ return true;
+}
+
+bool ValidateIsFramebuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ FramebufferID framebuffer)
+{
+ return true;
+}
+
+bool ValidateIsProgram(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program)
+{
+ return true;
+}
+
+bool ValidateIsRenderbuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ RenderbufferID renderbuffer)
+{
+ return true;
+}
+
+bool ValidateIsShader(const Context *context, angle::EntryPoint entryPoint, ShaderProgramID shader)
+{
+ return true;
+}
+
+bool ValidateIsTexture(const Context *context, angle::EntryPoint entryPoint, TextureID texture)
+{
+ return true;
+}
+
+bool ValidatePixelStorei(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLint param)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ switch (pname)
+ {
+ case GL_UNPACK_IMAGE_HEIGHT:
+ case GL_UNPACK_SKIP_IMAGES:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname);
+ return false;
+
+ case GL_UNPACK_ROW_LENGTH:
+ case GL_UNPACK_SKIP_ROWS:
+ case GL_UNPACK_SKIP_PIXELS:
+ if (!context->getExtensions().unpackSubimageEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname);
+ return false;
+ }
+ break;
+
+ case GL_PACK_ROW_LENGTH:
+ case GL_PACK_SKIP_ROWS:
+ case GL_PACK_SKIP_PIXELS:
+ if (!context->getExtensions().packSubimageNV)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname);
+ return false;
+ }
+ break;
+ }
+ }
+
+ if (param < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeParam);
+ return false;
+ }
+
+ switch (pname)
+ {
+ case GL_UNPACK_ALIGNMENT:
+ if (param != 1 && param != 2 && param != 4 && param != 8)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidUnpackAlignment);
+ return false;
+ }
+ break;
+
+ case GL_PACK_ALIGNMENT:
+ if (param != 1 && param != 2 && param != 4 && param != 8)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidUnpackAlignment);
+ return false;
+ }
+ break;
+
+ case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
+ if (!context->getExtensions().packReverseRowOrderANGLE)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname);
+ }
+ break;
+
+ case GL_UNPACK_ROW_LENGTH:
+ case GL_UNPACK_IMAGE_HEIGHT:
+ case GL_UNPACK_SKIP_IMAGES:
+ case GL_UNPACK_SKIP_ROWS:
+ case GL_UNPACK_SKIP_PIXELS:
+ case GL_PACK_ROW_LENGTH:
+ case GL_PACK_SKIP_ROWS:
+ case GL_PACK_SKIP_PIXELS:
+ break;
+
+ default:
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidatePolygonOffset(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat factor,
+ GLfloat units)
+{
+ return true;
+}
+
+bool ValidateReleaseShaderCompiler(const Context *context, angle::EntryPoint entryPoint)
+{
+ return true;
+}
+
+bool ValidateSampleCoverage(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat value,
+ GLboolean invert)
+{
+ return true;
+}
+
+bool ValidateScissor(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height)
+{
+ if (width < 0 || height < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeSize);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateShaderBinary(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const ShaderProgramID *shaders,
+ GLenum binaryformat,
+ const void *binary,
+ GLsizei length)
+{
+ const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
+ if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
+ shaderBinaryFormats.end())
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidShaderBinaryFormat);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateShaderSource(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID shader,
+ GLsizei count,
+ const GLchar *const *string,
+ const GLint *length)
+{
+ if (count < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeCount);
+ return false;
+ }
+
+ Shader *shaderObject = GetValidShader(context, entryPoint, shader);
+ if (!shaderObject)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateStencilFunc(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum func,
+ GLint ref,
+ GLuint mask)
+{
+ if (!IsValidStencilFunc(func))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidStencil);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateStencilFuncSeparate(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum face,
+ GLenum func,
+ GLint ref,
+ GLuint mask)
+{
+ if (!IsValidStencilFace(face))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidStencil);
+ return false;
+ }
+
+ if (!IsValidStencilFunc(func))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidStencil);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateStencilMask(const Context *context, angle::EntryPoint entryPoint, GLuint mask)
+{
+ return true;
+}
+
+bool ValidateStencilMaskSeparate(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum face,
+ GLuint mask)
+{
+ if (!IsValidStencilFace(face))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidStencil);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateStencilOp(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum fail,
+ GLenum zfail,
+ GLenum zpass)
+{
+ if (!IsValidStencilOp(fail))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidStencil);
+ return false;
+ }
+
+ if (!IsValidStencilOp(zfail))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidStencil);
+ return false;
+ }
+
+ if (!IsValidStencilOp(zpass))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidStencil);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateStencilOpSeparate(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum face,
+ GLenum fail,
+ GLenum zfail,
+ GLenum zpass)
+{
+ if (!IsValidStencilFace(face))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidStencil);
+ return false;
+ }
+
+ return ValidateStencilOp(context, entryPoint, fail, zfail, zpass);
+}
+
+bool ValidateUniform1f(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLfloat x)
+{
+ return ValidateUniform(context, entryPoint, GL_FLOAT, location, 1);
+}
+
+bool ValidateUniform1fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLsizei count,
+ const GLfloat *v)
+{
+ return ValidateUniform(context, entryPoint, GL_FLOAT, location, count);
+}
+
+bool ValidateUniform1i(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLint x)
+{
+ return ValidateUniform1iv(context, entryPoint, location, 1, &x);
+}
+
+bool ValidateUniform2fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLsizei count,
+ const GLfloat *v)
+{
+ return ValidateUniform(context, entryPoint, GL_FLOAT_VEC2, location, count);
+}
+
+bool ValidateUniform2i(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLint x,
+ GLint y)
+{
+ return ValidateUniform(context, entryPoint, GL_INT_VEC2, location, 1);
+}
+
+bool ValidateUniform2iv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLsizei count,
+ const GLint *v)
+{
+ return ValidateUniform(context, entryPoint, GL_INT_VEC2, location, count);
+}
+
+bool ValidateUniform3f(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLfloat x,
+ GLfloat y,
+ GLfloat z)
+{
+ return ValidateUniform(context, entryPoint, GL_FLOAT_VEC3, location, 1);
+}
+
+bool ValidateUniform3fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLsizei count,
+ const GLfloat *v)
+{
+ return ValidateUniform(context, entryPoint, GL_FLOAT_VEC3, location, count);
+}
+
+bool ValidateUniform3i(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLint x,
+ GLint y,
+ GLint z)
+{
+ return ValidateUniform(context, entryPoint, GL_INT_VEC3, location, 1);
+}
+
+bool ValidateUniform3iv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLsizei count,
+ const GLint *v)
+{
+ return ValidateUniform(context, entryPoint, GL_INT_VEC3, location, count);
+}
+
+bool ValidateUniform4f(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLfloat x,
+ GLfloat y,
+ GLfloat z,
+ GLfloat w)
+{
+ return ValidateUniform(context, entryPoint, GL_FLOAT_VEC4, location, 1);
+}
+
+bool ValidateUniform4fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLsizei count,
+ const GLfloat *v)
+{
+ return ValidateUniform(context, entryPoint, GL_FLOAT_VEC4, location, count);
+}
+
+bool ValidateUniform4i(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLint x,
+ GLint y,
+ GLint z,
+ GLint w)
+{
+ return ValidateUniform(context, entryPoint, GL_INT_VEC4, location, 1);
+}
+
+bool ValidateUniform4iv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLsizei count,
+ const GLint *v)
+{
+ return ValidateUniform(context, entryPoint, GL_INT_VEC4, location, count);
+}
+
+bool ValidateUniformMatrix2fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return ValidateUniformMatrix(context, entryPoint, GL_FLOAT_MAT2, location, count, transpose);
+}
+
+bool ValidateUniformMatrix3fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return ValidateUniformMatrix(context, entryPoint, GL_FLOAT_MAT3, location, count, transpose);
+}
+
+bool ValidateUniformMatrix4fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return ValidateUniformMatrix(context, entryPoint, GL_FLOAT_MAT4, location, count, transpose);
+}
+
+bool ValidateValidateProgram(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program)
+{
+ Program *programObject = GetValidProgram(context, entryPoint, program);
+
+ if (!programObject)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateVertexAttrib1f(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLfloat x)
+{
+ return ValidateVertexAttribIndex(context, entryPoint, index);
+}
+
+bool ValidateVertexAttrib1fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLfloat *values)
+{
+ return ValidateVertexAttribIndex(context, entryPoint, index);
+}
+
+bool ValidateVertexAttrib2f(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLfloat x,
+ GLfloat y)
+{
+ return ValidateVertexAttribIndex(context, entryPoint, index);
+}
+
+bool ValidateVertexAttrib2fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLfloat *values)
+{
+ return ValidateVertexAttribIndex(context, entryPoint, index);
+}
+
+bool ValidateVertexAttrib3f(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLfloat x,
+ GLfloat y,
+ GLfloat z)
+{
+ return ValidateVertexAttribIndex(context, entryPoint, index);
+}
+
+bool ValidateVertexAttrib3fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLfloat *values)
+{
+ return ValidateVertexAttribIndex(context, entryPoint, index);
+}
+
+bool ValidateVertexAttrib4f(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLfloat x,
+ GLfloat y,
+ GLfloat z,
+ GLfloat w)
+{
+ return ValidateVertexAttribIndex(context, entryPoint, index);
+}
+
+bool ValidateVertexAttrib4fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLfloat *values)
+{
+ return ValidateVertexAttribIndex(context, entryPoint, index);
+}
+
+bool ValidateViewport(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height)
+{
+ if (width < 0 || height < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kViewportNegativeSize);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetFramebufferAttachmentParameteriv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ GLenum pname,
+ const GLint *params)
+{
+ return ValidateGetFramebufferAttachmentParameterivBase(context, entryPoint, target, attachment,
+ pname, nullptr);
+}
+
+bool ValidateGetProgramiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLenum pname,
+ const GLint *params)
+{
+ return ValidateGetProgramivBase(context, entryPoint, program, pname, nullptr);
+}
+
+bool ValidateCopyTexImage2D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLenum internalformat,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLint border)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ return ValidateES2CopyTexImageParameters(context, entryPoint, target, level, internalformat,
+ false, 0, 0, x, y, width, height, border);
+ }
+
+ ASSERT(context->getClientMajorVersion() == 3);
+ return ValidateES3CopyTexImage2DParameters(context, entryPoint, target, level, internalformat,
+ false, 0, 0, 0, x, y, width, height, border);
+}
+
+bool ValidateCopyTexSubImage2D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ return ValidateES2CopyTexImageParameters(context, entryPoint, target, level, GL_NONE, true,
+ xoffset, yoffset, x, y, width, height, 0);
+ }
+
+ return ValidateES3CopyTexImage2DParameters(context, entryPoint, target, level, GL_NONE, true,
+ xoffset, yoffset, 0, x, y, width, height, 0);
+}
+
+bool ValidateCopyTexSubImage3DOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height)
+{
+ return ValidateCopyTexSubImage3D(context, entryPoint, target, level, xoffset, yoffset, zoffset,
+ x, y, width, height);
+}
+
+bool ValidateDeleteBuffers(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint n,
+ const BufferID *buffers)
+{
+ return ValidateGenOrDelete(context, entryPoint, n);
+}
+
+bool ValidateDeleteFramebuffers(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint n,
+ const FramebufferID *framebuffers)
+{
+ return ValidateGenOrDelete(context, entryPoint, n);
+}
+
+bool ValidateDeleteRenderbuffers(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint n,
+ const RenderbufferID *renderbuffers)
+{
+ return ValidateGenOrDelete(context, entryPoint, n);
+}
+
+bool ValidateDeleteTextures(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint n,
+ const TextureID *textures)
+{
+ return ValidateGenOrDelete(context, entryPoint, n);
+}
+
+bool ValidateDisable(const Context *context, angle::EntryPoint entryPoint, GLenum cap)
+{
+ if (!ValidCap(context, cap, false))
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, cap);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateEnable(const Context *context, angle::EntryPoint entryPoint, GLenum cap)
+{
+ if (!ValidCap(context, cap, false))
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, cap);
+ return false;
+ }
+
+ if (context->getLimitations().noSampleAlphaToCoverageSupport &&
+ cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kNoSampleAlphaToCoveragesLimitation);
+
+ // We also output an error message to the debugger window if tracing is active, so that
+ // developers can see the error message.
+ ERR() << kNoSampleAlphaToCoveragesLimitation;
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateFramebufferRenderbuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ GLenum renderbuffertarget,
+ RenderbufferID renderbuffer)
+{
+ return ValidateFramebufferRenderbufferBase(context, entryPoint, target, attachment,
+ renderbuffertarget, renderbuffer);
+}
+
+bool ValidateFramebufferTexture2D(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ TextureTarget textarget,
+ TextureID texture,
+ GLint level)
+{
+ // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
+ // extension
+ if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmapOES &&
+ level != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidFramebufferTextureLevel);
+ return false;
+ }
+
+ if (!ValidateFramebufferTextureBase(context, entryPoint, target, attachment, texture, level))
+ {
+ return false;
+ }
+
+ if (texture.value != 0)
+ {
+ Texture *tex = context->getTexture(texture);
+ ASSERT(tex);
+
+ const Caps &caps = context->getCaps();
+
+ switch (textarget)
+ {
+ case TextureTarget::_2D:
+ {
+ if (level > log2(caps.max2DTextureSize))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel);
+ return false;
+ }
+ if (tex->getType() != TextureType::_2D)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kInvalidTextureTarget);
+ return false;
+ }
+ }
+ break;
+
+ case TextureTarget::Rectangle:
+ {
+ if (level != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel);
+ return false;
+ }
+ if (tex->getType() != TextureType::Rectangle)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kTextureTargetMismatch);
+ return false;
+ }
+ }
+ break;
+
+ case TextureTarget::CubeMapNegativeX:
+ case TextureTarget::CubeMapNegativeY:
+ case TextureTarget::CubeMapNegativeZ:
+ case TextureTarget::CubeMapPositiveX:
+ case TextureTarget::CubeMapPositiveY:
+ case TextureTarget::CubeMapPositiveZ:
+ {
+ if (level > log2(caps.maxCubeMapTextureSize))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel);
+ return false;
+ }
+ if (tex->getType() != TextureType::CubeMap)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kTextureTargetMismatch);
+ return false;
+ }
+ }
+ break;
+
+ case TextureTarget::_2DMultisample:
+ {
+ if (context->getClientVersion() < ES_3_1 &&
+ !context->getExtensions().textureMultisampleANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kMultisampleTextureExtensionOrES31Required);
+ return false;
+ }
+
+ if (level != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kLevelNotZero);
+ return false;
+ }
+ if (tex->getType() != TextureType::_2DMultisample)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kTextureTargetMismatch);
+ return false;
+ }
+ }
+ break;
+
+ case TextureTarget::External:
+ {
+ if (!context->getExtensions().YUVTargetEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kYUVTargetExtensionRequired);
+ return false;
+ }
+
+ if (attachment != GL_COLOR_ATTACHMENT0)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidAttachment);
+ return false;
+ }
+
+ if (tex->getType() != TextureType::External)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kTextureTargetMismatch);
+ return false;
+ }
+ }
+ break;
+
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateFramebufferTexture3DOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ TextureTarget textargetPacked,
+ TextureID texture,
+ GLint level,
+ GLint zoffset)
+{
+ // We don't call into a base ValidateFramebufferTexture3D here because
+ // it doesn't exist for OpenGL ES. This function is replaced by
+ // FramebufferTextureLayer in ES 3.x, which has broader support.
+ if (!context->getExtensions().texture3DOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ // Attachments are required to be bound to level 0 without ES3 or the
+ // GL_OES_fbo_render_mipmap extension
+ if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmapOES &&
+ level != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidFramebufferTextureLevel);
+ return false;
+ }
+
+ if (!ValidateFramebufferTextureBase(context, entryPoint, target, attachment, texture, level))
+ {
+ return false;
+ }
+
+ if (texture.value != 0)
+ {
+ Texture *tex = context->getTexture(texture);
+ ASSERT(tex);
+
+ const Caps &caps = context->getCaps();
+
+ switch (textargetPacked)
+ {
+ case TextureTarget::_3D:
+ {
+ if (level > log2(caps.max3DTextureSize))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel);
+ return false;
+ }
+ if (zoffset >= caps.max3DTextureSize)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidZOffset);
+ return false;
+ }
+ if (tex->getType() != TextureType::_3D)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidTextureType);
+ return false;
+ }
+ }
+ break;
+
+ default:
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidTextureTarget);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateGenBuffers(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint n,
+ const BufferID *buffers)
+{
+ return ValidateGenOrDelete(context, entryPoint, n);
+}
+
+bool ValidateGenFramebuffers(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint n,
+ const FramebufferID *framebuffers)
+{
+ return ValidateGenOrDelete(context, entryPoint, n);
+}
+
+bool ValidateGenRenderbuffers(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint n,
+ const RenderbufferID *renderbuffers)
+{
+ return ValidateGenOrDelete(context, entryPoint, n);
+}
+
+bool ValidateGenTextures(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint n,
+ const TextureID *textures)
+{
+ return ValidateGenOrDelete(context, entryPoint, n);
+}
+
+bool ValidateGenerateMipmap(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target)
+{
+ return ValidateGenerateMipmapBase(context, entryPoint, target);
+}
+
+bool ValidateGetBufferParameteriv(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding target,
+ GLenum pname,
+ const GLint *params)
+{
+ return ValidateGetBufferParameterBase(context, entryPoint, target, pname, false, nullptr);
+}
+
+bool ValidateGetRenderbufferParameteriv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum pname,
+ const GLint *params)
+{
+ return ValidateGetRenderbufferParameterivBase(context, entryPoint, target, pname, nullptr);
+}
+
+bool ValidateGetShaderiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID shader,
+ GLenum pname,
+ const GLint *params)
+{
+ return ValidateGetShaderivBase(context, entryPoint, shader, pname, nullptr);
+}
+
+bool ValidateGetTexParameterfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLenum pname,
+ const GLfloat *params)
+{
+ return ValidateGetTexParameterBase(context, entryPoint, target, pname, nullptr);
+}
+
+bool ValidateGetTexParameteriv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLenum pname,
+ const GLint *params)
+{
+ return ValidateGetTexParameterBase(context, entryPoint, target, pname, nullptr);
+}
+
+bool ValidateGetTexParameterIivOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLenum pname,
+ const GLint *params)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+ return ValidateGetTexParameterBase(context, entryPoint, target, pname, nullptr);
+}
+
+bool ValidateGetTexParameterIuivOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLenum pname,
+ const GLuint *params)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+ return ValidateGetTexParameterBase(context, entryPoint, target, pname, nullptr);
+}
+
+bool ValidateGetUniformfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ const GLfloat *params)
+{
+ return ValidateGetUniformBase(context, entryPoint, program, location);
+}
+
+bool ValidateGetUniformiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ const GLint *params)
+{
+ return ValidateGetUniformBase(context, entryPoint, program, location);
+}
+
+bool ValidateGetVertexAttribfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum pname,
+ const GLfloat *params)
+{
+ return ValidateGetVertexAttribBase(context, entryPoint, index, pname, nullptr, false, false);
+}
+
+bool ValidateGetVertexAttribiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum pname,
+ const GLint *params)
+{
+ return ValidateGetVertexAttribBase(context, entryPoint, index, pname, nullptr, false, false);
+}
+
+bool ValidateGetVertexAttribPointerv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum pname,
+ void *const *pointer)
+{
+ return ValidateGetVertexAttribBase(context, entryPoint, index, pname, nullptr, true, false);
+}
+
+bool ValidateIsEnabled(const Context *context, angle::EntryPoint entryPoint, GLenum cap)
+{
+ if (!ValidCap(context, cap, true))
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, cap);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateLinkProgram(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program)
+{
+ if (context->hasActiveTransformFeedback(program))
+ {
+ // ES 3.0.4 section 2.15 page 91
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kTransformFeedbackActiveDuringLink);
+ return false;
+ }
+
+ Program *programObject = GetValidProgram(context, entryPoint, program);
+ if (!programObject)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateReadPixels(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ return ValidateReadPixelsBase(context, entryPoint, x, y, width, height, format, type, -1,
+ nullptr, nullptr, nullptr, pixels);
+}
+
+bool ValidateTexParameterf(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLenum pname,
+ GLfloat param)
+{
+ return ValidateTexParameterBase(context, entryPoint, target, pname, -1, false, &param);
+}
+
+bool ValidateTexParameterfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLenum pname,
+ const GLfloat *params)
+{
+ return ValidateTexParameterBase(context, entryPoint, target, pname, -1, true, params);
+}
+
+bool ValidateTexParameteri(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLenum pname,
+ GLint param)
+{
+ return ValidateTexParameterBase(context, entryPoint, target, pname, -1, false, &param);
+}
+
+bool ValidateTexParameteriv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLenum pname,
+ const GLint *params)
+{
+ return ValidateTexParameterBase(context, entryPoint, target, pname, -1, true, params);
+}
+
+bool ValidateTexParameterIivOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLenum pname,
+ const GLint *params)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+ return ValidateTexParameterBase(context, entryPoint, target, pname, -1, true, params);
+}
+
+bool ValidateTexParameterIuivOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLenum pname,
+ const GLuint *params)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+ return ValidateTexParameterBase(context, entryPoint, target, pname, -1, true, params);
+}
+
+bool ValidateUseProgram(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program)
+{
+ if (program.value != 0)
+ {
+ Program *programObject = context->getProgramResolveLink(program);
+ if (!programObject)
+ {
+ // ES 3.1.0 section 7.3 page 72
+ if (context->getShader(program))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExpectedProgramName);
+ return false;
+ }
+ else
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidProgramName);
+ return false;
+ }
+ }
+ if (!programObject->isLinked())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotLinked);
+ return false;
+ }
+ }
+ if (context->getState().isTransformFeedbackActiveUnpaused())
+ {
+ // ES 3.0.4 section 2.15 page 91
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kTransformFeedbackUseProgram);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateDeleteFencesNV(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const FenceNVID *fences)
+{
+ if (!context->getExtensions().fenceNV)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kNVFenceNotSupported);
+ return false;
+ }
+
+ if (n < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeCount);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateFinishFenceNV(const Context *context, angle::EntryPoint entryPoint, FenceNVID fence)
+{
+ if (!context->getExtensions().fenceNV)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kNVFenceNotSupported);
+ return false;
+ }
+
+ FenceNV *fenceObject = context->getFenceNV(fence);
+
+ if (fenceObject == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFence);
+ return false;
+ }
+
+ if (!fenceObject->isSet())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFenceState);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGenFencesNV(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const FenceNVID *fences)
+{
+ if (!context->getExtensions().fenceNV)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kNVFenceNotSupported);
+ return false;
+ }
+
+ if (n < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeCount);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetFenceivNV(const Context *context,
+ angle::EntryPoint entryPoint,
+ FenceNVID fence,
+ GLenum pname,
+ const GLint *params)
+{
+ if (!context->getExtensions().fenceNV)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kNVFenceNotSupported);
+ return false;
+ }
+
+ FenceNV *fenceObject = context->getFenceNV(fence);
+
+ if (fenceObject == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFence);
+ return false;
+ }
+
+ if (!fenceObject->isSet())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFenceState);
+ return false;
+ }
+
+ switch (pname)
+ {
+ case GL_FENCE_STATUS_NV:
+ case GL_FENCE_CONDITION_NV:
+ break;
+
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetGraphicsResetStatusEXT(const Context *context, angle::EntryPoint entryPoint)
+{
+ if (!context->getExtensions().robustnessEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetTranslatedShaderSourceANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID shader,
+ GLsizei bufsize,
+ const GLsizei *length,
+ const GLchar *source)
+{
+ if (!context->getExtensions().translatedShaderSourceANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ if (bufsize < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBufferSize);
+ return false;
+ }
+
+ Shader *shaderObject = context->getShader(shader);
+
+ if (!shaderObject)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidShaderName);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateIsFenceNV(const Context *context, angle::EntryPoint entryPoint, FenceNVID fence)
+{
+ if (!context->getExtensions().fenceNV)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kNVFenceNotSupported);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateSetFenceNV(const Context *context,
+ angle::EntryPoint entryPoint,
+ FenceNVID fence,
+ GLenum condition)
+{
+ if (!context->getExtensions().fenceNV)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kNVFenceNotSupported);
+ return false;
+ }
+
+ if (condition != GL_ALL_COMPLETED_NV)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFenceCondition);
+ return false;
+ }
+
+ FenceNV *fenceObject = context->getFenceNV(fence);
+
+ if (fenceObject == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFence);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateTestFenceNV(const Context *context, angle::EntryPoint entryPoint, FenceNVID fence)
+{
+ if (!context->getExtensions().fenceNV)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kNVFenceNotSupported);
+ return false;
+ }
+
+ FenceNV *fenceObject = context->getFenceNV(fence);
+
+ if (fenceObject == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFence);
+ return false;
+ }
+
+ if (fenceObject->isSet() != GL_TRUE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFenceState);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateTexStorage2DEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType type,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height)
+{
+ if (!context->getExtensions().textureStorageEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ if (context->getClientMajorVersion() < 3)
+ {
+ return ValidateES2TexStorageParametersBase(context, entryPoint, type, levels,
+ internalformat, width, height);
+ }
+
+ ASSERT(context->getClientMajorVersion() >= 3);
+ return ValidateES3TexStorage2DParameters(context, entryPoint, type, levels, internalformat,
+ width, height, 1);
+}
+
+bool ValidateVertexAttribDivisorANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLuint divisor)
+{
+ if (!context->getExtensions().instancedArraysANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ if (index >= static_cast<GLuint>(context->getCaps().maxVertexAttributes))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
+ return false;
+ }
+
+ if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
+ {
+ if (index == 0 && divisor != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kAttributeZeroRequiresDivisorLimitation);
+
+ // We also output an error message to the debugger window if tracing is active, so
+ // that developers can see the error message.
+ ERR() << kAttributeZeroRequiresDivisorLimitation;
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateVertexAttribDivisorEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLuint divisor)
+{
+ if (!context->getExtensions().instancedArraysEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ if (index >= static_cast<GLuint>(context->getCaps().maxVertexAttributes))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateTexImage3DOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ return ValidateTexImage3D(context, entryPoint, target, level, internalformat, width, height,
+ depth, border, format, type, pixels);
+}
+
+bool ValidatePopGroupMarkerEXT(const Context *context, angle::EntryPoint entryPoint)
+{
+ if (!context->getExtensions().debugMarkerEXT)
+ {
+ // The debug marker calls should not set error state
+ // However, it seems reasonable to set an error state if the extension is not enabled
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateTexStorage1DEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width)
+{
+ UNIMPLEMENTED();
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+}
+
+bool ValidateTexStorage3DEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth)
+{
+ if (!context->getExtensions().textureStorageEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateES3TexStorage3DParameters(context, entryPoint, target, levels, internalformat,
+ width, height, depth);
+}
+
+bool ValidateMaxShaderCompilerThreadsKHR(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint count)
+{
+ if (!context->getExtensions().parallelShaderCompileKHR)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+ return true;
+}
+
+bool ValidateMultiDrawArraysANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ const GLint *firsts,
+ const GLsizei *counts,
+ GLsizei drawcount)
+{
+ if (!context->getExtensions().multiDrawANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+ for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
+ {
+ if (!ValidateDrawArrays(context, entryPoint, mode, firsts[drawID], counts[drawID]))
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool ValidateMultiDrawElementsANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ const GLsizei *counts,
+ DrawElementsType type,
+ const GLvoid *const *indices,
+ GLsizei drawcount)
+{
+ if (!context->getExtensions().multiDrawANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+ for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
+ {
+ if (!ValidateDrawElements(context, entryPoint, mode, counts[drawID], type, indices[drawID]))
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool ValidateProvokingVertexANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProvokingVertexConvention modePacked)
+{
+ if (!context->getExtensions().provokingVertexANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ switch (modePacked)
+ {
+ case ProvokingVertexConvention::FirstVertexConvention:
+ case ProvokingVertexConvention::LastVertexConvention:
+ break;
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidProvokingVertex);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateFramebufferTexture2DMultisampleEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ TextureTarget textarget,
+ TextureID texture,
+ GLint level,
+ GLsizei samples)
+{
+ if (!context->getExtensions().multisampledRenderToTextureEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ if (samples < 0)
+ {
+ return false;
+ }
+
+ // EXT_multisampled_render_to_texture states that the value of samples
+ // must be less than or equal to MAX_SAMPLES_EXT (Context::getCaps().maxSamples)
+ // otherwise GL_INVALID_VALUE is generated.
+ if (samples > context->getCaps().maxSamples)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kSamplesOutOfRange);
+ return false;
+ }
+
+ if (!ValidateFramebufferTextureBase(context, entryPoint, target, attachment, texture, level))
+ {
+ return false;
+ }
+
+ // EXT_multisampled_render_to_texture returns INVALID_OPERATION when a sample number higher than
+ // the maximum sample number supported by this format is passed.
+ // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
+ if (texture.value != 0 && context->getClientMajorVersion() >= 3)
+ {
+ Texture *tex = context->getTexture(texture);
+ GLenum sizedInternalFormat = tex->getFormat(textarget, level).info->sizedInternalFormat;
+ const TextureCaps &formatCaps = context->getTextureCaps().get(sizedInternalFormat);
+ if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kSamplesOutOfRange);
+ return false;
+ }
+ }
+
+ // Unless EXT_multisampled_render_to_texture2 is enabled, only color attachment 0 can be used.
+ if (!context->getExtensions().multisampledRenderToTexture2EXT &&
+ attachment != GL_COLOR_ATTACHMENT0)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidAttachment);
+ return false;
+ }
+
+ if (!ValidTexture2DDestinationTarget(context, textarget))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateRenderbufferStorageMultisampleEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height)
+{
+ if (!context->getExtensions().multisampledRenderToTextureEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+ if (!ValidateRenderbufferStorageParametersBase(context, entryPoint, target, samples,
+ internalformat, width, height))
+ {
+ return false;
+ }
+
+ // EXT_multisampled_render_to_texture states that the value of samples
+ // must be less than or equal to MAX_SAMPLES_EXT (Context::getCaps().maxSamples)
+ // otherwise GL_INVALID_VALUE is generated.
+ if (samples > context->getCaps().maxSamples)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kSamplesOutOfRange);
+ return false;
+ }
+
+ // EXT_multisampled_render_to_texture returns GL_OUT_OF_MEMORY on failure to create
+ // 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->getClientMajorVersion() >= 3)
+ {
+ const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
+ if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
+ {
+ context->validationError(entryPoint, GL_OUT_OF_MEMORY, kSamplesOutOfRange);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void RecordBindTextureTypeError(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target)
+{
+ ASSERT(!context->getStateCache().isValidBindTextureType(target));
+
+ switch (target)
+ {
+ case TextureType::Rectangle:
+ ASSERT(!context->getExtensions().textureRectangleANGLE);
+ context->validationError(entryPoint, GL_INVALID_ENUM, kTextureRectangleNotSupported);
+ break;
+
+ case TextureType::_3D:
+ case TextureType::_2DArray:
+ ASSERT(context->getClientMajorVersion() < 3);
+ context->validationError(entryPoint, GL_INVALID_ENUM, kES3Required);
+ break;
+
+ case TextureType::_2DMultisample:
+ ASSERT(context->getClientVersion() < Version(3, 1) &&
+ !context->getExtensions().textureMultisampleANGLE);
+ context->validationError(entryPoint, GL_INVALID_ENUM,
+ kMultisampleTextureExtensionOrES31Required);
+ break;
+
+ case TextureType::_2DMultisampleArray:
+ ASSERT(!context->getExtensions().textureStorageMultisample2dArrayOES);
+ context->validationError(entryPoint, GL_INVALID_ENUM,
+ kMultisampleArrayExtensionRequired);
+ break;
+
+ case TextureType::External:
+ ASSERT(!context->getExtensions().EGLImageExternalOES &&
+ !context->getExtensions().EGLStreamConsumerExternalNV);
+ context->validationError(entryPoint, GL_INVALID_ENUM, kExternalTextureNotSupported);
+ break;
+
+ case TextureType::VideoImage:
+ ASSERT(!context->getExtensions().videoTextureWEBGL);
+ context->validationError(entryPoint, GL_INVALID_ENUM, kExtensionNotEnabled);
+ break;
+
+ case TextureType::Buffer:
+ ASSERT(!context->getExtensions().textureBufferOES &&
+ !context->getExtensions().textureBufferEXT);
+ context->validationError(entryPoint, GL_INVALID_ENUM, kExtensionNotEnabled);
+ break;
+
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget);
+ }
+}
+
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/validationES2.h b/gfx/angle/checkout/src/libANGLE/validationES2.h
new file mode 100644
index 0000000000..399779aa7c
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/validationES2.h
@@ -0,0 +1,207 @@
+//
+// Copyright 2018 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.
+//
+// validationES2.h:
+// Inlined validation functions for OpenGL ES 2.0 entry points.
+
+#ifndef LIBANGLE_VALIDATION_ES2_H_
+#define LIBANGLE_VALIDATION_ES2_H_
+
+#include "libANGLE/ErrorStrings.h"
+#include "libANGLE/validationES.h"
+#include "libANGLE/validationES2_autogen.h"
+
+namespace gl
+{
+ANGLE_INLINE bool ValidateDrawArrays(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLint first,
+ GLsizei count)
+{
+ return ValidateDrawArraysCommon(context, entryPoint, mode, first, count, 1);
+}
+
+ANGLE_INLINE bool ValidateUniform2f(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLfloat x,
+ GLfloat y)
+{
+ return ValidateUniform(context, entryPoint, GL_FLOAT_VEC2, location, 1);
+}
+
+ANGLE_INLINE bool ValidateBindBuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding target,
+ BufferID buffer)
+{
+ if (!context->isValidBufferBinding(target))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, err::kInvalidBufferTypes);
+ return false;
+ }
+
+ if (!context->getState().isBindGeneratesResourceEnabled() &&
+ !context->isBufferGenerated(buffer))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, err::kObjectNotGenerated);
+ return false;
+ }
+
+ return true;
+}
+
+ANGLE_INLINE bool ValidateDrawElements(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLsizei count,
+ DrawElementsType type,
+ const void *indices)
+{
+ return ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices, 1);
+}
+
+ANGLE_INLINE bool ValidateVertexAttribPointer(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLint size,
+ VertexAttribType type,
+ GLboolean normalized,
+ GLsizei stride,
+ const void *ptr)
+{
+ if (!ValidateFloatVertexFormat(context, entryPoint, index, size, type))
+ {
+ return false;
+ }
+
+ if (stride < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, err::kNegativeStride);
+ return false;
+ }
+
+ if (context->getClientVersion() >= ES_3_1)
+ {
+ const Caps &caps = context->getCaps();
+ if (stride > caps.maxVertexAttribStride)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ err::kExceedsMaxVertexAttribStride);
+ return false;
+ }
+
+ if (index >= static_cast<GLuint>(caps.maxVertexAttribBindings))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ err::kExceedsMaxVertexAttribBindings);
+ return false;
+ }
+ }
+
+ // [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,
+ // and the pointer argument is not NULL.
+ bool nullBufferAllowed = context->getState().areClientArraysEnabled() &&
+ context->getState().getVertexArray()->id().value == 0;
+ if (!nullBufferAllowed && context->getState().getTargetBuffer(BufferBinding::Array) == 0 &&
+ ptr != nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, err::kClientDataInVertexArray);
+ return false;
+ }
+
+ if (context->isWebGL())
+ {
+ // WebGL 1.0 [Section 6.14] Fixed point support
+ // The WebGL API does not support the GL_FIXED data type.
+ if (type == VertexAttribType::Fixed)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, err::kFixedNotInWebGL);
+ return false;
+ }
+
+ if (!ValidateWebGLVertexAttribPointer(context, entryPoint, type, normalized, stride, ptr,
+ false))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void RecordBindTextureTypeError(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target);
+
+ANGLE_INLINE bool ValidateBindTexture(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ TextureID texture)
+{
+ if (!context->getStateCache().isValidBindTextureType(target))
+ {
+ RecordBindTextureTypeError(context, entryPoint, target);
+ return false;
+ }
+
+ if (texture.value == 0)
+ {
+ return true;
+ }
+
+ Texture *textureObject = context->getTexture(texture);
+ if (textureObject && textureObject->getType() != target)
+ {
+ context->validationErrorF(
+ entryPoint, GL_INVALID_OPERATION, err::kTextureTargetMismatchWithLabel,
+ static_cast<uint8_t>(target), static_cast<uint8_t>(textureObject->getType()),
+ textureObject->getLabel().c_str());
+ return false;
+ }
+
+ if (!context->getState().isBindGeneratesResourceEnabled() &&
+ !context->isTextureGenerated(texture))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, err::kObjectNotGenerated);
+ return false;
+ }
+
+ return true;
+}
+
+// Validation of all Tex[Sub]Image2D parameters except TextureTarget.
+bool ValidateES2TexImageParametersBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget 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 void *pixels);
+
+// Validation of TexStorage*2DEXT
+bool ValidateES2TexStorageParametersBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height);
+
+} // namespace gl
+
+#endif // LIBANGLE_VALIDATION_ES2_H_
diff --git a/gfx/angle/checkout/src/libANGLE/validationES2_autogen.h b/gfx/angle/checkout/src/libANGLE/validationES2_autogen.h
new file mode 100644
index 0000000000..335139fe70
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/validationES2_autogen.h
@@ -0,0 +1,666 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml and gl_angle_ext.xml.
+//
+// Copyright 2020 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.
+//
+// validationES2_autogen.h:
+// Validation functions for the OpenGL ES 2.0 entry points.
+
+#ifndef LIBANGLE_VALIDATION_ES2_AUTOGEN_H_
+#define LIBANGLE_VALIDATION_ES2_AUTOGEN_H_
+
+#include "common/PackedEnums.h"
+#include "common/entry_points_enum_autogen.h"
+
+namespace gl
+{
+class Context;
+
+bool ValidateActiveTexture(const Context *context, angle::EntryPoint entryPoint, GLenum texture);
+bool ValidateAttachShader(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ ShaderProgramID shaderPacked);
+bool ValidateBindAttribLocation(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ GLuint index,
+ const GLchar *name);
+bool ValidateBindBuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding targetPacked,
+ BufferID bufferPacked);
+bool ValidateBindFramebuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ FramebufferID framebufferPacked);
+bool ValidateBindRenderbuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ RenderbufferID renderbufferPacked);
+bool ValidateBindTexture(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ TextureID texturePacked);
+bool ValidateBlendColor(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat red,
+ GLfloat green,
+ GLfloat blue,
+ GLfloat alpha);
+bool ValidateBlendEquation(const Context *context, angle::EntryPoint entryPoint, GLenum mode);
+bool ValidateBlendEquationSeparate(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum modeRGB,
+ GLenum modeAlpha);
+bool ValidateBlendFunc(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum sfactor,
+ GLenum dfactor);
+bool ValidateBlendFuncSeparate(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum sfactorRGB,
+ GLenum dfactorRGB,
+ GLenum sfactorAlpha,
+ GLenum dfactorAlpha);
+bool ValidateBufferData(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding targetPacked,
+ GLsizeiptr size,
+ const void *data,
+ BufferUsage usagePacked);
+bool ValidateBufferSubData(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding targetPacked,
+ GLintptr offset,
+ GLsizeiptr size,
+ const void *data);
+bool ValidateCheckFramebufferStatus(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target);
+bool ValidateClear(const Context *context, angle::EntryPoint entryPoint, GLbitfield mask);
+bool ValidateClearColor(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat red,
+ GLfloat green,
+ GLfloat blue,
+ GLfloat alpha);
+bool ValidateClearDepthf(const Context *context, angle::EntryPoint entryPoint, GLfloat d);
+bool ValidateClearStencil(const Context *context, angle::EntryPoint entryPoint, GLint s);
+bool ValidateColorMask(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLboolean red,
+ GLboolean green,
+ GLboolean blue,
+ GLboolean alpha);
+bool ValidateCompileShader(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID shaderPacked);
+bool ValidateCompressedTexImage2D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLsizei imageSize,
+ const void *data);
+bool ValidateCompressedTexSubImage2D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data);
+bool ValidateCopyTexImage2D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum internalformat,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLint border);
+bool ValidateCopyTexSubImage2D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height);
+bool ValidateCreateProgram(const Context *context, angle::EntryPoint entryPoint);
+bool ValidateCreateShader(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderType typePacked);
+bool ValidateCullFace(const Context *context,
+ angle::EntryPoint entryPoint,
+ CullFaceMode modePacked);
+bool ValidateDeleteBuffers(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const BufferID *buffersPacked);
+bool ValidateDeleteFramebuffers(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const FramebufferID *framebuffersPacked);
+bool ValidateDeleteProgram(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked);
+bool ValidateDeleteRenderbuffers(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const RenderbufferID *renderbuffersPacked);
+bool ValidateDeleteShader(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID shaderPacked);
+bool ValidateDeleteTextures(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const TextureID *texturesPacked);
+bool ValidateDepthFunc(const Context *context, angle::EntryPoint entryPoint, GLenum func);
+bool ValidateDepthMask(const Context *context, angle::EntryPoint entryPoint, GLboolean flag);
+bool ValidateDepthRangef(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat n,
+ GLfloat f);
+bool ValidateDetachShader(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ ShaderProgramID shaderPacked);
+bool ValidateDisable(const Context *context, angle::EntryPoint entryPoint, GLenum cap);
+bool ValidateDisableVertexAttribArray(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index);
+bool ValidateDrawArrays(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ GLint first,
+ GLsizei count);
+bool ValidateDrawElements(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices);
+bool ValidateEnable(const Context *context, angle::EntryPoint entryPoint, GLenum cap);
+bool ValidateEnableVertexAttribArray(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index);
+bool ValidateFinish(const Context *context, angle::EntryPoint entryPoint);
+bool ValidateFlush(const Context *context, angle::EntryPoint entryPoint);
+bool ValidateFramebufferRenderbuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ GLenum renderbuffertarget,
+ RenderbufferID renderbufferPacked);
+bool ValidateFramebufferTexture2D(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ TextureTarget textargetPacked,
+ TextureID texturePacked,
+ GLint level);
+bool ValidateFrontFace(const Context *context, angle::EntryPoint entryPoint, GLenum mode);
+bool ValidateGenBuffers(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const BufferID *buffersPacked);
+bool ValidateGenFramebuffers(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const FramebufferID *framebuffersPacked);
+bool ValidateGenRenderbuffers(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const RenderbufferID *renderbuffersPacked);
+bool ValidateGenTextures(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const TextureID *texturesPacked);
+bool ValidateGenerateMipmap(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked);
+bool ValidateGetActiveAttrib(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ GLuint index,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *size,
+ const GLenum *type,
+ const GLchar *name);
+bool ValidateGetActiveUniform(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ GLuint index,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *size,
+ const GLenum *type,
+ const GLchar *name);
+bool ValidateGetAttachedShaders(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ GLsizei maxCount,
+ const GLsizei *count,
+ const ShaderProgramID *shadersPacked);
+bool ValidateGetAttribLocation(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ const GLchar *name);
+bool ValidateGetBooleanv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ const GLboolean *data);
+bool ValidateGetBufferParameteriv(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding targetPacked,
+ GLenum pname,
+ const GLint *params);
+bool ValidateGetError(const Context *context, angle::EntryPoint entryPoint);
+bool ValidateGetFloatv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ const GLfloat *data);
+bool ValidateGetFramebufferAttachmentParameteriv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ GLenum pname,
+ const GLint *params);
+bool ValidateGetIntegerv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ const GLint *data);
+bool ValidateGetProgramInfoLog(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLchar *infoLog);
+bool ValidateGetProgramiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ GLenum pname,
+ const GLint *params);
+bool ValidateGetRenderbufferParameteriv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum pname,
+ const GLint *params);
+bool ValidateGetShaderInfoLog(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID shaderPacked,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLchar *infoLog);
+bool ValidateGetShaderPrecisionFormat(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum shadertype,
+ GLenum precisiontype,
+ const GLint *range,
+ const GLint *precision);
+bool ValidateGetShaderSource(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID shaderPacked,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLchar *source);
+bool ValidateGetShaderiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID shaderPacked,
+ GLenum pname,
+ const GLint *params);
+bool ValidateGetString(const Context *context, angle::EntryPoint entryPoint, GLenum name);
+bool ValidateGetTexParameterfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLfloat *params);
+bool ValidateGetTexParameteriv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLint *params);
+bool ValidateGetUniformLocation(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ const GLchar *name);
+bool ValidateGetUniformfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ const GLfloat *params);
+bool ValidateGetUniformiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ const GLint *params);
+bool ValidateGetVertexAttribPointerv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum pname,
+ void *const *pointer);
+bool ValidateGetVertexAttribfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum pname,
+ const GLfloat *params);
+bool ValidateGetVertexAttribiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum pname,
+ const GLint *params);
+bool ValidateHint(const Context *context, angle::EntryPoint entryPoint, GLenum target, GLenum mode);
+bool ValidateIsBuffer(const Context *context, angle::EntryPoint entryPoint, BufferID bufferPacked);
+bool ValidateIsEnabled(const Context *context, angle::EntryPoint entryPoint, GLenum cap);
+bool ValidateIsFramebuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ FramebufferID framebufferPacked);
+bool ValidateIsProgram(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked);
+bool ValidateIsRenderbuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ RenderbufferID renderbufferPacked);
+bool ValidateIsShader(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID shaderPacked);
+bool ValidateIsTexture(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texturePacked);
+bool ValidateLineWidth(const Context *context, angle::EntryPoint entryPoint, GLfloat width);
+bool ValidateLinkProgram(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked);
+bool ValidatePixelStorei(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLint param);
+bool ValidatePolygonOffset(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat factor,
+ GLfloat units);
+bool ValidateReadPixels(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ const void *pixels);
+bool ValidateReleaseShaderCompiler(const Context *context, angle::EntryPoint entryPoint);
+bool ValidateRenderbufferStorage(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height);
+bool ValidateSampleCoverage(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat value,
+ GLboolean invert);
+bool ValidateScissor(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height);
+bool ValidateShaderBinary(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei count,
+ const ShaderProgramID *shadersPacked,
+ GLenum binaryFormat,
+ const void *binary,
+ GLsizei length);
+bool ValidateShaderSource(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID shaderPacked,
+ GLsizei count,
+ const GLchar *const *string,
+ const GLint *length);
+bool ValidateStencilFunc(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum func,
+ GLint ref,
+ GLuint mask);
+bool ValidateStencilFuncSeparate(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum face,
+ GLenum func,
+ GLint ref,
+ GLuint mask);
+bool ValidateStencilMask(const Context *context, angle::EntryPoint entryPoint, GLuint mask);
+bool ValidateStencilMaskSeparate(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum face,
+ GLuint mask);
+bool ValidateStencilOp(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum fail,
+ GLenum zfail,
+ GLenum zpass);
+bool ValidateStencilOpSeparate(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum face,
+ GLenum sfail,
+ GLenum dpfail,
+ GLenum dppass);
+bool ValidateTexImage2D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const void *pixels);
+bool ValidateTexParameterf(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum pname,
+ GLfloat param);
+bool ValidateTexParameterfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLfloat *params);
+bool ValidateTexParameteri(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum pname,
+ GLint param);
+bool ValidateTexParameteriv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLint *params);
+bool ValidateTexSubImage2D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ const void *pixels);
+bool ValidateUniform1f(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLfloat v0);
+bool ValidateUniform1fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value);
+bool ValidateUniform1i(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLint v0);
+bool ValidateUniform1iv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value);
+bool ValidateUniform2f(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLfloat v0,
+ GLfloat v1);
+bool ValidateUniform2fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value);
+bool ValidateUniform2i(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLint v0,
+ GLint v1);
+bool ValidateUniform2iv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value);
+bool ValidateUniform3f(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLfloat v0,
+ GLfloat v1,
+ GLfloat v2);
+bool ValidateUniform3fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value);
+bool ValidateUniform3i(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLint v0,
+ GLint v1,
+ GLint v2);
+bool ValidateUniform3iv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value);
+bool ValidateUniform4f(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLfloat v0,
+ GLfloat v1,
+ GLfloat v2,
+ GLfloat v3);
+bool ValidateUniform4fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value);
+bool ValidateUniform4i(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLint v0,
+ GLint v1,
+ GLint v2,
+ GLint v3);
+bool ValidateUniform4iv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value);
+bool ValidateUniformMatrix2fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+bool ValidateUniformMatrix3fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+bool ValidateUniformMatrix4fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+bool ValidateUseProgram(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked);
+bool ValidateValidateProgram(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked);
+bool ValidateVertexAttrib1f(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLfloat x);
+bool ValidateVertexAttrib1fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLfloat *v);
+bool ValidateVertexAttrib2f(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLfloat x,
+ GLfloat y);
+bool ValidateVertexAttrib2fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLfloat *v);
+bool ValidateVertexAttrib3f(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLfloat x,
+ GLfloat y,
+ GLfloat z);
+bool ValidateVertexAttrib3fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLfloat *v);
+bool ValidateVertexAttrib4f(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLfloat x,
+ GLfloat y,
+ GLfloat z,
+ GLfloat w);
+bool ValidateVertexAttrib4fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLfloat *v);
+bool ValidateVertexAttribPointer(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLint size,
+ VertexAttribType typePacked,
+ GLboolean normalized,
+ GLsizei stride,
+ const void *pointer);
+bool ValidateViewport(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height);
+} // namespace gl
+
+#endif // LIBANGLE_VALIDATION_ES2_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libANGLE/validationES3.cpp b/gfx/angle/checkout/src/libANGLE/validationES3.cpp
new file mode 100644
index 0000000000..633cc02da9
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/validationES3.cpp
@@ -0,0 +1,5311 @@
+//
+// Copyright 2013 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.
+//
+
+// validationES3.cpp: Validation functions for OpenGL ES 3.0 entry point parameters
+
+#include "libANGLE/validationES3_autogen.h"
+
+#include "anglebase/numerics/safe_conversions.h"
+#include "common/mathutil.h"
+#include "common/utilities.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/ErrorStrings.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/FramebufferAttachment.h"
+#include "libANGLE/PixelLocalStorage.h"
+#include "libANGLE/Renderbuffer.h"
+#include "libANGLE/Texture.h"
+#include "libANGLE/VertexArray.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/validationES.h"
+
+using namespace angle;
+
+namespace gl
+{
+using namespace err;
+
+namespace
+{
+bool ValidateFramebufferTextureMultiviewBaseANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ TextureID texture,
+ GLint level,
+ GLsizei numViews)
+{
+ if (!(context->getExtensions().multiviewOVR || context->getExtensions().multiview2OVR))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kMultiviewNotAvailable);
+ return false;
+ }
+
+ if (!ValidateFramebufferTextureBase(context, entryPoint, target, attachment, texture, level))
+ {
+ return false;
+ }
+
+ if (texture.value != 0 && numViews < 1)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kMultiviewViewsTooSmall);
+ return false;
+ }
+
+ if (static_cast<GLuint>(numViews) > context->getCaps().maxViews)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kMultiviewViewsTooLarge);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateFramebufferTextureMultiviewLevelAndFormat(const Context *context,
+ angle::EntryPoint entryPoint,
+ const Texture *texture,
+ GLint level)
+{
+ TextureType type = texture->getType();
+ if (!ValidMipLevel(context, type, level))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel);
+ return false;
+ }
+
+ const auto &format = texture->getFormat(NonCubeTextureTypeToTarget(type), level);
+ if (format.info->compressed)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kCompressedTexturesNotAttachable);
+ return false;
+ }
+ return true;
+}
+
+bool ValidateUniformES3(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum uniformType,
+ UniformLocation location,
+ GLint count)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ return ValidateUniform(context, entryPoint, uniformType, location, count);
+}
+
+bool ValidateUniformMatrixES3(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum valueType,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose)
+{
+ // Check for ES3 uniform entry points
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ return ValidateUniformMatrix(context, entryPoint, valueType, location, count, transpose);
+}
+
+bool ValidateGenOrDeleteES3(const Context *context, angle::EntryPoint entryPoint, GLint n)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+ return ValidateGenOrDelete(context, entryPoint, n);
+}
+
+bool ValidateGenOrDeleteCountES3(const Context *context, angle::EntryPoint entryPoint, GLint count)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+ if (count < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeCount);
+ return false;
+ }
+ return true;
+}
+
+bool ValidateCopyTexture3DCommon(const Context *context,
+ angle::EntryPoint entryPoint,
+ const Texture *source,
+ GLint sourceLevel,
+ GLint srcInternalFormat,
+ const Texture *dest,
+ GLint destLevel,
+ GLint internalFormat,
+ TextureTarget destTarget)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ if (!context->getExtensions().copyTexture3dANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kANGLECopyTexture3DUnavailable);
+ return false;
+ }
+
+ if (!ValidTexture3DTarget(context, source->getType()))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget);
+ return false;
+ }
+
+ // Table 1.1 from the ANGLE_copy_texture_3d spec
+ switch (GetUnsizedFormat(srcInternalFormat))
+ {
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ case GL_RED:
+ case GL_RED_INTEGER:
+ case GL_RG:
+ case GL_RG_INTEGER:
+ case GL_RGB:
+ case GL_RGB_INTEGER:
+ case GL_RGBA:
+ case GL_RGBA_INTEGER:
+ case GL_DEPTH_COMPONENT:
+ case GL_DEPTH_STENCIL:
+ break;
+ default:
+ context->validationErrorF(entryPoint, GL_INVALID_OPERATION, kInvalidInternalFormat,
+ srcInternalFormat);
+ return false;
+ }
+
+ if (!ValidTexture3DTarget(context, TextureTargetToType(destTarget)))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget);
+ return false;
+ }
+
+ // Table 1.0 from the ANGLE_copy_texture_3d spec
+ switch (internalFormat)
+ {
+ case GL_RGB:
+ case GL_RGBA:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ case GL_ALPHA:
+ case GL_R8:
+ case GL_R8_SNORM:
+ case GL_R16F:
+ case GL_R32F:
+ case GL_R8UI:
+ case GL_R8I:
+ case GL_R16UI:
+ case GL_R16I:
+ case GL_R32UI:
+ case GL_R32I:
+ case GL_RG:
+ case GL_RG8:
+ case GL_RG8_SNORM:
+ case GL_RG16F:
+ case GL_RG32F:
+ case GL_RG8UI:
+ case GL_RG8I:
+ case GL_RG16UI:
+ case GL_RG16I:
+ case GL_RG32UI:
+ case GL_RG32I:
+ case GL_RGB8:
+ case GL_RGBX8_ANGLE:
+ case GL_SRGB8:
+ case GL_RGB565:
+ case GL_RGB8_SNORM:
+ case GL_R11F_G11F_B10F:
+ case GL_RGB9_E5:
+ case GL_RGB16F:
+ case GL_RGB32F:
+ case GL_RGB8UI:
+ case GL_RGB8I:
+ case GL_RGB16UI:
+ case GL_RGB16I:
+ case GL_RGB32UI:
+ case GL_RGB32I:
+ case GL_RGBA8:
+ case GL_SRGB8_ALPHA8:
+ case GL_RGBA8_SNORM:
+ case GL_RGB5_A1:
+ case GL_RGBA4:
+ case GL_RGB10_A2:
+ case GL_RGBA16F:
+ case GL_RGBA32F:
+ case GL_RGBA8UI:
+ case GL_RGBA8I:
+ case GL_RGB10_A2UI:
+ case GL_RGBA16UI:
+ case GL_RGBA16I:
+ case GL_RGBA32I:
+ case GL_RGBA32UI:
+ break;
+ default:
+ context->validationErrorF(entryPoint, GL_INVALID_OPERATION, kInvalidInternalFormat,
+ internalFormat);
+ return false;
+ }
+
+ return true;
+}
+} // anonymous namespace
+
+static bool ValidateTexImageFormatCombination(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLenum internalFormat,
+ GLenum format,
+ GLenum type)
+{
+ // Different validation if on desktop api
+ if (context->getClientType() == EGL_OPENGL_API)
+ {
+ // The type and format are valid if any supported internal format has that type and format
+ if (!ValidDesktopFormat(format))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat);
+ return false;
+ }
+
+ if (!ValidDesktopType(type))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidType);
+ return false;
+ }
+ }
+ else
+ {
+ // The type and format are valid if any supported internal format has that type and format.
+ // ANGLE_texture_external_yuv_sampling extension adds support for YUV formats
+ if (gl::IsYuvFormat(format))
+ {
+ if (!context->getExtensions().yuvInternalFormatANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat);
+ return false;
+ }
+ }
+ else
+ {
+ if (!ValidES3Format(format))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat);
+ return false;
+ }
+ }
+
+ if (!ValidES3Type(type) || (type == GL_HALF_FLOAT_OES && context->isWebGL()))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidType);
+ return false;
+ }
+ }
+
+ // For historical reasons, glTexImage2D and glTexImage3D pass in their internal format as a
+ // GLint instead of a GLenum. Therefor an invalid internal format gives a GL_INVALID_VALUE
+ // 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.
+ if (!ValidES3InternalFormat(internalFormat))
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_VALUE, kInvalidInternalFormat,
+ internalFormat);
+ return false;
+ }
+
+ // From the ES 3.0 spec section 3.8.3:
+ // Textures with a base internal format of DEPTH_COMPONENT or DEPTH_STENCIL are supported by
+ // texture image specification commands only if target is TEXTURE_2D, TEXTURE_2D_ARRAY, or
+ // TEXTURE_CUBE_MAP.Using these formats in conjunction with any other target will result in an
+ // INVALID_OPERATION error.
+ if (target == TextureType::_3D && (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, k3DDepthStencil);
+ return false;
+ }
+
+ if (context->getClientType() == EGL_OPENGL_API)
+ {
+ // Check if this is a valid format combination to load texture data
+ if (!ValidDesktopFormatCombination(format, type, internalFormat))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormatCombination);
+ return false;
+ }
+ }
+ else
+ {
+ // Check if this is a valid format combination to load texture data
+ // ANGLE_texture_external_yuv_sampling extension adds support for YUV formats
+ if (gl::IsYuvFormat(format))
+ {
+ if (type != GL_UNSIGNED_BYTE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kInvalidFormatCombination);
+ return false;
+ }
+ }
+ else
+ {
+ if (!ValidES3FormatCombination(format, type, internalFormat))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kInvalidFormatCombination);
+ return false;
+ }
+ }
+ }
+
+ const InternalFormat &formatInfo = GetInternalFormatInfo(internalFormat, type);
+ if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_OPERATION, kInvalidInternalFormat,
+ internalFormat);
+ return false;
+ }
+
+ return true;
+}
+
+static bool ValidateES3CompressedFormatForTexture2DArray(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum format)
+{
+ if (IsETC1Format(format) || IsPVRTC1Format(format))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kInternalFormatRequiresTexture2D);
+ return false;
+ }
+
+ return true;
+}
+
+static bool ValidateES3CompressedFormatForTexture3D(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum format)
+{
+ if (IsETC1Format(format) || IsPVRTC1Format(format))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kInternalFormatRequiresTexture2D);
+ return false;
+ }
+
+ if (IsETC2EACFormat(format))
+ {
+ // ES 3.1, Section 8.7, page 169.
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kInternalFormatRequiresTexture2DArray);
+ return false;
+ }
+
+ if (IsASTC2DFormat(format) && !(context->getExtensions().textureCompressionAstcHdrKHR ||
+ context->getExtensions().textureCompressionAstcSliced3dKHR))
+ {
+ // GL_KHR_texture_compression_astc_hdr, TEXTURE_3D is not supported without HDR profile
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kInternalFormatRequiresTexture2DArrayASTC);
+ return false;
+ }
+
+ if (IsS3TCFormat(format))
+ {
+ // GL_EXT_texture_compression_s3tc
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kInternalFormatRequiresTexture2DArrayS3TC);
+ return false;
+ }
+
+ if (IsRGTCFormat(format))
+ {
+ // GL_EXT_texture_compression_rgtc
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kInternalFormatRequiresTexture2DArrayRGTC);
+ return false;
+ }
+
+ if (IsBPTCFormat(format) && (context->getLimitations().noCompressedTexture3D))
+ {
+ // GL_EXT_texture_compression_bptc
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kInternalFormatRequiresTexture2DArrayBPTC);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateES3TexImageParametersBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLenum internalformat,
+ bool isCompressed,
+ bool isSubImage,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ GLsizei imageSize,
+ const void *pixels)
+{
+ TextureType texType = TextureTargetToType(target);
+
+ if (gl::IsYuvFormat(format))
+ {
+ // According to ANGLE_yuv_internal_format, the texture needs to be an immutable
+ // texture, texture target can only be TEXTURE_2D and there is no mipmap support
+ if (!context->getExtensions().yuvInternalFormatANGLE || !isSubImage)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat);
+ return false;
+ }
+
+ if (target != TextureTarget::_2D)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget);
+ return false;
+ }
+
+ if (level != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel);
+ return false;
+ }
+ }
+
+ // Validate image size
+ if (!ValidImageSizeParameters(context, entryPoint, texType, level, width, height, depth,
+ isSubImage))
+ {
+ // Error already processed.
+ return false;
+ }
+
+ // Verify zero border
+ if (border != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidBorder);
+ return false;
+ }
+
+ if (xoffset < 0 || yoffset < 0 || zoffset < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeOffset);
+ return false;
+ }
+
+ if (std::numeric_limits<GLsizei>::max() - xoffset < width ||
+ std::numeric_limits<GLsizei>::max() - yoffset < height ||
+ std::numeric_limits<GLsizei>::max() - zoffset < depth)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kOffsetOverflow);
+ return false;
+ }
+
+ const Caps &caps = context->getCaps();
+
+ switch (texType)
+ {
+ case TextureType::_2D:
+ case TextureType::External:
+ case TextureType::VideoImage:
+ if (width > (caps.max2DTextureSize >> level) ||
+ height > (caps.max2DTextureSize >> level))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize);
+ return false;
+ }
+ break;
+
+ case TextureType::Rectangle:
+ ASSERT(level == 0);
+ if (width > caps.maxRectangleTextureSize || height > caps.maxRectangleTextureSize)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize);
+ return false;
+ }
+ if (isCompressed)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kRectangleTextureCompressed);
+ return false;
+ }
+ break;
+
+ case TextureType::CubeMap:
+ if (!isSubImage && width != height)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kCubemapFacesEqualDimensions);
+ return false;
+ }
+
+ if (width > (caps.maxCubeMapTextureSize >> level))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize);
+ return false;
+ }
+ break;
+
+ case TextureType::_3D:
+ if (width > (caps.max3DTextureSize >> level) ||
+ height > (caps.max3DTextureSize >> level) ||
+ depth > (caps.max3DTextureSize >> level))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize);
+ return false;
+ }
+ break;
+
+ case TextureType::_2DArray:
+ if (width > (caps.max2DTextureSize >> level) ||
+ height > (caps.max2DTextureSize >> level) || depth > caps.maxArrayTextureLayers)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize);
+ return false;
+ }
+ break;
+
+ case TextureType::CubeMapArray:
+ if (!isSubImage && width != height)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kCubemapFacesEqualDimensions);
+ return false;
+ }
+
+ if (width > (caps.maxCubeMapTextureSize >> level))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize);
+ return false;
+ }
+
+ if (width > (caps.max3DTextureSize >> level) ||
+ height > (caps.max3DTextureSize >> level) ||
+ depth > (caps.max3DTextureSize >> level))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize);
+ return false;
+ }
+
+ if (!isSubImage && depth % 6 != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kCubemapInvalidDepth);
+ return false;
+ }
+ break;
+
+ case TextureType::InvalidEnum:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kEnumInvalid);
+ return false;
+ default:
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported,
+ ToGLenum(texType));
+ return false;
+ }
+
+ Texture *texture = context->getTextureByType(texType);
+ if (!texture)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kMissingTexture);
+ return false;
+ }
+
+ if (texture->getImmutableFormat() && !isSubImage)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kTextureIsImmutable);
+ return false;
+ }
+
+ // Validate texture formats
+ GLenum actualInternalFormat =
+ isSubImage ? texture->getFormat(target, level).info->internalFormat : internalformat;
+ if (isSubImage && actualInternalFormat == GL_NONE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidMipLevel);
+ return false;
+ }
+
+ const InternalFormat &actualFormatInfo = isSubImage
+ ? *texture->getFormat(target, level).info
+ : GetInternalFormatInfo(internalformat, type);
+ if (isCompressed)
+ {
+ // compressedTexSubImage does not generate GL_INVALID_ENUM when format is unknown or invalid
+ if (!isSubImage)
+ {
+ if (!actualFormatInfo.compressed && !actualFormatInfo.paletted)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kCompressedMismatch);
+ return false;
+ }
+
+ if (!actualFormatInfo.textureSupport(context->getClientVersion(),
+ context->getExtensions()))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat);
+ return false;
+ }
+ }
+
+ if (texType == TextureType::_2DArray)
+ {
+ GLenum compressedDataFormat = isSubImage ? format : internalformat;
+ if (!ValidateES3CompressedFormatForTexture2DArray(context, entryPoint,
+ compressedDataFormat))
+ {
+ // Error already generated.
+ return false;
+ }
+ }
+
+ if (texType == TextureType::_3D)
+ {
+ GLenum compressedDataFormat = isSubImage ? format : internalformat;
+ if (!ValidateES3CompressedFormatForTexture3D(context, entryPoint, compressedDataFormat))
+ {
+ // Error already generated.
+ return false;
+ }
+ }
+
+ if (isSubImage)
+ {
+ if (!ValidCompressedSubImageSize(
+ context, actualFormatInfo.internalFormat, xoffset, yoffset, zoffset, width,
+ height, depth, texture->getWidth(target, level),
+ texture->getHeight(target, level), texture->getDepth(target, level)))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kInvalidCompressedImageSize);
+ return false;
+ }
+
+ if (format != actualInternalFormat)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kMismatchedFormat);
+ return false;
+ }
+
+ // GL_EXT_compressed_ETC1_RGB8_sub_texture allows this format
+ if (IsETC1Format(actualInternalFormat) &&
+ !context->getExtensions().compressedETC1RGB8SubTextureEXT)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_OPERATION, kInvalidInternalFormat,
+ internalformat);
+ return false;
+ }
+ }
+ else
+ {
+ if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height,
+ depth))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kInvalidCompressedImageSize);
+ return false;
+ }
+ }
+
+ // Disallow 3D-only compressed formats from being set on 2D textures
+ if (actualFormatInfo.compressedBlockDepth > 1 && texType != TextureType::_2DArray)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidTextureTarget);
+ return false;
+ }
+ }
+ else
+ {
+ // Compressed formats are not valid internal formats for glTexImage*D
+ if (!isSubImage)
+ {
+ const InternalFormat &internalFormatInfo = GetSizedInternalFormatInfo(internalformat);
+ if (internalFormatInfo.compressed)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_VALUE, kInvalidInternalFormat,
+ internalformat);
+ return false;
+ }
+ }
+
+ if (!ValidateTexImageFormatCombination(context, entryPoint, texType, actualInternalFormat,
+ format, type))
+ {
+ return false;
+ }
+ }
+
+ // Validate sub image parameters
+ if (isSubImage)
+ {
+ if (isCompressed != actualFormatInfo.compressed)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kCompressedMismatch);
+ return false;
+ }
+
+ if (xoffset < 0 || yoffset < 0 || zoffset < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeOffset);
+ return false;
+ }
+
+ if (std::numeric_limits<GLsizei>::max() - xoffset < width ||
+ std::numeric_limits<GLsizei>::max() - yoffset < height ||
+ std::numeric_limits<GLsizei>::max() - zoffset < depth)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kOffsetOverflow);
+ return false;
+ }
+
+ if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
+ static_cast<size_t>(yoffset + height) > texture->getHeight(target, level) ||
+ static_cast<size_t>(zoffset + depth) > texture->getDepth(target, level))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kOffsetOverflow);
+ return false;
+ }
+
+ if (width > 0 && height > 0 && depth > 0 && pixels == nullptr &&
+ context->getState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kPixelDataNull);
+ return false;
+ }
+ }
+
+ GLenum sizeCheckFormat = isSubImage ? format : internalformat;
+ if (!ValidImageDataSize(context, entryPoint, texType, width, height, depth, sizeCheckFormat,
+ type, pixels, imageSize))
+ {
+ return false;
+ }
+
+ // Check for pixel unpack buffer related API errors
+ Buffer *pixelUnpackBuffer = context->getState().getTargetBuffer(BufferBinding::PixelUnpack);
+ if (pixelUnpackBuffer != nullptr)
+ {
+ // ...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>(GetTypeInfo(type).bytes);
+
+ if ((offset % dataBytesPerPixel) != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kDataTypeNotAligned);
+ return false;
+ }
+ }
+
+ // ...the buffer object's data store is currently mapped but not persistently.
+ if (pixelUnpackBuffer->isMapped() && !pixelUnpackBuffer->isPersistentlyMapped())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferMapped);
+ return false;
+ }
+ }
+
+ if (context->getExtensions().webglCompatibilityANGLE)
+ {
+ // Define:
+ // DataStoreWidth = (GL_UNPACK_ROW_LENGTH ? GL_UNPACK_ROW_LENGTH : width)
+ // DataStoreHeight = (GL_UNPACK_IMAGE_HEIGHT ? GL_UNPACK_IMAGE_HEIGHT : height)
+ //
+ // WebGL 2.0 imposes the following additional constraints:
+ //
+ // 1) texImage2D and texSubImage2D generate INVALID_OPERATION if:
+ // GL_UNPACK_SKIP_PIXELS + width > DataStoreWidth
+ // except for texImage2D if no GL_PIXEL_UNPACK_BUFFER is
+ // bound and _pixels_ is null.
+ //
+ // 2) texImage3D and texSubImage3D generate INVALID_OPERATION if:
+ // GL_UNPACK_SKIP_PIXELS + width > DataStoreWidth
+ // GL_UNPACK_SKIP_ROWS + height > DataStoreHeight
+ // except for texImage3D if no GL_PIXEL_UNPACK_BUFFER is
+ // bound and _pixels_ is null.
+ if (!pixelUnpackBuffer && !pixels && !isSubImage)
+ {
+ // Exception case for texImage2D or texImage3D, above.
+ }
+ else
+ {
+ const auto &unpack = context->getState().getUnpackState();
+ GLint dataStoreWidth = unpack.rowLength ? unpack.rowLength : width;
+ if (unpack.skipPixels + width > dataStoreWidth)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kInvalidUnpackParametersForWebGL);
+ return false;
+ }
+ if (target == TextureTarget::_3D || target == TextureTarget::_2DArray)
+ {
+ GLint dataStoreHeight = unpack.imageHeight ? unpack.imageHeight : height;
+ if (unpack.skipRows + height > dataStoreHeight)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kInvalidUnpackParametersForWebGL);
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+bool ValidateES3TexImage2DParameters(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLenum internalformat,
+ bool isCompressed,
+ bool isSubImage,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ GLsizei imageSize,
+ const void *pixels)
+{
+ if (!ValidTexture2DDestinationTarget(context, target))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget);
+ return false;
+ }
+
+ return ValidateES3TexImageParametersBase(
+ context, entryPoint, target, level, internalformat, isCompressed, isSubImage, xoffset,
+ yoffset, zoffset, width, height, depth, border, format, type, imageSize, pixels);
+}
+
+bool ValidateES3TexImage3DParameters(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLenum internalformat,
+ bool isCompressed,
+ bool isSubImage,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *pixels)
+{
+ if (!ValidTexture3DDestinationTarget(context, target))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget);
+ return false;
+ }
+
+ return ValidateES3TexImageParametersBase(
+ context, entryPoint, target, level, internalformat, isCompressed, isSubImage, xoffset,
+ yoffset, zoffset, width, height, depth, border, format, type, bufSize, pixels);
+}
+
+struct EffectiveInternalFormatInfo
+{
+ GLenum effectiveFormat;
+ GLenum destFormat;
+ GLuint minRedBits;
+ GLuint maxRedBits;
+ GLuint minGreenBits;
+ GLuint maxGreenBits;
+ GLuint minBlueBits;
+ GLuint maxBlueBits;
+ GLuint minAlphaBits;
+ GLuint maxAlphaBits;
+};
+
+static bool QueryEffectiveFormatList(const InternalFormat &srcFormat,
+ GLenum targetFormat,
+ const EffectiveInternalFormatInfo *list,
+ size_t size,
+ GLenum *outEffectiveFormat)
+{
+ for (size_t curFormat = 0; curFormat < size; ++curFormat)
+ {
+ const EffectiveInternalFormatInfo &formatInfo = list[curFormat];
+ if ((formatInfo.destFormat == targetFormat) &&
+ (formatInfo.minRedBits <= srcFormat.redBits &&
+ formatInfo.maxRedBits >= srcFormat.redBits) &&
+ (formatInfo.minGreenBits <= srcFormat.greenBits &&
+ formatInfo.maxGreenBits >= srcFormat.greenBits) &&
+ (formatInfo.minBlueBits <= srcFormat.blueBits &&
+ formatInfo.maxBlueBits >= srcFormat.blueBits) &&
+ (formatInfo.minAlphaBits <= srcFormat.alphaBits &&
+ formatInfo.maxAlphaBits >= srcFormat.alphaBits))
+ {
+ *outEffectiveFormat = formatInfo.effectiveFormat;
+ return true;
+ }
+ }
+
+ *outEffectiveFormat = GL_NONE;
+ return false;
+}
+
+bool GetSizedEffectiveInternalFormatInfo(const InternalFormat &srcFormat,
+ GLenum *outEffectiveFormat)
+{
+ // OpenGL ES 3.0.3 Specification, Table 3.17, pg 141:
+ // Effective internal format coresponding to destination internal format and linear source
+ // buffer component sizes.
+ // | Source channel min/max sizes |
+ // Effective Internal Format | N/A | R | G | B | A |
+ // clang-format off
+ constexpr EffectiveInternalFormatInfo list[] = {
+ { GL_ALPHA8_EXT, GL_NONE, 0, 0, 0, 0, 0, 0, 1, 8 },
+ { GL_R8, GL_NONE, 1, 8, 0, 0, 0, 0, 0, 0 },
+ { GL_RG8, GL_NONE, 1, 8, 1, 8, 0, 0, 0, 0 },
+ { GL_RGB565, GL_NONE, 1, 5, 1, 6, 1, 5, 0, 0 },
+ { GL_RGB8, GL_NONE, 6, 8, 7, 8, 6, 8, 0, 0 },
+ { GL_RGBA4, GL_NONE, 1, 4, 1, 4, 1, 4, 1, 4 },
+ { GL_RGB5_A1, GL_NONE, 5, 5, 5, 5, 5, 5, 1, 1 },
+ { GL_RGBA8, GL_NONE, 5, 8, 5, 8, 5, 8, 2, 8 },
+ { GL_RGB10_A2, GL_NONE, 9, 10, 9, 10, 9, 10, 2, 2 },
+ };
+ // clang-format on
+
+ return QueryEffectiveFormatList(srcFormat, GL_NONE, list, ArraySize(list), outEffectiveFormat);
+}
+
+bool GetUnsizedEffectiveInternalFormatInfo(const InternalFormat &srcFormat,
+ const InternalFormat &destFormat,
+ GLenum *outEffectiveFormat)
+{
+ constexpr GLuint umax = UINT_MAX;
+
+ // OpenGL ES 3.0.3 Specification, Table 3.17, pg 141:
+ // Effective internal format coresponding to destination internal format andlinear source buffer
+ // component sizes.
+ // | Source channel min/max sizes |
+ // Effective Internal Format | Dest Format | R | G | B | A |
+ // clang-format off
+ constexpr EffectiveInternalFormatInfo list[] = {
+ { GL_ALPHA8_EXT, GL_ALPHA, 0, umax, 0, umax, 0, umax, 1, 8 },
+ { GL_LUMINANCE8_EXT, GL_LUMINANCE, 1, 8, 0, umax, 0, umax, 0, umax },
+ { GL_LUMINANCE8_ALPHA8_EXT, GL_LUMINANCE_ALPHA, 1, 8, 0, umax, 0, umax, 1, 8 },
+ { GL_RGB565, GL_RGB, 1, 5, 1, 6, 1, 5, 0, umax },
+ { GL_RGB8, GL_RGB, 6, 8, 7, 8, 6, 8, 0, umax },
+ { GL_RGBA4, GL_RGBA, 1, 4, 1, 4, 1, 4, 1, 4 },
+ { GL_RGB5_A1, GL_RGBA, 5, 5, 5, 5, 5, 5, 1, 1 },
+ { GL_RGBA8, GL_RGBA, 5, 8, 5, 8, 5, 8, 5, 8 },
+ };
+ // clang-format on
+
+ return QueryEffectiveFormatList(srcFormat, destFormat.format, list, ArraySize(list),
+ outEffectiveFormat);
+}
+
+static bool GetEffectiveInternalFormat(const InternalFormat &srcFormat,
+ const InternalFormat &destFormat,
+ GLenum *outEffectiveFormat)
+{
+ if (destFormat.sized)
+ {
+ return GetSizedEffectiveInternalFormatInfo(srcFormat, outEffectiveFormat);
+ }
+ else
+ {
+ return GetUnsizedEffectiveInternalFormatInfo(srcFormat, destFormat, outEffectiveFormat);
+ }
+}
+
+static bool EqualOrFirstZero(GLuint first, GLuint second)
+{
+ return first == 0 || first == second;
+}
+
+static bool IsValidES3CopyTexImageCombination(const InternalFormat &textureFormatInfo,
+ const InternalFormat &framebufferFormatInfo,
+ FramebufferID readBufferHandle)
+{
+ if (!ValidES3CopyConversion(textureFormatInfo.format, framebufferFormatInfo.format))
+ {
+ return false;
+ }
+
+ // 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 ((textureFormatInfo.colorEncoding == GL_SRGB) !=
+ (framebufferFormatInfo.colorEncoding == GL_SRGB))
+ {
+ return false;
+ }
+
+ if (((textureFormatInfo.componentType == GL_INT) !=
+ (framebufferFormatInfo.componentType == GL_INT)) ||
+ ((textureFormatInfo.componentType == GL_UNSIGNED_INT) !=
+ (framebufferFormatInfo.componentType == GL_UNSIGNED_INT)))
+ {
+ return false;
+ }
+
+ if ((textureFormatInfo.componentType == GL_UNSIGNED_NORMALIZED ||
+ textureFormatInfo.componentType == GL_SIGNED_NORMALIZED) &&
+ !(framebufferFormatInfo.componentType == GL_UNSIGNED_NORMALIZED ||
+ framebufferFormatInfo.componentType == GL_SIGNED_NORMALIZED))
+ {
+ return false;
+ }
+
+ // SNORM is not supported (e.g. is not in the tables of "effective internal format" that
+ // correspond to internal formats.
+ if (textureFormatInfo.componentType == GL_SIGNED_NORMALIZED)
+ {
+ return false;
+ }
+
+ // Section 3.8.5 of the GLES 3.0.3 (and section 8.6 of the GLES 3.2) spec has a caveat, that
+ // the KHR dEQP tests enforce:
+ //
+ // Note that the above rules disallow matches where some components sizes are smaller and
+ // others are larger (such as RGB10_A2).
+ if (!textureFormatInfo.sized && (framebufferFormatInfo.internalFormat == GL_RGB10_A2))
+ {
+ return false;
+ }
+
+ // GLES specification 3.0.3, sec 3.8.5, pg 139-140:
+ // The effective internal format of the source buffer is determined with the following rules
+ // applied in order:
+ // * If the source buffer is a texture or renderbuffer that was created with a sized internal
+ // format then the effective internal format is the source buffer's sized internal format.
+ // * If the source buffer is a texture that was created with an unsized base internal format,
+ // then the effective internal format is the source image array's effective internal
+ // format, as specified by table 3.12, which is determined from the <format> and <type>
+ // that were used when the source image array was specified by TexImage*.
+ // * Otherwise the effective internal format is determined by the row in table 3.17 or 3.18
+ // where Destination Internal Format matches internalformat and where the [source channel
+ // sizes] are consistent with the values of the source buffer's [channel sizes]. Table 3.17
+ // is used if the FRAMEBUFFER_ATTACHMENT_ENCODING is LINEAR and table 3.18 is used if the
+ // FRAMEBUFFER_ATTACHMENT_ENCODING is SRGB.
+ const InternalFormat *sourceEffectiveFormat = nullptr;
+ if (readBufferHandle.value != 0)
+ {
+ // Not the default framebuffer, therefore the read buffer must be a user-created texture or
+ // renderbuffer
+ if (framebufferFormatInfo.sized)
+ {
+ 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.
+ sourceEffectiveFormat =
+ &GetSizedInternalFormatInfo(framebufferFormatInfo.sizedInternalFormat);
+ }
+ }
+ else
+ {
+ // 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 (framebufferFormatInfo.colorEncoding == GL_LINEAR)
+ {
+ GLenum effectiveFormat;
+ if (GetEffectiveInternalFormat(framebufferFormatInfo, textureFormatInfo,
+ &effectiveFormat))
+ {
+ sourceEffectiveFormat = &GetSizedInternalFormatInfo(effectiveFormat);
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else if (framebufferFormatInfo.colorEncoding == GL_SRGB)
+ {
+ // SRGB buffers can only be copied to sized format destinations according to table 3.18
+ if (textureFormatInfo.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 = &GetSizedInternalFormatInfo(GL_SRGB8_ALPHA8);
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else
+ {
+ UNREACHABLE();
+ return false;
+ }
+ }
+
+ if (textureFormatInfo.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(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.
+}
+
+bool ValidateES3CopyTexImageParametersBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLenum internalformat,
+ bool isSubImage,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLint border)
+{
+ Format textureFormat = Format::Invalid();
+ if (!ValidateCopyTexImageParametersBase(context, entryPoint, target, level, internalformat,
+ isSubImage, xoffset, yoffset, zoffset, x, y, width,
+ height, border, &textureFormat))
+ {
+ return false;
+ }
+ ASSERT(textureFormat.valid() || !isSubImage);
+
+ const auto &state = context->getState();
+ Framebuffer *framebuffer = state.getReadFramebuffer();
+ FramebufferID readFramebufferID = framebuffer->id();
+
+ if (!ValidateFramebufferComplete(context, entryPoint, framebuffer))
+ {
+ return false;
+ }
+
+ // needIntrinsic = true. Treat renderToTexture textures as single sample since they will be
+ // resolved before copying
+ if (!framebuffer->isDefault() &&
+ !ValidateFramebufferNotMultisampled(context, entryPoint, framebuffer, true))
+ {
+ return false;
+ }
+
+ const FramebufferAttachment *source = framebuffer->getReadColorAttachment();
+
+ // According to ES 3.x spec, if the internalformat of the texture
+ // is RGB9_E5 and copy to such a texture, generate INVALID_OPERATION.
+ if (textureFormat.info->internalFormat == GL_RGB9_E5)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFormat);
+ return false;
+ }
+
+ if (isSubImage)
+ {
+ if (!IsValidES3CopyTexImageCombination(*textureFormat.info, *source->getFormat().info,
+ readFramebufferID))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidCopyCombination);
+ return false;
+ }
+ }
+ else
+ {
+ // Use format/type from the source FBO. (Might not be perfect for all cases?)
+ const InternalFormat &framebufferFormat = *source->getFormat().info;
+ const InternalFormat &copyFormat = GetInternalFormatInfo(internalformat, GL_UNSIGNED_BYTE);
+ if (!IsValidES3CopyTexImageCombination(copyFormat, framebufferFormat, readFramebufferID))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidCopyCombination);
+ return false;
+ }
+ }
+
+ // If width or height is zero, it is a no-op. Return false without setting an error.
+ return (width > 0 && height > 0);
+}
+
+bool ValidateES3CopyTexImage2DParameters(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLenum internalformat,
+ bool isSubImage,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLint border)
+{
+ if (!ValidTexture2DDestinationTarget(context, target))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget);
+ return false;
+ }
+
+ return ValidateES3CopyTexImageParametersBase(context, entryPoint, target, level, internalformat,
+ isSubImage, xoffset, yoffset, zoffset, x, y, width,
+ height, border);
+}
+
+bool ValidateES3CopyTexImage3DParameters(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLenum internalformat,
+ bool isSubImage,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLint border)
+{
+ if (!ValidTexture3DDestinationTarget(context, target))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget);
+ return false;
+ }
+
+ return ValidateES3CopyTexImageParametersBase(context, entryPoint, target, level, internalformat,
+ isSubImage, xoffset, yoffset, zoffset, x, y, width,
+ height, border);
+}
+
+bool ValidateES3TexStorageParametersLevel(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLsizei levels,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth)
+{
+ GLsizei maxDim = std::max(width, height);
+ if (target != TextureType::_2DArray)
+ {
+ maxDim = std::max(maxDim, depth);
+ }
+
+ if (levels > log2(maxDim) + 1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidMipLevels);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateES3TexStorageParametersExtent(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLsizei levels,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth)
+{
+ const Caps &caps = context->getCaps();
+
+ switch (target)
+ {
+ case TextureType::_2D:
+ {
+ if (width > caps.max2DTextureSize || height > caps.max2DTextureSize)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize);
+ return false;
+ }
+ }
+ break;
+
+ case TextureType::Rectangle:
+ {
+ if (levels != 1)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevels);
+ return false;
+ }
+
+ if (width > caps.maxRectangleTextureSize || height > caps.maxRectangleTextureSize)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize);
+ return false;
+ }
+ }
+ break;
+
+ case TextureType::CubeMap:
+ {
+ if (width != height)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kCubemapFacesEqualDimensions);
+ return false;
+ }
+
+ if (width > caps.maxCubeMapTextureSize)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize);
+ return false;
+ }
+ }
+ break;
+
+ case TextureType::_3D:
+ {
+ if (width > caps.max3DTextureSize || height > caps.max3DTextureSize ||
+ depth > caps.max3DTextureSize)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize);
+ return false;
+ }
+ }
+ break;
+
+ case TextureType::_2DArray:
+ {
+ if (width > caps.max2DTextureSize || height > caps.max2DTextureSize ||
+ depth > caps.maxArrayTextureLayers)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize);
+ return false;
+ }
+ }
+ break;
+
+ case TextureType::CubeMapArray:
+ {
+ if (width != height)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kCubemapFacesEqualDimensions);
+ return false;
+ }
+
+ if (width > caps.maxCubeMapTextureSize)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize);
+ return false;
+ }
+
+ if (width > caps.max3DTextureSize || height > caps.max3DTextureSize ||
+ depth > caps.max3DTextureSize)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize);
+ return false;
+ }
+
+ if (depth % 6 != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kCubemapInvalidDepth);
+ return false;
+ }
+ }
+ break;
+
+ default:
+ UNREACHABLE();
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateES3TexStorageParametersTexObject(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target)
+{
+ Texture *texture = context->getTextureByType(target);
+ if (!texture || texture->id().value == 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kMissingTexture);
+ return false;
+ }
+
+ if (texture->getImmutableFormat())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kTextureIsImmutable);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateES3TexStorageParametersFormat(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth)
+{
+ // From ANGLE_texture_external_yuv_sampling:
+ // Texture target can only be TEXTURE_2D, there is no mipmap support
+ if (gl::IsYuvFormat(internalformat))
+ {
+ if (!context->getExtensions().yuvInternalFormatANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat);
+ return false;
+ }
+
+ if (target != TextureType::_2D)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget);
+ return false;
+ }
+
+ if (levels != 1)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel);
+ return false;
+ }
+ }
+
+ const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
+ if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat);
+ return false;
+ }
+
+ if (!formatInfo.sized)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat);
+ return false;
+ }
+
+ if (formatInfo.compressed)
+ {
+ if (target == TextureType::Rectangle)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kRectangleTextureCompressed);
+ return false;
+ }
+
+ if (target == TextureType::_2DArray)
+ {
+ if (!ValidateES3CompressedFormatForTexture2DArray(context, entryPoint,
+ formatInfo.internalFormat))
+ {
+ // Error already generated.
+ return false;
+ }
+ }
+
+ if (target == TextureType::_3D)
+ {
+ if (!ValidateES3CompressedFormatForTexture3D(context, entryPoint,
+ formatInfo.internalFormat))
+ {
+ // Error already generated.
+ return false;
+ }
+ }
+
+ if (!ValidCompressedImageSize(context, formatInfo.internalFormat, 0, width, height, depth))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidCompressedImageSize);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateES3TexStorageParametersBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth)
+{
+ if (width < 1 || height < 1 || depth < 1 || levels < 1)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kTextureSizeTooSmall);
+ return false;
+ }
+
+ if (!ValidateES3TexStorageParametersLevel(context, entryPoint, target, levels, width, height,
+ depth))
+ {
+ // Error already generated.
+ return false;
+ }
+
+ if (!ValidateES3TexStorageParametersExtent(context, entryPoint, target, levels, width, height,
+ depth))
+ {
+ // Error already generated.
+ return false;
+ }
+
+ if (!ValidateES3TexStorageParametersTexObject(context, entryPoint, target))
+ {
+ // Error already generated.
+ return false;
+ }
+
+ if (!ValidateES3TexStorageParametersFormat(context, entryPoint, target, levels, internalformat,
+ width, height, depth))
+ {
+ // Error already generated.
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateES3TexStorage2DParameters(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth)
+{
+ if (!ValidTexture2DTarget(context, target))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget);
+ return false;
+ }
+
+ return ValidateES3TexStorageParametersBase(context, entryPoint, target, levels, internalformat,
+ width, height, depth);
+}
+
+bool ValidateES3TexStorage3DParameters(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth)
+{
+ if (!ValidTexture3DTarget(context, target))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget);
+ return false;
+ }
+
+ return ValidateES3TexStorageParametersBase(context, entryPoint, target, levels, internalformat,
+ width, height, depth);
+}
+
+bool ValidateBeginQuery(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryType target,
+ QueryID id)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ return ValidateBeginQueryBase(context, entryPoint, target, id);
+}
+
+bool ValidateEndQuery(const Context *context, angle::EntryPoint entryPoint, QueryType target)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ return ValidateEndQueryBase(context, entryPoint, target);
+}
+
+bool ValidateGetQueryiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryType target,
+ GLenum pname,
+ const GLint *params)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ return ValidateGetQueryivBase(context, entryPoint, target, pname, nullptr);
+}
+
+bool ValidateGetQueryObjectuiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID id,
+ GLenum pname,
+ const GLuint *params)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ return ValidateGetQueryObjectValueBase(context, entryPoint, id, pname, nullptr);
+}
+
+bool ValidateFramebufferTextureLayer(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ TextureID texture,
+ GLint level,
+ GLint layer)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ if (!ValidateFramebufferTextureBase(context, entryPoint, target, attachment, texture, level))
+ {
+ return false;
+ }
+
+ const Caps &caps = context->getCaps();
+ if (texture.value != 0)
+ {
+ if (layer < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeLayer);
+ return false;
+ }
+
+ Texture *tex = context->getTexture(texture);
+ ASSERT(tex);
+
+ switch (tex->getType())
+ {
+ case TextureType::_2DArray:
+ {
+ if (level > log2(caps.max2DTextureSize))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kFramebufferTextureInvalidMipLevel);
+ return false;
+ }
+
+ if (layer >= caps.maxArrayTextureLayers)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kFramebufferTextureInvalidLayer);
+ return false;
+ }
+ }
+ break;
+
+ case TextureType::_3D:
+ {
+ if (level > log2(caps.max3DTextureSize))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kFramebufferTextureInvalidMipLevel);
+ return false;
+ }
+
+ if (layer >= caps.max3DTextureSize)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kFramebufferTextureInvalidLayer);
+ return false;
+ }
+ }
+ break;
+
+ case TextureType::_2DMultisampleArray:
+ {
+ if (level != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kFramebufferTextureInvalidMipLevel);
+ return false;
+ }
+
+ if (layer >= caps.maxArrayTextureLayers)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kFramebufferTextureInvalidLayer);
+ return false;
+ }
+ }
+ break;
+
+ case TextureType::CubeMap:
+ {
+ if (level > log2(caps.maxCubeMapTextureSize))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kFramebufferTextureInvalidMipLevel);
+ return false;
+ }
+
+ if (layer >= static_cast<GLint>(kCubeFaceCount))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kFramebufferTextureInvalidLayer);
+ return false;
+ }
+ }
+ break;
+
+ case TextureType::CubeMapArray:
+ {
+ if (level > log2(caps.maxCubeMapTextureSize))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kFramebufferTextureInvalidMipLevel);
+ return false;
+ }
+
+ if (layer >= caps.maxArrayTextureLayers)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kFramebufferTextureInvalidLayer);
+ return false;
+ }
+ }
+ break;
+
+ default:
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kFramebufferTextureLayerIncorrectTextureType);
+ return false;
+ }
+
+ const auto &format = tex->getFormat(TextureTypeToTarget(tex->getType(), layer), level);
+ if (format.info->compressed)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kCompressedTexturesNotAttachable);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateInvalidateFramebuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLsizei numAttachments,
+ const GLenum *attachments)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ bool defaultFramebuffer = false;
+
+ switch (target)
+ {
+ case GL_DRAW_FRAMEBUFFER:
+ case GL_FRAMEBUFFER:
+ defaultFramebuffer = context->getState().getDrawFramebuffer()->isDefault();
+ break;
+ case GL_READ_FRAMEBUFFER:
+ defaultFramebuffer = context->getState().getReadFramebuffer()->isDefault();
+ break;
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFramebufferTarget);
+ return false;
+ }
+
+ return ValidateDiscardFramebufferBase(context, entryPoint, target, numAttachments, attachments,
+ defaultFramebuffer);
+}
+
+bool ValidateInvalidateSubFramebuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLsizei numAttachments,
+ const GLenum *attachments,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height)
+{
+ if (width < 0 || height < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeSize);
+ return false;
+ }
+
+ return ValidateInvalidateFramebuffer(context, entryPoint, target, numAttachments, attachments);
+}
+
+bool ValidateClearBuffer(const Context *context, angle::EntryPoint entryPoint)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ if (!ValidateFramebufferComplete(context, entryPoint, context->getState().getDrawFramebuffer()))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateDrawRangeElements(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ DrawElementsType type,
+ const void *indices)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ if (end < start)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidElementRange);
+ return false;
+ }
+
+ if (!ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices, 0))
+ {
+ return false;
+ }
+
+ // Skip range checks for no-op calls.
+ if (count <= 0)
+ {
+ return true;
+ }
+
+ return true;
+}
+
+bool ValidateGetUniformuiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ const GLuint *params)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ return ValidateGetUniformBase(context, entryPoint, program, location);
+}
+
+bool ValidateReadBuffer(const Context *context, angle::EntryPoint entryPoint, GLenum src)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ const Framebuffer *readFBO = context->getState().getReadFramebuffer();
+
+ if (readFBO == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kNoReadFramebuffer);
+ return false;
+ }
+
+ if (src == GL_NONE)
+ {
+ return true;
+ }
+
+ if (src != GL_BACK && (src < GL_COLOR_ATTACHMENT0 || src > GL_COLOR_ATTACHMENT31))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidReadBuffer);
+ return false;
+ }
+
+ if (readFBO->isDefault())
+ {
+ if (src != GL_BACK)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidDefaultReadBuffer);
+ return false;
+ }
+ }
+ else
+ {
+ GLuint drawBuffer = static_cast<GLuint>(src - GL_COLOR_ATTACHMENT0);
+
+ if (drawBuffer >= static_cast<GLuint>(context->getCaps().maxColorAttachments))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExceedsMaxColorAttachments);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateCompressedTexImage3D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLsizei imageSize,
+ const void *data)
+{
+ if ((context->getClientMajorVersion() < 3) && !context->getExtensions().texture3DOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ if (!ValidTextureTarget(context, TextureTargetToType(target)))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget);
+ return false;
+ }
+
+ // Validate image size
+ if (!ValidImageSizeParameters(context, entryPoint, TextureTargetToType(target), level, width,
+ height, depth, false))
+ {
+ // Error already generated.
+ return false;
+ }
+
+ const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
+ if (!formatInfo.compressed)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidCompressedFormat);
+ return false;
+ }
+
+ GLuint blockSize = 0;
+ if (!formatInfo.computeCompressedImageSize(Extents(width, height, depth), &blockSize))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kIntegerOverflow);
+ return false;
+ }
+
+ if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidCompressedImageSize);
+ return false;
+ }
+
+ // 3D texture target validation
+ if (target != TextureTarget::_3D && target != TextureTarget::_2DArray)
+ {
+ if (context->getClientVersion() < ES_3_2 || target != TextureTarget::CubeMapArray)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget);
+ return false;
+ }
+ }
+
+ // validateES3TexImageFormat sets the error code if there is an error
+ if (!ValidateES3TexImage3DParameters(context, entryPoint, target, level, internalformat, true,
+ false, 0, 0, 0, width, height, depth, border, GL_NONE,
+ GL_NONE, -1, data))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateCompressedTexImage3DRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLsizei imageSize,
+ GLsizei dataSize,
+ const void *data)
+{
+ if (!ValidateRobustCompressedTexImageBase(context, entryPoint, imageSize, dataSize))
+ {
+ return false;
+ }
+
+ return ValidateCompressedTexImage3D(context, entryPoint, target, level, internalformat, width,
+ height, depth, border, imageSize, data);
+}
+
+bool ValidateBindVertexArray(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexArrayID array)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ return ValidateBindVertexArrayBase(context, entryPoint, array);
+}
+
+bool ValidateIsVertexArray(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexArrayID array)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ return true;
+}
+
+static bool ValidateBindBufferCommon(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding target,
+ GLuint index,
+ BufferID buffer,
+ GLintptr offset,
+ GLsizeiptr size)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ if (buffer.value != 0 && offset < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeOffset);
+ return false;
+ }
+
+ if (!context->getState().isBindGeneratesResourceEnabled() &&
+ !context->isBufferGenerated(buffer))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kObjectNotGenerated);
+ return false;
+ }
+
+ const Caps &caps = context->getCaps();
+ switch (target)
+ {
+ case BufferBinding::TransformFeedback:
+ {
+ if (index >= static_cast<GLuint>(caps.maxTransformFeedbackSeparateAttributes))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kIndexExceedsTransformFeedbackBufferBindings);
+ return false;
+ }
+ if (buffer.value != 0 && ((offset % 4) != 0 || (size % 4) != 0))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kOffsetAndSizeAlignment);
+ return false;
+ }
+
+ if (context->getState().isTransformFeedbackActive())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kTransformFeedbackTargetActive);
+ return false;
+ }
+ break;
+ }
+ case BufferBinding::Uniform:
+ {
+ if (index >= static_cast<GLuint>(caps.maxUniformBufferBindings))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kIndexExceedsMaxUniformBufferBindings);
+ return false;
+ }
+
+ ASSERT(caps.uniformBufferOffsetAlignment);
+ if (buffer.value != 0 && (offset % caps.uniformBufferOffsetAlignment) != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kUniformBufferOffsetAlignment);
+ return false;
+ }
+ break;
+ }
+ case BufferBinding::AtomicCounter:
+ {
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kEnumRequiresGLES31);
+ return false;
+ }
+ if (index >= static_cast<GLuint>(caps.maxAtomicCounterBufferBindings))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kIndexExceedsMaxAtomicCounterBufferBindings);
+ return false;
+ }
+ if (buffer.value != 0 && (offset % 4) != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kOffsetAlignment);
+ return false;
+ }
+ break;
+ }
+ case BufferBinding::ShaderStorage:
+ {
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kEnumRequiresGLES31);
+ return false;
+ }
+ if (index >= static_cast<GLuint>(caps.maxShaderStorageBufferBindings))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kExceedsMaxShaderStorageBufferBindings);
+ return false;
+ }
+ ASSERT(caps.shaderStorageBufferOffsetAlignment);
+ if (buffer.value != 0 && (offset % caps.shaderStorageBufferOffsetAlignment) != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kShaderStorageBufferOffsetAlignment);
+ return false;
+ }
+ break;
+ }
+ case BufferBinding::Texture:
+ {
+ if (!context->getExtensions().textureBufferAny())
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM,
+ kTextureBufferExtensionNotAvailable);
+ return false;
+ }
+ if (index != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kIndexExceedsMaxUniformBufferBindings);
+ return false;
+ }
+ if (buffer.value != 0 && (offset % caps.textureBufferOffsetAlignment) != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kTextureBufferOffsetAlignment);
+ return false;
+ }
+ break;
+ }
+ case BufferBinding::InvalidEnum:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kEnumInvalid);
+ return false;
+ default:
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported,
+ ToGLenum(target));
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateBindBufferBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding target,
+ GLuint index,
+ BufferID buffer)
+{
+ return ValidateBindBufferCommon(context, entryPoint, target, index, buffer, 0, 0);
+}
+
+bool ValidateBindBufferRange(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding target,
+ GLuint index,
+ BufferID buffer,
+ GLintptr offset,
+ GLsizeiptr size)
+{
+ if (buffer.value != 0 && size <= 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidBindBufferSize);
+ return false;
+ }
+ return ValidateBindBufferCommon(context, entryPoint, target, index, buffer, offset, size);
+}
+
+bool ValidateProgramBinary(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLenum binaryFormat,
+ const void *binary,
+ GLsizei length)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ return ValidateProgramBinaryBase(context, entryPoint, program, binaryFormat, binary, length);
+}
+
+bool ValidateGetProgramBinary(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLenum *binaryFormat,
+ const void *binary)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ return ValidateGetProgramBinaryBase(context, entryPoint, program, bufSize, length, binaryFormat,
+ binary);
+}
+
+bool ValidateProgramParameteriBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLenum pname,
+ GLint value)
+{
+ if (GetValidProgram(context, entryPoint, program) == nullptr)
+ {
+ return false;
+ }
+
+ switch (pname)
+ {
+ case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
+ if (value != GL_FALSE && value != GL_TRUE)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidBooleanValue);
+ return false;
+ }
+ break;
+
+ case GL_PROGRAM_SEPARABLE:
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kES31Required);
+ return false;
+ }
+
+ if (value != GL_FALSE && value != GL_TRUE)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidBooleanValue);
+ return false;
+ }
+ break;
+
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateProgramParameteri(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLenum pname,
+ GLint value)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ return ValidateProgramParameteriBase(context, entryPoint, program, pname, value);
+}
+
+bool ValidateBlitFramebuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint srcX0,
+ GLint srcY0,
+ GLint srcX1,
+ GLint srcY1,
+ GLint dstX0,
+ GLint dstY0,
+ GLint dstX1,
+ GLint dstY1,
+ GLbitfield mask,
+ GLenum filter)
+{
+ if (context->getClientMajorVersion() < 3 && !context->getExtensions().framebufferBlitNV)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ return ValidateBlitFramebufferParameters(context, entryPoint, srcX0, srcY0, srcX1, srcY1, dstX0,
+ dstY0, dstX1, dstY1, mask, filter);
+}
+
+bool ValidateClearBufferiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLint *value)
+{
+ switch (buffer)
+ {
+ case GL_COLOR:
+ if (drawbuffer < 0 || drawbuffer >= context->getCaps().maxDrawBuffers)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxDrawBuffer);
+ return false;
+ }
+ if (context->getExtensions().webglCompatibilityANGLE)
+ {
+ constexpr GLenum validComponentTypes[] = {GL_INT};
+ if (!ValidateWebGLFramebufferAttachmentClearType(context, entryPoint, drawbuffer,
+ validComponentTypes,
+ ArraySize(validComponentTypes)))
+ {
+ return false;
+ }
+ }
+ break;
+
+ case GL_STENCIL:
+ if (drawbuffer != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kInvalidDepthStencilDrawBuffer);
+ return false;
+ }
+ break;
+
+ default:
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, buffer);
+ return false;
+ }
+
+ return ValidateClearBuffer(context, entryPoint);
+}
+
+bool ValidateClearBufferuiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLuint *value)
+{
+ switch (buffer)
+ {
+ case GL_COLOR:
+ if (drawbuffer < 0 || drawbuffer >= context->getCaps().maxDrawBuffers)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxDrawBuffer);
+ return false;
+ }
+ if (context->getExtensions().webglCompatibilityANGLE)
+ {
+ constexpr GLenum validComponentTypes[] = {GL_UNSIGNED_INT};
+ if (!ValidateWebGLFramebufferAttachmentClearType(context, entryPoint, drawbuffer,
+ validComponentTypes,
+ ArraySize(validComponentTypes)))
+ {
+ return false;
+ }
+ }
+ break;
+
+ default:
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, buffer);
+ return false;
+ }
+
+ return ValidateClearBuffer(context, entryPoint);
+}
+
+bool ValidateClearBufferfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLfloat *value)
+{
+ switch (buffer)
+ {
+ case GL_COLOR:
+ if (drawbuffer < 0 || drawbuffer >= context->getCaps().maxDrawBuffers)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxDrawBuffer);
+ return false;
+ }
+ if (context->getExtensions().webglCompatibilityANGLE)
+ {
+ constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
+ GL_SIGNED_NORMALIZED};
+ if (!ValidateWebGLFramebufferAttachmentClearType(context, entryPoint, drawbuffer,
+ validComponentTypes,
+ ArraySize(validComponentTypes)))
+ {
+ return false;
+ }
+ }
+ break;
+
+ case GL_DEPTH:
+ if (drawbuffer != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kInvalidDepthStencilDrawBuffer);
+ return false;
+ }
+ break;
+
+ default:
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, buffer);
+ return false;
+ }
+
+ return ValidateClearBuffer(context, entryPoint);
+}
+
+bool ValidateClearBufferfi(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum buffer,
+ GLint drawbuffer,
+ GLfloat depth,
+ GLint stencil)
+{
+ switch (buffer)
+ {
+ case GL_DEPTH_STENCIL:
+ if (drawbuffer != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kInvalidDepthStencilDrawBuffer);
+ return false;
+ }
+ break;
+
+ default:
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, buffer);
+ return false;
+ }
+
+ return ValidateClearBuffer(context, entryPoint);
+}
+
+bool ValidateDrawBuffers(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const GLenum *bufs)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ return ValidateDrawBuffersBase(context, entryPoint, n, bufs);
+}
+
+bool ValidateCopyTexSubImage3D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height)
+{
+ if ((context->getClientMajorVersion() < 3) && !context->getExtensions().texture3DOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ return ValidateES3CopyTexImage3DParameters(context, entryPoint, target, level, GL_NONE, true,
+ xoffset, yoffset, zoffset, x, y, width, height, 0);
+}
+
+bool ValidateCopyTexture3DANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID sourceId,
+ GLint sourceLevel,
+ TextureTarget destTarget,
+ TextureID destId,
+ GLint destLevel,
+ GLint internalFormat,
+ GLenum destType,
+ GLboolean unpackFlipY,
+ GLboolean unpackPremultiplyAlpha,
+ GLboolean unpackUnmultiplyAlpha)
+{
+ const Texture *source = context->getTexture(sourceId);
+ if (source == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidSourceTexture);
+ return false;
+ }
+
+ TextureType sourceType = source->getType();
+ ASSERT(sourceType != TextureType::CubeMap);
+ TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
+ const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
+
+ const Texture *dest = context->getTexture(destId);
+ if (dest == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidDestinationTexture);
+ return false;
+ }
+
+ if (!ValidateCopyTexture3DCommon(context, entryPoint, source, sourceLevel,
+ sourceFormat.info->internalFormat, dest, destLevel,
+ internalFormat, destTarget))
+ {
+ return false;
+ }
+
+ if (!ValidMipLevel(context, source->getType(), sourceLevel))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidSourceTextureLevel);
+ return false;
+ }
+
+ GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
+ GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
+ if (sourceWidth == 0 || sourceHeight == 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidSourceTextureSize);
+ return false;
+ }
+
+ if (dest->getImmutableFormat())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kDestinationImmutable);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateCopySubTexture3DANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID sourceId,
+ GLint sourceLevel,
+ TextureTarget destTarget,
+ TextureID destId,
+ GLint destLevel,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLint x,
+ GLint y,
+ GLint z,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean unpackFlipY,
+ GLboolean unpackPremultiplyAlpha,
+ GLboolean unpackUnmultiplyAlpha)
+{
+ const Texture *source = context->getTexture(sourceId);
+ if (source == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidSourceTexture);
+ return false;
+ }
+
+ TextureType sourceType = source->getType();
+ ASSERT(sourceType != TextureType::CubeMap);
+ TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
+ const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
+
+ const Texture *dest = context->getTexture(destId);
+ if (dest == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidDestinationTexture);
+ return false;
+ }
+
+ const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
+
+ if (!ValidateCopyTexture3DCommon(context, entryPoint, source, sourceLevel,
+ sourceFormat.info->internalFormat, dest, destLevel,
+ destFormat.internalFormat, destTarget))
+ {
+ return false;
+ }
+
+ if (x < 0 || y < 0 || z < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeXYZ);
+ return false;
+ }
+
+ if (width < 0 || height < 0 || depth < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeHeightWidthDepth);
+ return false;
+ }
+
+ if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
+ static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel) ||
+ static_cast<size_t>(z + depth) > source->getDepth(sourceTarget, sourceLevel))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kSourceTextureTooSmall);
+ return false;
+ }
+
+ if (TextureTargetToType(destTarget) != dest->getType())
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidDestinationTextureType);
+ return false;
+ }
+
+ if (xoffset < 0 || yoffset < 0 || zoffset < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeOffset);
+ return false;
+ }
+
+ if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
+ static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel) ||
+ static_cast<size_t>(zoffset + depth) > dest->getDepth(destTarget, destLevel))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kDestinationTextureTooSmall);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateTexImage3D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ if ((context->getClientMajorVersion() < 3) && !context->getExtensions().texture3DOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateES3TexImage3DParameters(context, entryPoint, target, level, internalformat,
+ false, false, 0, 0, 0, width, height, depth, border,
+ format, type, -1, pixels);
+}
+
+bool ValidateTexImage3DRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *pixels)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
+ {
+ return false;
+ }
+
+ return ValidateES3TexImage3DParameters(context, entryPoint, target, level, internalformat,
+ false, false, 0, 0, 0, width, height, depth, border,
+ format, type, bufSize, pixels);
+}
+
+bool ValidateTexSubImage3D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ if ((context->getClientMajorVersion() < 3) && !context->getExtensions().texture3DOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ return ValidateES3TexImage3DParameters(context, entryPoint, target, level, GL_NONE, false, true,
+ xoffset, yoffset, zoffset, width, height, depth, 0,
+ format, type, -1, pixels);
+}
+
+bool ValidateTexSubImage3DRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *pixels)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
+ {
+ return false;
+ }
+
+ return ValidateES3TexImage3DParameters(context, entryPoint, target, level, GL_NONE, false, true,
+ xoffset, yoffset, zoffset, width, height, depth, 0,
+ format, type, bufSize, pixels);
+}
+
+bool ValidateCompressedTexSubImage3D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data)
+{
+ if ((context->getClientMajorVersion() < 3) && !context->getExtensions().texture3DOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ if (!ValidateES3TexImage3DParameters(context, entryPoint, target, level, GL_NONE, true, true,
+ xoffset, yoffset, zoffset, width, height, depth, 0, format,
+ GL_NONE, -1, data))
+ {
+ return false;
+ }
+
+ const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
+
+ if (!formatInfo.compressed)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidCompressedFormat);
+ return false;
+ }
+
+ GLuint blockSize = 0;
+ if (!formatInfo.computeCompressedImageSize(Extents(width, height, depth), &blockSize))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kIntegerOverflow);
+ return false;
+ }
+
+ if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidCompressedImageSize);
+ return false;
+ }
+
+ if (data == nullptr)
+ {
+ if (context->getState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
+ {
+ // If data is null, we need an unpack buffer to read from
+ context->validationError(entryPoint, GL_INVALID_VALUE, kPixelDataNull);
+ return false;
+ }
+
+ if (context->getTextureByTarget(target)->isCompressedFormatEmulated(context, target, level))
+ {
+ // TODO (anglebug.com/7464): Can't populate from a buffer using emulated format
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidEmulatedFormat);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateCompressedTexSubImage3DRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLsizei imageSize,
+ GLsizei dataSize,
+ const void *data)
+{
+ if (!ValidateRobustCompressedTexImageBase(context, entryPoint, imageSize, dataSize))
+ {
+ return false;
+ }
+
+ return ValidateCompressedTexSubImage3D(context, entryPoint, target, level, xoffset, yoffset,
+ zoffset, width, height, depth, format, imageSize, data);
+}
+
+bool ValidateGenQueries(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const QueryID *queries)
+{
+ return ValidateGenOrDeleteES3(context, entryPoint, n);
+}
+
+bool ValidateDeleteQueries(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const QueryID *queries)
+{
+ return ValidateGenOrDeleteES3(context, entryPoint, n);
+}
+
+bool ValidateGenSamplers(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei count,
+ const SamplerID *samplers)
+{
+ return ValidateGenOrDeleteCountES3(context, entryPoint, count);
+}
+
+bool ValidateDeleteSamplers(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei count,
+ const SamplerID *samplers)
+{
+ return ValidateGenOrDeleteCountES3(context, entryPoint, count);
+}
+
+bool ValidateGenTransformFeedbacks(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const TransformFeedbackID *ids)
+{
+ return ValidateGenOrDeleteES3(context, entryPoint, n);
+}
+
+bool ValidateDeleteTransformFeedbacks(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const TransformFeedbackID *ids)
+{
+ if (!ValidateGenOrDeleteES3(context, entryPoint, n))
+ {
+ return false;
+ }
+ for (GLint i = 0; i < n; ++i)
+ {
+ auto *transformFeedback = context->getTransformFeedback(ids[i]);
+ if (transformFeedback != nullptr && transformFeedback->isActive())
+ {
+ // ES 3.0.4 section 2.15.1 page 86
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kTransformFeedbackActiveDelete);
+ return false;
+ }
+ }
+ return true;
+}
+
+bool ValidateGenVertexArrays(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const VertexArrayID *arrays)
+{
+ return ValidateGenOrDeleteES3(context, entryPoint, n);
+}
+
+bool ValidateDeleteVertexArrays(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const VertexArrayID *arrays)
+{
+ return ValidateGenOrDeleteES3(context, entryPoint, n);
+}
+
+bool ValidateBeginTransformFeedback(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode primitiveMode)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+ switch (primitiveMode)
+ {
+ case PrimitiveMode::Triangles:
+ case PrimitiveMode::Lines:
+ case PrimitiveMode::Points:
+ break;
+
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPrimitiveMode);
+ return false;
+ }
+
+ TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
+ ASSERT(transformFeedback != nullptr);
+
+ if (transformFeedback->isActive())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kTransfomFeedbackAlreadyActive);
+ return false;
+ }
+
+ for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
+ {
+ const OffsetBindingPointer<Buffer> &buffer = transformFeedback->getIndexedBuffer(i);
+ if (buffer.get())
+ {
+ if (buffer->isMapped())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferMapped);
+ return false;
+ }
+ if ((context->getLimitations().noDoubleBoundTransformFeedbackBuffers ||
+ context->getExtensions().webglCompatibilityANGLE) &&
+ buffer->isDoubleBoundForTransformFeedback())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kTransformFeedbackBufferMultipleOutputs);
+ return false;
+ }
+ }
+ }
+
+ const ProgramExecutable *programExecutable =
+ context->getState().getLinkedProgramExecutable(context);
+ if (!programExecutable)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotBound);
+ return false;
+ }
+
+ if (programExecutable->getLinkedTransformFeedbackVaryings().empty())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kNoTransformFeedbackOutputVariables);
+ return false;
+ }
+
+ if (!ValidateProgramExecutableXFBBuffersPresent(context, programExecutable))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kTransformFeedbackBufferMissing);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetBufferPointerv(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding target,
+ GLenum pname,
+ void *const *params)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ return ValidateGetBufferPointervBase(context, entryPoint, target, pname, nullptr, params);
+}
+
+bool ValidateGetBufferPointervRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding target,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ void *const *params)
+{
+ if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
+ {
+ return false;
+ }
+
+ GLsizei numParams = 0;
+
+ if (context->getClientMajorVersion() < 3 && !context->getExtensions().mapbufferOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ if (!ValidateGetBufferPointervBase(context, entryPoint, target, pname, &numParams, params))
+ {
+ return false;
+ }
+
+ if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
+ {
+ return false;
+ }
+
+ SetRobustLengthParam(length, numParams);
+
+ return true;
+}
+
+bool ValidateUnmapBuffer(const Context *context, angle::EntryPoint entryPoint, BufferBinding target)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ return ValidateUnmapBufferBase(context, entryPoint, target);
+}
+
+bool ValidateMapBufferRange(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding target,
+ GLintptr offset,
+ GLsizeiptr length,
+ GLbitfield access)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ return ValidateMapBufferRangeBase(context, entryPoint, target, offset, length, access);
+}
+
+bool ValidateFlushMappedBufferRange(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding target,
+ GLintptr offset,
+ GLsizeiptr length)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ return ValidateFlushMappedBufferRangeBase(context, entryPoint, target, offset, length);
+}
+
+bool ValidateIndexedStateQuery(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLuint index,
+ GLsizei *length)
+{
+ if (length)
+ {
+ *length = 0;
+ }
+
+ GLenum nativeType;
+ unsigned int numParams;
+ if (!context->getIndexedQueryParameterInfo(pname, &nativeType, &numParams))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname);
+ return false;
+ }
+
+ const Caps &caps = context->getCaps();
+ switch (pname)
+ {
+ case GL_BLEND_SRC_RGB:
+ case GL_BLEND_SRC_ALPHA:
+ case GL_BLEND_DST_RGB:
+ case GL_BLEND_DST_ALPHA:
+ case GL_BLEND_EQUATION_RGB:
+ case GL_BLEND_EQUATION_ALPHA:
+ case GL_COLOR_WRITEMASK:
+ if (!context->getExtensions().drawBuffersIndexedAny())
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM,
+ kDrawBuffersIndexedExtensionNotAvailable);
+ return false;
+ }
+ if (index >= static_cast<GLuint>(caps.maxDrawBuffers))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxDrawBuffer);
+ return false;
+ }
+ break;
+ case GL_TRANSFORM_FEEDBACK_BUFFER_START:
+ case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
+ case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
+ if (index >= static_cast<GLuint>(caps.maxTransformFeedbackSeparateAttributes))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kIndexExceedsMaxTransformFeedbackAttribs);
+ return false;
+ }
+ break;
+
+ case GL_UNIFORM_BUFFER_START:
+ case GL_UNIFORM_BUFFER_SIZE:
+ case GL_UNIFORM_BUFFER_BINDING:
+ if (index >= static_cast<GLuint>(caps.maxUniformBufferBindings))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kIndexExceedsMaxUniformBufferBindings);
+ return false;
+ }
+ break;
+
+ case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
+ case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
+ if (index >= 3u)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kIndexExceedsMaxWorkgroupDimensions);
+ return false;
+ }
+ break;
+
+ case GL_ATOMIC_COUNTER_BUFFER_START:
+ case GL_ATOMIC_COUNTER_BUFFER_SIZE:
+ case GL_ATOMIC_COUNTER_BUFFER_BINDING:
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kEnumRequiresGLES31);
+ return false;
+ }
+ if (index >= static_cast<GLuint>(caps.maxAtomicCounterBufferBindings))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kIndexExceedsMaxAtomicCounterBufferBindings);
+ return false;
+ }
+ break;
+
+ case GL_SHADER_STORAGE_BUFFER_START:
+ case GL_SHADER_STORAGE_BUFFER_SIZE:
+ case GL_SHADER_STORAGE_BUFFER_BINDING:
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kEnumRequiresGLES31);
+ return false;
+ }
+ if (index >= static_cast<GLuint>(caps.maxShaderStorageBufferBindings))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kExceedsMaxShaderStorageBufferBindings);
+ return false;
+ }
+ break;
+
+ case GL_VERTEX_BINDING_BUFFER:
+ case GL_VERTEX_BINDING_DIVISOR:
+ case GL_VERTEX_BINDING_OFFSET:
+ case GL_VERTEX_BINDING_STRIDE:
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kEnumRequiresGLES31);
+ return false;
+ }
+ if (index >= static_cast<GLuint>(caps.maxVertexAttribBindings))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kExceedsMaxVertexAttribBindings);
+ return false;
+ }
+ break;
+ case GL_SAMPLE_MASK_VALUE:
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kEnumRequiresGLES31);
+ return false;
+ }
+ if (index >= static_cast<GLuint>(caps.maxSampleMaskWords))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidSampleMaskNumber);
+ return false;
+ }
+ break;
+ case GL_IMAGE_BINDING_NAME:
+ case GL_IMAGE_BINDING_LEVEL:
+ case GL_IMAGE_BINDING_LAYERED:
+ case GL_IMAGE_BINDING_LAYER:
+ case GL_IMAGE_BINDING_ACCESS:
+ case GL_IMAGE_BINDING_FORMAT:
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kEnumRequiresGLES31);
+ return false;
+ }
+ if (index >= static_cast<GLuint>(caps.maxImageUnits))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsMaxImageUnits);
+ return false;
+ }
+ break;
+ // GL_ANGLE_shader_pixel_local_storage
+ case GL_PIXEL_LOCAL_FORMAT_ANGLE:
+ case GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE:
+ case GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE:
+ case GL_PIXEL_LOCAL_TEXTURE_LAYER_ANGLE:
+ {
+ // Check that the pixel local storage extension is enabled at all.
+ if (!context->getExtensions().shaderPixelLocalStorageANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kPLSExtensionNotEnabled);
+ return false;
+ }
+ // INVALID_FRAMEBUFFER_OPERATION is generated if the default framebuffer object name 0
+ // is bound to DRAW_FRAMEBUFFER.
+ Framebuffer *framebuffer = context->getState().getDrawFramebuffer();
+ if (framebuffer->id().value == 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_FRAMEBUFFER_OPERATION,
+ kPLSDefaultFramebufferBound);
+ return false;
+ }
+ // INVALID_VALUE is generated if <index> >= MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE.
+ if (index >= context->getCaps().maxPixelLocalStoragePlanes)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kPLSPlaneOutOfRange);
+ return false;
+ }
+ break;
+ }
+ default:
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname);
+ return false;
+ }
+
+ if (length)
+ {
+ if (pname == GL_COLOR_WRITEMASK)
+ {
+ *length = 4;
+ }
+ else
+ {
+ *length = 1;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateGetIntegeri_v(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint index,
+ const GLint *data)
+{
+ if (context->getClientVersion() < ES_3_0)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+ return ValidateIndexedStateQuery(context, entryPoint, target, index, nullptr);
+}
+
+bool ValidateGetIntegeri_vRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint index,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *data)
+{
+ if (context->getClientVersion() < ES_3_0)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
+ {
+ return false;
+ }
+
+ GLsizei numParams = 0;
+
+ if (!ValidateIndexedStateQuery(context, entryPoint, target, index, &numParams))
+ {
+ return false;
+ }
+
+ if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
+ {
+ return false;
+ }
+
+ SetRobustLengthParam(length, numParams);
+
+ return true;
+}
+
+bool ValidateGetInteger64i_v(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint index,
+ const GLint64 *data)
+{
+ if (context->getClientVersion() < ES_3_0)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+ return ValidateIndexedStateQuery(context, entryPoint, target, index, nullptr);
+}
+
+bool ValidateGetInteger64i_vRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint index,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint64 *data)
+{
+ if (context->getClientVersion() < ES_3_0)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
+ {
+ return false;
+ }
+
+ GLsizei numParams = 0;
+
+ if (!ValidateIndexedStateQuery(context, entryPoint, target, index, &numParams))
+ {
+ return false;
+ }
+
+ if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
+ {
+ return false;
+ }
+
+ SetRobustLengthParam(length, numParams);
+
+ return true;
+}
+
+bool ValidateCopyBufferSubData(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding readTarget,
+ BufferBinding writeTarget,
+ GLintptr readOffset,
+ GLintptr writeOffset,
+ GLsizeiptr size)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ if (!context->isValidBufferBinding(readTarget) || !context->isValidBufferBinding(writeTarget))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBufferTypes);
+ return false;
+ }
+
+ Buffer *readBuffer = context->getState().getTargetBuffer(readTarget);
+ Buffer *writeBuffer = context->getState().getTargetBuffer(writeTarget);
+
+ if (!readBuffer || !writeBuffer)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferNotBound);
+ return false;
+ }
+
+ // EXT_buffer_storage allows persistently mapped buffers to be updated via glCopyBufferSubData
+ bool isReadPersistent = (readBuffer->getAccessFlags() & GL_MAP_PERSISTENT_BIT_EXT) != 0;
+ bool isWritePersistent = (writeBuffer->getAccessFlags() & GL_MAP_PERSISTENT_BIT_EXT) != 0;
+
+ // Verify that readBuffer and writeBuffer are not currently mapped unless persistent
+ if ((readBuffer->isMapped() && !isReadPersistent) ||
+ (writeBuffer->isMapped() && !isWritePersistent))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferMapped);
+ return false;
+ }
+
+ if (readBuffer->hasWebGLXFBBindingConflict(context->isWebGL()) ||
+ writeBuffer->hasWebGLXFBBindingConflict(context->isWebGL()))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kBufferBoundForTransformFeedback);
+ return false;
+ }
+
+ CheckedNumeric<GLintptr> checkedReadOffset(readOffset);
+ CheckedNumeric<GLintptr> checkedWriteOffset(writeOffset);
+ CheckedNumeric<GLintptr> checkedSize(size);
+
+ auto checkedReadSum = checkedReadOffset + checkedSize;
+ auto checkedWriteSum = checkedWriteOffset + checkedSize;
+
+ if (!checkedReadSum.IsValid() || !checkedWriteSum.IsValid() ||
+ !IsValueInRangeForNumericType<GLintptr>(readBuffer->getSize()) ||
+ !IsValueInRangeForNumericType<GLintptr>(writeBuffer->getSize()))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kIntegerOverflow);
+ return false;
+ }
+
+ if (readOffset < 0 || writeOffset < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeOffset);
+ return false;
+ }
+
+ if (size < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeSize);
+ return false;
+ }
+
+ if (checkedReadSum.ValueOrDie() > readBuffer->getSize() ||
+ checkedWriteSum.ValueOrDie() > writeBuffer->getSize())
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kBufferOffsetOverflow);
+ return false;
+ }
+
+ if (readBuffer == writeBuffer)
+ {
+ auto checkedOffsetDiff = (checkedReadOffset - checkedWriteOffset).Abs();
+ if (!checkedOffsetDiff.IsValid())
+ {
+ // This shold not be possible.
+ UNREACHABLE();
+ context->validationError(entryPoint, GL_INVALID_VALUE, kIntegerOverflow);
+ return false;
+ }
+
+ if (checkedOffsetDiff.ValueOrDie() < size)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kCopyAlias);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateGetStringi(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum name,
+ GLuint index)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ switch (name)
+ {
+ case GL_EXTENSIONS:
+ if (index >= context->getExtensionStringCount())
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsNumExtensions);
+ return false;
+ }
+ break;
+
+ case GL_REQUESTABLE_EXTENSIONS_ANGLE:
+ if (!context->getExtensions().requestExtensionANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidName);
+ return false;
+ }
+ if (index >= context->getRequestableExtensionStringCount())
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kExceedsNumRequestableExtensions);
+ return false;
+ }
+ break;
+
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidName);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateRenderbufferStorageMultisample(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ if (!ValidateRenderbufferStorageParametersBase(context, entryPoint, target, samples,
+ internalformat, width, height))
+ {
+ return false;
+ }
+
+ // The ES3 spec(section 4.4.2) states that the internal format must be sized and not an integer
+ // format if samples is greater than zero. In ES3.1(section 9.2.5), it can support integer
+ // multisample renderbuffer, but the samples should not be greater than MAX_INTEGER_SAMPLES.
+ const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
+ if (formatInfo.isInt())
+ {
+ if ((samples > 0 && context->getClientVersion() == ES_3_0) ||
+ samples > context->getCaps().maxIntegerSamples)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kSamplesOutOfRange);
+ return false;
+ }
+ }
+
+ // The behavior is different than the ANGLE version, which would generate a GL_OUT_OF_MEMORY.
+ const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
+ if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kSamplesOutOfRange);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateVertexAttribIPointer(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLint size,
+ VertexAttribType type,
+ GLsizei stride,
+ const void *pointer)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ if (!ValidateIntegerVertexFormat(context, entryPoint, index, size, type))
+ {
+ return false;
+ }
+
+ if (stride < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeStride);
+ return false;
+ }
+
+ const Caps &caps = context->getCaps();
+ if (context->getClientVersion() >= ES_3_1)
+ {
+ if (stride > caps.maxVertexAttribStride)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsMaxVertexAttribStride);
+ return false;
+ }
+
+ // [OpenGL ES 3.1] Section 10.3.1 page 245:
+ // glVertexAttribBinding is part of the equivalent code of VertexAttribIPointer, so its
+ // validation should be inherited.
+ if (index >= static_cast<GLuint>(caps.maxVertexAttribBindings))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsMaxVertexAttribBindings);
+ return false;
+ }
+ }
+
+ // [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,
+ // and the pointer argument is not NULL.
+ if (context->getState().getVertexArrayId().value != 0 &&
+ context->getState().getTargetBuffer(BufferBinding::Array) == 0 && pointer != nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kClientDataInVertexArray);
+ return false;
+ }
+
+ if (context->getExtensions().webglCompatibilityANGLE)
+ {
+ if (!ValidateWebGLVertexAttribPointer(context, entryPoint, type, false, stride, pointer,
+ true))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateGetSynciv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsync sync,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *values)
+{
+ if ((context->getClientMajorVersion() < 3) && !context->getExtensions().syncARB)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ if (bufSize < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBufferSize);
+ return false;
+ }
+
+ if (context->isContextLost())
+ {
+ context->validationError(entryPoint, GL_CONTEXT_LOST, kContextLost);
+
+ if (pname == GL_SYNC_STATUS)
+ {
+ // Generate an error but still return true, the context still needs to return a
+ // value in this case.
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ Sync *syncObject = context->getSync(sync);
+ if (!syncObject)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kSyncMissing);
+ return false;
+ }
+
+ switch (pname)
+ {
+ case GL_OBJECT_TYPE:
+ case GL_SYNC_CONDITION:
+ case GL_SYNC_FLAGS:
+ case GL_SYNC_STATUS:
+ break;
+
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateDrawElementsInstanced(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLsizei count,
+ DrawElementsType type,
+ const void *indices,
+ GLsizei instanceCount)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ return ValidateDrawElementsInstancedBase(context, entryPoint, mode, count, type, indices,
+ instanceCount);
+}
+
+bool ValidateMultiDrawArraysInstancedANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ const GLint *firsts,
+ const GLsizei *counts,
+ const GLsizei *instanceCounts,
+ GLsizei drawcount)
+{
+ if (!context->getExtensions().multiDrawANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+ if (context->getClientMajorVersion() < 3)
+ {
+ if (!context->getExtensions().instancedArraysAny())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+ if (!ValidateDrawInstancedANGLE(context, entryPoint))
+ {
+ return false;
+ }
+ }
+ for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
+ {
+ if (!ValidateDrawArraysInstancedBase(context, entryPoint, mode, firsts[drawID],
+ counts[drawID], instanceCounts[drawID]))
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool ValidateMultiDrawElementsInstancedANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ const GLsizei *counts,
+ DrawElementsType type,
+ const GLvoid *const *indices,
+ const GLsizei *instanceCounts,
+ GLsizei drawcount)
+{
+ if (!context->getExtensions().multiDrawANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+ if (context->getClientMajorVersion() < 3)
+ {
+ if (!context->getExtensions().instancedArraysAny())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+ if (!ValidateDrawInstancedANGLE(context, entryPoint))
+ {
+ return false;
+ }
+ }
+ for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
+ {
+ if (!ValidateDrawElementsInstancedBase(context, entryPoint, mode, counts[drawID], type,
+ indices[drawID], instanceCounts[drawID]))
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool ValidateDrawArraysInstancedBaseInstanceANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLint first,
+ GLsizei count,
+ GLsizei instanceCount,
+ GLuint baseInstance)
+{
+ if (!context->getExtensions().baseVertexBaseInstanceANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateDrawArraysInstancedBase(context, entryPoint, mode, first, count, instanceCount);
+}
+
+bool ValidateDrawElementsInstancedBaseVertexBaseInstanceANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLsizei count,
+ DrawElementsType type,
+ const GLvoid *indices,
+ GLsizei instanceCount,
+ GLint baseVertex,
+ GLuint baseInstance)
+{
+ if (!context->getExtensions().baseVertexBaseInstanceANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateDrawElementsInstancedBase(context, entryPoint, mode, count, type, indices,
+ instanceCount);
+}
+
+bool ValidateMultiDrawArraysInstancedBaseInstanceANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ const GLint *firsts,
+ const GLsizei *counts,
+ const GLsizei *instanceCounts,
+ const GLuint *baseInstances,
+ GLsizei drawcount)
+{
+ if (!context->getExtensions().multiDrawANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+ if (drawcount < 0)
+ {
+ return false;
+ }
+ for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
+ {
+ if (!ValidateDrawArraysInstancedBase(context, entryPoint, modePacked, firsts[drawID],
+ counts[drawID], instanceCounts[drawID]))
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool ValidateMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ const GLsizei *counts,
+ DrawElementsType typePacked,
+ const GLvoid *const *indices,
+ const GLsizei *instanceCounts,
+ const GLint *baseVertices,
+ const GLuint *baseInstances,
+ GLsizei drawcount)
+{
+ if (!context->getExtensions().multiDrawANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+ if (drawcount < 0)
+ {
+ return false;
+ }
+ for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
+ {
+ if (!ValidateDrawElementsInstancedBase(context, entryPoint, modePacked, counts[drawID],
+ typePacked, indices[drawID], instanceCounts[drawID]))
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool ValidateFramebufferTextureMultiviewOVR(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ TextureID texture,
+ GLint level,
+ GLint baseViewIndex,
+ GLsizei numViews)
+{
+ if (!ValidateFramebufferTextureMultiviewBaseANGLE(context, entryPoint, target, attachment,
+ texture, level, numViews))
+ {
+ return false;
+ }
+
+ if (texture.value != 0)
+ {
+ if (baseViewIndex < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBaseViewIndex);
+ return false;
+ }
+
+ Texture *tex = context->getTexture(texture);
+ ASSERT(tex);
+
+ switch (tex->getType())
+ {
+ case TextureType::_2DArray:
+ case TextureType::_2DMultisampleArray:
+ {
+ if (tex->getType() == TextureType::_2DMultisampleArray)
+ {
+ if (!context->getExtensions().multiviewMultisampleANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kInvalidTextureType);
+ return false;
+ }
+ }
+
+ const Caps &caps = context->getCaps();
+ if (baseViewIndex + numViews > caps.maxArrayTextureLayers)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kViewsExceedMaxArrayLayers);
+ return false;
+ }
+
+ break;
+ }
+ default:
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidTextureType);
+ return false;
+ }
+
+ if (!ValidateFramebufferTextureMultiviewLevelAndFormat(context, entryPoint, tex, level))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateUniform1ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLuint v0)
+{
+ return ValidateUniformES3(context, entryPoint, GL_UNSIGNED_INT, location, 1);
+}
+
+bool ValidateUniform2ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLuint v0,
+ GLuint v1)
+{
+ return ValidateUniformES3(context, entryPoint, GL_UNSIGNED_INT_VEC2, location, 1);
+}
+
+bool ValidateUniform3ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLuint v0,
+ GLuint v1,
+ GLuint v2)
+{
+ return ValidateUniformES3(context, entryPoint, GL_UNSIGNED_INT_VEC3, location, 1);
+}
+
+bool ValidateUniform4ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLuint v0,
+ GLuint v1,
+ GLuint v2,
+ GLuint v3)
+{
+ return ValidateUniformES3(context, entryPoint, GL_UNSIGNED_INT_VEC4, location, 1);
+}
+
+bool ValidateUniform1uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLsizei count,
+ const GLuint *value)
+{
+ return ValidateUniformES3(context, entryPoint, GL_UNSIGNED_INT, location, count);
+}
+
+bool ValidateUniform2uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLsizei count,
+ const GLuint *value)
+{
+ return ValidateUniformES3(context, entryPoint, GL_UNSIGNED_INT_VEC2, location, count);
+}
+
+bool ValidateUniform3uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLsizei count,
+ const GLuint *value)
+{
+ return ValidateUniformES3(context, entryPoint, GL_UNSIGNED_INT_VEC3, location, count);
+}
+
+bool ValidateUniform4uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLsizei count,
+ const GLuint *value)
+{
+ return ValidateUniformES3(context, entryPoint, GL_UNSIGNED_INT_VEC4, location, count);
+}
+
+bool ValidateIsQuery(const Context *context, angle::EntryPoint entryPoint, QueryID id)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateUniformMatrix2x3fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return ValidateUniformMatrixES3(context, entryPoint, GL_FLOAT_MAT2x3, location, count,
+ transpose);
+}
+
+bool ValidateUniformMatrix3x2fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return ValidateUniformMatrixES3(context, entryPoint, GL_FLOAT_MAT3x2, location, count,
+ transpose);
+}
+
+bool ValidateUniformMatrix2x4fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return ValidateUniformMatrixES3(context, entryPoint, GL_FLOAT_MAT2x4, location, count,
+ transpose);
+}
+
+bool ValidateUniformMatrix4x2fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return ValidateUniformMatrixES3(context, entryPoint, GL_FLOAT_MAT4x2, location, count,
+ transpose);
+}
+
+bool ValidateUniformMatrix3x4fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return ValidateUniformMatrixES3(context, entryPoint, GL_FLOAT_MAT3x4, location, count,
+ transpose);
+}
+
+bool ValidateUniformMatrix4x3fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return ValidateUniformMatrixES3(context, entryPoint, GL_FLOAT_MAT4x3, location, count,
+ transpose);
+}
+
+bool ValidateEndTransformFeedback(const Context *context, angle::EntryPoint entryPoint)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
+ ASSERT(transformFeedback != nullptr);
+
+ if (!transformFeedback->isActive())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kTransformFeedbackNotActive);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateTransformFeedbackVaryings(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLsizei count,
+ const GLchar *const *varyings,
+ GLenum bufferMode)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ if (count < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeCount);
+ return false;
+ }
+
+ switch (bufferMode)
+ {
+ case GL_INTERLEAVED_ATTRIBS:
+ break;
+ case GL_SEPARATE_ATTRIBS:
+ {
+ const Caps &caps = context->getCaps();
+ if (count > caps.maxTransformFeedbackSeparateAttributes)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kInvalidTransformFeedbackAttribsCount);
+ return false;
+ }
+ break;
+ }
+ default:
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, bufferMode);
+ return false;
+ }
+
+ Program *programObject = GetValidProgram(context, entryPoint, program);
+ if (!programObject)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetTransformFeedbackVarying(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLuint index,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLsizei *size,
+ const GLenum *type,
+ const GLchar *name)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ if (bufSize < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBufferSize);
+ return false;
+ }
+
+ Program *programObject = GetValidProgram(context, entryPoint, program);
+ if (!programObject)
+ {
+ return false;
+ }
+
+ if (index >= static_cast<GLuint>(programObject->getTransformFeedbackVaryingCount()))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kTransformFeedbackVaryingIndexOutOfRange);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateBindTransformFeedback(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ TransformFeedbackID id)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ switch (target)
+ {
+ case GL_TRANSFORM_FEEDBACK:
+ {
+ // Cannot bind a transform feedback object if the current one is started and not
+ // paused (3.0.2 pg 85 section 2.14.1)
+ if (context->getState().isTransformFeedbackActiveUnpaused())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kTransformFeedbackNotPaused);
+ return false;
+ }
+
+ // Cannot bind a transform feedback object that does not exist (3.0.2 pg 85 section
+ // 2.14.1)
+ if (!context->isTransformFeedbackGenerated(id))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kTransformFeedbackDoesNotExist);
+ return false;
+ }
+ }
+ break;
+
+ default:
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, target);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateIsTransformFeedback(const Context *context,
+ angle::EntryPoint entryPoint,
+ TransformFeedbackID id)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidatePauseTransformFeedback(const Context *context, angle::EntryPoint entryPoint)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
+ ASSERT(transformFeedback != nullptr);
+
+ // Current transform feedback must be active and not paused in order to pause (3.0.2 pg 86)
+ if (!transformFeedback->isActive())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kTransformFeedbackNotActive);
+ return false;
+ }
+
+ if (transformFeedback->isPaused())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kTransformFeedbackPaused);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateResumeTransformFeedback(const Context *context, angle::EntryPoint entryPoint)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
+ ASSERT(transformFeedback != nullptr);
+
+ // Current transform feedback must be active and paused in order to resume (3.0.2 pg 86)
+ if (!transformFeedback->isActive())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kTransformFeedbackNotActive);
+ return false;
+ }
+
+ if (!transformFeedback->isPaused())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kTransformFeedbackNotPaused);
+ return false;
+ }
+
+ if (!ValidateProgramExecutableXFBBuffersPresent(
+ context, context->getState().getLinkedProgramExecutable(context)))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kTransformFeedbackBufferMissing);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateVertexAttribI4i(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLint x,
+ GLint y,
+ GLint z,
+ GLint w)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ return ValidateVertexAttribIndex(context, entryPoint, index);
+}
+
+bool ValidateVertexAttribI4ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLuint x,
+ GLuint y,
+ GLuint z,
+ GLuint w)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ return ValidateVertexAttribIndex(context, entryPoint, index);
+}
+
+bool ValidateVertexAttribI4iv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLint *v)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ return ValidateVertexAttribIndex(context, entryPoint, index);
+}
+
+bool ValidateVertexAttribI4uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLuint *v)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ return ValidateVertexAttribIndex(context, entryPoint, index);
+}
+
+bool ValidateGetFragDataLocation(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ const GLchar *name)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ Program *programObject = GetValidProgram(context, entryPoint, program);
+ if (!programObject)
+ {
+ return false;
+ }
+
+ if (!programObject->isLinked())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotLinked);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetUniformIndices(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLsizei uniformCount,
+ const GLchar *const *uniformNames,
+ const GLuint *uniformIndices)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ if (uniformCount < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeCount);
+ return false;
+ }
+
+ Program *programObject = GetValidProgram(context, entryPoint, program);
+ if (!programObject)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetActiveUniformsiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLsizei uniformCount,
+ const GLuint *uniformIndices,
+ GLenum pname,
+ const GLint *params)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ if (uniformCount < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeCount);
+ return false;
+ }
+
+ Program *programObject = GetValidProgram(context, entryPoint, program);
+ if (!programObject)
+ {
+ return false;
+ }
+
+ switch (pname)
+ {
+ case GL_UNIFORM_TYPE:
+ case GL_UNIFORM_SIZE:
+ break;
+ case GL_UNIFORM_NAME_LENGTH:
+ if (context->getExtensions().webglCompatibilityANGLE)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname);
+ return false;
+ }
+ break;
+ case GL_UNIFORM_BLOCK_INDEX:
+ case GL_UNIFORM_OFFSET:
+ case GL_UNIFORM_ARRAY_STRIDE:
+ case GL_UNIFORM_MATRIX_STRIDE:
+ case GL_UNIFORM_IS_ROW_MAJOR:
+ break;
+
+ default:
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname);
+ return false;
+ }
+
+ if (uniformCount > programObject->getActiveUniformCount())
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxActiveUniform);
+ return false;
+ }
+
+ for (int uniformId = 0; uniformId < uniformCount; uniformId++)
+ {
+ const GLuint index = uniformIndices[uniformId];
+
+ if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxActiveUniform);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateGetUniformBlockIndex(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ const GLchar *uniformBlockName)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ Program *programObject = GetValidProgram(context, entryPoint, program);
+ if (!programObject)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetActiveUniformBlockiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformBlockIndex uniformBlockIndex,
+ GLenum pname,
+ const GLint *params)
+{
+ return ValidateGetActiveUniformBlockivBase(context, entryPoint, program, uniformBlockIndex,
+ pname, nullptr);
+}
+
+bool ValidateGetActiveUniformBlockName(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformBlockIndex uniformBlockIndex,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLchar *uniformBlockName)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ Program *programObject = GetValidProgram(context, entryPoint, program);
+ if (!programObject)
+ {
+ return false;
+ }
+
+ if (uniformBlockIndex.value >= programObject->getActiveUniformBlockCount())
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxActiveUniformBlock);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateUniformBlockBinding(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformBlockIndex uniformBlockIndex,
+ GLuint uniformBlockBinding)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ if (uniformBlockBinding >= static_cast<GLuint>(context->getCaps().maxUniformBufferBindings))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kIndexExceedsMaxUniformBufferBindings);
+ return false;
+ }
+
+ Program *programObject = GetValidProgram(context, entryPoint, program);
+ if (!programObject)
+ {
+ return false;
+ }
+
+ // if never linked, there won't be any uniform blocks
+ if (uniformBlockIndex.value >= programObject->getActiveUniformBlockCount())
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kIndexExceedsMaxUniformBufferBindings);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateDrawArraysInstanced(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLint first,
+ GLsizei count,
+ GLsizei primcount)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ return ValidateDrawArraysInstancedBase(context, entryPoint, mode, first, count, primcount);
+}
+
+bool ValidateFenceSync(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum condition,
+ GLbitfield flags)
+{
+ if ((context->getClientMajorVersion() < 3) && !context->getExtensions().syncARB)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ if (condition != GL_SYNC_GPU_COMMANDS_COMPLETE)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFenceCondition);
+ return false;
+ }
+
+ if (flags != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidFlags);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateIsSync(const Context *context, angle::EntryPoint entryPoint, GLsync sync)
+{
+ if ((context->getClientMajorVersion() < 3) && !context->getExtensions().syncARB)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateDeleteSync(const Context *context, angle::EntryPoint entryPoint, GLsync sync)
+{
+ if ((context->getClientMajorVersion() < 3) && !context->getExtensions().syncARB)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ if (sync != static_cast<GLsync>(0) && !context->getSync(sync))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kSyncMissing);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateClientWaitSync(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsync sync,
+ GLbitfield flags,
+ GLuint64 timeout)
+{
+ if ((context->getClientMajorVersion() < 3) && !context->getExtensions().syncARB)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ if ((flags & ~(GL_SYNC_FLUSH_COMMANDS_BIT)) != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidFlags);
+ return false;
+ }
+
+ Sync *clientWaitSync = context->getSync(sync);
+ if (!clientWaitSync)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kSyncMissing);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateWaitSync(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsync sync,
+ GLbitfield flags,
+ GLuint64 timeout)
+{
+ if ((context->getClientMajorVersion() < 3) && !context->getExtensions().syncARB)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ if (flags != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidFlags);
+ return false;
+ }
+
+ if (timeout != GL_TIMEOUT_IGNORED)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidTimeout);
+ return false;
+ }
+
+ Sync *waitSync = context->getSync(sync);
+ if (!waitSync)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kSyncMissing);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetInteger64v(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ const GLint64 *params)
+{
+ if ((context->getClientMajorVersion() < 3) && !context->getExtensions().syncARB)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ GLenum nativeType = GL_NONE;
+ unsigned int numParams = 0;
+ if (!ValidateStateQuery(context, entryPoint, pname, &nativeType, &numParams))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateIsSampler(const Context *context, angle::EntryPoint entryPoint, SamplerID sampler)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateBindSampler(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint unit,
+ SamplerID sampler)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ if (GetIDValue(sampler) != 0 && !context->isSampler(sampler))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidSampler);
+ return false;
+ }
+
+ if (unit >= static_cast<GLuint>(context->getCaps().maxCombinedTextureImageUnits))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidCombinedImageUnit);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateVertexAttribDivisor(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLuint divisor)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ return ValidateVertexAttribIndex(context, entryPoint, index);
+}
+
+bool ValidateTexStorage2D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ if (!ValidateES3TexStorage2DParameters(context, entryPoint, target, levels, internalformat,
+ width, height, 1))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateTexStorage3D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+
+ if (!ValidateES3TexStorage3DParameters(context, entryPoint, target, levels, internalformat,
+ width, height, depth))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetBufferParameteri64v(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding target,
+ GLenum pname,
+ const GLint64 *params)
+{
+ return ValidateGetBufferParameterBase(context, entryPoint, target, pname, false, nullptr);
+}
+
+bool ValidateGetSamplerParameterfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID sampler,
+ GLenum pname,
+ const GLfloat *params)
+{
+ return ValidateGetSamplerParameterBase(context, entryPoint, sampler, pname, nullptr);
+}
+
+bool ValidateGetSamplerParameteriv(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID sampler,
+ GLenum pname,
+ const GLint *params)
+{
+ return ValidateGetSamplerParameterBase(context, entryPoint, sampler, pname, nullptr);
+}
+
+bool ValidateGetSamplerParameterIivOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID sampler,
+ GLenum pname,
+ const GLint *params)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+ return ValidateGetSamplerParameterBase(context, entryPoint, sampler, pname, nullptr);
+}
+
+bool ValidateGetSamplerParameterIuivOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID sampler,
+ GLenum pname,
+ const GLuint *params)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+ return ValidateGetSamplerParameterBase(context, entryPoint, sampler, pname, nullptr);
+}
+
+bool ValidateSamplerParameterf(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID sampler,
+ GLenum pname,
+ GLfloat param)
+{
+ return ValidateSamplerParameterBase(context, entryPoint, sampler, pname, -1, false, &param);
+}
+
+bool ValidateSamplerParameterfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID sampler,
+ GLenum pname,
+ const GLfloat *params)
+{
+ return ValidateSamplerParameterBase(context, entryPoint, sampler, pname, -1, true, params);
+}
+
+bool ValidateSamplerParameteri(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID sampler,
+ GLenum pname,
+ GLint param)
+{
+ return ValidateSamplerParameterBase(context, entryPoint, sampler, pname, -1, false, &param);
+}
+
+bool ValidateSamplerParameteriv(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID sampler,
+ GLenum pname,
+ const GLint *params)
+{
+ return ValidateSamplerParameterBase(context, entryPoint, sampler, pname, -1, true, params);
+}
+
+bool ValidateSamplerParameterIivOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID sampler,
+ GLenum pname,
+ const GLint *params)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+ return ValidateSamplerParameterBase(context, entryPoint, sampler, pname, -1, true, params);
+}
+
+bool ValidateSamplerParameterIuivOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID sampler,
+ GLenum pname,
+ const GLuint *params)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+ return ValidateSamplerParameterBase(context, entryPoint, sampler, pname, -1, true, params);
+}
+
+bool ValidateGetVertexAttribIiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum pname,
+ const GLint *params)
+{
+ return ValidateGetVertexAttribBase(context, entryPoint, index, pname, nullptr, false, true);
+}
+
+bool ValidateGetVertexAttribIuiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum pname,
+ const GLuint *params)
+{
+ return ValidateGetVertexAttribBase(context, entryPoint, index, pname, nullptr, false, true);
+}
+
+bool ValidateGetInternalformativ(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum internalformat,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLint *params)
+{
+ return ValidateGetInternalFormativBase(context, entryPoint, target, internalformat, pname,
+ bufSize, nullptr);
+}
+
+bool ValidateBindFragDataLocationIndexedEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLuint colorNumber,
+ GLuint index,
+ const char *name)
+{
+ if (!context->getExtensions().blendFuncExtendedEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+ if (index > 1)
+ {
+ // This error is not explicitly specified but the spec does say that "<index> may be zero or
+ // one to specify that the color be used as either the first or second color input to the
+ // blend equation, respectively"
+ context->validationError(entryPoint, GL_INVALID_VALUE, kFragDataBindingIndexOutOfRange);
+ return false;
+ }
+ if (index == 1)
+ {
+ if (colorNumber >= context->getCaps().maxDualSourceDrawBuffers)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kColorNumberGreaterThanMaxDualSourceDrawBuffers);
+ return false;
+ }
+ }
+ else
+ {
+ if (colorNumber >= static_cast<GLuint>(context->getCaps().maxDrawBuffers))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE,
+ kColorNumberGreaterThanMaxDrawBuffers);
+ return false;
+ }
+ }
+ Program *programObject = GetValidProgram(context, entryPoint, program);
+ if (!programObject)
+ {
+ return false;
+ }
+ return true;
+}
+
+bool ValidateBindFragDataLocationEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLuint colorNumber,
+ const char *name)
+{
+ return ValidateBindFragDataLocationIndexedEXT(context, entryPoint, program, colorNumber, 0u,
+ name);
+}
+
+bool ValidateGetFragDataIndexEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ const char *name)
+{
+ if (!context->getExtensions().blendFuncExtendedEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+ Program *programObject = GetValidProgram(context, entryPoint, program);
+ if (!programObject)
+ {
+ return false;
+ }
+ if (!programObject->isLinked())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotLinked);
+ return false;
+ }
+ return true;
+}
+
+bool ValidateTexStorage2DMultisampleANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedSampleLocations)
+{
+ if (!context->getExtensions().textureMultisampleANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kMultisampleTextureExtensionOrES31Required);
+ return false;
+ }
+
+ return ValidateTexStorage2DMultisampleBase(context, entryPoint, target, samples, internalFormat,
+ width, height);
+}
+
+bool ValidateGetTexLevelParameterfvANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLenum pname,
+ const GLfloat *params)
+{
+ if (!context->getExtensions().textureMultisampleANGLE &&
+ !context->getExtensions().getTexLevelParameterANGLE)
+ {
+ context->validationError(
+ entryPoint, GL_INVALID_OPERATION,
+ kMultisampleTextureExtensionOrGetTexLevelParameterExtensionOrES31Required);
+ return false;
+ }
+
+ return ValidateGetTexLevelParameterBase(context, entryPoint, target, level, pname, nullptr);
+}
+
+bool ValidateGetTexLevelParameterivANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLenum pname,
+ const GLint *params)
+{
+ if (!context->getExtensions().textureMultisampleANGLE &&
+ !context->getExtensions().getTexLevelParameterANGLE)
+ {
+ context->validationError(
+ entryPoint, GL_INVALID_OPERATION,
+ kMultisampleTextureExtensionOrGetTexLevelParameterExtensionOrES31Required);
+ return false;
+ }
+
+ return ValidateGetTexLevelParameterBase(context, entryPoint, target, level, pname, nullptr);
+}
+
+bool ValidateGetMultisamplefvANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLuint index,
+ const GLfloat *val)
+{
+ if (!context->getExtensions().textureMultisampleANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kMultisampleTextureExtensionOrES31Required);
+ return false;
+ }
+
+ return ValidateGetMultisamplefvBase(context, entryPoint, pname, index, val);
+}
+
+bool ValidateSampleMaskiANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint maskNumber,
+ GLbitfield mask)
+{
+ if (!context->getExtensions().textureMultisampleANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kMultisampleTextureExtensionOrES31Required);
+ return false;
+ }
+
+ return ValidateSampleMaskiBase(context, entryPoint, maskNumber, mask);
+}
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/validationES3.h b/gfx/angle/checkout/src/libANGLE/validationES3.h
new file mode 100644
index 0000000000..dcea322874
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/validationES3.h
@@ -0,0 +1,72 @@
+//
+// Copyright 2018 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.
+//
+// validationES3.h:
+// Inlined validation functions for OpenGL ES 3.0 entry points.
+
+#ifndef LIBANGLE_VALIDATION_ES3_H_
+#define LIBANGLE_VALIDATION_ES3_H_
+
+#include "libANGLE/ErrorStrings.h"
+#include "libANGLE/validationES3_autogen.h"
+
+namespace gl
+{
+bool ValidateES3TexImageParametersBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLenum internalformat,
+ bool isCompressed,
+ bool isSubImage,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ GLsizei imageSize,
+ const void *pixels);
+
+bool ValidateES3TexStorageParametersLevel(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLsizei levels,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth);
+
+bool ValidateES3TexStorageParametersExtent(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLsizei levels,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth);
+
+bool ValidateES3TexStorageParametersTexObject(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target);
+
+bool ValidateES3TexStorageParametersFormat(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth);
+
+bool ValidateProgramParameteriBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLenum pname,
+ GLint value);
+} // namespace gl
+
+#endif // LIBANGLE_VALIDATION_ES3_H_
diff --git a/gfx/angle/checkout/src/libANGLE/validationES31.cpp b/gfx/angle/checkout/src/libANGLE/validationES31.cpp
new file mode 100644
index 0000000000..c0222f7497
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/validationES31.cpp
@@ -0,0 +1,3157 @@
+//
+// 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.
+//
+
+// validationES31.cpp: Validation functions for OpenGL ES 3.1 entry point parameters
+
+#include "libANGLE/validationES31_autogen.h"
+
+#include "libANGLE/Context.h"
+#include "libANGLE/ErrorStrings.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/ProgramExecutable.h"
+#include "libANGLE/VertexArray.h"
+#include "libANGLE/validationES.h"
+#include "libANGLE/validationES2_autogen.h"
+#include "libANGLE/validationES31.h"
+#include "libANGLE/validationES3_autogen.h"
+
+#include "common/utilities.h"
+
+using namespace angle;
+
+namespace gl
+{
+using namespace err;
+
+namespace
+{
+
+bool ValidateNamedProgramInterface(GLenum programInterface)
+{
+ switch (programInterface)
+ {
+ case GL_UNIFORM:
+ case GL_UNIFORM_BLOCK:
+ case GL_PROGRAM_INPUT:
+ case GL_PROGRAM_OUTPUT:
+ case GL_TRANSFORM_FEEDBACK_VARYING:
+ case GL_BUFFER_VARIABLE:
+ case GL_SHADER_STORAGE_BLOCK:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool ValidateLocationProgramInterface(GLenum programInterface)
+{
+ switch (programInterface)
+ {
+ case GL_UNIFORM:
+ case GL_PROGRAM_INPUT:
+ case GL_PROGRAM_OUTPUT:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool ValidateProgramInterface(GLenum programInterface)
+{
+ return (programInterface == GL_ATOMIC_COUNTER_BUFFER ||
+ ValidateNamedProgramInterface(programInterface));
+}
+
+bool ValidateProgramResourceProperty(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum prop)
+{
+ ASSERT(context);
+ switch (prop)
+ {
+ case GL_ACTIVE_VARIABLES:
+ case GL_BUFFER_BINDING:
+ case GL_NUM_ACTIVE_VARIABLES:
+
+ case GL_ARRAY_SIZE:
+
+ case GL_ARRAY_STRIDE:
+ case GL_BLOCK_INDEX:
+ case GL_IS_ROW_MAJOR:
+ case GL_MATRIX_STRIDE:
+
+ case GL_ATOMIC_COUNTER_BUFFER_INDEX:
+
+ case GL_BUFFER_DATA_SIZE:
+
+ case GL_LOCATION:
+
+ case GL_NAME_LENGTH:
+
+ case GL_OFFSET:
+
+ case GL_REFERENCED_BY_VERTEX_SHADER:
+ case GL_REFERENCED_BY_FRAGMENT_SHADER:
+ case GL_REFERENCED_BY_COMPUTE_SHADER:
+
+ case GL_TOP_LEVEL_ARRAY_SIZE:
+ case GL_TOP_LEVEL_ARRAY_STRIDE:
+
+ case GL_TYPE:
+ return true;
+
+ case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
+ return context->getExtensions().geometryShaderAny() ||
+ context->getClientVersion() >= ES_3_2;
+
+ case GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT:
+ case GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT:
+ case GL_IS_PER_PATCH_EXT:
+ return context->getExtensions().tessellationShaderEXT ||
+ context->getClientVersion() >= ES_3_2;
+
+ case GL_LOCATION_INDEX_EXT:
+ return context->getExtensions().blendFuncExtendedEXT;
+
+ default:
+ return false;
+ }
+}
+
+// GLES 3.10 spec: Page 82 -- Table 7.2
+bool ValidateProgramResourcePropertyByInterface(GLenum prop, GLenum programInterface)
+{
+ switch (prop)
+ {
+ case GL_ACTIVE_VARIABLES:
+ case GL_BUFFER_BINDING:
+ case GL_NUM_ACTIVE_VARIABLES:
+ {
+ switch (programInterface)
+ {
+ case GL_ATOMIC_COUNTER_BUFFER:
+ case GL_SHADER_STORAGE_BLOCK:
+ case GL_UNIFORM_BLOCK:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ case GL_ARRAY_SIZE:
+ {
+ switch (programInterface)
+ {
+ case GL_BUFFER_VARIABLE:
+ case GL_PROGRAM_INPUT:
+ case GL_PROGRAM_OUTPUT:
+ case GL_TRANSFORM_FEEDBACK_VARYING:
+ case GL_UNIFORM:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ case GL_ARRAY_STRIDE:
+ case GL_BLOCK_INDEX:
+ case GL_IS_ROW_MAJOR:
+ case GL_MATRIX_STRIDE:
+ {
+ switch (programInterface)
+ {
+ case GL_BUFFER_VARIABLE:
+ case GL_UNIFORM:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ case GL_ATOMIC_COUNTER_BUFFER_INDEX:
+ {
+ if (programInterface == GL_UNIFORM)
+ {
+ return true;
+ }
+ return false;
+ }
+
+ case GL_BUFFER_DATA_SIZE:
+ {
+ switch (programInterface)
+ {
+ case GL_ATOMIC_COUNTER_BUFFER:
+ case GL_SHADER_STORAGE_BLOCK:
+ case GL_UNIFORM_BLOCK:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ case GL_LOCATION:
+ {
+ return ValidateLocationProgramInterface(programInterface);
+ }
+
+ case GL_LOCATION_INDEX_EXT:
+ {
+ // EXT_blend_func_extended
+ return (programInterface == GL_PROGRAM_OUTPUT);
+ }
+
+ case GL_NAME_LENGTH:
+ {
+ return ValidateNamedProgramInterface(programInterface);
+ }
+
+ case GL_OFFSET:
+ {
+ switch (programInterface)
+ {
+ case GL_BUFFER_VARIABLE:
+ case GL_UNIFORM:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ case GL_REFERENCED_BY_VERTEX_SHADER:
+ case GL_REFERENCED_BY_FRAGMENT_SHADER:
+ case GL_REFERENCED_BY_COMPUTE_SHADER:
+ case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
+ case GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT:
+ case GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT:
+ {
+ switch (programInterface)
+ {
+ case GL_ATOMIC_COUNTER_BUFFER:
+ case GL_BUFFER_VARIABLE:
+ case GL_PROGRAM_INPUT:
+ case GL_PROGRAM_OUTPUT:
+ case GL_SHADER_STORAGE_BLOCK:
+ case GL_UNIFORM:
+ case GL_UNIFORM_BLOCK:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ case GL_TOP_LEVEL_ARRAY_SIZE:
+ case GL_TOP_LEVEL_ARRAY_STRIDE:
+ {
+ if (programInterface == GL_BUFFER_VARIABLE)
+ {
+ return true;
+ }
+ return false;
+ }
+
+ case GL_TYPE:
+ {
+ switch (programInterface)
+ {
+ case GL_BUFFER_VARIABLE:
+ case GL_PROGRAM_INPUT:
+ case GL_PROGRAM_OUTPUT:
+ case GL_TRANSFORM_FEEDBACK_VARYING:
+ case GL_UNIFORM:
+ return true;
+ default:
+ return false;
+ }
+ }
+ case GL_IS_PER_PATCH_EXT:
+ switch (programInterface)
+ {
+ case GL_PROGRAM_INPUT:
+ case GL_PROGRAM_OUTPUT:
+ return true;
+ }
+ return false;
+
+ default:
+ return false;
+ }
+}
+
+bool ValidateProgramResourceIndex(const Program *programObject,
+ GLenum programInterface,
+ GLuint index)
+{
+ switch (programInterface)
+ {
+ case GL_PROGRAM_INPUT:
+ return (index <
+ static_cast<GLuint>(programObject->getState().getProgramInputs().size()));
+
+ case GL_PROGRAM_OUTPUT:
+ return (index < static_cast<GLuint>(programObject->getOutputResourceCount()));
+
+ case GL_UNIFORM:
+ return (index < static_cast<GLuint>(programObject->getActiveUniformCount()));
+
+ case GL_BUFFER_VARIABLE:
+ return (index < static_cast<GLuint>(programObject->getActiveBufferVariableCount()));
+
+ case GL_SHADER_STORAGE_BLOCK:
+ return (index < static_cast<GLuint>(programObject->getActiveShaderStorageBlockCount()));
+
+ case GL_UNIFORM_BLOCK:
+ return (index < programObject->getActiveUniformBlockCount());
+
+ case GL_ATOMIC_COUNTER_BUFFER:
+ return (index < programObject->getActiveAtomicCounterBufferCount());
+
+ case GL_TRANSFORM_FEEDBACK_VARYING:
+ return (index < static_cast<GLuint>(programObject->getTransformFeedbackVaryingCount()));
+
+ default:
+ UNREACHABLE();
+ return false;
+ }
+}
+
+bool ValidateProgramUniformBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum valueType,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count)
+{
+ const LinkedUniform *uniform = nullptr;
+ Program *programObject = GetValidProgram(context, entryPoint, program);
+ return ValidateUniformCommonBase(context, entryPoint, programObject, location, count,
+ &uniform) &&
+ ValidateUniformValue(context, entryPoint, valueType, uniform->type);
+}
+
+bool ValidateProgramUniformMatrixBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum valueType,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose)
+{
+ const LinkedUniform *uniform = nullptr;
+ Program *programObject = GetValidProgram(context, entryPoint, program);
+ return ValidateUniformCommonBase(context, entryPoint, programObject, location, count,
+ &uniform) &&
+ ValidateUniformMatrixValue(context, entryPoint, valueType, uniform->type);
+}
+
+bool ValidateVertexAttribFormatCommon(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint relativeOffset)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ const Caps &caps = context->getCaps();
+ if (relativeOffset > static_cast<GLuint>(caps.maxVertexAttribRelativeOffset))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kRelativeOffsetTooLarge);
+ return false;
+ }
+
+ // [OpenGL ES 3.1] Section 10.3.1 page 243:
+ // An INVALID_OPERATION error is generated if the default vertex array object is bound.
+ if (context->getState().getVertexArrayId().value == 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kDefaultVertexArray);
+ return false;
+ }
+
+ return true;
+}
+
+} // anonymous namespace
+
+bool ValidateGetBooleani_v(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint index,
+ const GLboolean *data)
+{
+ if (context->getClientVersion() < ES_3_1 && !context->getExtensions().drawBuffersIndexedAny())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kES31OrDrawBuffersIndexedExtensionNotAvailable);
+ return false;
+ }
+
+ if (!ValidateIndexedStateQuery(context, entryPoint, target, index, nullptr))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetBooleani_vRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint index,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLboolean *data)
+{
+ if (context->getClientVersion() < ES_3_1 && !context->getExtensions().drawBuffersIndexedAny())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kES31OrDrawBuffersIndexedExtensionNotAvailable);
+ return false;
+ }
+
+ if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
+ {
+ return false;
+ }
+
+ GLsizei numParams = 0;
+
+ if (!ValidateIndexedStateQuery(context, entryPoint, target, index, &numParams))
+ {
+ return false;
+ }
+
+ if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
+ {
+ return false;
+ }
+
+ SetRobustLengthParam(length, numParams);
+ return true;
+}
+
+bool ValidateDrawIndirectBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ const void *indirect)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ // Here the third parameter 1 is only to pass the count validation.
+ if (!ValidateDrawBase(context, entryPoint, mode))
+ {
+ return false;
+ }
+
+ const State &state = context->getState();
+
+ // An INVALID_OPERATION error is generated if zero is bound to VERTEX_ARRAY_BINDING,
+ // DRAW_INDIRECT_BUFFER or to any enabled vertex array.
+ if (state.getVertexArrayId().value == 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kDefaultVertexArray);
+ return false;
+ }
+
+ if (context->getStateCache().hasAnyActiveClientAttrib())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kClientDataInVertexArray);
+ return false;
+ }
+
+ Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect);
+ if (!drawIndirectBuffer)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kDrawIndirectBufferNotBound);
+ return false;
+ }
+
+ // An INVALID_VALUE error is generated if indirect is not a multiple of the size, in basic
+ // machine units, of uint.
+ GLint64 offset = reinterpret_cast<GLint64>(indirect);
+ if ((static_cast<GLuint>(offset) % sizeof(GLuint)) != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidIndirectOffset);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateDrawArraysIndirect(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ const void *indirect)
+{
+ const State &state = context->getState();
+ TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
+ if (curTransformFeedback && curTransformFeedback->isActive() &&
+ !curTransformFeedback->isPaused())
+ {
+ // EXT_geometry_shader allows transform feedback to work with all draw commands.
+ // [EXT_geometry_shader] Section 12.1, "Transform Feedback"
+ if (context->getExtensions().geometryShaderAny() || context->getClientVersion() >= ES_3_2)
+ {
+ if (!ValidateTransformFeedbackPrimitiveMode(
+ context, entryPoint, curTransformFeedback->getPrimitiveMode(), mode))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kInvalidDrawModeTransformFeedback);
+ return false;
+ }
+ }
+ else
+ {
+ // An INVALID_OPERATION error is generated if transform feedback is active and not
+ // paused.
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kUnsupportedDrawModeForTransformFeedback);
+ return false;
+ }
+ }
+
+ if (!ValidateDrawIndirectBase(context, entryPoint, mode, indirect))
+ return false;
+
+ Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect);
+ CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(indirect));
+ // In OpenGL ES3.1 spec, session 10.5, it defines the struct of DrawArraysIndirectCommand
+ // which's size is 4 * sizeof(uint).
+ auto checkedSum = checkedOffset + 4 * sizeof(GLuint);
+ if (!checkedSum.IsValid() ||
+ checkedSum.ValueOrDie() > static_cast<size_t>(drawIndirectBuffer->getSize()))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kParamOverflow);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateDrawElementsIndirect(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ DrawElementsType type,
+ const void *indirect)
+{
+ if (!ValidateDrawElementsBase(context, entryPoint, mode, type))
+ {
+ return false;
+ }
+
+ const State &state = context->getState();
+ const VertexArray *vao = state.getVertexArray();
+ Buffer *elementArrayBuffer = vao->getElementArrayBuffer();
+ if (!elementArrayBuffer)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kMustHaveElementArrayBinding);
+ return false;
+ }
+
+ if (!ValidateDrawIndirectBase(context, entryPoint, mode, indirect))
+ return false;
+
+ Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect);
+ CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(indirect));
+ // In OpenGL ES3.1 spec, session 10.5, it defines the struct of DrawElementsIndirectCommand
+ // which's size is 5 * sizeof(uint).
+ auto checkedSum = checkedOffset + 5 * sizeof(GLuint);
+ if (!checkedSum.IsValid() ||
+ checkedSum.ValueOrDie() > static_cast<size_t>(drawIndirectBuffer->getSize()))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kParamOverflow);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateMultiDrawIndirectBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei drawcount,
+ GLsizei stride)
+{
+ if (!context->getExtensions().multiDrawIndirectEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ // An INVALID_VALUE error is generated if stride is neither 0 nor a multiple of 4.
+ if ((stride & 3) != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidDrawBufferValue);
+ return false;
+ }
+
+ // An INVALID_VALUE error is generated if drawcount is not positive.
+ if (drawcount <= 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidValueNonPositive);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateProgramUniform1iBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLint v0)
+{
+ return ValidateProgramUniform1ivBase(context, entryPoint, program, location, 1, &v0);
+}
+
+bool ValidateProgramUniform2iBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLint v0,
+ GLint v1)
+{
+ GLint xy[2] = {v0, v1};
+ return ValidateProgramUniform2ivBase(context, entryPoint, program, location, 1, xy);
+}
+
+bool ValidateProgramUniform3iBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLint v0,
+ GLint v1,
+ GLint v2)
+{
+ GLint xyz[3] = {v0, v1, v2};
+ return ValidateProgramUniform3ivBase(context, entryPoint, program, location, 1, xyz);
+}
+
+bool ValidateProgramUniform4iBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLint v0,
+ GLint v1,
+ GLint v2,
+ GLint v3)
+{
+ GLint xyzw[4] = {v0, v1, v2, v3};
+ return ValidateProgramUniform4ivBase(context, entryPoint, program, location, 1, xyzw);
+}
+
+bool ValidateProgramUniform1uiBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLuint v0)
+{
+ return ValidateProgramUniform1uivBase(context, entryPoint, program, location, 1, &v0);
+}
+
+bool ValidateProgramUniform2uiBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLuint v0,
+ GLuint v1)
+{
+ GLuint xy[2] = {v0, v1};
+ return ValidateProgramUniform2uivBase(context, entryPoint, program, location, 1, xy);
+}
+
+bool ValidateProgramUniform3uiBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLuint v0,
+ GLuint v1,
+ GLuint v2)
+{
+ GLuint xyz[3] = {v0, v1, v2};
+ return ValidateProgramUniform3uivBase(context, entryPoint, program, location, 1, xyz);
+}
+
+bool ValidateProgramUniform4uiBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLuint v0,
+ GLuint v1,
+ GLuint v2,
+ GLuint v3)
+{
+ GLuint xyzw[4] = {v0, v1, v2, v3};
+ return ValidateProgramUniform4uivBase(context, entryPoint, program, location, 1, xyzw);
+}
+
+bool ValidateProgramUniform1fBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLfloat v0)
+{
+ return ValidateProgramUniform1fvBase(context, entryPoint, program, location, 1, &v0);
+}
+
+bool ValidateProgramUniform2fBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLfloat v0,
+ GLfloat v1)
+{
+ GLfloat xy[2] = {v0, v1};
+ return ValidateProgramUniform2fvBase(context, entryPoint, program, location, 1, xy);
+}
+
+bool ValidateProgramUniform3fBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLfloat v0,
+ GLfloat v1,
+ GLfloat v2)
+{
+ GLfloat xyz[3] = {v0, v1, v2};
+ return ValidateProgramUniform3fvBase(context, entryPoint, program, location, 1, xyz);
+}
+
+bool ValidateProgramUniform4fBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLfloat v0,
+ GLfloat v1,
+ GLfloat v2,
+ GLfloat v3)
+{
+ GLfloat xyzw[4] = {v0, v1, v2, v3};
+ return ValidateProgramUniform4fvBase(context, entryPoint, program, location, 1, xyzw);
+}
+
+bool ValidateProgramUniform1ivBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ const GLint *value)
+{
+ const LinkedUniform *uniform = nullptr;
+ Program *programObject = GetValidProgram(context, entryPoint, program);
+ return ValidateUniformCommonBase(context, entryPoint, programObject, location, count,
+ &uniform) &&
+ ValidateUniform1ivValue(context, entryPoint, uniform->type, count, value);
+}
+
+bool ValidateProgramUniform2ivBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ const GLint *value)
+{
+ return ValidateProgramUniformBase(context, entryPoint, GL_INT_VEC2, program, location, count);
+}
+
+bool ValidateProgramUniform3ivBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ const GLint *value)
+{
+ return ValidateProgramUniformBase(context, entryPoint, GL_INT_VEC3, program, location, count);
+}
+
+bool ValidateProgramUniform4ivBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ const GLint *value)
+{
+ return ValidateProgramUniformBase(context, entryPoint, GL_INT_VEC4, program, location, count);
+}
+
+bool ValidateProgramUniform1uivBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ const GLuint *value)
+{
+ return ValidateProgramUniformBase(context, entryPoint, GL_UNSIGNED_INT, program, location,
+ count);
+}
+
+bool ValidateProgramUniform2uivBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ const GLuint *value)
+{
+ return ValidateProgramUniformBase(context, entryPoint, GL_UNSIGNED_INT_VEC2, program, location,
+ count);
+}
+
+bool ValidateProgramUniform3uivBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ const GLuint *value)
+{
+ return ValidateProgramUniformBase(context, entryPoint, GL_UNSIGNED_INT_VEC3, program, location,
+ count);
+}
+
+bool ValidateProgramUniform4uivBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ const GLuint *value)
+{
+ return ValidateProgramUniformBase(context, entryPoint, GL_UNSIGNED_INT_VEC4, program, location,
+ count);
+}
+
+bool ValidateProgramUniform1fvBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ const GLfloat *value)
+{
+ return ValidateProgramUniformBase(context, entryPoint, GL_FLOAT, program, location, count);
+}
+
+bool ValidateProgramUniform2fvBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ const GLfloat *value)
+{
+ return ValidateProgramUniformBase(context, entryPoint, GL_FLOAT_VEC2, program, location, count);
+}
+
+bool ValidateProgramUniform3fvBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ const GLfloat *value)
+{
+ return ValidateProgramUniformBase(context, entryPoint, GL_FLOAT_VEC3, program, location, count);
+}
+
+bool ValidateProgramUniform4fvBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ const GLfloat *value)
+{
+ return ValidateProgramUniformBase(context, entryPoint, GL_FLOAT_VEC4, program, location, count);
+}
+
+bool ValidateProgramUniformMatrix2fvBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return ValidateProgramUniformMatrixBase(context, entryPoint, GL_FLOAT_MAT2, program, location,
+ count, transpose);
+}
+
+bool ValidateProgramUniformMatrix3fvBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return ValidateProgramUniformMatrixBase(context, entryPoint, GL_FLOAT_MAT3, program, location,
+ count, transpose);
+}
+
+bool ValidateProgramUniformMatrix4fvBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return ValidateProgramUniformMatrixBase(context, entryPoint, GL_FLOAT_MAT4, program, location,
+ count, transpose);
+}
+
+bool ValidateProgramUniformMatrix2x3fvBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return ValidateProgramUniformMatrixBase(context, entryPoint, GL_FLOAT_MAT2x3, program, location,
+ count, transpose);
+}
+
+bool ValidateProgramUniformMatrix3x2fvBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return ValidateProgramUniformMatrixBase(context, entryPoint, GL_FLOAT_MAT3x2, program, location,
+ count, transpose);
+}
+
+bool ValidateProgramUniformMatrix2x4fvBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return ValidateProgramUniformMatrixBase(context, entryPoint, GL_FLOAT_MAT2x4, program, location,
+ count, transpose);
+}
+
+bool ValidateProgramUniformMatrix4x2fvBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return ValidateProgramUniformMatrixBase(context, entryPoint, GL_FLOAT_MAT4x2, program, location,
+ count, transpose);
+}
+
+bool ValidateProgramUniformMatrix3x4fvBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return ValidateProgramUniformMatrixBase(context, entryPoint, GL_FLOAT_MAT3x4, program, location,
+ count, transpose);
+}
+
+bool ValidateProgramUniformMatrix4x3fvBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return ValidateProgramUniformMatrixBase(context, entryPoint, GL_FLOAT_MAT4x3, program, location,
+ count, transpose);
+}
+
+bool ValidateGetTexLevelParameterfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLenum pname,
+ const GLfloat *params)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateGetTexLevelParameterBase(context, entryPoint, target, level, pname, nullptr);
+}
+
+bool ValidateGetTexLevelParameterfvRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLfloat *params)
+{
+ UNIMPLEMENTED();
+ return false;
+}
+
+bool ValidateGetTexLevelParameteriv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLenum pname,
+ const GLint *params)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateGetTexLevelParameterBase(context, entryPoint, target, level, pname, nullptr);
+}
+
+bool ValidateGetTexLevelParameterivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params)
+{
+ UNIMPLEMENTED();
+ return false;
+}
+
+bool ValidateTexStorage2DMultisample(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedSampleLocations)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateTexStorage2DMultisampleBase(context, entryPoint, target, samples, internalFormat,
+ width, height);
+}
+
+bool ValidateTexStorageMem2DMultisampleEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedSampleLocations,
+ MemoryObjectID memory,
+ GLuint64 offset)
+{
+ if (!context->getExtensions().memoryObjectEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ UNIMPLEMENTED();
+ return false;
+}
+
+bool ValidateGetMultisamplefv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLuint index,
+ const GLfloat *val)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateGetMultisamplefvBase(context, entryPoint, pname, index, val);
+}
+
+bool ValidateGetMultisamplefvRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLuint index,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLfloat *val)
+{
+ UNIMPLEMENTED();
+ return false;
+}
+
+bool ValidateFramebufferParameteri(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum pname,
+ GLint param)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateFramebufferParameteriBase(context, entryPoint, target, pname, param);
+}
+
+bool ValidateGetFramebufferParameteriv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum pname,
+ const GLint *params)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateGetFramebufferParameterivBase(context, entryPoint, target, pname, params);
+}
+
+bool ValidateGetFramebufferParameterivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params)
+{
+ UNIMPLEMENTED();
+ return false;
+}
+
+bool ValidateGetProgramResourceIndex(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLenum programInterface,
+ const GLchar *name)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ Program *programObject = GetValidProgram(context, entryPoint, program);
+ if (programObject == nullptr)
+ {
+ return false;
+ }
+
+ if (!ValidateNamedProgramInterface(programInterface))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidProgramInterface);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateBindVertexBuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint bindingIndex,
+ BufferID buffer,
+ GLintptr offset,
+ GLsizei stride)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ if (!context->isBufferGenerated(buffer))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kObjectNotGenerated);
+ return false;
+ }
+
+ const Caps &caps = context->getCaps();
+ if (bindingIndex >= static_cast<GLuint>(caps.maxVertexAttribBindings))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsMaxVertexAttribBindings);
+ return false;
+ }
+
+ if (offset < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeOffset);
+ return false;
+ }
+
+ if (stride < 0 || stride > caps.maxVertexAttribStride)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsMaxVertexAttribStride);
+ return false;
+ }
+
+ // [OpenGL ES 3.1] Section 10.3.1 page 244:
+ // An INVALID_OPERATION error is generated if the default vertex array object is bound.
+ if (context->getState().getVertexArrayId().value == 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kDefaultVertexArray);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateVertexBindingDivisor(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint bindingIndex,
+ GLuint divisor)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ const Caps &caps = context->getCaps();
+ if (bindingIndex >= static_cast<GLuint>(caps.maxVertexAttribBindings))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsMaxVertexAttribBindings);
+ return false;
+ }
+
+ // [OpenGL ES 3.1] Section 10.3.1 page 243:
+ // An INVALID_OPERATION error is generated if the default vertex array object is bound.
+ if (context->getState().getVertexArrayId().value == 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kDefaultVertexArray);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateVertexAttribFormat(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint attribindex,
+ GLint size,
+ VertexAttribType type,
+ GLboolean normalized,
+ GLuint relativeoffset)
+{
+ if (!ValidateVertexAttribFormatCommon(context, entryPoint, relativeoffset))
+ {
+ return false;
+ }
+
+ return ValidateFloatVertexFormat(context, entryPoint, attribindex, size, type);
+}
+
+bool ValidateVertexAttribIFormat(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint attribindex,
+ GLint size,
+ VertexAttribType type,
+ GLuint relativeoffset)
+{
+ if (!ValidateVertexAttribFormatCommon(context, entryPoint, relativeoffset))
+ {
+ return false;
+ }
+
+ return ValidateIntegerVertexFormat(context, entryPoint, attribindex, size, type);
+}
+
+bool ValidateVertexAttribBinding(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint attribIndex,
+ GLuint bindingIndex)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ // [OpenGL ES 3.1] Section 10.3.1 page 243:
+ // An INVALID_OPERATION error is generated if the default vertex array object is bound.
+ if (context->getState().getVertexArrayId().value == 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kDefaultVertexArray);
+ return false;
+ }
+
+ const Caps &caps = context->getCaps();
+ if (attribIndex >= static_cast<GLuint>(caps.maxVertexAttributes))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
+ return false;
+ }
+
+ if (bindingIndex >= static_cast<GLuint>(caps.maxVertexAttribBindings))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsMaxVertexAttribBindings);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetProgramResourceName(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLenum programInterface,
+ GLuint index,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLchar *name)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ Program *programObject = GetValidProgram(context, entryPoint, program);
+ if (programObject == nullptr)
+ {
+ return false;
+ }
+
+ if (!ValidateNamedProgramInterface(programInterface))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidProgramInterface);
+ return false;
+ }
+
+ if (!ValidateProgramResourceIndex(programObject, programInterface, index))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidProgramResourceIndex);
+ return false;
+ }
+
+ if (bufSize < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBufferSize);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateDispatchCompute(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint numGroupsX,
+ GLuint numGroupsY,
+ GLuint numGroupsZ)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ const State &state = context->getState();
+ const ProgramExecutable *executable = state.getProgramExecutable();
+
+ if (executable == nullptr || !executable->hasLinkedShaderStage(ShaderType::Compute))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kNoActiveProgramWithComputeShader);
+ return false;
+ }
+
+ const Caps &caps = context->getCaps();
+ if (numGroupsX > static_cast<GLuint>(caps.maxComputeWorkGroupCount[0]))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsComputeWorkGroupCountX);
+ return false;
+ }
+ if (numGroupsY > static_cast<GLuint>(caps.maxComputeWorkGroupCount[1]))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsComputeWorkGroupCountY);
+ return false;
+ }
+ if (numGroupsZ > static_cast<GLuint>(caps.maxComputeWorkGroupCount[2]))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsComputeWorkGroupCountZ);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateDispatchComputeIndirect(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLintptr indirect)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ const State &state = context->getState();
+ const ProgramExecutable *executable = state.getProgramExecutable();
+
+ if (executable == nullptr || !executable->hasLinkedShaderStage(ShaderType::Compute))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kNoActiveProgramWithComputeShader);
+ return false;
+ }
+
+ if (indirect < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeOffset);
+ return false;
+ }
+
+ if ((indirect & (sizeof(GLuint) - 1)) != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kOffsetMustBeMultipleOfUint);
+ return false;
+ }
+
+ Buffer *dispatchIndirectBuffer = state.getTargetBuffer(BufferBinding::DispatchIndirect);
+ if (!dispatchIndirectBuffer)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kDispatchIndirectBufferNotBound);
+ return false;
+ }
+
+ CheckedNumeric<GLuint64> checkedOffset(static_cast<GLuint64>(indirect));
+ auto checkedSum = checkedOffset + static_cast<GLuint64>(3 * sizeof(GLuint));
+ if (!checkedSum.IsValid() ||
+ checkedSum.ValueOrDie() > static_cast<GLuint64>(dispatchIndirectBuffer->getSize()))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInsufficientBufferSize);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateBindImageTexture(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint unit,
+ TextureID texture,
+ GLint level,
+ GLboolean layered,
+ GLint layer,
+ GLenum access,
+ GLenum format)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ GLuint maxImageUnits = static_cast<GLuint>(context->getCaps().maxImageUnits);
+ if (unit >= maxImageUnits)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsMaxImageUnits);
+ return false;
+ }
+
+ if (level < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeLevel);
+ return false;
+ }
+
+ if (layer < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeLayer);
+ return false;
+ }
+
+ if (access != GL_READ_ONLY && access != GL_WRITE_ONLY && access != GL_READ_WRITE)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidImageAccess);
+ return false;
+ }
+
+ switch (format)
+ {
+ case GL_RGBA32F:
+ case GL_RGBA16F:
+ case GL_R32F:
+ case GL_RGBA32UI:
+ case GL_RGBA16UI:
+ case GL_RGBA8UI:
+ case GL_R32UI:
+ case GL_RGBA32I:
+ case GL_RGBA16I:
+ case GL_RGBA8I:
+ case GL_R32I:
+ case GL_RGBA8:
+ case GL_RGBA8_SNORM:
+ break;
+ default:
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidImageFormat);
+ return false;
+ }
+
+ if (texture.value != 0)
+ {
+ Texture *tex = context->getTexture(texture);
+
+ if (tex == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kMissingTextureName);
+ return false;
+ }
+
+ if (!tex->getImmutableFormat() && tex->getType() != gl::TextureType::Buffer)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kTextureIsNeitherImmutableNorTextureBuffer);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateGetProgramResourceLocation(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLenum programInterface,
+ const GLchar *name)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ Program *programObject = GetValidProgram(context, entryPoint, program);
+ if (programObject == nullptr)
+ {
+ return false;
+ }
+
+ if (!programObject->isLinked())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotLinked);
+ return false;
+ }
+
+ if (!ValidateLocationProgramInterface(programInterface))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidProgramInterface);
+ return false;
+ }
+ return true;
+}
+
+bool ValidateGetProgramResourceiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLenum programInterface,
+ GLuint index,
+ GLsizei propCount,
+ const GLenum *props,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ Program *programObject = GetValidProgram(context, entryPoint, program);
+ if (programObject == nullptr)
+ {
+ return false;
+ }
+ if (!ValidateProgramInterface(programInterface))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidProgramInterface);
+ return false;
+ }
+ if (propCount <= 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidPropCount);
+ return false;
+ }
+ if (bufSize < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBufSize);
+ return false;
+ }
+ if (!ValidateProgramResourceIndex(programObject, programInterface, index))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidProgramResourceIndex);
+ return false;
+ }
+ for (GLsizei i = 0; i < propCount; i++)
+ {
+ if (!ValidateProgramResourceProperty(context, entryPoint, props[i]))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidProgramResourceProperty);
+ return false;
+ }
+ if (!ValidateProgramResourcePropertyByInterface(props[i], programInterface))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kInvalidPropertyForProgramInterface);
+ return false;
+ }
+ }
+ return true;
+}
+
+bool ValidateGetProgramInterfaceiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLenum programInterface,
+ GLenum pname,
+ const GLint *params)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ Program *programObject = GetValidProgram(context, entryPoint, program);
+ if (programObject == nullptr)
+ {
+ return false;
+ }
+
+ if (!ValidateProgramInterface(programInterface))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidProgramInterface);
+ return false;
+ }
+
+ switch (pname)
+ {
+ case GL_ACTIVE_RESOURCES:
+ case GL_MAX_NAME_LENGTH:
+ case GL_MAX_NUM_ACTIVE_VARIABLES:
+ break;
+
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname);
+ return false;
+ }
+
+ if (pname == GL_MAX_NAME_LENGTH && programInterface == GL_ATOMIC_COUNTER_BUFFER)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kAtomicCounterResourceName);
+ return false;
+ }
+
+ if (pname == GL_MAX_NUM_ACTIVE_VARIABLES)
+ {
+ switch (programInterface)
+ {
+ case GL_ATOMIC_COUNTER_BUFFER:
+ case GL_SHADER_STORAGE_BLOCK:
+ case GL_UNIFORM_BLOCK:
+ break;
+
+ default:
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kMaxActiveVariablesInterface);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateGetProgramInterfaceivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLenum programInterface,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params)
+{
+ UNIMPLEMENTED();
+ return false;
+}
+
+bool ValidateGenProgramPipelinesBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const ProgramPipelineID *pipelines)
+{
+ return ValidateGenOrDelete(context, entryPoint, n);
+}
+
+bool ValidateDeleteProgramPipelinesBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const ProgramPipelineID *pipelines)
+{
+ return ValidateGenOrDelete(context, entryPoint, n);
+}
+
+bool ValidateBindProgramPipelineBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProgramPipelineID pipeline)
+{
+ if (!context->isProgramPipelineGenerated({pipeline}))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kObjectNotGenerated);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateIsProgramPipelineBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProgramPipelineID pipeline)
+{
+ return true;
+}
+
+bool ValidateUseProgramStagesBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProgramPipelineID pipeline,
+ GLbitfield stages,
+ ShaderProgramID programId)
+{
+ // GL_INVALID_VALUE is generated if shaders contains set bits that are not recognized, and is
+ // not the reserved value GL_ALL_SHADER_BITS.
+ GLbitfield knownShaderBits =
+ GL_VERTEX_SHADER_BIT | GL_FRAGMENT_SHADER_BIT | GL_COMPUTE_SHADER_BIT;
+
+ if (context->getClientVersion() >= ES_3_2 || context->getExtensions().geometryShaderAny())
+ {
+ knownShaderBits |= GL_GEOMETRY_SHADER_BIT;
+ }
+
+ if (context->getClientVersion() >= ES_3_2 || context->getExtensions().tessellationShaderEXT)
+ {
+ knownShaderBits |= GL_TESS_CONTROL_SHADER_BIT;
+ knownShaderBits |= GL_TESS_EVALUATION_SHADER_BIT;
+ }
+
+ if ((stages & ~knownShaderBits) && (stages != GL_ALL_SHADER_BITS))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kUnrecognizedShaderStageBit);
+ return false;
+ }
+
+ // GL_INVALID_OPERATION is generated if pipeline is not a name previously returned from a call
+ // to glGenProgramPipelines or if such a name has been deleted by a call to
+ // glDeleteProgramPipelines.
+ if (!context->isProgramPipelineGenerated({pipeline}))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kObjectNotGenerated);
+ return false;
+ }
+
+ // If program is zero, or refers to a program object with no valid shader executable for a given
+ // stage, it is as if the pipeline object has no programmable stage configured for the indicated
+ // shader stages.
+ if (programId.value == 0)
+ {
+ return true;
+ }
+
+ Program *program = context->getProgramNoResolveLink(programId);
+ if (!program)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kProgramDoesNotExist);
+ return false;
+ }
+
+ // GL_INVALID_OPERATION is generated if program refers to a program object that was not linked
+ // with its GL_PROGRAM_SEPARABLE status set.
+ // resolveLink() may not have been called if glCreateShaderProgramv() was not used and
+ // glDetachShader() was not called.
+ program->resolveLink(context);
+ if (!program->isSeparable())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotSeparable);
+ return false;
+ }
+
+ // GL_INVALID_OPERATION is generated if program refers to a program object that has not been
+ // successfully linked.
+ if (!program->isLinked())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotLinked);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateActiveShaderProgramBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProgramPipelineID pipeline,
+ ShaderProgramID programId)
+{
+ // An INVALID_OPERATION error is generated if pipeline is not a name returned from a previous
+ // call to GenProgramPipelines or if such a name has since been deleted by
+ // DeleteProgramPipelines.
+ if (!context->isProgramPipelineGenerated({pipeline}))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kObjectNotGenerated);
+ return false;
+ }
+
+ // An INVALID_VALUE error is generated if program is not zero and is not the name of either a
+ // program or shader object.
+ if ((programId.value != 0) && !context->isProgram(programId) && !context->isShader(programId))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kProgramDoesNotExist);
+ return false;
+ }
+
+ // An INVALID_OPERATION error is generated if program is the name of a shader object.
+ if (context->isShader(programId))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExpectedProgramName);
+ return false;
+ }
+
+ // An INVALID_OPERATION error is generated if program is not zero and has not been linked, or
+ // was last linked unsuccessfully. The active program is not modified.
+ Program *program = context->getProgramNoResolveLink(programId);
+ if ((programId.value != 0) && !program->isLinked())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotLinked);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateCreateShaderProgramvBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderType type,
+ GLsizei count,
+ const GLchar *const *strings)
+{
+ switch (type)
+ {
+ case ShaderType::InvalidEnum:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidShaderType);
+ return false;
+ case ShaderType::Vertex:
+ case ShaderType::Fragment:
+ case ShaderType::Compute:
+ break;
+ case ShaderType::Geometry:
+ if (!context->getExtensions().geometryShaderAny() &&
+ context->getClientVersion() < ES_3_2)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidShaderType);
+ return false;
+ }
+ break;
+ case ShaderType::TessControl:
+ case ShaderType::TessEvaluation:
+ if (!context->getExtensions().tessellationShaderEXT &&
+ context->getClientVersion() < ES_3_2)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidShaderType);
+ return false;
+ }
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ // GL_INVALID_VALUE is generated if count is negative.
+ if (count < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeCount);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateCreateShaderProgramvBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderType type,
+ GLsizei count,
+ const GLchar **strings)
+{
+ const GLchar *const *tmpStrings = strings;
+ return ValidateCreateShaderProgramvBase(context, entryPoint, type, count, tmpStrings);
+}
+
+bool ValidateGetProgramPipelineivBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProgramPipelineID pipeline,
+ GLenum pname,
+ const GLint *params)
+{
+ // An INVALID_OPERATION error is generated if pipeline is not a name returned from a previous
+ // call to GenProgramPipelines or if such a name has since been deleted by
+ // DeleteProgramPipelines.
+ if ((pipeline.value == 0) || (!context->isProgramPipelineGenerated(pipeline)))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramPipelineDoesNotExist);
+ return false;
+ }
+
+ // An INVALID_ENUM error is generated if pname is not ACTIVE_PROGRAM,
+ // INFO_LOG_LENGTH, VALIDATE_STATUS, or one of the type arguments in
+ // table 7.1.
+ switch (pname)
+ {
+ case GL_ACTIVE_PROGRAM:
+ case GL_INFO_LOG_LENGTH:
+ case GL_VALIDATE_STATUS:
+ case GL_VERTEX_SHADER:
+ case GL_FRAGMENT_SHADER:
+ case GL_COMPUTE_SHADER:
+ break;
+ case GL_GEOMETRY_SHADER:
+ return context->getExtensions().geometryShaderAny() ||
+ context->getClientVersion() >= ES_3_2;
+ case GL_TESS_CONTROL_SHADER:
+ case GL_TESS_EVALUATION_SHADER:
+ return context->getExtensions().tessellationShaderEXT ||
+ context->getClientVersion() >= ES_3_2;
+
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateValidateProgramPipelineBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProgramPipelineID pipeline)
+{
+ if (pipeline.value == 0)
+ {
+ return false;
+ }
+
+ if (!context->isProgramPipelineGenerated(pipeline))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramPipelineDoesNotExist);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetProgramPipelineInfoLogBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProgramPipelineID pipeline,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLchar *infoLog)
+{
+ if (bufSize < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBufferSize);
+ return false;
+ }
+
+ if (!context->isProgramPipelineGenerated(pipeline))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kProgramPipelineDoesNotExist);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateActiveShaderProgram(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProgramPipelineID pipelinePacked,
+ ShaderProgramID programPacked)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateActiveShaderProgramBase(context, entryPoint, pipelinePacked, programPacked);
+}
+
+bool ValidateBindProgramPipeline(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProgramPipelineID pipelinePacked)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateBindProgramPipelineBase(context, entryPoint, pipelinePacked);
+}
+
+bool ValidateCreateShaderProgramv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderType typePacked,
+ GLsizei count,
+ const GLchar *const *strings)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateCreateShaderProgramvBase(context, entryPoint, typePacked, count, strings);
+}
+
+bool ValidateDeleteProgramPipelines(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const ProgramPipelineID *pipelinesPacked)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateDeleteProgramPipelinesBase(context, entryPoint, n, pipelinesPacked);
+}
+
+bool ValidateGenProgramPipelines(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const ProgramPipelineID *pipelinesPacked)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateGenProgramPipelinesBase(context, entryPoint, n, pipelinesPacked);
+}
+
+bool ValidateGetProgramPipelineInfoLog(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProgramPipelineID pipelinePacked,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLchar *infoLog)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateGetProgramPipelineInfoLogBase(context, entryPoint, pipelinePacked, bufSize,
+ length, infoLog);
+}
+
+bool ValidateGetProgramPipelineiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProgramPipelineID pipelinePacked,
+ GLenum pname,
+ const GLint *params)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateGetProgramPipelineivBase(context, entryPoint, pipelinePacked, pname, params);
+}
+
+bool ValidateIsProgramPipeline(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProgramPipelineID pipelinePacked)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateIsProgramPipelineBase(context, entryPoint, pipelinePacked);
+}
+
+bool ValidateProgramUniform1f(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLfloat v0)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateProgramUniform1fBase(context, entryPoint, programPacked, locationPacked, v0);
+}
+
+bool ValidateProgramUniform1fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateProgramUniform1fvBase(context, entryPoint, programPacked, locationPacked, count,
+ value);
+}
+
+bool ValidateProgramUniform1i(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLint v0)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateProgramUniform1iBase(context, entryPoint, programPacked, locationPacked, v0);
+}
+
+bool ValidateProgramUniform1iv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateProgramUniform1ivBase(context, entryPoint, programPacked, locationPacked, count,
+ value);
+}
+
+bool ValidateProgramUniform1ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLuint v0)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateProgramUniform1uiBase(context, entryPoint, programPacked, locationPacked, v0);
+}
+
+bool ValidateProgramUniform1uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateProgramUniform1uivBase(context, entryPoint, programPacked, locationPacked, count,
+ value);
+}
+
+bool ValidateProgramUniform2f(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLfloat v0,
+ GLfloat v1)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateProgramUniform2fBase(context, entryPoint, programPacked, locationPacked, v0, v1);
+}
+
+bool ValidateProgramUniform2fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateProgramUniform2fvBase(context, entryPoint, programPacked, locationPacked, count,
+ value);
+}
+
+bool ValidateProgramUniform2i(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLint v0,
+ GLint v1)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateProgramUniform2iBase(context, entryPoint, programPacked, locationPacked, v0, v1);
+}
+
+bool ValidateProgramUniform2iv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateProgramUniform2ivBase(context, entryPoint, programPacked, locationPacked, count,
+ value);
+}
+
+bool ValidateProgramUniform2ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLuint v0,
+ GLuint v1)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateProgramUniform2uiBase(context, entryPoint, programPacked, locationPacked, v0,
+ v1);
+}
+
+bool ValidateProgramUniform2uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateProgramUniform2uivBase(context, entryPoint, programPacked, locationPacked, count,
+ value);
+}
+
+bool ValidateProgramUniform3f(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLfloat v0,
+ GLfloat v1,
+ GLfloat v2)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateProgramUniform3fBase(context, entryPoint, programPacked, locationPacked, v0, v1,
+ v2);
+}
+
+bool ValidateProgramUniform3fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateProgramUniform3fvBase(context, entryPoint, programPacked, locationPacked, count,
+ value);
+}
+
+bool ValidateProgramUniform3i(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLint v0,
+ GLint v1,
+ GLint v2)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateProgramUniform3iBase(context, entryPoint, programPacked, locationPacked, v0, v1,
+ v2);
+}
+
+bool ValidateProgramUniform3iv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateProgramUniform3ivBase(context, entryPoint, programPacked, locationPacked, count,
+ value);
+}
+
+bool ValidateProgramUniform3ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLuint v0,
+ GLuint v1,
+ GLuint v2)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateProgramUniform3uiBase(context, entryPoint, programPacked, locationPacked, v0, v1,
+ v2);
+}
+
+bool ValidateProgramUniform3uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateProgramUniform3uivBase(context, entryPoint, programPacked, locationPacked, count,
+ value);
+}
+
+bool ValidateProgramUniform4f(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLfloat v0,
+ GLfloat v1,
+ GLfloat v2,
+ GLfloat v3)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateProgramUniform4fBase(context, entryPoint, programPacked, locationPacked, v0, v1,
+ v2, v3);
+}
+
+bool ValidateProgramUniform4fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateProgramUniform4fvBase(context, entryPoint, programPacked, locationPacked, count,
+ value);
+}
+
+bool ValidateProgramUniform4i(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLint v0,
+ GLint v1,
+ GLint v2,
+ GLint v3)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateProgramUniform4iBase(context, entryPoint, programPacked, locationPacked, v0, v1,
+ v2, v3);
+}
+
+bool ValidateProgramUniform4iv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateProgramUniform4ivBase(context, entryPoint, programPacked, locationPacked, count,
+ value);
+}
+
+bool ValidateProgramUniform4ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLuint v0,
+ GLuint v1,
+ GLuint v2,
+ GLuint v3)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateProgramUniform4uiBase(context, entryPoint, programPacked, locationPacked, v0, v1,
+ v2, v3);
+}
+
+bool ValidateProgramUniform4uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateProgramUniform4uivBase(context, entryPoint, programPacked, locationPacked, count,
+ value);
+}
+
+bool ValidateProgramUniformMatrix2fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateProgramUniformMatrix2fvBase(context, entryPoint, programPacked, locationPacked,
+ count, transpose, value);
+}
+
+bool ValidateProgramUniformMatrix2x3fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateProgramUniformMatrix2x3fvBase(context, entryPoint, programPacked, locationPacked,
+ count, transpose, value);
+}
+
+bool ValidateProgramUniformMatrix2x4fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateProgramUniformMatrix2x4fvBase(context, entryPoint, programPacked, locationPacked,
+ count, transpose, value);
+}
+
+bool ValidateProgramUniformMatrix3fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateProgramUniformMatrix3fvBase(context, entryPoint, programPacked, locationPacked,
+ count, transpose, value);
+}
+
+bool ValidateProgramUniformMatrix3x2fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateProgramUniformMatrix3x2fvBase(context, entryPoint, programPacked, locationPacked,
+ count, transpose, value);
+}
+
+bool ValidateProgramUniformMatrix3x4fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateProgramUniformMatrix3x4fvBase(context, entryPoint, programPacked, locationPacked,
+ count, transpose, value);
+}
+
+bool ValidateProgramUniformMatrix4fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateProgramUniformMatrix4fvBase(context, entryPoint, programPacked, locationPacked,
+ count, transpose, value);
+}
+
+bool ValidateProgramUniformMatrix4x2fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateProgramUniformMatrix4x2fvBase(context, entryPoint, programPacked, locationPacked,
+ count, transpose, value);
+}
+
+bool ValidateProgramUniformMatrix4x3fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateProgramUniformMatrix4x3fvBase(context, entryPoint, programPacked, locationPacked,
+ count, transpose, value);
+}
+
+bool ValidateUseProgramStages(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProgramPipelineID pipelinePacked,
+ GLbitfield stages,
+ ShaderProgramID programPacked)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateUseProgramStagesBase(context, entryPoint, pipelinePacked, stages, programPacked);
+}
+
+bool ValidateValidateProgramPipeline(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProgramPipelineID pipelinePacked)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateValidateProgramPipelineBase(context, entryPoint, pipelinePacked);
+}
+
+bool ValidateMemoryBarrier(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLbitfield barriers)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ if (barriers == GL_ALL_BARRIER_BITS)
+ {
+ return true;
+ }
+
+ GLbitfield supported_barrier_bits =
+ GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | GL_ELEMENT_ARRAY_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT |
+ GL_TEXTURE_FETCH_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT | GL_COMMAND_BARRIER_BIT |
+ GL_PIXEL_BUFFER_BARRIER_BIT | GL_TEXTURE_UPDATE_BARRIER_BIT | GL_BUFFER_UPDATE_BARRIER_BIT |
+ GL_FRAMEBUFFER_BARRIER_BIT | GL_TRANSFORM_FEEDBACK_BARRIER_BIT |
+ GL_ATOMIC_COUNTER_BARRIER_BIT | GL_SHADER_STORAGE_BARRIER_BIT;
+
+ if (context->getExtensions().bufferStorageEXT)
+ {
+ supported_barrier_bits |= GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT_EXT;
+ }
+
+ if (barriers == 0 || (barriers & ~supported_barrier_bits) != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMemoryBarrierBit);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateMemoryBarrierByRegion(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLbitfield barriers)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ if (barriers == GL_ALL_BARRIER_BITS)
+ {
+ return true;
+ }
+
+ GLbitfield supported_barrier_bits = GL_ATOMIC_COUNTER_BARRIER_BIT | GL_FRAMEBUFFER_BARRIER_BIT |
+ GL_SHADER_IMAGE_ACCESS_BARRIER_BIT |
+ GL_SHADER_STORAGE_BARRIER_BIT |
+ GL_TEXTURE_FETCH_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT;
+ if (barriers == 0 || (barriers & ~supported_barrier_bits) != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMemoryBarrierBit);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateSampleMaski(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint maskNumber,
+ GLbitfield mask)
+{
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+
+ return ValidateSampleMaskiBase(context, entryPoint, maskNumber, mask);
+}
+
+bool ValidateMinSampleShadingOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat value)
+{
+ if (!context->getExtensions().sampleShadingOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateFramebufferTextureCommon(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ TextureID texture,
+ GLint level)
+{
+ if (texture.value != 0)
+ {
+ Texture *tex = context->getTexture(texture);
+
+ // [EXT_geometry_shader] Section 9.2.8 "Attaching Texture Images to a Framebuffer"
+ // An INVALID_VALUE error is generated if <texture> is not the name of a texture object.
+ // We put this validation before ValidateFramebufferTextureBase because it is an
+ // INVALID_OPERATION error for both FramebufferTexture2D and FramebufferTextureLayer:
+ // [OpenGL ES 3.1] Chapter 9.2.8 (FramebufferTexture2D)
+ // An INVALID_OPERATION error is generated if texture is not zero, and does not name an
+ // existing texture object of type matching textarget.
+ // [OpenGL ES 3.1 Chapter 9.2.8 (FramebufferTextureLayer)
+ // An INVALID_OPERATION error is generated if texture is non-zero and is not the name of a
+ // three-dimensional or two-dimensional array texture.
+ if (tex == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidTextureName);
+ return false;
+ }
+
+ if (!ValidMipLevel(context, tex->getType(), level))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel);
+ return false;
+ }
+
+ // GLES spec 3.1, Section 9.2.8 "Attaching Texture Images to a Framebuffer"
+ // If textarget is TEXTURE_2D_MULTISAMPLE, then level must be zero.
+ if (tex->getType() == TextureType::_2DMultisample && level != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kLevelNotZero);
+ return false;
+ }
+
+ // [OES_texture_storage_multisample_2d_array] Section 9.2.2 "Attaching Images to Framebuffer
+ // Objects"
+ // If texture is a two-dimensional multisample array texture, then level must be zero.
+ if (context->getExtensions().textureStorageMultisample2dArrayOES &&
+ tex->getType() == TextureType::_2DMultisampleArray && level != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kLevelNotZero);
+ return false;
+ }
+ }
+
+ if (!ValidateFramebufferTextureBase(context, entryPoint, target, attachment, texture, level))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateFramebufferTextureEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ TextureID texture,
+ GLint level)
+{
+ if (!context->getExtensions().geometryShaderEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kGeometryShaderExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateFramebufferTextureCommon(context, entryPoint, target, attachment, texture,
+ level);
+}
+
+bool ValidateFramebufferTextureOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ TextureID texture,
+ GLint level)
+{
+ if (!context->getExtensions().geometryShaderOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kGeometryShaderExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateFramebufferTextureCommon(context, entryPoint, target, attachment, texture,
+ level);
+}
+
+// GL_OES_texture_storage_multisample_2d_array
+bool ValidateTexStorage3DMultisampleOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLsizei samples,
+ GLenum sizedinternalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean fixedsamplelocations)
+{
+ if (!context->getExtensions().textureStorageMultisample2dArrayOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kMultisampleArrayExtensionRequired);
+ return false;
+ }
+
+ if (target != TextureType::_2DMultisampleArray)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM,
+ kTargetMustBeTexture2DMultisampleArrayOES);
+ return false;
+ }
+
+ if (width < 1 || height < 1 || depth < 1)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeSize);
+ return false;
+ }
+
+ if (depth > context->getCaps().maxArrayTextureLayers)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kTextureDepthOutOfRange);
+ return false;
+ }
+
+ return ValidateTexStorageMultisample(context, entryPoint, target, samples, sizedinternalformat,
+ width, height);
+}
+
+bool ValidateTexStorageMem3DMultisampleEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean fixedSampleLocations,
+ MemoryObjectID memory,
+ GLuint64 offset)
+{
+ if (!context->getExtensions().memoryObjectEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ UNIMPLEMENTED();
+ return false;
+}
+
+bool ValidateGetProgramResourceLocationIndexEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLenum programInterface,
+ const char *name)
+{
+ if (!context->getExtensions().blendFuncExtendedEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+ if (context->getClientVersion() < ES_3_1)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
+ return false;
+ }
+ if (programInterface != GL_PROGRAM_OUTPUT)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kProgramInterfaceMustBeProgramOutput);
+ return false;
+ }
+ Program *programObject = GetValidProgram(context, entryPoint, program);
+ if (!programObject)
+ {
+ return false;
+ }
+ if (!programObject->isLinked())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotLinked);
+ return false;
+ }
+ return true;
+}
+
+// GL_OES_texture_buffer
+bool ValidateTexBufferOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLenum internalformat,
+ BufferID bufferPacked)
+{
+ if (!context->getExtensions().textureBufferOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kTextureBufferExtensionNotAvailable);
+ return false;
+ }
+
+ return ValidateTexBufferBase(context, entryPoint, target, internalformat, bufferPacked);
+}
+
+bool ValidateTexBufferRangeOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLenum internalformat,
+ BufferID bufferPacked,
+ GLintptr offset,
+ GLsizeiptr size)
+{
+ if (!context->getExtensions().textureBufferOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kTextureBufferExtensionNotAvailable);
+ return false;
+ }
+
+ return ValidateTexBufferRangeBase(context, entryPoint, target, internalformat, bufferPacked,
+ offset, size);
+}
+
+// GL_EXT_texture_buffer
+bool ValidateTexBufferEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLenum internalformat,
+ BufferID bufferPacked)
+{
+ if (!context->getExtensions().textureBufferEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kTextureBufferExtensionNotAvailable);
+ return false;
+ }
+
+ return ValidateTexBufferBase(context, entryPoint, target, internalformat, bufferPacked);
+}
+
+bool ValidateTexBufferRangeEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLenum internalformat,
+ BufferID bufferPacked,
+ GLintptr offset,
+ GLsizeiptr size)
+{
+ if (!context->getExtensions().textureBufferEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kTextureBufferExtensionNotAvailable);
+ return false;
+ }
+
+ return ValidateTexBufferRangeBase(context, entryPoint, target, internalformat, bufferPacked,
+ offset, size);
+}
+
+bool ValidateTexBufferBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLenum internalformat,
+ BufferID bufferPacked)
+{
+ if (target != TextureType::Buffer)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kTextureBufferTarget);
+ return false;
+ }
+
+ switch (internalformat)
+ {
+ case GL_R8:
+ case GL_R16F:
+ case GL_R32F:
+ case GL_R8I:
+ case GL_R16I:
+ case GL_R32I:
+ case GL_R8UI:
+ case GL_R16UI:
+ case GL_R32UI:
+ case GL_RG8:
+ case GL_RG16F:
+ case GL_RG32F:
+ case GL_RG8I:
+ case GL_RG16I:
+ case GL_RG32I:
+ case GL_RG8UI:
+ case GL_RG16UI:
+ case GL_RG32UI:
+ case GL_RGB32F:
+ case GL_RGB32I:
+ case GL_RGB32UI:
+ case GL_RGBA8:
+ case GL_RGBA16F:
+ case GL_RGBA32F:
+ case GL_RGBA8I:
+ case GL_RGBA16I:
+ case GL_RGBA32I:
+ case GL_RGBA8UI:
+ case GL_RGBA16UI:
+ case GL_RGBA32UI:
+ break;
+
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kTextureBufferInternalFormat);
+ return false;
+ }
+
+ if (bufferPacked.value != 0)
+ {
+ if (!context->isBufferGenerated(bufferPacked))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kTextureBufferInvalidBuffer);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateTexBufferRangeBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLenum internalformat,
+ BufferID bufferPacked,
+ GLintptr offset,
+ GLsizeiptr size)
+{
+ const Caps &caps = context->getCaps();
+
+ if (offset < 0 || (offset % caps.textureBufferOffsetAlignment) != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kTextureBufferOffsetAlignment);
+ return false;
+ }
+ if (size <= 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kTextureBufferSize);
+ return false;
+ }
+ const Buffer *buffer = context->getBuffer(bufferPacked);
+
+ if (!buffer)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferNotBound);
+ return false;
+ }
+
+ if (offset + size > buffer->getSize())
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kTextureBufferSizeOffset);
+ return false;
+ }
+
+ return ValidateTexBufferBase(context, entryPoint, target, internalformat, bufferPacked);
+}
+
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/validationES31.h b/gfx/angle/checkout/src/libANGLE/validationES31.h
new file mode 100644
index 0000000000..c41cedf0da
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/validationES31.h
@@ -0,0 +1,300 @@
+//
+// Copyright 2018 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:
+// Inlined validation functions for OpenGL ES 3.1 entry points.
+
+#ifndef LIBANGLE_VALIDATION_ES31_H_
+#define LIBANGLE_VALIDATION_ES31_H_
+
+#include "libANGLE/ErrorStrings.h"
+#include "libANGLE/validationES31_autogen.h"
+
+namespace gl
+{
+
+bool ValidateTexBufferBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLenum internalformat,
+ BufferID bufferPacked);
+bool ValidateTexBufferRangeBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLenum internalformat,
+ BufferID bufferPacked,
+ GLintptr offset,
+ GLsizeiptr size);
+
+// GL_EXT_multi_draw_indirect
+bool ValidateMultiDrawIndirectBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei drawcount,
+ GLsizei stride);
+
+// GL_EXT_separate_shader_objects
+bool ValidateActiveShaderProgramBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProgramPipelineID pipelinePacked,
+ ShaderProgramID programPacked);
+bool ValidateBindProgramPipelineBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProgramPipelineID pipelinePacked);
+bool ValidateCreateShaderProgramvBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderType typePacked,
+ GLsizei count,
+ const GLchar **strings);
+bool ValidateDeleteProgramPipelinesBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const ProgramPipelineID *pipelinesPacked);
+bool ValidateGenProgramPipelinesBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const ProgramPipelineID *pipelinesPacked);
+bool ValidateGetProgramPipelineInfoLogBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProgramPipelineID pipelinePacked,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLchar *infoLog);
+bool ValidateGetProgramPipelineivBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProgramPipelineID pipelinePacked,
+ GLenum pname,
+ const GLint *params);
+bool ValidateIsProgramPipelineBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProgramPipelineID pipelinePacked);
+bool ValidateProgramParameteriBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ GLenum pname,
+ GLint value);
+bool ValidateProgramUniform1fBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLfloat v0);
+bool ValidateProgramUniform1fvBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value);
+bool ValidateProgramUniform1iBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLint v0);
+bool ValidateProgramUniform1ivBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value);
+bool ValidateProgramUniform1uiBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLuint v0);
+bool ValidateProgramUniform1uivBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value);
+bool ValidateProgramUniform2fBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLfloat v0,
+ GLfloat v1);
+bool ValidateProgramUniform2fvBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value);
+bool ValidateProgramUniform2iBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLint v0,
+ GLint v1);
+bool ValidateProgramUniform2ivBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value);
+bool ValidateProgramUniform2uiBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLuint v0,
+ GLuint v1);
+bool ValidateProgramUniform2uivBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value);
+bool ValidateProgramUniform3fBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLfloat v0,
+ GLfloat v1,
+ GLfloat v2);
+bool ValidateProgramUniform3fvBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value);
+bool ValidateProgramUniform3iBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLint v0,
+ GLint v1,
+ GLint v2);
+bool ValidateProgramUniform3ivBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value);
+bool ValidateProgramUniform3uiBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLuint v0,
+ GLuint v1,
+ GLuint v2);
+bool ValidateProgramUniform3uivBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value);
+bool ValidateProgramUniform4fBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLfloat v0,
+ GLfloat v1,
+ GLfloat v2,
+ GLfloat v3);
+bool ValidateProgramUniform4fvBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value);
+bool ValidateProgramUniform4iBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLint v0,
+ GLint v1,
+ GLint v2,
+ GLint v3);
+bool ValidateProgramUniform4ivBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value);
+bool ValidateProgramUniform4uiBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLuint v0,
+ GLuint v1,
+ GLuint v2,
+ GLuint v3);
+bool ValidateProgramUniform4uivBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value);
+bool ValidateProgramUniformMatrix2fvBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+bool ValidateProgramUniformMatrix2x3fvBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+bool ValidateProgramUniformMatrix2x4fvBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+bool ValidateProgramUniformMatrix3fvBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+bool ValidateProgramUniformMatrix3x2fvBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+bool ValidateProgramUniformMatrix3x4fvBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+bool ValidateProgramUniformMatrix4fvBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+bool ValidateProgramUniformMatrix4x2fvBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+bool ValidateProgramUniformMatrix4x3fvBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+bool ValidateUseProgramStagesBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProgramPipelineID pipelinePacked,
+ GLbitfield stages,
+ ShaderProgramID programPacked);
+bool ValidateValidateProgramPipelineBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProgramPipelineID pipelinePacked);
+} // namespace gl
+
+#endif // LIBANGLE_VALIDATION_ES31_H_
diff --git a/gfx/angle/checkout/src/libANGLE/validationES31_autogen.h b/gfx/angle/checkout/src/libANGLE/validationES31_autogen.h
new file mode 100644
index 0000000000..3e2adb50d0
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/validationES31_autogen.h
@@ -0,0 +1,415 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml and gl_angle_ext.xml.
+//
+// Copyright 2020 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_autogen.h:
+// Validation functions for the OpenGL ES 3.1 entry points.
+
+#ifndef LIBANGLE_VALIDATION_ES31_AUTOGEN_H_
+#define LIBANGLE_VALIDATION_ES31_AUTOGEN_H_
+
+#include "common/PackedEnums.h"
+#include "common/entry_points_enum_autogen.h"
+
+namespace gl
+{
+class Context;
+
+bool ValidateActiveShaderProgram(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProgramPipelineID pipelinePacked,
+ ShaderProgramID programPacked);
+bool ValidateBindImageTexture(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint unit,
+ TextureID texturePacked,
+ GLint level,
+ GLboolean layered,
+ GLint layer,
+ GLenum access,
+ GLenum format);
+bool ValidateBindProgramPipeline(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProgramPipelineID pipelinePacked);
+bool ValidateBindVertexBuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint bindingindex,
+ BufferID bufferPacked,
+ GLintptr offset,
+ GLsizei stride);
+bool ValidateCreateShaderProgramv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderType typePacked,
+ GLsizei count,
+ const GLchar *const *strings);
+bool ValidateDeleteProgramPipelines(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const ProgramPipelineID *pipelinesPacked);
+bool ValidateDispatchCompute(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint num_groups_x,
+ GLuint num_groups_y,
+ GLuint num_groups_z);
+bool ValidateDispatchComputeIndirect(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLintptr indirect);
+bool ValidateDrawArraysIndirect(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ const void *indirect);
+bool ValidateDrawElementsIndirect(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ DrawElementsType typePacked,
+ const void *indirect);
+bool ValidateFramebufferParameteri(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum pname,
+ GLint param);
+bool ValidateGenProgramPipelines(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const ProgramPipelineID *pipelinesPacked);
+bool ValidateGetBooleani_v(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint index,
+ const GLboolean *data);
+bool ValidateGetFramebufferParameteriv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum pname,
+ const GLint *params);
+bool ValidateGetMultisamplefv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLuint index,
+ const GLfloat *val);
+bool ValidateGetProgramInterfaceiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ GLenum programInterface,
+ GLenum pname,
+ const GLint *params);
+bool ValidateGetProgramPipelineInfoLog(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProgramPipelineID pipelinePacked,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLchar *infoLog);
+bool ValidateGetProgramPipelineiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProgramPipelineID pipelinePacked,
+ GLenum pname,
+ const GLint *params);
+bool ValidateGetProgramResourceIndex(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ GLenum programInterface,
+ const GLchar *name);
+bool ValidateGetProgramResourceLocation(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ GLenum programInterface,
+ const GLchar *name);
+bool ValidateGetProgramResourceName(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ GLenum programInterface,
+ GLuint index,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLchar *name);
+bool ValidateGetProgramResourceiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ GLenum programInterface,
+ GLuint index,
+ GLsizei propCount,
+ const GLenum *props,
+ GLsizei count,
+ const GLsizei *length,
+ const GLint *params);
+bool ValidateGetTexLevelParameterfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum pname,
+ const GLfloat *params);
+bool ValidateGetTexLevelParameteriv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum pname,
+ const GLint *params);
+bool ValidateIsProgramPipeline(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProgramPipelineID pipelinePacked);
+bool ValidateMemoryBarrier(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLbitfield barriers);
+bool ValidateMemoryBarrierByRegion(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLbitfield barriers);
+bool ValidateProgramUniform1f(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLfloat v0);
+bool ValidateProgramUniform1fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value);
+bool ValidateProgramUniform1i(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLint v0);
+bool ValidateProgramUniform1iv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value);
+bool ValidateProgramUniform1ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLuint v0);
+bool ValidateProgramUniform1uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value);
+bool ValidateProgramUniform2f(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLfloat v0,
+ GLfloat v1);
+bool ValidateProgramUniform2fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value);
+bool ValidateProgramUniform2i(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLint v0,
+ GLint v1);
+bool ValidateProgramUniform2iv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value);
+bool ValidateProgramUniform2ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLuint v0,
+ GLuint v1);
+bool ValidateProgramUniform2uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value);
+bool ValidateProgramUniform3f(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLfloat v0,
+ GLfloat v1,
+ GLfloat v2);
+bool ValidateProgramUniform3fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value);
+bool ValidateProgramUniform3i(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLint v0,
+ GLint v1,
+ GLint v2);
+bool ValidateProgramUniform3iv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value);
+bool ValidateProgramUniform3ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLuint v0,
+ GLuint v1,
+ GLuint v2);
+bool ValidateProgramUniform3uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value);
+bool ValidateProgramUniform4f(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLfloat v0,
+ GLfloat v1,
+ GLfloat v2,
+ GLfloat v3);
+bool ValidateProgramUniform4fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value);
+bool ValidateProgramUniform4i(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLint v0,
+ GLint v1,
+ GLint v2,
+ GLint v3);
+bool ValidateProgramUniform4iv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value);
+bool ValidateProgramUniform4ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLuint v0,
+ GLuint v1,
+ GLuint v2,
+ GLuint v3);
+bool ValidateProgramUniform4uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value);
+bool ValidateProgramUniformMatrix2fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+bool ValidateProgramUniformMatrix2x3fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+bool ValidateProgramUniformMatrix2x4fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+bool ValidateProgramUniformMatrix3fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+bool ValidateProgramUniformMatrix3x2fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+bool ValidateProgramUniformMatrix3x4fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+bool ValidateProgramUniformMatrix4fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+bool ValidateProgramUniformMatrix4x2fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+bool ValidateProgramUniformMatrix4x3fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+bool ValidateSampleMaski(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint maskNumber,
+ GLbitfield mask);
+bool ValidateTexStorage2DMultisample(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedsamplelocations);
+bool ValidateUseProgramStages(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProgramPipelineID pipelinePacked,
+ GLbitfield stages,
+ ShaderProgramID programPacked);
+bool ValidateValidateProgramPipeline(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProgramPipelineID pipelinePacked);
+bool ValidateVertexAttribBinding(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint attribindex,
+ GLuint bindingindex);
+bool ValidateVertexAttribFormat(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint attribindex,
+ GLint size,
+ VertexAttribType typePacked,
+ GLboolean normalized,
+ GLuint relativeoffset);
+bool ValidateVertexAttribIFormat(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint attribindex,
+ GLint size,
+ VertexAttribType typePacked,
+ GLuint relativeoffset);
+bool ValidateVertexBindingDivisor(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint bindingindex,
+ GLuint divisor);
+} // namespace gl
+
+#endif // LIBANGLE_VALIDATION_ES31_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libANGLE/validationES32.cpp b/gfx/angle/checkout/src/libANGLE/validationES32.cpp
new file mode 100644
index 0000000000..b7d412393b
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/validationES32.cpp
@@ -0,0 +1,628 @@
+//
+// Copyright 2019 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.
+//
+
+// validationES32.cpp: Validation functions for OpenGL ES 3.2 entry point parameters
+
+#include "libANGLE/validationES32_autogen.h"
+
+#include "libANGLE/Context.h"
+#include "libANGLE/ErrorStrings.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/VertexArray.h"
+#include "libANGLE/validationES.h"
+#include "libANGLE/validationES2_autogen.h"
+#include "libANGLE/validationES31.h"
+#include "libANGLE/validationES31_autogen.h"
+#include "libANGLE/validationES3_autogen.h"
+
+#include "common/utilities.h"
+
+using namespace angle;
+
+namespace gl
+{
+using namespace err;
+
+bool ValidateBlendBarrier(const Context *context, angle::EntryPoint entryPoint)
+{
+ return true;
+}
+
+bool ValidateBlendEquationSeparatei(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint buf,
+ GLenum modeRGB,
+ GLenum modeAlpha)
+{
+ if (buf >= static_cast<GLuint>(context->getCaps().maxDrawBuffers))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsMaxDrawBuffers);
+ return false;
+ }
+
+ if (!ValidateBlendEquationSeparate(context, entryPoint, modeRGB, modeAlpha))
+ {
+ // error already generated
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateBlendEquationi(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint buf,
+ GLenum mode)
+{
+ if (buf >= static_cast<GLuint>(context->getCaps().maxDrawBuffers))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsMaxDrawBuffers);
+ return false;
+ }
+
+ if (!ValidateBlendEquation(context, entryPoint, mode))
+ {
+ // error already generated
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateBlendFuncSeparatei(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint buf,
+ GLenum srcRGB,
+ GLenum dstRGB,
+ GLenum srcAlpha,
+ GLenum dstAlpha)
+{
+ if (buf >= static_cast<GLuint>(context->getCaps().maxDrawBuffers))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsMaxDrawBuffers);
+ return false;
+ }
+
+ if (!ValidateBlendFuncSeparate(context, entryPoint, srcRGB, dstRGB, srcAlpha, dstAlpha))
+ {
+ // error already generated
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateBlendFunci(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint buf,
+ GLenum src,
+ GLenum dst)
+{
+ if (buf >= static_cast<GLuint>(context->getCaps().maxDrawBuffers))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsMaxDrawBuffers);
+ return false;
+ }
+
+ if (!ValidateBlendFunc(context, entryPoint, src, dst))
+ {
+ // error already generated
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateColorMaski(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLboolean r,
+ GLboolean g,
+ GLboolean b,
+ GLboolean a)
+{
+ if (index >= static_cast<GLuint>(context->getCaps().maxDrawBuffers))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxDrawBuffer);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateCopyImageSubData(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint srcName,
+ GLenum srcTarget,
+ GLint srcLevel,
+ GLint srcX,
+ GLint srcY,
+ GLint srcZ,
+ GLuint dstName,
+ GLenum dstTarget,
+ GLint dstLevel,
+ GLint dstX,
+ GLint dstY,
+ GLint dstZ,
+ GLsizei srcWidth,
+ GLsizei srcHeight,
+ GLsizei srcDepth)
+{
+ if (context->getClientVersion() < ES_3_2)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES32Required);
+ return false;
+ }
+
+ return ValidateCopyImageSubDataBase(context, entryPoint, srcName, srcTarget, srcLevel, srcX,
+ srcY, srcZ, dstName, dstTarget, dstLevel, dstX, dstY, dstZ,
+ srcWidth, srcHeight, srcDepth);
+}
+
+bool ValidateDebugMessageCallback(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLDEBUGPROC callback,
+ const void *userParam)
+{
+ return true;
+}
+
+bool ValidateDebugMessageControl(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum source,
+ GLenum type,
+ GLenum severity,
+ GLsizei count,
+ const GLuint *ids,
+ GLboolean enabled)
+{
+ return true;
+}
+
+bool ValidateDebugMessageInsert(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum source,
+ GLenum type,
+ GLuint id,
+ GLenum severity,
+ GLsizei length,
+ const GLchar *buf)
+{
+ return true;
+}
+
+bool ValidateDisablei(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint index)
+{
+ switch (target)
+ {
+ case GL_BLEND:
+ if (index >= static_cast<GLuint>(context->getCaps().maxDrawBuffers))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxDrawBuffer);
+ return false;
+ }
+ break;
+ default:
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, target);
+ return false;
+ }
+ return true;
+}
+
+bool ValidateDrawElementsBaseVertex(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLsizei count,
+ DrawElementsType type,
+ const void *indices,
+ GLint basevertex)
+{
+ return ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices, 1);
+}
+
+bool ValidateDrawElementsInstancedBaseVertex(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLsizei count,
+ DrawElementsType type,
+ const void *indices,
+ GLsizei instancecount,
+ GLint basevertex)
+{
+ return ValidateDrawElementsInstancedBase(context, entryPoint, mode, count, type, indices,
+ instancecount);
+}
+
+bool ValidateDrawRangeElementsBaseVertex(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ DrawElementsType type,
+ const void *indices,
+ GLint basevertex)
+{
+ if (end < start)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidElementRange);
+ return false;
+ }
+
+ if (!ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices, 0))
+ {
+ return false;
+ }
+
+ // Skip range checks for no-op calls.
+ if (count <= 0)
+ {
+ return true;
+ }
+
+ return true;
+}
+
+bool ValidateEnablei(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint index)
+{
+ switch (target)
+ {
+ case GL_BLEND:
+ if (index >= static_cast<GLuint>(context->getCaps().maxDrawBuffers))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxDrawBuffer);
+ return false;
+ }
+ break;
+ default:
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, target);
+ return false;
+ }
+ return true;
+}
+
+bool ValidateFramebufferTexture(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ TextureID texture,
+ GLint level)
+{
+ return true;
+}
+
+bool ValidateGetDebugMessageLog(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint count,
+ GLsizei bufSize,
+ const GLenum *sources,
+ const GLenum *types,
+ const GLuint *ids,
+ const GLenum *severities,
+ const GLsizei *lengths,
+ const GLchar *messageLog)
+{
+ return true;
+}
+
+bool ValidateGetGraphicsResetStatus(const Context *context, angle::EntryPoint entryPoint)
+{
+ return true;
+}
+
+bool ValidateGetObjectLabel(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum identifier,
+ GLuint name,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLchar *label)
+{
+ return true;
+}
+
+bool ValidateGetObjectPtrLabel(const Context *context,
+ angle::EntryPoint entryPoint,
+ const void *ptr,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLchar *label)
+{
+ return true;
+}
+
+bool ValidateGetPointerv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ void *const *params)
+{
+ Version clientVersion = context->getClientVersion();
+
+ if ((clientVersion == ES_1_0) || (clientVersion == ES_1_1))
+ {
+ switch (pname)
+ {
+ case GL_VERTEX_ARRAY_POINTER:
+ case GL_NORMAL_ARRAY_POINTER:
+ case GL_COLOR_ARRAY_POINTER:
+ case GL_TEXTURE_COORD_ARRAY_POINTER:
+ case GL_POINT_SIZE_ARRAY_POINTER_OES:
+ return true;
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPointerQuery);
+ return false;
+ }
+ }
+ else if (clientVersion == ES_3_2)
+ {
+ switch (pname)
+ {
+ case GL_DEBUG_CALLBACK_FUNCTION:
+ case GL_DEBUG_CALLBACK_USER_PARAM:
+ return true;
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPointerQuery);
+ return false;
+ }
+ }
+ else
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES1or32Required);
+ return false;
+ }
+}
+
+bool ValidateGetSamplerParameterIiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID sampler,
+ GLenum pname,
+ const GLint *params)
+{
+ return true;
+}
+
+bool ValidateGetSamplerParameterIuiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID sampler,
+ GLenum pname,
+ const GLuint *params)
+{
+ return true;
+}
+
+bool ValidateGetTexParameterIiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLint *params)
+{
+ return true;
+}
+
+bool ValidateGetTexParameterIuiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLuint *params)
+{
+ return true;
+}
+
+bool ValidateGetnUniformfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei bufSize,
+ const GLfloat *params)
+{
+ return ValidateSizedGetUniform(context, entryPoint, program, location, bufSize, nullptr);
+}
+
+bool ValidateGetnUniformiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei bufSize,
+ const GLint *params)
+{
+ return ValidateSizedGetUniform(context, entryPoint, program, location, bufSize, nullptr);
+}
+
+bool ValidateGetnUniformuiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei bufSize,
+ const GLuint *params)
+{
+ return ValidateSizedGetUniform(context, entryPoint, program, location, bufSize, nullptr);
+}
+
+bool ValidateIsEnabledi(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint index)
+{
+ switch (target)
+ {
+ case GL_BLEND:
+ if (index >= static_cast<GLuint>(context->getCaps().maxDrawBuffers))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxDrawBuffer);
+ return false;
+ }
+ break;
+ default:
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, target);
+ return false;
+ }
+ return true;
+}
+
+bool ValidateMinSampleShading(const Context *context, angle::EntryPoint entryPoint, GLfloat value)
+{
+ return true;
+}
+
+bool ValidateObjectLabel(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum identifier,
+ GLuint name,
+ GLsizei length,
+ const GLchar *label)
+{
+ return true;
+}
+
+bool ValidateObjectPtrLabel(const Context *context,
+ angle::EntryPoint entryPoint,
+ const void *ptr,
+ GLsizei length,
+ const GLchar *label)
+{
+ return true;
+}
+
+bool ValidatePatchParameteri(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLint value)
+{
+ return true;
+}
+
+bool ValidatePopDebugGroup(const Context *context, angle::EntryPoint entryPoint)
+{
+ return true;
+}
+
+bool ValidatePrimitiveBoundingBox(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat minX,
+ GLfloat minY,
+ GLfloat minZ,
+ GLfloat minW,
+ GLfloat maxX,
+ GLfloat maxY,
+ GLfloat maxZ,
+ GLfloat maxW)
+{
+ return true;
+}
+
+bool ValidatePushDebugGroup(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum source,
+ GLuint id,
+ GLsizei length,
+ const GLchar *message)
+{
+ return true;
+}
+
+bool ValidateReadnPixels(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *data)
+{
+ return true;
+}
+
+bool ValidateSamplerParameterIiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID sampler,
+ GLenum pname,
+ const GLint *param)
+{
+ return true;
+}
+
+bool ValidateSamplerParameterIuiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID sampler,
+ GLenum pname,
+ const GLuint *param)
+{
+ return true;
+}
+
+bool ValidateTexBuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLenum internalformat,
+ BufferID buffer)
+{
+ if (context->getClientVersion() < ES_3_2)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES32Required);
+ return false;
+ }
+
+ return ValidateTexBufferBase(context, entryPoint, target, internalformat, buffer);
+}
+
+bool ValidateTexBufferRange(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLenum internalformat,
+ BufferID buffer,
+ GLintptr offset,
+ GLsizeiptr size)
+{
+ if (context->getClientVersion() < ES_3_2)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES32Required);
+ return false;
+ }
+
+ return ValidateTexBufferRangeBase(context, entryPoint, target, internalformat, buffer, offset,
+ size);
+}
+
+bool ValidateTexParameterIiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLint *params)
+{
+ return true;
+}
+
+bool ValidateTexParameterIuiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLuint *params)
+{
+ return true;
+}
+
+bool ValidateTexStorage3DMultisample(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean fixedsamplelocations)
+{
+ return true;
+}
+
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/validationES32.h b/gfx/angle/checkout/src/libANGLE/validationES32.h
new file mode 100644
index 0000000000..674bc81d06
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/validationES32.h
@@ -0,0 +1,20 @@
+//
+// Copyright 2019 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.
+//
+// validationES32.h:
+// Inlined validation functions for OpenGL ES 3.2 entry points.
+
+#ifndef LIBANGLE_VALIDATION_ES32_H_
+#define LIBANGLE_VALIDATION_ES32_H_
+
+#include "libANGLE/ErrorStrings.h"
+#include "libANGLE/validationES32_autogen.h"
+
+namespace gl
+{
+// Nothing here yet.
+} // namespace gl
+
+#endif // LIBANGLE_VALIDATION_ES32_H_
diff --git a/gfx/angle/checkout/src/libANGLE/validationES32_autogen.h b/gfx/angle/checkout/src/libANGLE/validationES32_autogen.h
new file mode 100644
index 0000000000..171f94d55c
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/validationES32_autogen.h
@@ -0,0 +1,281 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml and gl_angle_ext.xml.
+//
+// Copyright 2020 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.
+//
+// validationES32_autogen.h:
+// Validation functions for the OpenGL ES 3.2 entry points.
+
+#ifndef LIBANGLE_VALIDATION_ES32_AUTOGEN_H_
+#define LIBANGLE_VALIDATION_ES32_AUTOGEN_H_
+
+#include "common/PackedEnums.h"
+#include "common/entry_points_enum_autogen.h"
+
+namespace gl
+{
+class Context;
+
+bool ValidateBlendBarrier(const Context *context, angle::EntryPoint entryPoint);
+bool ValidateBlendEquationSeparatei(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint buf,
+ GLenum modeRGB,
+ GLenum modeAlpha);
+bool ValidateBlendEquationi(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint buf,
+ GLenum mode);
+bool ValidateBlendFuncSeparatei(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint buf,
+ GLenum srcRGB,
+ GLenum dstRGB,
+ GLenum srcAlpha,
+ GLenum dstAlpha);
+bool ValidateBlendFunci(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint buf,
+ GLenum src,
+ GLenum dst);
+bool ValidateColorMaski(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLboolean r,
+ GLboolean g,
+ GLboolean b,
+ GLboolean a);
+bool ValidateCopyImageSubData(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint srcName,
+ GLenum srcTarget,
+ GLint srcLevel,
+ GLint srcX,
+ GLint srcY,
+ GLint srcZ,
+ GLuint dstName,
+ GLenum dstTarget,
+ GLint dstLevel,
+ GLint dstX,
+ GLint dstY,
+ GLint dstZ,
+ GLsizei srcWidth,
+ GLsizei srcHeight,
+ GLsizei srcDepth);
+bool ValidateDebugMessageCallback(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLDEBUGPROC callback,
+ const void *userParam);
+bool ValidateDebugMessageControl(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum source,
+ GLenum type,
+ GLenum severity,
+ GLsizei count,
+ const GLuint *ids,
+ GLboolean enabled);
+bool ValidateDebugMessageInsert(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum source,
+ GLenum type,
+ GLuint id,
+ GLenum severity,
+ GLsizei length,
+ const GLchar *buf);
+bool ValidateDisablei(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint index);
+bool ValidateDrawElementsBaseVertex(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLint basevertex);
+bool ValidateDrawElementsInstancedBaseVertex(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLsizei instancecount,
+ GLint basevertex);
+bool ValidateDrawRangeElementsBaseVertex(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLint basevertex);
+bool ValidateEnablei(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint index);
+bool ValidateFramebufferTexture(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ TextureID texturePacked,
+ GLint level);
+bool ValidateGetDebugMessageLog(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint count,
+ GLsizei bufSize,
+ const GLenum *sources,
+ const GLenum *types,
+ const GLuint *ids,
+ const GLenum *severities,
+ const GLsizei *lengths,
+ const GLchar *messageLog);
+bool ValidateGetGraphicsResetStatus(const Context *context, angle::EntryPoint entryPoint);
+bool ValidateGetObjectLabel(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum identifier,
+ GLuint name,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLchar *label);
+bool ValidateGetObjectPtrLabel(const Context *context,
+ angle::EntryPoint entryPoint,
+ const void *ptr,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLchar *label);
+bool ValidateGetPointerv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ void *const *params);
+bool ValidateGetSamplerParameterIiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID samplerPacked,
+ GLenum pname,
+ const GLint *params);
+bool ValidateGetSamplerParameterIuiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID samplerPacked,
+ GLenum pname,
+ const GLuint *params);
+bool ValidateGetTexParameterIiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLint *params);
+bool ValidateGetTexParameterIuiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLuint *params);
+bool ValidateGetnUniformfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei bufSize,
+ const GLfloat *params);
+bool ValidateGetnUniformiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei bufSize,
+ const GLint *params);
+bool ValidateGetnUniformuiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei bufSize,
+ const GLuint *params);
+bool ValidateIsEnabledi(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint index);
+bool ValidateMinSampleShading(const Context *context, angle::EntryPoint entryPoint, GLfloat value);
+bool ValidateObjectLabel(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum identifier,
+ GLuint name,
+ GLsizei length,
+ const GLchar *label);
+bool ValidateObjectPtrLabel(const Context *context,
+ angle::EntryPoint entryPoint,
+ const void *ptr,
+ GLsizei length,
+ const GLchar *label);
+bool ValidatePatchParameteri(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLint value);
+bool ValidatePopDebugGroup(const Context *context, angle::EntryPoint entryPoint);
+bool ValidatePrimitiveBoundingBox(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat minX,
+ GLfloat minY,
+ GLfloat minZ,
+ GLfloat minW,
+ GLfloat maxX,
+ GLfloat maxY,
+ GLfloat maxZ,
+ GLfloat maxW);
+bool ValidatePushDebugGroup(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum source,
+ GLuint id,
+ GLsizei length,
+ const GLchar *message);
+bool ValidateReadnPixels(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *data);
+bool ValidateSamplerParameterIiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID samplerPacked,
+ GLenum pname,
+ const GLint *param);
+bool ValidateSamplerParameterIuiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID samplerPacked,
+ GLenum pname,
+ const GLuint *param);
+bool ValidateTexBuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum internalformat,
+ BufferID bufferPacked);
+bool ValidateTexBufferRange(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum internalformat,
+ BufferID bufferPacked,
+ GLintptr offset,
+ GLsizeiptr size);
+bool ValidateTexParameterIiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLint *params);
+bool ValidateTexParameterIuiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLuint *params);
+bool ValidateTexStorage3DMultisample(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean fixedsamplelocations);
+} // namespace gl
+
+#endif // LIBANGLE_VALIDATION_ES32_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libANGLE/validationES3_autogen.h b/gfx/angle/checkout/src/libANGLE/validationES3_autogen.h
new file mode 100644
index 0000000000..10465c63f5
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/validationES3_autogen.h
@@ -0,0 +1,578 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml and gl_angle_ext.xml.
+//
+// Copyright 2020 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.
+//
+// validationES3_autogen.h:
+// Validation functions for the OpenGL ES 3.0 entry points.
+
+#ifndef LIBANGLE_VALIDATION_ES3_AUTOGEN_H_
+#define LIBANGLE_VALIDATION_ES3_AUTOGEN_H_
+
+#include "common/PackedEnums.h"
+#include "common/entry_points_enum_autogen.h"
+
+namespace gl
+{
+class Context;
+
+bool ValidateBeginQuery(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryType targetPacked,
+ QueryID idPacked);
+bool ValidateBeginTransformFeedback(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode primitiveModePacked);
+bool ValidateBindBufferBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding targetPacked,
+ GLuint index,
+ BufferID bufferPacked);
+bool ValidateBindBufferRange(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding targetPacked,
+ GLuint index,
+ BufferID bufferPacked,
+ GLintptr offset,
+ GLsizeiptr size);
+bool ValidateBindSampler(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint unit,
+ SamplerID samplerPacked);
+bool ValidateBindTransformFeedback(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ TransformFeedbackID idPacked);
+bool ValidateBindVertexArray(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexArrayID arrayPacked);
+bool ValidateBlitFramebuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint srcX0,
+ GLint srcY0,
+ GLint srcX1,
+ GLint srcY1,
+ GLint dstX0,
+ GLint dstY0,
+ GLint dstX1,
+ GLint dstY1,
+ GLbitfield mask,
+ GLenum filter);
+bool ValidateClearBufferfi(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum buffer,
+ GLint drawbuffer,
+ GLfloat depth,
+ GLint stencil);
+bool ValidateClearBufferfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLfloat *value);
+bool ValidateClearBufferiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLint *value);
+bool ValidateClearBufferuiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLuint *value);
+bool ValidateClientWaitSync(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsync sync,
+ GLbitfield flags,
+ GLuint64 timeout);
+bool ValidateCompressedTexImage3D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLsizei imageSize,
+ const void *data);
+bool ValidateCompressedTexSubImage3D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data);
+bool ValidateCopyBufferSubData(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding readTargetPacked,
+ BufferBinding writeTargetPacked,
+ GLintptr readOffset,
+ GLintptr writeOffset,
+ GLsizeiptr size);
+bool ValidateCopyTexSubImage3D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height);
+bool ValidateDeleteQueries(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const QueryID *idsPacked);
+bool ValidateDeleteSamplers(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei count,
+ const SamplerID *samplersPacked);
+bool ValidateDeleteSync(const Context *context, angle::EntryPoint entryPoint, GLsync sync);
+bool ValidateDeleteTransformFeedbacks(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const TransformFeedbackID *idsPacked);
+bool ValidateDeleteVertexArrays(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const VertexArrayID *arraysPacked);
+bool ValidateDrawArraysInstanced(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ GLint first,
+ GLsizei count,
+ GLsizei instancecount);
+bool ValidateDrawBuffers(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const GLenum *bufs);
+bool ValidateDrawElementsInstanced(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLsizei instancecount);
+bool ValidateDrawRangeElements(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices);
+bool ValidateEndQuery(const Context *context, angle::EntryPoint entryPoint, QueryType targetPacked);
+bool ValidateEndTransformFeedback(const Context *context, angle::EntryPoint entryPoint);
+bool ValidateFenceSync(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum condition,
+ GLbitfield flags);
+bool ValidateFlushMappedBufferRange(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding targetPacked,
+ GLintptr offset,
+ GLsizeiptr length);
+bool ValidateFramebufferTextureLayer(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ TextureID texturePacked,
+ GLint level,
+ GLint layer);
+bool ValidateGenQueries(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const QueryID *idsPacked);
+bool ValidateGenSamplers(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei count,
+ const SamplerID *samplersPacked);
+bool ValidateGenTransformFeedbacks(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const TransformFeedbackID *idsPacked);
+bool ValidateGenVertexArrays(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const VertexArrayID *arraysPacked);
+bool ValidateGetActiveUniformBlockName(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformBlockIndex uniformBlockIndexPacked,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLchar *uniformBlockName);
+bool ValidateGetActiveUniformBlockiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformBlockIndex uniformBlockIndexPacked,
+ GLenum pname,
+ const GLint *params);
+bool ValidateGetActiveUniformsiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ GLsizei uniformCount,
+ const GLuint *uniformIndices,
+ GLenum pname,
+ const GLint *params);
+bool ValidateGetBufferParameteri64v(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding targetPacked,
+ GLenum pname,
+ const GLint64 *params);
+bool ValidateGetBufferPointerv(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding targetPacked,
+ GLenum pname,
+ void *const *params);
+bool ValidateGetFragDataLocation(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ const GLchar *name);
+bool ValidateGetInteger64i_v(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint index,
+ const GLint64 *data);
+bool ValidateGetInteger64v(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ const GLint64 *data);
+bool ValidateGetIntegeri_v(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint index,
+ const GLint *data);
+bool ValidateGetInternalformativ(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum internalformat,
+ GLenum pname,
+ GLsizei count,
+ const GLint *params);
+bool ValidateGetProgramBinary(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLenum *binaryFormat,
+ const void *binary);
+bool ValidateGetQueryObjectuiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID idPacked,
+ GLenum pname,
+ const GLuint *params);
+bool ValidateGetQueryiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryType targetPacked,
+ GLenum pname,
+ const GLint *params);
+bool ValidateGetSamplerParameterfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID samplerPacked,
+ GLenum pname,
+ const GLfloat *params);
+bool ValidateGetSamplerParameteriv(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID samplerPacked,
+ GLenum pname,
+ const GLint *params);
+bool ValidateGetStringi(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum name,
+ GLuint index);
+bool ValidateGetSynciv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsync sync,
+ GLenum pname,
+ GLsizei count,
+ const GLsizei *length,
+ const GLint *values);
+bool ValidateGetTransformFeedbackVarying(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ GLuint index,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLsizei *size,
+ const GLenum *type,
+ const GLchar *name);
+bool ValidateGetUniformBlockIndex(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ const GLchar *uniformBlockName);
+bool ValidateGetUniformIndices(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ GLsizei uniformCount,
+ const GLchar *const *uniformNames,
+ const GLuint *uniformIndices);
+bool ValidateGetUniformuiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ const GLuint *params);
+bool ValidateGetVertexAttribIiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum pname,
+ const GLint *params);
+bool ValidateGetVertexAttribIuiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum pname,
+ const GLuint *params);
+bool ValidateInvalidateFramebuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLsizei numAttachments,
+ const GLenum *attachments);
+bool ValidateInvalidateSubFramebuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLsizei numAttachments,
+ const GLenum *attachments,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height);
+bool ValidateIsQuery(const Context *context, angle::EntryPoint entryPoint, QueryID idPacked);
+bool ValidateIsSampler(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID samplerPacked);
+bool ValidateIsSync(const Context *context, angle::EntryPoint entryPoint, GLsync sync);
+bool ValidateIsTransformFeedback(const Context *context,
+ angle::EntryPoint entryPoint,
+ TransformFeedbackID idPacked);
+bool ValidateIsVertexArray(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexArrayID arrayPacked);
+bool ValidateMapBufferRange(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding targetPacked,
+ GLintptr offset,
+ GLsizeiptr length,
+ GLbitfield access);
+bool ValidatePauseTransformFeedback(const Context *context, angle::EntryPoint entryPoint);
+bool ValidateProgramBinary(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ GLenum binaryFormat,
+ const void *binary,
+ GLsizei length);
+bool ValidateProgramParameteri(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ GLenum pname,
+ GLint value);
+bool ValidateReadBuffer(const Context *context, angle::EntryPoint entryPoint, GLenum src);
+bool ValidateRenderbufferStorageMultisample(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height);
+bool ValidateResumeTransformFeedback(const Context *context, angle::EntryPoint entryPoint);
+bool ValidateSamplerParameterf(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLfloat param);
+bool ValidateSamplerParameterfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID samplerPacked,
+ GLenum pname,
+ const GLfloat *param);
+bool ValidateSamplerParameteri(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLint param);
+bool ValidateSamplerParameteriv(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID samplerPacked,
+ GLenum pname,
+ const GLint *param);
+bool ValidateTexImage3D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const void *pixels);
+bool ValidateTexStorage2D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height);
+bool ValidateTexStorage3D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth);
+bool ValidateTexSubImage3D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ const void *pixels);
+bool ValidateTransformFeedbackVaryings(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ GLsizei count,
+ const GLchar *const *varyings,
+ GLenum bufferMode);
+bool ValidateUniform1ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLuint v0);
+bool ValidateUniform1uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value);
+bool ValidateUniform2ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLuint v0,
+ GLuint v1);
+bool ValidateUniform2uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value);
+bool ValidateUniform3ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLuint v0,
+ GLuint v1,
+ GLuint v2);
+bool ValidateUniform3uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value);
+bool ValidateUniform4ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLuint v0,
+ GLuint v1,
+ GLuint v2,
+ GLuint v3);
+bool ValidateUniform4uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value);
+bool ValidateUniformBlockBinding(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformBlockIndex uniformBlockIndexPacked,
+ GLuint uniformBlockBinding);
+bool ValidateUniformMatrix2x3fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+bool ValidateUniformMatrix2x4fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+bool ValidateUniformMatrix3x2fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+bool ValidateUniformMatrix3x4fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+bool ValidateUniformMatrix4x2fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+bool ValidateUniformMatrix4x3fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+bool ValidateUnmapBuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding targetPacked);
+bool ValidateVertexAttribDivisor(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLuint divisor);
+bool ValidateVertexAttribI4i(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLint x,
+ GLint y,
+ GLint z,
+ GLint w);
+bool ValidateVertexAttribI4iv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLint *v);
+bool ValidateVertexAttribI4ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLuint x,
+ GLuint y,
+ GLuint z,
+ GLuint w);
+bool ValidateVertexAttribI4uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLuint *v);
+bool ValidateVertexAttribIPointer(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLint size,
+ VertexAttribType typePacked,
+ GLsizei stride,
+ const void *pointer);
+bool ValidateWaitSync(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsync sync,
+ GLbitfield flags,
+ GLuint64 timeout);
+} // namespace gl
+
+#endif // LIBANGLE_VALIDATION_ES3_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libANGLE/validationESEXT.cpp b/gfx/angle/checkout/src/libANGLE/validationESEXT.cpp
new file mode 100644
index 0000000000..c708206412
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/validationESEXT.cpp
@@ -0,0 +1,3599 @@
+//
+// Copyright 2019 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.
+//
+// validationESEXT.cpp: Validation functions for OpenGL ES extension entry points.
+
+#include "libANGLE/validationESEXT_autogen.h"
+
+#include "libANGLE/Context.h"
+#include "libANGLE/ErrorStrings.h"
+#include "libANGLE/MemoryObject.h"
+#include "libANGLE/PixelLocalStorage.h"
+#include "libANGLE/validationES.h"
+#include "libANGLE/validationES2.h"
+#include "libANGLE/validationES3.h"
+#include "libANGLE/validationES31.h"
+#include "libANGLE/validationES32.h"
+
+namespace gl
+{
+using namespace err;
+
+namespace
+{
+template <typename ObjectT>
+bool ValidateGetImageFormatAndType(const Context *context,
+ angle::EntryPoint entryPoint,
+ ObjectT *obj,
+ GLenum format,
+ GLenum type)
+{
+ GLenum implFormat = obj->getImplementationColorReadFormat(context);
+ if (!ValidES3Format(format) && (format != implFormat || format == GL_NONE))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidFormat);
+ return false;
+ }
+
+ GLenum implType = obj->getImplementationColorReadType(context);
+ if (!ValidES3Type(type) && (type != implType || type == GL_NONE))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidType);
+ return false;
+ }
+
+ // Format/type combinations are not yet validated.
+
+ return true;
+}
+
+bool IsValidImageLayout(ImageLayout layout)
+{
+ switch (layout)
+ {
+ case ImageLayout::Undefined:
+ case ImageLayout::General:
+ case ImageLayout::ColorAttachment:
+ case ImageLayout::DepthStencilAttachment:
+ case ImageLayout::DepthStencilReadOnlyAttachment:
+ case ImageLayout::ShaderReadOnly:
+ case ImageLayout::TransferSrc:
+ case ImageLayout::TransferDst:
+ case ImageLayout::DepthReadOnlyStencilAttachment:
+ case ImageLayout::DepthAttachmentStencilReadOnly:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+bool IsValidMemoryObjectParamater(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname)
+{
+ switch (pname)
+ {
+ case GL_DEDICATED_MEMORY_OBJECT_EXT:
+ return true;
+
+ case GL_PROTECTED_MEMORY_OBJECT_EXT:
+ if (!context->getExtensions().protectedTexturesEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+bool ValidateObjectIdentifierAndName(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum identifier,
+ GLuint name)
+{
+ bool isGLES11 = context->getClientVersion() == Version(1, 1);
+ bool isGLES3 = context->getClientMajorVersion() >= 3;
+ bool isGLES31 = context->getClientVersion() >= Version(3, 1);
+ switch (identifier)
+ {
+ case GL_BUFFER_OBJECT_EXT:
+ if (context->getBuffer({name}) == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidBufferName);
+ return false;
+ }
+ return true;
+
+ case GL_SHADER_OBJECT_EXT:
+ if (isGLES11)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidType);
+ return false;
+ }
+ if (context->getShader({name}) == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidShaderName);
+ return false;
+ }
+ return true;
+
+ case GL_PROGRAM_OBJECT_EXT:
+ if (isGLES11)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidType);
+ return false;
+ }
+ if (context->getProgramNoResolveLink({name}) == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidProgramName);
+ return false;
+ }
+ return true;
+
+ case GL_VERTEX_ARRAY_OBJECT_EXT:
+ if (!isGLES3 && !context->getExtensions().vertexArrayObjectOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidType);
+ return false;
+ }
+ if (context->getVertexArray({name}) == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidVertexArrayName);
+ return false;
+ }
+ return true;
+
+ case GL_QUERY_OBJECT_EXT:
+ if (!isGLES3 && !context->getExtensions().occlusionQueryBooleanEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidType);
+ return false;
+ }
+ if (context->getQuery({name}) == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidQueryName);
+ return false;
+ }
+ return true;
+
+ case GL_TRANSFORM_FEEDBACK:
+ if (!isGLES3)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidType);
+ return false;
+ }
+ if (context->getTransformFeedback({name}) == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kInvalidTransformFeedbackName);
+ return false;
+ }
+ return true;
+
+ case GL_SAMPLER:
+ if (!isGLES3)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidType);
+ return false;
+ }
+ if (context->getSampler({name}) == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidSamplerName);
+ return false;
+ }
+ return true;
+
+ case GL_TEXTURE:
+ if (context->getTexture({name}) == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidTextureName);
+ return false;
+ }
+ return true;
+
+ case GL_RENDERBUFFER:
+ if (!context->isRenderbuffer({name}))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kInvalidRenderbufferName);
+ return false;
+ }
+ return true;
+
+ case GL_FRAMEBUFFER:
+ if (context->getFramebuffer({name}) == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidFramebufferName);
+ return false;
+ }
+ return true;
+
+ case GL_PROGRAM_PIPELINE_OBJECT_EXT:
+ if (!isGLES31 && !context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidType);
+ return false;
+ }
+ if (context->getProgramPipeline({name}) == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kInvalidProgramPipelineName);
+ return false;
+ }
+ return true;
+
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidIndentifier);
+ return false;
+ }
+}
+} // namespace
+
+bool ValidateGetTexImage(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level)
+{
+ if (!context->getExtensions().getImageANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kGetImageExtensionNotEnabled);
+ return false;
+ }
+
+ if (!ValidTexture2DDestinationTarget(context, target) &&
+ !ValidTexture3DDestinationTarget(context, target))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget);
+ return false;
+ }
+
+ if (level < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeLevel);
+ return false;
+ }
+
+ TextureType textureType = TextureTargetToType(target);
+ if (!ValidMipLevel(context, textureType, level))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetTexImageANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ if (!ValidateGetTexImage(context, entryPoint, target, level))
+ {
+ return false;
+ }
+
+ Texture *texture = context->getTextureByTarget(target);
+
+ if (!ValidateGetImageFormatAndType(context, entryPoint, texture, format, type))
+ {
+ return false;
+ }
+
+ GLsizei width = static_cast<GLsizei>(texture->getWidth(target, level));
+ GLsizei height = static_cast<GLsizei>(texture->getHeight(target, level));
+ if (!ValidatePixelPack(context, entryPoint, format, type, 0, 0, width, height, -1, nullptr,
+ pixels))
+ {
+ return false;
+ }
+
+ if (texture->getFormat(target, level).info->compressed)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kGetImageCompressed);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetCompressedTexImageANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ const void *pixels)
+{
+ if (!ValidateGetTexImage(context, entryPoint, target, level))
+ {
+ return false;
+ }
+
+ Texture *texture = context->getTextureByTarget(target);
+ if (!texture->getFormat(target, level).info->compressed)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kGetImageNotCompressed);
+ return false;
+ }
+
+ if (texture->isCompressedFormatEmulated(context, target, level))
+ {
+ // TODO (anglebug.com/7464): We can't currently read back from an emulated format
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidEmulatedFormat);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetRenderbufferImageANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ if (!context->getExtensions().getImageANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kGetImageExtensionNotEnabled);
+ return false;
+ }
+
+ if (target != GL_RENDERBUFFER)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidRenderbufferTarget);
+ return false;
+ }
+
+ Renderbuffer *renderbuffer = context->getState().getCurrentRenderbuffer();
+
+ if (!ValidateGetImageFormatAndType(context, entryPoint, renderbuffer, format, type))
+ {
+ return false;
+ }
+
+ GLsizei width = renderbuffer->getWidth();
+ GLsizei height = renderbuffer->getHeight();
+ if (!ValidatePixelPack(context, entryPoint, format, type, 0, 0, width, height, -1, nullptr,
+ pixels))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateDrawElementsBaseVertexEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLsizei count,
+ DrawElementsType type,
+ const void *indices,
+ GLint basevertex)
+{
+ if (!context->getExtensions().drawElementsBaseVertexAny())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices, 1);
+}
+
+bool ValidateDrawElementsInstancedBaseVertexEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLsizei count,
+ DrawElementsType type,
+ const void *indices,
+ GLsizei instancecount,
+ GLint basevertex)
+{
+ if (!context->getExtensions().drawElementsBaseVertexAny())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateDrawElementsInstancedBase(context, entryPoint, mode, count, type, indices,
+ instancecount);
+}
+
+bool ValidateDrawRangeElementsBaseVertexEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ DrawElementsType type,
+ const void *indices,
+ GLint basevertex)
+{
+ if (!context->getExtensions().drawElementsBaseVertexAny())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ if (end < start)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidElementRange);
+ return false;
+ }
+
+ if (!ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices, 0))
+ {
+ return false;
+ }
+
+ // Skip range checks for no-op calls.
+ if (count <= 0)
+ {
+ return true;
+ }
+
+ // Note that resolving the index range is a bit slow. We should probably optimize this.
+ IndexRange indexRange;
+ ANGLE_VALIDATION_TRY(context->getState().getVertexArray()->getIndexRange(context, type, count,
+ indices, &indexRange));
+
+ if (indexRange.end > end || indexRange.start < start)
+ {
+ // GL spec says that behavior in this case is undefined - generating an error is fine.
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExceedsElementRange);
+ return false;
+ }
+ return true;
+}
+
+bool ValidateMultiDrawElementsBaseVertexEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ const GLsizei *count,
+ DrawElementsType type,
+ const void *const *indices,
+ GLsizei drawcount,
+ const GLint *basevertex)
+{
+ return true;
+}
+
+bool ValidateMultiDrawArraysIndirectEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ const void *indirect,
+ GLsizei drawcount,
+ GLsizei stride)
+{
+ if (!ValidateMultiDrawIndirectBase(context, entryPoint, drawcount, stride))
+ {
+ return false;
+ }
+
+ if (!ValidateDrawArraysIndirect(context, entryPoint, modePacked, indirect))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateMultiDrawElementsIndirectEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ DrawElementsType typePacked,
+ const void *indirect,
+ GLsizei drawcount,
+ GLsizei stride)
+{
+ if (!ValidateMultiDrawIndirectBase(context, entryPoint, drawcount, stride))
+ {
+ return false;
+ }
+
+ const State &state = context->getState();
+ TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
+ if (!ValidateDrawElementsIndirect(context, entryPoint, modePacked, typePacked, indirect))
+ {
+ return false;
+ }
+
+ if (curTransformFeedback && curTransformFeedback->isActive() &&
+ !curTransformFeedback->isPaused())
+ {
+ // EXT_geometry_shader allows transform feedback to work with all draw commands.
+ // [EXT_geometry_shader] Section 12.1, "Transform Feedback"
+ if (context->getExtensions().geometryShaderAny() || context->getClientVersion() >= ES_3_2)
+ {
+ if (!ValidateTransformFeedbackPrimitiveMode(
+ context, entryPoint, curTransformFeedback->getPrimitiveMode(), modePacked))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kInvalidDrawModeTransformFeedback);
+ return false;
+ }
+ }
+ else
+ {
+ // An INVALID_OPERATION error is generated if transform feedback is active and not
+ // paused.
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kUnsupportedDrawModeForTransformFeedback);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateDrawArraysInstancedBaseInstanceEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLint first,
+ GLsizei count,
+ GLsizei instanceCount,
+ GLuint baseInstance)
+{
+ if (!context->getExtensions().baseInstanceEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateDrawArraysInstancedBase(context, entryPoint, mode, first, count, instanceCount);
+}
+
+bool ValidateDrawElementsInstancedBaseInstanceEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLsizei count,
+ DrawElementsType type,
+ void const *indices,
+ GLsizei instancecount,
+ GLuint baseinstance)
+{
+ if (!context->getExtensions().baseInstanceEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateDrawElementsInstancedBase(context, entryPoint, mode, count, type, indices,
+ instancecount);
+}
+
+bool ValidateDrawElementsInstancedBaseVertexBaseInstanceEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLsizei instancecount,
+ GLint basevertex,
+ GLuint baseinstance)
+{
+ if (!context->getExtensions().baseInstanceEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateDrawElementsInstancedBase(context, entryPoint, mode, count, typePacked, indices,
+ instancecount);
+}
+
+bool ValidateDrawElementsBaseVertexOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLsizei count,
+ DrawElementsType type,
+ const void *indices,
+ GLint basevertex)
+{
+ if (!context->getExtensions().drawElementsBaseVertexAny())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices, 1);
+}
+
+bool ValidateDrawElementsInstancedBaseVertexOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLsizei count,
+ DrawElementsType type,
+ const void *indices,
+ GLsizei instancecount,
+ GLint basevertex)
+{
+ if (!context->getExtensions().drawElementsBaseVertexAny())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateDrawElementsInstancedBase(context, entryPoint, mode, count, type, indices,
+ instancecount);
+}
+
+bool ValidateDrawRangeElementsBaseVertexOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ DrawElementsType type,
+ const void *indices,
+ GLint basevertex)
+{
+ if (!context->getExtensions().drawElementsBaseVertexAny())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ if (end < start)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidElementRange);
+ return false;
+ }
+
+ if (!ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices, 0))
+ {
+ return false;
+ }
+
+ // Skip range checks for no-op calls.
+ if (count <= 0)
+ {
+ return true;
+ }
+
+ // Note that resolving the index range is a bit slow. We should probably optimize this.
+ IndexRange indexRange;
+ ANGLE_VALIDATION_TRY(context->getState().getVertexArray()->getIndexRange(context, type, count,
+ indices, &indexRange));
+
+ if (indexRange.end > end || indexRange.start < start)
+ {
+ // GL spec says that behavior in this case is undefined - generating an error is fine.
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExceedsElementRange);
+ return false;
+ }
+ return true;
+}
+
+// GL_KHR_blend_equation_advanced
+bool ValidateBlendBarrierKHR(const Context *context, angle::EntryPoint entryPoint)
+{
+ const Extensions &extensions = context->getExtensions();
+
+ if (!extensions.blendEquationAdvancedKHR)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kAdvancedBlendExtensionNotEnabled);
+ }
+
+ return true;
+}
+
+bool ValidateBlendEquationSeparateiEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint buf,
+ GLenum modeRGB,
+ GLenum modeAlpha)
+{
+ if (!context->getExtensions().drawBuffersIndexedEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateBlendEquationSeparatei(context, entryPoint, buf, modeRGB, modeAlpha);
+}
+
+bool ValidateBlendEquationiEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint buf,
+ GLenum mode)
+{
+ if (!context->getExtensions().drawBuffersIndexedEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateBlendEquationi(context, entryPoint, buf, mode);
+}
+
+bool ValidateBlendFuncSeparateiEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint buf,
+ GLenum srcRGB,
+ GLenum dstRGB,
+ GLenum srcAlpha,
+ GLenum dstAlpha)
+{
+ if (!context->getExtensions().drawBuffersIndexedEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateBlendFuncSeparatei(context, entryPoint, buf, srcRGB, dstRGB, srcAlpha, dstAlpha);
+}
+
+bool ValidateBlendFunciEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint buf,
+ GLenum src,
+ GLenum dst)
+{
+ if (!context->getExtensions().drawBuffersIndexedEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateBlendFunci(context, entryPoint, buf, src, dst);
+}
+
+bool ValidateColorMaskiEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLboolean r,
+ GLboolean g,
+ GLboolean b,
+ GLboolean a)
+{
+ if (!context->getExtensions().drawBuffersIndexedEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateColorMaski(context, entryPoint, index, r, g, b, a);
+}
+
+bool ValidateDisableiEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint index)
+{
+ if (!context->getExtensions().drawBuffersIndexedEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateDisablei(context, entryPoint, target, index);
+}
+
+bool ValidateEnableiEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint index)
+{
+ if (!context->getExtensions().drawBuffersIndexedEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateEnablei(context, entryPoint, target, index);
+}
+
+bool ValidateIsEnablediEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint index)
+{
+ if (!context->getExtensions().drawBuffersIndexedEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateIsEnabledi(context, entryPoint, target, index);
+}
+
+bool ValidateBlendEquationSeparateiOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint buf,
+ GLenum modeRGB,
+ GLenum modeAlpha)
+{
+ if (!context->getExtensions().drawBuffersIndexedOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateBlendEquationSeparatei(context, entryPoint, buf, modeRGB, modeAlpha);
+}
+
+bool ValidateBlendEquationiOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint buf,
+ GLenum mode)
+{
+ if (!context->getExtensions().drawBuffersIndexedOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateBlendEquationi(context, entryPoint, buf, mode);
+}
+
+bool ValidateBlendFuncSeparateiOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint buf,
+ GLenum srcRGB,
+ GLenum dstRGB,
+ GLenum srcAlpha,
+ GLenum dstAlpha)
+{
+ if (!context->getExtensions().drawBuffersIndexedOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateBlendFuncSeparatei(context, entryPoint, buf, srcRGB, dstRGB, srcAlpha, dstAlpha);
+}
+
+bool ValidateBlendFunciOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint buf,
+ GLenum src,
+ GLenum dst)
+{
+ if (!context->getExtensions().drawBuffersIndexedOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateBlendFunci(context, entryPoint, buf, src, dst);
+}
+
+bool ValidateColorMaskiOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLboolean r,
+ GLboolean g,
+ GLboolean b,
+ GLboolean a)
+{
+ if (!context->getExtensions().drawBuffersIndexedOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateColorMaski(context, entryPoint, index, r, g, b, a);
+}
+
+bool ValidateDisableiOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint index)
+{
+ if (!context->getExtensions().drawBuffersIndexedOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateDisablei(context, entryPoint, target, index);
+}
+
+bool ValidateEnableiOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint index)
+{
+ if (!context->getExtensions().drawBuffersIndexedOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateEnablei(context, entryPoint, target, index);
+}
+
+bool ValidateIsEnablediOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint index)
+{
+ if (!context->getExtensions().drawBuffersIndexedOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateIsEnabledi(context, entryPoint, target, index);
+}
+
+bool ValidateGetInteger64vEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ const GLint64 *data)
+{
+ if (!context->getExtensions().disjointTimerQueryEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ GLenum nativeType = GL_NONE;
+ unsigned int numParams = 0;
+ if (!ValidateStateQuery(context, entryPoint, pname, &nativeType, &numParams))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateCopyImageSubDataEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint srcName,
+ GLenum srcTarget,
+ GLint srcLevel,
+ GLint srcX,
+ GLint srcY,
+ GLint srcZ,
+ GLuint dstName,
+ GLenum dstTarget,
+ GLint dstLevel,
+ GLint dstX,
+ GLint dstY,
+ GLint dstZ,
+ GLsizei srcWidth,
+ GLsizei srcHeight,
+ GLsizei srcDepth)
+{
+ if (!context->getExtensions().copyImageEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateCopyImageSubDataBase(context, entryPoint, srcName, srcTarget, srcLevel, srcX,
+ srcY, srcZ, dstName, dstTarget, dstLevel, dstX, dstY, dstZ,
+ srcWidth, srcHeight, srcDepth);
+}
+
+bool ValidateCopyImageSubDataOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint srcName,
+ GLenum srcTarget,
+ GLint srcLevel,
+ GLint srcX,
+ GLint srcY,
+ GLint srcZ,
+ GLuint dstName,
+ GLenum dstTarget,
+ GLint dstLevel,
+ GLint dstX,
+ GLint dstY,
+ GLint dstZ,
+ GLsizei srcWidth,
+ GLsizei srcHeight,
+ GLsizei srcDepth)
+{
+ if (!context->getExtensions().copyImageEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateCopyImageSubDataBase(context, entryPoint, srcName, srcTarget, srcLevel, srcX,
+ srcY, srcZ, dstName, dstTarget, dstLevel, dstX, dstY, dstZ,
+ srcWidth, srcHeight, srcDepth);
+}
+
+bool ValidateBufferStorageMemEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLsizeiptr size,
+ MemoryObjectID memory,
+ GLuint64 offset)
+{
+ if (!context->getExtensions().memoryObjectEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ UNIMPLEMENTED();
+ return false;
+}
+
+bool ValidateCreateMemoryObjectsEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const MemoryObjectID *memoryObjects)
+{
+ if (!context->getExtensions().memoryObjectEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateGenOrDelete(context, entryPoint, n);
+}
+
+bool ValidateDeleteMemoryObjectsEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const MemoryObjectID *memoryObjects)
+{
+ if (!context->getExtensions().memoryObjectEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateGenOrDelete(context, entryPoint, n);
+}
+
+bool ValidateGetMemoryObjectParameterivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ MemoryObjectID memoryObject,
+ GLenum pname,
+ const GLint *params)
+{
+ if (!context->getExtensions().memoryObjectEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ const MemoryObject *memory = context->getMemoryObject(memoryObject);
+ if (memory == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMemoryObject);
+ }
+
+ if (!IsValidMemoryObjectParamater(context, entryPoint, pname))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidMemoryObjectParameter);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetUnsignedBytevEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ const GLubyte *data)
+{
+ if (!context->getExtensions().memoryObjectEXT && !context->getExtensions().semaphoreEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ UNIMPLEMENTED();
+ return false;
+}
+
+bool ValidateGetUnsignedBytei_vEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint index,
+ const GLubyte *data)
+{
+ if (!context->getExtensions().memoryObjectEXT && !context->getExtensions().semaphoreEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ UNIMPLEMENTED();
+ return false;
+}
+
+bool ValidateIsMemoryObjectEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ MemoryObjectID memoryObject)
+{
+ if (!context->getExtensions().memoryObjectEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateMemoryObjectParameterivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ MemoryObjectID memoryObject,
+ GLenum pname,
+ const GLint *params)
+{
+ if (!context->getExtensions().memoryObjectEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ const MemoryObject *memory = context->getMemoryObject(memoryObject);
+ if (memory == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMemoryObject);
+ return false;
+ }
+
+ if (memory->isImmutable())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kImmutableMemoryObject);
+ return false;
+ }
+
+ if (!IsValidMemoryObjectParamater(context, entryPoint, pname))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidMemoryObjectParameter);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateTexStorageMem2DEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ MemoryObjectID memory,
+ GLuint64 offset)
+{
+ if (!context->getExtensions().memoryObjectEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ if (context->getClientMajorVersion() < 3)
+ {
+ return ValidateES2TexStorageParametersBase(context, entryPoint, target, levels,
+ internalFormat, width, height);
+ }
+
+ ASSERT(context->getClientMajorVersion() >= 3);
+ return ValidateES3TexStorage2DParameters(context, entryPoint, target, levels, internalFormat,
+ width, height, 1);
+}
+
+bool ValidateTexStorageMem3DEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType target,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ MemoryObjectID memory,
+ GLuint64 offset)
+{
+ if (!context->getExtensions().memoryObjectEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ UNIMPLEMENTED();
+ return false;
+}
+
+bool ValidateImportMemoryFdEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ MemoryObjectID memory,
+ GLuint64 size,
+ HandleType handleType,
+ GLint fd)
+{
+ if (!context->getExtensions().memoryObjectFdEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ switch (handleType)
+ {
+ case HandleType::OpaqueFd:
+ break;
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidHandleType);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateImportMemoryZirconHandleANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ MemoryObjectID memory,
+ GLuint64 size,
+ HandleType handleType,
+ GLuint handle)
+{
+ if (!context->getExtensions().memoryObjectFuchsiaANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ switch (handleType)
+ {
+ case HandleType::ZirconVmo:
+ break;
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidHandleType);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateDeleteSemaphoresEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const SemaphoreID *semaphores)
+{
+ if (!context->getExtensions().semaphoreEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateGenOrDelete(context, entryPoint, n);
+}
+
+bool ValidateGenSemaphoresEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const SemaphoreID *semaphores)
+{
+ if (!context->getExtensions().semaphoreEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateGenOrDelete(context, entryPoint, n);
+}
+
+bool ValidateGetSemaphoreParameterui64vEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ SemaphoreID semaphore,
+ GLenum pname,
+ const GLuint64 *params)
+{
+ if (!context->getExtensions().semaphoreEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ UNIMPLEMENTED();
+ return false;
+}
+
+bool ValidateIsSemaphoreEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ SemaphoreID semaphore)
+{
+ if (!context->getExtensions().semaphoreEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateSemaphoreParameterui64vEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ SemaphoreID semaphore,
+ GLenum pname,
+ const GLuint64 *params)
+{
+ if (!context->getExtensions().semaphoreEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ UNIMPLEMENTED();
+ return false;
+}
+
+bool ValidateSignalSemaphoreEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ SemaphoreID semaphore,
+ GLuint numBufferBarriers,
+ const BufferID *buffers,
+ GLuint numTextureBarriers,
+ const TextureID *textures,
+ const GLenum *dstLayouts)
+{
+ if (!context->getExtensions().semaphoreEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ for (GLuint i = 0; i < numBufferBarriers; ++i)
+ {
+ if (!context->getBuffer(buffers[i]))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidBufferName);
+ return false;
+ }
+ }
+
+ for (GLuint i = 0; i < numTextureBarriers; ++i)
+ {
+ if (!context->getTexture(textures[i]))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidTextureName);
+ return false;
+ }
+ if (!IsValidImageLayout(FromGLenum<ImageLayout>(dstLayouts[i])))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidImageLayout);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateWaitSemaphoreEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ SemaphoreID semaphore,
+ GLuint numBufferBarriers,
+ const BufferID *buffers,
+ GLuint numTextureBarriers,
+ const TextureID *textures,
+ const GLenum *srcLayouts)
+{
+ if (!context->getExtensions().semaphoreEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ for (GLuint i = 0; i < numBufferBarriers; ++i)
+ {
+ if (!context->getBuffer(buffers[i]))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidBufferName);
+ return false;
+ }
+ }
+
+ for (GLuint i = 0; i < numTextureBarriers; ++i)
+ {
+ if (!context->getTexture(textures[i]))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidTextureName);
+ return false;
+ }
+ if (!IsValidImageLayout(FromGLenum<ImageLayout>(srcLayouts[i])))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidImageLayout);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateImportSemaphoreFdEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ SemaphoreID semaphore,
+ HandleType handleType,
+ GLint fd)
+{
+ if (!context->getExtensions().semaphoreFdEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ switch (handleType)
+ {
+ case HandleType::OpaqueFd:
+ break;
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidHandleType);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetSamplerParameterIivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID samplerPacked,
+ GLenum pname,
+ const GLint *params)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+ return ValidateGetSamplerParameterBase(context, entryPoint, samplerPacked, pname, nullptr);
+}
+
+bool ValidateGetSamplerParameterIuivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID samplerPacked,
+ GLenum pname,
+ const GLuint *params)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+ return ValidateGetSamplerParameterBase(context, entryPoint, samplerPacked, pname, nullptr);
+}
+
+bool ValidateGetTexParameterIivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLint *params)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+ return ValidateGetTexParameterBase(context, entryPoint, targetPacked, pname, nullptr);
+}
+
+bool ValidateGetTexParameterIuivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLuint *params)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+ return ValidateGetTexParameterBase(context, entryPoint, targetPacked, pname, nullptr);
+}
+
+bool ValidateSamplerParameterIivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID samplerPacked,
+ GLenum pname,
+ const GLint *param)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+ return ValidateSamplerParameterBase(context, entryPoint, samplerPacked, pname, -1, true, param);
+}
+
+bool ValidateSamplerParameterIuivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID samplerPacked,
+ GLenum pname,
+ const GLuint *param)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+ return ValidateSamplerParameterBase(context, entryPoint, samplerPacked, pname, -1, true, param);
+}
+
+bool ValidateTexParameterIivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLint *params)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+ return ValidateTexParameterBase(context, entryPoint, targetPacked, pname, -1, true, params);
+}
+
+bool ValidateTexParameterIuivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLuint *params)
+{
+ if (context->getClientMajorVersion() < 3)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
+ return false;
+ }
+ return ValidateTexParameterBase(context, entryPoint, targetPacked, pname, -1, true, params);
+}
+
+bool ValidateImportSemaphoreZirconHandleANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ SemaphoreID semaphore,
+ HandleType handleType,
+ GLuint handle)
+{
+ if (!context->getExtensions().semaphoreFuchsiaANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ switch (handleType)
+ {
+ case HandleType::ZirconEvent:
+ break;
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidHandleType);
+ return false;
+ }
+
+ return true;
+}
+
+namespace
+{
+enum class PLSExpectedStatus : bool
+{
+ Inactive,
+ Active
+};
+
+bool ValidatePLSCommon(const Context *context,
+ angle::EntryPoint entryPoint,
+ PLSExpectedStatus expectedStatus)
+{
+ // Check that the pixel local storage extension is enabled at all.
+ if (!context->getExtensions().shaderPixelLocalStorageANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kPLSExtensionNotEnabled);
+ return false;
+ }
+
+ // INVALID_FRAMEBUFFER_OPERATION is generated if the default framebuffer object name 0 is
+ // bound to DRAW_FRAMEBUFFER.
+ if (context->getState().getDrawFramebuffer()->id().value == 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_FRAMEBUFFER_OPERATION,
+ kPLSDefaultFramebufferBound);
+ return false;
+ }
+
+ if (expectedStatus == PLSExpectedStatus::Inactive)
+ {
+ // INVALID_OPERATION is generated if PIXEL_LOCAL_STORAGE_ACTIVE_ANGLE is TRUE.
+ if (context->getState().getPixelLocalStorageActive())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kPLSActive);
+ return false;
+ }
+ }
+ else
+ {
+ ASSERT(expectedStatus == PLSExpectedStatus::Active);
+
+ // INVALID_OPERATION is generated if PIXEL_LOCAL_STORAGE_ACTIVE_ANGLE is FALSE.
+ if (!context->getState().getPixelLocalStorageActive())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kPLSInactive);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidatePLSCommon(const Context *context, angle::EntryPoint entryPoint, GLint plane)
+{
+ if (!ValidatePLSCommon(context, entryPoint, PLSExpectedStatus::Inactive))
+ {
+ return false;
+ }
+
+ // INVALID_VALUE is generated if <plane> < 0 or <plane> >= MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE.
+ if (plane < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kPLSPlaneLessThanZero);
+ return false;
+ }
+ if (plane >= static_cast<GLint>(context->getCaps().maxPixelLocalStoragePlanes))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kPLSPlaneOutOfRange);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidatePLSInternalformat(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum internalformat)
+{
+ // INVALID_ENUM is generated if <internalformat> is not one of the acceptable values in Table
+ // X.2, or NONE.
+ switch (internalformat)
+ {
+ case GL_RGBA8:
+ case GL_RGBA8I:
+ case GL_RGBA8UI:
+ case GL_R32F:
+ case GL_R32UI:
+ return true;
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kPLSInvalidInternalformat);
+ return false;
+ }
+}
+
+bool ValidatePLSTextureType(const Context *context,
+ angle::EntryPoint entryPoint,
+ Texture *tex,
+ size_t *textureDepth)
+{
+ // INVALID_ENUM is generated if <backingtexture> is nonzero and not of type GL_TEXTURE_2D,
+ // GL_TEXTURE_CUBE_MAP, GL_TEXTURE_2D_ARRAY, or GL_TEXTURE_3D.
+ switch (tex->getType())
+ {
+ case TextureType::_2D:
+ *textureDepth = 1;
+ return true;
+ case TextureType::CubeMap:
+ *textureDepth = 6;
+ return true;
+ case TextureType::_2DArray:
+ *textureDepth = tex->getDepth(TextureTarget::_2DArray, 0);
+ return true;
+ case TextureType::_3D:
+ *textureDepth = tex->getDepth(TextureTarget::_3D, 0);
+ return true;
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kPLSInvalidTextureType);
+ return false;
+ }
+}
+
+bool ValidatePLSLoadOperation(const Context *context, angle::EntryPoint entryPoint, GLenum loadop)
+{
+ // INVALID_ENUM is generated if <loadops>[0..<planes>-1] is not one of the Load Operations
+ // enumerated in Table X.1.
+ switch (loadop)
+ {
+ case GL_ZERO:
+ case GL_CLEAR_ANGLE:
+ case GL_KEEP:
+ case GL_DONT_CARE:
+ case GL_DISABLE_ANGLE:
+ return true;
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kPLSInvalidLoadOperation);
+ return false;
+ }
+}
+} // namespace
+
+bool ValidateFramebufferMemorylessPixelLocalStorageANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint plane,
+ GLenum internalformat)
+{
+ if (!ValidatePLSCommon(context, entryPoint, plane))
+ {
+ return false;
+ }
+
+ // INVALID_ENUM is generated if <internalformat> is not one of the acceptable values in Table
+ // X.2, or NONE.
+ if (internalformat != GL_NONE)
+ {
+ if (!ValidatePLSInternalformat(context, entryPoint, internalformat))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateFramebufferTexturePixelLocalStorageANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint plane,
+ TextureID backingtexture,
+ GLint level,
+ GLint layer)
+{
+ if (!ValidatePLSCommon(context, entryPoint, plane))
+ {
+ return false;
+ }
+
+ if (backingtexture.value != 0)
+ {
+ Texture *tex = context->getTexture(backingtexture);
+
+ // INVALID_OPERATION is generated if <backingtexture> is not the name of an existing
+ // immutable texture object, or zero.
+ if (!tex)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidTextureName);
+ return false;
+ }
+ if (!tex->getImmutableFormat())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kTextureIsNotImmutable);
+ return false;
+ }
+
+ // INVALID_ENUM is generated if <backingtexture> is nonzero and not of type GL_TEXTURE_2D,
+ // GL_TEXTURE_CUBE_MAP, GL_TEXTURE_2D_ARRAY, or GL_TEXTURE_3D.
+ size_t textureDepth;
+ if (!ValidatePLSTextureType(context, entryPoint, tex, &textureDepth))
+ {
+ return false;
+ }
+
+ // INVALID_VALUE is generated if <backingtexture> is nonzero and <level> < 0.
+ if (level < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeLevel);
+ return false;
+ }
+
+ // INVALID_VALUE is generated if <backingtexture> is nonzero and <level> >= the
+ // immutable number of mipmap levels in <backingtexture>.
+ if (static_cast<GLuint>(level) >= tex->getImmutableLevels())
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kTextureLevelOutOfRange);
+ return false;
+ }
+
+ // INVALID_VALUE is generated if <backingtexture> is nonzero and <layer> < 0.
+ if (layer < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeLayer);
+ return false;
+ }
+
+ // INVALID_VALUE is generated if <backingtexture> is nonzero and <layer> >= the immutable
+ // number of texture layers in <backingtexture>.
+ if ((size_t)layer >= textureDepth)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kTextureLayerOutOfRange);
+ return false;
+ }
+
+ // INVALID_ENUM is generated if <backingtexture> is nonzero and its internalformat is not
+ // one of the acceptable values in Table X.2.
+ ASSERT(tex->getImmutableFormat());
+ GLenum internalformat = tex->getState().getBaseLevelDesc().format.info->internalFormat;
+ if (!ValidatePLSInternalformat(context, entryPoint, internalformat))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateBeginPixelLocalStorageANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei planes,
+ const GLenum loadops[],
+ const void *cleardata)
+{
+ if (!ValidatePLSCommon(context, entryPoint, PLSExpectedStatus::Inactive))
+ {
+ return false;
+ }
+
+ const State &state = context->getState();
+ const Framebuffer *framebuffer = state.getDrawFramebuffer();
+
+ // INVALID_OPERATION is generated if the value of SAMPLE_BUFFERS is 1 (i.e., if rendering to a
+ // multisampled framebuffer).
+ if (framebuffer->getSamples(context) != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kPLSMultisamplingEnabled);
+ return false;
+ }
+
+ // INVALID_OPERATION is generated if DITHER is enabled.
+ if (state.isDitherEnabled())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kPLSDitherEnabled);
+ return false;
+ }
+
+ // INVALID_OPERATION is generated if RASTERIZER_DISCARD is enabled.
+ if (state.isRasterizerDiscardEnabled())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kPLSRasterizerDiscardEnabled);
+ return false;
+ }
+
+ // INVALID_OPERATION is generated if SAMPLE_ALPHA_TO_COVERAGE is enabled.
+ if (state.isSampleAlphaToCoverageEnabled())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kPLSSampleAlphaToCoverageEnabled);
+ return false;
+ }
+
+ // INVALID_OPERATION is generated if SAMPLE_COVERAGE is enabled.
+ if (state.isSampleCoverageEnabled())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kPLSSampleCoverageEnabled);
+ return false;
+ }
+
+ // INVALID_VALUE is generated if <planes> < 1 or <planes> >
+ // MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE.
+ if (planes < 1)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kPLSPlanesLessThanOne);
+ return false;
+ }
+ if (planes > static_cast<GLsizei>(context->getCaps().maxPixelLocalStoragePlanes))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kPLSPlanesOutOfRange);
+ return false;
+ }
+
+ // INVALID_FRAMEBUFFER_OPERATION is generated if the draw framebuffer has an image attached to
+ // any color attachment point on or after:
+ //
+ // COLOR_ATTACHMENT0 +
+ // MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE_ANGLE
+ //
+ const Caps &caps = context->getCaps();
+ for (int i = caps.maxColorAttachmentsWithActivePixelLocalStorage; i < caps.maxColorAttachments;
+ ++i)
+ {
+ if (framebuffer->getColorAttachment(i))
+ {
+ context->validationError(entryPoint, GL_INVALID_FRAMEBUFFER_OPERATION,
+ kPLSMaxColorAttachmentsExceded);
+ return false;
+ }
+ }
+
+ // INVALID_FRAMEBUFFER_OPERATION is generated if the draw framebuffer has an image attached to
+ // any color attachment point on or after:
+ //
+ // COLOR_ATTACHMENT0 +
+ // MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES_ANGLE -
+ // <planes>
+ //
+ for (GLuint i = caps.maxCombinedDrawBuffersAndPixelLocalStoragePlanes - planes;
+ i < caps.maxColorAttachmentsWithActivePixelLocalStorage; ++i)
+ {
+ if (framebuffer->getColorAttachment(i))
+ {
+ context->validationError(entryPoint, GL_INVALID_FRAMEBUFFER_OPERATION,
+ kPLSMaxCombinedDrawBuffersAndPlanesExceded);
+ return false;
+ }
+ }
+
+ // INVALID_VALUE is generated if <loadops> is NULL.
+ if (!loadops)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kPLSNullLoadOps);
+ return false;
+ }
+
+ const PixelLocalStorage *pls = framebuffer->peekPixelLocalStorage();
+ bool hasTextureBackedPLSPlanes = false;
+ Extents textureBackedPLSExtents{};
+
+ for (int i = 0; i < planes; ++i)
+ {
+ // INVALID_ENUM is generated if <loadops>[0..<planes>-1] is not one of the Load
+ // Operations enumerated in Table X.1.
+ if (!ValidatePLSLoadOperation(context, entryPoint, loadops[i]))
+ {
+ return false;
+ }
+
+ if (loadops[i] == GL_DISABLE_ANGLE)
+ {
+ continue;
+ }
+
+ // INVALID_VALUE is generated if <loadops>[0..<planes>-1] is CLEAR_ANGLE and <cleardata> is
+ // NULL.
+ if (loadops[i] == GL_CLEAR_ANGLE && !cleardata)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kPLSNullClearData);
+ return false;
+ }
+
+ // INVALID_OPERATION is generated if <loadops>[0..<planes>-1] is not DISABLE_ANGLE, and
+ // the pixel local storage plane at that same index is is in a deinitialized state.
+ if (pls == nullptr || pls->getPlane(i).isDeinitialized())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kPLSEnablingDeinitializedPlane);
+ return false;
+ }
+
+ // [ANGLE_shader_pixel_local_storage] Section 4.4.2.X "Configuring Pixel Local Storage
+ // on a Framebuffer": When a texture object is deleted, any pixel local storage plane to
+ // which it was bound is automatically converted to a memoryless plane of matching
+ // internalformat.
+ const PixelLocalStoragePlane &plane = pls->getPlane(i);
+
+ Extents textureExtents;
+ if (plane.getTextureImageExtents(context, &textureExtents))
+ {
+ // INVALID_OPERATION is generated if all enabled, texture-backed pixel local storage
+ // planes do not have the same width and height.
+ if (!hasTextureBackedPLSPlanes)
+ {
+ textureBackedPLSExtents = textureExtents;
+ hasTextureBackedPLSPlanes = true;
+ }
+ else if (textureExtents != textureBackedPLSExtents)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kPLSMismatchedBackingTextureSizes);
+ return false;
+ }
+ }
+ else
+ {
+ // INVALID_OPERATION is generated if <loadops>[0..<planes>-1] is KEEP and the pixel
+ // local storage plane at that same index is memoryless.
+ if (loadops[i] == GL_KEEP)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kPLSKeepingMemorylessPlane);
+ return false;
+ }
+ }
+ }
+
+ const FramebufferAttachment *firstAttachment =
+ framebuffer->getState().getFirstNonNullAttachment();
+ if (firstAttachment)
+ {
+ // INVALID_OPERATION is generated if the draw framebuffer has other attachments, and its
+ // enabled, texture-backed pixel local storage planes do not have identical dimensions
+ // with the rendering area.
+ if (hasTextureBackedPLSPlanes &&
+ textureBackedPLSExtents != framebuffer->getState().getAttachmentExtentsIntersection())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kPLSDimensionsDontMatchRenderingArea);
+ return false;
+ }
+ }
+ else
+ {
+ // INVALID_OPERATION is generated if the draw framebuffer has no attachments and no
+ // enabled, texture-backed pixel local storage planes.
+ if (!hasTextureBackedPLSPlanes)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kPLSNoAttachmentsNoTextureBacked);
+ return false;
+ }
+ }
+
+ // INVALID_OPERATION is generated if a single texture image is bound to more than one pixel
+ // local storage plane.
+ //
+ // TODO(anglebug.com/7279): Block feedback loops
+ //
+
+ // INVALID_OPERATION is generated if a single texture image is simultaneously bound to a pixel
+ // local storage plane and attached to the draw framebuffer.
+ //
+ // TODO(anglebug.com/7279): Block feedback loops
+ //
+
+ return true;
+}
+
+bool ValidateEndPixelLocalStorageANGLE(const Context *context, angle::EntryPoint entryPoint)
+{
+ return ValidatePLSCommon(context, entryPoint, PLSExpectedStatus::Active);
+}
+
+bool ValidatePixelLocalStorageBarrierANGLE(const Context *context, angle::EntryPoint entryPoint)
+{
+ return ValidatePLSCommon(context, entryPoint, PLSExpectedStatus::Active);
+}
+
+bool ValidateFramebufferFetchBarrierEXT(const Context *context, angle::EntryPoint entryPoint)
+{
+ if (!context->getExtensions().shaderFramebufferFetchNonCoherentEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kFramebufferFetchNonCoherentExtensionNotEnabled);
+ return false;
+ }
+ return true;
+}
+
+bool ValidatePatchParameteriEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLint value)
+{
+ if (!context->getExtensions().tessellationShaderEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION,
+ kTessellationShaderExtensionNotEnabled);
+ return false;
+ }
+
+ if (pname != GL_PATCH_VERTICES)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname);
+ return false;
+ }
+
+ if (value <= 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidValueNonPositive);
+ return false;
+ }
+
+ if (value > context->getCaps().maxPatchVertices)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidValueExceedsMaxPatchSize);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateTexStorageMemFlags2DANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ MemoryObjectID memoryPacked,
+ GLuint64 offset,
+ GLbitfield createFlags,
+ GLbitfield usageFlags,
+ const void *imageCreateInfoPNext)
+{
+ if (!context->getExtensions().memoryObjectFlagsANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ if (!ValidateTexStorageMem2DEXT(context, entryPoint, targetPacked, levels, internalFormat,
+ width, height, memoryPacked, offset))
+ {
+ return false;
+ }
+
+ // |createFlags| and |usageFlags| must only have bits specified by the extension.
+ constexpr GLbitfield kAllCreateFlags =
+ GL_CREATE_SPARSE_BINDING_BIT_ANGLE | GL_CREATE_SPARSE_RESIDENCY_BIT_ANGLE |
+ GL_CREATE_SPARSE_ALIASED_BIT_ANGLE | GL_CREATE_MUTABLE_FORMAT_BIT_ANGLE |
+ GL_CREATE_CUBE_COMPATIBLE_BIT_ANGLE | GL_CREATE_ALIAS_BIT_ANGLE |
+ GL_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_ANGLE | GL_CREATE_2D_ARRAY_COMPATIBLE_BIT_ANGLE |
+ GL_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT_ANGLE | GL_CREATE_EXTENDED_USAGE_BIT_ANGLE |
+ GL_CREATE_PROTECTED_BIT_ANGLE | GL_CREATE_DISJOINT_BIT_ANGLE |
+ GL_CREATE_CORNER_SAMPLED_BIT_ANGLE | GL_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_ANGLE |
+ GL_CREATE_SUBSAMPLED_BIT_ANGLE;
+
+ if ((createFlags & ~kAllCreateFlags) != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidExternalCreateFlags);
+ return false;
+ }
+
+ constexpr GLbitfield kAllUsageFlags =
+ GL_USAGE_TRANSFER_SRC_BIT_ANGLE | GL_USAGE_TRANSFER_DST_BIT_ANGLE |
+ GL_USAGE_SAMPLED_BIT_ANGLE | GL_USAGE_STORAGE_BIT_ANGLE |
+ GL_USAGE_COLOR_ATTACHMENT_BIT_ANGLE | GL_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT_ANGLE |
+ GL_USAGE_TRANSIENT_ATTACHMENT_BIT_ANGLE | GL_USAGE_INPUT_ATTACHMENT_BIT_ANGLE |
+ GL_USAGE_SHADING_RATE_IMAGE_BIT_ANGLE | GL_USAGE_FRAGMENT_DENSITY_MAP_BIT_ANGLE;
+
+ if ((usageFlags & ~kAllUsageFlags) != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidExternalUsageFlags);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateTexStorageMemFlags2DMultisampleANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedSampleLocations,
+ MemoryObjectID memoryPacked,
+ GLuint64 offset,
+ GLbitfield createFlags,
+ GLbitfield usageFlags,
+ const void *imageCreateInfoPNext)
+{
+ UNIMPLEMENTED();
+ return false;
+}
+
+bool ValidateTexStorageMemFlags3DANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ MemoryObjectID memoryPacked,
+ GLuint64 offset,
+ GLbitfield createFlags,
+ GLbitfield usageFlags,
+ const void *imageCreateInfoPNext)
+{
+ UNIMPLEMENTED();
+ return false;
+}
+
+bool ValidateTexStorageMemFlags3DMultisampleANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean fixedSampleLocations,
+ MemoryObjectID memoryPacked,
+ GLuint64 offset,
+ GLbitfield createFlags,
+ GLbitfield usageFlags,
+ const void *imageCreateInfoPNext)
+{
+ UNIMPLEMENTED();
+ return false;
+}
+
+// GL_EXT_buffer_storage
+bool ValidateBufferStorageEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding targetPacked,
+ GLsizeiptr size,
+ const void *data,
+ GLbitfield flags)
+{
+ if (!context->isValidBufferBinding(targetPacked))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBufferTypes);
+ return false;
+ }
+
+ if (size <= 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNonPositiveSize);
+ return false;
+ }
+
+ constexpr GLbitfield kAllUsageFlags =
+ (GL_DYNAMIC_STORAGE_BIT_EXT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT |
+ GL_MAP_PERSISTENT_BIT_EXT | GL_MAP_COHERENT_BIT_EXT | GL_CLIENT_STORAGE_BIT_EXT);
+ if ((flags & ~kAllUsageFlags) != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidBufferUsageFlags);
+ return false;
+ }
+
+ if (((flags & GL_MAP_PERSISTENT_BIT_EXT) != 0) &&
+ ((flags & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == 0))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidBufferUsageFlags);
+ return false;
+ }
+
+ if (((flags & GL_MAP_COHERENT_BIT_EXT) != 0) && ((flags & GL_MAP_PERSISTENT_BIT_EXT) == 0))
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidBufferUsageFlags);
+ return false;
+ }
+
+ Buffer *buffer = context->getState().getTargetBuffer(targetPacked);
+
+ if (buffer == nullptr)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferNotBound);
+ return false;
+ }
+
+ if (buffer->isImmutable())
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferImmutable);
+ return false;
+ }
+
+ return true;
+}
+
+// GL_EXT_clip_control
+bool ValidateClipControlEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum origin,
+ GLenum depth)
+{
+ if ((origin != GL_LOWER_LEFT_EXT) && (origin != GL_UPPER_LEFT_EXT))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidOriginEnum);
+ return false;
+ }
+
+ if ((depth != GL_NEGATIVE_ONE_TO_ONE_EXT) && (depth != GL_ZERO_TO_ONE_EXT))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidDepthEnum);
+ return false;
+ }
+
+ return true;
+}
+
+// GL_EXT_external_buffer
+bool ValidateBufferStorageExternalEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding targetPacked,
+ GLintptr offset,
+ GLsizeiptr size,
+ GLeglClientBufferEXT clientBuffer,
+ GLbitfield flags)
+{
+ if (!ValidateBufferStorageEXT(context, entryPoint, targetPacked, size, nullptr, flags))
+ {
+ return false;
+ }
+
+ if (offset != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kExternalBufferInvalidOffset);
+ return false;
+ }
+
+ if (clientBuffer == nullptr && size > 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kClientBufferInvalid);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateNamedBufferStorageExternalEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint buffer,
+ GLintptr offset,
+ GLsizeiptr size,
+ GLeglClientBufferEXT clientBuffer,
+ GLbitfield flags)
+{
+ UNIMPLEMENTED();
+ return false;
+}
+
+// GL_EXT_primitive_bounding_box
+bool ValidatePrimitiveBoundingBoxEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat minX,
+ GLfloat minY,
+ GLfloat minZ,
+ GLfloat minW,
+ GLfloat maxX,
+ GLfloat maxY,
+ GLfloat maxZ,
+ GLfloat maxW)
+{
+ if (!context->getExtensions().primitiveBoundingBoxEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return true;
+}
+
+// GL_OES_primitive_bounding_box
+bool ValidatePrimitiveBoundingBoxOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat minX,
+ GLfloat minY,
+ GLfloat minZ,
+ GLfloat minW,
+ GLfloat maxX,
+ GLfloat maxY,
+ GLfloat maxZ,
+ GLfloat maxW)
+{
+ if (!context->getExtensions().primitiveBoundingBoxOES)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return true;
+}
+
+// GL_EXT_separate_shader_objects
+bool ValidateActiveShaderProgramEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProgramPipelineID pipelinePacked,
+ ShaderProgramID programPacked)
+{
+ if (!context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateActiveShaderProgramBase(context, entryPoint, pipelinePacked, programPacked);
+}
+
+bool ValidateBindProgramPipelineEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProgramPipelineID pipelinePacked)
+{
+ if (!context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateBindProgramPipelineBase(context, entryPoint, pipelinePacked);
+}
+
+bool ValidateCreateShaderProgramvEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderType typePacked,
+ GLsizei count,
+ const GLchar **strings)
+{
+ if (!context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateCreateShaderProgramvBase(context, entryPoint, typePacked, count, strings);
+}
+
+bool ValidateDeleteProgramPipelinesEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const ProgramPipelineID *pipelinesPacked)
+{
+ if (!context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateDeleteProgramPipelinesBase(context, entryPoint, n, pipelinesPacked);
+}
+
+bool ValidateGenProgramPipelinesEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const ProgramPipelineID *pipelinesPacked)
+{
+ if (!context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateGenProgramPipelinesBase(context, entryPoint, n, pipelinesPacked);
+}
+
+bool ValidateGetProgramPipelineInfoLogEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProgramPipelineID pipelinePacked,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLchar *infoLog)
+{
+ if (!context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateGetProgramPipelineInfoLogBase(context, entryPoint, pipelinePacked, bufSize,
+ length, infoLog);
+}
+
+bool ValidateGetProgramPipelineivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProgramPipelineID pipelinePacked,
+ GLenum pname,
+ const GLint *params)
+{
+ if (!context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateGetProgramPipelineivBase(context, entryPoint, pipelinePacked, pname, params);
+}
+
+bool ValidateIsProgramPipelineEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProgramPipelineID pipelinePacked)
+{
+ if (!context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateIsProgramPipelineBase(context, entryPoint, pipelinePacked);
+}
+
+bool ValidateProgramParameteriEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ GLenum pname,
+ GLint value)
+{
+ if (!context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateProgramParameteriBase(context, entryPoint, programPacked, pname, value);
+}
+
+bool ValidateProgramUniform1fEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLfloat v0)
+{
+ if (!context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateProgramUniform1fBase(context, entryPoint, programPacked, locationPacked, v0);
+}
+
+bool ValidateProgramUniform1fvEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value)
+{
+ if (!context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateProgramUniform1fvBase(context, entryPoint, programPacked, locationPacked, count,
+ value);
+}
+
+bool ValidateProgramUniform1iEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLint v0)
+{
+ if (!context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateProgramUniform1iBase(context, entryPoint, programPacked, locationPacked, v0);
+}
+
+bool ValidateProgramUniform1ivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value)
+{
+ if (!context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateProgramUniform1ivBase(context, entryPoint, programPacked, locationPacked, count,
+ value);
+}
+
+bool ValidateProgramUniform1uiEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLuint v0)
+{
+ if (!context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateProgramUniform1uiBase(context, entryPoint, programPacked, locationPacked, v0);
+}
+
+bool ValidateProgramUniform1uivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value)
+{
+ if (!context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateProgramUniform1uivBase(context, entryPoint, programPacked, locationPacked, count,
+ value);
+}
+
+bool ValidateProgramUniform2fEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLfloat v0,
+ GLfloat v1)
+{
+ if (!context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateProgramUniform2fBase(context, entryPoint, programPacked, locationPacked, v0, v1);
+}
+
+bool ValidateProgramUniform2fvEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value)
+{
+ if (!context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateProgramUniform2fvBase(context, entryPoint, programPacked, locationPacked, count,
+ value);
+}
+
+bool ValidateProgramUniform2iEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLint v0,
+ GLint v1)
+{
+ if (!context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateProgramUniform2iBase(context, entryPoint, programPacked, locationPacked, v0, v1);
+}
+
+bool ValidateProgramUniform2ivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value)
+{
+ if (!context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateProgramUniform2ivBase(context, entryPoint, programPacked, locationPacked, count,
+ value);
+}
+
+bool ValidateProgramUniform2uiEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLuint v0,
+ GLuint v1)
+{
+ if (!context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateProgramUniform2uiBase(context, entryPoint, programPacked, locationPacked, v0,
+ v1);
+}
+
+bool ValidateProgramUniform2uivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value)
+{
+ if (!context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateProgramUniform2uivBase(context, entryPoint, programPacked, locationPacked, count,
+ value);
+}
+
+bool ValidateProgramUniform3fEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLfloat v0,
+ GLfloat v1,
+ GLfloat v2)
+{
+ if (!context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateProgramUniform3fBase(context, entryPoint, programPacked, locationPacked, v0, v1,
+ v2);
+}
+
+bool ValidateProgramUniform3fvEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value)
+{
+ if (!context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateProgramUniform3fvBase(context, entryPoint, programPacked, locationPacked, count,
+ value);
+}
+
+bool ValidateProgramUniform3iEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLint v0,
+ GLint v1,
+ GLint v2)
+{
+ if (!context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateProgramUniform3iBase(context, entryPoint, programPacked, locationPacked, v0, v1,
+ v2);
+}
+
+bool ValidateProgramUniform3ivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value)
+{
+ if (!context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateProgramUniform3ivBase(context, entryPoint, programPacked, locationPacked, count,
+ value);
+}
+
+bool ValidateProgramUniform3uiEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLuint v0,
+ GLuint v1,
+ GLuint v2)
+{
+ if (!context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateProgramUniform3uiBase(context, entryPoint, programPacked, locationPacked, v0, v1,
+ v2);
+}
+
+bool ValidateProgramUniform3uivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value)
+{
+ if (!context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateProgramUniform3uivBase(context, entryPoint, programPacked, locationPacked, count,
+ value);
+}
+
+bool ValidateProgramUniform4fEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLfloat v0,
+ GLfloat v1,
+ GLfloat v2,
+ GLfloat v3)
+{
+ if (!context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateProgramUniform4fBase(context, entryPoint, programPacked, locationPacked, v0, v1,
+ v2, v3);
+}
+
+bool ValidateProgramUniform4fvEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value)
+{
+ if (!context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateProgramUniform4fvBase(context, entryPoint, programPacked, locationPacked, count,
+ value);
+}
+
+bool ValidateProgramUniform4iEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLint v0,
+ GLint v1,
+ GLint v2,
+ GLint v3)
+{
+ if (!context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateProgramUniform4iBase(context, entryPoint, programPacked, locationPacked, v0, v1,
+ v2, v3);
+}
+
+bool ValidateProgramUniform4ivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value)
+{
+ return ValidateProgramUniform4ivBase(context, entryPoint, programPacked, locationPacked, count,
+ value);
+}
+
+bool ValidateProgramUniform4uiEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLuint v0,
+ GLuint v1,
+ GLuint v2,
+ GLuint v3)
+{
+ if (!context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateProgramUniform4uiBase(context, entryPoint, programPacked, locationPacked, v0, v1,
+ v2, v3);
+}
+
+bool ValidateProgramUniform4uivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value)
+{
+ return ValidateProgramUniform4uivBase(context, entryPoint, programPacked, locationPacked, count,
+ value);
+}
+
+bool ValidateProgramUniformMatrix2fvEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ if (!context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateProgramUniformMatrix2fvBase(context, entryPoint, programPacked, locationPacked,
+ count, transpose, value);
+}
+
+bool ValidateProgramUniformMatrix2x3fvEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ if (!context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateProgramUniformMatrix2x3fvBase(context, entryPoint, programPacked, locationPacked,
+ count, transpose, value);
+}
+
+bool ValidateProgramUniformMatrix2x4fvEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ if (!context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateProgramUniformMatrix2x4fvBase(context, entryPoint, programPacked, locationPacked,
+ count, transpose, value);
+}
+
+bool ValidateProgramUniformMatrix3fvEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ if (!context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateProgramUniformMatrix3fvBase(context, entryPoint, programPacked, locationPacked,
+ count, transpose, value);
+}
+
+bool ValidateProgramUniformMatrix3x2fvEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ if (!context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateProgramUniformMatrix3x2fvBase(context, entryPoint, programPacked, locationPacked,
+ count, transpose, value);
+}
+
+bool ValidateProgramUniformMatrix3x4fvEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ if (!context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateProgramUniformMatrix3x4fvBase(context, entryPoint, programPacked, locationPacked,
+ count, transpose, value);
+}
+
+bool ValidateProgramUniformMatrix4fvEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ if (!context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateProgramUniformMatrix4fvBase(context, entryPoint, programPacked, locationPacked,
+ count, transpose, value);
+}
+
+bool ValidateProgramUniformMatrix4x2fvEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ if (!context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateProgramUniformMatrix4x2fvBase(context, entryPoint, programPacked, locationPacked,
+ count, transpose, value);
+}
+
+bool ValidateProgramUniformMatrix4x3fvEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ if (!context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateProgramUniformMatrix4x3fvBase(context, entryPoint, programPacked, locationPacked,
+ count, transpose, value);
+}
+
+bool ValidateUseProgramStagesEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProgramPipelineID pipelinePacked,
+ GLbitfield stages,
+ ShaderProgramID programPacked)
+{
+ if (!context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateUseProgramStagesBase(context, entryPoint, pipelinePacked, stages, programPacked);
+}
+
+bool ValidateValidateProgramPipelineEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProgramPipelineID pipelinePacked)
+{
+ if (!context->getExtensions().separateShaderObjectsEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateValidateProgramPipelineBase(context, entryPoint, pipelinePacked);
+}
+
+// GL_EXT_debug_label
+bool ValidateGetObjectLabelEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ GLuint object,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLchar *label)
+{
+ if (!context->getExtensions().debugLabelEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ if (bufSize < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBufferSize);
+ return false;
+ }
+
+ return ValidateObjectIdentifierAndName(context, entryPoint, type, object);
+}
+
+bool ValidateLabelObjectEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ GLuint object,
+ GLsizei length,
+ const GLchar *label)
+{
+ if (!context->getExtensions().debugLabelEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ if (length < 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeLength);
+ return false;
+ }
+
+ return ValidateObjectIdentifierAndName(context, entryPoint, type, object);
+}
+
+bool ValidateEGLImageTargetTextureStorageEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint texture,
+ GLeglImageOES image,
+ const GLint *attrib_list)
+{
+ UNREACHABLE();
+ return false;
+}
+
+bool ValidateEGLImageTargetTexStorageEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLeglImageOES image,
+ const GLint *attrib_list)
+{
+ if (!context->getExtensions().EGLImageStorageEXT)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ gl::TextureType targetType = FromGLenum<TextureType>(target);
+ switch (targetType)
+ {
+ case TextureType::External:
+ if (!context->getExtensions().EGLImageExternalOES)
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported,
+ ToGLenum(targetType));
+ }
+ break;
+ case TextureType::CubeMapArray:
+ if (!context->getExtensions().textureCubeMapArrayAny())
+ {
+ context->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported,
+ ToGLenum(targetType));
+ }
+ break;
+ case TextureType::_2D:
+ case TextureType::_2DArray:
+ case TextureType::_3D:
+ case TextureType::CubeMap:
+ break;
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidTextureTarget);
+ return false;
+ }
+
+ // Validate egl source image is valid
+ egl::Image *imageObject = static_cast<egl::Image *>(image);
+ if (!ValidateEGLImageObject(context, entryPoint, targetType, image))
+ {
+ return false;
+ }
+
+ // attrib list validation
+ if (attrib_list != nullptr && attrib_list[0] != GL_NONE)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kAttributeListNotNull);
+ return false;
+ }
+
+ GLsizei levelCount = imageObject->getLevelCount();
+ Extents size = imageObject->getExtents();
+ GLsizei width = static_cast<GLsizei>(size.width);
+ GLsizei height = static_cast<GLsizei>(size.height);
+ GLsizei depth = static_cast<GLsizei>(size.depth);
+ GLenum internalformat = imageObject->getFormat().info->sizedInternalFormat;
+
+ if (width < 1 || height < 1 || depth < 1 || levelCount < 1)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kTextureSizeTooSmall);
+ return false;
+ }
+
+ if (!ValidateES3TexStorageParametersLevel(context, entryPoint, targetType, levelCount, width,
+ height, depth))
+ {
+ // Error already generated.
+ return false;
+ }
+
+ if (targetType == TextureType::External)
+ {
+ const Caps &caps = context->getCaps();
+ if (width > caps.max2DTextureSize || height > caps.max2DTextureSize)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kResourceMaxTextureSize);
+ return false;
+ }
+ }
+ else if (!ValidateES3TexStorageParametersExtent(context, entryPoint, targetType, levelCount,
+ width, height, depth))
+ {
+ // Error already generated.
+ return false;
+ }
+
+ if (!ValidateES3TexStorageParametersTexObject(context, entryPoint, targetType))
+ {
+ // Error already generated.
+ return false;
+ }
+
+ if (!ValidateES3TexStorageParametersFormat(context, entryPoint, targetType, levelCount,
+ internalformat, width, height, depth))
+ {
+ // Error already generated.
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateAcquireTexturesANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint numTextures,
+ const TextureID *textures,
+ const GLenum *layouts)
+{
+ if (!context->getExtensions().vulkanImageANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ for (GLuint i = 0; i < numTextures; ++i)
+ {
+ if (!context->getTexture(textures[i]))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidTextureName);
+ return false;
+ }
+ if (!IsValidImageLayout(FromGLenum<ImageLayout>(layouts[i])))
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidImageLayout);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateReleaseTexturesANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint numTextures,
+ const TextureID *textures,
+ const GLenum *layouts)
+{
+ if (!context->getExtensions().vulkanImageANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+ for (GLuint i = 0; i < numTextures; ++i)
+ {
+ if (!context->getTexture(textures[i]))
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidTextureName);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateFramebufferParameteriMESA(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum pname,
+ GLint param)
+{
+ if (pname != GL_FRAMEBUFFER_FLIP_Y_MESA)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname);
+ return false;
+ }
+ return ValidateFramebufferParameteriBase(context, entryPoint, target, pname, param);
+}
+
+bool ValidateGetFramebufferParameterivMESA(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum pname,
+ const GLint *params)
+{
+ if (pname != GL_FRAMEBUFFER_FLIP_Y_MESA)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname);
+ return false;
+ }
+ return ValidateGetFramebufferParameterivBase(context, entryPoint, target, pname, params);
+}
+
+// GL_AMD_performance_monitor
+bool ValidateBeginPerfMonitorAMD(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint monitor)
+{
+ if (!context->getExtensions().performanceMonitorAMD)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ UNIMPLEMENTED();
+ return false;
+}
+
+bool ValidateDeletePerfMonitorsAMD(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const GLuint *monitors)
+{
+ if (!context->getExtensions().performanceMonitorAMD)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ UNIMPLEMENTED();
+ return false;
+}
+
+bool ValidateEndPerfMonitorAMD(const Context *context, angle::EntryPoint entryPoint, GLuint monitor)
+{
+ if (!context->getExtensions().performanceMonitorAMD)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ UNIMPLEMENTED();
+ return false;
+}
+
+bool ValidateGenPerfMonitorsAMD(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const GLuint *monitors)
+{
+ if (!context->getExtensions().performanceMonitorAMD)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ UNIMPLEMENTED();
+ return false;
+}
+
+bool ValidateGetPerfMonitorCounterDataAMD(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint monitor,
+ GLenum pname,
+ GLsizei dataSize,
+ const GLuint *data,
+ const GLint *bytesWritten)
+{
+ if (!context->getExtensions().performanceMonitorAMD)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ if (monitor != 0)
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidPerfMonitor);
+ return false;
+ }
+
+ switch (pname)
+ {
+ case GL_PERFMON_RESULT_AVAILABLE_AMD:
+ case GL_PERFMON_RESULT_SIZE_AMD:
+ case GL_PERFMON_RESULT_AMD:
+ break;
+
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetPerfMonitorCounterInfoAMD(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint group,
+ GLuint counter,
+ GLenum pname,
+ const void *data)
+{
+ if (!context->getExtensions().performanceMonitorAMD)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ const angle::PerfMonitorCounterGroups &groups = context->getPerfMonitorCounterGroups();
+
+ if (group >= groups.size())
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidPerfMonitorGroup);
+ return false;
+ }
+
+ if (counter >= groups[group].counters.size())
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidPerfMonitorCounter);
+ return false;
+ }
+
+ switch (pname)
+ {
+ case GL_COUNTER_TYPE_AMD:
+ case GL_COUNTER_RANGE_AMD:
+ break;
+
+ default:
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetPerfMonitorCounterStringAMD(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint group,
+ GLuint counter,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLchar *counterString)
+{
+ if (!context->getExtensions().performanceMonitorAMD)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ const angle::PerfMonitorCounterGroups &groups = context->getPerfMonitorCounterGroups();
+
+ if (group >= groups.size())
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidPerfMonitorGroup);
+ return false;
+ }
+
+ if (counter >= groups[group].counters.size())
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidPerfMonitorCounter);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetPerfMonitorCountersAMD(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint group,
+ const GLint *numCounters,
+ const GLint *maxActiveCounters,
+ GLsizei counterSize,
+ const GLuint *counters)
+{
+ if (!context->getExtensions().performanceMonitorAMD)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ const angle::PerfMonitorCounterGroups &groups = context->getPerfMonitorCounterGroups();
+
+ if (group >= groups.size())
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidPerfMonitorGroup);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetPerfMonitorGroupStringAMD(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint group,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLchar *groupString)
+{
+ if (!context->getExtensions().performanceMonitorAMD)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ const angle::PerfMonitorCounterGroups &groups = context->getPerfMonitorCounterGroups();
+
+ if (group >= groups.size())
+ {
+ context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidPerfMonitorGroup);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateGetPerfMonitorGroupsAMD(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLint *numGroups,
+ GLsizei groupsSize,
+ const GLuint *groups)
+{
+ if (!context->getExtensions().performanceMonitorAMD)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateSelectPerfMonitorCountersAMD(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint monitor,
+ GLboolean enable,
+ GLuint group,
+ GLint numCounters,
+ const GLuint *counterList)
+{
+ if (!context->getExtensions().performanceMonitorAMD)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ UNIMPLEMENTED();
+ return false;
+}
+
+bool ValidateShadingRateQCOM(const Context *context, angle::EntryPoint entryPoint, GLenum rate)
+{
+ if (!context->getExtensions().shadingRateQCOM)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ gl::ShadingRate shadingRate = gl::FromGLenum<gl::ShadingRate>(rate);
+ if (shadingRate == gl::ShadingRate::Undefined || shadingRate == gl::ShadingRate::InvalidEnum)
+ {
+ context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidShadingRate);
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateLogicOpANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ LogicalOperation opcodePacked)
+{
+ if (!context->getExtensions().logicOpANGLE)
+ {
+ context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
+ return false;
+ }
+
+ return ValidateLogicOpCommon(context, entryPoint, opcodePacked);
+}
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/validationESEXT.h b/gfx/angle/checkout/src/libANGLE/validationESEXT.h
new file mode 100644
index 0000000000..b22ed4e379
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/validationESEXT.h
@@ -0,0 +1,20 @@
+//
+// Copyright 2018 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.
+//
+// validationESEXT.h:
+// Inlined validation functions for OpenGL ES extension entry points.
+
+#ifndef LIBANGLE_VALIDATION_ESEXT_H_
+#define LIBANGLE_VALIDATION_ESEXT_H_
+
+#include "libANGLE/ErrorStrings.h"
+#include "libANGLE/validationESEXT_autogen.h"
+
+namespace gl
+{
+// Nothing here yet.
+} // namespace gl
+
+#endif // LIBANGLE_VALIDATION_ESEXT_H_
diff --git a/gfx/angle/checkout/src/libANGLE/validationESEXT_autogen.h b/gfx/angle/checkout/src/libANGLE/validationESEXT_autogen.h
new file mode 100644
index 0000000000..47be44ab2f
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/validationESEXT_autogen.h
@@ -0,0 +1,2646 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml and gl_angle_ext.xml.
+//
+// Copyright 2020 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.
+//
+// validationESEXT_autogen.h:
+// Validation functions for the OpenGL ES extension entry points.
+
+#ifndef LIBANGLE_VALIDATION_ESEXT_AUTOGEN_H_
+#define LIBANGLE_VALIDATION_ESEXT_AUTOGEN_H_
+
+#include "common/PackedEnums.h"
+#include "common/entry_points_enum_autogen.h"
+
+namespace gl
+{
+class Context;
+
+// GL_AMD_performance_monitor
+bool ValidateBeginPerfMonitorAMD(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint monitor);
+bool ValidateDeletePerfMonitorsAMD(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const GLuint *monitors);
+bool ValidateEndPerfMonitorAMD(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint monitor);
+bool ValidateGenPerfMonitorsAMD(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const GLuint *monitors);
+bool ValidateGetPerfMonitorCounterDataAMD(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint monitor,
+ GLenum pname,
+ GLsizei dataSize,
+ const GLuint *data,
+ const GLint *bytesWritten);
+bool ValidateGetPerfMonitorCounterInfoAMD(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint group,
+ GLuint counter,
+ GLenum pname,
+ const void *data);
+bool ValidateGetPerfMonitorCounterStringAMD(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint group,
+ GLuint counter,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLchar *counterString);
+bool ValidateGetPerfMonitorCountersAMD(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint group,
+ const GLint *numCounters,
+ const GLint *maxActiveCounters,
+ GLsizei counterSize,
+ const GLuint *counters);
+bool ValidateGetPerfMonitorGroupStringAMD(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint group,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLchar *groupString);
+bool ValidateGetPerfMonitorGroupsAMD(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLint *numGroups,
+ GLsizei groupsSize,
+ const GLuint *groups);
+bool ValidateSelectPerfMonitorCountersAMD(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint monitor,
+ GLboolean enable,
+ GLuint group,
+ GLint numCounters,
+ const GLuint *counterList);
+
+// GL_ANDROID_extension_pack_es31a
+
+// GL_ANGLE_base_vertex_base_instance
+bool ValidateDrawArraysInstancedBaseInstanceANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ GLint first,
+ GLsizei count,
+ GLsizei instanceCount,
+ GLuint baseInstance);
+bool ValidateDrawElementsInstancedBaseVertexBaseInstanceANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const GLvoid *indices,
+ GLsizei instanceCount,
+ GLint baseVertex,
+ GLuint baseInstance);
+bool ValidateMultiDrawArraysInstancedBaseInstanceANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ const GLint *firsts,
+ const GLsizei *counts,
+ const GLsizei *instanceCounts,
+ const GLuint *baseInstances,
+ GLsizei drawcount);
+bool ValidateMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ const GLsizei *counts,
+ DrawElementsType typePacked,
+ const GLvoid *const *indices,
+ const GLsizei *instanceCounts,
+ const GLint *baseVertices,
+ const GLuint *baseInstances,
+ GLsizei drawcount);
+
+// GL_ANGLE_copy_texture_3d
+bool ValidateCopyTexture3DANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID sourceIdPacked,
+ GLint sourceLevel,
+ TextureTarget destTargetPacked,
+ TextureID destIdPacked,
+ GLint destLevel,
+ GLint internalFormat,
+ GLenum destType,
+ GLboolean unpackFlipY,
+ GLboolean unpackPremultiplyAlpha,
+ GLboolean unpackUnmultiplyAlpha);
+bool ValidateCopySubTexture3DANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID sourceIdPacked,
+ GLint sourceLevel,
+ TextureTarget destTargetPacked,
+ TextureID destIdPacked,
+ GLint destLevel,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLint x,
+ GLint y,
+ GLint z,
+ GLint width,
+ GLint height,
+ GLint depth,
+ GLboolean unpackFlipY,
+ GLboolean unpackPremultiplyAlpha,
+ GLboolean unpackUnmultiplyAlpha);
+
+// GL_ANGLE_depth_texture
+
+// GL_ANGLE_framebuffer_blit
+bool ValidateBlitFramebufferANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint srcX0,
+ GLint srcY0,
+ GLint srcX1,
+ GLint srcY1,
+ GLint dstX0,
+ GLint dstY0,
+ GLint dstX1,
+ GLint dstY1,
+ GLbitfield mask,
+ GLenum filter);
+
+// GL_ANGLE_framebuffer_multisample
+bool ValidateRenderbufferStorageMultisampleANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height);
+
+// GL_ANGLE_get_image
+bool ValidateGetTexImageANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum format,
+ GLenum type,
+ const void *pixels);
+bool ValidateGetCompressedTexImageANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget targetPacked,
+ GLint level,
+ const void *pixels);
+bool ValidateGetRenderbufferImageANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum format,
+ GLenum type,
+ const void *pixels);
+
+// GL_ANGLE_get_tex_level_parameter
+bool ValidateGetTexLevelParameterivANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum pname,
+ const GLint *params);
+bool ValidateGetTexLevelParameterfvANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum pname,
+ const GLfloat *params);
+
+// GL_ANGLE_instanced_arrays
+bool ValidateDrawArraysInstancedANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ GLint first,
+ GLsizei count,
+ GLsizei primcount);
+bool ValidateDrawElementsInstancedANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLsizei primcount);
+bool ValidateVertexAttribDivisorANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLuint divisor);
+
+// GL_ANGLE_logic_op
+bool ValidateLogicOpANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ LogicalOperation opcodePacked);
+
+// GL_ANGLE_memory_object_flags
+bool ValidateTexStorageMemFlags2DANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ MemoryObjectID memoryPacked,
+ GLuint64 offset,
+ GLbitfield createFlags,
+ GLbitfield usageFlags,
+ const void *imageCreateInfoPNext);
+bool ValidateTexStorageMemFlags2DMultisampleANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedSampleLocations,
+ MemoryObjectID memoryPacked,
+ GLuint64 offset,
+ GLbitfield createFlags,
+ GLbitfield usageFlags,
+ const void *imageCreateInfoPNext);
+bool ValidateTexStorageMemFlags3DANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ MemoryObjectID memoryPacked,
+ GLuint64 offset,
+ GLbitfield createFlags,
+ GLbitfield usageFlags,
+ const void *imageCreateInfoPNext);
+bool ValidateTexStorageMemFlags3DMultisampleANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean fixedSampleLocations,
+ MemoryObjectID memoryPacked,
+ GLuint64 offset,
+ GLbitfield createFlags,
+ GLbitfield usageFlags,
+ const void *imageCreateInfoPNext);
+
+// GL_ANGLE_memory_object_fuchsia
+bool ValidateImportMemoryZirconHandleANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ MemoryObjectID memoryPacked,
+ GLuint64 size,
+ HandleType handleTypePacked,
+ GLuint handle);
+
+// GL_ANGLE_multi_draw
+bool ValidateMultiDrawArraysANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ const GLint *firsts,
+ const GLsizei *counts,
+ GLsizei drawcount);
+bool ValidateMultiDrawArraysInstancedANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ const GLint *firsts,
+ const GLsizei *counts,
+ const GLsizei *instanceCounts,
+ GLsizei drawcount);
+bool ValidateMultiDrawElementsANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ const GLsizei *counts,
+ DrawElementsType typePacked,
+ const GLvoid *const *indices,
+ GLsizei drawcount);
+bool ValidateMultiDrawElementsInstancedANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ const GLsizei *counts,
+ DrawElementsType typePacked,
+ const GLvoid *const *indices,
+ const GLsizei *instanceCounts,
+ GLsizei drawcount);
+
+// GL_ANGLE_pack_reverse_row_order
+
+// GL_ANGLE_program_binary
+
+// GL_ANGLE_provoking_vertex
+bool ValidateProvokingVertexANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProvokingVertexConvention modePacked);
+
+// GL_ANGLE_request_extension
+bool ValidateRequestExtensionANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLchar *name);
+bool ValidateDisableExtensionANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLchar *name);
+
+// GL_ANGLE_robust_client_memory
+bool ValidateGetBooleanvRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLboolean *params);
+bool ValidateGetBufferParameterivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params);
+bool ValidateGetFloatvRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLfloat *params);
+bool ValidateGetFramebufferAttachmentParameterivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params);
+bool ValidateGetIntegervRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *data);
+bool ValidateGetProgramivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params);
+bool ValidateGetRenderbufferParameterivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params);
+bool ValidateGetShaderivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID shaderPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params);
+bool ValidateGetTexParameterfvRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLfloat *params);
+bool ValidateGetTexParameterivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params);
+bool ValidateGetUniformfvRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLfloat *params);
+bool ValidateGetUniformivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params);
+bool ValidateGetVertexAttribfvRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLfloat *params);
+bool ValidateGetVertexAttribivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params);
+bool ValidateGetVertexAttribPointervRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ void *const *pointer);
+bool ValidateReadPixelsRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLsizei *columns,
+ const GLsizei *rows,
+ const void *pixels);
+bool ValidateTexImage2DRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *pixels);
+bool ValidateTexParameterfvRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLfloat *params);
+bool ValidateTexParameterivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLint *params);
+bool ValidateTexSubImage2DRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *pixels);
+bool ValidateTexImage3DRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *pixels);
+bool ValidateTexSubImage3DRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *pixels);
+bool ValidateCompressedTexImage2DRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLsizei imageSize,
+ GLsizei dataSize,
+ const GLvoid *data);
+bool ValidateCompressedTexSubImage2DRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget targetPacked,
+ GLint level,
+ GLsizei xoffset,
+ GLsizei yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLsizei imageSize,
+ GLsizei dataSize,
+ const GLvoid *data);
+bool ValidateCompressedTexImage3DRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLsizei imageSize,
+ GLsizei dataSize,
+ const GLvoid *data);
+bool ValidateCompressedTexSubImage3DRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLsizei imageSize,
+ GLsizei dataSize,
+ const GLvoid *data);
+bool ValidateGetQueryivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryType targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params);
+bool ValidateGetQueryObjectuivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID idPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLuint *params);
+bool ValidateGetBufferPointervRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ void *const *params);
+bool ValidateGetIntegeri_vRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint index,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *data);
+bool ValidateGetInternalformativRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum internalformat,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params);
+bool ValidateGetVertexAttribIivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params);
+bool ValidateGetVertexAttribIuivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLuint *params);
+bool ValidateGetUniformuivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLuint *params);
+bool ValidateGetActiveUniformBlockivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformBlockIndex uniformBlockIndexPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params);
+bool ValidateGetInteger64vRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint64 *data);
+bool ValidateGetInteger64i_vRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint index,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint64 *data);
+bool ValidateGetBufferParameteri64vRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint64 *params);
+bool ValidateSamplerParameterivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID samplerPacked,
+ GLuint pname,
+ GLsizei bufSize,
+ const GLint *param);
+bool ValidateSamplerParameterfvRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLfloat *param);
+bool ValidateGetSamplerParameterivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params);
+bool ValidateGetSamplerParameterfvRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLfloat *params);
+bool ValidateGetFramebufferParameterivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params);
+bool ValidateGetProgramInterfaceivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ GLenum programInterface,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params);
+bool ValidateGetBooleani_vRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint index,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLboolean *data);
+bool ValidateGetMultisamplefvRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLuint index,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLfloat *val);
+bool ValidateGetTexLevelParameterivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params);
+bool ValidateGetTexLevelParameterfvRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLfloat *params);
+bool ValidateGetPointervRobustANGLERobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ void *const *params);
+bool ValidateReadnPixelsRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLsizei *columns,
+ const GLsizei *rows,
+ const void *data);
+bool ValidateGetnUniformfvRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLfloat *params);
+bool ValidateGetnUniformivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params);
+bool ValidateGetnUniformuivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLuint *params);
+bool ValidateTexParameterIivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLint *params);
+bool ValidateTexParameterIuivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLuint *params);
+bool ValidateGetTexParameterIivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params);
+bool ValidateGetTexParameterIuivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLuint *params);
+bool ValidateSamplerParameterIivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLint *param);
+bool ValidateSamplerParameterIuivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLuint *param);
+bool ValidateGetSamplerParameterIivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params);
+bool ValidateGetSamplerParameterIuivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID samplerPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLuint *params);
+bool ValidateGetQueryObjectivRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID idPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint *params);
+bool ValidateGetQueryObjecti64vRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID idPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLint64 *params);
+bool ValidateGetQueryObjectui64vRobustANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID idPacked,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLuint64 *params);
+
+// GL_ANGLE_robust_resource_initialization
+
+// GL_ANGLE_semaphore_fuchsia
+bool ValidateImportSemaphoreZirconHandleANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ SemaphoreID semaphorePacked,
+ HandleType handleTypePacked,
+ GLuint handle);
+
+// GL_ANGLE_shader_pixel_local_storage
+bool ValidateFramebufferMemorylessPixelLocalStorageANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint plane,
+ GLenum internalformat);
+bool ValidateFramebufferTexturePixelLocalStorageANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint plane,
+ TextureID backingtexturePacked,
+ GLint level,
+ GLint layer);
+bool ValidateBeginPixelLocalStorageANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei planes,
+ const GLenum *loadops,
+ const void *cleardata);
+bool ValidateEndPixelLocalStorageANGLE(const Context *context, angle::EntryPoint entryPoint);
+bool ValidatePixelLocalStorageBarrierANGLE(const Context *context, angle::EntryPoint entryPoint);
+
+// GL_ANGLE_texture_compression_dxt3
+
+// GL_ANGLE_texture_compression_dxt5
+
+// GL_ANGLE_texture_external_update
+bool ValidateTexImage2DExternalANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLenum format,
+ GLenum type);
+bool ValidateInvalidateTextureANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked);
+
+// GL_ANGLE_texture_multisample
+bool ValidateTexStorage2DMultisampleANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedsamplelocations);
+bool ValidateGetMultisamplefvANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLuint index,
+ const GLfloat *val);
+bool ValidateSampleMaskiANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint maskNumber,
+ GLbitfield mask);
+
+// GL_ANGLE_texture_usage
+
+// GL_ANGLE_translated_shader_source
+bool ValidateGetTranslatedShaderSourceANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID shaderPacked,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLchar *source);
+
+// GL_ANGLE_vulkan_image
+bool ValidateAcquireTexturesANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint numTextures,
+ const TextureID *texturesPacked,
+ const GLenum *layouts);
+bool ValidateReleaseTexturesANGLE(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint numTextures,
+ const TextureID *texturesPacked,
+ const GLenum *layouts);
+
+// GL_APPLE_clip_distance
+
+// GL_ARB_sync
+
+// GL_CHROMIUM_bind_uniform_location
+bool ValidateBindUniformLocationCHROMIUM(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ const GLchar *name);
+
+// GL_CHROMIUM_copy_compressed_texture
+bool ValidateCompressedCopyTextureCHROMIUM(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID sourceIdPacked,
+ TextureID destIdPacked);
+
+// GL_CHROMIUM_copy_texture
+bool ValidateCopyTextureCHROMIUM(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID sourceIdPacked,
+ GLint sourceLevel,
+ TextureTarget destTargetPacked,
+ TextureID destIdPacked,
+ GLint destLevel,
+ GLint internalFormat,
+ GLenum destType,
+ GLboolean unpackFlipY,
+ GLboolean unpackPremultiplyAlpha,
+ GLboolean unpackUnmultiplyAlpha);
+bool ValidateCopySubTextureCHROMIUM(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID sourceIdPacked,
+ GLint sourceLevel,
+ TextureTarget destTargetPacked,
+ TextureID destIdPacked,
+ GLint destLevel,
+ GLint xoffset,
+ GLint yoffset,
+ GLint x,
+ GLint y,
+ GLint width,
+ GLint height,
+ GLboolean unpackFlipY,
+ GLboolean unpackPremultiplyAlpha,
+ GLboolean unpackUnmultiplyAlpha);
+
+// GL_CHROMIUM_framebuffer_mixed_samples
+bool ValidateCoverageModulationCHROMIUM(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum components);
+
+// GL_CHROMIUM_lose_context
+bool ValidateLoseContextCHROMIUM(const Context *context,
+ angle::EntryPoint entryPoint,
+ GraphicsResetStatus currentPacked,
+ GraphicsResetStatus otherPacked);
+
+// GL_EXT_EGL_image_array
+
+// GL_EXT_EGL_image_storage
+bool ValidateEGLImageTargetTexStorageEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLeglImageOES image,
+ const GLint *attrib_list);
+bool ValidateEGLImageTargetTextureStorageEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint texture,
+ GLeglImageOES image,
+ const GLint *attrib_list);
+
+// GL_EXT_YUV_target
+
+// GL_EXT_base_instance
+bool ValidateDrawArraysInstancedBaseInstanceEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ GLint first,
+ GLsizei count,
+ GLsizei instancecount,
+ GLuint baseinstance);
+bool ValidateDrawElementsInstancedBaseInstanceEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLsizei instancecount,
+ GLuint baseinstance);
+bool ValidateDrawElementsInstancedBaseVertexBaseInstanceEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLsizei instancecount,
+ GLint basevertex,
+ GLuint baseinstance);
+
+// GL_EXT_blend_func_extended
+bool ValidateBindFragDataLocationEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ GLuint color,
+ const GLchar *name);
+bool ValidateBindFragDataLocationIndexedEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ GLuint colorNumber,
+ GLuint index,
+ const GLchar *name);
+bool ValidateGetFragDataIndexEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ const GLchar *name);
+bool ValidateGetProgramResourceLocationIndexEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ GLenum programInterface,
+ const GLchar *name);
+
+// GL_EXT_blend_minmax
+
+// GL_EXT_buffer_storage
+bool ValidateBufferStorageEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding targetPacked,
+ GLsizeiptr size,
+ const void *data,
+ GLbitfield flags);
+
+// GL_EXT_clip_control
+bool ValidateClipControlEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum origin,
+ GLenum depth);
+
+// GL_EXT_clip_cull_distance
+
+// GL_EXT_color_buffer_float
+
+// GL_EXT_color_buffer_half_float
+
+// GL_EXT_copy_image
+bool ValidateCopyImageSubDataEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint srcName,
+ GLenum srcTarget,
+ GLint srcLevel,
+ GLint srcX,
+ GLint srcY,
+ GLint srcZ,
+ GLuint dstName,
+ GLenum dstTarget,
+ GLint dstLevel,
+ GLint dstX,
+ GLint dstY,
+ GLint dstZ,
+ GLsizei srcWidth,
+ GLsizei srcHeight,
+ GLsizei srcDepth);
+
+// GL_EXT_debug_label
+bool ValidateGetObjectLabelEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ GLuint object,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLchar *label);
+bool ValidateLabelObjectEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ GLuint object,
+ GLsizei length,
+ const GLchar *label);
+
+// GL_EXT_debug_marker
+bool ValidateInsertEventMarkerEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei length,
+ const GLchar *marker);
+bool ValidatePopGroupMarkerEXT(const Context *context, angle::EntryPoint entryPoint);
+bool ValidatePushGroupMarkerEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei length,
+ const GLchar *marker);
+
+// GL_EXT_discard_framebuffer
+bool ValidateDiscardFramebufferEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLsizei numAttachments,
+ const GLenum *attachments);
+
+// GL_EXT_disjoint_timer_query
+bool ValidateBeginQueryEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryType targetPacked,
+ QueryID idPacked);
+bool ValidateDeleteQueriesEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const QueryID *idsPacked);
+bool ValidateEndQueryEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryType targetPacked);
+bool ValidateGenQueriesEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const QueryID *idsPacked);
+bool ValidateGetInteger64vEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ const GLint64 *data);
+bool ValidateGetQueryObjecti64vEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID idPacked,
+ GLenum pname,
+ const GLint64 *params);
+bool ValidateGetQueryObjectivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID idPacked,
+ GLenum pname,
+ const GLint *params);
+bool ValidateGetQueryObjectui64vEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID idPacked,
+ GLenum pname,
+ const GLuint64 *params);
+bool ValidateGetQueryObjectuivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID idPacked,
+ GLenum pname,
+ const GLuint *params);
+bool ValidateGetQueryivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryType targetPacked,
+ GLenum pname,
+ const GLint *params);
+bool ValidateIsQueryEXT(const Context *context, angle::EntryPoint entryPoint, QueryID idPacked);
+bool ValidateQueryCounterEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID idPacked,
+ QueryType targetPacked);
+
+// GL_EXT_draw_buffers
+bool ValidateDrawBuffersEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const GLenum *bufs);
+
+// GL_EXT_draw_buffers_indexed
+bool ValidateBlendEquationSeparateiEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint buf,
+ GLenum modeRGB,
+ GLenum modeAlpha);
+bool ValidateBlendEquationiEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint buf,
+ GLenum mode);
+bool ValidateBlendFuncSeparateiEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint buf,
+ GLenum srcRGB,
+ GLenum dstRGB,
+ GLenum srcAlpha,
+ GLenum dstAlpha);
+bool ValidateBlendFunciEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint buf,
+ GLenum src,
+ GLenum dst);
+bool ValidateColorMaskiEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLboolean r,
+ GLboolean g,
+ GLboolean b,
+ GLboolean a);
+bool ValidateDisableiEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint index);
+bool ValidateEnableiEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint index);
+bool ValidateIsEnablediEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint index);
+
+// GL_EXT_draw_elements_base_vertex
+bool ValidateDrawElementsBaseVertexEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLint basevertex);
+bool ValidateDrawElementsInstancedBaseVertexEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLsizei instancecount,
+ GLint basevertex);
+bool ValidateDrawRangeElementsBaseVertexEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLint basevertex);
+bool ValidateMultiDrawElementsBaseVertexEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ const GLsizei *count,
+ DrawElementsType typePacked,
+ const void *const *indices,
+ GLsizei drawcount,
+ const GLint *basevertex);
+
+// GL_EXT_external_buffer
+bool ValidateBufferStorageExternalEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding targetPacked,
+ GLintptr offset,
+ GLsizeiptr size,
+ GLeglClientBufferEXT clientBuffer,
+ GLbitfield flags);
+bool ValidateNamedBufferStorageExternalEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint buffer,
+ GLintptr offset,
+ GLsizeiptr size,
+ GLeglClientBufferEXT clientBuffer,
+ GLbitfield flags);
+
+// GL_EXT_float_blend
+
+// GL_EXT_geometry_shader
+bool ValidateFramebufferTextureEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ TextureID texturePacked,
+ GLint level);
+
+// GL_EXT_gpu_shader5
+
+// GL_EXT_instanced_arrays
+bool ValidateDrawArraysInstancedEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ GLint start,
+ GLsizei count,
+ GLsizei primcount);
+bool ValidateDrawElementsInstancedEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLsizei primcount);
+bool ValidateVertexAttribDivisorEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLuint divisor);
+
+// GL_EXT_map_buffer_range
+bool ValidateFlushMappedBufferRangeEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding targetPacked,
+ GLintptr offset,
+ GLsizeiptr length);
+bool ValidateMapBufferRangeEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding targetPacked,
+ GLintptr offset,
+ GLsizeiptr length,
+ GLbitfield access);
+
+// GL_EXT_memory_object
+bool ValidateBufferStorageMemEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLsizeiptr size,
+ MemoryObjectID memoryPacked,
+ GLuint64 offset);
+bool ValidateCreateMemoryObjectsEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const MemoryObjectID *memoryObjectsPacked);
+bool ValidateDeleteMemoryObjectsEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const MemoryObjectID *memoryObjectsPacked);
+bool ValidateGetMemoryObjectParameterivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ MemoryObjectID memoryObjectPacked,
+ GLenum pname,
+ const GLint *params);
+bool ValidateGetUnsignedBytevEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ const GLubyte *data);
+bool ValidateGetUnsignedBytei_vEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint index,
+ const GLubyte *data);
+bool ValidateIsMemoryObjectEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ MemoryObjectID memoryObjectPacked);
+bool ValidateMemoryObjectParameterivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ MemoryObjectID memoryObjectPacked,
+ GLenum pname,
+ const GLint *params);
+bool ValidateTexStorageMem2DEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ MemoryObjectID memoryPacked,
+ GLuint64 offset);
+bool ValidateTexStorageMem2DMultisampleEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedSampleLocations,
+ MemoryObjectID memoryPacked,
+ GLuint64 offset);
+bool ValidateTexStorageMem3DEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ MemoryObjectID memoryPacked,
+ GLuint64 offset);
+bool ValidateTexStorageMem3DMultisampleEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean fixedSampleLocations,
+ MemoryObjectID memoryPacked,
+ GLuint64 offset);
+
+// GL_EXT_memory_object_fd
+bool ValidateImportMemoryFdEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ MemoryObjectID memoryPacked,
+ GLuint64 size,
+ HandleType handleTypePacked,
+ GLint fd);
+
+// GL_EXT_multi_draw_indirect
+bool ValidateMultiDrawArraysIndirectEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ const void *indirect,
+ GLsizei drawcount,
+ GLsizei stride);
+bool ValidateMultiDrawElementsIndirectEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ DrawElementsType typePacked,
+ const void *indirect,
+ GLsizei drawcount,
+ GLsizei stride);
+
+// GL_EXT_multisampled_render_to_texture
+bool ValidateFramebufferTexture2DMultisampleEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ TextureTarget textargetPacked,
+ TextureID texturePacked,
+ GLint level,
+ GLsizei samples);
+bool ValidateRenderbufferStorageMultisampleEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height);
+
+// GL_EXT_multisampled_render_to_texture2
+
+// GL_EXT_occlusion_query_boolean
+
+// GL_EXT_primitive_bounding_box
+bool ValidatePrimitiveBoundingBoxEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat minX,
+ GLfloat minY,
+ GLfloat minZ,
+ GLfloat minW,
+ GLfloat maxX,
+ GLfloat maxY,
+ GLfloat maxZ,
+ GLfloat maxW);
+
+// GL_EXT_protected_textures
+
+// GL_EXT_pvrtc_sRGB
+
+// GL_EXT_read_format_bgra
+
+// GL_EXT_robustness
+bool ValidateGetGraphicsResetStatusEXT(const Context *context, angle::EntryPoint entryPoint);
+bool ValidateGetnUniformfvEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei bufSize,
+ const GLfloat *params);
+bool ValidateGetnUniformivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei bufSize,
+ const GLint *params);
+bool ValidateReadnPixelsEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *data);
+
+// GL_EXT_sRGB
+
+// GL_EXT_sRGB_write_control
+
+// GL_EXT_semaphore
+bool ValidateDeleteSemaphoresEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const SemaphoreID *semaphoresPacked);
+bool ValidateGenSemaphoresEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const SemaphoreID *semaphoresPacked);
+bool ValidateGetSemaphoreParameterui64vEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ SemaphoreID semaphorePacked,
+ GLenum pname,
+ const GLuint64 *params);
+bool ValidateIsSemaphoreEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ SemaphoreID semaphorePacked);
+bool ValidateSemaphoreParameterui64vEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ SemaphoreID semaphorePacked,
+ GLenum pname,
+ const GLuint64 *params);
+bool ValidateSignalSemaphoreEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ SemaphoreID semaphorePacked,
+ GLuint numBufferBarriers,
+ const BufferID *buffersPacked,
+ GLuint numTextureBarriers,
+ const TextureID *texturesPacked,
+ const GLenum *dstLayouts);
+bool ValidateWaitSemaphoreEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ SemaphoreID semaphorePacked,
+ GLuint numBufferBarriers,
+ const BufferID *buffersPacked,
+ GLuint numTextureBarriers,
+ const TextureID *texturesPacked,
+ const GLenum *srcLayouts);
+
+// GL_EXT_semaphore_fd
+bool ValidateImportSemaphoreFdEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ SemaphoreID semaphorePacked,
+ HandleType handleTypePacked,
+ GLint fd);
+
+// GL_EXT_separate_shader_objects
+bool ValidateActiveShaderProgramEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProgramPipelineID pipelinePacked,
+ ShaderProgramID programPacked);
+bool ValidateBindProgramPipelineEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProgramPipelineID pipelinePacked);
+bool ValidateCreateShaderProgramvEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderType typePacked,
+ GLsizei count,
+ const GLchar **strings);
+bool ValidateDeleteProgramPipelinesEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const ProgramPipelineID *pipelinesPacked);
+bool ValidateGenProgramPipelinesEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const ProgramPipelineID *pipelinesPacked);
+bool ValidateGetProgramPipelineInfoLogEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProgramPipelineID pipelinePacked,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLchar *infoLog);
+bool ValidateGetProgramPipelineivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProgramPipelineID pipelinePacked,
+ GLenum pname,
+ const GLint *params);
+bool ValidateIsProgramPipelineEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProgramPipelineID pipelinePacked);
+bool ValidateProgramParameteriEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ GLenum pname,
+ GLint value);
+bool ValidateProgramUniform1fEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLfloat v0);
+bool ValidateProgramUniform1fvEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value);
+bool ValidateProgramUniform1iEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLint v0);
+bool ValidateProgramUniform1ivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value);
+bool ValidateProgramUniform1uiEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLuint v0);
+bool ValidateProgramUniform1uivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value);
+bool ValidateProgramUniform2fEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLfloat v0,
+ GLfloat v1);
+bool ValidateProgramUniform2fvEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value);
+bool ValidateProgramUniform2iEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLint v0,
+ GLint v1);
+bool ValidateProgramUniform2ivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value);
+bool ValidateProgramUniform2uiEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLuint v0,
+ GLuint v1);
+bool ValidateProgramUniform2uivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value);
+bool ValidateProgramUniform3fEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLfloat v0,
+ GLfloat v1,
+ GLfloat v2);
+bool ValidateProgramUniform3fvEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value);
+bool ValidateProgramUniform3iEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLint v0,
+ GLint v1,
+ GLint v2);
+bool ValidateProgramUniform3ivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value);
+bool ValidateProgramUniform3uiEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLuint v0,
+ GLuint v1,
+ GLuint v2);
+bool ValidateProgramUniform3uivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value);
+bool ValidateProgramUniform4fEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLfloat v0,
+ GLfloat v1,
+ GLfloat v2,
+ GLfloat v3);
+bool ValidateProgramUniform4fvEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLfloat *value);
+bool ValidateProgramUniform4iEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLint v0,
+ GLint v1,
+ GLint v2,
+ GLint v3);
+bool ValidateProgramUniform4ivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLint *value);
+bool ValidateProgramUniform4uiEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLuint v0,
+ GLuint v1,
+ GLuint v2,
+ GLuint v3);
+bool ValidateProgramUniform4uivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLuint *value);
+bool ValidateProgramUniformMatrix2fvEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+bool ValidateProgramUniformMatrix2x3fvEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+bool ValidateProgramUniformMatrix2x4fvEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+bool ValidateProgramUniformMatrix3fvEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+bool ValidateProgramUniformMatrix3x2fvEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+bool ValidateProgramUniformMatrix3x4fvEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+bool ValidateProgramUniformMatrix4fvEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+bool ValidateProgramUniformMatrix4x2fvEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+bool ValidateProgramUniformMatrix4x3fvEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+bool ValidateUseProgramStagesEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProgramPipelineID pipelinePacked,
+ GLbitfield stages,
+ ShaderProgramID programPacked);
+bool ValidateValidateProgramPipelineEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProgramPipelineID pipelinePacked);
+
+// GL_EXT_shader_framebuffer_fetch
+
+// GL_EXT_shader_framebuffer_fetch_non_coherent
+bool ValidateFramebufferFetchBarrierEXT(const Context *context, angle::EntryPoint entryPoint);
+
+// GL_EXT_shader_io_blocks
+
+// GL_EXT_shader_non_constant_global_initializers
+
+// GL_EXT_shader_texture_lod
+
+// GL_EXT_shadow_samplers
+
+// GL_EXT_tessellation_shader
+bool ValidatePatchParameteriEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLint value);
+
+// GL_EXT_texture_border_clamp
+bool ValidateGetSamplerParameterIivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID samplerPacked,
+ GLenum pname,
+ const GLint *params);
+bool ValidateGetSamplerParameterIuivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID samplerPacked,
+ GLenum pname,
+ const GLuint *params);
+bool ValidateGetTexParameterIivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLint *params);
+bool ValidateGetTexParameterIuivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLuint *params);
+bool ValidateSamplerParameterIivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID samplerPacked,
+ GLenum pname,
+ const GLint *param);
+bool ValidateSamplerParameterIuivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID samplerPacked,
+ GLenum pname,
+ const GLuint *param);
+bool ValidateTexParameterIivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLint *params);
+bool ValidateTexParameterIuivEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLuint *params);
+
+// GL_EXT_texture_buffer
+bool ValidateTexBufferEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum internalformat,
+ BufferID bufferPacked);
+bool ValidateTexBufferRangeEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum internalformat,
+ BufferID bufferPacked,
+ GLintptr offset,
+ GLsizeiptr size);
+
+// GL_EXT_texture_compression_bptc
+
+// GL_EXT_texture_compression_dxt1
+
+// GL_EXT_texture_compression_rgtc
+
+// GL_EXT_texture_compression_s3tc
+
+// GL_EXT_texture_compression_s3tc_srgb
+
+// GL_EXT_texture_cube_map_array
+
+// GL_EXT_texture_filter_anisotropic
+
+// GL_EXT_texture_format_BGRA8888
+
+// GL_EXT_texture_format_sRGB_override
+
+// GL_EXT_texture_norm16
+
+// GL_EXT_texture_rg
+
+// GL_EXT_texture_sRGB_R8
+
+// GL_EXT_texture_sRGB_RG8
+
+// GL_EXT_texture_sRGB_decode
+
+// GL_EXT_texture_storage
+bool ValidateTexStorage1DEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width);
+bool ValidateTexStorage2DEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height);
+bool ValidateTexStorage3DEXT(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth);
+
+// GL_EXT_texture_type_2_10_10_10_REV
+
+// GL_EXT_unpack_subimage
+
+// GL_IMG_texture_compression_pvrtc
+
+// GL_IMG_texture_compression_pvrtc2
+
+// GL_KHR_blend_equation_advanced
+bool ValidateBlendBarrierKHR(const Context *context, angle::EntryPoint entryPoint);
+
+// GL_KHR_debug
+bool ValidateDebugMessageCallbackKHR(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLDEBUGPROCKHR callback,
+ const void *userParam);
+bool ValidateDebugMessageControlKHR(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum source,
+ GLenum type,
+ GLenum severity,
+ GLsizei count,
+ const GLuint *ids,
+ GLboolean enabled);
+bool ValidateDebugMessageInsertKHR(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum source,
+ GLenum type,
+ GLuint id,
+ GLenum severity,
+ GLsizei length,
+ const GLchar *buf);
+bool ValidateGetDebugMessageLogKHR(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint count,
+ GLsizei bufSize,
+ const GLenum *sources,
+ const GLenum *types,
+ const GLuint *ids,
+ const GLenum *severities,
+ const GLsizei *lengths,
+ const GLchar *messageLog);
+bool ValidateGetObjectLabelKHR(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum identifier,
+ GLuint name,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLchar *label);
+bool ValidateGetObjectPtrLabelKHR(const Context *context,
+ angle::EntryPoint entryPoint,
+ const void *ptr,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLchar *label);
+bool ValidateGetPointervKHR(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ void *const *params);
+bool ValidateObjectLabelKHR(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum identifier,
+ GLuint name,
+ GLsizei length,
+ const GLchar *label);
+bool ValidateObjectPtrLabelKHR(const Context *context,
+ angle::EntryPoint entryPoint,
+ const void *ptr,
+ GLsizei length,
+ const GLchar *label);
+bool ValidatePopDebugGroupKHR(const Context *context, angle::EntryPoint entryPoint);
+bool ValidatePushDebugGroupKHR(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum source,
+ GLuint id,
+ GLsizei length,
+ const GLchar *message);
+
+// GL_KHR_no_error
+
+// GL_KHR_parallel_shader_compile
+bool ValidateMaxShaderCompilerThreadsKHR(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint count);
+
+// GL_KHR_robust_buffer_access_behavior
+
+// GL_KHR_texture_compression_astc_hdr
+
+// GL_KHR_texture_compression_astc_ldr
+
+// GL_KHR_texture_compression_astc_sliced_3d
+
+// GL_MESA_framebuffer_flip_y
+bool ValidateFramebufferParameteriMESA(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum pname,
+ GLint param);
+bool ValidateGetFramebufferParameterivMESA(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum pname,
+ const GLint *params);
+
+// GL_NV_fence
+bool ValidateDeleteFencesNV(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const FenceNVID *fencesPacked);
+bool ValidateFinishFenceNV(const Context *context,
+ angle::EntryPoint entryPoint,
+ FenceNVID fencePacked);
+bool ValidateGenFencesNV(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const FenceNVID *fencesPacked);
+bool ValidateGetFenceivNV(const Context *context,
+ angle::EntryPoint entryPoint,
+ FenceNVID fencePacked,
+ GLenum pname,
+ const GLint *params);
+bool ValidateIsFenceNV(const Context *context, angle::EntryPoint entryPoint, FenceNVID fencePacked);
+bool ValidateSetFenceNV(const Context *context,
+ angle::EntryPoint entryPoint,
+ FenceNVID fencePacked,
+ GLenum condition);
+bool ValidateTestFenceNV(const Context *context,
+ angle::EntryPoint entryPoint,
+ FenceNVID fencePacked);
+
+// GL_NV_framebuffer_blit
+bool ValidateBlitFramebufferNV(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint srcX0,
+ GLint srcY0,
+ GLint srcX1,
+ GLint srcY1,
+ GLint dstX0,
+ GLint dstY0,
+ GLint dstX1,
+ GLint dstY1,
+ GLbitfield mask,
+ GLenum filter);
+
+// GL_NV_pixel_buffer_object
+
+// GL_NV_read_depth
+
+// GL_NV_read_depth_stencil
+
+// GL_NV_read_stencil
+
+// GL_NV_robustness_video_memory_purge
+
+// GL_NV_shader_noperspective_interpolation
+
+// GL_OES_EGL_image
+bool ValidateEGLImageTargetRenderbufferStorageOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLeglImageOES image);
+bool ValidateEGLImageTargetTexture2DOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLeglImageOES image);
+
+// GL_OES_EGL_image_external
+
+// GL_OES_EGL_image_external_essl3
+
+// GL_OES_compressed_ETC1_RGB8_texture
+
+// GL_OES_compressed_paletted_texture
+
+// GL_OES_copy_image
+bool ValidateCopyImageSubDataOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint srcName,
+ GLenum srcTarget,
+ GLint srcLevel,
+ GLint srcX,
+ GLint srcY,
+ GLint srcZ,
+ GLuint dstName,
+ GLenum dstTarget,
+ GLint dstLevel,
+ GLint dstX,
+ GLint dstY,
+ GLint dstZ,
+ GLsizei srcWidth,
+ GLsizei srcHeight,
+ GLsizei srcDepth);
+
+// GL_OES_depth24
+
+// GL_OES_depth32
+
+// GL_OES_depth_texture
+
+// GL_OES_draw_buffers_indexed
+bool ValidateBlendEquationSeparateiOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint buf,
+ GLenum modeRGB,
+ GLenum modeAlpha);
+bool ValidateBlendEquationiOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint buf,
+ GLenum mode);
+bool ValidateBlendFuncSeparateiOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint buf,
+ GLenum srcRGB,
+ GLenum dstRGB,
+ GLenum srcAlpha,
+ GLenum dstAlpha);
+bool ValidateBlendFunciOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint buf,
+ GLenum src,
+ GLenum dst);
+bool ValidateColorMaskiOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLboolean r,
+ GLboolean g,
+ GLboolean b,
+ GLboolean a);
+bool ValidateDisableiOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint index);
+bool ValidateEnableiOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint index);
+bool ValidateIsEnablediOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint index);
+
+// GL_OES_draw_elements_base_vertex
+bool ValidateDrawElementsBaseVertexOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLint basevertex);
+bool ValidateDrawElementsInstancedBaseVertexOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLsizei instancecount,
+ GLint basevertex);
+bool ValidateDrawRangeElementsBaseVertexOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLint basevertex);
+
+// GL_OES_draw_texture
+bool ValidateDrawTexfOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat x,
+ GLfloat y,
+ GLfloat z,
+ GLfloat width,
+ GLfloat height);
+bool ValidateDrawTexfvOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLfloat *coords);
+bool ValidateDrawTexiOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint x,
+ GLint y,
+ GLint z,
+ GLint width,
+ GLint height);
+bool ValidateDrawTexivOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLint *coords);
+bool ValidateDrawTexsOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLshort x,
+ GLshort y,
+ GLshort z,
+ GLshort width,
+ GLshort height);
+bool ValidateDrawTexsvOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLshort *coords);
+bool ValidateDrawTexxOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfixed x,
+ GLfixed y,
+ GLfixed z,
+ GLfixed width,
+ GLfixed height);
+bool ValidateDrawTexxvOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLfixed *coords);
+
+// GL_OES_element_index_uint
+
+// GL_OES_fbo_render_mipmap
+
+// GL_OES_framebuffer_object
+bool ValidateBindFramebufferOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ FramebufferID framebufferPacked);
+bool ValidateBindRenderbufferOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ RenderbufferID renderbufferPacked);
+bool ValidateCheckFramebufferStatusOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target);
+bool ValidateDeleteFramebuffersOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const FramebufferID *framebuffersPacked);
+bool ValidateDeleteRenderbuffersOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const RenderbufferID *renderbuffersPacked);
+bool ValidateFramebufferRenderbufferOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ GLenum renderbuffertarget,
+ RenderbufferID renderbufferPacked);
+bool ValidateFramebufferTexture2DOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ TextureTarget textargetPacked,
+ TextureID texturePacked,
+ GLint level);
+bool ValidateGenFramebuffersOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const FramebufferID *framebuffersPacked);
+bool ValidateGenRenderbuffersOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const RenderbufferID *renderbuffersPacked);
+bool ValidateGenerateMipmapOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked);
+bool ValidateGetFramebufferAttachmentParameterivOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ GLenum pname,
+ const GLint *params);
+bool ValidateGetRenderbufferParameterivOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum pname,
+ const GLint *params);
+bool ValidateIsFramebufferOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ FramebufferID framebufferPacked);
+bool ValidateIsRenderbufferOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ RenderbufferID renderbufferPacked);
+bool ValidateRenderbufferStorageOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height);
+
+// GL_OES_geometry_shader
+bool ValidateFramebufferTextureOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ TextureID texturePacked,
+ GLint level);
+
+// GL_OES_get_program_binary
+bool ValidateGetProgramBinaryOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLenum *binaryFormat,
+ const void *binary);
+bool ValidateProgramBinaryOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ GLenum binaryFormat,
+ const void *binary,
+ GLint length);
+
+// GL_OES_mapbuffer
+bool ValidateGetBufferPointervOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding targetPacked,
+ GLenum pname,
+ void *const *params);
+bool ValidateMapBufferOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding targetPacked,
+ GLenum access);
+bool ValidateUnmapBufferOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding targetPacked);
+
+// GL_OES_matrix_palette
+bool ValidateCurrentPaletteMatrixOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint matrixpaletteindex);
+bool ValidateLoadPaletteFromModelViewMatrixOES(const Context *context,
+ angle::EntryPoint entryPoint);
+bool ValidateMatrixIndexPointerOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint size,
+ GLenum type,
+ GLsizei stride,
+ const void *pointer);
+bool ValidateWeightPointerOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint size,
+ GLenum type,
+ GLsizei stride,
+ const void *pointer);
+
+// GL_OES_packed_depth_stencil
+
+// GL_OES_point_size_array
+bool ValidatePointSizePointerOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexAttribType typePacked,
+ GLsizei stride,
+ const void *pointer);
+
+// GL_OES_point_sprite
+
+// GL_OES_primitive_bounding_box
+bool ValidatePrimitiveBoundingBoxOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat minX,
+ GLfloat minY,
+ GLfloat minZ,
+ GLfloat minW,
+ GLfloat maxX,
+ GLfloat maxY,
+ GLfloat maxZ,
+ GLfloat maxW);
+
+// GL_OES_query_matrix
+bool ValidateQueryMatrixxOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLfixed *mantissa,
+ const GLint *exponent);
+
+// GL_OES_rgb8_rgba8
+
+// GL_OES_sample_shading
+bool ValidateMinSampleShadingOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat value);
+
+// GL_OES_sample_variables
+
+// GL_OES_shader_image_atomic
+
+// GL_OES_shader_io_blocks
+
+// GL_OES_shader_multisample_interpolation
+
+// GL_OES_standard_derivatives
+
+// GL_OES_surfaceless_context
+
+// GL_OES_texture_3D
+bool ValidateCompressedTexImage3DOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLsizei imageSize,
+ const void *data);
+bool ValidateCompressedTexSubImage3DOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data);
+bool ValidateCopyTexSubImage3DOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height);
+bool ValidateFramebufferTexture3DOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ TextureTarget textargetPacked,
+ TextureID texturePacked,
+ GLint level,
+ GLint zoffset);
+bool ValidateTexImage3DOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const void *pixels);
+bool ValidateTexSubImage3DOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget targetPacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ const void *pixels);
+
+// GL_OES_texture_border_clamp
+bool ValidateGetSamplerParameterIivOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID samplerPacked,
+ GLenum pname,
+ const GLint *params);
+bool ValidateGetSamplerParameterIuivOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID samplerPacked,
+ GLenum pname,
+ const GLuint *params);
+bool ValidateGetTexParameterIivOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLint *params);
+bool ValidateGetTexParameterIuivOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLuint *params);
+bool ValidateSamplerParameterIivOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID samplerPacked,
+ GLenum pname,
+ const GLint *param);
+bool ValidateSamplerParameterIuivOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ SamplerID samplerPacked,
+ GLenum pname,
+ const GLuint *param);
+bool ValidateTexParameterIivOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLint *params);
+bool ValidateTexParameterIuivOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum pname,
+ const GLuint *params);
+
+// GL_OES_texture_buffer
+bool ValidateTexBufferOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum internalformat,
+ BufferID bufferPacked);
+bool ValidateTexBufferRangeOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLenum internalformat,
+ BufferID bufferPacked,
+ GLintptr offset,
+ GLsizeiptr size);
+
+// GL_OES_texture_compression_astc
+
+// GL_OES_texture_cube_map
+bool ValidateGetTexGenfvOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum coord,
+ GLenum pname,
+ const GLfloat *params);
+bool ValidateGetTexGenivOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum coord,
+ GLenum pname,
+ const GLint *params);
+bool ValidateGetTexGenxvOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum coord,
+ GLenum pname,
+ const GLfixed *params);
+bool ValidateTexGenfOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum coord,
+ GLenum pname,
+ GLfloat param);
+bool ValidateTexGenfvOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum coord,
+ GLenum pname,
+ const GLfloat *params);
+bool ValidateTexGeniOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum coord,
+ GLenum pname,
+ GLint param);
+bool ValidateTexGenivOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum coord,
+ GLenum pname,
+ const GLint *params);
+bool ValidateTexGenxOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum coord,
+ GLenum pname,
+ GLfixed param);
+bool ValidateTexGenxvOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum coord,
+ GLenum pname,
+ const GLfixed *params);
+
+// GL_OES_texture_cube_map_array
+
+// GL_OES_texture_float
+
+// GL_OES_texture_float_linear
+
+// GL_OES_texture_half_float
+
+// GL_OES_texture_half_float_linear
+
+// GL_OES_texture_npot
+
+// GL_OES_texture_stencil8
+
+// GL_OES_texture_storage_multisample_2d_array
+bool ValidateTexStorage3DMultisampleOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureType targetPacked,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean fixedsamplelocations);
+
+// GL_OES_vertex_array_object
+bool ValidateBindVertexArrayOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexArrayID arrayPacked);
+bool ValidateDeleteVertexArraysOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const VertexArrayID *arraysPacked);
+bool ValidateGenVertexArraysOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const VertexArrayID *arraysPacked);
+bool ValidateIsVertexArrayOES(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexArrayID arrayPacked);
+
+// GL_OES_vertex_half_float
+
+// GL_OES_vertex_type_10_10_10_2
+
+// GL_OVR_multiview
+bool ValidateFramebufferTextureMultiviewOVR(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ TextureID texturePacked,
+ GLint level,
+ GLint baseViewIndex,
+ GLsizei numViews);
+
+// GL_OVR_multiview2
+
+// GL_QCOM_shading_rate
+bool ValidateShadingRateQCOM(const Context *context, angle::EntryPoint entryPoint, GLenum rate);
+} // namespace gl
+
+#endif // LIBANGLE_VALIDATION_ESEXT_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libANGLE/validationGL1.cpp b/gfx/angle/checkout/src/libANGLE/validationGL1.cpp
new file mode 100644
index 0000000000..3e884d4014
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/validationGL1.cpp
@@ -0,0 +1,2421 @@
+//
+// Copyright 2019 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.
+//
+
+// validationGL1.cpp: Validation functions for OpenGL 1.0 entry point parameters
+
+#include "libANGLE/validationGL1_autogen.h"
+
+namespace gl
+{
+
+bool ValidateAccum(const Context *, angle::EntryPoint entryPoint, GLenum op, GLfloat value)
+{
+ return true;
+}
+
+bool ValidateBegin(const Context *, angle::EntryPoint entryPoint, GLenum mode)
+{
+ return true;
+}
+
+bool ValidateBitmap(const Context *,
+ angle::EntryPoint entryPoint,
+ GLsizei width,
+ GLsizei height,
+ GLfloat xorig,
+ GLfloat yorig,
+ GLfloat xmove,
+ GLfloat ymove,
+ const GLubyte *bitmap)
+{
+ return true;
+}
+
+bool ValidateCallList(const Context *, angle::EntryPoint entryPoint, GLuint list)
+{
+ return true;
+}
+
+bool ValidateCallLists(const Context *,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ GLenum type,
+ const void *lists)
+{
+ return true;
+}
+
+bool ValidateClearAccum(const Context *,
+ angle::EntryPoint entryPoint,
+ GLfloat red,
+ GLfloat green,
+ GLfloat blue,
+ GLfloat alpha)
+{
+ return true;
+}
+
+bool ValidateClearDepth(const Context *, angle::EntryPoint entryPoint, GLdouble depth)
+{
+ return true;
+}
+
+bool ValidateClearIndex(const Context *, angle::EntryPoint entryPoint, GLfloat c)
+{
+ return true;
+}
+
+bool ValidateClipPlane(const Context *,
+ angle::EntryPoint entryPoint,
+ GLenum plane,
+ const GLdouble *equation)
+{
+ return true;
+}
+
+bool ValidateColor3b(const Context *,
+ angle::EntryPoint entryPoint,
+ GLbyte red,
+ GLbyte green,
+ GLbyte blue)
+{
+ return true;
+}
+
+bool ValidateColor3bv(const Context *, angle::EntryPoint entryPoint, const GLbyte *v)
+{
+ return true;
+}
+
+bool ValidateColor3d(const Context *,
+ angle::EntryPoint entryPoint,
+ GLdouble red,
+ GLdouble green,
+ GLdouble blue)
+{
+ return true;
+}
+
+bool ValidateColor3dv(const Context *, angle::EntryPoint entryPoint, const GLdouble *v)
+{
+ return true;
+}
+
+bool ValidateColor3f(const Context *,
+ angle::EntryPoint entryPoint,
+ GLfloat red,
+ GLfloat green,
+ GLfloat blue)
+{
+ return true;
+}
+
+bool ValidateColor3fv(const Context *, angle::EntryPoint entryPoint, const GLfloat *v)
+{
+ return true;
+}
+
+bool ValidateColor3i(const Context *,
+ angle::EntryPoint entryPoint,
+ GLint red,
+ GLint green,
+ GLint blue)
+{
+ return true;
+}
+
+bool ValidateColor3iv(const Context *, angle::EntryPoint entryPoint, const GLint *v)
+{
+ return true;
+}
+
+bool ValidateColor3s(const Context *,
+ angle::EntryPoint entryPoint,
+ GLshort red,
+ GLshort green,
+ GLshort blue)
+{
+ return true;
+}
+
+bool ValidateColor3sv(const Context *, angle::EntryPoint entryPoint, const GLshort *v)
+{
+ return true;
+}
+
+bool ValidateColor3ub(const Context *,
+ angle::EntryPoint entryPoint,
+ GLubyte red,
+ GLubyte green,
+ GLubyte blue)
+{
+ return true;
+}
+
+bool ValidateColor3ubv(const Context *, angle::EntryPoint entryPoint, const GLubyte *v)
+{
+ return true;
+}
+
+bool ValidateColor3ui(const Context *,
+ angle::EntryPoint entryPoint,
+ GLuint red,
+ GLuint green,
+ GLuint blue)
+{
+ return true;
+}
+
+bool ValidateColor3uiv(const Context *, angle::EntryPoint entryPoint, const GLuint *v)
+{
+ return true;
+}
+
+bool ValidateColor3us(const Context *,
+ angle::EntryPoint entryPoint,
+ GLushort red,
+ GLushort green,
+ GLushort blue)
+{
+ return true;
+}
+
+bool ValidateColor3usv(const Context *, angle::EntryPoint entryPoint, const GLushort *v)
+{
+ return true;
+}
+
+bool ValidateColor4b(const Context *,
+ angle::EntryPoint entryPoint,
+ GLbyte red,
+ GLbyte green,
+ GLbyte blue,
+ GLbyte alpha)
+{
+ return true;
+}
+
+bool ValidateColor4bv(const Context *, angle::EntryPoint entryPoint, const GLbyte *v)
+{
+ return true;
+}
+
+bool ValidateColor4d(const Context *,
+ angle::EntryPoint entryPoint,
+ GLdouble red,
+ GLdouble green,
+ GLdouble blue,
+ GLdouble alpha)
+{
+ return true;
+}
+
+bool ValidateColor4dv(const Context *, angle::EntryPoint entryPoint, const GLdouble *v)
+{
+ return true;
+}
+
+bool ValidateColor4fv(const Context *, angle::EntryPoint entryPoint, const GLfloat *v)
+{
+ return true;
+}
+
+bool ValidateColor4i(const Context *,
+ angle::EntryPoint entryPoint,
+ GLint red,
+ GLint green,
+ GLint blue,
+ GLint alpha)
+{
+ return true;
+}
+
+bool ValidateColor4iv(const Context *, angle::EntryPoint entryPoint, const GLint *v)
+{
+ return true;
+}
+
+bool ValidateColor4s(const Context *,
+ angle::EntryPoint entryPoint,
+ GLshort red,
+ GLshort green,
+ GLshort blue,
+ GLshort alpha)
+{
+ return true;
+}
+
+bool ValidateColor4sv(const Context *, angle::EntryPoint entryPoint, const GLshort *v)
+{
+ return true;
+}
+
+bool ValidateColor4ubv(const Context *, angle::EntryPoint entryPoint, const GLubyte *v)
+{
+ return true;
+}
+
+bool ValidateColor4ui(const Context *,
+ angle::EntryPoint entryPoint,
+ GLuint red,
+ GLuint green,
+ GLuint blue,
+ GLuint alpha)
+{
+ return true;
+}
+
+bool ValidateColor4uiv(const Context *, angle::EntryPoint entryPoint, const GLuint *v)
+{
+ return true;
+}
+
+bool ValidateColor4us(const Context *,
+ angle::EntryPoint entryPoint,
+ GLushort red,
+ GLushort green,
+ GLushort blue,
+ GLushort alpha)
+{
+ return true;
+}
+
+bool ValidateColor4usv(const Context *, angle::EntryPoint entryPoint, const GLushort *v)
+{
+ return true;
+}
+
+bool ValidateColorMaterial(const Context *, angle::EntryPoint entryPoint, GLenum face, GLenum mode)
+{
+ return true;
+}
+
+bool ValidateCopyPixels(const Context *,
+ angle::EntryPoint entryPoint,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum type)
+{
+ return true;
+}
+
+bool ValidateDeleteLists(const Context *, angle::EntryPoint entryPoint, GLuint list, GLsizei range)
+{
+ return true;
+}
+
+bool ValidateDepthRange(const Context *, angle::EntryPoint entryPoint, GLdouble n, GLdouble f)
+{
+ return true;
+}
+
+bool ValidateDrawBuffer(const Context *, angle::EntryPoint entryPoint, GLenum buf)
+{
+ return true;
+}
+
+bool ValidateDrawPixels(const Context *,
+ angle::EntryPoint entryPoint,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ return true;
+}
+
+bool ValidateEdgeFlag(const Context *, angle::EntryPoint entryPoint, GLboolean flag)
+{
+ return true;
+}
+
+bool ValidateEdgeFlagv(const Context *, angle::EntryPoint entryPoint, const GLboolean *flag)
+{
+ return true;
+}
+
+bool ValidateEnd(const Context *, angle::EntryPoint entryPoint)
+{
+ return true;
+}
+
+bool ValidateEndList(const Context *, angle::EntryPoint entryPoint)
+{
+ return true;
+}
+
+bool ValidateEvalCoord1d(const Context *, angle::EntryPoint entryPoint, GLdouble u)
+{
+ return true;
+}
+
+bool ValidateEvalCoord1dv(const Context *, angle::EntryPoint entryPoint, const GLdouble *u)
+{
+ return true;
+}
+
+bool ValidateEvalCoord1f(const Context *, angle::EntryPoint entryPoint, GLfloat u)
+{
+ return true;
+}
+
+bool ValidateEvalCoord1fv(const Context *, angle::EntryPoint entryPoint, const GLfloat *u)
+{
+ return true;
+}
+
+bool ValidateEvalCoord2d(const Context *, angle::EntryPoint entryPoint, GLdouble u, GLdouble v)
+{
+ return true;
+}
+
+bool ValidateEvalCoord2dv(const Context *, angle::EntryPoint entryPoint, const GLdouble *u)
+{
+ return true;
+}
+
+bool ValidateEvalCoord2f(const Context *, angle::EntryPoint entryPoint, GLfloat u, GLfloat v)
+{
+ return true;
+}
+
+bool ValidateEvalCoord2fv(const Context *, angle::EntryPoint entryPoint, const GLfloat *u)
+{
+ return true;
+}
+
+bool ValidateEvalMesh1(const Context *,
+ angle::EntryPoint entryPoint,
+ GLenum mode,
+ GLint i1,
+ GLint i2)
+{
+ return true;
+}
+
+bool ValidateEvalMesh2(const Context *,
+ angle::EntryPoint entryPoint,
+ GLenum mode,
+ GLint i1,
+ GLint i2,
+ GLint j1,
+ GLint j2)
+{
+ return true;
+}
+
+bool ValidateEvalPoint1(const Context *, angle::EntryPoint entryPoint, GLint i)
+{
+ return true;
+}
+
+bool ValidateEvalPoint2(const Context *, angle::EntryPoint entryPoint, GLint i, GLint j)
+{
+ return true;
+}
+
+bool ValidateFeedbackBuffer(const Context *,
+ angle::EntryPoint entryPoint,
+ GLsizei size,
+ GLenum type,
+ const GLfloat *buffer)
+{
+ return true;
+}
+
+bool ValidateFogi(const Context *, angle::EntryPoint entryPoint, GLenum pname, GLint param)
+{
+ return true;
+}
+
+bool ValidateFogiv(const Context *, angle::EntryPoint entryPoint, GLenum pname, const GLint *params)
+{
+ return true;
+}
+
+bool ValidateFrustum(const Context *,
+ angle::EntryPoint entryPoint,
+ GLdouble left,
+ GLdouble right,
+ GLdouble bottom,
+ GLdouble top,
+ GLdouble zNear,
+ GLdouble zFar)
+{
+ return true;
+}
+
+bool ValidateGenLists(const Context *, angle::EntryPoint entryPoint, GLsizei range)
+{
+ return true;
+}
+
+bool ValidateGetClipPlane(const Context *,
+ angle::EntryPoint entryPoint,
+ GLenum plane,
+ const GLdouble *equation)
+{
+ return true;
+}
+
+bool ValidateGetDoublev(const Context *,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ const GLdouble *data)
+{
+ return true;
+}
+
+bool ValidateGetLightiv(const Context *,
+ angle::EntryPoint entryPoint,
+ GLenum light,
+ GLenum pname,
+ const GLint *params)
+{
+ return true;
+}
+
+bool ValidateGetMapdv(const Context *,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum query,
+ const GLdouble *v)
+{
+ return true;
+}
+
+bool ValidateGetMapfv(const Context *,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum query,
+ const GLfloat *v)
+{
+ return true;
+}
+
+bool ValidateGetMapiv(const Context *,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum query,
+ const GLint *v)
+{
+ return true;
+}
+
+bool ValidateGetMaterialiv(const Context *,
+ angle::EntryPoint entryPoint,
+ GLenum face,
+ GLenum pname,
+ const GLint *params)
+{
+ return true;
+}
+
+bool ValidateGetPixelMapfv(const Context *,
+ angle::EntryPoint entryPoint,
+ GLenum map,
+ const GLfloat *values)
+{
+ return true;
+}
+
+bool ValidateGetPixelMapuiv(const Context *,
+ angle::EntryPoint entryPoint,
+ GLenum map,
+ const GLuint *values)
+{
+ return true;
+}
+
+bool ValidateGetPixelMapusv(const Context *,
+ angle::EntryPoint entryPoint,
+ GLenum map,
+ const GLushort *values)
+{
+ return true;
+}
+
+bool ValidateGetPolygonStipple(const Context *, angle::EntryPoint entryPoint, const GLubyte *mask)
+{
+ return true;
+}
+
+bool ValidateGetTexGendv(const Context *,
+ angle::EntryPoint entryPoint,
+ GLenum coord,
+ GLenum pname,
+ const GLdouble *params)
+{
+ return true;
+}
+
+bool ValidateGetTexGenfv(const Context *,
+ angle::EntryPoint entryPoint,
+ GLenum coord,
+ GLenum pname,
+ const GLfloat *params)
+{
+ return true;
+}
+
+bool ValidateGetTexGeniv(const Context *,
+ angle::EntryPoint entryPoint,
+ GLenum coord,
+ GLenum pname,
+ const GLint *params)
+{
+ return true;
+}
+
+bool ValidateGetTexImage(const Context *,
+ angle::EntryPoint entryPoint,
+ TextureTarget target,
+ GLint level,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ return true;
+}
+
+bool ValidateIndexMask(const Context *, angle::EntryPoint entryPoint, GLuint mask)
+{
+ return true;
+}
+
+bool ValidateIndexd(const Context *, angle::EntryPoint entryPoint, GLdouble c)
+{
+ return true;
+}
+
+bool ValidateIndexdv(const Context *, angle::EntryPoint entryPoint, const GLdouble *c)
+{
+ return true;
+}
+
+bool ValidateIndexf(const Context *, angle::EntryPoint entryPoint, GLfloat c)
+{
+ return true;
+}
+
+bool ValidateIndexfv(const Context *, angle::EntryPoint entryPoint, const GLfloat *c)
+{
+ return true;
+}
+
+bool ValidateIndexi(const Context *, angle::EntryPoint entryPoint, GLint c)
+{
+ return true;
+}
+
+bool ValidateIndexiv(const Context *, angle::EntryPoint entryPoint, const GLint *c)
+{
+ return true;
+}
+
+bool ValidateIndexs(const Context *, angle::EntryPoint entryPoint, GLshort c)
+{
+ return true;
+}
+
+bool ValidateIndexsv(const Context *, angle::EntryPoint entryPoint, const GLshort *c)
+{
+ return true;
+}
+
+bool ValidateInitNames(const Context *, angle::EntryPoint entryPoint)
+{
+ return true;
+}
+
+bool ValidateIsList(const Context *, angle::EntryPoint entryPoint, GLuint list)
+{
+ return true;
+}
+
+bool ValidateLightModeli(const Context *, angle::EntryPoint entryPoint, GLenum pname, GLint param)
+{
+ return true;
+}
+
+bool ValidateLightModeliv(const Context *,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ const GLint *params)
+{
+ return true;
+}
+
+bool ValidateLighti(const Context *,
+ angle::EntryPoint entryPoint,
+ GLenum light,
+ GLenum pname,
+ GLint param)
+{
+ return true;
+}
+
+bool ValidateLightiv(const Context *,
+ angle::EntryPoint entryPoint,
+ GLenum light,
+ GLenum pname,
+ const GLint *params)
+{
+ return true;
+}
+
+bool ValidateLineStipple(const Context *,
+ angle::EntryPoint entryPoint,
+ GLint factor,
+ GLushort pattern)
+{
+ return true;
+}
+
+bool ValidateListBase(const Context *, angle::EntryPoint entryPoint, GLuint base)
+{
+ return true;
+}
+
+bool ValidateLoadMatrixd(const Context *, angle::EntryPoint entryPoint, const GLdouble *m)
+{
+ return true;
+}
+
+bool ValidateLoadName(const Context *, angle::EntryPoint entryPoint, GLuint name)
+{
+ return true;
+}
+
+bool ValidateMap1d(const Context *,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLdouble u1,
+ GLdouble u2,
+ GLint stride,
+ GLint order,
+ const GLdouble *points)
+{
+ return true;
+}
+
+bool ValidateMap1f(const Context *,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLfloat u1,
+ GLfloat u2,
+ GLint stride,
+ GLint order,
+ const GLfloat *points)
+{
+ return true;
+}
+
+bool ValidateMap2d(const Context *,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLdouble u1,
+ GLdouble u2,
+ GLint ustride,
+ GLint uorder,
+ GLdouble v1,
+ GLdouble v2,
+ GLint vstride,
+ GLint vorder,
+ const GLdouble *points)
+{
+ return true;
+}
+
+bool ValidateMap2f(const Context *,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLfloat u1,
+ GLfloat u2,
+ GLint ustride,
+ GLint uorder,
+ GLfloat v1,
+ GLfloat v2,
+ GLint vstride,
+ GLint vorder,
+ const GLfloat *points)
+{
+ return true;
+}
+
+bool ValidateMapGrid1d(const Context *,
+ angle::EntryPoint entryPoint,
+ GLint un,
+ GLdouble u1,
+ GLdouble u2)
+{
+ return true;
+}
+
+bool ValidateMapGrid1f(const Context *,
+ angle::EntryPoint entryPoint,
+ GLint un,
+ GLfloat u1,
+ GLfloat u2)
+{
+ return true;
+}
+
+bool ValidateMapGrid2d(const Context *,
+ angle::EntryPoint entryPoint,
+ GLint un,
+ GLdouble u1,
+ GLdouble u2,
+ GLint vn,
+ GLdouble v1,
+ GLdouble v2)
+{
+ return true;
+}
+
+bool ValidateMapGrid2f(const Context *,
+ angle::EntryPoint entryPoint,
+ GLint un,
+ GLfloat u1,
+ GLfloat u2,
+ GLint vn,
+ GLfloat v1,
+ GLfloat v2)
+{
+ return true;
+}
+
+bool ValidateMateriali(const Context *,
+ angle::EntryPoint entryPoint,
+ GLenum face,
+ GLenum pname,
+ GLint param)
+{
+ return true;
+}
+
+bool ValidateMaterialiv(const Context *,
+ angle::EntryPoint entryPoint,
+ GLenum face,
+ GLenum pname,
+ const GLint *params)
+{
+ return true;
+}
+
+bool ValidateMultMatrixd(const Context *, angle::EntryPoint entryPoint, const GLdouble *m)
+{
+ return true;
+}
+
+bool ValidateNewList(const Context *, angle::EntryPoint entryPoint, GLuint list, GLenum mode)
+{
+ return true;
+}
+
+bool ValidateNormal3b(const Context *,
+ angle::EntryPoint entryPoint,
+ GLbyte nx,
+ GLbyte ny,
+ GLbyte nz)
+{
+ return true;
+}
+
+bool ValidateNormal3bv(const Context *, angle::EntryPoint entryPoint, const GLbyte *v)
+{
+ return true;
+}
+
+bool ValidateNormal3d(const Context *,
+ angle::EntryPoint entryPoint,
+ GLdouble nx,
+ GLdouble ny,
+ GLdouble nz)
+{
+ return true;
+}
+
+bool ValidateNormal3dv(const Context *, angle::EntryPoint entryPoint, const GLdouble *v)
+{
+ return true;
+}
+
+bool ValidateNormal3fv(const Context *, angle::EntryPoint entryPoint, const GLfloat *v)
+{
+ return true;
+}
+
+bool ValidateNormal3i(const Context *, angle::EntryPoint entryPoint, GLint nx, GLint ny, GLint nz)
+{
+ return true;
+}
+
+bool ValidateNormal3iv(const Context *, angle::EntryPoint entryPoint, const GLint *v)
+{
+ return true;
+}
+
+bool ValidateNormal3s(const Context *,
+ angle::EntryPoint entryPoint,
+ GLshort nx,
+ GLshort ny,
+ GLshort nz)
+{
+ return true;
+}
+
+bool ValidateNormal3sv(const Context *, angle::EntryPoint entryPoint, const GLshort *v)
+{
+ return true;
+}
+
+bool ValidateOrtho(const Context *,
+ angle::EntryPoint entryPoint,
+ GLdouble left,
+ GLdouble right,
+ GLdouble bottom,
+ GLdouble top,
+ GLdouble zNear,
+ GLdouble zFar)
+{
+ return true;
+}
+
+bool ValidatePassThrough(const Context *, angle::EntryPoint entryPoint, GLfloat token)
+{
+ return true;
+}
+
+bool ValidatePixelMapfv(const Context *,
+ angle::EntryPoint entryPoint,
+ GLenum map,
+ GLsizei mapsize,
+ const GLfloat *values)
+{
+ return true;
+}
+
+bool ValidatePixelMapuiv(const Context *,
+ angle::EntryPoint entryPoint,
+ GLenum map,
+ GLsizei mapsize,
+ const GLuint *values)
+{
+ return true;
+}
+
+bool ValidatePixelMapusv(const Context *,
+ angle::EntryPoint entryPoint,
+ GLenum map,
+ GLsizei mapsize,
+ const GLushort *values)
+{
+ return true;
+}
+
+bool ValidatePixelStoref(const Context *, angle::EntryPoint entryPoint, GLenum pname, GLfloat param)
+{
+ return true;
+}
+
+bool ValidatePixelTransferf(const Context *,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLfloat param)
+{
+ return true;
+}
+
+bool ValidatePixelTransferi(const Context *,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLint param)
+{
+ return true;
+}
+
+bool ValidatePixelZoom(const Context *,
+ angle::EntryPoint entryPoint,
+ GLfloat xfactor,
+ GLfloat yfactor)
+{
+ return true;
+}
+
+bool ValidatePolygonMode(const Context *, angle::EntryPoint entryPoint, GLenum face, GLenum mode)
+{
+ return true;
+}
+
+bool ValidatePolygonStipple(const Context *, angle::EntryPoint entryPoint, const GLubyte *mask)
+{
+ return true;
+}
+
+bool ValidatePopAttrib(const Context *, angle::EntryPoint entryPoint)
+{
+ return true;
+}
+
+bool ValidatePopName(const Context *, angle::EntryPoint entryPoint)
+{
+ return true;
+}
+
+bool ValidatePushAttrib(const Context *, angle::EntryPoint entryPoint, GLbitfield mask)
+{
+ return true;
+}
+
+bool ValidatePushName(const Context *, angle::EntryPoint entryPoint, GLuint name)
+{
+ return true;
+}
+
+bool ValidateRasterPos2d(const Context *, angle::EntryPoint entryPoint, GLdouble x, GLdouble y)
+{
+ return true;
+}
+
+bool ValidateRasterPos2dv(const Context *, angle::EntryPoint entryPoint, const GLdouble *v)
+{
+ return true;
+}
+
+bool ValidateRasterPos2f(const Context *, angle::EntryPoint entryPoint, GLfloat x, GLfloat y)
+{
+ return true;
+}
+
+bool ValidateRasterPos2fv(const Context *, angle::EntryPoint entryPoint, const GLfloat *v)
+{
+ return true;
+}
+
+bool ValidateRasterPos2i(const Context *, angle::EntryPoint entryPoint, GLint x, GLint y)
+{
+ return true;
+}
+
+bool ValidateRasterPos2iv(const Context *, angle::EntryPoint entryPoint, const GLint *v)
+{
+ return true;
+}
+
+bool ValidateRasterPos2s(const Context *, angle::EntryPoint entryPoint, GLshort x, GLshort y)
+{
+ return true;
+}
+
+bool ValidateRasterPos2sv(const Context *, angle::EntryPoint entryPoint, const GLshort *v)
+{
+ return true;
+}
+
+bool ValidateRasterPos3d(const Context *,
+ angle::EntryPoint entryPoint,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z)
+{
+ return true;
+}
+
+bool ValidateRasterPos3dv(const Context *, angle::EntryPoint entryPoint, const GLdouble *v)
+{
+ return true;
+}
+
+bool ValidateRasterPos3f(const Context *,
+ angle::EntryPoint entryPoint,
+ GLfloat x,
+ GLfloat y,
+ GLfloat z)
+{
+ return true;
+}
+
+bool ValidateRasterPos3fv(const Context *, angle::EntryPoint entryPoint, const GLfloat *v)
+{
+ return true;
+}
+
+bool ValidateRasterPos3i(const Context *, angle::EntryPoint entryPoint, GLint x, GLint y, GLint z)
+{
+ return true;
+}
+
+bool ValidateRasterPos3iv(const Context *, angle::EntryPoint entryPoint, const GLint *v)
+{
+ return true;
+}
+
+bool ValidateRasterPos3s(const Context *,
+ angle::EntryPoint entryPoint,
+ GLshort x,
+ GLshort y,
+ GLshort z)
+{
+ return true;
+}
+
+bool ValidateRasterPos3sv(const Context *, angle::EntryPoint entryPoint, const GLshort *v)
+{
+ return true;
+}
+
+bool ValidateRasterPos4d(const Context *,
+ angle::EntryPoint entryPoint,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z,
+ GLdouble w)
+{
+ return true;
+}
+
+bool ValidateRasterPos4dv(const Context *, angle::EntryPoint entryPoint, const GLdouble *v)
+{
+ return true;
+}
+
+bool ValidateRasterPos4f(const Context *,
+ angle::EntryPoint entryPoint,
+ GLfloat x,
+ GLfloat y,
+ GLfloat z,
+ GLfloat w)
+{
+ return true;
+}
+
+bool ValidateRasterPos4fv(const Context *, angle::EntryPoint entryPoint, const GLfloat *v)
+{
+ return true;
+}
+
+bool ValidateRasterPos4i(const Context *,
+ angle::EntryPoint entryPoint,
+ GLint x,
+ GLint y,
+ GLint z,
+ GLint w)
+{
+ return true;
+}
+
+bool ValidateRasterPos4iv(const Context *, angle::EntryPoint entryPoint, const GLint *v)
+{
+ return true;
+}
+
+bool ValidateRasterPos4s(const Context *,
+ angle::EntryPoint entryPoint,
+ GLshort x,
+ GLshort y,
+ GLshort z,
+ GLshort w)
+{
+ return true;
+}
+
+bool ValidateRasterPos4sv(const Context *, angle::EntryPoint entryPoint, const GLshort *v)
+{
+ return true;
+}
+
+bool ValidateRectd(const Context *,
+ angle::EntryPoint entryPoint,
+ GLdouble x1,
+ GLdouble y1,
+ GLdouble x2,
+ GLdouble y2)
+{
+ return true;
+}
+
+bool ValidateRectdv(const Context *,
+ angle::EntryPoint entryPoint,
+ const GLdouble *v1,
+ const GLdouble *v2)
+{
+ return true;
+}
+
+bool ValidateRectf(const Context *,
+ angle::EntryPoint entryPoint,
+ GLfloat x1,
+ GLfloat y1,
+ GLfloat x2,
+ GLfloat y2)
+{
+ return true;
+}
+
+bool ValidateRectfv(const Context *,
+ angle::EntryPoint entryPoint,
+ const GLfloat *v1,
+ const GLfloat *v2)
+{
+ return true;
+}
+
+bool ValidateRecti(const Context *,
+ angle::EntryPoint entryPoint,
+ GLint x1,
+ GLint y1,
+ GLint x2,
+ GLint y2)
+{
+ return true;
+}
+
+bool ValidateRectiv(const Context *, angle::EntryPoint entryPoint, const GLint *v1, const GLint *v2)
+{
+ return true;
+}
+
+bool ValidateRects(const Context *,
+ angle::EntryPoint entryPoint,
+ GLshort x1,
+ GLshort y1,
+ GLshort x2,
+ GLshort y2)
+{
+ return true;
+}
+
+bool ValidateRectsv(const Context *,
+ angle::EntryPoint entryPoint,
+ const GLshort *v1,
+ const GLshort *v2)
+{
+ return true;
+}
+
+bool ValidateRenderMode(const Context *, angle::EntryPoint entryPoint, GLenum mode)
+{
+ return true;
+}
+
+bool ValidateRotated(const Context *,
+ angle::EntryPoint entryPoint,
+ GLdouble angle,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z)
+{
+ return true;
+}
+
+bool ValidateScaled(const Context *,
+ angle::EntryPoint entryPoint,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z)
+{
+ return true;
+}
+
+bool ValidateSelectBuffer(const Context *,
+ angle::EntryPoint entryPoint,
+ GLsizei size,
+ const GLuint *buffer)
+{
+ return true;
+}
+
+bool ValidateTexCoord1d(const Context *, angle::EntryPoint entryPoint, GLdouble s)
+{
+ return true;
+}
+
+bool ValidateTexCoord1dv(const Context *, angle::EntryPoint entryPoint, const GLdouble *v)
+{
+ return true;
+}
+
+bool ValidateTexCoord1f(const Context *, angle::EntryPoint entryPoint, GLfloat s)
+{
+ return true;
+}
+
+bool ValidateTexCoord1fv(const Context *, angle::EntryPoint entryPoint, const GLfloat *v)
+{
+ return true;
+}
+
+bool ValidateTexCoord1i(const Context *, angle::EntryPoint entryPoint, GLint s)
+{
+ return true;
+}
+
+bool ValidateTexCoord1iv(const Context *, angle::EntryPoint entryPoint, const GLint *v)
+{
+ return true;
+}
+
+bool ValidateTexCoord1s(const Context *, angle::EntryPoint entryPoint, GLshort s)
+{
+ return true;
+}
+
+bool ValidateTexCoord1sv(const Context *, angle::EntryPoint entryPoint, const GLshort *v)
+{
+ return true;
+}
+
+bool ValidateTexCoord2d(const Context *, angle::EntryPoint entryPoint, GLdouble s, GLdouble t)
+{
+ return true;
+}
+
+bool ValidateTexCoord2dv(const Context *, angle::EntryPoint entryPoint, const GLdouble *v)
+{
+ return true;
+}
+
+bool ValidateTexCoord2f(const Context *, angle::EntryPoint entryPoint, GLfloat s, GLfloat t)
+{
+ return true;
+}
+
+bool ValidateTexCoord2fv(const Context *, angle::EntryPoint entryPoint, const GLfloat *v)
+{
+ return true;
+}
+
+bool ValidateTexCoord2i(const Context *, angle::EntryPoint entryPoint, GLint s, GLint t)
+{
+ return true;
+}
+
+bool ValidateTexCoord2iv(const Context *, angle::EntryPoint entryPoint, const GLint *v)
+{
+ return true;
+}
+
+bool ValidateTexCoord2s(const Context *, angle::EntryPoint entryPoint, GLshort s, GLshort t)
+{
+ return true;
+}
+
+bool ValidateTexCoord2sv(const Context *, angle::EntryPoint entryPoint, const GLshort *v)
+{
+ return true;
+}
+
+bool ValidateTexCoord3d(const Context *,
+ angle::EntryPoint entryPoint,
+ GLdouble s,
+ GLdouble t,
+ GLdouble r)
+{
+ return true;
+}
+
+bool ValidateTexCoord3dv(const Context *, angle::EntryPoint entryPoint, const GLdouble *v)
+{
+ return true;
+}
+
+bool ValidateTexCoord3f(const Context *,
+ angle::EntryPoint entryPoint,
+ GLfloat s,
+ GLfloat t,
+ GLfloat r)
+{
+ return true;
+}
+
+bool ValidateTexCoord3fv(const Context *, angle::EntryPoint entryPoint, const GLfloat *v)
+{
+ return true;
+}
+
+bool ValidateTexCoord3i(const Context *, angle::EntryPoint entryPoint, GLint s, GLint t, GLint r)
+{
+ return true;
+}
+
+bool ValidateTexCoord3iv(const Context *, angle::EntryPoint entryPoint, const GLint *v)
+{
+ return true;
+}
+
+bool ValidateTexCoord3s(const Context *,
+ angle::EntryPoint entryPoint,
+ GLshort s,
+ GLshort t,
+ GLshort r)
+{
+ return true;
+}
+
+bool ValidateTexCoord3sv(const Context *, angle::EntryPoint entryPoint, const GLshort *v)
+{
+ return true;
+}
+
+bool ValidateTexCoord4d(const Context *,
+ angle::EntryPoint entryPoint,
+ GLdouble s,
+ GLdouble t,
+ GLdouble r,
+ GLdouble q)
+{
+ return true;
+}
+
+bool ValidateTexCoord4dv(const Context *, angle::EntryPoint entryPoint, const GLdouble *v)
+{
+ return true;
+}
+
+bool ValidateTexCoord4f(const Context *,
+ angle::EntryPoint entryPoint,
+ GLfloat s,
+ GLfloat t,
+ GLfloat r,
+ GLfloat q)
+{
+ return true;
+}
+
+bool ValidateTexCoord4fv(const Context *, angle::EntryPoint entryPoint, const GLfloat *v)
+{
+ return true;
+}
+
+bool ValidateTexCoord4i(const Context *,
+ angle::EntryPoint entryPoint,
+ GLint s,
+ GLint t,
+ GLint r,
+ GLint q)
+{
+ return true;
+}
+
+bool ValidateTexCoord4iv(const Context *, angle::EntryPoint entryPoint, const GLint *v)
+{
+ return true;
+}
+
+bool ValidateTexCoord4s(const Context *,
+ angle::EntryPoint entryPoint,
+ GLshort s,
+ GLshort t,
+ GLshort r,
+ GLshort q)
+{
+ return true;
+}
+
+bool ValidateTexCoord4sv(const Context *, angle::EntryPoint entryPoint, const GLshort *v)
+{
+ return true;
+}
+
+bool ValidateTexGend(const Context *,
+ angle::EntryPoint entryPoint,
+ GLenum coord,
+ GLenum pname,
+ GLdouble param)
+{
+ return true;
+}
+
+bool ValidateTexGendv(const Context *,
+ angle::EntryPoint entryPoint,
+ GLenum coord,
+ GLenum pname,
+ const GLdouble *params)
+{
+ return true;
+}
+
+bool ValidateTexGenf(const Context *,
+ angle::EntryPoint entryPoint,
+ GLenum coord,
+ GLenum pname,
+ GLfloat param)
+{
+ return true;
+}
+bool ValidateTexGenfv(const Context *,
+ angle::EntryPoint entryPoint,
+ GLenum coord,
+ GLenum pname,
+ const GLfloat *params)
+{
+ return true;
+}
+
+bool ValidateTexGeni(const Context *,
+ angle::EntryPoint entryPoint,
+ GLenum coord,
+ GLenum pname,
+ GLint param)
+{
+ return true;
+}
+
+bool ValidateTexGeniv(const Context *,
+ angle::EntryPoint entryPoint,
+ GLenum coord,
+ GLenum pname,
+ const GLint *params)
+{
+ return true;
+}
+
+bool ValidateTexImage1D(const Context *,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ return true;
+}
+
+bool ValidateTranslated(const Context *,
+ angle::EntryPoint entryPoint,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z)
+{
+ return true;
+}
+
+bool ValidateVertex2d(const Context *, angle::EntryPoint entryPoint, GLdouble x, GLdouble y)
+{
+ return true;
+}
+
+bool ValidateVertex2dv(const Context *, angle::EntryPoint entryPoint, const GLdouble *v)
+{
+ return true;
+}
+
+bool ValidateVertex2f(const Context *, angle::EntryPoint entryPoint, GLfloat x, GLfloat y)
+{
+ return true;
+}
+
+bool ValidateVertex2fv(const Context *, angle::EntryPoint entryPoint, const GLfloat *v)
+{
+ return true;
+}
+
+bool ValidateVertex2i(const Context *, angle::EntryPoint entryPoint, GLint x, GLint y)
+{
+ return true;
+}
+
+bool ValidateVertex2iv(const Context *, angle::EntryPoint entryPoint, const GLint *v)
+{
+ return true;
+}
+
+bool ValidateVertex2s(const Context *, angle::EntryPoint entryPoint, GLshort x, GLshort y)
+{
+ return true;
+}
+
+bool ValidateVertex2sv(const Context *, angle::EntryPoint entryPoint, const GLshort *v)
+{
+ return true;
+}
+
+bool ValidateVertex3d(const Context *,
+ angle::EntryPoint entryPoint,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z)
+{
+ return true;
+}
+
+bool ValidateVertex3dv(const Context *, angle::EntryPoint entryPoint, const GLdouble *v)
+{
+ return true;
+}
+
+bool ValidateVertex3f(const Context *,
+ angle::EntryPoint entryPoint,
+ GLfloat x,
+ GLfloat y,
+ GLfloat z)
+{
+ return true;
+}
+
+bool ValidateVertex3fv(const Context *, angle::EntryPoint entryPoint, const GLfloat *v)
+{
+ return true;
+}
+
+bool ValidateVertex3i(const Context *, angle::EntryPoint entryPoint, GLint x, GLint y, GLint z)
+{
+ return true;
+}
+
+bool ValidateVertex3iv(const Context *, angle::EntryPoint entryPoint, const GLint *v)
+{
+ return true;
+}
+
+bool ValidateVertex3s(const Context *,
+ angle::EntryPoint entryPoint,
+ GLshort x,
+ GLshort y,
+ GLshort z)
+{
+ return true;
+}
+
+bool ValidateVertex3sv(const Context *, angle::EntryPoint entryPoint, const GLshort *v)
+{
+ return true;
+}
+
+bool ValidateVertex4d(const Context *,
+ angle::EntryPoint entryPoint,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z,
+ GLdouble w)
+{
+ return true;
+}
+
+bool ValidateVertex4dv(const Context *, angle::EntryPoint entryPoint, const GLdouble *v)
+{
+ return true;
+}
+
+bool ValidateVertex4f(const Context *,
+ angle::EntryPoint entryPoint,
+ GLfloat x,
+ GLfloat y,
+ GLfloat z,
+ GLfloat w)
+{
+ return true;
+}
+
+bool ValidateVertex4fv(const Context *, angle::EntryPoint entryPoint, const GLfloat *v)
+{
+ return true;
+}
+
+bool ValidateVertex4i(const Context *,
+ angle::EntryPoint entryPoint,
+ GLint x,
+ GLint y,
+ GLint z,
+ GLint w)
+{
+ return true;
+}
+
+bool ValidateVertex4iv(const Context *, angle::EntryPoint entryPoint, const GLint *v)
+{
+ return true;
+}
+
+bool ValidateVertex4s(const Context *,
+ angle::EntryPoint entryPoint,
+ GLshort x,
+ GLshort y,
+ GLshort z,
+ GLshort w)
+{
+ return true;
+}
+
+bool ValidateVertex4sv(const Context *, angle::EntryPoint entryPoint, const GLshort *v)
+{
+ return true;
+}
+
+bool ValidateAreTexturesResident(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const GLuint *textures,
+ const GLboolean *residences)
+{
+ return true;
+}
+
+bool ValidateArrayElement(const Context *context, angle::EntryPoint entryPoint, GLint i)
+{
+ return true;
+}
+
+bool ValidateCopyTexImage1D(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLint level,
+ GLenum internalformat,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLint border)
+{
+ return true;
+}
+
+bool ValidateCopyTexSubImage1D(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint x,
+ GLint y,
+ GLsizei width)
+{
+ return true;
+}
+
+bool ValidateEdgeFlagPointer(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei stride,
+ const void *pointer)
+{
+ return true;
+}
+
+bool ValidateIndexPointer(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ GLsizei stride,
+ const void *pointer)
+{
+ return true;
+}
+
+bool ValidateIndexub(const Context *context, angle::EntryPoint entryPoint, GLubyte c)
+{
+ return true;
+}
+
+bool ValidateIndexubv(const Context *context, angle::EntryPoint entryPoint, const GLubyte *c)
+{
+ return true;
+}
+
+bool ValidateInterleavedArrays(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum format,
+ GLsizei stride,
+ const void *pointer)
+{
+ return true;
+}
+
+bool ValidatePopClientAttrib(const Context *context, angle::EntryPoint entryPoint)
+{
+ return true;
+}
+
+bool ValidatePrioritizeTextures(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const GLuint *textures,
+ const GLfloat *priorities)
+{
+ return true;
+}
+
+bool ValidatePushClientAttrib(const Context *context, angle::EntryPoint entryPoint, GLbitfield mask)
+{
+ return true;
+}
+
+bool ValidateTexSubImage1D(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLsizei width,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ return true;
+}
+
+bool ValidateCompressedTexImage1D(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLint border,
+ GLsizei imageSize,
+ const void *data)
+{
+ return true;
+}
+
+bool ValidateCompressedTexSubImage1D(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLsizei width,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data)
+{
+ return true;
+}
+
+bool ValidateGetCompressedTexImage(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget targetPacked,
+ GLint level,
+ const void *img)
+{
+ return true;
+}
+
+bool ValidateLoadTransposeMatrixd(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLdouble *m)
+{
+ return true;
+}
+
+bool ValidateLoadTransposeMatrixf(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLfloat *m)
+{
+ return true;
+}
+
+bool ValidateMultTransposeMatrixd(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLdouble *m)
+{
+ return true;
+}
+
+bool ValidateMultTransposeMatrixf(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLfloat *m)
+{
+ return true;
+}
+
+bool ValidateMultiTexCoord1d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLdouble s)
+{
+ return true;
+}
+
+bool ValidateMultiTexCoord1dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ const GLdouble *v)
+{
+ return true;
+}
+
+bool ValidateMultiTexCoord1f(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLfloat s)
+{
+ return true;
+}
+
+bool ValidateMultiTexCoord1fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ const GLfloat *v)
+{
+ return true;
+}
+
+bool ValidateMultiTexCoord1i(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLint s)
+{
+ return true;
+}
+
+bool ValidateMultiTexCoord1iv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ const GLint *v)
+{
+ return true;
+}
+
+bool ValidateMultiTexCoord1s(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLshort s)
+{
+ return true;
+}
+
+bool ValidateMultiTexCoord1sv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ const GLshort *v)
+{
+ return true;
+}
+
+bool ValidateMultiTexCoord2d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLdouble s,
+ GLdouble t)
+{
+ return true;
+}
+
+bool ValidateMultiTexCoord2dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ const GLdouble *v)
+{
+ return true;
+}
+
+bool ValidateMultiTexCoord2f(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLfloat s,
+ GLfloat t)
+{
+ return true;
+}
+
+bool ValidateMultiTexCoord2fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ const GLfloat *v)
+{
+ return true;
+}
+
+bool ValidateMultiTexCoord2i(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLint s,
+ GLint t)
+{
+ return true;
+}
+
+bool ValidateMultiTexCoord2iv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ const GLint *v)
+{
+ return true;
+}
+
+bool ValidateMultiTexCoord2s(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLshort s,
+ GLshort t)
+{
+ return true;
+}
+
+bool ValidateMultiTexCoord2sv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ const GLshort *v)
+{
+ return true;
+}
+
+bool ValidateMultiTexCoord3d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLdouble s,
+ GLdouble t,
+ GLdouble r)
+{
+ return true;
+}
+
+bool ValidateMultiTexCoord3dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ const GLdouble *v)
+{
+ return true;
+}
+
+bool ValidateMultiTexCoord3f(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLfloat s,
+ GLfloat t,
+ GLfloat r)
+{
+ return true;
+}
+
+bool ValidateMultiTexCoord3fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ const GLfloat *v)
+{
+ return true;
+}
+
+bool ValidateMultiTexCoord3i(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLint s,
+ GLint t,
+ GLint r)
+{
+ return true;
+}
+
+bool ValidateMultiTexCoord3iv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ const GLint *v)
+{
+ return true;
+}
+
+bool ValidateMultiTexCoord3s(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLshort s,
+ GLshort t,
+ GLshort r)
+{
+ return true;
+}
+
+bool ValidateMultiTexCoord3sv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ const GLshort *v)
+{
+ return true;
+}
+
+bool ValidateMultiTexCoord4d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLdouble s,
+ GLdouble t,
+ GLdouble r,
+ GLdouble q)
+{
+ return true;
+}
+
+bool ValidateMultiTexCoord4dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ const GLdouble *v)
+{
+ return true;
+}
+
+bool ValidateMultiTexCoord4fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ const GLfloat *v)
+{
+ return true;
+}
+
+bool ValidateMultiTexCoord4i(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLint s,
+ GLint t,
+ GLint r,
+ GLint q)
+{
+ return true;
+}
+
+bool ValidateMultiTexCoord4iv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ const GLint *v)
+{
+ return true;
+}
+
+bool ValidateMultiTexCoord4s(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLshort s,
+ GLshort t,
+ GLshort r,
+ GLshort q)
+{
+ return true;
+}
+
+bool ValidateMultiTexCoord4sv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ const GLshort *v)
+{
+ return true;
+}
+
+bool ValidateFogCoordPointer(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ GLsizei stride,
+ const void *pointer)
+{
+ return true;
+}
+
+bool ValidateFogCoordd(const Context *context, angle::EntryPoint entryPoint, GLdouble coord)
+{
+ return true;
+}
+
+bool ValidateFogCoorddv(const Context *context, angle::EntryPoint entryPoint, const GLdouble *coord)
+{
+ return true;
+}
+
+bool ValidateFogCoordf(const Context *context, angle::EntryPoint entryPoint, GLfloat coord)
+{
+ return true;
+}
+
+bool ValidateFogCoordfv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *coord)
+{
+ return true;
+}
+
+bool ValidateMultiDrawArrays(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ const GLint *first,
+ const GLsizei *count,
+ GLsizei drawcount)
+{
+ return true;
+}
+
+bool ValidateMultiDrawElements(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ const GLsizei *count,
+ DrawElementsType typePacked,
+ const void *const *indices,
+ GLsizei drawcount)
+{
+ return true;
+}
+
+bool ValidatePointParameteri(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLint param)
+{
+ return true;
+}
+
+bool ValidatePointParameteriv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ const GLint *params)
+{
+ return true;
+}
+
+bool ValidateSecondaryColor3b(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLbyte red,
+ GLbyte green,
+ GLbyte blue)
+{
+ return true;
+}
+
+bool ValidateSecondaryColor3bv(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLbyte *v)
+{
+ return true;
+}
+
+bool ValidateSecondaryColor3d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLdouble red,
+ GLdouble green,
+ GLdouble blue)
+{
+ return true;
+}
+
+bool ValidateSecondaryColor3dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLdouble *v)
+{
+ return true;
+}
+
+bool ValidateSecondaryColor3f(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat red,
+ GLfloat green,
+ GLfloat blue)
+{
+ return true;
+}
+
+bool ValidateSecondaryColor3fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLfloat *v)
+{
+ return true;
+}
+
+bool ValidateSecondaryColor3i(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint red,
+ GLint green,
+ GLint blue)
+{
+ return true;
+}
+
+bool ValidateSecondaryColor3iv(const Context *context, angle::EntryPoint entryPoint, const GLint *v)
+{
+ return true;
+}
+
+bool ValidateSecondaryColor3s(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLshort red,
+ GLshort green,
+ GLshort blue)
+{
+ return true;
+}
+
+bool ValidateSecondaryColor3sv(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLshort *v)
+{
+ return true;
+}
+
+bool ValidateSecondaryColor3ub(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLubyte red,
+ GLubyte green,
+ GLubyte blue)
+{
+ return true;
+}
+
+bool ValidateSecondaryColor3ubv(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLubyte *v)
+{
+ return true;
+}
+
+bool ValidateSecondaryColor3ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint red,
+ GLuint green,
+ GLuint blue)
+{
+ return true;
+}
+
+bool ValidateSecondaryColor3uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLuint *v)
+{
+ return true;
+}
+
+bool ValidateSecondaryColor3us(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLushort red,
+ GLushort green,
+ GLushort blue)
+{
+ return true;
+}
+
+bool ValidateSecondaryColor3usv(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLushort *v)
+{
+ return true;
+}
+
+bool ValidateSecondaryColorPointer(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint size,
+ GLenum type,
+ GLsizei stride,
+ const void *pointer)
+{
+ return true;
+}
+
+bool ValidateWindowPos2d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLdouble x,
+ GLdouble y)
+{
+ return true;
+}
+
+bool ValidateWindowPos2dv(const Context *context, angle::EntryPoint entryPoint, const GLdouble *v)
+{
+ return true;
+}
+
+bool ValidateWindowPos2f(const Context *context, angle::EntryPoint entryPoint, GLfloat x, GLfloat y)
+{
+ return true;
+}
+
+bool ValidateWindowPos2fv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *v)
+{
+ return true;
+}
+
+bool ValidateWindowPos2i(const Context *context, angle::EntryPoint entryPoint, GLint x, GLint y)
+{
+ return true;
+}
+
+bool ValidateWindowPos2iv(const Context *context, angle::EntryPoint entryPoint, const GLint *v)
+{
+ return true;
+}
+
+bool ValidateWindowPos2s(const Context *context, angle::EntryPoint entryPoint, GLshort x, GLshort y)
+{
+ return true;
+}
+
+bool ValidateWindowPos2sv(const Context *context, angle::EntryPoint entryPoint, const GLshort *v)
+{
+ return true;
+}
+
+bool ValidateWindowPos3d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z)
+{
+ return true;
+}
+
+bool ValidateWindowPos3dv(const Context *context, angle::EntryPoint entryPoint, const GLdouble *v)
+{
+ return true;
+}
+
+bool ValidateWindowPos3f(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat x,
+ GLfloat y,
+ GLfloat z)
+{
+ return true;
+}
+
+bool ValidateWindowPos3fv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *v)
+{
+ return true;
+}
+
+bool ValidateWindowPos3i(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint x,
+ GLint y,
+ GLint z)
+{
+ return true;
+}
+
+bool ValidateWindowPos3iv(const Context *context, angle::EntryPoint entryPoint, const GLint *v)
+{
+ return true;
+}
+
+bool ValidateWindowPos3s(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLshort x,
+ GLshort y,
+ GLshort z)
+{
+ return true;
+}
+
+bool ValidateWindowPos3sv(const Context *context, angle::EntryPoint entryPoint, const GLshort *v)
+{
+ return true;
+}
+
+bool ValidateGetBufferSubData(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLintptr offset,
+ GLsizeiptr size,
+ const void *data)
+{
+ return true;
+}
+
+bool ValidateGetQueryObjectiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID id,
+ GLenum pname,
+ const GLint *params)
+{
+ return true;
+}
+
+bool ValidateMapBuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding targetPacked,
+ GLenum access)
+{
+ return true;
+}
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/validationGL1_autogen.h b/gfx/angle/checkout/src/libANGLE/validationGL1_autogen.h
new file mode 100644
index 0000000000..3e04829ea7
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/validationGL1_autogen.h
@@ -0,0 +1,1192 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml.
+//
+// Copyright 2020 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.
+//
+// validationGL1_autogen.h:
+// Validation functions for the OpenGL Desktop GL 1.x entry points.
+
+#ifndef LIBANGLE_VALIDATION_GL1_AUTOGEN_H_
+#define LIBANGLE_VALIDATION_GL1_AUTOGEN_H_
+
+#include "common/PackedEnums.h"
+#include "common/entry_points_enum_autogen.h"
+
+namespace gl
+{
+class Context;
+
+// GL 1.0
+bool ValidateAccum(const Context *context, angle::EntryPoint entryPoint, GLenum op, GLfloat value);
+bool ValidateBegin(const Context *context, angle::EntryPoint entryPoint, GLenum mode);
+bool ValidateBitmap(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei width,
+ GLsizei height,
+ GLfloat xorig,
+ GLfloat yorig,
+ GLfloat xmove,
+ GLfloat ymove,
+ const GLubyte *bitmap);
+bool ValidateCallList(const Context *context, angle::EntryPoint entryPoint, GLuint list);
+bool ValidateCallLists(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ GLenum type,
+ const void *lists);
+bool ValidateClearAccum(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat red,
+ GLfloat green,
+ GLfloat blue,
+ GLfloat alpha);
+bool ValidateClearDepth(const Context *context, angle::EntryPoint entryPoint, GLdouble depth);
+bool ValidateClearIndex(const Context *context, angle::EntryPoint entryPoint, GLfloat c);
+bool ValidateClipPlane(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum plane,
+ const GLdouble *equation);
+bool ValidateColor3b(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLbyte red,
+ GLbyte green,
+ GLbyte blue);
+bool ValidateColor3bv(const Context *context, angle::EntryPoint entryPoint, const GLbyte *v);
+bool ValidateColor3d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLdouble red,
+ GLdouble green,
+ GLdouble blue);
+bool ValidateColor3dv(const Context *context, angle::EntryPoint entryPoint, const GLdouble *v);
+bool ValidateColor3f(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat red,
+ GLfloat green,
+ GLfloat blue);
+bool ValidateColor3fv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *v);
+bool ValidateColor3i(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint red,
+ GLint green,
+ GLint blue);
+bool ValidateColor3iv(const Context *context, angle::EntryPoint entryPoint, const GLint *v);
+bool ValidateColor3s(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLshort red,
+ GLshort green,
+ GLshort blue);
+bool ValidateColor3sv(const Context *context, angle::EntryPoint entryPoint, const GLshort *v);
+bool ValidateColor3ub(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLubyte red,
+ GLubyte green,
+ GLubyte blue);
+bool ValidateColor3ubv(const Context *context, angle::EntryPoint entryPoint, const GLubyte *v);
+bool ValidateColor3ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint red,
+ GLuint green,
+ GLuint blue);
+bool ValidateColor3uiv(const Context *context, angle::EntryPoint entryPoint, const GLuint *v);
+bool ValidateColor3us(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLushort red,
+ GLushort green,
+ GLushort blue);
+bool ValidateColor3usv(const Context *context, angle::EntryPoint entryPoint, const GLushort *v);
+bool ValidateColor4b(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLbyte red,
+ GLbyte green,
+ GLbyte blue,
+ GLbyte alpha);
+bool ValidateColor4bv(const Context *context, angle::EntryPoint entryPoint, const GLbyte *v);
+bool ValidateColor4d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLdouble red,
+ GLdouble green,
+ GLdouble blue,
+ GLdouble alpha);
+bool ValidateColor4dv(const Context *context, angle::EntryPoint entryPoint, const GLdouble *v);
+bool ValidateColor4fv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *v);
+bool ValidateColor4i(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint red,
+ GLint green,
+ GLint blue,
+ GLint alpha);
+bool ValidateColor4iv(const Context *context, angle::EntryPoint entryPoint, const GLint *v);
+bool ValidateColor4s(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLshort red,
+ GLshort green,
+ GLshort blue,
+ GLshort alpha);
+bool ValidateColor4sv(const Context *context, angle::EntryPoint entryPoint, const GLshort *v);
+bool ValidateColor4ubv(const Context *context, angle::EntryPoint entryPoint, const GLubyte *v);
+bool ValidateColor4ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint red,
+ GLuint green,
+ GLuint blue,
+ GLuint alpha);
+bool ValidateColor4uiv(const Context *context, angle::EntryPoint entryPoint, const GLuint *v);
+bool ValidateColor4us(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLushort red,
+ GLushort green,
+ GLushort blue,
+ GLushort alpha);
+bool ValidateColor4usv(const Context *context, angle::EntryPoint entryPoint, const GLushort *v);
+bool ValidateColorMaterial(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum face,
+ GLenum mode);
+bool ValidateCopyPixels(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum type);
+bool ValidateDeleteLists(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint list,
+ GLsizei range);
+bool ValidateDepthRange(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLdouble n,
+ GLdouble f);
+bool ValidateDrawBuffer(const Context *context, angle::EntryPoint entryPoint, GLenum buf);
+bool ValidateDrawPixels(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ const void *pixels);
+bool ValidateEdgeFlag(const Context *context, angle::EntryPoint entryPoint, GLboolean flag);
+bool ValidateEdgeFlagv(const Context *context, angle::EntryPoint entryPoint, const GLboolean *flag);
+bool ValidateEnd(const Context *context, angle::EntryPoint entryPoint);
+bool ValidateEndList(const Context *context, angle::EntryPoint entryPoint);
+bool ValidateEvalCoord1d(const Context *context, angle::EntryPoint entryPoint, GLdouble u);
+bool ValidateEvalCoord1dv(const Context *context, angle::EntryPoint entryPoint, const GLdouble *u);
+bool ValidateEvalCoord1f(const Context *context, angle::EntryPoint entryPoint, GLfloat u);
+bool ValidateEvalCoord1fv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *u);
+bool ValidateEvalCoord2d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLdouble u,
+ GLdouble v);
+bool ValidateEvalCoord2dv(const Context *context, angle::EntryPoint entryPoint, const GLdouble *u);
+bool ValidateEvalCoord2f(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat u,
+ GLfloat v);
+bool ValidateEvalCoord2fv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *u);
+bool ValidateEvalMesh1(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum mode,
+ GLint i1,
+ GLint i2);
+bool ValidateEvalMesh2(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum mode,
+ GLint i1,
+ GLint i2,
+ GLint j1,
+ GLint j2);
+bool ValidateEvalPoint1(const Context *context, angle::EntryPoint entryPoint, GLint i);
+bool ValidateEvalPoint2(const Context *context, angle::EntryPoint entryPoint, GLint i, GLint j);
+bool ValidateFeedbackBuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei size,
+ GLenum type,
+ const GLfloat *buffer);
+bool ValidateFogi(const Context *context, angle::EntryPoint entryPoint, GLenum pname, GLint param);
+bool ValidateFogiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ const GLint *params);
+bool ValidateFrustum(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLdouble left,
+ GLdouble right,
+ GLdouble bottom,
+ GLdouble top,
+ GLdouble zNear,
+ GLdouble zFar);
+bool ValidateGenLists(const Context *context, angle::EntryPoint entryPoint, GLsizei range);
+bool ValidateGetClipPlane(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum plane,
+ const GLdouble *equation);
+bool ValidateGetDoublev(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ const GLdouble *data);
+bool ValidateGetLightiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum light,
+ GLenum pname,
+ const GLint *params);
+bool ValidateGetMapdv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum query,
+ const GLdouble *v);
+bool ValidateGetMapfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum query,
+ const GLfloat *v);
+bool ValidateGetMapiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum query,
+ const GLint *v);
+bool ValidateGetMaterialiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum face,
+ GLenum pname,
+ const GLint *params);
+bool ValidateGetPixelMapfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum map,
+ const GLfloat *values);
+bool ValidateGetPixelMapuiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum map,
+ const GLuint *values);
+bool ValidateGetPixelMapusv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum map,
+ const GLushort *values);
+bool ValidateGetPolygonStipple(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLubyte *mask);
+bool ValidateGetTexGendv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum coord,
+ GLenum pname,
+ const GLdouble *params);
+bool ValidateGetTexGenfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum coord,
+ GLenum pname,
+ const GLfloat *params);
+bool ValidateGetTexGeniv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum coord,
+ GLenum pname,
+ const GLint *params);
+bool ValidateGetTexImage(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget targetPacked,
+ GLint level,
+ GLenum format,
+ GLenum type,
+ const void *pixels);
+bool ValidateIndexMask(const Context *context, angle::EntryPoint entryPoint, GLuint mask);
+bool ValidateIndexd(const Context *context, angle::EntryPoint entryPoint, GLdouble c);
+bool ValidateIndexdv(const Context *context, angle::EntryPoint entryPoint, const GLdouble *c);
+bool ValidateIndexf(const Context *context, angle::EntryPoint entryPoint, GLfloat c);
+bool ValidateIndexfv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *c);
+bool ValidateIndexi(const Context *context, angle::EntryPoint entryPoint, GLint c);
+bool ValidateIndexiv(const Context *context, angle::EntryPoint entryPoint, const GLint *c);
+bool ValidateIndexs(const Context *context, angle::EntryPoint entryPoint, GLshort c);
+bool ValidateIndexsv(const Context *context, angle::EntryPoint entryPoint, const GLshort *c);
+bool ValidateInitNames(const Context *context, angle::EntryPoint entryPoint);
+bool ValidateIsList(const Context *context, angle::EntryPoint entryPoint, GLuint list);
+bool ValidateLightModeli(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLint param);
+bool ValidateLightModeliv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ const GLint *params);
+bool ValidateLighti(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum light,
+ GLenum pname,
+ GLint param);
+bool ValidateLightiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum light,
+ GLenum pname,
+ const GLint *params);
+bool ValidateLineStipple(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint factor,
+ GLushort pattern);
+bool ValidateListBase(const Context *context, angle::EntryPoint entryPoint, GLuint base);
+bool ValidateLoadMatrixd(const Context *context, angle::EntryPoint entryPoint, const GLdouble *m);
+bool ValidateLoadName(const Context *context, angle::EntryPoint entryPoint, GLuint name);
+bool ValidateMap1d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLdouble u1,
+ GLdouble u2,
+ GLint stride,
+ GLint order,
+ const GLdouble *points);
+bool ValidateMap1f(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLfloat u1,
+ GLfloat u2,
+ GLint stride,
+ GLint order,
+ const GLfloat *points);
+bool ValidateMap2d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLdouble u1,
+ GLdouble u2,
+ GLint ustride,
+ GLint uorder,
+ GLdouble v1,
+ GLdouble v2,
+ GLint vstride,
+ GLint vorder,
+ const GLdouble *points);
+bool ValidateMap2f(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLfloat u1,
+ GLfloat u2,
+ GLint ustride,
+ GLint uorder,
+ GLfloat v1,
+ GLfloat v2,
+ GLint vstride,
+ GLint vorder,
+ const GLfloat *points);
+bool ValidateMapGrid1d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint un,
+ GLdouble u1,
+ GLdouble u2);
+bool ValidateMapGrid1f(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint un,
+ GLfloat u1,
+ GLfloat u2);
+bool ValidateMapGrid2d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint un,
+ GLdouble u1,
+ GLdouble u2,
+ GLint vn,
+ GLdouble v1,
+ GLdouble v2);
+bool ValidateMapGrid2f(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint un,
+ GLfloat u1,
+ GLfloat u2,
+ GLint vn,
+ GLfloat v1,
+ GLfloat v2);
+bool ValidateMateriali(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum face,
+ GLenum pname,
+ GLint param);
+bool ValidateMaterialiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum face,
+ GLenum pname,
+ const GLint *params);
+bool ValidateMultMatrixd(const Context *context, angle::EntryPoint entryPoint, const GLdouble *m);
+bool ValidateNewList(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint list,
+ GLenum mode);
+bool ValidateNormal3b(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLbyte nx,
+ GLbyte ny,
+ GLbyte nz);
+bool ValidateNormal3bv(const Context *context, angle::EntryPoint entryPoint, const GLbyte *v);
+bool ValidateNormal3d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLdouble nx,
+ GLdouble ny,
+ GLdouble nz);
+bool ValidateNormal3dv(const Context *context, angle::EntryPoint entryPoint, const GLdouble *v);
+bool ValidateNormal3fv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *v);
+bool ValidateNormal3i(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint nx,
+ GLint ny,
+ GLint nz);
+bool ValidateNormal3iv(const Context *context, angle::EntryPoint entryPoint, const GLint *v);
+bool ValidateNormal3s(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLshort nx,
+ GLshort ny,
+ GLshort nz);
+bool ValidateNormal3sv(const Context *context, angle::EntryPoint entryPoint, const GLshort *v);
+bool ValidateOrtho(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLdouble left,
+ GLdouble right,
+ GLdouble bottom,
+ GLdouble top,
+ GLdouble zNear,
+ GLdouble zFar);
+bool ValidatePassThrough(const Context *context, angle::EntryPoint entryPoint, GLfloat token);
+bool ValidatePixelMapfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum map,
+ GLsizei mapsize,
+ const GLfloat *values);
+bool ValidatePixelMapuiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum map,
+ GLsizei mapsize,
+ const GLuint *values);
+bool ValidatePixelMapusv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum map,
+ GLsizei mapsize,
+ const GLushort *values);
+bool ValidatePixelStoref(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLfloat param);
+bool ValidatePixelTransferf(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLfloat param);
+bool ValidatePixelTransferi(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLint param);
+bool ValidatePixelZoom(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat xfactor,
+ GLfloat yfactor);
+bool ValidatePolygonMode(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum face,
+ GLenum mode);
+bool ValidatePolygonStipple(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLubyte *mask);
+bool ValidatePopAttrib(const Context *context, angle::EntryPoint entryPoint);
+bool ValidatePopName(const Context *context, angle::EntryPoint entryPoint);
+bool ValidatePushAttrib(const Context *context, angle::EntryPoint entryPoint, GLbitfield mask);
+bool ValidatePushName(const Context *context, angle::EntryPoint entryPoint, GLuint name);
+bool ValidateRasterPos2d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLdouble x,
+ GLdouble y);
+bool ValidateRasterPos2dv(const Context *context, angle::EntryPoint entryPoint, const GLdouble *v);
+bool ValidateRasterPos2f(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat x,
+ GLfloat y);
+bool ValidateRasterPos2fv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *v);
+bool ValidateRasterPos2i(const Context *context, angle::EntryPoint entryPoint, GLint x, GLint y);
+bool ValidateRasterPos2iv(const Context *context, angle::EntryPoint entryPoint, const GLint *v);
+bool ValidateRasterPos2s(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLshort x,
+ GLshort y);
+bool ValidateRasterPos2sv(const Context *context, angle::EntryPoint entryPoint, const GLshort *v);
+bool ValidateRasterPos3d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z);
+bool ValidateRasterPos3dv(const Context *context, angle::EntryPoint entryPoint, const GLdouble *v);
+bool ValidateRasterPos3f(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat x,
+ GLfloat y,
+ GLfloat z);
+bool ValidateRasterPos3fv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *v);
+bool ValidateRasterPos3i(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint x,
+ GLint y,
+ GLint z);
+bool ValidateRasterPos3iv(const Context *context, angle::EntryPoint entryPoint, const GLint *v);
+bool ValidateRasterPos3s(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLshort x,
+ GLshort y,
+ GLshort z);
+bool ValidateRasterPos3sv(const Context *context, angle::EntryPoint entryPoint, const GLshort *v);
+bool ValidateRasterPos4d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z,
+ GLdouble w);
+bool ValidateRasterPos4dv(const Context *context, angle::EntryPoint entryPoint, const GLdouble *v);
+bool ValidateRasterPos4f(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat x,
+ GLfloat y,
+ GLfloat z,
+ GLfloat w);
+bool ValidateRasterPos4fv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *v);
+bool ValidateRasterPos4i(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint x,
+ GLint y,
+ GLint z,
+ GLint w);
+bool ValidateRasterPos4iv(const Context *context, angle::EntryPoint entryPoint, const GLint *v);
+bool ValidateRasterPos4s(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLshort x,
+ GLshort y,
+ GLshort z,
+ GLshort w);
+bool ValidateRasterPos4sv(const Context *context, angle::EntryPoint entryPoint, const GLshort *v);
+bool ValidateRectd(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLdouble x1,
+ GLdouble y1,
+ GLdouble x2,
+ GLdouble y2);
+bool ValidateRectdv(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLdouble *v1,
+ const GLdouble *v2);
+bool ValidateRectf(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat x1,
+ GLfloat y1,
+ GLfloat x2,
+ GLfloat y2);
+bool ValidateRectfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLfloat *v1,
+ const GLfloat *v2);
+bool ValidateRecti(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint x1,
+ GLint y1,
+ GLint x2,
+ GLint y2);
+bool ValidateRectiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLint *v1,
+ const GLint *v2);
+bool ValidateRects(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLshort x1,
+ GLshort y1,
+ GLshort x2,
+ GLshort y2);
+bool ValidateRectsv(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLshort *v1,
+ const GLshort *v2);
+bool ValidateRenderMode(const Context *context, angle::EntryPoint entryPoint, GLenum mode);
+bool ValidateRotated(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLdouble angle,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z);
+bool ValidateScaled(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z);
+bool ValidateSelectBuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei size,
+ const GLuint *buffer);
+bool ValidateTexCoord1d(const Context *context, angle::EntryPoint entryPoint, GLdouble s);
+bool ValidateTexCoord1dv(const Context *context, angle::EntryPoint entryPoint, const GLdouble *v);
+bool ValidateTexCoord1f(const Context *context, angle::EntryPoint entryPoint, GLfloat s);
+bool ValidateTexCoord1fv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *v);
+bool ValidateTexCoord1i(const Context *context, angle::EntryPoint entryPoint, GLint s);
+bool ValidateTexCoord1iv(const Context *context, angle::EntryPoint entryPoint, const GLint *v);
+bool ValidateTexCoord1s(const Context *context, angle::EntryPoint entryPoint, GLshort s);
+bool ValidateTexCoord1sv(const Context *context, angle::EntryPoint entryPoint, const GLshort *v);
+bool ValidateTexCoord2d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLdouble s,
+ GLdouble t);
+bool ValidateTexCoord2dv(const Context *context, angle::EntryPoint entryPoint, const GLdouble *v);
+bool ValidateTexCoord2f(const Context *context, angle::EntryPoint entryPoint, GLfloat s, GLfloat t);
+bool ValidateTexCoord2fv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *v);
+bool ValidateTexCoord2i(const Context *context, angle::EntryPoint entryPoint, GLint s, GLint t);
+bool ValidateTexCoord2iv(const Context *context, angle::EntryPoint entryPoint, const GLint *v);
+bool ValidateTexCoord2s(const Context *context, angle::EntryPoint entryPoint, GLshort s, GLshort t);
+bool ValidateTexCoord2sv(const Context *context, angle::EntryPoint entryPoint, const GLshort *v);
+bool ValidateTexCoord3d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLdouble s,
+ GLdouble t,
+ GLdouble r);
+bool ValidateTexCoord3dv(const Context *context, angle::EntryPoint entryPoint, const GLdouble *v);
+bool ValidateTexCoord3f(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat s,
+ GLfloat t,
+ GLfloat r);
+bool ValidateTexCoord3fv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *v);
+bool ValidateTexCoord3i(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint s,
+ GLint t,
+ GLint r);
+bool ValidateTexCoord3iv(const Context *context, angle::EntryPoint entryPoint, const GLint *v);
+bool ValidateTexCoord3s(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLshort s,
+ GLshort t,
+ GLshort r);
+bool ValidateTexCoord3sv(const Context *context, angle::EntryPoint entryPoint, const GLshort *v);
+bool ValidateTexCoord4d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLdouble s,
+ GLdouble t,
+ GLdouble r,
+ GLdouble q);
+bool ValidateTexCoord4dv(const Context *context, angle::EntryPoint entryPoint, const GLdouble *v);
+bool ValidateTexCoord4f(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat s,
+ GLfloat t,
+ GLfloat r,
+ GLfloat q);
+bool ValidateTexCoord4fv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *v);
+bool ValidateTexCoord4i(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint s,
+ GLint t,
+ GLint r,
+ GLint q);
+bool ValidateTexCoord4iv(const Context *context, angle::EntryPoint entryPoint, const GLint *v);
+bool ValidateTexCoord4s(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLshort s,
+ GLshort t,
+ GLshort r,
+ GLshort q);
+bool ValidateTexCoord4sv(const Context *context, angle::EntryPoint entryPoint, const GLshort *v);
+bool ValidateTexGend(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum coord,
+ GLenum pname,
+ GLdouble param);
+bool ValidateTexGendv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum coord,
+ GLenum pname,
+ const GLdouble *params);
+bool ValidateTexGenf(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum coord,
+ GLenum pname,
+ GLfloat param);
+bool ValidateTexGenfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum coord,
+ GLenum pname,
+ const GLfloat *params);
+bool ValidateTexGeni(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum coord,
+ GLenum pname,
+ GLint param);
+bool ValidateTexGeniv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum coord,
+ GLenum pname,
+ const GLint *params);
+bool ValidateTexImage1D(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const void *pixels);
+bool ValidateTranslated(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z);
+bool ValidateVertex2d(const Context *context, angle::EntryPoint entryPoint, GLdouble x, GLdouble y);
+bool ValidateVertex2dv(const Context *context, angle::EntryPoint entryPoint, const GLdouble *v);
+bool ValidateVertex2f(const Context *context, angle::EntryPoint entryPoint, GLfloat x, GLfloat y);
+bool ValidateVertex2fv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *v);
+bool ValidateVertex2i(const Context *context, angle::EntryPoint entryPoint, GLint x, GLint y);
+bool ValidateVertex2iv(const Context *context, angle::EntryPoint entryPoint, const GLint *v);
+bool ValidateVertex2s(const Context *context, angle::EntryPoint entryPoint, GLshort x, GLshort y);
+bool ValidateVertex2sv(const Context *context, angle::EntryPoint entryPoint, const GLshort *v);
+bool ValidateVertex3d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z);
+bool ValidateVertex3dv(const Context *context, angle::EntryPoint entryPoint, const GLdouble *v);
+bool ValidateVertex3f(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat x,
+ GLfloat y,
+ GLfloat z);
+bool ValidateVertex3fv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *v);
+bool ValidateVertex3i(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint x,
+ GLint y,
+ GLint z);
+bool ValidateVertex3iv(const Context *context, angle::EntryPoint entryPoint, const GLint *v);
+bool ValidateVertex3s(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLshort x,
+ GLshort y,
+ GLshort z);
+bool ValidateVertex3sv(const Context *context, angle::EntryPoint entryPoint, const GLshort *v);
+bool ValidateVertex4d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z,
+ GLdouble w);
+bool ValidateVertex4dv(const Context *context, angle::EntryPoint entryPoint, const GLdouble *v);
+bool ValidateVertex4f(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat x,
+ GLfloat y,
+ GLfloat z,
+ GLfloat w);
+bool ValidateVertex4fv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *v);
+bool ValidateVertex4i(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint x,
+ GLint y,
+ GLint z,
+ GLint w);
+bool ValidateVertex4iv(const Context *context, angle::EntryPoint entryPoint, const GLint *v);
+bool ValidateVertex4s(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLshort x,
+ GLshort y,
+ GLshort z,
+ GLshort w);
+bool ValidateVertex4sv(const Context *context, angle::EntryPoint entryPoint, const GLshort *v);
+
+// GL 1.1
+bool ValidateAreTexturesResident(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const GLuint *textures,
+ const GLboolean *residences);
+bool ValidateArrayElement(const Context *context, angle::EntryPoint entryPoint, GLint i);
+bool ValidateCopyTexImage1D(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLint level,
+ GLenum internalformat,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLint border);
+bool ValidateCopyTexSubImage1D(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint x,
+ GLint y,
+ GLsizei width);
+bool ValidateEdgeFlagPointer(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei stride,
+ const void *pointer);
+bool ValidateIndexPointer(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ GLsizei stride,
+ const void *pointer);
+bool ValidateIndexub(const Context *context, angle::EntryPoint entryPoint, GLubyte c);
+bool ValidateIndexubv(const Context *context, angle::EntryPoint entryPoint, const GLubyte *c);
+bool ValidateInterleavedArrays(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum format,
+ GLsizei stride,
+ const void *pointer);
+bool ValidatePopClientAttrib(const Context *context, angle::EntryPoint entryPoint);
+bool ValidatePrioritizeTextures(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const GLuint *textures,
+ const GLfloat *priorities);
+bool ValidatePushClientAttrib(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLbitfield mask);
+bool ValidateTexSubImage1D(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLsizei width,
+ GLenum format,
+ GLenum type,
+ const void *pixels);
+
+// GL 1.2
+
+// GL 1.3
+bool ValidateCompressedTexImage1D(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLint border,
+ GLsizei imageSize,
+ const void *data);
+bool ValidateCompressedTexSubImage1D(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLsizei width,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data);
+bool ValidateGetCompressedTexImage(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureTarget targetPacked,
+ GLint level,
+ const void *img);
+bool ValidateLoadTransposeMatrixd(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLdouble *m);
+bool ValidateLoadTransposeMatrixf(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLfloat *m);
+bool ValidateMultTransposeMatrixd(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLdouble *m);
+bool ValidateMultTransposeMatrixf(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLfloat *m);
+bool ValidateMultiTexCoord1d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLdouble s);
+bool ValidateMultiTexCoord1dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ const GLdouble *v);
+bool ValidateMultiTexCoord1f(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLfloat s);
+bool ValidateMultiTexCoord1fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ const GLfloat *v);
+bool ValidateMultiTexCoord1i(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLint s);
+bool ValidateMultiTexCoord1iv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ const GLint *v);
+bool ValidateMultiTexCoord1s(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLshort s);
+bool ValidateMultiTexCoord1sv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ const GLshort *v);
+bool ValidateMultiTexCoord2d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLdouble s,
+ GLdouble t);
+bool ValidateMultiTexCoord2dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ const GLdouble *v);
+bool ValidateMultiTexCoord2f(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLfloat s,
+ GLfloat t);
+bool ValidateMultiTexCoord2fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ const GLfloat *v);
+bool ValidateMultiTexCoord2i(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLint s,
+ GLint t);
+bool ValidateMultiTexCoord2iv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ const GLint *v);
+bool ValidateMultiTexCoord2s(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLshort s,
+ GLshort t);
+bool ValidateMultiTexCoord2sv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ const GLshort *v);
+bool ValidateMultiTexCoord3d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLdouble s,
+ GLdouble t,
+ GLdouble r);
+bool ValidateMultiTexCoord3dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ const GLdouble *v);
+bool ValidateMultiTexCoord3f(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLfloat s,
+ GLfloat t,
+ GLfloat r);
+bool ValidateMultiTexCoord3fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ const GLfloat *v);
+bool ValidateMultiTexCoord3i(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLint s,
+ GLint t,
+ GLint r);
+bool ValidateMultiTexCoord3iv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ const GLint *v);
+bool ValidateMultiTexCoord3s(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLshort s,
+ GLshort t,
+ GLshort r);
+bool ValidateMultiTexCoord3sv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ const GLshort *v);
+bool ValidateMultiTexCoord4d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLdouble s,
+ GLdouble t,
+ GLdouble r,
+ GLdouble q);
+bool ValidateMultiTexCoord4dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ const GLdouble *v);
+bool ValidateMultiTexCoord4fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ const GLfloat *v);
+bool ValidateMultiTexCoord4i(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLint s,
+ GLint t,
+ GLint r,
+ GLint q);
+bool ValidateMultiTexCoord4iv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ const GLint *v);
+bool ValidateMultiTexCoord4s(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLshort s,
+ GLshort t,
+ GLshort r,
+ GLshort q);
+bool ValidateMultiTexCoord4sv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ const GLshort *v);
+
+// GL 1.4
+bool ValidateFogCoordPointer(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ GLsizei stride,
+ const void *pointer);
+bool ValidateFogCoordd(const Context *context, angle::EntryPoint entryPoint, GLdouble coord);
+bool ValidateFogCoorddv(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLdouble *coord);
+bool ValidateFogCoordf(const Context *context, angle::EntryPoint entryPoint, GLfloat coord);
+bool ValidateFogCoordfv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *coord);
+bool ValidateMultiDrawArrays(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ const GLint *first,
+ const GLsizei *count,
+ GLsizei drawcount);
+bool ValidateMultiDrawElements(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ const GLsizei *count,
+ DrawElementsType typePacked,
+ const void *const *indices,
+ GLsizei drawcount);
+bool ValidatePointParameteri(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ GLint param);
+bool ValidatePointParameteriv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ const GLint *params);
+bool ValidateSecondaryColor3b(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLbyte red,
+ GLbyte green,
+ GLbyte blue);
+bool ValidateSecondaryColor3bv(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLbyte *v);
+bool ValidateSecondaryColor3d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLdouble red,
+ GLdouble green,
+ GLdouble blue);
+bool ValidateSecondaryColor3dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLdouble *v);
+bool ValidateSecondaryColor3f(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat red,
+ GLfloat green,
+ GLfloat blue);
+bool ValidateSecondaryColor3fv(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLfloat *v);
+bool ValidateSecondaryColor3i(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint red,
+ GLint green,
+ GLint blue);
+bool ValidateSecondaryColor3iv(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLint *v);
+bool ValidateSecondaryColor3s(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLshort red,
+ GLshort green,
+ GLshort blue);
+bool ValidateSecondaryColor3sv(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLshort *v);
+bool ValidateSecondaryColor3ub(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLubyte red,
+ GLubyte green,
+ GLubyte blue);
+bool ValidateSecondaryColor3ubv(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLubyte *v);
+bool ValidateSecondaryColor3ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint red,
+ GLuint green,
+ GLuint blue);
+bool ValidateSecondaryColor3uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLuint *v);
+bool ValidateSecondaryColor3us(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLushort red,
+ GLushort green,
+ GLushort blue);
+bool ValidateSecondaryColor3usv(const Context *context,
+ angle::EntryPoint entryPoint,
+ const GLushort *v);
+bool ValidateSecondaryColorPointer(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint size,
+ GLenum type,
+ GLsizei stride,
+ const void *pointer);
+bool ValidateWindowPos2d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLdouble x,
+ GLdouble y);
+bool ValidateWindowPos2dv(const Context *context, angle::EntryPoint entryPoint, const GLdouble *v);
+bool ValidateWindowPos2f(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat x,
+ GLfloat y);
+bool ValidateWindowPos2fv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *v);
+bool ValidateWindowPos2i(const Context *context, angle::EntryPoint entryPoint, GLint x, GLint y);
+bool ValidateWindowPos2iv(const Context *context, angle::EntryPoint entryPoint, const GLint *v);
+bool ValidateWindowPos2s(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLshort x,
+ GLshort y);
+bool ValidateWindowPos2sv(const Context *context, angle::EntryPoint entryPoint, const GLshort *v);
+bool ValidateWindowPos3d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z);
+bool ValidateWindowPos3dv(const Context *context, angle::EntryPoint entryPoint, const GLdouble *v);
+bool ValidateWindowPos3f(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat x,
+ GLfloat y,
+ GLfloat z);
+bool ValidateWindowPos3fv(const Context *context, angle::EntryPoint entryPoint, const GLfloat *v);
+bool ValidateWindowPos3i(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLint x,
+ GLint y,
+ GLint z);
+bool ValidateWindowPos3iv(const Context *context, angle::EntryPoint entryPoint, const GLint *v);
+bool ValidateWindowPos3s(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLshort x,
+ GLshort y,
+ GLshort z);
+bool ValidateWindowPos3sv(const Context *context, angle::EntryPoint entryPoint, const GLshort *v);
+
+// GL 1.5
+bool ValidateGetBufferSubData(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLintptr offset,
+ GLsizeiptr size,
+ const void *data);
+bool ValidateGetQueryObjectiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID idPacked,
+ GLenum pname,
+ const GLint *params);
+bool ValidateMapBuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding targetPacked,
+ GLenum access);
+} // namespace gl
+
+#endif // LIBANGLE_VALIDATION_GL1_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libANGLE/validationGL2.cpp b/gfx/angle/checkout/src/libANGLE/validationGL2.cpp
new file mode 100644
index 0000000000..9eb97b2f94
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/validationGL2.cpp
@@ -0,0 +1,262 @@
+//
+// Copyright 2019 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.
+//
+
+// validationGL2.cpp: Validation functions for OpenGL 2.0 entry point parameters
+
+#include "libANGLE/validationGL2_autogen.h"
+
+namespace gl
+{
+
+bool ValidateGetVertexAttribdv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum pname,
+ const GLdouble *params)
+{
+ return true;
+}
+
+bool ValidateVertexAttrib1d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLdouble x)
+{
+ return true;
+}
+
+bool ValidateVertexAttrib1dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLdouble *v)
+{
+ return true;
+}
+
+bool ValidateVertexAttrib1s(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLshort x)
+{
+ return true;
+}
+
+bool ValidateVertexAttrib1sv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLshort *v)
+{
+ return true;
+}
+
+bool ValidateVertexAttrib2d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLdouble x,
+ GLdouble y)
+{
+ return true;
+}
+
+bool ValidateVertexAttrib2dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLdouble *v)
+{
+ return true;
+}
+
+bool ValidateVertexAttrib2s(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLshort x,
+ GLshort y)
+{
+ return true;
+}
+
+bool ValidateVertexAttrib2sv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLshort *v)
+{
+ return true;
+}
+
+bool ValidateVertexAttrib3d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z)
+{
+ return true;
+}
+
+bool ValidateVertexAttrib3dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLdouble *v)
+{
+ return true;
+}
+
+bool ValidateVertexAttrib3s(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLshort x,
+ GLshort y,
+ GLshort z)
+{
+ return true;
+}
+
+bool ValidateVertexAttrib3sv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLshort *v)
+{
+ return true;
+}
+
+bool ValidateVertexAttrib4Nbv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLbyte *v)
+{
+ return true;
+}
+
+bool ValidateVertexAttrib4Niv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLint *v)
+{
+ return true;
+}
+
+bool ValidateVertexAttrib4Nsv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLshort *v)
+{
+ return true;
+}
+
+bool ValidateVertexAttrib4Nub(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLubyte x,
+ GLubyte y,
+ GLubyte z,
+ GLubyte w)
+{
+ return true;
+}
+
+bool ValidateVertexAttrib4Nubv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLubyte *v)
+{
+ return true;
+}
+
+bool ValidateVertexAttrib4Nuiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLuint *v)
+{
+ return true;
+}
+
+bool ValidateVertexAttrib4Nusv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLushort *v)
+{
+ return true;
+}
+
+bool ValidateVertexAttrib4bv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLbyte *v)
+{
+ return true;
+}
+
+bool ValidateVertexAttrib4d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z,
+ GLdouble w)
+{
+ return true;
+}
+
+bool ValidateVertexAttrib4dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLdouble *v)
+{
+ return true;
+}
+
+bool ValidateVertexAttrib4iv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLint *v)
+{
+ return true;
+}
+
+bool ValidateVertexAttrib4s(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLshort x,
+ GLshort y,
+ GLshort z,
+ GLshort w)
+{
+ return true;
+}
+
+bool ValidateVertexAttrib4sv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLshort *v)
+{
+ return true;
+}
+
+bool ValidateVertexAttrib4ubv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLubyte *v)
+{
+ return true;
+}
+
+bool ValidateVertexAttrib4uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLuint *v)
+{
+ return true;
+}
+
+bool ValidateVertexAttrib4usv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLushort *v)
+{
+ return true;
+}
+
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/validationGL2_autogen.h b/gfx/angle/checkout/src/libANGLE/validationGL2_autogen.h
new file mode 100644
index 0000000000..5a6e0b375f
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/validationGL2_autogen.h
@@ -0,0 +1,158 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml.
+//
+// Copyright 2020 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.
+//
+// validationGL2_autogen.h:
+// Validation functions for the OpenGL Desktop GL 2.x entry points.
+
+#ifndef LIBANGLE_VALIDATION_GL2_AUTOGEN_H_
+#define LIBANGLE_VALIDATION_GL2_AUTOGEN_H_
+
+#include "common/PackedEnums.h"
+#include "common/entry_points_enum_autogen.h"
+
+namespace gl
+{
+class Context;
+
+// GL 2.0
+bool ValidateGetVertexAttribdv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum pname,
+ const GLdouble *params);
+bool ValidateVertexAttrib1d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLdouble x);
+bool ValidateVertexAttrib1dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLdouble *v);
+bool ValidateVertexAttrib1s(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLshort x);
+bool ValidateVertexAttrib1sv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLshort *v);
+bool ValidateVertexAttrib2d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLdouble x,
+ GLdouble y);
+bool ValidateVertexAttrib2dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLdouble *v);
+bool ValidateVertexAttrib2s(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLshort x,
+ GLshort y);
+bool ValidateVertexAttrib2sv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLshort *v);
+bool ValidateVertexAttrib3d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z);
+bool ValidateVertexAttrib3dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLdouble *v);
+bool ValidateVertexAttrib3s(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLshort x,
+ GLshort y,
+ GLshort z);
+bool ValidateVertexAttrib3sv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLshort *v);
+bool ValidateVertexAttrib4Nbv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLbyte *v);
+bool ValidateVertexAttrib4Niv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLint *v);
+bool ValidateVertexAttrib4Nsv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLshort *v);
+bool ValidateVertexAttrib4Nub(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLubyte x,
+ GLubyte y,
+ GLubyte z,
+ GLubyte w);
+bool ValidateVertexAttrib4Nubv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLubyte *v);
+bool ValidateVertexAttrib4Nuiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLuint *v);
+bool ValidateVertexAttrib4Nusv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLushort *v);
+bool ValidateVertexAttrib4bv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLbyte *v);
+bool ValidateVertexAttrib4d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z,
+ GLdouble w);
+bool ValidateVertexAttrib4dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLdouble *v);
+bool ValidateVertexAttrib4iv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLint *v);
+bool ValidateVertexAttrib4s(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLshort x,
+ GLshort y,
+ GLshort z,
+ GLshort w);
+bool ValidateVertexAttrib4sv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLshort *v);
+bool ValidateVertexAttrib4ubv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLubyte *v);
+bool ValidateVertexAttrib4uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLuint *v);
+bool ValidateVertexAttrib4usv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLushort *v);
+
+// GL 2.1
+} // namespace gl
+
+#endif // LIBANGLE_VALIDATION_GL2_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libANGLE/validationGL3.cpp b/gfx/angle/checkout/src/libANGLE/validationGL3.cpp
new file mode 100644
index 0000000000..1e452bd0f4
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/validationGL3.cpp
@@ -0,0 +1,634 @@
+//
+// Copyright 2019 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.
+//
+// validationGL3.cpp: Validation functions for OpenGL 3.0 entry point parameters
+
+#include "libANGLE/validationGL3_autogen.h"
+
+namespace gl
+{
+
+bool ValidateBeginConditionalRender(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint id,
+ GLenum mode)
+{
+ return true;
+}
+
+bool ValidateBindFragDataLocation(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLuint color,
+ const GLchar *name)
+{
+ return true;
+}
+
+bool ValidateClampColor(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum clamp)
+{
+ return true;
+}
+
+bool ValidateEndConditionalRender(const Context *context, angle::EntryPoint entryPoint)
+{
+ return true;
+}
+
+bool ValidateFramebufferTexture1D(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ TextureTarget textargetPacked,
+ TextureID texture,
+ GLint level)
+{
+ return true;
+}
+
+bool ValidateFramebufferTexture3D(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ TextureTarget textargetPacked,
+ TextureID texture,
+ GLint level,
+ GLint zoffset)
+{
+ return true;
+}
+
+bool ValidateVertexAttribI1i(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLint x)
+{
+ return true;
+}
+
+bool ValidateVertexAttribI1iv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLint *v)
+{
+ return true;
+}
+
+bool ValidateVertexAttribI1ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLuint x)
+{
+ return true;
+}
+
+bool ValidateVertexAttribI1uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLuint *v)
+{
+ return true;
+}
+
+bool ValidateVertexAttribI2i(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLint x,
+ GLint y)
+{
+ return true;
+}
+
+bool ValidateVertexAttribI2iv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLint *v)
+{
+ return true;
+}
+
+bool ValidateVertexAttribI2ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLuint x,
+ GLuint y)
+{
+ return true;
+}
+
+bool ValidateVertexAttribI2uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLuint *v)
+{
+ return true;
+}
+
+bool ValidateVertexAttribI3i(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLint x,
+ GLint y,
+ GLint z)
+{
+ return true;
+}
+
+bool ValidateVertexAttribI3iv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLint *v)
+{
+ return true;
+}
+
+bool ValidateVertexAttribI3ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLuint x,
+ GLuint y,
+ GLuint z)
+{
+ return true;
+}
+
+bool ValidateVertexAttribI3uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLuint *v)
+{
+ return true;
+}
+
+bool ValidateVertexAttribI4bv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLbyte *v)
+{
+ return true;
+}
+
+bool ValidateVertexAttribI4sv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLshort *v)
+{
+ return true;
+}
+
+bool ValidateVertexAttribI4ubv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLubyte *v)
+{
+ return true;
+}
+
+bool ValidateVertexAttribI4usv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLushort *v)
+{
+ return true;
+}
+
+bool ValidateGetActiveUniformName(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLuint uniformIndex,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLchar *uniformName)
+{
+ return true;
+}
+
+bool ValidatePrimitiveRestartIndex(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index)
+{
+ return true;
+}
+
+bool ValidateMultiDrawElementsBaseVertex(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ const GLsizei *count,
+ DrawElementsType type,
+ const void *const *indices,
+ GLsizei drawcount,
+ const GLint *basevertex)
+{
+ return true;
+}
+
+bool ValidateProvokingVertex(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProvokingVertexConvention modePacked)
+{
+ return true;
+}
+
+bool ValidateTexImage2DMultisample(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedsamplelocations)
+{
+ return true;
+}
+
+bool ValidateTexImage3DMultisample(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean fixedsamplelocations)
+{
+ return true;
+}
+
+bool ValidateBindFragDataLocationIndexed(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLuint colorNumber,
+ GLuint index,
+ const GLchar *name)
+{
+ return true;
+}
+
+bool ValidateColorP3ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ GLuint color)
+{
+ return true;
+}
+
+bool ValidateColorP3uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ const GLuint *color)
+{
+ return true;
+}
+
+bool ValidateColorP4ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ GLuint color)
+{
+ return true;
+}
+
+bool ValidateColorP4uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ const GLuint *color)
+{
+ return true;
+}
+
+bool ValidateGetFragDataIndex(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ const GLchar *name)
+{
+ return true;
+}
+
+bool ValidateGetQueryObjecti64v(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID id,
+ GLenum pname,
+ const GLint64 *params)
+{
+ return true;
+}
+
+bool ValidateGetQueryObjectui64v(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID id,
+ GLenum pname,
+ const GLuint64 *params)
+{
+ return true;
+}
+
+bool ValidateMultiTexCoordP1ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum texture,
+ GLenum type,
+ GLuint coords)
+{
+ return true;
+}
+
+bool ValidateMultiTexCoordP1uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum texture,
+ GLenum type,
+ const GLuint *coords)
+{
+ return true;
+}
+
+bool ValidateMultiTexCoordP2ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum texture,
+ GLenum type,
+ GLuint coords)
+{
+ return true;
+}
+
+bool ValidateMultiTexCoordP2uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum texture,
+ GLenum type,
+ const GLuint *coords)
+{
+ return true;
+}
+
+bool ValidateMultiTexCoordP3ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum texture,
+ GLenum type,
+ GLuint coords)
+{
+ return true;
+}
+
+bool ValidateMultiTexCoordP3uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum texture,
+ GLenum type,
+ const GLuint *coords)
+{
+ return true;
+}
+
+bool ValidateMultiTexCoordP4ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum texture,
+ GLenum type,
+ GLuint coords)
+{
+ return true;
+}
+
+bool ValidateMultiTexCoordP4uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum texture,
+ GLenum type,
+ const GLuint *coords)
+{
+ return true;
+}
+
+bool ValidateNormalP3ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ GLuint coords)
+{
+ return true;
+}
+
+bool ValidateNormalP3uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ const GLuint *coords)
+{
+ return true;
+}
+
+bool ValidateQueryCounter(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID id,
+ QueryType targetPacked)
+{
+ return true;
+}
+
+bool ValidateSecondaryColorP3ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ GLuint color)
+{
+ return true;
+}
+
+bool ValidateSecondaryColorP3uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ const GLuint *color)
+{
+ return true;
+}
+
+bool ValidateTexCoordP1ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ GLuint coords)
+{
+ return true;
+}
+
+bool ValidateTexCoordP1uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ const GLuint *coords)
+{
+ return true;
+}
+
+bool ValidateTexCoordP2ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ GLuint coords)
+{
+ return true;
+}
+
+bool ValidateTexCoordP2uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ const GLuint *coords)
+{
+ return true;
+}
+
+bool ValidateTexCoordP3ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ GLuint coords)
+{
+ return true;
+}
+
+bool ValidateTexCoordP3uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ const GLuint *coords)
+{
+ return true;
+}
+
+bool ValidateTexCoordP4ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ GLuint coords)
+{
+ return true;
+}
+
+bool ValidateTexCoordP4uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ const GLuint *coords)
+{
+ return true;
+}
+
+bool ValidateVertexAttribP1ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum type,
+ GLboolean normalized,
+ GLuint value)
+{
+ return true;
+}
+
+bool ValidateVertexAttribP1uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum type,
+ GLboolean normalized,
+ const GLuint *value)
+{
+ return true;
+}
+
+bool ValidateVertexAttribP2ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum type,
+ GLboolean normalized,
+ GLuint value)
+{
+ return true;
+}
+
+bool ValidateVertexAttribP2uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum type,
+ GLboolean normalized,
+ const GLuint *value)
+{
+ return true;
+}
+
+bool ValidateVertexAttribP3ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum type,
+ GLboolean normalized,
+ GLuint value)
+{
+ return true;
+}
+
+bool ValidateVertexAttribP3uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum type,
+ GLboolean normalized,
+ const GLuint *value)
+{
+ return true;
+}
+
+bool ValidateVertexAttribP4ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum type,
+ GLboolean normalized,
+ GLuint value)
+{
+ return true;
+}
+
+bool ValidateVertexAttribP4uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum type,
+ GLboolean normalized,
+ const GLuint *value)
+{
+ return true;
+}
+
+bool ValidateVertexP2ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ GLuint value)
+{
+ return true;
+}
+
+bool ValidateVertexP2uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ const GLuint *value)
+{
+ return true;
+}
+
+bool ValidateVertexP3ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ GLuint value)
+{
+ return true;
+}
+
+bool ValidateVertexP3uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ const GLuint *value)
+{
+ return true;
+}
+
+bool ValidateVertexP4ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ GLuint value)
+{
+ return true;
+}
+
+bool ValidateVertexP4uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ const GLuint *value)
+{
+ return true;
+}
+
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/validationGL3_autogen.h b/gfx/angle/checkout/src/libANGLE/validationGL3_autogen.h
new file mode 100644
index 0000000000..1f71153cb1
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/validationGL3_autogen.h
@@ -0,0 +1,367 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml.
+//
+// Copyright 2020 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.
+//
+// validationGL3_autogen.h:
+// Validation functions for the OpenGL Desktop GL 3.x entry points.
+
+#ifndef LIBANGLE_VALIDATION_GL3_AUTOGEN_H_
+#define LIBANGLE_VALIDATION_GL3_AUTOGEN_H_
+
+#include "common/PackedEnums.h"
+#include "common/entry_points_enum_autogen.h"
+
+namespace gl
+{
+class Context;
+
+// GL 3.0
+bool ValidateBeginConditionalRender(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint id,
+ GLenum mode);
+bool ValidateBindFragDataLocation(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ GLuint color,
+ const GLchar *name);
+bool ValidateClampColor(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum clamp);
+bool ValidateEndConditionalRender(const Context *context, angle::EntryPoint entryPoint);
+bool ValidateFramebufferTexture1D(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ TextureTarget textargetPacked,
+ TextureID texturePacked,
+ GLint level);
+bool ValidateFramebufferTexture3D(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum attachment,
+ TextureTarget textargetPacked,
+ TextureID texturePacked,
+ GLint level,
+ GLint zoffset);
+bool ValidateVertexAttribI1i(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLint x);
+bool ValidateVertexAttribI1iv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLint *v);
+bool ValidateVertexAttribI1ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLuint x);
+bool ValidateVertexAttribI1uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLuint *v);
+bool ValidateVertexAttribI2i(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLint x,
+ GLint y);
+bool ValidateVertexAttribI2iv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLint *v);
+bool ValidateVertexAttribI2ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLuint x,
+ GLuint y);
+bool ValidateVertexAttribI2uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLuint *v);
+bool ValidateVertexAttribI3i(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLint x,
+ GLint y,
+ GLint z);
+bool ValidateVertexAttribI3iv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLint *v);
+bool ValidateVertexAttribI3ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLuint x,
+ GLuint y,
+ GLuint z);
+bool ValidateVertexAttribI3uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLuint *v);
+bool ValidateVertexAttribI4bv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLbyte *v);
+bool ValidateVertexAttribI4sv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLshort *v);
+bool ValidateVertexAttribI4ubv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLubyte *v);
+bool ValidateVertexAttribI4usv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLushort *v);
+
+// GL 3.1
+bool ValidateGetActiveUniformName(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ GLuint uniformIndex,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLchar *uniformName);
+bool ValidatePrimitiveRestartIndex(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index);
+
+// GL 3.2
+bool ValidateMultiDrawElementsBaseVertex(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ const GLsizei *count,
+ DrawElementsType typePacked,
+ const void *const *indices,
+ GLsizei drawcount,
+ const GLint *basevertex);
+bool ValidateProvokingVertex(const Context *context,
+ angle::EntryPoint entryPoint,
+ ProvokingVertexConvention modePacked);
+bool ValidateTexImage2DMultisample(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedsamplelocations);
+bool ValidateTexImage3DMultisample(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean fixedsamplelocations);
+
+// GL 3.3
+bool ValidateBindFragDataLocationIndexed(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ GLuint colorNumber,
+ GLuint index,
+ const GLchar *name);
+bool ValidateColorP3ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ GLuint color);
+bool ValidateColorP3uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ const GLuint *color);
+bool ValidateColorP4ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ GLuint color);
+bool ValidateColorP4uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ const GLuint *color);
+bool ValidateGetFragDataIndex(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ const GLchar *name);
+bool ValidateGetQueryObjecti64v(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID idPacked,
+ GLenum pname,
+ const GLint64 *params);
+bool ValidateGetQueryObjectui64v(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID idPacked,
+ GLenum pname,
+ const GLuint64 *params);
+bool ValidateMultiTexCoordP1ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum texture,
+ GLenum type,
+ GLuint coords);
+bool ValidateMultiTexCoordP1uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum texture,
+ GLenum type,
+ const GLuint *coords);
+bool ValidateMultiTexCoordP2ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum texture,
+ GLenum type,
+ GLuint coords);
+bool ValidateMultiTexCoordP2uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum texture,
+ GLenum type,
+ const GLuint *coords);
+bool ValidateMultiTexCoordP3ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum texture,
+ GLenum type,
+ GLuint coords);
+bool ValidateMultiTexCoordP3uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum texture,
+ GLenum type,
+ const GLuint *coords);
+bool ValidateMultiTexCoordP4ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum texture,
+ GLenum type,
+ GLuint coords);
+bool ValidateMultiTexCoordP4uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum texture,
+ GLenum type,
+ const GLuint *coords);
+bool ValidateNormalP3ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ GLuint coords);
+bool ValidateNormalP3uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ const GLuint *coords);
+bool ValidateQueryCounter(const Context *context,
+ angle::EntryPoint entryPoint,
+ QueryID idPacked,
+ QueryType targetPacked);
+bool ValidateSecondaryColorP3ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ GLuint color);
+bool ValidateSecondaryColorP3uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ const GLuint *color);
+bool ValidateTexCoordP1ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ GLuint coords);
+bool ValidateTexCoordP1uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ const GLuint *coords);
+bool ValidateTexCoordP2ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ GLuint coords);
+bool ValidateTexCoordP2uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ const GLuint *coords);
+bool ValidateTexCoordP3ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ GLuint coords);
+bool ValidateTexCoordP3uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ const GLuint *coords);
+bool ValidateTexCoordP4ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ GLuint coords);
+bool ValidateTexCoordP4uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ const GLuint *coords);
+bool ValidateVertexAttribP1ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum type,
+ GLboolean normalized,
+ GLuint value);
+bool ValidateVertexAttribP1uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum type,
+ GLboolean normalized,
+ const GLuint *value);
+bool ValidateVertexAttribP2ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum type,
+ GLboolean normalized,
+ GLuint value);
+bool ValidateVertexAttribP2uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum type,
+ GLboolean normalized,
+ const GLuint *value);
+bool ValidateVertexAttribP3ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum type,
+ GLboolean normalized,
+ GLuint value);
+bool ValidateVertexAttribP3uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum type,
+ GLboolean normalized,
+ const GLuint *value);
+bool ValidateVertexAttribP4ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum type,
+ GLboolean normalized,
+ GLuint value);
+bool ValidateVertexAttribP4uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum type,
+ GLboolean normalized,
+ const GLuint *value);
+bool ValidateVertexP2ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ GLuint value);
+bool ValidateVertexP2uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ const GLuint *value);
+bool ValidateVertexP3ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ GLuint value);
+bool ValidateVertexP3uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ const GLuint *value);
+bool ValidateVertexP4ui(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ GLuint value);
+bool ValidateVertexP4uiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum type,
+ const GLuint *value);
+} // namespace gl
+
+#endif // LIBANGLE_VALIDATION_GL3_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libANGLE/validationGL4.cpp b/gfx/angle/checkout/src/libANGLE/validationGL4.cpp
new file mode 100644
index 0000000000..066391d1d9
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/validationGL4.cpp
@@ -0,0 +1,2223 @@
+//
+// Copyright 2019 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.
+//
+
+// validationGL4.cpp: Validation functions for OpenGL 4.0 entry point parameters
+
+#include "libANGLE/validationGL4_autogen.h"
+
+namespace gl
+{
+
+bool ValidateBeginQueryIndexed(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint index,
+ QueryID id)
+{
+ return true;
+}
+
+bool ValidateDrawTransformFeedback(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum mode,
+ TransformFeedbackID id)
+{
+ return true;
+}
+
+bool ValidateDrawTransformFeedbackStream(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum mode,
+ TransformFeedbackID id,
+ GLuint stream)
+{
+ return true;
+}
+
+bool ValidateEndQueryIndexed(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint index)
+{
+ return true;
+}
+
+bool ValidateGetActiveSubroutineName(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLenum shadertype,
+ GLuint index,
+ GLsizei bufsize,
+ const GLsizei *length,
+ const GLchar *name)
+{
+ return true;
+}
+
+bool ValidateGetActiveSubroutineUniformName(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLenum shadertype,
+ GLuint index,
+ GLsizei bufsize,
+ const GLsizei *length,
+ const GLchar *name)
+{
+ return true;
+}
+
+bool ValidateGetActiveSubroutineUniformiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLenum shadertype,
+ GLuint index,
+ GLenum pname,
+ const GLint *values)
+{
+ return true;
+}
+
+bool ValidateGetProgramStageiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLenum shadertype,
+ GLenum pname,
+ const GLint *values)
+{
+ return true;
+}
+
+bool ValidateGetQueryIndexediv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint index,
+ GLenum pname,
+ const GLint *params)
+{
+ return true;
+}
+
+bool ValidateGetSubroutineIndex(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLenum shadertype,
+ const GLchar *name)
+{
+ return true;
+}
+
+bool ValidateGetSubroutineUniformLocation(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLenum shadertype,
+ const GLchar *name)
+{
+ return true;
+}
+
+bool ValidateGetUniformSubroutineuiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum shadertype,
+ GLint location,
+ const GLuint *params)
+{
+ return true;
+}
+
+bool ValidateGetUniformdv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ const GLdouble *params)
+{
+ return true;
+}
+
+bool ValidatePatchParameterfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ const GLfloat *values)
+{
+ return true;
+}
+
+bool ValidateUniform1d(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLdouble x)
+{
+ return true;
+}
+
+bool ValidateUniform1dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLsizei count,
+ const GLdouble *value)
+{
+ return true;
+}
+
+bool ValidateUniform2d(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLdouble x,
+ GLdouble y)
+{
+ return true;
+}
+
+bool ValidateUniform2dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLsizei count,
+ const GLdouble *value)
+{
+ return true;
+}
+
+bool ValidateUniform3d(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z)
+{
+ return true;
+}
+
+bool ValidateUniform3dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLsizei count,
+ const GLdouble *value)
+{
+ return true;
+}
+
+bool ValidateUniform4d(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z,
+ GLdouble w)
+{
+ return true;
+}
+
+bool ValidateUniform4dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLsizei count,
+ const GLdouble *value)
+{
+ return true;
+}
+
+bool ValidateUniformMatrix2dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ return true;
+}
+
+bool ValidateUniformMatrix2x3dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ return true;
+}
+
+bool ValidateUniformMatrix2x4dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ return true;
+}
+
+bool ValidateUniformMatrix3dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ return true;
+}
+
+bool ValidateUniformMatrix3x2dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ return true;
+}
+
+bool ValidateUniformMatrix3x4dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ return true;
+}
+
+bool ValidateUniformMatrix4dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ return true;
+}
+
+bool ValidateUniformMatrix4x2dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ return true;
+}
+
+bool ValidateUniformMatrix4x3dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ return true;
+}
+
+bool ValidateUniformSubroutinesuiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum shadertype,
+ GLsizei count,
+ const GLuint *indices)
+{
+ return true;
+}
+
+bool ValidateDepthRangeArrayv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint first,
+ GLsizei count,
+ const GLdouble *v)
+{
+ return true;
+}
+
+bool ValidateDepthRangeIndexed(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLdouble n,
+ GLdouble f)
+{
+ return true;
+}
+
+bool ValidateGetDoublei_v(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint index,
+ const GLdouble *data)
+{
+ return true;
+}
+
+bool ValidateGetFloati_v(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint index,
+ const GLfloat *data)
+{
+ return true;
+}
+
+bool ValidateGetVertexAttribLdv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum pname,
+ const GLdouble *params)
+{
+ return true;
+}
+
+bool ValidateProgramUniform1d(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLdouble v0)
+{
+ return true;
+}
+
+bool ValidateProgramUniform1dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ const GLdouble *value)
+{
+ return true;
+}
+
+bool ValidateProgramUniform2d(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLdouble v0,
+ GLdouble v1)
+{
+ return true;
+}
+
+bool ValidateProgramUniform2dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ const GLdouble *value)
+{
+ return true;
+}
+
+bool ValidateProgramUniform3d(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLdouble v0,
+ GLdouble v1,
+ GLdouble v2)
+{
+ return true;
+}
+
+bool ValidateProgramUniform3dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ const GLdouble *value)
+{
+ return true;
+}
+
+bool ValidateProgramUniform4d(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLdouble v0,
+ GLdouble v1,
+ GLdouble v2,
+ GLdouble v3)
+{
+ return true;
+}
+
+bool ValidateProgramUniform4dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ const GLdouble *value)
+{
+ return true;
+}
+
+bool ValidateProgramUniformMatrix2dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ return true;
+}
+
+bool ValidateProgramUniformMatrix2x3dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ return true;
+}
+
+bool ValidateProgramUniformMatrix2x4dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ return true;
+}
+
+bool ValidateProgramUniformMatrix3dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ return true;
+}
+
+bool ValidateProgramUniformMatrix3x2dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ return true;
+}
+
+bool ValidateProgramUniformMatrix3x4dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ return true;
+}
+
+bool ValidateProgramUniformMatrix4dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ return true;
+}
+
+bool ValidateProgramUniformMatrix4x2dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ return true;
+}
+
+bool ValidateProgramUniformMatrix4x3dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ return true;
+}
+
+bool ValidateScissorArrayv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint first,
+ GLsizei count,
+ const GLint *v)
+{
+ return true;
+}
+
+bool ValidateScissorIndexed(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLint left,
+ GLint bottom,
+ GLsizei width,
+ GLsizei height)
+{
+ return true;
+}
+
+bool ValidateScissorIndexedv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLint *v)
+{
+ return true;
+}
+
+bool ValidateVertexAttribL1d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLdouble x)
+{
+ return true;
+}
+
+bool ValidateVertexAttribL1dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLdouble *v)
+{
+ return true;
+}
+
+bool ValidateVertexAttribL2d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLdouble x,
+ GLdouble y)
+{
+ return true;
+}
+
+bool ValidateVertexAttribL2dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLdouble *v)
+{
+ return true;
+}
+
+bool ValidateVertexAttribL3d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z)
+{
+ return true;
+}
+
+bool ValidateVertexAttribL3dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLdouble *v)
+{
+ return true;
+}
+
+bool ValidateVertexAttribL4d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z,
+ GLdouble w)
+{
+ return true;
+}
+
+bool ValidateVertexAttribL4dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLdouble *v)
+{
+ return true;
+}
+
+bool ValidateVertexAttribLPointer(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLint size,
+ GLenum type,
+ GLsizei stride,
+ const void *pointer)
+{
+ return true;
+}
+
+bool ValidateViewportArrayv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint first,
+ GLsizei count,
+ const GLfloat *v)
+{
+ return true;
+}
+
+bool ValidateViewportIndexedf(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLfloat x,
+ GLfloat y,
+ GLfloat w,
+ GLfloat h)
+{
+ return true;
+}
+
+bool ValidateViewportIndexedfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLfloat *v)
+{
+ return true;
+}
+
+bool ValidateDrawArraysInstancedBaseInstance(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLint first,
+ GLsizei count,
+ GLsizei instancecount,
+ GLuint baseinstance)
+{
+ return true;
+}
+
+bool ValidateDrawElementsInstancedBaseInstance(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLsizei count,
+ DrawElementsType type,
+ const void *indices,
+ GLsizei instancecount,
+ GLuint baseinstance)
+{
+ return true;
+}
+
+bool ValidateDrawElementsInstancedBaseVertexBaseInstance(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode mode,
+ GLsizei count,
+ DrawElementsType type,
+ const void *indices,
+ GLsizei instancecount,
+ GLint basevertex,
+ GLuint baseinstance)
+{
+ return true;
+}
+
+bool ValidateDrawTransformFeedbackInstanced(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum mode,
+ TransformFeedbackID id,
+ GLsizei instancecount)
+{
+ return true;
+}
+
+bool ValidateDrawTransformFeedbackStreamInstanced(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum mode,
+ TransformFeedbackID id,
+ GLuint stream,
+ GLsizei instancecount)
+{
+ return true;
+}
+
+bool ValidateGetActiveAtomicCounterBufferiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLuint bufferIndex,
+ GLenum pname,
+ const GLint *params)
+{
+ return true;
+}
+
+bool ValidateTexStorage1D(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width)
+{
+ return true;
+}
+
+bool ValidateClearBufferData(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum internalformat,
+ GLenum format,
+ GLenum type,
+ const void *data)
+{
+ return true;
+}
+
+bool ValidateClearBufferSubData(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum internalformat,
+ GLintptr offset,
+ GLsizeiptr size,
+ GLenum format,
+ GLenum type,
+ const void *data)
+{
+ return true;
+}
+
+bool ValidateGetInternalformati64v(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum internalformat,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLint64 *params)
+{
+ return true;
+}
+
+bool ValidateGetProgramResourceLocationIndex(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLenum programInterface,
+ const GLchar *name)
+{
+ return true;
+}
+
+bool ValidateInvalidateBufferData(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferID buffer)
+{
+ return true;
+}
+
+bool ValidateInvalidateBufferSubData(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferID buffer,
+ GLintptr offset,
+ GLsizeiptr length)
+{
+ return true;
+}
+
+bool ValidateInvalidateTexImage(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texture,
+ GLint level)
+{
+ return true;
+}
+
+bool ValidateInvalidateTexSubImage(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texture,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth)
+{
+ return true;
+}
+
+bool ValidateMultiDrawArraysIndirect(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ const void *indirect,
+ GLsizei drawcount,
+ GLsizei stride)
+{
+ return true;
+}
+
+bool ValidateMultiDrawElementsIndirect(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ DrawElementsType typePacked,
+ const void *indirect,
+ GLsizei drawcount,
+ GLsizei stride)
+{
+ return true;
+}
+
+bool ValidateShaderStorageBlockBinding(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ GLuint storageBlockIndex,
+ GLuint storageBlockBinding)
+{
+ return true;
+}
+
+bool ValidateTextureView(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texture,
+ GLenum target,
+ GLuint origtexture,
+ GLenum internalformat,
+ GLuint minlevel,
+ GLuint numlevels,
+ GLuint minlayer,
+ GLuint numlayers)
+{
+ return true;
+}
+
+bool ValidateVertexAttribLFormat(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint attribindex,
+ GLint size,
+ GLenum type,
+ GLuint relativeoffset)
+{
+ return true;
+}
+
+bool ValidateBindBuffersBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint first,
+ GLsizei count,
+ const BufferID *buffers)
+{
+ return true;
+}
+
+bool ValidateBindBuffersRange(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint first,
+ GLsizei count,
+ const BufferID *buffers,
+ const GLintptr *offsets,
+ const GLsizeiptr *sizes)
+{
+ return true;
+}
+
+bool ValidateBindImageTextures(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint first,
+ GLsizei count,
+ const GLuint *textures)
+{
+ return true;
+}
+
+bool ValidateBindSamplers(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint first,
+ GLsizei count,
+ const GLuint *samplers)
+{
+ return true;
+}
+
+bool ValidateBindTextures(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint first,
+ GLsizei count,
+ const GLuint *textures)
+{
+ return true;
+}
+
+bool ValidateBindVertexBuffers(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint first,
+ GLsizei count,
+ const BufferID *buffers,
+ const GLintptr *offsets,
+ const GLsizei *strides)
+{
+ return true;
+}
+
+bool ValidateBufferStorage(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding targetPacked,
+ GLsizeiptr size,
+ const void *data,
+ GLbitfield flags)
+{
+ return true;
+}
+
+bool ValidateClearTexImage(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texture,
+ GLint level,
+ GLenum format,
+ GLenum type,
+ const void *data)
+{
+ return true;
+}
+
+bool ValidateClearTexSubImage(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texture,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ const void *data)
+{
+ return true;
+}
+
+bool ValidateBindTextureUnit(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint unit,
+ TextureID texture)
+{
+ return true;
+}
+
+bool ValidateBlitNamedFramebuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint readFramebuffer,
+ GLuint drawFramebuffer,
+ GLint srcX0,
+ GLint srcY0,
+ GLint srcX1,
+ GLint srcY1,
+ GLint dstX0,
+ GLint dstY0,
+ GLint dstX1,
+ GLint dstY1,
+ GLbitfield mask,
+ GLenum filter)
+{
+ return true;
+}
+
+bool ValidateCheckNamedFramebufferStatus(const Context *context,
+ angle::EntryPoint entryPoint,
+ FramebufferID framebuffer,
+ GLenum target)
+{
+ return true;
+}
+
+bool ValidateClearNamedBufferData(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferID buffer,
+ GLenum internalformat,
+ GLenum format,
+ GLenum type,
+ const void *data)
+{
+ return true;
+}
+
+bool ValidateClearNamedBufferSubData(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferID buffer,
+ GLenum internalformat,
+ GLintptr offset,
+ GLsizeiptr size,
+ GLenum format,
+ GLenum type,
+ const void *data)
+{
+ return true;
+}
+
+bool ValidateClearNamedFramebufferfi(const Context *context,
+ angle::EntryPoint entryPoint,
+ FramebufferID framebuffer,
+ GLenum buffer,
+ GLint drawbuffer,
+ GLfloat depth,
+ GLint stencil)
+{
+ return true;
+}
+
+bool ValidateClearNamedFramebufferfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ FramebufferID framebuffer,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLfloat *value)
+{
+ return true;
+}
+
+bool ValidateClearNamedFramebufferiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ FramebufferID framebuffer,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLint *value)
+{
+ return true;
+}
+
+bool ValidateClearNamedFramebufferuiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ FramebufferID framebuffer,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLuint *value)
+{
+ return true;
+}
+
+bool ValidateClipControl(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum origin,
+ GLenum depth)
+{
+ return true;
+}
+
+bool ValidateCompressedTextureSubImage1D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texture,
+ GLint level,
+ GLint xoffset,
+ GLsizei width,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data)
+{
+ return true;
+}
+
+bool ValidateCompressedTextureSubImage2D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texture,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data)
+{
+ return true;
+}
+
+bool ValidateCompressedTextureSubImage3D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texture,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data)
+{
+ return true;
+}
+
+bool ValidateCopyNamedBufferSubData(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint readBuffer,
+ GLuint writeBuffer,
+ GLintptr readOffset,
+ GLintptr writeOffset,
+ GLsizeiptr size)
+{
+ return true;
+}
+
+bool ValidateCopyTextureSubImage1D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texture,
+ GLint level,
+ GLint xoffset,
+ GLint x,
+ GLint y,
+ GLsizei width)
+{
+ return true;
+}
+
+bool ValidateCopyTextureSubImage2D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texture,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height)
+{
+ return true;
+}
+
+bool ValidateCopyTextureSubImage3D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texture,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height)
+{
+ return true;
+}
+
+bool ValidateCreateBuffers(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const BufferID *buffers)
+{
+ return true;
+}
+
+bool ValidateCreateFramebuffers(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const GLuint *framebuffers)
+{
+ return true;
+}
+
+bool ValidateCreateProgramPipelines(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const GLuint *pipelines)
+{
+ return true;
+}
+
+bool ValidateCreateQueries(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLsizei n,
+ const GLuint *ids)
+{
+ return true;
+}
+
+bool ValidateCreateRenderbuffers(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const RenderbufferID *renderbuffers)
+{
+ return true;
+}
+
+bool ValidateCreateSamplers(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const GLuint *samplers)
+{
+ return true;
+}
+
+bool ValidateCreateTextures(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLsizei n,
+ const GLuint *textures)
+{
+ return true;
+}
+
+bool ValidateCreateTransformFeedbacks(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const GLuint *ids)
+{
+ return true;
+}
+
+bool ValidateCreateVertexArrays(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const VertexArrayID *arrays)
+{
+ return true;
+}
+
+bool ValidateDisableVertexArrayAttrib(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexArrayID vaobj,
+ GLuint index)
+{
+ return true;
+}
+
+bool ValidateEnableVertexArrayAttrib(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexArrayID vaobj,
+ GLuint index)
+{
+ return true;
+}
+
+bool ValidateFlushMappedNamedBufferRange(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferID buffer,
+ GLintptr offset,
+ GLsizeiptr length)
+{
+ return true;
+}
+
+bool ValidateGenerateTextureMipmap(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texture)
+{
+ return true;
+}
+
+bool ValidateGetCompressedTextureImage(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texture,
+ GLint level,
+ GLsizei bufSize,
+ const void *pixels)
+{
+ return true;
+}
+
+bool ValidateGetCompressedTextureSubImage(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texture,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLsizei bufSize,
+ const void *pixels)
+{
+ return true;
+}
+
+bool ValidateGetNamedBufferParameteri64v(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferID buffer,
+ GLenum pname,
+ const GLint64 *params)
+{
+ return true;
+}
+
+bool ValidateGetNamedBufferParameteriv(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferID buffer,
+ GLenum pname,
+ const GLint *params)
+{
+ return true;
+}
+
+bool ValidateGetNamedBufferPointerv(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferID buffer,
+ GLenum pname,
+ void *const *params)
+{
+ return true;
+}
+
+bool ValidateGetNamedBufferSubData(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferID buffer,
+ GLintptr offset,
+ GLsizeiptr size,
+ const void *data)
+{
+ return true;
+}
+
+bool ValidateGetNamedFramebufferAttachmentParameteriv(const Context *context,
+ angle::EntryPoint entryPoint,
+ FramebufferID framebuffer,
+ GLenum attachment,
+ GLenum pname,
+ const GLint *params)
+{
+ return true;
+}
+
+bool ValidateGetNamedFramebufferParameteriv(const Context *context,
+ angle::EntryPoint entryPoint,
+ FramebufferID framebuffer,
+ GLenum pname,
+ const GLint *param)
+{
+ return true;
+}
+
+bool ValidateGetNamedRenderbufferParameteriv(const Context *context,
+ angle::EntryPoint entryPoint,
+ RenderbufferID renderbuffer,
+ GLenum pname,
+ const GLint *params)
+{
+ return true;
+}
+
+bool ValidateGetQueryBufferObjecti64v(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint id,
+ BufferID buffer,
+ GLenum pname,
+ GLintptr offset)
+{
+ return true;
+}
+
+bool ValidateGetQueryBufferObjectiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint id,
+ BufferID buffer,
+ GLenum pname,
+ GLintptr offset)
+{
+ return true;
+}
+
+bool ValidateGetQueryBufferObjectui64v(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint id,
+ BufferID buffer,
+ GLenum pname,
+ GLintptr offset)
+{
+ return true;
+}
+
+bool ValidateGetQueryBufferObjectuiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint id,
+ BufferID buffer,
+ GLenum pname,
+ GLintptr offset)
+{
+ return true;
+}
+
+bool ValidateGetTextureImage(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texture,
+ GLint level,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *pixels)
+{
+ return true;
+}
+
+bool ValidateGetTextureLevelParameterfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texture,
+ GLint level,
+ GLenum pname,
+ const GLfloat *params)
+{
+ return true;
+}
+
+bool ValidateGetTextureLevelParameteriv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texture,
+ GLint level,
+ GLenum pname,
+ const GLint *params)
+{
+ return true;
+}
+
+bool ValidateGetTextureParameterIiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texture,
+ GLenum pname,
+ const GLint *params)
+{
+ return true;
+}
+
+bool ValidateGetTextureParameterIuiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texture,
+ GLenum pname,
+ const GLuint *params)
+{
+ return true;
+}
+
+bool ValidateGetTextureParameterfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texture,
+ GLenum pname,
+ const GLfloat *params)
+{
+ return true;
+}
+
+bool ValidateGetTextureParameteriv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texture,
+ GLenum pname,
+ const GLint *params)
+{
+ return true;
+}
+
+bool ValidateGetTextureSubImage(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texture,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *pixels)
+{
+ return true;
+}
+
+bool ValidateGetTransformFeedbacki64_v(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint xfb,
+ GLenum pname,
+ GLuint index,
+ const GLint64 *param)
+{
+ return true;
+}
+
+bool ValidateGetTransformFeedbacki_v(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint xfb,
+ GLenum pname,
+ GLuint index,
+ const GLint *param)
+{
+ return true;
+}
+
+bool ValidateGetTransformFeedbackiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint xfb,
+ GLenum pname,
+ const GLint *param)
+{
+ return true;
+}
+
+bool ValidateGetVertexArrayIndexed64iv(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexArrayID vaobj,
+ GLuint index,
+ GLenum pname,
+ const GLint64 *param)
+{
+ return true;
+}
+
+bool ValidateGetVertexArrayIndexediv(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexArrayID vaobj,
+ GLuint index,
+ GLenum pname,
+ const GLint *param)
+{
+ return true;
+}
+
+bool ValidateGetVertexArrayiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexArrayID vaobj,
+ GLenum pname,
+ const GLint *param)
+{
+ return true;
+}
+
+bool ValidateGetnColorTable(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *table)
+{
+ return true;
+}
+
+bool ValidateGetnCompressedTexImage(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLint lod,
+ GLsizei bufSize,
+ const void *pixels)
+{
+ return true;
+}
+
+bool ValidateGetnConvolutionFilter(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *image)
+{
+ return true;
+}
+
+bool ValidateGetnHistogram(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLboolean reset,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *values)
+{
+ return true;
+}
+
+bool ValidateGetnMapdv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum query,
+ GLsizei bufSize,
+ const GLdouble *v)
+{
+ return true;
+}
+
+bool ValidateGetnMapfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum query,
+ GLsizei bufSize,
+ const GLfloat *v)
+{
+ return true;
+}
+
+bool ValidateGetnMapiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum query,
+ GLsizei bufSize,
+ const GLint *v)
+{
+ return true;
+}
+
+bool ValidateGetnMinmax(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLboolean reset,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *values)
+{
+ return true;
+}
+
+bool ValidateGetnPixelMapfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum map,
+ GLsizei bufSize,
+ const GLfloat *values)
+{
+ return true;
+}
+
+bool ValidateGetnPixelMapuiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum map,
+ GLsizei bufSize,
+ const GLuint *values)
+{
+ return true;
+}
+
+bool ValidateGetnPixelMapusv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum map,
+ GLsizei bufSize,
+ const GLushort *values)
+{
+ return true;
+}
+
+bool ValidateGetnPolygonStipple(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei bufSize,
+ const GLubyte *pattern)
+{
+ return true;
+}
+
+bool ValidateGetnSeparableFilter(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum format,
+ GLenum type,
+ GLsizei rowBufSize,
+ const void *row,
+ GLsizei columnBufSize,
+ const void *column,
+ const void *span)
+{
+ return true;
+}
+
+bool ValidateGetnTexImage(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLint level,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *pixels)
+{
+ return true;
+}
+
+bool ValidateGetnUniformdv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID program,
+ UniformLocation location,
+ GLsizei bufSize,
+ const GLdouble *params)
+{
+ return true;
+}
+
+bool ValidateInvalidateNamedFramebufferData(const Context *context,
+ angle::EntryPoint entryPoint,
+ FramebufferID framebuffer,
+ GLsizei numAttachments,
+ const GLenum *attachments)
+{
+ return true;
+}
+
+bool ValidateInvalidateNamedFramebufferSubData(const Context *context,
+ angle::EntryPoint entryPoint,
+ FramebufferID framebuffer,
+ GLsizei numAttachments,
+ const GLenum *attachments,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height)
+{
+ return true;
+}
+
+bool ValidateMapNamedBuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferID buffer,
+ GLenum access)
+{
+ return true;
+}
+
+bool ValidateMapNamedBufferRange(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferID buffer,
+ GLintptr offset,
+ GLsizeiptr length,
+ GLbitfield access)
+{
+ return true;
+}
+
+bool ValidateNamedBufferData(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferID buffer,
+ GLsizeiptr size,
+ const void *data,
+ GLenum usage)
+{
+ return true;
+}
+
+bool ValidateNamedBufferStorage(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferID buffer,
+ GLsizeiptr size,
+ const void *data,
+ GLbitfield flags)
+{
+ return true;
+}
+
+bool ValidateNamedBufferSubData(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferID buffer,
+ GLintptr offset,
+ GLsizeiptr size,
+ const void *data)
+{
+ return true;
+}
+
+bool ValidateNamedFramebufferDrawBuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ FramebufferID framebuffer,
+ GLenum buf)
+{
+ return true;
+}
+
+bool ValidateNamedFramebufferDrawBuffers(const Context *context,
+ angle::EntryPoint entryPoint,
+ FramebufferID framebuffer,
+ GLsizei n,
+ const GLenum *bufs)
+{
+ return true;
+}
+
+bool ValidateNamedFramebufferParameteri(const Context *context,
+ angle::EntryPoint entryPoint,
+ FramebufferID framebuffer,
+ GLenum pname,
+ GLint param)
+{
+ return true;
+}
+
+bool ValidateNamedFramebufferReadBuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ FramebufferID framebuffer,
+ GLenum src)
+{
+ return true;
+}
+
+bool ValidateNamedFramebufferRenderbuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ FramebufferID framebuffer,
+ GLenum attachment,
+ GLenum renderbuffertarget,
+ RenderbufferID renderbuffer)
+{
+ return true;
+}
+
+bool ValidateNamedFramebufferTexture(const Context *context,
+ angle::EntryPoint entryPoint,
+ FramebufferID framebuffer,
+ GLenum attachment,
+ TextureID texture,
+ GLint level)
+{
+ return true;
+}
+
+bool ValidateNamedFramebufferTextureLayer(const Context *context,
+ angle::EntryPoint entryPoint,
+ FramebufferID framebuffer,
+ GLenum attachment,
+ TextureID texture,
+ GLint level,
+ GLint layer)
+{
+ return true;
+}
+
+bool ValidateNamedRenderbufferStorage(const Context *context,
+ angle::EntryPoint entryPoint,
+ RenderbufferID renderbuffer,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height)
+{
+ return true;
+}
+
+bool ValidateNamedRenderbufferStorageMultisample(const Context *context,
+ angle::EntryPoint entryPoint,
+ RenderbufferID renderbuffer,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height)
+{
+ return true;
+}
+
+bool ValidateTextureBarrier(const Context *context, angle::EntryPoint entryPoint)
+{
+ return true;
+}
+
+bool ValidateTextureBuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texture,
+ GLenum internalformat,
+ BufferID buffer)
+{
+ return true;
+}
+
+bool ValidateTextureBufferRange(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texture,
+ GLenum internalformat,
+ BufferID buffer,
+ GLintptr offset,
+ GLsizeiptr size)
+{
+ return true;
+}
+
+bool ValidateTextureParameterIiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texture,
+ GLenum pname,
+ const GLint *params)
+{
+ return true;
+}
+
+bool ValidateTextureParameterIuiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texture,
+ GLenum pname,
+ const GLuint *params)
+{
+ return true;
+}
+
+bool ValidateTextureParameterf(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texture,
+ GLenum pname,
+ GLfloat param)
+{
+ return true;
+}
+
+bool ValidateTextureParameterfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texture,
+ GLenum pname,
+ const GLfloat *param)
+{
+ return true;
+}
+
+bool ValidateTextureParameteri(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texture,
+ GLenum pname,
+ GLint param)
+{
+ return true;
+}
+
+bool ValidateTextureParameteriv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texture,
+ GLenum pname,
+ const GLint *param)
+{
+ return true;
+}
+
+bool ValidateTextureStorage1D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texture,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width)
+{
+ return true;
+}
+
+bool ValidateTextureStorage2D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texture,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height)
+{
+ return true;
+}
+
+bool ValidateTextureStorage2DMultisample(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texture,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedsamplelocations)
+{
+ return true;
+}
+
+bool ValidateTextureStorage3D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texture,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth)
+{
+ return true;
+}
+
+bool ValidateTextureStorage3DMultisample(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texture,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean fixedsamplelocations)
+{
+ return true;
+}
+
+bool ValidateTextureSubImage1D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texture,
+ GLint level,
+ GLint xoffset,
+ GLsizei width,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ return true;
+}
+
+bool ValidateTextureSubImage2D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texture,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ return true;
+}
+
+bool ValidateTextureSubImage3D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texture,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ return true;
+}
+
+bool ValidateTransformFeedbackBufferBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint xfb,
+ GLuint index,
+ BufferID buffer)
+{
+ return true;
+}
+
+bool ValidateTransformFeedbackBufferRange(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint xfb,
+ GLuint index,
+ BufferID buffer,
+ GLintptr offset,
+ GLsizeiptr size)
+{
+ return true;
+}
+
+bool ValidateUnmapNamedBuffer(const Context *context, angle::EntryPoint entryPoint, BufferID buffer)
+{
+ return true;
+}
+
+bool ValidateVertexArrayAttribBinding(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexArrayID vaobj,
+ GLuint attribindex,
+ GLuint bindingindex)
+{
+ return true;
+}
+
+bool ValidateVertexArrayAttribFormat(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexArrayID vaobj,
+ GLuint attribindex,
+ GLint size,
+ GLenum type,
+ GLboolean normalized,
+ GLuint relativeoffset)
+{
+ return true;
+}
+
+bool ValidateVertexArrayAttribIFormat(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexArrayID vaobj,
+ GLuint attribindex,
+ GLint size,
+ GLenum type,
+ GLuint relativeoffset)
+{
+ return true;
+}
+
+bool ValidateVertexArrayAttribLFormat(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexArrayID vaobj,
+ GLuint attribindex,
+ GLint size,
+ GLenum type,
+ GLuint relativeoffset)
+{
+ return true;
+}
+
+bool ValidateVertexArrayBindingDivisor(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexArrayID vaobj,
+ GLuint bindingindex,
+ GLuint divisor)
+{
+ return true;
+}
+
+bool ValidateVertexArrayElementBuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexArrayID vaobj,
+ BufferID buffer)
+{
+ return true;
+}
+
+bool ValidateVertexArrayVertexBuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexArrayID vaobj,
+ GLuint bindingindex,
+ BufferID buffer,
+ GLintptr offset,
+ GLsizei stride)
+{
+ return true;
+}
+
+bool ValidateVertexArrayVertexBuffers(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexArrayID vaobj,
+ GLuint first,
+ GLsizei count,
+ const BufferID *buffers,
+ const GLintptr *offsets,
+ const GLsizei *strides)
+{
+ return true;
+}
+
+bool ValidateMultiDrawArraysIndirectCount(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum mode,
+ const void *indirect,
+ GLintptr drawcount,
+ GLsizei maxdrawcount,
+ GLsizei stride)
+{
+ return true;
+}
+
+bool ValidateMultiDrawElementsIndirectCount(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum mode,
+ GLenum type,
+ const void *indirect,
+ GLintptr drawcount,
+ GLsizei maxdrawcount,
+ GLsizei stride)
+{
+ return true;
+}
+
+bool ValidatePolygonOffsetClamp(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat factor,
+ GLfloat units,
+ GLfloat clamp)
+{
+ return true;
+}
+
+bool ValidateSpecializeShader(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint shader,
+ const GLchar *pEntryPoint,
+ GLuint numSpecializationConstants,
+ const GLuint *pConstantIndex,
+ const GLuint *pConstantValue)
+{
+ return true;
+}
+
+} // namespace gl
diff --git a/gfx/angle/checkout/src/libANGLE/validationGL4_autogen.h b/gfx/angle/checkout/src/libANGLE/validationGL4_autogen.h
new file mode 100644
index 0000000000..a69a1f2092
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/validationGL4_autogen.h
@@ -0,0 +1,1375 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml.
+//
+// Copyright 2020 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.
+//
+// validationGL4_autogen.h:
+// Validation functions for the OpenGL Desktop GL 4.x entry points.
+
+#ifndef LIBANGLE_VALIDATION_GL4_AUTOGEN_H_
+#define LIBANGLE_VALIDATION_GL4_AUTOGEN_H_
+
+#include "common/PackedEnums.h"
+#include "common/entry_points_enum_autogen.h"
+
+namespace gl
+{
+class Context;
+
+// GL 4.0
+bool ValidateBeginQueryIndexed(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint index,
+ QueryID idPacked);
+bool ValidateDrawTransformFeedback(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum mode,
+ TransformFeedbackID idPacked);
+bool ValidateDrawTransformFeedbackStream(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum mode,
+ TransformFeedbackID idPacked,
+ GLuint stream);
+bool ValidateEndQueryIndexed(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint index);
+bool ValidateGetActiveSubroutineName(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ GLenum shadertype,
+ GLuint index,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLchar *name);
+bool ValidateGetActiveSubroutineUniformName(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ GLenum shadertype,
+ GLuint index,
+ GLsizei bufSize,
+ const GLsizei *length,
+ const GLchar *name);
+bool ValidateGetActiveSubroutineUniformiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ GLenum shadertype,
+ GLuint index,
+ GLenum pname,
+ const GLint *values);
+bool ValidateGetProgramStageiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ GLenum shadertype,
+ GLenum pname,
+ const GLint *values);
+bool ValidateGetQueryIndexediv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint index,
+ GLenum pname,
+ const GLint *params);
+bool ValidateGetSubroutineIndex(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ GLenum shadertype,
+ const GLchar *name);
+bool ValidateGetSubroutineUniformLocation(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ GLenum shadertype,
+ const GLchar *name);
+bool ValidateGetUniformSubroutineuiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum shadertype,
+ GLint location,
+ const GLuint *params);
+bool ValidateGetUniformdv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ const GLdouble *params);
+bool ValidatePatchParameterfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum pname,
+ const GLfloat *values);
+bool ValidateUniform1d(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLdouble x);
+bool ValidateUniform1dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLdouble *value);
+bool ValidateUniform2d(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLdouble x,
+ GLdouble y);
+bool ValidateUniform2dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLdouble *value);
+bool ValidateUniform3d(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z);
+bool ValidateUniform3dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLdouble *value);
+bool ValidateUniform4d(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z,
+ GLdouble w);
+bool ValidateUniform4dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLdouble *value);
+bool ValidateUniformMatrix2dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value);
+bool ValidateUniformMatrix2x3dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value);
+bool ValidateUniformMatrix2x4dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value);
+bool ValidateUniformMatrix3dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value);
+bool ValidateUniformMatrix3x2dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value);
+bool ValidateUniformMatrix3x4dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value);
+bool ValidateUniformMatrix4dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value);
+bool ValidateUniformMatrix4x2dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value);
+bool ValidateUniformMatrix4x3dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value);
+bool ValidateUniformSubroutinesuiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum shadertype,
+ GLsizei count,
+ const GLuint *indices);
+
+// GL 4.1
+bool ValidateDepthRangeArrayv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint first,
+ GLsizei count,
+ const GLdouble *v);
+bool ValidateDepthRangeIndexed(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLdouble n,
+ GLdouble f);
+bool ValidateGetDoublei_v(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint index,
+ const GLdouble *data);
+bool ValidateGetFloati_v(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint index,
+ const GLfloat *data);
+bool ValidateGetVertexAttribLdv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLenum pname,
+ const GLdouble *params);
+bool ValidateProgramUniform1d(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLdouble v0);
+bool ValidateProgramUniform1dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLdouble *value);
+bool ValidateProgramUniform2d(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLdouble v0,
+ GLdouble v1);
+bool ValidateProgramUniform2dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLdouble *value);
+bool ValidateProgramUniform3d(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLdouble v0,
+ GLdouble v1,
+ GLdouble v2);
+bool ValidateProgramUniform3dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLdouble *value);
+bool ValidateProgramUniform4d(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLdouble v0,
+ GLdouble v1,
+ GLdouble v2,
+ GLdouble v3);
+bool ValidateProgramUniform4dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ const GLdouble *value);
+bool ValidateProgramUniformMatrix2dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value);
+bool ValidateProgramUniformMatrix2x3dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value);
+bool ValidateProgramUniformMatrix2x4dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value);
+bool ValidateProgramUniformMatrix3dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value);
+bool ValidateProgramUniformMatrix3x2dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value);
+bool ValidateProgramUniformMatrix3x4dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value);
+bool ValidateProgramUniformMatrix4dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value);
+bool ValidateProgramUniformMatrix4x2dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value);
+bool ValidateProgramUniformMatrix4x3dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value);
+bool ValidateScissorArrayv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint first,
+ GLsizei count,
+ const GLint *v);
+bool ValidateScissorIndexed(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLint left,
+ GLint bottom,
+ GLsizei width,
+ GLsizei height);
+bool ValidateScissorIndexedv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLint *v);
+bool ValidateVertexAttribL1d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLdouble x);
+bool ValidateVertexAttribL1dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLdouble *v);
+bool ValidateVertexAttribL2d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLdouble x,
+ GLdouble y);
+bool ValidateVertexAttribL2dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLdouble *v);
+bool ValidateVertexAttribL3d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z);
+bool ValidateVertexAttribL3dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLdouble *v);
+bool ValidateVertexAttribL4d(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLdouble x,
+ GLdouble y,
+ GLdouble z,
+ GLdouble w);
+bool ValidateVertexAttribL4dv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLdouble *v);
+bool ValidateVertexAttribLPointer(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLint size,
+ GLenum type,
+ GLsizei stride,
+ const void *pointer);
+bool ValidateViewportArrayv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint first,
+ GLsizei count,
+ const GLfloat *v);
+bool ValidateViewportIndexedf(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ GLfloat x,
+ GLfloat y,
+ GLfloat w,
+ GLfloat h);
+bool ValidateViewportIndexedfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint index,
+ const GLfloat *v);
+
+// GL 4.2
+bool ValidateDrawArraysInstancedBaseInstance(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ GLint first,
+ GLsizei count,
+ GLsizei instancecount,
+ GLuint baseinstance);
+bool ValidateDrawElementsInstancedBaseInstance(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLsizei instancecount,
+ GLuint baseinstance);
+bool ValidateDrawElementsInstancedBaseVertexBaseInstance(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ GLsizei count,
+ DrawElementsType typePacked,
+ const void *indices,
+ GLsizei instancecount,
+ GLint basevertex,
+ GLuint baseinstance);
+bool ValidateDrawTransformFeedbackInstanced(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum mode,
+ TransformFeedbackID idPacked,
+ GLsizei instancecount);
+bool ValidateDrawTransformFeedbackStreamInstanced(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum mode,
+ TransformFeedbackID idPacked,
+ GLuint stream,
+ GLsizei instancecount);
+bool ValidateGetActiveAtomicCounterBufferiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ GLuint bufferIndex,
+ GLenum pname,
+ const GLint *params);
+bool ValidateTexStorage1D(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width);
+
+// GL 4.3
+bool ValidateClearBufferData(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum internalformat,
+ GLenum format,
+ GLenum type,
+ const void *data);
+bool ValidateClearBufferSubData(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum internalformat,
+ GLintptr offset,
+ GLsizeiptr size,
+ GLenum format,
+ GLenum type,
+ const void *data);
+bool ValidateGetInternalformati64v(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum internalformat,
+ GLenum pname,
+ GLsizei count,
+ const GLint64 *params);
+bool ValidateGetProgramResourceLocationIndex(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ GLenum programInterface,
+ const GLchar *name);
+bool ValidateInvalidateBufferData(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferID bufferPacked);
+bool ValidateInvalidateBufferSubData(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferID bufferPacked,
+ GLintptr offset,
+ GLsizeiptr length);
+bool ValidateInvalidateTexImage(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texturePacked,
+ GLint level);
+bool ValidateInvalidateTexSubImage(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texturePacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth);
+bool ValidateMultiDrawArraysIndirect(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ const void *indirect,
+ GLsizei drawcount,
+ GLsizei stride);
+bool ValidateMultiDrawElementsIndirect(const Context *context,
+ angle::EntryPoint entryPoint,
+ PrimitiveMode modePacked,
+ DrawElementsType typePacked,
+ const void *indirect,
+ GLsizei drawcount,
+ GLsizei stride);
+bool ValidateShaderStorageBlockBinding(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ GLuint storageBlockIndex,
+ GLuint storageBlockBinding);
+bool ValidateTextureView(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texturePacked,
+ GLenum target,
+ GLuint origtexture,
+ GLenum internalformat,
+ GLuint minlevel,
+ GLuint numlevels,
+ GLuint minlayer,
+ GLuint numlayers);
+bool ValidateVertexAttribLFormat(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint attribindex,
+ GLint size,
+ GLenum type,
+ GLuint relativeoffset);
+
+// GL 4.4
+bool ValidateBindBuffersBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint first,
+ GLsizei count,
+ const BufferID *buffersPacked);
+bool ValidateBindBuffersRange(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLuint first,
+ GLsizei count,
+ const BufferID *buffersPacked,
+ const GLintptr *offsets,
+ const GLsizeiptr *sizes);
+bool ValidateBindImageTextures(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint first,
+ GLsizei count,
+ const GLuint *textures);
+bool ValidateBindSamplers(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint first,
+ GLsizei count,
+ const GLuint *samplers);
+bool ValidateBindTextures(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint first,
+ GLsizei count,
+ const GLuint *textures);
+bool ValidateBindVertexBuffers(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint first,
+ GLsizei count,
+ const BufferID *buffersPacked,
+ const GLintptr *offsets,
+ const GLsizei *strides);
+bool ValidateBufferStorage(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferBinding targetPacked,
+ GLsizeiptr size,
+ const void *data,
+ GLbitfield flags);
+bool ValidateClearTexImage(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texturePacked,
+ GLint level,
+ GLenum format,
+ GLenum type,
+ const void *data);
+bool ValidateClearTexSubImage(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texturePacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ const void *data);
+
+// GL 4.5
+bool ValidateBindTextureUnit(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint unit,
+ TextureID texturePacked);
+bool ValidateBlitNamedFramebuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint readFramebuffer,
+ GLuint drawFramebuffer,
+ GLint srcX0,
+ GLint srcY0,
+ GLint srcX1,
+ GLint srcY1,
+ GLint dstX0,
+ GLint dstY0,
+ GLint dstX1,
+ GLint dstY1,
+ GLbitfield mask,
+ GLenum filter);
+bool ValidateCheckNamedFramebufferStatus(const Context *context,
+ angle::EntryPoint entryPoint,
+ FramebufferID framebufferPacked,
+ GLenum target);
+bool ValidateClearNamedBufferData(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferID bufferPacked,
+ GLenum internalformat,
+ GLenum format,
+ GLenum type,
+ const void *data);
+bool ValidateClearNamedBufferSubData(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferID bufferPacked,
+ GLenum internalformat,
+ GLintptr offset,
+ GLsizeiptr size,
+ GLenum format,
+ GLenum type,
+ const void *data);
+bool ValidateClearNamedFramebufferfi(const Context *context,
+ angle::EntryPoint entryPoint,
+ FramebufferID framebufferPacked,
+ GLenum buffer,
+ GLint drawbuffer,
+ GLfloat depth,
+ GLint stencil);
+bool ValidateClearNamedFramebufferfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ FramebufferID framebufferPacked,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLfloat *value);
+bool ValidateClearNamedFramebufferiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ FramebufferID framebufferPacked,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLint *value);
+bool ValidateClearNamedFramebufferuiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ FramebufferID framebufferPacked,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLuint *value);
+bool ValidateClipControl(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum origin,
+ GLenum depth);
+bool ValidateCompressedTextureSubImage1D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texturePacked,
+ GLint level,
+ GLint xoffset,
+ GLsizei width,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data);
+bool ValidateCompressedTextureSubImage2D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texturePacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data);
+bool ValidateCompressedTextureSubImage3D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texturePacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data);
+bool ValidateCopyNamedBufferSubData(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint readBuffer,
+ GLuint writeBuffer,
+ GLintptr readOffset,
+ GLintptr writeOffset,
+ GLsizeiptr size);
+bool ValidateCopyTextureSubImage1D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texturePacked,
+ GLint level,
+ GLint xoffset,
+ GLint x,
+ GLint y,
+ GLsizei width);
+bool ValidateCopyTextureSubImage2D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texturePacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height);
+bool ValidateCopyTextureSubImage3D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texturePacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height);
+bool ValidateCreateBuffers(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const BufferID *buffersPacked);
+bool ValidateCreateFramebuffers(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const GLuint *framebuffers);
+bool ValidateCreateProgramPipelines(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const GLuint *pipelines);
+bool ValidateCreateQueries(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLsizei n,
+ const GLuint *ids);
+bool ValidateCreateRenderbuffers(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const RenderbufferID *renderbuffersPacked);
+bool ValidateCreateSamplers(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const GLuint *samplers);
+bool ValidateCreateTextures(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLsizei n,
+ const GLuint *textures);
+bool ValidateCreateTransformFeedbacks(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const GLuint *ids);
+bool ValidateCreateVertexArrays(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei n,
+ const VertexArrayID *arraysPacked);
+bool ValidateDisableVertexArrayAttrib(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexArrayID vaobjPacked,
+ GLuint index);
+bool ValidateEnableVertexArrayAttrib(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexArrayID vaobjPacked,
+ GLuint index);
+bool ValidateFlushMappedNamedBufferRange(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferID bufferPacked,
+ GLintptr offset,
+ GLsizeiptr length);
+bool ValidateGenerateTextureMipmap(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texturePacked);
+bool ValidateGetCompressedTextureImage(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texturePacked,
+ GLint level,
+ GLsizei bufSize,
+ const void *pixels);
+bool ValidateGetCompressedTextureSubImage(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texturePacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLsizei bufSize,
+ const void *pixels);
+bool ValidateGetNamedBufferParameteri64v(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferID bufferPacked,
+ GLenum pname,
+ const GLint64 *params);
+bool ValidateGetNamedBufferParameteriv(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferID bufferPacked,
+ GLenum pname,
+ const GLint *params);
+bool ValidateGetNamedBufferPointerv(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferID bufferPacked,
+ GLenum pname,
+ void *const *params);
+bool ValidateGetNamedBufferSubData(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferID bufferPacked,
+ GLintptr offset,
+ GLsizeiptr size,
+ const void *data);
+bool ValidateGetNamedFramebufferAttachmentParameteriv(const Context *context,
+ angle::EntryPoint entryPoint,
+ FramebufferID framebufferPacked,
+ GLenum attachment,
+ GLenum pname,
+ const GLint *params);
+bool ValidateGetNamedFramebufferParameteriv(const Context *context,
+ angle::EntryPoint entryPoint,
+ FramebufferID framebufferPacked,
+ GLenum pname,
+ const GLint *param);
+bool ValidateGetNamedRenderbufferParameteriv(const Context *context,
+ angle::EntryPoint entryPoint,
+ RenderbufferID renderbufferPacked,
+ GLenum pname,
+ const GLint *params);
+bool ValidateGetQueryBufferObjecti64v(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint id,
+ BufferID bufferPacked,
+ GLenum pname,
+ GLintptr offset);
+bool ValidateGetQueryBufferObjectiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint id,
+ BufferID bufferPacked,
+ GLenum pname,
+ GLintptr offset);
+bool ValidateGetQueryBufferObjectui64v(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint id,
+ BufferID bufferPacked,
+ GLenum pname,
+ GLintptr offset);
+bool ValidateGetQueryBufferObjectuiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint id,
+ BufferID bufferPacked,
+ GLenum pname,
+ GLintptr offset);
+bool ValidateGetTextureImage(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texturePacked,
+ GLint level,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *pixels);
+bool ValidateGetTextureLevelParameterfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texturePacked,
+ GLint level,
+ GLenum pname,
+ const GLfloat *params);
+bool ValidateGetTextureLevelParameteriv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texturePacked,
+ GLint level,
+ GLenum pname,
+ const GLint *params);
+bool ValidateGetTextureParameterIiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texturePacked,
+ GLenum pname,
+ const GLint *params);
+bool ValidateGetTextureParameterIuiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texturePacked,
+ GLenum pname,
+ const GLuint *params);
+bool ValidateGetTextureParameterfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texturePacked,
+ GLenum pname,
+ const GLfloat *params);
+bool ValidateGetTextureParameteriv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texturePacked,
+ GLenum pname,
+ const GLint *params);
+bool ValidateGetTextureSubImage(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texturePacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *pixels);
+bool ValidateGetTransformFeedbacki64_v(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint xfb,
+ GLenum pname,
+ GLuint index,
+ const GLint64 *param);
+bool ValidateGetTransformFeedbacki_v(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint xfb,
+ GLenum pname,
+ GLuint index,
+ const GLint *param);
+bool ValidateGetTransformFeedbackiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint xfb,
+ GLenum pname,
+ const GLint *param);
+bool ValidateGetVertexArrayIndexed64iv(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexArrayID vaobjPacked,
+ GLuint index,
+ GLenum pname,
+ const GLint64 *param);
+bool ValidateGetVertexArrayIndexediv(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexArrayID vaobjPacked,
+ GLuint index,
+ GLenum pname,
+ const GLint *param);
+bool ValidateGetVertexArrayiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexArrayID vaobjPacked,
+ GLenum pname,
+ const GLint *param);
+bool ValidateGetnColorTable(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *table);
+bool ValidateGetnCompressedTexImage(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLint lod,
+ GLsizei bufSize,
+ const void *pixels);
+bool ValidateGetnConvolutionFilter(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *image);
+bool ValidateGetnHistogram(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLboolean reset,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *values);
+bool ValidateGetnMapdv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum query,
+ GLsizei bufSize,
+ const GLdouble *v);
+bool ValidateGetnMapfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum query,
+ GLsizei bufSize,
+ const GLfloat *v);
+bool ValidateGetnMapiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum query,
+ GLsizei bufSize,
+ const GLint *v);
+bool ValidateGetnMinmax(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLboolean reset,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *values);
+bool ValidateGetnPixelMapfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum map,
+ GLsizei bufSize,
+ const GLfloat *values);
+bool ValidateGetnPixelMapuiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum map,
+ GLsizei bufSize,
+ const GLuint *values);
+bool ValidateGetnPixelMapusv(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum map,
+ GLsizei bufSize,
+ const GLushort *values);
+bool ValidateGetnPolygonStipple(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLsizei bufSize,
+ const GLubyte *pattern);
+bool ValidateGetnSeparableFilter(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLenum format,
+ GLenum type,
+ GLsizei rowBufSize,
+ const void *row,
+ GLsizei columnBufSize,
+ const void *column,
+ const void *span);
+bool ValidateGetnTexImage(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum target,
+ GLint level,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *pixels);
+bool ValidateGetnUniformdv(const Context *context,
+ angle::EntryPoint entryPoint,
+ ShaderProgramID programPacked,
+ UniformLocation locationPacked,
+ GLsizei bufSize,
+ const GLdouble *params);
+bool ValidateInvalidateNamedFramebufferData(const Context *context,
+ angle::EntryPoint entryPoint,
+ FramebufferID framebufferPacked,
+ GLsizei numAttachments,
+ const GLenum *attachments);
+bool ValidateInvalidateNamedFramebufferSubData(const Context *context,
+ angle::EntryPoint entryPoint,
+ FramebufferID framebufferPacked,
+ GLsizei numAttachments,
+ const GLenum *attachments,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height);
+bool ValidateMapNamedBuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferID bufferPacked,
+ GLenum access);
+bool ValidateMapNamedBufferRange(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferID bufferPacked,
+ GLintptr offset,
+ GLsizeiptr length,
+ GLbitfield access);
+bool ValidateNamedBufferData(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferID bufferPacked,
+ GLsizeiptr size,
+ const void *data,
+ GLenum usage);
+bool ValidateNamedBufferStorage(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferID bufferPacked,
+ GLsizeiptr size,
+ const void *data,
+ GLbitfield flags);
+bool ValidateNamedBufferSubData(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferID bufferPacked,
+ GLintptr offset,
+ GLsizeiptr size,
+ const void *data);
+bool ValidateNamedFramebufferDrawBuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ FramebufferID framebufferPacked,
+ GLenum buf);
+bool ValidateNamedFramebufferDrawBuffers(const Context *context,
+ angle::EntryPoint entryPoint,
+ FramebufferID framebufferPacked,
+ GLsizei n,
+ const GLenum *bufs);
+bool ValidateNamedFramebufferParameteri(const Context *context,
+ angle::EntryPoint entryPoint,
+ FramebufferID framebufferPacked,
+ GLenum pname,
+ GLint param);
+bool ValidateNamedFramebufferReadBuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ FramebufferID framebufferPacked,
+ GLenum src);
+bool ValidateNamedFramebufferRenderbuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ FramebufferID framebufferPacked,
+ GLenum attachment,
+ GLenum renderbuffertarget,
+ RenderbufferID renderbufferPacked);
+bool ValidateNamedFramebufferTexture(const Context *context,
+ angle::EntryPoint entryPoint,
+ FramebufferID framebufferPacked,
+ GLenum attachment,
+ TextureID texturePacked,
+ GLint level);
+bool ValidateNamedFramebufferTextureLayer(const Context *context,
+ angle::EntryPoint entryPoint,
+ FramebufferID framebufferPacked,
+ GLenum attachment,
+ TextureID texturePacked,
+ GLint level,
+ GLint layer);
+bool ValidateNamedRenderbufferStorage(const Context *context,
+ angle::EntryPoint entryPoint,
+ RenderbufferID renderbufferPacked,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height);
+bool ValidateNamedRenderbufferStorageMultisample(const Context *context,
+ angle::EntryPoint entryPoint,
+ RenderbufferID renderbufferPacked,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height);
+bool ValidateTextureBarrier(const Context *context, angle::EntryPoint entryPoint);
+bool ValidateTextureBuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texturePacked,
+ GLenum internalformat,
+ BufferID bufferPacked);
+bool ValidateTextureBufferRange(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texturePacked,
+ GLenum internalformat,
+ BufferID bufferPacked,
+ GLintptr offset,
+ GLsizeiptr size);
+bool ValidateTextureParameterIiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texturePacked,
+ GLenum pname,
+ const GLint *params);
+bool ValidateTextureParameterIuiv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texturePacked,
+ GLenum pname,
+ const GLuint *params);
+bool ValidateTextureParameterf(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texturePacked,
+ GLenum pname,
+ GLfloat param);
+bool ValidateTextureParameterfv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texturePacked,
+ GLenum pname,
+ const GLfloat *param);
+bool ValidateTextureParameteri(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texturePacked,
+ GLenum pname,
+ GLint param);
+bool ValidateTextureParameteriv(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texturePacked,
+ GLenum pname,
+ const GLint *param);
+bool ValidateTextureStorage1D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texturePacked,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width);
+bool ValidateTextureStorage2D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texturePacked,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height);
+bool ValidateTextureStorage2DMultisample(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texturePacked,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedsamplelocations);
+bool ValidateTextureStorage3D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texturePacked,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth);
+bool ValidateTextureStorage3DMultisample(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texturePacked,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean fixedsamplelocations);
+bool ValidateTextureSubImage1D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texturePacked,
+ GLint level,
+ GLint xoffset,
+ GLsizei width,
+ GLenum format,
+ GLenum type,
+ const void *pixels);
+bool ValidateTextureSubImage2D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texturePacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ const void *pixels);
+bool ValidateTextureSubImage3D(const Context *context,
+ angle::EntryPoint entryPoint,
+ TextureID texturePacked,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ const void *pixels);
+bool ValidateTransformFeedbackBufferBase(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint xfb,
+ GLuint index,
+ BufferID bufferPacked);
+bool ValidateTransformFeedbackBufferRange(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint xfb,
+ GLuint index,
+ BufferID bufferPacked,
+ GLintptr offset,
+ GLsizeiptr size);
+bool ValidateUnmapNamedBuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ BufferID bufferPacked);
+bool ValidateVertexArrayAttribBinding(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexArrayID vaobjPacked,
+ GLuint attribindex,
+ GLuint bindingindex);
+bool ValidateVertexArrayAttribFormat(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexArrayID vaobjPacked,
+ GLuint attribindex,
+ GLint size,
+ GLenum type,
+ GLboolean normalized,
+ GLuint relativeoffset);
+bool ValidateVertexArrayAttribIFormat(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexArrayID vaobjPacked,
+ GLuint attribindex,
+ GLint size,
+ GLenum type,
+ GLuint relativeoffset);
+bool ValidateVertexArrayAttribLFormat(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexArrayID vaobjPacked,
+ GLuint attribindex,
+ GLint size,
+ GLenum type,
+ GLuint relativeoffset);
+bool ValidateVertexArrayBindingDivisor(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexArrayID vaobjPacked,
+ GLuint bindingindex,
+ GLuint divisor);
+bool ValidateVertexArrayElementBuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexArrayID vaobjPacked,
+ BufferID bufferPacked);
+bool ValidateVertexArrayVertexBuffer(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexArrayID vaobjPacked,
+ GLuint bindingindex,
+ BufferID bufferPacked,
+ GLintptr offset,
+ GLsizei stride);
+bool ValidateVertexArrayVertexBuffers(const Context *context,
+ angle::EntryPoint entryPoint,
+ VertexArrayID vaobjPacked,
+ GLuint first,
+ GLsizei count,
+ const BufferID *buffersPacked,
+ const GLintptr *offsets,
+ const GLsizei *strides);
+
+// GL 4.6
+bool ValidateMultiDrawArraysIndirectCount(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum mode,
+ const void *indirect,
+ GLintptr drawcount,
+ GLsizei maxdrawcount,
+ GLsizei stride);
+bool ValidateMultiDrawElementsIndirectCount(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLenum mode,
+ GLenum type,
+ const void *indirect,
+ GLintptr drawcount,
+ GLsizei maxdrawcount,
+ GLsizei stride);
+bool ValidatePolygonOffsetClamp(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLfloat factor,
+ GLfloat units,
+ GLfloat clamp);
+bool ValidateSpecializeShader(const Context *context,
+ angle::EntryPoint entryPoint,
+ GLuint shader,
+ const GLchar *pEntryPoint,
+ GLuint numSpecializationConstants,
+ const GLuint *pConstantIndex,
+ const GLuint *pConstantValue);
+} // namespace gl
+
+#endif // LIBANGLE_VALIDATION_GL4_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libEGL/egl_loader_autogen.cpp b/gfx/angle/checkout/src/libEGL/egl_loader_autogen.cpp
new file mode 100644
index 0000000000..9fbdeaad22
--- /dev/null
+++ b/gfx/angle/checkout/src/libEGL/egl_loader_autogen.cpp
@@ -0,0 +1,320 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_loader.py using data from egl.xml and egl_angle_ext.xml.
+//
+// Copyright 2018 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.
+//
+// egl_loader_autogen.cpp:
+// Simple EGL function loader.
+
+#include "egl_loader_autogen.h"
+
+PFNEGLCHOOSECONFIGPROC l_EGL_ChooseConfig;
+PFNEGLCOPYBUFFERSPROC l_EGL_CopyBuffers;
+PFNEGLCREATECONTEXTPROC l_EGL_CreateContext;
+PFNEGLCREATEPBUFFERSURFACEPROC l_EGL_CreatePbufferSurface;
+PFNEGLCREATEPIXMAPSURFACEPROC l_EGL_CreatePixmapSurface;
+PFNEGLCREATEWINDOWSURFACEPROC l_EGL_CreateWindowSurface;
+PFNEGLDESTROYCONTEXTPROC l_EGL_DestroyContext;
+PFNEGLDESTROYSURFACEPROC l_EGL_DestroySurface;
+PFNEGLGETCONFIGATTRIBPROC l_EGL_GetConfigAttrib;
+PFNEGLGETCONFIGSPROC l_EGL_GetConfigs;
+PFNEGLGETCURRENTDISPLAYPROC l_EGL_GetCurrentDisplay;
+PFNEGLGETCURRENTSURFACEPROC l_EGL_GetCurrentSurface;
+PFNEGLGETDISPLAYPROC l_EGL_GetDisplay;
+PFNEGLGETERRORPROC l_EGL_GetError;
+PFNEGLGETPROCADDRESSPROC l_EGL_GetProcAddress;
+PFNEGLINITIALIZEPROC l_EGL_Initialize;
+PFNEGLMAKECURRENTPROC l_EGL_MakeCurrent;
+PFNEGLQUERYCONTEXTPROC l_EGL_QueryContext;
+PFNEGLQUERYSTRINGPROC l_EGL_QueryString;
+PFNEGLQUERYSURFACEPROC l_EGL_QuerySurface;
+PFNEGLSWAPBUFFERSPROC l_EGL_SwapBuffers;
+PFNEGLTERMINATEPROC l_EGL_Terminate;
+PFNEGLWAITGLPROC l_EGL_WaitGL;
+PFNEGLWAITNATIVEPROC l_EGL_WaitNative;
+PFNEGLBINDTEXIMAGEPROC l_EGL_BindTexImage;
+PFNEGLRELEASETEXIMAGEPROC l_EGL_ReleaseTexImage;
+PFNEGLSURFACEATTRIBPROC l_EGL_SurfaceAttrib;
+PFNEGLSWAPINTERVALPROC l_EGL_SwapInterval;
+PFNEGLBINDAPIPROC l_EGL_BindAPI;
+PFNEGLQUERYAPIPROC l_EGL_QueryAPI;
+PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC l_EGL_CreatePbufferFromClientBuffer;
+PFNEGLRELEASETHREADPROC l_EGL_ReleaseThread;
+PFNEGLWAITCLIENTPROC l_EGL_WaitClient;
+PFNEGLGETCURRENTCONTEXTPROC l_EGL_GetCurrentContext;
+PFNEGLCREATESYNCPROC l_EGL_CreateSync;
+PFNEGLDESTROYSYNCPROC l_EGL_DestroySync;
+PFNEGLCLIENTWAITSYNCPROC l_EGL_ClientWaitSync;
+PFNEGLGETSYNCATTRIBPROC l_EGL_GetSyncAttrib;
+PFNEGLCREATEIMAGEPROC l_EGL_CreateImage;
+PFNEGLDESTROYIMAGEPROC l_EGL_DestroyImage;
+PFNEGLGETPLATFORMDISPLAYPROC l_EGL_GetPlatformDisplay;
+PFNEGLCREATEPLATFORMWINDOWSURFACEPROC l_EGL_CreatePlatformWindowSurface;
+PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC l_EGL_CreatePlatformPixmapSurface;
+PFNEGLWAITSYNCPROC l_EGL_WaitSync;
+PFNEGLSETBLOBCACHEFUNCSANDROIDPROC l_EGL_SetBlobCacheFuncsANDROID;
+PFNEGLCREATENATIVECLIENTBUFFERANDROIDPROC l_EGL_CreateNativeClientBufferANDROID;
+PFNEGLGETCOMPOSITORTIMINGANDROIDPROC l_EGL_GetCompositorTimingANDROID;
+PFNEGLGETCOMPOSITORTIMINGSUPPORTEDANDROIDPROC l_EGL_GetCompositorTimingSupportedANDROID;
+PFNEGLGETFRAMETIMESTAMPSUPPORTEDANDROIDPROC l_EGL_GetFrameTimestampSupportedANDROID;
+PFNEGLGETFRAMETIMESTAMPSANDROIDPROC l_EGL_GetFrameTimestampsANDROID;
+PFNEGLGETNEXTFRAMEIDANDROIDPROC l_EGL_GetNextFrameIdANDROID;
+PFNEGLGETNATIVECLIENTBUFFERANDROIDPROC l_EGL_GetNativeClientBufferANDROID;
+PFNEGLDUPNATIVEFENCEFDANDROIDPROC l_EGL_DupNativeFenceFDANDROID;
+PFNEGLPRESENTATIONTIMEANDROIDPROC l_EGL_PresentationTimeANDROID;
+PFNEGLCREATEDEVICEANGLEPROC l_EGL_CreateDeviceANGLE;
+PFNEGLRELEASEDEVICEANGLEPROC l_EGL_ReleaseDeviceANGLE;
+PFNEGLQUERYDISPLAYATTRIBANGLEPROC l_EGL_QueryDisplayAttribANGLE;
+PFNEGLQUERYSTRINGIANGLEPROC l_EGL_QueryStringiANGLE;
+PFNEGLCOPYMETALSHAREDEVENTANGLEPROC l_EGL_CopyMetalSharedEventANGLE;
+PFNEGLFORCEGPUSWITCHANGLEPROC l_EGL_ForceGPUSwitchANGLE;
+PFNEGLHANDLEGPUSWITCHANGLEPROC l_EGL_HandleGPUSwitchANGLE;
+PFNEGLREACQUIREHIGHPOWERGPUANGLEPROC l_EGL_ReacquireHighPowerGPUANGLE;
+PFNEGLRELEASEHIGHPOWERGPUANGLEPROC l_EGL_ReleaseHighPowerGPUANGLE;
+PFNEGLPREPARESWAPBUFFERSANGLEPROC l_EGL_PrepareSwapBuffersANGLE;
+PFNEGLPROGRAMCACHEGETATTRIBANGLEPROC l_EGL_ProgramCacheGetAttribANGLE;
+PFNEGLPROGRAMCACHEPOPULATEANGLEPROC l_EGL_ProgramCachePopulateANGLE;
+PFNEGLPROGRAMCACHEQUERYANGLEPROC l_EGL_ProgramCacheQueryANGLE;
+PFNEGLPROGRAMCACHERESIZEANGLEPROC l_EGL_ProgramCacheResizeANGLE;
+PFNEGLQUERYSURFACEPOINTERANGLEPROC l_EGL_QuerySurfacePointerANGLE;
+PFNEGLCREATESTREAMPRODUCERD3DTEXTUREANGLEPROC l_EGL_CreateStreamProducerD3DTextureANGLE;
+PFNEGLSTREAMPOSTD3DTEXTUREANGLEPROC l_EGL_StreamPostD3DTextureANGLE;
+PFNEGLSWAPBUFFERSWITHFRAMETOKENANGLEPROC l_EGL_SwapBuffersWithFrameTokenANGLE;
+PFNEGLGETMSCRATEANGLEPROC l_EGL_GetMscRateANGLE;
+PFNEGLEXPORTVKIMAGEANGLEPROC l_EGL_ExportVkImageANGLE;
+PFNEGLGETSYNCVALUESCHROMIUMPROC l_EGL_GetSyncValuesCHROMIUM;
+PFNEGLQUERYDEVICEATTRIBEXTPROC l_EGL_QueryDeviceAttribEXT;
+PFNEGLQUERYDEVICESTRINGEXTPROC l_EGL_QueryDeviceStringEXT;
+PFNEGLQUERYDISPLAYATTRIBEXTPROC l_EGL_QueryDisplayAttribEXT;
+PFNEGLQUERYDMABUFFORMATSEXTPROC l_EGL_QueryDmaBufFormatsEXT;
+PFNEGLQUERYDMABUFMODIFIERSEXTPROC l_EGL_QueryDmaBufModifiersEXT;
+PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC l_EGL_CreatePlatformPixmapSurfaceEXT;
+PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC l_EGL_CreatePlatformWindowSurfaceEXT;
+PFNEGLGETPLATFORMDISPLAYEXTPROC l_EGL_GetPlatformDisplayEXT;
+PFNEGLDEBUGMESSAGECONTROLKHRPROC l_EGL_DebugMessageControlKHR;
+PFNEGLLABELOBJECTKHRPROC l_EGL_LabelObjectKHR;
+PFNEGLQUERYDEBUGKHRPROC l_EGL_QueryDebugKHR;
+PFNEGLCLIENTWAITSYNCKHRPROC l_EGL_ClientWaitSyncKHR;
+PFNEGLCREATESYNCKHRPROC l_EGL_CreateSyncKHR;
+PFNEGLDESTROYSYNCKHRPROC l_EGL_DestroySyncKHR;
+PFNEGLGETSYNCATTRIBKHRPROC l_EGL_GetSyncAttribKHR;
+PFNEGLCREATEIMAGEKHRPROC l_EGL_CreateImageKHR;
+PFNEGLDESTROYIMAGEKHRPROC l_EGL_DestroyImageKHR;
+PFNEGLLOCKSURFACEKHRPROC l_EGL_LockSurfaceKHR;
+PFNEGLQUERYSURFACE64KHRPROC l_EGL_QuerySurface64KHR;
+PFNEGLUNLOCKSURFACEKHRPROC l_EGL_UnlockSurfaceKHR;
+PFNEGLSETDAMAGEREGIONKHRPROC l_EGL_SetDamageRegionKHR;
+PFNEGLSIGNALSYNCKHRPROC l_EGL_SignalSyncKHR;
+PFNEGLCREATESTREAMKHRPROC l_EGL_CreateStreamKHR;
+PFNEGLDESTROYSTREAMKHRPROC l_EGL_DestroyStreamKHR;
+PFNEGLQUERYSTREAMKHRPROC l_EGL_QueryStreamKHR;
+PFNEGLQUERYSTREAMU64KHRPROC l_EGL_QueryStreamu64KHR;
+PFNEGLSTREAMATTRIBKHRPROC l_EGL_StreamAttribKHR;
+PFNEGLSTREAMCONSUMERACQUIREKHRPROC l_EGL_StreamConsumerAcquireKHR;
+PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC l_EGL_StreamConsumerGLTextureExternalKHR;
+PFNEGLSTREAMCONSUMERRELEASEKHRPROC l_EGL_StreamConsumerReleaseKHR;
+PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC l_EGL_SwapBuffersWithDamageKHR;
+PFNEGLWAITSYNCKHRPROC l_EGL_WaitSyncKHR;
+PFNEGLPOSTSUBBUFFERNVPROC l_EGL_PostSubBufferNV;
+PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALATTRIBSNVPROC l_EGL_StreamConsumerGLTextureExternalAttribsNV;
+
+void LoadLibEGL_EGL(LoadProc loadProc)
+{
+ l_EGL_ChooseConfig = reinterpret_cast<PFNEGLCHOOSECONFIGPROC>(loadProc("EGL_ChooseConfig"));
+ l_EGL_CopyBuffers = reinterpret_cast<PFNEGLCOPYBUFFERSPROC>(loadProc("EGL_CopyBuffers"));
+ l_EGL_CreateContext = reinterpret_cast<PFNEGLCREATECONTEXTPROC>(loadProc("EGL_CreateContext"));
+ l_EGL_CreatePbufferSurface =
+ reinterpret_cast<PFNEGLCREATEPBUFFERSURFACEPROC>(loadProc("EGL_CreatePbufferSurface"));
+ l_EGL_CreatePixmapSurface =
+ reinterpret_cast<PFNEGLCREATEPIXMAPSURFACEPROC>(loadProc("EGL_CreatePixmapSurface"));
+ l_EGL_CreateWindowSurface =
+ reinterpret_cast<PFNEGLCREATEWINDOWSURFACEPROC>(loadProc("EGL_CreateWindowSurface"));
+ l_EGL_DestroyContext =
+ reinterpret_cast<PFNEGLDESTROYCONTEXTPROC>(loadProc("EGL_DestroyContext"));
+ l_EGL_DestroySurface =
+ reinterpret_cast<PFNEGLDESTROYSURFACEPROC>(loadProc("EGL_DestroySurface"));
+ l_EGL_GetConfigAttrib =
+ reinterpret_cast<PFNEGLGETCONFIGATTRIBPROC>(loadProc("EGL_GetConfigAttrib"));
+ l_EGL_GetConfigs = reinterpret_cast<PFNEGLGETCONFIGSPROC>(loadProc("EGL_GetConfigs"));
+ l_EGL_GetCurrentDisplay =
+ reinterpret_cast<PFNEGLGETCURRENTDISPLAYPROC>(loadProc("EGL_GetCurrentDisplay"));
+ l_EGL_GetCurrentSurface =
+ reinterpret_cast<PFNEGLGETCURRENTSURFACEPROC>(loadProc("EGL_GetCurrentSurface"));
+ l_EGL_GetDisplay = reinterpret_cast<PFNEGLGETDISPLAYPROC>(loadProc("EGL_GetDisplay"));
+ l_EGL_GetError = reinterpret_cast<PFNEGLGETERRORPROC>(loadProc("EGL_GetError"));
+ l_EGL_GetProcAddress =
+ reinterpret_cast<PFNEGLGETPROCADDRESSPROC>(loadProc("EGL_GetProcAddress"));
+ l_EGL_Initialize = reinterpret_cast<PFNEGLINITIALIZEPROC>(loadProc("EGL_Initialize"));
+ l_EGL_MakeCurrent = reinterpret_cast<PFNEGLMAKECURRENTPROC>(loadProc("EGL_MakeCurrent"));
+ l_EGL_QueryContext = reinterpret_cast<PFNEGLQUERYCONTEXTPROC>(loadProc("EGL_QueryContext"));
+ l_EGL_QueryString = reinterpret_cast<PFNEGLQUERYSTRINGPROC>(loadProc("EGL_QueryString"));
+ l_EGL_QuerySurface = reinterpret_cast<PFNEGLQUERYSURFACEPROC>(loadProc("EGL_QuerySurface"));
+ l_EGL_SwapBuffers = reinterpret_cast<PFNEGLSWAPBUFFERSPROC>(loadProc("EGL_SwapBuffers"));
+ l_EGL_Terminate = reinterpret_cast<PFNEGLTERMINATEPROC>(loadProc("EGL_Terminate"));
+ l_EGL_WaitGL = reinterpret_cast<PFNEGLWAITGLPROC>(loadProc("EGL_WaitGL"));
+ l_EGL_WaitNative = reinterpret_cast<PFNEGLWAITNATIVEPROC>(loadProc("EGL_WaitNative"));
+ l_EGL_BindTexImage = reinterpret_cast<PFNEGLBINDTEXIMAGEPROC>(loadProc("EGL_BindTexImage"));
+ l_EGL_ReleaseTexImage =
+ reinterpret_cast<PFNEGLRELEASETEXIMAGEPROC>(loadProc("EGL_ReleaseTexImage"));
+ l_EGL_SurfaceAttrib = reinterpret_cast<PFNEGLSURFACEATTRIBPROC>(loadProc("EGL_SurfaceAttrib"));
+ l_EGL_SwapInterval = reinterpret_cast<PFNEGLSWAPINTERVALPROC>(loadProc("EGL_SwapInterval"));
+ l_EGL_BindAPI = reinterpret_cast<PFNEGLBINDAPIPROC>(loadProc("EGL_BindAPI"));
+ l_EGL_QueryAPI = reinterpret_cast<PFNEGLQUERYAPIPROC>(loadProc("EGL_QueryAPI"));
+ l_EGL_CreatePbufferFromClientBuffer = reinterpret_cast<PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC>(
+ loadProc("EGL_CreatePbufferFromClientBuffer"));
+ l_EGL_ReleaseThread = reinterpret_cast<PFNEGLRELEASETHREADPROC>(loadProc("EGL_ReleaseThread"));
+ l_EGL_WaitClient = reinterpret_cast<PFNEGLWAITCLIENTPROC>(loadProc("EGL_WaitClient"));
+ l_EGL_GetCurrentContext =
+ reinterpret_cast<PFNEGLGETCURRENTCONTEXTPROC>(loadProc("EGL_GetCurrentContext"));
+ l_EGL_CreateSync = reinterpret_cast<PFNEGLCREATESYNCPROC>(loadProc("EGL_CreateSync"));
+ l_EGL_DestroySync = reinterpret_cast<PFNEGLDESTROYSYNCPROC>(loadProc("EGL_DestroySync"));
+ l_EGL_ClientWaitSync =
+ reinterpret_cast<PFNEGLCLIENTWAITSYNCPROC>(loadProc("EGL_ClientWaitSync"));
+ l_EGL_GetSyncAttrib = reinterpret_cast<PFNEGLGETSYNCATTRIBPROC>(loadProc("EGL_GetSyncAttrib"));
+ l_EGL_CreateImage = reinterpret_cast<PFNEGLCREATEIMAGEPROC>(loadProc("EGL_CreateImage"));
+ l_EGL_DestroyImage = reinterpret_cast<PFNEGLDESTROYIMAGEPROC>(loadProc("EGL_DestroyImage"));
+ l_EGL_GetPlatformDisplay =
+ reinterpret_cast<PFNEGLGETPLATFORMDISPLAYPROC>(loadProc("EGL_GetPlatformDisplay"));
+ l_EGL_CreatePlatformWindowSurface = reinterpret_cast<PFNEGLCREATEPLATFORMWINDOWSURFACEPROC>(
+ loadProc("EGL_CreatePlatformWindowSurface"));
+ l_EGL_CreatePlatformPixmapSurface = reinterpret_cast<PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC>(
+ loadProc("EGL_CreatePlatformPixmapSurface"));
+ l_EGL_WaitSync = reinterpret_cast<PFNEGLWAITSYNCPROC>(loadProc("EGL_WaitSync"));
+ l_EGL_SetBlobCacheFuncsANDROID = reinterpret_cast<PFNEGLSETBLOBCACHEFUNCSANDROIDPROC>(
+ loadProc("EGL_SetBlobCacheFuncsANDROID"));
+ l_EGL_CreateNativeClientBufferANDROID =
+ reinterpret_cast<PFNEGLCREATENATIVECLIENTBUFFERANDROIDPROC>(
+ loadProc("EGL_CreateNativeClientBufferANDROID"));
+ l_EGL_GetCompositorTimingANDROID = reinterpret_cast<PFNEGLGETCOMPOSITORTIMINGANDROIDPROC>(
+ loadProc("EGL_GetCompositorTimingANDROID"));
+ l_EGL_GetCompositorTimingSupportedANDROID =
+ reinterpret_cast<PFNEGLGETCOMPOSITORTIMINGSUPPORTEDANDROIDPROC>(
+ loadProc("EGL_GetCompositorTimingSupportedANDROID"));
+ l_EGL_GetFrameTimestampSupportedANDROID =
+ reinterpret_cast<PFNEGLGETFRAMETIMESTAMPSUPPORTEDANDROIDPROC>(
+ loadProc("EGL_GetFrameTimestampSupportedANDROID"));
+ l_EGL_GetFrameTimestampsANDROID = reinterpret_cast<PFNEGLGETFRAMETIMESTAMPSANDROIDPROC>(
+ loadProc("EGL_GetFrameTimestampsANDROID"));
+ l_EGL_GetNextFrameIdANDROID =
+ reinterpret_cast<PFNEGLGETNEXTFRAMEIDANDROIDPROC>(loadProc("EGL_GetNextFrameIdANDROID"));
+ l_EGL_GetNativeClientBufferANDROID = reinterpret_cast<PFNEGLGETNATIVECLIENTBUFFERANDROIDPROC>(
+ loadProc("EGL_GetNativeClientBufferANDROID"));
+ l_EGL_DupNativeFenceFDANDROID = reinterpret_cast<PFNEGLDUPNATIVEFENCEFDANDROIDPROC>(
+ loadProc("EGL_DupNativeFenceFDANDROID"));
+ l_EGL_PresentationTimeANDROID = reinterpret_cast<PFNEGLPRESENTATIONTIMEANDROIDPROC>(
+ loadProc("EGL_PresentationTimeANDROID"));
+ l_EGL_CreateDeviceANGLE =
+ reinterpret_cast<PFNEGLCREATEDEVICEANGLEPROC>(loadProc("EGL_CreateDeviceANGLE"));
+ l_EGL_ReleaseDeviceANGLE =
+ reinterpret_cast<PFNEGLRELEASEDEVICEANGLEPROC>(loadProc("EGL_ReleaseDeviceANGLE"));
+ l_EGL_QueryDisplayAttribANGLE = reinterpret_cast<PFNEGLQUERYDISPLAYATTRIBANGLEPROC>(
+ loadProc("EGL_QueryDisplayAttribANGLE"));
+ l_EGL_QueryStringiANGLE =
+ reinterpret_cast<PFNEGLQUERYSTRINGIANGLEPROC>(loadProc("EGL_QueryStringiANGLE"));
+ l_EGL_CopyMetalSharedEventANGLE = reinterpret_cast<PFNEGLCOPYMETALSHAREDEVENTANGLEPROC>(
+ loadProc("EGL_CopyMetalSharedEventANGLE"));
+ l_EGL_ForceGPUSwitchANGLE =
+ reinterpret_cast<PFNEGLFORCEGPUSWITCHANGLEPROC>(loadProc("EGL_ForceGPUSwitchANGLE"));
+ l_EGL_HandleGPUSwitchANGLE =
+ reinterpret_cast<PFNEGLHANDLEGPUSWITCHANGLEPROC>(loadProc("EGL_HandleGPUSwitchANGLE"));
+ l_EGL_ReacquireHighPowerGPUANGLE = reinterpret_cast<PFNEGLREACQUIREHIGHPOWERGPUANGLEPROC>(
+ loadProc("EGL_ReacquireHighPowerGPUANGLE"));
+ l_EGL_ReleaseHighPowerGPUANGLE = reinterpret_cast<PFNEGLRELEASEHIGHPOWERGPUANGLEPROC>(
+ loadProc("EGL_ReleaseHighPowerGPUANGLE"));
+ l_EGL_PrepareSwapBuffersANGLE = reinterpret_cast<PFNEGLPREPARESWAPBUFFERSANGLEPROC>(
+ loadProc("EGL_PrepareSwapBuffersANGLE"));
+ l_EGL_ProgramCacheGetAttribANGLE = reinterpret_cast<PFNEGLPROGRAMCACHEGETATTRIBANGLEPROC>(
+ loadProc("EGL_ProgramCacheGetAttribANGLE"));
+ l_EGL_ProgramCachePopulateANGLE = reinterpret_cast<PFNEGLPROGRAMCACHEPOPULATEANGLEPROC>(
+ loadProc("EGL_ProgramCachePopulateANGLE"));
+ l_EGL_ProgramCacheQueryANGLE =
+ reinterpret_cast<PFNEGLPROGRAMCACHEQUERYANGLEPROC>(loadProc("EGL_ProgramCacheQueryANGLE"));
+ l_EGL_ProgramCacheResizeANGLE = reinterpret_cast<PFNEGLPROGRAMCACHERESIZEANGLEPROC>(
+ loadProc("EGL_ProgramCacheResizeANGLE"));
+ l_EGL_QuerySurfacePointerANGLE = reinterpret_cast<PFNEGLQUERYSURFACEPOINTERANGLEPROC>(
+ loadProc("EGL_QuerySurfacePointerANGLE"));
+ l_EGL_CreateStreamProducerD3DTextureANGLE =
+ reinterpret_cast<PFNEGLCREATESTREAMPRODUCERD3DTEXTUREANGLEPROC>(
+ loadProc("EGL_CreateStreamProducerD3DTextureANGLE"));
+ l_EGL_StreamPostD3DTextureANGLE = reinterpret_cast<PFNEGLSTREAMPOSTD3DTEXTUREANGLEPROC>(
+ loadProc("EGL_StreamPostD3DTextureANGLE"));
+ l_EGL_SwapBuffersWithFrameTokenANGLE =
+ reinterpret_cast<PFNEGLSWAPBUFFERSWITHFRAMETOKENANGLEPROC>(
+ loadProc("EGL_SwapBuffersWithFrameTokenANGLE"));
+ l_EGL_GetMscRateANGLE =
+ reinterpret_cast<PFNEGLGETMSCRATEANGLEPROC>(loadProc("EGL_GetMscRateANGLE"));
+ l_EGL_ExportVkImageANGLE =
+ reinterpret_cast<PFNEGLEXPORTVKIMAGEANGLEPROC>(loadProc("EGL_ExportVkImageANGLE"));
+ l_EGL_GetSyncValuesCHROMIUM =
+ reinterpret_cast<PFNEGLGETSYNCVALUESCHROMIUMPROC>(loadProc("EGL_GetSyncValuesCHROMIUM"));
+ l_EGL_QueryDeviceAttribEXT =
+ reinterpret_cast<PFNEGLQUERYDEVICEATTRIBEXTPROC>(loadProc("EGL_QueryDeviceAttribEXT"));
+ l_EGL_QueryDeviceStringEXT =
+ reinterpret_cast<PFNEGLQUERYDEVICESTRINGEXTPROC>(loadProc("EGL_QueryDeviceStringEXT"));
+ l_EGL_QueryDisplayAttribEXT =
+ reinterpret_cast<PFNEGLQUERYDISPLAYATTRIBEXTPROC>(loadProc("EGL_QueryDisplayAttribEXT"));
+ l_EGL_QueryDmaBufFormatsEXT =
+ reinterpret_cast<PFNEGLQUERYDMABUFFORMATSEXTPROC>(loadProc("EGL_QueryDmaBufFormatsEXT"));
+ l_EGL_QueryDmaBufModifiersEXT = reinterpret_cast<PFNEGLQUERYDMABUFMODIFIERSEXTPROC>(
+ loadProc("EGL_QueryDmaBufModifiersEXT"));
+ l_EGL_CreatePlatformPixmapSurfaceEXT =
+ reinterpret_cast<PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC>(
+ loadProc("EGL_CreatePlatformPixmapSurfaceEXT"));
+ l_EGL_CreatePlatformWindowSurfaceEXT =
+ reinterpret_cast<PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC>(
+ loadProc("EGL_CreatePlatformWindowSurfaceEXT"));
+ l_EGL_GetPlatformDisplayEXT =
+ reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(loadProc("EGL_GetPlatformDisplayEXT"));
+ l_EGL_DebugMessageControlKHR =
+ reinterpret_cast<PFNEGLDEBUGMESSAGECONTROLKHRPROC>(loadProc("EGL_DebugMessageControlKHR"));
+ l_EGL_LabelObjectKHR =
+ reinterpret_cast<PFNEGLLABELOBJECTKHRPROC>(loadProc("EGL_LabelObjectKHR"));
+ l_EGL_QueryDebugKHR = reinterpret_cast<PFNEGLQUERYDEBUGKHRPROC>(loadProc("EGL_QueryDebugKHR"));
+ l_EGL_ClientWaitSyncKHR =
+ reinterpret_cast<PFNEGLCLIENTWAITSYNCKHRPROC>(loadProc("EGL_ClientWaitSyncKHR"));
+ l_EGL_CreateSyncKHR = reinterpret_cast<PFNEGLCREATESYNCKHRPROC>(loadProc("EGL_CreateSyncKHR"));
+ l_EGL_DestroySyncKHR =
+ reinterpret_cast<PFNEGLDESTROYSYNCKHRPROC>(loadProc("EGL_DestroySyncKHR"));
+ l_EGL_GetSyncAttribKHR =
+ reinterpret_cast<PFNEGLGETSYNCATTRIBKHRPROC>(loadProc("EGL_GetSyncAttribKHR"));
+ l_EGL_CreateImageKHR =
+ reinterpret_cast<PFNEGLCREATEIMAGEKHRPROC>(loadProc("EGL_CreateImageKHR"));
+ l_EGL_DestroyImageKHR =
+ reinterpret_cast<PFNEGLDESTROYIMAGEKHRPROC>(loadProc("EGL_DestroyImageKHR"));
+ l_EGL_LockSurfaceKHR =
+ reinterpret_cast<PFNEGLLOCKSURFACEKHRPROC>(loadProc("EGL_LockSurfaceKHR"));
+ l_EGL_QuerySurface64KHR =
+ reinterpret_cast<PFNEGLQUERYSURFACE64KHRPROC>(loadProc("EGL_QuerySurface64KHR"));
+ l_EGL_UnlockSurfaceKHR =
+ reinterpret_cast<PFNEGLUNLOCKSURFACEKHRPROC>(loadProc("EGL_UnlockSurfaceKHR"));
+ l_EGL_SetDamageRegionKHR =
+ reinterpret_cast<PFNEGLSETDAMAGEREGIONKHRPROC>(loadProc("EGL_SetDamageRegionKHR"));
+ l_EGL_SignalSyncKHR = reinterpret_cast<PFNEGLSIGNALSYNCKHRPROC>(loadProc("EGL_SignalSyncKHR"));
+ l_EGL_CreateStreamKHR =
+ reinterpret_cast<PFNEGLCREATESTREAMKHRPROC>(loadProc("EGL_CreateStreamKHR"));
+ l_EGL_DestroyStreamKHR =
+ reinterpret_cast<PFNEGLDESTROYSTREAMKHRPROC>(loadProc("EGL_DestroyStreamKHR"));
+ l_EGL_QueryStreamKHR =
+ reinterpret_cast<PFNEGLQUERYSTREAMKHRPROC>(loadProc("EGL_QueryStreamKHR"));
+ l_EGL_QueryStreamu64KHR =
+ reinterpret_cast<PFNEGLQUERYSTREAMU64KHRPROC>(loadProc("EGL_QueryStreamu64KHR"));
+ l_EGL_StreamAttribKHR =
+ reinterpret_cast<PFNEGLSTREAMATTRIBKHRPROC>(loadProc("EGL_StreamAttribKHR"));
+ l_EGL_StreamConsumerAcquireKHR = reinterpret_cast<PFNEGLSTREAMCONSUMERACQUIREKHRPROC>(
+ loadProc("EGL_StreamConsumerAcquireKHR"));
+ l_EGL_StreamConsumerGLTextureExternalKHR =
+ reinterpret_cast<PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC>(
+ loadProc("EGL_StreamConsumerGLTextureExternalKHR"));
+ l_EGL_StreamConsumerReleaseKHR = reinterpret_cast<PFNEGLSTREAMCONSUMERRELEASEKHRPROC>(
+ loadProc("EGL_StreamConsumerReleaseKHR"));
+ l_EGL_SwapBuffersWithDamageKHR = reinterpret_cast<PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC>(
+ loadProc("EGL_SwapBuffersWithDamageKHR"));
+ l_EGL_WaitSyncKHR = reinterpret_cast<PFNEGLWAITSYNCKHRPROC>(loadProc("EGL_WaitSyncKHR"));
+ l_EGL_PostSubBufferNV =
+ reinterpret_cast<PFNEGLPOSTSUBBUFFERNVPROC>(loadProc("EGL_PostSubBufferNV"));
+ l_EGL_StreamConsumerGLTextureExternalAttribsNV =
+ reinterpret_cast<PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALATTRIBSNVPROC>(
+ loadProc("EGL_StreamConsumerGLTextureExternalAttribsNV"));
+}
diff --git a/gfx/angle/checkout/src/libEGL/egl_loader_autogen.h b/gfx/angle/checkout/src/libEGL/egl_loader_autogen.h
new file mode 100644
index 0000000000..52e7f38f6d
--- /dev/null
+++ b/gfx/angle/checkout/src/libEGL/egl_loader_autogen.h
@@ -0,0 +1,250 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_loader.py using data from egl.xml and egl_angle_ext.xml.
+//
+// Copyright 2018 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.
+//
+// egl_loader_autogen.h:
+// Simple EGL function loader.
+
+#ifndef LIBEGL_EGL_LOADER_AUTOGEN_H_
+#define LIBEGL_EGL_LOADER_AUTOGEN_H_
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <export.h>
+
+#define EGL_ChooseConfig l_EGL_ChooseConfig
+#define EGL_CopyBuffers l_EGL_CopyBuffers
+#define EGL_CreateContext l_EGL_CreateContext
+#define EGL_CreatePbufferSurface l_EGL_CreatePbufferSurface
+#define EGL_CreatePixmapSurface l_EGL_CreatePixmapSurface
+#define EGL_CreateWindowSurface l_EGL_CreateWindowSurface
+#define EGL_DestroyContext l_EGL_DestroyContext
+#define EGL_DestroySurface l_EGL_DestroySurface
+#define EGL_GetConfigAttrib l_EGL_GetConfigAttrib
+#define EGL_GetConfigs l_EGL_GetConfigs
+#define EGL_GetCurrentDisplay l_EGL_GetCurrentDisplay
+#define EGL_GetCurrentSurface l_EGL_GetCurrentSurface
+#define EGL_GetDisplay l_EGL_GetDisplay
+#define EGL_GetError l_EGL_GetError
+#define EGL_GetProcAddress l_EGL_GetProcAddress
+#define EGL_Initialize l_EGL_Initialize
+#define EGL_MakeCurrent l_EGL_MakeCurrent
+#define EGL_QueryContext l_EGL_QueryContext
+#define EGL_QueryString l_EGL_QueryString
+#define EGL_QuerySurface l_EGL_QuerySurface
+#define EGL_SwapBuffers l_EGL_SwapBuffers
+#define EGL_Terminate l_EGL_Terminate
+#define EGL_WaitGL l_EGL_WaitGL
+#define EGL_WaitNative l_EGL_WaitNative
+#define EGL_BindTexImage l_EGL_BindTexImage
+#define EGL_ReleaseTexImage l_EGL_ReleaseTexImage
+#define EGL_SurfaceAttrib l_EGL_SurfaceAttrib
+#define EGL_SwapInterval l_EGL_SwapInterval
+#define EGL_BindAPI l_EGL_BindAPI
+#define EGL_QueryAPI l_EGL_QueryAPI
+#define EGL_CreatePbufferFromClientBuffer l_EGL_CreatePbufferFromClientBuffer
+#define EGL_ReleaseThread l_EGL_ReleaseThread
+#define EGL_WaitClient l_EGL_WaitClient
+#define EGL_GetCurrentContext l_EGL_GetCurrentContext
+#define EGL_CreateSync l_EGL_CreateSync
+#define EGL_DestroySync l_EGL_DestroySync
+#define EGL_ClientWaitSync l_EGL_ClientWaitSync
+#define EGL_GetSyncAttrib l_EGL_GetSyncAttrib
+#define EGL_CreateImage l_EGL_CreateImage
+#define EGL_DestroyImage l_EGL_DestroyImage
+#define EGL_GetPlatformDisplay l_EGL_GetPlatformDisplay
+#define EGL_CreatePlatformWindowSurface l_EGL_CreatePlatformWindowSurface
+#define EGL_CreatePlatformPixmapSurface l_EGL_CreatePlatformPixmapSurface
+#define EGL_WaitSync l_EGL_WaitSync
+#define EGL_SetBlobCacheFuncsANDROID l_EGL_SetBlobCacheFuncsANDROID
+#define EGL_CreateNativeClientBufferANDROID l_EGL_CreateNativeClientBufferANDROID
+#define EGL_GetCompositorTimingANDROID l_EGL_GetCompositorTimingANDROID
+#define EGL_GetCompositorTimingSupportedANDROID l_EGL_GetCompositorTimingSupportedANDROID
+#define EGL_GetFrameTimestampSupportedANDROID l_EGL_GetFrameTimestampSupportedANDROID
+#define EGL_GetFrameTimestampsANDROID l_EGL_GetFrameTimestampsANDROID
+#define EGL_GetNextFrameIdANDROID l_EGL_GetNextFrameIdANDROID
+#define EGL_GetNativeClientBufferANDROID l_EGL_GetNativeClientBufferANDROID
+#define EGL_DupNativeFenceFDANDROID l_EGL_DupNativeFenceFDANDROID
+#define EGL_PresentationTimeANDROID l_EGL_PresentationTimeANDROID
+#define EGL_CreateDeviceANGLE l_EGL_CreateDeviceANGLE
+#define EGL_ReleaseDeviceANGLE l_EGL_ReleaseDeviceANGLE
+#define EGL_QueryDisplayAttribANGLE l_EGL_QueryDisplayAttribANGLE
+#define EGL_QueryStringiANGLE l_EGL_QueryStringiANGLE
+#define EGL_CopyMetalSharedEventANGLE l_EGL_CopyMetalSharedEventANGLE
+#define EGL_ForceGPUSwitchANGLE l_EGL_ForceGPUSwitchANGLE
+#define EGL_HandleGPUSwitchANGLE l_EGL_HandleGPUSwitchANGLE
+#define EGL_ReacquireHighPowerGPUANGLE l_EGL_ReacquireHighPowerGPUANGLE
+#define EGL_ReleaseHighPowerGPUANGLE l_EGL_ReleaseHighPowerGPUANGLE
+#define EGL_PrepareSwapBuffersANGLE l_EGL_PrepareSwapBuffersANGLE
+#define EGL_ProgramCacheGetAttribANGLE l_EGL_ProgramCacheGetAttribANGLE
+#define EGL_ProgramCachePopulateANGLE l_EGL_ProgramCachePopulateANGLE
+#define EGL_ProgramCacheQueryANGLE l_EGL_ProgramCacheQueryANGLE
+#define EGL_ProgramCacheResizeANGLE l_EGL_ProgramCacheResizeANGLE
+#define EGL_QuerySurfacePointerANGLE l_EGL_QuerySurfacePointerANGLE
+#define EGL_CreateStreamProducerD3DTextureANGLE l_EGL_CreateStreamProducerD3DTextureANGLE
+#define EGL_StreamPostD3DTextureANGLE l_EGL_StreamPostD3DTextureANGLE
+#define EGL_SwapBuffersWithFrameTokenANGLE l_EGL_SwapBuffersWithFrameTokenANGLE
+#define EGL_GetMscRateANGLE l_EGL_GetMscRateANGLE
+#define EGL_ExportVkImageANGLE l_EGL_ExportVkImageANGLE
+#define EGL_GetSyncValuesCHROMIUM l_EGL_GetSyncValuesCHROMIUM
+#define EGL_QueryDeviceAttribEXT l_EGL_QueryDeviceAttribEXT
+#define EGL_QueryDeviceStringEXT l_EGL_QueryDeviceStringEXT
+#define EGL_QueryDisplayAttribEXT l_EGL_QueryDisplayAttribEXT
+#define EGL_QueryDmaBufFormatsEXT l_EGL_QueryDmaBufFormatsEXT
+#define EGL_QueryDmaBufModifiersEXT l_EGL_QueryDmaBufModifiersEXT
+#define EGL_CreatePlatformPixmapSurfaceEXT l_EGL_CreatePlatformPixmapSurfaceEXT
+#define EGL_CreatePlatformWindowSurfaceEXT l_EGL_CreatePlatformWindowSurfaceEXT
+#define EGL_GetPlatformDisplayEXT l_EGL_GetPlatformDisplayEXT
+#define EGL_DebugMessageControlKHR l_EGL_DebugMessageControlKHR
+#define EGL_LabelObjectKHR l_EGL_LabelObjectKHR
+#define EGL_QueryDebugKHR l_EGL_QueryDebugKHR
+#define EGL_ClientWaitSyncKHR l_EGL_ClientWaitSyncKHR
+#define EGL_CreateSyncKHR l_EGL_CreateSyncKHR
+#define EGL_DestroySyncKHR l_EGL_DestroySyncKHR
+#define EGL_GetSyncAttribKHR l_EGL_GetSyncAttribKHR
+#define EGL_CreateImageKHR l_EGL_CreateImageKHR
+#define EGL_DestroyImageKHR l_EGL_DestroyImageKHR
+#define EGL_LockSurfaceKHR l_EGL_LockSurfaceKHR
+#define EGL_QuerySurface64KHR l_EGL_QuerySurface64KHR
+#define EGL_UnlockSurfaceKHR l_EGL_UnlockSurfaceKHR
+#define EGL_SetDamageRegionKHR l_EGL_SetDamageRegionKHR
+#define EGL_SignalSyncKHR l_EGL_SignalSyncKHR
+#define EGL_CreateStreamKHR l_EGL_CreateStreamKHR
+#define EGL_DestroyStreamKHR l_EGL_DestroyStreamKHR
+#define EGL_QueryStreamKHR l_EGL_QueryStreamKHR
+#define EGL_QueryStreamu64KHR l_EGL_QueryStreamu64KHR
+#define EGL_StreamAttribKHR l_EGL_StreamAttribKHR
+#define EGL_StreamConsumerAcquireKHR l_EGL_StreamConsumerAcquireKHR
+#define EGL_StreamConsumerGLTextureExternalKHR l_EGL_StreamConsumerGLTextureExternalKHR
+#define EGL_StreamConsumerReleaseKHR l_EGL_StreamConsumerReleaseKHR
+#define EGL_SwapBuffersWithDamageKHR l_EGL_SwapBuffersWithDamageKHR
+#define EGL_WaitSyncKHR l_EGL_WaitSyncKHR
+#define EGL_PostSubBufferNV l_EGL_PostSubBufferNV
+#define EGL_StreamConsumerGLTextureExternalAttribsNV l_EGL_StreamConsumerGLTextureExternalAttribsNV
+ANGLE_NO_EXPORT extern PFNEGLCHOOSECONFIGPROC l_EGL_ChooseConfig;
+ANGLE_NO_EXPORT extern PFNEGLCOPYBUFFERSPROC l_EGL_CopyBuffers;
+ANGLE_NO_EXPORT extern PFNEGLCREATECONTEXTPROC l_EGL_CreateContext;
+ANGLE_NO_EXPORT extern PFNEGLCREATEPBUFFERSURFACEPROC l_EGL_CreatePbufferSurface;
+ANGLE_NO_EXPORT extern PFNEGLCREATEPIXMAPSURFACEPROC l_EGL_CreatePixmapSurface;
+ANGLE_NO_EXPORT extern PFNEGLCREATEWINDOWSURFACEPROC l_EGL_CreateWindowSurface;
+ANGLE_NO_EXPORT extern PFNEGLDESTROYCONTEXTPROC l_EGL_DestroyContext;
+ANGLE_NO_EXPORT extern PFNEGLDESTROYSURFACEPROC l_EGL_DestroySurface;
+ANGLE_NO_EXPORT extern PFNEGLGETCONFIGATTRIBPROC l_EGL_GetConfigAttrib;
+ANGLE_NO_EXPORT extern PFNEGLGETCONFIGSPROC l_EGL_GetConfigs;
+ANGLE_NO_EXPORT extern PFNEGLGETCURRENTDISPLAYPROC l_EGL_GetCurrentDisplay;
+ANGLE_NO_EXPORT extern PFNEGLGETCURRENTSURFACEPROC l_EGL_GetCurrentSurface;
+ANGLE_NO_EXPORT extern PFNEGLGETDISPLAYPROC l_EGL_GetDisplay;
+ANGLE_NO_EXPORT extern PFNEGLGETERRORPROC l_EGL_GetError;
+ANGLE_NO_EXPORT extern PFNEGLGETPROCADDRESSPROC l_EGL_GetProcAddress;
+ANGLE_NO_EXPORT extern PFNEGLINITIALIZEPROC l_EGL_Initialize;
+ANGLE_NO_EXPORT extern PFNEGLMAKECURRENTPROC l_EGL_MakeCurrent;
+ANGLE_NO_EXPORT extern PFNEGLQUERYCONTEXTPROC l_EGL_QueryContext;
+ANGLE_NO_EXPORT extern PFNEGLQUERYSTRINGPROC l_EGL_QueryString;
+ANGLE_NO_EXPORT extern PFNEGLQUERYSURFACEPROC l_EGL_QuerySurface;
+ANGLE_NO_EXPORT extern PFNEGLSWAPBUFFERSPROC l_EGL_SwapBuffers;
+ANGLE_NO_EXPORT extern PFNEGLTERMINATEPROC l_EGL_Terminate;
+ANGLE_NO_EXPORT extern PFNEGLWAITGLPROC l_EGL_WaitGL;
+ANGLE_NO_EXPORT extern PFNEGLWAITNATIVEPROC l_EGL_WaitNative;
+ANGLE_NO_EXPORT extern PFNEGLBINDTEXIMAGEPROC l_EGL_BindTexImage;
+ANGLE_NO_EXPORT extern PFNEGLRELEASETEXIMAGEPROC l_EGL_ReleaseTexImage;
+ANGLE_NO_EXPORT extern PFNEGLSURFACEATTRIBPROC l_EGL_SurfaceAttrib;
+ANGLE_NO_EXPORT extern PFNEGLSWAPINTERVALPROC l_EGL_SwapInterval;
+ANGLE_NO_EXPORT extern PFNEGLBINDAPIPROC l_EGL_BindAPI;
+ANGLE_NO_EXPORT extern PFNEGLQUERYAPIPROC l_EGL_QueryAPI;
+ANGLE_NO_EXPORT extern PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC l_EGL_CreatePbufferFromClientBuffer;
+ANGLE_NO_EXPORT extern PFNEGLRELEASETHREADPROC l_EGL_ReleaseThread;
+ANGLE_NO_EXPORT extern PFNEGLWAITCLIENTPROC l_EGL_WaitClient;
+ANGLE_NO_EXPORT extern PFNEGLGETCURRENTCONTEXTPROC l_EGL_GetCurrentContext;
+ANGLE_NO_EXPORT extern PFNEGLCREATESYNCPROC l_EGL_CreateSync;
+ANGLE_NO_EXPORT extern PFNEGLDESTROYSYNCPROC l_EGL_DestroySync;
+ANGLE_NO_EXPORT extern PFNEGLCLIENTWAITSYNCPROC l_EGL_ClientWaitSync;
+ANGLE_NO_EXPORT extern PFNEGLGETSYNCATTRIBPROC l_EGL_GetSyncAttrib;
+ANGLE_NO_EXPORT extern PFNEGLCREATEIMAGEPROC l_EGL_CreateImage;
+ANGLE_NO_EXPORT extern PFNEGLDESTROYIMAGEPROC l_EGL_DestroyImage;
+ANGLE_NO_EXPORT extern PFNEGLGETPLATFORMDISPLAYPROC l_EGL_GetPlatformDisplay;
+ANGLE_NO_EXPORT extern PFNEGLCREATEPLATFORMWINDOWSURFACEPROC l_EGL_CreatePlatformWindowSurface;
+ANGLE_NO_EXPORT extern PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC l_EGL_CreatePlatformPixmapSurface;
+ANGLE_NO_EXPORT extern PFNEGLWAITSYNCPROC l_EGL_WaitSync;
+ANGLE_NO_EXPORT extern PFNEGLSETBLOBCACHEFUNCSANDROIDPROC l_EGL_SetBlobCacheFuncsANDROID;
+ANGLE_NO_EXPORT extern PFNEGLCREATENATIVECLIENTBUFFERANDROIDPROC
+ l_EGL_CreateNativeClientBufferANDROID;
+ANGLE_NO_EXPORT extern PFNEGLGETCOMPOSITORTIMINGANDROIDPROC l_EGL_GetCompositorTimingANDROID;
+ANGLE_NO_EXPORT extern PFNEGLGETCOMPOSITORTIMINGSUPPORTEDANDROIDPROC
+ l_EGL_GetCompositorTimingSupportedANDROID;
+ANGLE_NO_EXPORT extern PFNEGLGETFRAMETIMESTAMPSUPPORTEDANDROIDPROC
+ l_EGL_GetFrameTimestampSupportedANDROID;
+ANGLE_NO_EXPORT extern PFNEGLGETFRAMETIMESTAMPSANDROIDPROC l_EGL_GetFrameTimestampsANDROID;
+ANGLE_NO_EXPORT extern PFNEGLGETNEXTFRAMEIDANDROIDPROC l_EGL_GetNextFrameIdANDROID;
+ANGLE_NO_EXPORT extern PFNEGLGETNATIVECLIENTBUFFERANDROIDPROC l_EGL_GetNativeClientBufferANDROID;
+ANGLE_NO_EXPORT extern PFNEGLDUPNATIVEFENCEFDANDROIDPROC l_EGL_DupNativeFenceFDANDROID;
+ANGLE_NO_EXPORT extern PFNEGLPRESENTATIONTIMEANDROIDPROC l_EGL_PresentationTimeANDROID;
+ANGLE_NO_EXPORT extern PFNEGLCREATEDEVICEANGLEPROC l_EGL_CreateDeviceANGLE;
+ANGLE_NO_EXPORT extern PFNEGLRELEASEDEVICEANGLEPROC l_EGL_ReleaseDeviceANGLE;
+ANGLE_NO_EXPORT extern PFNEGLQUERYDISPLAYATTRIBANGLEPROC l_EGL_QueryDisplayAttribANGLE;
+ANGLE_NO_EXPORT extern PFNEGLQUERYSTRINGIANGLEPROC l_EGL_QueryStringiANGLE;
+ANGLE_NO_EXPORT extern PFNEGLCOPYMETALSHAREDEVENTANGLEPROC l_EGL_CopyMetalSharedEventANGLE;
+ANGLE_NO_EXPORT extern PFNEGLFORCEGPUSWITCHANGLEPROC l_EGL_ForceGPUSwitchANGLE;
+ANGLE_NO_EXPORT extern PFNEGLHANDLEGPUSWITCHANGLEPROC l_EGL_HandleGPUSwitchANGLE;
+ANGLE_NO_EXPORT extern PFNEGLREACQUIREHIGHPOWERGPUANGLEPROC l_EGL_ReacquireHighPowerGPUANGLE;
+ANGLE_NO_EXPORT extern PFNEGLRELEASEHIGHPOWERGPUANGLEPROC l_EGL_ReleaseHighPowerGPUANGLE;
+ANGLE_NO_EXPORT extern PFNEGLPREPARESWAPBUFFERSANGLEPROC l_EGL_PrepareSwapBuffersANGLE;
+ANGLE_NO_EXPORT extern PFNEGLPROGRAMCACHEGETATTRIBANGLEPROC l_EGL_ProgramCacheGetAttribANGLE;
+ANGLE_NO_EXPORT extern PFNEGLPROGRAMCACHEPOPULATEANGLEPROC l_EGL_ProgramCachePopulateANGLE;
+ANGLE_NO_EXPORT extern PFNEGLPROGRAMCACHEQUERYANGLEPROC l_EGL_ProgramCacheQueryANGLE;
+ANGLE_NO_EXPORT extern PFNEGLPROGRAMCACHERESIZEANGLEPROC l_EGL_ProgramCacheResizeANGLE;
+ANGLE_NO_EXPORT extern PFNEGLQUERYSURFACEPOINTERANGLEPROC l_EGL_QuerySurfacePointerANGLE;
+ANGLE_NO_EXPORT extern PFNEGLCREATESTREAMPRODUCERD3DTEXTUREANGLEPROC
+ l_EGL_CreateStreamProducerD3DTextureANGLE;
+ANGLE_NO_EXPORT extern PFNEGLSTREAMPOSTD3DTEXTUREANGLEPROC l_EGL_StreamPostD3DTextureANGLE;
+ANGLE_NO_EXPORT extern PFNEGLSWAPBUFFERSWITHFRAMETOKENANGLEPROC
+ l_EGL_SwapBuffersWithFrameTokenANGLE;
+ANGLE_NO_EXPORT extern PFNEGLGETMSCRATEANGLEPROC l_EGL_GetMscRateANGLE;
+ANGLE_NO_EXPORT extern PFNEGLEXPORTVKIMAGEANGLEPROC l_EGL_ExportVkImageANGLE;
+ANGLE_NO_EXPORT extern PFNEGLGETSYNCVALUESCHROMIUMPROC l_EGL_GetSyncValuesCHROMIUM;
+ANGLE_NO_EXPORT extern PFNEGLQUERYDEVICEATTRIBEXTPROC l_EGL_QueryDeviceAttribEXT;
+ANGLE_NO_EXPORT extern PFNEGLQUERYDEVICESTRINGEXTPROC l_EGL_QueryDeviceStringEXT;
+ANGLE_NO_EXPORT extern PFNEGLQUERYDISPLAYATTRIBEXTPROC l_EGL_QueryDisplayAttribEXT;
+ANGLE_NO_EXPORT extern PFNEGLQUERYDMABUFFORMATSEXTPROC l_EGL_QueryDmaBufFormatsEXT;
+ANGLE_NO_EXPORT extern PFNEGLQUERYDMABUFMODIFIERSEXTPROC l_EGL_QueryDmaBufModifiersEXT;
+ANGLE_NO_EXPORT extern PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC
+ l_EGL_CreatePlatformPixmapSurfaceEXT;
+ANGLE_NO_EXPORT extern PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC
+ l_EGL_CreatePlatformWindowSurfaceEXT;
+ANGLE_NO_EXPORT extern PFNEGLGETPLATFORMDISPLAYEXTPROC l_EGL_GetPlatformDisplayEXT;
+ANGLE_NO_EXPORT extern PFNEGLDEBUGMESSAGECONTROLKHRPROC l_EGL_DebugMessageControlKHR;
+ANGLE_NO_EXPORT extern PFNEGLLABELOBJECTKHRPROC l_EGL_LabelObjectKHR;
+ANGLE_NO_EXPORT extern PFNEGLQUERYDEBUGKHRPROC l_EGL_QueryDebugKHR;
+ANGLE_NO_EXPORT extern PFNEGLCLIENTWAITSYNCKHRPROC l_EGL_ClientWaitSyncKHR;
+ANGLE_NO_EXPORT extern PFNEGLCREATESYNCKHRPROC l_EGL_CreateSyncKHR;
+ANGLE_NO_EXPORT extern PFNEGLDESTROYSYNCKHRPROC l_EGL_DestroySyncKHR;
+ANGLE_NO_EXPORT extern PFNEGLGETSYNCATTRIBKHRPROC l_EGL_GetSyncAttribKHR;
+ANGLE_NO_EXPORT extern PFNEGLCREATEIMAGEKHRPROC l_EGL_CreateImageKHR;
+ANGLE_NO_EXPORT extern PFNEGLDESTROYIMAGEKHRPROC l_EGL_DestroyImageKHR;
+ANGLE_NO_EXPORT extern PFNEGLLOCKSURFACEKHRPROC l_EGL_LockSurfaceKHR;
+ANGLE_NO_EXPORT extern PFNEGLQUERYSURFACE64KHRPROC l_EGL_QuerySurface64KHR;
+ANGLE_NO_EXPORT extern PFNEGLUNLOCKSURFACEKHRPROC l_EGL_UnlockSurfaceKHR;
+ANGLE_NO_EXPORT extern PFNEGLSETDAMAGEREGIONKHRPROC l_EGL_SetDamageRegionKHR;
+ANGLE_NO_EXPORT extern PFNEGLSIGNALSYNCKHRPROC l_EGL_SignalSyncKHR;
+ANGLE_NO_EXPORT extern PFNEGLCREATESTREAMKHRPROC l_EGL_CreateStreamKHR;
+ANGLE_NO_EXPORT extern PFNEGLDESTROYSTREAMKHRPROC l_EGL_DestroyStreamKHR;
+ANGLE_NO_EXPORT extern PFNEGLQUERYSTREAMKHRPROC l_EGL_QueryStreamKHR;
+ANGLE_NO_EXPORT extern PFNEGLQUERYSTREAMU64KHRPROC l_EGL_QueryStreamu64KHR;
+ANGLE_NO_EXPORT extern PFNEGLSTREAMATTRIBKHRPROC l_EGL_StreamAttribKHR;
+ANGLE_NO_EXPORT extern PFNEGLSTREAMCONSUMERACQUIREKHRPROC l_EGL_StreamConsumerAcquireKHR;
+ANGLE_NO_EXPORT extern PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC
+ l_EGL_StreamConsumerGLTextureExternalKHR;
+ANGLE_NO_EXPORT extern PFNEGLSTREAMCONSUMERRELEASEKHRPROC l_EGL_StreamConsumerReleaseKHR;
+ANGLE_NO_EXPORT extern PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC l_EGL_SwapBuffersWithDamageKHR;
+ANGLE_NO_EXPORT extern PFNEGLWAITSYNCKHRPROC l_EGL_WaitSyncKHR;
+ANGLE_NO_EXPORT extern PFNEGLPOSTSUBBUFFERNVPROC l_EGL_PostSubBufferNV;
+ANGLE_NO_EXPORT extern PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALATTRIBSNVPROC
+ l_EGL_StreamConsumerGLTextureExternalAttribsNV;
+
+using GenericProc = void (*)();
+using LoadProc = GenericProc(KHRONOS_APIENTRY *)(const char *);
+ANGLE_NO_EXPORT void LoadLibEGL_EGL(LoadProc loadProc);
+
+#endif // LIBEGL_EGL_LOADER_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libEGL/libEGL.rc b/gfx/angle/checkout/src/libEGL/libEGL.rc
new file mode 100644
index 0000000000..e1394ba80e
--- /dev/null
+++ b/gfx/angle/checkout/src/libEGL/libEGL.rc
@@ -0,0 +1,103 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include <windows.h>
+#include "../common/angle_version.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "#include ""../common/version.h""\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION ANGLE_MAJOR_VERSION,ANGLE_MINOR_VERSION,ANGLE_REVISION,0
+ PRODUCTVERSION ANGLE_MAJOR_VERSION,ANGLE_MINOR_VERSION,ANGLE_REVISION,0
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "FileDescription", "ANGLE libEGL Dynamic Link Library"
+ VALUE "FileVersion", ANGLE_VERSION_STRING
+ VALUE "InternalName", "libEGL"
+ VALUE "LegalCopyright", "Copyright (C) 2015 Google Inc."
+ VALUE "OriginalFilename", "libEGL.dll"
+ VALUE "PrivateBuild", ANGLE_VERSION_STRING
+ VALUE "ProductName", "ANGLE libEGL Dynamic Link Library"
+ VALUE "ProductVersion", ANGLE_VERSION_STRING
+ VALUE "Comments", "Build Date: " ANGLE_COMMIT_DATE
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
diff --git a/gfx/angle/checkout/src/libEGL/libEGL_autogen.cpp b/gfx/angle/checkout/src/libEGL/libEGL_autogen.cpp
new file mode 100644
index 0000000000..432ae26ce0
--- /dev/null
+++ b/gfx/angle/checkout/src/libEGL/libEGL_autogen.cpp
@@ -0,0 +1,917 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from egl.xml and egl_angle_ext.xml.
+//
+// Copyright 2020 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.
+//
+// libEGL_autogen.cpp: Implements the exported EGL functions.
+
+#include "anglebase/no_destructor.h"
+#include "common/system_utils.h"
+
+#include <memory>
+
+#if defined(ANGLE_USE_EGL_LOADER)
+# include "libEGL/egl_loader_autogen.h"
+#else
+# include "libGLESv2/entry_points_egl_autogen.h"
+# include "libGLESv2/entry_points_egl_ext_autogen.h"
+#endif // defined(ANGLE_USE_EGL_LOADER)
+
+namespace
+{
+#if defined(ANGLE_USE_EGL_LOADER)
+bool gLoaded = false;
+void *gEntryPointsLib = nullptr;
+
+GenericProc KHRONOS_APIENTRY GlobalLoad(const char *symbol)
+{
+ return reinterpret_cast<GenericProc>(angle::GetLibrarySymbol(gEntryPointsLib, symbol));
+}
+
+void EnsureEGLLoaded()
+{
+ if (gLoaded)
+ {
+ return;
+ }
+
+ std::string errorOut;
+ gEntryPointsLib = OpenSystemLibraryAndGetError(ANGLE_GLESV2_LIBRARY_NAME,
+ angle::SearchType::ModuleDir, &errorOut);
+ if (gEntryPointsLib)
+ {
+ LoadLibEGL_EGL(GlobalLoad);
+ gLoaded = true;
+ }
+ else
+ {
+ fprintf(stderr, "Error loading EGL entry points: %s\n", errorOut.c_str());
+ }
+}
+#else
+void EnsureEGLLoaded() {}
+#endif // defined(ANGLE_USE_EGL_LOADER)
+} // anonymous namespace
+
+extern "C" {
+
+// EGL 1.0
+EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy,
+ const EGLint *attrib_list,
+ EGLConfig *configs,
+ EGLint config_size,
+ EGLint *num_config)
+{
+ EnsureEGLLoaded();
+ return EGL_ChooseConfig(dpy, attrib_list, configs, config_size, num_config);
+}
+
+EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLNativePixmapType target)
+{
+ EnsureEGLLoaded();
+ return EGL_CopyBuffers(dpy, surface, target);
+}
+
+EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay dpy,
+ EGLConfig config,
+ EGLContext share_context,
+ const EGLint *attrib_list)
+{
+ EnsureEGLLoaded();
+ return EGL_CreateContext(dpy, config, share_context, attrib_list);
+}
+
+EGLSurface EGLAPIENTRY eglCreatePbufferSurface(EGLDisplay dpy,
+ EGLConfig config,
+ const EGLint *attrib_list)
+{
+ EnsureEGLLoaded();
+ return EGL_CreatePbufferSurface(dpy, config, attrib_list);
+}
+
+EGLSurface EGLAPIENTRY eglCreatePixmapSurface(EGLDisplay dpy,
+ EGLConfig config,
+ EGLNativePixmapType pixmap,
+ const EGLint *attrib_list)
+{
+ EnsureEGLLoaded();
+ return EGL_CreatePixmapSurface(dpy, config, pixmap, attrib_list);
+}
+
+EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay dpy,
+ EGLConfig config,
+ EGLNativeWindowType win,
+ const EGLint *attrib_list)
+{
+ EnsureEGLLoaded();
+ return EGL_CreateWindowSurface(dpy, config, win, attrib_list);
+}
+
+EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
+{
+ EnsureEGLLoaded();
+ return EGL_DestroyContext(dpy, ctx);
+}
+
+EGLBoolean EGLAPIENTRY eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
+{
+ EnsureEGLLoaded();
+ return EGL_DestroySurface(dpy, surface);
+}
+
+EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay dpy,
+ EGLConfig config,
+ EGLint attribute,
+ EGLint *value)
+{
+ EnsureEGLLoaded();
+ return EGL_GetConfigAttrib(dpy, config, attribute, value);
+}
+
+EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay dpy,
+ EGLConfig *configs,
+ EGLint config_size,
+ EGLint *num_config)
+{
+ EnsureEGLLoaded();
+ return EGL_GetConfigs(dpy, configs, config_size, num_config);
+}
+
+EGLDisplay EGLAPIENTRY eglGetCurrentDisplay()
+{
+ EnsureEGLLoaded();
+ return EGL_GetCurrentDisplay();
+}
+
+EGLSurface EGLAPIENTRY eglGetCurrentSurface(EGLint readdraw)
+{
+ EnsureEGLLoaded();
+ return EGL_GetCurrentSurface(readdraw);
+}
+
+EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id)
+{
+ EnsureEGLLoaded();
+ return EGL_GetDisplay(display_id);
+}
+
+EGLint EGLAPIENTRY eglGetError()
+{
+ EnsureEGLLoaded();
+ return EGL_GetError();
+}
+
+__eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress(const char *procname)
+{
+ EnsureEGLLoaded();
+ return EGL_GetProcAddress(procname);
+}
+
+EGLBoolean EGLAPIENTRY eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
+{
+ EnsureEGLLoaded();
+ return EGL_Initialize(dpy, major, minor);
+}
+
+EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy,
+ EGLSurface draw,
+ EGLSurface read,
+ EGLContext ctx)
+{
+ EnsureEGLLoaded();
+ return EGL_MakeCurrent(dpy, draw, read, ctx);
+}
+
+EGLBoolean EGLAPIENTRY eglQueryContext(EGLDisplay dpy,
+ EGLContext ctx,
+ EGLint attribute,
+ EGLint *value)
+{
+ EnsureEGLLoaded();
+ return EGL_QueryContext(dpy, ctx, attribute, value);
+}
+
+const char *EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name)
+{
+ EnsureEGLLoaded();
+ return EGL_QueryString(dpy, name);
+}
+
+EGLBoolean EGLAPIENTRY eglQuerySurface(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLint attribute,
+ EGLint *value)
+{
+ EnsureEGLLoaded();
+ return EGL_QuerySurface(dpy, surface, attribute, value);
+}
+
+EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
+{
+ EnsureEGLLoaded();
+ return EGL_SwapBuffers(dpy, surface);
+}
+
+EGLBoolean EGLAPIENTRY eglTerminate(EGLDisplay dpy)
+{
+ EnsureEGLLoaded();
+ return EGL_Terminate(dpy);
+}
+
+EGLBoolean EGLAPIENTRY eglWaitGL()
+{
+ EnsureEGLLoaded();
+ return EGL_WaitGL();
+}
+
+EGLBoolean EGLAPIENTRY eglWaitNative(EGLint engine)
+{
+ EnsureEGLLoaded();
+ return EGL_WaitNative(engine);
+}
+
+// EGL 1.1
+EGLBoolean EGLAPIENTRY eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+ EnsureEGLLoaded();
+ return EGL_BindTexImage(dpy, surface, buffer);
+}
+
+EGLBoolean EGLAPIENTRY eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+ EnsureEGLLoaded();
+ return EGL_ReleaseTexImage(dpy, surface, buffer);
+}
+
+EGLBoolean EGLAPIENTRY eglSurfaceAttrib(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLint attribute,
+ EGLint value)
+{
+ EnsureEGLLoaded();
+ return EGL_SurfaceAttrib(dpy, surface, attribute, value);
+}
+
+EGLBoolean EGLAPIENTRY eglSwapInterval(EGLDisplay dpy, EGLint interval)
+{
+ EnsureEGLLoaded();
+ return EGL_SwapInterval(dpy, interval);
+}
+
+// EGL 1.2
+EGLBoolean EGLAPIENTRY eglBindAPI(EGLenum api)
+{
+ EnsureEGLLoaded();
+ return EGL_BindAPI(api);
+}
+
+EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer(EGLDisplay dpy,
+ EGLenum buftype,
+ EGLClientBuffer buffer,
+ EGLConfig config,
+ const EGLint *attrib_list)
+{
+ EnsureEGLLoaded();
+ return EGL_CreatePbufferFromClientBuffer(dpy, buftype, buffer, config, attrib_list);
+}
+
+EGLenum EGLAPIENTRY eglQueryAPI()
+{
+ EnsureEGLLoaded();
+ return EGL_QueryAPI();
+}
+
+EGLBoolean EGLAPIENTRY eglReleaseThread()
+{
+ EnsureEGLLoaded();
+ return EGL_ReleaseThread();
+}
+
+EGLBoolean EGLAPIENTRY eglWaitClient()
+{
+ EnsureEGLLoaded();
+ return EGL_WaitClient();
+}
+
+// EGL 1.4
+EGLContext EGLAPIENTRY eglGetCurrentContext()
+{
+ EnsureEGLLoaded();
+ return EGL_GetCurrentContext();
+}
+
+// EGL 1.5
+EGLint EGLAPIENTRY eglClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout)
+{
+ EnsureEGLLoaded();
+ return EGL_ClientWaitSync(dpy, sync, flags, timeout);
+}
+
+EGLImage EGLAPIENTRY eglCreateImage(EGLDisplay dpy,
+ EGLContext ctx,
+ EGLenum target,
+ EGLClientBuffer buffer,
+ const EGLAttrib *attrib_list)
+{
+ EnsureEGLLoaded();
+ return EGL_CreateImage(dpy, ctx, target, buffer, attrib_list);
+}
+
+EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurface(EGLDisplay dpy,
+ EGLConfig config,
+ void *native_pixmap,
+ const EGLAttrib *attrib_list)
+{
+ EnsureEGLLoaded();
+ return EGL_CreatePlatformPixmapSurface(dpy, config, native_pixmap, attrib_list);
+}
+
+EGLSurface EGLAPIENTRY eglCreatePlatformWindowSurface(EGLDisplay dpy,
+ EGLConfig config,
+ void *native_window,
+ const EGLAttrib *attrib_list)
+{
+ EnsureEGLLoaded();
+ return EGL_CreatePlatformWindowSurface(dpy, config, native_window, attrib_list);
+}
+
+EGLSync EGLAPIENTRY eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
+{
+ EnsureEGLLoaded();
+ return EGL_CreateSync(dpy, type, attrib_list);
+}
+
+EGLBoolean EGLAPIENTRY eglDestroyImage(EGLDisplay dpy, EGLImage image)
+{
+ EnsureEGLLoaded();
+ return EGL_DestroyImage(dpy, image);
+}
+
+EGLBoolean EGLAPIENTRY eglDestroySync(EGLDisplay dpy, EGLSync sync)
+{
+ EnsureEGLLoaded();
+ return EGL_DestroySync(dpy, sync);
+}
+
+EGLDisplay EGLAPIENTRY eglGetPlatformDisplay(EGLenum platform,
+ void *native_display,
+ const EGLAttrib *attrib_list)
+{
+ EnsureEGLLoaded();
+ return EGL_GetPlatformDisplay(platform, native_display, attrib_list);
+}
+
+EGLBoolean EGLAPIENTRY eglGetSyncAttrib(EGLDisplay dpy,
+ EGLSync sync,
+ EGLint attribute,
+ EGLAttrib *value)
+{
+ EnsureEGLLoaded();
+ return EGL_GetSyncAttrib(dpy, sync, attribute, value);
+}
+
+EGLBoolean EGLAPIENTRY eglWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags)
+{
+ EnsureEGLLoaded();
+ return EGL_WaitSync(dpy, sync, flags);
+}
+
+// EGL_ANDROID_blob_cache
+void EGLAPIENTRY eglSetBlobCacheFuncsANDROID(EGLDisplay dpy,
+ EGLSetBlobFuncANDROID set,
+ EGLGetBlobFuncANDROID get)
+{
+ EnsureEGLLoaded();
+ return EGL_SetBlobCacheFuncsANDROID(dpy, set, get);
+}
+
+// EGL_ANDROID_create_native_client_buffer
+EGLClientBuffer EGLAPIENTRY eglCreateNativeClientBufferANDROID(const EGLint *attrib_list)
+{
+ EnsureEGLLoaded();
+ return EGL_CreateNativeClientBufferANDROID(attrib_list);
+}
+
+// EGL_ANDROID_get_frame_timestamps
+EGLBoolean EGLAPIENTRY eglGetCompositorTimingSupportedANDROID(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLint name)
+{
+ EnsureEGLLoaded();
+ return EGL_GetCompositorTimingSupportedANDROID(dpy, surface, name);
+}
+
+EGLBoolean EGLAPIENTRY eglGetCompositorTimingANDROID(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLint numTimestamps,
+ const EGLint *names,
+ EGLnsecsANDROID *values)
+{
+ EnsureEGLLoaded();
+ return EGL_GetCompositorTimingANDROID(dpy, surface, numTimestamps, names, values);
+}
+
+EGLBoolean EGLAPIENTRY eglGetNextFrameIdANDROID(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLuint64KHR *frameId)
+{
+ EnsureEGLLoaded();
+ return EGL_GetNextFrameIdANDROID(dpy, surface, frameId);
+}
+
+EGLBoolean EGLAPIENTRY eglGetFrameTimestampSupportedANDROID(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLint timestamp)
+{
+ EnsureEGLLoaded();
+ return EGL_GetFrameTimestampSupportedANDROID(dpy, surface, timestamp);
+}
+
+EGLBoolean EGLAPIENTRY eglGetFrameTimestampsANDROID(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLuint64KHR frameId,
+ EGLint numTimestamps,
+ const EGLint *timestamps,
+ EGLnsecsANDROID *values)
+{
+ EnsureEGLLoaded();
+ return EGL_GetFrameTimestampsANDROID(dpy, surface, frameId, numTimestamps, timestamps, values);
+}
+
+// EGL_ANDROID_get_native_client_buffer
+EGLClientBuffer EGLAPIENTRY eglGetNativeClientBufferANDROID(const struct AHardwareBuffer *buffer)
+{
+ EnsureEGLLoaded();
+ return EGL_GetNativeClientBufferANDROID(buffer);
+}
+
+// EGL_ANDROID_native_fence_sync
+EGLint EGLAPIENTRY eglDupNativeFenceFDANDROID(EGLDisplay dpy, EGLSyncKHR sync)
+{
+ EnsureEGLLoaded();
+ return EGL_DupNativeFenceFDANDROID(dpy, sync);
+}
+
+// EGL_ANDROID_presentation_time
+EGLBoolean EGLAPIENTRY eglPresentationTimeANDROID(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLnsecsANDROID time)
+{
+ EnsureEGLLoaded();
+ return EGL_PresentationTimeANDROID(dpy, surface, time);
+}
+
+// EGL_ANGLE_device_creation
+EGLDeviceEXT EGLAPIENTRY eglCreateDeviceANGLE(EGLint device_type,
+ void *native_device,
+ const EGLAttrib *attrib_list)
+{
+ EnsureEGLLoaded();
+ return EGL_CreateDeviceANGLE(device_type, native_device, attrib_list);
+}
+
+EGLBoolean EGLAPIENTRY eglReleaseDeviceANGLE(EGLDeviceEXT device)
+{
+ EnsureEGLLoaded();
+ return EGL_ReleaseDeviceANGLE(device);
+}
+
+// EGL_ANGLE_feature_control
+const char *EGLAPIENTRY eglQueryStringiANGLE(EGLDisplay dpy, EGLint name, EGLint index)
+{
+ EnsureEGLLoaded();
+ return EGL_QueryStringiANGLE(dpy, name, index);
+}
+
+EGLBoolean EGLAPIENTRY eglQueryDisplayAttribANGLE(EGLDisplay dpy,
+ EGLint attribute,
+ EGLAttrib *value)
+{
+ EnsureEGLLoaded();
+ return EGL_QueryDisplayAttribANGLE(dpy, attribute, value);
+}
+
+// EGL_ANGLE_metal_shared_event_sync
+void *EGLAPIENTRY eglCopyMetalSharedEventANGLE(EGLDisplay dpy, EGLSyncKHR sync)
+{
+ EnsureEGLLoaded();
+ return EGL_CopyMetalSharedEventANGLE(dpy, sync);
+}
+
+// EGL_ANGLE_power_preference
+void EGLAPIENTRY eglReleaseHighPowerGPUANGLE(EGLDisplay dpy, EGLContext ctx)
+{
+ EnsureEGLLoaded();
+ return EGL_ReleaseHighPowerGPUANGLE(dpy, ctx);
+}
+
+void EGLAPIENTRY eglReacquireHighPowerGPUANGLE(EGLDisplay dpy, EGLContext ctx)
+{
+ EnsureEGLLoaded();
+ return EGL_ReacquireHighPowerGPUANGLE(dpy, ctx);
+}
+
+void EGLAPIENTRY eglHandleGPUSwitchANGLE(EGLDisplay dpy)
+{
+ EnsureEGLLoaded();
+ return EGL_HandleGPUSwitchANGLE(dpy);
+}
+
+void EGLAPIENTRY eglForceGPUSwitchANGLE(EGLDisplay dpy, EGLint gpuIDHigh, EGLint gpuIDLow)
+{
+ EnsureEGLLoaded();
+ return EGL_ForceGPUSwitchANGLE(dpy, gpuIDHigh, gpuIDLow);
+}
+
+// EGL_ANGLE_prepare_swap_buffers
+EGLBoolean EGLAPIENTRY eglPrepareSwapBuffersANGLE(EGLDisplay dpy, EGLSurface surface)
+{
+ EnsureEGLLoaded();
+ return EGL_PrepareSwapBuffersANGLE(dpy, surface);
+}
+
+// EGL_ANGLE_program_cache_control
+EGLint EGLAPIENTRY eglProgramCacheGetAttribANGLE(EGLDisplay dpy, EGLenum attrib)
+{
+ EnsureEGLLoaded();
+ return EGL_ProgramCacheGetAttribANGLE(dpy, attrib);
+}
+
+void EGLAPIENTRY eglProgramCacheQueryANGLE(EGLDisplay dpy,
+ EGLint index,
+ void *key,
+ EGLint *keysize,
+ void *binary,
+ EGLint *binarysize)
+{
+ EnsureEGLLoaded();
+ return EGL_ProgramCacheQueryANGLE(dpy, index, key, keysize, binary, binarysize);
+}
+
+void EGLAPIENTRY eglProgramCachePopulateANGLE(EGLDisplay dpy,
+ const void *key,
+ EGLint keysize,
+ const void *binary,
+ EGLint binarysize)
+{
+ EnsureEGLLoaded();
+ return EGL_ProgramCachePopulateANGLE(dpy, key, keysize, binary, binarysize);
+}
+
+EGLint EGLAPIENTRY eglProgramCacheResizeANGLE(EGLDisplay dpy, EGLint limit, EGLint mode)
+{
+ EnsureEGLLoaded();
+ return EGL_ProgramCacheResizeANGLE(dpy, limit, mode);
+}
+
+// EGL_ANGLE_query_surface_pointer
+EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLint attribute,
+ void **value)
+{
+ EnsureEGLLoaded();
+ return EGL_QuerySurfacePointerANGLE(dpy, surface, attribute, value);
+}
+
+// EGL_ANGLE_stream_producer_d3d_texture
+EGLBoolean EGLAPIENTRY eglCreateStreamProducerD3DTextureANGLE(EGLDisplay dpy,
+ EGLStreamKHR stream,
+ const EGLAttrib *attrib_list)
+{
+ EnsureEGLLoaded();
+ return EGL_CreateStreamProducerD3DTextureANGLE(dpy, stream, attrib_list);
+}
+
+EGLBoolean EGLAPIENTRY eglStreamPostD3DTextureANGLE(EGLDisplay dpy,
+ EGLStreamKHR stream,
+ void *texture,
+ const EGLAttrib *attrib_list)
+{
+ EnsureEGLLoaded();
+ return EGL_StreamPostD3DTextureANGLE(dpy, stream, texture, attrib_list);
+}
+
+// EGL_ANGLE_swap_with_frame_token
+EGLBoolean EGLAPIENTRY eglSwapBuffersWithFrameTokenANGLE(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLFrameTokenANGLE frametoken)
+{
+ EnsureEGLLoaded();
+ return EGL_SwapBuffersWithFrameTokenANGLE(dpy, surface, frametoken);
+}
+
+// EGL_ANGLE_sync_control_rate
+EGLBoolean EGLAPIENTRY eglGetMscRateANGLE(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLint *numerator,
+ EGLint *denominator)
+{
+ EnsureEGLLoaded();
+ return EGL_GetMscRateANGLE(dpy, surface, numerator, denominator);
+}
+
+// EGL_ANGLE_vulkan_image
+EGLBoolean EGLAPIENTRY eglExportVkImageANGLE(EGLDisplay dpy,
+ EGLImage image,
+ void *vk_image,
+ void *vk_image_create_info)
+{
+ EnsureEGLLoaded();
+ return EGL_ExportVkImageANGLE(dpy, image, vk_image, vk_image_create_info);
+}
+
+// EGL_CHROMIUM_sync_control
+EGLBoolean EGLAPIENTRY eglGetSyncValuesCHROMIUM(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLuint64KHR *ust,
+ EGLuint64KHR *msc,
+ EGLuint64KHR *sbc)
+{
+ EnsureEGLLoaded();
+ return EGL_GetSyncValuesCHROMIUM(dpy, surface, ust, msc, sbc);
+}
+
+// EGL_EXT_device_query
+EGLBoolean EGLAPIENTRY eglQueryDeviceAttribEXT(EGLDeviceEXT device,
+ EGLint attribute,
+ EGLAttrib *value)
+{
+ EnsureEGLLoaded();
+ return EGL_QueryDeviceAttribEXT(device, attribute, value);
+}
+
+const char *EGLAPIENTRY eglQueryDeviceStringEXT(EGLDeviceEXT device, EGLint name)
+{
+ EnsureEGLLoaded();
+ return EGL_QueryDeviceStringEXT(device, name);
+}
+
+EGLBoolean EGLAPIENTRY eglQueryDisplayAttribEXT(EGLDisplay dpy, EGLint attribute, EGLAttrib *value)
+{
+ EnsureEGLLoaded();
+ return EGL_QueryDisplayAttribEXT(dpy, attribute, value);
+}
+
+// EGL_EXT_image_dma_buf_import_modifiers
+EGLBoolean EGLAPIENTRY eglQueryDmaBufFormatsEXT(EGLDisplay dpy,
+ EGLint max_formats,
+ EGLint *formats,
+ EGLint *num_formats)
+{
+ EnsureEGLLoaded();
+ return EGL_QueryDmaBufFormatsEXT(dpy, max_formats, formats, num_formats);
+}
+
+EGLBoolean EGLAPIENTRY eglQueryDmaBufModifiersEXT(EGLDisplay dpy,
+ EGLint format,
+ EGLint max_modifiers,
+ EGLuint64KHR *modifiers,
+ EGLBoolean *external_only,
+ EGLint *num_modifiers)
+{
+ EnsureEGLLoaded();
+ return EGL_QueryDmaBufModifiersEXT(dpy, format, max_modifiers, modifiers, external_only,
+ num_modifiers);
+}
+
+// EGL_EXT_platform_base
+EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurfaceEXT(EGLDisplay dpy,
+ EGLConfig config,
+ void *native_pixmap,
+ const EGLint *attrib_list)
+{
+ EnsureEGLLoaded();
+ return EGL_CreatePlatformPixmapSurfaceEXT(dpy, config, native_pixmap, attrib_list);
+}
+
+EGLSurface EGLAPIENTRY eglCreatePlatformWindowSurfaceEXT(EGLDisplay dpy,
+ EGLConfig config,
+ void *native_window,
+ const EGLint *attrib_list)
+{
+ EnsureEGLLoaded();
+ return EGL_CreatePlatformWindowSurfaceEXT(dpy, config, native_window, attrib_list);
+}
+
+EGLDisplay EGLAPIENTRY eglGetPlatformDisplayEXT(EGLenum platform,
+ void *native_display,
+ const EGLint *attrib_list)
+{
+ EnsureEGLLoaded();
+ return EGL_GetPlatformDisplayEXT(platform, native_display, attrib_list);
+}
+
+// EGL_KHR_debug
+EGLint EGLAPIENTRY eglDebugMessageControlKHR(EGLDEBUGPROCKHR callback, const EGLAttrib *attrib_list)
+{
+ EnsureEGLLoaded();
+ return EGL_DebugMessageControlKHR(callback, attrib_list);
+}
+
+EGLint EGLAPIENTRY eglLabelObjectKHR(EGLDisplay display,
+ EGLenum objectType,
+ EGLObjectKHR object,
+ EGLLabelKHR label)
+{
+ EnsureEGLLoaded();
+ return EGL_LabelObjectKHR(display, objectType, object, label);
+}
+
+EGLBoolean EGLAPIENTRY eglQueryDebugKHR(EGLint attribute, EGLAttrib *value)
+{
+ EnsureEGLLoaded();
+ return EGL_QueryDebugKHR(attribute, value);
+}
+
+// EGL_KHR_fence_sync
+EGLint EGLAPIENTRY eglClientWaitSyncKHR(EGLDisplay dpy,
+ EGLSyncKHR sync,
+ EGLint flags,
+ EGLTimeKHR timeout)
+{
+ EnsureEGLLoaded();
+ return EGL_ClientWaitSyncKHR(dpy, sync, flags, timeout);
+}
+
+EGLSyncKHR EGLAPIENTRY eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
+{
+ EnsureEGLLoaded();
+ return EGL_CreateSyncKHR(dpy, type, attrib_list);
+}
+
+EGLBoolean EGLAPIENTRY eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
+{
+ EnsureEGLLoaded();
+ return EGL_DestroySyncKHR(dpy, sync);
+}
+
+EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR(EGLDisplay dpy,
+ EGLSyncKHR sync,
+ EGLint attribute,
+ EGLint *value)
+{
+ EnsureEGLLoaded();
+ return EGL_GetSyncAttribKHR(dpy, sync, attribute, value);
+}
+
+// EGL_KHR_image
+EGLImageKHR EGLAPIENTRY eglCreateImageKHR(EGLDisplay dpy,
+ EGLContext ctx,
+ EGLenum target,
+ EGLClientBuffer buffer,
+ const EGLint *attrib_list)
+{
+ EnsureEGLLoaded();
+ return EGL_CreateImageKHR(dpy, ctx, target, buffer, attrib_list);
+}
+
+EGLBoolean EGLAPIENTRY eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
+{
+ EnsureEGLLoaded();
+ return EGL_DestroyImageKHR(dpy, image);
+}
+
+// EGL_KHR_lock_surface3
+EGLBoolean EGLAPIENTRY eglLockSurfaceKHR(EGLDisplay dpy,
+ EGLSurface surface,
+ const EGLint *attrib_list)
+{
+ EnsureEGLLoaded();
+ return EGL_LockSurfaceKHR(dpy, surface, attrib_list);
+}
+
+EGLBoolean EGLAPIENTRY eglQuerySurface64KHR(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLint attribute,
+ EGLAttribKHR *value)
+{
+ EnsureEGLLoaded();
+ return EGL_QuerySurface64KHR(dpy, surface, attribute, value);
+}
+
+EGLBoolean EGLAPIENTRY eglUnlockSurfaceKHR(EGLDisplay dpy, EGLSurface surface)
+{
+ EnsureEGLLoaded();
+ return EGL_UnlockSurfaceKHR(dpy, surface);
+}
+
+// EGL_KHR_partial_update
+EGLBoolean EGLAPIENTRY eglSetDamageRegionKHR(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLint *rects,
+ EGLint n_rects)
+{
+ EnsureEGLLoaded();
+ return EGL_SetDamageRegionKHR(dpy, surface, rects, n_rects);
+}
+
+// EGL_KHR_reusable_sync
+EGLBoolean EGLAPIENTRY eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode)
+{
+ EnsureEGLLoaded();
+ return EGL_SignalSyncKHR(dpy, sync, mode);
+}
+
+// EGL_KHR_stream
+EGLStreamKHR EGLAPIENTRY eglCreateStreamKHR(EGLDisplay dpy, const EGLint *attrib_list)
+{
+ EnsureEGLLoaded();
+ return EGL_CreateStreamKHR(dpy, attrib_list);
+}
+
+EGLBoolean EGLAPIENTRY eglDestroyStreamKHR(EGLDisplay dpy, EGLStreamKHR stream)
+{
+ EnsureEGLLoaded();
+ return EGL_DestroyStreamKHR(dpy, stream);
+}
+
+EGLBoolean EGLAPIENTRY eglQueryStreamKHR(EGLDisplay dpy,
+ EGLStreamKHR stream,
+ EGLenum attribute,
+ EGLint *value)
+{
+ EnsureEGLLoaded();
+ return EGL_QueryStreamKHR(dpy, stream, attribute, value);
+}
+
+EGLBoolean EGLAPIENTRY eglQueryStreamu64KHR(EGLDisplay dpy,
+ EGLStreamKHR stream,
+ EGLenum attribute,
+ EGLuint64KHR *value)
+{
+ EnsureEGLLoaded();
+ return EGL_QueryStreamu64KHR(dpy, stream, attribute, value);
+}
+
+EGLBoolean EGLAPIENTRY eglStreamAttribKHR(EGLDisplay dpy,
+ EGLStreamKHR stream,
+ EGLenum attribute,
+ EGLint value)
+{
+ EnsureEGLLoaded();
+ return EGL_StreamAttribKHR(dpy, stream, attribute, value);
+}
+
+// EGL_KHR_stream_consumer_gltexture
+EGLBoolean EGLAPIENTRY eglStreamConsumerAcquireKHR(EGLDisplay dpy, EGLStreamKHR stream)
+{
+ EnsureEGLLoaded();
+ return EGL_StreamConsumerAcquireKHR(dpy, stream);
+}
+
+EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalKHR(EGLDisplay dpy, EGLStreamKHR stream)
+{
+ EnsureEGLLoaded();
+ return EGL_StreamConsumerGLTextureExternalKHR(dpy, stream);
+}
+
+EGLBoolean EGLAPIENTRY eglStreamConsumerReleaseKHR(EGLDisplay dpy, EGLStreamKHR stream)
+{
+ EnsureEGLLoaded();
+ return EGL_StreamConsumerReleaseKHR(dpy, stream);
+}
+
+// EGL_KHR_swap_buffers_with_damage
+EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageKHR(EGLDisplay dpy,
+ EGLSurface surface,
+ const EGLint *rects,
+ EGLint n_rects)
+{
+ EnsureEGLLoaded();
+ return EGL_SwapBuffersWithDamageKHR(dpy, surface, rects, n_rects);
+}
+
+// EGL_KHR_wait_sync
+EGLint EGLAPIENTRY eglWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags)
+{
+ EnsureEGLLoaded();
+ return EGL_WaitSyncKHR(dpy, sync, flags);
+}
+
+// EGL_NV_post_sub_buffer
+EGLBoolean EGLAPIENTRY eglPostSubBufferNV(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLint x,
+ EGLint y,
+ EGLint width,
+ EGLint height)
+{
+ EnsureEGLLoaded();
+ return EGL_PostSubBufferNV(dpy, surface, x, y, width, height);
+}
+
+// EGL_NV_stream_consumer_gltexture_yuv
+EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalAttribsNV(EGLDisplay dpy,
+ EGLStreamKHR stream,
+ const EGLAttrib *attrib_list)
+{
+ EnsureEGLLoaded();
+ return EGL_StreamConsumerGLTextureExternalAttribsNV(dpy, stream, attrib_list);
+}
+
+} // extern "C"
diff --git a/gfx/angle/checkout/src/libEGL/libEGL_autogen.def b/gfx/angle/checkout/src/libEGL/libEGL_autogen.def
new file mode 100644
index 0000000000..5261144524
--- /dev/null
+++ b/gfx/angle/checkout/src/libEGL/libEGL_autogen.def
@@ -0,0 +1,193 @@
+; GENERATED FILE - DO NOT EDIT.
+; Generated by generate_entry_points.py using data from egl.xml and egl_angle_ext.xml.
+;
+; Copyright 2020 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.
+LIBRARY libEGL
+EXPORTS
+
+ ; EGL 1.0
+ eglChooseConfig
+ eglCopyBuffers
+ eglCreateContext
+ eglCreatePbufferSurface
+ eglCreatePixmapSurface
+ eglCreateWindowSurface
+ eglDestroyContext
+ eglDestroySurface
+ eglGetConfigAttrib
+ eglGetConfigs
+ eglGetCurrentDisplay
+ eglGetCurrentSurface
+ eglGetDisplay
+ eglGetError
+ eglGetProcAddress
+ eglInitialize
+ eglMakeCurrent
+ eglQueryContext
+ eglQueryString
+ eglQuerySurface
+ eglSwapBuffers
+ eglTerminate
+ eglWaitGL
+ eglWaitNative
+
+ ; EGL 1.1
+ eglBindTexImage
+ eglReleaseTexImage
+ eglSurfaceAttrib
+ eglSwapInterval
+
+ ; EGL 1.2
+ eglBindAPI
+ eglCreatePbufferFromClientBuffer
+ eglQueryAPI
+ eglReleaseThread
+ eglWaitClient
+
+ ; EGL 1.4
+ eglGetCurrentContext
+
+ ; EGL 1.5
+ eglClientWaitSync
+ eglCreateImage
+ eglCreatePlatformPixmapSurface
+ eglCreatePlatformWindowSurface
+ eglCreateSync
+ eglDestroyImage
+ eglDestroySync
+ eglGetPlatformDisplay
+ eglGetSyncAttrib
+ eglWaitSync
+
+ ; EGL_ANDROID_blob_cache
+ eglSetBlobCacheFuncsANDROID
+
+ ; EGL_ANDROID_create_native_client_buffer
+ eglCreateNativeClientBufferANDROID
+
+ ; EGL_ANDROID_get_frame_timestamps
+ eglGetCompositorTimingANDROID
+ eglGetCompositorTimingSupportedANDROID
+ eglGetFrameTimestampSupportedANDROID
+ eglGetFrameTimestampsANDROID
+ eglGetNextFrameIdANDROID
+
+ ; EGL_ANDROID_get_native_client_buffer
+ eglGetNativeClientBufferANDROID
+
+ ; EGL_ANDROID_native_fence_sync
+ eglDupNativeFenceFDANDROID
+
+ ; EGL_ANDROID_presentation_time
+ eglPresentationTimeANDROID
+
+ ; EGL_ANGLE_device_creation
+ eglCreateDeviceANGLE
+ eglReleaseDeviceANGLE
+
+ ; EGL_ANGLE_feature_control
+ eglQueryDisplayAttribANGLE
+ eglQueryStringiANGLE
+
+ ; EGL_ANGLE_metal_shared_event_sync
+ eglCopyMetalSharedEventANGLE
+
+ ; EGL_ANGLE_power_preference
+ eglForceGPUSwitchANGLE
+ eglHandleGPUSwitchANGLE
+ eglReacquireHighPowerGPUANGLE
+ eglReleaseHighPowerGPUANGLE
+
+ ; EGL_ANGLE_prepare_swap_buffers
+ eglPrepareSwapBuffersANGLE
+
+ ; EGL_ANGLE_program_cache_control
+ eglProgramCacheGetAttribANGLE
+ eglProgramCachePopulateANGLE
+ eglProgramCacheQueryANGLE
+ eglProgramCacheResizeANGLE
+
+ ; EGL_ANGLE_query_surface_pointer
+ eglQuerySurfacePointerANGLE
+
+ ; EGL_ANGLE_stream_producer_d3d_texture
+ eglCreateStreamProducerD3DTextureANGLE
+ eglStreamPostD3DTextureANGLE
+
+ ; EGL_ANGLE_swap_with_frame_token
+ eglSwapBuffersWithFrameTokenANGLE
+
+ ; EGL_ANGLE_sync_control_rate
+ eglGetMscRateANGLE
+
+ ; EGL_ANGLE_vulkan_image
+ eglExportVkImageANGLE
+
+ ; EGL_CHROMIUM_sync_control
+ eglGetSyncValuesCHROMIUM
+
+ ; EGL_EXT_device_query
+ eglQueryDeviceAttribEXT
+ eglQueryDeviceStringEXT
+ eglQueryDisplayAttribEXT
+
+ ; EGL_EXT_image_dma_buf_import_modifiers
+ eglQueryDmaBufFormatsEXT
+ eglQueryDmaBufModifiersEXT
+
+ ; EGL_EXT_platform_base
+ eglCreatePlatformPixmapSurfaceEXT
+ eglCreatePlatformWindowSurfaceEXT
+ eglGetPlatformDisplayEXT
+
+ ; EGL_KHR_debug
+ eglDebugMessageControlKHR
+ eglLabelObjectKHR
+ eglQueryDebugKHR
+
+ ; EGL_KHR_fence_sync
+ eglClientWaitSyncKHR
+ eglCreateSyncKHR
+ eglDestroySyncKHR
+ eglGetSyncAttribKHR
+
+ ; EGL_KHR_image
+ eglCreateImageKHR
+ eglDestroyImageKHR
+
+ ; EGL_KHR_lock_surface3
+ eglLockSurfaceKHR
+ eglQuerySurface64KHR
+ eglUnlockSurfaceKHR
+
+ ; EGL_KHR_partial_update
+ eglSetDamageRegionKHR
+
+ ; EGL_KHR_reusable_sync
+ eglSignalSyncKHR
+
+ ; EGL_KHR_stream
+ eglCreateStreamKHR
+ eglDestroyStreamKHR
+ eglQueryStreamKHR
+ eglQueryStreamu64KHR
+ eglStreamAttribKHR
+
+ ; EGL_KHR_stream_consumer_gltexture
+ eglStreamConsumerAcquireKHR
+ eglStreamConsumerGLTextureExternalKHR
+ eglStreamConsumerReleaseKHR
+
+ ; EGL_KHR_swap_buffers_with_damage
+ eglSwapBuffersWithDamageKHR
+
+ ; EGL_KHR_wait_sync
+ eglWaitSyncKHR
+
+ ; EGL_NV_post_sub_buffer
+ eglPostSubBufferNV
+
+ ; EGL_NV_stream_consumer_gltexture_yuv
+ eglStreamConsumerGLTextureExternalAttribsNV
diff --git a/gfx/angle/checkout/src/libEGL/resource.h b/gfx/angle/checkout/src/libEGL/resource.h
new file mode 100644
index 0000000000..018d085c02
--- /dev/null
+++ b/gfx/angle/checkout/src/libEGL/resource.h
@@ -0,0 +1,14 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by libEGL.rc
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+# ifndef APSTUDIO_READONLY_SYMBOLS
+# define _APS_NEXT_RESOURCE_VALUE 101
+# define _APS_NEXT_COMMAND_VALUE 40001
+# define _APS_NEXT_CONTROL_VALUE 1001
+# define _APS_NEXT_SYMED_VALUE 101
+# endif
+#endif
diff --git a/gfx/angle/checkout/src/libGLESv2/egl_ext_stubs.cpp b/gfx/angle/checkout/src/libGLESv2/egl_ext_stubs.cpp
new file mode 100644
index 0000000000..2476d50139
--- /dev/null
+++ b/gfx/angle/checkout/src/libGLESv2/egl_ext_stubs.cpp
@@ -0,0 +1,974 @@
+//
+// Copyright 2020 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.
+//
+// egl_ext_stubs.cpp: Stubs for EXT extension entry points.
+//
+
+#include "libGLESv2/egl_ext_stubs_autogen.h"
+
+#include "libANGLE/Device.h"
+#include "libANGLE/Display.h"
+#include "libANGLE/EGLSync.h"
+#include "libANGLE/Surface.h"
+#include "libANGLE/Thread.h"
+#include "libANGLE/capture/capture_egl.h"
+#include "libANGLE/capture/frame_capture_utils_autogen.h"
+#include "libANGLE/entry_points_utils.h"
+#include "libANGLE/queryutils.h"
+#include "libANGLE/renderer/DisplayImpl.h"
+#include "libANGLE/validationEGL.h"
+#include "libANGLE/validationEGL_autogen.h"
+#include "libGLESv2/global_state.h"
+
+namespace egl
+{
+EGLint ClientWaitSyncKHR(Thread *thread,
+ Display *display,
+ Sync *syncObject,
+ EGLint flags,
+ EGLTimeKHR timeout)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglClientWaitSync",
+ GetDisplayIfValid(display), EGL_FALSE);
+ gl::Context *currentContext = thread->getContext();
+ EGLint syncStatus = EGL_FALSE;
+ ANGLE_EGL_TRY_RETURN(
+ thread, syncObject->clientWait(display, currentContext, flags, timeout, &syncStatus),
+ "eglClientWaitSync", GetSyncIfValid(display, syncObject), EGL_FALSE);
+
+ thread->setSuccess();
+ return syncStatus;
+}
+
+EGLImageKHR CreateImageKHR(Thread *thread,
+ Display *display,
+ gl::Context *context,
+ EGLenum target,
+ EGLClientBuffer buffer,
+ const AttributeMap &attributes)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCreateImageKHR",
+ GetDisplayIfValid(display), EGL_NO_IMAGE);
+ Image *image = nullptr;
+ ANGLE_EGL_TRY_RETURN(thread, display->createImage(context, target, buffer, attributes, &image),
+ "", GetDisplayIfValid(display), EGL_NO_IMAGE);
+
+ ANGLE_CAPTURE_EGL(EGLCreateImage, thread, context, target, buffer, attributes, image);
+
+ thread->setSuccess();
+ return static_cast<EGLImage>(image);
+}
+
+EGLClientBuffer CreateNativeClientBufferANDROID(Thread *thread, const AttributeMap &attribMap)
+{
+ EGLClientBuffer eglClientBuffer = nullptr;
+ ANGLE_EGL_TRY_RETURN(thread,
+ egl::Display::CreateNativeClientBuffer(attribMap, &eglClientBuffer),
+ "eglCreateNativeClientBufferANDROID", nullptr, nullptr);
+
+ ANGLE_CAPTURE_EGL(CreateNativeClientBufferANDROID, thread, attribMap, eglClientBuffer);
+
+ thread->setSuccess();
+ return eglClientBuffer;
+}
+
+EGLSurface CreatePlatformPixmapSurfaceEXT(Thread *thread,
+ Display *display,
+ Config *configPacked,
+ void *native_pixmap,
+ const AttributeMap &attributes)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCreatePlatformPixmapSurfaceEXT",
+ GetDisplayIfValid(display), EGL_NO_SURFACE);
+ thread->setError(EGL_BAD_DISPLAY, "eglCreatePlatformPixmapSurfaceEXT",
+ GetDisplayIfValid(display), "CreatePlatformPixmapSurfaceEXT unimplemented.");
+ return EGL_NO_SURFACE;
+}
+
+EGLSurface CreatePlatformWindowSurfaceEXT(Thread *thread,
+ Display *display,
+ Config *configPacked,
+ void *native_window,
+ const AttributeMap &attributes)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCreatePlatformWindowSurfaceEXT",
+ GetDisplayIfValid(display), EGL_NO_SURFACE);
+ Surface *surface = nullptr;
+
+ // In X11, eglCreatePlatformWindowSurfaceEXT expects the native_window argument to be a pointer
+ // to a Window while the EGLNativeWindowType for X11 is its actual value.
+ // https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_platform_x11.txt
+ void *actualNativeWindow = display->getImplementation()->isX11()
+ ? *reinterpret_cast<void **>(native_window)
+ : native_window;
+ EGLNativeWindowType nativeWindow = reinterpret_cast<EGLNativeWindowType>(actualNativeWindow);
+
+ ANGLE_EGL_TRY_RETURN(
+ thread, display->createWindowSurface(configPacked, nativeWindow, attributes, &surface),
+ "eglPlatformCreateWindowSurfaceEXT", GetDisplayIfValid(display), EGL_NO_SURFACE);
+
+ return static_cast<EGLSurface>(surface);
+}
+
+EGLStreamKHR CreateStreamKHR(Thread *thread, Display *display, const AttributeMap &attributes)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCreateStreamKHR",
+ GetDisplayIfValid(display), EGL_NO_STREAM_KHR);
+ Stream *stream;
+ ANGLE_EGL_TRY_RETURN(thread, display->createStream(attributes, &stream), "eglCreateStreamKHR",
+ GetDisplayIfValid(display), EGL_NO_STREAM_KHR);
+
+ thread->setSuccess();
+ return static_cast<EGLStreamKHR>(stream);
+}
+
+EGLSyncKHR CreateSyncKHR(Thread *thread,
+ Display *display,
+ EGLenum type,
+ const AttributeMap &attributes)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCreateSyncKHR",
+ GetDisplayIfValid(display), EGL_NO_SYNC);
+ egl::Sync *syncObject = nullptr;
+ ANGLE_EGL_TRY_RETURN(thread,
+ display->createSync(thread->getContext(), type, attributes, &syncObject),
+ "eglCreateSyncKHR", GetDisplayIfValid(display), EGL_NO_SYNC);
+
+ thread->setSuccess();
+ return static_cast<EGLSync>(syncObject);
+}
+
+EGLint DebugMessageControlKHR(Thread *thread,
+ EGLDEBUGPROCKHR callback,
+ const AttributeMap &attributes)
+{
+ Debug *debug = GetDebug();
+ debug->setCallback(callback, attributes);
+
+ thread->setSuccess();
+ return EGL_SUCCESS;
+}
+
+EGLBoolean DestroyImageKHR(Thread *thread, Display *display, Image *img)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglDestroyImageKHR",
+ GetDisplayIfValid(display), EGL_FALSE);
+ display->destroyImage(img);
+
+ ANGLE_CAPTURE_EGL(EGLDestroyImage, thread, display, img);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean DestroyStreamKHR(Thread *thread, Display *display, Stream *streamObject)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglDestroyStreamKHR",
+ GetDisplayIfValid(display), EGL_FALSE);
+ display->destroyStream(streamObject);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean DestroySyncKHR(Thread *thread, Display *display, Sync *syncObject)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglDestroySync",
+ GetDisplayIfValid(display), EGL_FALSE);
+ display->destroySync(syncObject);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLint DupNativeFenceFDANDROID(Thread *thread, Display *display, Sync *syncObject)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglDupNativeFenceFDANDROID",
+ GetDisplayIfValid(display), EGL_NO_NATIVE_FENCE_FD_ANDROID);
+ EGLint result = EGL_NO_NATIVE_FENCE_FD_ANDROID;
+ ANGLE_EGL_TRY_RETURN(thread, syncObject->dupNativeFenceFD(display, &result),
+ "eglDupNativeFenceFDANDROID", GetSyncIfValid(display, syncObject),
+ EGL_NO_NATIVE_FENCE_FD_ANDROID);
+
+ thread->setSuccess();
+ return result;
+}
+
+EGLClientBuffer GetNativeClientBufferANDROID(Thread *thread, const struct AHardwareBuffer *buffer)
+{
+ thread->setSuccess();
+ return egl::Display::GetNativeClientBuffer(buffer);
+}
+
+EGLDisplay GetPlatformDisplayEXT(Thread *thread,
+ EGLenum platform,
+ void *native_display,
+ const AttributeMap &attribMap)
+{
+ switch (platform)
+ {
+ case EGL_PLATFORM_ANGLE_ANGLE:
+ case EGL_PLATFORM_GBM_KHR:
+ case EGL_PLATFORM_WAYLAND_EXT:
+ {
+ return egl::Display::GetDisplayFromNativeDisplay(
+ platform, gl::bitCast<EGLNativeDisplayType>(native_display), attribMap);
+ }
+ case EGL_PLATFORM_DEVICE_EXT:
+ {
+ Device *eglDevice = static_cast<Device *>(native_display);
+ return egl::Display::GetDisplayFromDevice(eglDevice, attribMap);
+ }
+ default:
+ {
+ UNREACHABLE();
+ return EGL_NO_DISPLAY;
+ }
+ }
+}
+
+EGLBoolean GetSyncAttribKHR(Thread *thread,
+ Display *display,
+ Sync *syncObject,
+ EGLint attribute,
+ EGLint *value)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglGetSyncAttrib",
+ GetDisplayIfValid(display), EGL_FALSE);
+ ANGLE_EGL_TRY_RETURN(thread, GetSyncAttrib(display, syncObject, attribute, value),
+ "eglGetSyncAttrib", GetSyncIfValid(display, syncObject), EGL_FALSE);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLint LabelObjectKHR(Thread *thread,
+ Display *display,
+ ObjectType objectTypePacked,
+ EGLObjectKHR object,
+ EGLLabelKHR label)
+{
+ LabeledObject *labeledObject =
+ GetLabeledObjectIfValid(thread, display, objectTypePacked, object);
+ ASSERT(labeledObject != nullptr);
+ labeledObject->setLabel(label);
+
+ thread->setSuccess();
+ return EGL_SUCCESS;
+}
+
+EGLBoolean PostSubBufferNV(Thread *thread,
+ Display *display,
+ Surface *eglSurface,
+ EGLint x,
+ EGLint y,
+ EGLint width,
+ EGLint height)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglPostSubBufferNV",
+ GetDisplayIfValid(display), EGL_FALSE);
+ Error error = eglSurface->postSubBuffer(thread->getContext(), x, y, width, height);
+ if (error.isError())
+ {
+ thread->setError(error, "eglPostSubBufferNV", GetSurfaceIfValid(display, eglSurface));
+ return EGL_FALSE;
+ }
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean PresentationTimeANDROID(Thread *thread,
+ Display *display,
+ Surface *eglSurface,
+ EGLnsecsANDROID time)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglPresentationTimeANDROID",
+ GetDisplayIfValid(display), EGL_FALSE);
+ ANGLE_EGL_TRY_RETURN(thread, eglSurface->setPresentationTime(time),
+ "eglPresentationTimeANDROID", GetSurfaceIfValid(display, eglSurface),
+ EGL_FALSE);
+
+ return EGL_TRUE;
+}
+
+EGLBoolean GetCompositorTimingSupportedANDROID(Thread *thread,
+ Display *display,
+ Surface *eglSurface,
+ CompositorTiming nameInternal)
+{
+ thread->setSuccess();
+ return eglSurface->getSupportedCompositorTimings().test(nameInternal);
+}
+
+EGLBoolean GetCompositorTimingANDROID(Thread *thread,
+ Display *display,
+ Surface *eglSurface,
+ EGLint numTimestamps,
+ const EGLint *names,
+ EGLnsecsANDROID *values)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglGetCompositorTimingANDROIDD",
+ GetDisplayIfValid(display), EGL_FALSE);
+ ANGLE_EGL_TRY_RETURN(thread, eglSurface->getCompositorTiming(numTimestamps, names, values),
+ "eglGetCompositorTimingANDROIDD", GetSurfaceIfValid(display, eglSurface),
+ EGL_FALSE);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean GetNextFrameIdANDROID(Thread *thread,
+ Display *display,
+ Surface *eglSurface,
+ EGLuint64KHR *frameId)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglGetNextFrameIdANDROID",
+ GetDisplayIfValid(display), EGL_FALSE);
+ ANGLE_EGL_TRY_RETURN(thread, eglSurface->getNextFrameId(frameId), "eglGetNextFrameIdANDROID",
+ GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean GetFrameTimestampSupportedANDROID(Thread *thread,
+ Display *display,
+ Surface *eglSurface,
+ Timestamp timestampInternal)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglQueryTimestampSupportedANDROID",
+ GetDisplayIfValid(display), EGL_FALSE);
+ thread->setSuccess();
+ return eglSurface->getSupportedTimestamps().test(timestampInternal);
+}
+
+EGLBoolean GetFrameTimestampsANDROID(Thread *thread,
+ Display *display,
+ Surface *eglSurface,
+ EGLuint64KHR frameId,
+ EGLint numTimestamps,
+ const EGLint *timestamps,
+ EGLnsecsANDROID *values)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglGetFrameTimestampsANDROID",
+ GetDisplayIfValid(display), EGL_FALSE);
+ ANGLE_EGL_TRY_RETURN(
+ thread, eglSurface->getFrameTimestamps(frameId, numTimestamps, timestamps, values),
+ "eglGetFrameTimestampsANDROID", GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean QueryDebugKHR(Thread *thread, EGLint attribute, EGLAttrib *value)
+{
+ Debug *debug = GetDebug();
+ switch (attribute)
+ {
+ case EGL_DEBUG_MSG_CRITICAL_KHR:
+ case EGL_DEBUG_MSG_ERROR_KHR:
+ case EGL_DEBUG_MSG_WARN_KHR:
+ case EGL_DEBUG_MSG_INFO_KHR:
+ *value = debug->isMessageTypeEnabled(FromEGLenum<MessageType>(attribute)) ? EGL_TRUE
+ : EGL_FALSE;
+ break;
+ case EGL_DEBUG_CALLBACK_KHR:
+ *value = reinterpret_cast<EGLAttrib>(debug->getCallback());
+ break;
+
+ default:
+ UNREACHABLE();
+ }
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean QueryDeviceAttribEXT(Thread *thread, Device *dev, EGLint attribute, EGLAttrib *value)
+{
+ ANGLE_EGL_TRY_RETURN(thread, dev->getAttribute(attribute, value), "eglQueryDeviceAttribEXT",
+ GetDeviceIfValid(dev), EGL_FALSE);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+const char *QueryDeviceStringEXT(Thread *thread, Device *dev, EGLint name)
+{
+ egl::Display *owningDisplay = dev->getOwningDisplay();
+ ANGLE_EGL_TRY_RETURN(thread, owningDisplay->prepareForCall(), "eglQueryDeviceStringEXT",
+ GetDisplayIfValid(owningDisplay), EGL_FALSE);
+ const char *result;
+ switch (name)
+ {
+ case EGL_EXTENSIONS:
+ result = dev->getExtensionString().c_str();
+ break;
+ default:
+ thread->setError(EglBadDevice(), "eglQueryDeviceStringEXT", GetDeviceIfValid(dev));
+ return nullptr;
+ }
+
+ thread->setSuccess();
+ return result;
+}
+
+EGLBoolean QueryDisplayAttribEXT(Thread *thread,
+ Display *display,
+ EGLint attribute,
+ EGLAttrib *value)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglQueryDisplayAttribEXT",
+ GetDisplayIfValid(display), EGL_FALSE);
+ *value = display->queryAttrib(attribute);
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean QueryStreamKHR(Thread *thread,
+ Display *display,
+ Stream *streamObject,
+ EGLenum attribute,
+ EGLint *value)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglQueryStreamKHR",
+ GetDisplayIfValid(display), EGL_FALSE);
+ switch (attribute)
+ {
+ case EGL_STREAM_STATE_KHR:
+ *value = streamObject->getState();
+ break;
+ case EGL_CONSUMER_LATENCY_USEC_KHR:
+ *value = streamObject->getConsumerLatency();
+ break;
+ case EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR:
+ *value = streamObject->getConsumerAcquireTimeout();
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean QueryStreamu64KHR(Thread *thread,
+ Display *display,
+ Stream *streamObject,
+ EGLenum attribute,
+ EGLuint64KHR *value)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglQueryStreamu64KHR",
+ GetDisplayIfValid(display), EGL_FALSE);
+ switch (attribute)
+ {
+ case EGL_PRODUCER_FRAME_KHR:
+ *value = streamObject->getProducerFrame();
+ break;
+ case EGL_CONSUMER_FRAME_KHR:
+ *value = streamObject->getConsumerFrame();
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean QuerySurfacePointerANGLE(Thread *thread,
+ Display *display,
+ Surface *eglSurface,
+ EGLint attribute,
+ void **value)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglQuerySurfacePointerANGLE",
+ GetDisplayIfValid(display), EGL_FALSE);
+ Error error = eglSurface->querySurfacePointerANGLE(attribute, value);
+ if (error.isError())
+ {
+ thread->setError(error, "eglQuerySurfacePointerANGLE",
+ GetSurfaceIfValid(display, eglSurface));
+ return EGL_FALSE;
+ }
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+void SetBlobCacheFuncsANDROID(Thread *thread,
+ Display *display,
+ EGLSetBlobFuncANDROID set,
+ EGLGetBlobFuncANDROID get)
+{
+ ANGLE_EGL_TRY(thread, display->prepareForCall(), "eglSetBlobCacheFuncsANDROID",
+ GetDisplayIfValid(display));
+ thread->setSuccess();
+ display->setBlobCacheFuncs(set, get);
+}
+
+EGLBoolean SignalSyncKHR(Thread *thread, Display *display, Sync *syncObject, EGLenum mode)
+{
+ gl::Context *currentContext = thread->getContext();
+ ANGLE_EGL_TRY_RETURN(thread, syncObject->signal(display, currentContext, mode),
+ "eglSignalSyncKHR", GetSyncIfValid(display, syncObject), EGL_FALSE);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean StreamAttribKHR(Thread *thread,
+ Display *display,
+ Stream *streamObject,
+ EGLenum attribute,
+ EGLint value)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglStreamAttribKHR",
+ GetDisplayIfValid(display), EGL_FALSE);
+ switch (attribute)
+ {
+ case EGL_CONSUMER_LATENCY_USEC_KHR:
+ streamObject->setConsumerLatency(value);
+ break;
+ case EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR:
+ streamObject->setConsumerAcquireTimeout(value);
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean StreamConsumerAcquireKHR(Thread *thread, Display *display, Stream *streamObject)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglStreamConsumerAcquireKHR",
+ GetDisplayIfValid(display), EGL_FALSE);
+ ANGLE_EGL_TRY_RETURN(thread, streamObject->consumerAcquire(thread->getContext()),
+ "eglStreamConsumerAcquireKHR", GetStreamIfValid(display, streamObject),
+ EGL_FALSE);
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean StreamConsumerGLTextureExternalKHR(Thread *thread,
+ Display *display,
+ Stream *streamObject)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglStreamConsumerGLTextureExternalKHR",
+ GetDisplayIfValid(display), EGL_FALSE);
+ ANGLE_EGL_TRY_RETURN(
+ thread, streamObject->createConsumerGLTextureExternal(AttributeMap(), thread->getContext()),
+ "eglStreamConsumerGLTextureExternalKHR", GetStreamIfValid(display, streamObject),
+ EGL_FALSE);
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean StreamConsumerGLTextureExternalAttribsNV(Thread *thread,
+ Display *display,
+ Stream *streamObject,
+ const AttributeMap &attributes)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(),
+ "eglStreamConsumerGLTextureExternalAttribsNV", GetDisplayIfValid(display),
+ EGL_FALSE);
+
+ gl::Context *context = gl::GetValidGlobalContext();
+ ANGLE_EGL_TRY_RETURN(thread, streamObject->createConsumerGLTextureExternal(attributes, context),
+ "eglStreamConsumerGLTextureExternalAttribsNV",
+ GetStreamIfValid(display, streamObject), EGL_FALSE);
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean StreamConsumerReleaseKHR(Thread *thread, Display *display, Stream *streamObject)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglStreamConsumerReleaseKHR",
+ GetDisplayIfValid(display), EGL_FALSE);
+
+ gl::Context *context = gl::GetValidGlobalContext();
+ ANGLE_EGL_TRY_RETURN(thread, streamObject->consumerRelease(context),
+ "eglStreamConsumerReleaseKHR", GetStreamIfValid(display, streamObject),
+ EGL_FALSE);
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean SwapBuffersWithDamageKHR(Thread *thread,
+ Display *display,
+ Surface *eglSurface,
+ const EGLint *rects,
+ EGLint n_rects)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglSwapBuffersWithDamageEXT",
+ GetDisplayIfValid(display), EGL_FALSE);
+ ANGLE_EGL_TRY_RETURN(thread, eglSurface->swapWithDamage(thread->getContext(), rects, n_rects),
+ "eglSwapBuffersWithDamageEXT", GetSurfaceIfValid(display, eglSurface),
+ EGL_FALSE);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean PrepareSwapBuffersANGLE(EGLDisplay dpy, EGLSurface surface)
+
+{
+ ANGLE_SCOPED_GLOBAL_SURFACE_LOCK();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Surface *surfacePacked = PackParam<Surface *>(surface);
+ Thread *thread = egl::GetCurrentThread();
+ {
+ ANGLE_SCOPED_GLOBAL_LOCK();
+
+ EGL_EVENT(PrepareSwapBuffersANGLE, "dpy = 0x%016" PRIxPTR ", surface = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, (uintptr_t)surface);
+
+ ANGLE_EGL_VALIDATE(thread, PrepareSwapBuffersANGLE, GetDisplayIfValid(dpyPacked),
+ EGLBoolean, dpyPacked, surfacePacked);
+
+ ANGLE_EGL_TRY_RETURN(thread, dpyPacked->prepareForCall(), "eglPrepareSwapBuffersANGLE",
+ GetDisplayIfValid(dpyPacked), EGL_FALSE);
+ }
+ ANGLE_EGL_TRY_RETURN(thread, surfacePacked->prepareSwap(thread->getContext()), "prepareSwap",
+ GetSurfaceIfValid(dpyPacked, surfacePacked), EGL_FALSE);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLint WaitSyncKHR(Thread *thread, Display *display, Sync *syncObject, EGLint flags)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglWaitSync",
+ GetDisplayIfValid(display), EGL_FALSE);
+ gl::Context *currentContext = thread->getContext();
+ ANGLE_EGL_TRY_RETURN(thread, syncObject->serverWait(display, currentContext, flags),
+ "eglWaitSync", GetSyncIfValid(display, syncObject), EGL_FALSE);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLDeviceEXT CreateDeviceANGLE(Thread *thread,
+ EGLint device_type,
+ void *native_device,
+ const EGLAttrib *attrib_list)
+{
+ Device *device = nullptr;
+ ANGLE_EGL_TRY_RETURN(thread, Device::CreateDevice(device_type, native_device, &device),
+ "eglCreateDeviceANGLE", GetThreadIfValid(thread), EGL_NO_DEVICE_EXT);
+
+ thread->setSuccess();
+ return device;
+}
+
+EGLBoolean ReleaseDeviceANGLE(Thread *thread, Device *dev)
+{
+ SafeDelete(dev);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean CreateStreamProducerD3DTextureANGLE(Thread *thread,
+ Display *display,
+ Stream *streamObject,
+ const AttributeMap &attributes)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(),
+ "eglCreateStreamProducerD3DTextureANGLE", GetDisplayIfValid(display),
+ EGL_FALSE);
+ ANGLE_EGL_TRY_RETURN(thread, streamObject->createProducerD3D11Texture(attributes),
+ "eglCreateStreamProducerD3DTextureANGLE",
+ GetStreamIfValid(display, streamObject), EGL_FALSE);
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean StreamPostD3DTextureANGLE(Thread *thread,
+ Display *display,
+ Stream *streamObject,
+ void *texture,
+ const AttributeMap &attributes)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglStreamPostD3DTextureANGLE",
+ GetDisplayIfValid(display), EGL_FALSE);
+ ANGLE_EGL_TRY_RETURN(thread, streamObject->postD3D11Texture(texture, attributes),
+ "eglStreamPostD3DTextureANGLE", GetStreamIfValid(display, streamObject),
+ EGL_FALSE);
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean GetMscRateANGLE(Thread *thread,
+ Display *display,
+ Surface *eglSurface,
+ EGLint *numerator,
+ EGLint *denominator)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglGetMscRateANGLE",
+ GetDisplayIfValid(display), EGL_FALSE);
+ ANGLE_EGL_TRY_RETURN(thread, eglSurface->getMscRate(numerator, denominator),
+ "eglGetMscRateANGLE", GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean GetSyncValuesCHROMIUM(Thread *thread,
+ Display *display,
+ Surface *eglSurface,
+ EGLuint64KHR *ust,
+ EGLuint64KHR *msc,
+ EGLuint64KHR *sbc)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglGetSyncValuesCHROMIUM",
+ GetDisplayIfValid(display), EGL_FALSE);
+ ANGLE_EGL_TRY_RETURN(thread, eglSurface->getSyncValues(ust, msc, sbc),
+ "eglGetSyncValuesCHROMIUM", GetSurfaceIfValid(display, eglSurface),
+ EGL_FALSE);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLint ProgramCacheGetAttribANGLE(Thread *thread, Display *display, EGLenum attrib)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglProgramCacheGetAttribANGLE",
+ GetDisplayIfValid(display), 0);
+ thread->setSuccess();
+ return display->programCacheGetAttrib(attrib);
+}
+
+void ProgramCacheQueryANGLE(Thread *thread,
+ Display *display,
+ EGLint index,
+ void *key,
+ EGLint *keysize,
+ void *binary,
+ EGLint *binarysize)
+{
+ ANGLE_EGL_TRY(thread, display->prepareForCall(), "eglProgramCacheQueryANGLE",
+ GetDisplayIfValid(display));
+ ANGLE_EGL_TRY(thread, display->programCacheQuery(index, key, keysize, binary, binarysize),
+ "eglProgramCacheQueryANGLE", GetDisplayIfValid(display));
+
+ thread->setSuccess();
+}
+
+void ProgramCachePopulateANGLE(Thread *thread,
+ Display *display,
+ const void *key,
+ EGLint keysize,
+ const void *binary,
+ EGLint binarysize)
+{
+ ANGLE_EGL_TRY(thread, display->prepareForCall(), "eglProgramCachePopulateANGLE",
+ GetDisplayIfValid(display));
+ ANGLE_EGL_TRY(thread, display->programCachePopulate(key, keysize, binary, binarysize),
+ "eglProgramCachePopulateANGLE", GetDisplayIfValid(display));
+
+ thread->setSuccess();
+}
+
+EGLint ProgramCacheResizeANGLE(Thread *thread, Display *display, EGLint limit, EGLint mode)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglProgramCacheResizeANGLE",
+ GetDisplayIfValid(display), 0);
+ thread->setSuccess();
+ return display->programCacheResize(limit, mode);
+}
+
+const char *QueryStringiANGLE(Thread *thread, Display *display, EGLint name, EGLint index)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglQueryStringiANGLE",
+ GetDisplayIfValid(display), nullptr);
+ thread->setSuccess();
+ return display->queryStringi(name, index);
+}
+
+EGLBoolean SwapBuffersWithFrameTokenANGLE(Thread *thread,
+ Display *display,
+ Surface *eglSurface,
+ EGLFrameTokenANGLE frametoken)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglSwapBuffersWithFrameTokenANGLE",
+ GetDisplayIfValid(display), EGL_FALSE);
+ ANGLE_EGL_TRY_RETURN(thread, eglSurface->swapWithFrameToken(thread->getContext(), frametoken),
+ "eglSwapBuffersWithFrameTokenANGLE", GetDisplayIfValid(display),
+ EGL_FALSE);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+void ReleaseHighPowerGPUANGLE(Thread *thread, Display *display, gl::Context *context)
+{
+ ANGLE_EGL_TRY(thread, display->prepareForCall(), "eglReleaseHighPowerGPUANGLE",
+ GetDisplayIfValid(display));
+ ANGLE_EGL_TRY(thread, context->releaseHighPowerGPU(), "eglReleaseHighPowerGPUANGLE",
+ GetDisplayIfValid(display));
+
+ thread->setSuccess();
+}
+
+void ReacquireHighPowerGPUANGLE(Thread *thread, Display *display, gl::Context *context)
+{
+ ANGLE_EGL_TRY(thread, display->prepareForCall(), "eglReacquireHighPowerGPUANGLE",
+ GetDisplayIfValid(display));
+ ANGLE_EGL_TRY(thread, context->reacquireHighPowerGPU(), "eglReacquireHighPowerGPUANGLE",
+ GetDisplayIfValid(display));
+
+ thread->setSuccess();
+}
+
+void HandleGPUSwitchANGLE(Thread *thread, Display *display)
+{
+ ANGLE_EGL_TRY(thread, display->prepareForCall(), "eglHandleGPUSwitchANGLE",
+ GetDisplayIfValid(display));
+ ANGLE_EGL_TRY(thread, display->handleGPUSwitch(), "eglHandleGPUSwitchANGLE",
+ GetDisplayIfValid(display));
+
+ thread->setSuccess();
+}
+
+void ForceGPUSwitchANGLE(Thread *thread, Display *display, EGLint gpuIDHigh, EGLint gpuIDLow)
+{
+ ANGLE_EGL_TRY(thread, display->prepareForCall(), "eglForceGPUSwitchANGLE",
+ GetDisplayIfValid(display));
+ ANGLE_EGL_TRY(thread, display->forceGPUSwitch(gpuIDHigh, gpuIDLow), "eglForceGPUSwitchANGLE",
+ GetDisplayIfValid(display));
+
+ thread->setSuccess();
+}
+
+EGLBoolean QueryDisplayAttribANGLE(Thread *thread,
+ Display *display,
+ EGLint attribute,
+ EGLAttrib *value)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglQueryDisplayAttribEXT",
+ GetDisplayIfValid(display), EGL_FALSE);
+ *value = display->queryAttrib(attribute);
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean LockSurfaceKHR(Thread *thread,
+ egl::Display *display,
+ Surface *surface,
+ const AttributeMap &attributes)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglLockSurfaceKHR",
+ GetDisplayIfValid(display), EGL_FALSE);
+ ANGLE_EGL_TRY_RETURN(thread, surface->lockSurfaceKHR(display, attributes), "eglLockSurfaceKHR",
+ GetSurfaceIfValid(display, surface), EGL_FALSE);
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean UnlockSurfaceKHR(Thread *thread, egl::Display *display, Surface *surface)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglUnlockSurfaceKHR",
+ GetDisplayIfValid(display), EGL_FALSE);
+ ANGLE_EGL_TRY_RETURN(thread, surface->unlockSurfaceKHR(display), "eglQuerySurface64KHR",
+ GetSurfaceIfValid(display, surface), EGL_FALSE);
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean QuerySurface64KHR(Thread *thread,
+ egl::Display *display,
+ Surface *surface,
+ EGLint attribute,
+ EGLAttribKHR *value)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglQuerySurface64KHR",
+ GetDisplayIfValid(display), EGL_FALSE);
+ ANGLE_EGL_TRY_RETURN(
+ thread, QuerySurfaceAttrib64KHR(display, thread->getContext(), surface, attribute, value),
+ "eglQuerySurface64KHR", GetSurfaceIfValid(display, surface), EGL_FALSE);
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean ExportVkImageANGLE(Thread *thread,
+ egl::Display *display,
+ Image *image,
+ void *vk_image,
+ void *vk_image_create_info)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglExportVkImageANGLE",
+ GetDisplayIfValid(display), EGL_FALSE);
+ ANGLE_EGL_TRY_RETURN(thread, image->exportVkImage(vk_image, vk_image_create_info),
+ "eglExportVkImageANGLE", GetImageIfValid(display, image), EGL_FALSE);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean SetDamageRegionKHR(Thread *thread,
+ egl::Display *display,
+ egl::Surface *surface,
+ EGLint *rects,
+ EGLint n_rects)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglSetDamageRegionKHR",
+ GetDisplayIfValid(display), EGL_FALSE);
+ surface->setDamageRegion(rects, n_rects);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean QueryDmaBufFormatsEXT(Thread *thread,
+ egl::Display *display,
+ EGLint max_formats,
+ EGLint *formats,
+ EGLint *num_formats)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglQueryDmaBufFormatsEXT",
+ GetDisplayIfValid(display), EGL_FALSE);
+ ANGLE_EGL_TRY_RETURN(thread, display->queryDmaBufFormats(max_formats, formats, num_formats),
+ "eglQueryDmaBufFormatsEXT", GetDisplayIfValid(display), EGL_FALSE);
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean QueryDmaBufModifiersEXT(Thread *thread,
+ egl::Display *display,
+ EGLint format,
+ EGLint max_modifiers,
+ EGLuint64KHR *modifiers,
+ EGLBoolean *external_only,
+ EGLint *num_modifiers)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglQueryDmaBufModifiersEXT",
+ GetDisplayIfValid(display), EGL_FALSE);
+ ANGLE_EGL_TRY_RETURN(thread,
+ display->queryDmaBufModifiers(format, max_modifiers, modifiers,
+ external_only, num_modifiers),
+ "eglQueryDmaBufModifiersEXT", GetDisplayIfValid(display), EGL_FALSE);
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+void *CopyMetalSharedEventANGLE(Thread *thread, Display *display, Sync *syncObject)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCopyMetalSharedEventANGLE",
+ GetDisplayIfValid(display), nullptr);
+ void *result = nullptr;
+ ANGLE_EGL_TRY_RETURN(thread, syncObject->copyMetalSharedEventANGLE(display, &result),
+ "eglCopyMetalSharedEventANGLE", GetSyncIfValid(display, syncObject),
+ nullptr);
+
+ thread->setSuccess();
+ return result;
+}
+
+} // namespace egl
diff --git a/gfx/angle/checkout/src/libGLESv2/egl_ext_stubs_autogen.h b/gfx/angle/checkout/src/libGLESv2/egl_ext_stubs_autogen.h
new file mode 100644
index 0000000000..5d2d7b92f1
--- /dev/null
+++ b/gfx/angle/checkout/src/libGLESv2/egl_ext_stubs_autogen.h
@@ -0,0 +1,264 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from egl.xml and egl_angle_ext.xml.
+//
+// Copyright 2020 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.
+//
+// egl_ext_stubs_autogen.h: Stubs for EXT extension entry points.
+
+#ifndef LIBGLESV2_EGL_EXT_STUBS_AUTOGEN_H_
+#define LIBGLESV2_EGL_EXT_STUBS_AUTOGEN_H_
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include "common/PackedEGLEnums_autogen.h"
+
+namespace gl
+{
+class Context;
+} // namespace gl
+
+namespace egl
+{
+class AttributeMap;
+class Device;
+class Display;
+class Image;
+class Stream;
+class Surface;
+class Sync;
+class Thread;
+struct Config;
+
+EGLint ClientWaitSyncKHR(Thread *thread,
+ egl::Display *dpyPacked,
+ Sync *syncPacked,
+ EGLint flags,
+ EGLTimeKHR timeout);
+EGLImageKHR CreateImageKHR(Thread *thread,
+ egl::Display *dpyPacked,
+ gl::Context *ctxPacked,
+ EGLenum target,
+ EGLClientBuffer buffer,
+ const AttributeMap &attrib_listPacked);
+EGLClientBuffer CreateNativeClientBufferANDROID(Thread *thread,
+ const AttributeMap &attrib_listPacked);
+EGLSurface CreatePlatformPixmapSurfaceEXT(Thread *thread,
+ egl::Display *dpyPacked,
+ Config *configPacked,
+ void *native_pixmap,
+ const AttributeMap &attrib_listPacked);
+EGLSurface CreatePlatformWindowSurfaceEXT(Thread *thread,
+ egl::Display *dpyPacked,
+ Config *configPacked,
+ void *native_window,
+ const AttributeMap &attrib_listPacked);
+EGLStreamKHR CreateStreamKHR(Thread *thread,
+ egl::Display *dpyPacked,
+ const AttributeMap &attrib_listPacked);
+EGLSyncKHR CreateSyncKHR(Thread *thread,
+ egl::Display *dpyPacked,
+ EGLenum type,
+ const AttributeMap &attrib_listPacked);
+EGLint DebugMessageControlKHR(Thread *thread,
+ EGLDEBUGPROCKHR callback,
+ const AttributeMap &attrib_listPacked);
+EGLBoolean DestroyImageKHR(Thread *thread, egl::Display *dpyPacked, Image *imagePacked);
+EGLBoolean DestroyStreamKHR(Thread *thread, egl::Display *dpyPacked, Stream *streamPacked);
+EGLBoolean DestroySyncKHR(Thread *thread, egl::Display *dpyPacked, Sync *syncPacked);
+EGLint DupNativeFenceFDANDROID(Thread *thread, egl::Display *dpyPacked, Sync *syncPacked);
+EGLBoolean GetMscRateANGLE(Thread *thread,
+ egl::Display *dpyPacked,
+ Surface *surfacePacked,
+ EGLint *numerator,
+ EGLint *denominator);
+EGLClientBuffer GetNativeClientBufferANDROID(Thread *thread, const struct AHardwareBuffer *buffer);
+EGLDisplay GetPlatformDisplayEXT(Thread *thread,
+ EGLenum platform,
+ void *native_display,
+ const AttributeMap &attrib_listPacked);
+EGLBoolean GetSyncAttribKHR(Thread *thread,
+ egl::Display *dpyPacked,
+ Sync *syncPacked,
+ EGLint attribute,
+ EGLint *value);
+EGLint LabelObjectKHR(Thread *thread,
+ egl::Display *displayPacked,
+ ObjectType objectTypePacked,
+ EGLObjectKHR object,
+ EGLLabelKHR label);
+EGLBoolean LockSurfaceKHR(Thread *thread,
+ egl::Display *dpyPacked,
+ Surface *surfacePacked,
+ const AttributeMap &attrib_listPacked);
+EGLBoolean PostSubBufferNV(Thread *thread,
+ egl::Display *dpyPacked,
+ Surface *surfacePacked,
+ EGLint x,
+ EGLint y,
+ EGLint width,
+ EGLint height);
+EGLBoolean PresentationTimeANDROID(Thread *thread,
+ egl::Display *dpyPacked,
+ Surface *surfacePacked,
+ EGLnsecsANDROID time);
+EGLBoolean GetCompositorTimingSupportedANDROID(Thread *thread,
+ egl::Display *dpyPacked,
+ Surface *surfacePacked,
+ CompositorTiming namePacked);
+EGLBoolean GetCompositorTimingANDROID(Thread *thread,
+ egl::Display *dpyPacked,
+ Surface *surfacePacked,
+ EGLint numTimestamps,
+ const EGLint *names,
+ EGLnsecsANDROID *values);
+EGLBoolean GetNextFrameIdANDROID(Thread *thread,
+ egl::Display *dpyPacked,
+ Surface *surfacePacked,
+ EGLuint64KHR *frameId);
+EGLBoolean GetFrameTimestampSupportedANDROID(Thread *thread,
+ egl::Display *dpyPacked,
+ Surface *surfacePacked,
+ Timestamp timestampPacked);
+EGLBoolean GetFrameTimestampsANDROID(Thread *thread,
+ egl::Display *dpyPacked,
+ Surface *surfacePacked,
+ EGLuint64KHR frameId,
+ EGLint numTimestamps,
+ const EGLint *timestamps,
+ EGLnsecsANDROID *values);
+EGLBoolean QueryDebugKHR(Thread *thread, EGLint attribute, EGLAttrib *value);
+EGLBoolean QueryDeviceAttribEXT(Thread *thread,
+ Device *devicePacked,
+ EGLint attribute,
+ EGLAttrib *value);
+const char *QueryDeviceStringEXT(Thread *thread, Device *devicePacked, EGLint name);
+EGLBoolean QueryDisplayAttribEXT(Thread *thread,
+ egl::Display *dpyPacked,
+ EGLint attribute,
+ EGLAttrib *value);
+EGLBoolean QueryDmaBufFormatsEXT(Thread *thread,
+ egl::Display *dpyPacked,
+ EGLint max_formats,
+ EGLint *formats,
+ EGLint *num_formats);
+EGLBoolean QueryDmaBufModifiersEXT(Thread *thread,
+ egl::Display *dpyPacked,
+ EGLint format,
+ EGLint max_modifiers,
+ EGLuint64KHR *modifiers,
+ EGLBoolean *external_only,
+ EGLint *num_modifiers);
+EGLBoolean QueryStreamKHR(Thread *thread,
+ egl::Display *dpyPacked,
+ Stream *streamPacked,
+ EGLenum attribute,
+ EGLint *value);
+EGLBoolean QueryStreamu64KHR(Thread *thread,
+ egl::Display *dpyPacked,
+ Stream *streamPacked,
+ EGLenum attribute,
+ EGLuint64KHR *value);
+EGLBoolean QuerySurface64KHR(Thread *thread,
+ egl::Display *dpyPacked,
+ Surface *surfacePacked,
+ EGLint attribute,
+ EGLAttribKHR *value);
+EGLBoolean QuerySurfacePointerANGLE(Thread *thread,
+ egl::Display *dpyPacked,
+ Surface *surfacePacked,
+ EGLint attribute,
+ void **value);
+void SetBlobCacheFuncsANDROID(Thread *thread,
+ egl::Display *dpyPacked,
+ EGLSetBlobFuncANDROID set,
+ EGLGetBlobFuncANDROID get);
+EGLBoolean SetDamageRegionKHR(Thread *thread,
+ egl::Display *dpyPacked,
+ Surface *surfacePacked,
+ EGLint *rects,
+ EGLint n_rects);
+EGLBoolean SignalSyncKHR(Thread *thread, egl::Display *dpyPacked, Sync *syncPacked, EGLenum mode);
+EGLBoolean StreamAttribKHR(Thread *thread,
+ egl::Display *dpyPacked,
+ Stream *streamPacked,
+ EGLenum attribute,
+ EGLint value);
+EGLBoolean StreamConsumerAcquireKHR(Thread *thread, egl::Display *dpyPacked, Stream *streamPacked);
+EGLBoolean StreamConsumerGLTextureExternalKHR(Thread *thread,
+ egl::Display *dpyPacked,
+ Stream *streamPacked);
+EGLBoolean StreamConsumerGLTextureExternalAttribsNV(Thread *thread,
+ egl::Display *dpyPacked,
+ Stream *streamPacked,
+ const AttributeMap &attrib_listPacked);
+EGLBoolean StreamConsumerReleaseKHR(Thread *thread, egl::Display *dpyPacked, Stream *streamPacked);
+EGLBoolean SwapBuffersWithDamageKHR(Thread *thread,
+ egl::Display *dpyPacked,
+ Surface *surfacePacked,
+ const EGLint *rects,
+ EGLint n_rects);
+EGLBoolean UnlockSurfaceKHR(Thread *thread, egl::Display *dpyPacked, Surface *surfacePacked);
+EGLint WaitSyncKHR(Thread *thread, egl::Display *dpyPacked, Sync *syncPacked, EGLint flags);
+EGLDeviceEXT CreateDeviceANGLE(Thread *thread,
+ EGLint device_type,
+ void *native_device,
+ const EGLAttrib *attrib_list);
+EGLBoolean ReleaseDeviceANGLE(Thread *thread, Device *devicePacked);
+EGLBoolean CreateStreamProducerD3DTextureANGLE(Thread *thread,
+ egl::Display *dpyPacked,
+ Stream *streamPacked,
+ const AttributeMap &attrib_listPacked);
+EGLBoolean StreamPostD3DTextureANGLE(Thread *thread,
+ egl::Display *dpyPacked,
+ Stream *streamPacked,
+ void *texture,
+ const AttributeMap &attrib_listPacked);
+EGLBoolean GetSyncValuesCHROMIUM(Thread *thread,
+ egl::Display *dpyPacked,
+ Surface *surfacePacked,
+ EGLuint64KHR *ust,
+ EGLuint64KHR *msc,
+ EGLuint64KHR *sbc);
+EGLint ProgramCacheGetAttribANGLE(Thread *thread, egl::Display *dpyPacked, EGLenum attrib);
+void ProgramCacheQueryANGLE(Thread *thread,
+ egl::Display *dpyPacked,
+ EGLint index,
+ void *key,
+ EGLint *keysize,
+ void *binary,
+ EGLint *binarysize);
+void ProgramCachePopulateANGLE(Thread *thread,
+ egl::Display *dpyPacked,
+ const void *key,
+ EGLint keysize,
+ const void *binary,
+ EGLint binarysize);
+EGLint ProgramCacheResizeANGLE(Thread *thread, egl::Display *dpyPacked, EGLint limit, EGLint mode);
+const char *QueryStringiANGLE(Thread *thread, egl::Display *dpyPacked, EGLint name, EGLint index);
+EGLBoolean SwapBuffersWithFrameTokenANGLE(Thread *thread,
+ egl::Display *dpyPacked,
+ Surface *surfacePacked,
+ EGLFrameTokenANGLE frametoken);
+EGLBoolean PrepareSwapBuffersANGLE(EGLDisplay dpy, EGLSurface surface);
+void ReleaseHighPowerGPUANGLE(Thread *thread, egl::Display *dpyPacked, gl::Context *ctxPacked);
+void ReacquireHighPowerGPUANGLE(Thread *thread, egl::Display *dpyPacked, gl::Context *ctxPacked);
+void HandleGPUSwitchANGLE(Thread *thread, egl::Display *dpyPacked);
+void ForceGPUSwitchANGLE(Thread *thread,
+ egl::Display *dpyPacked,
+ EGLint gpuIDHigh,
+ EGLint gpuIDLow);
+EGLBoolean QueryDisplayAttribANGLE(Thread *thread,
+ egl::Display *dpyPacked,
+ EGLint attribute,
+ EGLAttrib *value);
+EGLBoolean ExportVkImageANGLE(Thread *thread,
+ egl::Display *dpyPacked,
+ Image *imagePacked,
+ void *vk_image,
+ void *vk_image_create_info);
+void *CopyMetalSharedEventANGLE(Thread *thread, egl::Display *dpyPacked, Sync *syncPacked);
+} // namespace egl
+#endif // LIBGLESV2_EGL_EXT_STUBS_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libGLESv2/egl_stubs.cpp b/gfx/angle/checkout/src/libGLESv2/egl_stubs.cpp
new file mode 100644
index 0000000000..f2b8ad3dba
--- /dev/null
+++ b/gfx/angle/checkout/src/libGLESv2/egl_stubs.cpp
@@ -0,0 +1,777 @@
+//
+// Copyright 2020 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.
+//
+// egl_stubs.cpp: Stubs for EGL entry points.
+//
+
+#include "libGLESv2/egl_stubs_autogen.h"
+
+#include "common/angle_version_info.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Display.h"
+#include "libANGLE/EGLSync.h"
+#include "libANGLE/Surface.h"
+#include "libANGLE/Thread.h"
+#include "libANGLE/capture/capture_egl.h"
+#include "libANGLE/capture/frame_capture_utils_autogen.h"
+#include "libANGLE/capture/gl_enum_utils_autogen.h"
+#include "libANGLE/queryutils.h"
+#include "libANGLE/validationEGL.h"
+#include "libGLESv2/global_state.h"
+#include "libGLESv2/proc_table_egl.h"
+
+namespace egl
+{
+namespace
+{
+
+bool CompareProc(const ProcEntry &a, const char *b)
+{
+ return strcmp(a.first, b) < 0;
+}
+
+void ClipConfigs(const std::vector<const Config *> &filteredConfigs,
+ EGLConfig *outputConfigs,
+ EGLint configSize,
+ EGLint *numConfigs)
+{
+ EGLint resultSize = static_cast<EGLint>(filteredConfigs.size());
+ if (outputConfigs)
+ {
+ resultSize = std::max(std::min(resultSize, configSize), 0);
+ for (EGLint i = 0; i < resultSize; i++)
+ {
+ outputConfigs[i] = const_cast<Config *>(filteredConfigs[i]);
+ }
+ }
+ *numConfigs = resultSize;
+}
+} // anonymous namespace
+
+EGLBoolean BindAPI(Thread *thread, EGLenum api)
+{
+ thread->setAPI(api);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean BindTexImage(Thread *thread, Display *display, Surface *eglSurface, EGLint buffer)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglBindTexImage",
+ GetDisplayIfValid(display), EGL_FALSE);
+
+ gl::Context *context = thread->getContext();
+ if (context && !context->isContextLost())
+ {
+ gl::TextureType type =
+ egl_gl::EGLTextureTargetToTextureType(eglSurface->getTextureTarget());
+ gl::Texture *textureObject = context->getTextureByType(type);
+ ANGLE_EGL_TRY_RETURN(thread, eglSurface->bindTexImage(context, textureObject, buffer),
+ "eglBindTexImage", GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
+
+ ANGLE_CAPTURE_EGL(EGLBindTexImage, thread, eglSurface, buffer);
+ }
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean ChooseConfig(Thread *thread,
+ Display *display,
+ const AttributeMap &attribMap,
+ EGLConfig *configs,
+ EGLint config_size,
+ EGLint *num_config)
+{
+ ClipConfigs(display->chooseConfig(attribMap), configs, config_size, num_config);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLint ClientWaitSync(Thread *thread,
+ Display *display,
+ Sync *syncObject,
+ EGLint flags,
+ EGLTime timeout)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglClientWaitSync",
+ GetDisplayIfValid(display), EGL_FALSE);
+ gl::Context *currentContext = thread->getContext();
+ EGLint syncStatus = EGL_FALSE;
+ ANGLE_EGL_TRY_RETURN(
+ thread, syncObject->clientWait(display, currentContext, flags, timeout, &syncStatus),
+ "eglClientWaitSync", GetSyncIfValid(display, syncObject), EGL_FALSE);
+
+ thread->setSuccess();
+ return syncStatus;
+}
+
+EGLBoolean CopyBuffers(Thread *thread,
+ Display *display,
+ Surface *eglSurface,
+ EGLNativePixmapType target)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCopyBuffers",
+ GetDisplayIfValid(display), EGL_FALSE);
+ UNIMPLEMENTED(); // FIXME
+
+ thread->setSuccess();
+ return 0;
+}
+
+EGLContext CreateContext(Thread *thread,
+ Display *display,
+ Config *configuration,
+ gl::Context *sharedGLContext,
+ const AttributeMap &attributes)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCreateContext",
+ GetDisplayIfValid(display), EGL_NO_CONTEXT);
+ gl::Context *context = nullptr;
+ ANGLE_EGL_TRY_RETURN(thread,
+ display->createContext(configuration, sharedGLContext, thread->getAPI(),
+ attributes, &context),
+ "eglCreateContext", GetDisplayIfValid(display), EGL_NO_CONTEXT);
+
+ thread->setSuccess();
+ return static_cast<EGLContext>(context);
+}
+
+EGLImage CreateImage(Thread *thread,
+ Display *display,
+ gl::Context *context,
+ EGLenum target,
+ EGLClientBuffer buffer,
+ const AttributeMap &attributes)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCreateImage",
+ GetDisplayIfValid(display), EGL_FALSE);
+
+ Image *image = nullptr;
+ Error error = display->createImage(context, target, buffer, attributes, &image);
+ if (error.isError())
+ {
+ thread->setError(error, "eglCreateImage", GetDisplayIfValid(display));
+ return EGL_NO_IMAGE;
+ }
+
+ ANGLE_CAPTURE_EGL(EGLCreateImage, thread, context, target, buffer, attributes, image);
+
+ thread->setSuccess();
+ return static_cast<EGLImage>(image);
+}
+
+EGLSurface CreatePbufferFromClientBuffer(Thread *thread,
+ Display *display,
+ EGLenum buftype,
+ EGLClientBuffer buffer,
+ Config *configuration,
+ const AttributeMap &attributes)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCreatePbufferFromClientBuffer",
+ GetDisplayIfValid(display), EGL_NO_SURFACE);
+ Surface *surface = nullptr;
+ ANGLE_EGL_TRY_RETURN(thread,
+ display->createPbufferFromClientBuffer(configuration, buftype, buffer,
+ attributes, &surface),
+ "eglCreatePbufferFromClientBuffer", GetDisplayIfValid(display),
+ EGL_NO_SURFACE);
+
+ return static_cast<EGLSurface>(surface);
+}
+
+EGLSurface CreatePbufferSurface(Thread *thread,
+ Display *display,
+ Config *configuration,
+ const AttributeMap &attributes)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCreatePbufferSurface",
+ GetDisplayIfValid(display), EGL_NO_SURFACE);
+ Surface *surface = nullptr;
+ ANGLE_EGL_TRY_RETURN(thread, display->createPbufferSurface(configuration, attributes, &surface),
+ "eglCreatePbufferSurface", GetDisplayIfValid(display), EGL_NO_SURFACE);
+
+ ANGLE_CAPTURE_EGL(EGLCreatePbufferSurface, thread, attributes, surface);
+
+ return static_cast<EGLSurface>(surface);
+}
+
+EGLSurface CreatePixmapSurface(Thread *thread,
+ Display *display,
+ Config *configuration,
+ EGLNativePixmapType pixmap,
+ const AttributeMap &attributes)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCreatePixmapSurface",
+ GetDisplayIfValid(display), EGL_NO_SURFACE);
+ Surface *surface = nullptr;
+ ANGLE_EGL_TRY_RETURN(thread,
+ display->createPixmapSurface(configuration, pixmap, attributes, &surface),
+ "eglCreatePixmapSurface", GetDisplayIfValid(display), EGL_NO_SURFACE);
+
+ thread->setSuccess();
+ return static_cast<EGLSurface>(surface);
+}
+
+EGLSurface CreatePlatformPixmapSurface(Thread *thread,
+ Display *display,
+ Config *configuration,
+ void *pixmap,
+ const AttributeMap &attributes)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCreatePlatformPixmapSurface",
+ GetDisplayIfValid(display), EGL_NO_SURFACE);
+ Surface *surface = nullptr;
+ EGLNativePixmapType nativePixmap = reinterpret_cast<EGLNativePixmapType>(pixmap);
+ ANGLE_EGL_TRY_RETURN(
+ thread, display->createPixmapSurface(configuration, nativePixmap, attributes, &surface),
+ "eglCreatePlatformPixmapSurface", GetDisplayIfValid(display), EGL_NO_SURFACE);
+
+ thread->setSuccess();
+ return static_cast<EGLSurface>(surface);
+}
+
+EGLSurface CreatePlatformWindowSurface(Thread *thread,
+ Display *display,
+ Config *configuration,
+ void *win,
+ const AttributeMap &attributes)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCreatePlatformWindowSurface",
+ GetDisplayIfValid(display), EGL_NO_SURFACE);
+ Surface *surface = nullptr;
+ EGLNativeWindowType nativeWindow = reinterpret_cast<EGLNativeWindowType>(win);
+ ANGLE_EGL_TRY_RETURN(
+ thread, display->createWindowSurface(configuration, nativeWindow, attributes, &surface),
+ "eglPlatformCreateWindowSurface", GetDisplayIfValid(display), EGL_NO_SURFACE);
+
+ return static_cast<EGLSurface>(surface);
+}
+
+EGLSync CreateSync(Thread *thread, Display *display, EGLenum type, const AttributeMap &attributes)
+{
+ gl::Context *currentContext = thread->getContext();
+
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCreateSync",
+ GetDisplayIfValid(display), EGL_FALSE);
+ Sync *syncObject = nullptr;
+ ANGLE_EGL_TRY_RETURN(thread, display->createSync(currentContext, type, attributes, &syncObject),
+ "eglCreateSync", GetDisplayIfValid(display), EGL_NO_SYNC);
+
+ thread->setSuccess();
+ return static_cast<EGLSync>(syncObject);
+}
+
+EGLSurface CreateWindowSurface(Thread *thread,
+ Display *display,
+ Config *configuration,
+ EGLNativeWindowType win,
+ const AttributeMap &attributes)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCreateWindowSurface",
+ GetDisplayIfValid(display), EGL_NO_SURFACE);
+
+ Surface *surface = nullptr;
+ ANGLE_EGL_TRY_RETURN(thread,
+ display->createWindowSurface(configuration, win, attributes, &surface),
+ "eglCreateWindowSurface", GetDisplayIfValid(display), EGL_NO_SURFACE);
+
+ return static_cast<EGLSurface>(surface);
+}
+
+EGLBoolean DestroyContext(Thread *thread, Display *display, gl::Context *context)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglDestroyContext",
+ GetDisplayIfValid(display), EGL_FALSE);
+
+ ScopedSyncCurrentContextFromThread scopedSyncCurrent(thread);
+
+ ANGLE_EGL_TRY_RETURN(thread, display->destroyContext(thread, context), "eglDestroyContext",
+ GetContextIfValid(display, context), EGL_FALSE);
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean DestroyImage(Thread *thread, Display *display, Image *img)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglDestroyImage",
+ GetDisplayIfValid(display), EGL_FALSE);
+ display->destroyImage(img);
+
+ ANGLE_CAPTURE_EGL(EGLDestroyImage, thread, display, img);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean DestroySurface(Thread *thread, Display *display, Surface *eglSurface)
+{
+ ANGLE_CAPTURE_EGL(EGLDestroySurface, thread, display, eglSurface);
+
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglDestroySurface",
+ GetDisplayIfValid(display), EGL_FALSE);
+
+ ANGLE_EGL_TRY_RETURN(thread, display->destroySurface(eglSurface), "eglDestroySurface",
+ GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean DestroySync(Thread *thread, Display *display, Sync *syncObject)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglDestroySync",
+ GetDisplayIfValid(display), EGL_FALSE);
+ display->destroySync(syncObject);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean GetConfigAttrib(Thread *thread,
+ Display *display,
+ Config *configuration,
+ EGLint attribute,
+ EGLint *value)
+{
+ QueryConfigAttrib(configuration, attribute, value);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean GetConfigs(Thread *thread,
+ Display *display,
+ EGLConfig *configs,
+ EGLint config_size,
+ EGLint *num_config)
+{
+ ClipConfigs(display->getConfigs(AttributeMap()), configs, config_size, num_config);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLContext GetCurrentContext(Thread *thread)
+{
+ gl::Context *context = thread->getContext();
+
+ thread->setSuccess();
+ return static_cast<EGLContext>(context);
+}
+
+EGLDisplay GetCurrentDisplay(Thread *thread)
+{
+ thread->setSuccess();
+ if (thread->getContext() != nullptr)
+ {
+ return thread->getContext()->getDisplay();
+ }
+ return EGL_NO_DISPLAY;
+}
+
+EGLSurface GetCurrentSurface(Thread *thread, EGLint readdraw)
+{
+ if (readdraw == EGL_READ)
+ {
+ thread->setSuccess();
+ return thread->getCurrentReadSurface();
+ }
+ else if (readdraw == EGL_DRAW)
+ {
+ thread->setSuccess();
+ return thread->getCurrentDrawSurface();
+ }
+ else
+ {
+ thread->setError(EglBadParameter(), "eglGetCurrentSurface", nullptr);
+ return EGL_NO_SURFACE;
+ }
+}
+
+EGLDisplay GetDisplay(Thread *thread, EGLNativeDisplayType display_id)
+{
+ return Display::GetDisplayFromNativeDisplay(EGL_PLATFORM_ANGLE_ANGLE, display_id,
+ AttributeMap());
+}
+
+EGLint GetError(Thread *thread)
+{
+ EGLint error = thread->getError();
+ thread->setSuccess();
+ return error;
+}
+
+EGLDisplay GetPlatformDisplay(Thread *thread,
+ EGLenum platform,
+ void *native_display,
+ const AttributeMap &attribMap)
+{
+ switch (platform)
+ {
+ case EGL_PLATFORM_ANGLE_ANGLE:
+ case EGL_PLATFORM_GBM_KHR:
+ case EGL_PLATFORM_WAYLAND_EXT:
+ {
+ return Display::GetDisplayFromNativeDisplay(
+ platform, gl::bitCast<EGLNativeDisplayType>(native_display), attribMap);
+ }
+ case EGL_PLATFORM_DEVICE_EXT:
+ {
+ Device *eglDevice = static_cast<Device *>(native_display);
+ return Display::GetDisplayFromDevice(eglDevice, attribMap);
+ }
+ default:
+ {
+ UNREACHABLE();
+ return EGL_NO_DISPLAY;
+ }
+ }
+}
+
+__eglMustCastToProperFunctionPointerType GetProcAddress(Thread *thread, const char *procname)
+{
+ const ProcEntry *entry =
+ std::lower_bound(&g_procTable[0], &g_procTable[g_numProcs], procname, CompareProc);
+
+ thread->setSuccess();
+
+ if (entry == &g_procTable[g_numProcs] || strcmp(entry->first, procname) != 0)
+ {
+ return nullptr;
+ }
+
+ return entry->second;
+}
+
+EGLBoolean GetSyncAttrib(Thread *thread,
+ Display *display,
+ Sync *syncObject,
+ EGLint attribute,
+ EGLAttrib *value)
+{
+ EGLint valueExt;
+ ANGLE_EGL_TRY_RETURN(thread, GetSyncAttrib(display, syncObject, attribute, &valueExt),
+ "eglGetSyncAttrib", GetSyncIfValid(display, syncObject), EGL_FALSE);
+ *value = valueExt;
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean Initialize(Thread *thread, Display *display, EGLint *major, EGLint *minor)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->initialize(), "eglInitialize", GetDisplayIfValid(display),
+ EGL_FALSE);
+
+ if (major)
+ {
+ *major = kEglMajorVersion;
+ }
+ if (minor)
+ {
+ *minor = kEglMinorVersion;
+ }
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean MakeCurrent(Thread *thread,
+ Display *display,
+ Surface *drawSurface,
+ Surface *readSurface,
+ gl::Context *context)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglMakeCurrent",
+ GetDisplayIfValid(display), EGL_FALSE);
+ ScopedSyncCurrentContextFromThread scopedSyncCurrent(thread);
+
+ Surface *previousDraw = thread->getCurrentDrawSurface();
+ Surface *previousRead = thread->getCurrentReadSurface();
+ gl::Context *previousContext = thread->getContext();
+
+ // Only call makeCurrent if the context or surfaces have changed.
+ if (previousDraw != drawSurface || previousRead != readSurface || previousContext != context)
+ {
+ ANGLE_EGL_TRY_RETURN(
+ thread,
+ display->makeCurrent(thread, previousContext, drawSurface, readSurface, context),
+ "eglMakeCurrent", GetContextIfValid(display, context), EGL_FALSE);
+
+ ANGLE_CAPTURE_EGL(EGLMakeCurrent, thread, drawSurface, readSurface, context);
+ }
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLenum QueryAPI(Thread *thread)
+{
+ EGLenum API = thread->getAPI();
+
+ thread->setSuccess();
+ return API;
+}
+
+EGLBoolean QueryContext(Thread *thread,
+ Display *display,
+ gl::Context *context,
+ EGLint attribute,
+ EGLint *value)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglQueryContext",
+ GetDisplayIfValid(display), EGL_FALSE);
+ QueryContextAttrib(context, attribute, value);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+const char *QueryString(Thread *thread, Display *display, EGLint name)
+{
+ if (display)
+ {
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglQueryString",
+ GetDisplayIfValid(display), nullptr);
+ }
+
+ const char *result = nullptr;
+ switch (name)
+ {
+ case EGL_CLIENT_APIS:
+ result = display->getClientAPIString().c_str();
+ break;
+ case EGL_EXTENSIONS:
+ if (display == EGL_NO_DISPLAY)
+ {
+ result = Display::GetClientExtensionString().c_str();
+ }
+ else
+ {
+ result = display->getExtensionString().c_str();
+ }
+ break;
+ case EGL_VENDOR:
+ result = display->getVendorString().c_str();
+ break;
+ case EGL_VERSION:
+ {
+ static const char *sVersionString =
+ MakeStaticString(std::string("1.5 (ANGLE ") + angle::GetANGLEVersionString() + ")");
+ result = sVersionString;
+ break;
+ }
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ thread->setSuccess();
+ return result;
+}
+
+EGLBoolean QuerySurface(Thread *thread,
+ Display *display,
+ Surface *eglSurface,
+ EGLint attribute,
+ EGLint *value)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglQuerySurface",
+ GetDisplayIfValid(display), EGL_FALSE);
+ ANGLE_EGL_TRY_RETURN(
+ thread, QuerySurfaceAttrib(display, thread->getContext(), eglSurface, attribute, value),
+ "eglQuerySurface", GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean ReleaseTexImage(Thread *thread, Display *display, Surface *eglSurface, EGLint buffer)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglReleaseTexImage",
+ GetDisplayIfValid(display), EGL_FALSE);
+ gl::Context *context = thread->getContext();
+ if (context && !context->isContextLost())
+ {
+ gl::Texture *texture = eglSurface->getBoundTexture();
+
+ if (texture)
+ {
+ ANGLE_EGL_TRY_RETURN(thread, eglSurface->releaseTexImage(thread->getContext(), buffer),
+ "eglReleaseTexImage", GetSurfaceIfValid(display, eglSurface),
+ EGL_FALSE);
+ ANGLE_CAPTURE_EGL(EGLReleaseTexImage, thread, eglSurface, buffer);
+ }
+ }
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean ReleaseThread(Thread *thread)
+{
+ ScopedSyncCurrentContextFromThread scopedSyncCurrent(thread);
+
+ Surface *previousDraw = thread->getCurrentDrawSurface();
+ Surface *previousRead = thread->getCurrentReadSurface();
+ gl::Context *previousContext = thread->getContext();
+ Display *previousDisplay = thread->getDisplay();
+
+ if (previousDisplay != EGL_NO_DISPLAY)
+ {
+ ANGLE_EGL_TRY_RETURN(thread, previousDisplay->prepareForCall(), "eglReleaseThread",
+ GetDisplayIfValid(previousDisplay), EGL_FALSE);
+ // Only call makeCurrent if the context or surfaces have changed.
+ if (previousDraw != EGL_NO_SURFACE || previousRead != EGL_NO_SURFACE ||
+ previousContext != EGL_NO_CONTEXT)
+ {
+ ANGLE_EGL_TRY_RETURN(
+ thread,
+ previousDisplay->makeCurrent(thread, previousContext, nullptr, nullptr, nullptr),
+ "eglReleaseThread", nullptr, EGL_FALSE);
+ }
+ ANGLE_EGL_TRY_RETURN(thread, previousDisplay->releaseThread(), "eglReleaseThread",
+ GetDisplayIfValid(previousDisplay), EGL_FALSE);
+ }
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean SurfaceAttrib(Thread *thread,
+ Display *display,
+ Surface *eglSurface,
+ EGLint attribute,
+ EGLint value)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglSurfaceAttrib",
+ GetDisplayIfValid(display), EGL_FALSE);
+
+ ANGLE_EGL_TRY_RETURN(thread, SetSurfaceAttrib(eglSurface, attribute, value), "eglSurfaceAttrib",
+ GetDisplayIfValid(display), EGL_FALSE);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean SwapBuffers(Thread *thread, Display *display, Surface *eglSurface)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglSwapBuffers",
+ GetDisplayIfValid(display), EGL_FALSE);
+
+ ANGLE_EGL_TRY_RETURN(thread, eglSurface->swap(thread->getContext()), "eglSwapBuffers",
+ GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean SwapInterval(Thread *thread, Display *display, EGLint interval)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglSwapInterval",
+ GetDisplayIfValid(display), EGL_FALSE);
+
+ Surface *drawSurface = static_cast<Surface *>(thread->getCurrentDrawSurface());
+ const Config *surfaceConfig = drawSurface->getConfig();
+ EGLint clampedInterval = std::min(std::max(interval, surfaceConfig->minSwapInterval),
+ surfaceConfig->maxSwapInterval);
+
+ drawSurface->setSwapInterval(clampedInterval);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean Terminate(Thread *thread, Display *display)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglTerminate",
+ GetDisplayIfValid(display), EGL_FALSE);
+
+ ScopedSyncCurrentContextFromThread scopedSyncCurrent(thread);
+
+ ANGLE_EGL_TRY_RETURN(thread, display->terminate(thread, Display::TerminateReason::Api),
+ "eglTerminate", GetDisplayIfValid(display), EGL_FALSE);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean WaitClient(Thread *thread)
+{
+ Display *display = thread->getDisplay();
+ if (display == nullptr)
+ {
+ // EGL spec says this about eglWaitClient -
+ // If there is no current context for the current rendering API,
+ // the function has no effect but still returns EGL_TRUE.
+ return EGL_TRUE;
+ }
+
+ gl::Context *context = thread->getContext();
+
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglWaitClient",
+ GetDisplayIfValid(display), EGL_FALSE);
+ ANGLE_EGL_TRY_RETURN(thread, display->waitClient(context), "eglWaitClient",
+ GetContextIfValid(display, context), EGL_FALSE);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean WaitGL(Thread *thread)
+{
+ Display *display = thread->getDisplay();
+ if (display == nullptr)
+ {
+ // EGL spec says this about eglWaitGL -
+ // eglWaitGL is ignored if there is no current EGL rendering context for OpenGL ES.
+ return EGL_TRUE;
+ }
+
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglWaitGL", GetDisplayIfValid(display),
+ EGL_FALSE);
+
+ // eglWaitGL like calling eglWaitClient with the OpenGL ES API bound. Since we only implement
+ // OpenGL ES we can do the call directly.
+ ANGLE_EGL_TRY_RETURN(thread, display->waitClient(thread->getContext()), "eglWaitGL",
+ GetDisplayIfValid(display), EGL_FALSE);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean WaitNative(Thread *thread, EGLint engine)
+{
+ Display *display = thread->getDisplay();
+ if (display == nullptr)
+ {
+ // EGL spec says this about eglWaitNative -
+ // eglWaitNative is ignored if there is no current EGL rendering context.
+ return EGL_TRUE;
+ }
+
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglWaitNative",
+ GetDisplayIfValid(display), EGL_FALSE);
+ ANGLE_EGL_TRY_RETURN(thread, display->waitNative(thread->getContext(), engine), "eglWaitNative",
+ GetThreadIfValid(thread), EGL_FALSE);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean WaitSync(Thread *thread, Display *display, Sync *syncObject, EGLint flags)
+{
+ ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglWaitSync",
+ GetDisplayIfValid(display), EGL_FALSE);
+ gl::Context *currentContext = thread->getContext();
+ ANGLE_EGL_TRY_RETURN(thread, syncObject->serverWait(display, currentContext, flags),
+ "eglWaitSync", GetSyncIfValid(display, syncObject), EGL_FALSE);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+} // namespace egl
diff --git a/gfx/angle/checkout/src/libGLESv2/egl_stubs_autogen.h b/gfx/angle/checkout/src/libGLESv2/egl_stubs_autogen.h
new file mode 100644
index 0000000000..6d7d210d9d
--- /dev/null
+++ b/gfx/angle/checkout/src/libGLESv2/egl_stubs_autogen.h
@@ -0,0 +1,165 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from egl.xml.
+//
+// Copyright 2020 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.
+//
+// egl_stubs_autogen.h: Stubs for EGL entry points.
+
+#ifndef LIBGLESV2_EGL_STUBS_AUTOGEN_H_
+#define LIBGLESV2_EGL_STUBS_AUTOGEN_H_
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include "common/PackedEGLEnums_autogen.h"
+
+namespace gl
+{
+class Context;
+} // namespace gl
+
+namespace egl
+{
+class AttributeMap;
+class Device;
+class Display;
+class Image;
+class Stream;
+class Surface;
+class Sync;
+class Thread;
+struct Config;
+
+EGLBoolean BindAPI(Thread *thread, EGLenum api);
+EGLBoolean BindTexImage(Thread *thread,
+ egl::Display *dpyPacked,
+ Surface *surfacePacked,
+ EGLint buffer);
+EGLBoolean ChooseConfig(Thread *thread,
+ egl::Display *dpyPacked,
+ const AttributeMap &attrib_listPacked,
+ EGLConfig *configs,
+ EGLint config_size,
+ EGLint *num_config);
+EGLint ClientWaitSync(Thread *thread,
+ egl::Display *dpyPacked,
+ Sync *syncPacked,
+ EGLint flags,
+ EGLTime timeout);
+EGLBoolean CopyBuffers(Thread *thread,
+ egl::Display *dpyPacked,
+ Surface *surfacePacked,
+ EGLNativePixmapType target);
+EGLContext CreateContext(Thread *thread,
+ egl::Display *dpyPacked,
+ Config *configPacked,
+ gl::Context *share_contextPacked,
+ const AttributeMap &attrib_listPacked);
+EGLImage CreateImage(Thread *thread,
+ egl::Display *dpyPacked,
+ gl::Context *ctxPacked,
+ EGLenum target,
+ EGLClientBuffer buffer,
+ const AttributeMap &attrib_listPacked);
+EGLSurface CreatePbufferFromClientBuffer(Thread *thread,
+ egl::Display *dpyPacked,
+ EGLenum buftype,
+ EGLClientBuffer buffer,
+ Config *configPacked,
+ const AttributeMap &attrib_listPacked);
+EGLSurface CreatePbufferSurface(Thread *thread,
+ egl::Display *dpyPacked,
+ Config *configPacked,
+ const AttributeMap &attrib_listPacked);
+EGLSurface CreatePixmapSurface(Thread *thread,
+ egl::Display *dpyPacked,
+ Config *configPacked,
+ EGLNativePixmapType pixmap,
+ const AttributeMap &attrib_listPacked);
+EGLSurface CreatePlatformPixmapSurface(Thread *thread,
+ egl::Display *dpyPacked,
+ Config *configPacked,
+ void *native_pixmap,
+ const AttributeMap &attrib_listPacked);
+EGLSurface CreatePlatformWindowSurface(Thread *thread,
+ egl::Display *dpyPacked,
+ Config *configPacked,
+ void *native_window,
+ const AttributeMap &attrib_listPacked);
+EGLSync CreateSync(Thread *thread,
+ egl::Display *dpyPacked,
+ EGLenum type,
+ const AttributeMap &attrib_listPacked);
+EGLSurface CreateWindowSurface(Thread *thread,
+ egl::Display *dpyPacked,
+ Config *configPacked,
+ EGLNativeWindowType win,
+ const AttributeMap &attrib_listPacked);
+EGLBoolean DestroyContext(Thread *thread, egl::Display *dpyPacked, gl::Context *ctxPacked);
+EGLBoolean DestroyImage(Thread *thread, egl::Display *dpyPacked, Image *imagePacked);
+EGLBoolean DestroySurface(Thread *thread, egl::Display *dpyPacked, Surface *surfacePacked);
+EGLBoolean DestroySync(Thread *thread, egl::Display *dpyPacked, Sync *syncPacked);
+EGLBoolean GetConfigAttrib(Thread *thread,
+ egl::Display *dpyPacked,
+ Config *configPacked,
+ EGLint attribute,
+ EGLint *value);
+EGLBoolean GetConfigs(Thread *thread,
+ egl::Display *dpyPacked,
+ EGLConfig *configs,
+ EGLint config_size,
+ EGLint *num_config);
+EGLContext GetCurrentContext(Thread *thread);
+EGLDisplay GetCurrentDisplay(Thread *thread);
+EGLSurface GetCurrentSurface(Thread *thread, EGLint readdraw);
+EGLDisplay GetDisplay(Thread *thread, EGLNativeDisplayType display_id);
+EGLint GetError(Thread *thread);
+EGLDisplay GetPlatformDisplay(Thread *thread,
+ EGLenum platform,
+ void *native_display,
+ const AttributeMap &attrib_listPacked);
+__eglMustCastToProperFunctionPointerType GetProcAddress(Thread *thread, const char *procname);
+EGLBoolean GetSyncAttrib(Thread *thread,
+ egl::Display *dpyPacked,
+ Sync *syncPacked,
+ EGLint attribute,
+ EGLAttrib *value);
+EGLBoolean Initialize(Thread *thread, egl::Display *dpyPacked, EGLint *major, EGLint *minor);
+EGLBoolean MakeCurrent(Thread *thread,
+ egl::Display *dpyPacked,
+ Surface *drawPacked,
+ Surface *readPacked,
+ gl::Context *ctxPacked);
+EGLenum QueryAPI(Thread *thread);
+EGLBoolean QueryContext(Thread *thread,
+ egl::Display *dpyPacked,
+ gl::Context *ctxPacked,
+ EGLint attribute,
+ EGLint *value);
+const char *QueryString(Thread *thread, egl::Display *dpyPacked, EGLint name);
+EGLBoolean QuerySurface(Thread *thread,
+ egl::Display *dpyPacked,
+ Surface *surfacePacked,
+ EGLint attribute,
+ EGLint *value);
+EGLBoolean ReleaseTexImage(Thread *thread,
+ egl::Display *dpyPacked,
+ Surface *surfacePacked,
+ EGLint buffer);
+EGLBoolean ReleaseThread(Thread *thread);
+EGLBoolean SurfaceAttrib(Thread *thread,
+ egl::Display *dpyPacked,
+ Surface *surfacePacked,
+ EGLint attribute,
+ EGLint value);
+EGLBoolean SwapBuffers(Thread *thread, egl::Display *dpyPacked, Surface *surfacePacked);
+EGLBoolean SwapInterval(Thread *thread, egl::Display *dpyPacked, EGLint interval);
+EGLBoolean Terminate(Thread *thread, egl::Display *dpyPacked);
+EGLBoolean WaitClient(Thread *thread);
+EGLBoolean WaitGL(Thread *thread);
+EGLBoolean WaitNative(Thread *thread, EGLint engine);
+EGLBoolean WaitSync(Thread *thread, egl::Display *dpyPacked, Sync *syncPacked, EGLint flags);
+} // namespace egl
+#endif // LIBGLESV2_EGL_STUBS_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libGLESv2/entry_points_egl_autogen.cpp b/gfx/angle/checkout/src/libGLESv2/entry_points_egl_autogen.cpp
new file mode 100644
index 0000000000..3bd9761b1a
--- /dev/null
+++ b/gfx/angle/checkout/src/libGLESv2/entry_points_egl_autogen.cpp
@@ -0,0 +1,865 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from egl.xml.
+//
+// Copyright 2020 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_egl_autogen.cpp:
+// Defines the EGL entry points.
+
+#include "libGLESv2/entry_points_egl_autogen.h"
+
+#include "libANGLE/entry_points_utils.h"
+#include "libANGLE/validationEGL_autogen.h"
+#include "libGLESv2/egl_ext_stubs_autogen.h"
+#include "libGLESv2/egl_stubs_autogen.h"
+#include "libGLESv2/global_state.h"
+
+using namespace egl;
+
+extern "C" {
+
+// EGL 1.0
+EGLBoolean EGLAPIENTRY EGL_ChooseConfig(EGLDisplay dpy,
+ const EGLint *attrib_list,
+ EGLConfig *configs,
+ EGLint config_size,
+ EGLint *num_config)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(ChooseConfig,
+ "dpy = 0x%016" PRIxPTR ", attrib_list = 0x%016" PRIxPTR ", configs = 0x%016" PRIxPTR
+ ", config_size = %d, num_config = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, (uintptr_t)attrib_list, (uintptr_t)configs, config_size,
+ (uintptr_t)num_config);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ const AttributeMap &attrib_listPacked = PackParam<const AttributeMap &>(attrib_list);
+
+ ANGLE_EGL_VALIDATE(thread, ChooseConfig, GetDisplayIfValid(dpyPacked), EGLBoolean, dpyPacked,
+ attrib_listPacked, configs, config_size, num_config);
+
+ return ChooseConfig(thread, dpyPacked, attrib_listPacked, configs, config_size, num_config);
+}
+
+EGLBoolean EGLAPIENTRY EGL_CopyBuffers(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLNativePixmapType target)
+{
+
+ ANGLE_SCOPED_GLOBAL_SURFACE_LOCK();
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(CopyBuffers,
+ "dpy = 0x%016" PRIxPTR ", surface = 0x%016" PRIxPTR ", target = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, (uintptr_t)surface, (uintptr_t)target);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Surface *surfacePacked = PackParam<Surface *>(surface);
+
+ ANGLE_EGL_VALIDATE(thread, CopyBuffers, GetDisplayIfValid(dpyPacked), EGLBoolean, dpyPacked,
+ surfacePacked, target);
+
+ return CopyBuffers(thread, dpyPacked, surfacePacked, target);
+}
+
+EGLContext EGLAPIENTRY EGL_CreateContext(EGLDisplay dpy,
+ EGLConfig config,
+ EGLContext share_context,
+ const EGLint *attrib_list)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(CreateContext,
+ "dpy = 0x%016" PRIxPTR ", config = 0x%016" PRIxPTR ", share_context = 0x%016" PRIxPTR
+ ", attrib_list = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, (uintptr_t)config, (uintptr_t)share_context, (uintptr_t)attrib_list);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Config *configPacked = PackParam<Config *>(config);
+ gl::Context *share_contextPacked = PackParam<gl::Context *>(share_context);
+ const AttributeMap &attrib_listPacked = PackParam<const AttributeMap &>(attrib_list);
+
+ ANGLE_EGL_VALIDATE(thread, CreateContext, GetDisplayIfValid(dpyPacked), EGLContext, dpyPacked,
+ configPacked, share_contextPacked, attrib_listPacked);
+
+ return CreateContext(thread, dpyPacked, configPacked, share_contextPacked, attrib_listPacked);
+}
+
+EGLSurface EGLAPIENTRY EGL_CreatePbufferSurface(EGLDisplay dpy,
+ EGLConfig config,
+ const EGLint *attrib_list)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(CreatePbufferSurface,
+ "dpy = 0x%016" PRIxPTR ", config = 0x%016" PRIxPTR ", attrib_list = 0x%016" PRIxPTR
+ "",
+ (uintptr_t)dpy, (uintptr_t)config, (uintptr_t)attrib_list);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Config *configPacked = PackParam<Config *>(config);
+ const AttributeMap &attrib_listPacked = PackParam<const AttributeMap &>(attrib_list);
+
+ ANGLE_EGL_VALIDATE(thread, CreatePbufferSurface, GetDisplayIfValid(dpyPacked), EGLSurface,
+ dpyPacked, configPacked, attrib_listPacked);
+
+ return CreatePbufferSurface(thread, dpyPacked, configPacked, attrib_listPacked);
+}
+
+EGLSurface EGLAPIENTRY EGL_CreatePixmapSurface(EGLDisplay dpy,
+ EGLConfig config,
+ EGLNativePixmapType pixmap,
+ const EGLint *attrib_list)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(CreatePixmapSurface,
+ "dpy = 0x%016" PRIxPTR ", config = 0x%016" PRIxPTR ", pixmap = 0x%016" PRIxPTR
+ ", attrib_list = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, (uintptr_t)config, (uintptr_t)pixmap, (uintptr_t)attrib_list);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Config *configPacked = PackParam<Config *>(config);
+ const AttributeMap &attrib_listPacked = PackParam<const AttributeMap &>(attrib_list);
+
+ ANGLE_EGL_VALIDATE(thread, CreatePixmapSurface, GetDisplayIfValid(dpyPacked), EGLSurface,
+ dpyPacked, configPacked, pixmap, attrib_listPacked);
+
+ return CreatePixmapSurface(thread, dpyPacked, configPacked, pixmap, attrib_listPacked);
+}
+
+EGLSurface EGLAPIENTRY EGL_CreateWindowSurface(EGLDisplay dpy,
+ EGLConfig config,
+ EGLNativeWindowType win,
+ const EGLint *attrib_list)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(CreateWindowSurface,
+ "dpy = 0x%016" PRIxPTR ", config = 0x%016" PRIxPTR ", win = 0x%016" PRIxPTR
+ ", attrib_list = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, (uintptr_t)config, (uintptr_t)win, (uintptr_t)attrib_list);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Config *configPacked = PackParam<Config *>(config);
+ const AttributeMap &attrib_listPacked = PackParam<const AttributeMap &>(attrib_list);
+
+ ANGLE_EGL_VALIDATE(thread, CreateWindowSurface, GetDisplayIfValid(dpyPacked), EGLSurface,
+ dpyPacked, configPacked, win, attrib_listPacked);
+
+ return CreateWindowSurface(thread, dpyPacked, configPacked, win, attrib_listPacked);
+}
+
+EGLBoolean EGLAPIENTRY EGL_DestroyContext(EGLDisplay dpy, EGLContext ctx)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(DestroyContext, "dpy = 0x%016" PRIxPTR ", ctx = 0x%016" PRIxPTR "", (uintptr_t)dpy,
+ (uintptr_t)ctx);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ gl::Context *ctxPacked = PackParam<gl::Context *>(ctx);
+
+ ANGLE_EGL_VALIDATE(thread, DestroyContext, GetDisplayIfValid(dpyPacked), EGLBoolean, dpyPacked,
+ ctxPacked);
+
+ return DestroyContext(thread, dpyPacked, ctxPacked);
+}
+
+EGLBoolean EGLAPIENTRY EGL_DestroySurface(EGLDisplay dpy, EGLSurface surface)
+{
+
+ ANGLE_SCOPED_GLOBAL_SURFACE_LOCK();
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(DestroySurface, "dpy = 0x%016" PRIxPTR ", surface = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, (uintptr_t)surface);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Surface *surfacePacked = PackParam<Surface *>(surface);
+
+ ANGLE_EGL_VALIDATE(thread, DestroySurface, GetDisplayIfValid(dpyPacked), EGLBoolean, dpyPacked,
+ surfacePacked);
+
+ return DestroySurface(thread, dpyPacked, surfacePacked);
+}
+
+EGLBoolean EGLAPIENTRY EGL_GetConfigAttrib(EGLDisplay dpy,
+ EGLConfig config,
+ EGLint attribute,
+ EGLint *value)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(GetConfigAttrib,
+ "dpy = 0x%016" PRIxPTR ", config = 0x%016" PRIxPTR
+ ", attribute = %d, value = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, (uintptr_t)config, attribute, (uintptr_t)value);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Config *configPacked = PackParam<Config *>(config);
+
+ ANGLE_EGL_VALIDATE(thread, GetConfigAttrib, GetDisplayIfValid(dpyPacked), EGLBoolean, dpyPacked,
+ configPacked, attribute, value);
+
+ return GetConfigAttrib(thread, dpyPacked, configPacked, attribute, value);
+}
+
+EGLBoolean EGLAPIENTRY EGL_GetConfigs(EGLDisplay dpy,
+ EGLConfig *configs,
+ EGLint config_size,
+ EGLint *num_config)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(GetConfigs,
+ "dpy = 0x%016" PRIxPTR ", configs = 0x%016" PRIxPTR
+ ", config_size = %d, num_config = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, (uintptr_t)configs, config_size, (uintptr_t)num_config);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+
+ ANGLE_EGL_VALIDATE(thread, GetConfigs, GetDisplayIfValid(dpyPacked), EGLBoolean, dpyPacked,
+ configs, config_size, num_config);
+
+ return GetConfigs(thread, dpyPacked, configs, config_size, num_config);
+}
+
+EGLDisplay EGLAPIENTRY EGL_GetCurrentDisplay()
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(GetCurrentDisplay, "");
+
+ Thread *thread = egl::GetCurrentThread();
+
+ ANGLE_EGL_VALIDATE(thread, GetCurrentDisplay, nullptr, EGLDisplay);
+
+ return GetCurrentDisplay(thread);
+}
+
+EGLSurface EGLAPIENTRY EGL_GetCurrentSurface(EGLint readdraw)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(GetCurrentSurface, "readdraw = %d", readdraw);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ ANGLE_EGL_VALIDATE(thread, GetCurrentSurface, nullptr, EGLSurface, readdraw);
+
+ return GetCurrentSurface(thread, readdraw);
+}
+
+EGLDisplay EGLAPIENTRY EGL_GetDisplay(EGLNativeDisplayType display_id)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(GetDisplay, "display_id = 0x%016" PRIxPTR "", (uintptr_t)display_id);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ ANGLE_EGL_VALIDATE(thread, GetDisplay, nullptr, EGLDisplay, display_id);
+
+ return GetDisplay(thread, display_id);
+}
+
+EGLint EGLAPIENTRY EGL_GetError()
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(GetError, "");
+
+ Thread *thread = egl::GetCurrentThread();
+
+ ANGLE_EGL_VALIDATE(thread, GetError, nullptr, EGLint);
+
+ return GetError(thread);
+}
+
+__eglMustCastToProperFunctionPointerType EGLAPIENTRY EGL_GetProcAddress(const char *procname)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(GetProcAddress, "procname = 0x%016" PRIxPTR "", (uintptr_t)procname);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ ANGLE_EGL_VALIDATE(thread, GetProcAddress, nullptr, __eglMustCastToProperFunctionPointerType,
+ procname);
+
+ return GetProcAddress(thread, procname);
+}
+
+EGLBoolean EGLAPIENTRY EGL_Initialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(Initialize,
+ "dpy = 0x%016" PRIxPTR ", major = 0x%016" PRIxPTR ", minor = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, (uintptr_t)major, (uintptr_t)minor);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+
+ ANGLE_EGL_VALIDATE(thread, Initialize, GetDisplayIfValid(dpyPacked), EGLBoolean, dpyPacked,
+ major, minor);
+
+ return Initialize(thread, dpyPacked, major, minor);
+}
+
+EGLBoolean EGLAPIENTRY EGL_MakeCurrent(EGLDisplay dpy,
+ EGLSurface draw,
+ EGLSurface read,
+ EGLContext ctx)
+{
+
+ ANGLE_SCOPED_GLOBAL_SURFACE_LOCK();
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(MakeCurrent,
+ "dpy = 0x%016" PRIxPTR ", draw = 0x%016" PRIxPTR ", read = 0x%016" PRIxPTR
+ ", ctx = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, (uintptr_t)draw, (uintptr_t)read, (uintptr_t)ctx);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Surface *drawPacked = PackParam<Surface *>(draw);
+ Surface *readPacked = PackParam<Surface *>(read);
+ gl::Context *ctxPacked = PackParam<gl::Context *>(ctx);
+
+ ANGLE_EGL_VALIDATE(thread, MakeCurrent, GetDisplayIfValid(dpyPacked), EGLBoolean, dpyPacked,
+ drawPacked, readPacked, ctxPacked);
+
+ return MakeCurrent(thread, dpyPacked, drawPacked, readPacked, ctxPacked);
+}
+
+EGLBoolean EGLAPIENTRY EGL_QueryContext(EGLDisplay dpy,
+ EGLContext ctx,
+ EGLint attribute,
+ EGLint *value)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(QueryContext,
+ "dpy = 0x%016" PRIxPTR ", ctx = 0x%016" PRIxPTR
+ ", attribute = %d, value = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, (uintptr_t)ctx, attribute, (uintptr_t)value);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ gl::Context *ctxPacked = PackParam<gl::Context *>(ctx);
+
+ ANGLE_EGL_VALIDATE(thread, QueryContext, GetDisplayIfValid(dpyPacked), EGLBoolean, dpyPacked,
+ ctxPacked, attribute, value);
+
+ return QueryContext(thread, dpyPacked, ctxPacked, attribute, value);
+}
+
+const char *EGLAPIENTRY EGL_QueryString(EGLDisplay dpy, EGLint name)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(QueryString, "dpy = 0x%016" PRIxPTR ", name = %d", (uintptr_t)dpy, name);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+
+ ANGLE_EGL_VALIDATE(thread, QueryString, GetDisplayIfValid(dpyPacked), const char *, dpyPacked,
+ name);
+
+ return QueryString(thread, dpyPacked, name);
+}
+
+EGLBoolean EGLAPIENTRY EGL_QuerySurface(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLint attribute,
+ EGLint *value)
+{
+
+ ANGLE_SCOPED_GLOBAL_SURFACE_LOCK();
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(QuerySurface,
+ "dpy = 0x%016" PRIxPTR ", surface = 0x%016" PRIxPTR
+ ", attribute = %d, value = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, (uintptr_t)surface, attribute, (uintptr_t)value);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Surface *surfacePacked = PackParam<Surface *>(surface);
+
+ ANGLE_EGL_VALIDATE(thread, QuerySurface, GetDisplayIfValid(dpyPacked), EGLBoolean, dpyPacked,
+ surfacePacked, attribute, value);
+
+ return QuerySurface(thread, dpyPacked, surfacePacked, attribute, value);
+}
+
+EGLBoolean EGLAPIENTRY EGL_SwapBuffers(EGLDisplay dpy, EGLSurface surface)
+{
+ ANGLE_EGLBOOLEAN_TRY(PrepareSwapBuffersANGLE(dpy, surface));
+ ANGLE_SCOPED_GLOBAL_SURFACE_LOCK();
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(SwapBuffers, "dpy = 0x%016" PRIxPTR ", surface = 0x%016" PRIxPTR "", (uintptr_t)dpy,
+ (uintptr_t)surface);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Surface *surfacePacked = PackParam<Surface *>(surface);
+
+ ANGLE_EGL_VALIDATE(thread, SwapBuffers, GetDisplayIfValid(dpyPacked), EGLBoolean, dpyPacked,
+ surfacePacked);
+
+ return SwapBuffers(thread, dpyPacked, surfacePacked);
+}
+
+EGLBoolean EGLAPIENTRY EGL_Terminate(EGLDisplay dpy)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(Terminate, "dpy = 0x%016" PRIxPTR "", (uintptr_t)dpy);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+
+ ANGLE_EGL_VALIDATE(thread, Terminate, GetDisplayIfValid(dpyPacked), EGLBoolean, dpyPacked);
+
+ return Terminate(thread, dpyPacked);
+}
+
+EGLBoolean EGLAPIENTRY EGL_WaitGL()
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(WaitGL, "");
+
+ Thread *thread = egl::GetCurrentThread();
+
+ ANGLE_EGL_VALIDATE(thread, WaitGL, nullptr, EGLBoolean);
+
+ return WaitGL(thread);
+}
+
+EGLBoolean EGLAPIENTRY EGL_WaitNative(EGLint engine)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(WaitNative, "engine = %d", engine);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ ANGLE_EGL_VALIDATE(thread, WaitNative, nullptr, EGLBoolean, engine);
+
+ return WaitNative(thread, engine);
+}
+
+// EGL 1.1
+EGLBoolean EGLAPIENTRY EGL_BindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+
+ ANGLE_SCOPED_GLOBAL_SURFACE_LOCK();
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(BindTexImage, "dpy = 0x%016" PRIxPTR ", surface = 0x%016" PRIxPTR ", buffer = %d",
+ (uintptr_t)dpy, (uintptr_t)surface, buffer);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Surface *surfacePacked = PackParam<Surface *>(surface);
+
+ ANGLE_EGL_VALIDATE(thread, BindTexImage, GetDisplayIfValid(dpyPacked), EGLBoolean, dpyPacked,
+ surfacePacked, buffer);
+
+ return BindTexImage(thread, dpyPacked, surfacePacked, buffer);
+}
+
+EGLBoolean EGLAPIENTRY EGL_ReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+
+ ANGLE_SCOPED_GLOBAL_SURFACE_LOCK();
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(ReleaseTexImage, "dpy = 0x%016" PRIxPTR ", surface = 0x%016" PRIxPTR ", buffer = %d",
+ (uintptr_t)dpy, (uintptr_t)surface, buffer);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Surface *surfacePacked = PackParam<Surface *>(surface);
+
+ ANGLE_EGL_VALIDATE(thread, ReleaseTexImage, GetDisplayIfValid(dpyPacked), EGLBoolean, dpyPacked,
+ surfacePacked, buffer);
+
+ return ReleaseTexImage(thread, dpyPacked, surfacePacked, buffer);
+}
+
+EGLBoolean EGLAPIENTRY EGL_SurfaceAttrib(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLint attribute,
+ EGLint value)
+{
+
+ ANGLE_SCOPED_GLOBAL_SURFACE_LOCK();
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(SurfaceAttrib,
+ "dpy = 0x%016" PRIxPTR ", surface = 0x%016" PRIxPTR ", attribute = %d, value = %d",
+ (uintptr_t)dpy, (uintptr_t)surface, attribute, value);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Surface *surfacePacked = PackParam<Surface *>(surface);
+
+ ANGLE_EGL_VALIDATE(thread, SurfaceAttrib, GetDisplayIfValid(dpyPacked), EGLBoolean, dpyPacked,
+ surfacePacked, attribute, value);
+
+ return SurfaceAttrib(thread, dpyPacked, surfacePacked, attribute, value);
+}
+
+EGLBoolean EGLAPIENTRY EGL_SwapInterval(EGLDisplay dpy, EGLint interval)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(SwapInterval, "dpy = 0x%016" PRIxPTR ", interval = %d", (uintptr_t)dpy, interval);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+
+ ANGLE_EGL_VALIDATE(thread, SwapInterval, GetDisplayIfValid(dpyPacked), EGLBoolean, dpyPacked,
+ interval);
+
+ return SwapInterval(thread, dpyPacked, interval);
+}
+
+// EGL 1.2
+EGLBoolean EGLAPIENTRY EGL_BindAPI(EGLenum api)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(BindAPI, "api = 0x%X", api);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ ANGLE_EGL_VALIDATE(thread, BindAPI, nullptr, EGLBoolean, api);
+
+ return BindAPI(thread, api);
+}
+
+EGLSurface EGLAPIENTRY EGL_CreatePbufferFromClientBuffer(EGLDisplay dpy,
+ EGLenum buftype,
+ EGLClientBuffer buffer,
+ EGLConfig config,
+ const EGLint *attrib_list)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(CreatePbufferFromClientBuffer,
+ "dpy = 0x%016" PRIxPTR ", buftype = 0x%X, buffer = 0x%016" PRIxPTR
+ ", config = 0x%016" PRIxPTR ", attrib_list = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, buftype, (uintptr_t)buffer, (uintptr_t)config,
+ (uintptr_t)attrib_list);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Config *configPacked = PackParam<Config *>(config);
+ const AttributeMap &attrib_listPacked = PackParam<const AttributeMap &>(attrib_list);
+
+ ANGLE_EGL_VALIDATE(thread, CreatePbufferFromClientBuffer, GetDisplayIfValid(dpyPacked),
+ EGLSurface, dpyPacked, buftype, buffer, configPacked, attrib_listPacked);
+
+ return CreatePbufferFromClientBuffer(thread, dpyPacked, buftype, buffer, configPacked,
+ attrib_listPacked);
+}
+
+EGLenum EGLAPIENTRY EGL_QueryAPI()
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(QueryAPI, "");
+
+ Thread *thread = egl::GetCurrentThread();
+
+ ANGLE_EGL_VALIDATE(thread, QueryAPI, nullptr, EGLenum);
+
+ return QueryAPI(thread);
+}
+
+EGLBoolean EGLAPIENTRY EGL_ReleaseThread()
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(ReleaseThread, "");
+
+ Thread *thread = egl::GetCurrentThread();
+
+ ANGLE_EGL_VALIDATE(thread, ReleaseThread, nullptr, EGLBoolean);
+
+ return ReleaseThread(thread);
+}
+
+EGLBoolean EGLAPIENTRY EGL_WaitClient()
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(WaitClient, "");
+
+ Thread *thread = egl::GetCurrentThread();
+
+ ANGLE_EGL_VALIDATE(thread, WaitClient, nullptr, EGLBoolean);
+
+ return WaitClient(thread);
+}
+
+// EGL 1.4
+EGLContext EGLAPIENTRY EGL_GetCurrentContext()
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(GetCurrentContext, "");
+
+ Thread *thread = egl::GetCurrentThread();
+
+ ANGLE_EGL_VALIDATE(thread, GetCurrentContext, nullptr, EGLContext);
+
+ return GetCurrentContext(thread);
+}
+
+// EGL 1.5
+EGLint EGLAPIENTRY EGL_ClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(ClientWaitSync,
+ "dpy = 0x%016" PRIxPTR ", sync = 0x%016" PRIxPTR ", flags = %d, timeout = %llu",
+ (uintptr_t)dpy, (uintptr_t)sync, flags, static_cast<unsigned long long>(timeout));
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Sync *syncPacked = PackParam<Sync *>(sync);
+
+ ANGLE_EGL_VALIDATE(thread, ClientWaitSync, GetDisplayIfValid(dpyPacked), EGLint, dpyPacked,
+ syncPacked, flags, timeout);
+
+ return ClientWaitSync(thread, dpyPacked, syncPacked, flags, timeout);
+}
+
+EGLImage EGLAPIENTRY EGL_CreateImage(EGLDisplay dpy,
+ EGLContext ctx,
+ EGLenum target,
+ EGLClientBuffer buffer,
+ const EGLAttrib *attrib_list)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(CreateImage,
+ "dpy = 0x%016" PRIxPTR ", ctx = 0x%016" PRIxPTR
+ ", target = 0x%X, buffer = 0x%016" PRIxPTR ", attrib_list = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, (uintptr_t)ctx, target, (uintptr_t)buffer, (uintptr_t)attrib_list);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ gl::Context *ctxPacked = PackParam<gl::Context *>(ctx);
+ const AttributeMap &attrib_listPacked = PackParam<const AttributeMap &>(attrib_list);
+
+ ANGLE_EGL_VALIDATE(thread, CreateImage, GetDisplayIfValid(dpyPacked), EGLImage, dpyPacked,
+ ctxPacked, target, buffer, attrib_listPacked);
+
+ return CreateImage(thread, dpyPacked, ctxPacked, target, buffer, attrib_listPacked);
+}
+
+EGLSurface EGLAPIENTRY EGL_CreatePlatformPixmapSurface(EGLDisplay dpy,
+ EGLConfig config,
+ void *native_pixmap,
+ const EGLAttrib *attrib_list)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(CreatePlatformPixmapSurface,
+ "dpy = 0x%016" PRIxPTR ", config = 0x%016" PRIxPTR ", native_pixmap = 0x%016" PRIxPTR
+ ", attrib_list = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, (uintptr_t)config, (uintptr_t)native_pixmap, (uintptr_t)attrib_list);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Config *configPacked = PackParam<Config *>(config);
+ const AttributeMap &attrib_listPacked = PackParam<const AttributeMap &>(attrib_list);
+
+ ANGLE_EGL_VALIDATE(thread, CreatePlatformPixmapSurface, GetDisplayIfValid(dpyPacked),
+ EGLSurface, dpyPacked, configPacked, native_pixmap, attrib_listPacked);
+
+ return CreatePlatformPixmapSurface(thread, dpyPacked, configPacked, native_pixmap,
+ attrib_listPacked);
+}
+
+EGLSurface EGLAPIENTRY EGL_CreatePlatformWindowSurface(EGLDisplay dpy,
+ EGLConfig config,
+ void *native_window,
+ const EGLAttrib *attrib_list)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(CreatePlatformWindowSurface,
+ "dpy = 0x%016" PRIxPTR ", config = 0x%016" PRIxPTR ", native_window = 0x%016" PRIxPTR
+ ", attrib_list = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, (uintptr_t)config, (uintptr_t)native_window, (uintptr_t)attrib_list);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Config *configPacked = PackParam<Config *>(config);
+ const AttributeMap &attrib_listPacked = PackParam<const AttributeMap &>(attrib_list);
+
+ ANGLE_EGL_VALIDATE(thread, CreatePlatformWindowSurface, GetDisplayIfValid(dpyPacked),
+ EGLSurface, dpyPacked, configPacked, native_window, attrib_listPacked);
+
+ return CreatePlatformWindowSurface(thread, dpyPacked, configPacked, native_window,
+ attrib_listPacked);
+}
+
+EGLSync EGLAPIENTRY EGL_CreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(CreateSync, "dpy = 0x%016" PRIxPTR ", type = 0x%X, attrib_list = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, type, (uintptr_t)attrib_list);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ const AttributeMap &attrib_listPacked = PackParam<const AttributeMap &>(attrib_list);
+
+ ANGLE_EGL_VALIDATE(thread, CreateSync, GetDisplayIfValid(dpyPacked), EGLSync, dpyPacked, type,
+ attrib_listPacked);
+
+ return CreateSync(thread, dpyPacked, type, attrib_listPacked);
+}
+
+EGLBoolean EGLAPIENTRY EGL_DestroyImage(EGLDisplay dpy, EGLImage image)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(DestroyImage, "dpy = 0x%016" PRIxPTR ", image = 0x%016" PRIxPTR "", (uintptr_t)dpy,
+ (uintptr_t)image);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Image *imagePacked = PackParam<Image *>(image);
+
+ ANGLE_EGL_VALIDATE(thread, DestroyImage, GetDisplayIfValid(dpyPacked), EGLBoolean, dpyPacked,
+ imagePacked);
+
+ return DestroyImage(thread, dpyPacked, imagePacked);
+}
+
+EGLBoolean EGLAPIENTRY EGL_DestroySync(EGLDisplay dpy, EGLSync sync)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(DestroySync, "dpy = 0x%016" PRIxPTR ", sync = 0x%016" PRIxPTR "", (uintptr_t)dpy,
+ (uintptr_t)sync);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Sync *syncPacked = PackParam<Sync *>(sync);
+
+ ANGLE_EGL_VALIDATE(thread, DestroySync, GetDisplayIfValid(dpyPacked), EGLBoolean, dpyPacked,
+ syncPacked);
+
+ return DestroySync(thread, dpyPacked, syncPacked);
+}
+
+EGLDisplay EGLAPIENTRY EGL_GetPlatformDisplay(EGLenum platform,
+ void *native_display,
+ const EGLAttrib *attrib_list)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(GetPlatformDisplay,
+ "platform = 0x%X, native_display = 0x%016" PRIxPTR ", attrib_list = 0x%016" PRIxPTR
+ "",
+ platform, (uintptr_t)native_display, (uintptr_t)attrib_list);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ const AttributeMap &attrib_listPacked = PackParam<const AttributeMap &>(attrib_list);
+
+ ANGLE_EGL_VALIDATE(thread, GetPlatformDisplay, nullptr, EGLDisplay, platform, native_display,
+ attrib_listPacked);
+
+ return GetPlatformDisplay(thread, platform, native_display, attrib_listPacked);
+}
+
+EGLBoolean EGLAPIENTRY EGL_GetSyncAttrib(EGLDisplay dpy,
+ EGLSync sync,
+ EGLint attribute,
+ EGLAttrib *value)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(GetSyncAttrib,
+ "dpy = 0x%016" PRIxPTR ", sync = 0x%016" PRIxPTR
+ ", attribute = %d, value = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, (uintptr_t)sync, attribute, (uintptr_t)value);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Sync *syncPacked = PackParam<Sync *>(sync);
+
+ ANGLE_EGL_VALIDATE(thread, GetSyncAttrib, GetDisplayIfValid(dpyPacked), EGLBoolean, dpyPacked,
+ syncPacked, attribute, value);
+
+ return GetSyncAttrib(thread, dpyPacked, syncPacked, attribute, value);
+}
+
+EGLBoolean EGLAPIENTRY EGL_WaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(WaitSync, "dpy = 0x%016" PRIxPTR ", sync = 0x%016" PRIxPTR ", flags = %d",
+ (uintptr_t)dpy, (uintptr_t)sync, flags);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Sync *syncPacked = PackParam<Sync *>(sync);
+
+ ANGLE_EGL_VALIDATE(thread, WaitSync, GetDisplayIfValid(dpyPacked), EGLBoolean, dpyPacked,
+ syncPacked, flags);
+
+ return WaitSync(thread, dpyPacked, syncPacked, flags);
+}
+
+} // extern "C"
diff --git a/gfx/angle/checkout/src/libGLESv2/entry_points_egl_autogen.h b/gfx/angle/checkout/src/libGLESv2/entry_points_egl_autogen.h
new file mode 100644
index 0000000000..407054b3e6
--- /dev/null
+++ b/gfx/angle/checkout/src/libGLESv2/entry_points_egl_autogen.h
@@ -0,0 +1,138 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from egl.xml.
+//
+// Copyright 2020 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_egl_autogen.h:
+// Defines the EGL entry points.
+
+#ifndef LIBGLESV2_ENTRY_POINTS_EGL_AUTOGEN_H_
+#define LIBGLESV2_ENTRY_POINTS_EGL_AUTOGEN_H_
+
+#include <EGL/egl.h>
+#include <export.h>
+
+extern "C" {
+
+// EGL 1.0
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_ChooseConfig(EGLDisplay dpy,
+ const EGLint *attrib_list,
+ EGLConfig *configs,
+ EGLint config_size,
+ EGLint *num_config);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_CopyBuffers(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLNativePixmapType target);
+ANGLE_EXPORT EGLContext EGLAPIENTRY EGL_CreateContext(EGLDisplay dpy,
+ EGLConfig config,
+ EGLContext share_context,
+ const EGLint *attrib_list);
+ANGLE_EXPORT EGLSurface EGLAPIENTRY EGL_CreatePbufferSurface(EGLDisplay dpy,
+ EGLConfig config,
+ const EGLint *attrib_list);
+ANGLE_EXPORT EGLSurface EGLAPIENTRY EGL_CreatePixmapSurface(EGLDisplay dpy,
+ EGLConfig config,
+ EGLNativePixmapType pixmap,
+ const EGLint *attrib_list);
+ANGLE_EXPORT EGLSurface EGLAPIENTRY EGL_CreateWindowSurface(EGLDisplay dpy,
+ EGLConfig config,
+ EGLNativeWindowType win,
+ const EGLint *attrib_list);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_DestroyContext(EGLDisplay dpy, EGLContext ctx);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_DestroySurface(EGLDisplay dpy, EGLSurface surface);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_GetConfigAttrib(EGLDisplay dpy,
+ EGLConfig config,
+ EGLint attribute,
+ EGLint *value);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_GetConfigs(EGLDisplay dpy,
+ EGLConfig *configs,
+ EGLint config_size,
+ EGLint *num_config);
+ANGLE_EXPORT EGLDisplay EGLAPIENTRY EGL_GetCurrentDisplay();
+ANGLE_EXPORT EGLSurface EGLAPIENTRY EGL_GetCurrentSurface(EGLint readdraw);
+ANGLE_EXPORT EGLDisplay EGLAPIENTRY EGL_GetDisplay(EGLNativeDisplayType display_id);
+ANGLE_EXPORT EGLint EGLAPIENTRY EGL_GetError();
+ANGLE_EXPORT __eglMustCastToProperFunctionPointerType EGLAPIENTRY
+EGL_GetProcAddress(const char *procname);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_Initialize(EGLDisplay dpy, EGLint *major, EGLint *minor);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_MakeCurrent(EGLDisplay dpy,
+ EGLSurface draw,
+ EGLSurface read,
+ EGLContext ctx);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_QueryContext(EGLDisplay dpy,
+ EGLContext ctx,
+ EGLint attribute,
+ EGLint *value);
+ANGLE_EXPORT const char *EGLAPIENTRY EGL_QueryString(EGLDisplay dpy, EGLint name);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_QuerySurface(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLint attribute,
+ EGLint *value);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_SwapBuffers(EGLDisplay dpy, EGLSurface surface);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_Terminate(EGLDisplay dpy);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_WaitGL();
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_WaitNative(EGLint engine);
+
+// EGL 1.1
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_BindTexImage(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLint buffer);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_ReleaseTexImage(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLint buffer);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_SurfaceAttrib(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLint attribute,
+ EGLint value);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_SwapInterval(EGLDisplay dpy, EGLint interval);
+
+// EGL 1.2
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_BindAPI(EGLenum api);
+ANGLE_EXPORT EGLSurface EGLAPIENTRY EGL_CreatePbufferFromClientBuffer(EGLDisplay dpy,
+ EGLenum buftype,
+ EGLClientBuffer buffer,
+ EGLConfig config,
+ const EGLint *attrib_list);
+ANGLE_EXPORT EGLenum EGLAPIENTRY EGL_QueryAPI();
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_ReleaseThread();
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_WaitClient();
+
+// EGL 1.4
+ANGLE_EXPORT EGLContext EGLAPIENTRY EGL_GetCurrentContext();
+
+// EGL 1.5
+ANGLE_EXPORT EGLint EGLAPIENTRY EGL_ClientWaitSync(EGLDisplay dpy,
+ EGLSync sync,
+ EGLint flags,
+ EGLTime timeout);
+ANGLE_EXPORT EGLImage EGLAPIENTRY EGL_CreateImage(EGLDisplay dpy,
+ EGLContext ctx,
+ EGLenum target,
+ EGLClientBuffer buffer,
+ const EGLAttrib *attrib_list);
+ANGLE_EXPORT EGLSurface EGLAPIENTRY EGL_CreatePlatformPixmapSurface(EGLDisplay dpy,
+ EGLConfig config,
+ void *native_pixmap,
+ const EGLAttrib *attrib_list);
+ANGLE_EXPORT EGLSurface EGLAPIENTRY EGL_CreatePlatformWindowSurface(EGLDisplay dpy,
+ EGLConfig config,
+ void *native_window,
+ const EGLAttrib *attrib_list);
+ANGLE_EXPORT EGLSync EGLAPIENTRY EGL_CreateSync(EGLDisplay dpy,
+ EGLenum type,
+ const EGLAttrib *attrib_list);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_DestroyImage(EGLDisplay dpy, EGLImage image);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_DestroySync(EGLDisplay dpy, EGLSync sync);
+ANGLE_EXPORT EGLDisplay EGLAPIENTRY EGL_GetPlatformDisplay(EGLenum platform,
+ void *native_display,
+ const EGLAttrib *attrib_list);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_GetSyncAttrib(EGLDisplay dpy,
+ EGLSync sync,
+ EGLint attribute,
+ EGLAttrib *value);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_WaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags);
+} // extern "C"
+
+#endif // LIBGLESV2_ENTRY_POINTS_EGL_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libGLESv2/entry_points_egl_ext_autogen.cpp b/gfx/angle/checkout/src/libGLESv2/entry_points_egl_ext_autogen.cpp
new file mode 100644
index 0000000000..c07c518e77
--- /dev/null
+++ b/gfx/angle/checkout/src/libGLESv2/entry_points_egl_ext_autogen.cpp
@@ -0,0 +1,1403 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from egl.xml and egl_angle_ext.xml.
+//
+// Copyright 2020 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_egl_ext_autogen.cpp:
+// Defines the EGL Extension entry points.
+
+#include "libGLESv2/entry_points_egl_ext_autogen.h"
+
+#include "libANGLE/entry_points_utils.h"
+#include "libANGLE/validationEGL_autogen.h"
+#include "libGLESv2/egl_ext_stubs_autogen.h"
+#include "libGLESv2/global_state.h"
+
+using namespace egl;
+
+extern "C" {
+
+// EGL_ANDROID_blob_cache
+void EGLAPIENTRY EGL_SetBlobCacheFuncsANDROID(EGLDisplay dpy,
+ EGLSetBlobFuncANDROID set,
+ EGLGetBlobFuncANDROID get)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(SetBlobCacheFuncsANDROID,
+ "dpy = 0x%016" PRIxPTR ", set = 0x%016" PRIxPTR ", get = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, (uintptr_t)set, (uintptr_t)get);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+
+ ANGLE_EGL_VALIDATE_VOID(thread, SetBlobCacheFuncsANDROID, GetDisplayIfValid(dpyPacked),
+ dpyPacked, set, get);
+
+ SetBlobCacheFuncsANDROID(thread, dpyPacked, set, get);
+}
+
+// EGL_ANDROID_create_native_client_buffer
+EGLClientBuffer EGLAPIENTRY EGL_CreateNativeClientBufferANDROID(const EGLint *attrib_list)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(CreateNativeClientBufferANDROID, "attrib_list = 0x%016" PRIxPTR "",
+ (uintptr_t)attrib_list);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ const AttributeMap &attrib_listPacked = PackParam<const AttributeMap &>(attrib_list);
+
+ ANGLE_EGL_VALIDATE(thread, CreateNativeClientBufferANDROID, nullptr, EGLClientBuffer,
+ attrib_listPacked);
+
+ return CreateNativeClientBufferANDROID(thread, attrib_listPacked);
+}
+
+// EGL_ANDROID_get_frame_timestamps
+EGLBoolean EGLAPIENTRY EGL_GetCompositorTimingSupportedANDROID(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLint name)
+{
+
+ ANGLE_SCOPED_GLOBAL_SURFACE_LOCK();
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(GetCompositorTimingSupportedANDROID,
+ "dpy = 0x%016" PRIxPTR ", surface = 0x%016" PRIxPTR ", name = %d", (uintptr_t)dpy,
+ (uintptr_t)surface, name);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Surface *surfacePacked = PackParam<Surface *>(surface);
+ CompositorTiming namePacked = PackParam<CompositorTiming>(name);
+
+ ANGLE_EGL_VALIDATE(thread, GetCompositorTimingSupportedANDROID, GetDisplayIfValid(dpyPacked),
+ EGLBoolean, dpyPacked, surfacePacked, namePacked);
+
+ return GetCompositorTimingSupportedANDROID(thread, dpyPacked, surfacePacked, namePacked);
+}
+
+EGLBoolean EGLAPIENTRY EGL_GetCompositorTimingANDROID(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLint numTimestamps,
+ const EGLint *names,
+ EGLnsecsANDROID *values)
+{
+
+ ANGLE_SCOPED_GLOBAL_SURFACE_LOCK();
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(GetCompositorTimingANDROID,
+ "dpy = 0x%016" PRIxPTR ", surface = 0x%016" PRIxPTR
+ ", numTimestamps = %d, names = 0x%016" PRIxPTR ", values = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, (uintptr_t)surface, numTimestamps, (uintptr_t)names,
+ (uintptr_t)values);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Surface *surfacePacked = PackParam<Surface *>(surface);
+
+ ANGLE_EGL_VALIDATE(thread, GetCompositorTimingANDROID, GetDisplayIfValid(dpyPacked), EGLBoolean,
+ dpyPacked, surfacePacked, numTimestamps, names, values);
+
+ return GetCompositorTimingANDROID(thread, dpyPacked, surfacePacked, numTimestamps, names,
+ values);
+}
+
+EGLBoolean EGLAPIENTRY EGL_GetNextFrameIdANDROID(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLuint64KHR *frameId)
+{
+
+ ANGLE_SCOPED_GLOBAL_SURFACE_LOCK();
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(GetNextFrameIdANDROID,
+ "dpy = 0x%016" PRIxPTR ", surface = 0x%016" PRIxPTR ", frameId = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, (uintptr_t)surface, (uintptr_t)frameId);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Surface *surfacePacked = PackParam<Surface *>(surface);
+
+ ANGLE_EGL_VALIDATE(thread, GetNextFrameIdANDROID, GetDisplayIfValid(dpyPacked), EGLBoolean,
+ dpyPacked, surfacePacked, frameId);
+
+ return GetNextFrameIdANDROID(thread, dpyPacked, surfacePacked, frameId);
+}
+
+EGLBoolean EGLAPIENTRY EGL_GetFrameTimestampSupportedANDROID(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLint timestamp)
+{
+
+ ANGLE_SCOPED_GLOBAL_SURFACE_LOCK();
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(GetFrameTimestampSupportedANDROID,
+ "dpy = 0x%016" PRIxPTR ", surface = 0x%016" PRIxPTR ", timestamp = %d",
+ (uintptr_t)dpy, (uintptr_t)surface, timestamp);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Surface *surfacePacked = PackParam<Surface *>(surface);
+ Timestamp timestampPacked = PackParam<Timestamp>(timestamp);
+
+ ANGLE_EGL_VALIDATE(thread, GetFrameTimestampSupportedANDROID, GetDisplayIfValid(dpyPacked),
+ EGLBoolean, dpyPacked, surfacePacked, timestampPacked);
+
+ return GetFrameTimestampSupportedANDROID(thread, dpyPacked, surfacePacked, timestampPacked);
+}
+
+EGLBoolean EGLAPIENTRY EGL_GetFrameTimestampsANDROID(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLuint64KHR frameId,
+ EGLint numTimestamps,
+ const EGLint *timestamps,
+ EGLnsecsANDROID *values)
+{
+
+ ANGLE_SCOPED_GLOBAL_SURFACE_LOCK();
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(GetFrameTimestampsANDROID,
+ "dpy = 0x%016" PRIxPTR ", surface = 0x%016" PRIxPTR
+ ", frameId = %llu, numTimestamps = %d, timestamps = 0x%016" PRIxPTR
+ ", values = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, (uintptr_t)surface, static_cast<unsigned long long>(frameId),
+ numTimestamps, (uintptr_t)timestamps, (uintptr_t)values);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Surface *surfacePacked = PackParam<Surface *>(surface);
+
+ ANGLE_EGL_VALIDATE(thread, GetFrameTimestampsANDROID, GetDisplayIfValid(dpyPacked), EGLBoolean,
+ dpyPacked, surfacePacked, frameId, numTimestamps, timestamps, values);
+
+ return GetFrameTimestampsANDROID(thread, dpyPacked, surfacePacked, frameId, numTimestamps,
+ timestamps, values);
+}
+
+// EGL_ANDROID_get_native_client_buffer
+EGLClientBuffer EGLAPIENTRY EGL_GetNativeClientBufferANDROID(const struct AHardwareBuffer *buffer)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(GetNativeClientBufferANDROID, "buffer = 0x%016" PRIxPTR "", (uintptr_t)buffer);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ ANGLE_EGL_VALIDATE(thread, GetNativeClientBufferANDROID, nullptr, EGLClientBuffer, buffer);
+
+ return GetNativeClientBufferANDROID(thread, buffer);
+}
+
+// EGL_ANDROID_native_fence_sync
+EGLint EGLAPIENTRY EGL_DupNativeFenceFDANDROID(EGLDisplay dpy, EGLSyncKHR sync)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(DupNativeFenceFDANDROID, "dpy = 0x%016" PRIxPTR ", sync = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, (uintptr_t)sync);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Sync *syncPacked = PackParam<Sync *>(sync);
+
+ ANGLE_EGL_VALIDATE(thread, DupNativeFenceFDANDROID, GetDisplayIfValid(dpyPacked), EGLint,
+ dpyPacked, syncPacked);
+
+ return DupNativeFenceFDANDROID(thread, dpyPacked, syncPacked);
+}
+
+// EGL_ANDROID_presentation_time
+EGLBoolean EGLAPIENTRY EGL_PresentationTimeANDROID(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLnsecsANDROID time)
+{
+
+ ANGLE_SCOPED_GLOBAL_SURFACE_LOCK();
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(PresentationTimeANDROID,
+ "dpy = 0x%016" PRIxPTR ", surface = 0x%016" PRIxPTR ", time = %llu", (uintptr_t)dpy,
+ (uintptr_t)surface, static_cast<unsigned long long>(time));
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Surface *surfacePacked = PackParam<Surface *>(surface);
+
+ ANGLE_EGL_VALIDATE(thread, PresentationTimeANDROID, GetDisplayIfValid(dpyPacked), EGLBoolean,
+ dpyPacked, surfacePacked, time);
+
+ return PresentationTimeANDROID(thread, dpyPacked, surfacePacked, time);
+}
+
+// EGL_ANGLE_device_creation
+EGLDeviceEXT EGLAPIENTRY EGL_CreateDeviceANGLE(EGLint device_type,
+ void *native_device,
+ const EGLAttrib *attrib_list)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(CreateDeviceANGLE,
+ "device_type = %d, native_device = 0x%016" PRIxPTR ", attrib_list = 0x%016" PRIxPTR
+ "",
+ device_type, (uintptr_t)native_device, (uintptr_t)attrib_list);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ ANGLE_EGL_VALIDATE(thread, CreateDeviceANGLE, nullptr, EGLDeviceEXT, device_type, native_device,
+ attrib_list);
+
+ return CreateDeviceANGLE(thread, device_type, native_device, attrib_list);
+}
+
+EGLBoolean EGLAPIENTRY EGL_ReleaseDeviceANGLE(EGLDeviceEXT device)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(ReleaseDeviceANGLE, "device = 0x%016" PRIxPTR "", (uintptr_t)device);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ Device *devicePacked = PackParam<Device *>(device);
+
+ ANGLE_EGL_VALIDATE(thread, ReleaseDeviceANGLE, nullptr, EGLBoolean, devicePacked);
+
+ return ReleaseDeviceANGLE(thread, devicePacked);
+}
+
+// EGL_ANGLE_feature_control
+const char *EGLAPIENTRY EGL_QueryStringiANGLE(EGLDisplay dpy, EGLint name, EGLint index)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(QueryStringiANGLE, "dpy = 0x%016" PRIxPTR ", name = %d, index = %d", (uintptr_t)dpy,
+ name, index);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+
+ ANGLE_EGL_VALIDATE(thread, QueryStringiANGLE, GetDisplayIfValid(dpyPacked), const char *,
+ dpyPacked, name, index);
+
+ return QueryStringiANGLE(thread, dpyPacked, name, index);
+}
+
+EGLBoolean EGLAPIENTRY EGL_QueryDisplayAttribANGLE(EGLDisplay dpy,
+ EGLint attribute,
+ EGLAttrib *value)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(QueryDisplayAttribANGLE,
+ "dpy = 0x%016" PRIxPTR ", attribute = %d, value = 0x%016" PRIxPTR "", (uintptr_t)dpy,
+ attribute, (uintptr_t)value);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+
+ ANGLE_EGL_VALIDATE(thread, QueryDisplayAttribANGLE, GetDisplayIfValid(dpyPacked), EGLBoolean,
+ dpyPacked, attribute, value);
+
+ return QueryDisplayAttribANGLE(thread, dpyPacked, attribute, value);
+}
+
+// EGL_ANGLE_metal_shared_event_sync
+void *EGLAPIENTRY EGL_CopyMetalSharedEventANGLE(EGLDisplay dpy, EGLSyncKHR sync)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(CopyMetalSharedEventANGLE, "dpy = 0x%016" PRIxPTR ", sync = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, (uintptr_t)sync);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Sync *syncPacked = PackParam<Sync *>(sync);
+
+ ANGLE_EGL_VALIDATE(thread, CopyMetalSharedEventANGLE, GetDisplayIfValid(dpyPacked), void *,
+ dpyPacked, syncPacked);
+
+ return CopyMetalSharedEventANGLE(thread, dpyPacked, syncPacked);
+}
+
+// EGL_ANGLE_power_preference
+void EGLAPIENTRY EGL_ReleaseHighPowerGPUANGLE(EGLDisplay dpy, EGLContext ctx)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(ReleaseHighPowerGPUANGLE, "dpy = 0x%016" PRIxPTR ", ctx = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, (uintptr_t)ctx);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ gl::Context *ctxPacked = PackParam<gl::Context *>(ctx);
+
+ ANGLE_EGL_VALIDATE_VOID(thread, ReleaseHighPowerGPUANGLE, GetDisplayIfValid(dpyPacked),
+ dpyPacked, ctxPacked);
+
+ ReleaseHighPowerGPUANGLE(thread, dpyPacked, ctxPacked);
+}
+
+void EGLAPIENTRY EGL_ReacquireHighPowerGPUANGLE(EGLDisplay dpy, EGLContext ctx)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(ReacquireHighPowerGPUANGLE, "dpy = 0x%016" PRIxPTR ", ctx = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, (uintptr_t)ctx);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ gl::Context *ctxPacked = PackParam<gl::Context *>(ctx);
+
+ ANGLE_EGL_VALIDATE_VOID(thread, ReacquireHighPowerGPUANGLE, GetDisplayIfValid(dpyPacked),
+ dpyPacked, ctxPacked);
+
+ ReacquireHighPowerGPUANGLE(thread, dpyPacked, ctxPacked);
+}
+
+void EGLAPIENTRY EGL_HandleGPUSwitchANGLE(EGLDisplay dpy)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(HandleGPUSwitchANGLE, "dpy = 0x%016" PRIxPTR "", (uintptr_t)dpy);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+
+ ANGLE_EGL_VALIDATE_VOID(thread, HandleGPUSwitchANGLE, GetDisplayIfValid(dpyPacked), dpyPacked);
+
+ HandleGPUSwitchANGLE(thread, dpyPacked);
+}
+
+void EGLAPIENTRY EGL_ForceGPUSwitchANGLE(EGLDisplay dpy, EGLint gpuIDHigh, EGLint gpuIDLow)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(ForceGPUSwitchANGLE, "dpy = 0x%016" PRIxPTR ", gpuIDHigh = %d, gpuIDLow = %d",
+ (uintptr_t)dpy, gpuIDHigh, gpuIDLow);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+
+ ANGLE_EGL_VALIDATE_VOID(thread, ForceGPUSwitchANGLE, GetDisplayIfValid(dpyPacked), dpyPacked,
+ gpuIDHigh, gpuIDLow);
+
+ ForceGPUSwitchANGLE(thread, dpyPacked, gpuIDHigh, gpuIDLow);
+}
+
+// EGL_ANGLE_prepare_swap_buffers
+EGLBoolean EGLAPIENTRY EGL_PrepareSwapBuffersANGLE(EGLDisplay dpy, EGLSurface surface)
+{
+ return PrepareSwapBuffersANGLE(dpy, surface);
+}
+
+// EGL_ANGLE_program_cache_control
+EGLint EGLAPIENTRY EGL_ProgramCacheGetAttribANGLE(EGLDisplay dpy, EGLenum attrib)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(ProgramCacheGetAttribANGLE, "dpy = 0x%016" PRIxPTR ", attrib = 0x%X", (uintptr_t)dpy,
+ attrib);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+
+ ANGLE_EGL_VALIDATE(thread, ProgramCacheGetAttribANGLE, GetDisplayIfValid(dpyPacked), EGLint,
+ dpyPacked, attrib);
+
+ return ProgramCacheGetAttribANGLE(thread, dpyPacked, attrib);
+}
+
+void EGLAPIENTRY EGL_ProgramCacheQueryANGLE(EGLDisplay dpy,
+ EGLint index,
+ void *key,
+ EGLint *keysize,
+ void *binary,
+ EGLint *binarysize)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(ProgramCacheQueryANGLE,
+ "dpy = 0x%016" PRIxPTR ", index = %d, key = 0x%016" PRIxPTR
+ ", keysize = 0x%016" PRIxPTR ", binary = 0x%016" PRIxPTR
+ ", binarysize = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, index, (uintptr_t)key, (uintptr_t)keysize, (uintptr_t)binary,
+ (uintptr_t)binarysize);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+
+ ANGLE_EGL_VALIDATE_VOID(thread, ProgramCacheQueryANGLE, GetDisplayIfValid(dpyPacked), dpyPacked,
+ index, key, keysize, binary, binarysize);
+
+ ProgramCacheQueryANGLE(thread, dpyPacked, index, key, keysize, binary, binarysize);
+}
+
+void EGLAPIENTRY EGL_ProgramCachePopulateANGLE(EGLDisplay dpy,
+ const void *key,
+ EGLint keysize,
+ const void *binary,
+ EGLint binarysize)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(ProgramCachePopulateANGLE,
+ "dpy = 0x%016" PRIxPTR ", key = 0x%016" PRIxPTR
+ ", keysize = %d, binary = 0x%016" PRIxPTR ", binarysize = %d",
+ (uintptr_t)dpy, (uintptr_t)key, keysize, (uintptr_t)binary, binarysize);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+
+ ANGLE_EGL_VALIDATE_VOID(thread, ProgramCachePopulateANGLE, GetDisplayIfValid(dpyPacked),
+ dpyPacked, key, keysize, binary, binarysize);
+
+ ProgramCachePopulateANGLE(thread, dpyPacked, key, keysize, binary, binarysize);
+}
+
+EGLint EGLAPIENTRY EGL_ProgramCacheResizeANGLE(EGLDisplay dpy, EGLint limit, EGLint mode)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(ProgramCacheResizeANGLE, "dpy = 0x%016" PRIxPTR ", limit = %d, mode = %d",
+ (uintptr_t)dpy, limit, mode);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+
+ ANGLE_EGL_VALIDATE(thread, ProgramCacheResizeANGLE, GetDisplayIfValid(dpyPacked), EGLint,
+ dpyPacked, limit, mode);
+
+ return ProgramCacheResizeANGLE(thread, dpyPacked, limit, mode);
+}
+
+// EGL_ANGLE_query_surface_pointer
+EGLBoolean EGLAPIENTRY EGL_QuerySurfacePointerANGLE(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLint attribute,
+ void **value)
+{
+
+ ANGLE_SCOPED_GLOBAL_SURFACE_LOCK();
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(QuerySurfacePointerANGLE,
+ "dpy = 0x%016" PRIxPTR ", surface = 0x%016" PRIxPTR
+ ", attribute = %d, value = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, (uintptr_t)surface, attribute, (uintptr_t)value);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Surface *surfacePacked = PackParam<Surface *>(surface);
+
+ ANGLE_EGL_VALIDATE(thread, QuerySurfacePointerANGLE, GetDisplayIfValid(dpyPacked), EGLBoolean,
+ dpyPacked, surfacePacked, attribute, value);
+
+ return QuerySurfacePointerANGLE(thread, dpyPacked, surfacePacked, attribute, value);
+}
+
+// EGL_ANGLE_stream_producer_d3d_texture
+EGLBoolean EGLAPIENTRY EGL_CreateStreamProducerD3DTextureANGLE(EGLDisplay dpy,
+ EGLStreamKHR stream,
+ const EGLAttrib *attrib_list)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(CreateStreamProducerD3DTextureANGLE,
+ "dpy = 0x%016" PRIxPTR ", stream = 0x%016" PRIxPTR ", attrib_list = 0x%016" PRIxPTR
+ "",
+ (uintptr_t)dpy, (uintptr_t)stream, (uintptr_t)attrib_list);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Stream *streamPacked = PackParam<Stream *>(stream);
+ const AttributeMap &attrib_listPacked = PackParam<const AttributeMap &>(attrib_list);
+
+ ANGLE_EGL_VALIDATE(thread, CreateStreamProducerD3DTextureANGLE, GetDisplayIfValid(dpyPacked),
+ EGLBoolean, dpyPacked, streamPacked, attrib_listPacked);
+
+ return CreateStreamProducerD3DTextureANGLE(thread, dpyPacked, streamPacked, attrib_listPacked);
+}
+
+EGLBoolean EGLAPIENTRY EGL_StreamPostD3DTextureANGLE(EGLDisplay dpy,
+ EGLStreamKHR stream,
+ void *texture,
+ const EGLAttrib *attrib_list)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(StreamPostD3DTextureANGLE,
+ "dpy = 0x%016" PRIxPTR ", stream = 0x%016" PRIxPTR ", texture = 0x%016" PRIxPTR
+ ", attrib_list = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, (uintptr_t)stream, (uintptr_t)texture, (uintptr_t)attrib_list);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Stream *streamPacked = PackParam<Stream *>(stream);
+ const AttributeMap &attrib_listPacked = PackParam<const AttributeMap &>(attrib_list);
+
+ ANGLE_EGL_VALIDATE(thread, StreamPostD3DTextureANGLE, GetDisplayIfValid(dpyPacked), EGLBoolean,
+ dpyPacked, streamPacked, texture, attrib_listPacked);
+
+ return StreamPostD3DTextureANGLE(thread, dpyPacked, streamPacked, texture, attrib_listPacked);
+}
+
+// EGL_ANGLE_swap_with_frame_token
+EGLBoolean EGLAPIENTRY EGL_SwapBuffersWithFrameTokenANGLE(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLFrameTokenANGLE frametoken)
+{
+ ANGLE_EGLBOOLEAN_TRY(PrepareSwapBuffersANGLE(dpy, surface));
+ ANGLE_SCOPED_GLOBAL_SURFACE_LOCK();
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(SwapBuffersWithFrameTokenANGLE,
+ "dpy = 0x%016" PRIxPTR ", surface = 0x%016" PRIxPTR ", frametoken = 0x%llX",
+ (uintptr_t)dpy, (uintptr_t)surface, static_cast<unsigned long long>(frametoken));
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Surface *surfacePacked = PackParam<Surface *>(surface);
+
+ ANGLE_EGL_VALIDATE(thread, SwapBuffersWithFrameTokenANGLE, GetDisplayIfValid(dpyPacked),
+ EGLBoolean, dpyPacked, surfacePacked, frametoken);
+
+ return SwapBuffersWithFrameTokenANGLE(thread, dpyPacked, surfacePacked, frametoken);
+}
+
+// EGL_ANGLE_sync_control_rate
+EGLBoolean EGLAPIENTRY EGL_GetMscRateANGLE(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLint *numerator,
+ EGLint *denominator)
+{
+
+ ANGLE_SCOPED_GLOBAL_SURFACE_LOCK();
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(GetMscRateANGLE,
+ "dpy = 0x%016" PRIxPTR ", surface = 0x%016" PRIxPTR ", numerator = 0x%016" PRIxPTR
+ ", denominator = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, (uintptr_t)surface, (uintptr_t)numerator, (uintptr_t)denominator);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Surface *surfacePacked = PackParam<Surface *>(surface);
+
+ ANGLE_EGL_VALIDATE(thread, GetMscRateANGLE, GetDisplayIfValid(dpyPacked), EGLBoolean, dpyPacked,
+ surfacePacked, numerator, denominator);
+
+ return GetMscRateANGLE(thread, dpyPacked, surfacePacked, numerator, denominator);
+}
+
+// EGL_ANGLE_vulkan_image
+EGLBoolean EGLAPIENTRY EGL_ExportVkImageANGLE(EGLDisplay dpy,
+ EGLImage image,
+ void *vk_image,
+ void *vk_image_create_info)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(ExportVkImageANGLE,
+ "dpy = 0x%016" PRIxPTR ", image = 0x%016" PRIxPTR ", vk_image = 0x%016" PRIxPTR
+ ", vk_image_create_info = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, (uintptr_t)image, (uintptr_t)vk_image,
+ (uintptr_t)vk_image_create_info);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Image *imagePacked = PackParam<Image *>(image);
+
+ ANGLE_EGL_VALIDATE(thread, ExportVkImageANGLE, GetDisplayIfValid(dpyPacked), EGLBoolean,
+ dpyPacked, imagePacked, vk_image, vk_image_create_info);
+
+ return ExportVkImageANGLE(thread, dpyPacked, imagePacked, vk_image, vk_image_create_info);
+}
+
+// EGL_CHROMIUM_sync_control
+EGLBoolean EGLAPIENTRY EGL_GetSyncValuesCHROMIUM(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLuint64KHR *ust,
+ EGLuint64KHR *msc,
+ EGLuint64KHR *sbc)
+{
+
+ ANGLE_SCOPED_GLOBAL_SURFACE_LOCK();
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(GetSyncValuesCHROMIUM,
+ "dpy = 0x%016" PRIxPTR ", surface = 0x%016" PRIxPTR ", ust = 0x%016" PRIxPTR
+ ", msc = 0x%016" PRIxPTR ", sbc = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, (uintptr_t)surface, (uintptr_t)ust, (uintptr_t)msc, (uintptr_t)sbc);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Surface *surfacePacked = PackParam<Surface *>(surface);
+
+ ANGLE_EGL_VALIDATE(thread, GetSyncValuesCHROMIUM, GetDisplayIfValid(dpyPacked), EGLBoolean,
+ dpyPacked, surfacePacked, ust, msc, sbc);
+
+ return GetSyncValuesCHROMIUM(thread, dpyPacked, surfacePacked, ust, msc, sbc);
+}
+
+// EGL_EXT_device_query
+EGLBoolean EGLAPIENTRY EGL_QueryDeviceAttribEXT(EGLDeviceEXT device,
+ EGLint attribute,
+ EGLAttrib *value)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(QueryDeviceAttribEXT,
+ "device = 0x%016" PRIxPTR ", attribute = %d, value = 0x%016" PRIxPTR "",
+ (uintptr_t)device, attribute, (uintptr_t)value);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ Device *devicePacked = PackParam<Device *>(device);
+
+ ANGLE_EGL_VALIDATE(thread, QueryDeviceAttribEXT, nullptr, EGLBoolean, devicePacked, attribute,
+ value);
+
+ return QueryDeviceAttribEXT(thread, devicePacked, attribute, value);
+}
+
+const char *EGLAPIENTRY EGL_QueryDeviceStringEXT(EGLDeviceEXT device, EGLint name)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(QueryDeviceStringEXT, "device = 0x%016" PRIxPTR ", name = %d", (uintptr_t)device,
+ name);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ Device *devicePacked = PackParam<Device *>(device);
+
+ ANGLE_EGL_VALIDATE(thread, QueryDeviceStringEXT, nullptr, const char *, devicePacked, name);
+
+ return QueryDeviceStringEXT(thread, devicePacked, name);
+}
+
+EGLBoolean EGLAPIENTRY EGL_QueryDisplayAttribEXT(EGLDisplay dpy, EGLint attribute, EGLAttrib *value)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(QueryDisplayAttribEXT,
+ "dpy = 0x%016" PRIxPTR ", attribute = %d, value = 0x%016" PRIxPTR "", (uintptr_t)dpy,
+ attribute, (uintptr_t)value);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+
+ ANGLE_EGL_VALIDATE(thread, QueryDisplayAttribEXT, GetDisplayIfValid(dpyPacked), EGLBoolean,
+ dpyPacked, attribute, value);
+
+ return QueryDisplayAttribEXT(thread, dpyPacked, attribute, value);
+}
+
+// EGL_EXT_image_dma_buf_import_modifiers
+EGLBoolean EGLAPIENTRY EGL_QueryDmaBufFormatsEXT(EGLDisplay dpy,
+ EGLint max_formats,
+ EGLint *formats,
+ EGLint *num_formats)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(QueryDmaBufFormatsEXT,
+ "dpy = 0x%016" PRIxPTR ", max_formats = %d, formats = 0x%016" PRIxPTR
+ ", num_formats = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, max_formats, (uintptr_t)formats, (uintptr_t)num_formats);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+
+ ANGLE_EGL_VALIDATE(thread, QueryDmaBufFormatsEXT, GetDisplayIfValid(dpyPacked), EGLBoolean,
+ dpyPacked, max_formats, formats, num_formats);
+
+ return QueryDmaBufFormatsEXT(thread, dpyPacked, max_formats, formats, num_formats);
+}
+
+EGLBoolean EGLAPIENTRY EGL_QueryDmaBufModifiersEXT(EGLDisplay dpy,
+ EGLint format,
+ EGLint max_modifiers,
+ EGLuint64KHR *modifiers,
+ EGLBoolean *external_only,
+ EGLint *num_modifiers)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(QueryDmaBufModifiersEXT,
+ "dpy = 0x%016" PRIxPTR ", format = %d, max_modifiers = %d, modifiers = 0x%016" PRIxPTR
+ ", external_only = 0x%016" PRIxPTR ", num_modifiers = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, format, max_modifiers, (uintptr_t)modifiers, (uintptr_t)external_only,
+ (uintptr_t)num_modifiers);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+
+ ANGLE_EGL_VALIDATE(thread, QueryDmaBufModifiersEXT, GetDisplayIfValid(dpyPacked), EGLBoolean,
+ dpyPacked, format, max_modifiers, modifiers, external_only, num_modifiers);
+
+ return QueryDmaBufModifiersEXT(thread, dpyPacked, format, max_modifiers, modifiers,
+ external_only, num_modifiers);
+}
+
+// EGL_EXT_platform_base
+EGLSurface EGLAPIENTRY EGL_CreatePlatformPixmapSurfaceEXT(EGLDisplay dpy,
+ EGLConfig config,
+ void *native_pixmap,
+ const EGLint *attrib_list)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(CreatePlatformPixmapSurfaceEXT,
+ "dpy = 0x%016" PRIxPTR ", config = 0x%016" PRIxPTR ", native_pixmap = 0x%016" PRIxPTR
+ ", attrib_list = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, (uintptr_t)config, (uintptr_t)native_pixmap, (uintptr_t)attrib_list);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Config *configPacked = PackParam<Config *>(config);
+ const AttributeMap &attrib_listPacked = PackParam<const AttributeMap &>(attrib_list);
+
+ ANGLE_EGL_VALIDATE(thread, CreatePlatformPixmapSurfaceEXT, GetDisplayIfValid(dpyPacked),
+ EGLSurface, dpyPacked, configPacked, native_pixmap, attrib_listPacked);
+
+ return CreatePlatformPixmapSurfaceEXT(thread, dpyPacked, configPacked, native_pixmap,
+ attrib_listPacked);
+}
+
+EGLSurface EGLAPIENTRY EGL_CreatePlatformWindowSurfaceEXT(EGLDisplay dpy,
+ EGLConfig config,
+ void *native_window,
+ const EGLint *attrib_list)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(CreatePlatformWindowSurfaceEXT,
+ "dpy = 0x%016" PRIxPTR ", config = 0x%016" PRIxPTR ", native_window = 0x%016" PRIxPTR
+ ", attrib_list = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, (uintptr_t)config, (uintptr_t)native_window, (uintptr_t)attrib_list);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Config *configPacked = PackParam<Config *>(config);
+ const AttributeMap &attrib_listPacked = PackParam<const AttributeMap &>(attrib_list);
+
+ ANGLE_EGL_VALIDATE(thread, CreatePlatformWindowSurfaceEXT, GetDisplayIfValid(dpyPacked),
+ EGLSurface, dpyPacked, configPacked, native_window, attrib_listPacked);
+
+ return CreatePlatformWindowSurfaceEXT(thread, dpyPacked, configPacked, native_window,
+ attrib_listPacked);
+}
+
+EGLDisplay EGLAPIENTRY EGL_GetPlatformDisplayEXT(EGLenum platform,
+ void *native_display,
+ const EGLint *attrib_list)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(GetPlatformDisplayEXT,
+ "platform = 0x%X, native_display = 0x%016" PRIxPTR ", attrib_list = 0x%016" PRIxPTR
+ "",
+ platform, (uintptr_t)native_display, (uintptr_t)attrib_list);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ const AttributeMap &attrib_listPacked = PackParam<const AttributeMap &>(attrib_list);
+
+ ANGLE_EGL_VALIDATE(thread, GetPlatformDisplayEXT, nullptr, EGLDisplay, platform, native_display,
+ attrib_listPacked);
+
+ return GetPlatformDisplayEXT(thread, platform, native_display, attrib_listPacked);
+}
+
+// EGL_KHR_debug
+EGLint EGLAPIENTRY EGL_DebugMessageControlKHR(EGLDEBUGPROCKHR callback,
+ const EGLAttrib *attrib_list)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(DebugMessageControlKHR,
+ "callback = 0x%016" PRIxPTR ", attrib_list = 0x%016" PRIxPTR "", (uintptr_t)callback,
+ (uintptr_t)attrib_list);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ const AttributeMap &attrib_listPacked = PackParam<const AttributeMap &>(attrib_list);
+
+ ANGLE_EGL_VALIDATE(thread, DebugMessageControlKHR, nullptr, EGLint, callback,
+ attrib_listPacked);
+
+ return DebugMessageControlKHR(thread, callback, attrib_listPacked);
+}
+
+EGLint EGLAPIENTRY EGL_LabelObjectKHR(EGLDisplay display,
+ EGLenum objectType,
+ EGLObjectKHR object,
+ EGLLabelKHR label)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(LabelObjectKHR,
+ "display = 0x%016" PRIxPTR ", objectType = 0x%X, object = 0x%016" PRIxPTR
+ ", label = 0x%016" PRIxPTR "",
+ (uintptr_t)display, objectType, (uintptr_t)object, (uintptr_t)label);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *displayPacked = PackParam<egl::Display *>(display);
+ ObjectType objectTypePacked = PackParam<ObjectType>(objectType);
+
+ ANGLE_EGL_VALIDATE(thread, LabelObjectKHR, GetDisplayIfValid(displayPacked), EGLint,
+ displayPacked, objectTypePacked, object, label);
+
+ return LabelObjectKHR(thread, displayPacked, objectTypePacked, object, label);
+}
+
+EGLBoolean EGLAPIENTRY EGL_QueryDebugKHR(EGLint attribute, EGLAttrib *value)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(QueryDebugKHR, "attribute = %d, value = 0x%016" PRIxPTR "", attribute,
+ (uintptr_t)value);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ ANGLE_EGL_VALIDATE(thread, QueryDebugKHR, nullptr, EGLBoolean, attribute, value);
+
+ return QueryDebugKHR(thread, attribute, value);
+}
+
+// EGL_KHR_fence_sync
+EGLint EGLAPIENTRY EGL_ClientWaitSyncKHR(EGLDisplay dpy,
+ EGLSyncKHR sync,
+ EGLint flags,
+ EGLTimeKHR timeout)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(ClientWaitSyncKHR,
+ "dpy = 0x%016" PRIxPTR ", sync = 0x%016" PRIxPTR ", flags = %d, timeout = %llu",
+ (uintptr_t)dpy, (uintptr_t)sync, flags, static_cast<unsigned long long>(timeout));
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Sync *syncPacked = PackParam<Sync *>(sync);
+
+ ANGLE_EGL_VALIDATE(thread, ClientWaitSyncKHR, GetDisplayIfValid(dpyPacked), EGLint, dpyPacked,
+ syncPacked, flags, timeout);
+
+ return ClientWaitSyncKHR(thread, dpyPacked, syncPacked, flags, timeout);
+}
+
+EGLSyncKHR EGLAPIENTRY EGL_CreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(CreateSyncKHR,
+ "dpy = 0x%016" PRIxPTR ", type = 0x%X, attrib_list = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, type, (uintptr_t)attrib_list);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ const AttributeMap &attrib_listPacked = PackParam<const AttributeMap &>(attrib_list);
+
+ ANGLE_EGL_VALIDATE(thread, CreateSyncKHR, GetDisplayIfValid(dpyPacked), EGLSyncKHR, dpyPacked,
+ type, attrib_listPacked);
+
+ return CreateSyncKHR(thread, dpyPacked, type, attrib_listPacked);
+}
+
+EGLBoolean EGLAPIENTRY EGL_DestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(DestroySyncKHR, "dpy = 0x%016" PRIxPTR ", sync = 0x%016" PRIxPTR "", (uintptr_t)dpy,
+ (uintptr_t)sync);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Sync *syncPacked = PackParam<Sync *>(sync);
+
+ ANGLE_EGL_VALIDATE(thread, DestroySyncKHR, GetDisplayIfValid(dpyPacked), EGLBoolean, dpyPacked,
+ syncPacked);
+
+ return DestroySyncKHR(thread, dpyPacked, syncPacked);
+}
+
+EGLBoolean EGLAPIENTRY EGL_GetSyncAttribKHR(EGLDisplay dpy,
+ EGLSyncKHR sync,
+ EGLint attribute,
+ EGLint *value)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(GetSyncAttribKHR,
+ "dpy = 0x%016" PRIxPTR ", sync = 0x%016" PRIxPTR
+ ", attribute = %d, value = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, (uintptr_t)sync, attribute, (uintptr_t)value);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Sync *syncPacked = PackParam<Sync *>(sync);
+
+ ANGLE_EGL_VALIDATE(thread, GetSyncAttribKHR, GetDisplayIfValid(dpyPacked), EGLBoolean,
+ dpyPacked, syncPacked, attribute, value);
+
+ return GetSyncAttribKHR(thread, dpyPacked, syncPacked, attribute, value);
+}
+
+// EGL_KHR_image
+EGLImageKHR EGLAPIENTRY EGL_CreateImageKHR(EGLDisplay dpy,
+ EGLContext ctx,
+ EGLenum target,
+ EGLClientBuffer buffer,
+ const EGLint *attrib_list)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(CreateImageKHR,
+ "dpy = 0x%016" PRIxPTR ", ctx = 0x%016" PRIxPTR
+ ", target = 0x%X, buffer = 0x%016" PRIxPTR ", attrib_list = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, (uintptr_t)ctx, target, (uintptr_t)buffer, (uintptr_t)attrib_list);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ gl::Context *ctxPacked = PackParam<gl::Context *>(ctx);
+ const AttributeMap &attrib_listPacked = PackParam<const AttributeMap &>(attrib_list);
+
+ ANGLE_EGL_VALIDATE(thread, CreateImageKHR, GetDisplayIfValid(dpyPacked), EGLImageKHR, dpyPacked,
+ ctxPacked, target, buffer, attrib_listPacked);
+
+ return CreateImageKHR(thread, dpyPacked, ctxPacked, target, buffer, attrib_listPacked);
+}
+
+EGLBoolean EGLAPIENTRY EGL_DestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(DestroyImageKHR, "dpy = 0x%016" PRIxPTR ", image = 0x%016" PRIxPTR "", (uintptr_t)dpy,
+ (uintptr_t)image);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Image *imagePacked = PackParam<Image *>(image);
+
+ ANGLE_EGL_VALIDATE(thread, DestroyImageKHR, GetDisplayIfValid(dpyPacked), EGLBoolean, dpyPacked,
+ imagePacked);
+
+ return DestroyImageKHR(thread, dpyPacked, imagePacked);
+}
+
+// EGL_KHR_lock_surface3
+EGLBoolean EGLAPIENTRY EGL_LockSurfaceKHR(EGLDisplay dpy,
+ EGLSurface surface,
+ const EGLint *attrib_list)
+{
+
+ ANGLE_SCOPED_GLOBAL_SURFACE_LOCK();
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(LockSurfaceKHR,
+ "dpy = 0x%016" PRIxPTR ", surface = 0x%016" PRIxPTR ", attrib_list = 0x%016" PRIxPTR
+ "",
+ (uintptr_t)dpy, (uintptr_t)surface, (uintptr_t)attrib_list);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Surface *surfacePacked = PackParam<Surface *>(surface);
+ const AttributeMap &attrib_listPacked = PackParam<const AttributeMap &>(attrib_list);
+
+ ANGLE_EGL_VALIDATE(thread, LockSurfaceKHR, GetDisplayIfValid(dpyPacked), EGLBoolean, dpyPacked,
+ surfacePacked, attrib_listPacked);
+
+ return LockSurfaceKHR(thread, dpyPacked, surfacePacked, attrib_listPacked);
+}
+
+EGLBoolean EGLAPIENTRY EGL_QuerySurface64KHR(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLint attribute,
+ EGLAttribKHR *value)
+{
+
+ ANGLE_SCOPED_GLOBAL_SURFACE_LOCK();
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(QuerySurface64KHR,
+ "dpy = 0x%016" PRIxPTR ", surface = 0x%016" PRIxPTR
+ ", attribute = %d, value = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, (uintptr_t)surface, attribute, (uintptr_t)value);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Surface *surfacePacked = PackParam<Surface *>(surface);
+
+ ANGLE_EGL_VALIDATE(thread, QuerySurface64KHR, GetDisplayIfValid(dpyPacked), EGLBoolean,
+ dpyPacked, surfacePacked, attribute, value);
+
+ return QuerySurface64KHR(thread, dpyPacked, surfacePacked, attribute, value);
+}
+
+EGLBoolean EGLAPIENTRY EGL_UnlockSurfaceKHR(EGLDisplay dpy, EGLSurface surface)
+{
+
+ ANGLE_SCOPED_GLOBAL_SURFACE_LOCK();
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(UnlockSurfaceKHR, "dpy = 0x%016" PRIxPTR ", surface = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, (uintptr_t)surface);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Surface *surfacePacked = PackParam<Surface *>(surface);
+
+ ANGLE_EGL_VALIDATE(thread, UnlockSurfaceKHR, GetDisplayIfValid(dpyPacked), EGLBoolean,
+ dpyPacked, surfacePacked);
+
+ return UnlockSurfaceKHR(thread, dpyPacked, surfacePacked);
+}
+
+// EGL_KHR_partial_update
+EGLBoolean EGLAPIENTRY EGL_SetDamageRegionKHR(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLint *rects,
+ EGLint n_rects)
+{
+
+ ANGLE_SCOPED_GLOBAL_SURFACE_LOCK();
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(SetDamageRegionKHR,
+ "dpy = 0x%016" PRIxPTR ", surface = 0x%016" PRIxPTR ", rects = 0x%016" PRIxPTR
+ ", n_rects = %d",
+ (uintptr_t)dpy, (uintptr_t)surface, (uintptr_t)rects, n_rects);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Surface *surfacePacked = PackParam<Surface *>(surface);
+
+ ANGLE_EGL_VALIDATE(thread, SetDamageRegionKHR, GetDisplayIfValid(dpyPacked), EGLBoolean,
+ dpyPacked, surfacePacked, rects, n_rects);
+
+ return SetDamageRegionKHR(thread, dpyPacked, surfacePacked, rects, n_rects);
+}
+
+// EGL_KHR_reusable_sync
+EGLBoolean EGLAPIENTRY EGL_SignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(SignalSyncKHR, "dpy = 0x%016" PRIxPTR ", sync = 0x%016" PRIxPTR ", mode = 0x%X",
+ (uintptr_t)dpy, (uintptr_t)sync, mode);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Sync *syncPacked = PackParam<Sync *>(sync);
+
+ ANGLE_EGL_VALIDATE(thread, SignalSyncKHR, GetDisplayIfValid(dpyPacked), EGLBoolean, dpyPacked,
+ syncPacked, mode);
+
+ return SignalSyncKHR(thread, dpyPacked, syncPacked, mode);
+}
+
+// ClientWaitSyncKHR is already defined.
+
+// CreateSyncKHR is already defined.
+
+// DestroySyncKHR is already defined.
+
+// GetSyncAttribKHR is already defined.
+
+// EGL_KHR_stream
+EGLStreamKHR EGLAPIENTRY EGL_CreateStreamKHR(EGLDisplay dpy, const EGLint *attrib_list)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(CreateStreamKHR, "dpy = 0x%016" PRIxPTR ", attrib_list = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, (uintptr_t)attrib_list);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ const AttributeMap &attrib_listPacked = PackParam<const AttributeMap &>(attrib_list);
+
+ ANGLE_EGL_VALIDATE(thread, CreateStreamKHR, GetDisplayIfValid(dpyPacked), EGLStreamKHR,
+ dpyPacked, attrib_listPacked);
+
+ return CreateStreamKHR(thread, dpyPacked, attrib_listPacked);
+}
+
+EGLBoolean EGLAPIENTRY EGL_DestroyStreamKHR(EGLDisplay dpy, EGLStreamKHR stream)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(DestroyStreamKHR, "dpy = 0x%016" PRIxPTR ", stream = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, (uintptr_t)stream);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Stream *streamPacked = PackParam<Stream *>(stream);
+
+ ANGLE_EGL_VALIDATE(thread, DestroyStreamKHR, GetDisplayIfValid(dpyPacked), EGLBoolean,
+ dpyPacked, streamPacked);
+
+ return DestroyStreamKHR(thread, dpyPacked, streamPacked);
+}
+
+EGLBoolean EGLAPIENTRY EGL_QueryStreamKHR(EGLDisplay dpy,
+ EGLStreamKHR stream,
+ EGLenum attribute,
+ EGLint *value)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(QueryStreamKHR,
+ "dpy = 0x%016" PRIxPTR ", stream = 0x%016" PRIxPTR
+ ", attribute = 0x%X, value = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, (uintptr_t)stream, attribute, (uintptr_t)value);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Stream *streamPacked = PackParam<Stream *>(stream);
+
+ ANGLE_EGL_VALIDATE(thread, QueryStreamKHR, GetDisplayIfValid(dpyPacked), EGLBoolean, dpyPacked,
+ streamPacked, attribute, value);
+
+ return QueryStreamKHR(thread, dpyPacked, streamPacked, attribute, value);
+}
+
+EGLBoolean EGLAPIENTRY EGL_QueryStreamu64KHR(EGLDisplay dpy,
+ EGLStreamKHR stream,
+ EGLenum attribute,
+ EGLuint64KHR *value)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(QueryStreamu64KHR,
+ "dpy = 0x%016" PRIxPTR ", stream = 0x%016" PRIxPTR
+ ", attribute = 0x%X, value = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, (uintptr_t)stream, attribute, (uintptr_t)value);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Stream *streamPacked = PackParam<Stream *>(stream);
+
+ ANGLE_EGL_VALIDATE(thread, QueryStreamu64KHR, GetDisplayIfValid(dpyPacked), EGLBoolean,
+ dpyPacked, streamPacked, attribute, value);
+
+ return QueryStreamu64KHR(thread, dpyPacked, streamPacked, attribute, value);
+}
+
+EGLBoolean EGLAPIENTRY EGL_StreamAttribKHR(EGLDisplay dpy,
+ EGLStreamKHR stream,
+ EGLenum attribute,
+ EGLint value)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(StreamAttribKHR,
+ "dpy = 0x%016" PRIxPTR ", stream = 0x%016" PRIxPTR ", attribute = 0x%X, value = %d",
+ (uintptr_t)dpy, (uintptr_t)stream, attribute, value);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Stream *streamPacked = PackParam<Stream *>(stream);
+
+ ANGLE_EGL_VALIDATE(thread, StreamAttribKHR, GetDisplayIfValid(dpyPacked), EGLBoolean, dpyPacked,
+ streamPacked, attribute, value);
+
+ return StreamAttribKHR(thread, dpyPacked, streamPacked, attribute, value);
+}
+
+// EGL_KHR_stream_consumer_gltexture
+EGLBoolean EGLAPIENTRY EGL_StreamConsumerAcquireKHR(EGLDisplay dpy, EGLStreamKHR stream)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(StreamConsumerAcquireKHR, "dpy = 0x%016" PRIxPTR ", stream = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, (uintptr_t)stream);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Stream *streamPacked = PackParam<Stream *>(stream);
+
+ ANGLE_EGL_VALIDATE(thread, StreamConsumerAcquireKHR, GetDisplayIfValid(dpyPacked), EGLBoolean,
+ dpyPacked, streamPacked);
+
+ return StreamConsumerAcquireKHR(thread, dpyPacked, streamPacked);
+}
+
+EGLBoolean EGLAPIENTRY EGL_StreamConsumerGLTextureExternalKHR(EGLDisplay dpy, EGLStreamKHR stream)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(StreamConsumerGLTextureExternalKHR,
+ "dpy = 0x%016" PRIxPTR ", stream = 0x%016" PRIxPTR "", (uintptr_t)dpy,
+ (uintptr_t)stream);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Stream *streamPacked = PackParam<Stream *>(stream);
+
+ ANGLE_EGL_VALIDATE(thread, StreamConsumerGLTextureExternalKHR, GetDisplayIfValid(dpyPacked),
+ EGLBoolean, dpyPacked, streamPacked);
+
+ return StreamConsumerGLTextureExternalKHR(thread, dpyPacked, streamPacked);
+}
+
+EGLBoolean EGLAPIENTRY EGL_StreamConsumerReleaseKHR(EGLDisplay dpy, EGLStreamKHR stream)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(StreamConsumerReleaseKHR, "dpy = 0x%016" PRIxPTR ", stream = 0x%016" PRIxPTR "",
+ (uintptr_t)dpy, (uintptr_t)stream);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Stream *streamPacked = PackParam<Stream *>(stream);
+
+ ANGLE_EGL_VALIDATE(thread, StreamConsumerReleaseKHR, GetDisplayIfValid(dpyPacked), EGLBoolean,
+ dpyPacked, streamPacked);
+
+ return StreamConsumerReleaseKHR(thread, dpyPacked, streamPacked);
+}
+
+// EGL_KHR_swap_buffers_with_damage
+EGLBoolean EGLAPIENTRY EGL_SwapBuffersWithDamageKHR(EGLDisplay dpy,
+ EGLSurface surface,
+ const EGLint *rects,
+ EGLint n_rects)
+{
+ ANGLE_EGLBOOLEAN_TRY(PrepareSwapBuffersANGLE(dpy, surface));
+ ANGLE_SCOPED_GLOBAL_SURFACE_LOCK();
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(SwapBuffersWithDamageKHR,
+ "dpy = 0x%016" PRIxPTR ", surface = 0x%016" PRIxPTR ", rects = 0x%016" PRIxPTR
+ ", n_rects = %d",
+ (uintptr_t)dpy, (uintptr_t)surface, (uintptr_t)rects, n_rects);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Surface *surfacePacked = PackParam<Surface *>(surface);
+
+ ANGLE_EGL_VALIDATE(thread, SwapBuffersWithDamageKHR, GetDisplayIfValid(dpyPacked), EGLBoolean,
+ dpyPacked, surfacePacked, rects, n_rects);
+
+ return SwapBuffersWithDamageKHR(thread, dpyPacked, surfacePacked, rects, n_rects);
+}
+
+// EGL_KHR_wait_sync
+EGLint EGLAPIENTRY EGL_WaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(WaitSyncKHR, "dpy = 0x%016" PRIxPTR ", sync = 0x%016" PRIxPTR ", flags = %d",
+ (uintptr_t)dpy, (uintptr_t)sync, flags);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Sync *syncPacked = PackParam<Sync *>(sync);
+
+ ANGLE_EGL_VALIDATE(thread, WaitSyncKHR, GetDisplayIfValid(dpyPacked), EGLint, dpyPacked,
+ syncPacked, flags);
+
+ return WaitSyncKHR(thread, dpyPacked, syncPacked, flags);
+}
+
+// EGL_NV_post_sub_buffer
+EGLBoolean EGLAPIENTRY EGL_PostSubBufferNV(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLint x,
+ EGLint y,
+ EGLint width,
+ EGLint height)
+{
+
+ ANGLE_SCOPED_GLOBAL_SURFACE_LOCK();
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(PostSubBufferNV,
+ "dpy = 0x%016" PRIxPTR ", surface = 0x%016" PRIxPTR
+ ", x = %d, y = %d, width = %d, height = %d",
+ (uintptr_t)dpy, (uintptr_t)surface, x, y, width, height);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Surface *surfacePacked = PackParam<Surface *>(surface);
+
+ ANGLE_EGL_VALIDATE(thread, PostSubBufferNV, GetDisplayIfValid(dpyPacked), EGLBoolean, dpyPacked,
+ surfacePacked, x, y, width, height);
+
+ return PostSubBufferNV(thread, dpyPacked, surfacePacked, x, y, width, height);
+}
+
+// EGL_NV_stream_consumer_gltexture_yuv
+EGLBoolean EGLAPIENTRY EGL_StreamConsumerGLTextureExternalAttribsNV(EGLDisplay dpy,
+ EGLStreamKHR stream,
+ const EGLAttrib *attrib_list)
+{
+
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EGL_EVENT(StreamConsumerGLTextureExternalAttribsNV,
+ "dpy = 0x%016" PRIxPTR ", stream = 0x%016" PRIxPTR ", attrib_list = 0x%016" PRIxPTR
+ "",
+ (uintptr_t)dpy, (uintptr_t)stream, (uintptr_t)attrib_list);
+
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *dpyPacked = PackParam<egl::Display *>(dpy);
+ Stream *streamPacked = PackParam<Stream *>(stream);
+ const AttributeMap &attrib_listPacked = PackParam<const AttributeMap &>(attrib_list);
+
+ ANGLE_EGL_VALIDATE(thread, StreamConsumerGLTextureExternalAttribsNV,
+ GetDisplayIfValid(dpyPacked), EGLBoolean, dpyPacked, streamPacked,
+ attrib_listPacked);
+
+ return StreamConsumerGLTextureExternalAttribsNV(thread, dpyPacked, streamPacked,
+ attrib_listPacked);
+}
+
+} // extern "C"
diff --git a/gfx/angle/checkout/src/libGLESv2/entry_points_egl_ext_autogen.h b/gfx/angle/checkout/src/libGLESv2/entry_points_egl_ext_autogen.h
new file mode 100644
index 0000000000..b109973534
--- /dev/null
+++ b/gfx/angle/checkout/src/libGLESv2/entry_points_egl_ext_autogen.h
@@ -0,0 +1,284 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from egl.xml and egl_angle_ext.xml.
+//
+// Copyright 2020 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_egl_ext_autogen.h:
+// Defines the EGL Extension entry points.
+
+#ifndef LIBGLESV2_ENTRY_POINTS_EGL_EXT_AUTOGEN_H_
+#define LIBGLESV2_ENTRY_POINTS_EGL_EXT_AUTOGEN_H_
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <export.h>
+
+extern "C" {
+
+// EGL_ANDROID_blob_cache
+ANGLE_EXPORT void EGLAPIENTRY EGL_SetBlobCacheFuncsANDROID(EGLDisplay dpy,
+ EGLSetBlobFuncANDROID set,
+ EGLGetBlobFuncANDROID get);
+
+// EGL_ANDROID_create_native_client_buffer
+ANGLE_EXPORT EGLClientBuffer EGLAPIENTRY
+EGL_CreateNativeClientBufferANDROID(const EGLint *attrib_list);
+
+// EGL_ANDROID_get_frame_timestamps
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_GetCompositorTimingSupportedANDROID(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLint name);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_GetCompositorTimingANDROID(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLint numTimestamps,
+ const EGLint *names,
+ EGLnsecsANDROID *values);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_GetNextFrameIdANDROID(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLuint64KHR *frameId);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_GetFrameTimestampSupportedANDROID(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLint timestamp);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_GetFrameTimestampsANDROID(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLuint64KHR frameId,
+ EGLint numTimestamps,
+ const EGLint *timestamps,
+ EGLnsecsANDROID *values);
+
+// EGL_ANDROID_get_native_client_buffer
+ANGLE_EXPORT EGLClientBuffer EGLAPIENTRY
+EGL_GetNativeClientBufferANDROID(const struct AHardwareBuffer *buffer);
+
+// EGL_ANDROID_native_fence_sync
+ANGLE_EXPORT EGLint EGLAPIENTRY EGL_DupNativeFenceFDANDROID(EGLDisplay dpy, EGLSyncKHR sync);
+
+// EGL_ANDROID_presentation_time
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_PresentationTimeANDROID(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLnsecsANDROID time);
+
+// EGL_ANGLE_device_creation
+ANGLE_EXPORT EGLDeviceEXT EGLAPIENTRY EGL_CreateDeviceANGLE(EGLint device_type,
+ void *native_device,
+ const EGLAttrib *attrib_list);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_ReleaseDeviceANGLE(EGLDeviceEXT device);
+
+// EGL_ANGLE_feature_control
+ANGLE_EXPORT const char *EGLAPIENTRY EGL_QueryStringiANGLE(EGLDisplay dpy,
+ EGLint name,
+ EGLint index);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_QueryDisplayAttribANGLE(EGLDisplay dpy,
+ EGLint attribute,
+ EGLAttrib *value);
+
+// EGL_ANGLE_metal_shared_event_sync
+ANGLE_EXPORT void *EGLAPIENTRY EGL_CopyMetalSharedEventANGLE(EGLDisplay dpy, EGLSyncKHR sync);
+
+// EGL_ANGLE_power_preference
+ANGLE_EXPORT void EGLAPIENTRY EGL_ReleaseHighPowerGPUANGLE(EGLDisplay dpy, EGLContext ctx);
+ANGLE_EXPORT void EGLAPIENTRY EGL_ReacquireHighPowerGPUANGLE(EGLDisplay dpy, EGLContext ctx);
+ANGLE_EXPORT void EGLAPIENTRY EGL_HandleGPUSwitchANGLE(EGLDisplay dpy);
+ANGLE_EXPORT void EGLAPIENTRY EGL_ForceGPUSwitchANGLE(EGLDisplay dpy,
+ EGLint gpuIDHigh,
+ EGLint gpuIDLow);
+
+// EGL_ANGLE_prepare_swap_buffers
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_PrepareSwapBuffersANGLE(EGLDisplay dpy, EGLSurface surface);
+
+// EGL_ANGLE_program_cache_control
+ANGLE_EXPORT EGLint EGLAPIENTRY EGL_ProgramCacheGetAttribANGLE(EGLDisplay dpy, EGLenum attrib);
+ANGLE_EXPORT void EGLAPIENTRY EGL_ProgramCacheQueryANGLE(EGLDisplay dpy,
+ EGLint index,
+ void *key,
+ EGLint *keysize,
+ void *binary,
+ EGLint *binarysize);
+ANGLE_EXPORT void EGLAPIENTRY EGL_ProgramCachePopulateANGLE(EGLDisplay dpy,
+ const void *key,
+ EGLint keysize,
+ const void *binary,
+ EGLint binarysize);
+ANGLE_EXPORT EGLint EGLAPIENTRY EGL_ProgramCacheResizeANGLE(EGLDisplay dpy,
+ EGLint limit,
+ EGLint mode);
+
+// EGL_ANGLE_query_surface_pointer
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_QuerySurfacePointerANGLE(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLint attribute,
+ void **value);
+
+// EGL_ANGLE_stream_producer_d3d_texture
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY
+EGL_CreateStreamProducerD3DTextureANGLE(EGLDisplay dpy,
+ EGLStreamKHR stream,
+ const EGLAttrib *attrib_list);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_StreamPostD3DTextureANGLE(EGLDisplay dpy,
+ EGLStreamKHR stream,
+ void *texture,
+ const EGLAttrib *attrib_list);
+
+// EGL_ANGLE_swap_with_frame_token
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY
+EGL_SwapBuffersWithFrameTokenANGLE(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLFrameTokenANGLE frametoken);
+
+// EGL_ANGLE_sync_control_rate
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_GetMscRateANGLE(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLint *numerator,
+ EGLint *denominator);
+
+// EGL_ANGLE_vulkan_image
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_ExportVkImageANGLE(EGLDisplay dpy,
+ EGLImage image,
+ void *vk_image,
+ void *vk_image_create_info);
+
+// EGL_CHROMIUM_sync_control
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_GetSyncValuesCHROMIUM(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLuint64KHR *ust,
+ EGLuint64KHR *msc,
+ EGLuint64KHR *sbc);
+
+// EGL_EXT_device_query
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_QueryDeviceAttribEXT(EGLDeviceEXT device,
+ EGLint attribute,
+ EGLAttrib *value);
+ANGLE_EXPORT const char *EGLAPIENTRY EGL_QueryDeviceStringEXT(EGLDeviceEXT device, EGLint name);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_QueryDisplayAttribEXT(EGLDisplay dpy,
+ EGLint attribute,
+ EGLAttrib *value);
+
+// EGL_EXT_image_dma_buf_import_modifiers
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_QueryDmaBufFormatsEXT(EGLDisplay dpy,
+ EGLint max_formats,
+ EGLint *formats,
+ EGLint *num_formats);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_QueryDmaBufModifiersEXT(EGLDisplay dpy,
+ EGLint format,
+ EGLint max_modifiers,
+ EGLuint64KHR *modifiers,
+ EGLBoolean *external_only,
+ EGLint *num_modifiers);
+
+// EGL_EXT_platform_base
+ANGLE_EXPORT EGLSurface EGLAPIENTRY EGL_CreatePlatformPixmapSurfaceEXT(EGLDisplay dpy,
+ EGLConfig config,
+ void *native_pixmap,
+ const EGLint *attrib_list);
+ANGLE_EXPORT EGLSurface EGLAPIENTRY EGL_CreatePlatformWindowSurfaceEXT(EGLDisplay dpy,
+ EGLConfig config,
+ void *native_window,
+ const EGLint *attrib_list);
+ANGLE_EXPORT EGLDisplay EGLAPIENTRY EGL_GetPlatformDisplayEXT(EGLenum platform,
+ void *native_display,
+ const EGLint *attrib_list);
+
+// EGL_KHR_debug
+ANGLE_EXPORT EGLint EGLAPIENTRY EGL_DebugMessageControlKHR(EGLDEBUGPROCKHR callback,
+ const EGLAttrib *attrib_list);
+ANGLE_EXPORT EGLint EGLAPIENTRY EGL_LabelObjectKHR(EGLDisplay display,
+ EGLenum objectType,
+ EGLObjectKHR object,
+ EGLLabelKHR label);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_QueryDebugKHR(EGLint attribute, EGLAttrib *value);
+
+// EGL_KHR_fence_sync
+ANGLE_EXPORT EGLint EGLAPIENTRY EGL_ClientWaitSyncKHR(EGLDisplay dpy,
+ EGLSyncKHR sync,
+ EGLint flags,
+ EGLTimeKHR timeout);
+ANGLE_EXPORT EGLSyncKHR EGLAPIENTRY EGL_CreateSyncKHR(EGLDisplay dpy,
+ EGLenum type,
+ const EGLint *attrib_list);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_DestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_GetSyncAttribKHR(EGLDisplay dpy,
+ EGLSyncKHR sync,
+ EGLint attribute,
+ EGLint *value);
+
+// EGL_KHR_image
+ANGLE_EXPORT EGLImageKHR EGLAPIENTRY EGL_CreateImageKHR(EGLDisplay dpy,
+ EGLContext ctx,
+ EGLenum target,
+ EGLClientBuffer buffer,
+ const EGLint *attrib_list);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_DestroyImageKHR(EGLDisplay dpy, EGLImageKHR image);
+
+// EGL_KHR_lock_surface3
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_LockSurfaceKHR(EGLDisplay dpy,
+ EGLSurface surface,
+ const EGLint *attrib_list);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_QuerySurface64KHR(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLint attribute,
+ EGLAttribKHR *value);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_UnlockSurfaceKHR(EGLDisplay dpy, EGLSurface surface);
+
+// EGL_KHR_partial_update
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_SetDamageRegionKHR(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLint *rects,
+ EGLint n_rects);
+
+// EGL_KHR_reusable_sync
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_SignalSyncKHR(EGLDisplay dpy,
+ EGLSyncKHR sync,
+ EGLenum mode);
+
+// EGL_KHR_stream
+ANGLE_EXPORT EGLStreamKHR EGLAPIENTRY EGL_CreateStreamKHR(EGLDisplay dpy,
+ const EGLint *attrib_list);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_DestroyStreamKHR(EGLDisplay dpy, EGLStreamKHR stream);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_QueryStreamKHR(EGLDisplay dpy,
+ EGLStreamKHR stream,
+ EGLenum attribute,
+ EGLint *value);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_QueryStreamu64KHR(EGLDisplay dpy,
+ EGLStreamKHR stream,
+ EGLenum attribute,
+ EGLuint64KHR *value);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_StreamAttribKHR(EGLDisplay dpy,
+ EGLStreamKHR stream,
+ EGLenum attribute,
+ EGLint value);
+
+// EGL_KHR_stream_consumer_gltexture
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_StreamConsumerAcquireKHR(EGLDisplay dpy,
+ EGLStreamKHR stream);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_StreamConsumerGLTextureExternalKHR(EGLDisplay dpy,
+ EGLStreamKHR stream);
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_StreamConsumerReleaseKHR(EGLDisplay dpy,
+ EGLStreamKHR stream);
+
+// EGL_KHR_swap_buffers_with_damage
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_SwapBuffersWithDamageKHR(EGLDisplay dpy,
+ EGLSurface surface,
+ const EGLint *rects,
+ EGLint n_rects);
+
+// EGL_KHR_wait_sync
+ANGLE_EXPORT EGLint EGLAPIENTRY EGL_WaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags);
+
+// EGL_NV_post_sub_buffer
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY EGL_PostSubBufferNV(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLint x,
+ EGLint y,
+ EGLint width,
+ EGLint height);
+
+// EGL_NV_stream_consumer_gltexture_yuv
+ANGLE_EXPORT EGLBoolean EGLAPIENTRY
+EGL_StreamConsumerGLTextureExternalAttribsNV(EGLDisplay dpy,
+ EGLStreamKHR stream,
+ const EGLAttrib *attrib_list);
+} // extern "C"
+
+#endif // LIBGLESV2_ENTRY_POINTS_EGL_EXT_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libGLESv2/entry_points_gles_1_0_autogen.cpp b/gfx/angle/checkout/src/libGLESv2/entry_points_gles_1_0_autogen.cpp
new file mode 100644
index 0000000000..243d630881
--- /dev/null
+++ b/gfx/angle/checkout/src/libGLESv2/entry_points_gles_1_0_autogen.cpp
@@ -0,0 +1,2116 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml.
+//
+// Copyright 2020 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_1_0_autogen.cpp:
+// Defines the GLES 1.0 entry points.
+
+#include "libGLESv2/entry_points_gles_1_0_autogen.h"
+
+#include "common/entry_points_enum_autogen.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Context.inl.h"
+#include "libANGLE/capture/capture_gles_1_0_autogen.h"
+#include "libANGLE/capture/gl_enum_utils.h"
+#include "libANGLE/entry_points_utils.h"
+#include "libANGLE/validationES1.h"
+#include "libGLESv2/global_state.h"
+
+using namespace gl;
+
+extern "C" {
+void GL_APIENTRY GL_AlphaFunc(GLenum func, GLfloat ref)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLAlphaFunc, "context = %d, func = %s, ref = %f", CID(context),
+ GLenumToString(GLESEnum::AlphaFunction, func), ref);
+
+ if (context)
+ {
+ AlphaTestFunc funcPacked = PackParam<AlphaTestFunc>(func);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateAlphaFunc(context, angle::EntryPoint::GLAlphaFunc, funcPacked, ref));
+ if (isCallValid)
+ {
+ context->alphaFunc(funcPacked, ref);
+ }
+ ANGLE_CAPTURE_GL(AlphaFunc, isCallValid, context, funcPacked, ref);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_AlphaFuncx(GLenum func, GLfixed ref)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLAlphaFuncx, "context = %d, func = %s, ref = 0x%X", CID(context),
+ GLenumToString(GLESEnum::AlphaFunction, func), ref);
+
+ if (context)
+ {
+ AlphaTestFunc funcPacked = PackParam<AlphaTestFunc>(func);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateAlphaFuncx(context, angle::EntryPoint::GLAlphaFuncx, funcPacked, ref));
+ if (isCallValid)
+ {
+ context->alphaFuncx(funcPacked, ref);
+ }
+ ANGLE_CAPTURE_GL(AlphaFuncx, isCallValid, context, funcPacked, ref);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ClearColorx(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLClearColorx,
+ "context = %d, red = 0x%X, green = 0x%X, blue = 0x%X, alpha = 0x%X", CID(context), red,
+ green, blue, alpha);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateClearColorx(context, angle::EntryPoint::GLClearColorx, red,
+ green, blue, alpha));
+ if (isCallValid)
+ {
+ context->clearColorx(red, green, blue, alpha);
+ }
+ ANGLE_CAPTURE_GL(ClearColorx, isCallValid, context, red, green, blue, alpha);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ClearDepthx(GLfixed depth)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLClearDepthx, "context = %d, depth = 0x%X", CID(context), depth);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateClearDepthx(context, angle::EntryPoint::GLClearDepthx, depth));
+ if (isCallValid)
+ {
+ context->clearDepthx(depth);
+ }
+ ANGLE_CAPTURE_GL(ClearDepthx, isCallValid, context, depth);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ClientActiveTexture(GLenum texture)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLClientActiveTexture, "context = %d, texture = %s", CID(context),
+ GLenumToString(GLESEnum::TextureUnit, texture));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateClientActiveTexture(
+ context, angle::EntryPoint::GLClientActiveTexture, texture));
+ if (isCallValid)
+ {
+ context->clientActiveTexture(texture);
+ }
+ ANGLE_CAPTURE_GL(ClientActiveTexture, isCallValid, context, texture);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ClipPlanef(GLenum p, const GLfloat *eqn)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLClipPlanef, "context = %d, p = %s, eqn = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::ClipPlaneName, p), (uintptr_t)eqn);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateClipPlanef(context, angle::EntryPoint::GLClipPlanef, p, eqn));
+ if (isCallValid)
+ {
+ context->clipPlanef(p, eqn);
+ }
+ ANGLE_CAPTURE_GL(ClipPlanef, isCallValid, context, p, eqn);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ClipPlanex(GLenum plane, const GLfixed *equation)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLClipPlanex, "context = %d, plane = %s, equation = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::ClipPlaneName, plane), (uintptr_t)equation);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateClipPlanex(context, angle::EntryPoint::GLClipPlanex, plane, equation));
+ if (isCallValid)
+ {
+ context->clipPlanex(plane, equation);
+ }
+ ANGLE_CAPTURE_GL(ClipPlanex, isCallValid, context, plane, equation);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Color4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLColor4f, "context = %d, red = %f, green = %f, blue = %f, alpha = %f",
+ CID(context), red, green, blue, alpha);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateColor4f(context, angle::EntryPoint::GLColor4f, red, green, blue, alpha));
+ if (isCallValid)
+ {
+ context->color4f(red, green, blue, alpha);
+ }
+ ANGLE_CAPTURE_GL(Color4f, isCallValid, context, red, green, blue, alpha);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Color4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLColor4ub, "context = %d, red = %d, green = %d, blue = %d, alpha = %d",
+ CID(context), red, green, blue, alpha);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateColor4ub(context, angle::EntryPoint::GLColor4ub, red, green, blue, alpha));
+ if (isCallValid)
+ {
+ context->color4ub(red, green, blue, alpha);
+ }
+ ANGLE_CAPTURE_GL(Color4ub, isCallValid, context, red, green, blue, alpha);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Color4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLColor4x, "context = %d, red = 0x%X, green = 0x%X, blue = 0x%X, alpha = 0x%X",
+ CID(context), red, green, blue, alpha);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateColor4x(context, angle::EntryPoint::GLColor4x, red, green, blue, alpha));
+ if (isCallValid)
+ {
+ context->color4x(red, green, blue, alpha);
+ }
+ ANGLE_CAPTURE_GL(Color4x, isCallValid, context, red, green, blue, alpha);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ColorPointer(GLint size, GLenum type, GLsizei stride, const void *pointer)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLColorPointer,
+ "context = %d, size = %d, type = %s, stride = %d, pointer = 0x%016" PRIxPTR "",
+ CID(context), size, GLenumToString(GLESEnum::ColorPointerType, type), stride,
+ (uintptr_t)pointer);
+
+ if (context)
+ {
+ VertexAttribType typePacked = PackParam<VertexAttribType>(type);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateColorPointer(context, angle::EntryPoint::GLColorPointer, size,
+ typePacked, stride, pointer));
+ if (isCallValid)
+ {
+ context->colorPointer(size, typePacked, stride, pointer);
+ }
+ ANGLE_CAPTURE_GL(ColorPointer, isCallValid, context, size, typePacked, stride, pointer);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DepthRangex(GLfixed n, GLfixed f)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDepthRangex, "context = %d, n = 0x%X, f = 0x%X", CID(context), n, f);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateDepthRangex(context, angle::EntryPoint::GLDepthRangex, n, f));
+ if (isCallValid)
+ {
+ context->depthRangex(n, f);
+ }
+ ANGLE_CAPTURE_GL(DepthRangex, isCallValid, context, n, f);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DisableClientState(GLenum array)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDisableClientState, "context = %d, array = %s", CID(context),
+ GLenumToString(GLESEnum::EnableCap, array));
+
+ if (context)
+ {
+ ClientVertexArrayType arrayPacked = PackParam<ClientVertexArrayType>(array);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateDisableClientState(
+ context, angle::EntryPoint::GLDisableClientState, arrayPacked));
+ if (isCallValid)
+ {
+ context->disableClientState(arrayPacked);
+ }
+ ANGLE_CAPTURE_GL(DisableClientState, isCallValid, context, arrayPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_EnableClientState(GLenum array)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLEnableClientState, "context = %d, array = %s", CID(context),
+ GLenumToString(GLESEnum::EnableCap, array));
+
+ if (context)
+ {
+ ClientVertexArrayType arrayPacked = PackParam<ClientVertexArrayType>(array);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateEnableClientState(
+ context, angle::EntryPoint::GLEnableClientState, arrayPacked));
+ if (isCallValid)
+ {
+ context->enableClientState(arrayPacked);
+ }
+ ANGLE_CAPTURE_GL(EnableClientState, isCallValid, context, arrayPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Fogf(GLenum pname, GLfloat param)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLFogf, "context = %d, pname = %s, param = %f", CID(context),
+ GLenumToString(GLESEnum::FogParameter, pname), param);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateFogf(context, angle::EntryPoint::GLFogf, pname, param));
+ if (isCallValid)
+ {
+ context->fogf(pname, param);
+ }
+ ANGLE_CAPTURE_GL(Fogf, isCallValid, context, pname, param);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Fogfv(GLenum pname, const GLfloat *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLFogfv, "context = %d, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::FogParameter, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateFogfv(context, angle::EntryPoint::GLFogfv, pname, params));
+ if (isCallValid)
+ {
+ context->fogfv(pname, params);
+ }
+ ANGLE_CAPTURE_GL(Fogfv, isCallValid, context, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Fogx(GLenum pname, GLfixed param)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLFogx, "context = %d, pname = %s, param = 0x%X", CID(context),
+ GLenumToString(GLESEnum::FogPName, pname), param);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateFogx(context, angle::EntryPoint::GLFogx, pname, param));
+ if (isCallValid)
+ {
+ context->fogx(pname, param);
+ }
+ ANGLE_CAPTURE_GL(Fogx, isCallValid, context, pname, param);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Fogxv(GLenum pname, const GLfixed *param)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLFogxv, "context = %d, pname = %s, param = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::FogPName, pname), (uintptr_t)param);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateFogxv(context, angle::EntryPoint::GLFogxv, pname, param));
+ if (isCallValid)
+ {
+ context->fogxv(pname, param);
+ }
+ ANGLE_CAPTURE_GL(Fogxv, isCallValid, context, pname, param);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Frustumf(GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLFrustumf, "context = %d, l = %f, r = %f, b = %f, t = %f, n = %f, f = %f",
+ CID(context), l, r, b, t, n, f);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateFrustumf(context, angle::EntryPoint::GLFrustumf, l, r, b, t, n, f));
+ if (isCallValid)
+ {
+ context->frustumf(l, r, b, t, n, f);
+ }
+ ANGLE_CAPTURE_GL(Frustumf, isCallValid, context, l, r, b, t, n, f);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Frustumx(GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLFrustumx,
+ "context = %d, l = 0x%X, r = 0x%X, b = 0x%X, t = 0x%X, n = 0x%X, f = 0x%X", CID(context),
+ l, r, b, t, n, f);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateFrustumx(context, angle::EntryPoint::GLFrustumx, l, r, b, t, n, f));
+ if (isCallValid)
+ {
+ context->frustumx(l, r, b, t, n, f);
+ }
+ ANGLE_CAPTURE_GL(Frustumx, isCallValid, context, l, r, b, t, n, f);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetClipPlanef(GLenum plane, GLfloat *equation)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetClipPlanef, "context = %d, plane = %s, equation = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::ClipPlaneName, plane), (uintptr_t)equation);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetClipPlanef(context, angle::EntryPoint::GLGetClipPlanef, plane, equation));
+ if (isCallValid)
+ {
+ context->getClipPlanef(plane, equation);
+ }
+ ANGLE_CAPTURE_GL(GetClipPlanef, isCallValid, context, plane, equation);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetClipPlanex(GLenum plane, GLfixed *equation)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetClipPlanex, "context = %d, plane = %s, equation = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::ClipPlaneName, plane), (uintptr_t)equation);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetClipPlanex(context, angle::EntryPoint::GLGetClipPlanex, plane, equation));
+ if (isCallValid)
+ {
+ context->getClipPlanex(plane, equation);
+ }
+ ANGLE_CAPTURE_GL(GetClipPlanex, isCallValid, context, plane, equation);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetFixedv(GLenum pname, GLfixed *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetFixedv, "context = %d, pname = %s, params = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::GetPName, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetFixedv(context, angle::EntryPoint::GLGetFixedv, pname, params));
+ if (isCallValid)
+ {
+ context->getFixedv(pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetFixedv, isCallValid, context, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetLightfv(GLenum light, GLenum pname, GLfloat *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetLightfv, "context = %d, light = %s, pname = %s, params = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::LightName, light),
+ GLenumToString(GLESEnum::LightParameter, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ LightParameter pnamePacked = PackParam<LightParameter>(pname);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetLightfv(context, angle::EntryPoint::GLGetLightfv, light,
+ pnamePacked, params));
+ if (isCallValid)
+ {
+ context->getLightfv(light, pnamePacked, params);
+ }
+ ANGLE_CAPTURE_GL(GetLightfv, isCallValid, context, light, pnamePacked, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetLightxv(GLenum light, GLenum pname, GLfixed *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetLightxv, "context = %d, light = %s, pname = %s, params = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::LightName, light),
+ GLenumToString(GLESEnum::LightParameter, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ LightParameter pnamePacked = PackParam<LightParameter>(pname);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetLightxv(context, angle::EntryPoint::GLGetLightxv, light,
+ pnamePacked, params));
+ if (isCallValid)
+ {
+ context->getLightxv(light, pnamePacked, params);
+ }
+ ANGLE_CAPTURE_GL(GetLightxv, isCallValid, context, light, pnamePacked, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetMaterialfv(GLenum face, GLenum pname, GLfloat *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetMaterialfv,
+ "context = %d, face = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::TriangleFace, face),
+ GLenumToString(GLESEnum::MaterialParameter, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ MaterialParameter pnamePacked = PackParam<MaterialParameter>(pname);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetMaterialfv(context, angle::EntryPoint::GLGetMaterialfv, face,
+ pnamePacked, params));
+ if (isCallValid)
+ {
+ context->getMaterialfv(face, pnamePacked, params);
+ }
+ ANGLE_CAPTURE_GL(GetMaterialfv, isCallValid, context, face, pnamePacked, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetMaterialxv(GLenum face, GLenum pname, GLfixed *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetMaterialxv,
+ "context = %d, face = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::TriangleFace, face),
+ GLenumToString(GLESEnum::MaterialParameter, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ MaterialParameter pnamePacked = PackParam<MaterialParameter>(pname);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetMaterialxv(context, angle::EntryPoint::GLGetMaterialxv, face,
+ pnamePacked, params));
+ if (isCallValid)
+ {
+ context->getMaterialxv(face, pnamePacked, params);
+ }
+ ANGLE_CAPTURE_GL(GetMaterialxv, isCallValid, context, face, pnamePacked, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetTexEnvfv(GLenum target, GLenum pname, GLfloat *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetTexEnvfv,
+ "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::TextureEnvTarget, target),
+ GLenumToString(GLESEnum::TextureEnvParameter, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ TextureEnvTarget targetPacked = PackParam<TextureEnvTarget>(target);
+ TextureEnvParameter pnamePacked = PackParam<TextureEnvParameter>(pname);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetTexEnvfv(context, angle::EntryPoint::GLGetTexEnvfv,
+ targetPacked, pnamePacked, params));
+ if (isCallValid)
+ {
+ context->getTexEnvfv(targetPacked, pnamePacked, params);
+ }
+ ANGLE_CAPTURE_GL(GetTexEnvfv, isCallValid, context, targetPacked, pnamePacked, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetTexEnviv(GLenum target, GLenum pname, GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetTexEnviv,
+ "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::TextureEnvTarget, target),
+ GLenumToString(GLESEnum::TextureEnvParameter, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ TextureEnvTarget targetPacked = PackParam<TextureEnvTarget>(target);
+ TextureEnvParameter pnamePacked = PackParam<TextureEnvParameter>(pname);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetTexEnviv(context, angle::EntryPoint::GLGetTexEnviv,
+ targetPacked, pnamePacked, params));
+ if (isCallValid)
+ {
+ context->getTexEnviv(targetPacked, pnamePacked, params);
+ }
+ ANGLE_CAPTURE_GL(GetTexEnviv, isCallValid, context, targetPacked, pnamePacked, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetTexEnvxv(GLenum target, GLenum pname, GLfixed *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetTexEnvxv,
+ "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::TextureEnvTarget, target),
+ GLenumToString(GLESEnum::TextureEnvParameter, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ TextureEnvTarget targetPacked = PackParam<TextureEnvTarget>(target);
+ TextureEnvParameter pnamePacked = PackParam<TextureEnvParameter>(pname);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetTexEnvxv(context, angle::EntryPoint::GLGetTexEnvxv,
+ targetPacked, pnamePacked, params));
+ if (isCallValid)
+ {
+ context->getTexEnvxv(targetPacked, pnamePacked, params);
+ }
+ ANGLE_CAPTURE_GL(GetTexEnvxv, isCallValid, context, targetPacked, pnamePacked, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetTexParameterxv(GLenum target, GLenum pname, GLfixed *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetTexParameterxv,
+ "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::TextureTarget, target),
+ GLenumToString(GLESEnum::GetTextureParameter, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetTexParameterxv(context, angle::EntryPoint::GLGetTexParameterxv,
+ targetPacked, pname, params));
+ if (isCallValid)
+ {
+ context->getTexParameterxv(targetPacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetTexParameterxv, isCallValid, context, targetPacked, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_LightModelf(GLenum pname, GLfloat param)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLLightModelf, "context = %d, pname = %s, param = %f", CID(context),
+ GLenumToString(GLESEnum::LightModelParameter, pname), param);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateLightModelf(context, angle::EntryPoint::GLLightModelf, pname, param));
+ if (isCallValid)
+ {
+ context->lightModelf(pname, param);
+ }
+ ANGLE_CAPTURE_GL(LightModelf, isCallValid, context, pname, param);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_LightModelfv(GLenum pname, const GLfloat *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLLightModelfv, "context = %d, pname = %s, params = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::LightModelParameter, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateLightModelfv(context, angle::EntryPoint::GLLightModelfv, pname, params));
+ if (isCallValid)
+ {
+ context->lightModelfv(pname, params);
+ }
+ ANGLE_CAPTURE_GL(LightModelfv, isCallValid, context, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_LightModelx(GLenum pname, GLfixed param)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLLightModelx, "context = %d, pname = %s, param = 0x%X", CID(context),
+ GLenumToString(GLESEnum::LightModelParameter, pname), param);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateLightModelx(context, angle::EntryPoint::GLLightModelx, pname, param));
+ if (isCallValid)
+ {
+ context->lightModelx(pname, param);
+ }
+ ANGLE_CAPTURE_GL(LightModelx, isCallValid, context, pname, param);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_LightModelxv(GLenum pname, const GLfixed *param)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLLightModelxv, "context = %d, pname = %s, param = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::LightModelParameter, pname), (uintptr_t)param);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateLightModelxv(context, angle::EntryPoint::GLLightModelxv, pname, param));
+ if (isCallValid)
+ {
+ context->lightModelxv(pname, param);
+ }
+ ANGLE_CAPTURE_GL(LightModelxv, isCallValid, context, pname, param);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Lightf(GLenum light, GLenum pname, GLfloat param)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLLightf, "context = %d, light = %s, pname = %s, param = %f", CID(context),
+ GLenumToString(GLESEnum::LightName, light),
+ GLenumToString(GLESEnum::LightParameter, pname), param);
+
+ if (context)
+ {
+ LightParameter pnamePacked = PackParam<LightParameter>(pname);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateLightf(context, angle::EntryPoint::GLLightf, light, pnamePacked, param));
+ if (isCallValid)
+ {
+ context->lightf(light, pnamePacked, param);
+ }
+ ANGLE_CAPTURE_GL(Lightf, isCallValid, context, light, pnamePacked, param);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Lightfv(GLenum light, GLenum pname, const GLfloat *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLLightfv, "context = %d, light = %s, pname = %s, params = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::LightName, light),
+ GLenumToString(GLESEnum::LightParameter, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ LightParameter pnamePacked = PackParam<LightParameter>(pname);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateLightfv(context, angle::EntryPoint::GLLightfv, light, pnamePacked, params));
+ if (isCallValid)
+ {
+ context->lightfv(light, pnamePacked, params);
+ }
+ ANGLE_CAPTURE_GL(Lightfv, isCallValid, context, light, pnamePacked, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Lightx(GLenum light, GLenum pname, GLfixed param)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLLightx, "context = %d, light = %s, pname = %s, param = 0x%X", CID(context),
+ GLenumToString(GLESEnum::LightName, light),
+ GLenumToString(GLESEnum::LightParameter, pname), param);
+
+ if (context)
+ {
+ LightParameter pnamePacked = PackParam<LightParameter>(pname);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateLightx(context, angle::EntryPoint::GLLightx, light, pnamePacked, param));
+ if (isCallValid)
+ {
+ context->lightx(light, pnamePacked, param);
+ }
+ ANGLE_CAPTURE_GL(Lightx, isCallValid, context, light, pnamePacked, param);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Lightxv(GLenum light, GLenum pname, const GLfixed *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLLightxv, "context = %d, light = %s, pname = %s, params = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::LightName, light),
+ GLenumToString(GLESEnum::LightParameter, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ LightParameter pnamePacked = PackParam<LightParameter>(pname);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateLightxv(context, angle::EntryPoint::GLLightxv, light, pnamePacked, params));
+ if (isCallValid)
+ {
+ context->lightxv(light, pnamePacked, params);
+ }
+ ANGLE_CAPTURE_GL(Lightxv, isCallValid, context, light, pnamePacked, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_LineWidthx(GLfixed width)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLLineWidthx, "context = %d, width = 0x%X", CID(context), width);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateLineWidthx(context, angle::EntryPoint::GLLineWidthx, width));
+ if (isCallValid)
+ {
+ context->lineWidthx(width);
+ }
+ ANGLE_CAPTURE_GL(LineWidthx, isCallValid, context, width);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_LoadIdentity()
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLLoadIdentity, "context = %d", CID(context));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateLoadIdentity(context, angle::EntryPoint::GLLoadIdentity));
+ if (isCallValid)
+ {
+ context->loadIdentity();
+ }
+ ANGLE_CAPTURE_GL(LoadIdentity, isCallValid, context);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_LoadMatrixf(const GLfloat *m)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLLoadMatrixf, "context = %d, m = 0x%016" PRIxPTR "", CID(context),
+ (uintptr_t)m);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateLoadMatrixf(context, angle::EntryPoint::GLLoadMatrixf, m));
+ if (isCallValid)
+ {
+ context->loadMatrixf(m);
+ }
+ ANGLE_CAPTURE_GL(LoadMatrixf, isCallValid, context, m);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_LoadMatrixx(const GLfixed *m)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLLoadMatrixx, "context = %d, m = 0x%016" PRIxPTR "", CID(context),
+ (uintptr_t)m);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateLoadMatrixx(context, angle::EntryPoint::GLLoadMatrixx, m));
+ if (isCallValid)
+ {
+ context->loadMatrixx(m);
+ }
+ ANGLE_CAPTURE_GL(LoadMatrixx, isCallValid, context, m);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_LogicOp(GLenum opcode)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLLogicOp, "context = %d, opcode = %s", CID(context),
+ GLenumToString(GLESEnum::LogicOp, opcode));
+
+ if (context)
+ {
+ LogicalOperation opcodePacked = PackParam<LogicalOperation>(opcode);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateLogicOp(context, angle::EntryPoint::GLLogicOp, opcodePacked));
+ if (isCallValid)
+ {
+ context->logicOp(opcodePacked);
+ }
+ ANGLE_CAPTURE_GL(LogicOp, isCallValid, context, opcodePacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Materialf(GLenum face, GLenum pname, GLfloat param)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLMaterialf, "context = %d, face = %s, pname = %s, param = %f", CID(context),
+ GLenumToString(GLESEnum::TriangleFace, face),
+ GLenumToString(GLESEnum::MaterialParameter, pname), param);
+
+ if (context)
+ {
+ MaterialParameter pnamePacked = PackParam<MaterialParameter>(pname);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateMaterialf(context, angle::EntryPoint::GLMaterialf, face, pnamePacked, param));
+ if (isCallValid)
+ {
+ context->materialf(face, pnamePacked, param);
+ }
+ ANGLE_CAPTURE_GL(Materialf, isCallValid, context, face, pnamePacked, param);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Materialfv(GLenum face, GLenum pname, const GLfloat *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLMaterialfv, "context = %d, face = %s, pname = %s, params = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::TriangleFace, face),
+ GLenumToString(GLESEnum::MaterialParameter, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ MaterialParameter pnamePacked = PackParam<MaterialParameter>(pname);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateMaterialfv(context, angle::EntryPoint::GLMaterialfv, face,
+ pnamePacked, params));
+ if (isCallValid)
+ {
+ context->materialfv(face, pnamePacked, params);
+ }
+ ANGLE_CAPTURE_GL(Materialfv, isCallValid, context, face, pnamePacked, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Materialx(GLenum face, GLenum pname, GLfixed param)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLMaterialx, "context = %d, face = %s, pname = %s, param = 0x%X", CID(context),
+ GLenumToString(GLESEnum::TriangleFace, face),
+ GLenumToString(GLESEnum::MaterialParameter, pname), param);
+
+ if (context)
+ {
+ MaterialParameter pnamePacked = PackParam<MaterialParameter>(pname);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateMaterialx(context, angle::EntryPoint::GLMaterialx, face, pnamePacked, param));
+ if (isCallValid)
+ {
+ context->materialx(face, pnamePacked, param);
+ }
+ ANGLE_CAPTURE_GL(Materialx, isCallValid, context, face, pnamePacked, param);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Materialxv(GLenum face, GLenum pname, const GLfixed *param)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLMaterialxv, "context = %d, face = %s, pname = %s, param = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::TriangleFace, face),
+ GLenumToString(GLESEnum::MaterialParameter, pname), (uintptr_t)param);
+
+ if (context)
+ {
+ MaterialParameter pnamePacked = PackParam<MaterialParameter>(pname);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateMaterialxv(context, angle::EntryPoint::GLMaterialxv, face,
+ pnamePacked, param));
+ if (isCallValid)
+ {
+ context->materialxv(face, pnamePacked, param);
+ }
+ ANGLE_CAPTURE_GL(Materialxv, isCallValid, context, face, pnamePacked, param);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_MatrixMode(GLenum mode)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLMatrixMode, "context = %d, mode = %s", CID(context),
+ GLenumToString(GLESEnum::MatrixMode, mode));
+
+ if (context)
+ {
+ MatrixType modePacked = PackParam<MatrixType>(mode);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateMatrixMode(context, angle::EntryPoint::GLMatrixMode, modePacked));
+ if (isCallValid)
+ {
+ context->matrixMode(modePacked);
+ }
+ ANGLE_CAPTURE_GL(MatrixMode, isCallValid, context, modePacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_MultMatrixf(const GLfloat *m)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLMultMatrixf, "context = %d, m = 0x%016" PRIxPTR "", CID(context),
+ (uintptr_t)m);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateMultMatrixf(context, angle::EntryPoint::GLMultMatrixf, m));
+ if (isCallValid)
+ {
+ context->multMatrixf(m);
+ }
+ ANGLE_CAPTURE_GL(MultMatrixf, isCallValid, context, m);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_MultMatrixx(const GLfixed *m)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLMultMatrixx, "context = %d, m = 0x%016" PRIxPTR "", CID(context),
+ (uintptr_t)m);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateMultMatrixx(context, angle::EntryPoint::GLMultMatrixx, m));
+ if (isCallValid)
+ {
+ context->multMatrixx(m);
+ }
+ ANGLE_CAPTURE_GL(MultMatrixx, isCallValid, context, m);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_MultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLMultiTexCoord4f, "context = %d, target = %s, s = %f, t = %f, r = %f, q = %f",
+ CID(context), GLenumToString(GLESEnum::TextureUnit, target), s, t, r, q);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateMultiTexCoord4f(context, angle::EntryPoint::GLMultiTexCoord4f,
+ target, s, t, r, q));
+ if (isCallValid)
+ {
+ context->multiTexCoord4f(target, s, t, r, q);
+ }
+ ANGLE_CAPTURE_GL(MultiTexCoord4f, isCallValid, context, target, s, t, r, q);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_MultiTexCoord4x(GLenum texture, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLMultiTexCoord4x,
+ "context = %d, texture = %s, s = 0x%X, t = 0x%X, r = 0x%X, q = 0x%X", CID(context),
+ GLenumToString(GLESEnum::TextureUnit, texture), s, t, r, q);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateMultiTexCoord4x(context, angle::EntryPoint::GLMultiTexCoord4x,
+ texture, s, t, r, q));
+ if (isCallValid)
+ {
+ context->multiTexCoord4x(texture, s, t, r, q);
+ }
+ ANGLE_CAPTURE_GL(MultiTexCoord4x, isCallValid, context, texture, s, t, r, q);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Normal3f(GLfloat nx, GLfloat ny, GLfloat nz)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLNormal3f, "context = %d, nx = %f, ny = %f, nz = %f", CID(context), nx, ny, nz);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateNormal3f(context, angle::EntryPoint::GLNormal3f, nx, ny, nz));
+ if (isCallValid)
+ {
+ context->normal3f(nx, ny, nz);
+ }
+ ANGLE_CAPTURE_GL(Normal3f, isCallValid, context, nx, ny, nz);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Normal3x(GLfixed nx, GLfixed ny, GLfixed nz)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLNormal3x, "context = %d, nx = 0x%X, ny = 0x%X, nz = 0x%X", CID(context), nx,
+ ny, nz);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateNormal3x(context, angle::EntryPoint::GLNormal3x, nx, ny, nz));
+ if (isCallValid)
+ {
+ context->normal3x(nx, ny, nz);
+ }
+ ANGLE_CAPTURE_GL(Normal3x, isCallValid, context, nx, ny, nz);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_NormalPointer(GLenum type, GLsizei stride, const void *pointer)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLNormalPointer,
+ "context = %d, type = %s, stride = %d, pointer = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::NormalPointerType, type), stride, (uintptr_t)pointer);
+
+ if (context)
+ {
+ VertexAttribType typePacked = PackParam<VertexAttribType>(type);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateNormalPointer(context, angle::EntryPoint::GLNormalPointer,
+ typePacked, stride, pointer));
+ if (isCallValid)
+ {
+ context->normalPointer(typePacked, stride, pointer);
+ }
+ ANGLE_CAPTURE_GL(NormalPointer, isCallValid, context, typePacked, stride, pointer);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Orthof(GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLOrthof, "context = %d, l = %f, r = %f, b = %f, t = %f, n = %f, f = %f",
+ CID(context), l, r, b, t, n, f);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateOrthof(context, angle::EntryPoint::GLOrthof, l, r, b, t, n, f));
+ if (isCallValid)
+ {
+ context->orthof(l, r, b, t, n, f);
+ }
+ ANGLE_CAPTURE_GL(Orthof, isCallValid, context, l, r, b, t, n, f);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Orthox(GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLOrthox,
+ "context = %d, l = 0x%X, r = 0x%X, b = 0x%X, t = 0x%X, n = 0x%X, f = 0x%X", CID(context),
+ l, r, b, t, n, f);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateOrthox(context, angle::EntryPoint::GLOrthox, l, r, b, t, n, f));
+ if (isCallValid)
+ {
+ context->orthox(l, r, b, t, n, f);
+ }
+ ANGLE_CAPTURE_GL(Orthox, isCallValid, context, l, r, b, t, n, f);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_PointParameterf(GLenum pname, GLfloat param)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLPointParameterf, "context = %d, pname = %s, param = %f", CID(context),
+ GLenumToString(GLESEnum::AllEnums, pname), param);
+
+ if (context)
+ {
+ PointParameter pnamePacked = PackParam<PointParameter>(pname);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidatePointParameterf(context, angle::EntryPoint::GLPointParameterf,
+ pnamePacked, param));
+ if (isCallValid)
+ {
+ context->pointParameterf(pnamePacked, param);
+ }
+ ANGLE_CAPTURE_GL(PointParameterf, isCallValid, context, pnamePacked, param);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_PointParameterfv(GLenum pname, const GLfloat *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLPointParameterfv, "context = %d, pname = %s, params = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ PointParameter pnamePacked = PackParam<PointParameter>(pname);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidatePointParameterfv(context, angle::EntryPoint::GLPointParameterfv,
+ pnamePacked, params));
+ if (isCallValid)
+ {
+ context->pointParameterfv(pnamePacked, params);
+ }
+ ANGLE_CAPTURE_GL(PointParameterfv, isCallValid, context, pnamePacked, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_PointParameterx(GLenum pname, GLfixed param)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLPointParameterx, "context = %d, pname = %s, param = 0x%X", CID(context),
+ GLenumToString(GLESEnum::AllEnums, pname), param);
+
+ if (context)
+ {
+ PointParameter pnamePacked = PackParam<PointParameter>(pname);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidatePointParameterx(context, angle::EntryPoint::GLPointParameterx,
+ pnamePacked, param));
+ if (isCallValid)
+ {
+ context->pointParameterx(pnamePacked, param);
+ }
+ ANGLE_CAPTURE_GL(PointParameterx, isCallValid, context, pnamePacked, param);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_PointParameterxv(GLenum pname, const GLfixed *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLPointParameterxv, "context = %d, pname = %s, params = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ PointParameter pnamePacked = PackParam<PointParameter>(pname);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidatePointParameterxv(context, angle::EntryPoint::GLPointParameterxv,
+ pnamePacked, params));
+ if (isCallValid)
+ {
+ context->pointParameterxv(pnamePacked, params);
+ }
+ ANGLE_CAPTURE_GL(PointParameterxv, isCallValid, context, pnamePacked, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_PointSize(GLfloat size)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLPointSize, "context = %d, size = %f", CID(context), size);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidatePointSize(context, angle::EntryPoint::GLPointSize, size));
+ if (isCallValid)
+ {
+ context->pointSize(size);
+ }
+ ANGLE_CAPTURE_GL(PointSize, isCallValid, context, size);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_PointSizex(GLfixed size)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLPointSizex, "context = %d, size = 0x%X", CID(context), size);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidatePointSizex(context, angle::EntryPoint::GLPointSizex, size));
+ if (isCallValid)
+ {
+ context->pointSizex(size);
+ }
+ ANGLE_CAPTURE_GL(PointSizex, isCallValid, context, size);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_PolygonOffsetx(GLfixed factor, GLfixed units)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLPolygonOffsetx, "context = %d, factor = 0x%X, units = 0x%X", CID(context),
+ factor, units);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidatePolygonOffsetx(context, angle::EntryPoint::GLPolygonOffsetx, factor, units));
+ if (isCallValid)
+ {
+ context->polygonOffsetx(factor, units);
+ }
+ ANGLE_CAPTURE_GL(PolygonOffsetx, isCallValid, context, factor, units);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_PopMatrix()
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLPopMatrix, "context = %d", CID(context));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidatePopMatrix(context, angle::EntryPoint::GLPopMatrix));
+ if (isCallValid)
+ {
+ context->popMatrix();
+ }
+ ANGLE_CAPTURE_GL(PopMatrix, isCallValid, context);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_PushMatrix()
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLPushMatrix, "context = %d", CID(context));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidatePushMatrix(context, angle::EntryPoint::GLPushMatrix));
+ if (isCallValid)
+ {
+ context->pushMatrix();
+ }
+ ANGLE_CAPTURE_GL(PushMatrix, isCallValid, context);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Rotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLRotatef, "context = %d, angle = %f, x = %f, y = %f, z = %f", CID(context),
+ angle, x, y, z);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateRotatef(context, angle::EntryPoint::GLRotatef, angle, x, y, z));
+ if (isCallValid)
+ {
+ context->rotatef(angle, x, y, z);
+ }
+ ANGLE_CAPTURE_GL(Rotatef, isCallValid, context, angle, x, y, z);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Rotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLRotatex, "context = %d, angle = 0x%X, x = 0x%X, y = 0x%X, z = 0x%X",
+ CID(context), angle, x, y, z);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateRotatex(context, angle::EntryPoint::GLRotatex, angle, x, y, z));
+ if (isCallValid)
+ {
+ context->rotatex(angle, x, y, z);
+ }
+ ANGLE_CAPTURE_GL(Rotatex, isCallValid, context, angle, x, y, z);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_SampleCoveragex(GLclampx value, GLboolean invert)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLSampleCoveragex, "context = %d, value = 0x%X, invert = %s", CID(context),
+ value, GLbooleanToString(invert));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateSampleCoveragex(context, angle::EntryPoint::GLSampleCoveragex, value, invert));
+ if (isCallValid)
+ {
+ context->sampleCoveragex(value, invert);
+ }
+ ANGLE_CAPTURE_GL(SampleCoveragex, isCallValid, context, value, invert);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Scalef(GLfloat x, GLfloat y, GLfloat z)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLScalef, "context = %d, x = %f, y = %f, z = %f", CID(context), x, y, z);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateScalef(context, angle::EntryPoint::GLScalef, x, y, z));
+ if (isCallValid)
+ {
+ context->scalef(x, y, z);
+ }
+ ANGLE_CAPTURE_GL(Scalef, isCallValid, context, x, y, z);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Scalex(GLfixed x, GLfixed y, GLfixed z)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLScalex, "context = %d, x = 0x%X, y = 0x%X, z = 0x%X", CID(context), x, y, z);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateScalex(context, angle::EntryPoint::GLScalex, x, y, z));
+ if (isCallValid)
+ {
+ context->scalex(x, y, z);
+ }
+ ANGLE_CAPTURE_GL(Scalex, isCallValid, context, x, y, z);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ShadeModel(GLenum mode)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLShadeModel, "context = %d, mode = %s", CID(context),
+ GLenumToString(GLESEnum::ShadingModel, mode));
+
+ if (context)
+ {
+ ShadingModel modePacked = PackParam<ShadingModel>(mode);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateShadeModel(context, angle::EntryPoint::GLShadeModel, modePacked));
+ if (isCallValid)
+ {
+ context->shadeModel(modePacked);
+ }
+ ANGLE_CAPTURE_GL(ShadeModel, isCallValid, context, modePacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexCoordPointer(GLint size, GLenum type, GLsizei stride, const void *pointer)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexCoordPointer,
+ "context = %d, size = %d, type = %s, stride = %d, pointer = 0x%016" PRIxPTR "",
+ CID(context), size, GLenumToString(GLESEnum::TexCoordPointerType, type), stride,
+ (uintptr_t)pointer);
+
+ if (context)
+ {
+ VertexAttribType typePacked = PackParam<VertexAttribType>(type);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateTexCoordPointer(context, angle::EntryPoint::GLTexCoordPointer,
+ size, typePacked, stride, pointer));
+ if (isCallValid)
+ {
+ context->texCoordPointer(size, typePacked, stride, pointer);
+ }
+ ANGLE_CAPTURE_GL(TexCoordPointer, isCallValid, context, size, typePacked, stride, pointer);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexEnvf(GLenum target, GLenum pname, GLfloat param)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexEnvf, "context = %d, target = %s, pname = %s, param = %f", CID(context),
+ GLenumToString(GLESEnum::TextureEnvTarget, target),
+ GLenumToString(GLESEnum::TextureEnvParameter, pname), param);
+
+ if (context)
+ {
+ TextureEnvTarget targetPacked = PackParam<TextureEnvTarget>(target);
+ TextureEnvParameter pnamePacked = PackParam<TextureEnvParameter>(pname);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() || ValidateTexEnvf(context, angle::EntryPoint::GLTexEnvf,
+ targetPacked, pnamePacked, param));
+ if (isCallValid)
+ {
+ context->texEnvf(targetPacked, pnamePacked, param);
+ }
+ ANGLE_CAPTURE_GL(TexEnvf, isCallValid, context, targetPacked, pnamePacked, param);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexEnvfv(GLenum target, GLenum pname, const GLfloat *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexEnvfv, "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::TextureEnvTarget, target),
+ GLenumToString(GLESEnum::TextureEnvParameter, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ TextureEnvTarget targetPacked = PackParam<TextureEnvTarget>(target);
+ TextureEnvParameter pnamePacked = PackParam<TextureEnvParameter>(pname);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() || ValidateTexEnvfv(context, angle::EntryPoint::GLTexEnvfv,
+ targetPacked, pnamePacked, params));
+ if (isCallValid)
+ {
+ context->texEnvfv(targetPacked, pnamePacked, params);
+ }
+ ANGLE_CAPTURE_GL(TexEnvfv, isCallValid, context, targetPacked, pnamePacked, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexEnvi(GLenum target, GLenum pname, GLint param)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexEnvi, "context = %d, target = %s, pname = %s, param = %d", CID(context),
+ GLenumToString(GLESEnum::TextureEnvTarget, target),
+ GLenumToString(GLESEnum::TextureEnvParameter, pname), param);
+
+ if (context)
+ {
+ TextureEnvTarget targetPacked = PackParam<TextureEnvTarget>(target);
+ TextureEnvParameter pnamePacked = PackParam<TextureEnvParameter>(pname);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() || ValidateTexEnvi(context, angle::EntryPoint::GLTexEnvi,
+ targetPacked, pnamePacked, param));
+ if (isCallValid)
+ {
+ context->texEnvi(targetPacked, pnamePacked, param);
+ }
+ ANGLE_CAPTURE_GL(TexEnvi, isCallValid, context, targetPacked, pnamePacked, param);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexEnviv(GLenum target, GLenum pname, const GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexEnviv, "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::TextureEnvTarget, target),
+ GLenumToString(GLESEnum::TextureEnvParameter, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ TextureEnvTarget targetPacked = PackParam<TextureEnvTarget>(target);
+ TextureEnvParameter pnamePacked = PackParam<TextureEnvParameter>(pname);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() || ValidateTexEnviv(context, angle::EntryPoint::GLTexEnviv,
+ targetPacked, pnamePacked, params));
+ if (isCallValid)
+ {
+ context->texEnviv(targetPacked, pnamePacked, params);
+ }
+ ANGLE_CAPTURE_GL(TexEnviv, isCallValid, context, targetPacked, pnamePacked, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexEnvx(GLenum target, GLenum pname, GLfixed param)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexEnvx, "context = %d, target = %s, pname = %s, param = 0x%X", CID(context),
+ GLenumToString(GLESEnum::TextureEnvTarget, target),
+ GLenumToString(GLESEnum::TextureEnvParameter, pname), param);
+
+ if (context)
+ {
+ TextureEnvTarget targetPacked = PackParam<TextureEnvTarget>(target);
+ TextureEnvParameter pnamePacked = PackParam<TextureEnvParameter>(pname);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() || ValidateTexEnvx(context, angle::EntryPoint::GLTexEnvx,
+ targetPacked, pnamePacked, param));
+ if (isCallValid)
+ {
+ context->texEnvx(targetPacked, pnamePacked, param);
+ }
+ ANGLE_CAPTURE_GL(TexEnvx, isCallValid, context, targetPacked, pnamePacked, param);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexEnvxv(GLenum target, GLenum pname, const GLfixed *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexEnvxv, "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::TextureEnvTarget, target),
+ GLenumToString(GLESEnum::TextureEnvParameter, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ TextureEnvTarget targetPacked = PackParam<TextureEnvTarget>(target);
+ TextureEnvParameter pnamePacked = PackParam<TextureEnvParameter>(pname);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() || ValidateTexEnvxv(context, angle::EntryPoint::GLTexEnvxv,
+ targetPacked, pnamePacked, params));
+ if (isCallValid)
+ {
+ context->texEnvxv(targetPacked, pnamePacked, params);
+ }
+ ANGLE_CAPTURE_GL(TexEnvxv, isCallValid, context, targetPacked, pnamePacked, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexParameterx(GLenum target, GLenum pname, GLfixed param)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexParameterx, "context = %d, target = %s, pname = %s, param = 0x%X",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target),
+ GLenumToString(GLESEnum::GetTextureParameter, pname), param);
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateTexParameterx(context, angle::EntryPoint::GLTexParameterx,
+ targetPacked, pname, param));
+ if (isCallValid)
+ {
+ context->texParameterx(targetPacked, pname, param);
+ }
+ ANGLE_CAPTURE_GL(TexParameterx, isCallValid, context, targetPacked, pname, param);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexParameterxv(GLenum target, GLenum pname, const GLfixed *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexParameterxv,
+ "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::TextureTarget, target),
+ GLenumToString(GLESEnum::GetTextureParameter, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateTexParameterxv(context, angle::EntryPoint::GLTexParameterxv,
+ targetPacked, pname, params));
+ if (isCallValid)
+ {
+ context->texParameterxv(targetPacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(TexParameterxv, isCallValid, context, targetPacked, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Translatef(GLfloat x, GLfloat y, GLfloat z)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTranslatef, "context = %d, x = %f, y = %f, z = %f", CID(context), x, y, z);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateTranslatef(context, angle::EntryPoint::GLTranslatef, x, y, z));
+ if (isCallValid)
+ {
+ context->translatef(x, y, z);
+ }
+ ANGLE_CAPTURE_GL(Translatef, isCallValid, context, x, y, z);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Translatex(GLfixed x, GLfixed y, GLfixed z)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTranslatex, "context = %d, x = 0x%X, y = 0x%X, z = 0x%X", CID(context), x, y,
+ z);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateTranslatex(context, angle::EntryPoint::GLTranslatex, x, y, z));
+ if (isCallValid)
+ {
+ context->translatex(x, y, z);
+ }
+ ANGLE_CAPTURE_GL(Translatex, isCallValid, context, x, y, z);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_VertexPointer(GLint size, GLenum type, GLsizei stride, const void *pointer)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLVertexPointer,
+ "context = %d, size = %d, type = %s, stride = %d, pointer = 0x%016" PRIxPTR "",
+ CID(context), size, GLenumToString(GLESEnum::VertexPointerType, type), stride,
+ (uintptr_t)pointer);
+
+ if (context)
+ {
+ VertexAttribType typePacked = PackParam<VertexAttribType>(type);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateVertexPointer(context, angle::EntryPoint::GLVertexPointer, size,
+ typePacked, stride, pointer));
+ if (isCallValid)
+ {
+ context->vertexPointer(size, typePacked, stride, pointer);
+ }
+ ANGLE_CAPTURE_GL(VertexPointer, isCallValid, context, size, typePacked, stride, pointer);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+} // extern "C"
diff --git a/gfx/angle/checkout/src/libGLESv2/entry_points_gles_1_0_autogen.h b/gfx/angle/checkout/src/libGLESv2/entry_points_gles_1_0_autogen.h
new file mode 100644
index 0000000000..211fb5b8db
--- /dev/null
+++ b/gfx/angle/checkout/src/libGLESv2/entry_points_gles_1_0_autogen.h
@@ -0,0 +1,123 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml.
+//
+// Copyright 2020 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_1_0_autogen.h:
+// Defines the GLES 1.0 entry points.
+
+#ifndef LIBGLESV2_ENTRY_POINTS_GLES_1_0_AUTOGEN_H_
+#define LIBGLESV2_ENTRY_POINTS_GLES_1_0_AUTOGEN_H_
+
+#include <GLES/gl.h>
+#include <export.h>
+
+extern "C" {
+ANGLE_EXPORT void GL_APIENTRY GL_AlphaFunc(GLenum func, GLfloat ref);
+ANGLE_EXPORT void GL_APIENTRY GL_AlphaFuncx(GLenum func, GLfixed ref);
+ANGLE_EXPORT void GL_APIENTRY GL_ClearColorx(GLfixed red,
+ GLfixed green,
+ GLfixed blue,
+ GLfixed alpha);
+ANGLE_EXPORT void GL_APIENTRY GL_ClearDepthx(GLfixed depth);
+ANGLE_EXPORT void GL_APIENTRY GL_ClientActiveTexture(GLenum texture);
+ANGLE_EXPORT void GL_APIENTRY GL_ClipPlanef(GLenum p, const GLfloat *eqn);
+ANGLE_EXPORT void GL_APIENTRY GL_ClipPlanex(GLenum plane, const GLfixed *equation);
+ANGLE_EXPORT void GL_APIENTRY GL_Color4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+ANGLE_EXPORT void GL_APIENTRY GL_Color4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha);
+ANGLE_EXPORT void GL_APIENTRY GL_Color4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha);
+ANGLE_EXPORT void GL_APIENTRY GL_ColorPointer(GLint size,
+ GLenum type,
+ GLsizei stride,
+ const void *pointer);
+ANGLE_EXPORT void GL_APIENTRY GL_DepthRangex(GLfixed n, GLfixed f);
+ANGLE_EXPORT void GL_APIENTRY GL_DisableClientState(GLenum array);
+ANGLE_EXPORT void GL_APIENTRY GL_EnableClientState(GLenum array);
+ANGLE_EXPORT void GL_APIENTRY GL_Fogf(GLenum pname, GLfloat param);
+ANGLE_EXPORT void GL_APIENTRY GL_Fogfv(GLenum pname, const GLfloat *params);
+ANGLE_EXPORT void GL_APIENTRY GL_Fogx(GLenum pname, GLfixed param);
+ANGLE_EXPORT void GL_APIENTRY GL_Fogxv(GLenum pname, const GLfixed *param);
+ANGLE_EXPORT void GL_APIENTRY
+GL_Frustumf(GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f);
+ANGLE_EXPORT void GL_APIENTRY
+GL_Frustumx(GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f);
+ANGLE_EXPORT void GL_APIENTRY GL_GetClipPlanef(GLenum plane, GLfloat *equation);
+ANGLE_EXPORT void GL_APIENTRY GL_GetClipPlanex(GLenum plane, GLfixed *equation);
+ANGLE_EXPORT void GL_APIENTRY GL_GetFixedv(GLenum pname, GLfixed *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetLightfv(GLenum light, GLenum pname, GLfloat *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetLightxv(GLenum light, GLenum pname, GLfixed *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetMaterialfv(GLenum face, GLenum pname, GLfloat *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetMaterialxv(GLenum face, GLenum pname, GLfixed *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetTexEnvfv(GLenum target, GLenum pname, GLfloat *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetTexEnviv(GLenum target, GLenum pname, GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetTexEnvxv(GLenum target, GLenum pname, GLfixed *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetTexParameterxv(GLenum target, GLenum pname, GLfixed *params);
+ANGLE_EXPORT void GL_APIENTRY GL_LightModelf(GLenum pname, GLfloat param);
+ANGLE_EXPORT void GL_APIENTRY GL_LightModelfv(GLenum pname, const GLfloat *params);
+ANGLE_EXPORT void GL_APIENTRY GL_LightModelx(GLenum pname, GLfixed param);
+ANGLE_EXPORT void GL_APIENTRY GL_LightModelxv(GLenum pname, const GLfixed *param);
+ANGLE_EXPORT void GL_APIENTRY GL_Lightf(GLenum light, GLenum pname, GLfloat param);
+ANGLE_EXPORT void GL_APIENTRY GL_Lightfv(GLenum light, GLenum pname, const GLfloat *params);
+ANGLE_EXPORT void GL_APIENTRY GL_Lightx(GLenum light, GLenum pname, GLfixed param);
+ANGLE_EXPORT void GL_APIENTRY GL_Lightxv(GLenum light, GLenum pname, const GLfixed *params);
+ANGLE_EXPORT void GL_APIENTRY GL_LineWidthx(GLfixed width);
+ANGLE_EXPORT void GL_APIENTRY GL_LoadIdentity();
+ANGLE_EXPORT void GL_APIENTRY GL_LoadMatrixf(const GLfloat *m);
+ANGLE_EXPORT void GL_APIENTRY GL_LoadMatrixx(const GLfixed *m);
+ANGLE_EXPORT void GL_APIENTRY GL_LogicOp(GLenum opcode);
+ANGLE_EXPORT void GL_APIENTRY GL_Materialf(GLenum face, GLenum pname, GLfloat param);
+ANGLE_EXPORT void GL_APIENTRY GL_Materialfv(GLenum face, GLenum pname, const GLfloat *params);
+ANGLE_EXPORT void GL_APIENTRY GL_Materialx(GLenum face, GLenum pname, GLfixed param);
+ANGLE_EXPORT void GL_APIENTRY GL_Materialxv(GLenum face, GLenum pname, const GLfixed *param);
+ANGLE_EXPORT void GL_APIENTRY GL_MatrixMode(GLenum mode);
+ANGLE_EXPORT void GL_APIENTRY GL_MultMatrixf(const GLfloat *m);
+ANGLE_EXPORT void GL_APIENTRY GL_MultMatrixx(const GLfixed *m);
+ANGLE_EXPORT void GL_APIENTRY
+GL_MultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+ANGLE_EXPORT void GL_APIENTRY
+GL_MultiTexCoord4x(GLenum texture, GLfixed s, GLfixed t, GLfixed r, GLfixed q);
+ANGLE_EXPORT void GL_APIENTRY GL_Normal3f(GLfloat nx, GLfloat ny, GLfloat nz);
+ANGLE_EXPORT void GL_APIENTRY GL_Normal3x(GLfixed nx, GLfixed ny, GLfixed nz);
+ANGLE_EXPORT void GL_APIENTRY GL_NormalPointer(GLenum type, GLsizei stride, const void *pointer);
+ANGLE_EXPORT void GL_APIENTRY
+GL_Orthof(GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f);
+ANGLE_EXPORT void GL_APIENTRY
+GL_Orthox(GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f);
+ANGLE_EXPORT void GL_APIENTRY GL_PointParameterf(GLenum pname, GLfloat param);
+ANGLE_EXPORT void GL_APIENTRY GL_PointParameterfv(GLenum pname, const GLfloat *params);
+ANGLE_EXPORT void GL_APIENTRY GL_PointParameterx(GLenum pname, GLfixed param);
+ANGLE_EXPORT void GL_APIENTRY GL_PointParameterxv(GLenum pname, const GLfixed *params);
+ANGLE_EXPORT void GL_APIENTRY GL_PointSize(GLfloat size);
+ANGLE_EXPORT void GL_APIENTRY GL_PointSizex(GLfixed size);
+ANGLE_EXPORT void GL_APIENTRY GL_PolygonOffsetx(GLfixed factor, GLfixed units);
+ANGLE_EXPORT void GL_APIENTRY GL_PopMatrix();
+ANGLE_EXPORT void GL_APIENTRY GL_PushMatrix();
+ANGLE_EXPORT void GL_APIENTRY GL_Rotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
+ANGLE_EXPORT void GL_APIENTRY GL_Rotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z);
+ANGLE_EXPORT void GL_APIENTRY GL_SampleCoveragex(GLclampx value, GLboolean invert);
+ANGLE_EXPORT void GL_APIENTRY GL_Scalef(GLfloat x, GLfloat y, GLfloat z);
+ANGLE_EXPORT void GL_APIENTRY GL_Scalex(GLfixed x, GLfixed y, GLfixed z);
+ANGLE_EXPORT void GL_APIENTRY GL_ShadeModel(GLenum mode);
+ANGLE_EXPORT void GL_APIENTRY GL_TexCoordPointer(GLint size,
+ GLenum type,
+ GLsizei stride,
+ const void *pointer);
+ANGLE_EXPORT void GL_APIENTRY GL_TexEnvf(GLenum target, GLenum pname, GLfloat param);
+ANGLE_EXPORT void GL_APIENTRY GL_TexEnvfv(GLenum target, GLenum pname, const GLfloat *params);
+ANGLE_EXPORT void GL_APIENTRY GL_TexEnvi(GLenum target, GLenum pname, GLint param);
+ANGLE_EXPORT void GL_APIENTRY GL_TexEnviv(GLenum target, GLenum pname, const GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_TexEnvx(GLenum target, GLenum pname, GLfixed param);
+ANGLE_EXPORT void GL_APIENTRY GL_TexEnvxv(GLenum target, GLenum pname, const GLfixed *params);
+ANGLE_EXPORT void GL_APIENTRY GL_TexParameterx(GLenum target, GLenum pname, GLfixed param);
+ANGLE_EXPORT void GL_APIENTRY GL_TexParameterxv(GLenum target, GLenum pname, const GLfixed *params);
+ANGLE_EXPORT void GL_APIENTRY GL_Translatef(GLfloat x, GLfloat y, GLfloat z);
+ANGLE_EXPORT void GL_APIENTRY GL_Translatex(GLfixed x, GLfixed y, GLfixed z);
+ANGLE_EXPORT void GL_APIENTRY GL_VertexPointer(GLint size,
+ GLenum type,
+ GLsizei stride,
+ const void *pointer);
+} // extern "C"
+
+#endif // LIBGLESV2_ENTRY_POINTS_GLES_1_0_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libGLESv2/entry_points_gles_2_0_autogen.cpp b/gfx/angle/checkout/src/libGLESv2/entry_points_gles_2_0_autogen.cpp
new file mode 100644
index 0000000000..fd49217e16
--- /dev/null
+++ b/gfx/angle/checkout/src/libGLESv2/entry_points_gles_2_0_autogen.cpp
@@ -0,0 +1,3864 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml.
+//
+// Copyright 2020 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_2_0_autogen.cpp:
+// Defines the GLES 2.0 entry points.
+
+#include "libGLESv2/entry_points_gles_2_0_autogen.h"
+
+#include "common/entry_points_enum_autogen.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Context.inl.h"
+#include "libANGLE/capture/capture_gles_2_0_autogen.h"
+#include "libANGLE/capture/gl_enum_utils.h"
+#include "libANGLE/entry_points_utils.h"
+#include "libANGLE/validationES2.h"
+#include "libGLESv2/global_state.h"
+
+using namespace gl;
+
+extern "C" {
+void GL_APIENTRY GL_ActiveTexture(GLenum texture)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLActiveTexture, "context = %d, texture = %s", CID(context),
+ GLenumToString(GLESEnum::TextureUnit, texture));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateActiveTexture(context, angle::EntryPoint::GLActiveTexture, texture));
+ if (isCallValid)
+ {
+ context->activeTexture(texture);
+ }
+ ANGLE_CAPTURE_GL(ActiveTexture, isCallValid, context, texture);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_AttachShader(GLuint program, GLuint shader)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLAttachShader, "context = %d, program = %u, shader = %u", CID(context), program,
+ shader);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ ShaderProgramID shaderPacked = PackParam<ShaderProgramID>(shader);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateAttachShader(context, angle::EntryPoint::GLAttachShader,
+ programPacked, shaderPacked));
+ if (isCallValid)
+ {
+ context->attachShader(programPacked, shaderPacked);
+ }
+ ANGLE_CAPTURE_GL(AttachShader, isCallValid, context, programPacked, shaderPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_BindAttribLocation(GLuint program, GLuint index, const GLchar *name)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBindAttribLocation,
+ "context = %d, program = %u, index = %u, name = 0x%016" PRIxPTR "", CID(context), program,
+ index, (uintptr_t)name);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateBindAttribLocation(context, angle::EntryPoint::GLBindAttribLocation,
+ programPacked, index, name));
+ if (isCallValid)
+ {
+ context->bindAttribLocation(programPacked, index, name);
+ }
+ ANGLE_CAPTURE_GL(BindAttribLocation, isCallValid, context, programPacked, index, name);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_BindBuffer(GLenum target, GLuint buffer)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBindBuffer, "context = %d, target = %s, buffer = %u", CID(context),
+ GLenumToString(GLESEnum::BufferTargetARB, target), buffer);
+
+ if (context)
+ {
+ BufferBinding targetPacked = PackParam<BufferBinding>(target);
+ BufferID bufferPacked = PackParam<BufferID>(buffer);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateBindBuffer(context, angle::EntryPoint::GLBindBuffer,
+ targetPacked, bufferPacked));
+ if (isCallValid)
+ {
+ context->bindBuffer(targetPacked, bufferPacked);
+ }
+ ANGLE_CAPTURE_GL(BindBuffer, isCallValid, context, targetPacked, bufferPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_BindFramebuffer(GLenum target, GLuint framebuffer)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBindFramebuffer, "context = %d, target = %s, framebuffer = %u", CID(context),
+ GLenumToString(GLESEnum::FramebufferTarget, target), framebuffer);
+
+ if (context)
+ {
+ FramebufferID framebufferPacked = PackParam<FramebufferID>(framebuffer);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateBindFramebuffer(context, angle::EntryPoint::GLBindFramebuffer,
+ target, framebufferPacked));
+ if (isCallValid)
+ {
+ context->bindFramebuffer(target, framebufferPacked);
+ }
+ ANGLE_CAPTURE_GL(BindFramebuffer, isCallValid, context, target, framebufferPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_BindRenderbuffer(GLenum target, GLuint renderbuffer)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBindRenderbuffer, "context = %d, target = %s, renderbuffer = %u", CID(context),
+ GLenumToString(GLESEnum::RenderbufferTarget, target), renderbuffer);
+
+ if (context)
+ {
+ RenderbufferID renderbufferPacked = PackParam<RenderbufferID>(renderbuffer);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateBindRenderbuffer(context, angle::EntryPoint::GLBindRenderbuffer,
+ target, renderbufferPacked));
+ if (isCallValid)
+ {
+ context->bindRenderbuffer(target, renderbufferPacked);
+ }
+ ANGLE_CAPTURE_GL(BindRenderbuffer, isCallValid, context, target, renderbufferPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_BindTexture(GLenum target, GLuint texture)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBindTexture, "context = %d, target = %s, texture = %u", CID(context),
+ GLenumToString(GLESEnum::TextureTarget, target), texture);
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ TextureID texturePacked = PackParam<TextureID>(texture);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateBindTexture(context, angle::EntryPoint::GLBindTexture,
+ targetPacked, texturePacked));
+ if (isCallValid)
+ {
+ context->bindTexture(targetPacked, texturePacked);
+ }
+ ANGLE_CAPTURE_GL(BindTexture, isCallValid, context, targetPacked, texturePacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_BlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBlendColor, "context = %d, red = %f, green = %f, blue = %f, alpha = %f",
+ CID(context), red, green, blue, alpha);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateBlendColor(context, angle::EntryPoint::GLBlendColor, red, green, blue, alpha));
+ if (isCallValid)
+ {
+ context->blendColor(red, green, blue, alpha);
+ }
+ ANGLE_CAPTURE_GL(BlendColor, isCallValid, context, red, green, blue, alpha);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_BlendEquation(GLenum mode)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBlendEquation, "context = %d, mode = %s", CID(context),
+ GLenumToString(GLESEnum::BlendEquationModeEXT, mode));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateBlendEquation(context, angle::EntryPoint::GLBlendEquation, mode));
+ if (isCallValid)
+ {
+ context->blendEquation(mode);
+ }
+ ANGLE_CAPTURE_GL(BlendEquation, isCallValid, context, mode);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBlendEquationSeparate, "context = %d, modeRGB = %s, modeAlpha = %s",
+ CID(context), GLenumToString(GLESEnum::BlendEquationModeEXT, modeRGB),
+ GLenumToString(GLESEnum::BlendEquationModeEXT, modeAlpha));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateBlendEquationSeparate(context, angle::EntryPoint::GLBlendEquationSeparate,
+ modeRGB, modeAlpha));
+ if (isCallValid)
+ {
+ context->blendEquationSeparate(modeRGB, modeAlpha);
+ }
+ ANGLE_CAPTURE_GL(BlendEquationSeparate, isCallValid, context, modeRGB, modeAlpha);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_BlendFunc(GLenum sfactor, GLenum dfactor)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBlendFunc, "context = %d, sfactor = %s, dfactor = %s", CID(context),
+ GLenumToString(GLESEnum::BlendingFactor, sfactor),
+ GLenumToString(GLESEnum::BlendingFactor, dfactor));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateBlendFunc(context, angle::EntryPoint::GLBlendFunc, sfactor, dfactor));
+ if (isCallValid)
+ {
+ context->blendFunc(sfactor, dfactor);
+ }
+ ANGLE_CAPTURE_GL(BlendFunc, isCallValid, context, sfactor, dfactor);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_BlendFuncSeparate(GLenum sfactorRGB,
+ GLenum dfactorRGB,
+ GLenum sfactorAlpha,
+ GLenum dfactorAlpha)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBlendFuncSeparate,
+ "context = %d, sfactorRGB = %s, dfactorRGB = %s, sfactorAlpha = %s, dfactorAlpha = %s",
+ CID(context), GLenumToString(GLESEnum::BlendingFactor, sfactorRGB),
+ GLenumToString(GLESEnum::BlendingFactor, dfactorRGB),
+ GLenumToString(GLESEnum::BlendingFactor, sfactorAlpha),
+ GLenumToString(GLESEnum::BlendingFactor, dfactorAlpha));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateBlendFuncSeparate(context, angle::EntryPoint::GLBlendFuncSeparate, sfactorRGB,
+ dfactorRGB, sfactorAlpha, dfactorAlpha));
+ if (isCallValid)
+ {
+ context->blendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha);
+ }
+ ANGLE_CAPTURE_GL(BlendFuncSeparate, isCallValid, context, sfactorRGB, dfactorRGB,
+ sfactorAlpha, dfactorAlpha);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_BufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBufferData,
+ "context = %d, target = %s, size = %llu, data = 0x%016" PRIxPTR ", usage = %s",
+ CID(context), GLenumToString(GLESEnum::BufferTargetARB, target),
+ static_cast<unsigned long long>(size), (uintptr_t)data,
+ GLenumToString(GLESEnum::BufferUsageARB, usage));
+
+ if (context)
+ {
+ BufferBinding targetPacked = PackParam<BufferBinding>(target);
+ BufferUsage usagePacked = PackParam<BufferUsage>(usage);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateBufferData(context, angle::EntryPoint::GLBufferData,
+ targetPacked, size, data, usagePacked));
+ if (isCallValid)
+ {
+ context->bufferData(targetPacked, size, data, usagePacked);
+ }
+ ANGLE_CAPTURE_GL(BufferData, isCallValid, context, targetPacked, size, data, usagePacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBufferSubData,
+ "context = %d, target = %s, offset = %llu, size = %llu, data = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::BufferTargetARB, target),
+ static_cast<unsigned long long>(offset), static_cast<unsigned long long>(size),
+ (uintptr_t)data);
+
+ if (context)
+ {
+ BufferBinding targetPacked = PackParam<BufferBinding>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateBufferSubData(context, angle::EntryPoint::GLBufferSubData,
+ targetPacked, offset, size, data));
+ if (isCallValid)
+ {
+ context->bufferSubData(targetPacked, offset, size, data);
+ }
+ ANGLE_CAPTURE_GL(BufferSubData, isCallValid, context, targetPacked, offset, size, data);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+GLenum GL_APIENTRY GL_CheckFramebufferStatus(GLenum target)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLCheckFramebufferStatus, "context = %d, target = %s", CID(context),
+ GLenumToString(GLESEnum::FramebufferTarget, target));
+
+ GLenum returnValue;
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateCheckFramebufferStatus(
+ context, angle::EntryPoint::GLCheckFramebufferStatus, target));
+ if (isCallValid)
+ {
+ returnValue = context->checkFramebufferStatus(target);
+ }
+ else
+ {
+ returnValue =
+ GetDefaultReturnValue<angle::EntryPoint::GLCheckFramebufferStatus, GLenum>();
+ }
+ ANGLE_CAPTURE_GL(CheckFramebufferStatus, isCallValid, context, target, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLCheckFramebufferStatus, GLenum>();
+ }
+ return returnValue;
+}
+
+void GL_APIENTRY GL_Clear(GLbitfield mask)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLClear, "context = %d, mask = %s", CID(context),
+ GLbitfieldToString(GLESEnum::ClearBufferMask, mask).c_str());
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() || ValidateClear(context, angle::EntryPoint::GLClear, mask));
+ if (isCallValid)
+ {
+ context->clear(mask);
+ }
+ ANGLE_CAPTURE_GL(Clear, isCallValid, context, mask);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLClearColor, "context = %d, red = %f, green = %f, blue = %f, alpha = %f",
+ CID(context), red, green, blue, alpha);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateClearColor(context, angle::EntryPoint::GLClearColor, red, green, blue, alpha));
+ if (isCallValid)
+ {
+ context->clearColor(red, green, blue, alpha);
+ }
+ ANGLE_CAPTURE_GL(ClearColor, isCallValid, context, red, green, blue, alpha);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ClearDepthf(GLfloat d)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLClearDepthf, "context = %d, d = %f", CID(context), d);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateClearDepthf(context, angle::EntryPoint::GLClearDepthf, d));
+ if (isCallValid)
+ {
+ context->clearDepthf(d);
+ }
+ ANGLE_CAPTURE_GL(ClearDepthf, isCallValid, context, d);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ClearStencil(GLint s)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLClearStencil, "context = %d, s = %d", CID(context), s);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateClearStencil(context, angle::EntryPoint::GLClearStencil, s));
+ if (isCallValid)
+ {
+ context->clearStencil(s);
+ }
+ ANGLE_CAPTURE_GL(ClearStencil, isCallValid, context, s);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLColorMask, "context = %d, red = %s, green = %s, blue = %s, alpha = %s",
+ CID(context), GLbooleanToString(red), GLbooleanToString(green), GLbooleanToString(blue),
+ GLbooleanToString(alpha));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateColorMask(context, angle::EntryPoint::GLColorMask, red, green, blue, alpha));
+ if (isCallValid)
+ {
+ context->colorMask(red, green, blue, alpha);
+ }
+ ANGLE_CAPTURE_GL(ColorMask, isCallValid, context, red, green, blue, alpha);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_CompileShader(GLuint shader)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLCompileShader, "context = %d, shader = %u", CID(context), shader);
+
+ if (context)
+ {
+ ShaderProgramID shaderPacked = PackParam<ShaderProgramID>(shader);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateCompileShader(context, angle::EntryPoint::GLCompileShader, shaderPacked));
+ if (isCallValid)
+ {
+ context->compileShader(shaderPacked);
+ }
+ ANGLE_CAPTURE_GL(CompileShader, isCallValid, context, shaderPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_CompressedTexImage2D(GLenum target,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLsizei imageSize,
+ const void *data)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLCompressedTexImage2D,
+ "context = %d, target = %s, level = %d, internalformat = %s, width = %d, height = %d, "
+ "border = %d, imageSize = %d, data = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target), level,
+ GLenumToString(GLESEnum::InternalFormat, internalformat), width, height, border,
+ imageSize, (uintptr_t)data);
+
+ if (context)
+ {
+ TextureTarget targetPacked = PackParam<TextureTarget>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateCompressedTexImage2D(
+ context, angle::EntryPoint::GLCompressedTexImage2D, targetPacked,
+ level, internalformat, width, height, border, imageSize, data));
+ if (isCallValid)
+ {
+ context->compressedTexImage2D(targetPacked, level, internalformat, width, height,
+ border, imageSize, data);
+ }
+ ANGLE_CAPTURE_GL(CompressedTexImage2D, isCallValid, context, targetPacked, level,
+ internalformat, width, height, border, imageSize, data);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_CompressedTexSubImage2D(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLCompressedTexSubImage2D,
+ "context = %d, target = %s, level = %d, xoffset = %d, yoffset = %d, width = %d, height = "
+ "%d, format = %s, imageSize = %d, data = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target), level, xoffset, yoffset,
+ width, height, GLenumToString(GLESEnum::InternalFormat, format), imageSize,
+ (uintptr_t)data);
+
+ if (context)
+ {
+ TextureTarget targetPacked = PackParam<TextureTarget>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateCompressedTexSubImage2D(
+ context, angle::EntryPoint::GLCompressedTexSubImage2D, targetPacked,
+ level, xoffset, yoffset, width, height, format, imageSize, data));
+ if (isCallValid)
+ {
+ context->compressedTexSubImage2D(targetPacked, level, xoffset, yoffset, width, height,
+ format, imageSize, data);
+ }
+ ANGLE_CAPTURE_GL(CompressedTexSubImage2D, isCallValid, context, targetPacked, level,
+ xoffset, yoffset, width, height, format, imageSize, data);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_CopyTexImage2D(GLenum target,
+ GLint level,
+ GLenum internalformat,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLint border)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLCopyTexImage2D,
+ "context = %d, target = %s, level = %d, internalformat = %s, x = %d, y = %d, width = %d, "
+ "height = %d, border = %d",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target), level,
+ GLenumToString(GLESEnum::InternalFormat, internalformat), x, y, width, height, border);
+
+ if (context)
+ {
+ TextureTarget targetPacked = PackParam<TextureTarget>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateCopyTexImage2D(context, angle::EntryPoint::GLCopyTexImage2D, targetPacked,
+ level, internalformat, x, y, width, height, border));
+ if (isCallValid)
+ {
+ context->copyTexImage2D(targetPacked, level, internalformat, x, y, width, height,
+ border);
+ }
+ ANGLE_CAPTURE_GL(CopyTexImage2D, isCallValid, context, targetPacked, level, internalformat,
+ x, y, width, height, border);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_CopyTexSubImage2D(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLCopyTexSubImage2D,
+ "context = %d, target = %s, level = %d, xoffset = %d, yoffset = %d, x = %d, y = %d, "
+ "width = %d, height = %d",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target), level, xoffset, yoffset, x,
+ y, width, height);
+
+ if (context)
+ {
+ TextureTarget targetPacked = PackParam<TextureTarget>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateCopyTexSubImage2D(context, angle::EntryPoint::GLCopyTexSubImage2D,
+ targetPacked, level, xoffset, yoffset, x, y, width, height));
+ if (isCallValid)
+ {
+ context->copyTexSubImage2D(targetPacked, level, xoffset, yoffset, x, y, width, height);
+ }
+ ANGLE_CAPTURE_GL(CopyTexSubImage2D, isCallValid, context, targetPacked, level, xoffset,
+ yoffset, x, y, width, height);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+GLuint GL_APIENTRY GL_CreateProgram()
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLCreateProgram, "context = %d", CID(context));
+
+ GLuint returnValue;
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateCreateProgram(context, angle::EntryPoint::GLCreateProgram));
+ if (isCallValid)
+ {
+ returnValue = context->createProgram();
+ }
+ else
+ {
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLCreateProgram, GLuint>();
+ }
+ ANGLE_CAPTURE_GL(CreateProgram, isCallValid, context, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLCreateProgram, GLuint>();
+ }
+ return returnValue;
+}
+
+GLuint GL_APIENTRY GL_CreateShader(GLenum type)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLCreateShader, "context = %d, type = %s", CID(context),
+ GLenumToString(GLESEnum::ShaderType, type));
+
+ GLuint returnValue;
+ if (context)
+ {
+ ShaderType typePacked = PackParam<ShaderType>(type);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateCreateShader(context, angle::EntryPoint::GLCreateShader, typePacked));
+ if (isCallValid)
+ {
+ returnValue = context->createShader(typePacked);
+ }
+ else
+ {
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLCreateShader, GLuint>();
+ }
+ ANGLE_CAPTURE_GL(CreateShader, isCallValid, context, typePacked, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLCreateShader, GLuint>();
+ }
+ return returnValue;
+}
+
+void GL_APIENTRY GL_CullFace(GLenum mode)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLCullFace, "context = %d, mode = %s", CID(context),
+ GLenumToString(GLESEnum::TriangleFace, mode));
+
+ if (context)
+ {
+ CullFaceMode modePacked = PackParam<CullFaceMode>(mode);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateCullFace(context, angle::EntryPoint::GLCullFace, modePacked));
+ if (isCallValid)
+ {
+ context->cullFace(modePacked);
+ }
+ ANGLE_CAPTURE_GL(CullFace, isCallValid, context, modePacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DeleteBuffers(GLsizei n, const GLuint *buffers)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDeleteBuffers, "context = %d, n = %d, buffers = 0x%016" PRIxPTR "",
+ CID(context), n, (uintptr_t)buffers);
+
+ if (context)
+ {
+ const BufferID *buffersPacked = PackParam<const BufferID *>(buffers);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateDeleteBuffers(context, angle::EntryPoint::GLDeleteBuffers, n, buffersPacked));
+ if (isCallValid)
+ {
+ context->deleteBuffers(n, buffersPacked);
+ }
+ ANGLE_CAPTURE_GL(DeleteBuffers, isCallValid, context, n, buffersPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DeleteFramebuffers(GLsizei n, const GLuint *framebuffers)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDeleteFramebuffers, "context = %d, n = %d, framebuffers = 0x%016" PRIxPTR "",
+ CID(context), n, (uintptr_t)framebuffers);
+
+ if (context)
+ {
+ const FramebufferID *framebuffersPacked = PackParam<const FramebufferID *>(framebuffers);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateDeleteFramebuffers(context, angle::EntryPoint::GLDeleteFramebuffers, n,
+ framebuffersPacked));
+ if (isCallValid)
+ {
+ context->deleteFramebuffers(n, framebuffersPacked);
+ }
+ ANGLE_CAPTURE_GL(DeleteFramebuffers, isCallValid, context, n, framebuffersPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DeleteProgram(GLuint program)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDeleteProgram, "context = %d, program = %u", CID(context), program);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateDeleteProgram(context, angle::EntryPoint::GLDeleteProgram, programPacked));
+ if (isCallValid)
+ {
+ context->deleteProgram(programPacked);
+ }
+ ANGLE_CAPTURE_GL(DeleteProgram, isCallValid, context, programPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDeleteRenderbuffers, "context = %d, n = %d, renderbuffers = 0x%016" PRIxPTR "",
+ CID(context), n, (uintptr_t)renderbuffers);
+
+ if (context)
+ {
+ const RenderbufferID *renderbuffersPacked =
+ PackParam<const RenderbufferID *>(renderbuffers);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateDeleteRenderbuffers(context, angle::EntryPoint::GLDeleteRenderbuffers, n,
+ renderbuffersPacked));
+ if (isCallValid)
+ {
+ context->deleteRenderbuffers(n, renderbuffersPacked);
+ }
+ ANGLE_CAPTURE_GL(DeleteRenderbuffers, isCallValid, context, n, renderbuffersPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DeleteShader(GLuint shader)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDeleteShader, "context = %d, shader = %u", CID(context), shader);
+
+ if (context)
+ {
+ ShaderProgramID shaderPacked = PackParam<ShaderProgramID>(shader);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateDeleteShader(context, angle::EntryPoint::GLDeleteShader, shaderPacked));
+ if (isCallValid)
+ {
+ context->deleteShader(shaderPacked);
+ }
+ ANGLE_CAPTURE_GL(DeleteShader, isCallValid, context, shaderPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DeleteTextures(GLsizei n, const GLuint *textures)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDeleteTextures, "context = %d, n = %d, textures = 0x%016" PRIxPTR "",
+ CID(context), n, (uintptr_t)textures);
+
+ if (context)
+ {
+ const TextureID *texturesPacked = PackParam<const TextureID *>(textures);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateDeleteTextures(context, angle::EntryPoint::GLDeleteTextures, n,
+ texturesPacked));
+ if (isCallValid)
+ {
+ context->deleteTextures(n, texturesPacked);
+ }
+ ANGLE_CAPTURE_GL(DeleteTextures, isCallValid, context, n, texturesPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DepthFunc(GLenum func)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDepthFunc, "context = %d, func = %s", CID(context),
+ GLenumToString(GLESEnum::DepthFunction, func));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateDepthFunc(context, angle::EntryPoint::GLDepthFunc, func));
+ if (isCallValid)
+ {
+ context->depthFunc(func);
+ }
+ ANGLE_CAPTURE_GL(DepthFunc, isCallValid, context, func);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DepthMask(GLboolean flag)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDepthMask, "context = %d, flag = %s", CID(context), GLbooleanToString(flag));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateDepthMask(context, angle::EntryPoint::GLDepthMask, flag));
+ if (isCallValid)
+ {
+ context->depthMask(flag);
+ }
+ ANGLE_CAPTURE_GL(DepthMask, isCallValid, context, flag);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DepthRangef(GLfloat n, GLfloat f)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDepthRangef, "context = %d, n = %f, f = %f", CID(context), n, f);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateDepthRangef(context, angle::EntryPoint::GLDepthRangef, n, f));
+ if (isCallValid)
+ {
+ context->depthRangef(n, f);
+ }
+ ANGLE_CAPTURE_GL(DepthRangef, isCallValid, context, n, f);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DetachShader(GLuint program, GLuint shader)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDetachShader, "context = %d, program = %u, shader = %u", CID(context), program,
+ shader);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ ShaderProgramID shaderPacked = PackParam<ShaderProgramID>(shader);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateDetachShader(context, angle::EntryPoint::GLDetachShader,
+ programPacked, shaderPacked));
+ if (isCallValid)
+ {
+ context->detachShader(programPacked, shaderPacked);
+ }
+ ANGLE_CAPTURE_GL(DetachShader, isCallValid, context, programPacked, shaderPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Disable(GLenum cap)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDisable, "context = %d, cap = %s", CID(context),
+ GLenumToString(GLESEnum::EnableCap, cap));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateDisable(context, angle::EntryPoint::GLDisable, cap));
+ if (isCallValid)
+ {
+ context->disable(cap);
+ }
+ ANGLE_CAPTURE_GL(Disable, isCallValid, context, cap);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DisableVertexAttribArray(GLuint index)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDisableVertexAttribArray, "context = %d, index = %u", CID(context), index);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateDisableVertexAttribArray(
+ context, angle::EntryPoint::GLDisableVertexAttribArray, index));
+ if (isCallValid)
+ {
+ context->disableVertexAttribArray(index);
+ }
+ ANGLE_CAPTURE_GL(DisableVertexAttribArray, isCallValid, context, index);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DrawArrays(GLenum mode, GLint first, GLsizei count)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDrawArrays, "context = %d, mode = %s, first = %d, count = %d", CID(context),
+ GLenumToString(GLESEnum::PrimitiveType, mode), first, count);
+
+ if (context)
+ {
+ PrimitiveMode modePacked = PackParam<PrimitiveMode>(mode);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateDrawArrays(context, angle::EntryPoint::GLDrawArrays, modePacked,
+ first, count));
+ if (isCallValid)
+ {
+ context->drawArrays(modePacked, first, count);
+ }
+ ANGLE_CAPTURE_GL(DrawArrays, isCallValid, context, modePacked, first, count);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DrawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDrawElements,
+ "context = %d, mode = %s, count = %d, type = %s, indices = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::PrimitiveType, mode), count,
+ GLenumToString(GLESEnum::DrawElementsType, type), (uintptr_t)indices);
+
+ if (context)
+ {
+ PrimitiveMode modePacked = PackParam<PrimitiveMode>(mode);
+ DrawElementsType typePacked = PackParam<DrawElementsType>(type);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateDrawElements(context, angle::EntryPoint::GLDrawElements,
+ modePacked, count, typePacked, indices));
+ if (isCallValid)
+ {
+ context->drawElements(modePacked, count, typePacked, indices);
+ }
+ ANGLE_CAPTURE_GL(DrawElements, isCallValid, context, modePacked, count, typePacked,
+ indices);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Enable(GLenum cap)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLEnable, "context = %d, cap = %s", CID(context),
+ GLenumToString(GLESEnum::EnableCap, cap));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateEnable(context, angle::EntryPoint::GLEnable, cap));
+ if (isCallValid)
+ {
+ context->enable(cap);
+ }
+ ANGLE_CAPTURE_GL(Enable, isCallValid, context, cap);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_EnableVertexAttribArray(GLuint index)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLEnableVertexAttribArray, "context = %d, index = %u", CID(context), index);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateEnableVertexAttribArray(
+ context, angle::EntryPoint::GLEnableVertexAttribArray, index));
+ if (isCallValid)
+ {
+ context->enableVertexAttribArray(index);
+ }
+ ANGLE_CAPTURE_GL(EnableVertexAttribArray, isCallValid, context, index);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Finish()
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLFinish, "context = %d", CID(context));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() || ValidateFinish(context, angle::EntryPoint::GLFinish));
+ if (isCallValid)
+ {
+ context->finish();
+ }
+ ANGLE_CAPTURE_GL(Finish, isCallValid, context);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Flush()
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLFlush, "context = %d", CID(context));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() || ValidateFlush(context, angle::EntryPoint::GLFlush));
+ if (isCallValid)
+ {
+ context->flush();
+ }
+ ANGLE_CAPTURE_GL(Flush, isCallValid, context);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_FramebufferRenderbuffer(GLenum target,
+ GLenum attachment,
+ GLenum renderbuffertarget,
+ GLuint renderbuffer)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLFramebufferRenderbuffer,
+ "context = %d, target = %s, attachment = %s, renderbuffertarget = %s, renderbuffer = %u",
+ CID(context), GLenumToString(GLESEnum::FramebufferTarget, target),
+ GLenumToString(GLESEnum::FramebufferAttachment, attachment),
+ GLenumToString(GLESEnum::RenderbufferTarget, renderbuffertarget), renderbuffer);
+
+ if (context)
+ {
+ RenderbufferID renderbufferPacked = PackParam<RenderbufferID>(renderbuffer);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateFramebufferRenderbuffer(
+ context, angle::EntryPoint::GLFramebufferRenderbuffer, target,
+ attachment, renderbuffertarget, renderbufferPacked));
+ if (isCallValid)
+ {
+ context->framebufferRenderbuffer(target, attachment, renderbuffertarget,
+ renderbufferPacked);
+ }
+ ANGLE_CAPTURE_GL(FramebufferRenderbuffer, isCallValid, context, target, attachment,
+ renderbuffertarget, renderbufferPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_FramebufferTexture2D(GLenum target,
+ GLenum attachment,
+ GLenum textarget,
+ GLuint texture,
+ GLint level)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLFramebufferTexture2D,
+ "context = %d, target = %s, attachment = %s, textarget = %s, texture = %u, level = %d",
+ CID(context), GLenumToString(GLESEnum::FramebufferTarget, target),
+ GLenumToString(GLESEnum::FramebufferAttachment, attachment),
+ GLenumToString(GLESEnum::TextureTarget, textarget), texture, level);
+
+ if (context)
+ {
+ TextureTarget textargetPacked = PackParam<TextureTarget>(textarget);
+ TextureID texturePacked = PackParam<TextureID>(texture);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateFramebufferTexture2D(
+ context, angle::EntryPoint::GLFramebufferTexture2D, target,
+ attachment, textargetPacked, texturePacked, level));
+ if (isCallValid)
+ {
+ context->framebufferTexture2D(target, attachment, textargetPacked, texturePacked,
+ level);
+ }
+ ANGLE_CAPTURE_GL(FramebufferTexture2D, isCallValid, context, target, attachment,
+ textargetPacked, texturePacked, level);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_FrontFace(GLenum mode)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLFrontFace, "context = %d, mode = %s", CID(context),
+ GLenumToString(GLESEnum::FrontFaceDirection, mode));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateFrontFace(context, angle::EntryPoint::GLFrontFace, mode));
+ if (isCallValid)
+ {
+ context->frontFace(mode);
+ }
+ ANGLE_CAPTURE_GL(FrontFace, isCallValid, context, mode);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GenBuffers(GLsizei n, GLuint *buffers)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGenBuffers, "context = %d, n = %d, buffers = 0x%016" PRIxPTR "", CID(context),
+ n, (uintptr_t)buffers);
+
+ if (context)
+ {
+ BufferID *buffersPacked = PackParam<BufferID *>(buffers);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGenBuffers(context, angle::EntryPoint::GLGenBuffers, n, buffersPacked));
+ if (isCallValid)
+ {
+ context->genBuffers(n, buffersPacked);
+ }
+ ANGLE_CAPTURE_GL(GenBuffers, isCallValid, context, n, buffersPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GenFramebuffers(GLsizei n, GLuint *framebuffers)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGenFramebuffers, "context = %d, n = %d, framebuffers = 0x%016" PRIxPTR "",
+ CID(context), n, (uintptr_t)framebuffers);
+
+ if (context)
+ {
+ FramebufferID *framebuffersPacked = PackParam<FramebufferID *>(framebuffers);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGenFramebuffers(context, angle::EntryPoint::GLGenFramebuffers,
+ n, framebuffersPacked));
+ if (isCallValid)
+ {
+ context->genFramebuffers(n, framebuffersPacked);
+ }
+ ANGLE_CAPTURE_GL(GenFramebuffers, isCallValid, context, n, framebuffersPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GenRenderbuffers(GLsizei n, GLuint *renderbuffers)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGenRenderbuffers, "context = %d, n = %d, renderbuffers = 0x%016" PRIxPTR "",
+ CID(context), n, (uintptr_t)renderbuffers);
+
+ if (context)
+ {
+ RenderbufferID *renderbuffersPacked = PackParam<RenderbufferID *>(renderbuffers);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGenRenderbuffers(context, angle::EntryPoint::GLGenRenderbuffers,
+ n, renderbuffersPacked));
+ if (isCallValid)
+ {
+ context->genRenderbuffers(n, renderbuffersPacked);
+ }
+ ANGLE_CAPTURE_GL(GenRenderbuffers, isCallValid, context, n, renderbuffersPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GenTextures(GLsizei n, GLuint *textures)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGenTextures, "context = %d, n = %d, textures = 0x%016" PRIxPTR "",
+ CID(context), n, (uintptr_t)textures);
+
+ if (context)
+ {
+ TextureID *texturesPacked = PackParam<TextureID *>(textures);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGenTextures(context, angle::EntryPoint::GLGenTextures, n, texturesPacked));
+ if (isCallValid)
+ {
+ context->genTextures(n, texturesPacked);
+ }
+ ANGLE_CAPTURE_GL(GenTextures, isCallValid, context, n, texturesPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GenerateMipmap(GLenum target)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGenerateMipmap, "context = %d, target = %s", CID(context),
+ GLenumToString(GLESEnum::TextureTarget, target));
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGenerateMipmap(context, angle::EntryPoint::GLGenerateMipmap, targetPacked));
+ if (isCallValid)
+ {
+ context->generateMipmap(targetPacked);
+ }
+ ANGLE_CAPTURE_GL(GenerateMipmap, isCallValid, context, targetPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetActiveAttrib(GLuint program,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *size,
+ GLenum *type,
+ GLchar *name)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetActiveAttrib,
+ "context = %d, program = %u, index = %u, bufSize = %d, length = 0x%016" PRIxPTR
+ ", size = 0x%016" PRIxPTR ", type = 0x%016" PRIxPTR ", name = 0x%016" PRIxPTR "",
+ CID(context), program, index, bufSize, (uintptr_t)length, (uintptr_t)size,
+ (uintptr_t)type, (uintptr_t)name);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetActiveAttrib(context, angle::EntryPoint::GLGetActiveAttrib, programPacked,
+ index, bufSize, length, size, type, name));
+ if (isCallValid)
+ {
+ context->getActiveAttrib(programPacked, index, bufSize, length, size, type, name);
+ }
+ ANGLE_CAPTURE_GL(GetActiveAttrib, isCallValid, context, programPacked, index, bufSize,
+ length, size, type, name);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetActiveUniform(GLuint program,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *size,
+ GLenum *type,
+ GLchar *name)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetActiveUniform,
+ "context = %d, program = %u, index = %u, bufSize = %d, length = 0x%016" PRIxPTR
+ ", size = 0x%016" PRIxPTR ", type = 0x%016" PRIxPTR ", name = 0x%016" PRIxPTR "",
+ CID(context), program, index, bufSize, (uintptr_t)length, (uintptr_t)size,
+ (uintptr_t)type, (uintptr_t)name);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetActiveUniform(context, angle::EntryPoint::GLGetActiveUniform, programPacked,
+ index, bufSize, length, size, type, name));
+ if (isCallValid)
+ {
+ context->getActiveUniform(programPacked, index, bufSize, length, size, type, name);
+ }
+ ANGLE_CAPTURE_GL(GetActiveUniform, isCallValid, context, programPacked, index, bufSize,
+ length, size, type, name);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetAttachedShaders(GLuint program,
+ GLsizei maxCount,
+ GLsizei *count,
+ GLuint *shaders)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetAttachedShaders,
+ "context = %d, program = %u, maxCount = %d, count = 0x%016" PRIxPTR
+ ", shaders = 0x%016" PRIxPTR "",
+ CID(context), program, maxCount, (uintptr_t)count, (uintptr_t)shaders);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ ShaderProgramID *shadersPacked = PackParam<ShaderProgramID *>(shaders);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetAttachedShaders(context, angle::EntryPoint::GLGetAttachedShaders,
+ programPacked, maxCount, count, shadersPacked));
+ if (isCallValid)
+ {
+ context->getAttachedShaders(programPacked, maxCount, count, shadersPacked);
+ }
+ ANGLE_CAPTURE_GL(GetAttachedShaders, isCallValid, context, programPacked, maxCount, count,
+ shadersPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+GLint GL_APIENTRY GL_GetAttribLocation(GLuint program, const GLchar *name)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetAttribLocation, "context = %d, program = %u, name = 0x%016" PRIxPTR "",
+ CID(context), program, (uintptr_t)name);
+
+ GLint returnValue;
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetAttribLocation(context, angle::EntryPoint::GLGetAttribLocation,
+ programPacked, name));
+ if (isCallValid)
+ {
+ returnValue = context->getAttribLocation(programPacked, name);
+ }
+ else
+ {
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLGetAttribLocation, GLint>();
+ }
+ ANGLE_CAPTURE_GL(GetAttribLocation, isCallValid, context, programPacked, name, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLGetAttribLocation, GLint>();
+ }
+ return returnValue;
+}
+
+void GL_APIENTRY GL_GetBooleanv(GLenum pname, GLboolean *data)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetBooleanv, "context = %d, pname = %s, data = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::GetPName, pname), (uintptr_t)data);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetBooleanv(context, angle::EntryPoint::GLGetBooleanv, pname, data));
+ if (isCallValid)
+ {
+ context->getBooleanv(pname, data);
+ }
+ ANGLE_CAPTURE_GL(GetBooleanv, isCallValid, context, pname, data);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetBufferParameteriv(GLenum target, GLenum pname, GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetBufferParameteriv,
+ "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::BufferTargetARB, target),
+ GLenumToString(GLESEnum::AllEnums, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ BufferBinding targetPacked = PackParam<BufferBinding>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetBufferParameteriv(context, angle::EntryPoint::GLGetBufferParameteriv,
+ targetPacked, pname, params));
+ if (isCallValid)
+ {
+ context->getBufferParameteriv(targetPacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetBufferParameteriv, isCallValid, context, targetPacked, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+GLenum GL_APIENTRY GL_GetError()
+{
+ Context *context = GetGlobalContext();
+ EVENT(context, GLGetError, "context = %d", CID(context));
+
+ GLenum returnValue;
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() || ValidateGetError(context, angle::EntryPoint::GLGetError));
+ if (isCallValid)
+ {
+ returnValue = context->getError();
+ }
+ else
+ {
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLGetError, GLenum>();
+ }
+ ANGLE_CAPTURE_GL(GetError, isCallValid, context, returnValue);
+ }
+ else
+ {
+
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLGetError, GLenum>();
+ }
+ return returnValue;
+}
+
+void GL_APIENTRY GL_GetFloatv(GLenum pname, GLfloat *data)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetFloatv, "context = %d, pname = %s, data = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::GetPName, pname), (uintptr_t)data);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetFloatv(context, angle::EntryPoint::GLGetFloatv, pname, data));
+ if (isCallValid)
+ {
+ context->getFloatv(pname, data);
+ }
+ ANGLE_CAPTURE_GL(GetFloatv, isCallValid, context, pname, data);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetFramebufferAttachmentParameteriv(GLenum target,
+ GLenum attachment,
+ GLenum pname,
+ GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetFramebufferAttachmentParameteriv,
+ "context = %d, target = %s, attachment = %s, pname = %s, params = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::FramebufferTarget, target),
+ GLenumToString(GLESEnum::FramebufferAttachment, attachment),
+ GLenumToString(GLESEnum::FramebufferAttachmentParameterName, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetFramebufferAttachmentParameteriv(
+ context, angle::EntryPoint::GLGetFramebufferAttachmentParameteriv,
+ target, attachment, pname, params));
+ if (isCallValid)
+ {
+ context->getFramebufferAttachmentParameteriv(target, attachment, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetFramebufferAttachmentParameteriv, isCallValid, context, target,
+ attachment, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetIntegerv(GLenum pname, GLint *data)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetIntegerv, "context = %d, pname = %s, data = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::GetPName, pname), (uintptr_t)data);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetIntegerv(context, angle::EntryPoint::GLGetIntegerv, pname, data));
+ if (isCallValid)
+ {
+ context->getIntegerv(pname, data);
+ }
+ ANGLE_CAPTURE_GL(GetIntegerv, isCallValid, context, pname, data);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetProgramInfoLog(GLuint program,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *infoLog)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetProgramInfoLog,
+ "context = %d, program = %u, bufSize = %d, length = 0x%016" PRIxPTR
+ ", infoLog = 0x%016" PRIxPTR "",
+ CID(context), program, bufSize, (uintptr_t)length, (uintptr_t)infoLog);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetProgramInfoLog(context, angle::EntryPoint::GLGetProgramInfoLog,
+ programPacked, bufSize, length, infoLog));
+ if (isCallValid)
+ {
+ context->getProgramInfoLog(programPacked, bufSize, length, infoLog);
+ }
+ ANGLE_CAPTURE_GL(GetProgramInfoLog, isCallValid, context, programPacked, bufSize, length,
+ infoLog);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetProgramiv(GLuint program, GLenum pname, GLint *params)
+{
+ Context *context = GetGlobalContext();
+ EVENT(context, GLGetProgramiv,
+ "context = %d, program = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ program, GLenumToString(GLESEnum::ProgramPropertyARB, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetProgramiv(context, angle::EntryPoint::GLGetProgramiv,
+ programPacked, pname, params));
+ if (isCallValid)
+ {
+ context->getProgramiv(programPacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetProgramiv, isCallValid, context, programPacked, pname, params);
+ }
+ else
+ {}
+}
+
+void GL_APIENTRY GL_GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetRenderbufferParameteriv,
+ "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::RenderbufferTarget, target),
+ GLenumToString(GLESEnum::RenderbufferParameterName, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetRenderbufferParameteriv(
+ context, angle::EntryPoint::GLGetRenderbufferParameteriv, target, pname, params));
+ if (isCallValid)
+ {
+ context->getRenderbufferParameteriv(target, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetRenderbufferParameteriv, isCallValid, context, target, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetShaderInfoLog(GLuint shader,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *infoLog)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetShaderInfoLog,
+ "context = %d, shader = %u, bufSize = %d, length = 0x%016" PRIxPTR
+ ", infoLog = 0x%016" PRIxPTR "",
+ CID(context), shader, bufSize, (uintptr_t)length, (uintptr_t)infoLog);
+
+ if (context)
+ {
+ ShaderProgramID shaderPacked = PackParam<ShaderProgramID>(shader);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetShaderInfoLog(context, angle::EntryPoint::GLGetShaderInfoLog,
+ shaderPacked, bufSize, length, infoLog));
+ if (isCallValid)
+ {
+ context->getShaderInfoLog(shaderPacked, bufSize, length, infoLog);
+ }
+ ANGLE_CAPTURE_GL(GetShaderInfoLog, isCallValid, context, shaderPacked, bufSize, length,
+ infoLog);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetShaderPrecisionFormat(GLenum shadertype,
+ GLenum precisiontype,
+ GLint *range,
+ GLint *precision)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetShaderPrecisionFormat,
+ "context = %d, shadertype = %s, precisiontype = %s, range = 0x%016" PRIxPTR
+ ", precision = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::ShaderType, shadertype),
+ GLenumToString(GLESEnum::PrecisionType, precisiontype), (uintptr_t)range,
+ (uintptr_t)precision);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetShaderPrecisionFormat(
+ context, angle::EntryPoint::GLGetShaderPrecisionFormat, shadertype,
+ precisiontype, range, precision));
+ if (isCallValid)
+ {
+ context->getShaderPrecisionFormat(shadertype, precisiontype, range, precision);
+ }
+ ANGLE_CAPTURE_GL(GetShaderPrecisionFormat, isCallValid, context, shadertype, precisiontype,
+ range, precision);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetShaderSource(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetShaderSource,
+ "context = %d, shader = %u, bufSize = %d, length = 0x%016" PRIxPTR
+ ", source = 0x%016" PRIxPTR "",
+ CID(context), shader, bufSize, (uintptr_t)length, (uintptr_t)source);
+
+ if (context)
+ {
+ ShaderProgramID shaderPacked = PackParam<ShaderProgramID>(shader);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetShaderSource(context, angle::EntryPoint::GLGetShaderSource,
+ shaderPacked, bufSize, length, source));
+ if (isCallValid)
+ {
+ context->getShaderSource(shaderPacked, bufSize, length, source);
+ }
+ ANGLE_CAPTURE_GL(GetShaderSource, isCallValid, context, shaderPacked, bufSize, length,
+ source);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetShaderiv(GLuint shader, GLenum pname, GLint *params)
+{
+ Context *context = GetGlobalContext();
+ EVENT(context, GLGetShaderiv,
+ "context = %d, shader = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context), shader,
+ GLenumToString(GLESEnum::ShaderParameterName, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ ShaderProgramID shaderPacked = PackParam<ShaderProgramID>(shader);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetShaderiv(context, angle::EntryPoint::GLGetShaderiv,
+ shaderPacked, pname, params));
+ if (isCallValid)
+ {
+ context->getShaderiv(shaderPacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetShaderiv, isCallValid, context, shaderPacked, pname, params);
+ }
+ else
+ {}
+}
+
+const GLubyte *GL_APIENTRY GL_GetString(GLenum name)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetString, "context = %d, name = %s", CID(context),
+ GLenumToString(GLESEnum::StringName, name));
+
+ const GLubyte *returnValue;
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetString(context, angle::EntryPoint::GLGetString, name));
+ if (isCallValid)
+ {
+ returnValue = context->getString(name);
+ }
+ else
+ {
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLGetString, const GLubyte *>();
+ }
+ ANGLE_CAPTURE_GL(GetString, isCallValid, context, name, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLGetString, const GLubyte *>();
+ }
+ return returnValue;
+}
+
+void GL_APIENTRY GL_GetTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetTexParameterfv,
+ "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::TextureTarget, target),
+ GLenumToString(GLESEnum::GetTextureParameter, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetTexParameterfv(context, angle::EntryPoint::GLGetTexParameterfv,
+ targetPacked, pname, params));
+ if (isCallValid)
+ {
+ context->getTexParameterfv(targetPacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetTexParameterfv, isCallValid, context, targetPacked, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetTexParameteriv(GLenum target, GLenum pname, GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetTexParameteriv,
+ "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::TextureTarget, target),
+ GLenumToString(GLESEnum::GetTextureParameter, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetTexParameteriv(context, angle::EntryPoint::GLGetTexParameteriv,
+ targetPacked, pname, params));
+ if (isCallValid)
+ {
+ context->getTexParameteriv(targetPacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetTexParameteriv, isCallValid, context, targetPacked, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+GLint GL_APIENTRY GL_GetUniformLocation(GLuint program, const GLchar *name)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetUniformLocation, "context = %d, program = %u, name = 0x%016" PRIxPTR "",
+ CID(context), program, (uintptr_t)name);
+
+ GLint returnValue;
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetUniformLocation(context, angle::EntryPoint::GLGetUniformLocation,
+ programPacked, name));
+ if (isCallValid)
+ {
+ returnValue = context->getUniformLocation(programPacked, name);
+ }
+ else
+ {
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLGetUniformLocation, GLint>();
+ }
+ ANGLE_CAPTURE_GL(GetUniformLocation, isCallValid, context, programPacked, name,
+ returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLGetUniformLocation, GLint>();
+ }
+ return returnValue;
+}
+
+void GL_APIENTRY GL_GetUniformfv(GLuint program, GLint location, GLfloat *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetUniformfv,
+ "context = %d, program = %u, location = %d, params = 0x%016" PRIxPTR "", CID(context),
+ program, location, (uintptr_t)params);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetUniformfv(context, angle::EntryPoint::GLGetUniformfv,
+ programPacked, locationPacked, params));
+ if (isCallValid)
+ {
+ context->getUniformfv(programPacked, locationPacked, params);
+ }
+ ANGLE_CAPTURE_GL(GetUniformfv, isCallValid, context, programPacked, locationPacked, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetUniformiv(GLuint program, GLint location, GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetUniformiv,
+ "context = %d, program = %u, location = %d, params = 0x%016" PRIxPTR "", CID(context),
+ program, location, (uintptr_t)params);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetUniformiv(context, angle::EntryPoint::GLGetUniformiv,
+ programPacked, locationPacked, params));
+ if (isCallValid)
+ {
+ context->getUniformiv(programPacked, locationPacked, params);
+ }
+ ANGLE_CAPTURE_GL(GetUniformiv, isCallValid, context, programPacked, locationPacked, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetVertexAttribPointerv(GLuint index, GLenum pname, void **pointer)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetVertexAttribPointerv,
+ "context = %d, index = %u, pname = %s, pointer = 0x%016" PRIxPTR "", CID(context), index,
+ GLenumToString(GLESEnum::AllEnums, pname), (uintptr_t)pointer);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetVertexAttribPointerv(context, angle::EntryPoint::GLGetVertexAttribPointerv,
+ index, pname, pointer));
+ if (isCallValid)
+ {
+ context->getVertexAttribPointerv(index, pname, pointer);
+ }
+ ANGLE_CAPTURE_GL(GetVertexAttribPointerv, isCallValid, context, index, pname, pointer);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetVertexAttribfv,
+ "context = %d, index = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context), index,
+ GLenumToString(GLESEnum::AllEnums, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetVertexAttribfv(context, angle::EntryPoint::GLGetVertexAttribfv, index,
+ pname, params));
+ if (isCallValid)
+ {
+ context->getVertexAttribfv(index, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetVertexAttribfv, isCallValid, context, index, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetVertexAttribiv(GLuint index, GLenum pname, GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetVertexAttribiv,
+ "context = %d, index = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context), index,
+ GLenumToString(GLESEnum::AllEnums, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetVertexAttribiv(context, angle::EntryPoint::GLGetVertexAttribiv, index,
+ pname, params));
+ if (isCallValid)
+ {
+ context->getVertexAttribiv(index, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetVertexAttribiv, isCallValid, context, index, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Hint(GLenum target, GLenum mode)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLHint, "context = %d, target = %s, mode = %s", CID(context),
+ GLenumToString(GLESEnum::HintTarget, target), GLenumToString(GLESEnum::HintMode, mode));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateHint(context, angle::EntryPoint::GLHint, target, mode));
+ if (isCallValid)
+ {
+ context->hint(target, mode);
+ }
+ ANGLE_CAPTURE_GL(Hint, isCallValid, context, target, mode);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+GLboolean GL_APIENTRY GL_IsBuffer(GLuint buffer)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLIsBuffer, "context = %d, buffer = %u", CID(context), buffer);
+
+ GLboolean returnValue;
+ if (context)
+ {
+ BufferID bufferPacked = PackParam<BufferID>(buffer);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateIsBuffer(context, angle::EntryPoint::GLIsBuffer, bufferPacked));
+ if (isCallValid)
+ {
+ returnValue = context->isBuffer(bufferPacked);
+ }
+ else
+ {
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsBuffer, GLboolean>();
+ }
+ ANGLE_CAPTURE_GL(IsBuffer, isCallValid, context, bufferPacked, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsBuffer, GLboolean>();
+ }
+ return returnValue;
+}
+
+GLboolean GL_APIENTRY GL_IsEnabled(GLenum cap)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLIsEnabled, "context = %d, cap = %s", CID(context),
+ GLenumToString(GLESEnum::EnableCap, cap));
+
+ GLboolean returnValue;
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateIsEnabled(context, angle::EntryPoint::GLIsEnabled, cap));
+ if (isCallValid)
+ {
+ returnValue = context->isEnabled(cap);
+ }
+ else
+ {
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsEnabled, GLboolean>();
+ }
+ ANGLE_CAPTURE_GL(IsEnabled, isCallValid, context, cap, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsEnabled, GLboolean>();
+ }
+ return returnValue;
+}
+
+GLboolean GL_APIENTRY GL_IsFramebuffer(GLuint framebuffer)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLIsFramebuffer, "context = %d, framebuffer = %u", CID(context), framebuffer);
+
+ GLboolean returnValue;
+ if (context)
+ {
+ FramebufferID framebufferPacked = PackParam<FramebufferID>(framebuffer);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateIsFramebuffer(context, angle::EntryPoint::GLIsFramebuffer, framebufferPacked));
+ if (isCallValid)
+ {
+ returnValue = context->isFramebuffer(framebufferPacked);
+ }
+ else
+ {
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsFramebuffer, GLboolean>();
+ }
+ ANGLE_CAPTURE_GL(IsFramebuffer, isCallValid, context, framebufferPacked, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsFramebuffer, GLboolean>();
+ }
+ return returnValue;
+}
+
+GLboolean GL_APIENTRY GL_IsProgram(GLuint program)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLIsProgram, "context = %d, program = %u", CID(context), program);
+
+ GLboolean returnValue;
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateIsProgram(context, angle::EntryPoint::GLIsProgram, programPacked));
+ if (isCallValid)
+ {
+ returnValue = context->isProgram(programPacked);
+ }
+ else
+ {
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsProgram, GLboolean>();
+ }
+ ANGLE_CAPTURE_GL(IsProgram, isCallValid, context, programPacked, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsProgram, GLboolean>();
+ }
+ return returnValue;
+}
+
+GLboolean GL_APIENTRY GL_IsRenderbuffer(GLuint renderbuffer)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLIsRenderbuffer, "context = %d, renderbuffer = %u", CID(context), renderbuffer);
+
+ GLboolean returnValue;
+ if (context)
+ {
+ RenderbufferID renderbufferPacked = PackParam<RenderbufferID>(renderbuffer);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateIsRenderbuffer(context, angle::EntryPoint::GLIsRenderbuffer,
+ renderbufferPacked));
+ if (isCallValid)
+ {
+ returnValue = context->isRenderbuffer(renderbufferPacked);
+ }
+ else
+ {
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsRenderbuffer, GLboolean>();
+ }
+ ANGLE_CAPTURE_GL(IsRenderbuffer, isCallValid, context, renderbufferPacked, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsRenderbuffer, GLboolean>();
+ }
+ return returnValue;
+}
+
+GLboolean GL_APIENTRY GL_IsShader(GLuint shader)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLIsShader, "context = %d, shader = %u", CID(context), shader);
+
+ GLboolean returnValue;
+ if (context)
+ {
+ ShaderProgramID shaderPacked = PackParam<ShaderProgramID>(shader);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateIsShader(context, angle::EntryPoint::GLIsShader, shaderPacked));
+ if (isCallValid)
+ {
+ returnValue = context->isShader(shaderPacked);
+ }
+ else
+ {
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsShader, GLboolean>();
+ }
+ ANGLE_CAPTURE_GL(IsShader, isCallValid, context, shaderPacked, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsShader, GLboolean>();
+ }
+ return returnValue;
+}
+
+GLboolean GL_APIENTRY GL_IsTexture(GLuint texture)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLIsTexture, "context = %d, texture = %u", CID(context), texture);
+
+ GLboolean returnValue;
+ if (context)
+ {
+ TextureID texturePacked = PackParam<TextureID>(texture);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateIsTexture(context, angle::EntryPoint::GLIsTexture, texturePacked));
+ if (isCallValid)
+ {
+ returnValue = context->isTexture(texturePacked);
+ }
+ else
+ {
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsTexture, GLboolean>();
+ }
+ ANGLE_CAPTURE_GL(IsTexture, isCallValid, context, texturePacked, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsTexture, GLboolean>();
+ }
+ return returnValue;
+}
+
+void GL_APIENTRY GL_LineWidth(GLfloat width)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLLineWidth, "context = %d, width = %f", CID(context), width);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateLineWidth(context, angle::EntryPoint::GLLineWidth, width));
+ if (isCallValid)
+ {
+ context->lineWidth(width);
+ }
+ ANGLE_CAPTURE_GL(LineWidth, isCallValid, context, width);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_LinkProgram(GLuint program)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLLinkProgram, "context = %d, program = %u", CID(context), program);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateLinkProgram(context, angle::EntryPoint::GLLinkProgram, programPacked));
+ if (isCallValid)
+ {
+ context->linkProgram(programPacked);
+ }
+ ANGLE_CAPTURE_GL(LinkProgram, isCallValid, context, programPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_PixelStorei(GLenum pname, GLint param)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLPixelStorei, "context = %d, pname = %s, param = %d", CID(context),
+ GLenumToString(GLESEnum::PixelStoreParameter, pname), param);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidatePixelStorei(context, angle::EntryPoint::GLPixelStorei, pname, param));
+ if (isCallValid)
+ {
+ context->pixelStorei(pname, param);
+ }
+ ANGLE_CAPTURE_GL(PixelStorei, isCallValid, context, pname, param);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_PolygonOffset(GLfloat factor, GLfloat units)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLPolygonOffset, "context = %d, factor = %f, units = %f", CID(context), factor,
+ units);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidatePolygonOffset(context, angle::EntryPoint::GLPolygonOffset, factor, units));
+ if (isCallValid)
+ {
+ context->polygonOffset(factor, units);
+ }
+ ANGLE_CAPTURE_GL(PolygonOffset, isCallValid, context, factor, units);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ReadPixels(GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ void *pixels)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLReadPixels,
+ "context = %d, x = %d, y = %d, width = %d, height = %d, format = %s, type = %s, pixels = "
+ "0x%016" PRIxPTR "",
+ CID(context), x, y, width, height, GLenumToString(GLESEnum::PixelFormat, format),
+ GLenumToString(GLESEnum::PixelType, type), (uintptr_t)pixels);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateReadPixels(context, angle::EntryPoint::GLReadPixels, x, y,
+ width, height, format, type, pixels));
+ if (isCallValid)
+ {
+ context->readPixels(x, y, width, height, format, type, pixels);
+ }
+ ANGLE_CAPTURE_GL(ReadPixels, isCallValid, context, x, y, width, height, format, type,
+ pixels);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ReleaseShaderCompiler()
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLReleaseShaderCompiler, "context = %d", CID(context));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateReleaseShaderCompiler(context, angle::EntryPoint::GLReleaseShaderCompiler));
+ if (isCallValid)
+ {
+ context->releaseShaderCompiler();
+ }
+ ANGLE_CAPTURE_GL(ReleaseShaderCompiler, isCallValid, context);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_RenderbufferStorage(GLenum target,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLRenderbufferStorage,
+ "context = %d, target = %s, internalformat = %s, width = %d, height = %d", CID(context),
+ GLenumToString(GLESEnum::RenderbufferTarget, target),
+ GLenumToString(GLESEnum::InternalFormat, internalformat), width, height);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateRenderbufferStorage(context, angle::EntryPoint::GLRenderbufferStorage, target,
+ internalformat, width, height));
+ if (isCallValid)
+ {
+ context->renderbufferStorage(target, internalformat, width, height);
+ }
+ ANGLE_CAPTURE_GL(RenderbufferStorage, isCallValid, context, target, internalformat, width,
+ height);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_SampleCoverage(GLfloat value, GLboolean invert)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLSampleCoverage, "context = %d, value = %f, invert = %s", CID(context), value,
+ GLbooleanToString(invert));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateSampleCoverage(context, angle::EntryPoint::GLSampleCoverage, value, invert));
+ if (isCallValid)
+ {
+ context->sampleCoverage(value, invert);
+ }
+ ANGLE_CAPTURE_GL(SampleCoverage, isCallValid, context, value, invert);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Scissor(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLScissor, "context = %d, x = %d, y = %d, width = %d, height = %d", CID(context),
+ x, y, width, height);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateScissor(context, angle::EntryPoint::GLScissor, x, y, width, height));
+ if (isCallValid)
+ {
+ context->scissor(x, y, width, height);
+ }
+ ANGLE_CAPTURE_GL(Scissor, isCallValid, context, x, y, width, height);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ShaderBinary(GLsizei count,
+ const GLuint *shaders,
+ GLenum binaryFormat,
+ const void *binary,
+ GLsizei length)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLShaderBinary,
+ "context = %d, count = %d, shaders = 0x%016" PRIxPTR
+ ", binaryFormat = %s, binary = 0x%016" PRIxPTR ", length = %d",
+ CID(context), count, (uintptr_t)shaders,
+ GLenumToString(GLESEnum::ShaderBinaryFormat, binaryFormat), (uintptr_t)binary, length);
+
+ if (context)
+ {
+ const ShaderProgramID *shadersPacked = PackParam<const ShaderProgramID *>(shaders);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateShaderBinary(context, angle::EntryPoint::GLShaderBinary, count,
+ shadersPacked, binaryFormat, binary, length));
+ if (isCallValid)
+ {
+ context->shaderBinary(count, shadersPacked, binaryFormat, binary, length);
+ }
+ ANGLE_CAPTURE_GL(ShaderBinary, isCallValid, context, count, shadersPacked, binaryFormat,
+ binary, length);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ShaderSource(GLuint shader,
+ GLsizei count,
+ const GLchar *const *string,
+ const GLint *length)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLShaderSource,
+ "context = %d, shader = %u, count = %d, string = 0x%016" PRIxPTR
+ ", length = 0x%016" PRIxPTR "",
+ CID(context), shader, count, (uintptr_t)string, (uintptr_t)length);
+
+ if (context)
+ {
+ ShaderProgramID shaderPacked = PackParam<ShaderProgramID>(shader);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateShaderSource(context, angle::EntryPoint::GLShaderSource,
+ shaderPacked, count, string, length));
+ if (isCallValid)
+ {
+ context->shaderSource(shaderPacked, count, string, length);
+ }
+ ANGLE_CAPTURE_GL(ShaderSource, isCallValid, context, shaderPacked, count, string, length);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_StencilFunc(GLenum func, GLint ref, GLuint mask)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLStencilFunc, "context = %d, func = %s, ref = %d, mask = %u", CID(context),
+ GLenumToString(GLESEnum::StencilFunction, func), ref, mask);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateStencilFunc(context, angle::EntryPoint::GLStencilFunc, func, ref, mask));
+ if (isCallValid)
+ {
+ context->stencilFunc(func, ref, mask);
+ }
+ ANGLE_CAPTURE_GL(StencilFunc, isCallValid, context, func, ref, mask);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLStencilFuncSeparate, "context = %d, face = %s, func = %s, ref = %d, mask = %u",
+ CID(context), GLenumToString(GLESEnum::TriangleFace, face),
+ GLenumToString(GLESEnum::StencilFunction, func), ref, mask);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateStencilFuncSeparate(context, angle::EntryPoint::GLStencilFuncSeparate, face,
+ func, ref, mask));
+ if (isCallValid)
+ {
+ context->stencilFuncSeparate(face, func, ref, mask);
+ }
+ ANGLE_CAPTURE_GL(StencilFuncSeparate, isCallValid, context, face, func, ref, mask);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_StencilMask(GLuint mask)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLStencilMask, "context = %d, mask = %u", CID(context), mask);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateStencilMask(context, angle::EntryPoint::GLStencilMask, mask));
+ if (isCallValid)
+ {
+ context->stencilMask(mask);
+ }
+ ANGLE_CAPTURE_GL(StencilMask, isCallValid, context, mask);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_StencilMaskSeparate(GLenum face, GLuint mask)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLStencilMaskSeparate, "context = %d, face = %s, mask = %u", CID(context),
+ GLenumToString(GLESEnum::TriangleFace, face), mask);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateStencilMaskSeparate(
+ context, angle::EntryPoint::GLStencilMaskSeparate, face, mask));
+ if (isCallValid)
+ {
+ context->stencilMaskSeparate(face, mask);
+ }
+ ANGLE_CAPTURE_GL(StencilMaskSeparate, isCallValid, context, face, mask);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_StencilOp(GLenum fail, GLenum zfail, GLenum zpass)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLStencilOp, "context = %d, fail = %s, zfail = %s, zpass = %s", CID(context),
+ GLenumToString(GLESEnum::StencilOp, fail), GLenumToString(GLESEnum::StencilOp, zfail),
+ GLenumToString(GLESEnum::StencilOp, zpass));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateStencilOp(context, angle::EntryPoint::GLStencilOp, fail, zfail, zpass));
+ if (isCallValid)
+ {
+ context->stencilOp(fail, zfail, zpass);
+ }
+ ANGLE_CAPTURE_GL(StencilOp, isCallValid, context, fail, zfail, zpass);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_StencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLStencilOpSeparate,
+ "context = %d, face = %s, sfail = %s, dpfail = %s, dppass = %s", CID(context),
+ GLenumToString(GLESEnum::TriangleFace, face), GLenumToString(GLESEnum::StencilOp, sfail),
+ GLenumToString(GLESEnum::StencilOp, dpfail), GLenumToString(GLESEnum::StencilOp, dppass));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateStencilOpSeparate(context, angle::EntryPoint::GLStencilOpSeparate, face, sfail,
+ dpfail, dppass));
+ if (isCallValid)
+ {
+ context->stencilOpSeparate(face, sfail, dpfail, dppass);
+ }
+ ANGLE_CAPTURE_GL(StencilOpSeparate, isCallValid, context, face, sfail, dpfail, dppass);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexImage2D(GLenum target,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexImage2D,
+ "context = %d, target = %s, level = %d, internalformat = %d, width = %d, height = %d, "
+ "border = %d, format = %s, type = %s, pixels = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target), level, internalformat,
+ width, height, border, GLenumToString(GLESEnum::PixelFormat, format),
+ GLenumToString(GLESEnum::PixelType, type), (uintptr_t)pixels);
+
+ if (context)
+ {
+ TextureTarget targetPacked = PackParam<TextureTarget>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateTexImage2D(context, angle::EntryPoint::GLTexImage2D, targetPacked, level,
+ internalformat, width, height, border, format, type, pixels));
+ if (isCallValid)
+ {
+ context->texImage2D(targetPacked, level, internalformat, width, height, border, format,
+ type, pixels);
+ }
+ ANGLE_CAPTURE_GL(TexImage2D, isCallValid, context, targetPacked, level, internalformat,
+ width, height, border, format, type, pixels);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexParameterf(GLenum target, GLenum pname, GLfloat param)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexParameterf, "context = %d, target = %s, pname = %s, param = %f",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target),
+ GLenumToString(GLESEnum::TextureParameterName, pname), param);
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateTexParameterf(context, angle::EntryPoint::GLTexParameterf,
+ targetPacked, pname, param));
+ if (isCallValid)
+ {
+ context->texParameterf(targetPacked, pname, param);
+ }
+ ANGLE_CAPTURE_GL(TexParameterf, isCallValid, context, targetPacked, pname, param);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexParameterfv,
+ "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::TextureTarget, target),
+ GLenumToString(GLESEnum::TextureParameterName, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateTexParameterfv(context, angle::EntryPoint::GLTexParameterfv,
+ targetPacked, pname, params));
+ if (isCallValid)
+ {
+ context->texParameterfv(targetPacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(TexParameterfv, isCallValid, context, targetPacked, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexParameteri(GLenum target, GLenum pname, GLint param)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexParameteri, "context = %d, target = %s, pname = %s, param = %d",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target),
+ GLenumToString(GLESEnum::TextureParameterName, pname), param);
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateTexParameteri(context, angle::EntryPoint::GLTexParameteri,
+ targetPacked, pname, param));
+ if (isCallValid)
+ {
+ context->texParameteri(targetPacked, pname, param);
+ }
+ ANGLE_CAPTURE_GL(TexParameteri, isCallValid, context, targetPacked, pname, param);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexParameteriv(GLenum target, GLenum pname, const GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexParameteriv,
+ "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::TextureTarget, target),
+ GLenumToString(GLESEnum::TextureParameterName, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateTexParameteriv(context, angle::EntryPoint::GLTexParameteriv,
+ targetPacked, pname, params));
+ if (isCallValid)
+ {
+ context->texParameteriv(targetPacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(TexParameteriv, isCallValid, context, targetPacked, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexSubImage2D(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexSubImage2D,
+ "context = %d, target = %s, level = %d, xoffset = %d, yoffset = %d, width = %d, height = "
+ "%d, format = %s, type = %s, pixels = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target), level, xoffset, yoffset,
+ width, height, GLenumToString(GLESEnum::PixelFormat, format),
+ GLenumToString(GLESEnum::PixelType, type), (uintptr_t)pixels);
+
+ if (context)
+ {
+ TextureTarget targetPacked = PackParam<TextureTarget>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateTexSubImage2D(context, angle::EntryPoint::GLTexSubImage2D, targetPacked, level,
+ xoffset, yoffset, width, height, format, type, pixels));
+ if (isCallValid)
+ {
+ context->texSubImage2D(targetPacked, level, xoffset, yoffset, width, height, format,
+ type, pixels);
+ }
+ ANGLE_CAPTURE_GL(TexSubImage2D, isCallValid, context, targetPacked, level, xoffset, yoffset,
+ width, height, format, type, pixels);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Uniform1f(GLint location, GLfloat v0)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLUniform1f, "context = %d, location = %d, v0 = %f", CID(context), location, v0);
+
+ if (context)
+ {
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateUniform1f(context, angle::EntryPoint::GLUniform1f, locationPacked, v0));
+ if (isCallValid)
+ {
+ context->uniform1f(locationPacked, v0);
+ }
+ ANGLE_CAPTURE_GL(Uniform1f, isCallValid, context, locationPacked, v0);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Uniform1fv(GLint location, GLsizei count, const GLfloat *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLUniform1fv,
+ "context = %d, location = %d, count = %d, value = 0x%016" PRIxPTR "", CID(context),
+ location, count, (uintptr_t)value);
+
+ if (context)
+ {
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateUniform1fv(context, angle::EntryPoint::GLUniform1fv,
+ locationPacked, count, value));
+ if (isCallValid)
+ {
+ context->uniform1fv(locationPacked, count, value);
+ }
+ ANGLE_CAPTURE_GL(Uniform1fv, isCallValid, context, locationPacked, count, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Uniform1i(GLint location, GLint v0)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLUniform1i, "context = %d, location = %d, v0 = %d", CID(context), location, v0);
+
+ if (context)
+ {
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateUniform1i(context, angle::EntryPoint::GLUniform1i, locationPacked, v0));
+ if (isCallValid)
+ {
+ context->uniform1i(locationPacked, v0);
+ }
+ ANGLE_CAPTURE_GL(Uniform1i, isCallValid, context, locationPacked, v0);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Uniform1iv(GLint location, GLsizei count, const GLint *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLUniform1iv,
+ "context = %d, location = %d, count = %d, value = 0x%016" PRIxPTR "", CID(context),
+ location, count, (uintptr_t)value);
+
+ if (context)
+ {
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateUniform1iv(context, angle::EntryPoint::GLUniform1iv,
+ locationPacked, count, value));
+ if (isCallValid)
+ {
+ context->uniform1iv(locationPacked, count, value);
+ }
+ ANGLE_CAPTURE_GL(Uniform1iv, isCallValid, context, locationPacked, count, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Uniform2f(GLint location, GLfloat v0, GLfloat v1)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLUniform2f, "context = %d, location = %d, v0 = %f, v1 = %f", CID(context),
+ location, v0, v1);
+
+ if (context)
+ {
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateUniform2f(context, angle::EntryPoint::GLUniform2f, locationPacked, v0, v1));
+ if (isCallValid)
+ {
+ context->uniform2f(locationPacked, v0, v1);
+ }
+ ANGLE_CAPTURE_GL(Uniform2f, isCallValid, context, locationPacked, v0, v1);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Uniform2fv(GLint location, GLsizei count, const GLfloat *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLUniform2fv,
+ "context = %d, location = %d, count = %d, value = 0x%016" PRIxPTR "", CID(context),
+ location, count, (uintptr_t)value);
+
+ if (context)
+ {
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateUniform2fv(context, angle::EntryPoint::GLUniform2fv,
+ locationPacked, count, value));
+ if (isCallValid)
+ {
+ context->uniform2fv(locationPacked, count, value);
+ }
+ ANGLE_CAPTURE_GL(Uniform2fv, isCallValid, context, locationPacked, count, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Uniform2i(GLint location, GLint v0, GLint v1)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLUniform2i, "context = %d, location = %d, v0 = %d, v1 = %d", CID(context),
+ location, v0, v1);
+
+ if (context)
+ {
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateUniform2i(context, angle::EntryPoint::GLUniform2i, locationPacked, v0, v1));
+ if (isCallValid)
+ {
+ context->uniform2i(locationPacked, v0, v1);
+ }
+ ANGLE_CAPTURE_GL(Uniform2i, isCallValid, context, locationPacked, v0, v1);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Uniform2iv(GLint location, GLsizei count, const GLint *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLUniform2iv,
+ "context = %d, location = %d, count = %d, value = 0x%016" PRIxPTR "", CID(context),
+ location, count, (uintptr_t)value);
+
+ if (context)
+ {
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateUniform2iv(context, angle::EntryPoint::GLUniform2iv,
+ locationPacked, count, value));
+ if (isCallValid)
+ {
+ context->uniform2iv(locationPacked, count, value);
+ }
+ ANGLE_CAPTURE_GL(Uniform2iv, isCallValid, context, locationPacked, count, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Uniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLUniform3f, "context = %d, location = %d, v0 = %f, v1 = %f, v2 = %f",
+ CID(context), location, v0, v1, v2);
+
+ if (context)
+ {
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() || ValidateUniform3f(context, angle::EntryPoint::GLUniform3f,
+ locationPacked, v0, v1, v2));
+ if (isCallValid)
+ {
+ context->uniform3f(locationPacked, v0, v1, v2);
+ }
+ ANGLE_CAPTURE_GL(Uniform3f, isCallValid, context, locationPacked, v0, v1, v2);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Uniform3fv(GLint location, GLsizei count, const GLfloat *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLUniform3fv,
+ "context = %d, location = %d, count = %d, value = 0x%016" PRIxPTR "", CID(context),
+ location, count, (uintptr_t)value);
+
+ if (context)
+ {
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateUniform3fv(context, angle::EntryPoint::GLUniform3fv,
+ locationPacked, count, value));
+ if (isCallValid)
+ {
+ context->uniform3fv(locationPacked, count, value);
+ }
+ ANGLE_CAPTURE_GL(Uniform3fv, isCallValid, context, locationPacked, count, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Uniform3i(GLint location, GLint v0, GLint v1, GLint v2)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLUniform3i, "context = %d, location = %d, v0 = %d, v1 = %d, v2 = %d",
+ CID(context), location, v0, v1, v2);
+
+ if (context)
+ {
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() || ValidateUniform3i(context, angle::EntryPoint::GLUniform3i,
+ locationPacked, v0, v1, v2));
+ if (isCallValid)
+ {
+ context->uniform3i(locationPacked, v0, v1, v2);
+ }
+ ANGLE_CAPTURE_GL(Uniform3i, isCallValid, context, locationPacked, v0, v1, v2);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Uniform3iv(GLint location, GLsizei count, const GLint *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLUniform3iv,
+ "context = %d, location = %d, count = %d, value = 0x%016" PRIxPTR "", CID(context),
+ location, count, (uintptr_t)value);
+
+ if (context)
+ {
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateUniform3iv(context, angle::EntryPoint::GLUniform3iv,
+ locationPacked, count, value));
+ if (isCallValid)
+ {
+ context->uniform3iv(locationPacked, count, value);
+ }
+ ANGLE_CAPTURE_GL(Uniform3iv, isCallValid, context, locationPacked, count, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Uniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLUniform4f, "context = %d, location = %d, v0 = %f, v1 = %f, v2 = %f, v3 = %f",
+ CID(context), location, v0, v1, v2, v3);
+
+ if (context)
+ {
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() || ValidateUniform4f(context, angle::EntryPoint::GLUniform4f,
+ locationPacked, v0, v1, v2, v3));
+ if (isCallValid)
+ {
+ context->uniform4f(locationPacked, v0, v1, v2, v3);
+ }
+ ANGLE_CAPTURE_GL(Uniform4f, isCallValid, context, locationPacked, v0, v1, v2, v3);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Uniform4fv(GLint location, GLsizei count, const GLfloat *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLUniform4fv,
+ "context = %d, location = %d, count = %d, value = 0x%016" PRIxPTR "", CID(context),
+ location, count, (uintptr_t)value);
+
+ if (context)
+ {
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateUniform4fv(context, angle::EntryPoint::GLUniform4fv,
+ locationPacked, count, value));
+ if (isCallValid)
+ {
+ context->uniform4fv(locationPacked, count, value);
+ }
+ ANGLE_CAPTURE_GL(Uniform4fv, isCallValid, context, locationPacked, count, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Uniform4i(GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLUniform4i, "context = %d, location = %d, v0 = %d, v1 = %d, v2 = %d, v3 = %d",
+ CID(context), location, v0, v1, v2, v3);
+
+ if (context)
+ {
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() || ValidateUniform4i(context, angle::EntryPoint::GLUniform4i,
+ locationPacked, v0, v1, v2, v3));
+ if (isCallValid)
+ {
+ context->uniform4i(locationPacked, v0, v1, v2, v3);
+ }
+ ANGLE_CAPTURE_GL(Uniform4i, isCallValid, context, locationPacked, v0, v1, v2, v3);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Uniform4iv(GLint location, GLsizei count, const GLint *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLUniform4iv,
+ "context = %d, location = %d, count = %d, value = 0x%016" PRIxPTR "", CID(context),
+ location, count, (uintptr_t)value);
+
+ if (context)
+ {
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateUniform4iv(context, angle::EntryPoint::GLUniform4iv,
+ locationPacked, count, value));
+ if (isCallValid)
+ {
+ context->uniform4iv(locationPacked, count, value);
+ }
+ ANGLE_CAPTURE_GL(Uniform4iv, isCallValid, context, locationPacked, count, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_UniformMatrix2fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLUniformMatrix2fv,
+ "context = %d, location = %d, count = %d, transpose = %s, value = 0x%016" PRIxPTR "",
+ CID(context), location, count, GLbooleanToString(transpose), (uintptr_t)value);
+
+ if (context)
+ {
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateUniformMatrix2fv(context, angle::EntryPoint::GLUniformMatrix2fv,
+ locationPacked, count, transpose, value));
+ if (isCallValid)
+ {
+ context->uniformMatrix2fv(locationPacked, count, transpose, value);
+ }
+ ANGLE_CAPTURE_GL(UniformMatrix2fv, isCallValid, context, locationPacked, count, transpose,
+ value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_UniformMatrix3fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLUniformMatrix3fv,
+ "context = %d, location = %d, count = %d, transpose = %s, value = 0x%016" PRIxPTR "",
+ CID(context), location, count, GLbooleanToString(transpose), (uintptr_t)value);
+
+ if (context)
+ {
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateUniformMatrix3fv(context, angle::EntryPoint::GLUniformMatrix3fv,
+ locationPacked, count, transpose, value));
+ if (isCallValid)
+ {
+ context->uniformMatrix3fv(locationPacked, count, transpose, value);
+ }
+ ANGLE_CAPTURE_GL(UniformMatrix3fv, isCallValid, context, locationPacked, count, transpose,
+ value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_UniformMatrix4fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLUniformMatrix4fv,
+ "context = %d, location = %d, count = %d, transpose = %s, value = 0x%016" PRIxPTR "",
+ CID(context), location, count, GLbooleanToString(transpose), (uintptr_t)value);
+
+ if (context)
+ {
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateUniformMatrix4fv(context, angle::EntryPoint::GLUniformMatrix4fv,
+ locationPacked, count, transpose, value));
+ if (isCallValid)
+ {
+ context->uniformMatrix4fv(locationPacked, count, transpose, value);
+ }
+ ANGLE_CAPTURE_GL(UniformMatrix4fv, isCallValid, context, locationPacked, count, transpose,
+ value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_UseProgram(GLuint program)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLUseProgram, "context = %d, program = %u", CID(context), program);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateUseProgram(context, angle::EntryPoint::GLUseProgram, programPacked));
+ if (isCallValid)
+ {
+ context->useProgram(programPacked);
+ }
+ ANGLE_CAPTURE_GL(UseProgram, isCallValid, context, programPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ValidateProgram(GLuint program)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLValidateProgram, "context = %d, program = %u", CID(context), program);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateValidateProgram(context, angle::EntryPoint::GLValidateProgram, programPacked));
+ if (isCallValid)
+ {
+ context->validateProgram(programPacked);
+ }
+ ANGLE_CAPTURE_GL(ValidateProgram, isCallValid, context, programPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_VertexAttrib1f(GLuint index, GLfloat x)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLVertexAttrib1f, "context = %d, index = %u, x = %f", CID(context), index, x);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateVertexAttrib1f(context, angle::EntryPoint::GLVertexAttrib1f, index, x));
+ if (isCallValid)
+ {
+ context->vertexAttrib1f(index, x);
+ }
+ ANGLE_CAPTURE_GL(VertexAttrib1f, isCallValid, context, index, x);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_VertexAttrib1fv(GLuint index, const GLfloat *v)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLVertexAttrib1fv, "context = %d, index = %u, v = 0x%016" PRIxPTR "",
+ CID(context), index, (uintptr_t)v);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateVertexAttrib1fv(context, angle::EntryPoint::GLVertexAttrib1fv, index, v));
+ if (isCallValid)
+ {
+ context->vertexAttrib1fv(index, v);
+ }
+ ANGLE_CAPTURE_GL(VertexAttrib1fv, isCallValid, context, index, v);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_VertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLVertexAttrib2f, "context = %d, index = %u, x = %f, y = %f", CID(context),
+ index, x, y);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateVertexAttrib2f(context, angle::EntryPoint::GLVertexAttrib2f, index, x, y));
+ if (isCallValid)
+ {
+ context->vertexAttrib2f(index, x, y);
+ }
+ ANGLE_CAPTURE_GL(VertexAttrib2f, isCallValid, context, index, x, y);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_VertexAttrib2fv(GLuint index, const GLfloat *v)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLVertexAttrib2fv, "context = %d, index = %u, v = 0x%016" PRIxPTR "",
+ CID(context), index, (uintptr_t)v);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateVertexAttrib2fv(context, angle::EntryPoint::GLVertexAttrib2fv, index, v));
+ if (isCallValid)
+ {
+ context->vertexAttrib2fv(index, v);
+ }
+ ANGLE_CAPTURE_GL(VertexAttrib2fv, isCallValid, context, index, v);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_VertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLVertexAttrib3f, "context = %d, index = %u, x = %f, y = %f, z = %f",
+ CID(context), index, x, y, z);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateVertexAttrib3f(context, angle::EntryPoint::GLVertexAttrib3f, index, x, y, z));
+ if (isCallValid)
+ {
+ context->vertexAttrib3f(index, x, y, z);
+ }
+ ANGLE_CAPTURE_GL(VertexAttrib3f, isCallValid, context, index, x, y, z);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_VertexAttrib3fv(GLuint index, const GLfloat *v)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLVertexAttrib3fv, "context = %d, index = %u, v = 0x%016" PRIxPTR "",
+ CID(context), index, (uintptr_t)v);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateVertexAttrib3fv(context, angle::EntryPoint::GLVertexAttrib3fv, index, v));
+ if (isCallValid)
+ {
+ context->vertexAttrib3fv(index, v);
+ }
+ ANGLE_CAPTURE_GL(VertexAttrib3fv, isCallValid, context, index, v);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLVertexAttrib4f, "context = %d, index = %u, x = %f, y = %f, z = %f, w = %f",
+ CID(context), index, x, y, z, w);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateVertexAttrib4f(context, angle::EntryPoint::GLVertexAttrib4f,
+ index, x, y, z, w));
+ if (isCallValid)
+ {
+ context->vertexAttrib4f(index, x, y, z, w);
+ }
+ ANGLE_CAPTURE_GL(VertexAttrib4f, isCallValid, context, index, x, y, z, w);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_VertexAttrib4fv(GLuint index, const GLfloat *v)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLVertexAttrib4fv, "context = %d, index = %u, v = 0x%016" PRIxPTR "",
+ CID(context), index, (uintptr_t)v);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateVertexAttrib4fv(context, angle::EntryPoint::GLVertexAttrib4fv, index, v));
+ if (isCallValid)
+ {
+ context->vertexAttrib4fv(index, v);
+ }
+ ANGLE_CAPTURE_GL(VertexAttrib4fv, isCallValid, context, index, v);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_VertexAttribPointer(GLuint index,
+ GLint size,
+ GLenum type,
+ GLboolean normalized,
+ GLsizei stride,
+ const void *pointer)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLVertexAttribPointer,
+ "context = %d, index = %u, size = %d, type = %s, normalized = %s, stride = %d, pointer = "
+ "0x%016" PRIxPTR "",
+ CID(context), index, size, GLenumToString(GLESEnum::VertexAttribPointerType, type),
+ GLbooleanToString(normalized), stride, (uintptr_t)pointer);
+
+ if (context)
+ {
+ VertexAttribType typePacked = PackParam<VertexAttribType>(type);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateVertexAttribPointer(context, angle::EntryPoint::GLVertexAttribPointer, index,
+ size, typePacked, normalized, stride, pointer));
+ if (isCallValid)
+ {
+ context->vertexAttribPointer(index, size, typePacked, normalized, stride, pointer);
+ }
+ ANGLE_CAPTURE_GL(VertexAttribPointer, isCallValid, context, index, size, typePacked,
+ normalized, stride, pointer);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Viewport(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLViewport, "context = %d, x = %d, y = %d, width = %d, height = %d",
+ CID(context), x, y, width, height);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateViewport(context, angle::EntryPoint::GLViewport, x, y, width, height));
+ if (isCallValid)
+ {
+ context->viewport(x, y, width, height);
+ }
+ ANGLE_CAPTURE_GL(Viewport, isCallValid, context, x, y, width, height);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+} // extern "C"
diff --git a/gfx/angle/checkout/src/libGLESv2/entry_points_gles_2_0_autogen.h b/gfx/angle/checkout/src/libGLESv2/entry_points_gles_2_0_autogen.h
new file mode 100644
index 0000000000..5f5bab31ec
--- /dev/null
+++ b/gfx/angle/checkout/src/libGLESv2/entry_points_gles_2_0_autogen.h
@@ -0,0 +1,309 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml.
+//
+// Copyright 2020 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_2_0_autogen.h:
+// Defines the GLES 2.0 entry points.
+
+#ifndef LIBGLESV2_ENTRY_POINTS_GLES_2_0_AUTOGEN_H_
+#define LIBGLESV2_ENTRY_POINTS_GLES_2_0_AUTOGEN_H_
+
+#include <GLES2/gl2.h>
+#include <export.h>
+
+extern "C" {
+ANGLE_EXPORT void GL_APIENTRY GL_ActiveTexture(GLenum texture);
+ANGLE_EXPORT void GL_APIENTRY GL_AttachShader(GLuint program, GLuint shader);
+ANGLE_EXPORT void GL_APIENTRY GL_BindAttribLocation(GLuint program,
+ GLuint index,
+ const GLchar *name);
+ANGLE_EXPORT void GL_APIENTRY GL_BindBuffer(GLenum target, GLuint buffer);
+ANGLE_EXPORT void GL_APIENTRY GL_BindFramebuffer(GLenum target, GLuint framebuffer);
+ANGLE_EXPORT void GL_APIENTRY GL_BindRenderbuffer(GLenum target, GLuint renderbuffer);
+ANGLE_EXPORT void GL_APIENTRY GL_BindTexture(GLenum target, GLuint texture);
+ANGLE_EXPORT void GL_APIENTRY GL_BlendColor(GLfloat red,
+ GLfloat green,
+ GLfloat blue,
+ GLfloat alpha);
+ANGLE_EXPORT void GL_APIENTRY GL_BlendEquation(GLenum mode);
+ANGLE_EXPORT void GL_APIENTRY GL_BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
+ANGLE_EXPORT void GL_APIENTRY GL_BlendFunc(GLenum sfactor, GLenum dfactor);
+ANGLE_EXPORT void GL_APIENTRY GL_BlendFuncSeparate(GLenum sfactorRGB,
+ GLenum dfactorRGB,
+ GLenum sfactorAlpha,
+ GLenum dfactorAlpha);
+ANGLE_EXPORT void GL_APIENTRY GL_BufferData(GLenum target,
+ GLsizeiptr size,
+ const void *data,
+ GLenum usage);
+ANGLE_EXPORT void GL_APIENTRY GL_BufferSubData(GLenum target,
+ GLintptr offset,
+ GLsizeiptr size,
+ const void *data);
+ANGLE_EXPORT GLenum GL_APIENTRY GL_CheckFramebufferStatus(GLenum target);
+ANGLE_EXPORT void GL_APIENTRY GL_Clear(GLbitfield mask);
+ANGLE_EXPORT void GL_APIENTRY GL_ClearColor(GLfloat red,
+ GLfloat green,
+ GLfloat blue,
+ GLfloat alpha);
+ANGLE_EXPORT void GL_APIENTRY GL_ClearDepthf(GLfloat d);
+ANGLE_EXPORT void GL_APIENTRY GL_ClearStencil(GLint s);
+ANGLE_EXPORT void GL_APIENTRY GL_ColorMask(GLboolean red,
+ GLboolean green,
+ GLboolean blue,
+ GLboolean alpha);
+ANGLE_EXPORT void GL_APIENTRY GL_CompileShader(GLuint shader);
+ANGLE_EXPORT void GL_APIENTRY GL_CompressedTexImage2D(GLenum target,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLsizei imageSize,
+ const void *data);
+ANGLE_EXPORT void GL_APIENTRY GL_CompressedTexSubImage2D(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data);
+ANGLE_EXPORT void GL_APIENTRY GL_CopyTexImage2D(GLenum target,
+ GLint level,
+ GLenum internalformat,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLint border);
+ANGLE_EXPORT void GL_APIENTRY GL_CopyTexSubImage2D(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height);
+ANGLE_EXPORT GLuint GL_APIENTRY GL_CreateProgram();
+ANGLE_EXPORT GLuint GL_APIENTRY GL_CreateShader(GLenum type);
+ANGLE_EXPORT void GL_APIENTRY GL_CullFace(GLenum mode);
+ANGLE_EXPORT void GL_APIENTRY GL_DeleteBuffers(GLsizei n, const GLuint *buffers);
+ANGLE_EXPORT void GL_APIENTRY GL_DeleteFramebuffers(GLsizei n, const GLuint *framebuffers);
+ANGLE_EXPORT void GL_APIENTRY GL_DeleteProgram(GLuint program);
+ANGLE_EXPORT void GL_APIENTRY GL_DeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers);
+ANGLE_EXPORT void GL_APIENTRY GL_DeleteShader(GLuint shader);
+ANGLE_EXPORT void GL_APIENTRY GL_DeleteTextures(GLsizei n, const GLuint *textures);
+ANGLE_EXPORT void GL_APIENTRY GL_DepthFunc(GLenum func);
+ANGLE_EXPORT void GL_APIENTRY GL_DepthMask(GLboolean flag);
+ANGLE_EXPORT void GL_APIENTRY GL_DepthRangef(GLfloat n, GLfloat f);
+ANGLE_EXPORT void GL_APIENTRY GL_DetachShader(GLuint program, GLuint shader);
+ANGLE_EXPORT void GL_APIENTRY GL_Disable(GLenum cap);
+ANGLE_EXPORT void GL_APIENTRY GL_DisableVertexAttribArray(GLuint index);
+ANGLE_EXPORT void GL_APIENTRY GL_DrawArrays(GLenum mode, GLint first, GLsizei count);
+ANGLE_EXPORT void GL_APIENTRY GL_DrawElements(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const void *indices);
+ANGLE_EXPORT void GL_APIENTRY GL_Enable(GLenum cap);
+ANGLE_EXPORT void GL_APIENTRY GL_EnableVertexAttribArray(GLuint index);
+ANGLE_EXPORT void GL_APIENTRY GL_Finish();
+ANGLE_EXPORT void GL_APIENTRY GL_Flush();
+ANGLE_EXPORT void GL_APIENTRY GL_FramebufferRenderbuffer(GLenum target,
+ GLenum attachment,
+ GLenum renderbuffertarget,
+ GLuint renderbuffer);
+ANGLE_EXPORT void GL_APIENTRY GL_FramebufferTexture2D(GLenum target,
+ GLenum attachment,
+ GLenum textarget,
+ GLuint texture,
+ GLint level);
+ANGLE_EXPORT void GL_APIENTRY GL_FrontFace(GLenum mode);
+ANGLE_EXPORT void GL_APIENTRY GL_GenBuffers(GLsizei n, GLuint *buffers);
+ANGLE_EXPORT void GL_APIENTRY GL_GenFramebuffers(GLsizei n, GLuint *framebuffers);
+ANGLE_EXPORT void GL_APIENTRY GL_GenRenderbuffers(GLsizei n, GLuint *renderbuffers);
+ANGLE_EXPORT void GL_APIENTRY GL_GenTextures(GLsizei n, GLuint *textures);
+ANGLE_EXPORT void GL_APIENTRY GL_GenerateMipmap(GLenum target);
+ANGLE_EXPORT void GL_APIENTRY GL_GetActiveAttrib(GLuint program,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *size,
+ GLenum *type,
+ GLchar *name);
+ANGLE_EXPORT void GL_APIENTRY GL_GetActiveUniform(GLuint program,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *size,
+ GLenum *type,
+ GLchar *name);
+ANGLE_EXPORT void GL_APIENTRY GL_GetAttachedShaders(GLuint program,
+ GLsizei maxCount,
+ GLsizei *count,
+ GLuint *shaders);
+ANGLE_EXPORT GLint GL_APIENTRY GL_GetAttribLocation(GLuint program, const GLchar *name);
+ANGLE_EXPORT void GL_APIENTRY GL_GetBooleanv(GLenum pname, GLboolean *data);
+ANGLE_EXPORT void GL_APIENTRY GL_GetBufferParameteriv(GLenum target, GLenum pname, GLint *params);
+ANGLE_EXPORT GLenum GL_APIENTRY GL_GetError();
+ANGLE_EXPORT void GL_APIENTRY GL_GetFloatv(GLenum pname, GLfloat *data);
+ANGLE_EXPORT void GL_APIENTRY GL_GetFramebufferAttachmentParameteriv(GLenum target,
+ GLenum attachment,
+ GLenum pname,
+ GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetIntegerv(GLenum pname, GLint *data);
+ANGLE_EXPORT void GL_APIENTRY GL_GetProgramInfoLog(GLuint program,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *infoLog);
+ANGLE_EXPORT void GL_APIENTRY GL_GetProgramiv(GLuint program, GLenum pname, GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetRenderbufferParameteriv(GLenum target,
+ GLenum pname,
+ GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetShaderInfoLog(GLuint shader,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *infoLog);
+ANGLE_EXPORT void GL_APIENTRY GL_GetShaderPrecisionFormat(GLenum shadertype,
+ GLenum precisiontype,
+ GLint *range,
+ GLint *precision);
+ANGLE_EXPORT void GL_APIENTRY GL_GetShaderSource(GLuint shader,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *source);
+ANGLE_EXPORT void GL_APIENTRY GL_GetShaderiv(GLuint shader, GLenum pname, GLint *params);
+ANGLE_EXPORT const GLubyte *GL_APIENTRY GL_GetString(GLenum name);
+ANGLE_EXPORT void GL_APIENTRY GL_GetTexParameterfv(GLenum target, GLenum pname, GLfloat *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetTexParameteriv(GLenum target, GLenum pname, GLint *params);
+ANGLE_EXPORT GLint GL_APIENTRY GL_GetUniformLocation(GLuint program, const GLchar *name);
+ANGLE_EXPORT void GL_APIENTRY GL_GetUniformfv(GLuint program, GLint location, GLfloat *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetUniformiv(GLuint program, GLint location, GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetVertexAttribPointerv(GLuint index,
+ GLenum pname,
+ void **pointer);
+ANGLE_EXPORT void GL_APIENTRY GL_GetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetVertexAttribiv(GLuint index, GLenum pname, GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_Hint(GLenum target, GLenum mode);
+ANGLE_EXPORT GLboolean GL_APIENTRY GL_IsBuffer(GLuint buffer);
+ANGLE_EXPORT GLboolean GL_APIENTRY GL_IsEnabled(GLenum cap);
+ANGLE_EXPORT GLboolean GL_APIENTRY GL_IsFramebuffer(GLuint framebuffer);
+ANGLE_EXPORT GLboolean GL_APIENTRY GL_IsProgram(GLuint program);
+ANGLE_EXPORT GLboolean GL_APIENTRY GL_IsRenderbuffer(GLuint renderbuffer);
+ANGLE_EXPORT GLboolean GL_APIENTRY GL_IsShader(GLuint shader);
+ANGLE_EXPORT GLboolean GL_APIENTRY GL_IsTexture(GLuint texture);
+ANGLE_EXPORT void GL_APIENTRY GL_LineWidth(GLfloat width);
+ANGLE_EXPORT void GL_APIENTRY GL_LinkProgram(GLuint program);
+ANGLE_EXPORT void GL_APIENTRY GL_PixelStorei(GLenum pname, GLint param);
+ANGLE_EXPORT void GL_APIENTRY GL_PolygonOffset(GLfloat factor, GLfloat units);
+ANGLE_EXPORT void GL_APIENTRY GL_ReadPixels(GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ void *pixels);
+ANGLE_EXPORT void GL_APIENTRY GL_ReleaseShaderCompiler();
+ANGLE_EXPORT void GL_APIENTRY GL_RenderbufferStorage(GLenum target,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height);
+ANGLE_EXPORT void GL_APIENTRY GL_SampleCoverage(GLfloat value, GLboolean invert);
+ANGLE_EXPORT void GL_APIENTRY GL_Scissor(GLint x, GLint y, GLsizei width, GLsizei height);
+ANGLE_EXPORT void GL_APIENTRY GL_ShaderBinary(GLsizei count,
+ const GLuint *shaders,
+ GLenum binaryFormat,
+ const void *binary,
+ GLsizei length);
+ANGLE_EXPORT void GL_APIENTRY GL_ShaderSource(GLuint shader,
+ GLsizei count,
+ const GLchar *const *string,
+ const GLint *length);
+ANGLE_EXPORT void GL_APIENTRY GL_StencilFunc(GLenum func, GLint ref, GLuint mask);
+ANGLE_EXPORT void GL_APIENTRY GL_StencilFuncSeparate(GLenum face,
+ GLenum func,
+ GLint ref,
+ GLuint mask);
+ANGLE_EXPORT void GL_APIENTRY GL_StencilMask(GLuint mask);
+ANGLE_EXPORT void GL_APIENTRY GL_StencilMaskSeparate(GLenum face, GLuint mask);
+ANGLE_EXPORT void GL_APIENTRY GL_StencilOp(GLenum fail, GLenum zfail, GLenum zpass);
+ANGLE_EXPORT void GL_APIENTRY GL_StencilOpSeparate(GLenum face,
+ GLenum sfail,
+ GLenum dpfail,
+ GLenum dppass);
+ANGLE_EXPORT void GL_APIENTRY GL_TexImage2D(GLenum target,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const void *pixels);
+ANGLE_EXPORT void GL_APIENTRY GL_TexParameterf(GLenum target, GLenum pname, GLfloat param);
+ANGLE_EXPORT void GL_APIENTRY GL_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params);
+ANGLE_EXPORT void GL_APIENTRY GL_TexParameteri(GLenum target, GLenum pname, GLint param);
+ANGLE_EXPORT void GL_APIENTRY GL_TexParameteriv(GLenum target, GLenum pname, const GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_TexSubImage2D(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ const void *pixels);
+ANGLE_EXPORT void GL_APIENTRY GL_Uniform1f(GLint location, GLfloat v0);
+ANGLE_EXPORT void GL_APIENTRY GL_Uniform1fv(GLint location, GLsizei count, const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY GL_Uniform1i(GLint location, GLint v0);
+ANGLE_EXPORT void GL_APIENTRY GL_Uniform1iv(GLint location, GLsizei count, const GLint *value);
+ANGLE_EXPORT void GL_APIENTRY GL_Uniform2f(GLint location, GLfloat v0, GLfloat v1);
+ANGLE_EXPORT void GL_APIENTRY GL_Uniform2fv(GLint location, GLsizei count, const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY GL_Uniform2i(GLint location, GLint v0, GLint v1);
+ANGLE_EXPORT void GL_APIENTRY GL_Uniform2iv(GLint location, GLsizei count, const GLint *value);
+ANGLE_EXPORT void GL_APIENTRY GL_Uniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+ANGLE_EXPORT void GL_APIENTRY GL_Uniform3fv(GLint location, GLsizei count, const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY GL_Uniform3i(GLint location, GLint v0, GLint v1, GLint v2);
+ANGLE_EXPORT void GL_APIENTRY GL_Uniform3iv(GLint location, GLsizei count, const GLint *value);
+ANGLE_EXPORT void GL_APIENTRY
+GL_Uniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+ANGLE_EXPORT void GL_APIENTRY GL_Uniform4fv(GLint location, GLsizei count, const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY GL_Uniform4i(GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+ANGLE_EXPORT void GL_APIENTRY GL_Uniform4iv(GLint location, GLsizei count, const GLint *value);
+ANGLE_EXPORT void GL_APIENTRY GL_UniformMatrix2fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY GL_UniformMatrix3fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY GL_UniformMatrix4fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY GL_UseProgram(GLuint program);
+ANGLE_EXPORT void GL_APIENTRY GL_ValidateProgram(GLuint program);
+ANGLE_EXPORT void GL_APIENTRY GL_VertexAttrib1f(GLuint index, GLfloat x);
+ANGLE_EXPORT void GL_APIENTRY GL_VertexAttrib1fv(GLuint index, const GLfloat *v);
+ANGLE_EXPORT void GL_APIENTRY GL_VertexAttrib2f(GLuint index, GLfloat x, GLfloat y);
+ANGLE_EXPORT void GL_APIENTRY GL_VertexAttrib2fv(GLuint index, const GLfloat *v);
+ANGLE_EXPORT void GL_APIENTRY GL_VertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z);
+ANGLE_EXPORT void GL_APIENTRY GL_VertexAttrib3fv(GLuint index, const GLfloat *v);
+ANGLE_EXPORT void GL_APIENTRY
+GL_VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+ANGLE_EXPORT void GL_APIENTRY GL_VertexAttrib4fv(GLuint index, const GLfloat *v);
+ANGLE_EXPORT void GL_APIENTRY GL_VertexAttribPointer(GLuint index,
+ GLint size,
+ GLenum type,
+ GLboolean normalized,
+ GLsizei stride,
+ const void *pointer);
+ANGLE_EXPORT void GL_APIENTRY GL_Viewport(GLint x, GLint y, GLsizei width, GLsizei height);
+} // extern "C"
+
+#endif // LIBGLESV2_ENTRY_POINTS_GLES_2_0_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libGLESv2/entry_points_gles_3_0_autogen.cpp b/gfx/angle/checkout/src/libGLESv2/entry_points_gles_3_0_autogen.cpp
new file mode 100644
index 0000000000..a5d8c1172e
--- /dev/null
+++ b/gfx/angle/checkout/src/libGLESv2/entry_points_gles_3_0_autogen.cpp
@@ -0,0 +1,3057 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml.
+//
+// Copyright 2020 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_0_autogen.cpp:
+// Defines the GLES 3.0 entry points.
+
+#include "libGLESv2/entry_points_gles_3_0_autogen.h"
+
+#include "common/entry_points_enum_autogen.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Context.inl.h"
+#include "libANGLE/capture/capture_gles_3_0_autogen.h"
+#include "libANGLE/capture/gl_enum_utils.h"
+#include "libANGLE/entry_points_utils.h"
+#include "libANGLE/validationES3.h"
+#include "libGLESv2/global_state.h"
+
+using namespace gl;
+
+extern "C" {
+void GL_APIENTRY GL_BeginQuery(GLenum target, GLuint id)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBeginQuery, "context = %d, target = %s, id = %u", CID(context),
+ GLenumToString(GLESEnum::QueryTarget, target), id);
+
+ if (context)
+ {
+ QueryType targetPacked = PackParam<QueryType>(target);
+ QueryID idPacked = PackParam<QueryID>(id);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateBeginQuery(context, angle::EntryPoint::GLBeginQuery, targetPacked, idPacked));
+ if (isCallValid)
+ {
+ context->beginQuery(targetPacked, idPacked);
+ }
+ ANGLE_CAPTURE_GL(BeginQuery, isCallValid, context, targetPacked, idPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_BeginTransformFeedback(GLenum primitiveMode)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBeginTransformFeedback, "context = %d, primitiveMode = %s", CID(context),
+ GLenumToString(GLESEnum::PrimitiveType, primitiveMode));
+
+ if (context)
+ {
+ PrimitiveMode primitiveModePacked = PackParam<PrimitiveMode>(primitiveMode);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateBeginTransformFeedback(context, angle::EntryPoint::GLBeginTransformFeedback,
+ primitiveModePacked));
+ if (isCallValid)
+ {
+ context->beginTransformFeedback(primitiveModePacked);
+ }
+ ANGLE_CAPTURE_GL(BeginTransformFeedback, isCallValid, context, primitiveModePacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_BindBufferBase(GLenum target, GLuint index, GLuint buffer)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBindBufferBase, "context = %d, target = %s, index = %u, buffer = %u",
+ CID(context), GLenumToString(GLESEnum::BufferTargetARB, target), index, buffer);
+
+ if (context)
+ {
+ BufferBinding targetPacked = PackParam<BufferBinding>(target);
+ BufferID bufferPacked = PackParam<BufferID>(buffer);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateBindBufferBase(context, angle::EntryPoint::GLBindBufferBase,
+ targetPacked, index, bufferPacked));
+ if (isCallValid)
+ {
+ context->bindBufferBase(targetPacked, index, bufferPacked);
+ }
+ ANGLE_CAPTURE_GL(BindBufferBase, isCallValid, context, targetPacked, index, bufferPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY
+GL_BindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBindBufferRange,
+ "context = %d, target = %s, index = %u, buffer = %u, offset = %llu, size = %llu",
+ CID(context), GLenumToString(GLESEnum::BufferTargetARB, target), index, buffer,
+ static_cast<unsigned long long>(offset), static_cast<unsigned long long>(size));
+
+ if (context)
+ {
+ BufferBinding targetPacked = PackParam<BufferBinding>(target);
+ BufferID bufferPacked = PackParam<BufferID>(buffer);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateBindBufferRange(context, angle::EntryPoint::GLBindBufferRange, targetPacked,
+ index, bufferPacked, offset, size));
+ if (isCallValid)
+ {
+ context->bindBufferRange(targetPacked, index, bufferPacked, offset, size);
+ }
+ ANGLE_CAPTURE_GL(BindBufferRange, isCallValid, context, targetPacked, index, bufferPacked,
+ offset, size);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_BindSampler(GLuint unit, GLuint sampler)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBindSampler, "context = %d, unit = %u, sampler = %u", CID(context), unit,
+ sampler);
+
+ if (context)
+ {
+ SamplerID samplerPacked = PackParam<SamplerID>(sampler);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateBindSampler(context, angle::EntryPoint::GLBindSampler, unit, samplerPacked));
+ if (isCallValid)
+ {
+ context->bindSampler(unit, samplerPacked);
+ }
+ ANGLE_CAPTURE_GL(BindSampler, isCallValid, context, unit, samplerPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_BindTransformFeedback(GLenum target, GLuint id)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBindTransformFeedback, "context = %d, target = %s, id = %u", CID(context),
+ GLenumToString(GLESEnum::BindTransformFeedbackTarget, target), id);
+
+ if (context)
+ {
+ TransformFeedbackID idPacked = PackParam<TransformFeedbackID>(id);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateBindTransformFeedback(context, angle::EntryPoint::GLBindTransformFeedback,
+ target, idPacked));
+ if (isCallValid)
+ {
+ context->bindTransformFeedback(target, idPacked);
+ }
+ ANGLE_CAPTURE_GL(BindTransformFeedback, isCallValid, context, target, idPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_BindVertexArray(GLuint array)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBindVertexArray, "context = %d, array = %u", CID(context), array);
+
+ if (context)
+ {
+ VertexArrayID arrayPacked = PackParam<VertexArrayID>(array);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateBindVertexArray(context, angle::EntryPoint::GLBindVertexArray, arrayPacked));
+ if (isCallValid)
+ {
+ context->bindVertexArray(arrayPacked);
+ }
+ ANGLE_CAPTURE_GL(BindVertexArray, isCallValid, context, arrayPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_BlitFramebuffer(GLint srcX0,
+ GLint srcY0,
+ GLint srcX1,
+ GLint srcY1,
+ GLint dstX0,
+ GLint dstY0,
+ GLint dstX1,
+ GLint dstY1,
+ GLbitfield mask,
+ GLenum filter)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBlitFramebuffer,
+ "context = %d, srcX0 = %d, srcY0 = %d, srcX1 = %d, srcY1 = %d, dstX0 = %d, dstY0 = %d, "
+ "dstX1 = %d, dstY1 = %d, mask = %s, filter = %s",
+ CID(context), srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,
+ GLbitfieldToString(GLESEnum::ClearBufferMask, mask).c_str(),
+ GLenumToString(GLESEnum::BlitFramebufferFilter, filter));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateBlitFramebuffer(context, angle::EntryPoint::GLBlitFramebuffer, srcX0, srcY0,
+ srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter));
+ if (isCallValid)
+ {
+ context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask,
+ filter);
+ }
+ ANGLE_CAPTURE_GL(BlitFramebuffer, isCallValid, context, srcX0, srcY0, srcX1, srcY1, dstX0,
+ dstY0, dstX1, dstY1, mask, filter);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLClearBufferfi,
+ "context = %d, buffer = %s, drawbuffer = %d, depth = %f, stencil = %d", CID(context),
+ GLenumToString(GLESEnum::Buffer, buffer), drawbuffer, depth, stencil);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateClearBufferfi(context, angle::EntryPoint::GLClearBufferfi,
+ buffer, drawbuffer, depth, stencil));
+ if (isCallValid)
+ {
+ context->clearBufferfi(buffer, drawbuffer, depth, stencil);
+ }
+ ANGLE_CAPTURE_GL(ClearBufferfi, isCallValid, context, buffer, drawbuffer, depth, stencil);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLClearBufferfv,
+ "context = %d, buffer = %s, drawbuffer = %d, value = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::Buffer, buffer), drawbuffer, (uintptr_t)value);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateClearBufferfv(context, angle::EntryPoint::GLClearBufferfv,
+ buffer, drawbuffer, value));
+ if (isCallValid)
+ {
+ context->clearBufferfv(buffer, drawbuffer, value);
+ }
+ ANGLE_CAPTURE_GL(ClearBufferfv, isCallValid, context, buffer, drawbuffer, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLClearBufferiv,
+ "context = %d, buffer = %s, drawbuffer = %d, value = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::Buffer, buffer), drawbuffer, (uintptr_t)value);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateClearBufferiv(context, angle::EntryPoint::GLClearBufferiv,
+ buffer, drawbuffer, value));
+ if (isCallValid)
+ {
+ context->clearBufferiv(buffer, drawbuffer, value);
+ }
+ ANGLE_CAPTURE_GL(ClearBufferiv, isCallValid, context, buffer, drawbuffer, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLClearBufferuiv,
+ "context = %d, buffer = %s, drawbuffer = %d, value = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::Buffer, buffer), drawbuffer, (uintptr_t)value);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateClearBufferuiv(context, angle::EntryPoint::GLClearBufferuiv,
+ buffer, drawbuffer, value));
+ if (isCallValid)
+ {
+ context->clearBufferuiv(buffer, drawbuffer, value);
+ }
+ ANGLE_CAPTURE_GL(ClearBufferuiv, isCallValid, context, buffer, drawbuffer, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+GLenum GL_APIENTRY GL_ClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLClientWaitSync,
+ "context = %d, sync = 0x%016" PRIxPTR ", flags = %s, timeout = %llu", CID(context),
+ (uintptr_t)sync, GLbitfieldToString(GLESEnum::SyncObjectMask, flags).c_str(),
+ static_cast<unsigned long long>(timeout));
+
+ GLenum returnValue;
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateClientWaitSync(context, angle::EntryPoint::GLClientWaitSync,
+ sync, flags, timeout));
+ if (isCallValid)
+ {
+ returnValue = context->clientWaitSync(sync, flags, timeout);
+ }
+ else
+ {
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLClientWaitSync, GLenum>();
+ }
+ ANGLE_CAPTURE_GL(ClientWaitSync, isCallValid, context, sync, flags, timeout, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLClientWaitSync, GLenum>();
+ }
+ return returnValue;
+}
+
+void GL_APIENTRY GL_CompressedTexImage3D(GLenum target,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLsizei imageSize,
+ const void *data)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLCompressedTexImage3D,
+ "context = %d, target = %s, level = %d, internalformat = %s, width = %d, height = %d, "
+ "depth = %d, border = %d, imageSize = %d, data = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target), level,
+ GLenumToString(GLESEnum::InternalFormat, internalformat), width, height, depth, border,
+ imageSize, (uintptr_t)data);
+
+ if (context)
+ {
+ TextureTarget targetPacked = PackParam<TextureTarget>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateCompressedTexImage3D(context, angle::EntryPoint::GLCompressedTexImage3D,
+ targetPacked, level, internalformat, width, height, depth,
+ border, imageSize, data));
+ if (isCallValid)
+ {
+ context->compressedTexImage3D(targetPacked, level, internalformat, width, height, depth,
+ border, imageSize, data);
+ }
+ ANGLE_CAPTURE_GL(CompressedTexImage3D, isCallValid, context, targetPacked, level,
+ internalformat, width, height, depth, border, imageSize, data);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_CompressedTexSubImage3D(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLCompressedTexSubImage3D,
+ "context = %d, target = %s, level = %d, xoffset = %d, yoffset = %d, zoffset = %d, width "
+ "= %d, height = %d, depth = %d, format = %s, imageSize = %d, data = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target), level, xoffset, yoffset,
+ zoffset, width, height, depth, GLenumToString(GLESEnum::InternalFormat, format),
+ imageSize, (uintptr_t)data);
+
+ if (context)
+ {
+ TextureTarget targetPacked = PackParam<TextureTarget>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateCompressedTexSubImage3D(context, angle::EntryPoint::GLCompressedTexSubImage3D,
+ targetPacked, level, xoffset, yoffset, zoffset, width,
+ height, depth, format, imageSize, data));
+ if (isCallValid)
+ {
+ context->compressedTexSubImage3D(targetPacked, level, xoffset, yoffset, zoffset, width,
+ height, depth, format, imageSize, data);
+ }
+ ANGLE_CAPTURE_GL(CompressedTexSubImage3D, isCallValid, context, targetPacked, level,
+ xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_CopyBufferSubData(GLenum readTarget,
+ GLenum writeTarget,
+ GLintptr readOffset,
+ GLintptr writeOffset,
+ GLsizeiptr size)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLCopyBufferSubData,
+ "context = %d, readTarget = %s, writeTarget = %s, readOffset = %llu, writeOffset = %llu, "
+ "size = %llu",
+ CID(context), GLenumToString(GLESEnum::CopyBufferSubDataTarget, readTarget),
+ GLenumToString(GLESEnum::CopyBufferSubDataTarget, writeTarget),
+ static_cast<unsigned long long>(readOffset), static_cast<unsigned long long>(writeOffset),
+ static_cast<unsigned long long>(size));
+
+ if (context)
+ {
+ BufferBinding readTargetPacked = PackParam<BufferBinding>(readTarget);
+ BufferBinding writeTargetPacked = PackParam<BufferBinding>(writeTarget);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateCopyBufferSubData(
+ context, angle::EntryPoint::GLCopyBufferSubData, readTargetPacked,
+ writeTargetPacked, readOffset, writeOffset, size));
+ if (isCallValid)
+ {
+ context->copyBufferSubData(readTargetPacked, writeTargetPacked, readOffset, writeOffset,
+ size);
+ }
+ ANGLE_CAPTURE_GL(CopyBufferSubData, isCallValid, context, readTargetPacked,
+ writeTargetPacked, readOffset, writeOffset, size);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_CopyTexSubImage3D(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLCopyTexSubImage3D,
+ "context = %d, target = %s, level = %d, xoffset = %d, yoffset = %d, zoffset = %d, x = "
+ "%d, y = %d, width = %d, height = %d",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target), level, xoffset, yoffset,
+ zoffset, x, y, width, height);
+
+ if (context)
+ {
+ TextureTarget targetPacked = PackParam<TextureTarget>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateCopyTexSubImage3D(
+ context, angle::EntryPoint::GLCopyTexSubImage3D, targetPacked,
+ level, xoffset, yoffset, zoffset, x, y, width, height));
+ if (isCallValid)
+ {
+ context->copyTexSubImage3D(targetPacked, level, xoffset, yoffset, zoffset, x, y, width,
+ height);
+ }
+ ANGLE_CAPTURE_GL(CopyTexSubImage3D, isCallValid, context, targetPacked, level, xoffset,
+ yoffset, zoffset, x, y, width, height);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DeleteQueries(GLsizei n, const GLuint *ids)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDeleteQueries, "context = %d, n = %d, ids = 0x%016" PRIxPTR "", CID(context),
+ n, (uintptr_t)ids);
+
+ if (context)
+ {
+ const QueryID *idsPacked = PackParam<const QueryID *>(ids);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateDeleteQueries(context, angle::EntryPoint::GLDeleteQueries, n, idsPacked));
+ if (isCallValid)
+ {
+ context->deleteQueries(n, idsPacked);
+ }
+ ANGLE_CAPTURE_GL(DeleteQueries, isCallValid, context, n, idsPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DeleteSamplers(GLsizei count, const GLuint *samplers)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDeleteSamplers, "context = %d, count = %d, samplers = 0x%016" PRIxPTR "",
+ CID(context), count, (uintptr_t)samplers);
+
+ if (context)
+ {
+ const SamplerID *samplersPacked = PackParam<const SamplerID *>(samplers);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateDeleteSamplers(context, angle::EntryPoint::GLDeleteSamplers,
+ count, samplersPacked));
+ if (isCallValid)
+ {
+ context->deleteSamplers(count, samplersPacked);
+ }
+ ANGLE_CAPTURE_GL(DeleteSamplers, isCallValid, context, count, samplersPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DeleteSync(GLsync sync)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDeleteSync, "context = %d, sync = 0x%016" PRIxPTR "", CID(context),
+ (uintptr_t)sync);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateDeleteSync(context, angle::EntryPoint::GLDeleteSync, sync));
+ if (isCallValid)
+ {
+ context->deleteSync(sync);
+ }
+ ANGLE_CAPTURE_GL(DeleteSync, isCallValid, context, sync);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DeleteTransformFeedbacks(GLsizei n, const GLuint *ids)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDeleteTransformFeedbacks, "context = %d, n = %d, ids = 0x%016" PRIxPTR "",
+ CID(context), n, (uintptr_t)ids);
+
+ if (context)
+ {
+ const TransformFeedbackID *idsPacked = PackParam<const TransformFeedbackID *>(ids);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateDeleteTransformFeedbacks(
+ context, angle::EntryPoint::GLDeleteTransformFeedbacks, n, idsPacked));
+ if (isCallValid)
+ {
+ context->deleteTransformFeedbacks(n, idsPacked);
+ }
+ ANGLE_CAPTURE_GL(DeleteTransformFeedbacks, isCallValid, context, n, idsPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DeleteVertexArrays(GLsizei n, const GLuint *arrays)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDeleteVertexArrays, "context = %d, n = %d, arrays = 0x%016" PRIxPTR "",
+ CID(context), n, (uintptr_t)arrays);
+
+ if (context)
+ {
+ const VertexArrayID *arraysPacked = PackParam<const VertexArrayID *>(arrays);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateDeleteVertexArrays(
+ context, angle::EntryPoint::GLDeleteVertexArrays, n, arraysPacked));
+ if (isCallValid)
+ {
+ context->deleteVertexArrays(n, arraysPacked);
+ }
+ ANGLE_CAPTURE_GL(DeleteVertexArrays, isCallValid, context, n, arraysPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DrawArraysInstanced(GLenum mode,
+ GLint first,
+ GLsizei count,
+ GLsizei instancecount)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDrawArraysInstanced,
+ "context = %d, mode = %s, first = %d, count = %d, instancecount = %d", CID(context),
+ GLenumToString(GLESEnum::PrimitiveType, mode), first, count, instancecount);
+
+ if (context)
+ {
+ PrimitiveMode modePacked = PackParam<PrimitiveMode>(mode);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateDrawArraysInstanced(context, angle::EntryPoint::GLDrawArraysInstanced,
+ modePacked, first, count, instancecount));
+ if (isCallValid)
+ {
+ context->drawArraysInstanced(modePacked, first, count, instancecount);
+ }
+ ANGLE_CAPTURE_GL(DrawArraysInstanced, isCallValid, context, modePacked, first, count,
+ instancecount);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DrawBuffers(GLsizei n, const GLenum *bufs)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDrawBuffers, "context = %d, n = %d, bufs = 0x%016" PRIxPTR "", CID(context), n,
+ (uintptr_t)bufs);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateDrawBuffers(context, angle::EntryPoint::GLDrawBuffers, n, bufs));
+ if (isCallValid)
+ {
+ context->drawBuffers(n, bufs);
+ }
+ ANGLE_CAPTURE_GL(DrawBuffers, isCallValid, context, n, bufs);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DrawElementsInstanced(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLsizei instancecount)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDrawElementsInstanced,
+ "context = %d, mode = %s, count = %d, type = %s, indices = 0x%016" PRIxPTR
+ ", instancecount = %d",
+ CID(context), GLenumToString(GLESEnum::PrimitiveType, mode), count,
+ GLenumToString(GLESEnum::DrawElementsType, type), (uintptr_t)indices, instancecount);
+
+ if (context)
+ {
+ PrimitiveMode modePacked = PackParam<PrimitiveMode>(mode);
+ DrawElementsType typePacked = PackParam<DrawElementsType>(type);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateDrawElementsInstanced(context, angle::EntryPoint::GLDrawElementsInstanced,
+ modePacked, count, typePacked, indices, instancecount));
+ if (isCallValid)
+ {
+ context->drawElementsInstanced(modePacked, count, typePacked, indices, instancecount);
+ }
+ ANGLE_CAPTURE_GL(DrawElementsInstanced, isCallValid, context, modePacked, count, typePacked,
+ indices, instancecount);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DrawRangeElements(GLenum mode,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ GLenum type,
+ const void *indices)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDrawRangeElements,
+ "context = %d, mode = %s, start = %u, end = %u, count = %d, type = %s, indices = "
+ "0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::PrimitiveType, mode), start, end, count,
+ GLenumToString(GLESEnum::DrawElementsType, type), (uintptr_t)indices);
+
+ if (context)
+ {
+ PrimitiveMode modePacked = PackParam<PrimitiveMode>(mode);
+ DrawElementsType typePacked = PackParam<DrawElementsType>(type);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateDrawRangeElements(context, angle::EntryPoint::GLDrawRangeElements, modePacked,
+ start, end, count, typePacked, indices));
+ if (isCallValid)
+ {
+ context->drawRangeElements(modePacked, start, end, count, typePacked, indices);
+ }
+ ANGLE_CAPTURE_GL(DrawRangeElements, isCallValid, context, modePacked, start, end, count,
+ typePacked, indices);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_EndQuery(GLenum target)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLEndQuery, "context = %d, target = %s", CID(context),
+ GLenumToString(GLESEnum::QueryTarget, target));
+
+ if (context)
+ {
+ QueryType targetPacked = PackParam<QueryType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateEndQuery(context, angle::EntryPoint::GLEndQuery, targetPacked));
+ if (isCallValid)
+ {
+ context->endQuery(targetPacked);
+ }
+ ANGLE_CAPTURE_GL(EndQuery, isCallValid, context, targetPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_EndTransformFeedback()
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLEndTransformFeedback, "context = %d", CID(context));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateEndTransformFeedback(context, angle::EntryPoint::GLEndTransformFeedback));
+ if (isCallValid)
+ {
+ context->endTransformFeedback();
+ }
+ ANGLE_CAPTURE_GL(EndTransformFeedback, isCallValid, context);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+GLsync GL_APIENTRY GL_FenceSync(GLenum condition, GLbitfield flags)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLFenceSync, "context = %d, condition = %s, flags = %s", CID(context),
+ GLenumToString(GLESEnum::SyncCondition, condition),
+ GLbitfieldToString(GLESEnum::SyncBehaviorFlags, flags).c_str());
+
+ GLsync returnValue;
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateFenceSync(context, angle::EntryPoint::GLFenceSync, condition, flags));
+ if (isCallValid)
+ {
+ returnValue = context->fenceSync(condition, flags);
+ }
+ else
+ {
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLFenceSync, GLsync>();
+ }
+ ANGLE_CAPTURE_GL(FenceSync, isCallValid, context, condition, flags, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLFenceSync, GLsync>();
+ }
+ return returnValue;
+}
+
+void GL_APIENTRY GL_FlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLFlushMappedBufferRange,
+ "context = %d, target = %s, offset = %llu, length = %llu", CID(context),
+ GLenumToString(GLESEnum::BufferTargetARB, target),
+ static_cast<unsigned long long>(offset), static_cast<unsigned long long>(length));
+
+ if (context)
+ {
+ BufferBinding targetPacked = PackParam<BufferBinding>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateFlushMappedBufferRange(context, angle::EntryPoint::GLFlushMappedBufferRange,
+ targetPacked, offset, length));
+ if (isCallValid)
+ {
+ context->flushMappedBufferRange(targetPacked, offset, length);
+ }
+ ANGLE_CAPTURE_GL(FlushMappedBufferRange, isCallValid, context, targetPacked, offset,
+ length);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_FramebufferTextureLayer(GLenum target,
+ GLenum attachment,
+ GLuint texture,
+ GLint level,
+ GLint layer)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLFramebufferTextureLayer,
+ "context = %d, target = %s, attachment = %s, texture = %u, level = %d, layer = %d",
+ CID(context), GLenumToString(GLESEnum::FramebufferTarget, target),
+ GLenumToString(GLESEnum::FramebufferAttachment, attachment), texture, level, layer);
+
+ if (context)
+ {
+ TextureID texturePacked = PackParam<TextureID>(texture);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateFramebufferTextureLayer(context, angle::EntryPoint::GLFramebufferTextureLayer,
+ target, attachment, texturePacked, level, layer));
+ if (isCallValid)
+ {
+ context->framebufferTextureLayer(target, attachment, texturePacked, level, layer);
+ }
+ ANGLE_CAPTURE_GL(FramebufferTextureLayer, isCallValid, context, target, attachment,
+ texturePacked, level, layer);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GenQueries(GLsizei n, GLuint *ids)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGenQueries, "context = %d, n = %d, ids = 0x%016" PRIxPTR "", CID(context), n,
+ (uintptr_t)ids);
+
+ if (context)
+ {
+ QueryID *idsPacked = PackParam<QueryID *>(ids);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGenQueries(context, angle::EntryPoint::GLGenQueries, n, idsPacked));
+ if (isCallValid)
+ {
+ context->genQueries(n, idsPacked);
+ }
+ ANGLE_CAPTURE_GL(GenQueries, isCallValid, context, n, idsPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GenSamplers(GLsizei count, GLuint *samplers)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGenSamplers, "context = %d, count = %d, samplers = 0x%016" PRIxPTR "",
+ CID(context), count, (uintptr_t)samplers);
+
+ if (context)
+ {
+ SamplerID *samplersPacked = PackParam<SamplerID *>(samplers);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGenSamplers(context, angle::EntryPoint::GLGenSamplers, count, samplersPacked));
+ if (isCallValid)
+ {
+ context->genSamplers(count, samplersPacked);
+ }
+ ANGLE_CAPTURE_GL(GenSamplers, isCallValid, context, count, samplersPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GenTransformFeedbacks(GLsizei n, GLuint *ids)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGenTransformFeedbacks, "context = %d, n = %d, ids = 0x%016" PRIxPTR "",
+ CID(context), n, (uintptr_t)ids);
+
+ if (context)
+ {
+ TransformFeedbackID *idsPacked = PackParam<TransformFeedbackID *>(ids);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGenTransformFeedbacks(
+ context, angle::EntryPoint::GLGenTransformFeedbacks, n, idsPacked));
+ if (isCallValid)
+ {
+ context->genTransformFeedbacks(n, idsPacked);
+ }
+ ANGLE_CAPTURE_GL(GenTransformFeedbacks, isCallValid, context, n, idsPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GenVertexArrays(GLsizei n, GLuint *arrays)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGenVertexArrays, "context = %d, n = %d, arrays = 0x%016" PRIxPTR "",
+ CID(context), n, (uintptr_t)arrays);
+
+ if (context)
+ {
+ VertexArrayID *arraysPacked = PackParam<VertexArrayID *>(arrays);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGenVertexArrays(context, angle::EntryPoint::GLGenVertexArrays,
+ n, arraysPacked));
+ if (isCallValid)
+ {
+ context->genVertexArrays(n, arraysPacked);
+ }
+ ANGLE_CAPTURE_GL(GenVertexArrays, isCallValid, context, n, arraysPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetActiveUniformBlockName(GLuint program,
+ GLuint uniformBlockIndex,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *uniformBlockName)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(
+ context, GLGetActiveUniformBlockName,
+ "context = %d, program = %u, uniformBlockIndex = %u, bufSize = %d, length = 0x%016" PRIxPTR
+ ", uniformBlockName = 0x%016" PRIxPTR "",
+ CID(context), program, uniformBlockIndex, bufSize, (uintptr_t)length,
+ (uintptr_t)uniformBlockName);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformBlockIndex uniformBlockIndexPacked = PackParam<UniformBlockIndex>(uniformBlockIndex);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetActiveUniformBlockName(
+ context, angle::EntryPoint::GLGetActiveUniformBlockName, programPacked,
+ uniformBlockIndexPacked, bufSize, length, uniformBlockName));
+ if (isCallValid)
+ {
+ context->getActiveUniformBlockName(programPacked, uniformBlockIndexPacked, bufSize,
+ length, uniformBlockName);
+ }
+ ANGLE_CAPTURE_GL(GetActiveUniformBlockName, isCallValid, context, programPacked,
+ uniformBlockIndexPacked, bufSize, length, uniformBlockName);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetActiveUniformBlockiv(GLuint program,
+ GLuint uniformBlockIndex,
+ GLenum pname,
+ GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetActiveUniformBlockiv,
+ "context = %d, program = %u, uniformBlockIndex = %u, pname = %s, params = 0x%016" PRIxPTR
+ "",
+ CID(context), program, uniformBlockIndex,
+ GLenumToString(GLESEnum::UniformBlockPName, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformBlockIndex uniformBlockIndexPacked = PackParam<UniformBlockIndex>(uniformBlockIndex);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetActiveUniformBlockiv(
+ context, angle::EntryPoint::GLGetActiveUniformBlockiv,
+ programPacked, uniformBlockIndexPacked, pname, params));
+ if (isCallValid)
+ {
+ context->getActiveUniformBlockiv(programPacked, uniformBlockIndexPacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetActiveUniformBlockiv, isCallValid, context, programPacked,
+ uniformBlockIndexPacked, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetActiveUniformsiv(GLuint program,
+ GLsizei uniformCount,
+ const GLuint *uniformIndices,
+ GLenum pname,
+ GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetActiveUniformsiv,
+ "context = %d, program = %u, uniformCount = %d, uniformIndices = 0x%016" PRIxPTR
+ ", pname = %s, params = 0x%016" PRIxPTR "",
+ CID(context), program, uniformCount, (uintptr_t)uniformIndices,
+ GLenumToString(GLESEnum::UniformPName, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetActiveUniformsiv(
+ context, angle::EntryPoint::GLGetActiveUniformsiv, programPacked,
+ uniformCount, uniformIndices, pname, params));
+ if (isCallValid)
+ {
+ context->getActiveUniformsiv(programPacked, uniformCount, uniformIndices, pname,
+ params);
+ }
+ ANGLE_CAPTURE_GL(GetActiveUniformsiv, isCallValid, context, programPacked, uniformCount,
+ uniformIndices, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetBufferParameteri64v,
+ "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::BufferTargetARB, target),
+ GLenumToString(GLESEnum::AllEnums, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ BufferBinding targetPacked = PackParam<BufferBinding>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetBufferParameteri64v(context, angle::EntryPoint::GLGetBufferParameteri64v,
+ targetPacked, pname, params));
+ if (isCallValid)
+ {
+ context->getBufferParameteri64v(targetPacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetBufferParameteri64v, isCallValid, context, targetPacked, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetBufferPointerv(GLenum target, GLenum pname, void **params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetBufferPointerv,
+ "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::BufferTargetARB, target),
+ GLenumToString(GLESEnum::AllEnums, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ BufferBinding targetPacked = PackParam<BufferBinding>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetBufferPointerv(context, angle::EntryPoint::GLGetBufferPointerv,
+ targetPacked, pname, params));
+ if (isCallValid)
+ {
+ context->getBufferPointerv(targetPacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetBufferPointerv, isCallValid, context, targetPacked, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+GLint GL_APIENTRY GL_GetFragDataLocation(GLuint program, const GLchar *name)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetFragDataLocation, "context = %d, program = %u, name = 0x%016" PRIxPTR "",
+ CID(context), program, (uintptr_t)name);
+
+ GLint returnValue;
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetFragDataLocation(context, angle::EntryPoint::GLGetFragDataLocation,
+ programPacked, name));
+ if (isCallValid)
+ {
+ returnValue = context->getFragDataLocation(programPacked, name);
+ }
+ else
+ {
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLGetFragDataLocation, GLint>();
+ }
+ ANGLE_CAPTURE_GL(GetFragDataLocation, isCallValid, context, programPacked, name,
+ returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLGetFragDataLocation, GLint>();
+ }
+ return returnValue;
+}
+
+void GL_APIENTRY GL_GetInteger64i_v(GLenum target, GLuint index, GLint64 *data)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetInteger64i_v,
+ "context = %d, target = %s, index = %u, data = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::GetPName, target), index, (uintptr_t)data);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetInteger64i_v(context, angle::EntryPoint::GLGetInteger64i_v,
+ target, index, data));
+ if (isCallValid)
+ {
+ context->getInteger64i_v(target, index, data);
+ }
+ ANGLE_CAPTURE_GL(GetInteger64i_v, isCallValid, context, target, index, data);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetInteger64v(GLenum pname, GLint64 *data)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetInteger64v, "context = %d, pname = %s, data = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::GetPName, pname), (uintptr_t)data);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetInteger64v(context, angle::EntryPoint::GLGetInteger64v, pname, data));
+ if (isCallValid)
+ {
+ context->getInteger64v(pname, data);
+ }
+ ANGLE_CAPTURE_GL(GetInteger64v, isCallValid, context, pname, data);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetIntegeri_v(GLenum target, GLuint index, GLint *data)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetIntegeri_v,
+ "context = %d, target = %s, index = %u, data = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::GetPName, target), index, (uintptr_t)data);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetIntegeri_v(context, angle::EntryPoint::GLGetIntegeri_v,
+ target, index, data));
+ if (isCallValid)
+ {
+ context->getIntegeri_v(target, index, data);
+ }
+ ANGLE_CAPTURE_GL(GetIntegeri_v, isCallValid, context, target, index, data);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetInternalformativ(GLenum target,
+ GLenum internalformat,
+ GLenum pname,
+ GLsizei count,
+ GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetInternalformativ,
+ "context = %d, target = %s, internalformat = %s, pname = %s, count = %d, params = "
+ "0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target),
+ GLenumToString(GLESEnum::InternalFormat, internalformat),
+ GLenumToString(GLESEnum::InternalFormatPName, pname), count, (uintptr_t)params);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetInternalformativ(context, angle::EntryPoint::GLGetInternalformativ, target,
+ internalformat, pname, count, params));
+ if (isCallValid)
+ {
+ context->getInternalformativ(target, internalformat, pname, count, params);
+ }
+ ANGLE_CAPTURE_GL(GetInternalformativ, isCallValid, context, target, internalformat, pname,
+ count, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetProgramBinary(GLuint program,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLenum *binaryFormat,
+ void *binary)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetProgramBinary,
+ "context = %d, program = %u, bufSize = %d, length = 0x%016" PRIxPTR
+ ", binaryFormat = 0x%016" PRIxPTR ", binary = 0x%016" PRIxPTR "",
+ CID(context), program, bufSize, (uintptr_t)length, (uintptr_t)binaryFormat,
+ (uintptr_t)binary);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetProgramBinary(context, angle::EntryPoint::GLGetProgramBinary, programPacked,
+ bufSize, length, binaryFormat, binary));
+ if (isCallValid)
+ {
+ context->getProgramBinary(programPacked, bufSize, length, binaryFormat, binary);
+ }
+ ANGLE_CAPTURE_GL(GetProgramBinary, isCallValid, context, programPacked, bufSize, length,
+ binaryFormat, binary);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetQueryObjectuiv,
+ "context = %d, id = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context), id,
+ GLenumToString(GLESEnum::QueryObjectParameterName, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ QueryID idPacked = PackParam<QueryID>(id);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetQueryObjectuiv(context, angle::EntryPoint::GLGetQueryObjectuiv, idPacked,
+ pname, params));
+ if (isCallValid)
+ {
+ context->getQueryObjectuiv(idPacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetQueryObjectuiv, isCallValid, context, idPacked, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetQueryiv(GLenum target, GLenum pname, GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetQueryiv,
+ "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::QueryTarget, target),
+ GLenumToString(GLESEnum::QueryParameterName, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ QueryType targetPacked = PackParam<QueryType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetQueryiv(context, angle::EntryPoint::GLGetQueryiv,
+ targetPacked, pname, params));
+ if (isCallValid)
+ {
+ context->getQueryiv(targetPacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetQueryiv, isCallValid, context, targetPacked, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetSamplerParameterfv,
+ "context = %d, sampler = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ sampler, GLenumToString(GLESEnum::SamplerParameterF, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ SamplerID samplerPacked = PackParam<SamplerID>(sampler);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetSamplerParameterfv(context, angle::EntryPoint::GLGetSamplerParameterfv,
+ samplerPacked, pname, params));
+ if (isCallValid)
+ {
+ context->getSamplerParameterfv(samplerPacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetSamplerParameterfv, isCallValid, context, samplerPacked, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetSamplerParameteriv,
+ "context = %d, sampler = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ sampler, GLenumToString(GLESEnum::SamplerParameterI, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ SamplerID samplerPacked = PackParam<SamplerID>(sampler);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetSamplerParameteriv(context, angle::EntryPoint::GLGetSamplerParameteriv,
+ samplerPacked, pname, params));
+ if (isCallValid)
+ {
+ context->getSamplerParameteriv(samplerPacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetSamplerParameteriv, isCallValid, context, samplerPacked, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+const GLubyte *GL_APIENTRY GL_GetStringi(GLenum name, GLuint index)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetStringi, "context = %d, name = %s, index = %u", CID(context),
+ GLenumToString(GLESEnum::StringName, name), index);
+
+ const GLubyte *returnValue;
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetStringi(context, angle::EntryPoint::GLGetStringi, name, index));
+ if (isCallValid)
+ {
+ returnValue = context->getStringi(name, index);
+ }
+ else
+ {
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLGetStringi, const GLubyte *>();
+ }
+ ANGLE_CAPTURE_GL(GetStringi, isCallValid, context, name, index, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLGetStringi, const GLubyte *>();
+ }
+ return returnValue;
+}
+
+void GL_APIENTRY
+GL_GetSynciv(GLsync sync, GLenum pname, GLsizei count, GLsizei *length, GLint *values)
+{
+ Context *context = GetGlobalContext();
+ EVENT(context, GLGetSynciv,
+ "context = %d, sync = 0x%016" PRIxPTR ", pname = %s, count = %d, length = 0x%016" PRIxPTR
+ ", values = 0x%016" PRIxPTR "",
+ CID(context), (uintptr_t)sync, GLenumToString(GLESEnum::SyncParameterName, pname), count,
+ (uintptr_t)length, (uintptr_t)values);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() || ValidateGetSynciv(context, angle::EntryPoint::GLGetSynciv,
+ sync, pname, count, length, values));
+ if (isCallValid)
+ {
+ context->getSynciv(sync, pname, count, length, values);
+ }
+ ANGLE_CAPTURE_GL(GetSynciv, isCallValid, context, sync, pname, count, length, values);
+ }
+ else
+ {}
+}
+
+void GL_APIENTRY GL_GetTransformFeedbackVarying(GLuint program,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLsizei *size,
+ GLenum *type,
+ GLchar *name)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetTransformFeedbackVarying,
+ "context = %d, program = %u, index = %u, bufSize = %d, length = 0x%016" PRIxPTR
+ ", size = 0x%016" PRIxPTR ", type = 0x%016" PRIxPTR ", name = 0x%016" PRIxPTR "",
+ CID(context), program, index, bufSize, (uintptr_t)length, (uintptr_t)size,
+ (uintptr_t)type, (uintptr_t)name);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetTransformFeedbackVarying(
+ context, angle::EntryPoint::GLGetTransformFeedbackVarying,
+ programPacked, index, bufSize, length, size, type, name));
+ if (isCallValid)
+ {
+ context->getTransformFeedbackVarying(programPacked, index, bufSize, length, size, type,
+ name);
+ }
+ ANGLE_CAPTURE_GL(GetTransformFeedbackVarying, isCallValid, context, programPacked, index,
+ bufSize, length, size, type, name);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+GLuint GL_APIENTRY GL_GetUniformBlockIndex(GLuint program, const GLchar *uniformBlockName)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetUniformBlockIndex,
+ "context = %d, program = %u, uniformBlockName = 0x%016" PRIxPTR "", CID(context), program,
+ (uintptr_t)uniformBlockName);
+
+ GLuint returnValue;
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetUniformBlockIndex(context, angle::EntryPoint::GLGetUniformBlockIndex,
+ programPacked, uniformBlockName));
+ if (isCallValid)
+ {
+ returnValue = context->getUniformBlockIndex(programPacked, uniformBlockName);
+ }
+ else
+ {
+ returnValue =
+ GetDefaultReturnValue<angle::EntryPoint::GLGetUniformBlockIndex, GLuint>();
+ }
+ ANGLE_CAPTURE_GL(GetUniformBlockIndex, isCallValid, context, programPacked,
+ uniformBlockName, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLGetUniformBlockIndex, GLuint>();
+ }
+ return returnValue;
+}
+
+void GL_APIENTRY GL_GetUniformIndices(GLuint program,
+ GLsizei uniformCount,
+ const GLchar *const *uniformNames,
+ GLuint *uniformIndices)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetUniformIndices,
+ "context = %d, program = %u, uniformCount = %d, uniformNames = 0x%016" PRIxPTR
+ ", uniformIndices = 0x%016" PRIxPTR "",
+ CID(context), program, uniformCount, (uintptr_t)uniformNames, (uintptr_t)uniformIndices);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetUniformIndices(context, angle::EntryPoint::GLGetUniformIndices,
+ programPacked, uniformCount, uniformNames, uniformIndices));
+ if (isCallValid)
+ {
+ context->getUniformIndices(programPacked, uniformCount, uniformNames, uniformIndices);
+ }
+ ANGLE_CAPTURE_GL(GetUniformIndices, isCallValid, context, programPacked, uniformCount,
+ uniformNames, uniformIndices);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetUniformuiv(GLuint program, GLint location, GLuint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetUniformuiv,
+ "context = %d, program = %u, location = %d, params = 0x%016" PRIxPTR "", CID(context),
+ program, location, (uintptr_t)params);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetUniformuiv(context, angle::EntryPoint::GLGetUniformuiv,
+ programPacked, locationPacked, params));
+ if (isCallValid)
+ {
+ context->getUniformuiv(programPacked, locationPacked, params);
+ }
+ ANGLE_CAPTURE_GL(GetUniformuiv, isCallValid, context, programPacked, locationPacked,
+ params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetVertexAttribIiv,
+ "context = %d, index = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context), index,
+ GLenumToString(GLESEnum::VertexAttribEnum, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetVertexAttribIiv(context, angle::EntryPoint::GLGetVertexAttribIiv, index,
+ pname, params));
+ if (isCallValid)
+ {
+ context->getVertexAttribIiv(index, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetVertexAttribIiv, isCallValid, context, index, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetVertexAttribIuiv,
+ "context = %d, index = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context), index,
+ GLenumToString(GLESEnum::VertexAttribEnum, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetVertexAttribIuiv(context, angle::EntryPoint::GLGetVertexAttribIuiv, index,
+ pname, params));
+ if (isCallValid)
+ {
+ context->getVertexAttribIuiv(index, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetVertexAttribIuiv, isCallValid, context, index, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_InvalidateFramebuffer(GLenum target,
+ GLsizei numAttachments,
+ const GLenum *attachments)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLInvalidateFramebuffer,
+ "context = %d, target = %s, numAttachments = %d, attachments = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::FramebufferTarget, target), numAttachments,
+ (uintptr_t)attachments);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateInvalidateFramebuffer(context, angle::EntryPoint::GLInvalidateFramebuffer,
+ target, numAttachments, attachments));
+ if (isCallValid)
+ {
+ context->invalidateFramebuffer(target, numAttachments, attachments);
+ }
+ ANGLE_CAPTURE_GL(InvalidateFramebuffer, isCallValid, context, target, numAttachments,
+ attachments);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_InvalidateSubFramebuffer(GLenum target,
+ GLsizei numAttachments,
+ const GLenum *attachments,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLInvalidateSubFramebuffer,
+ "context = %d, target = %s, numAttachments = %d, attachments = 0x%016" PRIxPTR
+ ", x = %d, y = %d, width = %d, height = %d",
+ CID(context), GLenumToString(GLESEnum::FramebufferTarget, target), numAttachments,
+ (uintptr_t)attachments, x, y, width, height);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateInvalidateSubFramebuffer(
+ context, angle::EntryPoint::GLInvalidateSubFramebuffer, target,
+ numAttachments, attachments, x, y, width, height));
+ if (isCallValid)
+ {
+ context->invalidateSubFramebuffer(target, numAttachments, attachments, x, y, width,
+ height);
+ }
+ ANGLE_CAPTURE_GL(InvalidateSubFramebuffer, isCallValid, context, target, numAttachments,
+ attachments, x, y, width, height);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+GLboolean GL_APIENTRY GL_IsQuery(GLuint id)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLIsQuery, "context = %d, id = %u", CID(context), id);
+
+ GLboolean returnValue;
+ if (context)
+ {
+ QueryID idPacked = PackParam<QueryID>(id);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateIsQuery(context, angle::EntryPoint::GLIsQuery, idPacked));
+ if (isCallValid)
+ {
+ returnValue = context->isQuery(idPacked);
+ }
+ else
+ {
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsQuery, GLboolean>();
+ }
+ ANGLE_CAPTURE_GL(IsQuery, isCallValid, context, idPacked, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsQuery, GLboolean>();
+ }
+ return returnValue;
+}
+
+GLboolean GL_APIENTRY GL_IsSampler(GLuint sampler)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLIsSampler, "context = %d, sampler = %u", CID(context), sampler);
+
+ GLboolean returnValue;
+ if (context)
+ {
+ SamplerID samplerPacked = PackParam<SamplerID>(sampler);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateIsSampler(context, angle::EntryPoint::GLIsSampler, samplerPacked));
+ if (isCallValid)
+ {
+ returnValue = context->isSampler(samplerPacked);
+ }
+ else
+ {
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsSampler, GLboolean>();
+ }
+ ANGLE_CAPTURE_GL(IsSampler, isCallValid, context, samplerPacked, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsSampler, GLboolean>();
+ }
+ return returnValue;
+}
+
+GLboolean GL_APIENTRY GL_IsSync(GLsync sync)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLIsSync, "context = %d, sync = 0x%016" PRIxPTR "", CID(context),
+ (uintptr_t)sync);
+
+ GLboolean returnValue;
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateIsSync(context, angle::EntryPoint::GLIsSync, sync));
+ if (isCallValid)
+ {
+ returnValue = context->isSync(sync);
+ }
+ else
+ {
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsSync, GLboolean>();
+ }
+ ANGLE_CAPTURE_GL(IsSync, isCallValid, context, sync, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsSync, GLboolean>();
+ }
+ return returnValue;
+}
+
+GLboolean GL_APIENTRY GL_IsTransformFeedback(GLuint id)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLIsTransformFeedback, "context = %d, id = %u", CID(context), id);
+
+ GLboolean returnValue;
+ if (context)
+ {
+ TransformFeedbackID idPacked = PackParam<TransformFeedbackID>(id);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateIsTransformFeedback(
+ context, angle::EntryPoint::GLIsTransformFeedback, idPacked));
+ if (isCallValid)
+ {
+ returnValue = context->isTransformFeedback(idPacked);
+ }
+ else
+ {
+ returnValue =
+ GetDefaultReturnValue<angle::EntryPoint::GLIsTransformFeedback, GLboolean>();
+ }
+ ANGLE_CAPTURE_GL(IsTransformFeedback, isCallValid, context, idPacked, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsTransformFeedback, GLboolean>();
+ }
+ return returnValue;
+}
+
+GLboolean GL_APIENTRY GL_IsVertexArray(GLuint array)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLIsVertexArray, "context = %d, array = %u", CID(context), array);
+
+ GLboolean returnValue;
+ if (context)
+ {
+ VertexArrayID arrayPacked = PackParam<VertexArrayID>(array);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateIsVertexArray(context, angle::EntryPoint::GLIsVertexArray, arrayPacked));
+ if (isCallValid)
+ {
+ returnValue = context->isVertexArray(arrayPacked);
+ }
+ else
+ {
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsVertexArray, GLboolean>();
+ }
+ ANGLE_CAPTURE_GL(IsVertexArray, isCallValid, context, arrayPacked, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsVertexArray, GLboolean>();
+ }
+ return returnValue;
+}
+
+void *GL_APIENTRY GL_MapBufferRange(GLenum target,
+ GLintptr offset,
+ GLsizeiptr length,
+ GLbitfield access)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLMapBufferRange,
+ "context = %d, target = %s, offset = %llu, length = %llu, access = %s", CID(context),
+ GLenumToString(GLESEnum::BufferTargetARB, target),
+ static_cast<unsigned long long>(offset), static_cast<unsigned long long>(length),
+ GLbitfieldToString(GLESEnum::MapBufferAccessMask, access).c_str());
+
+ void *returnValue;
+ if (context)
+ {
+ BufferBinding targetPacked = PackParam<BufferBinding>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateMapBufferRange(context, angle::EntryPoint::GLMapBufferRange,
+ targetPacked, offset, length, access));
+ if (isCallValid)
+ {
+ returnValue = context->mapBufferRange(targetPacked, offset, length, access);
+ }
+ else
+ {
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLMapBufferRange, void *>();
+ }
+ ANGLE_CAPTURE_GL(MapBufferRange, isCallValid, context, targetPacked, offset, length, access,
+ returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLMapBufferRange, void *>();
+ }
+ return returnValue;
+}
+
+void GL_APIENTRY GL_PauseTransformFeedback()
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLPauseTransformFeedback, "context = %d", CID(context));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidatePauseTransformFeedback(context, angle::EntryPoint::GLPauseTransformFeedback));
+ if (isCallValid)
+ {
+ context->pauseTransformFeedback();
+ }
+ ANGLE_CAPTURE_GL(PauseTransformFeedback, isCallValid, context);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramBinary(GLuint program,
+ GLenum binaryFormat,
+ const void *binary,
+ GLsizei length)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramBinary,
+ "context = %d, program = %u, binaryFormat = %s, binary = 0x%016" PRIxPTR ", length = %d",
+ CID(context), program, GLenumToString(GLESEnum::AllEnums, binaryFormat),
+ (uintptr_t)binary, length);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateProgramBinary(context, angle::EntryPoint::GLProgramBinary,
+ programPacked, binaryFormat, binary, length));
+ if (isCallValid)
+ {
+ context->programBinary(programPacked, binaryFormat, binary, length);
+ }
+ ANGLE_CAPTURE_GL(ProgramBinary, isCallValid, context, programPacked, binaryFormat, binary,
+ length);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramParameteri(GLuint program, GLenum pname, GLint value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramParameteri, "context = %d, program = %u, pname = %s, value = %d",
+ CID(context), program, GLenumToString(GLESEnum::ProgramParameterPName, pname), value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramParameteri(context, angle::EntryPoint::GLProgramParameteri,
+ programPacked, pname, value));
+ if (isCallValid)
+ {
+ context->programParameteri(programPacked, pname, value);
+ }
+ ANGLE_CAPTURE_GL(ProgramParameteri, isCallValid, context, programPacked, pname, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ReadBuffer(GLenum src)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLReadBuffer, "context = %d, src = %s", CID(context),
+ GLenumToString(GLESEnum::ReadBufferMode, src));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateReadBuffer(context, angle::EntryPoint::GLReadBuffer, src));
+ if (isCallValid)
+ {
+ context->readBuffer(src);
+ }
+ ANGLE_CAPTURE_GL(ReadBuffer, isCallValid, context, src);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_RenderbufferStorageMultisample(GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLRenderbufferStorageMultisample,
+ "context = %d, target = %s, samples = %d, internalformat = %s, width = %d, height = %d",
+ CID(context), GLenumToString(GLESEnum::RenderbufferTarget, target), samples,
+ GLenumToString(GLESEnum::InternalFormat, internalformat), width, height);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateRenderbufferStorageMultisample(
+ context, angle::EntryPoint::GLRenderbufferStorageMultisample,
+ target, samples, internalformat, width, height));
+ if (isCallValid)
+ {
+ context->renderbufferStorageMultisample(target, samples, internalformat, width, height);
+ }
+ ANGLE_CAPTURE_GL(RenderbufferStorageMultisample, isCallValid, context, target, samples,
+ internalformat, width, height);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ResumeTransformFeedback()
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLResumeTransformFeedback, "context = %d", CID(context));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateResumeTransformFeedback(
+ context, angle::EntryPoint::GLResumeTransformFeedback));
+ if (isCallValid)
+ {
+ context->resumeTransformFeedback();
+ }
+ ANGLE_CAPTURE_GL(ResumeTransformFeedback, isCallValid, context);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLSamplerParameterf, "context = %d, sampler = %u, pname = %s, param = %f",
+ CID(context), sampler, GLenumToString(GLESEnum::SamplerParameterF, pname), param);
+
+ if (context)
+ {
+ SamplerID samplerPacked = PackParam<SamplerID>(sampler);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateSamplerParameterf(context, angle::EntryPoint::GLSamplerParameterf,
+ samplerPacked, pname, param));
+ if (isCallValid)
+ {
+ context->samplerParameterf(samplerPacked, pname, param);
+ }
+ ANGLE_CAPTURE_GL(SamplerParameterf, isCallValid, context, samplerPacked, pname, param);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_SamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLSamplerParameterfv,
+ "context = %d, sampler = %u, pname = %s, param = 0x%016" PRIxPTR "", CID(context),
+ sampler, GLenumToString(GLESEnum::SamplerParameterF, pname), (uintptr_t)param);
+
+ if (context)
+ {
+ SamplerID samplerPacked = PackParam<SamplerID>(sampler);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateSamplerParameterfv(context, angle::EntryPoint::GLSamplerParameterfv,
+ samplerPacked, pname, param));
+ if (isCallValid)
+ {
+ context->samplerParameterfv(samplerPacked, pname, param);
+ }
+ ANGLE_CAPTURE_GL(SamplerParameterfv, isCallValid, context, samplerPacked, pname, param);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_SamplerParameteri(GLuint sampler, GLenum pname, GLint param)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLSamplerParameteri, "context = %d, sampler = %u, pname = %s, param = %d",
+ CID(context), sampler, GLenumToString(GLESEnum::SamplerParameterI, pname), param);
+
+ if (context)
+ {
+ SamplerID samplerPacked = PackParam<SamplerID>(sampler);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateSamplerParameteri(context, angle::EntryPoint::GLSamplerParameteri,
+ samplerPacked, pname, param));
+ if (isCallValid)
+ {
+ context->samplerParameteri(samplerPacked, pname, param);
+ }
+ ANGLE_CAPTURE_GL(SamplerParameteri, isCallValid, context, samplerPacked, pname, param);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_SamplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLSamplerParameteriv,
+ "context = %d, sampler = %u, pname = %s, param = 0x%016" PRIxPTR "", CID(context),
+ sampler, GLenumToString(GLESEnum::SamplerParameterI, pname), (uintptr_t)param);
+
+ if (context)
+ {
+ SamplerID samplerPacked = PackParam<SamplerID>(sampler);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateSamplerParameteriv(context, angle::EntryPoint::GLSamplerParameteriv,
+ samplerPacked, pname, param));
+ if (isCallValid)
+ {
+ context->samplerParameteriv(samplerPacked, pname, param);
+ }
+ ANGLE_CAPTURE_GL(SamplerParameteriv, isCallValid, context, samplerPacked, pname, param);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexImage3D(GLenum target,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexImage3D,
+ "context = %d, target = %s, level = %d, internalformat = %d, width = %d, height = %d, "
+ "depth = %d, border = %d, format = %s, type = %s, pixels = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target), level, internalformat,
+ width, height, depth, border, GLenumToString(GLESEnum::PixelFormat, format),
+ GLenumToString(GLESEnum::PixelType, type), (uintptr_t)pixels);
+
+ if (context)
+ {
+ TextureTarget targetPacked = PackParam<TextureTarget>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateTexImage3D(context, angle::EntryPoint::GLTexImage3D,
+ targetPacked, level, internalformat, width, height,
+ depth, border, format, type, pixels));
+ if (isCallValid)
+ {
+ context->texImage3D(targetPacked, level, internalformat, width, height, depth, border,
+ format, type, pixels);
+ }
+ ANGLE_CAPTURE_GL(TexImage3D, isCallValid, context, targetPacked, level, internalformat,
+ width, height, depth, border, format, type, pixels);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY
+GL_TexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexStorage2D,
+ "context = %d, target = %s, levels = %d, internalformat = %s, width = %d, height = %d",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target), levels,
+ GLenumToString(GLESEnum::SizedInternalFormat, internalformat), width, height);
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateTexStorage2D(context, angle::EntryPoint::GLTexStorage2D, targetPacked, levels,
+ internalformat, width, height));
+ if (isCallValid)
+ {
+ context->texStorage2D(targetPacked, levels, internalformat, width, height);
+ }
+ ANGLE_CAPTURE_GL(TexStorage2D, isCallValid, context, targetPacked, levels, internalformat,
+ width, height);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexStorage3D(GLenum target,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexStorage3D,
+ "context = %d, target = %s, levels = %d, internalformat = %s, width = %d, height = %d, "
+ "depth = %d",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target), levels,
+ GLenumToString(GLESEnum::SizedInternalFormat, internalformat), width, height, depth);
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateTexStorage3D(context, angle::EntryPoint::GLTexStorage3D, targetPacked, levels,
+ internalformat, width, height, depth));
+ if (isCallValid)
+ {
+ context->texStorage3D(targetPacked, levels, internalformat, width, height, depth);
+ }
+ ANGLE_CAPTURE_GL(TexStorage3D, isCallValid, context, targetPacked, levels, internalformat,
+ width, height, depth);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexSubImage3D(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexSubImage3D,
+ "context = %d, target = %s, level = %d, xoffset = %d, yoffset = %d, zoffset = %d, width "
+ "= %d, height = %d, depth = %d, format = %s, type = %s, pixels = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target), level, xoffset, yoffset,
+ zoffset, width, height, depth, GLenumToString(GLESEnum::PixelFormat, format),
+ GLenumToString(GLESEnum::PixelType, type), (uintptr_t)pixels);
+
+ if (context)
+ {
+ TextureTarget targetPacked = PackParam<TextureTarget>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateTexSubImage3D(context, angle::EntryPoint::GLTexSubImage3D,
+ targetPacked, level, xoffset, yoffset, zoffset,
+ width, height, depth, format, type, pixels));
+ if (isCallValid)
+ {
+ context->texSubImage3D(targetPacked, level, xoffset, yoffset, zoffset, width, height,
+ depth, format, type, pixels);
+ }
+ ANGLE_CAPTURE_GL(TexSubImage3D, isCallValid, context, targetPacked, level, xoffset, yoffset,
+ zoffset, width, height, depth, format, type, pixels);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TransformFeedbackVaryings(GLuint program,
+ GLsizei count,
+ const GLchar *const *varyings,
+ GLenum bufferMode)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTransformFeedbackVaryings,
+ "context = %d, program = %u, count = %d, varyings = 0x%016" PRIxPTR ", bufferMode = %s",
+ CID(context), program, count, (uintptr_t)varyings,
+ GLenumToString(GLESEnum::TransformFeedbackBufferMode, bufferMode));
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateTransformFeedbackVaryings(
+ context, angle::EntryPoint::GLTransformFeedbackVaryings,
+ programPacked, count, varyings, bufferMode));
+ if (isCallValid)
+ {
+ context->transformFeedbackVaryings(programPacked, count, varyings, bufferMode);
+ }
+ ANGLE_CAPTURE_GL(TransformFeedbackVaryings, isCallValid, context, programPacked, count,
+ varyings, bufferMode);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Uniform1ui(GLint location, GLuint v0)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLUniform1ui, "context = %d, location = %d, v0 = %u", CID(context), location,
+ v0);
+
+ if (context)
+ {
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateUniform1ui(context, angle::EntryPoint::GLUniform1ui, locationPacked, v0));
+ if (isCallValid)
+ {
+ context->uniform1ui(locationPacked, v0);
+ }
+ ANGLE_CAPTURE_GL(Uniform1ui, isCallValid, context, locationPacked, v0);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Uniform1uiv(GLint location, GLsizei count, const GLuint *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLUniform1uiv,
+ "context = %d, location = %d, count = %d, value = 0x%016" PRIxPTR "", CID(context),
+ location, count, (uintptr_t)value);
+
+ if (context)
+ {
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateUniform1uiv(context, angle::EntryPoint::GLUniform1uiv,
+ locationPacked, count, value));
+ if (isCallValid)
+ {
+ context->uniform1uiv(locationPacked, count, value);
+ }
+ ANGLE_CAPTURE_GL(Uniform1uiv, isCallValid, context, locationPacked, count, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Uniform2ui(GLint location, GLuint v0, GLuint v1)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLUniform2ui, "context = %d, location = %d, v0 = %u, v1 = %u", CID(context),
+ location, v0, v1);
+
+ if (context)
+ {
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateUniform2ui(context, angle::EntryPoint::GLUniform2ui, locationPacked, v0, v1));
+ if (isCallValid)
+ {
+ context->uniform2ui(locationPacked, v0, v1);
+ }
+ ANGLE_CAPTURE_GL(Uniform2ui, isCallValid, context, locationPacked, v0, v1);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Uniform2uiv(GLint location, GLsizei count, const GLuint *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLUniform2uiv,
+ "context = %d, location = %d, count = %d, value = 0x%016" PRIxPTR "", CID(context),
+ location, count, (uintptr_t)value);
+
+ if (context)
+ {
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateUniform2uiv(context, angle::EntryPoint::GLUniform2uiv,
+ locationPacked, count, value));
+ if (isCallValid)
+ {
+ context->uniform2uiv(locationPacked, count, value);
+ }
+ ANGLE_CAPTURE_GL(Uniform2uiv, isCallValid, context, locationPacked, count, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLUniform3ui, "context = %d, location = %d, v0 = %u, v1 = %u, v2 = %u",
+ CID(context), location, v0, v1, v2);
+
+ if (context)
+ {
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateUniform3ui(context, angle::EntryPoint::GLUniform3ui,
+ locationPacked, v0, v1, v2));
+ if (isCallValid)
+ {
+ context->uniform3ui(locationPacked, v0, v1, v2);
+ }
+ ANGLE_CAPTURE_GL(Uniform3ui, isCallValid, context, locationPacked, v0, v1, v2);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Uniform3uiv(GLint location, GLsizei count, const GLuint *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLUniform3uiv,
+ "context = %d, location = %d, count = %d, value = 0x%016" PRIxPTR "", CID(context),
+ location, count, (uintptr_t)value);
+
+ if (context)
+ {
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateUniform3uiv(context, angle::EntryPoint::GLUniform3uiv,
+ locationPacked, count, value));
+ if (isCallValid)
+ {
+ context->uniform3uiv(locationPacked, count, value);
+ }
+ ANGLE_CAPTURE_GL(Uniform3uiv, isCallValid, context, locationPacked, count, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLUniform4ui, "context = %d, location = %d, v0 = %u, v1 = %u, v2 = %u, v3 = %u",
+ CID(context), location, v0, v1, v2, v3);
+
+ if (context)
+ {
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateUniform4ui(context, angle::EntryPoint::GLUniform4ui,
+ locationPacked, v0, v1, v2, v3));
+ if (isCallValid)
+ {
+ context->uniform4ui(locationPacked, v0, v1, v2, v3);
+ }
+ ANGLE_CAPTURE_GL(Uniform4ui, isCallValid, context, locationPacked, v0, v1, v2, v3);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Uniform4uiv(GLint location, GLsizei count, const GLuint *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLUniform4uiv,
+ "context = %d, location = %d, count = %d, value = 0x%016" PRIxPTR "", CID(context),
+ location, count, (uintptr_t)value);
+
+ if (context)
+ {
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateUniform4uiv(context, angle::EntryPoint::GLUniform4uiv,
+ locationPacked, count, value));
+ if (isCallValid)
+ {
+ context->uniform4uiv(locationPacked, count, value);
+ }
+ ANGLE_CAPTURE_GL(Uniform4uiv, isCallValid, context, locationPacked, count, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_UniformBlockBinding(GLuint program,
+ GLuint uniformBlockIndex,
+ GLuint uniformBlockBinding)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLUniformBlockBinding,
+ "context = %d, program = %u, uniformBlockIndex = %u, uniformBlockBinding = %u",
+ CID(context), program, uniformBlockIndex, uniformBlockBinding);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformBlockIndex uniformBlockIndexPacked = PackParam<UniformBlockIndex>(uniformBlockIndex);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateUniformBlockBinding(
+ context, angle::EntryPoint::GLUniformBlockBinding, programPacked,
+ uniformBlockIndexPacked, uniformBlockBinding));
+ if (isCallValid)
+ {
+ context->uniformBlockBinding(programPacked, uniformBlockIndexPacked,
+ uniformBlockBinding);
+ }
+ ANGLE_CAPTURE_GL(UniformBlockBinding, isCallValid, context, programPacked,
+ uniformBlockIndexPacked, uniformBlockBinding);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_UniformMatrix2x3fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLUniformMatrix2x3fv,
+ "context = %d, location = %d, count = %d, transpose = %s, value = 0x%016" PRIxPTR "",
+ CID(context), location, count, GLbooleanToString(transpose), (uintptr_t)value);
+
+ if (context)
+ {
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateUniformMatrix2x3fv(context, angle::EntryPoint::GLUniformMatrix2x3fv,
+ locationPacked, count, transpose, value));
+ if (isCallValid)
+ {
+ context->uniformMatrix2x3fv(locationPacked, count, transpose, value);
+ }
+ ANGLE_CAPTURE_GL(UniformMatrix2x3fv, isCallValid, context, locationPacked, count, transpose,
+ value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_UniformMatrix2x4fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLUniformMatrix2x4fv,
+ "context = %d, location = %d, count = %d, transpose = %s, value = 0x%016" PRIxPTR "",
+ CID(context), location, count, GLbooleanToString(transpose), (uintptr_t)value);
+
+ if (context)
+ {
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateUniformMatrix2x4fv(context, angle::EntryPoint::GLUniformMatrix2x4fv,
+ locationPacked, count, transpose, value));
+ if (isCallValid)
+ {
+ context->uniformMatrix2x4fv(locationPacked, count, transpose, value);
+ }
+ ANGLE_CAPTURE_GL(UniformMatrix2x4fv, isCallValid, context, locationPacked, count, transpose,
+ value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_UniformMatrix3x2fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLUniformMatrix3x2fv,
+ "context = %d, location = %d, count = %d, transpose = %s, value = 0x%016" PRIxPTR "",
+ CID(context), location, count, GLbooleanToString(transpose), (uintptr_t)value);
+
+ if (context)
+ {
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateUniformMatrix3x2fv(context, angle::EntryPoint::GLUniformMatrix3x2fv,
+ locationPacked, count, transpose, value));
+ if (isCallValid)
+ {
+ context->uniformMatrix3x2fv(locationPacked, count, transpose, value);
+ }
+ ANGLE_CAPTURE_GL(UniformMatrix3x2fv, isCallValid, context, locationPacked, count, transpose,
+ value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_UniformMatrix3x4fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLUniformMatrix3x4fv,
+ "context = %d, location = %d, count = %d, transpose = %s, value = 0x%016" PRIxPTR "",
+ CID(context), location, count, GLbooleanToString(transpose), (uintptr_t)value);
+
+ if (context)
+ {
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateUniformMatrix3x4fv(context, angle::EntryPoint::GLUniformMatrix3x4fv,
+ locationPacked, count, transpose, value));
+ if (isCallValid)
+ {
+ context->uniformMatrix3x4fv(locationPacked, count, transpose, value);
+ }
+ ANGLE_CAPTURE_GL(UniformMatrix3x4fv, isCallValid, context, locationPacked, count, transpose,
+ value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_UniformMatrix4x2fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLUniformMatrix4x2fv,
+ "context = %d, location = %d, count = %d, transpose = %s, value = 0x%016" PRIxPTR "",
+ CID(context), location, count, GLbooleanToString(transpose), (uintptr_t)value);
+
+ if (context)
+ {
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateUniformMatrix4x2fv(context, angle::EntryPoint::GLUniformMatrix4x2fv,
+ locationPacked, count, transpose, value));
+ if (isCallValid)
+ {
+ context->uniformMatrix4x2fv(locationPacked, count, transpose, value);
+ }
+ ANGLE_CAPTURE_GL(UniformMatrix4x2fv, isCallValid, context, locationPacked, count, transpose,
+ value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_UniformMatrix4x3fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLUniformMatrix4x3fv,
+ "context = %d, location = %d, count = %d, transpose = %s, value = 0x%016" PRIxPTR "",
+ CID(context), location, count, GLbooleanToString(transpose), (uintptr_t)value);
+
+ if (context)
+ {
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateUniformMatrix4x3fv(context, angle::EntryPoint::GLUniformMatrix4x3fv,
+ locationPacked, count, transpose, value));
+ if (isCallValid)
+ {
+ context->uniformMatrix4x3fv(locationPacked, count, transpose, value);
+ }
+ ANGLE_CAPTURE_GL(UniformMatrix4x3fv, isCallValid, context, locationPacked, count, transpose,
+ value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+GLboolean GL_APIENTRY GL_UnmapBuffer(GLenum target)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLUnmapBuffer, "context = %d, target = %s", CID(context),
+ GLenumToString(GLESEnum::BufferTargetARB, target));
+
+ GLboolean returnValue;
+ if (context)
+ {
+ BufferBinding targetPacked = PackParam<BufferBinding>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateUnmapBuffer(context, angle::EntryPoint::GLUnmapBuffer, targetPacked));
+ if (isCallValid)
+ {
+ returnValue = context->unmapBuffer(targetPacked);
+ }
+ else
+ {
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLUnmapBuffer, GLboolean>();
+ }
+ ANGLE_CAPTURE_GL(UnmapBuffer, isCallValid, context, targetPacked, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLUnmapBuffer, GLboolean>();
+ }
+ return returnValue;
+}
+
+void GL_APIENTRY GL_VertexAttribDivisor(GLuint index, GLuint divisor)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLVertexAttribDivisor, "context = %d, index = %u, divisor = %u", CID(context),
+ index, divisor);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateVertexAttribDivisor(
+ context, angle::EntryPoint::GLVertexAttribDivisor, index, divisor));
+ if (isCallValid)
+ {
+ context->vertexAttribDivisor(index, divisor);
+ }
+ ANGLE_CAPTURE_GL(VertexAttribDivisor, isCallValid, context, index, divisor);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_VertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLVertexAttribI4i, "context = %d, index = %u, x = %d, y = %d, z = %d, w = %d",
+ CID(context), index, x, y, z, w);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateVertexAttribI4i(context, angle::EntryPoint::GLVertexAttribI4i,
+ index, x, y, z, w));
+ if (isCallValid)
+ {
+ context->vertexAttribI4i(index, x, y, z, w);
+ }
+ ANGLE_CAPTURE_GL(VertexAttribI4i, isCallValid, context, index, x, y, z, w);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_VertexAttribI4iv(GLuint index, const GLint *v)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLVertexAttribI4iv, "context = %d, index = %u, v = 0x%016" PRIxPTR "",
+ CID(context), index, (uintptr_t)v);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateVertexAttribI4iv(context, angle::EntryPoint::GLVertexAttribI4iv, index, v));
+ if (isCallValid)
+ {
+ context->vertexAttribI4iv(index, v);
+ }
+ ANGLE_CAPTURE_GL(VertexAttribI4iv, isCallValid, context, index, v);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_VertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLVertexAttribI4ui, "context = %d, index = %u, x = %u, y = %u, z = %u, w = %u",
+ CID(context), index, x, y, z, w);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateVertexAttribI4ui(context, angle::EntryPoint::GLVertexAttribI4ui,
+ index, x, y, z, w));
+ if (isCallValid)
+ {
+ context->vertexAttribI4ui(index, x, y, z, w);
+ }
+ ANGLE_CAPTURE_GL(VertexAttribI4ui, isCallValid, context, index, x, y, z, w);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_VertexAttribI4uiv(GLuint index, const GLuint *v)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLVertexAttribI4uiv, "context = %d, index = %u, v = 0x%016" PRIxPTR "",
+ CID(context), index, (uintptr_t)v);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateVertexAttribI4uiv(context, angle::EntryPoint::GLVertexAttribI4uiv, index, v));
+ if (isCallValid)
+ {
+ context->vertexAttribI4uiv(index, v);
+ }
+ ANGLE_CAPTURE_GL(VertexAttribI4uiv, isCallValid, context, index, v);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY
+GL_VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLVertexAttribIPointer,
+ "context = %d, index = %u, size = %d, type = %s, stride = %d, pointer = 0x%016" PRIxPTR
+ "",
+ CID(context), index, size, GLenumToString(GLESEnum::VertexAttribIType, type), stride,
+ (uintptr_t)pointer);
+
+ if (context)
+ {
+ VertexAttribType typePacked = PackParam<VertexAttribType>(type);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateVertexAttribIPointer(context, angle::EntryPoint::GLVertexAttribIPointer, index,
+ size, typePacked, stride, pointer));
+ if (isCallValid)
+ {
+ context->vertexAttribIPointer(index, size, typePacked, stride, pointer);
+ }
+ ANGLE_CAPTURE_GL(VertexAttribIPointer, isCallValid, context, index, size, typePacked,
+ stride, pointer);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLWaitSync, "context = %d, sync = 0x%016" PRIxPTR ", flags = %s, timeout = %llu",
+ CID(context), (uintptr_t)sync,
+ GLbitfieldToString(GLESEnum::SyncBehaviorFlags, flags).c_str(),
+ static_cast<unsigned long long>(timeout));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateWaitSync(context, angle::EntryPoint::GLWaitSync, sync, flags, timeout));
+ if (isCallValid)
+ {
+ context->waitSync(sync, flags, timeout);
+ }
+ ANGLE_CAPTURE_GL(WaitSync, isCallValid, context, sync, flags, timeout);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+} // extern "C"
diff --git a/gfx/angle/checkout/src/libGLESv2/entry_points_gles_3_0_autogen.h b/gfx/angle/checkout/src/libGLESv2/entry_points_gles_3_0_autogen.h
new file mode 100644
index 0000000000..7660b8a427
--- /dev/null
+++ b/gfx/angle/checkout/src/libGLESv2/entry_points_gles_3_0_autogen.h
@@ -0,0 +1,299 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml.
+//
+// Copyright 2020 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_0_autogen.h:
+// Defines the GLES 3.0 entry points.
+
+#ifndef LIBGLESV2_ENTRY_POINTS_GLES_3_0_AUTOGEN_H_
+#define LIBGLESV2_ENTRY_POINTS_GLES_3_0_AUTOGEN_H_
+
+#include <GLES3/gl3.h>
+#include <export.h>
+
+extern "C" {
+ANGLE_EXPORT void GL_APIENTRY GL_BeginQuery(GLenum target, GLuint id);
+ANGLE_EXPORT void GL_APIENTRY GL_BeginTransformFeedback(GLenum primitiveMode);
+ANGLE_EXPORT void GL_APIENTRY GL_BindBufferBase(GLenum target, GLuint index, GLuint buffer);
+ANGLE_EXPORT void GL_APIENTRY
+GL_BindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+ANGLE_EXPORT void GL_APIENTRY GL_BindSampler(GLuint unit, GLuint sampler);
+ANGLE_EXPORT void GL_APIENTRY GL_BindTransformFeedback(GLenum target, GLuint id);
+ANGLE_EXPORT void GL_APIENTRY GL_BindVertexArray(GLuint array);
+ANGLE_EXPORT void GL_APIENTRY GL_BlitFramebuffer(GLint srcX0,
+ GLint srcY0,
+ GLint srcX1,
+ GLint srcY1,
+ GLint dstX0,
+ GLint dstY0,
+ GLint dstX1,
+ GLint dstY1,
+ GLbitfield mask,
+ GLenum filter);
+ANGLE_EXPORT void GL_APIENTRY GL_ClearBufferfi(GLenum buffer,
+ GLint drawbuffer,
+ GLfloat depth,
+ GLint stencil);
+ANGLE_EXPORT void GL_APIENTRY GL_ClearBufferfv(GLenum buffer,
+ GLint drawbuffer,
+ const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY GL_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value);
+ANGLE_EXPORT void GL_APIENTRY GL_ClearBufferuiv(GLenum buffer,
+ GLint drawbuffer,
+ const GLuint *value);
+ANGLE_EXPORT GLenum GL_APIENTRY GL_ClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout);
+ANGLE_EXPORT void GL_APIENTRY GL_CompressedTexImage3D(GLenum target,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLsizei imageSize,
+ const void *data);
+ANGLE_EXPORT void GL_APIENTRY GL_CompressedTexSubImage3D(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data);
+ANGLE_EXPORT void GL_APIENTRY GL_CopyBufferSubData(GLenum readTarget,
+ GLenum writeTarget,
+ GLintptr readOffset,
+ GLintptr writeOffset,
+ GLsizeiptr size);
+ANGLE_EXPORT void GL_APIENTRY GL_CopyTexSubImage3D(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height);
+ANGLE_EXPORT void GL_APIENTRY GL_DeleteQueries(GLsizei n, const GLuint *ids);
+ANGLE_EXPORT void GL_APIENTRY GL_DeleteSamplers(GLsizei count, const GLuint *samplers);
+ANGLE_EXPORT void GL_APIENTRY GL_DeleteSync(GLsync sync);
+ANGLE_EXPORT void GL_APIENTRY GL_DeleteTransformFeedbacks(GLsizei n, const GLuint *ids);
+ANGLE_EXPORT void GL_APIENTRY GL_DeleteVertexArrays(GLsizei n, const GLuint *arrays);
+ANGLE_EXPORT void GL_APIENTRY GL_DrawArraysInstanced(GLenum mode,
+ GLint first,
+ GLsizei count,
+ GLsizei instancecount);
+ANGLE_EXPORT void GL_APIENTRY GL_DrawBuffers(GLsizei n, const GLenum *bufs);
+ANGLE_EXPORT void GL_APIENTRY GL_DrawElementsInstanced(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLsizei instancecount);
+ANGLE_EXPORT void GL_APIENTRY GL_DrawRangeElements(GLenum mode,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ GLenum type,
+ const void *indices);
+ANGLE_EXPORT void GL_APIENTRY GL_EndQuery(GLenum target);
+ANGLE_EXPORT void GL_APIENTRY GL_EndTransformFeedback();
+ANGLE_EXPORT GLsync GL_APIENTRY GL_FenceSync(GLenum condition, GLbitfield flags);
+ANGLE_EXPORT void GL_APIENTRY GL_FlushMappedBufferRange(GLenum target,
+ GLintptr offset,
+ GLsizeiptr length);
+ANGLE_EXPORT void GL_APIENTRY GL_FramebufferTextureLayer(GLenum target,
+ GLenum attachment,
+ GLuint texture,
+ GLint level,
+ GLint layer);
+ANGLE_EXPORT void GL_APIENTRY GL_GenQueries(GLsizei n, GLuint *ids);
+ANGLE_EXPORT void GL_APIENTRY GL_GenSamplers(GLsizei count, GLuint *samplers);
+ANGLE_EXPORT void GL_APIENTRY GL_GenTransformFeedbacks(GLsizei n, GLuint *ids);
+ANGLE_EXPORT void GL_APIENTRY GL_GenVertexArrays(GLsizei n, GLuint *arrays);
+ANGLE_EXPORT void GL_APIENTRY GL_GetActiveUniformBlockName(GLuint program,
+ GLuint uniformBlockIndex,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *uniformBlockName);
+ANGLE_EXPORT void GL_APIENTRY GL_GetActiveUniformBlockiv(GLuint program,
+ GLuint uniformBlockIndex,
+ GLenum pname,
+ GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetActiveUniformsiv(GLuint program,
+ GLsizei uniformCount,
+ const GLuint *uniformIndices,
+ GLenum pname,
+ GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetBufferParameteri64v(GLenum target,
+ GLenum pname,
+ GLint64 *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetBufferPointerv(GLenum target, GLenum pname, void **params);
+ANGLE_EXPORT GLint GL_APIENTRY GL_GetFragDataLocation(GLuint program, const GLchar *name);
+ANGLE_EXPORT void GL_APIENTRY GL_GetInteger64i_v(GLenum target, GLuint index, GLint64 *data);
+ANGLE_EXPORT void GL_APIENTRY GL_GetInteger64v(GLenum pname, GLint64 *data);
+ANGLE_EXPORT void GL_APIENTRY GL_GetIntegeri_v(GLenum target, GLuint index, GLint *data);
+ANGLE_EXPORT void GL_APIENTRY GL_GetInternalformativ(GLenum target,
+ GLenum internalformat,
+ GLenum pname,
+ GLsizei count,
+ GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetProgramBinary(GLuint program,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLenum *binaryFormat,
+ void *binary);
+ANGLE_EXPORT void GL_APIENTRY GL_GetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetQueryiv(GLenum target, GLenum pname, GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetSamplerParameterfv(GLuint sampler,
+ GLenum pname,
+ GLfloat *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params);
+ANGLE_EXPORT const GLubyte *GL_APIENTRY GL_GetStringi(GLenum name, GLuint index);
+ANGLE_EXPORT void GL_APIENTRY
+GL_GetSynciv(GLsync sync, GLenum pname, GLsizei count, GLsizei *length, GLint *values);
+ANGLE_EXPORT void GL_APIENTRY GL_GetTransformFeedbackVarying(GLuint program,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLsizei *size,
+ GLenum *type,
+ GLchar *name);
+ANGLE_EXPORT GLuint GL_APIENTRY GL_GetUniformBlockIndex(GLuint program,
+ const GLchar *uniformBlockName);
+ANGLE_EXPORT void GL_APIENTRY GL_GetUniformIndices(GLuint program,
+ GLsizei uniformCount,
+ const GLchar *const *uniformNames,
+ GLuint *uniformIndices);
+ANGLE_EXPORT void GL_APIENTRY GL_GetUniformuiv(GLuint program, GLint location, GLuint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetVertexAttribIiv(GLuint index, GLenum pname, GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_InvalidateFramebuffer(GLenum target,
+ GLsizei numAttachments,
+ const GLenum *attachments);
+ANGLE_EXPORT void GL_APIENTRY GL_InvalidateSubFramebuffer(GLenum target,
+ GLsizei numAttachments,
+ const GLenum *attachments,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height);
+ANGLE_EXPORT GLboolean GL_APIENTRY GL_IsQuery(GLuint id);
+ANGLE_EXPORT GLboolean GL_APIENTRY GL_IsSampler(GLuint sampler);
+ANGLE_EXPORT GLboolean GL_APIENTRY GL_IsSync(GLsync sync);
+ANGLE_EXPORT GLboolean GL_APIENTRY GL_IsTransformFeedback(GLuint id);
+ANGLE_EXPORT GLboolean GL_APIENTRY GL_IsVertexArray(GLuint array);
+ANGLE_EXPORT void *GL_APIENTRY GL_MapBufferRange(GLenum target,
+ GLintptr offset,
+ GLsizeiptr length,
+ GLbitfield access);
+ANGLE_EXPORT void GL_APIENTRY GL_PauseTransformFeedback();
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramBinary(GLuint program,
+ GLenum binaryFormat,
+ const void *binary,
+ GLsizei length);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramParameteri(GLuint program, GLenum pname, GLint value);
+ANGLE_EXPORT void GL_APIENTRY GL_ReadBuffer(GLenum src);
+ANGLE_EXPORT void GL_APIENTRY GL_RenderbufferStorageMultisample(GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height);
+ANGLE_EXPORT void GL_APIENTRY GL_ResumeTransformFeedback();
+ANGLE_EXPORT void GL_APIENTRY GL_SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param);
+ANGLE_EXPORT void GL_APIENTRY GL_SamplerParameterfv(GLuint sampler,
+ GLenum pname,
+ const GLfloat *param);
+ANGLE_EXPORT void GL_APIENTRY GL_SamplerParameteri(GLuint sampler, GLenum pname, GLint param);
+ANGLE_EXPORT void GL_APIENTRY GL_SamplerParameteriv(GLuint sampler,
+ GLenum pname,
+ const GLint *param);
+ANGLE_EXPORT void GL_APIENTRY GL_TexImage3D(GLenum target,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const void *pixels);
+ANGLE_EXPORT void GL_APIENTRY GL_TexStorage2D(GLenum target,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height);
+ANGLE_EXPORT void GL_APIENTRY GL_TexStorage3D(GLenum target,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth);
+ANGLE_EXPORT void GL_APIENTRY GL_TexSubImage3D(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ const void *pixels);
+ANGLE_EXPORT void GL_APIENTRY GL_TransformFeedbackVaryings(GLuint program,
+ GLsizei count,
+ const GLchar *const *varyings,
+ GLenum bufferMode);
+ANGLE_EXPORT void GL_APIENTRY GL_Uniform1ui(GLint location, GLuint v0);
+ANGLE_EXPORT void GL_APIENTRY GL_Uniform1uiv(GLint location, GLsizei count, const GLuint *value);
+ANGLE_EXPORT void GL_APIENTRY GL_Uniform2ui(GLint location, GLuint v0, GLuint v1);
+ANGLE_EXPORT void GL_APIENTRY GL_Uniform2uiv(GLint location, GLsizei count, const GLuint *value);
+ANGLE_EXPORT void GL_APIENTRY GL_Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2);
+ANGLE_EXPORT void GL_APIENTRY GL_Uniform3uiv(GLint location, GLsizei count, const GLuint *value);
+ANGLE_EXPORT void GL_APIENTRY
+GL_Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+ANGLE_EXPORT void GL_APIENTRY GL_Uniform4uiv(GLint location, GLsizei count, const GLuint *value);
+ANGLE_EXPORT void GL_APIENTRY GL_UniformBlockBinding(GLuint program,
+ GLuint uniformBlockIndex,
+ GLuint uniformBlockBinding);
+ANGLE_EXPORT void GL_APIENTRY GL_UniformMatrix2x3fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY GL_UniformMatrix2x4fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY GL_UniformMatrix3x2fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY GL_UniformMatrix3x4fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY GL_UniformMatrix4x2fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY GL_UniformMatrix4x3fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+ANGLE_EXPORT GLboolean GL_APIENTRY GL_UnmapBuffer(GLenum target);
+ANGLE_EXPORT void GL_APIENTRY GL_VertexAttribDivisor(GLuint index, GLuint divisor);
+ANGLE_EXPORT void GL_APIENTRY GL_VertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w);
+ANGLE_EXPORT void GL_APIENTRY GL_VertexAttribI4iv(GLuint index, const GLint *v);
+ANGLE_EXPORT void GL_APIENTRY
+GL_VertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+ANGLE_EXPORT void GL_APIENTRY GL_VertexAttribI4uiv(GLuint index, const GLuint *v);
+ANGLE_EXPORT void GL_APIENTRY
+GL_VertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer);
+ANGLE_EXPORT void GL_APIENTRY GL_WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout);
+} // extern "C"
+
+#endif // LIBGLESV2_ENTRY_POINTS_GLES_3_0_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libGLESv2/entry_points_gles_3_1_autogen.cpp b/gfx/angle/checkout/src/libGLESv2/entry_points_gles_3_1_autogen.cpp
new file mode 100644
index 0000000000..a1345d5a62
--- /dev/null
+++ b/gfx/angle/checkout/src/libGLESv2/entry_points_gles_3_1_autogen.cpp
@@ -0,0 +1,2098 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml.
+//
+// Copyright 2020 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_autogen.cpp:
+// Defines the GLES 3.1 entry points.
+
+#include "libGLESv2/entry_points_gles_3_1_autogen.h"
+
+#include "common/entry_points_enum_autogen.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Context.inl.h"
+#include "libANGLE/capture/capture_gles_3_1_autogen.h"
+#include "libANGLE/capture/gl_enum_utils.h"
+#include "libANGLE/entry_points_utils.h"
+#include "libANGLE/validationES31.h"
+#include "libGLESv2/global_state.h"
+
+using namespace gl;
+
+extern "C" {
+void GL_APIENTRY GL_ActiveShaderProgram(GLuint pipeline, GLuint program)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLActiveShaderProgram, "context = %d, pipeline = %u, program = %u", CID(context),
+ pipeline, program);
+
+ if (context)
+ {
+ ProgramPipelineID pipelinePacked = PackParam<ProgramPipelineID>(pipeline);
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateActiveShaderProgram(context, angle::EntryPoint::GLActiveShaderProgram,
+ pipelinePacked, programPacked));
+ if (isCallValid)
+ {
+ context->activeShaderProgram(pipelinePacked, programPacked);
+ }
+ ANGLE_CAPTURE_GL(ActiveShaderProgram, isCallValid, context, pipelinePacked, programPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_BindImageTexture(GLuint unit,
+ GLuint texture,
+ GLint level,
+ GLboolean layered,
+ GLint layer,
+ GLenum access,
+ GLenum format)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBindImageTexture,
+ "context = %d, unit = %u, texture = %u, level = %d, layered = %s, layer = %d, access = "
+ "%s, format = %s",
+ CID(context), unit, texture, level, GLbooleanToString(layered), layer,
+ GLenumToString(GLESEnum::BufferAccessARB, access),
+ GLenumToString(GLESEnum::InternalFormat, format));
+
+ if (context)
+ {
+ TextureID texturePacked = PackParam<TextureID>(texture);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateBindImageTexture(context, angle::EntryPoint::GLBindImageTexture, unit,
+ texturePacked, level, layered, layer, access, format));
+ if (isCallValid)
+ {
+ context->bindImageTexture(unit, texturePacked, level, layered, layer, access, format);
+ }
+ ANGLE_CAPTURE_GL(BindImageTexture, isCallValid, context, unit, texturePacked, level,
+ layered, layer, access, format);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_BindProgramPipeline(GLuint pipeline)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBindProgramPipeline, "context = %d, pipeline = %u", CID(context), pipeline);
+
+ if (context)
+ {
+ ProgramPipelineID pipelinePacked = PackParam<ProgramPipelineID>(pipeline);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateBindProgramPipeline(
+ context, angle::EntryPoint::GLBindProgramPipeline, pipelinePacked));
+ if (isCallValid)
+ {
+ context->bindProgramPipeline(pipelinePacked);
+ }
+ ANGLE_CAPTURE_GL(BindProgramPipeline, isCallValid, context, pipelinePacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_BindVertexBuffer(GLuint bindingindex,
+ GLuint buffer,
+ GLintptr offset,
+ GLsizei stride)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBindVertexBuffer,
+ "context = %d, bindingindex = %u, buffer = %u, offset = %llu, stride = %d", CID(context),
+ bindingindex, buffer, static_cast<unsigned long long>(offset), stride);
+
+ if (context)
+ {
+ BufferID bufferPacked = PackParam<BufferID>(buffer);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateBindVertexBuffer(context, angle::EntryPoint::GLBindVertexBuffer,
+ bindingindex, bufferPacked, offset, stride));
+ if (isCallValid)
+ {
+ context->bindVertexBuffer(bindingindex, bufferPacked, offset, stride);
+ }
+ ANGLE_CAPTURE_GL(BindVertexBuffer, isCallValid, context, bindingindex, bufferPacked, offset,
+ stride);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+GLuint GL_APIENTRY GL_CreateShaderProgramv(GLenum type, GLsizei count, const GLchar *const *strings)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLCreateShaderProgramv,
+ "context = %d, type = %s, count = %d, strings = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::ShaderType, type), count, (uintptr_t)strings);
+
+ GLuint returnValue;
+ if (context)
+ {
+ ShaderType typePacked = PackParam<ShaderType>(type);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateCreateShaderProgramv(context, angle::EntryPoint::GLCreateShaderProgramv,
+ typePacked, count, strings));
+ if (isCallValid)
+ {
+ returnValue = context->createShaderProgramv(typePacked, count, strings);
+ }
+ else
+ {
+ returnValue =
+ GetDefaultReturnValue<angle::EntryPoint::GLCreateShaderProgramv, GLuint>();
+ }
+ ANGLE_CAPTURE_GL(CreateShaderProgramv, isCallValid, context, typePacked, count, strings,
+ returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLCreateShaderProgramv, GLuint>();
+ }
+ return returnValue;
+}
+
+void GL_APIENTRY GL_DeleteProgramPipelines(GLsizei n, const GLuint *pipelines)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDeleteProgramPipelines, "context = %d, n = %d, pipelines = 0x%016" PRIxPTR "",
+ CID(context), n, (uintptr_t)pipelines);
+
+ if (context)
+ {
+ const ProgramPipelineID *pipelinesPacked = PackParam<const ProgramPipelineID *>(pipelines);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateDeleteProgramPipelines(context, angle::EntryPoint::GLDeleteProgramPipelines, n,
+ pipelinesPacked));
+ if (isCallValid)
+ {
+ context->deleteProgramPipelines(n, pipelinesPacked);
+ }
+ ANGLE_CAPTURE_GL(DeleteProgramPipelines, isCallValid, context, n, pipelinesPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DispatchCompute(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDispatchCompute,
+ "context = %d, num_groups_x = %u, num_groups_y = %u, num_groups_z = %u", CID(context),
+ num_groups_x, num_groups_y, num_groups_z);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateDispatchCompute(context, angle::EntryPoint::GLDispatchCompute,
+ num_groups_x, num_groups_y, num_groups_z));
+ if (isCallValid)
+ {
+ context->dispatchCompute(num_groups_x, num_groups_y, num_groups_z);
+ }
+ ANGLE_CAPTURE_GL(DispatchCompute, isCallValid, context, num_groups_x, num_groups_y,
+ num_groups_z);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DispatchComputeIndirect(GLintptr indirect)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDispatchComputeIndirect, "context = %d, indirect = %llu", CID(context),
+ static_cast<unsigned long long>(indirect));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateDispatchComputeIndirect(
+ context, angle::EntryPoint::GLDispatchComputeIndirect, indirect));
+ if (isCallValid)
+ {
+ context->dispatchComputeIndirect(indirect);
+ }
+ ANGLE_CAPTURE_GL(DispatchComputeIndirect, isCallValid, context, indirect);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DrawArraysIndirect(GLenum mode, const void *indirect)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDrawArraysIndirect, "context = %d, mode = %s, indirect = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::PrimitiveType, mode), (uintptr_t)indirect);
+
+ if (context)
+ {
+ PrimitiveMode modePacked = PackParam<PrimitiveMode>(mode);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateDrawArraysIndirect(context, angle::EntryPoint::GLDrawArraysIndirect,
+ modePacked, indirect));
+ if (isCallValid)
+ {
+ context->drawArraysIndirect(modePacked, indirect);
+ }
+ ANGLE_CAPTURE_GL(DrawArraysIndirect, isCallValid, context, modePacked, indirect);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DrawElementsIndirect(GLenum mode, GLenum type, const void *indirect)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDrawElementsIndirect,
+ "context = %d, mode = %s, type = %s, indirect = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::PrimitiveType, mode),
+ GLenumToString(GLESEnum::DrawElementsType, type), (uintptr_t)indirect);
+
+ if (context)
+ {
+ PrimitiveMode modePacked = PackParam<PrimitiveMode>(mode);
+ DrawElementsType typePacked = PackParam<DrawElementsType>(type);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateDrawElementsIndirect(context, angle::EntryPoint::GLDrawElementsIndirect,
+ modePacked, typePacked, indirect));
+ if (isCallValid)
+ {
+ context->drawElementsIndirect(modePacked, typePacked, indirect);
+ }
+ ANGLE_CAPTURE_GL(DrawElementsIndirect, isCallValid, context, modePacked, typePacked,
+ indirect);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_FramebufferParameteri(GLenum target, GLenum pname, GLint param)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLFramebufferParameteri, "context = %d, target = %s, pname = %s, param = %d",
+ CID(context), GLenumToString(GLESEnum::FramebufferTarget, target),
+ GLenumToString(GLESEnum::FramebufferParameterName, pname), param);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateFramebufferParameteri(context, angle::EntryPoint::GLFramebufferParameteri,
+ target, pname, param));
+ if (isCallValid)
+ {
+ context->framebufferParameteri(target, pname, param);
+ }
+ ANGLE_CAPTURE_GL(FramebufferParameteri, isCallValid, context, target, pname, param);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GenProgramPipelines(GLsizei n, GLuint *pipelines)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGenProgramPipelines, "context = %d, n = %d, pipelines = 0x%016" PRIxPTR "",
+ CID(context), n, (uintptr_t)pipelines);
+
+ if (context)
+ {
+ ProgramPipelineID *pipelinesPacked = PackParam<ProgramPipelineID *>(pipelines);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGenProgramPipelines(context, angle::EntryPoint::GLGenProgramPipelines, n,
+ pipelinesPacked));
+ if (isCallValid)
+ {
+ context->genProgramPipelines(n, pipelinesPacked);
+ }
+ ANGLE_CAPTURE_GL(GenProgramPipelines, isCallValid, context, n, pipelinesPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetBooleani_v(GLenum target, GLuint index, GLboolean *data)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetBooleani_v,
+ "context = %d, target = %s, index = %u, data = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::BufferTargetARB, target), index, (uintptr_t)data);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetBooleani_v(context, angle::EntryPoint::GLGetBooleani_v,
+ target, index, data));
+ if (isCallValid)
+ {
+ context->getBooleani_v(target, index, data);
+ }
+ ANGLE_CAPTURE_GL(GetBooleani_v, isCallValid, context, target, index, data);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetFramebufferParameteriv,
+ "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::FramebufferTarget, target),
+ GLenumToString(GLESEnum::FramebufferAttachmentParameterName, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetFramebufferParameteriv(
+ context, angle::EntryPoint::GLGetFramebufferParameteriv, target, pname, params));
+ if (isCallValid)
+ {
+ context->getFramebufferParameteriv(target, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetFramebufferParameteriv, isCallValid, context, target, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetMultisamplefv,
+ "context = %d, pname = %s, index = %u, val = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::AllEnums, pname), index, (uintptr_t)val);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetMultisamplefv(context, angle::EntryPoint::GLGetMultisamplefv,
+ pname, index, val));
+ if (isCallValid)
+ {
+ context->getMultisamplefv(pname, index, val);
+ }
+ ANGLE_CAPTURE_GL(GetMultisamplefv, isCallValid, context, pname, index, val);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetProgramInterfaceiv(GLuint program,
+ GLenum programInterface,
+ GLenum pname,
+ GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetProgramInterfaceiv,
+ "context = %d, program = %u, programInterface = %s, pname = %s, params = 0x%016" PRIxPTR
+ "",
+ CID(context), program, GLenumToString(GLESEnum::ProgramInterface, programInterface),
+ GLenumToString(GLESEnum::ProgramInterfacePName, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetProgramInterfaceiv(context, angle::EntryPoint::GLGetProgramInterfaceiv,
+ programPacked, programInterface, pname, params));
+ if (isCallValid)
+ {
+ context->getProgramInterfaceiv(programPacked, programInterface, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetProgramInterfaceiv, isCallValid, context, programPacked,
+ programInterface, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetProgramPipelineInfoLog(GLuint pipeline,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *infoLog)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetProgramPipelineInfoLog,
+ "context = %d, pipeline = %u, bufSize = %d, length = 0x%016" PRIxPTR
+ ", infoLog = 0x%016" PRIxPTR "",
+ CID(context), pipeline, bufSize, (uintptr_t)length, (uintptr_t)infoLog);
+
+ if (context)
+ {
+ ProgramPipelineID pipelinePacked = PackParam<ProgramPipelineID>(pipeline);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetProgramPipelineInfoLog(
+ context, angle::EntryPoint::GLGetProgramPipelineInfoLog,
+ pipelinePacked, bufSize, length, infoLog));
+ if (isCallValid)
+ {
+ context->getProgramPipelineInfoLog(pipelinePacked, bufSize, length, infoLog);
+ }
+ ANGLE_CAPTURE_GL(GetProgramPipelineInfoLog, isCallValid, context, pipelinePacked, bufSize,
+ length, infoLog);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetProgramPipelineiv,
+ "context = %d, pipeline = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ pipeline, GLenumToString(GLESEnum::PipelineParameterName, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ ProgramPipelineID pipelinePacked = PackParam<ProgramPipelineID>(pipeline);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetProgramPipelineiv(context, angle::EntryPoint::GLGetProgramPipelineiv,
+ pipelinePacked, pname, params));
+ if (isCallValid)
+ {
+ context->getProgramPipelineiv(pipelinePacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetProgramPipelineiv, isCallValid, context, pipelinePacked, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+GLuint GL_APIENTRY GL_GetProgramResourceIndex(GLuint program,
+ GLenum programInterface,
+ const GLchar *name)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetProgramResourceIndex,
+ "context = %d, program = %u, programInterface = %s, name = 0x%016" PRIxPTR "",
+ CID(context), program, GLenumToString(GLESEnum::ProgramInterface, programInterface),
+ (uintptr_t)name);
+
+ GLuint returnValue;
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetProgramResourceIndex(context, angle::EntryPoint::GLGetProgramResourceIndex,
+ programPacked, programInterface, name));
+ if (isCallValid)
+ {
+ returnValue = context->getProgramResourceIndex(programPacked, programInterface, name);
+ }
+ else
+ {
+ returnValue =
+ GetDefaultReturnValue<angle::EntryPoint::GLGetProgramResourceIndex, GLuint>();
+ }
+ ANGLE_CAPTURE_GL(GetProgramResourceIndex, isCallValid, context, programPacked,
+ programInterface, name, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLGetProgramResourceIndex, GLuint>();
+ }
+ return returnValue;
+}
+
+GLint GL_APIENTRY GL_GetProgramResourceLocation(GLuint program,
+ GLenum programInterface,
+ const GLchar *name)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetProgramResourceLocation,
+ "context = %d, program = %u, programInterface = %s, name = 0x%016" PRIxPTR "",
+ CID(context), program, GLenumToString(GLESEnum::ProgramInterface, programInterface),
+ (uintptr_t)name);
+
+ GLint returnValue;
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetProgramResourceLocation(
+ context, angle::EntryPoint::GLGetProgramResourceLocation,
+ programPacked, programInterface, name));
+ if (isCallValid)
+ {
+ returnValue =
+ context->getProgramResourceLocation(programPacked, programInterface, name);
+ }
+ else
+ {
+ returnValue =
+ GetDefaultReturnValue<angle::EntryPoint::GLGetProgramResourceLocation, GLint>();
+ }
+ ANGLE_CAPTURE_GL(GetProgramResourceLocation, isCallValid, context, programPacked,
+ programInterface, name, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue =
+ GetDefaultReturnValue<angle::EntryPoint::GLGetProgramResourceLocation, GLint>();
+ }
+ return returnValue;
+}
+
+void GL_APIENTRY GL_GetProgramResourceName(GLuint program,
+ GLenum programInterface,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *name)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetProgramResourceName,
+ "context = %d, program = %u, programInterface = %s, index = %u, bufSize = %d, length = "
+ "0x%016" PRIxPTR ", name = 0x%016" PRIxPTR "",
+ CID(context), program, GLenumToString(GLESEnum::ProgramInterface, programInterface),
+ index, bufSize, (uintptr_t)length, (uintptr_t)name);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetProgramResourceName(
+ context, angle::EntryPoint::GLGetProgramResourceName, programPacked,
+ programInterface, index, bufSize, length, name));
+ if (isCallValid)
+ {
+ context->getProgramResourceName(programPacked, programInterface, index, bufSize, length,
+ name);
+ }
+ ANGLE_CAPTURE_GL(GetProgramResourceName, isCallValid, context, programPacked,
+ programInterface, index, bufSize, length, name);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetProgramResourceiv(GLuint program,
+ GLenum programInterface,
+ GLuint index,
+ GLsizei propCount,
+ const GLenum *props,
+ GLsizei count,
+ GLsizei *length,
+ GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetProgramResourceiv,
+ "context = %d, program = %u, programInterface = %s, index = %u, propCount = %d, props = "
+ "0x%016" PRIxPTR ", count = %d, length = 0x%016" PRIxPTR ", params = 0x%016" PRIxPTR "",
+ CID(context), program, GLenumToString(GLESEnum::ProgramInterface, programInterface),
+ index, propCount, (uintptr_t)props, count, (uintptr_t)length, (uintptr_t)params);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetProgramResourceiv(
+ context, angle::EntryPoint::GLGetProgramResourceiv, programPacked,
+ programInterface, index, propCount, props, count, length, params));
+ if (isCallValid)
+ {
+ context->getProgramResourceiv(programPacked, programInterface, index, propCount, props,
+ count, length, params);
+ }
+ ANGLE_CAPTURE_GL(GetProgramResourceiv, isCallValid, context, programPacked,
+ programInterface, index, propCount, props, count, length, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetTexLevelParameterfv(GLenum target,
+ GLint level,
+ GLenum pname,
+ GLfloat *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetTexLevelParameterfv,
+ "context = %d, target = %s, level = %d, pname = %s, params = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target), level,
+ GLenumToString(GLESEnum::GetTextureParameter, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ TextureTarget targetPacked = PackParam<TextureTarget>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetTexLevelParameterfv(context, angle::EntryPoint::GLGetTexLevelParameterfv,
+ targetPacked, level, pname, params));
+ if (isCallValid)
+ {
+ context->getTexLevelParameterfv(targetPacked, level, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetTexLevelParameterfv, isCallValid, context, targetPacked, level, pname,
+ params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetTexLevelParameteriv,
+ "context = %d, target = %s, level = %d, pname = %s, params = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target), level,
+ GLenumToString(GLESEnum::GetTextureParameter, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ TextureTarget targetPacked = PackParam<TextureTarget>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetTexLevelParameteriv(context, angle::EntryPoint::GLGetTexLevelParameteriv,
+ targetPacked, level, pname, params));
+ if (isCallValid)
+ {
+ context->getTexLevelParameteriv(targetPacked, level, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetTexLevelParameteriv, isCallValid, context, targetPacked, level, pname,
+ params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+GLboolean GL_APIENTRY GL_IsProgramPipeline(GLuint pipeline)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLIsProgramPipeline, "context = %d, pipeline = %u", CID(context), pipeline);
+
+ GLboolean returnValue;
+ if (context)
+ {
+ ProgramPipelineID pipelinePacked = PackParam<ProgramPipelineID>(pipeline);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateIsProgramPipeline(
+ context, angle::EntryPoint::GLIsProgramPipeline, pipelinePacked));
+ if (isCallValid)
+ {
+ returnValue = context->isProgramPipeline(pipelinePacked);
+ }
+ else
+ {
+ returnValue =
+ GetDefaultReturnValue<angle::EntryPoint::GLIsProgramPipeline, GLboolean>();
+ }
+ ANGLE_CAPTURE_GL(IsProgramPipeline, isCallValid, context, pipelinePacked, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsProgramPipeline, GLboolean>();
+ }
+ return returnValue;
+}
+
+void GL_APIENTRY GL_MemoryBarrier(GLbitfield barriers)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLMemoryBarrier, "context = %d, barriers = %s", CID(context),
+ GLbitfieldToString(GLESEnum::MemoryBarrierMask, barriers).c_str());
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateMemoryBarrier(context, angle::EntryPoint::GLMemoryBarrier, barriers));
+ if (isCallValid)
+ {
+ context->memoryBarrier(barriers);
+ }
+ ANGLE_CAPTURE_GL(MemoryBarrier, isCallValid, context, barriers);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_MemoryBarrierByRegion(GLbitfield barriers)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLMemoryBarrierByRegion, "context = %d, barriers = %s", CID(context),
+ GLbitfieldToString(GLESEnum::MemoryBarrierMask, barriers).c_str());
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateMemoryBarrierByRegion(
+ context, angle::EntryPoint::GLMemoryBarrierByRegion, barriers));
+ if (isCallValid)
+ {
+ context->memoryBarrierByRegion(barriers);
+ }
+ ANGLE_CAPTURE_GL(MemoryBarrierByRegion, isCallValid, context, barriers);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniform1f(GLuint program, GLint location, GLfloat v0)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform1f, "context = %d, program = %u, location = %d, v0 = %f",
+ CID(context), program, location, v0);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateProgramUniform1f(context, angle::EntryPoint::GLProgramUniform1f,
+ programPacked, locationPacked, v0));
+ if (isCallValid)
+ {
+ context->programUniform1f(programPacked, locationPacked, v0);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform1f, isCallValid, context, programPacked, locationPacked, v0);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniform1fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLfloat *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform1fv,
+ "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
+ CID(context), program, location, count, (uintptr_t)value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramUniform1fv(context, angle::EntryPoint::GLProgramUniform1fv,
+ programPacked, locationPacked, count, value));
+ if (isCallValid)
+ {
+ context->programUniform1fv(programPacked, locationPacked, count, value);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform1fv, isCallValid, context, programPacked, locationPacked,
+ count, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniform1i(GLuint program, GLint location, GLint v0)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform1i, "context = %d, program = %u, location = %d, v0 = %d",
+ CID(context), program, location, v0);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateProgramUniform1i(context, angle::EntryPoint::GLProgramUniform1i,
+ programPacked, locationPacked, v0));
+ if (isCallValid)
+ {
+ context->programUniform1i(programPacked, locationPacked, v0);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform1i, isCallValid, context, programPacked, locationPacked, v0);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniform1iv(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLint *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform1iv,
+ "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
+ CID(context), program, location, count, (uintptr_t)value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramUniform1iv(context, angle::EntryPoint::GLProgramUniform1iv,
+ programPacked, locationPacked, count, value));
+ if (isCallValid)
+ {
+ context->programUniform1iv(programPacked, locationPacked, count, value);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform1iv, isCallValid, context, programPacked, locationPacked,
+ count, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniform1ui(GLuint program, GLint location, GLuint v0)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform1ui, "context = %d, program = %u, location = %d, v0 = %u",
+ CID(context), program, location, v0);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramUniform1ui(context, angle::EntryPoint::GLProgramUniform1ui,
+ programPacked, locationPacked, v0));
+ if (isCallValid)
+ {
+ context->programUniform1ui(programPacked, locationPacked, v0);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform1ui, isCallValid, context, programPacked, locationPacked,
+ v0);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniform1uiv(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLuint *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform1uiv,
+ "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
+ CID(context), program, location, count, (uintptr_t)value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramUniform1uiv(context, angle::EntryPoint::GLProgramUniform1uiv,
+ programPacked, locationPacked, count, value));
+ if (isCallValid)
+ {
+ context->programUniform1uiv(programPacked, locationPacked, count, value);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform1uiv, isCallValid, context, programPacked, locationPacked,
+ count, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniform2f(GLuint program, GLint location, GLfloat v0, GLfloat v1)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform2f,
+ "context = %d, program = %u, location = %d, v0 = %f, v1 = %f", CID(context), program,
+ location, v0, v1);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateProgramUniform2f(context, angle::EntryPoint::GLProgramUniform2f,
+ programPacked, locationPacked, v0, v1));
+ if (isCallValid)
+ {
+ context->programUniform2f(programPacked, locationPacked, v0, v1);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform2f, isCallValid, context, programPacked, locationPacked, v0,
+ v1);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniform2fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLfloat *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform2fv,
+ "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
+ CID(context), program, location, count, (uintptr_t)value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramUniform2fv(context, angle::EntryPoint::GLProgramUniform2fv,
+ programPacked, locationPacked, count, value));
+ if (isCallValid)
+ {
+ context->programUniform2fv(programPacked, locationPacked, count, value);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform2fv, isCallValid, context, programPacked, locationPacked,
+ count, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniform2i(GLuint program, GLint location, GLint v0, GLint v1)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform2i,
+ "context = %d, program = %u, location = %d, v0 = %d, v1 = %d", CID(context), program,
+ location, v0, v1);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateProgramUniform2i(context, angle::EntryPoint::GLProgramUniform2i,
+ programPacked, locationPacked, v0, v1));
+ if (isCallValid)
+ {
+ context->programUniform2i(programPacked, locationPacked, v0, v1);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform2i, isCallValid, context, programPacked, locationPacked, v0,
+ v1);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniform2iv(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLint *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform2iv,
+ "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
+ CID(context), program, location, count, (uintptr_t)value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramUniform2iv(context, angle::EntryPoint::GLProgramUniform2iv,
+ programPacked, locationPacked, count, value));
+ if (isCallValid)
+ {
+ context->programUniform2iv(programPacked, locationPacked, count, value);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform2iv, isCallValid, context, programPacked, locationPacked,
+ count, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniform2ui(GLuint program, GLint location, GLuint v0, GLuint v1)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform2ui,
+ "context = %d, program = %u, location = %d, v0 = %u, v1 = %u", CID(context), program,
+ location, v0, v1);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramUniform2ui(context, angle::EntryPoint::GLProgramUniform2ui,
+ programPacked, locationPacked, v0, v1));
+ if (isCallValid)
+ {
+ context->programUniform2ui(programPacked, locationPacked, v0, v1);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform2ui, isCallValid, context, programPacked, locationPacked, v0,
+ v1);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniform2uiv(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLuint *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform2uiv,
+ "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
+ CID(context), program, location, count, (uintptr_t)value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramUniform2uiv(context, angle::EntryPoint::GLProgramUniform2uiv,
+ programPacked, locationPacked, count, value));
+ if (isCallValid)
+ {
+ context->programUniform2uiv(programPacked, locationPacked, count, value);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform2uiv, isCallValid, context, programPacked, locationPacked,
+ count, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY
+GL_ProgramUniform3f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform3f,
+ "context = %d, program = %u, location = %d, v0 = %f, v1 = %f, v2 = %f", CID(context),
+ program, location, v0, v1, v2);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateProgramUniform3f(context, angle::EntryPoint::GLProgramUniform3f,
+ programPacked, locationPacked, v0, v1, v2));
+ if (isCallValid)
+ {
+ context->programUniform3f(programPacked, locationPacked, v0, v1, v2);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform3f, isCallValid, context, programPacked, locationPacked, v0,
+ v1, v2);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniform3fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLfloat *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform3fv,
+ "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
+ CID(context), program, location, count, (uintptr_t)value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramUniform3fv(context, angle::EntryPoint::GLProgramUniform3fv,
+ programPacked, locationPacked, count, value));
+ if (isCallValid)
+ {
+ context->programUniform3fv(programPacked, locationPacked, count, value);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform3fv, isCallValid, context, programPacked, locationPacked,
+ count, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniform3i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform3i,
+ "context = %d, program = %u, location = %d, v0 = %d, v1 = %d, v2 = %d", CID(context),
+ program, location, v0, v1, v2);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateProgramUniform3i(context, angle::EntryPoint::GLProgramUniform3i,
+ programPacked, locationPacked, v0, v1, v2));
+ if (isCallValid)
+ {
+ context->programUniform3i(programPacked, locationPacked, v0, v1, v2);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform3i, isCallValid, context, programPacked, locationPacked, v0,
+ v1, v2);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniform3iv(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLint *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform3iv,
+ "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
+ CID(context), program, location, count, (uintptr_t)value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramUniform3iv(context, angle::EntryPoint::GLProgramUniform3iv,
+ programPacked, locationPacked, count, value));
+ if (isCallValid)
+ {
+ context->programUniform3iv(programPacked, locationPacked, count, value);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform3iv, isCallValid, context, programPacked, locationPacked,
+ count, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY
+GL_ProgramUniform3ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform3ui,
+ "context = %d, program = %u, location = %d, v0 = %u, v1 = %u, v2 = %u", CID(context),
+ program, location, v0, v1, v2);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramUniform3ui(context, angle::EntryPoint::GLProgramUniform3ui,
+ programPacked, locationPacked, v0, v1, v2));
+ if (isCallValid)
+ {
+ context->programUniform3ui(programPacked, locationPacked, v0, v1, v2);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform3ui, isCallValid, context, programPacked, locationPacked, v0,
+ v1, v2);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniform3uiv(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLuint *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform3uiv,
+ "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
+ CID(context), program, location, count, (uintptr_t)value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramUniform3uiv(context, angle::EntryPoint::GLProgramUniform3uiv,
+ programPacked, locationPacked, count, value));
+ if (isCallValid)
+ {
+ context->programUniform3uiv(programPacked, locationPacked, count, value);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform3uiv, isCallValid, context, programPacked, locationPacked,
+ count, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY
+GL_ProgramUniform4f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform4f,
+ "context = %d, program = %u, location = %d, v0 = %f, v1 = %f, v2 = %f, v3 = %f",
+ CID(context), program, location, v0, v1, v2, v3);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramUniform4f(context, angle::EntryPoint::GLProgramUniform4f, programPacked,
+ locationPacked, v0, v1, v2, v3));
+ if (isCallValid)
+ {
+ context->programUniform4f(programPacked, locationPacked, v0, v1, v2, v3);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform4f, isCallValid, context, programPacked, locationPacked, v0,
+ v1, v2, v3);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniform4fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLfloat *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform4fv,
+ "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
+ CID(context), program, location, count, (uintptr_t)value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramUniform4fv(context, angle::EntryPoint::GLProgramUniform4fv,
+ programPacked, locationPacked, count, value));
+ if (isCallValid)
+ {
+ context->programUniform4fv(programPacked, locationPacked, count, value);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform4fv, isCallValid, context, programPacked, locationPacked,
+ count, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY
+GL_ProgramUniform4i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform4i,
+ "context = %d, program = %u, location = %d, v0 = %d, v1 = %d, v2 = %d, v3 = %d",
+ CID(context), program, location, v0, v1, v2, v3);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramUniform4i(context, angle::EntryPoint::GLProgramUniform4i, programPacked,
+ locationPacked, v0, v1, v2, v3));
+ if (isCallValid)
+ {
+ context->programUniform4i(programPacked, locationPacked, v0, v1, v2, v3);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform4i, isCallValid, context, programPacked, locationPacked, v0,
+ v1, v2, v3);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniform4iv(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLint *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform4iv,
+ "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
+ CID(context), program, location, count, (uintptr_t)value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramUniform4iv(context, angle::EntryPoint::GLProgramUniform4iv,
+ programPacked, locationPacked, count, value));
+ if (isCallValid)
+ {
+ context->programUniform4iv(programPacked, locationPacked, count, value);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform4iv, isCallValid, context, programPacked, locationPacked,
+ count, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY
+GL_ProgramUniform4ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform4ui,
+ "context = %d, program = %u, location = %d, v0 = %u, v1 = %u, v2 = %u, v3 = %u",
+ CID(context), program, location, v0, v1, v2, v3);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramUniform4ui(context, angle::EntryPoint::GLProgramUniform4ui,
+ programPacked, locationPacked, v0, v1, v2, v3));
+ if (isCallValid)
+ {
+ context->programUniform4ui(programPacked, locationPacked, v0, v1, v2, v3);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform4ui, isCallValid, context, programPacked, locationPacked, v0,
+ v1, v2, v3);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniform4uiv(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLuint *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform4uiv,
+ "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
+ CID(context), program, location, count, (uintptr_t)value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramUniform4uiv(context, angle::EntryPoint::GLProgramUniform4uiv,
+ programPacked, locationPacked, count, value));
+ if (isCallValid)
+ {
+ context->programUniform4uiv(programPacked, locationPacked, count, value);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform4uiv, isCallValid, context, programPacked, locationPacked,
+ count, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniformMatrix2fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniformMatrix2fv,
+ "context = %d, program = %u, location = %d, count = %d, transpose = %s, value = "
+ "0x%016" PRIxPTR "",
+ CID(context), program, location, count, GLbooleanToString(transpose), (uintptr_t)value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateProgramUniformMatrix2fv(
+ context, angle::EntryPoint::GLProgramUniformMatrix2fv,
+ programPacked, locationPacked, count, transpose, value));
+ if (isCallValid)
+ {
+ context->programUniformMatrix2fv(programPacked, locationPacked, count, transpose,
+ value);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniformMatrix2fv, isCallValid, context, programPacked,
+ locationPacked, count, transpose, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniformMatrix2x3fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniformMatrix2x3fv,
+ "context = %d, program = %u, location = %d, count = %d, transpose = %s, value = "
+ "0x%016" PRIxPTR "",
+ CID(context), program, location, count, GLbooleanToString(transpose), (uintptr_t)value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateProgramUniformMatrix2x3fv(
+ context, angle::EntryPoint::GLProgramUniformMatrix2x3fv,
+ programPacked, locationPacked, count, transpose, value));
+ if (isCallValid)
+ {
+ context->programUniformMatrix2x3fv(programPacked, locationPacked, count, transpose,
+ value);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniformMatrix2x3fv, isCallValid, context, programPacked,
+ locationPacked, count, transpose, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniformMatrix2x4fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniformMatrix2x4fv,
+ "context = %d, program = %u, location = %d, count = %d, transpose = %s, value = "
+ "0x%016" PRIxPTR "",
+ CID(context), program, location, count, GLbooleanToString(transpose), (uintptr_t)value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateProgramUniformMatrix2x4fv(
+ context, angle::EntryPoint::GLProgramUniformMatrix2x4fv,
+ programPacked, locationPacked, count, transpose, value));
+ if (isCallValid)
+ {
+ context->programUniformMatrix2x4fv(programPacked, locationPacked, count, transpose,
+ value);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniformMatrix2x4fv, isCallValid, context, programPacked,
+ locationPacked, count, transpose, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniformMatrix3fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniformMatrix3fv,
+ "context = %d, program = %u, location = %d, count = %d, transpose = %s, value = "
+ "0x%016" PRIxPTR "",
+ CID(context), program, location, count, GLbooleanToString(transpose), (uintptr_t)value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateProgramUniformMatrix3fv(
+ context, angle::EntryPoint::GLProgramUniformMatrix3fv,
+ programPacked, locationPacked, count, transpose, value));
+ if (isCallValid)
+ {
+ context->programUniformMatrix3fv(programPacked, locationPacked, count, transpose,
+ value);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniformMatrix3fv, isCallValid, context, programPacked,
+ locationPacked, count, transpose, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniformMatrix3x2fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniformMatrix3x2fv,
+ "context = %d, program = %u, location = %d, count = %d, transpose = %s, value = "
+ "0x%016" PRIxPTR "",
+ CID(context), program, location, count, GLbooleanToString(transpose), (uintptr_t)value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateProgramUniformMatrix3x2fv(
+ context, angle::EntryPoint::GLProgramUniformMatrix3x2fv,
+ programPacked, locationPacked, count, transpose, value));
+ if (isCallValid)
+ {
+ context->programUniformMatrix3x2fv(programPacked, locationPacked, count, transpose,
+ value);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniformMatrix3x2fv, isCallValid, context, programPacked,
+ locationPacked, count, transpose, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniformMatrix3x4fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniformMatrix3x4fv,
+ "context = %d, program = %u, location = %d, count = %d, transpose = %s, value = "
+ "0x%016" PRIxPTR "",
+ CID(context), program, location, count, GLbooleanToString(transpose), (uintptr_t)value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateProgramUniformMatrix3x4fv(
+ context, angle::EntryPoint::GLProgramUniformMatrix3x4fv,
+ programPacked, locationPacked, count, transpose, value));
+ if (isCallValid)
+ {
+ context->programUniformMatrix3x4fv(programPacked, locationPacked, count, transpose,
+ value);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniformMatrix3x4fv, isCallValid, context, programPacked,
+ locationPacked, count, transpose, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniformMatrix4fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniformMatrix4fv,
+ "context = %d, program = %u, location = %d, count = %d, transpose = %s, value = "
+ "0x%016" PRIxPTR "",
+ CID(context), program, location, count, GLbooleanToString(transpose), (uintptr_t)value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateProgramUniformMatrix4fv(
+ context, angle::EntryPoint::GLProgramUniformMatrix4fv,
+ programPacked, locationPacked, count, transpose, value));
+ if (isCallValid)
+ {
+ context->programUniformMatrix4fv(programPacked, locationPacked, count, transpose,
+ value);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniformMatrix4fv, isCallValid, context, programPacked,
+ locationPacked, count, transpose, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniformMatrix4x2fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniformMatrix4x2fv,
+ "context = %d, program = %u, location = %d, count = %d, transpose = %s, value = "
+ "0x%016" PRIxPTR "",
+ CID(context), program, location, count, GLbooleanToString(transpose), (uintptr_t)value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateProgramUniformMatrix4x2fv(
+ context, angle::EntryPoint::GLProgramUniformMatrix4x2fv,
+ programPacked, locationPacked, count, transpose, value));
+ if (isCallValid)
+ {
+ context->programUniformMatrix4x2fv(programPacked, locationPacked, count, transpose,
+ value);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniformMatrix4x2fv, isCallValid, context, programPacked,
+ locationPacked, count, transpose, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniformMatrix4x3fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniformMatrix4x3fv,
+ "context = %d, program = %u, location = %d, count = %d, transpose = %s, value = "
+ "0x%016" PRIxPTR "",
+ CID(context), program, location, count, GLbooleanToString(transpose), (uintptr_t)value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateProgramUniformMatrix4x3fv(
+ context, angle::EntryPoint::GLProgramUniformMatrix4x3fv,
+ programPacked, locationPacked, count, transpose, value));
+ if (isCallValid)
+ {
+ context->programUniformMatrix4x3fv(programPacked, locationPacked, count, transpose,
+ value);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniformMatrix4x3fv, isCallValid, context, programPacked,
+ locationPacked, count, transpose, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_SampleMaski(GLuint maskNumber, GLbitfield mask)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLSampleMaski, "context = %d, maskNumber = %u, mask = %s", CID(context),
+ maskNumber, GLbitfieldToString(GLESEnum::AllEnums, mask).c_str());
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateSampleMaski(context, angle::EntryPoint::GLSampleMaski, maskNumber, mask));
+ if (isCallValid)
+ {
+ context->sampleMaski(maskNumber, mask);
+ }
+ ANGLE_CAPTURE_GL(SampleMaski, isCallValid, context, maskNumber, mask);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexStorage2DMultisample(GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedsamplelocations)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexStorage2DMultisample,
+ "context = %d, target = %s, samples = %d, internalformat = %s, width = %d, height = %d, "
+ "fixedsamplelocations = %s",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target), samples,
+ GLenumToString(GLESEnum::SizedInternalFormat, internalformat), width, height,
+ GLbooleanToString(fixedsamplelocations));
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateTexStorage2DMultisample(
+ context, angle::EntryPoint::GLTexStorage2DMultisample, targetPacked,
+ samples, internalformat, width, height, fixedsamplelocations));
+ if (isCallValid)
+ {
+ context->texStorage2DMultisample(targetPacked, samples, internalformat, width, height,
+ fixedsamplelocations);
+ }
+ ANGLE_CAPTURE_GL(TexStorage2DMultisample, isCallValid, context, targetPacked, samples,
+ internalformat, width, height, fixedsamplelocations);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_UseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLUseProgramStages, "context = %d, pipeline = %u, stages = %s, program = %u",
+ CID(context), pipeline, GLbitfieldToString(GLESEnum::UseProgramStageMask, stages).c_str(),
+ program);
+
+ if (context)
+ {
+ ProgramPipelineID pipelinePacked = PackParam<ProgramPipelineID>(pipeline);
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateUseProgramStages(context, angle::EntryPoint::GLUseProgramStages,
+ pipelinePacked, stages, programPacked));
+ if (isCallValid)
+ {
+ context->useProgramStages(pipelinePacked, stages, programPacked);
+ }
+ ANGLE_CAPTURE_GL(UseProgramStages, isCallValid, context, pipelinePacked, stages,
+ programPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ValidateProgramPipeline(GLuint pipeline)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLValidateProgramPipeline, "context = %d, pipeline = %u", CID(context),
+ pipeline);
+
+ if (context)
+ {
+ ProgramPipelineID pipelinePacked = PackParam<ProgramPipelineID>(pipeline);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateValidateProgramPipeline(context, angle::EntryPoint::GLValidateProgramPipeline,
+ pipelinePacked));
+ if (isCallValid)
+ {
+ context->validateProgramPipeline(pipelinePacked);
+ }
+ ANGLE_CAPTURE_GL(ValidateProgramPipeline, isCallValid, context, pipelinePacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_VertexAttribBinding(GLuint attribindex, GLuint bindingindex)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLVertexAttribBinding, "context = %d, attribindex = %u, bindingindex = %u",
+ CID(context), attribindex, bindingindex);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateVertexAttribBinding(context, angle::EntryPoint::GLVertexAttribBinding,
+ attribindex, bindingindex));
+ if (isCallValid)
+ {
+ context->vertexAttribBinding(attribindex, bindingindex);
+ }
+ ANGLE_CAPTURE_GL(VertexAttribBinding, isCallValid, context, attribindex, bindingindex);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_VertexAttribFormat(GLuint attribindex,
+ GLint size,
+ GLenum type,
+ GLboolean normalized,
+ GLuint relativeoffset)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLVertexAttribFormat,
+ "context = %d, attribindex = %u, size = %d, type = %s, normalized = %s, relativeoffset = "
+ "%u",
+ CID(context), attribindex, size, GLenumToString(GLESEnum::VertexAttribType, type),
+ GLbooleanToString(normalized), relativeoffset);
+
+ if (context)
+ {
+ VertexAttribType typePacked = PackParam<VertexAttribType>(type);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateVertexAttribFormat(context, angle::EntryPoint::GLVertexAttribFormat,
+ attribindex, size, typePacked, normalized, relativeoffset));
+ if (isCallValid)
+ {
+ context->vertexAttribFormat(attribindex, size, typePacked, normalized, relativeoffset);
+ }
+ ANGLE_CAPTURE_GL(VertexAttribFormat, isCallValid, context, attribindex, size, typePacked,
+ normalized, relativeoffset);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_VertexAttribIFormat(GLuint attribindex,
+ GLint size,
+ GLenum type,
+ GLuint relativeoffset)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLVertexAttribIFormat,
+ "context = %d, attribindex = %u, size = %d, type = %s, relativeoffset = %u", CID(context),
+ attribindex, size, GLenumToString(GLESEnum::VertexAttribIType, type), relativeoffset);
+
+ if (context)
+ {
+ VertexAttribType typePacked = PackParam<VertexAttribType>(type);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateVertexAttribIFormat(context, angle::EntryPoint::GLVertexAttribIFormat,
+ attribindex, size, typePacked, relativeoffset));
+ if (isCallValid)
+ {
+ context->vertexAttribIFormat(attribindex, size, typePacked, relativeoffset);
+ }
+ ANGLE_CAPTURE_GL(VertexAttribIFormat, isCallValid, context, attribindex, size, typePacked,
+ relativeoffset);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_VertexBindingDivisor(GLuint bindingindex, GLuint divisor)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLVertexBindingDivisor, "context = %d, bindingindex = %u, divisor = %u",
+ CID(context), bindingindex, divisor);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateVertexBindingDivisor(context, angle::EntryPoint::GLVertexBindingDivisor,
+ bindingindex, divisor));
+ if (isCallValid)
+ {
+ context->vertexBindingDivisor(bindingindex, divisor);
+ }
+ ANGLE_CAPTURE_GL(VertexBindingDivisor, isCallValid, context, bindingindex, divisor);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+} // extern "C"
diff --git a/gfx/angle/checkout/src/libGLESv2/entry_points_gles_3_1_autogen.h b/gfx/angle/checkout/src/libGLESv2/entry_points_gles_3_1_autogen.h
new file mode 100644
index 0000000000..8af020ef14
--- /dev/null
+++ b/gfx/angle/checkout/src/libGLESv2/entry_points_gles_3_1_autogen.h
@@ -0,0 +1,235 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml.
+//
+// Copyright 2020 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_autogen.h:
+// Defines the GLES 3.1 entry points.
+
+#ifndef LIBGLESV2_ENTRY_POINTS_GLES_3_1_AUTOGEN_H_
+#define LIBGLESV2_ENTRY_POINTS_GLES_3_1_AUTOGEN_H_
+
+#include <GLES3/gl31.h>
+#include <export.h>
+#include "common/platform.h"
+
+extern "C" {
+ANGLE_EXPORT void GL_APIENTRY GL_ActiveShaderProgram(GLuint pipeline, GLuint program);
+ANGLE_EXPORT void GL_APIENTRY GL_BindImageTexture(GLuint unit,
+ GLuint texture,
+ GLint level,
+ GLboolean layered,
+ GLint layer,
+ GLenum access,
+ GLenum format);
+ANGLE_EXPORT void GL_APIENTRY GL_BindProgramPipeline(GLuint pipeline);
+ANGLE_EXPORT void GL_APIENTRY GL_BindVertexBuffer(GLuint bindingindex,
+ GLuint buffer,
+ GLintptr offset,
+ GLsizei stride);
+ANGLE_EXPORT GLuint GL_APIENTRY GL_CreateShaderProgramv(GLenum type,
+ GLsizei count,
+ const GLchar *const *strings);
+ANGLE_EXPORT void GL_APIENTRY GL_DeleteProgramPipelines(GLsizei n, const GLuint *pipelines);
+ANGLE_EXPORT void GL_APIENTRY GL_DispatchCompute(GLuint num_groups_x,
+ GLuint num_groups_y,
+ GLuint num_groups_z);
+ANGLE_EXPORT void GL_APIENTRY GL_DispatchComputeIndirect(GLintptr indirect);
+ANGLE_EXPORT void GL_APIENTRY GL_DrawArraysIndirect(GLenum mode, const void *indirect);
+ANGLE_EXPORT void GL_APIENTRY GL_DrawElementsIndirect(GLenum mode,
+ GLenum type,
+ const void *indirect);
+ANGLE_EXPORT void GL_APIENTRY GL_FramebufferParameteri(GLenum target, GLenum pname, GLint param);
+ANGLE_EXPORT void GL_APIENTRY GL_GenProgramPipelines(GLsizei n, GLuint *pipelines);
+ANGLE_EXPORT void GL_APIENTRY GL_GetBooleani_v(GLenum target, GLuint index, GLboolean *data);
+ANGLE_EXPORT void GL_APIENTRY GL_GetFramebufferParameteriv(GLenum target,
+ GLenum pname,
+ GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetMultisamplefv(GLenum pname, GLuint index, GLfloat *val);
+ANGLE_EXPORT void GL_APIENTRY GL_GetProgramInterfaceiv(GLuint program,
+ GLenum programInterface,
+ GLenum pname,
+ GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetProgramPipelineInfoLog(GLuint pipeline,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *infoLog);
+ANGLE_EXPORT void GL_APIENTRY GL_GetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params);
+ANGLE_EXPORT GLuint GL_APIENTRY GL_GetProgramResourceIndex(GLuint program,
+ GLenum programInterface,
+ const GLchar *name);
+ANGLE_EXPORT GLint GL_APIENTRY GL_GetProgramResourceLocation(GLuint program,
+ GLenum programInterface,
+ const GLchar *name);
+ANGLE_EXPORT void GL_APIENTRY GL_GetProgramResourceName(GLuint program,
+ GLenum programInterface,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *name);
+ANGLE_EXPORT void GL_APIENTRY GL_GetProgramResourceiv(GLuint program,
+ GLenum programInterface,
+ GLuint index,
+ GLsizei propCount,
+ const GLenum *props,
+ GLsizei count,
+ GLsizei *length,
+ GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetTexLevelParameterfv(GLenum target,
+ GLint level,
+ GLenum pname,
+ GLfloat *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetTexLevelParameteriv(GLenum target,
+ GLint level,
+ GLenum pname,
+ GLint *params);
+ANGLE_EXPORT GLboolean GL_APIENTRY GL_IsProgramPipeline(GLuint pipeline);
+ANGLE_EXPORT void GL_APIENTRY GL_MemoryBarrier(GLbitfield barriers);
+ANGLE_EXPORT void GL_APIENTRY GL_MemoryBarrierByRegion(GLbitfield barriers);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniform1f(GLuint program, GLint location, GLfloat v0);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniform1fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniform1i(GLuint program, GLint location, GLint v0);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniform1iv(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLint *value);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniform1ui(GLuint program, GLint location, GLuint v0);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniform1uiv(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLuint *value);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniform2f(GLuint program,
+ GLint location,
+ GLfloat v0,
+ GLfloat v1);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniform2fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniform2i(GLuint program,
+ GLint location,
+ GLint v0,
+ GLint v1);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniform2iv(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLint *value);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniform2ui(GLuint program,
+ GLint location,
+ GLuint v0,
+ GLuint v1);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniform2uiv(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLuint *value);
+ANGLE_EXPORT void GL_APIENTRY
+GL_ProgramUniform3f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniform3fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY
+GL_ProgramUniform3i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniform3iv(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLint *value);
+ANGLE_EXPORT void GL_APIENTRY
+GL_ProgramUniform3ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniform3uiv(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLuint *value);
+ANGLE_EXPORT void GL_APIENTRY
+GL_ProgramUniform4f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniform4fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY
+GL_ProgramUniform4i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniform4iv(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLint *value);
+ANGLE_EXPORT void GL_APIENTRY
+GL_ProgramUniform4ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniform4uiv(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLuint *value);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniformMatrix2fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniformMatrix2x3fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniformMatrix2x4fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniformMatrix3fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniformMatrix3x2fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniformMatrix3x4fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniformMatrix4fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniformMatrix4x2fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniformMatrix4x3fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY GL_SampleMaski(GLuint maskNumber, GLbitfield mask);
+ANGLE_EXPORT void GL_APIENTRY GL_TexStorage2DMultisample(GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedsamplelocations);
+ANGLE_EXPORT void GL_APIENTRY GL_UseProgramStages(GLuint pipeline,
+ GLbitfield stages,
+ GLuint program);
+ANGLE_EXPORT void GL_APIENTRY GL_ValidateProgramPipeline(GLuint pipeline);
+ANGLE_EXPORT void GL_APIENTRY GL_VertexAttribBinding(GLuint attribindex, GLuint bindingindex);
+ANGLE_EXPORT void GL_APIENTRY GL_VertexAttribFormat(GLuint attribindex,
+ GLint size,
+ GLenum type,
+ GLboolean normalized,
+ GLuint relativeoffset);
+ANGLE_EXPORT void GL_APIENTRY GL_VertexAttribIFormat(GLuint attribindex,
+ GLint size,
+ GLenum type,
+ GLuint relativeoffset);
+ANGLE_EXPORT void GL_APIENTRY GL_VertexBindingDivisor(GLuint bindingindex, GLuint divisor);
+} // extern "C"
+
+#endif // LIBGLESV2_ENTRY_POINTS_GLES_3_1_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libGLESv2/entry_points_gles_3_2_autogen.cpp b/gfx/angle/checkout/src/libGLESv2/entry_points_gles_3_2_autogen.cpp
new file mode 100644
index 0000000000..831c92acee
--- /dev/null
+++ b/gfx/angle/checkout/src/libGLESv2/entry_points_gles_3_2_autogen.cpp
@@ -0,0 +1,1327 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml.
+//
+// Copyright 2020 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_2_autogen.cpp:
+// Defines the GLES 3.2 entry points.
+
+#include "libGLESv2/entry_points_gles_3_2_autogen.h"
+
+#include "common/entry_points_enum_autogen.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Context.inl.h"
+#include "libANGLE/capture/capture_gles_3_2_autogen.h"
+#include "libANGLE/capture/gl_enum_utils.h"
+#include "libANGLE/entry_points_utils.h"
+#include "libANGLE/validationES32.h"
+#include "libGLESv2/global_state.h"
+
+using namespace gl;
+
+extern "C" {
+void GL_APIENTRY GL_BlendBarrier()
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBlendBarrier, "context = %d", CID(context));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateBlendBarrier(context, angle::EntryPoint::GLBlendBarrier));
+ if (isCallValid)
+ {
+ context->blendBarrier();
+ }
+ ANGLE_CAPTURE_GL(BlendBarrier, isCallValid, context);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_BlendEquationSeparatei(GLuint buf, GLenum modeRGB, GLenum modeAlpha)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBlendEquationSeparatei, "context = %d, buf = %u, modeRGB = %s, modeAlpha = %s",
+ CID(context), buf, GLenumToString(GLESEnum::BlendEquationModeEXT, modeRGB),
+ GLenumToString(GLESEnum::BlendEquationModeEXT, modeAlpha));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateBlendEquationSeparatei(context, angle::EntryPoint::GLBlendEquationSeparatei,
+ buf, modeRGB, modeAlpha));
+ if (isCallValid)
+ {
+ context->blendEquationSeparatei(buf, modeRGB, modeAlpha);
+ }
+ ANGLE_CAPTURE_GL(BlendEquationSeparatei, isCallValid, context, buf, modeRGB, modeAlpha);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_BlendEquationi(GLuint buf, GLenum mode)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBlendEquationi, "context = %d, buf = %u, mode = %s", CID(context), buf,
+ GLenumToString(GLESEnum::BlendEquationModeEXT, mode));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateBlendEquationi(context, angle::EntryPoint::GLBlendEquationi, buf, mode));
+ if (isCallValid)
+ {
+ context->blendEquationi(buf, mode);
+ }
+ ANGLE_CAPTURE_GL(BlendEquationi, isCallValid, context, buf, mode);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY
+GL_BlendFuncSeparatei(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBlendFuncSeparatei,
+ "context = %d, buf = %u, srcRGB = %s, dstRGB = %s, srcAlpha = %s, dstAlpha = %s",
+ CID(context), buf, GLenumToString(GLESEnum::BlendingFactor, srcRGB),
+ GLenumToString(GLESEnum::BlendingFactor, dstRGB),
+ GLenumToString(GLESEnum::BlendingFactor, srcAlpha),
+ GLenumToString(GLESEnum::BlendingFactor, dstAlpha));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateBlendFuncSeparatei(context, angle::EntryPoint::GLBlendFuncSeparatei, buf,
+ srcRGB, dstRGB, srcAlpha, dstAlpha));
+ if (isCallValid)
+ {
+ context->blendFuncSeparatei(buf, srcRGB, dstRGB, srcAlpha, dstAlpha);
+ }
+ ANGLE_CAPTURE_GL(BlendFuncSeparatei, isCallValid, context, buf, srcRGB, dstRGB, srcAlpha,
+ dstAlpha);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_BlendFunci(GLuint buf, GLenum src, GLenum dst)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBlendFunci, "context = %d, buf = %u, src = %s, dst = %s", CID(context), buf,
+ GLenumToString(GLESEnum::BlendingFactor, src),
+ GLenumToString(GLESEnum::BlendingFactor, dst));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateBlendFunci(context, angle::EntryPoint::GLBlendFunci, buf, src, dst));
+ if (isCallValid)
+ {
+ context->blendFunci(buf, src, dst);
+ }
+ ANGLE_CAPTURE_GL(BlendFunci, isCallValid, context, buf, src, dst);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ColorMaski(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLColorMaski, "context = %d, index = %u, r = %s, g = %s, b = %s, a = %s",
+ CID(context), index, GLbooleanToString(r), GLbooleanToString(g), GLbooleanToString(b),
+ GLbooleanToString(a));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateColorMaski(context, angle::EntryPoint::GLColorMaski, index, r, g, b, a));
+ if (isCallValid)
+ {
+ context->colorMaski(index, r, g, b, a);
+ }
+ ANGLE_CAPTURE_GL(ColorMaski, isCallValid, context, index, r, g, b, a);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_CopyImageSubData(GLuint srcName,
+ GLenum srcTarget,
+ GLint srcLevel,
+ GLint srcX,
+ GLint srcY,
+ GLint srcZ,
+ GLuint dstName,
+ GLenum dstTarget,
+ GLint dstLevel,
+ GLint dstX,
+ GLint dstY,
+ GLint dstZ,
+ GLsizei srcWidth,
+ GLsizei srcHeight,
+ GLsizei srcDepth)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLCopyImageSubData,
+ "context = %d, srcName = %u, srcTarget = %s, srcLevel = %d, srcX = %d, srcY = %d, srcZ = "
+ "%d, dstName = %u, dstTarget = %s, dstLevel = %d, dstX = %d, dstY = %d, dstZ = %d, "
+ "srcWidth = %d, srcHeight = %d, srcDepth = %d",
+ CID(context), srcName, GLenumToString(GLESEnum::CopyImageSubDataTarget, srcTarget),
+ srcLevel, srcX, srcY, srcZ, dstName,
+ GLenumToString(GLESEnum::CopyImageSubDataTarget, dstTarget), dstLevel, dstX, dstY, dstZ,
+ srcWidth, srcHeight, srcDepth);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateCopyImageSubData(context, angle::EntryPoint::GLCopyImageSubData, srcName,
+ srcTarget, srcLevel, srcX, srcY, srcZ, dstName, dstTarget,
+ dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight, srcDepth));
+ if (isCallValid)
+ {
+ context->copyImageSubData(srcName, srcTarget, srcLevel, srcX, srcY, srcZ, dstName,
+ dstTarget, dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight,
+ srcDepth);
+ }
+ ANGLE_CAPTURE_GL(CopyImageSubData, isCallValid, context, srcName, srcTarget, srcLevel, srcX,
+ srcY, srcZ, dstName, dstTarget, dstLevel, dstX, dstY, dstZ, srcWidth,
+ srcHeight, srcDepth);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DebugMessageCallback(GLDEBUGPROC callback, const void *userParam)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDebugMessageCallback,
+ "context = %d, callback = 0x%016" PRIxPTR ", userParam = 0x%016" PRIxPTR "", CID(context),
+ (uintptr_t)callback, (uintptr_t)userParam);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateDebugMessageCallback(context, angle::EntryPoint::GLDebugMessageCallback,
+ callback, userParam));
+ if (isCallValid)
+ {
+ context->debugMessageCallback(callback, userParam);
+ }
+ ANGLE_CAPTURE_GL(DebugMessageCallback, isCallValid, context, callback, userParam);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DebugMessageControl(GLenum source,
+ GLenum type,
+ GLenum severity,
+ GLsizei count,
+ const GLuint *ids,
+ GLboolean enabled)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDebugMessageControl,
+ "context = %d, source = %s, type = %s, severity = %s, count = %d, ids = 0x%016" PRIxPTR
+ ", enabled = %s",
+ CID(context), GLenumToString(GLESEnum::DebugSource, source),
+ GLenumToString(GLESEnum::DebugType, type),
+ GLenumToString(GLESEnum::DebugSeverity, severity), count, (uintptr_t)ids,
+ GLbooleanToString(enabled));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateDebugMessageControl(context, angle::EntryPoint::GLDebugMessageControl, source,
+ type, severity, count, ids, enabled));
+ if (isCallValid)
+ {
+ context->debugMessageControl(source, type, severity, count, ids, enabled);
+ }
+ ANGLE_CAPTURE_GL(DebugMessageControl, isCallValid, context, source, type, severity, count,
+ ids, enabled);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DebugMessageInsert(GLenum source,
+ GLenum type,
+ GLuint id,
+ GLenum severity,
+ GLsizei length,
+ const GLchar *buf)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDebugMessageInsert,
+ "context = %d, source = %s, type = %s, id = %u, severity = %s, length = %d, buf = "
+ "0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::DebugSource, source),
+ GLenumToString(GLESEnum::DebugType, type), id,
+ GLenumToString(GLESEnum::DebugSeverity, severity), length, (uintptr_t)buf);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateDebugMessageInsert(context, angle::EntryPoint::GLDebugMessageInsert, source,
+ type, id, severity, length, buf));
+ if (isCallValid)
+ {
+ context->debugMessageInsert(source, type, id, severity, length, buf);
+ }
+ ANGLE_CAPTURE_GL(DebugMessageInsert, isCallValid, context, source, type, id, severity,
+ length, buf);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Disablei(GLenum target, GLuint index)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDisablei, "context = %d, target = %s, index = %u", CID(context),
+ GLenumToString(GLESEnum::EnableCap, target), index);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateDisablei(context, angle::EntryPoint::GLDisablei, target, index));
+ if (isCallValid)
+ {
+ context->disablei(target, index);
+ }
+ ANGLE_CAPTURE_GL(Disablei, isCallValid, context, target, index);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DrawElementsBaseVertex(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLint basevertex)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDrawElementsBaseVertex,
+ "context = %d, mode = %s, count = %d, type = %s, indices = 0x%016" PRIxPTR
+ ", basevertex = %d",
+ CID(context), GLenumToString(GLESEnum::PrimitiveType, mode), count,
+ GLenumToString(GLESEnum::DrawElementsType, type), (uintptr_t)indices, basevertex);
+
+ if (context)
+ {
+ PrimitiveMode modePacked = PackParam<PrimitiveMode>(mode);
+ DrawElementsType typePacked = PackParam<DrawElementsType>(type);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateDrawElementsBaseVertex(context, angle::EntryPoint::GLDrawElementsBaseVertex,
+ modePacked, count, typePacked, indices, basevertex));
+ if (isCallValid)
+ {
+ context->drawElementsBaseVertex(modePacked, count, typePacked, indices, basevertex);
+ }
+ ANGLE_CAPTURE_GL(DrawElementsBaseVertex, isCallValid, context, modePacked, count,
+ typePacked, indices, basevertex);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DrawElementsInstancedBaseVertex(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLsizei instancecount,
+ GLint basevertex)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDrawElementsInstancedBaseVertex,
+ "context = %d, mode = %s, count = %d, type = %s, indices = 0x%016" PRIxPTR
+ ", instancecount = %d, basevertex = %d",
+ CID(context), GLenumToString(GLESEnum::PrimitiveType, mode), count,
+ GLenumToString(GLESEnum::DrawElementsType, type), (uintptr_t)indices, instancecount,
+ basevertex);
+
+ if (context)
+ {
+ PrimitiveMode modePacked = PackParam<PrimitiveMode>(mode);
+ DrawElementsType typePacked = PackParam<DrawElementsType>(type);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateDrawElementsInstancedBaseVertex(
+ context, angle::EntryPoint::GLDrawElementsInstancedBaseVertex,
+ modePacked, count, typePacked, indices, instancecount, basevertex));
+ if (isCallValid)
+ {
+ context->drawElementsInstancedBaseVertex(modePacked, count, typePacked, indices,
+ instancecount, basevertex);
+ }
+ ANGLE_CAPTURE_GL(DrawElementsInstancedBaseVertex, isCallValid, context, modePacked, count,
+ typePacked, indices, instancecount, basevertex);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DrawRangeElementsBaseVertex(GLenum mode,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLint basevertex)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDrawRangeElementsBaseVertex,
+ "context = %d, mode = %s, start = %u, end = %u, count = %d, type = %s, indices = "
+ "0x%016" PRIxPTR ", basevertex = %d",
+ CID(context), GLenumToString(GLESEnum::PrimitiveType, mode), start, end, count,
+ GLenumToString(GLESEnum::DrawElementsType, type), (uintptr_t)indices, basevertex);
+
+ if (context)
+ {
+ PrimitiveMode modePacked = PackParam<PrimitiveMode>(mode);
+ DrawElementsType typePacked = PackParam<DrawElementsType>(type);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateDrawRangeElementsBaseVertex(
+ context, angle::EntryPoint::GLDrawRangeElementsBaseVertex,
+ modePacked, start, end, count, typePacked, indices, basevertex));
+ if (isCallValid)
+ {
+ context->drawRangeElementsBaseVertex(modePacked, start, end, count, typePacked, indices,
+ basevertex);
+ }
+ ANGLE_CAPTURE_GL(DrawRangeElementsBaseVertex, isCallValid, context, modePacked, start, end,
+ count, typePacked, indices, basevertex);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_Enablei(GLenum target, GLuint index)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLEnablei, "context = %d, target = %s, index = %u", CID(context),
+ GLenumToString(GLESEnum::EnableCap, target), index);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateEnablei(context, angle::EntryPoint::GLEnablei, target, index));
+ if (isCallValid)
+ {
+ context->enablei(target, index);
+ }
+ ANGLE_CAPTURE_GL(Enablei, isCallValid, context, target, index);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_FramebufferTexture(GLenum target,
+ GLenum attachment,
+ GLuint texture,
+ GLint level)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLFramebufferTexture,
+ "context = %d, target = %s, attachment = %s, texture = %u, level = %d", CID(context),
+ GLenumToString(GLESEnum::FramebufferTarget, target),
+ GLenumToString(GLESEnum::FramebufferAttachment, attachment), texture, level);
+
+ if (context)
+ {
+ TextureID texturePacked = PackParam<TextureID>(texture);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateFramebufferTexture(context, angle::EntryPoint::GLFramebufferTexture, target,
+ attachment, texturePacked, level));
+ if (isCallValid)
+ {
+ context->framebufferTexture(target, attachment, texturePacked, level);
+ }
+ ANGLE_CAPTURE_GL(FramebufferTexture, isCallValid, context, target, attachment,
+ texturePacked, level);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+GLuint GL_APIENTRY GL_GetDebugMessageLog(GLuint count,
+ GLsizei bufSize,
+ GLenum *sources,
+ GLenum *types,
+ GLuint *ids,
+ GLenum *severities,
+ GLsizei *lengths,
+ GLchar *messageLog)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetDebugMessageLog,
+ "context = %d, count = %u, bufSize = %d, sources = 0x%016" PRIxPTR
+ ", types = 0x%016" PRIxPTR ", ids = 0x%016" PRIxPTR ", severities = 0x%016" PRIxPTR
+ ", lengths = 0x%016" PRIxPTR ", messageLog = 0x%016" PRIxPTR "",
+ CID(context), count, bufSize, (uintptr_t)sources, (uintptr_t)types, (uintptr_t)ids,
+ (uintptr_t)severities, (uintptr_t)lengths, (uintptr_t)messageLog);
+
+ GLuint returnValue;
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetDebugMessageLog(
+ context, angle::EntryPoint::GLGetDebugMessageLog, count, bufSize,
+ sources, types, ids, severities, lengths, messageLog));
+ if (isCallValid)
+ {
+ returnValue = context->getDebugMessageLog(count, bufSize, sources, types, ids,
+ severities, lengths, messageLog);
+ }
+ else
+ {
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLGetDebugMessageLog, GLuint>();
+ }
+ ANGLE_CAPTURE_GL(GetDebugMessageLog, isCallValid, context, count, bufSize, sources, types,
+ ids, severities, lengths, messageLog, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLGetDebugMessageLog, GLuint>();
+ }
+ return returnValue;
+}
+
+GLenum GL_APIENTRY GL_GetGraphicsResetStatus()
+{
+ Context *context = GetGlobalContext();
+ EVENT(context, GLGetGraphicsResetStatus, "context = %d", CID(context));
+
+ GLenum returnValue;
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetGraphicsResetStatus(context, angle::EntryPoint::GLGetGraphicsResetStatus));
+ if (isCallValid)
+ {
+ returnValue = context->getGraphicsResetStatus();
+ }
+ else
+ {
+ returnValue =
+ GetDefaultReturnValue<angle::EntryPoint::GLGetGraphicsResetStatus, GLenum>();
+ }
+ ANGLE_CAPTURE_GL(GetGraphicsResetStatus, isCallValid, context, returnValue);
+ }
+ else
+ {
+
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLGetGraphicsResetStatus, GLenum>();
+ }
+ return returnValue;
+}
+
+void GL_APIENTRY
+GL_GetObjectLabel(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetObjectLabel,
+ "context = %d, identifier = %s, name = %u, bufSize = %d, length = 0x%016" PRIxPTR
+ ", label = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::ObjectIdentifier, identifier), name, bufSize,
+ (uintptr_t)length, (uintptr_t)label);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetObjectLabel(context, angle::EntryPoint::GLGetObjectLabel,
+ identifier, name, bufSize, length, label));
+ if (isCallValid)
+ {
+ context->getObjectLabel(identifier, name, bufSize, length, label);
+ }
+ ANGLE_CAPTURE_GL(GetObjectLabel, isCallValid, context, identifier, name, bufSize, length,
+ label);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetObjectPtrLabel(const void *ptr,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *label)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetObjectPtrLabel,
+ "context = %d, ptr = 0x%016" PRIxPTR ", bufSize = %d, length = 0x%016" PRIxPTR
+ ", label = 0x%016" PRIxPTR "",
+ CID(context), (uintptr_t)ptr, bufSize, (uintptr_t)length, (uintptr_t)label);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetObjectPtrLabel(context, angle::EntryPoint::GLGetObjectPtrLabel, ptr,
+ bufSize, length, label));
+ if (isCallValid)
+ {
+ context->getObjectPtrLabel(ptr, bufSize, length, label);
+ }
+ ANGLE_CAPTURE_GL(GetObjectPtrLabel, isCallValid, context, ptr, bufSize, length, label);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetPointerv(GLenum pname, void **params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetPointerv, "context = %d, pname = %s, params = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::GetPointervPName, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetPointerv(context, angle::EntryPoint::GLGetPointerv, pname, params));
+ if (isCallValid)
+ {
+ context->getPointerv(pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetPointerv, isCallValid, context, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetSamplerParameterIiv(GLuint sampler, GLenum pname, GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetSamplerParameterIiv,
+ "context = %d, sampler = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ sampler, GLenumToString(GLESEnum::SamplerParameterI, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ SamplerID samplerPacked = PackParam<SamplerID>(sampler);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetSamplerParameterIiv(context, angle::EntryPoint::GLGetSamplerParameterIiv,
+ samplerPacked, pname, params));
+ if (isCallValid)
+ {
+ context->getSamplerParameterIiv(samplerPacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetSamplerParameterIiv, isCallValid, context, samplerPacked, pname,
+ params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetSamplerParameterIuiv(GLuint sampler, GLenum pname, GLuint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetSamplerParameterIuiv,
+ "context = %d, sampler = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ sampler, GLenumToString(GLESEnum::SamplerParameterI, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ SamplerID samplerPacked = PackParam<SamplerID>(sampler);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetSamplerParameterIuiv(context, angle::EntryPoint::GLGetSamplerParameterIuiv,
+ samplerPacked, pname, params));
+ if (isCallValid)
+ {
+ context->getSamplerParameterIuiv(samplerPacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetSamplerParameterIuiv, isCallValid, context, samplerPacked, pname,
+ params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetTexParameterIiv(GLenum target, GLenum pname, GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetTexParameterIiv,
+ "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::TextureTarget, target),
+ GLenumToString(GLESEnum::GetTextureParameter, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetTexParameterIiv(context, angle::EntryPoint::GLGetTexParameterIiv,
+ targetPacked, pname, params));
+ if (isCallValid)
+ {
+ context->getTexParameterIiv(targetPacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetTexParameterIiv, isCallValid, context, targetPacked, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetTexParameterIuiv(GLenum target, GLenum pname, GLuint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetTexParameterIuiv,
+ "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::TextureTarget, target),
+ GLenumToString(GLESEnum::GetTextureParameter, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetTexParameterIuiv(context, angle::EntryPoint::GLGetTexParameterIuiv,
+ targetPacked, pname, params));
+ if (isCallValid)
+ {
+ context->getTexParameterIuiv(targetPacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetTexParameterIuiv, isCallValid, context, targetPacked, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetnUniformfv(GLuint program, GLint location, GLsizei bufSize, GLfloat *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetnUniformfv,
+ "context = %d, program = %u, location = %d, bufSize = %d, params = 0x%016" PRIxPTR "",
+ CID(context), program, location, bufSize, (uintptr_t)params);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetnUniformfv(context, angle::EntryPoint::GLGetnUniformfv,
+ programPacked, locationPacked, bufSize, params));
+ if (isCallValid)
+ {
+ context->getnUniformfv(programPacked, locationPacked, bufSize, params);
+ }
+ ANGLE_CAPTURE_GL(GetnUniformfv, isCallValid, context, programPacked, locationPacked,
+ bufSize, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetnUniformiv(GLuint program, GLint location, GLsizei bufSize, GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetnUniformiv,
+ "context = %d, program = %u, location = %d, bufSize = %d, params = 0x%016" PRIxPTR "",
+ CID(context), program, location, bufSize, (uintptr_t)params);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetnUniformiv(context, angle::EntryPoint::GLGetnUniformiv,
+ programPacked, locationPacked, bufSize, params));
+ if (isCallValid)
+ {
+ context->getnUniformiv(programPacked, locationPacked, bufSize, params);
+ }
+ ANGLE_CAPTURE_GL(GetnUniformiv, isCallValid, context, programPacked, locationPacked,
+ bufSize, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetnUniformuiv(GLuint program, GLint location, GLsizei bufSize, GLuint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetnUniformuiv,
+ "context = %d, program = %u, location = %d, bufSize = %d, params = 0x%016" PRIxPTR "",
+ CID(context), program, location, bufSize, (uintptr_t)params);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetnUniformuiv(context, angle::EntryPoint::GLGetnUniformuiv,
+ programPacked, locationPacked, bufSize, params));
+ if (isCallValid)
+ {
+ context->getnUniformuiv(programPacked, locationPacked, bufSize, params);
+ }
+ ANGLE_CAPTURE_GL(GetnUniformuiv, isCallValid, context, programPacked, locationPacked,
+ bufSize, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+GLboolean GL_APIENTRY GL_IsEnabledi(GLenum target, GLuint index)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLIsEnabledi, "context = %d, target = %s, index = %u", CID(context),
+ GLenumToString(GLESEnum::EnableCap, target), index);
+
+ GLboolean returnValue;
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateIsEnabledi(context, angle::EntryPoint::GLIsEnabledi, target, index));
+ if (isCallValid)
+ {
+ returnValue = context->isEnabledi(target, index);
+ }
+ else
+ {
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsEnabledi, GLboolean>();
+ }
+ ANGLE_CAPTURE_GL(IsEnabledi, isCallValid, context, target, index, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsEnabledi, GLboolean>();
+ }
+ return returnValue;
+}
+
+void GL_APIENTRY GL_MinSampleShading(GLfloat value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLMinSampleShading, "context = %d, value = %f", CID(context), value);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateMinSampleShading(context, angle::EntryPoint::GLMinSampleShading, value));
+ if (isCallValid)
+ {
+ context->minSampleShading(value);
+ }
+ ANGLE_CAPTURE_GL(MinSampleShading, isCallValid, context, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ObjectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLObjectLabel,
+ "context = %d, identifier = %s, name = %u, length = %d, label = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::ObjectIdentifier, identifier), name, length,
+ (uintptr_t)label);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateObjectLabel(context, angle::EntryPoint::GLObjectLabel,
+ identifier, name, length, label));
+ if (isCallValid)
+ {
+ context->objectLabel(identifier, name, length, label);
+ }
+ ANGLE_CAPTURE_GL(ObjectLabel, isCallValid, context, identifier, name, length, label);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ObjectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLObjectPtrLabel,
+ "context = %d, ptr = 0x%016" PRIxPTR ", length = %d, label = 0x%016" PRIxPTR "",
+ CID(context), (uintptr_t)ptr, length, (uintptr_t)label);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateObjectPtrLabel(context, angle::EntryPoint::GLObjectPtrLabel,
+ ptr, length, label));
+ if (isCallValid)
+ {
+ context->objectPtrLabel(ptr, length, label);
+ }
+ ANGLE_CAPTURE_GL(ObjectPtrLabel, isCallValid, context, ptr, length, label);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_PatchParameteri(GLenum pname, GLint value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLPatchParameteri, "context = %d, pname = %s, value = %d", CID(context),
+ GLenumToString(GLESEnum::PatchParameterName, pname), value);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidatePatchParameteri(context, angle::EntryPoint::GLPatchParameteri, pname, value));
+ if (isCallValid)
+ {
+ context->patchParameteri(pname, value);
+ }
+ ANGLE_CAPTURE_GL(PatchParameteri, isCallValid, context, pname, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_PopDebugGroup()
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLPopDebugGroup, "context = %d", CID(context));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidatePopDebugGroup(context, angle::EntryPoint::GLPopDebugGroup));
+ if (isCallValid)
+ {
+ context->popDebugGroup();
+ }
+ ANGLE_CAPTURE_GL(PopDebugGroup, isCallValid, context);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_PrimitiveBoundingBox(GLfloat minX,
+ GLfloat minY,
+ GLfloat minZ,
+ GLfloat minW,
+ GLfloat maxX,
+ GLfloat maxY,
+ GLfloat maxZ,
+ GLfloat maxW)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLPrimitiveBoundingBox,
+ "context = %d, minX = %f, minY = %f, minZ = %f, minW = %f, maxX = %f, maxY = %f, maxZ = "
+ "%f, maxW = %f",
+ CID(context), minX, minY, minZ, minW, maxX, maxY, maxZ, maxW);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidatePrimitiveBoundingBox(context, angle::EntryPoint::GLPrimitiveBoundingBox, minX,
+ minY, minZ, minW, maxX, maxY, maxZ, maxW));
+ if (isCallValid)
+ {
+ context->primitiveBoundingBox(minX, minY, minZ, minW, maxX, maxY, maxZ, maxW);
+ }
+ ANGLE_CAPTURE_GL(PrimitiveBoundingBox, isCallValid, context, minX, minY, minZ, minW, maxX,
+ maxY, maxZ, maxW);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_PushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLPushDebugGroup,
+ "context = %d, source = %s, id = %u, length = %d, message = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::DebugSource, source), id, length,
+ (uintptr_t)message);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidatePushDebugGroup(context, angle::EntryPoint::GLPushDebugGroup,
+ source, id, length, message));
+ if (isCallValid)
+ {
+ context->pushDebugGroup(source, id, length, message);
+ }
+ ANGLE_CAPTURE_GL(PushDebugGroup, isCallValid, context, source, id, length, message);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ReadnPixels(GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ void *data)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLReadnPixels,
+ "context = %d, x = %d, y = %d, width = %d, height = %d, format = %s, type = %s, bufSize "
+ "= %d, data = 0x%016" PRIxPTR "",
+ CID(context), x, y, width, height, GLenumToString(GLESEnum::PixelFormat, format),
+ GLenumToString(GLESEnum::PixelType, type), bufSize, (uintptr_t)data);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateReadnPixels(context, angle::EntryPoint::GLReadnPixels, x, y,
+ width, height, format, type, bufSize, data));
+ if (isCallValid)
+ {
+ context->readnPixels(x, y, width, height, format, type, bufSize, data);
+ }
+ ANGLE_CAPTURE_GL(ReadnPixels, isCallValid, context, x, y, width, height, format, type,
+ bufSize, data);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_SamplerParameterIiv(GLuint sampler, GLenum pname, const GLint *param)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLSamplerParameterIiv,
+ "context = %d, sampler = %u, pname = %s, param = 0x%016" PRIxPTR "", CID(context),
+ sampler, GLenumToString(GLESEnum::SamplerParameterI, pname), (uintptr_t)param);
+
+ if (context)
+ {
+ SamplerID samplerPacked = PackParam<SamplerID>(sampler);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateSamplerParameterIiv(context, angle::EntryPoint::GLSamplerParameterIiv,
+ samplerPacked, pname, param));
+ if (isCallValid)
+ {
+ context->samplerParameterIiv(samplerPacked, pname, param);
+ }
+ ANGLE_CAPTURE_GL(SamplerParameterIiv, isCallValid, context, samplerPacked, pname, param);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_SamplerParameterIuiv(GLuint sampler, GLenum pname, const GLuint *param)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLSamplerParameterIuiv,
+ "context = %d, sampler = %u, pname = %s, param = 0x%016" PRIxPTR "", CID(context),
+ sampler, GLenumToString(GLESEnum::SamplerParameterI, pname), (uintptr_t)param);
+
+ if (context)
+ {
+ SamplerID samplerPacked = PackParam<SamplerID>(sampler);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateSamplerParameterIuiv(context, angle::EntryPoint::GLSamplerParameterIuiv,
+ samplerPacked, pname, param));
+ if (isCallValid)
+ {
+ context->samplerParameterIuiv(samplerPacked, pname, param);
+ }
+ ANGLE_CAPTURE_GL(SamplerParameterIuiv, isCallValid, context, samplerPacked, pname, param);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexBuffer(GLenum target, GLenum internalformat, GLuint buffer)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexBuffer, "context = %d, target = %s, internalformat = %s, buffer = %u",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target),
+ GLenumToString(GLESEnum::SizedInternalFormat, internalformat), buffer);
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ BufferID bufferPacked = PackParam<BufferID>(buffer);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateTexBuffer(context, angle::EntryPoint::GLTexBuffer, targetPacked,
+ internalformat, bufferPacked));
+ if (isCallValid)
+ {
+ context->texBuffer(targetPacked, internalformat, bufferPacked);
+ }
+ ANGLE_CAPTURE_GL(TexBuffer, isCallValid, context, targetPacked, internalformat,
+ bufferPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexBufferRange(GLenum target,
+ GLenum internalformat,
+ GLuint buffer,
+ GLintptr offset,
+ GLsizeiptr size)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexBufferRange,
+ "context = %d, target = %s, internalformat = %s, buffer = %u, offset = %llu, size = %llu",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target),
+ GLenumToString(GLESEnum::SizedInternalFormat, internalformat), buffer,
+ static_cast<unsigned long long>(offset), static_cast<unsigned long long>(size));
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ BufferID bufferPacked = PackParam<BufferID>(buffer);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateTexBufferRange(context, angle::EntryPoint::GLTexBufferRange, targetPacked,
+ internalformat, bufferPacked, offset, size));
+ if (isCallValid)
+ {
+ context->texBufferRange(targetPacked, internalformat, bufferPacked, offset, size);
+ }
+ ANGLE_CAPTURE_GL(TexBufferRange, isCallValid, context, targetPacked, internalformat,
+ bufferPacked, offset, size);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexParameterIiv(GLenum target, GLenum pname, const GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexParameterIiv,
+ "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::TextureTarget, target),
+ GLenumToString(GLESEnum::TextureParameterName, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateTexParameterIiv(context, angle::EntryPoint::GLTexParameterIiv,
+ targetPacked, pname, params));
+ if (isCallValid)
+ {
+ context->texParameterIiv(targetPacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(TexParameterIiv, isCallValid, context, targetPacked, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexParameterIuiv(GLenum target, GLenum pname, const GLuint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexParameterIuiv,
+ "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::TextureTarget, target),
+ GLenumToString(GLESEnum::TextureParameterName, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateTexParameterIuiv(context, angle::EntryPoint::GLTexParameterIuiv,
+ targetPacked, pname, params));
+ if (isCallValid)
+ {
+ context->texParameterIuiv(targetPacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(TexParameterIuiv, isCallValid, context, targetPacked, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexStorage3DMultisample(GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean fixedsamplelocations)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexStorage3DMultisample,
+ "context = %d, target = %s, samples = %d, internalformat = %s, width = %d, height = %d, "
+ "depth = %d, fixedsamplelocations = %s",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target), samples,
+ GLenumToString(GLESEnum::SizedInternalFormat, internalformat), width, height, depth,
+ GLbooleanToString(fixedsamplelocations));
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateTexStorage3DMultisample(context, angle::EntryPoint::GLTexStorage3DMultisample,
+ targetPacked, samples, internalformat, width, height,
+ depth, fixedsamplelocations));
+ if (isCallValid)
+ {
+ context->texStorage3DMultisample(targetPacked, samples, internalformat, width, height,
+ depth, fixedsamplelocations);
+ }
+ ANGLE_CAPTURE_GL(TexStorage3DMultisample, isCallValid, context, targetPacked, samples,
+ internalformat, width, height, depth, fixedsamplelocations);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+} // extern "C"
diff --git a/gfx/angle/checkout/src/libGLESv2/entry_points_gles_3_2_autogen.h b/gfx/angle/checkout/src/libGLESv2/entry_points_gles_3_2_autogen.h
new file mode 100644
index 0000000000..02fd24d436
--- /dev/null
+++ b/gfx/angle/checkout/src/libGLESv2/entry_points_gles_3_2_autogen.h
@@ -0,0 +1,172 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml.
+//
+// Copyright 2020 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_2_autogen.h:
+// Defines the GLES 3.2 entry points.
+
+#ifndef LIBGLESV2_ENTRY_POINTS_GLES_3_2_AUTOGEN_H_
+#define LIBGLESV2_ENTRY_POINTS_GLES_3_2_AUTOGEN_H_
+
+#include <GLES3/gl32.h>
+#include <export.h>
+
+extern "C" {
+ANGLE_EXPORT void GL_APIENTRY GL_BlendBarrier();
+ANGLE_EXPORT void GL_APIENTRY GL_BlendEquationSeparatei(GLuint buf,
+ GLenum modeRGB,
+ GLenum modeAlpha);
+ANGLE_EXPORT void GL_APIENTRY GL_BlendEquationi(GLuint buf, GLenum mode);
+ANGLE_EXPORT void GL_APIENTRY
+GL_BlendFuncSeparatei(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+ANGLE_EXPORT void GL_APIENTRY GL_BlendFunci(GLuint buf, GLenum src, GLenum dst);
+ANGLE_EXPORT void GL_APIENTRY
+GL_ColorMaski(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
+ANGLE_EXPORT void GL_APIENTRY GL_CopyImageSubData(GLuint srcName,
+ GLenum srcTarget,
+ GLint srcLevel,
+ GLint srcX,
+ GLint srcY,
+ GLint srcZ,
+ GLuint dstName,
+ GLenum dstTarget,
+ GLint dstLevel,
+ GLint dstX,
+ GLint dstY,
+ GLint dstZ,
+ GLsizei srcWidth,
+ GLsizei srcHeight,
+ GLsizei srcDepth);
+ANGLE_EXPORT void GL_APIENTRY GL_DebugMessageCallback(GLDEBUGPROC callback, const void *userParam);
+ANGLE_EXPORT void GL_APIENTRY GL_DebugMessageControl(GLenum source,
+ GLenum type,
+ GLenum severity,
+ GLsizei count,
+ const GLuint *ids,
+ GLboolean enabled);
+ANGLE_EXPORT void GL_APIENTRY GL_DebugMessageInsert(GLenum source,
+ GLenum type,
+ GLuint id,
+ GLenum severity,
+ GLsizei length,
+ const GLchar *buf);
+ANGLE_EXPORT void GL_APIENTRY GL_Disablei(GLenum target, GLuint index);
+ANGLE_EXPORT void GL_APIENTRY GL_DrawElementsBaseVertex(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLint basevertex);
+ANGLE_EXPORT void GL_APIENTRY GL_DrawElementsInstancedBaseVertex(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLsizei instancecount,
+ GLint basevertex);
+ANGLE_EXPORT void GL_APIENTRY GL_DrawRangeElementsBaseVertex(GLenum mode,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLint basevertex);
+ANGLE_EXPORT void GL_APIENTRY GL_Enablei(GLenum target, GLuint index);
+ANGLE_EXPORT void GL_APIENTRY GL_FramebufferTexture(GLenum target,
+ GLenum attachment,
+ GLuint texture,
+ GLint level);
+ANGLE_EXPORT GLuint GL_APIENTRY GL_GetDebugMessageLog(GLuint count,
+ GLsizei bufSize,
+ GLenum *sources,
+ GLenum *types,
+ GLuint *ids,
+ GLenum *severities,
+ GLsizei *lengths,
+ GLchar *messageLog);
+ANGLE_EXPORT GLenum GL_APIENTRY GL_GetGraphicsResetStatus();
+ANGLE_EXPORT void GL_APIENTRY
+GL_GetObjectLabel(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label);
+ANGLE_EXPORT void GL_APIENTRY GL_GetObjectPtrLabel(const void *ptr,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *label);
+ANGLE_EXPORT void GL_APIENTRY GL_GetPointerv(GLenum pname, void **params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetSamplerParameterIiv(GLuint sampler,
+ GLenum pname,
+ GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetSamplerParameterIuiv(GLuint sampler,
+ GLenum pname,
+ GLuint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetTexParameterIiv(GLenum target, GLenum pname, GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetTexParameterIuiv(GLenum target, GLenum pname, GLuint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetnUniformfv(GLuint program,
+ GLint location,
+ GLsizei bufSize,
+ GLfloat *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetnUniformiv(GLuint program,
+ GLint location,
+ GLsizei bufSize,
+ GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetnUniformuiv(GLuint program,
+ GLint location,
+ GLsizei bufSize,
+ GLuint *params);
+ANGLE_EXPORT GLboolean GL_APIENTRY GL_IsEnabledi(GLenum target, GLuint index);
+ANGLE_EXPORT void GL_APIENTRY GL_MinSampleShading(GLfloat value);
+ANGLE_EXPORT void GL_APIENTRY GL_ObjectLabel(GLenum identifier,
+ GLuint name,
+ GLsizei length,
+ const GLchar *label);
+ANGLE_EXPORT void GL_APIENTRY GL_ObjectPtrLabel(const void *ptr,
+ GLsizei length,
+ const GLchar *label);
+ANGLE_EXPORT void GL_APIENTRY GL_PatchParameteri(GLenum pname, GLint value);
+ANGLE_EXPORT void GL_APIENTRY GL_PopDebugGroup();
+ANGLE_EXPORT void GL_APIENTRY GL_PrimitiveBoundingBox(GLfloat minX,
+ GLfloat minY,
+ GLfloat minZ,
+ GLfloat minW,
+ GLfloat maxX,
+ GLfloat maxY,
+ GLfloat maxZ,
+ GLfloat maxW);
+ANGLE_EXPORT void GL_APIENTRY GL_PushDebugGroup(GLenum source,
+ GLuint id,
+ GLsizei length,
+ const GLchar *message);
+ANGLE_EXPORT void GL_APIENTRY GL_ReadnPixels(GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ void *data);
+ANGLE_EXPORT void GL_APIENTRY GL_SamplerParameterIiv(GLuint sampler,
+ GLenum pname,
+ const GLint *param);
+ANGLE_EXPORT void GL_APIENTRY GL_SamplerParameterIuiv(GLuint sampler,
+ GLenum pname,
+ const GLuint *param);
+ANGLE_EXPORT void GL_APIENTRY GL_TexBuffer(GLenum target, GLenum internalformat, GLuint buffer);
+ANGLE_EXPORT void GL_APIENTRY GL_TexBufferRange(GLenum target,
+ GLenum internalformat,
+ GLuint buffer,
+ GLintptr offset,
+ GLsizeiptr size);
+ANGLE_EXPORT void GL_APIENTRY GL_TexParameterIiv(GLenum target, GLenum pname, const GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_TexParameterIuiv(GLenum target,
+ GLenum pname,
+ const GLuint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_TexStorage3DMultisample(GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean fixedsamplelocations);
+} // extern "C"
+
+#endif // LIBGLESV2_ENTRY_POINTS_GLES_3_2_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libGLESv2/entry_points_gles_ext_autogen.cpp b/gfx/angle/checkout/src/libGLESv2/entry_points_gles_ext_autogen.cpp
new file mode 100644
index 0000000000..ae88df708c
--- /dev/null
+++ b/gfx/angle/checkout/src/libGLESv2/entry_points_gles_ext_autogen.cpp
@@ -0,0 +1,11984 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml and gl_angle_ext.xml.
+//
+// Copyright 2020 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_ext_autogen.cpp:
+// Defines the GLES extension entry points.
+
+#include "libGLESv2/entry_points_gles_ext_autogen.h"
+
+#include "common/entry_points_enum_autogen.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Context.inl.h"
+#include "libANGLE/capture/capture_gles_ext_autogen.h"
+#include "libANGLE/capture/gl_enum_utils.h"
+#include "libANGLE/entry_points_utils.h"
+#include "libANGLE/validationESEXT.h"
+#include "libGLESv2/global_state.h"
+
+using namespace gl;
+
+#include "libANGLE/capture/capture_gles_1_0_autogen.h"
+#include "libANGLE/capture/capture_gles_2_0_autogen.h"
+#include "libANGLE/capture/capture_gles_3_0_autogen.h"
+#include "libANGLE/capture/capture_gles_3_1_autogen.h"
+#include "libANGLE/capture/capture_gles_3_2_autogen.h"
+#include "libANGLE/validationES1.h"
+#include "libANGLE/validationES2.h"
+#include "libANGLE/validationES3.h"
+#include "libANGLE/validationES31.h"
+#include "libANGLE/validationES32.h"
+
+using namespace gl;
+
+extern "C" {
+
+// GL_AMD_performance_monitor
+void GL_APIENTRY GL_BeginPerfMonitorAMD(GLuint monitor)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBeginPerfMonitorAMD, "context = %d, monitor = %u", CID(context), monitor);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateBeginPerfMonitorAMD(
+ context, angle::EntryPoint::GLBeginPerfMonitorAMD, monitor));
+ if (isCallValid)
+ {
+ context->beginPerfMonitor(monitor);
+ }
+ ANGLE_CAPTURE_GL(BeginPerfMonitorAMD, isCallValid, context, monitor);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DeletePerfMonitorsAMD(GLsizei n, GLuint *monitors)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDeletePerfMonitorsAMD, "context = %d, n = %d, monitors = 0x%016" PRIxPTR "",
+ CID(context), n, (uintptr_t)monitors);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateDeletePerfMonitorsAMD(
+ context, angle::EntryPoint::GLDeletePerfMonitorsAMD, n, monitors));
+ if (isCallValid)
+ {
+ context->deletePerfMonitors(n, monitors);
+ }
+ ANGLE_CAPTURE_GL(DeletePerfMonitorsAMD, isCallValid, context, n, monitors);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_EndPerfMonitorAMD(GLuint monitor)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLEndPerfMonitorAMD, "context = %d, monitor = %u", CID(context), monitor);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateEndPerfMonitorAMD(context, angle::EntryPoint::GLEndPerfMonitorAMD, monitor));
+ if (isCallValid)
+ {
+ context->endPerfMonitor(monitor);
+ }
+ ANGLE_CAPTURE_GL(EndPerfMonitorAMD, isCallValid, context, monitor);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GenPerfMonitorsAMD(GLsizei n, GLuint *monitors)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGenPerfMonitorsAMD, "context = %d, n = %d, monitors = 0x%016" PRIxPTR "",
+ CID(context), n, (uintptr_t)monitors);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGenPerfMonitorsAMD(
+ context, angle::EntryPoint::GLGenPerfMonitorsAMD, n, monitors));
+ if (isCallValid)
+ {
+ context->genPerfMonitors(n, monitors);
+ }
+ ANGLE_CAPTURE_GL(GenPerfMonitorsAMD, isCallValid, context, n, monitors);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetPerfMonitorCounterDataAMD(GLuint monitor,
+ GLenum pname,
+ GLsizei dataSize,
+ GLuint *data,
+ GLint *bytesWritten)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetPerfMonitorCounterDataAMD,
+ "context = %d, monitor = %u, pname = %s, dataSize = %d, data = 0x%016" PRIxPTR
+ ", bytesWritten = 0x%016" PRIxPTR "",
+ CID(context), monitor, GLenumToString(GLESEnum::AllEnums, pname), dataSize,
+ (uintptr_t)data, (uintptr_t)bytesWritten);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetPerfMonitorCounterDataAMD(
+ context, angle::EntryPoint::GLGetPerfMonitorCounterDataAMD, monitor,
+ pname, dataSize, data, bytesWritten));
+ if (isCallValid)
+ {
+ context->getPerfMonitorCounterData(monitor, pname, dataSize, data, bytesWritten);
+ }
+ ANGLE_CAPTURE_GL(GetPerfMonitorCounterDataAMD, isCallValid, context, monitor, pname,
+ dataSize, data, bytesWritten);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetPerfMonitorCounterInfoAMD(GLuint group,
+ GLuint counter,
+ GLenum pname,
+ void *data)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetPerfMonitorCounterInfoAMD,
+ "context = %d, group = %u, counter = %u, pname = %s, data = 0x%016" PRIxPTR "",
+ CID(context), group, counter, GLenumToString(GLESEnum::AllEnums, pname), (uintptr_t)data);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetPerfMonitorCounterInfoAMD(
+ context, angle::EntryPoint::GLGetPerfMonitorCounterInfoAMD, group,
+ counter, pname, data));
+ if (isCallValid)
+ {
+ context->getPerfMonitorCounterInfo(group, counter, pname, data);
+ }
+ ANGLE_CAPTURE_GL(GetPerfMonitorCounterInfoAMD, isCallValid, context, group, counter, pname,
+ data);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetPerfMonitorCounterStringAMD(GLuint group,
+ GLuint counter,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *counterString)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetPerfMonitorCounterStringAMD,
+ "context = %d, group = %u, counter = %u, bufSize = %d, length = 0x%016" PRIxPTR
+ ", counterString = 0x%016" PRIxPTR "",
+ CID(context), group, counter, bufSize, (uintptr_t)length, (uintptr_t)counterString);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetPerfMonitorCounterStringAMD(
+ context, angle::EntryPoint::GLGetPerfMonitorCounterStringAMD, group,
+ counter, bufSize, length, counterString));
+ if (isCallValid)
+ {
+ context->getPerfMonitorCounterString(group, counter, bufSize, length, counterString);
+ }
+ ANGLE_CAPTURE_GL(GetPerfMonitorCounterStringAMD, isCallValid, context, group, counter,
+ bufSize, length, counterString);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetPerfMonitorCountersAMD(GLuint group,
+ GLint *numCounters,
+ GLint *maxActiveCounters,
+ GLsizei counterSize,
+ GLuint *counters)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetPerfMonitorCountersAMD,
+ "context = %d, group = %u, numCounters = 0x%016" PRIxPTR
+ ", maxActiveCounters = 0x%016" PRIxPTR ", counterSize = %d, counters = 0x%016" PRIxPTR "",
+ CID(context), group, (uintptr_t)numCounters, (uintptr_t)maxActiveCounters, counterSize,
+ (uintptr_t)counters);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetPerfMonitorCountersAMD(
+ context, angle::EntryPoint::GLGetPerfMonitorCountersAMD, group,
+ numCounters, maxActiveCounters, counterSize, counters));
+ if (isCallValid)
+ {
+ context->getPerfMonitorCounters(group, numCounters, maxActiveCounters, counterSize,
+ counters);
+ }
+ ANGLE_CAPTURE_GL(GetPerfMonitorCountersAMD, isCallValid, context, group, numCounters,
+ maxActiveCounters, counterSize, counters);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetPerfMonitorGroupStringAMD(GLuint group,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *groupString)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetPerfMonitorGroupStringAMD,
+ "context = %d, group = %u, bufSize = %d, length = 0x%016" PRIxPTR
+ ", groupString = 0x%016" PRIxPTR "",
+ CID(context), group, bufSize, (uintptr_t)length, (uintptr_t)groupString);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetPerfMonitorGroupStringAMD(
+ context, angle::EntryPoint::GLGetPerfMonitorGroupStringAMD, group,
+ bufSize, length, groupString));
+ if (isCallValid)
+ {
+ context->getPerfMonitorGroupString(group, bufSize, length, groupString);
+ }
+ ANGLE_CAPTURE_GL(GetPerfMonitorGroupStringAMD, isCallValid, context, group, bufSize, length,
+ groupString);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetPerfMonitorGroupsAMD(GLint *numGroups, GLsizei groupsSize, GLuint *groups)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetPerfMonitorGroupsAMD,
+ "context = %d, numGroups = 0x%016" PRIxPTR ", groupsSize = %d, groups = 0x%016" PRIxPTR
+ "",
+ CID(context), (uintptr_t)numGroups, groupsSize, (uintptr_t)groups);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetPerfMonitorGroupsAMD(context, angle::EntryPoint::GLGetPerfMonitorGroupsAMD,
+ numGroups, groupsSize, groups));
+ if (isCallValid)
+ {
+ context->getPerfMonitorGroups(numGroups, groupsSize, groups);
+ }
+ ANGLE_CAPTURE_GL(GetPerfMonitorGroupsAMD, isCallValid, context, numGroups, groupsSize,
+ groups);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_SelectPerfMonitorCountersAMD(GLuint monitor,
+ GLboolean enable,
+ GLuint group,
+ GLint numCounters,
+ GLuint *counterList)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLSelectPerfMonitorCountersAMD,
+ "context = %d, monitor = %u, enable = %s, group = %u, numCounters = %d, counterList = "
+ "0x%016" PRIxPTR "",
+ CID(context), monitor, GLbooleanToString(enable), group, numCounters,
+ (uintptr_t)counterList);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateSelectPerfMonitorCountersAMD(
+ context, angle::EntryPoint::GLSelectPerfMonitorCountersAMD, monitor,
+ enable, group, numCounters, counterList));
+ if (isCallValid)
+ {
+ context->selectPerfMonitorCounters(monitor, enable, group, numCounters, counterList);
+ }
+ ANGLE_CAPTURE_GL(SelectPerfMonitorCountersAMD, isCallValid, context, monitor, enable, group,
+ numCounters, counterList);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_ANDROID_extension_pack_es31a
+
+// GL_ANGLE_base_vertex_base_instance
+void GL_APIENTRY GL_DrawArraysInstancedBaseInstanceANGLE(GLenum mode,
+ GLint first,
+ GLsizei count,
+ GLsizei instanceCount,
+ GLuint baseInstance)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDrawArraysInstancedBaseInstanceANGLE,
+ "context = %d, mode = %s, first = %d, count = %d, instanceCount = %d, baseInstance = %u",
+ CID(context), GLenumToString(GLESEnum::PrimitiveType, mode), first, count, instanceCount,
+ baseInstance);
+
+ if (context)
+ {
+ PrimitiveMode modePacked = PackParam<PrimitiveMode>(mode);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateDrawArraysInstancedBaseInstanceANGLE(
+ context, angle::EntryPoint::GLDrawArraysInstancedBaseInstanceANGLE,
+ modePacked, first, count, instanceCount, baseInstance));
+ if (isCallValid)
+ {
+ context->drawArraysInstancedBaseInstanceANGLE(modePacked, first, count, instanceCount,
+ baseInstance);
+ }
+ ANGLE_CAPTURE_GL(DrawArraysInstancedBaseInstanceANGLE, isCallValid, context, modePacked,
+ first, count, instanceCount, baseInstance);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DrawElementsInstancedBaseVertexBaseInstanceANGLE(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const GLvoid *indices,
+ GLsizei instanceCount,
+ GLint baseVertex,
+ GLuint baseInstance)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDrawElementsInstancedBaseVertexBaseInstanceANGLE,
+ "context = %d, mode = %s, count = %d, type = %s, indices = 0x%016" PRIxPTR
+ ", instanceCount = %d, baseVertex = %d, baseInstance = %u",
+ CID(context), GLenumToString(GLESEnum::PrimitiveType, mode), count,
+ GLenumToString(GLESEnum::DrawElementsType, type), (uintptr_t)indices, instanceCount,
+ baseVertex, baseInstance);
+
+ if (context)
+ {
+ PrimitiveMode modePacked = PackParam<PrimitiveMode>(mode);
+ DrawElementsType typePacked = PackParam<DrawElementsType>(type);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateDrawElementsInstancedBaseVertexBaseInstanceANGLE(
+ context, angle::EntryPoint::GLDrawElementsInstancedBaseVertexBaseInstanceANGLE,
+ modePacked, count, typePacked, indices, instanceCount, baseVertex, baseInstance));
+ if (isCallValid)
+ {
+ context->drawElementsInstancedBaseVertexBaseInstanceANGLE(
+ modePacked, count, typePacked, indices, instanceCount, baseVertex, baseInstance);
+ }
+ ANGLE_CAPTURE_GL(DrawElementsInstancedBaseVertexBaseInstanceANGLE, isCallValid, context,
+ modePacked, count, typePacked, indices, instanceCount, baseVertex,
+ baseInstance);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_MultiDrawArraysInstancedBaseInstanceANGLE(GLenum mode,
+ const GLint *firsts,
+ const GLsizei *counts,
+ const GLsizei *instanceCounts,
+ const GLuint *baseInstances,
+ GLsizei drawcount)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLMultiDrawArraysInstancedBaseInstanceANGLE,
+ "context = %d, mode = %s, firsts = 0x%016" PRIxPTR ", counts = 0x%016" PRIxPTR
+ ", instanceCounts = 0x%016" PRIxPTR ", baseInstances = 0x%016" PRIxPTR ", drawcount = %d",
+ CID(context), GLenumToString(GLESEnum::PrimitiveType, mode), (uintptr_t)firsts,
+ (uintptr_t)counts, (uintptr_t)instanceCounts, (uintptr_t)baseInstances, drawcount);
+
+ if (context)
+ {
+ PrimitiveMode modePacked = PackParam<PrimitiveMode>(mode);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateMultiDrawArraysInstancedBaseInstanceANGLE(
+ context, angle::EntryPoint::GLMultiDrawArraysInstancedBaseInstanceANGLE,
+ modePacked, firsts, counts, instanceCounts, baseInstances, drawcount));
+ if (isCallValid)
+ {
+ context->multiDrawArraysInstancedBaseInstance(modePacked, firsts, counts,
+ instanceCounts, baseInstances, drawcount);
+ }
+ ANGLE_CAPTURE_GL(MultiDrawArraysInstancedBaseInstanceANGLE, isCallValid, context,
+ modePacked, firsts, counts, instanceCounts, baseInstances, drawcount);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY
+GL_MultiDrawElementsInstancedBaseVertexBaseInstanceANGLE(GLenum mode,
+ const GLsizei *counts,
+ GLenum type,
+ const GLvoid *const *indices,
+ const GLsizei *instanceCounts,
+ const GLint *baseVertices,
+ const GLuint *baseInstances,
+ GLsizei drawcount)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE,
+ "context = %d, mode = %s, counts = 0x%016" PRIxPTR ", type = %s, indices = 0x%016" PRIxPTR
+ ", instanceCounts = 0x%016" PRIxPTR ", baseVertices = 0x%016" PRIxPTR
+ ", baseInstances = 0x%016" PRIxPTR ", drawcount = %d",
+ CID(context), GLenumToString(GLESEnum::PrimitiveType, mode), (uintptr_t)counts,
+ GLenumToString(GLESEnum::DrawElementsType, type), (uintptr_t)indices,
+ (uintptr_t)instanceCounts, (uintptr_t)baseVertices, (uintptr_t)baseInstances, drawcount);
+
+ if (context)
+ {
+ PrimitiveMode modePacked = PackParam<PrimitiveMode>(mode);
+ DrawElementsType typePacked = PackParam<DrawElementsType>(type);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE(
+ context,
+ angle::EntryPoint::GLMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE,
+ modePacked, counts, typePacked, indices, instanceCounts, baseVertices,
+ baseInstances, drawcount));
+ if (isCallValid)
+ {
+ context->multiDrawElementsInstancedBaseVertexBaseInstance(
+ modePacked, counts, typePacked, indices, instanceCounts, baseVertices,
+ baseInstances, drawcount);
+ }
+ ANGLE_CAPTURE_GL(MultiDrawElementsInstancedBaseVertexBaseInstanceANGLE, isCallValid,
+ context, modePacked, counts, typePacked, indices, instanceCounts,
+ baseVertices, baseInstances, drawcount);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_ANGLE_copy_texture_3d
+void GL_APIENTRY GL_CopyTexture3DANGLE(GLuint sourceId,
+ GLint sourceLevel,
+ GLenum destTarget,
+ GLuint destId,
+ GLint destLevel,
+ GLint internalFormat,
+ GLenum destType,
+ GLboolean unpackFlipY,
+ GLboolean unpackPremultiplyAlpha,
+ GLboolean unpackUnmultiplyAlpha)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLCopyTexture3DANGLE,
+ "context = %d, sourceId = %u, sourceLevel = %d, destTarget = %s, destId = %u, destLevel "
+ "= %d, internalFormat = %d, destType = %s, unpackFlipY = %s, unpackPremultiplyAlpha = "
+ "%s, unpackUnmultiplyAlpha = %s",
+ CID(context), sourceId, sourceLevel, GLenumToString(GLESEnum::AllEnums, destTarget),
+ destId, destLevel, internalFormat, GLenumToString(GLESEnum::AllEnums, destType),
+ GLbooleanToString(unpackFlipY), GLbooleanToString(unpackPremultiplyAlpha),
+ GLbooleanToString(unpackUnmultiplyAlpha));
+
+ if (context)
+ {
+ TextureID sourceIdPacked = PackParam<TextureID>(sourceId);
+ TextureTarget destTargetPacked = PackParam<TextureTarget>(destTarget);
+ TextureID destIdPacked = PackParam<TextureID>(destId);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateCopyTexture3DANGLE(context, angle::EntryPoint::GLCopyTexture3DANGLE,
+ sourceIdPacked, sourceLevel, destTargetPacked, destIdPacked,
+ destLevel, internalFormat, destType, unpackFlipY,
+ unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
+ if (isCallValid)
+ {
+ context->copyTexture3D(sourceIdPacked, sourceLevel, destTargetPacked, destIdPacked,
+ destLevel, internalFormat, destType, unpackFlipY,
+ unpackPremultiplyAlpha, unpackUnmultiplyAlpha);
+ }
+ ANGLE_CAPTURE_GL(CopyTexture3DANGLE, isCallValid, context, sourceIdPacked, sourceLevel,
+ destTargetPacked, destIdPacked, destLevel, internalFormat, destType,
+ unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_CopySubTexture3DANGLE(GLuint sourceId,
+ GLint sourceLevel,
+ GLenum destTarget,
+ GLuint destId,
+ GLint destLevel,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLint x,
+ GLint y,
+ GLint z,
+ GLint width,
+ GLint height,
+ GLint depth,
+ GLboolean unpackFlipY,
+ GLboolean unpackPremultiplyAlpha,
+ GLboolean unpackUnmultiplyAlpha)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLCopySubTexture3DANGLE,
+ "context = %d, sourceId = %u, sourceLevel = %d, destTarget = %s, destId = %u, destLevel "
+ "= %d, xoffset = %d, yoffset = %d, zoffset = %d, x = %d, y = %d, z = %d, width = %d, "
+ "height = %d, depth = %d, unpackFlipY = %s, unpackPremultiplyAlpha = %s, "
+ "unpackUnmultiplyAlpha = %s",
+ CID(context), sourceId, sourceLevel, GLenumToString(GLESEnum::AllEnums, destTarget),
+ destId, destLevel, xoffset, yoffset, zoffset, x, y, z, width, height, depth,
+ GLbooleanToString(unpackFlipY), GLbooleanToString(unpackPremultiplyAlpha),
+ GLbooleanToString(unpackUnmultiplyAlpha));
+
+ if (context)
+ {
+ TextureID sourceIdPacked = PackParam<TextureID>(sourceId);
+ TextureTarget destTargetPacked = PackParam<TextureTarget>(destTarget);
+ TextureID destIdPacked = PackParam<TextureID>(destId);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateCopySubTexture3DANGLE(
+ context, angle::EntryPoint::GLCopySubTexture3DANGLE, sourceIdPacked, sourceLevel,
+ destTargetPacked, destIdPacked, destLevel, xoffset, yoffset, zoffset, x, y, z,
+ width, height, depth, unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
+ if (isCallValid)
+ {
+ context->copySubTexture3D(sourceIdPacked, sourceLevel, destTargetPacked, destIdPacked,
+ destLevel, xoffset, yoffset, zoffset, x, y, z, width, height,
+ depth, unpackFlipY, unpackPremultiplyAlpha,
+ unpackUnmultiplyAlpha);
+ }
+ ANGLE_CAPTURE_GL(CopySubTexture3DANGLE, isCallValid, context, sourceIdPacked, sourceLevel,
+ destTargetPacked, destIdPacked, destLevel, xoffset, yoffset, zoffset, x, y,
+ z, width, height, depth, unpackFlipY, unpackPremultiplyAlpha,
+ unpackUnmultiplyAlpha);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_ANGLE_depth_texture
+
+// GL_ANGLE_framebuffer_blit
+void GL_APIENTRY GL_BlitFramebufferANGLE(GLint srcX0,
+ GLint srcY0,
+ GLint srcX1,
+ GLint srcY1,
+ GLint dstX0,
+ GLint dstY0,
+ GLint dstX1,
+ GLint dstY1,
+ GLbitfield mask,
+ GLenum filter)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBlitFramebufferANGLE,
+ "context = %d, srcX0 = %d, srcY0 = %d, srcX1 = %d, srcY1 = %d, dstX0 = %d, dstY0 = %d, "
+ "dstX1 = %d, dstY1 = %d, mask = %s, filter = %s",
+ CID(context), srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,
+ GLbitfieldToString(GLESEnum::ClearBufferMask, mask).c_str(),
+ GLenumToString(GLESEnum::BlitFramebufferFilter, filter));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateBlitFramebufferANGLE(
+ context, angle::EntryPoint::GLBlitFramebufferANGLE, srcX0, srcY0,
+ srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter));
+ if (isCallValid)
+ {
+ context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask,
+ filter);
+ }
+ ANGLE_CAPTURE_GL(BlitFramebufferANGLE, isCallValid, context, srcX0, srcY0, srcX1, srcY1,
+ dstX0, dstY0, dstX1, dstY1, mask, filter);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_ANGLE_framebuffer_multisample
+void GL_APIENTRY GL_RenderbufferStorageMultisampleANGLE(GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLRenderbufferStorageMultisampleANGLE,
+ "context = %d, target = %s, samples = %d, internalformat = %s, width = %d, height = %d",
+ CID(context), GLenumToString(GLESEnum::RenderbufferTarget, target), samples,
+ GLenumToString(GLESEnum::InternalFormat, internalformat), width, height);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateRenderbufferStorageMultisampleANGLE(
+ context, angle::EntryPoint::GLRenderbufferStorageMultisampleANGLE,
+ target, samples, internalformat, width, height));
+ if (isCallValid)
+ {
+ context->renderbufferStorageMultisample(target, samples, internalformat, width, height);
+ }
+ ANGLE_CAPTURE_GL(RenderbufferStorageMultisampleANGLE, isCallValid, context, target, samples,
+ internalformat, width, height);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_ANGLE_get_image
+void GL_APIENTRY
+GL_GetTexImageANGLE(GLenum target, GLint level, GLenum format, GLenum type, void *pixels)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetTexImageANGLE,
+ "context = %d, target = %s, level = %d, format = %s, type = %s, pixels = 0x%016" PRIxPTR
+ "",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target), level,
+ GLenumToString(GLESEnum::PixelFormat, format), GLenumToString(GLESEnum::PixelType, type),
+ (uintptr_t)pixels);
+
+ if (context)
+ {
+ TextureTarget targetPacked = PackParam<TextureTarget>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetTexImageANGLE(context, angle::EntryPoint::GLGetTexImageANGLE,
+ targetPacked, level, format, type, pixels));
+ if (isCallValid)
+ {
+ context->getTexImage(targetPacked, level, format, type, pixels);
+ }
+ ANGLE_CAPTURE_GL(GetTexImageANGLE, isCallValid, context, targetPacked, level, format, type,
+ pixels);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetCompressedTexImageANGLE(GLenum target, GLint level, void *pixels)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetCompressedTexImageANGLE,
+ "context = %d, target = %s, level = %d, pixels = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::TextureTarget, target), level, (uintptr_t)pixels);
+
+ if (context)
+ {
+ TextureTarget targetPacked = PackParam<TextureTarget>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetCompressedTexImageANGLE(
+ context, angle::EntryPoint::GLGetCompressedTexImageANGLE,
+ targetPacked, level, pixels));
+ if (isCallValid)
+ {
+ context->getCompressedTexImage(targetPacked, level, pixels);
+ }
+ ANGLE_CAPTURE_GL(GetCompressedTexImageANGLE, isCallValid, context, targetPacked, level,
+ pixels);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetRenderbufferImageANGLE(GLenum target,
+ GLenum format,
+ GLenum type,
+ void *pixels)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetRenderbufferImageANGLE,
+ "context = %d, target = %s, format = %s, type = %s, pixels = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::RenderbufferTarget, target),
+ GLenumToString(GLESEnum::PixelFormat, format), GLenumToString(GLESEnum::PixelType, type),
+ (uintptr_t)pixels);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetRenderbufferImageANGLE(
+ context, angle::EntryPoint::GLGetRenderbufferImageANGLE, target,
+ format, type, pixels));
+ if (isCallValid)
+ {
+ context->getRenderbufferImage(target, format, type, pixels);
+ }
+ ANGLE_CAPTURE_GL(GetRenderbufferImageANGLE, isCallValid, context, target, format, type,
+ pixels);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_ANGLE_get_tex_level_parameter
+void GL_APIENTRY GL_GetTexLevelParameterivANGLE(GLenum target,
+ GLint level,
+ GLenum pname,
+ GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetTexLevelParameterivANGLE,
+ "context = %d, target = %s, level = %d, pname = %s, params = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target), level,
+ GLenumToString(GLESEnum::GetTextureParameter, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ TextureTarget targetPacked = PackParam<TextureTarget>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetTexLevelParameterivANGLE(
+ context, angle::EntryPoint::GLGetTexLevelParameterivANGLE,
+ targetPacked, level, pname, params));
+ if (isCallValid)
+ {
+ context->getTexLevelParameteriv(targetPacked, level, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetTexLevelParameterivANGLE, isCallValid, context, targetPacked, level,
+ pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetTexLevelParameterfvANGLE(GLenum target,
+ GLint level,
+ GLenum pname,
+ GLfloat *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetTexLevelParameterfvANGLE,
+ "context = %d, target = %s, level = %d, pname = %s, params = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, target), level,
+ GLenumToString(GLESEnum::AllEnums, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ TextureTarget targetPacked = PackParam<TextureTarget>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetTexLevelParameterfvANGLE(
+ context, angle::EntryPoint::GLGetTexLevelParameterfvANGLE,
+ targetPacked, level, pname, params));
+ if (isCallValid)
+ {
+ context->getTexLevelParameterfv(targetPacked, level, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetTexLevelParameterfvANGLE, isCallValid, context, targetPacked, level,
+ pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_ANGLE_instanced_arrays
+void GL_APIENTRY GL_DrawArraysInstancedANGLE(GLenum mode,
+ GLint first,
+ GLsizei count,
+ GLsizei primcount)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDrawArraysInstancedANGLE,
+ "context = %d, mode = %s, first = %d, count = %d, primcount = %d", CID(context),
+ GLenumToString(GLESEnum::PrimitiveType, mode), first, count, primcount);
+
+ if (context)
+ {
+ PrimitiveMode modePacked = PackParam<PrimitiveMode>(mode);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateDrawArraysInstancedANGLE(
+ context, angle::EntryPoint::GLDrawArraysInstancedANGLE, modePacked,
+ first, count, primcount));
+ if (isCallValid)
+ {
+ context->drawArraysInstanced(modePacked, first, count, primcount);
+ }
+ ANGLE_CAPTURE_GL(DrawArraysInstancedANGLE, isCallValid, context, modePacked, first, count,
+ primcount);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DrawElementsInstancedANGLE(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLsizei primcount)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDrawElementsInstancedANGLE,
+ "context = %d, mode = %s, count = %d, type = %s, indices = 0x%016" PRIxPTR
+ ", primcount = %d",
+ CID(context), GLenumToString(GLESEnum::PrimitiveType, mode), count,
+ GLenumToString(GLESEnum::PrimitiveType, type), (uintptr_t)indices, primcount);
+
+ if (context)
+ {
+ PrimitiveMode modePacked = PackParam<PrimitiveMode>(mode);
+ DrawElementsType typePacked = PackParam<DrawElementsType>(type);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateDrawElementsInstancedANGLE(
+ context, angle::EntryPoint::GLDrawElementsInstancedANGLE,
+ modePacked, count, typePacked, indices, primcount));
+ if (isCallValid)
+ {
+ context->drawElementsInstanced(modePacked, count, typePacked, indices, primcount);
+ }
+ ANGLE_CAPTURE_GL(DrawElementsInstancedANGLE, isCallValid, context, modePacked, count,
+ typePacked, indices, primcount);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_VertexAttribDivisorANGLE(GLuint index, GLuint divisor)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLVertexAttribDivisorANGLE, "context = %d, index = %u, divisor = %u",
+ CID(context), index, divisor);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateVertexAttribDivisorANGLE(
+ context, angle::EntryPoint::GLVertexAttribDivisorANGLE, index, divisor));
+ if (isCallValid)
+ {
+ context->vertexAttribDivisor(index, divisor);
+ }
+ ANGLE_CAPTURE_GL(VertexAttribDivisorANGLE, isCallValid, context, index, divisor);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_ANGLE_logic_op
+void GL_APIENTRY GL_LogicOpANGLE(GLenum opcode)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLLogicOpANGLE, "context = %d, opcode = %s", CID(context),
+ GLenumToString(GLESEnum::LogicOp, opcode));
+
+ if (context)
+ {
+ LogicalOperation opcodePacked = PackParam<LogicalOperation>(opcode);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateLogicOpANGLE(context, angle::EntryPoint::GLLogicOpANGLE, opcodePacked));
+ if (isCallValid)
+ {
+ context->logicOpANGLE(opcodePacked);
+ }
+ ANGLE_CAPTURE_GL(LogicOpANGLE, isCallValid, context, opcodePacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_ANGLE_memory_object_flags
+void GL_APIENTRY GL_TexStorageMemFlags2DANGLE(GLenum target,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLuint memory,
+ GLuint64 offset,
+ GLbitfield createFlags,
+ GLbitfield usageFlags,
+ const void *imageCreateInfoPNext)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexStorageMemFlags2DANGLE,
+ "context = %d, target = %s, levels = %d, internalFormat = %s, width = %d, height = %d, "
+ "memory = %u, offset = %llu, createFlags = %s, usageFlags = %s, imageCreateInfoPNext = "
+ "0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target), levels,
+ GLenumToString(GLESEnum::AllEnums, internalFormat), width, height, memory,
+ static_cast<unsigned long long>(offset),
+ GLbitfieldToString(GLESEnum::AllEnums, createFlags).c_str(),
+ GLbitfieldToString(GLESEnum::AllEnums, usageFlags).c_str(),
+ (uintptr_t)imageCreateInfoPNext);
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ MemoryObjectID memoryPacked = PackParam<MemoryObjectID>(memory);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateTexStorageMemFlags2DANGLE(
+ context, angle::EntryPoint::GLTexStorageMemFlags2DANGLE,
+ targetPacked, levels, internalFormat, width, height, memoryPacked,
+ offset, createFlags, usageFlags, imageCreateInfoPNext));
+ if (isCallValid)
+ {
+ context->texStorageMemFlags2D(targetPacked, levels, internalFormat, width, height,
+ memoryPacked, offset, createFlags, usageFlags,
+ imageCreateInfoPNext);
+ }
+ ANGLE_CAPTURE_GL(TexStorageMemFlags2DANGLE, isCallValid, context, targetPacked, levels,
+ internalFormat, width, height, memoryPacked, offset, createFlags,
+ usageFlags, imageCreateInfoPNext);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexStorageMemFlags2DMultisampleANGLE(GLenum target,
+ GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedSampleLocations,
+ GLuint memory,
+ GLuint64 offset,
+ GLbitfield createFlags,
+ GLbitfield usageFlags,
+ const void *imageCreateInfoPNext)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexStorageMemFlags2DMultisampleANGLE,
+ "context = %d, target = %s, samples = %d, internalFormat = %s, width = %d, height = %d, "
+ "fixedSampleLocations = %s, memory = %u, offset = %llu, createFlags = %s, usageFlags = "
+ "%s, imageCreateInfoPNext = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target), samples,
+ GLenumToString(GLESEnum::AllEnums, internalFormat), width, height,
+ GLbooleanToString(fixedSampleLocations), memory, static_cast<unsigned long long>(offset),
+ GLbitfieldToString(GLESEnum::AllEnums, createFlags).c_str(),
+ GLbitfieldToString(GLESEnum::AllEnums, usageFlags).c_str(),
+ (uintptr_t)imageCreateInfoPNext);
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ MemoryObjectID memoryPacked = PackParam<MemoryObjectID>(memory);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateTexStorageMemFlags2DMultisampleANGLE(
+ context, angle::EntryPoint::GLTexStorageMemFlags2DMultisampleANGLE, targetPacked,
+ samples, internalFormat, width, height, fixedSampleLocations, memoryPacked, offset,
+ createFlags, usageFlags, imageCreateInfoPNext));
+ if (isCallValid)
+ {
+ context->texStorageMemFlags2DMultisample(
+ targetPacked, samples, internalFormat, width, height, fixedSampleLocations,
+ memoryPacked, offset, createFlags, usageFlags, imageCreateInfoPNext);
+ }
+ ANGLE_CAPTURE_GL(TexStorageMemFlags2DMultisampleANGLE, isCallValid, context, targetPacked,
+ samples, internalFormat, width, height, fixedSampleLocations, memoryPacked,
+ offset, createFlags, usageFlags, imageCreateInfoPNext);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexStorageMemFlags3DANGLE(GLenum target,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLuint memory,
+ GLuint64 offset,
+ GLbitfield createFlags,
+ GLbitfield usageFlags,
+ const void *imageCreateInfoPNext)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexStorageMemFlags3DANGLE,
+ "context = %d, target = %s, levels = %d, internalFormat = %s, width = %d, height = %d, "
+ "depth = %d, memory = %u, offset = %llu, createFlags = %s, usageFlags = %s, "
+ "imageCreateInfoPNext = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target), levels,
+ GLenumToString(GLESEnum::AllEnums, internalFormat), width, height, depth, memory,
+ static_cast<unsigned long long>(offset),
+ GLbitfieldToString(GLESEnum::AllEnums, createFlags).c_str(),
+ GLbitfieldToString(GLESEnum::AllEnums, usageFlags).c_str(),
+ (uintptr_t)imageCreateInfoPNext);
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ MemoryObjectID memoryPacked = PackParam<MemoryObjectID>(memory);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateTexStorageMemFlags3DANGLE(
+ context, angle::EntryPoint::GLTexStorageMemFlags3DANGLE, targetPacked, levels,
+ internalFormat, width, height, depth, memoryPacked, offset, createFlags,
+ usageFlags, imageCreateInfoPNext));
+ if (isCallValid)
+ {
+ context->texStorageMemFlags3D(targetPacked, levels, internalFormat, width, height,
+ depth, memoryPacked, offset, createFlags, usageFlags,
+ imageCreateInfoPNext);
+ }
+ ANGLE_CAPTURE_GL(TexStorageMemFlags3DANGLE, isCallValid, context, targetPacked, levels,
+ internalFormat, width, height, depth, memoryPacked, offset, createFlags,
+ usageFlags, imageCreateInfoPNext);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexStorageMemFlags3DMultisampleANGLE(GLenum target,
+ GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean fixedSampleLocations,
+ GLuint memory,
+ GLuint64 offset,
+ GLbitfield createFlags,
+ GLbitfield usageFlags,
+ const void *imageCreateInfoPNext)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexStorageMemFlags3DMultisampleANGLE,
+ "context = %d, target = %s, samples = %d, internalFormat = %s, width = %d, height = %d, "
+ "depth = %d, fixedSampleLocations = %s, memory = %u, offset = %llu, createFlags = %s, "
+ "usageFlags = %s, imageCreateInfoPNext = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target), samples,
+ GLenumToString(GLESEnum::AllEnums, internalFormat), width, height, depth,
+ GLbooleanToString(fixedSampleLocations), memory, static_cast<unsigned long long>(offset),
+ GLbitfieldToString(GLESEnum::AllEnums, createFlags).c_str(),
+ GLbitfieldToString(GLESEnum::AllEnums, usageFlags).c_str(),
+ (uintptr_t)imageCreateInfoPNext);
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ MemoryObjectID memoryPacked = PackParam<MemoryObjectID>(memory);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateTexStorageMemFlags3DMultisampleANGLE(
+ context, angle::EntryPoint::GLTexStorageMemFlags3DMultisampleANGLE, targetPacked,
+ samples, internalFormat, width, height, depth, fixedSampleLocations, memoryPacked,
+ offset, createFlags, usageFlags, imageCreateInfoPNext));
+ if (isCallValid)
+ {
+ context->texStorageMemFlags3DMultisample(
+ targetPacked, samples, internalFormat, width, height, depth, fixedSampleLocations,
+ memoryPacked, offset, createFlags, usageFlags, imageCreateInfoPNext);
+ }
+ ANGLE_CAPTURE_GL(TexStorageMemFlags3DMultisampleANGLE, isCallValid, context, targetPacked,
+ samples, internalFormat, width, height, depth, fixedSampleLocations,
+ memoryPacked, offset, createFlags, usageFlags, imageCreateInfoPNext);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_ANGLE_memory_object_fuchsia
+void GL_APIENTRY GL_ImportMemoryZirconHandleANGLE(GLuint memory,
+ GLuint64 size,
+ GLenum handleType,
+ GLuint handle)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLImportMemoryZirconHandleANGLE,
+ "context = %d, memory = %u, size = %llu, handleType = %s, handle = %u", CID(context),
+ memory, static_cast<unsigned long long>(size),
+ GLenumToString(GLESEnum::ExternalHandleType, handleType), handle);
+
+ if (context)
+ {
+ MemoryObjectID memoryPacked = PackParam<MemoryObjectID>(memory);
+ HandleType handleTypePacked = PackParam<HandleType>(handleType);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateImportMemoryZirconHandleANGLE(
+ context, angle::EntryPoint::GLImportMemoryZirconHandleANGLE,
+ memoryPacked, size, handleTypePacked, handle));
+ if (isCallValid)
+ {
+ context->importMemoryZirconHandle(memoryPacked, size, handleTypePacked, handle);
+ }
+ ANGLE_CAPTURE_GL(ImportMemoryZirconHandleANGLE, isCallValid, context, memoryPacked, size,
+ handleTypePacked, handle);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_ANGLE_multi_draw
+void GL_APIENTRY GL_MultiDrawArraysANGLE(GLenum mode,
+ const GLint *firsts,
+ const GLsizei *counts,
+ GLsizei drawcount)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLMultiDrawArraysANGLE,
+ "context = %d, mode = %s, firsts = 0x%016" PRIxPTR ", counts = 0x%016" PRIxPTR
+ ", drawcount = %d",
+ CID(context), GLenumToString(GLESEnum::PrimitiveType, mode), (uintptr_t)firsts,
+ (uintptr_t)counts, drawcount);
+
+ if (context)
+ {
+ PrimitiveMode modePacked = PackParam<PrimitiveMode>(mode);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateMultiDrawArraysANGLE(context, angle::EntryPoint::GLMultiDrawArraysANGLE,
+ modePacked, firsts, counts, drawcount));
+ if (isCallValid)
+ {
+ context->multiDrawArrays(modePacked, firsts, counts, drawcount);
+ }
+ ANGLE_CAPTURE_GL(MultiDrawArraysANGLE, isCallValid, context, modePacked, firsts, counts,
+ drawcount);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_MultiDrawArraysInstancedANGLE(GLenum mode,
+ const GLint *firsts,
+ const GLsizei *counts,
+ const GLsizei *instanceCounts,
+ GLsizei drawcount)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLMultiDrawArraysInstancedANGLE,
+ "context = %d, mode = %s, firsts = 0x%016" PRIxPTR ", counts = 0x%016" PRIxPTR
+ ", instanceCounts = 0x%016" PRIxPTR ", drawcount = %d",
+ CID(context), GLenumToString(GLESEnum::PrimitiveType, mode), (uintptr_t)firsts,
+ (uintptr_t)counts, (uintptr_t)instanceCounts, drawcount);
+
+ if (context)
+ {
+ PrimitiveMode modePacked = PackParam<PrimitiveMode>(mode);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateMultiDrawArraysInstancedANGLE(
+ context, angle::EntryPoint::GLMultiDrawArraysInstancedANGLE,
+ modePacked, firsts, counts, instanceCounts, drawcount));
+ if (isCallValid)
+ {
+ context->multiDrawArraysInstanced(modePacked, firsts, counts, instanceCounts,
+ drawcount);
+ }
+ ANGLE_CAPTURE_GL(MultiDrawArraysInstancedANGLE, isCallValid, context, modePacked, firsts,
+ counts, instanceCounts, drawcount);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_MultiDrawElementsANGLE(GLenum mode,
+ const GLsizei *counts,
+ GLenum type,
+ const GLvoid *const *indices,
+ GLsizei drawcount)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLMultiDrawElementsANGLE,
+ "context = %d, mode = %s, counts = 0x%016" PRIxPTR ", type = %s, indices = 0x%016" PRIxPTR
+ ", drawcount = %d",
+ CID(context), GLenumToString(GLESEnum::PrimitiveType, mode), (uintptr_t)counts,
+ GLenumToString(GLESEnum::DrawElementsType, type), (uintptr_t)indices, drawcount);
+
+ if (context)
+ {
+ PrimitiveMode modePacked = PackParam<PrimitiveMode>(mode);
+ DrawElementsType typePacked = PackParam<DrawElementsType>(type);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateMultiDrawElementsANGLE(context, angle::EntryPoint::GLMultiDrawElementsANGLE,
+ modePacked, counts, typePacked, indices, drawcount));
+ if (isCallValid)
+ {
+ context->multiDrawElements(modePacked, counts, typePacked, indices, drawcount);
+ }
+ ANGLE_CAPTURE_GL(MultiDrawElementsANGLE, isCallValid, context, modePacked, counts,
+ typePacked, indices, drawcount);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_MultiDrawElementsInstancedANGLE(GLenum mode,
+ const GLsizei *counts,
+ GLenum type,
+ const GLvoid *const *indices,
+ const GLsizei *instanceCounts,
+ GLsizei drawcount)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLMultiDrawElementsInstancedANGLE,
+ "context = %d, mode = %s, counts = 0x%016" PRIxPTR ", type = %s, indices = 0x%016" PRIxPTR
+ ", instanceCounts = 0x%016" PRIxPTR ", drawcount = %d",
+ CID(context), GLenumToString(GLESEnum::PrimitiveType, mode), (uintptr_t)counts,
+ GLenumToString(GLESEnum::DrawElementsType, type), (uintptr_t)indices,
+ (uintptr_t)instanceCounts, drawcount);
+
+ if (context)
+ {
+ PrimitiveMode modePacked = PackParam<PrimitiveMode>(mode);
+ DrawElementsType typePacked = PackParam<DrawElementsType>(type);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateMultiDrawElementsInstancedANGLE(
+ context, angle::EntryPoint::GLMultiDrawElementsInstancedANGLE, modePacked, counts,
+ typePacked, indices, instanceCounts, drawcount));
+ if (isCallValid)
+ {
+ context->multiDrawElementsInstanced(modePacked, counts, typePacked, indices,
+ instanceCounts, drawcount);
+ }
+ ANGLE_CAPTURE_GL(MultiDrawElementsInstancedANGLE, isCallValid, context, modePacked, counts,
+ typePacked, indices, instanceCounts, drawcount);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_ANGLE_pack_reverse_row_order
+
+// GL_ANGLE_program_binary
+
+// GL_ANGLE_provoking_vertex
+void GL_APIENTRY GL_ProvokingVertexANGLE(GLenum mode)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProvokingVertexANGLE, "context = %d, mode = %s", CID(context),
+ GLenumToString(GLESEnum::VertexProvokingMode, mode));
+
+ if (context)
+ {
+ ProvokingVertexConvention modePacked = PackParam<ProvokingVertexConvention>(mode);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateProvokingVertexANGLE(
+ context, angle::EntryPoint::GLProvokingVertexANGLE, modePacked));
+ if (isCallValid)
+ {
+ context->provokingVertex(modePacked);
+ }
+ ANGLE_CAPTURE_GL(ProvokingVertexANGLE, isCallValid, context, modePacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_ANGLE_request_extension
+void GL_APIENTRY GL_RequestExtensionANGLE(const GLchar *name)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLRequestExtensionANGLE, "context = %d, name = 0x%016" PRIxPTR "", CID(context),
+ (uintptr_t)name);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateRequestExtensionANGLE(
+ context, angle::EntryPoint::GLRequestExtensionANGLE, name));
+ if (isCallValid)
+ {
+ context->requestExtension(name);
+ }
+ ANGLE_CAPTURE_GL(RequestExtensionANGLE, isCallValid, context, name);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DisableExtensionANGLE(const GLchar *name)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDisableExtensionANGLE, "context = %d, name = 0x%016" PRIxPTR "", CID(context),
+ (uintptr_t)name);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateDisableExtensionANGLE(
+ context, angle::EntryPoint::GLDisableExtensionANGLE, name));
+ if (isCallValid)
+ {
+ context->disableExtension(name);
+ }
+ ANGLE_CAPTURE_GL(DisableExtensionANGLE, isCallValid, context, name);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_ANGLE_robust_client_memory
+void GL_APIENTRY GL_GetBooleanvRobustANGLE(GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLboolean *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetBooleanvRobustANGLE,
+ "context = %d, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
+ ", params = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, pname), bufSize, (uintptr_t)length,
+ (uintptr_t)params);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetBooleanvRobustANGLE(context, angle::EntryPoint::GLGetBooleanvRobustANGLE,
+ pname, bufSize, length, params));
+ if (isCallValid)
+ {
+ context->getBooleanvRobust(pname, bufSize, length, params);
+ }
+ ANGLE_CAPTURE_GL(GetBooleanvRobustANGLE, isCallValid, context, pname, bufSize, length,
+ params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetBufferParameterivRobustANGLE(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetBufferParameterivRobustANGLE,
+ "context = %d, target = %s, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
+ ", params = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, target),
+ GLenumToString(GLESEnum::AllEnums, pname), bufSize, (uintptr_t)length, (uintptr_t)params);
+
+ if (context)
+ {
+ BufferBinding targetPacked = PackParam<BufferBinding>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetBufferParameterivRobustANGLE(
+ context, angle::EntryPoint::GLGetBufferParameterivRobustANGLE,
+ targetPacked, pname, bufSize, length, params));
+ if (isCallValid)
+ {
+ context->getBufferParameterivRobust(targetPacked, pname, bufSize, length, params);
+ }
+ ANGLE_CAPTURE_GL(GetBufferParameterivRobustANGLE, isCallValid, context, targetPacked, pname,
+ bufSize, length, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetFloatvRobustANGLE(GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetFloatvRobustANGLE,
+ "context = %d, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
+ ", params = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, pname), bufSize, (uintptr_t)length,
+ (uintptr_t)params);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetFloatvRobustANGLE(context, angle::EntryPoint::GLGetFloatvRobustANGLE, pname,
+ bufSize, length, params));
+ if (isCallValid)
+ {
+ context->getFloatvRobust(pname, bufSize, length, params);
+ }
+ ANGLE_CAPTURE_GL(GetFloatvRobustANGLE, isCallValid, context, pname, bufSize, length,
+ params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetFramebufferAttachmentParameterivRobustANGLE(GLenum target,
+ GLenum attachment,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetFramebufferAttachmentParameterivRobustANGLE,
+ "context = %d, target = %s, attachment = %s, pname = %s, bufSize = %d, length = "
+ "0x%016" PRIxPTR ", params = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, target),
+ GLenumToString(GLESEnum::AllEnums, attachment), GLenumToString(GLESEnum::AllEnums, pname),
+ bufSize, (uintptr_t)length, (uintptr_t)params);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetFramebufferAttachmentParameterivRobustANGLE(
+ context, angle::EntryPoint::GLGetFramebufferAttachmentParameterivRobustANGLE,
+ target, attachment, pname, bufSize, length, params));
+ if (isCallValid)
+ {
+ context->getFramebufferAttachmentParameterivRobust(target, attachment, pname, bufSize,
+ length, params);
+ }
+ ANGLE_CAPTURE_GL(GetFramebufferAttachmentParameterivRobustANGLE, isCallValid, context,
+ target, attachment, pname, bufSize, length, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetIntegervRobustANGLE(GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *data)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetIntegervRobustANGLE,
+ "context = %d, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
+ ", data = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, pname), bufSize, (uintptr_t)length,
+ (uintptr_t)data);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetIntegervRobustANGLE(context, angle::EntryPoint::GLGetIntegervRobustANGLE,
+ pname, bufSize, length, data));
+ if (isCallValid)
+ {
+ context->getIntegervRobust(pname, bufSize, length, data);
+ }
+ ANGLE_CAPTURE_GL(GetIntegervRobustANGLE, isCallValid, context, pname, bufSize, length,
+ data);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetProgramivRobustANGLE(GLuint program,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ Context *context = GetGlobalContext();
+ EVENT(context, GLGetProgramivRobustANGLE,
+ "context = %d, program = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
+ ", params = 0x%016" PRIxPTR "",
+ CID(context), program, GLenumToString(GLESEnum::AllEnums, pname), bufSize,
+ (uintptr_t)length, (uintptr_t)params);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetProgramivRobustANGLE(context, angle::EntryPoint::GLGetProgramivRobustANGLE,
+ programPacked, pname, bufSize, length, params));
+ if (isCallValid)
+ {
+ context->getProgramivRobust(programPacked, pname, bufSize, length, params);
+ }
+ ANGLE_CAPTURE_GL(GetProgramivRobustANGLE, isCallValid, context, programPacked, pname,
+ bufSize, length, params);
+ }
+ else
+ {}
+}
+
+void GL_APIENTRY GL_GetRenderbufferParameterivRobustANGLE(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetRenderbufferParameterivRobustANGLE,
+ "context = %d, target = %s, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
+ ", params = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, target),
+ GLenumToString(GLESEnum::AllEnums, pname), bufSize, (uintptr_t)length, (uintptr_t)params);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetRenderbufferParameterivRobustANGLE(
+ context, angle::EntryPoint::GLGetRenderbufferParameterivRobustANGLE,
+ target, pname, bufSize, length, params));
+ if (isCallValid)
+ {
+ context->getRenderbufferParameterivRobust(target, pname, bufSize, length, params);
+ }
+ ANGLE_CAPTURE_GL(GetRenderbufferParameterivRobustANGLE, isCallValid, context, target, pname,
+ bufSize, length, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetShaderivRobustANGLE(GLuint shader,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ Context *context = GetGlobalContext();
+ EVENT(context, GLGetShaderivRobustANGLE,
+ "context = %d, shader = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
+ ", params = 0x%016" PRIxPTR "",
+ CID(context), shader, GLenumToString(GLESEnum::AllEnums, pname), bufSize,
+ (uintptr_t)length, (uintptr_t)params);
+
+ if (context)
+ {
+ ShaderProgramID shaderPacked = PackParam<ShaderProgramID>(shader);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetShaderivRobustANGLE(context, angle::EntryPoint::GLGetShaderivRobustANGLE,
+ shaderPacked, pname, bufSize, length, params));
+ if (isCallValid)
+ {
+ context->getShaderivRobust(shaderPacked, pname, bufSize, length, params);
+ }
+ ANGLE_CAPTURE_GL(GetShaderivRobustANGLE, isCallValid, context, shaderPacked, pname, bufSize,
+ length, params);
+ }
+ else
+ {}
+}
+
+void GL_APIENTRY GL_GetTexParameterfvRobustANGLE(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetTexParameterfvRobustANGLE,
+ "context = %d, target = %s, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
+ ", params = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, target),
+ GLenumToString(GLESEnum::AllEnums, pname), bufSize, (uintptr_t)length, (uintptr_t)params);
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetTexParameterfvRobustANGLE(
+ context, angle::EntryPoint::GLGetTexParameterfvRobustANGLE,
+ targetPacked, pname, bufSize, length, params));
+ if (isCallValid)
+ {
+ context->getTexParameterfvRobust(targetPacked, pname, bufSize, length, params);
+ }
+ ANGLE_CAPTURE_GL(GetTexParameterfvRobustANGLE, isCallValid, context, targetPacked, pname,
+ bufSize, length, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetTexParameterivRobustANGLE(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetTexParameterivRobustANGLE,
+ "context = %d, target = %s, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
+ ", params = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, target),
+ GLenumToString(GLESEnum::AllEnums, pname), bufSize, (uintptr_t)length, (uintptr_t)params);
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetTexParameterivRobustANGLE(
+ context, angle::EntryPoint::GLGetTexParameterivRobustANGLE,
+ targetPacked, pname, bufSize, length, params));
+ if (isCallValid)
+ {
+ context->getTexParameterivRobust(targetPacked, pname, bufSize, length, params);
+ }
+ ANGLE_CAPTURE_GL(GetTexParameterivRobustANGLE, isCallValid, context, targetPacked, pname,
+ bufSize, length, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetUniformfvRobustANGLE(GLuint program,
+ GLint location,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetUniformfvRobustANGLE,
+ "context = %d, program = %u, location = %d, bufSize = %d, length = 0x%016" PRIxPTR
+ ", params = 0x%016" PRIxPTR "",
+ CID(context), program, location, bufSize, (uintptr_t)length, (uintptr_t)params);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetUniformfvRobustANGLE(
+ context, angle::EntryPoint::GLGetUniformfvRobustANGLE,
+ programPacked, locationPacked, bufSize, length, params));
+ if (isCallValid)
+ {
+ context->getUniformfvRobust(programPacked, locationPacked, bufSize, length, params);
+ }
+ ANGLE_CAPTURE_GL(GetUniformfvRobustANGLE, isCallValid, context, programPacked,
+ locationPacked, bufSize, length, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetUniformivRobustANGLE(GLuint program,
+ GLint location,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetUniformivRobustANGLE,
+ "context = %d, program = %u, location = %d, bufSize = %d, length = 0x%016" PRIxPTR
+ ", params = 0x%016" PRIxPTR "",
+ CID(context), program, location, bufSize, (uintptr_t)length, (uintptr_t)params);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetUniformivRobustANGLE(
+ context, angle::EntryPoint::GLGetUniformivRobustANGLE,
+ programPacked, locationPacked, bufSize, length, params));
+ if (isCallValid)
+ {
+ context->getUniformivRobust(programPacked, locationPacked, bufSize, length, params);
+ }
+ ANGLE_CAPTURE_GL(GetUniformivRobustANGLE, isCallValid, context, programPacked,
+ locationPacked, bufSize, length, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetVertexAttribfvRobustANGLE(GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetVertexAttribfvRobustANGLE,
+ "context = %d, index = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
+ ", params = 0x%016" PRIxPTR "",
+ CID(context), index, GLenumToString(GLESEnum::AllEnums, pname), bufSize,
+ (uintptr_t)length, (uintptr_t)params);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetVertexAttribfvRobustANGLE(
+ context, angle::EntryPoint::GLGetVertexAttribfvRobustANGLE, index,
+ pname, bufSize, length, params));
+ if (isCallValid)
+ {
+ context->getVertexAttribfvRobust(index, pname, bufSize, length, params);
+ }
+ ANGLE_CAPTURE_GL(GetVertexAttribfvRobustANGLE, isCallValid, context, index, pname, bufSize,
+ length, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetVertexAttribivRobustANGLE(GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetVertexAttribivRobustANGLE,
+ "context = %d, index = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
+ ", params = 0x%016" PRIxPTR "",
+ CID(context), index, GLenumToString(GLESEnum::AllEnums, pname), bufSize,
+ (uintptr_t)length, (uintptr_t)params);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetVertexAttribivRobustANGLE(
+ context, angle::EntryPoint::GLGetVertexAttribivRobustANGLE, index,
+ pname, bufSize, length, params));
+ if (isCallValid)
+ {
+ context->getVertexAttribivRobust(index, pname, bufSize, length, params);
+ }
+ ANGLE_CAPTURE_GL(GetVertexAttribivRobustANGLE, isCallValid, context, index, pname, bufSize,
+ length, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetVertexAttribPointervRobustANGLE(GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ void **pointer)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetVertexAttribPointervRobustANGLE,
+ "context = %d, index = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
+ ", pointer = 0x%016" PRIxPTR "",
+ CID(context), index, GLenumToString(GLESEnum::AllEnums, pname), bufSize,
+ (uintptr_t)length, (uintptr_t)pointer);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetVertexAttribPointervRobustANGLE(
+ context, angle::EntryPoint::GLGetVertexAttribPointervRobustANGLE,
+ index, pname, bufSize, length, pointer));
+ if (isCallValid)
+ {
+ context->getVertexAttribPointervRobust(index, pname, bufSize, length, pointer);
+ }
+ ANGLE_CAPTURE_GL(GetVertexAttribPointervRobustANGLE, isCallValid, context, index, pname,
+ bufSize, length, pointer);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ReadPixelsRobustANGLE(GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLsizei *columns,
+ GLsizei *rows,
+ void *pixels)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLReadPixelsRobustANGLE,
+ "context = %d, x = %d, y = %d, width = %d, height = %d, format = %s, type = %s, bufSize "
+ "= %d, length = 0x%016" PRIxPTR ", columns = 0x%016" PRIxPTR ", rows = 0x%016" PRIxPTR
+ ", pixels = 0x%016" PRIxPTR "",
+ CID(context), x, y, width, height, GLenumToString(GLESEnum::AllEnums, format),
+ GLenumToString(GLESEnum::AllEnums, type), bufSize, (uintptr_t)length, (uintptr_t)columns,
+ (uintptr_t)rows, (uintptr_t)pixels);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateReadPixelsRobustANGLE(
+ context, angle::EntryPoint::GLReadPixelsRobustANGLE, x, y, width,
+ height, format, type, bufSize, length, columns, rows, pixels));
+ if (isCallValid)
+ {
+ context->readPixelsRobust(x, y, width, height, format, type, bufSize, length, columns,
+ rows, pixels);
+ }
+ ANGLE_CAPTURE_GL(ReadPixelsRobustANGLE, isCallValid, context, x, y, width, height, format,
+ type, bufSize, length, columns, rows, pixels);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexImage2DRobustANGLE(GLenum target,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *pixels)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexImage2DRobustANGLE,
+ "context = %d, target = %s, level = %d, internalformat = %d, width = %d, height = %d, "
+ "border = %d, format = %s, type = %s, bufSize = %d, pixels = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, target), level, internalformat, width,
+ height, border, GLenumToString(GLESEnum::AllEnums, format),
+ GLenumToString(GLESEnum::AllEnums, type), bufSize, (uintptr_t)pixels);
+
+ if (context)
+ {
+ TextureTarget targetPacked = PackParam<TextureTarget>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateTexImage2DRobustANGLE(context, angle::EntryPoint::GLTexImage2DRobustANGLE,
+ targetPacked, level, internalformat, width, height,
+ border, format, type, bufSize, pixels));
+ if (isCallValid)
+ {
+ context->texImage2DRobust(targetPacked, level, internalformat, width, height, border,
+ format, type, bufSize, pixels);
+ }
+ ANGLE_CAPTURE_GL(TexImage2DRobustANGLE, isCallValid, context, targetPacked, level,
+ internalformat, width, height, border, format, type, bufSize, pixels);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexParameterfvRobustANGLE(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLfloat *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexParameterfvRobustANGLE,
+ "context = %d, target = %s, pname = %s, bufSize = %d, params = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, target),
+ GLenumToString(GLESEnum::AllEnums, pname), bufSize, (uintptr_t)params);
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateTexParameterfvRobustANGLE(
+ context, angle::EntryPoint::GLTexParameterfvRobustANGLE,
+ targetPacked, pname, bufSize, params));
+ if (isCallValid)
+ {
+ context->texParameterfvRobust(targetPacked, pname, bufSize, params);
+ }
+ ANGLE_CAPTURE_GL(TexParameterfvRobustANGLE, isCallValid, context, targetPacked, pname,
+ bufSize, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexParameterivRobustANGLE(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexParameterivRobustANGLE,
+ "context = %d, target = %s, pname = %s, bufSize = %d, params = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, target),
+ GLenumToString(GLESEnum::AllEnums, pname), bufSize, (uintptr_t)params);
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateTexParameterivRobustANGLE(
+ context, angle::EntryPoint::GLTexParameterivRobustANGLE,
+ targetPacked, pname, bufSize, params));
+ if (isCallValid)
+ {
+ context->texParameterivRobust(targetPacked, pname, bufSize, params);
+ }
+ ANGLE_CAPTURE_GL(TexParameterivRobustANGLE, isCallValid, context, targetPacked, pname,
+ bufSize, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexSubImage2DRobustANGLE(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *pixels)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexSubImage2DRobustANGLE,
+ "context = %d, target = %s, level = %d, xoffset = %d, yoffset = %d, width = %d, height = "
+ "%d, format = %s, type = %s, bufSize = %d, pixels = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, target), level, xoffset, yoffset, width,
+ height, GLenumToString(GLESEnum::AllEnums, format),
+ GLenumToString(GLESEnum::AllEnums, type), bufSize, (uintptr_t)pixels);
+
+ if (context)
+ {
+ TextureTarget targetPacked = PackParam<TextureTarget>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateTexSubImage2DRobustANGLE(
+ context, angle::EntryPoint::GLTexSubImage2DRobustANGLE, targetPacked, level,
+ xoffset, yoffset, width, height, format, type, bufSize, pixels));
+ if (isCallValid)
+ {
+ context->texSubImage2DRobust(targetPacked, level, xoffset, yoffset, width, height,
+ format, type, bufSize, pixels);
+ }
+ ANGLE_CAPTURE_GL(TexSubImage2DRobustANGLE, isCallValid, context, targetPacked, level,
+ xoffset, yoffset, width, height, format, type, bufSize, pixels);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexImage3DRobustANGLE(GLenum target,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *pixels)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexImage3DRobustANGLE,
+ "context = %d, target = %s, level = %d, internalformat = %d, width = %d, height = %d, "
+ "depth = %d, border = %d, format = %s, type = %s, bufSize = %d, pixels = 0x%016" PRIxPTR
+ "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, target), level, internalformat, width,
+ height, depth, border, GLenumToString(GLESEnum::AllEnums, format),
+ GLenumToString(GLESEnum::AllEnums, type), bufSize, (uintptr_t)pixels);
+
+ if (context)
+ {
+ TextureTarget targetPacked = PackParam<TextureTarget>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateTexImage3DRobustANGLE(context, angle::EntryPoint::GLTexImage3DRobustANGLE,
+ targetPacked, level, internalformat, width, height,
+ depth, border, format, type, bufSize, pixels));
+ if (isCallValid)
+ {
+ context->texImage3DRobust(targetPacked, level, internalformat, width, height, depth,
+ border, format, type, bufSize, pixels);
+ }
+ ANGLE_CAPTURE_GL(TexImage3DRobustANGLE, isCallValid, context, targetPacked, level,
+ internalformat, width, height, depth, border, format, type, bufSize,
+ pixels);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_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)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(
+ context, GLTexSubImage3DRobustANGLE,
+ "context = %d, target = %s, level = %d, xoffset = %d, yoffset = %d, zoffset = %d, width = "
+ "%d, height = %d, depth = %d, format = %s, type = %s, bufSize = %d, pixels = 0x%016" PRIxPTR
+ "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, target), level, xoffset, yoffset, zoffset,
+ width, height, depth, GLenumToString(GLESEnum::AllEnums, format),
+ GLenumToString(GLESEnum::AllEnums, type), bufSize, (uintptr_t)pixels);
+
+ if (context)
+ {
+ TextureTarget targetPacked = PackParam<TextureTarget>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateTexSubImage3DRobustANGLE(
+ context, angle::EntryPoint::GLTexSubImage3DRobustANGLE, targetPacked, level,
+ xoffset, yoffset, zoffset, width, height, depth, format, type, bufSize, pixels));
+ if (isCallValid)
+ {
+ context->texSubImage3DRobust(targetPacked, level, xoffset, yoffset, zoffset, width,
+ height, depth, format, type, bufSize, pixels);
+ }
+ ANGLE_CAPTURE_GL(TexSubImage3DRobustANGLE, isCallValid, context, targetPacked, level,
+ xoffset, yoffset, zoffset, width, height, depth, format, type, bufSize,
+ pixels);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_CompressedTexImage2DRobustANGLE(GLenum target,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLsizei imageSize,
+ GLsizei dataSize,
+ const GLvoid *data)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLCompressedTexImage2DRobustANGLE,
+ "context = %d, target = %s, level = %d, internalformat = %s, width = %d, height = %d, "
+ "border = %d, imageSize = %d, dataSize = %d, data = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, target), level,
+ GLenumToString(GLESEnum::AllEnums, internalformat), width, height, border, imageSize,
+ dataSize, (uintptr_t)data);
+
+ if (context)
+ {
+ TextureTarget targetPacked = PackParam<TextureTarget>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateCompressedTexImage2DRobustANGLE(
+ context, angle::EntryPoint::GLCompressedTexImage2DRobustANGLE, targetPacked, level,
+ internalformat, width, height, border, imageSize, dataSize, data));
+ if (isCallValid)
+ {
+ context->compressedTexImage2DRobust(targetPacked, level, internalformat, width, height,
+ border, imageSize, dataSize, data);
+ }
+ ANGLE_CAPTURE_GL(CompressedTexImage2DRobustANGLE, isCallValid, context, targetPacked, level,
+ internalformat, width, height, border, imageSize, dataSize, data);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_CompressedTexSubImage2DRobustANGLE(GLenum target,
+ GLint level,
+ GLsizei xoffset,
+ GLsizei yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLsizei imageSize,
+ GLsizei dataSize,
+ const GLvoid *data)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLCompressedTexSubImage2DRobustANGLE,
+ "context = %d, target = %s, level = %d, xoffset = %d, yoffset = %d, width = %d, height = "
+ "%d, format = %s, imageSize = %d, dataSize = %d, data = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, target), level, xoffset, yoffset, width,
+ height, GLenumToString(GLESEnum::AllEnums, format), imageSize, dataSize, (uintptr_t)data);
+
+ if (context)
+ {
+ TextureTarget targetPacked = PackParam<TextureTarget>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateCompressedTexSubImage2DRobustANGLE(
+ context, angle::EntryPoint::GLCompressedTexSubImage2DRobustANGLE, targetPacked,
+ level, xoffset, yoffset, width, height, format, imageSize, dataSize, data));
+ if (isCallValid)
+ {
+ context->compressedTexSubImage2DRobust(targetPacked, level, xoffset, yoffset, width,
+ height, format, imageSize, dataSize, data);
+ }
+ ANGLE_CAPTURE_GL(CompressedTexSubImage2DRobustANGLE, isCallValid, context, targetPacked,
+ level, xoffset, yoffset, width, height, format, imageSize, dataSize, data);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_CompressedTexImage3DRobustANGLE(GLenum target,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLsizei imageSize,
+ GLsizei dataSize,
+ const GLvoid *data)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLCompressedTexImage3DRobustANGLE,
+ "context = %d, target = %s, level = %d, internalformat = %s, width = %d, height = %d, "
+ "depth = %d, border = %d, imageSize = %d, dataSize = %d, data = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, target), level,
+ GLenumToString(GLESEnum::AllEnums, internalformat), width, height, depth, border,
+ imageSize, dataSize, (uintptr_t)data);
+
+ if (context)
+ {
+ TextureTarget targetPacked = PackParam<TextureTarget>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateCompressedTexImage3DRobustANGLE(
+ context, angle::EntryPoint::GLCompressedTexImage3DRobustANGLE, targetPacked, level,
+ internalformat, width, height, depth, border, imageSize, dataSize, data));
+ if (isCallValid)
+ {
+ context->compressedTexImage3DRobust(targetPacked, level, internalformat, width, height,
+ depth, border, imageSize, dataSize, data);
+ }
+ ANGLE_CAPTURE_GL(CompressedTexImage3DRobustANGLE, isCallValid, context, targetPacked, level,
+ internalformat, width, height, depth, border, imageSize, dataSize, data);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_CompressedTexSubImage3DRobustANGLE(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLsizei imageSize,
+ GLsizei dataSize,
+ const GLvoid *data)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLCompressedTexSubImage3DRobustANGLE,
+ "context = %d, target = %s, level = %d, xoffset = %d, yoffset = %d, zoffset = %d, width "
+ "= %d, height = %d, depth = %d, format = %s, imageSize = %d, dataSize = %d, data = "
+ "0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, target), level, xoffset, yoffset,
+ zoffset, width, height, depth, GLenumToString(GLESEnum::AllEnums, format), imageSize,
+ dataSize, (uintptr_t)data);
+
+ if (context)
+ {
+ TextureTarget targetPacked = PackParam<TextureTarget>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateCompressedTexSubImage3DRobustANGLE(
+ context, angle::EntryPoint::GLCompressedTexSubImage3DRobustANGLE,
+ targetPacked, level, xoffset, yoffset, zoffset, width, height,
+ depth, format, imageSize, dataSize, data));
+ if (isCallValid)
+ {
+ context->compressedTexSubImage3DRobust(targetPacked, level, xoffset, yoffset, zoffset,
+ width, height, depth, format, imageSize,
+ dataSize, data);
+ }
+ ANGLE_CAPTURE_GL(CompressedTexSubImage3DRobustANGLE, isCallValid, context, targetPacked,
+ level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize,
+ dataSize, data);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetQueryivRobustANGLE(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetQueryivRobustANGLE,
+ "context = %d, target = %s, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
+ ", params = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, target),
+ GLenumToString(GLESEnum::AllEnums, pname), bufSize, (uintptr_t)length, (uintptr_t)params);
+
+ if (context)
+ {
+ QueryType targetPacked = PackParam<QueryType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetQueryivRobustANGLE(context, angle::EntryPoint::GLGetQueryivRobustANGLE,
+ targetPacked, pname, bufSize, length, params));
+ if (isCallValid)
+ {
+ context->getQueryivRobust(targetPacked, pname, bufSize, length, params);
+ }
+ ANGLE_CAPTURE_GL(GetQueryivRobustANGLE, isCallValid, context, targetPacked, pname, bufSize,
+ length, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetQueryObjectuivRobustANGLE(GLuint id,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetQueryObjectuivRobustANGLE,
+ "context = %d, id = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
+ ", params = 0x%016" PRIxPTR "",
+ CID(context), id, GLenumToString(GLESEnum::AllEnums, pname), bufSize, (uintptr_t)length,
+ (uintptr_t)params);
+
+ if (context)
+ {
+ QueryID idPacked = PackParam<QueryID>(id);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetQueryObjectuivRobustANGLE(
+ context, angle::EntryPoint::GLGetQueryObjectuivRobustANGLE,
+ idPacked, pname, bufSize, length, params));
+ if (isCallValid)
+ {
+ context->getQueryObjectuivRobust(idPacked, pname, bufSize, length, params);
+ }
+ ANGLE_CAPTURE_GL(GetQueryObjectuivRobustANGLE, isCallValid, context, idPacked, pname,
+ bufSize, length, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetBufferPointervRobustANGLE(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ void **params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetBufferPointervRobustANGLE,
+ "context = %d, target = %s, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
+ ", params = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, target),
+ GLenumToString(GLESEnum::AllEnums, pname), bufSize, (uintptr_t)length, (uintptr_t)params);
+
+ if (context)
+ {
+ BufferBinding targetPacked = PackParam<BufferBinding>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetBufferPointervRobustANGLE(
+ context, angle::EntryPoint::GLGetBufferPointervRobustANGLE,
+ targetPacked, pname, bufSize, length, params));
+ if (isCallValid)
+ {
+ context->getBufferPointervRobust(targetPacked, pname, bufSize, length, params);
+ }
+ ANGLE_CAPTURE_GL(GetBufferPointervRobustANGLE, isCallValid, context, targetPacked, pname,
+ bufSize, length, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetIntegeri_vRobustANGLE(GLenum target,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *data)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetIntegeri_vRobustANGLE,
+ "context = %d, target = %s, index = %u, bufSize = %d, length = 0x%016" PRIxPTR
+ ", data = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, target), index, bufSize,
+ (uintptr_t)length, (uintptr_t)data);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetIntegeri_vRobustANGLE(
+ context, angle::EntryPoint::GLGetIntegeri_vRobustANGLE, target,
+ index, bufSize, length, data));
+ if (isCallValid)
+ {
+ context->getIntegeri_vRobust(target, index, bufSize, length, data);
+ }
+ ANGLE_CAPTURE_GL(GetIntegeri_vRobustANGLE, isCallValid, context, target, index, bufSize,
+ length, data);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetInternalformativRobustANGLE(GLenum target,
+ GLenum internalformat,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetInternalformativRobustANGLE,
+ "context = %d, target = %s, internalformat = %s, pname = %s, bufSize = %d, length = "
+ "0x%016" PRIxPTR ", params = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, target),
+ GLenumToString(GLESEnum::AllEnums, internalformat),
+ GLenumToString(GLESEnum::AllEnums, pname), bufSize, (uintptr_t)length, (uintptr_t)params);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetInternalformativRobustANGLE(
+ context, angle::EntryPoint::GLGetInternalformativRobustANGLE,
+ target, internalformat, pname, bufSize, length, params));
+ if (isCallValid)
+ {
+ context->getInternalformativRobust(target, internalformat, pname, bufSize, length,
+ params);
+ }
+ ANGLE_CAPTURE_GL(GetInternalformativRobustANGLE, isCallValid, context, target,
+ internalformat, pname, bufSize, length, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetVertexAttribIivRobustANGLE(GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetVertexAttribIivRobustANGLE,
+ "context = %d, index = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
+ ", params = 0x%016" PRIxPTR "",
+ CID(context), index, GLenumToString(GLESEnum::AllEnums, pname), bufSize,
+ (uintptr_t)length, (uintptr_t)params);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetVertexAttribIivRobustANGLE(
+ context, angle::EntryPoint::GLGetVertexAttribIivRobustANGLE, index,
+ pname, bufSize, length, params));
+ if (isCallValid)
+ {
+ context->getVertexAttribIivRobust(index, pname, bufSize, length, params);
+ }
+ ANGLE_CAPTURE_GL(GetVertexAttribIivRobustANGLE, isCallValid, context, index, pname, bufSize,
+ length, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetVertexAttribIuivRobustANGLE(GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetVertexAttribIuivRobustANGLE,
+ "context = %d, index = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
+ ", params = 0x%016" PRIxPTR "",
+ CID(context), index, GLenumToString(GLESEnum::AllEnums, pname), bufSize,
+ (uintptr_t)length, (uintptr_t)params);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetVertexAttribIuivRobustANGLE(
+ context, angle::EntryPoint::GLGetVertexAttribIuivRobustANGLE, index,
+ pname, bufSize, length, params));
+ if (isCallValid)
+ {
+ context->getVertexAttribIuivRobust(index, pname, bufSize, length, params);
+ }
+ ANGLE_CAPTURE_GL(GetVertexAttribIuivRobustANGLE, isCallValid, context, index, pname,
+ bufSize, length, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetUniformuivRobustANGLE(GLuint program,
+ GLint location,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetUniformuivRobustANGLE,
+ "context = %d, program = %u, location = %d, bufSize = %d, length = 0x%016" PRIxPTR
+ ", params = 0x%016" PRIxPTR "",
+ CID(context), program, location, bufSize, (uintptr_t)length, (uintptr_t)params);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetUniformuivRobustANGLE(
+ context, angle::EntryPoint::GLGetUniformuivRobustANGLE,
+ programPacked, locationPacked, bufSize, length, params));
+ if (isCallValid)
+ {
+ context->getUniformuivRobust(programPacked, locationPacked, bufSize, length, params);
+ }
+ ANGLE_CAPTURE_GL(GetUniformuivRobustANGLE, isCallValid, context, programPacked,
+ locationPacked, bufSize, length, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetActiveUniformBlockivRobustANGLE(GLuint program,
+ GLuint uniformBlockIndex,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetActiveUniformBlockivRobustANGLE,
+ "context = %d, program = %u, uniformBlockIndex = %u, pname = %s, bufSize = %d, length = "
+ "0x%016" PRIxPTR ", params = 0x%016" PRIxPTR "",
+ CID(context), program, uniformBlockIndex, GLenumToString(GLESEnum::AllEnums, pname),
+ bufSize, (uintptr_t)length, (uintptr_t)params);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformBlockIndex uniformBlockIndexPacked = PackParam<UniformBlockIndex>(uniformBlockIndex);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetActiveUniformBlockivRobustANGLE(
+ context, angle::EntryPoint::GLGetActiveUniformBlockivRobustANGLE, programPacked,
+ uniformBlockIndexPacked, pname, bufSize, length, params));
+ if (isCallValid)
+ {
+ context->getActiveUniformBlockivRobust(programPacked, uniformBlockIndexPacked, pname,
+ bufSize, length, params);
+ }
+ ANGLE_CAPTURE_GL(GetActiveUniformBlockivRobustANGLE, isCallValid, context, programPacked,
+ uniformBlockIndexPacked, pname, bufSize, length, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetInteger64vRobustANGLE(GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint64 *data)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetInteger64vRobustANGLE,
+ "context = %d, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
+ ", data = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, pname), bufSize, (uintptr_t)length,
+ (uintptr_t)data);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetInteger64vRobustANGLE(
+ context, angle::EntryPoint::GLGetInteger64vRobustANGLE, pname,
+ bufSize, length, data));
+ if (isCallValid)
+ {
+ context->getInteger64vRobust(pname, bufSize, length, data);
+ }
+ ANGLE_CAPTURE_GL(GetInteger64vRobustANGLE, isCallValid, context, pname, bufSize, length,
+ data);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetInteger64i_vRobustANGLE(GLenum target,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint64 *data)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetInteger64i_vRobustANGLE,
+ "context = %d, target = %s, index = %u, bufSize = %d, length = 0x%016" PRIxPTR
+ ", data = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, target), index, bufSize,
+ (uintptr_t)length, (uintptr_t)data);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetInteger64i_vRobustANGLE(
+ context, angle::EntryPoint::GLGetInteger64i_vRobustANGLE, target,
+ index, bufSize, length, data));
+ if (isCallValid)
+ {
+ context->getInteger64i_vRobust(target, index, bufSize, length, data);
+ }
+ ANGLE_CAPTURE_GL(GetInteger64i_vRobustANGLE, isCallValid, context, target, index, bufSize,
+ length, data);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetBufferParameteri64vRobustANGLE(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint64 *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetBufferParameteri64vRobustANGLE,
+ "context = %d, target = %s, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
+ ", params = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, target),
+ GLenumToString(GLESEnum::AllEnums, pname), bufSize, (uintptr_t)length, (uintptr_t)params);
+
+ if (context)
+ {
+ BufferBinding targetPacked = PackParam<BufferBinding>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetBufferParameteri64vRobustANGLE(
+ context, angle::EntryPoint::GLGetBufferParameteri64vRobustANGLE,
+ targetPacked, pname, bufSize, length, params));
+ if (isCallValid)
+ {
+ context->getBufferParameteri64vRobust(targetPacked, pname, bufSize, length, params);
+ }
+ ANGLE_CAPTURE_GL(GetBufferParameteri64vRobustANGLE, isCallValid, context, targetPacked,
+ pname, bufSize, length, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_SamplerParameterivRobustANGLE(GLuint sampler,
+ GLuint pname,
+ GLsizei bufSize,
+ const GLint *param)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLSamplerParameterivRobustANGLE,
+ "context = %d, sampler = %u, pname = %u, bufSize = %d, param = 0x%016" PRIxPTR "",
+ CID(context), sampler, pname, bufSize, (uintptr_t)param);
+
+ if (context)
+ {
+ SamplerID samplerPacked = PackParam<SamplerID>(sampler);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateSamplerParameterivRobustANGLE(
+ context, angle::EntryPoint::GLSamplerParameterivRobustANGLE,
+ samplerPacked, pname, bufSize, param));
+ if (isCallValid)
+ {
+ context->samplerParameterivRobust(samplerPacked, pname, bufSize, param);
+ }
+ ANGLE_CAPTURE_GL(SamplerParameterivRobustANGLE, isCallValid, context, samplerPacked, pname,
+ bufSize, param);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_SamplerParameterfvRobustANGLE(GLuint sampler,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLfloat *param)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLSamplerParameterfvRobustANGLE,
+ "context = %d, sampler = %u, pname = %s, bufSize = %d, param = 0x%016" PRIxPTR "",
+ CID(context), sampler, GLenumToString(GLESEnum::AllEnums, pname), bufSize,
+ (uintptr_t)param);
+
+ if (context)
+ {
+ SamplerID samplerPacked = PackParam<SamplerID>(sampler);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateSamplerParameterfvRobustANGLE(
+ context, angle::EntryPoint::GLSamplerParameterfvRobustANGLE,
+ samplerPacked, pname, bufSize, param));
+ if (isCallValid)
+ {
+ context->samplerParameterfvRobust(samplerPacked, pname, bufSize, param);
+ }
+ ANGLE_CAPTURE_GL(SamplerParameterfvRobustANGLE, isCallValid, context, samplerPacked, pname,
+ bufSize, param);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetSamplerParameterivRobustANGLE(GLuint sampler,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetSamplerParameterivRobustANGLE,
+ "context = %d, sampler = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
+ ", params = 0x%016" PRIxPTR "",
+ CID(context), sampler, GLenumToString(GLESEnum::AllEnums, pname), bufSize,
+ (uintptr_t)length, (uintptr_t)params);
+
+ if (context)
+ {
+ SamplerID samplerPacked = PackParam<SamplerID>(sampler);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetSamplerParameterivRobustANGLE(
+ context, angle::EntryPoint::GLGetSamplerParameterivRobustANGLE,
+ samplerPacked, pname, bufSize, length, params));
+ if (isCallValid)
+ {
+ context->getSamplerParameterivRobust(samplerPacked, pname, bufSize, length, params);
+ }
+ ANGLE_CAPTURE_GL(GetSamplerParameterivRobustANGLE, isCallValid, context, samplerPacked,
+ pname, bufSize, length, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetSamplerParameterfvRobustANGLE(GLuint sampler,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetSamplerParameterfvRobustANGLE,
+ "context = %d, sampler = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
+ ", params = 0x%016" PRIxPTR "",
+ CID(context), sampler, GLenumToString(GLESEnum::AllEnums, pname), bufSize,
+ (uintptr_t)length, (uintptr_t)params);
+
+ if (context)
+ {
+ SamplerID samplerPacked = PackParam<SamplerID>(sampler);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetSamplerParameterfvRobustANGLE(
+ context, angle::EntryPoint::GLGetSamplerParameterfvRobustANGLE,
+ samplerPacked, pname, bufSize, length, params));
+ if (isCallValid)
+ {
+ context->getSamplerParameterfvRobust(samplerPacked, pname, bufSize, length, params);
+ }
+ ANGLE_CAPTURE_GL(GetSamplerParameterfvRobustANGLE, isCallValid, context, samplerPacked,
+ pname, bufSize, length, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetFramebufferParameterivRobustANGLE(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetFramebufferParameterivRobustANGLE,
+ "context = %d, target = %s, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
+ ", params = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, target),
+ GLenumToString(GLESEnum::AllEnums, pname), bufSize, (uintptr_t)length, (uintptr_t)params);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetFramebufferParameterivRobustANGLE(
+ context, angle::EntryPoint::GLGetFramebufferParameterivRobustANGLE,
+ target, pname, bufSize, length, params));
+ if (isCallValid)
+ {
+ context->getFramebufferParameterivRobust(target, pname, bufSize, length, params);
+ }
+ ANGLE_CAPTURE_GL(GetFramebufferParameterivRobustANGLE, isCallValid, context, target, pname,
+ bufSize, length, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetProgramInterfaceivRobustANGLE(GLuint program,
+ GLenum programInterface,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetProgramInterfaceivRobustANGLE,
+ "context = %d, program = %u, programInterface = %s, pname = %s, bufSize = %d, length = "
+ "0x%016" PRIxPTR ", params = 0x%016" PRIxPTR "",
+ CID(context), program, GLenumToString(GLESEnum::AllEnums, programInterface),
+ GLenumToString(GLESEnum::AllEnums, pname), bufSize, (uintptr_t)length, (uintptr_t)params);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetProgramInterfaceivRobustANGLE(
+ context, angle::EntryPoint::GLGetProgramInterfaceivRobustANGLE,
+ programPacked, programInterface, pname, bufSize, length, params));
+ if (isCallValid)
+ {
+ context->getProgramInterfaceivRobust(programPacked, programInterface, pname, bufSize,
+ length, params);
+ }
+ ANGLE_CAPTURE_GL(GetProgramInterfaceivRobustANGLE, isCallValid, context, programPacked,
+ programInterface, pname, bufSize, length, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetBooleani_vRobustANGLE(GLenum target,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLboolean *data)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetBooleani_vRobustANGLE,
+ "context = %d, target = %s, index = %u, bufSize = %d, length = 0x%016" PRIxPTR
+ ", data = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, target), index, bufSize,
+ (uintptr_t)length, (uintptr_t)data);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetBooleani_vRobustANGLE(
+ context, angle::EntryPoint::GLGetBooleani_vRobustANGLE, target,
+ index, bufSize, length, data));
+ if (isCallValid)
+ {
+ context->getBooleani_vRobust(target, index, bufSize, length, data);
+ }
+ ANGLE_CAPTURE_GL(GetBooleani_vRobustANGLE, isCallValid, context, target, index, bufSize,
+ length, data);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetMultisamplefvRobustANGLE(GLenum pname,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *val)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetMultisamplefvRobustANGLE,
+ "context = %d, pname = %s, index = %u, bufSize = %d, length = 0x%016" PRIxPTR
+ ", val = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, pname), index, bufSize,
+ (uintptr_t)length, (uintptr_t)val);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetMultisamplefvRobustANGLE(
+ context, angle::EntryPoint::GLGetMultisamplefvRobustANGLE, pname,
+ index, bufSize, length, val));
+ if (isCallValid)
+ {
+ context->getMultisamplefvRobust(pname, index, bufSize, length, val);
+ }
+ ANGLE_CAPTURE_GL(GetMultisamplefvRobustANGLE, isCallValid, context, pname, index, bufSize,
+ length, val);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetTexLevelParameterivRobustANGLE(GLenum target,
+ GLint level,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetTexLevelParameterivRobustANGLE,
+ "context = %d, target = %s, level = %d, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
+ ", params = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, target), level,
+ GLenumToString(GLESEnum::AllEnums, pname), bufSize, (uintptr_t)length, (uintptr_t)params);
+
+ if (context)
+ {
+ TextureTarget targetPacked = PackParam<TextureTarget>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetTexLevelParameterivRobustANGLE(
+ context, angle::EntryPoint::GLGetTexLevelParameterivRobustANGLE,
+ targetPacked, level, pname, bufSize, length, params));
+ if (isCallValid)
+ {
+ context->getTexLevelParameterivRobust(targetPacked, level, pname, bufSize, length,
+ params);
+ }
+ ANGLE_CAPTURE_GL(GetTexLevelParameterivRobustANGLE, isCallValid, context, targetPacked,
+ level, pname, bufSize, length, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetTexLevelParameterfvRobustANGLE(GLenum target,
+ GLint level,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetTexLevelParameterfvRobustANGLE,
+ "context = %d, target = %s, level = %d, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
+ ", params = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, target), level,
+ GLenumToString(GLESEnum::AllEnums, pname), bufSize, (uintptr_t)length, (uintptr_t)params);
+
+ if (context)
+ {
+ TextureTarget targetPacked = PackParam<TextureTarget>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetTexLevelParameterfvRobustANGLE(
+ context, angle::EntryPoint::GLGetTexLevelParameterfvRobustANGLE,
+ targetPacked, level, pname, bufSize, length, params));
+ if (isCallValid)
+ {
+ context->getTexLevelParameterfvRobust(targetPacked, level, pname, bufSize, length,
+ params);
+ }
+ ANGLE_CAPTURE_GL(GetTexLevelParameterfvRobustANGLE, isCallValid, context, targetPacked,
+ level, pname, bufSize, length, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetPointervRobustANGLERobustANGLE(GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ void **params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetPointervRobustANGLERobustANGLE,
+ "context = %d, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
+ ", params = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, pname), bufSize, (uintptr_t)length,
+ (uintptr_t)params);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetPointervRobustANGLERobustANGLE(
+ context, angle::EntryPoint::GLGetPointervRobustANGLERobustANGLE,
+ pname, bufSize, length, params));
+ if (isCallValid)
+ {
+ context->getPointervRobustANGLERobust(pname, bufSize, length, params);
+ }
+ ANGLE_CAPTURE_GL(GetPointervRobustANGLERobustANGLE, isCallValid, context, pname, bufSize,
+ length, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ReadnPixelsRobustANGLE(GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLsizei *columns,
+ GLsizei *rows,
+ void *data)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLReadnPixelsRobustANGLE,
+ "context = %d, x = %d, y = %d, width = %d, height = %d, format = %s, type = %s, bufSize "
+ "= %d, length = 0x%016" PRIxPTR ", columns = 0x%016" PRIxPTR ", rows = 0x%016" PRIxPTR
+ ", data = 0x%016" PRIxPTR "",
+ CID(context), x, y, width, height, GLenumToString(GLESEnum::AllEnums, format),
+ GLenumToString(GLESEnum::AllEnums, type), bufSize, (uintptr_t)length, (uintptr_t)columns,
+ (uintptr_t)rows, (uintptr_t)data);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateReadnPixelsRobustANGLE(
+ context, angle::EntryPoint::GLReadnPixelsRobustANGLE, x, y, width,
+ height, format, type, bufSize, length, columns, rows, data));
+ if (isCallValid)
+ {
+ context->readnPixelsRobust(x, y, width, height, format, type, bufSize, length, columns,
+ rows, data);
+ }
+ ANGLE_CAPTURE_GL(ReadnPixelsRobustANGLE, isCallValid, context, x, y, width, height, format,
+ type, bufSize, length, columns, rows, data);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetnUniformfvRobustANGLE(GLuint program,
+ GLint location,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetnUniformfvRobustANGLE,
+ "context = %d, program = %u, location = %d, bufSize = %d, length = 0x%016" PRIxPTR
+ ", params = 0x%016" PRIxPTR "",
+ CID(context), program, location, bufSize, (uintptr_t)length, (uintptr_t)params);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetnUniformfvRobustANGLE(
+ context, angle::EntryPoint::GLGetnUniformfvRobustANGLE,
+ programPacked, locationPacked, bufSize, length, params));
+ if (isCallValid)
+ {
+ context->getnUniformfvRobust(programPacked, locationPacked, bufSize, length, params);
+ }
+ ANGLE_CAPTURE_GL(GetnUniformfvRobustANGLE, isCallValid, context, programPacked,
+ locationPacked, bufSize, length, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetnUniformivRobustANGLE(GLuint program,
+ GLint location,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetnUniformivRobustANGLE,
+ "context = %d, program = %u, location = %d, bufSize = %d, length = 0x%016" PRIxPTR
+ ", params = 0x%016" PRIxPTR "",
+ CID(context), program, location, bufSize, (uintptr_t)length, (uintptr_t)params);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetnUniformivRobustANGLE(
+ context, angle::EntryPoint::GLGetnUniformivRobustANGLE,
+ programPacked, locationPacked, bufSize, length, params));
+ if (isCallValid)
+ {
+ context->getnUniformivRobust(programPacked, locationPacked, bufSize, length, params);
+ }
+ ANGLE_CAPTURE_GL(GetnUniformivRobustANGLE, isCallValid, context, programPacked,
+ locationPacked, bufSize, length, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetnUniformuivRobustANGLE(GLuint program,
+ GLint location,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetnUniformuivRobustANGLE,
+ "context = %d, program = %u, location = %d, bufSize = %d, length = 0x%016" PRIxPTR
+ ", params = 0x%016" PRIxPTR "",
+ CID(context), program, location, bufSize, (uintptr_t)length, (uintptr_t)params);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetnUniformuivRobustANGLE(
+ context, angle::EntryPoint::GLGetnUniformuivRobustANGLE,
+ programPacked, locationPacked, bufSize, length, params));
+ if (isCallValid)
+ {
+ context->getnUniformuivRobust(programPacked, locationPacked, bufSize, length, params);
+ }
+ ANGLE_CAPTURE_GL(GetnUniformuivRobustANGLE, isCallValid, context, programPacked,
+ locationPacked, bufSize, length, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexParameterIivRobustANGLE(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexParameterIivRobustANGLE,
+ "context = %d, target = %s, pname = %s, bufSize = %d, params = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, target),
+ GLenumToString(GLESEnum::AllEnums, pname), bufSize, (uintptr_t)params);
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateTexParameterIivRobustANGLE(
+ context, angle::EntryPoint::GLTexParameterIivRobustANGLE,
+ targetPacked, pname, bufSize, params));
+ if (isCallValid)
+ {
+ context->texParameterIivRobust(targetPacked, pname, bufSize, params);
+ }
+ ANGLE_CAPTURE_GL(TexParameterIivRobustANGLE, isCallValid, context, targetPacked, pname,
+ bufSize, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexParameterIuivRobustANGLE(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLuint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexParameterIuivRobustANGLE,
+ "context = %d, target = %s, pname = %s, bufSize = %d, params = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, target),
+ GLenumToString(GLESEnum::AllEnums, pname), bufSize, (uintptr_t)params);
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateTexParameterIuivRobustANGLE(
+ context, angle::EntryPoint::GLTexParameterIuivRobustANGLE,
+ targetPacked, pname, bufSize, params));
+ if (isCallValid)
+ {
+ context->texParameterIuivRobust(targetPacked, pname, bufSize, params);
+ }
+ ANGLE_CAPTURE_GL(TexParameterIuivRobustANGLE, isCallValid, context, targetPacked, pname,
+ bufSize, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetTexParameterIivRobustANGLE(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetTexParameterIivRobustANGLE,
+ "context = %d, target = %s, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
+ ", params = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, target),
+ GLenumToString(GLESEnum::AllEnums, pname), bufSize, (uintptr_t)length, (uintptr_t)params);
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetTexParameterIivRobustANGLE(
+ context, angle::EntryPoint::GLGetTexParameterIivRobustANGLE,
+ targetPacked, pname, bufSize, length, params));
+ if (isCallValid)
+ {
+ context->getTexParameterIivRobust(targetPacked, pname, bufSize, length, params);
+ }
+ ANGLE_CAPTURE_GL(GetTexParameterIivRobustANGLE, isCallValid, context, targetPacked, pname,
+ bufSize, length, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetTexParameterIuivRobustANGLE(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetTexParameterIuivRobustANGLE,
+ "context = %d, target = %s, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
+ ", params = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, target),
+ GLenumToString(GLESEnum::AllEnums, pname), bufSize, (uintptr_t)length, (uintptr_t)params);
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetTexParameterIuivRobustANGLE(
+ context, angle::EntryPoint::GLGetTexParameterIuivRobustANGLE,
+ targetPacked, pname, bufSize, length, params));
+ if (isCallValid)
+ {
+ context->getTexParameterIuivRobust(targetPacked, pname, bufSize, length, params);
+ }
+ ANGLE_CAPTURE_GL(GetTexParameterIuivRobustANGLE, isCallValid, context, targetPacked, pname,
+ bufSize, length, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_SamplerParameterIivRobustANGLE(GLuint sampler,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLint *param)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLSamplerParameterIivRobustANGLE,
+ "context = %d, sampler = %u, pname = %s, bufSize = %d, param = 0x%016" PRIxPTR "",
+ CID(context), sampler, GLenumToString(GLESEnum::AllEnums, pname), bufSize,
+ (uintptr_t)param);
+
+ if (context)
+ {
+ SamplerID samplerPacked = PackParam<SamplerID>(sampler);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateSamplerParameterIivRobustANGLE(
+ context, angle::EntryPoint::GLSamplerParameterIivRobustANGLE,
+ samplerPacked, pname, bufSize, param));
+ if (isCallValid)
+ {
+ context->samplerParameterIivRobust(samplerPacked, pname, bufSize, param);
+ }
+ ANGLE_CAPTURE_GL(SamplerParameterIivRobustANGLE, isCallValid, context, samplerPacked, pname,
+ bufSize, param);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_SamplerParameterIuivRobustANGLE(GLuint sampler,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLuint *param)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLSamplerParameterIuivRobustANGLE,
+ "context = %d, sampler = %u, pname = %s, bufSize = %d, param = 0x%016" PRIxPTR "",
+ CID(context), sampler, GLenumToString(GLESEnum::AllEnums, pname), bufSize,
+ (uintptr_t)param);
+
+ if (context)
+ {
+ SamplerID samplerPacked = PackParam<SamplerID>(sampler);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateSamplerParameterIuivRobustANGLE(
+ context, angle::EntryPoint::GLSamplerParameterIuivRobustANGLE,
+ samplerPacked, pname, bufSize, param));
+ if (isCallValid)
+ {
+ context->samplerParameterIuivRobust(samplerPacked, pname, bufSize, param);
+ }
+ ANGLE_CAPTURE_GL(SamplerParameterIuivRobustANGLE, isCallValid, context, samplerPacked,
+ pname, bufSize, param);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetSamplerParameterIivRobustANGLE(GLuint sampler,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetSamplerParameterIivRobustANGLE,
+ "context = %d, sampler = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
+ ", params = 0x%016" PRIxPTR "",
+ CID(context), sampler, GLenumToString(GLESEnum::AllEnums, pname), bufSize,
+ (uintptr_t)length, (uintptr_t)params);
+
+ if (context)
+ {
+ SamplerID samplerPacked = PackParam<SamplerID>(sampler);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetSamplerParameterIivRobustANGLE(
+ context, angle::EntryPoint::GLGetSamplerParameterIivRobustANGLE,
+ samplerPacked, pname, bufSize, length, params));
+ if (isCallValid)
+ {
+ context->getSamplerParameterIivRobust(samplerPacked, pname, bufSize, length, params);
+ }
+ ANGLE_CAPTURE_GL(GetSamplerParameterIivRobustANGLE, isCallValid, context, samplerPacked,
+ pname, bufSize, length, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetSamplerParameterIuivRobustANGLE(GLuint sampler,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetSamplerParameterIuivRobustANGLE,
+ "context = %d, sampler = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
+ ", params = 0x%016" PRIxPTR "",
+ CID(context), sampler, GLenumToString(GLESEnum::AllEnums, pname), bufSize,
+ (uintptr_t)length, (uintptr_t)params);
+
+ if (context)
+ {
+ SamplerID samplerPacked = PackParam<SamplerID>(sampler);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetSamplerParameterIuivRobustANGLE(
+ context, angle::EntryPoint::GLGetSamplerParameterIuivRobustANGLE,
+ samplerPacked, pname, bufSize, length, params));
+ if (isCallValid)
+ {
+ context->getSamplerParameterIuivRobust(samplerPacked, pname, bufSize, length, params);
+ }
+ ANGLE_CAPTURE_GL(GetSamplerParameterIuivRobustANGLE, isCallValid, context, samplerPacked,
+ pname, bufSize, length, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetQueryObjectivRobustANGLE(GLuint id,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ Context *context = GetGlobalContext();
+ EVENT(context, GLGetQueryObjectivRobustANGLE,
+ "context = %d, id = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
+ ", params = 0x%016" PRIxPTR "",
+ CID(context), id, GLenumToString(GLESEnum::AllEnums, pname), bufSize, (uintptr_t)length,
+ (uintptr_t)params);
+
+ if (context)
+ {
+ QueryID idPacked = PackParam<QueryID>(id);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetQueryObjectivRobustANGLE(
+ context, angle::EntryPoint::GLGetQueryObjectivRobustANGLE, idPacked,
+ pname, bufSize, length, params));
+ if (isCallValid)
+ {
+ context->getQueryObjectivRobust(idPacked, pname, bufSize, length, params);
+ }
+ ANGLE_CAPTURE_GL(GetQueryObjectivRobustANGLE, isCallValid, context, idPacked, pname,
+ bufSize, length, params);
+ }
+ else
+ {}
+}
+
+void GL_APIENTRY GL_GetQueryObjecti64vRobustANGLE(GLuint id,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint64 *params)
+{
+ Context *context = GetGlobalContext();
+ EVENT(context, GLGetQueryObjecti64vRobustANGLE,
+ "context = %d, id = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
+ ", params = 0x%016" PRIxPTR "",
+ CID(context), id, GLenumToString(GLESEnum::AllEnums, pname), bufSize, (uintptr_t)length,
+ (uintptr_t)params);
+
+ if (context)
+ {
+ QueryID idPacked = PackParam<QueryID>(id);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetQueryObjecti64vRobustANGLE(
+ context, angle::EntryPoint::GLGetQueryObjecti64vRobustANGLE,
+ idPacked, pname, bufSize, length, params));
+ if (isCallValid)
+ {
+ context->getQueryObjecti64vRobust(idPacked, pname, bufSize, length, params);
+ }
+ ANGLE_CAPTURE_GL(GetQueryObjecti64vRobustANGLE, isCallValid, context, idPacked, pname,
+ bufSize, length, params);
+ }
+ else
+ {}
+}
+
+void GL_APIENTRY GL_GetQueryObjectui64vRobustANGLE(GLuint id,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint64 *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetQueryObjectui64vRobustANGLE,
+ "context = %d, id = %u, pname = %s, bufSize = %d, length = 0x%016" PRIxPTR
+ ", params = 0x%016" PRIxPTR "",
+ CID(context), id, GLenumToString(GLESEnum::AllEnums, pname), bufSize, (uintptr_t)length,
+ (uintptr_t)params);
+
+ if (context)
+ {
+ QueryID idPacked = PackParam<QueryID>(id);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetQueryObjectui64vRobustANGLE(
+ context, angle::EntryPoint::GLGetQueryObjectui64vRobustANGLE,
+ idPacked, pname, bufSize, length, params));
+ if (isCallValid)
+ {
+ context->getQueryObjectui64vRobust(idPacked, pname, bufSize, length, params);
+ }
+ ANGLE_CAPTURE_GL(GetQueryObjectui64vRobustANGLE, isCallValid, context, idPacked, pname,
+ bufSize, length, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_ANGLE_robust_resource_initialization
+
+// GL_ANGLE_semaphore_fuchsia
+void GL_APIENTRY GL_ImportSemaphoreZirconHandleANGLE(GLuint semaphore,
+ GLenum handleType,
+ GLuint handle)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLImportSemaphoreZirconHandleANGLE,
+ "context = %d, semaphore = %u, handleType = %s, handle = %u", CID(context), semaphore,
+ GLenumToString(GLESEnum::ExternalHandleType, handleType), handle);
+
+ if (context)
+ {
+ SemaphoreID semaphorePacked = PackParam<SemaphoreID>(semaphore);
+ HandleType handleTypePacked = PackParam<HandleType>(handleType);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateImportSemaphoreZirconHandleANGLE(
+ context, angle::EntryPoint::GLImportSemaphoreZirconHandleANGLE,
+ semaphorePacked, handleTypePacked, handle));
+ if (isCallValid)
+ {
+ context->importSemaphoreZirconHandle(semaphorePacked, handleTypePacked, handle);
+ }
+ ANGLE_CAPTURE_GL(ImportSemaphoreZirconHandleANGLE, isCallValid, context, semaphorePacked,
+ handleTypePacked, handle);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_ANGLE_shader_pixel_local_storage
+void GL_APIENTRY GL_FramebufferMemorylessPixelLocalStorageANGLE(GLint plane, GLenum internalformat)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLFramebufferMemorylessPixelLocalStorageANGLE,
+ "context = %d, plane = %d, internalformat = %s", CID(context), plane,
+ GLenumToString(GLESEnum::AllEnums, internalformat));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateFramebufferMemorylessPixelLocalStorageANGLE(
+ context, angle::EntryPoint::GLFramebufferMemorylessPixelLocalStorageANGLE, plane,
+ internalformat));
+ if (isCallValid)
+ {
+ context->framebufferMemorylessPixelLocalStorage(plane, internalformat);
+ }
+ ANGLE_CAPTURE_GL(FramebufferMemorylessPixelLocalStorageANGLE, isCallValid, context, plane,
+ internalformat);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_FramebufferTexturePixelLocalStorageANGLE(GLint plane,
+ GLuint backingtexture,
+ GLint level,
+ GLint layer)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLFramebufferTexturePixelLocalStorageANGLE,
+ "context = %d, plane = %d, backingtexture = %u, level = %d, layer = %d", CID(context),
+ plane, backingtexture, level, layer);
+
+ if (context)
+ {
+ TextureID backingtexturePacked = PackParam<TextureID>(backingtexture);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateFramebufferTexturePixelLocalStorageANGLE(
+ context, angle::EntryPoint::GLFramebufferTexturePixelLocalStorageANGLE, plane,
+ backingtexturePacked, level, layer));
+ if (isCallValid)
+ {
+ context->framebufferTexturePixelLocalStorage(plane, backingtexturePacked, level, layer);
+ }
+ ANGLE_CAPTURE_GL(FramebufferTexturePixelLocalStorageANGLE, isCallValid, context, plane,
+ backingtexturePacked, level, layer);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_BeginPixelLocalStorageANGLE(GLsizei planes,
+ const GLenum *loadops,
+ const void *cleardata)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBeginPixelLocalStorageANGLE,
+ "context = %d, planes = %d, loadops = 0x%016" PRIxPTR ", cleardata = 0x%016" PRIxPTR "",
+ CID(context), planes, (uintptr_t)loadops, (uintptr_t)cleardata);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateBeginPixelLocalStorageANGLE(
+ context, angle::EntryPoint::GLBeginPixelLocalStorageANGLE, planes,
+ loadops, cleardata));
+ if (isCallValid)
+ {
+ context->beginPixelLocalStorage(planes, loadops, cleardata);
+ }
+ ANGLE_CAPTURE_GL(BeginPixelLocalStorageANGLE, isCallValid, context, planes, loadops,
+ cleardata);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_EndPixelLocalStorageANGLE()
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLEndPixelLocalStorageANGLE, "context = %d", CID(context));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateEndPixelLocalStorageANGLE(
+ context, angle::EntryPoint::GLEndPixelLocalStorageANGLE));
+ if (isCallValid)
+ {
+ context->endPixelLocalStorage();
+ }
+ ANGLE_CAPTURE_GL(EndPixelLocalStorageANGLE, isCallValid, context);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_PixelLocalStorageBarrierANGLE()
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLPixelLocalStorageBarrierANGLE, "context = %d", CID(context));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidatePixelLocalStorageBarrierANGLE(
+ context, angle::EntryPoint::GLPixelLocalStorageBarrierANGLE));
+ if (isCallValid)
+ {
+ context->pixelLocalStorageBarrier();
+ }
+ ANGLE_CAPTURE_GL(PixelLocalStorageBarrierANGLE, isCallValid, context);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_ANGLE_texture_compression_dxt3
+
+// GL_ANGLE_texture_compression_dxt5
+
+// GL_ANGLE_texture_external_update
+void GL_APIENTRY GL_TexImage2DExternalANGLE(GLenum target,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLenum format,
+ GLenum type)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexImage2DExternalANGLE,
+ "context = %d, target = %s, level = %d, internalformat = %d, width = %d, height = %d, "
+ "border = %d, format = %s, type = %s",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target), level, internalformat,
+ width, height, border, GLenumToString(GLESEnum::PixelFormat, format),
+ GLenumToString(GLESEnum::PixelType, type));
+
+ if (context)
+ {
+ TextureTarget targetPacked = PackParam<TextureTarget>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateTexImage2DExternalANGLE(
+ context, angle::EntryPoint::GLTexImage2DExternalANGLE, targetPacked,
+ level, internalformat, width, height, border, format, type));
+ if (isCallValid)
+ {
+ context->texImage2DExternal(targetPacked, level, internalformat, width, height, border,
+ format, type);
+ }
+ ANGLE_CAPTURE_GL(TexImage2DExternalANGLE, isCallValid, context, targetPacked, level,
+ internalformat, width, height, border, format, type);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_InvalidateTextureANGLE(GLenum target)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLInvalidateTextureANGLE, "context = %d, target = %s", CID(context),
+ GLenumToString(GLESEnum::TextureTarget, target));
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateInvalidateTextureANGLE(context, angle::EntryPoint::GLInvalidateTextureANGLE,
+ targetPacked));
+ if (isCallValid)
+ {
+ context->invalidateTexture(targetPacked);
+ }
+ ANGLE_CAPTURE_GL(InvalidateTextureANGLE, isCallValid, context, targetPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_ANGLE_texture_multisample
+void GL_APIENTRY GL_TexStorage2DMultisampleANGLE(GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedsamplelocations)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexStorage2DMultisampleANGLE,
+ "context = %d, target = %s, samples = %d, internalformat = %s, width = %d, height = %d, "
+ "fixedsamplelocations = %s",
+ CID(context), GLenumToString(GLESEnum::AllEnums, target), samples,
+ GLenumToString(GLESEnum::AllEnums, internalformat), width, height,
+ GLbooleanToString(fixedsamplelocations));
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateTexStorage2DMultisampleANGLE(
+ context, angle::EntryPoint::GLTexStorage2DMultisampleANGLE, targetPacked, samples,
+ internalformat, width, height, fixedsamplelocations));
+ if (isCallValid)
+ {
+ context->texStorage2DMultisample(targetPacked, samples, internalformat, width, height,
+ fixedsamplelocations);
+ }
+ ANGLE_CAPTURE_GL(TexStorage2DMultisampleANGLE, isCallValid, context, targetPacked, samples,
+ internalformat, width, height, fixedsamplelocations);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetMultisamplefvANGLE(GLenum pname, GLuint index, GLfloat *val)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetMultisamplefvANGLE,
+ "context = %d, pname = %s, index = %u, val = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::AllEnums, pname), index, (uintptr_t)val);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetMultisamplefvANGLE(context, angle::EntryPoint::GLGetMultisamplefvANGLE,
+ pname, index, val));
+ if (isCallValid)
+ {
+ context->getMultisamplefv(pname, index, val);
+ }
+ ANGLE_CAPTURE_GL(GetMultisamplefvANGLE, isCallValid, context, pname, index, val);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_SampleMaskiANGLE(GLuint maskNumber, GLbitfield mask)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLSampleMaskiANGLE, "context = %d, maskNumber = %u, mask = %s", CID(context),
+ maskNumber, GLbitfieldToString(GLESEnum::AllEnums, mask).c_str());
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateSampleMaskiANGLE(context, angle::EntryPoint::GLSampleMaskiANGLE,
+ maskNumber, mask));
+ if (isCallValid)
+ {
+ context->sampleMaski(maskNumber, mask);
+ }
+ ANGLE_CAPTURE_GL(SampleMaskiANGLE, isCallValid, context, maskNumber, mask);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GetTexLevelParameterfvANGLE is already defined.
+
+// GetTexLevelParameterivANGLE is already defined.
+
+// GL_ANGLE_texture_usage
+
+// GL_ANGLE_translated_shader_source
+void GL_APIENTRY GL_GetTranslatedShaderSourceANGLE(GLuint shader,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *source)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetTranslatedShaderSourceANGLE,
+ "context = %d, shader = %u, bufSize = %d, length = 0x%016" PRIxPTR
+ ", source = 0x%016" PRIxPTR "",
+ CID(context), shader, bufSize, (uintptr_t)length, (uintptr_t)source);
+
+ if (context)
+ {
+ ShaderProgramID shaderPacked = PackParam<ShaderProgramID>(shader);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetTranslatedShaderSourceANGLE(
+ context, angle::EntryPoint::GLGetTranslatedShaderSourceANGLE,
+ shaderPacked, bufSize, length, source));
+ if (isCallValid)
+ {
+ context->getTranslatedShaderSource(shaderPacked, bufSize, length, source);
+ }
+ ANGLE_CAPTURE_GL(GetTranslatedShaderSourceANGLE, isCallValid, context, shaderPacked,
+ bufSize, length, source);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_ANGLE_vulkan_image
+void GL_APIENTRY GL_AcquireTexturesANGLE(GLuint numTextures,
+ const GLuint *textures,
+ const GLenum *layouts)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLAcquireTexturesANGLE,
+ "context = %d, numTextures = %u, textures = 0x%016" PRIxPTR ", layouts = 0x%016" PRIxPTR
+ "",
+ CID(context), numTextures, (uintptr_t)textures, (uintptr_t)layouts);
+
+ if (context)
+ {
+ const TextureID *texturesPacked = PackParam<const TextureID *>(textures);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateAcquireTexturesANGLE(context, angle::EntryPoint::GLAcquireTexturesANGLE,
+ numTextures, texturesPacked, layouts));
+ if (isCallValid)
+ {
+ context->acquireTextures(numTextures, texturesPacked, layouts);
+ }
+ ANGLE_CAPTURE_GL(AcquireTexturesANGLE, isCallValid, context, numTextures, texturesPacked,
+ layouts);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ReleaseTexturesANGLE(GLuint numTextures,
+ const GLuint *textures,
+ GLenum *layouts)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLReleaseTexturesANGLE,
+ "context = %d, numTextures = %u, textures = 0x%016" PRIxPTR ", layouts = 0x%016" PRIxPTR
+ "",
+ CID(context), numTextures, (uintptr_t)textures, (uintptr_t)layouts);
+
+ if (context)
+ {
+ const TextureID *texturesPacked = PackParam<const TextureID *>(textures);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateReleaseTexturesANGLE(context, angle::EntryPoint::GLReleaseTexturesANGLE,
+ numTextures, texturesPacked, layouts));
+ if (isCallValid)
+ {
+ context->releaseTextures(numTextures, texturesPacked, layouts);
+ }
+ ANGLE_CAPTURE_GL(ReleaseTexturesANGLE, isCallValid, context, numTextures, texturesPacked,
+ layouts);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_APPLE_clip_distance
+
+// GL_ARB_sync
+// ClientWaitSync is already defined.
+
+// DeleteSync is already defined.
+
+// FenceSync is already defined.
+
+// GetInteger64v is already defined.
+
+// GetSynciv is already defined.
+
+// IsSync is already defined.
+
+// WaitSync is already defined.
+
+// GL_CHROMIUM_bind_uniform_location
+void GL_APIENTRY GL_BindUniformLocationCHROMIUM(GLuint program, GLint location, const GLchar *name)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBindUniformLocationCHROMIUM,
+ "context = %d, program = %u, location = %d, name = 0x%016" PRIxPTR "", CID(context),
+ program, location, (uintptr_t)name);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateBindUniformLocationCHROMIUM(
+ context, angle::EntryPoint::GLBindUniformLocationCHROMIUM,
+ programPacked, locationPacked, name));
+ if (isCallValid)
+ {
+ context->bindUniformLocation(programPacked, locationPacked, name);
+ }
+ ANGLE_CAPTURE_GL(BindUniformLocationCHROMIUM, isCallValid, context, programPacked,
+ locationPacked, name);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_CHROMIUM_copy_compressed_texture
+void GL_APIENTRY GL_CompressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLCompressedCopyTextureCHROMIUM, "context = %d, sourceId = %u, destId = %u",
+ CID(context), sourceId, destId);
+
+ if (context)
+ {
+ TextureID sourceIdPacked = PackParam<TextureID>(sourceId);
+ TextureID destIdPacked = PackParam<TextureID>(destId);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateCompressedCopyTextureCHROMIUM(
+ context, angle::EntryPoint::GLCompressedCopyTextureCHROMIUM,
+ sourceIdPacked, destIdPacked));
+ if (isCallValid)
+ {
+ context->compressedCopyTexture(sourceIdPacked, destIdPacked);
+ }
+ ANGLE_CAPTURE_GL(CompressedCopyTextureCHROMIUM, isCallValid, context, sourceIdPacked,
+ destIdPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_CHROMIUM_copy_texture
+void GL_APIENTRY GL_CopyTextureCHROMIUM(GLuint sourceId,
+ GLint sourceLevel,
+ GLenum destTarget,
+ GLuint destId,
+ GLint destLevel,
+ GLint internalFormat,
+ GLenum destType,
+ GLboolean unpackFlipY,
+ GLboolean unpackPremultiplyAlpha,
+ GLboolean unpackUnmultiplyAlpha)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLCopyTextureCHROMIUM,
+ "context = %d, sourceId = %u, sourceLevel = %d, destTarget = %s, destId = %u, destLevel "
+ "= %d, internalFormat = %d, destType = %s, unpackFlipY = %s, unpackPremultiplyAlpha = "
+ "%s, unpackUnmultiplyAlpha = %s",
+ CID(context), sourceId, sourceLevel, GLenumToString(GLESEnum::AllEnums, destTarget),
+ destId, destLevel, internalFormat, GLenumToString(GLESEnum::AllEnums, destType),
+ GLbooleanToString(unpackFlipY), GLbooleanToString(unpackPremultiplyAlpha),
+ GLbooleanToString(unpackUnmultiplyAlpha));
+
+ if (context)
+ {
+ TextureID sourceIdPacked = PackParam<TextureID>(sourceId);
+ TextureTarget destTargetPacked = PackParam<TextureTarget>(destTarget);
+ TextureID destIdPacked = PackParam<TextureID>(destId);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateCopyTextureCHROMIUM(
+ context, angle::EntryPoint::GLCopyTextureCHROMIUM, sourceIdPacked, sourceLevel,
+ destTargetPacked, destIdPacked, destLevel, internalFormat, destType, unpackFlipY,
+ unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
+ if (isCallValid)
+ {
+ context->copyTexture(sourceIdPacked, sourceLevel, destTargetPacked, destIdPacked,
+ destLevel, internalFormat, destType, unpackFlipY,
+ unpackPremultiplyAlpha, unpackUnmultiplyAlpha);
+ }
+ ANGLE_CAPTURE_GL(CopyTextureCHROMIUM, isCallValid, context, sourceIdPacked, sourceLevel,
+ destTargetPacked, destIdPacked, destLevel, internalFormat, destType,
+ unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_CopySubTextureCHROMIUM(GLuint sourceId,
+ GLint sourceLevel,
+ GLenum destTarget,
+ GLuint destId,
+ GLint destLevel,
+ GLint xoffset,
+ GLint yoffset,
+ GLint x,
+ GLint y,
+ GLint width,
+ GLint height,
+ GLboolean unpackFlipY,
+ GLboolean unpackPremultiplyAlpha,
+ GLboolean unpackUnmultiplyAlpha)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLCopySubTextureCHROMIUM,
+ "context = %d, sourceId = %u, sourceLevel = %d, destTarget = %s, destId = %u, destLevel "
+ "= %d, xoffset = %d, yoffset = %d, x = %d, y = %d, width = %d, height = %d, unpackFlipY "
+ "= %s, unpackPremultiplyAlpha = %s, unpackUnmultiplyAlpha = %s",
+ CID(context), sourceId, sourceLevel, GLenumToString(GLESEnum::AllEnums, destTarget),
+ destId, destLevel, xoffset, yoffset, x, y, width, height, GLbooleanToString(unpackFlipY),
+ GLbooleanToString(unpackPremultiplyAlpha), GLbooleanToString(unpackUnmultiplyAlpha));
+
+ if (context)
+ {
+ TextureID sourceIdPacked = PackParam<TextureID>(sourceId);
+ TextureTarget destTargetPacked = PackParam<TextureTarget>(destTarget);
+ TextureID destIdPacked = PackParam<TextureID>(destId);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateCopySubTextureCHROMIUM(
+ context, angle::EntryPoint::GLCopySubTextureCHROMIUM, sourceIdPacked, sourceLevel,
+ destTargetPacked, destIdPacked, destLevel, xoffset, yoffset, x, y, width, height,
+ unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha));
+ if (isCallValid)
+ {
+ context->copySubTexture(sourceIdPacked, sourceLevel, destTargetPacked, destIdPacked,
+ destLevel, xoffset, yoffset, x, y, width, height, unpackFlipY,
+ unpackPremultiplyAlpha, unpackUnmultiplyAlpha);
+ }
+ ANGLE_CAPTURE_GL(CopySubTextureCHROMIUM, isCallValid, context, sourceIdPacked, sourceLevel,
+ destTargetPacked, destIdPacked, destLevel, xoffset, yoffset, x, y, width,
+ height, unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_CHROMIUM_framebuffer_mixed_samples
+void GL_APIENTRY GL_CoverageModulationCHROMIUM(GLenum components)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLCoverageModulationCHROMIUM, "context = %d, components = %s", CID(context),
+ GLenumToString(GLESEnum::AllEnums, components));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateCoverageModulationCHROMIUM(
+ context, angle::EntryPoint::GLCoverageModulationCHROMIUM, components));
+ if (isCallValid)
+ {
+ context->coverageModulation(components);
+ }
+ ANGLE_CAPTURE_GL(CoverageModulationCHROMIUM, isCallValid, context, components);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_CHROMIUM_lose_context
+void GL_APIENTRY GL_LoseContextCHROMIUM(GLenum current, GLenum other)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLLoseContextCHROMIUM, "context = %d, current = %s, other = %s", CID(context),
+ GLenumToString(GLESEnum::GraphicsResetStatus, current),
+ GLenumToString(GLESEnum::GraphicsResetStatus, other));
+
+ if (context)
+ {
+ GraphicsResetStatus currentPacked = PackParam<GraphicsResetStatus>(current);
+ GraphicsResetStatus otherPacked = PackParam<GraphicsResetStatus>(other);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateLoseContextCHROMIUM(context, angle::EntryPoint::GLLoseContextCHROMIUM,
+ currentPacked, otherPacked));
+ if (isCallValid)
+ {
+ context->loseContext(currentPacked, otherPacked);
+ }
+ ANGLE_CAPTURE_GL(LoseContextCHROMIUM, isCallValid, context, currentPacked, otherPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_EXT_EGL_image_array
+
+// GL_EXT_EGL_image_storage
+void GL_APIENTRY GL_EGLImageTargetTexStorageEXT(GLenum target,
+ GLeglImageOES image,
+ const GLint *attrib_list)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLEGLImageTargetTexStorageEXT,
+ "context = %d, target = %s, image = 0x%016" PRIxPTR ", attrib_list = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, target), (uintptr_t)image,
+ (uintptr_t)attrib_list);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateEGLImageTargetTexStorageEXT(
+ context, angle::EntryPoint::GLEGLImageTargetTexStorageEXT, target,
+ image, attrib_list));
+ if (isCallValid)
+ {
+ context->eGLImageTargetTexStorage(target, image, attrib_list);
+ }
+ ANGLE_CAPTURE_GL(EGLImageTargetTexStorageEXT, isCallValid, context, target, image,
+ attrib_list);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_EGLImageTargetTextureStorageEXT(GLuint texture,
+ GLeglImageOES image,
+ const GLint *attrib_list)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLEGLImageTargetTextureStorageEXT,
+ "context = %d, texture = %u, image = 0x%016" PRIxPTR ", attrib_list = 0x%016" PRIxPTR "",
+ CID(context), texture, (uintptr_t)image, (uintptr_t)attrib_list);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateEGLImageTargetTextureStorageEXT(
+ context, angle::EntryPoint::GLEGLImageTargetTextureStorageEXT,
+ texture, image, attrib_list));
+ if (isCallValid)
+ {
+ context->eGLImageTargetTextureStorage(texture, image, attrib_list);
+ }
+ ANGLE_CAPTURE_GL(EGLImageTargetTextureStorageEXT, isCallValid, context, texture, image,
+ attrib_list);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_EXT_YUV_target
+
+// GL_EXT_base_instance
+void GL_APIENTRY GL_DrawArraysInstancedBaseInstanceEXT(GLenum mode,
+ GLint first,
+ GLsizei count,
+ GLsizei instancecount,
+ GLuint baseinstance)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDrawArraysInstancedBaseInstanceEXT,
+ "context = %d, mode = %s, first = %d, count = %d, instancecount = %d, baseinstance = %u",
+ CID(context), GLenumToString(GLESEnum::PrimitiveType, mode), first, count, instancecount,
+ baseinstance);
+
+ if (context)
+ {
+ PrimitiveMode modePacked = PackParam<PrimitiveMode>(mode);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateDrawArraysInstancedBaseInstanceEXT(
+ context, angle::EntryPoint::GLDrawArraysInstancedBaseInstanceEXT,
+ modePacked, first, count, instancecount, baseinstance));
+ if (isCallValid)
+ {
+ context->drawArraysInstancedBaseInstance(modePacked, first, count, instancecount,
+ baseinstance);
+ }
+ ANGLE_CAPTURE_GL(DrawArraysInstancedBaseInstanceEXT, isCallValid, context, modePacked,
+ first, count, instancecount, baseinstance);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DrawElementsInstancedBaseInstanceEXT(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLsizei instancecount,
+ GLuint baseinstance)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDrawElementsInstancedBaseInstanceEXT,
+ "context = %d, mode = %s, count = %d, type = %s, indices = 0x%016" PRIxPTR
+ ", instancecount = %d, baseinstance = %u",
+ CID(context), GLenumToString(GLESEnum::PrimitiveType, mode), count,
+ GLenumToString(GLESEnum::PrimitiveType, type), (uintptr_t)indices, instancecount,
+ baseinstance);
+
+ if (context)
+ {
+ PrimitiveMode modePacked = PackParam<PrimitiveMode>(mode);
+ DrawElementsType typePacked = PackParam<DrawElementsType>(type);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateDrawElementsInstancedBaseInstanceEXT(
+ context, angle::EntryPoint::GLDrawElementsInstancedBaseInstanceEXT, modePacked,
+ count, typePacked, indices, instancecount, baseinstance));
+ if (isCallValid)
+ {
+ context->drawElementsInstancedBaseInstance(modePacked, count, typePacked, indices,
+ instancecount, baseinstance);
+ }
+ ANGLE_CAPTURE_GL(DrawElementsInstancedBaseInstanceEXT, isCallValid, context, modePacked,
+ count, typePacked, indices, instancecount, baseinstance);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DrawElementsInstancedBaseVertexBaseInstanceEXT(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLsizei instancecount,
+ GLint basevertex,
+ GLuint baseinstance)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDrawElementsInstancedBaseVertexBaseInstanceEXT,
+ "context = %d, mode = %s, count = %d, type = %s, indices = 0x%016" PRIxPTR
+ ", instancecount = %d, basevertex = %d, baseinstance = %u",
+ CID(context), GLenumToString(GLESEnum::PrimitiveType, mode), count,
+ GLenumToString(GLESEnum::DrawElementsType, type), (uintptr_t)indices, instancecount,
+ basevertex, baseinstance);
+
+ if (context)
+ {
+ PrimitiveMode modePacked = PackParam<PrimitiveMode>(mode);
+ DrawElementsType typePacked = PackParam<DrawElementsType>(type);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateDrawElementsInstancedBaseVertexBaseInstanceEXT(
+ context, angle::EntryPoint::GLDrawElementsInstancedBaseVertexBaseInstanceEXT,
+ modePacked, count, typePacked, indices, instancecount, basevertex, baseinstance));
+ if (isCallValid)
+ {
+ context->drawElementsInstancedBaseVertexBaseInstance(
+ modePacked, count, typePacked, indices, instancecount, basevertex, baseinstance);
+ }
+ ANGLE_CAPTURE_GL(DrawElementsInstancedBaseVertexBaseInstanceEXT, isCallValid, context,
+ modePacked, count, typePacked, indices, instancecount, basevertex,
+ baseinstance);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_EXT_blend_func_extended
+void GL_APIENTRY GL_BindFragDataLocationEXT(GLuint program, GLuint color, const GLchar *name)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBindFragDataLocationEXT,
+ "context = %d, program = %u, color = %u, name = 0x%016" PRIxPTR "", CID(context), program,
+ color, (uintptr_t)name);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateBindFragDataLocationEXT(context, angle::EntryPoint::GLBindFragDataLocationEXT,
+ programPacked, color, name));
+ if (isCallValid)
+ {
+ context->bindFragDataLocation(programPacked, color, name);
+ }
+ ANGLE_CAPTURE_GL(BindFragDataLocationEXT, isCallValid, context, programPacked, color, name);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_BindFragDataLocationIndexedEXT(GLuint program,
+ GLuint colorNumber,
+ GLuint index,
+ const GLchar *name)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBindFragDataLocationIndexedEXT,
+ "context = %d, program = %u, colorNumber = %u, index = %u, name = 0x%016" PRIxPTR "",
+ CID(context), program, colorNumber, index, (uintptr_t)name);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateBindFragDataLocationIndexedEXT(
+ context, angle::EntryPoint::GLBindFragDataLocationIndexedEXT,
+ programPacked, colorNumber, index, name));
+ if (isCallValid)
+ {
+ context->bindFragDataLocationIndexed(programPacked, colorNumber, index, name);
+ }
+ ANGLE_CAPTURE_GL(BindFragDataLocationIndexedEXT, isCallValid, context, programPacked,
+ colorNumber, index, name);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+GLint GL_APIENTRY GL_GetFragDataIndexEXT(GLuint program, const GLchar *name)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetFragDataIndexEXT, "context = %d, program = %u, name = 0x%016" PRIxPTR "",
+ CID(context), program, (uintptr_t)name);
+
+ GLint returnValue;
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetFragDataIndexEXT(context, angle::EntryPoint::GLGetFragDataIndexEXT,
+ programPacked, name));
+ if (isCallValid)
+ {
+ returnValue = context->getFragDataIndex(programPacked, name);
+ }
+ else
+ {
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLGetFragDataIndexEXT, GLint>();
+ }
+ ANGLE_CAPTURE_GL(GetFragDataIndexEXT, isCallValid, context, programPacked, name,
+ returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLGetFragDataIndexEXT, GLint>();
+ }
+ return returnValue;
+}
+
+GLint GL_APIENTRY GL_GetProgramResourceLocationIndexEXT(GLuint program,
+ GLenum programInterface,
+ const GLchar *name)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetProgramResourceLocationIndexEXT,
+ "context = %d, program = %u, programInterface = %s, name = 0x%016" PRIxPTR "",
+ CID(context), program, GLenumToString(GLESEnum::ProgramInterface, programInterface),
+ (uintptr_t)name);
+
+ GLint returnValue;
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetProgramResourceLocationIndexEXT(
+ context, angle::EntryPoint::GLGetProgramResourceLocationIndexEXT,
+ programPacked, programInterface, name));
+ if (isCallValid)
+ {
+ returnValue =
+ context->getProgramResourceLocationIndex(programPacked, programInterface, name);
+ }
+ else
+ {
+ returnValue =
+ GetDefaultReturnValue<angle::EntryPoint::GLGetProgramResourceLocationIndexEXT,
+ GLint>();
+ }
+ ANGLE_CAPTURE_GL(GetProgramResourceLocationIndexEXT, isCallValid, context, programPacked,
+ programInterface, name, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue =
+ GetDefaultReturnValue<angle::EntryPoint::GLGetProgramResourceLocationIndexEXT, GLint>();
+ }
+ return returnValue;
+}
+
+// GL_EXT_blend_minmax
+
+// GL_EXT_buffer_storage
+void GL_APIENTRY GL_BufferStorageEXT(GLenum target,
+ GLsizeiptr size,
+ const void *data,
+ GLbitfield flags)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBufferStorageEXT,
+ "context = %d, target = %s, size = %llu, data = 0x%016" PRIxPTR ", flags = %s",
+ CID(context), GLenumToString(GLESEnum::BufferStorageTarget, target),
+ static_cast<unsigned long long>(size), (uintptr_t)data,
+ GLbitfieldToString(GLESEnum::BufferStorageMask, flags).c_str());
+
+ if (context)
+ {
+ BufferBinding targetPacked = PackParam<BufferBinding>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateBufferStorageEXT(context, angle::EntryPoint::GLBufferStorageEXT,
+ targetPacked, size, data, flags));
+ if (isCallValid)
+ {
+ context->bufferStorage(targetPacked, size, data, flags);
+ }
+ ANGLE_CAPTURE_GL(BufferStorageEXT, isCallValid, context, targetPacked, size, data, flags);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_EXT_clip_control
+void GL_APIENTRY GL_ClipControlEXT(GLenum origin, GLenum depth)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLClipControlEXT, "context = %d, origin = %s, depth = %s", CID(context),
+ GLenumToString(GLESEnum::AllEnums, origin), GLenumToString(GLESEnum::AllEnums, depth));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateClipControlEXT(context, angle::EntryPoint::GLClipControlEXT, origin, depth));
+ if (isCallValid)
+ {
+ context->clipControl(origin, depth);
+ }
+ ANGLE_CAPTURE_GL(ClipControlEXT, isCallValid, context, origin, depth);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_EXT_clip_cull_distance
+
+// GL_EXT_color_buffer_float
+
+// GL_EXT_color_buffer_half_float
+
+// GL_EXT_copy_image
+void GL_APIENTRY GL_CopyImageSubDataEXT(GLuint srcName,
+ GLenum srcTarget,
+ GLint srcLevel,
+ GLint srcX,
+ GLint srcY,
+ GLint srcZ,
+ GLuint dstName,
+ GLenum dstTarget,
+ GLint dstLevel,
+ GLint dstX,
+ GLint dstY,
+ GLint dstZ,
+ GLsizei srcWidth,
+ GLsizei srcHeight,
+ GLsizei srcDepth)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLCopyImageSubDataEXT,
+ "context = %d, srcName = %u, srcTarget = %s, srcLevel = %d, srcX = %d, srcY = %d, srcZ = "
+ "%d, dstName = %u, dstTarget = %s, dstLevel = %d, dstX = %d, dstY = %d, dstZ = %d, "
+ "srcWidth = %d, srcHeight = %d, srcDepth = %d",
+ CID(context), srcName, GLenumToString(GLESEnum::CopyBufferSubDataTarget, srcTarget),
+ srcLevel, srcX, srcY, srcZ, dstName,
+ GLenumToString(GLESEnum::CopyBufferSubDataTarget, dstTarget), dstLevel, dstX, dstY, dstZ,
+ srcWidth, srcHeight, srcDepth);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateCopyImageSubDataEXT(
+ context, angle::EntryPoint::GLCopyImageSubDataEXT, srcName,
+ srcTarget, srcLevel, srcX, srcY, srcZ, dstName, dstTarget, dstLevel,
+ dstX, dstY, dstZ, srcWidth, srcHeight, srcDepth));
+ if (isCallValid)
+ {
+ context->copyImageSubData(srcName, srcTarget, srcLevel, srcX, srcY, srcZ, dstName,
+ dstTarget, dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight,
+ srcDepth);
+ }
+ ANGLE_CAPTURE_GL(CopyImageSubDataEXT, isCallValid, context, srcName, srcTarget, srcLevel,
+ srcX, srcY, srcZ, dstName, dstTarget, dstLevel, dstX, dstY, dstZ, srcWidth,
+ srcHeight, srcDepth);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_EXT_debug_label
+void GL_APIENTRY
+GL_GetObjectLabelEXT(GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetObjectLabelEXT,
+ "context = %d, type = %s, object = %u, bufSize = %d, length = 0x%016" PRIxPTR
+ ", label = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, type), object, bufSize,
+ (uintptr_t)length, (uintptr_t)label);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetObjectLabelEXT(context, angle::EntryPoint::GLGetObjectLabelEXT, type,
+ object, bufSize, length, label));
+ if (isCallValid)
+ {
+ context->getObjectLabel(type, object, bufSize, length, label);
+ }
+ ANGLE_CAPTURE_GL(GetObjectLabelEXT, isCallValid, context, type, object, bufSize, length,
+ label);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_LabelObjectEXT(GLenum type, GLuint object, GLsizei length, const GLchar *label)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLLabelObjectEXT,
+ "context = %d, type = %s, object = %u, length = %d, label = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, type), object, length, (uintptr_t)label);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateLabelObjectEXT(context, angle::EntryPoint::GLLabelObjectEXT,
+ type, object, length, label));
+ if (isCallValid)
+ {
+ context->labelObject(type, object, length, label);
+ }
+ ANGLE_CAPTURE_GL(LabelObjectEXT, isCallValid, context, type, object, length, label);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_EXT_debug_marker
+void GL_APIENTRY GL_InsertEventMarkerEXT(GLsizei length, const GLchar *marker)
+{
+ Context *context = GetValidGlobalContext();
+ // Don't run the EVENT() macro on the EXT_debug_marker entry points.
+ // It can interfere with the debug events being set by the caller.
+ // EVENT(context, GLInsertEventMarkerEXT, "context = %d, length = %d, marker = 0x%016" PRIxPTR
+ // "", CID(context), length, (uintptr_t)marker);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateInsertEventMarkerEXT(context, angle::EntryPoint::GLInsertEventMarkerEXT,
+ length, marker));
+ if (isCallValid)
+ {
+ context->insertEventMarker(length, marker);
+ }
+ ANGLE_CAPTURE_GL(InsertEventMarkerEXT, isCallValid, context, length, marker);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_PopGroupMarkerEXT()
+{
+ Context *context = GetValidGlobalContext();
+ // Don't run the EVENT() macro on the EXT_debug_marker entry points.
+ // It can interfere with the debug events being set by the caller.
+ // EVENT(context, GLPopGroupMarkerEXT, "context = %d", CID(context));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidatePopGroupMarkerEXT(context, angle::EntryPoint::GLPopGroupMarkerEXT));
+ if (isCallValid)
+ {
+ context->popGroupMarker();
+ }
+ ANGLE_CAPTURE_GL(PopGroupMarkerEXT, isCallValid, context);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_PushGroupMarkerEXT(GLsizei length, const GLchar *marker)
+{
+ Context *context = GetValidGlobalContext();
+ // Don't run the EVENT() macro on the EXT_debug_marker entry points.
+ // It can interfere with the debug events being set by the caller.
+ // EVENT(context, GLPushGroupMarkerEXT, "context = %d, length = %d, marker = 0x%016" PRIxPTR "",
+ // CID(context), length, (uintptr_t)marker);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidatePushGroupMarkerEXT(
+ context, angle::EntryPoint::GLPushGroupMarkerEXT, length, marker));
+ if (isCallValid)
+ {
+ context->pushGroupMarker(length, marker);
+ }
+ ANGLE_CAPTURE_GL(PushGroupMarkerEXT, isCallValid, context, length, marker);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_EXT_discard_framebuffer
+void GL_APIENTRY GL_DiscardFramebufferEXT(GLenum target,
+ GLsizei numAttachments,
+ const GLenum *attachments)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDiscardFramebufferEXT,
+ "context = %d, target = %s, numAttachments = %d, attachments = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::FramebufferTarget, target), numAttachments,
+ (uintptr_t)attachments);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateDiscardFramebufferEXT(context, angle::EntryPoint::GLDiscardFramebufferEXT,
+ target, numAttachments, attachments));
+ if (isCallValid)
+ {
+ context->discardFramebuffer(target, numAttachments, attachments);
+ }
+ ANGLE_CAPTURE_GL(DiscardFramebufferEXT, isCallValid, context, target, numAttachments,
+ attachments);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_EXT_disjoint_timer_query
+void GL_APIENTRY GL_BeginQueryEXT(GLenum target, GLuint id)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBeginQueryEXT, "context = %d, target = %s, id = %u", CID(context),
+ GLenumToString(GLESEnum::QueryTarget, target), id);
+
+ if (context)
+ {
+ QueryType targetPacked = PackParam<QueryType>(target);
+ QueryID idPacked = PackParam<QueryID>(id);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateBeginQueryEXT(context, angle::EntryPoint::GLBeginQueryEXT,
+ targetPacked, idPacked));
+ if (isCallValid)
+ {
+ context->beginQuery(targetPacked, idPacked);
+ }
+ ANGLE_CAPTURE_GL(BeginQueryEXT, isCallValid, context, targetPacked, idPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DeleteQueriesEXT(GLsizei n, const GLuint *ids)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDeleteQueriesEXT, "context = %d, n = %d, ids = 0x%016" PRIxPTR "",
+ CID(context), n, (uintptr_t)ids);
+
+ if (context)
+ {
+ const QueryID *idsPacked = PackParam<const QueryID *>(ids);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateDeleteQueriesEXT(context, angle::EntryPoint::GLDeleteQueriesEXT,
+ n, idsPacked));
+ if (isCallValid)
+ {
+ context->deleteQueries(n, idsPacked);
+ }
+ ANGLE_CAPTURE_GL(DeleteQueriesEXT, isCallValid, context, n, idsPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_EndQueryEXT(GLenum target)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLEndQueryEXT, "context = %d, target = %s", CID(context),
+ GLenumToString(GLESEnum::QueryTarget, target));
+
+ if (context)
+ {
+ QueryType targetPacked = PackParam<QueryType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateEndQueryEXT(context, angle::EntryPoint::GLEndQueryEXT, targetPacked));
+ if (isCallValid)
+ {
+ context->endQuery(targetPacked);
+ }
+ ANGLE_CAPTURE_GL(EndQueryEXT, isCallValid, context, targetPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GenQueriesEXT(GLsizei n, GLuint *ids)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGenQueriesEXT, "context = %d, n = %d, ids = 0x%016" PRIxPTR "", CID(context),
+ n, (uintptr_t)ids);
+
+ if (context)
+ {
+ QueryID *idsPacked = PackParam<QueryID *>(ids);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGenQueriesEXT(context, angle::EntryPoint::GLGenQueriesEXT, n, idsPacked));
+ if (isCallValid)
+ {
+ context->genQueries(n, idsPacked);
+ }
+ ANGLE_CAPTURE_GL(GenQueriesEXT, isCallValid, context, n, idsPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetInteger64vEXT(GLenum pname, GLint64 *data)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetInteger64vEXT, "context = %d, pname = %s, data = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::GetPName, pname), (uintptr_t)data);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetInteger64vEXT(context, angle::EntryPoint::GLGetInteger64vEXT, pname, data));
+ if (isCallValid)
+ {
+ context->getInteger64v(pname, data);
+ }
+ ANGLE_CAPTURE_GL(GetInteger64vEXT, isCallValid, context, pname, data);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetQueryObjecti64vEXT(GLuint id, GLenum pname, GLint64 *params)
+{
+ Context *context = GetGlobalContext();
+ EVENT(context, GLGetQueryObjecti64vEXT,
+ "context = %d, id = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context), id,
+ GLenumToString(GLESEnum::QueryObjectParameterName, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ QueryID idPacked = PackParam<QueryID>(id);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetQueryObjecti64vEXT(context, angle::EntryPoint::GLGetQueryObjecti64vEXT,
+ idPacked, pname, params));
+ if (isCallValid)
+ {
+ context->getQueryObjecti64v(idPacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetQueryObjecti64vEXT, isCallValid, context, idPacked, pname, params);
+ }
+ else
+ {}
+}
+
+void GL_APIENTRY GL_GetQueryObjectivEXT(GLuint id, GLenum pname, GLint *params)
+{
+ Context *context = GetGlobalContext();
+ EVENT(context, GLGetQueryObjectivEXT,
+ "context = %d, id = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context), id,
+ GLenumToString(GLESEnum::QueryObjectParameterName, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ QueryID idPacked = PackParam<QueryID>(id);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetQueryObjectivEXT(context, angle::EntryPoint::GLGetQueryObjectivEXT,
+ idPacked, pname, params));
+ if (isCallValid)
+ {
+ context->getQueryObjectiv(idPacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetQueryObjectivEXT, isCallValid, context, idPacked, pname, params);
+ }
+ else
+ {}
+}
+
+void GL_APIENTRY GL_GetQueryObjectui64vEXT(GLuint id, GLenum pname, GLuint64 *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetQueryObjectui64vEXT,
+ "context = %d, id = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context), id,
+ GLenumToString(GLESEnum::QueryObjectParameterName, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ QueryID idPacked = PackParam<QueryID>(id);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetQueryObjectui64vEXT(context, angle::EntryPoint::GLGetQueryObjectui64vEXT,
+ idPacked, pname, params));
+ if (isCallValid)
+ {
+ context->getQueryObjectui64v(idPacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetQueryObjectui64vEXT, isCallValid, context, idPacked, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetQueryObjectuivEXT,
+ "context = %d, id = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context), id,
+ GLenumToString(GLESEnum::QueryObjectParameterName, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ QueryID idPacked = PackParam<QueryID>(id);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetQueryObjectuivEXT(context, angle::EntryPoint::GLGetQueryObjectuivEXT,
+ idPacked, pname, params));
+ if (isCallValid)
+ {
+ context->getQueryObjectuiv(idPacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetQueryObjectuivEXT, isCallValid, context, idPacked, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetQueryivEXT(GLenum target, GLenum pname, GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetQueryivEXT,
+ "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::QueryTarget, target),
+ GLenumToString(GLESEnum::QueryParameterName, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ QueryType targetPacked = PackParam<QueryType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetQueryivEXT(context, angle::EntryPoint::GLGetQueryivEXT,
+ targetPacked, pname, params));
+ if (isCallValid)
+ {
+ context->getQueryiv(targetPacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetQueryivEXT, isCallValid, context, targetPacked, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+GLboolean GL_APIENTRY GL_IsQueryEXT(GLuint id)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLIsQueryEXT, "context = %d, id = %u", CID(context), id);
+
+ GLboolean returnValue;
+ if (context)
+ {
+ QueryID idPacked = PackParam<QueryID>(id);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateIsQueryEXT(context, angle::EntryPoint::GLIsQueryEXT, idPacked));
+ if (isCallValid)
+ {
+ returnValue = context->isQuery(idPacked);
+ }
+ else
+ {
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsQueryEXT, GLboolean>();
+ }
+ ANGLE_CAPTURE_GL(IsQueryEXT, isCallValid, context, idPacked, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsQueryEXT, GLboolean>();
+ }
+ return returnValue;
+}
+
+void GL_APIENTRY GL_QueryCounterEXT(GLuint id, GLenum target)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLQueryCounterEXT, "context = %d, id = %u, target = %s", CID(context), id,
+ GLenumToString(GLESEnum::QueryCounterTarget, target));
+
+ if (context)
+ {
+ QueryID idPacked = PackParam<QueryID>(id);
+ QueryType targetPacked = PackParam<QueryType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateQueryCounterEXT(context, angle::EntryPoint::GLQueryCounterEXT,
+ idPacked, targetPacked));
+ if (isCallValid)
+ {
+ context->queryCounter(idPacked, targetPacked);
+ }
+ ANGLE_CAPTURE_GL(QueryCounterEXT, isCallValid, context, idPacked, targetPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_EXT_draw_buffers
+void GL_APIENTRY GL_DrawBuffersEXT(GLsizei n, const GLenum *bufs)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDrawBuffersEXT, "context = %d, n = %d, bufs = 0x%016" PRIxPTR "", CID(context),
+ n, (uintptr_t)bufs);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateDrawBuffersEXT(context, angle::EntryPoint::GLDrawBuffersEXT, n, bufs));
+ if (isCallValid)
+ {
+ context->drawBuffers(n, bufs);
+ }
+ ANGLE_CAPTURE_GL(DrawBuffersEXT, isCallValid, context, n, bufs);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_EXT_draw_buffers_indexed
+void GL_APIENTRY GL_BlendEquationSeparateiEXT(GLuint buf, GLenum modeRGB, GLenum modeAlpha)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBlendEquationSeparateiEXT,
+ "context = %d, buf = %u, modeRGB = %s, modeAlpha = %s", CID(context), buf,
+ GLenumToString(GLESEnum::BlendEquationModeEXT, modeRGB),
+ GLenumToString(GLESEnum::BlendEquationModeEXT, modeAlpha));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateBlendEquationSeparateiEXT(
+ context, angle::EntryPoint::GLBlendEquationSeparateiEXT, buf, modeRGB, modeAlpha));
+ if (isCallValid)
+ {
+ context->blendEquationSeparatei(buf, modeRGB, modeAlpha);
+ }
+ ANGLE_CAPTURE_GL(BlendEquationSeparateiEXT, isCallValid, context, buf, modeRGB, modeAlpha);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_BlendEquationiEXT(GLuint buf, GLenum mode)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBlendEquationiEXT, "context = %d, buf = %u, mode = %s", CID(context), buf,
+ GLenumToString(GLESEnum::BlendEquationModeEXT, mode));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateBlendEquationiEXT(context, angle::EntryPoint::GLBlendEquationiEXT, buf, mode));
+ if (isCallValid)
+ {
+ context->blendEquationi(buf, mode);
+ }
+ ANGLE_CAPTURE_GL(BlendEquationiEXT, isCallValid, context, buf, mode);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY
+GL_BlendFuncSeparateiEXT(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBlendFuncSeparateiEXT,
+ "context = %d, buf = %u, srcRGB = %s, dstRGB = %s, srcAlpha = %s, dstAlpha = %s",
+ CID(context), buf, GLenumToString(GLESEnum::BlendingFactor, srcRGB),
+ GLenumToString(GLESEnum::BlendingFactor, dstRGB),
+ GLenumToString(GLESEnum::BlendingFactor, srcAlpha),
+ GLenumToString(GLESEnum::BlendingFactor, dstAlpha));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateBlendFuncSeparateiEXT(context, angle::EntryPoint::GLBlendFuncSeparateiEXT, buf,
+ srcRGB, dstRGB, srcAlpha, dstAlpha));
+ if (isCallValid)
+ {
+ context->blendFuncSeparatei(buf, srcRGB, dstRGB, srcAlpha, dstAlpha);
+ }
+ ANGLE_CAPTURE_GL(BlendFuncSeparateiEXT, isCallValid, context, buf, srcRGB, dstRGB, srcAlpha,
+ dstAlpha);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_BlendFunciEXT(GLuint buf, GLenum src, GLenum dst)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBlendFunciEXT, "context = %d, buf = %u, src = %s, dst = %s", CID(context), buf,
+ GLenumToString(GLESEnum::BlendingFactor, src),
+ GLenumToString(GLESEnum::BlendingFactor, dst));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateBlendFunciEXT(context, angle::EntryPoint::GLBlendFunciEXT, buf, src, dst));
+ if (isCallValid)
+ {
+ context->blendFunci(buf, src, dst);
+ }
+ ANGLE_CAPTURE_GL(BlendFunciEXT, isCallValid, context, buf, src, dst);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ColorMaskiEXT(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLColorMaskiEXT, "context = %d, index = %u, r = %s, g = %s, b = %s, a = %s",
+ CID(context), index, GLbooleanToString(r), GLbooleanToString(g), GLbooleanToString(b),
+ GLbooleanToString(a));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateColorMaskiEXT(context, angle::EntryPoint::GLColorMaskiEXT, index, r, g, b, a));
+ if (isCallValid)
+ {
+ context->colorMaski(index, r, g, b, a);
+ }
+ ANGLE_CAPTURE_GL(ColorMaskiEXT, isCallValid, context, index, r, g, b, a);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DisableiEXT(GLenum target, GLuint index)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDisableiEXT, "context = %d, target = %s, index = %u", CID(context),
+ GLenumToString(GLESEnum::EnableCap, target), index);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateDisableiEXT(context, angle::EntryPoint::GLDisableiEXT, target, index));
+ if (isCallValid)
+ {
+ context->disablei(target, index);
+ }
+ ANGLE_CAPTURE_GL(DisableiEXT, isCallValid, context, target, index);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_EnableiEXT(GLenum target, GLuint index)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLEnableiEXT, "context = %d, target = %s, index = %u", CID(context),
+ GLenumToString(GLESEnum::EnableCap, target), index);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateEnableiEXT(context, angle::EntryPoint::GLEnableiEXT, target, index));
+ if (isCallValid)
+ {
+ context->enablei(target, index);
+ }
+ ANGLE_CAPTURE_GL(EnableiEXT, isCallValid, context, target, index);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+GLboolean GL_APIENTRY GL_IsEnablediEXT(GLenum target, GLuint index)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLIsEnablediEXT, "context = %d, target = %s, index = %u", CID(context),
+ GLenumToString(GLESEnum::EnableCap, target), index);
+
+ GLboolean returnValue;
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateIsEnablediEXT(context, angle::EntryPoint::GLIsEnablediEXT, target, index));
+ if (isCallValid)
+ {
+ returnValue = context->isEnabledi(target, index);
+ }
+ else
+ {
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsEnablediEXT, GLboolean>();
+ }
+ ANGLE_CAPTURE_GL(IsEnablediEXT, isCallValid, context, target, index, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsEnablediEXT, GLboolean>();
+ }
+ return returnValue;
+}
+
+// GL_EXT_draw_elements_base_vertex
+void GL_APIENTRY GL_DrawElementsBaseVertexEXT(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLint basevertex)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDrawElementsBaseVertexEXT,
+ "context = %d, mode = %s, count = %d, type = %s, indices = 0x%016" PRIxPTR
+ ", basevertex = %d",
+ CID(context), GLenumToString(GLESEnum::PrimitiveType, mode), count,
+ GLenumToString(GLESEnum::DrawElementsType, type), (uintptr_t)indices, basevertex);
+
+ if (context)
+ {
+ PrimitiveMode modePacked = PackParam<PrimitiveMode>(mode);
+ DrawElementsType typePacked = PackParam<DrawElementsType>(type);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateDrawElementsBaseVertexEXT(
+ context, angle::EntryPoint::GLDrawElementsBaseVertexEXT, modePacked,
+ count, typePacked, indices, basevertex));
+ if (isCallValid)
+ {
+ context->drawElementsBaseVertex(modePacked, count, typePacked, indices, basevertex);
+ }
+ ANGLE_CAPTURE_GL(DrawElementsBaseVertexEXT, isCallValid, context, modePacked, count,
+ typePacked, indices, basevertex);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DrawElementsInstancedBaseVertexEXT(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLsizei instancecount,
+ GLint basevertex)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDrawElementsInstancedBaseVertexEXT,
+ "context = %d, mode = %s, count = %d, type = %s, indices = 0x%016" PRIxPTR
+ ", instancecount = %d, basevertex = %d",
+ CID(context), GLenumToString(GLESEnum::PrimitiveType, mode), count,
+ GLenumToString(GLESEnum::DrawElementsType, type), (uintptr_t)indices, instancecount,
+ basevertex);
+
+ if (context)
+ {
+ PrimitiveMode modePacked = PackParam<PrimitiveMode>(mode);
+ DrawElementsType typePacked = PackParam<DrawElementsType>(type);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateDrawElementsInstancedBaseVertexEXT(
+ context, angle::EntryPoint::GLDrawElementsInstancedBaseVertexEXT,
+ modePacked, count, typePacked, indices, instancecount, basevertex));
+ if (isCallValid)
+ {
+ context->drawElementsInstancedBaseVertex(modePacked, count, typePacked, indices,
+ instancecount, basevertex);
+ }
+ ANGLE_CAPTURE_GL(DrawElementsInstancedBaseVertexEXT, isCallValid, context, modePacked,
+ count, typePacked, indices, instancecount, basevertex);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DrawRangeElementsBaseVertexEXT(GLenum mode,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLint basevertex)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDrawRangeElementsBaseVertexEXT,
+ "context = %d, mode = %s, start = %u, end = %u, count = %d, type = %s, indices = "
+ "0x%016" PRIxPTR ", basevertex = %d",
+ CID(context), GLenumToString(GLESEnum::PrimitiveType, mode), start, end, count,
+ GLenumToString(GLESEnum::DrawElementsType, type), (uintptr_t)indices, basevertex);
+
+ if (context)
+ {
+ PrimitiveMode modePacked = PackParam<PrimitiveMode>(mode);
+ DrawElementsType typePacked = PackParam<DrawElementsType>(type);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateDrawRangeElementsBaseVertexEXT(
+ context, angle::EntryPoint::GLDrawRangeElementsBaseVertexEXT,
+ modePacked, start, end, count, typePacked, indices, basevertex));
+ if (isCallValid)
+ {
+ context->drawRangeElementsBaseVertex(modePacked, start, end, count, typePacked, indices,
+ basevertex);
+ }
+ ANGLE_CAPTURE_GL(DrawRangeElementsBaseVertexEXT, isCallValid, context, modePacked, start,
+ end, count, typePacked, indices, basevertex);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_MultiDrawElementsBaseVertexEXT(GLenum mode,
+ const GLsizei *count,
+ GLenum type,
+ const void *const *indices,
+ GLsizei drawcount,
+ const GLint *basevertex)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLMultiDrawElementsBaseVertexEXT,
+ "context = %d, mode = %s, count = 0x%016" PRIxPTR ", type = %s, indices = 0x%016" PRIxPTR
+ ", drawcount = %d, basevertex = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::PrimitiveType, mode), (uintptr_t)count,
+ GLenumToString(GLESEnum::DrawElementsType, type), (uintptr_t)indices, drawcount,
+ (uintptr_t)basevertex);
+
+ if (context)
+ {
+ PrimitiveMode modePacked = PackParam<PrimitiveMode>(mode);
+ DrawElementsType typePacked = PackParam<DrawElementsType>(type);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateMultiDrawElementsBaseVertexEXT(
+ context, angle::EntryPoint::GLMultiDrawElementsBaseVertexEXT,
+ modePacked, count, typePacked, indices, drawcount, basevertex));
+ if (isCallValid)
+ {
+ context->multiDrawElementsBaseVertex(modePacked, count, typePacked, indices, drawcount,
+ basevertex);
+ }
+ ANGLE_CAPTURE_GL(MultiDrawElementsBaseVertexEXT, isCallValid, context, modePacked, count,
+ typePacked, indices, drawcount, basevertex);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_EXT_external_buffer
+void GL_APIENTRY GL_BufferStorageExternalEXT(GLenum target,
+ GLintptr offset,
+ GLsizeiptr size,
+ GLeglClientBufferEXT clientBuffer,
+ GLbitfield flags)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBufferStorageExternalEXT,
+ "context = %d, target = %s, offset = %llu, size = %llu, clientBuffer = 0x%016" PRIxPTR
+ ", flags = %s",
+ CID(context), GLenumToString(GLESEnum::AllEnums, target),
+ static_cast<unsigned long long>(offset), static_cast<unsigned long long>(size),
+ (uintptr_t)clientBuffer, GLbitfieldToString(GLESEnum::BufferStorageMask, flags).c_str());
+
+ if (context)
+ {
+ BufferBinding targetPacked = PackParam<BufferBinding>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateBufferStorageExternalEXT(
+ context, angle::EntryPoint::GLBufferStorageExternalEXT,
+ targetPacked, offset, size, clientBuffer, flags));
+ if (isCallValid)
+ {
+ context->bufferStorageExternal(targetPacked, offset, size, clientBuffer, flags);
+ }
+ ANGLE_CAPTURE_GL(BufferStorageExternalEXT, isCallValid, context, targetPacked, offset, size,
+ clientBuffer, flags);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_NamedBufferStorageExternalEXT(GLuint buffer,
+ GLintptr offset,
+ GLsizeiptr size,
+ GLeglClientBufferEXT clientBuffer,
+ GLbitfield flags)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLNamedBufferStorageExternalEXT,
+ "context = %d, buffer = %u, offset = %llu, size = %llu, clientBuffer = 0x%016" PRIxPTR
+ ", flags = %s",
+ CID(context), buffer, static_cast<unsigned long long>(offset),
+ static_cast<unsigned long long>(size), (uintptr_t)clientBuffer,
+ GLbitfieldToString(GLESEnum::BufferStorageMask, flags).c_str());
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateNamedBufferStorageExternalEXT(
+ context, angle::EntryPoint::GLNamedBufferStorageExternalEXT, buffer,
+ offset, size, clientBuffer, flags));
+ if (isCallValid)
+ {
+ context->namedBufferStorageExternal(buffer, offset, size, clientBuffer, flags);
+ }
+ ANGLE_CAPTURE_GL(NamedBufferStorageExternalEXT, isCallValid, context, buffer, offset, size,
+ clientBuffer, flags);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_EXT_float_blend
+
+// GL_EXT_geometry_shader
+void GL_APIENTRY GL_FramebufferTextureEXT(GLenum target,
+ GLenum attachment,
+ GLuint texture,
+ GLint level)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLFramebufferTextureEXT,
+ "context = %d, target = %s, attachment = %s, texture = %u, level = %d", CID(context),
+ GLenumToString(GLESEnum::FramebufferTarget, target),
+ GLenumToString(GLESEnum::FramebufferAttachment, attachment), texture, level);
+
+ if (context)
+ {
+ TextureID texturePacked = PackParam<TextureID>(texture);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateFramebufferTextureEXT(context, angle::EntryPoint::GLFramebufferTextureEXT,
+ target, attachment, texturePacked, level));
+ if (isCallValid)
+ {
+ context->framebufferTexture(target, attachment, texturePacked, level);
+ }
+ ANGLE_CAPTURE_GL(FramebufferTextureEXT, isCallValid, context, target, attachment,
+ texturePacked, level);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_EXT_gpu_shader5
+
+// GL_EXT_instanced_arrays
+void GL_APIENTRY GL_DrawArraysInstancedEXT(GLenum mode,
+ GLint start,
+ GLsizei count,
+ GLsizei primcount)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDrawArraysInstancedEXT,
+ "context = %d, mode = %s, start = %d, count = %d, primcount = %d", CID(context),
+ GLenumToString(GLESEnum::PrimitiveType, mode), start, count, primcount);
+
+ if (context)
+ {
+ PrimitiveMode modePacked = PackParam<PrimitiveMode>(mode);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateDrawArraysInstancedEXT(context, angle::EntryPoint::GLDrawArraysInstancedEXT,
+ modePacked, start, count, primcount));
+ if (isCallValid)
+ {
+ context->drawArraysInstanced(modePacked, start, count, primcount);
+ }
+ ANGLE_CAPTURE_GL(DrawArraysInstancedEXT, isCallValid, context, modePacked, start, count,
+ primcount);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DrawElementsInstancedEXT(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLsizei primcount)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDrawElementsInstancedEXT,
+ "context = %d, mode = %s, count = %d, type = %s, indices = 0x%016" PRIxPTR
+ ", primcount = %d",
+ CID(context), GLenumToString(GLESEnum::PrimitiveType, mode), count,
+ GLenumToString(GLESEnum::DrawElementsType, type), (uintptr_t)indices, primcount);
+
+ if (context)
+ {
+ PrimitiveMode modePacked = PackParam<PrimitiveMode>(mode);
+ DrawElementsType typePacked = PackParam<DrawElementsType>(type);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateDrawElementsInstancedEXT(
+ context, angle::EntryPoint::GLDrawElementsInstancedEXT, modePacked,
+ count, typePacked, indices, primcount));
+ if (isCallValid)
+ {
+ context->drawElementsInstanced(modePacked, count, typePacked, indices, primcount);
+ }
+ ANGLE_CAPTURE_GL(DrawElementsInstancedEXT, isCallValid, context, modePacked, count,
+ typePacked, indices, primcount);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_VertexAttribDivisorEXT(GLuint index, GLuint divisor)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLVertexAttribDivisorEXT, "context = %d, index = %u, divisor = %u", CID(context),
+ index, divisor);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateVertexAttribDivisorEXT(context, angle::EntryPoint::GLVertexAttribDivisorEXT,
+ index, divisor));
+ if (isCallValid)
+ {
+ context->vertexAttribDivisor(index, divisor);
+ }
+ ANGLE_CAPTURE_GL(VertexAttribDivisorEXT, isCallValid, context, index, divisor);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_EXT_map_buffer_range
+void GL_APIENTRY GL_FlushMappedBufferRangeEXT(GLenum target, GLintptr offset, GLsizeiptr length)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLFlushMappedBufferRangeEXT,
+ "context = %d, target = %s, offset = %llu, length = %llu", CID(context),
+ GLenumToString(GLESEnum::BufferTargetARB, target),
+ static_cast<unsigned long long>(offset), static_cast<unsigned long long>(length));
+
+ if (context)
+ {
+ BufferBinding targetPacked = PackParam<BufferBinding>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateFlushMappedBufferRangeEXT(
+ context, angle::EntryPoint::GLFlushMappedBufferRangeEXT,
+ targetPacked, offset, length));
+ if (isCallValid)
+ {
+ context->flushMappedBufferRange(targetPacked, offset, length);
+ }
+ ANGLE_CAPTURE_GL(FlushMappedBufferRangeEXT, isCallValid, context, targetPacked, offset,
+ length);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void *GL_APIENTRY GL_MapBufferRangeEXT(GLenum target,
+ GLintptr offset,
+ GLsizeiptr length,
+ GLbitfield access)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLMapBufferRangeEXT,
+ "context = %d, target = %s, offset = %llu, length = %llu, access = %s", CID(context),
+ GLenumToString(GLESEnum::BufferTargetARB, target),
+ static_cast<unsigned long long>(offset), static_cast<unsigned long long>(length),
+ GLbitfieldToString(GLESEnum::MapBufferAccessMask, access).c_str());
+
+ void *returnValue;
+ if (context)
+ {
+ BufferBinding targetPacked = PackParam<BufferBinding>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateMapBufferRangeEXT(context, angle::EntryPoint::GLMapBufferRangeEXT,
+ targetPacked, offset, length, access));
+ if (isCallValid)
+ {
+ returnValue = context->mapBufferRange(targetPacked, offset, length, access);
+ }
+ else
+ {
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLMapBufferRangeEXT, void *>();
+ }
+ ANGLE_CAPTURE_GL(MapBufferRangeEXT, isCallValid, context, targetPacked, offset, length,
+ access, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLMapBufferRangeEXT, void *>();
+ }
+ return returnValue;
+}
+
+// GL_EXT_memory_object
+void GL_APIENTRY GL_BufferStorageMemEXT(GLenum target,
+ GLsizeiptr size,
+ GLuint memory,
+ GLuint64 offset)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBufferStorageMemEXT,
+ "context = %d, target = %s, size = %llu, memory = %u, offset = %llu", CID(context),
+ GLenumToString(GLESEnum::BufferTargetARB, target), static_cast<unsigned long long>(size),
+ memory, static_cast<unsigned long long>(offset));
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ MemoryObjectID memoryPacked = PackParam<MemoryObjectID>(memory);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateBufferStorageMemEXT(context, angle::EntryPoint::GLBufferStorageMemEXT,
+ targetPacked, size, memoryPacked, offset));
+ if (isCallValid)
+ {
+ context->bufferStorageMem(targetPacked, size, memoryPacked, offset);
+ }
+ ANGLE_CAPTURE_GL(BufferStorageMemEXT, isCallValid, context, targetPacked, size,
+ memoryPacked, offset);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_CreateMemoryObjectsEXT(GLsizei n, GLuint *memoryObjects)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLCreateMemoryObjectsEXT,
+ "context = %d, n = %d, memoryObjects = 0x%016" PRIxPTR "", CID(context), n,
+ (uintptr_t)memoryObjects);
+
+ if (context)
+ {
+ MemoryObjectID *memoryObjectsPacked = PackParam<MemoryObjectID *>(memoryObjects);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateCreateMemoryObjectsEXT(context, angle::EntryPoint::GLCreateMemoryObjectsEXT, n,
+ memoryObjectsPacked));
+ if (isCallValid)
+ {
+ context->createMemoryObjects(n, memoryObjectsPacked);
+ }
+ ANGLE_CAPTURE_GL(CreateMemoryObjectsEXT, isCallValid, context, n, memoryObjectsPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DeleteMemoryObjectsEXT(GLsizei n, const GLuint *memoryObjects)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDeleteMemoryObjectsEXT,
+ "context = %d, n = %d, memoryObjects = 0x%016" PRIxPTR "", CID(context), n,
+ (uintptr_t)memoryObjects);
+
+ if (context)
+ {
+ const MemoryObjectID *memoryObjectsPacked =
+ PackParam<const MemoryObjectID *>(memoryObjects);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateDeleteMemoryObjectsEXT(context, angle::EntryPoint::GLDeleteMemoryObjectsEXT, n,
+ memoryObjectsPacked));
+ if (isCallValid)
+ {
+ context->deleteMemoryObjects(n, memoryObjectsPacked);
+ }
+ ANGLE_CAPTURE_GL(DeleteMemoryObjectsEXT, isCallValid, context, n, memoryObjectsPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetMemoryObjectParameterivEXT(GLuint memoryObject, GLenum pname, GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetMemoryObjectParameterivEXT,
+ "context = %d, memoryObject = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ memoryObject, GLenumToString(GLESEnum::MemoryObjectParameterName, pname),
+ (uintptr_t)params);
+
+ if (context)
+ {
+ MemoryObjectID memoryObjectPacked = PackParam<MemoryObjectID>(memoryObject);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetMemoryObjectParameterivEXT(
+ context, angle::EntryPoint::GLGetMemoryObjectParameterivEXT,
+ memoryObjectPacked, pname, params));
+ if (isCallValid)
+ {
+ context->getMemoryObjectParameteriv(memoryObjectPacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetMemoryObjectParameterivEXT, isCallValid, context, memoryObjectPacked,
+ pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetUnsignedBytevEXT(GLenum pname, GLubyte *data)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetUnsignedBytevEXT, "context = %d, pname = %s, data = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::GetPName, pname), (uintptr_t)data);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetUnsignedBytevEXT(
+ context, angle::EntryPoint::GLGetUnsignedBytevEXT, pname, data));
+ if (isCallValid)
+ {
+ context->getUnsignedBytev(pname, data);
+ }
+ ANGLE_CAPTURE_GL(GetUnsignedBytevEXT, isCallValid, context, pname, data);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetUnsignedBytei_vEXT(GLenum target, GLuint index, GLubyte *data)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetUnsignedBytei_vEXT,
+ "context = %d, target = %s, index = %u, data = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::AllEnums, target), index, (uintptr_t)data);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetUnsignedBytei_vEXT(context, angle::EntryPoint::GLGetUnsignedBytei_vEXT,
+ target, index, data));
+ if (isCallValid)
+ {
+ context->getUnsignedBytei_v(target, index, data);
+ }
+ ANGLE_CAPTURE_GL(GetUnsignedBytei_vEXT, isCallValid, context, target, index, data);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+GLboolean GL_APIENTRY GL_IsMemoryObjectEXT(GLuint memoryObject)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLIsMemoryObjectEXT, "context = %d, memoryObject = %u", CID(context),
+ memoryObject);
+
+ GLboolean returnValue;
+ if (context)
+ {
+ MemoryObjectID memoryObjectPacked = PackParam<MemoryObjectID>(memoryObject);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateIsMemoryObjectEXT(context, angle::EntryPoint::GLIsMemoryObjectEXT,
+ memoryObjectPacked));
+ if (isCallValid)
+ {
+ returnValue = context->isMemoryObject(memoryObjectPacked);
+ }
+ else
+ {
+ returnValue =
+ GetDefaultReturnValue<angle::EntryPoint::GLIsMemoryObjectEXT, GLboolean>();
+ }
+ ANGLE_CAPTURE_GL(IsMemoryObjectEXT, isCallValid, context, memoryObjectPacked, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsMemoryObjectEXT, GLboolean>();
+ }
+ return returnValue;
+}
+
+void GL_APIENTRY GL_MemoryObjectParameterivEXT(GLuint memoryObject,
+ GLenum pname,
+ const GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLMemoryObjectParameterivEXT,
+ "context = %d, memoryObject = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ memoryObject, GLenumToString(GLESEnum::MemoryObjectParameterName, pname),
+ (uintptr_t)params);
+
+ if (context)
+ {
+ MemoryObjectID memoryObjectPacked = PackParam<MemoryObjectID>(memoryObject);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateMemoryObjectParameterivEXT(
+ context, angle::EntryPoint::GLMemoryObjectParameterivEXT,
+ memoryObjectPacked, pname, params));
+ if (isCallValid)
+ {
+ context->memoryObjectParameteriv(memoryObjectPacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(MemoryObjectParameterivEXT, isCallValid, context, memoryObjectPacked,
+ pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexStorageMem2DEXT(GLenum target,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLuint memory,
+ GLuint64 offset)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexStorageMem2DEXT,
+ "context = %d, target = %s, levels = %d, internalFormat = %s, width = %d, height = %d, "
+ "memory = %u, offset = %llu",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target), levels,
+ GLenumToString(GLESEnum::SizedInternalFormat, internalFormat), width, height, memory,
+ static_cast<unsigned long long>(offset));
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ MemoryObjectID memoryPacked = PackParam<MemoryObjectID>(memory);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateTexStorageMem2DEXT(
+ context, angle::EntryPoint::GLTexStorageMem2DEXT, targetPacked,
+ levels, internalFormat, width, height, memoryPacked, offset));
+ if (isCallValid)
+ {
+ context->texStorageMem2D(targetPacked, levels, internalFormat, width, height,
+ memoryPacked, offset);
+ }
+ ANGLE_CAPTURE_GL(TexStorageMem2DEXT, isCallValid, context, targetPacked, levels,
+ internalFormat, width, height, memoryPacked, offset);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexStorageMem2DMultisampleEXT(GLenum target,
+ GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedSampleLocations,
+ GLuint memory,
+ GLuint64 offset)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexStorageMem2DMultisampleEXT,
+ "context = %d, target = %s, samples = %d, internalFormat = %s, width = %d, height = %d, "
+ "fixedSampleLocations = %s, memory = %u, offset = %llu",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target), samples,
+ GLenumToString(GLESEnum::SizedInternalFormat, internalFormat), width, height,
+ GLbooleanToString(fixedSampleLocations), memory, static_cast<unsigned long long>(offset));
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ MemoryObjectID memoryPacked = PackParam<MemoryObjectID>(memory);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateTexStorageMem2DMultisampleEXT(
+ context, angle::EntryPoint::GLTexStorageMem2DMultisampleEXT, targetPacked, samples,
+ internalFormat, width, height, fixedSampleLocations, memoryPacked, offset));
+ if (isCallValid)
+ {
+ context->texStorageMem2DMultisample(targetPacked, samples, internalFormat, width,
+ height, fixedSampleLocations, memoryPacked, offset);
+ }
+ ANGLE_CAPTURE_GL(TexStorageMem2DMultisampleEXT, isCallValid, context, targetPacked, samples,
+ internalFormat, width, height, fixedSampleLocations, memoryPacked, offset);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexStorageMem3DEXT(GLenum target,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLuint memory,
+ GLuint64 offset)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexStorageMem3DEXT,
+ "context = %d, target = %s, levels = %d, internalFormat = %s, width = %d, height = %d, "
+ "depth = %d, memory = %u, offset = %llu",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target), levels,
+ GLenumToString(GLESEnum::SizedInternalFormat, internalFormat), width, height, depth,
+ memory, static_cast<unsigned long long>(offset));
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ MemoryObjectID memoryPacked = PackParam<MemoryObjectID>(memory);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateTexStorageMem3DEXT(context, angle::EntryPoint::GLTexStorageMem3DEXT,
+ targetPacked, levels, internalFormat, width, height, depth,
+ memoryPacked, offset));
+ if (isCallValid)
+ {
+ context->texStorageMem3D(targetPacked, levels, internalFormat, width, height, depth,
+ memoryPacked, offset);
+ }
+ ANGLE_CAPTURE_GL(TexStorageMem3DEXT, isCallValid, context, targetPacked, levels,
+ internalFormat, width, height, depth, memoryPacked, offset);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexStorageMem3DMultisampleEXT(GLenum target,
+ GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean fixedSampleLocations,
+ GLuint memory,
+ GLuint64 offset)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexStorageMem3DMultisampleEXT,
+ "context = %d, target = %s, samples = %d, internalFormat = %s, width = %d, height = %d, "
+ "depth = %d, fixedSampleLocations = %s, memory = %u, offset = %llu",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target), samples,
+ GLenumToString(GLESEnum::SizedInternalFormat, internalFormat), width, height, depth,
+ GLbooleanToString(fixedSampleLocations), memory, static_cast<unsigned long long>(offset));
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ MemoryObjectID memoryPacked = PackParam<MemoryObjectID>(memory);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateTexStorageMem3DMultisampleEXT(
+ context, angle::EntryPoint::GLTexStorageMem3DMultisampleEXT, targetPacked, samples,
+ internalFormat, width, height, depth, fixedSampleLocations, memoryPacked, offset));
+ if (isCallValid)
+ {
+ context->texStorageMem3DMultisample(targetPacked, samples, internalFormat, width,
+ height, depth, fixedSampleLocations, memoryPacked,
+ offset);
+ }
+ ANGLE_CAPTURE_GL(TexStorageMem3DMultisampleEXT, isCallValid, context, targetPacked, samples,
+ internalFormat, width, height, depth, fixedSampleLocations, memoryPacked,
+ offset);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_EXT_memory_object_fd
+void GL_APIENTRY GL_ImportMemoryFdEXT(GLuint memory, GLuint64 size, GLenum handleType, GLint fd)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLImportMemoryFdEXT,
+ "context = %d, memory = %u, size = %llu, handleType = %s, fd = %d", CID(context), memory,
+ static_cast<unsigned long long>(size),
+ GLenumToString(GLESEnum::ExternalHandleType, handleType), fd);
+
+ if (context)
+ {
+ MemoryObjectID memoryPacked = PackParam<MemoryObjectID>(memory);
+ HandleType handleTypePacked = PackParam<HandleType>(handleType);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateImportMemoryFdEXT(context, angle::EntryPoint::GLImportMemoryFdEXT,
+ memoryPacked, size, handleTypePacked, fd));
+ if (isCallValid)
+ {
+ context->importMemoryFd(memoryPacked, size, handleTypePacked, fd);
+ }
+ ANGLE_CAPTURE_GL(ImportMemoryFdEXT, isCallValid, context, memoryPacked, size,
+ handleTypePacked, fd);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_EXT_multi_draw_indirect
+void GL_APIENTRY GL_MultiDrawArraysIndirectEXT(GLenum mode,
+ const void *indirect,
+ GLsizei drawcount,
+ GLsizei stride)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLMultiDrawArraysIndirectEXT,
+ "context = %d, mode = %s, indirect = 0x%016" PRIxPTR ", drawcount = %d, stride = %d",
+ CID(context), GLenumToString(GLESEnum::PrimitiveType, mode), (uintptr_t)indirect,
+ drawcount, stride);
+
+ if (context)
+ {
+ PrimitiveMode modePacked = PackParam<PrimitiveMode>(mode);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateMultiDrawArraysIndirectEXT(
+ context, angle::EntryPoint::GLMultiDrawArraysIndirectEXT,
+ modePacked, indirect, drawcount, stride));
+ if (isCallValid)
+ {
+ context->multiDrawArraysIndirect(modePacked, indirect, drawcount, stride);
+ }
+ ANGLE_CAPTURE_GL(MultiDrawArraysIndirectEXT, isCallValid, context, modePacked, indirect,
+ drawcount, stride);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_MultiDrawElementsIndirectEXT(GLenum mode,
+ GLenum type,
+ const void *indirect,
+ GLsizei drawcount,
+ GLsizei stride)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLMultiDrawElementsIndirectEXT,
+ "context = %d, mode = %s, type = %s, indirect = 0x%016" PRIxPTR
+ ", drawcount = %d, stride = %d",
+ CID(context), GLenumToString(GLESEnum::PrimitiveType, mode),
+ GLenumToString(GLESEnum::DrawElementsType, type), (uintptr_t)indirect, drawcount, stride);
+
+ if (context)
+ {
+ PrimitiveMode modePacked = PackParam<PrimitiveMode>(mode);
+ DrawElementsType typePacked = PackParam<DrawElementsType>(type);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateMultiDrawElementsIndirectEXT(
+ context, angle::EntryPoint::GLMultiDrawElementsIndirectEXT,
+ modePacked, typePacked, indirect, drawcount, stride));
+ if (isCallValid)
+ {
+ context->multiDrawElementsIndirect(modePacked, typePacked, indirect, drawcount, stride);
+ }
+ ANGLE_CAPTURE_GL(MultiDrawElementsIndirectEXT, isCallValid, context, modePacked, typePacked,
+ indirect, drawcount, stride);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_EXT_multisampled_render_to_texture
+void GL_APIENTRY GL_FramebufferTexture2DMultisampleEXT(GLenum target,
+ GLenum attachment,
+ GLenum textarget,
+ GLuint texture,
+ GLint level,
+ GLsizei samples)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLFramebufferTexture2DMultisampleEXT,
+ "context = %d, target = %s, attachment = %s, textarget = %s, texture = %u, level = %d, "
+ "samples = %d",
+ CID(context), GLenumToString(GLESEnum::FramebufferTarget, target),
+ GLenumToString(GLESEnum::FramebufferAttachment, attachment),
+ GLenumToString(GLESEnum::TextureTarget, textarget), texture, level, samples);
+
+ if (context)
+ {
+ TextureTarget textargetPacked = PackParam<TextureTarget>(textarget);
+ TextureID texturePacked = PackParam<TextureID>(texture);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateFramebufferTexture2DMultisampleEXT(
+ context, angle::EntryPoint::GLFramebufferTexture2DMultisampleEXT, target,
+ attachment, textargetPacked, texturePacked, level, samples));
+ if (isCallValid)
+ {
+ context->framebufferTexture2DMultisample(target, attachment, textargetPacked,
+ texturePacked, level, samples);
+ }
+ ANGLE_CAPTURE_GL(FramebufferTexture2DMultisampleEXT, isCallValid, context, target,
+ attachment, textargetPacked, texturePacked, level, samples);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_RenderbufferStorageMultisampleEXT(GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLRenderbufferStorageMultisampleEXT,
+ "context = %d, target = %s, samples = %d, internalformat = %s, width = %d, height = %d",
+ CID(context), GLenumToString(GLESEnum::RenderbufferTarget, target), samples,
+ GLenumToString(GLESEnum::InternalFormat, internalformat), width, height);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateRenderbufferStorageMultisampleEXT(
+ context, angle::EntryPoint::GLRenderbufferStorageMultisampleEXT,
+ target, samples, internalformat, width, height));
+ if (isCallValid)
+ {
+ context->renderbufferStorageMultisampleEXT(target, samples, internalformat, width,
+ height);
+ }
+ ANGLE_CAPTURE_GL(RenderbufferStorageMultisampleEXT, isCallValid, context, target, samples,
+ internalformat, width, height);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_EXT_multisampled_render_to_texture2
+
+// GL_EXT_occlusion_query_boolean
+// BeginQueryEXT is already defined.
+
+// DeleteQueriesEXT is already defined.
+
+// EndQueryEXT is already defined.
+
+// GenQueriesEXT is already defined.
+
+// GetQueryObjectuivEXT is already defined.
+
+// GetQueryivEXT is already defined.
+
+// IsQueryEXT is already defined.
+
+// GL_EXT_primitive_bounding_box
+void GL_APIENTRY GL_PrimitiveBoundingBoxEXT(GLfloat minX,
+ GLfloat minY,
+ GLfloat minZ,
+ GLfloat minW,
+ GLfloat maxX,
+ GLfloat maxY,
+ GLfloat maxZ,
+ GLfloat maxW)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLPrimitiveBoundingBoxEXT,
+ "context = %d, minX = %f, minY = %f, minZ = %f, minW = %f, maxX = %f, maxY = %f, maxZ = "
+ "%f, maxW = %f",
+ CID(context), minX, minY, minZ, minW, maxX, maxY, maxZ, maxW);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidatePrimitiveBoundingBoxEXT(context, angle::EntryPoint::GLPrimitiveBoundingBoxEXT,
+ minX, minY, minZ, minW, maxX, maxY, maxZ, maxW));
+ if (isCallValid)
+ {
+ context->primitiveBoundingBox(minX, minY, minZ, minW, maxX, maxY, maxZ, maxW);
+ }
+ ANGLE_CAPTURE_GL(PrimitiveBoundingBoxEXT, isCallValid, context, minX, minY, minZ, minW,
+ maxX, maxY, maxZ, maxW);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_EXT_protected_textures
+
+// GL_EXT_pvrtc_sRGB
+
+// GL_EXT_read_format_bgra
+
+// GL_EXT_robustness
+GLenum GL_APIENTRY GL_GetGraphicsResetStatusEXT()
+{
+ Context *context = GetGlobalContext();
+ EVENT(context, GLGetGraphicsResetStatusEXT, "context = %d", CID(context));
+
+ GLenum returnValue;
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetGraphicsResetStatusEXT(
+ context, angle::EntryPoint::GLGetGraphicsResetStatusEXT));
+ if (isCallValid)
+ {
+ returnValue = context->getGraphicsResetStatus();
+ }
+ else
+ {
+ returnValue =
+ GetDefaultReturnValue<angle::EntryPoint::GLGetGraphicsResetStatusEXT, GLenum>();
+ }
+ ANGLE_CAPTURE_GL(GetGraphicsResetStatusEXT, isCallValid, context, returnValue);
+ }
+ else
+ {
+
+ returnValue =
+ GetDefaultReturnValue<angle::EntryPoint::GLGetGraphicsResetStatusEXT, GLenum>();
+ }
+ return returnValue;
+}
+
+void GL_APIENTRY GL_GetnUniformfvEXT(GLuint program,
+ GLint location,
+ GLsizei bufSize,
+ GLfloat *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetnUniformfvEXT,
+ "context = %d, program = %u, location = %d, bufSize = %d, params = 0x%016" PRIxPTR "",
+ CID(context), program, location, bufSize, (uintptr_t)params);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetnUniformfvEXT(context, angle::EntryPoint::GLGetnUniformfvEXT, programPacked,
+ locationPacked, bufSize, params));
+ if (isCallValid)
+ {
+ context->getnUniformfv(programPacked, locationPacked, bufSize, params);
+ }
+ ANGLE_CAPTURE_GL(GetnUniformfvEXT, isCallValid, context, programPacked, locationPacked,
+ bufSize, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetnUniformivEXT,
+ "context = %d, program = %u, location = %d, bufSize = %d, params = 0x%016" PRIxPTR "",
+ CID(context), program, location, bufSize, (uintptr_t)params);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetnUniformivEXT(context, angle::EntryPoint::GLGetnUniformivEXT, programPacked,
+ locationPacked, bufSize, params));
+ if (isCallValid)
+ {
+ context->getnUniformiv(programPacked, locationPacked, bufSize, params);
+ }
+ ANGLE_CAPTURE_GL(GetnUniformivEXT, isCallValid, context, programPacked, locationPacked,
+ bufSize, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ReadnPixelsEXT(GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ void *data)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLReadnPixelsEXT,
+ "context = %d, x = %d, y = %d, width = %d, height = %d, format = %s, type = %s, bufSize "
+ "= %d, data = 0x%016" PRIxPTR "",
+ CID(context), x, y, width, height, GLenumToString(GLESEnum::PixelFormat, format),
+ GLenumToString(GLESEnum::PixelType, type), bufSize, (uintptr_t)data);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateReadnPixelsEXT(context, angle::EntryPoint::GLReadnPixelsEXT, x,
+ y, width, height, format, type, bufSize, data));
+ if (isCallValid)
+ {
+ context->readnPixels(x, y, width, height, format, type, bufSize, data);
+ }
+ ANGLE_CAPTURE_GL(ReadnPixelsEXT, isCallValid, context, x, y, width, height, format, type,
+ bufSize, data);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_EXT_sRGB
+
+// GL_EXT_sRGB_write_control
+
+// GL_EXT_semaphore
+void GL_APIENTRY GL_DeleteSemaphoresEXT(GLsizei n, const GLuint *semaphores)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDeleteSemaphoresEXT, "context = %d, n = %d, semaphores = 0x%016" PRIxPTR "",
+ CID(context), n, (uintptr_t)semaphores);
+
+ if (context)
+ {
+ const SemaphoreID *semaphoresPacked = PackParam<const SemaphoreID *>(semaphores);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateDeleteSemaphoresEXT(context, angle::EntryPoint::GLDeleteSemaphoresEXT, n,
+ semaphoresPacked));
+ if (isCallValid)
+ {
+ context->deleteSemaphores(n, semaphoresPacked);
+ }
+ ANGLE_CAPTURE_GL(DeleteSemaphoresEXT, isCallValid, context, n, semaphoresPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GenSemaphoresEXT(GLsizei n, GLuint *semaphores)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGenSemaphoresEXT, "context = %d, n = %d, semaphores = 0x%016" PRIxPTR "",
+ CID(context), n, (uintptr_t)semaphores);
+
+ if (context)
+ {
+ SemaphoreID *semaphoresPacked = PackParam<SemaphoreID *>(semaphores);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGenSemaphoresEXT(context, angle::EntryPoint::GLGenSemaphoresEXT,
+ n, semaphoresPacked));
+ if (isCallValid)
+ {
+ context->genSemaphores(n, semaphoresPacked);
+ }
+ ANGLE_CAPTURE_GL(GenSemaphoresEXT, isCallValid, context, n, semaphoresPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetSemaphoreParameterui64vEXT(GLuint semaphore, GLenum pname, GLuint64 *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetSemaphoreParameterui64vEXT,
+ "context = %d, semaphore = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ semaphore, GLenumToString(GLESEnum::SemaphoreParameterName, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ SemaphoreID semaphorePacked = PackParam<SemaphoreID>(semaphore);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetSemaphoreParameterui64vEXT(
+ context, angle::EntryPoint::GLGetSemaphoreParameterui64vEXT,
+ semaphorePacked, pname, params));
+ if (isCallValid)
+ {
+ context->getSemaphoreParameterui64v(semaphorePacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetSemaphoreParameterui64vEXT, isCallValid, context, semaphorePacked,
+ pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+GLboolean GL_APIENTRY GL_IsSemaphoreEXT(GLuint semaphore)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLIsSemaphoreEXT, "context = %d, semaphore = %u", CID(context), semaphore);
+
+ GLboolean returnValue;
+ if (context)
+ {
+ SemaphoreID semaphorePacked = PackParam<SemaphoreID>(semaphore);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateIsSemaphoreEXT(context, angle::EntryPoint::GLIsSemaphoreEXT, semaphorePacked));
+ if (isCallValid)
+ {
+ returnValue = context->isSemaphore(semaphorePacked);
+ }
+ else
+ {
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsSemaphoreEXT, GLboolean>();
+ }
+ ANGLE_CAPTURE_GL(IsSemaphoreEXT, isCallValid, context, semaphorePacked, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsSemaphoreEXT, GLboolean>();
+ }
+ return returnValue;
+}
+
+void GL_APIENTRY GL_SemaphoreParameterui64vEXT(GLuint semaphore,
+ GLenum pname,
+ const GLuint64 *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLSemaphoreParameterui64vEXT,
+ "context = %d, semaphore = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ semaphore, GLenumToString(GLESEnum::SemaphoreParameterName, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ SemaphoreID semaphorePacked = PackParam<SemaphoreID>(semaphore);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateSemaphoreParameterui64vEXT(
+ context, angle::EntryPoint::GLSemaphoreParameterui64vEXT,
+ semaphorePacked, pname, params));
+ if (isCallValid)
+ {
+ context->semaphoreParameterui64v(semaphorePacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(SemaphoreParameterui64vEXT, isCallValid, context, semaphorePacked, pname,
+ params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_SignalSemaphoreEXT(GLuint semaphore,
+ GLuint numBufferBarriers,
+ const GLuint *buffers,
+ GLuint numTextureBarriers,
+ const GLuint *textures,
+ const GLenum *dstLayouts)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLSignalSemaphoreEXT,
+ "context = %d, semaphore = %u, numBufferBarriers = %u, buffers = 0x%016" PRIxPTR
+ ", numTextureBarriers = %u, textures = 0x%016" PRIxPTR ", dstLayouts = 0x%016" PRIxPTR "",
+ CID(context), semaphore, numBufferBarriers, (uintptr_t)buffers, numTextureBarriers,
+ (uintptr_t)textures, (uintptr_t)dstLayouts);
+
+ if (context)
+ {
+ SemaphoreID semaphorePacked = PackParam<SemaphoreID>(semaphore);
+ const BufferID *buffersPacked = PackParam<const BufferID *>(buffers);
+ const TextureID *texturesPacked = PackParam<const TextureID *>(textures);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateSignalSemaphoreEXT(context, angle::EntryPoint::GLSignalSemaphoreEXT,
+ semaphorePacked, numBufferBarriers, buffersPacked,
+ numTextureBarriers, texturesPacked, dstLayouts));
+ if (isCallValid)
+ {
+ context->signalSemaphore(semaphorePacked, numBufferBarriers, buffersPacked,
+ numTextureBarriers, texturesPacked, dstLayouts);
+ }
+ ANGLE_CAPTURE_GL(SignalSemaphoreEXT, isCallValid, context, semaphorePacked,
+ numBufferBarriers, buffersPacked, numTextureBarriers, texturesPacked,
+ dstLayouts);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_WaitSemaphoreEXT(GLuint semaphore,
+ GLuint numBufferBarriers,
+ const GLuint *buffers,
+ GLuint numTextureBarriers,
+ const GLuint *textures,
+ const GLenum *srcLayouts)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLWaitSemaphoreEXT,
+ "context = %d, semaphore = %u, numBufferBarriers = %u, buffers = 0x%016" PRIxPTR
+ ", numTextureBarriers = %u, textures = 0x%016" PRIxPTR ", srcLayouts = 0x%016" PRIxPTR "",
+ CID(context), semaphore, numBufferBarriers, (uintptr_t)buffers, numTextureBarriers,
+ (uintptr_t)textures, (uintptr_t)srcLayouts);
+
+ if (context)
+ {
+ SemaphoreID semaphorePacked = PackParam<SemaphoreID>(semaphore);
+ const BufferID *buffersPacked = PackParam<const BufferID *>(buffers);
+ const TextureID *texturesPacked = PackParam<const TextureID *>(textures);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateWaitSemaphoreEXT(context, angle::EntryPoint::GLWaitSemaphoreEXT,
+ semaphorePacked, numBufferBarriers, buffersPacked,
+ numTextureBarriers, texturesPacked, srcLayouts));
+ if (isCallValid)
+ {
+ context->waitSemaphore(semaphorePacked, numBufferBarriers, buffersPacked,
+ numTextureBarriers, texturesPacked, srcLayouts);
+ }
+ ANGLE_CAPTURE_GL(WaitSemaphoreEXT, isCallValid, context, semaphorePacked, numBufferBarriers,
+ buffersPacked, numTextureBarriers, texturesPacked, srcLayouts);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GetUnsignedBytei_vEXT is already defined.
+
+// GetUnsignedBytevEXT is already defined.
+
+// GL_EXT_semaphore_fd
+void GL_APIENTRY GL_ImportSemaphoreFdEXT(GLuint semaphore, GLenum handleType, GLint fd)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLImportSemaphoreFdEXT, "context = %d, semaphore = %u, handleType = %s, fd = %d",
+ CID(context), semaphore, GLenumToString(GLESEnum::ExternalHandleType, handleType), fd);
+
+ if (context)
+ {
+ SemaphoreID semaphorePacked = PackParam<SemaphoreID>(semaphore);
+ HandleType handleTypePacked = PackParam<HandleType>(handleType);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateImportSemaphoreFdEXT(context, angle::EntryPoint::GLImportSemaphoreFdEXT,
+ semaphorePacked, handleTypePacked, fd));
+ if (isCallValid)
+ {
+ context->importSemaphoreFd(semaphorePacked, handleTypePacked, fd);
+ }
+ ANGLE_CAPTURE_GL(ImportSemaphoreFdEXT, isCallValid, context, semaphorePacked,
+ handleTypePacked, fd);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_EXT_separate_shader_objects
+void GL_APIENTRY GL_ActiveShaderProgramEXT(GLuint pipeline, GLuint program)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLActiveShaderProgramEXT, "context = %d, pipeline = %u, program = %u",
+ CID(context), pipeline, program);
+
+ if (context)
+ {
+ ProgramPipelineID pipelinePacked = PackParam<ProgramPipelineID>(pipeline);
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateActiveShaderProgramEXT(context, angle::EntryPoint::GLActiveShaderProgramEXT,
+ pipelinePacked, programPacked));
+ if (isCallValid)
+ {
+ context->activeShaderProgram(pipelinePacked, programPacked);
+ }
+ ANGLE_CAPTURE_GL(ActiveShaderProgramEXT, isCallValid, context, pipelinePacked,
+ programPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_BindProgramPipelineEXT(GLuint pipeline)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBindProgramPipelineEXT, "context = %d, pipeline = %u", CID(context), pipeline);
+
+ if (context)
+ {
+ ProgramPipelineID pipelinePacked = PackParam<ProgramPipelineID>(pipeline);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateBindProgramPipelineEXT(context, angle::EntryPoint::GLBindProgramPipelineEXT,
+ pipelinePacked));
+ if (isCallValid)
+ {
+ context->bindProgramPipeline(pipelinePacked);
+ }
+ ANGLE_CAPTURE_GL(BindProgramPipelineEXT, isCallValid, context, pipelinePacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+GLuint GL_APIENTRY GL_CreateShaderProgramvEXT(GLenum type, GLsizei count, const GLchar **strings)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLCreateShaderProgramvEXT,
+ "context = %d, type = %s, count = %d, strings = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::ShaderType, type), count, (uintptr_t)strings);
+
+ GLuint returnValue;
+ if (context)
+ {
+ ShaderType typePacked = PackParam<ShaderType>(type);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateCreateShaderProgramvEXT(context, angle::EntryPoint::GLCreateShaderProgramvEXT,
+ typePacked, count, strings));
+ if (isCallValid)
+ {
+ returnValue = context->createShaderProgramv(typePacked, count, strings);
+ }
+ else
+ {
+ returnValue =
+ GetDefaultReturnValue<angle::EntryPoint::GLCreateShaderProgramvEXT, GLuint>();
+ }
+ ANGLE_CAPTURE_GL(CreateShaderProgramvEXT, isCallValid, context, typePacked, count, strings,
+ returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLCreateShaderProgramvEXT, GLuint>();
+ }
+ return returnValue;
+}
+
+void GL_APIENTRY GL_DeleteProgramPipelinesEXT(GLsizei n, const GLuint *pipelines)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDeleteProgramPipelinesEXT,
+ "context = %d, n = %d, pipelines = 0x%016" PRIxPTR "", CID(context), n,
+ (uintptr_t)pipelines);
+
+ if (context)
+ {
+ const ProgramPipelineID *pipelinesPacked = PackParam<const ProgramPipelineID *>(pipelines);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateDeleteProgramPipelinesEXT(
+ context, angle::EntryPoint::GLDeleteProgramPipelinesEXT, n, pipelinesPacked));
+ if (isCallValid)
+ {
+ context->deleteProgramPipelines(n, pipelinesPacked);
+ }
+ ANGLE_CAPTURE_GL(DeleteProgramPipelinesEXT, isCallValid, context, n, pipelinesPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GenProgramPipelinesEXT(GLsizei n, GLuint *pipelines)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGenProgramPipelinesEXT, "context = %d, n = %d, pipelines = 0x%016" PRIxPTR "",
+ CID(context), n, (uintptr_t)pipelines);
+
+ if (context)
+ {
+ ProgramPipelineID *pipelinesPacked = PackParam<ProgramPipelineID *>(pipelines);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGenProgramPipelinesEXT(context, angle::EntryPoint::GLGenProgramPipelinesEXT, n,
+ pipelinesPacked));
+ if (isCallValid)
+ {
+ context->genProgramPipelines(n, pipelinesPacked);
+ }
+ ANGLE_CAPTURE_GL(GenProgramPipelinesEXT, isCallValid, context, n, pipelinesPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetProgramPipelineInfoLogEXT(GLuint pipeline,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *infoLog)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetProgramPipelineInfoLogEXT,
+ "context = %d, pipeline = %u, bufSize = %d, length = 0x%016" PRIxPTR
+ ", infoLog = 0x%016" PRIxPTR "",
+ CID(context), pipeline, bufSize, (uintptr_t)length, (uintptr_t)infoLog);
+
+ if (context)
+ {
+ ProgramPipelineID pipelinePacked = PackParam<ProgramPipelineID>(pipeline);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetProgramPipelineInfoLogEXT(
+ context, angle::EntryPoint::GLGetProgramPipelineInfoLogEXT,
+ pipelinePacked, bufSize, length, infoLog));
+ if (isCallValid)
+ {
+ context->getProgramPipelineInfoLog(pipelinePacked, bufSize, length, infoLog);
+ }
+ ANGLE_CAPTURE_GL(GetProgramPipelineInfoLogEXT, isCallValid, context, pipelinePacked,
+ bufSize, length, infoLog);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetProgramPipelineivEXT(GLuint pipeline, GLenum pname, GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetProgramPipelineivEXT,
+ "context = %d, pipeline = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ pipeline, GLenumToString(GLESEnum::PipelineParameterName, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ ProgramPipelineID pipelinePacked = PackParam<ProgramPipelineID>(pipeline);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetProgramPipelineivEXT(context, angle::EntryPoint::GLGetProgramPipelineivEXT,
+ pipelinePacked, pname, params));
+ if (isCallValid)
+ {
+ context->getProgramPipelineiv(pipelinePacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetProgramPipelineivEXT, isCallValid, context, pipelinePacked, pname,
+ params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+GLboolean GL_APIENTRY GL_IsProgramPipelineEXT(GLuint pipeline)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLIsProgramPipelineEXT, "context = %d, pipeline = %u", CID(context), pipeline);
+
+ GLboolean returnValue;
+ if (context)
+ {
+ ProgramPipelineID pipelinePacked = PackParam<ProgramPipelineID>(pipeline);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateIsProgramPipelineEXT(context, angle::EntryPoint::GLIsProgramPipelineEXT,
+ pipelinePacked));
+ if (isCallValid)
+ {
+ returnValue = context->isProgramPipeline(pipelinePacked);
+ }
+ else
+ {
+ returnValue =
+ GetDefaultReturnValue<angle::EntryPoint::GLIsProgramPipelineEXT, GLboolean>();
+ }
+ ANGLE_CAPTURE_GL(IsProgramPipelineEXT, isCallValid, context, pipelinePacked, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsProgramPipelineEXT, GLboolean>();
+ }
+ return returnValue;
+}
+
+void GL_APIENTRY GL_ProgramParameteriEXT(GLuint program, GLenum pname, GLint value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramParameteriEXT, "context = %d, program = %u, pname = %s, value = %d",
+ CID(context), program, GLenumToString(GLESEnum::ProgramParameterPName, pname), value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramParameteriEXT(context, angle::EntryPoint::GLProgramParameteriEXT,
+ programPacked, pname, value));
+ if (isCallValid)
+ {
+ context->programParameteri(programPacked, pname, value);
+ }
+ ANGLE_CAPTURE_GL(ProgramParameteriEXT, isCallValid, context, programPacked, pname, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniform1fEXT(GLuint program, GLint location, GLfloat v0)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform1fEXT, "context = %d, program = %u, location = %d, v0 = %f",
+ CID(context), program, location, v0);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramUniform1fEXT(context, angle::EntryPoint::GLProgramUniform1fEXT,
+ programPacked, locationPacked, v0));
+ if (isCallValid)
+ {
+ context->programUniform1f(programPacked, locationPacked, v0);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform1fEXT, isCallValid, context, programPacked, locationPacked,
+ v0);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniform1fvEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLfloat *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform1fvEXT,
+ "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
+ CID(context), program, location, count, (uintptr_t)value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramUniform1fvEXT(context, angle::EntryPoint::GLProgramUniform1fvEXT,
+ programPacked, locationPacked, count, value));
+ if (isCallValid)
+ {
+ context->programUniform1fv(programPacked, locationPacked, count, value);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform1fvEXT, isCallValid, context, programPacked, locationPacked,
+ count, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniform1iEXT(GLuint program, GLint location, GLint v0)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform1iEXT, "context = %d, program = %u, location = %d, v0 = %d",
+ CID(context), program, location, v0);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramUniform1iEXT(context, angle::EntryPoint::GLProgramUniform1iEXT,
+ programPacked, locationPacked, v0));
+ if (isCallValid)
+ {
+ context->programUniform1i(programPacked, locationPacked, v0);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform1iEXT, isCallValid, context, programPacked, locationPacked,
+ v0);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniform1ivEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLint *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform1ivEXT,
+ "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
+ CID(context), program, location, count, (uintptr_t)value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramUniform1ivEXT(context, angle::EntryPoint::GLProgramUniform1ivEXT,
+ programPacked, locationPacked, count, value));
+ if (isCallValid)
+ {
+ context->programUniform1iv(programPacked, locationPacked, count, value);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform1ivEXT, isCallValid, context, programPacked, locationPacked,
+ count, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniform1uiEXT(GLuint program, GLint location, GLuint v0)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform1uiEXT, "context = %d, program = %u, location = %d, v0 = %u",
+ CID(context), program, location, v0);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramUniform1uiEXT(context, angle::EntryPoint::GLProgramUniform1uiEXT,
+ programPacked, locationPacked, v0));
+ if (isCallValid)
+ {
+ context->programUniform1ui(programPacked, locationPacked, v0);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform1uiEXT, isCallValid, context, programPacked, locationPacked,
+ v0);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniform1uivEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLuint *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform1uivEXT,
+ "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
+ CID(context), program, location, count, (uintptr_t)value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramUniform1uivEXT(context, angle::EntryPoint::GLProgramUniform1uivEXT,
+ programPacked, locationPacked, count, value));
+ if (isCallValid)
+ {
+ context->programUniform1uiv(programPacked, locationPacked, count, value);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform1uivEXT, isCallValid, context, programPacked, locationPacked,
+ count, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniform2fEXT(GLuint program, GLint location, GLfloat v0, GLfloat v1)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform2fEXT,
+ "context = %d, program = %u, location = %d, v0 = %f, v1 = %f", CID(context), program,
+ location, v0, v1);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramUniform2fEXT(context, angle::EntryPoint::GLProgramUniform2fEXT,
+ programPacked, locationPacked, v0, v1));
+ if (isCallValid)
+ {
+ context->programUniform2f(programPacked, locationPacked, v0, v1);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform2fEXT, isCallValid, context, programPacked, locationPacked,
+ v0, v1);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniform2fvEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLfloat *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform2fvEXT,
+ "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
+ CID(context), program, location, count, (uintptr_t)value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramUniform2fvEXT(context, angle::EntryPoint::GLProgramUniform2fvEXT,
+ programPacked, locationPacked, count, value));
+ if (isCallValid)
+ {
+ context->programUniform2fv(programPacked, locationPacked, count, value);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform2fvEXT, isCallValid, context, programPacked, locationPacked,
+ count, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniform2iEXT(GLuint program, GLint location, GLint v0, GLint v1)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform2iEXT,
+ "context = %d, program = %u, location = %d, v0 = %d, v1 = %d", CID(context), program,
+ location, v0, v1);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramUniform2iEXT(context, angle::EntryPoint::GLProgramUniform2iEXT,
+ programPacked, locationPacked, v0, v1));
+ if (isCallValid)
+ {
+ context->programUniform2i(programPacked, locationPacked, v0, v1);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform2iEXT, isCallValid, context, programPacked, locationPacked,
+ v0, v1);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniform2ivEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLint *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform2ivEXT,
+ "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
+ CID(context), program, location, count, (uintptr_t)value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramUniform2ivEXT(context, angle::EntryPoint::GLProgramUniform2ivEXT,
+ programPacked, locationPacked, count, value));
+ if (isCallValid)
+ {
+ context->programUniform2iv(programPacked, locationPacked, count, value);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform2ivEXT, isCallValid, context, programPacked, locationPacked,
+ count, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniform2uiEXT(GLuint program, GLint location, GLuint v0, GLuint v1)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform2uiEXT,
+ "context = %d, program = %u, location = %d, v0 = %u, v1 = %u", CID(context), program,
+ location, v0, v1);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramUniform2uiEXT(context, angle::EntryPoint::GLProgramUniform2uiEXT,
+ programPacked, locationPacked, v0, v1));
+ if (isCallValid)
+ {
+ context->programUniform2ui(programPacked, locationPacked, v0, v1);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform2uiEXT, isCallValid, context, programPacked, locationPacked,
+ v0, v1);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniform2uivEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLuint *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform2uivEXT,
+ "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
+ CID(context), program, location, count, (uintptr_t)value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramUniform2uivEXT(context, angle::EntryPoint::GLProgramUniform2uivEXT,
+ programPacked, locationPacked, count, value));
+ if (isCallValid)
+ {
+ context->programUniform2uiv(programPacked, locationPacked, count, value);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform2uivEXT, isCallValid, context, programPacked, locationPacked,
+ count, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY
+GL_ProgramUniform3fEXT(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform3fEXT,
+ "context = %d, program = %u, location = %d, v0 = %f, v1 = %f, v2 = %f", CID(context),
+ program, location, v0, v1, v2);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramUniform3fEXT(context, angle::EntryPoint::GLProgramUniform3fEXT,
+ programPacked, locationPacked, v0, v1, v2));
+ if (isCallValid)
+ {
+ context->programUniform3f(programPacked, locationPacked, v0, v1, v2);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform3fEXT, isCallValid, context, programPacked, locationPacked,
+ v0, v1, v2);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniform3fvEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLfloat *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform3fvEXT,
+ "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
+ CID(context), program, location, count, (uintptr_t)value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramUniform3fvEXT(context, angle::EntryPoint::GLProgramUniform3fvEXT,
+ programPacked, locationPacked, count, value));
+ if (isCallValid)
+ {
+ context->programUniform3fv(programPacked, locationPacked, count, value);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform3fvEXT, isCallValid, context, programPacked, locationPacked,
+ count, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY
+GL_ProgramUniform3iEXT(GLuint program, GLint location, GLint v0, GLint v1, GLint v2)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform3iEXT,
+ "context = %d, program = %u, location = %d, v0 = %d, v1 = %d, v2 = %d", CID(context),
+ program, location, v0, v1, v2);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramUniform3iEXT(context, angle::EntryPoint::GLProgramUniform3iEXT,
+ programPacked, locationPacked, v0, v1, v2));
+ if (isCallValid)
+ {
+ context->programUniform3i(programPacked, locationPacked, v0, v1, v2);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform3iEXT, isCallValid, context, programPacked, locationPacked,
+ v0, v1, v2);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniform3ivEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLint *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform3ivEXT,
+ "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
+ CID(context), program, location, count, (uintptr_t)value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramUniform3ivEXT(context, angle::EntryPoint::GLProgramUniform3ivEXT,
+ programPacked, locationPacked, count, value));
+ if (isCallValid)
+ {
+ context->programUniform3iv(programPacked, locationPacked, count, value);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform3ivEXT, isCallValid, context, programPacked, locationPacked,
+ count, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY
+GL_ProgramUniform3uiEXT(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform3uiEXT,
+ "context = %d, program = %u, location = %d, v0 = %u, v1 = %u, v2 = %u", CID(context),
+ program, location, v0, v1, v2);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramUniform3uiEXT(context, angle::EntryPoint::GLProgramUniform3uiEXT,
+ programPacked, locationPacked, v0, v1, v2));
+ if (isCallValid)
+ {
+ context->programUniform3ui(programPacked, locationPacked, v0, v1, v2);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform3uiEXT, isCallValid, context, programPacked, locationPacked,
+ v0, v1, v2);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniform3uivEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLuint *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform3uivEXT,
+ "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
+ CID(context), program, location, count, (uintptr_t)value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramUniform3uivEXT(context, angle::EntryPoint::GLProgramUniform3uivEXT,
+ programPacked, locationPacked, count, value));
+ if (isCallValid)
+ {
+ context->programUniform3uiv(programPacked, locationPacked, count, value);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform3uivEXT, isCallValid, context, programPacked, locationPacked,
+ count, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniform4fEXT(GLuint program,
+ GLint location,
+ GLfloat v0,
+ GLfloat v1,
+ GLfloat v2,
+ GLfloat v3)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform4fEXT,
+ "context = %d, program = %u, location = %d, v0 = %f, v1 = %f, v2 = %f, v3 = %f",
+ CID(context), program, location, v0, v1, v2, v3);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramUniform4fEXT(context, angle::EntryPoint::GLProgramUniform4fEXT,
+ programPacked, locationPacked, v0, v1, v2, v3));
+ if (isCallValid)
+ {
+ context->programUniform4f(programPacked, locationPacked, v0, v1, v2, v3);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform4fEXT, isCallValid, context, programPacked, locationPacked,
+ v0, v1, v2, v3);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniform4fvEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLfloat *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform4fvEXT,
+ "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
+ CID(context), program, location, count, (uintptr_t)value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramUniform4fvEXT(context, angle::EntryPoint::GLProgramUniform4fvEXT,
+ programPacked, locationPacked, count, value));
+ if (isCallValid)
+ {
+ context->programUniform4fv(programPacked, locationPacked, count, value);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform4fvEXT, isCallValid, context, programPacked, locationPacked,
+ count, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY
+GL_ProgramUniform4iEXT(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform4iEXT,
+ "context = %d, program = %u, location = %d, v0 = %d, v1 = %d, v2 = %d, v3 = %d",
+ CID(context), program, location, v0, v1, v2, v3);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramUniform4iEXT(context, angle::EntryPoint::GLProgramUniform4iEXT,
+ programPacked, locationPacked, v0, v1, v2, v3));
+ if (isCallValid)
+ {
+ context->programUniform4i(programPacked, locationPacked, v0, v1, v2, v3);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform4iEXT, isCallValid, context, programPacked, locationPacked,
+ v0, v1, v2, v3);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniform4ivEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLint *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform4ivEXT,
+ "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
+ CID(context), program, location, count, (uintptr_t)value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramUniform4ivEXT(context, angle::EntryPoint::GLProgramUniform4ivEXT,
+ programPacked, locationPacked, count, value));
+ if (isCallValid)
+ {
+ context->programUniform4iv(programPacked, locationPacked, count, value);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform4ivEXT, isCallValid, context, programPacked, locationPacked,
+ count, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY
+GL_ProgramUniform4uiEXT(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform4uiEXT,
+ "context = %d, program = %u, location = %d, v0 = %u, v1 = %u, v2 = %u, v3 = %u",
+ CID(context), program, location, v0, v1, v2, v3);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramUniform4uiEXT(context, angle::EntryPoint::GLProgramUniform4uiEXT,
+ programPacked, locationPacked, v0, v1, v2, v3));
+ if (isCallValid)
+ {
+ context->programUniform4ui(programPacked, locationPacked, v0, v1, v2, v3);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform4uiEXT, isCallValid, context, programPacked, locationPacked,
+ v0, v1, v2, v3);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniform4uivEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLuint *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniform4uivEXT,
+ "context = %d, program = %u, location = %d, count = %d, value = 0x%016" PRIxPTR "",
+ CID(context), program, location, count, (uintptr_t)value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateProgramUniform4uivEXT(context, angle::EntryPoint::GLProgramUniform4uivEXT,
+ programPacked, locationPacked, count, value));
+ if (isCallValid)
+ {
+ context->programUniform4uiv(programPacked, locationPacked, count, value);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniform4uivEXT, isCallValid, context, programPacked, locationPacked,
+ count, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniformMatrix2fvEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniformMatrix2fvEXT,
+ "context = %d, program = %u, location = %d, count = %d, transpose = %s, value = "
+ "0x%016" PRIxPTR "",
+ CID(context), program, location, count, GLbooleanToString(transpose), (uintptr_t)value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateProgramUniformMatrix2fvEXT(
+ context, angle::EntryPoint::GLProgramUniformMatrix2fvEXT,
+ programPacked, locationPacked, count, transpose, value));
+ if (isCallValid)
+ {
+ context->programUniformMatrix2fv(programPacked, locationPacked, count, transpose,
+ value);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniformMatrix2fvEXT, isCallValid, context, programPacked,
+ locationPacked, count, transpose, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniformMatrix2x3fvEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniformMatrix2x3fvEXT,
+ "context = %d, program = %u, location = %d, count = %d, transpose = %s, value = "
+ "0x%016" PRIxPTR "",
+ CID(context), program, location, count, GLbooleanToString(transpose), (uintptr_t)value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateProgramUniformMatrix2x3fvEXT(
+ context, angle::EntryPoint::GLProgramUniformMatrix2x3fvEXT,
+ programPacked, locationPacked, count, transpose, value));
+ if (isCallValid)
+ {
+ context->programUniformMatrix2x3fv(programPacked, locationPacked, count, transpose,
+ value);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniformMatrix2x3fvEXT, isCallValid, context, programPacked,
+ locationPacked, count, transpose, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniformMatrix2x4fvEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniformMatrix2x4fvEXT,
+ "context = %d, program = %u, location = %d, count = %d, transpose = %s, value = "
+ "0x%016" PRIxPTR "",
+ CID(context), program, location, count, GLbooleanToString(transpose), (uintptr_t)value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateProgramUniformMatrix2x4fvEXT(
+ context, angle::EntryPoint::GLProgramUniformMatrix2x4fvEXT,
+ programPacked, locationPacked, count, transpose, value));
+ if (isCallValid)
+ {
+ context->programUniformMatrix2x4fv(programPacked, locationPacked, count, transpose,
+ value);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniformMatrix2x4fvEXT, isCallValid, context, programPacked,
+ locationPacked, count, transpose, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniformMatrix3fvEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniformMatrix3fvEXT,
+ "context = %d, program = %u, location = %d, count = %d, transpose = %s, value = "
+ "0x%016" PRIxPTR "",
+ CID(context), program, location, count, GLbooleanToString(transpose), (uintptr_t)value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateProgramUniformMatrix3fvEXT(
+ context, angle::EntryPoint::GLProgramUniformMatrix3fvEXT,
+ programPacked, locationPacked, count, transpose, value));
+ if (isCallValid)
+ {
+ context->programUniformMatrix3fv(programPacked, locationPacked, count, transpose,
+ value);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniformMatrix3fvEXT, isCallValid, context, programPacked,
+ locationPacked, count, transpose, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniformMatrix3x2fvEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniformMatrix3x2fvEXT,
+ "context = %d, program = %u, location = %d, count = %d, transpose = %s, value = "
+ "0x%016" PRIxPTR "",
+ CID(context), program, location, count, GLbooleanToString(transpose), (uintptr_t)value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateProgramUniformMatrix3x2fvEXT(
+ context, angle::EntryPoint::GLProgramUniformMatrix3x2fvEXT,
+ programPacked, locationPacked, count, transpose, value));
+ if (isCallValid)
+ {
+ context->programUniformMatrix3x2fv(programPacked, locationPacked, count, transpose,
+ value);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniformMatrix3x2fvEXT, isCallValid, context, programPacked,
+ locationPacked, count, transpose, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniformMatrix3x4fvEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniformMatrix3x4fvEXT,
+ "context = %d, program = %u, location = %d, count = %d, transpose = %s, value = "
+ "0x%016" PRIxPTR "",
+ CID(context), program, location, count, GLbooleanToString(transpose), (uintptr_t)value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateProgramUniformMatrix3x4fvEXT(
+ context, angle::EntryPoint::GLProgramUniformMatrix3x4fvEXT,
+ programPacked, locationPacked, count, transpose, value));
+ if (isCallValid)
+ {
+ context->programUniformMatrix3x4fv(programPacked, locationPacked, count, transpose,
+ value);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniformMatrix3x4fvEXT, isCallValid, context, programPacked,
+ locationPacked, count, transpose, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniformMatrix4fvEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniformMatrix4fvEXT,
+ "context = %d, program = %u, location = %d, count = %d, transpose = %s, value = "
+ "0x%016" PRIxPTR "",
+ CID(context), program, location, count, GLbooleanToString(transpose), (uintptr_t)value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateProgramUniformMatrix4fvEXT(
+ context, angle::EntryPoint::GLProgramUniformMatrix4fvEXT,
+ programPacked, locationPacked, count, transpose, value));
+ if (isCallValid)
+ {
+ context->programUniformMatrix4fv(programPacked, locationPacked, count, transpose,
+ value);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniformMatrix4fvEXT, isCallValid, context, programPacked,
+ locationPacked, count, transpose, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniformMatrix4x2fvEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniformMatrix4x2fvEXT,
+ "context = %d, program = %u, location = %d, count = %d, transpose = %s, value = "
+ "0x%016" PRIxPTR "",
+ CID(context), program, location, count, GLbooleanToString(transpose), (uintptr_t)value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateProgramUniformMatrix4x2fvEXT(
+ context, angle::EntryPoint::GLProgramUniformMatrix4x2fvEXT,
+ programPacked, locationPacked, count, transpose, value));
+ if (isCallValid)
+ {
+ context->programUniformMatrix4x2fv(programPacked, locationPacked, count, transpose,
+ value);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniformMatrix4x2fvEXT, isCallValid, context, programPacked,
+ locationPacked, count, transpose, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramUniformMatrix4x3fvEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramUniformMatrix4x3fvEXT,
+ "context = %d, program = %u, location = %d, count = %d, transpose = %s, value = "
+ "0x%016" PRIxPTR "",
+ CID(context), program, location, count, GLbooleanToString(transpose), (uintptr_t)value);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ UniformLocation locationPacked = PackParam<UniformLocation>(location);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateProgramUniformMatrix4x3fvEXT(
+ context, angle::EntryPoint::GLProgramUniformMatrix4x3fvEXT,
+ programPacked, locationPacked, count, transpose, value));
+ if (isCallValid)
+ {
+ context->programUniformMatrix4x3fv(programPacked, locationPacked, count, transpose,
+ value);
+ }
+ ANGLE_CAPTURE_GL(ProgramUniformMatrix4x3fvEXT, isCallValid, context, programPacked,
+ locationPacked, count, transpose, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_UseProgramStagesEXT(GLuint pipeline, GLbitfield stages, GLuint program)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLUseProgramStagesEXT, "context = %d, pipeline = %u, stages = %s, program = %u",
+ CID(context), pipeline, GLbitfieldToString(GLESEnum::UseProgramStageMask, stages).c_str(),
+ program);
+
+ if (context)
+ {
+ ProgramPipelineID pipelinePacked = PackParam<ProgramPipelineID>(pipeline);
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateUseProgramStagesEXT(context, angle::EntryPoint::GLUseProgramStagesEXT,
+ pipelinePacked, stages, programPacked));
+ if (isCallValid)
+ {
+ context->useProgramStages(pipelinePacked, stages, programPacked);
+ }
+ ANGLE_CAPTURE_GL(UseProgramStagesEXT, isCallValid, context, pipelinePacked, stages,
+ programPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ValidateProgramPipelineEXT(GLuint pipeline)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLValidateProgramPipelineEXT, "context = %d, pipeline = %u", CID(context),
+ pipeline);
+
+ if (context)
+ {
+ ProgramPipelineID pipelinePacked = PackParam<ProgramPipelineID>(pipeline);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateValidateProgramPipelineEXT(
+ context, angle::EntryPoint::GLValidateProgramPipelineEXT, pipelinePacked));
+ if (isCallValid)
+ {
+ context->validateProgramPipeline(pipelinePacked);
+ }
+ ANGLE_CAPTURE_GL(ValidateProgramPipelineEXT, isCallValid, context, pipelinePacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_EXT_shader_framebuffer_fetch
+
+// GL_EXT_shader_framebuffer_fetch_non_coherent
+void GL_APIENTRY GL_FramebufferFetchBarrierEXT()
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLFramebufferFetchBarrierEXT, "context = %d", CID(context));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateFramebufferFetchBarrierEXT(
+ context, angle::EntryPoint::GLFramebufferFetchBarrierEXT));
+ if (isCallValid)
+ {
+ context->framebufferFetchBarrier();
+ }
+ ANGLE_CAPTURE_GL(FramebufferFetchBarrierEXT, isCallValid, context);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_EXT_shader_io_blocks
+
+// GL_EXT_shader_non_constant_global_initializers
+
+// GL_EXT_shader_texture_lod
+
+// GL_EXT_shadow_samplers
+
+// GL_EXT_tessellation_shader
+void GL_APIENTRY GL_PatchParameteriEXT(GLenum pname, GLint value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLPatchParameteriEXT, "context = %d, pname = %s, value = %d", CID(context),
+ GLenumToString(GLESEnum::PatchParameterName, pname), value);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidatePatchParameteriEXT(
+ context, angle::EntryPoint::GLPatchParameteriEXT, pname, value));
+ if (isCallValid)
+ {
+ context->patchParameteri(pname, value);
+ }
+ ANGLE_CAPTURE_GL(PatchParameteriEXT, isCallValid, context, pname, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_EXT_texture_border_clamp
+void GL_APIENTRY GL_GetSamplerParameterIivEXT(GLuint sampler, GLenum pname, GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetSamplerParameterIivEXT,
+ "context = %d, sampler = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ sampler, GLenumToString(GLESEnum::SamplerParameterI, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ SamplerID samplerPacked = PackParam<SamplerID>(sampler);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetSamplerParameterIivEXT(
+ context, angle::EntryPoint::GLGetSamplerParameterIivEXT,
+ samplerPacked, pname, params));
+ if (isCallValid)
+ {
+ context->getSamplerParameterIiv(samplerPacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetSamplerParameterIivEXT, isCallValid, context, samplerPacked, pname,
+ params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetSamplerParameterIuivEXT(GLuint sampler, GLenum pname, GLuint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetSamplerParameterIuivEXT,
+ "context = %d, sampler = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ sampler, GLenumToString(GLESEnum::SamplerParameterI, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ SamplerID samplerPacked = PackParam<SamplerID>(sampler);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetSamplerParameterIuivEXT(
+ context, angle::EntryPoint::GLGetSamplerParameterIuivEXT,
+ samplerPacked, pname, params));
+ if (isCallValid)
+ {
+ context->getSamplerParameterIuiv(samplerPacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetSamplerParameterIuivEXT, isCallValid, context, samplerPacked, pname,
+ params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetTexParameterIivEXT(GLenum target, GLenum pname, GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetTexParameterIivEXT,
+ "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::TextureTarget, target),
+ GLenumToString(GLESEnum::GetTextureParameter, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetTexParameterIivEXT(context, angle::EntryPoint::GLGetTexParameterIivEXT,
+ targetPacked, pname, params));
+ if (isCallValid)
+ {
+ context->getTexParameterIiv(targetPacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetTexParameterIivEXT, isCallValid, context, targetPacked, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetTexParameterIuivEXT(GLenum target, GLenum pname, GLuint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetTexParameterIuivEXT,
+ "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::TextureTarget, target),
+ GLenumToString(GLESEnum::GetTextureParameter, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetTexParameterIuivEXT(context, angle::EntryPoint::GLGetTexParameterIuivEXT,
+ targetPacked, pname, params));
+ if (isCallValid)
+ {
+ context->getTexParameterIuiv(targetPacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetTexParameterIuivEXT, isCallValid, context, targetPacked, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_SamplerParameterIivEXT(GLuint sampler, GLenum pname, const GLint *param)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLSamplerParameterIivEXT,
+ "context = %d, sampler = %u, pname = %s, param = 0x%016" PRIxPTR "", CID(context),
+ sampler, GLenumToString(GLESEnum::SamplerParameterI, pname), (uintptr_t)param);
+
+ if (context)
+ {
+ SamplerID samplerPacked = PackParam<SamplerID>(sampler);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateSamplerParameterIivEXT(context, angle::EntryPoint::GLSamplerParameterIivEXT,
+ samplerPacked, pname, param));
+ if (isCallValid)
+ {
+ context->samplerParameterIiv(samplerPacked, pname, param);
+ }
+ ANGLE_CAPTURE_GL(SamplerParameterIivEXT, isCallValid, context, samplerPacked, pname, param);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_SamplerParameterIuivEXT(GLuint sampler, GLenum pname, const GLuint *param)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLSamplerParameterIuivEXT,
+ "context = %d, sampler = %u, pname = %s, param = 0x%016" PRIxPTR "", CID(context),
+ sampler, GLenumToString(GLESEnum::SamplerParameterI, pname), (uintptr_t)param);
+
+ if (context)
+ {
+ SamplerID samplerPacked = PackParam<SamplerID>(sampler);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateSamplerParameterIuivEXT(context, angle::EntryPoint::GLSamplerParameterIuivEXT,
+ samplerPacked, pname, param));
+ if (isCallValid)
+ {
+ context->samplerParameterIuiv(samplerPacked, pname, param);
+ }
+ ANGLE_CAPTURE_GL(SamplerParameterIuivEXT, isCallValid, context, samplerPacked, pname,
+ param);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexParameterIivEXT(GLenum target, GLenum pname, const GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexParameterIivEXT,
+ "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::TextureTarget, target),
+ GLenumToString(GLESEnum::TextureParameterName, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateTexParameterIivEXT(context, angle::EntryPoint::GLTexParameterIivEXT,
+ targetPacked, pname, params));
+ if (isCallValid)
+ {
+ context->texParameterIiv(targetPacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(TexParameterIivEXT, isCallValid, context, targetPacked, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexParameterIuivEXT(GLenum target, GLenum pname, const GLuint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexParameterIuivEXT,
+ "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::TextureTarget, target),
+ GLenumToString(GLESEnum::TextureParameterName, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateTexParameterIuivEXT(context, angle::EntryPoint::GLTexParameterIuivEXT,
+ targetPacked, pname, params));
+ if (isCallValid)
+ {
+ context->texParameterIuiv(targetPacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(TexParameterIuivEXT, isCallValid, context, targetPacked, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_EXT_texture_buffer
+void GL_APIENTRY GL_TexBufferEXT(GLenum target, GLenum internalformat, GLuint buffer)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexBufferEXT, "context = %d, target = %s, internalformat = %s, buffer = %u",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target),
+ GLenumToString(GLESEnum::SizedInternalFormat, internalformat), buffer);
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ BufferID bufferPacked = PackParam<BufferID>(buffer);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateTexBufferEXT(context, angle::EntryPoint::GLTexBufferEXT,
+ targetPacked, internalformat, bufferPacked));
+ if (isCallValid)
+ {
+ context->texBuffer(targetPacked, internalformat, bufferPacked);
+ }
+ ANGLE_CAPTURE_GL(TexBufferEXT, isCallValid, context, targetPacked, internalformat,
+ bufferPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexBufferRangeEXT(GLenum target,
+ GLenum internalformat,
+ GLuint buffer,
+ GLintptr offset,
+ GLsizeiptr size)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexBufferRangeEXT,
+ "context = %d, target = %s, internalformat = %s, buffer = %u, offset = %llu, size = %llu",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target),
+ GLenumToString(GLESEnum::SizedInternalFormat, internalformat), buffer,
+ static_cast<unsigned long long>(offset), static_cast<unsigned long long>(size));
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ BufferID bufferPacked = PackParam<BufferID>(buffer);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateTexBufferRangeEXT(context, angle::EntryPoint::GLTexBufferRangeEXT,
+ targetPacked, internalformat, bufferPacked, offset, size));
+ if (isCallValid)
+ {
+ context->texBufferRange(targetPacked, internalformat, bufferPacked, offset, size);
+ }
+ ANGLE_CAPTURE_GL(TexBufferRangeEXT, isCallValid, context, targetPacked, internalformat,
+ bufferPacked, offset, size);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_EXT_texture_compression_bptc
+
+// GL_EXT_texture_compression_dxt1
+
+// GL_EXT_texture_compression_rgtc
+
+// GL_EXT_texture_compression_s3tc
+
+// GL_EXT_texture_compression_s3tc_srgb
+
+// GL_EXT_texture_cube_map_array
+
+// GL_EXT_texture_filter_anisotropic
+
+// GL_EXT_texture_format_BGRA8888
+
+// GL_EXT_texture_format_sRGB_override
+
+// GL_EXT_texture_norm16
+
+// GL_EXT_texture_rg
+
+// GL_EXT_texture_sRGB_R8
+
+// GL_EXT_texture_sRGB_RG8
+
+// GL_EXT_texture_sRGB_decode
+
+// GL_EXT_texture_storage
+void GL_APIENTRY GL_TexStorage1DEXT(GLenum target,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexStorage1DEXT,
+ "context = %d, target = %s, levels = %d, internalformat = %s, width = %d", CID(context),
+ GLenumToString(GLESEnum::TextureTarget, target), levels,
+ GLenumToString(GLESEnum::SizedInternalFormat, internalformat), width);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateTexStorage1DEXT(context, angle::EntryPoint::GLTexStorage1DEXT,
+ target, levels, internalformat, width));
+ if (isCallValid)
+ {
+ context->texStorage1D(target, levels, internalformat, width);
+ }
+ ANGLE_CAPTURE_GL(TexStorage1DEXT, isCallValid, context, target, levels, internalformat,
+ width);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexStorage2DEXT(GLenum target,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexStorage2DEXT,
+ "context = %d, target = %s, levels = %d, internalformat = %s, width = %d, height = %d",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target), levels,
+ GLenumToString(GLESEnum::SizedInternalFormat, internalformat), width, height);
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateTexStorage2DEXT(context, angle::EntryPoint::GLTexStorage2DEXT, targetPacked,
+ levels, internalformat, width, height));
+ if (isCallValid)
+ {
+ context->texStorage2D(targetPacked, levels, internalformat, width, height);
+ }
+ ANGLE_CAPTURE_GL(TexStorage2DEXT, isCallValid, context, targetPacked, levels,
+ internalformat, width, height);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexStorage3DEXT(GLenum target,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexStorage3DEXT,
+ "context = %d, target = %s, levels = %d, internalformat = %s, width = %d, height = %d, "
+ "depth = %d",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target), levels,
+ GLenumToString(GLESEnum::SizedInternalFormat, internalformat), width, height, depth);
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateTexStorage3DEXT(context, angle::EntryPoint::GLTexStorage3DEXT, targetPacked,
+ levels, internalformat, width, height, depth));
+ if (isCallValid)
+ {
+ context->texStorage3D(targetPacked, levels, internalformat, width, height, depth);
+ }
+ ANGLE_CAPTURE_GL(TexStorage3DEXT, isCallValid, context, targetPacked, levels,
+ internalformat, width, height, depth);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_EXT_texture_type_2_10_10_10_REV
+
+// GL_EXT_unpack_subimage
+
+// GL_IMG_texture_compression_pvrtc
+
+// GL_IMG_texture_compression_pvrtc2
+
+// GL_KHR_blend_equation_advanced
+void GL_APIENTRY GL_BlendBarrierKHR()
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBlendBarrierKHR, "context = %d", CID(context));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateBlendBarrierKHR(context, angle::EntryPoint::GLBlendBarrierKHR));
+ if (isCallValid)
+ {
+ context->blendBarrier();
+ }
+ ANGLE_CAPTURE_GL(BlendBarrierKHR, isCallValid, context);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_KHR_debug
+void GL_APIENTRY GL_DebugMessageCallbackKHR(GLDEBUGPROCKHR callback, const void *userParam)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDebugMessageCallbackKHR,
+ "context = %d, callback = 0x%016" PRIxPTR ", userParam = 0x%016" PRIxPTR "", CID(context),
+ (uintptr_t)callback, (uintptr_t)userParam);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateDebugMessageCallbackKHR(context, angle::EntryPoint::GLDebugMessageCallbackKHR,
+ callback, userParam));
+ if (isCallValid)
+ {
+ context->debugMessageCallback(callback, userParam);
+ }
+ ANGLE_CAPTURE_GL(DebugMessageCallbackKHR, isCallValid, context, callback, userParam);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DebugMessageControlKHR(GLenum source,
+ GLenum type,
+ GLenum severity,
+ GLsizei count,
+ const GLuint *ids,
+ GLboolean enabled)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDebugMessageControlKHR,
+ "context = %d, source = %s, type = %s, severity = %s, count = %d, ids = 0x%016" PRIxPTR
+ ", enabled = %s",
+ CID(context), GLenumToString(GLESEnum::DebugSource, source),
+ GLenumToString(GLESEnum::DebugType, type),
+ GLenumToString(GLESEnum::DebugSeverity, severity), count, (uintptr_t)ids,
+ GLbooleanToString(enabled));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateDebugMessageControlKHR(context, angle::EntryPoint::GLDebugMessageControlKHR,
+ source, type, severity, count, ids, enabled));
+ if (isCallValid)
+ {
+ context->debugMessageControl(source, type, severity, count, ids, enabled);
+ }
+ ANGLE_CAPTURE_GL(DebugMessageControlKHR, isCallValid, context, source, type, severity,
+ count, ids, enabled);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DebugMessageInsertKHR(GLenum source,
+ GLenum type,
+ GLuint id,
+ GLenum severity,
+ GLsizei length,
+ const GLchar *buf)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDebugMessageInsertKHR,
+ "context = %d, source = %s, type = %s, id = %u, severity = %s, length = %d, buf = "
+ "0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::DebugSource, source),
+ GLenumToString(GLESEnum::DebugType, type), id,
+ GLenumToString(GLESEnum::DebugSeverity, severity), length, (uintptr_t)buf);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateDebugMessageInsertKHR(context, angle::EntryPoint::GLDebugMessageInsertKHR,
+ source, type, id, severity, length, buf));
+ if (isCallValid)
+ {
+ context->debugMessageInsert(source, type, id, severity, length, buf);
+ }
+ ANGLE_CAPTURE_GL(DebugMessageInsertKHR, isCallValid, context, source, type, id, severity,
+ length, buf);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+GLuint GL_APIENTRY GL_GetDebugMessageLogKHR(GLuint count,
+ GLsizei bufSize,
+ GLenum *sources,
+ GLenum *types,
+ GLuint *ids,
+ GLenum *severities,
+ GLsizei *lengths,
+ GLchar *messageLog)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetDebugMessageLogKHR,
+ "context = %d, count = %u, bufSize = %d, sources = 0x%016" PRIxPTR
+ ", types = 0x%016" PRIxPTR ", ids = 0x%016" PRIxPTR ", severities = 0x%016" PRIxPTR
+ ", lengths = 0x%016" PRIxPTR ", messageLog = 0x%016" PRIxPTR "",
+ CID(context), count, bufSize, (uintptr_t)sources, (uintptr_t)types, (uintptr_t)ids,
+ (uintptr_t)severities, (uintptr_t)lengths, (uintptr_t)messageLog);
+
+ GLuint returnValue;
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetDebugMessageLogKHR(
+ context, angle::EntryPoint::GLGetDebugMessageLogKHR, count, bufSize,
+ sources, types, ids, severities, lengths, messageLog));
+ if (isCallValid)
+ {
+ returnValue = context->getDebugMessageLog(count, bufSize, sources, types, ids,
+ severities, lengths, messageLog);
+ }
+ else
+ {
+ returnValue =
+ GetDefaultReturnValue<angle::EntryPoint::GLGetDebugMessageLogKHR, GLuint>();
+ }
+ ANGLE_CAPTURE_GL(GetDebugMessageLogKHR, isCallValid, context, count, bufSize, sources,
+ types, ids, severities, lengths, messageLog, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLGetDebugMessageLogKHR, GLuint>();
+ }
+ return returnValue;
+}
+
+void GL_APIENTRY GL_GetObjectLabelKHR(GLenum identifier,
+ GLuint name,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *label)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetObjectLabelKHR,
+ "context = %d, identifier = %s, name = %u, bufSize = %d, length = 0x%016" PRIxPTR
+ ", label = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, identifier), name, bufSize,
+ (uintptr_t)length, (uintptr_t)label);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetObjectLabelKHR(context, angle::EntryPoint::GLGetObjectLabelKHR, identifier,
+ name, bufSize, length, label));
+ if (isCallValid)
+ {
+ context->getObjectLabel(identifier, name, bufSize, length, label);
+ }
+ ANGLE_CAPTURE_GL(GetObjectLabelKHR, isCallValid, context, identifier, name, bufSize, length,
+ label);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetObjectPtrLabelKHR(const void *ptr,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *label)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetObjectPtrLabelKHR,
+ "context = %d, ptr = 0x%016" PRIxPTR ", bufSize = %d, length = 0x%016" PRIxPTR
+ ", label = 0x%016" PRIxPTR "",
+ CID(context), (uintptr_t)ptr, bufSize, (uintptr_t)length, (uintptr_t)label);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetObjectPtrLabelKHR(context, angle::EntryPoint::GLGetObjectPtrLabelKHR, ptr,
+ bufSize, length, label));
+ if (isCallValid)
+ {
+ context->getObjectPtrLabel(ptr, bufSize, length, label);
+ }
+ ANGLE_CAPTURE_GL(GetObjectPtrLabelKHR, isCallValid, context, ptr, bufSize, length, label);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetPointervKHR(GLenum pname, void **params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetPointervKHR, "context = %d, pname = %s, params = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::AllEnums, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetPointervKHR(context, angle::EntryPoint::GLGetPointervKHR, pname, params));
+ if (isCallValid)
+ {
+ context->getPointerv(pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetPointervKHR, isCallValid, context, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ObjectLabelKHR(GLenum identifier,
+ GLuint name,
+ GLsizei length,
+ const GLchar *label)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLObjectLabelKHR,
+ "context = %d, identifier = %s, name = %u, length = %d, label = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::ObjectIdentifier, identifier), name, length,
+ (uintptr_t)label);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateObjectLabelKHR(context, angle::EntryPoint::GLObjectLabelKHR,
+ identifier, name, length, label));
+ if (isCallValid)
+ {
+ context->objectLabel(identifier, name, length, label);
+ }
+ ANGLE_CAPTURE_GL(ObjectLabelKHR, isCallValid, context, identifier, name, length, label);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ObjectPtrLabelKHR(const void *ptr, GLsizei length, const GLchar *label)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLObjectPtrLabelKHR,
+ "context = %d, ptr = 0x%016" PRIxPTR ", length = %d, label = 0x%016" PRIxPTR "",
+ CID(context), (uintptr_t)ptr, length, (uintptr_t)label);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateObjectPtrLabelKHR(context, angle::EntryPoint::GLObjectPtrLabelKHR, ptr, length,
+ label));
+ if (isCallValid)
+ {
+ context->objectPtrLabel(ptr, length, label);
+ }
+ ANGLE_CAPTURE_GL(ObjectPtrLabelKHR, isCallValid, context, ptr, length, label);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_PopDebugGroupKHR()
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLPopDebugGroupKHR, "context = %d", CID(context));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidatePopDebugGroupKHR(context, angle::EntryPoint::GLPopDebugGroupKHR));
+ if (isCallValid)
+ {
+ context->popDebugGroup();
+ }
+ ANGLE_CAPTURE_GL(PopDebugGroupKHR, isCallValid, context);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_PushDebugGroupKHR(GLenum source,
+ GLuint id,
+ GLsizei length,
+ const GLchar *message)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLPushDebugGroupKHR,
+ "context = %d, source = %s, id = %u, length = %d, message = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::DebugSource, source), id, length,
+ (uintptr_t)message);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidatePushDebugGroupKHR(context, angle::EntryPoint::GLPushDebugGroupKHR, source, id,
+ length, message));
+ if (isCallValid)
+ {
+ context->pushDebugGroup(source, id, length, message);
+ }
+ ANGLE_CAPTURE_GL(PushDebugGroupKHR, isCallValid, context, source, id, length, message);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_KHR_no_error
+
+// GL_KHR_parallel_shader_compile
+void GL_APIENTRY GL_MaxShaderCompilerThreadsKHR(GLuint count)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLMaxShaderCompilerThreadsKHR, "context = %d, count = %u", CID(context), count);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateMaxShaderCompilerThreadsKHR(
+ context, angle::EntryPoint::GLMaxShaderCompilerThreadsKHR, count));
+ if (isCallValid)
+ {
+ context->maxShaderCompilerThreads(count);
+ }
+ ANGLE_CAPTURE_GL(MaxShaderCompilerThreadsKHR, isCallValid, context, count);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_KHR_robust_buffer_access_behavior
+
+// GL_KHR_texture_compression_astc_hdr
+
+// GL_KHR_texture_compression_astc_ldr
+
+// GL_KHR_texture_compression_astc_sliced_3d
+
+// GL_MESA_framebuffer_flip_y
+void GL_APIENTRY GL_FramebufferParameteriMESA(GLenum target, GLenum pname, GLint param)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLFramebufferParameteriMESA, "context = %d, target = %s, pname = %s, param = %d",
+ CID(context), GLenumToString(GLESEnum::FramebufferTarget, target),
+ GLenumToString(GLESEnum::FramebufferParameterName, pname), param);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateFramebufferParameteriMESA(
+ context, angle::EntryPoint::GLFramebufferParameteriMESA, target, pname, param));
+ if (isCallValid)
+ {
+ context->framebufferParameteriMESA(target, pname, param);
+ }
+ ANGLE_CAPTURE_GL(FramebufferParameteriMESA, isCallValid, context, target, pname, param);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetFramebufferParameterivMESA(GLenum target, GLenum pname, GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetFramebufferParameterivMESA,
+ "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::FramebufferTarget, target),
+ GLenumToString(GLESEnum::FramebufferAttachmentParameterName, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetFramebufferParameterivMESA(
+ context, angle::EntryPoint::GLGetFramebufferParameterivMESA, target,
+ pname, params));
+ if (isCallValid)
+ {
+ context->getFramebufferParameterivMESA(target, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetFramebufferParameterivMESA, isCallValid, context, target, pname,
+ params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_NV_fence
+void GL_APIENTRY GL_DeleteFencesNV(GLsizei n, const GLuint *fences)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDeleteFencesNV, "context = %d, n = %d, fences = 0x%016" PRIxPTR "",
+ CID(context), n, (uintptr_t)fences);
+
+ if (context)
+ {
+ const FenceNVID *fencesPacked = PackParam<const FenceNVID *>(fences);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateDeleteFencesNV(context, angle::EntryPoint::GLDeleteFencesNV, n, fencesPacked));
+ if (isCallValid)
+ {
+ context->deleteFencesNV(n, fencesPacked);
+ }
+ ANGLE_CAPTURE_GL(DeleteFencesNV, isCallValid, context, n, fencesPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_FinishFenceNV(GLuint fence)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLFinishFenceNV, "context = %d, fence = %u", CID(context), fence);
+
+ if (context)
+ {
+ FenceNVID fencePacked = PackParam<FenceNVID>(fence);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateFinishFenceNV(context, angle::EntryPoint::GLFinishFenceNV, fencePacked));
+ if (isCallValid)
+ {
+ context->finishFenceNV(fencePacked);
+ }
+ ANGLE_CAPTURE_GL(FinishFenceNV, isCallValid, context, fencePacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GenFencesNV(GLsizei n, GLuint *fences)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGenFencesNV, "context = %d, n = %d, fences = 0x%016" PRIxPTR "", CID(context),
+ n, (uintptr_t)fences);
+
+ if (context)
+ {
+ FenceNVID *fencesPacked = PackParam<FenceNVID *>(fences);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGenFencesNV(context, angle::EntryPoint::GLGenFencesNV, n, fencesPacked));
+ if (isCallValid)
+ {
+ context->genFencesNV(n, fencesPacked);
+ }
+ ANGLE_CAPTURE_GL(GenFencesNV, isCallValid, context, n, fencesPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetFenceivNV(GLuint fence, GLenum pname, GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetFenceivNV,
+ "context = %d, fence = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context), fence,
+ GLenumToString(GLESEnum::AllEnums, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ FenceNVID fencePacked = PackParam<FenceNVID>(fence);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetFenceivNV(context, angle::EntryPoint::GLGetFenceivNV,
+ fencePacked, pname, params));
+ if (isCallValid)
+ {
+ context->getFenceivNV(fencePacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetFenceivNV, isCallValid, context, fencePacked, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+GLboolean GL_APIENTRY GL_IsFenceNV(GLuint fence)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLIsFenceNV, "context = %d, fence = %u", CID(context), fence);
+
+ GLboolean returnValue;
+ if (context)
+ {
+ FenceNVID fencePacked = PackParam<FenceNVID>(fence);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateIsFenceNV(context, angle::EntryPoint::GLIsFenceNV, fencePacked));
+ if (isCallValid)
+ {
+ returnValue = context->isFenceNV(fencePacked);
+ }
+ else
+ {
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsFenceNV, GLboolean>();
+ }
+ ANGLE_CAPTURE_GL(IsFenceNV, isCallValid, context, fencePacked, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsFenceNV, GLboolean>();
+ }
+ return returnValue;
+}
+
+void GL_APIENTRY GL_SetFenceNV(GLuint fence, GLenum condition)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLSetFenceNV, "context = %d, fence = %u, condition = %s", CID(context), fence,
+ GLenumToString(GLESEnum::AllEnums, condition));
+
+ if (context)
+ {
+ FenceNVID fencePacked = PackParam<FenceNVID>(fence);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateSetFenceNV(context, angle::EntryPoint::GLSetFenceNV, fencePacked, condition));
+ if (isCallValid)
+ {
+ context->setFenceNV(fencePacked, condition);
+ }
+ ANGLE_CAPTURE_GL(SetFenceNV, isCallValid, context, fencePacked, condition);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+GLboolean GL_APIENTRY GL_TestFenceNV(GLuint fence)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTestFenceNV, "context = %d, fence = %u", CID(context), fence);
+
+ GLboolean returnValue;
+ if (context)
+ {
+ FenceNVID fencePacked = PackParam<FenceNVID>(fence);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateTestFenceNV(context, angle::EntryPoint::GLTestFenceNV, fencePacked));
+ if (isCallValid)
+ {
+ returnValue = context->testFenceNV(fencePacked);
+ }
+ else
+ {
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLTestFenceNV, GLboolean>();
+ }
+ ANGLE_CAPTURE_GL(TestFenceNV, isCallValid, context, fencePacked, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLTestFenceNV, GLboolean>();
+ }
+ return returnValue;
+}
+
+// GL_NV_framebuffer_blit
+void GL_APIENTRY GL_BlitFramebufferNV(GLint srcX0,
+ GLint srcY0,
+ GLint srcX1,
+ GLint srcY1,
+ GLint dstX0,
+ GLint dstY0,
+ GLint dstX1,
+ GLint dstY1,
+ GLbitfield mask,
+ GLenum filter)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBlitFramebufferNV,
+ "context = %d, srcX0 = %d, srcY0 = %d, srcX1 = %d, srcY1 = %d, dstX0 = %d, dstY0 = %d, "
+ "dstX1 = %d, dstY1 = %d, mask = %s, filter = %s",
+ CID(context), srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,
+ GLbitfieldToString(GLESEnum::ClearBufferMask, mask).c_str(),
+ GLenumToString(GLESEnum::BlitFramebufferFilter, filter));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateBlitFramebufferNV(
+ context, angle::EntryPoint::GLBlitFramebufferNV, srcX0, srcY0,
+ srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter));
+ if (isCallValid)
+ {
+ context->blitFramebufferNV(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask,
+ filter);
+ }
+ ANGLE_CAPTURE_GL(BlitFramebufferNV, isCallValid, context, srcX0, srcY0, srcX1, srcY1, dstX0,
+ dstY0, dstX1, dstY1, mask, filter);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_NV_pixel_buffer_object
+
+// GL_NV_read_depth
+
+// GL_NV_read_depth_stencil
+
+// GL_NV_read_stencil
+
+// GL_NV_robustness_video_memory_purge
+
+// GL_NV_shader_noperspective_interpolation
+
+// GL_OES_EGL_image
+void GL_APIENTRY GL_EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLEGLImageTargetRenderbufferStorageOES,
+ "context = %d, target = %s, image = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::AllEnums, target), (uintptr_t)image);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateEGLImageTargetRenderbufferStorageOES(
+ context, angle::EntryPoint::GLEGLImageTargetRenderbufferStorageOES,
+ target, image));
+ if (isCallValid)
+ {
+ context->eGLImageTargetRenderbufferStorage(target, image);
+ }
+ ANGLE_CAPTURE_GL(EGLImageTargetRenderbufferStorageOES, isCallValid, context, target, image);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLEGLImageTargetTexture2DOES,
+ "context = %d, target = %s, image = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::AllEnums, target), (uintptr_t)image);
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateEGLImageTargetTexture2DOES(
+ context, angle::EntryPoint::GLEGLImageTargetTexture2DOES, targetPacked, image));
+ if (isCallValid)
+ {
+ context->eGLImageTargetTexture2D(targetPacked, image);
+ }
+ ANGLE_CAPTURE_GL(EGLImageTargetTexture2DOES, isCallValid, context, targetPacked, image);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_OES_EGL_image_external
+
+// GL_OES_EGL_image_external_essl3
+
+// GL_OES_compressed_ETC1_RGB8_texture
+
+// GL_OES_compressed_paletted_texture
+
+// GL_OES_copy_image
+void GL_APIENTRY GL_CopyImageSubDataOES(GLuint srcName,
+ GLenum srcTarget,
+ GLint srcLevel,
+ GLint srcX,
+ GLint srcY,
+ GLint srcZ,
+ GLuint dstName,
+ GLenum dstTarget,
+ GLint dstLevel,
+ GLint dstX,
+ GLint dstY,
+ GLint dstZ,
+ GLsizei srcWidth,
+ GLsizei srcHeight,
+ GLsizei srcDepth)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLCopyImageSubDataOES,
+ "context = %d, srcName = %u, srcTarget = %s, srcLevel = %d, srcX = %d, srcY = %d, srcZ = "
+ "%d, dstName = %u, dstTarget = %s, dstLevel = %d, dstX = %d, dstY = %d, dstZ = %d, "
+ "srcWidth = %d, srcHeight = %d, srcDepth = %d",
+ CID(context), srcName, GLenumToString(GLESEnum::CopyBufferSubDataTarget, srcTarget),
+ srcLevel, srcX, srcY, srcZ, dstName,
+ GLenumToString(GLESEnum::CopyBufferSubDataTarget, dstTarget), dstLevel, dstX, dstY, dstZ,
+ srcWidth, srcHeight, srcDepth);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateCopyImageSubDataOES(
+ context, angle::EntryPoint::GLCopyImageSubDataOES, srcName,
+ srcTarget, srcLevel, srcX, srcY, srcZ, dstName, dstTarget, dstLevel,
+ dstX, dstY, dstZ, srcWidth, srcHeight, srcDepth));
+ if (isCallValid)
+ {
+ context->copyImageSubData(srcName, srcTarget, srcLevel, srcX, srcY, srcZ, dstName,
+ dstTarget, dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight,
+ srcDepth);
+ }
+ ANGLE_CAPTURE_GL(CopyImageSubDataOES, isCallValid, context, srcName, srcTarget, srcLevel,
+ srcX, srcY, srcZ, dstName, dstTarget, dstLevel, dstX, dstY, dstZ, srcWidth,
+ srcHeight, srcDepth);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_OES_depth24
+
+// GL_OES_depth32
+
+// GL_OES_depth_texture
+
+// GL_OES_draw_buffers_indexed
+void GL_APIENTRY GL_BlendEquationSeparateiOES(GLuint buf, GLenum modeRGB, GLenum modeAlpha)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBlendEquationSeparateiOES,
+ "context = %d, buf = %u, modeRGB = %s, modeAlpha = %s", CID(context), buf,
+ GLenumToString(GLESEnum::BlendEquationModeEXT, modeRGB),
+ GLenumToString(GLESEnum::BlendEquationModeEXT, modeAlpha));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateBlendEquationSeparateiOES(
+ context, angle::EntryPoint::GLBlendEquationSeparateiOES, buf, modeRGB, modeAlpha));
+ if (isCallValid)
+ {
+ context->blendEquationSeparatei(buf, modeRGB, modeAlpha);
+ }
+ ANGLE_CAPTURE_GL(BlendEquationSeparateiOES, isCallValid, context, buf, modeRGB, modeAlpha);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_BlendEquationiOES(GLuint buf, GLenum mode)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBlendEquationiOES, "context = %d, buf = %u, mode = %s", CID(context), buf,
+ GLenumToString(GLESEnum::BlendEquationModeEXT, mode));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateBlendEquationiOES(context, angle::EntryPoint::GLBlendEquationiOES, buf, mode));
+ if (isCallValid)
+ {
+ context->blendEquationi(buf, mode);
+ }
+ ANGLE_CAPTURE_GL(BlendEquationiOES, isCallValid, context, buf, mode);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY
+GL_BlendFuncSeparateiOES(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBlendFuncSeparateiOES,
+ "context = %d, buf = %u, srcRGB = %s, dstRGB = %s, srcAlpha = %s, dstAlpha = %s",
+ CID(context), buf, GLenumToString(GLESEnum::BlendingFactor, srcRGB),
+ GLenumToString(GLESEnum::BlendingFactor, dstRGB),
+ GLenumToString(GLESEnum::BlendingFactor, srcAlpha),
+ GLenumToString(GLESEnum::BlendingFactor, dstAlpha));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateBlendFuncSeparateiOES(context, angle::EntryPoint::GLBlendFuncSeparateiOES, buf,
+ srcRGB, dstRGB, srcAlpha, dstAlpha));
+ if (isCallValid)
+ {
+ context->blendFuncSeparatei(buf, srcRGB, dstRGB, srcAlpha, dstAlpha);
+ }
+ ANGLE_CAPTURE_GL(BlendFuncSeparateiOES, isCallValid, context, buf, srcRGB, dstRGB, srcAlpha,
+ dstAlpha);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_BlendFunciOES(GLuint buf, GLenum src, GLenum dst)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBlendFunciOES, "context = %d, buf = %u, src = %s, dst = %s", CID(context), buf,
+ GLenumToString(GLESEnum::BlendingFactor, src),
+ GLenumToString(GLESEnum::BlendingFactor, dst));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateBlendFunciOES(context, angle::EntryPoint::GLBlendFunciOES, buf, src, dst));
+ if (isCallValid)
+ {
+ context->blendFunci(buf, src, dst);
+ }
+ ANGLE_CAPTURE_GL(BlendFunciOES, isCallValid, context, buf, src, dst);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ColorMaskiOES(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLColorMaskiOES, "context = %d, index = %u, r = %s, g = %s, b = %s, a = %s",
+ CID(context), index, GLbooleanToString(r), GLbooleanToString(g), GLbooleanToString(b),
+ GLbooleanToString(a));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateColorMaskiOES(context, angle::EntryPoint::GLColorMaskiOES, index, r, g, b, a));
+ if (isCallValid)
+ {
+ context->colorMaski(index, r, g, b, a);
+ }
+ ANGLE_CAPTURE_GL(ColorMaskiOES, isCallValid, context, index, r, g, b, a);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DisableiOES(GLenum target, GLuint index)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDisableiOES, "context = %d, target = %s, index = %u", CID(context),
+ GLenumToString(GLESEnum::EnableCap, target), index);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateDisableiOES(context, angle::EntryPoint::GLDisableiOES, target, index));
+ if (isCallValid)
+ {
+ context->disablei(target, index);
+ }
+ ANGLE_CAPTURE_GL(DisableiOES, isCallValid, context, target, index);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_EnableiOES(GLenum target, GLuint index)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLEnableiOES, "context = %d, target = %s, index = %u", CID(context),
+ GLenumToString(GLESEnum::EnableCap, target), index);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateEnableiOES(context, angle::EntryPoint::GLEnableiOES, target, index));
+ if (isCallValid)
+ {
+ context->enablei(target, index);
+ }
+ ANGLE_CAPTURE_GL(EnableiOES, isCallValid, context, target, index);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+GLboolean GL_APIENTRY GL_IsEnablediOES(GLenum target, GLuint index)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLIsEnablediOES, "context = %d, target = %s, index = %u", CID(context),
+ GLenumToString(GLESEnum::EnableCap, target), index);
+
+ GLboolean returnValue;
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateIsEnablediOES(context, angle::EntryPoint::GLIsEnablediOES, target, index));
+ if (isCallValid)
+ {
+ returnValue = context->isEnabledi(target, index);
+ }
+ else
+ {
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsEnablediOES, GLboolean>();
+ }
+ ANGLE_CAPTURE_GL(IsEnablediOES, isCallValid, context, target, index, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsEnablediOES, GLboolean>();
+ }
+ return returnValue;
+}
+
+// GL_OES_draw_elements_base_vertex
+void GL_APIENTRY GL_DrawElementsBaseVertexOES(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLint basevertex)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDrawElementsBaseVertexOES,
+ "context = %d, mode = %s, count = %d, type = %s, indices = 0x%016" PRIxPTR
+ ", basevertex = %d",
+ CID(context), GLenumToString(GLESEnum::PrimitiveType, mode), count,
+ GLenumToString(GLESEnum::DrawElementsType, type), (uintptr_t)indices, basevertex);
+
+ if (context)
+ {
+ PrimitiveMode modePacked = PackParam<PrimitiveMode>(mode);
+ DrawElementsType typePacked = PackParam<DrawElementsType>(type);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateDrawElementsBaseVertexOES(
+ context, angle::EntryPoint::GLDrawElementsBaseVertexOES, modePacked,
+ count, typePacked, indices, basevertex));
+ if (isCallValid)
+ {
+ context->drawElementsBaseVertex(modePacked, count, typePacked, indices, basevertex);
+ }
+ ANGLE_CAPTURE_GL(DrawElementsBaseVertexOES, isCallValid, context, modePacked, count,
+ typePacked, indices, basevertex);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DrawElementsInstancedBaseVertexOES(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLsizei instancecount,
+ GLint basevertex)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDrawElementsInstancedBaseVertexOES,
+ "context = %d, mode = %s, count = %d, type = %s, indices = 0x%016" PRIxPTR
+ ", instancecount = %d, basevertex = %d",
+ CID(context), GLenumToString(GLESEnum::PrimitiveType, mode), count,
+ GLenumToString(GLESEnum::DrawElementsType, type), (uintptr_t)indices, instancecount,
+ basevertex);
+
+ if (context)
+ {
+ PrimitiveMode modePacked = PackParam<PrimitiveMode>(mode);
+ DrawElementsType typePacked = PackParam<DrawElementsType>(type);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateDrawElementsInstancedBaseVertexOES(
+ context, angle::EntryPoint::GLDrawElementsInstancedBaseVertexOES,
+ modePacked, count, typePacked, indices, instancecount, basevertex));
+ if (isCallValid)
+ {
+ context->drawElementsInstancedBaseVertex(modePacked, count, typePacked, indices,
+ instancecount, basevertex);
+ }
+ ANGLE_CAPTURE_GL(DrawElementsInstancedBaseVertexOES, isCallValid, context, modePacked,
+ count, typePacked, indices, instancecount, basevertex);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DrawRangeElementsBaseVertexOES(GLenum mode,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLint basevertex)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDrawRangeElementsBaseVertexOES,
+ "context = %d, mode = %s, start = %u, end = %u, count = %d, type = %s, indices = "
+ "0x%016" PRIxPTR ", basevertex = %d",
+ CID(context), GLenumToString(GLESEnum::PrimitiveType, mode), start, end, count,
+ GLenumToString(GLESEnum::DrawElementsType, type), (uintptr_t)indices, basevertex);
+
+ if (context)
+ {
+ PrimitiveMode modePacked = PackParam<PrimitiveMode>(mode);
+ DrawElementsType typePacked = PackParam<DrawElementsType>(type);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateDrawRangeElementsBaseVertexOES(
+ context, angle::EntryPoint::GLDrawRangeElementsBaseVertexOES,
+ modePacked, start, end, count, typePacked, indices, basevertex));
+ if (isCallValid)
+ {
+ context->drawRangeElementsBaseVertex(modePacked, start, end, count, typePacked, indices,
+ basevertex);
+ }
+ ANGLE_CAPTURE_GL(DrawRangeElementsBaseVertexOES, isCallValid, context, modePacked, start,
+ end, count, typePacked, indices, basevertex);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// MultiDrawElementsBaseVertexEXT is already defined.
+
+// GL_OES_draw_texture
+void GL_APIENTRY GL_DrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDrawTexfOES, "context = %d, x = %f, y = %f, z = %f, width = %f, height = %f",
+ CID(context), x, y, z, width, height);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateDrawTexfOES(context, angle::EntryPoint::GLDrawTexfOES, x, y, z,
+ width, height));
+ if (isCallValid)
+ {
+ context->drawTexf(x, y, z, width, height);
+ }
+ ANGLE_CAPTURE_GL(DrawTexfOES, isCallValid, context, x, y, z, width, height);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DrawTexfvOES(const GLfloat *coords)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDrawTexfvOES, "context = %d, coords = 0x%016" PRIxPTR "", CID(context),
+ (uintptr_t)coords);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateDrawTexfvOES(context, angle::EntryPoint::GLDrawTexfvOES, coords));
+ if (isCallValid)
+ {
+ context->drawTexfv(coords);
+ }
+ ANGLE_CAPTURE_GL(DrawTexfvOES, isCallValid, context, coords);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDrawTexiOES, "context = %d, x = %d, y = %d, z = %d, width = %d, height = %d",
+ CID(context), x, y, z, width, height);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateDrawTexiOES(context, angle::EntryPoint::GLDrawTexiOES, x, y, z,
+ width, height));
+ if (isCallValid)
+ {
+ context->drawTexi(x, y, z, width, height);
+ }
+ ANGLE_CAPTURE_GL(DrawTexiOES, isCallValid, context, x, y, z, width, height);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DrawTexivOES(const GLint *coords)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDrawTexivOES, "context = %d, coords = 0x%016" PRIxPTR "", CID(context),
+ (uintptr_t)coords);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateDrawTexivOES(context, angle::EntryPoint::GLDrawTexivOES, coords));
+ if (isCallValid)
+ {
+ context->drawTexiv(coords);
+ }
+ ANGLE_CAPTURE_GL(DrawTexivOES, isCallValid, context, coords);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DrawTexsOES(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDrawTexsOES, "context = %d, x = %d, y = %d, z = %d, width = %d, height = %d",
+ CID(context), x, y, z, width, height);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateDrawTexsOES(context, angle::EntryPoint::GLDrawTexsOES, x, y, z,
+ width, height));
+ if (isCallValid)
+ {
+ context->drawTexs(x, y, z, width, height);
+ }
+ ANGLE_CAPTURE_GL(DrawTexsOES, isCallValid, context, x, y, z, width, height);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DrawTexsvOES(const GLshort *coords)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDrawTexsvOES, "context = %d, coords = 0x%016" PRIxPTR "", CID(context),
+ (uintptr_t)coords);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateDrawTexsvOES(context, angle::EntryPoint::GLDrawTexsvOES, coords));
+ if (isCallValid)
+ {
+ context->drawTexsv(coords);
+ }
+ ANGLE_CAPTURE_GL(DrawTexsvOES, isCallValid, context, coords);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDrawTexxOES,
+ "context = %d, x = 0x%X, y = 0x%X, z = 0x%X, width = 0x%X, height = 0x%X", CID(context),
+ x, y, z, width, height);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateDrawTexxOES(context, angle::EntryPoint::GLDrawTexxOES, x, y, z,
+ width, height));
+ if (isCallValid)
+ {
+ context->drawTexx(x, y, z, width, height);
+ }
+ ANGLE_CAPTURE_GL(DrawTexxOES, isCallValid, context, x, y, z, width, height);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DrawTexxvOES(const GLfixed *coords)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDrawTexxvOES, "context = %d, coords = 0x%016" PRIxPTR "", CID(context),
+ (uintptr_t)coords);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateDrawTexxvOES(context, angle::EntryPoint::GLDrawTexxvOES, coords));
+ if (isCallValid)
+ {
+ context->drawTexxv(coords);
+ }
+ ANGLE_CAPTURE_GL(DrawTexxvOES, isCallValid, context, coords);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_OES_element_index_uint
+
+// GL_OES_fbo_render_mipmap
+
+// GL_OES_framebuffer_object
+void GL_APIENTRY GL_BindFramebufferOES(GLenum target, GLuint framebuffer)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBindFramebufferOES, "context = %d, target = %s, framebuffer = %u",
+ CID(context), GLenumToString(GLESEnum::FramebufferTarget, target), framebuffer);
+
+ if (context)
+ {
+ FramebufferID framebufferPacked = PackParam<FramebufferID>(framebuffer);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateBindFramebufferOES(context, angle::EntryPoint::GLBindFramebufferOES, target,
+ framebufferPacked));
+ if (isCallValid)
+ {
+ context->bindFramebuffer(target, framebufferPacked);
+ }
+ ANGLE_CAPTURE_GL(BindFramebufferOES, isCallValid, context, target, framebufferPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_BindRenderbufferOES(GLenum target, GLuint renderbuffer)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBindRenderbufferOES, "context = %d, target = %s, renderbuffer = %u",
+ CID(context), GLenumToString(GLESEnum::RenderbufferTarget, target), renderbuffer);
+
+ if (context)
+ {
+ RenderbufferID renderbufferPacked = PackParam<RenderbufferID>(renderbuffer);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateBindRenderbufferOES(context, angle::EntryPoint::GLBindRenderbufferOES, target,
+ renderbufferPacked));
+ if (isCallValid)
+ {
+ context->bindRenderbuffer(target, renderbufferPacked);
+ }
+ ANGLE_CAPTURE_GL(BindRenderbufferOES, isCallValid, context, target, renderbufferPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+GLenum GL_APIENTRY GL_CheckFramebufferStatusOES(GLenum target)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLCheckFramebufferStatusOES, "context = %d, target = %s", CID(context),
+ GLenumToString(GLESEnum::FramebufferTarget, target));
+
+ GLenum returnValue;
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateCheckFramebufferStatusOES(
+ context, angle::EntryPoint::GLCheckFramebufferStatusOES, target));
+ if (isCallValid)
+ {
+ returnValue = context->checkFramebufferStatus(target);
+ }
+ else
+ {
+ returnValue =
+ GetDefaultReturnValue<angle::EntryPoint::GLCheckFramebufferStatusOES, GLenum>();
+ }
+ ANGLE_CAPTURE_GL(CheckFramebufferStatusOES, isCallValid, context, target, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue =
+ GetDefaultReturnValue<angle::EntryPoint::GLCheckFramebufferStatusOES, GLenum>();
+ }
+ return returnValue;
+}
+
+void GL_APIENTRY GL_DeleteFramebuffersOES(GLsizei n, const GLuint *framebuffers)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDeleteFramebuffersOES,
+ "context = %d, n = %d, framebuffers = 0x%016" PRIxPTR "", CID(context), n,
+ (uintptr_t)framebuffers);
+
+ if (context)
+ {
+ const FramebufferID *framebuffersPacked = PackParam<const FramebufferID *>(framebuffers);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateDeleteFramebuffersOES(context, angle::EntryPoint::GLDeleteFramebuffersOES, n,
+ framebuffersPacked));
+ if (isCallValid)
+ {
+ context->deleteFramebuffers(n, framebuffersPacked);
+ }
+ ANGLE_CAPTURE_GL(DeleteFramebuffersOES, isCallValid, context, n, framebuffersPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DeleteRenderbuffersOES(GLsizei n, const GLuint *renderbuffers)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDeleteRenderbuffersOES,
+ "context = %d, n = %d, renderbuffers = 0x%016" PRIxPTR "", CID(context), n,
+ (uintptr_t)renderbuffers);
+
+ if (context)
+ {
+ const RenderbufferID *renderbuffersPacked =
+ PackParam<const RenderbufferID *>(renderbuffers);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateDeleteRenderbuffersOES(context, angle::EntryPoint::GLDeleteRenderbuffersOES, n,
+ renderbuffersPacked));
+ if (isCallValid)
+ {
+ context->deleteRenderbuffers(n, renderbuffersPacked);
+ }
+ ANGLE_CAPTURE_GL(DeleteRenderbuffersOES, isCallValid, context, n, renderbuffersPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_FramebufferRenderbufferOES(GLenum target,
+ GLenum attachment,
+ GLenum renderbuffertarget,
+ GLuint renderbuffer)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLFramebufferRenderbufferOES,
+ "context = %d, target = %s, attachment = %s, renderbuffertarget = %s, renderbuffer = %u",
+ CID(context), GLenumToString(GLESEnum::FramebufferTarget, target),
+ GLenumToString(GLESEnum::FramebufferAttachment, attachment),
+ GLenumToString(GLESEnum::RenderbufferTarget, renderbuffertarget), renderbuffer);
+
+ if (context)
+ {
+ RenderbufferID renderbufferPacked = PackParam<RenderbufferID>(renderbuffer);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateFramebufferRenderbufferOES(
+ context, angle::EntryPoint::GLFramebufferRenderbufferOES, target,
+ attachment, renderbuffertarget, renderbufferPacked));
+ if (isCallValid)
+ {
+ context->framebufferRenderbuffer(target, attachment, renderbuffertarget,
+ renderbufferPacked);
+ }
+ ANGLE_CAPTURE_GL(FramebufferRenderbufferOES, isCallValid, context, target, attachment,
+ renderbuffertarget, renderbufferPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_FramebufferTexture2DOES(GLenum target,
+ GLenum attachment,
+ GLenum textarget,
+ GLuint texture,
+ GLint level)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLFramebufferTexture2DOES,
+ "context = %d, target = %s, attachment = %s, textarget = %s, texture = %u, level = %d",
+ CID(context), GLenumToString(GLESEnum::FramebufferTarget, target),
+ GLenumToString(GLESEnum::FramebufferAttachment, attachment),
+ GLenumToString(GLESEnum::TextureTarget, textarget), texture, level);
+
+ if (context)
+ {
+ TextureTarget textargetPacked = PackParam<TextureTarget>(textarget);
+ TextureID texturePacked = PackParam<TextureID>(texture);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateFramebufferTexture2DOES(
+ context, angle::EntryPoint::GLFramebufferTexture2DOES, target,
+ attachment, textargetPacked, texturePacked, level));
+ if (isCallValid)
+ {
+ context->framebufferTexture2D(target, attachment, textargetPacked, texturePacked,
+ level);
+ }
+ ANGLE_CAPTURE_GL(FramebufferTexture2DOES, isCallValid, context, target, attachment,
+ textargetPacked, texturePacked, level);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GenFramebuffersOES(GLsizei n, GLuint *framebuffers)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGenFramebuffersOES, "context = %d, n = %d, framebuffers = 0x%016" PRIxPTR "",
+ CID(context), n, (uintptr_t)framebuffers);
+
+ if (context)
+ {
+ FramebufferID *framebuffersPacked = PackParam<FramebufferID *>(framebuffers);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGenFramebuffersOES(context, angle::EntryPoint::GLGenFramebuffersOES, n,
+ framebuffersPacked));
+ if (isCallValid)
+ {
+ context->genFramebuffers(n, framebuffersPacked);
+ }
+ ANGLE_CAPTURE_GL(GenFramebuffersOES, isCallValid, context, n, framebuffersPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GenRenderbuffersOES(GLsizei n, GLuint *renderbuffers)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGenRenderbuffersOES, "context = %d, n = %d, renderbuffers = 0x%016" PRIxPTR "",
+ CID(context), n, (uintptr_t)renderbuffers);
+
+ if (context)
+ {
+ RenderbufferID *renderbuffersPacked = PackParam<RenderbufferID *>(renderbuffers);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGenRenderbuffersOES(context, angle::EntryPoint::GLGenRenderbuffersOES, n,
+ renderbuffersPacked));
+ if (isCallValid)
+ {
+ context->genRenderbuffers(n, renderbuffersPacked);
+ }
+ ANGLE_CAPTURE_GL(GenRenderbuffersOES, isCallValid, context, n, renderbuffersPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GenerateMipmapOES(GLenum target)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGenerateMipmapOES, "context = %d, target = %s", CID(context),
+ GLenumToString(GLESEnum::TextureTarget, target));
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGenerateMipmapOES(
+ context, angle::EntryPoint::GLGenerateMipmapOES, targetPacked));
+ if (isCallValid)
+ {
+ context->generateMipmap(targetPacked);
+ }
+ ANGLE_CAPTURE_GL(GenerateMipmapOES, isCallValid, context, targetPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetFramebufferAttachmentParameterivOES(GLenum target,
+ GLenum attachment,
+ GLenum pname,
+ GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetFramebufferAttachmentParameterivOES,
+ "context = %d, target = %s, attachment = %s, pname = %s, params = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::FramebufferTarget, target),
+ GLenumToString(GLESEnum::FramebufferAttachment, attachment),
+ GLenumToString(GLESEnum::FramebufferAttachmentParameterName, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetFramebufferAttachmentParameterivOES(
+ context, angle::EntryPoint::GLGetFramebufferAttachmentParameterivOES, target,
+ attachment, pname, params));
+ if (isCallValid)
+ {
+ context->getFramebufferAttachmentParameteriv(target, attachment, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetFramebufferAttachmentParameterivOES, isCallValid, context, target,
+ attachment, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetRenderbufferParameterivOES,
+ "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::RenderbufferTarget, target),
+ GLenumToString(GLESEnum::RenderbufferParameterName, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetRenderbufferParameterivOES(
+ context, angle::EntryPoint::GLGetRenderbufferParameterivOES, target,
+ pname, params));
+ if (isCallValid)
+ {
+ context->getRenderbufferParameteriv(target, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetRenderbufferParameterivOES, isCallValid, context, target, pname,
+ params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+GLboolean GL_APIENTRY GL_IsFramebufferOES(GLuint framebuffer)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLIsFramebufferOES, "context = %d, framebuffer = %u", CID(context), framebuffer);
+
+ GLboolean returnValue;
+ if (context)
+ {
+ FramebufferID framebufferPacked = PackParam<FramebufferID>(framebuffer);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateIsFramebufferOES(context, angle::EntryPoint::GLIsFramebufferOES,
+ framebufferPacked));
+ if (isCallValid)
+ {
+ returnValue = context->isFramebuffer(framebufferPacked);
+ }
+ else
+ {
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsFramebufferOES, GLboolean>();
+ }
+ ANGLE_CAPTURE_GL(IsFramebufferOES, isCallValid, context, framebufferPacked, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsFramebufferOES, GLboolean>();
+ }
+ return returnValue;
+}
+
+GLboolean GL_APIENTRY GL_IsRenderbufferOES(GLuint renderbuffer)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLIsRenderbufferOES, "context = %d, renderbuffer = %u", CID(context),
+ renderbuffer);
+
+ GLboolean returnValue;
+ if (context)
+ {
+ RenderbufferID renderbufferPacked = PackParam<RenderbufferID>(renderbuffer);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateIsRenderbufferOES(context, angle::EntryPoint::GLIsRenderbufferOES,
+ renderbufferPacked));
+ if (isCallValid)
+ {
+ returnValue = context->isRenderbuffer(renderbufferPacked);
+ }
+ else
+ {
+ returnValue =
+ GetDefaultReturnValue<angle::EntryPoint::GLIsRenderbufferOES, GLboolean>();
+ }
+ ANGLE_CAPTURE_GL(IsRenderbufferOES, isCallValid, context, renderbufferPacked, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsRenderbufferOES, GLboolean>();
+ }
+ return returnValue;
+}
+
+void GL_APIENTRY GL_RenderbufferStorageOES(GLenum target,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLRenderbufferStorageOES,
+ "context = %d, target = %s, internalformat = %s, width = %d, height = %d", CID(context),
+ GLenumToString(GLESEnum::RenderbufferTarget, target),
+ GLenumToString(GLESEnum::InternalFormat, internalformat), width, height);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateRenderbufferStorageOES(context, angle::EntryPoint::GLRenderbufferStorageOES,
+ target, internalformat, width, height));
+ if (isCallValid)
+ {
+ context->renderbufferStorage(target, internalformat, width, height);
+ }
+ ANGLE_CAPTURE_GL(RenderbufferStorageOES, isCallValid, context, target, internalformat,
+ width, height);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_OES_geometry_shader
+void GL_APIENTRY GL_FramebufferTextureOES(GLenum target,
+ GLenum attachment,
+ GLuint texture,
+ GLint level)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLFramebufferTextureOES,
+ "context = %d, target = %s, attachment = %s, texture = %u, level = %d", CID(context),
+ GLenumToString(GLESEnum::FramebufferTarget, target),
+ GLenumToString(GLESEnum::FramebufferAttachment, attachment), texture, level);
+
+ if (context)
+ {
+ TextureID texturePacked = PackParam<TextureID>(texture);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateFramebufferTextureOES(context, angle::EntryPoint::GLFramebufferTextureOES,
+ target, attachment, texturePacked, level));
+ if (isCallValid)
+ {
+ context->framebufferTexture(target, attachment, texturePacked, level);
+ }
+ ANGLE_CAPTURE_GL(FramebufferTextureOES, isCallValid, context, target, attachment,
+ texturePacked, level);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_OES_get_program_binary
+void GL_APIENTRY GL_GetProgramBinaryOES(GLuint program,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLenum *binaryFormat,
+ void *binary)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetProgramBinaryOES,
+ "context = %d, program = %u, bufSize = %d, length = 0x%016" PRIxPTR
+ ", binaryFormat = 0x%016" PRIxPTR ", binary = 0x%016" PRIxPTR "",
+ CID(context), program, bufSize, (uintptr_t)length, (uintptr_t)binaryFormat,
+ (uintptr_t)binary);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetProgramBinaryOES(context, angle::EntryPoint::GLGetProgramBinaryOES,
+ programPacked, bufSize, length, binaryFormat, binary));
+ if (isCallValid)
+ {
+ context->getProgramBinary(programPacked, bufSize, length, binaryFormat, binary);
+ }
+ ANGLE_CAPTURE_GL(GetProgramBinaryOES, isCallValid, context, programPacked, bufSize, length,
+ binaryFormat, binary);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_ProgramBinaryOES(GLuint program,
+ GLenum binaryFormat,
+ const void *binary,
+ GLint length)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLProgramBinaryOES,
+ "context = %d, program = %u, binaryFormat = %s, binary = 0x%016" PRIxPTR ", length = %d",
+ CID(context), program, GLenumToString(GLESEnum::AllEnums, binaryFormat),
+ (uintptr_t)binary, length);
+
+ if (context)
+ {
+ ShaderProgramID programPacked = PackParam<ShaderProgramID>(program);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateProgramBinaryOES(context, angle::EntryPoint::GLProgramBinaryOES,
+ programPacked, binaryFormat, binary, length));
+ if (isCallValid)
+ {
+ context->programBinary(programPacked, binaryFormat, binary, length);
+ }
+ ANGLE_CAPTURE_GL(ProgramBinaryOES, isCallValid, context, programPacked, binaryFormat,
+ binary, length);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_OES_mapbuffer
+void GL_APIENTRY GL_GetBufferPointervOES(GLenum target, GLenum pname, void **params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetBufferPointervOES,
+ "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::BufferTargetARB, target),
+ GLenumToString(GLESEnum::AllEnums, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ BufferBinding targetPacked = PackParam<BufferBinding>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetBufferPointervOES(context, angle::EntryPoint::GLGetBufferPointervOES,
+ targetPacked, pname, params));
+ if (isCallValid)
+ {
+ context->getBufferPointerv(targetPacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetBufferPointervOES, isCallValid, context, targetPacked, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void *GL_APIENTRY GL_MapBufferOES(GLenum target, GLenum access)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLMapBufferOES, "context = %d, target = %s, access = %s", CID(context),
+ GLenumToString(GLESEnum::BufferTargetARB, target),
+ GLenumToString(GLESEnum::BufferAccessARB, access));
+
+ void *returnValue;
+ if (context)
+ {
+ BufferBinding targetPacked = PackParam<BufferBinding>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateMapBufferOES(context, angle::EntryPoint::GLMapBufferOES,
+ targetPacked, access));
+ if (isCallValid)
+ {
+ returnValue = context->mapBuffer(targetPacked, access);
+ }
+ else
+ {
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLMapBufferOES, void *>();
+ }
+ ANGLE_CAPTURE_GL(MapBufferOES, isCallValid, context, targetPacked, access, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLMapBufferOES, void *>();
+ }
+ return returnValue;
+}
+
+GLboolean GL_APIENTRY GL_UnmapBufferOES(GLenum target)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLUnmapBufferOES, "context = %d, target = %s", CID(context),
+ GLenumToString(GLESEnum::AllEnums, target));
+
+ GLboolean returnValue;
+ if (context)
+ {
+ BufferBinding targetPacked = PackParam<BufferBinding>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateUnmapBufferOES(context, angle::EntryPoint::GLUnmapBufferOES, targetPacked));
+ if (isCallValid)
+ {
+ returnValue = context->unmapBuffer(targetPacked);
+ }
+ else
+ {
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLUnmapBufferOES, GLboolean>();
+ }
+ ANGLE_CAPTURE_GL(UnmapBufferOES, isCallValid, context, targetPacked, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLUnmapBufferOES, GLboolean>();
+ }
+ return returnValue;
+}
+
+// GL_OES_matrix_palette
+void GL_APIENTRY GL_CurrentPaletteMatrixOES(GLuint matrixpaletteindex)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLCurrentPaletteMatrixOES, "context = %d, matrixpaletteindex = %u", CID(context),
+ matrixpaletteindex);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateCurrentPaletteMatrixOES(context, angle::EntryPoint::GLCurrentPaletteMatrixOES,
+ matrixpaletteindex));
+ if (isCallValid)
+ {
+ context->currentPaletteMatrix(matrixpaletteindex);
+ }
+ ANGLE_CAPTURE_GL(CurrentPaletteMatrixOES, isCallValid, context, matrixpaletteindex);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_LoadPaletteFromModelViewMatrixOES()
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLLoadPaletteFromModelViewMatrixOES, "context = %d", CID(context));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateLoadPaletteFromModelViewMatrixOES(
+ context, angle::EntryPoint::GLLoadPaletteFromModelViewMatrixOES));
+ if (isCallValid)
+ {
+ context->loadPaletteFromModelViewMatrix();
+ }
+ ANGLE_CAPTURE_GL(LoadPaletteFromModelViewMatrixOES, isCallValid, context);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_MatrixIndexPointerOES(GLint size,
+ GLenum type,
+ GLsizei stride,
+ const void *pointer)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLMatrixIndexPointerOES,
+ "context = %d, size = %d, type = %s, stride = %d, pointer = 0x%016" PRIxPTR "",
+ CID(context), size, GLenumToString(GLESEnum::AllEnums, type), stride, (uintptr_t)pointer);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateMatrixIndexPointerOES(context, angle::EntryPoint::GLMatrixIndexPointerOES,
+ size, type, stride, pointer));
+ if (isCallValid)
+ {
+ context->matrixIndexPointer(size, type, stride, pointer);
+ }
+ ANGLE_CAPTURE_GL(MatrixIndexPointerOES, isCallValid, context, size, type, stride, pointer);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_WeightPointerOES(GLint size, GLenum type, GLsizei stride, const void *pointer)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLWeightPointerOES,
+ "context = %d, size = %d, type = %s, stride = %d, pointer = 0x%016" PRIxPTR "",
+ CID(context), size, GLenumToString(GLESEnum::AllEnums, type), stride, (uintptr_t)pointer);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateWeightPointerOES(context, angle::EntryPoint::GLWeightPointerOES,
+ size, type, stride, pointer));
+ if (isCallValid)
+ {
+ context->weightPointer(size, type, stride, pointer);
+ }
+ ANGLE_CAPTURE_GL(WeightPointerOES, isCallValid, context, size, type, stride, pointer);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_OES_packed_depth_stencil
+
+// GL_OES_point_size_array
+void GL_APIENTRY GL_PointSizePointerOES(GLenum type, GLsizei stride, const void *pointer)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLPointSizePointerOES,
+ "context = %d, type = %s, stride = %d, pointer = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::AllEnums, type), stride, (uintptr_t)pointer);
+
+ if (context)
+ {
+ VertexAttribType typePacked = PackParam<VertexAttribType>(type);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidatePointSizePointerOES(context, angle::EntryPoint::GLPointSizePointerOES,
+ typePacked, stride, pointer));
+ if (isCallValid)
+ {
+ context->pointSizePointer(typePacked, stride, pointer);
+ }
+ ANGLE_CAPTURE_GL(PointSizePointerOES, isCallValid, context, typePacked, stride, pointer);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_OES_point_sprite
+
+// GL_OES_primitive_bounding_box
+void GL_APIENTRY GL_PrimitiveBoundingBoxOES(GLfloat minX,
+ GLfloat minY,
+ GLfloat minZ,
+ GLfloat minW,
+ GLfloat maxX,
+ GLfloat maxY,
+ GLfloat maxZ,
+ GLfloat maxW)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLPrimitiveBoundingBoxOES,
+ "context = %d, minX = %f, minY = %f, minZ = %f, minW = %f, maxX = %f, maxY = %f, maxZ = "
+ "%f, maxW = %f",
+ CID(context), minX, minY, minZ, minW, maxX, maxY, maxZ, maxW);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidatePrimitiveBoundingBoxOES(context, angle::EntryPoint::GLPrimitiveBoundingBoxOES,
+ minX, minY, minZ, minW, maxX, maxY, maxZ, maxW));
+ if (isCallValid)
+ {
+ context->primitiveBoundingBox(minX, minY, minZ, minW, maxX, maxY, maxZ, maxW);
+ }
+ ANGLE_CAPTURE_GL(PrimitiveBoundingBoxOES, isCallValid, context, minX, minY, minZ, minW,
+ maxX, maxY, maxZ, maxW);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_OES_query_matrix
+GLbitfield GL_APIENTRY GL_QueryMatrixxOES(GLfixed *mantissa, GLint *exponent)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLQueryMatrixxOES,
+ "context = %d, mantissa = 0x%016" PRIxPTR ", exponent = 0x%016" PRIxPTR "", CID(context),
+ (uintptr_t)mantissa, (uintptr_t)exponent);
+
+ GLbitfield returnValue;
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateQueryMatrixxOES(context, angle::EntryPoint::GLQueryMatrixxOES,
+ mantissa, exponent));
+ if (isCallValid)
+ {
+ returnValue = context->queryMatrixx(mantissa, exponent);
+ }
+ else
+ {
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLQueryMatrixxOES, GLbitfield>();
+ }
+ ANGLE_CAPTURE_GL(QueryMatrixxOES, isCallValid, context, mantissa, exponent, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLQueryMatrixxOES, GLbitfield>();
+ }
+ return returnValue;
+}
+
+// GL_OES_rgb8_rgba8
+
+// GL_OES_sample_shading
+void GL_APIENTRY GL_MinSampleShadingOES(GLfloat value)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLMinSampleShadingOES, "context = %d, value = %f", CID(context), value);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateMinSampleShadingOES(context, angle::EntryPoint::GLMinSampleShadingOES, value));
+ if (isCallValid)
+ {
+ context->minSampleShading(value);
+ }
+ ANGLE_CAPTURE_GL(MinSampleShadingOES, isCallValid, context, value);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_OES_sample_variables
+
+// GL_OES_shader_image_atomic
+
+// GL_OES_shader_io_blocks
+
+// GL_OES_shader_multisample_interpolation
+
+// GL_OES_standard_derivatives
+
+// GL_OES_surfaceless_context
+
+// GL_OES_texture_3D
+void GL_APIENTRY GL_CompressedTexImage3DOES(GLenum target,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLsizei imageSize,
+ const void *data)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLCompressedTexImage3DOES,
+ "context = %d, target = %s, level = %d, internalformat = %s, width = %d, height = %d, "
+ "depth = %d, border = %d, imageSize = %d, data = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target), level,
+ GLenumToString(GLESEnum::InternalFormat, internalformat), width, height, depth, border,
+ imageSize, (uintptr_t)data);
+
+ if (context)
+ {
+ TextureTarget targetPacked = PackParam<TextureTarget>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateCompressedTexImage3DOES(context, angle::EntryPoint::GLCompressedTexImage3DOES,
+ targetPacked, level, internalformat, width, height,
+ depth, border, imageSize, data));
+ if (isCallValid)
+ {
+ context->compressedTexImage3D(targetPacked, level, internalformat, width, height, depth,
+ border, imageSize, data);
+ }
+ ANGLE_CAPTURE_GL(CompressedTexImage3DOES, isCallValid, context, targetPacked, level,
+ internalformat, width, height, depth, border, imageSize, data);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_CompressedTexSubImage3DOES(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLCompressedTexSubImage3DOES,
+ "context = %d, target = %s, level = %d, xoffset = %d, yoffset = %d, zoffset = %d, width "
+ "= %d, height = %d, depth = %d, format = %s, imageSize = %d, data = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target), level, xoffset, yoffset,
+ zoffset, width, height, depth, GLenumToString(GLESEnum::InternalFormat, format),
+ imageSize, (uintptr_t)data);
+
+ if (context)
+ {
+ TextureTarget targetPacked = PackParam<TextureTarget>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateCompressedTexSubImage3DOES(
+ context, angle::EntryPoint::GLCompressedTexSubImage3DOES, targetPacked, level,
+ xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data));
+ if (isCallValid)
+ {
+ context->compressedTexSubImage3D(targetPacked, level, xoffset, yoffset, zoffset, width,
+ height, depth, format, imageSize, data);
+ }
+ ANGLE_CAPTURE_GL(CompressedTexSubImage3DOES, isCallValid, context, targetPacked, level,
+ xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_CopyTexSubImage3DOES(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLCopyTexSubImage3DOES,
+ "context = %d, target = %s, level = %d, xoffset = %d, yoffset = %d, zoffset = %d, x = "
+ "%d, y = %d, width = %d, height = %d",
+ CID(context), GLenumToString(GLESEnum::AllEnums, target), level, xoffset, yoffset,
+ zoffset, x, y, width, height);
+
+ if (context)
+ {
+ TextureTarget targetPacked = PackParam<TextureTarget>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateCopyTexSubImage3DOES(
+ context, angle::EntryPoint::GLCopyTexSubImage3DOES, targetPacked,
+ level, xoffset, yoffset, zoffset, x, y, width, height));
+ if (isCallValid)
+ {
+ context->copyTexSubImage3D(targetPacked, level, xoffset, yoffset, zoffset, x, y, width,
+ height);
+ }
+ ANGLE_CAPTURE_GL(CopyTexSubImage3DOES, isCallValid, context, targetPacked, level, xoffset,
+ yoffset, zoffset, x, y, width, height);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_FramebufferTexture3DOES(GLenum target,
+ GLenum attachment,
+ GLenum textarget,
+ GLuint texture,
+ GLint level,
+ GLint zoffset)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLFramebufferTexture3DOES,
+ "context = %d, target = %s, attachment = %s, textarget = %s, texture = %u, level = %d, "
+ "zoffset = %d",
+ CID(context), GLenumToString(GLESEnum::FramebufferTarget, target),
+ GLenumToString(GLESEnum::FramebufferAttachment, attachment),
+ GLenumToString(GLESEnum::TextureTarget, textarget), texture, level, zoffset);
+
+ if (context)
+ {
+ TextureTarget textargetPacked = PackParam<TextureTarget>(textarget);
+ TextureID texturePacked = PackParam<TextureID>(texture);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateFramebufferTexture3DOES(
+ context, angle::EntryPoint::GLFramebufferTexture3DOES, target,
+ attachment, textargetPacked, texturePacked, level, zoffset));
+ if (isCallValid)
+ {
+ context->framebufferTexture3D(target, attachment, textargetPacked, texturePacked, level,
+ zoffset);
+ }
+ ANGLE_CAPTURE_GL(FramebufferTexture3DOES, isCallValid, context, target, attachment,
+ textargetPacked, texturePacked, level, zoffset);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexImage3DOES(GLenum target,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexImage3DOES,
+ "context = %d, target = %s, level = %d, internalformat = %s, width = %d, height = %d, "
+ "depth = %d, border = %d, format = %s, type = %s, pixels = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target), level,
+ GLenumToString(GLESEnum::InternalFormat, internalformat), width, height, depth, border,
+ GLenumToString(GLESEnum::PixelFormat, format), GLenumToString(GLESEnum::PixelType, type),
+ (uintptr_t)pixels);
+
+ if (context)
+ {
+ TextureTarget targetPacked = PackParam<TextureTarget>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateTexImage3DOES(context, angle::EntryPoint::GLTexImage3DOES,
+ targetPacked, level, internalformat, width,
+ height, depth, border, format, type, pixels));
+ if (isCallValid)
+ {
+ context->texImage3D(targetPacked, level, internalformat, width, height, depth, border,
+ format, type, pixels);
+ }
+ ANGLE_CAPTURE_GL(TexImage3DOES, isCallValid, context, targetPacked, level, internalformat,
+ width, height, depth, border, format, type, pixels);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexSubImage3DOES(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexSubImage3DOES,
+ "context = %d, target = %s, level = %d, xoffset = %d, yoffset = %d, zoffset = %d, width "
+ "= %d, height = %d, depth = %d, format = %s, type = %s, pixels = 0x%016" PRIxPTR "",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target), level, xoffset, yoffset,
+ zoffset, width, height, depth, GLenumToString(GLESEnum::PixelFormat, format),
+ GLenumToString(GLESEnum::PixelType, type), (uintptr_t)pixels);
+
+ if (context)
+ {
+ TextureTarget targetPacked = PackParam<TextureTarget>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateTexSubImage3DOES(context, angle::EntryPoint::GLTexSubImage3DOES,
+ targetPacked, level, xoffset, yoffset, zoffset,
+ width, height, depth, format, type, pixels));
+ if (isCallValid)
+ {
+ context->texSubImage3D(targetPacked, level, xoffset, yoffset, zoffset, width, height,
+ depth, format, type, pixels);
+ }
+ ANGLE_CAPTURE_GL(TexSubImage3DOES, isCallValid, context, targetPacked, level, xoffset,
+ yoffset, zoffset, width, height, depth, format, type, pixels);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_OES_texture_border_clamp
+void GL_APIENTRY GL_GetSamplerParameterIivOES(GLuint sampler, GLenum pname, GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetSamplerParameterIivOES,
+ "context = %d, sampler = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ sampler, GLenumToString(GLESEnum::SamplerParameterI, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ SamplerID samplerPacked = PackParam<SamplerID>(sampler);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetSamplerParameterIivOES(
+ context, angle::EntryPoint::GLGetSamplerParameterIivOES,
+ samplerPacked, pname, params));
+ if (isCallValid)
+ {
+ context->getSamplerParameterIiv(samplerPacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetSamplerParameterIivOES, isCallValid, context, samplerPacked, pname,
+ params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetSamplerParameterIuivOES(GLuint sampler, GLenum pname, GLuint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetSamplerParameterIuivOES,
+ "context = %d, sampler = %u, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ sampler, GLenumToString(GLESEnum::SamplerParameterI, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ SamplerID samplerPacked = PackParam<SamplerID>(sampler);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetSamplerParameterIuivOES(
+ context, angle::EntryPoint::GLGetSamplerParameterIuivOES,
+ samplerPacked, pname, params));
+ if (isCallValid)
+ {
+ context->getSamplerParameterIuiv(samplerPacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetSamplerParameterIuivOES, isCallValid, context, samplerPacked, pname,
+ params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetTexParameterIivOES(GLenum target, GLenum pname, GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetTexParameterIivOES,
+ "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::TextureTarget, target),
+ GLenumToString(GLESEnum::GetTextureParameter, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetTexParameterIivOES(context, angle::EntryPoint::GLGetTexParameterIivOES,
+ targetPacked, pname, params));
+ if (isCallValid)
+ {
+ context->getTexParameterIiv(targetPacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetTexParameterIivOES, isCallValid, context, targetPacked, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetTexParameterIuivOES(GLenum target, GLenum pname, GLuint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetTexParameterIuivOES,
+ "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::TextureTarget, target),
+ GLenumToString(GLESEnum::GetTextureParameter, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateGetTexParameterIuivOES(context, angle::EntryPoint::GLGetTexParameterIuivOES,
+ targetPacked, pname, params));
+ if (isCallValid)
+ {
+ context->getTexParameterIuiv(targetPacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetTexParameterIuivOES, isCallValid, context, targetPacked, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_SamplerParameterIivOES(GLuint sampler, GLenum pname, const GLint *param)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLSamplerParameterIivOES,
+ "context = %d, sampler = %u, pname = %s, param = 0x%016" PRIxPTR "", CID(context),
+ sampler, GLenumToString(GLESEnum::SamplerParameterI, pname), (uintptr_t)param);
+
+ if (context)
+ {
+ SamplerID samplerPacked = PackParam<SamplerID>(sampler);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateSamplerParameterIivOES(context, angle::EntryPoint::GLSamplerParameterIivOES,
+ samplerPacked, pname, param));
+ if (isCallValid)
+ {
+ context->samplerParameterIiv(samplerPacked, pname, param);
+ }
+ ANGLE_CAPTURE_GL(SamplerParameterIivOES, isCallValid, context, samplerPacked, pname, param);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_SamplerParameterIuivOES(GLuint sampler, GLenum pname, const GLuint *param)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLSamplerParameterIuivOES,
+ "context = %d, sampler = %u, pname = %s, param = 0x%016" PRIxPTR "", CID(context),
+ sampler, GLenumToString(GLESEnum::SamplerParameterI, pname), (uintptr_t)param);
+
+ if (context)
+ {
+ SamplerID samplerPacked = PackParam<SamplerID>(sampler);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateSamplerParameterIuivOES(context, angle::EntryPoint::GLSamplerParameterIuivOES,
+ samplerPacked, pname, param));
+ if (isCallValid)
+ {
+ context->samplerParameterIuiv(samplerPacked, pname, param);
+ }
+ ANGLE_CAPTURE_GL(SamplerParameterIuivOES, isCallValid, context, samplerPacked, pname,
+ param);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexParameterIivOES(GLenum target, GLenum pname, const GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexParameterIivOES,
+ "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::TextureTarget, target),
+ GLenumToString(GLESEnum::TextureParameterName, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateTexParameterIivOES(context, angle::EntryPoint::GLTexParameterIivOES,
+ targetPacked, pname, params));
+ if (isCallValid)
+ {
+ context->texParameterIiv(targetPacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(TexParameterIivOES, isCallValid, context, targetPacked, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexParameterIuivOES(GLenum target, GLenum pname, const GLuint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexParameterIuivOES,
+ "context = %d, target = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::TextureTarget, target),
+ GLenumToString(GLESEnum::TextureParameterName, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateTexParameterIuivOES(context, angle::EntryPoint::GLTexParameterIuivOES,
+ targetPacked, pname, params));
+ if (isCallValid)
+ {
+ context->texParameterIuiv(targetPacked, pname, params);
+ }
+ ANGLE_CAPTURE_GL(TexParameterIuivOES, isCallValid, context, targetPacked, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_OES_texture_buffer
+void GL_APIENTRY GL_TexBufferOES(GLenum target, GLenum internalformat, GLuint buffer)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexBufferOES, "context = %d, target = %s, internalformat = %s, buffer = %u",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target),
+ GLenumToString(GLESEnum::SizedInternalFormat, internalformat), buffer);
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ BufferID bufferPacked = PackParam<BufferID>(buffer);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateTexBufferOES(context, angle::EntryPoint::GLTexBufferOES,
+ targetPacked, internalformat, bufferPacked));
+ if (isCallValid)
+ {
+ context->texBuffer(targetPacked, internalformat, bufferPacked);
+ }
+ ANGLE_CAPTURE_GL(TexBufferOES, isCallValid, context, targetPacked, internalformat,
+ bufferPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexBufferRangeOES(GLenum target,
+ GLenum internalformat,
+ GLuint buffer,
+ GLintptr offset,
+ GLsizeiptr size)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexBufferRangeOES,
+ "context = %d, target = %s, internalformat = %s, buffer = %u, offset = %llu, size = %llu",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target),
+ GLenumToString(GLESEnum::SizedInternalFormat, internalformat), buffer,
+ static_cast<unsigned long long>(offset), static_cast<unsigned long long>(size));
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ BufferID bufferPacked = PackParam<BufferID>(buffer);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateTexBufferRangeOES(context, angle::EntryPoint::GLTexBufferRangeOES,
+ targetPacked, internalformat, bufferPacked, offset, size));
+ if (isCallValid)
+ {
+ context->texBufferRange(targetPacked, internalformat, bufferPacked, offset, size);
+ }
+ ANGLE_CAPTURE_GL(TexBufferRangeOES, isCallValid, context, targetPacked, internalformat,
+ bufferPacked, offset, size);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_OES_texture_compression_astc
+
+// GL_OES_texture_cube_map
+void GL_APIENTRY GL_GetTexGenfvOES(GLenum coord, GLenum pname, GLfloat *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetTexGenfvOES,
+ "context = %d, coord = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::TextureCoordName, coord),
+ GLenumToString(GLESEnum::TextureGenParameter, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetTexGenfvOES(context, angle::EntryPoint::GLGetTexGenfvOES,
+ coord, pname, params));
+ if (isCallValid)
+ {
+ context->getTexGenfv(coord, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetTexGenfvOES, isCallValid, context, coord, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetTexGenivOES(GLenum coord, GLenum pname, GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetTexGenivOES,
+ "context = %d, coord = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::TextureCoordName, coord),
+ GLenumToString(GLESEnum::TextureGenParameter, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetTexGenivOES(context, angle::EntryPoint::GLGetTexGenivOES,
+ coord, pname, params));
+ if (isCallValid)
+ {
+ context->getTexGeniv(coord, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetTexGenivOES, isCallValid, context, coord, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GetTexGenxvOES(GLenum coord, GLenum pname, GLfixed *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGetTexGenxvOES,
+ "context = %d, coord = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::TextureCoordName, coord),
+ GLenumToString(GLESEnum::TextureGenParameter, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGetTexGenxvOES(context, angle::EntryPoint::GLGetTexGenxvOES,
+ coord, pname, params));
+ if (isCallValid)
+ {
+ context->getTexGenxv(coord, pname, params);
+ }
+ ANGLE_CAPTURE_GL(GetTexGenxvOES, isCallValid, context, coord, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexGenfOES(GLenum coord, GLenum pname, GLfloat param)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexGenfOES, "context = %d, coord = %s, pname = %s, param = %f", CID(context),
+ GLenumToString(GLESEnum::TextureCoordName, coord),
+ GLenumToString(GLESEnum::TextureGenParameter, pname), param);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateTexGenfOES(context, angle::EntryPoint::GLTexGenfOES, coord, pname, param));
+ if (isCallValid)
+ {
+ context->texGenf(coord, pname, param);
+ }
+ ANGLE_CAPTURE_GL(TexGenfOES, isCallValid, context, coord, pname, param);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexGenfvOES(GLenum coord, GLenum pname, const GLfloat *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexGenfvOES,
+ "context = %d, coord = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::TextureCoordName, coord),
+ GLenumToString(GLESEnum::TextureGenParameter, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateTexGenfvOES(context, angle::EntryPoint::GLTexGenfvOES, coord, pname, params));
+ if (isCallValid)
+ {
+ context->texGenfv(coord, pname, params);
+ }
+ ANGLE_CAPTURE_GL(TexGenfvOES, isCallValid, context, coord, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexGeniOES(GLenum coord, GLenum pname, GLint param)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexGeniOES, "context = %d, coord = %s, pname = %s, param = %d", CID(context),
+ GLenumToString(GLESEnum::TextureCoordName, coord),
+ GLenumToString(GLESEnum::TextureGenParameter, pname), param);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateTexGeniOES(context, angle::EntryPoint::GLTexGeniOES, coord, pname, param));
+ if (isCallValid)
+ {
+ context->texGeni(coord, pname, param);
+ }
+ ANGLE_CAPTURE_GL(TexGeniOES, isCallValid, context, coord, pname, param);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexGenivOES(GLenum coord, GLenum pname, const GLint *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexGenivOES,
+ "context = %d, coord = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::TextureCoordName, coord),
+ GLenumToString(GLESEnum::TextureGenParameter, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateTexGenivOES(context, angle::EntryPoint::GLTexGenivOES, coord, pname, params));
+ if (isCallValid)
+ {
+ context->texGeniv(coord, pname, params);
+ }
+ ANGLE_CAPTURE_GL(TexGenivOES, isCallValid, context, coord, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexGenxOES(GLenum coord, GLenum pname, GLfixed param)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexGenxOES, "context = %d, coord = %s, pname = %s, param = 0x%X", CID(context),
+ GLenumToString(GLESEnum::TextureCoordName, coord),
+ GLenumToString(GLESEnum::TextureGenParameter, pname), param);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateTexGenxOES(context, angle::EntryPoint::GLTexGenxOES, coord, pname, param));
+ if (isCallValid)
+ {
+ context->texGenx(coord, pname, param);
+ }
+ ANGLE_CAPTURE_GL(TexGenxOES, isCallValid, context, coord, pname, param);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_TexGenxvOES(GLenum coord, GLenum pname, const GLfixed *params)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexGenxvOES,
+ "context = %d, coord = %s, pname = %s, params = 0x%016" PRIxPTR "", CID(context),
+ GLenumToString(GLESEnum::TextureCoordName, coord),
+ GLenumToString(GLESEnum::TextureGenParameter, pname), (uintptr_t)params);
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateTexGenxvOES(context, angle::EntryPoint::GLTexGenxvOES, coord, pname, params));
+ if (isCallValid)
+ {
+ context->texGenxv(coord, pname, params);
+ }
+ ANGLE_CAPTURE_GL(TexGenxvOES, isCallValid, context, coord, pname, params);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_OES_texture_cube_map_array
+
+// GL_OES_texture_float
+
+// GL_OES_texture_float_linear
+
+// GL_OES_texture_half_float
+
+// GL_OES_texture_half_float_linear
+
+// GL_OES_texture_npot
+
+// GL_OES_texture_stencil8
+
+// GL_OES_texture_storage_multisample_2d_array
+void GL_APIENTRY GL_TexStorage3DMultisampleOES(GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean fixedsamplelocations)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLTexStorage3DMultisampleOES,
+ "context = %d, target = %s, samples = %d, internalformat = %s, width = %d, height = %d, "
+ "depth = %d, fixedsamplelocations = %s",
+ CID(context), GLenumToString(GLESEnum::TextureTarget, target), samples,
+ GLenumToString(GLESEnum::SizedInternalFormat, internalformat), width, height, depth,
+ GLbooleanToString(fixedsamplelocations));
+
+ if (context)
+ {
+ TextureType targetPacked = PackParam<TextureType>(target);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateTexStorage3DMultisampleOES(
+ context, angle::EntryPoint::GLTexStorage3DMultisampleOES, targetPacked, samples,
+ internalformat, width, height, depth, fixedsamplelocations));
+ if (isCallValid)
+ {
+ context->texStorage3DMultisample(targetPacked, samples, internalformat, width, height,
+ depth, fixedsamplelocations);
+ }
+ ANGLE_CAPTURE_GL(TexStorage3DMultisampleOES, isCallValid, context, targetPacked, samples,
+ internalformat, width, height, depth, fixedsamplelocations);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_OES_vertex_array_object
+void GL_APIENTRY GL_BindVertexArrayOES(GLuint array)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLBindVertexArrayOES, "context = %d, array = %u", CID(context), array);
+
+ if (context)
+ {
+ VertexArrayID arrayPacked = PackParam<VertexArrayID>(array);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateBindVertexArrayOES(
+ context, angle::EntryPoint::GLBindVertexArrayOES, arrayPacked));
+ if (isCallValid)
+ {
+ context->bindVertexArray(arrayPacked);
+ }
+ ANGLE_CAPTURE_GL(BindVertexArrayOES, isCallValid, context, arrayPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_DeleteVertexArraysOES(GLsizei n, const GLuint *arrays)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLDeleteVertexArraysOES, "context = %d, n = %d, arrays = 0x%016" PRIxPTR "",
+ CID(context), n, (uintptr_t)arrays);
+
+ if (context)
+ {
+ const VertexArrayID *arraysPacked = PackParam<const VertexArrayID *>(arrays);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateDeleteVertexArraysOES(context, angle::EntryPoint::GLDeleteVertexArraysOES, n,
+ arraysPacked));
+ if (isCallValid)
+ {
+ context->deleteVertexArrays(n, arraysPacked);
+ }
+ ANGLE_CAPTURE_GL(DeleteVertexArraysOES, isCallValid, context, n, arraysPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+void GL_APIENTRY GL_GenVertexArraysOES(GLsizei n, GLuint *arrays)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLGenVertexArraysOES, "context = %d, n = %d, arrays = 0x%016" PRIxPTR "",
+ CID(context), n, (uintptr_t)arrays);
+
+ if (context)
+ {
+ VertexArrayID *arraysPacked = PackParam<VertexArrayID *>(arrays);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateGenVertexArraysOES(
+ context, angle::EntryPoint::GLGenVertexArraysOES, n, arraysPacked));
+ if (isCallValid)
+ {
+ context->genVertexArrays(n, arraysPacked);
+ }
+ ANGLE_CAPTURE_GL(GenVertexArraysOES, isCallValid, context, n, arraysPacked);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+GLboolean GL_APIENTRY GL_IsVertexArrayOES(GLuint array)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLIsVertexArrayOES, "context = %d, array = %u", CID(context), array);
+
+ GLboolean returnValue;
+ if (context)
+ {
+ VertexArrayID arrayPacked = PackParam<VertexArrayID>(array);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateIsVertexArrayOES(context, angle::EntryPoint::GLIsVertexArrayOES, arrayPacked));
+ if (isCallValid)
+ {
+ returnValue = context->isVertexArray(arrayPacked);
+ }
+ else
+ {
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsVertexArrayOES, GLboolean>();
+ }
+ ANGLE_CAPTURE_GL(IsVertexArrayOES, isCallValid, context, arrayPacked, returnValue);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ returnValue = GetDefaultReturnValue<angle::EntryPoint::GLIsVertexArrayOES, GLboolean>();
+ }
+ return returnValue;
+}
+
+// GL_OES_vertex_half_float
+
+// GL_OES_vertex_type_10_10_10_2
+
+// GL_OVR_multiview
+void GL_APIENTRY GL_FramebufferTextureMultiviewOVR(GLenum target,
+ GLenum attachment,
+ GLuint texture,
+ GLint level,
+ GLint baseViewIndex,
+ GLsizei numViews)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLFramebufferTextureMultiviewOVR,
+ "context = %d, target = %s, attachment = %s, texture = %u, level = %d, baseViewIndex = "
+ "%d, numViews = %d",
+ CID(context), GLenumToString(GLESEnum::FramebufferTarget, target),
+ GLenumToString(GLESEnum::FramebufferAttachment, attachment), texture, level,
+ baseViewIndex, numViews);
+
+ if (context)
+ {
+ TextureID texturePacked = PackParam<TextureID>(texture);
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid = (context->skipValidation() ||
+ ValidateFramebufferTextureMultiviewOVR(
+ context, angle::EntryPoint::GLFramebufferTextureMultiviewOVR,
+ target, attachment, texturePacked, level, baseViewIndex, numViews));
+ if (isCallValid)
+ {
+ context->framebufferTextureMultiview(target, attachment, texturePacked, level,
+ baseViewIndex, numViews);
+ }
+ ANGLE_CAPTURE_GL(FramebufferTextureMultiviewOVR, isCallValid, context, target, attachment,
+ texturePacked, level, baseViewIndex, numViews);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+// GL_OVR_multiview2
+
+// GL_QCOM_shading_rate
+void GL_APIENTRY GL_ShadingRateQCOM(GLenum rate)
+{
+ Context *context = GetValidGlobalContext();
+ EVENT(context, GLShadingRateQCOM, "context = %d, rate = %s", CID(context),
+ GLenumToString(GLESEnum::ShadingRateQCOM, rate));
+
+ if (context)
+ {
+ SCOPED_SHARE_CONTEXT_LOCK(context);
+ bool isCallValid =
+ (context->skipValidation() ||
+ ValidateShadingRateQCOM(context, angle::EntryPoint::GLShadingRateQCOM, rate));
+ if (isCallValid)
+ {
+ context->shadingRateQCOM(rate);
+ }
+ ANGLE_CAPTURE_GL(ShadingRateQCOM, isCallValid, context, rate);
+ }
+ else
+ {
+ GenerateContextLostErrorOnCurrentGlobalContext();
+ }
+}
+
+} // extern "C"
diff --git a/gfx/angle/checkout/src/libGLESv2/entry_points_gles_ext_autogen.h b/gfx/angle/checkout/src/libGLESv2/entry_points_gles_ext_autogen.h
new file mode 100644
index 0000000000..b086a3aa35
--- /dev/null
+++ b/gfx/angle/checkout/src/libGLESv2/entry_points_gles_ext_autogen.h
@@ -0,0 +1,1788 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml and gl_angle_ext.xml.
+//
+// Copyright 2020 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_ext_autogen.h:
+// Defines the GLES extension entry points.
+
+#ifndef LIBGLESV2_ENTRY_POINTS_GLES_EXT_AUTOGEN_H_
+#define LIBGLESV2_ENTRY_POINTS_GLES_EXT_AUTOGEN_H_
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <GLES3/gl32.h>
+#include <export.h>
+
+extern "C" {
+
+// GL_AMD_performance_monitor
+ANGLE_EXPORT void GL_APIENTRY GL_BeginPerfMonitorAMD(GLuint monitor);
+ANGLE_EXPORT void GL_APIENTRY GL_DeletePerfMonitorsAMD(GLsizei n, GLuint *monitors);
+ANGLE_EXPORT void GL_APIENTRY GL_EndPerfMonitorAMD(GLuint monitor);
+ANGLE_EXPORT void GL_APIENTRY GL_GenPerfMonitorsAMD(GLsizei n, GLuint *monitors);
+ANGLE_EXPORT void GL_APIENTRY GL_GetPerfMonitorCounterDataAMD(GLuint monitor,
+ GLenum pname,
+ GLsizei dataSize,
+ GLuint *data,
+ GLint *bytesWritten);
+ANGLE_EXPORT void GL_APIENTRY GL_GetPerfMonitorCounterInfoAMD(GLuint group,
+ GLuint counter,
+ GLenum pname,
+ void *data);
+ANGLE_EXPORT void GL_APIENTRY GL_GetPerfMonitorCounterStringAMD(GLuint group,
+ GLuint counter,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *counterString);
+ANGLE_EXPORT void GL_APIENTRY GL_GetPerfMonitorCountersAMD(GLuint group,
+ GLint *numCounters,
+ GLint *maxActiveCounters,
+ GLsizei counterSize,
+ GLuint *counters);
+ANGLE_EXPORT void GL_APIENTRY GL_GetPerfMonitorGroupStringAMD(GLuint group,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *groupString);
+ANGLE_EXPORT void GL_APIENTRY GL_GetPerfMonitorGroupsAMD(GLint *numGroups,
+ GLsizei groupsSize,
+ GLuint *groups);
+ANGLE_EXPORT void GL_APIENTRY GL_SelectPerfMonitorCountersAMD(GLuint monitor,
+ GLboolean enable,
+ GLuint group,
+ GLint numCounters,
+ GLuint *counterList);
+
+// GL_ANDROID_extension_pack_es31a
+
+// GL_ANGLE_base_vertex_base_instance
+ANGLE_EXPORT void GL_APIENTRY GL_DrawArraysInstancedBaseInstanceANGLE(GLenum mode,
+ GLint first,
+ GLsizei count,
+ GLsizei instanceCount,
+ GLuint baseInstance);
+ANGLE_EXPORT void GL_APIENTRY
+GL_DrawElementsInstancedBaseVertexBaseInstanceANGLE(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const GLvoid *indices,
+ GLsizei instanceCount,
+ GLint baseVertex,
+ GLuint baseInstance);
+ANGLE_EXPORT void GL_APIENTRY
+GL_MultiDrawArraysInstancedBaseInstanceANGLE(GLenum mode,
+ const GLint *firsts,
+ const GLsizei *counts,
+ const GLsizei *instanceCounts,
+ const GLuint *baseInstances,
+ GLsizei drawcount);
+ANGLE_EXPORT void GL_APIENTRY
+GL_MultiDrawElementsInstancedBaseVertexBaseInstanceANGLE(GLenum mode,
+ const GLsizei *counts,
+ GLenum type,
+ const GLvoid *const *indices,
+ const GLsizei *instanceCounts,
+ const GLint *baseVertices,
+ const GLuint *baseInstances,
+ GLsizei drawcount);
+
+// GL_ANGLE_copy_texture_3d
+ANGLE_EXPORT void GL_APIENTRY GL_CopyTexture3DANGLE(GLuint sourceId,
+ GLint sourceLevel,
+ GLenum destTarget,
+ GLuint destId,
+ GLint destLevel,
+ GLint internalFormat,
+ GLenum destType,
+ GLboolean unpackFlipY,
+ GLboolean unpackPremultiplyAlpha,
+ GLboolean unpackUnmultiplyAlpha);
+ANGLE_EXPORT void GL_APIENTRY GL_CopySubTexture3DANGLE(GLuint sourceId,
+ GLint sourceLevel,
+ GLenum destTarget,
+ GLuint destId,
+ GLint destLevel,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLint x,
+ GLint y,
+ GLint z,
+ GLint width,
+ GLint height,
+ GLint depth,
+ GLboolean unpackFlipY,
+ GLboolean unpackPremultiplyAlpha,
+ GLboolean unpackUnmultiplyAlpha);
+
+// GL_ANGLE_depth_texture
+
+// GL_ANGLE_framebuffer_blit
+ANGLE_EXPORT void GL_APIENTRY GL_BlitFramebufferANGLE(GLint srcX0,
+ GLint srcY0,
+ GLint srcX1,
+ GLint srcY1,
+ GLint dstX0,
+ GLint dstY0,
+ GLint dstX1,
+ GLint dstY1,
+ GLbitfield mask,
+ GLenum filter);
+
+// GL_ANGLE_framebuffer_multisample
+ANGLE_EXPORT void GL_APIENTRY GL_RenderbufferStorageMultisampleANGLE(GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height);
+
+// GL_ANGLE_get_image
+ANGLE_EXPORT void GL_APIENTRY
+GL_GetTexImageANGLE(GLenum target, GLint level, GLenum format, GLenum type, void *pixels);
+ANGLE_EXPORT void GL_APIENTRY GL_GetCompressedTexImageANGLE(GLenum target,
+ GLint level,
+ void *pixels);
+ANGLE_EXPORT void GL_APIENTRY GL_GetRenderbufferImageANGLE(GLenum target,
+ GLenum format,
+ GLenum type,
+ void *pixels);
+
+// GL_ANGLE_get_tex_level_parameter
+ANGLE_EXPORT void GL_APIENTRY GL_GetTexLevelParameterivANGLE(GLenum target,
+ GLint level,
+ GLenum pname,
+ GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetTexLevelParameterfvANGLE(GLenum target,
+ GLint level,
+ GLenum pname,
+ GLfloat *params);
+
+// GL_ANGLE_instanced_arrays
+ANGLE_EXPORT void GL_APIENTRY GL_DrawArraysInstancedANGLE(GLenum mode,
+ GLint first,
+ GLsizei count,
+ GLsizei primcount);
+ANGLE_EXPORT void GL_APIENTRY GL_DrawElementsInstancedANGLE(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLsizei primcount);
+ANGLE_EXPORT void GL_APIENTRY GL_VertexAttribDivisorANGLE(GLuint index, GLuint divisor);
+
+// GL_ANGLE_logic_op
+ANGLE_EXPORT void GL_APIENTRY GL_LogicOpANGLE(GLenum opcode);
+
+// GL_ANGLE_memory_object_flags
+ANGLE_EXPORT void GL_APIENTRY GL_TexStorageMemFlags2DANGLE(GLenum target,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLuint memory,
+ GLuint64 offset,
+ GLbitfield createFlags,
+ GLbitfield usageFlags,
+ const void *imageCreateInfoPNext);
+ANGLE_EXPORT void GL_APIENTRY
+GL_TexStorageMemFlags2DMultisampleANGLE(GLenum target,
+ GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedSampleLocations,
+ GLuint memory,
+ GLuint64 offset,
+ GLbitfield createFlags,
+ GLbitfield usageFlags,
+ const void *imageCreateInfoPNext);
+ANGLE_EXPORT void GL_APIENTRY GL_TexStorageMemFlags3DANGLE(GLenum target,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLuint memory,
+ GLuint64 offset,
+ GLbitfield createFlags,
+ GLbitfield usageFlags,
+ const void *imageCreateInfoPNext);
+ANGLE_EXPORT void GL_APIENTRY
+GL_TexStorageMemFlags3DMultisampleANGLE(GLenum target,
+ GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean fixedSampleLocations,
+ GLuint memory,
+ GLuint64 offset,
+ GLbitfield createFlags,
+ GLbitfield usageFlags,
+ const void *imageCreateInfoPNext);
+
+// GL_ANGLE_memory_object_fuchsia
+ANGLE_EXPORT void GL_APIENTRY GL_ImportMemoryZirconHandleANGLE(GLuint memory,
+ GLuint64 size,
+ GLenum handleType,
+ GLuint handle);
+
+// GL_ANGLE_multi_draw
+ANGLE_EXPORT void GL_APIENTRY GL_MultiDrawArraysANGLE(GLenum mode,
+ const GLint *firsts,
+ const GLsizei *counts,
+ GLsizei drawcount);
+ANGLE_EXPORT void GL_APIENTRY GL_MultiDrawArraysInstancedANGLE(GLenum mode,
+ const GLint *firsts,
+ const GLsizei *counts,
+ const GLsizei *instanceCounts,
+ GLsizei drawcount);
+ANGLE_EXPORT void GL_APIENTRY GL_MultiDrawElementsANGLE(GLenum mode,
+ const GLsizei *counts,
+ GLenum type,
+ const GLvoid *const *indices,
+ GLsizei drawcount);
+ANGLE_EXPORT void GL_APIENTRY GL_MultiDrawElementsInstancedANGLE(GLenum mode,
+ const GLsizei *counts,
+ GLenum type,
+ const GLvoid *const *indices,
+ const GLsizei *instanceCounts,
+ GLsizei drawcount);
+
+// GL_ANGLE_pack_reverse_row_order
+
+// GL_ANGLE_program_binary
+
+// GL_ANGLE_provoking_vertex
+ANGLE_EXPORT void GL_APIENTRY GL_ProvokingVertexANGLE(GLenum mode);
+
+// GL_ANGLE_request_extension
+ANGLE_EXPORT void GL_APIENTRY GL_RequestExtensionANGLE(const GLchar *name);
+ANGLE_EXPORT void GL_APIENTRY GL_DisableExtensionANGLE(const GLchar *name);
+
+// GL_ANGLE_robust_client_memory
+ANGLE_EXPORT void GL_APIENTRY GL_GetBooleanvRobustANGLE(GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLboolean *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetBufferParameterivRobustANGLE(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetFloatvRobustANGLE(GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetFramebufferAttachmentParameterivRobustANGLE(GLenum target,
+ GLenum attachment,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetIntegervRobustANGLE(GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *data);
+ANGLE_EXPORT void GL_APIENTRY GL_GetProgramivRobustANGLE(GLuint program,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetRenderbufferParameterivRobustANGLE(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetShaderivRobustANGLE(GLuint shader,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetTexParameterfvRobustANGLE(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetTexParameterivRobustANGLE(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetUniformfvRobustANGLE(GLuint program,
+ GLint location,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetUniformivRobustANGLE(GLuint program,
+ GLint location,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetVertexAttribfvRobustANGLE(GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetVertexAttribivRobustANGLE(GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetVertexAttribPointervRobustANGLE(GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ void **pointer);
+ANGLE_EXPORT void GL_APIENTRY GL_ReadPixelsRobustANGLE(GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLsizei *columns,
+ GLsizei *rows,
+ void *pixels);
+ANGLE_EXPORT void GL_APIENTRY GL_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 GL_TexParameterfvRobustANGLE(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLfloat *params);
+ANGLE_EXPORT void GL_APIENTRY GL_TexParameterivRobustANGLE(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_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 GL_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 GL_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 GL_CompressedTexImage2DRobustANGLE(GLenum target,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLsizei imageSize,
+ GLsizei dataSize,
+ const GLvoid *data);
+ANGLE_EXPORT void GL_APIENTRY GL_CompressedTexSubImage2DRobustANGLE(GLenum target,
+ GLint level,
+ GLsizei xoffset,
+ GLsizei yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLsizei imageSize,
+ GLsizei dataSize,
+ const GLvoid *data);
+ANGLE_EXPORT void GL_APIENTRY GL_CompressedTexImage3DRobustANGLE(GLenum target,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLsizei imageSize,
+ GLsizei dataSize,
+ const GLvoid *data);
+ANGLE_EXPORT void GL_APIENTRY GL_CompressedTexSubImage3DRobustANGLE(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLsizei imageSize,
+ GLsizei dataSize,
+ const GLvoid *data);
+ANGLE_EXPORT void GL_APIENTRY GL_GetQueryivRobustANGLE(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetQueryObjectuivRobustANGLE(GLuint id,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetBufferPointervRobustANGLE(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ void **params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetIntegeri_vRobustANGLE(GLenum target,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *data);
+ANGLE_EXPORT void GL_APIENTRY GL_GetInternalformativRobustANGLE(GLenum target,
+ GLenum internalformat,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetVertexAttribIivRobustANGLE(GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetVertexAttribIuivRobustANGLE(GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetUniformuivRobustANGLE(GLuint program,
+ GLint location,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetActiveUniformBlockivRobustANGLE(GLuint program,
+ GLuint uniformBlockIndex,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetInteger64vRobustANGLE(GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint64 *data);
+ANGLE_EXPORT void GL_APIENTRY GL_GetInteger64i_vRobustANGLE(GLenum target,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint64 *data);
+ANGLE_EXPORT void GL_APIENTRY GL_GetBufferParameteri64vRobustANGLE(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint64 *params);
+ANGLE_EXPORT void GL_APIENTRY GL_SamplerParameterivRobustANGLE(GLuint sampler,
+ GLuint pname,
+ GLsizei bufSize,
+ const GLint *param);
+ANGLE_EXPORT void GL_APIENTRY GL_SamplerParameterfvRobustANGLE(GLuint sampler,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLfloat *param);
+ANGLE_EXPORT void GL_APIENTRY GL_GetSamplerParameterivRobustANGLE(GLuint sampler,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetSamplerParameterfvRobustANGLE(GLuint sampler,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetFramebufferParameterivRobustANGLE(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetProgramInterfaceivRobustANGLE(GLuint program,
+ GLenum programInterface,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetBooleani_vRobustANGLE(GLenum target,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLboolean *data);
+ANGLE_EXPORT void GL_APIENTRY GL_GetMultisamplefvRobustANGLE(GLenum pname,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *val);
+ANGLE_EXPORT void GL_APIENTRY GL_GetTexLevelParameterivRobustANGLE(GLenum target,
+ GLint level,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetTexLevelParameterfvRobustANGLE(GLenum target,
+ GLint level,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetPointervRobustANGLERobustANGLE(GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ void **params);
+ANGLE_EXPORT void GL_APIENTRY GL_ReadnPixelsRobustANGLE(GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLsizei *columns,
+ GLsizei *rows,
+ void *data);
+ANGLE_EXPORT void GL_APIENTRY GL_GetnUniformfvRobustANGLE(GLuint program,
+ GLint location,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetnUniformivRobustANGLE(GLuint program,
+ GLint location,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetnUniformuivRobustANGLE(GLuint program,
+ GLint location,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_TexParameterIivRobustANGLE(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_TexParameterIuivRobustANGLE(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLuint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetTexParameterIivRobustANGLE(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetTexParameterIuivRobustANGLE(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_SamplerParameterIivRobustANGLE(GLuint sampler,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLint *param);
+ANGLE_EXPORT void GL_APIENTRY GL_SamplerParameterIuivRobustANGLE(GLuint sampler,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLuint *param);
+ANGLE_EXPORT void GL_APIENTRY GL_GetSamplerParameterIivRobustANGLE(GLuint sampler,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetSamplerParameterIuivRobustANGLE(GLuint sampler,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetQueryObjectivRobustANGLE(GLuint id,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetQueryObjecti64vRobustANGLE(GLuint id,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint64 *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetQueryObjectui64vRobustANGLE(GLuint id,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint64 *params);
+
+// GL_ANGLE_robust_resource_initialization
+
+// GL_ANGLE_semaphore_fuchsia
+ANGLE_EXPORT void GL_APIENTRY GL_ImportSemaphoreZirconHandleANGLE(GLuint semaphore,
+ GLenum handleType,
+ GLuint handle);
+
+// GL_ANGLE_shader_pixel_local_storage
+ANGLE_EXPORT void GL_APIENTRY GL_FramebufferMemorylessPixelLocalStorageANGLE(GLint plane,
+ GLenum internalformat);
+ANGLE_EXPORT void GL_APIENTRY GL_FramebufferTexturePixelLocalStorageANGLE(GLint plane,
+ GLuint backingtexture,
+ GLint level,
+ GLint layer);
+ANGLE_EXPORT void GL_APIENTRY GL_BeginPixelLocalStorageANGLE(GLsizei planes,
+ const GLenum *loadops,
+ const void *cleardata);
+ANGLE_EXPORT void GL_APIENTRY GL_EndPixelLocalStorageANGLE();
+ANGLE_EXPORT void GL_APIENTRY GL_PixelLocalStorageBarrierANGLE();
+
+// GL_ANGLE_texture_compression_dxt3
+
+// GL_ANGLE_texture_compression_dxt5
+
+// GL_ANGLE_texture_external_update
+ANGLE_EXPORT void GL_APIENTRY GL_TexImage2DExternalANGLE(GLenum target,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLenum format,
+ GLenum type);
+ANGLE_EXPORT void GL_APIENTRY GL_InvalidateTextureANGLE(GLenum target);
+
+// GL_ANGLE_texture_multisample
+ANGLE_EXPORT void GL_APIENTRY GL_TexStorage2DMultisampleANGLE(GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedsamplelocations);
+ANGLE_EXPORT void GL_APIENTRY GL_GetMultisamplefvANGLE(GLenum pname, GLuint index, GLfloat *val);
+ANGLE_EXPORT void GL_APIENTRY GL_SampleMaskiANGLE(GLuint maskNumber, GLbitfield mask);
+
+// GL_ANGLE_texture_usage
+
+// GL_ANGLE_translated_shader_source
+ANGLE_EXPORT void GL_APIENTRY GL_GetTranslatedShaderSourceANGLE(GLuint shader,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *source);
+
+// GL_ANGLE_vulkan_image
+ANGLE_EXPORT void GL_APIENTRY GL_AcquireTexturesANGLE(GLuint numTextures,
+ const GLuint *textures,
+ const GLenum *layouts);
+ANGLE_EXPORT void GL_APIENTRY GL_ReleaseTexturesANGLE(GLuint numTextures,
+ const GLuint *textures,
+ GLenum *layouts);
+
+// GL_APPLE_clip_distance
+
+// GL_ARB_sync
+
+// GL_CHROMIUM_bind_uniform_location
+ANGLE_EXPORT void GL_APIENTRY GL_BindUniformLocationCHROMIUM(GLuint program,
+ GLint location,
+ const GLchar *name);
+
+// GL_CHROMIUM_copy_compressed_texture
+ANGLE_EXPORT void GL_APIENTRY GL_CompressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId);
+
+// GL_CHROMIUM_copy_texture
+ANGLE_EXPORT void GL_APIENTRY GL_CopyTextureCHROMIUM(GLuint sourceId,
+ GLint sourceLevel,
+ GLenum destTarget,
+ GLuint destId,
+ GLint destLevel,
+ GLint internalFormat,
+ GLenum destType,
+ GLboolean unpackFlipY,
+ GLboolean unpackPremultiplyAlpha,
+ GLboolean unpackUnmultiplyAlpha);
+ANGLE_EXPORT void GL_APIENTRY GL_CopySubTextureCHROMIUM(GLuint sourceId,
+ GLint sourceLevel,
+ GLenum destTarget,
+ GLuint destId,
+ GLint destLevel,
+ GLint xoffset,
+ GLint yoffset,
+ GLint x,
+ GLint y,
+ GLint width,
+ GLint height,
+ GLboolean unpackFlipY,
+ GLboolean unpackPremultiplyAlpha,
+ GLboolean unpackUnmultiplyAlpha);
+
+// GL_CHROMIUM_framebuffer_mixed_samples
+ANGLE_EXPORT void GL_APIENTRY GL_CoverageModulationCHROMIUM(GLenum components);
+
+// GL_CHROMIUM_lose_context
+ANGLE_EXPORT void GL_APIENTRY GL_LoseContextCHROMIUM(GLenum current, GLenum other);
+
+// GL_EXT_EGL_image_array
+
+// GL_EXT_EGL_image_storage
+ANGLE_EXPORT void GL_APIENTRY GL_EGLImageTargetTexStorageEXT(GLenum target,
+ GLeglImageOES image,
+ const GLint *attrib_list);
+ANGLE_EXPORT void GL_APIENTRY GL_EGLImageTargetTextureStorageEXT(GLuint texture,
+ GLeglImageOES image,
+ const GLint *attrib_list);
+
+// GL_EXT_YUV_target
+
+// GL_EXT_base_instance
+ANGLE_EXPORT void GL_APIENTRY GL_DrawArraysInstancedBaseInstanceEXT(GLenum mode,
+ GLint first,
+ GLsizei count,
+ GLsizei instancecount,
+ GLuint baseinstance);
+ANGLE_EXPORT void GL_APIENTRY GL_DrawElementsInstancedBaseInstanceEXT(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLsizei instancecount,
+ GLuint baseinstance);
+ANGLE_EXPORT void GL_APIENTRY
+GL_DrawElementsInstancedBaseVertexBaseInstanceEXT(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLsizei instancecount,
+ GLint basevertex,
+ GLuint baseinstance);
+
+// GL_EXT_blend_func_extended
+ANGLE_EXPORT void GL_APIENTRY GL_BindFragDataLocationEXT(GLuint program,
+ GLuint color,
+ const GLchar *name);
+ANGLE_EXPORT void GL_APIENTRY GL_BindFragDataLocationIndexedEXT(GLuint program,
+ GLuint colorNumber,
+ GLuint index,
+ const GLchar *name);
+ANGLE_EXPORT GLint GL_APIENTRY GL_GetFragDataIndexEXT(GLuint program, const GLchar *name);
+ANGLE_EXPORT GLint GL_APIENTRY GL_GetProgramResourceLocationIndexEXT(GLuint program,
+ GLenum programInterface,
+ const GLchar *name);
+
+// GL_EXT_blend_minmax
+
+// GL_EXT_buffer_storage
+ANGLE_EXPORT void GL_APIENTRY GL_BufferStorageEXT(GLenum target,
+ GLsizeiptr size,
+ const void *data,
+ GLbitfield flags);
+
+// GL_EXT_clip_control
+ANGLE_EXPORT void GL_APIENTRY GL_ClipControlEXT(GLenum origin, GLenum depth);
+
+// GL_EXT_clip_cull_distance
+
+// GL_EXT_color_buffer_float
+
+// GL_EXT_color_buffer_half_float
+
+// GL_EXT_copy_image
+ANGLE_EXPORT void GL_APIENTRY GL_CopyImageSubDataEXT(GLuint srcName,
+ GLenum srcTarget,
+ GLint srcLevel,
+ GLint srcX,
+ GLint srcY,
+ GLint srcZ,
+ GLuint dstName,
+ GLenum dstTarget,
+ GLint dstLevel,
+ GLint dstX,
+ GLint dstY,
+ GLint dstZ,
+ GLsizei srcWidth,
+ GLsizei srcHeight,
+ GLsizei srcDepth);
+
+// GL_EXT_debug_label
+ANGLE_EXPORT void GL_APIENTRY
+GL_GetObjectLabelEXT(GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label);
+ANGLE_EXPORT void GL_APIENTRY GL_LabelObjectEXT(GLenum type,
+ GLuint object,
+ GLsizei length,
+ const GLchar *label);
+
+// GL_EXT_debug_marker
+ANGLE_EXPORT void GL_APIENTRY GL_InsertEventMarkerEXT(GLsizei length, const GLchar *marker);
+ANGLE_EXPORT void GL_APIENTRY GL_PopGroupMarkerEXT();
+ANGLE_EXPORT void GL_APIENTRY GL_PushGroupMarkerEXT(GLsizei length, const GLchar *marker);
+
+// GL_EXT_discard_framebuffer
+ANGLE_EXPORT void GL_APIENTRY GL_DiscardFramebufferEXT(GLenum target,
+ GLsizei numAttachments,
+ const GLenum *attachments);
+
+// GL_EXT_disjoint_timer_query
+ANGLE_EXPORT void GL_APIENTRY GL_BeginQueryEXT(GLenum target, GLuint id);
+ANGLE_EXPORT void GL_APIENTRY GL_DeleteQueriesEXT(GLsizei n, const GLuint *ids);
+ANGLE_EXPORT void GL_APIENTRY GL_EndQueryEXT(GLenum target);
+ANGLE_EXPORT void GL_APIENTRY GL_GenQueriesEXT(GLsizei n, GLuint *ids);
+ANGLE_EXPORT void GL_APIENTRY GL_GetInteger64vEXT(GLenum pname, GLint64 *data);
+ANGLE_EXPORT void GL_APIENTRY GL_GetQueryObjecti64vEXT(GLuint id, GLenum pname, GLint64 *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetQueryObjectivEXT(GLuint id, GLenum pname, GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetQueryObjectui64vEXT(GLuint id, GLenum pname, GLuint64 *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetQueryivEXT(GLenum target, GLenum pname, GLint *params);
+ANGLE_EXPORT GLboolean GL_APIENTRY GL_IsQueryEXT(GLuint id);
+ANGLE_EXPORT void GL_APIENTRY GL_QueryCounterEXT(GLuint id, GLenum target);
+
+// GL_EXT_draw_buffers
+ANGLE_EXPORT void GL_APIENTRY GL_DrawBuffersEXT(GLsizei n, const GLenum *bufs);
+
+// GL_EXT_draw_buffers_indexed
+ANGLE_EXPORT void GL_APIENTRY GL_BlendEquationSeparateiEXT(GLuint buf,
+ GLenum modeRGB,
+ GLenum modeAlpha);
+ANGLE_EXPORT void GL_APIENTRY GL_BlendEquationiEXT(GLuint buf, GLenum mode);
+ANGLE_EXPORT void GL_APIENTRY GL_BlendFuncSeparateiEXT(GLuint buf,
+ GLenum srcRGB,
+ GLenum dstRGB,
+ GLenum srcAlpha,
+ GLenum dstAlpha);
+ANGLE_EXPORT void GL_APIENTRY GL_BlendFunciEXT(GLuint buf, GLenum src, GLenum dst);
+ANGLE_EXPORT void GL_APIENTRY
+GL_ColorMaskiEXT(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
+ANGLE_EXPORT void GL_APIENTRY GL_DisableiEXT(GLenum target, GLuint index);
+ANGLE_EXPORT void GL_APIENTRY GL_EnableiEXT(GLenum target, GLuint index);
+ANGLE_EXPORT GLboolean GL_APIENTRY GL_IsEnablediEXT(GLenum target, GLuint index);
+
+// GL_EXT_draw_elements_base_vertex
+ANGLE_EXPORT void GL_APIENTRY GL_DrawElementsBaseVertexEXT(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLint basevertex);
+ANGLE_EXPORT void GL_APIENTRY GL_DrawElementsInstancedBaseVertexEXT(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLsizei instancecount,
+ GLint basevertex);
+ANGLE_EXPORT void GL_APIENTRY GL_DrawRangeElementsBaseVertexEXT(GLenum mode,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLint basevertex);
+ANGLE_EXPORT void GL_APIENTRY GL_MultiDrawElementsBaseVertexEXT(GLenum mode,
+ const GLsizei *count,
+ GLenum type,
+ const void *const *indices,
+ GLsizei drawcount,
+ const GLint *basevertex);
+
+// GL_EXT_external_buffer
+ANGLE_EXPORT void GL_APIENTRY GL_BufferStorageExternalEXT(GLenum target,
+ GLintptr offset,
+ GLsizeiptr size,
+ GLeglClientBufferEXT clientBuffer,
+ GLbitfield flags);
+ANGLE_EXPORT void GL_APIENTRY GL_NamedBufferStorageExternalEXT(GLuint buffer,
+ GLintptr offset,
+ GLsizeiptr size,
+ GLeglClientBufferEXT clientBuffer,
+ GLbitfield flags);
+
+// GL_EXT_float_blend
+
+// GL_EXT_geometry_shader
+ANGLE_EXPORT void GL_APIENTRY GL_FramebufferTextureEXT(GLenum target,
+ GLenum attachment,
+ GLuint texture,
+ GLint level);
+
+// GL_EXT_gpu_shader5
+
+// GL_EXT_instanced_arrays
+ANGLE_EXPORT void GL_APIENTRY GL_DrawArraysInstancedEXT(GLenum mode,
+ GLint start,
+ GLsizei count,
+ GLsizei primcount);
+ANGLE_EXPORT void GL_APIENTRY GL_DrawElementsInstancedEXT(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLsizei primcount);
+ANGLE_EXPORT void GL_APIENTRY GL_VertexAttribDivisorEXT(GLuint index, GLuint divisor);
+
+// GL_EXT_map_buffer_range
+ANGLE_EXPORT void GL_APIENTRY GL_FlushMappedBufferRangeEXT(GLenum target,
+ GLintptr offset,
+ GLsizeiptr length);
+ANGLE_EXPORT void *GL_APIENTRY GL_MapBufferRangeEXT(GLenum target,
+ GLintptr offset,
+ GLsizeiptr length,
+ GLbitfield access);
+
+// GL_EXT_memory_object
+ANGLE_EXPORT void GL_APIENTRY GL_BufferStorageMemEXT(GLenum target,
+ GLsizeiptr size,
+ GLuint memory,
+ GLuint64 offset);
+ANGLE_EXPORT void GL_APIENTRY GL_CreateMemoryObjectsEXT(GLsizei n, GLuint *memoryObjects);
+ANGLE_EXPORT void GL_APIENTRY GL_DeleteMemoryObjectsEXT(GLsizei n, const GLuint *memoryObjects);
+ANGLE_EXPORT void GL_APIENTRY GL_GetMemoryObjectParameterivEXT(GLuint memoryObject,
+ GLenum pname,
+ GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetUnsignedBytevEXT(GLenum pname, GLubyte *data);
+ANGLE_EXPORT void GL_APIENTRY GL_GetUnsignedBytei_vEXT(GLenum target, GLuint index, GLubyte *data);
+ANGLE_EXPORT GLboolean GL_APIENTRY GL_IsMemoryObjectEXT(GLuint memoryObject);
+ANGLE_EXPORT void GL_APIENTRY GL_MemoryObjectParameterivEXT(GLuint memoryObject,
+ GLenum pname,
+ const GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_TexStorageMem2DEXT(GLenum target,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLuint memory,
+ GLuint64 offset);
+ANGLE_EXPORT void GL_APIENTRY GL_TexStorageMem2DMultisampleEXT(GLenum target,
+ GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedSampleLocations,
+ GLuint memory,
+ GLuint64 offset);
+ANGLE_EXPORT void GL_APIENTRY GL_TexStorageMem3DEXT(GLenum target,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLuint memory,
+ GLuint64 offset);
+ANGLE_EXPORT void GL_APIENTRY GL_TexStorageMem3DMultisampleEXT(GLenum target,
+ GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean fixedSampleLocations,
+ GLuint memory,
+ GLuint64 offset);
+
+// GL_EXT_memory_object_fd
+ANGLE_EXPORT void GL_APIENTRY GL_ImportMemoryFdEXT(GLuint memory,
+ GLuint64 size,
+ GLenum handleType,
+ GLint fd);
+
+// GL_EXT_multi_draw_indirect
+ANGLE_EXPORT void GL_APIENTRY GL_MultiDrawArraysIndirectEXT(GLenum mode,
+ const void *indirect,
+ GLsizei drawcount,
+ GLsizei stride);
+ANGLE_EXPORT void GL_APIENTRY GL_MultiDrawElementsIndirectEXT(GLenum mode,
+ GLenum type,
+ const void *indirect,
+ GLsizei drawcount,
+ GLsizei stride);
+
+// GL_EXT_multisampled_render_to_texture
+ANGLE_EXPORT void GL_APIENTRY GL_FramebufferTexture2DMultisampleEXT(GLenum target,
+ GLenum attachment,
+ GLenum textarget,
+ GLuint texture,
+ GLint level,
+ GLsizei samples);
+ANGLE_EXPORT void GL_APIENTRY GL_RenderbufferStorageMultisampleEXT(GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height);
+
+// GL_EXT_multisampled_render_to_texture2
+
+// GL_EXT_occlusion_query_boolean
+
+// GL_EXT_primitive_bounding_box
+ANGLE_EXPORT void GL_APIENTRY GL_PrimitiveBoundingBoxEXT(GLfloat minX,
+ GLfloat minY,
+ GLfloat minZ,
+ GLfloat minW,
+ GLfloat maxX,
+ GLfloat maxY,
+ GLfloat maxZ,
+ GLfloat maxW);
+
+// GL_EXT_protected_textures
+
+// GL_EXT_pvrtc_sRGB
+
+// GL_EXT_read_format_bgra
+
+// GL_EXT_robustness
+ANGLE_EXPORT GLenum GL_APIENTRY GL_GetGraphicsResetStatusEXT();
+ANGLE_EXPORT void GL_APIENTRY GL_GetnUniformfvEXT(GLuint program,
+ GLint location,
+ GLsizei bufSize,
+ GLfloat *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetnUniformivEXT(GLuint program,
+ GLint location,
+ GLsizei bufSize,
+ GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_ReadnPixelsEXT(GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ void *data);
+
+// GL_EXT_sRGB
+
+// GL_EXT_sRGB_write_control
+
+// GL_EXT_semaphore
+ANGLE_EXPORT void GL_APIENTRY GL_DeleteSemaphoresEXT(GLsizei n, const GLuint *semaphores);
+ANGLE_EXPORT void GL_APIENTRY GL_GenSemaphoresEXT(GLsizei n, GLuint *semaphores);
+ANGLE_EXPORT void GL_APIENTRY GL_GetSemaphoreParameterui64vEXT(GLuint semaphore,
+ GLenum pname,
+ GLuint64 *params);
+ANGLE_EXPORT GLboolean GL_APIENTRY GL_IsSemaphoreEXT(GLuint semaphore);
+ANGLE_EXPORT void GL_APIENTRY GL_SemaphoreParameterui64vEXT(GLuint semaphore,
+ GLenum pname,
+ const GLuint64 *params);
+ANGLE_EXPORT void GL_APIENTRY GL_SignalSemaphoreEXT(GLuint semaphore,
+ GLuint numBufferBarriers,
+ const GLuint *buffers,
+ GLuint numTextureBarriers,
+ const GLuint *textures,
+ const GLenum *dstLayouts);
+ANGLE_EXPORT void GL_APIENTRY GL_WaitSemaphoreEXT(GLuint semaphore,
+ GLuint numBufferBarriers,
+ const GLuint *buffers,
+ GLuint numTextureBarriers,
+ const GLuint *textures,
+ const GLenum *srcLayouts);
+
+// GL_EXT_semaphore_fd
+ANGLE_EXPORT void GL_APIENTRY GL_ImportSemaphoreFdEXT(GLuint semaphore,
+ GLenum handleType,
+ GLint fd);
+
+// GL_EXT_separate_shader_objects
+ANGLE_EXPORT void GL_APIENTRY GL_ActiveShaderProgramEXT(GLuint pipeline, GLuint program);
+ANGLE_EXPORT void GL_APIENTRY GL_BindProgramPipelineEXT(GLuint pipeline);
+ANGLE_EXPORT GLuint GL_APIENTRY GL_CreateShaderProgramvEXT(GLenum type,
+ GLsizei count,
+ const GLchar **strings);
+ANGLE_EXPORT void GL_APIENTRY GL_DeleteProgramPipelinesEXT(GLsizei n, const GLuint *pipelines);
+ANGLE_EXPORT void GL_APIENTRY GL_GenProgramPipelinesEXT(GLsizei n, GLuint *pipelines);
+ANGLE_EXPORT void GL_APIENTRY GL_GetProgramPipelineInfoLogEXT(GLuint pipeline,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *infoLog);
+ANGLE_EXPORT void GL_APIENTRY GL_GetProgramPipelineivEXT(GLuint pipeline,
+ GLenum pname,
+ GLint *params);
+ANGLE_EXPORT GLboolean GL_APIENTRY GL_IsProgramPipelineEXT(GLuint pipeline);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramParameteriEXT(GLuint program, GLenum pname, GLint value);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniform1fEXT(GLuint program, GLint location, GLfloat v0);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniform1fvEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniform1iEXT(GLuint program, GLint location, GLint v0);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniform1ivEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLint *value);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniform1uiEXT(GLuint program, GLint location, GLuint v0);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniform1uivEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLuint *value);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniform2fEXT(GLuint program,
+ GLint location,
+ GLfloat v0,
+ GLfloat v1);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniform2fvEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniform2iEXT(GLuint program,
+ GLint location,
+ GLint v0,
+ GLint v1);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniform2ivEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLint *value);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniform2uiEXT(GLuint program,
+ GLint location,
+ GLuint v0,
+ GLuint v1);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniform2uivEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLuint *value);
+ANGLE_EXPORT void GL_APIENTRY
+GL_ProgramUniform3fEXT(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniform3fvEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY
+GL_ProgramUniform3iEXT(GLuint program, GLint location, GLint v0, GLint v1, GLint v2);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniform3ivEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLint *value);
+ANGLE_EXPORT void GL_APIENTRY
+GL_ProgramUniform3uiEXT(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniform3uivEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLuint *value);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniform4fEXT(GLuint program,
+ GLint location,
+ GLfloat v0,
+ GLfloat v1,
+ GLfloat v2,
+ GLfloat v3);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniform4fvEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY
+GL_ProgramUniform4iEXT(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniform4ivEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLint *value);
+ANGLE_EXPORT void GL_APIENTRY
+GL_ProgramUniform4uiEXT(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniform4uivEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLuint *value);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniformMatrix2fvEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniformMatrix2x3fvEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniformMatrix2x4fvEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniformMatrix3fvEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniformMatrix3x2fvEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniformMatrix3x4fvEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniformMatrix4fvEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniformMatrix4x2fvEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramUniformMatrix4x3fvEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value);
+ANGLE_EXPORT void GL_APIENTRY GL_UseProgramStagesEXT(GLuint pipeline,
+ GLbitfield stages,
+ GLuint program);
+ANGLE_EXPORT void GL_APIENTRY GL_ValidateProgramPipelineEXT(GLuint pipeline);
+
+// GL_EXT_shader_framebuffer_fetch
+
+// GL_EXT_shader_framebuffer_fetch_non_coherent
+ANGLE_EXPORT void GL_APIENTRY GL_FramebufferFetchBarrierEXT();
+
+// GL_EXT_shader_io_blocks
+
+// GL_EXT_shader_non_constant_global_initializers
+
+// GL_EXT_shader_texture_lod
+
+// GL_EXT_shadow_samplers
+
+// GL_EXT_tessellation_shader
+ANGLE_EXPORT void GL_APIENTRY GL_PatchParameteriEXT(GLenum pname, GLint value);
+
+// GL_EXT_texture_border_clamp
+ANGLE_EXPORT void GL_APIENTRY GL_GetSamplerParameterIivEXT(GLuint sampler,
+ GLenum pname,
+ GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetSamplerParameterIuivEXT(GLuint sampler,
+ GLenum pname,
+ GLuint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetTexParameterIivEXT(GLenum target, GLenum pname, GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetTexParameterIuivEXT(GLenum target,
+ GLenum pname,
+ GLuint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_SamplerParameterIivEXT(GLuint sampler,
+ GLenum pname,
+ const GLint *param);
+ANGLE_EXPORT void GL_APIENTRY GL_SamplerParameterIuivEXT(GLuint sampler,
+ GLenum pname,
+ const GLuint *param);
+ANGLE_EXPORT void GL_APIENTRY GL_TexParameterIivEXT(GLenum target,
+ GLenum pname,
+ const GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_TexParameterIuivEXT(GLenum target,
+ GLenum pname,
+ const GLuint *params);
+
+// GL_EXT_texture_buffer
+ANGLE_EXPORT void GL_APIENTRY GL_TexBufferEXT(GLenum target, GLenum internalformat, GLuint buffer);
+ANGLE_EXPORT void GL_APIENTRY GL_TexBufferRangeEXT(GLenum target,
+ GLenum internalformat,
+ GLuint buffer,
+ GLintptr offset,
+ GLsizeiptr size);
+
+// GL_EXT_texture_compression_bptc
+
+// GL_EXT_texture_compression_dxt1
+
+// GL_EXT_texture_compression_rgtc
+
+// GL_EXT_texture_compression_s3tc
+
+// GL_EXT_texture_compression_s3tc_srgb
+
+// GL_EXT_texture_cube_map_array
+
+// GL_EXT_texture_filter_anisotropic
+
+// GL_EXT_texture_format_BGRA8888
+
+// GL_EXT_texture_format_sRGB_override
+
+// GL_EXT_texture_norm16
+
+// GL_EXT_texture_rg
+
+// GL_EXT_texture_sRGB_R8
+
+// GL_EXT_texture_sRGB_RG8
+
+// GL_EXT_texture_sRGB_decode
+
+// GL_EXT_texture_storage
+ANGLE_EXPORT void GL_APIENTRY GL_TexStorage1DEXT(GLenum target,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width);
+ANGLE_EXPORT void GL_APIENTRY GL_TexStorage2DEXT(GLenum target,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height);
+ANGLE_EXPORT void GL_APIENTRY GL_TexStorage3DEXT(GLenum target,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth);
+
+// GL_EXT_texture_type_2_10_10_10_REV
+
+// GL_EXT_unpack_subimage
+
+// GL_IMG_texture_compression_pvrtc
+
+// GL_IMG_texture_compression_pvrtc2
+
+// GL_KHR_blend_equation_advanced
+ANGLE_EXPORT void GL_APIENTRY GL_BlendBarrierKHR();
+
+// GL_KHR_debug
+ANGLE_EXPORT void GL_APIENTRY GL_DebugMessageCallbackKHR(GLDEBUGPROCKHR callback,
+ const void *userParam);
+ANGLE_EXPORT void GL_APIENTRY GL_DebugMessageControlKHR(GLenum source,
+ GLenum type,
+ GLenum severity,
+ GLsizei count,
+ const GLuint *ids,
+ GLboolean enabled);
+ANGLE_EXPORT void GL_APIENTRY GL_DebugMessageInsertKHR(GLenum source,
+ GLenum type,
+ GLuint id,
+ GLenum severity,
+ GLsizei length,
+ const GLchar *buf);
+ANGLE_EXPORT GLuint GL_APIENTRY GL_GetDebugMessageLogKHR(GLuint count,
+ GLsizei bufSize,
+ GLenum *sources,
+ GLenum *types,
+ GLuint *ids,
+ GLenum *severities,
+ GLsizei *lengths,
+ GLchar *messageLog);
+ANGLE_EXPORT void GL_APIENTRY GL_GetObjectLabelKHR(GLenum identifier,
+ GLuint name,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *label);
+ANGLE_EXPORT void GL_APIENTRY GL_GetObjectPtrLabelKHR(const void *ptr,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *label);
+ANGLE_EXPORT void GL_APIENTRY GL_GetPointervKHR(GLenum pname, void **params);
+ANGLE_EXPORT void GL_APIENTRY GL_ObjectLabelKHR(GLenum identifier,
+ GLuint name,
+ GLsizei length,
+ const GLchar *label);
+ANGLE_EXPORT void GL_APIENTRY GL_ObjectPtrLabelKHR(const void *ptr,
+ GLsizei length,
+ const GLchar *label);
+ANGLE_EXPORT void GL_APIENTRY GL_PopDebugGroupKHR();
+ANGLE_EXPORT void GL_APIENTRY GL_PushDebugGroupKHR(GLenum source,
+ GLuint id,
+ GLsizei length,
+ const GLchar *message);
+
+// GL_KHR_no_error
+
+// GL_KHR_parallel_shader_compile
+ANGLE_EXPORT void GL_APIENTRY GL_MaxShaderCompilerThreadsKHR(GLuint count);
+
+// GL_KHR_robust_buffer_access_behavior
+
+// GL_KHR_texture_compression_astc_hdr
+
+// GL_KHR_texture_compression_astc_ldr
+
+// GL_KHR_texture_compression_astc_sliced_3d
+
+// GL_MESA_framebuffer_flip_y
+ANGLE_EXPORT void GL_APIENTRY GL_FramebufferParameteriMESA(GLenum target,
+ GLenum pname,
+ GLint param);
+ANGLE_EXPORT void GL_APIENTRY GL_GetFramebufferParameterivMESA(GLenum target,
+ GLenum pname,
+ GLint *params);
+
+// GL_NV_fence
+ANGLE_EXPORT void GL_APIENTRY GL_DeleteFencesNV(GLsizei n, const GLuint *fences);
+ANGLE_EXPORT void GL_APIENTRY GL_FinishFenceNV(GLuint fence);
+ANGLE_EXPORT void GL_APIENTRY GL_GenFencesNV(GLsizei n, GLuint *fences);
+ANGLE_EXPORT void GL_APIENTRY GL_GetFenceivNV(GLuint fence, GLenum pname, GLint *params);
+ANGLE_EXPORT GLboolean GL_APIENTRY GL_IsFenceNV(GLuint fence);
+ANGLE_EXPORT void GL_APIENTRY GL_SetFenceNV(GLuint fence, GLenum condition);
+ANGLE_EXPORT GLboolean GL_APIENTRY GL_TestFenceNV(GLuint fence);
+
+// GL_NV_framebuffer_blit
+ANGLE_EXPORT void GL_APIENTRY GL_BlitFramebufferNV(GLint srcX0,
+ GLint srcY0,
+ GLint srcX1,
+ GLint srcY1,
+ GLint dstX0,
+ GLint dstY0,
+ GLint dstX1,
+ GLint dstY1,
+ GLbitfield mask,
+ GLenum filter);
+
+// GL_NV_pixel_buffer_object
+
+// GL_NV_read_depth
+
+// GL_NV_read_depth_stencil
+
+// GL_NV_read_stencil
+
+// GL_NV_robustness_video_memory_purge
+
+// GL_NV_shader_noperspective_interpolation
+
+// GL_OES_EGL_image
+ANGLE_EXPORT void GL_APIENTRY GL_EGLImageTargetRenderbufferStorageOES(GLenum target,
+ GLeglImageOES image);
+ANGLE_EXPORT void GL_APIENTRY GL_EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image);
+
+// GL_OES_EGL_image_external
+
+// GL_OES_EGL_image_external_essl3
+
+// GL_OES_compressed_ETC1_RGB8_texture
+
+// GL_OES_compressed_paletted_texture
+
+// GL_OES_copy_image
+ANGLE_EXPORT void GL_APIENTRY GL_CopyImageSubDataOES(GLuint srcName,
+ GLenum srcTarget,
+ GLint srcLevel,
+ GLint srcX,
+ GLint srcY,
+ GLint srcZ,
+ GLuint dstName,
+ GLenum dstTarget,
+ GLint dstLevel,
+ GLint dstX,
+ GLint dstY,
+ GLint dstZ,
+ GLsizei srcWidth,
+ GLsizei srcHeight,
+ GLsizei srcDepth);
+
+// GL_OES_depth24
+
+// GL_OES_depth32
+
+// GL_OES_depth_texture
+
+// GL_OES_draw_buffers_indexed
+ANGLE_EXPORT void GL_APIENTRY GL_BlendEquationSeparateiOES(GLuint buf,
+ GLenum modeRGB,
+ GLenum modeAlpha);
+ANGLE_EXPORT void GL_APIENTRY GL_BlendEquationiOES(GLuint buf, GLenum mode);
+ANGLE_EXPORT void GL_APIENTRY GL_BlendFuncSeparateiOES(GLuint buf,
+ GLenum srcRGB,
+ GLenum dstRGB,
+ GLenum srcAlpha,
+ GLenum dstAlpha);
+ANGLE_EXPORT void GL_APIENTRY GL_BlendFunciOES(GLuint buf, GLenum src, GLenum dst);
+ANGLE_EXPORT void GL_APIENTRY
+GL_ColorMaskiOES(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
+ANGLE_EXPORT void GL_APIENTRY GL_DisableiOES(GLenum target, GLuint index);
+ANGLE_EXPORT void GL_APIENTRY GL_EnableiOES(GLenum target, GLuint index);
+ANGLE_EXPORT GLboolean GL_APIENTRY GL_IsEnablediOES(GLenum target, GLuint index);
+
+// GL_OES_draw_elements_base_vertex
+ANGLE_EXPORT void GL_APIENTRY GL_DrawElementsBaseVertexOES(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLint basevertex);
+ANGLE_EXPORT void GL_APIENTRY GL_DrawElementsInstancedBaseVertexOES(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLsizei instancecount,
+ GLint basevertex);
+ANGLE_EXPORT void GL_APIENTRY GL_DrawRangeElementsBaseVertexOES(GLenum mode,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLint basevertex);
+
+// GL_OES_draw_texture
+ANGLE_EXPORT void GL_APIENTRY
+GL_DrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height);
+ANGLE_EXPORT void GL_APIENTRY GL_DrawTexfvOES(const GLfloat *coords);
+ANGLE_EXPORT void GL_APIENTRY GL_DrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height);
+ANGLE_EXPORT void GL_APIENTRY GL_DrawTexivOES(const GLint *coords);
+ANGLE_EXPORT void GL_APIENTRY
+GL_DrawTexsOES(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height);
+ANGLE_EXPORT void GL_APIENTRY GL_DrawTexsvOES(const GLshort *coords);
+ANGLE_EXPORT void GL_APIENTRY
+GL_DrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height);
+ANGLE_EXPORT void GL_APIENTRY GL_DrawTexxvOES(const GLfixed *coords);
+
+// GL_OES_element_index_uint
+
+// GL_OES_fbo_render_mipmap
+
+// GL_OES_framebuffer_object
+ANGLE_EXPORT void GL_APIENTRY GL_BindFramebufferOES(GLenum target, GLuint framebuffer);
+ANGLE_EXPORT void GL_APIENTRY GL_BindRenderbufferOES(GLenum target, GLuint renderbuffer);
+ANGLE_EXPORT GLenum GL_APIENTRY GL_CheckFramebufferStatusOES(GLenum target);
+ANGLE_EXPORT void GL_APIENTRY GL_DeleteFramebuffersOES(GLsizei n, const GLuint *framebuffers);
+ANGLE_EXPORT void GL_APIENTRY GL_DeleteRenderbuffersOES(GLsizei n, const GLuint *renderbuffers);
+ANGLE_EXPORT void GL_APIENTRY GL_FramebufferRenderbufferOES(GLenum target,
+ GLenum attachment,
+ GLenum renderbuffertarget,
+ GLuint renderbuffer);
+ANGLE_EXPORT void GL_APIENTRY GL_FramebufferTexture2DOES(GLenum target,
+ GLenum attachment,
+ GLenum textarget,
+ GLuint texture,
+ GLint level);
+ANGLE_EXPORT void GL_APIENTRY GL_GenFramebuffersOES(GLsizei n, GLuint *framebuffers);
+ANGLE_EXPORT void GL_APIENTRY GL_GenRenderbuffersOES(GLsizei n, GLuint *renderbuffers);
+ANGLE_EXPORT void GL_APIENTRY GL_GenerateMipmapOES(GLenum target);
+ANGLE_EXPORT void GL_APIENTRY GL_GetFramebufferAttachmentParameterivOES(GLenum target,
+ GLenum attachment,
+ GLenum pname,
+ GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetRenderbufferParameterivOES(GLenum target,
+ GLenum pname,
+ GLint *params);
+ANGLE_EXPORT GLboolean GL_APIENTRY GL_IsFramebufferOES(GLuint framebuffer);
+ANGLE_EXPORT GLboolean GL_APIENTRY GL_IsRenderbufferOES(GLuint renderbuffer);
+ANGLE_EXPORT void GL_APIENTRY GL_RenderbufferStorageOES(GLenum target,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height);
+
+// GL_OES_geometry_shader
+ANGLE_EXPORT void GL_APIENTRY GL_FramebufferTextureOES(GLenum target,
+ GLenum attachment,
+ GLuint texture,
+ GLint level);
+
+// GL_OES_get_program_binary
+ANGLE_EXPORT void GL_APIENTRY GL_GetProgramBinaryOES(GLuint program,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLenum *binaryFormat,
+ void *binary);
+ANGLE_EXPORT void GL_APIENTRY GL_ProgramBinaryOES(GLuint program,
+ GLenum binaryFormat,
+ const void *binary,
+ GLint length);
+
+// GL_OES_mapbuffer
+ANGLE_EXPORT void GL_APIENTRY GL_GetBufferPointervOES(GLenum target, GLenum pname, void **params);
+ANGLE_EXPORT void *GL_APIENTRY GL_MapBufferOES(GLenum target, GLenum access);
+ANGLE_EXPORT GLboolean GL_APIENTRY GL_UnmapBufferOES(GLenum target);
+
+// GL_OES_matrix_palette
+ANGLE_EXPORT void GL_APIENTRY GL_CurrentPaletteMatrixOES(GLuint matrixpaletteindex);
+ANGLE_EXPORT void GL_APIENTRY GL_LoadPaletteFromModelViewMatrixOES();
+ANGLE_EXPORT void GL_APIENTRY GL_MatrixIndexPointerOES(GLint size,
+ GLenum type,
+ GLsizei stride,
+ const void *pointer);
+ANGLE_EXPORT void GL_APIENTRY GL_WeightPointerOES(GLint size,
+ GLenum type,
+ GLsizei stride,
+ const void *pointer);
+
+// GL_OES_packed_depth_stencil
+
+// GL_OES_point_size_array
+ANGLE_EXPORT void GL_APIENTRY GL_PointSizePointerOES(GLenum type,
+ GLsizei stride,
+ const void *pointer);
+
+// GL_OES_point_sprite
+
+// GL_OES_primitive_bounding_box
+ANGLE_EXPORT void GL_APIENTRY GL_PrimitiveBoundingBoxOES(GLfloat minX,
+ GLfloat minY,
+ GLfloat minZ,
+ GLfloat minW,
+ GLfloat maxX,
+ GLfloat maxY,
+ GLfloat maxZ,
+ GLfloat maxW);
+
+// GL_OES_query_matrix
+ANGLE_EXPORT GLbitfield GL_APIENTRY GL_QueryMatrixxOES(GLfixed *mantissa, GLint *exponent);
+
+// GL_OES_rgb8_rgba8
+
+// GL_OES_sample_shading
+ANGLE_EXPORT void GL_APIENTRY GL_MinSampleShadingOES(GLfloat value);
+
+// GL_OES_sample_variables
+
+// GL_OES_shader_image_atomic
+
+// GL_OES_shader_io_blocks
+
+// GL_OES_shader_multisample_interpolation
+
+// GL_OES_standard_derivatives
+
+// GL_OES_surfaceless_context
+
+// GL_OES_texture_3D
+ANGLE_EXPORT void GL_APIENTRY GL_CompressedTexImage3DOES(GLenum target,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLsizei imageSize,
+ const void *data);
+ANGLE_EXPORT void GL_APIENTRY GL_CompressedTexSubImage3DOES(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data);
+ANGLE_EXPORT void GL_APIENTRY GL_CopyTexSubImage3DOES(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height);
+ANGLE_EXPORT void GL_APIENTRY GL_FramebufferTexture3DOES(GLenum target,
+ GLenum attachment,
+ GLenum textarget,
+ GLuint texture,
+ GLint level,
+ GLint zoffset);
+ANGLE_EXPORT void GL_APIENTRY GL_TexImage3DOES(GLenum target,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const void *pixels);
+ANGLE_EXPORT void GL_APIENTRY GL_TexSubImage3DOES(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ const void *pixels);
+
+// GL_OES_texture_border_clamp
+ANGLE_EXPORT void GL_APIENTRY GL_GetSamplerParameterIivOES(GLuint sampler,
+ GLenum pname,
+ GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetSamplerParameterIuivOES(GLuint sampler,
+ GLenum pname,
+ GLuint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetTexParameterIivOES(GLenum target, GLenum pname, GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetTexParameterIuivOES(GLenum target,
+ GLenum pname,
+ GLuint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_SamplerParameterIivOES(GLuint sampler,
+ GLenum pname,
+ const GLint *param);
+ANGLE_EXPORT void GL_APIENTRY GL_SamplerParameterIuivOES(GLuint sampler,
+ GLenum pname,
+ const GLuint *param);
+ANGLE_EXPORT void GL_APIENTRY GL_TexParameterIivOES(GLenum target,
+ GLenum pname,
+ const GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_TexParameterIuivOES(GLenum target,
+ GLenum pname,
+ const GLuint *params);
+
+// GL_OES_texture_buffer
+ANGLE_EXPORT void GL_APIENTRY GL_TexBufferOES(GLenum target, GLenum internalformat, GLuint buffer);
+ANGLE_EXPORT void GL_APIENTRY GL_TexBufferRangeOES(GLenum target,
+ GLenum internalformat,
+ GLuint buffer,
+ GLintptr offset,
+ GLsizeiptr size);
+
+// GL_OES_texture_compression_astc
+
+// GL_OES_texture_cube_map
+ANGLE_EXPORT void GL_APIENTRY GL_GetTexGenfvOES(GLenum coord, GLenum pname, GLfloat *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetTexGenivOES(GLenum coord, GLenum pname, GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_GetTexGenxvOES(GLenum coord, GLenum pname, GLfixed *params);
+ANGLE_EXPORT void GL_APIENTRY GL_TexGenfOES(GLenum coord, GLenum pname, GLfloat param);
+ANGLE_EXPORT void GL_APIENTRY GL_TexGenfvOES(GLenum coord, GLenum pname, const GLfloat *params);
+ANGLE_EXPORT void GL_APIENTRY GL_TexGeniOES(GLenum coord, GLenum pname, GLint param);
+ANGLE_EXPORT void GL_APIENTRY GL_TexGenivOES(GLenum coord, GLenum pname, const GLint *params);
+ANGLE_EXPORT void GL_APIENTRY GL_TexGenxOES(GLenum coord, GLenum pname, GLfixed param);
+ANGLE_EXPORT void GL_APIENTRY GL_TexGenxvOES(GLenum coord, GLenum pname, const GLfixed *params);
+
+// GL_OES_texture_cube_map_array
+
+// GL_OES_texture_float
+
+// GL_OES_texture_float_linear
+
+// GL_OES_texture_half_float
+
+// GL_OES_texture_half_float_linear
+
+// GL_OES_texture_npot
+
+// GL_OES_texture_stencil8
+
+// GL_OES_texture_storage_multisample_2d_array
+ANGLE_EXPORT void GL_APIENTRY GL_TexStorage3DMultisampleOES(GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean fixedsamplelocations);
+
+// GL_OES_vertex_array_object
+ANGLE_EXPORT void GL_APIENTRY GL_BindVertexArrayOES(GLuint array);
+ANGLE_EXPORT void GL_APIENTRY GL_DeleteVertexArraysOES(GLsizei n, const GLuint *arrays);
+ANGLE_EXPORT void GL_APIENTRY GL_GenVertexArraysOES(GLsizei n, GLuint *arrays);
+ANGLE_EXPORT GLboolean GL_APIENTRY GL_IsVertexArrayOES(GLuint array);
+
+// GL_OES_vertex_half_float
+
+// GL_OES_vertex_type_10_10_10_2
+
+// GL_OVR_multiview
+ANGLE_EXPORT void GL_APIENTRY GL_FramebufferTextureMultiviewOVR(GLenum target,
+ GLenum attachment,
+ GLuint texture,
+ GLint level,
+ GLint baseViewIndex,
+ GLsizei numViews);
+
+// GL_OVR_multiview2
+
+// GL_QCOM_shading_rate
+ANGLE_EXPORT void GL_APIENTRY GL_ShadingRateQCOM(GLenum rate);
+} // extern "C"
+
+#endif // LIBGLESV2_ENTRY_POINTS_GLES_EXT_AUTOGEN_H_
diff --git a/gfx/angle/checkout/src/libGLESv2/global_state.cpp b/gfx/angle/checkout/src/libGLESv2/global_state.cpp
new file mode 100644
index 0000000000..c776980524
--- /dev/null
+++ b/gfx/angle/checkout/src/libGLESv2/global_state.cpp
@@ -0,0 +1,373 @@
+//
+// 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.
+//
+
+// global_state.cpp : Implements functions for querying the thread-local GL and EGL state.
+
+#include "libGLESv2/global_state.h"
+
+#include "common/debug.h"
+#include "common/platform.h"
+#include "common/system_utils.h"
+#include "libANGLE/ErrorStrings.h"
+#include "libANGLE/Thread.h"
+#include "libGLESv2/resource.h"
+
+#include <atomic>
+#if defined(ANGLE_PLATFORM_APPLE)
+# include <dispatch/dispatch.h>
+#endif
+namespace egl
+{
+namespace
+{
+ANGLE_REQUIRE_CONSTANT_INIT std::atomic<angle::GlobalMutex *> g_Mutex{};
+static_assert(std::is_trivially_destructible<decltype(g_Mutex)>::value,
+ "global mutex is not trivially destructible");
+ANGLE_REQUIRE_CONSTANT_INIT std::atomic<angle::GlobalMutex *> g_SurfaceMutex{};
+static_assert(std::is_trivially_destructible<decltype(g_SurfaceMutex)>::value,
+ "global mutex is not trivially destructible");
+
+ANGLE_REQUIRE_CONSTANT_INIT gl::Context *g_LastContext(nullptr);
+static_assert(std::is_trivially_destructible<decltype(g_LastContext)>::value,
+ "global last context is not trivially destructible");
+
+void SetContextToAndroidOpenGLTLSSlot(gl::Context *value)
+{
+#if defined(ANGLE_USE_ANDROID_TLS_SLOT)
+ if (angle::gUseAndroidOpenGLTlsSlot)
+ {
+ ANGLE_ANDROID_GET_GL_TLS()[angle::kAndroidOpenGLTlsSlot] = static_cast<void *>(value);
+ }
+#endif
+}
+
+// Called only on Android platform
+[[maybe_unused]] void ThreadCleanupCallback(void *ptr)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ angle::PthreadKeyDestructorCallback(ptr);
+}
+
+Thread *AllocateCurrentThread()
+{
+ Thread *thread;
+ {
+ // Global thread intentionally leaked
+ ANGLE_SCOPED_DISABLE_LSAN();
+ thread = new Thread();
+#if defined(ANGLE_PLATFORM_APPLE)
+ SetCurrentThreadTLS(thread);
+#else
+ gCurrentThread = thread;
+#endif
+ }
+
+ // Initialize fast TLS slot
+ SetContextToAndroidOpenGLTLSSlot(nullptr);
+
+#if defined(ANGLE_PLATFORM_APPLE)
+ gl::SetCurrentValidContextTLS(nullptr);
+#else
+ gl::gCurrentValidContext = nullptr;
+#endif
+
+#if defined(ANGLE_PLATFORM_ANDROID)
+ static pthread_once_t keyOnce = PTHREAD_ONCE_INIT;
+ static TLSIndex gThreadCleanupTLSIndex = TLS_INVALID_INDEX;
+
+ // Create thread cleanup TLS slot
+ auto CreateThreadCleanupTLSIndex = []() {
+ gThreadCleanupTLSIndex = CreateTLSIndex(ThreadCleanupCallback);
+ };
+ pthread_once(&keyOnce, CreateThreadCleanupTLSIndex);
+ ASSERT(gThreadCleanupTLSIndex != TLS_INVALID_INDEX);
+
+ // Initialize thread cleanup TLS slot
+ SetTLSValue(gThreadCleanupTLSIndex, thread);
+#endif // ANGLE_PLATFORM_ANDROID
+
+ ASSERT(thread);
+ return thread;
+}
+
+void AllocateGlobalMutex(std::atomic<angle::GlobalMutex *> &mutex)
+{
+ if (mutex == nullptr)
+ {
+ std::unique_ptr<angle::GlobalMutex> newMutex(new angle::GlobalMutex());
+ angle::GlobalMutex *expected = nullptr;
+ if (mutex.compare_exchange_strong(expected, newMutex.get()))
+ {
+ newMutex.release();
+ }
+ }
+}
+
+void AllocateMutex()
+{
+ AllocateGlobalMutex(g_Mutex);
+}
+
+void AllocateSurfaceMutex()
+{
+ AllocateGlobalMutex(g_SurfaceMutex);
+}
+
+} // anonymous namespace
+
+#if defined(ANGLE_PLATFORM_APPLE)
+// TODO(angleproject:6479): Due to a bug in Apple's dyld loader, `thread_local` will cause
+// excessive memory use. Temporarily avoid it by using pthread's thread
+// local storage instead.
+// https://bugs.webkit.org/show_bug.cgi?id=228240
+
+static TLSIndex GetCurrentThreadTLSIndex()
+{
+ static TLSIndex CurrentThreadIndex = TLS_INVALID_INDEX;
+ static dispatch_once_t once;
+ dispatch_once(&once, ^{
+ ASSERT(CurrentThreadIndex == TLS_INVALID_INDEX);
+ CurrentThreadIndex = CreateTLSIndex(nullptr);
+ });
+ return CurrentThreadIndex;
+}
+Thread *GetCurrentThreadTLS()
+{
+ TLSIndex CurrentThreadIndex = GetCurrentThreadTLSIndex();
+ ASSERT(CurrentThreadIndex != TLS_INVALID_INDEX);
+ return static_cast<Thread *>(GetTLSValue(CurrentThreadIndex));
+}
+void SetCurrentThreadTLS(Thread *thread)
+{
+ TLSIndex CurrentThreadIndex = GetCurrentThreadTLSIndex();
+ ASSERT(CurrentThreadIndex != TLS_INVALID_INDEX);
+ SetTLSValue(CurrentThreadIndex, thread);
+}
+#else
+thread_local Thread *gCurrentThread = nullptr;
+#endif
+
+angle::GlobalMutex &GetGlobalMutex()
+{
+ AllocateMutex();
+ return *g_Mutex;
+}
+
+angle::GlobalMutex &GetGlobalSurfaceMutex()
+{
+ AllocateSurfaceMutex();
+ return *g_SurfaceMutex;
+}
+
+gl::Context *GetGlobalLastContext()
+{
+ return g_LastContext;
+}
+
+void SetGlobalLastContext(gl::Context *context)
+{
+ g_LastContext = context;
+}
+
+// This function causes an MSAN false positive, which is muted. See https://crbug.com/1211047
+// It also causes a flaky false positive in TSAN. http://crbug.com/1223970
+ANGLE_NO_SANITIZE_MEMORY ANGLE_NO_SANITIZE_THREAD Thread *GetCurrentThread()
+{
+#if defined(ANGLE_PLATFORM_APPLE)
+ Thread *current = GetCurrentThreadTLS();
+#else
+ Thread *current = gCurrentThread;
+#endif
+ return (current ? current : AllocateCurrentThread());
+}
+
+void SetContextCurrent(Thread *thread, gl::Context *context)
+{
+#if defined(ANGLE_PLATFORM_APPLE)
+ Thread *currentThread = GetCurrentThreadTLS();
+#else
+ Thread *currentThread = gCurrentThread;
+#endif
+ ASSERT(currentThread);
+ currentThread->setCurrent(context);
+ SetContextToAndroidOpenGLTLSSlot(context);
+
+#if defined(ANGLE_PLATFORM_APPLE)
+ gl::SetCurrentValidContextTLS(context);
+#else
+ gl::gCurrentValidContext = context;
+#endif
+
+#if defined(ANGLE_FORCE_CONTEXT_CHECK_EVERY_CALL)
+ DirtyContextIfNeeded(context);
+#endif
+}
+
+ScopedSyncCurrentContextFromThread::ScopedSyncCurrentContextFromThread(egl::Thread *thread)
+ : mThread(thread)
+{
+ ASSERT(mThread);
+}
+
+ScopedSyncCurrentContextFromThread::~ScopedSyncCurrentContextFromThread()
+{
+ SetContextCurrent(mThread, mThread->getContext());
+}
+
+} // namespace egl
+
+namespace gl
+{
+void GenerateContextLostErrorOnContext(Context *context)
+{
+ if (context && context->isContextLost())
+ {
+ context->validationError(angle::EntryPoint::GLInvalid, GL_CONTEXT_LOST, err::kContextLost);
+ }
+}
+
+void GenerateContextLostErrorOnCurrentGlobalContext()
+{
+ // If the client starts issuing GL calls before ANGLE has had a chance to initialize,
+ // GenerateContextLostErrorOnCurrentGlobalContext can be called before AllocateCurrentThread has
+ // had a chance to run. Calling GetCurrentThread() ensures that TLS thread state is set up.
+ egl::GetCurrentThread();
+
+ GenerateContextLostErrorOnContext(GetGlobalContext());
+}
+} // namespace gl
+
+#if defined(ANGLE_PLATFORM_WINDOWS) && !defined(ANGLE_STATIC)
+namespace egl
+{
+
+namespace
+{
+
+void DeallocateGlobalMutex(std::atomic<angle::GlobalMutex *> &mutex)
+{
+ angle::GlobalMutex *toDelete = mutex.exchange(nullptr);
+ if (!mutex)
+ return;
+ {
+ // Wait for toDelete to become released by other threads before deleting.
+ std::lock_guard<angle::GlobalMutex> lock(*toDelete);
+ }
+ SafeDelete(toDelete);
+}
+
+void DeallocateCurrentThread()
+{
+ SafeDelete(gCurrentThread);
+}
+
+void DeallocateMutex()
+{
+ DeallocateGlobalMutex(g_Mutex);
+}
+
+void DeallocateSurfaceMutex()
+{
+ DeallocateGlobalMutex(g_SurfaceMutex);
+}
+
+bool InitializeProcess()
+{
+ EnsureDebugAllocated();
+ AllocateMutex();
+ return AllocateCurrentThread() != nullptr;
+}
+
+void TerminateProcess()
+{
+ DeallocateDebug();
+ DeallocateSurfaceMutex();
+ DeallocateMutex();
+ DeallocateCurrentThread();
+}
+
+} // anonymous namespace
+
+} // namespace egl
+
+namespace
+{
+// The following WaitForDebugger code is based on SwiftShader. See:
+// https://cs.chromium.org/chromium/src/third_party/swiftshader/src/Vulkan/main.cpp
+# if defined(ANGLE_ENABLE_ASSERTS) && !defined(ANGLE_ENABLE_WINDOWS_UWP)
+INT_PTR CALLBACK DebuggerWaitDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ RECT rect;
+
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ ::GetWindowRect(GetDesktopWindow(), &rect);
+ ::SetWindowPos(hwnd, HWND_TOP, rect.right / 2, rect.bottom / 2, 0, 0, SWP_NOSIZE);
+ ::SetTimer(hwnd, 1, 100, NULL);
+ return TRUE;
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDCANCEL)
+ {
+ ::EndDialog(hwnd, 0);
+ }
+ break;
+ case WM_TIMER:
+ if (angle::IsDebuggerAttached())
+ {
+ ::EndDialog(hwnd, 0);
+ }
+ }
+
+ return FALSE;
+}
+
+void WaitForDebugger(HINSTANCE instance)
+{
+ if (angle::IsDebuggerAttached())
+ return;
+
+ HRSRC dialog = ::FindResourceA(instance, MAKEINTRESOURCEA(IDD_DIALOG1), MAKEINTRESOURCEA(5));
+ if (!dialog)
+ {
+ printf("Error finding wait for debugger dialog. Error %lu.\n", ::GetLastError());
+ return;
+ }
+
+ DLGTEMPLATE *dialogTemplate = reinterpret_cast<DLGTEMPLATE *>(::LoadResource(instance, dialog));
+ ::DialogBoxIndirectA(instance, dialogTemplate, NULL, DebuggerWaitDialogProc);
+}
+# else
+void WaitForDebugger(HINSTANCE instance) {}
+# endif // defined(ANGLE_ENABLE_ASSERTS) && !defined(ANGLE_ENABLE_WINDOWS_UWP)
+} // namespace
+
+extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID)
+{
+ switch (reason)
+ {
+ case DLL_PROCESS_ATTACH:
+ if (angle::GetEnvironmentVar("ANGLE_WAIT_FOR_DEBUGGER") == "1")
+ {
+ WaitForDebugger(instance);
+ }
+ return static_cast<BOOL>(egl::InitializeProcess());
+
+ case DLL_THREAD_ATTACH:
+ return static_cast<BOOL>(egl::AllocateCurrentThread() != nullptr);
+
+ case DLL_THREAD_DETACH:
+ egl::DeallocateCurrentThread();
+ break;
+
+ case DLL_PROCESS_DETACH:
+ egl::TerminateProcess();
+ break;
+ }
+
+ return TRUE;
+}
+#endif // defined(ANGLE_PLATFORM_WINDOWS) && !defined(ANGLE_STATIC)
diff --git a/gfx/angle/checkout/src/libGLESv2/global_state.h b/gfx/angle/checkout/src/libGLESv2/global_state.h
new file mode 100644
index 0000000000..947baf3c06
--- /dev/null
+++ b/gfx/angle/checkout/src/libGLESv2/global_state.h
@@ -0,0 +1,215 @@
+//
+// 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.
+//
+
+// global_state.h : Defines functions for querying the thread-local GL and EGL state.
+
+#ifndef LIBGLESV2_GLOBALSTATE_H_
+#define LIBGLESV2_GLOBALSTATE_H_
+
+#include "libANGLE/Context.h"
+#include "libANGLE/Debug.h"
+#include "libANGLE/Thread.h"
+#include "libANGLE/features.h"
+
+#if defined(ANGLE_PLATFORM_APPLE) || (ANGLE_PLATFORM_ANDROID)
+# include "common/tls.h"
+#endif
+
+#include <mutex>
+
+namespace angle
+{
+using GlobalMutex = std::recursive_mutex;
+
+// - TLS_SLOT_OPENGL and TLS_SLOT_OPENGL_API: These two aren't used by bionic
+// itself, but allow the graphics code to access TLS directly rather than
+// using the pthread API.
+//
+// Choose the TLS_SLOT_OPENGL TLS slot with the value that matches value in the header file in
+// bionic(tls_defines.h)
+constexpr size_t kAndroidOpenGLTlsSlot = 3;
+
+#if defined(ANGLE_PLATFORM_ANDROID)
+
+// The following ASM variant provides a much more performant store/retrieve interface
+// compared to those provided by the pthread library. These have been derived from code
+// in the bionic module of Android ->
+// https://cs.android.com/android/platform/superproject/+/master:bionic/libc/platform/bionic/tls.h;l=30
+
+# if defined(__aarch64__)
+# define ANGLE_ANDROID_GET_GL_TLS() \
+ ({ \
+ void **__val; \
+ __asm__("mrs %0, tpidr_el0" : "=r"(__val)); \
+ __val; \
+ })
+# elif defined(__arm__)
+# define ANGLE_ANDROID_GET_GL_TLS() \
+ ({ \
+ void **__val; \
+ __asm__("mrc p15, 0, %0, c13, c0, 3" : "=r"(__val)); \
+ __val; \
+ })
+# elif defined(__mips__)
+// On mips32r1, this goes via a kernel illegal instruction trap that's
+// optimized for v1
+# define ANGLE_ANDROID_GET_GL_TLS() \
+ ({ \
+ register void **__val asm("v1"); \
+ __asm__( \
+ ".set push\n" \
+ ".set mips32r2\n" \
+ "rdhwr %0,$29\n" \
+ ".set pop\n" \
+ : "=r"(__val)); \
+ __val; \
+ })
+# elif defined(__i386__)
+# define ANGLE_ANDROID_GET_GL_TLS() \
+ ({ \
+ void **__val; \
+ __asm__("movl %%gs:0, %0" : "=r"(__val)); \
+ __val; \
+ })
+# elif defined(__x86_64__)
+# define ANGLE_ANDROID_GET_GL_TLS() \
+ ({ \
+ void **__val; \
+ __asm__("mov %%fs:0, %0" : "=r"(__val)); \
+ __val; \
+ })
+# else
+# error unsupported architecture
+# endif
+
+#endif // ANGLE_PLATFORM_ANDROID
+} // namespace angle
+
+namespace egl
+{
+class Debug;
+class Thread;
+
+#if defined(ANGLE_PLATFORM_APPLE)
+extern Thread *GetCurrentThreadTLS();
+extern void SetCurrentThreadTLS(Thread *thread);
+#else
+extern thread_local Thread *gCurrentThread;
+#endif
+
+angle::GlobalMutex &GetGlobalMutex();
+angle::GlobalMutex &GetGlobalSurfaceMutex();
+gl::Context *GetGlobalLastContext();
+void SetGlobalLastContext(gl::Context *context);
+Thread *GetCurrentThread();
+Debug *GetDebug();
+
+// Sync the current context from Thread to global state.
+class [[nodiscard]] ScopedSyncCurrentContextFromThread
+{
+ public:
+ ScopedSyncCurrentContextFromThread(egl::Thread *thread);
+ ~ScopedSyncCurrentContextFromThread();
+
+ private:
+ egl::Thread *const mThread;
+};
+
+} // namespace egl
+
+#define ANGLE_GLOBAL_SURFACE_LOCK_VAR_NAME globalSurfaceMutexLock
+#define ANGLE_SCOPED_GLOBAL_SURFACE_LOCK() \
+ std::lock_guard<angle::GlobalMutex> ANGLE_GLOBAL_SURFACE_LOCK_VAR_NAME( \
+ egl::GetGlobalSurfaceMutex())
+
+#define ANGLE_GLOBAL_LOCK_VAR_NAME globalMutexLock
+#define ANGLE_SCOPED_GLOBAL_LOCK() \
+ std::lock_guard<angle::GlobalMutex> ANGLE_GLOBAL_LOCK_VAR_NAME(egl::GetGlobalMutex())
+
+namespace gl
+{
+ANGLE_INLINE Context *GetGlobalContext()
+{
+#if defined(ANGLE_USE_ANDROID_TLS_SLOT)
+ // TODO: Replace this branch with a compile time flag (http://anglebug.com/4764)
+ if (angle::gUseAndroidOpenGLTlsSlot)
+ {
+ return static_cast<gl::Context *>(ANGLE_ANDROID_GET_GL_TLS()[angle::kAndroidOpenGLTlsSlot]);
+ }
+#endif
+
+#if defined(ANGLE_PLATFORM_APPLE)
+ egl::Thread *currentThread = egl::GetCurrentThreadTLS();
+#else
+ egl::Thread *currentThread = egl::gCurrentThread;
+#endif
+ ASSERT(currentThread);
+ return currentThread->getContext();
+}
+
+ANGLE_INLINE Context *GetValidGlobalContext()
+{
+#if defined(ANGLE_USE_ANDROID_TLS_SLOT)
+ // TODO: Replace this branch with a compile time flag (http://anglebug.com/4764)
+ if (angle::gUseAndroidOpenGLTlsSlot)
+ {
+ Context *context =
+ static_cast<gl::Context *>(ANGLE_ANDROID_GET_GL_TLS()[angle::kAndroidOpenGLTlsSlot]);
+ if (context && !context->isContextLost())
+ {
+ return context;
+ }
+ }
+#endif
+
+#if defined(ANGLE_PLATFORM_APPLE)
+ return GetCurrentValidContextTLS();
+#else
+ return gCurrentValidContext;
+#endif
+}
+
+// Generate a context lost error on the context if it is non-null and lost.
+void GenerateContextLostErrorOnContext(Context *context);
+void GenerateContextLostErrorOnCurrentGlobalContext();
+
+#if defined(ANGLE_FORCE_CONTEXT_CHECK_EVERY_CALL)
+// TODO(b/177574181): This should be handled in a backend-specific way.
+// if previous context different from current context, dirty all state
+static ANGLE_INLINE void DirtyContextIfNeeded(Context *context)
+{
+ if (context && context != egl::GetGlobalLastContext())
+ {
+ context->dirtyAllState();
+ SetGlobalLastContext(context);
+ }
+}
+
+#endif
+
+#if !defined(ANGLE_ENABLE_SHARE_CONTEXT_LOCK)
+# define SCOPED_SHARE_CONTEXT_LOCK(context)
+#else
+ANGLE_INLINE std::unique_lock<angle::GlobalMutex> GetContextLock(Context *context)
+{
+# if defined(ANGLE_FORCE_CONTEXT_CHECK_EVERY_CALL)
+ auto lock = std::unique_lock<angle::GlobalMutex>(egl::GetGlobalMutex());
+
+ DirtyContextIfNeeded(context);
+ return lock;
+# else
+ return context->isShared() ? std::unique_lock<angle::GlobalMutex>(egl::GetGlobalMutex())
+ : std::unique_lock<angle::GlobalMutex>();
+# endif
+}
+
+# define SCOPED_SHARE_CONTEXT_LOCK(context) \
+ std::unique_lock<angle::GlobalMutex> shareContextLock = GetContextLock(context)
+#endif
+
+} // namespace gl
+
+#endif // LIBGLESV2_GLOBALSTATE_H_
diff --git a/gfx/angle/checkout/src/libGLESv2/libGLESv2.rc b/gfx/angle/checkout/src/libGLESv2/libGLESv2.rc
new file mode 100644
index 0000000000..2d2c9f9681
--- /dev/null
+++ b/gfx/angle/checkout/src/libGLESv2/libGLESv2.rc
@@ -0,0 +1,137 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include <windows.h>
+#include "../common/angle_version.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "#include ""../common/version.h""\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION ANGLE_MAJOR_VERSION,ANGLE_MINOR_VERSION,ANGLE_REVISION,0
+ PRODUCTVERSION ANGLE_MAJOR_VERSION,ANGLE_MINOR_VERSION,ANGLE_REVISION,0
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "FileDescription", "ANGLE libGLESv2 Dynamic Link Library"
+ VALUE "FileVersion", ANGLE_VERSION_STRING
+ VALUE "InternalName", "libGLESv2"
+ VALUE "LegalCopyright", "Copyright (C) 2015 Google Inc."
+ VALUE "OriginalFilename", "libGLESv2.dll"
+ VALUE "PrivateBuild", ANGLE_VERSION_STRING
+ VALUE "ProductName", "ANGLE libGLESv2 Dynamic Link Library"
+ VALUE "ProductVersion", ANGLE_VERSION_STRING
+ VALUE "Comments", "Build Date: " ANGLE_COMMIT_DATE
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_DIALOG1 DIALOGEX 0, 0, 129, 47
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Waiting for debugger"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+PUSHBUTTON "Cancel",IDCANCEL,72,26,50,14
+LTEXT "Attach a debugger or ESC to cancel",IDC_STATIC,7,7,115,8
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+IDD_DIALOG1, DIALOG
+BEGIN
+LEFTMARGIN, 7
+RIGHTMARGIN, 122
+TOPMARGIN, 7
+BOTTOMMARGIN, 40
+END
+END
+#endif // APSTUDIO_INVOKED
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
diff --git a/gfx/angle/checkout/src/libGLESv2/libGLESv2_autogen.cpp b/gfx/angle/checkout/src/libGLESv2/libGLESv2_autogen.cpp
new file mode 100644
index 0000000000..078dc810a0
--- /dev/null
+++ b/gfx/angle/checkout/src/libGLESv2/libGLESv2_autogen.cpp
@@ -0,0 +1,9704 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_entry_points.py using data from gl.xml and gl_angle_ext.xml.
+//
+// Copyright 2020 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.
+//
+// libGLESv2_autogen.cpp: Implements the exported OpenGL ES functions.
+
+#include "angle_gl.h"
+
+#include "libGLESv2/entry_points_gles_1_0_autogen.h"
+#include "libGLESv2/entry_points_gles_2_0_autogen.h"
+#include "libGLESv2/entry_points_gles_3_0_autogen.h"
+#include "libGLESv2/entry_points_gles_3_1_autogen.h"
+#include "libGLESv2/entry_points_gles_3_2_autogen.h"
+#include "libGLESv2/entry_points_gles_ext_autogen.h"
+
+#if defined(ANGLE_ENABLE_GL_DESKTOP_FRONTEND)
+# include "libGLESv2/entry_points_gl_1_autogen.h"
+# include "libGLESv2/entry_points_gl_2_autogen.h"
+# include "libGLESv2/entry_points_gl_3_autogen.h"
+# include "libGLESv2/entry_points_gl_4_autogen.h"
+#endif
+
+#include "common/event_tracer.h"
+
+extern "C" {
+
+// OpenGL ES 2.0
+void GL_APIENTRY glActiveTexture(GLenum texture)
+{
+ return GL_ActiveTexture(texture);
+}
+
+void GL_APIENTRY glAttachShader(GLuint program, GLuint shader)
+{
+ return GL_AttachShader(program, shader);
+}
+
+void GL_APIENTRY glBindAttribLocation(GLuint program, GLuint index, const GLchar *name)
+{
+ return GL_BindAttribLocation(program, index, name);
+}
+
+void GL_APIENTRY glBindBuffer(GLenum target, GLuint buffer)
+{
+ return GL_BindBuffer(target, buffer);
+}
+
+void GL_APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer)
+{
+ return GL_BindFramebuffer(target, framebuffer);
+}
+
+void GL_APIENTRY glBindRenderbuffer(GLenum target, GLuint renderbuffer)
+{
+ return GL_BindRenderbuffer(target, renderbuffer);
+}
+
+void GL_APIENTRY glBindTexture(GLenum target, GLuint texture)
+{
+ return GL_BindTexture(target, texture);
+}
+
+void GL_APIENTRY glBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+ return GL_BlendColor(red, green, blue, alpha);
+}
+
+void GL_APIENTRY glBlendEquation(GLenum mode)
+{
+ return GL_BlendEquation(mode);
+}
+
+void GL_APIENTRY glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
+{
+ return GL_BlendEquationSeparate(modeRGB, modeAlpha);
+}
+
+void GL_APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)
+{
+ return GL_BlendFunc(sfactor, dfactor);
+}
+
+void GL_APIENTRY glBlendFuncSeparate(GLenum sfactorRGB,
+ GLenum dfactorRGB,
+ GLenum sfactorAlpha,
+ GLenum dfactorAlpha)
+{
+ return GL_BlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha);
+}
+
+void GL_APIENTRY glBufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage)
+{
+ return GL_BufferData(target, size, data, usage);
+}
+
+void GL_APIENTRY glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data)
+{
+ return GL_BufferSubData(target, offset, size, data);
+}
+
+GLenum GL_APIENTRY glCheckFramebufferStatus(GLenum target)
+{
+ return GL_CheckFramebufferStatus(target);
+}
+
+void GL_APIENTRY glClear(GLbitfield mask)
+{
+ return GL_Clear(mask);
+}
+
+void GL_APIENTRY glClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+ return GL_ClearColor(red, green, blue, alpha);
+}
+
+void GL_APIENTRY glClearDepthf(GLfloat d)
+{
+ return GL_ClearDepthf(d);
+}
+
+void GL_APIENTRY glClearStencil(GLint s)
+{
+ return GL_ClearStencil(s);
+}
+
+void GL_APIENTRY glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
+{
+ return GL_ColorMask(red, green, blue, alpha);
+}
+
+void GL_APIENTRY glCompileShader(GLuint shader)
+{
+ return GL_CompileShader(shader);
+}
+
+void GL_APIENTRY glCompressedTexImage2D(GLenum target,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLsizei imageSize,
+ const void *data)
+{
+ return GL_CompressedTexImage2D(target, level, internalformat, width, height, border, imageSize,
+ data);
+}
+
+void GL_APIENTRY glCompressedTexSubImage2D(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data)
+{
+ return GL_CompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format,
+ imageSize, data);
+}
+
+void GL_APIENTRY glCopyTexImage2D(GLenum target,
+ GLint level,
+ GLenum internalformat,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLint border)
+{
+ return GL_CopyTexImage2D(target, level, internalformat, x, y, width, height, border);
+}
+
+void GL_APIENTRY glCopyTexSubImage2D(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height)
+{
+ return GL_CopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
+}
+
+GLuint GL_APIENTRY glCreateProgram()
+{
+ return GL_CreateProgram();
+}
+
+GLuint GL_APIENTRY glCreateShader(GLenum type)
+{
+ return GL_CreateShader(type);
+}
+
+void GL_APIENTRY glCullFace(GLenum mode)
+{
+ return GL_CullFace(mode);
+}
+
+void GL_APIENTRY glDeleteBuffers(GLsizei n, const GLuint *buffers)
+{
+ return GL_DeleteBuffers(n, buffers);
+}
+
+void GL_APIENTRY glDeleteFramebuffers(GLsizei n, const GLuint *framebuffers)
+{
+ return GL_DeleteFramebuffers(n, framebuffers);
+}
+
+void GL_APIENTRY glDeleteProgram(GLuint program)
+{
+ return GL_DeleteProgram(program);
+}
+
+void GL_APIENTRY glDeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)
+{
+ return GL_DeleteRenderbuffers(n, renderbuffers);
+}
+
+void GL_APIENTRY glDeleteShader(GLuint shader)
+{
+ return GL_DeleteShader(shader);
+}
+
+void GL_APIENTRY glDeleteTextures(GLsizei n, const GLuint *textures)
+{
+ return GL_DeleteTextures(n, textures);
+}
+
+void GL_APIENTRY glDepthFunc(GLenum func)
+{
+ return GL_DepthFunc(func);
+}
+
+void GL_APIENTRY glDepthMask(GLboolean flag)
+{
+ return GL_DepthMask(flag);
+}
+
+void GL_APIENTRY glDepthRangef(GLfloat n, GLfloat f)
+{
+ return GL_DepthRangef(n, f);
+}
+
+void GL_APIENTRY glDetachShader(GLuint program, GLuint shader)
+{
+ return GL_DetachShader(program, shader);
+}
+
+void GL_APIENTRY glDisable(GLenum cap)
+{
+ return GL_Disable(cap);
+}
+
+void GL_APIENTRY glDisableVertexAttribArray(GLuint index)
+{
+ return GL_DisableVertexAttribArray(index);
+}
+
+void GL_APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count)
+{
+ return GL_DrawArrays(mode, first, count);
+}
+
+void GL_APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
+{
+ return GL_DrawElements(mode, count, type, indices);
+}
+
+void GL_APIENTRY glEnable(GLenum cap)
+{
+ return GL_Enable(cap);
+}
+
+void GL_APIENTRY glEnableVertexAttribArray(GLuint index)
+{
+ return GL_EnableVertexAttribArray(index);
+}
+
+void GL_APIENTRY glFinish()
+{
+ return GL_Finish();
+}
+
+void GL_APIENTRY glFlush()
+{
+ return GL_Flush();
+}
+
+void GL_APIENTRY glFramebufferRenderbuffer(GLenum target,
+ GLenum attachment,
+ GLenum renderbuffertarget,
+ GLuint renderbuffer)
+{
+ return GL_FramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
+}
+
+void GL_APIENTRY glFramebufferTexture2D(GLenum target,
+ GLenum attachment,
+ GLenum textarget,
+ GLuint texture,
+ GLint level)
+{
+ return GL_FramebufferTexture2D(target, attachment, textarget, texture, level);
+}
+
+void GL_APIENTRY glFrontFace(GLenum mode)
+{
+ return GL_FrontFace(mode);
+}
+
+void GL_APIENTRY glGenBuffers(GLsizei n, GLuint *buffers)
+{
+ return GL_GenBuffers(n, buffers);
+}
+
+void GL_APIENTRY glGenFramebuffers(GLsizei n, GLuint *framebuffers)
+{
+ return GL_GenFramebuffers(n, framebuffers);
+}
+
+void GL_APIENTRY glGenRenderbuffers(GLsizei n, GLuint *renderbuffers)
+{
+ return GL_GenRenderbuffers(n, renderbuffers);
+}
+
+void GL_APIENTRY glGenTextures(GLsizei n, GLuint *textures)
+{
+ return GL_GenTextures(n, textures);
+}
+
+void GL_APIENTRY glGenerateMipmap(GLenum target)
+{
+ return GL_GenerateMipmap(target);
+}
+
+void GL_APIENTRY glGetActiveAttrib(GLuint program,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *size,
+ GLenum *type,
+ GLchar *name)
+{
+ return GL_GetActiveAttrib(program, index, bufSize, length, size, type, name);
+}
+
+void GL_APIENTRY glGetActiveUniform(GLuint program,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *size,
+ GLenum *type,
+ GLchar *name)
+{
+ return GL_GetActiveUniform(program, index, bufSize, length, size, type, name);
+}
+
+void GL_APIENTRY glGetAttachedShaders(GLuint program,
+ GLsizei maxCount,
+ GLsizei *count,
+ GLuint *shaders)
+{
+ return GL_GetAttachedShaders(program, maxCount, count, shaders);
+}
+
+GLint GL_APIENTRY glGetAttribLocation(GLuint program, const GLchar *name)
+{
+ return GL_GetAttribLocation(program, name);
+}
+
+void GL_APIENTRY glGetBooleanv(GLenum pname, GLboolean *data)
+{
+ return GL_GetBooleanv(pname, data);
+}
+
+void GL_APIENTRY glGetBufferParameteriv(GLenum target, GLenum pname, GLint *params)
+{
+ return GL_GetBufferParameteriv(target, pname, params);
+}
+
+GLenum GL_APIENTRY glGetError()
+{
+ return GL_GetError();
+}
+
+void GL_APIENTRY glGetFloatv(GLenum pname, GLfloat *data)
+{
+ return GL_GetFloatv(pname, data);
+}
+
+void GL_APIENTRY glGetFramebufferAttachmentParameteriv(GLenum target,
+ GLenum attachment,
+ GLenum pname,
+ GLint *params)
+{
+ return GL_GetFramebufferAttachmentParameteriv(target, attachment, pname, params);
+}
+
+void GL_APIENTRY glGetIntegerv(GLenum pname, GLint *data)
+{
+ return GL_GetIntegerv(pname, data);
+}
+
+void GL_APIENTRY glGetProgramInfoLog(GLuint program,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *infoLog)
+{
+ return GL_GetProgramInfoLog(program, bufSize, length, infoLog);
+}
+
+void GL_APIENTRY glGetProgramiv(GLuint program, GLenum pname, GLint *params)
+{
+ return GL_GetProgramiv(program, pname, params);
+}
+
+void GL_APIENTRY glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
+{
+ return GL_GetRenderbufferParameteriv(target, pname, params);
+}
+
+void GL_APIENTRY glGetShaderInfoLog(GLuint shader,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *infoLog)
+{
+ return GL_GetShaderInfoLog(shader, bufSize, length, infoLog);
+}
+
+void GL_APIENTRY glGetShaderPrecisionFormat(GLenum shadertype,
+ GLenum precisiontype,
+ GLint *range,
+ GLint *precision)
+{
+ return GL_GetShaderPrecisionFormat(shadertype, precisiontype, range, precision);
+}
+
+void GL_APIENTRY glGetShaderSource(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source)
+{
+ return GL_GetShaderSource(shader, bufSize, length, source);
+}
+
+void GL_APIENTRY glGetShaderiv(GLuint shader, GLenum pname, GLint *params)
+{
+ return GL_GetShaderiv(shader, pname, params);
+}
+
+const GLubyte *GL_APIENTRY glGetString(GLenum name)
+{
+ return GL_GetString(name);
+}
+
+void GL_APIENTRY glGetTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
+{
+ return GL_GetTexParameterfv(target, pname, params);
+}
+
+void GL_APIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint *params)
+{
+ return GL_GetTexParameteriv(target, pname, params);
+}
+
+GLint GL_APIENTRY glGetUniformLocation(GLuint program, const GLchar *name)
+{
+ return GL_GetUniformLocation(program, name);
+}
+
+void GL_APIENTRY glGetUniformfv(GLuint program, GLint location, GLfloat *params)
+{
+ return GL_GetUniformfv(program, location, params);
+}
+
+void GL_APIENTRY glGetUniformiv(GLuint program, GLint location, GLint *params)
+{
+ return GL_GetUniformiv(program, location, params);
+}
+
+void GL_APIENTRY glGetVertexAttribPointerv(GLuint index, GLenum pname, void **pointer)
+{
+ return GL_GetVertexAttribPointerv(index, pname, pointer);
+}
+
+void GL_APIENTRY glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
+{
+ return GL_GetVertexAttribfv(index, pname, params);
+}
+
+void GL_APIENTRY glGetVertexAttribiv(GLuint index, GLenum pname, GLint *params)
+{
+ return GL_GetVertexAttribiv(index, pname, params);
+}
+
+void GL_APIENTRY glHint(GLenum target, GLenum mode)
+{
+ return GL_Hint(target, mode);
+}
+
+GLboolean GL_APIENTRY glIsBuffer(GLuint buffer)
+{
+ return GL_IsBuffer(buffer);
+}
+
+GLboolean GL_APIENTRY glIsEnabled(GLenum cap)
+{
+ return GL_IsEnabled(cap);
+}
+
+GLboolean GL_APIENTRY glIsFramebuffer(GLuint framebuffer)
+{
+ return GL_IsFramebuffer(framebuffer);
+}
+
+GLboolean GL_APIENTRY glIsProgram(GLuint program)
+{
+ return GL_IsProgram(program);
+}
+
+GLboolean GL_APIENTRY glIsRenderbuffer(GLuint renderbuffer)
+{
+ return GL_IsRenderbuffer(renderbuffer);
+}
+
+GLboolean GL_APIENTRY glIsShader(GLuint shader)
+{
+ return GL_IsShader(shader);
+}
+
+GLboolean GL_APIENTRY glIsTexture(GLuint texture)
+{
+ return GL_IsTexture(texture);
+}
+
+void GL_APIENTRY glLineWidth(GLfloat width)
+{
+ return GL_LineWidth(width);
+}
+
+void GL_APIENTRY glLinkProgram(GLuint program)
+{
+ return GL_LinkProgram(program);
+}
+
+void GL_APIENTRY glPixelStorei(GLenum pname, GLint param)
+{
+ return GL_PixelStorei(pname, param);
+}
+
+void GL_APIENTRY glPolygonOffset(GLfloat factor, GLfloat units)
+{
+ return GL_PolygonOffset(factor, units);
+}
+
+void GL_APIENTRY glReadPixels(GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ void *pixels)
+{
+ return GL_ReadPixels(x, y, width, height, format, type, pixels);
+}
+
+void GL_APIENTRY glReleaseShaderCompiler()
+{
+ return GL_ReleaseShaderCompiler();
+}
+
+void GL_APIENTRY glRenderbufferStorage(GLenum target,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height)
+{
+ return GL_RenderbufferStorage(target, internalformat, width, height);
+}
+
+void GL_APIENTRY glSampleCoverage(GLfloat value, GLboolean invert)
+{
+ return GL_SampleCoverage(value, invert);
+}
+
+void GL_APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ return GL_Scissor(x, y, width, height);
+}
+
+void GL_APIENTRY glShaderBinary(GLsizei count,
+ const GLuint *shaders,
+ GLenum binaryFormat,
+ const void *binary,
+ GLsizei length)
+{
+ return GL_ShaderBinary(count, shaders, binaryFormat, binary, length);
+}
+
+void GL_APIENTRY glShaderSource(GLuint shader,
+ GLsizei count,
+ const GLchar *const *string,
+ const GLint *length)
+{
+ return GL_ShaderSource(shader, count, string, length);
+}
+
+void GL_APIENTRY glStencilFunc(GLenum func, GLint ref, GLuint mask)
+{
+ return GL_StencilFunc(func, ref, mask);
+}
+
+void GL_APIENTRY glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
+{
+ return GL_StencilFuncSeparate(face, func, ref, mask);
+}
+
+void GL_APIENTRY glStencilMask(GLuint mask)
+{
+ return GL_StencilMask(mask);
+}
+
+void GL_APIENTRY glStencilMaskSeparate(GLenum face, GLuint mask)
+{
+ return GL_StencilMaskSeparate(face, mask);
+}
+
+void GL_APIENTRY glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
+{
+ return GL_StencilOp(fail, zfail, zpass);
+}
+
+void GL_APIENTRY glStencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass)
+{
+ return GL_StencilOpSeparate(face, sfail, dpfail, dppass);
+}
+
+void GL_APIENTRY glTexImage2D(GLenum target,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ return GL_TexImage2D(target, level, internalformat, width, height, border, format, type,
+ pixels);
+}
+
+void GL_APIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param)
+{
+ return GL_TexParameterf(target, pname, param);
+}
+
+void GL_APIENTRY glTexParameterfv(GLenum target, GLenum pname, const GLfloat *params)
+{
+ return GL_TexParameterfv(target, pname, params);
+}
+
+void GL_APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param)
+{
+ return GL_TexParameteri(target, pname, param);
+}
+
+void GL_APIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint *params)
+{
+ return GL_TexParameteriv(target, pname, params);
+}
+
+void GL_APIENTRY glTexSubImage2D(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ return GL_TexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
+}
+
+void GL_APIENTRY glUniform1f(GLint location, GLfloat v0)
+{
+ return GL_Uniform1f(location, v0);
+}
+
+void GL_APIENTRY glUniform1fv(GLint location, GLsizei count, const GLfloat *value)
+{
+ return GL_Uniform1fv(location, count, value);
+}
+
+void GL_APIENTRY glUniform1i(GLint location, GLint v0)
+{
+ return GL_Uniform1i(location, v0);
+}
+
+void GL_APIENTRY glUniform1iv(GLint location, GLsizei count, const GLint *value)
+{
+ return GL_Uniform1iv(location, count, value);
+}
+
+void GL_APIENTRY glUniform2f(GLint location, GLfloat v0, GLfloat v1)
+{
+ return GL_Uniform2f(location, v0, v1);
+}
+
+void GL_APIENTRY glUniform2fv(GLint location, GLsizei count, const GLfloat *value)
+{
+ return GL_Uniform2fv(location, count, value);
+}
+
+void GL_APIENTRY glUniform2i(GLint location, GLint v0, GLint v1)
+{
+ return GL_Uniform2i(location, v0, v1);
+}
+
+void GL_APIENTRY glUniform2iv(GLint location, GLsizei count, const GLint *value)
+{
+ return GL_Uniform2iv(location, count, value);
+}
+
+void GL_APIENTRY glUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
+{
+ return GL_Uniform3f(location, v0, v1, v2);
+}
+
+void GL_APIENTRY glUniform3fv(GLint location, GLsizei count, const GLfloat *value)
+{
+ return GL_Uniform3fv(location, count, value);
+}
+
+void GL_APIENTRY glUniform3i(GLint location, GLint v0, GLint v1, GLint v2)
+{
+ return GL_Uniform3i(location, v0, v1, v2);
+}
+
+void GL_APIENTRY glUniform3iv(GLint location, GLsizei count, const GLint *value)
+{
+ return GL_Uniform3iv(location, count, value);
+}
+
+void GL_APIENTRY glUniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
+{
+ return GL_Uniform4f(location, v0, v1, v2, v3);
+}
+
+void GL_APIENTRY glUniform4fv(GLint location, GLsizei count, const GLfloat *value)
+{
+ return GL_Uniform4fv(location, count, value);
+}
+
+void GL_APIENTRY glUniform4i(GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
+{
+ return GL_Uniform4i(location, v0, v1, v2, v3);
+}
+
+void GL_APIENTRY glUniform4iv(GLint location, GLsizei count, const GLint *value)
+{
+ return GL_Uniform4iv(location, count, value);
+}
+
+void GL_APIENTRY glUniformMatrix2fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return GL_UniformMatrix2fv(location, count, transpose, value);
+}
+
+void GL_APIENTRY glUniformMatrix3fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return GL_UniformMatrix3fv(location, count, transpose, value);
+}
+
+void GL_APIENTRY glUniformMatrix4fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return GL_UniformMatrix4fv(location, count, transpose, value);
+}
+
+void GL_APIENTRY glUseProgram(GLuint program)
+{
+ return GL_UseProgram(program);
+}
+
+void GL_APIENTRY glValidateProgram(GLuint program)
+{
+ return GL_ValidateProgram(program);
+}
+
+void GL_APIENTRY glVertexAttrib1f(GLuint index, GLfloat x)
+{
+ return GL_VertexAttrib1f(index, x);
+}
+
+void GL_APIENTRY glVertexAttrib1fv(GLuint index, const GLfloat *v)
+{
+ return GL_VertexAttrib1fv(index, v);
+}
+
+void GL_APIENTRY glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
+{
+ return GL_VertexAttrib2f(index, x, y);
+}
+
+void GL_APIENTRY glVertexAttrib2fv(GLuint index, const GLfloat *v)
+{
+ return GL_VertexAttrib2fv(index, v);
+}
+
+void GL_APIENTRY glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
+{
+ return GL_VertexAttrib3f(index, x, y, z);
+}
+
+void GL_APIENTRY glVertexAttrib3fv(GLuint index, const GLfloat *v)
+{
+ return GL_VertexAttrib3fv(index, v);
+}
+
+void GL_APIENTRY glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ return GL_VertexAttrib4f(index, x, y, z, w);
+}
+
+void GL_APIENTRY glVertexAttrib4fv(GLuint index, const GLfloat *v)
+{
+ return GL_VertexAttrib4fv(index, v);
+}
+
+void GL_APIENTRY glVertexAttribPointer(GLuint index,
+ GLint size,
+ GLenum type,
+ GLboolean normalized,
+ GLsizei stride,
+ const void *pointer)
+{
+ return GL_VertexAttribPointer(index, size, type, normalized, stride, pointer);
+}
+
+void GL_APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ return GL_Viewport(x, y, width, height);
+}
+
+// OpenGL ES 3.0
+void GL_APIENTRY glBeginQuery(GLenum target, GLuint id)
+{
+ return GL_BeginQuery(target, id);
+}
+
+void GL_APIENTRY glBeginTransformFeedback(GLenum primitiveMode)
+{
+ return GL_BeginTransformFeedback(primitiveMode);
+}
+
+void GL_APIENTRY glBindBufferBase(GLenum target, GLuint index, GLuint buffer)
+{
+ return GL_BindBufferBase(target, index, buffer);
+}
+
+void GL_APIENTRY
+glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size)
+{
+ return GL_BindBufferRange(target, index, buffer, offset, size);
+}
+
+void GL_APIENTRY glBindSampler(GLuint unit, GLuint sampler)
+{
+ return GL_BindSampler(unit, sampler);
+}
+
+void GL_APIENTRY glBindTransformFeedback(GLenum target, GLuint id)
+{
+ return GL_BindTransformFeedback(target, id);
+}
+
+void GL_APIENTRY glBindVertexArray(GLuint array)
+{
+ return GL_BindVertexArray(array);
+}
+
+void GL_APIENTRY glBlitFramebuffer(GLint srcX0,
+ GLint srcY0,
+ GLint srcX1,
+ GLint srcY1,
+ GLint dstX0,
+ GLint dstY0,
+ GLint dstX1,
+ GLint dstY1,
+ GLbitfield mask,
+ GLenum filter)
+{
+ return GL_BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
+}
+
+void GL_APIENTRY glClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
+{
+ return GL_ClearBufferfi(buffer, drawbuffer, depth, stencil);
+}
+
+void GL_APIENTRY glClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value)
+{
+ return GL_ClearBufferfv(buffer, drawbuffer, value);
+}
+
+void GL_APIENTRY glClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value)
+{
+ return GL_ClearBufferiv(buffer, drawbuffer, value);
+}
+
+void GL_APIENTRY glClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value)
+{
+ return GL_ClearBufferuiv(buffer, drawbuffer, value);
+}
+
+GLenum GL_APIENTRY glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
+{
+ return GL_ClientWaitSync(sync, flags, timeout);
+}
+
+void GL_APIENTRY glCompressedTexImage3D(GLenum target,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLsizei imageSize,
+ const void *data)
+{
+ return GL_CompressedTexImage3D(target, level, internalformat, width, height, depth, border,
+ imageSize, data);
+}
+
+void GL_APIENTRY glCompressedTexSubImage3D(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data)
+{
+ return GL_CompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height,
+ depth, format, imageSize, data);
+}
+
+void GL_APIENTRY glCopyBufferSubData(GLenum readTarget,
+ GLenum writeTarget,
+ GLintptr readOffset,
+ GLintptr writeOffset,
+ GLsizeiptr size)
+{
+ return GL_CopyBufferSubData(readTarget, writeTarget, readOffset, writeOffset, size);
+}
+
+void GL_APIENTRY glCopyTexSubImage3D(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height)
+{
+ return GL_CopyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height);
+}
+
+void GL_APIENTRY glDeleteQueries(GLsizei n, const GLuint *ids)
+{
+ return GL_DeleteQueries(n, ids);
+}
+
+void GL_APIENTRY glDeleteSamplers(GLsizei count, const GLuint *samplers)
+{
+ return GL_DeleteSamplers(count, samplers);
+}
+
+void GL_APIENTRY glDeleteSync(GLsync sync)
+{
+ return GL_DeleteSync(sync);
+}
+
+void GL_APIENTRY glDeleteTransformFeedbacks(GLsizei n, const GLuint *ids)
+{
+ return GL_DeleteTransformFeedbacks(n, ids);
+}
+
+void GL_APIENTRY glDeleteVertexArrays(GLsizei n, const GLuint *arrays)
+{
+ return GL_DeleteVertexArrays(n, arrays);
+}
+
+void GL_APIENTRY glDrawArraysInstanced(GLenum mode,
+ GLint first,
+ GLsizei count,
+ GLsizei instancecount)
+{
+ return GL_DrawArraysInstanced(mode, first, count, instancecount);
+}
+
+void GL_APIENTRY glDrawBuffers(GLsizei n, const GLenum *bufs)
+{
+ return GL_DrawBuffers(n, bufs);
+}
+
+void GL_APIENTRY glDrawElementsInstanced(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLsizei instancecount)
+{
+ return GL_DrawElementsInstanced(mode, count, type, indices, instancecount);
+}
+
+void GL_APIENTRY glDrawRangeElements(GLenum mode,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ GLenum type,
+ const void *indices)
+{
+ return GL_DrawRangeElements(mode, start, end, count, type, indices);
+}
+
+void GL_APIENTRY glEndQuery(GLenum target)
+{
+ return GL_EndQuery(target);
+}
+
+void GL_APIENTRY glEndTransformFeedback()
+{
+ return GL_EndTransformFeedback();
+}
+
+GLsync GL_APIENTRY glFenceSync(GLenum condition, GLbitfield flags)
+{
+ return GL_FenceSync(condition, flags);
+}
+
+void GL_APIENTRY glFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length)
+{
+ return GL_FlushMappedBufferRange(target, offset, length);
+}
+
+void GL_APIENTRY glFramebufferTextureLayer(GLenum target,
+ GLenum attachment,
+ GLuint texture,
+ GLint level,
+ GLint layer)
+{
+ return GL_FramebufferTextureLayer(target, attachment, texture, level, layer);
+}
+
+void GL_APIENTRY glGenQueries(GLsizei n, GLuint *ids)
+{
+ return GL_GenQueries(n, ids);
+}
+
+void GL_APIENTRY glGenSamplers(GLsizei count, GLuint *samplers)
+{
+ return GL_GenSamplers(count, samplers);
+}
+
+void GL_APIENTRY glGenTransformFeedbacks(GLsizei n, GLuint *ids)
+{
+ return GL_GenTransformFeedbacks(n, ids);
+}
+
+void GL_APIENTRY glGenVertexArrays(GLsizei n, GLuint *arrays)
+{
+ return GL_GenVertexArrays(n, arrays);
+}
+
+void GL_APIENTRY glGetActiveUniformBlockName(GLuint program,
+ GLuint uniformBlockIndex,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *uniformBlockName)
+{
+ return GL_GetActiveUniformBlockName(program, uniformBlockIndex, bufSize, length,
+ uniformBlockName);
+}
+
+void GL_APIENTRY glGetActiveUniformBlockiv(GLuint program,
+ GLuint uniformBlockIndex,
+ GLenum pname,
+ GLint *params)
+{
+ return GL_GetActiveUniformBlockiv(program, uniformBlockIndex, pname, params);
+}
+
+void GL_APIENTRY glGetActiveUniformsiv(GLuint program,
+ GLsizei uniformCount,
+ const GLuint *uniformIndices,
+ GLenum pname,
+ GLint *params)
+{
+ return GL_GetActiveUniformsiv(program, uniformCount, uniformIndices, pname, params);
+}
+
+void GL_APIENTRY glGetBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params)
+{
+ return GL_GetBufferParameteri64v(target, pname, params);
+}
+
+void GL_APIENTRY glGetBufferPointerv(GLenum target, GLenum pname, void **params)
+{
+ return GL_GetBufferPointerv(target, pname, params);
+}
+
+GLint GL_APIENTRY glGetFragDataLocation(GLuint program, const GLchar *name)
+{
+ return GL_GetFragDataLocation(program, name);
+}
+
+void GL_APIENTRY glGetInteger64i_v(GLenum target, GLuint index, GLint64 *data)
+{
+ return GL_GetInteger64i_v(target, index, data);
+}
+
+void GL_APIENTRY glGetInteger64v(GLenum pname, GLint64 *data)
+{
+ return GL_GetInteger64v(pname, data);
+}
+
+void GL_APIENTRY glGetIntegeri_v(GLenum target, GLuint index, GLint *data)
+{
+ return GL_GetIntegeri_v(target, index, data);
+}
+
+void GL_APIENTRY glGetInternalformativ(GLenum target,
+ GLenum internalformat,
+ GLenum pname,
+ GLsizei count,
+ GLint *params)
+{
+ return GL_GetInternalformativ(target, internalformat, pname, count, params);
+}
+
+void GL_APIENTRY glGetProgramBinary(GLuint program,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLenum *binaryFormat,
+ void *binary)
+{
+ return GL_GetProgramBinary(program, bufSize, length, binaryFormat, binary);
+}
+
+void GL_APIENTRY glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
+{
+ return GL_GetQueryObjectuiv(id, pname, params);
+}
+
+void GL_APIENTRY glGetQueryiv(GLenum target, GLenum pname, GLint *params)
+{
+ return GL_GetQueryiv(target, pname, params);
+}
+
+void GL_APIENTRY glGetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
+{
+ return GL_GetSamplerParameterfv(sampler, pname, params);
+}
+
+void GL_APIENTRY glGetSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
+{
+ return GL_GetSamplerParameteriv(sampler, pname, params);
+}
+
+const GLubyte *GL_APIENTRY glGetStringi(GLenum name, GLuint index)
+{
+ return GL_GetStringi(name, index);
+}
+
+void GL_APIENTRY
+glGetSynciv(GLsync sync, GLenum pname, GLsizei count, GLsizei *length, GLint *values)
+{
+ return GL_GetSynciv(sync, pname, count, length, values);
+}
+
+void GL_APIENTRY glGetTransformFeedbackVarying(GLuint program,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLsizei *size,
+ GLenum *type,
+ GLchar *name)
+{
+ return GL_GetTransformFeedbackVarying(program, index, bufSize, length, size, type, name);
+}
+
+GLuint GL_APIENTRY glGetUniformBlockIndex(GLuint program, const GLchar *uniformBlockName)
+{
+ return GL_GetUniformBlockIndex(program, uniformBlockName);
+}
+
+void GL_APIENTRY glGetUniformIndices(GLuint program,
+ GLsizei uniformCount,
+ const GLchar *const *uniformNames,
+ GLuint *uniformIndices)
+{
+ return GL_GetUniformIndices(program, uniformCount, uniformNames, uniformIndices);
+}
+
+void GL_APIENTRY glGetUniformuiv(GLuint program, GLint location, GLuint *params)
+{
+ return GL_GetUniformuiv(program, location, params);
+}
+
+void GL_APIENTRY glGetVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
+{
+ return GL_GetVertexAttribIiv(index, pname, params);
+}
+
+void GL_APIENTRY glGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
+{
+ return GL_GetVertexAttribIuiv(index, pname, params);
+}
+
+void GL_APIENTRY glInvalidateFramebuffer(GLenum target,
+ GLsizei numAttachments,
+ const GLenum *attachments)
+{
+ return GL_InvalidateFramebuffer(target, numAttachments, attachments);
+}
+
+void GL_APIENTRY glInvalidateSubFramebuffer(GLenum target,
+ GLsizei numAttachments,
+ const GLenum *attachments,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height)
+{
+ return GL_InvalidateSubFramebuffer(target, numAttachments, attachments, x, y, width, height);
+}
+
+GLboolean GL_APIENTRY glIsQuery(GLuint id)
+{
+ return GL_IsQuery(id);
+}
+
+GLboolean GL_APIENTRY glIsSampler(GLuint sampler)
+{
+ return GL_IsSampler(sampler);
+}
+
+GLboolean GL_APIENTRY glIsSync(GLsync sync)
+{
+ return GL_IsSync(sync);
+}
+
+GLboolean GL_APIENTRY glIsTransformFeedback(GLuint id)
+{
+ return GL_IsTransformFeedback(id);
+}
+
+GLboolean GL_APIENTRY glIsVertexArray(GLuint array)
+{
+ return GL_IsVertexArray(array);
+}
+
+void *GL_APIENTRY glMapBufferRange(GLenum target,
+ GLintptr offset,
+ GLsizeiptr length,
+ GLbitfield access)
+{
+ return GL_MapBufferRange(target, offset, length, access);
+}
+
+void GL_APIENTRY glPauseTransformFeedback()
+{
+ return GL_PauseTransformFeedback();
+}
+
+void GL_APIENTRY glProgramBinary(GLuint program,
+ GLenum binaryFormat,
+ const void *binary,
+ GLsizei length)
+{
+ return GL_ProgramBinary(program, binaryFormat, binary, length);
+}
+
+void GL_APIENTRY glProgramParameteri(GLuint program, GLenum pname, GLint value)
+{
+ return GL_ProgramParameteri(program, pname, value);
+}
+
+void GL_APIENTRY glReadBuffer(GLenum src)
+{
+ return GL_ReadBuffer(src);
+}
+
+void GL_APIENTRY glRenderbufferStorageMultisample(GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height)
+{
+ return GL_RenderbufferStorageMultisample(target, samples, internalformat, width, height);
+}
+
+void GL_APIENTRY glResumeTransformFeedback()
+{
+ return GL_ResumeTransformFeedback();
+}
+
+void GL_APIENTRY glSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
+{
+ return GL_SamplerParameterf(sampler, pname, param);
+}
+
+void GL_APIENTRY glSamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *param)
+{
+ return GL_SamplerParameterfv(sampler, pname, param);
+}
+
+void GL_APIENTRY glSamplerParameteri(GLuint sampler, GLenum pname, GLint param)
+{
+ return GL_SamplerParameteri(sampler, pname, param);
+}
+
+void GL_APIENTRY glSamplerParameteriv(GLuint sampler, GLenum pname, const GLint *param)
+{
+ return GL_SamplerParameteriv(sampler, pname, param);
+}
+
+void GL_APIENTRY glTexImage3D(GLenum target,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ return GL_TexImage3D(target, level, internalformat, width, height, depth, border, format, type,
+ pixels);
+}
+
+void GL_APIENTRY
+glTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
+{
+ return GL_TexStorage2D(target, levels, internalformat, width, height);
+}
+
+void GL_APIENTRY glTexStorage3D(GLenum target,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth)
+{
+ return GL_TexStorage3D(target, levels, internalformat, width, height, depth);
+}
+
+void GL_APIENTRY glTexSubImage3D(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ return GL_TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format,
+ type, pixels);
+}
+
+void GL_APIENTRY glTransformFeedbackVaryings(GLuint program,
+ GLsizei count,
+ const GLchar *const *varyings,
+ GLenum bufferMode)
+{
+ return GL_TransformFeedbackVaryings(program, count, varyings, bufferMode);
+}
+
+void GL_APIENTRY glUniform1ui(GLint location, GLuint v0)
+{
+ return GL_Uniform1ui(location, v0);
+}
+
+void GL_APIENTRY glUniform1uiv(GLint location, GLsizei count, const GLuint *value)
+{
+ return GL_Uniform1uiv(location, count, value);
+}
+
+void GL_APIENTRY glUniform2ui(GLint location, GLuint v0, GLuint v1)
+{
+ return GL_Uniform2ui(location, v0, v1);
+}
+
+void GL_APIENTRY glUniform2uiv(GLint location, GLsizei count, const GLuint *value)
+{
+ return GL_Uniform2uiv(location, count, value);
+}
+
+void GL_APIENTRY glUniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
+{
+ return GL_Uniform3ui(location, v0, v1, v2);
+}
+
+void GL_APIENTRY glUniform3uiv(GLint location, GLsizei count, const GLuint *value)
+{
+ return GL_Uniform3uiv(location, count, value);
+}
+
+void GL_APIENTRY glUniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
+{
+ return GL_Uniform4ui(location, v0, v1, v2, v3);
+}
+
+void GL_APIENTRY glUniform4uiv(GLint location, GLsizei count, const GLuint *value)
+{
+ return GL_Uniform4uiv(location, count, value);
+}
+
+void GL_APIENTRY glUniformBlockBinding(GLuint program,
+ GLuint uniformBlockIndex,
+ GLuint uniformBlockBinding)
+{
+ return GL_UniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding);
+}
+
+void GL_APIENTRY glUniformMatrix2x3fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return GL_UniformMatrix2x3fv(location, count, transpose, value);
+}
+
+void GL_APIENTRY glUniformMatrix2x4fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return GL_UniformMatrix2x4fv(location, count, transpose, value);
+}
+
+void GL_APIENTRY glUniformMatrix3x2fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return GL_UniformMatrix3x2fv(location, count, transpose, value);
+}
+
+void GL_APIENTRY glUniformMatrix3x4fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return GL_UniformMatrix3x4fv(location, count, transpose, value);
+}
+
+void GL_APIENTRY glUniformMatrix4x2fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return GL_UniformMatrix4x2fv(location, count, transpose, value);
+}
+
+void GL_APIENTRY glUniformMatrix4x3fv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return GL_UniformMatrix4x3fv(location, count, transpose, value);
+}
+
+GLboolean GL_APIENTRY glUnmapBuffer(GLenum target)
+{
+ return GL_UnmapBuffer(target);
+}
+
+void GL_APIENTRY glVertexAttribDivisor(GLuint index, GLuint divisor)
+{
+ return GL_VertexAttribDivisor(index, divisor);
+}
+
+void GL_APIENTRY glVertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
+{
+ return GL_VertexAttribI4i(index, x, y, z, w);
+}
+
+void GL_APIENTRY glVertexAttribI4iv(GLuint index, const GLint *v)
+{
+ return GL_VertexAttribI4iv(index, v);
+}
+
+void GL_APIENTRY glVertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
+{
+ return GL_VertexAttribI4ui(index, x, y, z, w);
+}
+
+void GL_APIENTRY glVertexAttribI4uiv(GLuint index, const GLuint *v)
+{
+ return GL_VertexAttribI4uiv(index, v);
+}
+
+void GL_APIENTRY
+glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer)
+{
+ return GL_VertexAttribIPointer(index, size, type, stride, pointer);
+}
+
+void GL_APIENTRY glWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
+{
+ return GL_WaitSync(sync, flags, timeout);
+}
+
+// OpenGL ES 3.1
+void GL_APIENTRY glActiveShaderProgram(GLuint pipeline, GLuint program)
+{
+ return GL_ActiveShaderProgram(pipeline, program);
+}
+
+void GL_APIENTRY glBindImageTexture(GLuint unit,
+ GLuint texture,
+ GLint level,
+ GLboolean layered,
+ GLint layer,
+ GLenum access,
+ GLenum format)
+{
+ return GL_BindImageTexture(unit, texture, level, layered, layer, access, format);
+}
+
+void GL_APIENTRY glBindProgramPipeline(GLuint pipeline)
+{
+ return GL_BindProgramPipeline(pipeline);
+}
+
+void GL_APIENTRY glBindVertexBuffer(GLuint bindingindex,
+ GLuint buffer,
+ GLintptr offset,
+ GLsizei stride)
+{
+ return GL_BindVertexBuffer(bindingindex, buffer, offset, stride);
+}
+
+GLuint GL_APIENTRY glCreateShaderProgramv(GLenum type, GLsizei count, const GLchar *const *strings)
+{
+ return GL_CreateShaderProgramv(type, count, strings);
+}
+
+void GL_APIENTRY glDeleteProgramPipelines(GLsizei n, const GLuint *pipelines)
+{
+ return GL_DeleteProgramPipelines(n, pipelines);
+}
+
+void GL_APIENTRY glDispatchCompute(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z)
+{
+ return GL_DispatchCompute(num_groups_x, num_groups_y, num_groups_z);
+}
+
+void GL_APIENTRY glDispatchComputeIndirect(GLintptr indirect)
+{
+ return GL_DispatchComputeIndirect(indirect);
+}
+
+void GL_APIENTRY glDrawArraysIndirect(GLenum mode, const void *indirect)
+{
+ return GL_DrawArraysIndirect(mode, indirect);
+}
+
+void GL_APIENTRY glDrawElementsIndirect(GLenum mode, GLenum type, const void *indirect)
+{
+ return GL_DrawElementsIndirect(mode, type, indirect);
+}
+
+void GL_APIENTRY glFramebufferParameteri(GLenum target, GLenum pname, GLint param)
+{
+ return GL_FramebufferParameteri(target, pname, param);
+}
+
+void GL_APIENTRY glGenProgramPipelines(GLsizei n, GLuint *pipelines)
+{
+ return GL_GenProgramPipelines(n, pipelines);
+}
+
+void GL_APIENTRY glGetBooleani_v(GLenum target, GLuint index, GLboolean *data)
+{
+ return GL_GetBooleani_v(target, index, data);
+}
+
+void GL_APIENTRY glGetFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
+{
+ return GL_GetFramebufferParameteriv(target, pname, params);
+}
+
+void GL_APIENTRY glGetMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
+{
+ return GL_GetMultisamplefv(pname, index, val);
+}
+
+void GL_APIENTRY glGetProgramInterfaceiv(GLuint program,
+ GLenum programInterface,
+ GLenum pname,
+ GLint *params)
+{
+ return GL_GetProgramInterfaceiv(program, programInterface, pname, params);
+}
+
+void GL_APIENTRY glGetProgramPipelineInfoLog(GLuint pipeline,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *infoLog)
+{
+ return GL_GetProgramPipelineInfoLog(pipeline, bufSize, length, infoLog);
+}
+
+void GL_APIENTRY glGetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params)
+{
+ return GL_GetProgramPipelineiv(pipeline, pname, params);
+}
+
+GLuint GL_APIENTRY glGetProgramResourceIndex(GLuint program,
+ GLenum programInterface,
+ const GLchar *name)
+{
+ return GL_GetProgramResourceIndex(program, programInterface, name);
+}
+
+GLint GL_APIENTRY glGetProgramResourceLocation(GLuint program,
+ GLenum programInterface,
+ const GLchar *name)
+{
+ return GL_GetProgramResourceLocation(program, programInterface, name);
+}
+
+void GL_APIENTRY glGetProgramResourceName(GLuint program,
+ GLenum programInterface,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *name)
+{
+ return GL_GetProgramResourceName(program, programInterface, index, bufSize, length, name);
+}
+
+void GL_APIENTRY glGetProgramResourceiv(GLuint program,
+ GLenum programInterface,
+ GLuint index,
+ GLsizei propCount,
+ const GLenum *props,
+ GLsizei count,
+ GLsizei *length,
+ GLint *params)
+{
+ return GL_GetProgramResourceiv(program, programInterface, index, propCount, props, count,
+ length, params);
+}
+
+void GL_APIENTRY glGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params)
+{
+ return GL_GetTexLevelParameterfv(target, level, pname, params);
+}
+
+void GL_APIENTRY glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params)
+{
+ return GL_GetTexLevelParameteriv(target, level, pname, params);
+}
+
+GLboolean GL_APIENTRY glIsProgramPipeline(GLuint pipeline)
+{
+ return GL_IsProgramPipeline(pipeline);
+}
+
+void GL_APIENTRY glMemoryBarrier(GLbitfield barriers)
+{
+ return GL_MemoryBarrier(barriers);
+}
+
+void GL_APIENTRY glMemoryBarrierByRegion(GLbitfield barriers)
+{
+ return GL_MemoryBarrierByRegion(barriers);
+}
+
+void GL_APIENTRY glProgramUniform1f(GLuint program, GLint location, GLfloat v0)
+{
+ return GL_ProgramUniform1f(program, location, v0);
+}
+
+void GL_APIENTRY glProgramUniform1fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLfloat *value)
+{
+ return GL_ProgramUniform1fv(program, location, count, value);
+}
+
+void GL_APIENTRY glProgramUniform1i(GLuint program, GLint location, GLint v0)
+{
+ return GL_ProgramUniform1i(program, location, v0);
+}
+
+void GL_APIENTRY glProgramUniform1iv(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLint *value)
+{
+ return GL_ProgramUniform1iv(program, location, count, value);
+}
+
+void GL_APIENTRY glProgramUniform1ui(GLuint program, GLint location, GLuint v0)
+{
+ return GL_ProgramUniform1ui(program, location, v0);
+}
+
+void GL_APIENTRY glProgramUniform1uiv(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLuint *value)
+{
+ return GL_ProgramUniform1uiv(program, location, count, value);
+}
+
+void GL_APIENTRY glProgramUniform2f(GLuint program, GLint location, GLfloat v0, GLfloat v1)
+{
+ return GL_ProgramUniform2f(program, location, v0, v1);
+}
+
+void GL_APIENTRY glProgramUniform2fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLfloat *value)
+{
+ return GL_ProgramUniform2fv(program, location, count, value);
+}
+
+void GL_APIENTRY glProgramUniform2i(GLuint program, GLint location, GLint v0, GLint v1)
+{
+ return GL_ProgramUniform2i(program, location, v0, v1);
+}
+
+void GL_APIENTRY glProgramUniform2iv(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLint *value)
+{
+ return GL_ProgramUniform2iv(program, location, count, value);
+}
+
+void GL_APIENTRY glProgramUniform2ui(GLuint program, GLint location, GLuint v0, GLuint v1)
+{
+ return GL_ProgramUniform2ui(program, location, v0, v1);
+}
+
+void GL_APIENTRY glProgramUniform2uiv(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLuint *value)
+{
+ return GL_ProgramUniform2uiv(program, location, count, value);
+}
+
+void GL_APIENTRY
+glProgramUniform3f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
+{
+ return GL_ProgramUniform3f(program, location, v0, v1, v2);
+}
+
+void GL_APIENTRY glProgramUniform3fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLfloat *value)
+{
+ return GL_ProgramUniform3fv(program, location, count, value);
+}
+
+void GL_APIENTRY glProgramUniform3i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2)
+{
+ return GL_ProgramUniform3i(program, location, v0, v1, v2);
+}
+
+void GL_APIENTRY glProgramUniform3iv(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLint *value)
+{
+ return GL_ProgramUniform3iv(program, location, count, value);
+}
+
+void GL_APIENTRY
+glProgramUniform3ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2)
+{
+ return GL_ProgramUniform3ui(program, location, v0, v1, v2);
+}
+
+void GL_APIENTRY glProgramUniform3uiv(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLuint *value)
+{
+ return GL_ProgramUniform3uiv(program, location, count, value);
+}
+
+void GL_APIENTRY
+glProgramUniform4f(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
+{
+ return GL_ProgramUniform4f(program, location, v0, v1, v2, v3);
+}
+
+void GL_APIENTRY glProgramUniform4fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLfloat *value)
+{
+ return GL_ProgramUniform4fv(program, location, count, value);
+}
+
+void GL_APIENTRY
+glProgramUniform4i(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
+{
+ return GL_ProgramUniform4i(program, location, v0, v1, v2, v3);
+}
+
+void GL_APIENTRY glProgramUniform4iv(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLint *value)
+{
+ return GL_ProgramUniform4iv(program, location, count, value);
+}
+
+void GL_APIENTRY
+glProgramUniform4ui(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
+{
+ return GL_ProgramUniform4ui(program, location, v0, v1, v2, v3);
+}
+
+void GL_APIENTRY glProgramUniform4uiv(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLuint *value)
+{
+ return GL_ProgramUniform4uiv(program, location, count, value);
+}
+
+void GL_APIENTRY glProgramUniformMatrix2fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return GL_ProgramUniformMatrix2fv(program, location, count, transpose, value);
+}
+
+void GL_APIENTRY glProgramUniformMatrix2x3fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return GL_ProgramUniformMatrix2x3fv(program, location, count, transpose, value);
+}
+
+void GL_APIENTRY glProgramUniformMatrix2x4fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return GL_ProgramUniformMatrix2x4fv(program, location, count, transpose, value);
+}
+
+void GL_APIENTRY glProgramUniformMatrix3fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return GL_ProgramUniformMatrix3fv(program, location, count, transpose, value);
+}
+
+void GL_APIENTRY glProgramUniformMatrix3x2fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return GL_ProgramUniformMatrix3x2fv(program, location, count, transpose, value);
+}
+
+void GL_APIENTRY glProgramUniformMatrix3x4fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return GL_ProgramUniformMatrix3x4fv(program, location, count, transpose, value);
+}
+
+void GL_APIENTRY glProgramUniformMatrix4fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return GL_ProgramUniformMatrix4fv(program, location, count, transpose, value);
+}
+
+void GL_APIENTRY glProgramUniformMatrix4x2fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return GL_ProgramUniformMatrix4x2fv(program, location, count, transpose, value);
+}
+
+void GL_APIENTRY glProgramUniformMatrix4x3fv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return GL_ProgramUniformMatrix4x3fv(program, location, count, transpose, value);
+}
+
+void GL_APIENTRY glSampleMaski(GLuint maskNumber, GLbitfield mask)
+{
+ return GL_SampleMaski(maskNumber, mask);
+}
+
+void GL_APIENTRY glTexStorage2DMultisample(GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedsamplelocations)
+{
+ return GL_TexStorage2DMultisample(target, samples, internalformat, width, height,
+ fixedsamplelocations);
+}
+
+void GL_APIENTRY glUseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program)
+{
+ return GL_UseProgramStages(pipeline, stages, program);
+}
+
+void GL_APIENTRY glValidateProgramPipeline(GLuint pipeline)
+{
+ return GL_ValidateProgramPipeline(pipeline);
+}
+
+void GL_APIENTRY glVertexAttribBinding(GLuint attribindex, GLuint bindingindex)
+{
+ return GL_VertexAttribBinding(attribindex, bindingindex);
+}
+
+void GL_APIENTRY glVertexAttribFormat(GLuint attribindex,
+ GLint size,
+ GLenum type,
+ GLboolean normalized,
+ GLuint relativeoffset)
+{
+ return GL_VertexAttribFormat(attribindex, size, type, normalized, relativeoffset);
+}
+
+void GL_APIENTRY glVertexAttribIFormat(GLuint attribindex,
+ GLint size,
+ GLenum type,
+ GLuint relativeoffset)
+{
+ return GL_VertexAttribIFormat(attribindex, size, type, relativeoffset);
+}
+
+void GL_APIENTRY glVertexBindingDivisor(GLuint bindingindex, GLuint divisor)
+{
+ return GL_VertexBindingDivisor(bindingindex, divisor);
+}
+
+// OpenGL ES 3.2
+void GL_APIENTRY glBlendBarrier()
+{
+ return GL_BlendBarrier();
+}
+
+void GL_APIENTRY glBlendEquationSeparatei(GLuint buf, GLenum modeRGB, GLenum modeAlpha)
+{
+ return GL_BlendEquationSeparatei(buf, modeRGB, modeAlpha);
+}
+
+void GL_APIENTRY glBlendEquationi(GLuint buf, GLenum mode)
+{
+ return GL_BlendEquationi(buf, mode);
+}
+
+void GL_APIENTRY
+glBlendFuncSeparatei(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+{
+ return GL_BlendFuncSeparatei(buf, srcRGB, dstRGB, srcAlpha, dstAlpha);
+}
+
+void GL_APIENTRY glBlendFunci(GLuint buf, GLenum src, GLenum dst)
+{
+ return GL_BlendFunci(buf, src, dst);
+}
+
+void GL_APIENTRY glColorMaski(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a)
+{
+ return GL_ColorMaski(index, r, g, b, a);
+}
+
+void GL_APIENTRY glCopyImageSubData(GLuint srcName,
+ GLenum srcTarget,
+ GLint srcLevel,
+ GLint srcX,
+ GLint srcY,
+ GLint srcZ,
+ GLuint dstName,
+ GLenum dstTarget,
+ GLint dstLevel,
+ GLint dstX,
+ GLint dstY,
+ GLint dstZ,
+ GLsizei srcWidth,
+ GLsizei srcHeight,
+ GLsizei srcDepth)
+{
+ return GL_CopyImageSubData(srcName, srcTarget, srcLevel, srcX, srcY, srcZ, dstName, dstTarget,
+ dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight, srcDepth);
+}
+
+void GL_APIENTRY glDebugMessageCallback(GLDEBUGPROC callback, const void *userParam)
+{
+ return GL_DebugMessageCallback(callback, userParam);
+}
+
+void GL_APIENTRY glDebugMessageControl(GLenum source,
+ GLenum type,
+ GLenum severity,
+ GLsizei count,
+ const GLuint *ids,
+ GLboolean enabled)
+{
+ return GL_DebugMessageControl(source, type, severity, count, ids, enabled);
+}
+
+void GL_APIENTRY glDebugMessageInsert(GLenum source,
+ GLenum type,
+ GLuint id,
+ GLenum severity,
+ GLsizei length,
+ const GLchar *buf)
+{
+ return GL_DebugMessageInsert(source, type, id, severity, length, buf);
+}
+
+void GL_APIENTRY glDisablei(GLenum target, GLuint index)
+{
+ return GL_Disablei(target, index);
+}
+
+void GL_APIENTRY glDrawElementsBaseVertex(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLint basevertex)
+{
+ return GL_DrawElementsBaseVertex(mode, count, type, indices, basevertex);
+}
+
+void GL_APIENTRY glDrawElementsInstancedBaseVertex(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLsizei instancecount,
+ GLint basevertex)
+{
+ return GL_DrawElementsInstancedBaseVertex(mode, count, type, indices, instancecount,
+ basevertex);
+}
+
+void GL_APIENTRY glDrawRangeElementsBaseVertex(GLenum mode,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLint basevertex)
+{
+ return GL_DrawRangeElementsBaseVertex(mode, start, end, count, type, indices, basevertex);
+}
+
+void GL_APIENTRY glEnablei(GLenum target, GLuint index)
+{
+ return GL_Enablei(target, index);
+}
+
+void GL_APIENTRY glFramebufferTexture(GLenum target, GLenum attachment, GLuint texture, GLint level)
+{
+ return GL_FramebufferTexture(target, attachment, texture, level);
+}
+
+GLuint GL_APIENTRY glGetDebugMessageLog(GLuint count,
+ GLsizei bufSize,
+ GLenum *sources,
+ GLenum *types,
+ GLuint *ids,
+ GLenum *severities,
+ GLsizei *lengths,
+ GLchar *messageLog)
+{
+ return GL_GetDebugMessageLog(count, bufSize, sources, types, ids, severities, lengths,
+ messageLog);
+}
+
+GLenum GL_APIENTRY glGetGraphicsResetStatus()
+{
+ return GL_GetGraphicsResetStatus();
+}
+
+void GL_APIENTRY
+glGetObjectLabel(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label)
+{
+ return GL_GetObjectLabel(identifier, name, bufSize, length, label);
+}
+
+void GL_APIENTRY glGetObjectPtrLabel(const void *ptr,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *label)
+{
+ return GL_GetObjectPtrLabel(ptr, bufSize, length, label);
+}
+
+void GL_APIENTRY glGetPointerv(GLenum pname, void **params)
+{
+ return GL_GetPointerv(pname, params);
+}
+
+void GL_APIENTRY glGetSamplerParameterIiv(GLuint sampler, GLenum pname, GLint *params)
+{
+ return GL_GetSamplerParameterIiv(sampler, pname, params);
+}
+
+void GL_APIENTRY glGetSamplerParameterIuiv(GLuint sampler, GLenum pname, GLuint *params)
+{
+ return GL_GetSamplerParameterIuiv(sampler, pname, params);
+}
+
+void GL_APIENTRY glGetTexParameterIiv(GLenum target, GLenum pname, GLint *params)
+{
+ return GL_GetTexParameterIiv(target, pname, params);
+}
+
+void GL_APIENTRY glGetTexParameterIuiv(GLenum target, GLenum pname, GLuint *params)
+{
+ return GL_GetTexParameterIuiv(target, pname, params);
+}
+
+void GL_APIENTRY glGetnUniformfv(GLuint program, GLint location, GLsizei bufSize, GLfloat *params)
+{
+ return GL_GetnUniformfv(program, location, bufSize, params);
+}
+
+void GL_APIENTRY glGetnUniformiv(GLuint program, GLint location, GLsizei bufSize, GLint *params)
+{
+ return GL_GetnUniformiv(program, location, bufSize, params);
+}
+
+void GL_APIENTRY glGetnUniformuiv(GLuint program, GLint location, GLsizei bufSize, GLuint *params)
+{
+ return GL_GetnUniformuiv(program, location, bufSize, params);
+}
+
+GLboolean GL_APIENTRY glIsEnabledi(GLenum target, GLuint index)
+{
+ return GL_IsEnabledi(target, index);
+}
+
+void GL_APIENTRY glMinSampleShading(GLfloat value)
+{
+ return GL_MinSampleShading(value);
+}
+
+void GL_APIENTRY glObjectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
+{
+ return GL_ObjectLabel(identifier, name, length, label);
+}
+
+void GL_APIENTRY glObjectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
+{
+ return GL_ObjectPtrLabel(ptr, length, label);
+}
+
+void GL_APIENTRY glPatchParameteri(GLenum pname, GLint value)
+{
+ return GL_PatchParameteri(pname, value);
+}
+
+void GL_APIENTRY glPopDebugGroup()
+{
+ return GL_PopDebugGroup();
+}
+
+void GL_APIENTRY glPrimitiveBoundingBox(GLfloat minX,
+ GLfloat minY,
+ GLfloat minZ,
+ GLfloat minW,
+ GLfloat maxX,
+ GLfloat maxY,
+ GLfloat maxZ,
+ GLfloat maxW)
+{
+ return GL_PrimitiveBoundingBox(minX, minY, minZ, minW, maxX, maxY, maxZ, maxW);
+}
+
+void GL_APIENTRY glPushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
+{
+ return GL_PushDebugGroup(source, id, length, message);
+}
+
+void GL_APIENTRY glReadnPixels(GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ void *data)
+{
+ return GL_ReadnPixels(x, y, width, height, format, type, bufSize, data);
+}
+
+void GL_APIENTRY glSamplerParameterIiv(GLuint sampler, GLenum pname, const GLint *param)
+{
+ return GL_SamplerParameterIiv(sampler, pname, param);
+}
+
+void GL_APIENTRY glSamplerParameterIuiv(GLuint sampler, GLenum pname, const GLuint *param)
+{
+ return GL_SamplerParameterIuiv(sampler, pname, param);
+}
+
+void GL_APIENTRY glTexBuffer(GLenum target, GLenum internalformat, GLuint buffer)
+{
+ return GL_TexBuffer(target, internalformat, buffer);
+}
+
+void GL_APIENTRY glTexBufferRange(GLenum target,
+ GLenum internalformat,
+ GLuint buffer,
+ GLintptr offset,
+ GLsizeiptr size)
+{
+ return GL_TexBufferRange(target, internalformat, buffer, offset, size);
+}
+
+void GL_APIENTRY glTexParameterIiv(GLenum target, GLenum pname, const GLint *params)
+{
+ return GL_TexParameterIiv(target, pname, params);
+}
+
+void GL_APIENTRY glTexParameterIuiv(GLenum target, GLenum pname, const GLuint *params)
+{
+ return GL_TexParameterIuiv(target, pname, params);
+}
+
+void GL_APIENTRY glTexStorage3DMultisample(GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean fixedsamplelocations)
+{
+ return GL_TexStorage3DMultisample(target, samples, internalformat, width, height, depth,
+ fixedsamplelocations);
+}
+
+// OpenGL ES 1.0
+void GL_APIENTRY glAlphaFunc(GLenum func, GLfloat ref)
+{
+ return GL_AlphaFunc(func, ref);
+}
+
+void GL_APIENTRY glAlphaFuncx(GLenum func, GLfixed ref)
+{
+ return GL_AlphaFuncx(func, ref);
+}
+
+void GL_APIENTRY glClearColorx(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)
+{
+ return GL_ClearColorx(red, green, blue, alpha);
+}
+
+void GL_APIENTRY glClearDepthx(GLfixed depth)
+{
+ return GL_ClearDepthx(depth);
+}
+
+void GL_APIENTRY glClientActiveTexture(GLenum texture)
+{
+ return GL_ClientActiveTexture(texture);
+}
+
+void GL_APIENTRY glClipPlanef(GLenum p, const GLfloat *eqn)
+{
+ return GL_ClipPlanef(p, eqn);
+}
+
+void GL_APIENTRY glClipPlanex(GLenum plane, const GLfixed *equation)
+{
+ return GL_ClipPlanex(plane, equation);
+}
+
+void GL_APIENTRY glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+ return GL_Color4f(red, green, blue, alpha);
+}
+
+void GL_APIENTRY glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
+{
+ return GL_Color4ub(red, green, blue, alpha);
+}
+
+void GL_APIENTRY glColor4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)
+{
+ return GL_Color4x(red, green, blue, alpha);
+}
+
+void GL_APIENTRY glColorPointer(GLint size, GLenum type, GLsizei stride, const void *pointer)
+{
+ return GL_ColorPointer(size, type, stride, pointer);
+}
+
+void GL_APIENTRY glDepthRangex(GLfixed n, GLfixed f)
+{
+ return GL_DepthRangex(n, f);
+}
+
+void GL_APIENTRY glDisableClientState(GLenum array)
+{
+ return GL_DisableClientState(array);
+}
+
+void GL_APIENTRY glEnableClientState(GLenum array)
+{
+ return GL_EnableClientState(array);
+}
+
+void GL_APIENTRY glFogf(GLenum pname, GLfloat param)
+{
+ return GL_Fogf(pname, param);
+}
+
+void GL_APIENTRY glFogfv(GLenum pname, const GLfloat *params)
+{
+ return GL_Fogfv(pname, params);
+}
+
+void GL_APIENTRY glFogx(GLenum pname, GLfixed param)
+{
+ return GL_Fogx(pname, param);
+}
+
+void GL_APIENTRY glFogxv(GLenum pname, const GLfixed *param)
+{
+ return GL_Fogxv(pname, param);
+}
+
+void GL_APIENTRY glFrustumf(GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f)
+{
+ return GL_Frustumf(l, r, b, t, n, f);
+}
+
+void GL_APIENTRY glFrustumx(GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f)
+{
+ return GL_Frustumx(l, r, b, t, n, f);
+}
+
+void GL_APIENTRY glGetClipPlanef(GLenum plane, GLfloat *equation)
+{
+ return GL_GetClipPlanef(plane, equation);
+}
+
+void GL_APIENTRY glGetClipPlanex(GLenum plane, GLfixed *equation)
+{
+ return GL_GetClipPlanex(plane, equation);
+}
+
+void GL_APIENTRY glGetFixedv(GLenum pname, GLfixed *params)
+{
+ return GL_GetFixedv(pname, params);
+}
+
+void GL_APIENTRY glGetLightfv(GLenum light, GLenum pname, GLfloat *params)
+{
+ return GL_GetLightfv(light, pname, params);
+}
+
+void GL_APIENTRY glGetLightxv(GLenum light, GLenum pname, GLfixed *params)
+{
+ return GL_GetLightxv(light, pname, params);
+}
+
+void GL_APIENTRY glGetMaterialfv(GLenum face, GLenum pname, GLfloat *params)
+{
+ return GL_GetMaterialfv(face, pname, params);
+}
+
+void GL_APIENTRY glGetMaterialxv(GLenum face, GLenum pname, GLfixed *params)
+{
+ return GL_GetMaterialxv(face, pname, params);
+}
+
+void GL_APIENTRY glGetTexEnvfv(GLenum target, GLenum pname, GLfloat *params)
+{
+ return GL_GetTexEnvfv(target, pname, params);
+}
+
+void GL_APIENTRY glGetTexEnviv(GLenum target, GLenum pname, GLint *params)
+{
+ return GL_GetTexEnviv(target, pname, params);
+}
+
+void GL_APIENTRY glGetTexEnvxv(GLenum target, GLenum pname, GLfixed *params)
+{
+ return GL_GetTexEnvxv(target, pname, params);
+}
+
+void GL_APIENTRY glGetTexParameterxv(GLenum target, GLenum pname, GLfixed *params)
+{
+ return GL_GetTexParameterxv(target, pname, params);
+}
+
+void GL_APIENTRY glLightModelf(GLenum pname, GLfloat param)
+{
+ return GL_LightModelf(pname, param);
+}
+
+void GL_APIENTRY glLightModelfv(GLenum pname, const GLfloat *params)
+{
+ return GL_LightModelfv(pname, params);
+}
+
+void GL_APIENTRY glLightModelx(GLenum pname, GLfixed param)
+{
+ return GL_LightModelx(pname, param);
+}
+
+void GL_APIENTRY glLightModelxv(GLenum pname, const GLfixed *param)
+{
+ return GL_LightModelxv(pname, param);
+}
+
+void GL_APIENTRY glLightf(GLenum light, GLenum pname, GLfloat param)
+{
+ return GL_Lightf(light, pname, param);
+}
+
+void GL_APIENTRY glLightfv(GLenum light, GLenum pname, const GLfloat *params)
+{
+ return GL_Lightfv(light, pname, params);
+}
+
+void GL_APIENTRY glLightx(GLenum light, GLenum pname, GLfixed param)
+{
+ return GL_Lightx(light, pname, param);
+}
+
+void GL_APIENTRY glLightxv(GLenum light, GLenum pname, const GLfixed *params)
+{
+ return GL_Lightxv(light, pname, params);
+}
+
+void GL_APIENTRY glLineWidthx(GLfixed width)
+{
+ return GL_LineWidthx(width);
+}
+
+void GL_APIENTRY glLoadIdentity()
+{
+ return GL_LoadIdentity();
+}
+
+void GL_APIENTRY glLoadMatrixf(const GLfloat *m)
+{
+ return GL_LoadMatrixf(m);
+}
+
+void GL_APIENTRY glLoadMatrixx(const GLfixed *m)
+{
+ return GL_LoadMatrixx(m);
+}
+
+void GL_APIENTRY glLogicOp(GLenum opcode)
+{
+ return GL_LogicOp(opcode);
+}
+
+void GL_APIENTRY glMaterialf(GLenum face, GLenum pname, GLfloat param)
+{
+ return GL_Materialf(face, pname, param);
+}
+
+void GL_APIENTRY glMaterialfv(GLenum face, GLenum pname, const GLfloat *params)
+{
+ return GL_Materialfv(face, pname, params);
+}
+
+void GL_APIENTRY glMaterialx(GLenum face, GLenum pname, GLfixed param)
+{
+ return GL_Materialx(face, pname, param);
+}
+
+void GL_APIENTRY glMaterialxv(GLenum face, GLenum pname, const GLfixed *param)
+{
+ return GL_Materialxv(face, pname, param);
+}
+
+void GL_APIENTRY glMatrixMode(GLenum mode)
+{
+ return GL_MatrixMode(mode);
+}
+
+void GL_APIENTRY glMultMatrixf(const GLfloat *m)
+{
+ return GL_MultMatrixf(m);
+}
+
+void GL_APIENTRY glMultMatrixx(const GLfixed *m)
+{
+ return GL_MultMatrixx(m);
+}
+
+void GL_APIENTRY glMultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
+{
+ return GL_MultiTexCoord4f(target, s, t, r, q);
+}
+
+void GL_APIENTRY glMultiTexCoord4x(GLenum texture, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
+{
+ return GL_MultiTexCoord4x(texture, s, t, r, q);
+}
+
+void GL_APIENTRY glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz)
+{
+ return GL_Normal3f(nx, ny, nz);
+}
+
+void GL_APIENTRY glNormal3x(GLfixed nx, GLfixed ny, GLfixed nz)
+{
+ return GL_Normal3x(nx, ny, nz);
+}
+
+void GL_APIENTRY glNormalPointer(GLenum type, GLsizei stride, const void *pointer)
+{
+ return GL_NormalPointer(type, stride, pointer);
+}
+
+void GL_APIENTRY glOrthof(GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f)
+{
+ return GL_Orthof(l, r, b, t, n, f);
+}
+
+void GL_APIENTRY glOrthox(GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f)
+{
+ return GL_Orthox(l, r, b, t, n, f);
+}
+
+void GL_APIENTRY glPointParameterf(GLenum pname, GLfloat param)
+{
+ return GL_PointParameterf(pname, param);
+}
+
+void GL_APIENTRY glPointParameterfv(GLenum pname, const GLfloat *params)
+{
+ return GL_PointParameterfv(pname, params);
+}
+
+void GL_APIENTRY glPointParameterx(GLenum pname, GLfixed param)
+{
+ return GL_PointParameterx(pname, param);
+}
+
+void GL_APIENTRY glPointParameterxv(GLenum pname, const GLfixed *params)
+{
+ return GL_PointParameterxv(pname, params);
+}
+
+void GL_APIENTRY glPointSize(GLfloat size)
+{
+ return GL_PointSize(size);
+}
+
+void GL_APIENTRY glPointSizex(GLfixed size)
+{
+ return GL_PointSizex(size);
+}
+
+void GL_APIENTRY glPolygonOffsetx(GLfixed factor, GLfixed units)
+{
+ return GL_PolygonOffsetx(factor, units);
+}
+
+void GL_APIENTRY glPopMatrix()
+{
+ return GL_PopMatrix();
+}
+
+void GL_APIENTRY glPushMatrix()
+{
+ return GL_PushMatrix();
+}
+
+void GL_APIENTRY glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
+{
+ return GL_Rotatef(angle, x, y, z);
+}
+
+void GL_APIENTRY glRotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z)
+{
+ return GL_Rotatex(angle, x, y, z);
+}
+
+void GL_APIENTRY glSampleCoveragex(GLclampx value, GLboolean invert)
+{
+ return GL_SampleCoveragex(value, invert);
+}
+
+void GL_APIENTRY glScalef(GLfloat x, GLfloat y, GLfloat z)
+{
+ return GL_Scalef(x, y, z);
+}
+
+void GL_APIENTRY glScalex(GLfixed x, GLfixed y, GLfixed z)
+{
+ return GL_Scalex(x, y, z);
+}
+
+void GL_APIENTRY glShadeModel(GLenum mode)
+{
+ return GL_ShadeModel(mode);
+}
+
+void GL_APIENTRY glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const void *pointer)
+{
+ return GL_TexCoordPointer(size, type, stride, pointer);
+}
+
+void GL_APIENTRY glTexEnvf(GLenum target, GLenum pname, GLfloat param)
+{
+ return GL_TexEnvf(target, pname, param);
+}
+
+void GL_APIENTRY glTexEnvfv(GLenum target, GLenum pname, const GLfloat *params)
+{
+ return GL_TexEnvfv(target, pname, params);
+}
+
+void GL_APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param)
+{
+ return GL_TexEnvi(target, pname, param);
+}
+
+void GL_APIENTRY glTexEnviv(GLenum target, GLenum pname, const GLint *params)
+{
+ return GL_TexEnviv(target, pname, params);
+}
+
+void GL_APIENTRY glTexEnvx(GLenum target, GLenum pname, GLfixed param)
+{
+ return GL_TexEnvx(target, pname, param);
+}
+
+void GL_APIENTRY glTexEnvxv(GLenum target, GLenum pname, const GLfixed *params)
+{
+ return GL_TexEnvxv(target, pname, params);
+}
+
+void GL_APIENTRY glTexParameterx(GLenum target, GLenum pname, GLfixed param)
+{
+ return GL_TexParameterx(target, pname, param);
+}
+
+void GL_APIENTRY glTexParameterxv(GLenum target, GLenum pname, const GLfixed *params)
+{
+ return GL_TexParameterxv(target, pname, params);
+}
+
+void GL_APIENTRY glTranslatef(GLfloat x, GLfloat y, GLfloat z)
+{
+ return GL_Translatef(x, y, z);
+}
+
+void GL_APIENTRY glTranslatex(GLfixed x, GLfixed y, GLfixed z)
+{
+ return GL_Translatex(x, y, z);
+}
+
+void GL_APIENTRY glVertexPointer(GLint size, GLenum type, GLsizei stride, const void *pointer)
+{
+ return GL_VertexPointer(size, type, stride, pointer);
+}
+
+// GL_AMD_performance_monitor
+void GL_APIENTRY glBeginPerfMonitorAMD(GLuint monitor)
+{
+ return GL_BeginPerfMonitorAMD(monitor);
+}
+
+void GL_APIENTRY glDeletePerfMonitorsAMD(GLsizei n, GLuint *monitors)
+{
+ return GL_DeletePerfMonitorsAMD(n, monitors);
+}
+
+void GL_APIENTRY glEndPerfMonitorAMD(GLuint monitor)
+{
+ return GL_EndPerfMonitorAMD(monitor);
+}
+
+void GL_APIENTRY glGenPerfMonitorsAMD(GLsizei n, GLuint *monitors)
+{
+ return GL_GenPerfMonitorsAMD(n, monitors);
+}
+
+void GL_APIENTRY glGetPerfMonitorCounterDataAMD(GLuint monitor,
+ GLenum pname,
+ GLsizei dataSize,
+ GLuint *data,
+ GLint *bytesWritten)
+{
+ return GL_GetPerfMonitorCounterDataAMD(monitor, pname, dataSize, data, bytesWritten);
+}
+
+void GL_APIENTRY glGetPerfMonitorCounterInfoAMD(GLuint group,
+ GLuint counter,
+ GLenum pname,
+ void *data)
+{
+ return GL_GetPerfMonitorCounterInfoAMD(group, counter, pname, data);
+}
+
+void GL_APIENTRY glGetPerfMonitorCounterStringAMD(GLuint group,
+ GLuint counter,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *counterString)
+{
+ return GL_GetPerfMonitorCounterStringAMD(group, counter, bufSize, length, counterString);
+}
+
+void GL_APIENTRY glGetPerfMonitorCountersAMD(GLuint group,
+ GLint *numCounters,
+ GLint *maxActiveCounters,
+ GLsizei counterSize,
+ GLuint *counters)
+{
+ return GL_GetPerfMonitorCountersAMD(group, numCounters, maxActiveCounters, counterSize,
+ counters);
+}
+
+void GL_APIENTRY glGetPerfMonitorGroupStringAMD(GLuint group,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *groupString)
+{
+ return GL_GetPerfMonitorGroupStringAMD(group, bufSize, length, groupString);
+}
+
+void GL_APIENTRY glGetPerfMonitorGroupsAMD(GLint *numGroups, GLsizei groupsSize, GLuint *groups)
+{
+ return GL_GetPerfMonitorGroupsAMD(numGroups, groupsSize, groups);
+}
+
+void GL_APIENTRY glSelectPerfMonitorCountersAMD(GLuint monitor,
+ GLboolean enable,
+ GLuint group,
+ GLint numCounters,
+ GLuint *counterList)
+{
+ return GL_SelectPerfMonitorCountersAMD(monitor, enable, group, numCounters, counterList);
+}
+
+// GL_ANDROID_extension_pack_es31a
+
+// GL_ANGLE_base_vertex_base_instance
+void GL_APIENTRY glDrawArraysInstancedBaseInstanceANGLE(GLenum mode,
+ GLint first,
+ GLsizei count,
+ GLsizei instanceCount,
+ GLuint baseInstance)
+{
+ return GL_DrawArraysInstancedBaseInstanceANGLE(mode, first, count, instanceCount, baseInstance);
+}
+
+void GL_APIENTRY glDrawElementsInstancedBaseVertexBaseInstanceANGLE(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const GLvoid *indices,
+ GLsizei instanceCount,
+ GLint baseVertex,
+ GLuint baseInstance)
+{
+ return GL_DrawElementsInstancedBaseVertexBaseInstanceANGLE(
+ mode, count, type, indices, instanceCount, baseVertex, baseInstance);
+}
+
+void GL_APIENTRY glMultiDrawArraysInstancedBaseInstanceANGLE(GLenum mode,
+ const GLint *firsts,
+ const GLsizei *counts,
+ const GLsizei *instanceCounts,
+ const GLuint *baseInstances,
+ GLsizei drawcount)
+{
+ return GL_MultiDrawArraysInstancedBaseInstanceANGLE(mode, firsts, counts, instanceCounts,
+ baseInstances, drawcount);
+}
+
+void GL_APIENTRY
+glMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE(GLenum mode,
+ const GLsizei *counts,
+ GLenum type,
+ const GLvoid *const *indices,
+ const GLsizei *instanceCounts,
+ const GLint *baseVertices,
+ const GLuint *baseInstances,
+ GLsizei drawcount)
+{
+ return GL_MultiDrawElementsInstancedBaseVertexBaseInstanceANGLE(
+ mode, counts, type, indices, instanceCounts, baseVertices, baseInstances, drawcount);
+}
+
+// GL_ANGLE_copy_texture_3d
+void GL_APIENTRY glCopyTexture3DANGLE(GLuint sourceId,
+ GLint sourceLevel,
+ GLenum destTarget,
+ GLuint destId,
+ GLint destLevel,
+ GLint internalFormat,
+ GLenum destType,
+ GLboolean unpackFlipY,
+ GLboolean unpackPremultiplyAlpha,
+ GLboolean unpackUnmultiplyAlpha)
+{
+ return GL_CopyTexture3DANGLE(sourceId, sourceLevel, destTarget, destId, destLevel,
+ internalFormat, destType, unpackFlipY, unpackPremultiplyAlpha,
+ unpackUnmultiplyAlpha);
+}
+
+void GL_APIENTRY glCopySubTexture3DANGLE(GLuint sourceId,
+ GLint sourceLevel,
+ GLenum destTarget,
+ GLuint destId,
+ GLint destLevel,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLint x,
+ GLint y,
+ GLint z,
+ GLint width,
+ GLint height,
+ GLint depth,
+ GLboolean unpackFlipY,
+ GLboolean unpackPremultiplyAlpha,
+ GLboolean unpackUnmultiplyAlpha)
+{
+ return GL_CopySubTexture3DANGLE(sourceId, sourceLevel, destTarget, destId, destLevel, xoffset,
+ yoffset, zoffset, x, y, z, width, height, depth, unpackFlipY,
+ unpackPremultiplyAlpha, unpackUnmultiplyAlpha);
+}
+
+// GL_ANGLE_depth_texture
+
+// GL_ANGLE_framebuffer_blit
+void GL_APIENTRY glBlitFramebufferANGLE(GLint srcX0,
+ GLint srcY0,
+ GLint srcX1,
+ GLint srcY1,
+ GLint dstX0,
+ GLint dstY0,
+ GLint dstX1,
+ GLint dstY1,
+ GLbitfield mask,
+ GLenum filter)
+{
+ return GL_BlitFramebufferANGLE(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask,
+ filter);
+}
+
+// GL_ANGLE_framebuffer_multisample
+void GL_APIENTRY glRenderbufferStorageMultisampleANGLE(GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height)
+{
+ return GL_RenderbufferStorageMultisampleANGLE(target, samples, internalformat, width, height);
+}
+
+// GL_ANGLE_get_image
+void GL_APIENTRY
+glGetTexImageANGLE(GLenum target, GLint level, GLenum format, GLenum type, void *pixels)
+{
+ return GL_GetTexImageANGLE(target, level, format, type, pixels);
+}
+
+void GL_APIENTRY glGetCompressedTexImageANGLE(GLenum target, GLint level, void *pixels)
+{
+ return GL_GetCompressedTexImageANGLE(target, level, pixels);
+}
+
+void GL_APIENTRY glGetRenderbufferImageANGLE(GLenum target,
+ GLenum format,
+ GLenum type,
+ void *pixels)
+{
+ return GL_GetRenderbufferImageANGLE(target, format, type, pixels);
+}
+
+// GL_ANGLE_get_tex_level_parameter
+void GL_APIENTRY glGetTexLevelParameterivANGLE(GLenum target,
+ GLint level,
+ GLenum pname,
+ GLint *params)
+{
+ return GL_GetTexLevelParameterivANGLE(target, level, pname, params);
+}
+
+void GL_APIENTRY glGetTexLevelParameterfvANGLE(GLenum target,
+ GLint level,
+ GLenum pname,
+ GLfloat *params)
+{
+ return GL_GetTexLevelParameterfvANGLE(target, level, pname, params);
+}
+
+// GL_ANGLE_instanced_arrays
+void GL_APIENTRY glDrawArraysInstancedANGLE(GLenum mode,
+ GLint first,
+ GLsizei count,
+ GLsizei primcount)
+{
+ return GL_DrawArraysInstancedANGLE(mode, first, count, primcount);
+}
+
+void GL_APIENTRY glDrawElementsInstancedANGLE(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLsizei primcount)
+{
+ return GL_DrawElementsInstancedANGLE(mode, count, type, indices, primcount);
+}
+
+void GL_APIENTRY glVertexAttribDivisorANGLE(GLuint index, GLuint divisor)
+{
+ return GL_VertexAttribDivisorANGLE(index, divisor);
+}
+
+// GL_ANGLE_logic_op
+void GL_APIENTRY glLogicOpANGLE(GLenum opcode)
+{
+ return GL_LogicOpANGLE(opcode);
+}
+
+// GL_ANGLE_memory_object_flags
+void GL_APIENTRY glTexStorageMemFlags2DANGLE(GLenum target,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLuint memory,
+ GLuint64 offset,
+ GLbitfield createFlags,
+ GLbitfield usageFlags,
+ const void *imageCreateInfoPNext)
+{
+ return GL_TexStorageMemFlags2DANGLE(target, levels, internalFormat, width, height, memory,
+ offset, createFlags, usageFlags, imageCreateInfoPNext);
+}
+
+void GL_APIENTRY glTexStorageMemFlags2DMultisampleANGLE(GLenum target,
+ GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedSampleLocations,
+ GLuint memory,
+ GLuint64 offset,
+ GLbitfield createFlags,
+ GLbitfield usageFlags,
+ const void *imageCreateInfoPNext)
+{
+ return GL_TexStorageMemFlags2DMultisampleANGLE(target, samples, internalFormat, width, height,
+ fixedSampleLocations, memory, offset,
+ createFlags, usageFlags, imageCreateInfoPNext);
+}
+
+void GL_APIENTRY glTexStorageMemFlags3DANGLE(GLenum target,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLuint memory,
+ GLuint64 offset,
+ GLbitfield createFlags,
+ GLbitfield usageFlags,
+ const void *imageCreateInfoPNext)
+{
+ return GL_TexStorageMemFlags3DANGLE(target, levels, internalFormat, width, height, depth,
+ memory, offset, createFlags, usageFlags,
+ imageCreateInfoPNext);
+}
+
+void GL_APIENTRY glTexStorageMemFlags3DMultisampleANGLE(GLenum target,
+ GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean fixedSampleLocations,
+ GLuint memory,
+ GLuint64 offset,
+ GLbitfield createFlags,
+ GLbitfield usageFlags,
+ const void *imageCreateInfoPNext)
+{
+ return GL_TexStorageMemFlags3DMultisampleANGLE(target, samples, internalFormat, width, height,
+ depth, fixedSampleLocations, memory, offset,
+ createFlags, usageFlags, imageCreateInfoPNext);
+}
+
+// GL_ANGLE_memory_object_fuchsia
+void GL_APIENTRY glImportMemoryZirconHandleANGLE(GLuint memory,
+ GLuint64 size,
+ GLenum handleType,
+ GLuint handle)
+{
+ return GL_ImportMemoryZirconHandleANGLE(memory, size, handleType, handle);
+}
+
+// GL_ANGLE_multi_draw
+void GL_APIENTRY glMultiDrawArraysANGLE(GLenum mode,
+ const GLint *firsts,
+ const GLsizei *counts,
+ GLsizei drawcount)
+{
+ return GL_MultiDrawArraysANGLE(mode, firsts, counts, drawcount);
+}
+
+void GL_APIENTRY glMultiDrawArraysInstancedANGLE(GLenum mode,
+ const GLint *firsts,
+ const GLsizei *counts,
+ const GLsizei *instanceCounts,
+ GLsizei drawcount)
+{
+ return GL_MultiDrawArraysInstancedANGLE(mode, firsts, counts, instanceCounts, drawcount);
+}
+
+void GL_APIENTRY glMultiDrawElementsANGLE(GLenum mode,
+ const GLsizei *counts,
+ GLenum type,
+ const GLvoid *const *indices,
+ GLsizei drawcount)
+{
+ return GL_MultiDrawElementsANGLE(mode, counts, type, indices, drawcount);
+}
+
+void GL_APIENTRY glMultiDrawElementsInstancedANGLE(GLenum mode,
+ const GLsizei *counts,
+ GLenum type,
+ const GLvoid *const *indices,
+ const GLsizei *instanceCounts,
+ GLsizei drawcount)
+{
+ return GL_MultiDrawElementsInstancedANGLE(mode, counts, type, indices, instanceCounts,
+ drawcount);
+}
+
+// GL_ANGLE_pack_reverse_row_order
+
+// GL_ANGLE_program_binary
+
+// GL_ANGLE_provoking_vertex
+void GL_APIENTRY glProvokingVertexANGLE(GLenum mode)
+{
+ return GL_ProvokingVertexANGLE(mode);
+}
+
+// GL_ANGLE_request_extension
+void GL_APIENTRY glRequestExtensionANGLE(const GLchar *name)
+{
+ return GL_RequestExtensionANGLE(name);
+}
+
+void GL_APIENTRY glDisableExtensionANGLE(const GLchar *name)
+{
+ return GL_DisableExtensionANGLE(name);
+}
+
+// GL_ANGLE_robust_client_memory
+void GL_APIENTRY glGetBooleanvRobustANGLE(GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLboolean *params)
+{
+ return GL_GetBooleanvRobustANGLE(pname, bufSize, length, params);
+}
+
+void GL_APIENTRY glGetBufferParameterivRobustANGLE(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ return GL_GetBufferParameterivRobustANGLE(target, pname, bufSize, length, params);
+}
+
+void GL_APIENTRY glGetFloatvRobustANGLE(GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params)
+{
+ return GL_GetFloatvRobustANGLE(pname, bufSize, length, params);
+}
+
+void GL_APIENTRY glGetFramebufferAttachmentParameterivRobustANGLE(GLenum target,
+ GLenum attachment,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ return GL_GetFramebufferAttachmentParameterivRobustANGLE(target, attachment, pname, bufSize,
+ length, params);
+}
+
+void GL_APIENTRY glGetIntegervRobustANGLE(GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *data)
+{
+ return GL_GetIntegervRobustANGLE(pname, bufSize, length, data);
+}
+
+void GL_APIENTRY glGetProgramivRobustANGLE(GLuint program,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ return GL_GetProgramivRobustANGLE(program, pname, bufSize, length, params);
+}
+
+void GL_APIENTRY glGetRenderbufferParameterivRobustANGLE(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ return GL_GetRenderbufferParameterivRobustANGLE(target, pname, bufSize, length, params);
+}
+
+void GL_APIENTRY glGetShaderivRobustANGLE(GLuint shader,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ return GL_GetShaderivRobustANGLE(shader, pname, bufSize, length, params);
+}
+
+void GL_APIENTRY glGetTexParameterfvRobustANGLE(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params)
+{
+ return GL_GetTexParameterfvRobustANGLE(target, pname, bufSize, length, params);
+}
+
+void GL_APIENTRY glGetTexParameterivRobustANGLE(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ return GL_GetTexParameterivRobustANGLE(target, pname, bufSize, length, params);
+}
+
+void GL_APIENTRY glGetUniformfvRobustANGLE(GLuint program,
+ GLint location,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params)
+{
+ return GL_GetUniformfvRobustANGLE(program, location, bufSize, length, params);
+}
+
+void GL_APIENTRY glGetUniformivRobustANGLE(GLuint program,
+ GLint location,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ return GL_GetUniformivRobustANGLE(program, location, bufSize, length, params);
+}
+
+void GL_APIENTRY glGetVertexAttribfvRobustANGLE(GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params)
+{
+ return GL_GetVertexAttribfvRobustANGLE(index, pname, bufSize, length, params);
+}
+
+void GL_APIENTRY glGetVertexAttribivRobustANGLE(GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ return GL_GetVertexAttribivRobustANGLE(index, pname, bufSize, length, params);
+}
+
+void GL_APIENTRY glGetVertexAttribPointervRobustANGLE(GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ void **pointer)
+{
+ return GL_GetVertexAttribPointervRobustANGLE(index, pname, bufSize, length, pointer);
+}
+
+void GL_APIENTRY glReadPixelsRobustANGLE(GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLsizei *columns,
+ GLsizei *rows,
+ void *pixels)
+{
+ return GL_ReadPixelsRobustANGLE(x, y, width, height, format, type, bufSize, length, columns,
+ rows, pixels);
+}
+
+void GL_APIENTRY glTexImage2DRobustANGLE(GLenum target,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *pixels)
+{
+ return GL_TexImage2DRobustANGLE(target, level, internalformat, width, height, border, format,
+ type, bufSize, pixels);
+}
+
+void GL_APIENTRY glTexParameterfvRobustANGLE(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLfloat *params)
+{
+ return GL_TexParameterfvRobustANGLE(target, pname, bufSize, params);
+}
+
+void GL_APIENTRY glTexParameterivRobustANGLE(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLint *params)
+{
+ return GL_TexParameterivRobustANGLE(target, pname, bufSize, params);
+}
+
+void GL_APIENTRY glTexSubImage2DRobustANGLE(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *pixels)
+{
+ return GL_TexSubImage2DRobustANGLE(target, level, xoffset, yoffset, width, height, format, type,
+ bufSize, pixels);
+}
+
+void GL_APIENTRY glTexImage3DRobustANGLE(GLenum target,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ const void *pixels)
+{
+ return GL_TexImage3DRobustANGLE(target, level, internalformat, width, height, depth, border,
+ format, type, bufSize, pixels);
+}
+
+void GL_APIENTRY glTexSubImage3DRobustANGLE(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)
+{
+ return GL_TexSubImage3DRobustANGLE(target, level, xoffset, yoffset, zoffset, width, height,
+ depth, format, type, bufSize, pixels);
+}
+
+void GL_APIENTRY glCompressedTexImage2DRobustANGLE(GLenum target,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLsizei imageSize,
+ GLsizei dataSize,
+ const GLvoid *data)
+{
+ return GL_CompressedTexImage2DRobustANGLE(target, level, internalformat, width, height, border,
+ imageSize, dataSize, data);
+}
+
+void GL_APIENTRY glCompressedTexSubImage2DRobustANGLE(GLenum target,
+ GLint level,
+ GLsizei xoffset,
+ GLsizei yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLsizei imageSize,
+ GLsizei dataSize,
+ const GLvoid *data)
+{
+ return GL_CompressedTexSubImage2DRobustANGLE(target, level, xoffset, yoffset, width, height,
+ format, imageSize, dataSize, data);
+}
+
+void GL_APIENTRY glCompressedTexImage3DRobustANGLE(GLenum target,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLsizei imageSize,
+ GLsizei dataSize,
+ const GLvoid *data)
+{
+ return GL_CompressedTexImage3DRobustANGLE(target, level, internalformat, width, height, depth,
+ border, imageSize, dataSize, data);
+}
+
+void GL_APIENTRY glCompressedTexSubImage3DRobustANGLE(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLsizei imageSize,
+ GLsizei dataSize,
+ const GLvoid *data)
+{
+ return GL_CompressedTexSubImage3DRobustANGLE(target, level, xoffset, yoffset, zoffset, width,
+ height, depth, format, imageSize, dataSize, data);
+}
+
+void GL_APIENTRY glGetQueryivRobustANGLE(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ return GL_GetQueryivRobustANGLE(target, pname, bufSize, length, params);
+}
+
+void GL_APIENTRY glGetQueryObjectuivRobustANGLE(GLuint id,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint *params)
+{
+ return GL_GetQueryObjectuivRobustANGLE(id, pname, bufSize, length, params);
+}
+
+void GL_APIENTRY glGetBufferPointervRobustANGLE(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ void **params)
+{
+ return GL_GetBufferPointervRobustANGLE(target, pname, bufSize, length, params);
+}
+
+void GL_APIENTRY glGetIntegeri_vRobustANGLE(GLenum target,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *data)
+{
+ return GL_GetIntegeri_vRobustANGLE(target, index, bufSize, length, data);
+}
+
+void GL_APIENTRY glGetInternalformativRobustANGLE(GLenum target,
+ GLenum internalformat,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ return GL_GetInternalformativRobustANGLE(target, internalformat, pname, bufSize, length,
+ params);
+}
+
+void GL_APIENTRY glGetVertexAttribIivRobustANGLE(GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ return GL_GetVertexAttribIivRobustANGLE(index, pname, bufSize, length, params);
+}
+
+void GL_APIENTRY glGetVertexAttribIuivRobustANGLE(GLuint index,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint *params)
+{
+ return GL_GetVertexAttribIuivRobustANGLE(index, pname, bufSize, length, params);
+}
+
+void GL_APIENTRY glGetUniformuivRobustANGLE(GLuint program,
+ GLint location,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint *params)
+{
+ return GL_GetUniformuivRobustANGLE(program, location, bufSize, length, params);
+}
+
+void GL_APIENTRY glGetActiveUniformBlockivRobustANGLE(GLuint program,
+ GLuint uniformBlockIndex,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ return GL_GetActiveUniformBlockivRobustANGLE(program, uniformBlockIndex, pname, bufSize, length,
+ params);
+}
+
+void GL_APIENTRY glGetInteger64vRobustANGLE(GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint64 *data)
+{
+ return GL_GetInteger64vRobustANGLE(pname, bufSize, length, data);
+}
+
+void GL_APIENTRY glGetInteger64i_vRobustANGLE(GLenum target,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint64 *data)
+{
+ return GL_GetInteger64i_vRobustANGLE(target, index, bufSize, length, data);
+}
+
+void GL_APIENTRY glGetBufferParameteri64vRobustANGLE(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint64 *params)
+{
+ return GL_GetBufferParameteri64vRobustANGLE(target, pname, bufSize, length, params);
+}
+
+void GL_APIENTRY glSamplerParameterivRobustANGLE(GLuint sampler,
+ GLuint pname,
+ GLsizei bufSize,
+ const GLint *param)
+{
+ return GL_SamplerParameterivRobustANGLE(sampler, pname, bufSize, param);
+}
+
+void GL_APIENTRY glSamplerParameterfvRobustANGLE(GLuint sampler,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLfloat *param)
+{
+ return GL_SamplerParameterfvRobustANGLE(sampler, pname, bufSize, param);
+}
+
+void GL_APIENTRY glGetSamplerParameterivRobustANGLE(GLuint sampler,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ return GL_GetSamplerParameterivRobustANGLE(sampler, pname, bufSize, length, params);
+}
+
+void GL_APIENTRY glGetSamplerParameterfvRobustANGLE(GLuint sampler,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params)
+{
+ return GL_GetSamplerParameterfvRobustANGLE(sampler, pname, bufSize, length, params);
+}
+
+void GL_APIENTRY glGetFramebufferParameterivRobustANGLE(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ return GL_GetFramebufferParameterivRobustANGLE(target, pname, bufSize, length, params);
+}
+
+void GL_APIENTRY glGetProgramInterfaceivRobustANGLE(GLuint program,
+ GLenum programInterface,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ return GL_GetProgramInterfaceivRobustANGLE(program, programInterface, pname, bufSize, length,
+ params);
+}
+
+void GL_APIENTRY glGetBooleani_vRobustANGLE(GLenum target,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLboolean *data)
+{
+ return GL_GetBooleani_vRobustANGLE(target, index, bufSize, length, data);
+}
+
+void GL_APIENTRY glGetMultisamplefvRobustANGLE(GLenum pname,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *val)
+{
+ return GL_GetMultisamplefvRobustANGLE(pname, index, bufSize, length, val);
+}
+
+void GL_APIENTRY glGetTexLevelParameterivRobustANGLE(GLenum target,
+ GLint level,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ return GL_GetTexLevelParameterivRobustANGLE(target, level, pname, bufSize, length, params);
+}
+
+void GL_APIENTRY glGetTexLevelParameterfvRobustANGLE(GLenum target,
+ GLint level,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params)
+{
+ return GL_GetTexLevelParameterfvRobustANGLE(target, level, pname, bufSize, length, params);
+}
+
+void GL_APIENTRY glGetPointervRobustANGLERobustANGLE(GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ void **params)
+{
+ return GL_GetPointervRobustANGLERobustANGLE(pname, bufSize, length, params);
+}
+
+void GL_APIENTRY glReadnPixelsRobustANGLE(GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLsizei *columns,
+ GLsizei *rows,
+ void *data)
+{
+ return GL_ReadnPixelsRobustANGLE(x, y, width, height, format, type, bufSize, length, columns,
+ rows, data);
+}
+
+void GL_APIENTRY glGetnUniformfvRobustANGLE(GLuint program,
+ GLint location,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLfloat *params)
+{
+ return GL_GetnUniformfvRobustANGLE(program, location, bufSize, length, params);
+}
+
+void GL_APIENTRY glGetnUniformivRobustANGLE(GLuint program,
+ GLint location,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ return GL_GetnUniformivRobustANGLE(program, location, bufSize, length, params);
+}
+
+void GL_APIENTRY glGetnUniformuivRobustANGLE(GLuint program,
+ GLint location,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint *params)
+{
+ return GL_GetnUniformuivRobustANGLE(program, location, bufSize, length, params);
+}
+
+void GL_APIENTRY glTexParameterIivRobustANGLE(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLint *params)
+{
+ return GL_TexParameterIivRobustANGLE(target, pname, bufSize, params);
+}
+
+void GL_APIENTRY glTexParameterIuivRobustANGLE(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLuint *params)
+{
+ return GL_TexParameterIuivRobustANGLE(target, pname, bufSize, params);
+}
+
+void GL_APIENTRY glGetTexParameterIivRobustANGLE(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ return GL_GetTexParameterIivRobustANGLE(target, pname, bufSize, length, params);
+}
+
+void GL_APIENTRY glGetTexParameterIuivRobustANGLE(GLenum target,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint *params)
+{
+ return GL_GetTexParameterIuivRobustANGLE(target, pname, bufSize, length, params);
+}
+
+void GL_APIENTRY glSamplerParameterIivRobustANGLE(GLuint sampler,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLint *param)
+{
+ return GL_SamplerParameterIivRobustANGLE(sampler, pname, bufSize, param);
+}
+
+void GL_APIENTRY glSamplerParameterIuivRobustANGLE(GLuint sampler,
+ GLenum pname,
+ GLsizei bufSize,
+ const GLuint *param)
+{
+ return GL_SamplerParameterIuivRobustANGLE(sampler, pname, bufSize, param);
+}
+
+void GL_APIENTRY glGetSamplerParameterIivRobustANGLE(GLuint sampler,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ return GL_GetSamplerParameterIivRobustANGLE(sampler, pname, bufSize, length, params);
+}
+
+void GL_APIENTRY glGetSamplerParameterIuivRobustANGLE(GLuint sampler,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint *params)
+{
+ return GL_GetSamplerParameterIuivRobustANGLE(sampler, pname, bufSize, length, params);
+}
+
+void GL_APIENTRY glGetQueryObjectivRobustANGLE(GLuint id,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint *params)
+{
+ return GL_GetQueryObjectivRobustANGLE(id, pname, bufSize, length, params);
+}
+
+void GL_APIENTRY glGetQueryObjecti64vRobustANGLE(GLuint id,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLint64 *params)
+{
+ return GL_GetQueryObjecti64vRobustANGLE(id, pname, bufSize, length, params);
+}
+
+void GL_APIENTRY glGetQueryObjectui64vRobustANGLE(GLuint id,
+ GLenum pname,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLuint64 *params)
+{
+ return GL_GetQueryObjectui64vRobustANGLE(id, pname, bufSize, length, params);
+}
+
+// GL_ANGLE_robust_resource_initialization
+
+// GL_ANGLE_semaphore_fuchsia
+void GL_APIENTRY glImportSemaphoreZirconHandleANGLE(GLuint semaphore,
+ GLenum handleType,
+ GLuint handle)
+{
+ return GL_ImportSemaphoreZirconHandleANGLE(semaphore, handleType, handle);
+}
+
+// GL_ANGLE_shader_pixel_local_storage
+void GL_APIENTRY glFramebufferMemorylessPixelLocalStorageANGLE(GLint plane, GLenum internalformat)
+{
+ return GL_FramebufferMemorylessPixelLocalStorageANGLE(plane, internalformat);
+}
+
+void GL_APIENTRY glFramebufferTexturePixelLocalStorageANGLE(GLint plane,
+ GLuint backingtexture,
+ GLint level,
+ GLint layer)
+{
+ return GL_FramebufferTexturePixelLocalStorageANGLE(plane, backingtexture, level, layer);
+}
+
+void GL_APIENTRY glBeginPixelLocalStorageANGLE(GLsizei planes,
+ const GLenum *loadops,
+ const void *cleardata)
+{
+ return GL_BeginPixelLocalStorageANGLE(planes, loadops, cleardata);
+}
+
+void GL_APIENTRY glEndPixelLocalStorageANGLE()
+{
+ return GL_EndPixelLocalStorageANGLE();
+}
+
+void GL_APIENTRY glPixelLocalStorageBarrierANGLE()
+{
+ return GL_PixelLocalStorageBarrierANGLE();
+}
+
+// GL_ANGLE_texture_compression_dxt3
+
+// GL_ANGLE_texture_compression_dxt5
+
+// GL_ANGLE_texture_external_update
+void GL_APIENTRY glTexImage2DExternalANGLE(GLenum target,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLenum format,
+ GLenum type)
+{
+ return GL_TexImage2DExternalANGLE(target, level, internalformat, width, height, border, format,
+ type);
+}
+
+void GL_APIENTRY glInvalidateTextureANGLE(GLenum target)
+{
+ return GL_InvalidateTextureANGLE(target);
+}
+
+// GL_ANGLE_texture_multisample
+void GL_APIENTRY glTexStorage2DMultisampleANGLE(GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedsamplelocations)
+{
+ return GL_TexStorage2DMultisampleANGLE(target, samples, internalformat, width, height,
+ fixedsamplelocations);
+}
+
+void GL_APIENTRY glGetMultisamplefvANGLE(GLenum pname, GLuint index, GLfloat *val)
+{
+ return GL_GetMultisamplefvANGLE(pname, index, val);
+}
+
+void GL_APIENTRY glSampleMaskiANGLE(GLuint maskNumber, GLbitfield mask)
+{
+ return GL_SampleMaskiANGLE(maskNumber, mask);
+}
+
+// GL_ANGLE_texture_usage
+
+// GL_ANGLE_translated_shader_source
+void GL_APIENTRY glGetTranslatedShaderSourceANGLE(GLuint shader,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *source)
+{
+ return GL_GetTranslatedShaderSourceANGLE(shader, bufSize, length, source);
+}
+
+// GL_ANGLE_vulkan_image
+void GL_APIENTRY glAcquireTexturesANGLE(GLuint numTextures,
+ const GLuint *textures,
+ const GLenum *layouts)
+{
+ return GL_AcquireTexturesANGLE(numTextures, textures, layouts);
+}
+
+void GL_APIENTRY glReleaseTexturesANGLE(GLuint numTextures, const GLuint *textures, GLenum *layouts)
+{
+ return GL_ReleaseTexturesANGLE(numTextures, textures, layouts);
+}
+
+// GL_APPLE_clip_distance
+
+// GL_ARB_sync
+
+// GL_CHROMIUM_bind_uniform_location
+void GL_APIENTRY glBindUniformLocationCHROMIUM(GLuint program, GLint location, const GLchar *name)
+{
+ return GL_BindUniformLocationCHROMIUM(program, location, name);
+}
+
+// GL_CHROMIUM_copy_compressed_texture
+void GL_APIENTRY glCompressedCopyTextureCHROMIUM(GLuint sourceId, GLuint destId)
+{
+ return GL_CompressedCopyTextureCHROMIUM(sourceId, destId);
+}
+
+// GL_CHROMIUM_copy_texture
+void GL_APIENTRY glCopyTextureCHROMIUM(GLuint sourceId,
+ GLint sourceLevel,
+ GLenum destTarget,
+ GLuint destId,
+ GLint destLevel,
+ GLint internalFormat,
+ GLenum destType,
+ GLboolean unpackFlipY,
+ GLboolean unpackPremultiplyAlpha,
+ GLboolean unpackUnmultiplyAlpha)
+{
+ return GL_CopyTextureCHROMIUM(sourceId, sourceLevel, destTarget, destId, destLevel,
+ internalFormat, destType, unpackFlipY, unpackPremultiplyAlpha,
+ unpackUnmultiplyAlpha);
+}
+
+void GL_APIENTRY glCopySubTextureCHROMIUM(GLuint sourceId,
+ GLint sourceLevel,
+ GLenum destTarget,
+ GLuint destId,
+ GLint destLevel,
+ GLint xoffset,
+ GLint yoffset,
+ GLint x,
+ GLint y,
+ GLint width,
+ GLint height,
+ GLboolean unpackFlipY,
+ GLboolean unpackPremultiplyAlpha,
+ GLboolean unpackUnmultiplyAlpha)
+{
+ return GL_CopySubTextureCHROMIUM(sourceId, sourceLevel, destTarget, destId, destLevel, xoffset,
+ yoffset, x, y, width, height, unpackFlipY,
+ unpackPremultiplyAlpha, unpackUnmultiplyAlpha);
+}
+
+// GL_CHROMIUM_framebuffer_mixed_samples
+void GL_APIENTRY glCoverageModulationCHROMIUM(GLenum components)
+{
+ return GL_CoverageModulationCHROMIUM(components);
+}
+
+// GL_CHROMIUM_lose_context
+void GL_APIENTRY glLoseContextCHROMIUM(GLenum current, GLenum other)
+{
+ return GL_LoseContextCHROMIUM(current, other);
+}
+
+// GL_EXT_EGL_image_array
+
+// GL_EXT_EGL_image_storage
+void GL_APIENTRY glEGLImageTargetTexStorageEXT(GLenum target,
+ GLeglImageOES image,
+ const GLint *attrib_list)
+{
+ return GL_EGLImageTargetTexStorageEXT(target, image, attrib_list);
+}
+
+void GL_APIENTRY glEGLImageTargetTextureStorageEXT(GLuint texture,
+ GLeglImageOES image,
+ const GLint *attrib_list)
+{
+ return GL_EGLImageTargetTextureStorageEXT(texture, image, attrib_list);
+}
+
+// GL_EXT_YUV_target
+
+// GL_EXT_base_instance
+void GL_APIENTRY glDrawArraysInstancedBaseInstanceEXT(GLenum mode,
+ GLint first,
+ GLsizei count,
+ GLsizei instancecount,
+ GLuint baseinstance)
+{
+ return GL_DrawArraysInstancedBaseInstanceEXT(mode, first, count, instancecount, baseinstance);
+}
+
+void GL_APIENTRY glDrawElementsInstancedBaseInstanceEXT(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLsizei instancecount,
+ GLuint baseinstance)
+{
+ return GL_DrawElementsInstancedBaseInstanceEXT(mode, count, type, indices, instancecount,
+ baseinstance);
+}
+
+void GL_APIENTRY glDrawElementsInstancedBaseVertexBaseInstanceEXT(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLsizei instancecount,
+ GLint basevertex,
+ GLuint baseinstance)
+{
+ return GL_DrawElementsInstancedBaseVertexBaseInstanceEXT(
+ mode, count, type, indices, instancecount, basevertex, baseinstance);
+}
+
+// GL_EXT_blend_func_extended
+void GL_APIENTRY glBindFragDataLocationEXT(GLuint program, GLuint color, const GLchar *name)
+{
+ return GL_BindFragDataLocationEXT(program, color, name);
+}
+
+void GL_APIENTRY glBindFragDataLocationIndexedEXT(GLuint program,
+ GLuint colorNumber,
+ GLuint index,
+ const GLchar *name)
+{
+ return GL_BindFragDataLocationIndexedEXT(program, colorNumber, index, name);
+}
+
+GLint GL_APIENTRY glGetFragDataIndexEXT(GLuint program, const GLchar *name)
+{
+ return GL_GetFragDataIndexEXT(program, name);
+}
+
+GLint GL_APIENTRY glGetProgramResourceLocationIndexEXT(GLuint program,
+ GLenum programInterface,
+ const GLchar *name)
+{
+ return GL_GetProgramResourceLocationIndexEXT(program, programInterface, name);
+}
+
+// GL_EXT_blend_minmax
+
+// GL_EXT_buffer_storage
+void GL_APIENTRY glBufferStorageEXT(GLenum target,
+ GLsizeiptr size,
+ const void *data,
+ GLbitfield flags)
+{
+ return GL_BufferStorageEXT(target, size, data, flags);
+}
+
+// GL_EXT_clip_control
+void GL_APIENTRY glClipControlEXT(GLenum origin, GLenum depth)
+{
+ return GL_ClipControlEXT(origin, depth);
+}
+
+// GL_EXT_clip_cull_distance
+
+// GL_EXT_color_buffer_float
+
+// GL_EXT_color_buffer_half_float
+
+// GL_EXT_copy_image
+void GL_APIENTRY glCopyImageSubDataEXT(GLuint srcName,
+ GLenum srcTarget,
+ GLint srcLevel,
+ GLint srcX,
+ GLint srcY,
+ GLint srcZ,
+ GLuint dstName,
+ GLenum dstTarget,
+ GLint dstLevel,
+ GLint dstX,
+ GLint dstY,
+ GLint dstZ,
+ GLsizei srcWidth,
+ GLsizei srcHeight,
+ GLsizei srcDepth)
+{
+ return GL_CopyImageSubDataEXT(srcName, srcTarget, srcLevel, srcX, srcY, srcZ, dstName,
+ dstTarget, dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight,
+ srcDepth);
+}
+
+// GL_EXT_debug_label
+void GL_APIENTRY
+glGetObjectLabelEXT(GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label)
+{
+ return GL_GetObjectLabelEXT(type, object, bufSize, length, label);
+}
+
+void GL_APIENTRY glLabelObjectEXT(GLenum type, GLuint object, GLsizei length, const GLchar *label)
+{
+ return GL_LabelObjectEXT(type, object, length, label);
+}
+
+// GL_EXT_debug_marker
+void GL_APIENTRY glInsertEventMarkerEXT(GLsizei length, const GLchar *marker)
+{
+ return GL_InsertEventMarkerEXT(length, marker);
+}
+
+void GL_APIENTRY glPopGroupMarkerEXT()
+{
+ return GL_PopGroupMarkerEXT();
+}
+
+void GL_APIENTRY glPushGroupMarkerEXT(GLsizei length, const GLchar *marker)
+{
+ return GL_PushGroupMarkerEXT(length, marker);
+}
+
+// GL_EXT_discard_framebuffer
+void GL_APIENTRY glDiscardFramebufferEXT(GLenum target,
+ GLsizei numAttachments,
+ const GLenum *attachments)
+{
+ return GL_DiscardFramebufferEXT(target, numAttachments, attachments);
+}
+
+// GL_EXT_disjoint_timer_query
+void GL_APIENTRY glBeginQueryEXT(GLenum target, GLuint id)
+{
+ return GL_BeginQueryEXT(target, id);
+}
+
+void GL_APIENTRY glDeleteQueriesEXT(GLsizei n, const GLuint *ids)
+{
+ return GL_DeleteQueriesEXT(n, ids);
+}
+
+void GL_APIENTRY glEndQueryEXT(GLenum target)
+{
+ return GL_EndQueryEXT(target);
+}
+
+void GL_APIENTRY glGenQueriesEXT(GLsizei n, GLuint *ids)
+{
+ return GL_GenQueriesEXT(n, ids);
+}
+
+void GL_APIENTRY glGetInteger64vEXT(GLenum pname, GLint64 *data)
+{
+ return GL_GetInteger64vEXT(pname, data);
+}
+
+void GL_APIENTRY glGetQueryObjecti64vEXT(GLuint id, GLenum pname, GLint64 *params)
+{
+ return GL_GetQueryObjecti64vEXT(id, pname, params);
+}
+
+void GL_APIENTRY glGetQueryObjectivEXT(GLuint id, GLenum pname, GLint *params)
+{
+ return GL_GetQueryObjectivEXT(id, pname, params);
+}
+
+void GL_APIENTRY glGetQueryObjectui64vEXT(GLuint id, GLenum pname, GLuint64 *params)
+{
+ return GL_GetQueryObjectui64vEXT(id, pname, params);
+}
+
+void GL_APIENTRY glGetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params)
+{
+ return GL_GetQueryObjectuivEXT(id, pname, params);
+}
+
+void GL_APIENTRY glGetQueryivEXT(GLenum target, GLenum pname, GLint *params)
+{
+ return GL_GetQueryivEXT(target, pname, params);
+}
+
+GLboolean GL_APIENTRY glIsQueryEXT(GLuint id)
+{
+ return GL_IsQueryEXT(id);
+}
+
+void GL_APIENTRY glQueryCounterEXT(GLuint id, GLenum target)
+{
+ return GL_QueryCounterEXT(id, target);
+}
+
+// GL_EXT_draw_buffers
+void GL_APIENTRY glDrawBuffersEXT(GLsizei n, const GLenum *bufs)
+{
+ return GL_DrawBuffersEXT(n, bufs);
+}
+
+// GL_EXT_draw_buffers_indexed
+void GL_APIENTRY glBlendEquationSeparateiEXT(GLuint buf, GLenum modeRGB, GLenum modeAlpha)
+{
+ return GL_BlendEquationSeparateiEXT(buf, modeRGB, modeAlpha);
+}
+
+void GL_APIENTRY glBlendEquationiEXT(GLuint buf, GLenum mode)
+{
+ return GL_BlendEquationiEXT(buf, mode);
+}
+
+void GL_APIENTRY
+glBlendFuncSeparateiEXT(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+{
+ return GL_BlendFuncSeparateiEXT(buf, srcRGB, dstRGB, srcAlpha, dstAlpha);
+}
+
+void GL_APIENTRY glBlendFunciEXT(GLuint buf, GLenum src, GLenum dst)
+{
+ return GL_BlendFunciEXT(buf, src, dst);
+}
+
+void GL_APIENTRY glColorMaskiEXT(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a)
+{
+ return GL_ColorMaskiEXT(index, r, g, b, a);
+}
+
+void GL_APIENTRY glDisableiEXT(GLenum target, GLuint index)
+{
+ return GL_DisableiEXT(target, index);
+}
+
+void GL_APIENTRY glEnableiEXT(GLenum target, GLuint index)
+{
+ return GL_EnableiEXT(target, index);
+}
+
+GLboolean GL_APIENTRY glIsEnablediEXT(GLenum target, GLuint index)
+{
+ return GL_IsEnablediEXT(target, index);
+}
+
+// GL_EXT_draw_elements_base_vertex
+void GL_APIENTRY glDrawElementsBaseVertexEXT(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLint basevertex)
+{
+ return GL_DrawElementsBaseVertexEXT(mode, count, type, indices, basevertex);
+}
+
+void GL_APIENTRY glDrawElementsInstancedBaseVertexEXT(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLsizei instancecount,
+ GLint basevertex)
+{
+ return GL_DrawElementsInstancedBaseVertexEXT(mode, count, type, indices, instancecount,
+ basevertex);
+}
+
+void GL_APIENTRY glDrawRangeElementsBaseVertexEXT(GLenum mode,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLint basevertex)
+{
+ return GL_DrawRangeElementsBaseVertexEXT(mode, start, end, count, type, indices, basevertex);
+}
+
+void GL_APIENTRY glMultiDrawElementsBaseVertexEXT(GLenum mode,
+ const GLsizei *count,
+ GLenum type,
+ const void *const *indices,
+ GLsizei drawcount,
+ const GLint *basevertex)
+{
+ return GL_MultiDrawElementsBaseVertexEXT(mode, count, type, indices, drawcount, basevertex);
+}
+
+// GL_EXT_external_buffer
+void GL_APIENTRY glBufferStorageExternalEXT(GLenum target,
+ GLintptr offset,
+ GLsizeiptr size,
+ GLeglClientBufferEXT clientBuffer,
+ GLbitfield flags)
+{
+ return GL_BufferStorageExternalEXT(target, offset, size, clientBuffer, flags);
+}
+
+void GL_APIENTRY glNamedBufferStorageExternalEXT(GLuint buffer,
+ GLintptr offset,
+ GLsizeiptr size,
+ GLeglClientBufferEXT clientBuffer,
+ GLbitfield flags)
+{
+ return GL_NamedBufferStorageExternalEXT(buffer, offset, size, clientBuffer, flags);
+}
+
+// GL_EXT_float_blend
+
+// GL_EXT_geometry_shader
+void GL_APIENTRY glFramebufferTextureEXT(GLenum target,
+ GLenum attachment,
+ GLuint texture,
+ GLint level)
+{
+ return GL_FramebufferTextureEXT(target, attachment, texture, level);
+}
+
+// GL_EXT_gpu_shader5
+
+// GL_EXT_instanced_arrays
+void GL_APIENTRY glDrawArraysInstancedEXT(GLenum mode,
+ GLint start,
+ GLsizei count,
+ GLsizei primcount)
+{
+ return GL_DrawArraysInstancedEXT(mode, start, count, primcount);
+}
+
+void GL_APIENTRY glDrawElementsInstancedEXT(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLsizei primcount)
+{
+ return GL_DrawElementsInstancedEXT(mode, count, type, indices, primcount);
+}
+
+void GL_APIENTRY glVertexAttribDivisorEXT(GLuint index, GLuint divisor)
+{
+ return GL_VertexAttribDivisorEXT(index, divisor);
+}
+
+// GL_EXT_map_buffer_range
+void GL_APIENTRY glFlushMappedBufferRangeEXT(GLenum target, GLintptr offset, GLsizeiptr length)
+{
+ return GL_FlushMappedBufferRangeEXT(target, offset, length);
+}
+
+void *GL_APIENTRY glMapBufferRangeEXT(GLenum target,
+ GLintptr offset,
+ GLsizeiptr length,
+ GLbitfield access)
+{
+ return GL_MapBufferRangeEXT(target, offset, length, access);
+}
+
+// GL_EXT_memory_object
+void GL_APIENTRY glBufferStorageMemEXT(GLenum target,
+ GLsizeiptr size,
+ GLuint memory,
+ GLuint64 offset)
+{
+ return GL_BufferStorageMemEXT(target, size, memory, offset);
+}
+
+void GL_APIENTRY glCreateMemoryObjectsEXT(GLsizei n, GLuint *memoryObjects)
+{
+ return GL_CreateMemoryObjectsEXT(n, memoryObjects);
+}
+
+void GL_APIENTRY glDeleteMemoryObjectsEXT(GLsizei n, const GLuint *memoryObjects)
+{
+ return GL_DeleteMemoryObjectsEXT(n, memoryObjects);
+}
+
+void GL_APIENTRY glGetMemoryObjectParameterivEXT(GLuint memoryObject, GLenum pname, GLint *params)
+{
+ return GL_GetMemoryObjectParameterivEXT(memoryObject, pname, params);
+}
+
+void GL_APIENTRY glGetUnsignedBytevEXT(GLenum pname, GLubyte *data)
+{
+ return GL_GetUnsignedBytevEXT(pname, data);
+}
+
+void GL_APIENTRY glGetUnsignedBytei_vEXT(GLenum target, GLuint index, GLubyte *data)
+{
+ return GL_GetUnsignedBytei_vEXT(target, index, data);
+}
+
+GLboolean GL_APIENTRY glIsMemoryObjectEXT(GLuint memoryObject)
+{
+ return GL_IsMemoryObjectEXT(memoryObject);
+}
+
+void GL_APIENTRY glMemoryObjectParameterivEXT(GLuint memoryObject,
+ GLenum pname,
+ const GLint *params)
+{
+ return GL_MemoryObjectParameterivEXT(memoryObject, pname, params);
+}
+
+void GL_APIENTRY glTexStorageMem2DEXT(GLenum target,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLuint memory,
+ GLuint64 offset)
+{
+ return GL_TexStorageMem2DEXT(target, levels, internalFormat, width, height, memory, offset);
+}
+
+void GL_APIENTRY glTexStorageMem2DMultisampleEXT(GLenum target,
+ GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedSampleLocations,
+ GLuint memory,
+ GLuint64 offset)
+{
+ return GL_TexStorageMem2DMultisampleEXT(target, samples, internalFormat, width, height,
+ fixedSampleLocations, memory, offset);
+}
+
+void GL_APIENTRY glTexStorageMem3DEXT(GLenum target,
+ GLsizei levels,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLuint memory,
+ GLuint64 offset)
+{
+ return GL_TexStorageMem3DEXT(target, levels, internalFormat, width, height, depth, memory,
+ offset);
+}
+
+void GL_APIENTRY glTexStorageMem3DMultisampleEXT(GLenum target,
+ GLsizei samples,
+ GLenum internalFormat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean fixedSampleLocations,
+ GLuint memory,
+ GLuint64 offset)
+{
+ return GL_TexStorageMem3DMultisampleEXT(target, samples, internalFormat, width, height, depth,
+ fixedSampleLocations, memory, offset);
+}
+
+// GL_EXT_memory_object_fd
+void GL_APIENTRY glImportMemoryFdEXT(GLuint memory, GLuint64 size, GLenum handleType, GLint fd)
+{
+ return GL_ImportMemoryFdEXT(memory, size, handleType, fd);
+}
+
+// GL_EXT_multi_draw_indirect
+void GL_APIENTRY glMultiDrawArraysIndirectEXT(GLenum mode,
+ const void *indirect,
+ GLsizei drawcount,
+ GLsizei stride)
+{
+ return GL_MultiDrawArraysIndirectEXT(mode, indirect, drawcount, stride);
+}
+
+void GL_APIENTRY glMultiDrawElementsIndirectEXT(GLenum mode,
+ GLenum type,
+ const void *indirect,
+ GLsizei drawcount,
+ GLsizei stride)
+{
+ return GL_MultiDrawElementsIndirectEXT(mode, type, indirect, drawcount, stride);
+}
+
+// GL_EXT_multisampled_render_to_texture
+void GL_APIENTRY glFramebufferTexture2DMultisampleEXT(GLenum target,
+ GLenum attachment,
+ GLenum textarget,
+ GLuint texture,
+ GLint level,
+ GLsizei samples)
+{
+ return GL_FramebufferTexture2DMultisampleEXT(target, attachment, textarget, texture, level,
+ samples);
+}
+
+void GL_APIENTRY glRenderbufferStorageMultisampleEXT(GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height)
+{
+ return GL_RenderbufferStorageMultisampleEXT(target, samples, internalformat, width, height);
+}
+
+// GL_EXT_multisampled_render_to_texture2
+
+// GL_EXT_occlusion_query_boolean
+
+// GL_EXT_primitive_bounding_box
+void GL_APIENTRY glPrimitiveBoundingBoxEXT(GLfloat minX,
+ GLfloat minY,
+ GLfloat minZ,
+ GLfloat minW,
+ GLfloat maxX,
+ GLfloat maxY,
+ GLfloat maxZ,
+ GLfloat maxW)
+{
+ return GL_PrimitiveBoundingBoxEXT(minX, minY, minZ, minW, maxX, maxY, maxZ, maxW);
+}
+
+// GL_EXT_protected_textures
+
+// GL_EXT_pvrtc_sRGB
+
+// GL_EXT_read_format_bgra
+
+// GL_EXT_robustness
+GLenum GL_APIENTRY glGetGraphicsResetStatusEXT()
+{
+ return GL_GetGraphicsResetStatusEXT();
+}
+
+void GL_APIENTRY glGetnUniformfvEXT(GLuint program,
+ GLint location,
+ GLsizei bufSize,
+ GLfloat *params)
+{
+ return GL_GetnUniformfvEXT(program, location, bufSize, params);
+}
+
+void GL_APIENTRY glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint *params)
+{
+ return GL_GetnUniformivEXT(program, location, bufSize, params);
+}
+
+void GL_APIENTRY glReadnPixelsEXT(GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ void *data)
+{
+ return GL_ReadnPixelsEXT(x, y, width, height, format, type, bufSize, data);
+}
+
+// GL_EXT_sRGB
+
+// GL_EXT_sRGB_write_control
+
+// GL_EXT_semaphore
+void GL_APIENTRY glDeleteSemaphoresEXT(GLsizei n, const GLuint *semaphores)
+{
+ return GL_DeleteSemaphoresEXT(n, semaphores);
+}
+
+void GL_APIENTRY glGenSemaphoresEXT(GLsizei n, GLuint *semaphores)
+{
+ return GL_GenSemaphoresEXT(n, semaphores);
+}
+
+void GL_APIENTRY glGetSemaphoreParameterui64vEXT(GLuint semaphore, GLenum pname, GLuint64 *params)
+{
+ return GL_GetSemaphoreParameterui64vEXT(semaphore, pname, params);
+}
+
+GLboolean GL_APIENTRY glIsSemaphoreEXT(GLuint semaphore)
+{
+ return GL_IsSemaphoreEXT(semaphore);
+}
+
+void GL_APIENTRY glSemaphoreParameterui64vEXT(GLuint semaphore,
+ GLenum pname,
+ const GLuint64 *params)
+{
+ return GL_SemaphoreParameterui64vEXT(semaphore, pname, params);
+}
+
+void GL_APIENTRY glSignalSemaphoreEXT(GLuint semaphore,
+ GLuint numBufferBarriers,
+ const GLuint *buffers,
+ GLuint numTextureBarriers,
+ const GLuint *textures,
+ const GLenum *dstLayouts)
+{
+ return GL_SignalSemaphoreEXT(semaphore, numBufferBarriers, buffers, numTextureBarriers,
+ textures, dstLayouts);
+}
+
+void GL_APIENTRY glWaitSemaphoreEXT(GLuint semaphore,
+ GLuint numBufferBarriers,
+ const GLuint *buffers,
+ GLuint numTextureBarriers,
+ const GLuint *textures,
+ const GLenum *srcLayouts)
+{
+ return GL_WaitSemaphoreEXT(semaphore, numBufferBarriers, buffers, numTextureBarriers, textures,
+ srcLayouts);
+}
+
+// GL_EXT_semaphore_fd
+void GL_APIENTRY glImportSemaphoreFdEXT(GLuint semaphore, GLenum handleType, GLint fd)
+{
+ return GL_ImportSemaphoreFdEXT(semaphore, handleType, fd);
+}
+
+// GL_EXT_separate_shader_objects
+void GL_APIENTRY glActiveShaderProgramEXT(GLuint pipeline, GLuint program)
+{
+ return GL_ActiveShaderProgramEXT(pipeline, program);
+}
+
+void GL_APIENTRY glBindProgramPipelineEXT(GLuint pipeline)
+{
+ return GL_BindProgramPipelineEXT(pipeline);
+}
+
+GLuint GL_APIENTRY glCreateShaderProgramvEXT(GLenum type, GLsizei count, const GLchar **strings)
+{
+ return GL_CreateShaderProgramvEXT(type, count, strings);
+}
+
+void GL_APIENTRY glDeleteProgramPipelinesEXT(GLsizei n, const GLuint *pipelines)
+{
+ return GL_DeleteProgramPipelinesEXT(n, pipelines);
+}
+
+void GL_APIENTRY glGenProgramPipelinesEXT(GLsizei n, GLuint *pipelines)
+{
+ return GL_GenProgramPipelinesEXT(n, pipelines);
+}
+
+void GL_APIENTRY glGetProgramPipelineInfoLogEXT(GLuint pipeline,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *infoLog)
+{
+ return GL_GetProgramPipelineInfoLogEXT(pipeline, bufSize, length, infoLog);
+}
+
+void GL_APIENTRY glGetProgramPipelineivEXT(GLuint pipeline, GLenum pname, GLint *params)
+{
+ return GL_GetProgramPipelineivEXT(pipeline, pname, params);
+}
+
+GLboolean GL_APIENTRY glIsProgramPipelineEXT(GLuint pipeline)
+{
+ return GL_IsProgramPipelineEXT(pipeline);
+}
+
+void GL_APIENTRY glProgramParameteriEXT(GLuint program, GLenum pname, GLint value)
+{
+ return GL_ProgramParameteriEXT(program, pname, value);
+}
+
+void GL_APIENTRY glProgramUniform1fEXT(GLuint program, GLint location, GLfloat v0)
+{
+ return GL_ProgramUniform1fEXT(program, location, v0);
+}
+
+void GL_APIENTRY glProgramUniform1fvEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLfloat *value)
+{
+ return GL_ProgramUniform1fvEXT(program, location, count, value);
+}
+
+void GL_APIENTRY glProgramUniform1iEXT(GLuint program, GLint location, GLint v0)
+{
+ return GL_ProgramUniform1iEXT(program, location, v0);
+}
+
+void GL_APIENTRY glProgramUniform1ivEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLint *value)
+{
+ return GL_ProgramUniform1ivEXT(program, location, count, value);
+}
+
+void GL_APIENTRY glProgramUniform1uiEXT(GLuint program, GLint location, GLuint v0)
+{
+ return GL_ProgramUniform1uiEXT(program, location, v0);
+}
+
+void GL_APIENTRY glProgramUniform1uivEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLuint *value)
+{
+ return GL_ProgramUniform1uivEXT(program, location, count, value);
+}
+
+void GL_APIENTRY glProgramUniform2fEXT(GLuint program, GLint location, GLfloat v0, GLfloat v1)
+{
+ return GL_ProgramUniform2fEXT(program, location, v0, v1);
+}
+
+void GL_APIENTRY glProgramUniform2fvEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLfloat *value)
+{
+ return GL_ProgramUniform2fvEXT(program, location, count, value);
+}
+
+void GL_APIENTRY glProgramUniform2iEXT(GLuint program, GLint location, GLint v0, GLint v1)
+{
+ return GL_ProgramUniform2iEXT(program, location, v0, v1);
+}
+
+void GL_APIENTRY glProgramUniform2ivEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLint *value)
+{
+ return GL_ProgramUniform2ivEXT(program, location, count, value);
+}
+
+void GL_APIENTRY glProgramUniform2uiEXT(GLuint program, GLint location, GLuint v0, GLuint v1)
+{
+ return GL_ProgramUniform2uiEXT(program, location, v0, v1);
+}
+
+void GL_APIENTRY glProgramUniform2uivEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLuint *value)
+{
+ return GL_ProgramUniform2uivEXT(program, location, count, value);
+}
+
+void GL_APIENTRY
+glProgramUniform3fEXT(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
+{
+ return GL_ProgramUniform3fEXT(program, location, v0, v1, v2);
+}
+
+void GL_APIENTRY glProgramUniform3fvEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLfloat *value)
+{
+ return GL_ProgramUniform3fvEXT(program, location, count, value);
+}
+
+void GL_APIENTRY glProgramUniform3iEXT(GLuint program, GLint location, GLint v0, GLint v1, GLint v2)
+{
+ return GL_ProgramUniform3iEXT(program, location, v0, v1, v2);
+}
+
+void GL_APIENTRY glProgramUniform3ivEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLint *value)
+{
+ return GL_ProgramUniform3ivEXT(program, location, count, value);
+}
+
+void GL_APIENTRY
+glProgramUniform3uiEXT(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2)
+{
+ return GL_ProgramUniform3uiEXT(program, location, v0, v1, v2);
+}
+
+void GL_APIENTRY glProgramUniform3uivEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLuint *value)
+{
+ return GL_ProgramUniform3uivEXT(program, location, count, value);
+}
+
+void GL_APIENTRY glProgramUniform4fEXT(GLuint program,
+ GLint location,
+ GLfloat v0,
+ GLfloat v1,
+ GLfloat v2,
+ GLfloat v3)
+{
+ return GL_ProgramUniform4fEXT(program, location, v0, v1, v2, v3);
+}
+
+void GL_APIENTRY glProgramUniform4fvEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLfloat *value)
+{
+ return GL_ProgramUniform4fvEXT(program, location, count, value);
+}
+
+void GL_APIENTRY
+glProgramUniform4iEXT(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
+{
+ return GL_ProgramUniform4iEXT(program, location, v0, v1, v2, v3);
+}
+
+void GL_APIENTRY glProgramUniform4ivEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLint *value)
+{
+ return GL_ProgramUniform4ivEXT(program, location, count, value);
+}
+
+void GL_APIENTRY
+glProgramUniform4uiEXT(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
+{
+ return GL_ProgramUniform4uiEXT(program, location, v0, v1, v2, v3);
+}
+
+void GL_APIENTRY glProgramUniform4uivEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLuint *value)
+{
+ return GL_ProgramUniform4uivEXT(program, location, count, value);
+}
+
+void GL_APIENTRY glProgramUniformMatrix2fvEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return GL_ProgramUniformMatrix2fvEXT(program, location, count, transpose, value);
+}
+
+void GL_APIENTRY glProgramUniformMatrix2x3fvEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return GL_ProgramUniformMatrix2x3fvEXT(program, location, count, transpose, value);
+}
+
+void GL_APIENTRY glProgramUniformMatrix2x4fvEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return GL_ProgramUniformMatrix2x4fvEXT(program, location, count, transpose, value);
+}
+
+void GL_APIENTRY glProgramUniformMatrix3fvEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return GL_ProgramUniformMatrix3fvEXT(program, location, count, transpose, value);
+}
+
+void GL_APIENTRY glProgramUniformMatrix3x2fvEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return GL_ProgramUniformMatrix3x2fvEXT(program, location, count, transpose, value);
+}
+
+void GL_APIENTRY glProgramUniformMatrix3x4fvEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return GL_ProgramUniformMatrix3x4fvEXT(program, location, count, transpose, value);
+}
+
+void GL_APIENTRY glProgramUniformMatrix4fvEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return GL_ProgramUniformMatrix4fvEXT(program, location, count, transpose, value);
+}
+
+void GL_APIENTRY glProgramUniformMatrix4x2fvEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return GL_ProgramUniformMatrix4x2fvEXT(program, location, count, transpose, value);
+}
+
+void GL_APIENTRY glProgramUniformMatrix4x3fvEXT(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLfloat *value)
+{
+ return GL_ProgramUniformMatrix4x3fvEXT(program, location, count, transpose, value);
+}
+
+void GL_APIENTRY glUseProgramStagesEXT(GLuint pipeline, GLbitfield stages, GLuint program)
+{
+ return GL_UseProgramStagesEXT(pipeline, stages, program);
+}
+
+void GL_APIENTRY glValidateProgramPipelineEXT(GLuint pipeline)
+{
+ return GL_ValidateProgramPipelineEXT(pipeline);
+}
+
+// GL_EXT_shader_framebuffer_fetch
+
+// GL_EXT_shader_framebuffer_fetch_non_coherent
+void GL_APIENTRY glFramebufferFetchBarrierEXT()
+{
+ return GL_FramebufferFetchBarrierEXT();
+}
+
+// GL_EXT_shader_io_blocks
+
+// GL_EXT_shader_non_constant_global_initializers
+
+// GL_EXT_shader_texture_lod
+
+// GL_EXT_shadow_samplers
+
+// GL_EXT_tessellation_shader
+void GL_APIENTRY glPatchParameteriEXT(GLenum pname, GLint value)
+{
+ return GL_PatchParameteriEXT(pname, value);
+}
+
+// GL_EXT_texture_border_clamp
+void GL_APIENTRY glGetSamplerParameterIivEXT(GLuint sampler, GLenum pname, GLint *params)
+{
+ return GL_GetSamplerParameterIivEXT(sampler, pname, params);
+}
+
+void GL_APIENTRY glGetSamplerParameterIuivEXT(GLuint sampler, GLenum pname, GLuint *params)
+{
+ return GL_GetSamplerParameterIuivEXT(sampler, pname, params);
+}
+
+void GL_APIENTRY glGetTexParameterIivEXT(GLenum target, GLenum pname, GLint *params)
+{
+ return GL_GetTexParameterIivEXT(target, pname, params);
+}
+
+void GL_APIENTRY glGetTexParameterIuivEXT(GLenum target, GLenum pname, GLuint *params)
+{
+ return GL_GetTexParameterIuivEXT(target, pname, params);
+}
+
+void GL_APIENTRY glSamplerParameterIivEXT(GLuint sampler, GLenum pname, const GLint *param)
+{
+ return GL_SamplerParameterIivEXT(sampler, pname, param);
+}
+
+void GL_APIENTRY glSamplerParameterIuivEXT(GLuint sampler, GLenum pname, const GLuint *param)
+{
+ return GL_SamplerParameterIuivEXT(sampler, pname, param);
+}
+
+void GL_APIENTRY glTexParameterIivEXT(GLenum target, GLenum pname, const GLint *params)
+{
+ return GL_TexParameterIivEXT(target, pname, params);
+}
+
+void GL_APIENTRY glTexParameterIuivEXT(GLenum target, GLenum pname, const GLuint *params)
+{
+ return GL_TexParameterIuivEXT(target, pname, params);
+}
+
+// GL_EXT_texture_buffer
+void GL_APIENTRY glTexBufferEXT(GLenum target, GLenum internalformat, GLuint buffer)
+{
+ return GL_TexBufferEXT(target, internalformat, buffer);
+}
+
+void GL_APIENTRY glTexBufferRangeEXT(GLenum target,
+ GLenum internalformat,
+ GLuint buffer,
+ GLintptr offset,
+ GLsizeiptr size)
+{
+ return GL_TexBufferRangeEXT(target, internalformat, buffer, offset, size);
+}
+
+// GL_EXT_texture_compression_bptc
+
+// GL_EXT_texture_compression_dxt1
+
+// GL_EXT_texture_compression_rgtc
+
+// GL_EXT_texture_compression_s3tc
+
+// GL_EXT_texture_compression_s3tc_srgb
+
+// GL_EXT_texture_cube_map_array
+
+// GL_EXT_texture_filter_anisotropic
+
+// GL_EXT_texture_format_BGRA8888
+
+// GL_EXT_texture_format_sRGB_override
+
+// GL_EXT_texture_norm16
+
+// GL_EXT_texture_rg
+
+// GL_EXT_texture_sRGB_R8
+
+// GL_EXT_texture_sRGB_RG8
+
+// GL_EXT_texture_sRGB_decode
+
+// GL_EXT_texture_storage
+void GL_APIENTRY glTexStorage1DEXT(GLenum target,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width)
+{
+ return GL_TexStorage1DEXT(target, levels, internalformat, width);
+}
+
+void GL_APIENTRY glTexStorage2DEXT(GLenum target,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height)
+{
+ return GL_TexStorage2DEXT(target, levels, internalformat, width, height);
+}
+
+void GL_APIENTRY glTexStorage3DEXT(GLenum target,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth)
+{
+ return GL_TexStorage3DEXT(target, levels, internalformat, width, height, depth);
+}
+
+// GL_EXT_texture_type_2_10_10_10_REV
+
+// GL_EXT_unpack_subimage
+
+// GL_IMG_texture_compression_pvrtc
+
+// GL_IMG_texture_compression_pvrtc2
+
+// GL_KHR_blend_equation_advanced
+void GL_APIENTRY glBlendBarrierKHR()
+{
+ return GL_BlendBarrierKHR();
+}
+
+// GL_KHR_debug
+void GL_APIENTRY glDebugMessageCallbackKHR(GLDEBUGPROCKHR callback, const void *userParam)
+{
+ return GL_DebugMessageCallbackKHR(callback, userParam);
+}
+
+void GL_APIENTRY glDebugMessageControlKHR(GLenum source,
+ GLenum type,
+ GLenum severity,
+ GLsizei count,
+ const GLuint *ids,
+ GLboolean enabled)
+{
+ return GL_DebugMessageControlKHR(source, type, severity, count, ids, enabled);
+}
+
+void GL_APIENTRY glDebugMessageInsertKHR(GLenum source,
+ GLenum type,
+ GLuint id,
+ GLenum severity,
+ GLsizei length,
+ const GLchar *buf)
+{
+ return GL_DebugMessageInsertKHR(source, type, id, severity, length, buf);
+}
+
+GLuint GL_APIENTRY glGetDebugMessageLogKHR(GLuint count,
+ GLsizei bufSize,
+ GLenum *sources,
+ GLenum *types,
+ GLuint *ids,
+ GLenum *severities,
+ GLsizei *lengths,
+ GLchar *messageLog)
+{
+ return GL_GetDebugMessageLogKHR(count, bufSize, sources, types, ids, severities, lengths,
+ messageLog);
+}
+
+void GL_APIENTRY
+glGetObjectLabelKHR(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label)
+{
+ return GL_GetObjectLabelKHR(identifier, name, bufSize, length, label);
+}
+
+void GL_APIENTRY glGetObjectPtrLabelKHR(const void *ptr,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *label)
+{
+ return GL_GetObjectPtrLabelKHR(ptr, bufSize, length, label);
+}
+
+void GL_APIENTRY glGetPointervKHR(GLenum pname, void **params)
+{
+ return GL_GetPointervKHR(pname, params);
+}
+
+void GL_APIENTRY glObjectLabelKHR(GLenum identifier,
+ GLuint name,
+ GLsizei length,
+ const GLchar *label)
+{
+ return GL_ObjectLabelKHR(identifier, name, length, label);
+}
+
+void GL_APIENTRY glObjectPtrLabelKHR(const void *ptr, GLsizei length, const GLchar *label)
+{
+ return GL_ObjectPtrLabelKHR(ptr, length, label);
+}
+
+void GL_APIENTRY glPopDebugGroupKHR()
+{
+ return GL_PopDebugGroupKHR();
+}
+
+void GL_APIENTRY glPushDebugGroupKHR(GLenum source,
+ GLuint id,
+ GLsizei length,
+ const GLchar *message)
+{
+ return GL_PushDebugGroupKHR(source, id, length, message);
+}
+
+// GL_KHR_no_error
+
+// GL_KHR_parallel_shader_compile
+void GL_APIENTRY glMaxShaderCompilerThreadsKHR(GLuint count)
+{
+ return GL_MaxShaderCompilerThreadsKHR(count);
+}
+
+// GL_KHR_robust_buffer_access_behavior
+
+// GL_KHR_texture_compression_astc_hdr
+
+// GL_KHR_texture_compression_astc_ldr
+
+// GL_KHR_texture_compression_astc_sliced_3d
+
+// GL_MESA_framebuffer_flip_y
+void GL_APIENTRY glFramebufferParameteriMESA(GLenum target, GLenum pname, GLint param)
+{
+ return GL_FramebufferParameteriMESA(target, pname, param);
+}
+
+void GL_APIENTRY glGetFramebufferParameterivMESA(GLenum target, GLenum pname, GLint *params)
+{
+ return GL_GetFramebufferParameterivMESA(target, pname, params);
+}
+
+// GL_NV_fence
+void GL_APIENTRY glDeleteFencesNV(GLsizei n, const GLuint *fences)
+{
+ return GL_DeleteFencesNV(n, fences);
+}
+
+void GL_APIENTRY glFinishFenceNV(GLuint fence)
+{
+ return GL_FinishFenceNV(fence);
+}
+
+void GL_APIENTRY glGenFencesNV(GLsizei n, GLuint *fences)
+{
+ return GL_GenFencesNV(n, fences);
+}
+
+void GL_APIENTRY glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
+{
+ return GL_GetFenceivNV(fence, pname, params);
+}
+
+GLboolean GL_APIENTRY glIsFenceNV(GLuint fence)
+{
+ return GL_IsFenceNV(fence);
+}
+
+void GL_APIENTRY glSetFenceNV(GLuint fence, GLenum condition)
+{
+ return GL_SetFenceNV(fence, condition);
+}
+
+GLboolean GL_APIENTRY glTestFenceNV(GLuint fence)
+{
+ return GL_TestFenceNV(fence);
+}
+
+// GL_NV_framebuffer_blit
+void GL_APIENTRY glBlitFramebufferNV(GLint srcX0,
+ GLint srcY0,
+ GLint srcX1,
+ GLint srcY1,
+ GLint dstX0,
+ GLint dstY0,
+ GLint dstX1,
+ GLint dstY1,
+ GLbitfield mask,
+ GLenum filter)
+{
+ return GL_BlitFramebufferNV(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask,
+ filter);
+}
+
+// GL_NV_pixel_buffer_object
+
+// GL_NV_read_depth
+
+// GL_NV_read_depth_stencil
+
+// GL_NV_read_stencil
+
+// GL_NV_robustness_video_memory_purge
+
+// GL_NV_shader_noperspective_interpolation
+
+// GL_OES_EGL_image
+void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
+{
+ return GL_EGLImageTargetRenderbufferStorageOES(target, image);
+}
+
+void GL_APIENTRY glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
+{
+ return GL_EGLImageTargetTexture2DOES(target, image);
+}
+
+// GL_OES_EGL_image_external
+
+// GL_OES_EGL_image_external_essl3
+
+// GL_OES_compressed_ETC1_RGB8_texture
+
+// GL_OES_compressed_paletted_texture
+
+// GL_OES_copy_image
+void GL_APIENTRY glCopyImageSubDataOES(GLuint srcName,
+ GLenum srcTarget,
+ GLint srcLevel,
+ GLint srcX,
+ GLint srcY,
+ GLint srcZ,
+ GLuint dstName,
+ GLenum dstTarget,
+ GLint dstLevel,
+ GLint dstX,
+ GLint dstY,
+ GLint dstZ,
+ GLsizei srcWidth,
+ GLsizei srcHeight,
+ GLsizei srcDepth)
+{
+ return GL_CopyImageSubDataOES(srcName, srcTarget, srcLevel, srcX, srcY, srcZ, dstName,
+ dstTarget, dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight,
+ srcDepth);
+}
+
+// GL_OES_depth24
+
+// GL_OES_depth32
+
+// GL_OES_depth_texture
+
+// GL_OES_draw_buffers_indexed
+void GL_APIENTRY glBlendEquationSeparateiOES(GLuint buf, GLenum modeRGB, GLenum modeAlpha)
+{
+ return GL_BlendEquationSeparateiOES(buf, modeRGB, modeAlpha);
+}
+
+void GL_APIENTRY glBlendEquationiOES(GLuint buf, GLenum mode)
+{
+ return GL_BlendEquationiOES(buf, mode);
+}
+
+void GL_APIENTRY
+glBlendFuncSeparateiOES(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+{
+ return GL_BlendFuncSeparateiOES(buf, srcRGB, dstRGB, srcAlpha, dstAlpha);
+}
+
+void GL_APIENTRY glBlendFunciOES(GLuint buf, GLenum src, GLenum dst)
+{
+ return GL_BlendFunciOES(buf, src, dst);
+}
+
+void GL_APIENTRY glColorMaskiOES(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a)
+{
+ return GL_ColorMaskiOES(index, r, g, b, a);
+}
+
+void GL_APIENTRY glDisableiOES(GLenum target, GLuint index)
+{
+ return GL_DisableiOES(target, index);
+}
+
+void GL_APIENTRY glEnableiOES(GLenum target, GLuint index)
+{
+ return GL_EnableiOES(target, index);
+}
+
+GLboolean GL_APIENTRY glIsEnablediOES(GLenum target, GLuint index)
+{
+ return GL_IsEnablediOES(target, index);
+}
+
+// GL_OES_draw_elements_base_vertex
+void GL_APIENTRY glDrawElementsBaseVertexOES(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLint basevertex)
+{
+ return GL_DrawElementsBaseVertexOES(mode, count, type, indices, basevertex);
+}
+
+void GL_APIENTRY glDrawElementsInstancedBaseVertexOES(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLsizei instancecount,
+ GLint basevertex)
+{
+ return GL_DrawElementsInstancedBaseVertexOES(mode, count, type, indices, instancecount,
+ basevertex);
+}
+
+void GL_APIENTRY glDrawRangeElementsBaseVertexOES(GLenum mode,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLint basevertex)
+{
+ return GL_DrawRangeElementsBaseVertexOES(mode, start, end, count, type, indices, basevertex);
+}
+
+// GL_OES_draw_texture
+void GL_APIENTRY glDrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height)
+{
+ return GL_DrawTexfOES(x, y, z, width, height);
+}
+
+void GL_APIENTRY glDrawTexfvOES(const GLfloat *coords)
+{
+ return GL_DrawTexfvOES(coords);
+}
+
+void GL_APIENTRY glDrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height)
+{
+ return GL_DrawTexiOES(x, y, z, width, height);
+}
+
+void GL_APIENTRY glDrawTexivOES(const GLint *coords)
+{
+ return GL_DrawTexivOES(coords);
+}
+
+void GL_APIENTRY glDrawTexsOES(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height)
+{
+ return GL_DrawTexsOES(x, y, z, width, height);
+}
+
+void GL_APIENTRY glDrawTexsvOES(const GLshort *coords)
+{
+ return GL_DrawTexsvOES(coords);
+}
+
+void GL_APIENTRY glDrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height)
+{
+ return GL_DrawTexxOES(x, y, z, width, height);
+}
+
+void GL_APIENTRY glDrawTexxvOES(const GLfixed *coords)
+{
+ return GL_DrawTexxvOES(coords);
+}
+
+// GL_OES_element_index_uint
+
+// GL_OES_fbo_render_mipmap
+
+// GL_OES_framebuffer_object
+void GL_APIENTRY glBindFramebufferOES(GLenum target, GLuint framebuffer)
+{
+ return GL_BindFramebufferOES(target, framebuffer);
+}
+
+void GL_APIENTRY glBindRenderbufferOES(GLenum target, GLuint renderbuffer)
+{
+ return GL_BindRenderbufferOES(target, renderbuffer);
+}
+
+GLenum GL_APIENTRY glCheckFramebufferStatusOES(GLenum target)
+{
+ return GL_CheckFramebufferStatusOES(target);
+}
+
+void GL_APIENTRY glDeleteFramebuffersOES(GLsizei n, const GLuint *framebuffers)
+{
+ return GL_DeleteFramebuffersOES(n, framebuffers);
+}
+
+void GL_APIENTRY glDeleteRenderbuffersOES(GLsizei n, const GLuint *renderbuffers)
+{
+ return GL_DeleteRenderbuffersOES(n, renderbuffers);
+}
+
+void GL_APIENTRY glFramebufferRenderbufferOES(GLenum target,
+ GLenum attachment,
+ GLenum renderbuffertarget,
+ GLuint renderbuffer)
+{
+ return GL_FramebufferRenderbufferOES(target, attachment, renderbuffertarget, renderbuffer);
+}
+
+void GL_APIENTRY glFramebufferTexture2DOES(GLenum target,
+ GLenum attachment,
+ GLenum textarget,
+ GLuint texture,
+ GLint level)
+{
+ return GL_FramebufferTexture2DOES(target, attachment, textarget, texture, level);
+}
+
+void GL_APIENTRY glGenFramebuffersOES(GLsizei n, GLuint *framebuffers)
+{
+ return GL_GenFramebuffersOES(n, framebuffers);
+}
+
+void GL_APIENTRY glGenRenderbuffersOES(GLsizei n, GLuint *renderbuffers)
+{
+ return GL_GenRenderbuffersOES(n, renderbuffers);
+}
+
+void GL_APIENTRY glGenerateMipmapOES(GLenum target)
+{
+ return GL_GenerateMipmapOES(target);
+}
+
+void GL_APIENTRY glGetFramebufferAttachmentParameterivOES(GLenum target,
+ GLenum attachment,
+ GLenum pname,
+ GLint *params)
+{
+ return GL_GetFramebufferAttachmentParameterivOES(target, attachment, pname, params);
+}
+
+void GL_APIENTRY glGetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint *params)
+{
+ return GL_GetRenderbufferParameterivOES(target, pname, params);
+}
+
+GLboolean GL_APIENTRY glIsFramebufferOES(GLuint framebuffer)
+{
+ return GL_IsFramebufferOES(framebuffer);
+}
+
+GLboolean GL_APIENTRY glIsRenderbufferOES(GLuint renderbuffer)
+{
+ return GL_IsRenderbufferOES(renderbuffer);
+}
+
+void GL_APIENTRY glRenderbufferStorageOES(GLenum target,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height)
+{
+ return GL_RenderbufferStorageOES(target, internalformat, width, height);
+}
+
+// GL_OES_geometry_shader
+void GL_APIENTRY glFramebufferTextureOES(GLenum target,
+ GLenum attachment,
+ GLuint texture,
+ GLint level)
+{
+ return GL_FramebufferTextureOES(target, attachment, texture, level);
+}
+
+// GL_OES_get_program_binary
+void GL_APIENTRY glGetProgramBinaryOES(GLuint program,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLenum *binaryFormat,
+ void *binary)
+{
+ return GL_GetProgramBinaryOES(program, bufSize, length, binaryFormat, binary);
+}
+
+void GL_APIENTRY glProgramBinaryOES(GLuint program,
+ GLenum binaryFormat,
+ const void *binary,
+ GLint length)
+{
+ return GL_ProgramBinaryOES(program, binaryFormat, binary, length);
+}
+
+// GL_OES_mapbuffer
+void GL_APIENTRY glGetBufferPointervOES(GLenum target, GLenum pname, void **params)
+{
+ return GL_GetBufferPointervOES(target, pname, params);
+}
+
+void *GL_APIENTRY glMapBufferOES(GLenum target, GLenum access)
+{
+ return GL_MapBufferOES(target, access);
+}
+
+GLboolean GL_APIENTRY glUnmapBufferOES(GLenum target)
+{
+ return GL_UnmapBufferOES(target);
+}
+
+// GL_OES_matrix_palette
+void GL_APIENTRY glCurrentPaletteMatrixOES(GLuint matrixpaletteindex)
+{
+ return GL_CurrentPaletteMatrixOES(matrixpaletteindex);
+}
+
+void GL_APIENTRY glLoadPaletteFromModelViewMatrixOES()
+{
+ return GL_LoadPaletteFromModelViewMatrixOES();
+}
+
+void GL_APIENTRY glMatrixIndexPointerOES(GLint size,
+ GLenum type,
+ GLsizei stride,
+ const void *pointer)
+{
+ return GL_MatrixIndexPointerOES(size, type, stride, pointer);
+}
+
+void GL_APIENTRY glWeightPointerOES(GLint size, GLenum type, GLsizei stride, const void *pointer)
+{
+ return GL_WeightPointerOES(size, type, stride, pointer);
+}
+
+// GL_OES_packed_depth_stencil
+
+// GL_OES_point_size_array
+void GL_APIENTRY glPointSizePointerOES(GLenum type, GLsizei stride, const void *pointer)
+{
+ return GL_PointSizePointerOES(type, stride, pointer);
+}
+
+// GL_OES_point_sprite
+
+// GL_OES_primitive_bounding_box
+void GL_APIENTRY glPrimitiveBoundingBoxOES(GLfloat minX,
+ GLfloat minY,
+ GLfloat minZ,
+ GLfloat minW,
+ GLfloat maxX,
+ GLfloat maxY,
+ GLfloat maxZ,
+ GLfloat maxW)
+{
+ return GL_PrimitiveBoundingBoxOES(minX, minY, minZ, minW, maxX, maxY, maxZ, maxW);
+}
+
+// GL_OES_query_matrix
+GLbitfield GL_APIENTRY glQueryMatrixxOES(GLfixed *mantissa, GLint *exponent)
+{
+ return GL_QueryMatrixxOES(mantissa, exponent);
+}
+
+// GL_OES_rgb8_rgba8
+
+// GL_OES_sample_shading
+void GL_APIENTRY glMinSampleShadingOES(GLfloat value)
+{
+ return GL_MinSampleShadingOES(value);
+}
+
+// GL_OES_sample_variables
+
+// GL_OES_shader_image_atomic
+
+// GL_OES_shader_io_blocks
+
+// GL_OES_shader_multisample_interpolation
+
+// GL_OES_standard_derivatives
+
+// GL_OES_surfaceless_context
+
+// GL_OES_texture_3D
+void GL_APIENTRY glCompressedTexImage3DOES(GLenum target,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLsizei imageSize,
+ const void *data)
+{
+ return GL_CompressedTexImage3DOES(target, level, internalformat, width, height, depth, border,
+ imageSize, data);
+}
+
+void GL_APIENTRY glCompressedTexSubImage3DOES(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data)
+{
+ return GL_CompressedTexSubImage3DOES(target, level, xoffset, yoffset, zoffset, width, height,
+ depth, format, imageSize, data);
+}
+
+void GL_APIENTRY glCopyTexSubImage3DOES(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height)
+{
+ return GL_CopyTexSubImage3DOES(target, level, xoffset, yoffset, zoffset, x, y, width, height);
+}
+
+void GL_APIENTRY glFramebufferTexture3DOES(GLenum target,
+ GLenum attachment,
+ GLenum textarget,
+ GLuint texture,
+ GLint level,
+ GLint zoffset)
+{
+ return GL_FramebufferTexture3DOES(target, attachment, textarget, texture, level, zoffset);
+}
+
+void GL_APIENTRY glTexImage3DOES(GLenum target,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ return GL_TexImage3DOES(target, level, internalformat, width, height, depth, border, format,
+ type, pixels);
+}
+
+void GL_APIENTRY glTexSubImage3DOES(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ return GL_TexSubImage3DOES(target, level, xoffset, yoffset, zoffset, width, height, depth,
+ format, type, pixels);
+}
+
+// GL_OES_texture_border_clamp
+void GL_APIENTRY glGetSamplerParameterIivOES(GLuint sampler, GLenum pname, GLint *params)
+{
+ return GL_GetSamplerParameterIivOES(sampler, pname, params);
+}
+
+void GL_APIENTRY glGetSamplerParameterIuivOES(GLuint sampler, GLenum pname, GLuint *params)
+{
+ return GL_GetSamplerParameterIuivOES(sampler, pname, params);
+}
+
+void GL_APIENTRY glGetTexParameterIivOES(GLenum target, GLenum pname, GLint *params)
+{
+ return GL_GetTexParameterIivOES(target, pname, params);
+}
+
+void GL_APIENTRY glGetTexParameterIuivOES(GLenum target, GLenum pname, GLuint *params)
+{
+ return GL_GetTexParameterIuivOES(target, pname, params);
+}
+
+void GL_APIENTRY glSamplerParameterIivOES(GLuint sampler, GLenum pname, const GLint *param)
+{
+ return GL_SamplerParameterIivOES(sampler, pname, param);
+}
+
+void GL_APIENTRY glSamplerParameterIuivOES(GLuint sampler, GLenum pname, const GLuint *param)
+{
+ return GL_SamplerParameterIuivOES(sampler, pname, param);
+}
+
+void GL_APIENTRY glTexParameterIivOES(GLenum target, GLenum pname, const GLint *params)
+{
+ return GL_TexParameterIivOES(target, pname, params);
+}
+
+void GL_APIENTRY glTexParameterIuivOES(GLenum target, GLenum pname, const GLuint *params)
+{
+ return GL_TexParameterIuivOES(target, pname, params);
+}
+
+// GL_OES_texture_buffer
+void GL_APIENTRY glTexBufferOES(GLenum target, GLenum internalformat, GLuint buffer)
+{
+ return GL_TexBufferOES(target, internalformat, buffer);
+}
+
+void GL_APIENTRY glTexBufferRangeOES(GLenum target,
+ GLenum internalformat,
+ GLuint buffer,
+ GLintptr offset,
+ GLsizeiptr size)
+{
+ return GL_TexBufferRangeOES(target, internalformat, buffer, offset, size);
+}
+
+// GL_OES_texture_compression_astc
+
+// GL_OES_texture_cube_map
+void GL_APIENTRY glGetTexGenfvOES(GLenum coord, GLenum pname, GLfloat *params)
+{
+ return GL_GetTexGenfvOES(coord, pname, params);
+}
+
+void GL_APIENTRY glGetTexGenivOES(GLenum coord, GLenum pname, GLint *params)
+{
+ return GL_GetTexGenivOES(coord, pname, params);
+}
+
+void GL_APIENTRY glGetTexGenxvOES(GLenum coord, GLenum pname, GLfixed *params)
+{
+ return GL_GetTexGenxvOES(coord, pname, params);
+}
+
+void GL_APIENTRY glTexGenfOES(GLenum coord, GLenum pname, GLfloat param)
+{
+ return GL_TexGenfOES(coord, pname, param);
+}
+
+void GL_APIENTRY glTexGenfvOES(GLenum coord, GLenum pname, const GLfloat *params)
+{
+ return GL_TexGenfvOES(coord, pname, params);
+}
+
+void GL_APIENTRY glTexGeniOES(GLenum coord, GLenum pname, GLint param)
+{
+ return GL_TexGeniOES(coord, pname, param);
+}
+
+void GL_APIENTRY glTexGenivOES(GLenum coord, GLenum pname, const GLint *params)
+{
+ return GL_TexGenivOES(coord, pname, params);
+}
+
+void GL_APIENTRY glTexGenxOES(GLenum coord, GLenum pname, GLfixed param)
+{
+ return GL_TexGenxOES(coord, pname, param);
+}
+
+void GL_APIENTRY glTexGenxvOES(GLenum coord, GLenum pname, const GLfixed *params)
+{
+ return GL_TexGenxvOES(coord, pname, params);
+}
+
+// GL_OES_texture_cube_map_array
+
+// GL_OES_texture_float
+
+// GL_OES_texture_float_linear
+
+// GL_OES_texture_half_float
+
+// GL_OES_texture_half_float_linear
+
+// GL_OES_texture_npot
+
+// GL_OES_texture_stencil8
+
+// GL_OES_texture_storage_multisample_2d_array
+void GL_APIENTRY glTexStorage3DMultisampleOES(GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean fixedsamplelocations)
+{
+ return GL_TexStorage3DMultisampleOES(target, samples, internalformat, width, height, depth,
+ fixedsamplelocations);
+}
+
+// GL_OES_vertex_array_object
+void GL_APIENTRY glBindVertexArrayOES(GLuint array)
+{
+ return GL_BindVertexArrayOES(array);
+}
+
+void GL_APIENTRY glDeleteVertexArraysOES(GLsizei n, const GLuint *arrays)
+{
+ return GL_DeleteVertexArraysOES(n, arrays);
+}
+
+void GL_APIENTRY glGenVertexArraysOES(GLsizei n, GLuint *arrays)
+{
+ return GL_GenVertexArraysOES(n, arrays);
+}
+
+GLboolean GL_APIENTRY glIsVertexArrayOES(GLuint array)
+{
+ return GL_IsVertexArrayOES(array);
+}
+
+// GL_OES_vertex_half_float
+
+// GL_OES_vertex_type_10_10_10_2
+
+// GL_OVR_multiview
+void GL_APIENTRY glFramebufferTextureMultiviewOVR(GLenum target,
+ GLenum attachment,
+ GLuint texture,
+ GLint level,
+ GLint baseViewIndex,
+ GLsizei numViews)
+{
+ return GL_FramebufferTextureMultiviewOVR(target, attachment, texture, level, baseViewIndex,
+ numViews);
+}
+
+// GL_OVR_multiview2
+
+// GL_QCOM_shading_rate
+void GL_APIENTRY glShadingRateQCOM(GLenum rate)
+{
+ return GL_ShadingRateQCOM(rate);
+}
+
+#if defined(ANGLE_ENABLE_GL_DESKTOP_FRONTEND)
+
+// GL 1.0
+void GL_APIENTRY glAccum(GLenum op, GLfloat value)
+{
+ return GL_Accum(op, value);
+}
+
+void GL_APIENTRY glBegin(GLenum mode)
+{
+ return GL_Begin(mode);
+}
+
+void GL_APIENTRY glBitmap(GLsizei width,
+ GLsizei height,
+ GLfloat xorig,
+ GLfloat yorig,
+ GLfloat xmove,
+ GLfloat ymove,
+ const GLubyte *bitmap)
+{
+ return GL_Bitmap(width, height, xorig, yorig, xmove, ymove, bitmap);
+}
+
+void GL_APIENTRY glCallList(GLuint list)
+{
+ return GL_CallList(list);
+}
+
+void GL_APIENTRY glCallLists(GLsizei n, GLenum type, const void *lists)
+{
+ return GL_CallLists(n, type, lists);
+}
+
+void GL_APIENTRY glClearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+ return GL_ClearAccum(red, green, blue, alpha);
+}
+
+void GL_APIENTRY glClearDepth(GLdouble depth)
+{
+ return GL_ClearDepth(depth);
+}
+
+void GL_APIENTRY glClearIndex(GLfloat c)
+{
+ return GL_ClearIndex(c);
+}
+
+void GL_APIENTRY glClipPlane(GLenum plane, const GLdouble *equation)
+{
+ return GL_ClipPlane(plane, equation);
+}
+
+void GL_APIENTRY glColor3b(GLbyte red, GLbyte green, GLbyte blue)
+{
+ return GL_Color3b(red, green, blue);
+}
+
+void GL_APIENTRY glColor3bv(const GLbyte *v)
+{
+ return GL_Color3bv(v);
+}
+
+void GL_APIENTRY glColor3d(GLdouble red, GLdouble green, GLdouble blue)
+{
+ return GL_Color3d(red, green, blue);
+}
+
+void GL_APIENTRY glColor3dv(const GLdouble *v)
+{
+ return GL_Color3dv(v);
+}
+
+void GL_APIENTRY glColor3f(GLfloat red, GLfloat green, GLfloat blue)
+{
+ return GL_Color3f(red, green, blue);
+}
+
+void GL_APIENTRY glColor3fv(const GLfloat *v)
+{
+ return GL_Color3fv(v);
+}
+
+void GL_APIENTRY glColor3i(GLint red, GLint green, GLint blue)
+{
+ return GL_Color3i(red, green, blue);
+}
+
+void GL_APIENTRY glColor3iv(const GLint *v)
+{
+ return GL_Color3iv(v);
+}
+
+void GL_APIENTRY glColor3s(GLshort red, GLshort green, GLshort blue)
+{
+ return GL_Color3s(red, green, blue);
+}
+
+void GL_APIENTRY glColor3sv(const GLshort *v)
+{
+ return GL_Color3sv(v);
+}
+
+void GL_APIENTRY glColor3ub(GLubyte red, GLubyte green, GLubyte blue)
+{
+ return GL_Color3ub(red, green, blue);
+}
+
+void GL_APIENTRY glColor3ubv(const GLubyte *v)
+{
+ return GL_Color3ubv(v);
+}
+
+void GL_APIENTRY glColor3ui(GLuint red, GLuint green, GLuint blue)
+{
+ return GL_Color3ui(red, green, blue);
+}
+
+void GL_APIENTRY glColor3uiv(const GLuint *v)
+{
+ return GL_Color3uiv(v);
+}
+
+void GL_APIENTRY glColor3us(GLushort red, GLushort green, GLushort blue)
+{
+ return GL_Color3us(red, green, blue);
+}
+
+void GL_APIENTRY glColor3usv(const GLushort *v)
+{
+ return GL_Color3usv(v);
+}
+
+void GL_APIENTRY glColor4b(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha)
+{
+ return GL_Color4b(red, green, blue, alpha);
+}
+
+void GL_APIENTRY glColor4bv(const GLbyte *v)
+{
+ return GL_Color4bv(v);
+}
+
+void GL_APIENTRY glColor4d(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha)
+{
+ return GL_Color4d(red, green, blue, alpha);
+}
+
+void GL_APIENTRY glColor4dv(const GLdouble *v)
+{
+ return GL_Color4dv(v);
+}
+
+void GL_APIENTRY glColor4fv(const GLfloat *v)
+{
+ return GL_Color4fv(v);
+}
+
+void GL_APIENTRY glColor4i(GLint red, GLint green, GLint blue, GLint alpha)
+{
+ return GL_Color4i(red, green, blue, alpha);
+}
+
+void GL_APIENTRY glColor4iv(const GLint *v)
+{
+ return GL_Color4iv(v);
+}
+
+void GL_APIENTRY glColor4s(GLshort red, GLshort green, GLshort blue, GLshort alpha)
+{
+ return GL_Color4s(red, green, blue, alpha);
+}
+
+void GL_APIENTRY glColor4sv(const GLshort *v)
+{
+ return GL_Color4sv(v);
+}
+
+void GL_APIENTRY glColor4ubv(const GLubyte *v)
+{
+ return GL_Color4ubv(v);
+}
+
+void GL_APIENTRY glColor4ui(GLuint red, GLuint green, GLuint blue, GLuint alpha)
+{
+ return GL_Color4ui(red, green, blue, alpha);
+}
+
+void GL_APIENTRY glColor4uiv(const GLuint *v)
+{
+ return GL_Color4uiv(v);
+}
+
+void GL_APIENTRY glColor4us(GLushort red, GLushort green, GLushort blue, GLushort alpha)
+{
+ return GL_Color4us(red, green, blue, alpha);
+}
+
+void GL_APIENTRY glColor4usv(const GLushort *v)
+{
+ return GL_Color4usv(v);
+}
+
+void GL_APIENTRY glColorMaterial(GLenum face, GLenum mode)
+{
+ return GL_ColorMaterial(face, mode);
+}
+
+void GL_APIENTRY glCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type)
+{
+ return GL_CopyPixels(x, y, width, height, type);
+}
+
+void GL_APIENTRY glDeleteLists(GLuint list, GLsizei range)
+{
+ return GL_DeleteLists(list, range);
+}
+
+void GL_APIENTRY glDepthRange(GLdouble n, GLdouble f)
+{
+ return GL_DepthRange(n, f);
+}
+
+void GL_APIENTRY glDrawBuffer(GLenum buf)
+{
+ return GL_DrawBuffer(buf);
+}
+
+void GL_APIENTRY
+glDrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels)
+{
+ return GL_DrawPixels(width, height, format, type, pixels);
+}
+
+void GL_APIENTRY glEdgeFlag(GLboolean flag)
+{
+ return GL_EdgeFlag(flag);
+}
+
+void GL_APIENTRY glEdgeFlagv(const GLboolean *flag)
+{
+ return GL_EdgeFlagv(flag);
+}
+
+void GL_APIENTRY glEnd()
+{
+ return GL_End();
+}
+
+void GL_APIENTRY glEndList()
+{
+ return GL_EndList();
+}
+
+void GL_APIENTRY glEvalCoord1d(GLdouble u)
+{
+ return GL_EvalCoord1d(u);
+}
+
+void GL_APIENTRY glEvalCoord1dv(const GLdouble *u)
+{
+ return GL_EvalCoord1dv(u);
+}
+
+void GL_APIENTRY glEvalCoord1f(GLfloat u)
+{
+ return GL_EvalCoord1f(u);
+}
+
+void GL_APIENTRY glEvalCoord1fv(const GLfloat *u)
+{
+ return GL_EvalCoord1fv(u);
+}
+
+void GL_APIENTRY glEvalCoord2d(GLdouble u, GLdouble v)
+{
+ return GL_EvalCoord2d(u, v);
+}
+
+void GL_APIENTRY glEvalCoord2dv(const GLdouble *u)
+{
+ return GL_EvalCoord2dv(u);
+}
+
+void GL_APIENTRY glEvalCoord2f(GLfloat u, GLfloat v)
+{
+ return GL_EvalCoord2f(u, v);
+}
+
+void GL_APIENTRY glEvalCoord2fv(const GLfloat *u)
+{
+ return GL_EvalCoord2fv(u);
+}
+
+void GL_APIENTRY glEvalMesh1(GLenum mode, GLint i1, GLint i2)
+{
+ return GL_EvalMesh1(mode, i1, i2);
+}
+
+void GL_APIENTRY glEvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2)
+{
+ return GL_EvalMesh2(mode, i1, i2, j1, j2);
+}
+
+void GL_APIENTRY glEvalPoint1(GLint i)
+{
+ return GL_EvalPoint1(i);
+}
+
+void GL_APIENTRY glEvalPoint2(GLint i, GLint j)
+{
+ return GL_EvalPoint2(i, j);
+}
+
+void GL_APIENTRY glFeedbackBuffer(GLsizei size, GLenum type, GLfloat *buffer)
+{
+ return GL_FeedbackBuffer(size, type, buffer);
+}
+
+void GL_APIENTRY glFogi(GLenum pname, GLint param)
+{
+ return GL_Fogi(pname, param);
+}
+
+void GL_APIENTRY glFogiv(GLenum pname, const GLint *params)
+{
+ return GL_Fogiv(pname, params);
+}
+
+void GL_APIENTRY glFrustum(GLdouble left,
+ GLdouble right,
+ GLdouble bottom,
+ GLdouble top,
+ GLdouble zNear,
+ GLdouble zFar)
+{
+ return GL_Frustum(left, right, bottom, top, zNear, zFar);
+}
+
+GLuint GL_APIENTRY glGenLists(GLsizei range)
+{
+ return GL_GenLists(range);
+}
+
+void GL_APIENTRY glGetClipPlane(GLenum plane, GLdouble *equation)
+{
+ return GL_GetClipPlane(plane, equation);
+}
+
+void GL_APIENTRY glGetDoublev(GLenum pname, GLdouble *data)
+{
+ return GL_GetDoublev(pname, data);
+}
+
+void GL_APIENTRY glGetLightiv(GLenum light, GLenum pname, GLint *params)
+{
+ return GL_GetLightiv(light, pname, params);
+}
+
+void GL_APIENTRY glGetMapdv(GLenum target, GLenum query, GLdouble *v)
+{
+ return GL_GetMapdv(target, query, v);
+}
+
+void GL_APIENTRY glGetMapfv(GLenum target, GLenum query, GLfloat *v)
+{
+ return GL_GetMapfv(target, query, v);
+}
+
+void GL_APIENTRY glGetMapiv(GLenum target, GLenum query, GLint *v)
+{
+ return GL_GetMapiv(target, query, v);
+}
+
+void GL_APIENTRY glGetMaterialiv(GLenum face, GLenum pname, GLint *params)
+{
+ return GL_GetMaterialiv(face, pname, params);
+}
+
+void GL_APIENTRY glGetPixelMapfv(GLenum map, GLfloat *values)
+{
+ return GL_GetPixelMapfv(map, values);
+}
+
+void GL_APIENTRY glGetPixelMapuiv(GLenum map, GLuint *values)
+{
+ return GL_GetPixelMapuiv(map, values);
+}
+
+void GL_APIENTRY glGetPixelMapusv(GLenum map, GLushort *values)
+{
+ return GL_GetPixelMapusv(map, values);
+}
+
+void GL_APIENTRY glGetPolygonStipple(GLubyte *mask)
+{
+ return GL_GetPolygonStipple(mask);
+}
+
+void GL_APIENTRY glGetTexGendv(GLenum coord, GLenum pname, GLdouble *params)
+{
+ return GL_GetTexGendv(coord, pname, params);
+}
+
+void GL_APIENTRY glGetTexGenfv(GLenum coord, GLenum pname, GLfloat *params)
+{
+ return GL_GetTexGenfv(coord, pname, params);
+}
+
+void GL_APIENTRY glGetTexGeniv(GLenum coord, GLenum pname, GLint *params)
+{
+ return GL_GetTexGeniv(coord, pname, params);
+}
+
+void GL_APIENTRY glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, void *pixels)
+{
+ return GL_GetTexImage(target, level, format, type, pixels);
+}
+
+void GL_APIENTRY glIndexMask(GLuint mask)
+{
+ return GL_IndexMask(mask);
+}
+
+void GL_APIENTRY glIndexd(GLdouble c)
+{
+ return GL_Indexd(c);
+}
+
+void GL_APIENTRY glIndexdv(const GLdouble *c)
+{
+ return GL_Indexdv(c);
+}
+
+void GL_APIENTRY glIndexf(GLfloat c)
+{
+ return GL_Indexf(c);
+}
+
+void GL_APIENTRY glIndexfv(const GLfloat *c)
+{
+ return GL_Indexfv(c);
+}
+
+void GL_APIENTRY glIndexi(GLint c)
+{
+ return GL_Indexi(c);
+}
+
+void GL_APIENTRY glIndexiv(const GLint *c)
+{
+ return GL_Indexiv(c);
+}
+
+void GL_APIENTRY glIndexs(GLshort c)
+{
+ return GL_Indexs(c);
+}
+
+void GL_APIENTRY glIndexsv(const GLshort *c)
+{
+ return GL_Indexsv(c);
+}
+
+void GL_APIENTRY glInitNames()
+{
+ return GL_InitNames();
+}
+
+GLboolean GL_APIENTRY glIsList(GLuint list)
+{
+ return GL_IsList(list);
+}
+
+void GL_APIENTRY glLightModeli(GLenum pname, GLint param)
+{
+ return GL_LightModeli(pname, param);
+}
+
+void GL_APIENTRY glLightModeliv(GLenum pname, const GLint *params)
+{
+ return GL_LightModeliv(pname, params);
+}
+
+void GL_APIENTRY glLighti(GLenum light, GLenum pname, GLint param)
+{
+ return GL_Lighti(light, pname, param);
+}
+
+void GL_APIENTRY glLightiv(GLenum light, GLenum pname, const GLint *params)
+{
+ return GL_Lightiv(light, pname, params);
+}
+
+void GL_APIENTRY glLineStipple(GLint factor, GLushort pattern)
+{
+ return GL_LineStipple(factor, pattern);
+}
+
+void GL_APIENTRY glListBase(GLuint base)
+{
+ return GL_ListBase(base);
+}
+
+void GL_APIENTRY glLoadMatrixd(const GLdouble *m)
+{
+ return GL_LoadMatrixd(m);
+}
+
+void GL_APIENTRY glLoadName(GLuint name)
+{
+ return GL_LoadName(name);
+}
+
+void GL_APIENTRY
+glMap1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points)
+{
+ return GL_Map1d(target, u1, u2, stride, order, points);
+}
+
+void GL_APIENTRY
+glMap1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points)
+{
+ return GL_Map1f(target, u1, u2, stride, order, points);
+}
+
+void GL_APIENTRY glMap2d(GLenum target,
+ GLdouble u1,
+ GLdouble u2,
+ GLint ustride,
+ GLint uorder,
+ GLdouble v1,
+ GLdouble v2,
+ GLint vstride,
+ GLint vorder,
+ const GLdouble *points)
+{
+ return GL_Map2d(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points);
+}
+
+void GL_APIENTRY glMap2f(GLenum target,
+ GLfloat u1,
+ GLfloat u2,
+ GLint ustride,
+ GLint uorder,
+ GLfloat v1,
+ GLfloat v2,
+ GLint vstride,
+ GLint vorder,
+ const GLfloat *points)
+{
+ return GL_Map2f(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points);
+}
+
+void GL_APIENTRY glMapGrid1d(GLint un, GLdouble u1, GLdouble u2)
+{
+ return GL_MapGrid1d(un, u1, u2);
+}
+
+void GL_APIENTRY glMapGrid1f(GLint un, GLfloat u1, GLfloat u2)
+{
+ return GL_MapGrid1f(un, u1, u2);
+}
+
+void GL_APIENTRY glMapGrid2d(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2)
+{
+ return GL_MapGrid2d(un, u1, u2, vn, v1, v2);
+}
+
+void GL_APIENTRY glMapGrid2f(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2)
+{
+ return GL_MapGrid2f(un, u1, u2, vn, v1, v2);
+}
+
+void GL_APIENTRY glMateriali(GLenum face, GLenum pname, GLint param)
+{
+ return GL_Materiali(face, pname, param);
+}
+
+void GL_APIENTRY glMaterialiv(GLenum face, GLenum pname, const GLint *params)
+{
+ return GL_Materialiv(face, pname, params);
+}
+
+void GL_APIENTRY glMultMatrixd(const GLdouble *m)
+{
+ return GL_MultMatrixd(m);
+}
+
+void GL_APIENTRY glNewList(GLuint list, GLenum mode)
+{
+ return GL_NewList(list, mode);
+}
+
+void GL_APIENTRY glNormal3b(GLbyte nx, GLbyte ny, GLbyte nz)
+{
+ return GL_Normal3b(nx, ny, nz);
+}
+
+void GL_APIENTRY glNormal3bv(const GLbyte *v)
+{
+ return GL_Normal3bv(v);
+}
+
+void GL_APIENTRY glNormal3d(GLdouble nx, GLdouble ny, GLdouble nz)
+{
+ return GL_Normal3d(nx, ny, nz);
+}
+
+void GL_APIENTRY glNormal3dv(const GLdouble *v)
+{
+ return GL_Normal3dv(v);
+}
+
+void GL_APIENTRY glNormal3fv(const GLfloat *v)
+{
+ return GL_Normal3fv(v);
+}
+
+void GL_APIENTRY glNormal3i(GLint nx, GLint ny, GLint nz)
+{
+ return GL_Normal3i(nx, ny, nz);
+}
+
+void GL_APIENTRY glNormal3iv(const GLint *v)
+{
+ return GL_Normal3iv(v);
+}
+
+void GL_APIENTRY glNormal3s(GLshort nx, GLshort ny, GLshort nz)
+{
+ return GL_Normal3s(nx, ny, nz);
+}
+
+void GL_APIENTRY glNormal3sv(const GLshort *v)
+{
+ return GL_Normal3sv(v);
+}
+
+void GL_APIENTRY
+glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
+{
+ return GL_Ortho(left, right, bottom, top, zNear, zFar);
+}
+
+void GL_APIENTRY glPassThrough(GLfloat token)
+{
+ return GL_PassThrough(token);
+}
+
+void GL_APIENTRY glPixelMapfv(GLenum map, GLsizei mapsize, const GLfloat *values)
+{
+ return GL_PixelMapfv(map, mapsize, values);
+}
+
+void GL_APIENTRY glPixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values)
+{
+ return GL_PixelMapuiv(map, mapsize, values);
+}
+
+void GL_APIENTRY glPixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values)
+{
+ return GL_PixelMapusv(map, mapsize, values);
+}
+
+void GL_APIENTRY glPixelStoref(GLenum pname, GLfloat param)
+{
+ return GL_PixelStoref(pname, param);
+}
+
+void GL_APIENTRY glPixelTransferf(GLenum pname, GLfloat param)
+{
+ return GL_PixelTransferf(pname, param);
+}
+
+void GL_APIENTRY glPixelTransferi(GLenum pname, GLint param)
+{
+ return GL_PixelTransferi(pname, param);
+}
+
+void GL_APIENTRY glPixelZoom(GLfloat xfactor, GLfloat yfactor)
+{
+ return GL_PixelZoom(xfactor, yfactor);
+}
+
+void GL_APIENTRY glPolygonMode(GLenum face, GLenum mode)
+{
+ return GL_PolygonMode(face, mode);
+}
+
+void GL_APIENTRY glPolygonStipple(const GLubyte *mask)
+{
+ return GL_PolygonStipple(mask);
+}
+
+void GL_APIENTRY glPopAttrib()
+{
+ return GL_PopAttrib();
+}
+
+void GL_APIENTRY glPopName()
+{
+ return GL_PopName();
+}
+
+void GL_APIENTRY glPushAttrib(GLbitfield mask)
+{
+ return GL_PushAttrib(mask);
+}
+
+void GL_APIENTRY glPushName(GLuint name)
+{
+ return GL_PushName(name);
+}
+
+void GL_APIENTRY glRasterPos2d(GLdouble x, GLdouble y)
+{
+ return GL_RasterPos2d(x, y);
+}
+
+void GL_APIENTRY glRasterPos2dv(const GLdouble *v)
+{
+ return GL_RasterPos2dv(v);
+}
+
+void GL_APIENTRY glRasterPos2f(GLfloat x, GLfloat y)
+{
+ return GL_RasterPos2f(x, y);
+}
+
+void GL_APIENTRY glRasterPos2fv(const GLfloat *v)
+{
+ return GL_RasterPos2fv(v);
+}
+
+void GL_APIENTRY glRasterPos2i(GLint x, GLint y)
+{
+ return GL_RasterPos2i(x, y);
+}
+
+void GL_APIENTRY glRasterPos2iv(const GLint *v)
+{
+ return GL_RasterPos2iv(v);
+}
+
+void GL_APIENTRY glRasterPos2s(GLshort x, GLshort y)
+{
+ return GL_RasterPos2s(x, y);
+}
+
+void GL_APIENTRY glRasterPos2sv(const GLshort *v)
+{
+ return GL_RasterPos2sv(v);
+}
+
+void GL_APIENTRY glRasterPos3d(GLdouble x, GLdouble y, GLdouble z)
+{
+ return GL_RasterPos3d(x, y, z);
+}
+
+void GL_APIENTRY glRasterPos3dv(const GLdouble *v)
+{
+ return GL_RasterPos3dv(v);
+}
+
+void GL_APIENTRY glRasterPos3f(GLfloat x, GLfloat y, GLfloat z)
+{
+ return GL_RasterPos3f(x, y, z);
+}
+
+void GL_APIENTRY glRasterPos3fv(const GLfloat *v)
+{
+ return GL_RasterPos3fv(v);
+}
+
+void GL_APIENTRY glRasterPos3i(GLint x, GLint y, GLint z)
+{
+ return GL_RasterPos3i(x, y, z);
+}
+
+void GL_APIENTRY glRasterPos3iv(const GLint *v)
+{
+ return GL_RasterPos3iv(v);
+}
+
+void GL_APIENTRY glRasterPos3s(GLshort x, GLshort y, GLshort z)
+{
+ return GL_RasterPos3s(x, y, z);
+}
+
+void GL_APIENTRY glRasterPos3sv(const GLshort *v)
+{
+ return GL_RasterPos3sv(v);
+}
+
+void GL_APIENTRY glRasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
+{
+ return GL_RasterPos4d(x, y, z, w);
+}
+
+void GL_APIENTRY glRasterPos4dv(const GLdouble *v)
+{
+ return GL_RasterPos4dv(v);
+}
+
+void GL_APIENTRY glRasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ return GL_RasterPos4f(x, y, z, w);
+}
+
+void GL_APIENTRY glRasterPos4fv(const GLfloat *v)
+{
+ return GL_RasterPos4fv(v);
+}
+
+void GL_APIENTRY glRasterPos4i(GLint x, GLint y, GLint z, GLint w)
+{
+ return GL_RasterPos4i(x, y, z, w);
+}
+
+void GL_APIENTRY glRasterPos4iv(const GLint *v)
+{
+ return GL_RasterPos4iv(v);
+}
+
+void GL_APIENTRY glRasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w)
+{
+ return GL_RasterPos4s(x, y, z, w);
+}
+
+void GL_APIENTRY glRasterPos4sv(const GLshort *v)
+{
+ return GL_RasterPos4sv(v);
+}
+
+void GL_APIENTRY glRectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2)
+{
+ return GL_Rectd(x1, y1, x2, y2);
+}
+
+void GL_APIENTRY glRectdv(const GLdouble *v1, const GLdouble *v2)
+{
+ return GL_Rectdv(v1, v2);
+}
+
+void GL_APIENTRY glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
+{
+ return GL_Rectf(x1, y1, x2, y2);
+}
+
+void GL_APIENTRY glRectfv(const GLfloat *v1, const GLfloat *v2)
+{
+ return GL_Rectfv(v1, v2);
+}
+
+void GL_APIENTRY glRecti(GLint x1, GLint y1, GLint x2, GLint y2)
+{
+ return GL_Recti(x1, y1, x2, y2);
+}
+
+void GL_APIENTRY glRectiv(const GLint *v1, const GLint *v2)
+{
+ return GL_Rectiv(v1, v2);
+}
+
+void GL_APIENTRY glRects(GLshort x1, GLshort y1, GLshort x2, GLshort y2)
+{
+ return GL_Rects(x1, y1, x2, y2);
+}
+
+void GL_APIENTRY glRectsv(const GLshort *v1, const GLshort *v2)
+{
+ return GL_Rectsv(v1, v2);
+}
+
+GLint GL_APIENTRY glRenderMode(GLenum mode)
+{
+ return GL_RenderMode(mode);
+}
+
+void GL_APIENTRY glRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z)
+{
+ return GL_Rotated(angle, x, y, z);
+}
+
+void GL_APIENTRY glScaled(GLdouble x, GLdouble y, GLdouble z)
+{
+ return GL_Scaled(x, y, z);
+}
+
+void GL_APIENTRY glSelectBuffer(GLsizei size, GLuint *buffer)
+{
+ return GL_SelectBuffer(size, buffer);
+}
+
+void GL_APIENTRY glTexCoord1d(GLdouble s)
+{
+ return GL_TexCoord1d(s);
+}
+
+void GL_APIENTRY glTexCoord1dv(const GLdouble *v)
+{
+ return GL_TexCoord1dv(v);
+}
+
+void GL_APIENTRY glTexCoord1f(GLfloat s)
+{
+ return GL_TexCoord1f(s);
+}
+
+void GL_APIENTRY glTexCoord1fv(const GLfloat *v)
+{
+ return GL_TexCoord1fv(v);
+}
+
+void GL_APIENTRY glTexCoord1i(GLint s)
+{
+ return GL_TexCoord1i(s);
+}
+
+void GL_APIENTRY glTexCoord1iv(const GLint *v)
+{
+ return GL_TexCoord1iv(v);
+}
+
+void GL_APIENTRY glTexCoord1s(GLshort s)
+{
+ return GL_TexCoord1s(s);
+}
+
+void GL_APIENTRY glTexCoord1sv(const GLshort *v)
+{
+ return GL_TexCoord1sv(v);
+}
+
+void GL_APIENTRY glTexCoord2d(GLdouble s, GLdouble t)
+{
+ return GL_TexCoord2d(s, t);
+}
+
+void GL_APIENTRY glTexCoord2dv(const GLdouble *v)
+{
+ return GL_TexCoord2dv(v);
+}
+
+void GL_APIENTRY glTexCoord2f(GLfloat s, GLfloat t)
+{
+ return GL_TexCoord2f(s, t);
+}
+
+void GL_APIENTRY glTexCoord2fv(const GLfloat *v)
+{
+ return GL_TexCoord2fv(v);
+}
+
+void GL_APIENTRY glTexCoord2i(GLint s, GLint t)
+{
+ return GL_TexCoord2i(s, t);
+}
+
+void GL_APIENTRY glTexCoord2iv(const GLint *v)
+{
+ return GL_TexCoord2iv(v);
+}
+
+void GL_APIENTRY glTexCoord2s(GLshort s, GLshort t)
+{
+ return GL_TexCoord2s(s, t);
+}
+
+void GL_APIENTRY glTexCoord2sv(const GLshort *v)
+{
+ return GL_TexCoord2sv(v);
+}
+
+void GL_APIENTRY glTexCoord3d(GLdouble s, GLdouble t, GLdouble r)
+{
+ return GL_TexCoord3d(s, t, r);
+}
+
+void GL_APIENTRY glTexCoord3dv(const GLdouble *v)
+{
+ return GL_TexCoord3dv(v);
+}
+
+void GL_APIENTRY glTexCoord3f(GLfloat s, GLfloat t, GLfloat r)
+{
+ return GL_TexCoord3f(s, t, r);
+}
+
+void GL_APIENTRY glTexCoord3fv(const GLfloat *v)
+{
+ return GL_TexCoord3fv(v);
+}
+
+void GL_APIENTRY glTexCoord3i(GLint s, GLint t, GLint r)
+{
+ return GL_TexCoord3i(s, t, r);
+}
+
+void GL_APIENTRY glTexCoord3iv(const GLint *v)
+{
+ return GL_TexCoord3iv(v);
+}
+
+void GL_APIENTRY glTexCoord3s(GLshort s, GLshort t, GLshort r)
+{
+ return GL_TexCoord3s(s, t, r);
+}
+
+void GL_APIENTRY glTexCoord3sv(const GLshort *v)
+{
+ return GL_TexCoord3sv(v);
+}
+
+void GL_APIENTRY glTexCoord4d(GLdouble s, GLdouble t, GLdouble r, GLdouble q)
+{
+ return GL_TexCoord4d(s, t, r, q);
+}
+
+void GL_APIENTRY glTexCoord4dv(const GLdouble *v)
+{
+ return GL_TexCoord4dv(v);
+}
+
+void GL_APIENTRY glTexCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q)
+{
+ return GL_TexCoord4f(s, t, r, q);
+}
+
+void GL_APIENTRY glTexCoord4fv(const GLfloat *v)
+{
+ return GL_TexCoord4fv(v);
+}
+
+void GL_APIENTRY glTexCoord4i(GLint s, GLint t, GLint r, GLint q)
+{
+ return GL_TexCoord4i(s, t, r, q);
+}
+
+void GL_APIENTRY glTexCoord4iv(const GLint *v)
+{
+ return GL_TexCoord4iv(v);
+}
+
+void GL_APIENTRY glTexCoord4s(GLshort s, GLshort t, GLshort r, GLshort q)
+{
+ return GL_TexCoord4s(s, t, r, q);
+}
+
+void GL_APIENTRY glTexCoord4sv(const GLshort *v)
+{
+ return GL_TexCoord4sv(v);
+}
+
+void GL_APIENTRY glTexGend(GLenum coord, GLenum pname, GLdouble param)
+{
+ return GL_TexGend(coord, pname, param);
+}
+
+void GL_APIENTRY glTexGendv(GLenum coord, GLenum pname, const GLdouble *params)
+{
+ return GL_TexGendv(coord, pname, params);
+}
+
+void GL_APIENTRY glTexGenf(GLenum coord, GLenum pname, GLfloat param)
+{
+ return GL_TexGenf(coord, pname, param);
+}
+
+void GL_APIENTRY glTexGenfv(GLenum coord, GLenum pname, const GLfloat *params)
+{
+ return GL_TexGenfv(coord, pname, params);
+}
+
+void GL_APIENTRY glTexGeni(GLenum coord, GLenum pname, GLint param)
+{
+ return GL_TexGeni(coord, pname, param);
+}
+
+void GL_APIENTRY glTexGeniv(GLenum coord, GLenum pname, const GLint *params)
+{
+ return GL_TexGeniv(coord, pname, params);
+}
+
+void GL_APIENTRY glTexImage1D(GLenum target,
+ GLint level,
+ GLint internalformat,
+ GLsizei width,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ return GL_TexImage1D(target, level, internalformat, width, border, format, type, pixels);
+}
+
+void GL_APIENTRY glTranslated(GLdouble x, GLdouble y, GLdouble z)
+{
+ return GL_Translated(x, y, z);
+}
+
+void GL_APIENTRY glVertex2d(GLdouble x, GLdouble y)
+{
+ return GL_Vertex2d(x, y);
+}
+
+void GL_APIENTRY glVertex2dv(const GLdouble *v)
+{
+ return GL_Vertex2dv(v);
+}
+
+void GL_APIENTRY glVertex2f(GLfloat x, GLfloat y)
+{
+ return GL_Vertex2f(x, y);
+}
+
+void GL_APIENTRY glVertex2fv(const GLfloat *v)
+{
+ return GL_Vertex2fv(v);
+}
+
+void GL_APIENTRY glVertex2i(GLint x, GLint y)
+{
+ return GL_Vertex2i(x, y);
+}
+
+void GL_APIENTRY glVertex2iv(const GLint *v)
+{
+ return GL_Vertex2iv(v);
+}
+
+void GL_APIENTRY glVertex2s(GLshort x, GLshort y)
+{
+ return GL_Vertex2s(x, y);
+}
+
+void GL_APIENTRY glVertex2sv(const GLshort *v)
+{
+ return GL_Vertex2sv(v);
+}
+
+void GL_APIENTRY glVertex3d(GLdouble x, GLdouble y, GLdouble z)
+{
+ return GL_Vertex3d(x, y, z);
+}
+
+void GL_APIENTRY glVertex3dv(const GLdouble *v)
+{
+ return GL_Vertex3dv(v);
+}
+
+void GL_APIENTRY glVertex3f(GLfloat x, GLfloat y, GLfloat z)
+{
+ return GL_Vertex3f(x, y, z);
+}
+
+void GL_APIENTRY glVertex3fv(const GLfloat *v)
+{
+ return GL_Vertex3fv(v);
+}
+
+void GL_APIENTRY glVertex3i(GLint x, GLint y, GLint z)
+{
+ return GL_Vertex3i(x, y, z);
+}
+
+void GL_APIENTRY glVertex3iv(const GLint *v)
+{
+ return GL_Vertex3iv(v);
+}
+
+void GL_APIENTRY glVertex3s(GLshort x, GLshort y, GLshort z)
+{
+ return GL_Vertex3s(x, y, z);
+}
+
+void GL_APIENTRY glVertex3sv(const GLshort *v)
+{
+ return GL_Vertex3sv(v);
+}
+
+void GL_APIENTRY glVertex4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
+{
+ return GL_Vertex4d(x, y, z, w);
+}
+
+void GL_APIENTRY glVertex4dv(const GLdouble *v)
+{
+ return GL_Vertex4dv(v);
+}
+
+void GL_APIENTRY glVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ return GL_Vertex4f(x, y, z, w);
+}
+
+void GL_APIENTRY glVertex4fv(const GLfloat *v)
+{
+ return GL_Vertex4fv(v);
+}
+
+void GL_APIENTRY glVertex4i(GLint x, GLint y, GLint z, GLint w)
+{
+ return GL_Vertex4i(x, y, z, w);
+}
+
+void GL_APIENTRY glVertex4iv(const GLint *v)
+{
+ return GL_Vertex4iv(v);
+}
+
+void GL_APIENTRY glVertex4s(GLshort x, GLshort y, GLshort z, GLshort w)
+{
+ return GL_Vertex4s(x, y, z, w);
+}
+
+void GL_APIENTRY glVertex4sv(const GLshort *v)
+{
+ return GL_Vertex4sv(v);
+}
+
+// GL 1.1
+GLboolean GL_APIENTRY glAreTexturesResident(GLsizei n,
+ const GLuint *textures,
+ GLboolean *residences)
+{
+ return GL_AreTexturesResident(n, textures, residences);
+}
+
+void GL_APIENTRY glArrayElement(GLint i)
+{
+ return GL_ArrayElement(i);
+}
+
+void GL_APIENTRY glCopyTexImage1D(GLenum target,
+ GLint level,
+ GLenum internalformat,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLint border)
+{
+ return GL_CopyTexImage1D(target, level, internalformat, x, y, width, border);
+}
+
+void GL_APIENTRY
+glCopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width)
+{
+ return GL_CopyTexSubImage1D(target, level, xoffset, x, y, width);
+}
+
+void GL_APIENTRY glEdgeFlagPointer(GLsizei stride, const void *pointer)
+{
+ return GL_EdgeFlagPointer(stride, pointer);
+}
+
+void GL_APIENTRY glIndexPointer(GLenum type, GLsizei stride, const void *pointer)
+{
+ return GL_IndexPointer(type, stride, pointer);
+}
+
+void GL_APIENTRY glIndexub(GLubyte c)
+{
+ return GL_Indexub(c);
+}
+
+void GL_APIENTRY glIndexubv(const GLubyte *c)
+{
+ return GL_Indexubv(c);
+}
+
+void GL_APIENTRY glInterleavedArrays(GLenum format, GLsizei stride, const void *pointer)
+{
+ return GL_InterleavedArrays(format, stride, pointer);
+}
+
+void GL_APIENTRY glPopClientAttrib()
+{
+ return GL_PopClientAttrib();
+}
+
+void GL_APIENTRY glPrioritizeTextures(GLsizei n, const GLuint *textures, const GLfloat *priorities)
+{
+ return GL_PrioritizeTextures(n, textures, priorities);
+}
+
+void GL_APIENTRY glPushClientAttrib(GLbitfield mask)
+{
+ return GL_PushClientAttrib(mask);
+}
+
+void GL_APIENTRY glTexSubImage1D(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLsizei width,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ return GL_TexSubImage1D(target, level, xoffset, width, format, type, pixels);
+}
+
+// GL 1.2
+
+// GL 1.3
+void GL_APIENTRY glCompressedTexImage1D(GLenum target,
+ GLint level,
+ GLenum internalformat,
+ GLsizei width,
+ GLint border,
+ GLsizei imageSize,
+ const void *data)
+{
+ return GL_CompressedTexImage1D(target, level, internalformat, width, border, imageSize, data);
+}
+
+void GL_APIENTRY glCompressedTexSubImage1D(GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLsizei width,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data)
+{
+ return GL_CompressedTexSubImage1D(target, level, xoffset, width, format, imageSize, data);
+}
+
+void GL_APIENTRY glGetCompressedTexImage(GLenum target, GLint level, void *img)
+{
+ return GL_GetCompressedTexImage(target, level, img);
+}
+
+void GL_APIENTRY glLoadTransposeMatrixd(const GLdouble *m)
+{
+ return GL_LoadTransposeMatrixd(m);
+}
+
+void GL_APIENTRY glLoadTransposeMatrixf(const GLfloat *m)
+{
+ return GL_LoadTransposeMatrixf(m);
+}
+
+void GL_APIENTRY glMultTransposeMatrixd(const GLdouble *m)
+{
+ return GL_MultTransposeMatrixd(m);
+}
+
+void GL_APIENTRY glMultTransposeMatrixf(const GLfloat *m)
+{
+ return GL_MultTransposeMatrixf(m);
+}
+
+void GL_APIENTRY glMultiTexCoord1d(GLenum target, GLdouble s)
+{
+ return GL_MultiTexCoord1d(target, s);
+}
+
+void GL_APIENTRY glMultiTexCoord1dv(GLenum target, const GLdouble *v)
+{
+ return GL_MultiTexCoord1dv(target, v);
+}
+
+void GL_APIENTRY glMultiTexCoord1f(GLenum target, GLfloat s)
+{
+ return GL_MultiTexCoord1f(target, s);
+}
+
+void GL_APIENTRY glMultiTexCoord1fv(GLenum target, const GLfloat *v)
+{
+ return GL_MultiTexCoord1fv(target, v);
+}
+
+void GL_APIENTRY glMultiTexCoord1i(GLenum target, GLint s)
+{
+ return GL_MultiTexCoord1i(target, s);
+}
+
+void GL_APIENTRY glMultiTexCoord1iv(GLenum target, const GLint *v)
+{
+ return GL_MultiTexCoord1iv(target, v);
+}
+
+void GL_APIENTRY glMultiTexCoord1s(GLenum target, GLshort s)
+{
+ return GL_MultiTexCoord1s(target, s);
+}
+
+void GL_APIENTRY glMultiTexCoord1sv(GLenum target, const GLshort *v)
+{
+ return GL_MultiTexCoord1sv(target, v);
+}
+
+void GL_APIENTRY glMultiTexCoord2d(GLenum target, GLdouble s, GLdouble t)
+{
+ return GL_MultiTexCoord2d(target, s, t);
+}
+
+void GL_APIENTRY glMultiTexCoord2dv(GLenum target, const GLdouble *v)
+{
+ return GL_MultiTexCoord2dv(target, v);
+}
+
+void GL_APIENTRY glMultiTexCoord2f(GLenum target, GLfloat s, GLfloat t)
+{
+ return GL_MultiTexCoord2f(target, s, t);
+}
+
+void GL_APIENTRY glMultiTexCoord2fv(GLenum target, const GLfloat *v)
+{
+ return GL_MultiTexCoord2fv(target, v);
+}
+
+void GL_APIENTRY glMultiTexCoord2i(GLenum target, GLint s, GLint t)
+{
+ return GL_MultiTexCoord2i(target, s, t);
+}
+
+void GL_APIENTRY glMultiTexCoord2iv(GLenum target, const GLint *v)
+{
+ return GL_MultiTexCoord2iv(target, v);
+}
+
+void GL_APIENTRY glMultiTexCoord2s(GLenum target, GLshort s, GLshort t)
+{
+ return GL_MultiTexCoord2s(target, s, t);
+}
+
+void GL_APIENTRY glMultiTexCoord2sv(GLenum target, const GLshort *v)
+{
+ return GL_MultiTexCoord2sv(target, v);
+}
+
+void GL_APIENTRY glMultiTexCoord3d(GLenum target, GLdouble s, GLdouble t, GLdouble r)
+{
+ return GL_MultiTexCoord3d(target, s, t, r);
+}
+
+void GL_APIENTRY glMultiTexCoord3dv(GLenum target, const GLdouble *v)
+{
+ return GL_MultiTexCoord3dv(target, v);
+}
+
+void GL_APIENTRY glMultiTexCoord3f(GLenum target, GLfloat s, GLfloat t, GLfloat r)
+{
+ return GL_MultiTexCoord3f(target, s, t, r);
+}
+
+void GL_APIENTRY glMultiTexCoord3fv(GLenum target, const GLfloat *v)
+{
+ return GL_MultiTexCoord3fv(target, v);
+}
+
+void GL_APIENTRY glMultiTexCoord3i(GLenum target, GLint s, GLint t, GLint r)
+{
+ return GL_MultiTexCoord3i(target, s, t, r);
+}
+
+void GL_APIENTRY glMultiTexCoord3iv(GLenum target, const GLint *v)
+{
+ return GL_MultiTexCoord3iv(target, v);
+}
+
+void GL_APIENTRY glMultiTexCoord3s(GLenum target, GLshort s, GLshort t, GLshort r)
+{
+ return GL_MultiTexCoord3s(target, s, t, r);
+}
+
+void GL_APIENTRY glMultiTexCoord3sv(GLenum target, const GLshort *v)
+{
+ return GL_MultiTexCoord3sv(target, v);
+}
+
+void GL_APIENTRY glMultiTexCoord4d(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q)
+{
+ return GL_MultiTexCoord4d(target, s, t, r, q);
+}
+
+void GL_APIENTRY glMultiTexCoord4dv(GLenum target, const GLdouble *v)
+{
+ return GL_MultiTexCoord4dv(target, v);
+}
+
+void GL_APIENTRY glMultiTexCoord4fv(GLenum target, const GLfloat *v)
+{
+ return GL_MultiTexCoord4fv(target, v);
+}
+
+void GL_APIENTRY glMultiTexCoord4i(GLenum target, GLint s, GLint t, GLint r, GLint q)
+{
+ return GL_MultiTexCoord4i(target, s, t, r, q);
+}
+
+void GL_APIENTRY glMultiTexCoord4iv(GLenum target, const GLint *v)
+{
+ return GL_MultiTexCoord4iv(target, v);
+}
+
+void GL_APIENTRY glMultiTexCoord4s(GLenum target, GLshort s, GLshort t, GLshort r, GLshort q)
+{
+ return GL_MultiTexCoord4s(target, s, t, r, q);
+}
+
+void GL_APIENTRY glMultiTexCoord4sv(GLenum target, const GLshort *v)
+{
+ return GL_MultiTexCoord4sv(target, v);
+}
+
+// GL 1.4
+void GL_APIENTRY glFogCoordPointer(GLenum type, GLsizei stride, const void *pointer)
+{
+ return GL_FogCoordPointer(type, stride, pointer);
+}
+
+void GL_APIENTRY glFogCoordd(GLdouble coord)
+{
+ return GL_FogCoordd(coord);
+}
+
+void GL_APIENTRY glFogCoorddv(const GLdouble *coord)
+{
+ return GL_FogCoorddv(coord);
+}
+
+void GL_APIENTRY glFogCoordf(GLfloat coord)
+{
+ return GL_FogCoordf(coord);
+}
+
+void GL_APIENTRY glFogCoordfv(const GLfloat *coord)
+{
+ return GL_FogCoordfv(coord);
+}
+
+void GL_APIENTRY glMultiDrawArrays(GLenum mode,
+ const GLint *first,
+ const GLsizei *count,
+ GLsizei drawcount)
+{
+ return GL_MultiDrawArrays(mode, first, count, drawcount);
+}
+
+void GL_APIENTRY glMultiDrawElements(GLenum mode,
+ const GLsizei *count,
+ GLenum type,
+ const void *const *indices,
+ GLsizei drawcount)
+{
+ return GL_MultiDrawElements(mode, count, type, indices, drawcount);
+}
+
+void GL_APIENTRY glPointParameteri(GLenum pname, GLint param)
+{
+ return GL_PointParameteri(pname, param);
+}
+
+void GL_APIENTRY glPointParameteriv(GLenum pname, const GLint *params)
+{
+ return GL_PointParameteriv(pname, params);
+}
+
+void GL_APIENTRY glSecondaryColor3b(GLbyte red, GLbyte green, GLbyte blue)
+{
+ return GL_SecondaryColor3b(red, green, blue);
+}
+
+void GL_APIENTRY glSecondaryColor3bv(const GLbyte *v)
+{
+ return GL_SecondaryColor3bv(v);
+}
+
+void GL_APIENTRY glSecondaryColor3d(GLdouble red, GLdouble green, GLdouble blue)
+{
+ return GL_SecondaryColor3d(red, green, blue);
+}
+
+void GL_APIENTRY glSecondaryColor3dv(const GLdouble *v)
+{
+ return GL_SecondaryColor3dv(v);
+}
+
+void GL_APIENTRY glSecondaryColor3f(GLfloat red, GLfloat green, GLfloat blue)
+{
+ return GL_SecondaryColor3f(red, green, blue);
+}
+
+void GL_APIENTRY glSecondaryColor3fv(const GLfloat *v)
+{
+ return GL_SecondaryColor3fv(v);
+}
+
+void GL_APIENTRY glSecondaryColor3i(GLint red, GLint green, GLint blue)
+{
+ return GL_SecondaryColor3i(red, green, blue);
+}
+
+void GL_APIENTRY glSecondaryColor3iv(const GLint *v)
+{
+ return GL_SecondaryColor3iv(v);
+}
+
+void GL_APIENTRY glSecondaryColor3s(GLshort red, GLshort green, GLshort blue)
+{
+ return GL_SecondaryColor3s(red, green, blue);
+}
+
+void GL_APIENTRY glSecondaryColor3sv(const GLshort *v)
+{
+ return GL_SecondaryColor3sv(v);
+}
+
+void GL_APIENTRY glSecondaryColor3ub(GLubyte red, GLubyte green, GLubyte blue)
+{
+ return GL_SecondaryColor3ub(red, green, blue);
+}
+
+void GL_APIENTRY glSecondaryColor3ubv(const GLubyte *v)
+{
+ return GL_SecondaryColor3ubv(v);
+}
+
+void GL_APIENTRY glSecondaryColor3ui(GLuint red, GLuint green, GLuint blue)
+{
+ return GL_SecondaryColor3ui(red, green, blue);
+}
+
+void GL_APIENTRY glSecondaryColor3uiv(const GLuint *v)
+{
+ return GL_SecondaryColor3uiv(v);
+}
+
+void GL_APIENTRY glSecondaryColor3us(GLushort red, GLushort green, GLushort blue)
+{
+ return GL_SecondaryColor3us(red, green, blue);
+}
+
+void GL_APIENTRY glSecondaryColor3usv(const GLushort *v)
+{
+ return GL_SecondaryColor3usv(v);
+}
+
+void GL_APIENTRY glSecondaryColorPointer(GLint size,
+ GLenum type,
+ GLsizei stride,
+ const void *pointer)
+{
+ return GL_SecondaryColorPointer(size, type, stride, pointer);
+}
+
+void GL_APIENTRY glWindowPos2d(GLdouble x, GLdouble y)
+{
+ return GL_WindowPos2d(x, y);
+}
+
+void GL_APIENTRY glWindowPos2dv(const GLdouble *v)
+{
+ return GL_WindowPos2dv(v);
+}
+
+void GL_APIENTRY glWindowPos2f(GLfloat x, GLfloat y)
+{
+ return GL_WindowPos2f(x, y);
+}
+
+void GL_APIENTRY glWindowPos2fv(const GLfloat *v)
+{
+ return GL_WindowPos2fv(v);
+}
+
+void GL_APIENTRY glWindowPos2i(GLint x, GLint y)
+{
+ return GL_WindowPos2i(x, y);
+}
+
+void GL_APIENTRY glWindowPos2iv(const GLint *v)
+{
+ return GL_WindowPos2iv(v);
+}
+
+void GL_APIENTRY glWindowPos2s(GLshort x, GLshort y)
+{
+ return GL_WindowPos2s(x, y);
+}
+
+void GL_APIENTRY glWindowPos2sv(const GLshort *v)
+{
+ return GL_WindowPos2sv(v);
+}
+
+void GL_APIENTRY glWindowPos3d(GLdouble x, GLdouble y, GLdouble z)
+{
+ return GL_WindowPos3d(x, y, z);
+}
+
+void GL_APIENTRY glWindowPos3dv(const GLdouble *v)
+{
+ return GL_WindowPos3dv(v);
+}
+
+void GL_APIENTRY glWindowPos3f(GLfloat x, GLfloat y, GLfloat z)
+{
+ return GL_WindowPos3f(x, y, z);
+}
+
+void GL_APIENTRY glWindowPos3fv(const GLfloat *v)
+{
+ return GL_WindowPos3fv(v);
+}
+
+void GL_APIENTRY glWindowPos3i(GLint x, GLint y, GLint z)
+{
+ return GL_WindowPos3i(x, y, z);
+}
+
+void GL_APIENTRY glWindowPos3iv(const GLint *v)
+{
+ return GL_WindowPos3iv(v);
+}
+
+void GL_APIENTRY glWindowPos3s(GLshort x, GLshort y, GLshort z)
+{
+ return GL_WindowPos3s(x, y, z);
+}
+
+void GL_APIENTRY glWindowPos3sv(const GLshort *v)
+{
+ return GL_WindowPos3sv(v);
+}
+
+// GL 1.5
+void GL_APIENTRY glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, void *data)
+{
+ return GL_GetBufferSubData(target, offset, size, data);
+}
+
+void GL_APIENTRY glGetQueryObjectiv(GLuint id, GLenum pname, GLint *params)
+{
+ return GL_GetQueryObjectiv(id, pname, params);
+}
+
+void *GL_APIENTRY glMapBuffer(GLenum target, GLenum access)
+{
+ return GL_MapBuffer(target, access);
+}
+
+// GL 2.0
+void GL_APIENTRY glGetVertexAttribdv(GLuint index, GLenum pname, GLdouble *params)
+{
+ return GL_GetVertexAttribdv(index, pname, params);
+}
+
+void GL_APIENTRY glVertexAttrib1d(GLuint index, GLdouble x)
+{
+ return GL_VertexAttrib1d(index, x);
+}
+
+void GL_APIENTRY glVertexAttrib1dv(GLuint index, const GLdouble *v)
+{
+ return GL_VertexAttrib1dv(index, v);
+}
+
+void GL_APIENTRY glVertexAttrib1s(GLuint index, GLshort x)
+{
+ return GL_VertexAttrib1s(index, x);
+}
+
+void GL_APIENTRY glVertexAttrib1sv(GLuint index, const GLshort *v)
+{
+ return GL_VertexAttrib1sv(index, v);
+}
+
+void GL_APIENTRY glVertexAttrib2d(GLuint index, GLdouble x, GLdouble y)
+{
+ return GL_VertexAttrib2d(index, x, y);
+}
+
+void GL_APIENTRY glVertexAttrib2dv(GLuint index, const GLdouble *v)
+{
+ return GL_VertexAttrib2dv(index, v);
+}
+
+void GL_APIENTRY glVertexAttrib2s(GLuint index, GLshort x, GLshort y)
+{
+ return GL_VertexAttrib2s(index, x, y);
+}
+
+void GL_APIENTRY glVertexAttrib2sv(GLuint index, const GLshort *v)
+{
+ return GL_VertexAttrib2sv(index, v);
+}
+
+void GL_APIENTRY glVertexAttrib3d(GLuint index, GLdouble x, GLdouble y, GLdouble z)
+{
+ return GL_VertexAttrib3d(index, x, y, z);
+}
+
+void GL_APIENTRY glVertexAttrib3dv(GLuint index, const GLdouble *v)
+{
+ return GL_VertexAttrib3dv(index, v);
+}
+
+void GL_APIENTRY glVertexAttrib3s(GLuint index, GLshort x, GLshort y, GLshort z)
+{
+ return GL_VertexAttrib3s(index, x, y, z);
+}
+
+void GL_APIENTRY glVertexAttrib3sv(GLuint index, const GLshort *v)
+{
+ return GL_VertexAttrib3sv(index, v);
+}
+
+void GL_APIENTRY glVertexAttrib4Nbv(GLuint index, const GLbyte *v)
+{
+ return GL_VertexAttrib4Nbv(index, v);
+}
+
+void GL_APIENTRY glVertexAttrib4Niv(GLuint index, const GLint *v)
+{
+ return GL_VertexAttrib4Niv(index, v);
+}
+
+void GL_APIENTRY glVertexAttrib4Nsv(GLuint index, const GLshort *v)
+{
+ return GL_VertexAttrib4Nsv(index, v);
+}
+
+void GL_APIENTRY glVertexAttrib4Nub(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w)
+{
+ return GL_VertexAttrib4Nub(index, x, y, z, w);
+}
+
+void GL_APIENTRY glVertexAttrib4Nubv(GLuint index, const GLubyte *v)
+{
+ return GL_VertexAttrib4Nubv(index, v);
+}
+
+void GL_APIENTRY glVertexAttrib4Nuiv(GLuint index, const GLuint *v)
+{
+ return GL_VertexAttrib4Nuiv(index, v);
+}
+
+void GL_APIENTRY glVertexAttrib4Nusv(GLuint index, const GLushort *v)
+{
+ return GL_VertexAttrib4Nusv(index, v);
+}
+
+void GL_APIENTRY glVertexAttrib4bv(GLuint index, const GLbyte *v)
+{
+ return GL_VertexAttrib4bv(index, v);
+}
+
+void GL_APIENTRY glVertexAttrib4d(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w)
+{
+ return GL_VertexAttrib4d(index, x, y, z, w);
+}
+
+void GL_APIENTRY glVertexAttrib4dv(GLuint index, const GLdouble *v)
+{
+ return GL_VertexAttrib4dv(index, v);
+}
+
+void GL_APIENTRY glVertexAttrib4iv(GLuint index, const GLint *v)
+{
+ return GL_VertexAttrib4iv(index, v);
+}
+
+void GL_APIENTRY glVertexAttrib4s(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w)
+{
+ return GL_VertexAttrib4s(index, x, y, z, w);
+}
+
+void GL_APIENTRY glVertexAttrib4sv(GLuint index, const GLshort *v)
+{
+ return GL_VertexAttrib4sv(index, v);
+}
+
+void GL_APIENTRY glVertexAttrib4ubv(GLuint index, const GLubyte *v)
+{
+ return GL_VertexAttrib4ubv(index, v);
+}
+
+void GL_APIENTRY glVertexAttrib4uiv(GLuint index, const GLuint *v)
+{
+ return GL_VertexAttrib4uiv(index, v);
+}
+
+void GL_APIENTRY glVertexAttrib4usv(GLuint index, const GLushort *v)
+{
+ return GL_VertexAttrib4usv(index, v);
+}
+
+// GL 2.1
+
+// GL 3.0
+void GL_APIENTRY glBeginConditionalRender(GLuint id, GLenum mode)
+{
+ return GL_BeginConditionalRender(id, mode);
+}
+
+void GL_APIENTRY glBindFragDataLocation(GLuint program, GLuint color, const GLchar *name)
+{
+ return GL_BindFragDataLocation(program, color, name);
+}
+
+void GL_APIENTRY glClampColor(GLenum target, GLenum clamp)
+{
+ return GL_ClampColor(target, clamp);
+}
+
+void GL_APIENTRY glEndConditionalRender()
+{
+ return GL_EndConditionalRender();
+}
+
+void GL_APIENTRY glFramebufferTexture1D(GLenum target,
+ GLenum attachment,
+ GLenum textarget,
+ GLuint texture,
+ GLint level)
+{
+ return GL_FramebufferTexture1D(target, attachment, textarget, texture, level);
+}
+
+void GL_APIENTRY glFramebufferTexture3D(GLenum target,
+ GLenum attachment,
+ GLenum textarget,
+ GLuint texture,
+ GLint level,
+ GLint zoffset)
+{
+ return GL_FramebufferTexture3D(target, attachment, textarget, texture, level, zoffset);
+}
+
+void GL_APIENTRY glVertexAttribI1i(GLuint index, GLint x)
+{
+ return GL_VertexAttribI1i(index, x);
+}
+
+void GL_APIENTRY glVertexAttribI1iv(GLuint index, const GLint *v)
+{
+ return GL_VertexAttribI1iv(index, v);
+}
+
+void GL_APIENTRY glVertexAttribI1ui(GLuint index, GLuint x)
+{
+ return GL_VertexAttribI1ui(index, x);
+}
+
+void GL_APIENTRY glVertexAttribI1uiv(GLuint index, const GLuint *v)
+{
+ return GL_VertexAttribI1uiv(index, v);
+}
+
+void GL_APIENTRY glVertexAttribI2i(GLuint index, GLint x, GLint y)
+{
+ return GL_VertexAttribI2i(index, x, y);
+}
+
+void GL_APIENTRY glVertexAttribI2iv(GLuint index, const GLint *v)
+{
+ return GL_VertexAttribI2iv(index, v);
+}
+
+void GL_APIENTRY glVertexAttribI2ui(GLuint index, GLuint x, GLuint y)
+{
+ return GL_VertexAttribI2ui(index, x, y);
+}
+
+void GL_APIENTRY glVertexAttribI2uiv(GLuint index, const GLuint *v)
+{
+ return GL_VertexAttribI2uiv(index, v);
+}
+
+void GL_APIENTRY glVertexAttribI3i(GLuint index, GLint x, GLint y, GLint z)
+{
+ return GL_VertexAttribI3i(index, x, y, z);
+}
+
+void GL_APIENTRY glVertexAttribI3iv(GLuint index, const GLint *v)
+{
+ return GL_VertexAttribI3iv(index, v);
+}
+
+void GL_APIENTRY glVertexAttribI3ui(GLuint index, GLuint x, GLuint y, GLuint z)
+{
+ return GL_VertexAttribI3ui(index, x, y, z);
+}
+
+void GL_APIENTRY glVertexAttribI3uiv(GLuint index, const GLuint *v)
+{
+ return GL_VertexAttribI3uiv(index, v);
+}
+
+void GL_APIENTRY glVertexAttribI4bv(GLuint index, const GLbyte *v)
+{
+ return GL_VertexAttribI4bv(index, v);
+}
+
+void GL_APIENTRY glVertexAttribI4sv(GLuint index, const GLshort *v)
+{
+ return GL_VertexAttribI4sv(index, v);
+}
+
+void GL_APIENTRY glVertexAttribI4ubv(GLuint index, const GLubyte *v)
+{
+ return GL_VertexAttribI4ubv(index, v);
+}
+
+void GL_APIENTRY glVertexAttribI4usv(GLuint index, const GLushort *v)
+{
+ return GL_VertexAttribI4usv(index, v);
+}
+
+// GL 3.1
+void GL_APIENTRY glGetActiveUniformName(GLuint program,
+ GLuint uniformIndex,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *uniformName)
+{
+ return GL_GetActiveUniformName(program, uniformIndex, bufSize, length, uniformName);
+}
+
+void GL_APIENTRY glPrimitiveRestartIndex(GLuint index)
+{
+ return GL_PrimitiveRestartIndex(index);
+}
+
+// GL 3.2
+void GL_APIENTRY glMultiDrawElementsBaseVertex(GLenum mode,
+ const GLsizei *count,
+ GLenum type,
+ const void *const *indices,
+ GLsizei drawcount,
+ const GLint *basevertex)
+{
+ return GL_MultiDrawElementsBaseVertex(mode, count, type, indices, drawcount, basevertex);
+}
+
+void GL_APIENTRY glProvokingVertex(GLenum mode)
+{
+ return GL_ProvokingVertex(mode);
+}
+
+void GL_APIENTRY glTexImage2DMultisample(GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedsamplelocations)
+{
+ return GL_TexImage2DMultisample(target, samples, internalformat, width, height,
+ fixedsamplelocations);
+}
+
+void GL_APIENTRY glTexImage3DMultisample(GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean fixedsamplelocations)
+{
+ return GL_TexImage3DMultisample(target, samples, internalformat, width, height, depth,
+ fixedsamplelocations);
+}
+
+// GL 3.3
+void GL_APIENTRY glBindFragDataLocationIndexed(GLuint program,
+ GLuint colorNumber,
+ GLuint index,
+ const GLchar *name)
+{
+ return GL_BindFragDataLocationIndexed(program, colorNumber, index, name);
+}
+
+void GL_APIENTRY glColorP3ui(GLenum type, GLuint color)
+{
+ return GL_ColorP3ui(type, color);
+}
+
+void GL_APIENTRY glColorP3uiv(GLenum type, const GLuint *color)
+{
+ return GL_ColorP3uiv(type, color);
+}
+
+void GL_APIENTRY glColorP4ui(GLenum type, GLuint color)
+{
+ return GL_ColorP4ui(type, color);
+}
+
+void GL_APIENTRY glColorP4uiv(GLenum type, const GLuint *color)
+{
+ return GL_ColorP4uiv(type, color);
+}
+
+GLint GL_APIENTRY glGetFragDataIndex(GLuint program, const GLchar *name)
+{
+ return GL_GetFragDataIndex(program, name);
+}
+
+void GL_APIENTRY glGetQueryObjecti64v(GLuint id, GLenum pname, GLint64 *params)
+{
+ return GL_GetQueryObjecti64v(id, pname, params);
+}
+
+void GL_APIENTRY glGetQueryObjectui64v(GLuint id, GLenum pname, GLuint64 *params)
+{
+ return GL_GetQueryObjectui64v(id, pname, params);
+}
+
+void GL_APIENTRY glMultiTexCoordP1ui(GLenum texture, GLenum type, GLuint coords)
+{
+ return GL_MultiTexCoordP1ui(texture, type, coords);
+}
+
+void GL_APIENTRY glMultiTexCoordP1uiv(GLenum texture, GLenum type, const GLuint *coords)
+{
+ return GL_MultiTexCoordP1uiv(texture, type, coords);
+}
+
+void GL_APIENTRY glMultiTexCoordP2ui(GLenum texture, GLenum type, GLuint coords)
+{
+ return GL_MultiTexCoordP2ui(texture, type, coords);
+}
+
+void GL_APIENTRY glMultiTexCoordP2uiv(GLenum texture, GLenum type, const GLuint *coords)
+{
+ return GL_MultiTexCoordP2uiv(texture, type, coords);
+}
+
+void GL_APIENTRY glMultiTexCoordP3ui(GLenum texture, GLenum type, GLuint coords)
+{
+ return GL_MultiTexCoordP3ui(texture, type, coords);
+}
+
+void GL_APIENTRY glMultiTexCoordP3uiv(GLenum texture, GLenum type, const GLuint *coords)
+{
+ return GL_MultiTexCoordP3uiv(texture, type, coords);
+}
+
+void GL_APIENTRY glMultiTexCoordP4ui(GLenum texture, GLenum type, GLuint coords)
+{
+ return GL_MultiTexCoordP4ui(texture, type, coords);
+}
+
+void GL_APIENTRY glMultiTexCoordP4uiv(GLenum texture, GLenum type, const GLuint *coords)
+{
+ return GL_MultiTexCoordP4uiv(texture, type, coords);
+}
+
+void GL_APIENTRY glNormalP3ui(GLenum type, GLuint coords)
+{
+ return GL_NormalP3ui(type, coords);
+}
+
+void GL_APIENTRY glNormalP3uiv(GLenum type, const GLuint *coords)
+{
+ return GL_NormalP3uiv(type, coords);
+}
+
+void GL_APIENTRY glQueryCounter(GLuint id, GLenum target)
+{
+ return GL_QueryCounter(id, target);
+}
+
+void GL_APIENTRY glSecondaryColorP3ui(GLenum type, GLuint color)
+{
+ return GL_SecondaryColorP3ui(type, color);
+}
+
+void GL_APIENTRY glSecondaryColorP3uiv(GLenum type, const GLuint *color)
+{
+ return GL_SecondaryColorP3uiv(type, color);
+}
+
+void GL_APIENTRY glTexCoordP1ui(GLenum type, GLuint coords)
+{
+ return GL_TexCoordP1ui(type, coords);
+}
+
+void GL_APIENTRY glTexCoordP1uiv(GLenum type, const GLuint *coords)
+{
+ return GL_TexCoordP1uiv(type, coords);
+}
+
+void GL_APIENTRY glTexCoordP2ui(GLenum type, GLuint coords)
+{
+ return GL_TexCoordP2ui(type, coords);
+}
+
+void GL_APIENTRY glTexCoordP2uiv(GLenum type, const GLuint *coords)
+{
+ return GL_TexCoordP2uiv(type, coords);
+}
+
+void GL_APIENTRY glTexCoordP3ui(GLenum type, GLuint coords)
+{
+ return GL_TexCoordP3ui(type, coords);
+}
+
+void GL_APIENTRY glTexCoordP3uiv(GLenum type, const GLuint *coords)
+{
+ return GL_TexCoordP3uiv(type, coords);
+}
+
+void GL_APIENTRY glTexCoordP4ui(GLenum type, GLuint coords)
+{
+ return GL_TexCoordP4ui(type, coords);
+}
+
+void GL_APIENTRY glTexCoordP4uiv(GLenum type, const GLuint *coords)
+{
+ return GL_TexCoordP4uiv(type, coords);
+}
+
+void GL_APIENTRY glVertexAttribP1ui(GLuint index, GLenum type, GLboolean normalized, GLuint value)
+{
+ return GL_VertexAttribP1ui(index, type, normalized, value);
+}
+
+void GL_APIENTRY glVertexAttribP1uiv(GLuint index,
+ GLenum type,
+ GLboolean normalized,
+ const GLuint *value)
+{
+ return GL_VertexAttribP1uiv(index, type, normalized, value);
+}
+
+void GL_APIENTRY glVertexAttribP2ui(GLuint index, GLenum type, GLboolean normalized, GLuint value)
+{
+ return GL_VertexAttribP2ui(index, type, normalized, value);
+}
+
+void GL_APIENTRY glVertexAttribP2uiv(GLuint index,
+ GLenum type,
+ GLboolean normalized,
+ const GLuint *value)
+{
+ return GL_VertexAttribP2uiv(index, type, normalized, value);
+}
+
+void GL_APIENTRY glVertexAttribP3ui(GLuint index, GLenum type, GLboolean normalized, GLuint value)
+{
+ return GL_VertexAttribP3ui(index, type, normalized, value);
+}
+
+void GL_APIENTRY glVertexAttribP3uiv(GLuint index,
+ GLenum type,
+ GLboolean normalized,
+ const GLuint *value)
+{
+ return GL_VertexAttribP3uiv(index, type, normalized, value);
+}
+
+void GL_APIENTRY glVertexAttribP4ui(GLuint index, GLenum type, GLboolean normalized, GLuint value)
+{
+ return GL_VertexAttribP4ui(index, type, normalized, value);
+}
+
+void GL_APIENTRY glVertexAttribP4uiv(GLuint index,
+ GLenum type,
+ GLboolean normalized,
+ const GLuint *value)
+{
+ return GL_VertexAttribP4uiv(index, type, normalized, value);
+}
+
+void GL_APIENTRY glVertexP2ui(GLenum type, GLuint value)
+{
+ return GL_VertexP2ui(type, value);
+}
+
+void GL_APIENTRY glVertexP2uiv(GLenum type, const GLuint *value)
+{
+ return GL_VertexP2uiv(type, value);
+}
+
+void GL_APIENTRY glVertexP3ui(GLenum type, GLuint value)
+{
+ return GL_VertexP3ui(type, value);
+}
+
+void GL_APIENTRY glVertexP3uiv(GLenum type, const GLuint *value)
+{
+ return GL_VertexP3uiv(type, value);
+}
+
+void GL_APIENTRY glVertexP4ui(GLenum type, GLuint value)
+{
+ return GL_VertexP4ui(type, value);
+}
+
+void GL_APIENTRY glVertexP4uiv(GLenum type, const GLuint *value)
+{
+ return GL_VertexP4uiv(type, value);
+}
+
+// GL 4.0
+void GL_APIENTRY glBeginQueryIndexed(GLenum target, GLuint index, GLuint id)
+{
+ return GL_BeginQueryIndexed(target, index, id);
+}
+
+void GL_APIENTRY glDrawTransformFeedback(GLenum mode, GLuint id)
+{
+ return GL_DrawTransformFeedback(mode, id);
+}
+
+void GL_APIENTRY glDrawTransformFeedbackStream(GLenum mode, GLuint id, GLuint stream)
+{
+ return GL_DrawTransformFeedbackStream(mode, id, stream);
+}
+
+void GL_APIENTRY glEndQueryIndexed(GLenum target, GLuint index)
+{
+ return GL_EndQueryIndexed(target, index);
+}
+
+void GL_APIENTRY glGetActiveSubroutineName(GLuint program,
+ GLenum shadertype,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *name)
+{
+ return GL_GetActiveSubroutineName(program, shadertype, index, bufSize, length, name);
+}
+
+void GL_APIENTRY glGetActiveSubroutineUniformName(GLuint program,
+ GLenum shadertype,
+ GLuint index,
+ GLsizei bufSize,
+ GLsizei *length,
+ GLchar *name)
+{
+ return GL_GetActiveSubroutineUniformName(program, shadertype, index, bufSize, length, name);
+}
+
+void GL_APIENTRY glGetActiveSubroutineUniformiv(GLuint program,
+ GLenum shadertype,
+ GLuint index,
+ GLenum pname,
+ GLint *values)
+{
+ return GL_GetActiveSubroutineUniformiv(program, shadertype, index, pname, values);
+}
+
+void GL_APIENTRY glGetProgramStageiv(GLuint program, GLenum shadertype, GLenum pname, GLint *values)
+{
+ return GL_GetProgramStageiv(program, shadertype, pname, values);
+}
+
+void GL_APIENTRY glGetQueryIndexediv(GLenum target, GLuint index, GLenum pname, GLint *params)
+{
+ return GL_GetQueryIndexediv(target, index, pname, params);
+}
+
+GLuint GL_APIENTRY glGetSubroutineIndex(GLuint program, GLenum shadertype, const GLchar *name)
+{
+ return GL_GetSubroutineIndex(program, shadertype, name);
+}
+
+GLint GL_APIENTRY glGetSubroutineUniformLocation(GLuint program,
+ GLenum shadertype,
+ const GLchar *name)
+{
+ return GL_GetSubroutineUniformLocation(program, shadertype, name);
+}
+
+void GL_APIENTRY glGetUniformSubroutineuiv(GLenum shadertype, GLint location, GLuint *params)
+{
+ return GL_GetUniformSubroutineuiv(shadertype, location, params);
+}
+
+void GL_APIENTRY glGetUniformdv(GLuint program, GLint location, GLdouble *params)
+{
+ return GL_GetUniformdv(program, location, params);
+}
+
+void GL_APIENTRY glPatchParameterfv(GLenum pname, const GLfloat *values)
+{
+ return GL_PatchParameterfv(pname, values);
+}
+
+void GL_APIENTRY glUniform1d(GLint location, GLdouble x)
+{
+ return GL_Uniform1d(location, x);
+}
+
+void GL_APIENTRY glUniform1dv(GLint location, GLsizei count, const GLdouble *value)
+{
+ return GL_Uniform1dv(location, count, value);
+}
+
+void GL_APIENTRY glUniform2d(GLint location, GLdouble x, GLdouble y)
+{
+ return GL_Uniform2d(location, x, y);
+}
+
+void GL_APIENTRY glUniform2dv(GLint location, GLsizei count, const GLdouble *value)
+{
+ return GL_Uniform2dv(location, count, value);
+}
+
+void GL_APIENTRY glUniform3d(GLint location, GLdouble x, GLdouble y, GLdouble z)
+{
+ return GL_Uniform3d(location, x, y, z);
+}
+
+void GL_APIENTRY glUniform3dv(GLint location, GLsizei count, const GLdouble *value)
+{
+ return GL_Uniform3dv(location, count, value);
+}
+
+void GL_APIENTRY glUniform4d(GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w)
+{
+ return GL_Uniform4d(location, x, y, z, w);
+}
+
+void GL_APIENTRY glUniform4dv(GLint location, GLsizei count, const GLdouble *value)
+{
+ return GL_Uniform4dv(location, count, value);
+}
+
+void GL_APIENTRY glUniformMatrix2dv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ return GL_UniformMatrix2dv(location, count, transpose, value);
+}
+
+void GL_APIENTRY glUniformMatrix2x3dv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ return GL_UniformMatrix2x3dv(location, count, transpose, value);
+}
+
+void GL_APIENTRY glUniformMatrix2x4dv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ return GL_UniformMatrix2x4dv(location, count, transpose, value);
+}
+
+void GL_APIENTRY glUniformMatrix3dv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ return GL_UniformMatrix3dv(location, count, transpose, value);
+}
+
+void GL_APIENTRY glUniformMatrix3x2dv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ return GL_UniformMatrix3x2dv(location, count, transpose, value);
+}
+
+void GL_APIENTRY glUniformMatrix3x4dv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ return GL_UniformMatrix3x4dv(location, count, transpose, value);
+}
+
+void GL_APIENTRY glUniformMatrix4dv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ return GL_UniformMatrix4dv(location, count, transpose, value);
+}
+
+void GL_APIENTRY glUniformMatrix4x2dv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ return GL_UniformMatrix4x2dv(location, count, transpose, value);
+}
+
+void GL_APIENTRY glUniformMatrix4x3dv(GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ return GL_UniformMatrix4x3dv(location, count, transpose, value);
+}
+
+void GL_APIENTRY glUniformSubroutinesuiv(GLenum shadertype, GLsizei count, const GLuint *indices)
+{
+ return GL_UniformSubroutinesuiv(shadertype, count, indices);
+}
+
+// GL 4.1
+void GL_APIENTRY glDepthRangeArrayv(GLuint first, GLsizei count, const GLdouble *v)
+{
+ return GL_DepthRangeArrayv(first, count, v);
+}
+
+void GL_APIENTRY glDepthRangeIndexed(GLuint index, GLdouble n, GLdouble f)
+{
+ return GL_DepthRangeIndexed(index, n, f);
+}
+
+void GL_APIENTRY glGetDoublei_v(GLenum target, GLuint index, GLdouble *data)
+{
+ return GL_GetDoublei_v(target, index, data);
+}
+
+void GL_APIENTRY glGetFloati_v(GLenum target, GLuint index, GLfloat *data)
+{
+ return GL_GetFloati_v(target, index, data);
+}
+
+void GL_APIENTRY glGetVertexAttribLdv(GLuint index, GLenum pname, GLdouble *params)
+{
+ return GL_GetVertexAttribLdv(index, pname, params);
+}
+
+void GL_APIENTRY glProgramUniform1d(GLuint program, GLint location, GLdouble v0)
+{
+ return GL_ProgramUniform1d(program, location, v0);
+}
+
+void GL_APIENTRY glProgramUniform1dv(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLdouble *value)
+{
+ return GL_ProgramUniform1dv(program, location, count, value);
+}
+
+void GL_APIENTRY glProgramUniform2d(GLuint program, GLint location, GLdouble v0, GLdouble v1)
+{
+ return GL_ProgramUniform2d(program, location, v0, v1);
+}
+
+void GL_APIENTRY glProgramUniform2dv(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLdouble *value)
+{
+ return GL_ProgramUniform2dv(program, location, count, value);
+}
+
+void GL_APIENTRY
+glProgramUniform3d(GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2)
+{
+ return GL_ProgramUniform3d(program, location, v0, v1, v2);
+}
+
+void GL_APIENTRY glProgramUniform3dv(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLdouble *value)
+{
+ return GL_ProgramUniform3dv(program, location, count, value);
+}
+
+void GL_APIENTRY glProgramUniform4d(GLuint program,
+ GLint location,
+ GLdouble v0,
+ GLdouble v1,
+ GLdouble v2,
+ GLdouble v3)
+{
+ return GL_ProgramUniform4d(program, location, v0, v1, v2, v3);
+}
+
+void GL_APIENTRY glProgramUniform4dv(GLuint program,
+ GLint location,
+ GLsizei count,
+ const GLdouble *value)
+{
+ return GL_ProgramUniform4dv(program, location, count, value);
+}
+
+void GL_APIENTRY glProgramUniformMatrix2dv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ return GL_ProgramUniformMatrix2dv(program, location, count, transpose, value);
+}
+
+void GL_APIENTRY glProgramUniformMatrix2x3dv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ return GL_ProgramUniformMatrix2x3dv(program, location, count, transpose, value);
+}
+
+void GL_APIENTRY glProgramUniformMatrix2x4dv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ return GL_ProgramUniformMatrix2x4dv(program, location, count, transpose, value);
+}
+
+void GL_APIENTRY glProgramUniformMatrix3dv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ return GL_ProgramUniformMatrix3dv(program, location, count, transpose, value);
+}
+
+void GL_APIENTRY glProgramUniformMatrix3x2dv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ return GL_ProgramUniformMatrix3x2dv(program, location, count, transpose, value);
+}
+
+void GL_APIENTRY glProgramUniformMatrix3x4dv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ return GL_ProgramUniformMatrix3x4dv(program, location, count, transpose, value);
+}
+
+void GL_APIENTRY glProgramUniformMatrix4dv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ return GL_ProgramUniformMatrix4dv(program, location, count, transpose, value);
+}
+
+void GL_APIENTRY glProgramUniformMatrix4x2dv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ return GL_ProgramUniformMatrix4x2dv(program, location, count, transpose, value);
+}
+
+void GL_APIENTRY glProgramUniformMatrix4x3dv(GLuint program,
+ GLint location,
+ GLsizei count,
+ GLboolean transpose,
+ const GLdouble *value)
+{
+ return GL_ProgramUniformMatrix4x3dv(program, location, count, transpose, value);
+}
+
+void GL_APIENTRY glScissorArrayv(GLuint first, GLsizei count, const GLint *v)
+{
+ return GL_ScissorArrayv(first, count, v);
+}
+
+void GL_APIENTRY
+glScissorIndexed(GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height)
+{
+ return GL_ScissorIndexed(index, left, bottom, width, height);
+}
+
+void GL_APIENTRY glScissorIndexedv(GLuint index, const GLint *v)
+{
+ return GL_ScissorIndexedv(index, v);
+}
+
+void GL_APIENTRY glVertexAttribL1d(GLuint index, GLdouble x)
+{
+ return GL_VertexAttribL1d(index, x);
+}
+
+void GL_APIENTRY glVertexAttribL1dv(GLuint index, const GLdouble *v)
+{
+ return GL_VertexAttribL1dv(index, v);
+}
+
+void GL_APIENTRY glVertexAttribL2d(GLuint index, GLdouble x, GLdouble y)
+{
+ return GL_VertexAttribL2d(index, x, y);
+}
+
+void GL_APIENTRY glVertexAttribL2dv(GLuint index, const GLdouble *v)
+{
+ return GL_VertexAttribL2dv(index, v);
+}
+
+void GL_APIENTRY glVertexAttribL3d(GLuint index, GLdouble x, GLdouble y, GLdouble z)
+{
+ return GL_VertexAttribL3d(index, x, y, z);
+}
+
+void GL_APIENTRY glVertexAttribL3dv(GLuint index, const GLdouble *v)
+{
+ return GL_VertexAttribL3dv(index, v);
+}
+
+void GL_APIENTRY glVertexAttribL4d(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w)
+{
+ return GL_VertexAttribL4d(index, x, y, z, w);
+}
+
+void GL_APIENTRY glVertexAttribL4dv(GLuint index, const GLdouble *v)
+{
+ return GL_VertexAttribL4dv(index, v);
+}
+
+void GL_APIENTRY
+glVertexAttribLPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer)
+{
+ return GL_VertexAttribLPointer(index, size, type, stride, pointer);
+}
+
+void GL_APIENTRY glViewportArrayv(GLuint first, GLsizei count, const GLfloat *v)
+{
+ return GL_ViewportArrayv(first, count, v);
+}
+
+void GL_APIENTRY glViewportIndexedf(GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h)
+{
+ return GL_ViewportIndexedf(index, x, y, w, h);
+}
+
+void GL_APIENTRY glViewportIndexedfv(GLuint index, const GLfloat *v)
+{
+ return GL_ViewportIndexedfv(index, v);
+}
+
+// GL 4.2
+void GL_APIENTRY glDrawArraysInstancedBaseInstance(GLenum mode,
+ GLint first,
+ GLsizei count,
+ GLsizei instancecount,
+ GLuint baseinstance)
+{
+ return GL_DrawArraysInstancedBaseInstance(mode, first, count, instancecount, baseinstance);
+}
+
+void GL_APIENTRY glDrawElementsInstancedBaseInstance(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLsizei instancecount,
+ GLuint baseinstance)
+{
+ return GL_DrawElementsInstancedBaseInstance(mode, count, type, indices, instancecount,
+ baseinstance);
+}
+
+void GL_APIENTRY glDrawElementsInstancedBaseVertexBaseInstance(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const void *indices,
+ GLsizei instancecount,
+ GLint basevertex,
+ GLuint baseinstance)
+{
+ return GL_DrawElementsInstancedBaseVertexBaseInstance(mode, count, type, indices, instancecount,
+ basevertex, baseinstance);
+}
+
+void GL_APIENTRY glDrawTransformFeedbackInstanced(GLenum mode, GLuint id, GLsizei instancecount)
+{
+ return GL_DrawTransformFeedbackInstanced(mode, id, instancecount);
+}
+
+void GL_APIENTRY glDrawTransformFeedbackStreamInstanced(GLenum mode,
+ GLuint id,
+ GLuint stream,
+ GLsizei instancecount)
+{
+ return GL_DrawTransformFeedbackStreamInstanced(mode, id, stream, instancecount);
+}
+
+void GL_APIENTRY glGetActiveAtomicCounterBufferiv(GLuint program,
+ GLuint bufferIndex,
+ GLenum pname,
+ GLint *params)
+{
+ return GL_GetActiveAtomicCounterBufferiv(program, bufferIndex, pname, params);
+}
+
+void GL_APIENTRY glTexStorage1D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width)
+{
+ return GL_TexStorage1D(target, levels, internalformat, width);
+}
+
+// GL 4.3
+void GL_APIENTRY glClearBufferData(GLenum target,
+ GLenum internalformat,
+ GLenum format,
+ GLenum type,
+ const void *data)
+{
+ return GL_ClearBufferData(target, internalformat, format, type, data);
+}
+
+void GL_APIENTRY glClearBufferSubData(GLenum target,
+ GLenum internalformat,
+ GLintptr offset,
+ GLsizeiptr size,
+ GLenum format,
+ GLenum type,
+ const void *data)
+{
+ return GL_ClearBufferSubData(target, internalformat, offset, size, format, type, data);
+}
+
+void GL_APIENTRY glGetInternalformati64v(GLenum target,
+ GLenum internalformat,
+ GLenum pname,
+ GLsizei count,
+ GLint64 *params)
+{
+ return GL_GetInternalformati64v(target, internalformat, pname, count, params);
+}
+
+GLint GL_APIENTRY glGetProgramResourceLocationIndex(GLuint program,
+ GLenum programInterface,
+ const GLchar *name)
+{
+ return GL_GetProgramResourceLocationIndex(program, programInterface, name);
+}
+
+void GL_APIENTRY glInvalidateBufferData(GLuint buffer)
+{
+ return GL_InvalidateBufferData(buffer);
+}
+
+void GL_APIENTRY glInvalidateBufferSubData(GLuint buffer, GLintptr offset, GLsizeiptr length)
+{
+ return GL_InvalidateBufferSubData(buffer, offset, length);
+}
+
+void GL_APIENTRY glInvalidateTexImage(GLuint texture, GLint level)
+{
+ return GL_InvalidateTexImage(texture, level);
+}
+
+void GL_APIENTRY glInvalidateTexSubImage(GLuint texture,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth)
+{
+ return GL_InvalidateTexSubImage(texture, level, xoffset, yoffset, zoffset, width, height,
+ depth);
+}
+
+void GL_APIENTRY glMultiDrawArraysIndirect(GLenum mode,
+ const void *indirect,
+ GLsizei drawcount,
+ GLsizei stride)
+{
+ return GL_MultiDrawArraysIndirect(mode, indirect, drawcount, stride);
+}
+
+void GL_APIENTRY glMultiDrawElementsIndirect(GLenum mode,
+ GLenum type,
+ const void *indirect,
+ GLsizei drawcount,
+ GLsizei stride)
+{
+ return GL_MultiDrawElementsIndirect(mode, type, indirect, drawcount, stride);
+}
+
+void GL_APIENTRY glShaderStorageBlockBinding(GLuint program,
+ GLuint storageBlockIndex,
+ GLuint storageBlockBinding)
+{
+ return GL_ShaderStorageBlockBinding(program, storageBlockIndex, storageBlockBinding);
+}
+
+void GL_APIENTRY glTextureView(GLuint texture,
+ GLenum target,
+ GLuint origtexture,
+ GLenum internalformat,
+ GLuint minlevel,
+ GLuint numlevels,
+ GLuint minlayer,
+ GLuint numlayers)
+{
+ return GL_TextureView(texture, target, origtexture, internalformat, minlevel, numlevels,
+ minlayer, numlayers);
+}
+
+void GL_APIENTRY glVertexAttribLFormat(GLuint attribindex,
+ GLint size,
+ GLenum type,
+ GLuint relativeoffset)
+{
+ return GL_VertexAttribLFormat(attribindex, size, type, relativeoffset);
+}
+
+// GL 4.4
+void GL_APIENTRY glBindBuffersBase(GLenum target,
+ GLuint first,
+ GLsizei count,
+ const GLuint *buffers)
+{
+ return GL_BindBuffersBase(target, first, count, buffers);
+}
+
+void GL_APIENTRY glBindBuffersRange(GLenum target,
+ GLuint first,
+ GLsizei count,
+ const GLuint *buffers,
+ const GLintptr *offsets,
+ const GLsizeiptr *sizes)
+{
+ return GL_BindBuffersRange(target, first, count, buffers, offsets, sizes);
+}
+
+void GL_APIENTRY glBindImageTextures(GLuint first, GLsizei count, const GLuint *textures)
+{
+ return GL_BindImageTextures(first, count, textures);
+}
+
+void GL_APIENTRY glBindSamplers(GLuint first, GLsizei count, const GLuint *samplers)
+{
+ return GL_BindSamplers(first, count, samplers);
+}
+
+void GL_APIENTRY glBindTextures(GLuint first, GLsizei count, const GLuint *textures)
+{
+ return GL_BindTextures(first, count, textures);
+}
+
+void GL_APIENTRY glBindVertexBuffers(GLuint first,
+ GLsizei count,
+ const GLuint *buffers,
+ const GLintptr *offsets,
+ const GLsizei *strides)
+{
+ return GL_BindVertexBuffers(first, count, buffers, offsets, strides);
+}
+
+void GL_APIENTRY glBufferStorage(GLenum target, GLsizeiptr size, const void *data, GLbitfield flags)
+{
+ return GL_BufferStorage(target, size, data, flags);
+}
+
+void GL_APIENTRY
+glClearTexImage(GLuint texture, GLint level, GLenum format, GLenum type, const void *data)
+{
+ return GL_ClearTexImage(texture, level, format, type, data);
+}
+
+void GL_APIENTRY glClearTexSubImage(GLuint texture,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ const void *data)
+{
+ return GL_ClearTexSubImage(texture, level, xoffset, yoffset, zoffset, width, height, depth,
+ format, type, data);
+}
+
+// GL 4.5
+void GL_APIENTRY glBindTextureUnit(GLuint unit, GLuint texture)
+{
+ return GL_BindTextureUnit(unit, texture);
+}
+
+void GL_APIENTRY glBlitNamedFramebuffer(GLuint readFramebuffer,
+ GLuint drawFramebuffer,
+ GLint srcX0,
+ GLint srcY0,
+ GLint srcX1,
+ GLint srcY1,
+ GLint dstX0,
+ GLint dstY0,
+ GLint dstX1,
+ GLint dstY1,
+ GLbitfield mask,
+ GLenum filter)
+{
+ return GL_BlitNamedFramebuffer(readFramebuffer, drawFramebuffer, srcX0, srcY0, srcX1, srcY1,
+ dstX0, dstY0, dstX1, dstY1, mask, filter);
+}
+
+GLenum GL_APIENTRY glCheckNamedFramebufferStatus(GLuint framebuffer, GLenum target)
+{
+ return GL_CheckNamedFramebufferStatus(framebuffer, target);
+}
+
+void GL_APIENTRY glClearNamedBufferData(GLuint buffer,
+ GLenum internalformat,
+ GLenum format,
+ GLenum type,
+ const void *data)
+{
+ return GL_ClearNamedBufferData(buffer, internalformat, format, type, data);
+}
+
+void GL_APIENTRY glClearNamedBufferSubData(GLuint buffer,
+ GLenum internalformat,
+ GLintptr offset,
+ GLsizeiptr size,
+ GLenum format,
+ GLenum type,
+ const void *data)
+{
+ return GL_ClearNamedBufferSubData(buffer, internalformat, offset, size, format, type, data);
+}
+
+void GL_APIENTRY glClearNamedFramebufferfi(GLuint framebuffer,
+ GLenum buffer,
+ GLint drawbuffer,
+ GLfloat depth,
+ GLint stencil)
+{
+ return GL_ClearNamedFramebufferfi(framebuffer, buffer, drawbuffer, depth, stencil);
+}
+
+void GL_APIENTRY glClearNamedFramebufferfv(GLuint framebuffer,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLfloat *value)
+{
+ return GL_ClearNamedFramebufferfv(framebuffer, buffer, drawbuffer, value);
+}
+
+void GL_APIENTRY glClearNamedFramebufferiv(GLuint framebuffer,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLint *value)
+{
+ return GL_ClearNamedFramebufferiv(framebuffer, buffer, drawbuffer, value);
+}
+
+void GL_APIENTRY glClearNamedFramebufferuiv(GLuint framebuffer,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLuint *value)
+{
+ return GL_ClearNamedFramebufferuiv(framebuffer, buffer, drawbuffer, value);
+}
+
+void GL_APIENTRY glClipControl(GLenum origin, GLenum depth)
+{
+ return GL_ClipControl(origin, depth);
+}
+
+void GL_APIENTRY glCompressedTextureSubImage1D(GLuint texture,
+ GLint level,
+ GLint xoffset,
+ GLsizei width,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data)
+{
+ return GL_CompressedTextureSubImage1D(texture, level, xoffset, width, format, imageSize, data);
+}
+
+void GL_APIENTRY glCompressedTextureSubImage2D(GLuint texture,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data)
+{
+ return GL_CompressedTextureSubImage2D(texture, level, xoffset, yoffset, width, height, format,
+ imageSize, data);
+}
+
+void GL_APIENTRY glCompressedTextureSubImage3D(GLuint texture,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLsizei imageSize,
+ const void *data)
+{
+ return GL_CompressedTextureSubImage3D(texture, level, xoffset, yoffset, zoffset, width, height,
+ depth, format, imageSize, data);
+}
+
+void GL_APIENTRY glCopyNamedBufferSubData(GLuint readBuffer,
+ GLuint writeBuffer,
+ GLintptr readOffset,
+ GLintptr writeOffset,
+ GLsizeiptr size)
+{
+ return GL_CopyNamedBufferSubData(readBuffer, writeBuffer, readOffset, writeOffset, size);
+}
+
+void GL_APIENTRY
+glCopyTextureSubImage1D(GLuint texture, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width)
+{
+ return GL_CopyTextureSubImage1D(texture, level, xoffset, x, y, width);
+}
+
+void GL_APIENTRY glCopyTextureSubImage2D(GLuint texture,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height)
+{
+ return GL_CopyTextureSubImage2D(texture, level, xoffset, yoffset, x, y, width, height);
+}
+
+void GL_APIENTRY glCopyTextureSubImage3D(GLuint texture,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height)
+{
+ return GL_CopyTextureSubImage3D(texture, level, xoffset, yoffset, zoffset, x, y, width, height);
+}
+
+void GL_APIENTRY glCreateBuffers(GLsizei n, GLuint *buffers)
+{
+ return GL_CreateBuffers(n, buffers);
+}
+
+void GL_APIENTRY glCreateFramebuffers(GLsizei n, GLuint *framebuffers)
+{
+ return GL_CreateFramebuffers(n, framebuffers);
+}
+
+void GL_APIENTRY glCreateProgramPipelines(GLsizei n, GLuint *pipelines)
+{
+ return GL_CreateProgramPipelines(n, pipelines);
+}
+
+void GL_APIENTRY glCreateQueries(GLenum target, GLsizei n, GLuint *ids)
+{
+ return GL_CreateQueries(target, n, ids);
+}
+
+void GL_APIENTRY glCreateRenderbuffers(GLsizei n, GLuint *renderbuffers)
+{
+ return GL_CreateRenderbuffers(n, renderbuffers);
+}
+
+void GL_APIENTRY glCreateSamplers(GLsizei n, GLuint *samplers)
+{
+ return GL_CreateSamplers(n, samplers);
+}
+
+void GL_APIENTRY glCreateTextures(GLenum target, GLsizei n, GLuint *textures)
+{
+ return GL_CreateTextures(target, n, textures);
+}
+
+void GL_APIENTRY glCreateTransformFeedbacks(GLsizei n, GLuint *ids)
+{
+ return GL_CreateTransformFeedbacks(n, ids);
+}
+
+void GL_APIENTRY glCreateVertexArrays(GLsizei n, GLuint *arrays)
+{
+ return GL_CreateVertexArrays(n, arrays);
+}
+
+void GL_APIENTRY glDisableVertexArrayAttrib(GLuint vaobj, GLuint index)
+{
+ return GL_DisableVertexArrayAttrib(vaobj, index);
+}
+
+void GL_APIENTRY glEnableVertexArrayAttrib(GLuint vaobj, GLuint index)
+{
+ return GL_EnableVertexArrayAttrib(vaobj, index);
+}
+
+void GL_APIENTRY glFlushMappedNamedBufferRange(GLuint buffer, GLintptr offset, GLsizeiptr length)
+{
+ return GL_FlushMappedNamedBufferRange(buffer, offset, length);
+}
+
+void GL_APIENTRY glGenerateTextureMipmap(GLuint texture)
+{
+ return GL_GenerateTextureMipmap(texture);
+}
+
+void GL_APIENTRY glGetCompressedTextureImage(GLuint texture,
+ GLint level,
+ GLsizei bufSize,
+ void *pixels)
+{
+ return GL_GetCompressedTextureImage(texture, level, bufSize, pixels);
+}
+
+void GL_APIENTRY glGetCompressedTextureSubImage(GLuint texture,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLsizei bufSize,
+ void *pixels)
+{
+ return GL_GetCompressedTextureSubImage(texture, level, xoffset, yoffset, zoffset, width, height,
+ depth, bufSize, pixels);
+}
+
+void GL_APIENTRY glGetNamedBufferParameteri64v(GLuint buffer, GLenum pname, GLint64 *params)
+{
+ return GL_GetNamedBufferParameteri64v(buffer, pname, params);
+}
+
+void GL_APIENTRY glGetNamedBufferParameteriv(GLuint buffer, GLenum pname, GLint *params)
+{
+ return GL_GetNamedBufferParameteriv(buffer, pname, params);
+}
+
+void GL_APIENTRY glGetNamedBufferPointerv(GLuint buffer, GLenum pname, void **params)
+{
+ return GL_GetNamedBufferPointerv(buffer, pname, params);
+}
+
+void GL_APIENTRY glGetNamedBufferSubData(GLuint buffer,
+ GLintptr offset,
+ GLsizeiptr size,
+ void *data)
+{
+ return GL_GetNamedBufferSubData(buffer, offset, size, data);
+}
+
+void GL_APIENTRY glGetNamedFramebufferAttachmentParameteriv(GLuint framebuffer,
+ GLenum attachment,
+ GLenum pname,
+ GLint *params)
+{
+ return GL_GetNamedFramebufferAttachmentParameteriv(framebuffer, attachment, pname, params);
+}
+
+void GL_APIENTRY glGetNamedFramebufferParameteriv(GLuint framebuffer, GLenum pname, GLint *param)
+{
+ return GL_GetNamedFramebufferParameteriv(framebuffer, pname, param);
+}
+
+void GL_APIENTRY glGetNamedRenderbufferParameteriv(GLuint renderbuffer, GLenum pname, GLint *params)
+{
+ return GL_GetNamedRenderbufferParameteriv(renderbuffer, pname, params);
+}
+
+void GL_APIENTRY glGetQueryBufferObjecti64v(GLuint id, GLuint buffer, GLenum pname, GLintptr offset)
+{
+ return GL_GetQueryBufferObjecti64v(id, buffer, pname, offset);
+}
+
+void GL_APIENTRY glGetQueryBufferObjectiv(GLuint id, GLuint buffer, GLenum pname, GLintptr offset)
+{
+ return GL_GetQueryBufferObjectiv(id, buffer, pname, offset);
+}
+
+void GL_APIENTRY glGetQueryBufferObjectui64v(GLuint id,
+ GLuint buffer,
+ GLenum pname,
+ GLintptr offset)
+{
+ return GL_GetQueryBufferObjectui64v(id, buffer, pname, offset);
+}
+
+void GL_APIENTRY glGetQueryBufferObjectuiv(GLuint id, GLuint buffer, GLenum pname, GLintptr offset)
+{
+ return GL_GetQueryBufferObjectuiv(id, buffer, pname, offset);
+}
+
+void GL_APIENTRY glGetTextureImage(GLuint texture,
+ GLint level,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ void *pixels)
+{
+ return GL_GetTextureImage(texture, level, format, type, bufSize, pixels);
+}
+
+void GL_APIENTRY glGetTextureLevelParameterfv(GLuint texture,
+ GLint level,
+ GLenum pname,
+ GLfloat *params)
+{
+ return GL_GetTextureLevelParameterfv(texture, level, pname, params);
+}
+
+void GL_APIENTRY glGetTextureLevelParameteriv(GLuint texture,
+ GLint level,
+ GLenum pname,
+ GLint *params)
+{
+ return GL_GetTextureLevelParameteriv(texture, level, pname, params);
+}
+
+void GL_APIENTRY glGetTextureParameterIiv(GLuint texture, GLenum pname, GLint *params)
+{
+ return GL_GetTextureParameterIiv(texture, pname, params);
+}
+
+void GL_APIENTRY glGetTextureParameterIuiv(GLuint texture, GLenum pname, GLuint *params)
+{
+ return GL_GetTextureParameterIuiv(texture, pname, params);
+}
+
+void GL_APIENTRY glGetTextureParameterfv(GLuint texture, GLenum pname, GLfloat *params)
+{
+ return GL_GetTextureParameterfv(texture, pname, params);
+}
+
+void GL_APIENTRY glGetTextureParameteriv(GLuint texture, GLenum pname, GLint *params)
+{
+ return GL_GetTextureParameteriv(texture, pname, params);
+}
+
+void GL_APIENTRY glGetTextureSubImage(GLuint texture,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ void *pixels)
+{
+ return GL_GetTextureSubImage(texture, level, xoffset, yoffset, zoffset, width, height, depth,
+ format, type, bufSize, pixels);
+}
+
+void GL_APIENTRY glGetTransformFeedbacki64_v(GLuint xfb, GLenum pname, GLuint index, GLint64 *param)
+{
+ return GL_GetTransformFeedbacki64_v(xfb, pname, index, param);
+}
+
+void GL_APIENTRY glGetTransformFeedbacki_v(GLuint xfb, GLenum pname, GLuint index, GLint *param)
+{
+ return GL_GetTransformFeedbacki_v(xfb, pname, index, param);
+}
+
+void GL_APIENTRY glGetTransformFeedbackiv(GLuint xfb, GLenum pname, GLint *param)
+{
+ return GL_GetTransformFeedbackiv(xfb, pname, param);
+}
+
+void GL_APIENTRY glGetVertexArrayIndexed64iv(GLuint vaobj,
+ GLuint index,
+ GLenum pname,
+ GLint64 *param)
+{
+ return GL_GetVertexArrayIndexed64iv(vaobj, index, pname, param);
+}
+
+void GL_APIENTRY glGetVertexArrayIndexediv(GLuint vaobj, GLuint index, GLenum pname, GLint *param)
+{
+ return GL_GetVertexArrayIndexediv(vaobj, index, pname, param);
+}
+
+void GL_APIENTRY glGetVertexArrayiv(GLuint vaobj, GLenum pname, GLint *param)
+{
+ return GL_GetVertexArrayiv(vaobj, pname, param);
+}
+
+void GL_APIENTRY
+glGetnColorTable(GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *table)
+{
+ return GL_GetnColorTable(target, format, type, bufSize, table);
+}
+
+void GL_APIENTRY glGetnCompressedTexImage(GLenum target, GLint lod, GLsizei bufSize, void *pixels)
+{
+ return GL_GetnCompressedTexImage(target, lod, bufSize, pixels);
+}
+
+void GL_APIENTRY
+glGetnConvolutionFilter(GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *image)
+{
+ return GL_GetnConvolutionFilter(target, format, type, bufSize, image);
+}
+
+void GL_APIENTRY glGetnHistogram(GLenum target,
+ GLboolean reset,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ void *values)
+{
+ return GL_GetnHistogram(target, reset, format, type, bufSize, values);
+}
+
+void GL_APIENTRY glGetnMapdv(GLenum target, GLenum query, GLsizei bufSize, GLdouble *v)
+{
+ return GL_GetnMapdv(target, query, bufSize, v);
+}
+
+void GL_APIENTRY glGetnMapfv(GLenum target, GLenum query, GLsizei bufSize, GLfloat *v)
+{
+ return GL_GetnMapfv(target, query, bufSize, v);
+}
+
+void GL_APIENTRY glGetnMapiv(GLenum target, GLenum query, GLsizei bufSize, GLint *v)
+{
+ return GL_GetnMapiv(target, query, bufSize, v);
+}
+
+void GL_APIENTRY glGetnMinmax(GLenum target,
+ GLboolean reset,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ void *values)
+{
+ return GL_GetnMinmax(target, reset, format, type, bufSize, values);
+}
+
+void GL_APIENTRY glGetnPixelMapfv(GLenum map, GLsizei bufSize, GLfloat *values)
+{
+ return GL_GetnPixelMapfv(map, bufSize, values);
+}
+
+void GL_APIENTRY glGetnPixelMapuiv(GLenum map, GLsizei bufSize, GLuint *values)
+{
+ return GL_GetnPixelMapuiv(map, bufSize, values);
+}
+
+void GL_APIENTRY glGetnPixelMapusv(GLenum map, GLsizei bufSize, GLushort *values)
+{
+ return GL_GetnPixelMapusv(map, bufSize, values);
+}
+
+void GL_APIENTRY glGetnPolygonStipple(GLsizei bufSize, GLubyte *pattern)
+{
+ return GL_GetnPolygonStipple(bufSize, pattern);
+}
+
+void GL_APIENTRY glGetnSeparableFilter(GLenum target,
+ GLenum format,
+ GLenum type,
+ GLsizei rowBufSize,
+ void *row,
+ GLsizei columnBufSize,
+ void *column,
+ void *span)
+{
+ return GL_GetnSeparableFilter(target, format, type, rowBufSize, row, columnBufSize, column,
+ span);
+}
+
+void GL_APIENTRY glGetnTexImage(GLenum target,
+ GLint level,
+ GLenum format,
+ GLenum type,
+ GLsizei bufSize,
+ void *pixels)
+{
+ return GL_GetnTexImage(target, level, format, type, bufSize, pixels);
+}
+
+void GL_APIENTRY glGetnUniformdv(GLuint program, GLint location, GLsizei bufSize, GLdouble *params)
+{
+ return GL_GetnUniformdv(program, location, bufSize, params);
+}
+
+void GL_APIENTRY glInvalidateNamedFramebufferData(GLuint framebuffer,
+ GLsizei numAttachments,
+ const GLenum *attachments)
+{
+ return GL_InvalidateNamedFramebufferData(framebuffer, numAttachments, attachments);
+}
+
+void GL_APIENTRY glInvalidateNamedFramebufferSubData(GLuint framebuffer,
+ GLsizei numAttachments,
+ const GLenum *attachments,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height)
+{
+ return GL_InvalidateNamedFramebufferSubData(framebuffer, numAttachments, attachments, x, y,
+ width, height);
+}
+
+void *GL_APIENTRY glMapNamedBuffer(GLuint buffer, GLenum access)
+{
+ return GL_MapNamedBuffer(buffer, access);
+}
+
+void *GL_APIENTRY glMapNamedBufferRange(GLuint buffer,
+ GLintptr offset,
+ GLsizeiptr length,
+ GLbitfield access)
+{
+ return GL_MapNamedBufferRange(buffer, offset, length, access);
+}
+
+void GL_APIENTRY glNamedBufferData(GLuint buffer, GLsizeiptr size, const void *data, GLenum usage)
+{
+ return GL_NamedBufferData(buffer, size, data, usage);
+}
+
+void GL_APIENTRY glNamedBufferStorage(GLuint buffer,
+ GLsizeiptr size,
+ const void *data,
+ GLbitfield flags)
+{
+ return GL_NamedBufferStorage(buffer, size, data, flags);
+}
+
+void GL_APIENTRY glNamedBufferSubData(GLuint buffer,
+ GLintptr offset,
+ GLsizeiptr size,
+ const void *data)
+{
+ return GL_NamedBufferSubData(buffer, offset, size, data);
+}
+
+void GL_APIENTRY glNamedFramebufferDrawBuffer(GLuint framebuffer, GLenum buf)
+{
+ return GL_NamedFramebufferDrawBuffer(framebuffer, buf);
+}
+
+void GL_APIENTRY glNamedFramebufferDrawBuffers(GLuint framebuffer, GLsizei n, const GLenum *bufs)
+{
+ return GL_NamedFramebufferDrawBuffers(framebuffer, n, bufs);
+}
+
+void GL_APIENTRY glNamedFramebufferParameteri(GLuint framebuffer, GLenum pname, GLint param)
+{
+ return GL_NamedFramebufferParameteri(framebuffer, pname, param);
+}
+
+void GL_APIENTRY glNamedFramebufferReadBuffer(GLuint framebuffer, GLenum src)
+{
+ return GL_NamedFramebufferReadBuffer(framebuffer, src);
+}
+
+void GL_APIENTRY glNamedFramebufferRenderbuffer(GLuint framebuffer,
+ GLenum attachment,
+ GLenum renderbuffertarget,
+ GLuint renderbuffer)
+{
+ return GL_NamedFramebufferRenderbuffer(framebuffer, attachment, renderbuffertarget,
+ renderbuffer);
+}
+
+void GL_APIENTRY glNamedFramebufferTexture(GLuint framebuffer,
+ GLenum attachment,
+ GLuint texture,
+ GLint level)
+{
+ return GL_NamedFramebufferTexture(framebuffer, attachment, texture, level);
+}
+
+void GL_APIENTRY glNamedFramebufferTextureLayer(GLuint framebuffer,
+ GLenum attachment,
+ GLuint texture,
+ GLint level,
+ GLint layer)
+{
+ return GL_NamedFramebufferTextureLayer(framebuffer, attachment, texture, level, layer);
+}
+
+void GL_APIENTRY glNamedRenderbufferStorage(GLuint renderbuffer,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height)
+{
+ return GL_NamedRenderbufferStorage(renderbuffer, internalformat, width, height);
+}
+
+void GL_APIENTRY glNamedRenderbufferStorageMultisample(GLuint renderbuffer,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height)
+{
+ return GL_NamedRenderbufferStorageMultisample(renderbuffer, samples, internalformat, width,
+ height);
+}
+
+void GL_APIENTRY glTextureBarrier()
+{
+ return GL_TextureBarrier();
+}
+
+void GL_APIENTRY glTextureBuffer(GLuint texture, GLenum internalformat, GLuint buffer)
+{
+ return GL_TextureBuffer(texture, internalformat, buffer);
+}
+
+void GL_APIENTRY glTextureBufferRange(GLuint texture,
+ GLenum internalformat,
+ GLuint buffer,
+ GLintptr offset,
+ GLsizeiptr size)
+{
+ return GL_TextureBufferRange(texture, internalformat, buffer, offset, size);
+}
+
+void GL_APIENTRY glTextureParameterIiv(GLuint texture, GLenum pname, const GLint *params)
+{
+ return GL_TextureParameterIiv(texture, pname, params);
+}
+
+void GL_APIENTRY glTextureParameterIuiv(GLuint texture, GLenum pname, const GLuint *params)
+{
+ return GL_TextureParameterIuiv(texture, pname, params);
+}
+
+void GL_APIENTRY glTextureParameterf(GLuint texture, GLenum pname, GLfloat param)
+{
+ return GL_TextureParameterf(texture, pname, param);
+}
+
+void GL_APIENTRY glTextureParameterfv(GLuint texture, GLenum pname, const GLfloat *param)
+{
+ return GL_TextureParameterfv(texture, pname, param);
+}
+
+void GL_APIENTRY glTextureParameteri(GLuint texture, GLenum pname, GLint param)
+{
+ return GL_TextureParameteri(texture, pname, param);
+}
+
+void GL_APIENTRY glTextureParameteriv(GLuint texture, GLenum pname, const GLint *param)
+{
+ return GL_TextureParameteriv(texture, pname, param);
+}
+
+void GL_APIENTRY glTextureStorage1D(GLuint texture,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width)
+{
+ return GL_TextureStorage1D(texture, levels, internalformat, width);
+}
+
+void GL_APIENTRY glTextureStorage2D(GLuint texture,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height)
+{
+ return GL_TextureStorage2D(texture, levels, internalformat, width, height);
+}
+
+void GL_APIENTRY glTextureStorage2DMultisample(GLuint texture,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLboolean fixedsamplelocations)
+{
+ return GL_TextureStorage2DMultisample(texture, samples, internalformat, width, height,
+ fixedsamplelocations);
+}
+
+void GL_APIENTRY glTextureStorage3D(GLuint texture,
+ GLsizei levels,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth)
+{
+ return GL_TextureStorage3D(texture, levels, internalformat, width, height, depth);
+}
+
+void GL_APIENTRY glTextureStorage3DMultisample(GLuint texture,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLboolean fixedsamplelocations)
+{
+ return GL_TextureStorage3DMultisample(texture, samples, internalformat, width, height, depth,
+ fixedsamplelocations);
+}
+
+void GL_APIENTRY glTextureSubImage1D(GLuint texture,
+ GLint level,
+ GLint xoffset,
+ GLsizei width,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ return GL_TextureSubImage1D(texture, level, xoffset, width, format, type, pixels);
+}
+
+void GL_APIENTRY glTextureSubImage2D(GLuint texture,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ return GL_TextureSubImage2D(texture, level, xoffset, yoffset, width, height, format, type,
+ pixels);
+}
+
+void GL_APIENTRY glTextureSubImage3D(GLuint texture,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint zoffset,
+ GLsizei width,
+ GLsizei height,
+ GLsizei depth,
+ GLenum format,
+ GLenum type,
+ const void *pixels)
+{
+ return GL_TextureSubImage3D(texture, level, xoffset, yoffset, zoffset, width, height, depth,
+ format, type, pixels);
+}
+
+void GL_APIENTRY glTransformFeedbackBufferBase(GLuint xfb, GLuint index, GLuint buffer)
+{
+ return GL_TransformFeedbackBufferBase(xfb, index, buffer);
+}
+
+void GL_APIENTRY glTransformFeedbackBufferRange(GLuint xfb,
+ GLuint index,
+ GLuint buffer,
+ GLintptr offset,
+ GLsizeiptr size)
+{
+ return GL_TransformFeedbackBufferRange(xfb, index, buffer, offset, size);
+}
+
+GLboolean GL_APIENTRY glUnmapNamedBuffer(GLuint buffer)
+{
+ return GL_UnmapNamedBuffer(buffer);
+}
+
+void GL_APIENTRY glVertexArrayAttribBinding(GLuint vaobj, GLuint attribindex, GLuint bindingindex)
+{
+ return GL_VertexArrayAttribBinding(vaobj, attribindex, bindingindex);
+}
+
+void GL_APIENTRY glVertexArrayAttribFormat(GLuint vaobj,
+ GLuint attribindex,
+ GLint size,
+ GLenum type,
+ GLboolean normalized,
+ GLuint relativeoffset)
+{
+ return GL_VertexArrayAttribFormat(vaobj, attribindex, size, type, normalized, relativeoffset);
+}
+
+void GL_APIENTRY glVertexArrayAttribIFormat(GLuint vaobj,
+ GLuint attribindex,
+ GLint size,
+ GLenum type,
+ GLuint relativeoffset)
+{
+ return GL_VertexArrayAttribIFormat(vaobj, attribindex, size, type, relativeoffset);
+}
+
+void GL_APIENTRY glVertexArrayAttribLFormat(GLuint vaobj,
+ GLuint attribindex,
+ GLint size,
+ GLenum type,
+ GLuint relativeoffset)
+{
+ return GL_VertexArrayAttribLFormat(vaobj, attribindex, size, type, relativeoffset);
+}
+
+void GL_APIENTRY glVertexArrayBindingDivisor(GLuint vaobj, GLuint bindingindex, GLuint divisor)
+{
+ return GL_VertexArrayBindingDivisor(vaobj, bindingindex, divisor);
+}
+
+void GL_APIENTRY glVertexArrayElementBuffer(GLuint vaobj, GLuint buffer)
+{
+ return GL_VertexArrayElementBuffer(vaobj, buffer);
+}
+
+void GL_APIENTRY glVertexArrayVertexBuffer(GLuint vaobj,
+ GLuint bindingindex,
+ GLuint buffer,
+ GLintptr offset,
+ GLsizei stride)
+{
+ return GL_VertexArrayVertexBuffer(vaobj, bindingindex, buffer, offset, stride);
+}
+
+void GL_APIENTRY glVertexArrayVertexBuffers(GLuint vaobj,
+ GLuint first,
+ GLsizei count,
+ const GLuint *buffers,
+ const GLintptr *offsets,
+ const GLsizei *strides)
+{
+ return GL_VertexArrayVertexBuffers(vaobj, first, count, buffers, offsets, strides);
+}
+
+// GL 4.6
+void GL_APIENTRY glMultiDrawArraysIndirectCount(GLenum mode,
+ const void *indirect,
+ GLintptr drawcount,
+ GLsizei maxdrawcount,
+ GLsizei stride)
+{
+ return GL_MultiDrawArraysIndirectCount(mode, indirect, drawcount, maxdrawcount, stride);
+}
+
+void GL_APIENTRY glMultiDrawElementsIndirectCount(GLenum mode,
+ GLenum type,
+ const void *indirect,
+ GLintptr drawcount,
+ GLsizei maxdrawcount,
+ GLsizei stride)
+{
+ return GL_MultiDrawElementsIndirectCount(mode, type, indirect, drawcount, maxdrawcount, stride);
+}
+
+void GL_APIENTRY glPolygonOffsetClamp(GLfloat factor, GLfloat units, GLfloat clamp)
+{
+ return GL_PolygonOffsetClamp(factor, units, clamp);
+}
+
+void GL_APIENTRY glSpecializeShader(GLuint shader,
+ const GLchar *pEntryPoint,
+ GLuint numSpecializationConstants,
+ const GLuint *pConstantIndex,
+ const GLuint *pConstantValue)
+{
+ return GL_SpecializeShader(shader, pEntryPoint, numSpecializationConstants, pConstantIndex,
+ pConstantValue);
+}
+
+#endif // defined(ANGLE_ENABLE_GL_DESKTOP_FRONTEND)
+} // extern "C"
diff --git a/gfx/angle/checkout/src/libGLESv2/libGLESv2_autogen.def b/gfx/angle/checkout/src/libGLESv2/libGLESv2_autogen.def
new file mode 100644
index 0000000000..c192344a35
--- /dev/null
+++ b/gfx/angle/checkout/src/libGLESv2/libGLESv2_autogen.def
@@ -0,0 +1,1362 @@
+; GENERATED FILE - DO NOT EDIT.
+; Generated by generate_entry_points.py using data from Khronos and ANGLE XML files.
+;
+; Copyright 2020 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.
+LIBRARY libGLESv2
+EXPORTS
+
+ ; OpenGL ES 2.0
+ glActiveTexture
+ glAttachShader
+ glBindAttribLocation
+ glBindBuffer
+ glBindFramebuffer
+ glBindRenderbuffer
+ glBindTexture
+ glBlendColor
+ glBlendEquation
+ glBlendEquationSeparate
+ glBlendFunc
+ glBlendFuncSeparate
+ glBufferData
+ glBufferSubData
+ glCheckFramebufferStatus
+ glClear
+ glClearColor
+ glClearDepthf
+ glClearStencil
+ glColorMask
+ glCompileShader
+ glCompressedTexImage2D
+ glCompressedTexSubImage2D
+ glCopyTexImage2D
+ glCopyTexSubImage2D
+ glCreateProgram
+ glCreateShader
+ glCullFace
+ glDeleteBuffers
+ glDeleteFramebuffers
+ glDeleteProgram
+ glDeleteRenderbuffers
+ glDeleteShader
+ glDeleteTextures
+ glDepthFunc
+ glDepthMask
+ glDepthRangef
+ glDetachShader
+ glDisable
+ glDisableVertexAttribArray
+ glDrawArrays
+ glDrawElements
+ glEnable
+ glEnableVertexAttribArray
+ glFinish
+ glFlush
+ glFramebufferRenderbuffer
+ glFramebufferTexture2D
+ glFrontFace
+ glGenBuffers
+ glGenFramebuffers
+ glGenRenderbuffers
+ glGenTextures
+ glGenerateMipmap
+ glGetActiveAttrib
+ glGetActiveUniform
+ glGetAttachedShaders
+ glGetAttribLocation
+ glGetBooleanv
+ glGetBufferParameteriv
+ glGetError
+ glGetFloatv
+ glGetFramebufferAttachmentParameteriv
+ glGetIntegerv
+ glGetProgramInfoLog
+ glGetProgramiv
+ glGetRenderbufferParameteriv
+ glGetShaderInfoLog
+ glGetShaderPrecisionFormat
+ glGetShaderSource
+ glGetShaderiv
+ glGetString
+ glGetTexParameterfv
+ glGetTexParameteriv
+ glGetUniformLocation
+ glGetUniformfv
+ glGetUniformiv
+ glGetVertexAttribPointerv
+ glGetVertexAttribfv
+ glGetVertexAttribiv
+ glHint
+ glIsBuffer
+ glIsEnabled
+ glIsFramebuffer
+ glIsProgram
+ glIsRenderbuffer
+ glIsShader
+ glIsTexture
+ glLineWidth
+ glLinkProgram
+ glPixelStorei
+ glPolygonOffset
+ glReadPixels
+ glReleaseShaderCompiler
+ glRenderbufferStorage
+ glSampleCoverage
+ glScissor
+ glShaderBinary
+ glShaderSource
+ glStencilFunc
+ glStencilFuncSeparate
+ glStencilMask
+ glStencilMaskSeparate
+ glStencilOp
+ glStencilOpSeparate
+ glTexImage2D
+ glTexParameterf
+ glTexParameterfv
+ glTexParameteri
+ glTexParameteriv
+ glTexSubImage2D
+ glUniform1f
+ glUniform1fv
+ glUniform1i
+ glUniform1iv
+ glUniform2f
+ glUniform2fv
+ glUniform2i
+ glUniform2iv
+ glUniform3f
+ glUniform3fv
+ glUniform3i
+ glUniform3iv
+ glUniform4f
+ glUniform4fv
+ glUniform4i
+ glUniform4iv
+ glUniformMatrix2fv
+ glUniformMatrix3fv
+ glUniformMatrix4fv
+ glUseProgram
+ glValidateProgram
+ glVertexAttrib1f
+ glVertexAttrib1fv
+ glVertexAttrib2f
+ glVertexAttrib2fv
+ glVertexAttrib3f
+ glVertexAttrib3fv
+ glVertexAttrib4f
+ glVertexAttrib4fv
+ glVertexAttribPointer
+ glViewport
+
+ ; OpenGL ES 3.0
+ glBeginQuery
+ glBeginTransformFeedback
+ glBindBufferBase
+ glBindBufferRange
+ glBindSampler
+ glBindTransformFeedback
+ glBindVertexArray
+ glBlitFramebuffer
+ glClearBufferfi
+ glClearBufferfv
+ glClearBufferiv
+ glClearBufferuiv
+ glClientWaitSync
+ glCompressedTexImage3D
+ glCompressedTexSubImage3D
+ glCopyBufferSubData
+ glCopyTexSubImage3D
+ glDeleteQueries
+ glDeleteSamplers
+ glDeleteSync
+ glDeleteTransformFeedbacks
+ glDeleteVertexArrays
+ glDrawArraysInstanced
+ glDrawBuffers
+ glDrawElementsInstanced
+ glDrawRangeElements
+ glEndQuery
+ glEndTransformFeedback
+ glFenceSync
+ glFlushMappedBufferRange
+ glFramebufferTextureLayer
+ glGenQueries
+ glGenSamplers
+ glGenTransformFeedbacks
+ glGenVertexArrays
+ glGetActiveUniformBlockName
+ glGetActiveUniformBlockiv
+ glGetActiveUniformsiv
+ glGetBufferParameteri64v
+ glGetBufferPointerv
+ glGetFragDataLocation
+ glGetInteger64i_v
+ glGetInteger64v
+ glGetIntegeri_v
+ glGetInternalformativ
+ glGetProgramBinary
+ glGetQueryObjectuiv
+ glGetQueryiv
+ glGetSamplerParameterfv
+ glGetSamplerParameteriv
+ glGetStringi
+ glGetSynciv
+ glGetTransformFeedbackVarying
+ glGetUniformBlockIndex
+ glGetUniformIndices
+ glGetUniformuiv
+ glGetVertexAttribIiv
+ glGetVertexAttribIuiv
+ glInvalidateFramebuffer
+ glInvalidateSubFramebuffer
+ glIsQuery
+ glIsSampler
+ glIsSync
+ glIsTransformFeedback
+ glIsVertexArray
+ glMapBufferRange
+ glPauseTransformFeedback
+ glProgramBinary
+ glProgramParameteri
+ glReadBuffer
+ glRenderbufferStorageMultisample
+ glResumeTransformFeedback
+ glSamplerParameterf
+ glSamplerParameterfv
+ glSamplerParameteri
+ glSamplerParameteriv
+ glTexImage3D
+ glTexStorage2D
+ glTexStorage3D
+ glTexSubImage3D
+ glTransformFeedbackVaryings
+ glUniform1ui
+ glUniform1uiv
+ glUniform2ui
+ glUniform2uiv
+ glUniform3ui
+ glUniform3uiv
+ glUniform4ui
+ glUniform4uiv
+ glUniformBlockBinding
+ glUniformMatrix2x3fv
+ glUniformMatrix2x4fv
+ glUniformMatrix3x2fv
+ glUniformMatrix3x4fv
+ glUniformMatrix4x2fv
+ glUniformMatrix4x3fv
+ glUnmapBuffer
+ glVertexAttribDivisor
+ glVertexAttribI4i
+ glVertexAttribI4iv
+ glVertexAttribI4ui
+ glVertexAttribI4uiv
+ glVertexAttribIPointer
+ glWaitSync
+
+ ; OpenGL ES 3.1
+ glActiveShaderProgram
+ glBindImageTexture
+ glBindProgramPipeline
+ glBindVertexBuffer
+ glCreateShaderProgramv
+ glDeleteProgramPipelines
+ glDispatchCompute
+ glDispatchComputeIndirect
+ glDrawArraysIndirect
+ glDrawElementsIndirect
+ glFramebufferParameteri
+ glGenProgramPipelines
+ glGetBooleani_v
+ glGetFramebufferParameteriv
+ glGetMultisamplefv
+ glGetProgramInterfaceiv
+ glGetProgramPipelineInfoLog
+ glGetProgramPipelineiv
+ glGetProgramResourceIndex
+ glGetProgramResourceLocation
+ glGetProgramResourceName
+ glGetProgramResourceiv
+ glGetTexLevelParameterfv
+ glGetTexLevelParameteriv
+ glIsProgramPipeline
+ glMemoryBarrier
+ glMemoryBarrierByRegion
+ glProgramUniform1f
+ glProgramUniform1fv
+ glProgramUniform1i
+ glProgramUniform1iv
+ glProgramUniform1ui
+ glProgramUniform1uiv
+ glProgramUniform2f
+ glProgramUniform2fv
+ glProgramUniform2i
+ glProgramUniform2iv
+ glProgramUniform2ui
+ glProgramUniform2uiv
+ glProgramUniform3f
+ glProgramUniform3fv
+ glProgramUniform3i
+ glProgramUniform3iv
+ glProgramUniform3ui
+ glProgramUniform3uiv
+ glProgramUniform4f
+ glProgramUniform4fv
+ glProgramUniform4i
+ glProgramUniform4iv
+ glProgramUniform4ui
+ glProgramUniform4uiv
+ glProgramUniformMatrix2fv
+ glProgramUniformMatrix2x3fv
+ glProgramUniformMatrix2x4fv
+ glProgramUniformMatrix3fv
+ glProgramUniformMatrix3x2fv
+ glProgramUniformMatrix3x4fv
+ glProgramUniformMatrix4fv
+ glProgramUniformMatrix4x2fv
+ glProgramUniformMatrix4x3fv
+ glSampleMaski
+ glTexStorage2DMultisample
+ glUseProgramStages
+ glValidateProgramPipeline
+ glVertexAttribBinding
+ glVertexAttribFormat
+ glVertexAttribIFormat
+ glVertexBindingDivisor
+
+ ; OpenGL ES 3.2
+ glBlendBarrier
+ glBlendEquationSeparatei
+ glBlendEquationi
+ glBlendFuncSeparatei
+ glBlendFunci
+ glColorMaski
+ glCopyImageSubData
+ glDebugMessageCallback
+ glDebugMessageControl
+ glDebugMessageInsert
+ glDisablei
+ glDrawElementsBaseVertex
+ glDrawElementsInstancedBaseVertex
+ glDrawRangeElementsBaseVertex
+ glEnablei
+ glFramebufferTexture
+ glGetDebugMessageLog
+ glGetGraphicsResetStatus
+ glGetObjectLabel
+ glGetObjectPtrLabel
+ glGetPointerv
+ glGetSamplerParameterIiv
+ glGetSamplerParameterIuiv
+ glGetTexParameterIiv
+ glGetTexParameterIuiv
+ glGetnUniformfv
+ glGetnUniformiv
+ glGetnUniformuiv
+ glIsEnabledi
+ glMinSampleShading
+ glObjectLabel
+ glObjectPtrLabel
+ glPatchParameteri
+ glPopDebugGroup
+ glPrimitiveBoundingBox
+ glPushDebugGroup
+ glReadnPixels
+ glSamplerParameterIiv
+ glSamplerParameterIuiv
+ glTexBuffer
+ glTexBufferRange
+ glTexParameterIiv
+ glTexParameterIuiv
+ glTexStorage3DMultisample
+
+ ; OpenGL ES 1.0
+ glAlphaFunc
+ glAlphaFuncx
+ glClearColorx
+ glClearDepthx
+ glClientActiveTexture
+ glClipPlanef
+ glClipPlanex
+ glColor4f
+ glColor4ub
+ glColor4x
+ glColorPointer
+ glDepthRangex
+ glDisableClientState
+ glEnableClientState
+ glFogf
+ glFogfv
+ glFogx
+ glFogxv
+ glFrustumf
+ glFrustumx
+ glGetClipPlanef
+ glGetClipPlanex
+ glGetFixedv
+ glGetLightfv
+ glGetLightxv
+ glGetMaterialfv
+ glGetMaterialxv
+ glGetTexEnvfv
+ glGetTexEnviv
+ glGetTexEnvxv
+ glGetTexParameterxv
+ glLightModelf
+ glLightModelfv
+ glLightModelx
+ glLightModelxv
+ glLightf
+ glLightfv
+ glLightx
+ glLightxv
+ glLineWidthx
+ glLoadIdentity
+ glLoadMatrixf
+ glLoadMatrixx
+ glLogicOp
+ glMaterialf
+ glMaterialfv
+ glMaterialx
+ glMaterialxv
+ glMatrixMode
+ glMultMatrixf
+ glMultMatrixx
+ glMultiTexCoord4f
+ glMultiTexCoord4x
+ glNormal3f
+ glNormal3x
+ glNormalPointer
+ glOrthof
+ glOrthox
+ glPointParameterf
+ glPointParameterfv
+ glPointParameterx
+ glPointParameterxv
+ glPointSize
+ glPointSizex
+ glPolygonOffsetx
+ glPopMatrix
+ glPushMatrix
+ glRotatef
+ glRotatex
+ glSampleCoveragex
+ glScalef
+ glScalex
+ glShadeModel
+ glTexCoordPointer
+ glTexEnvf
+ glTexEnvfv
+ glTexEnvi
+ glTexEnviv
+ glTexEnvx
+ glTexEnvxv
+ glTexParameterx
+ glTexParameterxv
+ glTranslatef
+ glTranslatex
+ glVertexPointer
+
+ ; GL_AMD_performance_monitor
+ glBeginPerfMonitorAMD
+ glDeletePerfMonitorsAMD
+ glEndPerfMonitorAMD
+ glGenPerfMonitorsAMD
+ glGetPerfMonitorCounterDataAMD
+ glGetPerfMonitorCounterInfoAMD
+ glGetPerfMonitorCounterStringAMD
+ glGetPerfMonitorCountersAMD
+ glGetPerfMonitorGroupStringAMD
+ glGetPerfMonitorGroupsAMD
+ glSelectPerfMonitorCountersAMD
+
+ ; GL_ANDROID_extension_pack_es31a
+
+ ; GL_ANGLE_base_vertex_base_instance
+ glDrawArraysInstancedBaseInstanceANGLE
+ glDrawElementsInstancedBaseVertexBaseInstanceANGLE
+ glMultiDrawArraysInstancedBaseInstanceANGLE
+ glMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE
+
+ ; GL_ANGLE_copy_texture_3d
+ glCopySubTexture3DANGLE
+ glCopyTexture3DANGLE
+
+ ; GL_ANGLE_depth_texture
+
+ ; GL_ANGLE_framebuffer_blit
+ glBlitFramebufferANGLE
+
+ ; GL_ANGLE_framebuffer_multisample
+ glRenderbufferStorageMultisampleANGLE
+
+ ; GL_ANGLE_get_image
+ glGetCompressedTexImageANGLE
+ glGetRenderbufferImageANGLE
+ glGetTexImageANGLE
+
+ ; GL_ANGLE_get_tex_level_parameter
+ glGetTexLevelParameterfvANGLE
+ glGetTexLevelParameterivANGLE
+
+ ; GL_ANGLE_instanced_arrays
+ glDrawArraysInstancedANGLE
+ glDrawElementsInstancedANGLE
+ glVertexAttribDivisorANGLE
+
+ ; GL_ANGLE_logic_op
+ glLogicOpANGLE
+
+ ; GL_ANGLE_memory_object_flags
+ glTexStorageMemFlags2DANGLE
+ glTexStorageMemFlags2DMultisampleANGLE
+ glTexStorageMemFlags3DANGLE
+ glTexStorageMemFlags3DMultisampleANGLE
+
+ ; GL_ANGLE_memory_object_fuchsia
+ glImportMemoryZirconHandleANGLE
+
+ ; GL_ANGLE_multi_draw
+ glMultiDrawArraysANGLE
+ glMultiDrawArraysInstancedANGLE
+ glMultiDrawElementsANGLE
+ glMultiDrawElementsInstancedANGLE
+
+ ; GL_ANGLE_pack_reverse_row_order
+
+ ; GL_ANGLE_program_binary
+
+ ; GL_ANGLE_provoking_vertex
+ glProvokingVertexANGLE
+
+ ; GL_ANGLE_request_extension
+ glDisableExtensionANGLE
+ glRequestExtensionANGLE
+
+ ; GL_ANGLE_robust_client_memory
+ glCompressedTexImage2DRobustANGLE
+ glCompressedTexImage3DRobustANGLE
+ glCompressedTexSubImage2DRobustANGLE
+ glCompressedTexSubImage3DRobustANGLE
+ glGetActiveUniformBlockivRobustANGLE
+ glGetBooleani_vRobustANGLE
+ glGetBooleanvRobustANGLE
+ glGetBufferParameteri64vRobustANGLE
+ glGetBufferParameterivRobustANGLE
+ glGetBufferPointervRobustANGLE
+ glGetFloatvRobustANGLE
+ glGetFramebufferAttachmentParameterivRobustANGLE
+ glGetFramebufferParameterivRobustANGLE
+ glGetInteger64i_vRobustANGLE
+ glGetInteger64vRobustANGLE
+ glGetIntegeri_vRobustANGLE
+ glGetIntegervRobustANGLE
+ glGetInternalformativRobustANGLE
+ glGetMultisamplefvRobustANGLE
+ glGetPointervRobustANGLERobustANGLE
+ glGetProgramInterfaceivRobustANGLE
+ glGetProgramivRobustANGLE
+ glGetQueryObjecti64vRobustANGLE
+ glGetQueryObjectivRobustANGLE
+ glGetQueryObjectui64vRobustANGLE
+ glGetQueryObjectuivRobustANGLE
+ glGetQueryivRobustANGLE
+ glGetRenderbufferParameterivRobustANGLE
+ glGetSamplerParameterIivRobustANGLE
+ glGetSamplerParameterIuivRobustANGLE
+ glGetSamplerParameterfvRobustANGLE
+ glGetSamplerParameterivRobustANGLE
+ glGetShaderivRobustANGLE
+ glGetTexLevelParameterfvRobustANGLE
+ glGetTexLevelParameterivRobustANGLE
+ glGetTexParameterIivRobustANGLE
+ glGetTexParameterIuivRobustANGLE
+ glGetTexParameterfvRobustANGLE
+ glGetTexParameterivRobustANGLE
+ glGetUniformfvRobustANGLE
+ glGetUniformivRobustANGLE
+ glGetUniformuivRobustANGLE
+ glGetVertexAttribIivRobustANGLE
+ glGetVertexAttribIuivRobustANGLE
+ glGetVertexAttribPointervRobustANGLE
+ glGetVertexAttribfvRobustANGLE
+ glGetVertexAttribivRobustANGLE
+ glGetnUniformfvRobustANGLE
+ glGetnUniformivRobustANGLE
+ glGetnUniformuivRobustANGLE
+ glReadPixelsRobustANGLE
+ glReadnPixelsRobustANGLE
+ glSamplerParameterIivRobustANGLE
+ glSamplerParameterIuivRobustANGLE
+ glSamplerParameterfvRobustANGLE
+ glSamplerParameterivRobustANGLE
+ glTexImage2DRobustANGLE
+ glTexImage3DRobustANGLE
+ glTexParameterIivRobustANGLE
+ glTexParameterIuivRobustANGLE
+ glTexParameterfvRobustANGLE
+ glTexParameterivRobustANGLE
+ glTexSubImage2DRobustANGLE
+ glTexSubImage3DRobustANGLE
+
+ ; GL_ANGLE_robust_resource_initialization
+
+ ; GL_ANGLE_semaphore_fuchsia
+ glImportSemaphoreZirconHandleANGLE
+
+ ; GL_ANGLE_shader_pixel_local_storage
+ glBeginPixelLocalStorageANGLE
+ glEndPixelLocalStorageANGLE
+ glFramebufferMemorylessPixelLocalStorageANGLE
+ glFramebufferTexturePixelLocalStorageANGLE
+ glPixelLocalStorageBarrierANGLE
+
+ ; GL_ANGLE_texture_compression_dxt3
+
+ ; GL_ANGLE_texture_compression_dxt5
+
+ ; GL_ANGLE_texture_external_update
+ glInvalidateTextureANGLE
+ glTexImage2DExternalANGLE
+
+ ; GL_ANGLE_texture_multisample
+ glGetMultisamplefvANGLE
+ glSampleMaskiANGLE
+ glTexStorage2DMultisampleANGLE
+
+ ; GL_ANGLE_texture_usage
+
+ ; GL_ANGLE_translated_shader_source
+ glGetTranslatedShaderSourceANGLE
+
+ ; GL_ANGLE_vulkan_image
+ glAcquireTexturesANGLE
+ glReleaseTexturesANGLE
+
+ ; GL_APPLE_clip_distance
+
+ ; GL_ARB_sync
+
+ ; GL_CHROMIUM_bind_uniform_location
+ glBindUniformLocationCHROMIUM
+
+ ; GL_CHROMIUM_copy_compressed_texture
+ glCompressedCopyTextureCHROMIUM
+
+ ; GL_CHROMIUM_copy_texture
+ glCopySubTextureCHROMIUM
+ glCopyTextureCHROMIUM
+
+ ; GL_CHROMIUM_framebuffer_mixed_samples
+ glCoverageModulationCHROMIUM
+
+ ; GL_CHROMIUM_lose_context
+ glLoseContextCHROMIUM
+
+ ; GL_EXT_EGL_image_array
+
+ ; GL_EXT_EGL_image_storage
+ glEGLImageTargetTexStorageEXT
+ glEGLImageTargetTextureStorageEXT
+
+ ; GL_EXT_YUV_target
+
+ ; GL_EXT_base_instance
+ glDrawArraysInstancedBaseInstanceEXT
+ glDrawElementsInstancedBaseInstanceEXT
+ glDrawElementsInstancedBaseVertexBaseInstanceEXT
+
+ ; GL_EXT_blend_func_extended
+ glBindFragDataLocationEXT
+ glBindFragDataLocationIndexedEXT
+ glGetFragDataIndexEXT
+ glGetProgramResourceLocationIndexEXT
+
+ ; GL_EXT_blend_minmax
+
+ ; GL_EXT_buffer_storage
+ glBufferStorageEXT
+
+ ; GL_EXT_clip_control
+ glClipControlEXT
+
+ ; GL_EXT_clip_cull_distance
+
+ ; GL_EXT_color_buffer_float
+
+ ; GL_EXT_color_buffer_half_float
+
+ ; GL_EXT_copy_image
+ glCopyImageSubDataEXT
+
+ ; GL_EXT_debug_label
+ glGetObjectLabelEXT
+ glLabelObjectEXT
+
+ ; GL_EXT_debug_marker
+ glInsertEventMarkerEXT
+ glPopGroupMarkerEXT
+ glPushGroupMarkerEXT
+
+ ; GL_EXT_discard_framebuffer
+ glDiscardFramebufferEXT
+
+ ; GL_EXT_disjoint_timer_query
+ glBeginQueryEXT
+ glDeleteQueriesEXT
+ glEndQueryEXT
+ glGenQueriesEXT
+ glGetInteger64vEXT
+ glGetQueryObjecti64vEXT
+ glGetQueryObjectivEXT
+ glGetQueryObjectui64vEXT
+ glGetQueryObjectuivEXT
+ glGetQueryivEXT
+ glIsQueryEXT
+ glQueryCounterEXT
+
+ ; GL_EXT_draw_buffers
+ glDrawBuffersEXT
+
+ ; GL_EXT_draw_buffers_indexed
+ glBlendEquationSeparateiEXT
+ glBlendEquationiEXT
+ glBlendFuncSeparateiEXT
+ glBlendFunciEXT
+ glColorMaskiEXT
+ glDisableiEXT
+ glEnableiEXT
+ glIsEnablediEXT
+
+ ; GL_EXT_draw_elements_base_vertex
+ glDrawElementsBaseVertexEXT
+ glDrawElementsInstancedBaseVertexEXT
+ glDrawRangeElementsBaseVertexEXT
+ glMultiDrawElementsBaseVertexEXT
+
+ ; GL_EXT_external_buffer
+ glBufferStorageExternalEXT
+ glNamedBufferStorageExternalEXT
+
+ ; GL_EXT_float_blend
+
+ ; GL_EXT_geometry_shader
+ glFramebufferTextureEXT
+
+ ; GL_EXT_gpu_shader5
+
+ ; GL_EXT_instanced_arrays
+ glDrawArraysInstancedEXT
+ glDrawElementsInstancedEXT
+ glVertexAttribDivisorEXT
+
+ ; GL_EXT_map_buffer_range
+ glFlushMappedBufferRangeEXT
+ glMapBufferRangeEXT
+
+ ; GL_EXT_memory_object
+ glBufferStorageMemEXT
+ glCreateMemoryObjectsEXT
+ glDeleteMemoryObjectsEXT
+ glGetMemoryObjectParameterivEXT
+ glGetUnsignedBytei_vEXT
+ glGetUnsignedBytevEXT
+ glIsMemoryObjectEXT
+ glMemoryObjectParameterivEXT
+ glTexStorageMem2DEXT
+ glTexStorageMem2DMultisampleEXT
+ glTexStorageMem3DEXT
+ glTexStorageMem3DMultisampleEXT
+
+ ; GL_EXT_memory_object_fd
+ glImportMemoryFdEXT
+
+ ; GL_EXT_multi_draw_indirect
+ glMultiDrawArraysIndirectEXT
+ glMultiDrawElementsIndirectEXT
+
+ ; GL_EXT_multisampled_render_to_texture
+ glFramebufferTexture2DMultisampleEXT
+ glRenderbufferStorageMultisampleEXT
+
+ ; GL_EXT_multisampled_render_to_texture2
+
+ ; GL_EXT_occlusion_query_boolean
+
+ ; GL_EXT_primitive_bounding_box
+ glPrimitiveBoundingBoxEXT
+
+ ; GL_EXT_protected_textures
+
+ ; GL_EXT_pvrtc_sRGB
+
+ ; GL_EXT_read_format_bgra
+
+ ; GL_EXT_robustness
+ glGetGraphicsResetStatusEXT
+ glGetnUniformfvEXT
+ glGetnUniformivEXT
+ glReadnPixelsEXT
+
+ ; GL_EXT_sRGB
+
+ ; GL_EXT_sRGB_write_control
+
+ ; GL_EXT_semaphore
+ glDeleteSemaphoresEXT
+ glGenSemaphoresEXT
+ glGetSemaphoreParameterui64vEXT
+ glIsSemaphoreEXT
+ glSemaphoreParameterui64vEXT
+ glSignalSemaphoreEXT
+ glWaitSemaphoreEXT
+
+ ; GL_EXT_semaphore_fd
+ glImportSemaphoreFdEXT
+
+ ; GL_EXT_separate_shader_objects
+ glActiveShaderProgramEXT
+ glBindProgramPipelineEXT
+ glCreateShaderProgramvEXT
+ glDeleteProgramPipelinesEXT
+ glGenProgramPipelinesEXT
+ glGetProgramPipelineInfoLogEXT
+ glGetProgramPipelineivEXT
+ glIsProgramPipelineEXT
+ glProgramParameteriEXT
+ glProgramUniform1fEXT
+ glProgramUniform1fvEXT
+ glProgramUniform1iEXT
+ glProgramUniform1ivEXT
+ glProgramUniform1uiEXT
+ glProgramUniform1uivEXT
+ glProgramUniform2fEXT
+ glProgramUniform2fvEXT
+ glProgramUniform2iEXT
+ glProgramUniform2ivEXT
+ glProgramUniform2uiEXT
+ glProgramUniform2uivEXT
+ glProgramUniform3fEXT
+ glProgramUniform3fvEXT
+ glProgramUniform3iEXT
+ glProgramUniform3ivEXT
+ glProgramUniform3uiEXT
+ glProgramUniform3uivEXT
+ glProgramUniform4fEXT
+ glProgramUniform4fvEXT
+ glProgramUniform4iEXT
+ glProgramUniform4ivEXT
+ glProgramUniform4uiEXT
+ glProgramUniform4uivEXT
+ glProgramUniformMatrix2fvEXT
+ glProgramUniformMatrix2x3fvEXT
+ glProgramUniformMatrix2x4fvEXT
+ glProgramUniformMatrix3fvEXT
+ glProgramUniformMatrix3x2fvEXT
+ glProgramUniformMatrix3x4fvEXT
+ glProgramUniformMatrix4fvEXT
+ glProgramUniformMatrix4x2fvEXT
+ glProgramUniformMatrix4x3fvEXT
+ glUseProgramStagesEXT
+ glValidateProgramPipelineEXT
+
+ ; GL_EXT_shader_framebuffer_fetch
+
+ ; GL_EXT_shader_framebuffer_fetch_non_coherent
+ glFramebufferFetchBarrierEXT
+
+ ; GL_EXT_shader_io_blocks
+
+ ; GL_EXT_shader_non_constant_global_initializers
+
+ ; GL_EXT_shader_texture_lod
+
+ ; GL_EXT_shadow_samplers
+
+ ; GL_EXT_tessellation_shader
+ glPatchParameteriEXT
+
+ ; GL_EXT_texture_border_clamp
+ glGetSamplerParameterIivEXT
+ glGetSamplerParameterIuivEXT
+ glGetTexParameterIivEXT
+ glGetTexParameterIuivEXT
+ glSamplerParameterIivEXT
+ glSamplerParameterIuivEXT
+ glTexParameterIivEXT
+ glTexParameterIuivEXT
+
+ ; GL_EXT_texture_buffer
+ glTexBufferEXT
+ glTexBufferRangeEXT
+
+ ; GL_EXT_texture_compression_bptc
+
+ ; GL_EXT_texture_compression_dxt1
+
+ ; GL_EXT_texture_compression_rgtc
+
+ ; GL_EXT_texture_compression_s3tc
+
+ ; GL_EXT_texture_compression_s3tc_srgb
+
+ ; GL_EXT_texture_cube_map_array
+
+ ; GL_EXT_texture_filter_anisotropic
+
+ ; GL_EXT_texture_format_BGRA8888
+
+ ; GL_EXT_texture_format_sRGB_override
+
+ ; GL_EXT_texture_norm16
+
+ ; GL_EXT_texture_rg
+
+ ; GL_EXT_texture_sRGB_R8
+
+ ; GL_EXT_texture_sRGB_RG8
+
+ ; GL_EXT_texture_sRGB_decode
+
+ ; GL_EXT_texture_storage
+ glTexStorage1DEXT
+ glTexStorage2DEXT
+ glTexStorage3DEXT
+
+ ; GL_EXT_texture_type_2_10_10_10_REV
+
+ ; GL_EXT_unpack_subimage
+
+ ; GL_IMG_texture_compression_pvrtc
+
+ ; GL_IMG_texture_compression_pvrtc2
+
+ ; GL_KHR_blend_equation_advanced
+ glBlendBarrierKHR
+
+ ; GL_KHR_debug
+ glDebugMessageCallbackKHR
+ glDebugMessageControlKHR
+ glDebugMessageInsertKHR
+ glGetDebugMessageLogKHR
+ glGetObjectLabelKHR
+ glGetObjectPtrLabelKHR
+ glGetPointervKHR
+ glObjectLabelKHR
+ glObjectPtrLabelKHR
+ glPopDebugGroupKHR
+ glPushDebugGroupKHR
+
+ ; GL_KHR_no_error
+
+ ; GL_KHR_parallel_shader_compile
+ glMaxShaderCompilerThreadsKHR
+
+ ; GL_KHR_robust_buffer_access_behavior
+
+ ; GL_KHR_texture_compression_astc_hdr
+
+ ; GL_KHR_texture_compression_astc_ldr
+
+ ; GL_KHR_texture_compression_astc_sliced_3d
+
+ ; GL_MESA_framebuffer_flip_y
+ glFramebufferParameteriMESA
+ glGetFramebufferParameterivMESA
+
+ ; GL_NV_fence
+ glDeleteFencesNV
+ glFinishFenceNV
+ glGenFencesNV
+ glGetFenceivNV
+ glIsFenceNV
+ glSetFenceNV
+ glTestFenceNV
+
+ ; GL_NV_framebuffer_blit
+ glBlitFramebufferNV
+
+ ; GL_NV_pixel_buffer_object
+
+ ; GL_NV_read_depth
+
+ ; GL_NV_read_depth_stencil
+
+ ; GL_NV_read_stencil
+
+ ; GL_NV_robustness_video_memory_purge
+
+ ; GL_NV_shader_noperspective_interpolation
+
+ ; GL_OES_EGL_image
+ glEGLImageTargetRenderbufferStorageOES
+ glEGLImageTargetTexture2DOES
+
+ ; GL_OES_EGL_image_external
+
+ ; GL_OES_EGL_image_external_essl3
+
+ ; GL_OES_compressed_ETC1_RGB8_texture
+
+ ; GL_OES_compressed_paletted_texture
+
+ ; GL_OES_copy_image
+ glCopyImageSubDataOES
+
+ ; GL_OES_depth24
+
+ ; GL_OES_depth32
+
+ ; GL_OES_depth_texture
+
+ ; GL_OES_draw_buffers_indexed
+ glBlendEquationSeparateiOES
+ glBlendEquationiOES
+ glBlendFuncSeparateiOES
+ glBlendFunciOES
+ glColorMaskiOES
+ glDisableiOES
+ glEnableiOES
+ glIsEnablediOES
+
+ ; GL_OES_draw_elements_base_vertex
+ glDrawElementsBaseVertexOES
+ glDrawElementsInstancedBaseVertexOES
+ glDrawRangeElementsBaseVertexOES
+
+ ; GL_OES_draw_texture
+ glDrawTexfOES
+ glDrawTexfvOES
+ glDrawTexiOES
+ glDrawTexivOES
+ glDrawTexsOES
+ glDrawTexsvOES
+ glDrawTexxOES
+ glDrawTexxvOES
+
+ ; GL_OES_element_index_uint
+
+ ; GL_OES_fbo_render_mipmap
+
+ ; GL_OES_framebuffer_object
+ glBindFramebufferOES
+ glBindRenderbufferOES
+ glCheckFramebufferStatusOES
+ glDeleteFramebuffersOES
+ glDeleteRenderbuffersOES
+ glFramebufferRenderbufferOES
+ glFramebufferTexture2DOES
+ glGenFramebuffersOES
+ glGenRenderbuffersOES
+ glGenerateMipmapOES
+ glGetFramebufferAttachmentParameterivOES
+ glGetRenderbufferParameterivOES
+ glIsFramebufferOES
+ glIsRenderbufferOES
+ glRenderbufferStorageOES
+
+ ; GL_OES_geometry_shader
+ glFramebufferTextureOES
+
+ ; GL_OES_get_program_binary
+ glGetProgramBinaryOES
+ glProgramBinaryOES
+
+ ; GL_OES_mapbuffer
+ glGetBufferPointervOES
+ glMapBufferOES
+ glUnmapBufferOES
+
+ ; GL_OES_matrix_palette
+ glCurrentPaletteMatrixOES
+ glLoadPaletteFromModelViewMatrixOES
+ glMatrixIndexPointerOES
+ glWeightPointerOES
+
+ ; GL_OES_packed_depth_stencil
+
+ ; GL_OES_point_size_array
+ glPointSizePointerOES
+
+ ; GL_OES_point_sprite
+
+ ; GL_OES_primitive_bounding_box
+ glPrimitiveBoundingBoxOES
+
+ ; GL_OES_query_matrix
+ glQueryMatrixxOES
+
+ ; GL_OES_rgb8_rgba8
+
+ ; GL_OES_sample_shading
+ glMinSampleShadingOES
+
+ ; GL_OES_sample_variables
+
+ ; GL_OES_shader_image_atomic
+
+ ; GL_OES_shader_io_blocks
+
+ ; GL_OES_shader_multisample_interpolation
+
+ ; GL_OES_standard_derivatives
+
+ ; GL_OES_surfaceless_context
+
+ ; GL_OES_texture_3D
+ glCompressedTexImage3DOES
+ glCompressedTexSubImage3DOES
+ glCopyTexSubImage3DOES
+ glFramebufferTexture3DOES
+ glTexImage3DOES
+ glTexSubImage3DOES
+
+ ; GL_OES_texture_border_clamp
+ glGetSamplerParameterIivOES
+ glGetSamplerParameterIuivOES
+ glGetTexParameterIivOES
+ glGetTexParameterIuivOES
+ glSamplerParameterIivOES
+ glSamplerParameterIuivOES
+ glTexParameterIivOES
+ glTexParameterIuivOES
+
+ ; GL_OES_texture_buffer
+ glTexBufferOES
+ glTexBufferRangeOES
+
+ ; GL_OES_texture_compression_astc
+
+ ; GL_OES_texture_cube_map
+ glGetTexGenfvOES
+ glGetTexGenivOES
+ glGetTexGenxvOES
+ glTexGenfOES
+ glTexGenfvOES
+ glTexGeniOES
+ glTexGenivOES
+ glTexGenxOES
+ glTexGenxvOES
+
+ ; GL_OES_texture_cube_map_array
+
+ ; GL_OES_texture_float
+
+ ; GL_OES_texture_float_linear
+
+ ; GL_OES_texture_half_float
+
+ ; GL_OES_texture_half_float_linear
+
+ ; GL_OES_texture_npot
+
+ ; GL_OES_texture_stencil8
+
+ ; GL_OES_texture_storage_multisample_2d_array
+ glTexStorage3DMultisampleOES
+
+ ; GL_OES_vertex_array_object
+ glBindVertexArrayOES
+ glDeleteVertexArraysOES
+ glGenVertexArraysOES
+ glIsVertexArrayOES
+
+ ; GL_OES_vertex_half_float
+
+ ; GL_OES_vertex_type_10_10_10_2
+
+ ; GL_OVR_multiview
+ glFramebufferTextureMultiviewOVR
+
+ ; GL_OVR_multiview2
+
+ ; GL_QCOM_shading_rate
+ glShadingRateQCOM
+
+ ; EGL 1.0
+ EGL_ChooseConfig
+ EGL_CopyBuffers
+ EGL_CreateContext
+ EGL_CreatePbufferSurface
+ EGL_CreatePixmapSurface
+ EGL_CreateWindowSurface
+ EGL_DestroyContext
+ EGL_DestroySurface
+ EGL_GetConfigAttrib
+ EGL_GetConfigs
+ EGL_GetCurrentDisplay
+ EGL_GetCurrentSurface
+ EGL_GetDisplay
+ EGL_GetError
+ EGL_GetProcAddress
+ EGL_Initialize
+ EGL_MakeCurrent
+ EGL_QueryContext
+ EGL_QueryString
+ EGL_QuerySurface
+ EGL_SwapBuffers
+ EGL_Terminate
+ EGL_WaitGL
+ EGL_WaitNative
+
+ ; EGL 1.1
+ EGL_BindTexImage
+ EGL_ReleaseTexImage
+ EGL_SurfaceAttrib
+ EGL_SwapInterval
+
+ ; EGL 1.2
+ EGL_BindAPI
+ EGL_CreatePbufferFromClientBuffer
+ EGL_QueryAPI
+ EGL_ReleaseThread
+ EGL_WaitClient
+
+ ; EGL 1.4
+ EGL_GetCurrentContext
+
+ ; EGL 1.5
+ EGL_ClientWaitSync
+ EGL_CreateImage
+ EGL_CreatePlatformPixmapSurface
+ EGL_CreatePlatformWindowSurface
+ EGL_CreateSync
+ EGL_DestroyImage
+ EGL_DestroySync
+ EGL_GetPlatformDisplay
+ EGL_GetSyncAttrib
+ EGL_WaitSync
+
+ ; EGL_ANDROID_blob_cache
+ EGL_SetBlobCacheFuncsANDROID
+
+ ; EGL_ANDROID_create_native_client_buffer
+ EGL_CreateNativeClientBufferANDROID
+
+ ; EGL_ANDROID_get_frame_timestamps
+ EGL_GetCompositorTimingANDROID
+ EGL_GetCompositorTimingSupportedANDROID
+ EGL_GetFrameTimestampSupportedANDROID
+ EGL_GetFrameTimestampsANDROID
+ EGL_GetNextFrameIdANDROID
+
+ ; EGL_ANDROID_get_native_client_buffer
+ EGL_GetNativeClientBufferANDROID
+
+ ; EGL_ANDROID_native_fence_sync
+ EGL_DupNativeFenceFDANDROID
+
+ ; EGL_ANDROID_presentation_time
+ EGL_PresentationTimeANDROID
+
+ ; EGL_ANGLE_device_creation
+ EGL_CreateDeviceANGLE
+ EGL_ReleaseDeviceANGLE
+
+ ; EGL_ANGLE_feature_control
+ EGL_QueryDisplayAttribANGLE
+ EGL_QueryStringiANGLE
+
+ ; EGL_ANGLE_metal_shared_event_sync
+ EGL_CopyMetalSharedEventANGLE
+
+ ; EGL_ANGLE_power_preference
+ EGL_ForceGPUSwitchANGLE
+ EGL_HandleGPUSwitchANGLE
+ EGL_ReacquireHighPowerGPUANGLE
+ EGL_ReleaseHighPowerGPUANGLE
+
+ ; EGL_ANGLE_prepare_swap_buffers
+ EGL_PrepareSwapBuffersANGLE
+
+ ; EGL_ANGLE_program_cache_control
+ EGL_ProgramCacheGetAttribANGLE
+ EGL_ProgramCachePopulateANGLE
+ EGL_ProgramCacheQueryANGLE
+ EGL_ProgramCacheResizeANGLE
+
+ ; EGL_ANGLE_query_surface_pointer
+ EGL_QuerySurfacePointerANGLE
+
+ ; EGL_ANGLE_stream_producer_d3d_texture
+ EGL_CreateStreamProducerD3DTextureANGLE
+ EGL_StreamPostD3DTextureANGLE
+
+ ; EGL_ANGLE_swap_with_frame_token
+ EGL_SwapBuffersWithFrameTokenANGLE
+
+ ; EGL_ANGLE_sync_control_rate
+ EGL_GetMscRateANGLE
+
+ ; EGL_ANGLE_vulkan_image
+ EGL_ExportVkImageANGLE
+
+ ; EGL_CHROMIUM_sync_control
+ EGL_GetSyncValuesCHROMIUM
+
+ ; EGL_EXT_device_query
+ EGL_QueryDeviceAttribEXT
+ EGL_QueryDeviceStringEXT
+ EGL_QueryDisplayAttribEXT
+
+ ; EGL_EXT_image_dma_buf_import_modifiers
+ EGL_QueryDmaBufFormatsEXT
+ EGL_QueryDmaBufModifiersEXT
+
+ ; EGL_EXT_platform_base
+ EGL_CreatePlatformPixmapSurfaceEXT
+ EGL_CreatePlatformWindowSurfaceEXT
+ EGL_GetPlatformDisplayEXT
+
+ ; EGL_KHR_debug
+ EGL_DebugMessageControlKHR
+ EGL_LabelObjectKHR
+ EGL_QueryDebugKHR
+
+ ; EGL_KHR_fence_sync
+ EGL_ClientWaitSyncKHR
+ EGL_CreateSyncKHR
+ EGL_DestroySyncKHR
+ EGL_GetSyncAttribKHR
+
+ ; EGL_KHR_image
+ EGL_CreateImageKHR
+ EGL_DestroyImageKHR
+
+ ; EGL_KHR_lock_surface3
+ EGL_LockSurfaceKHR
+ EGL_QuerySurface64KHR
+ EGL_UnlockSurfaceKHR
+
+ ; EGL_KHR_partial_update
+ EGL_SetDamageRegionKHR
+
+ ; EGL_KHR_reusable_sync
+ EGL_SignalSyncKHR
+
+ ; EGL_KHR_stream
+ EGL_CreateStreamKHR
+ EGL_DestroyStreamKHR
+ EGL_QueryStreamKHR
+ EGL_QueryStreamu64KHR
+ EGL_StreamAttribKHR
+
+ ; EGL_KHR_stream_consumer_gltexture
+ EGL_StreamConsumerAcquireKHR
+ EGL_StreamConsumerGLTextureExternalKHR
+ EGL_StreamConsumerReleaseKHR
+
+ ; EGL_KHR_swap_buffers_with_damage
+ EGL_SwapBuffersWithDamageKHR
+
+ ; EGL_KHR_wait_sync
+ EGL_WaitSyncKHR
+
+ ; EGL_NV_post_sub_buffer
+ EGL_PostSubBufferNV
+
+ ; EGL_NV_stream_consumer_gltexture_yuv
+ EGL_StreamConsumerGLTextureExternalAttribsNV
diff --git a/gfx/angle/checkout/src/libGLESv2/proc_table_egl.h b/gfx/angle/checkout/src/libGLESv2/proc_table_egl.h
new file mode 100644
index 0000000000..d4960b7728
--- /dev/null
+++ b/gfx/angle/checkout/src/libGLESv2/proc_table_egl.h
@@ -0,0 +1,25 @@
+//
+// Copyright 2017 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.
+//
+// getProcAddress loader table:
+// Mapping from a string entry point name to function address.
+//
+
+#ifndef LIBGLESV2_PROC_TABLE_H_
+#define LIBGLESV2_PROC_TABLE_H_
+
+#include <EGL/egl.h>
+#include <stddef.h>
+#include <utility>
+
+namespace egl
+{
+using ProcEntry = std::pair<const char *, __eglMustCastToProperFunctionPointerType>;
+
+extern const ProcEntry g_procTable[];
+extern const size_t g_numProcs;
+} // namespace egl
+
+#endif // LIBGLESV2_PROC_TABLE_H_
diff --git a/gfx/angle/checkout/src/libGLESv2/proc_table_egl_autogen.cpp b/gfx/angle/checkout/src/libGLESv2/proc_table_egl_autogen.cpp
new file mode 100644
index 0000000000..3b77295b56
--- /dev/null
+++ b/gfx/angle/checkout/src/libGLESv2/proc_table_egl_autogen.cpp
@@ -0,0 +1,1623 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by gen_proc_table.py using data from gl.xml, gl_angle_ext.xml, egl.xml,
+// egl_angle_ext.xml.
+//
+// Copyright 2019 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.
+//
+// getProcAddress loader table:
+// Mapping from a string entry point name to function address.
+//
+
+#include "libGLESv2/proc_table_egl.h"
+
+#include "libGLESv2/entry_points_egl_autogen.h"
+#include "libGLESv2/entry_points_egl_ext_autogen.h"
+#include "libGLESv2/entry_points_gles_1_0_autogen.h"
+#include "libGLESv2/entry_points_gles_2_0_autogen.h"
+#include "libGLESv2/entry_points_gles_3_0_autogen.h"
+#include "libGLESv2/entry_points_gles_3_1_autogen.h"
+#include "libGLESv2/entry_points_gles_3_2_autogen.h"
+#include "libGLESv2/entry_points_gles_ext_autogen.h"
+#include "platform/PlatformMethods.h"
+
+#if defined(ANGLE_ENABLE_GL_DESKTOP_FRONTEND)
+# include "libGLESv2/entry_points_gl_1_autogen.h"
+# include "libGLESv2/entry_points_gl_2_autogen.h"
+# include "libGLESv2/entry_points_gl_3_autogen.h"
+# include "libGLESv2/entry_points_gl_4_autogen.h"
+#endif
+
+#include <iterator>
+
+#define P(FUNC) reinterpret_cast<__eglMustCastToProperFunctionPointerType>(FUNC)
+
+#if defined(ANGLE_ENABLE_GL_DESKTOP_FRONTEND)
+# define DESKTOP_ONLY(func, angleFunc) {func, P(angleFunc)},
+#else
+# define DESKTOP_ONLY(func, angleFunc)
+#endif
+
+namespace egl
+{
+// clang-format off
+const ProcEntry g_procTable[] = {
+ {"ANGLEGetDisplayPlatform", P(ANGLEGetDisplayPlatform)},
+ {"ANGLEResetDisplayPlatform", P(ANGLEResetDisplayPlatform)},
+ {"eglBindAPI", P(EGL_BindAPI)},
+ {"eglBindTexImage", P(EGL_BindTexImage)},
+ {"eglChooseConfig", P(EGL_ChooseConfig)},
+ {"eglClientWaitSync", P(EGL_ClientWaitSync)},
+ {"eglClientWaitSyncKHR", P(EGL_ClientWaitSyncKHR)},
+ {"eglCopyBuffers", P(EGL_CopyBuffers)},
+ {"eglCopyMetalSharedEventANGLE", P(EGL_CopyMetalSharedEventANGLE)},
+ {"eglCreateContext", P(EGL_CreateContext)},
+ {"eglCreateDeviceANGLE", P(EGL_CreateDeviceANGLE)},
+ {"eglCreateImage", P(EGL_CreateImage)},
+ {"eglCreateImageKHR", P(EGL_CreateImageKHR)},
+ {"eglCreateNativeClientBufferANDROID", P(EGL_CreateNativeClientBufferANDROID)},
+ {"eglCreatePbufferFromClientBuffer", P(EGL_CreatePbufferFromClientBuffer)},
+ {"eglCreatePbufferSurface", P(EGL_CreatePbufferSurface)},
+ {"eglCreatePixmapSurface", P(EGL_CreatePixmapSurface)},
+ {"eglCreatePlatformPixmapSurface", P(EGL_CreatePlatformPixmapSurface)},
+ {"eglCreatePlatformPixmapSurfaceEXT", P(EGL_CreatePlatformPixmapSurfaceEXT)},
+ {"eglCreatePlatformWindowSurface", P(EGL_CreatePlatformWindowSurface)},
+ {"eglCreatePlatformWindowSurfaceEXT", P(EGL_CreatePlatformWindowSurfaceEXT)},
+ {"eglCreateStreamKHR", P(EGL_CreateStreamKHR)},
+ {"eglCreateStreamProducerD3DTextureANGLE", P(EGL_CreateStreamProducerD3DTextureANGLE)},
+ {"eglCreateSync", P(EGL_CreateSync)},
+ {"eglCreateSyncKHR", P(EGL_CreateSyncKHR)},
+ {"eglCreateWindowSurface", P(EGL_CreateWindowSurface)},
+ {"eglDebugMessageControlKHR", P(EGL_DebugMessageControlKHR)},
+ {"eglDestroyContext", P(EGL_DestroyContext)},
+ {"eglDestroyImage", P(EGL_DestroyImage)},
+ {"eglDestroyImageKHR", P(EGL_DestroyImageKHR)},
+ {"eglDestroyStreamKHR", P(EGL_DestroyStreamKHR)},
+ {"eglDestroySurface", P(EGL_DestroySurface)},
+ {"eglDestroySync", P(EGL_DestroySync)},
+ {"eglDestroySyncKHR", P(EGL_DestroySyncKHR)},
+ {"eglDupNativeFenceFDANDROID", P(EGL_DupNativeFenceFDANDROID)},
+ {"eglExportVkImageANGLE", P(EGL_ExportVkImageANGLE)},
+ {"eglForceGPUSwitchANGLE", P(EGL_ForceGPUSwitchANGLE)},
+ {"eglGetCompositorTimingANDROID", P(EGL_GetCompositorTimingANDROID)},
+ {"eglGetCompositorTimingSupportedANDROID", P(EGL_GetCompositorTimingSupportedANDROID)},
+ {"eglGetConfigAttrib", P(EGL_GetConfigAttrib)},
+ {"eglGetConfigs", P(EGL_GetConfigs)},
+ {"eglGetCurrentContext", P(EGL_GetCurrentContext)},
+ {"eglGetCurrentDisplay", P(EGL_GetCurrentDisplay)},
+ {"eglGetCurrentSurface", P(EGL_GetCurrentSurface)},
+ {"eglGetDisplay", P(EGL_GetDisplay)},
+ {"eglGetError", P(EGL_GetError)},
+ {"eglGetFrameTimestampSupportedANDROID", P(EGL_GetFrameTimestampSupportedANDROID)},
+ {"eglGetFrameTimestampsANDROID", P(EGL_GetFrameTimestampsANDROID)},
+ {"eglGetMscRateANGLE", P(EGL_GetMscRateANGLE)},
+ {"eglGetNativeClientBufferANDROID", P(EGL_GetNativeClientBufferANDROID)},
+ {"eglGetNextFrameIdANDROID", P(EGL_GetNextFrameIdANDROID)},
+ {"eglGetPlatformDisplay", P(EGL_GetPlatformDisplay)},
+ {"eglGetPlatformDisplayEXT", P(EGL_GetPlatformDisplayEXT)},
+ {"eglGetProcAddress", P(EGL_GetProcAddress)},
+ {"eglGetSyncAttrib", P(EGL_GetSyncAttrib)},
+ {"eglGetSyncAttribKHR", P(EGL_GetSyncAttribKHR)},
+ {"eglGetSyncValuesCHROMIUM", P(EGL_GetSyncValuesCHROMIUM)},
+ {"eglHandleGPUSwitchANGLE", P(EGL_HandleGPUSwitchANGLE)},
+ {"eglInitialize", P(EGL_Initialize)},
+ {"eglLabelObjectKHR", P(EGL_LabelObjectKHR)},
+ {"eglLockSurfaceKHR", P(EGL_LockSurfaceKHR)},
+ {"eglMakeCurrent", P(EGL_MakeCurrent)},
+ {"eglPostSubBufferNV", P(EGL_PostSubBufferNV)},
+ {"eglPrepareSwapBuffersANGLE", P(EGL_PrepareSwapBuffersANGLE)},
+ {"eglPresentationTimeANDROID", P(EGL_PresentationTimeANDROID)},
+ {"eglProgramCacheGetAttribANGLE", P(EGL_ProgramCacheGetAttribANGLE)},
+ {"eglProgramCachePopulateANGLE", P(EGL_ProgramCachePopulateANGLE)},
+ {"eglProgramCacheQueryANGLE", P(EGL_ProgramCacheQueryANGLE)},
+ {"eglProgramCacheResizeANGLE", P(EGL_ProgramCacheResizeANGLE)},
+ {"eglQueryAPI", P(EGL_QueryAPI)},
+ {"eglQueryContext", P(EGL_QueryContext)},
+ {"eglQueryDebugKHR", P(EGL_QueryDebugKHR)},
+ {"eglQueryDeviceAttribEXT", P(EGL_QueryDeviceAttribEXT)},
+ {"eglQueryDeviceStringEXT", P(EGL_QueryDeviceStringEXT)},
+ {"eglQueryDisplayAttribANGLE", P(EGL_QueryDisplayAttribANGLE)},
+ {"eglQueryDisplayAttribEXT", P(EGL_QueryDisplayAttribEXT)},
+ {"eglQueryDmaBufFormatsEXT", P(EGL_QueryDmaBufFormatsEXT)},
+ {"eglQueryDmaBufModifiersEXT", P(EGL_QueryDmaBufModifiersEXT)},
+ {"eglQueryStreamKHR", P(EGL_QueryStreamKHR)},
+ {"eglQueryStreamu64KHR", P(EGL_QueryStreamu64KHR)},
+ {"eglQueryString", P(EGL_QueryString)},
+ {"eglQueryStringiANGLE", P(EGL_QueryStringiANGLE)},
+ {"eglQuerySurface", P(EGL_QuerySurface)},
+ {"eglQuerySurface64KHR", P(EGL_QuerySurface64KHR)},
+ {"eglQuerySurfacePointerANGLE", P(EGL_QuerySurfacePointerANGLE)},
+ {"eglReacquireHighPowerGPUANGLE", P(EGL_ReacquireHighPowerGPUANGLE)},
+ {"eglReleaseDeviceANGLE", P(EGL_ReleaseDeviceANGLE)},
+ {"eglReleaseHighPowerGPUANGLE", P(EGL_ReleaseHighPowerGPUANGLE)},
+ {"eglReleaseTexImage", P(EGL_ReleaseTexImage)},
+ {"eglReleaseThread", P(EGL_ReleaseThread)},
+ {"eglSetBlobCacheFuncsANDROID", P(EGL_SetBlobCacheFuncsANDROID)},
+ {"eglSetDamageRegionKHR", P(EGL_SetDamageRegionKHR)},
+ {"eglSignalSyncKHR", P(EGL_SignalSyncKHR)},
+ {"eglStreamAttribKHR", P(EGL_StreamAttribKHR)},
+ {"eglStreamConsumerAcquireKHR", P(EGL_StreamConsumerAcquireKHR)},
+ {"eglStreamConsumerGLTextureExternalAttribsNV", P(EGL_StreamConsumerGLTextureExternalAttribsNV)},
+ {"eglStreamConsumerGLTextureExternalKHR", P(EGL_StreamConsumerGLTextureExternalKHR)},
+ {"eglStreamConsumerReleaseKHR", P(EGL_StreamConsumerReleaseKHR)},
+ {"eglStreamPostD3DTextureANGLE", P(EGL_StreamPostD3DTextureANGLE)},
+ {"eglSurfaceAttrib", P(EGL_SurfaceAttrib)},
+ {"eglSwapBuffers", P(EGL_SwapBuffers)},
+ {"eglSwapBuffersWithDamageKHR", P(EGL_SwapBuffersWithDamageKHR)},
+ {"eglSwapBuffersWithFrameTokenANGLE", P(EGL_SwapBuffersWithFrameTokenANGLE)},
+ {"eglSwapInterval", P(EGL_SwapInterval)},
+ {"eglTerminate", P(EGL_Terminate)},
+ {"eglUnlockSurfaceKHR", P(EGL_UnlockSurfaceKHR)},
+ {"eglWaitClient", P(EGL_WaitClient)},
+ {"eglWaitGL", P(EGL_WaitGL)},
+ {"eglWaitNative", P(EGL_WaitNative)},
+ {"eglWaitSync", P(EGL_WaitSync)},
+ {"eglWaitSyncKHR", P(EGL_WaitSyncKHR)},
+ DESKTOP_ONLY("glAccum", GL_Accum)
+ {"glAcquireTexturesANGLE", P(GL_AcquireTexturesANGLE)},
+ {"glActiveShaderProgram", P(GL_ActiveShaderProgram)},
+ {"glActiveShaderProgramEXT", P(GL_ActiveShaderProgramEXT)},
+ {"glActiveTexture", P(GL_ActiveTexture)},
+ {"glAlphaFunc", P(GL_AlphaFunc)},
+ {"glAlphaFuncx", P(GL_AlphaFuncx)},
+ DESKTOP_ONLY("glAreTexturesResident", GL_AreTexturesResident)
+ DESKTOP_ONLY("glArrayElement", GL_ArrayElement)
+ {"glAttachShader", P(GL_AttachShader)},
+ DESKTOP_ONLY("glBegin", GL_Begin)
+ DESKTOP_ONLY("glBeginConditionalRender", GL_BeginConditionalRender)
+ {"glBeginPerfMonitorAMD", P(GL_BeginPerfMonitorAMD)},
+ {"glBeginPixelLocalStorageANGLE", P(GL_BeginPixelLocalStorageANGLE)},
+ {"glBeginQuery", P(GL_BeginQuery)},
+ {"glBeginQueryEXT", P(GL_BeginQueryEXT)},
+ DESKTOP_ONLY("glBeginQueryIndexed", GL_BeginQueryIndexed)
+ {"glBeginTransformFeedback", P(GL_BeginTransformFeedback)},
+ {"glBindAttribLocation", P(GL_BindAttribLocation)},
+ {"glBindBuffer", P(GL_BindBuffer)},
+ {"glBindBufferBase", P(GL_BindBufferBase)},
+ {"glBindBufferRange", P(GL_BindBufferRange)},
+ DESKTOP_ONLY("glBindBuffersBase", GL_BindBuffersBase)
+ DESKTOP_ONLY("glBindBuffersRange", GL_BindBuffersRange)
+ DESKTOP_ONLY("glBindFragDataLocation", GL_BindFragDataLocation)
+ {"glBindFragDataLocationEXT", P(GL_BindFragDataLocationEXT)},
+ DESKTOP_ONLY("glBindFragDataLocationIndexed", GL_BindFragDataLocationIndexed)
+ {"glBindFragDataLocationIndexedEXT", P(GL_BindFragDataLocationIndexedEXT)},
+ {"glBindFramebuffer", P(GL_BindFramebuffer)},
+ {"glBindFramebufferOES", P(GL_BindFramebufferOES)},
+ {"glBindImageTexture", P(GL_BindImageTexture)},
+ DESKTOP_ONLY("glBindImageTextures", GL_BindImageTextures)
+ {"glBindProgramPipeline", P(GL_BindProgramPipeline)},
+ {"glBindProgramPipelineEXT", P(GL_BindProgramPipelineEXT)},
+ {"glBindRenderbuffer", P(GL_BindRenderbuffer)},
+ {"glBindRenderbufferOES", P(GL_BindRenderbufferOES)},
+ {"glBindSampler", P(GL_BindSampler)},
+ DESKTOP_ONLY("glBindSamplers", GL_BindSamplers)
+ {"glBindTexture", P(GL_BindTexture)},
+ DESKTOP_ONLY("glBindTextureUnit", GL_BindTextureUnit)
+ DESKTOP_ONLY("glBindTextures", GL_BindTextures)
+ {"glBindTransformFeedback", P(GL_BindTransformFeedback)},
+ {"glBindUniformLocationCHROMIUM", P(GL_BindUniformLocationCHROMIUM)},
+ {"glBindVertexArray", P(GL_BindVertexArray)},
+ {"glBindVertexArrayOES", P(GL_BindVertexArrayOES)},
+ {"glBindVertexBuffer", P(GL_BindVertexBuffer)},
+ DESKTOP_ONLY("glBindVertexBuffers", GL_BindVertexBuffers)
+ DESKTOP_ONLY("glBitmap", GL_Bitmap)
+ {"glBlendBarrier", P(GL_BlendBarrier)},
+ {"glBlendBarrierKHR", P(GL_BlendBarrierKHR)},
+ {"glBlendColor", P(GL_BlendColor)},
+ {"glBlendEquation", P(GL_BlendEquation)},
+ {"glBlendEquationSeparate", P(GL_BlendEquationSeparate)},
+ {"glBlendEquationSeparatei", P(GL_BlendEquationSeparatei)},
+ {"glBlendEquationSeparateiEXT", P(GL_BlendEquationSeparateiEXT)},
+ {"glBlendEquationSeparateiOES", P(GL_BlendEquationSeparateiOES)},
+ {"glBlendEquationi", P(GL_BlendEquationi)},
+ {"glBlendEquationiEXT", P(GL_BlendEquationiEXT)},
+ {"glBlendEquationiOES", P(GL_BlendEquationiOES)},
+ {"glBlendFunc", P(GL_BlendFunc)},
+ {"glBlendFuncSeparate", P(GL_BlendFuncSeparate)},
+ {"glBlendFuncSeparatei", P(GL_BlendFuncSeparatei)},
+ {"glBlendFuncSeparateiEXT", P(GL_BlendFuncSeparateiEXT)},
+ {"glBlendFuncSeparateiOES", P(GL_BlendFuncSeparateiOES)},
+ {"glBlendFunci", P(GL_BlendFunci)},
+ {"glBlendFunciEXT", P(GL_BlendFunciEXT)},
+ {"glBlendFunciOES", P(GL_BlendFunciOES)},
+ {"glBlitFramebuffer", P(GL_BlitFramebuffer)},
+ {"glBlitFramebufferANGLE", P(GL_BlitFramebufferANGLE)},
+ {"glBlitFramebufferNV", P(GL_BlitFramebufferNV)},
+ DESKTOP_ONLY("glBlitNamedFramebuffer", GL_BlitNamedFramebuffer)
+ {"glBufferData", P(GL_BufferData)},
+ DESKTOP_ONLY("glBufferStorage", GL_BufferStorage)
+ {"glBufferStorageEXT", P(GL_BufferStorageEXT)},
+ {"glBufferStorageExternalEXT", P(GL_BufferStorageExternalEXT)},
+ {"glBufferStorageMemEXT", P(GL_BufferStorageMemEXT)},
+ {"glBufferSubData", P(GL_BufferSubData)},
+ DESKTOP_ONLY("glCallList", GL_CallList)
+ DESKTOP_ONLY("glCallLists", GL_CallLists)
+ {"glCheckFramebufferStatus", P(GL_CheckFramebufferStatus)},
+ {"glCheckFramebufferStatusOES", P(GL_CheckFramebufferStatusOES)},
+ DESKTOP_ONLY("glCheckNamedFramebufferStatus", GL_CheckNamedFramebufferStatus)
+ DESKTOP_ONLY("glClampColor", GL_ClampColor)
+ {"glClear", P(GL_Clear)},
+ DESKTOP_ONLY("glClearAccum", GL_ClearAccum)
+ DESKTOP_ONLY("glClearBufferData", GL_ClearBufferData)
+ DESKTOP_ONLY("glClearBufferSubData", GL_ClearBufferSubData)
+ {"glClearBufferfi", P(GL_ClearBufferfi)},
+ {"glClearBufferfv", P(GL_ClearBufferfv)},
+ {"glClearBufferiv", P(GL_ClearBufferiv)},
+ {"glClearBufferuiv", P(GL_ClearBufferuiv)},
+ {"glClearColor", P(GL_ClearColor)},
+ {"glClearColorx", P(GL_ClearColorx)},
+ DESKTOP_ONLY("glClearDepth", GL_ClearDepth)
+ {"glClearDepthf", P(GL_ClearDepthf)},
+ {"glClearDepthx", P(GL_ClearDepthx)},
+ DESKTOP_ONLY("glClearIndex", GL_ClearIndex)
+ DESKTOP_ONLY("glClearNamedBufferData", GL_ClearNamedBufferData)
+ DESKTOP_ONLY("glClearNamedBufferSubData", GL_ClearNamedBufferSubData)
+ DESKTOP_ONLY("glClearNamedFramebufferfi", GL_ClearNamedFramebufferfi)
+ DESKTOP_ONLY("glClearNamedFramebufferfv", GL_ClearNamedFramebufferfv)
+ DESKTOP_ONLY("glClearNamedFramebufferiv", GL_ClearNamedFramebufferiv)
+ DESKTOP_ONLY("glClearNamedFramebufferuiv", GL_ClearNamedFramebufferuiv)
+ {"glClearStencil", P(GL_ClearStencil)},
+ DESKTOP_ONLY("glClearTexImage", GL_ClearTexImage)
+ DESKTOP_ONLY("glClearTexSubImage", GL_ClearTexSubImage)
+ {"glClientActiveTexture", P(GL_ClientActiveTexture)},
+ {"glClientWaitSync", P(GL_ClientWaitSync)},
+ DESKTOP_ONLY("glClipControl", GL_ClipControl)
+ {"glClipControlEXT", P(GL_ClipControlEXT)},
+ DESKTOP_ONLY("glClipPlane", GL_ClipPlane)
+ {"glClipPlanef", P(GL_ClipPlanef)},
+ {"glClipPlanex", P(GL_ClipPlanex)},
+ DESKTOP_ONLY("glColor3b", GL_Color3b)
+ DESKTOP_ONLY("glColor3bv", GL_Color3bv)
+ DESKTOP_ONLY("glColor3d", GL_Color3d)
+ DESKTOP_ONLY("glColor3dv", GL_Color3dv)
+ DESKTOP_ONLY("glColor3f", GL_Color3f)
+ DESKTOP_ONLY("glColor3fv", GL_Color3fv)
+ DESKTOP_ONLY("glColor3i", GL_Color3i)
+ DESKTOP_ONLY("glColor3iv", GL_Color3iv)
+ DESKTOP_ONLY("glColor3s", GL_Color3s)
+ DESKTOP_ONLY("glColor3sv", GL_Color3sv)
+ DESKTOP_ONLY("glColor3ub", GL_Color3ub)
+ DESKTOP_ONLY("glColor3ubv", GL_Color3ubv)
+ DESKTOP_ONLY("glColor3ui", GL_Color3ui)
+ DESKTOP_ONLY("glColor3uiv", GL_Color3uiv)
+ DESKTOP_ONLY("glColor3us", GL_Color3us)
+ DESKTOP_ONLY("glColor3usv", GL_Color3usv)
+ DESKTOP_ONLY("glColor4b", GL_Color4b)
+ DESKTOP_ONLY("glColor4bv", GL_Color4bv)
+ DESKTOP_ONLY("glColor4d", GL_Color4d)
+ DESKTOP_ONLY("glColor4dv", GL_Color4dv)
+ {"glColor4f", P(GL_Color4f)},
+ DESKTOP_ONLY("glColor4fv", GL_Color4fv)
+ DESKTOP_ONLY("glColor4i", GL_Color4i)
+ DESKTOP_ONLY("glColor4iv", GL_Color4iv)
+ DESKTOP_ONLY("glColor4s", GL_Color4s)
+ DESKTOP_ONLY("glColor4sv", GL_Color4sv)
+ {"glColor4ub", P(GL_Color4ub)},
+ DESKTOP_ONLY("glColor4ubv", GL_Color4ubv)
+ DESKTOP_ONLY("glColor4ui", GL_Color4ui)
+ DESKTOP_ONLY("glColor4uiv", GL_Color4uiv)
+ DESKTOP_ONLY("glColor4us", GL_Color4us)
+ DESKTOP_ONLY("glColor4usv", GL_Color4usv)
+ {"glColor4x", P(GL_Color4x)},
+ {"glColorMask", P(GL_ColorMask)},
+ {"glColorMaski", P(GL_ColorMaski)},
+ {"glColorMaskiEXT", P(GL_ColorMaskiEXT)},
+ {"glColorMaskiOES", P(GL_ColorMaskiOES)},
+ DESKTOP_ONLY("glColorMaterial", GL_ColorMaterial)
+ DESKTOP_ONLY("glColorP3ui", GL_ColorP3ui)
+ DESKTOP_ONLY("glColorP3uiv", GL_ColorP3uiv)
+ DESKTOP_ONLY("glColorP4ui", GL_ColorP4ui)
+ DESKTOP_ONLY("glColorP4uiv", GL_ColorP4uiv)
+ {"glColorPointer", P(GL_ColorPointer)},
+ {"glCompileShader", P(GL_CompileShader)},
+ {"glCompressedCopyTextureCHROMIUM", P(GL_CompressedCopyTextureCHROMIUM)},
+ DESKTOP_ONLY("glCompressedTexImage1D", GL_CompressedTexImage1D)
+ {"glCompressedTexImage2D", P(GL_CompressedTexImage2D)},
+ {"glCompressedTexImage2DRobustANGLE", P(GL_CompressedTexImage2DRobustANGLE)},
+ {"glCompressedTexImage3D", P(GL_CompressedTexImage3D)},
+ {"glCompressedTexImage3DOES", P(GL_CompressedTexImage3DOES)},
+ {"glCompressedTexImage3DRobustANGLE", P(GL_CompressedTexImage3DRobustANGLE)},
+ DESKTOP_ONLY("glCompressedTexSubImage1D", GL_CompressedTexSubImage1D)
+ {"glCompressedTexSubImage2D", P(GL_CompressedTexSubImage2D)},
+ {"glCompressedTexSubImage2DRobustANGLE", P(GL_CompressedTexSubImage2DRobustANGLE)},
+ {"glCompressedTexSubImage3D", P(GL_CompressedTexSubImage3D)},
+ {"glCompressedTexSubImage3DOES", P(GL_CompressedTexSubImage3DOES)},
+ {"glCompressedTexSubImage3DRobustANGLE", P(GL_CompressedTexSubImage3DRobustANGLE)},
+ DESKTOP_ONLY("glCompressedTextureSubImage1D", GL_CompressedTextureSubImage1D)
+ DESKTOP_ONLY("glCompressedTextureSubImage2D", GL_CompressedTextureSubImage2D)
+ DESKTOP_ONLY("glCompressedTextureSubImage3D", GL_CompressedTextureSubImage3D)
+ {"glCopyBufferSubData", P(GL_CopyBufferSubData)},
+ {"glCopyImageSubData", P(GL_CopyImageSubData)},
+ {"glCopyImageSubDataEXT", P(GL_CopyImageSubDataEXT)},
+ {"glCopyImageSubDataOES", P(GL_CopyImageSubDataOES)},
+ DESKTOP_ONLY("glCopyNamedBufferSubData", GL_CopyNamedBufferSubData)
+ DESKTOP_ONLY("glCopyPixels", GL_CopyPixels)
+ {"glCopySubTexture3DANGLE", P(GL_CopySubTexture3DANGLE)},
+ {"glCopySubTextureCHROMIUM", P(GL_CopySubTextureCHROMIUM)},
+ DESKTOP_ONLY("glCopyTexImage1D", GL_CopyTexImage1D)
+ {"glCopyTexImage2D", P(GL_CopyTexImage2D)},
+ DESKTOP_ONLY("glCopyTexSubImage1D", GL_CopyTexSubImage1D)
+ {"glCopyTexSubImage2D", P(GL_CopyTexSubImage2D)},
+ {"glCopyTexSubImage3D", P(GL_CopyTexSubImage3D)},
+ {"glCopyTexSubImage3DOES", P(GL_CopyTexSubImage3DOES)},
+ {"glCopyTexture3DANGLE", P(GL_CopyTexture3DANGLE)},
+ {"glCopyTextureCHROMIUM", P(GL_CopyTextureCHROMIUM)},
+ DESKTOP_ONLY("glCopyTextureSubImage1D", GL_CopyTextureSubImage1D)
+ DESKTOP_ONLY("glCopyTextureSubImage2D", GL_CopyTextureSubImage2D)
+ DESKTOP_ONLY("glCopyTextureSubImage3D", GL_CopyTextureSubImage3D)
+ {"glCoverageModulationCHROMIUM", P(GL_CoverageModulationCHROMIUM)},
+ DESKTOP_ONLY("glCreateBuffers", GL_CreateBuffers)
+ DESKTOP_ONLY("glCreateFramebuffers", GL_CreateFramebuffers)
+ {"glCreateMemoryObjectsEXT", P(GL_CreateMemoryObjectsEXT)},
+ {"glCreateProgram", P(GL_CreateProgram)},
+ DESKTOP_ONLY("glCreateProgramPipelines", GL_CreateProgramPipelines)
+ DESKTOP_ONLY("glCreateQueries", GL_CreateQueries)
+ DESKTOP_ONLY("glCreateRenderbuffers", GL_CreateRenderbuffers)
+ DESKTOP_ONLY("glCreateSamplers", GL_CreateSamplers)
+ {"glCreateShader", P(GL_CreateShader)},
+ {"glCreateShaderProgramv", P(GL_CreateShaderProgramv)},
+ {"glCreateShaderProgramvEXT", P(GL_CreateShaderProgramvEXT)},
+ DESKTOP_ONLY("glCreateTextures", GL_CreateTextures)
+ DESKTOP_ONLY("glCreateTransformFeedbacks", GL_CreateTransformFeedbacks)
+ DESKTOP_ONLY("glCreateVertexArrays", GL_CreateVertexArrays)
+ {"glCullFace", P(GL_CullFace)},
+ {"glCurrentPaletteMatrixOES", P(GL_CurrentPaletteMatrixOES)},
+ {"glDebugMessageCallback", P(GL_DebugMessageCallback)},
+ {"glDebugMessageCallbackKHR", P(GL_DebugMessageCallbackKHR)},
+ {"glDebugMessageControl", P(GL_DebugMessageControl)},
+ {"glDebugMessageControlKHR", P(GL_DebugMessageControlKHR)},
+ {"glDebugMessageInsert", P(GL_DebugMessageInsert)},
+ {"glDebugMessageInsertKHR", P(GL_DebugMessageInsertKHR)},
+ {"glDeleteBuffers", P(GL_DeleteBuffers)},
+ {"glDeleteFencesNV", P(GL_DeleteFencesNV)},
+ {"glDeleteFramebuffers", P(GL_DeleteFramebuffers)},
+ {"glDeleteFramebuffersOES", P(GL_DeleteFramebuffersOES)},
+ DESKTOP_ONLY("glDeleteLists", GL_DeleteLists)
+ {"glDeleteMemoryObjectsEXT", P(GL_DeleteMemoryObjectsEXT)},
+ {"glDeletePerfMonitorsAMD", P(GL_DeletePerfMonitorsAMD)},
+ {"glDeleteProgram", P(GL_DeleteProgram)},
+ {"glDeleteProgramPipelines", P(GL_DeleteProgramPipelines)},
+ {"glDeleteProgramPipelinesEXT", P(GL_DeleteProgramPipelinesEXT)},
+ {"glDeleteQueries", P(GL_DeleteQueries)},
+ {"glDeleteQueriesEXT", P(GL_DeleteQueriesEXT)},
+ {"glDeleteRenderbuffers", P(GL_DeleteRenderbuffers)},
+ {"glDeleteRenderbuffersOES", P(GL_DeleteRenderbuffersOES)},
+ {"glDeleteSamplers", P(GL_DeleteSamplers)},
+ {"glDeleteSemaphoresEXT", P(GL_DeleteSemaphoresEXT)},
+ {"glDeleteShader", P(GL_DeleteShader)},
+ {"glDeleteSync", P(GL_DeleteSync)},
+ {"glDeleteTextures", P(GL_DeleteTextures)},
+ {"glDeleteTransformFeedbacks", P(GL_DeleteTransformFeedbacks)},
+ {"glDeleteVertexArrays", P(GL_DeleteVertexArrays)},
+ {"glDeleteVertexArraysOES", P(GL_DeleteVertexArraysOES)},
+ {"glDepthFunc", P(GL_DepthFunc)},
+ {"glDepthMask", P(GL_DepthMask)},
+ DESKTOP_ONLY("glDepthRange", GL_DepthRange)
+ DESKTOP_ONLY("glDepthRangeArrayv", GL_DepthRangeArrayv)
+ DESKTOP_ONLY("glDepthRangeIndexed", GL_DepthRangeIndexed)
+ {"glDepthRangef", P(GL_DepthRangef)},
+ {"glDepthRangex", P(GL_DepthRangex)},
+ {"glDetachShader", P(GL_DetachShader)},
+ {"glDisable", P(GL_Disable)},
+ {"glDisableClientState", P(GL_DisableClientState)},
+ {"glDisableExtensionANGLE", P(GL_DisableExtensionANGLE)},
+ DESKTOP_ONLY("glDisableVertexArrayAttrib", GL_DisableVertexArrayAttrib)
+ {"glDisableVertexAttribArray", P(GL_DisableVertexAttribArray)},
+ {"glDisablei", P(GL_Disablei)},
+ {"glDisableiEXT", P(GL_DisableiEXT)},
+ {"glDisableiOES", P(GL_DisableiOES)},
+ {"glDiscardFramebufferEXT", P(GL_DiscardFramebufferEXT)},
+ {"glDispatchCompute", P(GL_DispatchCompute)},
+ {"glDispatchComputeIndirect", P(GL_DispatchComputeIndirect)},
+ {"glDrawArrays", P(GL_DrawArrays)},
+ {"glDrawArraysIndirect", P(GL_DrawArraysIndirect)},
+ {"glDrawArraysInstanced", P(GL_DrawArraysInstanced)},
+ {"glDrawArraysInstancedANGLE", P(GL_DrawArraysInstancedANGLE)},
+ DESKTOP_ONLY("glDrawArraysInstancedBaseInstance", GL_DrawArraysInstancedBaseInstance)
+ {"glDrawArraysInstancedBaseInstanceANGLE", P(GL_DrawArraysInstancedBaseInstanceANGLE)},
+ {"glDrawArraysInstancedBaseInstanceEXT", P(GL_DrawArraysInstancedBaseInstanceEXT)},
+ {"glDrawArraysInstancedEXT", P(GL_DrawArraysInstancedEXT)},
+ DESKTOP_ONLY("glDrawBuffer", GL_DrawBuffer)
+ {"glDrawBuffers", P(GL_DrawBuffers)},
+ {"glDrawBuffersEXT", P(GL_DrawBuffersEXT)},
+ {"glDrawElements", P(GL_DrawElements)},
+ {"glDrawElementsBaseVertex", P(GL_DrawElementsBaseVertex)},
+ {"glDrawElementsBaseVertexEXT", P(GL_DrawElementsBaseVertexEXT)},
+ {"glDrawElementsBaseVertexOES", P(GL_DrawElementsBaseVertexOES)},
+ {"glDrawElementsIndirect", P(GL_DrawElementsIndirect)},
+ {"glDrawElementsInstanced", P(GL_DrawElementsInstanced)},
+ {"glDrawElementsInstancedANGLE", P(GL_DrawElementsInstancedANGLE)},
+ DESKTOP_ONLY("glDrawElementsInstancedBaseInstance", GL_DrawElementsInstancedBaseInstance)
+ {"glDrawElementsInstancedBaseInstanceEXT", P(GL_DrawElementsInstancedBaseInstanceEXT)},
+ {"glDrawElementsInstancedBaseVertex", P(GL_DrawElementsInstancedBaseVertex)},
+ DESKTOP_ONLY("glDrawElementsInstancedBaseVertexBaseInstance", GL_DrawElementsInstancedBaseVertexBaseInstance)
+ {"glDrawElementsInstancedBaseVertexBaseInstanceANGLE", P(GL_DrawElementsInstancedBaseVertexBaseInstanceANGLE)},
+ {"glDrawElementsInstancedBaseVertexBaseInstanceEXT", P(GL_DrawElementsInstancedBaseVertexBaseInstanceEXT)},
+ {"glDrawElementsInstancedBaseVertexEXT", P(GL_DrawElementsInstancedBaseVertexEXT)},
+ {"glDrawElementsInstancedBaseVertexOES", P(GL_DrawElementsInstancedBaseVertexOES)},
+ {"glDrawElementsInstancedEXT", P(GL_DrawElementsInstancedEXT)},
+ DESKTOP_ONLY("glDrawPixels", GL_DrawPixels)
+ {"glDrawRangeElements", P(GL_DrawRangeElements)},
+ {"glDrawRangeElementsBaseVertex", P(GL_DrawRangeElementsBaseVertex)},
+ {"glDrawRangeElementsBaseVertexEXT", P(GL_DrawRangeElementsBaseVertexEXT)},
+ {"glDrawRangeElementsBaseVertexOES", P(GL_DrawRangeElementsBaseVertexOES)},
+ {"glDrawTexfOES", P(GL_DrawTexfOES)},
+ {"glDrawTexfvOES", P(GL_DrawTexfvOES)},
+ {"glDrawTexiOES", P(GL_DrawTexiOES)},
+ {"glDrawTexivOES", P(GL_DrawTexivOES)},
+ {"glDrawTexsOES", P(GL_DrawTexsOES)},
+ {"glDrawTexsvOES", P(GL_DrawTexsvOES)},
+ {"glDrawTexxOES", P(GL_DrawTexxOES)},
+ {"glDrawTexxvOES", P(GL_DrawTexxvOES)},
+ DESKTOP_ONLY("glDrawTransformFeedback", GL_DrawTransformFeedback)
+ DESKTOP_ONLY("glDrawTransformFeedbackInstanced", GL_DrawTransformFeedbackInstanced)
+ DESKTOP_ONLY("glDrawTransformFeedbackStream", GL_DrawTransformFeedbackStream)
+ DESKTOP_ONLY("glDrawTransformFeedbackStreamInstanced", GL_DrawTransformFeedbackStreamInstanced)
+ {"glEGLImageTargetRenderbufferStorageOES", P(GL_EGLImageTargetRenderbufferStorageOES)},
+ {"glEGLImageTargetTexStorageEXT", P(GL_EGLImageTargetTexStorageEXT)},
+ {"glEGLImageTargetTexture2DOES", P(GL_EGLImageTargetTexture2DOES)},
+ {"glEGLImageTargetTextureStorageEXT", P(GL_EGLImageTargetTextureStorageEXT)},
+ DESKTOP_ONLY("glEdgeFlag", GL_EdgeFlag)
+ DESKTOP_ONLY("glEdgeFlagPointer", GL_EdgeFlagPointer)
+ DESKTOP_ONLY("glEdgeFlagv", GL_EdgeFlagv)
+ {"glEnable", P(GL_Enable)},
+ {"glEnableClientState", P(GL_EnableClientState)},
+ DESKTOP_ONLY("glEnableVertexArrayAttrib", GL_EnableVertexArrayAttrib)
+ {"glEnableVertexAttribArray", P(GL_EnableVertexAttribArray)},
+ {"glEnablei", P(GL_Enablei)},
+ {"glEnableiEXT", P(GL_EnableiEXT)},
+ {"glEnableiOES", P(GL_EnableiOES)},
+ DESKTOP_ONLY("glEnd", GL_End)
+ DESKTOP_ONLY("glEndConditionalRender", GL_EndConditionalRender)
+ DESKTOP_ONLY("glEndList", GL_EndList)
+ {"glEndPerfMonitorAMD", P(GL_EndPerfMonitorAMD)},
+ {"glEndPixelLocalStorageANGLE", P(GL_EndPixelLocalStorageANGLE)},
+ {"glEndQuery", P(GL_EndQuery)},
+ {"glEndQueryEXT", P(GL_EndQueryEXT)},
+ DESKTOP_ONLY("glEndQueryIndexed", GL_EndQueryIndexed)
+ {"glEndTransformFeedback", P(GL_EndTransformFeedback)},
+ DESKTOP_ONLY("glEvalCoord1d", GL_EvalCoord1d)
+ DESKTOP_ONLY("glEvalCoord1dv", GL_EvalCoord1dv)
+ DESKTOP_ONLY("glEvalCoord1f", GL_EvalCoord1f)
+ DESKTOP_ONLY("glEvalCoord1fv", GL_EvalCoord1fv)
+ DESKTOP_ONLY("glEvalCoord2d", GL_EvalCoord2d)
+ DESKTOP_ONLY("glEvalCoord2dv", GL_EvalCoord2dv)
+ DESKTOP_ONLY("glEvalCoord2f", GL_EvalCoord2f)
+ DESKTOP_ONLY("glEvalCoord2fv", GL_EvalCoord2fv)
+ DESKTOP_ONLY("glEvalMesh1", GL_EvalMesh1)
+ DESKTOP_ONLY("glEvalMesh2", GL_EvalMesh2)
+ DESKTOP_ONLY("glEvalPoint1", GL_EvalPoint1)
+ DESKTOP_ONLY("glEvalPoint2", GL_EvalPoint2)
+ DESKTOP_ONLY("glFeedbackBuffer", GL_FeedbackBuffer)
+ {"glFenceSync", P(GL_FenceSync)},
+ {"glFinish", P(GL_Finish)},
+ {"glFinishFenceNV", P(GL_FinishFenceNV)},
+ {"glFlush", P(GL_Flush)},
+ {"glFlushMappedBufferRange", P(GL_FlushMappedBufferRange)},
+ {"glFlushMappedBufferRangeEXT", P(GL_FlushMappedBufferRangeEXT)},
+ DESKTOP_ONLY("glFlushMappedNamedBufferRange", GL_FlushMappedNamedBufferRange)
+ DESKTOP_ONLY("glFogCoordPointer", GL_FogCoordPointer)
+ DESKTOP_ONLY("glFogCoordd", GL_FogCoordd)
+ DESKTOP_ONLY("glFogCoorddv", GL_FogCoorddv)
+ DESKTOP_ONLY("glFogCoordf", GL_FogCoordf)
+ DESKTOP_ONLY("glFogCoordfv", GL_FogCoordfv)
+ {"glFogf", P(GL_Fogf)},
+ {"glFogfv", P(GL_Fogfv)},
+ DESKTOP_ONLY("glFogi", GL_Fogi)
+ DESKTOP_ONLY("glFogiv", GL_Fogiv)
+ {"glFogx", P(GL_Fogx)},
+ {"glFogxv", P(GL_Fogxv)},
+ {"glFramebufferFetchBarrierEXT", P(GL_FramebufferFetchBarrierEXT)},
+ {"glFramebufferMemorylessPixelLocalStorageANGLE", P(GL_FramebufferMemorylessPixelLocalStorageANGLE)},
+ {"glFramebufferParameteri", P(GL_FramebufferParameteri)},
+ {"glFramebufferParameteriMESA", P(GL_FramebufferParameteriMESA)},
+ {"glFramebufferRenderbuffer", P(GL_FramebufferRenderbuffer)},
+ {"glFramebufferRenderbufferOES", P(GL_FramebufferRenderbufferOES)},
+ {"glFramebufferTexture", P(GL_FramebufferTexture)},
+ DESKTOP_ONLY("glFramebufferTexture1D", GL_FramebufferTexture1D)
+ {"glFramebufferTexture2D", P(GL_FramebufferTexture2D)},
+ {"glFramebufferTexture2DMultisampleEXT", P(GL_FramebufferTexture2DMultisampleEXT)},
+ {"glFramebufferTexture2DOES", P(GL_FramebufferTexture2DOES)},
+ DESKTOP_ONLY("glFramebufferTexture3D", GL_FramebufferTexture3D)
+ {"glFramebufferTexture3DOES", P(GL_FramebufferTexture3DOES)},
+ {"glFramebufferTextureEXT", P(GL_FramebufferTextureEXT)},
+ {"glFramebufferTextureLayer", P(GL_FramebufferTextureLayer)},
+ {"glFramebufferTextureMultiviewOVR", P(GL_FramebufferTextureMultiviewOVR)},
+ {"glFramebufferTextureOES", P(GL_FramebufferTextureOES)},
+ {"glFramebufferTexturePixelLocalStorageANGLE", P(GL_FramebufferTexturePixelLocalStorageANGLE)},
+ {"glFrontFace", P(GL_FrontFace)},
+ DESKTOP_ONLY("glFrustum", GL_Frustum)
+ {"glFrustumf", P(GL_Frustumf)},
+ {"glFrustumx", P(GL_Frustumx)},
+ {"glGenBuffers", P(GL_GenBuffers)},
+ {"glGenFencesNV", P(GL_GenFencesNV)},
+ {"glGenFramebuffers", P(GL_GenFramebuffers)},
+ {"glGenFramebuffersOES", P(GL_GenFramebuffersOES)},
+ DESKTOP_ONLY("glGenLists", GL_GenLists)
+ {"glGenPerfMonitorsAMD", P(GL_GenPerfMonitorsAMD)},
+ {"glGenProgramPipelines", P(GL_GenProgramPipelines)},
+ {"glGenProgramPipelinesEXT", P(GL_GenProgramPipelinesEXT)},
+ {"glGenQueries", P(GL_GenQueries)},
+ {"glGenQueriesEXT", P(GL_GenQueriesEXT)},
+ {"glGenRenderbuffers", P(GL_GenRenderbuffers)},
+ {"glGenRenderbuffersOES", P(GL_GenRenderbuffersOES)},
+ {"glGenSamplers", P(GL_GenSamplers)},
+ {"glGenSemaphoresEXT", P(GL_GenSemaphoresEXT)},
+ {"glGenTextures", P(GL_GenTextures)},
+ {"glGenTransformFeedbacks", P(GL_GenTransformFeedbacks)},
+ {"glGenVertexArrays", P(GL_GenVertexArrays)},
+ {"glGenVertexArraysOES", P(GL_GenVertexArraysOES)},
+ {"glGenerateMipmap", P(GL_GenerateMipmap)},
+ {"glGenerateMipmapOES", P(GL_GenerateMipmapOES)},
+ DESKTOP_ONLY("glGenerateTextureMipmap", GL_GenerateTextureMipmap)
+ DESKTOP_ONLY("glGetActiveAtomicCounterBufferiv", GL_GetActiveAtomicCounterBufferiv)
+ {"glGetActiveAttrib", P(GL_GetActiveAttrib)},
+ DESKTOP_ONLY("glGetActiveSubroutineName", GL_GetActiveSubroutineName)
+ DESKTOP_ONLY("glGetActiveSubroutineUniformName", GL_GetActiveSubroutineUniformName)
+ DESKTOP_ONLY("glGetActiveSubroutineUniformiv", GL_GetActiveSubroutineUniformiv)
+ {"glGetActiveUniform", P(GL_GetActiveUniform)},
+ {"glGetActiveUniformBlockName", P(GL_GetActiveUniformBlockName)},
+ {"glGetActiveUniformBlockiv", P(GL_GetActiveUniformBlockiv)},
+ {"glGetActiveUniformBlockivRobustANGLE", P(GL_GetActiveUniformBlockivRobustANGLE)},
+ DESKTOP_ONLY("glGetActiveUniformName", GL_GetActiveUniformName)
+ {"glGetActiveUniformsiv", P(GL_GetActiveUniformsiv)},
+ {"glGetAttachedShaders", P(GL_GetAttachedShaders)},
+ {"glGetAttribLocation", P(GL_GetAttribLocation)},
+ {"glGetBooleani_v", P(GL_GetBooleani_v)},
+ {"glGetBooleani_vRobustANGLE", P(GL_GetBooleani_vRobustANGLE)},
+ {"glGetBooleanv", P(GL_GetBooleanv)},
+ {"glGetBooleanvRobustANGLE", P(GL_GetBooleanvRobustANGLE)},
+ {"glGetBufferParameteri64v", P(GL_GetBufferParameteri64v)},
+ {"glGetBufferParameteri64vRobustANGLE", P(GL_GetBufferParameteri64vRobustANGLE)},
+ {"glGetBufferParameteriv", P(GL_GetBufferParameteriv)},
+ {"glGetBufferParameterivRobustANGLE", P(GL_GetBufferParameterivRobustANGLE)},
+ {"glGetBufferPointerv", P(GL_GetBufferPointerv)},
+ {"glGetBufferPointervOES", P(GL_GetBufferPointervOES)},
+ {"glGetBufferPointervRobustANGLE", P(GL_GetBufferPointervRobustANGLE)},
+ DESKTOP_ONLY("glGetBufferSubData", GL_GetBufferSubData)
+ DESKTOP_ONLY("glGetClipPlane", GL_GetClipPlane)
+ {"glGetClipPlanef", P(GL_GetClipPlanef)},
+ {"glGetClipPlanex", P(GL_GetClipPlanex)},
+ DESKTOP_ONLY("glGetCompressedTexImage", GL_GetCompressedTexImage)
+ {"glGetCompressedTexImageANGLE", P(GL_GetCompressedTexImageANGLE)},
+ DESKTOP_ONLY("glGetCompressedTextureImage", GL_GetCompressedTextureImage)
+ DESKTOP_ONLY("glGetCompressedTextureSubImage", GL_GetCompressedTextureSubImage)
+ {"glGetDebugMessageLog", P(GL_GetDebugMessageLog)},
+ {"glGetDebugMessageLogKHR", P(GL_GetDebugMessageLogKHR)},
+ DESKTOP_ONLY("glGetDoublei_v", GL_GetDoublei_v)
+ DESKTOP_ONLY("glGetDoublev", GL_GetDoublev)
+ {"glGetError", P(GL_GetError)},
+ {"glGetFenceivNV", P(GL_GetFenceivNV)},
+ {"glGetFixedv", P(GL_GetFixedv)},
+ DESKTOP_ONLY("glGetFloati_v", GL_GetFloati_v)
+ {"glGetFloatv", P(GL_GetFloatv)},
+ {"glGetFloatvRobustANGLE", P(GL_GetFloatvRobustANGLE)},
+ DESKTOP_ONLY("glGetFragDataIndex", GL_GetFragDataIndex)
+ {"glGetFragDataIndexEXT", P(GL_GetFragDataIndexEXT)},
+ {"glGetFragDataLocation", P(GL_GetFragDataLocation)},
+ {"glGetFramebufferAttachmentParameteriv", P(GL_GetFramebufferAttachmentParameteriv)},
+ {"glGetFramebufferAttachmentParameterivOES", P(GL_GetFramebufferAttachmentParameterivOES)},
+ {"glGetFramebufferAttachmentParameterivRobustANGLE", P(GL_GetFramebufferAttachmentParameterivRobustANGLE)},
+ {"glGetFramebufferParameteriv", P(GL_GetFramebufferParameteriv)},
+ {"glGetFramebufferParameterivMESA", P(GL_GetFramebufferParameterivMESA)},
+ {"glGetFramebufferParameterivRobustANGLE", P(GL_GetFramebufferParameterivRobustANGLE)},
+ {"glGetGraphicsResetStatus", P(GL_GetGraphicsResetStatus)},
+ {"glGetGraphicsResetStatusEXT", P(GL_GetGraphicsResetStatusEXT)},
+ {"glGetInteger64i_v", P(GL_GetInteger64i_v)},
+ {"glGetInteger64i_vRobustANGLE", P(GL_GetInteger64i_vRobustANGLE)},
+ {"glGetInteger64v", P(GL_GetInteger64v)},
+ {"glGetInteger64vEXT", P(GL_GetInteger64vEXT)},
+ {"glGetInteger64vRobustANGLE", P(GL_GetInteger64vRobustANGLE)},
+ {"glGetIntegeri_v", P(GL_GetIntegeri_v)},
+ {"glGetIntegeri_vRobustANGLE", P(GL_GetIntegeri_vRobustANGLE)},
+ {"glGetIntegerv", P(GL_GetIntegerv)},
+ {"glGetIntegervRobustANGLE", P(GL_GetIntegervRobustANGLE)},
+ DESKTOP_ONLY("glGetInternalformati64v", GL_GetInternalformati64v)
+ {"glGetInternalformativ", P(GL_GetInternalformativ)},
+ {"glGetInternalformativRobustANGLE", P(GL_GetInternalformativRobustANGLE)},
+ {"glGetLightfv", P(GL_GetLightfv)},
+ DESKTOP_ONLY("glGetLightiv", GL_GetLightiv)
+ {"glGetLightxv", P(GL_GetLightxv)},
+ DESKTOP_ONLY("glGetMapdv", GL_GetMapdv)
+ DESKTOP_ONLY("glGetMapfv", GL_GetMapfv)
+ DESKTOP_ONLY("glGetMapiv", GL_GetMapiv)
+ {"glGetMaterialfv", P(GL_GetMaterialfv)},
+ DESKTOP_ONLY("glGetMaterialiv", GL_GetMaterialiv)
+ {"glGetMaterialxv", P(GL_GetMaterialxv)},
+ {"glGetMemoryObjectParameterivEXT", P(GL_GetMemoryObjectParameterivEXT)},
+ {"glGetMultisamplefv", P(GL_GetMultisamplefv)},
+ {"glGetMultisamplefvANGLE", P(GL_GetMultisamplefvANGLE)},
+ {"glGetMultisamplefvRobustANGLE", P(GL_GetMultisamplefvRobustANGLE)},
+ DESKTOP_ONLY("glGetNamedBufferParameteri64v", GL_GetNamedBufferParameteri64v)
+ DESKTOP_ONLY("glGetNamedBufferParameteriv", GL_GetNamedBufferParameteriv)
+ DESKTOP_ONLY("glGetNamedBufferPointerv", GL_GetNamedBufferPointerv)
+ DESKTOP_ONLY("glGetNamedBufferSubData", GL_GetNamedBufferSubData)
+ DESKTOP_ONLY("glGetNamedFramebufferAttachmentParameteriv", GL_GetNamedFramebufferAttachmentParameteriv)
+ DESKTOP_ONLY("glGetNamedFramebufferParameteriv", GL_GetNamedFramebufferParameteriv)
+ DESKTOP_ONLY("glGetNamedRenderbufferParameteriv", GL_GetNamedRenderbufferParameteriv)
+ {"glGetObjectLabel", P(GL_GetObjectLabel)},
+ {"glGetObjectLabelEXT", P(GL_GetObjectLabelEXT)},
+ {"glGetObjectLabelKHR", P(GL_GetObjectLabelKHR)},
+ {"glGetObjectPtrLabel", P(GL_GetObjectPtrLabel)},
+ {"glGetObjectPtrLabelKHR", P(GL_GetObjectPtrLabelKHR)},
+ {"glGetPerfMonitorCounterDataAMD", P(GL_GetPerfMonitorCounterDataAMD)},
+ {"glGetPerfMonitorCounterInfoAMD", P(GL_GetPerfMonitorCounterInfoAMD)},
+ {"glGetPerfMonitorCounterStringAMD", P(GL_GetPerfMonitorCounterStringAMD)},
+ {"glGetPerfMonitorCountersAMD", P(GL_GetPerfMonitorCountersAMD)},
+ {"glGetPerfMonitorGroupStringAMD", P(GL_GetPerfMonitorGroupStringAMD)},
+ {"glGetPerfMonitorGroupsAMD", P(GL_GetPerfMonitorGroupsAMD)},
+ DESKTOP_ONLY("glGetPixelMapfv", GL_GetPixelMapfv)
+ DESKTOP_ONLY("glGetPixelMapuiv", GL_GetPixelMapuiv)
+ DESKTOP_ONLY("glGetPixelMapusv", GL_GetPixelMapusv)
+ {"glGetPointerv", P(GL_GetPointerv)},
+ {"glGetPointervKHR", P(GL_GetPointervKHR)},
+ {"glGetPointervRobustANGLERobustANGLE", P(GL_GetPointervRobustANGLERobustANGLE)},
+ DESKTOP_ONLY("glGetPolygonStipple", GL_GetPolygonStipple)
+ {"glGetProgramBinary", P(GL_GetProgramBinary)},
+ {"glGetProgramBinaryOES", P(GL_GetProgramBinaryOES)},
+ {"glGetProgramInfoLog", P(GL_GetProgramInfoLog)},
+ {"glGetProgramInterfaceiv", P(GL_GetProgramInterfaceiv)},
+ {"glGetProgramInterfaceivRobustANGLE", P(GL_GetProgramInterfaceivRobustANGLE)},
+ {"glGetProgramPipelineInfoLog", P(GL_GetProgramPipelineInfoLog)},
+ {"glGetProgramPipelineInfoLogEXT", P(GL_GetProgramPipelineInfoLogEXT)},
+ {"glGetProgramPipelineiv", P(GL_GetProgramPipelineiv)},
+ {"glGetProgramPipelineivEXT", P(GL_GetProgramPipelineivEXT)},
+ {"glGetProgramResourceIndex", P(GL_GetProgramResourceIndex)},
+ {"glGetProgramResourceLocation", P(GL_GetProgramResourceLocation)},
+ DESKTOP_ONLY("glGetProgramResourceLocationIndex", GL_GetProgramResourceLocationIndex)
+ {"glGetProgramResourceLocationIndexEXT", P(GL_GetProgramResourceLocationIndexEXT)},
+ {"glGetProgramResourceName", P(GL_GetProgramResourceName)},
+ {"glGetProgramResourceiv", P(GL_GetProgramResourceiv)},
+ DESKTOP_ONLY("glGetProgramStageiv", GL_GetProgramStageiv)
+ {"glGetProgramiv", P(GL_GetProgramiv)},
+ {"glGetProgramivRobustANGLE", P(GL_GetProgramivRobustANGLE)},
+ DESKTOP_ONLY("glGetQueryBufferObjecti64v", GL_GetQueryBufferObjecti64v)
+ DESKTOP_ONLY("glGetQueryBufferObjectiv", GL_GetQueryBufferObjectiv)
+ DESKTOP_ONLY("glGetQueryBufferObjectui64v", GL_GetQueryBufferObjectui64v)
+ DESKTOP_ONLY("glGetQueryBufferObjectuiv", GL_GetQueryBufferObjectuiv)
+ DESKTOP_ONLY("glGetQueryIndexediv", GL_GetQueryIndexediv)
+ DESKTOP_ONLY("glGetQueryObjecti64v", GL_GetQueryObjecti64v)
+ {"glGetQueryObjecti64vEXT", P(GL_GetQueryObjecti64vEXT)},
+ {"glGetQueryObjecti64vRobustANGLE", P(GL_GetQueryObjecti64vRobustANGLE)},
+ DESKTOP_ONLY("glGetQueryObjectiv", GL_GetQueryObjectiv)
+ {"glGetQueryObjectivEXT", P(GL_GetQueryObjectivEXT)},
+ {"glGetQueryObjectivRobustANGLE", P(GL_GetQueryObjectivRobustANGLE)},
+ DESKTOP_ONLY("glGetQueryObjectui64v", GL_GetQueryObjectui64v)
+ {"glGetQueryObjectui64vEXT", P(GL_GetQueryObjectui64vEXT)},
+ {"glGetQueryObjectui64vRobustANGLE", P(GL_GetQueryObjectui64vRobustANGLE)},
+ {"glGetQueryObjectuiv", P(GL_GetQueryObjectuiv)},
+ {"glGetQueryObjectuivEXT", P(GL_GetQueryObjectuivEXT)},
+ {"glGetQueryObjectuivRobustANGLE", P(GL_GetQueryObjectuivRobustANGLE)},
+ {"glGetQueryiv", P(GL_GetQueryiv)},
+ {"glGetQueryivEXT", P(GL_GetQueryivEXT)},
+ {"glGetQueryivRobustANGLE", P(GL_GetQueryivRobustANGLE)},
+ {"glGetRenderbufferImageANGLE", P(GL_GetRenderbufferImageANGLE)},
+ {"glGetRenderbufferParameteriv", P(GL_GetRenderbufferParameteriv)},
+ {"glGetRenderbufferParameterivOES", P(GL_GetRenderbufferParameterivOES)},
+ {"glGetRenderbufferParameterivRobustANGLE", P(GL_GetRenderbufferParameterivRobustANGLE)},
+ {"glGetSamplerParameterIiv", P(GL_GetSamplerParameterIiv)},
+ {"glGetSamplerParameterIivEXT", P(GL_GetSamplerParameterIivEXT)},
+ {"glGetSamplerParameterIivOES", P(GL_GetSamplerParameterIivOES)},
+ {"glGetSamplerParameterIivRobustANGLE", P(GL_GetSamplerParameterIivRobustANGLE)},
+ {"glGetSamplerParameterIuiv", P(GL_GetSamplerParameterIuiv)},
+ {"glGetSamplerParameterIuivEXT", P(GL_GetSamplerParameterIuivEXT)},
+ {"glGetSamplerParameterIuivOES", P(GL_GetSamplerParameterIuivOES)},
+ {"glGetSamplerParameterIuivRobustANGLE", P(GL_GetSamplerParameterIuivRobustANGLE)},
+ {"glGetSamplerParameterfv", P(GL_GetSamplerParameterfv)},
+ {"glGetSamplerParameterfvRobustANGLE", P(GL_GetSamplerParameterfvRobustANGLE)},
+ {"glGetSamplerParameteriv", P(GL_GetSamplerParameteriv)},
+ {"glGetSamplerParameterivRobustANGLE", P(GL_GetSamplerParameterivRobustANGLE)},
+ {"glGetSemaphoreParameterui64vEXT", P(GL_GetSemaphoreParameterui64vEXT)},
+ {"glGetShaderInfoLog", P(GL_GetShaderInfoLog)},
+ {"glGetShaderPrecisionFormat", P(GL_GetShaderPrecisionFormat)},
+ {"glGetShaderSource", P(GL_GetShaderSource)},
+ {"glGetShaderiv", P(GL_GetShaderiv)},
+ {"glGetShaderivRobustANGLE", P(GL_GetShaderivRobustANGLE)},
+ {"glGetString", P(GL_GetString)},
+ {"glGetStringi", P(GL_GetStringi)},
+ DESKTOP_ONLY("glGetSubroutineIndex", GL_GetSubroutineIndex)
+ DESKTOP_ONLY("glGetSubroutineUniformLocation", GL_GetSubroutineUniformLocation)
+ {"glGetSynciv", P(GL_GetSynciv)},
+ {"glGetTexEnvfv", P(GL_GetTexEnvfv)},
+ {"glGetTexEnviv", P(GL_GetTexEnviv)},
+ {"glGetTexEnvxv", P(GL_GetTexEnvxv)},
+ DESKTOP_ONLY("glGetTexGendv", GL_GetTexGendv)
+ DESKTOP_ONLY("glGetTexGenfv", GL_GetTexGenfv)
+ {"glGetTexGenfvOES", P(GL_GetTexGenfvOES)},
+ DESKTOP_ONLY("glGetTexGeniv", GL_GetTexGeniv)
+ {"glGetTexGenivOES", P(GL_GetTexGenivOES)},
+ {"glGetTexGenxvOES", P(GL_GetTexGenxvOES)},
+ DESKTOP_ONLY("glGetTexImage", GL_GetTexImage)
+ {"glGetTexImageANGLE", P(GL_GetTexImageANGLE)},
+ {"glGetTexLevelParameterfv", P(GL_GetTexLevelParameterfv)},
+ {"glGetTexLevelParameterfvANGLE", P(GL_GetTexLevelParameterfvANGLE)},
+ {"glGetTexLevelParameterfvRobustANGLE", P(GL_GetTexLevelParameterfvRobustANGLE)},
+ {"glGetTexLevelParameteriv", P(GL_GetTexLevelParameteriv)},
+ {"glGetTexLevelParameterivANGLE", P(GL_GetTexLevelParameterivANGLE)},
+ {"glGetTexLevelParameterivRobustANGLE", P(GL_GetTexLevelParameterivRobustANGLE)},
+ {"glGetTexParameterIiv", P(GL_GetTexParameterIiv)},
+ {"glGetTexParameterIivEXT", P(GL_GetTexParameterIivEXT)},
+ {"glGetTexParameterIivOES", P(GL_GetTexParameterIivOES)},
+ {"glGetTexParameterIivRobustANGLE", P(GL_GetTexParameterIivRobustANGLE)},
+ {"glGetTexParameterIuiv", P(GL_GetTexParameterIuiv)},
+ {"glGetTexParameterIuivEXT", P(GL_GetTexParameterIuivEXT)},
+ {"glGetTexParameterIuivOES", P(GL_GetTexParameterIuivOES)},
+ {"glGetTexParameterIuivRobustANGLE", P(GL_GetTexParameterIuivRobustANGLE)},
+ {"glGetTexParameterfv", P(GL_GetTexParameterfv)},
+ {"glGetTexParameterfvRobustANGLE", P(GL_GetTexParameterfvRobustANGLE)},
+ {"glGetTexParameteriv", P(GL_GetTexParameteriv)},
+ {"glGetTexParameterivRobustANGLE", P(GL_GetTexParameterivRobustANGLE)},
+ {"glGetTexParameterxv", P(GL_GetTexParameterxv)},
+ DESKTOP_ONLY("glGetTextureImage", GL_GetTextureImage)
+ DESKTOP_ONLY("glGetTextureLevelParameterfv", GL_GetTextureLevelParameterfv)
+ DESKTOP_ONLY("glGetTextureLevelParameteriv", GL_GetTextureLevelParameteriv)
+ DESKTOP_ONLY("glGetTextureParameterIiv", GL_GetTextureParameterIiv)
+ DESKTOP_ONLY("glGetTextureParameterIuiv", GL_GetTextureParameterIuiv)
+ DESKTOP_ONLY("glGetTextureParameterfv", GL_GetTextureParameterfv)
+ DESKTOP_ONLY("glGetTextureParameteriv", GL_GetTextureParameteriv)
+ DESKTOP_ONLY("glGetTextureSubImage", GL_GetTextureSubImage)
+ {"glGetTransformFeedbackVarying", P(GL_GetTransformFeedbackVarying)},
+ DESKTOP_ONLY("glGetTransformFeedbacki64_v", GL_GetTransformFeedbacki64_v)
+ DESKTOP_ONLY("glGetTransformFeedbacki_v", GL_GetTransformFeedbacki_v)
+ DESKTOP_ONLY("glGetTransformFeedbackiv", GL_GetTransformFeedbackiv)
+ {"glGetTranslatedShaderSourceANGLE", P(GL_GetTranslatedShaderSourceANGLE)},
+ {"glGetUniformBlockIndex", P(GL_GetUniformBlockIndex)},
+ {"glGetUniformIndices", P(GL_GetUniformIndices)},
+ {"glGetUniformLocation", P(GL_GetUniformLocation)},
+ DESKTOP_ONLY("glGetUniformSubroutineuiv", GL_GetUniformSubroutineuiv)
+ DESKTOP_ONLY("glGetUniformdv", GL_GetUniformdv)
+ {"glGetUniformfv", P(GL_GetUniformfv)},
+ {"glGetUniformfvRobustANGLE", P(GL_GetUniformfvRobustANGLE)},
+ {"glGetUniformiv", P(GL_GetUniformiv)},
+ {"glGetUniformivRobustANGLE", P(GL_GetUniformivRobustANGLE)},
+ {"glGetUniformuiv", P(GL_GetUniformuiv)},
+ {"glGetUniformuivRobustANGLE", P(GL_GetUniformuivRobustANGLE)},
+ {"glGetUnsignedBytei_vEXT", P(GL_GetUnsignedBytei_vEXT)},
+ {"glGetUnsignedBytevEXT", P(GL_GetUnsignedBytevEXT)},
+ DESKTOP_ONLY("glGetVertexArrayIndexed64iv", GL_GetVertexArrayIndexed64iv)
+ DESKTOP_ONLY("glGetVertexArrayIndexediv", GL_GetVertexArrayIndexediv)
+ DESKTOP_ONLY("glGetVertexArrayiv", GL_GetVertexArrayiv)
+ {"glGetVertexAttribIiv", P(GL_GetVertexAttribIiv)},
+ {"glGetVertexAttribIivRobustANGLE", P(GL_GetVertexAttribIivRobustANGLE)},
+ {"glGetVertexAttribIuiv", P(GL_GetVertexAttribIuiv)},
+ {"glGetVertexAttribIuivRobustANGLE", P(GL_GetVertexAttribIuivRobustANGLE)},
+ DESKTOP_ONLY("glGetVertexAttribLdv", GL_GetVertexAttribLdv)
+ {"glGetVertexAttribPointerv", P(GL_GetVertexAttribPointerv)},
+ {"glGetVertexAttribPointervRobustANGLE", P(GL_GetVertexAttribPointervRobustANGLE)},
+ DESKTOP_ONLY("glGetVertexAttribdv", GL_GetVertexAttribdv)
+ {"glGetVertexAttribfv", P(GL_GetVertexAttribfv)},
+ {"glGetVertexAttribfvRobustANGLE", P(GL_GetVertexAttribfvRobustANGLE)},
+ {"glGetVertexAttribiv", P(GL_GetVertexAttribiv)},
+ {"glGetVertexAttribivRobustANGLE", P(GL_GetVertexAttribivRobustANGLE)},
+ DESKTOP_ONLY("glGetnColorTable", GL_GetnColorTable)
+ DESKTOP_ONLY("glGetnCompressedTexImage", GL_GetnCompressedTexImage)
+ DESKTOP_ONLY("glGetnConvolutionFilter", GL_GetnConvolutionFilter)
+ DESKTOP_ONLY("glGetnHistogram", GL_GetnHistogram)
+ DESKTOP_ONLY("glGetnMapdv", GL_GetnMapdv)
+ DESKTOP_ONLY("glGetnMapfv", GL_GetnMapfv)
+ DESKTOP_ONLY("glGetnMapiv", GL_GetnMapiv)
+ DESKTOP_ONLY("glGetnMinmax", GL_GetnMinmax)
+ DESKTOP_ONLY("glGetnPixelMapfv", GL_GetnPixelMapfv)
+ DESKTOP_ONLY("glGetnPixelMapuiv", GL_GetnPixelMapuiv)
+ DESKTOP_ONLY("glGetnPixelMapusv", GL_GetnPixelMapusv)
+ DESKTOP_ONLY("glGetnPolygonStipple", GL_GetnPolygonStipple)
+ DESKTOP_ONLY("glGetnSeparableFilter", GL_GetnSeparableFilter)
+ DESKTOP_ONLY("glGetnTexImage", GL_GetnTexImage)
+ DESKTOP_ONLY("glGetnUniformdv", GL_GetnUniformdv)
+ {"glGetnUniformfv", P(GL_GetnUniformfv)},
+ {"glGetnUniformfvEXT", P(GL_GetnUniformfvEXT)},
+ {"glGetnUniformfvRobustANGLE", P(GL_GetnUniformfvRobustANGLE)},
+ {"glGetnUniformiv", P(GL_GetnUniformiv)},
+ {"glGetnUniformivEXT", P(GL_GetnUniformivEXT)},
+ {"glGetnUniformivRobustANGLE", P(GL_GetnUniformivRobustANGLE)},
+ {"glGetnUniformuiv", P(GL_GetnUniformuiv)},
+ {"glGetnUniformuivRobustANGLE", P(GL_GetnUniformuivRobustANGLE)},
+ {"glHint", P(GL_Hint)},
+ {"glImportMemoryFdEXT", P(GL_ImportMemoryFdEXT)},
+ {"glImportMemoryZirconHandleANGLE", P(GL_ImportMemoryZirconHandleANGLE)},
+ {"glImportSemaphoreFdEXT", P(GL_ImportSemaphoreFdEXT)},
+ {"glImportSemaphoreZirconHandleANGLE", P(GL_ImportSemaphoreZirconHandleANGLE)},
+ DESKTOP_ONLY("glIndexMask", GL_IndexMask)
+ DESKTOP_ONLY("glIndexPointer", GL_IndexPointer)
+ DESKTOP_ONLY("glIndexd", GL_Indexd)
+ DESKTOP_ONLY("glIndexdv", GL_Indexdv)
+ DESKTOP_ONLY("glIndexf", GL_Indexf)
+ DESKTOP_ONLY("glIndexfv", GL_Indexfv)
+ DESKTOP_ONLY("glIndexi", GL_Indexi)
+ DESKTOP_ONLY("glIndexiv", GL_Indexiv)
+ DESKTOP_ONLY("glIndexs", GL_Indexs)
+ DESKTOP_ONLY("glIndexsv", GL_Indexsv)
+ DESKTOP_ONLY("glIndexub", GL_Indexub)
+ DESKTOP_ONLY("glIndexubv", GL_Indexubv)
+ DESKTOP_ONLY("glInitNames", GL_InitNames)
+ {"glInsertEventMarkerEXT", P(GL_InsertEventMarkerEXT)},
+ DESKTOP_ONLY("glInterleavedArrays", GL_InterleavedArrays)
+ DESKTOP_ONLY("glInvalidateBufferData", GL_InvalidateBufferData)
+ DESKTOP_ONLY("glInvalidateBufferSubData", GL_InvalidateBufferSubData)
+ {"glInvalidateFramebuffer", P(GL_InvalidateFramebuffer)},
+ DESKTOP_ONLY("glInvalidateNamedFramebufferData", GL_InvalidateNamedFramebufferData)
+ DESKTOP_ONLY("glInvalidateNamedFramebufferSubData", GL_InvalidateNamedFramebufferSubData)
+ {"glInvalidateSubFramebuffer", P(GL_InvalidateSubFramebuffer)},
+ DESKTOP_ONLY("glInvalidateTexImage", GL_InvalidateTexImage)
+ DESKTOP_ONLY("glInvalidateTexSubImage", GL_InvalidateTexSubImage)
+ {"glInvalidateTextureANGLE", P(GL_InvalidateTextureANGLE)},
+ {"glIsBuffer", P(GL_IsBuffer)},
+ {"glIsEnabled", P(GL_IsEnabled)},
+ {"glIsEnabledi", P(GL_IsEnabledi)},
+ {"glIsEnablediEXT", P(GL_IsEnablediEXT)},
+ {"glIsEnablediOES", P(GL_IsEnablediOES)},
+ {"glIsFenceNV", P(GL_IsFenceNV)},
+ {"glIsFramebuffer", P(GL_IsFramebuffer)},
+ {"glIsFramebufferOES", P(GL_IsFramebufferOES)},
+ DESKTOP_ONLY("glIsList", GL_IsList)
+ {"glIsMemoryObjectEXT", P(GL_IsMemoryObjectEXT)},
+ {"glIsProgram", P(GL_IsProgram)},
+ {"glIsProgramPipeline", P(GL_IsProgramPipeline)},
+ {"glIsProgramPipelineEXT", P(GL_IsProgramPipelineEXT)},
+ {"glIsQuery", P(GL_IsQuery)},
+ {"glIsQueryEXT", P(GL_IsQueryEXT)},
+ {"glIsRenderbuffer", P(GL_IsRenderbuffer)},
+ {"glIsRenderbufferOES", P(GL_IsRenderbufferOES)},
+ {"glIsSampler", P(GL_IsSampler)},
+ {"glIsSemaphoreEXT", P(GL_IsSemaphoreEXT)},
+ {"glIsShader", P(GL_IsShader)},
+ {"glIsSync", P(GL_IsSync)},
+ {"glIsTexture", P(GL_IsTexture)},
+ {"glIsTransformFeedback", P(GL_IsTransformFeedback)},
+ {"glIsVertexArray", P(GL_IsVertexArray)},
+ {"glIsVertexArrayOES", P(GL_IsVertexArrayOES)},
+ {"glLabelObjectEXT", P(GL_LabelObjectEXT)},
+ {"glLightModelf", P(GL_LightModelf)},
+ {"glLightModelfv", P(GL_LightModelfv)},
+ DESKTOP_ONLY("glLightModeli", GL_LightModeli)
+ DESKTOP_ONLY("glLightModeliv", GL_LightModeliv)
+ {"glLightModelx", P(GL_LightModelx)},
+ {"glLightModelxv", P(GL_LightModelxv)},
+ {"glLightf", P(GL_Lightf)},
+ {"glLightfv", P(GL_Lightfv)},
+ DESKTOP_ONLY("glLighti", GL_Lighti)
+ DESKTOP_ONLY("glLightiv", GL_Lightiv)
+ {"glLightx", P(GL_Lightx)},
+ {"glLightxv", P(GL_Lightxv)},
+ DESKTOP_ONLY("glLineStipple", GL_LineStipple)
+ {"glLineWidth", P(GL_LineWidth)},
+ {"glLineWidthx", P(GL_LineWidthx)},
+ {"glLinkProgram", P(GL_LinkProgram)},
+ DESKTOP_ONLY("glListBase", GL_ListBase)
+ {"glLoadIdentity", P(GL_LoadIdentity)},
+ DESKTOP_ONLY("glLoadMatrixd", GL_LoadMatrixd)
+ {"glLoadMatrixf", P(GL_LoadMatrixf)},
+ {"glLoadMatrixx", P(GL_LoadMatrixx)},
+ DESKTOP_ONLY("glLoadName", GL_LoadName)
+ {"glLoadPaletteFromModelViewMatrixOES", P(GL_LoadPaletteFromModelViewMatrixOES)},
+ DESKTOP_ONLY("glLoadTransposeMatrixd", GL_LoadTransposeMatrixd)
+ DESKTOP_ONLY("glLoadTransposeMatrixf", GL_LoadTransposeMatrixf)
+ {"glLogicOp", P(GL_LogicOp)},
+ {"glLogicOpANGLE", P(GL_LogicOpANGLE)},
+ {"glLoseContextCHROMIUM", P(GL_LoseContextCHROMIUM)},
+ DESKTOP_ONLY("glMap1d", GL_Map1d)
+ DESKTOP_ONLY("glMap1f", GL_Map1f)
+ DESKTOP_ONLY("glMap2d", GL_Map2d)
+ DESKTOP_ONLY("glMap2f", GL_Map2f)
+ DESKTOP_ONLY("glMapBuffer", GL_MapBuffer)
+ {"glMapBufferOES", P(GL_MapBufferOES)},
+ {"glMapBufferRange", P(GL_MapBufferRange)},
+ {"glMapBufferRangeEXT", P(GL_MapBufferRangeEXT)},
+ DESKTOP_ONLY("glMapGrid1d", GL_MapGrid1d)
+ DESKTOP_ONLY("glMapGrid1f", GL_MapGrid1f)
+ DESKTOP_ONLY("glMapGrid2d", GL_MapGrid2d)
+ DESKTOP_ONLY("glMapGrid2f", GL_MapGrid2f)
+ DESKTOP_ONLY("glMapNamedBuffer", GL_MapNamedBuffer)
+ DESKTOP_ONLY("glMapNamedBufferRange", GL_MapNamedBufferRange)
+ {"glMaterialf", P(GL_Materialf)},
+ {"glMaterialfv", P(GL_Materialfv)},
+ DESKTOP_ONLY("glMateriali", GL_Materiali)
+ DESKTOP_ONLY("glMaterialiv", GL_Materialiv)
+ {"glMaterialx", P(GL_Materialx)},
+ {"glMaterialxv", P(GL_Materialxv)},
+ {"glMatrixIndexPointerOES", P(GL_MatrixIndexPointerOES)},
+ {"glMatrixMode", P(GL_MatrixMode)},
+ {"glMaxShaderCompilerThreadsKHR", P(GL_MaxShaderCompilerThreadsKHR)},
+ {"glMemoryBarrier", P(GL_MemoryBarrier)},
+ {"glMemoryBarrierByRegion", P(GL_MemoryBarrierByRegion)},
+ {"glMemoryObjectParameterivEXT", P(GL_MemoryObjectParameterivEXT)},
+ {"glMinSampleShading", P(GL_MinSampleShading)},
+ {"glMinSampleShadingOES", P(GL_MinSampleShadingOES)},
+ DESKTOP_ONLY("glMultMatrixd", GL_MultMatrixd)
+ {"glMultMatrixf", P(GL_MultMatrixf)},
+ {"glMultMatrixx", P(GL_MultMatrixx)},
+ DESKTOP_ONLY("glMultTransposeMatrixd", GL_MultTransposeMatrixd)
+ DESKTOP_ONLY("glMultTransposeMatrixf", GL_MultTransposeMatrixf)
+ DESKTOP_ONLY("glMultiDrawArrays", GL_MultiDrawArrays)
+ {"glMultiDrawArraysANGLE", P(GL_MultiDrawArraysANGLE)},
+ DESKTOP_ONLY("glMultiDrawArraysIndirect", GL_MultiDrawArraysIndirect)
+ DESKTOP_ONLY("glMultiDrawArraysIndirectCount", GL_MultiDrawArraysIndirectCount)
+ {"glMultiDrawArraysIndirectEXT", P(GL_MultiDrawArraysIndirectEXT)},
+ {"glMultiDrawArraysInstancedANGLE", P(GL_MultiDrawArraysInstancedANGLE)},
+ {"glMultiDrawArraysInstancedBaseInstanceANGLE", P(GL_MultiDrawArraysInstancedBaseInstanceANGLE)},
+ DESKTOP_ONLY("glMultiDrawElements", GL_MultiDrawElements)
+ {"glMultiDrawElementsANGLE", P(GL_MultiDrawElementsANGLE)},
+ DESKTOP_ONLY("glMultiDrawElementsBaseVertex", GL_MultiDrawElementsBaseVertex)
+ {"glMultiDrawElementsBaseVertexEXT", P(GL_MultiDrawElementsBaseVertexEXT)},
+ DESKTOP_ONLY("glMultiDrawElementsIndirect", GL_MultiDrawElementsIndirect)
+ DESKTOP_ONLY("glMultiDrawElementsIndirectCount", GL_MultiDrawElementsIndirectCount)
+ {"glMultiDrawElementsIndirectEXT", P(GL_MultiDrawElementsIndirectEXT)},
+ {"glMultiDrawElementsInstancedANGLE", P(GL_MultiDrawElementsInstancedANGLE)},
+ {"glMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE", P(GL_MultiDrawElementsInstancedBaseVertexBaseInstanceANGLE)},
+ DESKTOP_ONLY("glMultiTexCoord1d", GL_MultiTexCoord1d)
+ DESKTOP_ONLY("glMultiTexCoord1dv", GL_MultiTexCoord1dv)
+ DESKTOP_ONLY("glMultiTexCoord1f", GL_MultiTexCoord1f)
+ DESKTOP_ONLY("glMultiTexCoord1fv", GL_MultiTexCoord1fv)
+ DESKTOP_ONLY("glMultiTexCoord1i", GL_MultiTexCoord1i)
+ DESKTOP_ONLY("glMultiTexCoord1iv", GL_MultiTexCoord1iv)
+ DESKTOP_ONLY("glMultiTexCoord1s", GL_MultiTexCoord1s)
+ DESKTOP_ONLY("glMultiTexCoord1sv", GL_MultiTexCoord1sv)
+ DESKTOP_ONLY("glMultiTexCoord2d", GL_MultiTexCoord2d)
+ DESKTOP_ONLY("glMultiTexCoord2dv", GL_MultiTexCoord2dv)
+ DESKTOP_ONLY("glMultiTexCoord2f", GL_MultiTexCoord2f)
+ DESKTOP_ONLY("glMultiTexCoord2fv", GL_MultiTexCoord2fv)
+ DESKTOP_ONLY("glMultiTexCoord2i", GL_MultiTexCoord2i)
+ DESKTOP_ONLY("glMultiTexCoord2iv", GL_MultiTexCoord2iv)
+ DESKTOP_ONLY("glMultiTexCoord2s", GL_MultiTexCoord2s)
+ DESKTOP_ONLY("glMultiTexCoord2sv", GL_MultiTexCoord2sv)
+ DESKTOP_ONLY("glMultiTexCoord3d", GL_MultiTexCoord3d)
+ DESKTOP_ONLY("glMultiTexCoord3dv", GL_MultiTexCoord3dv)
+ DESKTOP_ONLY("glMultiTexCoord3f", GL_MultiTexCoord3f)
+ DESKTOP_ONLY("glMultiTexCoord3fv", GL_MultiTexCoord3fv)
+ DESKTOP_ONLY("glMultiTexCoord3i", GL_MultiTexCoord3i)
+ DESKTOP_ONLY("glMultiTexCoord3iv", GL_MultiTexCoord3iv)
+ DESKTOP_ONLY("glMultiTexCoord3s", GL_MultiTexCoord3s)
+ DESKTOP_ONLY("glMultiTexCoord3sv", GL_MultiTexCoord3sv)
+ DESKTOP_ONLY("glMultiTexCoord4d", GL_MultiTexCoord4d)
+ DESKTOP_ONLY("glMultiTexCoord4dv", GL_MultiTexCoord4dv)
+ {"glMultiTexCoord4f", P(GL_MultiTexCoord4f)},
+ DESKTOP_ONLY("glMultiTexCoord4fv", GL_MultiTexCoord4fv)
+ DESKTOP_ONLY("glMultiTexCoord4i", GL_MultiTexCoord4i)
+ DESKTOP_ONLY("glMultiTexCoord4iv", GL_MultiTexCoord4iv)
+ DESKTOP_ONLY("glMultiTexCoord4s", GL_MultiTexCoord4s)
+ DESKTOP_ONLY("glMultiTexCoord4sv", GL_MultiTexCoord4sv)
+ {"glMultiTexCoord4x", P(GL_MultiTexCoord4x)},
+ DESKTOP_ONLY("glMultiTexCoordP1ui", GL_MultiTexCoordP1ui)
+ DESKTOP_ONLY("glMultiTexCoordP1uiv", GL_MultiTexCoordP1uiv)
+ DESKTOP_ONLY("glMultiTexCoordP2ui", GL_MultiTexCoordP2ui)
+ DESKTOP_ONLY("glMultiTexCoordP2uiv", GL_MultiTexCoordP2uiv)
+ DESKTOP_ONLY("glMultiTexCoordP3ui", GL_MultiTexCoordP3ui)
+ DESKTOP_ONLY("glMultiTexCoordP3uiv", GL_MultiTexCoordP3uiv)
+ DESKTOP_ONLY("glMultiTexCoordP4ui", GL_MultiTexCoordP4ui)
+ DESKTOP_ONLY("glMultiTexCoordP4uiv", GL_MultiTexCoordP4uiv)
+ DESKTOP_ONLY("glNamedBufferData", GL_NamedBufferData)
+ DESKTOP_ONLY("glNamedBufferStorage", GL_NamedBufferStorage)
+ {"glNamedBufferStorageExternalEXT", P(GL_NamedBufferStorageExternalEXT)},
+ DESKTOP_ONLY("glNamedBufferSubData", GL_NamedBufferSubData)
+ DESKTOP_ONLY("glNamedFramebufferDrawBuffer", GL_NamedFramebufferDrawBuffer)
+ DESKTOP_ONLY("glNamedFramebufferDrawBuffers", GL_NamedFramebufferDrawBuffers)
+ DESKTOP_ONLY("glNamedFramebufferParameteri", GL_NamedFramebufferParameteri)
+ DESKTOP_ONLY("glNamedFramebufferReadBuffer", GL_NamedFramebufferReadBuffer)
+ DESKTOP_ONLY("glNamedFramebufferRenderbuffer", GL_NamedFramebufferRenderbuffer)
+ DESKTOP_ONLY("glNamedFramebufferTexture", GL_NamedFramebufferTexture)
+ DESKTOP_ONLY("glNamedFramebufferTextureLayer", GL_NamedFramebufferTextureLayer)
+ DESKTOP_ONLY("glNamedRenderbufferStorage", GL_NamedRenderbufferStorage)
+ DESKTOP_ONLY("glNamedRenderbufferStorageMultisample", GL_NamedRenderbufferStorageMultisample)
+ DESKTOP_ONLY("glNewList", GL_NewList)
+ DESKTOP_ONLY("glNormal3b", GL_Normal3b)
+ DESKTOP_ONLY("glNormal3bv", GL_Normal3bv)
+ DESKTOP_ONLY("glNormal3d", GL_Normal3d)
+ DESKTOP_ONLY("glNormal3dv", GL_Normal3dv)
+ {"glNormal3f", P(GL_Normal3f)},
+ DESKTOP_ONLY("glNormal3fv", GL_Normal3fv)
+ DESKTOP_ONLY("glNormal3i", GL_Normal3i)
+ DESKTOP_ONLY("glNormal3iv", GL_Normal3iv)
+ DESKTOP_ONLY("glNormal3s", GL_Normal3s)
+ DESKTOP_ONLY("glNormal3sv", GL_Normal3sv)
+ {"glNormal3x", P(GL_Normal3x)},
+ DESKTOP_ONLY("glNormalP3ui", GL_NormalP3ui)
+ DESKTOP_ONLY("glNormalP3uiv", GL_NormalP3uiv)
+ {"glNormalPointer", P(GL_NormalPointer)},
+ {"glObjectLabel", P(GL_ObjectLabel)},
+ {"glObjectLabelKHR", P(GL_ObjectLabelKHR)},
+ {"glObjectPtrLabel", P(GL_ObjectPtrLabel)},
+ {"glObjectPtrLabelKHR", P(GL_ObjectPtrLabelKHR)},
+ DESKTOP_ONLY("glOrtho", GL_Ortho)
+ {"glOrthof", P(GL_Orthof)},
+ {"glOrthox", P(GL_Orthox)},
+ DESKTOP_ONLY("glPassThrough", GL_PassThrough)
+ DESKTOP_ONLY("glPatchParameterfv", GL_PatchParameterfv)
+ {"glPatchParameteri", P(GL_PatchParameteri)},
+ {"glPatchParameteriEXT", P(GL_PatchParameteriEXT)},
+ {"glPauseTransformFeedback", P(GL_PauseTransformFeedback)},
+ {"glPixelLocalStorageBarrierANGLE", P(GL_PixelLocalStorageBarrierANGLE)},
+ DESKTOP_ONLY("glPixelMapfv", GL_PixelMapfv)
+ DESKTOP_ONLY("glPixelMapuiv", GL_PixelMapuiv)
+ DESKTOP_ONLY("glPixelMapusv", GL_PixelMapusv)
+ DESKTOP_ONLY("glPixelStoref", GL_PixelStoref)
+ {"glPixelStorei", P(GL_PixelStorei)},
+ DESKTOP_ONLY("glPixelTransferf", GL_PixelTransferf)
+ DESKTOP_ONLY("glPixelTransferi", GL_PixelTransferi)
+ DESKTOP_ONLY("glPixelZoom", GL_PixelZoom)
+ {"glPointParameterf", P(GL_PointParameterf)},
+ {"glPointParameterfv", P(GL_PointParameterfv)},
+ DESKTOP_ONLY("glPointParameteri", GL_PointParameteri)
+ DESKTOP_ONLY("glPointParameteriv", GL_PointParameteriv)
+ {"glPointParameterx", P(GL_PointParameterx)},
+ {"glPointParameterxv", P(GL_PointParameterxv)},
+ {"glPointSize", P(GL_PointSize)},
+ {"glPointSizePointerOES", P(GL_PointSizePointerOES)},
+ {"glPointSizex", P(GL_PointSizex)},
+ DESKTOP_ONLY("glPolygonMode", GL_PolygonMode)
+ {"glPolygonOffset", P(GL_PolygonOffset)},
+ DESKTOP_ONLY("glPolygonOffsetClamp", GL_PolygonOffsetClamp)
+ {"glPolygonOffsetx", P(GL_PolygonOffsetx)},
+ DESKTOP_ONLY("glPolygonStipple", GL_PolygonStipple)
+ DESKTOP_ONLY("glPopAttrib", GL_PopAttrib)
+ DESKTOP_ONLY("glPopClientAttrib", GL_PopClientAttrib)
+ {"glPopDebugGroup", P(GL_PopDebugGroup)},
+ {"glPopDebugGroupKHR", P(GL_PopDebugGroupKHR)},
+ {"glPopGroupMarkerEXT", P(GL_PopGroupMarkerEXT)},
+ {"glPopMatrix", P(GL_PopMatrix)},
+ DESKTOP_ONLY("glPopName", GL_PopName)
+ {"glPrimitiveBoundingBox", P(GL_PrimitiveBoundingBox)},
+ {"glPrimitiveBoundingBoxEXT", P(GL_PrimitiveBoundingBoxEXT)},
+ {"glPrimitiveBoundingBoxOES", P(GL_PrimitiveBoundingBoxOES)},
+ DESKTOP_ONLY("glPrimitiveRestartIndex", GL_PrimitiveRestartIndex)
+ DESKTOP_ONLY("glPrioritizeTextures", GL_PrioritizeTextures)
+ {"glProgramBinary", P(GL_ProgramBinary)},
+ {"glProgramBinaryOES", P(GL_ProgramBinaryOES)},
+ {"glProgramParameteri", P(GL_ProgramParameteri)},
+ {"glProgramParameteriEXT", P(GL_ProgramParameteriEXT)},
+ DESKTOP_ONLY("glProgramUniform1d", GL_ProgramUniform1d)
+ DESKTOP_ONLY("glProgramUniform1dv", GL_ProgramUniform1dv)
+ {"glProgramUniform1f", P(GL_ProgramUniform1f)},
+ {"glProgramUniform1fEXT", P(GL_ProgramUniform1fEXT)},
+ {"glProgramUniform1fv", P(GL_ProgramUniform1fv)},
+ {"glProgramUniform1fvEXT", P(GL_ProgramUniform1fvEXT)},
+ {"glProgramUniform1i", P(GL_ProgramUniform1i)},
+ {"glProgramUniform1iEXT", P(GL_ProgramUniform1iEXT)},
+ {"glProgramUniform1iv", P(GL_ProgramUniform1iv)},
+ {"glProgramUniform1ivEXT", P(GL_ProgramUniform1ivEXT)},
+ {"glProgramUniform1ui", P(GL_ProgramUniform1ui)},
+ {"glProgramUniform1uiEXT", P(GL_ProgramUniform1uiEXT)},
+ {"glProgramUniform1uiv", P(GL_ProgramUniform1uiv)},
+ {"glProgramUniform1uivEXT", P(GL_ProgramUniform1uivEXT)},
+ DESKTOP_ONLY("glProgramUniform2d", GL_ProgramUniform2d)
+ DESKTOP_ONLY("glProgramUniform2dv", GL_ProgramUniform2dv)
+ {"glProgramUniform2f", P(GL_ProgramUniform2f)},
+ {"glProgramUniform2fEXT", P(GL_ProgramUniform2fEXT)},
+ {"glProgramUniform2fv", P(GL_ProgramUniform2fv)},
+ {"glProgramUniform2fvEXT", P(GL_ProgramUniform2fvEXT)},
+ {"glProgramUniform2i", P(GL_ProgramUniform2i)},
+ {"glProgramUniform2iEXT", P(GL_ProgramUniform2iEXT)},
+ {"glProgramUniform2iv", P(GL_ProgramUniform2iv)},
+ {"glProgramUniform2ivEXT", P(GL_ProgramUniform2ivEXT)},
+ {"glProgramUniform2ui", P(GL_ProgramUniform2ui)},
+ {"glProgramUniform2uiEXT", P(GL_ProgramUniform2uiEXT)},
+ {"glProgramUniform2uiv", P(GL_ProgramUniform2uiv)},
+ {"glProgramUniform2uivEXT", P(GL_ProgramUniform2uivEXT)},
+ DESKTOP_ONLY("glProgramUniform3d", GL_ProgramUniform3d)
+ DESKTOP_ONLY("glProgramUniform3dv", GL_ProgramUniform3dv)
+ {"glProgramUniform3f", P(GL_ProgramUniform3f)},
+ {"glProgramUniform3fEXT", P(GL_ProgramUniform3fEXT)},
+ {"glProgramUniform3fv", P(GL_ProgramUniform3fv)},
+ {"glProgramUniform3fvEXT", P(GL_ProgramUniform3fvEXT)},
+ {"glProgramUniform3i", P(GL_ProgramUniform3i)},
+ {"glProgramUniform3iEXT", P(GL_ProgramUniform3iEXT)},
+ {"glProgramUniform3iv", P(GL_ProgramUniform3iv)},
+ {"glProgramUniform3ivEXT", P(GL_ProgramUniform3ivEXT)},
+ {"glProgramUniform3ui", P(GL_ProgramUniform3ui)},
+ {"glProgramUniform3uiEXT", P(GL_ProgramUniform3uiEXT)},
+ {"glProgramUniform3uiv", P(GL_ProgramUniform3uiv)},
+ {"glProgramUniform3uivEXT", P(GL_ProgramUniform3uivEXT)},
+ DESKTOP_ONLY("glProgramUniform4d", GL_ProgramUniform4d)
+ DESKTOP_ONLY("glProgramUniform4dv", GL_ProgramUniform4dv)
+ {"glProgramUniform4f", P(GL_ProgramUniform4f)},
+ {"glProgramUniform4fEXT", P(GL_ProgramUniform4fEXT)},
+ {"glProgramUniform4fv", P(GL_ProgramUniform4fv)},
+ {"glProgramUniform4fvEXT", P(GL_ProgramUniform4fvEXT)},
+ {"glProgramUniform4i", P(GL_ProgramUniform4i)},
+ {"glProgramUniform4iEXT", P(GL_ProgramUniform4iEXT)},
+ {"glProgramUniform4iv", P(GL_ProgramUniform4iv)},
+ {"glProgramUniform4ivEXT", P(GL_ProgramUniform4ivEXT)},
+ {"glProgramUniform4ui", P(GL_ProgramUniform4ui)},
+ {"glProgramUniform4uiEXT", P(GL_ProgramUniform4uiEXT)},
+ {"glProgramUniform4uiv", P(GL_ProgramUniform4uiv)},
+ {"glProgramUniform4uivEXT", P(GL_ProgramUniform4uivEXT)},
+ DESKTOP_ONLY("glProgramUniformMatrix2dv", GL_ProgramUniformMatrix2dv)
+ {"glProgramUniformMatrix2fv", P(GL_ProgramUniformMatrix2fv)},
+ {"glProgramUniformMatrix2fvEXT", P(GL_ProgramUniformMatrix2fvEXT)},
+ DESKTOP_ONLY("glProgramUniformMatrix2x3dv", GL_ProgramUniformMatrix2x3dv)
+ {"glProgramUniformMatrix2x3fv", P(GL_ProgramUniformMatrix2x3fv)},
+ {"glProgramUniformMatrix2x3fvEXT", P(GL_ProgramUniformMatrix2x3fvEXT)},
+ DESKTOP_ONLY("glProgramUniformMatrix2x4dv", GL_ProgramUniformMatrix2x4dv)
+ {"glProgramUniformMatrix2x4fv", P(GL_ProgramUniformMatrix2x4fv)},
+ {"glProgramUniformMatrix2x4fvEXT", P(GL_ProgramUniformMatrix2x4fvEXT)},
+ DESKTOP_ONLY("glProgramUniformMatrix3dv", GL_ProgramUniformMatrix3dv)
+ {"glProgramUniformMatrix3fv", P(GL_ProgramUniformMatrix3fv)},
+ {"glProgramUniformMatrix3fvEXT", P(GL_ProgramUniformMatrix3fvEXT)},
+ DESKTOP_ONLY("glProgramUniformMatrix3x2dv", GL_ProgramUniformMatrix3x2dv)
+ {"glProgramUniformMatrix3x2fv", P(GL_ProgramUniformMatrix3x2fv)},
+ {"glProgramUniformMatrix3x2fvEXT", P(GL_ProgramUniformMatrix3x2fvEXT)},
+ DESKTOP_ONLY("glProgramUniformMatrix3x4dv", GL_ProgramUniformMatrix3x4dv)
+ {"glProgramUniformMatrix3x4fv", P(GL_ProgramUniformMatrix3x4fv)},
+ {"glProgramUniformMatrix3x4fvEXT", P(GL_ProgramUniformMatrix3x4fvEXT)},
+ DESKTOP_ONLY("glProgramUniformMatrix4dv", GL_ProgramUniformMatrix4dv)
+ {"glProgramUniformMatrix4fv", P(GL_ProgramUniformMatrix4fv)},
+ {"glProgramUniformMatrix4fvEXT", P(GL_ProgramUniformMatrix4fvEXT)},
+ DESKTOP_ONLY("glProgramUniformMatrix4x2dv", GL_ProgramUniformMatrix4x2dv)
+ {"glProgramUniformMatrix4x2fv", P(GL_ProgramUniformMatrix4x2fv)},
+ {"glProgramUniformMatrix4x2fvEXT", P(GL_ProgramUniformMatrix4x2fvEXT)},
+ DESKTOP_ONLY("glProgramUniformMatrix4x3dv", GL_ProgramUniformMatrix4x3dv)
+ {"glProgramUniformMatrix4x3fv", P(GL_ProgramUniformMatrix4x3fv)},
+ {"glProgramUniformMatrix4x3fvEXT", P(GL_ProgramUniformMatrix4x3fvEXT)},
+ DESKTOP_ONLY("glProvokingVertex", GL_ProvokingVertex)
+ {"glProvokingVertexANGLE", P(GL_ProvokingVertexANGLE)},
+ DESKTOP_ONLY("glPushAttrib", GL_PushAttrib)
+ DESKTOP_ONLY("glPushClientAttrib", GL_PushClientAttrib)
+ {"glPushDebugGroup", P(GL_PushDebugGroup)},
+ {"glPushDebugGroupKHR", P(GL_PushDebugGroupKHR)},
+ {"glPushGroupMarkerEXT", P(GL_PushGroupMarkerEXT)},
+ {"glPushMatrix", P(GL_PushMatrix)},
+ DESKTOP_ONLY("glPushName", GL_PushName)
+ DESKTOP_ONLY("glQueryCounter", GL_QueryCounter)
+ {"glQueryCounterEXT", P(GL_QueryCounterEXT)},
+ {"glQueryMatrixxOES", P(GL_QueryMatrixxOES)},
+ DESKTOP_ONLY("glRasterPos2d", GL_RasterPos2d)
+ DESKTOP_ONLY("glRasterPos2dv", GL_RasterPos2dv)
+ DESKTOP_ONLY("glRasterPos2f", GL_RasterPos2f)
+ DESKTOP_ONLY("glRasterPos2fv", GL_RasterPos2fv)
+ DESKTOP_ONLY("glRasterPos2i", GL_RasterPos2i)
+ DESKTOP_ONLY("glRasterPos2iv", GL_RasterPos2iv)
+ DESKTOP_ONLY("glRasterPos2s", GL_RasterPos2s)
+ DESKTOP_ONLY("glRasterPos2sv", GL_RasterPos2sv)
+ DESKTOP_ONLY("glRasterPos3d", GL_RasterPos3d)
+ DESKTOP_ONLY("glRasterPos3dv", GL_RasterPos3dv)
+ DESKTOP_ONLY("glRasterPos3f", GL_RasterPos3f)
+ DESKTOP_ONLY("glRasterPos3fv", GL_RasterPos3fv)
+ DESKTOP_ONLY("glRasterPos3i", GL_RasterPos3i)
+ DESKTOP_ONLY("glRasterPos3iv", GL_RasterPos3iv)
+ DESKTOP_ONLY("glRasterPos3s", GL_RasterPos3s)
+ DESKTOP_ONLY("glRasterPos3sv", GL_RasterPos3sv)
+ DESKTOP_ONLY("glRasterPos4d", GL_RasterPos4d)
+ DESKTOP_ONLY("glRasterPos4dv", GL_RasterPos4dv)
+ DESKTOP_ONLY("glRasterPos4f", GL_RasterPos4f)
+ DESKTOP_ONLY("glRasterPos4fv", GL_RasterPos4fv)
+ DESKTOP_ONLY("glRasterPos4i", GL_RasterPos4i)
+ DESKTOP_ONLY("glRasterPos4iv", GL_RasterPos4iv)
+ DESKTOP_ONLY("glRasterPos4s", GL_RasterPos4s)
+ DESKTOP_ONLY("glRasterPos4sv", GL_RasterPos4sv)
+ {"glReadBuffer", P(GL_ReadBuffer)},
+ {"glReadPixels", P(GL_ReadPixels)},
+ {"glReadPixelsRobustANGLE", P(GL_ReadPixelsRobustANGLE)},
+ {"glReadnPixels", P(GL_ReadnPixels)},
+ {"glReadnPixelsEXT", P(GL_ReadnPixelsEXT)},
+ {"glReadnPixelsRobustANGLE", P(GL_ReadnPixelsRobustANGLE)},
+ DESKTOP_ONLY("glRectd", GL_Rectd)
+ DESKTOP_ONLY("glRectdv", GL_Rectdv)
+ DESKTOP_ONLY("glRectf", GL_Rectf)
+ DESKTOP_ONLY("glRectfv", GL_Rectfv)
+ DESKTOP_ONLY("glRecti", GL_Recti)
+ DESKTOP_ONLY("glRectiv", GL_Rectiv)
+ DESKTOP_ONLY("glRects", GL_Rects)
+ DESKTOP_ONLY("glRectsv", GL_Rectsv)
+ {"glReleaseShaderCompiler", P(GL_ReleaseShaderCompiler)},
+ {"glReleaseTexturesANGLE", P(GL_ReleaseTexturesANGLE)},
+ DESKTOP_ONLY("glRenderMode", GL_RenderMode)
+ {"glRenderbufferStorage", P(GL_RenderbufferStorage)},
+ {"glRenderbufferStorageMultisample", P(GL_RenderbufferStorageMultisample)},
+ {"glRenderbufferStorageMultisampleANGLE", P(GL_RenderbufferStorageMultisampleANGLE)},
+ {"glRenderbufferStorageMultisampleEXT", P(GL_RenderbufferStorageMultisampleEXT)},
+ {"glRenderbufferStorageOES", P(GL_RenderbufferStorageOES)},
+ {"glRequestExtensionANGLE", P(GL_RequestExtensionANGLE)},
+ {"glResumeTransformFeedback", P(GL_ResumeTransformFeedback)},
+ DESKTOP_ONLY("glRotated", GL_Rotated)
+ {"glRotatef", P(GL_Rotatef)},
+ {"glRotatex", P(GL_Rotatex)},
+ {"glSampleCoverage", P(GL_SampleCoverage)},
+ {"glSampleCoveragex", P(GL_SampleCoveragex)},
+ {"glSampleMaski", P(GL_SampleMaski)},
+ {"glSampleMaskiANGLE", P(GL_SampleMaskiANGLE)},
+ {"glSamplerParameterIiv", P(GL_SamplerParameterIiv)},
+ {"glSamplerParameterIivEXT", P(GL_SamplerParameterIivEXT)},
+ {"glSamplerParameterIivOES", P(GL_SamplerParameterIivOES)},
+ {"glSamplerParameterIivRobustANGLE", P(GL_SamplerParameterIivRobustANGLE)},
+ {"glSamplerParameterIuiv", P(GL_SamplerParameterIuiv)},
+ {"glSamplerParameterIuivEXT", P(GL_SamplerParameterIuivEXT)},
+ {"glSamplerParameterIuivOES", P(GL_SamplerParameterIuivOES)},
+ {"glSamplerParameterIuivRobustANGLE", P(GL_SamplerParameterIuivRobustANGLE)},
+ {"glSamplerParameterf", P(GL_SamplerParameterf)},
+ {"glSamplerParameterfv", P(GL_SamplerParameterfv)},
+ {"glSamplerParameterfvRobustANGLE", P(GL_SamplerParameterfvRobustANGLE)},
+ {"glSamplerParameteri", P(GL_SamplerParameteri)},
+ {"glSamplerParameteriv", P(GL_SamplerParameteriv)},
+ {"glSamplerParameterivRobustANGLE", P(GL_SamplerParameterivRobustANGLE)},
+ DESKTOP_ONLY("glScaled", GL_Scaled)
+ {"glScalef", P(GL_Scalef)},
+ {"glScalex", P(GL_Scalex)},
+ {"glScissor", P(GL_Scissor)},
+ DESKTOP_ONLY("glScissorArrayv", GL_ScissorArrayv)
+ DESKTOP_ONLY("glScissorIndexed", GL_ScissorIndexed)
+ DESKTOP_ONLY("glScissorIndexedv", GL_ScissorIndexedv)
+ DESKTOP_ONLY("glSecondaryColor3b", GL_SecondaryColor3b)
+ DESKTOP_ONLY("glSecondaryColor3bv", GL_SecondaryColor3bv)
+ DESKTOP_ONLY("glSecondaryColor3d", GL_SecondaryColor3d)
+ DESKTOP_ONLY("glSecondaryColor3dv", GL_SecondaryColor3dv)
+ DESKTOP_ONLY("glSecondaryColor3f", GL_SecondaryColor3f)
+ DESKTOP_ONLY("glSecondaryColor3fv", GL_SecondaryColor3fv)
+ DESKTOP_ONLY("glSecondaryColor3i", GL_SecondaryColor3i)
+ DESKTOP_ONLY("glSecondaryColor3iv", GL_SecondaryColor3iv)
+ DESKTOP_ONLY("glSecondaryColor3s", GL_SecondaryColor3s)
+ DESKTOP_ONLY("glSecondaryColor3sv", GL_SecondaryColor3sv)
+ DESKTOP_ONLY("glSecondaryColor3ub", GL_SecondaryColor3ub)
+ DESKTOP_ONLY("glSecondaryColor3ubv", GL_SecondaryColor3ubv)
+ DESKTOP_ONLY("glSecondaryColor3ui", GL_SecondaryColor3ui)
+ DESKTOP_ONLY("glSecondaryColor3uiv", GL_SecondaryColor3uiv)
+ DESKTOP_ONLY("glSecondaryColor3us", GL_SecondaryColor3us)
+ DESKTOP_ONLY("glSecondaryColor3usv", GL_SecondaryColor3usv)
+ DESKTOP_ONLY("glSecondaryColorP3ui", GL_SecondaryColorP3ui)
+ DESKTOP_ONLY("glSecondaryColorP3uiv", GL_SecondaryColorP3uiv)
+ DESKTOP_ONLY("glSecondaryColorPointer", GL_SecondaryColorPointer)
+ DESKTOP_ONLY("glSelectBuffer", GL_SelectBuffer)
+ {"glSelectPerfMonitorCountersAMD", P(GL_SelectPerfMonitorCountersAMD)},
+ {"glSemaphoreParameterui64vEXT", P(GL_SemaphoreParameterui64vEXT)},
+ {"glSetFenceNV", P(GL_SetFenceNV)},
+ {"glShadeModel", P(GL_ShadeModel)},
+ {"glShaderBinary", P(GL_ShaderBinary)},
+ {"glShaderSource", P(GL_ShaderSource)},
+ DESKTOP_ONLY("glShaderStorageBlockBinding", GL_ShaderStorageBlockBinding)
+ {"glShadingRateQCOM", P(GL_ShadingRateQCOM)},
+ {"glSignalSemaphoreEXT", P(GL_SignalSemaphoreEXT)},
+ DESKTOP_ONLY("glSpecializeShader", GL_SpecializeShader)
+ {"glStencilFunc", P(GL_StencilFunc)},
+ {"glStencilFuncSeparate", P(GL_StencilFuncSeparate)},
+ {"glStencilMask", P(GL_StencilMask)},
+ {"glStencilMaskSeparate", P(GL_StencilMaskSeparate)},
+ {"glStencilOp", P(GL_StencilOp)},
+ {"glStencilOpSeparate", P(GL_StencilOpSeparate)},
+ {"glTestFenceNV", P(GL_TestFenceNV)},
+ {"glTexBuffer", P(GL_TexBuffer)},
+ {"glTexBufferEXT", P(GL_TexBufferEXT)},
+ {"glTexBufferOES", P(GL_TexBufferOES)},
+ {"glTexBufferRange", P(GL_TexBufferRange)},
+ {"glTexBufferRangeEXT", P(GL_TexBufferRangeEXT)},
+ {"glTexBufferRangeOES", P(GL_TexBufferRangeOES)},
+ DESKTOP_ONLY("glTexCoord1d", GL_TexCoord1d)
+ DESKTOP_ONLY("glTexCoord1dv", GL_TexCoord1dv)
+ DESKTOP_ONLY("glTexCoord1f", GL_TexCoord1f)
+ DESKTOP_ONLY("glTexCoord1fv", GL_TexCoord1fv)
+ DESKTOP_ONLY("glTexCoord1i", GL_TexCoord1i)
+ DESKTOP_ONLY("glTexCoord1iv", GL_TexCoord1iv)
+ DESKTOP_ONLY("glTexCoord1s", GL_TexCoord1s)
+ DESKTOP_ONLY("glTexCoord1sv", GL_TexCoord1sv)
+ DESKTOP_ONLY("glTexCoord2d", GL_TexCoord2d)
+ DESKTOP_ONLY("glTexCoord2dv", GL_TexCoord2dv)
+ DESKTOP_ONLY("glTexCoord2f", GL_TexCoord2f)
+ DESKTOP_ONLY("glTexCoord2fv", GL_TexCoord2fv)
+ DESKTOP_ONLY("glTexCoord2i", GL_TexCoord2i)
+ DESKTOP_ONLY("glTexCoord2iv", GL_TexCoord2iv)
+ DESKTOP_ONLY("glTexCoord2s", GL_TexCoord2s)
+ DESKTOP_ONLY("glTexCoord2sv", GL_TexCoord2sv)
+ DESKTOP_ONLY("glTexCoord3d", GL_TexCoord3d)
+ DESKTOP_ONLY("glTexCoord3dv", GL_TexCoord3dv)
+ DESKTOP_ONLY("glTexCoord3f", GL_TexCoord3f)
+ DESKTOP_ONLY("glTexCoord3fv", GL_TexCoord3fv)
+ DESKTOP_ONLY("glTexCoord3i", GL_TexCoord3i)
+ DESKTOP_ONLY("glTexCoord3iv", GL_TexCoord3iv)
+ DESKTOP_ONLY("glTexCoord3s", GL_TexCoord3s)
+ DESKTOP_ONLY("glTexCoord3sv", GL_TexCoord3sv)
+ DESKTOP_ONLY("glTexCoord4d", GL_TexCoord4d)
+ DESKTOP_ONLY("glTexCoord4dv", GL_TexCoord4dv)
+ DESKTOP_ONLY("glTexCoord4f", GL_TexCoord4f)
+ DESKTOP_ONLY("glTexCoord4fv", GL_TexCoord4fv)
+ DESKTOP_ONLY("glTexCoord4i", GL_TexCoord4i)
+ DESKTOP_ONLY("glTexCoord4iv", GL_TexCoord4iv)
+ DESKTOP_ONLY("glTexCoord4s", GL_TexCoord4s)
+ DESKTOP_ONLY("glTexCoord4sv", GL_TexCoord4sv)
+ DESKTOP_ONLY("glTexCoordP1ui", GL_TexCoordP1ui)
+ DESKTOP_ONLY("glTexCoordP1uiv", GL_TexCoordP1uiv)
+ DESKTOP_ONLY("glTexCoordP2ui", GL_TexCoordP2ui)
+ DESKTOP_ONLY("glTexCoordP2uiv", GL_TexCoordP2uiv)
+ DESKTOP_ONLY("glTexCoordP3ui", GL_TexCoordP3ui)
+ DESKTOP_ONLY("glTexCoordP3uiv", GL_TexCoordP3uiv)
+ DESKTOP_ONLY("glTexCoordP4ui", GL_TexCoordP4ui)
+ DESKTOP_ONLY("glTexCoordP4uiv", GL_TexCoordP4uiv)
+ {"glTexCoordPointer", P(GL_TexCoordPointer)},
+ {"glTexEnvf", P(GL_TexEnvf)},
+ {"glTexEnvfv", P(GL_TexEnvfv)},
+ {"glTexEnvi", P(GL_TexEnvi)},
+ {"glTexEnviv", P(GL_TexEnviv)},
+ {"glTexEnvx", P(GL_TexEnvx)},
+ {"glTexEnvxv", P(GL_TexEnvxv)},
+ DESKTOP_ONLY("glTexGend", GL_TexGend)
+ DESKTOP_ONLY("glTexGendv", GL_TexGendv)
+ DESKTOP_ONLY("glTexGenf", GL_TexGenf)
+ {"glTexGenfOES", P(GL_TexGenfOES)},
+ DESKTOP_ONLY("glTexGenfv", GL_TexGenfv)
+ {"glTexGenfvOES", P(GL_TexGenfvOES)},
+ DESKTOP_ONLY("glTexGeni", GL_TexGeni)
+ {"glTexGeniOES", P(GL_TexGeniOES)},
+ DESKTOP_ONLY("glTexGeniv", GL_TexGeniv)
+ {"glTexGenivOES", P(GL_TexGenivOES)},
+ {"glTexGenxOES", P(GL_TexGenxOES)},
+ {"glTexGenxvOES", P(GL_TexGenxvOES)},
+ DESKTOP_ONLY("glTexImage1D", GL_TexImage1D)
+ {"glTexImage2D", P(GL_TexImage2D)},
+ {"glTexImage2DExternalANGLE", P(GL_TexImage2DExternalANGLE)},
+ DESKTOP_ONLY("glTexImage2DMultisample", GL_TexImage2DMultisample)
+ {"glTexImage2DRobustANGLE", P(GL_TexImage2DRobustANGLE)},
+ {"glTexImage3D", P(GL_TexImage3D)},
+ DESKTOP_ONLY("glTexImage3DMultisample", GL_TexImage3DMultisample)
+ {"glTexImage3DOES", P(GL_TexImage3DOES)},
+ {"glTexImage3DRobustANGLE", P(GL_TexImage3DRobustANGLE)},
+ {"glTexParameterIiv", P(GL_TexParameterIiv)},
+ {"glTexParameterIivEXT", P(GL_TexParameterIivEXT)},
+ {"glTexParameterIivOES", P(GL_TexParameterIivOES)},
+ {"glTexParameterIivRobustANGLE", P(GL_TexParameterIivRobustANGLE)},
+ {"glTexParameterIuiv", P(GL_TexParameterIuiv)},
+ {"glTexParameterIuivEXT", P(GL_TexParameterIuivEXT)},
+ {"glTexParameterIuivOES", P(GL_TexParameterIuivOES)},
+ {"glTexParameterIuivRobustANGLE", P(GL_TexParameterIuivRobustANGLE)},
+ {"glTexParameterf", P(GL_TexParameterf)},
+ {"glTexParameterfv", P(GL_TexParameterfv)},
+ {"glTexParameterfvRobustANGLE", P(GL_TexParameterfvRobustANGLE)},
+ {"glTexParameteri", P(GL_TexParameteri)},
+ {"glTexParameteriv", P(GL_TexParameteriv)},
+ {"glTexParameterivRobustANGLE", P(GL_TexParameterivRobustANGLE)},
+ {"glTexParameterx", P(GL_TexParameterx)},
+ {"glTexParameterxv", P(GL_TexParameterxv)},
+ DESKTOP_ONLY("glTexStorage1D", GL_TexStorage1D)
+ {"glTexStorage1DEXT", P(GL_TexStorage1DEXT)},
+ {"glTexStorage2D", P(GL_TexStorage2D)},
+ {"glTexStorage2DEXT", P(GL_TexStorage2DEXT)},
+ {"glTexStorage2DMultisample", P(GL_TexStorage2DMultisample)},
+ {"glTexStorage2DMultisampleANGLE", P(GL_TexStorage2DMultisampleANGLE)},
+ {"glTexStorage3D", P(GL_TexStorage3D)},
+ {"glTexStorage3DEXT", P(GL_TexStorage3DEXT)},
+ {"glTexStorage3DMultisample", P(GL_TexStorage3DMultisample)},
+ {"glTexStorage3DMultisampleOES", P(GL_TexStorage3DMultisampleOES)},
+ {"glTexStorageMem2DEXT", P(GL_TexStorageMem2DEXT)},
+ {"glTexStorageMem2DMultisampleEXT", P(GL_TexStorageMem2DMultisampleEXT)},
+ {"glTexStorageMem3DEXT", P(GL_TexStorageMem3DEXT)},
+ {"glTexStorageMem3DMultisampleEXT", P(GL_TexStorageMem3DMultisampleEXT)},
+ {"glTexStorageMemFlags2DANGLE", P(GL_TexStorageMemFlags2DANGLE)},
+ {"glTexStorageMemFlags2DMultisampleANGLE", P(GL_TexStorageMemFlags2DMultisampleANGLE)},
+ {"glTexStorageMemFlags3DANGLE", P(GL_TexStorageMemFlags3DANGLE)},
+ {"glTexStorageMemFlags3DMultisampleANGLE", P(GL_TexStorageMemFlags3DMultisampleANGLE)},
+ DESKTOP_ONLY("glTexSubImage1D", GL_TexSubImage1D)
+ {"glTexSubImage2D", P(GL_TexSubImage2D)},
+ {"glTexSubImage2DRobustANGLE", P(GL_TexSubImage2DRobustANGLE)},
+ {"glTexSubImage3D", P(GL_TexSubImage3D)},
+ {"glTexSubImage3DOES", P(GL_TexSubImage3DOES)},
+ {"glTexSubImage3DRobustANGLE", P(GL_TexSubImage3DRobustANGLE)},
+ DESKTOP_ONLY("glTextureBarrier", GL_TextureBarrier)
+ DESKTOP_ONLY("glTextureBuffer", GL_TextureBuffer)
+ DESKTOP_ONLY("glTextureBufferRange", GL_TextureBufferRange)
+ DESKTOP_ONLY("glTextureParameterIiv", GL_TextureParameterIiv)
+ DESKTOP_ONLY("glTextureParameterIuiv", GL_TextureParameterIuiv)
+ DESKTOP_ONLY("glTextureParameterf", GL_TextureParameterf)
+ DESKTOP_ONLY("glTextureParameterfv", GL_TextureParameterfv)
+ DESKTOP_ONLY("glTextureParameteri", GL_TextureParameteri)
+ DESKTOP_ONLY("glTextureParameteriv", GL_TextureParameteriv)
+ DESKTOP_ONLY("glTextureStorage1D", GL_TextureStorage1D)
+ DESKTOP_ONLY("glTextureStorage2D", GL_TextureStorage2D)
+ DESKTOP_ONLY("glTextureStorage2DMultisample", GL_TextureStorage2DMultisample)
+ DESKTOP_ONLY("glTextureStorage3D", GL_TextureStorage3D)
+ DESKTOP_ONLY("glTextureStorage3DMultisample", GL_TextureStorage3DMultisample)
+ DESKTOP_ONLY("glTextureSubImage1D", GL_TextureSubImage1D)
+ DESKTOP_ONLY("glTextureSubImage2D", GL_TextureSubImage2D)
+ DESKTOP_ONLY("glTextureSubImage3D", GL_TextureSubImage3D)
+ DESKTOP_ONLY("glTextureView", GL_TextureView)
+ DESKTOP_ONLY("glTransformFeedbackBufferBase", GL_TransformFeedbackBufferBase)
+ DESKTOP_ONLY("glTransformFeedbackBufferRange", GL_TransformFeedbackBufferRange)
+ {"glTransformFeedbackVaryings", P(GL_TransformFeedbackVaryings)},
+ DESKTOP_ONLY("glTranslated", GL_Translated)
+ {"glTranslatef", P(GL_Translatef)},
+ {"glTranslatex", P(GL_Translatex)},
+ DESKTOP_ONLY("glUniform1d", GL_Uniform1d)
+ DESKTOP_ONLY("glUniform1dv", GL_Uniform1dv)
+ {"glUniform1f", P(GL_Uniform1f)},
+ {"glUniform1fv", P(GL_Uniform1fv)},
+ {"glUniform1i", P(GL_Uniform1i)},
+ {"glUniform1iv", P(GL_Uniform1iv)},
+ {"glUniform1ui", P(GL_Uniform1ui)},
+ {"glUniform1uiv", P(GL_Uniform1uiv)},
+ DESKTOP_ONLY("glUniform2d", GL_Uniform2d)
+ DESKTOP_ONLY("glUniform2dv", GL_Uniform2dv)
+ {"glUniform2f", P(GL_Uniform2f)},
+ {"glUniform2fv", P(GL_Uniform2fv)},
+ {"glUniform2i", P(GL_Uniform2i)},
+ {"glUniform2iv", P(GL_Uniform2iv)},
+ {"glUniform2ui", P(GL_Uniform2ui)},
+ {"glUniform2uiv", P(GL_Uniform2uiv)},
+ DESKTOP_ONLY("glUniform3d", GL_Uniform3d)
+ DESKTOP_ONLY("glUniform3dv", GL_Uniform3dv)
+ {"glUniform3f", P(GL_Uniform3f)},
+ {"glUniform3fv", P(GL_Uniform3fv)},
+ {"glUniform3i", P(GL_Uniform3i)},
+ {"glUniform3iv", P(GL_Uniform3iv)},
+ {"glUniform3ui", P(GL_Uniform3ui)},
+ {"glUniform3uiv", P(GL_Uniform3uiv)},
+ DESKTOP_ONLY("glUniform4d", GL_Uniform4d)
+ DESKTOP_ONLY("glUniform4dv", GL_Uniform4dv)
+ {"glUniform4f", P(GL_Uniform4f)},
+ {"glUniform4fv", P(GL_Uniform4fv)},
+ {"glUniform4i", P(GL_Uniform4i)},
+ {"glUniform4iv", P(GL_Uniform4iv)},
+ {"glUniform4ui", P(GL_Uniform4ui)},
+ {"glUniform4uiv", P(GL_Uniform4uiv)},
+ {"glUniformBlockBinding", P(GL_UniformBlockBinding)},
+ DESKTOP_ONLY("glUniformMatrix2dv", GL_UniformMatrix2dv)
+ {"glUniformMatrix2fv", P(GL_UniformMatrix2fv)},
+ DESKTOP_ONLY("glUniformMatrix2x3dv", GL_UniformMatrix2x3dv)
+ {"glUniformMatrix2x3fv", P(GL_UniformMatrix2x3fv)},
+ DESKTOP_ONLY("glUniformMatrix2x4dv", GL_UniformMatrix2x4dv)
+ {"glUniformMatrix2x4fv", P(GL_UniformMatrix2x4fv)},
+ DESKTOP_ONLY("glUniformMatrix3dv", GL_UniformMatrix3dv)
+ {"glUniformMatrix3fv", P(GL_UniformMatrix3fv)},
+ DESKTOP_ONLY("glUniformMatrix3x2dv", GL_UniformMatrix3x2dv)
+ {"glUniformMatrix3x2fv", P(GL_UniformMatrix3x2fv)},
+ DESKTOP_ONLY("glUniformMatrix3x4dv", GL_UniformMatrix3x4dv)
+ {"glUniformMatrix3x4fv", P(GL_UniformMatrix3x4fv)},
+ DESKTOP_ONLY("glUniformMatrix4dv", GL_UniformMatrix4dv)
+ {"glUniformMatrix4fv", P(GL_UniformMatrix4fv)},
+ DESKTOP_ONLY("glUniformMatrix4x2dv", GL_UniformMatrix4x2dv)
+ {"glUniformMatrix4x2fv", P(GL_UniformMatrix4x2fv)},
+ DESKTOP_ONLY("glUniformMatrix4x3dv", GL_UniformMatrix4x3dv)
+ {"glUniformMatrix4x3fv", P(GL_UniformMatrix4x3fv)},
+ DESKTOP_ONLY("glUniformSubroutinesuiv", GL_UniformSubroutinesuiv)
+ {"glUnmapBuffer", P(GL_UnmapBuffer)},
+ {"glUnmapBufferOES", P(GL_UnmapBufferOES)},
+ DESKTOP_ONLY("glUnmapNamedBuffer", GL_UnmapNamedBuffer)
+ {"glUseProgram", P(GL_UseProgram)},
+ {"glUseProgramStages", P(GL_UseProgramStages)},
+ {"glUseProgramStagesEXT", P(GL_UseProgramStagesEXT)},
+ {"glValidateProgram", P(GL_ValidateProgram)},
+ {"glValidateProgramPipeline", P(GL_ValidateProgramPipeline)},
+ {"glValidateProgramPipelineEXT", P(GL_ValidateProgramPipelineEXT)},
+ DESKTOP_ONLY("glVertex2d", GL_Vertex2d)
+ DESKTOP_ONLY("glVertex2dv", GL_Vertex2dv)
+ DESKTOP_ONLY("glVertex2f", GL_Vertex2f)
+ DESKTOP_ONLY("glVertex2fv", GL_Vertex2fv)
+ DESKTOP_ONLY("glVertex2i", GL_Vertex2i)
+ DESKTOP_ONLY("glVertex2iv", GL_Vertex2iv)
+ DESKTOP_ONLY("glVertex2s", GL_Vertex2s)
+ DESKTOP_ONLY("glVertex2sv", GL_Vertex2sv)
+ DESKTOP_ONLY("glVertex3d", GL_Vertex3d)
+ DESKTOP_ONLY("glVertex3dv", GL_Vertex3dv)
+ DESKTOP_ONLY("glVertex3f", GL_Vertex3f)
+ DESKTOP_ONLY("glVertex3fv", GL_Vertex3fv)
+ DESKTOP_ONLY("glVertex3i", GL_Vertex3i)
+ DESKTOP_ONLY("glVertex3iv", GL_Vertex3iv)
+ DESKTOP_ONLY("glVertex3s", GL_Vertex3s)
+ DESKTOP_ONLY("glVertex3sv", GL_Vertex3sv)
+ DESKTOP_ONLY("glVertex4d", GL_Vertex4d)
+ DESKTOP_ONLY("glVertex4dv", GL_Vertex4dv)
+ DESKTOP_ONLY("glVertex4f", GL_Vertex4f)
+ DESKTOP_ONLY("glVertex4fv", GL_Vertex4fv)
+ DESKTOP_ONLY("glVertex4i", GL_Vertex4i)
+ DESKTOP_ONLY("glVertex4iv", GL_Vertex4iv)
+ DESKTOP_ONLY("glVertex4s", GL_Vertex4s)
+ DESKTOP_ONLY("glVertex4sv", GL_Vertex4sv)
+ DESKTOP_ONLY("glVertexArrayAttribBinding", GL_VertexArrayAttribBinding)
+ DESKTOP_ONLY("glVertexArrayAttribFormat", GL_VertexArrayAttribFormat)
+ DESKTOP_ONLY("glVertexArrayAttribIFormat", GL_VertexArrayAttribIFormat)
+ DESKTOP_ONLY("glVertexArrayAttribLFormat", GL_VertexArrayAttribLFormat)
+ DESKTOP_ONLY("glVertexArrayBindingDivisor", GL_VertexArrayBindingDivisor)
+ DESKTOP_ONLY("glVertexArrayElementBuffer", GL_VertexArrayElementBuffer)
+ DESKTOP_ONLY("glVertexArrayVertexBuffer", GL_VertexArrayVertexBuffer)
+ DESKTOP_ONLY("glVertexArrayVertexBuffers", GL_VertexArrayVertexBuffers)
+ DESKTOP_ONLY("glVertexAttrib1d", GL_VertexAttrib1d)
+ DESKTOP_ONLY("glVertexAttrib1dv", GL_VertexAttrib1dv)
+ {"glVertexAttrib1f", P(GL_VertexAttrib1f)},
+ {"glVertexAttrib1fv", P(GL_VertexAttrib1fv)},
+ DESKTOP_ONLY("glVertexAttrib1s", GL_VertexAttrib1s)
+ DESKTOP_ONLY("glVertexAttrib1sv", GL_VertexAttrib1sv)
+ DESKTOP_ONLY("glVertexAttrib2d", GL_VertexAttrib2d)
+ DESKTOP_ONLY("glVertexAttrib2dv", GL_VertexAttrib2dv)
+ {"glVertexAttrib2f", P(GL_VertexAttrib2f)},
+ {"glVertexAttrib2fv", P(GL_VertexAttrib2fv)},
+ DESKTOP_ONLY("glVertexAttrib2s", GL_VertexAttrib2s)
+ DESKTOP_ONLY("glVertexAttrib2sv", GL_VertexAttrib2sv)
+ DESKTOP_ONLY("glVertexAttrib3d", GL_VertexAttrib3d)
+ DESKTOP_ONLY("glVertexAttrib3dv", GL_VertexAttrib3dv)
+ {"glVertexAttrib3f", P(GL_VertexAttrib3f)},
+ {"glVertexAttrib3fv", P(GL_VertexAttrib3fv)},
+ DESKTOP_ONLY("glVertexAttrib3s", GL_VertexAttrib3s)
+ DESKTOP_ONLY("glVertexAttrib3sv", GL_VertexAttrib3sv)
+ DESKTOP_ONLY("glVertexAttrib4Nbv", GL_VertexAttrib4Nbv)
+ DESKTOP_ONLY("glVertexAttrib4Niv", GL_VertexAttrib4Niv)
+ DESKTOP_ONLY("glVertexAttrib4Nsv", GL_VertexAttrib4Nsv)
+ DESKTOP_ONLY("glVertexAttrib4Nub", GL_VertexAttrib4Nub)
+ DESKTOP_ONLY("glVertexAttrib4Nubv", GL_VertexAttrib4Nubv)
+ DESKTOP_ONLY("glVertexAttrib4Nuiv", GL_VertexAttrib4Nuiv)
+ DESKTOP_ONLY("glVertexAttrib4Nusv", GL_VertexAttrib4Nusv)
+ DESKTOP_ONLY("glVertexAttrib4bv", GL_VertexAttrib4bv)
+ DESKTOP_ONLY("glVertexAttrib4d", GL_VertexAttrib4d)
+ DESKTOP_ONLY("glVertexAttrib4dv", GL_VertexAttrib4dv)
+ {"glVertexAttrib4f", P(GL_VertexAttrib4f)},
+ {"glVertexAttrib4fv", P(GL_VertexAttrib4fv)},
+ DESKTOP_ONLY("glVertexAttrib4iv", GL_VertexAttrib4iv)
+ DESKTOP_ONLY("glVertexAttrib4s", GL_VertexAttrib4s)
+ DESKTOP_ONLY("glVertexAttrib4sv", GL_VertexAttrib4sv)
+ DESKTOP_ONLY("glVertexAttrib4ubv", GL_VertexAttrib4ubv)
+ DESKTOP_ONLY("glVertexAttrib4uiv", GL_VertexAttrib4uiv)
+ DESKTOP_ONLY("glVertexAttrib4usv", GL_VertexAttrib4usv)
+ {"glVertexAttribBinding", P(GL_VertexAttribBinding)},
+ {"glVertexAttribDivisor", P(GL_VertexAttribDivisor)},
+ {"glVertexAttribDivisorANGLE", P(GL_VertexAttribDivisorANGLE)},
+ {"glVertexAttribDivisorEXT", P(GL_VertexAttribDivisorEXT)},
+ {"glVertexAttribFormat", P(GL_VertexAttribFormat)},
+ DESKTOP_ONLY("glVertexAttribI1i", GL_VertexAttribI1i)
+ DESKTOP_ONLY("glVertexAttribI1iv", GL_VertexAttribI1iv)
+ DESKTOP_ONLY("glVertexAttribI1ui", GL_VertexAttribI1ui)
+ DESKTOP_ONLY("glVertexAttribI1uiv", GL_VertexAttribI1uiv)
+ DESKTOP_ONLY("glVertexAttribI2i", GL_VertexAttribI2i)
+ DESKTOP_ONLY("glVertexAttribI2iv", GL_VertexAttribI2iv)
+ DESKTOP_ONLY("glVertexAttribI2ui", GL_VertexAttribI2ui)
+ DESKTOP_ONLY("glVertexAttribI2uiv", GL_VertexAttribI2uiv)
+ DESKTOP_ONLY("glVertexAttribI3i", GL_VertexAttribI3i)
+ DESKTOP_ONLY("glVertexAttribI3iv", GL_VertexAttribI3iv)
+ DESKTOP_ONLY("glVertexAttribI3ui", GL_VertexAttribI3ui)
+ DESKTOP_ONLY("glVertexAttribI3uiv", GL_VertexAttribI3uiv)
+ DESKTOP_ONLY("glVertexAttribI4bv", GL_VertexAttribI4bv)
+ {"glVertexAttribI4i", P(GL_VertexAttribI4i)},
+ {"glVertexAttribI4iv", P(GL_VertexAttribI4iv)},
+ DESKTOP_ONLY("glVertexAttribI4sv", GL_VertexAttribI4sv)
+ DESKTOP_ONLY("glVertexAttribI4ubv", GL_VertexAttribI4ubv)
+ {"glVertexAttribI4ui", P(GL_VertexAttribI4ui)},
+ {"glVertexAttribI4uiv", P(GL_VertexAttribI4uiv)},
+ DESKTOP_ONLY("glVertexAttribI4usv", GL_VertexAttribI4usv)
+ {"glVertexAttribIFormat", P(GL_VertexAttribIFormat)},
+ {"glVertexAttribIPointer", P(GL_VertexAttribIPointer)},
+ DESKTOP_ONLY("glVertexAttribL1d", GL_VertexAttribL1d)
+ DESKTOP_ONLY("glVertexAttribL1dv", GL_VertexAttribL1dv)
+ DESKTOP_ONLY("glVertexAttribL2d", GL_VertexAttribL2d)
+ DESKTOP_ONLY("glVertexAttribL2dv", GL_VertexAttribL2dv)
+ DESKTOP_ONLY("glVertexAttribL3d", GL_VertexAttribL3d)
+ DESKTOP_ONLY("glVertexAttribL3dv", GL_VertexAttribL3dv)
+ DESKTOP_ONLY("glVertexAttribL4d", GL_VertexAttribL4d)
+ DESKTOP_ONLY("glVertexAttribL4dv", GL_VertexAttribL4dv)
+ DESKTOP_ONLY("glVertexAttribLFormat", GL_VertexAttribLFormat)
+ DESKTOP_ONLY("glVertexAttribLPointer", GL_VertexAttribLPointer)
+ DESKTOP_ONLY("glVertexAttribP1ui", GL_VertexAttribP1ui)
+ DESKTOP_ONLY("glVertexAttribP1uiv", GL_VertexAttribP1uiv)
+ DESKTOP_ONLY("glVertexAttribP2ui", GL_VertexAttribP2ui)
+ DESKTOP_ONLY("glVertexAttribP2uiv", GL_VertexAttribP2uiv)
+ DESKTOP_ONLY("glVertexAttribP3ui", GL_VertexAttribP3ui)
+ DESKTOP_ONLY("glVertexAttribP3uiv", GL_VertexAttribP3uiv)
+ DESKTOP_ONLY("glVertexAttribP4ui", GL_VertexAttribP4ui)
+ DESKTOP_ONLY("glVertexAttribP4uiv", GL_VertexAttribP4uiv)
+ {"glVertexAttribPointer", P(GL_VertexAttribPointer)},
+ {"glVertexBindingDivisor", P(GL_VertexBindingDivisor)},
+ DESKTOP_ONLY("glVertexP2ui", GL_VertexP2ui)
+ DESKTOP_ONLY("glVertexP2uiv", GL_VertexP2uiv)
+ DESKTOP_ONLY("glVertexP3ui", GL_VertexP3ui)
+ DESKTOP_ONLY("glVertexP3uiv", GL_VertexP3uiv)
+ DESKTOP_ONLY("glVertexP4ui", GL_VertexP4ui)
+ DESKTOP_ONLY("glVertexP4uiv", GL_VertexP4uiv)
+ {"glVertexPointer", P(GL_VertexPointer)},
+ {"glViewport", P(GL_Viewport)},
+ DESKTOP_ONLY("glViewportArrayv", GL_ViewportArrayv)
+ DESKTOP_ONLY("glViewportIndexedf", GL_ViewportIndexedf)
+ DESKTOP_ONLY("glViewportIndexedfv", GL_ViewportIndexedfv)
+ {"glWaitSemaphoreEXT", P(GL_WaitSemaphoreEXT)},
+ {"glWaitSync", P(GL_WaitSync)},
+ {"glWeightPointerOES", P(GL_WeightPointerOES)},
+ DESKTOP_ONLY("glWindowPos2d", GL_WindowPos2d)
+ DESKTOP_ONLY("glWindowPos2dv", GL_WindowPos2dv)
+ DESKTOP_ONLY("glWindowPos2f", GL_WindowPos2f)
+ DESKTOP_ONLY("glWindowPos2fv", GL_WindowPos2fv)
+ DESKTOP_ONLY("glWindowPos2i", GL_WindowPos2i)
+ DESKTOP_ONLY("glWindowPos2iv", GL_WindowPos2iv)
+ DESKTOP_ONLY("glWindowPos2s", GL_WindowPos2s)
+ DESKTOP_ONLY("glWindowPos2sv", GL_WindowPos2sv)
+ DESKTOP_ONLY("glWindowPos3d", GL_WindowPos3d)
+ DESKTOP_ONLY("glWindowPos3dv", GL_WindowPos3dv)
+ DESKTOP_ONLY("glWindowPos3f", GL_WindowPos3f)
+ DESKTOP_ONLY("glWindowPos3fv", GL_WindowPos3fv)
+ DESKTOP_ONLY("glWindowPos3i", GL_WindowPos3i)
+ DESKTOP_ONLY("glWindowPos3iv", GL_WindowPos3iv)
+ DESKTOP_ONLY("glWindowPos3s", GL_WindowPos3s)
+ DESKTOP_ONLY("glWindowPos3sv", GL_WindowPos3sv)
+};
+// clang-format on
+const size_t g_numProcs = std::size(g_procTable);
+} // namespace egl
diff --git a/gfx/angle/checkout/src/libGLESv2/resource.h b/gfx/angle/checkout/src/libGLESv2/resource.h
new file mode 100644
index 0000000000..025777671d
--- /dev/null
+++ b/gfx/angle/checkout/src/libGLESv2/resource.h
@@ -0,0 +1,17 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by libGLESv2.rc
+
+#define IDD_DIALOG1 101
+#define IDC_STATIC -1
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+# ifndef APSTUDIO_READONLY_SYMBOLS
+# define _APS_NEXT_RESOURCE_VALUE 101
+# define _APS_NEXT_COMMAND_VALUE 40001
+# define _APS_NEXT_CONTROL_VALUE 1001
+# define _APS_NEXT_SYMED_VALUE 101
+# endif
+#endif
diff --git a/gfx/angle/checkout/src/third_party/systeminfo/SystemInfo.cpp b/gfx/angle/checkout/src/third_party/systeminfo/SystemInfo.cpp
new file mode 100644
index 0000000000..4b11109761
--- /dev/null
+++ b/gfx/angle/checkout/src/third_party/systeminfo/SystemInfo.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <windows.h>
+#include "common/platform.h"
+
+#if _WIN32_WINNT_WINBLUE
+# include <versionhelpers.h>
+#endif
+
+namespace rx
+{
+
+#ifndef _WIN32_WINNT_WINBLUE
+static bool IsWindowsVistaOrGreater()
+{
+ OSVERSIONINFOEXW osvi = {};
+ osvi.dwOSVersionInfoSize = sizeof(osvi);
+ osvi.dwMajorVersion = HIBYTE(_WIN32_WINNT_VISTA);
+ osvi.dwMinorVersion = LOBYTE(_WIN32_WINNT_VISTA);
+ DWORDLONG condition = 0;
+ VER_SET_CONDITION(condition, VER_MAJORVERSION, VER_GREATER_EQUAL);
+ VER_SET_CONDITION(condition, VER_MINORVERSION, VER_GREATER_EQUAL);
+ return !!::VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION, condition);
+}
+#endif
+
+bool isWindowsVistaOrGreater()
+{
+ static bool initialized = false;
+ static bool cachedIsWindowsVistaOrGreater;
+
+ if (!initialized)
+ {
+ initialized = true;
+#if defined(ANGLE_ENABLE_WINDOWS_STORE)
+ cachedIsWindowsVistaOrGreater = true;
+#else
+ cachedIsWindowsVistaOrGreater = IsWindowsVistaOrGreater();
+#endif
+ }
+ return cachedIsWindowsVistaOrGreater;
+}
+
+} // namespace rx
diff --git a/gfx/angle/checkout/src/third_party/systeminfo/SystemInfo.h b/gfx/angle/checkout/src/third_party/systeminfo/SystemInfo.h
new file mode 100644
index 0000000000..5c3b2e6541
--- /dev/null
+++ b/gfx/angle/checkout/src/third_party/systeminfo/SystemInfo.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef THIRD_PARTY_SYSTEMINFO_SYSTEMINFO_H_
+#define THIRD_PARTY_SYSTEMINFO_SYSTEMINFO_H_
+
+namespace rx
+{
+
+bool isWindowsVistaOrGreater();
+
+} // namespace rx
+
+#endif // THIRD_PARTY_SYSTEMINFO_SYSTEMINFO_H_
diff --git a/gfx/angle/checkout/src/third_party/trace_event/trace_event.h b/gfx/angle/checkout/src/third_party/trace_event/trace_event.h
new file mode 100644
index 0000000000..53b5277145
--- /dev/null
+++ b/gfx/angle/checkout/src/third_party/trace_event/trace_event.h
@@ -0,0 +1,777 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Trace events are for tracking application performance and resource usage.
+// Macros are provided to track:
+// Begin and end of function calls
+// Counters
+//
+// Events are issued against categories. Whereas LOG's
+// categories are statically defined, TRACE categories are created
+// implicitly with a string. For example:
+// TRACE_EVENT_INSTANT0("MY_SUBSYSTEM", "SomeImportantEvent")
+//
+// Events can be INSTANT, or can be pairs of BEGIN and END in the same scope:
+// TRACE_EVENT_BEGIN0("MY_SUBSYSTEM", "SomethingCostly")
+// doSomethingCostly()
+// TRACE_EVENT_END0("MY_SUBSYSTEM", "SomethingCostly")
+// Note: our tools can't always determine the correct BEGIN/END pairs unless
+// these are used in the same scope. Use ASYNC_BEGIN/ASYNC_END macros if you need them
+// to be in separate scopes.
+//
+// A common use case is to trace entire function scopes. This
+// issues a trace BEGIN and END automatically:
+// void doSomethingCostly() {
+// TRACE_EVENT0("MY_SUBSYSTEM", "doSomethingCostly");
+// ...
+// }
+//
+// Additional parameters can be associated with an event:
+// void doSomethingCostly2(int howMuch) {
+// TRACE_EVENT1("MY_SUBSYSTEM", "doSomethingCostly",
+// "howMuch", howMuch);
+// ...
+// }
+//
+// The trace system will automatically add to this information the
+// current process id, thread id, and a timestamp in microseconds.
+//
+// To trace an asynchronous procedure such as an IPC send/receive, use ASYNC_BEGIN and
+// ASYNC_END:
+// [single threaded sender code]
+// static int send_count = 0;
+// ++send_count;
+// TRACE_EVENT_ASYNC_BEGIN0("ipc", "message", send_count);
+// Send(new MyMessage(send_count));
+// [receive code]
+// void OnMyMessage(send_count) {
+// TRACE_EVENT_ASYNC_END0("ipc", "message", send_count);
+// }
+// The third parameter is a unique ID to match ASYNC_BEGIN/ASYNC_END pairs.
+// ASYNC_BEGIN and ASYNC_END can occur on any thread of any traced process. Pointers can
+// be used for the ID parameter, and they will be mangled internally so that
+// the same pointer on two different processes will not match. For example:
+// class MyTracedClass {
+// public:
+// MyTracedClass() {
+// TRACE_EVENT_ASYNC_BEGIN0("category", "MyTracedClass", this);
+// }
+// ~MyTracedClass() {
+// TRACE_EVENT_ASYNC_END0("category", "MyTracedClass", this);
+// }
+// }
+//
+// Trace event also supports counters, which is a way to track a quantity
+// as it varies over time. Counters are created with the following macro:
+// TRACE_COUNTER1("MY_SUBSYSTEM", "myCounter", g_myCounterValue);
+//
+// Counters are process-specific. The macro itself can be issued from any
+// thread, however.
+//
+// Sometimes, you want to track two counters at once. You can do this with two
+// counter macros:
+// TRACE_COUNTER1("MY_SUBSYSTEM", "myCounter0", g_myCounterValue[0]);
+// TRACE_COUNTER1("MY_SUBSYSTEM", "myCounter1", g_myCounterValue[1]);
+// Or you can do it with a combined macro:
+// TRACE_COUNTER2("MY_SUBSYSTEM", "myCounter",
+// "bytesPinned", g_myCounterValue[0],
+// "bytesAllocated", g_myCounterValue[1]);
+// This indicates to the tracing UI that these counters should be displayed
+// in a single graph, as a summed area chart.
+//
+// Since counters are in a global namespace, you may want to disembiguate with a
+// unique ID, by using the TRACE_COUNTER_ID* variations.
+//
+// By default, trace collection is compiled in, but turned off at runtime.
+// Collecting trace data is the responsibility of the embedding
+// application. In Chrome's case, navigating to about:tracing will turn on
+// tracing and display data collected across all active processes.
+//
+//
+// Memory scoping note:
+// Tracing copies the pointers, not the string content, of the strings passed
+// in for category, name, and arg_names. Thus, the following code will
+// cause problems:
+// char* str = strdup("impprtantName");
+// TRACE_EVENT_INSTANT0("SUBSYSTEM", str); // BAD!
+// free(str); // Trace system now has dangling pointer
+//
+// To avoid this issue with the |name| and |arg_name| parameters, use the
+// TRACE_EVENT_COPY_XXX overloads of the macros at additional runtime overhead.
+// Notes: The category must always be in a long-lived char* (i.e. static const).
+// The |arg_values|, when used, are always deep copied with the _COPY
+// macros.
+//
+// When are string argument values copied:
+// const char* arg_values are only referenced by default:
+// TRACE_EVENT1("category", "name",
+// "arg1", "literal string is only referenced");
+// Use TRACE_STR_COPY to force copying of a const char*:
+// TRACE_EVENT1("category", "name",
+// "arg1", TRACE_STR_COPY("string will be copied"));
+// std::string arg_values are always copied:
+// TRACE_EVENT1("category", "name",
+// "arg1", std::string("string will be copied"));
+//
+//
+// Thread Safety:
+// A thread safe singleton and mutex are used for thread safety. Category
+// enabled flags are used to limit the performance impact when the system
+// is not enabled.
+//
+// TRACE_EVENT macros first cache a pointer to a category. The categories are
+// statically allocated and safe at all times, even after exit. Fetching a
+// category is protected by the TraceLog::lock_. Multiple threads initializing
+// the static variable is safe, as they will be serialized by the lock and
+// multiple calls will return the same pointer to the category.
+//
+// Then the category_enabled flag is checked. This is a unsigned char, and
+// not intended to be multithread safe. It optimizes access to addTraceEvent
+// which is threadsafe internally via TraceLog::lock_. The enabled flag may
+// cause some threads to incorrectly call or skip calling addTraceEvent near
+// the time of the system being enabled or disabled. This is acceptable as
+// we tolerate some data loss while the system is being enabled/disabled and
+// because addTraceEvent is threadsafe internally and checks the enabled state
+// again under lock.
+//
+// Without the use of these static category pointers and enabled flags all
+// trace points would carry a significant performance cost of aquiring a lock
+// and resolving the category.
+
+#ifndef COMMON_TRACE_EVENT_H_
+#define COMMON_TRACE_EVENT_H_
+
+#include <string>
+
+#include "common/event_tracer.h"
+
+// By default, const char* argument values are assumed to have long-lived scope
+// and will not be copied. Use this macro to force a const char* to be copied.
+#define TRACE_STR_COPY(str) WebCore::TraceEvent::TraceStringWithCopy(str)
+
+// Records a pair of begin and end events called "name" for the current
+// scope, with 0, 1 or 2 associated arguments. If the category is not
+// enabled, then this does nothing.
+// - category and name strings must have application lifetime (statics or
+// literals). They may not include " chars.
+#define TRACE_EVENT0(platform, category, name) \
+ INTERNAL_TRACE_EVENT_ADD_SCOPED(platform, category, name)
+#define TRACE_EVENT1(platform, category, name, arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD_SCOPED(platform, category, name, arg1_name, arg1_val)
+#define TRACE_EVENT2(category, name, arg1_name, arg1_val, arg2_name, arg2_val) \
+ INTERNAL_TRACE_EVENT_ADD_SCOPED(platform, category, name, arg1_name, arg1_val, arg2_name, \
+ arg2_val)
+
+// Records a single event called "name" immediately, with 0, 1 or 2
+// associated arguments. If the category is not enabled, then this
+// does nothing.
+// - category and name strings must have application lifetime (statics or
+// literals). They may not include " chars.
+#define TRACE_EVENT_INSTANT0(platform, category, name) \
+ INTERNAL_TRACE_EVENT_ADD(platform, TRACE_EVENT_PHASE_INSTANT, category, name, \
+ TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_INSTANT1(platform, category, name, arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD(platform, TRACE_EVENT_PHASE_INSTANT, category, name, \
+ TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
+#define TRACE_EVENT_INSTANT2(platform, category, name, arg1_name, arg1_val, arg2_name, arg2_val) \
+ INTERNAL_TRACE_EVENT_ADD(platform, TRACE_EVENT_PHASE_INSTANT, category, name, \
+ TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, arg2_name, arg2_val)
+#define TRACE_EVENT_COPY_INSTANT0(platform, category, name) \
+ INTERNAL_TRACE_EVENT_ADD(platform, TRACE_EVENT_PHASE_INSTANT, category, name, \
+ TRACE_EVENT_FLAG_COPY)
+#define TRACE_EVENT_COPY_INSTANT1(platform, category, name, arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD(platform, TRACE_EVENT_PHASE_INSTANT, category, name, \
+ TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val)
+#define TRACE_EVENT_COPY_INSTANT2(platform, category, name, arg1_name, arg1_val, arg2_name, \
+ arg2_val) \
+ INTERNAL_TRACE_EVENT_ADD(platform, TRACE_EVENT_PHASE_INSTANT, category, name, \
+ TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, arg2_name, arg2_val)
+
+// Records a single BEGIN event called "name" immediately, with 0, 1 or 2
+// associated arguments. If the category is not enabled, then this
+// does nothing.
+// - category and name strings must have application lifetime (statics or
+// literals). They may not include " chars.
+#define TRACE_EVENT_BEGIN0(platform, category, name) \
+ INTERNAL_TRACE_EVENT_ADD(platform, TRACE_EVENT_PHASE_BEGIN, category, name, \
+ TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_BEGIN1(platform, category, name, arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD(platform, TRACE_EVENT_PHASE_BEGIN, category, name, \
+ TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
+#define TRACE_EVENT_BEGIN2(platform, category, name, arg1_name, arg1_val, arg2_name, arg2_val) \
+ INTERNAL_TRACE_EVENT_ADD(platform, TRACE_EVENT_PHASE_BEGIN, category, name, \
+ TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, arg2_name, arg2_val)
+#define TRACE_EVENT_COPY_BEGIN0(platform, category, name) \
+ INTERNAL_TRACE_EVENT_ADD(platform, TRACE_EVENT_PHASE_BEGIN, category, name, \
+ TRACE_EVENT_FLAG_COPY)
+#define TRACE_EVENT_COPY_BEGIN1(platform, category, name, arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD(platform, TRACE_EVENT_PHASE_BEGIN, category, name, \
+ TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val)
+#define TRACE_EVENT_COPY_BEGIN2(platform, category, name, arg1_name, arg1_val, arg2_name, \
+ arg2_val) \
+ INTERNAL_TRACE_EVENT_ADD(platform, TRACE_EVENT_PHASE_BEGIN, category, name, \
+ TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, arg2_name, arg2_val)
+
+// Records a single END event for "name" immediately. If the category
+// is not enabled, then this does nothing.
+// - category and name strings must have application lifetime (statics or
+// literals). They may not include " chars.
+#define TRACE_EVENT_END0(platform, category, name) \
+ INTERNAL_TRACE_EVENT_ADD(platform, TRACE_EVENT_PHASE_END, category, name, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_END1(platform, category, name, arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD(platform, TRACE_EVENT_PHASE_END, category, name, \
+ TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
+#define TRACE_EVENT_END2(platform, category, name, arg1_name, arg1_val, arg2_name, arg2_val) \
+ INTERNAL_TRACE_EVENT_ADD(platform, TRACE_EVENT_PHASE_END, category, name, \
+ TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, arg2_name, arg2_val)
+#define TRACE_EVENT_COPY_END0(platform, category, name) \
+ INTERNAL_TRACE_EVENT_ADD(platform, TRACE_EVENT_PHASE_END, category, name, TRACE_EVENT_FLAG_COPY)
+#define TRACE_EVENT_COPY_END1(platform, category, name, arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD(platform, TRACE_EVENT_PHASE_END, category, name, \
+ TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val)
+#define TRACE_EVENT_COPY_END2(platform, category, name, arg1_name, arg1_val, arg2_name, arg2_val) \
+ INTERNAL_TRACE_EVENT_ADD(platform, TRACE_EVENT_PHASE_END, category, name, \
+ TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, arg2_name, arg2_val)
+
+// Records the value of a counter called "name" immediately. Value
+// must be representable as a 32 bit integer.
+// - category and name strings must have application lifetime (statics or
+// literals). They may not include " chars.
+#define TRACE_COUNTER1(platform, category, name, value) \
+ INTERNAL_TRACE_EVENT_ADD(platform, TRACE_EVENT_PHASE_COUNTER, category, name, \
+ TRACE_EVENT_FLAG_NONE, "value", static_cast<int>(value))
+#define TRACE_COPY_COUNTER1(platform, category, name, value) \
+ INTERNAL_TRACE_EVENT_ADD(platform, TRACE_EVENT_PHASE_COUNTER, category, name, \
+ TRACE_EVENT_FLAG_COPY, "value", static_cast<int>(value))
+
+// Records the values of a multi-parted counter called "name" immediately.
+// The UI will treat value1 and value2 as parts of a whole, displaying their
+// values as a stacked-bar chart.
+// - category and name strings must have application lifetime (statics or
+// literals). They may not include " chars.
+#define TRACE_COUNTER2(platform, category, name, value1_name, value1_val, value2_name, value2_val) \
+ INTERNAL_TRACE_EVENT_ADD(platform, TRACE_EVENT_PHASE_COUNTER, category, name, \
+ TRACE_EVENT_FLAG_NONE, value1_name, static_cast<int>(value1_val), \
+ value2_name, static_cast<int>(value2_val))
+#define TRACE_COPY_COUNTER2(platform, category, name, value1_name, value1_val, value2_name, \
+ value2_val) \
+ INTERNAL_TRACE_EVENT_ADD(platform, TRACE_EVENT_PHASE_COUNTER, category, name, \
+ TRACE_EVENT_FLAG_COPY, value1_name, static_cast<int>(value1_val), \
+ value2_name, static_cast<int>(value2_val))
+
+// Records the value of a counter called "name" immediately. Value
+// must be representable as a 32 bit integer.
+// - category and name strings must have application lifetime (statics or
+// literals). They may not include " chars.
+// - |id| is used to disambiguate counters with the same name. It must either
+// be a pointer or an integer value up to 64 bits. If it's a pointer, the bits
+// will be xored with a hash of the process ID so that the same pointer on
+// two different processes will not collide.
+#define TRACE_COUNTER_ID1(platform, category, name, id, value) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(platform, TRACE_EVENT_PHASE_COUNTER, category, name, id, \
+ TRACE_EVENT_FLAG_NONE, "value", static_cast<int>(value))
+#define TRACE_COPY_COUNTER_ID1(platform, category, name, id, value) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(platform, TRACE_EVENT_PHASE_COUNTER, category, name, id, \
+ TRACE_EVENT_FLAG_COPY, "value", static_cast<int>(value))
+
+// Records the values of a multi-parted counter called "name" immediately.
+// The UI will treat value1 and value2 as parts of a whole, displaying their
+// values as a stacked-bar chart.
+// - category and name strings must have application lifetime (statics or
+// literals). They may not include " chars.
+// - |id| is used to disambiguate counters with the same name. It must either
+// be a pointer or an integer value up to 64 bits. If it's a pointer, the bits
+// will be xored with a hash of the process ID so that the same pointer on
+// two different processes will not collide.
+#define TRACE_COUNTER_ID2(platform, category, name, id, value1_name, value1_val, value2_name, \
+ value2_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID( \
+ platform, TRACE_EVENT_PHASE_COUNTER, category, name, id, TRACE_EVENT_FLAG_NONE, \
+ value1_name, static_cast<int>(value1_val), value2_name, static_cast<int>(value2_val))
+#define TRACE_COPY_COUNTER_ID2(platform, category, name, id, value1_name, value1_val, value2_name, \
+ value2_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID( \
+ platform, TRACE_EVENT_PHASE_COUNTER, category, name, id, TRACE_EVENT_FLAG_COPY, \
+ value1_name, static_cast<int>(value1_val), value2_name, static_cast<int>(value2_val))
+
+// Records a single ASYNC_BEGIN event called "name" immediately, with 0, 1 or 2
+// associated arguments. If the category is not enabled, then this
+// does nothing.
+// - category and name strings must have application lifetime (statics or
+// literals). They may not include " chars.
+// - |id| is used to match the ASYNC_BEGIN event with the ASYNC_END event. ASYNC
+// events are considered to match if their category, name and id values all
+// match. |id| must either be a pointer or an integer value up to 64 bits. If
+// it's a pointer, the bits will be xored with a hash of the process ID so
+// that the same pointer on two different processes will not collide.
+// An asynchronous operation can consist of multiple phases. The first phase is
+// defined by the ASYNC_BEGIN calls. Additional phases can be defined using the
+// ASYNC_STEP_BEGIN macros. When the operation completes, call ASYNC_END.
+// An async operation can span threads and processes, but all events in that
+// operation must use the same |name| and |id|. Each event can have its own
+// args.
+#define TRACE_EVENT_ASYNC_BEGIN0(platform, category, name, id) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(platform, TRACE_EVENT_PHASE_ASYNC_BEGIN, category, name, id, \
+ TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_ASYNC_BEGIN1(platform, category, name, id, arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(platform, TRACE_EVENT_PHASE_ASYNC_BEGIN, category, name, id, \
+ TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
+#define TRACE_EVENT_ASYNC_BEGIN2(platform, category, name, id, arg1_name, arg1_val, arg2_name, \
+ arg2_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(platform, TRACE_EVENT_PHASE_ASYNC_BEGIN, category, name, id, \
+ TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, arg2_name, \
+ arg2_val)
+#define TRACE_EVENT_COPY_ASYNC_BEGIN0(platform, category, name, id) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(platform, TRACE_EVENT_PHASE_ASYNC_BEGIN, category, name, id, \
+ TRACE_EVENT_FLAG_COPY)
+#define TRACE_EVENT_COPY_ASYNC_BEGIN1(platform, category, name, id, arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(platform, TRACE_EVENT_PHASE_ASYNC_BEGIN, category, name, id, \
+ TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val)
+#define TRACE_EVENT_COPY_ASYNC_BEGIN2(platform, category, name, id, arg1_name, arg1_val, \
+ arg2_name, arg2_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(platform, TRACE_EVENT_PHASE_ASYNC_BEGIN, category, name, id, \
+ TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, arg2_name, \
+ arg2_val)
+
+// Records a single ASYNC_STEP event for |step| immediately. If the category
+// is not enabled, then this does nothing. The |name| and |id| must match the
+// ASYNC_BEGIN event above. The |step| param identifies this step within the
+// async event. This should be called at the beginning of the next phase of an
+// asynchronous operation.
+#define TRACE_EVENT_ASYNC_STEP0(platform, category, name, id, step) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(platform, TRACE_EVENT_PHASE_ASYNC_STEP, category, name, id, \
+ TRACE_EVENT_FLAG_NONE, "step", step)
+#define TRACE_EVENT_ASYNC_STEP1(platform, category, name, id, step, arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(platform, TRACE_EVENT_PHASE_ASYNC_STEP, category, name, id, \
+ TRACE_EVENT_FLAG_NONE, "step", step, arg1_name, arg1_val)
+#define TRACE_EVENT_COPY_ASYNC_STEP0(platform, category, name, id, step) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(platform, TRACE_EVENT_PHASE_ASYNC_STEP, category, name, id, \
+ TRACE_EVENT_FLAG_COPY, "step", step)
+#define TRACE_EVENT_COPY_ASYNC_STEP1(platform, category, name, id, step, arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(platform, TRACE_EVENT_PHASE_ASYNC_STEP, category, name, id, \
+ TRACE_EVENT_FLAG_COPY, "step", step, arg1_name, arg1_val)
+
+// Records a single ASYNC_END event for "name" immediately. If the category
+// is not enabled, then this does nothing.
+#define TRACE_EVENT_ASYNC_END0(platform, category, name, id) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(platform, TRACE_EVENT_PHASE_ASYNC_END, category, name, id, \
+ TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_ASYNC_END1(platform, category, name, id, arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(platform, TRACE_EVENT_PHASE_ASYNC_END, category, name, id, \
+ TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
+#define TRACE_EVENT_ASYNC_END2(platform, category, name, id, arg1_name, arg1_val, arg2_name, \
+ arg2_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(platform, TRACE_EVENT_PHASE_ASYNC_END, category, name, id, \
+ TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, arg2_name, \
+ arg2_val)
+#define TRACE_EVENT_COPY_ASYNC_END0(platform, category, name, id) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(platform, TRACE_EVENT_PHASE_ASYNC_END, category, name, id, \
+ TRACE_EVENT_FLAG_COPY)
+#define TRACE_EVENT_COPY_ASYNC_END1(platform, category, name, id, arg1_name, arg1_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(platform, TRACE_EVENT_PHASE_ASYNC_END, category, name, id, \
+ TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val)
+#define TRACE_EVENT_COPY_ASYNC_END2(platform, category, name, id, arg1_name, arg1_val, arg2_name, \
+ arg2_val) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID(platform, TRACE_EVENT_PHASE_ASYNC_END, category, name, id, \
+ TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, arg2_name, \
+ arg2_val)
+
+// Creates a scope of a sampling state with the given category and name (both must
+// be constant strings). These states are intended for a sampling profiler.
+// Implementation note: we store category and name together because we don't
+// want the inconsistency/expense of storing two pointers.
+// |thread_bucket| is [0..2] and is used to statically isolate samples in one
+// thread from others.
+//
+// { // The sampling state is set within this scope.
+// TRACE_EVENT_SAMPLING_STATE_SCOPE_FOR_BUCKET(0, "category", "name");
+// ...;
+// }
+#define TRACE_EVENT_SCOPED_SAMPLING_STATE_FOR_BUCKET(bucket_number, category, name) \
+ TraceEvent::SamplingStateScope<bucket_number> traceEventSamplingScope(category "\0" name);
+
+// Returns a current sampling state of the given bucket.
+// The format of the returned string is "category\0name".
+#define TRACE_EVENT_GET_SAMPLING_STATE_FOR_BUCKET(bucket_number) \
+ TraceEvent::SamplingStateScope<bucket_number>::current()
+
+// Sets a current sampling state of the given bucket.
+// |category| and |name| have to be constant strings.
+#define TRACE_EVENT_SET_SAMPLING_STATE_FOR_BUCKET(bucket_number, category, name) \
+ TraceEvent::SamplingStateScope<bucket_number>::set(category "\0" name)
+
+// Sets a current sampling state of the given bucket.
+// |categoryAndName| doesn't need to be a constant string.
+// The format of the string is "category\0name".
+#define TRACE_EVENT_SET_NONCONST_SAMPLING_STATE_FOR_BUCKET(bucket_number, categoryAndName) \
+ TraceEvent::SamplingStateScope<bucket_number>::set(categoryAndName)
+
+// Syntactic sugars for the sampling tracing in the main thread.
+#define TRACE_EVENT_SCOPED_SAMPLING_STATE(category, name) \
+ TRACE_EVENT_SCOPED_SAMPLING_STATE_FOR_BUCKET(0, category, name)
+#define TRACE_EVENT_GET_SAMPLING_STATE() TRACE_EVENT_GET_SAMPLING_STATE_FOR_BUCKET(0)
+#define TRACE_EVENT_SET_SAMPLING_STATE(category, name) \
+ TRACE_EVENT_SET_SAMPLING_STATE_FOR_BUCKET(0, category, name)
+#define TRACE_EVENT_SET_NONCONST_SAMPLING_STATE(categoryAndName) \
+ TRACE_EVENT_SET_NONCONST_SAMPLING_STATE_FOR_BUCKET(0, categoryAndName)
+
+////////////////////////////////////////////////////////////////////////////////
+// Implementation specific tracing API definitions.
+
+// Get a pointer to the enabled state of the given trace category. Only
+// long-lived literal strings should be given as the category name. The returned
+// pointer can be held permanently in a local static for example. If the
+// unsigned char is non-zero, tracing is enabled. If tracing is enabled,
+// TRACE_EVENT_API_ADD_TRACE_EVENT can be called. It's OK if tracing is disabled
+// between the load of the tracing state and the call to
+// TRACE_EVENT_API_ADD_TRACE_EVENT, because this flag only provides an early out
+// for best performance when tracing is disabled.
+// const unsigned char*
+// TRACE_EVENT_API_GET_CATEGORY_ENABLED(const char* category_name)
+#define TRACE_EVENT_API_GET_CATEGORY_ENABLED angle::GetTraceCategoryEnabledFlag
+
+// Add a trace event to the platform tracing system.
+// void TRACE_EVENT_API_ADD_TRACE_EVENT(
+// char phase,
+// const unsigned char* category_enabled,
+// const char* name,
+// unsigned long long id,
+// int num_args,
+// const char** arg_names,
+// const unsigned char* arg_types,
+// const unsigned long long* arg_values,
+// unsigned char flags)
+#define TRACE_EVENT_API_ADD_TRACE_EVENT angle::AddTraceEvent
+
+////////////////////////////////////////////////////////////////////////////////
+
+// Implementation detail: trace event macros create temporary variables
+// to keep instrumentation overhead low. These macros give each temporary
+// variable a unique name based on the line number to prevent name collissions.
+#define INTERNAL_TRACE_EVENT_UID3(a, b) trace_event_unique_##a##b
+#define INTERNAL_TRACE_EVENT_UID2(a, b) INTERNAL_TRACE_EVENT_UID3(a, b)
+#define INTERNALTRACEEVENTUID(name_prefix) INTERNAL_TRACE_EVENT_UID2(name_prefix, __LINE__)
+
+// Implementation detail: internal macro to create static category.
+#define INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(platform, category) \
+ static const unsigned char *INTERNALTRACEEVENTUID(catstatic) = \
+ TRACE_EVENT_API_GET_CATEGORY_ENABLED(platform, category);
+
+// Implementation detail: internal macro to create static category and add
+// event if the category is enabled.
+#define INTERNAL_TRACE_EVENT_ADD(platform, phase, category, name, flags, ...) \
+ do \
+ { \
+ INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(platform, category); \
+ if (*INTERNALTRACEEVENTUID(catstatic)) \
+ { \
+ gl::TraceEvent::addTraceEvent(platform, phase, INTERNALTRACEEVENTUID(catstatic), name, \
+ gl::TraceEvent::noEventId, flags, ##__VA_ARGS__); \
+ } \
+ } while (0)
+
+// Implementation detail: internal macro to create static category and add begin
+// event if the category is enabled. Also adds the end event when the scope
+// ends.
+#define INTERNAL_TRACE_EVENT_ADD_SCOPED(platform, category, name, ...) \
+ INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(platform, category); \
+ gl::TraceEvent::TraceEndOnScopeClose INTERNALTRACEEVENTUID(profileScope); \
+ do \
+ { \
+ if (*INTERNALTRACEEVENTUID(catstatic)) \
+ { \
+ gl::TraceEvent::addTraceEvent( \
+ platform, TRACE_EVENT_PHASE_BEGIN, INTERNALTRACEEVENTUID(catstatic), name, \
+ gl::TraceEvent::noEventId, TRACE_EVENT_FLAG_NONE, ##__VA_ARGS__); \
+ INTERNALTRACEEVENTUID(profileScope) \
+ .initialize(platform, INTERNALTRACEEVENTUID(catstatic), name); \
+ } \
+ } while (0)
+
+// Implementation detail: internal macro to create static category and add
+// event if the category is enabled.
+#define INTERNAL_TRACE_EVENT_ADD_WITH_ID(platform, phase, category, name, id, flags, ...) \
+ do \
+ { \
+ INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(platform, category); \
+ if (*INTERNALTRACEEVENTUID(catstatic)) \
+ { \
+ unsigned char traceEventFlags = flags | TRACE_EVENT_FLAG_HAS_ID; \
+ gl::TraceEvent::TraceID traceEventTraceID(id, &traceEventFlags); \
+ gl::TraceEvent::addTraceEvent(platform, phase, INTERNALTRACEEVENTUID(catstatic), name, \
+ traceEventTraceID.data(), traceEventFlags, \
+ ##__VA_ARGS__); \
+ } \
+ } while (0)
+
+// Notes regarding the following definitions:
+// New values can be added and propagated to third party libraries, but existing
+// definitions must never be changed, because third party libraries may use old
+// definitions.
+
+// Phase indicates the nature of an event entry. E.g. part of a begin/end pair.
+#define TRACE_EVENT_PHASE_BEGIN ('B')
+#define TRACE_EVENT_PHASE_END ('E')
+#define TRACE_EVENT_PHASE_INSTANT ('I')
+#define TRACE_EVENT_PHASE_ASYNC_BEGIN ('S')
+#define TRACE_EVENT_PHASE_ASYNC_STEP ('T')
+#define TRACE_EVENT_PHASE_ASYNC_END ('F')
+#define TRACE_EVENT_PHASE_METADATA ('M')
+#define TRACE_EVENT_PHASE_COUNTER ('C')
+#define TRACE_EVENT_PHASE_SAMPLE ('P')
+
+// Flags for changing the behavior of TRACE_EVENT_API_ADD_TRACE_EVENT.
+#define TRACE_EVENT_FLAG_NONE (static_cast<unsigned char>(0))
+#define TRACE_EVENT_FLAG_COPY (static_cast<unsigned char>(1 << 0))
+#define TRACE_EVENT_FLAG_HAS_ID (static_cast<unsigned char>(1 << 1))
+#define TRACE_EVENT_FLAG_MANGLE_ID (static_cast<unsigned char>(1 << 2))
+
+// Type values for identifying types in the TraceValue union.
+#define TRACE_VALUE_TYPE_BOOL (static_cast<unsigned char>(1))
+#define TRACE_VALUE_TYPE_UINT (static_cast<unsigned char>(2))
+#define TRACE_VALUE_TYPE_INT (static_cast<unsigned char>(3))
+#define TRACE_VALUE_TYPE_DOUBLE (static_cast<unsigned char>(4))
+#define TRACE_VALUE_TYPE_POINTER (static_cast<unsigned char>(5))
+#define TRACE_VALUE_TYPE_STRING (static_cast<unsigned char>(6))
+#define TRACE_VALUE_TYPE_COPY_STRING (static_cast<unsigned char>(7))
+
+namespace gl
+{
+
+namespace TraceEvent
+{
+
+// Specify these values when the corresponding argument of addTraceEvent is not
+// used.
+const int zeroNumArgs = 0;
+const unsigned long long noEventId = 0;
+
+// TraceID encapsulates an ID that can either be an integer or pointer. Pointers
+// are mangled with the Process ID so that they are unlikely to collide when the
+// same pointer is used on different processes.
+class TraceID
+{
+ public:
+ explicit TraceID(const void *id, unsigned char *flags)
+ : m_data(static_cast<unsigned long long>(reinterpret_cast<uintptr_t>(id)))
+ {
+ *flags |= TRACE_EVENT_FLAG_MANGLE_ID;
+ }
+ explicit TraceID(unsigned long long id, unsigned char *flags) : m_data(id) { (void)flags; }
+ explicit TraceID(unsigned long id, unsigned char *flags) : m_data(id) { (void)flags; }
+ explicit TraceID(unsigned int id, unsigned char *flags) : m_data(id) { (void)flags; }
+ explicit TraceID(unsigned short id, unsigned char *flags) : m_data(id) { (void)flags; }
+ explicit TraceID(unsigned char id, unsigned char *flags) : m_data(id) { (void)flags; }
+ explicit TraceID(long long id, unsigned char *flags)
+ : m_data(static_cast<unsigned long long>(id))
+ {
+ (void)flags;
+ }
+ explicit TraceID(long id, unsigned char *flags) : m_data(static_cast<unsigned long long>(id))
+ {
+ (void)flags;
+ }
+ explicit TraceID(int id, unsigned char *flags) : m_data(static_cast<unsigned long long>(id))
+ {
+ (void)flags;
+ }
+ explicit TraceID(short id, unsigned char *flags) : m_data(static_cast<unsigned long long>(id))
+ {
+ (void)flags;
+ }
+ explicit TraceID(signed char id, unsigned char *flags)
+ : m_data(static_cast<unsigned long long>(id))
+ {
+ (void)flags;
+ }
+
+ unsigned long long data() const { return m_data; }
+
+ private:
+ unsigned long long m_data;
+};
+
+// Simple union to store various types as unsigned long long.
+union TraceValueUnion
+{
+ bool m_bool;
+ unsigned long long m_uint;
+ long long m_int;
+ double m_double;
+ const void *m_pointer;
+ const char *m_string;
+};
+
+// Simple container for const char* that should be copied instead of retained.
+class TraceStringWithCopy
+{
+ public:
+ explicit TraceStringWithCopy(const char *str) : m_str(str) {}
+ operator const char *() const { return m_str; }
+
+ private:
+ const char *m_str;
+};
+
+// Define setTraceValue for each allowed type. It stores the type and
+// value in the return arguments. This allows this API to avoid declaring any
+// structures so that it is portable to third_party libraries.
+#define INTERNAL_DECLARE_SET_TRACE_VALUE(actual_type, union_member, value_type_id) \
+ static inline void setTraceValue(actual_type arg, unsigned char *type, \
+ unsigned long long *value) \
+ { \
+ TraceValueUnion typeValue; \
+ typeValue.union_member = arg; \
+ *type = value_type_id; \
+ *value = typeValue.m_uint; \
+ }
+// Simpler form for int types that can be safely casted.
+#define INTERNAL_DECLARE_SET_TRACE_VALUE_INT(actual_type, value_type_id) \
+ static inline void setTraceValue(actual_type arg, unsigned char *type, \
+ unsigned long long *value) \
+ { \
+ *type = value_type_id; \
+ *value = static_cast<unsigned long long>(arg); \
+ }
+
+INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned long long, TRACE_VALUE_TYPE_UINT)
+INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned int, TRACE_VALUE_TYPE_UINT)
+INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned short, TRACE_VALUE_TYPE_UINT)
+INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned char, TRACE_VALUE_TYPE_UINT)
+INTERNAL_DECLARE_SET_TRACE_VALUE_INT(long long, TRACE_VALUE_TYPE_INT)
+INTERNAL_DECLARE_SET_TRACE_VALUE_INT(int, TRACE_VALUE_TYPE_INT)
+INTERNAL_DECLARE_SET_TRACE_VALUE_INT(short, TRACE_VALUE_TYPE_INT)
+INTERNAL_DECLARE_SET_TRACE_VALUE_INT(signed char, TRACE_VALUE_TYPE_INT)
+INTERNAL_DECLARE_SET_TRACE_VALUE(bool, m_bool, TRACE_VALUE_TYPE_BOOL)
+INTERNAL_DECLARE_SET_TRACE_VALUE(double, m_double, TRACE_VALUE_TYPE_DOUBLE)
+INTERNAL_DECLARE_SET_TRACE_VALUE(const void *, m_pointer, TRACE_VALUE_TYPE_POINTER)
+INTERNAL_DECLARE_SET_TRACE_VALUE(const char *, m_string, TRACE_VALUE_TYPE_STRING)
+INTERNAL_DECLARE_SET_TRACE_VALUE(const TraceStringWithCopy &,
+ m_string,
+ TRACE_VALUE_TYPE_COPY_STRING)
+
+#undef INTERNAL_DECLARE_SET_TRACE_VALUE
+#undef INTERNAL_DECLARE_SET_TRACE_VALUE_INT
+
+static inline void setTraceValue(const std::string &arg,
+ unsigned char *type,
+ unsigned long long *value)
+{
+ TraceValueUnion typeValue;
+ typeValue.m_string = arg.data();
+ *type = TRACE_VALUE_TYPE_COPY_STRING;
+ *value = typeValue.m_uint;
+}
+
+// These addTraceEvent template functions are defined here instead of in the
+// macro, because the arg values could be temporary string objects. In order to
+// store pointers to the internal c_str and pass through to the tracing API, the
+// arg values must live throughout these procedures.
+
+static inline angle::TraceEventHandle addTraceEvent(angle::PlatformMethods *platform,
+ char phase,
+ const unsigned char *categoryEnabled,
+ const char *name,
+ unsigned long long id,
+ unsigned char flags)
+{
+ return TRACE_EVENT_API_ADD_TRACE_EVENT(platform, phase, categoryEnabled, name, id, zeroNumArgs,
+ 0, 0, 0, flags);
+}
+
+template <class ARG1_TYPE>
+static inline angle::TraceEventHandle addTraceEvent(angle::PlatformMethods *platform,
+ char phase,
+ const unsigned char *categoryEnabled,
+ const char *name,
+ unsigned long long id,
+ unsigned char flags,
+ const char *arg1Name,
+ const ARG1_TYPE &arg1Val)
+{
+ const int numArgs = 1;
+ unsigned char argTypes[1];
+ unsigned long long argValues[1];
+ setTraceValue(arg1Val, &argTypes[0], &argValues[0]);
+ return TRACE_EVENT_API_ADD_TRACE_EVENT(platform, phase, categoryEnabled, name, id, numArgs,
+ &arg1Name, argTypes, argValues, flags);
+}
+
+template <class ARG1_TYPE, class ARG2_TYPE>
+static inline angle::TraceEventHandle addTraceEvent(angle::PlatformMethods *platform,
+ char phase,
+ const unsigned char *categoryEnabled,
+ const char *name,
+ unsigned long long id,
+ unsigned char flags,
+ const char *arg1Name,
+ const ARG1_TYPE &arg1Val,
+ const char *arg2Name,
+ const ARG2_TYPE &arg2Val)
+{
+ const int numArgs = 2;
+ const char *argNames[2] = {arg1Name, arg2Name};
+ unsigned char argTypes[2];
+ unsigned long long argValues[2];
+ setTraceValue(arg1Val, &argTypes[0], &argValues[0]);
+ setTraceValue(arg2Val, &argTypes[1], &argValues[1]);
+ return TRACE_EVENT_API_ADD_TRACE_EVENT(platform, phase, categoryEnabled, name, id, numArgs,
+ argNames, argTypes, argValues, flags);
+}
+
+// Used by TRACE_EVENTx macro. Do not use directly.
+class TraceEndOnScopeClose
+{
+ public:
+ // Note: members of m_data intentionally left uninitialized. See initialize.
+ TraceEndOnScopeClose() : m_pdata(0) {}
+ ~TraceEndOnScopeClose()
+ {
+ if (m_pdata)
+ addEventIfEnabled();
+ }
+
+ void initialize(angle::PlatformMethods *platform,
+ const unsigned char *categoryEnabled,
+ const char *name)
+ {
+ m_data.platform = platform;
+ m_data.categoryEnabled = categoryEnabled;
+ m_data.name = name;
+ m_pdata = &m_data;
+ }
+
+ private:
+ // Add the end event if the category is still enabled.
+ void addEventIfEnabled()
+ {
+ // Only called when m_pdata is non-null.
+ if (*m_pdata->categoryEnabled)
+ {
+ TRACE_EVENT_API_ADD_TRACE_EVENT(m_pdata->platform, TRACE_EVENT_PHASE_END,
+ m_pdata->categoryEnabled, m_pdata->name, noEventId,
+ zeroNumArgs, 0, 0, 0, TRACE_EVENT_FLAG_NONE);
+ }
+ }
+
+ // This Data struct workaround is to avoid initializing all the members
+ // in Data during construction of this object, since this object is always
+ // constructed, even when tracing is disabled. If the members of Data were
+ // members of this class instead, compiler warnings occur about potential
+ // uninitialized accesses.
+ struct Data
+ {
+ angle::PlatformMethods *platform;
+ const unsigned char *categoryEnabled;
+ const char *name;
+ };
+ Data *m_pdata;
+ Data m_data;
+};
+
+} // namespace TraceEvent
+
+} // namespace gl
+
+#endif
diff --git a/gfx/angle/checkout/src/third_party/volk/volk.c b/gfx/angle/checkout/src/third_party/volk/volk.c
new file mode 100644
index 0000000000..98adf3f6d2
--- /dev/null
+++ b/gfx/angle/checkout/src/third_party/volk/volk.c
@@ -0,0 +1,2396 @@
+/* This file is part of volk library; see volk.h for version/license details */
+/* clang-format off */
+#include "volk.h"
+
+#ifdef _WIN32
+ typedef const char* LPCSTR;
+ typedef struct HINSTANCE__* HINSTANCE;
+ typedef HINSTANCE HMODULE;
+ #ifdef _WIN64
+ typedef __int64 (__stdcall* FARPROC)(void);
+ #else
+ typedef int (__stdcall* FARPROC)(void);
+ #endif
+#else
+# include <dlfcn.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef _WIN32
+__declspec(dllimport) HMODULE __stdcall LoadLibraryA(LPCSTR);
+__declspec(dllimport) FARPROC __stdcall GetProcAddress(HMODULE, LPCSTR);
+#endif
+
+static VkInstance loadedInstance = VK_NULL_HANDLE;
+static VkDevice loadedDevice = VK_NULL_HANDLE;
+
+static void volkGenLoadLoader(void* context, PFN_vkVoidFunction (*load)(void*, const char*));
+static void volkGenLoadInstance(void* context, PFN_vkVoidFunction (*load)(void*, const char*));
+static void volkGenLoadDevice(void* context, PFN_vkVoidFunction (*load)(void*, const char*));
+static void volkGenLoadDeviceTable(struct VolkDeviceTable* table, void* context, PFN_vkVoidFunction (*load)(void*, const char*));
+
+static PFN_vkVoidFunction vkGetInstanceProcAddrStub(void* context, const char* name)
+{
+ return vkGetInstanceProcAddr((VkInstance)context, name);
+}
+
+static PFN_vkVoidFunction vkGetDeviceProcAddrStub(void* context, const char* name)
+{
+ return vkGetDeviceProcAddr((VkDevice)context, name);
+}
+
+VkResult volkInitialize(void)
+{
+#if defined(_WIN32)
+ HMODULE module = LoadLibraryA("vulkan-1.dll");
+ if (!module)
+ return VK_ERROR_INITIALIZATION_FAILED;
+
+ // note: function pointer is cast through void function pointer to silence cast-function-type warning on gcc8
+ vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)(void(*)(void))GetProcAddress(module, "vkGetInstanceProcAddr");
+#elif defined(__APPLE__)
+ void* module = dlopen("libvulkan.dylib", RTLD_NOW | RTLD_LOCAL);
+ if (!module)
+ module = dlopen("libvulkan.1.dylib", RTLD_NOW | RTLD_LOCAL);
+ if (!module)
+ module = dlopen("libMoltenVK.dylib", RTLD_NOW | RTLD_LOCAL);
+ if (!module)
+ return VK_ERROR_INITIALIZATION_FAILED;
+
+ vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)dlsym(module, "vkGetInstanceProcAddr");
+#else
+ void* module = dlopen("libvulkan.so.1", RTLD_NOW | RTLD_LOCAL);
+ if (!module)
+ module = dlopen("libvulkan.so", RTLD_NOW | RTLD_LOCAL);
+ if (!module)
+ return VK_ERROR_INITIALIZATION_FAILED;
+
+ vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)dlsym(module, "vkGetInstanceProcAddr");
+#endif
+
+ volkGenLoadLoader(NULL, vkGetInstanceProcAddrStub);
+
+ return VK_SUCCESS;
+}
+
+void volkInitializeCustom(PFN_vkGetInstanceProcAddr handler)
+{
+ vkGetInstanceProcAddr = handler;
+
+ volkGenLoadLoader(NULL, vkGetInstanceProcAddrStub);
+}
+
+uint32_t volkGetInstanceVersion(void)
+{
+#if defined(VK_VERSION_1_1)
+ uint32_t apiVersion = 0;
+ if (vkEnumerateInstanceVersion && vkEnumerateInstanceVersion(&apiVersion) == VK_SUCCESS)
+ return apiVersion;
+#endif
+
+ if (vkCreateInstance)
+ return VK_API_VERSION_1_0;
+
+ return 0;
+}
+
+void volkLoadInstance(VkInstance instance)
+{
+ loadedInstance = instance;
+ volkGenLoadInstance(instance, vkGetInstanceProcAddrStub);
+ volkGenLoadDevice(instance, vkGetInstanceProcAddrStub);
+}
+
+void volkLoadInstanceOnly(VkInstance instance)
+{
+ loadedInstance = instance;
+ volkGenLoadInstance(instance, vkGetInstanceProcAddrStub);
+}
+
+VkInstance volkGetLoadedInstance()
+{
+ return loadedInstance;
+}
+
+void volkLoadDevice(VkDevice device)
+{
+ loadedDevice = device;
+ volkGenLoadDevice(device, vkGetDeviceProcAddrStub);
+}
+
+VkDevice volkGetLoadedDevice()
+{
+ return loadedDevice;
+}
+
+void volkLoadDeviceTable(struct VolkDeviceTable* table, VkDevice device)
+{
+ volkGenLoadDeviceTable(table, device, vkGetDeviceProcAddrStub);
+}
+
+static void volkGenLoadLoader(void* context, PFN_vkVoidFunction (*load)(void*, const char*))
+{
+ /* VOLK_GENERATE_LOAD_LOADER */
+#if defined(VK_VERSION_1_0)
+ vkCreateInstance = (PFN_vkCreateInstance)load(context, "vkCreateInstance");
+ vkEnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties)load(context, "vkEnumerateInstanceExtensionProperties");
+ vkEnumerateInstanceLayerProperties = (PFN_vkEnumerateInstanceLayerProperties)load(context, "vkEnumerateInstanceLayerProperties");
+#endif /* defined(VK_VERSION_1_0) */
+#if defined(VK_VERSION_1_1)
+ vkEnumerateInstanceVersion = (PFN_vkEnumerateInstanceVersion)load(context, "vkEnumerateInstanceVersion");
+#endif /* defined(VK_VERSION_1_1) */
+ /* VOLK_GENERATE_LOAD_LOADER */
+}
+
+static void volkGenLoadInstance(void* context, PFN_vkVoidFunction (*load)(void*, const char*))
+{
+ /* VOLK_GENERATE_LOAD_INSTANCE */
+#if defined(VK_VERSION_1_0)
+ vkCreateDevice = (PFN_vkCreateDevice)load(context, "vkCreateDevice");
+ vkDestroyInstance = (PFN_vkDestroyInstance)load(context, "vkDestroyInstance");
+ vkEnumerateDeviceExtensionProperties = (PFN_vkEnumerateDeviceExtensionProperties)load(context, "vkEnumerateDeviceExtensionProperties");
+ vkEnumerateDeviceLayerProperties = (PFN_vkEnumerateDeviceLayerProperties)load(context, "vkEnumerateDeviceLayerProperties");
+ vkEnumeratePhysicalDevices = (PFN_vkEnumeratePhysicalDevices)load(context, "vkEnumeratePhysicalDevices");
+ vkGetDeviceProcAddr = (PFN_vkGetDeviceProcAddr)load(context, "vkGetDeviceProcAddr");
+ vkGetPhysicalDeviceFeatures = (PFN_vkGetPhysicalDeviceFeatures)load(context, "vkGetPhysicalDeviceFeatures");
+ vkGetPhysicalDeviceFormatProperties = (PFN_vkGetPhysicalDeviceFormatProperties)load(context, "vkGetPhysicalDeviceFormatProperties");
+ vkGetPhysicalDeviceImageFormatProperties = (PFN_vkGetPhysicalDeviceImageFormatProperties)load(context, "vkGetPhysicalDeviceImageFormatProperties");
+ vkGetPhysicalDeviceMemoryProperties = (PFN_vkGetPhysicalDeviceMemoryProperties)load(context, "vkGetPhysicalDeviceMemoryProperties");
+ vkGetPhysicalDeviceProperties = (PFN_vkGetPhysicalDeviceProperties)load(context, "vkGetPhysicalDeviceProperties");
+ vkGetPhysicalDeviceQueueFamilyProperties = (PFN_vkGetPhysicalDeviceQueueFamilyProperties)load(context, "vkGetPhysicalDeviceQueueFamilyProperties");
+ vkGetPhysicalDeviceSparseImageFormatProperties = (PFN_vkGetPhysicalDeviceSparseImageFormatProperties)load(context, "vkGetPhysicalDeviceSparseImageFormatProperties");
+#endif /* defined(VK_VERSION_1_0) */
+#if defined(VK_VERSION_1_1)
+ vkEnumeratePhysicalDeviceGroups = (PFN_vkEnumeratePhysicalDeviceGroups)load(context, "vkEnumeratePhysicalDeviceGroups");
+ vkGetPhysicalDeviceExternalBufferProperties = (PFN_vkGetPhysicalDeviceExternalBufferProperties)load(context, "vkGetPhysicalDeviceExternalBufferProperties");
+ vkGetPhysicalDeviceExternalFenceProperties = (PFN_vkGetPhysicalDeviceExternalFenceProperties)load(context, "vkGetPhysicalDeviceExternalFenceProperties");
+ vkGetPhysicalDeviceExternalSemaphoreProperties = (PFN_vkGetPhysicalDeviceExternalSemaphoreProperties)load(context, "vkGetPhysicalDeviceExternalSemaphoreProperties");
+ vkGetPhysicalDeviceFeatures2 = (PFN_vkGetPhysicalDeviceFeatures2)load(context, "vkGetPhysicalDeviceFeatures2");
+ vkGetPhysicalDeviceFormatProperties2 = (PFN_vkGetPhysicalDeviceFormatProperties2)load(context, "vkGetPhysicalDeviceFormatProperties2");
+ vkGetPhysicalDeviceImageFormatProperties2 = (PFN_vkGetPhysicalDeviceImageFormatProperties2)load(context, "vkGetPhysicalDeviceImageFormatProperties2");
+ vkGetPhysicalDeviceMemoryProperties2 = (PFN_vkGetPhysicalDeviceMemoryProperties2)load(context, "vkGetPhysicalDeviceMemoryProperties2");
+ vkGetPhysicalDeviceProperties2 = (PFN_vkGetPhysicalDeviceProperties2)load(context, "vkGetPhysicalDeviceProperties2");
+ vkGetPhysicalDeviceQueueFamilyProperties2 = (PFN_vkGetPhysicalDeviceQueueFamilyProperties2)load(context, "vkGetPhysicalDeviceQueueFamilyProperties2");
+ vkGetPhysicalDeviceSparseImageFormatProperties2 = (PFN_vkGetPhysicalDeviceSparseImageFormatProperties2)load(context, "vkGetPhysicalDeviceSparseImageFormatProperties2");
+#endif /* defined(VK_VERSION_1_1) */
+#if defined(VK_VERSION_1_3)
+ vkGetPhysicalDeviceToolProperties = (PFN_vkGetPhysicalDeviceToolProperties)load(context, "vkGetPhysicalDeviceToolProperties");
+#endif /* defined(VK_VERSION_1_3) */
+#if defined(VK_EXT_acquire_drm_display)
+ vkAcquireDrmDisplayEXT = (PFN_vkAcquireDrmDisplayEXT)load(context, "vkAcquireDrmDisplayEXT");
+ vkGetDrmDisplayEXT = (PFN_vkGetDrmDisplayEXT)load(context, "vkGetDrmDisplayEXT");
+#endif /* defined(VK_EXT_acquire_drm_display) */
+#if defined(VK_EXT_acquire_xlib_display)
+ vkAcquireXlibDisplayEXT = (PFN_vkAcquireXlibDisplayEXT)load(context, "vkAcquireXlibDisplayEXT");
+ vkGetRandROutputDisplayEXT = (PFN_vkGetRandROutputDisplayEXT)load(context, "vkGetRandROutputDisplayEXT");
+#endif /* defined(VK_EXT_acquire_xlib_display) */
+#if defined(VK_EXT_calibrated_timestamps)
+ vkGetPhysicalDeviceCalibrateableTimeDomainsEXT = (PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT)load(context, "vkGetPhysicalDeviceCalibrateableTimeDomainsEXT");
+#endif /* defined(VK_EXT_calibrated_timestamps) */
+#if defined(VK_EXT_debug_report)
+ vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)load(context, "vkCreateDebugReportCallbackEXT");
+ vkDebugReportMessageEXT = (PFN_vkDebugReportMessageEXT)load(context, "vkDebugReportMessageEXT");
+ vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)load(context, "vkDestroyDebugReportCallbackEXT");
+#endif /* defined(VK_EXT_debug_report) */
+#if defined(VK_EXT_debug_utils)
+ vkCmdBeginDebugUtilsLabelEXT = (PFN_vkCmdBeginDebugUtilsLabelEXT)load(context, "vkCmdBeginDebugUtilsLabelEXT");
+ vkCmdEndDebugUtilsLabelEXT = (PFN_vkCmdEndDebugUtilsLabelEXT)load(context, "vkCmdEndDebugUtilsLabelEXT");
+ vkCmdInsertDebugUtilsLabelEXT = (PFN_vkCmdInsertDebugUtilsLabelEXT)load(context, "vkCmdInsertDebugUtilsLabelEXT");
+ vkCreateDebugUtilsMessengerEXT = (PFN_vkCreateDebugUtilsMessengerEXT)load(context, "vkCreateDebugUtilsMessengerEXT");
+ vkDestroyDebugUtilsMessengerEXT = (PFN_vkDestroyDebugUtilsMessengerEXT)load(context, "vkDestroyDebugUtilsMessengerEXT");
+ vkQueueBeginDebugUtilsLabelEXT = (PFN_vkQueueBeginDebugUtilsLabelEXT)load(context, "vkQueueBeginDebugUtilsLabelEXT");
+ vkQueueEndDebugUtilsLabelEXT = (PFN_vkQueueEndDebugUtilsLabelEXT)load(context, "vkQueueEndDebugUtilsLabelEXT");
+ vkQueueInsertDebugUtilsLabelEXT = (PFN_vkQueueInsertDebugUtilsLabelEXT)load(context, "vkQueueInsertDebugUtilsLabelEXT");
+ vkSetDebugUtilsObjectNameEXT = (PFN_vkSetDebugUtilsObjectNameEXT)load(context, "vkSetDebugUtilsObjectNameEXT");
+ vkSetDebugUtilsObjectTagEXT = (PFN_vkSetDebugUtilsObjectTagEXT)load(context, "vkSetDebugUtilsObjectTagEXT");
+ vkSubmitDebugUtilsMessageEXT = (PFN_vkSubmitDebugUtilsMessageEXT)load(context, "vkSubmitDebugUtilsMessageEXT");
+#endif /* defined(VK_EXT_debug_utils) */
+#if defined(VK_EXT_direct_mode_display)
+ vkReleaseDisplayEXT = (PFN_vkReleaseDisplayEXT)load(context, "vkReleaseDisplayEXT");
+#endif /* defined(VK_EXT_direct_mode_display) */
+#if defined(VK_EXT_directfb_surface)
+ vkCreateDirectFBSurfaceEXT = (PFN_vkCreateDirectFBSurfaceEXT)load(context, "vkCreateDirectFBSurfaceEXT");
+ vkGetPhysicalDeviceDirectFBPresentationSupportEXT = (PFN_vkGetPhysicalDeviceDirectFBPresentationSupportEXT)load(context, "vkGetPhysicalDeviceDirectFBPresentationSupportEXT");
+#endif /* defined(VK_EXT_directfb_surface) */
+#if defined(VK_EXT_display_surface_counter)
+ vkGetPhysicalDeviceSurfaceCapabilities2EXT = (PFN_vkGetPhysicalDeviceSurfaceCapabilities2EXT)load(context, "vkGetPhysicalDeviceSurfaceCapabilities2EXT");
+#endif /* defined(VK_EXT_display_surface_counter) */
+#if defined(VK_EXT_full_screen_exclusive)
+ vkGetPhysicalDeviceSurfacePresentModes2EXT = (PFN_vkGetPhysicalDeviceSurfacePresentModes2EXT)load(context, "vkGetPhysicalDeviceSurfacePresentModes2EXT");
+#endif /* defined(VK_EXT_full_screen_exclusive) */
+#if defined(VK_EXT_headless_surface)
+ vkCreateHeadlessSurfaceEXT = (PFN_vkCreateHeadlessSurfaceEXT)load(context, "vkCreateHeadlessSurfaceEXT");
+#endif /* defined(VK_EXT_headless_surface) */
+#if defined(VK_EXT_metal_surface)
+ vkCreateMetalSurfaceEXT = (PFN_vkCreateMetalSurfaceEXT)load(context, "vkCreateMetalSurfaceEXT");
+#endif /* defined(VK_EXT_metal_surface) */
+#if defined(VK_EXT_sample_locations)
+ vkGetPhysicalDeviceMultisamplePropertiesEXT = (PFN_vkGetPhysicalDeviceMultisamplePropertiesEXT)load(context, "vkGetPhysicalDeviceMultisamplePropertiesEXT");
+#endif /* defined(VK_EXT_sample_locations) */
+#if defined(VK_EXT_tooling_info)
+ vkGetPhysicalDeviceToolPropertiesEXT = (PFN_vkGetPhysicalDeviceToolPropertiesEXT)load(context, "vkGetPhysicalDeviceToolPropertiesEXT");
+#endif /* defined(VK_EXT_tooling_info) */
+#if defined(VK_FUCHSIA_imagepipe_surface)
+ vkCreateImagePipeSurfaceFUCHSIA = (PFN_vkCreateImagePipeSurfaceFUCHSIA)load(context, "vkCreateImagePipeSurfaceFUCHSIA");
+#endif /* defined(VK_FUCHSIA_imagepipe_surface) */
+#if defined(VK_GGP_stream_descriptor_surface)
+ vkCreateStreamDescriptorSurfaceGGP = (PFN_vkCreateStreamDescriptorSurfaceGGP)load(context, "vkCreateStreamDescriptorSurfaceGGP");
+#endif /* defined(VK_GGP_stream_descriptor_surface) */
+#if defined(VK_KHR_android_surface)
+ vkCreateAndroidSurfaceKHR = (PFN_vkCreateAndroidSurfaceKHR)load(context, "vkCreateAndroidSurfaceKHR");
+#endif /* defined(VK_KHR_android_surface) */
+#if defined(VK_KHR_device_group_creation)
+ vkEnumeratePhysicalDeviceGroupsKHR = (PFN_vkEnumeratePhysicalDeviceGroupsKHR)load(context, "vkEnumeratePhysicalDeviceGroupsKHR");
+#endif /* defined(VK_KHR_device_group_creation) */
+#if defined(VK_KHR_display)
+ vkCreateDisplayModeKHR = (PFN_vkCreateDisplayModeKHR)load(context, "vkCreateDisplayModeKHR");
+ vkCreateDisplayPlaneSurfaceKHR = (PFN_vkCreateDisplayPlaneSurfaceKHR)load(context, "vkCreateDisplayPlaneSurfaceKHR");
+ vkGetDisplayModePropertiesKHR = (PFN_vkGetDisplayModePropertiesKHR)load(context, "vkGetDisplayModePropertiesKHR");
+ vkGetDisplayPlaneCapabilitiesKHR = (PFN_vkGetDisplayPlaneCapabilitiesKHR)load(context, "vkGetDisplayPlaneCapabilitiesKHR");
+ vkGetDisplayPlaneSupportedDisplaysKHR = (PFN_vkGetDisplayPlaneSupportedDisplaysKHR)load(context, "vkGetDisplayPlaneSupportedDisplaysKHR");
+ vkGetPhysicalDeviceDisplayPlanePropertiesKHR = (PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR)load(context, "vkGetPhysicalDeviceDisplayPlanePropertiesKHR");
+ vkGetPhysicalDeviceDisplayPropertiesKHR = (PFN_vkGetPhysicalDeviceDisplayPropertiesKHR)load(context, "vkGetPhysicalDeviceDisplayPropertiesKHR");
+#endif /* defined(VK_KHR_display) */
+#if defined(VK_KHR_external_fence_capabilities)
+ vkGetPhysicalDeviceExternalFencePropertiesKHR = (PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR)load(context, "vkGetPhysicalDeviceExternalFencePropertiesKHR");
+#endif /* defined(VK_KHR_external_fence_capabilities) */
+#if defined(VK_KHR_external_memory_capabilities)
+ vkGetPhysicalDeviceExternalBufferPropertiesKHR = (PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR)load(context, "vkGetPhysicalDeviceExternalBufferPropertiesKHR");
+#endif /* defined(VK_KHR_external_memory_capabilities) */
+#if defined(VK_KHR_external_semaphore_capabilities)
+ vkGetPhysicalDeviceExternalSemaphorePropertiesKHR = (PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR)load(context, "vkGetPhysicalDeviceExternalSemaphorePropertiesKHR");
+#endif /* defined(VK_KHR_external_semaphore_capabilities) */
+#if defined(VK_KHR_fragment_shading_rate)
+ vkGetPhysicalDeviceFragmentShadingRatesKHR = (PFN_vkGetPhysicalDeviceFragmentShadingRatesKHR)load(context, "vkGetPhysicalDeviceFragmentShadingRatesKHR");
+#endif /* defined(VK_KHR_fragment_shading_rate) */
+#if defined(VK_KHR_get_display_properties2)
+ vkGetDisplayModeProperties2KHR = (PFN_vkGetDisplayModeProperties2KHR)load(context, "vkGetDisplayModeProperties2KHR");
+ vkGetDisplayPlaneCapabilities2KHR = (PFN_vkGetDisplayPlaneCapabilities2KHR)load(context, "vkGetDisplayPlaneCapabilities2KHR");
+ vkGetPhysicalDeviceDisplayPlaneProperties2KHR = (PFN_vkGetPhysicalDeviceDisplayPlaneProperties2KHR)load(context, "vkGetPhysicalDeviceDisplayPlaneProperties2KHR");
+ vkGetPhysicalDeviceDisplayProperties2KHR = (PFN_vkGetPhysicalDeviceDisplayProperties2KHR)load(context, "vkGetPhysicalDeviceDisplayProperties2KHR");
+#endif /* defined(VK_KHR_get_display_properties2) */
+#if defined(VK_KHR_get_physical_device_properties2)
+ vkGetPhysicalDeviceFeatures2KHR = (PFN_vkGetPhysicalDeviceFeatures2KHR)load(context, "vkGetPhysicalDeviceFeatures2KHR");
+ vkGetPhysicalDeviceFormatProperties2KHR = (PFN_vkGetPhysicalDeviceFormatProperties2KHR)load(context, "vkGetPhysicalDeviceFormatProperties2KHR");
+ vkGetPhysicalDeviceImageFormatProperties2KHR = (PFN_vkGetPhysicalDeviceImageFormatProperties2KHR)load(context, "vkGetPhysicalDeviceImageFormatProperties2KHR");
+ vkGetPhysicalDeviceMemoryProperties2KHR = (PFN_vkGetPhysicalDeviceMemoryProperties2KHR)load(context, "vkGetPhysicalDeviceMemoryProperties2KHR");
+ vkGetPhysicalDeviceProperties2KHR = (PFN_vkGetPhysicalDeviceProperties2KHR)load(context, "vkGetPhysicalDeviceProperties2KHR");
+ vkGetPhysicalDeviceQueueFamilyProperties2KHR = (PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR)load(context, "vkGetPhysicalDeviceQueueFamilyProperties2KHR");
+ vkGetPhysicalDeviceSparseImageFormatProperties2KHR = (PFN_vkGetPhysicalDeviceSparseImageFormatProperties2KHR)load(context, "vkGetPhysicalDeviceSparseImageFormatProperties2KHR");
+#endif /* defined(VK_KHR_get_physical_device_properties2) */
+#if defined(VK_KHR_get_surface_capabilities2)
+ vkGetPhysicalDeviceSurfaceCapabilities2KHR = (PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR)load(context, "vkGetPhysicalDeviceSurfaceCapabilities2KHR");
+ vkGetPhysicalDeviceSurfaceFormats2KHR = (PFN_vkGetPhysicalDeviceSurfaceFormats2KHR)load(context, "vkGetPhysicalDeviceSurfaceFormats2KHR");
+#endif /* defined(VK_KHR_get_surface_capabilities2) */
+#if defined(VK_KHR_performance_query)
+ vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR = (PFN_vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR)load(context, "vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR");
+ vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR = (PFN_vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR)load(context, "vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR");
+#endif /* defined(VK_KHR_performance_query) */
+#if defined(VK_KHR_surface)
+ vkDestroySurfaceKHR = (PFN_vkDestroySurfaceKHR)load(context, "vkDestroySurfaceKHR");
+ vkGetPhysicalDeviceSurfaceCapabilitiesKHR = (PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR)load(context, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR");
+ vkGetPhysicalDeviceSurfaceFormatsKHR = (PFN_vkGetPhysicalDeviceSurfaceFormatsKHR)load(context, "vkGetPhysicalDeviceSurfaceFormatsKHR");
+ vkGetPhysicalDeviceSurfacePresentModesKHR = (PFN_vkGetPhysicalDeviceSurfacePresentModesKHR)load(context, "vkGetPhysicalDeviceSurfacePresentModesKHR");
+ vkGetPhysicalDeviceSurfaceSupportKHR = (PFN_vkGetPhysicalDeviceSurfaceSupportKHR)load(context, "vkGetPhysicalDeviceSurfaceSupportKHR");
+#endif /* defined(VK_KHR_surface) */
+#if defined(VK_KHR_video_queue)
+ vkGetPhysicalDeviceVideoCapabilitiesKHR = (PFN_vkGetPhysicalDeviceVideoCapabilitiesKHR)load(context, "vkGetPhysicalDeviceVideoCapabilitiesKHR");
+ vkGetPhysicalDeviceVideoFormatPropertiesKHR = (PFN_vkGetPhysicalDeviceVideoFormatPropertiesKHR)load(context, "vkGetPhysicalDeviceVideoFormatPropertiesKHR");
+#endif /* defined(VK_KHR_video_queue) */
+#if defined(VK_KHR_wayland_surface)
+ vkCreateWaylandSurfaceKHR = (PFN_vkCreateWaylandSurfaceKHR)load(context, "vkCreateWaylandSurfaceKHR");
+ vkGetPhysicalDeviceWaylandPresentationSupportKHR = (PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)load(context, "vkGetPhysicalDeviceWaylandPresentationSupportKHR");
+#endif /* defined(VK_KHR_wayland_surface) */
+#if defined(VK_KHR_win32_surface)
+ vkCreateWin32SurfaceKHR = (PFN_vkCreateWin32SurfaceKHR)load(context, "vkCreateWin32SurfaceKHR");
+ vkGetPhysicalDeviceWin32PresentationSupportKHR = (PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)load(context, "vkGetPhysicalDeviceWin32PresentationSupportKHR");
+#endif /* defined(VK_KHR_win32_surface) */
+#if defined(VK_KHR_xcb_surface)
+ vkCreateXcbSurfaceKHR = (PFN_vkCreateXcbSurfaceKHR)load(context, "vkCreateXcbSurfaceKHR");
+ vkGetPhysicalDeviceXcbPresentationSupportKHR = (PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)load(context, "vkGetPhysicalDeviceXcbPresentationSupportKHR");
+#endif /* defined(VK_KHR_xcb_surface) */
+#if defined(VK_KHR_xlib_surface)
+ vkCreateXlibSurfaceKHR = (PFN_vkCreateXlibSurfaceKHR)load(context, "vkCreateXlibSurfaceKHR");
+ vkGetPhysicalDeviceXlibPresentationSupportKHR = (PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)load(context, "vkGetPhysicalDeviceXlibPresentationSupportKHR");
+#endif /* defined(VK_KHR_xlib_surface) */
+#if defined(VK_MVK_ios_surface)
+ vkCreateIOSSurfaceMVK = (PFN_vkCreateIOSSurfaceMVK)load(context, "vkCreateIOSSurfaceMVK");
+#endif /* defined(VK_MVK_ios_surface) */
+#if defined(VK_MVK_macos_surface)
+ vkCreateMacOSSurfaceMVK = (PFN_vkCreateMacOSSurfaceMVK)load(context, "vkCreateMacOSSurfaceMVK");
+#endif /* defined(VK_MVK_macos_surface) */
+#if defined(VK_NN_vi_surface)
+ vkCreateViSurfaceNN = (PFN_vkCreateViSurfaceNN)load(context, "vkCreateViSurfaceNN");
+#endif /* defined(VK_NN_vi_surface) */
+#if defined(VK_NV_acquire_winrt_display)
+ vkAcquireWinrtDisplayNV = (PFN_vkAcquireWinrtDisplayNV)load(context, "vkAcquireWinrtDisplayNV");
+ vkGetWinrtDisplayNV = (PFN_vkGetWinrtDisplayNV)load(context, "vkGetWinrtDisplayNV");
+#endif /* defined(VK_NV_acquire_winrt_display) */
+#if defined(VK_NV_cooperative_matrix)
+ vkGetPhysicalDeviceCooperativeMatrixPropertiesNV = (PFN_vkGetPhysicalDeviceCooperativeMatrixPropertiesNV)load(context, "vkGetPhysicalDeviceCooperativeMatrixPropertiesNV");
+#endif /* defined(VK_NV_cooperative_matrix) */
+#if defined(VK_NV_coverage_reduction_mode)
+ vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV = (PFN_vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV)load(context, "vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV");
+#endif /* defined(VK_NV_coverage_reduction_mode) */
+#if defined(VK_NV_external_memory_capabilities)
+ vkGetPhysicalDeviceExternalImageFormatPropertiesNV = (PFN_vkGetPhysicalDeviceExternalImageFormatPropertiesNV)load(context, "vkGetPhysicalDeviceExternalImageFormatPropertiesNV");
+#endif /* defined(VK_NV_external_memory_capabilities) */
+#if defined(VK_QNX_screen_surface)
+ vkCreateScreenSurfaceQNX = (PFN_vkCreateScreenSurfaceQNX)load(context, "vkCreateScreenSurfaceQNX");
+ vkGetPhysicalDeviceScreenPresentationSupportQNX = (PFN_vkGetPhysicalDeviceScreenPresentationSupportQNX)load(context, "vkGetPhysicalDeviceScreenPresentationSupportQNX");
+#endif /* defined(VK_QNX_screen_surface) */
+#if (defined(VK_KHR_device_group) && defined(VK_KHR_surface)) || (defined(VK_KHR_swapchain) && defined(VK_VERSION_1_1))
+ vkGetPhysicalDevicePresentRectanglesKHR = (PFN_vkGetPhysicalDevicePresentRectanglesKHR)load(context, "vkGetPhysicalDevicePresentRectanglesKHR");
+#endif /* (defined(VK_KHR_device_group) && defined(VK_KHR_surface)) || (defined(VK_KHR_swapchain) && defined(VK_VERSION_1_1)) */
+ /* VOLK_GENERATE_LOAD_INSTANCE */
+}
+
+static void volkGenLoadDevice(void* context, PFN_vkVoidFunction (*load)(void*, const char*))
+{
+ /* VOLK_GENERATE_LOAD_DEVICE */
+#if defined(VK_VERSION_1_0)
+ vkAllocateCommandBuffers = (PFN_vkAllocateCommandBuffers)load(context, "vkAllocateCommandBuffers");
+ vkAllocateDescriptorSets = (PFN_vkAllocateDescriptorSets)load(context, "vkAllocateDescriptorSets");
+ vkAllocateMemory = (PFN_vkAllocateMemory)load(context, "vkAllocateMemory");
+ vkBeginCommandBuffer = (PFN_vkBeginCommandBuffer)load(context, "vkBeginCommandBuffer");
+ vkBindBufferMemory = (PFN_vkBindBufferMemory)load(context, "vkBindBufferMemory");
+ vkBindImageMemory = (PFN_vkBindImageMemory)load(context, "vkBindImageMemory");
+ vkCmdBeginQuery = (PFN_vkCmdBeginQuery)load(context, "vkCmdBeginQuery");
+ vkCmdBeginRenderPass = (PFN_vkCmdBeginRenderPass)load(context, "vkCmdBeginRenderPass");
+ vkCmdBindDescriptorSets = (PFN_vkCmdBindDescriptorSets)load(context, "vkCmdBindDescriptorSets");
+ vkCmdBindIndexBuffer = (PFN_vkCmdBindIndexBuffer)load(context, "vkCmdBindIndexBuffer");
+ vkCmdBindPipeline = (PFN_vkCmdBindPipeline)load(context, "vkCmdBindPipeline");
+ vkCmdBindVertexBuffers = (PFN_vkCmdBindVertexBuffers)load(context, "vkCmdBindVertexBuffers");
+ vkCmdBlitImage = (PFN_vkCmdBlitImage)load(context, "vkCmdBlitImage");
+ vkCmdClearAttachments = (PFN_vkCmdClearAttachments)load(context, "vkCmdClearAttachments");
+ vkCmdClearColorImage = (PFN_vkCmdClearColorImage)load(context, "vkCmdClearColorImage");
+ vkCmdClearDepthStencilImage = (PFN_vkCmdClearDepthStencilImage)load(context, "vkCmdClearDepthStencilImage");
+ vkCmdCopyBuffer = (PFN_vkCmdCopyBuffer)load(context, "vkCmdCopyBuffer");
+ vkCmdCopyBufferToImage = (PFN_vkCmdCopyBufferToImage)load(context, "vkCmdCopyBufferToImage");
+ vkCmdCopyImage = (PFN_vkCmdCopyImage)load(context, "vkCmdCopyImage");
+ vkCmdCopyImageToBuffer = (PFN_vkCmdCopyImageToBuffer)load(context, "vkCmdCopyImageToBuffer");
+ vkCmdCopyQueryPoolResults = (PFN_vkCmdCopyQueryPoolResults)load(context, "vkCmdCopyQueryPoolResults");
+ vkCmdDispatch = (PFN_vkCmdDispatch)load(context, "vkCmdDispatch");
+ vkCmdDispatchIndirect = (PFN_vkCmdDispatchIndirect)load(context, "vkCmdDispatchIndirect");
+ vkCmdDraw = (PFN_vkCmdDraw)load(context, "vkCmdDraw");
+ vkCmdDrawIndexed = (PFN_vkCmdDrawIndexed)load(context, "vkCmdDrawIndexed");
+ vkCmdDrawIndexedIndirect = (PFN_vkCmdDrawIndexedIndirect)load(context, "vkCmdDrawIndexedIndirect");
+ vkCmdDrawIndirect = (PFN_vkCmdDrawIndirect)load(context, "vkCmdDrawIndirect");
+ vkCmdEndQuery = (PFN_vkCmdEndQuery)load(context, "vkCmdEndQuery");
+ vkCmdEndRenderPass = (PFN_vkCmdEndRenderPass)load(context, "vkCmdEndRenderPass");
+ vkCmdExecuteCommands = (PFN_vkCmdExecuteCommands)load(context, "vkCmdExecuteCommands");
+ vkCmdFillBuffer = (PFN_vkCmdFillBuffer)load(context, "vkCmdFillBuffer");
+ vkCmdNextSubpass = (PFN_vkCmdNextSubpass)load(context, "vkCmdNextSubpass");
+ vkCmdPipelineBarrier = (PFN_vkCmdPipelineBarrier)load(context, "vkCmdPipelineBarrier");
+ vkCmdPushConstants = (PFN_vkCmdPushConstants)load(context, "vkCmdPushConstants");
+ vkCmdResetEvent = (PFN_vkCmdResetEvent)load(context, "vkCmdResetEvent");
+ vkCmdResetQueryPool = (PFN_vkCmdResetQueryPool)load(context, "vkCmdResetQueryPool");
+ vkCmdResolveImage = (PFN_vkCmdResolveImage)load(context, "vkCmdResolveImage");
+ vkCmdSetBlendConstants = (PFN_vkCmdSetBlendConstants)load(context, "vkCmdSetBlendConstants");
+ vkCmdSetDepthBias = (PFN_vkCmdSetDepthBias)load(context, "vkCmdSetDepthBias");
+ vkCmdSetDepthBounds = (PFN_vkCmdSetDepthBounds)load(context, "vkCmdSetDepthBounds");
+ vkCmdSetEvent = (PFN_vkCmdSetEvent)load(context, "vkCmdSetEvent");
+ vkCmdSetLineWidth = (PFN_vkCmdSetLineWidth)load(context, "vkCmdSetLineWidth");
+ vkCmdSetScissor = (PFN_vkCmdSetScissor)load(context, "vkCmdSetScissor");
+ vkCmdSetStencilCompareMask = (PFN_vkCmdSetStencilCompareMask)load(context, "vkCmdSetStencilCompareMask");
+ vkCmdSetStencilReference = (PFN_vkCmdSetStencilReference)load(context, "vkCmdSetStencilReference");
+ vkCmdSetStencilWriteMask = (PFN_vkCmdSetStencilWriteMask)load(context, "vkCmdSetStencilWriteMask");
+ vkCmdSetViewport = (PFN_vkCmdSetViewport)load(context, "vkCmdSetViewport");
+ vkCmdUpdateBuffer = (PFN_vkCmdUpdateBuffer)load(context, "vkCmdUpdateBuffer");
+ vkCmdWaitEvents = (PFN_vkCmdWaitEvents)load(context, "vkCmdWaitEvents");
+ vkCmdWriteTimestamp = (PFN_vkCmdWriteTimestamp)load(context, "vkCmdWriteTimestamp");
+ vkCreateBuffer = (PFN_vkCreateBuffer)load(context, "vkCreateBuffer");
+ vkCreateBufferView = (PFN_vkCreateBufferView)load(context, "vkCreateBufferView");
+ vkCreateCommandPool = (PFN_vkCreateCommandPool)load(context, "vkCreateCommandPool");
+ vkCreateComputePipelines = (PFN_vkCreateComputePipelines)load(context, "vkCreateComputePipelines");
+ vkCreateDescriptorPool = (PFN_vkCreateDescriptorPool)load(context, "vkCreateDescriptorPool");
+ vkCreateDescriptorSetLayout = (PFN_vkCreateDescriptorSetLayout)load(context, "vkCreateDescriptorSetLayout");
+ vkCreateEvent = (PFN_vkCreateEvent)load(context, "vkCreateEvent");
+ vkCreateFence = (PFN_vkCreateFence)load(context, "vkCreateFence");
+ vkCreateFramebuffer = (PFN_vkCreateFramebuffer)load(context, "vkCreateFramebuffer");
+ vkCreateGraphicsPipelines = (PFN_vkCreateGraphicsPipelines)load(context, "vkCreateGraphicsPipelines");
+ vkCreateImage = (PFN_vkCreateImage)load(context, "vkCreateImage");
+ vkCreateImageView = (PFN_vkCreateImageView)load(context, "vkCreateImageView");
+ vkCreatePipelineCache = (PFN_vkCreatePipelineCache)load(context, "vkCreatePipelineCache");
+ vkCreatePipelineLayout = (PFN_vkCreatePipelineLayout)load(context, "vkCreatePipelineLayout");
+ vkCreateQueryPool = (PFN_vkCreateQueryPool)load(context, "vkCreateQueryPool");
+ vkCreateRenderPass = (PFN_vkCreateRenderPass)load(context, "vkCreateRenderPass");
+ vkCreateSampler = (PFN_vkCreateSampler)load(context, "vkCreateSampler");
+ vkCreateSemaphore = (PFN_vkCreateSemaphore)load(context, "vkCreateSemaphore");
+ vkCreateShaderModule = (PFN_vkCreateShaderModule)load(context, "vkCreateShaderModule");
+ vkDestroyBuffer = (PFN_vkDestroyBuffer)load(context, "vkDestroyBuffer");
+ vkDestroyBufferView = (PFN_vkDestroyBufferView)load(context, "vkDestroyBufferView");
+ vkDestroyCommandPool = (PFN_vkDestroyCommandPool)load(context, "vkDestroyCommandPool");
+ vkDestroyDescriptorPool = (PFN_vkDestroyDescriptorPool)load(context, "vkDestroyDescriptorPool");
+ vkDestroyDescriptorSetLayout = (PFN_vkDestroyDescriptorSetLayout)load(context, "vkDestroyDescriptorSetLayout");
+ vkDestroyDevice = (PFN_vkDestroyDevice)load(context, "vkDestroyDevice");
+ vkDestroyEvent = (PFN_vkDestroyEvent)load(context, "vkDestroyEvent");
+ vkDestroyFence = (PFN_vkDestroyFence)load(context, "vkDestroyFence");
+ vkDestroyFramebuffer = (PFN_vkDestroyFramebuffer)load(context, "vkDestroyFramebuffer");
+ vkDestroyImage = (PFN_vkDestroyImage)load(context, "vkDestroyImage");
+ vkDestroyImageView = (PFN_vkDestroyImageView)load(context, "vkDestroyImageView");
+ vkDestroyPipeline = (PFN_vkDestroyPipeline)load(context, "vkDestroyPipeline");
+ vkDestroyPipelineCache = (PFN_vkDestroyPipelineCache)load(context, "vkDestroyPipelineCache");
+ vkDestroyPipelineLayout = (PFN_vkDestroyPipelineLayout)load(context, "vkDestroyPipelineLayout");
+ vkDestroyQueryPool = (PFN_vkDestroyQueryPool)load(context, "vkDestroyQueryPool");
+ vkDestroyRenderPass = (PFN_vkDestroyRenderPass)load(context, "vkDestroyRenderPass");
+ vkDestroySampler = (PFN_vkDestroySampler)load(context, "vkDestroySampler");
+ vkDestroySemaphore = (PFN_vkDestroySemaphore)load(context, "vkDestroySemaphore");
+ vkDestroyShaderModule = (PFN_vkDestroyShaderModule)load(context, "vkDestroyShaderModule");
+ vkDeviceWaitIdle = (PFN_vkDeviceWaitIdle)load(context, "vkDeviceWaitIdle");
+ vkEndCommandBuffer = (PFN_vkEndCommandBuffer)load(context, "vkEndCommandBuffer");
+ vkFlushMappedMemoryRanges = (PFN_vkFlushMappedMemoryRanges)load(context, "vkFlushMappedMemoryRanges");
+ vkFreeCommandBuffers = (PFN_vkFreeCommandBuffers)load(context, "vkFreeCommandBuffers");
+ vkFreeDescriptorSets = (PFN_vkFreeDescriptorSets)load(context, "vkFreeDescriptorSets");
+ vkFreeMemory = (PFN_vkFreeMemory)load(context, "vkFreeMemory");
+ vkGetBufferMemoryRequirements = (PFN_vkGetBufferMemoryRequirements)load(context, "vkGetBufferMemoryRequirements");
+ vkGetDeviceMemoryCommitment = (PFN_vkGetDeviceMemoryCommitment)load(context, "vkGetDeviceMemoryCommitment");
+ vkGetDeviceQueue = (PFN_vkGetDeviceQueue)load(context, "vkGetDeviceQueue");
+ vkGetEventStatus = (PFN_vkGetEventStatus)load(context, "vkGetEventStatus");
+ vkGetFenceStatus = (PFN_vkGetFenceStatus)load(context, "vkGetFenceStatus");
+ vkGetImageMemoryRequirements = (PFN_vkGetImageMemoryRequirements)load(context, "vkGetImageMemoryRequirements");
+ vkGetImageSparseMemoryRequirements = (PFN_vkGetImageSparseMemoryRequirements)load(context, "vkGetImageSparseMemoryRequirements");
+ vkGetImageSubresourceLayout = (PFN_vkGetImageSubresourceLayout)load(context, "vkGetImageSubresourceLayout");
+ vkGetPipelineCacheData = (PFN_vkGetPipelineCacheData)load(context, "vkGetPipelineCacheData");
+ vkGetQueryPoolResults = (PFN_vkGetQueryPoolResults)load(context, "vkGetQueryPoolResults");
+ vkGetRenderAreaGranularity = (PFN_vkGetRenderAreaGranularity)load(context, "vkGetRenderAreaGranularity");
+ vkInvalidateMappedMemoryRanges = (PFN_vkInvalidateMappedMemoryRanges)load(context, "vkInvalidateMappedMemoryRanges");
+ vkMapMemory = (PFN_vkMapMemory)load(context, "vkMapMemory");
+ vkMergePipelineCaches = (PFN_vkMergePipelineCaches)load(context, "vkMergePipelineCaches");
+ vkQueueBindSparse = (PFN_vkQueueBindSparse)load(context, "vkQueueBindSparse");
+ vkQueueSubmit = (PFN_vkQueueSubmit)load(context, "vkQueueSubmit");
+ vkQueueWaitIdle = (PFN_vkQueueWaitIdle)load(context, "vkQueueWaitIdle");
+ vkResetCommandBuffer = (PFN_vkResetCommandBuffer)load(context, "vkResetCommandBuffer");
+ vkResetCommandPool = (PFN_vkResetCommandPool)load(context, "vkResetCommandPool");
+ vkResetDescriptorPool = (PFN_vkResetDescriptorPool)load(context, "vkResetDescriptorPool");
+ vkResetEvent = (PFN_vkResetEvent)load(context, "vkResetEvent");
+ vkResetFences = (PFN_vkResetFences)load(context, "vkResetFences");
+ vkSetEvent = (PFN_vkSetEvent)load(context, "vkSetEvent");
+ vkUnmapMemory = (PFN_vkUnmapMemory)load(context, "vkUnmapMemory");
+ vkUpdateDescriptorSets = (PFN_vkUpdateDescriptorSets)load(context, "vkUpdateDescriptorSets");
+ vkWaitForFences = (PFN_vkWaitForFences)load(context, "vkWaitForFences");
+#endif /* defined(VK_VERSION_1_0) */
+#if defined(VK_VERSION_1_1)
+ vkBindBufferMemory2 = (PFN_vkBindBufferMemory2)load(context, "vkBindBufferMemory2");
+ vkBindImageMemory2 = (PFN_vkBindImageMemory2)load(context, "vkBindImageMemory2");
+ vkCmdDispatchBase = (PFN_vkCmdDispatchBase)load(context, "vkCmdDispatchBase");
+ vkCmdSetDeviceMask = (PFN_vkCmdSetDeviceMask)load(context, "vkCmdSetDeviceMask");
+ vkCreateDescriptorUpdateTemplate = (PFN_vkCreateDescriptorUpdateTemplate)load(context, "vkCreateDescriptorUpdateTemplate");
+ vkCreateSamplerYcbcrConversion = (PFN_vkCreateSamplerYcbcrConversion)load(context, "vkCreateSamplerYcbcrConversion");
+ vkDestroyDescriptorUpdateTemplate = (PFN_vkDestroyDescriptorUpdateTemplate)load(context, "vkDestroyDescriptorUpdateTemplate");
+ vkDestroySamplerYcbcrConversion = (PFN_vkDestroySamplerYcbcrConversion)load(context, "vkDestroySamplerYcbcrConversion");
+ vkGetBufferMemoryRequirements2 = (PFN_vkGetBufferMemoryRequirements2)load(context, "vkGetBufferMemoryRequirements2");
+ vkGetDescriptorSetLayoutSupport = (PFN_vkGetDescriptorSetLayoutSupport)load(context, "vkGetDescriptorSetLayoutSupport");
+ vkGetDeviceGroupPeerMemoryFeatures = (PFN_vkGetDeviceGroupPeerMemoryFeatures)load(context, "vkGetDeviceGroupPeerMemoryFeatures");
+ vkGetDeviceQueue2 = (PFN_vkGetDeviceQueue2)load(context, "vkGetDeviceQueue2");
+ vkGetImageMemoryRequirements2 = (PFN_vkGetImageMemoryRequirements2)load(context, "vkGetImageMemoryRequirements2");
+ vkGetImageSparseMemoryRequirements2 = (PFN_vkGetImageSparseMemoryRequirements2)load(context, "vkGetImageSparseMemoryRequirements2");
+ vkTrimCommandPool = (PFN_vkTrimCommandPool)load(context, "vkTrimCommandPool");
+ vkUpdateDescriptorSetWithTemplate = (PFN_vkUpdateDescriptorSetWithTemplate)load(context, "vkUpdateDescriptorSetWithTemplate");
+#endif /* defined(VK_VERSION_1_1) */
+#if defined(VK_VERSION_1_2)
+ vkCmdBeginRenderPass2 = (PFN_vkCmdBeginRenderPass2)load(context, "vkCmdBeginRenderPass2");
+ vkCmdDrawIndexedIndirectCount = (PFN_vkCmdDrawIndexedIndirectCount)load(context, "vkCmdDrawIndexedIndirectCount");
+ vkCmdDrawIndirectCount = (PFN_vkCmdDrawIndirectCount)load(context, "vkCmdDrawIndirectCount");
+ vkCmdEndRenderPass2 = (PFN_vkCmdEndRenderPass2)load(context, "vkCmdEndRenderPass2");
+ vkCmdNextSubpass2 = (PFN_vkCmdNextSubpass2)load(context, "vkCmdNextSubpass2");
+ vkCreateRenderPass2 = (PFN_vkCreateRenderPass2)load(context, "vkCreateRenderPass2");
+ vkGetBufferDeviceAddress = (PFN_vkGetBufferDeviceAddress)load(context, "vkGetBufferDeviceAddress");
+ vkGetBufferOpaqueCaptureAddress = (PFN_vkGetBufferOpaqueCaptureAddress)load(context, "vkGetBufferOpaqueCaptureAddress");
+ vkGetDeviceMemoryOpaqueCaptureAddress = (PFN_vkGetDeviceMemoryOpaqueCaptureAddress)load(context, "vkGetDeviceMemoryOpaqueCaptureAddress");
+ vkGetSemaphoreCounterValue = (PFN_vkGetSemaphoreCounterValue)load(context, "vkGetSemaphoreCounterValue");
+ vkResetQueryPool = (PFN_vkResetQueryPool)load(context, "vkResetQueryPool");
+ vkSignalSemaphore = (PFN_vkSignalSemaphore)load(context, "vkSignalSemaphore");
+ vkWaitSemaphores = (PFN_vkWaitSemaphores)load(context, "vkWaitSemaphores");
+#endif /* defined(VK_VERSION_1_2) */
+#if defined(VK_VERSION_1_3)
+ vkCmdBeginRendering = (PFN_vkCmdBeginRendering)load(context, "vkCmdBeginRendering");
+ vkCmdBindVertexBuffers2 = (PFN_vkCmdBindVertexBuffers2)load(context, "vkCmdBindVertexBuffers2");
+ vkCmdBlitImage2 = (PFN_vkCmdBlitImage2)load(context, "vkCmdBlitImage2");
+ vkCmdCopyBuffer2 = (PFN_vkCmdCopyBuffer2)load(context, "vkCmdCopyBuffer2");
+ vkCmdCopyBufferToImage2 = (PFN_vkCmdCopyBufferToImage2)load(context, "vkCmdCopyBufferToImage2");
+ vkCmdCopyImage2 = (PFN_vkCmdCopyImage2)load(context, "vkCmdCopyImage2");
+ vkCmdCopyImageToBuffer2 = (PFN_vkCmdCopyImageToBuffer2)load(context, "vkCmdCopyImageToBuffer2");
+ vkCmdEndRendering = (PFN_vkCmdEndRendering)load(context, "vkCmdEndRendering");
+ vkCmdPipelineBarrier2 = (PFN_vkCmdPipelineBarrier2)load(context, "vkCmdPipelineBarrier2");
+ vkCmdResetEvent2 = (PFN_vkCmdResetEvent2)load(context, "vkCmdResetEvent2");
+ vkCmdResolveImage2 = (PFN_vkCmdResolveImage2)load(context, "vkCmdResolveImage2");
+ vkCmdSetCullMode = (PFN_vkCmdSetCullMode)load(context, "vkCmdSetCullMode");
+ vkCmdSetDepthBiasEnable = (PFN_vkCmdSetDepthBiasEnable)load(context, "vkCmdSetDepthBiasEnable");
+ vkCmdSetDepthBoundsTestEnable = (PFN_vkCmdSetDepthBoundsTestEnable)load(context, "vkCmdSetDepthBoundsTestEnable");
+ vkCmdSetDepthCompareOp = (PFN_vkCmdSetDepthCompareOp)load(context, "vkCmdSetDepthCompareOp");
+ vkCmdSetDepthTestEnable = (PFN_vkCmdSetDepthTestEnable)load(context, "vkCmdSetDepthTestEnable");
+ vkCmdSetDepthWriteEnable = (PFN_vkCmdSetDepthWriteEnable)load(context, "vkCmdSetDepthWriteEnable");
+ vkCmdSetEvent2 = (PFN_vkCmdSetEvent2)load(context, "vkCmdSetEvent2");
+ vkCmdSetFrontFace = (PFN_vkCmdSetFrontFace)load(context, "vkCmdSetFrontFace");
+ vkCmdSetPrimitiveRestartEnable = (PFN_vkCmdSetPrimitiveRestartEnable)load(context, "vkCmdSetPrimitiveRestartEnable");
+ vkCmdSetPrimitiveTopology = (PFN_vkCmdSetPrimitiveTopology)load(context, "vkCmdSetPrimitiveTopology");
+ vkCmdSetRasterizerDiscardEnable = (PFN_vkCmdSetRasterizerDiscardEnable)load(context, "vkCmdSetRasterizerDiscardEnable");
+ vkCmdSetScissorWithCount = (PFN_vkCmdSetScissorWithCount)load(context, "vkCmdSetScissorWithCount");
+ vkCmdSetStencilOp = (PFN_vkCmdSetStencilOp)load(context, "vkCmdSetStencilOp");
+ vkCmdSetStencilTestEnable = (PFN_vkCmdSetStencilTestEnable)load(context, "vkCmdSetStencilTestEnable");
+ vkCmdSetViewportWithCount = (PFN_vkCmdSetViewportWithCount)load(context, "vkCmdSetViewportWithCount");
+ vkCmdWaitEvents2 = (PFN_vkCmdWaitEvents2)load(context, "vkCmdWaitEvents2");
+ vkCmdWriteTimestamp2 = (PFN_vkCmdWriteTimestamp2)load(context, "vkCmdWriteTimestamp2");
+ vkCreatePrivateDataSlot = (PFN_vkCreatePrivateDataSlot)load(context, "vkCreatePrivateDataSlot");
+ vkDestroyPrivateDataSlot = (PFN_vkDestroyPrivateDataSlot)load(context, "vkDestroyPrivateDataSlot");
+ vkGetDeviceBufferMemoryRequirements = (PFN_vkGetDeviceBufferMemoryRequirements)load(context, "vkGetDeviceBufferMemoryRequirements");
+ vkGetDeviceImageMemoryRequirements = (PFN_vkGetDeviceImageMemoryRequirements)load(context, "vkGetDeviceImageMemoryRequirements");
+ vkGetDeviceImageSparseMemoryRequirements = (PFN_vkGetDeviceImageSparseMemoryRequirements)load(context, "vkGetDeviceImageSparseMemoryRequirements");
+ vkGetPrivateData = (PFN_vkGetPrivateData)load(context, "vkGetPrivateData");
+ vkQueueSubmit2 = (PFN_vkQueueSubmit2)load(context, "vkQueueSubmit2");
+ vkSetPrivateData = (PFN_vkSetPrivateData)load(context, "vkSetPrivateData");
+#endif /* defined(VK_VERSION_1_3) */
+#if defined(VK_AMD_buffer_marker)
+ vkCmdWriteBufferMarkerAMD = (PFN_vkCmdWriteBufferMarkerAMD)load(context, "vkCmdWriteBufferMarkerAMD");
+#endif /* defined(VK_AMD_buffer_marker) */
+#if defined(VK_AMD_display_native_hdr)
+ vkSetLocalDimmingAMD = (PFN_vkSetLocalDimmingAMD)load(context, "vkSetLocalDimmingAMD");
+#endif /* defined(VK_AMD_display_native_hdr) */
+#if defined(VK_AMD_draw_indirect_count)
+ vkCmdDrawIndexedIndirectCountAMD = (PFN_vkCmdDrawIndexedIndirectCountAMD)load(context, "vkCmdDrawIndexedIndirectCountAMD");
+ vkCmdDrawIndirectCountAMD = (PFN_vkCmdDrawIndirectCountAMD)load(context, "vkCmdDrawIndirectCountAMD");
+#endif /* defined(VK_AMD_draw_indirect_count) */
+#if defined(VK_AMD_shader_info)
+ vkGetShaderInfoAMD = (PFN_vkGetShaderInfoAMD)load(context, "vkGetShaderInfoAMD");
+#endif /* defined(VK_AMD_shader_info) */
+#if defined(VK_ANDROID_external_memory_android_hardware_buffer)
+ vkGetAndroidHardwareBufferPropertiesANDROID = (PFN_vkGetAndroidHardwareBufferPropertiesANDROID)load(context, "vkGetAndroidHardwareBufferPropertiesANDROID");
+ vkGetMemoryAndroidHardwareBufferANDROID = (PFN_vkGetMemoryAndroidHardwareBufferANDROID)load(context, "vkGetMemoryAndroidHardwareBufferANDROID");
+#endif /* defined(VK_ANDROID_external_memory_android_hardware_buffer) */
+#if defined(VK_EXT_buffer_device_address)
+ vkGetBufferDeviceAddressEXT = (PFN_vkGetBufferDeviceAddressEXT)load(context, "vkGetBufferDeviceAddressEXT");
+#endif /* defined(VK_EXT_buffer_device_address) */
+#if defined(VK_EXT_calibrated_timestamps)
+ vkGetCalibratedTimestampsEXT = (PFN_vkGetCalibratedTimestampsEXT)load(context, "vkGetCalibratedTimestampsEXT");
+#endif /* defined(VK_EXT_calibrated_timestamps) */
+#if defined(VK_EXT_color_write_enable)
+ vkCmdSetColorWriteEnableEXT = (PFN_vkCmdSetColorWriteEnableEXT)load(context, "vkCmdSetColorWriteEnableEXT");
+#endif /* defined(VK_EXT_color_write_enable) */
+#if defined(VK_EXT_conditional_rendering)
+ vkCmdBeginConditionalRenderingEXT = (PFN_vkCmdBeginConditionalRenderingEXT)load(context, "vkCmdBeginConditionalRenderingEXT");
+ vkCmdEndConditionalRenderingEXT = (PFN_vkCmdEndConditionalRenderingEXT)load(context, "vkCmdEndConditionalRenderingEXT");
+#endif /* defined(VK_EXT_conditional_rendering) */
+#if defined(VK_EXT_debug_marker)
+ vkCmdDebugMarkerBeginEXT = (PFN_vkCmdDebugMarkerBeginEXT)load(context, "vkCmdDebugMarkerBeginEXT");
+ vkCmdDebugMarkerEndEXT = (PFN_vkCmdDebugMarkerEndEXT)load(context, "vkCmdDebugMarkerEndEXT");
+ vkCmdDebugMarkerInsertEXT = (PFN_vkCmdDebugMarkerInsertEXT)load(context, "vkCmdDebugMarkerInsertEXT");
+ vkDebugMarkerSetObjectNameEXT = (PFN_vkDebugMarkerSetObjectNameEXT)load(context, "vkDebugMarkerSetObjectNameEXT");
+ vkDebugMarkerSetObjectTagEXT = (PFN_vkDebugMarkerSetObjectTagEXT)load(context, "vkDebugMarkerSetObjectTagEXT");
+#endif /* defined(VK_EXT_debug_marker) */
+#if defined(VK_EXT_discard_rectangles)
+ vkCmdSetDiscardRectangleEXT = (PFN_vkCmdSetDiscardRectangleEXT)load(context, "vkCmdSetDiscardRectangleEXT");
+#endif /* defined(VK_EXT_discard_rectangles) */
+#if defined(VK_EXT_display_control)
+ vkDisplayPowerControlEXT = (PFN_vkDisplayPowerControlEXT)load(context, "vkDisplayPowerControlEXT");
+ vkGetSwapchainCounterEXT = (PFN_vkGetSwapchainCounterEXT)load(context, "vkGetSwapchainCounterEXT");
+ vkRegisterDeviceEventEXT = (PFN_vkRegisterDeviceEventEXT)load(context, "vkRegisterDeviceEventEXT");
+ vkRegisterDisplayEventEXT = (PFN_vkRegisterDisplayEventEXT)load(context, "vkRegisterDisplayEventEXT");
+#endif /* defined(VK_EXT_display_control) */
+#if defined(VK_EXT_extended_dynamic_state)
+ vkCmdBindVertexBuffers2EXT = (PFN_vkCmdBindVertexBuffers2EXT)load(context, "vkCmdBindVertexBuffers2EXT");
+ vkCmdSetCullModeEXT = (PFN_vkCmdSetCullModeEXT)load(context, "vkCmdSetCullModeEXT");
+ vkCmdSetDepthBoundsTestEnableEXT = (PFN_vkCmdSetDepthBoundsTestEnableEXT)load(context, "vkCmdSetDepthBoundsTestEnableEXT");
+ vkCmdSetDepthCompareOpEXT = (PFN_vkCmdSetDepthCompareOpEXT)load(context, "vkCmdSetDepthCompareOpEXT");
+ vkCmdSetDepthTestEnableEXT = (PFN_vkCmdSetDepthTestEnableEXT)load(context, "vkCmdSetDepthTestEnableEXT");
+ vkCmdSetDepthWriteEnableEXT = (PFN_vkCmdSetDepthWriteEnableEXT)load(context, "vkCmdSetDepthWriteEnableEXT");
+ vkCmdSetFrontFaceEXT = (PFN_vkCmdSetFrontFaceEXT)load(context, "vkCmdSetFrontFaceEXT");
+ vkCmdSetPrimitiveTopologyEXT = (PFN_vkCmdSetPrimitiveTopologyEXT)load(context, "vkCmdSetPrimitiveTopologyEXT");
+ vkCmdSetScissorWithCountEXT = (PFN_vkCmdSetScissorWithCountEXT)load(context, "vkCmdSetScissorWithCountEXT");
+ vkCmdSetStencilOpEXT = (PFN_vkCmdSetStencilOpEXT)load(context, "vkCmdSetStencilOpEXT");
+ vkCmdSetStencilTestEnableEXT = (PFN_vkCmdSetStencilTestEnableEXT)load(context, "vkCmdSetStencilTestEnableEXT");
+ vkCmdSetViewportWithCountEXT = (PFN_vkCmdSetViewportWithCountEXT)load(context, "vkCmdSetViewportWithCountEXT");
+#endif /* defined(VK_EXT_extended_dynamic_state) */
+#if defined(VK_EXT_extended_dynamic_state2)
+ vkCmdSetDepthBiasEnableEXT = (PFN_vkCmdSetDepthBiasEnableEXT)load(context, "vkCmdSetDepthBiasEnableEXT");
+ vkCmdSetLogicOpEXT = (PFN_vkCmdSetLogicOpEXT)load(context, "vkCmdSetLogicOpEXT");
+ vkCmdSetPatchControlPointsEXT = (PFN_vkCmdSetPatchControlPointsEXT)load(context, "vkCmdSetPatchControlPointsEXT");
+ vkCmdSetPrimitiveRestartEnableEXT = (PFN_vkCmdSetPrimitiveRestartEnableEXT)load(context, "vkCmdSetPrimitiveRestartEnableEXT");
+ vkCmdSetRasterizerDiscardEnableEXT = (PFN_vkCmdSetRasterizerDiscardEnableEXT)load(context, "vkCmdSetRasterizerDiscardEnableEXT");
+#endif /* defined(VK_EXT_extended_dynamic_state2) */
+#if defined(VK_EXT_external_memory_host)
+ vkGetMemoryHostPointerPropertiesEXT = (PFN_vkGetMemoryHostPointerPropertiesEXT)load(context, "vkGetMemoryHostPointerPropertiesEXT");
+#endif /* defined(VK_EXT_external_memory_host) */
+#if defined(VK_EXT_full_screen_exclusive)
+ vkAcquireFullScreenExclusiveModeEXT = (PFN_vkAcquireFullScreenExclusiveModeEXT)load(context, "vkAcquireFullScreenExclusiveModeEXT");
+ vkReleaseFullScreenExclusiveModeEXT = (PFN_vkReleaseFullScreenExclusiveModeEXT)load(context, "vkReleaseFullScreenExclusiveModeEXT");
+#endif /* defined(VK_EXT_full_screen_exclusive) */
+#if defined(VK_EXT_hdr_metadata)
+ vkSetHdrMetadataEXT = (PFN_vkSetHdrMetadataEXT)load(context, "vkSetHdrMetadataEXT");
+#endif /* defined(VK_EXT_hdr_metadata) */
+#if defined(VK_EXT_host_query_reset)
+ vkResetQueryPoolEXT = (PFN_vkResetQueryPoolEXT)load(context, "vkResetQueryPoolEXT");
+#endif /* defined(VK_EXT_host_query_reset) */
+#if defined(VK_EXT_image_drm_format_modifier)
+ vkGetImageDrmFormatModifierPropertiesEXT = (PFN_vkGetImageDrmFormatModifierPropertiesEXT)load(context, "vkGetImageDrmFormatModifierPropertiesEXT");
+#endif /* defined(VK_EXT_image_drm_format_modifier) */
+#if defined(VK_EXT_line_rasterization)
+ vkCmdSetLineStippleEXT = (PFN_vkCmdSetLineStippleEXT)load(context, "vkCmdSetLineStippleEXT");
+#endif /* defined(VK_EXT_line_rasterization) */
+#if defined(VK_EXT_multi_draw)
+ vkCmdDrawMultiEXT = (PFN_vkCmdDrawMultiEXT)load(context, "vkCmdDrawMultiEXT");
+ vkCmdDrawMultiIndexedEXT = (PFN_vkCmdDrawMultiIndexedEXT)load(context, "vkCmdDrawMultiIndexedEXT");
+#endif /* defined(VK_EXT_multi_draw) */
+#if defined(VK_EXT_pageable_device_local_memory)
+ vkSetDeviceMemoryPriorityEXT = (PFN_vkSetDeviceMemoryPriorityEXT)load(context, "vkSetDeviceMemoryPriorityEXT");
+#endif /* defined(VK_EXT_pageable_device_local_memory) */
+#if defined(VK_EXT_private_data)
+ vkCreatePrivateDataSlotEXT = (PFN_vkCreatePrivateDataSlotEXT)load(context, "vkCreatePrivateDataSlotEXT");
+ vkDestroyPrivateDataSlotEXT = (PFN_vkDestroyPrivateDataSlotEXT)load(context, "vkDestroyPrivateDataSlotEXT");
+ vkGetPrivateDataEXT = (PFN_vkGetPrivateDataEXT)load(context, "vkGetPrivateDataEXT");
+ vkSetPrivateDataEXT = (PFN_vkSetPrivateDataEXT)load(context, "vkSetPrivateDataEXT");
+#endif /* defined(VK_EXT_private_data) */
+#if defined(VK_EXT_sample_locations)
+ vkCmdSetSampleLocationsEXT = (PFN_vkCmdSetSampleLocationsEXT)load(context, "vkCmdSetSampleLocationsEXT");
+#endif /* defined(VK_EXT_sample_locations) */
+#if defined(VK_EXT_transform_feedback)
+ vkCmdBeginQueryIndexedEXT = (PFN_vkCmdBeginQueryIndexedEXT)load(context, "vkCmdBeginQueryIndexedEXT");
+ vkCmdBeginTransformFeedbackEXT = (PFN_vkCmdBeginTransformFeedbackEXT)load(context, "vkCmdBeginTransformFeedbackEXT");
+ vkCmdBindTransformFeedbackBuffersEXT = (PFN_vkCmdBindTransformFeedbackBuffersEXT)load(context, "vkCmdBindTransformFeedbackBuffersEXT");
+ vkCmdDrawIndirectByteCountEXT = (PFN_vkCmdDrawIndirectByteCountEXT)load(context, "vkCmdDrawIndirectByteCountEXT");
+ vkCmdEndQueryIndexedEXT = (PFN_vkCmdEndQueryIndexedEXT)load(context, "vkCmdEndQueryIndexedEXT");
+ vkCmdEndTransformFeedbackEXT = (PFN_vkCmdEndTransformFeedbackEXT)load(context, "vkCmdEndTransformFeedbackEXT");
+#endif /* defined(VK_EXT_transform_feedback) */
+#if defined(VK_EXT_validation_cache)
+ vkCreateValidationCacheEXT = (PFN_vkCreateValidationCacheEXT)load(context, "vkCreateValidationCacheEXT");
+ vkDestroyValidationCacheEXT = (PFN_vkDestroyValidationCacheEXT)load(context, "vkDestroyValidationCacheEXT");
+ vkGetValidationCacheDataEXT = (PFN_vkGetValidationCacheDataEXT)load(context, "vkGetValidationCacheDataEXT");
+ vkMergeValidationCachesEXT = (PFN_vkMergeValidationCachesEXT)load(context, "vkMergeValidationCachesEXT");
+#endif /* defined(VK_EXT_validation_cache) */
+#if defined(VK_EXT_vertex_input_dynamic_state)
+ vkCmdSetVertexInputEXT = (PFN_vkCmdSetVertexInputEXT)load(context, "vkCmdSetVertexInputEXT");
+#endif /* defined(VK_EXT_vertex_input_dynamic_state) */
+#if defined(VK_FUCHSIA_buffer_collection)
+ vkCreateBufferCollectionFUCHSIA = (PFN_vkCreateBufferCollectionFUCHSIA)load(context, "vkCreateBufferCollectionFUCHSIA");
+ vkDestroyBufferCollectionFUCHSIA = (PFN_vkDestroyBufferCollectionFUCHSIA)load(context, "vkDestroyBufferCollectionFUCHSIA");
+ vkGetBufferCollectionPropertiesFUCHSIA = (PFN_vkGetBufferCollectionPropertiesFUCHSIA)load(context, "vkGetBufferCollectionPropertiesFUCHSIA");
+ vkSetBufferCollectionBufferConstraintsFUCHSIA = (PFN_vkSetBufferCollectionBufferConstraintsFUCHSIA)load(context, "vkSetBufferCollectionBufferConstraintsFUCHSIA");
+ vkSetBufferCollectionImageConstraintsFUCHSIA = (PFN_vkSetBufferCollectionImageConstraintsFUCHSIA)load(context, "vkSetBufferCollectionImageConstraintsFUCHSIA");
+#endif /* defined(VK_FUCHSIA_buffer_collection) */
+#if defined(VK_FUCHSIA_external_memory)
+ vkGetMemoryZirconHandleFUCHSIA = (PFN_vkGetMemoryZirconHandleFUCHSIA)load(context, "vkGetMemoryZirconHandleFUCHSIA");
+ vkGetMemoryZirconHandlePropertiesFUCHSIA = (PFN_vkGetMemoryZirconHandlePropertiesFUCHSIA)load(context, "vkGetMemoryZirconHandlePropertiesFUCHSIA");
+#endif /* defined(VK_FUCHSIA_external_memory) */
+#if defined(VK_FUCHSIA_external_semaphore)
+ vkGetSemaphoreZirconHandleFUCHSIA = (PFN_vkGetSemaphoreZirconHandleFUCHSIA)load(context, "vkGetSemaphoreZirconHandleFUCHSIA");
+ vkImportSemaphoreZirconHandleFUCHSIA = (PFN_vkImportSemaphoreZirconHandleFUCHSIA)load(context, "vkImportSemaphoreZirconHandleFUCHSIA");
+#endif /* defined(VK_FUCHSIA_external_semaphore) */
+#if defined(VK_GOOGLE_display_timing)
+ vkGetPastPresentationTimingGOOGLE = (PFN_vkGetPastPresentationTimingGOOGLE)load(context, "vkGetPastPresentationTimingGOOGLE");
+ vkGetRefreshCycleDurationGOOGLE = (PFN_vkGetRefreshCycleDurationGOOGLE)load(context, "vkGetRefreshCycleDurationGOOGLE");
+#endif /* defined(VK_GOOGLE_display_timing) */
+#if defined(VK_HUAWEI_invocation_mask)
+ vkCmdBindInvocationMaskHUAWEI = (PFN_vkCmdBindInvocationMaskHUAWEI)load(context, "vkCmdBindInvocationMaskHUAWEI");
+#endif /* defined(VK_HUAWEI_invocation_mask) */
+#if defined(VK_HUAWEI_subpass_shading)
+ vkCmdSubpassShadingHUAWEI = (PFN_vkCmdSubpassShadingHUAWEI)load(context, "vkCmdSubpassShadingHUAWEI");
+ vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI = (PFN_vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI)load(context, "vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI");
+#endif /* defined(VK_HUAWEI_subpass_shading) */
+#if defined(VK_INTEL_performance_query)
+ vkAcquirePerformanceConfigurationINTEL = (PFN_vkAcquirePerformanceConfigurationINTEL)load(context, "vkAcquirePerformanceConfigurationINTEL");
+ vkCmdSetPerformanceMarkerINTEL = (PFN_vkCmdSetPerformanceMarkerINTEL)load(context, "vkCmdSetPerformanceMarkerINTEL");
+ vkCmdSetPerformanceOverrideINTEL = (PFN_vkCmdSetPerformanceOverrideINTEL)load(context, "vkCmdSetPerformanceOverrideINTEL");
+ vkCmdSetPerformanceStreamMarkerINTEL = (PFN_vkCmdSetPerformanceStreamMarkerINTEL)load(context, "vkCmdSetPerformanceStreamMarkerINTEL");
+ vkGetPerformanceParameterINTEL = (PFN_vkGetPerformanceParameterINTEL)load(context, "vkGetPerformanceParameterINTEL");
+ vkInitializePerformanceApiINTEL = (PFN_vkInitializePerformanceApiINTEL)load(context, "vkInitializePerformanceApiINTEL");
+ vkQueueSetPerformanceConfigurationINTEL = (PFN_vkQueueSetPerformanceConfigurationINTEL)load(context, "vkQueueSetPerformanceConfigurationINTEL");
+ vkReleasePerformanceConfigurationINTEL = (PFN_vkReleasePerformanceConfigurationINTEL)load(context, "vkReleasePerformanceConfigurationINTEL");
+ vkUninitializePerformanceApiINTEL = (PFN_vkUninitializePerformanceApiINTEL)load(context, "vkUninitializePerformanceApiINTEL");
+#endif /* defined(VK_INTEL_performance_query) */
+#if defined(VK_KHR_acceleration_structure)
+ vkBuildAccelerationStructuresKHR = (PFN_vkBuildAccelerationStructuresKHR)load(context, "vkBuildAccelerationStructuresKHR");
+ vkCmdBuildAccelerationStructuresIndirectKHR = (PFN_vkCmdBuildAccelerationStructuresIndirectKHR)load(context, "vkCmdBuildAccelerationStructuresIndirectKHR");
+ vkCmdBuildAccelerationStructuresKHR = (PFN_vkCmdBuildAccelerationStructuresKHR)load(context, "vkCmdBuildAccelerationStructuresKHR");
+ vkCmdCopyAccelerationStructureKHR = (PFN_vkCmdCopyAccelerationStructureKHR)load(context, "vkCmdCopyAccelerationStructureKHR");
+ vkCmdCopyAccelerationStructureToMemoryKHR = (PFN_vkCmdCopyAccelerationStructureToMemoryKHR)load(context, "vkCmdCopyAccelerationStructureToMemoryKHR");
+ vkCmdCopyMemoryToAccelerationStructureKHR = (PFN_vkCmdCopyMemoryToAccelerationStructureKHR)load(context, "vkCmdCopyMemoryToAccelerationStructureKHR");
+ vkCmdWriteAccelerationStructuresPropertiesKHR = (PFN_vkCmdWriteAccelerationStructuresPropertiesKHR)load(context, "vkCmdWriteAccelerationStructuresPropertiesKHR");
+ vkCopyAccelerationStructureKHR = (PFN_vkCopyAccelerationStructureKHR)load(context, "vkCopyAccelerationStructureKHR");
+ vkCopyAccelerationStructureToMemoryKHR = (PFN_vkCopyAccelerationStructureToMemoryKHR)load(context, "vkCopyAccelerationStructureToMemoryKHR");
+ vkCopyMemoryToAccelerationStructureKHR = (PFN_vkCopyMemoryToAccelerationStructureKHR)load(context, "vkCopyMemoryToAccelerationStructureKHR");
+ vkCreateAccelerationStructureKHR = (PFN_vkCreateAccelerationStructureKHR)load(context, "vkCreateAccelerationStructureKHR");
+ vkDestroyAccelerationStructureKHR = (PFN_vkDestroyAccelerationStructureKHR)load(context, "vkDestroyAccelerationStructureKHR");
+ vkGetAccelerationStructureBuildSizesKHR = (PFN_vkGetAccelerationStructureBuildSizesKHR)load(context, "vkGetAccelerationStructureBuildSizesKHR");
+ vkGetAccelerationStructureDeviceAddressKHR = (PFN_vkGetAccelerationStructureDeviceAddressKHR)load(context, "vkGetAccelerationStructureDeviceAddressKHR");
+ vkGetDeviceAccelerationStructureCompatibilityKHR = (PFN_vkGetDeviceAccelerationStructureCompatibilityKHR)load(context, "vkGetDeviceAccelerationStructureCompatibilityKHR");
+ vkWriteAccelerationStructuresPropertiesKHR = (PFN_vkWriteAccelerationStructuresPropertiesKHR)load(context, "vkWriteAccelerationStructuresPropertiesKHR");
+#endif /* defined(VK_KHR_acceleration_structure) */
+#if defined(VK_KHR_bind_memory2)
+ vkBindBufferMemory2KHR = (PFN_vkBindBufferMemory2KHR)load(context, "vkBindBufferMemory2KHR");
+ vkBindImageMemory2KHR = (PFN_vkBindImageMemory2KHR)load(context, "vkBindImageMemory2KHR");
+#endif /* defined(VK_KHR_bind_memory2) */
+#if defined(VK_KHR_buffer_device_address)
+ vkGetBufferDeviceAddressKHR = (PFN_vkGetBufferDeviceAddressKHR)load(context, "vkGetBufferDeviceAddressKHR");
+ vkGetBufferOpaqueCaptureAddressKHR = (PFN_vkGetBufferOpaqueCaptureAddressKHR)load(context, "vkGetBufferOpaqueCaptureAddressKHR");
+ vkGetDeviceMemoryOpaqueCaptureAddressKHR = (PFN_vkGetDeviceMemoryOpaqueCaptureAddressKHR)load(context, "vkGetDeviceMemoryOpaqueCaptureAddressKHR");
+#endif /* defined(VK_KHR_buffer_device_address) */
+#if defined(VK_KHR_copy_commands2)
+ vkCmdBlitImage2KHR = (PFN_vkCmdBlitImage2KHR)load(context, "vkCmdBlitImage2KHR");
+ vkCmdCopyBuffer2KHR = (PFN_vkCmdCopyBuffer2KHR)load(context, "vkCmdCopyBuffer2KHR");
+ vkCmdCopyBufferToImage2KHR = (PFN_vkCmdCopyBufferToImage2KHR)load(context, "vkCmdCopyBufferToImage2KHR");
+ vkCmdCopyImage2KHR = (PFN_vkCmdCopyImage2KHR)load(context, "vkCmdCopyImage2KHR");
+ vkCmdCopyImageToBuffer2KHR = (PFN_vkCmdCopyImageToBuffer2KHR)load(context, "vkCmdCopyImageToBuffer2KHR");
+ vkCmdResolveImage2KHR = (PFN_vkCmdResolveImage2KHR)load(context, "vkCmdResolveImage2KHR");
+#endif /* defined(VK_KHR_copy_commands2) */
+#if defined(VK_KHR_create_renderpass2)
+ vkCmdBeginRenderPass2KHR = (PFN_vkCmdBeginRenderPass2KHR)load(context, "vkCmdBeginRenderPass2KHR");
+ vkCmdEndRenderPass2KHR = (PFN_vkCmdEndRenderPass2KHR)load(context, "vkCmdEndRenderPass2KHR");
+ vkCmdNextSubpass2KHR = (PFN_vkCmdNextSubpass2KHR)load(context, "vkCmdNextSubpass2KHR");
+ vkCreateRenderPass2KHR = (PFN_vkCreateRenderPass2KHR)load(context, "vkCreateRenderPass2KHR");
+#endif /* defined(VK_KHR_create_renderpass2) */
+#if defined(VK_KHR_deferred_host_operations)
+ vkCreateDeferredOperationKHR = (PFN_vkCreateDeferredOperationKHR)load(context, "vkCreateDeferredOperationKHR");
+ vkDeferredOperationJoinKHR = (PFN_vkDeferredOperationJoinKHR)load(context, "vkDeferredOperationJoinKHR");
+ vkDestroyDeferredOperationKHR = (PFN_vkDestroyDeferredOperationKHR)load(context, "vkDestroyDeferredOperationKHR");
+ vkGetDeferredOperationMaxConcurrencyKHR = (PFN_vkGetDeferredOperationMaxConcurrencyKHR)load(context, "vkGetDeferredOperationMaxConcurrencyKHR");
+ vkGetDeferredOperationResultKHR = (PFN_vkGetDeferredOperationResultKHR)load(context, "vkGetDeferredOperationResultKHR");
+#endif /* defined(VK_KHR_deferred_host_operations) */
+#if defined(VK_KHR_descriptor_update_template)
+ vkCreateDescriptorUpdateTemplateKHR = (PFN_vkCreateDescriptorUpdateTemplateKHR)load(context, "vkCreateDescriptorUpdateTemplateKHR");
+ vkDestroyDescriptorUpdateTemplateKHR = (PFN_vkDestroyDescriptorUpdateTemplateKHR)load(context, "vkDestroyDescriptorUpdateTemplateKHR");
+ vkUpdateDescriptorSetWithTemplateKHR = (PFN_vkUpdateDescriptorSetWithTemplateKHR)load(context, "vkUpdateDescriptorSetWithTemplateKHR");
+#endif /* defined(VK_KHR_descriptor_update_template) */
+#if defined(VK_KHR_device_group)
+ vkCmdDispatchBaseKHR = (PFN_vkCmdDispatchBaseKHR)load(context, "vkCmdDispatchBaseKHR");
+ vkCmdSetDeviceMaskKHR = (PFN_vkCmdSetDeviceMaskKHR)load(context, "vkCmdSetDeviceMaskKHR");
+ vkGetDeviceGroupPeerMemoryFeaturesKHR = (PFN_vkGetDeviceGroupPeerMemoryFeaturesKHR)load(context, "vkGetDeviceGroupPeerMemoryFeaturesKHR");
+#endif /* defined(VK_KHR_device_group) */
+#if defined(VK_KHR_display_swapchain)
+ vkCreateSharedSwapchainsKHR = (PFN_vkCreateSharedSwapchainsKHR)load(context, "vkCreateSharedSwapchainsKHR");
+#endif /* defined(VK_KHR_display_swapchain) */
+#if defined(VK_KHR_draw_indirect_count)
+ vkCmdDrawIndexedIndirectCountKHR = (PFN_vkCmdDrawIndexedIndirectCountKHR)load(context, "vkCmdDrawIndexedIndirectCountKHR");
+ vkCmdDrawIndirectCountKHR = (PFN_vkCmdDrawIndirectCountKHR)load(context, "vkCmdDrawIndirectCountKHR");
+#endif /* defined(VK_KHR_draw_indirect_count) */
+#if defined(VK_KHR_dynamic_rendering)
+ vkCmdBeginRenderingKHR = (PFN_vkCmdBeginRenderingKHR)load(context, "vkCmdBeginRenderingKHR");
+ vkCmdEndRenderingKHR = (PFN_vkCmdEndRenderingKHR)load(context, "vkCmdEndRenderingKHR");
+#endif /* defined(VK_KHR_dynamic_rendering) */
+#if defined(VK_KHR_external_fence_fd)
+ vkGetFenceFdKHR = (PFN_vkGetFenceFdKHR)load(context, "vkGetFenceFdKHR");
+ vkImportFenceFdKHR = (PFN_vkImportFenceFdKHR)load(context, "vkImportFenceFdKHR");
+#endif /* defined(VK_KHR_external_fence_fd) */
+#if defined(VK_KHR_external_fence_win32)
+ vkGetFenceWin32HandleKHR = (PFN_vkGetFenceWin32HandleKHR)load(context, "vkGetFenceWin32HandleKHR");
+ vkImportFenceWin32HandleKHR = (PFN_vkImportFenceWin32HandleKHR)load(context, "vkImportFenceWin32HandleKHR");
+#endif /* defined(VK_KHR_external_fence_win32) */
+#if defined(VK_KHR_external_memory_fd)
+ vkGetMemoryFdKHR = (PFN_vkGetMemoryFdKHR)load(context, "vkGetMemoryFdKHR");
+ vkGetMemoryFdPropertiesKHR = (PFN_vkGetMemoryFdPropertiesKHR)load(context, "vkGetMemoryFdPropertiesKHR");
+#endif /* defined(VK_KHR_external_memory_fd) */
+#if defined(VK_KHR_external_memory_win32)
+ vkGetMemoryWin32HandleKHR = (PFN_vkGetMemoryWin32HandleKHR)load(context, "vkGetMemoryWin32HandleKHR");
+ vkGetMemoryWin32HandlePropertiesKHR = (PFN_vkGetMemoryWin32HandlePropertiesKHR)load(context, "vkGetMemoryWin32HandlePropertiesKHR");
+#endif /* defined(VK_KHR_external_memory_win32) */
+#if defined(VK_KHR_external_semaphore_fd)
+ vkGetSemaphoreFdKHR = (PFN_vkGetSemaphoreFdKHR)load(context, "vkGetSemaphoreFdKHR");
+ vkImportSemaphoreFdKHR = (PFN_vkImportSemaphoreFdKHR)load(context, "vkImportSemaphoreFdKHR");
+#endif /* defined(VK_KHR_external_semaphore_fd) */
+#if defined(VK_KHR_external_semaphore_win32)
+ vkGetSemaphoreWin32HandleKHR = (PFN_vkGetSemaphoreWin32HandleKHR)load(context, "vkGetSemaphoreWin32HandleKHR");
+ vkImportSemaphoreWin32HandleKHR = (PFN_vkImportSemaphoreWin32HandleKHR)load(context, "vkImportSemaphoreWin32HandleKHR");
+#endif /* defined(VK_KHR_external_semaphore_win32) */
+#if defined(VK_KHR_fragment_shading_rate)
+ vkCmdSetFragmentShadingRateKHR = (PFN_vkCmdSetFragmentShadingRateKHR)load(context, "vkCmdSetFragmentShadingRateKHR");
+#endif /* defined(VK_KHR_fragment_shading_rate) */
+#if defined(VK_KHR_get_memory_requirements2)
+ vkGetBufferMemoryRequirements2KHR = (PFN_vkGetBufferMemoryRequirements2KHR)load(context, "vkGetBufferMemoryRequirements2KHR");
+ vkGetImageMemoryRequirements2KHR = (PFN_vkGetImageMemoryRequirements2KHR)load(context, "vkGetImageMemoryRequirements2KHR");
+ vkGetImageSparseMemoryRequirements2KHR = (PFN_vkGetImageSparseMemoryRequirements2KHR)load(context, "vkGetImageSparseMemoryRequirements2KHR");
+#endif /* defined(VK_KHR_get_memory_requirements2) */
+#if defined(VK_KHR_maintenance1)
+ vkTrimCommandPoolKHR = (PFN_vkTrimCommandPoolKHR)load(context, "vkTrimCommandPoolKHR");
+#endif /* defined(VK_KHR_maintenance1) */
+#if defined(VK_KHR_maintenance3)
+ vkGetDescriptorSetLayoutSupportKHR = (PFN_vkGetDescriptorSetLayoutSupportKHR)load(context, "vkGetDescriptorSetLayoutSupportKHR");
+#endif /* defined(VK_KHR_maintenance3) */
+#if defined(VK_KHR_maintenance4)
+ vkGetDeviceBufferMemoryRequirementsKHR = (PFN_vkGetDeviceBufferMemoryRequirementsKHR)load(context, "vkGetDeviceBufferMemoryRequirementsKHR");
+ vkGetDeviceImageMemoryRequirementsKHR = (PFN_vkGetDeviceImageMemoryRequirementsKHR)load(context, "vkGetDeviceImageMemoryRequirementsKHR");
+ vkGetDeviceImageSparseMemoryRequirementsKHR = (PFN_vkGetDeviceImageSparseMemoryRequirementsKHR)load(context, "vkGetDeviceImageSparseMemoryRequirementsKHR");
+#endif /* defined(VK_KHR_maintenance4) */
+#if defined(VK_KHR_performance_query)
+ vkAcquireProfilingLockKHR = (PFN_vkAcquireProfilingLockKHR)load(context, "vkAcquireProfilingLockKHR");
+ vkReleaseProfilingLockKHR = (PFN_vkReleaseProfilingLockKHR)load(context, "vkReleaseProfilingLockKHR");
+#endif /* defined(VK_KHR_performance_query) */
+#if defined(VK_KHR_pipeline_executable_properties)
+ vkGetPipelineExecutableInternalRepresentationsKHR = (PFN_vkGetPipelineExecutableInternalRepresentationsKHR)load(context, "vkGetPipelineExecutableInternalRepresentationsKHR");
+ vkGetPipelineExecutablePropertiesKHR = (PFN_vkGetPipelineExecutablePropertiesKHR)load(context, "vkGetPipelineExecutablePropertiesKHR");
+ vkGetPipelineExecutableStatisticsKHR = (PFN_vkGetPipelineExecutableStatisticsKHR)load(context, "vkGetPipelineExecutableStatisticsKHR");
+#endif /* defined(VK_KHR_pipeline_executable_properties) */
+#if defined(VK_KHR_present_wait)
+ vkWaitForPresentKHR = (PFN_vkWaitForPresentKHR)load(context, "vkWaitForPresentKHR");
+#endif /* defined(VK_KHR_present_wait) */
+#if defined(VK_KHR_push_descriptor)
+ vkCmdPushDescriptorSetKHR = (PFN_vkCmdPushDescriptorSetKHR)load(context, "vkCmdPushDescriptorSetKHR");
+#endif /* defined(VK_KHR_push_descriptor) */
+#if defined(VK_KHR_ray_tracing_pipeline)
+ vkCmdSetRayTracingPipelineStackSizeKHR = (PFN_vkCmdSetRayTracingPipelineStackSizeKHR)load(context, "vkCmdSetRayTracingPipelineStackSizeKHR");
+ vkCmdTraceRaysIndirectKHR = (PFN_vkCmdTraceRaysIndirectKHR)load(context, "vkCmdTraceRaysIndirectKHR");
+ vkCmdTraceRaysKHR = (PFN_vkCmdTraceRaysKHR)load(context, "vkCmdTraceRaysKHR");
+ vkCreateRayTracingPipelinesKHR = (PFN_vkCreateRayTracingPipelinesKHR)load(context, "vkCreateRayTracingPipelinesKHR");
+ vkGetRayTracingCaptureReplayShaderGroupHandlesKHR = (PFN_vkGetRayTracingCaptureReplayShaderGroupHandlesKHR)load(context, "vkGetRayTracingCaptureReplayShaderGroupHandlesKHR");
+ vkGetRayTracingShaderGroupHandlesKHR = (PFN_vkGetRayTracingShaderGroupHandlesKHR)load(context, "vkGetRayTracingShaderGroupHandlesKHR");
+ vkGetRayTracingShaderGroupStackSizeKHR = (PFN_vkGetRayTracingShaderGroupStackSizeKHR)load(context, "vkGetRayTracingShaderGroupStackSizeKHR");
+#endif /* defined(VK_KHR_ray_tracing_pipeline) */
+#if defined(VK_KHR_sampler_ycbcr_conversion)
+ vkCreateSamplerYcbcrConversionKHR = (PFN_vkCreateSamplerYcbcrConversionKHR)load(context, "vkCreateSamplerYcbcrConversionKHR");
+ vkDestroySamplerYcbcrConversionKHR = (PFN_vkDestroySamplerYcbcrConversionKHR)load(context, "vkDestroySamplerYcbcrConversionKHR");
+#endif /* defined(VK_KHR_sampler_ycbcr_conversion) */
+#if defined(VK_KHR_shared_presentable_image)
+ vkGetSwapchainStatusKHR = (PFN_vkGetSwapchainStatusKHR)load(context, "vkGetSwapchainStatusKHR");
+#endif /* defined(VK_KHR_shared_presentable_image) */
+#if defined(VK_KHR_swapchain)
+ vkAcquireNextImageKHR = (PFN_vkAcquireNextImageKHR)load(context, "vkAcquireNextImageKHR");
+ vkCreateSwapchainKHR = (PFN_vkCreateSwapchainKHR)load(context, "vkCreateSwapchainKHR");
+ vkDestroySwapchainKHR = (PFN_vkDestroySwapchainKHR)load(context, "vkDestroySwapchainKHR");
+ vkGetSwapchainImagesKHR = (PFN_vkGetSwapchainImagesKHR)load(context, "vkGetSwapchainImagesKHR");
+ vkQueuePresentKHR = (PFN_vkQueuePresentKHR)load(context, "vkQueuePresentKHR");
+#endif /* defined(VK_KHR_swapchain) */
+#if defined(VK_KHR_synchronization2)
+ vkCmdPipelineBarrier2KHR = (PFN_vkCmdPipelineBarrier2KHR)load(context, "vkCmdPipelineBarrier2KHR");
+ vkCmdResetEvent2KHR = (PFN_vkCmdResetEvent2KHR)load(context, "vkCmdResetEvent2KHR");
+ vkCmdSetEvent2KHR = (PFN_vkCmdSetEvent2KHR)load(context, "vkCmdSetEvent2KHR");
+ vkCmdWaitEvents2KHR = (PFN_vkCmdWaitEvents2KHR)load(context, "vkCmdWaitEvents2KHR");
+ vkCmdWriteTimestamp2KHR = (PFN_vkCmdWriteTimestamp2KHR)load(context, "vkCmdWriteTimestamp2KHR");
+ vkQueueSubmit2KHR = (PFN_vkQueueSubmit2KHR)load(context, "vkQueueSubmit2KHR");
+#endif /* defined(VK_KHR_synchronization2) */
+#if defined(VK_KHR_synchronization2) && defined(VK_AMD_buffer_marker)
+ vkCmdWriteBufferMarker2AMD = (PFN_vkCmdWriteBufferMarker2AMD)load(context, "vkCmdWriteBufferMarker2AMD");
+#endif /* defined(VK_KHR_synchronization2) && defined(VK_AMD_buffer_marker) */
+#if defined(VK_KHR_synchronization2) && defined(VK_NV_device_diagnostic_checkpoints)
+ vkGetQueueCheckpointData2NV = (PFN_vkGetQueueCheckpointData2NV)load(context, "vkGetQueueCheckpointData2NV");
+#endif /* defined(VK_KHR_synchronization2) && defined(VK_NV_device_diagnostic_checkpoints) */
+#if defined(VK_KHR_timeline_semaphore)
+ vkGetSemaphoreCounterValueKHR = (PFN_vkGetSemaphoreCounterValueKHR)load(context, "vkGetSemaphoreCounterValueKHR");
+ vkSignalSemaphoreKHR = (PFN_vkSignalSemaphoreKHR)load(context, "vkSignalSemaphoreKHR");
+ vkWaitSemaphoresKHR = (PFN_vkWaitSemaphoresKHR)load(context, "vkWaitSemaphoresKHR");
+#endif /* defined(VK_KHR_timeline_semaphore) */
+#if defined(VK_KHR_video_decode_queue)
+ vkCmdDecodeVideoKHR = (PFN_vkCmdDecodeVideoKHR)load(context, "vkCmdDecodeVideoKHR");
+#endif /* defined(VK_KHR_video_decode_queue) */
+#if defined(VK_KHR_video_encode_queue)
+ vkCmdEncodeVideoKHR = (PFN_vkCmdEncodeVideoKHR)load(context, "vkCmdEncodeVideoKHR");
+#endif /* defined(VK_KHR_video_encode_queue) */
+#if defined(VK_KHR_video_queue)
+ vkBindVideoSessionMemoryKHR = (PFN_vkBindVideoSessionMemoryKHR)load(context, "vkBindVideoSessionMemoryKHR");
+ vkCmdBeginVideoCodingKHR = (PFN_vkCmdBeginVideoCodingKHR)load(context, "vkCmdBeginVideoCodingKHR");
+ vkCmdControlVideoCodingKHR = (PFN_vkCmdControlVideoCodingKHR)load(context, "vkCmdControlVideoCodingKHR");
+ vkCmdEndVideoCodingKHR = (PFN_vkCmdEndVideoCodingKHR)load(context, "vkCmdEndVideoCodingKHR");
+ vkCreateVideoSessionKHR = (PFN_vkCreateVideoSessionKHR)load(context, "vkCreateVideoSessionKHR");
+ vkCreateVideoSessionParametersKHR = (PFN_vkCreateVideoSessionParametersKHR)load(context, "vkCreateVideoSessionParametersKHR");
+ vkDestroyVideoSessionKHR = (PFN_vkDestroyVideoSessionKHR)load(context, "vkDestroyVideoSessionKHR");
+ vkDestroyVideoSessionParametersKHR = (PFN_vkDestroyVideoSessionParametersKHR)load(context, "vkDestroyVideoSessionParametersKHR");
+ vkGetVideoSessionMemoryRequirementsKHR = (PFN_vkGetVideoSessionMemoryRequirementsKHR)load(context, "vkGetVideoSessionMemoryRequirementsKHR");
+ vkUpdateVideoSessionParametersKHR = (PFN_vkUpdateVideoSessionParametersKHR)load(context, "vkUpdateVideoSessionParametersKHR");
+#endif /* defined(VK_KHR_video_queue) */
+#if defined(VK_NVX_binary_import)
+ vkCmdCuLaunchKernelNVX = (PFN_vkCmdCuLaunchKernelNVX)load(context, "vkCmdCuLaunchKernelNVX");
+ vkCreateCuFunctionNVX = (PFN_vkCreateCuFunctionNVX)load(context, "vkCreateCuFunctionNVX");
+ vkCreateCuModuleNVX = (PFN_vkCreateCuModuleNVX)load(context, "vkCreateCuModuleNVX");
+ vkDestroyCuFunctionNVX = (PFN_vkDestroyCuFunctionNVX)load(context, "vkDestroyCuFunctionNVX");
+ vkDestroyCuModuleNVX = (PFN_vkDestroyCuModuleNVX)load(context, "vkDestroyCuModuleNVX");
+#endif /* defined(VK_NVX_binary_import) */
+#if defined(VK_NVX_image_view_handle)
+ vkGetImageViewAddressNVX = (PFN_vkGetImageViewAddressNVX)load(context, "vkGetImageViewAddressNVX");
+ vkGetImageViewHandleNVX = (PFN_vkGetImageViewHandleNVX)load(context, "vkGetImageViewHandleNVX");
+#endif /* defined(VK_NVX_image_view_handle) */
+#if defined(VK_NV_clip_space_w_scaling)
+ vkCmdSetViewportWScalingNV = (PFN_vkCmdSetViewportWScalingNV)load(context, "vkCmdSetViewportWScalingNV");
+#endif /* defined(VK_NV_clip_space_w_scaling) */
+#if defined(VK_NV_device_diagnostic_checkpoints)
+ vkCmdSetCheckpointNV = (PFN_vkCmdSetCheckpointNV)load(context, "vkCmdSetCheckpointNV");
+ vkGetQueueCheckpointDataNV = (PFN_vkGetQueueCheckpointDataNV)load(context, "vkGetQueueCheckpointDataNV");
+#endif /* defined(VK_NV_device_diagnostic_checkpoints) */
+#if defined(VK_NV_device_generated_commands)
+ vkCmdBindPipelineShaderGroupNV = (PFN_vkCmdBindPipelineShaderGroupNV)load(context, "vkCmdBindPipelineShaderGroupNV");
+ vkCmdExecuteGeneratedCommandsNV = (PFN_vkCmdExecuteGeneratedCommandsNV)load(context, "vkCmdExecuteGeneratedCommandsNV");
+ vkCmdPreprocessGeneratedCommandsNV = (PFN_vkCmdPreprocessGeneratedCommandsNV)load(context, "vkCmdPreprocessGeneratedCommandsNV");
+ vkCreateIndirectCommandsLayoutNV = (PFN_vkCreateIndirectCommandsLayoutNV)load(context, "vkCreateIndirectCommandsLayoutNV");
+ vkDestroyIndirectCommandsLayoutNV = (PFN_vkDestroyIndirectCommandsLayoutNV)load(context, "vkDestroyIndirectCommandsLayoutNV");
+ vkGetGeneratedCommandsMemoryRequirementsNV = (PFN_vkGetGeneratedCommandsMemoryRequirementsNV)load(context, "vkGetGeneratedCommandsMemoryRequirementsNV");
+#endif /* defined(VK_NV_device_generated_commands) */
+#if defined(VK_NV_external_memory_rdma)
+ vkGetMemoryRemoteAddressNV = (PFN_vkGetMemoryRemoteAddressNV)load(context, "vkGetMemoryRemoteAddressNV");
+#endif /* defined(VK_NV_external_memory_rdma) */
+#if defined(VK_NV_external_memory_win32)
+ vkGetMemoryWin32HandleNV = (PFN_vkGetMemoryWin32HandleNV)load(context, "vkGetMemoryWin32HandleNV");
+#endif /* defined(VK_NV_external_memory_win32) */
+#if defined(VK_NV_fragment_shading_rate_enums)
+ vkCmdSetFragmentShadingRateEnumNV = (PFN_vkCmdSetFragmentShadingRateEnumNV)load(context, "vkCmdSetFragmentShadingRateEnumNV");
+#endif /* defined(VK_NV_fragment_shading_rate_enums) */
+#if defined(VK_NV_mesh_shader)
+ vkCmdDrawMeshTasksIndirectCountNV = (PFN_vkCmdDrawMeshTasksIndirectCountNV)load(context, "vkCmdDrawMeshTasksIndirectCountNV");
+ vkCmdDrawMeshTasksIndirectNV = (PFN_vkCmdDrawMeshTasksIndirectNV)load(context, "vkCmdDrawMeshTasksIndirectNV");
+ vkCmdDrawMeshTasksNV = (PFN_vkCmdDrawMeshTasksNV)load(context, "vkCmdDrawMeshTasksNV");
+#endif /* defined(VK_NV_mesh_shader) */
+#if defined(VK_NV_ray_tracing)
+ vkBindAccelerationStructureMemoryNV = (PFN_vkBindAccelerationStructureMemoryNV)load(context, "vkBindAccelerationStructureMemoryNV");
+ vkCmdBuildAccelerationStructureNV = (PFN_vkCmdBuildAccelerationStructureNV)load(context, "vkCmdBuildAccelerationStructureNV");
+ vkCmdCopyAccelerationStructureNV = (PFN_vkCmdCopyAccelerationStructureNV)load(context, "vkCmdCopyAccelerationStructureNV");
+ vkCmdTraceRaysNV = (PFN_vkCmdTraceRaysNV)load(context, "vkCmdTraceRaysNV");
+ vkCmdWriteAccelerationStructuresPropertiesNV = (PFN_vkCmdWriteAccelerationStructuresPropertiesNV)load(context, "vkCmdWriteAccelerationStructuresPropertiesNV");
+ vkCompileDeferredNV = (PFN_vkCompileDeferredNV)load(context, "vkCompileDeferredNV");
+ vkCreateAccelerationStructureNV = (PFN_vkCreateAccelerationStructureNV)load(context, "vkCreateAccelerationStructureNV");
+ vkCreateRayTracingPipelinesNV = (PFN_vkCreateRayTracingPipelinesNV)load(context, "vkCreateRayTracingPipelinesNV");
+ vkDestroyAccelerationStructureNV = (PFN_vkDestroyAccelerationStructureNV)load(context, "vkDestroyAccelerationStructureNV");
+ vkGetAccelerationStructureHandleNV = (PFN_vkGetAccelerationStructureHandleNV)load(context, "vkGetAccelerationStructureHandleNV");
+ vkGetAccelerationStructureMemoryRequirementsNV = (PFN_vkGetAccelerationStructureMemoryRequirementsNV)load(context, "vkGetAccelerationStructureMemoryRequirementsNV");
+ vkGetRayTracingShaderGroupHandlesNV = (PFN_vkGetRayTracingShaderGroupHandlesNV)load(context, "vkGetRayTracingShaderGroupHandlesNV");
+#endif /* defined(VK_NV_ray_tracing) */
+#if defined(VK_NV_scissor_exclusive)
+ vkCmdSetExclusiveScissorNV = (PFN_vkCmdSetExclusiveScissorNV)load(context, "vkCmdSetExclusiveScissorNV");
+#endif /* defined(VK_NV_scissor_exclusive) */
+#if defined(VK_NV_shading_rate_image)
+ vkCmdBindShadingRateImageNV = (PFN_vkCmdBindShadingRateImageNV)load(context, "vkCmdBindShadingRateImageNV");
+ vkCmdSetCoarseSampleOrderNV = (PFN_vkCmdSetCoarseSampleOrderNV)load(context, "vkCmdSetCoarseSampleOrderNV");
+ vkCmdSetViewportShadingRatePaletteNV = (PFN_vkCmdSetViewportShadingRatePaletteNV)load(context, "vkCmdSetViewportShadingRatePaletteNV");
+#endif /* defined(VK_NV_shading_rate_image) */
+#if (defined(VK_EXT_full_screen_exclusive) && defined(VK_KHR_device_group)) || (defined(VK_EXT_full_screen_exclusive) && defined(VK_VERSION_1_1))
+ vkGetDeviceGroupSurfacePresentModes2EXT = (PFN_vkGetDeviceGroupSurfacePresentModes2EXT)load(context, "vkGetDeviceGroupSurfacePresentModes2EXT");
+#endif /* (defined(VK_EXT_full_screen_exclusive) && defined(VK_KHR_device_group)) || (defined(VK_EXT_full_screen_exclusive) && defined(VK_VERSION_1_1)) */
+#if (defined(VK_KHR_descriptor_update_template) && defined(VK_KHR_push_descriptor)) || (defined(VK_KHR_push_descriptor) && defined(VK_VERSION_1_1)) || (defined(VK_KHR_push_descriptor) && defined(VK_KHR_descriptor_update_template))
+ vkCmdPushDescriptorSetWithTemplateKHR = (PFN_vkCmdPushDescriptorSetWithTemplateKHR)load(context, "vkCmdPushDescriptorSetWithTemplateKHR");
+#endif /* (defined(VK_KHR_descriptor_update_template) && defined(VK_KHR_push_descriptor)) || (defined(VK_KHR_push_descriptor) && defined(VK_VERSION_1_1)) || (defined(VK_KHR_push_descriptor) && defined(VK_KHR_descriptor_update_template)) */
+#if (defined(VK_KHR_device_group) && defined(VK_KHR_surface)) || (defined(VK_KHR_swapchain) && defined(VK_VERSION_1_1))
+ vkGetDeviceGroupPresentCapabilitiesKHR = (PFN_vkGetDeviceGroupPresentCapabilitiesKHR)load(context, "vkGetDeviceGroupPresentCapabilitiesKHR");
+ vkGetDeviceGroupSurfacePresentModesKHR = (PFN_vkGetDeviceGroupSurfacePresentModesKHR)load(context, "vkGetDeviceGroupSurfacePresentModesKHR");
+#endif /* (defined(VK_KHR_device_group) && defined(VK_KHR_surface)) || (defined(VK_KHR_swapchain) && defined(VK_VERSION_1_1)) */
+#if (defined(VK_KHR_device_group) && defined(VK_KHR_swapchain)) || (defined(VK_KHR_swapchain) && defined(VK_VERSION_1_1))
+ vkAcquireNextImage2KHR = (PFN_vkAcquireNextImage2KHR)load(context, "vkAcquireNextImage2KHR");
+#endif /* (defined(VK_KHR_device_group) && defined(VK_KHR_swapchain)) || (defined(VK_KHR_swapchain) && defined(VK_VERSION_1_1)) */
+ /* VOLK_GENERATE_LOAD_DEVICE */
+}
+
+static void volkGenLoadDeviceTable(struct VolkDeviceTable* table, void* context, PFN_vkVoidFunction (*load)(void*, const char*))
+{
+ /* VOLK_GENERATE_LOAD_DEVICE_TABLE */
+#if defined(VK_VERSION_1_0)
+ table->vkAllocateCommandBuffers = (PFN_vkAllocateCommandBuffers)load(context, "vkAllocateCommandBuffers");
+ table->vkAllocateDescriptorSets = (PFN_vkAllocateDescriptorSets)load(context, "vkAllocateDescriptorSets");
+ table->vkAllocateMemory = (PFN_vkAllocateMemory)load(context, "vkAllocateMemory");
+ table->vkBeginCommandBuffer = (PFN_vkBeginCommandBuffer)load(context, "vkBeginCommandBuffer");
+ table->vkBindBufferMemory = (PFN_vkBindBufferMemory)load(context, "vkBindBufferMemory");
+ table->vkBindImageMemory = (PFN_vkBindImageMemory)load(context, "vkBindImageMemory");
+ table->vkCmdBeginQuery = (PFN_vkCmdBeginQuery)load(context, "vkCmdBeginQuery");
+ table->vkCmdBeginRenderPass = (PFN_vkCmdBeginRenderPass)load(context, "vkCmdBeginRenderPass");
+ table->vkCmdBindDescriptorSets = (PFN_vkCmdBindDescriptorSets)load(context, "vkCmdBindDescriptorSets");
+ table->vkCmdBindIndexBuffer = (PFN_vkCmdBindIndexBuffer)load(context, "vkCmdBindIndexBuffer");
+ table->vkCmdBindPipeline = (PFN_vkCmdBindPipeline)load(context, "vkCmdBindPipeline");
+ table->vkCmdBindVertexBuffers = (PFN_vkCmdBindVertexBuffers)load(context, "vkCmdBindVertexBuffers");
+ table->vkCmdBlitImage = (PFN_vkCmdBlitImage)load(context, "vkCmdBlitImage");
+ table->vkCmdClearAttachments = (PFN_vkCmdClearAttachments)load(context, "vkCmdClearAttachments");
+ table->vkCmdClearColorImage = (PFN_vkCmdClearColorImage)load(context, "vkCmdClearColorImage");
+ table->vkCmdClearDepthStencilImage = (PFN_vkCmdClearDepthStencilImage)load(context, "vkCmdClearDepthStencilImage");
+ table->vkCmdCopyBuffer = (PFN_vkCmdCopyBuffer)load(context, "vkCmdCopyBuffer");
+ table->vkCmdCopyBufferToImage = (PFN_vkCmdCopyBufferToImage)load(context, "vkCmdCopyBufferToImage");
+ table->vkCmdCopyImage = (PFN_vkCmdCopyImage)load(context, "vkCmdCopyImage");
+ table->vkCmdCopyImageToBuffer = (PFN_vkCmdCopyImageToBuffer)load(context, "vkCmdCopyImageToBuffer");
+ table->vkCmdCopyQueryPoolResults = (PFN_vkCmdCopyQueryPoolResults)load(context, "vkCmdCopyQueryPoolResults");
+ table->vkCmdDispatch = (PFN_vkCmdDispatch)load(context, "vkCmdDispatch");
+ table->vkCmdDispatchIndirect = (PFN_vkCmdDispatchIndirect)load(context, "vkCmdDispatchIndirect");
+ table->vkCmdDraw = (PFN_vkCmdDraw)load(context, "vkCmdDraw");
+ table->vkCmdDrawIndexed = (PFN_vkCmdDrawIndexed)load(context, "vkCmdDrawIndexed");
+ table->vkCmdDrawIndexedIndirect = (PFN_vkCmdDrawIndexedIndirect)load(context, "vkCmdDrawIndexedIndirect");
+ table->vkCmdDrawIndirect = (PFN_vkCmdDrawIndirect)load(context, "vkCmdDrawIndirect");
+ table->vkCmdEndQuery = (PFN_vkCmdEndQuery)load(context, "vkCmdEndQuery");
+ table->vkCmdEndRenderPass = (PFN_vkCmdEndRenderPass)load(context, "vkCmdEndRenderPass");
+ table->vkCmdExecuteCommands = (PFN_vkCmdExecuteCommands)load(context, "vkCmdExecuteCommands");
+ table->vkCmdFillBuffer = (PFN_vkCmdFillBuffer)load(context, "vkCmdFillBuffer");
+ table->vkCmdNextSubpass = (PFN_vkCmdNextSubpass)load(context, "vkCmdNextSubpass");
+ table->vkCmdPipelineBarrier = (PFN_vkCmdPipelineBarrier)load(context, "vkCmdPipelineBarrier");
+ table->vkCmdPushConstants = (PFN_vkCmdPushConstants)load(context, "vkCmdPushConstants");
+ table->vkCmdResetEvent = (PFN_vkCmdResetEvent)load(context, "vkCmdResetEvent");
+ table->vkCmdResetQueryPool = (PFN_vkCmdResetQueryPool)load(context, "vkCmdResetQueryPool");
+ table->vkCmdResolveImage = (PFN_vkCmdResolveImage)load(context, "vkCmdResolveImage");
+ table->vkCmdSetBlendConstants = (PFN_vkCmdSetBlendConstants)load(context, "vkCmdSetBlendConstants");
+ table->vkCmdSetDepthBias = (PFN_vkCmdSetDepthBias)load(context, "vkCmdSetDepthBias");
+ table->vkCmdSetDepthBounds = (PFN_vkCmdSetDepthBounds)load(context, "vkCmdSetDepthBounds");
+ table->vkCmdSetEvent = (PFN_vkCmdSetEvent)load(context, "vkCmdSetEvent");
+ table->vkCmdSetLineWidth = (PFN_vkCmdSetLineWidth)load(context, "vkCmdSetLineWidth");
+ table->vkCmdSetScissor = (PFN_vkCmdSetScissor)load(context, "vkCmdSetScissor");
+ table->vkCmdSetStencilCompareMask = (PFN_vkCmdSetStencilCompareMask)load(context, "vkCmdSetStencilCompareMask");
+ table->vkCmdSetStencilReference = (PFN_vkCmdSetStencilReference)load(context, "vkCmdSetStencilReference");
+ table->vkCmdSetStencilWriteMask = (PFN_vkCmdSetStencilWriteMask)load(context, "vkCmdSetStencilWriteMask");
+ table->vkCmdSetViewport = (PFN_vkCmdSetViewport)load(context, "vkCmdSetViewport");
+ table->vkCmdUpdateBuffer = (PFN_vkCmdUpdateBuffer)load(context, "vkCmdUpdateBuffer");
+ table->vkCmdWaitEvents = (PFN_vkCmdWaitEvents)load(context, "vkCmdWaitEvents");
+ table->vkCmdWriteTimestamp = (PFN_vkCmdWriteTimestamp)load(context, "vkCmdWriteTimestamp");
+ table->vkCreateBuffer = (PFN_vkCreateBuffer)load(context, "vkCreateBuffer");
+ table->vkCreateBufferView = (PFN_vkCreateBufferView)load(context, "vkCreateBufferView");
+ table->vkCreateCommandPool = (PFN_vkCreateCommandPool)load(context, "vkCreateCommandPool");
+ table->vkCreateComputePipelines = (PFN_vkCreateComputePipelines)load(context, "vkCreateComputePipelines");
+ table->vkCreateDescriptorPool = (PFN_vkCreateDescriptorPool)load(context, "vkCreateDescriptorPool");
+ table->vkCreateDescriptorSetLayout = (PFN_vkCreateDescriptorSetLayout)load(context, "vkCreateDescriptorSetLayout");
+ table->vkCreateEvent = (PFN_vkCreateEvent)load(context, "vkCreateEvent");
+ table->vkCreateFence = (PFN_vkCreateFence)load(context, "vkCreateFence");
+ table->vkCreateFramebuffer = (PFN_vkCreateFramebuffer)load(context, "vkCreateFramebuffer");
+ table->vkCreateGraphicsPipelines = (PFN_vkCreateGraphicsPipelines)load(context, "vkCreateGraphicsPipelines");
+ table->vkCreateImage = (PFN_vkCreateImage)load(context, "vkCreateImage");
+ table->vkCreateImageView = (PFN_vkCreateImageView)load(context, "vkCreateImageView");
+ table->vkCreatePipelineCache = (PFN_vkCreatePipelineCache)load(context, "vkCreatePipelineCache");
+ table->vkCreatePipelineLayout = (PFN_vkCreatePipelineLayout)load(context, "vkCreatePipelineLayout");
+ table->vkCreateQueryPool = (PFN_vkCreateQueryPool)load(context, "vkCreateQueryPool");
+ table->vkCreateRenderPass = (PFN_vkCreateRenderPass)load(context, "vkCreateRenderPass");
+ table->vkCreateSampler = (PFN_vkCreateSampler)load(context, "vkCreateSampler");
+ table->vkCreateSemaphore = (PFN_vkCreateSemaphore)load(context, "vkCreateSemaphore");
+ table->vkCreateShaderModule = (PFN_vkCreateShaderModule)load(context, "vkCreateShaderModule");
+ table->vkDestroyBuffer = (PFN_vkDestroyBuffer)load(context, "vkDestroyBuffer");
+ table->vkDestroyBufferView = (PFN_vkDestroyBufferView)load(context, "vkDestroyBufferView");
+ table->vkDestroyCommandPool = (PFN_vkDestroyCommandPool)load(context, "vkDestroyCommandPool");
+ table->vkDestroyDescriptorPool = (PFN_vkDestroyDescriptorPool)load(context, "vkDestroyDescriptorPool");
+ table->vkDestroyDescriptorSetLayout = (PFN_vkDestroyDescriptorSetLayout)load(context, "vkDestroyDescriptorSetLayout");
+ table->vkDestroyDevice = (PFN_vkDestroyDevice)load(context, "vkDestroyDevice");
+ table->vkDestroyEvent = (PFN_vkDestroyEvent)load(context, "vkDestroyEvent");
+ table->vkDestroyFence = (PFN_vkDestroyFence)load(context, "vkDestroyFence");
+ table->vkDestroyFramebuffer = (PFN_vkDestroyFramebuffer)load(context, "vkDestroyFramebuffer");
+ table->vkDestroyImage = (PFN_vkDestroyImage)load(context, "vkDestroyImage");
+ table->vkDestroyImageView = (PFN_vkDestroyImageView)load(context, "vkDestroyImageView");
+ table->vkDestroyPipeline = (PFN_vkDestroyPipeline)load(context, "vkDestroyPipeline");
+ table->vkDestroyPipelineCache = (PFN_vkDestroyPipelineCache)load(context, "vkDestroyPipelineCache");
+ table->vkDestroyPipelineLayout = (PFN_vkDestroyPipelineLayout)load(context, "vkDestroyPipelineLayout");
+ table->vkDestroyQueryPool = (PFN_vkDestroyQueryPool)load(context, "vkDestroyQueryPool");
+ table->vkDestroyRenderPass = (PFN_vkDestroyRenderPass)load(context, "vkDestroyRenderPass");
+ table->vkDestroySampler = (PFN_vkDestroySampler)load(context, "vkDestroySampler");
+ table->vkDestroySemaphore = (PFN_vkDestroySemaphore)load(context, "vkDestroySemaphore");
+ table->vkDestroyShaderModule = (PFN_vkDestroyShaderModule)load(context, "vkDestroyShaderModule");
+ table->vkDeviceWaitIdle = (PFN_vkDeviceWaitIdle)load(context, "vkDeviceWaitIdle");
+ table->vkEndCommandBuffer = (PFN_vkEndCommandBuffer)load(context, "vkEndCommandBuffer");
+ table->vkFlushMappedMemoryRanges = (PFN_vkFlushMappedMemoryRanges)load(context, "vkFlushMappedMemoryRanges");
+ table->vkFreeCommandBuffers = (PFN_vkFreeCommandBuffers)load(context, "vkFreeCommandBuffers");
+ table->vkFreeDescriptorSets = (PFN_vkFreeDescriptorSets)load(context, "vkFreeDescriptorSets");
+ table->vkFreeMemory = (PFN_vkFreeMemory)load(context, "vkFreeMemory");
+ table->vkGetBufferMemoryRequirements = (PFN_vkGetBufferMemoryRequirements)load(context, "vkGetBufferMemoryRequirements");
+ table->vkGetDeviceMemoryCommitment = (PFN_vkGetDeviceMemoryCommitment)load(context, "vkGetDeviceMemoryCommitment");
+ table->vkGetDeviceQueue = (PFN_vkGetDeviceQueue)load(context, "vkGetDeviceQueue");
+ table->vkGetEventStatus = (PFN_vkGetEventStatus)load(context, "vkGetEventStatus");
+ table->vkGetFenceStatus = (PFN_vkGetFenceStatus)load(context, "vkGetFenceStatus");
+ table->vkGetImageMemoryRequirements = (PFN_vkGetImageMemoryRequirements)load(context, "vkGetImageMemoryRequirements");
+ table->vkGetImageSparseMemoryRequirements = (PFN_vkGetImageSparseMemoryRequirements)load(context, "vkGetImageSparseMemoryRequirements");
+ table->vkGetImageSubresourceLayout = (PFN_vkGetImageSubresourceLayout)load(context, "vkGetImageSubresourceLayout");
+ table->vkGetPipelineCacheData = (PFN_vkGetPipelineCacheData)load(context, "vkGetPipelineCacheData");
+ table->vkGetQueryPoolResults = (PFN_vkGetQueryPoolResults)load(context, "vkGetQueryPoolResults");
+ table->vkGetRenderAreaGranularity = (PFN_vkGetRenderAreaGranularity)load(context, "vkGetRenderAreaGranularity");
+ table->vkInvalidateMappedMemoryRanges = (PFN_vkInvalidateMappedMemoryRanges)load(context, "vkInvalidateMappedMemoryRanges");
+ table->vkMapMemory = (PFN_vkMapMemory)load(context, "vkMapMemory");
+ table->vkMergePipelineCaches = (PFN_vkMergePipelineCaches)load(context, "vkMergePipelineCaches");
+ table->vkQueueBindSparse = (PFN_vkQueueBindSparse)load(context, "vkQueueBindSparse");
+ table->vkQueueSubmit = (PFN_vkQueueSubmit)load(context, "vkQueueSubmit");
+ table->vkQueueWaitIdle = (PFN_vkQueueWaitIdle)load(context, "vkQueueWaitIdle");
+ table->vkResetCommandBuffer = (PFN_vkResetCommandBuffer)load(context, "vkResetCommandBuffer");
+ table->vkResetCommandPool = (PFN_vkResetCommandPool)load(context, "vkResetCommandPool");
+ table->vkResetDescriptorPool = (PFN_vkResetDescriptorPool)load(context, "vkResetDescriptorPool");
+ table->vkResetEvent = (PFN_vkResetEvent)load(context, "vkResetEvent");
+ table->vkResetFences = (PFN_vkResetFences)load(context, "vkResetFences");
+ table->vkSetEvent = (PFN_vkSetEvent)load(context, "vkSetEvent");
+ table->vkUnmapMemory = (PFN_vkUnmapMemory)load(context, "vkUnmapMemory");
+ table->vkUpdateDescriptorSets = (PFN_vkUpdateDescriptorSets)load(context, "vkUpdateDescriptorSets");
+ table->vkWaitForFences = (PFN_vkWaitForFences)load(context, "vkWaitForFences");
+#endif /* defined(VK_VERSION_1_0) */
+#if defined(VK_VERSION_1_1)
+ table->vkBindBufferMemory2 = (PFN_vkBindBufferMemory2)load(context, "vkBindBufferMemory2");
+ table->vkBindImageMemory2 = (PFN_vkBindImageMemory2)load(context, "vkBindImageMemory2");
+ table->vkCmdDispatchBase = (PFN_vkCmdDispatchBase)load(context, "vkCmdDispatchBase");
+ table->vkCmdSetDeviceMask = (PFN_vkCmdSetDeviceMask)load(context, "vkCmdSetDeviceMask");
+ table->vkCreateDescriptorUpdateTemplate = (PFN_vkCreateDescriptorUpdateTemplate)load(context, "vkCreateDescriptorUpdateTemplate");
+ table->vkCreateSamplerYcbcrConversion = (PFN_vkCreateSamplerYcbcrConversion)load(context, "vkCreateSamplerYcbcrConversion");
+ table->vkDestroyDescriptorUpdateTemplate = (PFN_vkDestroyDescriptorUpdateTemplate)load(context, "vkDestroyDescriptorUpdateTemplate");
+ table->vkDestroySamplerYcbcrConversion = (PFN_vkDestroySamplerYcbcrConversion)load(context, "vkDestroySamplerYcbcrConversion");
+ table->vkGetBufferMemoryRequirements2 = (PFN_vkGetBufferMemoryRequirements2)load(context, "vkGetBufferMemoryRequirements2");
+ table->vkGetDescriptorSetLayoutSupport = (PFN_vkGetDescriptorSetLayoutSupport)load(context, "vkGetDescriptorSetLayoutSupport");
+ table->vkGetDeviceGroupPeerMemoryFeatures = (PFN_vkGetDeviceGroupPeerMemoryFeatures)load(context, "vkGetDeviceGroupPeerMemoryFeatures");
+ table->vkGetDeviceQueue2 = (PFN_vkGetDeviceQueue2)load(context, "vkGetDeviceQueue2");
+ table->vkGetImageMemoryRequirements2 = (PFN_vkGetImageMemoryRequirements2)load(context, "vkGetImageMemoryRequirements2");
+ table->vkGetImageSparseMemoryRequirements2 = (PFN_vkGetImageSparseMemoryRequirements2)load(context, "vkGetImageSparseMemoryRequirements2");
+ table->vkTrimCommandPool = (PFN_vkTrimCommandPool)load(context, "vkTrimCommandPool");
+ table->vkUpdateDescriptorSetWithTemplate = (PFN_vkUpdateDescriptorSetWithTemplate)load(context, "vkUpdateDescriptorSetWithTemplate");
+#endif /* defined(VK_VERSION_1_1) */
+#if defined(VK_VERSION_1_2)
+ table->vkCmdBeginRenderPass2 = (PFN_vkCmdBeginRenderPass2)load(context, "vkCmdBeginRenderPass2");
+ table->vkCmdDrawIndexedIndirectCount = (PFN_vkCmdDrawIndexedIndirectCount)load(context, "vkCmdDrawIndexedIndirectCount");
+ table->vkCmdDrawIndirectCount = (PFN_vkCmdDrawIndirectCount)load(context, "vkCmdDrawIndirectCount");
+ table->vkCmdEndRenderPass2 = (PFN_vkCmdEndRenderPass2)load(context, "vkCmdEndRenderPass2");
+ table->vkCmdNextSubpass2 = (PFN_vkCmdNextSubpass2)load(context, "vkCmdNextSubpass2");
+ table->vkCreateRenderPass2 = (PFN_vkCreateRenderPass2)load(context, "vkCreateRenderPass2");
+ table->vkGetBufferDeviceAddress = (PFN_vkGetBufferDeviceAddress)load(context, "vkGetBufferDeviceAddress");
+ table->vkGetBufferOpaqueCaptureAddress = (PFN_vkGetBufferOpaqueCaptureAddress)load(context, "vkGetBufferOpaqueCaptureAddress");
+ table->vkGetDeviceMemoryOpaqueCaptureAddress = (PFN_vkGetDeviceMemoryOpaqueCaptureAddress)load(context, "vkGetDeviceMemoryOpaqueCaptureAddress");
+ table->vkGetSemaphoreCounterValue = (PFN_vkGetSemaphoreCounterValue)load(context, "vkGetSemaphoreCounterValue");
+ table->vkResetQueryPool = (PFN_vkResetQueryPool)load(context, "vkResetQueryPool");
+ table->vkSignalSemaphore = (PFN_vkSignalSemaphore)load(context, "vkSignalSemaphore");
+ table->vkWaitSemaphores = (PFN_vkWaitSemaphores)load(context, "vkWaitSemaphores");
+#endif /* defined(VK_VERSION_1_2) */
+#if defined(VK_VERSION_1_3)
+ table->vkCmdBeginRendering = (PFN_vkCmdBeginRendering)load(context, "vkCmdBeginRendering");
+ table->vkCmdBindVertexBuffers2 = (PFN_vkCmdBindVertexBuffers2)load(context, "vkCmdBindVertexBuffers2");
+ table->vkCmdBlitImage2 = (PFN_vkCmdBlitImage2)load(context, "vkCmdBlitImage2");
+ table->vkCmdCopyBuffer2 = (PFN_vkCmdCopyBuffer2)load(context, "vkCmdCopyBuffer2");
+ table->vkCmdCopyBufferToImage2 = (PFN_vkCmdCopyBufferToImage2)load(context, "vkCmdCopyBufferToImage2");
+ table->vkCmdCopyImage2 = (PFN_vkCmdCopyImage2)load(context, "vkCmdCopyImage2");
+ table->vkCmdCopyImageToBuffer2 = (PFN_vkCmdCopyImageToBuffer2)load(context, "vkCmdCopyImageToBuffer2");
+ table->vkCmdEndRendering = (PFN_vkCmdEndRendering)load(context, "vkCmdEndRendering");
+ table->vkCmdPipelineBarrier2 = (PFN_vkCmdPipelineBarrier2)load(context, "vkCmdPipelineBarrier2");
+ table->vkCmdResetEvent2 = (PFN_vkCmdResetEvent2)load(context, "vkCmdResetEvent2");
+ table->vkCmdResolveImage2 = (PFN_vkCmdResolveImage2)load(context, "vkCmdResolveImage2");
+ table->vkCmdSetCullMode = (PFN_vkCmdSetCullMode)load(context, "vkCmdSetCullMode");
+ table->vkCmdSetDepthBiasEnable = (PFN_vkCmdSetDepthBiasEnable)load(context, "vkCmdSetDepthBiasEnable");
+ table->vkCmdSetDepthBoundsTestEnable = (PFN_vkCmdSetDepthBoundsTestEnable)load(context, "vkCmdSetDepthBoundsTestEnable");
+ table->vkCmdSetDepthCompareOp = (PFN_vkCmdSetDepthCompareOp)load(context, "vkCmdSetDepthCompareOp");
+ table->vkCmdSetDepthTestEnable = (PFN_vkCmdSetDepthTestEnable)load(context, "vkCmdSetDepthTestEnable");
+ table->vkCmdSetDepthWriteEnable = (PFN_vkCmdSetDepthWriteEnable)load(context, "vkCmdSetDepthWriteEnable");
+ table->vkCmdSetEvent2 = (PFN_vkCmdSetEvent2)load(context, "vkCmdSetEvent2");
+ table->vkCmdSetFrontFace = (PFN_vkCmdSetFrontFace)load(context, "vkCmdSetFrontFace");
+ table->vkCmdSetPrimitiveRestartEnable = (PFN_vkCmdSetPrimitiveRestartEnable)load(context, "vkCmdSetPrimitiveRestartEnable");
+ table->vkCmdSetPrimitiveTopology = (PFN_vkCmdSetPrimitiveTopology)load(context, "vkCmdSetPrimitiveTopology");
+ table->vkCmdSetRasterizerDiscardEnable = (PFN_vkCmdSetRasterizerDiscardEnable)load(context, "vkCmdSetRasterizerDiscardEnable");
+ table->vkCmdSetScissorWithCount = (PFN_vkCmdSetScissorWithCount)load(context, "vkCmdSetScissorWithCount");
+ table->vkCmdSetStencilOp = (PFN_vkCmdSetStencilOp)load(context, "vkCmdSetStencilOp");
+ table->vkCmdSetStencilTestEnable = (PFN_vkCmdSetStencilTestEnable)load(context, "vkCmdSetStencilTestEnable");
+ table->vkCmdSetViewportWithCount = (PFN_vkCmdSetViewportWithCount)load(context, "vkCmdSetViewportWithCount");
+ table->vkCmdWaitEvents2 = (PFN_vkCmdWaitEvents2)load(context, "vkCmdWaitEvents2");
+ table->vkCmdWriteTimestamp2 = (PFN_vkCmdWriteTimestamp2)load(context, "vkCmdWriteTimestamp2");
+ table->vkCreatePrivateDataSlot = (PFN_vkCreatePrivateDataSlot)load(context, "vkCreatePrivateDataSlot");
+ table->vkDestroyPrivateDataSlot = (PFN_vkDestroyPrivateDataSlot)load(context, "vkDestroyPrivateDataSlot");
+ table->vkGetDeviceBufferMemoryRequirements = (PFN_vkGetDeviceBufferMemoryRequirements)load(context, "vkGetDeviceBufferMemoryRequirements");
+ table->vkGetDeviceImageMemoryRequirements = (PFN_vkGetDeviceImageMemoryRequirements)load(context, "vkGetDeviceImageMemoryRequirements");
+ table->vkGetDeviceImageSparseMemoryRequirements = (PFN_vkGetDeviceImageSparseMemoryRequirements)load(context, "vkGetDeviceImageSparseMemoryRequirements");
+ table->vkGetPrivateData = (PFN_vkGetPrivateData)load(context, "vkGetPrivateData");
+ table->vkQueueSubmit2 = (PFN_vkQueueSubmit2)load(context, "vkQueueSubmit2");
+ table->vkSetPrivateData = (PFN_vkSetPrivateData)load(context, "vkSetPrivateData");
+#endif /* defined(VK_VERSION_1_3) */
+#if defined(VK_AMD_buffer_marker)
+ table->vkCmdWriteBufferMarkerAMD = (PFN_vkCmdWriteBufferMarkerAMD)load(context, "vkCmdWriteBufferMarkerAMD");
+#endif /* defined(VK_AMD_buffer_marker) */
+#if defined(VK_AMD_display_native_hdr)
+ table->vkSetLocalDimmingAMD = (PFN_vkSetLocalDimmingAMD)load(context, "vkSetLocalDimmingAMD");
+#endif /* defined(VK_AMD_display_native_hdr) */
+#if defined(VK_AMD_draw_indirect_count)
+ table->vkCmdDrawIndexedIndirectCountAMD = (PFN_vkCmdDrawIndexedIndirectCountAMD)load(context, "vkCmdDrawIndexedIndirectCountAMD");
+ table->vkCmdDrawIndirectCountAMD = (PFN_vkCmdDrawIndirectCountAMD)load(context, "vkCmdDrawIndirectCountAMD");
+#endif /* defined(VK_AMD_draw_indirect_count) */
+#if defined(VK_AMD_shader_info)
+ table->vkGetShaderInfoAMD = (PFN_vkGetShaderInfoAMD)load(context, "vkGetShaderInfoAMD");
+#endif /* defined(VK_AMD_shader_info) */
+#if defined(VK_ANDROID_external_memory_android_hardware_buffer)
+ table->vkGetAndroidHardwareBufferPropertiesANDROID = (PFN_vkGetAndroidHardwareBufferPropertiesANDROID)load(context, "vkGetAndroidHardwareBufferPropertiesANDROID");
+ table->vkGetMemoryAndroidHardwareBufferANDROID = (PFN_vkGetMemoryAndroidHardwareBufferANDROID)load(context, "vkGetMemoryAndroidHardwareBufferANDROID");
+#endif /* defined(VK_ANDROID_external_memory_android_hardware_buffer) */
+#if defined(VK_EXT_buffer_device_address)
+ table->vkGetBufferDeviceAddressEXT = (PFN_vkGetBufferDeviceAddressEXT)load(context, "vkGetBufferDeviceAddressEXT");
+#endif /* defined(VK_EXT_buffer_device_address) */
+#if defined(VK_EXT_calibrated_timestamps)
+ table->vkGetCalibratedTimestampsEXT = (PFN_vkGetCalibratedTimestampsEXT)load(context, "vkGetCalibratedTimestampsEXT");
+#endif /* defined(VK_EXT_calibrated_timestamps) */
+#if defined(VK_EXT_color_write_enable)
+ table->vkCmdSetColorWriteEnableEXT = (PFN_vkCmdSetColorWriteEnableEXT)load(context, "vkCmdSetColorWriteEnableEXT");
+#endif /* defined(VK_EXT_color_write_enable) */
+#if defined(VK_EXT_conditional_rendering)
+ table->vkCmdBeginConditionalRenderingEXT = (PFN_vkCmdBeginConditionalRenderingEXT)load(context, "vkCmdBeginConditionalRenderingEXT");
+ table->vkCmdEndConditionalRenderingEXT = (PFN_vkCmdEndConditionalRenderingEXT)load(context, "vkCmdEndConditionalRenderingEXT");
+#endif /* defined(VK_EXT_conditional_rendering) */
+#if defined(VK_EXT_debug_marker)
+ table->vkCmdDebugMarkerBeginEXT = (PFN_vkCmdDebugMarkerBeginEXT)load(context, "vkCmdDebugMarkerBeginEXT");
+ table->vkCmdDebugMarkerEndEXT = (PFN_vkCmdDebugMarkerEndEXT)load(context, "vkCmdDebugMarkerEndEXT");
+ table->vkCmdDebugMarkerInsertEXT = (PFN_vkCmdDebugMarkerInsertEXT)load(context, "vkCmdDebugMarkerInsertEXT");
+ table->vkDebugMarkerSetObjectNameEXT = (PFN_vkDebugMarkerSetObjectNameEXT)load(context, "vkDebugMarkerSetObjectNameEXT");
+ table->vkDebugMarkerSetObjectTagEXT = (PFN_vkDebugMarkerSetObjectTagEXT)load(context, "vkDebugMarkerSetObjectTagEXT");
+#endif /* defined(VK_EXT_debug_marker) */
+#if defined(VK_EXT_discard_rectangles)
+ table->vkCmdSetDiscardRectangleEXT = (PFN_vkCmdSetDiscardRectangleEXT)load(context, "vkCmdSetDiscardRectangleEXT");
+#endif /* defined(VK_EXT_discard_rectangles) */
+#if defined(VK_EXT_display_control)
+ table->vkDisplayPowerControlEXT = (PFN_vkDisplayPowerControlEXT)load(context, "vkDisplayPowerControlEXT");
+ table->vkGetSwapchainCounterEXT = (PFN_vkGetSwapchainCounterEXT)load(context, "vkGetSwapchainCounterEXT");
+ table->vkRegisterDeviceEventEXT = (PFN_vkRegisterDeviceEventEXT)load(context, "vkRegisterDeviceEventEXT");
+ table->vkRegisterDisplayEventEXT = (PFN_vkRegisterDisplayEventEXT)load(context, "vkRegisterDisplayEventEXT");
+#endif /* defined(VK_EXT_display_control) */
+#if defined(VK_EXT_extended_dynamic_state)
+ table->vkCmdBindVertexBuffers2EXT = (PFN_vkCmdBindVertexBuffers2EXT)load(context, "vkCmdBindVertexBuffers2EXT");
+ table->vkCmdSetCullModeEXT = (PFN_vkCmdSetCullModeEXT)load(context, "vkCmdSetCullModeEXT");
+ table->vkCmdSetDepthBoundsTestEnableEXT = (PFN_vkCmdSetDepthBoundsTestEnableEXT)load(context, "vkCmdSetDepthBoundsTestEnableEXT");
+ table->vkCmdSetDepthCompareOpEXT = (PFN_vkCmdSetDepthCompareOpEXT)load(context, "vkCmdSetDepthCompareOpEXT");
+ table->vkCmdSetDepthTestEnableEXT = (PFN_vkCmdSetDepthTestEnableEXT)load(context, "vkCmdSetDepthTestEnableEXT");
+ table->vkCmdSetDepthWriteEnableEXT = (PFN_vkCmdSetDepthWriteEnableEXT)load(context, "vkCmdSetDepthWriteEnableEXT");
+ table->vkCmdSetFrontFaceEXT = (PFN_vkCmdSetFrontFaceEXT)load(context, "vkCmdSetFrontFaceEXT");
+ table->vkCmdSetPrimitiveTopologyEXT = (PFN_vkCmdSetPrimitiveTopologyEXT)load(context, "vkCmdSetPrimitiveTopologyEXT");
+ table->vkCmdSetScissorWithCountEXT = (PFN_vkCmdSetScissorWithCountEXT)load(context, "vkCmdSetScissorWithCountEXT");
+ table->vkCmdSetStencilOpEXT = (PFN_vkCmdSetStencilOpEXT)load(context, "vkCmdSetStencilOpEXT");
+ table->vkCmdSetStencilTestEnableEXT = (PFN_vkCmdSetStencilTestEnableEXT)load(context, "vkCmdSetStencilTestEnableEXT");
+ table->vkCmdSetViewportWithCountEXT = (PFN_vkCmdSetViewportWithCountEXT)load(context, "vkCmdSetViewportWithCountEXT");
+#endif /* defined(VK_EXT_extended_dynamic_state) */
+#if defined(VK_EXT_extended_dynamic_state2)
+ table->vkCmdSetDepthBiasEnableEXT = (PFN_vkCmdSetDepthBiasEnableEXT)load(context, "vkCmdSetDepthBiasEnableEXT");
+ table->vkCmdSetLogicOpEXT = (PFN_vkCmdSetLogicOpEXT)load(context, "vkCmdSetLogicOpEXT");
+ table->vkCmdSetPatchControlPointsEXT = (PFN_vkCmdSetPatchControlPointsEXT)load(context, "vkCmdSetPatchControlPointsEXT");
+ table->vkCmdSetPrimitiveRestartEnableEXT = (PFN_vkCmdSetPrimitiveRestartEnableEXT)load(context, "vkCmdSetPrimitiveRestartEnableEXT");
+ table->vkCmdSetRasterizerDiscardEnableEXT = (PFN_vkCmdSetRasterizerDiscardEnableEXT)load(context, "vkCmdSetRasterizerDiscardEnableEXT");
+#endif /* defined(VK_EXT_extended_dynamic_state2) */
+#if defined(VK_EXT_external_memory_host)
+ table->vkGetMemoryHostPointerPropertiesEXT = (PFN_vkGetMemoryHostPointerPropertiesEXT)load(context, "vkGetMemoryHostPointerPropertiesEXT");
+#endif /* defined(VK_EXT_external_memory_host) */
+#if defined(VK_EXT_full_screen_exclusive)
+ table->vkAcquireFullScreenExclusiveModeEXT = (PFN_vkAcquireFullScreenExclusiveModeEXT)load(context, "vkAcquireFullScreenExclusiveModeEXT");
+ table->vkReleaseFullScreenExclusiveModeEXT = (PFN_vkReleaseFullScreenExclusiveModeEXT)load(context, "vkReleaseFullScreenExclusiveModeEXT");
+#endif /* defined(VK_EXT_full_screen_exclusive) */
+#if defined(VK_EXT_hdr_metadata)
+ table->vkSetHdrMetadataEXT = (PFN_vkSetHdrMetadataEXT)load(context, "vkSetHdrMetadataEXT");
+#endif /* defined(VK_EXT_hdr_metadata) */
+#if defined(VK_EXT_host_query_reset)
+ table->vkResetQueryPoolEXT = (PFN_vkResetQueryPoolEXT)load(context, "vkResetQueryPoolEXT");
+#endif /* defined(VK_EXT_host_query_reset) */
+#if defined(VK_EXT_image_drm_format_modifier)
+ table->vkGetImageDrmFormatModifierPropertiesEXT = (PFN_vkGetImageDrmFormatModifierPropertiesEXT)load(context, "vkGetImageDrmFormatModifierPropertiesEXT");
+#endif /* defined(VK_EXT_image_drm_format_modifier) */
+#if defined(VK_EXT_line_rasterization)
+ table->vkCmdSetLineStippleEXT = (PFN_vkCmdSetLineStippleEXT)load(context, "vkCmdSetLineStippleEXT");
+#endif /* defined(VK_EXT_line_rasterization) */
+#if defined(VK_EXT_multi_draw)
+ table->vkCmdDrawMultiEXT = (PFN_vkCmdDrawMultiEXT)load(context, "vkCmdDrawMultiEXT");
+ table->vkCmdDrawMultiIndexedEXT = (PFN_vkCmdDrawMultiIndexedEXT)load(context, "vkCmdDrawMultiIndexedEXT");
+#endif /* defined(VK_EXT_multi_draw) */
+#if defined(VK_EXT_pageable_device_local_memory)
+ table->vkSetDeviceMemoryPriorityEXT = (PFN_vkSetDeviceMemoryPriorityEXT)load(context, "vkSetDeviceMemoryPriorityEXT");
+#endif /* defined(VK_EXT_pageable_device_local_memory) */
+#if defined(VK_EXT_private_data)
+ table->vkCreatePrivateDataSlotEXT = (PFN_vkCreatePrivateDataSlotEXT)load(context, "vkCreatePrivateDataSlotEXT");
+ table->vkDestroyPrivateDataSlotEXT = (PFN_vkDestroyPrivateDataSlotEXT)load(context, "vkDestroyPrivateDataSlotEXT");
+ table->vkGetPrivateDataEXT = (PFN_vkGetPrivateDataEXT)load(context, "vkGetPrivateDataEXT");
+ table->vkSetPrivateDataEXT = (PFN_vkSetPrivateDataEXT)load(context, "vkSetPrivateDataEXT");
+#endif /* defined(VK_EXT_private_data) */
+#if defined(VK_EXT_sample_locations)
+ table->vkCmdSetSampleLocationsEXT = (PFN_vkCmdSetSampleLocationsEXT)load(context, "vkCmdSetSampleLocationsEXT");
+#endif /* defined(VK_EXT_sample_locations) */
+#if defined(VK_EXT_transform_feedback)
+ table->vkCmdBeginQueryIndexedEXT = (PFN_vkCmdBeginQueryIndexedEXT)load(context, "vkCmdBeginQueryIndexedEXT");
+ table->vkCmdBeginTransformFeedbackEXT = (PFN_vkCmdBeginTransformFeedbackEXT)load(context, "vkCmdBeginTransformFeedbackEXT");
+ table->vkCmdBindTransformFeedbackBuffersEXT = (PFN_vkCmdBindTransformFeedbackBuffersEXT)load(context, "vkCmdBindTransformFeedbackBuffersEXT");
+ table->vkCmdDrawIndirectByteCountEXT = (PFN_vkCmdDrawIndirectByteCountEXT)load(context, "vkCmdDrawIndirectByteCountEXT");
+ table->vkCmdEndQueryIndexedEXT = (PFN_vkCmdEndQueryIndexedEXT)load(context, "vkCmdEndQueryIndexedEXT");
+ table->vkCmdEndTransformFeedbackEXT = (PFN_vkCmdEndTransformFeedbackEXT)load(context, "vkCmdEndTransformFeedbackEXT");
+#endif /* defined(VK_EXT_transform_feedback) */
+#if defined(VK_EXT_validation_cache)
+ table->vkCreateValidationCacheEXT = (PFN_vkCreateValidationCacheEXT)load(context, "vkCreateValidationCacheEXT");
+ table->vkDestroyValidationCacheEXT = (PFN_vkDestroyValidationCacheEXT)load(context, "vkDestroyValidationCacheEXT");
+ table->vkGetValidationCacheDataEXT = (PFN_vkGetValidationCacheDataEXT)load(context, "vkGetValidationCacheDataEXT");
+ table->vkMergeValidationCachesEXT = (PFN_vkMergeValidationCachesEXT)load(context, "vkMergeValidationCachesEXT");
+#endif /* defined(VK_EXT_validation_cache) */
+#if defined(VK_EXT_vertex_input_dynamic_state)
+ table->vkCmdSetVertexInputEXT = (PFN_vkCmdSetVertexInputEXT)load(context, "vkCmdSetVertexInputEXT");
+#endif /* defined(VK_EXT_vertex_input_dynamic_state) */
+#if defined(VK_FUCHSIA_buffer_collection)
+ table->vkCreateBufferCollectionFUCHSIA = (PFN_vkCreateBufferCollectionFUCHSIA)load(context, "vkCreateBufferCollectionFUCHSIA");
+ table->vkDestroyBufferCollectionFUCHSIA = (PFN_vkDestroyBufferCollectionFUCHSIA)load(context, "vkDestroyBufferCollectionFUCHSIA");
+ table->vkGetBufferCollectionPropertiesFUCHSIA = (PFN_vkGetBufferCollectionPropertiesFUCHSIA)load(context, "vkGetBufferCollectionPropertiesFUCHSIA");
+ table->vkSetBufferCollectionBufferConstraintsFUCHSIA = (PFN_vkSetBufferCollectionBufferConstraintsFUCHSIA)load(context, "vkSetBufferCollectionBufferConstraintsFUCHSIA");
+ table->vkSetBufferCollectionImageConstraintsFUCHSIA = (PFN_vkSetBufferCollectionImageConstraintsFUCHSIA)load(context, "vkSetBufferCollectionImageConstraintsFUCHSIA");
+#endif /* defined(VK_FUCHSIA_buffer_collection) */
+#if defined(VK_FUCHSIA_external_memory)
+ table->vkGetMemoryZirconHandleFUCHSIA = (PFN_vkGetMemoryZirconHandleFUCHSIA)load(context, "vkGetMemoryZirconHandleFUCHSIA");
+ table->vkGetMemoryZirconHandlePropertiesFUCHSIA = (PFN_vkGetMemoryZirconHandlePropertiesFUCHSIA)load(context, "vkGetMemoryZirconHandlePropertiesFUCHSIA");
+#endif /* defined(VK_FUCHSIA_external_memory) */
+#if defined(VK_FUCHSIA_external_semaphore)
+ table->vkGetSemaphoreZirconHandleFUCHSIA = (PFN_vkGetSemaphoreZirconHandleFUCHSIA)load(context, "vkGetSemaphoreZirconHandleFUCHSIA");
+ table->vkImportSemaphoreZirconHandleFUCHSIA = (PFN_vkImportSemaphoreZirconHandleFUCHSIA)load(context, "vkImportSemaphoreZirconHandleFUCHSIA");
+#endif /* defined(VK_FUCHSIA_external_semaphore) */
+#if defined(VK_GOOGLE_display_timing)
+ table->vkGetPastPresentationTimingGOOGLE = (PFN_vkGetPastPresentationTimingGOOGLE)load(context, "vkGetPastPresentationTimingGOOGLE");
+ table->vkGetRefreshCycleDurationGOOGLE = (PFN_vkGetRefreshCycleDurationGOOGLE)load(context, "vkGetRefreshCycleDurationGOOGLE");
+#endif /* defined(VK_GOOGLE_display_timing) */
+#if defined(VK_HUAWEI_invocation_mask)
+ table->vkCmdBindInvocationMaskHUAWEI = (PFN_vkCmdBindInvocationMaskHUAWEI)load(context, "vkCmdBindInvocationMaskHUAWEI");
+#endif /* defined(VK_HUAWEI_invocation_mask) */
+#if defined(VK_HUAWEI_subpass_shading)
+ table->vkCmdSubpassShadingHUAWEI = (PFN_vkCmdSubpassShadingHUAWEI)load(context, "vkCmdSubpassShadingHUAWEI");
+ table->vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI = (PFN_vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI)load(context, "vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI");
+#endif /* defined(VK_HUAWEI_subpass_shading) */
+#if defined(VK_INTEL_performance_query)
+ table->vkAcquirePerformanceConfigurationINTEL = (PFN_vkAcquirePerformanceConfigurationINTEL)load(context, "vkAcquirePerformanceConfigurationINTEL");
+ table->vkCmdSetPerformanceMarkerINTEL = (PFN_vkCmdSetPerformanceMarkerINTEL)load(context, "vkCmdSetPerformanceMarkerINTEL");
+ table->vkCmdSetPerformanceOverrideINTEL = (PFN_vkCmdSetPerformanceOverrideINTEL)load(context, "vkCmdSetPerformanceOverrideINTEL");
+ table->vkCmdSetPerformanceStreamMarkerINTEL = (PFN_vkCmdSetPerformanceStreamMarkerINTEL)load(context, "vkCmdSetPerformanceStreamMarkerINTEL");
+ table->vkGetPerformanceParameterINTEL = (PFN_vkGetPerformanceParameterINTEL)load(context, "vkGetPerformanceParameterINTEL");
+ table->vkInitializePerformanceApiINTEL = (PFN_vkInitializePerformanceApiINTEL)load(context, "vkInitializePerformanceApiINTEL");
+ table->vkQueueSetPerformanceConfigurationINTEL = (PFN_vkQueueSetPerformanceConfigurationINTEL)load(context, "vkQueueSetPerformanceConfigurationINTEL");
+ table->vkReleasePerformanceConfigurationINTEL = (PFN_vkReleasePerformanceConfigurationINTEL)load(context, "vkReleasePerformanceConfigurationINTEL");
+ table->vkUninitializePerformanceApiINTEL = (PFN_vkUninitializePerformanceApiINTEL)load(context, "vkUninitializePerformanceApiINTEL");
+#endif /* defined(VK_INTEL_performance_query) */
+#if defined(VK_KHR_acceleration_structure)
+ table->vkBuildAccelerationStructuresKHR = (PFN_vkBuildAccelerationStructuresKHR)load(context, "vkBuildAccelerationStructuresKHR");
+ table->vkCmdBuildAccelerationStructuresIndirectKHR = (PFN_vkCmdBuildAccelerationStructuresIndirectKHR)load(context, "vkCmdBuildAccelerationStructuresIndirectKHR");
+ table->vkCmdBuildAccelerationStructuresKHR = (PFN_vkCmdBuildAccelerationStructuresKHR)load(context, "vkCmdBuildAccelerationStructuresKHR");
+ table->vkCmdCopyAccelerationStructureKHR = (PFN_vkCmdCopyAccelerationStructureKHR)load(context, "vkCmdCopyAccelerationStructureKHR");
+ table->vkCmdCopyAccelerationStructureToMemoryKHR = (PFN_vkCmdCopyAccelerationStructureToMemoryKHR)load(context, "vkCmdCopyAccelerationStructureToMemoryKHR");
+ table->vkCmdCopyMemoryToAccelerationStructureKHR = (PFN_vkCmdCopyMemoryToAccelerationStructureKHR)load(context, "vkCmdCopyMemoryToAccelerationStructureKHR");
+ table->vkCmdWriteAccelerationStructuresPropertiesKHR = (PFN_vkCmdWriteAccelerationStructuresPropertiesKHR)load(context, "vkCmdWriteAccelerationStructuresPropertiesKHR");
+ table->vkCopyAccelerationStructureKHR = (PFN_vkCopyAccelerationStructureKHR)load(context, "vkCopyAccelerationStructureKHR");
+ table->vkCopyAccelerationStructureToMemoryKHR = (PFN_vkCopyAccelerationStructureToMemoryKHR)load(context, "vkCopyAccelerationStructureToMemoryKHR");
+ table->vkCopyMemoryToAccelerationStructureKHR = (PFN_vkCopyMemoryToAccelerationStructureKHR)load(context, "vkCopyMemoryToAccelerationStructureKHR");
+ table->vkCreateAccelerationStructureKHR = (PFN_vkCreateAccelerationStructureKHR)load(context, "vkCreateAccelerationStructureKHR");
+ table->vkDestroyAccelerationStructureKHR = (PFN_vkDestroyAccelerationStructureKHR)load(context, "vkDestroyAccelerationStructureKHR");
+ table->vkGetAccelerationStructureBuildSizesKHR = (PFN_vkGetAccelerationStructureBuildSizesKHR)load(context, "vkGetAccelerationStructureBuildSizesKHR");
+ table->vkGetAccelerationStructureDeviceAddressKHR = (PFN_vkGetAccelerationStructureDeviceAddressKHR)load(context, "vkGetAccelerationStructureDeviceAddressKHR");
+ table->vkGetDeviceAccelerationStructureCompatibilityKHR = (PFN_vkGetDeviceAccelerationStructureCompatibilityKHR)load(context, "vkGetDeviceAccelerationStructureCompatibilityKHR");
+ table->vkWriteAccelerationStructuresPropertiesKHR = (PFN_vkWriteAccelerationStructuresPropertiesKHR)load(context, "vkWriteAccelerationStructuresPropertiesKHR");
+#endif /* defined(VK_KHR_acceleration_structure) */
+#if defined(VK_KHR_bind_memory2)
+ table->vkBindBufferMemory2KHR = (PFN_vkBindBufferMemory2KHR)load(context, "vkBindBufferMemory2KHR");
+ table->vkBindImageMemory2KHR = (PFN_vkBindImageMemory2KHR)load(context, "vkBindImageMemory2KHR");
+#endif /* defined(VK_KHR_bind_memory2) */
+#if defined(VK_KHR_buffer_device_address)
+ table->vkGetBufferDeviceAddressKHR = (PFN_vkGetBufferDeviceAddressKHR)load(context, "vkGetBufferDeviceAddressKHR");
+ table->vkGetBufferOpaqueCaptureAddressKHR = (PFN_vkGetBufferOpaqueCaptureAddressKHR)load(context, "vkGetBufferOpaqueCaptureAddressKHR");
+ table->vkGetDeviceMemoryOpaqueCaptureAddressKHR = (PFN_vkGetDeviceMemoryOpaqueCaptureAddressKHR)load(context, "vkGetDeviceMemoryOpaqueCaptureAddressKHR");
+#endif /* defined(VK_KHR_buffer_device_address) */
+#if defined(VK_KHR_copy_commands2)
+ table->vkCmdBlitImage2KHR = (PFN_vkCmdBlitImage2KHR)load(context, "vkCmdBlitImage2KHR");
+ table->vkCmdCopyBuffer2KHR = (PFN_vkCmdCopyBuffer2KHR)load(context, "vkCmdCopyBuffer2KHR");
+ table->vkCmdCopyBufferToImage2KHR = (PFN_vkCmdCopyBufferToImage2KHR)load(context, "vkCmdCopyBufferToImage2KHR");
+ table->vkCmdCopyImage2KHR = (PFN_vkCmdCopyImage2KHR)load(context, "vkCmdCopyImage2KHR");
+ table->vkCmdCopyImageToBuffer2KHR = (PFN_vkCmdCopyImageToBuffer2KHR)load(context, "vkCmdCopyImageToBuffer2KHR");
+ table->vkCmdResolveImage2KHR = (PFN_vkCmdResolveImage2KHR)load(context, "vkCmdResolveImage2KHR");
+#endif /* defined(VK_KHR_copy_commands2) */
+#if defined(VK_KHR_create_renderpass2)
+ table->vkCmdBeginRenderPass2KHR = (PFN_vkCmdBeginRenderPass2KHR)load(context, "vkCmdBeginRenderPass2KHR");
+ table->vkCmdEndRenderPass2KHR = (PFN_vkCmdEndRenderPass2KHR)load(context, "vkCmdEndRenderPass2KHR");
+ table->vkCmdNextSubpass2KHR = (PFN_vkCmdNextSubpass2KHR)load(context, "vkCmdNextSubpass2KHR");
+ table->vkCreateRenderPass2KHR = (PFN_vkCreateRenderPass2KHR)load(context, "vkCreateRenderPass2KHR");
+#endif /* defined(VK_KHR_create_renderpass2) */
+#if defined(VK_KHR_deferred_host_operations)
+ table->vkCreateDeferredOperationKHR = (PFN_vkCreateDeferredOperationKHR)load(context, "vkCreateDeferredOperationKHR");
+ table->vkDeferredOperationJoinKHR = (PFN_vkDeferredOperationJoinKHR)load(context, "vkDeferredOperationJoinKHR");
+ table->vkDestroyDeferredOperationKHR = (PFN_vkDestroyDeferredOperationKHR)load(context, "vkDestroyDeferredOperationKHR");
+ table->vkGetDeferredOperationMaxConcurrencyKHR = (PFN_vkGetDeferredOperationMaxConcurrencyKHR)load(context, "vkGetDeferredOperationMaxConcurrencyKHR");
+ table->vkGetDeferredOperationResultKHR = (PFN_vkGetDeferredOperationResultKHR)load(context, "vkGetDeferredOperationResultKHR");
+#endif /* defined(VK_KHR_deferred_host_operations) */
+#if defined(VK_KHR_descriptor_update_template)
+ table->vkCreateDescriptorUpdateTemplateKHR = (PFN_vkCreateDescriptorUpdateTemplateKHR)load(context, "vkCreateDescriptorUpdateTemplateKHR");
+ table->vkDestroyDescriptorUpdateTemplateKHR = (PFN_vkDestroyDescriptorUpdateTemplateKHR)load(context, "vkDestroyDescriptorUpdateTemplateKHR");
+ table->vkUpdateDescriptorSetWithTemplateKHR = (PFN_vkUpdateDescriptorSetWithTemplateKHR)load(context, "vkUpdateDescriptorSetWithTemplateKHR");
+#endif /* defined(VK_KHR_descriptor_update_template) */
+#if defined(VK_KHR_device_group)
+ table->vkCmdDispatchBaseKHR = (PFN_vkCmdDispatchBaseKHR)load(context, "vkCmdDispatchBaseKHR");
+ table->vkCmdSetDeviceMaskKHR = (PFN_vkCmdSetDeviceMaskKHR)load(context, "vkCmdSetDeviceMaskKHR");
+ table->vkGetDeviceGroupPeerMemoryFeaturesKHR = (PFN_vkGetDeviceGroupPeerMemoryFeaturesKHR)load(context, "vkGetDeviceGroupPeerMemoryFeaturesKHR");
+#endif /* defined(VK_KHR_device_group) */
+#if defined(VK_KHR_display_swapchain)
+ table->vkCreateSharedSwapchainsKHR = (PFN_vkCreateSharedSwapchainsKHR)load(context, "vkCreateSharedSwapchainsKHR");
+#endif /* defined(VK_KHR_display_swapchain) */
+#if defined(VK_KHR_draw_indirect_count)
+ table->vkCmdDrawIndexedIndirectCountKHR = (PFN_vkCmdDrawIndexedIndirectCountKHR)load(context, "vkCmdDrawIndexedIndirectCountKHR");
+ table->vkCmdDrawIndirectCountKHR = (PFN_vkCmdDrawIndirectCountKHR)load(context, "vkCmdDrawIndirectCountKHR");
+#endif /* defined(VK_KHR_draw_indirect_count) */
+#if defined(VK_KHR_dynamic_rendering)
+ table->vkCmdBeginRenderingKHR = (PFN_vkCmdBeginRenderingKHR)load(context, "vkCmdBeginRenderingKHR");
+ table->vkCmdEndRenderingKHR = (PFN_vkCmdEndRenderingKHR)load(context, "vkCmdEndRenderingKHR");
+#endif /* defined(VK_KHR_dynamic_rendering) */
+#if defined(VK_KHR_external_fence_fd)
+ table->vkGetFenceFdKHR = (PFN_vkGetFenceFdKHR)load(context, "vkGetFenceFdKHR");
+ table->vkImportFenceFdKHR = (PFN_vkImportFenceFdKHR)load(context, "vkImportFenceFdKHR");
+#endif /* defined(VK_KHR_external_fence_fd) */
+#if defined(VK_KHR_external_fence_win32)
+ table->vkGetFenceWin32HandleKHR = (PFN_vkGetFenceWin32HandleKHR)load(context, "vkGetFenceWin32HandleKHR");
+ table->vkImportFenceWin32HandleKHR = (PFN_vkImportFenceWin32HandleKHR)load(context, "vkImportFenceWin32HandleKHR");
+#endif /* defined(VK_KHR_external_fence_win32) */
+#if defined(VK_KHR_external_memory_fd)
+ table->vkGetMemoryFdKHR = (PFN_vkGetMemoryFdKHR)load(context, "vkGetMemoryFdKHR");
+ table->vkGetMemoryFdPropertiesKHR = (PFN_vkGetMemoryFdPropertiesKHR)load(context, "vkGetMemoryFdPropertiesKHR");
+#endif /* defined(VK_KHR_external_memory_fd) */
+#if defined(VK_KHR_external_memory_win32)
+ table->vkGetMemoryWin32HandleKHR = (PFN_vkGetMemoryWin32HandleKHR)load(context, "vkGetMemoryWin32HandleKHR");
+ table->vkGetMemoryWin32HandlePropertiesKHR = (PFN_vkGetMemoryWin32HandlePropertiesKHR)load(context, "vkGetMemoryWin32HandlePropertiesKHR");
+#endif /* defined(VK_KHR_external_memory_win32) */
+#if defined(VK_KHR_external_semaphore_fd)
+ table->vkGetSemaphoreFdKHR = (PFN_vkGetSemaphoreFdKHR)load(context, "vkGetSemaphoreFdKHR");
+ table->vkImportSemaphoreFdKHR = (PFN_vkImportSemaphoreFdKHR)load(context, "vkImportSemaphoreFdKHR");
+#endif /* defined(VK_KHR_external_semaphore_fd) */
+#if defined(VK_KHR_external_semaphore_win32)
+ table->vkGetSemaphoreWin32HandleKHR = (PFN_vkGetSemaphoreWin32HandleKHR)load(context, "vkGetSemaphoreWin32HandleKHR");
+ table->vkImportSemaphoreWin32HandleKHR = (PFN_vkImportSemaphoreWin32HandleKHR)load(context, "vkImportSemaphoreWin32HandleKHR");
+#endif /* defined(VK_KHR_external_semaphore_win32) */
+#if defined(VK_KHR_fragment_shading_rate)
+ table->vkCmdSetFragmentShadingRateKHR = (PFN_vkCmdSetFragmentShadingRateKHR)load(context, "vkCmdSetFragmentShadingRateKHR");
+#endif /* defined(VK_KHR_fragment_shading_rate) */
+#if defined(VK_KHR_get_memory_requirements2)
+ table->vkGetBufferMemoryRequirements2KHR = (PFN_vkGetBufferMemoryRequirements2KHR)load(context, "vkGetBufferMemoryRequirements2KHR");
+ table->vkGetImageMemoryRequirements2KHR = (PFN_vkGetImageMemoryRequirements2KHR)load(context, "vkGetImageMemoryRequirements2KHR");
+ table->vkGetImageSparseMemoryRequirements2KHR = (PFN_vkGetImageSparseMemoryRequirements2KHR)load(context, "vkGetImageSparseMemoryRequirements2KHR");
+#endif /* defined(VK_KHR_get_memory_requirements2) */
+#if defined(VK_KHR_maintenance1)
+ table->vkTrimCommandPoolKHR = (PFN_vkTrimCommandPoolKHR)load(context, "vkTrimCommandPoolKHR");
+#endif /* defined(VK_KHR_maintenance1) */
+#if defined(VK_KHR_maintenance3)
+ table->vkGetDescriptorSetLayoutSupportKHR = (PFN_vkGetDescriptorSetLayoutSupportKHR)load(context, "vkGetDescriptorSetLayoutSupportKHR");
+#endif /* defined(VK_KHR_maintenance3) */
+#if defined(VK_KHR_maintenance4)
+ table->vkGetDeviceBufferMemoryRequirementsKHR = (PFN_vkGetDeviceBufferMemoryRequirementsKHR)load(context, "vkGetDeviceBufferMemoryRequirementsKHR");
+ table->vkGetDeviceImageMemoryRequirementsKHR = (PFN_vkGetDeviceImageMemoryRequirementsKHR)load(context, "vkGetDeviceImageMemoryRequirementsKHR");
+ table->vkGetDeviceImageSparseMemoryRequirementsKHR = (PFN_vkGetDeviceImageSparseMemoryRequirementsKHR)load(context, "vkGetDeviceImageSparseMemoryRequirementsKHR");
+#endif /* defined(VK_KHR_maintenance4) */
+#if defined(VK_KHR_performance_query)
+ table->vkAcquireProfilingLockKHR = (PFN_vkAcquireProfilingLockKHR)load(context, "vkAcquireProfilingLockKHR");
+ table->vkReleaseProfilingLockKHR = (PFN_vkReleaseProfilingLockKHR)load(context, "vkReleaseProfilingLockKHR");
+#endif /* defined(VK_KHR_performance_query) */
+#if defined(VK_KHR_pipeline_executable_properties)
+ table->vkGetPipelineExecutableInternalRepresentationsKHR = (PFN_vkGetPipelineExecutableInternalRepresentationsKHR)load(context, "vkGetPipelineExecutableInternalRepresentationsKHR");
+ table->vkGetPipelineExecutablePropertiesKHR = (PFN_vkGetPipelineExecutablePropertiesKHR)load(context, "vkGetPipelineExecutablePropertiesKHR");
+ table->vkGetPipelineExecutableStatisticsKHR = (PFN_vkGetPipelineExecutableStatisticsKHR)load(context, "vkGetPipelineExecutableStatisticsKHR");
+#endif /* defined(VK_KHR_pipeline_executable_properties) */
+#if defined(VK_KHR_present_wait)
+ table->vkWaitForPresentKHR = (PFN_vkWaitForPresentKHR)load(context, "vkWaitForPresentKHR");
+#endif /* defined(VK_KHR_present_wait) */
+#if defined(VK_KHR_push_descriptor)
+ table->vkCmdPushDescriptorSetKHR = (PFN_vkCmdPushDescriptorSetKHR)load(context, "vkCmdPushDescriptorSetKHR");
+#endif /* defined(VK_KHR_push_descriptor) */
+#if defined(VK_KHR_ray_tracing_pipeline)
+ table->vkCmdSetRayTracingPipelineStackSizeKHR = (PFN_vkCmdSetRayTracingPipelineStackSizeKHR)load(context, "vkCmdSetRayTracingPipelineStackSizeKHR");
+ table->vkCmdTraceRaysIndirectKHR = (PFN_vkCmdTraceRaysIndirectKHR)load(context, "vkCmdTraceRaysIndirectKHR");
+ table->vkCmdTraceRaysKHR = (PFN_vkCmdTraceRaysKHR)load(context, "vkCmdTraceRaysKHR");
+ table->vkCreateRayTracingPipelinesKHR = (PFN_vkCreateRayTracingPipelinesKHR)load(context, "vkCreateRayTracingPipelinesKHR");
+ table->vkGetRayTracingCaptureReplayShaderGroupHandlesKHR = (PFN_vkGetRayTracingCaptureReplayShaderGroupHandlesKHR)load(context, "vkGetRayTracingCaptureReplayShaderGroupHandlesKHR");
+ table->vkGetRayTracingShaderGroupHandlesKHR = (PFN_vkGetRayTracingShaderGroupHandlesKHR)load(context, "vkGetRayTracingShaderGroupHandlesKHR");
+ table->vkGetRayTracingShaderGroupStackSizeKHR = (PFN_vkGetRayTracingShaderGroupStackSizeKHR)load(context, "vkGetRayTracingShaderGroupStackSizeKHR");
+#endif /* defined(VK_KHR_ray_tracing_pipeline) */
+#if defined(VK_KHR_sampler_ycbcr_conversion)
+ table->vkCreateSamplerYcbcrConversionKHR = (PFN_vkCreateSamplerYcbcrConversionKHR)load(context, "vkCreateSamplerYcbcrConversionKHR");
+ table->vkDestroySamplerYcbcrConversionKHR = (PFN_vkDestroySamplerYcbcrConversionKHR)load(context, "vkDestroySamplerYcbcrConversionKHR");
+#endif /* defined(VK_KHR_sampler_ycbcr_conversion) */
+#if defined(VK_KHR_shared_presentable_image)
+ table->vkGetSwapchainStatusKHR = (PFN_vkGetSwapchainStatusKHR)load(context, "vkGetSwapchainStatusKHR");
+#endif /* defined(VK_KHR_shared_presentable_image) */
+#if defined(VK_KHR_swapchain)
+ table->vkAcquireNextImageKHR = (PFN_vkAcquireNextImageKHR)load(context, "vkAcquireNextImageKHR");
+ table->vkCreateSwapchainKHR = (PFN_vkCreateSwapchainKHR)load(context, "vkCreateSwapchainKHR");
+ table->vkDestroySwapchainKHR = (PFN_vkDestroySwapchainKHR)load(context, "vkDestroySwapchainKHR");
+ table->vkGetSwapchainImagesKHR = (PFN_vkGetSwapchainImagesKHR)load(context, "vkGetSwapchainImagesKHR");
+ table->vkQueuePresentKHR = (PFN_vkQueuePresentKHR)load(context, "vkQueuePresentKHR");
+#endif /* defined(VK_KHR_swapchain) */
+#if defined(VK_KHR_synchronization2)
+ table->vkCmdPipelineBarrier2KHR = (PFN_vkCmdPipelineBarrier2KHR)load(context, "vkCmdPipelineBarrier2KHR");
+ table->vkCmdResetEvent2KHR = (PFN_vkCmdResetEvent2KHR)load(context, "vkCmdResetEvent2KHR");
+ table->vkCmdSetEvent2KHR = (PFN_vkCmdSetEvent2KHR)load(context, "vkCmdSetEvent2KHR");
+ table->vkCmdWaitEvents2KHR = (PFN_vkCmdWaitEvents2KHR)load(context, "vkCmdWaitEvents2KHR");
+ table->vkCmdWriteTimestamp2KHR = (PFN_vkCmdWriteTimestamp2KHR)load(context, "vkCmdWriteTimestamp2KHR");
+ table->vkQueueSubmit2KHR = (PFN_vkQueueSubmit2KHR)load(context, "vkQueueSubmit2KHR");
+#endif /* defined(VK_KHR_synchronization2) */
+#if defined(VK_KHR_synchronization2) && defined(VK_AMD_buffer_marker)
+ table->vkCmdWriteBufferMarker2AMD = (PFN_vkCmdWriteBufferMarker2AMD)load(context, "vkCmdWriteBufferMarker2AMD");
+#endif /* defined(VK_KHR_synchronization2) && defined(VK_AMD_buffer_marker) */
+#if defined(VK_KHR_synchronization2) && defined(VK_NV_device_diagnostic_checkpoints)
+ table->vkGetQueueCheckpointData2NV = (PFN_vkGetQueueCheckpointData2NV)load(context, "vkGetQueueCheckpointData2NV");
+#endif /* defined(VK_KHR_synchronization2) && defined(VK_NV_device_diagnostic_checkpoints) */
+#if defined(VK_KHR_timeline_semaphore)
+ table->vkGetSemaphoreCounterValueKHR = (PFN_vkGetSemaphoreCounterValueKHR)load(context, "vkGetSemaphoreCounterValueKHR");
+ table->vkSignalSemaphoreKHR = (PFN_vkSignalSemaphoreKHR)load(context, "vkSignalSemaphoreKHR");
+ table->vkWaitSemaphoresKHR = (PFN_vkWaitSemaphoresKHR)load(context, "vkWaitSemaphoresKHR");
+#endif /* defined(VK_KHR_timeline_semaphore) */
+#if defined(VK_KHR_video_decode_queue)
+ table->vkCmdDecodeVideoKHR = (PFN_vkCmdDecodeVideoKHR)load(context, "vkCmdDecodeVideoKHR");
+#endif /* defined(VK_KHR_video_decode_queue) */
+#if defined(VK_KHR_video_encode_queue)
+ table->vkCmdEncodeVideoKHR = (PFN_vkCmdEncodeVideoKHR)load(context, "vkCmdEncodeVideoKHR");
+#endif /* defined(VK_KHR_video_encode_queue) */
+#if defined(VK_KHR_video_queue)
+ table->vkBindVideoSessionMemoryKHR = (PFN_vkBindVideoSessionMemoryKHR)load(context, "vkBindVideoSessionMemoryKHR");
+ table->vkCmdBeginVideoCodingKHR = (PFN_vkCmdBeginVideoCodingKHR)load(context, "vkCmdBeginVideoCodingKHR");
+ table->vkCmdControlVideoCodingKHR = (PFN_vkCmdControlVideoCodingKHR)load(context, "vkCmdControlVideoCodingKHR");
+ table->vkCmdEndVideoCodingKHR = (PFN_vkCmdEndVideoCodingKHR)load(context, "vkCmdEndVideoCodingKHR");
+ table->vkCreateVideoSessionKHR = (PFN_vkCreateVideoSessionKHR)load(context, "vkCreateVideoSessionKHR");
+ table->vkCreateVideoSessionParametersKHR = (PFN_vkCreateVideoSessionParametersKHR)load(context, "vkCreateVideoSessionParametersKHR");
+ table->vkDestroyVideoSessionKHR = (PFN_vkDestroyVideoSessionKHR)load(context, "vkDestroyVideoSessionKHR");
+ table->vkDestroyVideoSessionParametersKHR = (PFN_vkDestroyVideoSessionParametersKHR)load(context, "vkDestroyVideoSessionParametersKHR");
+ table->vkGetVideoSessionMemoryRequirementsKHR = (PFN_vkGetVideoSessionMemoryRequirementsKHR)load(context, "vkGetVideoSessionMemoryRequirementsKHR");
+ table->vkUpdateVideoSessionParametersKHR = (PFN_vkUpdateVideoSessionParametersKHR)load(context, "vkUpdateVideoSessionParametersKHR");
+#endif /* defined(VK_KHR_video_queue) */
+#if defined(VK_NVX_binary_import)
+ table->vkCmdCuLaunchKernelNVX = (PFN_vkCmdCuLaunchKernelNVX)load(context, "vkCmdCuLaunchKernelNVX");
+ table->vkCreateCuFunctionNVX = (PFN_vkCreateCuFunctionNVX)load(context, "vkCreateCuFunctionNVX");
+ table->vkCreateCuModuleNVX = (PFN_vkCreateCuModuleNVX)load(context, "vkCreateCuModuleNVX");
+ table->vkDestroyCuFunctionNVX = (PFN_vkDestroyCuFunctionNVX)load(context, "vkDestroyCuFunctionNVX");
+ table->vkDestroyCuModuleNVX = (PFN_vkDestroyCuModuleNVX)load(context, "vkDestroyCuModuleNVX");
+#endif /* defined(VK_NVX_binary_import) */
+#if defined(VK_NVX_image_view_handle)
+ table->vkGetImageViewAddressNVX = (PFN_vkGetImageViewAddressNVX)load(context, "vkGetImageViewAddressNVX");
+ table->vkGetImageViewHandleNVX = (PFN_vkGetImageViewHandleNVX)load(context, "vkGetImageViewHandleNVX");
+#endif /* defined(VK_NVX_image_view_handle) */
+#if defined(VK_NV_clip_space_w_scaling)
+ table->vkCmdSetViewportWScalingNV = (PFN_vkCmdSetViewportWScalingNV)load(context, "vkCmdSetViewportWScalingNV");
+#endif /* defined(VK_NV_clip_space_w_scaling) */
+#if defined(VK_NV_device_diagnostic_checkpoints)
+ table->vkCmdSetCheckpointNV = (PFN_vkCmdSetCheckpointNV)load(context, "vkCmdSetCheckpointNV");
+ table->vkGetQueueCheckpointDataNV = (PFN_vkGetQueueCheckpointDataNV)load(context, "vkGetQueueCheckpointDataNV");
+#endif /* defined(VK_NV_device_diagnostic_checkpoints) */
+#if defined(VK_NV_device_generated_commands)
+ table->vkCmdBindPipelineShaderGroupNV = (PFN_vkCmdBindPipelineShaderGroupNV)load(context, "vkCmdBindPipelineShaderGroupNV");
+ table->vkCmdExecuteGeneratedCommandsNV = (PFN_vkCmdExecuteGeneratedCommandsNV)load(context, "vkCmdExecuteGeneratedCommandsNV");
+ table->vkCmdPreprocessGeneratedCommandsNV = (PFN_vkCmdPreprocessGeneratedCommandsNV)load(context, "vkCmdPreprocessGeneratedCommandsNV");
+ table->vkCreateIndirectCommandsLayoutNV = (PFN_vkCreateIndirectCommandsLayoutNV)load(context, "vkCreateIndirectCommandsLayoutNV");
+ table->vkDestroyIndirectCommandsLayoutNV = (PFN_vkDestroyIndirectCommandsLayoutNV)load(context, "vkDestroyIndirectCommandsLayoutNV");
+ table->vkGetGeneratedCommandsMemoryRequirementsNV = (PFN_vkGetGeneratedCommandsMemoryRequirementsNV)load(context, "vkGetGeneratedCommandsMemoryRequirementsNV");
+#endif /* defined(VK_NV_device_generated_commands) */
+#if defined(VK_NV_external_memory_rdma)
+ table->vkGetMemoryRemoteAddressNV = (PFN_vkGetMemoryRemoteAddressNV)load(context, "vkGetMemoryRemoteAddressNV");
+#endif /* defined(VK_NV_external_memory_rdma) */
+#if defined(VK_NV_external_memory_win32)
+ table->vkGetMemoryWin32HandleNV = (PFN_vkGetMemoryWin32HandleNV)load(context, "vkGetMemoryWin32HandleNV");
+#endif /* defined(VK_NV_external_memory_win32) */
+#if defined(VK_NV_fragment_shading_rate_enums)
+ table->vkCmdSetFragmentShadingRateEnumNV = (PFN_vkCmdSetFragmentShadingRateEnumNV)load(context, "vkCmdSetFragmentShadingRateEnumNV");
+#endif /* defined(VK_NV_fragment_shading_rate_enums) */
+#if defined(VK_NV_mesh_shader)
+ table->vkCmdDrawMeshTasksIndirectCountNV = (PFN_vkCmdDrawMeshTasksIndirectCountNV)load(context, "vkCmdDrawMeshTasksIndirectCountNV");
+ table->vkCmdDrawMeshTasksIndirectNV = (PFN_vkCmdDrawMeshTasksIndirectNV)load(context, "vkCmdDrawMeshTasksIndirectNV");
+ table->vkCmdDrawMeshTasksNV = (PFN_vkCmdDrawMeshTasksNV)load(context, "vkCmdDrawMeshTasksNV");
+#endif /* defined(VK_NV_mesh_shader) */
+#if defined(VK_NV_ray_tracing)
+ table->vkBindAccelerationStructureMemoryNV = (PFN_vkBindAccelerationStructureMemoryNV)load(context, "vkBindAccelerationStructureMemoryNV");
+ table->vkCmdBuildAccelerationStructureNV = (PFN_vkCmdBuildAccelerationStructureNV)load(context, "vkCmdBuildAccelerationStructureNV");
+ table->vkCmdCopyAccelerationStructureNV = (PFN_vkCmdCopyAccelerationStructureNV)load(context, "vkCmdCopyAccelerationStructureNV");
+ table->vkCmdTraceRaysNV = (PFN_vkCmdTraceRaysNV)load(context, "vkCmdTraceRaysNV");
+ table->vkCmdWriteAccelerationStructuresPropertiesNV = (PFN_vkCmdWriteAccelerationStructuresPropertiesNV)load(context, "vkCmdWriteAccelerationStructuresPropertiesNV");
+ table->vkCompileDeferredNV = (PFN_vkCompileDeferredNV)load(context, "vkCompileDeferredNV");
+ table->vkCreateAccelerationStructureNV = (PFN_vkCreateAccelerationStructureNV)load(context, "vkCreateAccelerationStructureNV");
+ table->vkCreateRayTracingPipelinesNV = (PFN_vkCreateRayTracingPipelinesNV)load(context, "vkCreateRayTracingPipelinesNV");
+ table->vkDestroyAccelerationStructureNV = (PFN_vkDestroyAccelerationStructureNV)load(context, "vkDestroyAccelerationStructureNV");
+ table->vkGetAccelerationStructureHandleNV = (PFN_vkGetAccelerationStructureHandleNV)load(context, "vkGetAccelerationStructureHandleNV");
+ table->vkGetAccelerationStructureMemoryRequirementsNV = (PFN_vkGetAccelerationStructureMemoryRequirementsNV)load(context, "vkGetAccelerationStructureMemoryRequirementsNV");
+ table->vkGetRayTracingShaderGroupHandlesNV = (PFN_vkGetRayTracingShaderGroupHandlesNV)load(context, "vkGetRayTracingShaderGroupHandlesNV");
+#endif /* defined(VK_NV_ray_tracing) */
+#if defined(VK_NV_scissor_exclusive)
+ table->vkCmdSetExclusiveScissorNV = (PFN_vkCmdSetExclusiveScissorNV)load(context, "vkCmdSetExclusiveScissorNV");
+#endif /* defined(VK_NV_scissor_exclusive) */
+#if defined(VK_NV_shading_rate_image)
+ table->vkCmdBindShadingRateImageNV = (PFN_vkCmdBindShadingRateImageNV)load(context, "vkCmdBindShadingRateImageNV");
+ table->vkCmdSetCoarseSampleOrderNV = (PFN_vkCmdSetCoarseSampleOrderNV)load(context, "vkCmdSetCoarseSampleOrderNV");
+ table->vkCmdSetViewportShadingRatePaletteNV = (PFN_vkCmdSetViewportShadingRatePaletteNV)load(context, "vkCmdSetViewportShadingRatePaletteNV");
+#endif /* defined(VK_NV_shading_rate_image) */
+#if (defined(VK_EXT_full_screen_exclusive) && defined(VK_KHR_device_group)) || (defined(VK_EXT_full_screen_exclusive) && defined(VK_VERSION_1_1))
+ table->vkGetDeviceGroupSurfacePresentModes2EXT = (PFN_vkGetDeviceGroupSurfacePresentModes2EXT)load(context, "vkGetDeviceGroupSurfacePresentModes2EXT");
+#endif /* (defined(VK_EXT_full_screen_exclusive) && defined(VK_KHR_device_group)) || (defined(VK_EXT_full_screen_exclusive) && defined(VK_VERSION_1_1)) */
+#if (defined(VK_KHR_descriptor_update_template) && defined(VK_KHR_push_descriptor)) || (defined(VK_KHR_push_descriptor) && defined(VK_VERSION_1_1)) || (defined(VK_KHR_push_descriptor) && defined(VK_KHR_descriptor_update_template))
+ table->vkCmdPushDescriptorSetWithTemplateKHR = (PFN_vkCmdPushDescriptorSetWithTemplateKHR)load(context, "vkCmdPushDescriptorSetWithTemplateKHR");
+#endif /* (defined(VK_KHR_descriptor_update_template) && defined(VK_KHR_push_descriptor)) || (defined(VK_KHR_push_descriptor) && defined(VK_VERSION_1_1)) || (defined(VK_KHR_push_descriptor) && defined(VK_KHR_descriptor_update_template)) */
+#if (defined(VK_KHR_device_group) && defined(VK_KHR_surface)) || (defined(VK_KHR_swapchain) && defined(VK_VERSION_1_1))
+ table->vkGetDeviceGroupPresentCapabilitiesKHR = (PFN_vkGetDeviceGroupPresentCapabilitiesKHR)load(context, "vkGetDeviceGroupPresentCapabilitiesKHR");
+ table->vkGetDeviceGroupSurfacePresentModesKHR = (PFN_vkGetDeviceGroupSurfacePresentModesKHR)load(context, "vkGetDeviceGroupSurfacePresentModesKHR");
+#endif /* (defined(VK_KHR_device_group) && defined(VK_KHR_surface)) || (defined(VK_KHR_swapchain) && defined(VK_VERSION_1_1)) */
+#if (defined(VK_KHR_device_group) && defined(VK_KHR_swapchain)) || (defined(VK_KHR_swapchain) && defined(VK_VERSION_1_1))
+ table->vkAcquireNextImage2KHR = (PFN_vkAcquireNextImage2KHR)load(context, "vkAcquireNextImage2KHR");
+#endif /* (defined(VK_KHR_device_group) && defined(VK_KHR_swapchain)) || (defined(VK_KHR_swapchain) && defined(VK_VERSION_1_1)) */
+ /* VOLK_GENERATE_LOAD_DEVICE_TABLE */
+}
+
+#ifdef __GNUC__
+#ifdef VOLK_DEFAULT_VISIBILITY
+# pragma GCC visibility push(default)
+#else
+# pragma GCC visibility push(hidden)
+#endif
+#endif
+
+/* VOLK_GENERATE_PROTOTYPES_C */
+#if defined(VK_VERSION_1_0)
+PFN_vkAllocateCommandBuffers vkAllocateCommandBuffers;
+PFN_vkAllocateDescriptorSets vkAllocateDescriptorSets;
+PFN_vkAllocateMemory vkAllocateMemory;
+PFN_vkBeginCommandBuffer vkBeginCommandBuffer;
+PFN_vkBindBufferMemory vkBindBufferMemory;
+PFN_vkBindImageMemory vkBindImageMemory;
+PFN_vkCmdBeginQuery vkCmdBeginQuery;
+PFN_vkCmdBeginRenderPass vkCmdBeginRenderPass;
+PFN_vkCmdBindDescriptorSets vkCmdBindDescriptorSets;
+PFN_vkCmdBindIndexBuffer vkCmdBindIndexBuffer;
+PFN_vkCmdBindPipeline vkCmdBindPipeline;
+PFN_vkCmdBindVertexBuffers vkCmdBindVertexBuffers;
+PFN_vkCmdBlitImage vkCmdBlitImage;
+PFN_vkCmdClearAttachments vkCmdClearAttachments;
+PFN_vkCmdClearColorImage vkCmdClearColorImage;
+PFN_vkCmdClearDepthStencilImage vkCmdClearDepthStencilImage;
+PFN_vkCmdCopyBuffer vkCmdCopyBuffer;
+PFN_vkCmdCopyBufferToImage vkCmdCopyBufferToImage;
+PFN_vkCmdCopyImage vkCmdCopyImage;
+PFN_vkCmdCopyImageToBuffer vkCmdCopyImageToBuffer;
+PFN_vkCmdCopyQueryPoolResults vkCmdCopyQueryPoolResults;
+PFN_vkCmdDispatch vkCmdDispatch;
+PFN_vkCmdDispatchIndirect vkCmdDispatchIndirect;
+PFN_vkCmdDraw vkCmdDraw;
+PFN_vkCmdDrawIndexed vkCmdDrawIndexed;
+PFN_vkCmdDrawIndexedIndirect vkCmdDrawIndexedIndirect;
+PFN_vkCmdDrawIndirect vkCmdDrawIndirect;
+PFN_vkCmdEndQuery vkCmdEndQuery;
+PFN_vkCmdEndRenderPass vkCmdEndRenderPass;
+PFN_vkCmdExecuteCommands vkCmdExecuteCommands;
+PFN_vkCmdFillBuffer vkCmdFillBuffer;
+PFN_vkCmdNextSubpass vkCmdNextSubpass;
+PFN_vkCmdPipelineBarrier vkCmdPipelineBarrier;
+PFN_vkCmdPushConstants vkCmdPushConstants;
+PFN_vkCmdResetEvent vkCmdResetEvent;
+PFN_vkCmdResetQueryPool vkCmdResetQueryPool;
+PFN_vkCmdResolveImage vkCmdResolveImage;
+PFN_vkCmdSetBlendConstants vkCmdSetBlendConstants;
+PFN_vkCmdSetDepthBias vkCmdSetDepthBias;
+PFN_vkCmdSetDepthBounds vkCmdSetDepthBounds;
+PFN_vkCmdSetEvent vkCmdSetEvent;
+PFN_vkCmdSetLineWidth vkCmdSetLineWidth;
+PFN_vkCmdSetScissor vkCmdSetScissor;
+PFN_vkCmdSetStencilCompareMask vkCmdSetStencilCompareMask;
+PFN_vkCmdSetStencilReference vkCmdSetStencilReference;
+PFN_vkCmdSetStencilWriteMask vkCmdSetStencilWriteMask;
+PFN_vkCmdSetViewport vkCmdSetViewport;
+PFN_vkCmdUpdateBuffer vkCmdUpdateBuffer;
+PFN_vkCmdWaitEvents vkCmdWaitEvents;
+PFN_vkCmdWriteTimestamp vkCmdWriteTimestamp;
+PFN_vkCreateBuffer vkCreateBuffer;
+PFN_vkCreateBufferView vkCreateBufferView;
+PFN_vkCreateCommandPool vkCreateCommandPool;
+PFN_vkCreateComputePipelines vkCreateComputePipelines;
+PFN_vkCreateDescriptorPool vkCreateDescriptorPool;
+PFN_vkCreateDescriptorSetLayout vkCreateDescriptorSetLayout;
+PFN_vkCreateDevice vkCreateDevice;
+PFN_vkCreateEvent vkCreateEvent;
+PFN_vkCreateFence vkCreateFence;
+PFN_vkCreateFramebuffer vkCreateFramebuffer;
+PFN_vkCreateGraphicsPipelines vkCreateGraphicsPipelines;
+PFN_vkCreateImage vkCreateImage;
+PFN_vkCreateImageView vkCreateImageView;
+PFN_vkCreateInstance vkCreateInstance;
+PFN_vkCreatePipelineCache vkCreatePipelineCache;
+PFN_vkCreatePipelineLayout vkCreatePipelineLayout;
+PFN_vkCreateQueryPool vkCreateQueryPool;
+PFN_vkCreateRenderPass vkCreateRenderPass;
+PFN_vkCreateSampler vkCreateSampler;
+PFN_vkCreateSemaphore vkCreateSemaphore;
+PFN_vkCreateShaderModule vkCreateShaderModule;
+PFN_vkDestroyBuffer vkDestroyBuffer;
+PFN_vkDestroyBufferView vkDestroyBufferView;
+PFN_vkDestroyCommandPool vkDestroyCommandPool;
+PFN_vkDestroyDescriptorPool vkDestroyDescriptorPool;
+PFN_vkDestroyDescriptorSetLayout vkDestroyDescriptorSetLayout;
+PFN_vkDestroyDevice vkDestroyDevice;
+PFN_vkDestroyEvent vkDestroyEvent;
+PFN_vkDestroyFence vkDestroyFence;
+PFN_vkDestroyFramebuffer vkDestroyFramebuffer;
+PFN_vkDestroyImage vkDestroyImage;
+PFN_vkDestroyImageView vkDestroyImageView;
+PFN_vkDestroyInstance vkDestroyInstance;
+PFN_vkDestroyPipeline vkDestroyPipeline;
+PFN_vkDestroyPipelineCache vkDestroyPipelineCache;
+PFN_vkDestroyPipelineLayout vkDestroyPipelineLayout;
+PFN_vkDestroyQueryPool vkDestroyQueryPool;
+PFN_vkDestroyRenderPass vkDestroyRenderPass;
+PFN_vkDestroySampler vkDestroySampler;
+PFN_vkDestroySemaphore vkDestroySemaphore;
+PFN_vkDestroyShaderModule vkDestroyShaderModule;
+PFN_vkDeviceWaitIdle vkDeviceWaitIdle;
+PFN_vkEndCommandBuffer vkEndCommandBuffer;
+PFN_vkEnumerateDeviceExtensionProperties vkEnumerateDeviceExtensionProperties;
+PFN_vkEnumerateDeviceLayerProperties vkEnumerateDeviceLayerProperties;
+PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties;
+PFN_vkEnumerateInstanceLayerProperties vkEnumerateInstanceLayerProperties;
+PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices;
+PFN_vkFlushMappedMemoryRanges vkFlushMappedMemoryRanges;
+PFN_vkFreeCommandBuffers vkFreeCommandBuffers;
+PFN_vkFreeDescriptorSets vkFreeDescriptorSets;
+PFN_vkFreeMemory vkFreeMemory;
+PFN_vkGetBufferMemoryRequirements vkGetBufferMemoryRequirements;
+PFN_vkGetDeviceMemoryCommitment vkGetDeviceMemoryCommitment;
+PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr;
+PFN_vkGetDeviceQueue vkGetDeviceQueue;
+PFN_vkGetEventStatus vkGetEventStatus;
+PFN_vkGetFenceStatus vkGetFenceStatus;
+PFN_vkGetImageMemoryRequirements vkGetImageMemoryRequirements;
+PFN_vkGetImageSparseMemoryRequirements vkGetImageSparseMemoryRequirements;
+PFN_vkGetImageSubresourceLayout vkGetImageSubresourceLayout;
+PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr;
+PFN_vkGetPhysicalDeviceFeatures vkGetPhysicalDeviceFeatures;
+PFN_vkGetPhysicalDeviceFormatProperties vkGetPhysicalDeviceFormatProperties;
+PFN_vkGetPhysicalDeviceImageFormatProperties vkGetPhysicalDeviceImageFormatProperties;
+PFN_vkGetPhysicalDeviceMemoryProperties vkGetPhysicalDeviceMemoryProperties;
+PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties;
+PFN_vkGetPhysicalDeviceQueueFamilyProperties vkGetPhysicalDeviceQueueFamilyProperties;
+PFN_vkGetPhysicalDeviceSparseImageFormatProperties vkGetPhysicalDeviceSparseImageFormatProperties;
+PFN_vkGetPipelineCacheData vkGetPipelineCacheData;
+PFN_vkGetQueryPoolResults vkGetQueryPoolResults;
+PFN_vkGetRenderAreaGranularity vkGetRenderAreaGranularity;
+PFN_vkInvalidateMappedMemoryRanges vkInvalidateMappedMemoryRanges;
+PFN_vkMapMemory vkMapMemory;
+PFN_vkMergePipelineCaches vkMergePipelineCaches;
+PFN_vkQueueBindSparse vkQueueBindSparse;
+PFN_vkQueueSubmit vkQueueSubmit;
+PFN_vkQueueWaitIdle vkQueueWaitIdle;
+PFN_vkResetCommandBuffer vkResetCommandBuffer;
+PFN_vkResetCommandPool vkResetCommandPool;
+PFN_vkResetDescriptorPool vkResetDescriptorPool;
+PFN_vkResetEvent vkResetEvent;
+PFN_vkResetFences vkResetFences;
+PFN_vkSetEvent vkSetEvent;
+PFN_vkUnmapMemory vkUnmapMemory;
+PFN_vkUpdateDescriptorSets vkUpdateDescriptorSets;
+PFN_vkWaitForFences vkWaitForFences;
+#endif /* defined(VK_VERSION_1_0) */
+#if defined(VK_VERSION_1_1)
+PFN_vkBindBufferMemory2 vkBindBufferMemory2;
+PFN_vkBindImageMemory2 vkBindImageMemory2;
+PFN_vkCmdDispatchBase vkCmdDispatchBase;
+PFN_vkCmdSetDeviceMask vkCmdSetDeviceMask;
+PFN_vkCreateDescriptorUpdateTemplate vkCreateDescriptorUpdateTemplate;
+PFN_vkCreateSamplerYcbcrConversion vkCreateSamplerYcbcrConversion;
+PFN_vkDestroyDescriptorUpdateTemplate vkDestroyDescriptorUpdateTemplate;
+PFN_vkDestroySamplerYcbcrConversion vkDestroySamplerYcbcrConversion;
+PFN_vkEnumerateInstanceVersion vkEnumerateInstanceVersion;
+PFN_vkEnumeratePhysicalDeviceGroups vkEnumeratePhysicalDeviceGroups;
+PFN_vkGetBufferMemoryRequirements2 vkGetBufferMemoryRequirements2;
+PFN_vkGetDescriptorSetLayoutSupport vkGetDescriptorSetLayoutSupport;
+PFN_vkGetDeviceGroupPeerMemoryFeatures vkGetDeviceGroupPeerMemoryFeatures;
+PFN_vkGetDeviceQueue2 vkGetDeviceQueue2;
+PFN_vkGetImageMemoryRequirements2 vkGetImageMemoryRequirements2;
+PFN_vkGetImageSparseMemoryRequirements2 vkGetImageSparseMemoryRequirements2;
+PFN_vkGetPhysicalDeviceExternalBufferProperties vkGetPhysicalDeviceExternalBufferProperties;
+PFN_vkGetPhysicalDeviceExternalFenceProperties vkGetPhysicalDeviceExternalFenceProperties;
+PFN_vkGetPhysicalDeviceExternalSemaphoreProperties vkGetPhysicalDeviceExternalSemaphoreProperties;
+PFN_vkGetPhysicalDeviceFeatures2 vkGetPhysicalDeviceFeatures2;
+PFN_vkGetPhysicalDeviceFormatProperties2 vkGetPhysicalDeviceFormatProperties2;
+PFN_vkGetPhysicalDeviceImageFormatProperties2 vkGetPhysicalDeviceImageFormatProperties2;
+PFN_vkGetPhysicalDeviceMemoryProperties2 vkGetPhysicalDeviceMemoryProperties2;
+PFN_vkGetPhysicalDeviceProperties2 vkGetPhysicalDeviceProperties2;
+PFN_vkGetPhysicalDeviceQueueFamilyProperties2 vkGetPhysicalDeviceQueueFamilyProperties2;
+PFN_vkGetPhysicalDeviceSparseImageFormatProperties2 vkGetPhysicalDeviceSparseImageFormatProperties2;
+PFN_vkTrimCommandPool vkTrimCommandPool;
+PFN_vkUpdateDescriptorSetWithTemplate vkUpdateDescriptorSetWithTemplate;
+#endif /* defined(VK_VERSION_1_1) */
+#if defined(VK_VERSION_1_2)
+PFN_vkCmdBeginRenderPass2 vkCmdBeginRenderPass2;
+PFN_vkCmdDrawIndexedIndirectCount vkCmdDrawIndexedIndirectCount;
+PFN_vkCmdDrawIndirectCount vkCmdDrawIndirectCount;
+PFN_vkCmdEndRenderPass2 vkCmdEndRenderPass2;
+PFN_vkCmdNextSubpass2 vkCmdNextSubpass2;
+PFN_vkCreateRenderPass2 vkCreateRenderPass2;
+PFN_vkGetBufferDeviceAddress vkGetBufferDeviceAddress;
+PFN_vkGetBufferOpaqueCaptureAddress vkGetBufferOpaqueCaptureAddress;
+PFN_vkGetDeviceMemoryOpaqueCaptureAddress vkGetDeviceMemoryOpaqueCaptureAddress;
+PFN_vkGetSemaphoreCounterValue vkGetSemaphoreCounterValue;
+PFN_vkResetQueryPool vkResetQueryPool;
+PFN_vkSignalSemaphore vkSignalSemaphore;
+PFN_vkWaitSemaphores vkWaitSemaphores;
+#endif /* defined(VK_VERSION_1_2) */
+#if defined(VK_VERSION_1_3)
+PFN_vkCmdBeginRendering vkCmdBeginRendering;
+PFN_vkCmdBindVertexBuffers2 vkCmdBindVertexBuffers2;
+PFN_vkCmdBlitImage2 vkCmdBlitImage2;
+PFN_vkCmdCopyBuffer2 vkCmdCopyBuffer2;
+PFN_vkCmdCopyBufferToImage2 vkCmdCopyBufferToImage2;
+PFN_vkCmdCopyImage2 vkCmdCopyImage2;
+PFN_vkCmdCopyImageToBuffer2 vkCmdCopyImageToBuffer2;
+PFN_vkCmdEndRendering vkCmdEndRendering;
+PFN_vkCmdPipelineBarrier2 vkCmdPipelineBarrier2;
+PFN_vkCmdResetEvent2 vkCmdResetEvent2;
+PFN_vkCmdResolveImage2 vkCmdResolveImage2;
+PFN_vkCmdSetCullMode vkCmdSetCullMode;
+PFN_vkCmdSetDepthBiasEnable vkCmdSetDepthBiasEnable;
+PFN_vkCmdSetDepthBoundsTestEnable vkCmdSetDepthBoundsTestEnable;
+PFN_vkCmdSetDepthCompareOp vkCmdSetDepthCompareOp;
+PFN_vkCmdSetDepthTestEnable vkCmdSetDepthTestEnable;
+PFN_vkCmdSetDepthWriteEnable vkCmdSetDepthWriteEnable;
+PFN_vkCmdSetEvent2 vkCmdSetEvent2;
+PFN_vkCmdSetFrontFace vkCmdSetFrontFace;
+PFN_vkCmdSetPrimitiveRestartEnable vkCmdSetPrimitiveRestartEnable;
+PFN_vkCmdSetPrimitiveTopology vkCmdSetPrimitiveTopology;
+PFN_vkCmdSetRasterizerDiscardEnable vkCmdSetRasterizerDiscardEnable;
+PFN_vkCmdSetScissorWithCount vkCmdSetScissorWithCount;
+PFN_vkCmdSetStencilOp vkCmdSetStencilOp;
+PFN_vkCmdSetStencilTestEnable vkCmdSetStencilTestEnable;
+PFN_vkCmdSetViewportWithCount vkCmdSetViewportWithCount;
+PFN_vkCmdWaitEvents2 vkCmdWaitEvents2;
+PFN_vkCmdWriteTimestamp2 vkCmdWriteTimestamp2;
+PFN_vkCreatePrivateDataSlot vkCreatePrivateDataSlot;
+PFN_vkDestroyPrivateDataSlot vkDestroyPrivateDataSlot;
+PFN_vkGetDeviceBufferMemoryRequirements vkGetDeviceBufferMemoryRequirements;
+PFN_vkGetDeviceImageMemoryRequirements vkGetDeviceImageMemoryRequirements;
+PFN_vkGetDeviceImageSparseMemoryRequirements vkGetDeviceImageSparseMemoryRequirements;
+PFN_vkGetPhysicalDeviceToolProperties vkGetPhysicalDeviceToolProperties;
+PFN_vkGetPrivateData vkGetPrivateData;
+PFN_vkQueueSubmit2 vkQueueSubmit2;
+PFN_vkSetPrivateData vkSetPrivateData;
+#endif /* defined(VK_VERSION_1_3) */
+#if defined(VK_AMD_buffer_marker)
+PFN_vkCmdWriteBufferMarkerAMD vkCmdWriteBufferMarkerAMD;
+#endif /* defined(VK_AMD_buffer_marker) */
+#if defined(VK_AMD_display_native_hdr)
+PFN_vkSetLocalDimmingAMD vkSetLocalDimmingAMD;
+#endif /* defined(VK_AMD_display_native_hdr) */
+#if defined(VK_AMD_draw_indirect_count)
+PFN_vkCmdDrawIndexedIndirectCountAMD vkCmdDrawIndexedIndirectCountAMD;
+PFN_vkCmdDrawIndirectCountAMD vkCmdDrawIndirectCountAMD;
+#endif /* defined(VK_AMD_draw_indirect_count) */
+#if defined(VK_AMD_shader_info)
+PFN_vkGetShaderInfoAMD vkGetShaderInfoAMD;
+#endif /* defined(VK_AMD_shader_info) */
+#if defined(VK_ANDROID_external_memory_android_hardware_buffer)
+PFN_vkGetAndroidHardwareBufferPropertiesANDROID vkGetAndroidHardwareBufferPropertiesANDROID;
+PFN_vkGetMemoryAndroidHardwareBufferANDROID vkGetMemoryAndroidHardwareBufferANDROID;
+#endif /* defined(VK_ANDROID_external_memory_android_hardware_buffer) */
+#if defined(VK_EXT_acquire_drm_display)
+PFN_vkAcquireDrmDisplayEXT vkAcquireDrmDisplayEXT;
+PFN_vkGetDrmDisplayEXT vkGetDrmDisplayEXT;
+#endif /* defined(VK_EXT_acquire_drm_display) */
+#if defined(VK_EXT_acquire_xlib_display)
+PFN_vkAcquireXlibDisplayEXT vkAcquireXlibDisplayEXT;
+PFN_vkGetRandROutputDisplayEXT vkGetRandROutputDisplayEXT;
+#endif /* defined(VK_EXT_acquire_xlib_display) */
+#if defined(VK_EXT_buffer_device_address)
+PFN_vkGetBufferDeviceAddressEXT vkGetBufferDeviceAddressEXT;
+#endif /* defined(VK_EXT_buffer_device_address) */
+#if defined(VK_EXT_calibrated_timestamps)
+PFN_vkGetCalibratedTimestampsEXT vkGetCalibratedTimestampsEXT;
+PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT vkGetPhysicalDeviceCalibrateableTimeDomainsEXT;
+#endif /* defined(VK_EXT_calibrated_timestamps) */
+#if defined(VK_EXT_color_write_enable)
+PFN_vkCmdSetColorWriteEnableEXT vkCmdSetColorWriteEnableEXT;
+#endif /* defined(VK_EXT_color_write_enable) */
+#if defined(VK_EXT_conditional_rendering)
+PFN_vkCmdBeginConditionalRenderingEXT vkCmdBeginConditionalRenderingEXT;
+PFN_vkCmdEndConditionalRenderingEXT vkCmdEndConditionalRenderingEXT;
+#endif /* defined(VK_EXT_conditional_rendering) */
+#if defined(VK_EXT_debug_marker)
+PFN_vkCmdDebugMarkerBeginEXT vkCmdDebugMarkerBeginEXT;
+PFN_vkCmdDebugMarkerEndEXT vkCmdDebugMarkerEndEXT;
+PFN_vkCmdDebugMarkerInsertEXT vkCmdDebugMarkerInsertEXT;
+PFN_vkDebugMarkerSetObjectNameEXT vkDebugMarkerSetObjectNameEXT;
+PFN_vkDebugMarkerSetObjectTagEXT vkDebugMarkerSetObjectTagEXT;
+#endif /* defined(VK_EXT_debug_marker) */
+#if defined(VK_EXT_debug_report)
+PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT;
+PFN_vkDebugReportMessageEXT vkDebugReportMessageEXT;
+PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT;
+#endif /* defined(VK_EXT_debug_report) */
+#if defined(VK_EXT_debug_utils)
+PFN_vkCmdBeginDebugUtilsLabelEXT vkCmdBeginDebugUtilsLabelEXT;
+PFN_vkCmdEndDebugUtilsLabelEXT vkCmdEndDebugUtilsLabelEXT;
+PFN_vkCmdInsertDebugUtilsLabelEXT vkCmdInsertDebugUtilsLabelEXT;
+PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessengerEXT;
+PFN_vkDestroyDebugUtilsMessengerEXT vkDestroyDebugUtilsMessengerEXT;
+PFN_vkQueueBeginDebugUtilsLabelEXT vkQueueBeginDebugUtilsLabelEXT;
+PFN_vkQueueEndDebugUtilsLabelEXT vkQueueEndDebugUtilsLabelEXT;
+PFN_vkQueueInsertDebugUtilsLabelEXT vkQueueInsertDebugUtilsLabelEXT;
+PFN_vkSetDebugUtilsObjectNameEXT vkSetDebugUtilsObjectNameEXT;
+PFN_vkSetDebugUtilsObjectTagEXT vkSetDebugUtilsObjectTagEXT;
+PFN_vkSubmitDebugUtilsMessageEXT vkSubmitDebugUtilsMessageEXT;
+#endif /* defined(VK_EXT_debug_utils) */
+#if defined(VK_EXT_direct_mode_display)
+PFN_vkReleaseDisplayEXT vkReleaseDisplayEXT;
+#endif /* defined(VK_EXT_direct_mode_display) */
+#if defined(VK_EXT_directfb_surface)
+PFN_vkCreateDirectFBSurfaceEXT vkCreateDirectFBSurfaceEXT;
+PFN_vkGetPhysicalDeviceDirectFBPresentationSupportEXT vkGetPhysicalDeviceDirectFBPresentationSupportEXT;
+#endif /* defined(VK_EXT_directfb_surface) */
+#if defined(VK_EXT_discard_rectangles)
+PFN_vkCmdSetDiscardRectangleEXT vkCmdSetDiscardRectangleEXT;
+#endif /* defined(VK_EXT_discard_rectangles) */
+#if defined(VK_EXT_display_control)
+PFN_vkDisplayPowerControlEXT vkDisplayPowerControlEXT;
+PFN_vkGetSwapchainCounterEXT vkGetSwapchainCounterEXT;
+PFN_vkRegisterDeviceEventEXT vkRegisterDeviceEventEXT;
+PFN_vkRegisterDisplayEventEXT vkRegisterDisplayEventEXT;
+#endif /* defined(VK_EXT_display_control) */
+#if defined(VK_EXT_display_surface_counter)
+PFN_vkGetPhysicalDeviceSurfaceCapabilities2EXT vkGetPhysicalDeviceSurfaceCapabilities2EXT;
+#endif /* defined(VK_EXT_display_surface_counter) */
+#if defined(VK_EXT_extended_dynamic_state)
+PFN_vkCmdBindVertexBuffers2EXT vkCmdBindVertexBuffers2EXT;
+PFN_vkCmdSetCullModeEXT vkCmdSetCullModeEXT;
+PFN_vkCmdSetDepthBoundsTestEnableEXT vkCmdSetDepthBoundsTestEnableEXT;
+PFN_vkCmdSetDepthCompareOpEXT vkCmdSetDepthCompareOpEXT;
+PFN_vkCmdSetDepthTestEnableEXT vkCmdSetDepthTestEnableEXT;
+PFN_vkCmdSetDepthWriteEnableEXT vkCmdSetDepthWriteEnableEXT;
+PFN_vkCmdSetFrontFaceEXT vkCmdSetFrontFaceEXT;
+PFN_vkCmdSetPrimitiveTopologyEXT vkCmdSetPrimitiveTopologyEXT;
+PFN_vkCmdSetScissorWithCountEXT vkCmdSetScissorWithCountEXT;
+PFN_vkCmdSetStencilOpEXT vkCmdSetStencilOpEXT;
+PFN_vkCmdSetStencilTestEnableEXT vkCmdSetStencilTestEnableEXT;
+PFN_vkCmdSetViewportWithCountEXT vkCmdSetViewportWithCountEXT;
+#endif /* defined(VK_EXT_extended_dynamic_state) */
+#if defined(VK_EXT_extended_dynamic_state2)
+PFN_vkCmdSetDepthBiasEnableEXT vkCmdSetDepthBiasEnableEXT;
+PFN_vkCmdSetLogicOpEXT vkCmdSetLogicOpEXT;
+PFN_vkCmdSetPatchControlPointsEXT vkCmdSetPatchControlPointsEXT;
+PFN_vkCmdSetPrimitiveRestartEnableEXT vkCmdSetPrimitiveRestartEnableEXT;
+PFN_vkCmdSetRasterizerDiscardEnableEXT vkCmdSetRasterizerDiscardEnableEXT;
+#endif /* defined(VK_EXT_extended_dynamic_state2) */
+#if defined(VK_EXT_external_memory_host)
+PFN_vkGetMemoryHostPointerPropertiesEXT vkGetMemoryHostPointerPropertiesEXT;
+#endif /* defined(VK_EXT_external_memory_host) */
+#if defined(VK_EXT_full_screen_exclusive)
+PFN_vkAcquireFullScreenExclusiveModeEXT vkAcquireFullScreenExclusiveModeEXT;
+PFN_vkGetPhysicalDeviceSurfacePresentModes2EXT vkGetPhysicalDeviceSurfacePresentModes2EXT;
+PFN_vkReleaseFullScreenExclusiveModeEXT vkReleaseFullScreenExclusiveModeEXT;
+#endif /* defined(VK_EXT_full_screen_exclusive) */
+#if defined(VK_EXT_hdr_metadata)
+PFN_vkSetHdrMetadataEXT vkSetHdrMetadataEXT;
+#endif /* defined(VK_EXT_hdr_metadata) */
+#if defined(VK_EXT_headless_surface)
+PFN_vkCreateHeadlessSurfaceEXT vkCreateHeadlessSurfaceEXT;
+#endif /* defined(VK_EXT_headless_surface) */
+#if defined(VK_EXT_host_query_reset)
+PFN_vkResetQueryPoolEXT vkResetQueryPoolEXT;
+#endif /* defined(VK_EXT_host_query_reset) */
+#if defined(VK_EXT_image_drm_format_modifier)
+PFN_vkGetImageDrmFormatModifierPropertiesEXT vkGetImageDrmFormatModifierPropertiesEXT;
+#endif /* defined(VK_EXT_image_drm_format_modifier) */
+#if defined(VK_EXT_line_rasterization)
+PFN_vkCmdSetLineStippleEXT vkCmdSetLineStippleEXT;
+#endif /* defined(VK_EXT_line_rasterization) */
+#if defined(VK_EXT_metal_surface)
+PFN_vkCreateMetalSurfaceEXT vkCreateMetalSurfaceEXT;
+#endif /* defined(VK_EXT_metal_surface) */
+#if defined(VK_EXT_multi_draw)
+PFN_vkCmdDrawMultiEXT vkCmdDrawMultiEXT;
+PFN_vkCmdDrawMultiIndexedEXT vkCmdDrawMultiIndexedEXT;
+#endif /* defined(VK_EXT_multi_draw) */
+#if defined(VK_EXT_pageable_device_local_memory)
+PFN_vkSetDeviceMemoryPriorityEXT vkSetDeviceMemoryPriorityEXT;
+#endif /* defined(VK_EXT_pageable_device_local_memory) */
+#if defined(VK_EXT_private_data)
+PFN_vkCreatePrivateDataSlotEXT vkCreatePrivateDataSlotEXT;
+PFN_vkDestroyPrivateDataSlotEXT vkDestroyPrivateDataSlotEXT;
+PFN_vkGetPrivateDataEXT vkGetPrivateDataEXT;
+PFN_vkSetPrivateDataEXT vkSetPrivateDataEXT;
+#endif /* defined(VK_EXT_private_data) */
+#if defined(VK_EXT_sample_locations)
+PFN_vkCmdSetSampleLocationsEXT vkCmdSetSampleLocationsEXT;
+PFN_vkGetPhysicalDeviceMultisamplePropertiesEXT vkGetPhysicalDeviceMultisamplePropertiesEXT;
+#endif /* defined(VK_EXT_sample_locations) */
+#if defined(VK_EXT_tooling_info)
+PFN_vkGetPhysicalDeviceToolPropertiesEXT vkGetPhysicalDeviceToolPropertiesEXT;
+#endif /* defined(VK_EXT_tooling_info) */
+#if defined(VK_EXT_transform_feedback)
+PFN_vkCmdBeginQueryIndexedEXT vkCmdBeginQueryIndexedEXT;
+PFN_vkCmdBeginTransformFeedbackEXT vkCmdBeginTransformFeedbackEXT;
+PFN_vkCmdBindTransformFeedbackBuffersEXT vkCmdBindTransformFeedbackBuffersEXT;
+PFN_vkCmdDrawIndirectByteCountEXT vkCmdDrawIndirectByteCountEXT;
+PFN_vkCmdEndQueryIndexedEXT vkCmdEndQueryIndexedEXT;
+PFN_vkCmdEndTransformFeedbackEXT vkCmdEndTransformFeedbackEXT;
+#endif /* defined(VK_EXT_transform_feedback) */
+#if defined(VK_EXT_validation_cache)
+PFN_vkCreateValidationCacheEXT vkCreateValidationCacheEXT;
+PFN_vkDestroyValidationCacheEXT vkDestroyValidationCacheEXT;
+PFN_vkGetValidationCacheDataEXT vkGetValidationCacheDataEXT;
+PFN_vkMergeValidationCachesEXT vkMergeValidationCachesEXT;
+#endif /* defined(VK_EXT_validation_cache) */
+#if defined(VK_EXT_vertex_input_dynamic_state)
+PFN_vkCmdSetVertexInputEXT vkCmdSetVertexInputEXT;
+#endif /* defined(VK_EXT_vertex_input_dynamic_state) */
+#if defined(VK_FUCHSIA_buffer_collection)
+PFN_vkCreateBufferCollectionFUCHSIA vkCreateBufferCollectionFUCHSIA;
+PFN_vkDestroyBufferCollectionFUCHSIA vkDestroyBufferCollectionFUCHSIA;
+PFN_vkGetBufferCollectionPropertiesFUCHSIA vkGetBufferCollectionPropertiesFUCHSIA;
+PFN_vkSetBufferCollectionBufferConstraintsFUCHSIA vkSetBufferCollectionBufferConstraintsFUCHSIA;
+PFN_vkSetBufferCollectionImageConstraintsFUCHSIA vkSetBufferCollectionImageConstraintsFUCHSIA;
+#endif /* defined(VK_FUCHSIA_buffer_collection) */
+#if defined(VK_FUCHSIA_external_memory)
+PFN_vkGetMemoryZirconHandleFUCHSIA vkGetMemoryZirconHandleFUCHSIA;
+PFN_vkGetMemoryZirconHandlePropertiesFUCHSIA vkGetMemoryZirconHandlePropertiesFUCHSIA;
+#endif /* defined(VK_FUCHSIA_external_memory) */
+#if defined(VK_FUCHSIA_external_semaphore)
+PFN_vkGetSemaphoreZirconHandleFUCHSIA vkGetSemaphoreZirconHandleFUCHSIA;
+PFN_vkImportSemaphoreZirconHandleFUCHSIA vkImportSemaphoreZirconHandleFUCHSIA;
+#endif /* defined(VK_FUCHSIA_external_semaphore) */
+#if defined(VK_FUCHSIA_imagepipe_surface)
+PFN_vkCreateImagePipeSurfaceFUCHSIA vkCreateImagePipeSurfaceFUCHSIA;
+#endif /* defined(VK_FUCHSIA_imagepipe_surface) */
+#if defined(VK_GGP_stream_descriptor_surface)
+PFN_vkCreateStreamDescriptorSurfaceGGP vkCreateStreamDescriptorSurfaceGGP;
+#endif /* defined(VK_GGP_stream_descriptor_surface) */
+#if defined(VK_GOOGLE_display_timing)
+PFN_vkGetPastPresentationTimingGOOGLE vkGetPastPresentationTimingGOOGLE;
+PFN_vkGetRefreshCycleDurationGOOGLE vkGetRefreshCycleDurationGOOGLE;
+#endif /* defined(VK_GOOGLE_display_timing) */
+#if defined(VK_HUAWEI_invocation_mask)
+PFN_vkCmdBindInvocationMaskHUAWEI vkCmdBindInvocationMaskHUAWEI;
+#endif /* defined(VK_HUAWEI_invocation_mask) */
+#if defined(VK_HUAWEI_subpass_shading)
+PFN_vkCmdSubpassShadingHUAWEI vkCmdSubpassShadingHUAWEI;
+PFN_vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI;
+#endif /* defined(VK_HUAWEI_subpass_shading) */
+#if defined(VK_INTEL_performance_query)
+PFN_vkAcquirePerformanceConfigurationINTEL vkAcquirePerformanceConfigurationINTEL;
+PFN_vkCmdSetPerformanceMarkerINTEL vkCmdSetPerformanceMarkerINTEL;
+PFN_vkCmdSetPerformanceOverrideINTEL vkCmdSetPerformanceOverrideINTEL;
+PFN_vkCmdSetPerformanceStreamMarkerINTEL vkCmdSetPerformanceStreamMarkerINTEL;
+PFN_vkGetPerformanceParameterINTEL vkGetPerformanceParameterINTEL;
+PFN_vkInitializePerformanceApiINTEL vkInitializePerformanceApiINTEL;
+PFN_vkQueueSetPerformanceConfigurationINTEL vkQueueSetPerformanceConfigurationINTEL;
+PFN_vkReleasePerformanceConfigurationINTEL vkReleasePerformanceConfigurationINTEL;
+PFN_vkUninitializePerformanceApiINTEL vkUninitializePerformanceApiINTEL;
+#endif /* defined(VK_INTEL_performance_query) */
+#if defined(VK_KHR_acceleration_structure)
+PFN_vkBuildAccelerationStructuresKHR vkBuildAccelerationStructuresKHR;
+PFN_vkCmdBuildAccelerationStructuresIndirectKHR vkCmdBuildAccelerationStructuresIndirectKHR;
+PFN_vkCmdBuildAccelerationStructuresKHR vkCmdBuildAccelerationStructuresKHR;
+PFN_vkCmdCopyAccelerationStructureKHR vkCmdCopyAccelerationStructureKHR;
+PFN_vkCmdCopyAccelerationStructureToMemoryKHR vkCmdCopyAccelerationStructureToMemoryKHR;
+PFN_vkCmdCopyMemoryToAccelerationStructureKHR vkCmdCopyMemoryToAccelerationStructureKHR;
+PFN_vkCmdWriteAccelerationStructuresPropertiesKHR vkCmdWriteAccelerationStructuresPropertiesKHR;
+PFN_vkCopyAccelerationStructureKHR vkCopyAccelerationStructureKHR;
+PFN_vkCopyAccelerationStructureToMemoryKHR vkCopyAccelerationStructureToMemoryKHR;
+PFN_vkCopyMemoryToAccelerationStructureKHR vkCopyMemoryToAccelerationStructureKHR;
+PFN_vkCreateAccelerationStructureKHR vkCreateAccelerationStructureKHR;
+PFN_vkDestroyAccelerationStructureKHR vkDestroyAccelerationStructureKHR;
+PFN_vkGetAccelerationStructureBuildSizesKHR vkGetAccelerationStructureBuildSizesKHR;
+PFN_vkGetAccelerationStructureDeviceAddressKHR vkGetAccelerationStructureDeviceAddressKHR;
+PFN_vkGetDeviceAccelerationStructureCompatibilityKHR vkGetDeviceAccelerationStructureCompatibilityKHR;
+PFN_vkWriteAccelerationStructuresPropertiesKHR vkWriteAccelerationStructuresPropertiesKHR;
+#endif /* defined(VK_KHR_acceleration_structure) */
+#if defined(VK_KHR_android_surface)
+PFN_vkCreateAndroidSurfaceKHR vkCreateAndroidSurfaceKHR;
+#endif /* defined(VK_KHR_android_surface) */
+#if defined(VK_KHR_bind_memory2)
+PFN_vkBindBufferMemory2KHR vkBindBufferMemory2KHR;
+PFN_vkBindImageMemory2KHR vkBindImageMemory2KHR;
+#endif /* defined(VK_KHR_bind_memory2) */
+#if defined(VK_KHR_buffer_device_address)
+PFN_vkGetBufferDeviceAddressKHR vkGetBufferDeviceAddressKHR;
+PFN_vkGetBufferOpaqueCaptureAddressKHR vkGetBufferOpaqueCaptureAddressKHR;
+PFN_vkGetDeviceMemoryOpaqueCaptureAddressKHR vkGetDeviceMemoryOpaqueCaptureAddressKHR;
+#endif /* defined(VK_KHR_buffer_device_address) */
+#if defined(VK_KHR_copy_commands2)
+PFN_vkCmdBlitImage2KHR vkCmdBlitImage2KHR;
+PFN_vkCmdCopyBuffer2KHR vkCmdCopyBuffer2KHR;
+PFN_vkCmdCopyBufferToImage2KHR vkCmdCopyBufferToImage2KHR;
+PFN_vkCmdCopyImage2KHR vkCmdCopyImage2KHR;
+PFN_vkCmdCopyImageToBuffer2KHR vkCmdCopyImageToBuffer2KHR;
+PFN_vkCmdResolveImage2KHR vkCmdResolveImage2KHR;
+#endif /* defined(VK_KHR_copy_commands2) */
+#if defined(VK_KHR_create_renderpass2)
+PFN_vkCmdBeginRenderPass2KHR vkCmdBeginRenderPass2KHR;
+PFN_vkCmdEndRenderPass2KHR vkCmdEndRenderPass2KHR;
+PFN_vkCmdNextSubpass2KHR vkCmdNextSubpass2KHR;
+PFN_vkCreateRenderPass2KHR vkCreateRenderPass2KHR;
+#endif /* defined(VK_KHR_create_renderpass2) */
+#if defined(VK_KHR_deferred_host_operations)
+PFN_vkCreateDeferredOperationKHR vkCreateDeferredOperationKHR;
+PFN_vkDeferredOperationJoinKHR vkDeferredOperationJoinKHR;
+PFN_vkDestroyDeferredOperationKHR vkDestroyDeferredOperationKHR;
+PFN_vkGetDeferredOperationMaxConcurrencyKHR vkGetDeferredOperationMaxConcurrencyKHR;
+PFN_vkGetDeferredOperationResultKHR vkGetDeferredOperationResultKHR;
+#endif /* defined(VK_KHR_deferred_host_operations) */
+#if defined(VK_KHR_descriptor_update_template)
+PFN_vkCreateDescriptorUpdateTemplateKHR vkCreateDescriptorUpdateTemplateKHR;
+PFN_vkDestroyDescriptorUpdateTemplateKHR vkDestroyDescriptorUpdateTemplateKHR;
+PFN_vkUpdateDescriptorSetWithTemplateKHR vkUpdateDescriptorSetWithTemplateKHR;
+#endif /* defined(VK_KHR_descriptor_update_template) */
+#if defined(VK_KHR_device_group)
+PFN_vkCmdDispatchBaseKHR vkCmdDispatchBaseKHR;
+PFN_vkCmdSetDeviceMaskKHR vkCmdSetDeviceMaskKHR;
+PFN_vkGetDeviceGroupPeerMemoryFeaturesKHR vkGetDeviceGroupPeerMemoryFeaturesKHR;
+#endif /* defined(VK_KHR_device_group) */
+#if defined(VK_KHR_device_group_creation)
+PFN_vkEnumeratePhysicalDeviceGroupsKHR vkEnumeratePhysicalDeviceGroupsKHR;
+#endif /* defined(VK_KHR_device_group_creation) */
+#if defined(VK_KHR_display)
+PFN_vkCreateDisplayModeKHR vkCreateDisplayModeKHR;
+PFN_vkCreateDisplayPlaneSurfaceKHR vkCreateDisplayPlaneSurfaceKHR;
+PFN_vkGetDisplayModePropertiesKHR vkGetDisplayModePropertiesKHR;
+PFN_vkGetDisplayPlaneCapabilitiesKHR vkGetDisplayPlaneCapabilitiesKHR;
+PFN_vkGetDisplayPlaneSupportedDisplaysKHR vkGetDisplayPlaneSupportedDisplaysKHR;
+PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR vkGetPhysicalDeviceDisplayPlanePropertiesKHR;
+PFN_vkGetPhysicalDeviceDisplayPropertiesKHR vkGetPhysicalDeviceDisplayPropertiesKHR;
+#endif /* defined(VK_KHR_display) */
+#if defined(VK_KHR_display_swapchain)
+PFN_vkCreateSharedSwapchainsKHR vkCreateSharedSwapchainsKHR;
+#endif /* defined(VK_KHR_display_swapchain) */
+#if defined(VK_KHR_draw_indirect_count)
+PFN_vkCmdDrawIndexedIndirectCountKHR vkCmdDrawIndexedIndirectCountKHR;
+PFN_vkCmdDrawIndirectCountKHR vkCmdDrawIndirectCountKHR;
+#endif /* defined(VK_KHR_draw_indirect_count) */
+#if defined(VK_KHR_dynamic_rendering)
+PFN_vkCmdBeginRenderingKHR vkCmdBeginRenderingKHR;
+PFN_vkCmdEndRenderingKHR vkCmdEndRenderingKHR;
+#endif /* defined(VK_KHR_dynamic_rendering) */
+#if defined(VK_KHR_external_fence_capabilities)
+PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR vkGetPhysicalDeviceExternalFencePropertiesKHR;
+#endif /* defined(VK_KHR_external_fence_capabilities) */
+#if defined(VK_KHR_external_fence_fd)
+PFN_vkGetFenceFdKHR vkGetFenceFdKHR;
+PFN_vkImportFenceFdKHR vkImportFenceFdKHR;
+#endif /* defined(VK_KHR_external_fence_fd) */
+#if defined(VK_KHR_external_fence_win32)
+PFN_vkGetFenceWin32HandleKHR vkGetFenceWin32HandleKHR;
+PFN_vkImportFenceWin32HandleKHR vkImportFenceWin32HandleKHR;
+#endif /* defined(VK_KHR_external_fence_win32) */
+#if defined(VK_KHR_external_memory_capabilities)
+PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR vkGetPhysicalDeviceExternalBufferPropertiesKHR;
+#endif /* defined(VK_KHR_external_memory_capabilities) */
+#if defined(VK_KHR_external_memory_fd)
+PFN_vkGetMemoryFdKHR vkGetMemoryFdKHR;
+PFN_vkGetMemoryFdPropertiesKHR vkGetMemoryFdPropertiesKHR;
+#endif /* defined(VK_KHR_external_memory_fd) */
+#if defined(VK_KHR_external_memory_win32)
+PFN_vkGetMemoryWin32HandleKHR vkGetMemoryWin32HandleKHR;
+PFN_vkGetMemoryWin32HandlePropertiesKHR vkGetMemoryWin32HandlePropertiesKHR;
+#endif /* defined(VK_KHR_external_memory_win32) */
+#if defined(VK_KHR_external_semaphore_capabilities)
+PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR vkGetPhysicalDeviceExternalSemaphorePropertiesKHR;
+#endif /* defined(VK_KHR_external_semaphore_capabilities) */
+#if defined(VK_KHR_external_semaphore_fd)
+PFN_vkGetSemaphoreFdKHR vkGetSemaphoreFdKHR;
+PFN_vkImportSemaphoreFdKHR vkImportSemaphoreFdKHR;
+#endif /* defined(VK_KHR_external_semaphore_fd) */
+#if defined(VK_KHR_external_semaphore_win32)
+PFN_vkGetSemaphoreWin32HandleKHR vkGetSemaphoreWin32HandleKHR;
+PFN_vkImportSemaphoreWin32HandleKHR vkImportSemaphoreWin32HandleKHR;
+#endif /* defined(VK_KHR_external_semaphore_win32) */
+#if defined(VK_KHR_fragment_shading_rate)
+PFN_vkCmdSetFragmentShadingRateKHR vkCmdSetFragmentShadingRateKHR;
+PFN_vkGetPhysicalDeviceFragmentShadingRatesKHR vkGetPhysicalDeviceFragmentShadingRatesKHR;
+#endif /* defined(VK_KHR_fragment_shading_rate) */
+#if defined(VK_KHR_get_display_properties2)
+PFN_vkGetDisplayModeProperties2KHR vkGetDisplayModeProperties2KHR;
+PFN_vkGetDisplayPlaneCapabilities2KHR vkGetDisplayPlaneCapabilities2KHR;
+PFN_vkGetPhysicalDeviceDisplayPlaneProperties2KHR vkGetPhysicalDeviceDisplayPlaneProperties2KHR;
+PFN_vkGetPhysicalDeviceDisplayProperties2KHR vkGetPhysicalDeviceDisplayProperties2KHR;
+#endif /* defined(VK_KHR_get_display_properties2) */
+#if defined(VK_KHR_get_memory_requirements2)
+PFN_vkGetBufferMemoryRequirements2KHR vkGetBufferMemoryRequirements2KHR;
+PFN_vkGetImageMemoryRequirements2KHR vkGetImageMemoryRequirements2KHR;
+PFN_vkGetImageSparseMemoryRequirements2KHR vkGetImageSparseMemoryRequirements2KHR;
+#endif /* defined(VK_KHR_get_memory_requirements2) */
+#if defined(VK_KHR_get_physical_device_properties2)
+PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR;
+PFN_vkGetPhysicalDeviceFormatProperties2KHR vkGetPhysicalDeviceFormatProperties2KHR;
+PFN_vkGetPhysicalDeviceImageFormatProperties2KHR vkGetPhysicalDeviceImageFormatProperties2KHR;
+PFN_vkGetPhysicalDeviceMemoryProperties2KHR vkGetPhysicalDeviceMemoryProperties2KHR;
+PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR;
+PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR vkGetPhysicalDeviceQueueFamilyProperties2KHR;
+PFN_vkGetPhysicalDeviceSparseImageFormatProperties2KHR vkGetPhysicalDeviceSparseImageFormatProperties2KHR;
+#endif /* defined(VK_KHR_get_physical_device_properties2) */
+#if defined(VK_KHR_get_surface_capabilities2)
+PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR vkGetPhysicalDeviceSurfaceCapabilities2KHR;
+PFN_vkGetPhysicalDeviceSurfaceFormats2KHR vkGetPhysicalDeviceSurfaceFormats2KHR;
+#endif /* defined(VK_KHR_get_surface_capabilities2) */
+#if defined(VK_KHR_maintenance1)
+PFN_vkTrimCommandPoolKHR vkTrimCommandPoolKHR;
+#endif /* defined(VK_KHR_maintenance1) */
+#if defined(VK_KHR_maintenance3)
+PFN_vkGetDescriptorSetLayoutSupportKHR vkGetDescriptorSetLayoutSupportKHR;
+#endif /* defined(VK_KHR_maintenance3) */
+#if defined(VK_KHR_maintenance4)
+PFN_vkGetDeviceBufferMemoryRequirementsKHR vkGetDeviceBufferMemoryRequirementsKHR;
+PFN_vkGetDeviceImageMemoryRequirementsKHR vkGetDeviceImageMemoryRequirementsKHR;
+PFN_vkGetDeviceImageSparseMemoryRequirementsKHR vkGetDeviceImageSparseMemoryRequirementsKHR;
+#endif /* defined(VK_KHR_maintenance4) */
+#if defined(VK_KHR_performance_query)
+PFN_vkAcquireProfilingLockKHR vkAcquireProfilingLockKHR;
+PFN_vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR;
+PFN_vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR;
+PFN_vkReleaseProfilingLockKHR vkReleaseProfilingLockKHR;
+#endif /* defined(VK_KHR_performance_query) */
+#if defined(VK_KHR_pipeline_executable_properties)
+PFN_vkGetPipelineExecutableInternalRepresentationsKHR vkGetPipelineExecutableInternalRepresentationsKHR;
+PFN_vkGetPipelineExecutablePropertiesKHR vkGetPipelineExecutablePropertiesKHR;
+PFN_vkGetPipelineExecutableStatisticsKHR vkGetPipelineExecutableStatisticsKHR;
+#endif /* defined(VK_KHR_pipeline_executable_properties) */
+#if defined(VK_KHR_present_wait)
+PFN_vkWaitForPresentKHR vkWaitForPresentKHR;
+#endif /* defined(VK_KHR_present_wait) */
+#if defined(VK_KHR_push_descriptor)
+PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSetKHR;
+#endif /* defined(VK_KHR_push_descriptor) */
+#if defined(VK_KHR_ray_tracing_pipeline)
+PFN_vkCmdSetRayTracingPipelineStackSizeKHR vkCmdSetRayTracingPipelineStackSizeKHR;
+PFN_vkCmdTraceRaysIndirectKHR vkCmdTraceRaysIndirectKHR;
+PFN_vkCmdTraceRaysKHR vkCmdTraceRaysKHR;
+PFN_vkCreateRayTracingPipelinesKHR vkCreateRayTracingPipelinesKHR;
+PFN_vkGetRayTracingCaptureReplayShaderGroupHandlesKHR vkGetRayTracingCaptureReplayShaderGroupHandlesKHR;
+PFN_vkGetRayTracingShaderGroupHandlesKHR vkGetRayTracingShaderGroupHandlesKHR;
+PFN_vkGetRayTracingShaderGroupStackSizeKHR vkGetRayTracingShaderGroupStackSizeKHR;
+#endif /* defined(VK_KHR_ray_tracing_pipeline) */
+#if defined(VK_KHR_sampler_ycbcr_conversion)
+PFN_vkCreateSamplerYcbcrConversionKHR vkCreateSamplerYcbcrConversionKHR;
+PFN_vkDestroySamplerYcbcrConversionKHR vkDestroySamplerYcbcrConversionKHR;
+#endif /* defined(VK_KHR_sampler_ycbcr_conversion) */
+#if defined(VK_KHR_shared_presentable_image)
+PFN_vkGetSwapchainStatusKHR vkGetSwapchainStatusKHR;
+#endif /* defined(VK_KHR_shared_presentable_image) */
+#if defined(VK_KHR_surface)
+PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR;
+PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR;
+PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR;
+PFN_vkGetPhysicalDeviceSurfacePresentModesKHR vkGetPhysicalDeviceSurfacePresentModesKHR;
+PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR;
+#endif /* defined(VK_KHR_surface) */
+#if defined(VK_KHR_swapchain)
+PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR;
+PFN_vkCreateSwapchainKHR vkCreateSwapchainKHR;
+PFN_vkDestroySwapchainKHR vkDestroySwapchainKHR;
+PFN_vkGetSwapchainImagesKHR vkGetSwapchainImagesKHR;
+PFN_vkQueuePresentKHR vkQueuePresentKHR;
+#endif /* defined(VK_KHR_swapchain) */
+#if defined(VK_KHR_synchronization2)
+PFN_vkCmdPipelineBarrier2KHR vkCmdPipelineBarrier2KHR;
+PFN_vkCmdResetEvent2KHR vkCmdResetEvent2KHR;
+PFN_vkCmdSetEvent2KHR vkCmdSetEvent2KHR;
+PFN_vkCmdWaitEvents2KHR vkCmdWaitEvents2KHR;
+PFN_vkCmdWriteTimestamp2KHR vkCmdWriteTimestamp2KHR;
+PFN_vkQueueSubmit2KHR vkQueueSubmit2KHR;
+#endif /* defined(VK_KHR_synchronization2) */
+#if defined(VK_KHR_synchronization2) && defined(VK_AMD_buffer_marker)
+PFN_vkCmdWriteBufferMarker2AMD vkCmdWriteBufferMarker2AMD;
+#endif /* defined(VK_KHR_synchronization2) && defined(VK_AMD_buffer_marker) */
+#if defined(VK_KHR_synchronization2) && defined(VK_NV_device_diagnostic_checkpoints)
+PFN_vkGetQueueCheckpointData2NV vkGetQueueCheckpointData2NV;
+#endif /* defined(VK_KHR_synchronization2) && defined(VK_NV_device_diagnostic_checkpoints) */
+#if defined(VK_KHR_timeline_semaphore)
+PFN_vkGetSemaphoreCounterValueKHR vkGetSemaphoreCounterValueKHR;
+PFN_vkSignalSemaphoreKHR vkSignalSemaphoreKHR;
+PFN_vkWaitSemaphoresKHR vkWaitSemaphoresKHR;
+#endif /* defined(VK_KHR_timeline_semaphore) */
+#if defined(VK_KHR_video_decode_queue)
+PFN_vkCmdDecodeVideoKHR vkCmdDecodeVideoKHR;
+#endif /* defined(VK_KHR_video_decode_queue) */
+#if defined(VK_KHR_video_encode_queue)
+PFN_vkCmdEncodeVideoKHR vkCmdEncodeVideoKHR;
+#endif /* defined(VK_KHR_video_encode_queue) */
+#if defined(VK_KHR_video_queue)
+PFN_vkBindVideoSessionMemoryKHR vkBindVideoSessionMemoryKHR;
+PFN_vkCmdBeginVideoCodingKHR vkCmdBeginVideoCodingKHR;
+PFN_vkCmdControlVideoCodingKHR vkCmdControlVideoCodingKHR;
+PFN_vkCmdEndVideoCodingKHR vkCmdEndVideoCodingKHR;
+PFN_vkCreateVideoSessionKHR vkCreateVideoSessionKHR;
+PFN_vkCreateVideoSessionParametersKHR vkCreateVideoSessionParametersKHR;
+PFN_vkDestroyVideoSessionKHR vkDestroyVideoSessionKHR;
+PFN_vkDestroyVideoSessionParametersKHR vkDestroyVideoSessionParametersKHR;
+PFN_vkGetPhysicalDeviceVideoCapabilitiesKHR vkGetPhysicalDeviceVideoCapabilitiesKHR;
+PFN_vkGetPhysicalDeviceVideoFormatPropertiesKHR vkGetPhysicalDeviceVideoFormatPropertiesKHR;
+PFN_vkGetVideoSessionMemoryRequirementsKHR vkGetVideoSessionMemoryRequirementsKHR;
+PFN_vkUpdateVideoSessionParametersKHR vkUpdateVideoSessionParametersKHR;
+#endif /* defined(VK_KHR_video_queue) */
+#if defined(VK_KHR_wayland_surface)
+PFN_vkCreateWaylandSurfaceKHR vkCreateWaylandSurfaceKHR;
+PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR vkGetPhysicalDeviceWaylandPresentationSupportKHR;
+#endif /* defined(VK_KHR_wayland_surface) */
+#if defined(VK_KHR_win32_surface)
+PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR;
+PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR vkGetPhysicalDeviceWin32PresentationSupportKHR;
+#endif /* defined(VK_KHR_win32_surface) */
+#if defined(VK_KHR_xcb_surface)
+PFN_vkCreateXcbSurfaceKHR vkCreateXcbSurfaceKHR;
+PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR vkGetPhysicalDeviceXcbPresentationSupportKHR;
+#endif /* defined(VK_KHR_xcb_surface) */
+#if defined(VK_KHR_xlib_surface)
+PFN_vkCreateXlibSurfaceKHR vkCreateXlibSurfaceKHR;
+PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR vkGetPhysicalDeviceXlibPresentationSupportKHR;
+#endif /* defined(VK_KHR_xlib_surface) */
+#if defined(VK_MVK_ios_surface)
+PFN_vkCreateIOSSurfaceMVK vkCreateIOSSurfaceMVK;
+#endif /* defined(VK_MVK_ios_surface) */
+#if defined(VK_MVK_macos_surface)
+PFN_vkCreateMacOSSurfaceMVK vkCreateMacOSSurfaceMVK;
+#endif /* defined(VK_MVK_macos_surface) */
+#if defined(VK_NN_vi_surface)
+PFN_vkCreateViSurfaceNN vkCreateViSurfaceNN;
+#endif /* defined(VK_NN_vi_surface) */
+#if defined(VK_NVX_binary_import)
+PFN_vkCmdCuLaunchKernelNVX vkCmdCuLaunchKernelNVX;
+PFN_vkCreateCuFunctionNVX vkCreateCuFunctionNVX;
+PFN_vkCreateCuModuleNVX vkCreateCuModuleNVX;
+PFN_vkDestroyCuFunctionNVX vkDestroyCuFunctionNVX;
+PFN_vkDestroyCuModuleNVX vkDestroyCuModuleNVX;
+#endif /* defined(VK_NVX_binary_import) */
+#if defined(VK_NVX_image_view_handle)
+PFN_vkGetImageViewAddressNVX vkGetImageViewAddressNVX;
+PFN_vkGetImageViewHandleNVX vkGetImageViewHandleNVX;
+#endif /* defined(VK_NVX_image_view_handle) */
+#if defined(VK_NV_acquire_winrt_display)
+PFN_vkAcquireWinrtDisplayNV vkAcquireWinrtDisplayNV;
+PFN_vkGetWinrtDisplayNV vkGetWinrtDisplayNV;
+#endif /* defined(VK_NV_acquire_winrt_display) */
+#if defined(VK_NV_clip_space_w_scaling)
+PFN_vkCmdSetViewportWScalingNV vkCmdSetViewportWScalingNV;
+#endif /* defined(VK_NV_clip_space_w_scaling) */
+#if defined(VK_NV_cooperative_matrix)
+PFN_vkGetPhysicalDeviceCooperativeMatrixPropertiesNV vkGetPhysicalDeviceCooperativeMatrixPropertiesNV;
+#endif /* defined(VK_NV_cooperative_matrix) */
+#if defined(VK_NV_coverage_reduction_mode)
+PFN_vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV;
+#endif /* defined(VK_NV_coverage_reduction_mode) */
+#if defined(VK_NV_device_diagnostic_checkpoints)
+PFN_vkCmdSetCheckpointNV vkCmdSetCheckpointNV;
+PFN_vkGetQueueCheckpointDataNV vkGetQueueCheckpointDataNV;
+#endif /* defined(VK_NV_device_diagnostic_checkpoints) */
+#if defined(VK_NV_device_generated_commands)
+PFN_vkCmdBindPipelineShaderGroupNV vkCmdBindPipelineShaderGroupNV;
+PFN_vkCmdExecuteGeneratedCommandsNV vkCmdExecuteGeneratedCommandsNV;
+PFN_vkCmdPreprocessGeneratedCommandsNV vkCmdPreprocessGeneratedCommandsNV;
+PFN_vkCreateIndirectCommandsLayoutNV vkCreateIndirectCommandsLayoutNV;
+PFN_vkDestroyIndirectCommandsLayoutNV vkDestroyIndirectCommandsLayoutNV;
+PFN_vkGetGeneratedCommandsMemoryRequirementsNV vkGetGeneratedCommandsMemoryRequirementsNV;
+#endif /* defined(VK_NV_device_generated_commands) */
+#if defined(VK_NV_external_memory_capabilities)
+PFN_vkGetPhysicalDeviceExternalImageFormatPropertiesNV vkGetPhysicalDeviceExternalImageFormatPropertiesNV;
+#endif /* defined(VK_NV_external_memory_capabilities) */
+#if defined(VK_NV_external_memory_rdma)
+PFN_vkGetMemoryRemoteAddressNV vkGetMemoryRemoteAddressNV;
+#endif /* defined(VK_NV_external_memory_rdma) */
+#if defined(VK_NV_external_memory_win32)
+PFN_vkGetMemoryWin32HandleNV vkGetMemoryWin32HandleNV;
+#endif /* defined(VK_NV_external_memory_win32) */
+#if defined(VK_NV_fragment_shading_rate_enums)
+PFN_vkCmdSetFragmentShadingRateEnumNV vkCmdSetFragmentShadingRateEnumNV;
+#endif /* defined(VK_NV_fragment_shading_rate_enums) */
+#if defined(VK_NV_mesh_shader)
+PFN_vkCmdDrawMeshTasksIndirectCountNV vkCmdDrawMeshTasksIndirectCountNV;
+PFN_vkCmdDrawMeshTasksIndirectNV vkCmdDrawMeshTasksIndirectNV;
+PFN_vkCmdDrawMeshTasksNV vkCmdDrawMeshTasksNV;
+#endif /* defined(VK_NV_mesh_shader) */
+#if defined(VK_NV_ray_tracing)
+PFN_vkBindAccelerationStructureMemoryNV vkBindAccelerationStructureMemoryNV;
+PFN_vkCmdBuildAccelerationStructureNV vkCmdBuildAccelerationStructureNV;
+PFN_vkCmdCopyAccelerationStructureNV vkCmdCopyAccelerationStructureNV;
+PFN_vkCmdTraceRaysNV vkCmdTraceRaysNV;
+PFN_vkCmdWriteAccelerationStructuresPropertiesNV vkCmdWriteAccelerationStructuresPropertiesNV;
+PFN_vkCompileDeferredNV vkCompileDeferredNV;
+PFN_vkCreateAccelerationStructureNV vkCreateAccelerationStructureNV;
+PFN_vkCreateRayTracingPipelinesNV vkCreateRayTracingPipelinesNV;
+PFN_vkDestroyAccelerationStructureNV vkDestroyAccelerationStructureNV;
+PFN_vkGetAccelerationStructureHandleNV vkGetAccelerationStructureHandleNV;
+PFN_vkGetAccelerationStructureMemoryRequirementsNV vkGetAccelerationStructureMemoryRequirementsNV;
+PFN_vkGetRayTracingShaderGroupHandlesNV vkGetRayTracingShaderGroupHandlesNV;
+#endif /* defined(VK_NV_ray_tracing) */
+#if defined(VK_NV_scissor_exclusive)
+PFN_vkCmdSetExclusiveScissorNV vkCmdSetExclusiveScissorNV;
+#endif /* defined(VK_NV_scissor_exclusive) */
+#if defined(VK_NV_shading_rate_image)
+PFN_vkCmdBindShadingRateImageNV vkCmdBindShadingRateImageNV;
+PFN_vkCmdSetCoarseSampleOrderNV vkCmdSetCoarseSampleOrderNV;
+PFN_vkCmdSetViewportShadingRatePaletteNV vkCmdSetViewportShadingRatePaletteNV;
+#endif /* defined(VK_NV_shading_rate_image) */
+#if defined(VK_QNX_screen_surface)
+PFN_vkCreateScreenSurfaceQNX vkCreateScreenSurfaceQNX;
+PFN_vkGetPhysicalDeviceScreenPresentationSupportQNX vkGetPhysicalDeviceScreenPresentationSupportQNX;
+#endif /* defined(VK_QNX_screen_surface) */
+#if (defined(VK_EXT_full_screen_exclusive) && defined(VK_KHR_device_group)) || (defined(VK_EXT_full_screen_exclusive) && defined(VK_VERSION_1_1))
+PFN_vkGetDeviceGroupSurfacePresentModes2EXT vkGetDeviceGroupSurfacePresentModes2EXT;
+#endif /* (defined(VK_EXT_full_screen_exclusive) && defined(VK_KHR_device_group)) || (defined(VK_EXT_full_screen_exclusive) && defined(VK_VERSION_1_1)) */
+#if (defined(VK_KHR_descriptor_update_template) && defined(VK_KHR_push_descriptor)) || (defined(VK_KHR_push_descriptor) && defined(VK_VERSION_1_1)) || (defined(VK_KHR_push_descriptor) && defined(VK_KHR_descriptor_update_template))
+PFN_vkCmdPushDescriptorSetWithTemplateKHR vkCmdPushDescriptorSetWithTemplateKHR;
+#endif /* (defined(VK_KHR_descriptor_update_template) && defined(VK_KHR_push_descriptor)) || (defined(VK_KHR_push_descriptor) && defined(VK_VERSION_1_1)) || (defined(VK_KHR_push_descriptor) && defined(VK_KHR_descriptor_update_template)) */
+#if (defined(VK_KHR_device_group) && defined(VK_KHR_surface)) || (defined(VK_KHR_swapchain) && defined(VK_VERSION_1_1))
+PFN_vkGetDeviceGroupPresentCapabilitiesKHR vkGetDeviceGroupPresentCapabilitiesKHR;
+PFN_vkGetDeviceGroupSurfacePresentModesKHR vkGetDeviceGroupSurfacePresentModesKHR;
+PFN_vkGetPhysicalDevicePresentRectanglesKHR vkGetPhysicalDevicePresentRectanglesKHR;
+#endif /* (defined(VK_KHR_device_group) && defined(VK_KHR_surface)) || (defined(VK_KHR_swapchain) && defined(VK_VERSION_1_1)) */
+#if (defined(VK_KHR_device_group) && defined(VK_KHR_swapchain)) || (defined(VK_KHR_swapchain) && defined(VK_VERSION_1_1))
+PFN_vkAcquireNextImage2KHR vkAcquireNextImage2KHR;
+#endif /* (defined(VK_KHR_device_group) && defined(VK_KHR_swapchain)) || (defined(VK_KHR_swapchain) && defined(VK_VERSION_1_1)) */
+/* VOLK_GENERATE_PROTOTYPES_C */
+
+#ifdef __GNUC__
+# pragma GCC visibility pop
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+/* clang-format on */
diff --git a/gfx/angle/checkout/src/third_party/volk/volk.h b/gfx/angle/checkout/src/third_party/volk/volk.h
new file mode 100644
index 0000000000..08721b5edb
--- /dev/null
+++ b/gfx/angle/checkout/src/third_party/volk/volk.h
@@ -0,0 +1,1578 @@
+/**
+ * volk
+ *
+ * Copyright (C) 2018-2019, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
+ * Report bugs and download new versions at https://github.com/zeux/volk
+ *
+ * This library is distributed under the MIT License. See notice at the end of this file.
+ */
+/* clang-format off */
+#ifndef VOLK_H_
+#define VOLK_H_
+
+#if defined(VULKAN_H_) && !defined(VK_NO_PROTOTYPES)
+# error To use volk, you need to define VK_NO_PROTOTYPES before including vulkan.h
+#endif
+
+/* VOLK_GENERATE_VERSION_DEFINE */
+#define VOLK_HEADER_VERSION 204
+/* VOLK_GENERATE_VERSION_DEFINE */
+
+#ifndef VK_NO_PROTOTYPES
+# define VK_NO_PROTOTYPES
+#endif
+
+#ifndef VULKAN_H_
+# ifdef VOLK_VULKAN_H_PATH
+# include VOLK_VULKAN_H_PATH
+# elif defined(VK_USE_PLATFORM_WIN32_KHR)
+# include <vulkan/vk_platform.h>
+# include <vulkan/vulkan_core.h>
+
+ /* When VK_USE_PLATFORM_WIN32_KHR is defined, instead of including vulkan.h directly, we include individual parts of the SDK
+ * This is necessary to avoid including <windows.h> which is very heavy - it takes 200ms to parse without WIN32_LEAN_AND_MEAN
+ * and 100ms to parse with it. vulkan_win32.h only needs a few symbols that are easy to redefine ourselves.
+ */
+ typedef unsigned long DWORD;
+ typedef const wchar_t* LPCWSTR;
+ typedef void* HANDLE;
+ typedef struct HINSTANCE__* HINSTANCE;
+ typedef struct HWND__* HWND;
+ typedef struct HMONITOR__* HMONITOR;
+ typedef struct _SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES;
+
+# include <vulkan/vulkan_win32.h>
+
+# ifdef VK_ENABLE_BETA_EXTENSIONS
+# include <vulkan/vulkan_beta.h>
+# endif
+# else
+# include <vulkan/vulkan.h>
+# endif
+#endif
+
+/* Disable several extensions on earlier SDKs because later SDKs introduce a backwards incompatible change to function signatures */
+#if VK_HEADER_VERSION < 140
+# undef VK_NVX_image_view_handle
+#endif
+#if VK_HEADER_VERSION < 184
+# undef VK_HUAWEI_subpass_shading
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct VolkDeviceTable;
+
+/**
+ * Initialize library by loading Vulkan loader; call this function before creating the Vulkan instance.
+ *
+ * Returns VK_SUCCESS on success and VK_ERROR_INITIALIZATION_FAILED otherwise.
+ */
+VkResult volkInitialize(void);
+
+/**
+ * Initialize library by providing a custom handler to load global symbols.
+ *
+ * This function can be used instead of volkInitialize.
+ * The handler function pointer will be asked to load global Vulkan symbols which require no instance
+ * (such as vkCreateInstance, vkEnumerateInstance* and vkEnumerateInstanceVersion if available).
+ */
+void volkInitializeCustom(PFN_vkGetInstanceProcAddr handler);
+
+/**
+ * Get Vulkan instance version supported by the Vulkan loader, or 0 if Vulkan isn't supported
+ *
+ * Returns 0 if volkInitialize wasn't called or failed.
+ */
+uint32_t volkGetInstanceVersion(void);
+
+/**
+ * Load global function pointers using application-created VkInstance; call this function after creating the Vulkan instance.
+ */
+void volkLoadInstance(VkInstance instance);
+
+/**
+ * Load global function pointers using application-created VkInstance; call this function after creating the Vulkan instance.
+ * Skips loading device-based function pointers, requires usage of volkLoadDevice afterwards.
+ */
+void volkLoadInstanceOnly(VkInstance instance);
+
+/**
+ * Load global function pointers using application-created VkDevice; call this function after creating the Vulkan device.
+ *
+ * Note: this is not suitable for applications that want to use multiple VkDevice objects concurrently.
+ */
+void volkLoadDevice(VkDevice device);
+
+/**
+ * Return last VkInstance for which global function pointers have been loaded via volkLoadInstance(),
+ * or VK_NULL_HANDLE if volkLoadInstance() has not been called.
+ */
+VkInstance volkGetLoadedInstance(void);
+
+/**
+ * Return last VkDevice for which global function pointers have been loaded via volkLoadDevice(),
+ * or VK_NULL_HANDLE if volkLoadDevice() has not been called.
+ */
+VkDevice volkGetLoadedDevice(void);
+
+/**
+ * Load function pointers using application-created VkDevice into a table.
+ * Application should use function pointers from that table instead of using global function pointers.
+ */
+void volkLoadDeviceTable(struct VolkDeviceTable* table, VkDevice device);
+
+/**
+ * Device-specific function pointer table
+ */
+struct VolkDeviceTable
+{
+ /* VOLK_GENERATE_DEVICE_TABLE */
+#if defined(VK_VERSION_1_0)
+ PFN_vkAllocateCommandBuffers vkAllocateCommandBuffers;
+ PFN_vkAllocateDescriptorSets vkAllocateDescriptorSets;
+ PFN_vkAllocateMemory vkAllocateMemory;
+ PFN_vkBeginCommandBuffer vkBeginCommandBuffer;
+ PFN_vkBindBufferMemory vkBindBufferMemory;
+ PFN_vkBindImageMemory vkBindImageMemory;
+ PFN_vkCmdBeginQuery vkCmdBeginQuery;
+ PFN_vkCmdBeginRenderPass vkCmdBeginRenderPass;
+ PFN_vkCmdBindDescriptorSets vkCmdBindDescriptorSets;
+ PFN_vkCmdBindIndexBuffer vkCmdBindIndexBuffer;
+ PFN_vkCmdBindPipeline vkCmdBindPipeline;
+ PFN_vkCmdBindVertexBuffers vkCmdBindVertexBuffers;
+ PFN_vkCmdBlitImage vkCmdBlitImage;
+ PFN_vkCmdClearAttachments vkCmdClearAttachments;
+ PFN_vkCmdClearColorImage vkCmdClearColorImage;
+ PFN_vkCmdClearDepthStencilImage vkCmdClearDepthStencilImage;
+ PFN_vkCmdCopyBuffer vkCmdCopyBuffer;
+ PFN_vkCmdCopyBufferToImage vkCmdCopyBufferToImage;
+ PFN_vkCmdCopyImage vkCmdCopyImage;
+ PFN_vkCmdCopyImageToBuffer vkCmdCopyImageToBuffer;
+ PFN_vkCmdCopyQueryPoolResults vkCmdCopyQueryPoolResults;
+ PFN_vkCmdDispatch vkCmdDispatch;
+ PFN_vkCmdDispatchIndirect vkCmdDispatchIndirect;
+ PFN_vkCmdDraw vkCmdDraw;
+ PFN_vkCmdDrawIndexed vkCmdDrawIndexed;
+ PFN_vkCmdDrawIndexedIndirect vkCmdDrawIndexedIndirect;
+ PFN_vkCmdDrawIndirect vkCmdDrawIndirect;
+ PFN_vkCmdEndQuery vkCmdEndQuery;
+ PFN_vkCmdEndRenderPass vkCmdEndRenderPass;
+ PFN_vkCmdExecuteCommands vkCmdExecuteCommands;
+ PFN_vkCmdFillBuffer vkCmdFillBuffer;
+ PFN_vkCmdNextSubpass vkCmdNextSubpass;
+ PFN_vkCmdPipelineBarrier vkCmdPipelineBarrier;
+ PFN_vkCmdPushConstants vkCmdPushConstants;
+ PFN_vkCmdResetEvent vkCmdResetEvent;
+ PFN_vkCmdResetQueryPool vkCmdResetQueryPool;
+ PFN_vkCmdResolveImage vkCmdResolveImage;
+ PFN_vkCmdSetBlendConstants vkCmdSetBlendConstants;
+ PFN_vkCmdSetDepthBias vkCmdSetDepthBias;
+ PFN_vkCmdSetDepthBounds vkCmdSetDepthBounds;
+ PFN_vkCmdSetEvent vkCmdSetEvent;
+ PFN_vkCmdSetLineWidth vkCmdSetLineWidth;
+ PFN_vkCmdSetScissor vkCmdSetScissor;
+ PFN_vkCmdSetStencilCompareMask vkCmdSetStencilCompareMask;
+ PFN_vkCmdSetStencilReference vkCmdSetStencilReference;
+ PFN_vkCmdSetStencilWriteMask vkCmdSetStencilWriteMask;
+ PFN_vkCmdSetViewport vkCmdSetViewport;
+ PFN_vkCmdUpdateBuffer vkCmdUpdateBuffer;
+ PFN_vkCmdWaitEvents vkCmdWaitEvents;
+ PFN_vkCmdWriteTimestamp vkCmdWriteTimestamp;
+ PFN_vkCreateBuffer vkCreateBuffer;
+ PFN_vkCreateBufferView vkCreateBufferView;
+ PFN_vkCreateCommandPool vkCreateCommandPool;
+ PFN_vkCreateComputePipelines vkCreateComputePipelines;
+ PFN_vkCreateDescriptorPool vkCreateDescriptorPool;
+ PFN_vkCreateDescriptorSetLayout vkCreateDescriptorSetLayout;
+ PFN_vkCreateEvent vkCreateEvent;
+ PFN_vkCreateFence vkCreateFence;
+ PFN_vkCreateFramebuffer vkCreateFramebuffer;
+ PFN_vkCreateGraphicsPipelines vkCreateGraphicsPipelines;
+ PFN_vkCreateImage vkCreateImage;
+ PFN_vkCreateImageView vkCreateImageView;
+ PFN_vkCreatePipelineCache vkCreatePipelineCache;
+ PFN_vkCreatePipelineLayout vkCreatePipelineLayout;
+ PFN_vkCreateQueryPool vkCreateQueryPool;
+ PFN_vkCreateRenderPass vkCreateRenderPass;
+ PFN_vkCreateSampler vkCreateSampler;
+ PFN_vkCreateSemaphore vkCreateSemaphore;
+ PFN_vkCreateShaderModule vkCreateShaderModule;
+ PFN_vkDestroyBuffer vkDestroyBuffer;
+ PFN_vkDestroyBufferView vkDestroyBufferView;
+ PFN_vkDestroyCommandPool vkDestroyCommandPool;
+ PFN_vkDestroyDescriptorPool vkDestroyDescriptorPool;
+ PFN_vkDestroyDescriptorSetLayout vkDestroyDescriptorSetLayout;
+ PFN_vkDestroyDevice vkDestroyDevice;
+ PFN_vkDestroyEvent vkDestroyEvent;
+ PFN_vkDestroyFence vkDestroyFence;
+ PFN_vkDestroyFramebuffer vkDestroyFramebuffer;
+ PFN_vkDestroyImage vkDestroyImage;
+ PFN_vkDestroyImageView vkDestroyImageView;
+ PFN_vkDestroyPipeline vkDestroyPipeline;
+ PFN_vkDestroyPipelineCache vkDestroyPipelineCache;
+ PFN_vkDestroyPipelineLayout vkDestroyPipelineLayout;
+ PFN_vkDestroyQueryPool vkDestroyQueryPool;
+ PFN_vkDestroyRenderPass vkDestroyRenderPass;
+ PFN_vkDestroySampler vkDestroySampler;
+ PFN_vkDestroySemaphore vkDestroySemaphore;
+ PFN_vkDestroyShaderModule vkDestroyShaderModule;
+ PFN_vkDeviceWaitIdle vkDeviceWaitIdle;
+ PFN_vkEndCommandBuffer vkEndCommandBuffer;
+ PFN_vkFlushMappedMemoryRanges vkFlushMappedMemoryRanges;
+ PFN_vkFreeCommandBuffers vkFreeCommandBuffers;
+ PFN_vkFreeDescriptorSets vkFreeDescriptorSets;
+ PFN_vkFreeMemory vkFreeMemory;
+ PFN_vkGetBufferMemoryRequirements vkGetBufferMemoryRequirements;
+ PFN_vkGetDeviceMemoryCommitment vkGetDeviceMemoryCommitment;
+ PFN_vkGetDeviceQueue vkGetDeviceQueue;
+ PFN_vkGetEventStatus vkGetEventStatus;
+ PFN_vkGetFenceStatus vkGetFenceStatus;
+ PFN_vkGetImageMemoryRequirements vkGetImageMemoryRequirements;
+ PFN_vkGetImageSparseMemoryRequirements vkGetImageSparseMemoryRequirements;
+ PFN_vkGetImageSubresourceLayout vkGetImageSubresourceLayout;
+ PFN_vkGetPipelineCacheData vkGetPipelineCacheData;
+ PFN_vkGetQueryPoolResults vkGetQueryPoolResults;
+ PFN_vkGetRenderAreaGranularity vkGetRenderAreaGranularity;
+ PFN_vkInvalidateMappedMemoryRanges vkInvalidateMappedMemoryRanges;
+ PFN_vkMapMemory vkMapMemory;
+ PFN_vkMergePipelineCaches vkMergePipelineCaches;
+ PFN_vkQueueBindSparse vkQueueBindSparse;
+ PFN_vkQueueSubmit vkQueueSubmit;
+ PFN_vkQueueWaitIdle vkQueueWaitIdle;
+ PFN_vkResetCommandBuffer vkResetCommandBuffer;
+ PFN_vkResetCommandPool vkResetCommandPool;
+ PFN_vkResetDescriptorPool vkResetDescriptorPool;
+ PFN_vkResetEvent vkResetEvent;
+ PFN_vkResetFences vkResetFences;
+ PFN_vkSetEvent vkSetEvent;
+ PFN_vkUnmapMemory vkUnmapMemory;
+ PFN_vkUpdateDescriptorSets vkUpdateDescriptorSets;
+ PFN_vkWaitForFences vkWaitForFences;
+#endif /* defined(VK_VERSION_1_0) */
+#if defined(VK_VERSION_1_1)
+ PFN_vkBindBufferMemory2 vkBindBufferMemory2;
+ PFN_vkBindImageMemory2 vkBindImageMemory2;
+ PFN_vkCmdDispatchBase vkCmdDispatchBase;
+ PFN_vkCmdSetDeviceMask vkCmdSetDeviceMask;
+ PFN_vkCreateDescriptorUpdateTemplate vkCreateDescriptorUpdateTemplate;
+ PFN_vkCreateSamplerYcbcrConversion vkCreateSamplerYcbcrConversion;
+ PFN_vkDestroyDescriptorUpdateTemplate vkDestroyDescriptorUpdateTemplate;
+ PFN_vkDestroySamplerYcbcrConversion vkDestroySamplerYcbcrConversion;
+ PFN_vkGetBufferMemoryRequirements2 vkGetBufferMemoryRequirements2;
+ PFN_vkGetDescriptorSetLayoutSupport vkGetDescriptorSetLayoutSupport;
+ PFN_vkGetDeviceGroupPeerMemoryFeatures vkGetDeviceGroupPeerMemoryFeatures;
+ PFN_vkGetDeviceQueue2 vkGetDeviceQueue2;
+ PFN_vkGetImageMemoryRequirements2 vkGetImageMemoryRequirements2;
+ PFN_vkGetImageSparseMemoryRequirements2 vkGetImageSparseMemoryRequirements2;
+ PFN_vkTrimCommandPool vkTrimCommandPool;
+ PFN_vkUpdateDescriptorSetWithTemplate vkUpdateDescriptorSetWithTemplate;
+#endif /* defined(VK_VERSION_1_1) */
+#if defined(VK_VERSION_1_2)
+ PFN_vkCmdBeginRenderPass2 vkCmdBeginRenderPass2;
+ PFN_vkCmdDrawIndexedIndirectCount vkCmdDrawIndexedIndirectCount;
+ PFN_vkCmdDrawIndirectCount vkCmdDrawIndirectCount;
+ PFN_vkCmdEndRenderPass2 vkCmdEndRenderPass2;
+ PFN_vkCmdNextSubpass2 vkCmdNextSubpass2;
+ PFN_vkCreateRenderPass2 vkCreateRenderPass2;
+ PFN_vkGetBufferDeviceAddress vkGetBufferDeviceAddress;
+ PFN_vkGetBufferOpaqueCaptureAddress vkGetBufferOpaqueCaptureAddress;
+ PFN_vkGetDeviceMemoryOpaqueCaptureAddress vkGetDeviceMemoryOpaqueCaptureAddress;
+ PFN_vkGetSemaphoreCounterValue vkGetSemaphoreCounterValue;
+ PFN_vkResetQueryPool vkResetQueryPool;
+ PFN_vkSignalSemaphore vkSignalSemaphore;
+ PFN_vkWaitSemaphores vkWaitSemaphores;
+#endif /* defined(VK_VERSION_1_2) */
+#if defined(VK_VERSION_1_3)
+ PFN_vkCmdBeginRendering vkCmdBeginRendering;
+ PFN_vkCmdBindVertexBuffers2 vkCmdBindVertexBuffers2;
+ PFN_vkCmdBlitImage2 vkCmdBlitImage2;
+ PFN_vkCmdCopyBuffer2 vkCmdCopyBuffer2;
+ PFN_vkCmdCopyBufferToImage2 vkCmdCopyBufferToImage2;
+ PFN_vkCmdCopyImage2 vkCmdCopyImage2;
+ PFN_vkCmdCopyImageToBuffer2 vkCmdCopyImageToBuffer2;
+ PFN_vkCmdEndRendering vkCmdEndRendering;
+ PFN_vkCmdPipelineBarrier2 vkCmdPipelineBarrier2;
+ PFN_vkCmdResetEvent2 vkCmdResetEvent2;
+ PFN_vkCmdResolveImage2 vkCmdResolveImage2;
+ PFN_vkCmdSetCullMode vkCmdSetCullMode;
+ PFN_vkCmdSetDepthBiasEnable vkCmdSetDepthBiasEnable;
+ PFN_vkCmdSetDepthBoundsTestEnable vkCmdSetDepthBoundsTestEnable;
+ PFN_vkCmdSetDepthCompareOp vkCmdSetDepthCompareOp;
+ PFN_vkCmdSetDepthTestEnable vkCmdSetDepthTestEnable;
+ PFN_vkCmdSetDepthWriteEnable vkCmdSetDepthWriteEnable;
+ PFN_vkCmdSetEvent2 vkCmdSetEvent2;
+ PFN_vkCmdSetFrontFace vkCmdSetFrontFace;
+ PFN_vkCmdSetPrimitiveRestartEnable vkCmdSetPrimitiveRestartEnable;
+ PFN_vkCmdSetPrimitiveTopology vkCmdSetPrimitiveTopology;
+ PFN_vkCmdSetRasterizerDiscardEnable vkCmdSetRasterizerDiscardEnable;
+ PFN_vkCmdSetScissorWithCount vkCmdSetScissorWithCount;
+ PFN_vkCmdSetStencilOp vkCmdSetStencilOp;
+ PFN_vkCmdSetStencilTestEnable vkCmdSetStencilTestEnable;
+ PFN_vkCmdSetViewportWithCount vkCmdSetViewportWithCount;
+ PFN_vkCmdWaitEvents2 vkCmdWaitEvents2;
+ PFN_vkCmdWriteTimestamp2 vkCmdWriteTimestamp2;
+ PFN_vkCreatePrivateDataSlot vkCreatePrivateDataSlot;
+ PFN_vkDestroyPrivateDataSlot vkDestroyPrivateDataSlot;
+ PFN_vkGetDeviceBufferMemoryRequirements vkGetDeviceBufferMemoryRequirements;
+ PFN_vkGetDeviceImageMemoryRequirements vkGetDeviceImageMemoryRequirements;
+ PFN_vkGetDeviceImageSparseMemoryRequirements vkGetDeviceImageSparseMemoryRequirements;
+ PFN_vkGetPrivateData vkGetPrivateData;
+ PFN_vkQueueSubmit2 vkQueueSubmit2;
+ PFN_vkSetPrivateData vkSetPrivateData;
+#endif /* defined(VK_VERSION_1_3) */
+#if defined(VK_AMD_buffer_marker)
+ PFN_vkCmdWriteBufferMarkerAMD vkCmdWriteBufferMarkerAMD;
+#endif /* defined(VK_AMD_buffer_marker) */
+#if defined(VK_AMD_display_native_hdr)
+ PFN_vkSetLocalDimmingAMD vkSetLocalDimmingAMD;
+#endif /* defined(VK_AMD_display_native_hdr) */
+#if defined(VK_AMD_draw_indirect_count)
+ PFN_vkCmdDrawIndexedIndirectCountAMD vkCmdDrawIndexedIndirectCountAMD;
+ PFN_vkCmdDrawIndirectCountAMD vkCmdDrawIndirectCountAMD;
+#endif /* defined(VK_AMD_draw_indirect_count) */
+#if defined(VK_AMD_shader_info)
+ PFN_vkGetShaderInfoAMD vkGetShaderInfoAMD;
+#endif /* defined(VK_AMD_shader_info) */
+#if defined(VK_ANDROID_external_memory_android_hardware_buffer)
+ PFN_vkGetAndroidHardwareBufferPropertiesANDROID vkGetAndroidHardwareBufferPropertiesANDROID;
+ PFN_vkGetMemoryAndroidHardwareBufferANDROID vkGetMemoryAndroidHardwareBufferANDROID;
+#endif /* defined(VK_ANDROID_external_memory_android_hardware_buffer) */
+#if defined(VK_EXT_buffer_device_address)
+ PFN_vkGetBufferDeviceAddressEXT vkGetBufferDeviceAddressEXT;
+#endif /* defined(VK_EXT_buffer_device_address) */
+#if defined(VK_EXT_calibrated_timestamps)
+ PFN_vkGetCalibratedTimestampsEXT vkGetCalibratedTimestampsEXT;
+#endif /* defined(VK_EXT_calibrated_timestamps) */
+#if defined(VK_EXT_color_write_enable)
+ PFN_vkCmdSetColorWriteEnableEXT vkCmdSetColorWriteEnableEXT;
+#endif /* defined(VK_EXT_color_write_enable) */
+#if defined(VK_EXT_conditional_rendering)
+ PFN_vkCmdBeginConditionalRenderingEXT vkCmdBeginConditionalRenderingEXT;
+ PFN_vkCmdEndConditionalRenderingEXT vkCmdEndConditionalRenderingEXT;
+#endif /* defined(VK_EXT_conditional_rendering) */
+#if defined(VK_EXT_debug_marker)
+ PFN_vkCmdDebugMarkerBeginEXT vkCmdDebugMarkerBeginEXT;
+ PFN_vkCmdDebugMarkerEndEXT vkCmdDebugMarkerEndEXT;
+ PFN_vkCmdDebugMarkerInsertEXT vkCmdDebugMarkerInsertEXT;
+ PFN_vkDebugMarkerSetObjectNameEXT vkDebugMarkerSetObjectNameEXT;
+ PFN_vkDebugMarkerSetObjectTagEXT vkDebugMarkerSetObjectTagEXT;
+#endif /* defined(VK_EXT_debug_marker) */
+#if defined(VK_EXT_discard_rectangles)
+ PFN_vkCmdSetDiscardRectangleEXT vkCmdSetDiscardRectangleEXT;
+#endif /* defined(VK_EXT_discard_rectangles) */
+#if defined(VK_EXT_display_control)
+ PFN_vkDisplayPowerControlEXT vkDisplayPowerControlEXT;
+ PFN_vkGetSwapchainCounterEXT vkGetSwapchainCounterEXT;
+ PFN_vkRegisterDeviceEventEXT vkRegisterDeviceEventEXT;
+ PFN_vkRegisterDisplayEventEXT vkRegisterDisplayEventEXT;
+#endif /* defined(VK_EXT_display_control) */
+#if defined(VK_EXT_extended_dynamic_state)
+ PFN_vkCmdBindVertexBuffers2EXT vkCmdBindVertexBuffers2EXT;
+ PFN_vkCmdSetCullModeEXT vkCmdSetCullModeEXT;
+ PFN_vkCmdSetDepthBoundsTestEnableEXT vkCmdSetDepthBoundsTestEnableEXT;
+ PFN_vkCmdSetDepthCompareOpEXT vkCmdSetDepthCompareOpEXT;
+ PFN_vkCmdSetDepthTestEnableEXT vkCmdSetDepthTestEnableEXT;
+ PFN_vkCmdSetDepthWriteEnableEXT vkCmdSetDepthWriteEnableEXT;
+ PFN_vkCmdSetFrontFaceEXT vkCmdSetFrontFaceEXT;
+ PFN_vkCmdSetPrimitiveTopologyEXT vkCmdSetPrimitiveTopologyEXT;
+ PFN_vkCmdSetScissorWithCountEXT vkCmdSetScissorWithCountEXT;
+ PFN_vkCmdSetStencilOpEXT vkCmdSetStencilOpEXT;
+ PFN_vkCmdSetStencilTestEnableEXT vkCmdSetStencilTestEnableEXT;
+ PFN_vkCmdSetViewportWithCountEXT vkCmdSetViewportWithCountEXT;
+#endif /* defined(VK_EXT_extended_dynamic_state) */
+#if defined(VK_EXT_extended_dynamic_state2)
+ PFN_vkCmdSetDepthBiasEnableEXT vkCmdSetDepthBiasEnableEXT;
+ PFN_vkCmdSetLogicOpEXT vkCmdSetLogicOpEXT;
+ PFN_vkCmdSetPatchControlPointsEXT vkCmdSetPatchControlPointsEXT;
+ PFN_vkCmdSetPrimitiveRestartEnableEXT vkCmdSetPrimitiveRestartEnableEXT;
+ PFN_vkCmdSetRasterizerDiscardEnableEXT vkCmdSetRasterizerDiscardEnableEXT;
+#endif /* defined(VK_EXT_extended_dynamic_state2) */
+#if defined(VK_EXT_external_memory_host)
+ PFN_vkGetMemoryHostPointerPropertiesEXT vkGetMemoryHostPointerPropertiesEXT;
+#endif /* defined(VK_EXT_external_memory_host) */
+#if defined(VK_EXT_full_screen_exclusive)
+ PFN_vkAcquireFullScreenExclusiveModeEXT vkAcquireFullScreenExclusiveModeEXT;
+ PFN_vkReleaseFullScreenExclusiveModeEXT vkReleaseFullScreenExclusiveModeEXT;
+#endif /* defined(VK_EXT_full_screen_exclusive) */
+#if defined(VK_EXT_hdr_metadata)
+ PFN_vkSetHdrMetadataEXT vkSetHdrMetadataEXT;
+#endif /* defined(VK_EXT_hdr_metadata) */
+#if defined(VK_EXT_host_query_reset)
+ PFN_vkResetQueryPoolEXT vkResetQueryPoolEXT;
+#endif /* defined(VK_EXT_host_query_reset) */
+#if defined(VK_EXT_image_drm_format_modifier)
+ PFN_vkGetImageDrmFormatModifierPropertiesEXT vkGetImageDrmFormatModifierPropertiesEXT;
+#endif /* defined(VK_EXT_image_drm_format_modifier) */
+#if defined(VK_EXT_line_rasterization)
+ PFN_vkCmdSetLineStippleEXT vkCmdSetLineStippleEXT;
+#endif /* defined(VK_EXT_line_rasterization) */
+#if defined(VK_EXT_multi_draw)
+ PFN_vkCmdDrawMultiEXT vkCmdDrawMultiEXT;
+ PFN_vkCmdDrawMultiIndexedEXT vkCmdDrawMultiIndexedEXT;
+#endif /* defined(VK_EXT_multi_draw) */
+#if defined(VK_EXT_pageable_device_local_memory)
+ PFN_vkSetDeviceMemoryPriorityEXT vkSetDeviceMemoryPriorityEXT;
+#endif /* defined(VK_EXT_pageable_device_local_memory) */
+#if defined(VK_EXT_private_data)
+ PFN_vkCreatePrivateDataSlotEXT vkCreatePrivateDataSlotEXT;
+ PFN_vkDestroyPrivateDataSlotEXT vkDestroyPrivateDataSlotEXT;
+ PFN_vkGetPrivateDataEXT vkGetPrivateDataEXT;
+ PFN_vkSetPrivateDataEXT vkSetPrivateDataEXT;
+#endif /* defined(VK_EXT_private_data) */
+#if defined(VK_EXT_sample_locations)
+ PFN_vkCmdSetSampleLocationsEXT vkCmdSetSampleLocationsEXT;
+#endif /* defined(VK_EXT_sample_locations) */
+#if defined(VK_EXT_transform_feedback)
+ PFN_vkCmdBeginQueryIndexedEXT vkCmdBeginQueryIndexedEXT;
+ PFN_vkCmdBeginTransformFeedbackEXT vkCmdBeginTransformFeedbackEXT;
+ PFN_vkCmdBindTransformFeedbackBuffersEXT vkCmdBindTransformFeedbackBuffersEXT;
+ PFN_vkCmdDrawIndirectByteCountEXT vkCmdDrawIndirectByteCountEXT;
+ PFN_vkCmdEndQueryIndexedEXT vkCmdEndQueryIndexedEXT;
+ PFN_vkCmdEndTransformFeedbackEXT vkCmdEndTransformFeedbackEXT;
+#endif /* defined(VK_EXT_transform_feedback) */
+#if defined(VK_EXT_validation_cache)
+ PFN_vkCreateValidationCacheEXT vkCreateValidationCacheEXT;
+ PFN_vkDestroyValidationCacheEXT vkDestroyValidationCacheEXT;
+ PFN_vkGetValidationCacheDataEXT vkGetValidationCacheDataEXT;
+ PFN_vkMergeValidationCachesEXT vkMergeValidationCachesEXT;
+#endif /* defined(VK_EXT_validation_cache) */
+#if defined(VK_EXT_vertex_input_dynamic_state)
+ PFN_vkCmdSetVertexInputEXT vkCmdSetVertexInputEXT;
+#endif /* defined(VK_EXT_vertex_input_dynamic_state) */
+#if defined(VK_FUCHSIA_buffer_collection)
+ PFN_vkCreateBufferCollectionFUCHSIA vkCreateBufferCollectionFUCHSIA;
+ PFN_vkDestroyBufferCollectionFUCHSIA vkDestroyBufferCollectionFUCHSIA;
+ PFN_vkGetBufferCollectionPropertiesFUCHSIA vkGetBufferCollectionPropertiesFUCHSIA;
+ PFN_vkSetBufferCollectionBufferConstraintsFUCHSIA vkSetBufferCollectionBufferConstraintsFUCHSIA;
+ PFN_vkSetBufferCollectionImageConstraintsFUCHSIA vkSetBufferCollectionImageConstraintsFUCHSIA;
+#endif /* defined(VK_FUCHSIA_buffer_collection) */
+#if defined(VK_FUCHSIA_external_memory)
+ PFN_vkGetMemoryZirconHandleFUCHSIA vkGetMemoryZirconHandleFUCHSIA;
+ PFN_vkGetMemoryZirconHandlePropertiesFUCHSIA vkGetMemoryZirconHandlePropertiesFUCHSIA;
+#endif /* defined(VK_FUCHSIA_external_memory) */
+#if defined(VK_FUCHSIA_external_semaphore)
+ PFN_vkGetSemaphoreZirconHandleFUCHSIA vkGetSemaphoreZirconHandleFUCHSIA;
+ PFN_vkImportSemaphoreZirconHandleFUCHSIA vkImportSemaphoreZirconHandleFUCHSIA;
+#endif /* defined(VK_FUCHSIA_external_semaphore) */
+#if defined(VK_GOOGLE_display_timing)
+ PFN_vkGetPastPresentationTimingGOOGLE vkGetPastPresentationTimingGOOGLE;
+ PFN_vkGetRefreshCycleDurationGOOGLE vkGetRefreshCycleDurationGOOGLE;
+#endif /* defined(VK_GOOGLE_display_timing) */
+#if defined(VK_HUAWEI_invocation_mask)
+ PFN_vkCmdBindInvocationMaskHUAWEI vkCmdBindInvocationMaskHUAWEI;
+#endif /* defined(VK_HUAWEI_invocation_mask) */
+#if defined(VK_HUAWEI_subpass_shading)
+ PFN_vkCmdSubpassShadingHUAWEI vkCmdSubpassShadingHUAWEI;
+ PFN_vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI;
+#endif /* defined(VK_HUAWEI_subpass_shading) */
+#if defined(VK_INTEL_performance_query)
+ PFN_vkAcquirePerformanceConfigurationINTEL vkAcquirePerformanceConfigurationINTEL;
+ PFN_vkCmdSetPerformanceMarkerINTEL vkCmdSetPerformanceMarkerINTEL;
+ PFN_vkCmdSetPerformanceOverrideINTEL vkCmdSetPerformanceOverrideINTEL;
+ PFN_vkCmdSetPerformanceStreamMarkerINTEL vkCmdSetPerformanceStreamMarkerINTEL;
+ PFN_vkGetPerformanceParameterINTEL vkGetPerformanceParameterINTEL;
+ PFN_vkInitializePerformanceApiINTEL vkInitializePerformanceApiINTEL;
+ PFN_vkQueueSetPerformanceConfigurationINTEL vkQueueSetPerformanceConfigurationINTEL;
+ PFN_vkReleasePerformanceConfigurationINTEL vkReleasePerformanceConfigurationINTEL;
+ PFN_vkUninitializePerformanceApiINTEL vkUninitializePerformanceApiINTEL;
+#endif /* defined(VK_INTEL_performance_query) */
+#if defined(VK_KHR_acceleration_structure)
+ PFN_vkBuildAccelerationStructuresKHR vkBuildAccelerationStructuresKHR;
+ PFN_vkCmdBuildAccelerationStructuresIndirectKHR vkCmdBuildAccelerationStructuresIndirectKHR;
+ PFN_vkCmdBuildAccelerationStructuresKHR vkCmdBuildAccelerationStructuresKHR;
+ PFN_vkCmdCopyAccelerationStructureKHR vkCmdCopyAccelerationStructureKHR;
+ PFN_vkCmdCopyAccelerationStructureToMemoryKHR vkCmdCopyAccelerationStructureToMemoryKHR;
+ PFN_vkCmdCopyMemoryToAccelerationStructureKHR vkCmdCopyMemoryToAccelerationStructureKHR;
+ PFN_vkCmdWriteAccelerationStructuresPropertiesKHR vkCmdWriteAccelerationStructuresPropertiesKHR;
+ PFN_vkCopyAccelerationStructureKHR vkCopyAccelerationStructureKHR;
+ PFN_vkCopyAccelerationStructureToMemoryKHR vkCopyAccelerationStructureToMemoryKHR;
+ PFN_vkCopyMemoryToAccelerationStructureKHR vkCopyMemoryToAccelerationStructureKHR;
+ PFN_vkCreateAccelerationStructureKHR vkCreateAccelerationStructureKHR;
+ PFN_vkDestroyAccelerationStructureKHR vkDestroyAccelerationStructureKHR;
+ PFN_vkGetAccelerationStructureBuildSizesKHR vkGetAccelerationStructureBuildSizesKHR;
+ PFN_vkGetAccelerationStructureDeviceAddressKHR vkGetAccelerationStructureDeviceAddressKHR;
+ PFN_vkGetDeviceAccelerationStructureCompatibilityKHR vkGetDeviceAccelerationStructureCompatibilityKHR;
+ PFN_vkWriteAccelerationStructuresPropertiesKHR vkWriteAccelerationStructuresPropertiesKHR;
+#endif /* defined(VK_KHR_acceleration_structure) */
+#if defined(VK_KHR_bind_memory2)
+ PFN_vkBindBufferMemory2KHR vkBindBufferMemory2KHR;
+ PFN_vkBindImageMemory2KHR vkBindImageMemory2KHR;
+#endif /* defined(VK_KHR_bind_memory2) */
+#if defined(VK_KHR_buffer_device_address)
+ PFN_vkGetBufferDeviceAddressKHR vkGetBufferDeviceAddressKHR;
+ PFN_vkGetBufferOpaqueCaptureAddressKHR vkGetBufferOpaqueCaptureAddressKHR;
+ PFN_vkGetDeviceMemoryOpaqueCaptureAddressKHR vkGetDeviceMemoryOpaqueCaptureAddressKHR;
+#endif /* defined(VK_KHR_buffer_device_address) */
+#if defined(VK_KHR_copy_commands2)
+ PFN_vkCmdBlitImage2KHR vkCmdBlitImage2KHR;
+ PFN_vkCmdCopyBuffer2KHR vkCmdCopyBuffer2KHR;
+ PFN_vkCmdCopyBufferToImage2KHR vkCmdCopyBufferToImage2KHR;
+ PFN_vkCmdCopyImage2KHR vkCmdCopyImage2KHR;
+ PFN_vkCmdCopyImageToBuffer2KHR vkCmdCopyImageToBuffer2KHR;
+ PFN_vkCmdResolveImage2KHR vkCmdResolveImage2KHR;
+#endif /* defined(VK_KHR_copy_commands2) */
+#if defined(VK_KHR_create_renderpass2)
+ PFN_vkCmdBeginRenderPass2KHR vkCmdBeginRenderPass2KHR;
+ PFN_vkCmdEndRenderPass2KHR vkCmdEndRenderPass2KHR;
+ PFN_vkCmdNextSubpass2KHR vkCmdNextSubpass2KHR;
+ PFN_vkCreateRenderPass2KHR vkCreateRenderPass2KHR;
+#endif /* defined(VK_KHR_create_renderpass2) */
+#if defined(VK_KHR_deferred_host_operations)
+ PFN_vkCreateDeferredOperationKHR vkCreateDeferredOperationKHR;
+ PFN_vkDeferredOperationJoinKHR vkDeferredOperationJoinKHR;
+ PFN_vkDestroyDeferredOperationKHR vkDestroyDeferredOperationKHR;
+ PFN_vkGetDeferredOperationMaxConcurrencyKHR vkGetDeferredOperationMaxConcurrencyKHR;
+ PFN_vkGetDeferredOperationResultKHR vkGetDeferredOperationResultKHR;
+#endif /* defined(VK_KHR_deferred_host_operations) */
+#if defined(VK_KHR_descriptor_update_template)
+ PFN_vkCreateDescriptorUpdateTemplateKHR vkCreateDescriptorUpdateTemplateKHR;
+ PFN_vkDestroyDescriptorUpdateTemplateKHR vkDestroyDescriptorUpdateTemplateKHR;
+ PFN_vkUpdateDescriptorSetWithTemplateKHR vkUpdateDescriptorSetWithTemplateKHR;
+#endif /* defined(VK_KHR_descriptor_update_template) */
+#if defined(VK_KHR_device_group)
+ PFN_vkCmdDispatchBaseKHR vkCmdDispatchBaseKHR;
+ PFN_vkCmdSetDeviceMaskKHR vkCmdSetDeviceMaskKHR;
+ PFN_vkGetDeviceGroupPeerMemoryFeaturesKHR vkGetDeviceGroupPeerMemoryFeaturesKHR;
+#endif /* defined(VK_KHR_device_group) */
+#if defined(VK_KHR_display_swapchain)
+ PFN_vkCreateSharedSwapchainsKHR vkCreateSharedSwapchainsKHR;
+#endif /* defined(VK_KHR_display_swapchain) */
+#if defined(VK_KHR_draw_indirect_count)
+ PFN_vkCmdDrawIndexedIndirectCountKHR vkCmdDrawIndexedIndirectCountKHR;
+ PFN_vkCmdDrawIndirectCountKHR vkCmdDrawIndirectCountKHR;
+#endif /* defined(VK_KHR_draw_indirect_count) */
+#if defined(VK_KHR_dynamic_rendering)
+ PFN_vkCmdBeginRenderingKHR vkCmdBeginRenderingKHR;
+ PFN_vkCmdEndRenderingKHR vkCmdEndRenderingKHR;
+#endif /* defined(VK_KHR_dynamic_rendering) */
+#if defined(VK_KHR_external_fence_fd)
+ PFN_vkGetFenceFdKHR vkGetFenceFdKHR;
+ PFN_vkImportFenceFdKHR vkImportFenceFdKHR;
+#endif /* defined(VK_KHR_external_fence_fd) */
+#if defined(VK_KHR_external_fence_win32)
+ PFN_vkGetFenceWin32HandleKHR vkGetFenceWin32HandleKHR;
+ PFN_vkImportFenceWin32HandleKHR vkImportFenceWin32HandleKHR;
+#endif /* defined(VK_KHR_external_fence_win32) */
+#if defined(VK_KHR_external_memory_fd)
+ PFN_vkGetMemoryFdKHR vkGetMemoryFdKHR;
+ PFN_vkGetMemoryFdPropertiesKHR vkGetMemoryFdPropertiesKHR;
+#endif /* defined(VK_KHR_external_memory_fd) */
+#if defined(VK_KHR_external_memory_win32)
+ PFN_vkGetMemoryWin32HandleKHR vkGetMemoryWin32HandleKHR;
+ PFN_vkGetMemoryWin32HandlePropertiesKHR vkGetMemoryWin32HandlePropertiesKHR;
+#endif /* defined(VK_KHR_external_memory_win32) */
+#if defined(VK_KHR_external_semaphore_fd)
+ PFN_vkGetSemaphoreFdKHR vkGetSemaphoreFdKHR;
+ PFN_vkImportSemaphoreFdKHR vkImportSemaphoreFdKHR;
+#endif /* defined(VK_KHR_external_semaphore_fd) */
+#if defined(VK_KHR_external_semaphore_win32)
+ PFN_vkGetSemaphoreWin32HandleKHR vkGetSemaphoreWin32HandleKHR;
+ PFN_vkImportSemaphoreWin32HandleKHR vkImportSemaphoreWin32HandleKHR;
+#endif /* defined(VK_KHR_external_semaphore_win32) */
+#if defined(VK_KHR_fragment_shading_rate)
+ PFN_vkCmdSetFragmentShadingRateKHR vkCmdSetFragmentShadingRateKHR;
+#endif /* defined(VK_KHR_fragment_shading_rate) */
+#if defined(VK_KHR_get_memory_requirements2)
+ PFN_vkGetBufferMemoryRequirements2KHR vkGetBufferMemoryRequirements2KHR;
+ PFN_vkGetImageMemoryRequirements2KHR vkGetImageMemoryRequirements2KHR;
+ PFN_vkGetImageSparseMemoryRequirements2KHR vkGetImageSparseMemoryRequirements2KHR;
+#endif /* defined(VK_KHR_get_memory_requirements2) */
+#if defined(VK_KHR_maintenance1)
+ PFN_vkTrimCommandPoolKHR vkTrimCommandPoolKHR;
+#endif /* defined(VK_KHR_maintenance1) */
+#if defined(VK_KHR_maintenance3)
+ PFN_vkGetDescriptorSetLayoutSupportKHR vkGetDescriptorSetLayoutSupportKHR;
+#endif /* defined(VK_KHR_maintenance3) */
+#if defined(VK_KHR_maintenance4)
+ PFN_vkGetDeviceBufferMemoryRequirementsKHR vkGetDeviceBufferMemoryRequirementsKHR;
+ PFN_vkGetDeviceImageMemoryRequirementsKHR vkGetDeviceImageMemoryRequirementsKHR;
+ PFN_vkGetDeviceImageSparseMemoryRequirementsKHR vkGetDeviceImageSparseMemoryRequirementsKHR;
+#endif /* defined(VK_KHR_maintenance4) */
+#if defined(VK_KHR_performance_query)
+ PFN_vkAcquireProfilingLockKHR vkAcquireProfilingLockKHR;
+ PFN_vkReleaseProfilingLockKHR vkReleaseProfilingLockKHR;
+#endif /* defined(VK_KHR_performance_query) */
+#if defined(VK_KHR_pipeline_executable_properties)
+ PFN_vkGetPipelineExecutableInternalRepresentationsKHR vkGetPipelineExecutableInternalRepresentationsKHR;
+ PFN_vkGetPipelineExecutablePropertiesKHR vkGetPipelineExecutablePropertiesKHR;
+ PFN_vkGetPipelineExecutableStatisticsKHR vkGetPipelineExecutableStatisticsKHR;
+#endif /* defined(VK_KHR_pipeline_executable_properties) */
+#if defined(VK_KHR_present_wait)
+ PFN_vkWaitForPresentKHR vkWaitForPresentKHR;
+#endif /* defined(VK_KHR_present_wait) */
+#if defined(VK_KHR_push_descriptor)
+ PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSetKHR;
+#endif /* defined(VK_KHR_push_descriptor) */
+#if defined(VK_KHR_ray_tracing_pipeline)
+ PFN_vkCmdSetRayTracingPipelineStackSizeKHR vkCmdSetRayTracingPipelineStackSizeKHR;
+ PFN_vkCmdTraceRaysIndirectKHR vkCmdTraceRaysIndirectKHR;
+ PFN_vkCmdTraceRaysKHR vkCmdTraceRaysKHR;
+ PFN_vkCreateRayTracingPipelinesKHR vkCreateRayTracingPipelinesKHR;
+ PFN_vkGetRayTracingCaptureReplayShaderGroupHandlesKHR vkGetRayTracingCaptureReplayShaderGroupHandlesKHR;
+ PFN_vkGetRayTracingShaderGroupHandlesKHR vkGetRayTracingShaderGroupHandlesKHR;
+ PFN_vkGetRayTracingShaderGroupStackSizeKHR vkGetRayTracingShaderGroupStackSizeKHR;
+#endif /* defined(VK_KHR_ray_tracing_pipeline) */
+#if defined(VK_KHR_sampler_ycbcr_conversion)
+ PFN_vkCreateSamplerYcbcrConversionKHR vkCreateSamplerYcbcrConversionKHR;
+ PFN_vkDestroySamplerYcbcrConversionKHR vkDestroySamplerYcbcrConversionKHR;
+#endif /* defined(VK_KHR_sampler_ycbcr_conversion) */
+#if defined(VK_KHR_shared_presentable_image)
+ PFN_vkGetSwapchainStatusKHR vkGetSwapchainStatusKHR;
+#endif /* defined(VK_KHR_shared_presentable_image) */
+#if defined(VK_KHR_swapchain)
+ PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR;
+ PFN_vkCreateSwapchainKHR vkCreateSwapchainKHR;
+ PFN_vkDestroySwapchainKHR vkDestroySwapchainKHR;
+ PFN_vkGetSwapchainImagesKHR vkGetSwapchainImagesKHR;
+ PFN_vkQueuePresentKHR vkQueuePresentKHR;
+#endif /* defined(VK_KHR_swapchain) */
+#if defined(VK_KHR_synchronization2)
+ PFN_vkCmdPipelineBarrier2KHR vkCmdPipelineBarrier2KHR;
+ PFN_vkCmdResetEvent2KHR vkCmdResetEvent2KHR;
+ PFN_vkCmdSetEvent2KHR vkCmdSetEvent2KHR;
+ PFN_vkCmdWaitEvents2KHR vkCmdWaitEvents2KHR;
+ PFN_vkCmdWriteTimestamp2KHR vkCmdWriteTimestamp2KHR;
+ PFN_vkQueueSubmit2KHR vkQueueSubmit2KHR;
+#endif /* defined(VK_KHR_synchronization2) */
+#if defined(VK_KHR_synchronization2) && defined(VK_AMD_buffer_marker)
+ PFN_vkCmdWriteBufferMarker2AMD vkCmdWriteBufferMarker2AMD;
+#endif /* defined(VK_KHR_synchronization2) && defined(VK_AMD_buffer_marker) */
+#if defined(VK_KHR_synchronization2) && defined(VK_NV_device_diagnostic_checkpoints)
+ PFN_vkGetQueueCheckpointData2NV vkGetQueueCheckpointData2NV;
+#endif /* defined(VK_KHR_synchronization2) && defined(VK_NV_device_diagnostic_checkpoints) */
+#if defined(VK_KHR_timeline_semaphore)
+ PFN_vkGetSemaphoreCounterValueKHR vkGetSemaphoreCounterValueKHR;
+ PFN_vkSignalSemaphoreKHR vkSignalSemaphoreKHR;
+ PFN_vkWaitSemaphoresKHR vkWaitSemaphoresKHR;
+#endif /* defined(VK_KHR_timeline_semaphore) */
+#if defined(VK_KHR_video_decode_queue)
+ PFN_vkCmdDecodeVideoKHR vkCmdDecodeVideoKHR;
+#endif /* defined(VK_KHR_video_decode_queue) */
+#if defined(VK_KHR_video_encode_queue)
+ PFN_vkCmdEncodeVideoKHR vkCmdEncodeVideoKHR;
+#endif /* defined(VK_KHR_video_encode_queue) */
+#if defined(VK_KHR_video_queue)
+ PFN_vkBindVideoSessionMemoryKHR vkBindVideoSessionMemoryKHR;
+ PFN_vkCmdBeginVideoCodingKHR vkCmdBeginVideoCodingKHR;
+ PFN_vkCmdControlVideoCodingKHR vkCmdControlVideoCodingKHR;
+ PFN_vkCmdEndVideoCodingKHR vkCmdEndVideoCodingKHR;
+ PFN_vkCreateVideoSessionKHR vkCreateVideoSessionKHR;
+ PFN_vkCreateVideoSessionParametersKHR vkCreateVideoSessionParametersKHR;
+ PFN_vkDestroyVideoSessionKHR vkDestroyVideoSessionKHR;
+ PFN_vkDestroyVideoSessionParametersKHR vkDestroyVideoSessionParametersKHR;
+ PFN_vkGetVideoSessionMemoryRequirementsKHR vkGetVideoSessionMemoryRequirementsKHR;
+ PFN_vkUpdateVideoSessionParametersKHR vkUpdateVideoSessionParametersKHR;
+#endif /* defined(VK_KHR_video_queue) */
+#if defined(VK_NVX_binary_import)
+ PFN_vkCmdCuLaunchKernelNVX vkCmdCuLaunchKernelNVX;
+ PFN_vkCreateCuFunctionNVX vkCreateCuFunctionNVX;
+ PFN_vkCreateCuModuleNVX vkCreateCuModuleNVX;
+ PFN_vkDestroyCuFunctionNVX vkDestroyCuFunctionNVX;
+ PFN_vkDestroyCuModuleNVX vkDestroyCuModuleNVX;
+#endif /* defined(VK_NVX_binary_import) */
+#if defined(VK_NVX_image_view_handle)
+ PFN_vkGetImageViewAddressNVX vkGetImageViewAddressNVX;
+ PFN_vkGetImageViewHandleNVX vkGetImageViewHandleNVX;
+#endif /* defined(VK_NVX_image_view_handle) */
+#if defined(VK_NV_clip_space_w_scaling)
+ PFN_vkCmdSetViewportWScalingNV vkCmdSetViewportWScalingNV;
+#endif /* defined(VK_NV_clip_space_w_scaling) */
+#if defined(VK_NV_device_diagnostic_checkpoints)
+ PFN_vkCmdSetCheckpointNV vkCmdSetCheckpointNV;
+ PFN_vkGetQueueCheckpointDataNV vkGetQueueCheckpointDataNV;
+#endif /* defined(VK_NV_device_diagnostic_checkpoints) */
+#if defined(VK_NV_device_generated_commands)
+ PFN_vkCmdBindPipelineShaderGroupNV vkCmdBindPipelineShaderGroupNV;
+ PFN_vkCmdExecuteGeneratedCommandsNV vkCmdExecuteGeneratedCommandsNV;
+ PFN_vkCmdPreprocessGeneratedCommandsNV vkCmdPreprocessGeneratedCommandsNV;
+ PFN_vkCreateIndirectCommandsLayoutNV vkCreateIndirectCommandsLayoutNV;
+ PFN_vkDestroyIndirectCommandsLayoutNV vkDestroyIndirectCommandsLayoutNV;
+ PFN_vkGetGeneratedCommandsMemoryRequirementsNV vkGetGeneratedCommandsMemoryRequirementsNV;
+#endif /* defined(VK_NV_device_generated_commands) */
+#if defined(VK_NV_external_memory_rdma)
+ PFN_vkGetMemoryRemoteAddressNV vkGetMemoryRemoteAddressNV;
+#endif /* defined(VK_NV_external_memory_rdma) */
+#if defined(VK_NV_external_memory_win32)
+ PFN_vkGetMemoryWin32HandleNV vkGetMemoryWin32HandleNV;
+#endif /* defined(VK_NV_external_memory_win32) */
+#if defined(VK_NV_fragment_shading_rate_enums)
+ PFN_vkCmdSetFragmentShadingRateEnumNV vkCmdSetFragmentShadingRateEnumNV;
+#endif /* defined(VK_NV_fragment_shading_rate_enums) */
+#if defined(VK_NV_mesh_shader)
+ PFN_vkCmdDrawMeshTasksIndirectCountNV vkCmdDrawMeshTasksIndirectCountNV;
+ PFN_vkCmdDrawMeshTasksIndirectNV vkCmdDrawMeshTasksIndirectNV;
+ PFN_vkCmdDrawMeshTasksNV vkCmdDrawMeshTasksNV;
+#endif /* defined(VK_NV_mesh_shader) */
+#if defined(VK_NV_ray_tracing)
+ PFN_vkBindAccelerationStructureMemoryNV vkBindAccelerationStructureMemoryNV;
+ PFN_vkCmdBuildAccelerationStructureNV vkCmdBuildAccelerationStructureNV;
+ PFN_vkCmdCopyAccelerationStructureNV vkCmdCopyAccelerationStructureNV;
+ PFN_vkCmdTraceRaysNV vkCmdTraceRaysNV;
+ PFN_vkCmdWriteAccelerationStructuresPropertiesNV vkCmdWriteAccelerationStructuresPropertiesNV;
+ PFN_vkCompileDeferredNV vkCompileDeferredNV;
+ PFN_vkCreateAccelerationStructureNV vkCreateAccelerationStructureNV;
+ PFN_vkCreateRayTracingPipelinesNV vkCreateRayTracingPipelinesNV;
+ PFN_vkDestroyAccelerationStructureNV vkDestroyAccelerationStructureNV;
+ PFN_vkGetAccelerationStructureHandleNV vkGetAccelerationStructureHandleNV;
+ PFN_vkGetAccelerationStructureMemoryRequirementsNV vkGetAccelerationStructureMemoryRequirementsNV;
+ PFN_vkGetRayTracingShaderGroupHandlesNV vkGetRayTracingShaderGroupHandlesNV;
+#endif /* defined(VK_NV_ray_tracing) */
+#if defined(VK_NV_scissor_exclusive)
+ PFN_vkCmdSetExclusiveScissorNV vkCmdSetExclusiveScissorNV;
+#endif /* defined(VK_NV_scissor_exclusive) */
+#if defined(VK_NV_shading_rate_image)
+ PFN_vkCmdBindShadingRateImageNV vkCmdBindShadingRateImageNV;
+ PFN_vkCmdSetCoarseSampleOrderNV vkCmdSetCoarseSampleOrderNV;
+ PFN_vkCmdSetViewportShadingRatePaletteNV vkCmdSetViewportShadingRatePaletteNV;
+#endif /* defined(VK_NV_shading_rate_image) */
+#if (defined(VK_EXT_full_screen_exclusive) && defined(VK_KHR_device_group)) || (defined(VK_EXT_full_screen_exclusive) && defined(VK_VERSION_1_1))
+ PFN_vkGetDeviceGroupSurfacePresentModes2EXT vkGetDeviceGroupSurfacePresentModes2EXT;
+#endif /* (defined(VK_EXT_full_screen_exclusive) && defined(VK_KHR_device_group)) || (defined(VK_EXT_full_screen_exclusive) && defined(VK_VERSION_1_1)) */
+#if (defined(VK_KHR_descriptor_update_template) && defined(VK_KHR_push_descriptor)) || (defined(VK_KHR_push_descriptor) && defined(VK_VERSION_1_1)) || (defined(VK_KHR_push_descriptor) && defined(VK_KHR_descriptor_update_template))
+ PFN_vkCmdPushDescriptorSetWithTemplateKHR vkCmdPushDescriptorSetWithTemplateKHR;
+#endif /* (defined(VK_KHR_descriptor_update_template) && defined(VK_KHR_push_descriptor)) || (defined(VK_KHR_push_descriptor) && defined(VK_VERSION_1_1)) || (defined(VK_KHR_push_descriptor) && defined(VK_KHR_descriptor_update_template)) */
+#if (defined(VK_KHR_device_group) && defined(VK_KHR_surface)) || (defined(VK_KHR_swapchain) && defined(VK_VERSION_1_1))
+ PFN_vkGetDeviceGroupPresentCapabilitiesKHR vkGetDeviceGroupPresentCapabilitiesKHR;
+ PFN_vkGetDeviceGroupSurfacePresentModesKHR vkGetDeviceGroupSurfacePresentModesKHR;
+#endif /* (defined(VK_KHR_device_group) && defined(VK_KHR_surface)) || (defined(VK_KHR_swapchain) && defined(VK_VERSION_1_1)) */
+#if (defined(VK_KHR_device_group) && defined(VK_KHR_swapchain)) || (defined(VK_KHR_swapchain) && defined(VK_VERSION_1_1))
+ PFN_vkAcquireNextImage2KHR vkAcquireNextImage2KHR;
+#endif /* (defined(VK_KHR_device_group) && defined(VK_KHR_swapchain)) || (defined(VK_KHR_swapchain) && defined(VK_VERSION_1_1)) */
+ /* VOLK_GENERATE_DEVICE_TABLE */
+};
+
+/* VOLK_GENERATE_PROTOTYPES_H */
+#if defined(VK_VERSION_1_0)
+extern PFN_vkAllocateCommandBuffers vkAllocateCommandBuffers;
+extern PFN_vkAllocateDescriptorSets vkAllocateDescriptorSets;
+extern PFN_vkAllocateMemory vkAllocateMemory;
+extern PFN_vkBeginCommandBuffer vkBeginCommandBuffer;
+extern PFN_vkBindBufferMemory vkBindBufferMemory;
+extern PFN_vkBindImageMemory vkBindImageMemory;
+extern PFN_vkCmdBeginQuery vkCmdBeginQuery;
+extern PFN_vkCmdBeginRenderPass vkCmdBeginRenderPass;
+extern PFN_vkCmdBindDescriptorSets vkCmdBindDescriptorSets;
+extern PFN_vkCmdBindIndexBuffer vkCmdBindIndexBuffer;
+extern PFN_vkCmdBindPipeline vkCmdBindPipeline;
+extern PFN_vkCmdBindVertexBuffers vkCmdBindVertexBuffers;
+extern PFN_vkCmdBlitImage vkCmdBlitImage;
+extern PFN_vkCmdClearAttachments vkCmdClearAttachments;
+extern PFN_vkCmdClearColorImage vkCmdClearColorImage;
+extern PFN_vkCmdClearDepthStencilImage vkCmdClearDepthStencilImage;
+extern PFN_vkCmdCopyBuffer vkCmdCopyBuffer;
+extern PFN_vkCmdCopyBufferToImage vkCmdCopyBufferToImage;
+extern PFN_vkCmdCopyImage vkCmdCopyImage;
+extern PFN_vkCmdCopyImageToBuffer vkCmdCopyImageToBuffer;
+extern PFN_vkCmdCopyQueryPoolResults vkCmdCopyQueryPoolResults;
+extern PFN_vkCmdDispatch vkCmdDispatch;
+extern PFN_vkCmdDispatchIndirect vkCmdDispatchIndirect;
+extern PFN_vkCmdDraw vkCmdDraw;
+extern PFN_vkCmdDrawIndexed vkCmdDrawIndexed;
+extern PFN_vkCmdDrawIndexedIndirect vkCmdDrawIndexedIndirect;
+extern PFN_vkCmdDrawIndirect vkCmdDrawIndirect;
+extern PFN_vkCmdEndQuery vkCmdEndQuery;
+extern PFN_vkCmdEndRenderPass vkCmdEndRenderPass;
+extern PFN_vkCmdExecuteCommands vkCmdExecuteCommands;
+extern PFN_vkCmdFillBuffer vkCmdFillBuffer;
+extern PFN_vkCmdNextSubpass vkCmdNextSubpass;
+extern PFN_vkCmdPipelineBarrier vkCmdPipelineBarrier;
+extern PFN_vkCmdPushConstants vkCmdPushConstants;
+extern PFN_vkCmdResetEvent vkCmdResetEvent;
+extern PFN_vkCmdResetQueryPool vkCmdResetQueryPool;
+extern PFN_vkCmdResolveImage vkCmdResolveImage;
+extern PFN_vkCmdSetBlendConstants vkCmdSetBlendConstants;
+extern PFN_vkCmdSetDepthBias vkCmdSetDepthBias;
+extern PFN_vkCmdSetDepthBounds vkCmdSetDepthBounds;
+extern PFN_vkCmdSetEvent vkCmdSetEvent;
+extern PFN_vkCmdSetLineWidth vkCmdSetLineWidth;
+extern PFN_vkCmdSetScissor vkCmdSetScissor;
+extern PFN_vkCmdSetStencilCompareMask vkCmdSetStencilCompareMask;
+extern PFN_vkCmdSetStencilReference vkCmdSetStencilReference;
+extern PFN_vkCmdSetStencilWriteMask vkCmdSetStencilWriteMask;
+extern PFN_vkCmdSetViewport vkCmdSetViewport;
+extern PFN_vkCmdUpdateBuffer vkCmdUpdateBuffer;
+extern PFN_vkCmdWaitEvents vkCmdWaitEvents;
+extern PFN_vkCmdWriteTimestamp vkCmdWriteTimestamp;
+extern PFN_vkCreateBuffer vkCreateBuffer;
+extern PFN_vkCreateBufferView vkCreateBufferView;
+extern PFN_vkCreateCommandPool vkCreateCommandPool;
+extern PFN_vkCreateComputePipelines vkCreateComputePipelines;
+extern PFN_vkCreateDescriptorPool vkCreateDescriptorPool;
+extern PFN_vkCreateDescriptorSetLayout vkCreateDescriptorSetLayout;
+extern PFN_vkCreateDevice vkCreateDevice;
+extern PFN_vkCreateEvent vkCreateEvent;
+extern PFN_vkCreateFence vkCreateFence;
+extern PFN_vkCreateFramebuffer vkCreateFramebuffer;
+extern PFN_vkCreateGraphicsPipelines vkCreateGraphicsPipelines;
+extern PFN_vkCreateImage vkCreateImage;
+extern PFN_vkCreateImageView vkCreateImageView;
+extern PFN_vkCreateInstance vkCreateInstance;
+extern PFN_vkCreatePipelineCache vkCreatePipelineCache;
+extern PFN_vkCreatePipelineLayout vkCreatePipelineLayout;
+extern PFN_vkCreateQueryPool vkCreateQueryPool;
+extern PFN_vkCreateRenderPass vkCreateRenderPass;
+extern PFN_vkCreateSampler vkCreateSampler;
+extern PFN_vkCreateSemaphore vkCreateSemaphore;
+extern PFN_vkCreateShaderModule vkCreateShaderModule;
+extern PFN_vkDestroyBuffer vkDestroyBuffer;
+extern PFN_vkDestroyBufferView vkDestroyBufferView;
+extern PFN_vkDestroyCommandPool vkDestroyCommandPool;
+extern PFN_vkDestroyDescriptorPool vkDestroyDescriptorPool;
+extern PFN_vkDestroyDescriptorSetLayout vkDestroyDescriptorSetLayout;
+extern PFN_vkDestroyDevice vkDestroyDevice;
+extern PFN_vkDestroyEvent vkDestroyEvent;
+extern PFN_vkDestroyFence vkDestroyFence;
+extern PFN_vkDestroyFramebuffer vkDestroyFramebuffer;
+extern PFN_vkDestroyImage vkDestroyImage;
+extern PFN_vkDestroyImageView vkDestroyImageView;
+extern PFN_vkDestroyInstance vkDestroyInstance;
+extern PFN_vkDestroyPipeline vkDestroyPipeline;
+extern PFN_vkDestroyPipelineCache vkDestroyPipelineCache;
+extern PFN_vkDestroyPipelineLayout vkDestroyPipelineLayout;
+extern PFN_vkDestroyQueryPool vkDestroyQueryPool;
+extern PFN_vkDestroyRenderPass vkDestroyRenderPass;
+extern PFN_vkDestroySampler vkDestroySampler;
+extern PFN_vkDestroySemaphore vkDestroySemaphore;
+extern PFN_vkDestroyShaderModule vkDestroyShaderModule;
+extern PFN_vkDeviceWaitIdle vkDeviceWaitIdle;
+extern PFN_vkEndCommandBuffer vkEndCommandBuffer;
+extern PFN_vkEnumerateDeviceExtensionProperties vkEnumerateDeviceExtensionProperties;
+extern PFN_vkEnumerateDeviceLayerProperties vkEnumerateDeviceLayerProperties;
+extern PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties;
+extern PFN_vkEnumerateInstanceLayerProperties vkEnumerateInstanceLayerProperties;
+extern PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices;
+extern PFN_vkFlushMappedMemoryRanges vkFlushMappedMemoryRanges;
+extern PFN_vkFreeCommandBuffers vkFreeCommandBuffers;
+extern PFN_vkFreeDescriptorSets vkFreeDescriptorSets;
+extern PFN_vkFreeMemory vkFreeMemory;
+extern PFN_vkGetBufferMemoryRequirements vkGetBufferMemoryRequirements;
+extern PFN_vkGetDeviceMemoryCommitment vkGetDeviceMemoryCommitment;
+extern PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr;
+extern PFN_vkGetDeviceQueue vkGetDeviceQueue;
+extern PFN_vkGetEventStatus vkGetEventStatus;
+extern PFN_vkGetFenceStatus vkGetFenceStatus;
+extern PFN_vkGetImageMemoryRequirements vkGetImageMemoryRequirements;
+extern PFN_vkGetImageSparseMemoryRequirements vkGetImageSparseMemoryRequirements;
+extern PFN_vkGetImageSubresourceLayout vkGetImageSubresourceLayout;
+extern PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr;
+extern PFN_vkGetPhysicalDeviceFeatures vkGetPhysicalDeviceFeatures;
+extern PFN_vkGetPhysicalDeviceFormatProperties vkGetPhysicalDeviceFormatProperties;
+extern PFN_vkGetPhysicalDeviceImageFormatProperties vkGetPhysicalDeviceImageFormatProperties;
+extern PFN_vkGetPhysicalDeviceMemoryProperties vkGetPhysicalDeviceMemoryProperties;
+extern PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties;
+extern PFN_vkGetPhysicalDeviceQueueFamilyProperties vkGetPhysicalDeviceQueueFamilyProperties;
+extern PFN_vkGetPhysicalDeviceSparseImageFormatProperties vkGetPhysicalDeviceSparseImageFormatProperties;
+extern PFN_vkGetPipelineCacheData vkGetPipelineCacheData;
+extern PFN_vkGetQueryPoolResults vkGetQueryPoolResults;
+extern PFN_vkGetRenderAreaGranularity vkGetRenderAreaGranularity;
+extern PFN_vkInvalidateMappedMemoryRanges vkInvalidateMappedMemoryRanges;
+extern PFN_vkMapMemory vkMapMemory;
+extern PFN_vkMergePipelineCaches vkMergePipelineCaches;
+extern PFN_vkQueueBindSparse vkQueueBindSparse;
+extern PFN_vkQueueSubmit vkQueueSubmit;
+extern PFN_vkQueueWaitIdle vkQueueWaitIdle;
+extern PFN_vkResetCommandBuffer vkResetCommandBuffer;
+extern PFN_vkResetCommandPool vkResetCommandPool;
+extern PFN_vkResetDescriptorPool vkResetDescriptorPool;
+extern PFN_vkResetEvent vkResetEvent;
+extern PFN_vkResetFences vkResetFences;
+extern PFN_vkSetEvent vkSetEvent;
+extern PFN_vkUnmapMemory vkUnmapMemory;
+extern PFN_vkUpdateDescriptorSets vkUpdateDescriptorSets;
+extern PFN_vkWaitForFences vkWaitForFences;
+#endif /* defined(VK_VERSION_1_0) */
+#if defined(VK_VERSION_1_1)
+extern PFN_vkBindBufferMemory2 vkBindBufferMemory2;
+extern PFN_vkBindImageMemory2 vkBindImageMemory2;
+extern PFN_vkCmdDispatchBase vkCmdDispatchBase;
+extern PFN_vkCmdSetDeviceMask vkCmdSetDeviceMask;
+extern PFN_vkCreateDescriptorUpdateTemplate vkCreateDescriptorUpdateTemplate;
+extern PFN_vkCreateSamplerYcbcrConversion vkCreateSamplerYcbcrConversion;
+extern PFN_vkDestroyDescriptorUpdateTemplate vkDestroyDescriptorUpdateTemplate;
+extern PFN_vkDestroySamplerYcbcrConversion vkDestroySamplerYcbcrConversion;
+extern PFN_vkEnumerateInstanceVersion vkEnumerateInstanceVersion;
+extern PFN_vkEnumeratePhysicalDeviceGroups vkEnumeratePhysicalDeviceGroups;
+extern PFN_vkGetBufferMemoryRequirements2 vkGetBufferMemoryRequirements2;
+extern PFN_vkGetDescriptorSetLayoutSupport vkGetDescriptorSetLayoutSupport;
+extern PFN_vkGetDeviceGroupPeerMemoryFeatures vkGetDeviceGroupPeerMemoryFeatures;
+extern PFN_vkGetDeviceQueue2 vkGetDeviceQueue2;
+extern PFN_vkGetImageMemoryRequirements2 vkGetImageMemoryRequirements2;
+extern PFN_vkGetImageSparseMemoryRequirements2 vkGetImageSparseMemoryRequirements2;
+extern PFN_vkGetPhysicalDeviceExternalBufferProperties vkGetPhysicalDeviceExternalBufferProperties;
+extern PFN_vkGetPhysicalDeviceExternalFenceProperties vkGetPhysicalDeviceExternalFenceProperties;
+extern PFN_vkGetPhysicalDeviceExternalSemaphoreProperties vkGetPhysicalDeviceExternalSemaphoreProperties;
+extern PFN_vkGetPhysicalDeviceFeatures2 vkGetPhysicalDeviceFeatures2;
+extern PFN_vkGetPhysicalDeviceFormatProperties2 vkGetPhysicalDeviceFormatProperties2;
+extern PFN_vkGetPhysicalDeviceImageFormatProperties2 vkGetPhysicalDeviceImageFormatProperties2;
+extern PFN_vkGetPhysicalDeviceMemoryProperties2 vkGetPhysicalDeviceMemoryProperties2;
+extern PFN_vkGetPhysicalDeviceProperties2 vkGetPhysicalDeviceProperties2;
+extern PFN_vkGetPhysicalDeviceQueueFamilyProperties2 vkGetPhysicalDeviceQueueFamilyProperties2;
+extern PFN_vkGetPhysicalDeviceSparseImageFormatProperties2 vkGetPhysicalDeviceSparseImageFormatProperties2;
+extern PFN_vkTrimCommandPool vkTrimCommandPool;
+extern PFN_vkUpdateDescriptorSetWithTemplate vkUpdateDescriptorSetWithTemplate;
+#endif /* defined(VK_VERSION_1_1) */
+#if defined(VK_VERSION_1_2)
+extern PFN_vkCmdBeginRenderPass2 vkCmdBeginRenderPass2;
+extern PFN_vkCmdDrawIndexedIndirectCount vkCmdDrawIndexedIndirectCount;
+extern PFN_vkCmdDrawIndirectCount vkCmdDrawIndirectCount;
+extern PFN_vkCmdEndRenderPass2 vkCmdEndRenderPass2;
+extern PFN_vkCmdNextSubpass2 vkCmdNextSubpass2;
+extern PFN_vkCreateRenderPass2 vkCreateRenderPass2;
+extern PFN_vkGetBufferDeviceAddress vkGetBufferDeviceAddress;
+extern PFN_vkGetBufferOpaqueCaptureAddress vkGetBufferOpaqueCaptureAddress;
+extern PFN_vkGetDeviceMemoryOpaqueCaptureAddress vkGetDeviceMemoryOpaqueCaptureAddress;
+extern PFN_vkGetSemaphoreCounterValue vkGetSemaphoreCounterValue;
+extern PFN_vkResetQueryPool vkResetQueryPool;
+extern PFN_vkSignalSemaphore vkSignalSemaphore;
+extern PFN_vkWaitSemaphores vkWaitSemaphores;
+#endif /* defined(VK_VERSION_1_2) */
+#if defined(VK_VERSION_1_3)
+extern PFN_vkCmdBeginRendering vkCmdBeginRendering;
+extern PFN_vkCmdBindVertexBuffers2 vkCmdBindVertexBuffers2;
+extern PFN_vkCmdBlitImage2 vkCmdBlitImage2;
+extern PFN_vkCmdCopyBuffer2 vkCmdCopyBuffer2;
+extern PFN_vkCmdCopyBufferToImage2 vkCmdCopyBufferToImage2;
+extern PFN_vkCmdCopyImage2 vkCmdCopyImage2;
+extern PFN_vkCmdCopyImageToBuffer2 vkCmdCopyImageToBuffer2;
+extern PFN_vkCmdEndRendering vkCmdEndRendering;
+extern PFN_vkCmdPipelineBarrier2 vkCmdPipelineBarrier2;
+extern PFN_vkCmdResetEvent2 vkCmdResetEvent2;
+extern PFN_vkCmdResolveImage2 vkCmdResolveImage2;
+extern PFN_vkCmdSetCullMode vkCmdSetCullMode;
+extern PFN_vkCmdSetDepthBiasEnable vkCmdSetDepthBiasEnable;
+extern PFN_vkCmdSetDepthBoundsTestEnable vkCmdSetDepthBoundsTestEnable;
+extern PFN_vkCmdSetDepthCompareOp vkCmdSetDepthCompareOp;
+extern PFN_vkCmdSetDepthTestEnable vkCmdSetDepthTestEnable;
+extern PFN_vkCmdSetDepthWriteEnable vkCmdSetDepthWriteEnable;
+extern PFN_vkCmdSetEvent2 vkCmdSetEvent2;
+extern PFN_vkCmdSetFrontFace vkCmdSetFrontFace;
+extern PFN_vkCmdSetPrimitiveRestartEnable vkCmdSetPrimitiveRestartEnable;
+extern PFN_vkCmdSetPrimitiveTopology vkCmdSetPrimitiveTopology;
+extern PFN_vkCmdSetRasterizerDiscardEnable vkCmdSetRasterizerDiscardEnable;
+extern PFN_vkCmdSetScissorWithCount vkCmdSetScissorWithCount;
+extern PFN_vkCmdSetStencilOp vkCmdSetStencilOp;
+extern PFN_vkCmdSetStencilTestEnable vkCmdSetStencilTestEnable;
+extern PFN_vkCmdSetViewportWithCount vkCmdSetViewportWithCount;
+extern PFN_vkCmdWaitEvents2 vkCmdWaitEvents2;
+extern PFN_vkCmdWriteTimestamp2 vkCmdWriteTimestamp2;
+extern PFN_vkCreatePrivateDataSlot vkCreatePrivateDataSlot;
+extern PFN_vkDestroyPrivateDataSlot vkDestroyPrivateDataSlot;
+extern PFN_vkGetDeviceBufferMemoryRequirements vkGetDeviceBufferMemoryRequirements;
+extern PFN_vkGetDeviceImageMemoryRequirements vkGetDeviceImageMemoryRequirements;
+extern PFN_vkGetDeviceImageSparseMemoryRequirements vkGetDeviceImageSparseMemoryRequirements;
+extern PFN_vkGetPhysicalDeviceToolProperties vkGetPhysicalDeviceToolProperties;
+extern PFN_vkGetPrivateData vkGetPrivateData;
+extern PFN_vkQueueSubmit2 vkQueueSubmit2;
+extern PFN_vkSetPrivateData vkSetPrivateData;
+#endif /* defined(VK_VERSION_1_3) */
+#if defined(VK_AMD_buffer_marker)
+extern PFN_vkCmdWriteBufferMarkerAMD vkCmdWriteBufferMarkerAMD;
+#endif /* defined(VK_AMD_buffer_marker) */
+#if defined(VK_AMD_display_native_hdr)
+extern PFN_vkSetLocalDimmingAMD vkSetLocalDimmingAMD;
+#endif /* defined(VK_AMD_display_native_hdr) */
+#if defined(VK_AMD_draw_indirect_count)
+extern PFN_vkCmdDrawIndexedIndirectCountAMD vkCmdDrawIndexedIndirectCountAMD;
+extern PFN_vkCmdDrawIndirectCountAMD vkCmdDrawIndirectCountAMD;
+#endif /* defined(VK_AMD_draw_indirect_count) */
+#if defined(VK_AMD_shader_info)
+extern PFN_vkGetShaderInfoAMD vkGetShaderInfoAMD;
+#endif /* defined(VK_AMD_shader_info) */
+#if defined(VK_ANDROID_external_memory_android_hardware_buffer)
+extern PFN_vkGetAndroidHardwareBufferPropertiesANDROID vkGetAndroidHardwareBufferPropertiesANDROID;
+extern PFN_vkGetMemoryAndroidHardwareBufferANDROID vkGetMemoryAndroidHardwareBufferANDROID;
+#endif /* defined(VK_ANDROID_external_memory_android_hardware_buffer) */
+#if defined(VK_EXT_acquire_drm_display)
+extern PFN_vkAcquireDrmDisplayEXT vkAcquireDrmDisplayEXT;
+extern PFN_vkGetDrmDisplayEXT vkGetDrmDisplayEXT;
+#endif /* defined(VK_EXT_acquire_drm_display) */
+#if defined(VK_EXT_acquire_xlib_display)
+extern PFN_vkAcquireXlibDisplayEXT vkAcquireXlibDisplayEXT;
+extern PFN_vkGetRandROutputDisplayEXT vkGetRandROutputDisplayEXT;
+#endif /* defined(VK_EXT_acquire_xlib_display) */
+#if defined(VK_EXT_buffer_device_address)
+extern PFN_vkGetBufferDeviceAddressEXT vkGetBufferDeviceAddressEXT;
+#endif /* defined(VK_EXT_buffer_device_address) */
+#if defined(VK_EXT_calibrated_timestamps)
+extern PFN_vkGetCalibratedTimestampsEXT vkGetCalibratedTimestampsEXT;
+extern PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT vkGetPhysicalDeviceCalibrateableTimeDomainsEXT;
+#endif /* defined(VK_EXT_calibrated_timestamps) */
+#if defined(VK_EXT_color_write_enable)
+extern PFN_vkCmdSetColorWriteEnableEXT vkCmdSetColorWriteEnableEXT;
+#endif /* defined(VK_EXT_color_write_enable) */
+#if defined(VK_EXT_conditional_rendering)
+extern PFN_vkCmdBeginConditionalRenderingEXT vkCmdBeginConditionalRenderingEXT;
+extern PFN_vkCmdEndConditionalRenderingEXT vkCmdEndConditionalRenderingEXT;
+#endif /* defined(VK_EXT_conditional_rendering) */
+#if defined(VK_EXT_debug_marker)
+extern PFN_vkCmdDebugMarkerBeginEXT vkCmdDebugMarkerBeginEXT;
+extern PFN_vkCmdDebugMarkerEndEXT vkCmdDebugMarkerEndEXT;
+extern PFN_vkCmdDebugMarkerInsertEXT vkCmdDebugMarkerInsertEXT;
+extern PFN_vkDebugMarkerSetObjectNameEXT vkDebugMarkerSetObjectNameEXT;
+extern PFN_vkDebugMarkerSetObjectTagEXT vkDebugMarkerSetObjectTagEXT;
+#endif /* defined(VK_EXT_debug_marker) */
+#if defined(VK_EXT_debug_report)
+extern PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT;
+extern PFN_vkDebugReportMessageEXT vkDebugReportMessageEXT;
+extern PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT;
+#endif /* defined(VK_EXT_debug_report) */
+#if defined(VK_EXT_debug_utils)
+extern PFN_vkCmdBeginDebugUtilsLabelEXT vkCmdBeginDebugUtilsLabelEXT;
+extern PFN_vkCmdEndDebugUtilsLabelEXT vkCmdEndDebugUtilsLabelEXT;
+extern PFN_vkCmdInsertDebugUtilsLabelEXT vkCmdInsertDebugUtilsLabelEXT;
+extern PFN_vkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessengerEXT;
+extern PFN_vkDestroyDebugUtilsMessengerEXT vkDestroyDebugUtilsMessengerEXT;
+extern PFN_vkQueueBeginDebugUtilsLabelEXT vkQueueBeginDebugUtilsLabelEXT;
+extern PFN_vkQueueEndDebugUtilsLabelEXT vkQueueEndDebugUtilsLabelEXT;
+extern PFN_vkQueueInsertDebugUtilsLabelEXT vkQueueInsertDebugUtilsLabelEXT;
+extern PFN_vkSetDebugUtilsObjectNameEXT vkSetDebugUtilsObjectNameEXT;
+extern PFN_vkSetDebugUtilsObjectTagEXT vkSetDebugUtilsObjectTagEXT;
+extern PFN_vkSubmitDebugUtilsMessageEXT vkSubmitDebugUtilsMessageEXT;
+#endif /* defined(VK_EXT_debug_utils) */
+#if defined(VK_EXT_direct_mode_display)
+extern PFN_vkReleaseDisplayEXT vkReleaseDisplayEXT;
+#endif /* defined(VK_EXT_direct_mode_display) */
+#if defined(VK_EXT_directfb_surface)
+extern PFN_vkCreateDirectFBSurfaceEXT vkCreateDirectFBSurfaceEXT;
+extern PFN_vkGetPhysicalDeviceDirectFBPresentationSupportEXT vkGetPhysicalDeviceDirectFBPresentationSupportEXT;
+#endif /* defined(VK_EXT_directfb_surface) */
+#if defined(VK_EXT_discard_rectangles)
+extern PFN_vkCmdSetDiscardRectangleEXT vkCmdSetDiscardRectangleEXT;
+#endif /* defined(VK_EXT_discard_rectangles) */
+#if defined(VK_EXT_display_control)
+extern PFN_vkDisplayPowerControlEXT vkDisplayPowerControlEXT;
+extern PFN_vkGetSwapchainCounterEXT vkGetSwapchainCounterEXT;
+extern PFN_vkRegisterDeviceEventEXT vkRegisterDeviceEventEXT;
+extern PFN_vkRegisterDisplayEventEXT vkRegisterDisplayEventEXT;
+#endif /* defined(VK_EXT_display_control) */
+#if defined(VK_EXT_display_surface_counter)
+extern PFN_vkGetPhysicalDeviceSurfaceCapabilities2EXT vkGetPhysicalDeviceSurfaceCapabilities2EXT;
+#endif /* defined(VK_EXT_display_surface_counter) */
+#if defined(VK_EXT_extended_dynamic_state)
+extern PFN_vkCmdBindVertexBuffers2EXT vkCmdBindVertexBuffers2EXT;
+extern PFN_vkCmdSetCullModeEXT vkCmdSetCullModeEXT;
+extern PFN_vkCmdSetDepthBoundsTestEnableEXT vkCmdSetDepthBoundsTestEnableEXT;
+extern PFN_vkCmdSetDepthCompareOpEXT vkCmdSetDepthCompareOpEXT;
+extern PFN_vkCmdSetDepthTestEnableEXT vkCmdSetDepthTestEnableEXT;
+extern PFN_vkCmdSetDepthWriteEnableEXT vkCmdSetDepthWriteEnableEXT;
+extern PFN_vkCmdSetFrontFaceEXT vkCmdSetFrontFaceEXT;
+extern PFN_vkCmdSetPrimitiveTopologyEXT vkCmdSetPrimitiveTopologyEXT;
+extern PFN_vkCmdSetScissorWithCountEXT vkCmdSetScissorWithCountEXT;
+extern PFN_vkCmdSetStencilOpEXT vkCmdSetStencilOpEXT;
+extern PFN_vkCmdSetStencilTestEnableEXT vkCmdSetStencilTestEnableEXT;
+extern PFN_vkCmdSetViewportWithCountEXT vkCmdSetViewportWithCountEXT;
+#endif /* defined(VK_EXT_extended_dynamic_state) */
+#if defined(VK_EXT_extended_dynamic_state2)
+extern PFN_vkCmdSetDepthBiasEnableEXT vkCmdSetDepthBiasEnableEXT;
+extern PFN_vkCmdSetLogicOpEXT vkCmdSetLogicOpEXT;
+extern PFN_vkCmdSetPatchControlPointsEXT vkCmdSetPatchControlPointsEXT;
+extern PFN_vkCmdSetPrimitiveRestartEnableEXT vkCmdSetPrimitiveRestartEnableEXT;
+extern PFN_vkCmdSetRasterizerDiscardEnableEXT vkCmdSetRasterizerDiscardEnableEXT;
+#endif /* defined(VK_EXT_extended_dynamic_state2) */
+#if defined(VK_EXT_external_memory_host)
+extern PFN_vkGetMemoryHostPointerPropertiesEXT vkGetMemoryHostPointerPropertiesEXT;
+#endif /* defined(VK_EXT_external_memory_host) */
+#if defined(VK_EXT_full_screen_exclusive)
+extern PFN_vkAcquireFullScreenExclusiveModeEXT vkAcquireFullScreenExclusiveModeEXT;
+extern PFN_vkGetPhysicalDeviceSurfacePresentModes2EXT vkGetPhysicalDeviceSurfacePresentModes2EXT;
+extern PFN_vkReleaseFullScreenExclusiveModeEXT vkReleaseFullScreenExclusiveModeEXT;
+#endif /* defined(VK_EXT_full_screen_exclusive) */
+#if defined(VK_EXT_hdr_metadata)
+extern PFN_vkSetHdrMetadataEXT vkSetHdrMetadataEXT;
+#endif /* defined(VK_EXT_hdr_metadata) */
+#if defined(VK_EXT_headless_surface)
+extern PFN_vkCreateHeadlessSurfaceEXT vkCreateHeadlessSurfaceEXT;
+#endif /* defined(VK_EXT_headless_surface) */
+#if defined(VK_EXT_host_query_reset)
+extern PFN_vkResetQueryPoolEXT vkResetQueryPoolEXT;
+#endif /* defined(VK_EXT_host_query_reset) */
+#if defined(VK_EXT_image_drm_format_modifier)
+extern PFN_vkGetImageDrmFormatModifierPropertiesEXT vkGetImageDrmFormatModifierPropertiesEXT;
+#endif /* defined(VK_EXT_image_drm_format_modifier) */
+#if defined(VK_EXT_line_rasterization)
+extern PFN_vkCmdSetLineStippleEXT vkCmdSetLineStippleEXT;
+#endif /* defined(VK_EXT_line_rasterization) */
+#if defined(VK_EXT_metal_surface)
+extern PFN_vkCreateMetalSurfaceEXT vkCreateMetalSurfaceEXT;
+#endif /* defined(VK_EXT_metal_surface) */
+#if defined(VK_EXT_multi_draw)
+extern PFN_vkCmdDrawMultiEXT vkCmdDrawMultiEXT;
+extern PFN_vkCmdDrawMultiIndexedEXT vkCmdDrawMultiIndexedEXT;
+#endif /* defined(VK_EXT_multi_draw) */
+#if defined(VK_EXT_pageable_device_local_memory)
+extern PFN_vkSetDeviceMemoryPriorityEXT vkSetDeviceMemoryPriorityEXT;
+#endif /* defined(VK_EXT_pageable_device_local_memory) */
+#if defined(VK_EXT_private_data)
+extern PFN_vkCreatePrivateDataSlotEXT vkCreatePrivateDataSlotEXT;
+extern PFN_vkDestroyPrivateDataSlotEXT vkDestroyPrivateDataSlotEXT;
+extern PFN_vkGetPrivateDataEXT vkGetPrivateDataEXT;
+extern PFN_vkSetPrivateDataEXT vkSetPrivateDataEXT;
+#endif /* defined(VK_EXT_private_data) */
+#if defined(VK_EXT_sample_locations)
+extern PFN_vkCmdSetSampleLocationsEXT vkCmdSetSampleLocationsEXT;
+extern PFN_vkGetPhysicalDeviceMultisamplePropertiesEXT vkGetPhysicalDeviceMultisamplePropertiesEXT;
+#endif /* defined(VK_EXT_sample_locations) */
+#if defined(VK_EXT_tooling_info)
+extern PFN_vkGetPhysicalDeviceToolPropertiesEXT vkGetPhysicalDeviceToolPropertiesEXT;
+#endif /* defined(VK_EXT_tooling_info) */
+#if defined(VK_EXT_transform_feedback)
+extern PFN_vkCmdBeginQueryIndexedEXT vkCmdBeginQueryIndexedEXT;
+extern PFN_vkCmdBeginTransformFeedbackEXT vkCmdBeginTransformFeedbackEXT;
+extern PFN_vkCmdBindTransformFeedbackBuffersEXT vkCmdBindTransformFeedbackBuffersEXT;
+extern PFN_vkCmdDrawIndirectByteCountEXT vkCmdDrawIndirectByteCountEXT;
+extern PFN_vkCmdEndQueryIndexedEXT vkCmdEndQueryIndexedEXT;
+extern PFN_vkCmdEndTransformFeedbackEXT vkCmdEndTransformFeedbackEXT;
+#endif /* defined(VK_EXT_transform_feedback) */
+#if defined(VK_EXT_validation_cache)
+extern PFN_vkCreateValidationCacheEXT vkCreateValidationCacheEXT;
+extern PFN_vkDestroyValidationCacheEXT vkDestroyValidationCacheEXT;
+extern PFN_vkGetValidationCacheDataEXT vkGetValidationCacheDataEXT;
+extern PFN_vkMergeValidationCachesEXT vkMergeValidationCachesEXT;
+#endif /* defined(VK_EXT_validation_cache) */
+#if defined(VK_EXT_vertex_input_dynamic_state)
+extern PFN_vkCmdSetVertexInputEXT vkCmdSetVertexInputEXT;
+#endif /* defined(VK_EXT_vertex_input_dynamic_state) */
+#if defined(VK_FUCHSIA_buffer_collection)
+extern PFN_vkCreateBufferCollectionFUCHSIA vkCreateBufferCollectionFUCHSIA;
+extern PFN_vkDestroyBufferCollectionFUCHSIA vkDestroyBufferCollectionFUCHSIA;
+extern PFN_vkGetBufferCollectionPropertiesFUCHSIA vkGetBufferCollectionPropertiesFUCHSIA;
+extern PFN_vkSetBufferCollectionBufferConstraintsFUCHSIA vkSetBufferCollectionBufferConstraintsFUCHSIA;
+extern PFN_vkSetBufferCollectionImageConstraintsFUCHSIA vkSetBufferCollectionImageConstraintsFUCHSIA;
+#endif /* defined(VK_FUCHSIA_buffer_collection) */
+#if defined(VK_FUCHSIA_external_memory)
+extern PFN_vkGetMemoryZirconHandleFUCHSIA vkGetMemoryZirconHandleFUCHSIA;
+extern PFN_vkGetMemoryZirconHandlePropertiesFUCHSIA vkGetMemoryZirconHandlePropertiesFUCHSIA;
+#endif /* defined(VK_FUCHSIA_external_memory) */
+#if defined(VK_FUCHSIA_external_semaphore)
+extern PFN_vkGetSemaphoreZirconHandleFUCHSIA vkGetSemaphoreZirconHandleFUCHSIA;
+extern PFN_vkImportSemaphoreZirconHandleFUCHSIA vkImportSemaphoreZirconHandleFUCHSIA;
+#endif /* defined(VK_FUCHSIA_external_semaphore) */
+#if defined(VK_FUCHSIA_imagepipe_surface)
+extern PFN_vkCreateImagePipeSurfaceFUCHSIA vkCreateImagePipeSurfaceFUCHSIA;
+#endif /* defined(VK_FUCHSIA_imagepipe_surface) */
+#if defined(VK_GGP_stream_descriptor_surface)
+extern PFN_vkCreateStreamDescriptorSurfaceGGP vkCreateStreamDescriptorSurfaceGGP;
+#endif /* defined(VK_GGP_stream_descriptor_surface) */
+#if defined(VK_GOOGLE_display_timing)
+extern PFN_vkGetPastPresentationTimingGOOGLE vkGetPastPresentationTimingGOOGLE;
+extern PFN_vkGetRefreshCycleDurationGOOGLE vkGetRefreshCycleDurationGOOGLE;
+#endif /* defined(VK_GOOGLE_display_timing) */
+#if defined(VK_HUAWEI_invocation_mask)
+extern PFN_vkCmdBindInvocationMaskHUAWEI vkCmdBindInvocationMaskHUAWEI;
+#endif /* defined(VK_HUAWEI_invocation_mask) */
+#if defined(VK_HUAWEI_subpass_shading)
+extern PFN_vkCmdSubpassShadingHUAWEI vkCmdSubpassShadingHUAWEI;
+extern PFN_vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI;
+#endif /* defined(VK_HUAWEI_subpass_shading) */
+#if defined(VK_INTEL_performance_query)
+extern PFN_vkAcquirePerformanceConfigurationINTEL vkAcquirePerformanceConfigurationINTEL;
+extern PFN_vkCmdSetPerformanceMarkerINTEL vkCmdSetPerformanceMarkerINTEL;
+extern PFN_vkCmdSetPerformanceOverrideINTEL vkCmdSetPerformanceOverrideINTEL;
+extern PFN_vkCmdSetPerformanceStreamMarkerINTEL vkCmdSetPerformanceStreamMarkerINTEL;
+extern PFN_vkGetPerformanceParameterINTEL vkGetPerformanceParameterINTEL;
+extern PFN_vkInitializePerformanceApiINTEL vkInitializePerformanceApiINTEL;
+extern PFN_vkQueueSetPerformanceConfigurationINTEL vkQueueSetPerformanceConfigurationINTEL;
+extern PFN_vkReleasePerformanceConfigurationINTEL vkReleasePerformanceConfigurationINTEL;
+extern PFN_vkUninitializePerformanceApiINTEL vkUninitializePerformanceApiINTEL;
+#endif /* defined(VK_INTEL_performance_query) */
+#if defined(VK_KHR_acceleration_structure)
+extern PFN_vkBuildAccelerationStructuresKHR vkBuildAccelerationStructuresKHR;
+extern PFN_vkCmdBuildAccelerationStructuresIndirectKHR vkCmdBuildAccelerationStructuresIndirectKHR;
+extern PFN_vkCmdBuildAccelerationStructuresKHR vkCmdBuildAccelerationStructuresKHR;
+extern PFN_vkCmdCopyAccelerationStructureKHR vkCmdCopyAccelerationStructureKHR;
+extern PFN_vkCmdCopyAccelerationStructureToMemoryKHR vkCmdCopyAccelerationStructureToMemoryKHR;
+extern PFN_vkCmdCopyMemoryToAccelerationStructureKHR vkCmdCopyMemoryToAccelerationStructureKHR;
+extern PFN_vkCmdWriteAccelerationStructuresPropertiesKHR vkCmdWriteAccelerationStructuresPropertiesKHR;
+extern PFN_vkCopyAccelerationStructureKHR vkCopyAccelerationStructureKHR;
+extern PFN_vkCopyAccelerationStructureToMemoryKHR vkCopyAccelerationStructureToMemoryKHR;
+extern PFN_vkCopyMemoryToAccelerationStructureKHR vkCopyMemoryToAccelerationStructureKHR;
+extern PFN_vkCreateAccelerationStructureKHR vkCreateAccelerationStructureKHR;
+extern PFN_vkDestroyAccelerationStructureKHR vkDestroyAccelerationStructureKHR;
+extern PFN_vkGetAccelerationStructureBuildSizesKHR vkGetAccelerationStructureBuildSizesKHR;
+extern PFN_vkGetAccelerationStructureDeviceAddressKHR vkGetAccelerationStructureDeviceAddressKHR;
+extern PFN_vkGetDeviceAccelerationStructureCompatibilityKHR vkGetDeviceAccelerationStructureCompatibilityKHR;
+extern PFN_vkWriteAccelerationStructuresPropertiesKHR vkWriteAccelerationStructuresPropertiesKHR;
+#endif /* defined(VK_KHR_acceleration_structure) */
+#if defined(VK_KHR_android_surface)
+extern PFN_vkCreateAndroidSurfaceKHR vkCreateAndroidSurfaceKHR;
+#endif /* defined(VK_KHR_android_surface) */
+#if defined(VK_KHR_bind_memory2)
+extern PFN_vkBindBufferMemory2KHR vkBindBufferMemory2KHR;
+extern PFN_vkBindImageMemory2KHR vkBindImageMemory2KHR;
+#endif /* defined(VK_KHR_bind_memory2) */
+#if defined(VK_KHR_buffer_device_address)
+extern PFN_vkGetBufferDeviceAddressKHR vkGetBufferDeviceAddressKHR;
+extern PFN_vkGetBufferOpaqueCaptureAddressKHR vkGetBufferOpaqueCaptureAddressKHR;
+extern PFN_vkGetDeviceMemoryOpaqueCaptureAddressKHR vkGetDeviceMemoryOpaqueCaptureAddressKHR;
+#endif /* defined(VK_KHR_buffer_device_address) */
+#if defined(VK_KHR_copy_commands2)
+extern PFN_vkCmdBlitImage2KHR vkCmdBlitImage2KHR;
+extern PFN_vkCmdCopyBuffer2KHR vkCmdCopyBuffer2KHR;
+extern PFN_vkCmdCopyBufferToImage2KHR vkCmdCopyBufferToImage2KHR;
+extern PFN_vkCmdCopyImage2KHR vkCmdCopyImage2KHR;
+extern PFN_vkCmdCopyImageToBuffer2KHR vkCmdCopyImageToBuffer2KHR;
+extern PFN_vkCmdResolveImage2KHR vkCmdResolveImage2KHR;
+#endif /* defined(VK_KHR_copy_commands2) */
+#if defined(VK_KHR_create_renderpass2)
+extern PFN_vkCmdBeginRenderPass2KHR vkCmdBeginRenderPass2KHR;
+extern PFN_vkCmdEndRenderPass2KHR vkCmdEndRenderPass2KHR;
+extern PFN_vkCmdNextSubpass2KHR vkCmdNextSubpass2KHR;
+extern PFN_vkCreateRenderPass2KHR vkCreateRenderPass2KHR;
+#endif /* defined(VK_KHR_create_renderpass2) */
+#if defined(VK_KHR_deferred_host_operations)
+extern PFN_vkCreateDeferredOperationKHR vkCreateDeferredOperationKHR;
+extern PFN_vkDeferredOperationJoinKHR vkDeferredOperationJoinKHR;
+extern PFN_vkDestroyDeferredOperationKHR vkDestroyDeferredOperationKHR;
+extern PFN_vkGetDeferredOperationMaxConcurrencyKHR vkGetDeferredOperationMaxConcurrencyKHR;
+extern PFN_vkGetDeferredOperationResultKHR vkGetDeferredOperationResultKHR;
+#endif /* defined(VK_KHR_deferred_host_operations) */
+#if defined(VK_KHR_descriptor_update_template)
+extern PFN_vkCreateDescriptorUpdateTemplateKHR vkCreateDescriptorUpdateTemplateKHR;
+extern PFN_vkDestroyDescriptorUpdateTemplateKHR vkDestroyDescriptorUpdateTemplateKHR;
+extern PFN_vkUpdateDescriptorSetWithTemplateKHR vkUpdateDescriptorSetWithTemplateKHR;
+#endif /* defined(VK_KHR_descriptor_update_template) */
+#if defined(VK_KHR_device_group)
+extern PFN_vkCmdDispatchBaseKHR vkCmdDispatchBaseKHR;
+extern PFN_vkCmdSetDeviceMaskKHR vkCmdSetDeviceMaskKHR;
+extern PFN_vkGetDeviceGroupPeerMemoryFeaturesKHR vkGetDeviceGroupPeerMemoryFeaturesKHR;
+#endif /* defined(VK_KHR_device_group) */
+#if defined(VK_KHR_device_group_creation)
+extern PFN_vkEnumeratePhysicalDeviceGroupsKHR vkEnumeratePhysicalDeviceGroupsKHR;
+#endif /* defined(VK_KHR_device_group_creation) */
+#if defined(VK_KHR_display)
+extern PFN_vkCreateDisplayModeKHR vkCreateDisplayModeKHR;
+extern PFN_vkCreateDisplayPlaneSurfaceKHR vkCreateDisplayPlaneSurfaceKHR;
+extern PFN_vkGetDisplayModePropertiesKHR vkGetDisplayModePropertiesKHR;
+extern PFN_vkGetDisplayPlaneCapabilitiesKHR vkGetDisplayPlaneCapabilitiesKHR;
+extern PFN_vkGetDisplayPlaneSupportedDisplaysKHR vkGetDisplayPlaneSupportedDisplaysKHR;
+extern PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR vkGetPhysicalDeviceDisplayPlanePropertiesKHR;
+extern PFN_vkGetPhysicalDeviceDisplayPropertiesKHR vkGetPhysicalDeviceDisplayPropertiesKHR;
+#endif /* defined(VK_KHR_display) */
+#if defined(VK_KHR_display_swapchain)
+extern PFN_vkCreateSharedSwapchainsKHR vkCreateSharedSwapchainsKHR;
+#endif /* defined(VK_KHR_display_swapchain) */
+#if defined(VK_KHR_draw_indirect_count)
+extern PFN_vkCmdDrawIndexedIndirectCountKHR vkCmdDrawIndexedIndirectCountKHR;
+extern PFN_vkCmdDrawIndirectCountKHR vkCmdDrawIndirectCountKHR;
+#endif /* defined(VK_KHR_draw_indirect_count) */
+#if defined(VK_KHR_dynamic_rendering)
+extern PFN_vkCmdBeginRenderingKHR vkCmdBeginRenderingKHR;
+extern PFN_vkCmdEndRenderingKHR vkCmdEndRenderingKHR;
+#endif /* defined(VK_KHR_dynamic_rendering) */
+#if defined(VK_KHR_external_fence_capabilities)
+extern PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR vkGetPhysicalDeviceExternalFencePropertiesKHR;
+#endif /* defined(VK_KHR_external_fence_capabilities) */
+#if defined(VK_KHR_external_fence_fd)
+extern PFN_vkGetFenceFdKHR vkGetFenceFdKHR;
+extern PFN_vkImportFenceFdKHR vkImportFenceFdKHR;
+#endif /* defined(VK_KHR_external_fence_fd) */
+#if defined(VK_KHR_external_fence_win32)
+extern PFN_vkGetFenceWin32HandleKHR vkGetFenceWin32HandleKHR;
+extern PFN_vkImportFenceWin32HandleKHR vkImportFenceWin32HandleKHR;
+#endif /* defined(VK_KHR_external_fence_win32) */
+#if defined(VK_KHR_external_memory_capabilities)
+extern PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR vkGetPhysicalDeviceExternalBufferPropertiesKHR;
+#endif /* defined(VK_KHR_external_memory_capabilities) */
+#if defined(VK_KHR_external_memory_fd)
+extern PFN_vkGetMemoryFdKHR vkGetMemoryFdKHR;
+extern PFN_vkGetMemoryFdPropertiesKHR vkGetMemoryFdPropertiesKHR;
+#endif /* defined(VK_KHR_external_memory_fd) */
+#if defined(VK_KHR_external_memory_win32)
+extern PFN_vkGetMemoryWin32HandleKHR vkGetMemoryWin32HandleKHR;
+extern PFN_vkGetMemoryWin32HandlePropertiesKHR vkGetMemoryWin32HandlePropertiesKHR;
+#endif /* defined(VK_KHR_external_memory_win32) */
+#if defined(VK_KHR_external_semaphore_capabilities)
+extern PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR vkGetPhysicalDeviceExternalSemaphorePropertiesKHR;
+#endif /* defined(VK_KHR_external_semaphore_capabilities) */
+#if defined(VK_KHR_external_semaphore_fd)
+extern PFN_vkGetSemaphoreFdKHR vkGetSemaphoreFdKHR;
+extern PFN_vkImportSemaphoreFdKHR vkImportSemaphoreFdKHR;
+#endif /* defined(VK_KHR_external_semaphore_fd) */
+#if defined(VK_KHR_external_semaphore_win32)
+extern PFN_vkGetSemaphoreWin32HandleKHR vkGetSemaphoreWin32HandleKHR;
+extern PFN_vkImportSemaphoreWin32HandleKHR vkImportSemaphoreWin32HandleKHR;
+#endif /* defined(VK_KHR_external_semaphore_win32) */
+#if defined(VK_KHR_fragment_shading_rate)
+extern PFN_vkCmdSetFragmentShadingRateKHR vkCmdSetFragmentShadingRateKHR;
+extern PFN_vkGetPhysicalDeviceFragmentShadingRatesKHR vkGetPhysicalDeviceFragmentShadingRatesKHR;
+#endif /* defined(VK_KHR_fragment_shading_rate) */
+#if defined(VK_KHR_get_display_properties2)
+extern PFN_vkGetDisplayModeProperties2KHR vkGetDisplayModeProperties2KHR;
+extern PFN_vkGetDisplayPlaneCapabilities2KHR vkGetDisplayPlaneCapabilities2KHR;
+extern PFN_vkGetPhysicalDeviceDisplayPlaneProperties2KHR vkGetPhysicalDeviceDisplayPlaneProperties2KHR;
+extern PFN_vkGetPhysicalDeviceDisplayProperties2KHR vkGetPhysicalDeviceDisplayProperties2KHR;
+#endif /* defined(VK_KHR_get_display_properties2) */
+#if defined(VK_KHR_get_memory_requirements2)
+extern PFN_vkGetBufferMemoryRequirements2KHR vkGetBufferMemoryRequirements2KHR;
+extern PFN_vkGetImageMemoryRequirements2KHR vkGetImageMemoryRequirements2KHR;
+extern PFN_vkGetImageSparseMemoryRequirements2KHR vkGetImageSparseMemoryRequirements2KHR;
+#endif /* defined(VK_KHR_get_memory_requirements2) */
+#if defined(VK_KHR_get_physical_device_properties2)
+extern PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR;
+extern PFN_vkGetPhysicalDeviceFormatProperties2KHR vkGetPhysicalDeviceFormatProperties2KHR;
+extern PFN_vkGetPhysicalDeviceImageFormatProperties2KHR vkGetPhysicalDeviceImageFormatProperties2KHR;
+extern PFN_vkGetPhysicalDeviceMemoryProperties2KHR vkGetPhysicalDeviceMemoryProperties2KHR;
+extern PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR;
+extern PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR vkGetPhysicalDeviceQueueFamilyProperties2KHR;
+extern PFN_vkGetPhysicalDeviceSparseImageFormatProperties2KHR vkGetPhysicalDeviceSparseImageFormatProperties2KHR;
+#endif /* defined(VK_KHR_get_physical_device_properties2) */
+#if defined(VK_KHR_get_surface_capabilities2)
+extern PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR vkGetPhysicalDeviceSurfaceCapabilities2KHR;
+extern PFN_vkGetPhysicalDeviceSurfaceFormats2KHR vkGetPhysicalDeviceSurfaceFormats2KHR;
+#endif /* defined(VK_KHR_get_surface_capabilities2) */
+#if defined(VK_KHR_maintenance1)
+extern PFN_vkTrimCommandPoolKHR vkTrimCommandPoolKHR;
+#endif /* defined(VK_KHR_maintenance1) */
+#if defined(VK_KHR_maintenance3)
+extern PFN_vkGetDescriptorSetLayoutSupportKHR vkGetDescriptorSetLayoutSupportKHR;
+#endif /* defined(VK_KHR_maintenance3) */
+#if defined(VK_KHR_maintenance4)
+extern PFN_vkGetDeviceBufferMemoryRequirementsKHR vkGetDeviceBufferMemoryRequirementsKHR;
+extern PFN_vkGetDeviceImageMemoryRequirementsKHR vkGetDeviceImageMemoryRequirementsKHR;
+extern PFN_vkGetDeviceImageSparseMemoryRequirementsKHR vkGetDeviceImageSparseMemoryRequirementsKHR;
+#endif /* defined(VK_KHR_maintenance4) */
+#if defined(VK_KHR_performance_query)
+extern PFN_vkAcquireProfilingLockKHR vkAcquireProfilingLockKHR;
+extern PFN_vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR;
+extern PFN_vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR;
+extern PFN_vkReleaseProfilingLockKHR vkReleaseProfilingLockKHR;
+#endif /* defined(VK_KHR_performance_query) */
+#if defined(VK_KHR_pipeline_executable_properties)
+extern PFN_vkGetPipelineExecutableInternalRepresentationsKHR vkGetPipelineExecutableInternalRepresentationsKHR;
+extern PFN_vkGetPipelineExecutablePropertiesKHR vkGetPipelineExecutablePropertiesKHR;
+extern PFN_vkGetPipelineExecutableStatisticsKHR vkGetPipelineExecutableStatisticsKHR;
+#endif /* defined(VK_KHR_pipeline_executable_properties) */
+#if defined(VK_KHR_present_wait)
+extern PFN_vkWaitForPresentKHR vkWaitForPresentKHR;
+#endif /* defined(VK_KHR_present_wait) */
+#if defined(VK_KHR_push_descriptor)
+extern PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSetKHR;
+#endif /* defined(VK_KHR_push_descriptor) */
+#if defined(VK_KHR_ray_tracing_pipeline)
+extern PFN_vkCmdSetRayTracingPipelineStackSizeKHR vkCmdSetRayTracingPipelineStackSizeKHR;
+extern PFN_vkCmdTraceRaysIndirectKHR vkCmdTraceRaysIndirectKHR;
+extern PFN_vkCmdTraceRaysKHR vkCmdTraceRaysKHR;
+extern PFN_vkCreateRayTracingPipelinesKHR vkCreateRayTracingPipelinesKHR;
+extern PFN_vkGetRayTracingCaptureReplayShaderGroupHandlesKHR vkGetRayTracingCaptureReplayShaderGroupHandlesKHR;
+extern PFN_vkGetRayTracingShaderGroupHandlesKHR vkGetRayTracingShaderGroupHandlesKHR;
+extern PFN_vkGetRayTracingShaderGroupStackSizeKHR vkGetRayTracingShaderGroupStackSizeKHR;
+#endif /* defined(VK_KHR_ray_tracing_pipeline) */
+#if defined(VK_KHR_sampler_ycbcr_conversion)
+extern PFN_vkCreateSamplerYcbcrConversionKHR vkCreateSamplerYcbcrConversionKHR;
+extern PFN_vkDestroySamplerYcbcrConversionKHR vkDestroySamplerYcbcrConversionKHR;
+#endif /* defined(VK_KHR_sampler_ycbcr_conversion) */
+#if defined(VK_KHR_shared_presentable_image)
+extern PFN_vkGetSwapchainStatusKHR vkGetSwapchainStatusKHR;
+#endif /* defined(VK_KHR_shared_presentable_image) */
+#if defined(VK_KHR_surface)
+extern PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR;
+extern PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR;
+extern PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR;
+extern PFN_vkGetPhysicalDeviceSurfacePresentModesKHR vkGetPhysicalDeviceSurfacePresentModesKHR;
+extern PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR;
+#endif /* defined(VK_KHR_surface) */
+#if defined(VK_KHR_swapchain)
+extern PFN_vkAcquireNextImageKHR vkAcquireNextImageKHR;
+extern PFN_vkCreateSwapchainKHR vkCreateSwapchainKHR;
+extern PFN_vkDestroySwapchainKHR vkDestroySwapchainKHR;
+extern PFN_vkGetSwapchainImagesKHR vkGetSwapchainImagesKHR;
+extern PFN_vkQueuePresentKHR vkQueuePresentKHR;
+#endif /* defined(VK_KHR_swapchain) */
+#if defined(VK_KHR_synchronization2)
+extern PFN_vkCmdPipelineBarrier2KHR vkCmdPipelineBarrier2KHR;
+extern PFN_vkCmdResetEvent2KHR vkCmdResetEvent2KHR;
+extern PFN_vkCmdSetEvent2KHR vkCmdSetEvent2KHR;
+extern PFN_vkCmdWaitEvents2KHR vkCmdWaitEvents2KHR;
+extern PFN_vkCmdWriteTimestamp2KHR vkCmdWriteTimestamp2KHR;
+extern PFN_vkQueueSubmit2KHR vkQueueSubmit2KHR;
+#endif /* defined(VK_KHR_synchronization2) */
+#if defined(VK_KHR_synchronization2) && defined(VK_AMD_buffer_marker)
+extern PFN_vkCmdWriteBufferMarker2AMD vkCmdWriteBufferMarker2AMD;
+#endif /* defined(VK_KHR_synchronization2) && defined(VK_AMD_buffer_marker) */
+#if defined(VK_KHR_synchronization2) && defined(VK_NV_device_diagnostic_checkpoints)
+extern PFN_vkGetQueueCheckpointData2NV vkGetQueueCheckpointData2NV;
+#endif /* defined(VK_KHR_synchronization2) && defined(VK_NV_device_diagnostic_checkpoints) */
+#if defined(VK_KHR_timeline_semaphore)
+extern PFN_vkGetSemaphoreCounterValueKHR vkGetSemaphoreCounterValueKHR;
+extern PFN_vkSignalSemaphoreKHR vkSignalSemaphoreKHR;
+extern PFN_vkWaitSemaphoresKHR vkWaitSemaphoresKHR;
+#endif /* defined(VK_KHR_timeline_semaphore) */
+#if defined(VK_KHR_video_decode_queue)
+extern PFN_vkCmdDecodeVideoKHR vkCmdDecodeVideoKHR;
+#endif /* defined(VK_KHR_video_decode_queue) */
+#if defined(VK_KHR_video_encode_queue)
+extern PFN_vkCmdEncodeVideoKHR vkCmdEncodeVideoKHR;
+#endif /* defined(VK_KHR_video_encode_queue) */
+#if defined(VK_KHR_video_queue)
+extern PFN_vkBindVideoSessionMemoryKHR vkBindVideoSessionMemoryKHR;
+extern PFN_vkCmdBeginVideoCodingKHR vkCmdBeginVideoCodingKHR;
+extern PFN_vkCmdControlVideoCodingKHR vkCmdControlVideoCodingKHR;
+extern PFN_vkCmdEndVideoCodingKHR vkCmdEndVideoCodingKHR;
+extern PFN_vkCreateVideoSessionKHR vkCreateVideoSessionKHR;
+extern PFN_vkCreateVideoSessionParametersKHR vkCreateVideoSessionParametersKHR;
+extern PFN_vkDestroyVideoSessionKHR vkDestroyVideoSessionKHR;
+extern PFN_vkDestroyVideoSessionParametersKHR vkDestroyVideoSessionParametersKHR;
+extern PFN_vkGetPhysicalDeviceVideoCapabilitiesKHR vkGetPhysicalDeviceVideoCapabilitiesKHR;
+extern PFN_vkGetPhysicalDeviceVideoFormatPropertiesKHR vkGetPhysicalDeviceVideoFormatPropertiesKHR;
+extern PFN_vkGetVideoSessionMemoryRequirementsKHR vkGetVideoSessionMemoryRequirementsKHR;
+extern PFN_vkUpdateVideoSessionParametersKHR vkUpdateVideoSessionParametersKHR;
+#endif /* defined(VK_KHR_video_queue) */
+#if defined(VK_KHR_wayland_surface)
+extern PFN_vkCreateWaylandSurfaceKHR vkCreateWaylandSurfaceKHR;
+extern PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR vkGetPhysicalDeviceWaylandPresentationSupportKHR;
+#endif /* defined(VK_KHR_wayland_surface) */
+#if defined(VK_KHR_win32_surface)
+extern PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR;
+extern PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR vkGetPhysicalDeviceWin32PresentationSupportKHR;
+#endif /* defined(VK_KHR_win32_surface) */
+#if defined(VK_KHR_xcb_surface)
+extern PFN_vkCreateXcbSurfaceKHR vkCreateXcbSurfaceKHR;
+extern PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR vkGetPhysicalDeviceXcbPresentationSupportKHR;
+#endif /* defined(VK_KHR_xcb_surface) */
+#if defined(VK_KHR_xlib_surface)
+extern PFN_vkCreateXlibSurfaceKHR vkCreateXlibSurfaceKHR;
+extern PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR vkGetPhysicalDeviceXlibPresentationSupportKHR;
+#endif /* defined(VK_KHR_xlib_surface) */
+#if defined(VK_MVK_ios_surface)
+extern PFN_vkCreateIOSSurfaceMVK vkCreateIOSSurfaceMVK;
+#endif /* defined(VK_MVK_ios_surface) */
+#if defined(VK_MVK_macos_surface)
+extern PFN_vkCreateMacOSSurfaceMVK vkCreateMacOSSurfaceMVK;
+#endif /* defined(VK_MVK_macos_surface) */
+#if defined(VK_NN_vi_surface)
+extern PFN_vkCreateViSurfaceNN vkCreateViSurfaceNN;
+#endif /* defined(VK_NN_vi_surface) */
+#if defined(VK_NVX_binary_import)
+extern PFN_vkCmdCuLaunchKernelNVX vkCmdCuLaunchKernelNVX;
+extern PFN_vkCreateCuFunctionNVX vkCreateCuFunctionNVX;
+extern PFN_vkCreateCuModuleNVX vkCreateCuModuleNVX;
+extern PFN_vkDestroyCuFunctionNVX vkDestroyCuFunctionNVX;
+extern PFN_vkDestroyCuModuleNVX vkDestroyCuModuleNVX;
+#endif /* defined(VK_NVX_binary_import) */
+#if defined(VK_NVX_image_view_handle)
+extern PFN_vkGetImageViewAddressNVX vkGetImageViewAddressNVX;
+extern PFN_vkGetImageViewHandleNVX vkGetImageViewHandleNVX;
+#endif /* defined(VK_NVX_image_view_handle) */
+#if defined(VK_NV_acquire_winrt_display)
+extern PFN_vkAcquireWinrtDisplayNV vkAcquireWinrtDisplayNV;
+extern PFN_vkGetWinrtDisplayNV vkGetWinrtDisplayNV;
+#endif /* defined(VK_NV_acquire_winrt_display) */
+#if defined(VK_NV_clip_space_w_scaling)
+extern PFN_vkCmdSetViewportWScalingNV vkCmdSetViewportWScalingNV;
+#endif /* defined(VK_NV_clip_space_w_scaling) */
+#if defined(VK_NV_cooperative_matrix)
+extern PFN_vkGetPhysicalDeviceCooperativeMatrixPropertiesNV vkGetPhysicalDeviceCooperativeMatrixPropertiesNV;
+#endif /* defined(VK_NV_cooperative_matrix) */
+#if defined(VK_NV_coverage_reduction_mode)
+extern PFN_vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV;
+#endif /* defined(VK_NV_coverage_reduction_mode) */
+#if defined(VK_NV_device_diagnostic_checkpoints)
+extern PFN_vkCmdSetCheckpointNV vkCmdSetCheckpointNV;
+extern PFN_vkGetQueueCheckpointDataNV vkGetQueueCheckpointDataNV;
+#endif /* defined(VK_NV_device_diagnostic_checkpoints) */
+#if defined(VK_NV_device_generated_commands)
+extern PFN_vkCmdBindPipelineShaderGroupNV vkCmdBindPipelineShaderGroupNV;
+extern PFN_vkCmdExecuteGeneratedCommandsNV vkCmdExecuteGeneratedCommandsNV;
+extern PFN_vkCmdPreprocessGeneratedCommandsNV vkCmdPreprocessGeneratedCommandsNV;
+extern PFN_vkCreateIndirectCommandsLayoutNV vkCreateIndirectCommandsLayoutNV;
+extern PFN_vkDestroyIndirectCommandsLayoutNV vkDestroyIndirectCommandsLayoutNV;
+extern PFN_vkGetGeneratedCommandsMemoryRequirementsNV vkGetGeneratedCommandsMemoryRequirementsNV;
+#endif /* defined(VK_NV_device_generated_commands) */
+#if defined(VK_NV_external_memory_capabilities)
+extern PFN_vkGetPhysicalDeviceExternalImageFormatPropertiesNV vkGetPhysicalDeviceExternalImageFormatPropertiesNV;
+#endif /* defined(VK_NV_external_memory_capabilities) */
+#if defined(VK_NV_external_memory_rdma)
+extern PFN_vkGetMemoryRemoteAddressNV vkGetMemoryRemoteAddressNV;
+#endif /* defined(VK_NV_external_memory_rdma) */
+#if defined(VK_NV_external_memory_win32)
+extern PFN_vkGetMemoryWin32HandleNV vkGetMemoryWin32HandleNV;
+#endif /* defined(VK_NV_external_memory_win32) */
+#if defined(VK_NV_fragment_shading_rate_enums)
+extern PFN_vkCmdSetFragmentShadingRateEnumNV vkCmdSetFragmentShadingRateEnumNV;
+#endif /* defined(VK_NV_fragment_shading_rate_enums) */
+#if defined(VK_NV_mesh_shader)
+extern PFN_vkCmdDrawMeshTasksIndirectCountNV vkCmdDrawMeshTasksIndirectCountNV;
+extern PFN_vkCmdDrawMeshTasksIndirectNV vkCmdDrawMeshTasksIndirectNV;
+extern PFN_vkCmdDrawMeshTasksNV vkCmdDrawMeshTasksNV;
+#endif /* defined(VK_NV_mesh_shader) */
+#if defined(VK_NV_ray_tracing)
+extern PFN_vkBindAccelerationStructureMemoryNV vkBindAccelerationStructureMemoryNV;
+extern PFN_vkCmdBuildAccelerationStructureNV vkCmdBuildAccelerationStructureNV;
+extern PFN_vkCmdCopyAccelerationStructureNV vkCmdCopyAccelerationStructureNV;
+extern PFN_vkCmdTraceRaysNV vkCmdTraceRaysNV;
+extern PFN_vkCmdWriteAccelerationStructuresPropertiesNV vkCmdWriteAccelerationStructuresPropertiesNV;
+extern PFN_vkCompileDeferredNV vkCompileDeferredNV;
+extern PFN_vkCreateAccelerationStructureNV vkCreateAccelerationStructureNV;
+extern PFN_vkCreateRayTracingPipelinesNV vkCreateRayTracingPipelinesNV;
+extern PFN_vkDestroyAccelerationStructureNV vkDestroyAccelerationStructureNV;
+extern PFN_vkGetAccelerationStructureHandleNV vkGetAccelerationStructureHandleNV;
+extern PFN_vkGetAccelerationStructureMemoryRequirementsNV vkGetAccelerationStructureMemoryRequirementsNV;
+extern PFN_vkGetRayTracingShaderGroupHandlesNV vkGetRayTracingShaderGroupHandlesNV;
+#endif /* defined(VK_NV_ray_tracing) */
+#if defined(VK_NV_scissor_exclusive)
+extern PFN_vkCmdSetExclusiveScissorNV vkCmdSetExclusiveScissorNV;
+#endif /* defined(VK_NV_scissor_exclusive) */
+#if defined(VK_NV_shading_rate_image)
+extern PFN_vkCmdBindShadingRateImageNV vkCmdBindShadingRateImageNV;
+extern PFN_vkCmdSetCoarseSampleOrderNV vkCmdSetCoarseSampleOrderNV;
+extern PFN_vkCmdSetViewportShadingRatePaletteNV vkCmdSetViewportShadingRatePaletteNV;
+#endif /* defined(VK_NV_shading_rate_image) */
+#if defined(VK_QNX_screen_surface)
+extern PFN_vkCreateScreenSurfaceQNX vkCreateScreenSurfaceQNX;
+extern PFN_vkGetPhysicalDeviceScreenPresentationSupportQNX vkGetPhysicalDeviceScreenPresentationSupportQNX;
+#endif /* defined(VK_QNX_screen_surface) */
+#if (defined(VK_EXT_full_screen_exclusive) && defined(VK_KHR_device_group)) || (defined(VK_EXT_full_screen_exclusive) && defined(VK_VERSION_1_1))
+extern PFN_vkGetDeviceGroupSurfacePresentModes2EXT vkGetDeviceGroupSurfacePresentModes2EXT;
+#endif /* (defined(VK_EXT_full_screen_exclusive) && defined(VK_KHR_device_group)) || (defined(VK_EXT_full_screen_exclusive) && defined(VK_VERSION_1_1)) */
+#if (defined(VK_KHR_descriptor_update_template) && defined(VK_KHR_push_descriptor)) || (defined(VK_KHR_push_descriptor) && defined(VK_VERSION_1_1)) || (defined(VK_KHR_push_descriptor) && defined(VK_KHR_descriptor_update_template))
+extern PFN_vkCmdPushDescriptorSetWithTemplateKHR vkCmdPushDescriptorSetWithTemplateKHR;
+#endif /* (defined(VK_KHR_descriptor_update_template) && defined(VK_KHR_push_descriptor)) || (defined(VK_KHR_push_descriptor) && defined(VK_VERSION_1_1)) || (defined(VK_KHR_push_descriptor) && defined(VK_KHR_descriptor_update_template)) */
+#if (defined(VK_KHR_device_group) && defined(VK_KHR_surface)) || (defined(VK_KHR_swapchain) && defined(VK_VERSION_1_1))
+extern PFN_vkGetDeviceGroupPresentCapabilitiesKHR vkGetDeviceGroupPresentCapabilitiesKHR;
+extern PFN_vkGetDeviceGroupSurfacePresentModesKHR vkGetDeviceGroupSurfacePresentModesKHR;
+extern PFN_vkGetPhysicalDevicePresentRectanglesKHR vkGetPhysicalDevicePresentRectanglesKHR;
+#endif /* (defined(VK_KHR_device_group) && defined(VK_KHR_surface)) || (defined(VK_KHR_swapchain) && defined(VK_VERSION_1_1)) */
+#if (defined(VK_KHR_device_group) && defined(VK_KHR_swapchain)) || (defined(VK_KHR_swapchain) && defined(VK_VERSION_1_1))
+extern PFN_vkAcquireNextImage2KHR vkAcquireNextImage2KHR;
+#endif /* (defined(VK_KHR_device_group) && defined(VK_KHR_swapchain)) || (defined(VK_KHR_swapchain) && defined(VK_VERSION_1_1)) */
+/* VOLK_GENERATE_PROTOTYPES_H */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#ifdef VOLK_IMPLEMENTATION
+#undef VOLK_IMPLEMENTATION
+// Prevent tools like dependency checkers that don't evaluate
+// macros from detecting a cyclic dependency.
+#define VOLK_SOURCE "volk.c"
+#include VOLK_SOURCE
+#endif
+
+/**
+ * Copyright (c) 2018-2019 Arseny Kapoulkine
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+*/
+/* clang-format on */